]> git.sur5r.net Git - i3/i3status/blobdiff - src/print_volume.c
Merge pull request #305 from David96/master
[i3/i3status] / src / print_volume.c
index 58cba2a85b71a1c1de0e74869d8c371ad5a65793..4c0fbdea67970277c1a75dc98868675af06cc930 100644 (file)
@@ -4,6 +4,7 @@
 #include <stdlib.h>
 #include <stdio.h>
 #include <err.h>
+#include <ctype.h>
 #include <yajl/yajl_gen.h>
 #include <yajl/yajl_version.h>
 
@@ -34,15 +35,17 @@ static char *apply_volume_format(const char *fmt, char *outwalk, int ivolume) {
     for (; *walk != '\0'; walk++) {
         if (*walk != '%') {
             *(outwalk++) = *walk;
-            continue;
-        }
-        if (BEGINS_WITH(walk + 1, "%")) {
+
+        } else if (BEGINS_WITH(walk + 1, "%")) {
             outwalk += sprintf(outwalk, "%s", pct_mark);
             walk += strlen("%");
-        }
-        if (BEGINS_WITH(walk + 1, "volume")) {
+
+        } else if (BEGINS_WITH(walk + 1, "volume")) {
             outwalk += sprintf(outwalk, "%d%s", ivolume, pct_mark);
             walk += strlen("volume");
+
+        } else {
+            *(outwalk++) = '%';
         }
     }
     return outwalk;
@@ -60,16 +63,19 @@ void print_volume(yajl_gen json_gen, char *buffer, const char *fmt, const char *
         free(instance);
     }
 
-#ifndef __OpenBSD__
+#if !defined(__DragonFly__) && !defined(__OpenBSD__)
     /* Try PulseAudio first */
 
     /* If the device name has the format "pulse[:N]" where N is the
      * index of the PulseAudio sink then force PulseAudio, optionally
      * overriding the default sink */
     if (!strncasecmp(device, "pulse", strlen("pulse"))) {
-        uint32_t sink_idx = device[5] == ':' ? (uint32_t)atoi(device + 6)
-                                             : DEFAULT_SINK_INDEX;
-        int cvolume = pulse_initialize() ? volume_pulseaudio(sink_idx) : 0;
+        uint32_t sink_idx = device[strlen("pulse")] == ':' ? (uint32_t)atoi(device + strlen("pulse:")) : DEFAULT_SINK_INDEX;
+        const char *sink_name = device[strlen("pulse")] == ':' &&
+                                        !isdigit(device[strlen("pulse:")])
+                                    ? device + strlen("pulse:")
+                                    : NULL;
+        int cvolume = pulse_initialize() ? volume_pulseaudio(sink_idx, sink_name) : 0;
         int ivolume = DECOMPOSE_VOLUME(cvolume);
         bool muted = DECOMPOSE_MUTED(cvolume);
         if (muted) {
@@ -85,7 +91,7 @@ void print_volume(yajl_gen json_gen, char *buffer, const char *fmt, const char *
         goto out;
     } else if (!strcasecmp(device, "default") && pulse_initialize()) {
         /* no device specified or "default" set */
-        int cvolume = volume_pulseaudio(DEFAULT_SINK_INDEX);
+        int cvolume = volume_pulseaudio(DEFAULT_SINK_INDEX, NULL);
         int ivolume = DECOMPOSE_VOLUME(cvolume);
         bool muted = DECOMPOSE_MUTED(cvolume);
         if (ivolume >= 0) {
@@ -147,7 +153,7 @@ void print_volume(yajl_gen json_gen, char *buffer, const char *fmt, const char *
     snd_mixer_selem_id_set_index(sid, mixer_idx);
     snd_mixer_selem_id_set_name(sid, mixer);
     if (!(elem = snd_mixer_find_selem(m, sid))) {
-        fprintf(stderr, "i3status: ALSA: Cannot find mixer %s (index %i)\n",
+        fprintf(stderr, "i3status: ALSA: Cannot find mixer %s (index %u)\n",
                 snd_mixer_selem_id_get_name(sid), snd_mixer_selem_id_get_index(sid));
         snd_mixer_close(m);
         snd_mixer_selem_id_free(sid);
@@ -207,6 +213,7 @@ void print_volume(yajl_gen json_gen, char *buffer, const char *fmt, const char *
 
 #if defined(__OpenBSD__)
     int oclass_idx = -1, master_idx = -1, master_mute_idx = -1;
+    int master_next = AUDIO_MIXER_LAST;
     mixer_devinfo_t devinfo, devinfo2;
     mixer_ctrl_t vinfo;
 
@@ -224,12 +231,17 @@ void print_volume(yajl_gen json_gen, char *buffer, const char *fmt, const char *
 
     devinfo2.index = 0;
     while (ioctl(mixfd, AUDIO_MIXER_DEVINFO, &devinfo2) >= 0) {
-        if ((devinfo2.type == AUDIO_MIXER_VALUE) && (devinfo2.mixer_class == oclass_idx) && (strncmp(devinfo2.label.name, AudioNmaster, MAX_AUDIO_DEV_LEN) == 0))
+        if ((devinfo2.type == AUDIO_MIXER_VALUE) && (devinfo2.mixer_class == oclass_idx) && (strncmp(devinfo2.label.name, AudioNmaster, MAX_AUDIO_DEV_LEN) == 0)) {
             master_idx = devinfo2.index;
+            master_next = devinfo2.next;
+        }
 
         if ((devinfo2.type == AUDIO_MIXER_ENUM) && (devinfo2.mixer_class == oclass_idx) && (strncmp(devinfo2.label.name, AudioNmute, MAX_AUDIO_DEV_LEN) == 0))
-            master_mute_idx = devinfo2.index;
+            if (master_next == devinfo2.index)
+                master_mute_idx = devinfo2.index;
 
+        if (master_next != AUDIO_MIXER_LAST)
+            master_next = devinfo2.next;
         devinfo2.index++;
     }
 
@@ -242,6 +254,7 @@ void print_volume(yajl_gen json_gen, char *buffer, const char *fmt, const char *
 
     vinfo.dev = master_idx;
     vinfo.type = AUDIO_MIXER_VALUE;
+    vinfo.un.value.num_channels = devinfo.un.v.num_channels;
     if (ioctl(mixfd, AUDIO_MIXER_READ, &vinfo) == -1)
         goto out;