URI: 
       keymap.c - slstatus - status monitor
  HTML 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 }