commit c1dc896c806693a4a368abf59e6890d32d520074
parent e724907cc37749907cb8c63031d9fb35ef46a657
Author: Ingo Feinerer <[email protected]>
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:
4 files changed, 94 insertions(+), 29 deletions(-)
diff --git a/LICENSE b/LICENSE
@@ -18,6 +18,8 @@ Copyright 2018 Tobias Tschinkowitz <[email protected]>
 Copyright 2018 David Demelier <[email protected]>
 Copyright 2018-2019 Michael Buch <[email protected]>
 Copyright 2018 Ian Remmler <[email protected]>
+Copyright 2016-2019 Joerg Jung <[email protected]>
+Copyright 2019 Ingo Feinerer <[email protected]>
 
 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