Hi, The diff below mostly replaces kernel mixer(4) ioctls with the corresponding sioctl_open(3) calls.
There's no mute control on all setups, so I've changed dstat to not fail if output.mute is missing, just display the current volume. As for the other volume status ports, this makes dstat use the default sndio device (instead of the first one), and shows by default sndiod soft volume control, present regardless the hardware used. OK? Index: Makefile =================================================================== RCS file: /cvs/ports/x11/dstat/Makefile,v retrieving revision 1.7 diff -u -p -u -p -r1.7 Makefile --- Makefile 12 Jul 2019 20:51:09 -0000 1.7 +++ Makefile 11 Apr 2020 07:15:41 -0000 @@ -6,6 +6,8 @@ COMMENT = dwm status bar statistics DISTNAME = dstat-0.6 +REVISION = 0 + CATEGORIES = x11 sysutils HOMEPAGE = https://www.umaxx.net/ Index: patches/patch-Makefile =================================================================== RCS file: patches/patch-Makefile diff -N patches/patch-Makefile --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ patches/patch-Makefile 11 Apr 2020 07:15:41 -0000 @@ -0,0 +1,14 @@ +$OpenBSD$ + +Index: Makefile +--- Makefile.orig ++++ Makefile +@@ -30,7 +30,7 @@ CFLAGS+=-Isrc -I/usr/include -I$(INCDIR) -I/usr/X11R6/ + + LDFLAGS+=-L/usr/lib -L$(LIBDIR) -L/usr/X11R6/lib + +-LIBS+=-lX11 -lutil ++LIBS+=-lX11 -lutil -lsndio + + OBJECTS=dstat.o + Index: patches/patch-dstat_c =================================================================== RCS file: patches/patch-dstat_c diff -N patches/patch-dstat_c --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ patches/patch-dstat_c 11 Apr 2020 07:15:41 -0000 @@ -0,0 +1,140 @@ +$OpenBSD$ + +Index: dstat.c +--- dstat.c.orig ++++ dstat.c +@@ -23,10 +23,10 @@ + #include <limits.h> + #include <time.h> + #include <unistd.h> ++#include <sndio.h> + #include <sys/types.h> + #include <sys/ioctl.h> + #include <sys/param.h> +-#include <sys/audioio.h> + #include <sys/sched.h> + #include <sys/resource.h> + #include <sys/sensors.h> +@@ -48,7 +48,13 @@ + #define D_BUF 64 + + #define d_warn(s) (warn(s), s) ++#define d_warnx(s) (warnx(s), s) + ++struct d_vol { ++ int v; ++ int m; ++}; ++ + static const char *d_bar(unsigned char p) { + const char *s[] = { "▁", "▂", "▃", "▄", "▅", "▆", "▇", "█", "█" }; + +@@ -231,45 +237,41 @@ static char *d_temp(void) { + d_fmt(s, sizeof(s), "T %.1f°C", (t - 273150000) / 1000000.0); + } + +-static char *d_vol(int fd) { ++static void d_vol_ondesc(void *arg, struct sioctl_desc *d, int val) { ++ struct d_vol *vol = arg; ++ int p; ++ ++ if (d == NULL) ++ return; ++ if (strcmp(d->group, "") != 0 || strcmp(d->node0.name, "output") != 0) ++ return; ++ if (d->type == SIOCTL_NUM && strcmp(d->func, "level") == 0) { ++ p = val * 100 / d->maxval; ++ if (p > vol->v) ++ vol->v = p; ++ } else if (d->type == SIOCTL_SW && strcmp(d->func, "mute") == 0) { ++ if (val > vol->m) ++ vol->m = val; ++ } ++} ++ ++static char *d_vol(void) { + static char s[D_BUF]; +- static int cls = -1; +- struct mixer_devinfo mdi; +- struct mixer_ctrl mc; +- int v = -1, m = -1, p; ++ struct sioctl_hdl *hdl; ++ struct d_vol vol = {-1, 0}; + +- for (mdi.index = 0; cls == -1; mdi.index++) { +- if (ioctl(fd, AUDIO_MIXER_DEVINFO, &mdi) == -1) +- return d_warn("ioctl failed"); +- if (mdi.type == AUDIO_MIXER_CLASS && +- !strcmp(mdi.label.name, AudioCoutputs)) +- cls = mdi.index; +- } +- for (mdi.index = 0; v == -1 || m == -1; mdi.index++) { +- if (ioctl(fd, AUDIO_MIXER_DEVINFO, &mdi) == -1) +- return d_warn("ioctl failed"); +- if (mdi.mixer_class == cls && +- ((mdi.type == AUDIO_MIXER_VALUE && +- !strcmp(mdi.label.name, AudioNmaster)) || +- (mdi.type == AUDIO_MIXER_ENUM && +- !strcmp(mdi.label.name, AudioNmute)))) { +- mc.dev = mdi.index, mc.type = mdi.type; +- if (ioctl(fd, AUDIO_MIXER_READ, &mc) == -1) +- return d_warn("ioctl failed"); +- 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; +- } +- } +- return v == -1 ? "volume failed" : (m == -1 ? "mute failed" : (m ? +- d_fmt(s, sizeof(s), "♫ mute") : (p = ((v * 100) / 255), +- d_fmt(s, sizeof(s), "♫ %d%% %s", p, d_bar(p))))); ++ hdl = sioctl_open(SIO_DEVANY, SIOCTL_READ, 0); ++ if (hdl == NULL) ++ return d_warnx("cannot open audio control device"); ++ if (!sioctl_ondesc(hdl, d_vol_ondesc, &vol)) { ++ sioctl_close(hdl); ++ return d_warnx("cannot get audio controls descriptions\n"); ++ } ++ sioctl_close(hdl); ++ ++ return vol.v == -1 ? "volume failed" : (vol.m ? ++ d_fmt(s, sizeof(s), "♫ mute") : ++ d_fmt(s, sizeof(s), "♫ %d%% %s", vol.v, d_bar(vol.v))); + } + + static char *d_time(void) { +@@ -289,7 +291,7 @@ static char *d_time(void) { + static void d_run(const char *ifn) { + Display *d; + XFontStruct *f; +- int a = -1, m = -1; ++ int a = -1; + char s[LINE_MAX]; + + if (!(d = XOpenDisplay(NULL))) +@@ -297,17 +299,16 @@ static void d_run(const char *ifn) { + if (!(f = XLoadQueryFont(d, "-*-terminus-medium-*")) && + !(f = XLoadQueryFont(d, "fixed"))) + err(1, "XLoadQueryFont failed"); +- if ((a = open("/dev/apm", O_RDONLY)) == -1 || +- (m = open("/dev/mixer", O_RDONLY)) == -1) ++ if ((a = open("/dev/apm", O_RDONLY)) == -1) + err(1, "open failed"); + for (;;) { + XStoreName(d, DefaultRootWindow(d), + d_fmt(s, sizeof(s), "%s %s %s %s %s %s", +- d_net(ifn), d_cpu(), d_bat(a, d, f), d_temp(), d_vol(m), d_time())); ++ d_net(ifn), d_cpu(), d_bat(a, d, f), d_temp(), d_vol(), d_time())); + printf("%s\n", s); + XSync(d, False), sleep(1); + } +- close(m), close(a); ++ close(a); + XUnloadFont(d, f->fid); + XCloseDisplay(d); + }