* dwmstatus for OpenBSD
       
   URI git clone git://git.codevoid.de/dwmstatus-sdk
   DIR Log
   DIR Files
   DIR Refs
   DIR LICENSE
       ---
   DIR commit 813aed994aac60d514a3387d3346b0d05c5a3257
   DIR parent c85db57b426932e6f6a5664ebefa2c6c2d7b559e
   URI Author: Stefan Hagen <sh+git[at]codevoid[dot]de>
       Date:   Mon, 21 May 2018 09:03:58 +0200
       
       Add volume via mixer device
       
       Diffstat:
         M dwmstatus.c                         |      38 ++++++++++++++++++++++++++++++-
       
       1 file changed, 37 insertions(+), 1 deletion(-)
       ---
   DIR diff --git a/dwmstatus.c b/dwmstatus.c
       @@ -17,6 +17,8 @@
        #include <sys/types.h>
        #include <sys/sysctl.h>
        #include <sys/wait.h>
       +#include <fcntl.h>
       +#include <sys/soundcard.h>
        
        #include <X11/Xlib.h>
        
       @@ -53,6 +55,10 @@ smprintf(char *fmt, ...)
            return ret;
        }
        
       +/* Use FreeBSDs sysctl to retrieve information
       + * Sysctl may return different types, so you want
       + * to call the appropriate smprintf() in main();
       + */ 
        char *
        getsysctl(char *input_str) {
            char   *ret_val;
       @@ -74,6 +80,33 @@ getsysctl(char *input_str) {
            return ret_val;
        }
        
       +/* Use FreeBSDs mixer device to determine the master
       + * volume. Returns the volume %.
       + */
       +char *
       +getvolume(char *mixerpath) {
       +    char defaultmixer[] = "/dev/mixer";
       +    char *ret_val;
       +    int mixfd, vol, devmask = 0;
       +
       +    if (mixerpath == NULL)
       +        mixerpath = defaultmixer;
       +
       +    if ((mixfd = open(mixerpath, O_RDWR)) < 0) {
       +        smprintf(("Cannot open mixer"));
       +    }
       +    
       +    if (ioctl(mixfd, SOUND_MIXER_READ_DEVMASK, &devmask) == -1) {
       +        smprintf(("Cannot read mixer info"));
       +    }
       +    if (ioctl(mixfd, MIXER_READ(0), &vol) == -1) {
       +        smprintf(("Cannot read mixer info"));
       +    }
       +    close(mixfd);
       +    return smprintf("%i", vol & 0x7f);
       +} 
       +
       +
        void
        settz(char *tzname)
        {
       @@ -209,6 +242,7 @@ main(void)
            char *datetime;
            char *cputemp;
            char *battery;
       +    char *volume;
        
            if (!(dpy = XOpenDisplay(NULL))) {
                fprintf(stderr, "dwmstatus: cannot open display.\n");
       @@ -221,15 +255,17 @@ main(void)
                // battery
                battery  = smprintf("%i", getsysctl("hw.acpi.battery.life"));
                // audio volume
       +        volume = smprintf("%s", getvolume("/dev/mixer"));
                // IP + (lan speed / wlan ssid)
                // free disk space (root/home)
                // date and time: done
                datetime = mktimes("%d.%m.%Y %H:%M", tzberlin);
        
                // assemble and display
       -        status   = smprintf(" CPU:%s°C BAT:%s%% | %s ", cputemp, battery, datetime);
       +        status   = smprintf(" CPU:%s°C BAT:%s%% VOL:%s | %s ", cputemp, battery, volume, datetime);
                setstatus(status);
        
       +        free(volume);
                free(battery);
                free(cputemp);
                free(datetime);