1
0
mirror of https://github.com/gryf/wmamixer.git synced 2025-12-17 19:40:24 +01:00

Implemeneted read functions

This commit is contained in:
2015-01-27 20:16:30 +01:00
parent 633be48a34
commit 64897e201e
2 changed files with 563 additions and 279 deletions

View File

@@ -11,7 +11,7 @@
#include "wmamixer.h"
// global mixer struct
struct Mixer *mixer_ctrl;
struct Mixer *mix;
int main(int argc, char **argv) {
int i;
@@ -32,6 +32,15 @@ int main(int argc, char **argv) {
scanArgs(argc, argv);
initXWin(argc, argv);
gcm = GCGraphicsExposures;
gcv.graphics_exposures = false;
gc_gc = XCreateGC(d_display, w_root, gcm, &gcv);
color[0] = mixColor(ledcolor, 0, backcolor, 100);
color[1] = mixColor(ledcolor, 100, backcolor, 0);
color[2] = mixColor(ledcolor, 60, backcolor, 40);
color[3] = mixColor(ledcolor, 25, backcolor, 75);
xpmattr.numsymbols = 4;
xpmattr.colorsymbols = xpmcsym;
xpmattr.exactColors = false;
@@ -50,15 +59,6 @@ int main(int argc, char **argv) {
pm_disp = XCreatePixmap(d_display, w_root, 64, 64, DefaultDepth(d_display,
DefaultScreen(d_display)));
gcm = GCGraphicsExposures;
gcv.graphics_exposures = false;
gc_gc = XCreateGC(d_display, w_root, gcm, &gcv);
color[0] = mixColor(ledcolor, 0, backcolor, 100);
color[1] = mixColor(ledcolor, 100, backcolor, 0);
color[2] = mixColor(ledcolor, 60, backcolor, 40);
color[3] = mixColor(ledcolor, 25, backcolor, 75);
if (wmaker || ushape || astep) {
XShapeCombineMask(d_display, w_activewin, ShapeBounding, winsize/2-32,
winsize/2-32, pm_mask, ShapeSet);
@@ -70,25 +70,11 @@ int main(int argc, char **argv) {
XCopyArea(d_display, pm_main, pm_disp, gc_gc, 0, 0, 64, 64, 0, 0);
XSetClipMask(d_display, gc_gc, None);
mixer_ctrl = Mixer_create(mixer_device);
if (mixer_ctrl->openOK != 0) {
fprintf(stderr, "%s : Unable to open mixer device '%s'.\n", NAME,
mixer_device);
} else {
for (i=0; i <mixer_ctrl->devices_no; i++) {
if (i > 24) {
fprintf(stderr,"%s : Sorry, can only use channels 0-24\n", NAME);
break;
}
channel[channels] = i;
channels++;
}
}
mix = Mixer_create(card);
readFile();
if (channels==0)
if (mix->devices_no == 0)
fprintf(stderr,"%s: Sorry, no supported channels found.\n", NAME);
else {
checkVol(true);
@@ -129,8 +115,8 @@ int main(int argc, char **argv) {
else
curchannel--;
if (curchannel < 0)
curchannel = channels - 1;
if (curchannel >= channels)
curchannel = mix->devices_no - 1;
if (curchannel >= mix->devices_no)
curchannel = 0;
checkVol(true);
rpttimer = 0;
@@ -163,19 +149,290 @@ int main(int argc, char **argv) {
XFreePixmap(d_display, pm_digits);
XFreePixmap(d_display, pm_chars);
freeXWin();
Mixer_destroy(mixer_ctrl);
Mixer_destroy(mix);
return 0;
}
/* Mixer struct support functions */
struct Mixer *Mixer_create(char *device) {
struct Mixer *mixer_ctrl = malloc(sizeof(struct Mixer));
assert(mixer_ctrl != NULL);
mixer_ctrl->openOK = 0;
mixer_ctrl->devices_no = 0;
mixer_ctrl->devices_no = 0;
return mixer_ctrl;
struct Mixer *Mixer_create(char *devicename) {
struct Mixer *mixer = malloc(sizeof(struct Mixer));
int err;
const char *name;
slideCaptureMono capabilities;
snd_mixer_selem_id_t *sid;
snd_mixer_elem_t *elem;
snd_mixer_selem_id_alloca(&sid);
assert(mixer != NULL);
mixer->devices_no = 0;
if ((err = snd_mixer_open(&mixer->handle, 0)) < 0) {
fprintf(stderr, "Mixer %s open error: %s", card, snd_strerror(err));
exit(err);
}
if (smixer_level == 0 &&
(err = snd_mixer_attach(mixer->handle, card)) < 0) {
fprintf(stderr, "Mixer attach %s error: %s", card, snd_strerror(err));
snd_mixer_close(mixer->handle);
exit(err);
}
if ((err = snd_mixer_selem_register(mixer->handle,
smixer_level > 0 ? &smixer_options : NULL, NULL)) < 0) {
fprintf(stderr, "Mixer register error: %s", snd_strerror(err));
snd_mixer_close(mixer->handle);
exit(err);
}
err = snd_mixer_load(mixer->handle);
if (err < 0) {
fprintf(stderr, "Mixer %s load error: %s", card, snd_strerror(err));
snd_mixer_close(mixer->handle);
exit(err);
}
for (elem = snd_mixer_first_elem(mixer->handle); elem;
elem = snd_mixer_elem_next(elem)) {
snd_mixer_selem_get_id(elem, sid);
if (!snd_mixer_selem_is_active(elem))
continue;
capabilities = Mixer_getcapabilities(elem);
if (!capabilities.isvolume)
continue;
name = snd_mixer_selem_id_get_name(sid);
printf("DEBUG: capabilities cap: %d\n", capabilities.capture);
selems[mixer->devices_no] = malloc(sizeof(struct Selem));
selems[mixer->devices_no]->elem = elem;
selems[mixer->devices_no]->capture = capabilities.capture;
Mixer_set_limits(elem, selems[mixer->devices_no]);
Mixer_set_selem_props(selems[mixer->devices_no], name);
mixer->devices_no++;
printf("DEBUG: Simple mixer control '%s',%i\n", snd_mixer_selem_id_get_name(sid), snd_mixer_selem_id_get_index(sid));
if (mixer->devices_no == 32) {
// stop here. This is ridiculous anyway
break;
}
}
return mixer;
}
/* Guess and return short name for the mixer simple element */
void Mixer_set_selem_props(struct Selem *selem, const char *name) {
const char *pcm = "PCM",
*mic = "Mic",
*cap = "Capture",
*boost = "Boost",
*line = "Line";
snd_mixer_selem_channel_id_t chn;
char variable[4];
int idx;
// Get the name. Simple match.
if (strcmp("Master", name) == 0) {
selem->name = "mstr";
} else if (strstr(pcm, name)) {
selem->iconIndex = 1;
if (strcmp(pcm, name) == 0) {
selem->name = "pcm ";
} else {
sprintf(variable, "pcm%d", namesCount.pcm);
selem->name = variable;
namesCount.pcm++;
}
} else if (strstr("Headphone", name)) {
selem->name = "hdph";
selem->iconIndex = 8;
} else if (strstr("Beep", name)) {
selem->name = "beep";
selem->iconIndex = 7;
} else if (strstr("Digital", name)) {
selem->iconIndex = selem->capture ? 3 : 6;
selem->name = "digt";
} else if (strstr(mic, name)) {
if (strcmp(mic, name) == 0) {
selem->name = "mic ";
} else {
if (strstr(boost, name)) {
sprintf(variable, "mib%d", namesCount.micb);
namesCount.micb++;
} else {
sprintf(variable, "mib%d", namesCount.mic);
namesCount.mic++;
}
selem->name = variable;
}
selem->iconIndex = 4;
} else if (strstr(line, name)) {
if (strcmp(line, name) == 0) {
selem->name = "line";
} else {
if (strstr(boost, name)) {
sprintf(variable, "lnb%d", namesCount.lineb);
namesCount.lineb++;
} else {
sprintf(variable, "lin%d", namesCount.line);
namesCount.line++;
}
selem->name = variable;
}
selem->iconIndex = 5;
} else if (strstr(cap, name)) {
if (strcmp(cap, name) == 0) {
selem->name = "cap ";
} else {
sprintf(variable, "cap%d", namesCount.capt);
selem->name = variable;
namesCount.capt++;
}
selem->iconIndex = 3;
} else {
/* defaults */
sprintf(variable, "vol%d", namesCount.vol);
selem->name = variable;
namesCount.pcm++;
selem->iconIndex = 6;
}
if (snd_mixer_selem_has_playback_volume(selem->elem)) {
if (snd_mixer_selem_is_playback_mono(selem->elem)) {
printf("DEBUG: playback mono\n");
selem->stereo = false;
selem->channels[0] = SND_MIXER_SCHN_MONO;
selem->channels[1] = SND_MIXER_SCHN_MONO;
} else {
printf("DEBUG: playback stereo\n");
idx = 0;
for (chn = 0; chn <= SND_MIXER_SCHN_LAST; chn++){
if (!snd_mixer_selem_has_playback_channel(selem->elem, chn))
continue;
selem->channels[idx] = chn;
idx++;
if (idx == 2)
break;
}
}
}
if (snd_mixer_selem_has_capture_volume(selem->elem)) {
printf("Capture channels: ");
if (snd_mixer_selem_is_capture_mono(selem->elem)) {
printf("DEBUG: playback mono\n");
selem->stereo = false;
selem->channels[0] = SND_MIXER_SCHN_MONO;
selem->channels[1] = SND_MIXER_SCHN_MONO;
} else {
idx = 0;
for (chn = 0; chn <= SND_MIXER_SCHN_LAST; chn++){
if (!snd_mixer_selem_has_capture_channel(selem->elem, chn))
continue;
selem->channels[idx] = chn;
idx++;
if (idx == 2)
break;
}
}
}
}
slideCaptureMono Mixer_getcapabilities(snd_mixer_elem_t *elem) {
slideCaptureMono retval;
retval.mono = false;
retval.capture = false;
retval.isvolume = false;
if (snd_mixer_selem_has_common_volume(elem)) {
retval.isvolume = true;
if (snd_mixer_selem_has_playback_volume_joined(elem) ||
snd_mixer_selem_is_playback_mono(elem) )
retval.mono = true;
} else {
if (snd_mixer_selem_has_playback_volume(elem)) {
retval.isvolume = true;
if (snd_mixer_selem_has_playback_volume_joined(elem) ||
snd_mixer_selem_is_playback_mono(elem))
retval.mono = true;
}
if (snd_mixer_selem_has_capture_volume(elem)) {
retval.isvolume = true;
retval.capture = true;
if (snd_mixer_selem_has_capture_volume_joined(elem) ||
snd_mixer_selem_is_playback_mono(elem))
retval.mono = true;
}
}
return retval;
}
void Mixer_set_limits(snd_mixer_elem_t *elem, struct Selem *selem) {
long min = 0, max = 0;
if (snd_mixer_selem_has_common_volume(elem)) {
snd_mixer_selem_get_playback_volume_range(elem, &min, &max);
} else {
if (snd_mixer_selem_has_capture_volume(elem))
snd_mixer_selem_get_capture_volume_range(elem, &min, &max);
if (snd_mixer_selem_has_playback_volume(elem))
snd_mixer_selem_get_playback_volume_range(elem, &min, &max);
}
selem->min = min;
selem->max = max;
}
static int convert_prange(long val, long min, long max) {
long range = max - min;
int tmp;
if (range == 0)
return 0;
val -= min;
tmp = rint((double)val/(double)range * 100);
return tmp;
}
/*
vol_ops = [
{"has_volume": snd_mixer_selem_has_playback_volume,
"v": [
[snd_mixer_selem_get_playback_volume_range,
snd_mixer_selem_get_playback_volume,
set_playback_raw_volume],
[snd_mixer_selem_get_playback_dB_range,
snd_mixer_selem_get_playback_dB,
set_playback_dB],
[get_mapped_volume_range,
get_playback_mapped_volume,
set_playback_mapped_volume]]
},
// capt
{...}
]
*/
long get_volume(snd_mixer_elem_t *elem,
snd_mixer_selem_channel_id_t chn,
long min, long max, bool capt) {
long raw;
int volume;
if (!capt) {
snd_mixer_selem_get_playback_volume(elem, chn, &raw);
} else {
snd_mixer_selem_get_capture_volume(elem, chn, &raw);
}
volume = convert_prange(raw, min, max);
return volume;
}
void Mixer_set_left(int current, int value) {
@@ -188,25 +445,25 @@ void Mixer_write_volume(int current) {
}
int Mixer_read_left(int current) {
return 50;
struct Selem *selem = selems[current];
return get_volume(selem->elem, selem->channels[0],
selem->min, selem->max, selem->capture);
}
int Mixer_read_right(int current) {
struct Selem *selem = selems[current];
return get_volume(selem->elem, selem->channels[1],
selem->min, selem->max, selem->capture);
}
int Mixer_read_volume(int current, bool read) {
return 50;
}
int Mixer_read_volume(int channel, bool read) {
return 50;
}
bool Mixer_get_stereo(int channel) {
return true;
}
void Mixer_destroy(struct Mixer *mix) {
assert(mix != NULL);
//free(mix->name);
free(mix);
void Mixer_destroy(struct Mixer *mixer) {
assert(mixer != NULL);
snd_mixer_close(mixer->handle);
free(mixer);
}
void initXWin(int argc, char **argv)
@@ -279,18 +536,6 @@ void createWin(Window *win, int x, int y)
XSetClassHint(d_display, *win, &classHint);
}
unsigned long getColor(char *colorname)
{
XColor color;
XWindowAttributes winattr;
XGetWindowAttributes(d_display, w_root, &winattr);
color.pixel=0;
XParseColor(d_display, winattr.colormap, colorname, &color);
color.flags=DoRed | DoGreen | DoBlue;
XAllocColor(d_display, winattr.colormap, &color);
return color.pixel;
}
unsigned long mixColor(char *colorname1, int prop1, char *colorname2, int prop2)
{
XColor color, color1, color2;
@@ -309,54 +554,86 @@ unsigned long mixColor(char *colorname1, int prop1, char *colorname2, int prop2)
void scanArgs(int argc, char **argv) {
int i;
for (i = 1; i < argc; i++) {
if (strcmp(argv[i], "-h") == 0 || strcmp(argv[i], "--help") == 0) {
usage();
exit(0);
}
if (strcmp(argv[i], "-v") == 0 || strcmp(argv[i], "--version") == 0) {
fprintf(stderr, "wmsmixer version %s\n", VERSION);
fprintf(stderr, "%s version %s\n", NAME, VERSION);
exit(0);
}
if (strcmp(argv[i], "-w") == 0)
wmaker = !wmaker;
if (strcmp(argv[i], "-s") == 0)
ushape = !ushape;
if (strcmp(argv[i], "-a") == 0)
astep = !astep;
if (strcmp(argv[i], "-novol") == 0)
no_volume_display = 1;
if (strcmp(argv[i], "-d") == 0) {
if (i < argc - 1) {
i++;
sprintf(mixer_device, "%s", argv[i]);
if (strlen(argv[i]) > 255) {
fprintf(stderr, "%s: Illegal device name.\n", NAME);
exit(1);
}
sprintf(card, "%s", argv[i]);
smixer_options.device = card;
}
continue;
}
if (strcmp(argv[i], "-l") == 0) {
if ( i < argc - 1) {
i++;
if (strlen(argv[i]) > 255) {
fprintf(stderr, "%s: Illegal color name.\n", NAME);
exit(1);
}
sprintf(ledcolor, "%s", argv[i]);
}
continue;
}
if (strcmp(argv[i], "-b") == 0) {
if (i < argc - 1) {
i++;
if (strlen(argv[i]) > 255) {
fprintf(stderr, "%s: Illegal color name.\n", NAME);
exit(1);
}
sprintf(backcolor, "%s", argv[i]);
}
continue;
}
if (strcmp(argv[i], "-position") == 0) {
if (i < argc - 1) {
i++;
if (strlen(argv[i]) > 255) {
fprintf(stderr, "%s: Illegal position.\n", NAME);
exit(1);
}
sprintf(position, "%s", argv[i]);
}
continue;
}
if (strcmp(argv[i], "-display") == 0) {
if (i < argc - 1) {
i++;
if (strlen(argv[i]) > 255) {
fprintf(stderr, "%s: Illegal display name.\n", NAME);
exit(1);
}
sprintf(display, "%s", argv[i]);
}
continue;
@@ -366,10 +643,8 @@ void scanArgs(int argc, char **argv) {
void readFile() {
FILE *rcfile;
char buf[256];
int done;
int current=-1;
char *confpath;
int done, current = -1;
char *confpath, buf[256];
if (getenv("XDG_CONFIG_HOME")) {
confpath = malloc(snprintf(NULL, 0, "%s%s", getenv("XDG_CONFIG_HOME"),
@@ -382,56 +657,32 @@ void readFile() {
}
if(access(confpath, 0) != 0) {
printf("no conf file\n");
fprintf(stderr, "%s: No config file found.\n", NAME);
free(confpath);
return;
}
if ((rcfile = fopen(confpath, "r")) == NULL) {
printf("cannot open conf file\n");
fprintf(stderr, "%s: Cannot open config file. Using defaults.\n",
NAME);
free(confpath);
return;
}
channels=0;
do {
fgets(buf, 250, rcfile);
if ((done=feof(rcfile)) == 0) {
buf[strlen(buf) - 1] = 0;
if (strncmp(buf, "addchannel ", strlen("addchannel ")) == 0) {
sscanf(buf, "addchannel %i", &current);
if (current >= mixer_ctrl->devices_no ) {
fprintf(stderr, "%s : Sorry, this channel (%i) is "
"not supported.\n", NAME, current);
current = -1;
}
else{
channel[channels]=current;
channels++;
}
}
if (strncmp(buf, "setchannel ", strlen("setchannel ")) == 0) {
sscanf(buf, "setchannel %i", &current);
if (current >= mixer_ctrl->devices_no ) {
if (current >= mix->devices_no ) {
fprintf(stderr,"%s: Sorry, this channel (%i) is "
"not supported.\n", NAME, current);
current = -1;
}
}
if (strncmp(buf, "setname ", strlen("setname ")) == 0) {
if (current == -1) {
fprintf(stderr, "%s : Sorry, no current channel.\n",
NAME);
} else {
small_labels[current] = (char *) malloc(sizeof(char) *
5);
sscanf(buf, "setname %4s", small_labels[current]);
}
}
if (strncmp(buf, "setmono ", strlen("setmono ")) == 0) {
if (current == -1) {
fprintf(stderr,"%s: Sorry, no current channel.\n",
@@ -475,9 +726,9 @@ void readFile() {
}
void checkVol(bool forced) {
Mixer_read_volume(channel[curchannel], true);
int nl = Mixer_read_left(channel[curchannel]);
int nr = Mixer_read_right(channel[curchannel]);
Mixer_read_volume(curchannel, true);
int nl = Mixer_read_left(curchannel);
int nr = Mixer_read_right(curchannel);
if (forced ) {
curleft=nl;
curright=nr;
@@ -488,14 +739,14 @@ void checkVol(bool forced) {
if (nl!=curleft || nr!=curright ) {
if (nl!=curleft ) {
curleft=nl;
if (Mixer_get_stereo(channel[curchannel]))
if (selems[curchannel]->stereo)
drawLeft();
else
drawMono();
}
if (nr!=curright ) {
curright=nr;
if (Mixer_get_stereo(channel[curchannel]))
if (selems[curchannel]->stereo)
drawRight();
else
drawMono();
@@ -507,29 +758,34 @@ void checkVol(bool forced) {
}
}
void pressEvent(XButtonEvent *xev)
{
if (xev->button == Button4 || xev->button == Button5) {
int inc;
if (xev->button == Button4) inc = 4;
else inc = -4;
void pressEvent(XButtonEvent *xev) {
int inc, x, y, v;
Mixer_read_volume(channel[curchannel], false);
Mixer_set_left(channel[curchannel],
CLAMP(Mixer_read_left(channel[curchannel]) + inc, 0, 100));
Mixer_set_right(channel[curchannel],
CLAMP(Mixer_read_right(channel[curchannel]) + inc, 0, 100));
Mixer_write_volume(channel[curchannel]);
if (xev->button == Button4 || xev->button == Button5) {
if (xev->button == Button4) {
printf("inc\n");
inc = 4;
} else {
printf("dec\n");
inc = -4;
}
Mixer_read_volume(curchannel, false);
Mixer_set_left(curchannel,
CLAMP(Mixer_read_left(curchannel) + inc, 0, 100));
Mixer_set_right(curchannel,
CLAMP(Mixer_read_right(curchannel) + inc, 0, 100));
Mixer_write_volume(curchannel);
checkVol(false);
return;
}
int x=xev->x-(winsize/2-32);
int y=xev->y-(winsize/2-32);
x = xev->x - (winsize / 2 - 32);
y = xev->y - (winsize / 2 - 32);
if (x >= 5 && y >= 47 && x <= 17 && y <= 57) {
curchannel--;
if (curchannel < 0)
curchannel=channels-1;
curchannel = mix->devices_no -1;
btnstate |= BTNPREV;
rpttimer = 0;
drawBtns(BTNPREV);
@@ -538,7 +794,7 @@ void pressEvent(XButtonEvent *xev)
}
if (x >= 18 && y >= 47 && x <= 30 && y <= 57) {
curchannel++;
if (curchannel>=channels)
if (curchannel >= mix->devices_no)
curchannel = 0;
btnstate|=BTNNEXT;
rpttimer = 0;
@@ -547,21 +803,20 @@ void pressEvent(XButtonEvent *xev)
return;
}
if (x >= 37 && x <= 56 && y >= 8 && y <= 56) {
int v=((60-y)*100)/(2*25);
v = ((60 - y) * 100) / (2 * 25);
dragging = true;
if (x <= 50)
Mixer_set_left(channel[curchannel], v);
Mixer_set_left(curchannel, v);
if (x >= 45)
Mixer_set_right(channel[curchannel], v);
Mixer_write_volume(channel[curchannel]);
Mixer_set_right(curchannel, v);
Mixer_write_volume(curchannel);
checkVol(false);
return;
}
if (x >= 5 && y >= 21 && x <= 30 && y <= 42) {
drawText(small_labels[channel[curchannel]]);
drawText(selems[curchannel]->name);
return;
}
}
void releaseEvent() {
@@ -580,10 +835,10 @@ void motionEvent(XMotionEvent *xev)
if (v<0)
v=0;
if (x<=50)
Mixer_set_left(channel[curchannel], v);
Mixer_set_left(curchannel, v);
if (x>=45)
Mixer_set_right(channel[curchannel], v);
Mixer_write_volume(channel[curchannel]);
Mixer_set_right(curchannel, v);
Mixer_write_volume(curchannel);
checkVol(false);
}
}
@@ -595,22 +850,20 @@ void repaint()
while(XCheckTypedEvent(d_display, Expose, &xev));
}
void update()
{
drawText(small_labels[channel[curchannel]]);
void update() {
drawText(selems[curchannel]->name);
XCopyArea(d_display, pm_icon, pm_disp, gc_gc, icon[channel[curchannel]]*26, 0, 26, 24, 5, 19);
if (Mixer_get_stereo(channel[curchannel])) {
XCopyArea(d_display, pm_icon, pm_disp, gc_gc,
selems[curchannel]->iconIndex * 26, 0, 26, 24, 5, 19);
if (selems[curchannel]->stereo) {
drawLeft();
drawRight();
}
else {
} else {
drawMono();
}
}
void drawText(char *text)
{
void drawText(char *text) {
char *p = text;
char p2;
int i;
@@ -618,15 +871,16 @@ void drawText(char *text)
for (i = 0; i < 4; i++, p++) {
p2 = toupper(*p);
if (p2 >= 'A' && p2 <= 'Z') {
XCopyArea(d_display, pm_chars, pm_disp, gc_gc, 6*((int)p2-65), 0, 6, 9, 5+(i*6), 5);
}
else if (p2 >= '0' && p2 <= '9') {
XCopyArea(d_display, pm_digits, pm_disp, gc_gc, 6*((int)p2-48), 0, 6, 9, 5+(i*6), 5);
}
else {
XCopyArea(d_display, pm_chars, pm_disp, gc_gc,
6 * ((int)p2 - 65), 0, 6, 9, 5 + (i * 6), 5);
} else if (p2 >= '0' && p2 <= '9') {
XCopyArea(d_display, pm_digits, pm_disp, gc_gc,
6 * ((int)p2 - 48), 0, 6, 9, 5 + (i * 6), 5);
} else {
if (p2 == '\0')
p--;
XCopyArea(d_display, pm_digits, pm_disp, gc_gc, 60, 0, 6, 9, 5+(i*6), 5);
XCopyArea(d_display, pm_digits, pm_disp, gc_gc, 60, 0, 6, 9,
5 + (i * 6), 5);
}
}
if (!no_volume_display)
@@ -637,8 +891,7 @@ void drawVolLevel() {
int i;
int digits[4];
int vol = (Mixer_read_left(channel[curchannel]) +
Mixer_read_right(channel[curchannel])) / 2;
int vol = (Mixer_read_left(curchannel) + Mixer_read_right(curchannel)) / 2;
digits[0] = (vol/100) ? 1 : 10;
digits[1] = (vol/10) == 10 ? 0 : (vol/10);
@@ -730,7 +983,7 @@ See the README file for a more complete notice.\n\n", stdout);
-a use smaller window (for AfterStep Wharf)\n\
-l led_color use the specified color for led display\n\
-b back_color use the specified color for backgrounds\n\
-d mix_device use specified device (rather than /dev/mixer)\n\
-d alsa_device use specified device (rather than 'default')\n\
-position position set window position (see X manual pages)\n\
-display display select target display (see X manual pages)\n\n",
stdout);

View File

@@ -18,6 +18,7 @@
#include <ctype.h>
#include <stdbool.h>
#include <assert.h>
#include <math.h>
#include <X11/X.h>
#include <X11/Xlib.h>
@@ -46,6 +47,10 @@
#undef CLAMP
#define CLAMP(v, l, h) (((v) > (h)) ? (h) : (((v) < (l)) ? (l) : (v)))
/* Function to convert from percentage to volume. val = percentage */
#define convert_prange1(val, min, max) \
ceil((val) * ((max) - (min)) * 0.01 + (min))
// Pixmaps - standard
Pixmap pm_main;
@@ -77,7 +82,7 @@ int winsize;
bool no_volume_display = 0;
// Variables for command-line arguments - custom
char mixer_device[256] = "default";
char card[256] = "default";
char backcolor[256] = BACKCOLOR;
char ledcolor[256] = LEDCOLOR;
@@ -116,27 +121,49 @@ int rpttimer = 0;
// For draggable volume control
bool dragging = false;
int channels = 2;
int channel[25];
int icon[25] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17,
18, 19, 20, 21, 22, 23, 24};
char *small_labels[25] = {"vol ", "bass", "trbl", "synt", "pcm ",
"spkr", "line", "mic ", "cd ", "mix ", "pcm2", "rec ", "igai", "ogai",
"lin1", "lin2", "lin3", "dig1", "dig2", "dig3", "phin", "phou", "vid ",
"rad ", "mon "};
int channel[32];
int icon[9] = {0, 1, 2, 3, 4, 5, 6, 7, 8};
struct Selem {
char *name;
bool stereo;
int currentVolRight;
int currentVolLeft;
short int iconIndex;
snd_mixer_elem_t *elem;
long min;
long max;
bool capture;
snd_mixer_selem_channel_id_t channels[2];
};
typedef struct {
bool isvolume;
bool capture;
bool mono;
} slideCaptureMono;
struct NamesCount {
short int pcm, line, lineb, mic, micb, capt, vol;
} namesCount = {1, 1, 1, 1, 1, 1, 1};
struct Selem *selems[32];
struct Mixer {
int openOK;
int devices_no;
snd_mixer_t * handle;
void *elems[32];
};
static int smixer_level = 0;
static struct snd_mixer_selem_regopt smixer_options;
// Procedures and functions - standard
void initXWin(int argc, char **argv);
void freeXWin();
void createWin(Window *win, int x, int y);
unsigned long getColor(char *colorname);
unsigned long mixColor(char *colorname1, int prop1, char *colorname2,
int prop2);
unsigned long mixColor(char *color1, int prop1, char *color2, int prop2);
// Procedures and functions - custom
void scanArgs(int argc, char **argv);
@@ -156,14 +183,18 @@ void drawText(char *text);
void drawBtns(int btns);
void drawBtn(int x, int y, int w, int h, bool down);
struct Mixer *Mixer_create(char *device);
void Mixer_set_selem_props(struct Selem *selem, const char *name);
slideCaptureMono Mixer_getcapabilities(snd_mixer_elem_t *elem);
struct Mixer *Mixer_create(char *devicename);
void Mixer_set_left(int current, int value);
void Mixer_set_right(int current, int value);
void Mixer_write_volume(int current);
int Mixer_read_left(int current);
int Mixer_read_right(int current);
int Mixer_read_volume(int channel, bool read);
bool Mixer_get_stereo(int channel);
int Mixer_read_volume(int current, bool read);
void Mixer_set_limits(snd_mixer_elem_t *elem, struct Selem *selem);
void Mixer_destroy(struct Mixer *mix);