keymap.c - slstatus - status monitor | |
git clone git://git.suckless.org/slstatus | |
Log | |
Files | |
Refs | |
README | |
LICENSE | |
--- | |
keymap.c (1869B) | |
--- | |
1 /* See LICENSE file for copyright and license details. */ | |
2 #include <ctype.h> | |
3 #include <stdlib.h> | |
4 #include <string.h> | |
5 #include <X11/XKBlib.h> | |
6 #include <X11/Xlib.h> | |
7 | |
8 #include "../slstatus.h" | |
9 #include "../util.h" | |
10 | |
11 static int | |
12 valid_layout_or_variant(char *sym) | |
13 { | |
14 size_t i; | |
15 /* invalid symbols from xkb rules config */ | |
16 static const char *invalid[] = { "evdev", "inet", "pc", "base" }; | |
17 | |
18 for (i = 0; i < LEN(invalid); i++) | |
19 if (!strncmp(sym, invalid[i], strlen(invalid[i]))) | |
20 return 0; | |
21 | |
22 return 1; | |
23 } | |
24 | |
25 static char * | |
26 get_layout(char *syms, int grp_num) | |
27 { | |
28 char *tok, *layout; | |
29 int grp; | |
30 | |
31 layout = NULL; | |
32 tok = strtok(syms, "+:_"); | |
33 for (grp = 0; tok && grp <= grp_num; tok = strtok(NULL, "+:_")) { | |
34 if (!valid_layout_or_variant(tok)) { | |
35 continue; | |
36 } else if (strlen(tok) == 1 && isdigit(tok[0])) { | |
37 /* ignore :2, :3, :4 (additional layout groups) … | |
38 continue; | |
39 } | |
40 layout = tok; | |
41 grp++; | |
42 } | |
43 | |
44 return layout; | |
45 } | |
46 | |
47 const char * | |
48 keymap(const char *unused) | |
49 { | |
50 Display *dpy; | |
51 XkbDescRec *desc; | |
52 XkbStateRec state; | |
53 char *symbols; | |
54 const char *layout; | |
55 | |
56 layout = NULL; | |
57 | |
58 if (!(dpy = XOpenDisplay(NULL))) { | |
59 warn("XOpenDisplay: Failed to open display"); | |
60 return NULL; | |
61 } | |
62 if (!(desc = XkbAllocKeyboard())) { | |
63 warn("XkbAllocKeyboard: Failed to allocate keyboard"); | |
64 goto end; | |
65 } | |
66 if (XkbGetNames(dpy, XkbSymbolsNameMask, desc)) { | |
67 warn("XkbGetNames: Failed to retrieve key symbols"); | |
68 goto end; | |
69 } | |
70 if (XkbGetState(dpy, XkbUseCoreKbd, &state)) { | |
71 warn("XkbGetState: Failed to retrieve keyboard state"); | |
72 goto end; | |
73 } | |
74 if (!(symbols = XGetAtomName(dpy, desc->names->symbols))) { | |
75 warn("XGetAtomName: Failed to get atom name"); | |
76 goto end; | |
77 } | |
78 layout = bprintf("%s", get_layout(symbols, state.group)); | |
79 XFree(symbols); | |
80 end: | |
81 XkbFreeKeyboard(desc, XkbSymbolsNameMask, 1); | |
82 if (XCloseDisplay(dpy)) | |
83 warn("XCloseDisplay: Failed to close display"); | |
84 | |
85 return layout; | |
86 } |