aboutsummaryrefslogtreecommitdiff
path: root/i3/bin/kbdlayout.c
blob: bb030bbed25909656fcb2df016dbda1279cc24b0 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
#include <X11/XKBlib.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>

char* getActiveLayout(char* names, unsigned char active) {
	int i;
	for (i = 0; names[i]; i++) {
		if (names[i] == '+') {
			if (active <= 0) {
				int j = ++i;
				for (; names[j] && names[j] != '+' && names[j] != ':'; j++);
				char* ret = malloc(j - i + 1);
				strncpy(ret, names + i, j - i);
				ret[j - i] = '\0';
				return ret;
			} else {
				active--;
			}
		}
	}
	return NULL;
}

int main(void) {
	int evCode, errRet, rsnRet;
	int maj = XkbMajorVersion;
	int min = XkbMinorVersion;

	Display* disp = XkbOpenDisplay("", &evCode, &errRet, &maj, &min, &rsnRet);

	// State
	XkbStatePtr state = calloc(1, sizeof(XkbStateRec));
	XkbGetState(disp, 0x100, state);

	// Names
	XkbDescPtr desc = XkbAllocKeyboard();
	XkbGetNames(disp, XkbSymbolsNameMask, desc);

	Atom symNameAtom = desc->names->symbols;
	char* layouts = XGetAtomName(disp, symNameAtom);

	printf("%s\n", getActiveLayout(layouts, state->group));

	unsigned int mask = XkbStateNotifyMask;
	XkbSelectEvents(disp, XkbUseCoreKbd, mask, mask);

	XkbEvent event;
	while (1) {
		XNextEvent(disp, &event.core);
		if (event.state.changed & 0x90)
			printf("%s\n", getActiveLayout(layouts, event.state.group));
	}
}