-
Notifications
You must be signed in to change notification settings - Fork 0
/
keymap.c
63 lines (54 loc) · 1.33 KB
/
keymap.c
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
55
56
57
58
59
60
61
62
63
#include "keymap.h"
#include "mem.h"
#include "util.h"
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <X11/XKBlib.h>
#include <X11/Xlib.h>
int
valid_layout(char* str)
{
char* invalid[] = { "evdev", "pc", "inet", "base" };
for (size_t i = 0; i < ARRLEN(invalid); i++) {
if (!strncmp(str, invalid[i], strlen(invalid[i])))
return 0;
}
return 1;
}
char*
get_keymap(void)
{
Display* dpy;
XkbDescRec* desc;
XkbStateRec state;
char* symbols;
char* layout = NULL;
if (!(dpy = XOpenDisplay(NULL)))
return NULL;
if (!(desc = XkbAllocKeyboard()))
goto end;
if (XkbGetNames(dpy, XkbSymbolsNameMask, desc))
goto end;
if (XkbGetState(dpy, XkbUseCoreKbd, &state))
goto end;
if (!(symbols = XGetAtomName(dpy, desc->names->symbols)))
goto end;
char* ptr = strtok(symbols, "+:");
for (int g = 0; ptr && g <= state.group; ptr = strtok(NULL, "+:")) {
if (!valid_layout(ptr))
continue;
else if (strlen(ptr) == 1 && ISNUM(ptr[0]))
continue;
if (layout != NULL)
free(layout);
layout = strdup(ptr);
g++;
}
free(symbols);
end:
XkbFreeKeyboard(desc, XkbSymbolsNameMask, 1);
if (XCloseDisplay(dpy))
return NULL;
return layout;
}