In principle, yes. When I last did this in 2012, the way to go was to try and tell Linux that the second keyboard is very weird and really means XF86VolumeUp when it sends the keypress for Num 1, or whatever. Fortunately, there's quite a few keycodes that don't exist on standard keyboards that you can use in this way.
Let's run through this for a single key:
- use
xev | grep -i key to find the keycodes of the keys on your extra keyboard. I'll just do keypap 9, as an example, with keycode 81. (NB: my extra keypad has a key labeled "00" but that sends "0" twice, I have no idea how to handle that.)
KeyPress event, serial 38, synthetic NO, window 0x4400001,
state 0x10, keycode 81 (keysym 0xffb9, KP_9), same_screen YES,
KeyRelease event, serial 39, synthetic NO, window 0x4400001,
state 0x10, keycode 81 (keysym 0xffb9, KP_9), same_screen YES,
request MappingKeyboard, first_keycode 8, count 248
- check
setxkbmap -query for the rules of your (main) keyboard. We'll try to turn your extra keyboard into a dozen or so media keys on that layout. For me, it's
rules: evdev
model: pc105
layout: de
variant: nodeadkeys
- find enough entries in
/usr/share/X11/xkb/symbols/inet. The right-hand side is what the application will see, possibly with shift key modifiers etc., the left-hand side are scancodes. I'll pick this one, because my keyboard doesn't have a "calculator" key:
key <I148> { [ XF86Calculator ] };
- create a file in
/usr/share/X11/xkb/keycodes/ that maps scancodes to keycodes (from the first step). Yes, this seems backwards. My file is named trustkeypad and looks like this:
default xkb_keycodes "trustkeypad" {
minimum= 8;
maximum= 255;
// keypad 9
<I148> = 81;
};
Warning! Multiple definitions of keycodes
Using command line, ignoring rules file
Applied rules from evdev:
rules: evdev
model: pc105
layout: de
variant: nodeadkeys
Trying to build keymap using the following components:
keycodes: trustkeypad
types: complete
compat: complete
symbols: pc+de(nodeadkeys)+inet(evdev)
geometry: pc(pc105)
and that looks good, in particular, the keycodes line.
If you run xev now, you should see the new symbols being generated. Alas, I get only a half-victory right now:
KeyPress event, serial 39, synthetic NO, window 0x4600001,
root 0x168, subw 0x0, time 24043275, (1666,897), root:(1670,950),
state 0x10, keycode 81 (keysym 0x1008ff1d, XF86Calculator), same_screen YES,
XLookupString gives 0 bytes:
XmbLookupString gives 0 bytes:
XFilterEvent returns: False
KeyRelease event, serial 39, synthetic NO, window 0x4600001,
root 0x168, subw 0x0, time 24043403, (1666,897), root:(1670,950),
state 0x10, keycode 81 (keysym 0x1008ff1d, XF86Calculator), same_screen YES,
XLookupString gives 0 bytes:
XFilterEvent returns: False
KeyPress event, serial 39, synthetic NO, window 0x4600001,
root 0x168, subw 0x0, time 24043403, (1666,897), root:(1670,950),
state 0x10, keycode 77 (keysym 0x0, NoSymbol), same_screen YES,
XLookupString gives 0 bytes:
XmbLookupString gives 0 bytes:
XFilterEvent returns: False
KeyRelease event, serial 39, synthetic NO, window 0x4600001,
root 0x168, subw 0x0, time 24043411, (1666,897), root:(1670,950),
state 0x10, keycode 77 (keysym 0x0, NoSymbol), same_screen YES,
XLookupString gives 0 bytes:
XFilterEvent returns: False
but after I crashed X a couple of times by accident (do not think that setting the minimum value in the keycodes file higher will help), that went away. Maybe a simple reboot can help at this point. After you're successful, you should only get something like
KeyPress event, serial 38, synthetic NO, window 0x3e00001,
root 0x168, subw 0x0, time 26443862, (930,972), root:(934,1025),
state 0x10, keycode 81 (keysym 0x1008ff1d, XF86Calculator), same_screen YES,
XLookupString gives 0 bytes:
XmbLookupString gives 0 bytes:
XFilterEvent returns: False
KeyRelease event, serial 39, synthetic NO, window 0x3e00001,
root 0x168, subw 0x0, time 26444022, (930,972), root:(934,1025),
state 0x10, keycode 81 (keysym 0x1008ff1d, XF86Calculator), same_screen YES,
XLookupString gives 0 bytes:
XFilterEvent returns: False
and you can verify in your user settings that you can now assign a shortcut to this key, and it will say it's assigned to the Calculator key.
Still missing here: figuring out how to make this the standard setting, also across reboots. This will probably involve looking at udev, and https://help.ubuntu.com/community/Custom%20keyboard%20layout%20definitions might be useful, even though it has an "outdated" tag dating from 2014.