From f331064eae676b1352d91cc7db1ad87acea63975 Mon Sep 17 00:00:00 2001 From: Wade Berrier Date: Tue, 12 Jun 2012 22:21:21 -0600 Subject: [PATCH] Add AlsaMixer.app to repository http://dockapps.windowmaker.org/file.php/id/253 shows a version available from http://www.stud.fit.vutbr.cz/~xhlavk00/AlsaMixer.app/ but it's a dead link. Check in the version from http://dockapps.windowmaker.org/download.php/id/517/AlsaMixer.app-0.1.tar.gz Untarred and removed version from directory. No other changes. Signed-off-by: Wade Berrier --- AlsaMixer.app/AMixer/AChannel.cc | 41 ++ AlsaMixer.app/AMixer/AChannel.h | 28 + AlsaMixer.app/AMixer/AItem.cc | 87 ++++ AlsaMixer.app/AMixer/AItem.h | 39 ++ AlsaMixer.app/AMixer/AMixer.cc | 203 ++++++++ AlsaMixer.app/AMixer/AMixer.h | 42 ++ AlsaMixer.app/AlsaMixer.app.spec | 42 ++ AlsaMixer.app/COPYING | 340 ++++++++++++ AlsaMixer.app/INSTALL | 33 ++ AlsaMixer.app/Main.cc | 31 ++ AlsaMixer.app/Makefile | 35 ++ AlsaMixer.app/Mixer.cc | 598 ++++++++++++++++++++++ AlsaMixer.app/Mixer.h | 88 ++++ AlsaMixer.app/README | 80 +++ AlsaMixer.app/Xpm.cc | 107 ++++ AlsaMixer.app/Xpm.h | 44 ++ AlsaMixer.app/olddoc/ChangeLog.Mixer.app | 95 ++++ AlsaMixer.app/olddoc/INSTALL.Mixer.app | 33 ++ AlsaMixer.app/olddoc/README.Mixer.app | 75 +++ AlsaMixer.app/pixmaps | 1 + AlsaMixer.app/skins/barross@web.de/button.xpm | 47 ++ AlsaMixer.app/skins/barross@web.de/main.xpm | 167 ++++++ AlsaMixer.app/skins/barross@web.de/mutebutton.xpm | 64 +++ AlsaMixer.app/skins/barross@web.de/redlight.xpm | 7 + AlsaMixer.app/skins/default/button.xpm | 29 ++ AlsaMixer.app/skins/default/main.xpm | 261 ++++++++++ AlsaMixer.app/skins/default/mutebutton.xpm | 30 ++ AlsaMixer.app/skins/default/redlight.xpm | 7 + 28 files changed, 2654 insertions(+) create mode 100644 AlsaMixer.app/AMixer/AChannel.cc create mode 100644 AlsaMixer.app/AMixer/AChannel.h create mode 100644 AlsaMixer.app/AMixer/AItem.cc create mode 100644 AlsaMixer.app/AMixer/AItem.h create mode 100644 AlsaMixer.app/AMixer/AMixer.cc create mode 100644 AlsaMixer.app/AMixer/AMixer.h create mode 100644 AlsaMixer.app/AlsaMixer.app.spec create mode 100644 AlsaMixer.app/COPYING create mode 100644 AlsaMixer.app/INSTALL create mode 100644 AlsaMixer.app/Main.cc create mode 100644 AlsaMixer.app/Makefile create mode 100644 AlsaMixer.app/Mixer.cc create mode 100644 AlsaMixer.app/Mixer.h create mode 100644 AlsaMixer.app/README create mode 100644 AlsaMixer.app/Xpm.cc create mode 100644 AlsaMixer.app/Xpm.h create mode 100644 AlsaMixer.app/olddoc/ChangeLog.Mixer.app create mode 100644 AlsaMixer.app/olddoc/INSTALL.Mixer.app create mode 100644 AlsaMixer.app/olddoc/README.Mixer.app create mode 120000 AlsaMixer.app/pixmaps create mode 100644 AlsaMixer.app/skins/barross@web.de/button.xpm create mode 100644 AlsaMixer.app/skins/barross@web.de/main.xpm create mode 100644 AlsaMixer.app/skins/barross@web.de/mutebutton.xpm create mode 100644 AlsaMixer.app/skins/barross@web.de/redlight.xpm create mode 100644 AlsaMixer.app/skins/default/button.xpm create mode 100644 AlsaMixer.app/skins/default/main.xpm create mode 100644 AlsaMixer.app/skins/default/mutebutton.xpm create mode 100644 AlsaMixer.app/skins/default/redlight.xpm diff --git a/AlsaMixer.app/AMixer/AChannel.cc b/AlsaMixer.app/AMixer/AChannel.cc new file mode 100644 index 0000000..b0e55bb --- /dev/null +++ b/AlsaMixer.app/AMixer/AChannel.cc @@ -0,0 +1,41 @@ +// AChannel.cc, Petr Hlavka, 2004 + +#include "AMixer.h" +#include "AItem.h" +#include "AChannel.h" + +#include + + +AChannel::AChannel(AItem *item, SNDCHID_T cID) { + aItem = item; + id = cID; +} + + +AChannel::~AChannel() { +} + + +long AChannel::getVolume() { + long vol = 0; + + snd_mixer_selem_get_playback_volume(aItem->aElem, (SNDCHID_T) id, &vol); + + return (vol); +} + + +// it isn't necessery when using snd_mixer_selem_set_x_volume_all +void AChannel::setVolume(long value) { + std::cerr << "AChannel::setVolume not implemented!" << std::endl; +} + + +bool AChannel::isMuted() { + int val; + + snd_mixer_selem_get_playback_switch(aItem->aElem, (SNDCHID_T) id, &val); + + return (! (bool) val); +} diff --git a/AlsaMixer.app/AMixer/AChannel.h b/AlsaMixer.app/AMixer/AChannel.h new file mode 100644 index 0000000..57ad075 --- /dev/null +++ b/AlsaMixer.app/AMixer/AChannel.h @@ -0,0 +1,28 @@ +// AChannel.h, Petr Hlavka, 2004 + +#ifndef ACHANNEL_H +#define ACHANNEL_H + +#include "AMixer.h" +#include "AItem.h" + +#include + +#define SNDCHID_T snd_mixer_selem_channel_id_t + +class AItem; + +class AChannel { + private: + SNDCHID_T id; // channel id (front left, f. right, ...) + AItem *aItem; // parent mixer item + public: + AChannel(AItem *item, SNDCHID_T cID); // ctor + ~AChannel(); // dtor + + long getVolume(); // get channel volume + void setVolume(long value); // set channel volume + bool isMuted(); // return true, if channel is muted +}; + +#endif diff --git a/AlsaMixer.app/AMixer/AItem.cc b/AlsaMixer.app/AMixer/AItem.cc new file mode 100644 index 0000000..7272268 --- /dev/null +++ b/AlsaMixer.app/AMixer/AItem.cc @@ -0,0 +1,87 @@ +// AItem.cc, Petr Hlavka, 2004 + +#include "AItem.h" +#include "AMixer.h" + +#include +#include + +#define ROUND_POS(x) (long ((long (x) + 0.5 > (x)) ? (x) : (x) + 1)) + + +// load only playback channels, don't care about common items +AItem::AItem(AMixer *m, snd_mixer_elem_t *e) { + mixer = m; + aElem = e; + + name = snd_mixer_selem_get_name(aElem); + + hPVolume = snd_mixer_selem_has_playback_volume(aElem); + hPSwitch = snd_mixer_selem_has_playback_switch(aElem); + + if (hPVolume) + snd_mixer_selem_get_playback_volume_range(aElem, &minPVolume, &maxPVolume); + else + minPVolume = maxPVolume = 0; + + for (int channel = 0; channel <= (int) SND_MIXER_SCHN_LAST; channel++) { + if (snd_mixer_selem_has_playback_channel(aElem, (SNDCHID_T) channel)) { + AChannel *ch = new AChannel(this, (SNDCHID_T) channel); + pbChannels.push_back(ch); + } + } +} + + +AItem::~AItem() { + for (unsigned int i = 0; i < pbChannels.size(); i++) + delete pbChannels[i]; +} + + +// set same volume for all channels in this item in percent +void AItem::setVolumePerc(unsigned int percent) { + if (percent > 100) + percent = 100; + + snd_mixer_selem_set_playback_volume_all(aElem, (long) ROUND_POS((minPVolume + (maxPVolume - minPVolume) * percent / 100.0))); +} + + +// get max channel volume of all channels in this item in percent +unsigned int AItem::getVolumePerc() { + long max_vol = 0, act_vol; + + // find the max volume + for (unsigned int i = 0; i < pbChannels.size(); i++) + if ((act_vol = pbChannels[i]->getVolume()) > max_vol) + max_vol = act_vol; + + // convert it into percent + if (minPVolume != maxPVolume) + return ((unsigned int) ROUND_POS((max_vol - minPVolume) * 100.0 / (maxPVolume - minPVolume))); + else + return (0); +} + + +// in this app side of view, item is muted if all channels is muted +bool AItem::isMuted() { + for (unsigned int i = 0; i < pbChannels.size(); i++) + if (!pbChannels[i]->isMuted()) + return (false); + + return (true); +} + + +// mute all channels +void AItem::mute() { + snd_mixer_selem_set_playback_switch_all(aElem, false); +} + + +// unmute all channels +void AItem::unmute() { + snd_mixer_selem_set_playback_switch_all(aElem, true); +} diff --git a/AlsaMixer.app/AMixer/AItem.h b/AlsaMixer.app/AMixer/AItem.h new file mode 100644 index 0000000..0f4f71a --- /dev/null +++ b/AlsaMixer.app/AMixer/AItem.h @@ -0,0 +1,39 @@ +// AItem.h, Petr Hlavka, 2004 + +#ifndef AITEM_H +#define AITEM_H + +#include "AMixer.h" +#include "AChannel.h" + +#include +#include + + +class AChannel; +class AMixer; + +class AItem { + private: + AMixer *mixer; // parent mixer + std::vector pbChannels; // item channels + + long minPVolume, maxPVolume; // min/max playback volume + bool hPVolume; // has Playback volume + bool hPSwitch; // has Playback switch + + public: + snd_mixer_elem_t *aElem; // mixer item element + const char *name; // item name + + AItem(AMixer *m, snd_mixer_elem_t *e); // ctor + ~AItem(); // dtor + + void setVolumePerc(unsigned int percent); + unsigned int getVolumePerc(); + bool isMuted(); + void mute(); + void unmute(); +}; + +#endif diff --git a/AlsaMixer.app/AMixer/AMixer.cc b/AlsaMixer.app/AMixer/AMixer.cc new file mode 100644 index 0000000..dbf9002 --- /dev/null +++ b/AlsaMixer.app/AMixer/AMixer.cc @@ -0,0 +1,203 @@ +// AMixer.cc, Petr Hlavka, 2004 + +#include "AMixer.h" +#include "AItem.h" + +#include +#include +#include +#include + +static bool mixerChangeIndicator = false; +static bool mixerReinitIndicator = false; +static int mixerCallback(snd_mixer_t *ctl, unsigned int mask, + snd_mixer_elem_t *elem); +static int itemCallback(snd_mixer_elem_t *elem, unsigned int mask); + + +AMixer::AMixer(const char *card) { + int err; + + if (card) { + cardName = new char[std::strlen(card)]; + std::strcpy(cardName, card); + for (int i = 0; i < MIXER_ITEMS; i++) + mixerItems[i] = NULL; + + if ((err = snd_mixer_open(&mixerHandle, 0)) < 0) { + error("snd_mixer_open error", err); + mixerHandle = NULL; + + return; + } + if ((err = snd_mixer_attach(mixerHandle, card)) < 0) { + error("snd_mixer_attach error", err); + snd_mixer_close(mixerHandle); + mixerHandle = NULL; + + return; + } + if ((err = snd_mixer_selem_register(mixerHandle, NULL, NULL)) < 0) { + error("snd_mixer_selem_register error", err); + snd_mixer_close(mixerHandle); + mixerHandle = NULL; + + return; + } + if ((err = snd_mixer_load(mixerHandle)) < 0) { + error("snd_mixer_load error", err); + snd_mixer_close(mixerHandle); + mixerHandle = NULL; + + return; + } + + snd_mixer_set_callback(mixerHandle, (snd_mixer_callback_t) &mixerCallback); + } +} + + +AMixer::~AMixer() { + if (mixerHandle) { + snd_mixer_free(mixerHandle); + snd_mixer_detach(mixerHandle, cardName); + delete[] cardName; + snd_mixer_close(mixerHandle); + } +} + + +bool AMixer::opened() { + return (mixerHandle != NULL); +} + + +void AMixer::error(const char *errorString, int errorCode) { + std::cerr << cardName << ": " << errorString << ": " << snd_strerror(errorCode) << std::endl; +} + + +void AMixer::handleEvents() { + snd_mixer_handle_events(mixerHandle); +} + + +AItem *AMixer::attachItem(unsigned int itemNumber, const char *itemName) { + if (itemNumber >= MIXER_ITEMS || !itemName) + return (NULL); + + // item was already created, so deregister callback and free it first + if (mixerItems[itemNumber]) { + snd_mixer_elem_set_callback(mixerItems[itemNumber]->aElem, NULL); + delete mixerItems[itemNumber]; + } + + // try to find item by name, register callback, return success + snd_mixer_elem_t *elem; + for (elem = snd_mixer_first_elem(mixerHandle); elem; elem = snd_mixer_elem_next(elem)) { + if (snd_mixer_selem_is_active(elem) && + snd_mixer_elem_get_type(elem) == SND_MIXER_ELEM_SIMPLE && + std::strcmp(snd_mixer_selem_get_name(elem), itemName) == 0) { + snd_mixer_elem_set_callback(elem, (snd_mixer_elem_callback_t) &itemCallback); + return (mixerItems[itemNumber] = new AItem(this, elem)); + } + } + + return (NULL); +} + + +bool AMixer::itemOK(unsigned int itemNumber) { + return (itemNumber < MIXER_ITEMS && mixerItems[itemNumber]); +} + + +int AMixer::itemGetVolume(unsigned int itemNumber) { + if (itemNumber >= MIXER_ITEMS || !mixerItems[itemNumber]) + return (-1); + + return ((int) mixerItems[itemNumber]->getVolumePerc()); +} + + +void AMixer::itemSetVolume(unsigned int itemNumber, unsigned int volume) { + if (itemNumber < MIXER_ITEMS && mixerItems[itemNumber]) + mixerItems[itemNumber]->setVolumePerc(volume); +} + + +int AMixer::itemIsMuted(unsigned int itemNumber) { + if (itemNumber >= MIXER_ITEMS || !mixerItems[itemNumber]) + return (-1); + + return ((bool) mixerItems[itemNumber]->isMuted()); +} + + +void AMixer::itemToggleMute(unsigned int itemNumber) { + if (itemNumber < MIXER_ITEMS && mixerItems[itemNumber]) { + if (itemIsMuted(itemNumber)) + mixerItems[itemNumber]->unmute(); + else + mixerItems[itemNumber]->mute(); + } +} + + +// return true if mixer elm sent callback and this callback wasn't picked up yet +bool AMixer::mixerElemsChanged() { + if (mixerChangeIndicator) { + mixerChangeIndicator = false; + + return (true); + } + else + return (false); +} + + +// return true if mixer sent callback and this callback wasn't picked up yet +bool AMixer::mixerChanged() { + if (mixerReinitIndicator) { + mixerReinitIndicator = false; + + return (true); + } + else + return (false); +} + + +// this function should be called after mixer callback, reInit all items +void AMixer::reInit() { + for (int i = 0; i < MIXER_ITEMS; i++) + this->attachItem(i, mixerItems[i]->name); +} + + +int mixerCallback(snd_mixer_t *ctl, unsigned int mask, + snd_mixer_elem_t *elem) { + mixerReinitIndicator = true; + + return (0); +} + + +int itemCallback(snd_mixer_elem_t *elem, unsigned int mask) { + mixerChangeIndicator = true; + + return (0); +} + + +char* AMixer::convertIDToCard(const char* cardId) { + static char card[32] = ""; + int i = snd_card_get_index(cardId); + + if (i >= 0 && i < 32) + std::snprintf(card, 32, "hw:%i", i); + else + return (NULL); + + return (card); +} diff --git a/AlsaMixer.app/AMixer/AMixer.h b/AlsaMixer.app/AMixer/AMixer.h new file mode 100644 index 0000000..16c2960 --- /dev/null +++ b/AlsaMixer.app/AMixer/AMixer.h @@ -0,0 +1,42 @@ +// AMixer.h, Petr Hlavka, 2004 + +#ifndef AMIXER_H +#define AMIXER_H + +#include "AItem.h" + +#include + +#define MIXER_ITEMS 3 + + +class AItem; + +class AMixer { + private: + snd_mixer_t *mixerHandle; + AItem *mixerItems[MIXER_ITEMS]; + char *cardName; + + void error(const char *errorString, int errorCode); + + public: + AMixer(const char *card); // ctor + ~AMixer(); // dtor + + bool opened(); + void handleEvents(); + AItem *attachItem(unsigned int itemNumber, const char *itemName); + bool itemOK(unsigned int itemNumber); + int itemGetVolume(unsigned int itemNumber); + void itemSetVolume(unsigned int itemNumber, unsigned int volume); + int itemIsMuted(unsigned int itemNumber); + void itemToggleMute(unsigned int itemNumber); + void reInit(); + + static bool mixerElemsChanged(); + static bool mixerChanged(); + static char* convertIDToCard(const char* cardId); +}; + +#endif diff --git a/AlsaMixer.app/AlsaMixer.app.spec b/AlsaMixer.app/AlsaMixer.app.spec new file mode 100644 index 0000000..41b0aa0 --- /dev/null +++ b/AlsaMixer.app/AlsaMixer.app.spec @@ -0,0 +1,42 @@ +%define prefix /usr/local + +Summary: dockable mixer for ALSA driver and Window Maker +Name: AlsaMixer.app +Version: 0.1 +Release: 1 +Source0: %{name}-%{version}.tar.gz +License: GPL +Group: X11/Utilities +BuildRoot: %{_tmppath}/%{name}-root +Packager: Petr Hlavka +Requires: XFree86-devel, libXpm-devel +URL: http://www.stud.fit.vutbr.cz/~xhlavk00/AlsaMixer.app/ + +%description +AlsaMixer.app is simple dockable mixer application for WindowMaker. It can +control up to three volume sources, load/store mixer settings, run external +application on middle click (i.e. more sophisticated mixer) + +%prep +%setup -q + +%build +make + +%install +rm -rf $RPM_BUILD_ROOT +mkdir -p -m 0755 $RPM_BUILD_ROOT%{prefix}/bin +cp -f AlsaMixer.app $RPM_BUILD_ROOT%{prefix}/bin + + +%clean +if [ -d $RPM_BUILD_ROOT ]; then rm -rf $RPM_BUILD_ROOT; fi +if [ -d $RPM_BUILD_DIR/%{name}-%{version} ]; then rm -rf $RPM_BUILD_DIR/%{name}-%{version}; fi + +%files +%defattr(-,root,root) +%attr(0755,root,root) %{prefix}/bin/AlsaMixer.app + +%changelog +* Tue Sep 30 2004 Petr Hlavka +- initial release diff --git a/AlsaMixer.app/COPYING b/AlsaMixer.app/COPYING new file mode 100644 index 0000000..96e4591 --- /dev/null +++ b/AlsaMixer.app/COPYING @@ -0,0 +1,340 @@ + 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. + + GNU GENERAL PUBLIC LICENSE + TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION + + 0. This License applies to any program or other work which contains +a notice placed by the copyright holder saying it may be distributed +under the terms of this General Public License. The "Program", below, +refers to any such program or work, and a "work based on the Program" +means either the Program or any derivative work under copyright law: +that is to say, a work containing the Program or a portion of it, +either verbatim or with modifications and/or translated into another +language. (Hereinafter, translation is included without limitation in +the term "modification".) Each licensee is addressed as "you". + +Activities other than copying, distribution and modification are not +covered by this License; they are outside its scope. The act of +running the Program is not restricted, and the output from the Program +is covered only if its contents constitute a work based on the +Program (independent of having been made by running the Program). +Whether that is true depends on what the Program does. + + 1. You may copy and distribute verbatim copies of the Program's +source code as you receive it, in any medium, provided that you +conspicuously and appropriately publish on each copy an appropriate +copyright notice and disclaimer of warranty; keep intact all the +notices that refer to this License and to the absence of any warranty; +and give any other recipients of the Program a copy of this License +along with the Program. + +You may charge a fee for the physical act of transferring a copy, and +you may at your option offer warranty protection in exchange for a fee. + + 2. You may modify your copy or copies of the Program or any portion +of it, thus forming a work based on the Program, and copy and +distribute such modifications or work under the terms of Section 1 +above, provided that you also meet all of these conditions: + + a) You must cause the modified files to carry prominent notices + stating that you changed the files and the date of any change. + + b) You must cause any work that you distribute or publish, that in + whole or in part contains or is derived from the Program or any + part thereof, to be licensed as a whole at no charge to all third + parties under the terms of this License. + + c) If the modified program normally reads commands interactively + when run, you must cause it, when started running for such + interactive use in the most ordinary way, to print or display an + announcement including an appropriate copyright notice and a + notice that there is no warranty (or else, saying that you provide + a warranty) and that users may redistribute the program under + these conditions, and telling the user how to view a copy of this + License. (Exception: if the Program itself is interactive but + does not normally print such an announcement, your work based on + the Program is not required to print an announcement.) + +These requirements apply to the modified work as a whole. If +identifiable sections of that work are not derived from the Program, +and can be reasonably considered independent and separate works in +themselves, then this License, and its terms, do not apply to those +sections when you distribute them as separate works. But when you +distribute the same sections as part of a whole which is a work based +on the Program, the distribution of the whole must be on the terms of +this License, whose permissions for other licensees extend to the +entire whole, and thus to each and every part regardless of who wrote it. + +Thus, it is not the intent of this section to claim rights or contest +your rights to work written entirely by you; rather, the intent is to +exercise the right to control the distribution of derivative or +collective works based on the Program. + +In addition, mere aggregation of another work not based on the Program +with the Program (or with a work based on the Program) on a volume of +a storage or distribution medium does not bring the other work under +the scope of this License. + + 3. You may copy and distribute the Program (or a work based on it, +under Section 2) in object code or executable form under the terms of +Sections 1 and 2 above provided that you also do one of the following: + + a) Accompany it with the complete corresponding machine-readable + source code, which must be distributed under the terms of Sections + 1 and 2 above on a medium customarily used for software interchange; or, + + b) Accompany it with a written offer, valid for at least three + years, to give any third party, for a charge no more than your + cost of physically performing source distribution, a complete + machine-readable copy of the corresponding source code, to be + distributed under the terms of Sections 1 and 2 above on a medium + customarily used for software interchange; or, + + c) Accompany it with the information you received as to the offer + to distribute corresponding source code. (This alternative is + allowed only for noncommercial distribution and only if you + received the program in object code or executable form with such + an offer, in accord with Subsection b above.) + +The source code for a work means the preferred form of the work for +making modifications to it. For an executable work, complete source +code means all the source code for all modules it contains, plus any +associated interface definition files, plus the scripts used to +control compilation and installation of the executable. However, as a +special exception, the source code distributed need not include +anything that is normally distributed (in either source or binary +form) with the major components (compiler, kernel, and so on) of the +operating system on which the executable runs, unless that component +itself accompanies the executable. + +If distribution of executable or object code is made by offering +access to copy from a designated place, then offering equivalent +access to copy the source code from the same place counts as +distribution of the source code, even though third parties are not +compelled to copy the source along with the object code. + + 4. You may not copy, modify, sublicense, or distribute the Program +except as expressly provided under this License. Any attempt +otherwise to copy, modify, sublicense or distribute the Program is +void, and will automatically terminate your rights under this License. +However, parties who have received copies, or rights, from you under +this License will not have their licenses terminated so long as such +parties remain in full compliance. + + 5. You are not required to accept this License, since you have not +signed it. However, nothing else grants you permission to modify or +distribute the Program or its derivative works. These actions are +prohibited by law if you do not accept this License. Therefore, by +modifying or distributing the Program (or any work based on the +Program), you indicate your acceptance of this License to do so, and +all its terms and conditions for copying, distributing or modifying +the Program or works based on it. + + 6. Each time you redistribute the Program (or any work based on the +Program), the recipient automatically receives a license from the +original licensor to copy, distribute or modify the Program subject to +these terms and conditions. You may not impose any further +restrictions on the recipients' exercise of the rights granted herein. +You are not responsible for enforcing compliance by third parties to +this License. + + 7. If, as a consequence of a court judgment or allegation of patent +infringement or for any other reason (not limited to patent issues), +conditions are imposed on you (whether by court order, agreement or +otherwise) that contradict the conditions of this License, they do not +excuse you from the conditions of this License. If you cannot +distribute so as to satisfy simultaneously your obligations under this +License and any other pertinent obligations, then as a consequence you +may not distribute the Program at all. For example, if a patent +license would not permit royalty-free redistribution of the Program by +all those who receive copies directly or indirectly through you, then +the only way you could satisfy both it and this License would be to +refrain entirely from distribution of the Program. + +If any portion of this section is held invalid or unenforceable under +any particular circumstance, the balance of the section is intended to +apply and the section as a whole is intended to apply in other +circumstances. + +It is not the purpose of this section to induce you to infringe any +patents or other property right claims or to contest validity of any +such claims; this section has the sole purpose of protecting the +integrity of the free software distribution system, which is +implemented by public license practices. Many people have made +generous contributions to the wide range of software distributed +through that system in reliance on consistent application of that +system; it is up to the author/donor to decide if he or she is willing +to distribute software through any other system and a licensee cannot +impose that choice. + +This section is intended to make thoroughly clear what is believed to +be a consequence of the rest of this License. + + 8. If the distribution and/or use of the Program is restricted in +certain countries either by patents or by copyrighted interfaces, the +original copyright holder who places the Program under this License +may add an explicit geographical distribution limitation excluding +those countries, so that distribution is permitted only in or among +countries not thus excluded. In such case, this License incorporates +the limitation as if written in the body of this License. + + 9. The Free Software Foundation may publish revised and/or new versions +of the General Public License from time to time. Such new versions will +be similar in spirit to the present version, but may differ in detail to +address new problems or concerns. + +Each version is given a distinguishing version number. If the Program +specifies a version number of this License which applies to it and "any +later version", you have the option of following the terms and conditions +either of that version or of any later version published by the Free +Software Foundation. If the Program does not specify a version number of +this License, you may choose any version ever published by the Free Software +Foundation. + + 10. If you wish to incorporate parts of the Program into other free +programs whose distribution conditions are different, write to the author +to ask for permission. For software which is copyrighted by the Free +Software Foundation, write to the Free Software Foundation; we sometimes +make exceptions for this. Our decision will be guided by the two goals +of preserving the free status of all derivatives of our free software and +of promoting the sharing and reuse of software generally. + + NO WARRANTY + + 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY +FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN +OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES +PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED +OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF +MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS +TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE +PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, +REPAIR OR CORRECTION. + + 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING +WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR +REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, +INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING +OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED +TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY +YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER +PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE +POSSIBILITY OF SUCH DAMAGES. + + END OF TERMS AND CONDITIONS + + Appendix: How to Apply These Terms to Your New Programs + + If you develop a new program, and you want it to be of the greatest +possible use to the public, the best way to achieve this is to make it +free software which everyone can redistribute and change under these terms. + + To do so, attach the following notices to the program. It is safest +to attach them to the start of each source file to most effectively +convey the exclusion of warranty; and each file should have at least +the "copyright" line and a pointer to where the full notice is found. + + + Copyright (C) 19yy + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + +Also add information on how to contact you by electronic and paper mail. + +If the program is interactive, make it output a short notice like this +when it starts in an interactive mode: + + Gnomovision version 69, Copyright (C) 19yy name of author + Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'. + This is free software, and you are welcome to redistribute it + under certain conditions; type `show c' for details. + +The hypothetical commands `show w' and `show c' should show the appropriate +parts of the General Public License. Of course, the commands you use may +be called something other than `show w' and `show c'; they could even be +mouse-clicks or menu items--whatever suits your program. + +You should also get your employer (if you work as a programmer) or your +school, if any, to sign a "copyright disclaimer" for the program, if +necessary. Here is a sample; alter the names: + + Yoyodyne, Inc., hereby disclaims all copyright interest in the program + `Gnomovision' (which makes passes at compilers) written by James Hacker. + + , 1 April 1989 + Ty Coon, President of Vice + +This General Public License does not permit incorporating your program into +proprietary programs. If your program is a subroutine library, you may +consider it more useful to permit linking proprietary applications with the +library. If this is what you want to do, use the GNU Library General +Public License instead of this License. diff --git a/AlsaMixer.app/INSTALL b/AlsaMixer.app/INSTALL new file mode 100644 index 0000000..e9e04ca --- /dev/null +++ b/AlsaMixer.app/INSTALL @@ -0,0 +1,33 @@ +Installation instructions for AlsaMixer.app + + +Requirements +------------------------------------------------------------------- +- X11, libxpm (devel version of both), C++ development environment + Most (Linux) systems have these things installed by default. + If you don't have it look for packages that fit your + distribution (especially somelib-devel packages). + + +Installation +------------------------------------------------------------------- +1) make +2) su +3) make install (to put it in /usr/local/GNUstep/Apps/AlsaMixer.app) + or + make install-x11 (to put it in /usr/X11R6/bin) +5) exit + + +Running +------------------------------------------------------------------- +To run this program: +/usr/local/GNUstep/Apps/AlsaMixer.app/AlsaMixer & +or +/usr/X11R6/bin/AlsaMixer.app & + + +For more information about available command line arguments: +/usr/local/GNUstep/Apps/Mixer.app/AlsaMixer --help +or +/usr/X11R6/bin/AlsaMixer.app --help diff --git a/AlsaMixer.app/Main.cc b/AlsaMixer.app/Main.cc new file mode 100644 index 0000000..e3b5fd7 --- /dev/null +++ b/AlsaMixer.app/Main.cc @@ -0,0 +1,31 @@ +// +// Mixer.app +// +// Copyright (c) 1998-2002 Per Liden +// +// 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. +// + +#include "Mixer.h" + +Mixer* app; + +int main(int argc, char** argv) +{ + app = new Mixer(argc, argv); + app->run(); + return 0; +} diff --git a/AlsaMixer.app/Makefile b/AlsaMixer.app/Makefile new file mode 100644 index 0000000..14f510c --- /dev/null +++ b/AlsaMixer.app/Makefile @@ -0,0 +1,35 @@ +# +# Mixer.app Makefile +# + +DESTDIR = +GNUSTEP_BINDIR = /usr/local/GNUstep/Apps/AlsaMixer.app +X11_BINDIR = /usr/X11R6/bin + +CXX=c++ +CXXFLAGS += -Wall -pedantic -fno-rtti -fno-exceptions -O2 -I/usr/X11R6/include +LDFLAGS += -L/usr/X11R6/lib -lXpm -lXext -lX11 -lasound + +OBJECTS = Main.o Mixer.o Xpm.o AMixer/AMixer.o AMixer/AItem.o AMixer/AChannel.o + +all: AlsaMixer.app + +AlsaMixer.app: $(OBJECTS) + $(CXX) $(OBJECTS) -o $@ $(LDFLAGS) + +.PHONY: install clean distclean + +install: install-gnustep + +install-gnustep: all + install -d $(DESTDIR)$(GNUSTEP_BINDIR) + install -m 0755 AlsaMixer.app $(DESTDIR)$(GNUSTEP_BINDIR)/AlsaMixer + +install-x11: all + install -d $(DESTDIR)$(X11_BINDIR) + install -m 0755 AlsaMixer.app $(DESTDIR)$(X11_BINDIR)/AlsaMixer.app + +clean: + rm -f *~ $(OBJECTS) AlsaMixer.app + +# End of file diff --git a/AlsaMixer.app/Mixer.cc b/AlsaMixer.app/Mixer.cc new file mode 100644 index 0000000..11bec7c --- /dev/null +++ b/AlsaMixer.app/Mixer.cc @@ -0,0 +1,598 @@ +// +// Mixer.app +// +// Copyright (c) 1998-2002 Per Liden +// +// 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. +// + +#include +#include +#include +#include +#include +#include +#include "Xpm.h" +#include "Mixer.h" + +#include "AMixer/AMixer.h" + +#include "pixmaps/main.xpm" +#include "pixmaps/button.xpm" +#include "pixmaps/mutebutton.xpm" +#include "pixmaps/redlight.xpm" + +#define ROUND_POS(x) (int ((x) + 0.5) > int (x)) ? (int) ((x) + 1) : (int) (x) + +using namespace std; + +static const int ButtonX[] = {6, 24, 42}; +static const char* MixerSources[] = { "Master", "PCM", "CD" }; + +extern Mixer* app; + +void catchBrokenPipe(int sig) +{ + app->saveVolumeSettings(); + exit(0); +} + +int positionToPercent(int position) { + return ROUND_POS(100 - (((position - BUTTON_MAX) * 100.0) / (BUTTON_MIN - BUTTON_MAX))); +} + +int percentToPosition(int percent) { + return ROUND_POS(BUTTON_MIN - (percent * (BUTTON_MIN - BUTTON_MAX)) / 100.0); +} + +Mixer::Mixer(int argc, char** argv) +{ + XClassHint classHint; + XSizeHints sizeHints; + XWMHints wmHints; + Atom deleteWindow; + Xpm* image; + char* displayName = NULL; + char* card = "default"; + + mError = 0; + mInstanceName = INSTANCENAME; + mVolumeSource[0] = -1; + mVolumeSource[1] = -1; + mVolumeSource[2] = -1; + mVolumeMute[0] = 0; + mVolumeMute[1] = 0; + mVolumeMute[2] = 0; + mWheelButton = 1; + mLabelText = 0; + mSettingsFile = 0; + mSaveSettings = false; + mLoadSettings = false; + mCommand = NULL; + + // Parse command line + if (argc>1) { + for (int i=1; i 3) { + cerr << APPNAME << ": invalid wheel binding, must be 1, 2 or 3, not " << argv[i+1] << endl; + tryHelp(argv[0]); + exit(0); + } + + i++; + } + + // Label text + else if (!strcmp(argv[i], "-l")) { + checkArgument(argv, argc, i); + mLabelText = argv[i+1]; + i++; + } + + // Save settings on exit + else if (!strcmp(argv[i], "-S")) { + mSaveSettings = true; + } + + // Load settings on startup + else if (!strcmp(argv[i], "-L")) { + mLoadSettings = true; + } + + // Load/Save settings file + else if (!strcmp(argv[i], "-f")) { + checkArgument(argv, argc, i); + mSettingsFile = argv[i+1]; + i++; + } + + // Execute command on middle click + else if (!strcmp(argv[i], "-e")) { + checkArgument(argv, argc, i); + mCommand = argv[i + 1]; + i++; + } + + // Instance name + else if (!strcmp(argv[i], "-n")) { + checkArgument(argv, argc, i); + mInstanceName = argv[i+1]; + i++; + } + + // Version + else if (!strcmp(argv[i], "-v")) { + cerr << APPNAME << " version " << VERSION << endl; + exit(0); + } + + // Help + else if (!strcmp(argv[i], "-h") || !strcmp(argv[i], "--help")) { + showHelp(); + exit(0); + } + + // card + else if (!strcmp(argv[i], "--card")) { + card = AMixer::convertIDToCard(argv[i + 1]); + if (!card) { + cerr << APPNAME << ": invalid card number '" << argv[i + 1] << "'" << endl; + tryHelp(argv[0]); + exit(0); + } + i++; + } + + // device + else if (!strcmp(argv[i], "--device")) { + card = argv[i + 1]; + i++; + } + + // Unknown option + else { + cerr << APPNAME << ": invalid option '" << argv[i] << "'" << endl; + tryHelp(argv[0]); + exit(0); + } + } + } + + // default settings file + if (!mSettingsFile) { + char* home = getenv("HOME"); + if (home) { + mSettingsFile = new char[strlen(home) + strlen(SETTINGS) + 1]; + strcpy(mSettingsFile, home); + strcat(mSettingsFile, SETTINGS); + } else { + cerr << APPNAME << ": $HOME not set, could not find saved settings" << endl; + } + } + + // init mixer + aMixer = new AMixer(card); + if (!aMixer->opened()) { + cerr << APPNAME << ": could not open mixer device for card '" << card << "'" << endl; + exit(0); + } + + // open mixer sources + for (int i = 0; i < 3; i++) { + aMixer->attachItem(i, MixerSources[i]); + if (!aMixer->itemOK(i)) + cerr << APPNAME << ": could not select mixer source '" << MixerSources[i] << "'" << endl; + } + + // Open display + if ((mDisplay = XOpenDisplay(displayName)) == NULL) { + cerr << APPNAME << ": could not open display " << displayName << endl; + exit(0); + } + + // Get root window + mRoot = RootWindow(mDisplay, DefaultScreen(mDisplay)); + + // Create windows + mAppWin = XCreateSimpleWindow(mDisplay, mRoot, 1, 1, 64, 64, 0, 0, 0); + mIconWin = XCreateSimpleWindow(mDisplay, mAppWin, 0, 0, 64, 64, 0, 0, 0); + + // Set classhint + classHint.res_name = mInstanceName; + classHint.res_class = CLASSNAME; + XSetClassHint(mDisplay, mAppWin, &classHint); + + // Create delete atom + deleteWindow = XInternAtom(mDisplay, "WM_DELETE_WINDOW", False); + XSetWMProtocols(mDisplay, mAppWin, &deleteWindow, 1); + XSetWMProtocols(mDisplay, mIconWin, &deleteWindow, 1); + + // Set windowname + XStoreName(mDisplay, mAppWin, APPNAME); + XSetIconName(mDisplay, mAppWin, APPNAME); + + // Set sizehints + sizeHints.flags= USPosition; + sizeHints.x = 0; + sizeHints.y = 0; + XSetWMNormalHints(mDisplay, mAppWin, &sizeHints); + + // Set wmhints + wmHints.initial_state = WithdrawnState; + wmHints.icon_window = mIconWin; + wmHints.icon_x = 0; + wmHints.icon_y = 0; + wmHints.window_group = mAppWin; + wmHints.flags = StateHint | IconWindowHint | IconPositionHint | WindowGroupHint; + XSetWMHints(mDisplay, mAppWin, &wmHints); + + // Set command + XSetCommand(mDisplay, mAppWin, argv, argc); + + // Set background image + image = new Xpm(mDisplay, mRoot, main_xpm); + if (mLabelText) { + image->drawString(LABEL_X, LABEL_Y, mLabelText); + } + image->setWindowPixmapShaped(mIconWin); + delete image; + + // Create buttons + mButton[0] = XCreateSimpleWindow(mDisplay, mIconWin, ButtonX[0], BUTTON_MIN, 5, 5, 0, 0, 0); + mButton[1] = XCreateSimpleWindow(mDisplay, mIconWin, ButtonX[1], BUTTON_MIN, 5, 5, 0, 0, 0); + mButton[2] = XCreateSimpleWindow(mDisplay, mIconWin, ButtonX[2], BUTTON_MIN, 5, 5, 0, 0, 0); + + image = new Xpm(mDisplay, mRoot, button_xpm); + image->setWindowPixmap(mButton[0]); + image->setWindowPixmap(mButton[1]); + image->setWindowPixmap(mButton[2]); + delete image; + + XSelectInput(mDisplay, mButton[0], ButtonPressMask | ButtonReleaseMask | PointerMotionMask); + XSelectInput(mDisplay, mButton[1], ButtonPressMask | ButtonReleaseMask | PointerMotionMask); + XSelectInput(mDisplay, mButton[2], ButtonPressMask | ButtonReleaseMask | PointerMotionMask); + XSelectInput(mDisplay, mIconWin, ButtonPressMask); + + XMapWindow(mDisplay, mButton[0]); + XMapWindow(mDisplay, mButton[1]); + XMapWindow(mDisplay, mButton[2]); + + XMapWindow(mDisplay, mIconWin); + XMapWindow(mDisplay, mAppWin); + XSync(mDisplay, False); + + // Catch broker pipe signal + signal(SIGPIPE, catchBrokenPipe); + + // Check if error + if (mError) { + showErrorLed(); + } else { + getVolume(); + if (mLoadSettings) + loadVolumeSettings(); + } +} + +void Mixer::tryHelp(char* appname) +{ + cerr << "Try `" << appname << " --help' for more information" << endl; +} + +void Mixer::showHelp() +{ + cerr << APPNAME << " Copyright (c) 1998-2002 by Per Liden (per@fukt.bth.se), Petr Hlavka (xhlavk00@stud.fit.vutbr.cz)" << endl << endl + << "options:" << endl + << " -1 set sound source for control 1 (default is Master)" << endl + << " -2 set sound source for control 2 (default is PCM)" << endl + << " -3 set sound source for control 3 (default is CD)" << endl + << " -w 1|2|3 bind a control button to the mouse wheel (default is 1)" << endl + << " -l set label text" << endl + << " -S save volume settings on exit" << endl + << " -L load volume settings on start up" << endl + << " -f use setting instead of ~/GNUstep/Defaults/AlsaMixer" << endl + << " --card select card" << endl + << " --device select device, default 'default'" << endl + << " -e execute on middle click" << endl + << " -n set client instance name" << endl + << " -d set display" << endl + << " -v print version and exit" << endl + << " -h, --help display this help and exit" << endl << endl; +} + +void Mixer::checkArgument(char** argv, int argc, int index) +{ + if (argc-1 < index+1) { + cerr << APPNAME << ": option '" << argv[index] << "' requires an argument" << endl; + tryHelp(argv[0]); + exit(0); + } +} + +void Mixer::showErrorLed() +{ + Window led; + Xpm* image; + + led = XCreateSimpleWindow(mDisplay, mIconWin, LED_X, LED_Y, 3, 2, 0, 0, 0); + + // Set background image + image = new Xpm(mDisplay, mRoot, redlight_xpm); + image->setWindowPixmap(led); + delete image; + + // Show window + XMapWindow(mDisplay, led); + mError = 1; +} + +void Mixer::loadVolumeSettings() +{ + if (mSettingsFile) { + ifstream file(mSettingsFile); + if (file) { + // This could fail if the user has edited the file by hand and destroyed the structure + char dummy[1024]; + file >> dummy; // { + file >> dummy; // Volume1 + file >> dummy; // = + file >> mVolume[0]; + file >> dummy; // ; + + file >> dummy; // Volume2 + file >> dummy; // = + file >> mVolume[1]; + file >> dummy; // ; + + file >> dummy; // Volume3 + file >> dummy; // = + file >> mVolume[2]; + + file.close(); + for (int i = 0; i < 3; i++) { + setVolume(i, mVolume[i]); + setButtonPosition(i, percentToPosition(mVolume[i])); + } + } + } +} + +void Mixer::saveVolumeSettings() +{ + if (mSaveSettings) { + ofstream file(mSettingsFile); + if (file) { + // Files in ~/GNUstep/Defaults/ should follow the property list format + file << "{" << endl + << " Volume1 = " << mVolumePos[0] << ";" << endl + << " Volume2 = " << mVolumePos[1] << ";" << endl + << " Volume3 = " << mVolumePos[2] << ";" << endl + << "}" << endl; + file.close(); + } else { + cerr << APPNAME << ": failed to save volume settings in " << mSettingsFile << endl; + } + } +} + +void Mixer::getVolume() +{ + static int lastVolume[3] = {-1, -1, -1}; + static int lastVolumeMute[3] = {-1, -1, -1}; + + if (mError) { + return; + } + + // Read from device + for (int i=0; i<3; i++) { + mVolume[i] = aMixer->itemGetVolume(i); + mVolumeMute[i] = aMixer->itemIsMuted(i); + + if (lastVolume[i] != mVolume[i]) { + int y; + + // Set button position + if (mError) { + y = BUTTON_MIN; + } else { + y = percentToPosition(mVolume[i]); + } + + setButtonPosition(i, y); + lastVolume[i] = mVolume[i]; + } + + // set buttom type muted/unmuted + if (lastVolumeMute[i] != mVolumeMute[i]) { + setButtonType(i); + lastVolumeMute[i] = mVolumeMute[i]; + } + } + + if (mError) { + cerr << APPNAME << ": unable to read from " << mMixerDevice << endl; + showErrorLed(); + return; + } +} + +void Mixer::setVolume(int button, int volume) +{ + if (mError) { + return; + } + + // Store volume + mVolume[button] = volume; + + // Write to device + aMixer->itemSetVolume(button, mVolume[button]); +} + +void Mixer::toggleMute(int button) +{ + mVolumeMute[button] = !mVolumeMute[button]; + aMixer->itemToggleMute(button); + setButtonType(button); +} + +void Mixer::setButtonType(int button) +{ + Xpm* image; + + if (mVolumeMute[button] == 1) { // muted + image = new Xpm(mDisplay, mRoot, mutebutton_xpm); + image->setWindowPixmap(mButton[button]); + delete image; + + XClearWindow(mDisplay, mButton[button]); + } else { + image = new Xpm(mDisplay, mRoot, button_xpm); + image->setWindowPixmap(mButton[button]); + delete image; + + XClearWindow(mDisplay, mButton[button]); + } +} + +void Mixer::setButtonPosition(int button, int position) { + if (position > BUTTON_MIN) { + position = BUTTON_MIN; + } else if (position < BUTTON_MAX) { + position = BUTTON_MAX; + } + + XMoveWindow(mDisplay, mButton[button], ButtonX[button], position); + + mVolumePos[button] = position; +} + +void Mixer::setButtonPositionRelative(int button, int relativePosition) +{ + int y; + + // Calc new button position + y = mVolumePos[button] + relativePosition; + + if (y > BUTTON_MIN) { + y = BUTTON_MIN; + } else if (y < BUTTON_MAX) { + y = BUTTON_MAX; + } + + // Set button position and volume + XMoveWindow(mDisplay, mButton[button], ButtonX[button], y); + + mVolumePos[button] = y; + + // set volume + setVolume(button, positionToPercent(y)); +} + +void Mixer::run() +{ + XEvent event; + int buttonDown = 0; + int buttonDownPosition = 0; + + // Start handling events + while(1) { + while(XPending(mDisplay) || buttonDown) { + XNextEvent(mDisplay, &event); + + switch(event.type) { + case ButtonPress: + if (event.xbutton.button == Button4 || event.xbutton.button == Button5) { + // Wheel scroll + setButtonPositionRelative(mWheelButton - 1, event.xbutton.button == Button5? 3: -3); + } else if (event.xbutton.button == Button1 && event.xbutton.window != mIconWin) { + // Volume change + buttonDown = 1; + buttonDownPosition = event.xbutton.y; + } else if (event.xbutton.button == Button3 && buttonDown == 0 && event.xbutton.window != mIconWin) { + // Mute + for (int i=0; i<3; i++) { + if (mButton[i] == event.xbutton.window) { + toggleMute(i); + break; + } + } + } else if (event.xbutton.button == Button2) { + // Load defaults or execute command + if (mCommand) { + char command[512]; + + snprintf(command, 512, "%s &", mCommand); + system(command); + } + else + loadVolumeSettings(); + } + break; + + case ButtonRelease: + if (event.xbutton.button == Button1) { + buttonDown = 0; + } + break; + + case MotionNotify: + if (buttonDown) { + // Find button + for (int i=0; i<3; i++) { + if (mButton[i] == event.xmotion.window) { + setButtonPositionRelative(i, event.xmotion.y - buttonDownPosition); + break; + } + } + } + break; + } + } + + // Idle for a moment + usleep(100000); + + // Update volume status + aMixer->handleEvents(); + if (AMixer::mixerChanged()) + aMixer->reInit(); + else if (AMixer::mixerElemsChanged()) + getVolume(); + XSync(mDisplay, False); + } +} + diff --git a/AlsaMixer.app/Mixer.h b/AlsaMixer.app/Mixer.h new file mode 100644 index 0000000..98c0d66 --- /dev/null +++ b/AlsaMixer.app/Mixer.h @@ -0,0 +1,88 @@ +// +// Mixer.app +// +// Copyright (c) 1998-2002 Per Liden +// +// 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. +// + +#ifndef _MIXER_H_ +#define _MIXER_H_ + +#include "AMixer/AMixer.h" + +#include + +#define APPNAME "AlsaMixer.app" +#define VERSION "1.8.0" +#define INSTANCENAME "alsamixer_app" +#define CLASSNAME "AlsaMixer_app" +#define SETTINGS "/GNUstep/Defaults/AlsaMixer" +#define MAX_COMMAND_LENGTH 512 + +#define LABEL_X 4 +#define LABEL_Y 54 +#define LABEL_FONT "-*-helvetica-medium-r-*-*-8-*-*-*-*-*-*-*" + +#define LED_X 57 +#define LED_Y 59 +#define BUTTON_MIN 45 +#define BUTTON_MAX 6 + +class Mixer +{ +public: + Mixer(int argc, char** argv); + ~Mixer() {}; + void run(); + void saveVolumeSettings(); + +private: + void tryHelp(char* appname); + void showHelp(); + void checkArgument(char** argv, int argc, int index); + void showErrorLed(); + void findMixerDevice(); + void getVolume(); + void setVolume(int button, int volume); + void toggleMute(int button); + void setButtonType(int button); + void setButtonPosition(int button, int position); + void setButtonPositionRelative(int button, int relativePosition); + void loadVolumeSettings(); + + Display* mDisplay; + Window mRoot; + Window mAppWin; + Window mIconWin; + Window mButton[3]; + char* mMixerDevice; + char* mInstanceName; + char* mLabelText; + char* mSettingsFile; + char* mCommand; + int mError; + int mVolumeSource[3]; + int mVolume[3]; + int mVolumePos[3]; + int mVolumeMute[3]; + int mWheelButton; + bool mSaveSettings; + bool mLoadSettings; + AMixer* aMixer; +}; + +#endif diff --git a/AlsaMixer.app/README b/AlsaMixer.app/README new file mode 100644 index 0000000..477649e --- /dev/null +++ b/AlsaMixer.app/README @@ -0,0 +1,80 @@ +Description +-------------------------------------------------------------- +AlsaMixer.app is a mixer utility for Linux systems with ALSA sound driver. +It is designed to be docked in Window Maker (and other wms). This utility has +three volume controllers that can be configured to handle any sound source, +he default sources are 'Master', 'PCM' and 'CD' volume. Sound sources can be +easily muted and there is also wheel mouse support. +The whole GUI and command parsing was taken from Mixer.app (see old doc +for URL's), only connection to ALSA driver was added. + + +Hints +-------------------------------------------------------------- +Error led: + If the led on Mixer.app is red an error message has + been printed to stderr and something is not working + correctly. If the led is green everything is working ok. + (Error led doesn't work in AlsaMixer.app, TODO) + +Mute: + Right click on a volume controller to mute the sound + source. The button will then have a red led in one corner. + Right click again to restore the volume. If a muted sound + source is modified by another application Mixer.app will + automaticaly release its muted state. + +Wheel mouse: + If you have a wheel mouse (where the wheel is configured as + Button4 and Button5) you can control the volume by just moving + the mouse over Mixer.app and roll the wheel up and down. Use + the command line option -w to specify which slider that should + react to the wheel movement. + +Label: + If you run multiple instances of AlsaMixer.app you might want + to be able to tell them apart. This can easily be done + by setting a label to each one of them. By using the -l + option you can add a little text label at the bottom of + the mixer. + +Save volume settings: + Use the option -S (and -f ) if you want the volume + settings to be saved when AlsaMixer.app exits, and then + -L to be loaded again when AlsaMixer.app is started the next time. + When not using -f the settings are saved in/loaded from + ~/GNUstep/Defaults/AlsaMixer. Use the -f option + if you want to use a different file. + (TODO: mute states aren't saved/loaded) + +Configurable middle click: + By default, when you middle click anywhere inside application + window, app tries to load default mixer setting from default + or explicitly configured (-f) file. If file doesn't exist, + nothing happens. + You can also configure AlsaMixer.app to run command (i.e. + better mixer) on middle click by using -e option. + +Bugs +-------------------------------------------------------------- +If you discover any bugs in this software, please send a +bugreport to xhlavk00@stud.fit.vutbr.cz and describe the problem. + + +Special thanks to +-------------------------------------------------------------- +Per Liden - original author of Mixer.app +David Sauer +Theo Schlossnagle +Alban Hertroys + + +Copyright +-------------------------------------------------------------- +AlsaMixer.app, 2004, Petr Hlavka +Mixer.app is copyright (c) 1998-2002 by Per Liden and is +licensed through the GNU General Public License. Read the +COPYING file for the complete license. + +Minor parts of this code were taken from asmixer by Rob Malda +(malda@slashdot.org) diff --git a/AlsaMixer.app/Xpm.cc b/AlsaMixer.app/Xpm.cc new file mode 100644 index 0000000..a814ede --- /dev/null +++ b/AlsaMixer.app/Xpm.cc @@ -0,0 +1,107 @@ +// +// Mixer.app +// +// Copyright (c) 1998-2002 Per Liden +// +// 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. +// + +#include +#include +#include +#include +#include +#include +#include "Mixer.h" +#include "Xpm.h" + +using namespace std; + +Xpm::Xpm(Display* display, Window root, char** data) +{ + int error; + + mDisplay = display; + + mAttributes.valuemask = 0; + error = XpmCreatePixmapFromData(mDisplay, root, data, &mImage, &mMask, &mAttributes); + + switch (error) { + case XpmColorError: + cerr << APPNAME << ": xpm image loaded but did not get all colors needed" << endl; + break; + + case XpmColorFailed: + cerr << APPNAME << ": could not load xpm image (not enough colors available)" << endl; + exit(0); + break; + + case XpmNoMemory: + cerr << APPNAME << ": could not load xpm image (not enough memory available)" << endl; + exit(0); + break; + + case XpmOpenFailed: + case XpmFileInvalid: + cerr << APPNAME << ": could not load xpm image (image broken or corrupt)" << endl; + exit(0); + break; + + case XpmSuccess: + default: + // Image loaded ok + break; + } +} + +Xpm::~Xpm() +{ + if (mImage) { + XFreePixmap(mDisplay, mImage); + } + + if (mMask) { + XFreePixmap(mDisplay, mMask); + } +} + +void Xpm::setWindowPixmap(Window win) +{ + XResizeWindow(mDisplay, win, mAttributes.width, mAttributes.height); + XSetWindowBackgroundPixmap(mDisplay, win, mImage); +} + +void Xpm::setWindowPixmapShaped(Window win) +{ + XResizeWindow(mDisplay, win, mAttributes.width, mAttributes.height); + XSetWindowBackgroundPixmap(mDisplay, win, mImage); + XShapeCombineMask(mDisplay, win, ShapeBounding, 0, 0, mMask, ShapeSet); +} + +void Xpm::drawString(int x, int y, char* text) +{ + Font font; + GC gc; + XGCValues gcv; + + font = XLoadFont(mDisplay, LABEL_FONT); + gcv.font = font; + gcv.foreground = WhitePixel(mDisplay, DefaultScreen(mDisplay)); + gc = XCreateGC(mDisplay, mImage, GCFont | GCForeground, &gcv); + XDrawString(mDisplay, mImage, gc, x, y, text, strlen(text)); + XFreeGC(mDisplay, gc); + XUnloadFont(mDisplay, font); +} diff --git a/AlsaMixer.app/Xpm.h b/AlsaMixer.app/Xpm.h new file mode 100644 index 0000000..9405372 --- /dev/null +++ b/AlsaMixer.app/Xpm.h @@ -0,0 +1,44 @@ +// +// Mixer.app +// +// Copyright (c) 1998-2002 Per Liden +// +// 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. +// + +#ifndef _XPM_H_ +#define _XPM_H_ + +#include +#include + +class Xpm +{ +public: + Xpm(Display* display, Window root, char** data); + virtual ~Xpm(); + void setWindowPixmap(Window win); + void setWindowPixmapShaped(Window win); + void drawString(int x, int y, char* text); + +private: + Display* mDisplay; + XpmAttributes mAttributes; + Pixmap mImage; + Pixmap mMask; +}; + +#endif diff --git a/AlsaMixer.app/olddoc/ChangeLog.Mixer.app b/AlsaMixer.app/olddoc/ChangeLog.Mixer.app new file mode 100644 index 0000000..b2ae9f1 --- /dev/null +++ b/AlsaMixer.app/olddoc/ChangeLog.Mixer.app @@ -0,0 +1,95 @@ +Version Description +-------------------------------------------------------------------------------- +1.8.0 - Released 2002-09-15 + - Now supports all mixer sources. NOTE! The source names have + been changed. See "Mixer.app -h". + - Added alternative skin submitted by Hans D. . + - Fixed warnings when compiling with GCC 3.2. + - Added OpenBSD support (thanks to ptiJo ). + +1.7.0 - Released 2001-06-25 + - Fixed compilation problems. + +1.6.0 - Released 2001-03-17 + - Mixer.app is now devfs friendly, which means it will try to + use /dev/sound/mixer or /dev/sound/mixer1 first and fall back + to /dev/mixer if that didn't work. + - New Makefile. + +1.5.0 - Released 2000-02-21. + - Added command line options -s and -S , which cause + Mixer.app to load/save volume settings when starting/exiting. + When the option -s is used, settings are loaded from/saved in + ~/GNUstep/Defaults/Mixer. Use -S if you want Mixer.app + to use a different file. + - Fixed potential bug in command line parsing. + +1.4.1 - Released 1999-05-28. + - Added command line option -l that can be used to + add a text label in the corner of the mixer. + +1.4.0 - Released 1999-05-09. + - Added support for wheel mice. One of the sliders (use -w to + specify which one) will react on wheel movement. + - Misc. code clean up. + +1.3.3 - Released 1999-05-02. + - Fixed problem that caused Mixer.app to die. + +1.3.2 - Released 1999-04-18. + - Fixed exit bug. Mixer.app will now exit properly when + the windowmanager terminates. + +1.3.1 - Released 1999-02-09. + - Added new mute function (right click). + - Rewrote command-line parsing, not using getopt anymore. + - Minor code clean up. + +1.3.0 - Released 1999-02-04. + - New design. + - I didn't find the mute function very usefull so I removed it. + - Doing 'make install' will now install it in + /usr/local/GNUstep/Apps/Mixer.app/. + +1.2.0 - Released 1998-12-01. + - Moved back to old design. The design of version 1.1.1 made + Mixer.app (and Window Maker) unstable due to some strange + race condition at startup. It worked on some machines and + some not, so I desided to go back to the old design. + - Increased idle interval to reduce CPU usage. + +1.1.1 - Released 1998-11-14. + - Fixed XGetImage errors, (slow machines may still have this + problem, please report any errors). + - Added command line option -m to set mixer device. + - Added command line option -n to set instance name. + - Compiling under FreeBSD now works fine. + +1.1.0 - Released 1998-11-14. + - Alarm singals are no longer used so now the "Alarm Clock" + problem is solved for sure! + - Mute function. + - New design. + +1.0.5 - Released 1998-09-05. + - Fixed the "Alarm Clock" problem. + - Fixed problem when using WindowPlacement = manual + in WindowMaker. + +1.0.4 - Released 1998-03-19. + - Just some minor internal changes. + +1.0.3 - Released 1998-02-24. + - Changed default timerinterval. + - Minor changes to eventhandling code. + +1.0.2 - Released 1998-02-23. + - If the red led goes on (an error has occured) the control + buttons are set to volume 0. + +1.0.1 - Released 1998-02-23. + - Changed classname to "mixer_app.Mixer_app". + +1.0.0 - Released 1998-02-22. + - First official version. + diff --git a/AlsaMixer.app/olddoc/INSTALL.Mixer.app b/AlsaMixer.app/olddoc/INSTALL.Mixer.app new file mode 100644 index 0000000..a3766b5 --- /dev/null +++ b/AlsaMixer.app/olddoc/INSTALL.Mixer.app @@ -0,0 +1,33 @@ +Installation instructions for Mixer.app + + +Requirements +------------------------------------------------------------------- +- X11, libxpm, C++ development environment + Most (Linux) systems have these things installed by default. + If you don't have it look for packages that fit your + distribution. + + +Installation +------------------------------------------------------------------- +1) make +2) su +3) make install (to put it in /usr/local/GNUstep/Apps/Mixer.app) + or + make install-x11 (to put it in /usr/X11R6/bin) +5) exit + + +Running +------------------------------------------------------------------- +To run this program: +/usr/local/GNUstep/Apps/Mixer.app/Mixer & +or +/usr/X11R6/bin/Mixer.app & + + +For more information about available command line arguments: +/usr/local/GNUstep/Apps/Mixer.app/Mixer --help +or +/usr/X11R6/bin/Mixer.app --help diff --git a/AlsaMixer.app/olddoc/README.Mixer.app b/AlsaMixer.app/olddoc/README.Mixer.app new file mode 100644 index 0000000..2fa41db --- /dev/null +++ b/AlsaMixer.app/olddoc/README.Mixer.app @@ -0,0 +1,75 @@ + + Mixer.app + + + by Per Liden + + + +Description +-------------------------------------------------------------- +Mixer.app is a mixer utility for Linux/FreeBSD/OpenBSD systems. +It is designed to be docked in Window Maker. This utility has +three volume controllers that can be configured to handle any +sound source, the default sources are master-, cd- and pcm-volume. +Sound sources can easily be muted and there is also wheel mouse +support. + + +Hints +-------------------------------------------------------------- +Error led: + If the led on Mixer.app is red an error message has + been printed to stderr and something is not working + correctly. If the led is green everything is working ok. + +Mute: + Right click on a volume controller to mute the sound + source. The button will then have a red led in one corner. + Right click again to restore the volume. If a muted sound + source is modified by another application Mixer.app will + automaticaly release its muted state. + +Wheel mouse: + If you have a wheel mouse (where the wheel is configured as + Button4 and Button5) you can control the volume by just moving + the mouse over Mixer.app and roll the wheel up and down. Use + the command line option -w to specify which slider that should + react to the wheel movement. + +Label: + If you run multiple instances of Mixer.app you might want + to be able to tell them apart. This can easily be done + by setting a label to each one of them. By using the -l + option you can add a little text label at the bottom of + the mixer. + +Save volume settings: + Use the option -s or -S if you want the volume + settings to be saved when Mixer.app exits, and then + loaded again when Mixer.app is started the next time. + When using -s the settings are saved in/loaded from + ~/GNUstep/Defaults/Mixer. Use the -S option + if you want to use a different file. + +Bugs +-------------------------------------------------------------- +If you discover any bugs in this software, please send a +bugreport to per@fukt.bth.se and describe the problem. + + +Special thanks to +-------------------------------------------------------------- +David Sauer +Theo Schlossnagle +Alban Hertroys + + +Copyright +-------------------------------------------------------------- +Mixer.app is copyright (c) 1998-2002 by Per Liden and is +licensed through the GNU General Public License. Read the +COPYING file for the complete license. + +Minor parts of this code were taken from asmixer by Rob Malda +(malda@slashdot.org) diff --git a/AlsaMixer.app/pixmaps b/AlsaMixer.app/pixmaps new file mode 120000 index 0000000..9191efc --- /dev/null +++ b/AlsaMixer.app/pixmaps @@ -0,0 +1 @@ +skins/default \ No newline at end of file diff --git a/AlsaMixer.app/skins/barross@web.de/button.xpm b/AlsaMixer.app/skins/barross@web.de/button.xpm new file mode 100644 index 0000000..26f15c6 --- /dev/null +++ b/AlsaMixer.app/skins/barross@web.de/button.xpm @@ -0,0 +1,47 @@ +/* XPM */ +static char * button_xpm[] = { +"15 9 35 1", +" c None", +". c #DEDEE6", +"+ c #D5DAE6", +"@ c #D5D6E6", +"# c #CDD2DE", +"$ c #CDCEDE", +"% c #C5CAD5", +"& c #C5C6D5", +"* c #BDC2CD", +"= c #B4BECD", +"- c #BDBEC5", +"; c #C5CADE", +"> c #BDC6D5", +", c #BDBECD", +"' c #B4B6C5", +") c #ACB6C5", +"! c #ACB2C5", +"~ c #ACB2BD", +"{ c #ACAEBD", +"] c #8B8D9C", +"^ c #A4A5B4", +"/ c #9C9DAC", +"( c #94959C", +"_ c #8B919C", +": c #CDD2E6", +"< c #B4BAC5", +"[ c #BDC2D5", +"} c #B4BACD", +"| c #8B8D94", +"1 c #ACAAB4", +"2 c #9CA1AC", +"3 c #9C99A4", +"4 c #8B8994", +"5 c #B4BEC5", +"6 c #83858B", +"....++@@#$%&*=-", +".++@@#;>,')!~{]", +",~^/(__]]]]]]]]", +".+++@@:$%&*,,<]", +"++@:$&[}'!~{{~|", +"123(_]]]]]_]]]4", +"++@@@#;%>*,-<56", +"@@#;>*''!~~~~~6", +"/(__]]]_]]|]466"}; diff --git a/AlsaMixer.app/skins/barross@web.de/main.xpm b/AlsaMixer.app/skins/barross@web.de/main.xpm new file mode 100644 index 0000000..2dc3ab5 --- /dev/null +++ b/AlsaMixer.app/skins/barross@web.de/main.xpm @@ -0,0 +1,167 @@ +/* XPM */ +static char * main_xpm[] = { +"64 64 100 2", +" c None", +". c #212121", +"+ c #222223", +"@ c #E6EAEE", +"# c #DEE6EE", +"$ c #DEE2EE", +"% c #DEE2E6", +"& c #D5E2E6", +"* c #D5DEE6", +"= c #D5DAE6", +"- c #D5DADE", +"; c #CDDADE", +"> c #CDD6DE", +", c #CDD2DE", +"' c #C5D2D5", +") c #C5CED5", +"! c #C5CAD5", +"~ c #BDCAD5", +"{ c #BDC6D5", +"] c #BDC6CD", +"^ c #BDC2CD", +"/ c #EEF2EE", +"( c #C5D2DE", +"_ c #5A5D62", +": c #5A6162", +"< c #5A595A", +"[ c #B4C2CD", +"} c #5A555A", +"| c #52555A", +"1 c #4A4C5A", +"2 c #B4BECD", +"3 c #EBEEEB", +"4 c #4A4C52", +"5 c #D5D6DE", +"6 c #4A505A", +"7 c #B4BEC5", +"8 c #E5E7E5", +"9 c #4A484A", +"0 c #E2E3E2", +"a c #4A444A", +"b c #E1E2E1", +"c c #41404A", +"d c #E1E1E1", +"e c #393C4A", +"f c #41444A", +"g c #393C41", +"h c #39404A", +"i c #C5CEDE", +"j c #393839", +"k c #B4BAC5", +"l c #393439", +"m c #313039", +"n c #293031", +"o c #B3B9C4", +"p c #ACBAC5", +"q c #D4DDE5", +"r c #292C31", +"s c #D4DAE1", +"t c #292829", +"u c #D5D6E6", +"v c #293039", +"w c #D2D8DE", +"x c #292429", +"y c #ACB6C5", +"z c #D1D6DC", +"A c #202429", +"B c #292C29", +"C c #ACB6BD", +"D c #D1D6D9", +"E c #182020", +"F c #C4CDD4", +"G c #D1D6D8", +"H c #181C20", +"I c #CFD4D8", +"J c #CED3D9", +"K c #ACB2BD", +"L c #CFD4DB", +"M c #D0D3DA", +"N c #313439", +"O c #CDD4DC", +"P c #CCD5DD", +"Q c #BCC5D4", +"R c #BCC5CC", +"S c #ACAEBD", +"T c #A4AEB4", +"U c #A4AEBD", +"V c #A4AAB4", +"W c #4A555A", +"X c #ACAEB4", +"Y c #5A5D5A", +"Z c #9CAAB4", +"` c #626162", +" . c #9CA5B4", +".. c #62656A", +"+. c #62696A", +"@. c #7B8183", +"#. c #6A6D73", +"$. c #9CA1AC", +"%. c #1F1E22", +"&. c #26D526", +" ", +" ", +" ", +" . . . . . . . . . . . . . . . . . . + + + + + + + + + + + + + + + + + + + + + . . . . . . . . . . . . . . . . . . . ", +" . @ @ @ @ @ # # # # # $ $ $ % % & & * * * * * * * = = = = - ; > > > > > , , , , ' ) ) ) ) ! ! ! ! ! ~ { ] ] ] ^ ^ / ", +" . @ @ @ @ # # # # # $ $ $ % % % & * * * * * * * = = = = - - > > > > > > , , , ( ) ) ) ) ) ! ! ! ! ~ { ] ] ] ] ^ ^ / ", +" . @ @ @ # # # # # $ $ $ % % % & & * * * * * * * = = = = = ; > > > > > > , , , , ' ) ) ) ! ! ! ! ~ { ] ] ] ] ] ^ ^ / ", +" . @ @ # # # # # $ $ $ % % % & & * * * * * * * = = = = = - > > > > > > , , , , ' ) ) ) ) ! ! ! ~ { ] ] ] ] ] ^ ^ ^ / ", +" . @ # # # # # $ $ $ _ / % % % * * * * * * * * = = = = = : / > > > > > , , , , ' ) ) ) ! ! ! _ / { ] ] ] ] ^ ^ ^ ^ / ", +" . # # # # # $ $ $ $ < / % % * * * * * * * * = = = = = - _ / > > > > > , , , ( ) ) ) ) ) ! ! < / ] ] ] ] ^ ^ ^ ^ [ / ", +" . # # # # $ $ $ $ $ } / % * * * * * * * * = * = = = = = < / > > > > , , , , ( ) ) ) ) ! ! ! } / ] ] ] ^ ^ ^ ^ ^ [ / ", +" . # # # $ $ $ $ $ % | / & * * * * * * * * * = = = = = - < / > > > > > , , , ' ) ) ) ) ! ! ~ | / ] ] ^ ^ ^ ^ ^ [ [ / ", +" . # # $ $ $ $ % % % 1 / & * * * * * * * * * = = = = = - | / > > > > , , , , ) ) ) ) ! ! ! ! 1 / ] ] ^ ^ ^ ^ [ [ 2 3 ", +" . # $ $ $ $ % % % % 4 / * * * * * * * * * = = = = = - 5 6 / > > > > , , , , ) ) ) ) ! ! ! ~ 4 / ] ^ ^ ^ ^ [ [ 2 7 8 ", +" . $ $ $ $ % % % % & 9 / * * * * * * * * = = = = = = = 5 4 / > > > , , , , ( ) ) ) ) ! ! ! ~ 9 / ] ] ^ ^ ^ [ 2 7 7 0 ", +" . $ $ $ % % % % & & a / * * * * * * * = = = = = = = - 5 9 / > > > , , , , ' ) ) ) ) ! ! ~ { a / ] ^ ^ ^ [ 2 7 7 7 b ", +" . $ $ % % % & & & * c / * * * * * * = = = = = = = = - > 9 / > > > > , , ( ) ) ) ) ) ! ! ~ { c / ] ^ ^ ^ [ 2 7 7 7 d ", +" . $ % % % & & * * * e / * * * * * = * = = = = = = - 5 > f / > > > , , , ( ) ) ) ) ! ! ! { { e / ^ ^ ^ [ [ 2 7 7 7 d ", +" . % % % & & * * * * g / * * * * = * = = = = = = - = > > h / > > > , , , i ) ) ) ) ! ! ~ ~ ] g / ^ ^ ^ ^ 2 7 7 7 7 d ", +" . % & & & * * * * * j / * * * = * = = = = = = = = 5 > > g / > > , , , , ' ) ) ) ! ! ! ! { ] j / ^ ^ ^ [ 2 7 7 7 k d ", +" . & & * * * * * * * l / * * * * = = = = = = = = - 5 > > g / > > , , , ( ) ) ) ) ! ! ! ~ ] ] l / ^ ^ ^ 2 7 7 7 k k b ", +" . * * * * * * * * * m / * * * = = = = = = = = = 5 5 > > j / > , , , , ' ) ) ) ) ! ! ~ { ] ] m / ^ ^ [ 7 7 7 7 k k 0 ", +" . * * * * * * * * * n / * = = = = = = = = = = 5 - > > > l / > > , , , i ) ) ) ! ! ! ~ { ] ] n / ^ [ 2 2 7 7 o k p 8 ", +" . q * * * * * * * * r / = = = = = = = = = = 5 - > > > > m / > , , , ( ) ) ) ) ! ! ~ { ] ] ] r / ^ [ 2 7 7 7 k k p 3 ", +" . s * * * * * * * * t / = = = = = = = = = u - > > > > > v / > , , , i ) ) ) ! ! ! ~ { ] ] ^ t / ^ [ 7 7 7 k k p p / ", +" . w * * * * = * = = x / = = = = = = = - = - > > > > > > n / , , , , ' ) ) ) ! ! ~ ~ ] ] ] ^ x / ^ 2 7 7 k k k p y / ", +" . z * * = = = = = = A / = = = = = = 5 - 5 > > > > > > > B / , , , , ) ) ) ! ! ! ~ ] ] ] ^ ^ A / [ 7 7 7 k k k y C / ", +" . D = = = = = = = = E / = = = = 5 - - > > > > > > > > > t / , , , ( ) ) F ! ! ! { ] ] ] ^ ^ E / 2 7 7 7 k k p C C / ", +" + G = = = = = = = = H / - = - 5 - > > > > > > > > > > > t / , , ( ) ) ) ) ! ! ~ { ] ] ] ^ ^ H / 2 7 7 k k p y C C / ", +" + I = = = = = = = = E / 5 5 5 > > > > > > > > > > > > > B / , , i ) ) ) ! ! ! { ] ] ] ^ ^ ^ E / 7 7 7 k k p y C C / ", +" + I = = = = - = - - A / 5 > > > > > > > > > > > > > > > r / , ( ) ) ) ) ! ! ~ ] ] ] ^ ^ ^ [ A / 7 7 k k p p C C C / ", +" . J = = - = - ; > 5 x / > > > > > > > > > > > > , > , , n / ( ' ) ) ) ! ! ~ ~ ] ] ] ^ ^ ^ [ x / 7 k k p p C C C K / ", +" . L - - - > > > > > t / > > > > > > > > > > , > , , , , m / ' ) ) ) ! ! ! ~ ] ] ] ^ ^ ^ [ 2 t / k k k p y C C K K / ", +" . M - > > > > > > > r / > > > > > > > , , , , , , , , ( N / ) ) ) ! ! ! ~ { ] ] ^ ^ ^ [ [ 2 r / k k p p C C C K K / ", +" . O > > P P > > > > n / > > > > > > , , , , , , , , ( ' j / ) ) ! ! ! ! Q ] ] ^ ^ ^ ^ [ 2 7 n / k p p y C C K K K / ", +" . > > > > > > > > > m / > > > , , , , , , , , ( ( ) ) ) j / ) ! ! ! ! { R ] ] ^ ^ ^ ^ 2 7 7 m / k p y C C C K K S / ", +" . > > > > > > > > > l / > , , , , , , , , ( ( ) ) ) ) ) g / ! ! ! ! { ] ] ] ^ ^ ^ ^ 2 7 7 7 l / p y C C C K K S S / ", +" . > > > > > > > , , j / , , , , , , , ( ' ) ) ) ) ) ) ) h / ! ! ~ { ] ] ] ^ ^ ^ ^ [ 2 7 7 k j / y y C C K K K S S / ", +" . > > > > > , , , , g / , , , , , ( ) ) ) ) ) ) ) ) ! ! f / ! ~ { ] ] ] ^ ^ ^ ^ [ 2 7 7 7 k g / y C C C K K S S S / ", +" . > > , , , , , , , h / , , ' ' ) ) ) ) ) ) ) ) ) ! ! ! a / ~ { ] ] ] ^ ^ ^ ^ [ 2 7 7 7 k k h / C C C K K K S S T / ", +" . , , , , , , , , , f / ' ' ) ) ) ) ) ) ) ) ) ! ! ! ! ! 9 / ] ] ] ] ^ ^ ^ ^ [ 2 2 7 7 k k p f / C C K K K S S T T / ", +" . , , , , , , ( ' ( a / ) ) ) ) ) ) ) ) ) ! ! ! ! ! ! ~ 9 / ] ] ] ^ ^ ^ ^ [ 2 2 7 7 k k p p a / C K K K S S U T V / ", +" . , , , , ( ' ) ) ) 9 / ) ) ) ) ) ) ) ! ! ! ! ! ! ~ { { 4 / ] ] ^ ^ ^ ^ [ 2 7 7 7 k k p p C 9 / K K K S S S T T V / ", +" . , ( ( ' ) ) ) ) ) 4 / ) ) ) ) ! ! ! ! ! ~ ! ~ { { ] ] W / ^ ^ ^ ^ ^ [ 2 7 7 7 k k p p y C 4 / K K S S S T T V V / ", +" . ( ' ) ) ) ) ) ) ) 6 / ) ) ! ! ! ! ! ! ! ~ { ] ] ] ] ] | / ^ ^ ^ [ [ 2 7 7 7 k k p p y C C 6 / K K S S X T V V V / ", +" . ' ) ) ) ) ) ) ) ) | / ! ! ! ! ! ! ~ ~ { { ] ] ] ] ] ^ < / ^ ^ [ [ 2 7 7 7 k k p p y C C C | / K S S S T V V V V / ", +" . ) ) ) ) ) ) ) ! ! < / ! ! ! ~ ~ ~ { { ] ] ] ] ] ] ^ ^ Y / [ [ 2 2 7 7 7 k k p p y C C C K < / S S S T T V V V Z / ", +" . ) ) ) ) ) ! ! ! ! < / ! ~ ~ ~ ] { ] ] ] ] ] ] ^ ^ ^ ^ _ / [ 7 7 7 7 7 k k k p y C C C K K < / S S T T V V V Z Z / ", +" . ) ) ) ! ! ! ! ! ! _ / ~ { ] { ] ] ] ] ] ] ^ ^ ^ ^ ^ [ ` / 7 7 7 7 7 k k p y y C C C K K K _ / S T T V V V Z Z ./ ", +" . ) ) ! ! ! ! ! ~ ~ ` / { ] ] ] ] ] ] ] ^ ^ ^ ^ ^ ^ [ [ ../ 7 7 7 k k k p y y C C C K K K S ` / T T V V V Z Z . ./ ", +" . ) ! ! ! ! ! ~ ~ { ../ ] ] ] ] ] ^ ^ ^ ^ ^ ^ ^ [ [ 2 7 +./ 7 7 k k k p y C C C C K K K S S ../ T V V V Z Z . . ./ ", +" . ! ! ! ! ! ~ { { ] @./ ] ] ] ^ ^ ^ ^ ^ ^ ^ [ [ [ 2 7 7 #./ 7 k k k p y C C C C K K K S S S +./ V V V Z Z . . . ./ ", +" . ! ! ! ! ~ { { ] ] ] ] ^ ^ ^ ^ ^ ^ ^ ^ ^ [ [ 2 7 7 7 7 7 k k k p p y C C C C K K K S S S T T V V V Z Z . . . . ./ ", +" . ! ! ~ ~ { { ] ] ] ] ^ ^ ^ ^ ^ ^ ^ [ [ [ 2 7 7 7 7 k k k k k p y y C C C K K K K S S X T T V V V Z Z . . . . .$./ ", +" . ! ~ ~ { { ] ] ] ] ^ ^ ^ ^ ^ ^ [ [ 2 7 2 7 7 7 7 7 k k k p p y C C C C K K K K S S U T V V V V Z Z . . . . .$.$./ ", +" . ~ ~ { { ] ] ] ] ^ ^ ^ ^ ^ [ [ 2 2 2 7 7 7 7 k k k k k p y y C C C K K K K S S S S T T V V V Z Z . . . . .$.$.$./ ", +" . / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / ", +" %. %. %. %. %. %.%.%. %.%.%. ", +" %.%. %.%. %. %. %. %. %. %. %.%.%.%. ", +" %. %. %. %. %.%. %.%.%. %.%.%. %.&.&.&. ", +" %. %. %. %. %. %. %. %. %.&.&.&. ", +" %. %. %. %. %. %.%.%. %. %. ", +" ", +" "}; diff --git a/AlsaMixer.app/skins/barross@web.de/mutebutton.xpm b/AlsaMixer.app/skins/barross@web.de/mutebutton.xpm new file mode 100644 index 0000000..1aaa726 --- /dev/null +++ b/AlsaMixer.app/skins/barross@web.de/mutebutton.xpm @@ -0,0 +1,64 @@ +/* XPM */ +static char * mutebutton_xpm[] = { +"16 9 52 1", +" c None", +". c #DEDEE6", +"+ c #D5DAE6", +"@ c #D5D6E6", +"# c #CDD2DE", +"$ c #CDCEDE", +"% c #C5CAD5", +"& c #C5C6D5", +"* c #BDC2CD", +"= c #B4BECD", +"- c #BDBEC5", +"; c #C5CADE", +"> c #BDC6D5", +", c #BDBECD", +"' c #B4B6C5", +") c #ACB6C5", +"! c #ACB2C5", +"~ c #ACB2BD", +"{ c #ACAEBD", +"] c #8B8D9C", +"^ c #A4A5B4", +"/ c #9C9DAC", +"( c #94959C", +"_ c #8B919C", +": c #CDD2E6", +"< c #B4BAC5", +"[ c #BDC2D5", +"} c #B4BACD", +"| c #8B8D94", +"1 c #ACAAB4", +"2 c #9CA1AC", +"3 c #9C99A4", +"4 c #C07681", +"5 c #DC5156", +"6 c #ED3638", +"7 c #D14648", +"8 c #96555B", +"9 c #DA585D", +"0 c #F35F5E", +"a c #FB3A39", +"b c #FB2324", +"c c #B31818", +"d c #D4585C", +"e c #F71A1C", +"f c #FE1212", +"g c #FF1313", +"h c #D70E0E", +"i c #9E5C64", +"j c #C61A1D", +"k c #DB1010", +"l c #F80E0E", +"m c #CB0C0C", +".....++@@#$%&*=-", +"..++@@#;>,')!~{]", +".,~^/(__]]]]]]]]", +"..+++@@:$%&*,,<]", +".++@:$&[}'!~{{~|", +".123(_]]]]]45678", +".++@@@#;%>*90abc", +"+@@#;>*''!~defgh", +"+/(__]]]_]]ijklm"}; diff --git a/AlsaMixer.app/skins/barross@web.de/redlight.xpm b/AlsaMixer.app/skins/barross@web.de/redlight.xpm new file mode 100644 index 0000000..43d19e3 --- /dev/null +++ b/AlsaMixer.app/skins/barross@web.de/redlight.xpm @@ -0,0 +1,7 @@ +/* XPM */ +static char * redlight_xpm[] = { +"3 2 2 1", +" c None", +". c #FF0000", +"...", +"..."}; diff --git a/AlsaMixer.app/skins/default/button.xpm b/AlsaMixer.app/skins/default/button.xpm new file mode 100644 index 0000000..acb9993 --- /dev/null +++ b/AlsaMixer.app/skins/default/button.xpm @@ -0,0 +1,29 @@ +/* XPM */ +static char * button_xpm[] = { +"16 9 17 1", +" c None", +". c #B7BAC7", +"+ c #848694", +"@ c #838593", +"# c #828392", +"$ c #808290", +"% c #7F818F", +"& c #7E808E", +"* c #7C7E8C", +"= c #7B7D8B", +"- c #7A7C8A", +"; c #787A88", +"> c #777987", +", c #767886", +"' c #747784", +") c #737583", +"! c #000000", +"................", +".+@#$%&*=-;>,')!", +".!!!!!!!!!!!!!!!", +"...............!", +".+@#$%&*=-;>,')!", +".!!!!!!!!!!!!!!!", +"...............!", +".+@#$%&*=-;>,')!", +".!!!!!!!!!!!!!!!"}; diff --git a/AlsaMixer.app/skins/default/main.xpm b/AlsaMixer.app/skins/default/main.xpm new file mode 100644 index 0000000..14c6901 --- /dev/null +++ b/AlsaMixer.app/skins/default/main.xpm @@ -0,0 +1,261 @@ +/* XPM */ +static char * main_xpm[] = { +"64 64 194 2", +" c None", +". c #000000", +"+ c #2F2542", +"@ c #302643", +"# c #322745", +"$ c #332846", +"% c #342948", +"& c #352A49", +"* c #362B4B", +"= c #372C4C", +"- c #382D4E", +"; c #392E4F", +"> c #3A2E50", +", c #3B2F52", +"' c #3C3053", +") c #3C3154", +"! c #3D3155", +"~ c #3E3256", +"{ c #3F3357", +"] c #3F3358", +"^ c #403459", +"/ c #41345A", +"( c #41355A", +"_ c #41355B", +": c #42355B", +"< c #42365C", +"[ c #43365D", +"} c #B7BAC7", +"| c #312745", +"1 c #352A4A", +"2 c #372C4D", +"3 c #392F50", +"4 c #3B3052", +"5 c #43365C", +"6 c #43375E", +"7 c #44375E", +"8 c #44375F", +"9 c #44385F", +"0 c #45385F", +"a c #3A2F51", +"b c #322846", +"c c #392E50", +"d c #3A2F52", +"e c #453860", +"f c #463961", +"g c #3C3054", +"h c #3B3053", +"i c #332948", +"j c #403358", +"k c #463962", +"l c #473A62", +"m c #473A63", +"n c #483A63", +"o c #473963", +"p c #483A64", +"q c #3D3154", +"r c #332947", +"s c #342A49", +"t c #2E2F40", +"u c #9F9FB1", +"v c #483B64", +"w c #493B65", +"x c #493C65", +"y c #493C66", +"z c #303143", +"A c #A1A1B3", +"B c #2F2F40", +"C c #352B4A", +"D c #483B65", +"E c #4A3C66", +"F c #4A3C67", +"G c #4A3D67", +"H c #4B3D67", +"I c #4B3D68", +"J c #313143", +"K c #A1A1B4", +"L c #2F3041", +"M c #362B4C", +"N c #382D4D", +"O c #43375D", +"P c #4B3E69", +"Q c #4C3E69", +"R c #4C3E6A", +"S c #313244", +"T c #A2A1B4", +"U c #4C3F6A", +"V c #392D4F", +"W c #A0A0B2", +"X c #453960", +"Y c #4D3F6A", +"Z c #4D3F6B", +"` c #4E406C", +" . c #A2A2B5", +".. c #4F406D", +"+. c #4F416D", +"@. c #4F416E", +"#. c #323245", +"$. c #50416E", +"%. c #303042", +"&. c #382C4D", +"*. c #4D3F6C", +"=. c #4E406D", +"-. c #50426F", +";. c #504270", +">. c #514270", +",. c #A3A2B6", +"'. c #514371", +"). c #2F3042", +"!. c #524371", +"~. c #524372", +"{. c #524472", +"]. c #534473", +"^. c #323345", +"/. c #303142", +"(. c #A0A0B3", +"_. c #534574", +":. c #544574", +"<. c #544575", +"[. c #333346", +"}. c #A3A3B6", +"|. c #A1A0B3", +"1. c #554676", +"2. c #564777", +"3. c #A3A3B7", +"4. c #50416F", +"5. c #554675", +"6. c #574778", +"7. c #574879", +"8. c #333347", +"9. c #A4A3B7", +"0. c #58497A", +"a. c #58497B", +"b. c #59497B", +"c. c #343447", +"d. c #A4A3B8", +"e. c #3E3257", +"f. c #564778", +"g. c #594A7C", +"h. c #5A4A7D", +"i. c #5A4B7D", +"j. c #343448", +"k. c #A4A4B8", +"l. c #5B4B7E", +"m. c #313144", +"n. c #5C4C7F", +"o. c #A5A4B9", +"p. c #5C4C80", +"q. c #5A4A7C", +"r. c #5D4D81", +"s. c #5D4D82", +"t. c #353448", +"u. c #5E4D82", +"v. c #5E4E83", +"w. c #5F4F84", +"x. c #353549", +"y. c #A5A5B9", +"z. c #5E4E82", +"A. c #604F85", +"B. c #615086", +"C. c #A6A5BA", +"D. c #605086", +"E. c #615187", +"F. c #625188", +"G. c #35354A", +"H. c #625288", +"I. c #323244", +"J. c #625187", +"K. c #635289", +"L. c #63528A", +"M. c #36364A", +"N. c #A6A5BB", +"O. c #64538B", +"P. c #64538A", +"Q. c #65548C", +"R. c #36364B", +"S. c #A7A6BB", +"T. c #66548D", +"U. c #66558D", +"V. c #A7A6BC", +"W. c #67558F", +"X. c #685790", +"Y. c #584879", +"Z. c #59497C", +"`. c #67568F", +" + c #37364B", +".+ c #A8A6BD", +"++ c #695791", +"@+ c #2E2F3F", +"#+ c #9F9FB0", +"$+ c #382E4E", +"%+ c #42355C", +"&+ c #2E2440", +"*+ c #292039", +"=+ c #00FF29", +" ", +" ", +" ", +" . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +" . + @ # $ % & * = - ; > , ' ) ! ~ { ] ^ / ( _ : < < [ [ [ [ [ [ [ < < : _ ( / ^ ] { ~ ! ) ' , > ; - = * & % $ # @ } ", +" . @ | $ % 1 * 2 - ; 3 4 ' ! ~ { ] ^ / _ < 5 [ 6 7 7 8 9 7 0 0 9 8 7 7 6 [ 5 < _ / ^ ] { ~ ! , 4 a ; - 2 * 1 % $ | } ", +" . | b % & * 2 - c a d ) ! ~ ] ^ / : < [ 6 7 0 e e f f f e f f f f f e e 0 7 6 [ < : / ^ ] ~ g ) h a c - 2 * & % b } ", +" . b i & * 2 - c a ' ' ~ { j ^ _ < [ 7 9 e f f k l m m n o p p n m m l k f f e 9 7 [ < _ ^ j ~ ~ q ' a c - 2 * & i } ", +" . r s * = - c a ' q t u ^ / : [ 6 8 e f k m n v v w x y z A y y x w v v n m k f e 8 6 [ : / B u ~ q ' a c - = * s } ", +" . s C = - ; a ' q ~ t u ( < [ 7 e f k m v D x E F G H I J K I I H G F E x D v m k f e 7 [ < L u { ~ q ' a ; - = C } ", +" . 1 M N ; a h q ~ { B u < O 8 e f m v w y F H I P Q R R S T U R R Q P I H F y w v m f e 8 O L u ^ { ~ q h a ; N M } ", +" . * 2 V > 4 ) ~ { ^ L W 6 9 X k m v y F I P Q Y Z Z ` ` S .` ` ` Z Z Y Q P I F y v m k X 9 L W ( ^ { ~ ) 4 > V 2 } ", +" . = - c , ' ! { ^ ( L W 0 f l p w E H P R Z Z ` ..+.@.@.#. .$.@.@.+...` Z Z R P H E w p l f %.W < ( ^ { ! ' , c - } ", +" . &.; a ' ! ~ j / < L W f l v w F I Q Y *.=.+.$.-.;.>.>.#.,.'.>.>.;.-.$.+.=.*.Y Q I F w v l %.W O < / j ~ ! ' a ; } ", +" . - > 4 ) ~ ] ^ : [ ).W l v x G I R Z ` +.$.-.>.!.~.{.].^.,.].].{.~.!.>.-.$.+.` Z R I G x v /.W 8 [ : ^ ] ~ ) 4 > } ", +" . ; a ' ! { ^ _ [ 7 %.(.p w G I R Z =.@.-.>.!.{.]._.:.<.[.}.<.<.:._.].{.!.>.-.@.=.Z R I G w z (.e 7 [ _ ^ { ! ' a } ", +" . > 4 q ~ ] / < 6 e %.|.w F I R Z ..$.>.!.{.].:.<.1.1.2.[.3.2.2.1.1.<.:.].{.!.>.$...Z R I F z |.f e 6 < / ] ~ q 4 } ", +" . a ' ! { ^ : [ 8 f /.A E I R Z ..4.>.!.].:.5.1.2.6.7.7.8.9.7.7.7.6.2.1.5.:.].!.>.4...Z R I J A m f 8 [ : ^ { ! ' } ", +" . , ) ~ ] / < 7 e k z A H Q Z =.$.>.~.].<.1.2.6.7.0.a.b.c.d.b.b.a.0.7.6.2.1.<.].~.>.$.=.Z Q J A v k e 7 < / ] ~ ) } ", +" . ' ! e.^ _ [ 9 f m z K P Y ` @.>.!.].<.1.f.7.0.b.g.h.i.j.k.l.i.h.g.b.0.7.f.1.<.].!.>.@.` Y m.K w m f 9 [ _ ^ e.! } ", +" . ' ~ ] / < 6 e k v z K R *.+.-.!.].<.1.f.7.a.g.h.l.n.n.j.o.p.n.n.l.h.g.a.7.f.1.<.].!.-.+.*.m.K y v k e 6 < / ] ~ } ", +" . ) ~ j ( 5 7 f m D J K Z =.$.>.{.:.1.f.7.b.q.l.n.p.r.s.t.o.u.s.r.p.n.l.q.b.7.f.1.:.{.>.$.=.S K F D m f 7 5 ( j ~ } ", +" . ! e.^ _ [ 0 f n x J T Z +.-.!.].5.2.7.a.q.l.n.r.u.v.w.x.y.w.w.v.u.r.n.l.q.a.7.2.5.].!.-.+.S T H x n f 0 [ _ ^ e.} ", +" . ! { ^ : 6 e k v E J T ` $.>.{.:.1.6.0.g.l.n.r.z.w.A.B.x.C.B.B.A.w.z.r.n.l.g.0.6.1.:.{.>.$.S T I E v k e 6 : ^ { } ", +" . ~ ] / < 7 e l v F m.T ..-.!.].<.2.7.b.h.n.r.z.w.D.E.F.G.C.H.F.E.D.w.z.r.n.h.b.7.2.<.].!.-.I.T P F v l e 7 < / ] } ", +" . ~ ] ( < 7 f m w G m.T +.;.~._.1.6.0.g.l.p.u.w.D.J.K.L.M.N.O.L.K.J.D.w.u.p.l.g.0.6.1._.~.;.I.T Q G w m f 7 < ( ] } ", +" . ~ j ( [ 8 f m x H m. .@.>.{.:.1.7.a.h.n.r.v.A.E.K.P.Q.R.S.T.Q.P.K.E.A.v.r.n.h.a.7.1.:.{.>.#. .R H x m f 8 [ ( j } ", +" . ~ ^ _ [ 9 f n y I m. .@.>.].<.2.7.b.i.n.s.w.B.F.L.Q.U.R.V.W.U.Q.L.F.B.w.s.n.i.b.7.2.<.].>.#. .R I y n f 9 [ _ ^ } ", +" . ~ ^ _ [ 0 f p y I S .$.'.].<.2.7.b.l.p.u.w.B.H.O.T.W.R.V.X.W.T.O.H.B.w.u.p.l.b.7.2.<.].'.#. .U I y p f 0 [ _ ^ } ", +" . e.^ _ [ 0 f p y I S .$.'.].<.2.Y.Z.l.p.z.w.B.K.O.T.`. +.+++`.T.O.K.B.w.z.p.l.Z.Y.2.<.].'.#. .U I y p f 0 [ _ ^ } ", +" . ~ ^ _ [ 0 f p y I S .$.'.].<.2.7.b.l.p.u.w.B.H.O.T.W.R.V.X.W.T.O.H.B.w.u.p.l.b.7.2.<.].'.#. .U I y p f 0 [ _ ^ } ", +" . ~ ^ _ [ 9 f n y I m. .@.>.].<.2.7.b.i.n.s.w.B.F.L.Q.U.R.V.W.U.Q.L.F.B.w.s.n.i.b.7.2.<.].>.#. .R I y n f 9 [ _ ^ } ", +" . ~ j ( [ 8 f m x H m. .@.>.{.:.1.7.a.h.n.r.v.A.E.K.P.Q.R.S.T.Q.P.K.E.A.v.r.n.h.a.7.1.:.{.>.#. .R H x m f 8 [ ( j } ", +" . ~ ] ( < 7 f m w G m.T +.;.~._.1.6.0.g.l.p.u.w.D.J.K.L.M.N.O.L.K.J.D.w.u.p.l.g.0.6.1._.~.;.I.T Q G w m f 7 < ( ] } ", +" . ~ ] / < 7 e l v F m.T ..-.!.].<.2.7.b.h.n.r.z.w.D.E.F.G.C.H.F.E.D.w.z.r.n.h.b.7.2.<.].!.-.I.T P F v l e 7 < / ] } ", +" . ! { ^ : 6 e k v E J T ` $.>.{.:.1.6.0.g.l.n.r.z.w.A.B.x.C.B.B.A.w.z.r.n.l.g.0.6.1.:.{.>.$.S T I E v k e 6 : ^ { } ", +" . ! e.^ _ [ 0 f n x J T Z +.-.!.].5.2.7.a.q.l.n.r.u.v.w.x.y.w.w.v.u.r.n.l.q.a.7.2.5.].!.-.+.S T H x n f 0 [ _ ^ e.} ", +" . ) ~ j ( 5 7 f m D J K Z =.$.>.{.:.1.f.7.b.q.l.n.p.r.s.t.o.u.s.r.p.n.l.q.b.7.f.1.:.{.>.$.=.S K F D m f 7 5 ( j ~ } ", +" . ' ~ ] / < 6 e k v z K R *.+.-.!.].<.1.f.7.a.g.h.l.n.n.j.o.p.n.n.l.h.g.a.7.f.1.<.].!.-.+.*.m.K y v k e 6 < / ] ~ } ", +" . ' ! e.^ _ [ 9 f m z K P Y ` @.>.!.].<.1.f.7.0.b.g.h.i.j.k.l.i.h.g.b.0.7.f.1.<.].!.>.@.` Y m.K w m f 9 [ _ ^ e.! } ", +" . , ) ~ ] / < 7 e k z A H Q Z =.$.>.~.].<.1.2.6.7.0.a.b.c.d.b.b.a.0.7.6.2.1.<.].~.>.$.=.Z Q J A v k e 7 < / ] ~ ) } ", +" . a ' ! { ^ : [ 8 f /.A E I R Z ..4.>.!.].:.5.1.2.6.7.7.8.9.7.7.7.6.2.1.5.:.].!.>.4...Z R I J A m f 8 [ : ^ { ! ' } ", +" . > 4 q ~ ] / < 6 e %.|.w F I R Z ..$.>.!.{.].:.<.1.1.2.[.3.2.2.1.1.<.:.].{.!.>.$...Z R I F z |.f e 6 < / ] ~ q 4 } ", +" . ; a ' ! { ^ _ [ 7 %.(.p w G I R Z =.@.-.>.!.{.]._.:.<.[.}.<.<.:._.].{.!.>.-.@.=.Z R I G w z (.e 7 [ _ ^ { ! ' a } ", +" . - > 4 ) ~ ] ^ : [ ).W l v x G I R Z ` +.$.-.>.!.~.{.].^.,.].].{.~.!.>.-.$.+.` Z R I G x v /.W 8 [ : ^ ] ~ ) 4 > } ", +" . &.; a ' ! ~ j / < L W f l v w F I Q Y *.=.+.$.-.;.>.>.#.,.'.>.>.;.-.$.+.=.*.Y Q I F w v l %.W O < / j ~ ! ' a ; } ", +" . = - c , ' ! { ^ ( L W 0 f l p w E H P R Z Z ` ..+.@.@.#. .$.@.@.+...` Z Z R P H E w p l f %.W < ( ^ { ! ' , c - } ", +" . * 2 V > 4 ) ~ { ^ L W 6 9 X k m v y F I P Q Y Z Z ` ` S .` ` ` Z Z Y Q P I F y v m k X 9 L W ( ^ { ~ ) 4 > V 2 } ", +" . 1 M N ; a h q ~ { B u < O 8 e f m v w y F H I P Q R R S T U R R Q P I H F y w v m f e 8 O L u ^ { ~ q h a ; N M } ", +" . s C = - ; a ' q ~ t u ( < [ 7 e f k m v D x E F G H I J K I I H G F E x D v m k f e 7 [ < L u { ~ q ' a ; - = C } ", +" . r s * = - c a ' q t u ^ / : [ 6 8 e f k m n v v w x y z A y y x w v v n m k f e 8 6 [ : / B u ~ q ' a c - = * s } ", +" . b i & * 2 - c a ' @+#+{ j ^ _ < [ 7 9 e f f k l m m n z |.p n m m l k f f e 9 7 [ < _ ^ j t #+q ' a c - 2 * & i } ", +" . | b % & * 2 - c a d ) ! ~ ] ^ / : < [ 6 7 0 e e f f f e f f f f f e e 0 7 6 [ < : / ^ ] ~ g ) h a c - 2 * & % b } ", +" . @ | $ % 1 * 2 - ; 3 4 ' ! ~ { ] ^ / _ < 5 [ 6 7 7 8 9 7 0 0 9 8 7 7 6 [ 5 < _ / ^ ] { ~ ! , 4 a ; - 2 * 1 % $ | } ", +" . + @ # $ % & * = - $+> , ' ) ! ~ { ] ^ / ( _ : < < [ [ %+[ [ [ [ < < : _ ( / ^ ] { ~ ! ) ' a > ; - = * & % $ # @ } ", +" . &++ @ # $ % & * = N V c a 4 ' q ! ~ e.] j ^ ^ / ( ( _ _ _ _ _ ( ( / ^ ^ j ] e.~ ! q ' 4 a c V N = * & % $ # @ + } ", +" . } } } } } } } } } } } } } } } } } } } } } } } } } } } } } } } } } } } } } } } } } } } } } } } } } } } } } } } } } ", +" *+ *+ *+ *+ *+ *+*+*+ *+*+*+ ", +" *+*+ *+*+ *+ *+ *+ *+ *+ *+ *+*+*+*+ ", +" *+ *+ *+ *+ *+*+ *+*+*+ *+*+*+ *+=+=+=+ ", +" *+ *+ *+ *+ *+ *+ *+ *+ *+=+=+=+ ", +" *+ *+ *+ *+ *+ *+*+*+ *+ *+ ", +" ", +" "}; diff --git a/AlsaMixer.app/skins/default/mutebutton.xpm b/AlsaMixer.app/skins/default/mutebutton.xpm new file mode 100644 index 0000000..cce72e0 --- /dev/null +++ b/AlsaMixer.app/skins/default/mutebutton.xpm @@ -0,0 +1,30 @@ +/* XPM */ +static char * mutebutton_xpm[] = { +"16 9 18 1", +" c None", +". c #B7BAC7", +"+ c #848694", +"@ c #838593", +"# c #828392", +"$ c #808290", +"% c #7F818F", +"& c #7E808E", +"* c #7C7E8C", +"= c #7B7D8B", +"- c #7A7C8A", +"; c #787A88", +"> c #777987", +", c #767886", +"' c #747784", +") c #737583", +"! c #000000", +"~ c #FF0000", +"................", +".+@#$%&*=-;>,')!", +".!!!!!!!!!!!!!!!", +"...............!", +".+@#$%&*=-;>,')!", +".!!!!!!!!!!!!!!!", +"...........!~~~!", +".+@#$%&*=-;!~~~!", +".!!!!!!!!!!!!!!!"}; diff --git a/AlsaMixer.app/skins/default/redlight.xpm b/AlsaMixer.app/skins/default/redlight.xpm new file mode 100644 index 0000000..0e3791b --- /dev/null +++ b/AlsaMixer.app/skins/default/redlight.xpm @@ -0,0 +1,7 @@ +/* XPM */ +static char * redlight_xpm[] = { +"3 2 2 1", +" c None", +". c #FF0000", +"...", +"..."}; -- 2.11.4.GIT