diff options
author | Alan Coopersmith <alan.coopersmith@sun.com> | 2009-06-16 13:14:47 -0700 |
---|---|---|
committer | Alan Coopersmith <alan.coopersmith@sun.com> | 2009-06-16 13:32:03 -0700 |
commit | 9ee8b074cb8f8de84aafebcc22c6c266371693ec (patch) | |
tree | 1de306ff3e7f83f1fc9bf75c20aaaefe8459f2c7 /xset.c | |
parent | 8ce473c45da07eb82537509a4d14ccb50262bfa7 (diff) |
XKB named indicator support for led state query/set
xset q now lists XKB named indicator states in addition to led bitmask
Sample output:
Keyboard Control:
auto repeat: on key click percent: 0 LED mask: 0000000a
XKB indicators:
00: Caps Lock: off 01: Num Lock: on 02: Scroll Lock: off
03: Compose: on 04: Shift Lock: off 05: Group 2: off
06: Mouse Keys: off
[...]
New options "xset led named <name>" and "xset -led named <name>" allow
turning named leds/virtual indicators on & off.
('named' keyword is necessary to avoid ambiguity if an XKB indicator
is given a numeric name or a name that matches an existing xkb option
due to xset's horrible historic command line syntax model.)
Signed-off-by: Alan Coopersmith <alan.coopersmith@sun.com>
Diffstat (limited to 'xset.c')
-rw-r--r-- | xset.c | 137 |
1 files changed, 133 insertions, 4 deletions
@@ -153,6 +153,7 @@ static void set_bell_dur(Display *dpy, int duration); static void set_font_path(Display *dpy, char *path, int special, int before, int after); static void set_led(Display *dpy, int led, int led_mode); +static void xkbset_led(Display *dpy, const char *led, int led_mode); static void set_mouse(Display *dpy, int acc_num, int acc_denom, int threshold); static void set_saver(Display *dpy, int mask, int value); static void set_repeat(Display *dpy, int key, int auto_repeat_mode); @@ -439,6 +440,15 @@ main(int argc, char *argv[]) break; } arg = nextarg(i, argv); + if (strcmp(arg, "named") == 0) { + if (++i >= argc) { + usage("missing argument to led named", NULL); + } else { + arg = nextarg(i, argv); + xkbset_led(dpy, arg, values.led_mode); + } + break; + } if (is_number(arg, 32) && atoi(arg) > 0) { values.led = atoi(arg); i++; @@ -453,6 +463,15 @@ main(int argc, char *argv[]) break; } arg = nextarg(i, argv); + if (strcmp(arg, "named") == 0) { + if (++i >= argc) { + usage("missing argument to -led named", NULL); + } else { + arg = nextarg(i, argv); + xkbset_led(dpy, arg, values.led_mode); + } + break; + } if (strcmp(arg, "on") == 0) { i++; } else if (strcmp(arg, "off") == 0) { /* ...except in this case. */ @@ -1061,6 +1080,36 @@ set_led(Display *dpy, int led, int led_mode) } static void +xkbset_led(Display *dpy, const char *led, int led_mode) +{ +#ifndef XKB + error(" xset was not built with XKB Extension support\n"); +#else + int xkbmajor = XkbMajorVersion, xkbminor = XkbMinorVersion; + int xkbopcode, xkbevent, xkberror; + Atom ledatom; + + if (XkbQueryExtension(dpy, &xkbopcode, &xkbevent, &xkberror, + &xkbmajor, &xkbminor)) { + ledatom = XInternAtom(dpy, led, True); + if ((ledatom != None) && + XkbGetNamedIndicator(dpy, ledatom, NULL, NULL, NULL, NULL)) { + if (XkbSetNamedIndicator(dpy, ledatom, True, + led_mode, False, NULL) == False) { + printf("Failed to set led named %s %s\n", + led, led_mode ? "on" : "off"); + } + } else { + fprintf(stderr,"%s: Invalid led name: %s\n", progName, led); + } + } else { + printf(" Server does not have the XKB Extension\n"); + } +#endif + return; +} + +static void set_mouse(Display *dpy, int acc_num, int acc_denom, int threshold) { int do_accel = True, do_threshold = True; @@ -1314,10 +1363,86 @@ query(Display *dpy) #ifdef XKB if (XkbQueryExtension(dpy, &xkbopcode, &xkbevent, &xkberror, &xkbmajor, &xkbminor) - && (xkb = XkbAllocKeyboard()) != NULL - && XkbGetControls(dpy, XkbRepeatKeysMask, xkb) == Success) - printf(" auto repeat delay: %d repeat rate: %d\n", - xkb->ctrls->repeat_delay, 1000 / xkb->ctrls->repeat_interval); + && (xkb = XkbAllocKeyboard()) != NULL) { + if (XkbGetNames(dpy, XkbIndicatorNamesMask, xkb) == Success) { + Atom iatoms[XkbNumIndicators]; + char *iatomnames[XkbNumIndicators]; + Bool istates[XkbNumIndicators]; + int inds[XkbNumIndicators]; + int activecount = 0; + int maxnamelen = 0; + int columnwidth; + int linewidth; + + printf(" XKB indicators:\n"); + + for (i = 0, j = 0; i < XkbNumIndicators; i++) { + if (xkb->names->indicators[i] != None) { + iatoms[j++] = xkb->names->indicators[i]; + } + } + + if (XGetAtomNames(dpy, iatoms, j, iatomnames)) { + for (i = 0; i < j; i++) { + Bool state; + int ind; + + if (XkbGetNamedIndicator(dpy, iatoms[i], &inds[i], + &istates[i], NULL, NULL)) { + int namelen = strlen(iatomnames[i]); + if (namelen > maxnamelen) { + maxnamelen = namelen; + } + activecount++; + } else { + inds[i] = -1; + } + } + } + + if (activecount == 0) { + printf(" None\n"); + } else { + +#define XKB_IND_FORMAT_CHARS 13 /* size of other chars in ' DD: X: off' */ +#define MAX_LINE_WIDTH 76 + + columnwidth = maxnamelen + XKB_IND_FORMAT_CHARS; + if (columnwidth > MAX_LINE_WIDTH) { + columnwidth = MAX_LINE_WIDTH; + } + + for (i = 0, linewidth = 0; i < activecount ; i++) { + if (inds[i] != -1) { + int spaces = columnwidth - XKB_IND_FORMAT_CHARS + - strlen(iatomnames[i]); + + if (spaces < 0) + spaces = 0; + + linewidth += printf(" %02d: %s: %*s", + inds[i], iatomnames[i], + spaces + 3, + on_or_off(istates[i], + True, "on ", + False, "off", buf)); + } + if (linewidth > (MAX_LINE_WIDTH - columnwidth)) { + printf("\n"); + linewidth = 0; + } + } + if (linewidth > 0) { + printf("\n"); + } + } + } + if (XkbGetControls(dpy, XkbRepeatKeysMask, xkb) == Success) { + printf(" auto repeat delay: %d repeat rate: %d\n", + xkb->ctrls->repeat_delay, + 1000 / xkb->ctrls->repeat_interval); + } + } #ifdef XF86MISC else #endif @@ -1578,6 +1703,10 @@ usage(char *fmt, ...) fprintf(stderr, " To set LED states off or on:\n"); fprintf(stderr, "\t-led [1-32] led off\n"); fprintf(stderr, "\t led [1-32] led on\n"); +#ifdef XKB + fprintf(stderr, "\t-led named 'name' led off\n"); + fprintf(stderr, "\t led named 'name' led on\n"); +#endif fprintf(stderr, " To set mouse acceleration and threshold:\n"); fprintf(stderr, "\t m [acc_mult[/acc_div] [thr]] m default\n"); fprintf(stderr, " To set pixel colors:\n"); |