Added XAmixer2 to the alsa utilities tree. This should be all of the files necessary to work. Wish me luck.

This commit is contained in:
Christopher Lansdown 1999-06-03 19:51:06 +00:00
parent 67f54274bd
commit ece413337e
32 changed files with 3038 additions and 0 deletions

0
xamixer2/AUTHORS Normal file
View file

282
xamixer2/COPYING Normal file
View file

@ -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

0
xamixer2/ChangeLog Normal file
View file

182
xamixer2/INSTALL Normal file
View file

@ -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.

4
xamixer2/Makefile.am Normal file
View file

@ -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

0
xamixer2/NEWS Normal file
View file

0
xamixer2/README Normal file
View file

0
xamixer2/TODO Normal file
View file

181
xamixer2/callbacks.c Normal file
View file

@ -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;
}

27
xamixer2/callbacks.h Normal file
View file

@ -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 */
/*****************************************************************************/

384
xamixer2/cinit.c Normal file
View file

@ -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;
}

25
xamixer2/cinit.h Normal file
View file

@ -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 */
/*****************************************************************************/

483
xamixer2/config.c Normal file
View file

@ -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;
}

24
xamixer2/config.h Normal file
View file

@ -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 */
/*****************************************************************************/

11
xamixer2/configure.in Normal file
View file

@ -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)

590
xamixer2/display.c Normal file
View file

@ -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;
}

33
xamixer2/display.h Normal file
View file

@ -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 */
/*****************************************************************************/

0
xamixer2/main.c Normal file
View file

95
xamixer2/main.h Normal file
View file

@ -0,0 +1,95 @@
/*****************************************************************************/
/* Begin system #includes */
#include <stdio.h>
#include <unistd.h>
#include <fcntl.h>
#include <math.h>
#include <errno.h>
#include <string.h>
#include <stdlib.h>
#include <signal.h>
#include <sys/ioctl.h>
#include <sys/types.h>
#include <sys/asoundlib.h>
#include <gtk/gtk.h>
/* 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 */
/*****************************************************************************/

0
xamixer2/options.c Normal file
View file

0
xamixer2/options.h Normal file
View file

158
xamixer2/structs.h Normal file
View file

@ -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

0
xamixer2/switches.c Normal file
View file

0
xamixer2/switches.h Normal file
View file

31
xamixer2/test.c Normal file
View file

@ -0,0 +1,31 @@
#include <gtk/gtk.h>
#include <stdlib.h>
#include <stdio.h>
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;
}

11
xamixer2/test1.c Normal file
View file

@ -0,0 +1,11 @@
#include <stdio.h>
main()
{
printf("The value is %i\n", ~(1 << 1));
return 0;
}

173
xamixer2/util.c Normal file
View file

@ -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;
}

38
xamixer2/util.h Normal file
View file

@ -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 */
/*****************************************************************************/

47
xamixer2/xamixer.conf Normal file
View file

@ -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]

47
xamixer2/xamixer.home Normal file
View file

@ -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]

188
xamixer2/xamixer2.c Normal file
View file

@ -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;
}

24
xamixer2/xamixer2.h Normal file
View file

@ -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 */
/*****************************************************************************/