📄 uglusbkbd.c
字号:
}/******************************************************************************** uglUsbKbdFormatter - format keyboard input data to input event** This routine handles formatting of input device data into an appropriate* event. The scan code from the keyboard is read and processed to * approporately update state modifiers (ALT, CTRL, SHIFT) and update LED* states. An input event is generated that contains the updated modifier* states, the scan code, and the corresponding Unicode value.** Scan codes are synthesized for special keys (alt, ctrl, shift) since USB* driver gives us modifier codes not scan codes.** There are no "extended" keys with the USB keyboards, although the "usage* ID" values in the USB HID Usage Tables reserve up to 0xFFFF. Currently* only single byte codes are used.** When operating in the raw mode a data stream is sent, as follows:** byte 0 | byte 1 | ... | byte n-1 | byte n* modifier | scan code | ... | scan code | -1** The modifier byte always starts a report, even if it isn't changed itself.* Reports are received only when something changes, either modifier byte, or* the list of active keys. The -1 byte which is unique signifies the end of a* report. Typically up to 6 scan codes can be sent per report. Each code* represents a key currently being pressed.** RETURNS: UGL_STATUS_OK, when a packet was recieved* UGL_STATUS_DROP** ERRNO: N/A** SEE ALSO: uglUsbKbdInit()*/UGL_LOCAL UGL_STATUS uglUsbKbdFormatter ( UGL_INPUT_DEVICE * pDevice, /* device info */ UGL_EVENT * pEvent /* event to build */ ) { UGL_INPUT_EVENT * pInputEvent = (UGL_INPUT_EVENT *)pEvent; UGL_EVENT_SERVICE * pService = pDevice->pService; UGL_LOCAL int lastScanCode = 0xff; int status; int keysDown = 0; int keysUp = 0; int i; unsigned char scanCode; UGL_UINT32 modifiers = 0; UGL_USB_KBD_REPORT diffDown, diffUp, current; /* Read byte from pipe */ if (read(pDevice->fd, (char *)&scanCode, 1) != 1) return (UGL_STATUS_ERROR); if (scanCode != 0xfe) { if (lastScanCode != 0xff) { /* Not in sync, abort */ lastScanCode = scanCode; return (UGL_STATUS_DROP); } /* clear interim working reports */ for (i=0; i < BOOT_RPT_KEYCOUNT; i++) { current.keys[i] = 0; diffDown.keys[i] = 0; diffUp.keys[i] = 0; } current.modifier = scanCode; /* * Reports cannot have more than BOOT_RPT_KEYCOUNT, but with * the serial protocol we have with the driver, we could have * BOOT_RPT_KEYCOUNT and a -1. A -1 is an end flag anyway; * any more is an error. */ current.keyCount = 0; for (i = 0; i < BOOT_RPT_KEYCOUNT; i++) { if (read(pDevice->fd, (char *)&scanCode, 1) != 1) return (UGL_STATUS_ERROR); if (scanCode == 0xff) break; current.keys[i] = scanCode; current.keyCount++; } lastScanCode = scanCode; newKeys(¤t, &diffUp, &diffDown); } /* Get modifiers */ modifiers = pService->inputModifiers & (UGL_KEYBOARD_CAPS_LOCK | UGL_KEYBOARD_NUM_LOCK | UGL_KEYBOARD_SCROLL_LOCK); if (current.modifier & 0x4) modifiers |= UGL_KEYBOARD_LEFT_ALT; if (current.modifier & 0x40) modifiers |= UGL_KEYBOARD_RIGHT_ALT; if (current.modifier & 0x1) modifiers |= UGL_KEYBOARD_LEFT_CTRL; if (current.modifier & 0x10) modifiers |= UGL_KEYBOARD_RIGHT_CTRL; if (current.modifier & 0x2) modifiers |= UGL_KEYBOARD_LEFT_SHIFT; if (current.modifier & 0x20) modifiers |= UGL_KEYBOARD_RIGHT_SHIFT; /* Take care of down key events */ for (i=0; i < BOOT_RPT_KEYCOUNT; i++) { if (diffDown.keys[i] != 0) { keysDown++; if (keysDown == 1) { modifiers |= UGL_KEYBOARD_KEYDOWN; /* build input event */ pInputEvent->header.type = UGL_EVENT_TYPE_KEYBOARD; pInputEvent->header.category = UGL_EVENT_CATEGORY_INPUT; /* Fix up modifiers for locks */ if (diffDown.keys[i] == 0x39) /* CAPS Lock */ modifiers ^= UGL_KEYBOARD_CAPS_LOCK; if (diffDown.keys[i] == 0x53) /* Num Lock */ modifiers ^= UGL_KEYBOARD_NUM_LOCK; if (diffDown.keys[i] == 0x47) /* Scroll Lock */ modifiers ^= UGL_KEYBOARD_SCROLL_LOCK; pInputEvent->modifiers = modifiers; pInputEvent->type.keyboard.scanCode = diffDown.keys[i]; /* convert scan code to unicode */ pInputEvent->type.keyboard.key = MapKeyValue (diffDown.keys[i], modifiers); diffDown.keys[i] = 0; } } } if (keysDown == 0) { /* No key down events, so generate up events */ for (i=0; i < BOOT_RPT_KEYCOUNT; i++) { if (diffUp.keys[i] != 0) { keysUp++; if (keysUp == 1) { /* build input event */ pInputEvent->header.type = UGL_EVENT_TYPE_KEYBOARD; pInputEvent->header.category = UGL_EVENT_CATEGORY_INPUT; pInputEvent->modifiers = modifiers; pInputEvent->type.keyboard.scanCode = diffUp.keys[i]; /* convert scan code to unicode */ pInputEvent->type.keyboard.key = MapKeyValue (diffUp.keys[i], modifiers); diffUp.keys[i] = 0; } } } } /* Save current report in device for next comparison */ if (pInputEvent->type.keyboard.key == 0) status = UGL_STATUS_DROP; else status = UGL_STATUS_OK; usbKbdData.lastReport.keyCount = current.keyCount; for (i = 0; i < BOOT_RPT_KEYCOUNT; i++) usbKbdData.lastReport.keys[i] = current.keys[i]; usbKbdData.lastReport.modifier = current.modifier; return (status); }/******************************************************************************** uglUsbKbdInfo - control the keyboard operations** This routine obtains information from the device and sets new information* within the device. For the PC keyboard, the following operations are * provided:**\is*\i LED mode (UGL_DEVICE_SET_LED_CONTROL)* Allow an application to control the LED state*\i set LED states (UGL_DEVICE_SET_LED)* Turn on/off an LED*\i get LED states (UGL_DEVICE_GET_LED)* Get the current setting of the keyboard LEDs*\ie** RETURNS: UGL_STATUS_OK** ERRNO: N/A** SEE ALSO: uglPcKbdInit()**/UGL_LOCAL UGL_STATUS uglUsbKbdInfo ( UGL_INPUT_DEVICE * pDevice, /* device control structure */ UGL_DEVICE_REQ request, /* request to perform */ void * arg /* argument for request */ ) { if(pDevice == UGL_NULL) return(UGL_STATUS_ERROR); /* * Although the caller may have obtained an UGL_INPUT_DEV_ID from * an open, unless the attachment callback has been executed, * there is nothing we can do. */ if (usbKbdData.state == UGL_USB_KBD_UNATTACHED) { uglLog (UGL_ERR_TYPE_WARN, "Err: USB keyboard is not attached.\n",0,0,0,0,0); return (UGL_STATUS_ERROR); } switch (request) { case UGL_DEVICE_SET_LED: /* set LEDs */ usbKbdData.ledValue = (UGL_UINT32) arg; if ((usbKbdData.pSioChan->pDrvFuncs->ioctl) (usbKbdData.pSioChan, SIO_KYBD_LED_SET, (void *)(usbKbdData.ledValue)) != OK) { uglLog (UGL_ERR_TYPE_WARN, "LED change failed\n",0,0,0,0,0); } break; case UGL_DEVICE_GET_LED: /* get state of LEDs */ *(int *)arg = usbKbdData.ledValue; break; default: return (UGL_STATUS_ERROR); } return (UGL_STATUS_OK); }/******************************************************************************* newKeys - Returns the key and modifier state change.** Returns the set of keys that have gone up and those that have done down* since the last report. The changes are reported in the diffUp and diffDown* structures.*/UGL_LOCAL void newKeys ( UGL_USB_KBD_REPORT *current, UGL_USB_KBD_REPORT *diffUp, UGL_USB_KBD_REPORT *diffDown ) { int i, j, k; /* Find keys down */ k = 0; for (i=0; i < BOOT_RPT_KEYCOUNT; i++) { int found; found = 0; if (current->keys[i] != 0) { for (j = 0; j < BOOT_RPT_KEYCOUNT; j++) { if (current->keys[i] == usbKbdData.lastReport.keys[j]) { found = 1; break; } } } else break; if (found == 0) { diffDown->keys[k] = current->keys[i]; k++; } } diffDown->modifier = (usbKbdData.lastReport.modifier & current->modifier) ^ current->modifier; diffDown->keyCount = k; /* Find keys up */ k = 0; for (i=0; i < BOOT_RPT_KEYCOUNT; i++) { int found; found = 0; if (usbKbdData.lastReport.keys[i] != 0) { for (j = 0; j < BOOT_RPT_KEYCOUNT; j++) { if (current->keys[j] == usbKbdData.lastReport.keys[i]) { found = 1; break; } } } else break; if (found == 0) { diffUp->keys[k] = usbKbdData.lastReport.keys[i]; k++; } } diffUp->modifier = (usbKbdData.lastReport.modifier & current->modifier) ^ usbKbdData.lastReport.modifier; diffUp->keyCount = k; }/******************************************************************************** MapKeyValue - map a scan code to Unicode value** This routien maps a scan code to a unicode value. The <keyValue> which* is a PC AT scan code is mapped to the corresonding unicode value, adjusted* by the current state of the key modifiers (shift, num lock, etc.) which* is present in <modifiers>.** RETURNS: mapped unicode value when mapping available, otherwise zero** ERRNO: N/A** SEE ALSO: */UGL_LOCAL UGL_UINT16 MapKeyValue ( UGL_UINT16 keyValue, /* scan code */ UGL_UINT32 modifiers /* modifier state */ ) { UGL_UINT16 unshiftedKeyValue; UGL_UINT16 shiftedKeyValue; UGL_BOOL numLock = modifiers & UGL_KEYBOARD_NUM_LOCK; UGL_BOOL capsLock = modifiers & UGL_KEYBOARD_CAPS_LOCK; UGL_BOOL shift = modifiers & UGL_KEYBOARD_SHIFT; UGL_BOOL ctrl = modifiers & UGL_KEYBOARD_CTRL;/* Select the keyboard mapping */#ifdef INCLUDE_KMAP_ENGLISH_US USB_KBD_KEYMAP * pKbdKeyMapTable = usbKbdUsKeyMapTable; size_t sizeOfKmap = sizeOfUsbUsKmap;#endif /* INCLUDE_KMAP_ENGLISH_US */ if (keyValue < (sizeOfKmap / sizeof(USB_KBD_KEYMAP))) { unshiftedKeyValue = pKbdKeyMapTable[keyValue].unshiftedKeyValue; shiftedKeyValue = pKbdKeyMapTable[keyValue].shiftedKeyValue; if (ctrl) return (unshiftedKeyValue); else if (numLock && shiftedKeyValue >= '0' && shiftedKeyValue <= '9') return (shift ? unshiftedKeyValue : shiftedKeyValue); else if (capsLock) { keyValue = (shift ? shiftedKeyValue : unshiftedKeyValue); if (shift) return (tolower(keyValue)); else return (toupper(keyValue)); } else return (shift ? shiftedKeyValue : unshiftedKeyValue); } else return 0; }
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -