Xinqi Bao's Git

keymap: Add braces for for loop
[slstatus.git] / components / keymap.c
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 "../util.h"
9
10 #define LAYOUT_MAX 256
11
12 /* Given a token (sym) from the xkb_symbols string
13 * check whether it is a valid layout/variant. The
14 * EXCLUDES array contains invalid layouts/variants
15 * that are part of the xkb rules config.
16 */
17 static int
18 IsLayoutOrVariant(char *sym)
19 {
20 static const char* EXCLUDES[] = { "evdev", "inet", "pc", "base" };
21
22 size_t i;
23 for (i = 0; i < sizeof(EXCLUDES)/sizeof(EXCLUDES[0]); ++i) {
24 if (strstr(sym, EXCLUDES[i])) {
25 return 0;
26 }
27 }
28
29 return 1;
30 }
31
32 static void
33 GetKeyLayout(char *syms, char layout[], int groupNum)
34 {
35 char *token, *copy, *delims;
36 int group;
37
38 delims = "+:";
39 group = 0;
40 copy = strdup(syms);
41 token = strtok(copy, delims);
42 while (token != NULL && group <= groupNum) {
43 /* Ignore :2,:3,:4 which represent additional layout
44 * groups
45 */
46 if (IsLayoutOrVariant(token)
47 && !(strlen(token) == 1 && isdigit(token[0]))) {
48 strncpy (layout, token, LAYOUT_MAX);
49 group++;
50 }
51
52 token = strtok(NULL,delims);
53 }
54
55 free(copy);
56 }
57
58 const char *
59 keymap(void)
60 {
61 static char layout[LAYOUT_MAX];
62
63 Display *dpy;
64 char *symbols = NULL;
65 XkbDescRec* desc = NULL;
66
67 memset(layout, '\0', LAYOUT_MAX);
68
69 if (!(dpy = XOpenDisplay(NULL))) {
70 warn("XOpenDisplay: Failed to open display");
71 return NULL;
72 }
73
74 ;
75 if (!(desc = XkbAllocKeyboard())) {
76 warn("XkbAllocKeyboard: failed to allocate keyboard");
77 XCloseDisplay(dpy);
78 return NULL;
79 }
80
81 XkbGetNames(dpy, XkbSymbolsNameMask, desc);
82 if (desc->names) {
83 XkbStateRec state;
84 XkbGetState(dpy, XkbUseCoreKbd, &state);
85
86 symbols = XGetAtomName(dpy, desc->names->symbols);
87 GetKeyLayout(symbols, layout, state.group);
88 XFree(symbols);
89 } else {
90 warn("XkbGetNames: failed to retrieve symbols for keys");
91 return NULL;
92 }
93
94 XkbFreeKeyboard(desc, XkbSymbolsNameMask, 1);
95 XCloseDisplay(dpy);
96
97 return layout;
98 }