status-bat (with optional udev support!)
authorStiletto <blasux@blasux.ru>
Thu, 23 Oct 2014 19:00:42 +0400
changeset 6 de6b88d1fa3c
parent 5 e3ee9aa21b1f
child 7 c0ca2b08f061
status-bat (with optional udev support!)
config.def.h
config.mk
status-bat/Makefile
status-bat/bat.c
status-bat/config.def.h
status-bat/config.mk
--- a/config.def.h	Thu Oct 23 17:57:20 2014 +0400
+++ b/config.def.h	Thu Oct 23 19:00:42 2014 +0400
@@ -1,4 +1,6 @@
 static DPokeSource sources[] = {
+//    { DPOKE_PROGRAM, "./status-wifi/status-wifi wlan0 pango" },
+//    { DPOKE_PROGRAM, "./status-bat/status-bat BAT1 pango" },
     { DPOKE_PROGRAM, "./status-mem/status-mem" },
     { DPOKE_PROGRAM, "./status-loadavg/status-loadavg" },
     { DPOKE_PROGRAM, "./status-time/status-time" },
--- a/config.mk	Thu Oct 23 17:57:20 2014 +0400
+++ b/config.mk	Thu Oct 23 19:00:42 2014 +0400
@@ -16,6 +16,6 @@
 STATUS_CFLAGS = -std=c99 -pedantic -Wall -Os ${STATUS_INCS} ${STATUS_CPPFLAGS}
 STATUS_LDFLAGS = ${STATUS_LIBS} -static
 
-STATUS = status-time status-mem status-loadavg status-wifi
+STATUS = status-time status-mem status-loadavg status-wifi status-bat
 # compiler and linker
 CC = cc
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/status-bat/Makefile	Thu Oct 23 19:00:42 2014 +0400
@@ -0,0 +1,12 @@
+# dwm - dynamic window manager
+# See LICENSE file for copyright and license details.
+
+include ../config.mk
+include config.mk
+
+OUT = status-bat
+SRC = bat.c
+OBJ = ${SRC:.c=.o}
+CONFIG = config.h
+
+include ../Makefile.status.inc
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/status-bat/bat.c	Thu Oct 23 19:00:42 2014 +0400
@@ -0,0 +1,184 @@
+#include <stdio.h>
+#include <stdlib.h>
+#include <math.h>
+
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#include <assert.h>
+#include <string.h>
+#include <limits.h>
+#include <unistd.h>
+#include <errno.h>
+
+#include "config.h"
+#ifdef USE_UDEV
+#include <poll.h>
+#include <libudev.h>
+#endif
+
+char *eights[] = { "ø", "▁", "▂", "▃", "▄", "▅", "▆","▇", "█" };
+
+char *catfile(char *name) {
+    struct stat buffer;
+    int         status;
+    int         f;
+    char*       resbuf;
+    f = open(name, O_RDONLY);
+    if (f == -1) return NULL;
+    status = fstat(f, &buffer);
+    if (status != 0) return NULL;
+    resbuf = malloc(buffer.st_size+1);
+    if (resbuf == NULL) return NULL;
+    status = read(f,resbuf,buffer.st_size);
+    if (status == -1) {
+        free(resbuf);
+        return NULL;
+    }
+    if ((status>0)&&(resbuf[status-1]=='\n'))
+        resbuf[status-1]='\0';
+    resbuf[status]='\0';
+    return resbuf;
+}
+
+int catint(char *name) {
+    char *cont = catfile(name);
+    assert (cont != NULL);
+    int res = atoi(cont);
+    free(cont);
+    return res;
+}
+
+char *color_stop;
+char *color_red;
+char *color_orange;
+char *color_green;
+char *color_none;
+
+char *color(int low,int mid,int rev,int value) {
+    if (value>mid) {
+        return rev ? color_red : color_green;
+    } else if (value>low) {
+        return color_orange;
+    }
+    return rev ? color_green : color_red;
+}
+
+int main(int argc, char *argv[]) {
+    if (argc<=1) {
+        fprintf(stderr, "Usage: %s <BAT1> [term|pango]\n", argv[0]);
+        fflush(stderr);
+        return 1;
+    }
+
+    char *arrow_color;
+    char *eights_color;
+    char *percent_color;
+    char *remtimes_color;
+    if (argc>2 && !strcmp(argv[2],"term")) {
+        color_stop = "\x1b[0m";
+        color_red = "\x1b[1;31m";
+        color_green = "\x1b[1;32m";
+        color_orange = "\x1b[1;33m";
+        color_none = color_stop;
+    } else if (argc>2 && !strcmp(argv[2],"pango")) {
+        color_stop = "</span>";
+        color_red = "<span color='#f33'>";
+        color_green = "<span color='#0f0'>";
+        color_orange = "<span color='#fa0'>";
+        color_none = "<span>";
+    } else {
+        color_stop = color_red = color_green = color_orange = color_none = "";
+    }
+
+#ifdef USE_UDEV
+    struct udev *udev;
+    struct udev_device *dev;
+
+    struct udev_monitor *mon;
+    int mon_fd;
+
+    udev = udev_new();
+    if (!udev) {
+        printf("Can't create udev\n");
+        exit(1);
+    }
+    mon = udev_monitor_new_from_netlink(udev, "udev");
+    udev_monitor_filter_add_match_subsystem_devtype(mon, "power_supply", NULL);
+    udev_monitor_enable_receiving(mon);
+    mon_fd = udev_monitor_get_fd(mon);
+    static struct pollfd fds[1];
+    fds[0].fd = mon_fd;
+    fds[0].events = POLLIN;
+#endif
+    while (1) {
+        char filename[PATH_MAX+1];
+
+        snprintf(filename,PATH_MAX,"/sys/class/power_supply/%s/charge_now",argv[1]);
+        int charge_now = catint(filename);
+
+        snprintf(filename,PATH_MAX,"/sys/class/power_supply/%s/current_now",argv[1]);
+        int current_now = catint(filename);
+
+        snprintf(filename,PATH_MAX,"/sys/class/power_supply/%s/charge_full",argv[1]);
+        int charge_full = catint(filename);
+
+        snprintf(filename,PATH_MAX,"/sys/class/power_supply/%s/status",argv[1]);
+        char *status = catfile(filename);
+
+        int remtime = 0;
+        char remtimes[128];
+        char *arrow;
+
+        remtimes_color = color_none;
+        if (!strcmp(status,"Charging")) {
+            if (current_now != 0)
+                remtime = ((charge_full-charge_now) * 60) / current_now;
+            arrow = "↑";
+            arrow_color = color_orange;
+        }
+        else if (!strcmp(status,"Discharging")) {
+            if (current_now != 0)
+                remtime = (charge_now * 60) / current_now;
+            arrow = "↓";
+            arrow_color = color_none;
+            remtimes_color = color(20,120,0,remtime);
+        } else {
+            arrow = "—";
+            arrow_color = color_green;
+        }
+        free(status);
+        snprintf(remtimes,127,"%d:%02d",remtime/60,remtime%60);
+        //printf("%d %d %d %s %d %s %s\n",charge_now,current_now,charge_full,
+        //    eights[charge_now*8/charge_full], charge_now*100/charge_full,status,remtimes);
+
+
+        int percent = charge_now*100/charge_full;
+        eights_color = percent_color = color(15,40,0,percent);
+        printf("%s%s%s ",eights_color,eights[charge_now*8/charge_full],color_stop);
+        printf("%s%d%%%s ",percent_color,percent,color_stop);
+        printf("%s%s%s ",arrow_color,arrow,color_stop);
+        printf("%s%s%s\n",remtimes_color,remtimes,color_stop);
+        fflush(stdout);
+#ifdef USE_UDEV
+        int poll_status = poll(fds,1, UPDATE_PERIOD*1000);
+        if (poll_status < 0) {
+            if (poll_status != EINTR) {
+                perror("poll");
+                exit(12);
+            }
+        }
+        if (fds[0].revents & POLLIN) {
+            dev = udev_monitor_receive_device(mon);
+            if (dev) {
+                udev_device_unref(dev);
+            } else {
+                printf("UDEV DC\n");
+                exit(13);
+            }
+        }
+#else
+        sleep(UPDATE_PERIOD);
+#endif
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/status-bat/config.def.h	Thu Oct 23 19:00:42 2014 +0400
@@ -0,0 +1,3 @@
+#define UPDATE_PERIOD 60
+#define USE_UDEV
+//#define PANGO_MARKUP // use second argument instead
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/status-bat/config.mk	Thu Oct 23 19:00:42 2014 +0400
@@ -0,0 +1,3 @@
+STATUS_LIBS = -L/usr/lib -ludev
+STATUS_INCS = -std=gnu99
+STATUS_LDFLAGS = ${STATUS_LIBS}