一、mouse的8 bytes定义
二、keyboard的8 bytes定义
/*键盘发送给PC的数据每次8个字节 data0 data1 data2 data3 data4 data5 data6 data7 定义分别是: data0 -- |--bit0: Left Control是否按下,按下为1 |--bit1: Left Shift 是否按下,按下为1 |--bit2: Left Alt 是否按下,按下为1 |--bit3: Left GUI 是否按下,按下为1 |--bit4: Right Control是否按下,按下为1 |--bit5: Right Shift 是否按下,按下为1 |--bit6: Right Alt 是否按下,按下为1 |--bit7: Right GUI 是否按下,按下为1 data1 -- 保留 data2--data7 -- 普通按键 refer to hid spec 8.3*/
bytes[0]代表组合按键(左右ctrl、alt、shift、win)可以同时全部按下,
bytes[2]~bytes[7]代表普通的按键,最多可以同时按下6个键,
加起来的话总共可以同时按下4+4+6个按键系统能检测出来。
三、usb hid keyboard编码(见HID usage tables Chapter10),只列举部分
四、input子系统编码
在drivers/hid/usbhid/usbkbd.c中定义了一张表
static const unsigned char usb_kbd_keycode[256] = { 0, 0, 0, 0, 30, 48, 46, 32, 18, 33, 34, 35, 23, 36, 37, 38,//0 50, 49, 24, 25, 16, 19, 31, 20, 22, 47, 17, 45, 21, 44, 2, 3,//16 4, 5, 6, 7, 8, 9, 10, 11, 28, 1, 14, 15, 57, 12, 13, 26,//32 27, 43, 43, 39, 40, 41, 51, 52, 53, 58, 59, 60, 61, 62, 63, 64,//48 65, 66, 67, 68, 87, 88, 99, 70,119,110,102,104,111,107,109,106,//64 105,108,103, 69, 98, 55, 74, 78, 96, 79, 80, 81, 75, 76, 77, 71,//80 72, 73, 82, 83, 86,127,116,117,183,184,185,186,187,188,189,190,//96 191,192,193,194,134,138,130,132,128,129,131,137,133,135,136,113,//112 115,114, 0, 0, 0,121, 0, 89, 93,124, 92, 94, 95, 0, 0, 0,//128 122,123, 90, 91, 85, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,//144 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,//160 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,//176 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,//192 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,//208 29, 42, 56,125, 97, 54,100,126,164,166,165,163,161,115,114,113,//224 150,158,159,128,136,177,178,176,142,152,173,140//240-251 };
static void usb_kbd_irq(struct urb *urb) { struct usb_kbd *kbd = urb->context; int i; switch (urb->status) { case 0: /* success */ break; case -ECONNRESET: /* unlink */ case -ENOENT: case -ESHUTDOWN: return; /* -EPIPE: should clear the halt */ default: /* error */ goto resubmit; } /**************************检测组合键********************************************/ /* 1. kbd->new是urb的缓冲区用来存储设备发过来的8个字节 2. (kbd->new[0]>>i) & 1 检测第i位是否为1,如果为1,则上报案件usb_kbd_keycode[i+224] 例如,left control按下(bit0为1)即((kbd->new[0]>>0) & 1 ) = 1,所以上报usbkbd_keycode[0+224] = 29, 其中224代表hid编码,29代表此hid编码对应的input编码, hid code通过usb_kbd_keyboard映射到input code,usb_kbd_keycode[hid code] = input code */ for (i = 0; i < 8; i++) input_report_key(kbd->dev, usb_kbd_keycode[i + 224], (kbd->new[0] >> i) & 1); /**************************检测普通键********************************************/ /* 1. 可以从hid编码表格中看到有意义的hid规范从4(字符a)开始 2. 将kbd->old[i]的值在kbd->new的6个字节中寻找,看是否存在 如果在6个字节的kbd->new中不存在old[i]那么说明old[i]已经被释放了 3. 如果不是新的释放事件,而是原来的键一直处于释放状态,则不会执行下面的操作 说明只会在按键释放瞬间发生按键释放上报事件,而在未按期间不会上报释放事件。 */ for (i = 2; i < 8; i++) { if (kbd->old[i] > 3 && memscan(kbd->new + 2, kbd->old[i], 6) == kbd->new + 8) { if (usb_kbd_keycode[kbd->old[i]]) input_report_key(kbd->dev, usb_kbd_keycode[kbd->old[i]], 0); else dev_info(&urb->dev->dev, "Unknown key (scancode %#x) released.\n", kbd->old[i]); } /* 1. 将kbd->new[i]的值在kbd->old的6个字节中寻找,看是否存在,如果不存在,说明new[i]是新按下的 2. 如果不是新按下的键,而是原来的键一直没有释放,则不会上报按键事件, 说明只有在按键按下时上报事件,而在按的过程中不会上报按键事件。 */ if (kbd->new[i] > 3 && memscan(kbd->old + 2, kbd->new[i], 6) == kbd->old + 8) { if (usb_kbd_keycode[kbd->new[i]]) input_report_key(kbd->dev, usb_kbd_keycode[kbd->new[i]], 1); else dev_info(&urb->dev->dev, "Unknown key (scancode %#x) released.\n", kbd->new[i]); } } input_sync(kbd->dev); memcpy(kbd->old, kbd->new, 8); resubmit: i = usb_submit_urb (urb, GFP_ATOMIC); if (i) err_hid ("can't resubmit intr, %s-%s/input0, status %d", kbd->usbdev->bus->bus_name, kbd->usbdev->devpath, i); }
部分参考:http://blog.csdn.net/opencpu/article/details/6876083