diff --git a/.gitignore b/.gitignore index 2bf1ac8..c21fe43 100644 --- a/.gitignore +++ b/.gitignore @@ -1,3 +1,5 @@ +*.o + # Vim swap files *swp *~ diff --git a/bin/get-kbd-layout b/bin/get-kbd-layout new file mode 100755 index 0000000..7ce6ccf Binary files /dev/null and b/bin/get-kbd-layout differ diff --git a/bumblebee_status/modules/core/layout.py b/bumblebee_status/modules/core/layout.py new file mode 100644 index 0000000..3ebeeb5 --- /dev/null +++ b/bumblebee_status/modules/core/layout.py @@ -0,0 +1,39 @@ +# pylint: disable=C0111,R0903 + +"""Displays the current keyboard layout + +Parameters: + * layout.device: The device ID of the keyboard (as reported by `xinput -list`), defaults to the core device +""" + +import re + +import core.widget +import core.module + +import util.cli + +from bumblebee_status.discover import utility + +class Module(core.module.Module): + def __init__(self, config, theme): + super().__init__(config=config, theme=theme, widgets=core.widget.Widget(self.get_layout)) + + self._cmd = utility("get-kbd-layout") + keyboard = self.parameter("device", None) + if keyboard: + self._cmd += " {}".format(keyboard) + + def get_layout(self, widget): + result = util.cli.execute(self._cmd, ignore_errors=True) + + m = re.search("([a-zA-Z]+_)?([a-zA-Z]+)(\(([\w-]+)\))?", result) + + if m: + layout = m.group(2) + variant = m.group(3) + return layout if not variant else "{} {}".format(layout, variant) + + return "n/a" + +# vim: tabstop=8 expandtab shiftwidth=4 softtabstop=4 diff --git a/util/Makefile b/util/Makefile new file mode 100644 index 0000000..1e187c2 --- /dev/null +++ b/util/Makefile @@ -0,0 +1,13 @@ +CC=gcc +CFLAGS= + +%.o: %.c + $(CC) -c -o $@ $< $(CFLAGS) + +../bin/get-kbd-layout: layout.o + $(CC) -o $@ layout.o -lX11 + +.PHONY: clean + +clean: + rm -f *.o diff --git a/util/layout.c b/util/layout.c new file mode 100644 index 0000000..21aac1f --- /dev/null +++ b/util/layout.c @@ -0,0 +1,39 @@ +#include +#include + +#include + +void err_if(int condition, const char* msg) +{ + if (condition) { + fprintf(stderr, "fatal: %s\n", msg); + exit(1); + } +} + +int main(int argc, char** argv) +{ + Display* display = XOpenDisplay(NULL); + err_if(!display, "unable to open display"); + + int kbd = argc == 1 ? XkbUseCoreKbd : atoi(argv[1]); + + XkbStateRec state; + XkbGetState(display, kbd, &state); + + XkbDescPtr desc = XkbGetKeyboard(display, XkbAllComponentsMask, kbd); + char* symbols = XGetAtomName(display, desc->names->symbols); + printf("%s\n", symbols); + +#if 0 + char *group = XGetAtomName(display, desc->names->groups[state.group]); + XFree(group); +#endif + XFree(symbols); + XFree(desc); + + XCloseDisplay(display); + + return 0; +} +