tAdd key state plugin with caps lock as example - spoon - dwm status utility (2f30 fork)
 (HTM) git clone git://src.adamsgaard.dk/spoon
 (DIR) Log
 (DIR) Files
 (DIR) Refs
 (DIR) LICENSE
       ---
 (DIR) commit 26f4036b31ba4d4b96fb8f103fdc30a897438e46
 (DIR) parent cbac9231f348a7b018dfc6ac175cf6c3c78ae872
 (HTM) Author: lostd <lostd@2f30.org>
       Date:   Thu,  6 Apr 2017 10:05:53 +0300
       
       Add key state plugin with caps lock as example
       
       Diffstat:
         M Makefile                            |       4 ++--
         M config.def.h                        |       1 +
         A key.c                               |      50 +++++++++++++++++++++++++++++++
         M spoon.c                             |       2 ++
         M stub.c                              |       7 +++++++
         M types.h                             |       6 ++++++
       
       6 files changed, 68 insertions(+), 2 deletions(-)
       ---
 (DIR) diff --git a/Makefile b/Makefile
       t@@ -1,8 +1,8 @@
        VERSION = 0.3
        PREFIX = /usr/local
       -SRC = spoon.c batt.c wifi.c cpu.c temp.c date.c load.c file.c\
       +SRC = spoon.c batt.c wifi.c cpu.c temp.c date.c load.c file.c key.c\
              strlcpy.c strlcat.c stub.c mix.c xkblayout.c mpd.c
       -OBJ = spoon.o batt.o wifi.o cpu.o temp.o date.o load.o file.o\
       +OBJ = spoon.o batt.o wifi.o cpu.o temp.o date.o load.o file.o key.o\
              strlcpy.o strlcat.o stub.o
        BIN = spoon
        DISTFILES = $(SRC) types.h util.h config.def.h Makefile LICENSE configure
 (DIR) diff --git a/config.def.h b/config.def.h
       t@@ -11,6 +11,7 @@ struct ent ents[] = {
                { .fmt = "%s ",                .read = battread,        .arg = NULL },
                { .fmt = "%s ",                .read = wifiread,        .arg = NULL },
                { .fmt = "[%s] ",        .read = xkblayoutread,        .arg = NULL },
       +        { .fmt = "%s",                .read = keyread,        .arg = &(struct keyarg){ .sym = XK_Caps_Lock, .on = "[caps] ", .off = "" } },
                { .fmt = "%s ",                .read = fileread,        .arg = "/etc/myname" },
                { .fmt = "%s",                .read = dateread,        .arg = (char []){"%a %d %b %Y %H:%M %Z"} },
        };
 (DIR) diff --git a/key.c b/key.c
       t@@ -0,0 +1,50 @@
       +#include <err.h>
       +#include <stdio.h>
       +
       +#include <X11/keysym.h>
       +#include <X11/Xlib.h>
       +
       +#include "types.h"
       +#include "util.h"
       +
       +int
       +keyread(void *arg, char *buf, size_t len)
       +{
       +        static Display *dpy = NULL;
       +        XModifierKeymap *map;
       +        KeyCode keycode;
       +        Window w1, w2;
       +        int i1, i2, i3, i4;
       +        int modmask;
       +        int keymask;
       +        struct keyarg *key = arg;
       +        int on;
       +        int i;
       +
       +        if (dpy == NULL) {
       +                dpy = XOpenDisplay(NULL);
       +                if (dpy == NULL) {
       +                        warnx("cannot open display");
       +                        return -1;
       +                }
       +        }
       +        keycode = XKeysymToKeycode(dpy, key->sym);
       +        if (keycode == NoSymbol) {
       +                warnx("no key code for this symbol");
       +                return -1;
       +        }
       +        map = XGetModifierMapping(dpy);
       +        for (i = 0; i < 8; i++)
       +                if (map->modifiermap[map->max_keypermod * i] == keycode)
       +                        keymask = 1 << i;
       +        XFreeModifiermap(map);
       +        XQueryPointer(dpy, DefaultRootWindow(dpy),
       +                      &w1, &w2, &i1, &i2, &i3, &i4, &modmask);
       +        on = (keymask & modmask) != 0;
       +        DPRINTF_D(on);
       +        if (on)
       +                snprintf(buf, len, "%s", key->on);
       +        else
       +                snprintf(buf, len, "%s", key->off);
       +        return 0;
       +}
 (DIR) diff --git a/spoon.c b/spoon.c
       t@@ -3,6 +3,7 @@
        #include <stdio.h>
        #include <unistd.h>
        
       +#include <X11/keysym.h>
        #include <X11/Xlib.h>
        
        #include "util.h"
       t@@ -18,6 +19,7 @@ int tempread(void *, char *, size_t);
        int wifiread(void *, char *, size_t);
        int xkblayoutread(void *, char *, size_t);
        int fileread(void *, char *, size_t);
       +int keyread(void *, char *, size_t);
        
        struct ent {
                char *fmt;
 (DIR) diff --git a/stub.c b/stub.c
       t@@ -55,3 +55,10 @@ fileread(void *arg, char *buf, size_t len)
        {
                return -1;
        }
       +
       +#pragma weak keyread
       +int
       +keyread(void *arg, char *buf, size_t len)
       +{
       +        return -1;
       +}
 (DIR) diff --git a/types.h b/types.h
       t@@ -2,3 +2,9 @@ struct mpdarg {
                char *host;
                unsigned int port;
        };
       +
       +struct keyarg {
       +        int sym;
       +        char *on;
       +        char *off;
       +};