Neveikia xset led

T
Techtronic
Mindaugas N.
  • 5 Vas '14

Sveiki, senokai pastebejau sia problema, ir atrdo kad neveikia ne tik man vienam.
Komanda xset -q parodo visu LED state, taip pat galima on/off ledus:

xset led named 'Caps Lock'
xset -led named 'Caps Lock'

Bet neveikia.. Gal kas turi ideju kaip kontroliuoti siuos LED'us keyboard'o ?
Esu pradejas kurti savo programele kuri tai darytu:

#include <X11/Xlib.h>
#include <X11/Xutil.h>
#include <X11/Xresource.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

static void xkbset_led(Display *dpy, const char *led, int led_mode) {
  int xkbmajor = XkbMajorVersion;
  int 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,"Invalid led name: %s\n", led);
        }
    } else {
        printf("  Server does not have the XKB Extension\n");
    }
    return;
}

int main(int argc, char ** argv){
  int screen_num, width, height;
  unsigned long background, border;
  Window win;
  XEvent ev;
  Display *dpy;

  /* First connect to the display server */
  dpy = XOpenDisplay(NULL);
  if (!dpy) {fprintf(stderr, "unable to connect to displayn");return 7;}

  xkbset_led(dpy, '11', 'OFF');
  return 0;
}

Bet kaip suprantu tai toks pat metodas kuri naudoja xset'as, tai turbut nera reikalo toliau kurti toki toolsa.

E
  • 11 Vas '14

Neina tiesiog /sys/class kernelio fs'e junginėti led su echo 1 > /sys/class/kazkas/ledname?
Pas mane laptope per asus-nb firmware galiu kontroliuoti, kas pas tave yra per klasė nežinau. Panaršyk po aplanką gal atrasi ką nors.
Šiaip pasižiūrėk dar ```

<linux/leds.h>
``` biblioteką. Kernelis tiesiogiai tokius dalykus geriau valdo ne X'ai.

T
Techtronic
Mindaugas N.
  • 11 Vas '14

Taip, apie toki buda jau masciau, bet problema ne linux kernel'i, o Xorg XKB extension'e. As kiek patobulinau ta savaja app kuri dabar atrodo taip:

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

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <stdarg.h>

#define ON 1
#define OFF 0

static void xkbset_led(Display *dpy, const char *led, int led_mode) {
    int xkbmajor = XkbMajorVersion, xkbminor = XkbMinorVersion;
    int xkbopcode, xkbevent, xkberror;
    Atom ledatom;
    if (XkbQueryExtension(dpy, &xkbopcode, &xkbevent, &xkberror, &xkbmajor, &xkbminor)) {
        ledatom = XInternAtom(dpy, led, True);
        printf("Setting %s to %s\n", led, led_mode ? "on" : "off");
        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,"Invalid led name: %s\n", led);
        }
    } else {
        printf("Server does not have the XKB Extension?\n");
    }
    return;
}

int main(int argc, char* argv[]) {
    if (argv[1] && argv[2]) {
        register char *led;
        register char *state;

        XKeyboardControl values;
        Display *dpy;

        led = argv[1];
        state = argv[2];

        dpy = XOpenDisplay(NULL);
        if (dpy == NULL) {
            fprintf(stderr, "cannot connect to X server");
            return 1;
        };

        if (strcmp(state, "on") == 0) {
            values.led_mode = ON;
            xkbset_led(dpy, led, values.led_mode);
        } else if (strcmp(state, "off") == 0) {
            values.led_mode = OFF;
            xkbset_led(dpy, led, values.led_mode);
        } else {
            fprintf(stderr, "Wrong argument: %s\n", state);
            fprintf(stderr, "Usage: LED on|off\n");
            return 1;
        }
    } else {
        fprintf(stderr, "Usage: LED on|off\n"); 
        return 1;
    }
    return 0;
}
g++  -O0 -ggdb -pipe -I/usr/include -lX11 -lXmu -o test xkbd.c

Na ir aisku, neveikia. Radau kita app pavadinimu xsetleds, ji veikia kiek kitaip, bet taip pat naudoja Xlib, tai problema +- ta pati. Gal kada rades daugiau laiko sukompiliuosiu Xorg su debug simboliais ir pameginsiu atrasti kur butent yra klaida.

Mane dabar labiau domintu informacija, ar kam nors xset veikia ?

xset led named 'Caps Lock'
xset -led named 'Caps Lock'