On Sun Mar 08, 2020 at 04:45:44PM +0100, Alexandre Ratchov wrote: > This diff makes gqmpeg use sndio to display and control the > volume. This fixes the crash when the volume slider is touched. As a > side effect, this makes gqmpeg use the right device (one that's > playing) and nicely updates the slider position when other programs > change the master volume. > > OK?
OK rsadowski@ > > Index: Makefile > =================================================================== > RCS file: /cvs/ports/audio/gqmpeg/Makefile,v > retrieving revision 1.64 > diff -u -p -r1.64 Makefile > --- Makefile 12 Jul 2019 20:43:33 -0000 1.64 > +++ Makefile 8 Mar 2020 15:39:53 -0000 > @@ -3,7 +3,7 @@ > COMMENT= front-end to various audio players > > DISTNAME= gqmpeg-0.91.1 > -REVISION= 14 > +REVISION= 15 > CATEGORIES= audio > > HOMEPAGE= http://gqmpeg.sourceforge.net/ > Index: patches/patch-src_Makefile_in > =================================================================== > RCS file: patches/patch-src_Makefile_in > diff -N patches/patch-src_Makefile_in > --- /dev/null 1 Jan 1970 00:00:00 -0000 > +++ patches/patch-src_Makefile_in 8 Mar 2020 15:39:53 -0000 > @@ -0,0 +1,14 @@ > +$OpenBSD$ > + > +Index: src/Makefile.in > +--- src/Makefile.in.orig > ++++ src/Makefile.in > +@@ -342,7 +342,7 @@ gqmpeg_SOURCES = \ > + $(module_mpg123) $(module_xmp) $(module_ogg123) $(module_radio) > + > + > +-gqmpeg_LDADD = $(GTK_LIBS) $(LIBPNG) > ++gqmpeg_LDADD = $(GTK_LIBS) $(LIBPNG) -lsndio > + > + EXTRA_DIST = \ > + $(extra_SLIK) \ > Index: patches/patch-src_mixer_c > =================================================================== > RCS file: /cvs/ports/audio/gqmpeg/patches/patch-src_mixer_c,v > retrieving revision 1.2 > diff -u -p -r1.2 patch-src_mixer_c > --- patches/patch-src_mixer_c 14 Oct 2007 14:12:42 -0000 1.2 > +++ patches/patch-src_mixer_c 8 Mar 2020 15:39:53 -0000 > @@ -1,39 +1,288 @@ > $OpenBSD: patch-src_mixer_c,v 1.2 2007/10/14 14:12:42 jasper Exp $ > ---- src/mixer.c.orig Tue Sep 10 16:16:26 2002 > -+++ src/mixer.c Sun Oct 14 15:47:27 2007 > -@@ -285,7 +285,11 @@ void mixer_init(gint init_device_id) > - > - mixer_device = getenv("MIXERDEVICE"); > - if (mixer_device == NULL) > -+#ifdef __OpenBSD__ > -+ mixer_device = "/dev/mixer"; > -+#else > - mixer_device = "/dev/mixer0"; > -+#endif > +Index: src/mixer.c > +--- src/mixer.c.orig > ++++ src/mixer.c > +@@ -39,10 +39,16 @@ > + #include <sys/soundcard.h> > + #endif > > - if ((fd = open(mixer_device, O_RDWR)) == -1) { > - perror(mixer_device); > -@@ -362,7 +366,11 @@ static void mixer_set_vol(DeviceData *device, gint vol > - > - mixer_device = getenv("MIXERDEVICE"); > - if (mixer_device == NULL) > -+#ifdef __OpenBSD__ > -+ mixer_device = "/dev/mixer"; > -+#else > - mixer_device = "/dev/mixer0"; > -+#endif > +-#if defined(__NetBSD__) || defined(__OpenBSD__) > ++#if defined(__NetBSD__) > + #include <sys/audioio.h> > + #endif > > - if ((fd = open(mixer_device, O_RDWR)) == -1) { > - perror(mixer_device); > -@@ -406,7 +414,11 @@ static gint mixer_get_vol(DeviceData *device) > - > - mixer_device = getenv("MIXERDEVICE"); > - if (mixer_device == NULL) > -+#ifdef __OpenBSD__ > -+ mixer_device = "/dev/mixer"; > -+#else > - mixer_device = "/dev/mixer0"; > ++#if defined(__OpenBSD__) > ++#include <poll.h> > ++#include <sndio.h> > ++#include "display.h" > +#endif > ++ > + #if defined(sun) && defined(__svr4__) > + #include <sys/audioio.h> > + #endif > +@@ -267,11 +273,11 @@ static gint mixer_get_vol(DeviceData *device) > + > + /* > + *-------------------------------------------------------------------- > +- * NetBSD and OpenBSD > ++ * NetBSD > + *-------------------------------------------------------------------- > + */ > + > +-#elif defined(__NetBSD__) || defined(__OpenBSD__) > ++#elif defined(__NetBSD__) > + > + mixer_devinfo_t *infos; > + mixer_ctrl_t *values; > +@@ -442,6 +448,242 @@ static gint mixer_get_vol(DeviceData *device) > + > + /* > + *-------------------------------------------------------------------- > ++ * OpenBSD > ++ *-------------------------------------------------------------------- > ++ */ > ++ > ++#elif defined(__OpenBSD__) > ++ > ++struct control { > ++ struct control *next; > ++ unsigned int addr; > ++ unsigned int max, value; > ++}; > ++ > ++static struct control *controls; > ++static struct sioctl_hdl *hdl; > ++static struct pollfd *pfds; > ++static int initialized; > ++ > ++/* > ++ * new control registered > ++ */ > ++static void ondesc(void *unused, struct sioctl_desc *d, int val) > ++{ > ++ struct control *i, **pi; > ++ > ++ if (d == NULL) > ++ return; > ++ > ++ /* > ++ * delete existing control with the same address > ++ */ > ++ for (pi = &controls; (i = *pi) != NULL; pi = &i->next) { > ++ if (d->addr == i->addr) { > ++ *pi = i->next; > ++ free(i); > ++ break; > ++ } > ++ } > ++ > ++ /* > ++ * SIOCTL_NONE means control was deleted from the device > ++ */ > ++ if (d->type == SIOCTL_NONE) > ++ return; > ++ > ++ /* > ++ * we're interested in top-level output.level controls only > ++ */ > ++ if (d->group[0] != 0 || > ++ strcmp(d->node0.name, "output") != 0 || > ++ strcmp(d->func, "level") != 0) > ++ return; > ++ > ++ i = malloc(sizeof(struct control)); > ++ if (i == NULL) { > ++ perror("malloc"); > ++ return; > ++ } > ++ > ++ i->addr = d->addr; > ++ i->max = d->maxval; > ++ i->value = val; > ++ i->next = controls; > ++ controls = i; > ++ > ++ if (debug_mode) > ++ fprintf(stderr, "found output.level at %d\n", i->addr); > ++} > ++ > ++/* > ++ * control value changed > ++ */ > ++static void onval(void *unused, unsigned int addr, unsigned int value) > ++{ > ++ struct control *c; > ++ > ++ if (debug_mode) > ++ fprintf(stderr, "control %d changed to %d\n", addr, value); > ++ > ++ for (c = controls; ; c = c->next) { > ++ if (c == NULL) > ++ return; > ++ if (c->addr == addr) > ++ break; > ++ } > ++ > ++ c->value = value; > ++ > ++ if (debug_mode) > ++ fprintf(stderr, "refreshing\n"); > ++ display_set_volume(); > ++} > ++ > ++/* > ++ * Call poll(2), for both gtk and sndio descriptors. > ++ */ > ++int > ++do_poll(GPollFD *gtk_pfds, guint gtk_nfds, gint timeout) > ++{ > ++#define MAXFDS 64 > ++ struct pollfd pfds[MAXFDS], *sioctl_pfds; > ++ unsigned int sioctl_nfds; > ++ unsigned int i; > ++ int revents; > ++ int rc; > ++ > ++ for (i = 0; i < gtk_nfds; i++) { > ++ pfds[i].fd = gtk_pfds[i].fd; > ++ pfds[i].events = gtk_pfds[i].events; > ++ } > ++ if (hdl != NULL) { > ++ sioctl_pfds = pfds + gtk_nfds; > ++ sioctl_nfds = sioctl_pollfd(hdl, sioctl_pfds, POLLIN); > ++ } else > ++ sioctl_nfds = 0; > ++ > ++ rc = poll(pfds, gtk_nfds + sioctl_nfds, timeout); > ++ if (rc > 0 && hdl != NULL) { > ++ revents = sioctl_revents(hdl, sioctl_pfds); > ++ if (revents & POLLHUP) { > ++ fprintf(stderr, "Device disconnected\n"); > ++ sioctl_close(hdl); > ++ hdl = NULL; > ++ } > ++ } > ++ > ++ for (i = 0; i < gtk_nfds; i++) > ++ gtk_pfds[i].revents = pfds[i].revents; > ++ > ++ return rc; > ++} > ++ > ++void mixer_init(gint init_device_id) > ++{ > ++ if (debug_mode) > ++ fprintf(stderr, "mixer, initializing...\n"); > ++ > ++ if (initialized) { > ++ fprintf(stderr, "mixer, already initialized\n"); > ++ return; > ++ } > ++ > ++ initialized = 1; > ++ > ++ hdl = sioctl_open(SIO_DEVANY, SIOCTL_READ | SIOCTL_WRITE, 0); > ++ if (hdl == NULL) { > ++ fprintf(stderr, "Cannot open audio control device\n"); > ++ mixer_enabled = FALSE; > ++ return; > ++ } > ++ if (!sioctl_ondesc(hdl, ondesc, NULL)) { > ++ sioctl_close(hdl); > ++ fprintf(stderr, "Cannot get mixer information\n"); > ++ mixer_enabled = FALSE; > ++ return; > ++ } > ++ > ++ /* register call-back for external volume changes */ > ++ if (!sioctl_onval(hdl, onval, NULL)) { > ++ sioctl_close(hdl); > ++ fprintf(stderr, "Cannot get mixer values\n"); > ++ mixer_enabled = FALSE; > ++ return; > ++ } > ++ > ++ pfds = malloc(sizeof(struct pollfd) * sioctl_nfds(hdl)); > ++ if (pfds == NULL) { > ++ sioctl_close(hdl); > ++ fprintf(stderr, "Cannot allocate pollfd structures\n"); > ++ mixer_enabled = FALSE; > ++ return; > ++ } > ++ > ++ if (controls != NULL) { > ++ DeviceData *device = g_new0(DeviceData, 1); > ++ device->device_id = 0; > ++ device->device_name = "output.level"; > ++ device->stereo = (controls->next != NULL); > ++ device->recordable = 0; > ++ device_list = g_list_append(device_list, device); > ++ current_device = device_list->data; > ++ current_vol = mixer_get_vol(current_device); > ++ mixer_enabled = TRUE; > ++ } else > ++ mixer_enabled = FALSE; > ++ > ++ if (debug_mode) > ++ fprintf(stderr, "setting gtk poll function\n"); > ++ g_main_context_set_poll_func(g_main_context_default(), do_poll); > ++ > ++} > ++ > ++static void mixer_poll(void) > ++{ > ++ int n, nfds; > ++ > ++ nfds = sioctl_pollfd(hdl, pfds, 0); > ++ if (nfds > 0) { > ++ n = poll(pfds, nfds, 0); > ++ if (n >= 0) > ++ sioctl_revents(hdl, pfds); > ++ } > ++} > ++ > ++static void mixer_set_vol(DeviceData *device, gint vol) > ++{ > ++ struct control *c; > ++ > ++ if (hdl == NULL) > ++ return; > ++ > ++ for (c = controls; c != NULL; c = c->next) { > ++ sioctl_setval(hdl, c->addr, (vol * c->max + 50) / 100); > ++ if (debug_mode) > ++ fprintf(stderr, "setting %d to %d%%\n", c->addr, vol); > ++ } > ++} > ++ > ++static gint mixer_get_vol(DeviceData *device) > ++{ > ++ struct control *c; > ++ int vol, minvol = 100; > ++ > ++ for (c = controls; c != NULL; c = c->next) { > ++ vol = (c->value * 100 + c->max / 2) / c->max; > ++ if (vol < minvol) > ++ minvol = vol; > ++ } > ++ > ++ if (debug_mode) > ++ fprintf(stderr, "get volume: %d\n", minvol); > ++ > ++ return minvol; > ++} > ++ > ++/* > ++ *-------------------------------------------------------------------- > + * Sun (svr4) > + *-------------------------------------------------------------------- > + */ > +@@ -1266,7 +1508,7 @@ gint get_volume(void) > + * but some platforms did not have it update the volume (mixer_get_vol), > + * and I am not going to mess with it. > + */ > +-#if defined (linux) || defined (__FreeBSD__) > ++#if defined (linux) || defined (__FreeBSD__) || defined (__OpenBSD__) > + current_vol = mixer_get_vol(current_device); > + #endif > > - if ((fd = open(mixer_device, O_RDWR)) == -1) { > - perror(mixer_device); >