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);
> 

Reply via email to