Modifica lo stato dei led della tastiera, da una sessione X, senza accesso root


10

Sto cercando di forzare l'accensione del capslock. xsetnon funziona per me, quindi sto cercando di utilizzare setleds.

In una console grafica, questo comando restituisce:

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

In un terminale virtuale, funziona, tuttavia l'effetto è locale per quel terminale virtuale. Da quello che ho capito, correndo

> setleds -L +caps < /dev/tty1

da un terminale virtuale (il mio server X è seduto su tty1) dovrebbe funzionare. Tuttavia, questo richiede l'accesso come root.

C'è un modo per inviare un comando alla console sottostante un server X, sia da detto xserver o da un altro VT, senza root?

Modifica: da un suggerimento di Mark Plotnik e sulla base del codice trovato qui , ho scritto e compilato quanto segue:

#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;
}

Da quanto ha scritto Gilles xset, non mi aspettavo che funzionasse, ma in un certo senso ... imposta il led, ma imposta anche lo stato del capslock. Non capisco completamente tutto il codice sopra, quindi potrei aver fatto un errore sciocco. Apparentemente, la linea XChangeKeyboardControl...non cambia il comportamento del programma, ed XkbLockModifiersè ciò che imposta lo stato del led e del capslock.


Puoi fare qualcosa di simile xdotool key Caps_Locka un client X autorizzato, anche se questo in realtà attiva il blocco maiuscole.
Mark Plotnick,

@MarkPlotnick Il punto è davvero non attivare CapsLock. C'è un modo per disattivare CapsLock, senza toccare il led?
T. Verron,

Ho guardato l' xtermorigine e utilizza una chiamata a XChangeKeyboardControl () per impostare o annullare l' impostazione dei LED senza influire sullo stato del blocco maiuscole ecc. Quindi, se è possibile compilare il codice C, questo è un approccio.
Mark Plotnick,

@MarkPlotnick Influisce xtermsui led? Sembra una buona idea, modificherò la domanda con i miei risultati.
T. Verron,

