|
|
@@ -1,14 +1,26 @@ |
|
|
|
/* See LICENSE file for copyright and license details. */ |
|
|
|
#include <ctype.h> |
|
|
|
#include <stdio.h> |
|
|
|
#include <string.h> |
|
|
|
#include <X11/Xlib.h> |
|
|
|
|
|
|
|
#include "../util.h" |
|
|
|
|
|
|
|
/* |
|
|
|
* fmt consists of uppercase or lowercase 'c' for caps lock and/or 'n' for num |
|
|
|
* lock, each optionally followed by '?', in the order of indicators desired. |
|
|
|
* If followed by '?', the letter with case preserved is included in the output |
|
|
|
* if the corresponding indicator is on. Otherwise, the letter is always |
|
|
|
* included, lowercase when off and uppercase when on. |
|
|
|
*/ |
|
|
|
const char * |
|
|
|
keyboard_indicators(void) |
|
|
|
keyboard_indicators(const char *fmt) |
|
|
|
{ |
|
|
|
Display *dpy; |
|
|
|
XKeyboardState state; |
|
|
|
size_t fmtlen, i, n; |
|
|
|
int togglecase, isset; |
|
|
|
char key; |
|
|
|
|
|
|
|
if (!(dpy = XOpenDisplay(NULL))) { |
|
|
|
warn("XOpenDisplay: Failed to open display"); |
|
|
@@ -17,14 +29,20 @@ keyboard_indicators(void) |
|
|
|
XGetKeyboardControl(dpy, &state); |
|
|
|
XCloseDisplay(dpy); |
|
|
|
|
|
|
|
switch (state.led_mask) { |
|
|
|
case 1: |
|
|
|
return "c"; |
|
|
|
case 2: |
|
|
|
return "n"; |
|
|
|
case 3: |
|
|
|
return "cn"; |
|
|
|
default: |
|
|
|
return ""; |
|
|
|
fmtlen = strnlen(fmt, 4); |
|
|
|
for (i = n = 0; i < fmtlen; i++) { |
|
|
|
key = tolower(fmt[i]); |
|
|
|
if (key != 'c' && key != 'n') { |
|
|
|
continue; |
|
|
|
} |
|
|
|
togglecase = (i + 1 >= fmtlen || fmt[i + 1] != '?'); |
|
|
|
isset = (state.led_mask & (1 << (key == 'n'))); |
|
|
|
if (togglecase) { |
|
|
|
buf[n++] = isset ? toupper(key) : key; |
|
|
|
} else if (isset) { |
|
|
|
buf[n++] = fmt[i]; |
|
|
|
} |
|
|
|
} |
|
|
|
buf[n] = 0; |
|
|
|
return buf; |
|
|
|
} |