bat.c (2733B)
1 #include <stdio.h> 2 #include <stdlib.h> 3 #include <assert.h> 4 #include <dirent.h> 5 #include <string.h> 6 #include <assert.h> 7 #include <sys/stat.h> 8 #include "status2d.h" 9 10 int 11 main(void) { 12 enum { s_none, s_charge, s_dcharge }; 13 int percent, status = s_none, w, iw, ih; 14 #ifdef __linux__ 15 #define BATDIR "/sys/class/power_supply" 16 struct dirent **dirent; 17 struct stat st; 18 char buf[BUFSIZ]; 19 char *dir = NULL; 20 char *sfile = NULL; 21 char *cfile = NULL; 22 size_t len; 23 FILE *f; 24 int nbats, ndir, total; 25 int i; 26 27 if ((ndir = scandir(BATDIR, &dirent, 0, alphasort)) < 0) { 28 return 1; 29 } 30 31 for (i = total = nbats = 0; i < ndir; i++) { 32 if (strncmp(dirent[i]->d_name, "BAT", strlen("BAT")) == 0) { 33 free(dir); 34 len = strlen(BATDIR) + strlen(dirent[i]->d_name) + 2; /* / + \0 */ 35 dir = malloc(len); 36 assert(dir); 37 snprintf(dir, len, "%s/%s", BATDIR, dirent[i]->d_name); 38 39 if (stat(dir, &st) == -1 || !S_ISDIR(st.st_mode)) 40 continue; 41 42 free(sfile); 43 len = strlen(dir) + 8; /* /status\0 */ 44 sfile = malloc(len); 45 assert(sfile); 46 snprintf(sfile, len, "%s/status", dir); 47 if ((f = fopen(sfile, "r")) != NULL) { 48 memset(buf, '\0', sizeof(buf)); 49 fread(buf, sizeof(char), sizeof(buf), f); 50 fclose(f); 51 if (buf[strlen(buf) - 1] == '\n') 52 buf[strlen(buf) - 1] = '\0'; 53 /* XXX: some batteries charging, some discharging? */ 54 if (strcmp(buf, "Charging") == 0 && s_charge > status) 55 status = s_charge; 56 else if (strcmp(buf, "Discharging") == 0 && s_dcharge > status) 57 status = s_dcharge; 58 } 59 60 free(cfile); 61 len = strlen(dir) + 10; /* /capacity\0 */ 62 cfile = malloc(len); 63 assert(cfile); 64 snprintf(cfile, len, "%s/capacity", dir); 65 if ((f = fopen(cfile, "r")) != NULL) { 66 memset(buf, '\0', sizeof(buf)); 67 fread(buf, sizeof(char), sizeof(buf), f); 68 fclose(f); 69 if (buf[strlen(buf) - 1] == '\n') 70 buf[strlen(buf) - 1] = '\0'; 71 nbats++; 72 total += atoi(buf); 73 } 74 } 75 } 76 77 free(dir); 78 free(sfile); 79 free(cfile); 80 81 percent = total / nbats; 82 #else 83 s2d_print("no handler for this OS"); 84 s2d_finish(); 85 return 1; 86 #endif 87 iw = 18; 88 ih = bar_height - 8; 89 w = iw * percent / 100; 90 91 /* colour border+nose for charge indicator */ 92 if (status == s_dcharge) 93 s2d_fg(RED); 94 else if (status == s_charge) 95 s2d_fg(GREEN); 96 else 97 s2d_fg(BRBG); 98 99 /* draw nose */ 100 s2d_rect(2, (bar_height - 5) / 2, 1, 5); 101 102 /* draw border for battery */ 103 s2d_border(3, 3, iw + 2, ih + 2, 1); 104 105 /* fill battery */ 106 s2d_fg(BRBG); 107 s2d_rect(4, 4, iw, ih); 108 if (percent < 10) 109 s2d_fg(RED); 110 else if (percent < 20) 111 s2d_fg(ORANGE); 112 else if (percent < 30) 113 s2d_fg(YELLOW); 114 else 115 s2d_reset(1, 0); 116 s2d_rect(4 + iw - w, 4, w, ih); 117 118 /* pad + finish up */ 119 s2d_forward(2); 120 s2d_finish(); 121 return 0; 122 }