使用sed

使用sed

CapsLock LED を強制的にオンにしようとしています。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 サーバーまたは別の VT から、X サーバーの基盤となるコンソールにコマンドを送信する方法はありますか?

編集: 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 を設定するだけでなく、CapsLock ステータスも設定します。上記のコード全体を完全に理解しているわけではないので、ばかげた間違いを犯した可能性があります。どうやら、この行はXChangeKeyboardControl...プログラムの動作を変更せず、XkbLockModifiersLED と CapsLock ステータスを設定するものなのです。

答え1

原則的には、由緒あるxset指示。

xset led named 'Caps Lock'

またはxset led 4、システムが LED を名前で認識しない場合は、LED 番号 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
    

これで、 LED のオン/オフ設定がxset機能するはずです。バグレポートによると、LED がオンになっているはずのときにオフに切り替えることはできません (たとえば、CapsLock が有効になっている場合)。

答え2

使用sed

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

ログアウトして再度ログインすると、次のコマンドを使用して権限Caps Lockなしで LED を制御できるようになります。root

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

答え3

@Gilles によるルートレス アプローチと @Serge_Stroobandt による完全自動化のアイデアを組み合わせたものです。

制御を可能にするためにキャップスロックナンロックそしてシフトロックLED:

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

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'

関連情報