*nohtml*

local/bin/dwm-status

   1 //usr/bin/cc -xc $0 -lX11 -o$0~ && exec $0~
   2 
   3 #include <stdio.h>
   4 #include <stdlib.h>
   5 #include <unistd.h>
   6 #include <time.h>
   7 #include <glob.h>
   8 #include <X11/XKBlib.h>
   9 
  10 size_t readfile(const char *path){ // {{{
  11     size_t result = 0;
  12 
  13     glob_t glob_p;
  14     glob(path, 0, NULL, &glob_p);
  15 
  16     for (int i = 0; i < glob_p.gl_pathc; i++){
  17         size_t data;
  18         FILE *fp = fopen(glob_p.gl_pathv[i], "r");
  19         fscanf(fp, "%zu", &data);
  20         fclose(fp);
  21 
  22         result += data;
  23     }
  24 
  25     globfree(&glob_p);
  26     return result;
  27 } // }}}
  28 void network(char *buf, int istx){ // {{{
  29     static size_t now_rx = 0, now_tx = 0;
  30     size_t was_rx = now_rx, was_tx = now_tx;
  31     size_t *now, *was;
  32 
  33     if (istx){
  34         now = &now_tx;
  35         was = &was_tx;
  36     } else {
  37         now = &now_rx;
  38         was = &was_rx;
  39     }
  40 
  41     *now = readfile(istx ?
  42         "/sys/class/net/*/statistics/tx_bytes" :
  43         "/sys/class/net/*/statistics/rx_bytes"
  44     );
  45     sprintf(buf, "0 KB");
  46 
  47     if (*was == 0)
  48         return;
  49 
  50     int i = 0, num = (*now - *was);
  51     const char* map[] = {"B", "KB", "MB"};
  52 
  53     for (; num >= 1024; i++, num /= 1024);
  54 
  55     if (i > 0)
  56         sprintf(buf, "%d %s", num, map[i]);
  57 } // }}}
  58 void volume(char *buf){ // {{{
  59     char path[100];
  60     sprintf(path, "%s/.cache/volume", getenv("HOME"));
  61     sprintf(buf, "%zu", readfile(path));
  62 } // }}}
  63 void volumebar(char *buf, int len){ // {{{
  64     unsigned int i, pos;
  65     char vol[100], bar[100] = "";
  66 
  67     volume(vol);
  68     pos = (len * abs(atoi(vol)) / 100);
  69 
  70     if (pos > len)
  71         return;
  72 
  73     for (i = 0; i < len; i++)
  74         bar[i] = (i < pos ? '=' : '-');
  75 
  76     bar[i] = '-';
  77     bar[pos] = '|';
  78     sprintf(buf, "%s", bar);
  79 } // }}}
  80 void weather(char *buf){ // {{{
  81     FILE *fp;
  82     char path[100];
  83 
  84     sprintf(path, "%s/.cache/weather", getenv("HOME"));
  85 
  86     if ((fp = fopen(path, "r")) != NULL){
  87         fscanf(fp, "%s", buf);
  88         fclose(fp);
  89     }
  90 } // }}}
  91 
  92 int main(int argc, char **argv){
  93     Display *dpy = XOpenDisplay(NULL);
  94 
  95     char status[1000];
  96 
  97     char vol[100] = "";
  98     char wet[100] = "";
  99     XkbStateRec state;
 100 
 101     time_t tm;
 102     char date[100];
 103 
 104     char net_dl[100] = "--";
 105     char net_up[100] = "--";
 106 
 107     for (int timer = 0;; timer++){
 108         volumebar(vol, 20);
 109         XkbGetState(dpy, XkbUseCoreKbd, &state);
 110 
 111         tm = time(NULL);
 112         strftime(date, sizeof(date), "%T", localtime(&tm));
 113 
 114         if (timer % 10 == 0){
 115             weather(wet);
 116             network(net_dl, 0);
 117             network(net_up, 1);
 118         }
 119 
 120         sprintf(status, "  %s %s/s %s/s  %s   %s   %s ",
 121             wet, net_dl, net_up, vol, (state.group == 0 ? "En" : "Ru"), date
 122         );
 123 
 124         printf("%s\n", status);
 125         XStoreName(dpy, DefaultRootWindow(dpy), status);
 126 
 127         usleep(100000);
 128         fflush(stdout);
 129     }
 130 
 131     XCloseDisplay(dpy);
 132 }
 133 
 134 // vim: ft=c