Introduction
Introduction Statistics Contact Development Disclaimer Help
tApply upstream patch by Lucas for sndio support on OpenBSD - spoon - dwm statu…
git clone git://src.adamsgaard.dk/spoon
Log
Files
Refs
LICENSE
---
commit bd47937068b0c19f7eea595f41b4acba720bd8b8
parent 3c6eedee86ba611a19953902f16f2c2cdddd400f
Author: Anders Damsgaard <[email protected]>
Date: Sat, 23 May 2020 07:31:54 +0200
Apply upstream patch by Lucas for sndio support on OpenBSD
Diffstat:
M Makefile | 18 +++++++++++++++---
M mix.c | 178 +++++++++++++++++++++++------…
2 files changed, 147 insertions(+), 49 deletions(-)
---
diff --git a/Makefile b/Makefile
t@@ -8,16 +8,28 @@ OBJ = spoon.o batt.o wifi.o cpu.o count.o temp.o date.o load…
BIN = spoon
DISTFILES = $(SRC) arg.h types.h util.h config.def.h Makefile LICENSE configure
-#include config.mk
+include config.mk
-CPPFLAGS = -I/usr/X11R6/include -I/usr/local/include
-LDFLAGS = -L/usr/X11R6/lib -L/usr/local/lib
+CPPFLAGS_OpenBSD = -I/usr/X11R6/include -I/usr/local/include
+LDFLAGS_OpenBSD = -L/usr/X11R6/lib -L/usr/local/lib
+CPPFLAGS_Linux = -I/usr/local/include
+CPPFLAGS = $(CPPFLAGS_$(UNAME))
+LDFLAGS = $(LDFLAGS_$(UNAME))
LDLIBS = -lX11
+
# To remove extra compile time dependencies for unwanted plugins
# comment out the following sections. The stub implementations
# from stub.c will be used instead.
OBJ += mix.o
+LDLIBS_OpenBSD_mix = -lsndio
+# if ALSA
+LDLIBS_Linux_mix = -lasound
+CPPFLAGS += -DUSE_TINYALSA=0
+# else TinyALSA
+#LDLIBS_Linux_mix = -ltinyalsa
+#CPPFLAGS += -DUSE_TINYALSA=1
+LDLIBS += $(LDLIBS_$(UNAME)_mix)
OBJ += xkblayout.o
LDLIBS += -lxkbfile
diff --git a/mix.c b/mix.c
t@@ -4,67 +4,153 @@
#include "util.h"
#ifdef __OpenBSD__
-#include <sys/ioctl.h>
-#include <sys/audioio.h>
-
-#include <fcntl.h>
+#include <errno.h>
+#include <poll.h>
+#include <sndio.h>
+#include <stdlib.h>
#include <string.h>
-#include <unistd.h>
-int
-mixread(void *arg, char *buf, size_t len)
+#define MAX_CHANNELS 16
+
+static struct sioctl_hdl *hdl = NULL;
+static struct pollfd *pfds = NULL;
+
+static struct {
+ unsigned int addr;
+ int val;
+} channel[MAX_CHANNELS];
+static size_t nchannels = 0;
+
+static int
+get_output(void)
{
- mixer_devinfo_t dinfo;
- mixer_ctrl_t mctl;
- int fd, master, ret = 0, i = -1;
+ size_t i;
+ int val;
- fd = open("/dev/mixer", O_RDONLY);
- if (fd == -1) {
- warn("open %s", "/dev/mixer");
- return -1;
+ if (nchannels == 0)
+ return 0;
+
+ val = 0;
+ for (i = 0; i < nchannels; i++)
+ val += channel[i].val;
+ return 100 * ((val / (double)nchannels) / 255.0);
+}
+
+static void
+ondesc(void *arg, struct sioctl_desc *desc, int val)
+{
+ size_t i;
+
+ if (desc == NULL)
+ return;
+
+ if (desc->type != SIOCTL_NUM ||
+ strcmp(desc->func, "level") != 0 ||
+ strcmp(desc->node0.name, "output") != 0)
+ return;
+
+ for (i = 0; i < nchannels; i++)
+ if (channel[i].addr == desc->addr)
+ break;
+
+ if (i < nchannels) {
+ channel[i].val = val;
+ return;
}
- dinfo.index = 0;
- /* outputs */
- for (; ; dinfo.index++) {
- ret = ioctl(fd, AUDIO_MIXER_DEVINFO, &dinfo);
- if (ret == -1) {
- warn("AUDIO_MIXER_DEVINFO %s", "/dev/mixer");
- goto out;
- }
- if (dinfo.type == AUDIO_MIXER_CLASS &&
- strcmp(dinfo.label.name, AudioCoutputs) == 0) {
- i = dinfo.index;
+
+ if (nchannels >= MAX_CHANNELS) {
+ warnx("too many channels");
+ return;
+ }
+ channel[i].addr = desc->addr;
+ channel[i].val = val;
+ nchannels++;
+}
+
+static void
+onval(void *arg, unsigned int addr, unsigned int val)
+{
+ size_t i;
+
+ for (i = 0; i < nchannels; i++)
+ if (channel[i].addr == addr) {
+ channel[i].val = val;
break;
}
+}
+
+static int
+do_init(void)
+{
+ hdl = sioctl_open(SIO_DEVANY, SIOCTL_READ, 0);
+ if (hdl == NULL) {
+ warnx("sioctl_open %s", SIO_DEVANY);
+ return 0;
}
- if (i == -1) {
- warnx("no outputs mixer class: %s", "/dev/mixer");
- goto out;
+ if (!sioctl_ondesc(hdl, ondesc, NULL)) {
+ warnx("sioctl_ondesc");
+ sioctl_close(hdl);
+ return 0;
}
- /* outputs.master */
- for (; ; dinfo.index++) {
- ret = ioctl(fd, AUDIO_MIXER_DEVINFO, &dinfo);
- if (ret == -1) {
- warn("AUDIO_MIXER_DEVINFO %s", "/dev/mixer");
+ sioctl_onval(hdl, onval, NULL);
+
+ return 1;
+}
+
+static int
+poll_peek(void)
+{
+ int nfds, revents;
+
+ if (pfds == NULL) {
+ pfds = malloc(sizeof(struct pollfd) * sioctl_nfds(hdl));
+ if (pfds == NULL) {
+ warnx("out of memory");
goto out;
}
- if (dinfo.type == AUDIO_MIXER_VALUE &&
- dinfo.prev == AUDIO_MIXER_LAST &&
- dinfo.mixer_class == i &&
- strcmp(dinfo.label.name, AudioNmaster) == 0)
- break;
}
- mctl.dev = dinfo.index;
- ret = ioctl(fd, AUDIO_MIXER_READ, &mctl);
- if (ret == -1) {
- warn("AUDIO_MIXER_READ %s", "/dev/mixer");
+
+ nfds = sioctl_pollfd(hdl, pfds, POLLIN);
+ if (nfds == 0)
+ return 1;
+ while (poll(pfds, nfds, 0) == -1)
+ if (errno != EINTR) {
+ warn("sioctl poll");
+ goto out;
+ }
+ revents = sioctl_revents(hdl, pfds);
+ if (revents & POLLHUP) {
+ warnx("sioctl disconnected");
goto out;
}
- master = mctl.un.value.level[0] * 100 / 255;
- snprintf(buf, len, "%d%%", master);
+
+ return 1;
+
out:
- close(fd);
- return ret;
+ free(pfds);
+ pfds = NULL;
+ sioctl_close(hdl);
+
+ return 0;
+}
+
+int
+mixread(void *arg, char *buf, size_t len)
+{
+ static int init_done = 0;
+ struct pollfd *pfds;
+ int nfds;
+
+ if (!init_done) {
+ if (!do_init())
+ return -1;
+ init_done = 1;
+ }
+
+ init_done = poll_peek();
+ snprintf(buf, len, "%d%%", get_output());
+
+ return 0;
}
#elif __linux__ && !USE_TINYALSA
#include <alsa/asoundlib.h>
You are viewing proxied material from mx1.adamsgaard.dk. The copyright of proxied material belongs to its original authors. Any comments or complaints in relation to proxied material should be directed to the original authors of the content concerned. Please see the disclaimer for more details.