keyboard_indicators.c (1226B)
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 = XOpenDisplay(NULL))) { 26 warn("XOpenDisplay: Failed to open display"); 27 return NULL; 28 } 29 XGetKeyboardControl(dpy, &state); 30 XCloseDisplay(dpy); 31 32 fmtlen = strnlen(fmt, 4); 33 for (i = n = 0; i < fmtlen; i++) { 34 key = tolower(fmt[i]); 35 if (key != 'c' && key != 'n') { 36 continue; 37 } 38 togglecase = (i + 1 >= fmtlen || fmt[i + 1] != '?'); 39 isset = (state.led_mask & (1 << (key == 'n'))); 40 if (togglecase) { 41 buf[n++] = isset ? toupper(key) : key; 42 } else if (isset) { 43 buf[n++] = fmt[i]; 44 } 45 } 46 buf[n] = 0; 47 return buf; 48 }