keymap.c - slstatus - status monitor
(HTM) git clone git://git.suckless.org/slstatus
(DIR) Log
(DIR) Files
(DIR) Refs
(DIR) README
(DIR) 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 }