Linux

在 X 會話中更改鍵盤 LED 的狀態,無需 root 訪問

  • December 12, 2018

我正在嘗試強制打開大寫鎖定。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 伺服器底層的控制台發送命令,無論是從上述 xserver 還是從另一個 VT,沒有 root 權限?

編輯:根據 Mark Plotnik 的建議,並根據此處找到的程式碼,我編寫並編譯了以下內容:

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

從 Gilles 所寫的內容來看xset,我沒想到它會起作用,但它確實……在某種意義上:它設置了 LED,但它也設置了大寫鎖定狀態。我沒有完全理解上面的所有程式碼,所以我可能犯了一個愚蠢的錯誤。顯然,該行XChangeKeyboardControl...不會改變程序的行為,XkbLockModifiers而是設置 led 和 capslock 狀態。

原則上,您應該能夠使用 venerablexset命令來執行此操作。

xset led named 'Caps Lock'

xset led 4設置 LED 編號 4,如果您的系統無法按名稱辨識 LED。

但是,這似乎並不可靠。在我的機器上,我只能這樣設置 Scroll Lock,而且我不是唯一一個。這似乎是 XKB 配置的問題

以下使用者級解決方法應該可以工作(大部分情況下):

  1. 提取您目前的 xkb 配置:
xkbcomp $DISPLAY myconf.xkb
  1. 編輯文件,在相關塊中myconf.xkb替換!allowExplicit為:allowExplicit
indicator "Caps Lock" {
   allowExplicit;
   whichModState= locked;
   modifiers= Lock;
};
indicator "Num Lock" {
   allowExplicit;
   whichModState= locked;
   modifiers= NumLock;
};
  1. 載入新文件
xkbcomp myconf.xkb $DISPLAY

現在打開和關閉 LEDxset應該可以工作了。根據錯誤報告,當 LED 應該打開時,您將無法關閉它們(例如,如果 CapsLock 已啟用)。

引用自:https://unix.stackexchange.com/questions/179286