slstatus

Custom version of the Suckless status monitor
git clone git://git.danielmoch.com/slstatus.git
Log | Files | Refs | README | LICENSE

commit c1dc896c806693a4a368abf59e6890d32d520074
parent e724907cc37749907cb8c63031d9fb35ef46a657
Author: Ingo Feinerer <feinerer@logic.at>
Date:   Fri,  8 Feb 2019 15:37:17 +0100

Add native OpenBSD support for mute/volume

Based on functionality in dstat by Joerg Jung.

Diffstat:
MLICENSE | 2++
MREADME | 2+-
Mcomponents/volume.c | 118+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++------------------
Mconfig.mk | 1-
4 files changed, 94 insertions(+), 29 deletions(-)

diff --git a/LICENSE b/LICENSE @@ -18,6 +18,8 @@ Copyright 2018 Tobias Tschinkowitz <tobias@he4d.net> Copyright 2018 David Demelier <markand@malikania.fr> Copyright 2018-2019 Michael Buch <michaelbuch12@gmail.com> Copyright 2018 Ian Remmler <ian@remmler.org> +Copyright 2016-2019 Joerg Jung <jung@openbsd.org> +Copyright 2019 Ingo Feinerer <feinerer@logic.at> Permission to use, copy, modify, and/or distribute this software for any purpose with or without fee is hereby granted, provided that the above diff --git a/README b/README @@ -38,7 +38,7 @@ In order to build slstatus you need the Xlib header files. Installation ------------ Edit config.mk to match your local setup (slstatus is installed into the -/usr/local namespace by default). Uncomment OSSLIBS on OpenBSD. +/usr/local namespace by default). Afterwards enter the following command to build and install slstatus (if necessary as root): diff --git a/components/volume.c b/components/volume.c @@ -2,44 +2,108 @@ #include <fcntl.h> #include <stdio.h> #include <string.h> -#if defined(__OpenBSD__) - #include <soundcard.h> -#else - #include <sys/soundcard.h> -#endif #include <sys/ioctl.h> #include <unistd.h> #include "../util.h" -const char * -vol_perc(const char *card) -{ - size_t i; - int v, afd, devmask; - char *vnames[] = SOUND_DEVICE_NAMES; +#if defined(__OpenBSD__) + #include <sys/audioio.h> - if ((afd = open(card, O_RDONLY | O_NONBLOCK)) < 0) { - warn("open '%s':", card); - return NULL; - } + const char * + vol_perc(const char *card) + { + static int cls = -1; + mixer_devinfo_t mdi; + mixer_ctrl_t mc; + int afd = -1, m = -1, v = -1; - if (ioctl(afd, (int)SOUND_MIXER_READ_DEVMASK, &devmask) < 0) { - warn("ioctl 'SOUND_MIXER_READ_DEVMASK':"); - close(afd); - return NULL; - } - for (i = 0; i < LEN(vnames); i++) { - if (devmask & (1 << i) && !strcmp("vol", vnames[i])) { - if (ioctl(afd, MIXER_READ(i), &v) < 0) { - warn("ioctl 'MIXER_READ(%ld)':", i); + if ((afd = open(card, O_RDONLY)) < 0) { + warn("open '%s':", card); + return NULL; + } + + for (mdi.index = 0; cls == -1; mdi.index++) { + if (ioctl(afd, AUDIO_MIXER_DEVINFO, &mdi) < 0) { + warn("ioctl 'AUDIO_MIXER_DEVINFO':"); close(afd); return NULL; } + if (mdi.type == AUDIO_MIXER_CLASS && + !strncmp(mdi.label.name, + AudioCoutputs, + MAX_AUDIO_DEV_LEN)) + cls = mdi.index; + } + for (mdi.index = 0; v == -1 || m == -1; mdi.index++) { + if (ioctl(afd, AUDIO_MIXER_DEVINFO, &mdi) < 0) { + warn("ioctl 'AUDIO_MIXER_DEVINFO':"); + close(afd); + return NULL; + } + if (mdi.mixer_class == cls && + ((mdi.type == AUDIO_MIXER_VALUE && + !strncmp(mdi.label.name, + AudioNmaster, + MAX_AUDIO_DEV_LEN)) || + (mdi.type == AUDIO_MIXER_ENUM && + !strncmp(mdi.label.name, + AudioNmute, + MAX_AUDIO_DEV_LEN)))) { + mc.dev = mdi.index, mc.type = mdi.type; + if (ioctl(afd, AUDIO_MIXER_READ, &mc) < 0) { + warn("ioctl 'AUDIO_MIXER_READ':"); + close(afd); + return NULL; + } + if (mc.type == AUDIO_MIXER_VALUE) + v = mc.un.value.num_channels == 1 ? + mc.un.value.level[AUDIO_MIXER_LEVEL_MONO] : + (mc.un.value.level[AUDIO_MIXER_LEVEL_LEFT] > + mc.un.value.level[AUDIO_MIXER_LEVEL_RIGHT] ? + mc.un.value.level[AUDIO_MIXER_LEVEL_LEFT] : + mc.un.value.level[AUDIO_MIXER_LEVEL_RIGHT]); + else if (mc.type == AUDIO_MIXER_ENUM) + m = mc.un.ord; + } } + + close(afd); + + return bprintf("%d", m ? 0 : v * 100 / 255); } +#else + #include <sys/soundcard.h> + + const char * + vol_perc(const char *card) + { + size_t i; + int v, afd, devmask; + char *vnames[] = SOUND_DEVICE_NAMES; - close(afd); + if ((afd = open(card, O_RDONLY | O_NONBLOCK)) < 0) { + warn("open '%s':", card); + return NULL; + } - return bprintf("%d", v & 0xff); -} + if (ioctl(afd, (int)SOUND_MIXER_READ_DEVMASK, &devmask) < 0) { + warn("ioctl 'SOUND_MIXER_READ_DEVMASK':"); + close(afd); + return NULL; + } + for (i = 0; i < LEN(vnames); i++) { + if (devmask & (1 << i) && !strcmp("vol", vnames[i])) { + if (ioctl(afd, MIXER_READ(i), &v) < 0) { + warn("ioctl 'MIXER_READ(%ld)':", i); + close(afd); + return NULL; + } + } + } + + close(afd); + + return bprintf("%d", v & 0xff); + } +#endif diff --git a/config.mk b/config.mk @@ -14,7 +14,6 @@ X11LIB = /usr/X11R6/lib CPPFLAGS = -I$(X11INC) -D_DEFAULT_SOURCE CFLAGS = -std=c99 -pedantic -Wall -Wextra -Os LDFLAGS = -L$(X11LIB) -s -# OpenBSD: add -lossaudio LDLIBS = -lX11 # compiler and linker