Files
extra/i3status/build-without-pulse.patch
2025-06-22 20:39:04 -05:00

409 lines
12 KiB
Diff

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