vendredi 16 janvier 2015

Change the status of the keyboard leds, from within an X session, without root access


I am trying to force the capslock led on. xset does not work for me, so I am trying to use setleds.


In a graphical console, this command returns:



> LANG=C setleds -L +caps
KDGKBLED: Inappropriate ioctl for device
Error reading current flags setting. Maybe you are not on the console?


In a virtual terminal, it works, however the effect is local to that virtual terminal. From what I understand, running



> setleds -L +caps < /dev/tty1


from a virtual terminal (my X server is sitting on tty1) should work. However, this requires root access.


Is there a way to send a command to the console underlying a X server, be it from the said xserver or from another VT, without root?


Edit: From a suggestion from Mark Plotnik, and based on code found here, I wrote and compiled the following:



#include <X11/Xlib.h>
#include <X11/XKBlib.h>

#define SCROLLLOCK 1
#define CAPSLOCK 2
#define NUMLOCK 16

void setLeds(int leds) {
Display *dpy = XOpenDisplay(0);
XKeyboardControl values;
values.led_mode = leds & SCROLLLOCK ? LedModeOn : LedModeOff;
values.led = 3;
XChangeKeyboardControl(dpy, KBLedMode, &values);
XkbLockModifiers(dpy, XkbUseCoreKbd, CAPSLOCK | NUMLOCK,
leds & (CAPSLOCK | NUMLOCK) );
XFlush(dpy);
XCloseDisplay(dpy);
}

int main() {
setLeds(CAPSLOCK);
return 0;
}


From what Gilles wrote about xset, I did not expect it to work, but it does... in some sense: it sets the led, but it also sets the capslock status. I do not fully understand all the code above, so I may have done a silly mistake. Apparently, the line XChangeKeyboardControl... does not change the behavior of the program, and XkbLockModifiers is what sets the led and the capslock status.



Aucun commentaire:

Enregistrer un commentaire