[Pkg-wmaker-commits] [wmmixer] 01/24: Import Upstream version 0.8

Doug Torrance dtorrance-guest at moszumanska.debian.org
Sun Aug 27 13:12:52 UTC 2017


This is an automated email from the git hooks/post-receive script.

dtorrance-guest pushed a commit to branch master
in repository wmmixer.

commit 938708c47c0f296d10619cca27338a85be1362c8
Author: Doug Torrance <dtorrance at piedmont.edu>
Date:   Sun Aug 27 09:11:13 2017 -0400

    Import Upstream version 0.8
---
 .wmmixer        |  74 ++++++++
 COPYING         | 339 +++++++++++++++++++++++++++++++++
 FAQ             |  31 +++
 Imakefile       |  15 ++
 README          | 101 ++++++++++
 XPM/norec.xpm   |  12 ++
 XPM/symbols.xpm |  29 +++
 XPM/tile.xpm    | 121 ++++++++++++
 XPM/wmmixer.xpm |  74 ++++++++
 mixctl.h        | 218 +++++++++++++++++++++
 wmmixer.cc      | 573 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 11 files changed, 1587 insertions(+)

diff --git a/.wmmixer b/.wmmixer
new file mode 100644
index 0000000..07825f9
--- /dev/null
+++ b/.wmmixer
@@ -0,0 +1,74 @@
+# wmmixer - a mixer designed for WindowMaker
+# 07/05/98  Release 0.8
+# Copyright (C) 1998  Sam Hawker <shawkie at geocities.com>
+# This software comes with ABSOLUTELY NO WARRANTY
+# This software is free software, and you are welcome to redistribute it
+# under certain conditions
+# See the README file for a more complete notice.
+
+# User config file. Should be placed in ~/
+# Comments and blank lines mostly allowed
+
+# The format of this file is a series of commands:
+
+# addchannel %i
+#    adds a channel to the sequence. %i specifies a channel.
+#    these are the values from my <linux/soundcard.h>:
+#       SOUND_MIXER_VOLUME    0
+#       SOUND_MIXER_BASS      1
+#       SOUND_MIXER_TREBLE    2
+#       SOUND_MIXER_SYNTH     3
+#       SOUND_MIXER_PCM       4
+#       SOUND_MIXER_SPEAKER   5
+#       SOUND_MIXER_LINE      6
+#       SOUND_MIXER_MIC       7
+#       SOUND_MIXER_CD        8
+#    there are a few more, but these are the important ones (and are
+#    those identified with appropriate symbols)
+
+# setmono %i
+#    only valid at some point after an addchannel command.
+#    sets both left and right volumes for the last channel added.
+#    the channel may be mono or stereo.
+#    the value specified must be an integer in the range 0 to 100
+
+# setleft %i
+#    only valid at some point after an addchannel command.
+#    sets left volume for the last channel added.
+#    do not use on a mono channel.
+#    the value specified must be an integer in the range 0 to 100
+
+# setright %i
+#    only valid at some point after an addchannel command.
+#    sets right volume for the last channel added.
+#    do not use on a mono channel.
+#    the value specified must be an integer in the range 0 to 100
+
+# setrecsrc TRUE | FALSE
+#    only valid at some point after an addchannel command.
+#    enable or disable recording from the last channel added.
+#    ignored if the channel does not support it.
+#    the value is "TRUE" or "FALSE"
+#
+#    (setrecsrc entries are used to build a complete recsrc mask
+#    and a single instruction then sent to the mixer device, so
+#    order of entries is unimportant)
+
+# At least one channel must be added!
+
+addchannel 0
+
+addchannel 3
+
+addchannel 4
+
+addchannel 6
+
+addchannel 7
+
+addchannel 8
+
+
+
+
+
diff --git a/COPYING b/COPYING
new file mode 100644
index 0000000..a43ea21
--- /dev/null
+++ b/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.
+
+    <one line to give the program's name and a brief idea of what it does.>
+    Copyright (C) 19yy  <name of author>
+
+    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.
+
+  <signature of Ty Coon>, 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/FAQ b/FAQ
new file mode 100644
index 0000000..f0ed8bb
--- /dev/null
+++ b/FAQ
@@ -0,0 +1,31 @@
+wmmixer - a mixer designed for WindowMaker
+07/05/98  Release 0.8
+Copyright (C) 1998  Sam Hawker <shawkie at geocities.com>
+This software comes with ABSOLUTELY NO WARRANTY
+This software is free software, and you are welcome to redistribute it
+under certain conditions
+See the README file for a more complete notice.
+
+If this FAQ does not answer your question, or the suggested solution does
+not work, or cannot be implemented, please, email me.
+
+
+Frequently Asked Questions
+==========================
+
+   How do I make wmmount use it's application icon as it's window?
+      Start wmmixer with the "-w" command line option.
+
+   Why does wmmixer still not sit properly in Afterstep's Wharf?
+      Because the Wharf does not allow windows to use the full 64x64 pixels
+      which wmmixer needs.
+
+
+
+
+
+
+
+
+
+
diff --git a/Imakefile b/Imakefile
new file mode 100644
index 0000000..aec76e6
--- /dev/null
+++ b/Imakefile
@@ -0,0 +1,15 @@
+XPMLIB = -lXpm
+DEPLIBS = $(DEPXLIB) 
+
+OSSAUDIO =
+
+#ifdef NetBSDArchitecture
+OSSAUDIO = -lossaudio
+#endif
+
+LOCAL_LIBRARIES = $(XPMLIB) $(XLIB) $(OSSAUDIO)
+
+SRCS = wmmixer.cc
+OBJS = wmmixer.o
+
+ComplexProgramTarget(wmmixer)
diff --git a/README b/README
new file mode 100644
index 0000000..cf29017
--- /dev/null
+++ b/README
@@ -0,0 +1,101 @@
+wmmixer - a mixer designed for WindowMaker
+07/05/98  Release 0.8
+Copyright (C) 1998  Sam Hawker <shawkie at geocities.com>
+This software comes with ABSOLUTELY NO WARRANTY
+This software is free software, and you are welcome to redistribute it
+under certain conditions
+See the COPYING file for details.
+
+  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.
+
+
+THE AUTHOR:
+===========
+
+Sam Hawker
+shawkie at geocities.com
+http://www.geocities.com/SiliconValley/Vista/2471/
+
+
+INSTALLING:
+===========
+
+xmkmf
+make
+strip wmmixer
+make install
+cp .wmmixer ~/.wmmixer      (if you like. this file is very optional)
+
+
+USAGE:
+======
+
+wmmixer is based on the same interface used in my wmcdplay and wmmount programs.
+it uses my own mixer control class (see mixctl.h)
+
+it controls all mixer channels (in stereo and with recsrc button where
+appropriate), although only a few will be identified with an icon.
+
+it can now be configured to control/show only specific channels, through a
+~/.wmmixer file.
+
+click on the "<" and ">" buttons to select a different device/channel
+the icon identifies the current device (a volume symbol
+with a question mark represents an unknown device - commonly igain/ogain)
+click / drag the volume display to set channel volume.
+there is a also a button to set recording sources
+
+what else can i say, enjoy!
+
+RELEASE HISTORY:
+================
+
+release 0.1    07/02/98   Finally reached a state i am prepared to put my
+                          name to.
+                          No KNOWN bugs.
+
+release 0.2    12/02/98   Fixed nasty memory hole.
+
+release 0.3    24/02/98   Fixed bug relating to manual window positioning
+
+release 0.4    04/03/98   Reduced CPU Load (thanks to aseltine at cs.umass.edu)
+                          Support for NetBSD (you may need to make it use -lossaudio when linking)
+                                             (thanks to Geir.I.Jensen at runit.sintef.no)
+                          Only updates when it has to now
+
+release 0.5    05/03/98   Better support for NetBSD and FreeBSD
+                          Fixed bug relating to cards with no volume channel
+                             (thanks to dalroi at wit401310.student.utwente.nl)
+                          Fixed bug relating to hiding "Rec" checkbox on FreeBSD
+                             (thanks to dalroi at wit401310.student.utwente.nl)
+
+release 0.6    12/03/98   Fixed setRec() in mixctl.h
+                          (thanks to Geir.I.Jensen at runit.sintef.no)
+                          Now works on 8bpp displays with full colormaps
+                          (thanks to devernay at istar.fr on the mailing-list)
+                          Now configurable through a ~/.wmmixer file
+                          (suggested by steeve at minet.net)
+                          New channel symbols
+                          (thanks to steeve at minet.net)
+
+release 0.7    25/04/98   Better checking of supported channels
+                          Now GPL
+                          Sensible CPU load
+                          New FAQ
+                          New mixctl.h
+                          New look (thanks to warp at xs4all.nl)
+
+release 0.8    06/05/98   Removed broken display code
+                          Added "-b back_color" command line argument
\ No newline at end of file
diff --git a/XPM/norec.xpm b/XPM/norec.xpm
new file mode 100644
index 0000000..2b07db9
--- /dev/null
+++ b/XPM/norec.xpm
@@ -0,0 +1,12 @@
+/* XPM */
+static char * norec_xpm[] = {
+"6 7 2 1",
+" 	c #AEAAAE",
+".	c #86828E",
+"     .",
+" ... .",
+".. ...",
+".   ..",
+".. ...",
+" ... .",
+"     ."};
diff --git a/XPM/symbols.xpm b/XPM/symbols.xpm
new file mode 100644
index 0000000..dcda9c9
--- /dev/null
+++ b/XPM/symbols.xpm
@@ -0,0 +1,29 @@
+/* XPM */
+static char * symbols_xpm[] = {
+"220 22 4 1",
+" 	c #282828 s back_color",
+".	c #00ffff s led_color_high",
+"X	c #007b7b s led_color_low",
+"o	c #ffffff",
+"                                                                                                                                                                                                                            ",
+"                                                                                                                                                                                                                            ",
+"                                                                                                                                                                                          ..                                ",
+"                          ....                                                                                     X..                                          XXXXXX                   .  .            ..                 ",
+"                         .    .                                           ......             X......X             X..X.                    ..                  ........X                X.  .X          .  .                ",
+"                         .    .                                         ..XXX.....          X............X.       ..X.X.                  .. .                ..X   X....               X.  .X             .                ",
+"                 X.     .      .                                       ..XXXX......        X.......    . . .      .X.X..                 . . .       .       ...     .....  ..           .  .             .            X.   ",
+"               X...     .      .               ...............         ...XXX....o.        .X............X.        .X.. .               .X.  XX       .     X..X      X...X ..            ..             .           X...   ",
+"             X.....    .        .              .X.X.X.X X.X.X.X       .XX.XXX...o...       . X......X               ..XX .             . X.   .  .    .     X...X      ...X              X.X                       X.....   ",
+"           X.......    .        .              .X.X.X.X X.X.X.X       .XXXXX...o....       .                          .XX .               ..X .   .    .     ....      ...X             ....X            .       X.......   ",
+"         X.........    ....................    .X.X.X.X X.X.X.X       .XXXX.  .XXXX.       X.                          .XX .              .X. X . . .  .     X..X      ...X ..         X.X ..                  X.........   ",
+"       X...........              .        .    .X X X X X X X.X       .XXXX.  .XXXX.        X.                          .XX .             .X. .   .    .              X...X ..        ..X ....               X...........   ",
+"     X.............              .        .    .X X X X X X X.X       ....o...XXXXX.         .                           .XX .            ..  .   .    .              ....           X.X . .  .            X.............   ",
+"   X...............               .      .     ...............X       ...o...XX..XX.         .                            .XX.         . X.   .  .    .              ....            X.  .  . .          X...............   ",
+"  .................               .      .      XXXXXXXXXXXXXXX        .o....XXX...          .                             ...          .X.  XX       .            X....             X.     . .         .................   ",
+"                                   .    .                              ......XXXX..         ..                                .          . . .       .           X....X               X.   X.X.                             ",
+"                                   .    .                               .....XXX..         ..                          X...   .X          .. .                  ....                   X......                              ",
+"                                    ....                                  ......          ..                           .   ...X            ..                   ..                          .X                              ",
+"                                                                                          .                                                                                              ...X                               ",
+"                                                                                                                                                                                                                            ",
+"                                                                                                                                                                                                                            ",
+"                                                                                                                                                                                                                            "};
diff --git a/XPM/tile.xpm b/XPM/tile.xpm
new file mode 100644
index 0000000..e65c234
--- /dev/null
+++ b/XPM/tile.xpm
@@ -0,0 +1,121 @@
+/* XPM */
+static char *tile_xpm[] = {
+"64 64 54 1",
+" 	c #F3CEF3CEF3CE",
+".	c #000000000000",
+"X	c #514461856185",
+"o	c #A289A289B2CA",
+"O	c #A289A289A289",
+"+	c #A2899248B2CA",
+"@	c #9248A289A289",
+"#	c #A2899248A289",
+"$	c #92489248A289",
+"%	c #924892489248",
+"&	c #92488207A289",
+"*	c #820792489248",
+"=	c #924882079248",
+"-	c #820782079248",
+";	c #820782078207",
+":	c #820771C69248",
+">	c #618551446185",
+",	c #9248A289B2CA",
+"<	c #92489248B2CA",
+"1	c #82079248A289",
+"2	c #82078207A289",
+"3	c #71C682079248",
+"4	c #71C682078207",
+"5	c #514451446185",
+"6	c #514451445144",
+"7	c #820771C68207",
+"8	c #410351445144",
+"9	c #514441035144",
+"0	c #71C671C69248",
+"q	c #71C671C68207",
+"w	c #71C671C671C6",
+"e	c #410341035144",
+"r	c #71C661858207",
+"t	c #618571C68207",
+"y	c #410351444103",
+"u	c #410341034103",
+"i	c #618571C671C6",
+"p	c #410330C24103",
+"a	c #30C241034103",
+"s	c #71C6618571C6",
+"d	c #6185618571C6",
+"f	c #618561858207",
+"g	c #30C230C230C2",
+"h	c #618561856185",
+"j	c #30C230C24103",
+"k	c #5144618571C6",
+"l	c #30C2410330C2",
+"z	c #6185514471C6",
+"x	c #208130C230C2",
+"c	c #30C2208130C2",
+"v	c #5144514471C6",
+"b	c #2081208130C2",
+"n	c #208120812081",
+"m	c #410330C25144",
+"                                                               .",
+"                                                              X.",
+"  oOoO+O+O+O+@#$+@#$#$#$$$#$$%&%&%&%&*&*&*=-=*=-=-=--;---;:;:;>.",
+"  oo at o,o at o@o at +@+@<@$@$@$@$@$1$$$*$*$*&*&*2*&*2*-*-*-----3-3-4-X.",
+"  oO+OoO#O+@#@#@#$#@#$#%#$$%$%$%&%&*=%&*=*=*=-=-=--;-;-;:;:;:;5.",
+"  ,ooo at +@+ at +@+@<@#@<@$$$$$$$$$*$1$*&*&*&*&*2*---*-----3---4:4:6.",
+"  +O+O+O+@#$#@#$#$#$$%$$$%&%&%&%&*=*&*=-=*=---=--;---;:;:4:;:45.",
+"  @o at o@o at +@+@<@$@$@$$$@$1$1$*$*$*&*&*2*=*2*-*-*-----4-3-4:4-4:6.",
+"  +O#O+@#@#@#$#$#$#%#%$%&%$%&%&*=*&*=*=*=-=-=--;-;-;:;:;:;:4745.",
+"  @+ at +@+ at +@<@#@$@$$$$$$$$$*$*$*&*&*&*&*2*---*-----3---4:4:4:4:8.",
+"  #O+@#$#@#$#$#$$%$$$%&%&%&%&*=*&*=-=-=---=--;:;-;:;:4:4:474:49.",
+"  @o@<@+@<@$@$@$$$$$1$1$*$*$*&*&*2*=*2*-*-*-----4-4-4:4:4:4:408.",
+"  +@#@#@#$#$#$$%#%$%&%$%&%&*=*&*=*=*=-=-=--;-;-;:;:;:;:474747q9.",
+"  @+ at +@<@$$$@$$$$$1$$$*&*$*&*&*&*&*2*---------3-3-4:4:4:4:404q8.",
+"  #$#@#$#$#$$%$$$%&%&%&%&*=-&*=-=-=---=--;:;:;:;:4:4:474:47q7q9.",
+"  @#@<@$@$@$$$$$*$1$*$*$*&*&*2*-*2*-*-*-3---4-4-4:4:4:4:404q4q8.",
+"  #@#$#$#$$%$%$%&%$%&%&*=*=*=-=*=-=;=--;-;-;:;:47;:474747q7q7q9.",
+"  @<@$$$@$$$$$1$$$*&*&*&*&*&*=*2*---------4-3-4:4:4:4:404qq04q8.",
+"  #$#$#$$%$%$%&%&%&%&*=-&*=-=-=------;:;:;:;:4:4:47q747qqq7qqq9.",
+"  @$@$@$$$$$*$1$*$*$*&*&*2*-*-*---*-3-3-4-4-4:4:4:4:404q4q4qqq8.",
+"  #$#$$%$%$%&%&%&%&*=*=*=-=-=-=;=--;:;-;:;:474:474747q7q7qqwqw9.",
+"  $$@$$$$$*$$$*&*&*&*&*2*=*2*---------4-3-4:4:4:4:404qqq4qqqqqe.",
+"  #$$%$%$%&%&*&%&*=-&*=-=-=------;:;:;:;:4:4:47q7q7qqq7qqwrqqw9.",
+"  @$$$$$*$1$*&*$*2*&*2*-*-*-----3-3-4-4-4:4:404:404q4q4qqqqqtqy.",
+"  $%$%$%&%&%=%&*=*=*=-=-=--;=--;:;-;:;:474:474747q7q7qqwqwqwrwe.",
+"  $$$$*$1$*&*&*&*&*2*--2*-----3---4:3-4:4:4:4:404qqqqqqqqqtqtqu.",
+"  &%$%&%&*&*&*=-=*=-=-=--;---;:;:;:;:4:4:47q7q7qqq7qqwrqrwrwrip.",
+"  $$*$*$*&*&*2*&*2*-*-*-----3-3-4-4-4:4:404q404q4q4qtqqqiqtqiru.",
+"  $%&%&*=%&*=*=*=-=-=--;-;-;:;-;:;:474:47q747q7q7qqwqwqwrwrirwu.",
+"  *$1$*&*&*&*&*2*---*-----3---4:4:4:4:4:4:404qqqqqqqqqtqtqirira.",
+"  &%&*=*&*=-=*=-=-=--;---;:;:;:;:4:4:47q7q7qqqqqqwrqrwrwriririp.",
+"  *$*&*&*2*&*2*-*-*-----3-3-4-4-4:4:404q4q4qqq4qtqtqiqiqiriqira.",
+"  &*=*&*=*=*=-=-=--;-;-;:;:;:;:474:47q7q7q7q7qqwrwqwrwrirwrisip.",
+"  *&*&*&*&*2*---*-----3---4:4:4:4:404:404qqqqqqqqqtqtqiriririra.",
+"  =*&*=-=*=---=--;---;:;:4:;:474:47q7q7qqqqqqwrwrwrwriririsdrdp.",
+"  *&*2*=*2*-*-*-----4-3-4:4-4:4:404q4q4qqqqqtqtqiqiqiriqifirifa.",
+"  &*=*=*=-=-=--;-;-;:;:;:;:474747q7q7qqq7qqwrwqwrwrirwrisisisdp.",
+"  *&*&*2*---*-----3-3-4:4:4:4:404qq04qqqqqtqqqirtqiririririfida.",
+"  =-=-=---=--;:;-;:;:4:4:474:47q7q7qqqqqqwrwrwrwriririsdrdsdddp.",
+"  *=*2*-*-*-----4-4-4:4:4:4:404q4q4qqqqqtqtqiqiqiriqifififidida.",
+"  =*=-=-=--;-;-;:;:4:;:474747q7q7qqwqwqwrwqwrwrirwrisdsisdsdsdp.",
+"  *2*---------4-3-4:4:4:4:404qq04qqqqqtqqqiririririririfidddddg.",
+"  =---=--;:;:;:;:4:4:474:47q7q7qqqqqqwrwrwrwriririsdsdsddddddhj.",
+"  *---*-3---4-4-4:4:4:4:404q4q4qqqqqtqtqiqiqiririfififidddidkdl.",
+"  =;=--;:;-;:;:474:474747q7q7qqwqwqwrwrwrwrirwrisdsdsdsdsddhzhj.",
+"  --------4-3-4:4:4:4:404qq04qqqqqtqqqiririririfirifidddddddddx.",
+"  ---;:;:;:;:4:4:47q747qqq7qqwqqqwrwrirwriririsdsdsddddddhzhzhc.",
+"  --3-3-4-4-4:4:4:4:404q4q4qqqqqtqtqiriqiririfififidddddkdkdXdx.",
+"  -;:;-;:;:474:474747q7q7qqwqwqwrwrwrwrisisisdsdsdddsddhzhdhzhg.",
+"  ----4-3-4:4:4:4:404qqq4qqqqqtqtqiriririrififdfidddddkdddkzkdx.",
+"  :;:;:;:4:4:47q7q7qqq7qqwrqqwrwriririririsdsdsddddddhzhzhzhzXc.",
+"  3-4-4-4:4:404:404q4q4qqqqqtqtqiriqiririfidididddddkdkdXdXdXzx.",
+"  -;:;:474:47q747q7q7qqwqwqwrwrirwrisisisdsdsddddddhzhdhzhzXzhc.",
+"  4:4-4:4:4:4:404qqqqqqqqqtqtqiriririrififdfidddddkdddkzkdXzXzx.",
+"  :;:4:4:47q7q7qqq7qqwrqrwrwriririsirisdsdsddddddhzhzhzhzXzXzXc.",
+"  4-4:4:404q404qqq4qtqqqiqtqiriqiririfidididddddkdkdXdXdXzXzXvx.",
+"  :474:47q7q7q7q7qqwrwqwrwrirwrisisisdsdsddddddhzhzhzhzXzhzX>5c.",
+"  4:4:4:4:404qqqqqqqqqtqtqiririririfiddfidddddkdddXzkdXzXzXvXzx.",
+"  :4:47q7q7qqqqqqwrwrwrwriririsdrisdddsddddddhzhzXzhzXzXzX>5>5c.",
+"  4:404q4q4qqqqqtqtqiqiqiriqiririfidididddddkdkdXzXdXzXzXvXvXvx.",
+"  :47q7q7q7q7qqwrwqwrwrirwrisisisdsdsddhdddhzhzhzhzXzXzX>5>5>5b.",
+"  404:404qqqqqqqqqiqtqiririririfidddidddddkdkdXzkzXzXzXvXv5vX5n.",
+"  >65656569698989y9e9u9ueumueupupapaplpgjgjgjgcgcgcgcxcbcncnbnb.",
+" ..............................................................."};
diff --git a/XPM/wmmixer.xpm b/XPM/wmmixer.xpm
new file mode 100644
index 0000000..8effca6
--- /dev/null
+++ b/XPM/wmmixer.xpm
@@ -0,0 +1,74 @@
+/* XPM */
+static char * wmmixer_xpm[] = {
+"64 64 7 1",
+" 	c None",
+".	c #000000",
+"X	c #282828 s back_color",
+"o	c #C7C3C7",
+"O	c #F7F3FF",
+"+	c #86828E",
+"@	c #AEAAAE",
+"                                                                ",
+"                                                                ",
+"                                                                ",
+"                                                                ",
+"    ..........................     .........................    ",
+"    .XXXXXXXXXXXXXXXXXXXXXXXXo     .XXXXXXXXXXXXXXXXXXXXXXXo    ",
+"    .XXXXXXXXXXXXXXXXXXXXXXXXo     .XXXXXXXXXXXXXXXXXXXXXXXo    ",
+"    .XXXXXXXXXXXXXXXXXXXXXXXXo     .XXXXXXXXXXXXXXXXXXXXXXXo    ",
+"    .XXXXXXXXXXXXXXXXXXXXXXXXo     .XXXXXXXXXXXXXXXXXXXXXXXo    ",
+"    .XXXXXXXXXXXXXXXXXXXXXXXXo     .XXXXXXXXXXXXXXXXXXXXXXXo    ",
+"    .XXXXXXXXXXXXXXXXXXXXXXXXo     .XXXXXXXXXXXXXXXXXXXXXXXo    ",
+"    .XXXXXXXXXXXXXXXXXXXXXXXXo     .XXXXXXXXXXXXXXXXXXXXXXXo    ",
+"    .XXXXXXXXXXXXXXXXXXXXXXXXo     .XXXXXXXXXXXXXXXXXXXXXXXo    ",
+"    .XXXXXXXXXXXXXXXXXXXXXXXXo     .XXXXXXXXXXXXXXXXXXXXXXXo    ",
+"    .XXXXXXXXXXXXXXXXXXXXXXXXo     .XXXXXXXXXXXXXXXXXXXXXXXo    ",
+"    .XXXXXXXXXXXXXXXXXXXXXXXXo     .XXXXXXXXXXXXXXXXXXXXXXXo    ",
+"    .XXXXXXXXXXXXXXXXXXXXXXXXo     .XXXXXXXXXXXXXXXXXXXXXXXo    ",
+"    .XXXXXXXXXXXXXXXXXXXXXXXXo     .XXXXXXXXXXXXXXXXXXXXXXXo    ",
+"    .XXXXXXXXXXXXXXXXXXXXXXXXo     .XXXXXXXXXXXXXXXXXXXXXXXo    ",
+"    .XXXXXXXXXXXXXXXXXXXXXXXXo     .XXXXXXXXXXXXXXXXXXXXXXXo    ",
+"    .XXXXXXXXXXXXXXXXXXXXXXXXo     .XXXXXXXXXXXXXXXXXXXXXXXo    ",
+"    .XXXXXXXXXXXXXXXXXXXXXXXXo     .XXXXXXXXXXXXXXXXXXXXXXXo    ",
+"    .XXXXXXXXXXXXXXXXXXXXXXXXo     .XXXXXXXXXXXXXXXXXXXXXXXo    ",
+"    .XXXXXXXXXXXXXXXXXXXXXXXXo     .XXXXXXXXXXXXXXXXXXXXXXXo    ",
+"    .XXXXXXXXXXXXXXXXXXXXXXXXo     .XXXXXXXXXXXXXXXXXXXXXXXo    ",
+"    .XXXXXXXXXXXXXXXXXXXXXXXXo     .XXXXXXXXXXXXXXXXXXXXXXXo    ",
+"    .XXXXXXXXXXXXXXXXXXXXXXXXo     .XXXXXXXXXXXXXXXXXXXXXXXo    ",
+"    oooooooooooooooooooooooooo     .XXXXXXXXXXXXXXXXXXXXXXXo    ",
+"                                   .XXXXXXXXXXXXXXXXXXXXXXXo    ",
+"                                   .XXXXXXXXXXXXXXXXXXXXXXXo    ",
+"                                   .XXXXXXXXXXXXXXXXXXXXXXXo    ",
+"                                   .XXXXXXXXXXXXXXXXXXXXXXXo    ",
+"    ..........................     .XXXXXXXXXXXXXXXXXXXXXXXo    ",
+"    .OOOOOOOOOOO+OOOOOOOOOOO+o     .XXXXXXXXXXXXXXXXXXXXXXXo    ",
+"    .O@@@@@@@@@@.O@@@@@@@@@@.o     .XXXXXXXXXXXXXXXXXXXXXXXo    ",
+"    .O@@@@@@.@@@.O@@@.@@@@@@.o     .XXXXXXXXXXXXXXXXXXXXXXXo    ",
+"    .O@@@@@..@@@.O@@@..@@@@@.o     .XXXXXXXXXXXXXXXXXXXXXXXo    ",
+"    .O@@@@...@@@.O@@@...@@@@.o     .XXXXXXXXXXXXXXXXXXXXXXXo    ",
+"    .O@@@....@@@.O@@@....@@@.o     .XXXXXXXXXXXXXXXXXXXXXXXo    ",
+"    .O@@@@...@@@.O@@@...@@@@.o     .XXXXXXXXXXXXXXXXXXXXXXXo    ",
+"    .O@@@@@..@@@.O@@@..@@@@@.o     .XXXXXXXXXXXXXXXXXXXXXXXo    ",
+"    .O@@@@@@.@@@.O@@@.@@@@@@.o     .XXXXXXXXXXXXXXXXXXXXXXXo    ",
+"    .O@@@@@@@@@@.O@@@@@@@@@@.o     .XXXXXXXXXXXXXXXXXXXXXXXo    ",
+"    .+...........+...........o     .XXXXXXXXXXXXXXXXXXXXXXXo    ",
+"    oooooooooooooooooooooooooo     .XXXXXXXXXXXXXXXXXXXXXXXo    ",
+"                                   .XXXXXXXXXXXXXXXXXXXXXXXo    ",
+"    ..........................     .XXXXXXXXXXXXXXXXXXXXXXXo    ",
+"    .OOOOOOOOOOOOOOOOOOOOOOO+o     .XXXXXXXXXXXXXXXXXXXXXXXo    ",
+"    .O@@@@@@@@@@@@@@@@@@@@@@.o     .XXXXXXXXXXXXXXXXXXXXXXXo    ",
+"    .O@@@@@@@@@@@@@.@@@@@@@@.o     .XXXXXXXXXXXXXXXXXXXXXXXo    ",
+"    .O@@@@@@@@@... at .@@@@@@@@.o     .XXXXXXXXXXXXXXXXXXXXXXXo    ",
+"    .O@@@@@@@@.. at ...@@@@@@@@.o     .XXXXXXXXXXXXXXXXXXXXXXXo    ",
+"    .O@@@@@@@@.@@@..@@@@@@@@.o     .XXXXXXXXXXXXXXXXXXXXXXXo    ",
+"    .O@@@@@@@@.. at ...@@@@@@@@.o     .XXXXXXXXXXXXXXXXXXXXXXXo    ",
+"    .O@@@@@@@@@... at .@@@@@@@@.o     .XXXXXXXXXXXXXXXXXXXXXXXo    ",
+"    .O@@@@@@@@@@@@@.@@@@@@@@.o     .XXXXXXXXXXXXXXXXXXXXXXXo    ",
+"    .O@@@@@@@@@@@@@@@@@@@@@@.o     .XXXXXXXXXXXXXXXXXXXXXXXo    ",
+"    .+.......................o     .XXXXXXXXXXXXXXXXXXXXXXXo    ",
+"    oooooooooooooooooooooooooo     ooooooooooooooooooooooooo    ",
+"                                                                ",
+"                                                                ",
+"                                                                ",
+"                                                                ",
+"                                                                "};
diff --git a/mixctl.h b/mixctl.h
new file mode 100644
index 0000000..d56b2f7
--- /dev/null
+++ b/mixctl.h
@@ -0,0 +1,218 @@
+// mixctl.h - defines MixCtl class to provide easy control of audio mixer functions.
+// 07/05/98  Release 0.5
+// Copyright (C) 1998  Sam Hawker <shawkie at geocities.com>
+// This software comes with ABSOLUTELY NO WARRANTY
+// This software is free software, and you are welcome to redistribute it
+// under certain conditions
+// See the COPYING file for details.
+
+// Although mixctl.h is an integral part of wmmixer, it may also be distributed seperately.
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <sys/ioctl.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#include <unistd.h>
+#include <malloc.h>
+#ifdef __NetBSD__
+#include <soundcard.h>
+#endif
+#ifdef __FreeBSD__
+#include <machine/soundcard.h>
+#endif
+#ifdef __linux__
+#include <linux/soundcard.h>
+#endif
+
+#ifndef TRUE
+#define FALSE 0
+#define TRUE 1
+#endif
+
+class MixCtl
+{
+public:
+   MixCtl(char *dname){
+      device=(char *)malloc(sizeof(char)*(strlen(dname)+1));
+      strcpy(device,dname);
+      if(mixfdopen=(mixfd=open(device,O_NONBLOCK))!=-1){
+         nrdevices=SOUND_MIXER_NRDEVICES;
+         char *devnames[]=SOUND_DEVICE_NAMES;
+         char *devlabels[]=SOUND_DEVICE_LABELS;
+         ioctl(mixfd, SOUND_MIXER_READ_DEVMASK, &devmask);
+         ioctl(mixfd, SOUND_MIXER_READ_STEREODEVS, &stmask);
+         ioctl(mixfd, SOUND_MIXER_READ_RECMASK, &recmask);
+         ioctl(mixfd, SOUND_MIXER_READ_CAPS, &caps);
+         mixdevs=(struct MixDev *)malloc(sizeof(struct MixDev)*nrdevices);
+         int mixmask=1;
+         for(int i=0;i<nrdevices;i++){
+            mixdevs[i].support=devmask & mixmask;
+            mixdevs[i].stereo=stmask & mixmask;
+            mixdevs[i].records=recmask & mixmask;
+            mixdevs[i].mask=mixmask;
+            mixdevs[i].name=devnames[i];
+            mixdevs[i].label=devlabels[i];
+            mixmask*=2;
+         }
+         doStatus();
+      }
+   }
+   ~MixCtl(){
+      if(mixfdopen){
+         if(mixdevs!=NULL)
+            free(mixdevs);
+         close(mixfd);
+      }
+   }
+   void doStatus(){
+      ioctl(mixfd, SOUND_MIXER_READ_RECSRC, &recsrc);
+      for(int i=0;i<nrdevices;i++){
+	 if(mixdevs[i].support)
+	    ioctl(mixfd, MIXER_READ(i), &mixdevs[i].value);
+         mixdevs[i].recsrc=(recsrc & mixdevs[i].mask);
+      }
+   }
+
+   // Return volume for a device, optionally reading it from device first.
+   // Can be used as a way to avoid calling doStatus().
+   int readVol(int dev, bool read){
+      if(read)
+         ioctl(mixfd, MIXER_READ(dev), &mixdevs[dev].value);
+      return mixdevs[dev].value;
+   }
+
+   // Return left and right componenets of volume for a device.
+   // If you are lazy, you can call readVol to read from the device, then these
+   // to get left and right values.
+   int readLeft(int dev){
+      return mixdevs[dev].value%256;
+   }
+   int readRight(int dev){
+      return mixdevs[dev].value/256;
+   }
+
+   // Write volume to device. Use setVolume, setLeft and setRight first.
+   void writeVol(int dev){
+      ioctl(mixfd, MIXER_WRITE(dev), &mixdevs[dev].value);
+   }
+
+   // Set volume (or left or right component) for a device. You must call writeVol to write it.
+   void setVol(int dev, int value){
+      mixdevs[dev].value=value;
+   }
+   void setBoth(int dev, int l, int r){
+      mixdevs[dev].value=256*r+l;
+   }
+   void setLeft(int dev, int l){
+      int r;
+      if(mixdevs[dev].stereo)
+         r=mixdevs[dev].value/256;
+      else
+         r=l;
+      mixdevs[dev].value=256*r+l;
+   }
+   void setRight(int dev, int r){
+      int l;
+      if(mixdevs[dev].stereo)
+         l=mixdevs[dev].value%256;
+      else
+         l=r;
+      mixdevs[dev].value=256*r+l;
+   }
+
+   // Return record source value for a device, optionally reading it from device first.
+   bool readRec(int dev, bool read){
+      if(read){
+	 ioctl(mixfd, SOUND_MIXER_READ_RECSRC, &recsrc);
+         mixdevs[dev].recsrc=(recsrc & mixdevs[dev].mask);
+      }
+      return mixdevs[dev].recsrc;
+   }
+
+   // Write record source values to device. Use setRec first.
+   void writeRec(){
+      ioctl(mixfd, SOUND_MIXER_WRITE_RECSRC, &recsrc);
+   }
+
+   // Make a device (not) a record source.
+   void setRec(int dev, bool rec){
+      if(rec){
+         if(caps & SOUND_CAP_EXCL_INPUT)
+            recsrc=mixdevs[dev].mask;
+         else
+            recsrc|=mixdevs[dev].mask;
+      }
+      else
+         recsrc&=~mixdevs[dev].mask;
+   }
+
+   // Return various other info
+   char *getDevName(){
+      return device;
+   }
+   int getNrDevices(){
+      return nrdevices;
+   }
+   int getCapabilities(){
+      return caps;
+   }
+   bool getSupport(int dev){
+      return mixdevs[dev].support;
+   }
+   bool getStereo(int dev){
+      return mixdevs[dev].stereo;
+   }
+   bool getRecords(int dev){
+      return mixdevs[dev].records;
+   }
+   char *getName(int dev){
+      return mixdevs[dev].name;
+   }
+   char *getLabel(int dev){
+      return mixdevs[dev].label;
+   }
+
+private:
+   int mixfd;
+   int mixfdopen;
+   char *device;
+
+   struct MixDev{
+      bool support;
+      bool stereo;
+      bool recsrc;
+      bool records;
+      char *name;
+      char *label;
+      int value;
+      int mask;
+   };
+
+   int nrdevices;       // maximum number of devices
+   int devmask;         // supported devices
+   int stmask;          // stereo devices
+   int recmask;         // devices which can be recorded from
+   int caps;            // capabilities
+   int recsrc;          // devices which are being recorded from
+   struct MixDev *mixdevs;
+};
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/wmmixer.cc b/wmmixer.cc
new file mode 100644
index 0000000..24103bf
--- /dev/null
+++ b/wmmixer.cc
@@ -0,0 +1,573 @@
+// wmmixer - a mixer designed for WindowMaker
+// 07/05/98  Release 0.8
+// Copyright (C) 1998  Sam Hawker <shawkie at geocities.com>
+// This software comes with ABSOLUTELY NO WARRANTY
+// This software is free software, and you are welcome to redistribute it
+// under certain conditions
+// See the README file for a more complete notice.
+
+#define WINDOWMAKER FALSE
+#define USESHAPE FALSE
+#define NAME "wmmixer"
+#define CLASS "WMMixer"
+
+#define DEFAULTDEVICE "/dev/mixer"
+#define BACKCOLOR "#282828"
+#define LEDCOLOR "green"
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+
+#include <X11/X.h>
+#include <X11/Xlib.h>
+#include <X11/Xutil.h>
+#include <X11/Xproto.h>
+#include <X11/xpm.h>
+#include <X11/extensions/shape.h>
+
+#include "mixctl.h"
+
+Pixmap back;
+Pixmap tile;
+Pixmap disp;
+Pixmap mask;
+Pixmap symb;
+Pixmap nrec;
+
+unsigned long fcolor,bcolor;
+
+#include "XPM/wmmixer.xpm"
+#include "XPM/tile.xpm"
+#include "XPM/symbols.xpm"
+#include "XPM/norec.xpm"
+
+bool wmaker = WINDOWMAKER;
+bool ushape = USESHAPE;
+char txtdpy[256] = "";
+char txtdev[256] = DEFAULTDEVICE;
+char ledcol[256] = LEDCOLOR;
+char bckcol[256] = BACKCOLOR;
+
+Atom _XA_GNUSTEP_WM_FUNC;
+Atom deleteWin;
+
+Display *dpy;
+Window Win[2];
+Window Root;
+XWMHints *hints;
+GC WinGC;
+int activeWin;
+
+int curDev=0;
+int curShowRec;
+int curRec;
+int curLeft;
+int curRight;
+
+// For new buttons
+int btnstate=0;
+#define btnNext  1
+#define btnPrev  2
+#define btnRec   4
+
+// With repeat next/prev if you hold down mouse button
+#define btnrepeat 5
+int btntimer=0;
+
+int Channels=0;
+int Channel[20];
+int sympic[20]={0,7,8,2,1,6,4,5,3,9,9,9,9,9,9,9,9,9,9,9};
+
+bool dragging=FALSE;
+
+MixCtl *mixctl;
+
+// Standard dock-app stuff
+void initXWin(int argc, char *argv[]);
+void freeXWin();
+void createWin(Window *win);
+unsigned long getColor(char *colorName, float dim);
+
+// Custom dock-app stuff
+void scanArgs(int argc, char *argv[]);
+void readFile();
+void checkVol(bool forced=TRUE);
+void pressEvent(XButtonEvent *xev);
+void releaseEvent(XButtonEvent *xev);
+void motionEvent(XMotionEvent *xev);
+void repaint();
+void update();
+void drawLeft();
+void drawRight();
+void drawBtns(int btns);
+void drawBtn(int x, int y, int w, int h, bool down);
+
+int main(int argc,char *argv[])
+{
+   scanArgs(argc,argv);
+   initXWin(argc,argv);
+
+   XGCValues gcv;
+   unsigned long gcm;
+   gcm = GCForeground|GCBackground|GCGraphicsExposures;
+   gcv.graphics_exposures = False;
+   WinGC = XCreateGC(dpy, Root, gcm, &gcv);
+
+   XpmAttributes pixatt;
+   XpmColorSymbol ledcols[4]={{"led_color_high", NULL, 0},
+                              {"led_color_med",  NULL, 0},
+                              {"led_color_low",  NULL, 0},
+                              {"back_color",     NULL, 0}};
+   ledcols[0].pixel=getColor(ledcol, 1.00);
+   ledcols[1].pixel=getColor(ledcol, 1.65);
+   ledcols[2].pixel=getColor(ledcol, 2.60);
+   ledcols[3].pixel=getColor(bckcol, 1.00);
+   pixatt.numsymbols=4;
+   pixatt.colorsymbols=ledcols;
+   pixatt.exactColors=FALSE;
+   pixatt.closeness=40000;
+   pixatt.valuemask=XpmColorSymbols | XpmExactColors | XpmCloseness;
+   XpmCreatePixmapFromData(dpy, Root, wmmixer_xpm, &back, &mask, &pixatt);
+   XpmCreatePixmapFromData(dpy, Root, tile_xpm, &tile, NULL, &pixatt);
+   XpmCreatePixmapFromData(dpy, Root, symbols_xpm, &symb, NULL, &pixatt);
+   XpmCreatePixmapFromData(dpy, Root, norec_xpm, &nrec, NULL, &pixatt);
+   disp = XCreatePixmap(dpy, Root, 64, 64, DefaultDepth(dpy,DefaultScreen(dpy)));
+
+   fcolor=ledcols[0].pixel;
+   bcolor=ledcols[2].pixel;
+
+   // Install mask or copy background tile
+   if(wmaker || ushape)
+      XShapeCombineMask(dpy, Win[activeWin], ShapeBounding, 0, 0, mask, ShapeSet);
+   else
+      XCopyArea(dpy, tile, disp, WinGC, 0,0,64,64,0,0);
+
+   // Copy background
+   XSetClipMask(dpy, WinGC, mask);
+   XCopyArea(dpy, back, disp, WinGC, 0,0,64,64,0,0);
+   XSetClipMask(dpy, WinGC, None);
+
+   mixctl = new MixCtl(txtdev);
+
+   for(int i=0;i<mixctl->getNrDevices();i++){
+      if(mixctl->getSupport(i)){
+         Channel[Channels]=i;
+         Channels++;
+      }
+   }
+
+   readFile();
+
+   if(Channels==0)
+      fprintf(stderr,"Sorry, no supported channels found\n");
+   else{
+      checkVol(TRUE);
+
+      XEvent event;
+      XSelectInput(dpy, Win[activeWin], ExposureMask | ButtonPressMask | ButtonReleaseMask | ButtonMotionMask);
+      XMapWindow(dpy, Win[0]);
+
+      bool finished=FALSE;
+      while(!finished){
+         while(XPending(dpy)){
+            XNextEvent(dpy,&event);
+            switch(event.type){
+             case Expose:
+                repaint();
+             break;
+             case ButtonPress:
+                pressEvent(&event.xbutton);
+             break;
+             case ButtonRelease:
+                releaseEvent(&event.xbutton);
+             break;
+             case MotionNotify:
+                motionEvent(&event.xmotion);
+             break;
+             case ClientMessage:
+                if(event.xclient.data.l[0]==deleteWin)
+                   finished=TRUE;
+             break;
+            }
+         }
+
+         // Repeat next/prev
+         if(btnstate & (btnPrev | btnNext)){
+            btntimer++;
+            if(btntimer>=btnrepeat){
+               if(btnstate & btnNext)
+                  curDev++;
+               else
+                  curDev--;
+               if(curDev<0)
+                  curDev=Channels-1;
+               if(curDev>=Channels)
+                  curDev=0;
+               checkVol(TRUE);      // forced because of changed mount point
+               btntimer=0;
+            }
+         }
+         else{
+            // Check volume, and update as needed
+            checkVol(FALSE);
+         }
+         XFlush(dpy);
+         usleep(50000L);
+      }
+   }
+   XFreeGC(dpy, WinGC);
+   XFreePixmap(dpy, disp);
+   XFreePixmap(dpy, mask);
+   XFreePixmap(dpy, back);
+   XFreePixmap(dpy, tile);
+   XFreePixmap(dpy, symb);
+   XFreePixmap(dpy, nrec);
+   freeXWin();
+   delete mixctl;
+   return 0;
+}
+
+void initXWin(int argc, char *argv[]){
+   if((dpy=XOpenDisplay(txtdpy))==NULL){
+      fprintf(stderr,"You're probably trying to run an X app from the console, you idiot! RTFM\n");
+      exit(1);
+   }
+   _XA_GNUSTEP_WM_FUNC = XInternAtom(dpy, "_GNUSTEP_WM_FUNCTION", False);
+   deleteWin = XInternAtom(dpy, "WM_DELETE_WINDOW", False);
+   Root=DefaultRootWindow(dpy);
+   createWin(&Win[0]);
+   createWin(&Win[1]);
+   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], &deleteWin, 1);
+}
+
+void freeXWin(){
+   XDestroyWindow(dpy, Win[0]);
+   XDestroyWindow(dpy, Win[1]);
+   XCloseDisplay(dpy);
+}
+
+void createWin(Window *win){
+   XClassHint classHint;
+   *win = XCreateSimpleWindow(dpy, Root, 10, 10, 64, 64,0,0,0);
+   classHint.res_name = NAME;
+   classHint.res_class = CLASS;
+   XSetClassHint(dpy, *win, &classHint);
+}
+
+unsigned long getColor(char *colorName, float dim)
+{
+   XColor Color;
+   XWindowAttributes Attributes;
+
+   XGetWindowAttributes(dpy, Root, &Attributes);
+   Color.pixel = 0;
+
+   XParseColor (dpy, Attributes.colormap, colorName, &Color);
+   Color.red=(unsigned short)(Color.red/dim);
+   Color.blue=(unsigned short)(Color.blue/dim);
+   Color.green=(unsigned short)(Color.green/dim);
+   Color.flags=DoRed | DoGreen | DoBlue;
+   XAllocColor (dpy, Attributes.colormap, &Color);
+
+   return Color.pixel;
+}
+
+void scanArgs(int argc, char *argv[]){
+   for(int i=1;i<argc;i++){
+      if(strcmp(argv[i],"-h")==0 || strcmp(argv[i],"-help")==0 || strcmp(argv[i],"--help")==0){
+         fprintf(stderr,"wmmixer - a mixer designed for WindowMaker\n07/05/98  Release 0.8\n");
+         fprintf(stderr,"Copyright (C) 1998  Sam Hawker <shawkie at geocities.com>\n");
+         fprintf(stderr,"This software comes with ABSOLUTELY NO WARRANTY\n");
+         fprintf(stderr,"This software is free software, and you are welcome to redistribute it\n");
+         fprintf(stderr,"under certain conditions\n");
+         fprintf(stderr,"See the README file for a more complete notice.\n\n");
+         fprintf(stderr,"usage:\n\n   %s [options]\n\noptions:\n\n",argv[0]);
+         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,"   -l led_color           use the specified color for led display\n");
+         fprintf(stderr,"   -b back_color          use the specified color for backgrounds\n");
+         fprintf(stderr,"   -d mix_device          use specified device  (rather than /dev/mixer)\n");
+         fprintf(stderr,"   -display display       select target display (see X manual pages)\n\n");
+         exit(0);
+      }
+      if(strcmp(argv[i],"-w")==0)
+         wmaker=TRUE;
+      if(strcmp(argv[i],"-s")==0)
+         ushape=TRUE;
+      if(strcmp(argv[i],"-d")==0){
+	 if(i<argc-1){
+            i++;
+            sprintf(txtdev,"%s",argv[i]);
+         }
+         continue;
+      }
+      if(strcmp(argv[i],"-l")==0){
+	 if(i<argc-1){
+            i++;
+            sprintf(ledcol,"%s",argv[i]);
+	 }
+         continue;
+      }
+      if(strcmp(argv[i],"-b")==0){
+	 if(i<argc-1){
+            i++;
+            sprintf(bckcol,"%s",argv[i]);
+	 }
+         continue;
+      }
+      if(strcmp(argv[i],"-display")==0){
+	 if(i<argc-1){
+            i++;
+            sprintf(txtdpy,"%s",argv[i]);
+         }
+         continue;
+      }
+   }
+}
+
+void readFile(){
+   FILE *rcfile;
+   char rcfilen[256];
+   char buf[256];
+   int done;
+   sprintf(rcfilen,"%s/.wmmixer",getenv("HOME"));
+   if((rcfile=fopen(rcfilen,"r"))!=NULL){
+      Channels=0;
+      do{
+         fgets(buf,250,rcfile);
+         if((done=feof(rcfile))==0){
+            buf[strlen(buf)-1]=0;
+            if(strncmp(buf,"addchannel ",strlen("addchannel "))==0){
+               sscanf(buf,"addchannel %i",&Channel[Channels]);
+               if(Channel[Channels]<mixctl->getNrDevices()){
+                  if(mixctl->getSupport(Channel[Channels]))
+                     Channels++;
+	       }
+            }
+            if(strncmp(buf,"setmono ",strlen("setmono "))==0){
+               if(Channels>0){
+                  int value;
+                  sscanf(buf,"setmono %i",&value);
+                  mixctl->setLeft(Channel[Channels-1],value);
+                  mixctl->setRight(Channel[Channels-1],value);
+                  mixctl->writeVol(Channel[Channels-1]);
+               }
+            }
+            if(strncmp(buf,"setleft ",strlen("setleft "))==0){
+	       if(Channels>0){
+                  int value;
+                  sscanf(buf,"setleft %i",&value);
+                  mixctl->setLeft(Channel[Channels-1],value);
+                  mixctl->writeVol(Channel[Channels-1]);
+	       }
+            }
+            if(strncmp(buf,"setright ",strlen("setright "))==0){
+	       if(Channels>0){
+                  int value;
+                  sscanf(buf,"setleft %i",&value);
+                  mixctl->setRight(Channel[Channels-1],value);
+                  mixctl->writeVol(Channel[Channels-1]);
+	       }
+            }
+            if(strncmp(buf,"setrecsrc ",strlen("setrecsrc "))==0){
+	       if(Channels>0)
+                  mixctl->setRec(Channel[Channels-1],(strncmp(buf+strlen("setrecsrc "),"TRUE",strlen("TRUE"))==0));
+            }
+         }
+      }  while(done==0);
+      fclose(rcfile);
+      mixctl->writeRec();       // delayed write, to avoid interference from low-level drivers.
+   }
+}
+
+void checkVol(bool forced){
+   mixctl->readVol(Channel[curDev],TRUE);
+   int nl=mixctl->readLeft(Channel[curDev]);
+   int nr=mixctl->readRight(Channel[curDev]);
+   bool nrec=mixctl->readRec(Channel[curDev],TRUE);
+   if(forced){
+      curLeft=nl;
+      curRight=nr;
+      curRec=nrec;
+      if(nrec)
+         btnstate|=btnRec;
+      else
+         btnstate&=~btnRec;      
+      curShowRec=mixctl->getRecords(Channel[curDev]);
+      update();   // Update everything
+      repaint();
+   }
+   else{
+      if(nl!=curLeft || nr!=curRight || nrec!=curRec){
+         if(nl!=curLeft){
+            curLeft=nl;
+            drawLeft();
+         }
+         if(nr!=curRight){
+            curRight=nr;
+            drawRight();
+         }
+         if(nrec!=curRec){
+            curRec=nrec;
+            if(nrec)
+               btnstate|=btnRec;
+            else
+               btnstate&=~btnRec;
+            drawBtns(btnRec);
+         }
+         repaint();
+      }
+   }
+}
+
+void pressEvent(XButtonEvent *xev){
+   int x=xev->x;
+   int y=xev->y;
+   if(x>=5 && y>=33 && x<=16 && y<=43){
+      curDev--;
+      if(curDev<0)
+         curDev=Channels-1;
+      btnstate|=btnPrev;
+      btntimer=0;
+      drawBtns(btnPrev);
+      checkVol(TRUE);
+      return;
+   }
+   if(x>=17 && y>=33 && x<=28 && y<=43){
+      curDev++;
+      if(curDev>=Channels)
+         curDev=0;
+      btnstate|=btnNext;
+      btntimer=0;
+      drawBtns(btnNext);
+      checkVol(TRUE);
+      return;
+   }
+   if(x>=37 && x<=56 && y>=8 && y<=56){
+      int v=((60-y)*100)/(3*17);
+      dragging=TRUE;
+      if(x<=50)
+         mixctl->setLeft(Channel[curDev], v);
+      if(x>=45)
+         mixctl->setRight(Channel[curDev], v);
+      mixctl->writeVol(Channel[curDev]);
+      checkVol(FALSE);
+      return;
+   }
+   if(x>=5 && y>=47 && x<=28 && y<=57){
+      mixctl->setRec(Channel[curDev], !mixctl->readRec(Channel[curDev],FALSE));
+      mixctl->writeRec();
+      checkVol(FALSE);
+   }
+}
+
+void releaseEvent(XButtonEvent *xev){
+   dragging=FALSE;
+   btnstate&=~(btnPrev | btnNext);
+   drawBtns(btnPrev | btnNext);
+   repaint();
+}
+
+void motionEvent(XMotionEvent *xev){
+   int x=xev->x;
+   int y=xev->y;
+   if(x>=37 && x<=56 && y>=8 && dragging){
+      int v=((60-y)*100)/(3*17);
+      if(v<0)
+         v=0;
+      if(x<=50)
+         mixctl->setLeft(Channel[curDev], v);
+      if(x>=45)
+         mixctl->setRight(Channel[curDev], v);
+      mixctl->writeVol(Channel[curDev]);
+      checkVol(FALSE);
+   }
+}
+
+void repaint(){
+   XCopyArea(dpy, disp, Win[activeWin], WinGC, 0, 0, 64, 64, 0, 0);
+   XEvent xev;
+   while(XCheckTypedEvent(dpy, Expose, &xev));
+}
+
+void update(){
+   // Only needs to be called when the current device is changed
+
+   XCopyArea(dpy, symb, disp, WinGC, sympic[Channel[curDev]]*22,0,22,22, 6,5);
+   drawLeft();
+   drawRight();
+   drawBtns(btnRec);
+}
+
+void drawLeft(){
+   XSetForeground(dpy, WinGC, fcolor);
+   for(int i=0;i<17;i++){
+      if(i==(curLeft*17)/100)
+         XSetForeground(dpy, WinGC, bcolor);
+      XFillRectangle(dpy, disp, WinGC, 37, 54-3*i, 9, 2);
+   }
+}
+
+void drawRight(){
+   XSetForeground(dpy, WinGC, fcolor);
+   for(int i=0;i<17;i++){
+      if(i==(curRight*17)/100)
+         XSetForeground(dpy, WinGC, bcolor);
+      XFillRectangle(dpy, disp, WinGC, 48, 54-3*i, 9, 2);
+   }
+}
+
+void drawBtns(int btns){
+   if(btns & btnPrev)
+      drawBtn(5,33,12,11,(btnstate & btnPrev));
+   if(btns & btnNext)
+      drawBtn(17,33,12,11,(btnstate & btnNext));
+   if(btns & btnRec){
+      drawBtn(5,47,24,11,(btnstate & btnRec));
+      if(!curShowRec)
+         XCopyArea(dpy, nrec, disp, WinGC, 0,0,6,7,14,49);
+      else
+         XCopyArea(dpy, back, disp, WinGC, 14,49,6,7,14,49);
+   }
+}
+
+void drawBtn(int x, int y, int w, int h, bool down){
+   if(!down)
+      XCopyArea(dpy, back, disp, WinGC, x,y,w,h,x,y);
+   else{
+      XCopyArea(dpy, back, disp, WinGC, x,y,1,h-1,x+w-1,y+1);
+      XCopyArea(dpy, back, disp, WinGC, x+w-1,y+1,1,h-1,x,y);
+      XCopyArea(dpy, back, disp, WinGC, x,y,w-1,1,x+1,y+h-1);
+      XCopyArea(dpy, back, disp, WinGC, x+1,y+h-1,w-1,1,x,y);
+   }
+}

-- 
Alioth's /usr/local/bin/git-commit-notice on /srv/git.debian.org/git/pkg-wmaker/wmmixer.git



More information about the Pkg-wmaker-commits mailing list