Зміна стану світлодіодних світлодіодів протягом X сеансу без доступу root


10

Я намагаюсь змусити накладений накладок. 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) має працювати. Однак для цього потрібен кореневий доступ.

Чи є спосіб надіслати команду до консолі, що лежить в основі сервера X, будь то із зазначеного xserver або з іншого VT, без кореня?

Редагувати: із пропозиції Марка Плотника і на основі знайденого тут коду я написав і склав наступне:

#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, я не очікував, що це спрацює, але це є ... в деякому сенсі: він встановлює світлодіод, але він також встановлює статус шапки. Я не повністю розумію весь код вище, тому, можливо, я зробив дурну помилку. Судячи з усього, рядок XChangeKeyboardControl...не змінює поведінку програми, а XkbLockModifiersє тим, що встановлює статус led і caplock.


Ви можете зробити щось на зразок xdotool key Caps_Lockвід авторизованого клієнта X, хоча це насправді увімкне блокування шапки.
Марк Плотнік

@MarkPlotnick Справа справді не в тому, щоб увімкнути CapsLock. Чи є спосіб вимкнути функцію CapsLock, не торкаючись світлодіода?
Т. Веррон

Я подивився на xtermджерело, і воно використовує виклик XChangeKeyboardControl () для встановлення або зняття індикаторів світлодіодів, не впливаючи на стан блокування ковпачків і т. Д. Тож якщо ви можете скласти код C, це один підхід.
Марк Плотнік

@MarkPlotnick Чи xtermвпливає на світлодіоди? Це звучить як гарна ідея, я відредагую питання своїми результатами.
Т. Веррон

Мені xtermдовелося засвітити світлодіод ScrollLock, надіславши послідовність ESC [3 q, відповідно до файлу, ctlseqs.txtщо постачається з джерелом, але не вдалося засвітити світлодіоди Num або CapsLock з параметрами 1 і 2. Можливо, мені потрібно виконайте конфігурацію XKB, згадану у відповіді. xtermдзвінки XChangeKeyboardControlв xtermShowLEDі xtermClearLEDs, але не викликає XkbLockModifiersвзагалі ніде.
Марк Плотнік

Відповіді:


7

В принципі, ви повинні вміти робити це з поважною xsetкомандою.

xset led named 'Caps Lock'

або xset led 4встановити світлодіодний номер 4, якщо ваша система не розпізнає світлодіоди по імені.

Однак, схоже, це не працює надійно. На своїй машині я можу встановити лише Блокування прокрутки таким чином, і я не єдиний . Це , здається, питання конфігурації 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 увімкнено).


Дякую! Я раніше пробував xset, і справді це не працює. Я не бачив цього звіту про помилку. У будь-якому випадку, "Статус: Розв’язаний Wontfix" насправді не підбадьорює ... Навряд чи allowExplicitдля мене працюватимуть (мені не потрібно вимикати світлодіод), але для його зміни все одно потрібен корінь.
Т. Веррон

@ T.Verron Вам не потрібно мати root, щоб змінити конфігурацію XKB. Ви можете зателефонувати xkbcompв будь-який час. Я недостатньо знайомий з XKB, щоб точно сказати, що потрібно змінити (встановлення конкретного аспекту, а не повна заздалегідь визначена карта з XKB - це біль), але unix.stackexchange.com/questions/166844/mapping -пов’язання ключів /… повинно мати кілька покажчиків.
Жил "ТАК - перестань бути злим"

О, хороший пункт. Ну, як перша спроба, я спробував: xkbcomp $DISPLAY output.xkb, а потім замінити !allowExplicitна allowExplicitв indicator "Caps Lock"секції, потім завантажити файл з xkbcomp output.xkb. Існує багато попереджень, і xset згодом не працює. Я прочитаю ще трохи про xkb.
Т. Веррон

1
Цей вид працював для мене. Після імпорту модифікованого файлу я отримав кілька повідомлень про помилки, і я міг засвітити світлодіоди, але інші речі зіпсувались, плюс він не пережив перезавантаження. Тому я пішов вперед відредагованим /usr/share/X11/xkb/compat/ledcapsі ... / lednum, і це зробило його постійним.
jtgd

0

Використання 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'

Але для цього потрібен корінь.
Т. Веррон

@ T.Verron Тільки один раз, щоб змінити файл конфігурації, sudoа потім більше ніколи. Щоб зрозуміти, чому це може бути таким важливим для певних користувачів, перегляньте цю vimпрограму .
Серж Стротобандт

Будучи тим, хто поставив це питання 3 роки тому, я точно розумію, чому це може бути важливо для деяких користувачів (у моєму випадку, це було обійтися над дурними затримками яблучних клавіатур, коли активувати caplock, після перезавантаження капсулу для управління). Але тоді мені спеціально було потрібно рішення без жодного доступу до кореня, оскільки це було для робочого комп'ютера. Прийнята відповідь передбачає ще кілька кроків, але це працює без судо.
Т. Веррон

@ T.Verron Я розумію. Спільні системи - ще один випадок, коли це не працює. Незважаючи на це, мені сподобалася прямолінійність останнього коментатора щодо прийнятої відповіді, і я зробив з неї sedоднолінійку.
Серж Стротобандт

0

Поєднання безкореневого підходу від @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'
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.