[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