My slstatus configuration
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 

354 line
7.9 KiB

  1. /* See LICENSE file for copyright and license details. */
  2. /* global libraries */
  3. #include <alsa/asoundlib.h>
  4. #include <stdarg.h>
  5. #include <stdio.h>
  6. #include <stdlib.h>
  7. #include <string.h>
  8. #include <time.h>
  9. #include <unistd.h>
  10. #include <X11/Xlib.h>
  11. /* local libraries */
  12. #include "config.h"
  13. /* functions */
  14. void setstatus(char *str);
  15. char *smprintf(char *fmt, ...);
  16. char *get_battery();
  17. char *get_cpu_temperature();
  18. char *get_cpu_usage();
  19. char *get_datetime();
  20. char *get_ram_usage();
  21. char *get_volume();
  22. char *get_wifi_signal();
  23. /* global variables */
  24. static Display *dpy;
  25. /* set statusbar (WM_NAME) */
  26. void
  27. setstatus(char *str)
  28. {
  29. XStoreName(dpy, DefaultRootWindow(dpy), str);
  30. XSync(dpy, False);
  31. }
  32. /* smprintf function */
  33. char *
  34. smprintf(char *fmt, ...)
  35. {
  36. va_list fmtargs;
  37. char *ret = NULL;
  38. va_start(fmtargs, fmt);
  39. if (vasprintf(&ret, fmt, fmtargs) < 0)
  40. return NULL;
  41. va_end(fmtargs);
  42. return ret;
  43. }
  44. /* battery percentage */
  45. char *
  46. get_battery()
  47. {
  48. int now, full, perc;
  49. FILE *fp;
  50. /* open battery now file */
  51. if (!(fp = fopen(batterynowfile, "r"))) {
  52. fprintf(stderr, "Error opening battery file.");
  53. exit(1);
  54. }
  55. /* read value */
  56. fscanf(fp, "%i", &now);
  57. /* close battery now file */
  58. fclose(fp);
  59. /* open battery full file */
  60. if (!(fp = fopen(batteryfullfile, "r"))) {
  61. fprintf(stderr, "Error opening battery file.");
  62. exit(1);
  63. }
  64. /* read value */
  65. fscanf(fp, "%i", &full);
  66. /* close battery full file */
  67. fclose(fp);
  68. /* calculate percent */
  69. perc = now / (full / 100);
  70. /* return perc as string */
  71. return smprintf("%d%%", perc);
  72. }
  73. /* cpu temperature */
  74. char *
  75. get_cpu_temperature()
  76. {
  77. int temperature;
  78. FILE *fp;
  79. /* open temperature file */
  80. if (!(fp = fopen(tempfile, "r"))) {
  81. fprintf(stderr, "Could not open temperature file.\n");
  82. exit(1);
  83. }
  84. /* extract temperature */
  85. fscanf(fp, "%d", &temperature);
  86. /* close temperature file */
  87. fclose(fp);
  88. /* return temperature in degrees */
  89. return smprintf("%d°C", temperature / 1000);
  90. }
  91. /* cpu percentage */
  92. char *
  93. get_cpu_usage()
  94. {
  95. int perc;
  96. long double a[4], b[4];
  97. FILE *fp;
  98. /* open stat file */
  99. if (!(fp = fopen("/proc/stat","r"))) {
  100. fprintf(stderr, "Error opening stat file.");
  101. exit(1);
  102. }
  103. /* read values */
  104. fscanf(fp, "%*s %Lf %Lf %Lf %Lf", &a[0], &a[1], &a[2], &a[3]);
  105. /* close stat file */
  106. fclose(fp);
  107. /* wait a second (for avg values) */
  108. sleep(1);
  109. /* open stat file */
  110. if (!(fp = fopen("/proc/stat","r"))) {
  111. fprintf(stderr, "Error opening stat file.");
  112. exit(1);
  113. }
  114. /* read values */
  115. fscanf(fp, "%*s %Lf %Lf %Lf %Lf", &b[0], &b[1], &b[2], &b[3]);
  116. /* close stat file */
  117. fclose(fp);
  118. /* calculate avg in this second */
  119. perc = 100 * ((b[0]+b[1]+b[2]) - (a[0]+a[1]+a[2])) / ((b[0]+b[1]+b[2]+b[3]) - (a[0]+a[1]+a[2]+a[3]));
  120. /* return perc as string */
  121. return smprintf("%d%%", perc);
  122. }
  123. /* date and time */
  124. char *
  125. get_datetime()
  126. {
  127. time_t tm;
  128. size_t bufsize = 64;
  129. char *buf = malloc(bufsize);
  130. /* get time in format */
  131. time(&tm);
  132. if(!strftime(buf, bufsize, timeformat, localtime(&tm))) {
  133. fprintf(stderr, "Strftime failed.\n");
  134. exit(1);
  135. }
  136. /* return time */
  137. return smprintf("%s", buf);
  138. }
  139. /* ram percentage */
  140. char *
  141. get_ram_usage()
  142. {
  143. int perc;
  144. long total, free, buffers, cached;
  145. FILE *fp;
  146. /* open meminfo file */
  147. if (!(fp = fopen("/proc/meminfo", "r"))) {
  148. fprintf(stderr, "Error opening meminfo file.");
  149. exit(1);
  150. }
  151. /* read the values */
  152. fscanf(fp, "MemTotal: %ld kB\n", &total);
  153. fscanf(fp, "MemFree: %ld kB\n", &free);
  154. fscanf(fp, "MemAvailable: %ld kB\nBuffers: %ld kB\n", &buffers, &buffers);
  155. fscanf(fp, "Cached: %ld kB\n", &cached);
  156. /* close meminfo file */
  157. fclose(fp);
  158. /* calculate percentage */
  159. perc = 100 * ((total - free) - (buffers + cached)) / total;
  160. /* return perc as string */
  161. return smprintf("%d%%", perc);
  162. }
  163. /* alsa volume percentage */
  164. char *
  165. get_volume()
  166. {
  167. int mute = 0;
  168. long vol = 0, max = 0, min = 0;
  169. /* get volume from alsa */
  170. snd_mixer_t *handle;
  171. snd_mixer_elem_t *pcm_mixer, *mas_mixer;
  172. snd_mixer_selem_id_t *vol_info, *mute_info;
  173. snd_mixer_open(&handle, 0);
  174. snd_mixer_attach(handle, soundcard);
  175. snd_mixer_selem_register(handle, NULL, NULL);
  176. snd_mixer_load(handle);
  177. snd_mixer_selem_id_malloc(&vol_info);
  178. snd_mixer_selem_id_malloc(&mute_info);
  179. snd_mixer_selem_id_set_name(vol_info, channel);
  180. snd_mixer_selem_id_set_name(mute_info, channel);
  181. pcm_mixer = snd_mixer_find_selem(handle, vol_info);
  182. mas_mixer = snd_mixer_find_selem(handle, mute_info);
  183. snd_mixer_selem_get_playback_volume_range((snd_mixer_elem_t *)pcm_mixer, &min, &max);
  184. snd_mixer_selem_get_playback_volume((snd_mixer_elem_t *)pcm_mixer, SND_MIXER_SCHN_MONO, &vol);
  185. snd_mixer_selem_get_playback_switch(mas_mixer, SND_MIXER_SCHN_MONO, &mute);
  186. if (vol_info)
  187. snd_mixer_selem_id_free(vol_info);
  188. if (mute_info)
  189. snd_mixer_selem_id_free(mute_info);
  190. if (handle)
  191. snd_mixer_close(handle);
  192. /* return the string (mute) */
  193. if (!mute)
  194. return smprintf("mute");
  195. else
  196. return smprintf("%d%%", (vol * 100) / max);
  197. }
  198. /* wifi percentage */
  199. char *
  200. get_wifi_signal()
  201. {
  202. int bufsize = 255;
  203. int strength;
  204. char buf[bufsize];
  205. char *datastart;
  206. char path_start[16] = "/sys/class/net/";
  207. char path_end[11] = "/operstate";
  208. char path[32];
  209. char status[5];
  210. char needle[sizeof wificard + 1];
  211. FILE *fp;
  212. /* generate the path name */
  213. memset(path, 0, sizeof path);
  214. strcat(path, path_start);
  215. strcat(path, wificard);
  216. strcat(path, path_end);
  217. /* open wifi file */
  218. if(!(fp = fopen(path, "r"))) {
  219. fprintf(stderr, "Error opening wifi operstate file.");
  220. exit(1);
  221. }
  222. /* read the status */
  223. fgets(status, 5, fp);
  224. /* close wifi file */
  225. fclose(fp);
  226. /* check if interface down */
  227. if(strcmp(status, "up\n") != 0){
  228. return "n/a";
  229. }
  230. /* open wifi file */
  231. if (!(fp = fopen("/proc/net/wireless", "r"))) {
  232. fprintf(stderr, "Error opening wireless file.");
  233. exit(1);
  234. }
  235. /* extract the signal strength */
  236. strcpy(needle, wificard);
  237. strcat(needle, ":");
  238. fgets(buf, bufsize, fp);
  239. fgets(buf, bufsize, fp);
  240. fgets(buf, bufsize, fp);
  241. if ((datastart = strstr(buf, needle)) != NULL) {
  242. datastart = strstr(buf, ":");
  243. sscanf(datastart + 1, " %*d %d %*d %*d %*d %*d %*d %*d %*d %*d", &strength);
  244. }
  245. /* close wifi file */
  246. fclose(fp);
  247. /* return strength in percent */
  248. return smprintf("%d%%", strength);
  249. }
  250. /* main function */
  251. int
  252. main()
  253. {
  254. char status[1024];
  255. char *battery = NULL;
  256. char *cpu_temperature = NULL;
  257. char *cpu_usage = NULL;
  258. char *datetime = NULL;
  259. char *ram_usage = NULL;
  260. char *volume = NULL;
  261. char *wifi_signal = NULL;
  262. /* open display */
  263. if (!(dpy = XOpenDisplay(0x0))) {
  264. fprintf(stderr, "Cannot open display!\n");
  265. exit(1);
  266. }
  267. /* return status every second */
  268. for (;;) {
  269. /* assign the values */
  270. battery = get_battery();
  271. cpu_temperature = get_cpu_temperature();
  272. cpu_usage = get_cpu_usage();
  273. datetime = get_datetime();
  274. ram_usage = get_ram_usage();
  275. volume = get_volume();
  276. wifi_signal = get_wifi_signal();
  277. /* return the status */
  278. sprintf(status, FORMATSTRING, ARGUMENTS);
  279. setstatus(status);
  280. /* free the values */
  281. free(battery);
  282. free(cpu_temperature);
  283. free(cpu_usage);
  284. free(datetime);
  285. free(ram_usage);
  286. free(volume);
  287. free(wifi_signal);
  288. }
  289. /* close display */
  290. XCloseDisplay(dpy);
  291. /* exit successfully */
  292. return 0;
  293. }