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