From 091467490f30bf56504fc3b02a57e7be4b60abfb Mon Sep 17 00:00:00 2001 From: Doug Torrance Date: Wed, 13 Sep 2017 16:16:49 -0400 Subject: [PATCH] wmisdn: Add version 1.81 to repository. From https://web.archive.org/web/20040608222101/http://www.uni-bonn.de:80/~uzsymm/wmisdn/wmisdn-1.81.tgz --- wmisdn/CHANGES | 63 ++ wmisdn/COPYING | 339 +++++++++ wmisdn/INSTALL | 52 ++ wmisdn/Makefile | 30 + wmisdn/README | 180 +++++ wmisdn/SCRIPTS | 52 ++ wmisdn/optics/optics.h | 37 + wmisdn/optics/optics.h~ | 37 + wmisdn/regions.cc | 153 ++++ wmisdn/regions.h | 18 + wmisdn/wmisdn.cc | 1608 +++++++++++++++++++++++++++++++++++++++ wmisdn/xpm/bundled.xpm | 80 ++ wmisdn/xpm/bundling.xpm | 80 ++ wmisdn/xpm/cover.xpm | 71 ++ wmisdn/xpm/dialing.xpm | 80 ++ wmisdn/xpm/disabled.xpm | 80 ++ wmisdn/xpm/fax.xpm | 80 ++ wmisdn/xpm/incoming.xpm | 80 ++ wmisdn/xpm/info_sw.xpm | 15 + wmisdn/xpm/lamps.xpm | 21 + wmisdn/xpm/lamps_sw.xpm | 15 + wmisdn/xpm/leds.xpm | 17 + wmisdn/xpm/modem.xpm | 80 ++ wmisdn/xpm/off.xpm | 80 ++ wmisdn/xpm/offline.xpm | 80 ++ wmisdn/xpm/online.xpm | 80 ++ wmisdn/xpm/outgoing.xpm | 80 ++ wmisdn/xpm/raw.xpm | 80 ++ wmisdn/xpm/slave.xpm | 80 ++ wmisdn/xpm/unknown.xpm | 80 ++ wmisdn/xpm/voice.xpm | 80 ++ 31 files changed, 3908 insertions(+) create mode 100644 wmisdn/CHANGES create mode 100644 wmisdn/COPYING create mode 100644 wmisdn/INSTALL create mode 100644 wmisdn/Makefile create mode 100644 wmisdn/README create mode 100644 wmisdn/SCRIPTS create mode 100644 wmisdn/optics/optics.h create mode 100644 wmisdn/optics/optics.h~ create mode 100644 wmisdn/regions.cc create mode 100644 wmisdn/regions.h create mode 100644 wmisdn/wmisdn.cc create mode 100644 wmisdn/xpm/bundled.xpm create mode 100644 wmisdn/xpm/bundling.xpm create mode 100644 wmisdn/xpm/cover.xpm create mode 100644 wmisdn/xpm/dialing.xpm create mode 100644 wmisdn/xpm/disabled.xpm create mode 100644 wmisdn/xpm/fax.xpm create mode 100644 wmisdn/xpm/incoming.xpm create mode 100644 wmisdn/xpm/info_sw.xpm create mode 100644 wmisdn/xpm/lamps.xpm create mode 100644 wmisdn/xpm/lamps_sw.xpm create mode 100644 wmisdn/xpm/leds.xpm create mode 100644 wmisdn/xpm/modem.xpm create mode 100644 wmisdn/xpm/off.xpm create mode 100644 wmisdn/xpm/offline.xpm create mode 100644 wmisdn/xpm/online.xpm create mode 100644 wmisdn/xpm/outgoing.xpm create mode 100644 wmisdn/xpm/raw.xpm create mode 100644 wmisdn/xpm/slave.xpm create mode 100644 wmisdn/xpm/unknown.xpm create mode 100644 wmisdn/xpm/voice.xpm diff --git a/wmisdn/CHANGES b/wmisdn/CHANGES new file mode 100644 index 0000000..e2db8f3 --- /dev/null +++ b/wmisdn/CHANGES @@ -0,0 +1,63 @@ +1.81 +---- + +* Removed problems with the Makefile occuring on newer systems +* minor bugfix in the command line argument scanning + +1.8 +--- + +* Scripting modes (read the SCRIPTS file) +* Channel bundling (aka MPPP) support (details in the README). +* -font cmd line option for replacing the LED-font. +* I have a new email-address: tasho.kaletha@gmx.de :)))) + +1.7p3 (by Kalus Steven: klaus.steven@gmx.net) +----- + +* Script support (read the SCRIPTS file). +* Important bugfix for Alpha workstations. +* Connection control (Online<->Offline) by clicking anywhere on the display + with the middle mouse button. + +1.7 +--- + +* separated the look&feel code from the main code. Creating different + skins is now much easier. Expect them in the next version :)) (sorry, I'm + completely out of time for now). + +1.6 +--- + +* fixed a very nasty bug which caused the handling of any device except + ippp0 to fail (ooops! sorry) +* added support for handling multiple devices (see -device option) +* wmisdn now understands all connection modes of the ippp device + - fax, voice, etc... +* extended the information showed on the info panel + +1.51 +--- + +* fixed a small bug in the interface code, causing a highlited + button to remain selected if the mouse pointer is removed out of + the window quickly + +1.5 +--- + +* major rewrite of the interface code +* look and feel change: connection control buttons and info panel + can now be toggled separately using the new switches at the lower + left corner. + +1.2 +--- + +* added a new connection state: Dialing, which denotes the + dialing phase between Offline and Online +* fixed some compilation problems with gcc 2.9.x +* cleaned up the isdn code +* switched to a meaningful versioning. 0.1 is now 1.0 :)) + diff --git a/wmisdn/COPYING b/wmisdn/COPYING new file mode 100644 index 0000000..a43ea21 --- /dev/null +++ b/wmisdn/COPYING @@ -0,0 +1,339 @@ + GNU GENERAL PUBLIC LICENSE + Version 2, June 1991 + + Copyright (C) 1989, 1991 Free Software Foundation, Inc. + 675 Mass Ave, Cambridge, MA 02139, USA + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + + Preamble + + The licenses for most software are designed to take away your +freedom to share and change it. By contrast, the GNU General Public +License is intended to guarantee your freedom to share and change free +software--to make sure the software is free for all its users. This +General Public License applies to most of the Free Software +Foundation's software and to any other program whose authors commit to +using it. (Some other Free Software Foundation software is covered by +the GNU Library General Public License instead.) You can apply it to +your programs, too. + + When we speak of free software, we are referring to freedom, not +price. Our General Public Licenses are designed to make sure that you +have the freedom to distribute copies of free software (and charge for +this service if you wish), that you receive source code or can get it +if you want it, that you can change the software or use pieces of it +in new free programs; and that you know you can do these things. + + To protect your rights, we need to make restrictions that forbid +anyone to deny you these rights or to ask you to surrender the rights. +These restrictions translate to certain responsibilities for you if you +distribute copies of the software, or if you modify it. + + For example, if you distribute copies of such a program, whether +gratis or for a fee, you must give the recipients all the rights that +you have. You must make sure that they, too, receive or can get the +source code. And you must show them these terms so they know their +rights. + + We protect your rights with two steps: (1) copyright the software, and +(2) offer you this license which gives you legal permission to copy, +distribute and/or modify the software. + + Also, for each author's protection and ours, we want to make certain +that everyone understands that there is no warranty for this free +software. If the software is modified by someone else and passed on, we +want its recipients to know that what they have is not the original, so +that any problems introduced by others will not reflect on the original +authors' reputations. + + Finally, any free program is threatened constantly by software +patents. We wish to avoid the danger that redistributors of a free +program will individually obtain patent licenses, in effect making the +program proprietary. To prevent this, we have made it clear that any +patent must be licensed for everyone's free use or not licensed at all. + + The precise terms and conditions for copying, distribution and +modification follow. + + GNU GENERAL PUBLIC LICENSE + TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION + + 0. This License applies to any program or other work which contains +a notice placed by the copyright holder saying it may be distributed +under the terms of this General Public License. The "Program", below, +refers to any such program or work, and a "work based on the Program" +means either the Program or any derivative work under copyright law: +that is to say, a work containing the Program or a portion of it, +either verbatim or with modifications and/or translated into another +language. (Hereinafter, translation is included without limitation in +the term "modification".) Each licensee is addressed as "you". + +Activities other than copying, distribution and modification are not +covered by this License; they are outside its scope. The act of +running the Program is not restricted, and the output from the Program +is covered only if its contents constitute a work based on the +Program (independent of having been made by running the Program). +Whether that is true depends on what the Program does. + + 1. You may copy and distribute verbatim copies of the Program's +source code as you receive it, in any medium, provided that you +conspicuously and appropriately publish on each copy an appropriate +copyright notice and disclaimer of warranty; keep intact all the +notices that refer to this License and to the absence of any warranty; +and give any other recipients of the Program a copy of this License +along with the Program. + +You may charge a fee for the physical act of transferring a copy, and +you may at your option offer warranty protection in exchange for a fee. + + 2. You may modify your copy or copies of the Program or any portion +of it, thus forming a work based on the Program, and copy and +distribute such modifications or work under the terms of Section 1 +above, provided that you also meet all of these conditions: + + a) You must cause the modified files to carry prominent notices + stating that you changed the files and the date of any change. + + b) You must cause any work that you distribute or publish, that in + whole or in part contains or is derived from the Program or any + part thereof, to be licensed as a whole at no charge to all third + parties under the terms of this License. + + c) If the modified program normally reads commands interactively + when run, you must cause it, when started running for such + interactive use in the most ordinary way, to print or display an + announcement including an appropriate copyright notice and a + notice that there is no warranty (or else, saying that you provide + a warranty) and that users may redistribute the program under + these conditions, and telling the user how to view a copy of this + License. (Exception: if the Program itself is interactive but + does not normally print such an announcement, your work based on + the Program is not required to print an announcement.) + +These requirements apply to the modified work as a whole. If +identifiable sections of that work are not derived from the Program, +and can be reasonably considered independent and separate works in +themselves, then this License, and its terms, do not apply to those +sections when you distribute them as separate works. But when you +distribute the same sections as part of a whole which is a work based +on the Program, the distribution of the whole must be on the terms of +this License, whose permissions for other licensees extend to the +entire whole, and thus to each and every part regardless of who wrote it. + +Thus, it is not the intent of this section to claim rights or contest +your rights to work written entirely by you; rather, the intent is to +exercise the right to control the distribution of derivative or +collective works based on the Program. + +In addition, mere aggregation of another work not based on the Program +with the Program (or with a work based on the Program) on a volume of +a storage or distribution medium does not bring the other work under +the scope of this License. + + 3. You may copy and distribute the Program (or a work based on it, +under Section 2) in object code or executable form under the terms of +Sections 1 and 2 above provided that you also do one of the following: + + a) Accompany it with the complete corresponding machine-readable + source code, which must be distributed under the terms of Sections + 1 and 2 above on a medium customarily used for software interchange; or, + + b) Accompany it with a written offer, valid for at least three + years, to give any third party, for a charge no more than your + cost of physically performing source distribution, a complete + machine-readable copy of the corresponding source code, to be + distributed under the terms of Sections 1 and 2 above on a medium + customarily used for software interchange; or, + + c) Accompany it with the information you received as to the offer + to distribute corresponding source code. (This alternative is + allowed only for noncommercial distribution and only if you + received the program in object code or executable form with such + an offer, in accord with Subsection b above.) + +The source code for a work means the preferred form of the work for +making modifications to it. For an executable work, complete source +code means all the source code for all modules it contains, plus any +associated interface definition files, plus the scripts used to +control compilation and installation of the executable. However, as a +special exception, the source code distributed need not include +anything that is normally distributed (in either source or binary +form) with the major components (compiler, kernel, and so on) of the +operating system on which the executable runs, unless that component +itself accompanies the executable. + +If distribution of executable or object code is made by offering +access to copy from a designated place, then offering equivalent +access to copy the source code from the same place counts as +distribution of the source code, even though third parties are not +compelled to copy the source along with the object code. + + 4. You may not copy, modify, sublicense, or distribute the Program +except as expressly provided under this License. Any attempt +otherwise to copy, modify, sublicense or distribute the Program is +void, and will automatically terminate your rights under this License. +However, parties who have received copies, or rights, from you under +this License will not have their licenses terminated so long as such +parties remain in full compliance. + + 5. You are not required to accept this License, since you have not +signed it. However, nothing else grants you permission to modify or +distribute the Program or its derivative works. These actions are +prohibited by law if you do not accept this License. Therefore, by +modifying or distributing the Program (or any work based on the +Program), you indicate your acceptance of this License to do so, and +all its terms and conditions for copying, distributing or modifying +the Program or works based on it. + + 6. Each time you redistribute the Program (or any work based on the +Program), the recipient automatically receives a license from the +original licensor to copy, distribute or modify the Program subject to +these terms and conditions. You may not impose any further +restrictions on the recipients' exercise of the rights granted herein. +You are not responsible for enforcing compliance by third parties to +this License. + + 7. If, as a consequence of a court judgment or allegation of patent +infringement or for any other reason (not limited to patent issues), +conditions are imposed on you (whether by court order, agreement or +otherwise) that contradict the conditions of this License, they do not +excuse you from the conditions of this License. If you cannot +distribute so as to satisfy simultaneously your obligations under this +License and any other pertinent obligations, then as a consequence you +may not distribute the Program at all. For example, if a patent +license would not permit royalty-free redistribution of the Program by +all those who receive copies directly or indirectly through you, then +the only way you could satisfy both it and this License would be to +refrain entirely from distribution of the Program. + +If any portion of this section is held invalid or unenforceable under +any particular circumstance, the balance of the section is intended to +apply and the section as a whole is intended to apply in other +circumstances. + +It is not the purpose of this section to induce you to infringe any +patents or other property right claims or to contest validity of any +such claims; this section has the sole purpose of protecting the +integrity of the free software distribution system, which is +implemented by public license practices. Many people have made +generous contributions to the wide range of software distributed +through that system in reliance on consistent application of that +system; it is up to the author/donor to decide if he or she is willing +to distribute software through any other system and a licensee cannot +impose that choice. + +This section is intended to make thoroughly clear what is believed to +be a consequence of the rest of this License. + + 8. If the distribution and/or use of the Program is restricted in +certain countries either by patents or by copyrighted interfaces, the +original copyright holder who places the Program under this License +may add an explicit geographical distribution limitation excluding +those countries, so that distribution is permitted only in or among +countries not thus excluded. In such case, this License incorporates +the limitation as if written in the body of this License. + + 9. The Free Software Foundation may publish revised and/or new versions +of the General Public License from time to time. Such new versions will +be similar in spirit to the present version, but may differ in detail to +address new problems or concerns. + +Each version is given a distinguishing version number. If the Program +specifies a version number of this License which applies to it and "any +later version", you have the option of following the terms and conditions +either of that version or of any later version published by the Free +Software Foundation. If the Program does not specify a version number of +this License, you may choose any version ever published by the Free Software +Foundation. + + 10. If you wish to incorporate parts of the Program into other free +programs whose distribution conditions are different, write to the author +to ask for permission. For software which is copyrighted by the Free +Software Foundation, write to the Free Software Foundation; we sometimes +make exceptions for this. Our decision will be guided by the two goals +of preserving the free status of all derivatives of our free software and +of promoting the sharing and reuse of software generally. + + NO WARRANTY + + 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY +FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN +OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES +PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED +OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF +MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS +TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE +PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, +REPAIR OR CORRECTION. + + 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING +WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR +REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, +INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING +OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED +TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY +YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER +PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE +POSSIBILITY OF SUCH DAMAGES. + + END OF TERMS AND CONDITIONS + + Appendix: How to Apply These Terms to Your New Programs + + If you develop a new program, and you want it to be of the greatest +possible use to the public, the best way to achieve this is to make it +free software which everyone can redistribute and change under these terms. + + To do so, attach the following notices to the program. It is safest +to attach them to the start of each source file to most effectively +convey the exclusion of warranty; and each file should have at least +the "copyright" line and a pointer to where the full notice is found. + + + Copyright (C) 19yy + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + +Also add information on how to contact you by electronic and paper mail. + +If the program is interactive, make it output a short notice like this +when it starts in an interactive mode: + + Gnomovision version 69, Copyright (C) 19yy name of author + Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'. + This is free software, and you are welcome to redistribute it + under certain conditions; type `show c' for details. + +The hypothetical commands `show w' and `show c' should show the appropriate +parts of the General Public License. Of course, the commands you use may +be called something other than `show w' and `show c'; they could even be +mouse-clicks or menu items--whatever suits your program. + +You should also get your employer (if you work as a programmer) or your +school, if any, to sign a "copyright disclaimer" for the program, if +necessary. Here is a sample; alter the names: + + Yoyodyne, Inc., hereby disclaims all copyright interest in the program + `Gnomovision' (which makes passes at compilers) written by James Hacker. + + , 1 April 1989 + Ty Coon, President of Vice + +This General Public License does not permit incorporating your program into +proprietary programs. If your program is a subroutine library, you may +consider it more useful to permit linking proprietary applications with the +library. If this is what you want to do, use the GNU Library General +Public License instead of this License. diff --git a/wmisdn/INSTALL b/wmisdn/INSTALL new file mode 100644 index 0000000..12a373b --- /dev/null +++ b/wmisdn/INSTALL @@ -0,0 +1,52 @@ +Compiling and installing wmisdn: +-------------------------------- + +1. Change to the directory containing the wmisdn source +2. Type "make" +3. Copy the wmisdn binary to a directory of your choice +or + Type "make install" - this puts wmisdn into /usr/local/sbin +4. Type "make clean" to clean the source directory + +NOTE : In order to operate properly, wmisdn must have access to +/dev/isdnctrl and /dev/isdninfo. There are two ways to grant this access, both +of which require root privileges: + +I. The simple method: + 1. Login as root + 2. Change to the directory where the wmisdn binary resides + 3. Type "chown root.root wmisdn" + 4. Type "chmod +s wmisdn" + +II. The secure method: + 1. Login as root + 2. Create a group called net (or whatever name you like) + 3. Add the accounts, that should be able to use wmisdn (and generally dial out or controll the isdn connection in some other way), to this group + 4. Type "chgrp net /dev/isdninfo /dev/isdnctrl* /sbin/isdnctrl" + 5. Type "chmod g=rw /dev/isdninfo /dev/isdnctrl*" + +I recommend the second method, since it protects your systems against bug +exploits in wmisdn (I hope they don't exist, but I can't guarantee that to 100%). +It is the method recommended by Tom Berger on his site "www.mandrakeuser.org" +(/connect/cisdn2.html). + + +wmisdn currently compiles only under Linux. I have tested it on +* SuSE 6.0 - Kernel 2.0.36, glibc 2.0.7, XFree 3.3.4 +* SuSE 6.2 - Kernel 2.2.10, glibc 2.1, XFree 3.3.4 +It has been reported to work on RedHat and Mandrake systems too and should +actually compile and run on every Linux system with the kernel includes and +isdn4linux on it. + +If you use WindowMaker, useful options for the info panel of the extended +look are: + NoTitlebar = Yes; + NoResizebar = Yes; + NoCloseButton = Yes; + NoMiniaturizeButton = Yes; + Omnipresent = Yes; + SkipWindowList = Yes; + +You can set those in Windowmaker or in any other window manager that +supports them. Quite a shame, but I still haven't found an X function that +sets those attributes. I'd appreciate a mail if there is such function. diff --git a/wmisdn/Makefile b/wmisdn/Makefile new file mode 100644 index 0000000..89985cf --- /dev/null +++ b/wmisdn/Makefile @@ -0,0 +1,30 @@ +LIBDIR = -L/usr/X11R6/lib +LIBS = -lXpm -lXext -lX11 +OBJS = wmisdn.o regions.o +HS = optics/optics.h +VER = 1.81 +DIR = wmisdn-$(VER) + +.cc.o: + g++ -c -Wall -DVER=$(VER) $< -o $*.o + +wmisdn: $(OBJS) + g++ -o wmisdn $^ $(LIBDIR) $(LIBS) + +install:: wmisdn + install -d /usr/local/sbin/ + install -s -o root -g root -m 0700 wmisdn /usr/local/sbin/wmisdn + install -d /usr/local/doc/wmisdn/ + install -m 0644 CHANGES COPYING README /usr/local/doc/wmisdn/ + +clean:: + for i in $(OBJS); do rm -f $$i; done + rm -f wmisdn + rm -f *~ + +dist:: + cd ../ ; tar --exclude=$(DIR)/stuff --exclude=$(DIR)/dist -c $(DIR)/ | gzip -c > $(DIR)/dist/wmisdn-$(VER).tgz + +build:: + make clean + make diff --git a/wmisdn/README b/wmisdn/README new file mode 100644 index 0000000..fb09658 --- /dev/null +++ b/wmisdn/README @@ -0,0 +1,180 @@ +This is wmisdn version 1.81 +*************************** + +(if you're already familiar with wmisdn, you may want to check the CHANGES + file instead) + +What it is about and how to use it: +----------------------------------- + +wmisdn is a small isdn monitor that can be docked on the WindowMaker dock, +the Afterstep Wharf or KDE2 kappdock, or used in any other window manager as a +standalone window app. It gives some information about a specified ippp +device and lets the user control the connection. +wmisdn supports all current connection modes of an ippp device +(as of Kernel 2.2.10) + +off - the ippp defice has no connection and dialing is disabled +offline - the ippp device has no connection and is ready to dial +dialing - the ippp device is trying to establish a connection + +online - the ippp device is connected to a ppp server +fax - ippp serving fax call +voice - ippp serving voice call +modem - ippp working as a modem device +raw - ippp working as a raw device + +Every of the 5 connection states that indicate a connection mode has two +modes - incoming and outgoing. + +Additional information about the connection is displayed on a panel toggled +by the small horizontal arrow located on the lower left corner of the main +window. It containts the local and remote ip of the connection, the peer phone +number and channel bundling information. + +Connection control: +~~~~~~~~~~~~~~~~~~~ +The connection can be controlled using the three buttons on the upper side of +the main window. The can be toggled either using the small vertical arrow on +the lower left corner or using the -lamps command line option (see below). +The buttons are green, yellow and red. The yellow one cuts the current connection. +The red one does the same, as well as disabling the dialing for the specified +device. The green one triggers the dialing for the specified device. + +For those of you who find the lamps to be too small and hard to hit :)) - use +the middle mouse button anywhere on the status display to trigger the +connection on/off. + +Channel bundling (aka MPPP): +~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +If the device shown is a master mppp device (for channel bundling), then the +left mouse button is used to control the master connection and the right mouse +button is used to control the slave connection, i.e. if ippp1 is shown and it +is the master device of ippp2, then pressing the green lamp with the left +mouse button starts the connection of ippp1 (master) while the right mouse +button starts the connection of ippp2 (slave). The same applies to the yellow +lamp. +Please note that starting a slave connection while the master is offline +automatically starts the master connection too. Respectively: stopping the +master connection while the slave is on autimatically stops the slave too. +Another useful thing to know is that you can start/stop your slave connection +while the master connection is on without corrupting any downloads in progress. +The only effect you notice is that your connection becomes faster or slower, +and a small label "bundled" beneath the status display. + +NOTE: You must have configured your ISDN system for channel bundling for these + features to work. + + +Multiple devices: +~~~~~~~~~~~~~~~~~ +As of version 1.7, wmisdn can handle different devices, which can be toggled +by pressing on the device name at the lower right corner of the main window. + + +Compiling and installing: +------------------------- +If you downloaded wmisdn as a binary, just put it anywhere you want. I'd +recommend /usr/local/bin, but it's only a matter of taste, as long as your +system knows where it is. Please note, that as wmisdn highly depends on the +kernel (especially on the isdn4linux subsystem), a downloaded binary may not +work for your system. In this case, you should use the source. + +Detailed instructions for configuring your system (i.e. permissions for device +files etc) as well as compiling from source can be found in the INSTALL file. + +Command line options: +--------------------- + +Use the -w option if you want to dock wmisdn into the Windowmaker dock. +The -s option is useful for Afterstep and other dock-enabled window managers. + +The -dialmode option tells wmisdn which dialmode to use for the device when +the user presses the yellow button requesting that the connection (if any) +is stopped and the dialing is enabled. You can use 'auto' for enabling the +autodialing feature of i4l or manual. If the option is not present wmisdn +tries to get the current setting from the device. If the device's dialmode +setting is set to 'off', indicating that the device has been disabled, the +defualt setting 'auto' is assumed. + +The -device option tells which ippp devices should be monitored. The devices +are expected as a comma separated list of device names with NO BLANKS in it, +i.e. "-device ippp0,ippp1,ippp5". The order of the device names is not +important. On most systems the only configured device is ippp0 and this is +the default setting if none specified. +If you want to monitor a slave device (for mppp), you should also specify +it using this option. + +The -lamps option causes the connection control buttons to be displayed +directly upon startup, as if some magic hand has pressed the +vertical-arrow-button that toggles them. It is intended for users who need +them permanently. If you have set the hangup timeouts and the default routes +properly, so that dialing and hanging up is performed automatically, you +won't need the control buttons very often and since I find that wmisdn looks +better without them, they don't appear on the default display mode. + +The -font option can be used to specify a different font for the info window +and the device display (the default font is the LED-builtin). The font name +must follow the X11 font naming conventions and must be placed in quotation +marks (take a look at xfontsel if you don't know the font names on your +system). + +The -usescripts and -path options deal with the scripting feature of wmisdn. +For more information, read the SCRIPTS file. + +If it doesn't work: +------------------- + +If wmisdn starts and doesn't do what is expected, then take a look at your +syslog messages. In most cases, there will be an error message. Check if the +user rights are set properly (as explained above). +Check your device using the isdnctrl and ifconfig commands. + +Bugs, suggestions, etc.: +------------------------ + +There surely are some. I'm currently not aware of any, so feel free to mail +me bug reports and suggestions. If you mail a bug report, please +include the output of the following commands: + +ifconfig +isdnctrl list +cc -v +uname -a + +as well as the name of the Linux distribution you are using. + +If you are missing features like real time packet flow graphs or load +diagrams then take a look at wmifs or wmnd. These are really fine applets +that implement these features for any network device, not only ippp and +since they work fine and look good, I'm not planning to implement the same +things in wmisdn. + +Credits: +-------- + +Klaus Steven - he did a lot of work for bringing 1.7 to 1.8, especially + an importang bugfix for wmisdn/aplha and the scripting + feature, and gave me good ideas and advises throughout +Tom Berger - for helping me with the very early version of wmisdn (0.1 :)) + and giving good ideas (Dialing mode, etc) +Philip Lehman - skins for wmisdn (coming soon :) +Torsten Hilbrich - status check patch +Jogi - command line args parsing patch + +and many others for their support and suggestions + + +And: +---- + +Enjoy! Please mail me if you find the program useful so I can know if +I should keep maintaining it. + +--------------------------------- + + Tasho + + tasho.kaletha@gmx.de + + diff --git a/wmisdn/SCRIPTS b/wmisdn/SCRIPTS new file mode 100644 index 0000000..502d900 --- /dev/null +++ b/wmisdn/SCRIPTS @@ -0,0 +1,52 @@ +This file concerns the usage of scripts with wmisdn. +---------------------------------------------------- + + +NOTE: The wmisdn scripting is ONLY for ADVANCED unix users. I can't give any + support for user-made scripts. + + +Ok, if you're still here, then you know what you're doing, so I won't go into +details explaining well known things about Linux. + +As of version 1.8, wmisdn can use scripts to control the connection instead of +direct ioctl calls. If you want to use scripts, then put the "-usescripts" +option on the command line. The three files used by wmisdn are + +wmisdn-up +wmisdn-down +wmisdn-scriptmodes + +They must be located in /etc/isdn/, or in a directory specified by the +"-path" command line option. + +The first two are called when the green resp. yellow lamp is pressed. These +two scripts recieve two parameters. The first one is the name of the +ippp-device and the second is the script mode. + +The script mode is an integer, which corresponds to a line in the file +wmisdn-scriptmodes. Every line in this file defines one script mode - the first +line is mode 0, the second - mode 1, and so on. The contents of each line is +used as a user-friendly name for the script mode and is displayed on the info +window. The script modes are changed by pressing the green control lamp with +the middle mouse button. + +A sample wmisdn-scriptmodes might look like + +go online +check mail +update web-page + +where the wmisdn-up script uses the second command line argument to differ +between these modes (0,1 or 2 resp.). The -up/-down scripts should contain +the line +/usr/sbin/isdnctrl dial $1 +or +/usr/sbin/isdnctrl hangup $1 +respectively. + +I might consider putting some scripts on my web-page in the near future. I'd +also wellcome any user-made working scripts. + +Good luck and have fun! +Tasho diff --git a/wmisdn/optics/optics.h b/wmisdn/optics/optics.h new file mode 100644 index 0000000..9d435b9 --- /dev/null +++ b/wmisdn/optics/optics.h @@ -0,0 +1,37 @@ + +#ifndef _OPTICS_H +#define _OPTICS_H + + +struct position +{ + int x, y; +}; + +struct dimension +{ + int w, h; +}; + +struct rect +{ + position pos; + dimension dim; +}; + +static dimension MainWinDim = { 64, 64 }; +static dimension InfoWinDim = { 164, MainWinDim.h }; +static rect StatusPixmapRect = { { 5, 15 }, { 55, 30 } }; +static rect DirectionPixmapRect = { { 5, 33 }, { 55, 12 } }; +static dimension LedDim = { 6, 8 }; +static rect LampsRect[3] = { { {7,6}, {10,10} }, { {27,6}, {10,10} }, { {47,6}, {10,10} } }; +static rect InfoSWRect = { { 8, 48 }, { 10, 8 } }; +static rect LampsSWRect = { { 18, 48 }, { 10, 8 } }; +static rect DeviceRect = { { 30, 48}, { MainWinDim.w-30-2,LedDim.h } }; + +static char WindowBackgroundColor[] = "#202020"; +static char DeviceColorHigh[] = "#3ddeff"; +static char DeviceColorLow[] = "#007bff"; +static char InfoTextColor[] = "#167ce2"; + +#endif diff --git a/wmisdn/optics/optics.h~ b/wmisdn/optics/optics.h~ new file mode 100644 index 0000000..c101e1b --- /dev/null +++ b/wmisdn/optics/optics.h~ @@ -0,0 +1,37 @@ + +#ifndef _OPTICS_H +#define _OPTICS_H + + +struct position +{ + int x, y; +}; + +struct dimension +{ + int w, h; +}; + +struct rect +{ + position pos; + dimension dim; +}; + +static dimension MainWinDim = { 64, 64 }; +static dimension InfoWinDim = { 164, MainWinDim.h }; +static rect StatusPixmapRect = { { 5, 15 }, { 55, 30 } }; +static rect DirectionPixmapRect = { { 5, 33 }, { 12, 30 } }; +static dimension LedDim = { 6, 8 }; +static rect LampsRect[3] = { { {7,6}, {10,10} }, { {27,6}, {10,10} }, { {47,6}, {10,10} } }; +static rect InfoSWRect = { { 8, 48 }, { 10, 8 } }; +static rect LampsSWRect = { { 18, 48 }, { 10, 8 } }; +static rect DeviceRect = { { 30, 48}, { MainWinDim.w-30-2,LedDim.h } }; + +static char WindowBackgroundColor[] = "#202020"; +static char DeviceColorHigh[] = "#3ddeff"; +static char DeviceColorLow[] = "#007bff"; +static char InfoTextColor[] = "#167ce2"; + +#endif diff --git a/wmisdn/regions.cc b/wmisdn/regions.cc new file mode 100644 index 0000000..b01ed7d --- /dev/null +++ b/wmisdn/regions.cc @@ -0,0 +1,153 @@ +#include +#include +#include "regions.h" + +struct region +{ + int id; + int x, y, w, h; + bool enabled; + + void (*mouse_in)( int ); + void (*mouse_out)( int ); + void (*mouse_click)( int, unsigned int ); + + struct region *next; +}; + +struct regioned_window +{ + Window win; + struct region *first_reg; + struct regioned_window *next; +}; + + +static struct regioned_window *regioned_windows=NULL; +static Display *dpy=NULL; + + +static struct region *region_locate( Window win, int x, int y ); +static struct region *region_find( Window win, int id ); +static struct regioned_window *region_get_win( Window win ); + +void region_init( Display *_dpy ) +{ + dpy = _dpy; +} + +void region_add( Window win, int id, int x, int y, int w, int h, + void (*mouse_in)(int), void (*mouse_out)(int), void (*mouse_click)(int, unsigned int) ) +{ + /* cerate the region and set its fields */ + struct region *reg = new region; + reg->id = id; + reg->x = x; + reg->y = y; + reg->w = w; + reg->h = h; + reg->enabled = true; + reg->mouse_in = mouse_in; + reg->mouse_out = mouse_out; + reg->mouse_click = mouse_click; + + /* find the regioned_win and insert the new region into its list of regions */ + struct regioned_window *reg_win = region_get_win(win); + reg->next = reg_win->first_reg; + reg_win->first_reg = reg; +} + +void region_enable( Window win, int id ) +{ + struct region *reg = region_find( win, id ); + if( reg != NULL ) + reg->enabled = true; +} + +void region_disable( Window win, int id ) +{ + struct region *reg = region_find( win, id ); + if( reg != NULL ) + reg->enabled = false; +} + + +bool region_in( Window win, int x, int y ) +{ + return (region_locate(win,x,y) != NULL); +} + +void region_mouse_motion( Window win, int x, int y ) +{ + struct region *reg; + static struct region *last_active_reg=NULL; + reg = region_locate( win, x, y ); + if( reg == last_active_reg ) + return; + if( last_active_reg != NULL ) + { + last_active_reg->mouse_out( last_active_reg->id ); + XUngrabPointer( dpy, CurrentTime ); + } + if( reg != NULL ) + { + reg->mouse_in( reg->id) ; + XGrabPointer( dpy, win, true, PointerMotionMask|ButtonPress, GrabModeAsync, GrabModeAsync, None, None, CurrentTime ); + } + last_active_reg = reg; +} + +void region_mouse_click( Window win, int x, int y, unsigned int button ) +{ + struct region *reg; + region_mouse_motion( win, x, y ); + if( (reg=region_locate(win,x,y)) != NULL ) + reg->mouse_click(reg->id, button); +} + +static struct region *region_locate( Window win, int x, int y ) +{ + struct region *reg = region_get_win(win)->first_reg; + + while( reg != NULL ) + { + if( (x >= reg->x) && (x <= reg->x+reg->w) && + (y >= reg->y) && (y <= reg->y+reg->h ) && + reg->enabled ) + return reg; + reg = reg->next; + } + return NULL; +} + +static struct region *region_find( Window win, int id ) +{ + struct region *reg = region_get_win(win)->first_reg; + + while( reg != NULL ) + { + if( reg->id == id ) + return reg; + reg = reg->next; + } + return NULL; +} + +static struct regioned_window *region_get_win( Window win ) +{ + struct regioned_window *reg_win = regioned_windows; + + while( reg_win != NULL ) + { + if( reg_win->win == win ) + return reg_win; + reg_win = reg_win->next; + } + + reg_win = new regioned_window; + reg_win->win = win; + reg_win->first_reg = NULL; + reg_win->next = regioned_windows; + regioned_windows = reg_win; + return reg_win; +} diff --git a/wmisdn/regions.h b/wmisdn/regions.h new file mode 100644 index 0000000..69730c3 --- /dev/null +++ b/wmisdn/regions.h @@ -0,0 +1,18 @@ + +#ifndef _REGIONS_H +#define _REGIONS_H + +#include + +void region_init( Display *dpy ); + +void region_add( Window win, int id, int x, int y, int w, int h, + void (*mouse_in)(int), void (*mouse_out)(int), void (*mouse_click)(int, unsigned int) ); + +void region_enable( Window win, int id ); +void region_disable( Window win, int id ); +bool region_in( Window win, int x, int y ); +void region_mouse_motion( Window win, int x, int y ); +void region_mouse_click( Window win, int x, int y, unsigned int button ); + +#endif diff --git a/wmisdn/wmisdn.cc b/wmisdn/wmisdn.cc new file mode 100644 index 0000000..19f71b0 --- /dev/null +++ b/wmisdn/wmisdn.cc @@ -0,0 +1,1608 @@ +/* wmisdn - an ISDN monitor applet for windowmaker/afterstep + * Copyright (c) 2000-2001 Tasho Statev Kaletha + * tasho.kaletha@gmx.de + * + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + + +/* these defaults can be changed by command line options. */ +#define WINDOWMAKER false +#define USESHAPE false +#define NAME "wmisdn" +#define CLASS "WMIsdn" + +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include /* for ENOTCONN */ +#include + +#include +#include +#include +#include +#include +#include + +#include +#include +#include + +#include "regions.h" +#include "optics/optics.h" + +static Pixmap coverPixmap; +static Pixmap unknownPixmap; +static Pixmap dialingPixmap; +static Pixmap offPixmap; +static Pixmap disabledPixmap; +static Pixmap statusPixmaps[6]; +static Pixmap incomingPixmap, outgoingPixmap, bundlingPixmap, bundledPixmap, slavePixmap; + + +static Pixmap ledsPixmap; /* a row of led symbols as shown by the var led_text below */ +static Pixmap lampsPixmap; /* a row of lamp images - green off, green on, yellow off, yellow on, red off, red on */ +static Pixmap infoSWPixmap; /* a row of arrows - left off, left on, right off, right on */ +static Pixmap lampsSWPixmap; /* a row of arrows - up off, up on, down off, down on */ + +#include "xpm/unknown.xpm" +#include "xpm/disabled.xpm" +#include "xpm/off.xpm" +#include "xpm/offline.xpm" +#include "xpm/dialing.xpm" +#include "xpm/incoming.xpm" +#include "xpm/outgoing.xpm" +#include "xpm/bundling.xpm" +#include "xpm/bundled.xpm" +#include "xpm/slave.xpm" +#include "xpm/raw.xpm" +#include "xpm/modem.xpm" +#include "xpm/online.xpm" +#include "xpm/voice.xpm" +#include "xpm/fax.xpm" + +#include "xpm/cover.xpm" +#include "xpm/leds.xpm" +#include "xpm/lamps.xpm" +#include "xpm/lamps_sw.xpm" +#include "xpm/info_sw.xpm" + +/* Runtime pixmaps */ +static Pixmap disp_info; /* double buffer for the info panel */ +static Pixmap disp; /* for the main window */ +static Pixmap dmsk; /* clip mask for the main window */ + +/* For command line arguments */ +#define MAX_ARG_LEN 256 +static bool wmaker = WINDOWMAKER; +static bool ushape = USESHAPE; +static char txtdpy[MAX_ARG_LEN] = ""; +static char txtfont[MAX_ARG_LEN] = ""; +static int dialmode = ISDN_NET_DM_AUTO; +static char devices[ISDN_MAX_CHANNELS][MAX_ARG_LEN]; +static int selected_device=-1; /* selected device, points to an element of devices[] */ +static char scriptpath[MAX_ARG_LEN] = "/etc/isdn"; +static int scriptmode = 0; +static bool usescripts = false; +static int maxscriptmode = 0; +static char** scriptmodestrings = NULL; +static char *slave_pending = NULL; + +/* atoms for deleting window */ +static Atom _XA_GNUSTEP_WM_FUNC; +static Atom WM_DELETE_WINDOW; + +/* global variables */ +Display *dpy; +Window Win[3]; /* 0 - main win, 1 - icon win (for wmaker), 2 - info panel */ +Window Root; +GC WinGC; +int activeWin; +XFontStruct *textFont=NULL; + +static char led_text[] = "0123456789?/\\!@#$%^&*()_+-=\"~<>[]{}:. abcdefghijklmnopqrstuvwxyz"; + + +static int rootUID, rootGID; +static bool infoPanelActive = false; +static bool lampsActive = false; + +/* Der scriptmode wird als 2. Argument den Start-/Stopskripten uebergeben. + Aenderung mit mittlerer Maustaste auf InfoSw bei offenem Infopanel. */ + +#define ACTIVE 1 /* values are not only symbolc, but important for calculations! */ +#define INACTIVE 0 +#define ID_LAMP_GREEN 0 +#define ID_LAMP_YELLOW 1 +#define ID_LAMP_RED 2 + +#define ID_SWITCH_INFO 10 +#define ID_SWITCH_LAMPS 11 +#define ID_SWITCH_STATUS 19 +#define ID_DEVICE 20 + +#define UPDATE_INTERVAL 20 /* how many 50 milisec intervalls to wait between updates */ +#define STATUS_WARNING_SAT 5 /* how many times to display a warning upon failing to retrieve device stats */ + +#define INCOMING 0 +#define OUTGOING 1 +#define STAT_DISABLED 1000 +#define STAT_OFF 1001 +#define STAT_DIALING 1002 +#define STAT_UNKNOWN 2001 +#define STAT_UNINITIALIZED 2002 + +#define SCRIPT_UP "wmisdn-up" +#define SCRIPT_DOWN "wmisdn-down" +#define SCRIPT_MODES "wmisdn-scriptmodes" + +typedef enum mpppModeType { none, master, slave }; + +struct isdnStatus +{ + int usage; + int direction; + bool bundled; + char peerPhone[100]; + mpppModeType mpppMode; + char mpppPartner[100]; +} curStatus = { STAT_UNINITIALIZED, INCOMING, false, "", none, "" }; + + + +/* text i/o routines */ +bool scanArgs(int argc, char *argv[]); +void printUsage( char *prog_name ); +void printHeader(); +void parseDeviceNames( char *name_list ); +void readScriptModes(); + + +/* init/done routines */ +void initXWin(int argc, char *argv[]); +void freeXWin(); +void createMainWin( Window *win ); +void createInfoPanel( Window *win ); +void loadPixmaps(); +void freePixmaps(); +void createRegions(); + + +/* window routines */ +void alignInfoPanel(); +void getWindowPosition( Window win, int *x, int *y ); +void getWindowDimension( Window win, int *w, int *h ); + +/* graphic routines */ +unsigned long getColor(const char *colorname); +void createPixmap(char *data[], Pixmap *image, Pixmap *mask ); +void loadLeds(char *data[], Pixmap *image, const char *leds_color, const char *back_color ); +void drawText( char *text, Pixmap dst, int x, int y, const char *color=InfoTextColor ); +void drawLamp( int index, int active ); +void drawDevice( int active = INACTIVE ); +unsigned long mixColor( const char *colorname1, int prop1, const char *colorname2, int prop2); + +/* interaction routines */ +bool timeToUpdate(); +void update(); +void fullRepaint(); +void repaint( Window win, int x, int y, int w, int h ); +void setStatusPixmap(); +void updateInfoPanel(); +void blankMainWin( int x=0, int y=0, int w=MainWinDim.w, int h=MainWinDim.h ); +void pressLamp( int lamp, int button ); +void pressStatusSw(); +void activateLamps( bool active ); +void drawSwitches(); + +/* region event handlers */ +void mouseInLamp( int id ); +void mouseOutLamp( int id ); +void mouseClickLamp( int id, unsigned int button ); +void mouseInInfoSw( int id ); +void mouseOutInfoSw( int id ); +void mouseClickInfoSw( int id, unsigned int button ); +void mouseInLampsSw( int id ); +void mouseOutLampsSw( int id ); +void mouseClickLampsSw( int id, unsigned int button ); +void mouseInDevice( int id ); +void mouseOutDevice( int id ); +void mouseClickDevice( int id, unsigned int button ); +void mouseInStatusSw( int id ); +void mouseOutStatusSw( int id ); +void mouseClickStatusSw( int id, unsigned int button ); + + +void selectNextDevice(); + +/* event handlers */ +void exposeEvent( XExposeEvent *xev); +void pressEvent(XButtonEvent *xev); +void motionEvent( XMotionEvent *xev ); + +/* ISDN routines */ +void getStatus( char *device, isdnStatus *stat ); +void getLocalIP( int *a, int *b, int *c, int *d ); +inline void getRemoteIP( int *a, int *b, int *c, int *d ); +inline void translateIP( struct sockaddr *addr, int *a, int *b, int *c, int *d ); +int isdn_ioctl( int func, void *arg, const char *errmsg, const char *filename="/dev/isdnctrl" ); +void isdnInitDefaultDialmode(); +int getIpppNum( char *name ); + +inline void set_slave_pending(); +inline void clear_slave_pending(); +inline bool is_slave_pending(); +inline void manage_slave(); + +/* -------- Implementation ----------- */ + +int main(int argc, char *argv[]) +{ + + rootUID = geteuid(); rootGID = getegid(); + seteuid(getuid()); setegid(getgid()); + + printHeader(); + if( !scanArgs(argc, argv) ) + { + printUsage( argv[0] ); + return 1; + } + readScriptModes(); + + initXWin(argc, argv); + + loadPixmaps(); + createRegions(); + disp = XCreatePixmap(dpy, Root, MainWinDim.w, MainWinDim.h, DefaultDepth(dpy,DefaultScreen(dpy))); + disp_info = XCreatePixmap(dpy, Root, InfoWinDim.w, InfoWinDim.h, DefaultDepth(dpy,DefaultScreen(dpy))); + + XGCValues gcv; + unsigned long gcm; + gcm = GCGraphicsExposures|GCBackground; + gcv.graphics_exposures = True; + gcv.background = getColor( WindowBackgroundColor ); + if( strlen(txtfont) != 0 ) + { + textFont = XLoadQueryFont( dpy, txtfont ); + if( textFont != NULL ) + { + gcm |= GCFont; + gcv.font = textFont->fid; + } else + syslog( LOG_NOTICE, "Couldn't load specified font" ); + } + WinGC = XCreateGC(dpy, Root, gcm, &gcv); + + blankMainWin(); + drawDevice(INACTIVE); + activateLamps( lampsActive ); + drawSwitches(); + update(); + + if(!(wmaker || ushape)) + XSetClipMask(dpy, WinGC, dmsk); + else + XShapeCombineMask(dpy, Win[activeWin], ShapeBounding, 0, 0, dmsk, ShapeSet); + + XSetClipOrigin(dpy, WinGC, 0, 0); + XSetClipMask(dpy, WinGC, None); + + XEvent event; + XSelectInput(dpy, Win[activeWin], PointerMotionMask | ButtonPress | ExposureMask); + XSelectInput(dpy, Win[2], ExposureMask ); + XMapWindow(dpy, Win[0]); + + bool finished=false; + while(!finished){ + while(XPending(dpy)){ + XNextEvent(dpy,&event); + switch(event.type){ + case ButtonPress : pressEvent(&event.xbutton); break; + case MotionNotify : motionEvent(&event.xmotion); break; + + case ClientMessage : + if((Atom)event.xclient.data.l[0]==WM_DELETE_WINDOW) + finished=true; + break; + + case Expose : exposeEvent( &event.xexpose ); break; + } + } + if( timeToUpdate() ) + { + update(); + manage_slave(); + } + usleep(50000); + } + + if( textFont != NULL ) + XFreeFont( dpy, textFont ); + XFreeGC(dpy, WinGC); + freePixmaps(); + /* Free runtime pixmaps */ + XFreePixmap(dpy, disp_info); + XFreePixmap(dpy, disp); + XFreePixmap(dpy, dmsk); + /* Finish with X stuff */ + freeXWin(); + return 0; +} + +void initXWin(int argc, char *argv[]) +{ + if( (dpy=XOpenDisplay(txtdpy)) == NULL ) + { + fprintf(stderr,"cannot open display!\n"); + exit(1); + } + _XA_GNUSTEP_WM_FUNC = XInternAtom(dpy, "_GNUSTEP_WM_FUNCTION", false); + WM_DELETE_WINDOW = XInternAtom(dpy, "WM_DELETE_WINDOW", false); + Root=DefaultRootWindow(dpy); + createMainWin(&Win[0]); + createMainWin(&Win[1]); + createInfoPanel( &Win[2] ); + XWMHints hints; + XSizeHints shints; + hints.window_group = Win[0]; + shints.min_width=64; + shints.min_height=64; + shints.max_width=64; + shints.max_height=64; + shints.x=0; + shints.y=0; + if(wmaker) + { + hints.initial_state = WithdrawnState; + hints.icon_window = Win[1]; + hints.flags = WindowGroupHint | StateHint | IconWindowHint; + shints.flags = PMinSize | PMaxSize | PPosition; + activeWin=1; + } + else { + hints.initial_state = NormalState; + hints.flags = WindowGroupHint | StateHint; + shints.flags = PMinSize | PMaxSize; + activeWin=0; + } + XSetWMHints(dpy, Win[0], &hints); + XSetWMNormalHints(dpy, Win[0], &shints); + XSetCommand(dpy, Win[0], argv, argc); + XStoreName(dpy, Win[0], NAME); + XSetIconName(dpy, Win[0], NAME); + XSetWMProtocols(dpy, Win[activeWin], &WM_DELETE_WINDOW, 1); +} + +void freeXWin() +{ + XDestroyWindow(dpy, Win[0]); + XDestroyWindow(dpy, Win[1]); + XDestroyWindow(dpy, Win[2]); + XCloseDisplay(dpy); +} + +void loadPixmaps() +{ + createPixmap(cover_xpm, &coverPixmap, &dmsk ); + createPixmap(dialing_xpm, &dialingPixmap, NULL ); + createPixmap(unknown_xpm, &unknownPixmap, NULL ); + createPixmap(disabled_xpm, &disabledPixmap, NULL ); + createPixmap(off_xpm, &offPixmap, NULL ); + + createPixmap(incoming_xpm, &incomingPixmap, NULL ); + createPixmap(outgoing_xpm, &outgoingPixmap, NULL ); + createPixmap(bundling_xpm, &bundlingPixmap, NULL ); + createPixmap(bundled_xpm, &bundledPixmap, NULL ); + createPixmap(slave_xpm, &slavePixmap, NULL ); + + createPixmap(offline_xpm, &statusPixmaps[ISDN_USAGE_NONE], NULL ); + createPixmap(raw_xpm, &statusPixmaps[ISDN_USAGE_RAW], NULL ); + createPixmap(modem_xpm, &statusPixmaps[ISDN_USAGE_MODEM], NULL ); + createPixmap(online_xpm, &statusPixmaps[ISDN_USAGE_NET], NULL ); + createPixmap(voice_xpm, &statusPixmaps[ISDN_USAGE_VOICE], NULL ); + createPixmap(fax_xpm, &statusPixmaps[ISDN_USAGE_FAX], NULL ); + + createPixmap(lamps_xpm, &lampsPixmap, NULL ); + createPixmap(info_sw_xpm, &infoSWPixmap, NULL ); + createPixmap(lamps_sw_xpm, &lampsSWPixmap, NULL ); + loadLeds( leds_xpm, &ledsPixmap, InfoTextColor, WindowBackgroundColor ); +} + +void freePixmaps() +{ + XFreePixmap(dpy, coverPixmap); + XFreePixmap(dpy, dialingPixmap); + XFreePixmap(dpy, unknownPixmap); + XFreePixmap(dpy, disabledPixmap); + XFreePixmap(dpy, offPixmap); + + XFreePixmap(dpy, incomingPixmap); + XFreePixmap(dpy, outgoingPixmap); + XFreePixmap(dpy, bundlingPixmap); + XFreePixmap(dpy, bundledPixmap); + XFreePixmap(dpy, slavePixmap); + + for( int i=ISDN_USAGE_NONE; i < ISDN_USAGE_FAX; i++ ) + XFreePixmap( dpy, statusPixmaps[i] ); + + XFreePixmap(dpy, ledsPixmap); + XFreePixmap(dpy, lampsPixmap); + XFreePixmap(dpy, infoSWPixmap); + XFreePixmap(dpy, lampsSWPixmap); +} + +void createMainWin( Window *win ) +{ + *win = XCreateSimpleWindow(dpy, Root, 10, 10, MainWinDim.w, MainWinDim.h,0,0,0); + + XClassHint classHint; + classHint.res_name = NAME; + classHint.res_class = CLASS; + XSetClassHint(dpy, *win, &classHint); +} + +void createInfoPanel( Window *win ) +{ + *win = XCreateSimpleWindow(dpy, Root, 10, 10, InfoWinDim.w, InfoWinDim.h,0,0,0); + + XSizeHints shints; + shints.flags = PPosition; + XSetWMNormalHints( dpy, *win, &shints ); + + XClassHint classHint; + classHint.res_name = "Info"; + classHint.res_class = CLASS; + XSetClassHint(dpy, *win, &classHint); +} + +void createRegions() +{ + region_init(dpy); + + region_add( Win[activeWin], ID_LAMP_GREEN, LampsRect[ID_LAMP_GREEN].pos.x, LampsRect[ID_LAMP_GREEN].pos.y, LampsRect[ID_LAMP_GREEN].dim.w, LampsRect[ID_LAMP_GREEN].dim.h, mouseInLamp, mouseOutLamp, mouseClickLamp ); + region_add( Win[activeWin], ID_LAMP_YELLOW, LampsRect[ID_LAMP_YELLOW].pos.x, LampsRect[ID_LAMP_YELLOW].pos.y, LampsRect[ID_LAMP_YELLOW].dim.w, LampsRect[ID_LAMP_YELLOW].dim.h, mouseInLamp, mouseOutLamp, mouseClickLamp ); + region_add( Win[activeWin], ID_LAMP_RED, LampsRect[ID_LAMP_RED].pos.x, LampsRect[ID_LAMP_RED].pos.y, LampsRect[ID_LAMP_RED].dim.w, LampsRect[ID_LAMP_RED].dim.h, mouseInLamp, mouseOutLamp, mouseClickLamp ); + + region_add( Win[activeWin], ID_SWITCH_INFO, InfoSWRect.pos.x, InfoSWRect.pos.y, InfoSWRect.dim.w, InfoSWRect.dim.h, mouseInInfoSw, mouseOutInfoSw, mouseClickInfoSw ); + region_add( Win[activeWin], ID_SWITCH_LAMPS, LampsSWRect.pos.x, LampsSWRect.pos.y, LampsSWRect.dim.w, LampsSWRect.dim.h, mouseInLampsSw, mouseOutLampsSw, mouseClickLampsSw ); + + region_add( Win[activeWin], ID_DEVICE, DeviceRect.pos.x, DeviceRect.pos.y, DeviceRect.dim.w, DeviceRect.dim.h, mouseInDevice, mouseOutDevice, mouseClickDevice ); + region_add( Win[activeWin], ID_SWITCH_STATUS, StatusPixmapRect.pos.x, StatusPixmapRect.pos.y, StatusPixmapRect.dim.w, StatusPixmapRect.dim.h, mouseInStatusSw, mouseOutStatusSw, mouseClickStatusSw ); +} + +bool validIppp( char *name ) +{ + if( strlen(name) < 5 ) + return false; + if( strncmp( name, "ippp", 4 ) != 0 ) + return false; + for( char *p=name+4; *p != '\x0'; p++ ) + if( !isdigit(*p) ) + return false; + if( getIpppNum(name) >= ISDN_MAX_CHANNELS ) + return false; + return true; +} + +int getIpppNum( char *name ) +{ + return atoi( name + 4 ); +} + +void selectNextDevice() +{ + selected_device++; + if( devices[selected_device][0] == 0 ) + selected_device = 0; + drawDevice(); + update(); +} + +void printUsage( char *prog_name ) +{ + fprintf( stderr, "usage:\n\n %s [options]\n\noptions:\n\n", prog_name ); + fprintf( stderr, " -h | -help | --help display this help screen\n"); + fprintf( stderr, " -w use WithdrawnState (for WindowMaker)\n" ); + fprintf( stderr, " -s shaped window\n" ); + fprintf( stderr, " -display display select target display (see X manual pages)\n" ); + fprintf( stderr, " -font font select the font for displaying status information\n" ); + fprintf( stderr, " -dialmode mode select dial mode for offline mode (auto or manual)\n" ); + fprintf( stderr, " -device device select ippp devices to monitor\n" ); + fprintf( stderr, " (a list of comma-separated device names is expected containing __no blanks__)\n" ); + fprintf( stderr, " -lamps activate the line control switches upon startup\n" ); + fprintf( stderr, " -usescripts use user scripts for dialing/hanging up instead of direct ioctl calls\n" ); + fprintf( stderr, " -path path select directory with the up-/down-scripts\n\n" ); +} + +void printHeader() +{ + fprintf( stderr, "wmisdn v1.8 (C) 1999-2001 Tasho Statev Kaletha (kaletha@informatik.uni-bonn.de).\n\n" ); +} + +void parseDeviceNames( char *name_list ) +{ + char *ptr1, *ptr2; + int i; + + ptr1 = name_list; + + for( i = 0; i < ISDN_MAX_CHANNELS; i++ ) + { + ptr2 = strchr(ptr1,','); + if( ptr2 == NULL ) + ptr2 = &name_list[strlen(name_list)]; + strncpy( devices[i], ptr1, ptr2-ptr1 ); + devices[i][ptr2-ptr1] = 0; + devices[i+1][0] = 0; + if( !validIppp(devices[i]) ) + fprintf( stderr, "Warning : \"%s\" doesn't seem to be a valid ippp device. wmisdn may not work properly\n", devices[i] ); + if( ptr2[0] == 0 ) + return; + ptr1 = ptr2+1; + } +} + + +bool scanArgs(int argc, char *argv[]) +{ + bool dialmode_set = false; + + for(int i=1;i MAX_ARG_LEN-1 ) + { + fprintf( stderr, "Argument for -display option too long\n" ); + return false; + } + sprintf(txtdpy,"%s",argv[i]); + } + continue; + } + else if(strcmp(argv[i],"-font")==0) + { + if(i MAX_ARG_LEN-1 ) + { + fprintf( stderr, "Argument for -font option too long\n" ); + return false; + } + sprintf(txtfont,"%s",argv[i]); + } + continue; + } + else if(strcmp(argv[i],"-dialmode")==0) + { + if(i MAX_ARG_LEN-1 ) + { + fprintf( stderr, "Argument for -device option too long\n" ); + return false; + } + parseDeviceNames( argv[i] ); + selected_device = 0; + } + } + else if(strcmp(argv[i],"-path")==0) + { + if(i MAX_ARG_LEN-1 ) + { + fprintf( stderr, "Argument for -path option too long\n" ); + return false; + } + strcpy( scriptpath, argv[i] ); + } + } + else { + fprintf( stderr, "Unknown option \"%s\"\n", argv[i] ); + return false; + } + + } + if( !dialmode_set ) + isdnInitDefaultDialmode(); + if( selected_device == -1 ) + { + strcpy( devices[0], "ippp0" ); + devices[1][0] = 0; + selected_device = 0; + } + + return true; +} + +/* Reads the string representations of the scriptmode parameter given to the up/down scripts + * and initializes the coresponding variables */ +void readScriptModes() +{ + char filename[1000]; + char buf[1000]; + sprintf( filename, "%s/%s", scriptpath, SCRIPT_MODES ); + FILE *f = fopen( filename, "r" ); + /* init one default string if reading fails */ + if( f == NULL || (fgets(buf,sizeof(buf),f) == NULL) || !usescripts ) + { + maxscriptmode = 0; + if( usescripts ) + syslog( LOG_NOTICE, "Couldn't read script mode strings: %m" ); + scriptmodestrings = (char **)malloc( sizeof(char*) ); + scriptmodestrings[0] = (char *)malloc( sizeof("go online") ); + strcpy(scriptmodestrings[0], "go online" ); + if( f != NULL ) + fclose(f); + return; + } + maxscriptmode = -1; /* the first iteration sets it to 0 - first array index */ + + /* read the strings and put them into the scriptmodestrings array */ + do + { + maxscriptmode++; + scriptmodestrings = (char **)realloc( scriptmodestrings, (maxscriptmode+1)*sizeof(char*) ); + scriptmodestrings[maxscriptmode] = (char *)malloc( strlen(buf)+1 ); + while( strchr(buf,'\n') != NULL ) + *strchr(buf,'\n') = '\0'; + strcpy( scriptmodestrings[maxscriptmode], buf ); + } while( fgets(buf,sizeof(buf),f) != NULL ); + fclose(f); +} + +void advanceScriptMode() +{ + scriptmode++; + if(scriptmode > maxscriptmode) + scriptmode = 0; + update(); +} + +/* press event + * - if a lamp is pressed then the corresponding actions are taken. + * - outside a lamp the extended view is turned on or off + */ +void pressEvent(XButtonEvent *xev) +{ + if( region_in( xev->window, xev->x, xev->y ) ) + region_mouse_click( xev->window, xev->x, xev->y, xev->button ); +} + +/* pointer motion + * - draws a lamp in an active state if the pointer passes above it + */ +void motionEvent( XMotionEvent *xev ) +{ + region_mouse_motion( xev->window, xev->x, xev->y ); +} + +void exposeEvent( XExposeEvent *xev ) +{ + repaint( xev->window, xev->x, xev->y, xev->width, xev->height ); +} + +void alignInfoPanel() +{ + /* get the position of the main win */ + int win_x, win_y, screen_w, screen_h, panel_x, panel_y; + getWindowPosition( Win[activeWin], &win_x, &win_y ); + getWindowDimension( Root, &screen_w, &screen_h ); + /* find a suitable position for the info panel */ + if( win_x - InfoWinDim.w > 0 ) + panel_x = win_x - InfoWinDim.w; + else + panel_x = win_x + MainWinDim.w; + panel_y = win_y; + /* move the panel */ + XMoveWindow( dpy, Win[2], panel_x, panel_y ); +} + +void mouseInLamp( int id ) +{ + drawLamp( id, ACTIVE ); + for( int i=0; i < 3; i++ ) + repaint( Win[activeWin], LampsRect[i].pos.x, LampsRect[i].pos.y, LampsRect[i].dim.w, LampsRect[i].dim.h ); +} + +void mouseOutLamp( int id ) +{ + drawLamp( id, INACTIVE ); + for( int i=0; i < 3; i++ ) + repaint( Win[activeWin], LampsRect[i].pos.x, LampsRect[i].pos.y, LampsRect[i].dim.w, LampsRect[i].dim.h ); +} + +void mouseClickLamp( int id, unsigned int button ) +{ + pressLamp( id, button ); + update(); +} + +inline void drawInfoSwitch( int active ) +{ + int pixmap_index = (infoPanelActive ? 2:0) + active; + int offset_x = pixmap_index * InfoSWRect.dim.w; + XCopyArea( dpy, infoSWPixmap, disp, WinGC, offset_x, 0, InfoSWRect.dim.w, InfoSWRect.dim.h, InfoSWRect.pos.x, InfoSWRect.pos.y ); + repaint( Win[activeWin], InfoSWRect.pos.x, InfoSWRect.pos.y, InfoSWRect.dim.w, InfoSWRect.dim.h ); +} + +void mouseInInfoSw( int id ) +{ + drawInfoSwitch(ACTIVE); +} + +void mouseOutInfoSw( int id ) +{ + drawInfoSwitch(INACTIVE); +} + +void mouseClickInfoSw( int id, unsigned int button ) +{ + if( !infoPanelActive ) + { + alignInfoPanel(); + XMapWindow( dpy, Win[2] ); + } else + XUnmapWindow( dpy, Win[2] ); + infoPanelActive = !infoPanelActive; + mouseInInfoSw( ID_SWITCH_INFO ); + fullRepaint(); +} + +inline void drawLampsSwitch( int active ) +{ + int pixmap_index = (lampsActive ? 2:0) + active; + int offset_x = pixmap_index * LampsSWRect.dim.w; + XCopyArea( dpy, lampsSWPixmap, disp, WinGC, offset_x, 0, LampsSWRect.dim.w, LampsSWRect.dim.w, LampsSWRect.pos.x, LampsSWRect.pos.y ); + repaint( Win[activeWin], LampsSWRect.pos.x, LampsSWRect.pos.y, LampsSWRect.dim.w, LampsSWRect.dim.h ); +} + +void mouseInLampsSw( int id ) +{ + drawLampsSwitch(ACTIVE); +} + +void mouseOutLampsSw( int id ) +{ + drawLampsSwitch(INACTIVE); +} + +void mouseClickLampsSw( int id, unsigned int button ) +{ + activateLamps( !lampsActive ); + mouseInLampsSw( ID_SWITCH_LAMPS ); +} + +void activateLamps( bool active ) +{ + if( active ) + { + drawLamp( 0, INACTIVE ); + drawLamp( 1, INACTIVE ); + drawLamp( 2, INACTIVE ); + region_enable( Win[activeWin], ID_LAMP_GREEN ); + region_enable( Win[activeWin], ID_LAMP_YELLOW ); + region_enable( Win[activeWin], ID_LAMP_RED ); + } else { + for( int i=0; i < 3; i++ ) + blankMainWin( LampsRect[i].pos.x, LampsRect[i].pos.y, LampsRect[i].dim.w, LampsRect[i].dim.h ); + region_disable( Win[activeWin], ID_LAMP_GREEN ); + region_disable( Win[activeWin], ID_LAMP_YELLOW ); + region_disable( Win[activeWin], ID_LAMP_RED ); + } + lampsActive = active; + fullRepaint(); +} + +void drawSwitches() +{ + drawInfoSwitch( INACTIVE ); + drawLampsSwitch( INACTIVE ); +} + +void mouseInDevice( int id ) +{ + drawDevice(ACTIVE); + repaint( Win[activeWin], 0, 0, MainWinDim.w, MainWinDim.h ); +} + +void mouseOutDevice( int id ) +{ + drawDevice(INACTIVE); + repaint( Win[activeWin], 0, 0, MainWinDim.w, MainWinDim.h ); +} + +void mouseClickDevice( int id, unsigned int button ) +{ + selectNextDevice(); + mouseInDevice( ID_DEVICE ); +} + + +void drawDevice( int active ) +{ + char *color = active == ACTIVE ? DeviceColorHigh : DeviceColorLow; + drawText( devices[selected_device], disp, DeviceRect.pos.x, DeviceRect.pos.y, color ); +} + +void mouseInStatusSw( int id ) +{ + /* drawStatusSw( ACTIVE ); */ +} + +void mouseOutStatusSw( int id ) +{ + /* drawStatusSw( INACTIVE ); */ +} + +void mouseClickStatusSw( int id, unsigned int button ) +{ + if(button == 2) + pressStatusSw(); +} + +/* void drawStatusSw( int active ) */ + +void getWindowPosition( Window win, int *x, int *y ) +{ + XWindowAttributes winAttr; + Window dummy; + + XGetWindowAttributes( dpy, win, &winAttr ); + XTranslateCoordinates( dpy, win, winAttr.root, + -winAttr.border_width, -winAttr.border_width, + x, y, &dummy ); +} + +void getWindowDimension( Window win, int *w, int *h ) +{ + XWindowAttributes winAttr; + XGetWindowAttributes( dpy, win, &winAttr ); + *w = winAttr.width; + *h = winAttr.height; +} +void repaint( Window win, int x, int y, int w, int h ) +{ + //bad code start + Pixmap src; + if( win == Win[activeWin] ) + src = disp; + else if( win == Win[2] ) + src = disp_info; + else { + syslog( LOG_DEBUG, "Oops! Unknown window given to repaint\n" ); + return; + } + //bade code end + + XCopyArea( dpy, src, win, WinGC, x, y, w, h, x, y ); + XFlush(dpy); +} + +void fullRepaint() +{ + repaint( Win[activeWin], 0, 0, MainWinDim.w, MainWinDim.h ); + if( infoPanelActive ) + repaint( Win[2], 0, 0, InfoWinDim.w, InfoWinDim.h ); +} + +bool timeToUpdate() +{ + static int ticker = 0; + if( ticker++ > UPDATE_INTERVAL ) + { + ticker = 0; + return true; + } + return false; +} + +/* get ISDN device status and update windows as needed */ +void update() +{ + isdnStatus stat; + getStatus( devices[selected_device], &stat ); + if( memcmp(&curStatus, &stat, sizeof(stat)) != 0 ) + { + memcpy( &curStatus, &stat, sizeof(stat) ); + setStatusPixmap(); +// drawDevice(); + repaint( Win[activeWin], 0, 0, MainWinDim.w, MainWinDim.h ); + } + updateInfoPanel(); + repaint( Win[2], 0, 0, InfoWinDim.w, InfoWinDim.h ); +} + +/* set the appropriate pixmap on the main window */ +void setStatusPixmap() +{ + Pixmap statusPixmap, directionPixmap; + + if( curStatus.usage > ISDN_USAGE_NONE && curStatus.usage <= ISDN_USAGE_FAX ) + { + statusPixmap = statusPixmaps[curStatus.usage]; + switch( curStatus.mpppMode ) + { + case slave : directionPixmap = slavePixmap; break; + case master : if( curStatus.bundled == true ) { directionPixmap = bundledPixmap; break; } + if( is_slave_pending() ) { directionPixmap = bundlingPixmap; break; } + case none : directionPixmap = curStatus.direction == INCOMING ? incomingPixmap : outgoingPixmap; break; + default : syslog( LOG_DEBUG, "Ooops! curStatus.direction has an invalid value\n" ); directionPixmap = 0; + } + } + else { + switch( curStatus.usage ) + { + case STAT_OFF : statusPixmap = offPixmap; break; + case ISDN_USAGE_NONE: statusPixmap = statusPixmaps[ISDN_USAGE_NONE]; break; + case STAT_DISABLED : statusPixmap = disabledPixmap; break; + case STAT_DIALING : statusPixmap = dialingPixmap; break; + case STAT_UNKNOWN : statusPixmap = unknownPixmap; break; + default : syslog( LOG_DEBUG, "Ooops! curStatus.usage has an invalid value\n" ); statusPixmap = 0; + } + directionPixmap = 0; + } + if( statusPixmap != 0 ) + XCopyArea(dpy, statusPixmap, disp, WinGC, StatusPixmapRect.pos.x, StatusPixmapRect.pos.y, StatusPixmapRect.dim.w, StatusPixmapRect.dim.h, StatusPixmapRect.pos.x, StatusPixmapRect.pos.y); + if( directionPixmap != 0 ) + XCopyArea(dpy, directionPixmap, disp, WinGC, DirectionPixmapRect.pos.x, DirectionPixmapRect.pos.y, DirectionPixmapRect.dim.w, DirectionPixmapRect.dim.h, DirectionPixmapRect.pos.x, DirectionPixmapRect.pos.y); +} + +/* update the info panel */ +void updateInfoPanel() +{ + XSetForeground( dpy, WinGC, getColor(WindowBackgroundColor) ); + XFillRectangle( dpy, disp_info, WinGC, 0, 0, InfoWinDim.w, InfoWinDim.h ); + char line[100]; + if( (curStatus.usage > ISDN_USAGE_NONE && curStatus.usage <= ISDN_USAGE_FAX) || curStatus.usage == STAT_DIALING ) + { + sprintf( line, "peer phone: %s", curStatus.peerPhone ); + drawText( line, disp_info, 5, 5 ); + } + if( (curStatus.usage == ISDN_USAGE_NET) && (curStatus.mpppMode != slave) ) + { + int a, b, c, d; + getLocalIP( &a, &b, &c, &d ); + sprintf( line, "local ip : %d.%d.%d.%d", a, b, c, d ); + drawText( line, disp_info, 5, 20 ); + getRemoteIP( &a, &b, &c, &d ); + sprintf( line, "remote ip: %d.%d.%d.%d", a, b, c, d ); + drawText( line, disp_info, 5, 35 ); + } + else if( curStatus.usage == STAT_OFF ) + drawText( "dialing disabled", disp_info, 5, 5 ); + else if( curStatus.usage == STAT_DISABLED ) + drawText( "device disabled", disp_info, 5, 5 ); + else if( curStatus.usage == ISDN_USAGE_NONE ) + { + drawText( "not connected", disp_info, 5, 5 ); + sprintf( line, "action: %s", scriptmodestrings[scriptmode] ); + drawText( line, disp_info, 5, 20 ); + } + switch( curStatus.mpppMode ) + { + case none : sprintf( line, "bundling: none" ); break; + case master : sprintf( line, "bundling: master of %s", curStatus.mpppPartner ); break; + case slave : sprintf( line, "bundling: slave of %s", curStatus.mpppPartner ); break; + } + drawText( line, disp_info, 5, 50 ); +} + +void blankMainWin( int x, int y, int w, int h ) +{ + XCopyArea(dpy, coverPixmap, disp, WinGC, x, y, w, h, x, y); +} + +unsigned long getColor( const char *colorname ) +{ + XColor color; + XWindowAttributes winattr; + XGetWindowAttributes(dpy, Root, &winattr); + color.pixel=0; + XParseColor(dpy, winattr.colormap, colorname, &color); + color.flags=DoRed | DoGreen | DoBlue; + XAllocColor(dpy, winattr.colormap, &color); + return color.pixel; +} + +void createPixmap(char *data[], Pixmap *image, Pixmap *mask ) +{ + XpmAttributes pixatt; + + pixatt.exactColors=false; + pixatt.closeness=40000; + pixatt.valuemask=XpmExactColors | XpmCloseness | XpmSize; + XpmCreatePixmapFromData(dpy, Root, data, image, mask, &pixatt); +} + +void loadLeds( char *data[], Pixmap *image, const char *led_color, const char *back_color) +{ + XpmAttributes pixatt; + unsigned long color[4]; + + color[0] = mixColor(led_color, 0, back_color, 100); + color[1] = mixColor(led_color, 100, back_color, 0); + color[2] = mixColor(led_color, 60, back_color, 40); + color[3] = mixColor(led_color, 25, back_color, 75); + + XpmColorSymbol xpmcsym[4]={{"led_color_back", NULL, color[0] }, + {"led_color_high", NULL, color[1]}, + {"led_color_med", NULL, color[2]}, + {"led_color_low", NULL, color[3]}}; + + + pixatt.numsymbols = 4; + pixatt.colorsymbols = xpmcsym; + pixatt.exactColors = false; + pixatt.closeness = 40000; + pixatt.valuemask = XpmColorSymbols | XpmExactColors | XpmCloseness | XpmSize; + XpmCreatePixmapFromData(dpy, Root, data, image, NULL, &pixatt); +} + +unsigned long mixColor( const char *colorname1, int prop1, const char *colorname2, int prop2 ) +{ + XColor color, color1, color2; + XWindowAttributes winattr; + XGetWindowAttributes(dpy, Root, &winattr); + XParseColor(dpy, winattr.colormap, colorname1, &color1); + XParseColor(dpy, winattr.colormap, colorname2, &color2); + color.pixel=0; + color.red=(color1.red*prop1+color2.red*prop2)/(prop1+prop2); + color.green=(color1.green*prop1+color2.green*prop2)/(prop1+prop2); + color.blue=(color1.blue*prop1+color2.blue*prop2)/(prop1+prop2); + color.flags=DoRed | DoGreen | DoBlue; + XAllocColor(dpy, winattr.colormap, &color); + return color.pixel; +} + +/* draws text on dst using the led symbols from the leds pixmap */ +void leds_drawText( char *text, Pixmap dst, int x, int y, const char *color ) +{ + Pixmap leds_pixmap; + loadLeds( leds_xpm, &leds_pixmap, color, WindowBackgroundColor ); + + x -= 3; + char *led_ptr; + while( *text != 0 ) + { + led_ptr = strchr( led_text, tolower(*text) ); + if( led_ptr == NULL ) + { + /*syslog( LOG_DEBUG, "Oops! Internal bug in drawText: No led symbol for char %c\n", *text );*/ + led_ptr = strchr( led_text, '?' ); + } + XCopyArea( dpy, leds_pixmap, dst, WinGC, (led_ptr-led_text)*LedDim.w, 0, LedDim.w, LedDim.h, x, y ); + x += LedDim.w; + text++; + } + XFreePixmap( dpy, leds_pixmap ); +} + +/* draws text on dst using the X-Font from textFont */ +void font_drawText( char *text, Pixmap dst, int x, int y, const char *color ) +{ + XSetForeground( dpy, WinGC, getColor(color) ); + XDrawImageString( dpy, dst, WinGC, x, y+textFont->ascent/2, text, strlen(text) ); +} + +void drawText( char *text, Pixmap dst, int x, int y, const char *color ) +{ + if( textFont == NULL ) + leds_drawText( text, dst, x, y, color ); + else + font_drawText( text, dst, x, y, color ); +} + +/* draws the lamp in the specified state */ +void drawLamp( int lamp, int active ) +{ + int disp_x, disp_y, lamp_x=0; + + disp_x = LampsRect[lamp].pos.x; + disp_y = LampsRect[lamp].pos.y; + + /* find the offset of the lamp pixmap in the pixmap of all lamps */ + for( int i=0; i < lamp; i++ ) + lamp_x += LampsRect[i].dim.w*2; + lamp_x += active*LampsRect[lamp].dim.w; + + XCopyArea( dpy, lampsPixmap, disp, WinGC, lamp_x, 0, LampsRect[lamp].dim.w, LampsRect[lamp].dim.h, disp_x, disp_y ); +} + +void isdnInitDefaultDialmode() +{ + seteuid( rootUID ); + setegid( rootGID ); + + isdn_net_ioctl_cfg cfg; + strcpy( cfg.name, devices[selected_device] ); + if( isdn_ioctl( IIOCNETGCF, &cfg, NULL ) != -1 ) + dialmode = cfg.dialmode; + else + dialmode = ISDN_NET_DM_AUTO; /* for the sake of cleanness, we'll get an error msg soon anyway */ + if( dialmode == ISDN_NET_DM_OFF ) + dialmode = ISDN_NET_DM_AUTO; /* use auto as default dialmode if device disabled */ + + seteuid( getuid() ); + setegid( getgid() ); +} + +int isdn_ioctl( int func, void *arg, const char *errmsg, const char *filename ) +{ + int fd = fd = open( filename, O_RDONLY ); + if( fd == -1 ) + { + if( errmsg != NULL ) + syslog( LOG_NOTICE, "Couldn't open %s : %m\n", filename ); + return -1; + } + + int res = ioctl( fd, func, arg ); + if( res == -1 && errmsg != NULL ) + syslog( LOG_NOTICE, "%s : %m\n", errmsg ); + + close(fd); + + return res; +} + +inline void isdn_dial() +{ + if( !usescripts ) + isdn_ioctl( IIOCNETDIL, devices[selected_device], "Couldn't dial" ); + else + { + + int handle; + char command[MAX_ARG_LEN]; + + strcpy(command, scriptpath); + strcat(command, "/"); + strcat(command, SCRIPT_UP); + if ((handle = open(command, O_RDONLY)) == -1) + syslog( LOG_NOTICE, "Couldn't open %s : %m\n", SCRIPT_UP ); + else { + close(handle); + sprintf(command, "%s/%s %s %d 2>&1 | logger -t wmisdn.sh &", scriptpath, SCRIPT_UP, devices[selected_device], scriptmode); + system(command); + } + } + update(); +} + +inline void isdn_hangup() +{ + if( !usescripts ) + isdn_ioctl( IIOCNETHUP, devices[selected_device], "Couldn't hang up" ); + else + { + int handle; + char command[MAX_ARG_LEN]; + + strcpy(command, scriptpath); + strcat(command, "/"); + strcat(command, SCRIPT_DOWN); + + if ((handle = open(command, O_RDONLY)) == -1) + syslog( LOG_NOTICE, "Couldn't open %s : %m\n", SCRIPT_DOWN ); + else { + close(handle); + sprintf(command, "%s/%s %s %d 2>&1 | logger -t wmisdn.sh &", scriptpath, SCRIPT_DOWN, devices[selected_device], scriptmode); + system(command); + } + } + update(); +} + +inline void isdn_enable() +{ + isdn_net_ioctl_cfg cfg; + strcpy( cfg.name, devices[selected_device] ); + if( isdn_ioctl( IIOCNETGCF, &cfg, "Error enabling dialing. Couldn't get dev cfg" ) != -1 ) + { + cfg.dialmode = dialmode; + isdn_ioctl( IIOCNETSCF, &cfg, "Error enabling dialing. Couldn't set dev cfg" ); + } +} + +inline void isdn_disable() +{ + isdn_net_ioctl_cfg cfg; + strcpy( cfg.name, devices[selected_device] ); + if( isdn_ioctl( IIOCNETGCF, &cfg, "Error disabling dialing. Couldn't get dev cfg" ) != -1 ) + { + cfg.dialmode = ISDN_NET_DM_OFF; + isdn_ioctl( IIOCNETSCF, &cfg, "Error disabling dialing. Couldn't set dev cfg" ); + } +} + +inline void isdn_dial_slave( char *master ) +{ + isdn_ioctl( IIOCNETALN, master, "Couldn't fire up slave" ); +} + +inline void isdn_hangup_slave( char *master ) +{ + isdn_ioctl( IIOCNETDLN, master, "Couldn't hang up slave" ); +} + +inline void set_slave_pending() +{ + slave_pending = devices[selected_device]; +} + +inline void clear_slave_pending() +{ + slave_pending = NULL; +} + +inline bool is_slave_pending() +{ + return slave_pending != NULL; +} + +inline void manage_slave() +{ + if( is_slave_pending() ) + { + if( curStatus.usage == ISDN_USAGE_NET ) + { + isdn_dial_slave(slave_pending); + clear_slave_pending(); + } + if( curStatus.usage == ISDN_USAGE_NONE ) + clear_slave_pending(); + } +} + +/* react upon a lamp press + * - green opens a connection and sets the device in dial_auto mode + * - yellow ends the connection and sets the device in dial_auto mode + * - red ends the connection and sets the device in dial_off mode + */ + +inline void _pressGreenLamp( int button ) +{ + /* middle button - just change the script mode */ + if( button == 2 ) + { + advanceScriptMode(); + return; + } + /* online request of slave - add a channel to the master */ + if( curStatus.mpppMode == slave ) + isdn_dial_slave( curStatus.mpppPartner ); + /* online request of master or non-bundled device */ + else { + /* additional mppp-link requested - add a slave channel to the master (wait until master online) */ + if( (button == 3) && (curStatus.mpppMode == master) ) + set_slave_pending(); + /* if device is dialing or online - ignore button */ + if( curStatus.usage == STAT_DIALING || curStatus.usage == ISDN_USAGE_NET ) + return; + if( curStatus.usage == STAT_OFF ) + isdn_enable(); + isdn_dial(); + } +} + +inline void _pressYellowLamp( int button ) +{ + if( curStatus.usage == ISDN_USAGE_NONE ) + return; + if( curStatus.usage == STAT_OFF ) + isdn_enable(); + else + { + if( (button == 3) || (button == 1) && (curStatus.mpppMode == master) ) + isdn_hangup_slave( devices[selected_device] ); + if( button == 1 ) + { + if( curStatus.mpppMode == slave ) + isdn_hangup_slave( curStatus.mpppPartner ); + else + isdn_hangup(); + } + } +} + +inline void _pressRedLamp( int button ) +{ + if( (curStatus.usage == STAT_OFF) || (button != 1) ) + return; + _pressYellowLamp( button ); + isdn_disable(); +} + +void pressLamp( int lamp_id, int button ) +{ + seteuid( rootUID ); + setegid( rootGID ); + switch( lamp_id ) + { + case ID_LAMP_GREEN : _pressGreenLamp( button );break; + case ID_LAMP_YELLOW : _pressYellowLamp( button ); break; + case ID_LAMP_RED : _pressRedLamp( button ); break; + } + seteuid( getuid() ); + setegid( getgid() ); +} + +/* activated when user clicks the status pixmap with the right button - switch online<->offline */ +void pressStatusSw() +{ + seteuid( rootUID ); + setegid( rootGID ); + + if( curStatus.usage == ISDN_USAGE_NONE ) + _pressGreenLamp(1); + else if(curStatus.usage == ISDN_USAGE_NET ) + _pressYellowLamp(1); + + seteuid( getuid() ); + setegid( getgid() ); +} + + +/* Get the local/remote IP addresses of the devices[selected_device] */ + +void getLocalIP( int *a, int *b, int *c, int *d ) +{ + struct ifreq ifr; + int fd = socket( AF_INET, SOCK_DGRAM, 0 ); + + strcpy( ifr.ifr_ifrn.ifrn_name, devices[selected_device] ); + ifr.ifr_ifru.ifru_addr.sa_family = AF_INET; + int res = ioctl(fd, SIOCGIFADDR, &ifr); + close(fd); + translateIP( &(ifr.ifr_ifru.ifru_addr), a, b, c, d ); + + if( res != 0 ) + syslog( LOG_NOTICE, "Oops! Couldn't get local IP of device %s. ioctl() call failed : %m\n", devices[selected_device] ); +} + +void getRemoteIP( int *a, int *b, int *c, int *d ) +{ + struct ifreq ifr; + int fd = socket( AF_INET, SOCK_DGRAM, 0 ); + + strcpy( ifr.ifr_ifrn.ifrn_name, devices[selected_device] ); + ifr.ifr_ifru.ifru_addr.sa_family = AF_INET; + int res = ioctl( fd, SIOCGIFDSTADDR, &ifr ); + close(fd); + translateIP( &(ifr.ifr_ifru.ifru_addr), a, b, c, d ); + + if( res != 0 ) + syslog( LOG_NOTICE, "Oops! Couldn't get remote IP of device %s. ioctl() call failed : %m\n", devices[selected_device]); +} + +/* extract the ip address from the addr struct asuming that it is a valid INET sockaddr */ +inline void translateIP( struct sockaddr *addr, int *a, int *b, int *c, int *d ) +{ + struct sockaddr_in* inet_addr = (sockaddr_in *)addr; + unsigned int ip = inet_addr->sin_addr.s_addr; + *d = (ip >> 24) & 0xFF; + *c = (ip >> 16) & 0xFF; + *b = (ip >> 8 ) & 0xFF; + *a = ip & 0xFF; +} + +/* extract the data from the 'key'-line of /dev/isdninfo for all 16 B-Channels */ +bool extractIsdnInfoData( const char *all_data, const char *key, char buffer[ISDN_MAX_CHANNELS][100] ) +{ + char temp[100]; /* buffer the key string */ + char *ptr; + + ptr = strstr( all_data, key ); + if( ptr == NULL ) + { + syslog( LOG_NOTICE, "Error getting status info. /dev/isdninfo doesn't contain a '%s' line\n", key ); + return false; + } + sscanf( ptr, "%s %s %s %s %s %s %s %s %s %s %s %s %s %s %s %s %s", + temp, + buffer[0], buffer[1], buffer[2], buffer[3], + buffer[4], buffer[5], buffer[6], buffer[7], + buffer[8], buffer[9], buffer[10], buffer[11], + buffer[12], buffer[13], buffer[14], buffer[15] ); + + return true; +} + +bool getPeerPhone( char *ippp, char *phone ) +{ + isdn_net_ioctl_phone ippp_phone; + int res; + + strcpy( ippp_phone.name, ippp ); + res = isdn_ioctl( IIOCNETGPN, &ippp_phone, NULL, "/dev/isdninfo" ); + if( res < 0 ) + { + if( errno != ENOTCONN ) /* device not connected - no real error */ + syslog( LOG_NOTICE, "Error getting phone number for device %s: %m", ippp ); + return false; + } + strcpy( phone, ippp_phone.phone ); + return true; +} + +bool findBChannel( char *phone, char all_phones[ISDN_MAX_CHANNELS][100], int &channel ) +{ + for( int i=0; i < ISDN_MAX_CHANNELS; i++ ) + if( strcmp( all_phones[i], phone ) == 0 ) + { + channel = i; + return true; + } + syslog( LOG_NOTICE, "Hmm!!?? That's strange! Device phone number %s couldn't be found in /dev/isdninfo", phone ); + return false; +} + +void getMPPPSettings( isdn_net_ioctl_cfg *cfg, isdnStatus *stat ) +{ + stat->mpppMode = none; + if( strlen(cfg->master) != 0 ) + { + stat->mpppMode = slave; + strcpy( stat->mpppPartner, cfg->master ); + } + if( strlen(cfg->slave) != 0 ) + { + stat->mpppMode = master; + strcpy( stat->mpppPartner, cfg->slave ); + } +} + +/* get the status of the ippp device: + * + * - isOff if dialing is disabled + * - isOffline if dialing is enabled but no connection is established + * - isOnline if device has established a connection + * - isDialing if device is dialing the remote but no connection is established + * - isUnknown if no stat info available + */ +void getStatus( char *device, isdnStatus *stat ) +{ + isdn_net_ioctl_cfg cfg; + int fd, len, res; + char buf[10000]; + static int warning_count=0; + int channel, channel_usage; + char channel_info[ISDN_MAX_CHANNELS][100]; + + + /* get ippp device config */ + seteuid( rootUID ); + setegid( rootGID ); + strcpy( cfg.name, device ); + res = isdn_ioctl( IIOCNETGCF, &cfg, warning_count < STATUS_WARNING_SAT ? "Error getting status info. Couldn't get device cfg" : (char *)NULL ); + seteuid( getuid() ); + setegid( getgid() ); + + stat->usage = STAT_UNKNOWN; + stat->direction = INCOMING; + + if( res == -1 ) + { + warning_count++; + return; + } + warning_count = 0; + if( cfg.dialmode == ISDN_NET_DM_OFF ) + stat->usage = STAT_OFF; + else + stat->usage = ISDN_USAGE_NONE; + + stat->bundled = false; + getMPPPSettings( &cfg, stat ); + + /* read the device flags from /dev/isdninfo */ + fd = open( "/dev/isdninfo", O_RDONLY|O_NDELAY ); + if( fd == -1 ) + { + syslog( LOG_NOTICE, "Error getting status info. Couldn't open /dev/isdninfo : %m\n" ); + return; + } + len = read( fd, buf, sizeof(buf)-1 ); + close(fd); + if( len == -1 ) + { + syslog( LOG_NOTICE, "Error getting status info. Couldn't read from /dev/isdninfo : %m\n" ); + return; + } + buf[len] = 0; /* terminate the string */ + + if( !extractIsdnInfoData( buf, "phone:", channel_info ) ) + return; + if( !getPeerPhone( device, stat->peerPhone ) ) + return; + if( !findBChannel( stat->peerPhone, channel_info, channel ) ) + return; + if( !extractIsdnInfoData( buf, "usage:", channel_info ) ) + return; + + channel_usage = atoi(channel_info[channel]); + if( (channel_usage & ISDN_USAGE_DISABLED) != 0 ) + stat->usage = STAT_DISABLED; + else + stat->usage = channel_usage & ISDN_USAGE_MASK; + stat->direction = (channel_usage & ISDN_USAGE_OUTGOING) == 0 ? INCOMING : OUTGOING; + + /* check if device is still dialing or already online */ + if( stat->usage == ISDN_USAGE_NET ) + { + + if( !extractIsdnInfoData( buf, "flags:", channel_info ) ) + return; + + if( ((atoi(channel_info[0]) >> channel) & 1) == 0 ) + stat->usage = STAT_DIALING; + } + /* check for channel bundling */ + if( stat->mpppMode == master ) + { + isdnStatus slaveStatus; + getStatus( stat->mpppPartner, &slaveStatus ); + if( (stat->usage == slaveStatus.usage) && (stat->direction == slaveStatus.direction) && + (strcmp(stat->peerPhone,slaveStatus.peerPhone)==0) ) + stat->bundled = true; + } +} diff --git a/wmisdn/xpm/bundled.xpm b/wmisdn/xpm/bundled.xpm new file mode 100644 index 0000000..8d34296 --- /dev/null +++ b/wmisdn/xpm/bundled.xpm @@ -0,0 +1,80 @@ +/* XPM */ +static char * bundled_xpm[] = { +"64 64 13 1", +" c None", +". c #000000", +"+ c #202020", +"@ c #FFFFFF", +"# c #4F301A", +"$ c #B0520F", +"% c #683917", +"& c #974A12", +"* c #E06309", +"= c #F96C07", +"- c #C85B0C", +"; c #37281D", +"> c #804114", +" ", +" ", +" ", +" ", +" ", +" ", +" ", +" ", +" ", +" ", +" ", +" ", +" ", +" ", +" ", +" ", +" ", +" ", +" ", +" ", +" ", +" ", +" ", +" ", +" ", +" ", +" ", +" ", +" ", +" ", +" ", +" ", +" ", +" .++++++++++++++++++++++++++++++++++++++++++++++++++++@ ", +" .++++++++++++++++++++++++++++++++++++++++++++++++++++@ ", +" .+++++++++++++++#$++++++++++++++++++#$+$%+++++++++&%+@ ", +" .+++++++++++++++%$++++++++++++++++++%$+$%+++++++++$%+@ ", +" .+++++++++++++++%$++++++++++++++++++%$+$%+++++++++$%+@ ", +" .+++++++++++++++%**=%+$%+%$%-$=$+;*=*$+$%;-=*%+%==*%+@ ", +" .+++++++++++++++%-;;*#$%+%$%=$+=+-%+>$+$%-&;-&;*;+-%+@ ", +" .+++++++++++++++%$++$%$%+%$%*++=+=++%$+$%=$->+%$++$%+@ ", +" .+++++++++++++++%-+;*;$%+%$%$++=+*%+&$+$%*%+;&#*;;-%+@ ", +" .+++++++++++++++%*=*%+%==*$#$++=+%*=-$+$%%*=*>+&==-%+@ ", +" .++++++++++++++++++++++++++++++++++++++++++++++++++++@ ", +" .++++++++++++++++++++++++++++++++++++++++++++++++++++@ ", +" ", +" ", +" ", +" ", +" ", +" ", +" ", +" ", +" ", +" ", +" ", +" ", +" ", +" ", +" ", +" ", +" ", +" ", +" "}; diff --git a/wmisdn/xpm/bundling.xpm b/wmisdn/xpm/bundling.xpm new file mode 100644 index 0000000..6eded68 --- /dev/null +++ b/wmisdn/xpm/bundling.xpm @@ -0,0 +1,80 @@ +/* XPM */ +static char * bundling_xpm[] = { +"64 64 13 1", +" c None", +". c #000000", +"+ c #202020", +"@ c #FFFFFF", +"# c #50433B", +"$ c #B48C72", +"% c #6A5649", +"& c #38312D", +"* c #826856", +"= c #E5B08D", +"- c #FFC39B", +"; c #CD9E7F", +"> c #9B7A64", +" ", +" ", +" ", +" ", +" ", +" ", +" ", +" ", +" ", +" ", +" ", +" ", +" ", +" ", +" ", +" ", +" ", +" ", +" ", +" ", +" ", +" ", +" ", +" ", +" ", +" ", +" ", +" ", +" ", +" ", +" ", +" ", +" ", +" .++++++++++++++++++++++++++++++++++++++++++++++++++++@ ", +" .+++++#$++++++++++++++++++#$+$%&#++++++++++++++++++++@ ", +" .+++++%$++++++++++++++++++%$+$%#*++++++++++++++++++++@ ", +" .+++++%$++++++++++++++++++%$+$%++++++++++++++++++++++@ ", +" .+++++%==-%+$%+%$%;$-$+&=-=$+$%%$%;$-$+&;-;&+++++++++@ ", +" .+++++%;&&=#$%+%$%-$+-+;%+*$+$%%$%-$+-+;>+$%+++++++++@ ", +" .+++++%$++$%$%+%$%=++-+-++%$+$%%$%=++-+-++;%+++++++++@ ", +" .+++++%;+&=&$%+%$%$++-+=%+>$+$%%$%$++-+-&%-%+#+&&+#++@ ", +" .+++++%=-=%+%--=$#$++-+%=-;$+$%%$#$++-+%-=$%#=+>>+=#+@ ", +" .+++++++++++++++++++++++++++++++++++++++++=&+++++++++@ ", +" .++++++++++++++++++++++++++++++++++++++%%>=++++++++++@ ", +" .++++++++++++++++++++++++++++++++++++++>$>&++++++++++@ ", +" ", +" ", +" ", +" ", +" ", +" ", +" ", +" ", +" ", +" ", +" ", +" ", +" ", +" ", +" ", +" ", +" ", +" ", +" "}; diff --git a/wmisdn/xpm/cover.xpm b/wmisdn/xpm/cover.xpm new file mode 100644 index 0000000..4613920 --- /dev/null +++ b/wmisdn/xpm/cover.xpm @@ -0,0 +1,71 @@ +/* XPM */ +static char * cover_xpm[] = { +"64 64 4 1", +" c None", +". c #000000", +"+ c #202020", +"@ c #FFFFFF", +" ", +" ", +" ", +" ", +" ", +" .....................................................+ ", +" .++++++++++++++++++++++++++++++++++++++++++++++++++++@ ", +" .++++++++++++++++++++++++++++++++++++++++++++++++++++@ ", +" .++++++++++++++++++++++++++++++++++++++++++++++++++++@ ", +" .++++++++++++++++++++++++++++++++++++++++++++++++++++@ ", +" .++++++++++++++++++++++++++++++++++++++++++++++++++++@ ", +" .++++++++++++++++++++++++++++++++++++++++++++++++++++@ ", +" .++++++++++++++++++++++++++++++++++++++++++++++++++++@ ", +" .++++++++++++++++++++++++++++++++++++++++++++++++++++@ ", +" .++++++++++++++++++++++++++++++++++++++++++++++++++++@ ", +" .++++++++++++++++++++++++++++++++++++++++++++++++++++@ ", +" .++++++++++++++++++++++++++++++++++++++++++++++++++++@ ", +" .++++++++++++++++++++++++++++++++++++++++++++++++++++@ ", +" .++++++++++++++++++++++++++++++++++++++++++++++++++++@ ", +" .++++++++++++++++++++++++++++++++++++++++++++++++++++@ ", +" .++++++++++++++++++++++++++++++++++++++++++++++++++++@ ", +" .++++++++++++++++++++++++++++++++++++++++++++++++++++@ ", +" .++++++++++++++++++++++++++++++++++++++++++++++++++++@ ", +" .++++++++++++++++++++++++++++++++++++++++++++++++++++@ ", +" .++++++++++++++++++++++++++++++++++++++++++++++++++++@ ", +" .++++++++++++++++++++++++++++++++++++++++++++++++++++@ ", +" .++++++++++++++++++++++++++++++++++++++++++++++++++++@ ", +" .++++++++++++++++++++++++++++++++++++++++++++++++++++@ ", +" .++++++++++++++++++++++++++++++++++++++++++++++++++++@ ", +" .++++++++++++++++++++++++++++++++++++++++++++++++++++@ ", +" .++++++++++++++++++++++++++++++++++++++++++++++++++++@ ", +" .++++++++++++++++++++++++++++++++++++++++++++++++++++@ ", +" .++++++++++++++++++++++++++++++++++++++++++++++++++++@ ", +" .++++++++++++++++++++++++++++++++++++++++++++++++++++@ ", +" .++++++++++++++++++++++++++++++++++++++++++++++++++++@ ", +" .++++++++++++++++++++++++++++++++++++++++++++++++++++@ ", +" .++++++++++++++++++++++++++++++++++++++++++++++++++++@ ", +" .++++++++++++++++++++++++++++++++++++++++++++++++++++@ ", +" .++++++++++++++++++++++++++++++++++++++++++++++++++++@ ", +" .++++++++++++++++++++++++++++++++++++++++++++++++++++@ ", +" .++++++++++++++++++++++++++++++++++++++++++++++++++++@ ", +" .++++++++++++++++++++++++++++++++++++++++++++++++++++@ ", +" .++++++++++++++++++++++++++++++++++++++++++++++++++++@ ", +" .++++++++++++++++++++++++++++++++++++++++++++++++++++@ ", +" .++++++++++++++++++++++++++++++++++++++++++++++++++++@ ", +" .++++++++++++++++++++++++++++++++++++++++++++++++++++@ ", +" .++++++++++++++++++++++++++++++++++++++++++++++++++++@ ", +" .++++++++++++++++++++++++++++++++++++++++++++++++++++@ ", +" .++++++++++++++++++++++++++++++++++++++++++++++++++++@ ", +" .++++++++++++++++++++++++++++++++++++++++++++++++++++@ ", +" .++++++++++++++++++++++++++++++++++++++++++++++++++++@ ", +" .++++++++++++++++++++++++++++++++++++++++++++++++++++@ ", +" .++++++++++++++++++++++++++++++++++++++++++++++++++++@ ", +" .++++++++++++++++++++++++++++++++++++++++++++++++++++@ ", +" .++++++++++++++++++++++++++++++++++++++++++++++++++++@ ", +" .++++++++++++++++++++++++++++++++++++++++++++++++++++@ ", +" .++++++++++++++++++++++++++++++++++++++++++++++++++++@ ", +" .++++++++++++++++++++++++++++++++++++++++++++++++++++@ ", +" +@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ ", +" ", +" ", +" ", +" ", +" "}; diff --git a/wmisdn/xpm/dialing.xpm b/wmisdn/xpm/dialing.xpm new file mode 100644 index 0000000..421bc9e --- /dev/null +++ b/wmisdn/xpm/dialing.xpm @@ -0,0 +1,80 @@ +/* XPM */ +static char * dialing_xpm[] = { +"64 64 13 1", +" c None", +". c #000000", +"+ c #202020", +"@ c #FFFFFF", +"# c #434D21", +"$ c #51601E", +"% c #A3D10C", +"& c #6C8518", +"* c #95BD0F", +"= c #5E721B", +"- c #7A9815", +"; c #353A24", +"> c #87AB12", +" ", +" ", +" ", +" ", +" ", +" ", +" ", +" ", +" ", +" ", +" ", +" ", +" ", +" ", +" ", +" .++++++++++++++++++++++++++++++++++++++++++++++++++++@ ", +" .++++++++++++++++++++++++++++++++++++++++++++++++++++@ ", +" .++++++++++++++++++++++++++++++++++++++++++++++++++++@ ", +" .++++++++++++++++++++++++++++++++++++++++++++++++++++@ ", +" .++++++++++++++++++++++++++++++++++++++++++++++++++++@ ", +" .++++++++++++++++++++++++++++++++++++++++++++++++++++@ ", +" .++++++++++++++++++++++++++++++++++++++++++++++++++++@ ", +" .++++++++++++++++++++++++++++++++++++++++++++++++++++@ ", +" .++++++++++++++++++++++++++++++++++++++++++++++++++++@ ", +" .+++#++++++++++$+++++++++++#%#++$++++++++++++++++++++@ ", +" .++&%*=+++++++$%$++++++++++$%$+$%$+++++++++++++++++++@ ", +" .++-%&%%&;+++++$+++++++++++$%$++$++++++++++++++++++++@ ", +" .++-%++=**$++++++++++++++++$%$+++++++++++++++++++++++@ ", +" .++-%+++;-%$++;-;++++$--$++$%$+;-;+#%#;&-#+++;=--=+++@ ", +" .++-%+++++>*;+$%$++;>%%%%&+$%$+$%$+$%-%%%*++#*%%%%*++@ ", +" .++-%+++++#%=+$%$++-%-;$%$+$%$+$%$+$%%*;=%$+**#+;%%++@ ", +" .++-%++++++%-+$%$+;%>++$%$+$%$+$%$+$%%#+$%$=%=+++%*++@ ", +" .++-%+++++;%-+$%$+$%$++$%$+$%$+$%$+$%>++$%$-%+++$%-++@ ", +" .++-%+++++=%=+$%$+$%$++$%$+$%$+$%$+$%$++$%$-%+++=%-++@ ", +" .++-%++++$%*++$%$+#%&++;%&+$%$+$%$+$%$++$%$&%#+;*%-++@ ", +" .++-%*--*%*#++$%$++*%>-%%*+$%$+$%$+$%$++$%$;%*-*>%&++@ ", +" .++;=>%%*&;+++;-;++;-%%-=*##%#+;-;+#%#++#%#+$>%>;%$++@ ", +" .+++++++++++++++++++++++++++++++++++++++++++++++$%$++@ ", +" .+++++++++++++++++++++++++++++++++++++++++++++++>%;++@ ", +" .++++++++++++++++++++++++++++++++++++++++++&*--*%-+++@ ", +" .++++++++++++++++++++++++++++++++++++++++++$*%%*&++++@ ", +" .++++++++++++++++++++++++++++++++++++++++++++++++++++@ ", +" .++++++++++++++++++++++++++++++++++++++++++++++++++++@ ", +" .++++++++++++++++++++++++++++++++++++++++++++++++++++@ ", +" .++++++++++++++++++++++++++++++++++++++++++++++++++++@ ", +" ", +" ", +" ", +" ", +" ", +" ", +" ", +" ", +" ", +" ", +" ", +" ", +" ", +" ", +" ", +" ", +" ", +" ", +" "}; diff --git a/wmisdn/xpm/disabled.xpm b/wmisdn/xpm/disabled.xpm new file mode 100644 index 0000000..96a6b87 --- /dev/null +++ b/wmisdn/xpm/disabled.xpm @@ -0,0 +1,80 @@ +/* XPM */ +static char * disabled_xpm[] = { +"64 64 13 1", +" c None", +". c #000000", +"+ c #202020", +"@ c #FFFFFF", +"# c #3E2724", +"$ c #552620", +"% c #6D261D", +"& c #9A2515", +"* c #832519", +"= c #B22412", +"- c #F72307", +"; c #DF230A", +"> c #C8240E", +" ", +" ", +" ", +" ", +" ", +" ", +" ", +" ", +" ", +" ", +" ", +" ", +" ", +" ", +" ", +" .++++++++++++++++++++++++++++++++++++++++++++++++++++@ ", +" .++++++++++++++++++++++++++++++++++++++++++++++++++++@ ", +" .++++++++++++++++++++++++++++++++++++++++++++++++++++@ ", +" .++++++++++++++++++++++++++++++++++++++++++++++++++++@ ", +" .++++++++++++++++++++++++++++++++++++++++++++++++++++@ ", +" .++++++++++++++++++++++++++++++++++++++++++++++++++++@ ", +" .++++++++++++++++++++++++++++++++++++++++++++++++++++@ ", +" .++++++++++++++++++++++++++++++++++++++++++++++++++++@ ", +" .++++++++++++++++++++++++++++++++++++++++++++++++++++@ ", +" .++++++++++++++++++++++++++++++++++++++++++++++++++++@ ", +" .++++++++++++++++++++++++++#$++++++%#++++++++++++%+++@ ", +" .+++&*+++++++$+++++++++++++==++++++-%+++++++++++#-+++@ ", +" .+++-;;*++++$;+++++++++++++==++++++-%+++++++++++%-+++@ ", +" .+++-%$>;#++++++++#%+++++++==++++++-%+++++++++++%-+++@ ", +" .+++-%++*;#+#&++$>--%+$==%+==*=&+++-%+#&=&$++#&=&-+++@ ", +" .+++-%+++>=+%-+$-&#;$*->>-$=-;=->++-%#;;=;;+#-;=--+++@ ", +" .+++-%+++%-+%-+$-=*##-*+%-+=>++$-$+-%*;$*;=+&;++%-+++@ ", +" .+++-%+++*-+%-++#%>;*-++%-+==+++-%+-%=;>*#++==++%-+++@ ", +" .+++-%+++>=+%-+%%+#-&-%+%-#=>#+&-#+-%&;$+#=$&;$+=-+++@ ", +" .+++-=%%>-#+%-+*---;#=---;&=----%++-%#;--->+#;----#++@ ", +" .+++*>-->$+++$++#%%+++$%##$$$%%#+++=#++$%$++++%%#$+++@ ", +" .++++++++++++++++++++++++++++++++++++++++++++++++++++@ ", +" .++++++++++++++++++++++++++++++++++++++++++++++++++++@ ", +" .++++++++++++++++++++++++++++++++++++++++++++++++++++@ ", +" .++++++++++++++++++++++++++++++++++++++++++++++++++++@ ", +" .++++++++++++++++++++++++++++++++++++++++++++++++++++@ ", +" .++++++++++++++++++++++++++++++++++++++++++++++++++++@ ", +" .++++++++++++++++++++++++++++++++++++++++++++++++++++@ ", +" .++++++++++++++++++++++++++++++++++++++++++++++++++++@ ", +" .++++++++++++++++++++++++++++++++++++++++++++++++++++@ ", +" .++++++++++++++++++++++++++++++++++++++++++++++++++++@ ", +" ", +" ", +" ", +" ", +" ", +" ", +" ", +" ", +" ", +" ", +" ", +" ", +" ", +" ", +" ", +" ", +" ", +" "}; diff --git a/wmisdn/xpm/fax.xpm b/wmisdn/xpm/fax.xpm new file mode 100644 index 0000000..7e1cb80 --- /dev/null +++ b/wmisdn/xpm/fax.xpm @@ -0,0 +1,80 @@ +/* XPM */ +static char * fax_xpm[] = { +"64 64 13 1", +" c None", +". c #000000", +"+ c #202020", +"@ c #FFFFFF", +"# c #313D51", +"$ c #364867", +"% c #405D90", +"& c #5489E5", +"* c #4568A6", +"= c #2C323C", +"- c #3B527B", +"; c #4E7DCF", +"> c #4A73BA", +" ", +" ", +" ", +" ", +" ", +" ", +" ", +" ", +" ", +" ", +" ", +" ", +" ", +" ", +" ", +" .++++++++++++++++++++++++++++++++++++++++++++++++++++@ ", +" .++++++++++++++++++++++++++++++++++++++++++++++++++++@ ", +" .++++++++++++++++++++++++++++++++++++++++++++++++++++@ ", +" .++++++++++++++++++++++++++++++++++++++++++++++++++++@ ", +" .+++++++++++#$$#+++++++++++++++++++++++++++++++++++++@ ", +" .++++++++%&&&&&&&$+++++++++++++++++++++++++++++++++++@ ", +" .++++++++*&*$$$$*$+++++++++++++++++++++++++++++++++++@ ", +" .++++++++*&++++++++++++++++++++++++++++++++++++++++++@ ", +" .++++++++*&+++++++++=-*%#++%$++++#%++++++++++++++++++@ ", +" .++++++++*&$****$++$;&&&&#+>&$++=;;++++++++++++++++++@ ", +" .++++++++*&&&&&&%+=;&-+*&+++;;=$&;=++++++++++++++++++@ ", +" .++++++++*&$++++++-&-++*&+++=;;&*++++++++++++++++++++@ ", +" .++++++++*&+++++++*&+++*&++++%&;+++++++++++++++++++++@ ", +" .++++++++*&+++++++*&+++*&+++$&;&%++++++++++++++++++++@ ", +" .++++++++*&+++++++%&#++-&#+-&*+*&$+++++++++++++++++++@ ", +" .++++++++*&+++++++#&&*>&&%%&*+++>&$++++++++++++++++++@ ", +" .++++++++%;++++++++$>&;%%;$%++++=;%++++++++++++++++++@ ", +" .++++++++++++++++++++++++++++++++++++++++++++++++++++@ ", +" ", +" ", +" ", +" ", +" ", +" ", +" ", +" ", +" ", +" ", +" ", +" ", +" ", +" ", +" ", +" ", +" ", +" ", +" ", +" ", +" ", +" ", +" ", +" ", +" ", +" ", +" ", +" ", +" ", +" ", +" "}; diff --git a/wmisdn/xpm/incoming.xpm b/wmisdn/xpm/incoming.xpm new file mode 100644 index 0000000..095f971 --- /dev/null +++ b/wmisdn/xpm/incoming.xpm @@ -0,0 +1,80 @@ +/* XPM */ +static char * incoming_xpm[] = { +"64 64 13 1", +" c None", +". c #000000", +"+ c #202020", +"@ c #3D3527", +"# c #534327", +"$ c #FFFFFF", +"% c #805F27", +"& c #6A5127", +"* c #AC7B26", +"= c #C28926", +"- c #EFA526", +"; c #D89626", +"> c #966D26", +" ", +" ", +" ", +" ", +" ", +" ", +" ", +" ", +" ", +" ", +" ", +" ", +" ", +" ", +" ", +" ", +" ", +" ", +" ", +" ", +" ", +" ", +" ", +" ", +" ", +" ", +" ", +" ", +" ", +" ", +" ", +" ", +" ", +" .++++++++++++@#++++++++++++++++++++++++#@++++++++++++$ ", +" .++++++++++++#%++++++++++++++++++++++++%#++++++++++++$ ", +" .++++++++++++++++++++++++++++++++++++++++++++++++++++$ ", +" .++++++++++++&*&=*-*++*-=@@=-*+&**;*->+*&*>;-&+&;->++$ ", +" .++++++++++++&*&-*+-+>*+#@=%+;#&-%**%*+*&*-&&*@-#+-++$ ", +" .++++++++++++&*&;++-+-@+++-++*&&*+*&&=+*&*>+&*&*+@-++$ ", +" .++++++++++++&*&*++-+;&+%#;&@;@&*+*&+-+*&*&+&*&=+*-++$ ", +" .++++++++++++&*#*++-+&;-=@&;-&+&*+*&+-+*&>&+&*+*->-++$ ", +" .+++++++++++++++++++++++++++++++++#@+++++++++++++#=++$ ", +" .+++++++++++++++++++++++++++++++++++++++++++++@&&=>++$ ", +" .+++++++++++++++++++++++++++++++++++++++++++++@**%+++$ ", +" .++++++++++++++++++++++++++++++++++++++++++++++++++++$ ", +" ", +" ", +" ", +" ", +" ", +" ", +" ", +" ", +" ", +" ", +" ", +" ", +" ", +" ", +" ", +" ", +" ", +" ", +" "}; diff --git a/wmisdn/xpm/info_sw.xpm b/wmisdn/xpm/info_sw.xpm new file mode 100644 index 0000000..28ac8b9 --- /dev/null +++ b/wmisdn/xpm/info_sw.xpm @@ -0,0 +1,15 @@ +/* XPM */ +static char * info_sw_xpm[] = { +"40 8 4 1", +" c None", +". c #202020", +"+ c #364F6D", +"@ c #3DDEFF", +"........................................", +"...+.........@............+.........@...", +"..++........@@............++........@@..", +".+++++++++.@@@@@@@@@+++++++++.@@@@@@@@@.", +".+++++++++.@@@@@@@@@+++++++++.@@@@@@@@@.", +"..++........@@............++........@@..", +"...+.........@............+.........@...", +"........................................"}; diff --git a/wmisdn/xpm/lamps.xpm b/wmisdn/xpm/lamps.xpm new file mode 100644 index 0000000..51a0c2b --- /dev/null +++ b/wmisdn/xpm/lamps.xpm @@ -0,0 +1,21 @@ +/* XPM */ +static char * lamps_xpm[] = { +"60 10 8 1", +" c None", +". c #202020", +"+ c #9BA994", +"@ c #19FF00", +"# c #D4D3A9", +"$ c #FFFA40", +"% c #CF8888", +"& c #FF0000", +"............................................................", +"............................................................", +"............................................................", +"....+++.......@@@.......###.......$$$.......%%%.......&&&...", +"...+++++.....@@@@@.....#####.....$$$$$.....%%%%%.....&&&&&..", +"...+++++.....@@@@@.....#####.....$$$$$.....%%%%%.....&&&&&..", +"...+++++.....@@@@@.....#####.....$$$$$.....%%%%%.....&&&&&..", +"....+++.......@@@.......###.......$$$.......%%%.......&&&...", +"............................................................", +"............................................................"}; diff --git a/wmisdn/xpm/lamps_sw.xpm b/wmisdn/xpm/lamps_sw.xpm new file mode 100644 index 0000000..44555b5 --- /dev/null +++ b/wmisdn/xpm/lamps_sw.xpm @@ -0,0 +1,15 @@ +/* XPM */ +static char * lamps_sw_xpm[] = { +"40 8 4 1", +" c None", +". c #202020", +"+ c #364F6D", +"@ c #3DDEFF", +"....++........@@........++........@@....", +"...++++......@@@@.......++........@@....", +"..++++++....@@@@@@......++........@@....", +"....++........@@........++........@@....", +"....++........@@........++........@@....", +"....++........@@......++++++....@@@@@@..", +"....++........@@.......++++......@@@@...", +"....++........@@........++........@@...."}; diff --git a/wmisdn/xpm/leds.xpm b/wmisdn/xpm/leds.xpm new file mode 100644 index 0000000..7f98003 --- /dev/null +++ b/wmisdn/xpm/leds.xpm @@ -0,0 +1,17 @@ +/* XPM */ +static char * leds_xpm[] = { +"388 8 6 1", +" c None", +". c #202020 s led_color_back", +"+ c #20B2AE s led_color_high", +"@ c #004941 s led_color_low", +"# c #007D71 s led_color_mid", +"$ c #FFFFFF", +"..+++...@@@#.#+++#.#+++#.#@@@#.#+++#.#+++#.#+++#.#+++#.#+++#..+++................+....+++...+.+...+++..........+.....+...#...#....+...+.............................+.+..++.+......+..+....#+++...+++#...++...++.....................@+++@.#+++..#+++#.#+++..#+++#.#+++#.#+++#.#@@@#..@@@#..@@@#.#@@@#.#@@@..+@@@+.#+++..#+++#.#+++#.#+++#.#+++#.#+++#.#+++#.#@@@#.#@@@#.#@@@#.#@@@#.#@@@#.#+++#....", +".+...+.@...+.@...+.@...+.+...+.+...@.+...@.@...+.+...+.+...+.+...+....+..+.......+...+...+..+.+..+.+...+..+...+.+...+.+...+.+....+.....+...........+................+.+.+..+.+....+....+...+.........+..+.......+....................+...+.+...+.+...@.+...+.+...@.+...@.+...@.+...+.@...+.@...+.+...+.+...@.++.++.+...+.+...+.+...+.+...+.+...+.+...@.@.+.@.+...+.+...+.+...+.+...+.+...+.@...+....", +".+...+.@...+.@...+.@...+.+...+.+...@.+...@.@...+.+...+.+...+....+.....+..+.......+...+.+.+.+@+@+.+.+...#..+..+...+...+.....+....+.......+..........+.........+++++..#.#..........+......+..+.........+..+.......+...+................+...+.+...+.+...@.+...+.+...@.+...@.+...@.+...+.@...+.@...+.+..+@.+...@.+.+.+.+...+.+...+.+...+.+...+.+...+.+...@.@.+.@.+...+.+...+.+...+.@+.+@.+...+.@..+@....", +".#@@@#..@@@#.#+++#..+++#.#+++#.#+++#.#+++#..@@@#.@+++@.#+++#...+.....+....+......+...#@++#..+.+...+@+....+...........+...#+@+#..+.......+........+++++.+++++....................+........+.#.........#.+.........+..#................#+++#.#+++..#@@@..#@@@#.#+++..#+++..#@++#.#+++#..@@@#..@@@#.#++@..#@@@..#@@@#.#@@@#.#@@@#.#+++#.#+@@#.#+++..#+++#..@#@..#@@@#.#@@@#.#@@@#..@+@..#+++#..@+@.....", +".+...+.@...+.+...@.@...+.@...+.@...+.+...+.@...+.+...+.@...+.........+....+..........+.@...+@+@+...+.+...+..........+..+...+....+.......+..........+.........+++++...............+......+..+.........+..+.......+....................+...+.+...+.+...@.+...+.+...@.+...@.+...+.+...+.@...+.@...+.+..+@.+...@.+...+.+...+.+...+.+...@.+.+.+.+...+.@...+.@.+.@.+...+.+...+.+.+.+.@+.+@.@...+.@+..@....", +".+...+.@...+.+...@.@...+.@...+.@...+.+...+.@...+.+...+.@...+...+....+......+.....+...+...+..+.+....+.+..+..+.......+..+...+.+....+.....+...........+..............................+....+...+.........+..+.......+...+....+...........+...+.+...+.+...@.+...+.+...@.+...@.+...+.+...+.@...+.@...+.+...+.+...@.+...+.+...+.+...+.+...@.+..++.+...+.@...+.@.+.@.+...+.+...+.++.++.+...+.@...+.+...@....", +"..+++...@@@+.#+++#.#+++#..@@@#.#+++#.#+++#..@@@#.#+++#.#+++#...#....+......+.....#....+++...+.+...+++...+..#........++.+.#...#....+...+....+++++...................................+..+....#+++...+++#...++...++....#....#...........#@@@#.#+++..#+++#.++++..#+++#.+@@@..#+++#.#@@@#..@@@+.#+++#.#@@@#.#+++@.#@@@#.+@@@+.#+++#.#@@@..#+++#.#@@@#.#+++#..@#@..@++++..+++..+@@@+.#@@@+##+++#.#+++#....", +"...................................................................................................................................................................................................................................................................................................................................................................................................."}; diff --git a/wmisdn/xpm/modem.xpm b/wmisdn/xpm/modem.xpm new file mode 100644 index 0000000..72e7f47 --- /dev/null +++ b/wmisdn/xpm/modem.xpm @@ -0,0 +1,80 @@ +/* XPM */ +static char * modem_xpm[] = { +"64 64 13 1", +" c None", +". c #000000", +"+ c #202020", +"@ c #FFFFFF", +"# c #203B23", +"$ c #097516", +"% c #15581C", +"& c #067F14", +"* c #11621A", +"= c #1C4521", +"- c #0D6B18", +"; c #184E1F", +"> c #243125", +" ", +" ", +" ", +" ", +" ", +" ", +" ", +" ", +" ", +" ", +" ", +" ", +" ", +" ", +" ", +" .++++++++++++++++++++++++++++++++++++++++++++++++++++@ ", +" .++++++++++++++++++++++++++++++++++++++++++++++++++++@ ", +" .++++++++++++++++++++++++++++++++++++++++++++++++++++@ ", +" .++++#+++++#++++++++++++++++++$%+++++++++++++++++++++@ ", +" .+++%&#+++%&#+++++++++++++++++&*+++++++++++++++++++++@ ", +" .+++&&=+++-&=++++++++++++++++=&*+++++++++++++++++++++@ ", +" .++#&&*+++&&*++++++++++++++++=&*+++++++++++++++++++++@ ", +" .++=&&*++=&$*++++#%*;++++>%*%;&;+++=**;>++=*+#*=+;*=+@ ", +" .++%&*$++%$*-+++=&&&&%++>$&&&&&=++*&&&&$>+*&=&&&$&&&#@ ", +" .++--*&++$**&++>&$>>-&++-&=+>-&=+;&*>+*&=+*&$*=&$#%&=@ ", +" .++&%=&=#&==&>+%&#++;&=#&%+++=&=+-&>#-&$++*&*+=&=+=&*@ ", +" .+=&=#&;*&+#&=+*&+++=&==&=+++=&=+&--&-;+++*&++=&=+>&*@ ", +" .+%&++&*&*++&%+*&+++=&==&=+++=&=+&&*#+++++*&++=&=++&*@ ", +" .+&-++-&&=++--+;&;++-&+>&$>++*&=+$$>+++=$+-$+++&*++&$@ ", +" .=&*++*&&>++*&>>$&*$&;++%&$*-&&;+=&&-*$&*+-$+++&*++-&@ ", +" .=&=++#&%+++=&=+>-&$;++++;$&&%$%++=-&&-;++%$+++&*++%$@ ", +" .+=++++++++++=+++++++++++++++++++++++++++++++++#>++++@ ", +" .++++++++++++++++++++++++++++++++++++++++++++++++++++@ ", +" ", +" ", +" ", +" ", +" ", +" ", +" ", +" ", +" ", +" ", +" ", +" ", +" ", +" ", +" ", +" ", +" ", +" ", +" ", +" ", +" ", +" ", +" ", +" ", +" ", +" ", +" ", +" ", +" ", +" ", +" "}; diff --git a/wmisdn/xpm/off.xpm b/wmisdn/xpm/off.xpm new file mode 100644 index 0000000..7f8dd43 --- /dev/null +++ b/wmisdn/xpm/off.xpm @@ -0,0 +1,80 @@ +/* XPM */ +static char * off_xpm[] = { +"64 64 13 1", +" c None", +". c #000000", +"+ c #202020", +"@ c #FFFFFF", +"# c #552620", +"$ c #9A2515", +"% c #B22412", +"& c #3E2724", +"* c #832519", +"= c #6D261D", +"- c #F72307", +"; c #DF230A", +"> c #C8240E", +" ", +" ", +" ", +" ", +" ", +" ", +" ", +" ", +" ", +" ", +" ", +" ", +" ", +" ", +" ", +" .++++++++++++++++++++++++++++++++++++++++++++++++++++@ ", +" .++++++++++++++++++++++++++++++++++++++++++++++++++++@ ", +" .++++++++++++++++++++++++++++++++++++++++++++++++++++@ ", +" .++++++++++++++++++++++++++++++++++++++++++++++++++++@ ", +" .++++++++++++++++++++++++++++++++++++++++++++++++++++@ ", +" .++++++++++++++++++++++++++++++++++++++++++++++++++++@ ", +" .+++++++++++++++++++++++++++++#$%%&+++++&*%%=++++++++@ ", +" .++++++++++++++=%%%$=++++++++%----%++++=-----++++++++@ ", +" .++++++++++++=;------;#+++++#-----=++++;----%++++++++@ ", +" .+++++++++++*----------#++++%--$++++++=-->&++++++++++@ ", +" .++++++++++=---$&++#%-->++++;-;+++++++$--#+++++++++++@ ", +" .+++++++++&;--=++++++>--&+#=-->==#++&=>--===+++++++++@ ", +" .+++++++++$--$+++++++=--=$--------##--------$++++++++@ ", +" .+++++++++;-;++++++++=--=$--------##--------$++++++++@ ", +" .++++++++&--%++++++++=--=&==-->==&++==>--==#+++++++++@ ", +" .++++++++=--=++++++++$--&+++--%+++++++%--++++++++++++@ ", +" .++++++++=--=++++++++;-;++++--%+++++++%--++++++++++++@ ", +" .++++++++=--*+++++++*--$++++--%+++++++%--++++++++++++@ ", +" .+++++++++--;&+++++&---&++++--%+++++++%--++++++++++++@ ", +" .+++++++++$--;*&++*---*+++++--%+++++++%--++++++++++++@ ", +" .++++++++++%---------%++++++--%+++++++%--++++++++++++@ ", +" .+++++++++++$-------$++++++&--%+++++++>--++++++++++++@ ", +" .++++++++++++&=%%%*&+++++++=--*+++++++-->++++++++++++@ ", +" .+++++++++++++++++++++++++++$%&+++++++=%=++++++++++++@ ", +" .++++++++++++++++++++++++++++++++++++++++++++++++++++@ ", +" .++++++++++++++++++++++++++++++++++++++++++++++++++++@ ", +" .++++++++++++++++++++++++++++++++++++++++++++++++++++@ ", +" .++++++++++++++++++++++++++++++++++++++++++++++++++++@ ", +" .++++++++++++++++++++++++++++++++++++++++++++++++++++@ ", +" .++++++++++++++++++++++++++++++++++++++++++++++++++++@ ", +" .++++++++++++++++++++++++++++++++++++++++++++++++++++@ ", +" ", +" ", +" ", +" ", +" ", +" ", +" ", +" ", +" ", +" ", +" ", +" ", +" ", +" ", +" ", +" ", +" ", +" "}; diff --git a/wmisdn/xpm/offline.xpm b/wmisdn/xpm/offline.xpm new file mode 100644 index 0000000..e45a8aa --- /dev/null +++ b/wmisdn/xpm/offline.xpm @@ -0,0 +1,80 @@ +/* XPM */ +static char * offline_xpm[] = { +"64 64 13 1", +" c None", +". c #000000", +"+ c #202020", +"@ c #FFFFFF", +"# c #39382A", +"$ c #5C5A2F", +"% c #4A492C", +"& c #6E6B31", +"* c #918D36", +"= c #7F7C33", +"- c #C6C03D", +"; c #B4AE3A", +"> c #A29E38", +" ", +" ", +" ", +" ", +" ", +" ", +" ", +" ", +" ", +" ", +" ", +" ", +" ", +" ", +" ", +" .++++++++++++++++++++++++++++++++++++++++++++++++++++@ ", +" .++++++++++++++++++++++++++++++++++++++++++++++++++++@ ", +" .++++++++++++++++++++++++++++++++++++++++++++++++++++@ ", +" .++++++++++++++++++++++++++++++++++++++++++++++++++++@ ", +" .++++++++++++++++++++++++++++++++++++++++++++++++++++@ ", +" .++++++++++++++++++++++++++++++++++++++++++++++++++++@ ", +" .++++++++++++++++++++++++++++++++++++++++++++++++++++@ ", +" .++++++++++++++++++++++++++++++++++++++++++++++++++++@ ", +" .++++++++++++++++++++++++++++++++++++++++++++++++++++@ ", +" .++++++#$$%++++++#&*=#++#&*=#$*#+++++++++++++++++++++@ ", +" .++++#=----;$++++;---$++;---$*-$+%-=+++++++++++++++++@ ", +" .++++;--**>--$++$-;&$++$-;&$+*-$+%-=+++++++++++++++++@ ", +" .+++=-;#+++&->++*-&++++*-&+++*-$+++++++++++++++++++++@ ", +" .++#--#+++++--%;----;%;----;+*-$+=-%+;;&-;$++$;-;&+++@ ", +" .++&-*++++++--%----->%----->+*-$+*-$+----->+%-----%++@ ", +" .++*-$+++++%-;++*-$++++*-$+++*-$+*-$+--;#--+*-*#>-%++@ ", +" .++*-$+++++=-=++*-$++++*-$+++*-$+*-$+--&+--+--*--&+++@ ", +" .++&->++++%--%++*-$++++*-$+++*-$+*-$+--#+--+---=#++++@ ", +" .++#;->&$=--=+++*-$++++*-$+++*-$+*-$+--++--+;-=$&;=++@ ", +" .+++#;-----*++++*-$++++*-$+++*-$+*-$+--++--+$-----$++@ ", +" .+++++$**=%+++++>-%++++>-%+++$*#+$*#+&=++==++#=*=%+++@ ", +" .+++++++++++++++#%+++++#%++++++++++++++++++++++++++++@ ", +" .++++++++++++++++++++++++++++++++++++++++++++++++++++@ ", +" .++++++++++++++++++++++++++++++++++++++++++++++++++++@ ", +" .++++++++++++++++++++++++++++++++++++++++++++++++++++@ ", +" .++++++++++++++++++++++++++++++++++++++++++++++++++++@ ", +" .++++++++++++++++++++++++++++++++++++++++++++++++++++@ ", +" .++++++++++++++++++++++++++++++++++++++++++++++++++++@ ", +" .++++++++++++++++++++++++++++++++++++++++++++++++++++@ ", +" .++++++++++++++++++++++++++++++++++++++++++++++++++++@ ", +" ", +" ", +" ", +" ", +" ", +" ", +" ", +" ", +" ", +" ", +" ", +" ", +" ", +" ", +" ", +" ", +" ", +" ", +" "}; diff --git a/wmisdn/xpm/online.xpm b/wmisdn/xpm/online.xpm new file mode 100644 index 0000000..72c2ccd --- /dev/null +++ b/wmisdn/xpm/online.xpm @@ -0,0 +1,80 @@ +/* XPM */ +static char * online_xpm[] = { +"64 64 13 1", +" c None", +". c #000000", +"+ c #202020", +"@ c #FFFFFF", +"# c #25392B", +"$ c #205D32", +"% c #224B2E", +"& c #18933C", +"* c #1A8139", +"= c #10C947", +"- c #12B643", +"; c #15A540", +"> c #1D6F35", +" ", +" ", +" ", +" ", +" ", +" ", +" ", +" ", +" ", +" ", +" ", +" ", +" ", +" ", +" ", +" .++++++++++++++++++++++++++++++++++++++++++++++++++++@ ", +" .++++++++++++++++++++++++++++++++++++++++++++++++++++@ ", +" .++++++++++++++++++++++++++++++++++++++++++++++++++++@ ", +" .++++++++++++++++++++++++++++++++++++++++++++++++++++@ ", +" .++++++++++++++++++++++++++++++++++++++++++++++++++++@ ", +" .++++++++++++++++++++++++++++++++++++++++++++++++++++@ ", +" .+++++++#$$%+++++++++++#&$+++++++++++++++++++++++++++@ ", +" .+++++#*====-$+++++++++$=&++--+++++++++++++++++++++++@ ", +" .+++++-==&&;==$++++++++$=&++--+++++++++++++++++++++++@ ", +" .++++*=-#+++>=;++++++++$=&+++++++++++++++++++++++++++@ ", +" .+++#==#+++++==+-->=-$+$=&+%=*+*=>-=*++#;==*#++++++++@ ", +" .+++>=&++++++==+=====;+$=&+$=&+&=====#+-====*++++++++@ ", +" .+++&=$+++++%=-+==-#==+$=&+$=&+&==$&=$$=-#*=*++++++++@ ", +" .+++&=$+++++*=*+==>+==+$=&+$=&+&=;+&=$&=;-=&#++++++++@ ", +" .+++>=;++++%==%+==#+==+$=&+$=&+&=>+&=$&==;%++++++++++@ ", +" .+++#-=;>$*==*++==++==+$=&+$=&+&=$+&=$*=;$$;-++++++++@ ", +" .++++#-=====&+++==++==+$=&+$=&+&=$+&=$#-====&++++++++@ ", +" .++++++$&&*%++++>*++**+#&$+#&$+%&#+$&#++>&&$+++++++++@ ", +" ", +" ", +" ", +" ", +" ", +" ", +" ", +" ", +" ", +" ", +" ", +" ", +" ", +" ", +" ", +" ", +" ", +" ", +" ", +" ", +" ", +" ", +" ", +" ", +" ", +" ", +" ", +" ", +" ", +" ", +" "}; diff --git a/wmisdn/xpm/outgoing.xpm b/wmisdn/xpm/outgoing.xpm new file mode 100644 index 0000000..0971d8b --- /dev/null +++ b/wmisdn/xpm/outgoing.xpm @@ -0,0 +1,80 @@ +/* XPM */ +static char * outgoing_xpm[] = { +"64 64 13 1", +" c None", +". c #000000", +"+ c #202020", +"@ c #384E4F", +"# c #416263", +"$ c #497577", +"% c #FFFFFF", +"& c #5A9C9F", +"* c #52888A", +"= c #74D6DB", +"- c #6BC2C6", +"; c #303B3B", +"> c #63AFB2", +" ", +" ", +" ", +" ", +" ", +" ", +" ", +" ", +" ", +" ", +" ", +" ", +" ", +" ", +" ", +" ", +" ", +" ", +" ", +" ", +" ", +" ", +" ", +" ", +" ", +" ", +" ", +" ", +" ", +" ", +" ", +" ", +" ", +" .++++++++++++++++++++++++@#++++++++++++@$++++++++++++% ", +" .++++++++++++++++++++++++#&++++++++++++++++++++++++++% ", +" .+++++++++++++*=-;#&++=+-===@#-=*+;>=&+#&#>&=&+;>=>;+% ", +" .++++++++++++$>+**#&++=++#&+;=@+=+>$+-@#&#=&+=+>*+&#+% ", +" .++++++++++++&#+#&#&++=++#&+#&+;=+=++&##&#-++=+=++>#+% ", +" .++++++++++++*&+&$#&++=++#&+#>+&=+-#;-;#&#&++=+=;#=#+% ", +" .++++++++++++;>=&+;-=-=++#*++&=*=+#-=#+#&@&++=+#=-&#+% ", +" .++++++++++++++++++++++++++++++@>+++++++++++++++++-;+% ", +" .+++++++++++++++++++++++++++;##>*++++++++++++++##*-++% ", +" .+++++++++++++++++++++++++++;&&$+++++++++++++++*&*;++% ", +" .++++++++++++++++++++++++++++++++++++++++++++++++++++% ", +" .++++++++++++++++++++++++++++++++++++++++++++++++++++% ", +" ", +" ", +" ", +" ", +" ", +" ", +" ", +" ", +" ", +" ", +" ", +" ", +" ", +" ", +" ", +" ", +" ", +" ", +" "}; diff --git a/wmisdn/xpm/raw.xpm b/wmisdn/xpm/raw.xpm new file mode 100644 index 0000000..c6c22ea --- /dev/null +++ b/wmisdn/xpm/raw.xpm @@ -0,0 +1,80 @@ +/* XPM */ +static char * raw_xpm[] = { +"64 64 13 1", +" c None", +". c #000000", +"+ c #202020", +"@ c #FFFFFF", +"# c #45484C", +"$ c #54585E", +"% c #9DA9B9", +"& c #ADBACC", +"* c #8F99A7", +"= c #717882", +"- c #808995", +"; c #36383A", +"> c #626870", +" ", +" ", +" ", +" ", +" ", +" ", +" ", +" ", +" ", +" ", +" ", +" ", +" ", +" ", +" ", +" .++++++++++++++++++++++++++++++++++++++++++++++++++++@ ", +" .++++++++++++++++++++++++++++++++++++++++++++++++++++@ ", +" .++++++++++++++++++++++++++++++++++++++++++++++++++++@ ", +" .++++++++++++++++++++++++++++++++++++++++++++++++++++@ ", +" .++++++#$$+++++++++++++++++++++++++++++++++++++++++++@ ", +" .++++++%&&&*#++++++++++++++++++++++++++++++++++++++++@ ", +" .++++++&*$=%&=+++++++++++++++++++++++++++++++++++++++@ ", +" .++++++&-++;-&>++++++++++++++++++++++++++++++++++++++@ ", +" .++++++&-++++%%++++#=->;+$=++$=++;-;+++++++++++++++++@ ", +" .++++++&-++++-&+++=&&&&%+-&++&&#+>&#+++++++++++++++++@ ", +" .++++++&-+++>&*++$&%#+&-+-&+#&&$+-&++++++++++++++++++@ ", +" .++++++&%--&&*;++*&;++&-+$&$>&*=+%*++++++++++++++++++@ ", +" .++++++&&&&&#++++&-+++&-+$&$**--;&=++++++++++++++++++@ ", +" .++++++&-$*&%$+++&-+++&-+$&>&>>%$&$++++++++++++++++++@ ", +" .++++++&-++#%&-++%%+++*%+#&*&#$&-&+++++++++++++++++++@ ", +" .++++++&-++++-&=+=&%-%&&#+%&&++&&-+++++++++++++++++++@ ", +" .++++++%=+++++=$++=%&*>*=+$&$++=&;+++++++++++++++++++@ ", +" .++++++++++++++++++++++++++++++++++++++++++++++++++++@ ", +" ", +" ", +" ", +" ", +" ", +" ", +" ", +" ", +" ", +" ", +" ", +" ", +" ", +" ", +" ", +" ", +" ", +" ", +" ", +" ", +" ", +" ", +" ", +" ", +" ", +" ", +" ", +" ", +" ", +" ", +" "}; diff --git a/wmisdn/xpm/slave.xpm b/wmisdn/xpm/slave.xpm new file mode 100644 index 0000000..0c3069a --- /dev/null +++ b/wmisdn/xpm/slave.xpm @@ -0,0 +1,80 @@ +/* XPM */ +static char * slave_xpm[] = { +"64 64 13 1", +" c None", +". c #000000", +"+ c #202020", +"@ c #FFFFFF", +"# c #73CCDD", +"$ c #324549", +"% c #4D7F88", +"& c #60A5B2", +"* c #57929E", +"= c #293234", +"- c #3B595F", +"; c #69B8C7", +"> c #446C73", +" ", +" ", +" ", +" ", +" ", +" ", +" ", +" ", +" ", +" ", +" ", +" ", +" ", +" ", +" ", +" ", +" ", +" ", +" ", +" ", +" ", +" ", +" ", +" ", +" ", +" ", +" ", +" ", +" ", +" ", +" ", +" ", +" ", +" .++++++++++++++++++++++++++++++++++++++++++++++++++++@ ", +" .++++++++++++++++++++++++++++++++++#+++++++++++++++++@ ", +" .++++++++++++++++++++++++++++++++++#+++++++++++++++++@ ", +" .+++++++++++++++++++++++++++++++$$+#+++++++++++++++++@ ", +" .+++++++++++++++++++++++++++++%#&*+#+$&#&=#++%--;#&=+@ ", +" .++++++++++++++++++++++++++++-;$=$+#=#-+#+*-=;=#$$#$+@ ", +" .+++++++++++++++++++++++++++++>*;$+#-*++#+-%%>-;&*$++@ ", +" .++++++++++++++++++++++++++++$=+>*+#$&+=#=+;;+$;=+$>+@ ", +" .++++++++++++++++++++++++++++-;#;-+#+%#;%%+*>++%##&$+@ ", +" .++++++++++++++++++++++++++++++++++++++++++=+++++++++@ ", +" .++++++++++++++++++++++++++++++++++++++++++++++++++++@ ", +" .++++++++++++++++++++++++++++++++++++++++++++++++++++@ ", +" ", +" ", +" ", +" ", +" ", +" ", +" ", +" ", +" ", +" ", +" ", +" ", +" ", +" ", +" ", +" ", +" ", +" ", +" "}; diff --git a/wmisdn/xpm/unknown.xpm b/wmisdn/xpm/unknown.xpm new file mode 100644 index 0000000..a3c2822 --- /dev/null +++ b/wmisdn/xpm/unknown.xpm @@ -0,0 +1,80 @@ +/* XPM */ +static char * unknown_xpm[] = { +"64 64 13 1", +" c None", +". c #000000", +"+ c #202020", +"@ c #FFFFFF", +"# c #2B383A", +"$ c #325A5F", +"% c #2E484C", +"& c #3C8C96", +"* c #46BECE", +"= c #387A83", +"- c #42ACBB", +"; c #3F9CA8", +"> c #356A71", +" ", +" ", +" ", +" ", +" ", +" ", +" ", +" ", +" ", +" ", +" ", +" ", +" ", +" ", +" ", +" .++++++++++++++++++++++++++++++++++++++++++++++++++++@ ", +" .++++++++++++++++++++++++++++++++++++++++++++++++++++@ ", +" .++++++++++++++++++++++++++++++++++++++++++++++++++++@ ", +" .++++++++++++++++++++++++++++++++++++++++++++++++++++@ ", +" .++++++++++++++++++++++++++++++++++++++++++++++++++++@ ", +" .++++++++++++++++++++++++++++++++++++++++++++++++++++@ ", +" .++++++++++++++++++++++++++++++++++++++++++++++++++++@ ", +" .++++++++++++#$$+++++++++$$#++++++++%$%++++++++++++++@ ", +" .++++++++++#&****=+++++=-***;#++++$;***-$++++++++++++@ ", +" .+++++++++#-******-#++&*******$++$*******&+++++++++++@ ", +" .+++++++++$**->>-**&++***=$;**-#+&**;$=***$++++++++++@ ", +" .++++++++++==+++#-**#+$&#+++&**>+#&$+++$**;++++++++++@ ", +" .++++++++++++++++$**$++++++++**&++++++++&**++++++++++@ ", +" .++++++++++++++++&**%+++++++$**=+++++++#-*-++++++++++@ ", +" .++++++++++++++#&**-+++++++>***%++++++%-**=++++++++++@ ", +" .+++++++++++++$-**-#+++++#;***$++++++=***&+++++++++++@ ", +" .++++++++++++&***&#+++++$***-%+++++#-***>++++++++++++@ ", +" .+++++++++++$***$+++++++***&+++++++&**-#+++++++++++++@ ", +" .+++++++++++#--#++++++++&*$++++++++$*&+++++++++++++++@ ", +" .++++++++++++++++++++++++++++++++++++++++++++++++++++@ ", +" .+++++++++++$*&++++++++#--#++++++++&*$+++++++++++++++@ ", +" .+++++++++++***++++++++&**$+++++++$**&+++++++++++++++@ ", +" .+++++++++++-*;++++++++=**#+++++++%**>+++++++++++++++@ ", +" .+++++++++++#$#+++++++++$%+++++++++%$++++++++++++++++@ ", +" .++++++++++++++++++++++++++++++++++++++++++++++++++++@ ", +" .++++++++++++++++++++++++++++++++++++++++++++++++++++@ ", +" .++++++++++++++++++++++++++++++++++++++++++++++++++++@ ", +" .++++++++++++++++++++++++++++++++++++++++++++++++++++@ ", +" .++++++++++++++++++++++++++++++++++++++++++++++++++++@ ", +" .++++++++++++++++++++++++++++++++++++++++++++++++++++@ ", +" ", +" ", +" ", +" ", +" ", +" ", +" ", +" ", +" ", +" ", +" ", +" ", +" ", +" ", +" ", +" ", +" ", +" ", +" "}; diff --git a/wmisdn/xpm/voice.xpm b/wmisdn/xpm/voice.xpm new file mode 100644 index 0000000..8ebbca2 --- /dev/null +++ b/wmisdn/xpm/voice.xpm @@ -0,0 +1,80 @@ +/* XPM */ +static char * voice_xpm[] = { +"64 64 13 1", +" c None", +". c #000000", +"+ c #202020", +"@ c #FFFFFF", +"# c #4F5031", +"$ c #3B3C2C", +"% c #636537", +"& c #DBE055", +"* c #77793B", +"= c #B2B64A", +"- c #9FA246", +"; c #C6CB4F", +"> c #8A8D40", +" ", +" ", +" ", +" ", +" ", +" ", +" ", +" ", +" ", +" ", +" ", +" ", +" ", +" ", +" ", +" .++++++++++++++++++++++++++++++++++++++++++++++++++++@ ", +" .++++++++++++++++++++++++++++++++++++++++++++++++++++@ ", +" .++++++++++++++++++++++++++++++++++++++++++++++++++++@ ", +" .++++#$++++++%++++++++++%++++++++++++++++++++++++++++@ ", +" .++++&*+++++*&%++++++++%&%+++++++++++++++++++++++++++@ ", +" .++++=-+++++;=++++++++++%++++++++++++++++++++++++++++@ ", +" .++++>&++++%&%+++++++++++++++++++++++++++++++++++++++@ ", +" .++++%&%+++-&+++$*->$++$-$++++#->#+++$*--%+++++++++++@ ", +" .+++++&-+++&-++$;&&&;++%&%+++%&&&&>+$;&&&&-++++++++++@ ", +" .+++++-;++*&%++=&%+>&%+%&%++$&;$+*%+=&*+$;&++++++++++@ ", +" .+++++*&#+=&++#&>++$&-+%&%++>&#++++$&=+*;&>++++++++++@ ", +" .+++++#&*$&-++%&%+++&-+%&%++&=+++++%&-;&-#+++++++++++@ ", +" .++++++;=>&#++%&%+++&-+%&%++&-+++++%&;>$+++++++++++++@ ", +" .++++++>&;;+++$&=++*&%+%&%++;;$++*%#&-++++->+++++++++@ ", +" .++++++#&&>++++-&==&=++%&%++%&&-=&>+-&&--&&%+++++++++@ ", +" .+++++++;&$+++++>&&>$++$-$+++%=&;*+++>;&&-#++++++++++@ ", +" .++++++++++++++++++++++++++++++++++++++++++++++++++++@ ", +" .++++++++++++++++++++++++++++++++++++++++++++++++++++@ ", +" ", +" ", +" ", +" ", +" ", +" ", +" ", +" ", +" ", +" ", +" ", +" ", +" ", +" ", +" ", +" ", +" ", +" ", +" ", +" ", +" ", +" ", +" ", +" ", +" ", +" ", +" ", +" ", +" ", +" ", +" "};