409 lines
12 KiB
Diff
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();
|