Xinqi Bao's Git

Consistency with 80 char limit and breaks
[slstatus.git] / components / keyboard_indicators.c
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 }