Linux에서 특정 키보드에 대해서만 키를 다시 매핑하는 방법


18

최근에 교체 된 오른쪽 Alt 키와 Windows 키가 포함 된 Unicomp 키보드를 구입했습니다. 키보드는 lsusb에서 다음과 같이 식별됩니다.

Bus 003 Device 002: ID 17f6:0822 Unicomp, Inc 

커널이 (즉 xmodmap 기반이 아닌) 오른쪽 Alt 키와 Windows 키를 바꾸는 방법이 있습니까? 그래서 모든 응용 프로그램은 원시 키보드 입력을 얻더라도 스왑 된 장소에서 볼 수 있습니다 (xmodmap으로 물건을 바꾸는 것은 그렇게하지 않습니다) ? 이 키보드 하나만 사용할 수있는 방법이 있습니까?


키보드의 일련 번호를 일치시키고 다시 매핑하는 스크립트를 호출하여 udev 로이 작업을 수행 할 수 있다고 생각합니다. 장치를 다시 넣으려면 비슷한 스크립트를 분리해야합니다.

1
@jam 연결된 모든 키보드를 다시 매핑 하시겠습니까? 리눅스가 융통성이 없어서 연결된 모든 (USB) 키보드에 대해 하나의 매핑 테이블 만 관리 할 수 ​​있다고 상상할 수 없습니다.
FUZxxl

@jam 또한 실제 스와핑을 수행하는 방법을 설명 할 수 있다면 정말 도움이 될 것입니다. 나는 이것에 유용한 것을 찾지 못했고 xmodmap 만 사용하고 싶지 않았습니다.
FUZxxl

xmodmap을 사용하고 싶지 않다면, 내가 아는 내용이 너무 구체적이어서 미안합니다. 내가 제안한 방법은 xmodmap을 사용하여 특정 키보드가 연결된 기간 동안 모든 장치의 해당 키에 대한 키 코드를 교환 한 다음 다시 넣는 것입니다. 여러 키보드를 동시에 사용할 것으로 예상하십니까?

@jam Xmodmap을 사용하면 X 서버가 번역되지 않은 키 코드를 클라이언트에 보내기 때문에 X 프로그램은 여전히 ​​잘못된 키 코드를 보게됩니다. 이것은 예를 들어 비디오 게임에 중요합니다. 스캔 코드를 읽는 응용 프로그램으로 인생을 더 복잡하게 만들지 않는 커널 솔루션이 있어야합니다.
FUZxxl

답변:


27

예, XKB를 사용할 수 있습니다. xmodmap과 달리 XKB는 개별 장치의 키를 다시 매핑 할 수 있습니다.

참고 : xkbcomp> 1.2.0이 있는지 확인하십시오.

먼저 다음과 함께 장치를 나열하십시오.

xinput list

다음과 같은 것을 얻을 수 있습니다 :

⎡ Virtual core pointer                      id=2    [master pointer  (3)]
⎜   ↳ Virtual core XTEST pointer                id=4    [slave  pointer  (2)]
⎜   ↳ Wacom Bamboo Pen Pen stylus               id=11   [slave  pointer  (2)]
⎜   ↳ Wacom Bamboo Pen Finger touch             id=12   [slave  pointer  (2)]
⎜   ↳ Logitech USB-PS/2 Optical Mouse           id=13   [slave  pointer  (2)]
⎜   ↳ Wacom Bamboo Pen Pen eraser               id=14   [slave  pointer  (2)]
⎜   ↳ Wacom Bamboo Pen Finger pad               id=15   [slave  pointer  (2)]
⎜   ↳ GASIA USB KB V11                          id=17   [slave  pointer  (2)]
⎣ Virtual core keyboard                     id=3    [master keyboard (2)]
    ↳ Virtual core XTEST keyboard               id=5    [slave  keyboard (3)]
    ↳ Power Button                              id=6    [slave  keyboard (3)]
    ↳ Power Button                              id=7    [slave  keyboard (3)]
    ↳ G19 Gaming Keyboard                       id=8    [slave  keyboard (3)]
    ↳ G19 Gaming Keyboard                       id=9    [slave  keyboard (3)]
    ↳ Logitech G19 Gaming Keyboard              id=10   [slave  keyboard (3)]
    ↳ GASIA USB KB V11                          id=16   [slave  keyboard (3)]

