initial import
This commit is contained in:
46
i3status/PKGBUILD
Normal file
46
i3status/PKGBUILD
Normal file
@@ -0,0 +1,46 @@
|
||||
# Maintainer: Jesus E. <heckyel@riseup.net>
|
||||
|
||||
pkgname=i3status
|
||||
pkgver=2.13
|
||||
pkgrel=2
|
||||
pkgdesc="Generates status bar to use for example with i3bar or dzen2"
|
||||
arch=('i686' 'x86_64')
|
||||
url='https://i3wm.org/i3status/'
|
||||
license=('Modified-BSD')
|
||||
groups=('i3')
|
||||
depends=('sndio' 'confuse' 'libnl' 'yajl')
|
||||
makedepends=('asciidoc' 'xmlto')
|
||||
backup=('etc/i3status.conf')
|
||||
options=('docs')
|
||||
source=("https://i3wm.org/i3status/$pkgname-$pkgver.tar.bz2"
|
||||
"build-without-pulse.patch"
|
||||
"add-sndio-backend.patch")
|
||||
sha512sums=('6dadff19e53499d169ba4f491e1f821014b4f92fc3c93d7947c85cbbbdeaba538d02bd8ab98fe266a8f80756a287fd5803ec77a8cd874d50082b5cad309875c2'
|
||||
'3efd2ca3ef71a37689d5e6bbf0acb37571fa5dcf20608bad78f03a23386c4ece09519f7defe8d5ffe6d566b7864f82492316de558e5fdf5c9c2e0c3267ca263f'
|
||||
'd44093627fabc712b6464c1d045b5592995ab8b64b8227e9ee14bef384dc2226557239cbd7c3c67d39ff3fdfa065f507e75832ec2bc470e8a4aedd5d50b2830c')
|
||||
|
||||
prepare() {
|
||||
cd $pkgname-$pkgver
|
||||
|
||||
patch -Np1 -i $srcdir/build-without-pulse.patch
|
||||
patch -Np1 -i $srcdir/add-sndio-backend.patch
|
||||
autoreconf -vi
|
||||
}
|
||||
|
||||
build() {
|
||||
cd $pkgname-$pkgver
|
||||
mkdir build && cd build
|
||||
|
||||
../configure \
|
||||
--prefix=/usr \
|
||||
--sysconfdir=/etc \
|
||||
--disable-sanitizers \
|
||||
--disable-pulseaudio
|
||||
make CPPFLAGS+="-U_FORTIFY_SOURCE"
|
||||
}
|
||||
|
||||
package() {
|
||||
cd $pkgname-$pkgver/build
|
||||
make DESTDIR="$pkgdir" install
|
||||
install -Dm644 -t "$pkgdir"/usr/share/licenses/$pkgname ../LICENSE
|
||||
}
|
||||
229
i3status/add-sndio-backend.patch
Normal file
229
i3status/add-sndio-backend.patch
Normal file
@@ -0,0 +1,229 @@
|
||||
--- /dev/null
|
||||
+++ src/sndio.c
|
||||
@@ -0,0 +1,201 @@
|
||||
+#include <poll.h>
|
||||
+#include <sndio.h>
|
||||
+#include <stdio.h>
|
||||
+#include <stdlib.h>
|
||||
+#include <string.h>
|
||||
+#include "i3status.h"
|
||||
+
|
||||
+struct control {
|
||||
+ struct control *next;
|
||||
+ char name[32];
|
||||
+ unsigned int addr;
|
||||
+ unsigned int max;
|
||||
+ unsigned int value;
|
||||
+ unsigned int muted;
|
||||
+ unsigned int muteaddr;
|
||||
+};
|
||||
+
|
||||
+static int initialized;
|
||||
+static struct sioctl_hdl *hdl;
|
||||
+static struct control *controls;
|
||||
+static struct pollfd *pfds;
|
||||
+
|
||||
+/*
|
||||
+ * new control registered or control changed
|
||||
+ */
|
||||
+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;
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ /*
|
||||
+ * if we find an output.mute, associate it with its output.level
|
||||
+ */
|
||||
+ if (d->type == SIOCTL_SW &&
|
||||
+ d->group[0] == 0 &&
|
||||
+ strcmp(d->node0.name, "output") == 0 &&
|
||||
+ strcmp(d->func, "mute") == 0) {
|
||||
+ char name[32];
|
||||
+ snprintf(name, sizeof(name), "%s%d", d->node0.name, d->node0.unit);
|
||||
+ for (pi = &controls; (i = *pi) != NULL; pi = &i->next) {
|
||||
+ if (strcmp(name, i->name) == 0) {
|
||||
+ i->muted = val;
|
||||
+ i->muteaddr = d->addr;
|
||||
+ break;
|
||||
+ }
|
||||
+ }
|
||||
+ return;
|
||||
+ }
|
||||
+
|
||||
+ /*
|
||||
+ * we're interested in top-level output.level controls only
|
||||
+ */
|
||||
+ if (d->type != SIOCTL_NUM ||
|
||||
+ d->group[0] != 0 ||
|
||||
+ strcmp(d->node0.name, "output") != 0 ||
|
||||
+ strcmp(d->func, "level") != 0)
|
||||
+ return;
|
||||
+
|
||||
+ i = malloc(sizeof(struct control));
|
||||
+ if (i == NULL) {
|
||||
+ fprintf(stderr, "sndio: failed to allocate control\n");
|
||||
+ return;
|
||||
+ }
|
||||
+
|
||||
+ snprintf(i->name, sizeof(i->name), "%s%d", d->node0.name, d->node0.unit);
|
||||
+ i->addr = d->addr;
|
||||
+ i->max = d->maxval;
|
||||
+ i->value = val;
|
||||
+ i->next = controls;
|
||||
+ i->muted = 0;
|
||||
+ i->muteaddr = -1;
|
||||
+ controls = i;
|
||||
+}
|
||||
+
|
||||
+/*
|
||||
+ * control value changed
|
||||
+ */
|
||||
+static void onval(void *unused, unsigned int addr, unsigned int value)
|
||||
+{
|
||||
+ struct control *c;
|
||||
+
|
||||
+ for (c = controls; ; c = c->next) {
|
||||
+ if (c == NULL)
|
||||
+ return;
|
||||
+ if (c->addr == addr) {
|
||||
+ c->value = value;
|
||||
+ return;
|
||||
+ }
|
||||
+ if (c->muteaddr == addr) {
|
||||
+ c->muted = value;
|
||||
+ return;
|
||||
+ }
|
||||
+ }
|
||||
+}
|
||||
+
|
||||
+static void cleanup(void)
|
||||
+{
|
||||
+ struct control *c;
|
||||
+
|
||||
+ if (hdl) {
|
||||
+ sioctl_close(hdl);
|
||||
+ hdl = NULL;
|
||||
+ }
|
||||
+ if (pfds) {
|
||||
+ free(pfds);
|
||||
+ pfds = NULL;
|
||||
+ }
|
||||
+ while ((c = controls) != NULL) {
|
||||
+ controls = c->next;
|
||||
+ free(c);
|
||||
+ }
|
||||
+}
|
||||
+
|
||||
+static int init(void)
|
||||
+{
|
||||
+ /* open device */
|
||||
+ hdl = sioctl_open(SIO_DEVANY, SIOCTL_READ, 0);
|
||||
+ if (hdl == NULL) {
|
||||
+ fprintf(stderr, "sndio: cannot open device\n");
|
||||
+ goto failed;
|
||||
+ }
|
||||
+
|
||||
+ /* register call-back for control description changes */
|
||||
+ if (!sioctl_ondesc(hdl, ondesc, NULL)) {
|
||||
+ fprintf(stderr, "sndio: cannot get description\n");
|
||||
+ goto failed;
|
||||
+ }
|
||||
+
|
||||
+ /* register call-back for volume changes */
|
||||
+ if (!sioctl_onval(hdl, onval, NULL)) {
|
||||
+ fprintf(stderr, "sndio: cannot get values\n");
|
||||
+ goto failed;
|
||||
+ }
|
||||
+
|
||||
+ /* allocate structures for poll() syscall */
|
||||
+ pfds = calloc(sioctl_nfds(hdl), sizeof(struct pollfd));
|
||||
+ if (pfds == NULL) {
|
||||
+ fprintf(stderr, "sndio: cannot allocate pollfd structures\n");
|
||||
+ goto failed;
|
||||
+ }
|
||||
+ return 1;
|
||||
+failed:
|
||||
+ cleanup();
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+int volume_sndio(int *vol, int *muted)
|
||||
+{
|
||||
+ struct control *c;
|
||||
+ int n, v;
|
||||
+
|
||||
+ if (!initialized) {
|
||||
+ initialized = 1;
|
||||
+ init();
|
||||
+ }
|
||||
+ if (hdl == NULL)
|
||||
+ return -1;
|
||||
+
|
||||
+ /* check if controls changed */
|
||||
+ n = sioctl_pollfd(hdl, pfds, POLLIN);
|
||||
+ if (n > 0) {
|
||||
+ n = poll(pfds, n, 0);
|
||||
+ if (n > 0) {
|
||||
+ if (sioctl_revents(hdl, pfds) & POLLHUP) {
|
||||
+ fprintf(stderr, "sndio: disconnected\n");
|
||||
+ cleanup();
|
||||
+ return -1;
|
||||
+ }
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ /*
|
||||
+ * get control value: as there may be multiple
|
||||
+ * channels, return the minimum
|
||||
+ */
|
||||
+ *vol = 100;
|
||||
+ *muted = 0;
|
||||
+ for (c = controls; c != NULL; c = c->next) {
|
||||
+ v = (c->value * 100 + c->max / 2) / c->max;
|
||||
+ if (v < *vol) {
|
||||
+ *vol = v;
|
||||
+ *muted = c->muted;
|
||||
+
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
||||
--- a/configure.ac
|
||||
+++ b/configure.ac
|
||||
@@ -91,6 +91,13 @@ case $host_os in
|
||||
;;
|
||||
esac
|
||||
|
||||
+# if sndio is available, define USE_SNDIO
|
||||
+AC_CHECK_HEADER(sndio.h,
|
||||
+ [AC_CHECK_LIB([sndio], [sio_open], [
|
||||
+ AC_SUBST(SNDIO_LIBS, "-lsndio")
|
||||
+ AC_DEFINE([USE_SNDIO], [], [Use sndio])
|
||||
+ ], [])], [])
|
||||
+
|
||||
dnl TODO: check for libbsd for GNU/kFreeBSD
|
||||
|
||||
# Checks for programs.
|
||||
--- a/include/i3status.h
|
||||
+++ b/include/i3status.h
|
||||
@@ -425,6 +425,7 @@ void print_volume(volume_ctx_t *ctx);
|
||||
|
||||
bool process_runs(const char *path);
|
||||
int volume_pulseaudio(uint32_t sink_idx, const char *sink_name);
|
||||
+int volume_sndio(int *vol, int *muted);
|
||||
bool description_pulseaudio(uint32_t sink_idx, const char *sink_name, char buffer[MAX_SINK_DESCRIPTION_LEN]);
|
||||
bool pulse_initialize(void);
|
||||
408
i3status/build-without-pulse.patch
Normal file
408
i3status/build-without-pulse.patch
Normal file
@@ -0,0 +1,408 @@
|
||||
--- a/configure.ac 2019-06-30 19:53:24.000000000 +0200
|
||||
+++ b/configure.ac 2021-07-19 13:39:39.769190529 +0200
|
||||
@@ -80,11 +80,24 @@
|
||||
PKG_CHECK_MODULES([CONFUSE], [libconfuse])
|
||||
PKG_CHECK_MODULES([YAJL], [yajl])
|
||||
|
||||
+AC_ARG_ENABLE(pulseaudio,
|
||||
+ AS_HELP_STRING(
|
||||
+ [--disable-pulseaudio],
|
||||
+ [build without pulseaudio support]),
|
||||
+ [ax_pulse=$enableval],
|
||||
+ [ax_pulse=yes])
|
||||
+AM_CONDITIONAL([PULSE], [test x$ax_pulse = xyes])
|
||||
+AS_IF([test x"$ax_pulse" = x"yes"],
|
||||
+ [PKG_CHECK_MODULES([PULSE], [libpulse])])
|
||||
+pulse_def=0
|
||||
+AS_IF([test x"$ax_pulse" = x"yes"],
|
||||
+ [pulse_def=1])
|
||||
+AC_DEFINE_UNQUOTED([HAS_PULSEAUDIO], [$pulse_def], [Build with pulseaudio])
|
||||
+
|
||||
case $host_os in
|
||||
linux*)
|
||||
PKG_CHECK_MODULES([NLGENL], [libnl-genl-3.0])
|
||||
PKG_CHECK_MODULES([ALSA], [alsa])
|
||||
- PKG_CHECK_MODULES([PULSE], [libpulse])
|
||||
;;
|
||||
netbsd*)
|
||||
AC_SEARCH_LIBS([prop_string_create], [prop])
|
||||
@@ -101,12 +114,20 @@
|
||||
AC_PROG_RANLIB
|
||||
AC_PROG_LN_S
|
||||
|
||||
-AC_PATH_PROG([PATH_ASCIIDOC], [asciidoc], [no])
|
||||
-AS_IF([test x"$PATH_ASCIIDOC" = x"no"],
|
||||
- [AC_MSG_ERROR([asciidoc is required for generating man pages])])
|
||||
-AC_PATH_PROG([PATH_XMLTO], [xmlto], [no])
|
||||
-AS_IF([test x"$PATH_XMLTO" = x"no"],
|
||||
- [AC_MSG_ERROR([xmlto is required for generating man pages])])
|
||||
+AC_ARG_ENABLE(mans,
|
||||
+ AS_HELP_STRING(
|
||||
+ [--disable-mans],
|
||||
+ [disable building manual pages]),
|
||||
+ [ax_mans=$enableval],
|
||||
+ [ax_mans=yes])
|
||||
+AS_IF([test x$ax_mans = xyes], [
|
||||
+ AC_PATH_PROG([PATH_ASCIIDOC], [asciidoc])
|
||||
+])
|
||||
+AS_IF([test x$ax_mans = xyes], [
|
||||
+ AC_PATH_PROG([PATH_XMLTO], [xmlto])
|
||||
+ AC_PATH_PROG([PATH_POD2MAN], [pod2man])
|
||||
+])
|
||||
+AM_CONDITIONAL([BUILD_MANS], [test x$ax_mans = xyes && test x$PATH_ASCIIDOC != x && test x$PATH_XMLTO != x && test x$PATH_POD2MAN != x])
|
||||
|
||||
AM_PROG_AR
|
||||
|
||||
@@ -131,15 +152,12 @@
|
||||
|
||||
AC_OUTPUT
|
||||
|
||||
-in_git_worktree=`git rev-parse --is-inside-work-tree 2>/dev/null`
|
||||
-if [ "$in_git_worktree" = "true" ]; then
|
||||
- git_dir=`git rev-parse --git-dir 2>/dev/null`
|
||||
- srcdir=`dirname "$git_dir"`
|
||||
- exclude_dir=`pwd | sed "s,^$srcdir,,g"`
|
||||
- if ! grep -q "^$exclude_dir" "$git_dir/info/exclude"; then
|
||||
- echo "$exclude_dir" >> "$git_dir/info/exclude"
|
||||
- fi
|
||||
-fi
|
||||
+AS_IF([test -d ${srcdir}/.git], [
|
||||
+ srcdir_abs=`readlink -f "$srcdir"`
|
||||
+ exclude_dir=`pwd | sed "s,^$srcdir_abs/*,,g"`
|
||||
+ AS_IF([! grep -q "^$exclude_dir" "${srcdir}/.git/info/exclude"],
|
||||
+ [echo "$exclude_dir" >> "${srcdir}/.git/info/exclude"])])
|
||||
+
|
||||
|
||||
echo \
|
||||
"--------------------------------------------------------------------------------
|
||||
@@ -151,6 +169,7 @@
|
||||
AS_HELP_STRING([enable debug flags:], [${ax_enable_debug}])
|
||||
AS_HELP_STRING([code coverage:], [${CODE_COVERAGE_ENABLED}])
|
||||
AS_HELP_STRING([enabled sanitizers:], [${ax_enabled_sanitizers}])
|
||||
+AS_HELP_STRING([pulseaudio support:], [${ax_pulse}])
|
||||
|
||||
To compile, run:
|
||||
|
||||
--- a/Makefile.am 2019-02-21 15:35:12.000000000 +0100
|
||||
+++ b/Makefile.am 2021-07-19 13:47:05.320995008 +0200
|
||||
@@ -5,6 +5,7 @@
|
||||
|
||||
bin_PROGRAMS = i3status
|
||||
|
||||
+if BUILD_MANS
|
||||
dist_man1_MANS = \
|
||||
$(asciidoc_MANS)
|
||||
|
||||
@@ -17,6 +18,9 @@
|
||||
|
||||
man/%.xml: man/%.man man/asciidoc.conf man/$(dirstamp)
|
||||
$(AM_V_GEN) @PATH_ASCIIDOC@ -d manpage -b docbook -f $(top_builddir)/man/asciidoc.conf -o $@ $<
|
||||
+else
|
||||
+asciidoc_MANS =
|
||||
+endif
|
||||
|
||||
AM_CPPFLAGS = \
|
||||
-DSYSCONFDIR="\"$(sysconfdir)\"" \
|
||||
@@ -50,6 +54,7 @@
|
||||
i3status.c \
|
||||
src/auto_detect_format.c \
|
||||
src/first_network_device.c \
|
||||
+ src/format_placeholders.c \
|
||||
src/general.c \
|
||||
src/output.c \
|
||||
src/print_battery_info.c \
|
||||
@@ -68,8 +73,11 @@
|
||||
src/print_volume.c \
|
||||
src/print_wireless_info.c \
|
||||
src/print_file_contents.c \
|
||||
- src/process_runs.c \
|
||||
- src/pulse.c
|
||||
+ src/process_runs.c
|
||||
+
|
||||
+if PULSE
|
||||
+i3status_SOURCES += src/pulse.c
|
||||
+endif
|
||||
|
||||
dist_sysconf_DATA = \
|
||||
i3status.conf
|
||||
--- a/src/print_volume.c 2019-01-23 09:03:56.000000000 +0100
|
||||
+++ b/src/print_volume.c 2021-07-19 13:53:19.409302195 +0200
|
||||
@@ -21,7 +21,7 @@
|
||||
#include <sys/soundcard.h>
|
||||
#endif
|
||||
|
||||
-#ifdef __OpenBSD__
|
||||
+#if defined(__NetBSD__) || defined(__OpenBSD__)
|
||||
#include <fcntl.h>
|
||||
#include <unistd.h>
|
||||
#include <sys/audioio.h>
|
||||
@@ -31,6 +31,8 @@
|
||||
#include "i3status.h"
|
||||
#include "queue.h"
|
||||
|
||||
+#define STRING_SIZE 10
|
||||
+
|
||||
#define ALSA_VOLUME(channel) \
|
||||
err = snd_mixer_selem_get_##channel##_dB_range(elem, &min, &max) || \
|
||||
snd_mixer_selem_get_##channel##_dB(elem, 0, &val); \
|
||||
@@ -48,30 +50,20 @@
|
||||
fmt = fmt_muted; \
|
||||
}
|
||||
|
||||
-static char *apply_volume_format(const char *fmt, char *outwalk, int ivolume, const char *devicename) {
|
||||
- const char *walk = fmt;
|
||||
+static char *apply_volume_format(const char *fmt, char *buffer, int ivolume, const char *devicename) {
|
||||
+ char string_volume[STRING_SIZE];
|
||||
|
||||
- for (; *walk != '\0'; walk++) {
|
||||
- if (*walk != '%') {
|
||||
- *(outwalk++) = *walk;
|
||||
-
|
||||
- } else if (BEGINS_WITH(walk + 1, "%")) {
|
||||
- outwalk += sprintf(outwalk, "%s", pct_mark);
|
||||
- walk += strlen("%");
|
||||
-
|
||||
- } else if (BEGINS_WITH(walk + 1, "volume")) {
|
||||
- outwalk += sprintf(outwalk, "%d%s", ivolume, pct_mark);
|
||||
- walk += strlen("volume");
|
||||
-
|
||||
- } else if (BEGINS_WITH(walk + 1, "devicename")) {
|
||||
- outwalk += sprintf(outwalk, "%s", devicename);
|
||||
- walk += strlen("devicename");
|
||||
+ snprintf(string_volume, STRING_SIZE, "%d%s", ivolume, pct_mark);
|
||||
|
||||
- } else {
|
||||
- *(outwalk++) = '%';
|
||||
- }
|
||||
- }
|
||||
- return outwalk;
|
||||
+ placeholder_t placeholders[] = {
|
||||
+ {.name = "%%", .value = pct_mark},
|
||||
+ {.name = "%volume", .value = string_volume},
|
||||
+ {.name = "%devicename", .value = devicename}};
|
||||
+
|
||||
+ const size_t num = sizeof(placeholders) / sizeof(placeholder_t);
|
||||
+ buffer = format_placeholders(fmt, &placeholders[0], num);
|
||||
+
|
||||
+ return buffer;
|
||||
}
|
||||
|
||||
void print_volume(yajl_gen json_gen, char *buffer, const char *fmt, const char *fmt_muted, const char *device, const char *mixer, int mixer_idx) {
|
||||
@@ -86,7 +78,7 @@
|
||||
free(instance);
|
||||
}
|
||||
|
||||
-#if !defined(__DragonFly__) && !defined(__OpenBSD__)
|
||||
+#if HAS_PULSEAUDIO
|
||||
/* Try PulseAudio first */
|
||||
|
||||
/* If the device name has the format "pulse[:N]" where N is the
|
||||
@@ -119,11 +111,11 @@
|
||||
/* negative result means error, stick to 0 */
|
||||
if (ivolume < 0)
|
||||
ivolume = 0;
|
||||
- outwalk = apply_volume_format(muted ? fmt_muted : fmt,
|
||||
- outwalk,
|
||||
- ivolume,
|
||||
- description);
|
||||
- goto out;
|
||||
+ buffer = apply_volume_format(muted ? fmt_muted : fmt,
|
||||
+ buffer,
|
||||
+ ivolume,
|
||||
+ description);
|
||||
+ goto out_with_format;
|
||||
} else if (!strcasecmp(device, "default") && pulse_initialize()) {
|
||||
/* no device specified or "default" set */
|
||||
char description[MAX_SINK_DESCRIPTION_LEN];
|
||||
@@ -136,11 +128,11 @@
|
||||
START_COLOR("color_degraded");
|
||||
pbval = 0;
|
||||
}
|
||||
- outwalk = apply_volume_format(muted ? fmt_muted : fmt,
|
||||
- outwalk,
|
||||
- ivolume,
|
||||
- description);
|
||||
- goto out;
|
||||
+ buffer = apply_volume_format(muted ? fmt_muted : fmt,
|
||||
+ buffer,
|
||||
+ ivolume,
|
||||
+ description);
|
||||
+ goto out_with_format;
|
||||
}
|
||||
/* negative result or NULL description means error, fail PulseAudio attempt */
|
||||
}
|
||||
@@ -242,13 +234,14 @@
|
||||
ALSA_MUTE_SWITCH(capture)
|
||||
}
|
||||
|
||||
- outwalk = apply_volume_format(fmt, outwalk, avg, mixer_name);
|
||||
+ buffer = apply_volume_format(fmt, buffer, avg, mixer_name);
|
||||
|
||||
snd_mixer_close(m);
|
||||
snd_mixer_selem_id_free(sid);
|
||||
+ goto out_with_format;
|
||||
|
||||
#endif
|
||||
-#if defined(__FreeBSD__) || defined(__OpenBSD__) || defined(__DragonFly__)
|
||||
+#if defined(__FreeBSD__) || defined(__NetBSD__) || defined(__OpenBSD__) || defined(__DragonFly__)
|
||||
char *mixerpath;
|
||||
char defaultmixer[] = "/dev/mixer";
|
||||
int mixfd, vol, devmask = 0;
|
||||
@@ -261,7 +254,7 @@
|
||||
mixerpath = defaultmixer;
|
||||
|
||||
if ((mixfd = open(mixerpath, O_RDWR)) < 0) {
|
||||
-#if defined(__OpenBSD__)
|
||||
+#if defined(__NetBSD__) || defined(__OpenBSD__)
|
||||
warn("audioio: Cannot open mixer");
|
||||
#else
|
||||
warn("OSS: Cannot open mixer");
|
||||
@@ -272,7 +265,7 @@
|
||||
if (mixer_idx > 0)
|
||||
free(mixerpath);
|
||||
|
||||
-#if defined(__OpenBSD__)
|
||||
+#if defined(__NetBSD__) || defined(__OpenBSD__)
|
||||
int oclass_idx = -1, master_idx = -1, master_mute_idx = -1;
|
||||
int master_next = AUDIO_MIXER_LAST;
|
||||
mixer_devinfo_t devinfo, devinfo2;
|
||||
@@ -327,15 +320,17 @@
|
||||
vol = (int)vinfo.un.value.level[AUDIO_MIXER_LEVEL_MONO];
|
||||
}
|
||||
|
||||
- vinfo.dev = master_mute_idx;
|
||||
- vinfo.type = AUDIO_MIXER_ENUM;
|
||||
- if (ioctl(mixfd, AUDIO_MIXER_READ, &vinfo) == -1)
|
||||
- goto out;
|
||||
+ if (master_mute_idx != -1) {
|
||||
+ vinfo.dev = master_mute_idx;
|
||||
+ vinfo.type = AUDIO_MIXER_ENUM;
|
||||
+ if (ioctl(mixfd, AUDIO_MIXER_READ, &vinfo) == -1)
|
||||
+ goto out;
|
||||
|
||||
- if (master_mute_idx != -1 && vinfo.un.ord) {
|
||||
- START_COLOR("color_degraded");
|
||||
- fmt = fmt_muted;
|
||||
- pbval = 0;
|
||||
+ if (vinfo.un.ord) {
|
||||
+ START_COLOR("color_degraded");
|
||||
+ fmt = fmt_muted;
|
||||
+ pbval = 0;
|
||||
+ }
|
||||
}
|
||||
|
||||
#else
|
||||
@@ -354,13 +349,20 @@
|
||||
}
|
||||
|
||||
#endif
|
||||
- outwalk = apply_volume_format(fmt, outwalk, vol & 0x7f, devicename);
|
||||
+ buffer = apply_volume_format(fmt, buffer, vol & 0x7f, devicename);
|
||||
close(mixfd);
|
||||
+ goto out_with_format;
|
||||
#endif
|
||||
|
||||
out:
|
||||
- *outwalk = '\0';
|
||||
if (!pbval)
|
||||
END_COLOR;
|
||||
OUTPUT_FULL_TEXT(buffer);
|
||||
+ return;
|
||||
+
|
||||
+out_with_format:
|
||||
+ if (!pbval)
|
||||
+ END_COLOR;
|
||||
+ OUTPUT_FULL_TEXT(buffer);
|
||||
+ free(buffer);
|
||||
}
|
||||
--- /dev/null 2021-07-19 09:18:28.360000528 +0200
|
||||
+++ b/src/format_placeholders.c 2021-07-19 13:57:16.830921169 +0200
|
||||
@@ -0,0 +1,70 @@
|
||||
+/*
|
||||
+ * vim:ts=4:sw=4:expandtab
|
||||
+ *
|
||||
+ * i3 - an improved dynamic tiling window manager
|
||||
+ * © 2009 Michael Stapelberg and contributors (see also: LICENSE)
|
||||
+ *
|
||||
+ */
|
||||
+// copied from i3:libi3/format_placeholders.c
|
||||
+#include <stdbool.h>
|
||||
+#include <stdint.h>
|
||||
+#include <stdio.h>
|
||||
+#include <stdlib.h>
|
||||
+#include <string.h>
|
||||
+
|
||||
+#include "i3status.h"
|
||||
+
|
||||
+#ifndef CS_STARTS_WITH
|
||||
+#define CS_STARTS_WITH(string, needle) (strncmp((string), (needle), strlen((needle))) == 0)
|
||||
+#endif
|
||||
+
|
||||
+/*
|
||||
+ * Replaces occurrences of the defined placeholders in the format string.
|
||||
+ *
|
||||
+ */
|
||||
+char *format_placeholders(const char *format, placeholder_t *placeholders, int num) {
|
||||
+ if (format == NULL)
|
||||
+ return NULL;
|
||||
+
|
||||
+ /* We have to first iterate over the string to see how much buffer space
|
||||
+ * we need to allocate. */
|
||||
+ int buffer_len = strlen(format) + 1;
|
||||
+ for (const char *walk = format; *walk != '\0'; walk++) {
|
||||
+ for (int i = 0; i < num; i++) {
|
||||
+ if (!CS_STARTS_WITH(walk, placeholders[i].name))
|
||||
+ continue;
|
||||
+
|
||||
+ buffer_len = buffer_len - strlen(placeholders[i].name) + strlen(placeholders[i].value);
|
||||
+ walk += strlen(placeholders[i].name) - 1;
|
||||
+ break;
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ /* Now we can parse the format string. */
|
||||
+ char buffer[buffer_len];
|
||||
+ char *outwalk = buffer;
|
||||
+ for (const char *walk = format; *walk != '\0'; walk++) {
|
||||
+ if (*walk != '%') {
|
||||
+ *(outwalk++) = *walk;
|
||||
+ continue;
|
||||
+ }
|
||||
+
|
||||
+ bool matched = false;
|
||||
+ for (int i = 0; i < num; i++) {
|
||||
+ if (!CS_STARTS_WITH(walk, placeholders[i].name)) {
|
||||
+ continue;
|
||||
+ }
|
||||
+
|
||||
+ matched = true;
|
||||
+ outwalk += sprintf(outwalk, "%s", placeholders[i].value);
|
||||
+ walk += strlen(placeholders[i].name) - 1;
|
||||
+ break;
|
||||
+ }
|
||||
+
|
||||
+ if (!matched)
|
||||
+ *(outwalk++) = *walk;
|
||||
+ }
|
||||
+
|
||||
+ *outwalk = '\0';
|
||||
+ return sstrdup(buffer);
|
||||
+}
|
||||
--- a/include/i3status.h 2019-02-21 15:35:12.000000000 +0100
|
||||
+++ b/include/i3status.h 2021-07-19 14:06:39.618462946 +0200
|
||||
@@ -198,6 +199,16 @@
|
||||
void reset_cursor(void);
|
||||
void maybe_escape_markup(char *text, char **buffer);
|
||||
|
||||
+// copied from i3:libi3/format_placeholders.c
|
||||
+/* src/format_placeholders.c */
|
||||
+typedef struct {
|
||||
+ /* The placeholder to be replaced, e.g., "%title". */
|
||||
+ const char *name;
|
||||
+ /* The value this placeholder should be replaced with. */
|
||||
+ const char *value;
|
||||
+} placeholder_t;
|
||||
+char *format_placeholders(const char *format, placeholder_t *placeholders, int num);
|
||||
+
|
||||
/* src/auto_detect_format.c */
|
||||
char *auto_detect_format();
|
||||
Reference in New Issue
Block a user