Add native OpenBSD support for mute/volume - slstatus - status monitor
git clone git://git.suckless.org/slstatus
Log
Files
Refs
README
LICENSE
---
commit c1dc896c806693a4a368abf59e6890d32d520074
parent e724907cc37749907cb8c63031d9fb35ef46a657
Author: Ingo Feinerer 
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:
  M LICENSE                             |       2 ++
  M README                              |       2 +-
  M components/volume.c                 |     118 ++++++++++++++++++++++++-------
  M config.mk                           |       1 -

4 files changed, 94 insertions(+), 29 deletions(-)
---
diff --git a/LICENSE b/LICENSE
@@ -18,6 +18,8 @@ Copyright 2018 Tobias Tschinkowitz 
 Copyright 2018 David Demelier 
 Copyright 2018-2019 Michael Buch 
 Copyright 2018 Ian Remmler 
+Copyright 2016-2019 Joerg Jung 
+Copyright 2019 Ingo Feinerer 
 
 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 
 #include 
 #include 
-#if defined(__OpenBSD__)
-        #include 
-#else
-        #include 
-#endif
 #include 
 #include 
 
 #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 
 
-        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 
+
+        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