From ece413337e06fb9ad7001f6244beb8f839b46cd5 Mon Sep 17 00:00:00 2001 From: Christopher Lansdown Date: Thu, 3 Jun 1999 19:51:06 +0000 Subject: [PATCH] Added XAmixer2 to the alsa utilities tree. This should be all of the files necessary to work. Wish me luck. --- xamixer2/AUTHORS | 0 xamixer2/COPYING | 282 ++++++++++++++++++++ xamixer2/ChangeLog | 0 xamixer2/INSTALL | 182 +++++++++++++ xamixer2/Makefile.am | 4 + xamixer2/NEWS | 0 xamixer2/README | 0 xamixer2/TODO | 0 xamixer2/callbacks.c | 181 +++++++++++++ xamixer2/callbacks.h | 27 ++ xamixer2/cinit.c | 384 +++++++++++++++++++++++++++ xamixer2/cinit.h | 25 ++ xamixer2/config.c | 483 ++++++++++++++++++++++++++++++++++ xamixer2/config.h | 24 ++ xamixer2/configure.in | 11 + xamixer2/display.c | 590 ++++++++++++++++++++++++++++++++++++++++++ xamixer2/display.h | 33 +++ xamixer2/main.c | 0 xamixer2/main.h | 95 +++++++ xamixer2/options.c | 0 xamixer2/options.h | 0 xamixer2/structs.h | 158 +++++++++++ xamixer2/switches.c | 0 xamixer2/switches.h | 0 xamixer2/test.c | 31 +++ xamixer2/test1.c | 11 + xamixer2/util.c | 173 +++++++++++++ xamixer2/util.h | 38 +++ xamixer2/xamixer.conf | 47 ++++ xamixer2/xamixer.home | 47 ++++ xamixer2/xamixer2.c | 188 ++++++++++++++ xamixer2/xamixer2.h | 24 ++ 32 files changed, 3038 insertions(+) create mode 100644 xamixer2/AUTHORS create mode 100644 xamixer2/COPYING create mode 100644 xamixer2/ChangeLog create mode 100644 xamixer2/INSTALL create mode 100644 xamixer2/Makefile.am create mode 100644 xamixer2/NEWS create mode 100644 xamixer2/README create mode 100644 xamixer2/TODO create mode 100644 xamixer2/callbacks.c create mode 100644 xamixer2/callbacks.h create mode 100644 xamixer2/cinit.c create mode 100644 xamixer2/cinit.h create mode 100644 xamixer2/config.c create mode 100644 xamixer2/config.h create mode 100644 xamixer2/configure.in create mode 100644 xamixer2/display.c create mode 100644 xamixer2/display.h create mode 100644 xamixer2/main.c create mode 100644 xamixer2/main.h create mode 100644 xamixer2/options.c create mode 100644 xamixer2/options.h create mode 100644 xamixer2/structs.h create mode 100644 xamixer2/switches.c create mode 100644 xamixer2/switches.h create mode 100644 xamixer2/test.c create mode 100644 xamixer2/test1.c create mode 100644 xamixer2/util.c create mode 100644 xamixer2/util.h create mode 100644 xamixer2/xamixer.conf create mode 100644 xamixer2/xamixer.home create mode 100644 xamixer2/xamixer2.c create mode 100644 xamixer2/xamixer2.h diff --git a/xamixer2/AUTHORS b/xamixer2/AUTHORS new file mode 100644 index 0000000..e69de29 diff --git a/xamixer2/COPYING b/xamixer2/COPYING new file mode 100644 index 0000000..9392a19 --- /dev/null +++ b/xamixer2/COPYING @@ -0,0 +1,282 @@ +GNU GENERAL PUBLIC LICENSE + +Version 2, June 1991 + +Copyright (C) 1989, 1991 Free Software Foundation, Inc. +59 Temple Place - Suite 330, Boston, MA 02111-1307, 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. + +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 \ No newline at end of file diff --git a/xamixer2/ChangeLog b/xamixer2/ChangeLog new file mode 100644 index 0000000..e69de29 diff --git a/xamixer2/INSTALL b/xamixer2/INSTALL new file mode 100644 index 0000000..b42a17a --- /dev/null +++ b/xamixer2/INSTALL @@ -0,0 +1,182 @@ +Basic Installation +================== + + These are generic installation instructions. + + The `configure' shell script attempts to guess correct values for +various system-dependent variables used during compilation. It uses +those values to create a `Makefile' in each directory of the package. +It may also create one or more `.h' files containing system-dependent +definitions. Finally, it creates a shell script `config.status' that +you can run in the future to recreate the current configuration, a file +`config.cache' that saves the results of its tests to speed up +reconfiguring, and a file `config.log' containing compiler output +(useful mainly for debugging `configure'). + + If you need to do unusual things to compile the package, please try +to figure out how `configure' could check whether to do them, and mail +diffs or instructions to the address given in the `README' so they can +be considered for the next release. If at some point `config.cache' +contains results you don't want to keep, you may remove or edit it. + + The file `configure.in' is used to create `configure' by a program +called `autoconf'. You only need `configure.in' if you want to change +it or regenerate `configure' using a newer version of `autoconf'. + +The simplest way to compile this package is: + + 1. `cd' to the directory containing the package's source code and type + `./configure' to configure the package for your system. If you're + using `csh' on an old version of System V, you might need to type + `sh ./configure' instead to prevent `csh' from trying to execute + `configure' itself. + + Running `configure' takes awhile. While running, it prints some + messages telling which features it is checking for. + + 2. Type `make' to compile the package. + + 3. Optionally, type `make check' to run any self-tests that come with + the package. + + 4. Type `make install' to install the programs and any data files and + documentation. + + 5. You can remove the program binaries and object files from the + source code directory by typing `make clean'. To also remove the + files that `configure' created (so you can compile the package for + a different kind of computer), type `make distclean'. There is + also a `make maintainer-clean' target, but that is intended mainly + for the package's developers. If you use it, you may have to get + all sorts of other programs in order to regenerate files that came + with the distribution. + +Compilers and Options +===================== + + Some systems require unusual options for compilation or linking that +the `configure' script does not know about. You can give `configure' +initial values for variables by setting them in the environment. Using +a Bourne-compatible shell, you can do that on the command line like +this: + CC=c89 CFLAGS=-O2 LIBS=-lposix ./configure + +Or on systems that have the `env' program, you can do it like this: + env CPPFLAGS=-I/usr/local/include LDFLAGS=-s ./configure + +Compiling For Multiple Architectures +==================================== + + You can compile the package for more than one kind of computer at the +same time, by placing the object files for each architecture in their +own directory. To do this, you must use a version of `make' that +supports the `VPATH' variable, such as GNU `make'. `cd' to the +directory where you want the object files and executables to go and run +the `configure' script. `configure' automatically checks for the +source code in the directory that `configure' is in and in `..'. + + If you have to use a `make' that does not supports the `VPATH' +variable, you have to compile the package for one architecture at a time +in the source code directory. After you have installed the package for +one architecture, use `make distclean' before reconfiguring for another +architecture. + +Installation Names +================== + + By default, `make install' will install the package's files in +`/usr/local/bin', `/usr/local/man', etc. You can specify an +installation prefix other than `/usr/local' by giving `configure' the +option `--prefix=PATH'. + + You can specify separate installation prefixes for +architecture-specific files and architecture-independent files. If you +give `configure' the option `--exec-prefix=PATH', the package will use +PATH as the prefix for installing programs and libraries. +Documentation and other data files will still use the regular prefix. + + In addition, if you use an unusual directory layout you can give +options like `--bindir=PATH' to specify different values for particular +kinds of files. Run `configure --help' for a list of the directories +you can set and what kinds of files go in them. + + If the package supports it, you can cause programs to be installed +with an extra prefix or suffix on their names by giving `configure' the +option `--program-prefix=PREFIX' or `--program-suffix=SUFFIX'. + +Optional Features +================= + + Some packages pay attention to `--enable-FEATURE' options to +`configure', where FEATURE indicates an optional part of the package. +They may also pay attention to `--with-PACKAGE' options, where PACKAGE +is something like `gnu-as' or `x' (for the X Window System). The +`README' should mention any `--enable-' and `--with-' options that the +package recognizes. + + For packages that use the X Window System, `configure' can usually +find the X include and library files automatically, but if it doesn't, +you can use the `configure' options `--x-includes=DIR' and +`--x-libraries=DIR' to specify their locations. + +Specifying the System Type +========================== + + There may be some features `configure' can not figure out +automatically, but needs to determine by the type of host the package +will run on. Usually `configure' can figure that out, but if it prints +a message saying it can not guess the host type, give it the +`--host=TYPE' option. TYPE can either be a short name for the system +type, such as `sun4', or a canonical name with three fields: + CPU-COMPANY-SYSTEM + +See the file `config.sub' for the possible values of each field. If +`config.sub' isn't included in this package, then this package doesn't +need to know the host type. + + If you are building compiler tools for cross-compiling, you can also +use the `--target=TYPE' option to select the type of system they will +produce code for and the `--build=TYPE' option to select the type of +system on which you are compiling the package. + +Sharing Defaults +================ + + If you want to set default values for `configure' scripts to share, +you can create a site shell script called `config.site' that gives +default values for variables like `CC', `cache_file', and `prefix'. +`configure' looks for `PREFIX/share/config.site' if it exists, then +`PREFIX/etc/config.site' if it exists. Or, you can set the +`CONFIG_SITE' environment variable to the location of the site script. +A warning: not all `configure' scripts look for a site script. + +Operation Controls +================== + + `configure' recognizes the following options to control how it +operates. + +`--cache-file=FILE' + Use and save the results of the tests in FILE instead of + `./config.cache'. Set FILE to `/dev/null' to disable caching, for + debugging `configure'. + +`--help' + Print a summary of the options to `configure', and exit. + +`--quiet' +`--silent' +`-q' + Do not print messages saying which checks are being made. To + suppress all normal output, redirect it to `/dev/null' (any error + messages will still be shown). + +`--srcdir=DIR' + Look for the package's source code in directory DIR. Usually + `configure' can determine that directory automatically. + +`--version' + Print the version of Autoconf used to generate the `configure' + script, and exit. + +`configure' also accepts some other, not widely useful, options. diff --git a/xamixer2/Makefile.am b/xamixer2/Makefile.am new file mode 100644 index 0000000..8509c7d --- /dev/null +++ b/xamixer2/Makefile.am @@ -0,0 +1,4 @@ +bin_PROGRAMS = xamixer2 +xamixer2_SOURCES = main.h structs.h xamixer2.c xamixer2.h callbacks.c callbacks.h cinit.c cinit.h display.c display.h util.c util.h config.c config.h switches.c switches.h options.c options.h +sysconf_DATA = xamixer.conf +EXTRA_DIST = README COPYING INSTALL AUTHORS NEWS TODO xamixer.home xamixer.conf diff --git a/xamixer2/NEWS b/xamixer2/NEWS new file mode 100644 index 0000000..e69de29 diff --git a/xamixer2/README b/xamixer2/README new file mode 100644 index 0000000..e69de29 diff --git a/xamixer2/TODO b/xamixer2/TODO new file mode 100644 index 0000000..e69de29 diff --git a/xamixer2/callbacks.c b/xamixer2/callbacks.c new file mode 100644 index 0000000..55b17e8 --- /dev/null +++ b/xamixer2/callbacks.c @@ -0,0 +1,181 @@ +/***************************************************************************** + callbacks.c - an Alsa based gtk mixer + Written by Raistlinn (lansdoct@cs.alfred.edu) + Copyright (C) 1998 by Christopher Lansdown + + 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +******************************************************************************/ + +/*****************************************************************************/ +/* Begin #include's */ + +#include "main.h" + +/* End #include's */ +/*****************************************************************************/ + +/*****************************************************************************/ +/* Begin Global Variables */ + +extern GtkWidget *window; +extern Card *card; /* And array of the cards */ +extern int cards; /* The number of cards in the system. */ +extern Config config; /* The system config */ + +/* End Global Variables */ +/*****************************************************************************/ + + +void adjust_teffect1(GtkWidget *widget, CBData *data) +{ + int i, j, err; + Group *group; + + i = data->element; + j = data->index; + group = data->group; + + switch(j) { + case TYPE_SW: + if(GTK_TOGGLE_BUTTON(widget)->active) + group->element[i].data.teffect1.sw = 1; + else + group->element[i].data.teffect1.sw = 0; + break; + case TYPE_MONO_SW: + if(GTK_TOGGLE_BUTTON(widget)->active) + group->element[i].data.teffect1.mono_sw = 1; + else + group->element[i].data.teffect1.mono_sw = 0; + break; + case TYPE_WIDE: + group->element[i].data.teffect1.wide = + (int)GTK_ADJUSTMENT(widget)->value; + break; + case TYPE_VOLUME: + group->element[i].data.teffect1.volume = + (int)GTK_ADJUSTMENT(widget)->value; + break; + case TYPE_CENTER: + group->element[i].data.teffect1.center = + (int)GTK_ADJUSTMENT(widget)->value; + break; + case TYPE_SPACE: + group->element[i].data.teffect1.space = + (int)GTK_ADJUSTMENT(widget)->value; + break; + case TYPE_DEPTH: + group->element[i].data.teffect1.depth = + (int)GTK_ADJUSTMENT(widget)->value; + break; + case TYPE_DELAY: + group->element[i].data.teffect1.delay = + (int)GTK_ADJUSTMENT(widget)->value; + break; + case TYPE_FEEDBACK: + group->element[i].data.teffect1.feedback = + (int)GTK_ADJUSTMENT(widget)->value; + break; + default: + printf("Hit the default in adjust_teffect1 - this is bad.\n"); + break; + } + + /* Now let's write the new value to the card */ + if ((err = snd_mixer_element_write(data->handle, &group->element[i])) < 0) { + printf("3D Effect Mixer element write error: %s\n", snd_strerror(err)); + } + + return; +} +void adjust_switch1(GtkWidget *widget, CBData *data) +{ + int i, j, err; + + i = data->element; + j = data->index; + + if(GTK_TOGGLE_BUTTON(widget)->active) + data->group->element[i].data.switch1.psw[j / sizeof(unsigned int)] |= + (1 << (j % sizeof(unsigned int))); + else + data->group->element[i].data.switch1.psw[j / sizeof(unsigned int)] &= + ~(1 << (j % sizeof(unsigned int))); + + /* Now let's write the new value to the card */ + if ((err = snd_mixer_element_write(data->handle, &data->group->element[i])) < 0) { + printf("Mixer element write error: %s\n", snd_strerror(err)); + } + + return; +} + +void adjust_volume1(GtkWidget *widget, CBData *data) +{ + register int volume; + int i, j, err; + + i = data->element; + j = data->index; + + volume = (int)GTK_ADJUSTMENT(data->group->gtk[i].adjust[j])->value; + data->group->element[i].data.volume1.pvoices[j] = volume; + + /* Now let's write the new value to the card */ + if ((err = snd_mixer_element_write(data->handle, &data->group->element[i])) < 0) { + printf("Mixer element write error: %s\n", snd_strerror(err)); + } + + + return; +} + + +void adjust_switch2(GtkWidget *widget, CBData *data) +{ + int i, j, err; + + i = data->element; + j = data->index; + + if(GTK_TOGGLE_BUTTON(data->group->gtk[i].interface[j])->active) { + data->group->element[i].data.switch2.sw = 1; + } else { + data->group->element[i].data.switch2.sw = 0; + } + + /* Now let's write the new value to the card */ + if ((err = snd_mixer_element_write(data->handle, &data->group->element[i])) < 0) { + printf("Mixer element write error: %s\n", snd_strerror(err)); + } + + return; +} + + + + + + + + + + + + + + + + diff --git a/xamixer2/callbacks.h b/xamixer2/callbacks.h new file mode 100644 index 0000000..e96f73b --- /dev/null +++ b/xamixer2/callbacks.h @@ -0,0 +1,27 @@ +/*****************************************************************************/ +/* Begin #include statements */ + + + +/* End #include statements */ +/*****************************************************************************/ + + +/*****************************************************************************/ +/* Begin function prototypes */ + +void adjust_volume1(GtkWidget *widget, CBData *data); +void adjust_switch1(GtkWidget *widget, CBData *data); +void adjust_switch2(GtkWidget *widget, CBData *data); +void adjust_teffect1(GtkWidget *widget, CBData *data); + +/* End function prototypes */ +/*****************************************************************************/ + +/*****************************************************************************/ +/* Begin #define statements */ + + + +/* End #define statements */ +/*****************************************************************************/ diff --git a/xamixer2/cinit.c b/xamixer2/cinit.c new file mode 100644 index 0000000..3399917 --- /dev/null +++ b/xamixer2/cinit.c @@ -0,0 +1,384 @@ +/***************************************************************************** + cinit.c - routines to initialize the mixer devices + Written by Raistlinn (lansdoct@cs.alfred.edu) + Copyright (C) 1998 by Christopher Lansdown + + 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +******************************************************************************/ + + +/*****************************************************************************/ +/* Begin #include's */ + +#include "main.h" + +/* End #include's */ +/*****************************************************************************/ + +/*****************************************************************************/ +/* Begin Global Variables */ + +extern Card *card; /* And array of the cards */ +extern int cards; /* The number of cards in the system. */ +extern Config config; /* The system config */ + +/* End Global Variables */ +/*****************************************************************************/ + +/*****************************************************************************/ +/* Begin function prototypes */ + +int init_group(void *handle, Group *group); +int init_element_route(void *handle, snd_mixer_routes_t *routes, snd_mixer_eid_t *eid); +int misc_group_hack(Mixer *mixer, int index); + +/* End function prototypes */ +/*****************************************************************************/ + +int init_cards() +{ + int i,j,k; + int err; + void *handle; + + cards = snd_cards(); + card = calloc(cards, sizeof(Card)); + for(i = 0; i < cards; i++) { + /* Open the hardware */ + if((err = snd_ctl_open(&handle, i)) < 0) { + printf("Unable to open card #%i!\nError: %s\n", i, snd_strerror(err)); + card[i].mixer = NULL; + card[i].number = -1; + continue; + } else { + card[i].number = i; + } + + + /* Get the hardware info - the primary use of this is to find out how many + mixer devices the card has, but it's also useful to find out the human-readable + name of the card. */ + if((err = snd_ctl_hw_info(handle, &card[i].hw_info)) < 0) { + printf("Unable to get hardware information about card #%i!\nError: %s\n", + i, snd_strerror(err)); + printf("Trying to guess the appropriate values.\n"); + card[i].hw_info.mixerdevs = 1; + } + + + /* Allocate out the mixer array */ + card[i].mixer = calloc(card[i].hw_info.mixerdevs, sizeof(Mixer)); + + for(j = 0; j < card[i].hw_info.mixerdevs; j++) { + /* Open the mixer to begin with. Isn't it funny how there's all this + nice generalized code that can handle nearly any situation, and it + will be necessary in only a very small percentage of the situations. + Oh well, I guess that that's what distinguishes us from windows. :-) */ + if((err = snd_mixer_open(&card[i].mixer[j].handle, i, j)) < 0) { + printf("Unable to open mixer #%i on card #%i~\nError: %s\n", + j, i, snd_strerror(err)); + card[i].mixer[j].number = -1; + } else { + card[i].mixer[j].number = j; + } + + /* Get the mixer info */ + if((err = snd_mixer_info(card[i].mixer[j].handle, &card[i].mixer[j].info)) < 0) { + printf("Unable to get the info for mixer #%i on card %i! Error: %s\n", j, i, snd_strerror(err)); + printf("There's not much more I can do on this mixer."); + printf(" Shutting it down.\n"); + if((err = snd_mixer_close(card[i].mixer[j].handle)) < 0) { + printf("Oh well. I couldn't even close the mixer. I suspect that something is seriously wrong here. Good luck.\n"); + } + card[i].mixer[j].number = -1; + continue; + } + + bzero(&card[i].mixer[j].groups, sizeof(snd_mixer_groups_t)); + + if ((err = snd_mixer_groups(card[i].mixer[j].handle, + &card[i].mixer[j].groups)) < 0) { + printf("Mixer %i/%i groups error: %s", + i, j, snd_strerror(err)); + return -1; + } + + /* Allocate the space for the group array */ + card[i].mixer[j].groups.pgroups = (snd_mixer_gid_t *) + calloc(card[i].mixer[j].groups.groups_over, + sizeof(snd_mixer_gid_t)); + + if (!card[i].mixer[j].groups.pgroups) { + printf("No enough memory"); + return -1; + } + + card[i].mixer[j].groups.groups_size = card[i].mixer[j].info.groups; + card[i].mixer[j].groups.groups_over = card[i].mixer[j].groups.groups = 0; + if ((err = snd_mixer_groups(card[i].mixer[j].handle, + &card[i].mixer[j].groups)) < 0) { + printf("Mixer %i/%i groups (2) error: %s", + i, j, snd_strerror(err)); + return -1; + } + + /* Allocate the space for the array of the groups - this is more than + just their gid's, it's got group-specific info in it */ + card[i].mixer[j].group = calloc(card[i].mixer[j].info.groups + 1, + sizeof(Group)); + + /* get the group structures filled out */ + for(k = 0; k < card[i].mixer[j].info.groups; k++) { + card[i].mixer[j].group[k].group.gid = + card[i].mixer[j].groups.pgroups[k]; + + init_group(card[i].mixer[j].handle, + &card[i].mixer[j].group[k]); + + } + misc_group_hack(&card[i].mixer[j], k); + + } + + + if((err = snd_ctl_close(handle)) < 0) { + printf("strange, there was an error closing card #%i!\nError: %s\n", + i, snd_strerror(err)); + printf("Oh well.\n"); + } + } + + + /* return a successful execution. */ + return 0; +} + +int misc_group_hack(Mixer *mixer, int index) +{ + /* This code is largely copied straight from amixer. - God I love the GPL. */ + snd_mixer_elements_t elements; + snd_mixer_eid_t *element; + snd_mixer_group_t *group; + int err, idx, gdx, idx2; + int flag; + int count=0; /* The count of elements not in any group */ + snd_mixer_eid_t **array; + + bzero(&elements, sizeof(elements)); + if ((err = snd_mixer_elements(mixer->handle, &elements)) < 0) { + printf("Mixer elements error: %s", snd_strerror(err)); + return -1; + } + elements.pelements = (snd_mixer_eid_t *)malloc(elements.elements_over * + sizeof(snd_mixer_eid_t)); + if (!elements.pelements) { + printf("Not enough memory"); + return -1; + } + elements.elements_size = elements.elements_over; + elements.elements_over = elements.elements = 0; + if ((err = snd_mixer_elements(mixer->handle, &elements)) < 0) { + printf("Mixer elements (2) error: %s", snd_strerror(err)); + return -1; + } + + /* Allocate the temporary array to hold the mixer ID structs */ + array = malloc(elements.elements * sizeof(snd_mixer_eid_t *)); + if(!array) + printf("Not enough memory.\n"); + + + for (idx = 0; idx < elements.elements; idx++) { + element = &elements.pelements[idx]; + flag = 0; /* The flag will be set if the same element name & type + is encountered */ + for(gdx = 0; gdx < mixer->info.groups; gdx++) { + group = &mixer->group[gdx].group; + for(idx2 = 0; idx2 < group->elements; idx2++) { + if(group && element) + if(group->pelements[idx2].type == element->type && + is_same(group->pelements[idx2].name, element->name)) + flag = 1; + } + } + if(!flag) { + /* We found a mixer element that's not in a group */ + array[count] = element; + count++; + if(count > elements.elements) + printf("Houston, we have a problem.\n"); + } + } + + /* Set up the group member */ + strncpy(mixer->group[index].group.gid.name, "Miscellaneous\0", 24); + mixer->group[index].group.gid.index = 0; + mixer->group[index].group.elements_size = 0; /* I hope that this doesn't matter */ + mixer->group[index].group.elements = count; + mixer->group[index].group.elements_over = 0; /* I hope tha this doesn't matter */ + + + mixer->group[index].group.pelements = (snd_mixer_eid_t *)malloc(count * + sizeof(snd_mixer_eid_t)); + mixer->group[index].routes = calloc(mixer->group[index].group.elements, + sizeof(snd_mixer_routes_t)); + mixer->group[index].element = calloc(mixer->group[index].group.elements, + sizeof(snd_mixer_element_t)); + mixer->group[index].einfo = calloc(mixer->group[index].group.elements, + sizeof(snd_mixer_element_info_t)); + mixer->group[index].gtk = calloc(mixer->group[index].group.elements, + sizeof(Gtk_Channel)); + /* Copy the snd_mixer_eid_t structures into the new group structure and init the routes */ + + for(idx = 0; idx < count; idx++) { + mixer->group[index].group.pelements[idx] = *array[idx]; + + mixer->group[index].einfo[idx].eid = mixer->group[index].group.pelements[idx]; + if(snd_mixer_element_has_info(&mixer->group[index].group.pelements[idx]) == 1) + if((err = + snd_mixer_element_info_build(mixer->handle, + &mixer->group[index].einfo[idx])) < 0) { + printf("Unable to get element information for element %s! ", + mixer->group[index].group.pelements[idx].name); + printf("Error: %s.\n", snd_strerror(err)); + } + + mixer->group[index].element[idx].eid = mixer->group[index].group.pelements[idx]; + if((err = snd_mixer_element_build(mixer->handle, + &mixer->group[index].element[idx])) < 0) { + printf("Unable to read element %s! ", + mixer->group[index].group.pelements[idx].name); + printf("Error: %s.\n", snd_strerror(err)); + } + + init_element_route(mixer->handle, + &mixer->group[index].routes[idx], + &mixer->group[index].group.pelements[idx]); + } + + + + + + /* Increase the number of groups to include the new group */ + mixer->info.groups++; + + if(elements.pelements) + free(elements.pelements); + if(array) + free(array); + + return 1; +} + + +int init_group(void *handle, Group *group) +{ + /* This is largely a mess copied from amixer that gets the group info in a very strange + way, I wish that I knew how it really worked. Anyhow, once we get the group into + and the info about the elements in the group, we'll set up the element array. */ + int idx, err; + + if((err = snd_mixer_group(handle, + &group->group)) < 0) { + printf("Unable to get info for group %s! ", group->group.gid.name); + printf("Error: %s\n", snd_strerror(err)); + printf("elements_size = %i, elements_over=%i, elements=%i\n", + group->group.elements_size, + group->group.elements_over, + group->group.elements); + return 0; + } + group->group.pelements = (snd_mixer_eid_t *)calloc(group->group.elements_over, + sizeof(snd_mixer_eid_t)); + if (!group->group.pelements) { + printf("Not enough memory..."); + return 0; + } + group->group.elements_size = group->group.elements_over; + group->group.elements = group->group.elements_over = 0; + if ((err = snd_mixer_group(handle, &group->group)) < 0) { + printf("Unable to get second group info for group %s. Error: %s\n", + group->group.gid.name, snd_strerror(err)); + printf("elements_size = %i, elements_over=%i, elements=%i\n", + group->group.elements_size, + group->group.elements_over, + group->group.elements); + return 0; + } + + + /* Allocate out the arrays for the elements and element info */ + group->element = calloc(group->group.elements, sizeof(snd_mixer_element_t)); + group->einfo = calloc(group->group.elements, sizeof(snd_mixer_element_info_t)); + group->routes = calloc(group->group.elements, sizeof(snd_mixer_routes_t)); + group->gtk = calloc(group->group.elements, sizeof(Gtk_Channel)); + + /* Now go through and get that info */ + for (idx = 0; idx < group->group.elements; idx++) { + group->einfo[idx].eid = group->group.pelements[idx]; + if(snd_mixer_element_has_info(&group->group.pelements[idx]) == 1) + if((err = snd_mixer_element_info_build(handle, &group->einfo[idx])) < 0) { + printf("Unable to get element information for element %s! ", + group->group.pelements[idx].name); + printf("Error: %s.\n", snd_strerror(err)); + } + + group->element[idx].eid = group->group.pelements[idx]; + if((err = snd_mixer_element_build(handle, &group->element[idx])) < 0) { + printf("Unable to read element %s! ", + group->group.pelements[idx].name); + printf("Error: %s.\n", snd_strerror(err)); + } + + init_element_route(handle, &group->routes[idx], &group->group.pelements[idx]); + + } + + + return 1; +} + + +int init_element_route(void *handle, snd_mixer_routes_t *routes, snd_mixer_eid_t *eid) +{ + int err, idx; + /* Most of this code is taken straight from amixer as well. */ + /* This just gets the routes for the mixer element and stores them. */ + + bzero(routes, sizeof(snd_mixer_routes_t)); + routes->eid = *eid; + if ((err = snd_mixer_routes(handle, routes)) < 0) { + printf("Element %s route error: %s", eid->name, snd_strerror(err)); + return -1; + } + if (!routes->routes_over) + return 0; + routes->proutes = (snd_mixer_eid_t *)malloc(routes->routes_over * + sizeof(snd_mixer_eid_t)); + if (!routes->proutes) { + printf("No enough memory..."); + return -1; + } + routes->routes_size = routes->routes_over; + routes->routes = routes->routes_over = 0; + if ((err = snd_mixer_routes(handle, routes)) < 0) { + printf("Element (2) %s route error: %s", eid->name, snd_strerror(err)); + return -1; + } + + return 1; +} + diff --git a/xamixer2/cinit.h b/xamixer2/cinit.h new file mode 100644 index 0000000..17f5fa9 --- /dev/null +++ b/xamixer2/cinit.h @@ -0,0 +1,25 @@ +/*****************************************************************************/ +/* Begin #include statements */ + +/* End #include statements */ +/*****************************************************************************/ + +/*****************************************************************************/ +/* Begin function prototypes */ + +int init_cards(); + +/* End function prototypes */ +/*****************************************************************************/ + + + +/*****************************************************************************/ +/* Begin #define statements */ + + +/* End #define statements */ +/*****************************************************************************/ + + + diff --git a/xamixer2/config.c b/xamixer2/config.c new file mode 100644 index 0000000..30b5412 --- /dev/null +++ b/xamixer2/config.c @@ -0,0 +1,483 @@ +/***************************************************************************** + config.c - parses the config file + Written by Raistlinn (lansdoct@cs.alfred.edu) + Copyright (C) 1998 by Christopher Lansdown + + 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +******************************************************************************/ + +/*****************************************************************************/ +/* Begin #include's */ + +#include "main.h" + +/* End #include's */ +/*****************************************************************************/ + +/*****************************************************************************/ +/* Begin #define's */ + +#define CHANNEL_SIZE 64 +#define LABEL_SIZE 1024 + +/* End #define's */ +/*****************************************************************************/ + +/*****************************************************************************/ +/* Begin Global Variables */ + +extern Card *card; /* And array of the cards */ +extern int cards; /* The number of cards in the system. */ +Config config; /* The global config */ + +/* End Global Variables */ +/*****************************************************************************/ + +int config_init() +{ + /* Initialize the values to some reasonable defaults */ + config.flags &= 0; + config.labels = NULL; + config.xpm = NULL; + config.icon = NULL; + config.mute = "M"; + config.unmute = NULL; + config.simul = "|-|"; + config.unsimul = NULL; + config.rec = "Rec"; + config.unrec = NULL; + config.scale = 100; + config.x_pos = -1; + config.y_pos = -1; + config.padding = 5; + config.cdisplay = NULL; + + return 1; +} + +int config_read(const char *file) +{ + char *home_dir, *home_env; + FILE *stream; + char line[1025], *chr; + int state = 0; /* 0 = general config; 1 = history */ + unsigned int i = 0; + int linelen = 0; + char channel[CHANNEL_SIZE]; /* The name of the channel */ + char label[LABEL_SIZE]; /* The label or xpm name */ + int linenum = 0; + + stream = fopen(file, "r"); + + /* If there is no initialized value */ + if(stream == NULL) + return TRUE; + + while(fgets(line, 1024, stream)){ + linenum++; + /* Get wrid of comments */ + if(is_comment(line)) + continue; + strip_comment(line); + + /* Convert the line to upper case so that matches aren't case + sensitive (if not in history)*/ + linelen = strlen(line); + + if(strstr(line, "Position")) { + if(sscanf(line, "Position %i %i", &config.x_pos, &config.y_pos) < 2) + config.x_pos = config.y_pos = -1; + } + else if(strstr(line, "ShowCardName")) + config.flags |= CONFIG_SHOW_CARD_NAME; + else if(strstr(line, "ShowMixerNumber")) + config.flags |= CONFIG_SHOW_MIXER_NUMBER; + else if(strstr(line, "ShowMixerName")) + config.flags |= CONFIG_SHOW_MIXER_NAME; + else if(strstr(line, "IconXpm")) + if(sscanf(line, "IconXpm %s", label) < 1) + printf("Bad IconXpm entry at line %i.\n", linenum); + else { + config.icon = calloc(strlen(label) + 1, sizeof(char)); + strcpy(config.icon, label); + config.flags |= CONFIG_ICON_XPM; + } + else if(strstr(line, "IgnoreXpms")) + config.flags &= ~CONFIG_USE_XPMS; + else if(strstr(line, "UseXpms")) + config.flags |= CONFIG_USE_XPMS; + else if(strstr(line, "unMuteXpmLeft")) + if(sscanf(line, "unMuteXpmLeft %s", label) < 1) + printf("Bad unMuteXpmLeft entry at line %i.\n", linenum); + else { + config.unmute_l = calloc(strlen(label) + 1, sizeof(char)); + strcpy(config.unmute_l, label); + config.flags |= CONFIG_UNMUTE_XPM_L; + } + else if(strstr(line, "unMuteXpm")) + if(sscanf(line, "unMuteXpm %s", label) < 1) + printf("Bad unMuteXpm entry at line %i.\n", linenum); + else { + config.unmute = calloc(strlen(label) + 1, sizeof(char)); + strcpy(config.unmute, label); + config.flags |= CONFIG_UNMUTE_XPM; + } + else if(strstr(line, "unRecXpm")) + if(sscanf(line, "unRecXpm %s", label) < 1) + printf("Bad unRecXpm entry at line %i.\n", linenum); + else { + config.unrec = calloc(strlen(label) + 1, sizeof(char)); + strcpy(config.unrec, label); + config.flags |= CONFIG_UNREC_XPM; + } + else if(strstr(line, "unSimulXpm")) + if(sscanf(line, "unSimulXpm %s", label) < 1) + printf("Bad unSimulXpm entry at line %i.\n", linenum); + else { + config.unsimul = calloc(strlen(label) + 1, sizeof(char)); + strcpy(config.unsimul, label); + config.flags |= CONFIG_UNSIMUL_XPM; + } + else if(strstr(line, "MuteLabel")) + if(sscanf(line, "MuteLabel %s", label) < 1) + printf("Bad MuteLabel entry at line %i.\n", linenum); + else { + config.mute = calloc(strlen(label) + 1, sizeof(char)); + strcpy(config.mute, label); + config.flags &= ~CONFIG_MUTE_XPM; + } + else if(strstr(line, "SimulLabel")) + if(sscanf(line, "SimulLabel %s", label) < 1) + printf("Bad SimulLabel entry at line %i.\n", linenum); + else { + config.simul = calloc(strlen(label) + 1, sizeof(char)); + strcpy(config.simul, label); + config.flags &= ~CONFIG_SIMUL_XPM; + } + else if(strstr(line, "RecLabel")) + if(sscanf(line, "RecLabel %s", label) < 1) + printf("Bad RecLabel entry at line %i.\n", linenum); + else { + config.rec = calloc(strlen(label) + 1, sizeof(char)); + strcpy(config.rec, label); + config.flags &= ~CONFIG_REC_XPM; + } + else if(strstr(line, "MuteXpmLeft")) + if(sscanf(line, "MuteXpmLeft %s", label) < 1) + printf("Bad MuteXpmLeft entry at line %i.\n", linenum); + else { + config.mute_l = calloc(strlen(label) + 1, sizeof(char)); + strcpy(config.mute_l, label); + config.flags |= CONFIG_MUTE_XPM_L; + } + else if(strstr(line, "MuteXpm")) + if(sscanf(line, "MuteXpm %s", label) < 1) + printf("Bad MuteXpm entry at line %i.\n", linenum); + else { + config.mute = calloc(strlen(label) + 1, sizeof(char)); + strcpy(config.mute, label); + config.flags |= CONFIG_MUTE_XPM; + } + else if(strstr(line, "RecXpm")) + if(sscanf(line, "RecXpm %s", label) < 1) + printf("Bad RecXpm entry at line %i.\n", linenum); + else { + config.rec = calloc(strlen(label) + 1, sizeof(char)); + strcpy(config.rec, label); + config.flags |= CONFIG_REC_XPM; + } + else if(strstr(line, "SimulXpm")) + if(sscanf(line, "SimulXpm %s", label) < 1) + printf("Bad SimulXpm entry at line %i.\n", linenum); + else { + config.simul = calloc(strlen(label) + 1, sizeof(char)); + strcpy(config.simul, label); + config.flags |= CONFIG_SIMUL_XPM; + } + else if(strstr(line, "BackgroundXpm")) + if(sscanf(line, "BackgroundXpm %s", label) < 1) + printf("Bad BackgroundXpm entry at line %i.\n", linenum); + else { + config.background = calloc(strlen(label) + 1, sizeof(char)); + strcpy(config.background, label); + config.flags |= CONFIG_BACKGROUND_XPM; + } + else if(strstr(line, "Label")){ + if(get_label(line, "Label", channel, CHANNEL_SIZE, + label, LABEL_SIZE, '[', ']')){ + config.labels = channel_label_append(config.labels, channel, label); + } + else + printf("Bad Label entry found on line %i.\n", linenum); + } + else if(strstr(line, "Xpm")){ + if(get_label(line, "Xpm", channel, CHANNEL_SIZE, + label, LABEL_SIZE, '[', ']')){ + config.xpm = channel_label_append(config.xpm, channel, label); + } + else + printf("Bad Xpm entry found on line %i.\n", linenum); + } + else if(strstr(line, "ScaleSize")) + if(sscanf(line, "ScaleSize %i", &i) == 1) + config.scale = i; + else + printf("Bad ScaleSize entry at line %i.\n", linenum); + if(strstr(line, "ChannelPadding")) + if(sscanf(line, "ChannelPadding %i", &i) == 1) + config.padding = i; + else + printf("Bad ChannelPadding entry at line %i.\n", linenum); + + + } /* End of config loop */ + + /* Close the file */ + fclose(stream); + + return TRUE; +} + + +int setup_pixmaps(GtkWidget *xpmparent) +{ + GtkStyle *style; + int fd; + + if(!(config.flags & CONFIG_USE_XPMS)) { + config.mute = "M"; + config.simul = "|-|"; + config.rec = "Rec"; + return; + } + + + + if(config.flags & CONFIG_ICON_XPM){ + fd = open(config.icon, O_RDONLY); + if(fd != -1) { + close(fd); + style = gtk_widget_get_style(xpmparent); + config.icon_xpm = + gdk_pixmap_create_from_xpm(xpmparent->window, + &config.icon_mask, + &style->bg[GTK_STATE_NORMAL], + config.icon); + } + else { + printf("Unable to open pixmap %s.\n", config.icon); + config.flags &= ~CONFIG_ICON_XPM; + config.icon_xpm = NULL; + free(config.icon); + config.icon = NULL; + } + } + + + if(config.flags & CONFIG_MUTE_XPM_L){ + fd=open(config.mute_l, O_RDONLY); + if(fd != -1) { + close(fd); + style = gtk_widget_get_style(xpmparent); + config.mute_xpm_l = + gdk_pixmap_create_from_xpm(xpmparent->window, + &config.mute_mask_l, + &style->bg[GTK_STATE_NORMAL], + config.mute_l); + } + else { + printf("Unable to open pixmap %s.\n", config.mute_l); + config.flags &= ~CONFIG_MUTE_XPM_L; + config.mute_xpm_l = NULL; + free(config.mute_l); + config.mute_l = NULL; + } + } + + + if(config.flags & CONFIG_MUTE_XPM){ + fd=open(config.mute, O_RDONLY); + if(fd != -1) { + close(fd); + style = gtk_widget_get_style(xpmparent); + config.mute_xpm = + gdk_pixmap_create_from_xpm(xpmparent->window, + &config.mute_mask, + &style->bg[GTK_STATE_NORMAL], + config.mute); + if(!(config.flags & CONFIG_MUTE_XPM_L)) { + config.mute_xpm_l = config.mute_xpm; + config.mute_mask_l = config.mute_mask; + config.flags |= CONFIG_MUTE_XPM_L; + } + } + else { + printf("Unable to open pixmap %s.\n", config.mute); + config.flags &= ~CONFIG_MUTE_XPM; + config.mute_xpm = NULL; + free(config.mute); + config.mute = "M"; + } + } + + + + if(config.flags & CONFIG_UNMUTE_XPM_L) { + fd=open(config.unmute_l, O_RDONLY); + if(fd != -1) { + close(fd); + style = gtk_widget_get_style(xpmparent); + config.unmute_xpm_l = + gdk_pixmap_create_from_xpm(xpmparent->window, + &config.unmute_mask_l, + &style->bg[GTK_STATE_NORMAL], + config.unmute_l); + } + else { + printf("Unable to open pixmap %s.\n", config.unmute_l); + config.flags &= ~CONFIG_UNMUTE_XPM_L; + free(config.unmute_l); + config.unmute_l=NULL; + } + } + + + + if(config.flags & CONFIG_UNMUTE_XPM) { + fd=open(config.unmute, O_RDONLY); + if(fd != -1) { + close(fd); + style = gtk_widget_get_style(xpmparent); + config.unmute_xpm = + gdk_pixmap_create_from_xpm(xpmparent->window, + &config.unmute_mask, + &style->bg[GTK_STATE_NORMAL], + config.unmute); + if(!(config.flags & CONFIG_UNMUTE_XPM_L)) { + printf("Invoked!\n"); + config.unmute_xpm_l = config.unmute_xpm; + config.unmute_mask_l = config.unmute_mask; + config.flags |= CONFIG_UNMUTE_XPM_L; + } + } + else { + printf("Unable to open pixmap %s.\n", config.unmute); + config.flags &= ~CONFIG_UNMUTE_XPM; + free(config.unmute); + config.unmute=NULL; + } + } + + + + if(config.flags & CONFIG_REC_XPM) { + fd=open(config.rec, O_RDONLY); + if(fd != -1) { + close(fd); + style = gtk_widget_get_style(xpmparent); + config.rec_xpm = + gdk_pixmap_create_from_xpm(xpmparent->window, + &config.rec_mask, + &style->bg[GTK_STATE_NORMAL], + config.rec); + } + else { + printf("Unable to open pixmap %s.\n", config.rec); + config.flags &= ~CONFIG_REC_XPM; + free(config.rec); + config.rec = "Rec"; + } + } + + if(config.flags & CONFIG_UNREC_XPM) { + fd=open(config.unrec, O_RDONLY); + if(fd != -1) { + close(fd); + style = gtk_widget_get_style(xpmparent); + config.unrec_xpm = + gdk_pixmap_create_from_xpm(xpmparent->window, + &config.unrec_mask, + &style->bg[GTK_STATE_NORMAL], + config.unrec); + } + else { + printf("Unable to open pixmap %s.\n", config.unrec); + config.flags &= ~CONFIG_UNREC_XPM; + free(config.unrec); + config.unrec=NULL; + } + } + + if(config.flags & CONFIG_SIMUL_XPM) { + fd = open(config.simul, O_RDONLY); + if(fd != -1) { + close(fd); + style = gtk_widget_get_style(xpmparent); + config.simul_xpm = + gdk_pixmap_create_from_xpm(xpmparent->window, + &config.simul_mask, + &style->bg[GTK_STATE_NORMAL], + config.simul); + } + else { + printf("Unable to open pixmap %s.\n", config.simul); + config.flags &= ~CONFIG_SIMUL_XPM; + free(config.simul); + config.simul="|-|"; + } + } + + if(config.flags & CONFIG_UNSIMUL_XPM) { + fd = open(config.unsimul, O_RDONLY); + if(fd != -1) { + close(fd); + style = gtk_widget_get_style(xpmparent); + config.unsimul_xpm = + gdk_pixmap_create_from_xpm(xpmparent->window, + &config.unsimul_mask, + &style->bg[GTK_STATE_NORMAL], + config.unsimul); + } + else { + printf("Unable to open pixmap %s.\n", config.unsimul); + config.flags &= ~CONFIG_UNSIMUL_XPM; + free(config.unsimul); + config.unsimul=NULL; + } + } + + if(config.flags & CONFIG_BACKGROUND_XPM) { + fd = open(config.background, O_RDONLY); + if(fd != -1) { + close(fd); + style = gtk_widget_get_style(xpmparent); + config.background_xpm = + gdk_pixmap_create_from_xpm(xpmparent->window, + &config.background_mask, + &style->bg[GTK_STATE_NORMAL], + config.background); + } + else { + printf("Unable to open pixmap %s.\n", config.background); + config.flags &= ~CONFIG_BACKGROUND_XPM; + free(config.background); + config.background=NULL; + } + } + + return TRUE; +} + + diff --git a/xamixer2/config.h b/xamixer2/config.h new file mode 100644 index 0000000..5ded34f --- /dev/null +++ b/xamixer2/config.h @@ -0,0 +1,24 @@ +/*****************************************************************************/ +/* Begin #include statements */ + +/* End #include statements */ +/*****************************************************************************/ + + +/*****************************************************************************/ +/* Begin function prototypes */ + +int config_init(); +int config_read(const char *file); +int setup_pixmaps(GtkWidget *xpmparent); + +/* End function prototypes */ +/*****************************************************************************/ + +/*****************************************************************************/ +/* Begin #define statements */ + +#define HOME_FILE ".xamixer" + +/* End #define statements */ +/*****************************************************************************/ diff --git a/xamixer2/configure.in b/xamixer2/configure.in new file mode 100644 index 0000000..ecc7766 --- /dev/null +++ b/xamixer2/configure.in @@ -0,0 +1,11 @@ +AC_INIT(xamixer2.c) +AM_INIT_AUTOMAKE(xamixer2,0.1.3) +AC_PROG_CC +AC_PROG_INSTALL +AC_HEADER_STDC +AM_PATH_GTK(1.0.1) +AM_PATH_ALSA(0.1.3) +CFLAGS="$CFLAGS $GTK_CFLAGS $ALSA_FLAGS" +LDFLAGS="$LDFLAGS $GTK_LIBS $ALSA_LIBS" + +AC_OUTPUT(Makefile) diff --git a/xamixer2/display.c b/xamixer2/display.c new file mode 100644 index 0000000..a9940ae --- /dev/null +++ b/xamixer2/display.c @@ -0,0 +1,590 @@ +/***************************************************************************** + xamixer.c - an Alsa based gtk mixer + Written by Raistlinn (lansdoct@cs.alfred.edu) + Copyright (C) 1998 by Christopher Lansdown + + 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +******************************************************************************/ + +/*****************************************************************************/ +/* Begin #include's */ + +#include "main.h" + +/* End #include's */ +/*****************************************************************************/ + +/*****************************************************************************/ +/* Begin Global Variables */ + +extern GtkWidget *window; +extern Card *card; /* And array of the cards */ +extern int cards; /* The number of cards in the system. */ +extern Config config; /* The system config */ + +/* End Global Variables */ +/*****************************************************************************/ + +/*****************************************************************************/ +/* Begin function prototypes */ + +GtkWidget *group_elements(int card, int mixer, Group *group); +GtkWidget *display_volume1(Group *group, int element, void *handle, char *route); +GtkWidget *display_switch2(Group *group, int element, void *handle, char *route); +GtkWidget *display_switch1(Group *group, int element, void *handle, char *route); +GtkWidget *display_3deffect1(Group *group, int element, void *handle, char *route); + +/* End function protoypes */ +/*****************************************************************************/ + +GtkWidget *create_mixer_page(int card_num, int mixer_num) +{ + GtkWidget *vbox; + GtkWidget *hbox; + GtkWidget *frame; + int i=card_num, j=mixer_num, k=0, l, m; + int w=1, col; + + /* Compute the number of culumns to use */ + // w = (int)sqrt((double)card[i].mixer[j].info.elements); + w = (int)(1.5 * + (float)card[i].mixer[j].info.elements / + (float)card[i].mixer[j].info.groups); + + /* Compute the number of groups in a column */ + col = (card[i].mixer[j].info.groups + w - 1)/ w; + + /* Create the main bounding box */ + hbox = gtk_hbox_new(FALSE, 0); + gtk_widget_show(hbox); + + + /* Make a vertical box for each column, then put that column's worth + of mixer groups into the column */ + for(l = 0; l < w; l++) { + /* Make the vertical box to pack it in */ + vbox = gtk_vbox_new(FALSE, 0); + gtk_widget_show(vbox); + gtk_box_pack_start(GTK_BOX(hbox), vbox, FALSE, FALSE, 0); + + for(m = 0; m < col && k < card[i].mixer[j].info.groups; m++) { + /* Make the group frame */ + frame = gtk_frame_new(card[i].mixer[j].group[k].group.gid.name); + gtk_widget_show(frame); + gtk_box_pack_start(GTK_BOX(vbox), frame, FALSE, FALSE, 0); + + gtk_container_add(GTK_CONTAINER(frame), + group_elements(card_num, + mixer_num, + &card[i].mixer[j].group[k])); + + + /* Now increment the count of which mixer group we're on */ + k++; + } + } + + return hbox; +} + + +GtkWidget *group_elements(int card_num, int mixer, Group *group) +{ + GtkWidget *vbox; + GtkWidget *hbox; + GtkWidget *label; + GtkWidget *box; + GtkWidget *widget; + char thor[128]; + int i, j; + snd_mixer_element_t test; + + vbox = gtk_vbox_new(FALSE, 0); + gtk_widget_show(vbox); + + for(i = 0; i < group->group.elements; i++) { + /* Each element gets its own horizontal box */ + hbox=gtk_hbox_new(FALSE, 0); + gtk_widget_show(hbox); + gtk_box_pack_start(GTK_BOX(vbox), hbox, FALSE, FALSE, 0); + + snprintf(thor, 128, "%s routed to the %s", + group->group.pelements[i].name, + group->routes[i].proutes[0].name); + +/* label = gtk_label_new(thor); */ +/* gtk_widget_show(label); */ +/* gtk_box_pack_start(GTK_BOX(hbox), label, FALSE, FALSE, 0); */ + + + switch(group->group.pelements[i].type){ + + case SND_MIXER_ETYPE_VOLUME1: + gtk_box_pack_end(GTK_BOX(hbox), + display_volume1(group, i, + card[card_num].mixer[mixer].handle, + thor), + FALSE, FALSE, 0); + break; + + case SND_MIXER_ETYPE_SWITCH1: + gtk_box_pack_end(GTK_BOX(hbox), + display_switch1(group, i, + card[card_num].mixer[mixer].handle, + thor), + FALSE, FALSE, 0); + break; + + case SND_MIXER_ETYPE_SWITCH2: + gtk_box_pack_end(GTK_BOX(hbox), + display_switch2(group, i, + card[card_num].mixer[mixer].handle, + thor), + FALSE, FALSE, 0); + break; + + case SND_MIXER_ETYPE_3D_EFFECT1: + gtk_box_pack_end(GTK_BOX(hbox), + display_3deffect1(group, i, + card[card_num].mixer[mixer].handle, + thor), + FALSE, FALSE, 0); + break; + } + } + + + + return vbox; +} + +GtkWidget *display_3deffect1(Group *group, int element, void *handle, char *route) +{ + GtkWidget *vbox; + GtkWidget *box; + GtkTooltips *tooltips; + GtkWidget *widget; + GtkWidget *label; + int i=element; + GtkObject *adj; + + vbox = gtk_vbox_new(FALSE, 0); + gtk_widget_show(vbox); + + group->gtk[i].interface = calloc(10, sizeof(GtkWidget *)); + group->gtk[i].adjust = calloc(10, sizeof(GtkWidget *)); + + /* The on/off switch */ + if(group->einfo[i].data.teffect1.effect & SND_MIXER_EFF1_SW) { + box = gtk_hbox_new(FALSE, 0); + gtk_widget_show(box); + gtk_box_pack_start(GTK_BOX(vbox), box, FALSE, FALSE, 0); + + label = gtk_label_new("3D Effect"); + gtk_widget_show(label); + gtk_box_pack_start(GTK_BOX(box), label, FALSE, FALSE, 0); + + widget = gtk_check_button_new(); + if(group->element[i].data.teffect1.sw) + gtk_toggle_button_set_state(GTK_TOGGLE_BUTTON(widget), TRUE); + + gtk_widget_show(widget); + gtk_box_pack_end(GTK_BOX(box), widget, FALSE, FALSE, 0); + /* Connect it to the callback */ + gtk_signal_connect(GTK_OBJECT(widget), "toggled", + GTK_SIGNAL_FUNC(adjust_teffect1), + create_cb_data(group, handle, i, TYPE_SW)); + } + + + + /* The mono switch */ + if(group->einfo[i].data.teffect1.effect & SND_MIXER_EFF1_MONO_SW) { + box = gtk_hbox_new(FALSE, 0); + gtk_widget_show(box); + gtk_box_pack_start(GTK_BOX(vbox), box, FALSE, FALSE, 0); + + label = gtk_label_new("3D Effect Mono"); + gtk_widget_show(label); + gtk_box_pack_start(GTK_BOX(box), label, FALSE, FALSE, 0); + + widget = gtk_check_button_new(); + if(group->element[i].data.teffect1.sw) + gtk_toggle_button_set_state(GTK_TOGGLE_BUTTON(widget), TRUE); + gtk_widget_show(widget); + gtk_box_pack_end(GTK_BOX(box), widget, FALSE, FALSE, 0); + /* Connect it to the callback */ + gtk_signal_connect(GTK_OBJECT(widget), "toggled", + GTK_SIGNAL_FUNC(adjust_teffect1), + create_cb_data(group, handle, i, TYPE_MONO_SW)); + } + + + /* the wide control */ + if(group->einfo[i].data.teffect1.effect & SND_MIXER_EFF1_WIDE) { + box = gtk_hbox_new(FALSE, 0); + gtk_widget_show(box); + gtk_box_pack_start(GTK_BOX(vbox), box, FALSE, FALSE, 0); + + label = gtk_label_new("3D Effect Width"); + gtk_widget_show(label); + gtk_box_pack_start(GTK_BOX(box), label, FALSE, FALSE, 0); + + + adj = gtk_adjustment_new(group->element[i].data.teffect1.wide, + group->einfo[i].data.teffect1.min_wide, + group->einfo[i].data.teffect1.max_wide, + 1.0, + 3.0, + 0.0); + widget = gtk_hscale_new(GTK_ADJUSTMENT(adj)); + gtk_scale_set_value_pos(GTK_SCALE(widget), + GTK_POS_RIGHT); + gtk_widget_set_usize(widget, 100, -1); + gtk_widget_show(widget); + gtk_box_pack_end(GTK_BOX(box), widget, FALSE, FALSE, 0); + + /* connect the signal */ + gtk_signal_connect(GTK_OBJECT(adj), + "value_changed", + GTK_SIGNAL_FUNC (adjust_teffect1), + create_cb_data(group, handle, i, TYPE_WIDE)); + } + + /* the volume widget */ + if(group->einfo[i].data.teffect1.effect & SND_MIXER_EFF1_VOLUME) { + box = gtk_hbox_new(FALSE, 0); + gtk_widget_show(box); + gtk_box_pack_start(GTK_BOX(vbox), box, FALSE, FALSE, 0); + + label = gtk_label_new("3D Effect Volume"); + gtk_widget_show(label); + gtk_box_pack_start(GTK_BOX(box), label, FALSE, FALSE, 0); + + + adj = gtk_adjustment_new(group->element[i].data.teffect1.volume, + group->einfo[i].data.teffect1.min_volume, + group->einfo[i].data.teffect1.max_volume, + 1.0, + 3.0, + 0.0); + widget = gtk_hscale_new(GTK_ADJUSTMENT(adj)); + gtk_scale_set_value_pos(GTK_SCALE(widget), + GTK_POS_RIGHT); + gtk_widget_set_usize(widget, 100, -1); + gtk_widget_show(widget); + gtk_box_pack_end(GTK_BOX(box), widget, FALSE, FALSE, 0); + /* connect the signal */ + gtk_signal_connect(GTK_OBJECT(adj), + "value_changed", + GTK_SIGNAL_FUNC (adjust_teffect1), + create_cb_data(group, handle, i, TYPE_VOLUME)); + } + + + /* The center widget */ + if(group->einfo[i].data.teffect1.effect & SND_MIXER_EFF1_CENTER) { + box = gtk_hbox_new(FALSE, 0); + gtk_widget_show(box); + gtk_box_pack_start(GTK_BOX(vbox), box, FALSE, FALSE, 0); + + label = gtk_label_new("3D Effect Center"); + gtk_widget_show(label); + gtk_box_pack_start(GTK_BOX(box), label, FALSE, FALSE, 0); + + + adj = gtk_adjustment_new(group->element[i].data.teffect1.center, + group->einfo[i].data.teffect1.min_center, + group->einfo[i].data.teffect1.max_center, + 1.0, + 3.0, + 0.0); + widget = gtk_hscale_new(GTK_ADJUSTMENT(adj)); + gtk_scale_set_value_pos(GTK_SCALE(widget), + GTK_POS_RIGHT); + gtk_widget_set_usize(widget, 100, -1); + gtk_widget_show(widget); + gtk_box_pack_end(GTK_BOX(box), widget, FALSE, FALSE, 0); + gtk_signal_connect(GTK_OBJECT(adj), + "value_changed", + GTK_SIGNAL_FUNC (adjust_teffect1), + create_cb_data(group, handle, i, TYPE_CENTER)); + } + + + /* The Space widget */ + if(group->einfo[i].data.teffect1.effect & SND_MIXER_EFF1_SPACE) { + box = gtk_hbox_new(FALSE, 0); + gtk_widget_show(box); + gtk_box_pack_start(GTK_BOX(vbox), box, FALSE, FALSE, 0); + + label = gtk_label_new("3D Effect Space"); + gtk_widget_show(label); + gtk_box_pack_start(GTK_BOX(box), label, FALSE, FALSE, 0); + + + adj = gtk_adjustment_new(group->element[i].data.teffect1.space, + group->einfo[i].data.teffect1.min_space, + group->einfo[i].data.teffect1.max_space, + 1.0, + 3.0, + 0.0); + widget = gtk_hscale_new(GTK_ADJUSTMENT(adj)); + gtk_scale_set_value_pos(GTK_SCALE(widget), + GTK_POS_RIGHT); + gtk_widget_set_usize(widget, 100, -1); + gtk_widget_show(widget); + gtk_box_pack_end(GTK_BOX(box), widget, FALSE, FALSE, 0); + gtk_signal_connect(GTK_OBJECT(adj), + "value_changed", + GTK_SIGNAL_FUNC (adjust_teffect1), + create_cb_data(group, handle, i, TYPE_SPACE)); + } + + /* The depth widget */ + if(group->einfo[i].data.teffect1.effect & SND_MIXER_EFF1_DEPTH) { + box = gtk_hbox_new(FALSE, 0); + gtk_widget_show(box); + gtk_box_pack_start(GTK_BOX(vbox), box, FALSE, FALSE, 0); + + label = gtk_label_new("3D Effect Depth"); + gtk_widget_show(label); + gtk_box_pack_start(GTK_BOX(box), label, FALSE, FALSE, 0); + + + adj = gtk_adjustment_new(group->element[i].data.teffect1.depth, + group->einfo[i].data.teffect1.min_depth, + group->einfo[i].data.teffect1.max_depth, + 1.0, + 3.0, + 0.0); + widget = gtk_hscale_new(GTK_ADJUSTMENT(adj)); + gtk_scale_set_value_pos(GTK_SCALE(widget), + GTK_POS_RIGHT); + gtk_widget_set_usize(widget, 100, -1); + gtk_widget_show(widget); + gtk_box_pack_end(GTK_BOX(box), widget, FALSE, FALSE, 0); + gtk_signal_connect(GTK_OBJECT(adj), + "value_changed", + GTK_SIGNAL_FUNC (adjust_teffect1), + create_cb_data(group, handle, i, TYPE_DEPTH)); + } + + /* The delay widget */ + if(group->einfo[i].data.teffect1.effect & SND_MIXER_EFF1_DELAY) { + box = gtk_hbox_new(FALSE, 0); + gtk_widget_show(box); + gtk_box_pack_start(GTK_BOX(vbox), box, FALSE, FALSE, 0); + + label = gtk_label_new("3D Effect Delay"); + gtk_widget_show(label); + gtk_box_pack_start(GTK_BOX(box), label, FALSE, FALSE, 0); + + + adj = gtk_adjustment_new(group->element[i].data.teffect1.delay, + group->einfo[i].data.teffect1.min_delay, + group->einfo[i].data.teffect1.max_delay, + 1.0, + 3.0, + 0.0); + widget = gtk_hscale_new(GTK_ADJUSTMENT(adj)); + gtk_scale_set_value_pos(GTK_SCALE(widget), + GTK_POS_RIGHT); + gtk_widget_set_usize(widget, 100, -1); + gtk_widget_show(widget); + gtk_box_pack_end(GTK_BOX(box), widget, FALSE, FALSE, 0); + gtk_signal_connect(GTK_OBJECT(adj), + "value_changed", + GTK_SIGNAL_FUNC (adjust_teffect1), + create_cb_data(group, handle, i, TYPE_DELAY)); + } + + + /* The feedback widget */ + if(group->einfo[i].data.teffect1.effect & SND_MIXER_EFF1_FEEDBACK) { + box = gtk_hbox_new(FALSE, 0); + gtk_widget_show(box); + gtk_box_pack_start(GTK_BOX(vbox), box, FALSE, FALSE, 0); + + label = gtk_label_new("3D Effect Feedback"); + gtk_widget_show(label); + gtk_box_pack_start(GTK_BOX(box), label, FALSE, FALSE, 0); + + + adj = gtk_adjustment_new(group->element[i].data.teffect1.feedback, + group->einfo[i].data.teffect1.min_feedback, + group->einfo[i].data.teffect1.max_feedback, + 1.0, + 3.0, + 0.0); + widget = gtk_hscale_new(GTK_ADJUSTMENT(adj)); + gtk_scale_set_value_pos(GTK_SCALE(widget), + GTK_POS_RIGHT); + gtk_widget_set_usize(widget, 100, -1); + gtk_widget_show(widget); + gtk_box_pack_end(GTK_BOX(box), widget, FALSE, FALSE, 0); + gtk_signal_connect(GTK_OBJECT(adj), + "value_changed", + GTK_SIGNAL_FUNC (adjust_teffect1), + create_cb_data(group, handle, i, TYPE_FEEDBACK)); + } + + + + return vbox; +} + +GtkWidget *display_switch1(Group *group, int element, void *handle, char *route) +{ + GtkWidget *box; + GtkTooltips *tooltips; + GtkWidget *button; + int i, j; + + i = element; + + box = gtk_hbox_new(FALSE, 0); + gtk_widget_show(box); + + /* Allocate the widget array */ + group->gtk[i].interface = calloc(group->element[i].data.switch1.sw, sizeof(GtkWidget *)); + + for(j = 0; j < group->element[i].data.switch1.sw; j++) { + button = gtk_check_button_new(); + /* looks painful, doesn't it? It's checking the state of the appropriate bit */ + if(group->element[i].data.switch1.psw[j / sizeof(unsigned int)] & + (1 << (j % sizeof(unsigned int)))) + gtk_toggle_button_set_state(GTK_TOGGLE_BUTTON (button), TRUE); + gtk_widget_show(button); + + /* Set up the tooltips */ + tooltips = gtk_tooltips_new(); + gtk_tooltips_set_tip (tooltips, button, route, NULL); + + + gtk_box_pack_start(GTK_BOX (box), button, FALSE, FALSE, 0); + + /* Connect it to the callback */ + gtk_signal_connect(GTK_OBJECT(button), "toggled", + GTK_SIGNAL_FUNC(adjust_switch1), + create_cb_data(group, handle, i, j)); + + /* Store the widget */ + group->gtk[i].interface[j] = button; + } + + + return box; +} + + +GtkWidget *display_switch2(Group *group, int element, void *handle, char *route) +{ + GtkWidget *button; + GtkTooltips *tooltips; + int i, j=0; + + i = element; + + if(!group) { + printf("Group isn't initialized!\n"); + return NULL; + } + + button = gtk_check_button_new(); + + if(group->element) + if(group->element[i].data.switch2.sw) { + gtk_toggle_button_set_state(GTK_TOGGLE_BUTTON(button), TRUE); + } + + gtk_widget_show(button); + + /* Set up the tooltip */ + tooltips = gtk_tooltips_new(); + gtk_tooltips_set_tip (tooltips, button, route, NULL); + + if(group->gtk) { + group->gtk[i].interface = calloc(1, sizeof(GtkWidget *)); + group->gtk[i].interface[j] = button; + } else { + printf("Something wasn't initialized properly.\n"); + } + + /* Connect it to the callback */ + gtk_signal_connect(GTK_OBJECT(group->gtk[i].interface[j]), + "toggled", + GTK_SIGNAL_FUNC (adjust_switch2), + create_cb_data(group, handle, element, j)); + + return button; +} + +GtkWidget *display_volume1(Group *group, int element, void *handle, char *route) +{ + GtkWidget *box; + GtkTooltips *tooltips; + int i,j; + + i = element; + + box = gtk_vbox_new(FALSE, 0); + gtk_widget_show(box); + + group->gtk[i].adjust = calloc(group->element[i].data.volume1.voices, + sizeof(GtkObject *)); + group->gtk[i].interface = calloc(group->element[i].data.volume1.voices, + sizeof(GtkWidget *)); + + for(j=0; j < group->element[i].data.volume1.voices; j++) { + group->gtk[i].adjust[j] = + gtk_adjustment_new(group->element[i].data.volume1.pvoices[j], + group->einfo[i].data.volume1.prange[0].min, + group->einfo[i].data.volume1.prange[0].max, + 1.0, + 3.0, + 0.0); + + group->gtk[i].interface[j] = + gtk_hscale_new(GTK_ADJUSTMENT(group->gtk[i].adjust[j])); + + gtk_signal_connect(GTK_OBJECT(group->gtk[i].adjust[j]), + "value_changed", + GTK_SIGNAL_FUNC (adjust_volume1), + create_cb_data(group, handle, element, j)); + +/* gtk_scale_set_draw_value(GTK_SCALE(group->gtk[i].interface[j]), */ +/* FALSE); */ + + gtk_scale_set_value_pos(GTK_SCALE(group->gtk[i].interface[j]), + GTK_POS_RIGHT); + + gtk_widget_set_usize(group->gtk[i].interface[j], 100, -1); + + gtk_widget_show(group->gtk[i].interface[j]); + gtk_box_pack_start(GTK_BOX(box), + group->gtk[i].interface[j], + FALSE, FALSE, 0); + + /* Set up the tooltip */ + tooltips = gtk_tooltips_new(); + gtk_tooltips_set_tip (tooltips, group->gtk[i].interface[j], route, NULL); + + } + + + + return box; +} diff --git a/xamixer2/display.h b/xamixer2/display.h new file mode 100644 index 0000000..d3ff77e --- /dev/null +++ b/xamixer2/display.h @@ -0,0 +1,33 @@ +/*****************************************************************************/ +/* Begin #include statements */ + +/* End #include statements */ +/*****************************************************************************/ + + +/*****************************************************************************/ +/* Begin function prototypes */ + +GtkWidget *create_mixer_page(int card_num, int mixer_num); + + +/* End function prototypes */ +/*****************************************************************************/ + +/*****************************************************************************/ +/* Begin #define statements */ + +/* These types are for the callback data identification */ +#define TYPE_EFFECT 0 +#define TYPE_SW 1 +#define TYPE_MONO_SW 2 +#define TYPE_WIDE 3 +#define TYPE_VOLUME 4 +#define TYPE_CENTER 5 +#define TYPE_SPACE 6 +#define TYPE_DEPTH 7 +#define TYPE_DELAY 8 +#define TYPE_FEEDBACK 9 + +/* End #define statements */ +/*****************************************************************************/ diff --git a/xamixer2/main.c b/xamixer2/main.c new file mode 100644 index 0000000..e69de29 diff --git a/xamixer2/main.h b/xamixer2/main.h new file mode 100644 index 0000000..4ddf448 --- /dev/null +++ b/xamixer2/main.h @@ -0,0 +1,95 @@ +/*****************************************************************************/ +/* Begin system #includes */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +/* End system #includes */ +/*****************************************************************************/ + + + +/*****************************************************************************/ +/* Begin program #includes */ + +#include "structs.h" +#include "util.h" +#include "xamixer2.h" +#include "cinit.h" +#include "callbacks.h" +#include "display.h" +#include "config.h" +#include "switches.h" +#include "options.h" + +/* End program #includes */ +/*****************************************************************************/ + + + +/*****************************************************************************/ +/* Begin #defines */ + +#define CHANNEL_LEFT (1 << 0) +#define CHANNEL_RIGHT (1 << 1) +#define CHANNEL_MONO (1 << 2) +#define CHANNEL_MUTE_RIGHT (1 << 3) +#define CHANNEL_MUTE_LEFT (1 << 4) +#define CHANNEL_MUTE_MONO (1 << 5) +#define CHANNEL_RECORD (1 << 6) +#define CHANNEL_RECORD_RIGHT (1 << 7) +#define CHANNEL_RECORD_LEFT (1 << 8) +#define CHANNEL_SIMULTANEOUS (1 << 9) +#define CHANNEL_DISPLAYED (1 << 10) +#define CHANNEL_LTOR (1 << 11) +#define CHANNEL_RTOL (1 << 12) + + +#define CONFIG_USE_XPMS (1 << 0) +#define CONFIG_ICON_XPM (1 << 1) +#define CONFIG_MUTE_XPM (1 << 2) +#define CONFIG_MUTE_XPM_L (1 << 3) +#define CONFIG_UNMUTE_XPM (1 << 4) +#define CONFIG_UNMUTE_XPM_L (1 << 5) +#define CONFIG_REC_XPM (1 << 6) +#define CONFIG_UNREC_XPM (1 << 7) +#define CONFIG_SIMUL_XPM (1 << 8) +#define CONFIG_UNSIMUL_XPM (1 << 9) +#define CONFIG_LTOR_XPM (1 << 10) +#define CONFIG_UNLTOR_XPM (1 << 11) +#define CONFIG_RTOL_XPM (1 << 12) +#define CONFIG_UNRTOL_XPM (1 << 13) +#define CONFIG_BACKGROUND_XPM (1 << 14) +#define CONFIG_SHOW_CARD_NAME (1 << 15) +#define CONFIG_SHOW_MIXER_NUMBER (1 << 16) +#define CONFIG_SHOW_MIXER_NAME (1 << 17) +#define CONFIG_SWITCHES_HIDDEN (1 << 18) + +/* End #defines */ +/*****************************************************************************/ + + + +/*****************************************************************************/ +/* Gtk 1.0 compatability */ + +#ifndef GTK_HAVE_FEATURES_1_1_0 +#define gtk_button_set_relief(a,b) +#endif + +/* End Gtk 1.0 compatability */ +/*****************************************************************************/ + + + + diff --git a/xamixer2/options.c b/xamixer2/options.c new file mode 100644 index 0000000..e69de29 diff --git a/xamixer2/options.h b/xamixer2/options.h new file mode 100644 index 0000000..e69de29 diff --git a/xamixer2/structs.h b/xamixer2/structs.h new file mode 100644 index 0000000..a8381f0 --- /dev/null +++ b/xamixer2/structs.h @@ -0,0 +1,158 @@ +/******************************************************************************/ +/* Begin Structures */ + +struct _Gtk_Channel +{ + GtkWidget **interface; /* And array of the interfaces (slider, button, etc.) */ + GtkObject **adjust; /* An array of the adjustments */ +}; +typedef struct _Gtk_Channel Gtk_Channel; + +struct _Group +{ + snd_mixer_group_t group; /* The group structure */ + snd_mixer_element_t *element; /* an array of all the elements in the group */ + snd_mixer_element_info_t *einfo; /* an array of the info about all of the elements */ + snd_mixer_routes_t *routes; /* an array of all the routes for the elements */ + Gtk_Channel *gtk; /* The Gtk+ widgets used for each mixer element */ +}; +typedef struct _Group Group; + +struct _Mixer +{ + int number; /* The number of the mixer device */ + void *handle; + snd_mixer_info_t info; /* The info for the mixer */ + int cnum; /* The number of channels present */ + int snum; /* The number of mixer switches present */ + snd_mixer_groups_t groups; /* The mixer groups */ + Group *group; /* An array of the mixer groups */ + char name[80]; /* The name of the mixer */ + GtkWidget *switch_table; +}; +typedef struct _Mixer Mixer; + + + +struct _Card +{ + snd_ctl_hw_info_t hw_info; /* The hardware info about the card. */ + int number; /* The card's number */ + void *handle; /* The handle for the mixer */ + char name[80]; /* The name of the card */ + Mixer *mixer; /* A dynamic array of all of the mixers */ + int nmixers; /* The number of mixers on the card */ + int npcms; /* The number of pcm devices */ +}; +typedef struct _Card Card; + + +struct _MixerInfo +{ + Mixer *mixer; /* Which card */ + int channel; /* Which channel */ + unsigned int flags; /* flags */ + GtkWidget *other; /* The other range widget */ + GtkWidget *mute; /* The mute pixmap */ + GtkWidget *unmute; /* The unmute pixmap */ +}; +typedef struct _MixerInfo MixerInfo; + + +struct _ChannelLabel +{ + struct _ChannelLabel *next; /* pointer to the next node in the list */ + char *channel; /* The channel name */ + char *label; /* The channel label or pixmap */ +}; +typedef struct _ChannelLabel ChannelLabel; + + +struct _CBData +{ + Group *group; /* The group */ + void *handle; /* The mixer handle */ + int element; /* The element number to use as an index */ + int index; /* The index such as the voice # or something like that */ +}; +typedef struct _CBData CBData; + + + +struct _Config +{ + unsigned int flags; /* Flags */ + ChannelLabel *labels; /* The text labels for channels */ + ChannelLabel *xpm; /* The pixmaps (file names) for channels */ + char *icon; /* The Icon pixmap to use */ + char *mute; /* The mute label or pixmap (indicated in a flag) */ + char *mute_l; /* The left mute label or pixmap (indicated in a flag) */ + char *unmute; /* The unmute label or pixmap (indicated in a flag) */ + char *unmute_l; /* The left unmute label or pixmap (indicated in a flag) */ + char *simul; /* The simultaneous label or pixmap (indicated in a flag */ + char *unsimul; /* The unsimultaneous label or pixmap (indicated in a flag */ + char *rec; /* The record label or pixmap (indicated in a flag) */ + char *unrec; /* The unrecord label or pixmap (indicated in a flag) */ + char *background; /* The background xpm */ + unsigned int scale; /* The size in pixels that the scales should be set to */ + unsigned int padding; /* The padding between channels */ + int x_pos, y_pos; /* The position to start out at -1 = default */ + GtkWidget *cdisplay; /* The channel display window */ + GdkPixmap *icon_xpm; /* The icon xpm */ + GdkPixmap *mute_xpm; /* The mute pixmap */ + GdkPixmap *unmute_xpm; /* The unmute pixmap */ + GdkPixmap *mute_xpm_l; /* The left mute pixmap */ + GdkPixmap *unmute_xpm_l; /* The left unmute pixmap */ + GdkPixmap *rec_xpm; /* The record pixmap */ + GdkPixmap *unrec_xpm; /* The record off pixmap */ + GdkPixmap *simul_xpm; /* The sumultaneous pixmap */ + GdkPixmap *unsimul_xpm; /* The independent pixmap */ + GdkPixmap *background_xpm; /* The background pixmap */ + GdkBitmap *icon_mask; + GdkBitmap *mute_mask; + GdkBitmap *unmute_mask; + GdkBitmap *mute_mask_l; + GdkBitmap *unmute_mask_l; + GdkBitmap *rec_mask; + GdkBitmap *unrec_mask; + GdkBitmap *simul_mask; + GdkBitmap *unsimul_mask; + GdkBitmap *background_mask; +}; +typedef struct _Config Config; + +/* End Structures */ +/******************************************************************************/ + + +#if 0 +struct _Channel +{ + int num; /* The channel's number */ + snd_mixer_channel_t data; /* the data */ + snd_mixer_channel_info_t info; /* The info */ + unsigned int flags; /* The Channel's flags */ + GtkWidget *lm, *rm, *mm, *rec; /* The associated widgets */ + GtkWidget *lrec, *rrec; /* More associated widgets */ + GtkObject *ladj, *radj, *madj; /* The associated objects */ + GtkTooltips *left_tt, *right_tt, *mono_tt; /* The tooltips */ + GtkWidget *lscal, *rscal, *mscal; /* The scale widgets */ + GtkWidget *label, *lock; + GtkWidget *ltor_in, *rtol_in; + void *mixer; /* A pointer to the mixer */ +}; +typedef struct _Channel Channel; +#endif + + + + + + + + + + + + + diff --git a/xamixer2/switches.c b/xamixer2/switches.c new file mode 100644 index 0000000..e69de29 diff --git a/xamixer2/switches.h b/xamixer2/switches.h new file mode 100644 index 0000000..e69de29 diff --git a/xamixer2/test.c b/xamixer2/test.c new file mode 100644 index 0000000..86d94c0 --- /dev/null +++ b/xamixer2/test.c @@ -0,0 +1,31 @@ +#include +#include +#include + +int main(int argc, char **argv) +{ + GtkWidget *window; + GtkWidget *scale; + GtkObject *adj; + + + gtk_init(&argc, &argv); + + window=gtk_window_new(GTK_WINDOW_TOPLEVEL); + adj = gtk_adjustment_new(1.0, + 0.0, + 110.0, + 1.0, + 4.0, + 0.0); + scale = gtk_hscale_new(GTK_ADJUSTMENT(adj)); + gtk_widget_show(scale); + gtk_container_add(GTK_CONTAINER(window), scale); + + + gtk_widget_show(window); + gtk_main(); + + + return 0; +} diff --git a/xamixer2/test1.c b/xamixer2/test1.c new file mode 100644 index 0000000..99ef65f --- /dev/null +++ b/xamixer2/test1.c @@ -0,0 +1,11 @@ +#include + +main() +{ + printf("The value is %i\n", ~(1 << 1)); + + + + + return 0; +} diff --git a/xamixer2/util.c b/xamixer2/util.c new file mode 100644 index 0000000..4ab710a --- /dev/null +++ b/xamixer2/util.c @@ -0,0 +1,173 @@ +/***************************************************************************** + xamixer.c - an Alsa based gtk mixer + Written by Raistlinn (lansdoct@cs.alfred.edu) + Copyright (C) 1998 by Christopher Lansdown + + 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +******************************************************************************/ + +/*****************************************************************************/ +/* Begin #include's */ + +#include "main.h" + +/* End #include's */ +/*****************************************************************************/ +extern Config config; /* The system config */ + + +int is_same(char *string1, char *string2) +{ + int i = 0; + + if(strlen(string1) != strlen(string2)) + return 0; + + while(string1[i] != '\0') + if(string1[i] != string2[i]) + return 0; + else + i++; + + return 1; + +} + +void strip_comment(char *string) +{ + char *place; + int i = 0, j = 0, size; + + size = strlen(string); + /* Get wrid of the comments */ + place = string; + while((place = strchr(place, '#'))){ + if(string[(place - string) -1] != '\\') + *place = '\0'; + place++; + } + + /* Replace the escape sequences */ + place = calloc(1, strlen(string)); + while(string[i] != '\0'){ + if(string[i] == '\\') + place[j] = string[++i]; + else + place[j] = string[i]; + + i++; + j++; + } + + EAZERO(string, size); + strncpy(string, place, size); + free(place); + return; +} + +int is_comment(char *string) +{ + int i=0; + + while (string[i] != '\0'){ + if (string[i] == '#') + return 1; + if (string[i] != ' ' && string[i] != '\t') + return 0; + i++; + } + return 0; +} + +ChannelLabel *channel_label_append(ChannelLabel *head, char *channel, char *label) +{ + ChannelLabel *tmp; + + tmp = calloc(1, sizeof(ChannelLabel)); + + tmp->next = head; + tmp->channel = calloc(strlen(channel) + 1, sizeof(char)); + strcpy(tmp->channel, channel); + tmp->label = calloc(strlen(label) + 1, sizeof(char)); + strcpy(tmp->label, label); + + return tmp; +} + +int get_label(char *line, char *expect, char *value1, size_t value1_len, + char *value2, size_t value2_len, char quote1, char quote2) +{ + char *tmp; + int len, i; + + len = strlen(line); + + if(expect) { + tmp = strstr(line, expect); + if(!tmp) + return FALSE; + tmp = &tmp[strlen(expect)]; + } + else + tmp = line; + + + tmp = strchr(tmp, quote1) + 1; + if(!tmp) + return FALSE; + for(i = 0; i < (value1_len - 1) && tmp[i] != quote2; i++) + value1[i] = tmp[i]; + value1[i] = '\0'; + + tmp = strchr(tmp, quote1) + 1; + if(!tmp) + return FALSE; + for(i = 0; i < (value2_len - 1) && tmp[i] != quote2; i++) + value2[i] = tmp[i]; + value2[i] = '\0'; + + + + return TRUE; +} + +MixerInfo *create_mixer_info(Mixer *mixer, int num, unsigned int flags) +{ + MixerInfo *info; + info = calloc(1, sizeof(MixerInfo)); + + info->mixer = mixer; + info->channel = num; + info->flags = flags; + info->other = NULL; + info->mute = NULL; + info->unmute = NULL; + + return info; +} + +CBData *create_cb_data(Group *group, void *handle, int element, int index) +{ + CBData *data; + + data = malloc(sizeof(CBData)); + + data->group = group; + data->handle = handle; + data->element = element; + data->index = index; + + return data; +} diff --git a/xamixer2/util.h b/xamixer2/util.h new file mode 100644 index 0000000..e97e83a --- /dev/null +++ b/xamixer2/util.h @@ -0,0 +1,38 @@ +/*****************************************************************************/ +/* Begin #include statements */ + +/* End #include statements */ +/*****************************************************************************/ + + +/*****************************************************************************/ +/* Begin function prototypes */ + +int is_same(char *string1, char *string2); +void strip_comment(char *string); +int is_comment(char *string); +ChannelLabel *channel_label_append(ChannelLabel *head, char *channel, char *label); +int get_label(char *line, char *expect, char *value1, size_t value1_len, + char *value2, size_t value2_len, char quote1, char quote2); +MixerInfo *create_mixer_info(Mixer *mixer, int num, unsigned int flags); +CBData *create_cb_data(Group *group, void *handle, int element, int index); + +/* End function prototypes */ +/*****************************************************************************/ + +/*****************************************************************************/ +/* Begin #define statements */ + + +/* End #define statements */ +/*****************************************************************************/ + +/*****************************************************************************/ +/* Begin Macros */ + +#define EAZERO(S, L) S[L-1] = '\0'; +#define MIXER(m) ((Mixer *)m) + +/* End Macros */ +/*****************************************************************************/ + diff --git a/xamixer2/xamixer.conf b/xamixer2/xamixer.conf new file mode 100644 index 0000000..322c902 --- /dev/null +++ b/xamixer2/xamixer.conf @@ -0,0 +1,47 @@ +# XAmixer home file +# Comments are preceded anywhere on the line by a '#' +# All channel arguments (string & pixmap) must be enclosed in [ ] [ ] +UseXpms +#IgnoreXpms +ScaleSize 115 +ChannelPadding 5 +Position -1 -1 # Both arguments must be set (and >= 0) to get positioning. +ShowCardName +#ShowMixerNumber +#ShowMixerName +#MuteLabel Mute +#RecLabel Record +RecLabel R +#SimulLabel Lock +#BackgroundXpm /usr/local/share/xamixer/pixmaps/test.xpm +#BackgroundXpm /home/raistlin/xamixer/pixmaps/background5.xpm +#BackgroundXpm /home/raistlin/xamixer/pixmaps/background.xpm +#BackgroundXpm /tmp/background.xpm +IconXpm /usr/local/share/xamixer/pixmaps/icon3.xpm +#MuteXpm /usr/local/share/xamixer/pixmaps/mute3.xpm +#unMuteXpm /usr/local/share/xamixer/pixmaps/unmute3.xpm +MuteXpm /usr/local/share/xamixer/pixmaps/mute3.xpm +unMuteXpm /usr/local/share/xamixer/pixmaps/unmute3.xpm +#RecXpm /usr/local/share/xamixer/pixmaps/record.xpm +#unRecXpm /usr/local/share/xamixer/pixmaps/unrecord.xpm +RecXpm /usr/local/share/xamixer/pixmaps/rec.xpm +unRecXpm /usr/local/share/xamixer/pixmaps/unrec.xpm +#RecXpm /home/raistlin/xamixer/pixmaps/record.xpm +#unRecXpm /home/raistlin/xamixer/pixmaps/unrecord.xpm +SimulXpm /usr/local/share/xamixer/pixmaps/simul.xpm +unSimulXpm /usr/local/share/xamixer/pixmaps/unsimul.xpm +Label [Master] [Mstr] +Label [Master M] [MstrM] +Label [Line-In] [LineIn] +Label [Record-Gain] [RGain] +Label [PC Speaker] [Spkr] +Label [Aux A] [AuxA] +Label [In-Gain] [IGain] +Label [Out-Gain] [OGain] +Xpm [Master] [/usr/local/share/xamixer/pixmaps/master.xpm] +Xpm [CD] [/usr/local/share/xamixer/pixmaps/cd.xpm] +Xpm [MIC] [/usr/local/share/xamixer/pixmaps/mic.xpm] +Xpm [PCM] [/usr/local/share/xamixer/pixmaps/pcm.xpm] +Xpm [Synth] [/usr/local/share/xamixer/pixmaps/synth.xpm] +Xpm [Line-In] [/usr/local/share/xamixer/pixmaps/line-in.xpm] +Xpm [PC Speaker] [/usr/local/share/xamixer/pixmaps/speaker.xpm] diff --git a/xamixer2/xamixer.home b/xamixer2/xamixer.home new file mode 100644 index 0000000..322c902 --- /dev/null +++ b/xamixer2/xamixer.home @@ -0,0 +1,47 @@ +# XAmixer home file +# Comments are preceded anywhere on the line by a '#' +# All channel arguments (string & pixmap) must be enclosed in [ ] [ ] +UseXpms +#IgnoreXpms +ScaleSize 115 +ChannelPadding 5 +Position -1 -1 # Both arguments must be set (and >= 0) to get positioning. +ShowCardName +#ShowMixerNumber +#ShowMixerName +#MuteLabel Mute +#RecLabel Record +RecLabel R +#SimulLabel Lock +#BackgroundXpm /usr/local/share/xamixer/pixmaps/test.xpm +#BackgroundXpm /home/raistlin/xamixer/pixmaps/background5.xpm +#BackgroundXpm /home/raistlin/xamixer/pixmaps/background.xpm +#BackgroundXpm /tmp/background.xpm +IconXpm /usr/local/share/xamixer/pixmaps/icon3.xpm +#MuteXpm /usr/local/share/xamixer/pixmaps/mute3.xpm +#unMuteXpm /usr/local/share/xamixer/pixmaps/unmute3.xpm +MuteXpm /usr/local/share/xamixer/pixmaps/mute3.xpm +unMuteXpm /usr/local/share/xamixer/pixmaps/unmute3.xpm +#RecXpm /usr/local/share/xamixer/pixmaps/record.xpm +#unRecXpm /usr/local/share/xamixer/pixmaps/unrecord.xpm +RecXpm /usr/local/share/xamixer/pixmaps/rec.xpm +unRecXpm /usr/local/share/xamixer/pixmaps/unrec.xpm +#RecXpm /home/raistlin/xamixer/pixmaps/record.xpm +#unRecXpm /home/raistlin/xamixer/pixmaps/unrecord.xpm +SimulXpm /usr/local/share/xamixer/pixmaps/simul.xpm +unSimulXpm /usr/local/share/xamixer/pixmaps/unsimul.xpm +Label [Master] [Mstr] +Label [Master M] [MstrM] +Label [Line-In] [LineIn] +Label [Record-Gain] [RGain] +Label [PC Speaker] [Spkr] +Label [Aux A] [AuxA] +Label [In-Gain] [IGain] +Label [Out-Gain] [OGain] +Xpm [Master] [/usr/local/share/xamixer/pixmaps/master.xpm] +Xpm [CD] [/usr/local/share/xamixer/pixmaps/cd.xpm] +Xpm [MIC] [/usr/local/share/xamixer/pixmaps/mic.xpm] +Xpm [PCM] [/usr/local/share/xamixer/pixmaps/pcm.xpm] +Xpm [Synth] [/usr/local/share/xamixer/pixmaps/synth.xpm] +Xpm [Line-In] [/usr/local/share/xamixer/pixmaps/line-in.xpm] +Xpm [PC Speaker] [/usr/local/share/xamixer/pixmaps/speaker.xpm] diff --git a/xamixer2/xamixer2.c b/xamixer2/xamixer2.c new file mode 100644 index 0000000..3393924 --- /dev/null +++ b/xamixer2/xamixer2.c @@ -0,0 +1,188 @@ +/***************************************************************************** + xamixer.c - an Alsa based gtk mixer + Written by Raistlinn (lansdoct@cs.alfred.edu) + Copyright (C) 1998 by Christopher Lansdown + + 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +******************************************************************************/ + +/*****************************************************************************/ +/* Begin #include's */ + +#include "main.h" + +/* End #include's */ +/*****************************************************************************/ + +/*****************************************************************************/ +/* Begin Global Variables */ + +GtkWidget *window; +Card *card; /* And array of the cards */ +int cards; /* The number of cards in the system. */ +extern Config config; /* The system config */ + +/* End Global Variables */ +/*****************************************************************************/ + +int main(int argc, char **argv) +{ + + /* Begin Variable Declarations */ + GtkWidget *mainbox; + GtkWidget *notebook; + GtkWidget *frame; + GtkWidget *label; + GtkWidget *table; + GtkWidget *switch_button; + GtkWidget *tmpbox; + GtkWidget *tablebox; + GtkWidget *separator; + int i,j,k,xpm,found,fd; + char title[32]; + char name[128]; + ChannelLabel *tmp; + char labelname[256]; + char *home_env, *home_dir; + GtkStyle *style; + GtkWidget *hbox; + /* End Variable Declarations */ + + /* Go through gtk initialization */ + gtk_init(&argc, &argv); + + /* Read the personal config file - these values override the global config */ + home_env = getenv("HOME"); + home_dir = calloc((strlen(home_env) + 2 + strlen(RCFILE)), 1); + strcpy(home_dir, home_env); + strcat(home_dir, "/"); + strcat(home_dir, RCFILE); + gtk_rc_parse(home_dir); + free(home_dir); + + /* Read in the soundcard info */ + if(init_cards()) { + printf("Error. Unable to initialize sound cards.\n"); + return 1; + } + + /* Read in normal config info */ + config_init(); + config_read("/usr/local/etc/xamixer.conf"); + home_env = getenv("HOME"); + home_dir = calloc((strlen(home_env) + 2 + strlen(HOME_FILE)), 1); + strcpy(home_dir, home_env); + strcat(home_dir, "/"); + strcat(home_dir, HOME_FILE); + config_read(home_dir); + free(home_dir); + + /* Make the title */ + sprintf(title, "XAmixer2 %s", VERSION); + + /* Create the main window */ + window = gtk_window_new(GTK_WINDOW_TOPLEVEL); + gtk_window_set_title(GTK_WINDOW(window), title); + gtk_signal_connect(GTK_OBJECT (window), "delete_event", + (GtkSignalFunc) gtk_main_quit, NULL); + signal(SIGINT, (void *)gtk_main_quit); + /* Set the policy */ + gtk_window_set_policy(GTK_WINDOW (window), TRUE, TRUE, TRUE); + /* Set the position, if one has been defined */ + gtk_widget_set_uposition(window, config.x_pos, config.y_pos); + /* Realize the window so that we can start drawing pixmaps to it */ + gtk_widget_realize(window); + + /* Set up the pixmaps */ + setup_pixmaps(window); + + + /* Create the notebook */ + notebook = gtk_notebook_new(); + gtk_notebook_set_tab_pos (GTK_NOTEBOOK (notebook), GTK_POS_TOP); + + gtk_widget_show(notebook); + gtk_container_add(GTK_CONTAINER(window), notebook); + + + /* Create the notebook pages */ + for(i = 0; i < cards; i++) { + for(j = 0; j < card[i].hw_info.mixerdevs; j++) { + + frame = create_mixer_page(i, j); + + + + + /* Create the label and add the page to the notebook */ + bzero(labelname, 256); + if(config.flags & CONFIG_SHOW_CARD_NAME) { + strcpy(labelname, card[i].hw_info.name); + if(config.flags & (CONFIG_SHOW_MIXER_NAME | + CONFIG_SHOW_MIXER_NUMBER)) + strcat(labelname, ", "); + } + + if(config.flags & CONFIG_SHOW_MIXER_NUMBER) { + /* Do some trickery to get around an additional + variable, plus this may be more efficient, + since strcat() has to figure out where the end + of the line is anyhow, plus the copying. */ + sprintf(&labelname[strlen(labelname)], "Mixer %i", j); + if(config.flags & CONFIG_SHOW_MIXER_NAME) + strcat(labelname, ", "); + } + + if(config.flags & CONFIG_SHOW_MIXER_NAME) + strcat(labelname, card[i].mixer[j].info.name); + + /* Just in case nothing is specified in the config file */ + if(!(config.flags & (CONFIG_SHOW_CARD_NAME | + CONFIG_SHOW_MIXER_NAME | + CONFIG_SHOW_MIXER_NUMBER))) + sprintf(labelname, "%i", i + j); + + label = gtk_label_new(labelname); + gtk_widget_show(label); + gtk_notebook_append_page (GTK_NOTEBOOK (notebook), frame, label); + + + } + } + + /* Create the options page */ + frame = gtk_frame_new(""); + gtk_widget_show(frame); + // gtk_container_add(GTK_CONTAINER (frame), create_options_page()); + label = gtk_label_new("Options"); + gtk_widget_show(label); + gtk_notebook_append_page(GTK_NOTEBOOK (notebook), frame, label); + + + /* Set up the icon, if one has been defined. */ + if(config.flags & CONFIG_ICON_XPM && config.icon_xpm) + gdk_window_set_icon(window->window, NULL, + config.icon_xpm, config.icon_mask); + + + /* Show the whole kit and kaboodle */ + gtk_widget_show(window); + + /* And go into the gtk loop - why does this feel like the first + plunge in a roller coaster after the big hill at the beginning? */ + gtk_main(); + + return 0; +} diff --git a/xamixer2/xamixer2.h b/xamixer2/xamixer2.h new file mode 100644 index 0000000..980c62d --- /dev/null +++ b/xamixer2/xamixer2.h @@ -0,0 +1,24 @@ +/*****************************************************************************/ +/* Begin #include statements */ + +/* End #include statements */ +/*****************************************************************************/ + + +/*****************************************************************************/ +/* Begin function prototypes */ + + +/* End function prototypes */ +/*****************************************************************************/ + +/*****************************************************************************/ +/* Begin #define statements */ + +#define RCFILE ".xamixerrc" + +/* End #define statements */ +/*****************************************************************************/ + + + -- 2.47.1