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 }