Altera o status dos leds do teclado, dentro de uma sessão X, sem acesso root

9

Estou tentando forçar o capslock ligado. xset não funciona para mim, então estou tentando usar setleds .

Em um console gráfico, este comando retorna:

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

Em um terminal virtual, ele funciona, no entanto, o efeito é local para esse terminal virtual. Pelo que entendi, executando

> setleds -L +caps < /dev/tty1

de um terminal virtual (meu servidor X está sentado no tty1) deve funcionar. No entanto, isso requer acesso root.

Existe uma maneira de enviar um comando para o console subjacente a um servidor X, seja do referido xserver ou de outro VT, sem raiz?

Edit: De uma sugestão de Mark Plotnik, e com base no código encontrado aqui , eu escrevi e compilei o seguinte:

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

Pelo que Gilles escreveu sobre xset , eu não esperava que funcionasse, mas em algum sentido: ele define o led, mas também define o status de capslock. Eu não entendo completamente todo o código acima, então posso ter cometido um erro bobo. Aparentemente, a linha XChangeKeyboardControl... não altera o comportamento do programa e XkbLockModifiers é o que define o status do led e do capslock.

    
por T. Verron 15.01.2015 / 16:57

3 respostas

7

Em princípio, você deve ser capaz de fazer isso com o venerável Comando xset .

xset led named 'Caps Lock'

ou xset led 4 para definir o número de LED 4, se o seu sistema não reconhecer os LEDs pelo nome.

No entanto, isso não parece funcionar de forma confiável. Na minha máquina, só posso configurar o Scroll Lock dessa maneira, e Eu não sou o único . Este parece ser uma questão de configuração do XKB .

A solução a seguir no nível do usuário deve funcionar (na maior parte):

  1. Extraia sua configuração atual do xkb:

    xkbcomp $DISPLAY myconf.xkb
    
  2. Edite o arquivo myconf.xkb , substituindo !allowExplicit por allowExplicit nos blocos relevantes:

    indicator "Caps Lock" {
        allowExplicit;
        whichModState= locked;
        modifiers= Lock;
    };
    indicator "Num Lock" {
        allowExplicit;
        whichModState= locked;
        modifiers= NumLock;
    };
    
  3. Carregue o novo arquivo

    xkbcomp myconf.xkb $DISPLAY
    

Agora, ativar e desativar os leds com xset deve funcionar. De acordo com o relatório de erros, você não poderá desligar os leds quando eles estiverem ligados (por exemplo, se o CapsLock estiver ativado).

    
por 16.01.2015 / 01:38
0

Usando sed

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

Depois de sair e entrar novamente, o LED Caps Lock agora pode ser controlado sem nenhum privilégio root usando os comandos:

$ xset led named 'Caps Lock'
$ xset -led named 'Caps Lock'
    
por 04.11.2018 / 20:27
0

Uma combinação da abordagem sem raiz de @Gilles com a ideia de automação completa por @Serge_Stroobandt.

Para ativar o controle dos LEDs Caps Lock , Num Lock e Shift Lock :

#!/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

Para ligar e desligar um 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'
    
por 12.12.2018 / 08:58