Code Keyboard在BSD下的多媒体快捷键配置

在之前买了个Das Keyboard之后,这回为了在家里用搞了个Code Keyboard。
Code Keyboard自带一堆多媒体键,不过要让这些多媒体键发挥作用还要费些功夫。
刚插上去的时候,多出来一个键盘和一个鼠标设备:

ukbd2: <vendor 0x04d9 USB Keyboard, class 0/0, rev 1.10/1.10, addr 8> on usbus0
ums2: <vendor 0x04d9 USB Keyboard, class 0/0, rev 1.10/1.10, addr 8> on usbus0

作为一个键盘来说,有个鼠标设备还是很奇怪的,所以多半是用来给多媒体键的。Ports Tree里有个uhidd,https://wiki.freebsd.org/uhidd,可以用来处理这些多媒体键对应的hid事件。ukbd驱动不错,我们只要干掉ums驱动就可以了。为了这个,先配置uhidd让他干掉ums自己attach上去:

0x04d9:0x0169:0={
    detach_kernel_driver="NO"
}

0x04d9:0x0169:1={
    detach_kernel_driver="YES"
}

之后跑uhidd -h /dev/ugen0.7 (这里ugen0.7是这个键盘对应的ugen设备,-h启动HID类设备),就会发现/dev底下多了uvhid0。
跑系统自带的usbhidctl -f /dev/uvhid0 -l -a,然后按那些多媒体键,就能看见HID状态变化的事件,例如Volume_Increase从0变到1然后变回去之类。

之后,要让uhidd把这些事件翻译成键盘按键。在配置文件的0x04d9:0x0169:1那段里加一段:

    cc_keymap={
        Play/Pause="0x54"
        Stop="0x5a"
        Volume_Decrement="0x62"
        Volume_Increment="0x63"
        Mute="0x6f"
        Scan_Previous_Track="0x7a"
        Scan_Next_Track="0x7c"
    }

,之后用uhidd -o /dev/ugen0.7重新启动uhidd,然后再跑起一个xev,就会看见有键盘事件进来。-o参数启动Consumer Control类驱动,uhidd会参考cc_keymap映射表来映射那些事件。在uhidd.conf里列出了一些一般不会用的scancode,都可以拿来映射。

之后要把那些keycode映射到X的符号名上。xev收到的是keycode,上面指定的是scancode,映射的时候用xev里收到的。修改.Xmodmap,加上一些:

keycode 92  = XF86AudioPlay
keycode 130 = XF86AudioPrev
keycode 132 = XF86AudioNext
keycode 170 = XF86AudioStop
keycode 189 = XF86AudioLowerVolume
keycode 190 = XF86AudioRaiseVolume
keycode 207 = XF86AudioMute

在跑xmodmap .Xmodmap之后,xev里看见的应该就是类似于XF86AudioMute这样的符号名而不是光keycode了。

最后做一些对应这些符号名的快捷键,例如mpc next之类,就大功告成了……

本来uhidd应该自动启动,不过貌似不靠谱,我在/etc/devd/里加了codekbd.conf:

notify 100 {
    match "system"      "USB";
    match "subsystem"   "DEVICE";
    match "type"        "ATTACH";
    match "vendor"      "0x04d9";
    match "product"     "0x0169";
    action "/usr/local/sbin/uhidd -o /dev/$cdev";
};

这样uhidd就会自动启动了……

PS. 我在学校的Arch上试了一下,音量调整直接就能用……