slstatus

status monitor
git clone git://git.suckless.org/slstatus
Log | Files | Refs | README | LICENSE

keyboard_indicators.c (1238B)


      1 /* See LICENSE file for copyright and license details. */
      2 #include <ctype.h>
      3 #include <stdio.h>
      4 #include <string.h>
      5 #include <X11/Xlib.h>
      6 
      7 #include "../slstatus.h"
      8 #include "../util.h"
      9 
     10 /*
     11  * fmt consists of uppercase or lowercase 'c' for caps lock and/or 'n' for num
     12  * lock, each optionally followed by '?', in the order of indicators desired.
     13  * If followed by '?', the letter with case preserved is included in the output
     14  * if the corresponding indicator is on.  Otherwise, the letter is always
     15  * included, lowercase when off and uppercase when on.
     16  */
     17 const char *
     18 keyboard_indicators(const char *fmt)
     19 {
     20 	Display *dpy;
     21 	XKeyboardState state;
     22 	size_t fmtlen, i, n;
     23 	int togglecase, isset;
     24 	char key;
     25 
     26 	if (!(dpy = XOpenDisplay(NULL))) {
     27 		warn("XOpenDisplay: Failed to open display");
     28 		return NULL;
     29 	}
     30 	XGetKeyboardControl(dpy, &state);
     31 	XCloseDisplay(dpy);
     32 
     33 	fmtlen = strnlen(fmt, 4);
     34 	for (i = n = 0; i < fmtlen; i++) {
     35 		key = tolower(fmt[i]);
     36 		if (key != 'c' && key != 'n')
     37 			continue;
     38 
     39 		togglecase = (i + 1 >= fmtlen || fmt[i + 1] != '?');
     40 		isset = (state.led_mask & (1 << (key == 'n')));
     41 
     42 		if (togglecase)
     43 			buf[n++] = isset ? toupper(key) : key;
     44 		else if (isset)
     45 			buf[n++] = fmt[i];
     46 	}
     47 
     48 	buf[n] = 0;
     49 	return buf;
     50 }