Bladeren bron

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.
master
Michael Buch 6 jaren geleden
committed by Aaron Marcher
bovenliggende
commit
943b42de05
4 gewijzigde bestanden met toevoegingen van 103 en 0 verwijderingen
  1. +1
    -0
      Makefile
  2. +97
    -0
      components/keymap.c
  3. +2
    -0
      config.def.h
  4. +3
    -0
      slstatus.h

+ 1
- 0
Makefile Bestand weergeven

@@ -16,6 +16,7 @@ COM =\
components/ip\
components/kernel_release\
components/keyboard_indicators\
components/keymap\
components/load_avg\
components/netspeeds\
components/num_files\


+ 97
- 0
components/keymap.c Bestand weergeven

@@ -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;
}

+ 2
- 0
config.def.h Bestand weergeven

@@ -34,6 +34,8 @@ static const char unknown_str[] = "n/a";
* ipv6 IPv6 address interface name (eth0)
* kernel_release `uname -r` NULL
* keyboard_indicators caps/num lock indicators NULL
* keymap layout (variant) of current NULL
* keymap
* load_avg load average NULL
* netspeed_rx receive network speed interface name (wlan0)
* netspeed_tx transfer network speed interface name (wlan0)


+ 3
- 0
slstatus.h Bestand weergeven

@@ -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 *);



Laden…
Annuleren
Opslaan