Devo xtermaccendere il LED ScrollLock inviando la sequenza di escape ESC [3 q, come per il file ctlseqs.txtfornito con la sorgente, ma non riesco a far accendere i LED Num o CapsLock con i parametri 1 e 2. Forse dovrei fai la configurazione XKB menzionata nella risposta. xtermchiamate XChangeKeyboardControlin xtermShowLEDe xtermClearLEDs, ma non chiama XkbLockModifiersovunque a tutti.
Mark Plotnick,

Risposte:


7

In linea di principio, dovresti essere in grado di farlo con il venerabile xsetcomando.

xset led named 'Caps Lock'

o xset led 4per impostare il LED numero 4, se il sistema non riconosce i LED per nome.

Tuttavia, questo non sembra funzionare in modo affidabile. Sulla mia macchina, posso solo impostare Scroll Lock in questo modo, e non sono l'unico . Questa sembra essere una questione di configurazione XKB .

Il seguente work-around a livello di utente dovrebbe funzionare (per la maggior parte):

  1. Estrai la tua attuale configurazione xkb:

    xkbcomp $DISPLAY myconf.xkb
    
  2. Modifica il file myconf.xkb, sostituendolo !allowExplicitcon allowExplicitnei relativi blocchi:

    indicator "Caps Lock" {
        allowExplicit;
        whichModState= locked;
        modifiers= Lock;
    };
    indicator "Num Lock" {
        allowExplicit;
        whichModState= locked;
        modifiers= NumLock;
    };
    
  3. Carica il nuovo file

    xkbcomp myconf.xkb $DISPLAY
    

Ora accendendo e spegnendo i LED xsetdovrebbe funzionare. Secondo la segnalazione di bug, non sarà possibile spegnere i led quando dovrebbero essere accesi (ad esempio se CapsLock è abilitato).


Grazie! Ci avevo provato xsetprima, e in effetti non funziona. Non avevo visto questa segnalazione di bug però. Ad ogni modo, "Stato: risolto Wontfix" non è davvero incoraggiante ... Il rimedio allowExplicitavrebbe probabilmente funzionato per me (non ho bisogno di spegnere il led), ma cambiarlo richiede comunque root.
T. Verron,

@ T.Verron Non è necessario essere root per modificare la configurazione XKB. Puoi chiamare xkbcompin qualsiasi momento. Non ho abbastanza familiarità con XKB per dirti esattamente cosa devi cambiare (impostare un aspetto specifico piuttosto che una mappa predefinita completa con XKB è un po 'una seccatura), ma unix.stackexchange.com/questions/166844/mapping -key-bindings / ... dovrebbe avere alcuni puntatori.
Gilles 'SO- smetti di essere malvagio' il

Oh, buon punto. Ebbene, come un primo tentativo, ho provato: xkbcomp $DISPLAY output.xkb, poi sostituendo !allowExplicitda allowExplicitnella indicator "Caps Lock"sezione, quindi ricaricare il file con xkbcomp output.xkb. Ci sono molti avvertimenti e xset non funziona meglio dopo. Leggerò qualcosa in più su xkb.
T. Verron,

1
Questo tipo di lavoro ha funzionato per me. Dopo aver importato il file modificato, ho ricevuto alcuni messaggi di errore e ho potuto accendere i LED, ma altre cose si sono incasinate, inoltre non è sopravvissuto al riavvio. Quindi sono andato avanti con un montaggio /usr/share/X11/xkb/compat/ledcapse ... / lednum e questo lo ha reso permanente.
jtgd,

0

utilizzando sed

$ sudo sed -i 's|\!allowExplicit|allowExplicit|g' /usr/share/X11/xkb/compat/ledcaps

Dopo essersi disconnesso e riconnesso, Caps Lockora è possibile controllare il LED senza rootprivilegi utilizzando i comandi:

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

Ma questo richiede root.
T. Verron,

@ T.Verron Solo una volta per modificare un file di configurazione con sudoe poi mai più. Per capire perché questo potrebbe essere così importante per alcuni utenti, vedi questa vimapplicazione .
Serge Stroobandt,

Essendo quello che ha posto la domanda 3 anni fa, capisco sicuramente perché può essere importante per alcuni utenti (nel mio caso, è stato per aggirare lo stupido ritardo che hanno le tastiere Apple quando si attiva il maiuscolo, dopo aver rimappato il maiuscolo per controllarlo). Ma allora, avevo specificamente bisogno di una soluzione senza alcun accesso root, perché era per un computer di lavoro. La risposta accettata prevede alcuni altri passaggi, ma funziona senza sudo.
T. Verron,

@ T.Verron ho capito. I sistemi condivisi sono un altro caso in cui questo non funzionerebbe. Nonostante ciò, mi è piaciuta la semplicità dell'ultimo commentatore sulla risposta accettata e ne ho ricavato una sedsola riga.
Serge Stroobandt,

0

Una combinazione dell'approccio senza radici di @Gilles con l'idea di automazione completa di @Serge_Stroobandt.

Per abilitare il controllo dei LED BLOC MAIUSC , BLOC NUM e BLOC MAIUSC :

#!/bin/bash
# Enables to control keyboard LEDs that are not available for control by default
xkbcomp $DISPLAY /tmp/my_conf.xkb
cat /tmp/my_conf.xkb | awk -e '
    BEGIN {
        change = 0
    }

    {
        if (change == 1) {
            if ($1 == "!allowExplicit;") {
                gsub("!", "", $0)
            }
            change = 0
        }
        print $0

    }

    /indicator "Caps Lock"/ {
        change = 1
    }
    /indicator "Num Lock"/ {
        change = 1
    }
    /indicator "Shift Lock"/ {
        change = 1
    }
    ' > /tmp/my_conf_modified.xkb
xkbcomp /tmp/my_conf_modified.xkb $DISPLAY

Per accendere e spegnere un LED:

# Turns the LED on
xset led named 'Caps Lock'

# wait 1s
sleep 1

# Resets the LED to the actual state,
# so it might still be on, if Caps Lock is activated.
xset -led named 'Caps Lock'
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.