suckless/slstatus

components/keyboard_indicators.c in master
Repositories | Summary | Log | Files | README | LICENSE

keyboard_indicators.c (1238B) download


 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 */
17const char *
18keyboard_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}