On Fri Apr 10, 2020 at 05:37:03PM +0200, Alexandre Ratchov wrote:
> This just replaces kernel mixer(4) ioctls with appropriate
> sioctl_open(3) calls.
Looks like it work but after the start the text (only the text) shows
"vol:0%", although it is not so. After adjusting the sound volume, "vol
X%" gets the right value.
>
> OK?
>
> Index: Makefile
> ===================================================================
> RCS file: /cvs/ports/sysutils/xstatbar/Makefile,v
> retrieving revision 1.21
> diff -u -p -r1.21 Makefile
> --- Makefile 12 Jul 2019 20:49:55 -0000 1.21
> +++ Makefile 10 Apr 2020 15:32:32 -0000
> @@ -5,7 +5,7 @@ ONLY_FOR_ARCHS= ${APM_ARCHS}
> COMMENT= simple system monitor bar
>
> DISTNAME= xstatbar-0.5
> -REVISION= 10
> +REVISION= 11
> FIX_EXTRACT_PERMISSIONS=Yes
>
> CATEGORIES= sysutils x11
> Index: patches/patch-Makefile
> ===================================================================
> RCS file: /cvs/ports/sysutils/xstatbar/patches/patch-Makefile,v
> retrieving revision 1.5
> diff -u -p -r1.5 patch-Makefile
> --- patches/patch-Makefile 1 Jun 2018 14:16:46 -0000 1.5
> +++ patches/patch-Makefile 10 Apr 2020 15:32:32 -0000
> @@ -2,15 +2,17 @@ $OpenBSD: patch-Makefile,v 1.5 2018/06/0
> Index: Makefile
> --- Makefile.orig
> +++ Makefile
> -@@ -4,7 +4,7 @@ MANDIR=/usr/local/man/man1
> +@@ -4,8 +4,8 @@ MANDIR=/usr/local/man/man1
>
> # build flags
> CC?=/usr/bin/cc
> -CFLAGS+=-c -std=c89 -Wall -O2 -I/usr/X11R6/include
> +-LDFLAGS+=-L/usr/X11R6/lib -lX11 -lXext -lXrender -lXau -lXdmcp -lm
> +CFLAGS+=-c -std=c89 -Wall -I/usr/X11R6/include
> - LDFLAGS+=-L/usr/X11R6/lib -lX11 -lXext -lXrender -lXau -lXdmcp -lm
> ++LDFLAGS+=-L/usr/X11R6/lib -lX11 -lXext -lXrender -lXau -lXdmcp -lm -lsndio
>
> OBJS=xstatbar.o stats.o
> +
> @@ -16,8 +16,8 @@ xstatbar: $(OBJS)
> $(CC) $(CFLAGS) $<
>
> Index: patches/patch-stats_c
> ===================================================================
> RCS file: /cvs/ports/sysutils/xstatbar/patches/patch-stats_c,v
> retrieving revision 1.10
> diff -u -p -r1.10 patch-stats_c
> --- patches/patch-stats_c 24 Feb 2019 15:02:19 -0000 1.10
> +++ patches/patch-stats_c 10 Apr 2020 15:32:32 -0000
> @@ -6,19 +6,208 @@ progress and loop forever. Fix it by try
> Index: stats.c
> --- stats.c.orig
> +++ stats.c
> -@@ -101,8 +101,10 @@ volume_init()
> - devinfo.index = 0;
> - while (ioctl(volume.dev_fd, AUDIO_MIXER_DEVINFO, &devinfo) >= 0) {
> +@@ -61,118 +61,101 @@ fmtmem(int m)
> + * volume stuff
> +
> ****************************************************************************/
> +
> +-int
> +-volume_check_dev(int fd, int class, char *name)
> ++/*
> ++ * new control
> ++ */
> ++void
> ++volume_ondesc(void *unused, struct sioctl_desc *d, int val)
> + {
> +- mixer_devinfo_t devinfo;
> ++ if (d == NULL)
> ++ return;
> +
> +- if (class < 0 || name == NULL)
> +- return (-1);
> ++ if (d->addr == volume.left_addr)
> ++ volume.left_addr = -1;
> ++ if (d->addr == volume.right_addr)
> ++ volume.right_addr = -1;
> +
> +- devinfo.index = 0;
> +- while (ioctl(fd, AUDIO_MIXER_DEVINFO, &devinfo) >= 0) {
> +- if ((devinfo.type == AUDIO_MIXER_VALUE)
> +- && (devinfo.mixer_class == class)
> +- && (strncmp(devinfo.label.name, name, MAX_AUDIO_DEV_LEN) == 0))
> +- return (devinfo.index);
> ++ if (d->type == SIOCTL_NUM &&
> ++ strcmp(d->group, "") == 0 &&
> ++ strcmp(d->node0.name, "output") == 0 &&
> ++ strcmp(d->func, "level") == 0) {
> +
> +- devinfo.index++;
> ++ switch (d->node0.unit) {
> ++ case -1: /* mono */
> ++ case 0: /* left */
> ++ volume.left_addr = d->addr;
> ++ volume.left_max = d->maxval;
> ++ break;
> ++ case 1: /* right */
> ++ volume.right_addr = d->addr;
> ++ volume.right_max = d->maxval;
> ++ }
> + }
> ++}
> +
> +- return (-1);
> ++/*
> ++ * control value changed
> ++ */
> ++void
> ++volume_onval(void *unused, unsigned int addr, unsigned int value)
> ++{
> ++ if (addr == volume.left_addr)
> ++ volume.left = value;
> ++ if (addr == volume.right_addr)
> ++ volume.right = value;
> + }
> +
> + void
> + volume_init()
> + {
> +- mixer_devinfo_t devinfo;
> +- int oclass_idx, iclass_idx;
> +-
> + volume.is_setup = false;
>
> +- /* open mixer */
> +- if ((volume.dev_fd = open("/dev/mixer", O_RDWR)) < 0) {
> +- warn("volume: failed to open /dev/mixer");
> ++ if ((volume.hdl = sioctl_open(SIO_DEVANY, SIOCTL_READ, 0)) == NULL) {
> ++ warn("volume: failed to open default device");
> + return;
> + }
> +
> +- /* find the outputs and inputs classes */
> +- oclass_idx = iclass_idx = -1;
> +- devinfo.index = 0;
> +- while (ioctl(volume.dev_fd, AUDIO_MIXER_DEVINFO, &devinfo) >= 0) {
> +-
> - if (devinfo.type != AUDIO_MIXER_CLASS)
> -+ if (devinfo.type != AUDIO_MIXER_CLASS) {
> -+ devinfo.index++;
> - continue;
> -+ }
> +- continue;
> +-
> +- if (strncmp(devinfo.label.name, AudioCoutputs, MAX_AUDIO_DEV_LEN) ==
> 0)
> +- oclass_idx = devinfo.index;
> +- if (strncmp(devinfo.label.name, AudioCinputs, MAX_AUDIO_DEV_LEN) == 0)
> +- iclass_idx = devinfo.index;
> +-
> +- if (oclass_idx != -1 && iclass_idx != -1)
> +- break;
> +-
> +- devinfo.index++;
> ++ volume.pfds = calloc(sioctl_nfds(volume.hdl), sizeof(struct pollfd));
> ++ if (volume.pfds == NULL) {
> ++ warnx("volume: cannot allocate pfds\n");
> ++ goto bad_close;
> + }
> ++
> +
> +- /* find the master device */
> +- volume.master_idx = volume_check_dev(volume.dev_fd, oclass_idx,
> AudioNmaster);
> +- if (volume.master_idx == -1)
> +- volume.master_idx = volume_check_dev(volume.dev_fd, iclass_idx,
> AudioNdac);
> +- if (volume.master_idx == -1)
> +- volume.master_idx = volume_check_dev(volume.dev_fd, oclass_idx,
> AudioNdac);
> +- if (volume.master_idx == -1)
> +- volume.master_idx = volume_check_dev(volume.dev_fd, oclass_idx,
> AudioNoutput);
> +-
> +- if (volume.master_idx == -1) {
> +- warnx("volume: failed to find \"master\" mixer device");
> +- return;
> ++ if (!sioctl_ondesc(volume.hdl, volume_ondesc, NULL)) {
> ++ warnx("volume: cannot get descriptions\n");
> ++ goto bad_free;
> + }
> +
> +- devinfo.index = volume.master_idx;
> +- if (ioctl(volume.dev_fd, AUDIO_MIXER_DEVINFO, &devinfo) == -1) {
> +- warn("AUDIO_MIXER_DEVINFO");
> +- return;
> ++ if (!sioctl_onval(volume.hdl, volume_onval, NULL)) {
> ++ warnx("volume: cannot get values\n");
> ++ goto bad_free;
> + }
> +
> +- volume.max = AUDIO_MAX_GAIN;
> +- volume.nchan = devinfo.un.v.num_channels;
> +-
> +- /* finished... now close the device and reopen as read only */
> +- close(volume.dev_fd);
> +- volume.dev_fd = open("/dev/mixer", O_RDONLY);
> +- if (volume.dev_fd < 0) {
> +- warn("volume: failed to re-open /dev/mixer");
> +- return;
> +- }
> +-
> + volume.is_setup = true;
> ++ return;
> ++bad_free:
> ++ free(volume.pfds);
> ++bad_close:
> ++ sioctl_close(volume.hdl);
> + }
> +
> + void
> + volume_update()
> + {
> +- static mixer_ctrl_t vinfo;
> ++ int n;
>
> - if (strncmp(devinfo.label.name, AudioCoutputs, MAX_AUDIO_DEV_LEN) ==
> 0)
> - oclass_idx = devinfo.index;
> -@@ -358,7 +360,7 @@ sysinfo_init(int hist_size)
> + if (!volume.is_setup)
> + return;
> +
> +- /* query info */
> +- vinfo.dev = volume.master_idx;
> +- vinfo.type = AUDIO_MIXER_VALUE;
> +- vinfo.un.value.num_channels = volume.nchan;
> +- if (ioctl(volume.dev_fd, AUDIO_MIXER_READ, &(vinfo)) < 0) {
> +- warn("volume update: AUDIO_MIXER_READ");
> +- return;
> ++ n = sioctl_pollfd(volume.hdl, volume.pfds, POLLIN);
> ++ if (n > 0) {
> ++ n = poll(volume.pfds, n, 0);
> ++ if (n == -1)
> ++ return;
> ++ if (n > 0)
> ++ sioctl_revents(volume.hdl, volume.pfds);
> + }
> +-
> +- /* record in global struct */
> +- if (volume.nchan == 1)
> +- volume.left = volume.right =
> vinfo.un.value.level[AUDIO_MIXER_LEVEL_MONO];
> +- else {
> +- volume.left = vinfo.un.value.level[AUDIO_MIXER_LEVEL_LEFT];
> +- volume.right = vinfo.un.value.level[AUDIO_MIXER_LEVEL_RIGHT];
> +- }
> + }
> +
> + void
> +@@ -180,7 +163,7 @@ volume_close() {
> + if (!volume.is_setup)
> + return;
> +
> +- close(volume.dev_fd);
> ++ sioctl_close(volume.hdl);
> + }
> +
> + int
> +@@ -199,8 +182,8 @@ volume_draw(XColor color, int x, int y)
> + width = 5;
> +
> + /* get volume as percents */
> +- left = roundf(100.0 * (float)volume.left / (float)volume.max);
> +- right = roundf(100.0 * (float)volume.right / (float)volume.max);
> ++ left = roundf(100.0 * (float)volume.left / (float)volume.left_max);
> ++ right = roundf(100.0 * (float)volume.right / (float)volume.right_max);
> +
> + /* determine height of green-part of bar graphs */
> + lheight = (int)(left * (float)XINFO.height / 100.0);
> +@@ -358,7 +341,7 @@ sysinfo_init(int hist_size)
> err(1, "sysinfo init: memory calloc failed");
>
> for (i = 0; i < hist_size; i++) {
> @@ -27,7 +216,7 @@ Index: stats.c
> err(1, "sysinfo init: memory[%d] calloc failed", i);
>
> for (j = 0; j < 3; j++)
> -@@ -372,6 +374,7 @@ sysinfo_init(int hist_size)
> +@@ -372,6 +355,7 @@ sysinfo_init(int hist_size)
>
> /* allocate cpu history */
> sysinfo.cpu_raw = calloc(sysinfo.ncpu, sizeof(uint64_t**));
> @@ -35,7 +224,7 @@ Index: stats.c
> sysinfo.cpu_pcnts = calloc(sysinfo.ncpu, sizeof(int**));
> if (sysinfo.cpu_raw == NULL || sysinfo.cpu_pcnts == NULL)
> err(1, "sysinfo init: cpu_raw/cpu_pcnts calloc failed");
> -@@ -404,10 +407,14 @@ sysinfo_update()
> +@@ -404,10 +388,14 @@ sysinfo_update()
> {
> static int mib_nprocs[] = { CTL_KERN, KERN_NPROCS };
> static int mib_vm[] = { CTL_VM, VM_METER };
> @@ -51,7 +240,7 @@ Index: stats.c
> size_t size;
> int cpu, state;
> int cur, prev;
> -@@ -431,9 +438,16 @@ sysinfo_update()
> +@@ -431,9 +419,16 @@ sysinfo_update()
> if (sysctl(mib_vm, 2, &vminfo, &size, NULL, 0) < 0)
> err(1, "sysinfo update: VM.METER failed");
>
> @@ -68,7 +257,7 @@ Index: stats.c
>
> /* get swap status */
> if ((nswaps = swapctl(SWAP_NSWAP, 0, 0)) == 0)
> -@@ -454,24 +468,15 @@ sysinfo_update()
> +@@ -454,24 +449,15 @@ sysinfo_update()
>
> /* get states for each cpu. note this is raw # of ticks */
> size = CPUSTATES * sizeof(int64_t);
> @@ -102,7 +291,7 @@ Index: stats.c
> }
>
> /* convert ticks to percentages */
> -@@ -509,12 +514,16 @@ int
> +@@ -509,12 +495,16 @@ int
> cpu_draw(int cpu, XColor color, int x, int y)
> {
> static char str[1000];
> @@ -121,7 +310,7 @@ Index: stats.c
> startx = x;
>
> snprintf(str, sizeof(str), "cpu%d:", cpu);
> -@@ -531,7 +540,7 @@ cpu_draw(int cpu, XColor color, int x, int y)
> +@@ -531,7 +521,7 @@ cpu_draw(int cpu, XColor color, int x, int y)
>
> /* user time */
> h = 0;
> @@ -130,7 +319,7 @@ Index: stats.c
> h = h * XINFO.height / 100;
> XSetForeground(XINFO.disp, XINFO.gc, COLOR_RED.pixel);
> XDrawLine(XINFO.disp, XINFO.buf, XINFO.gc,
> -@@ -540,7 +549,7 @@ cpu_draw(int cpu, XColor color, int x, int y)
> +@@ -540,7 +530,7 @@ cpu_draw(int cpu, XColor color, int x, int y)
>
> /* nice time */
> h = 0;
> @@ -139,7 +328,7 @@ Index: stats.c
> h = h * XINFO.height / 100;
> XSetForeground(XINFO.disp, XINFO.gc, COLOR_BLUE.pixel);
> XDrawLine(XINFO.disp, XINFO.buf, XINFO.gc,
> -@@ -549,15 +558,24 @@ cpu_draw(int cpu, XColor color, int x, int y)
> +@@ -549,15 +539,24 @@ cpu_draw(int cpu, XColor color, int x, int y)
>
> /* system time */
> h = 0;
> @@ -166,7 +355,7 @@ Index: stats.c
> h = h * XINFO.height / 100;
> XSetForeground(XINFO.disp, XINFO.gc, COLOR_MAGENTA.pixel);
> XDrawLine(XINFO.disp, XINFO.buf, XINFO.gc,
> -@@ -594,7 +612,8 @@ mem_draw(XColor color, int x, int y)
> +@@ -594,7 +593,8 @@ mem_draw(XColor color, int x, int y)
> /* determine total memory */
> total = sysinfo.memory[cur][MEM_ACT]
> + sysinfo.memory[cur][MEM_TOT]
> @@ -176,7 +365,7 @@ Index: stats.c
>
> /* start drawing ... */
> x += render_text(color, x, y, "mem:") + 1;
> -@@ -610,7 +629,8 @@ mem_draw(XColor color, int x, int y)
> +@@ -610,7 +610,8 @@ mem_draw(XColor color, int x, int y)
>
> if ((sysinfo.memory[time][MEM_ACT] != 0)
> || (sysinfo.memory[time][MEM_TOT] != 0)
> @@ -186,7 +375,7 @@ Index: stats.c
>
>
> /* draw yellow (total) bar */
> -@@ -627,6 +647,13 @@ mem_draw(XColor color, int x, int y)
> +@@ -627,6 +628,13 @@ mem_draw(XColor color, int x, int y)
> XDrawLine(XINFO.disp, XINFO.buf, XINFO.gc,
> x + col, XINFO.height - h,
> x + col, XINFO.height);
> @@ -200,7 +389,7 @@ Index: stats.c
> }
>
> time = (time + 1) % sysinfo.hist_size;
> -@@ -639,6 +666,8 @@ mem_draw(XColor color, int x, int y)
> +@@ -639,6 +647,8 @@ mem_draw(XColor color, int x, int y)
> x += render_text(COLOR_YELLOW, x, y,
> fmtmem(sysinfo.memory[cur][MEM_TOT]));
> x += render_text(color, x, y, "/");
> x += render_text(COLOR_GREEN, x, y,
> fmtmem(sysinfo.memory[cur][MEM_FRE]));
> Index: patches/patch-stats_h
> ===================================================================
> RCS file: /cvs/ports/sysutils/xstatbar/patches/patch-stats_h,v
> retrieving revision 1.3
> diff -u -p -r1.3 patch-stats_h
> --- patches/patch-stats_h 24 Feb 2019 15:02:19 -0000 1.3
> +++ patches/patch-stats_h 10 Apr 2020 15:32:32 -0000
> @@ -2,8 +2,15 @@ $OpenBSD: patch-stats_h,v 1.3 2019/02/24
> Index: stats.h
> --- stats.h.orig
> +++ stats.h
> -@@ -30,10 +30,12 @@
> - #include <sys/audioio.h>
> +@@ -25,15 +25,18 @@
> + #include <fcntl.h>
> + #include <math.h>
> + #include <err.h>
> ++#include <poll.h>
> ++#include <sndio.h>
> +
> + #include <machine/apmvar.h>
> +-#include <sys/audioio.h>
> #include <sys/ioctl.h>
> #include <sys/param.h>
> +#include <sys/mount.h>
> @@ -15,7 +22,30 @@ Index: stats.h
>
> #include "xstatbar.h"
>
> -@@ -74,6 +76,8 @@ typedef struct {
> +@@ -45,14 +48,14 @@
> + /* volume */
> + typedef struct {
> + bool is_setup;
> +-
> +- int dev_fd;
> +- int master_idx;
> +-
> +- int max;
> +- int nchan;
> +- int left;
> +- int right;
> ++ struct sioctl_hdl *hdl;
> ++ struct pollfd *pfds;
> ++ int left;
> ++ int left_addr;
> ++ int left_max;
> ++ int right;
> ++ int right_addr;
> ++ int right_max;
> + } volume_info_t;
> + extern volume_info_t volume;
> +
> +@@ -74,6 +77,8 @@ typedef struct {
>
> int swap_used; /* swap space used */
> int swap_total; /* total amount of swap space */
> @@ -24,7 +54,7 @@ Index: stats.h
>
> /* cpu/memory historical stuff (for graphs) */
>
> -@@ -84,6 +88,7 @@ typedef struct {
> +@@ -84,6 +89,7 @@ typedef struct {
> #define MEM_ACT 0
> #define MEM_TOT 1
> #define MEM_FRE 2
>