usbhid类之mouse、keyboard

来源:互联网 发布:汽车模拟驾驶软件 编辑:程序博客网 时间:2024/05/16 07:54

一、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,//64105,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,//96191,192,193,194,134,138,130,132,128,129,131,137,133,135,136,113,//112115,114,  0,  0,  0,121,  0, 89, 93,124, 92, 94, 95,  0,  0,  0,//128122,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,//224150,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);elsedev_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);elsedev_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

0 0
原创粉丝点击