status-bat/bat.c
changeset 6 de6b88d1fa3c
child 9 96b47c0505b5
equal deleted inserted replaced
5:e3ee9aa21b1f 6:de6b88d1fa3c
       
     1 #include <stdio.h>
       
     2 #include <stdlib.h>
       
     3 #include <math.h>
       
     4 
       
     5 #include <sys/types.h>
       
     6 #include <sys/stat.h>
       
     7 #include <fcntl.h>
       
     8 #include <assert.h>
       
     9 #include <string.h>
       
    10 #include <limits.h>
       
    11 #include <unistd.h>
       
    12 #include <errno.h>
       
    13 
       
    14 #include "config.h"
       
    15 #ifdef USE_UDEV
       
    16 #include <poll.h>
       
    17 #include <libudev.h>
       
    18 #endif
       
    19 
       
    20 char *eights[] = { "ø", "▁", "▂", "▃", "▄", "▅", "▆","▇", "█" };
       
    21 
       
    22 char *catfile(char *name) {
       
    23     struct stat buffer;
       
    24     int         status;
       
    25     int         f;
       
    26     char*       resbuf;
       
    27     f = open(name, O_RDONLY);
       
    28     if (f == -1) return NULL;
       
    29     status = fstat(f, &buffer);
       
    30     if (status != 0) return NULL;
       
    31     resbuf = malloc(buffer.st_size+1);
       
    32     if (resbuf == NULL) return NULL;
       
    33     status = read(f,resbuf,buffer.st_size);
       
    34     if (status == -1) {
       
    35         free(resbuf);
       
    36         return NULL;
       
    37     }
       
    38     if ((status>0)&&(resbuf[status-1]=='\n'))
       
    39         resbuf[status-1]='\0';
       
    40     resbuf[status]='\0';
       
    41     return resbuf;
       
    42 }
       
    43 
       
    44 int catint(char *name) {
       
    45     char *cont = catfile(name);
       
    46     assert (cont != NULL);
       
    47     int res = atoi(cont);
       
    48     free(cont);
       
    49     return res;
       
    50 }
       
    51 
       
    52 char *color_stop;
       
    53 char *color_red;
       
    54 char *color_orange;
       
    55 char *color_green;
       
    56 char *color_none;
       
    57 
       
    58 char *color(int low,int mid,int rev,int value) {
       
    59     if (value>mid) {
       
    60         return rev ? color_red : color_green;
       
    61     } else if (value>low) {
       
    62         return color_orange;
       
    63     }
       
    64     return rev ? color_green : color_red;
       
    65 }
       
    66 
       
    67 int main(int argc, char *argv[]) {
       
    68     if (argc<=1) {
       
    69         fprintf(stderr, "Usage: %s <BAT1> [term|pango]\n", argv[0]);
       
    70         fflush(stderr);
       
    71         return 1;
       
    72     }
       
    73 
       
    74     char *arrow_color;
       
    75     char *eights_color;
       
    76     char *percent_color;
       
    77     char *remtimes_color;
       
    78     if (argc>2 && !strcmp(argv[2],"term")) {
       
    79         color_stop = "\x1b[0m";
       
    80         color_red = "\x1b[1;31m";
       
    81         color_green = "\x1b[1;32m";
       
    82         color_orange = "\x1b[1;33m";
       
    83         color_none = color_stop;
       
    84     } else if (argc>2 && !strcmp(argv[2],"pango")) {
       
    85         color_stop = "</span>";
       
    86         color_red = "<span color='#f33'>";
       
    87         color_green = "<span color='#0f0'>";
       
    88         color_orange = "<span color='#fa0'>";
       
    89         color_none = "<span>";
       
    90     } else {
       
    91         color_stop = color_red = color_green = color_orange = color_none = "";
       
    92     }
       
    93 
       
    94 #ifdef USE_UDEV
       
    95     struct udev *udev;
       
    96     struct udev_device *dev;
       
    97 
       
    98     struct udev_monitor *mon;
       
    99     int mon_fd;
       
   100 
       
   101     udev = udev_new();
       
   102     if (!udev) {
       
   103         printf("Can't create udev\n");
       
   104         exit(1);
       
   105     }
       
   106     mon = udev_monitor_new_from_netlink(udev, "udev");
       
   107     udev_monitor_filter_add_match_subsystem_devtype(mon, "power_supply", NULL);
       
   108     udev_monitor_enable_receiving(mon);
       
   109     mon_fd = udev_monitor_get_fd(mon);
       
   110     static struct pollfd fds[1];
       
   111     fds[0].fd = mon_fd;
       
   112     fds[0].events = POLLIN;
       
   113 #endif
       
   114     while (1) {
       
   115         char filename[PATH_MAX+1];
       
   116 
       
   117         snprintf(filename,PATH_MAX,"/sys/class/power_supply/%s/charge_now",argv[1]);
       
   118         int charge_now = catint(filename);
       
   119 
       
   120         snprintf(filename,PATH_MAX,"/sys/class/power_supply/%s/current_now",argv[1]);
       
   121         int current_now = catint(filename);
       
   122 
       
   123         snprintf(filename,PATH_MAX,"/sys/class/power_supply/%s/charge_full",argv[1]);
       
   124         int charge_full = catint(filename);
       
   125 
       
   126         snprintf(filename,PATH_MAX,"/sys/class/power_supply/%s/status",argv[1]);
       
   127         char *status = catfile(filename);
       
   128 
       
   129         int remtime = 0;
       
   130         char remtimes[128];
       
   131         char *arrow;
       
   132 
       
   133         remtimes_color = color_none;
       
   134         if (!strcmp(status,"Charging")) {
       
   135             if (current_now != 0)
       
   136                 remtime = ((charge_full-charge_now) * 60) / current_now;
       
   137             arrow = "↑";
       
   138             arrow_color = color_orange;
       
   139         }
       
   140         else if (!strcmp(status,"Discharging")) {
       
   141             if (current_now != 0)
       
   142                 remtime = (charge_now * 60) / current_now;
       
   143             arrow = "↓";
       
   144             arrow_color = color_none;
       
   145             remtimes_color = color(20,120,0,remtime);
       
   146         } else {
       
   147             arrow = "—";
       
   148             arrow_color = color_green;
       
   149         }
       
   150         free(status);
       
   151         snprintf(remtimes,127,"%d:%02d",remtime/60,remtime%60);
       
   152         //printf("%d %d %d %s %d %s %s\n",charge_now,current_now,charge_full,
       
   153         //    eights[charge_now*8/charge_full], charge_now*100/charge_full,status,remtimes);
       
   154 
       
   155 
       
   156         int percent = charge_now*100/charge_full;
       
   157         eights_color = percent_color = color(15,40,0,percent);
       
   158         printf("%s%s%s ",eights_color,eights[charge_now*8/charge_full],color_stop);
       
   159         printf("%s%d%%%s ",percent_color,percent,color_stop);
       
   160         printf("%s%s%s ",arrow_color,arrow,color_stop);
       
   161         printf("%s%s%s\n",remtimes_color,remtimes,color_stop);
       
   162         fflush(stdout);
       
   163 #ifdef USE_UDEV
       
   164         int poll_status = poll(fds,1, UPDATE_PERIOD*1000);
       
   165         if (poll_status < 0) {
       
   166             if (poll_status != EINTR) {
       
   167                 perror("poll");
       
   168                 exit(12);
       
   169             }
       
   170         }
       
   171         if (fds[0].revents & POLLIN) {
       
   172             dev = udev_monitor_receive_device(mon);
       
   173             if (dev) {
       
   174                 udev_device_unref(dev);
       
   175             } else {
       
   176                 printf("UDEV DC\n");
       
   177                 exit(13);
       
   178             }
       
   179         }
       
   180 #else
       
   181         sleep(UPDATE_PERIOD);
       
   182 #endif
       
   183     }
       
   184 }