С использованиемsed

С использованиемsed

Я пытаюсь принудительно включить светодиод CapsLock. xsetУ меня это не работает, поэтому я пытаюсь использовать setleds.

В графической консоли эта команда возвращает:

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

В виртуальном терминале это работает, однако эффект локален для этого виртуального терминала. Насколько я понимаю, запуск

> setleds -L +caps < /dev/tty1

с виртуального терминала (мой X-сервер находится на tty1) должно работать. Однако для этого требуется root-доступ.

Есть ли способ отправить команду на консоль, лежащую в основе X-сервера, будь то с указанного x-сервера или с другого VT, без прав root?

Редактировать: По предложению Марка Плотника и на основе найденного кодаздесь, я написал и скомпилировал следующее:

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

Из того, что написал Жиль xset, я не ожидал, что это сработает, но это работает... в каком-то смысле: оно устанавливает светодиод, но также устанавливает статус capslock. Я не до конца понимаю весь код выше, так что, возможно, я допустил глупую ошибку. Судя по всему, эта строка XChangeKeyboardControl...не меняет поведение программы, а XkbLockModifiersименно она устанавливает светодиод и статус capslock.

решение1

В принципе, вы должны быть в состоянии сделать это с почтеннымxsetкоманда.

xset led named 'Caps Lock'

или xset led 4установить светодиод номер 4, если ваша система не распознает светодиоды по названию.

Однако, это, похоже, не работает надежно. На моем компьютере я могу установить Scroll Lock только таким образом, иЯ не один. Этотпохоже, это вопрос конфигурации XKB.

Следующий обходной путь на уровне пользователя должен сработать (в большинстве случаев):

  1. Извлеките текущую конфигурацию xkb:

    xkbcomp $DISPLAY myconf.xkb
    
  2. Отредактируйте файл myconf.xkb, заменив !allowExplicitна allowExplicitв соответствующих блоках:

    indicator "Caps Lock" {
        allowExplicit;
        whichModState= locked;
        modifiers= Lock;
    };
    indicator "Num Lock" {
        allowExplicit;
        whichModState= locked;
        modifiers= NumLock;
    };
    
  3. Загрузить новый файл

    xkbcomp myconf.xkb $DISPLAY
    

Теперь включение и выключение светодиодов xsetдолжно работать. Согласно отчету об ошибке, вы не сможете выключить светодиоды, когда они должны быть включены (например, если включен CapsLock).

решение2

С использованиемsed

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

После выхода из системы и повторного входа в Caps Lockсистему светодиодом можно управлять без каких-либо rootпривилегий с помощью команд:

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

решение3

Сочетание подхода без корневого каталога @Gilles с идеей полной автоматизации @Serge_Stroobandt.

Чтобы включить контрольCaps Lock,Num Lockи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

Чтобы включить и выключить светодиод:

# 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'

Связанный контент