keyboard_indicators.c - slstatus - status monitor
  HTML git clone git://git.suckless.org/slstatus
   DIR Log
   DIR Files
   DIR Refs
   DIR README
   DIR LICENSE
       ---
       keyboard_indicators.c (1238B)
       ---
            1 /* See LICENSE file for copyright and license details. */
            2 #include <ctype.h>
            3 #include <stdio.h>
            4 #include <string.h>
            5 #include <X11/Xlib.h>
            6 
            7 #include "../slstatus.h"
            8 #include "../util.h"
            9 
           10 /*
           11  * fmt consists of uppercase or lowercase 'c' for caps lock and/or 'n' for num
           12  * lock, each optionally followed by '?', in the order of indicators desired.
           13  * If followed by '?', the letter with case preserved is included in the output
           14  * if the corresponding indicator is on.  Otherwise, the letter is always
           15  * included, lowercase when off and uppercase when on.
           16  */
           17 const char *
           18 keyboard_indicators(const char *fmt)
           19 {
           20         Display *dpy;
           21         XKeyboardState state;
           22         size_t fmtlen, i, n;
           23         int togglecase, isset;
           24         char key;
           25 
           26         if (!(dpy = XOpenDisplay(NULL))) {
           27                 warn("XOpenDisplay: Failed to open display");
           28                 return NULL;
           29         }
           30         XGetKeyboardControl(dpy, &state);
           31         XCloseDisplay(dpy);
           32 
           33         fmtlen = strnlen(fmt, 4);
           34         for (i = n = 0; i < fmtlen; i++) {
           35                 key = tolower(fmt[i]);
           36                 if (key != 'c' && key != 'n')
           37                         continue;
           38 
           39                 togglecase = (i + 1 >= fmtlen || fmt[i + 1] != '?');
           40                 isset = (state.led_mask & (1 << (key == 'n')));
           41 
           42                 if (togglecase)
           43                         buf[n++] = isset ? toupper(key) : key;
           44                 else if (isset)
           45                         buf[n++] = fmt[i];
           46         }
           47 
           48         buf[n] = 0;
           49         return buf;
           50 }