Add keymap component
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.
This commit is contained in:
parent
57f69e900b
commit
943b42de05
1
Makefile
1
Makefile
|
@ -16,6 +16,7 @@ COM =\
|
||||||
components/ip\
|
components/ip\
|
||||||
components/kernel_release\
|
components/kernel_release\
|
||||||
components/keyboard_indicators\
|
components/keyboard_indicators\
|
||||||
|
components/keymap\
|
||||||
components/load_avg\
|
components/load_avg\
|
||||||
components/netspeeds\
|
components/netspeeds\
|
||||||
components/num_files\
|
components/num_files\
|
||||||
|
|
|
@ -0,0 +1,97 @@
|
||||||
|
/* See LICENSE file for copyright and license details. */
|
||||||
|
#include <ctype.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <X11/XKBlib.h>
|
||||||
|
#include <X11/Xlib.h>
|
||||||
|
|
||||||
|
#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, &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;
|
||||||
|
}
|
||||||
|
|
||||||
|
XkbFreeKeyboard(desc, XkbSymbolsNameMask, 1);
|
||||||
|
XCloseDisplay(dpy);
|
||||||
|
|
||||||
|
return layout;
|
||||||
|
}
|
|
@ -34,6 +34,8 @@ static const char unknown_str[] = "n/a";
|
||||||
* ipv6 IPv6 address interface name (eth0)
|
* ipv6 IPv6 address interface name (eth0)
|
||||||
* kernel_release `uname -r` NULL
|
* kernel_release `uname -r` NULL
|
||||||
* keyboard_indicators caps/num lock indicators NULL
|
* keyboard_indicators caps/num lock indicators NULL
|
||||||
|
* keymap layout (variant) of current NULL
|
||||||
|
* keymap
|
||||||
* load_avg load average NULL
|
* load_avg load average NULL
|
||||||
* netspeed_rx receive network speed interface name (wlan0)
|
* netspeed_rx receive network speed interface name (wlan0)
|
||||||
* netspeed_tx transfer network speed interface name (wlan0)
|
* netspeed_tx transfer network speed interface name (wlan0)
|
||||||
|
|
|
@ -37,6 +37,9 @@ const char *kernel_release(void);
|
||||||
/* keyboard_indicators */
|
/* keyboard_indicators */
|
||||||
const char *keyboard_indicators(void);
|
const char *keyboard_indicators(void);
|
||||||
|
|
||||||
|
/* keymap */
|
||||||
|
const char *keymap(void);
|
||||||
|
|
||||||
/* load_avg */
|
/* load_avg */
|
||||||
const char *load_avg(const char *);
|
const char *load_avg(const char *);
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue