My slstatus configuration
Du kan inte välja fler än 25 ämnen Ämnen måste starta med en bokstav eller siffra, kan innehålla bindestreck ('-') och vara max 35 tecken långa.
 
 
 
 

377 rader
8.8 KiB

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