장치의 문자열을 식별하고 장치 이름에 맞는 sed 행을 변경하여 다음 쉘 스크립트를 편집하십시오. 그런 다음 재 매핑해야하는 키를 변경하십시오.

예 : xev다시 매핑하려는 키를 로드 하고 누릅니다. https://gist.github.com/zoqaeski/3880640 의 키 코드 84를 찾으십시오 . 키 이름은 <KP5>입니다. 그런 다음 교체하려는 키를 찾아보고 ( 아래 의 같은 링크에서 ) 괄호 안에있는 것을 복사하십시오. 원하는 모든 키에 대해이 과정을 반복하십시오.

remote_id=$(
    xinput list |
    sed -n 's/.*GASIA.*id=\([0-9]*\).*keyboard.*/\1/p'
)
[ "$remote_id" ] || exit

# remap the following keys, only for my custom vintage atari joystick connected
# through an old USB keyboard:
#
# keypad 5 -> keypad 6
# . -> keypad 2
# [ -> keypad 8
# left shift -> left control

mkdir -p /tmp/xkb/symbols
# This is a name for the file, it could be anything you
# want. For us, we'll name it "custom". This is important
# later.
#
# The KP_* come from /usr/include/X11/keysymdef.h
# Also note the name, "remote" is there in the stanza
# definition.
cat >/tmp/xkb/symbols/custom <<\EOF

xkb_symbols "remote" {
    key <KP5>  { [ KP_Right, KP_6, U2192, U21D2 ]       };
    key <I129> { [ KP_Down, KP_2, U2193, U21D3 ]       };
    key <AD12> { [ KP_Up, KP_8, U2191, U21D1 ]  };
    key <LFSH> { [ Control_L ]        };
};
EOF

# (1) We list our current definition
# (2) Modify it to have a keyboard mapping using the name
#     we used above, in this case it's the "remote" definition
#     described in the file named "custom" which we specify in
#     this world as "custom(remote)".
# (3) Now we take that as input back into our definition of the
#     keyboard. This includes the file we just made, read in last,
#     so as to override any prior definitions.  Importantly we 
#     need to include the directory of the place we placed the file
#     to be considered when reading things in.
#
# Also notice that we aren't including exactly the 
# directory we specified above. In this case, it will be looking
# for a directory structure similar to /usr/share/X11/xkb
# 
# What we provided was a "symbols" file. That's why above we put
# the file into a "symbols" directory, which is not being included
# below.
setxkbmap -device $remote_id -print \
 | sed 's/\(xkb_symbols.*\)"/\1+custom(remote)"/' \
 | xkbcomp -I/tmp/xkb -i $remote_id -synch - $DISPLAY 2>/dev/null

그런 다음 소스를 지정하십시오 (.xinitrc에 추가 할 수 있음). 다 했어요! 이제 키를 누르면 지정한 장치에 대해서만 원하는 출력이 생성됩니다.

편집 : 최근에 어떤 이유로 든 새로운 구성이 즉시 적용되지 않는 것으로 나타났습니다. 먼저 다른 키보드에서 키를 누른 다음 수정 된 키보드에서 구성된 키를 테스트해야합니다. 왜 이런 일이 발생했는지 모르겠습니다. 어쩌면 일종의 캐시 일 수 있습니다.


이 키보드를 사용하는 컴퓨터로 돌아와서 월요일에 시도해 보겠습니다.
FUZxxl

