From 103945e7bb8d3a4198cf175b8f6be09fe53ab9e1 Mon Sep 17 00:00:00 2001 From: Aaron Marcher Date: Mon, 21 May 2018 00:36:59 +0200 Subject: [PATCH 01/16] battery: Minor coding style fixes - Line length - Spacing and indentation - No explicit checks for NULL --- components/battery.c | 25 +++++++++++++++---------- 1 file changed, 15 insertions(+), 10 deletions(-) diff --git a/components/battery.c b/components/battery.c index ff06f40..6105a37 100644 --- a/components/battery.c +++ b/components/battery.c @@ -9,19 +9,22 @@ #include #include - #define CHARGE_NOW "/sys/class/power_supply/%s/charge_now" - #define ENERGY_NOW "/sys/class/power_supply/%s/energy_now" - #define CURRENT_NOW "/sys/class/power_supply/%s/current_now" - #define POWER_NOW "/sys/class/power_supply/%s/power_now" + #define CHARGE_NOW "/sys/class/power_supply/%s/charge_now" + #define ENERGY_NOW "/sys/class/power_supply/%s/energy_now" + #define CURRENT_NOW "/sys/class/power_supply/%s/current_now" + #define POWER_NOW "/sys/class/power_supply/%s/power_now" static const char * - pick(const char *bat, const char *f1, const char *f2, char *path, size_t length) + pick(const char *bat, const char *f1, const char *f2, char *path, + size_t length) { - if (esnprintf(path, length, f1, bat) > 0 && access(path, R_OK) == 0) { + if (esnprintf(path, length, f1, bat) > 0 && + access(path, R_OK) == 0) { return f1; } - if (esnprintf(path, length, f2, bat) > 0 && access(path, R_OK) == 0) { + if (esnprintf(path, length, f2, bat) > 0 && + access(path, R_OK) == 0) { return f2; } @@ -92,13 +95,14 @@ return NULL; } - if (pick(bat, CHARGE_NOW, ENERGY_NOW, path, sizeof (path)) == NULL || + if (!pick(bat, CHARGE_NOW, ENERGY_NOW, path, sizeof(path)) || pscanf(path, "%d", &charge_now) < 0) { return NULL; } if (!strcmp(state, "Discharging")) { - if (pick(bat, CURRENT_NOW, POWER_NOW, path, sizeof (path)) == NULL || + if (!pick(bat, CURRENT_NOW, POWER_NOW, path, + sizeof(path)) || pscanf(path, "%d", ¤t_now) < 0) { return NULL; } @@ -182,7 +186,8 @@ if (load_apm_power_info(&apm_info)) { if (apm_info.ac_state != APM_AC_ON) { - return bprintf("%uh %02um", apm_info.minutes_left / 60, + return bprintf("%uh %02um", + apm_info.minutes_left / 60, apm_info.minutes_left % 60); } else { return ""; -- 2.20.1 From a546d4b585234f66b82e048c2d7cb228b9e7fea4 Mon Sep 17 00:00:00 2001 From: Aaron Marcher Date: Mon, 21 May 2018 00:41:03 +0200 Subject: [PATCH 02/16] battery_remaining: Change float to double --- components/battery.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/components/battery.c b/components/battery.c index 6105a37..fa525be 100644 --- a/components/battery.c +++ b/components/battery.c @@ -83,7 +83,7 @@ battery_remaining(const char *bat) { int charge_now, current_now, m, h; - float timeleft; + double timeleft; char path[PATH_MAX], state[12]; if (esnprintf(path, sizeof(path), @@ -107,9 +107,9 @@ return NULL; } - timeleft = (float)charge_now / (float)current_now; + timeleft = (double)charge_now / (double)current_now; h = timeleft; - m = (timeleft - (float)h) * 60; + m = (timeleft - (double)h) * 60; return bprintf("%dh %dm", h, m); } -- 2.20.1 From aa8654795da19a8d517faf1b84cd4dc4ac75f6e7 Mon Sep 17 00:00:00 2001 From: Aaron Marcher Date: Mon, 21 May 2018 00:42:06 +0200 Subject: [PATCH 03/16] battery_remaining: check for division by zero --- components/battery.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/components/battery.c b/components/battery.c index fa525be..8bfe42a 100644 --- a/components/battery.c +++ b/components/battery.c @@ -107,6 +107,10 @@ return NULL; } + if (current_now == 0) { + return NULL; + } + timeleft = (double)charge_now / (double)current_now; h = timeleft; m = (timeleft - (double)h) * 60; -- 2.20.1 From fa8b939990ed0648f99b0cbeba4efed807160db3 Mon Sep 17 00:00:00 2001 From: Aaron Marcher Date: Mon, 21 May 2018 14:07:41 +0200 Subject: [PATCH 04/16] Add option to output only once and exit --- slstatus.1 | 4 +++- slstatus.c | 13 ++++++++++--- 2 files changed, 13 insertions(+), 4 deletions(-) diff --git a/slstatus.1 b/slstatus.1 index da1a99a..9517fab 100644 --- a/slstatus.1 +++ b/slstatus.1 @@ -6,7 +6,7 @@ .Nd suckless status monitor .Sh SYNOPSIS .Nm -.Op Fl s +.Op Fl so .Sh DESCRIPTION .Nm is a suckless status monitor for window managers that use WM_NAME (e.g. dwm) or @@ -18,6 +18,8 @@ outputs to WM_NAME. .Bl -tag -width Ds .It Fl s Write to stdout instead of WM_NAME. +.It Fl o +Write only once and exit. .El .Sh CUSTOMIZATION .Nm diff --git a/slstatus.c b/slstatus.c index 3222b02..b3abafb 100644 --- a/slstatus.c +++ b/slstatus.c @@ -42,7 +42,7 @@ difftimespec(struct timespec *res, struct timespec *a, struct timespec *b) static void usage(void) { - die("usage: %s [-s]", argv0); + die("usage: %s [-so]", argv0); } int @@ -51,15 +51,18 @@ main(int argc, char *argv[]) struct sigaction act; struct timespec start, current, diff, intspec, wait; size_t i, len; - int sflag, ret; + int sflag, oflag, ret; char status[MAXLEN]; const char *res; - sflag = 0; + sflag = oflag = 0; ARGBEGIN { case 's': sflag = 1; break; + case 'o': + oflag = 1; + break; default: usage(); } ARGEND @@ -107,6 +110,10 @@ main(int argc, char *argv[]) XFlush(dpy); } + if (oflag) { + done = 1; + } + if (!done) { if (clock_gettime(CLOCK_MONOTONIC, ¤t) < 0) { die("clock_gettime:"); -- 2.20.1 From fc0dde5a60a066b8506834f508aebf0ea5055990 Mon Sep 17 00:00:00 2001 From: Aaron Marcher Date: Mon, 21 May 2018 14:14:45 +0200 Subject: [PATCH 05/16] Remove fmt from load_avgs for consistency In a later commit something like that will be enabled for every component --- components/load_avg.c | 4 ++-- config.def.h | 3 +-- 2 files changed, 3 insertions(+), 4 deletions(-) diff --git a/components/load_avg.c b/components/load_avg.c index ea7bc2c..5c2e252 100644 --- a/components/load_avg.c +++ b/components/load_avg.c @@ -5,7 +5,7 @@ #include "../util.h" const char * -load_avg(const char *fmt) +load_avg(void) { double avgs[3]; @@ -14,5 +14,5 @@ load_avg(const char *fmt) return NULL; } - return bprintf(fmt, avgs[0], avgs[1], avgs[2]); + return bprintf("%.2f %.2f %.2f", avgs[0], avgs[1], avgs[2]); } diff --git a/config.def.h b/config.def.h index 49ea282..f144393 100644 --- a/config.def.h +++ b/config.def.h @@ -32,8 +32,7 @@ static const char unknown_str[] = "n/a"; * ipv6 IPv6 address interface name (eth0) * kernel_release `uname -r` NULL * keyboard_indicators caps/num lock indicators NULL - * load_avg load average format string - * (%.2f %.2f %.2f) + * load_avg load average NULL * netspeed_rx receive network speed interface name (wlan0) * netspeed_tx transfer network speed interface name (wlan0) * num_files number of files in a directory path -- 2.20.1 From 10dbc9543edd5b5a7929dd8fa87ed33dd545375c Mon Sep 17 00:00:00 2001 From: Aaron Marcher Date: Mon, 21 May 2018 14:44:21 +0200 Subject: [PATCH 06/16] Merge fmt_human_2 and fmt_human_10 to one function Now only one function, fmt_human, takes an additional argument "base". --- components/cpu.c | 4 ++-- components/disk.c | 6 +++--- components/netspeeds.c | 12 ++++++++---- components/ram.c | 21 ++++++++++++--------- components/swap.c | 12 ++++++------ util.c | 32 ++++++++++++-------------------- util.h | 3 +-- 7 files changed, 44 insertions(+), 46 deletions(-) diff --git a/components/cpu.c b/components/cpu.c index 3fadb36..ecd45a6 100644 --- a/components/cpu.c +++ b/components/cpu.c @@ -20,7 +20,7 @@ return NULL; } - return fmt_human_10(freq * 1000); + return fmt_human(freq * 1000, 1000); } const char * @@ -67,7 +67,7 @@ return NULL; } - return fmt_human_10((size_t)freq * 1000 * 1000); + return fmt_human((size_t)freq * 1000 * 1000, 1000); } const char * diff --git a/components/disk.c b/components/disk.c index cf3c099..f3c96d5 100644 --- a/components/disk.c +++ b/components/disk.c @@ -16,7 +16,7 @@ disk_free(const char *mnt) return NULL; } - return fmt_human_2(fs.f_frsize * fs.f_bavail); + return fmt_human(fs.f_frsize * fs.f_bavail, 1024); } const char * @@ -43,7 +43,7 @@ disk_total(const char *mnt) return NULL; } - return fmt_human_2(fs.f_frsize * fs.f_blocks); + return fmt_human(fs.f_frsize * fs.f_blocks, 1024); } const char * @@ -56,5 +56,5 @@ disk_used(const char *mnt) return NULL; } - return fmt_human_2(fs.f_frsize * (fs.f_blocks - fs.f_bfree)); + return fmt_human(fs.f_frsize * (fs.f_blocks - fs.f_bfree), 1024); } diff --git a/components/netspeeds.c b/components/netspeeds.c index 76557e0..4332024 100644 --- a/components/netspeeds.c +++ b/components/netspeeds.c @@ -29,7 +29,8 @@ return NULL; } - return fmt_human_2((rxbytes - oldrxbytes) * 1000 / interval); + return fmt_human((rxbytes - oldrxbytes) * 1000 / interval, + 1024); } const char * @@ -54,7 +55,8 @@ return NULL; } - return fmt_human_2((txbytes - oldtxbytes) * 1000 / interval); + return fmt_human((txbytes - oldtxbytes) * 1000 / interval, + 1024); } #elif defined(__OpenBSD__) #include @@ -95,7 +97,8 @@ return NULL; } - return fmt_human_2((rxbytes - oldrxbytes) * 1000 / interval); + return fmt_human((rxbytes - oldrxbytes) * 1000 / interval, + 1024); } const char * @@ -130,6 +133,7 @@ return NULL; } - return fmt_human_2((txbytes - oldtxbytes) * 1000 / interval); + return fmt_human_2((txbytes - oldtxbytes) * 1000 / interval, + 1024); } #endif diff --git a/components/ram.c b/components/ram.c index cba22a1..0ac9753 100644 --- a/components/ram.c +++ b/components/ram.c @@ -17,7 +17,7 @@ return NULL; } - return fmt_human_2(free * 1024); + return fmt_human(free * 1024, 1024); } const char * @@ -48,7 +48,7 @@ return NULL; } - return fmt_human_2(total * 1024); + return fmt_human(total * 1024, 1024); } const char * @@ -65,7 +65,8 @@ return NULL; } - return fmt_human_2((total - free - buffers - cached) * 1024); + return fmt_human((total - free - buffers - cached) * 1024, + 1024); } #elif defined(__OpenBSD__) #include @@ -99,8 +100,8 @@ if (load_uvmexp(&uvmexp)) { free_pages = uvmexp.npages - uvmexp.active; - return fmt_human_2(pagetok(free_pages, - uvmexp.pageshift) * 1024); + return fmt_human(pagetok(free_pages, uvmexp.pageshift) * + 1024, 1024); } return NULL; @@ -126,8 +127,9 @@ struct uvmexp uvmexp; if (load_uvmexp(&uvmexp)) { - return fmt_human_2(pagetok(uvmexp.npages, - uvmexp.pageshift) * 1024); + return fmt_human(pagetok(uvmexp.npages, + uvmexp.pageshift) * 1024, + 1024); } return NULL; @@ -139,8 +141,9 @@ struct uvmexp uvmexp; if (load_uvmexp(&uvmexp)) { - return fmt_human_2(pagetok(uvmexp.active, - uvmexp.pageshift) * 1024); + return fmt_human(pagetok(uvmexp.active, + uvmexp.pageshift) * 1024, + 1024); } return NULL; diff --git a/components/swap.c b/components/swap.c index c697d61..c9bb920 100644 --- a/components/swap.c +++ b/components/swap.c @@ -48,7 +48,7 @@ } sscanf(match, "SwapFree: %ld kB\n", &free); - return fmt_human_2(free * 1024); + return fmt_human(free * 1024, 1024); } const char * @@ -98,7 +98,7 @@ } sscanf(match, "SwapTotal: %ld kB\n", &total); - return fmt_human_2(total * 1024); + return fmt_human(total * 1024, 1024); } const char * @@ -126,7 +126,7 @@ } sscanf(match, "SwapFree: %ld kB\n", &free); - return fmt_human_2((total - free - cached) * 1024); + return fmt_human((total - free - cached) * 1024, 1024); } #elif defined(__OpenBSD__) #include @@ -178,7 +178,7 @@ getstats(&total, &used); - return fmt_human_2((total - used) * 1024); + return fmt_human((total - used) * 1024, 1024); } const char * @@ -202,7 +202,7 @@ getstats(&total, &used); - return fmt_human_2(total * 1024); + return fmt_human(total * 1024, 1024); } const char * @@ -212,6 +212,6 @@ getstats(&total, &used); - return fmt_human_2(used * 1024); + return fmt_human(used * 1024, 1024); } #endif diff --git a/util.c b/util.c index 6dd08d7..fc8b72a 100644 --- a/util.c +++ b/util.c @@ -87,32 +87,24 @@ bprintf(const char *fmt, ...) } const char * -fmt_human_2(size_t num) +fmt_human(size_t num, int base) { size_t i; double scaled; - const char *prefix[] = { "", "Ki", "Mi", "Gi", "Ti", "Pi", "Ei", - "Zi", "Yi" }; - - scaled = num; - for (i = 0; i < LEN(prefix) && scaled >= 1024; i++) { - scaled /= 1024.0; + const char *siprefix[] = { "", "k", "M", "G", "T", "P", "E", "Z", "Y" }; + const char *iecprefix[] = { "", "Ki", "Mi", "Gi", "Ti", "Pi", "Ei", + "Zi", "Yi" }; + char *prefix[9]; + + if (base == 1000) { + memcpy(prefix, siprefix, sizeof(prefix)); + } else if (base == 1024) { + memcpy(prefix, iecprefix, sizeof(prefix)); } - return bprintf("%.1f%s", scaled, prefix[i]); -} - -const char * -fmt_human_10(size_t num) -{ - size_t i; - double scaled; - const char *prefix[] = { "", "K", "M", "G", "T", "P", "E", - "Z", "Y" }; - scaled = num; - for (i = 0; i < LEN(prefix) && scaled >= 1000; i++) { - scaled /= 1000.0; + for (i = 0; i < LEN(prefix) && scaled >= 1024; i++) { + scaled /= base; } return bprintf("%.1f%s", scaled, prefix[i]); diff --git a/util.h b/util.h index 4879414..faa1472 100644 --- a/util.h +++ b/util.h @@ -10,6 +10,5 @@ void die(const char *, ...); int esnprintf(char *str, size_t size, const char *fmt, ...); const char *bprintf(const char *fmt, ...); -const char *fmt_human_2(size_t num); -const char *fmt_human_10(size_t num); +const char *fmt_human(size_t num, int iec); int pscanf(const char *path, const char *fmt, ...); -- 2.20.1 From ceb13206a4d9f410ab49c3824c487658c341d8c8 Mon Sep 17 00:00:00 2001 From: Laslo Hunhold Date: Mon, 21 May 2018 20:08:56 +0200 Subject: [PATCH 07/16] Refactor fmt_human() and fix a bug It is not necessary to copy memory or anything. Just keep a pointer to the active prefix-array and assign the length of the arrays to a variable. Make the code more readable by using a switch, be more strict when an invalid base is passed to it and fix a small oversight in the bottom of the code where the base 1024 was forgotten to generalized. --- util.c | 30 +++++++++++++++++++----------- util.h | 2 +- 2 files changed, 20 insertions(+), 12 deletions(-) diff --git a/util.c b/util.c index fc8b72a..b412211 100644 --- a/util.c +++ b/util.c @@ -89,21 +89,29 @@ bprintf(const char *fmt, ...) const char * fmt_human(size_t num, int base) { - size_t i; double scaled; - const char *siprefix[] = { "", "k", "M", "G", "T", "P", "E", "Z", "Y" }; - const char *iecprefix[] = { "", "Ki", "Mi", "Gi", "Ti", "Pi", "Ei", - "Zi", "Yi" }; - char *prefix[9]; - - if (base == 1000) { - memcpy(prefix, siprefix, sizeof(prefix)); - } else if (base == 1024) { - memcpy(prefix, iecprefix, sizeof(prefix)); + size_t i, prefixlen; + const char **prefix; + const char *prefix_1000[] = { "", "k", "M", "G", "T", "P", "E", "Z", "Y" }; + const char *prefix_1024[] = { "", "Ki", "Mi", "Gi", "Ti", "Pi", "Ei", + "Zi", "Yi" }; + + switch (base) { + case 1000: + prefix = prefix_1000; + prefixlen = LEN(prefix_1000); + break; + case 1024: + prefix = prefix_1024; + prefixlen = LEN(prefix_1024); + break; + default: + warn("fmt_human: Invalid base"); + return NULL; } scaled = num; - for (i = 0; i < LEN(prefix) && scaled >= 1024; i++) { + for (i = 0; i < prefixlen && scaled >= base; i++) { scaled /= base; } diff --git a/util.h b/util.h index faa1472..b474f88 100644 --- a/util.h +++ b/util.h @@ -10,5 +10,5 @@ void die(const char *, ...); int esnprintf(char *str, size_t size, const char *fmt, ...); const char *bprintf(const char *fmt, ...); -const char *fmt_human(size_t num, int iec); +const char *fmt_human(size_t num, int base); int pscanf(const char *path, const char *fmt, ...); -- 2.20.1 From 7f91ce265ea456b3096ccba7fdbb890bcf00e225 Mon Sep 17 00:00:00 2001 From: Laslo Hunhold Date: Mon, 21 May 2018 23:03:34 +0200 Subject: [PATCH 08/16] swap.c: Refactor getstats() and its usage Add a return value so we are able to check any errors and actually fail when there has been a critical error instead of carrying on uselessly. --- components/swap.c | 36 ++++++++++++++++++++++-------------- 1 file changed, 22 insertions(+), 14 deletions(-) diff --git a/components/swap.c b/components/swap.c index c9bb920..37ee85c 100644 --- a/components/swap.c +++ b/components/swap.c @@ -135,29 +135,27 @@ #include #include - static void + static int getstats(int *total, int *used) { struct swapent *sep, *fsep; int rnswap, nswap, i; - nswap = swapctl(SWAP_NSWAP, 0, 0); - if (nswap < 1) { + if ((nswap = swapctl(SWAP_NSWAP, 0, 0)) < 1) { warn("swaptctl 'SWAP_NSWAP':"); + return 1; } - - fsep = sep = calloc(nswap, sizeof(*sep)); - if (!sep) { + if (!(fsep = sep = calloc(nswap, sizeof(*sep)))) { warn("calloc 'nswap':"); + return 1; } - - rnswap = swapctl(SWAP_STATS, (void *)sep, nswap); - if (rnswap < 0) { + if ((rnswap = swapctl(SWAP_STATS, (void *)sep, nswap)) < 0) { warn("swapctl 'SWAP_STATA':"); + return 1; } - if (nswap != rnswap) { warn("getstats: SWAP_STATS != SWAP_NSWAP"); + return 1; } *total = 0; @@ -169,6 +167,8 @@ } free(fsep); + + return 0; } const char * @@ -176,7 +176,9 @@ { int total, used; - getstats(&total, &used); + if (getstats(&total, &used)) { + return NULL; + } return fmt_human((total - used) * 1024, 1024); } @@ -186,7 +188,9 @@ { int total, used; - getstats(&total, &used); + if (getstats(&total, &used)) { + return NULL; + } if (total == 0) { return NULL; @@ -200,7 +204,9 @@ { int total, used; - getstats(&total, &used); + if (getstats(&total, &used)) { + return NULL; + } return fmt_human(total * 1024, 1024); } @@ -210,7 +216,9 @@ { int total, used; - getstats(&total, &used); + if (getstats(&total, &used)) { + return NULL; + } return fmt_human(used * 1024, 1024); } -- 2.20.1 From cbbf59fd3dde3f7cfbdc9807da5f5f42b664cf49 Mon Sep 17 00:00:00 2001 From: Aaron Marcher Date: Tue, 22 May 2018 12:21:52 +0200 Subject: [PATCH 09/16] Change to fmt_human in netspeeds on OpenBSD Thanks to Hiltjo --- components/netspeeds.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/components/netspeeds.c b/components/netspeeds.c index 4332024..3c5dabf 100644 --- a/components/netspeeds.c +++ b/components/netspeeds.c @@ -133,7 +133,7 @@ return NULL; } - return fmt_human_2((txbytes - oldtxbytes) * 1000 / interval, + return fmt_human((txbytes - oldtxbytes) * 1000 / interval, 1024); } #endif -- 2.20.1 From 37724ac2c3f496f4736223d0d8e5d8fecb933590 Mon Sep 17 00:00:00 2001 From: David Demelier Date: Tue, 22 May 2018 09:23:29 +0200 Subject: [PATCH 10/16] Add basic backlight percentage support At the moment linux only, but will add support for OpenBSD as well. --- Makefile | 1 + README | 1 + components/backlight.c | 32 ++++++++++++++++++++++++++++++++ config.def.h | 2 ++ slstatus.h | 3 +++ util.h | 2 ++ 6 files changed, 41 insertions(+) create mode 100644 components/backlight.c diff --git a/Makefile b/Makefile index 0e925cc..8e18969 100644 --- a/Makefile +++ b/Makefile @@ -6,6 +6,7 @@ include config.mk REQ = util COM =\ + components/backlight\ components/battery\ components/cpu\ components/datetime\ diff --git a/README b/README index c278599..f6041de 100644 --- a/README +++ b/README @@ -6,6 +6,7 @@ slstatus is a suckless status monitor for window managers that use WM_NAME Features -------- +- Backlight percentage - Battery percentage/state/time left - CPU usage - CPU frequency diff --git a/components/backlight.c b/components/backlight.c new file mode 100644 index 0000000..f9c4096 --- /dev/null +++ b/components/backlight.c @@ -0,0 +1,32 @@ +/* See LICENSE file for copyright and license details. */ +#include "../util.h" + +#if defined(__linux__) + #include + + #define BRIGHTNESS_MAX "/sys/class/backlight/%s/max_brightness" + #define BRIGHTNESS_CUR "/sys/class/backlight/%s/brightness" + + const char * + backlight_perc(const char *card) + { + char path[PATH_MAX]; + int max, cur; + + if (esnprintf(path, sizeof (path), BRIGHTNESS_MAX, card) < 0 || + pscanf(path, "%d", &max) != 1) { + return NULL; + } + + if (esnprintf(path, sizeof (path), BRIGHTNESS_CUR, card) < 0 || + pscanf(path, "%d", &cur) != 1) { + return NULL; + } + + if (max == 0) { + return NULL; + } + + return bprintf("%d", cur * 100 / max); + } +#endif diff --git a/config.def.h b/config.def.h index f144393..45320a3 100644 --- a/config.def.h +++ b/config.def.h @@ -12,6 +12,8 @@ static const char unknown_str[] = "n/a"; /* * function description argument (example) * + * backlight_perc backlight percentage device name + * (intel_backlight) * battery_perc battery percentage battery name (BAT0) * NULL on OpenBSD * battery_state battery charging state battery name (BAT0) diff --git a/slstatus.h b/slstatus.h index 8bd8bb5..a18b881 100644 --- a/slstatus.h +++ b/slstatus.h @@ -1,5 +1,8 @@ /* See LICENSE file for copyright and license details. */ +/* backlight */ +const char *backlight_perc(const char *); + /* battery */ const char *battery_perc(const char *); const char *battery_state(const char *); diff --git a/util.h b/util.h index b474f88..f55c0eb 100644 --- a/util.h +++ b/util.h @@ -1,4 +1,6 @@ /* See LICENSE file for copyright and license details. */ +#include + extern char buf[1024]; #define LEN(x) (sizeof (x) / sizeof *(x)) -- 2.20.1 From 825f637e20e98901447825ac44aa24859083fe00 Mon Sep 17 00:00:00 2001 From: Aaron Marcher Date: Tue, 22 May 2018 12:42:31 +0200 Subject: [PATCH 11/16] netspeeds: Fix indentation --- components/netspeeds.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/components/netspeeds.c b/components/netspeeds.c index 3c5dabf..7ab1590 100644 --- a/components/netspeeds.c +++ b/components/netspeeds.c @@ -134,6 +134,6 @@ } return fmt_human((txbytes - oldtxbytes) * 1000 / interval, - 1024); + 1024); } #endif -- 2.20.1 From 9c9ce8a125f35bab61c829bdd58bdf77b8352d5e Mon Sep 17 00:00:00 2001 From: Laslo Hunhold Date: Tue, 22 May 2018 12:50:43 +0200 Subject: [PATCH 12/16] Check printf() for output errors This way cases like $ slstatus -s > /dev/full are properly caught and the program terminated with the proper return code. --- slstatus.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/slstatus.c b/slstatus.c index b3abafb..9bd9e81 100644 --- a/slstatus.c +++ b/slstatus.c @@ -102,7 +102,9 @@ main(int argc, char *argv[]) } if (sflag) { - printf("%s\n", status); + if (printf("%s\n", status) < 0) { + die("printf:"); + } } else { if (XStoreName(dpy, DefaultRootWindow(dpy), status) < 0) { die("XStoreName: Allocation failed"); -- 2.20.1 From 57f69e900bf7e3e7c60a720bf09f2134b724c5cc Mon Sep 17 00:00:00 2001 From: Laslo Hunhold Date: Mon, 21 May 2018 21:31:53 +0200 Subject: [PATCH 13/16] Remove o-flag as it is redundant Even if we extend the flag to be an n-flag with a numerical input, we already have other Unix-tools to take care of us much more flexibly, e.g. with head(1) you can easily get the first 10 outputs with slstatus -s | head -n 10, but also e.g. discard the first one and then get the consecutive 10 outputs. For the X11-root-window-name, you can limit the runtime with timeout(1) or a comparable solution. This reverts commit fa8b939990ed0648f99b0cbeba4efed807160db3. --- slstatus.1 | 4 +--- slstatus.c | 13 +++---------- 2 files changed, 4 insertions(+), 13 deletions(-) diff --git a/slstatus.1 b/slstatus.1 index 9517fab..da1a99a 100644 --- a/slstatus.1 +++ b/slstatus.1 @@ -6,7 +6,7 @@ .Nd suckless status monitor .Sh SYNOPSIS .Nm -.Op Fl so +.Op Fl s .Sh DESCRIPTION .Nm is a suckless status monitor for window managers that use WM_NAME (e.g. dwm) or @@ -18,8 +18,6 @@ outputs to WM_NAME. .Bl -tag -width Ds .It Fl s Write to stdout instead of WM_NAME. -.It Fl o -Write only once and exit. .El .Sh CUSTOMIZATION .Nm diff --git a/slstatus.c b/slstatus.c index 9bd9e81..4f7a2fc 100644 --- a/slstatus.c +++ b/slstatus.c @@ -42,7 +42,7 @@ difftimespec(struct timespec *res, struct timespec *a, struct timespec *b) static void usage(void) { - die("usage: %s [-so]", argv0); + die("usage: %s [-s]", argv0); } int @@ -51,18 +51,15 @@ main(int argc, char *argv[]) struct sigaction act; struct timespec start, current, diff, intspec, wait; size_t i, len; - int sflag, oflag, ret; + int sflag, ret; char status[MAXLEN]; const char *res; - sflag = oflag = 0; + sflag = 0; ARGBEGIN { case 's': sflag = 1; break; - case 'o': - oflag = 1; - break; default: usage(); } ARGEND @@ -112,10 +109,6 @@ main(int argc, char *argv[]) XFlush(dpy); } - if (oflag) { - done = 1; - } - if (!done) { if (clock_gettime(CLOCK_MONOTONIC, ¤t) < 0) { die("clock_gettime:"); -- 2.20.1 From 943b42de05cc3328ea74b0d9f527f17e1fcf47e7 Mon Sep 17 00:00:00 2001 From: Michael Buch Date: Wed, 23 May 2018 07:16:30 +0100 Subject: [PATCH 14/16] Add keymap component Adding a new keymap component that will indicate the current keyboard layout (language) and variant if any was set. I use the standard X11 XKB APIs to retrieve and parse the xkb_symbols set with setxkbmap. --- Makefile | 1 + components/keymap.c | 97 +++++++++++++++++++++++++++++++++++++++++++++ config.def.h | 2 + slstatus.h | 3 ++ 4 files changed, 103 insertions(+) create mode 100644 components/keymap.c diff --git a/Makefile b/Makefile index 8e18969..7ed7099 100644 --- a/Makefile +++ b/Makefile @@ -16,6 +16,7 @@ COM =\ components/ip\ components/kernel_release\ components/keyboard_indicators\ + components/keymap\ components/load_avg\ components/netspeeds\ components/num_files\ diff --git a/components/keymap.c b/components/keymap.c new file mode 100644 index 0000000..358a2ca --- /dev/null +++ b/components/keymap.c @@ -0,0 +1,97 @@ +/* See LICENSE file for copyright and license details. */ +#include +#include +#include +#include +#include + +#include "../util.h" + +#define LAYOUT_MAX 256 + +/* Given a token (sym) from the xkb_symbols string + * check whether it is a valid layout/variant. The + * EXCLUDES array contains invalid layouts/variants + * that are part of the xkb rules config. + */ +static int +IsLayoutOrVariant(char *sym) +{ + static const char* EXCLUDES[] = { "evdev", "inet", "pc", "base" }; + + size_t i; + for (i = 0; i < sizeof(EXCLUDES)/sizeof(EXCLUDES[0]); ++i) + if (strstr(sym, EXCLUDES[i])) { + return 0; + } + + return 1; +} + +static void +GetKeyLayout(char *syms, char layout[], int groupNum) +{ + char *token, *copy, *delims; + int group; + + delims = "+:"; + group = 0; + copy = strdup(syms); + token = strtok(copy, delims); + while (token != NULL && group <= groupNum) { + /* Ignore :2,:3,:4 which represent additional layout + * groups + */ + if (IsLayoutOrVariant(token) + && !(strlen(token) == 1 && isdigit(token[0]))) { + strncpy (layout, token, LAYOUT_MAX); + group++; + } + + token = strtok(NULL,delims); + } + + free(copy); +} + +const char * +keymap(void) +{ + static char layout[LAYOUT_MAX]; + + Display *dpy; + char *symbols = NULL; + XkbDescRec* desc = NULL; + + memset(layout, '\0', LAYOUT_MAX); + + if (!(dpy = XOpenDisplay(NULL))) { + warn("XOpenDisplay: Failed to open display"); + return NULL; + } + + ; + if (!(desc = XkbAllocKeyboard())) { + warn("XkbAllocKeyboard: failed to allocate keyboard"); + XCloseDisplay(dpy); + return NULL; + } + + XkbGetNames(dpy, XkbSymbolsNameMask, desc); + if (desc->names) { + XkbStateRec state; + XkbGetState(dpy, XkbUseCoreKbd, &state); + + symbols = XGetAtomName(dpy, desc->names->symbols); + GetKeyLayout(symbols, layout, state.group); + XFree(symbols); + } else { + warn("XkbGetNames: failed to retrieve symbols for keys"); + return NULL; + } + + XkbFreeKeyboard(desc, XkbSymbolsNameMask, 1); + XCloseDisplay(dpy); + + return layout; +} diff --git a/config.def.h b/config.def.h index 45320a3..75debe5 100644 --- a/config.def.h +++ b/config.def.h @@ -34,6 +34,8 @@ static const char unknown_str[] = "n/a"; * ipv6 IPv6 address interface name (eth0) * kernel_release `uname -r` NULL * keyboard_indicators caps/num lock indicators NULL + * keymap layout (variant) of current NULL + * keymap * load_avg load average NULL * netspeed_rx receive network speed interface name (wlan0) * netspeed_tx transfer network speed interface name (wlan0) diff --git a/slstatus.h b/slstatus.h index a18b881..6112e7e 100644 --- a/slstatus.h +++ b/slstatus.h @@ -37,6 +37,9 @@ const char *kernel_release(void); /* keyboard_indicators */ const char *keyboard_indicators(void); +/* keymap */ +const char *keymap(void); + /* load_avg */ const char *load_avg(const char *); -- 2.20.1 From cf2b604507a71c61e757d7bf85458c7300eb3cf5 Mon Sep 17 00:00:00 2001 From: Aaron Marcher Date: Wed, 23 May 2018 10:12:20 +0200 Subject: [PATCH 15/16] Add Michael Buch to LICENSE --- LICENSE | 1 + 1 file changed, 1 insertion(+) diff --git a/LICENSE b/LICENSE index bd6b13b..5956929 100644 --- a/LICENSE +++ b/LICENSE @@ -16,6 +16,7 @@ Copyright 2018 Darron Anderson Copyright 2018 Josuah Demangeon Copyright 2018 Tobias Tschinkowitz Copyright 2018 David Demelier +Copyright 2018 Michael Buch Permission to use, copy, modify, and/or distribute this software for any purpose with or without fee is hereby granted, provided that the above -- 2.20.1 From 385aedffd90e513cc007e44e57785d7c3d934f6f Mon Sep 17 00:00:00 2001 From: Aaron Marcher Date: Wed, 23 May 2018 11:50:08 +0200 Subject: [PATCH 16/16] Add keymap to README --- README | 1 + 1 file changed, 1 insertion(+) diff --git a/README b/README index f6041de..4f23959 100644 --- a/README +++ b/README @@ -19,6 +19,7 @@ Features - IP address (IPv4 and IPv6) - Kernel version - Keyboard indicators +- Keymap - Load average - Network speeds (RX and TX) - Number of files in a directory (hint: Maildir) -- 2.20.1