設定游標速度 -- ThinkPad USB 小紅帽鍵盤

最近 (我是 2013 年 11月買的),聯想 (Lenovo) 出的 USB 小紅帽鍵盤改版了,名稱也有稍許差異 -- ThinkPad Compact USB Keyboard with TrackPoint。更進一步,控制的驅動程式也變了,只好再重新找出控制的方法。新版的控制項目只剩「指標速度」和「ThinkPad 首選滾動」選項,中國製造,真是讓人覺得不可靠,從 IBM 接手過來後,功能越做越少。「ThinkPad 首選滾動」是什麼功用,不太清楚,應該可以用 xinput 來設定,就不管它了。前一版的控制項目是指標的靈敏度,新的是「指標速度」,不曉得是否同樣能夠讓我輕鬆推動小紅帽。

使用的分析工具是 USBlyzer - USB Protocol Analyzer and USB Traffic Sniffer (2.0 Build 23)。在 Vmare 的 VM 中裝 Windows XP,然後在 USB 控制器項目,勾選 "Show all USB input devices"。如此可以讓小紅點鍵盤給 VM 獨佔,才能由驅動程式控制速度。

裝好 XP 後,要下載及安裝驅動程式,請注意產品名稱,比以前多了 Compact 的字眼。再來,下載 USBlyzer,或其他 USB 的開發工具,裝好後,就可以開始進行追蹤的工作了。

透過程式收集到的相關裝置資料如下

Device Descriptor: ThinkPad Compact USB Keyboard with TrackPoint

idVendor: 17EFh (Lenovo)

idProduct: 6047h

bcdDevice: 3.00

iManufacturer: "Lenovo"

iProduct: "ThinkPad Compact USB Keyboard with TrackPoint"

透過 USBlyzer 擷取到的控制資料如下

Request : Class Interface

Request Details: Set Report (Feature id:19 len:9)

Device Object: 8609BE18h

Device Name: 000000a2

Driver Name: usbccgp

IRP: 862D3E00h

控制資料在 Raw Data 中,「指標速度」的控制資料為 (有 9 種變化)

13 02 09 00 00 00 00 00 (最快 fastest)

13 02 01 00 00 00 00 00 (最慢 slowest)

「ThinkPad 首選滾動」的控制資料為

13 09 01 00 00 00 00 00 (ON)

13 09 00 00 00 00 00 00 (OFF)

擷取到控制資料,但要用 pysub 來控制,控制指令不想得如何下。透過 Google 搜尋到可以用 usbmon 來擷取資料,擷取到的資料如下

ce199600 1.779302 C Co:1:007:0 0 9 >
cfd7c180 2.780328 S Co:1:007:0 s 21 09 0313 0001 0009 9 =
    13020800 00000000 00
cfd7c180 2.780575 C Co:1:007:0 0 9 >
cfd7c180 2.781443 S Co:1:007:0 s 21 09 0313 0001 0009 9 =
    13010300 00000000 00
cfd7c180 2.781701 C Co:1:007:0 0 9 >
ce199900 2.904609 S Co:1:007:0 s 21 09 0313 0001 0009 9 =
    13090000 00000000 00

可以看到 "=" 之後是控制參數 (Raw Data) "13020800 00000000 00",在 "=" 之前就是控制指令的參數 "21 09 0313 0001"。最後的 "0009 9" 代表 data 和 data 的長度。

接下來,要使用 pysub 來控制游標的速度和敏感度 (sensitivity)。程式 trackpoint-script.py 如下

#pyusb imports
import usb.core
import usb.util
# speed value
speed = 0x09
# 13020900 00000000 00
speed_dat = [0x13, 0x02, speed, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00]
# sensitivity value
sens_dat = [0x4, 0x6a, 0x3, 0xfc, 0x38]
dev = usb.core.find(idVendor=0x17ef, idProduct=0x6009)
# 21 09 0313 0001
dev.ctrl_transfer(0x21, 0x09, 0x0313, 0x01, speed_dat)
dev.ctrl_transfer(0x21, 0x9, 0x304, 0x1, sens_dat)

上面的 script,在 Mac OS X 下,可以直接用,但在 Linux 下,必需將裝置 unbind 之後,才能進行控制。關於 bind/unbind 的說明,請參考 Manual driver binding and unbinding

要 unbind 裝置,必須找出它的編號,這編號會隨連接的 USB port 改變。

用指令 dmesg | grep -i thinkpad 得到結果如下

input: Lenovo ThinkPad Compact USB Keyboard with TrackPoint as /d

evices/pci0000:00/0000:00:1a.0/usb1/1-1/1-1.5/1-1.5:1.1/input/input3

再用 tree /sys/bus/usb/drivers/usbhid 得到結果如下

/sys/bus/usb/drivers/usbhid

├── 1-1.5:1.0 -> ../../../../devices/pci0000:00/0000:00:1a.0/usb1/1-1/1-1.5/1-1.5:1.0

├── 1-1.5:1.1 -> ../../../../devices/pci0000:00/0000:00:1a.0/usb1/1-1/1-1.5/1-1.5:1.1

├── 1-1.6:1.0 -> ../../../../devices/pci0000:00/0000:00:1a.0/usb1/1-1/1-1.6/1-1.6:1.0

├── 1-1.6:1.1 -> ../../../../devices/pci0000:00/0000:00:1a.0/usb1/1-1/1-1.6/1-1.6:1.1

├── 1-1.6:1.2 -> ../../../../devices/pci0000:00/0000:00:1a.0/usb1/1-1/1-1.6/1-1.6:1.2

完成控制用的 shell 程式 set-trackpoint 如下

echo 1-1.5:1.1 > /sys/bus/usb/drivers/usbhid/unbind
python trackpoint-script.py
echo 1-1.5:1.1 > /sys/bus/usb/drivers/usbhid/bind

執行 sudo sh set-trackpoint 即可控制游標的速度。