commit 6a3a2b7d107daccf3d0ee2a3d53b76b246dd6422
parent 12b21d085d2e8d56034a7047dc1bcf60f49d46e8
Author: lostd <lostd@2f30.org>
Date:   Sat, 14 May 2016 18:52:42 +0100
Add support for X keyboard layout
Diffstat:
| M | spoon.c | | | 44 | ++++++++++++++++++++++++++++++++++++++++++++ | 
1 file changed, 44 insertions(+), 0 deletions(-)
diff --git a/spoon.c b/spoon.c
@@ -9,12 +9,16 @@
 
 #include <machine/apmvar.h>
 
+#include <X11/XKBlib.h>
+#include <X11/extensions/XKBrules.h>
+
 #define LEN(x) (sizeof (x) / sizeof *(x))
 
 int dummyread(char *buf, size_t len);
 int mpdread(char *buf, size_t len);
 int battread(char *buf, size_t len);
 int dateread(char *buf, size_t len);
+int xkblayoutread(char *buf, size_t len);
 
 struct ent {
 	char *fmt;
@@ -24,6 +28,8 @@ struct ent {
 	{ .fmt = " ", .read = dummyread },
 	{ .fmt = "%s%%", .read = battread },
 	{ .fmt = " ", .read = dummyread },
+	{ .fmt = "[%s]", .read = xkblayoutread },
+	{ .fmt = " ", .read = dummyread },
 	{ .fmt = "%s", .read = dateread },
 };
 
@@ -79,6 +85,44 @@ dateread(char *buf, size_t len)
 	return 0;
 }
 
+int
+xkblayoutread(char *buf, size_t len)
+{
+	Display *dpy;
+	XkbStateRec state;
+	XkbRF_VarDefsRec vd;
+	char *tmp, *str, *tok;
+	int i, ret = 0;
+
+	dpy = XOpenDisplay(NULL);
+	if (dpy == NULL) {
+		warnx("cannot open display");
+		return -1;
+	}
+	XkbGetState(dpy, XkbUseCoreKbd, &state);
+	XkbRF_GetNamesProp(dpy, &tmp, &vd);
+	str = strdup(vd.layout);
+	if (str == NULL) {
+		ret = -1;
+		goto out0;
+	}
+	tok = strtok(str, ",");
+	for (i = 0; i < state.group; i++) {
+		tok = strtok(NULL, ",");
+		if (tok == NULL) {
+			warnx("cannot extract layout");
+			ret = -1;
+			goto out1;
+		}
+	}
+	strlcpy(buf, tok, len);
+out1:
+	free(str);
+out0:
+	XCloseDisplay(dpy);
+	return ret;
+}
+
 void
 entcat(char *line, size_t len)
 {