| Refactor keymap.c - slstatus - status monitor | |
| git clone git://git.suckless.org/slstatus | |
| Log | |
| Files | |
| Refs | |
| README | |
| LICENSE | |
| --- | |
| commit f17f39d0a2e2898177dbcf5daf67284956005b9b | |
| parent 13d77cd268bade5e9ee9c07d9b94ca7c733cbe3d | |
| Author: Laslo Hunhold <[email protected]> | |
| Date: Wed, 23 May 2018 15:29:37 +0200 | |
| Refactor keymap.c | |
| - Get rid of camel-casing | |
| - Don't use all-caps for variable names | |
| - use LEN()-macro | |
| - use strncmp() rather than strstr() for prefix-checking | |
| - clean up the tokenizer-loop and don't use copies | |
| - make the loop more readable by separating different breaking | |
| conditions | |
| - stricter error-checking and cleanup | |
| - store the layout directly with bprintf rather than having | |
| a separate buffer | |
| Diffstat: | |
| M components/keymap.c | 101 ++++++++++++++---------------… | |
| 1 file changed, 45 insertions(+), 56 deletions(-) | |
| --- | |
| diff --git a/components/keymap.c b/components/keymap.c | |
| @@ -7,21 +7,15 @@ | |
| #include "../util.h" | |
| -#define LAYOUT_MAX 256 | |
| - | |
| -/* Given a token (sym) from the xkb_symbols string | |
| - * check whether it is a valid layout/variant. The | |
| - * EXCLUDES array contains invalid layouts/variants | |
| - * that are part of the xkb rules config. | |
| - */ | |
| static int | |
| -IsLayoutOrVariant(char *sym) | |
| +valid_layout_or_variant(char *sym) | |
| { | |
| - static const char* EXCLUDES[] = { "evdev", "inet", "pc", "base" }; | |
| - | |
| size_t i; | |
| - for (i = 0; i < sizeof(EXCLUDES)/sizeof(EXCLUDES[0]); ++i) { | |
| - if (strstr(sym, EXCLUDES[i])) { | |
| + /* invalid symbols from xkb rules config */ | |
| + static const char *invalid[] = { "evdev", "inet", "pc", "base" }; | |
| + | |
| + for (i = 0; i < LEN(invalid); i++) { | |
| + if (!strncmp(sym, invalid[i], strlen(invalid[i]))) { | |
| return 0; | |
| } | |
| } | |
| @@ -29,70 +23,65 @@ IsLayoutOrVariant(char *sym) | |
| return 1; | |
| } | |
| -static void | |
| -GetKeyLayout(char *syms, char layout[], int groupNum) | |
| +static char * | |
| +get_layout(char *syms, int grp_num) | |
| { | |
| - char *token, *copy, *delims; | |
| - int group; | |
| - | |
| - delims = "+:"; | |
| - group = 0; | |
| - copy = strdup(syms); | |
| - token = strtok(copy, delims); | |
| - while (token != NULL && group <= groupNum) { | |
| - /* Ignore :2,:3,:4 which represent additional layout | |
| - * groups | |
| - */ | |
| - if (IsLayoutOrVariant(token) | |
| - && !(strlen(token) == 1 && isdigit(token[0]))) { | |
| - strncpy (layout, token, LAYOUT_MAX); | |
| - group++; | |
| + char *tok, *layout; | |
| + int grp; | |
| + | |
| + layout = NULL; | |
| + tok = strtok(syms, "+:"); | |
| + for (grp = 0; tok && grp <= grp_num; tok = strtok(NULL, "+:")) { | |
| + if (!valid_layout_or_variant(tok)) { | |
| + continue; | |
| + } else if (strlen(tok) == 1 && isdigit(tok[0])) { | |
| + /* ignore :2, :3, :4 (additional layout groups) */ | |
| + continue; | |
| } | |
| - | |
| - token = strtok(NULL,delims); | |
| + layout = tok; | |
| + grp++; | |
| } | |
| - free(copy); | |
| + return layout; | |
| } | |
| const char * | |
| keymap(void) | |
| { | |
| - static char layout[LAYOUT_MAX]; | |
| - | |
| Display *dpy; | |
| - char *symbols = NULL; | |
| - XkbDescRec* desc = NULL; | |
| + XkbDescRec *desc; | |
| + XkbStateRec state; | |
| + char *symbols, *layout; | |
| - memset(layout, '\0', LAYOUT_MAX); | |
| + layout = NULL; | |
| if (!(dpy = XOpenDisplay(NULL))) { | |
| warn("XOpenDisplay: Failed to open display"); | |
| return NULL; | |
| } | |
| - | |
| - ; | |
| if (!(desc = XkbAllocKeyboard())) { | |
| - warn("XkbAllocKeyboard: failed to allocate keyboard"); | |
| - XCloseDisplay(dpy); | |
| - return NULL; | |
| + warn("XkbAllocKeyboard: Failed to allocate keyboard"); | |
| + goto end; | |
| } | |
| - | |
| - XkbGetNames(dpy, XkbSymbolsNameMask, desc); | |
| - if (desc->names) { | |
| - XkbStateRec state; | |
| - XkbGetState(dpy, XkbUseCoreKbd, &state); | |
| - | |
| - symbols = XGetAtomName(dpy, desc->names->symbols); | |
| - GetKeyLayout(symbols, layout, state.group); | |
| - XFree(symbols); | |
| - } else { | |
| - warn("XkbGetNames: failed to retrieve symbols for keys"); | |
| - return NULL; | |
| + if (XkbGetNames(dpy, XkbSymbolsNameMask, desc)) { | |
| + warn("XkbGetNames: Failed to retrieve key symbols"); | |
| + goto end; | |
| } | |
| - | |
| + if (XkbGetState(dpy, XkbUseCoreKbd, &state)) { | |
| + warn("XkbGetState: Failed to retrieve keyboard state"); | |
| + goto end; | |
| + } | |
| + if (!(symbols = XGetAtomName(dpy, desc->names->symbols))) { | |
| + warn("XGetAtomName: Failed to get atom name"); | |
| + goto end; | |
| + } | |
| + layout = (char *)bprintf("%s", get_layout(symbols, state.group)); | |
| + XFree(symbols); | |
| +end: | |
| XkbFreeKeyboard(desc, XkbSymbolsNameMask, 1); | |
| - XCloseDisplay(dpy); | |
| + if (XCloseDisplay(dpy)) { | |
| + warn("XCloseDisplay: Failed to close display"); | |
| + } | |
| return layout; | |
| } |