1
a) sed -n 's/.*G19 Gaming Keyboard.*id=\([0-9]*\).*keyboard.*/\1/p' c) 예, 먼저 $remote_idID 번호로 대체 하여 테스트해야합니다 . 거기에 두 개의 참조가 $remote_id있습니다. 둘 다 변경 했습니까?
Watcom

1
아, 그리고 하드 코딩 된 테스트 할 때 $remote_id, [ "$remote_id" ] || exit그렇지 않으면 아직 구제되지 않을 경우 라인을 주석 처리하십시오 .
Watcom

1
@ stats-hb $9가 작동하지 않습니다 9.
Watcom

1
이것은 나를 위해 작동합니다 lampjs.wordpress.com/2015/06/26/…
usil

6

Google에서 여기에 와서 질문자가 원래 기대했던 것과 더 일치하는 답변을 원하는 다른 사람들을 위해, evdev변경 사항이 모든 응용 프로그램에 적용되도록 레벨 에서 이벤트를 다시 매핑하는 두 가지 방법을 알고 있습니다.

  1. udev는 스캔 코드와 키 코드 간의 매핑을 제어하는 ​​하드웨어 데이터베이스 항목을 수정하기위한 API를 제공합니다. 지침이 포함 된 이 ArchiWiki 페이지 는 X11과 콘솔 입력 모두에서 작동한다고 명시 적으로 말합니다.

    핵심은 /etc/udev/hwdb.d/장치 일치 패턴과 일부 스캔 코드에서 키 코드로 다시 매핑 정의로 구성된 사용자 지정 항목을 만든 다음 systemd-hwdb update데이터베이스를 다시 빌드하고 udevadm trigger재부팅하지 않고 적용하는 것입니다.

  2. WAYLAND이 libinput의 관련 측면을 구성하는 UI를 구현하지 않는 X11의 키보드 서브 시스템과 GNOME 쉘과 웨스턴 같은 주요 WAYLAND의 컴포 지터를 사용하지 않음을 감안할 때, 누군가가 데몬이라는 쓴 evdevremapkeys 로지텍의 G15Daemon 사용자 공간 드라이버와 유사하게 문제를 해결합니다 G15 게임 키보드.

    (재 맵핑하려는 이벤트를 삼키므로 장치에서 수신하는 다른 사람은 볼 수 없으며 uinput사용자 공간에서 커널 레벨 입력 장치를 작성하기 위해 API를 통해 수정 된 이벤트를 생성합니다.)


나는 DuckDuckGo에서 여기에오고 있지만 어쨌든 대답 주셔서 감사합니다 (:
sm4rk0

0

@Watcom 옵션으로 성공하지 못한 사람들을 위해 다음과 같이 새 매핑 파일을 넣으십시오.

xkb_symbols "remote" {
    key <KP5>  { [ KP_Right, KP_6, U2192, U21D2 ]       };
    key <I129> { [ KP_Down, KP_2, U2193, U21D3 ]       };
    key <AD12> { [ KP_Up, KP_8, U2191, U21D1 ]  };
    key <LFSH> { [ Control_L ]        };
};

/ usr / share / X11 / xkb / symbols /에 루트 (우분투, 배포판에 따라 다를 수 있음)로 'custom'파일을 호출하십시오. 현재 레이아웃 문자열을 요청 setxkbmap -device <device id> -print | grep xkb_symbols하고 추가 +custom하십시오. 재 맵핑 된 키와 수정 된 레이아웃 문자열로 새 레이아웃을 설정하십시오.

setxkbmap -device <device id> -layout "us+ru:2+us:3+inet(evdev)+capslock(grouplock)+custom"

다른 키보드가 연결되었을 때 효과는 영구적이지 않으며 불행히도 재설정되지만 아직 수정 방법을 찾지 못했습니다. .bashrc그래도 위의 명령을 추가 할 수 있으므로 필요한 경우 다시 시작할 때 키가 교환됩니다.

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.