dwmstatus.c 5.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270
  1. #define _GNU_SOURCE
  2. #include <errno.h>
  3. #include <signal.h>
  4. #include <unistd.h>
  5. #include <stddef.h>
  6. #include <stdio.h>
  7. #include <stdlib.h>
  8. #include <stdarg.h>
  9. #include <string.h>
  10. #include <strings.h>
  11. #include <sys/time.h>
  12. #include <time.h>
  13. #include <sys/types.h>
  14. #include <sys/wait.h>
  15. #include <mpd/client.h>
  16. #include <glib.h>
  17. #include <X11/Xlib.h>
  18. #include "config.h"
  19. volatile sig_atomic_t term_request = False;
  20. static Display *dpy;
  21. char *
  22. smprintf(char *fmt, ...)
  23. {
  24. va_list fmtargs;
  25. char *ret;
  26. int len;
  27. va_start(fmtargs, fmt);
  28. len = vsnprintf(NULL, 0, fmt, fmtargs);
  29. va_end(fmtargs);
  30. ret = malloc(++len);
  31. if (ret == NULL) {
  32. perror("malloc");
  33. exit(1);
  34. }
  35. va_start(fmtargs, fmt);
  36. vsnprintf(ret, len, fmt, fmtargs);
  37. va_end(fmtargs);
  38. return ret;
  39. }
  40. char *
  41. get_battery(){
  42. long lnum1, lnum2 = 0;
  43. long batpercent;
  44. char status[12];
  45. char *s = "?";
  46. FILE *fp = NULL;
  47. if ((fp = fopen(BATT_NOW, "r"))) {
  48. fscanf(fp, "%ld\n", &lnum1);
  49. fclose(fp);
  50. fp = fopen(BATT_FULL, "r");
  51. fscanf(fp, "%ld\n", &lnum2);
  52. fclose(fp);
  53. fp = fopen(BATT_STATUS, "r");
  54. fscanf(fp, "%s\n", status);
  55. fclose(fp);
  56. batpercent = (lnum1/(lnum2/100));
  57. if (strcmp(status,"Charging") == 0)
  58. s = "YELLOW"
  59. BAT_CHARGING_GLYPH;
  60. if (strcmp(status,"Discharging") == 0) {
  61. if (batpercent >= 75) {
  62. s = BAT_FULL_GLYPH;
  63. } else if (batpercent >= 50) {
  64. s = BAT_70_PERCENT_GLYPH;
  65. } else if (batpercent >= 15) {
  66. s = BAT_30_PERCENT_GLYPH;
  67. } else {
  68. s = BAT_EMPTY_GLYPH;
  69. }
  70. }
  71. if (strcmp(status,"Full") == 0)
  72. s = BAT_FULL_GLYPH;
  73. return smprintf("%s %ld%%", s, batpercent);
  74. }
  75. else return smprintf(AC_POWER_GLYPH);
  76. }
  77. void
  78. settz(char *tzname)
  79. {
  80. setenv("TZ", tzname, 1);
  81. }
  82. char *
  83. get_time(char *fmt, char *tzname)
  84. {
  85. char buf[129];
  86. time_t tim;
  87. struct tm *timtm;
  88. memset(buf, 0, sizeof(buf));
  89. settz(tzname);
  90. tim = time(NULL);
  91. timtm = localtime(&tim);
  92. if (timtm == NULL) {
  93. perror("localtime");
  94. exit(1);
  95. }
  96. if (!strftime(buf, sizeof(buf)-1, fmt, timtm)) {
  97. fprintf(stderr, "strftime == 0\n");
  98. exit(1);
  99. }
  100. return smprintf("%s %s", CLOCK_GLYPH, buf);
  101. }
  102. char *
  103. get_net_status()
  104. {
  105. static const int bufsize = 255;
  106. char buf[bufsize];
  107. char *glyph;
  108. char *datastart;
  109. FILE *devfd;
  110. int strength = 0;
  111. if ((devfd = fopen("/sys/class/net/enp4s0/operstate", "r")) != NULL) {
  112. fgets(buf, bufsize, devfd);
  113. if (strcmp(buf, "up\n") == 0) {
  114. glyph = ETHER_GLYPH;
  115. } else {
  116. glyph = ETHER_GLYPH;
  117. }
  118. fclose(devfd);
  119. return smprintf("%s ", glyph);
  120. } else if ((devfd = fopen("/proc/net/wireless", "r")) != NULL) {
  121. // Ignore the first two lines of the file
  122. fgets(buf, bufsize, devfd);
  123. fgets(buf, bufsize, devfd);
  124. fgets(buf, bufsize, devfd);
  125. if ((datastart = strstr(buf, WIFI_DEV":")) != NULL) {
  126. datastart = strstr(buf, ":");
  127. sscanf(datastart + 1, " %*d %d %*d %*d %*d %*d %*d %*d %*d %*d",
  128. &strength);
  129. glyph = WIFI_GLYPH;
  130. } else {
  131. glyph = WIFI_GLYPH;
  132. }
  133. fclose(devfd);
  134. return smprintf("%s %d", glyph, strength);
  135. } else {
  136. perror("net status error");
  137. return NULL;
  138. }
  139. }
  140. char *
  141. get_mpd_stat() {
  142. struct mpd_song * song = NULL;
  143. char * retstr = NULL;
  144. struct mpd_connection * conn;
  145. if (!(conn = mpd_connection_new("localhost", 0, 30000)) ||
  146. mpd_connection_get_error(conn)){
  147. return smprintf("");
  148. }
  149. mpd_command_list_begin(conn, true);
  150. mpd_send_status(conn);
  151. mpd_send_current_song(conn);
  152. mpd_command_list_end(conn);
  153. struct mpd_status* the_status = mpd_recv_status(conn);
  154. if ((the_status)
  155. && (mpd_status_get_state(the_status) == MPD_STATE_PLAY)) {
  156. const char * title = NULL;
  157. const char * artist = NULL;
  158. const gchar * quoted_title = NULL;
  159. const gchar * quoted_artist = NULL;
  160. mpd_response_next(conn);
  161. song = mpd_recv_song(conn);
  162. title = smprintf("%s",
  163. mpd_song_get_tag(song, MPD_TAG_TITLE, 0));
  164. artist = smprintf("%s",
  165. mpd_song_get_tag(song, MPD_TAG_ARTIST, 0));
  166. quoted_title = g_markup_escape_text(title, strlen(title));
  167. quoted_artist = g_markup_escape_text(artist, strlen(artist));
  168. mpd_song_free(song);
  169. retstr = smprintf("%s %s - %s",
  170. MUSIC_GLYPH,
  171. quoted_artist, quoted_title);
  172. free((char*)title);
  173. free((char*)artist);
  174. g_free((gchar*)quoted_title);
  175. g_free((gchar*)quoted_artist);
  176. }
  177. else retstr = smprintf(MUSIC_GLYPH" ");
  178. mpd_status_free(the_status);
  179. mpd_response_finish(conn);
  180. mpd_connection_free(conn);
  181. return retstr;
  182. }
  183. void
  184. setstatus(char *str)
  185. {
  186. XStoreName(dpy, DefaultRootWindow(dpy), str);
  187. XSync(dpy, False);
  188. }
  189. void
  190. term(int signum)
  191. {
  192. term_request = True;
  193. }
  194. int
  195. main(void)
  196. {
  197. struct sigaction sa;
  198. memset(&sa, 0, sizeof(struct sigaction));
  199. sa.sa_handler = term;
  200. if (sigaction(SIGTERM, &sa, 0) == -1) {
  201. perror(0);
  202. exit(1);
  203. }
  204. char *status;
  205. char *tpk;
  206. char *strength;
  207. char *bat;
  208. char *mpdstring;
  209. if (!(dpy = XOpenDisplay(NULL))) {
  210. fprintf(stderr, "dwmstatus: cannot open display.\n");
  211. return 1;
  212. }
  213. for (; !term_request; sleep(3)) {
  214. tpk= get_time("%H:%M", tpakistan);
  215. strength = get_net_status();
  216. bat = get_battery();
  217. mpdstring = get_mpd_stat();
  218. status = smprintf(" %s %s %s %s %s %s %s %s ",
  219. POWERLINE_SOFT_RIGHT, mpdstring,
  220. POWERLINE_SOFT_RIGHT, strength,
  221. POWERLINE_SOFT_RIGHT, bat,
  222. POWERLINE_SOFT_RIGHT, tpk);
  223. setstatus(status);
  224. free(mpdstring);
  225. free(bat);
  226. free(strength);
  227. free(tpk);
  228. free(status);
  229. }
  230. XCloseDisplay(dpy);
  231. return 0;
  232. }