I'm currently trying to get buttons on my graphics tablet to be picked up as keycodes.
Since more programs support keyboard shortcuts than extra mouse buttons (e.g. Krita only seems to support left-click and right-click), I want to be able to have the tablet buttons treated as keycodes so I can assign them shortcuts in different programs.
## What I've Done so Far
I created a udev hwdb file (
/etc/udev/hwdb.d/90-huion.hwdb
) to map the tablet's scancodes to keycodes.
My hwdb file look like this:
evdev:input:b0003v256Cp006Ee0111*
KEYBOARD_KEY_90001=a
KEYBOARD_KEY_90002=a
KEYBOARD_KEY_90003=a
KEYBOARD_KEY_90004=a
KEYBOARD_KEY_90005=a
KEYBOARD_KEY_90006=a
KEYBOARD_KEY_90007=a
KEYBOARD_KEY_90008=a
KEYBOARD_KEY_90009=a
KEYBOARD_KEY_9000a=a
MANUAL_OVERRIDE=1
> The search portion used the values I found for event23 here:
>
> > cat /sys/class/input/event23/device/id/bustype
> > 0003
> cat /sys/class/input/event23/device/id/product
> > 006e
> cat /sys/class/input/event23/device/id/vendor
> > 256c
> cat /sys/class/input/event23/device/id/version
> > 0111
>
> I can't map based on the device's name since it has a colon (HID 256c:006e Pad),
> and I don't think that name will play nice with the hwdb file that uses colons as separators.
I've loaded this into hwdb.bin
and reloaded and (re)triggered udev rules
sudo systemd-hwdb update
sudo udevadmin trigger
sudo udevadm control --reload
> I've also tried updating the hwdb with the older sudo udevadm hwdb --update
with no difference.
> I've also tried removing and replugging in the tablet.
Using udevadm info
I can see my file is in use (hence the MANUAL_OVERRIDE=1
part that otherwise does nothing).
udevadm info
output:
P: /devices/pci0000:00/0000:00:14.0/usb1/1-2/1-2.1/1-2.1.1/1-2.1.1:1.0/0003:256C:006E.0004/input/input23/event23
N: input/event23
L: 0
S: input/by-id/usb-256c_006e-event-mouse
S: input/by-path/pci-0000:00:14.0-usb-0:2.1.1:1.0-event-mouse
E: DEVPATH=/devices/pci0000:00/0000:00:14.0/usb1/1-2/1-2.1/1-2.1.1/1-2.1.1:1.0/0003:256C:006E.0004/input/input23/event23
E: DEVNAME=/dev/input/event23
E: MAJOR=13
E: MINOR=87
E: SUBSYSTEM=input
E: USEC_INITIALIZED=5852671
E: KEYBOARD_KEY_90001=a
E: KEYBOARD_KEY_90002=a
E: KEYBOARD_KEY_90003=a
E: KEYBOARD_KEY_90004=a
E: KEYBOARD_KEY_90005=a
E: KEYBOARD_KEY_90006=a
E: KEYBOARD_KEY_90007=a
E: KEYBOARD_KEY_90008=a
E: KEYBOARD_KEY_90009=a
E: KEYBOARD_KEY_9000a=a
E: MANUAL_OVERRIDE=1
E: ID_INPUT=1
E: ID_INPUT_TABLET=1
E: ID_INPUT_KEY=1
E: ID_VENDOR=256c
E: ID_VENDOR_ENC=256c
E: ID_VENDOR_ID=256c
E: ID_MODEL=006e
E: ID_MODEL_ENC=006e
E: ID_MODEL_ID=006e
E: ID_REVISION=3000
E: ID_SERIAL=256c_006e
E: ID_TYPE=hid
E: ID_BUS=usb
E: ID_USB_INTERFACES=:030102:
E: ID_USB_INTERFACE_NUM=00
E: ID_USB_DRIVER=usbhid
E: ID_PATH=pci-0000:00:14.0-usb-0:2.1.1:1.0
E: ID_PATH_TAG=pci-0000_00_14_0-usb-0_2_1_1_1_0
E: ID_INPUT_TABLET_PAD=1
E: LIBINPUT_DEVICE_GROUP=3/256c/6e:usb-0000:00:14.0-2.1
E: DEVLINKS=/dev/input/by-id/usb-256c_006e-event-mouse /dev/input/by-path/pci-0000:00:14.0-usb-0:2.1.1:1.0-event-mouse
E: TAGS=:power-switch:aaaaaaaaaa
## Debugging
### Evtest
As far as I know, that should be all that's required to map the tablet's buttons, things even look (mostly) promising with evtest
:
Testing ... (interrupt to exit)
Event: time 1589801905.094479, type 4 (EV_MSC), code 4 (MSC_SCAN), value 90001
Event: time 1589801905.094479, type 1 (EV_KEY), code 30 (KEY_A), value 1
Event: time 1589801905.094479, -------------- SYN_REPORT ------------
Event: time 1589801905.252456, type 4 (EV_MSC), code 4 (MSC_SCAN), value 90001
Event: time 1589801905.252456, type 1 (EV_KEY), code 30 (KEY_A), value 0
Event: time 1589801905.252456, -------------- SYN_REPORT ------------
Event: time 1589801906.960440, type 4 (EV_MSC), code 4 (MSC_SCAN), value 90002
Event: time 1589801906.960440, type 1 (EV_KEY), code 30 (KEY_A), value 1
...
Event: time 1589801913.582373, -------------- SYN_REPORT ------------
Event: time 1589801913.936376, type 4 (EV_MSC), code 4 (MSC_SCAN), value 9000a
Event: time 1589801913.936376, type 1 (EV_KEY), code 30 (KEY_A), value 1
Event: time 1589801913.936376, -------------- SYN_REPORT ------------
Event: time 1589801914.086370, type 4 (EV_MSC), code 4 (MSC_SCAN), value 9000a
Event: time 1589801914.086370, type 1 (EV_KEY), code 30 (KEY_A), value 0
Event: time 1589801914.086370, -------------- SYN_REPORT ------------
Event: time 1589801914.992371, type 4 (EV_MSC), code 4 (MSC_SCAN), value 90001
Event: time 1589801914.992371, type 1 (EV_KEY), code 304 (BTN_SOUTH), value 1
Event: time 1589801914.992371, -------------- SYN_REPORT ------------
Event: time 1589801915.154366, type 4 (EV_MSC), code 4 (MSC_SCAN), value 90001
Event: time 1589801915.154366, type 1 (EV_KEY), code 304 (BTN_SOUTH), value 0
Event: time 1589801915.154366, -------------- SYN_REPORT ------------
Event: time 1589801915.358379, type 4 (EV_MSC), code 4 (MSC_SCAN), value 90002
Event: time 1589801915.358379, type 1 (EV_KEY), code 305 (BTN_EAST), value 1
Event: time 1589801915.358379, -------------- SYN_REPORT ------------
Event: time 1589801915.446357, type 4 (EV_MSC), code 4 (MSC_SCAN), value 90002
Event: time 1589801915.446357, type 1 (EV_KEY), code 305 (BTN_EAST), value 0
Event: time 1589801915.446357, -------------- SYN_REPORT ------------
With the exception of the final two buttons (BTN_SOUTH and BTN_EAST) that don't seem to be mapped (maybe because they have the same scancodes as buttons that are mapped), all the other buttons correctly report code 30 (KEY_A)
(if you have any ideas why these two buttons aren't mapped I'd love to know but it's not the problem I want to focus on right now).
### Xev
Using xev
only the two buttons that didn't seem to be mapped properly are picked up, here is the console output of xev
for those two buttons:
ButtonPress event, serial 34, synthetic NO, window 0x3a00001,
root 0x6bd, subw 0x0, time 8912753, (1,806), root:(971,821),
state 0x0, button 15, same_screen YES
ButtonRelease event, serial 34, synthetic NO, window 0x3a00001,
root 0x6bd, subw 0x0, time 8912953, (1,806), root:(971,821),
state 0x0, button 15, same_screen YES
ButtonPress event, serial 34, synthetic NO, window 0x3a00001,
root 0x6bd, subw 0x0, time 8913377, (1,806), root:(971,821),
state 0x0, button 16, same_screen YES
ButtonRelease event, serial 34, synthetic NO, window 0x3a00001,
root 0x6bd, subw 0x0, time 8913581, (1,806), root:(971,821),
state 0x0, button 16, same_screen YES
Before making the hwdb changes, the buttons were being picked up as buttons 1-3 and 8-16 (the unmapped buttons 15 and 16 are buttons BTN_SOUTH and BTN_EAST respectfully in the output of evtest
), but now xev
isn't seeing most of them (only the unmapped 15 and 16).
### Dmesg
Using sudo dmesg --follow
I don't see any events that look like unknown keypresses.
### Evemenu
The output of evemu-describe
before the hwdb changes:
# EVEMU 1.3
# Kernel: 5.7.0-1-MANJARO
# DMI: dmi:bvnAmericanMegatrendsInc.:bvr1205:bd05/11/2018:svnSystemmanufacturer:pnSystemProductName:pvrSystemVersion:rvnASUSTeKCOMPUTERINC.:rnPRIMEZ270-P:rvrRevX.0x:cvnDefaultstring:ct3:cvrDefaultstring:
# Input device name: "HID 256c:006e Pad"
# Input device ID: bus 0x03 vendor 0x256c product 0x6e version 0x111
# Supported events:
# Event type 0 (EV_SYN)
# Event code 0 (SYN_REPORT)
# Event code 1 (SYN_CONFIG)
# Event code 2 (SYN_MT_REPORT)
# Event code 3 (SYN_DROPPED)
# Event code 4 ((null))
# Event code 5 ((null))
# Event code 6 ((null))
# Event code 7 ((null))
# Event code 8 ((null))
# Event code 9 ((null))
# Event code 10 ((null))
# Event code 11 ((null))
# Event code 12 ((null))
# Event code 13 ((null))
# Event code 14 ((null))
# Event code 15 (SYN_MAX)
# Event type 1 (EV_KEY)
# Event code 256 (BTN_0)
# Event code 257 (BTN_1)
# Event code 258 (BTN_2)
# Event code 259 (BTN_3)
# Event code 260 (BTN_4)
# Event code 261 (BTN_5)
# Event code 262 (BTN_6)
# Event code 263 (BTN_7)
# Event code 264 (BTN_8)
# Event code 265 (BTN_9)
# Event code 304 (BTN_SOUTH)
# Event code 305 (BTN_EAST)
# Event code 306 (BTN_C)
# Event code 331 (BTN_STYLUS)
# Event type 3 (EV_ABS)
# Event code 0 (ABS_X)
# Value 0
# Min 0
# Max 1
# Fuzz 0
# Flat 0
# Resolution 0
# Event code 1 (ABS_Y)
# Value 0
# Min 0
# Max 1
# Fuzz 0
# Flat 0
# Resolution 0
# Event type 4 (EV_MSC)
# Event code 4 (MSC_SCAN)
# Properties:
N: HID 256c:006e Pad
I: 0003 256c 006e 0111
...
And after:
# EVEMU 1.3
# Kernel: 5.7.0-1-MANJARO
# DMI: dmi:bvnAmericanMegatrendsInc.:bvr1205:bd05/11/2018:svnSystemmanufacturer:pnSystemProductName:pvrSystemVersion:rvnASUSTeKCOMPUTERINC.:rnPRIMEZ270-P:rvrRevX.0x:cvnDefaultstring:ct3:cvrDefaultstring:
# Input device name: "HID 256c:006e Pad"
# Input device ID: bus 0x03 vendor 0x256c product 0x6e version 0x111
# Supported events:
# Event type 0 (EV_SYN)
# Event code 0 (SYN_REPORT)
# Event code 1 (SYN_CONFIG)
# Event code 2 (SYN_MT_REPORT)
# Event code 3 (SYN_DROPPED)
# Event code 4 ((null))
# Event code 5 ((null))
# Event code 6 ((null))
# Event code 7 ((null))
# Event code 8 ((null))
# Event code 9 ((null))
# Event code 10 ((null))
# Event code 11 ((null))
# Event code 12 ((null))
# Event code 13 ((null))
# Event code 14 ((null))
# Event code 15 (SYN_MAX)
# Event type 1 (EV_KEY)
# Event code 30 (KEY_A)
# Event code 256 (BTN_0)
# Event code 304 (BTN_SOUTH)
# Event code 305 (BTN_EAST)
# Event code 306 (BTN_C)
# Event code 331 (BTN_STYLUS)
# Event type 3 (EV_ABS)
# Event code 0 (ABS_X)
# Value 0
# Min 0
# Max 1
# Fuzz 0
# Flat 0
# Resolution 0
# Event code 1 (ABS_Y)
# Value 0
# Min 0
# Max 1
# Fuzz 0
# Flat 0
# Resolution 0
# Event type 4 (EV_MSC)
# Event code 4 (MSC_SCAN)
# Properties:
N: HID 256c:006e Pad
I: 0003 256c 006e 0111
...
### Trying Different Devices
In order to check if I did something wrong, I tried a very similar thing with my USB mouse (I didn't map scancode 90001 since that was left click). My mouse was picked up by xev
and when I right-click or scroll I get the letter "a" as I expect (so if you see any stray letter a's in the question that's why).
I compared the output of xev
on my keyboard and mouse:
#### Xev with Keyboard (no mapping)
KeyPress event, serial 34, synthetic NO, window 0x3a00001,
root 0x6bd, subw 0x0, time 4209087, (-1,721), root:(969,736),
state 0x0, keycode 38 (keysym 0x61, a), same_screen YES,
XLookupString gives 1 bytes: (61) "a"
XmbLookupString gives 1 bytes: (61) "a"
XFilterEvent returns: False
KeyRelease event, serial 34, synthetic NO, window 0x3a00001,
root 0x6bd, subw 0x0, time 4209151, (-1,721), root:(969,736),
state 0x0, keycode 38 (keysym 0x61, a), same_screen YES,
XLookupString gives 1 bytes: (61) "a"
XFilterEvent returns: False
#### Xev with Mouse (buttons mapped to "a")
MappingNotify event, serial 34, synthetic NO, window 0x0,
request MappingKeyboard, first_keycode 8, count 248
KeyPress event, serial 34, synthetic NO, window 0x3a00001,
root 0x6bd, subw 0x0, time 4211519, (-1,721), root:(969,736),
state 0x0, keycode 38 (keysym 0x61, a), same_screen YES,
XLookupString gives 1 bytes: (61) "a"
XmbLookupString gives 1 bytes: (61) "a"
XFilterEvent returns: False
KeyRelease event, serial 35, synthetic NO, window 0x3a00001,
root 0x6bd, subw 0x0, time 4211679, (-1,721), root:(969,736),
state 0x0, keycode 38 (keysym 0x61, a), same_screen YES,
XLookupString gives 1 bytes: (61) "a"
XFilterEvent returns: False
## The Device
The tablet in question is a "Huion New 1060Plus"
I installed digimend-kernel-drivers-dkms-git
and I think my tablet is using the evdev driver (I don't have the alternative wacom driver installed xf86-input-wacom
, but I have libwacom
installed because it's used by libinput
and gnome-settings-daemon
).
Other than my problem with the buttons the tablet works fine, including pen pressure.
## Guides Used
I've followed guides mainly from the following sources:
- https://wiki.archlinux.org/index.php/Map_scancodes_to_keycodes
- https://askubuntu.com/questions/1145057/remapping-mouse-buttons-to-keyboard-keys
- http://who-t.blogspot.com/2019/02/adding-entries-to-udev-hwdb.html
Asked by Jonathan Cowling
(121 rep)
May 18, 2020, 02:42 PM