Re: [hackers] [slstatus][PATCH keymap v2] Add keymap component

2018-05-23 Thread Aaron Marcher

Michael,

Thank you, merged.

Cheers!
Aaron

--
Web: https://drkhsh.at/ or http://drkhsh5rv6pnahas.onion/
Gopher: gopher://drkhsh.at or gopher://drkhsh5rv6pnahas.onion
GPG: 0x7A65E38D55BE96FE
Fingerprint: 4688 907C 8720 3318 0D9F AFDE 7A65 E38D 55BE 96FE



[hackers] [slstatus][PATCH keymap v2] Add keymap component

2018-05-23 Thread michaelbuch12
From: Michael Buch 

Adding a new keymap component that will
indicate the current keyboard layout (language)
and variant if any was set. I use the
standard X11 XKB APIs to retrieve and parse
the xkb_symbols set with setxkbmap.
---
 Makefile|  1 +
 components/keymap.c | 96 +
 config.def.h|  2 +
 slstatus.h  |  3 ++
 4 files changed, 102 insertions(+)
 create mode 100644 components/keymap.c

diff --git a/Makefile b/Makefile
index 8e18969..7ed7099 100644
--- a/Makefile
+++ b/Makefile
@@ -16,6 +16,7 @@ COM =\
components/ip\
components/kernel_release\
components/keyboard_indicators\
+   components/keymap\
components/load_avg\
components/netspeeds\
components/num_files\
diff --git a/components/keymap.c b/components/keymap.c
new file mode 100644
index 000..7a2e35a
--- /dev/null
+++ b/components/keymap.c
@@ -0,0 +1,96 @@
+/* See LICENSE file for copyright and license details. */
+#include 
+#include 
+#include 
+#include  
+#include 
+
+#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)
+{
+   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])) {
+   return 0;
+   }
+
+   return 1;
+}
+
+static void
+GetKeyLayout(char *syms, char layout[], int groupNum)
+{
+   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++;
+   }
+
+   token = strtok(NULL,delims);
+   }
+
+   free(copy);
+}
+
+const char *
+keymap(void)
+{
+   static char layout[LAYOUT_MAX];
+
+   Display *dpy;
+   char *symbols = NULL;
+   XkbDescRec* desc = NULL;
+
+   memset(layout, '\0', LAYOUT_MAX);
+
+   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;
+   }
+
+   XkbGetNames(dpy, XkbSymbolsNameMask, desc);
+   if (desc->names) {
+   XkbStateRec state;
+   XkbGetState(dpy, XkbUseCoreKbd, );
+
+   symbols = XGetAtomName(dpy, desc->names->symbols);
+   GetKeyLayout(symbols, layout, state.group);
+   XFree(symbols);
+   } else {
+   warn("XkbGetNames: failed to retrieve symbols for keys");
+   return NULL;
+   }
+
+   XkbFreeKeyboard(desc, XkbSymbolsNameMask, 1);
+   XCloseDisplay(dpy);
+   return layout;
+}
diff --git a/config.def.h b/config.def.h
index 45320a3..75debe5 100644
--- a/config.def.h
+++ b/config.def.h
@@ -34,6 +34,8 @@ static const char unknown_str[] = "n/a";
  * ipv6 IPv6 addressinterface name (eth0)
  * kernel_release   `uname -r`  NULL
  * keyboard_indicators  caps/num lock indicatorsNULL
+ * keymap   layout (variant) of current NULL
+ *  keymap
  * load_avg load averageNULL
  * netspeed_rx  receive network speed   interface name (wlan0)
  * netspeed_tx  transfer network speed  interface name (wlan0)
diff --git a/slstatus.h b/slstatus.h
index a18b881..6112e7e 100644
--- a/slstatus.h
+++ b/slstatus.h
@@ -37,6 +37,9 @@ const char *kernel_release(void);
 /* keyboard_indicators */
 const char *keyboard_indicators(void);
 
+/* keymap */
+const char *keymap(void);
+
 /* load_avg */
 const char *load_avg(const char *);
 
-- 
2.17.0