/** @file\r
-\r
Helper functions for USB Keyboard Driver.\r
\r
Copyright (c) 2004 - 2008, Intel Corporation\r
**/\r
\r
#include "KeyBoard.h"\r
-#include <Library/UefiUsbLib.h>\r
-\r
-//\r
-// Static English keyboard layout\r
-// Format:<efi key>, <unicode without shift>, <unicode with shift>, <Modifier>, <AffectedAttribute>\r
-//\r
-UINT8 KeyboardLayoutTable[USB_KEYCODE_MAX_MAKE + 8][5] = {\r
- {EfiKeyC1, 'a', 'A', EFI_NULL_MODIFIER, EFI_AFFECTED_BY_STANDARD_SHIFT | EFI_AFFECTED_BY_CAPS_LOCK}, // 0x04\r
- {EfiKeyB5, 'b', 'B', EFI_NULL_MODIFIER, EFI_AFFECTED_BY_STANDARD_SHIFT | EFI_AFFECTED_BY_CAPS_LOCK}, // 0x05\r
- {EfiKeyB3, 'c', 'C', EFI_NULL_MODIFIER, EFI_AFFECTED_BY_STANDARD_SHIFT | EFI_AFFECTED_BY_CAPS_LOCK}, // 0x06\r
- {EfiKeyC3, 'd', 'D', EFI_NULL_MODIFIER, EFI_AFFECTED_BY_STANDARD_SHIFT | EFI_AFFECTED_BY_CAPS_LOCK}, // 0x07\r
- {EfiKeyD3, 'e', 'E', EFI_NULL_MODIFIER, EFI_AFFECTED_BY_STANDARD_SHIFT | EFI_AFFECTED_BY_CAPS_LOCK}, // 0x08\r
- {EfiKeyC4, 'f', 'F', EFI_NULL_MODIFIER, EFI_AFFECTED_BY_STANDARD_SHIFT | EFI_AFFECTED_BY_CAPS_LOCK}, // 0x09\r
- {EfiKeyC5, 'g', 'G', EFI_NULL_MODIFIER, EFI_AFFECTED_BY_STANDARD_SHIFT | EFI_AFFECTED_BY_CAPS_LOCK}, // 0x0A\r
- {EfiKeyC6, 'h', 'H', EFI_NULL_MODIFIER, EFI_AFFECTED_BY_STANDARD_SHIFT | EFI_AFFECTED_BY_CAPS_LOCK}, // 0x0B\r
- {EfiKeyD8, 'i', 'I', EFI_NULL_MODIFIER, EFI_AFFECTED_BY_STANDARD_SHIFT | EFI_AFFECTED_BY_CAPS_LOCK}, // 0x0C\r
- {EfiKeyC7, 'j', 'J', EFI_NULL_MODIFIER, EFI_AFFECTED_BY_STANDARD_SHIFT | EFI_AFFECTED_BY_CAPS_LOCK}, // 0x0D\r
- {EfiKeyC8, 'k', 'K', EFI_NULL_MODIFIER, EFI_AFFECTED_BY_STANDARD_SHIFT | EFI_AFFECTED_BY_CAPS_LOCK}, // 0x0E\r
- {EfiKeyC9, 'l', 'L', EFI_NULL_MODIFIER, EFI_AFFECTED_BY_STANDARD_SHIFT | EFI_AFFECTED_BY_CAPS_LOCK}, // 0x0F\r
- {EfiKeyB7, 'm', 'M', EFI_NULL_MODIFIER, EFI_AFFECTED_BY_STANDARD_SHIFT | EFI_AFFECTED_BY_CAPS_LOCK}, // 0x10\r
- {EfiKeyB6, 'n', 'N', EFI_NULL_MODIFIER, EFI_AFFECTED_BY_STANDARD_SHIFT | EFI_AFFECTED_BY_CAPS_LOCK}, // 0x11\r
- {EfiKeyD9, 'o', 'O', EFI_NULL_MODIFIER, EFI_AFFECTED_BY_STANDARD_SHIFT | EFI_AFFECTED_BY_CAPS_LOCK}, // 0x12\r
- {EfiKeyD10, 'p', 'P', EFI_NULL_MODIFIER, EFI_AFFECTED_BY_STANDARD_SHIFT | EFI_AFFECTED_BY_CAPS_LOCK}, // 0x13\r
- {EfiKeyD1, 'q', 'Q', EFI_NULL_MODIFIER, EFI_AFFECTED_BY_STANDARD_SHIFT | EFI_AFFECTED_BY_CAPS_LOCK}, // 0x14\r
- {EfiKeyD4, 'r', 'R', EFI_NULL_MODIFIER, EFI_AFFECTED_BY_STANDARD_SHIFT | EFI_AFFECTED_BY_CAPS_LOCK}, // 0x15\r
- {EfiKeyC2, 's', 'S', EFI_NULL_MODIFIER, EFI_AFFECTED_BY_STANDARD_SHIFT | EFI_AFFECTED_BY_CAPS_LOCK}, // 0x16\r
- {EfiKeyD5, 't', 'T', EFI_NULL_MODIFIER, EFI_AFFECTED_BY_STANDARD_SHIFT | EFI_AFFECTED_BY_CAPS_LOCK}, // 0x17\r
- {EfiKeyD7, 'u', 'U', EFI_NULL_MODIFIER, EFI_AFFECTED_BY_STANDARD_SHIFT | EFI_AFFECTED_BY_CAPS_LOCK}, // 0x18\r
- {EfiKeyB4, 'v', 'V', EFI_NULL_MODIFIER, EFI_AFFECTED_BY_STANDARD_SHIFT | EFI_AFFECTED_BY_CAPS_LOCK}, // 0x19\r
- {EfiKeyD2, 'w', 'W', EFI_NULL_MODIFIER, EFI_AFFECTED_BY_STANDARD_SHIFT | EFI_AFFECTED_BY_CAPS_LOCK}, // 0x1A\r
- {EfiKeyB2, 'x', 'X', EFI_NULL_MODIFIER, EFI_AFFECTED_BY_STANDARD_SHIFT | EFI_AFFECTED_BY_CAPS_LOCK}, // 0x1B\r
- {EfiKeyD6, 'y', 'Y', EFI_NULL_MODIFIER, EFI_AFFECTED_BY_STANDARD_SHIFT | EFI_AFFECTED_BY_CAPS_LOCK}, // 0x1C\r
- {EfiKeyB1, 'z', 'Z', EFI_NULL_MODIFIER, EFI_AFFECTED_BY_STANDARD_SHIFT | EFI_AFFECTED_BY_CAPS_LOCK}, // 0x1D\r
- {EfiKeyE1, '1', '!', EFI_NULL_MODIFIER, EFI_AFFECTED_BY_STANDARD_SHIFT}, // 0x1E\r
- {EfiKeyE2, '2', '@', EFI_NULL_MODIFIER, EFI_AFFECTED_BY_STANDARD_SHIFT}, // 0x1F\r
- {EfiKeyE3, '3', '#', EFI_NULL_MODIFIER, EFI_AFFECTED_BY_STANDARD_SHIFT}, // 0x20\r
- {EfiKeyE4, '4', '$', EFI_NULL_MODIFIER, EFI_AFFECTED_BY_STANDARD_SHIFT}, // 0x21\r
- {EfiKeyE5, '5', '%', EFI_NULL_MODIFIER, EFI_AFFECTED_BY_STANDARD_SHIFT}, // 0x22\r
- {EfiKeyE6, '6', '^', EFI_NULL_MODIFIER, EFI_AFFECTED_BY_STANDARD_SHIFT}, // 0x23\r
- {EfiKeyE7, '7', '&', EFI_NULL_MODIFIER, EFI_AFFECTED_BY_STANDARD_SHIFT}, // 0x24\r
- {EfiKeyE8, '8', '*', EFI_NULL_MODIFIER, EFI_AFFECTED_BY_STANDARD_SHIFT}, // 0x25\r
- {EfiKeyE9, '9', '(', EFI_NULL_MODIFIER, EFI_AFFECTED_BY_STANDARD_SHIFT}, // 0x26\r
- {EfiKeyE10, '0', ')', EFI_NULL_MODIFIER, EFI_AFFECTED_BY_STANDARD_SHIFT}, // 0x27\r
- {EfiKeyEnter, 0x0d, 0x0d, EFI_NULL_MODIFIER, 0}, // 0x28 Enter\r
- {EfiKeyEsc, 0x1b, 0x1b, EFI_NULL_MODIFIER, 0}, // 0x29 Esc\r
- {EfiKeyBackSpace, 0x08, 0x08, EFI_NULL_MODIFIER, 0}, // 0x2A Backspace\r
- {EfiKeyTab, 0x09, 0x09, EFI_NULL_MODIFIER, 0}, // 0x2B Tab\r
- {EfiKeySpaceBar, ' ', ' ', EFI_NULL_MODIFIER, 0}, // 0x2C Spacebar\r
- {EfiKeyE11, '-', '_', EFI_NULL_MODIFIER, EFI_AFFECTED_BY_STANDARD_SHIFT}, // 0x2D\r
- {EfiKeyE12, '=', '+', EFI_NULL_MODIFIER, EFI_AFFECTED_BY_STANDARD_SHIFT}, // 0x2E\r
- {EfiKeyD11, '[', '{', EFI_NULL_MODIFIER, EFI_AFFECTED_BY_STANDARD_SHIFT}, // 0x2F\r
- {EfiKeyD12, ']', '}', EFI_NULL_MODIFIER, EFI_AFFECTED_BY_STANDARD_SHIFT}, // 0x30\r
- {EfiKeyD13, '\\', '|', EFI_NULL_MODIFIER, EFI_AFFECTED_BY_STANDARD_SHIFT}, // 0x31\r
- {EfiKeyC12, '\\', '|', EFI_NULL_MODIFIER, EFI_AFFECTED_BY_STANDARD_SHIFT}, // 0x32 Keyboard Non-US # and ~\r
- {EfiKeyC10, ';', ':', EFI_NULL_MODIFIER, EFI_AFFECTED_BY_STANDARD_SHIFT}, // 0x33\r
- {EfiKeyC11, '\'', '"', EFI_NULL_MODIFIER, EFI_AFFECTED_BY_STANDARD_SHIFT}, // 0x34\r
- {EfiKeyE0, '`', '~', EFI_NULL_MODIFIER, EFI_AFFECTED_BY_STANDARD_SHIFT}, // 0x35 Keyboard Grave Accent and Tlide\r
- {EfiKeyB8, ',', '<', EFI_NULL_MODIFIER, EFI_AFFECTED_BY_STANDARD_SHIFT}, // 0x36\r
- {EfiKeyB9, '.', '>', EFI_NULL_MODIFIER, EFI_AFFECTED_BY_STANDARD_SHIFT}, // 0x37\r
- {EfiKeyB10, '/', '?', EFI_NULL_MODIFIER, EFI_AFFECTED_BY_STANDARD_SHIFT}, // 0x38\r
- {EfiKeyCapsLock, 0x00, 0x00, EFI_CAPS_LOCK_MODIFIER, 0}, // 0x39 CapsLock\r
- {EfiKeyF1, 0x00, 0x00, EFI_FUNCTION_KEY_ONE_MODIFIER, 0}, // 0x3A\r
- {EfiKeyF2, 0x00, 0x00, EFI_FUNCTION_KEY_TWO_MODIFIER, 0}, // 0x3B\r
- {EfiKeyF3, 0x00, 0x00, EFI_FUNCTION_KEY_THREE_MODIFIER, 0}, // 0x3C\r
- {EfiKeyF4, 0x00, 0x00, EFI_FUNCTION_KEY_FOUR_MODIFIER, 0}, // 0x3D\r
- {EfiKeyF5, 0x00, 0x00, EFI_FUNCTION_KEY_FIVE_MODIFIER, 0}, // 0x3E\r
- {EfiKeyF6, 0x00, 0x00, EFI_FUNCTION_KEY_SIX_MODIFIER, 0}, // 0x3F\r
- {EfiKeyF7, 0x00, 0x00, EFI_FUNCTION_KEY_SEVEN_MODIFIER, 0}, // 0x40\r
- {EfiKeyF8, 0x00, 0x00, EFI_FUNCTION_KEY_EIGHT_MODIFIER, 0}, // 0x41\r
- {EfiKeyF9, 0x00, 0x00, EFI_FUNCTION_KEY_NINE_MODIFIER, 0}, // 0x42\r
- {EfiKeyF10, 0x00, 0x00, EFI_FUNCTION_KEY_TEN_MODIFIER, 0}, // 0x43\r
- {EfiKeyF11, 0x00, 0x00, EFI_FUNCTION_KEY_ELEVEN_MODIFIER, 0}, // 0x44 F11\r
- {EfiKeyF12, 0x00, 0x00, EFI_FUNCTION_KEY_TWELVE_MODIFIER, 0}, // 0x45 F12\r
- {EfiKeyPrint, 0x00, 0x00, EFI_PRINT_MODIFIER, 0}, // 0x46 PrintScreen\r
- {EfiKeySLck, 0x00, 0x00, EFI_SCROLL_LOCK_MODIFIER, 0}, // 0x47 Scroll Lock\r
- {EfiKeyPause, 0x00, 0x00, EFI_PAUSE_MODIFIER, 0}, // 0x48 Pause\r
- {EfiKeyIns, 0x00, 0x00, EFI_INSERT_MODIFIER, 0}, // 0x49\r
- {EfiKeyHome, 0x00, 0x00, EFI_HOME_MODIFIER, 0}, // 0x4A\r
- {EfiKeyPgUp, 0x00, 0x00, EFI_PAGE_UP_MODIFIER, 0}, // 0x4B\r
- {EfiKeyDel, 0x00, 0x00, EFI_DELETE_MODIFIER, 0}, // 0x4C\r
- {EfiKeyEnd, 0x00, 0x00, EFI_END_MODIFIER, 0}, // 0x4D\r
- {EfiKeyPgDn, 0x00, 0x00, EFI_PAGE_DOWN_MODIFIER, 0}, // 0x4E\r
- {EfiKeyRightArrow, 0x00, 0x00, EFI_RIGHT_ARROW_MODIFIER, 0}, // 0x4F\r
- {EfiKeyLeftArrow, 0x00, 0x00, EFI_LEFT_ARROW_MODIFIER, 0}, // 0x50\r
- {EfiKeyDownArrow, 0x00, 0x00, EFI_DOWN_ARROW_MODIFIER, 0}, // 0x51\r
- {EfiKeyUpArrow, 0x00, 0x00, EFI_UP_ARROW_MODIFIER, 0}, // 0x52\r
- {EfiKeyNLck, 0x00, 0x00, EFI_NUM_LOCK_MODIFIER, 0}, // 0x53 NumLock\r
- {EfiKeySlash, '/', '/', EFI_NULL_MODIFIER, 0}, // 0x54\r
- {EfiKeyAsterisk, '*', '*', EFI_NULL_MODIFIER, 0}, // 0x55\r
- {EfiKeyMinus, '-', '-', EFI_NULL_MODIFIER, 0}, // 0x56\r
- {EfiKeyPlus, '+', '+', EFI_NULL_MODIFIER, 0}, // 0x57\r
- {EfiKeyEnter, 0x0d, 0x0d, EFI_NULL_MODIFIER, 0}, // 0x58\r
- {EfiKeyOne, '1', '1', EFI_END_MODIFIER, EFI_AFFECTED_BY_STANDARD_SHIFT | EFI_AFFECTED_BY_NUM_LOCK}, // 0x59\r
- {EfiKeyTwo, '2', '2', EFI_DOWN_ARROW_MODIFIER, EFI_AFFECTED_BY_STANDARD_SHIFT | EFI_AFFECTED_BY_NUM_LOCK}, // 0x5A\r
- {EfiKeyThree, '3', '3', EFI_PAGE_DOWN_MODIFIER, EFI_AFFECTED_BY_STANDARD_SHIFT | EFI_AFFECTED_BY_NUM_LOCK}, // 0x5B\r
- {EfiKeyFour, '4', '4', EFI_LEFT_ARROW_MODIFIER, EFI_AFFECTED_BY_STANDARD_SHIFT | EFI_AFFECTED_BY_NUM_LOCK}, // 0x5C\r
- {EfiKeyFive, '5', '5', EFI_NULL_MODIFIER, EFI_AFFECTED_BY_STANDARD_SHIFT | EFI_AFFECTED_BY_NUM_LOCK}, // 0x5D\r
- {EfiKeySix, '6', '6', EFI_RIGHT_ARROW_MODIFIER, EFI_AFFECTED_BY_STANDARD_SHIFT | EFI_AFFECTED_BY_NUM_LOCK}, // 0x5E\r
- {EfiKeySeven, '7', '7', EFI_HOME_MODIFIER, EFI_AFFECTED_BY_STANDARD_SHIFT | EFI_AFFECTED_BY_NUM_LOCK}, // 0x5F\r
- {EfiKeyEight, '8', '8', EFI_UP_ARROW_MODIFIER, EFI_AFFECTED_BY_STANDARD_SHIFT | EFI_AFFECTED_BY_NUM_LOCK}, // 0x60\r
- {EfiKeyNine, '9', '9', EFI_PAGE_UP_MODIFIER, EFI_AFFECTED_BY_STANDARD_SHIFT | EFI_AFFECTED_BY_NUM_LOCK}, // 0x61\r
- {EfiKeyZero, '0', '0', EFI_INSERT_MODIFIER, EFI_AFFECTED_BY_STANDARD_SHIFT | EFI_AFFECTED_BY_NUM_LOCK}, // 0x62\r
- {EfiKeyPeriod, '.', '.', EFI_DELETE_MODIFIER, EFI_AFFECTED_BY_STANDARD_SHIFT | EFI_AFFECTED_BY_NUM_LOCK}, // 0x63\r
- {EfiKeyB0, '\\', '|', EFI_NULL_MODIFIER, EFI_AFFECTED_BY_STANDARD_SHIFT}, // 0x64 Keyboard Non-US \ and |\r
- {EfiKeyA4, 0x00, 0x00, EFI_MENU_MODIFIER, 0}, // 0x65 Keyboard Application\r
-\r
- {EfiKeyLCtrl, 0, 0, EFI_LEFT_CONTROL_MODIFIER, 0}, // 0xe0\r
- {EfiKeyLShift, 0, 0, EFI_LEFT_SHIFT_MODIFIER, 0}, // 0xe1\r
- {EfiKeyLAlt, 0, 0, EFI_LEFT_ALT_MODIFIER, 0}, // 0xe2\r
- {EfiKeyA0, 0, 0, EFI_LEFT_LOGO_MODIFIER, 0}, // 0xe3\r
- {EfiKeyRCtrl, 0, 0, EFI_RIGHT_CONTROL_MODIFIER, 0}, // 0xe4\r
- {EfiKeyRShift, 0, 0, EFI_RIGHT_SHIFT_MODIFIER, 0}, // 0xe5\r
- {EfiKeyA2, 0, 0, EFI_RIGHT_ALT_MODIFIER, 0}, // 0xe6\r
- {EfiKeyA3, 0, 0, EFI_RIGHT_LOGO_MODIFIER, 0}, // 0xe7\r
-};\r
-\r
-/**\r
- Initialize KeyConvertionTable by using default keyboard layout.\r
\r
- @param UsbKeyboardDevice The USB_KB_DEV instance.\r
- @retval None.\r
+EFI_GUID mUsbKeyboardLayoutPackageGuid = USB_KEYBOARD_LAYOUT_PACKAGE_GUID;\r
+EFI_GUID mUsbKeyboardLayoutKeyGuid = USB_KEYBOARD_LAYOUT_KEY_GUID;\r
\r
-**/\r
-VOID\r
-EFIAPI\r
-LoadDefaultKeyboardLayout (\r
- IN USB_KB_DEV *UsbKeyboardDevice\r
- )\r
-{\r
- UINTN Index;\r
- EFI_KEY_DESCRIPTOR *KeyDescriptor;\r
+USB_KEYBOARD_LAYOUT_PACK_BIN mUsbKeyboardLayoutBin = {\r
+ sizeof (USB_KEYBOARD_LAYOUT_PACK_BIN), // Binary size\r
\r
//\r
- // Construct KeyConvertionTable by default keyboard layout\r
+ // EFI_HII_PACKAGE_HEADER\r
//\r
- KeyDescriptor = &UsbKeyboardDevice->KeyConvertionTable[0];\r
-\r
- for (Index = 0; Index < (USB_KEYCODE_MAX_MAKE + 8); Index++) {\r
- KeyDescriptor->Key = (EFI_KEY) KeyboardLayoutTable[Index][0];\r
- KeyDescriptor->Unicode = KeyboardLayoutTable[Index][1];\r
- KeyDescriptor->ShiftedUnicode = KeyboardLayoutTable[Index][2];\r
- KeyDescriptor->AltGrUnicode = 0;\r
- KeyDescriptor->ShiftedAltGrUnicode = 0;\r
- KeyDescriptor->Modifier = KeyboardLayoutTable[Index][3];\r
- KeyDescriptor->AffectedAttribute = KeyboardLayoutTable[Index][4];\r
-\r
- KeyDescriptor++;\r
- }\r
-}\r
+ {\r
+ sizeof (USB_KEYBOARD_LAYOUT_PACK_BIN) - sizeof (UINT32),\r
+ EFI_HII_PACKAGE_KEYBOARD_LAYOUT\r
+ },\r
+ 1, // LayoutCount\r
+ sizeof (USB_KEYBOARD_LAYOUT_PACK_BIN) - sizeof (UINT32) - sizeof (EFI_HII_PACKAGE_HEADER) - sizeof (UINT16), // LayoutLength\r
+ USB_KEYBOARD_LAYOUT_KEY_GUID, // KeyGuid\r
+ sizeof (UINT16) + sizeof (EFI_GUID) + sizeof (UINT32) + sizeof (UINT8) + (USB_KEYBOARD_KEY_COUNT * sizeof (EFI_KEY_DESCRIPTOR)), // LayoutDescriptorStringOffset\r
+ USB_KEYBOARD_KEY_COUNT, // DescriptorCount\r
+ {\r
+ //\r
+ // EFI_KEY_DESCRIPTOR (total number is USB_KEYBOARD_KEY_COUNT)\r
+ //\r
+ {EfiKeyC1, 'a', 'A', 0, 0, EFI_NULL_MODIFIER, EFI_AFFECTED_BY_STANDARD_SHIFT | EFI_AFFECTED_BY_CAPS_LOCK},\r
+ {EfiKeyB5, 'b', 'B', 0, 0, EFI_NULL_MODIFIER, EFI_AFFECTED_BY_STANDARD_SHIFT | EFI_AFFECTED_BY_CAPS_LOCK},\r
+ {EfiKeyB3, 'c', 'C', 0, 0, EFI_NULL_MODIFIER, EFI_AFFECTED_BY_STANDARD_SHIFT | EFI_AFFECTED_BY_CAPS_LOCK},\r
+ {EfiKeyC3, 'd', 'D', 0, 0, EFI_NULL_MODIFIER, EFI_AFFECTED_BY_STANDARD_SHIFT | EFI_AFFECTED_BY_CAPS_LOCK},\r
+ {EfiKeyD3, 'e', 'E', 0, 0, EFI_NULL_MODIFIER, EFI_AFFECTED_BY_STANDARD_SHIFT | EFI_AFFECTED_BY_CAPS_LOCK},\r
+ {EfiKeyC4, 'f', 'F', 0, 0, EFI_NULL_MODIFIER, EFI_AFFECTED_BY_STANDARD_SHIFT | EFI_AFFECTED_BY_CAPS_LOCK},\r
+ {EfiKeyC5, 'g', 'G', 0, 0, EFI_NULL_MODIFIER, EFI_AFFECTED_BY_STANDARD_SHIFT | EFI_AFFECTED_BY_CAPS_LOCK},\r
+ {EfiKeyC6, 'h', 'H', 0, 0, EFI_NULL_MODIFIER, EFI_AFFECTED_BY_STANDARD_SHIFT | EFI_AFFECTED_BY_CAPS_LOCK},\r
+ {EfiKeyD8, 'i', 'I', 0, 0, EFI_NULL_MODIFIER, EFI_AFFECTED_BY_STANDARD_SHIFT | EFI_AFFECTED_BY_CAPS_LOCK},\r
+ {EfiKeyC7, 'j', 'J', 0, 0, EFI_NULL_MODIFIER, EFI_AFFECTED_BY_STANDARD_SHIFT | EFI_AFFECTED_BY_CAPS_LOCK},\r
+ {EfiKeyC8, 'k', 'K', 0, 0, EFI_NULL_MODIFIER, EFI_AFFECTED_BY_STANDARD_SHIFT | EFI_AFFECTED_BY_CAPS_LOCK},\r
+ {EfiKeyC9, 'l', 'L', 0, 0, EFI_NULL_MODIFIER, EFI_AFFECTED_BY_STANDARD_SHIFT | EFI_AFFECTED_BY_CAPS_LOCK},\r
+ {EfiKeyB7, 'm', 'M', 0, 0, EFI_NULL_MODIFIER, EFI_AFFECTED_BY_STANDARD_SHIFT | EFI_AFFECTED_BY_CAPS_LOCK},\r
+ {EfiKeyB6, 'n', 'N', 0, 0, EFI_NULL_MODIFIER, EFI_AFFECTED_BY_STANDARD_SHIFT | EFI_AFFECTED_BY_CAPS_LOCK},\r
+ {EfiKeyD9, 'o', 'O', 0, 0, EFI_NULL_MODIFIER, EFI_AFFECTED_BY_STANDARD_SHIFT | EFI_AFFECTED_BY_CAPS_LOCK},\r
+ {EfiKeyD10, 'p', 'P', 0, 0, EFI_NULL_MODIFIER, EFI_AFFECTED_BY_STANDARD_SHIFT | EFI_AFFECTED_BY_CAPS_LOCK},\r
+ {EfiKeyD1, 'q', 'Q', 0, 0, EFI_NULL_MODIFIER, EFI_AFFECTED_BY_STANDARD_SHIFT | EFI_AFFECTED_BY_CAPS_LOCK},\r
+ {EfiKeyD4, 'r', 'R', 0, 0, EFI_NULL_MODIFIER, EFI_AFFECTED_BY_STANDARD_SHIFT | EFI_AFFECTED_BY_CAPS_LOCK},\r
+ {EfiKeyC2, 's', 'S', 0, 0, EFI_NULL_MODIFIER, EFI_AFFECTED_BY_STANDARD_SHIFT | EFI_AFFECTED_BY_CAPS_LOCK},\r
+ {EfiKeyD5, 't', 'T', 0, 0, EFI_NULL_MODIFIER, EFI_AFFECTED_BY_STANDARD_SHIFT | EFI_AFFECTED_BY_CAPS_LOCK},\r
+ {EfiKeyD7, 'u', 'U', 0, 0, EFI_NULL_MODIFIER, EFI_AFFECTED_BY_STANDARD_SHIFT | EFI_AFFECTED_BY_CAPS_LOCK},\r
+ {EfiKeyB4, 'v', 'V', 0, 0, EFI_NULL_MODIFIER, EFI_AFFECTED_BY_STANDARD_SHIFT | EFI_AFFECTED_BY_CAPS_LOCK},\r
+ {EfiKeyD2, 'w', 'W', 0, 0, EFI_NULL_MODIFIER, EFI_AFFECTED_BY_STANDARD_SHIFT | EFI_AFFECTED_BY_CAPS_LOCK},\r
+ {EfiKeyB2, 'x', 'X', 0, 0, EFI_NULL_MODIFIER, EFI_AFFECTED_BY_STANDARD_SHIFT | EFI_AFFECTED_BY_CAPS_LOCK},\r
+ {EfiKeyD6, 'y', 'Y', 0, 0, EFI_NULL_MODIFIER, EFI_AFFECTED_BY_STANDARD_SHIFT | EFI_AFFECTED_BY_CAPS_LOCK},\r
+ {EfiKeyB1, 'z', 'Z', 0, 0, EFI_NULL_MODIFIER, EFI_AFFECTED_BY_STANDARD_SHIFT | EFI_AFFECTED_BY_CAPS_LOCK},\r
+ {EfiKeyE1, '1', '!', 0, 0, EFI_NULL_MODIFIER, EFI_AFFECTED_BY_STANDARD_SHIFT},\r
+ {EfiKeyE2, '2', '@', 0, 0, EFI_NULL_MODIFIER, EFI_AFFECTED_BY_STANDARD_SHIFT},\r
+ {EfiKeyE3, '3', '#', 0, 0, EFI_NULL_MODIFIER, EFI_AFFECTED_BY_STANDARD_SHIFT},\r
+ {EfiKeyE4, '4', '$', 0, 0, EFI_NULL_MODIFIER, EFI_AFFECTED_BY_STANDARD_SHIFT},\r
+ {EfiKeyE5, '5', '%', 0, 0, EFI_NULL_MODIFIER, EFI_AFFECTED_BY_STANDARD_SHIFT},\r
+ {EfiKeyE6, '6', '^', 0, 0, EFI_NULL_MODIFIER, EFI_AFFECTED_BY_STANDARD_SHIFT},\r
+ {EfiKeyE7, '7', '&', 0, 0, EFI_NULL_MODIFIER, EFI_AFFECTED_BY_STANDARD_SHIFT},\r
+ {EfiKeyE8, '8', '*', 0, 0, EFI_NULL_MODIFIER, EFI_AFFECTED_BY_STANDARD_SHIFT},\r
+ {EfiKeyE9, '9', '(', 0, 0, EFI_NULL_MODIFIER, EFI_AFFECTED_BY_STANDARD_SHIFT},\r
+ {EfiKeyE10, '0', ')', 0, 0, EFI_NULL_MODIFIER, EFI_AFFECTED_BY_STANDARD_SHIFT},\r
+ {EfiKeyEnter, 0x0d, 0x0d, 0, 0, EFI_NULL_MODIFIER, 0},\r
+ {EfiKeyEsc, 0x1b, 0x1b, 0, 0, EFI_NULL_MODIFIER, 0},\r
+ {EfiKeyBackSpace, 0x08, 0x08, 0, 0, EFI_NULL_MODIFIER, 0},\r
+ {EfiKeyTab, 0x09, 0x09, 0, 0, EFI_NULL_MODIFIER, 0},\r
+ {EfiKeySpaceBar, ' ', ' ', 0, 0, EFI_NULL_MODIFIER, 0},\r
+ {EfiKeyE11, '-', '_', 0, 0, EFI_NULL_MODIFIER, EFI_AFFECTED_BY_STANDARD_SHIFT},\r
+ {EfiKeyE12, '=', '+', 0, 0, EFI_NULL_MODIFIER, EFI_AFFECTED_BY_STANDARD_SHIFT},\r
+ {EfiKeyD11, '[', '{', 0, 0, EFI_NULL_MODIFIER, EFI_AFFECTED_BY_STANDARD_SHIFT},\r
+ {EfiKeyD12, ']', '}', 0, 0, EFI_NULL_MODIFIER, EFI_AFFECTED_BY_STANDARD_SHIFT},\r
+ {EfiKeyD13, '\\', '|', 0, 0, EFI_NULL_MODIFIER, EFI_AFFECTED_BY_STANDARD_SHIFT},\r
+ {EfiKeyC10, ';', ':', 0, 0, EFI_NULL_MODIFIER, EFI_AFFECTED_BY_STANDARD_SHIFT},\r
+ {EfiKeyC11, '\'', '"', 0, 0, EFI_NULL_MODIFIER, EFI_AFFECTED_BY_STANDARD_SHIFT},\r
+ {EfiKeyE0, '`', '~', 0, 0, EFI_NULL_MODIFIER, EFI_AFFECTED_BY_STANDARD_SHIFT},\r
+ {EfiKeyB8, ',', '<', 0, 0, EFI_NULL_MODIFIER, EFI_AFFECTED_BY_STANDARD_SHIFT},\r
+ {EfiKeyB9, '.', '>', 0, 0, EFI_NULL_MODIFIER, EFI_AFFECTED_BY_STANDARD_SHIFT},\r
+ {EfiKeyB10, '/', '?', 0, 0, EFI_NULL_MODIFIER, EFI_AFFECTED_BY_STANDARD_SHIFT},\r
+ {EfiKeyCapsLock, 0x00, 0x00, 0, 0, EFI_CAPS_LOCK_MODIFIER, 0},\r
+ {EfiKeyF1, 0x00, 0x00, 0, 0, EFI_FUNCTION_KEY_ONE_MODIFIER, 0},\r
+ {EfiKeyF2, 0x00, 0x00, 0, 0, EFI_FUNCTION_KEY_TWO_MODIFIER, 0},\r
+ {EfiKeyF3, 0x00, 0x00, 0, 0, EFI_FUNCTION_KEY_THREE_MODIFIER, 0},\r
+ {EfiKeyF4, 0x00, 0x00, 0, 0, EFI_FUNCTION_KEY_FOUR_MODIFIER, 0},\r
+ {EfiKeyF5, 0x00, 0x00, 0, 0, EFI_FUNCTION_KEY_FIVE_MODIFIER, 0},\r
+ {EfiKeyF6, 0x00, 0x00, 0, 0, EFI_FUNCTION_KEY_SIX_MODIFIER, 0},\r
+ {EfiKeyF7, 0x00, 0x00, 0, 0, EFI_FUNCTION_KEY_SEVEN_MODIFIER, 0},\r
+ {EfiKeyF8, 0x00, 0x00, 0, 0, EFI_FUNCTION_KEY_EIGHT_MODIFIER, 0},\r
+ {EfiKeyF9, 0x00, 0x00, 0, 0, EFI_FUNCTION_KEY_NINE_MODIFIER, 0},\r
+ {EfiKeyF10, 0x00, 0x00, 0, 0, EFI_FUNCTION_KEY_TEN_MODIFIER, 0},\r
+ {EfiKeyF11, 0x00, 0x00, 0, 0, EFI_FUNCTION_KEY_ELEVEN_MODIFIER, 0},\r
+ {EfiKeyF12, 0x00, 0x00, 0, 0, EFI_FUNCTION_KEY_TWELVE_MODIFIER, 0},\r
+ {EfiKeyPrint, 0x00, 0x00, 0, 0, EFI_PRINT_MODIFIER, 0},\r
+ {EfiKeySLck, 0x00, 0x00, 0, 0, EFI_SCROLL_LOCK_MODIFIER, 0},\r
+ {EfiKeyPause, 0x00, 0x00, 0, 0, EFI_PAUSE_MODIFIER, 0},\r
+ {EfiKeyIns, 0x00, 0x00, 0, 0, EFI_INSERT_MODIFIER, 0},\r
+ {EfiKeyHome, 0x00, 0x00, 0, 0, EFI_HOME_MODIFIER, 0},\r
+ {EfiKeyPgUp, 0x00, 0x00, 0, 0, EFI_PAGE_UP_MODIFIER, 0},\r
+ {EfiKeyDel, 0x00, 0x00, 0, 0, EFI_DELETE_MODIFIER, 0},\r
+ {EfiKeyEnd, 0x00, 0x00, 0, 0, EFI_END_MODIFIER, 0},\r
+ {EfiKeyPgDn, 0x00, 0x00, 0, 0, EFI_PAGE_DOWN_MODIFIER, 0},\r
+ {EfiKeyRightArrow, 0x00, 0x00, 0, 0, EFI_RIGHT_ARROW_MODIFIER, 0},\r
+ {EfiKeyLeftArrow, 0x00, 0x00, 0, 0, EFI_LEFT_ARROW_MODIFIER, 0},\r
+ {EfiKeyDownArrow, 0x00, 0x00, 0, 0, EFI_DOWN_ARROW_MODIFIER, 0},\r
+ {EfiKeyUpArrow, 0x00, 0x00, 0, 0, EFI_UP_ARROW_MODIFIER, 0},\r
+ {EfiKeyNLck, 0x00, 0x00, 0, 0, EFI_NUM_LOCK_MODIFIER, 0},\r
+ {EfiKeySlash, '/', '/', 0, 0, EFI_NULL_MODIFIER, 0},\r
+ {EfiKeyAsterisk, '*', '*', 0, 0, EFI_NULL_MODIFIER, 0},\r
+ {EfiKeyMinus, '-', '-', 0, 0, EFI_NULL_MODIFIER, 0},\r
+ {EfiKeyPlus, '+', '+', 0, 0, EFI_NULL_MODIFIER, 0},\r
+ {EfiKeyEnter, 0x0d, 0x0d, 0, 0, EFI_NULL_MODIFIER, 0},\r
+ {EfiKeyOne, '1', '1', 0, 0, EFI_END_MODIFIER, EFI_AFFECTED_BY_STANDARD_SHIFT | EFI_AFFECTED_BY_NUM_LOCK},\r
+ {EfiKeyTwo, '2', '2', 0, 0, EFI_DOWN_ARROW_MODIFIER, EFI_AFFECTED_BY_STANDARD_SHIFT | EFI_AFFECTED_BY_NUM_LOCK},\r
+ {EfiKeyThree, '3', '3', 0, 0, EFI_PAGE_DOWN_MODIFIER, EFI_AFFECTED_BY_STANDARD_SHIFT | EFI_AFFECTED_BY_NUM_LOCK},\r
+ {EfiKeyFour, '4', '4', 0, 0, EFI_LEFT_ARROW_MODIFIER, EFI_AFFECTED_BY_STANDARD_SHIFT | EFI_AFFECTED_BY_NUM_LOCK},\r
+ {EfiKeyFive, '5', '5', 0, 0, EFI_NULL_MODIFIER, EFI_AFFECTED_BY_STANDARD_SHIFT | EFI_AFFECTED_BY_NUM_LOCK},\r
+ {EfiKeySix, '6', '6', 0, 0, EFI_RIGHT_ARROW_MODIFIER, EFI_AFFECTED_BY_STANDARD_SHIFT | EFI_AFFECTED_BY_NUM_LOCK},\r
+ {EfiKeySeven, '7', '7', 0, 0, EFI_HOME_MODIFIER, EFI_AFFECTED_BY_STANDARD_SHIFT | EFI_AFFECTED_BY_NUM_LOCK},\r
+ {EfiKeyEight, '8', '8', 0, 0, EFI_UP_ARROW_MODIFIER, EFI_AFFECTED_BY_STANDARD_SHIFT | EFI_AFFECTED_BY_NUM_LOCK},\r
+ {EfiKeyNine, '9', '9', 0, 0, EFI_PAGE_UP_MODIFIER, EFI_AFFECTED_BY_STANDARD_SHIFT | EFI_AFFECTED_BY_NUM_LOCK},\r
+ {EfiKeyZero, '0', '0', 0, 0, EFI_INSERT_MODIFIER, EFI_AFFECTED_BY_STANDARD_SHIFT | EFI_AFFECTED_BY_NUM_LOCK},\r
+ {EfiKeyPeriod, '.', '.', 0, 0, EFI_DELETE_MODIFIER, EFI_AFFECTED_BY_STANDARD_SHIFT | EFI_AFFECTED_BY_NUM_LOCK},\r
+ {EfiKeyA4, 0x00, 0x00, 0, 0, EFI_MENU_MODIFIER, 0},\r
+ {EfiKeyLCtrl, 0, 0, 0, 0, EFI_LEFT_CONTROL_MODIFIER, 0},\r
+ {EfiKeyLShift, 0, 0, 0, 0, EFI_LEFT_SHIFT_MODIFIER, 0},\r
+ {EfiKeyLAlt, 0, 0, 0, 0, EFI_LEFT_ALT_MODIFIER, 0},\r
+ {EfiKeyA0, 0, 0, 0, 0, EFI_LEFT_LOGO_MODIFIER, 0},\r
+ {EfiKeyRCtrl, 0, 0, 0, 0, EFI_RIGHT_CONTROL_MODIFIER, 0},\r
+ {EfiKeyRShift, 0, 0, 0, 0, EFI_RIGHT_SHIFT_MODIFIER, 0},\r
+ {EfiKeyA2, 0, 0, 0, 0, EFI_RIGHT_ALT_MODIFIER, 0},\r
+ {EfiKeyA3, 0, 0, 0, 0, EFI_RIGHT_LOGO_MODIFIER, 0},\r
+ },\r
+ 1, // DescriptionCount\r
+ {'e', 'n', '-', 'U', 'S'}, // RFC4646 language code\r
+ ' ', // Space\r
+ {'E', 'n', 'g', 'l', 'i', 's', 'h', ' ', 'K', 'e', 'y', 'b', 'o', 'a', 'r', 'd', '\0'}, // DescriptionString[]\r
+};\r
\r
//\r
-// EFI_KEY to USB Scan Code convertion table\r
+// EFI_KEY to USB Keycode conversion table\r
+// EFI_KEY is defined in UEFI spec.\r
+// USB Keycode is defined in USB HID Firmware spec.\r
//\r
-UINT8 UsbScanCodeConvertionTable[] = {\r
+UINT8 EfiKeyToUsbKeyCodeConvertionTable[] = {\r
0xe0, // EfiKeyLCtrl\r
0xe3, // EfiKeyA0\r
0xe2, // EfiKeyLAlt\r
};\r
\r
//\r
-// Keyboard Layout Modifier to EFI Scan Code convertion table\r
+// Keyboard modifier value to EFI Scan Code convertion table\r
+// EFI Scan Code and the modifier values are defined in UEFI spec.\r
//\r
-UINT8 EfiScanCodeConvertionTable[] = {\r
+UINT8 ModifierValueToEfiScanCodeConvertionTable[] = {\r
SCAN_NULL, // EFI_NULL_MODIFIER\r
SCAN_NULL, // EFI_LEFT_CONTROL_MODIFIER\r
SCAN_NULL, // EFI_RIGHT_CONTROL_MODIFIER\r
SCAN_F12, // EFI_FUNCTION_KEY_TWELVE_MODIFIER\r
};\r
\r
-EFI_GUID mKeyboardLayoutEventGuid = EFI_HII_SET_KEYBOARD_LAYOUT_EVENT_GUID;\r
+/**\r
+ Initialize Key Convention Table by using default keyboard layout.\r
+\r
+ @param UsbKeyboardDevice The USB_KB_DEV instance.\r
\r
+ @retval EFI_SUCCESS The default keyboard layout was installed successfully\r
+ @retval Others Failure to install default keyboard layout.\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+InstallDefaultKeyboardLayout (\r
+ IN OUT USB_KB_DEV *UsbKeyboardDevice\r
+ )\r
+{\r
+ EFI_STATUS Status;\r
+ EFI_HII_DATABASE_PROTOCOL *HiiDatabase;\r
+ EFI_HII_HANDLE HiiHandle;\r
\r
-KB_MODIFIER KB_Mod[8] = {\r
- { MOD_CONTROL_L, 0xe0 }, // 11100000\r
- { MOD_CONTROL_R, 0xe4 }, // 11100100\r
- { MOD_SHIFT_L, 0xe1 }, // 11100001\r
- { MOD_SHIFT_R, 0xe5 }, // 11100101\r
- { MOD_ALT_L, 0xe2 }, // 11100010\r
- { MOD_ALT_R, 0xe6 }, // 11100110\r
- { MOD_WIN_L, 0xe3 }, // 11100011\r
- { MOD_WIN_R, 0xe7 }, // 11100111 \r
-};\r
+ //\r
+ // Locate Hii database protocol\r
+ //\r
+ Status = gBS->LocateProtocol (\r
+ &gEfiHiiDatabaseProtocolGuid,\r
+ NULL,\r
+ (VOID **) &HiiDatabase\r
+ );\r
+ if (EFI_ERROR (Status)) {\r
+ return Status;\r
+ }\r
\r
+ //\r
+ // Install Keyboard Layout package to HII database\r
+ //\r
+ HiiHandle = HiiAddPackages (\r
+ &mUsbKeyboardLayoutPackageGuid,\r
+ UsbKeyboardDevice->ControllerHandle,\r
+ &mUsbKeyboardLayoutBin,\r
+ NULL\r
+ );\r
+ if (HiiHandle == NULL) {\r
+ return EFI_OUT_OF_RESOURCES;\r
+ }\r
+\r
+ //\r
+ // Set current keyboard layout\r
+ //\r
+ Status = HiiDatabase->SetKeyboardLayout (HiiDatabase, &mUsbKeyboardLayoutKeyGuid);\r
+\r
+ return Status;\r
+}\r
\r
\r
/**\r
- Uses USB I/O to check whether the device is a USB Keyboard device.\r
+ Uses USB I/O to check whether the device is a USB keyboard device.\r
\r
- @param UsbIo Points to a USB I/O protocol instance.\r
- @retval None\r
+ @param UsbIo Pointer to a USB I/O protocol instance.\r
+\r
+ @retval TRUE Device is a USB keyboard device.\r
+ @retval FALSE Device is a not USB keyboard device.\r
\r
**/\r
BOOLEAN\r
EFI_USB_INTERFACE_DESCRIPTOR InterfaceDescriptor;\r
\r
//\r
- // Get the Default interface descriptor, currently we\r
- // assume it is interface 1\r
+ // Get the default interface descriptor\r
//\r
Status = UsbIo->UsbGetInterfaceDescriptor (\r
UsbIo,\r
InterfaceDescriptor.InterfaceSubClass == SUBCLASS_BOOT &&\r
InterfaceDescriptor.InterfaceProtocol == PROTOCOL_KEYBOARD\r
) {\r
-\r
return TRUE;\r
}\r
\r
/**\r
Get current keyboard layout from HII database.\r
\r
- @retval Pointer to EFI_HII_KEYBOARD_LAYOUT.\r
+ @return Pointer to HII Keyboard Layout.\r
+ NULL means failure occurred while trying to get keyboard layout.\r
\r
**/\r
EFI_HII_KEYBOARD_LAYOUT *\r
UINT16 Length;\r
\r
//\r
- // Locate Hii database protocol\r
+ // Locate HII Database Protocol\r
//\r
Status = gBS->LocateProtocol (\r
&gEfiHiiDatabaseProtocolGuid,\r
KeyboardLayout\r
);\r
if (EFI_ERROR (Status)) {\r
- gBS->FreePool (KeyboardLayout);\r
+ FreePool (KeyboardLayout);\r
KeyboardLayout = NULL;\r
}\r
}\r
}\r
\r
/**\r
- Find Key Descriptor in KeyConvertionTable given its scan code.\r
+ Find Key Descriptor in Key Convertion Table given its USB keycode.\r
\r
@param UsbKeyboardDevice The USB_KB_DEV instance.\r
- @param ScanCode USB scan code.\r
+ @param KeyCode USB Keycode.\r
\r
- @return The Key descriptor in KeyConvertionTable.\r
+ @return The Key Descriptor in Key Convertion Table.\r
+ NULL means not found.\r
\r
**/\r
EFI_KEY_DESCRIPTOR *\r
EFIAPI\r
GetKeyDescriptor (\r
IN USB_KB_DEV *UsbKeyboardDevice,\r
- IN UINT8 ScanCode\r
+ IN UINT8 KeyCode\r
)\r
{\r
UINT8 Index;\r
\r
- if (((ScanCode > 0x65) && (ScanCode < 0xe0)) || (ScanCode > 0xe7)) {\r
+ //\r
+ // Make sure KeyCode is in the range of [0x4, 0x65] or [0xe0, 0xe7]\r
+ //\r
+ if ((!USBKBD_VALID_KEYCODE (KeyCode)) || ((KeyCode > 0x65) && (KeyCode < 0xe0)) || (KeyCode > 0xe7)) {\r
return NULL;\r
}\r
\r
- if (ScanCode <= 0x65) {\r
- Index = (UINT8) (ScanCode - 4);\r
+ //\r
+ // Calculate the index of Key Descriptor in Key Convertion Table\r
+ //\r
+ if (KeyCode <= 0x65) {\r
+ Index = (UINT8) (KeyCode - 4);\r
} else {\r
- Index = (UINT8) (ScanCode - 0xe0 + USB_KEYCODE_MAX_MAKE);\r
+ Index = (UINT8) (KeyCode - 0xe0 + NUMBER_OF_VALID_NON_MODIFIER_USB_KEYCODE);\r
}\r
\r
return &UsbKeyboardDevice->KeyConvertionTable[Index];\r
}\r
\r
/**\r
- Find Non-Spacing key for given KeyDescriptor.\r
+ Find Non-Spacing key for given Key descriptor.\r
\r
@param UsbKeyboardDevice The USB_KB_DEV instance.\r
@param KeyDescriptor Key descriptor.\r
\r
- @retval NULL Key list is empty.\r
- @return Other The Non-Spacing key.\r
+ @return The Non-Spacing key corresponding to KeyDescriptor\r
+ NULL means not found.\r
\r
**/\r
USB_NS_KEY *\r
)\r
{\r
LIST_ENTRY *Link;\r
+ LIST_ENTRY *NsKeyList;\r
USB_NS_KEY *UsbNsKey;\r
-\r
- Link = GetFirstNode (&UsbKeyboardDevice->NsKeyList);\r
- while (!IsNull (&UsbKeyboardDevice->NsKeyList, Link)) {\r
+ \r
+ NsKeyList = &UsbKeyboardDevice->NsKeyList;\r
+ Link = GetFirstNode (NsKeyList);\r
+ while (!IsNull (NsKeyList, Link)) {\r
UsbNsKey = USB_NS_KEY_FORM_FROM_LINK (Link);\r
\r
if (UsbNsKey->NsKey[0].Key == KeyDescriptor->Key) {\r
return UsbNsKey;\r
}\r
\r
- Link = GetNextNode (&UsbKeyboardDevice->NsKeyList, Link);\r
+ Link = GetNextNode (NsKeyList, Link);\r
}\r
\r
return NULL;\r
}\r
\r
/**\r
- Find physical key definition for a given Key stroke.\r
+ Find physical key definition for a given key descriptor.\r
\r
- @param UsbNsKey The Non-Spacing key information.\r
- @param KeyDescriptor The key stroke.\r
+ For a specified non-spacing key, there are a list of physical\r
+ keys following it. This function traverses the list of\r
+ physical keys and tries to find the physical key matching\r
+ the KeyDescriptor.\r
+\r
+ @param UsbNsKey The non-spacing key information.\r
+ @param KeyDescriptor The key descriptor.\r
\r
@return The physical key definition.\r
+ If no physical key is found, parameter KeyDescriptor is returned.\r
\r
**/\r
EFI_KEY_DESCRIPTOR *\r
}\r
\r
/**\r
- The notification function for SET_KEYBOARD_LAYOUT_EVENT.\r
+ The notification function for EFI_HII_SET_KEYBOARD_LAYOUT_EVENT_GUID.\r
+\r
+ This function is registered to event of EFI_HII_SET_KEYBOARD_LAYOUT_EVENT_GUID\r
+ group type, which will be triggered by EFI_HII_DATABASE_PROTOCOL.SetKeyboardLayout().\r
+ It tries to get curent keyboard layout from HII database.\r
\r
- @param Event The instance of EFI_EVENT.\r
- @param Context passing parameter.\r
+ @param Event Event being signaled.\r
+ @param Context Points to USB_KB_DEV instance.\r
\r
**/\r
VOID\r
EFIAPI\r
SetKeyboardLayoutEvent (\r
- EFI_EVENT Event,\r
- VOID *Context\r
+ IN EFI_EVENT Event,\r
+ IN VOID *Context\r
)\r
{\r
USB_KB_DEV *UsbKeyboardDevice;\r
UINTN Index;\r
UINTN Index2;\r
UINTN KeyCount;\r
- UINT8 ScanCode;\r
+ UINT8 KeyCode;\r
\r
UsbKeyboardDevice = (USB_KB_DEV *) Context;\r
\r
//\r
- // Try to get current Keyboard Layout from HII database\r
+ // Try to get current keyboard layout from HII database\r
//\r
KeyboardLayout = GetCurrentKeyboardLayout ();\r
if (KeyboardLayout == NULL) {\r
}\r
\r
//\r
- // Allocate resource for KeyConvertionTable\r
+ // Re-allocate resource for KeyConvertionTable\r
//\r
ReleaseKeyboardLayoutResources (UsbKeyboardDevice);\r
- UsbKeyboardDevice->KeyConvertionTable = AllocateZeroPool ((USB_KEYCODE_MAX_MAKE + 8) * sizeof (EFI_KEY_DESCRIPTOR));\r
+ UsbKeyboardDevice->KeyConvertionTable = AllocateZeroPool ((NUMBER_OF_VALID_USB_KEYCODE) * sizeof (EFI_KEY_DESCRIPTOR));\r
ASSERT (UsbKeyboardDevice->KeyConvertionTable != NULL);\r
\r
+ //\r
+ // Traverse the list of key descriptors following the header of EFI_HII_KEYBOARD_LAYOUT\r
+ //\r
KeyDescriptor = (EFI_KEY_DESCRIPTOR *) (((UINT8 *) KeyboardLayout) + sizeof (EFI_HII_KEYBOARD_LAYOUT));\r
for (Index = 0; Index < KeyboardLayout->DescriptorCount; Index++) {\r
//\r
CopyMem (&TempKey, KeyDescriptor, sizeof (EFI_KEY_DESCRIPTOR));\r
\r
//\r
- // Fill the key into KeyConvertionTable (which use USB Scan Code as index)\r
+ // Fill the key into KeyConvertionTable, whose index is calculated from USB keycode.\r
//\r
- ScanCode = UsbScanCodeConvertionTable [(UINT8) (TempKey.Key)];\r
- TableEntry = GetKeyDescriptor (UsbKeyboardDevice, ScanCode);\r
+ KeyCode = EfiKeyToUsbKeyCodeConvertionTable [(UINT8) (TempKey.Key)];\r
+ TableEntry = GetKeyDescriptor (UsbKeyboardDevice, KeyCode);\r
CopyMem (TableEntry, KeyDescriptor, sizeof (EFI_KEY_DESCRIPTOR));\r
\r
+ //\r
+ // For non-spacing key, create the list with a non-spacing key followed by physical keys.\r
+ //\r
if (TempKey.Modifier == EFI_NS_KEY_MODIFIER) {\r
- //\r
- // Non-spacing key\r
- //\r
UsbNsKey = AllocatePool (sizeof (USB_NS_KEY));\r
ASSERT (UsbNsKey != NULL);\r
\r
NsKey = KeyDescriptor + 1;\r
for (Index2 = Index + 1; Index2 < KeyboardLayout->DescriptorCount; Index2++) {\r
CopyMem (&TempKey, NsKey, sizeof (EFI_KEY_DESCRIPTOR));\r
- if (TempKey.Modifier & EFI_NS_KEY_DEPENDENCY_MODIFIER) {\r
+ if (TempKey.Modifier == EFI_NS_KEY_DEPENDENCY_MODIFIER) {\r
KeyCount++;\r
} else {\r
break;\r
}\r
\r
//\r
- // There are two EfiKeyEnter, duplicate its Key Descriptor\r
+ // There are two EfiKeyEnter, duplicate its key descriptor\r
//\r
TableEntry = GetKeyDescriptor (UsbKeyboardDevice, 0x58);\r
KeyDescriptor = GetKeyDescriptor (UsbKeyboardDevice, 0x28);\r
CopyMem (TableEntry, KeyDescriptor, sizeof (EFI_KEY_DESCRIPTOR));\r
\r
- gBS->FreePool (KeyboardLayout);\r
+ FreePool (KeyboardLayout);\r
}\r
\r
/**\r
- Destroy resources for Keyboard layout.\r
+ Destroy resources for keyboard layout.\r
\r
@param UsbKeyboardDevice The USB_KB_DEV instance.\r
\r
VOID\r
EFIAPI\r
ReleaseKeyboardLayoutResources (\r
- IN USB_KB_DEV *UsbKeyboardDevice\r
+ IN OUT USB_KB_DEV *UsbKeyboardDevice\r
)\r
{\r
USB_NS_KEY *UsbNsKey;\r
}\r
\r
/**\r
- Initialize USB Keyboard layout.\r
+ Initialize USB keyboard layout.\r
+\r
+ This function initializes Key Convertion Table for the USB keyboard device.\r
+ It first tries to retrieve layout from HII database. If failed and default\r
+ layout is enabled, then it just uses the default layout.\r
\r
@param UsbKeyboardDevice The USB_KB_DEV instance.\r
\r
- @retval EFI_SUCCESS Initialization Success.\r
- @retval Other Keyboard layout initial failed.\r
+ @retval EFI_SUCCESS Initialization succeeded.\r
+ @retval EFI_NOT_READY Keyboard layout cannot be retrieve from HII\r
+ database, and default layout is disabled.\r
+ @retval Other Fail to register event to EFI_HII_SET_KEYBOARD_LAYOUT_EVENT_GUID group.\r
\r
**/\r
EFI_STATUS\r
EFIAPI\r
InitKeyboardLayout (\r
- IN USB_KB_DEV *UsbKeyboardDevice\r
+ OUT USB_KB_DEV *UsbKeyboardDevice\r
)\r
{\r
EFI_HII_KEYBOARD_LAYOUT *KeyboardLayout;\r
EFI_STATUS Status;\r
\r
- UsbKeyboardDevice->KeyConvertionTable = AllocateZeroPool ((USB_KEYCODE_MAX_MAKE + 8) * sizeof (EFI_KEY_DESCRIPTOR));\r
+ UsbKeyboardDevice->KeyConvertionTable = AllocateZeroPool ((NUMBER_OF_VALID_USB_KEYCODE) * sizeof (EFI_KEY_DESCRIPTOR));\r
ASSERT (UsbKeyboardDevice->KeyConvertionTable != NULL);\r
\r
InitializeListHead (&UsbKeyboardDevice->NsKeyList);\r
UsbKeyboardDevice->KeyboardLayoutEvent = NULL;\r
\r
//\r
- // Register SET_KEYBOARD_LAYOUT_EVENT notification\r
+ // Register event to EFI_HII_SET_KEYBOARD_LAYOUT_EVENT_GUID group,\r
+ // which will be triggered by EFI_HII_DATABASE_PROTOCOL.SetKeyboardLayout().\r
//\r
Status = gBS->CreateEventEx (\r
EVT_NOTIFY_SIGNAL,\r
TPL_NOTIFY,\r
SetKeyboardLayoutEvent,\r
UsbKeyboardDevice,\r
- &mKeyboardLayoutEventGuid,\r
+ &gEfiHiiKeyBoardLayoutGuid,\r
&UsbKeyboardDevice->KeyboardLayoutEvent\r
);\r
if (EFI_ERROR (Status)) {\r
return Status;\r
}\r
\r
- //\r
- // Try to get current keyboard layout from HII database\r
- //\r
KeyboardLayout = GetCurrentKeyboardLayout ();\r
if (KeyboardLayout != NULL) {\r
//\r
- // Force to initialize the keyboard layout\r
+ // If current keyboard layout is successfully retrieved from HII database,\r
+ // force to initialize the keyboard layout.\r
//\r
gBS->SignalEvent (UsbKeyboardDevice->KeyboardLayoutEvent);\r
} else {\r
if (FeaturePcdGet (PcdDisableDefaultKeyboardLayoutInUsbKbDriver)) {\r
- return EFI_NOT_READY;\r
- } else {\r
-\r
//\r
- // Fail to get keyboard layout from HII database,\r
- // use default keyboard layout\r
+ // If no keyboard layout can be retrieved from HII database, and default layout\r
+ // is disabled, then return EFI_NOT_READY.\r
//\r
- LoadDefaultKeyboardLayout (UsbKeyboardDevice);\r
+ return EFI_NOT_READY;\r
}\r
+ //\r
+ // If no keyboard layout can be retrieved from HII database, and default layout\r
+ // is enabled, then load the default keyboard layout.\r
+ //\r
+ InstallDefaultKeyboardLayout (UsbKeyboardDevice);\r
}\r
\r
return EFI_SUCCESS;\r
\r
\r
/**\r
- Initialize USB Keyboard device and all private data structures.\r
+ Initialize USB keyboard device and all private data structures.\r
\r
@param UsbKeyboardDevice The USB_KB_DEV instance.\r
\r
@retval EFI_SUCCESS Initialization is successful.\r
- @retval EFI_DEVICE_ERROR Configure hardware failed.\r
+ @retval EFI_DEVICE_ERROR Keyboard initialization failed.\r
\r
**/\r
EFI_STATUS\r
EFIAPI\r
InitUSBKeyboard (\r
- IN USB_KB_DEV *UsbKeyboardDevice\r
+ IN OUT USB_KB_DEV *UsbKeyboardDevice\r
)\r
{\r
UINT8 ConfigValue;\r
EFI_STATUS Status;\r
UINT32 TransferResult;\r
\r
- KbdReportStatusCode (\r
- UsbKeyboardDevice->DevicePath,\r
+ REPORT_STATUS_CODE_WITH_DEVICE_PATH (\r
EFI_PROGRESS_CODE,\r
- PcdGet32 (PcdStatusCodeValueKeyboardSelfTest)\r
+ PcdGet32 (PcdStatusCodeValueKeyboardSelfTest),\r
+ UsbKeyboardDevice->DevicePath\r
);\r
\r
InitUSBKeyBuffer (&(UsbKeyboardDevice->KeyboardBuffer));\r
\r
//\r
- // default configurations\r
+ // Uses default configuration to configure the USB keyboard device.\r
//\r
ConfigValue = 0x01;\r
-\r
- //\r
- // Uses default configuration to configure the USB Keyboard device.\r
- //\r
Status = UsbSetConfiguration (\r
- UsbKeyboardDevice->UsbIo,\r
- (UINT16) ConfigValue,\r
- &TransferResult\r
- );\r
+ UsbKeyboardDevice->UsbIo,\r
+ (UINT16) ConfigValue,\r
+ &TransferResult\r
+ );\r
if (EFI_ERROR (Status)) {\r
//\r
// If configuration could not be set here, it means\r
// the keyboard interface has some errors and could\r
// not be initialized\r
//\r
- KbdReportStatusCode (\r
- UsbKeyboardDevice->DevicePath,\r
+ REPORT_STATUS_CODE_WITH_DEVICE_PATH (\r
EFI_ERROR_CODE | EFI_ERROR_MINOR,\r
- PcdGet32 (PcdStatusCodeValueKeyboardInterfaceError)\r
+ PcdGet32 (PcdStatusCodeValueKeyboardInterfaceError),\r
+ UsbKeyboardDevice->DevicePath\r
);\r
\r
return EFI_DEVICE_ERROR;\r
&Protocol\r
);\r
//\r
- // Sets boot protocol for the USB Keyboard.\r
+ // Set boot protocol for the USB Keyboard.\r
// This driver only supports boot protocol.\r
- // !!BugBug: How about the device that does not support boot protocol?\r
//\r
if (Protocol != BOOT_PROTOCOL) {\r
UsbSetProtocolRequest (\r
BOOT_PROTOCOL\r
);\r
}\r
- //\r
- // the duration is indefinite, so the endpoint will inhibit reporting forever,\r
- // and only reporting when a change is detected in the report data.\r
- //\r
\r
//\r
- // idle value for all report ID\r
+ // ReportId is zero, which means the idle rate applies to all input reports.\r
//\r
ReportId = 0;\r
//\r
- // idle forever until there is a key pressed and released.\r
+ // Duration is zero, which means the duration is infinite.\r
+ // so the endpoint will inhibit reporting forever,\r
+ // and only reporting when a change is detected in the report data.\r
//\r
Duration = 0;\r
UsbSetIdleRequest (\r
Duration\r
);\r
\r
- UsbKeyboardDevice->CtrlOn = 0;\r
- UsbKeyboardDevice->AltOn = 0;\r
- UsbKeyboardDevice->ShiftOn = 0;\r
- UsbKeyboardDevice->NumLockOn = 0;\r
- UsbKeyboardDevice->CapsOn = 0;\r
- UsbKeyboardDevice->ScrollOn = 0;\r
+ UsbKeyboardDevice->CtrlOn = FALSE;\r
+ UsbKeyboardDevice->AltOn = FALSE;\r
+ UsbKeyboardDevice->ShiftOn = FALSE;\r
+ UsbKeyboardDevice->NumLockOn = FALSE;\r
+ UsbKeyboardDevice->CapsOn = FALSE;\r
+ UsbKeyboardDevice->ScrollOn = FALSE;\r
\r
- UsbKeyboardDevice->LeftCtrlOn = 0;\r
- UsbKeyboardDevice->LeftAltOn = 0;\r
- UsbKeyboardDevice->LeftShiftOn = 0;\r
- UsbKeyboardDevice->LeftLogoOn = 0;\r
- UsbKeyboardDevice->RightCtrlOn = 0;\r
- UsbKeyboardDevice->RightAltOn = 0;\r
- UsbKeyboardDevice->RightShiftOn = 0;\r
- UsbKeyboardDevice->RightLogoOn = 0;\r
- UsbKeyboardDevice->MenuKeyOn = 0;\r
- UsbKeyboardDevice->SysReqOn = 0;\r
-\r
- UsbKeyboardDevice->AltGrOn = 0;\r
+ UsbKeyboardDevice->LeftCtrlOn = FALSE;\r
+ UsbKeyboardDevice->LeftAltOn = FALSE;\r
+ UsbKeyboardDevice->LeftShiftOn = FALSE;\r
+ UsbKeyboardDevice->LeftLogoOn = FALSE;\r
+ UsbKeyboardDevice->RightCtrlOn = FALSE;\r
+ UsbKeyboardDevice->RightAltOn = FALSE;\r
+ UsbKeyboardDevice->RightShiftOn = FALSE;\r
+ UsbKeyboardDevice->RightLogoOn = FALSE;\r
+ UsbKeyboardDevice->MenuKeyOn = FALSE;\r
+ UsbKeyboardDevice->SysReqOn = FALSE;\r
+\r
+ UsbKeyboardDevice->AltGrOn = FALSE;\r
\r
UsbKeyboardDevice->CurrentNsKey = NULL;\r
\r
//\r
- // Sync the initial state of lights\r
+ // Sync the initial state of lights on keyboard.\r
//\r
SetKeyLED (UsbKeyboardDevice);\r
\r
ZeroMem (UsbKeyboardDevice->LastKeyCodeArray, sizeof (UINT8) * 8);\r
\r
//\r
- // Set a timer for repeat keys' generation.\r
+ // Create event for repeat keys' generation.\r
//\r
if (UsbKeyboardDevice->RepeatTimer != NULL) {\r
gBS->CloseEvent (UsbKeyboardDevice->RepeatTimer);\r
- UsbKeyboardDevice->RepeatTimer = 0;\r
+ UsbKeyboardDevice->RepeatTimer = NULL;\r
}\r
\r
- Status = gBS->CreateEvent (\r
- EVT_TIMER | EVT_NOTIFY_SIGNAL,\r
- TPL_NOTIFY,\r
- USBKeyboardRepeatHandler,\r
- UsbKeyboardDevice,\r
- &UsbKeyboardDevice->RepeatTimer\r
- );\r
+ gBS->CreateEvent (\r
+ EVT_TIMER | EVT_NOTIFY_SIGNAL,\r
+ TPL_NOTIFY,\r
+ USBKeyboardRepeatHandler,\r
+ UsbKeyboardDevice,\r
+ &UsbKeyboardDevice->RepeatTimer\r
+ );\r
\r
+ //\r
+ // Create event for delayed recovery, which deals with device error.\r
+ //\r
if (UsbKeyboardDevice->DelayedRecoveryEvent != NULL) {\r
gBS->CloseEvent (UsbKeyboardDevice->DelayedRecoveryEvent);\r
- UsbKeyboardDevice->DelayedRecoveryEvent = 0;\r
+ UsbKeyboardDevice->DelayedRecoveryEvent = NULL;\r
}\r
\r
- Status = gBS->CreateEvent (\r
- EVT_TIMER | EVT_NOTIFY_SIGNAL,\r
- TPL_NOTIFY,\r
- USBKeyboardRecoveryHandler,\r
- UsbKeyboardDevice,\r
- &UsbKeyboardDevice->DelayedRecoveryEvent\r
- );\r
+ gBS->CreateEvent (\r
+ EVT_TIMER | EVT_NOTIFY_SIGNAL,\r
+ TPL_NOTIFY,\r
+ USBKeyboardRecoveryHandler,\r
+ UsbKeyboardDevice,\r
+ &UsbKeyboardDevice->DelayedRecoveryEvent\r
+ );\r
\r
return EFI_SUCCESS;\r
}\r
\r
\r
/**\r
- Handler function for USB Keyboard's asynchronous interrupt transfer.\r
+ Handler function for USB keyboard's asynchronous interrupt transfer.\r
+\r
+ This function is the handler function for USB keyboard's asynchronous interrupt transfer\r
+ to manage the keyboard. It parses the USB keyboard input report, and inserts data to\r
+ keyboard buffer according to state of modifer keys and normal keys. Timer for repeat key\r
+ is also set accordingly.\r
\r
@param Data A pointer to a buffer that is filled with key data which is\r
retrieved via asynchronous interrupt transfer.\r
@param Context Pointing to USB_KB_DEV instance.\r
@param Result Indicates the result of the asynchronous interrupt transfer.\r
\r
- @retval EFI_SUCCESS Handler is successful.\r
- @retval EFI_DEVICE_ERROR Hardware Error\r
+ @retval EFI_SUCCESS Asynchronous interrupt transfer is handled successfully.\r
+ @retval EFI_DEVICE_ERROR Hardware error occurs.\r
\r
**/\r
EFI_STATUS\r
UINT8 *OldKeyCodeBuffer;\r
UINT8 CurModifierMap;\r
UINT8 OldModifierMap;\r
+ UINT8 Mask;\r
UINT8 Index;\r
UINT8 Index2;\r
BOOLEAN Down;\r
UINT32 UsbStatus;\r
EFI_KEY_DESCRIPTOR *KeyDescriptor;\r
\r
- ASSERT (Context);\r
+ ASSERT (Context != NULL);\r
\r
NewRepeatKey = 0;\r
UsbKeyboardDevice = (USB_KB_DEV *) Context;\r
UsbIo = UsbKeyboardDevice->UsbIo;\r
\r
//\r
- // Analyzes the Result and performs corresponding action.\r
+ // Analyzes Result and performs corresponding action.\r
//\r
if (Result != EFI_USB_NOERROR) {\r
//\r
// Some errors happen during the process\r
//\r
- KbdReportStatusCode (\r
- UsbKeyboardDevice->DevicePath,\r
+ REPORT_STATUS_CODE_WITH_DEVICE_PATH (\r
EFI_ERROR_CODE | EFI_ERROR_MINOR,\r
- PcdGet32 (PcdStatusCodeValueKeyboardInputError)\r
+ PcdGet32 (PcdStatusCodeValueKeyboardInputError),\r
+ UsbKeyboardDevice->DevicePath\r
);\r
\r
//\r
- // stop the repeat key generation if any\r
+ // Stop the repeat key generation if any\r
//\r
UsbKeyboardDevice->RepeatKey = 0;\r
\r
\r
//\r
// Delete & Submit this interrupt again\r
+ // Handler of DelayedRecoveryEvent triggered by timer will re-submit the interrupt. \r
//\r
-\r
UsbIo->UsbAsyncInterruptTransfer (\r
- UsbIo,\r
- UsbKeyboardDevice->IntEndpointDescriptor.EndpointAddress,\r
- FALSE,\r
- 0,\r
- 0,\r
- NULL,\r
- NULL\r
- );\r
-\r
+ UsbIo,\r
+ UsbKeyboardDevice->IntEndpointDescriptor.EndpointAddress,\r
+ FALSE,\r
+ 0,\r
+ 0,\r
+ NULL,\r
+ NULL\r
+ );\r
+ //\r
+ // EFI_USB_INTERRUPT_DELAY is defined in USB standard for error handling.\r
+ //\r
gBS->SetTimer (\r
- UsbKeyboardDevice->DelayedRecoveryEvent,\r
- TimerRelative,\r
- EFI_USB_INTERRUPT_DELAY\r
- );\r
+ UsbKeyboardDevice->DelayedRecoveryEvent,\r
+ TimerRelative,\r
+ EFI_USB_INTERRUPT_DELAY\r
+ );\r
\r
return EFI_DEVICE_ERROR;\r
}\r
\r
+ //\r
+ // If no error and no data, just return EFI_SUCCESS.\r
+ //\r
if (DataLength == 0 || Data == NULL) {\r
return EFI_SUCCESS;\r
}\r
\r
+ //\r
+ // Following code checks current keyboard input report against old key code buffer.\r
+ // According to USB HID Firmware Specification, the report consists of 8 bytes.\r
+ // Byte 0 is map of Modifier keys.\r
+ // Byte 1 is reserved.\r
+ // Bytes 2 to 7 are keycodes.\r
+ //\r
CurKeyCodeBuffer = (UINT8 *) Data;\r
OldKeyCodeBuffer = UsbKeyboardDevice->LastKeyCodeArray;\r
\r
//\r
- // checks for new key stroke.\r
- // if no new key got, return immediately.\r
+ // Checks for new key stroke.\r
//\r
for (Index = 0; Index < 8; Index++) {\r
if (OldKeyCodeBuffer[Index] != CurKeyCodeBuffer[Index]) {\r
}\r
}\r
\r
+ //\r
+ // If no new key, return EFI_SUCCESS immediately.\r
+ //\r
if (Index == 8) {\r
return EFI_SUCCESS;\r
}\r
\r
//\r
- // Parse the modifier key\r
+ // Parse the modifier key, which is the first byte of keyboard input report.\r
//\r
CurModifierMap = CurKeyCodeBuffer[0];\r
OldModifierMap = OldKeyCodeBuffer[0];\r
\r
//\r
- // handle modifier key's pressing or releasing situation.\r
+ // Handle modifier key's pressing or releasing situation.\r
+ // According to USB HID Firmware spec, Byte 0 uses folloing map of Modifier keys:\r
+ // Bit0: Left Control, Keycode: 0xe0\r
+ // Bit1: Left Shift, Keycode: 0xe1\r
+ // Bit2: Left Alt, Keycode: 0xe2\r
+ // Bit3: Left GUI, Keycode: 0xe3\r
+ // Bit4: Right Control, Keycode: 0xe4\r
+ // Bit5: Right Shift, Keycode: 0xe5\r
+ // Bit6: Right Alt, Keycode: 0xe6\r
+ // Bit7: Right GUI, Keycode: 0xe7\r
//\r
for (Index = 0; Index < 8; Index++) {\r
-\r
- if ((CurModifierMap & KB_Mod[Index].Mask) != (OldModifierMap & KB_Mod[Index].Mask)) {\r
+ Mask = (UINT8) (1 << Index);\r
+ if ((CurModifierMap & Mask) != (OldModifierMap & Mask)) {\r
//\r
- // if current modifier key is up, then\r
- // CurModifierMap & KB_Mod[Index].Mask = 0;\r
- // otherwize it is a non-zero value.\r
- // Inserts the pressed modifier key into key buffer.\r
+ // If current modifier key is up, then CurModifierMap & Mask = 0;\r
+ // otherwise it is a non-zero value.\r
+ // Insert the changed modifier key into key buffer.\r
//\r
- Down = (UINT8) (CurModifierMap & KB_Mod[Index].Mask);\r
- InsertKeyCode (&(UsbKeyboardDevice->KeyboardBuffer), KB_Mod[Index].Key, Down);\r
+ Down = (BOOLEAN) ((CurModifierMap & Mask) != 0);\r
+ InsertKeyCode (&(UsbKeyboardDevice->KeyboardBuffer), (UINT8) (0xe0 + Index), Down);\r
}\r
}\r
\r
//\r
- // handle normal key's releasing situation\r
+ // Handle normal key's releasing situation\r
+ // Bytes 2 to 7 are for normal keycodes\r
//\r
KeyRelease = FALSE;\r
for (Index = 2; Index < 8; Index++) {\r
if (!USBKBD_VALID_KEYCODE (OldKeyCodeBuffer[Index])) {\r
continue;\r
}\r
-\r
+ //\r
+ // For any key in old keycode buffer, if it is not in current keycode buffer,\r
+ // then it is released. Otherwise, it is not released.\r
+ //\r
KeyRelease = TRUE;\r
for (Index2 = 2; Index2 < 8; Index2++) {\r
\r
InsertKeyCode (\r
&(UsbKeyboardDevice->KeyboardBuffer),\r
OldKeyCodeBuffer[Index],\r
- 0\r
+ FALSE\r
);\r
//\r
- // the original reapeat key is released.\r
+ // The original repeat key is released.\r
//\r
if (OldKeyCodeBuffer[Index] == UsbKeyboardDevice->RepeatKey) {\r
UsbKeyboardDevice->RepeatKey = 0;\r
}\r
\r
//\r
- // original repeat key is released, cancel the repeat timer\r
+ // If original repeat key is released, cancel the repeat timer\r
//\r
if (UsbKeyboardDevice->RepeatKey == 0) {\r
gBS->SetTimer (\r
- UsbKeyboardDevice->RepeatTimer,\r
- TimerCancel,\r
- USBKBD_REPEAT_RATE\r
- );\r
+ UsbKeyboardDevice->RepeatTimer,\r
+ TimerCancel,\r
+ USBKBD_REPEAT_RATE\r
+ );\r
}\r
\r
//\r
- // handle normal key's pressing situation\r
+ // Handle normal key's pressing situation\r
//\r
KeyPress = FALSE;\r
for (Index = 2; Index < 8; Index++) {\r
if (!USBKBD_VALID_KEYCODE (CurKeyCodeBuffer[Index])) {\r
continue;\r
}\r
-\r
+ //\r
+ // For any key in current keycode buffer, if it is not in old keycode buffer,\r
+ // then it is pressed. Otherwise, it is not pressed.\r
+ //\r
KeyPress = TRUE;\r
for (Index2 = 2; Index2 < 8; Index2++) {\r
\r
}\r
\r
if (KeyPress) {\r
- InsertKeyCode (&(UsbKeyboardDevice->KeyboardBuffer), CurKeyCodeBuffer[Index], 1);\r
+ InsertKeyCode (&(UsbKeyboardDevice->KeyboardBuffer), CurKeyCodeBuffer[Index], TRUE);\r
+\r
//\r
- // NumLock pressed or CapsLock pressed\r
+ // Handle repeat key\r
//\r
KeyDescriptor = GetKeyDescriptor (UsbKeyboardDevice, CurKeyCodeBuffer[Index]);\r
+ ASSERT (KeyDescriptor != NULL);\r
+\r
if (KeyDescriptor->Modifier == EFI_NUM_LOCK_MODIFIER || KeyDescriptor->Modifier == EFI_CAPS_LOCK_MODIFIER) {\r
+ //\r
+ // For NumLock or CapsLock pressed, there is no need to handle repeat key for them.\r
+ //\r
UsbKeyboardDevice->RepeatKey = 0;\r
} else {\r
- NewRepeatKey = CurKeyCodeBuffer[Index];\r
//\r
- // do not repeat the original repeated key\r
+ // Prepare new repeat key, and clear the original one.\r
//\r
+ NewRepeatKey = CurKeyCodeBuffer[Index];\r
UsbKeyboardDevice->RepeatKey = 0;\r
}\r
}\r
}\r
\r
//\r
- // Update LastKeycodeArray[] buffer in the\r
- // Usb Keyboard Device data structure.\r
+ // Update LastKeycodeArray buffer in the UsbKeyboardDevice data structure.\r
//\r
for (Index = 0; Index < 8; Index++) {\r
UsbKeyboardDevice->LastKeyCodeArray[Index] = CurKeyCodeBuffer[Index];\r
}\r
\r
//\r
- // pre-process KeyboardBuffer, pop out the ctrl,alt,del key in sequence\r
- // and judge whether it will invoke reset event.\r
+ // Pre-process KeyboardBuffer to check if Ctrl + Alt + Del is pressed.\r
//\r
- SavedTail = UsbKeyboardDevice->KeyboardBuffer.bTail;\r
- Index = UsbKeyboardDevice->KeyboardBuffer.bHead;\r
+ SavedTail = UsbKeyboardDevice->KeyboardBuffer.BufferTail;\r
+ Index = UsbKeyboardDevice->KeyboardBuffer.BufferHead;\r
while (Index != SavedTail) {\r
RemoveKeyCode (&(UsbKeyboardDevice->KeyboardBuffer), &UsbKey);\r
\r
KeyDescriptor = GetKeyDescriptor (UsbKeyboardDevice, UsbKey.KeyCode);\r
+ ASSERT (KeyDescriptor != NULL);\r
\r
switch (KeyDescriptor->Modifier) {\r
\r
case EFI_LEFT_CONTROL_MODIFIER:\r
case EFI_RIGHT_CONTROL_MODIFIER:\r
- if (UsbKey.Down != 0) {\r
- UsbKeyboardDevice->CtrlOn = 1;\r
+ if (UsbKey.Down) {\r
+ UsbKeyboardDevice->CtrlOn = TRUE;\r
} else {\r
- UsbKeyboardDevice->CtrlOn = 0;\r
+ UsbKeyboardDevice->CtrlOn = FALSE;\r
}\r
break;\r
\r
case EFI_LEFT_ALT_MODIFIER:\r
case EFI_RIGHT_ALT_MODIFIER:\r
- if (UsbKey.Down != 0) {\r
- UsbKeyboardDevice->AltOn = 1;\r
+ if (UsbKey.Down) {\r
+ UsbKeyboardDevice->AltOn = TRUE;\r
} else {\r
- UsbKeyboardDevice->AltOn = 0;\r
+ UsbKeyboardDevice->AltOn = FALSE;\r
}\r
break;\r
\r
case EFI_ALT_GR_MODIFIER:\r
- if (UsbKey.Down != 0) {\r
- UsbKeyboardDevice->AltGrOn = 1;\r
+ if (UsbKey.Down) {\r
+ UsbKeyboardDevice->AltGrOn = TRUE;\r
} else {\r
- UsbKeyboardDevice->AltGrOn = 0;\r
+ UsbKeyboardDevice->AltGrOn = FALSE;\r
}\r
break;\r
\r
//\r
- // Del Key Code\r
+ // For Del Key, check if Ctrl + Alt + Del occurs for reset.\r
//\r
case EFI_DELETE_MODIFIER:\r
- if (UsbKey.Down != 0) {\r
- if ((UsbKeyboardDevice->CtrlOn != 0) && (UsbKeyboardDevice->AltOn != 0)) {\r
+ if (UsbKey.Down) {\r
+ if ((UsbKeyboardDevice->CtrlOn) && (UsbKeyboardDevice->AltOn)) {\r
gRT->ResetSystem (EfiResetWarm, EFI_SUCCESS, 0, NULL);\r
}\r
}\r
}\r
\r
//\r
- // insert the key back to the buffer.\r
+ // Insert the key back to the buffer,\r
// so the key sequence will not be destroyed.\r
//\r
InsertKeyCode (\r
UsbKey.KeyCode,\r
UsbKey.Down\r
);\r
- Index = UsbKeyboardDevice->KeyboardBuffer.bHead;\r
+ Index = UsbKeyboardDevice->KeyboardBuffer.BufferHead;\r
\r
}\r
//\r
- // If have new key pressed, update the RepeatKey value, and set the\r
+ // If there is new key pressed, update the RepeatKey value, and set the\r
// timer to repeate delay timer\r
//\r
if (NewRepeatKey != 0) {\r
//\r
- // sets trigger time to "Repeat Delay Time",\r
+ // Sets trigger time to "Repeat Delay Time",\r
// to trigger the repeat timer when the key is hold long\r
// enough time.\r
//\r
gBS->SetTimer (\r
- UsbKeyboardDevice->RepeatTimer,\r
- TimerRelative,\r
- USBKBD_REPEAT_DELAY\r
- );\r
+ UsbKeyboardDevice->RepeatTimer,\r
+ TimerRelative,\r
+ USBKBD_REPEAT_DELAY\r
+ );\r
UsbKeyboardDevice->RepeatKey = NewRepeatKey;\r
}\r
\r
\r
\r
/**\r
- Retrieves a key character after parsing the raw data in keyboard buffer.\r
+ Retrieves a USB keycode after parsing the raw data in keyboard buffer.\r
+\r
+ This function parses keyboard buffer. It updates state of modifier key for\r
+ USB_KB_DEV instancem, and returns keycode for output.\r
\r
@param UsbKeyboardDevice The USB_KB_DEV instance.\r
- @param KeyChar Points to the Key character after key parsing.\r
+ @param KeyCode Pointer to the USB keycode for output.\r
\r
- @retval EFI_SUCCESS Parse key is successful.\r
- @retval EFI_NOT_READY Device is not ready.\r
+ @retval EFI_SUCCESS Keycode successfully parsed.\r
+ @retval EFI_NOT_READY Keyboard buffer is not ready for a valid keycode\r
\r
**/\r
EFI_STATUS\r
EFIAPI\r
USBParseKey (\r
IN OUT USB_KB_DEV *UsbKeyboardDevice,\r
- OUT UINT8 *KeyChar\r
+ OUT UINT8 *KeyCode\r
)\r
{\r
USB_KEY UsbKey;\r
EFI_KEY_DESCRIPTOR *KeyDescriptor;\r
\r
- *KeyChar = 0;\r
+ *KeyCode = 0;\r
\r
while (!IsUSBKeyboardBufferEmpty (&UsbKeyboardDevice->KeyboardBuffer)) {\r
//\r
- // pops one raw data off.\r
+ // Pops one raw data off.\r
//\r
RemoveKeyCode (&(UsbKeyboardDevice->KeyboardBuffer), &UsbKey);\r
\r
KeyDescriptor = GetKeyDescriptor (UsbKeyboardDevice, UsbKey.KeyCode);\r
- if (UsbKey.Down == 0) {\r
+ ASSERT (KeyDescriptor != NULL);\r
+\r
+ if (!UsbKey.Down) {\r
+ //\r
+ // Key is released.\r
+ //\r
switch (KeyDescriptor->Modifier) {\r
\r
//\r
- // CTRL release\r
+ // Ctrl release\r
//\r
case EFI_LEFT_CONTROL_MODIFIER:\r
- UsbKeyboardDevice->LeftCtrlOn = 0;\r
- UsbKeyboardDevice->CtrlOn = 0;\r
+ UsbKeyboardDevice->LeftCtrlOn = FALSE;\r
+ UsbKeyboardDevice->CtrlOn = FALSE;\r
break;\r
case EFI_RIGHT_CONTROL_MODIFIER:\r
- UsbKeyboardDevice->RightCtrlOn = 0;\r
- UsbKeyboardDevice->CtrlOn = 0;\r
+ UsbKeyboardDevice->RightCtrlOn = FALSE;\r
+ UsbKeyboardDevice->CtrlOn = FALSE;\r
break;\r
\r
//\r
// Shift release\r
//\r
case EFI_LEFT_SHIFT_MODIFIER:\r
- UsbKeyboardDevice->LeftShiftOn = 0;\r
- UsbKeyboardDevice->ShiftOn = 0;\r
+ UsbKeyboardDevice->LeftShiftOn = FALSE;\r
+ UsbKeyboardDevice->ShiftOn = FALSE;\r
break;\r
case EFI_RIGHT_SHIFT_MODIFIER:\r
- UsbKeyboardDevice->RightShiftOn = 0;\r
- UsbKeyboardDevice->ShiftOn = 0;\r
+ UsbKeyboardDevice->RightShiftOn = FALSE;\r
+ UsbKeyboardDevice->ShiftOn = FALSE;\r
break;\r
\r
//\r
// Alt release\r
//\r
case EFI_LEFT_ALT_MODIFIER:\r
- UsbKeyboardDevice->LeftAltOn = 0;\r
- UsbKeyboardDevice->AltOn = 0;\r
+ UsbKeyboardDevice->LeftAltOn = FALSE;\r
+ UsbKeyboardDevice->AltOn = FALSE;\r
break;\r
case EFI_RIGHT_ALT_MODIFIER:\r
- UsbKeyboardDevice->RightAltOn = 0;\r
- UsbKeyboardDevice->AltOn = 0;\r
+ UsbKeyboardDevice->RightAltOn = FALSE;\r
+ UsbKeyboardDevice->AltOn = FALSE;\r
break;\r
\r
//\r
// Left Logo release\r
//\r
case EFI_LEFT_LOGO_MODIFIER:\r
- UsbKeyboardDevice->LeftLogoOn = 0;\r
+ UsbKeyboardDevice->LeftLogoOn = FALSE;\r
break;\r
\r
//\r
// Right Logo release\r
//\r
case EFI_RIGHT_LOGO_MODIFIER:\r
- UsbKeyboardDevice->RightLogoOn = 0;\r
+ UsbKeyboardDevice->RightLogoOn = FALSE;\r
break;\r
\r
//\r
// Menu key release\r
//\r
case EFI_MENU_MODIFIER:\r
- UsbKeyboardDevice->MenuKeyOn = 0;\r
+ UsbKeyboardDevice->MenuKeyOn = FALSE;\r
break;\r
\r
//\r
//\r
case EFI_PRINT_MODIFIER:\r
case EFI_SYS_REQUEST_MODIFIER:\r
- UsbKeyboardDevice->SysReqOn = 0;\r
+ UsbKeyboardDevice->SysReqOn = FALSE;\r
break;\r
\r
//\r
// AltGr release\r
//\r
case EFI_ALT_GR_MODIFIER:\r
- UsbKeyboardDevice->AltGrOn = 0;\r
+ UsbKeyboardDevice->AltGrOn = FALSE;\r
break;\r
\r
default:\r
switch (KeyDescriptor->Modifier) {\r
\r
//\r
- // CTRL press\r
+ // Ctrl press\r
//\r
case EFI_LEFT_CONTROL_MODIFIER:\r
- UsbKeyboardDevice->LeftCtrlOn = 1;\r
- UsbKeyboardDevice->CtrlOn = 1;\r
+ UsbKeyboardDevice->LeftCtrlOn = TRUE;\r
+ UsbKeyboardDevice->CtrlOn = TRUE;\r
continue;\r
break;\r
case EFI_RIGHT_CONTROL_MODIFIER:\r
- UsbKeyboardDevice->RightCtrlOn = 1;\r
- UsbKeyboardDevice->CtrlOn = 1;\r
+ UsbKeyboardDevice->RightCtrlOn = TRUE;\r
+ UsbKeyboardDevice->CtrlOn = TRUE;\r
continue;\r
break;\r
\r
// Shift press\r
//\r
case EFI_LEFT_SHIFT_MODIFIER:\r
- UsbKeyboardDevice->LeftShiftOn = 1;\r
- UsbKeyboardDevice->ShiftOn = 1;\r
+ UsbKeyboardDevice->LeftShiftOn = TRUE;\r
+ UsbKeyboardDevice->ShiftOn = TRUE;\r
continue;\r
break;\r
case EFI_RIGHT_SHIFT_MODIFIER:\r
- UsbKeyboardDevice->RightShiftOn = 1;\r
- UsbKeyboardDevice->ShiftOn = 1;\r
+ UsbKeyboardDevice->RightShiftOn = TRUE;\r
+ UsbKeyboardDevice->ShiftOn = TRUE;\r
continue;\r
break;\r
\r
// Alt press\r
//\r
case EFI_LEFT_ALT_MODIFIER:\r
- UsbKeyboardDevice->LeftAltOn = 1;\r
- UsbKeyboardDevice->AltOn = 1;\r
+ UsbKeyboardDevice->LeftAltOn = TRUE;\r
+ UsbKeyboardDevice->AltOn = TRUE;\r
continue;\r
break;\r
case EFI_RIGHT_ALT_MODIFIER:\r
- UsbKeyboardDevice->RightAltOn = 1;\r
- UsbKeyboardDevice->AltOn = 1;\r
+ UsbKeyboardDevice->RightAltOn = TRUE;\r
+ UsbKeyboardDevice->AltOn = TRUE;\r
continue;\r
break;\r
\r
// Left Logo press\r
//\r
case EFI_LEFT_LOGO_MODIFIER:\r
- UsbKeyboardDevice->LeftLogoOn = 1;\r
+ UsbKeyboardDevice->LeftLogoOn = TRUE;\r
break;\r
\r
//\r
// Right Logo press\r
//\r
case EFI_RIGHT_LOGO_MODIFIER:\r
- UsbKeyboardDevice->RightLogoOn = 1;\r
+ UsbKeyboardDevice->RightLogoOn = TRUE;\r
break;\r
\r
//\r
// Menu key press\r
//\r
case EFI_MENU_MODIFIER:\r
- UsbKeyboardDevice->MenuKeyOn = 1;\r
+ UsbKeyboardDevice->MenuKeyOn = TRUE;\r
break;\r
\r
//\r
//\r
case EFI_PRINT_MODIFIER:\r
case EFI_SYS_REQUEST_MODIFIER:\r
- UsbKeyboardDevice->SysReqOn = 1;\r
+ UsbKeyboardDevice->SysReqOn = TRUE;\r
continue;\r
break;\r
\r
// AltGr press\r
//\r
case EFI_ALT_GR_MODIFIER:\r
- UsbKeyboardDevice->AltGrOn = 1;\r
+ UsbKeyboardDevice->AltGrOn = TRUE;\r
break;\r
\r
case EFI_NUM_LOCK_MODIFIER:\r
- UsbKeyboardDevice->NumLockOn ^= 1;\r
//\r
- // Turn on the NumLock light on KB\r
+ // Toggle NumLock\r
//\r
+ UsbKeyboardDevice->NumLockOn = (BOOLEAN) (!(UsbKeyboardDevice->NumLockOn));\r
SetKeyLED (UsbKeyboardDevice);\r
continue;\r
break;\r
\r
case EFI_CAPS_LOCK_MODIFIER:\r
- UsbKeyboardDevice->CapsOn ^= 1;\r
//\r
- // Turn on the CapsLock light on KB\r
+ // Toggle CapsLock\r
//\r
+ UsbKeyboardDevice->CapsOn = (BOOLEAN) (!(UsbKeyboardDevice->CapsOn));\r
SetKeyLED (UsbKeyboardDevice);\r
continue;\r
break;\r
\r
case EFI_SCROLL_LOCK_MODIFIER:\r
- UsbKeyboardDevice->ScrollOn ^= 1;\r
//\r
- // Turn on the ScrollLock light on KB\r
+ // Toggle ScrollLock\r
//\r
+ UsbKeyboardDevice->ScrollOn = (BOOLEAN) (!(UsbKeyboardDevice->ScrollOn));\r
SetKeyLED (UsbKeyboardDevice);\r
continue;\r
break;\r
\r
//\r
- // F11,F12,PrintScreen,Pause/Break\r
- // could not be retrieved via SimpleTxtInEx protocol\r
+ // PrintScreen, Pause/Break could not be retrieved via SimpleTextInEx protocol\r
//\r
- case EFI_FUNCTION_KEY_ELEVEN_MODIFIER:\r
- case EFI_FUNCTION_KEY_TWELVE_MODIFIER:\r
case EFI_PAUSE_MODIFIER:\r
case EFI_BREAK_MODIFIER:\r
//\r
- // fall through\r
+ // Fall through\r
//\r
continue;\r
break;\r
}\r
\r
//\r
- // When encountered Del Key...\r
+ // When encountering Ctrl + Alt + Del, then warm reset.\r
//\r
if (KeyDescriptor->Modifier == EFI_DELETE_MODIFIER) {\r
- if ((UsbKeyboardDevice->CtrlOn != 0) && (UsbKeyboardDevice->AltOn != 0)) {\r
+ if ((UsbKeyboardDevice->CtrlOn) && (UsbKeyboardDevice->AltOn)) {\r
gRT->ResetSystem (EfiResetWarm, EFI_SUCCESS, 0, NULL);\r
}\r
}\r
\r
- *KeyChar = UsbKey.KeyCode;\r
+ *KeyCode = UsbKey.KeyCode;\r
return EFI_SUCCESS;\r
}\r
\r
\r
\r
/**\r
- Converts USB Keyboard code to EFI Scan Code.\r
+ Converts USB Keycode ranging from 0x4 to 0x65 to EFI_INPUT_KEY.\r
\r
- @param UsbKeyboardDevice The USB_KB_DEV instance.\r
- @param KeyChar Indicates the key code that will be interpreted.\r
- @param Key A pointer to a buffer that is filled in with\r
- the keystroke information for the key that\r
- was pressed.\r
+ @param UsbKeyboardDevice The USB_KB_DEV instance.\r
+ @param KeyCode Indicates the key code that will be interpreted.\r
+ @param Key A pointer to a buffer that is filled in with\r
+ the keystroke information for the key that\r
+ was pressed.\r
\r
- @retval EFI_NOT_READY Device is not ready\r
- @retval EFI_SUCCESS Success.\r
+ @retval EFI_SUCCESS Success.\r
+ @retval EFI_INVALID_PARAMETER KeyCode is not in the range of 0x4 to 0x65.\r
+ @retval EFI_INVALID_PARAMETER Translated EFI_INPUT_KEY has zero for both ScanCode and UnicodeChar.\r
+ @retval EFI_NOT_READY KeyCode represents a dead key with EFI_NS_KEY_MODIFIER\r
+ @retval EFI_DEVICE_ERROR Keyboard layout is invalid.\r
\r
**/\r
EFI_STATUS\r
EFIAPI\r
-USBKeyCodeToEFIScanCode (\r
+UsbKeyCodeToEfiInputKey (\r
IN USB_KB_DEV *UsbKeyboardDevice,\r
- IN UINT8 KeyChar,\r
+ IN UINT8 KeyCode,\r
OUT EFI_INPUT_KEY *Key\r
)\r
{\r
- UINT8 Index;\r
EFI_KEY_DESCRIPTOR *KeyDescriptor;\r
\r
- if (!USBKBD_VALID_KEYCODE (KeyChar)) {\r
- return EFI_NOT_READY;\r
- }\r
-\r
//\r
- // valid USB Key Code starts from 4\r
+ // KeyCode must in the range of 0x4 to 0x65\r
//\r
- Index = (UINT8) (KeyChar - 4);\r
-\r
- if (Index >= USB_KEYCODE_MAX_MAKE) {\r
- return EFI_NOT_READY;\r
+ if (!USBKBD_VALID_KEYCODE (KeyCode)) {\r
+ return EFI_INVALID_PARAMETER;\r
+ }\r
+ if ((KeyCode - 4) >= NUMBER_OF_VALID_NON_MODIFIER_USB_KEYCODE) {\r
+ return EFI_INVALID_PARAMETER;\r
}\r
\r
- KeyDescriptor = GetKeyDescriptor (UsbKeyboardDevice, KeyChar);\r
+ KeyDescriptor = GetKeyDescriptor (UsbKeyboardDevice, KeyCode);\r
+ ASSERT (KeyDescriptor != NULL);\r
\r
- //\r
- // Check for Non-spacing key\r
- //\r
if (KeyDescriptor->Modifier == EFI_NS_KEY_MODIFIER) {\r
+ //\r
+ // If this is a dead key with EFI_NS_KEY_MODIFIER, then record it and return.\r
+ //\r
UsbKeyboardDevice->CurrentNsKey = FindUsbNsKey (UsbKeyboardDevice, KeyDescriptor);\r
return EFI_NOT_READY;\r
}\r
\r
- //\r
- // Check whether this keystroke follows a Non-spacing key\r
- //\r
if (UsbKeyboardDevice->CurrentNsKey != NULL) {\r
+ //\r
+ // If this keystroke follows a non-spacing key, then find the descriptor for corresponding\r
+ // physical key.\r
+ //\r
KeyDescriptor = FindPhysicalKey (UsbKeyboardDevice->CurrentNsKey, KeyDescriptor);\r
UsbKeyboardDevice->CurrentNsKey = NULL;\r
}\r
\r
- Key->ScanCode = EfiScanCodeConvertionTable[KeyDescriptor->Modifier];\r
+ //\r
+ // Make sure modifier of Key Descriptor is in the valid range according to UEFI spec.\r
+ //\r
+ if (KeyDescriptor->Modifier > EFI_FUNCTION_KEY_TWELVE_MODIFIER) {\r
+ return EFI_DEVICE_ERROR;\r
+ }\r
+\r
+ Key->ScanCode = ModifierValueToEfiScanCodeConvertionTable[KeyDescriptor->Modifier];\r
Key->UnicodeChar = KeyDescriptor->Unicode;\r
\r
- if (KeyDescriptor->AffectedAttribute & EFI_AFFECTED_BY_STANDARD_SHIFT) {\r
- if (UsbKeyboardDevice->ShiftOn != 0) {\r
+ if ((KeyDescriptor->AffectedAttribute & EFI_AFFECTED_BY_STANDARD_SHIFT)!= 0) {\r
+ if (UsbKeyboardDevice->ShiftOn) {\r
Key->UnicodeChar = KeyDescriptor->ShiftedUnicode;\r
\r
//\r
// Need not return associated shift state if a class of printable characters that\r
// are normally adjusted by shift modifiers. e.g. Shift Key + 'f' key = 'F'\r
//\r
- if (KeyDescriptor->AffectedAttribute & EFI_AFFECTED_BY_CAPS_LOCK) {\r
- UsbKeyboardDevice->LeftShiftOn = 0;\r
- UsbKeyboardDevice->RightShiftOn = 0;\r
+ if ((KeyDescriptor->AffectedAttribute & EFI_AFFECTED_BY_CAPS_LOCK) != 0) {\r
+ UsbKeyboardDevice->LeftShiftOn = FALSE;\r
+ UsbKeyboardDevice->RightShiftOn = FALSE;\r
}\r
\r
- if (UsbKeyboardDevice->AltGrOn != 0) {\r
+ if (UsbKeyboardDevice->AltGrOn) {\r
Key->UnicodeChar = KeyDescriptor->ShiftedAltGrUnicode;\r
}\r
} else {\r
//\r
Key->UnicodeChar = KeyDescriptor->Unicode;\r
\r
- if (UsbKeyboardDevice->AltGrOn != 0) {\r
+ if (UsbKeyboardDevice->AltGrOn) {\r
Key->UnicodeChar = KeyDescriptor->AltGrUnicode;\r
}\r
}\r
}\r
\r
- if (KeyDescriptor->AffectedAttribute & EFI_AFFECTED_BY_CAPS_LOCK) {\r
- if (UsbKeyboardDevice->CapsOn != 0) {\r
-\r
+ if ((KeyDescriptor->AffectedAttribute & EFI_AFFECTED_BY_CAPS_LOCK) != 0) {\r
+ if (UsbKeyboardDevice->CapsOn) {\r
if (Key->UnicodeChar == KeyDescriptor->Unicode) {\r
-\r
Key->UnicodeChar = KeyDescriptor->ShiftedUnicode;\r
-\r
} else if (Key->UnicodeChar == KeyDescriptor->ShiftedUnicode) {\r
-\r
Key->UnicodeChar = KeyDescriptor->Unicode;\r
-\r
}\r
}\r
}\r
\r
//\r
- // Translate the CTRL-Alpha characters to their corresponding control value (ctrl-a = 0x0001 through ctrl-Z = 0x001A)\r
+ // Translate the CTRL-Alpha characters to their corresponding control value\r
+ // (ctrl-a = 0x0001 through ctrl-Z = 0x001A)\r
//\r
- if (UsbKeyboardDevice->CtrlOn != 0) {\r
+ if (UsbKeyboardDevice->CtrlOn) {\r
if (Key->UnicodeChar >= 'a' && Key->UnicodeChar <= 'z') {\r
Key->UnicodeChar = (UINT8) (Key->UnicodeChar - 'a' + 1);\r
} else if (Key->UnicodeChar >= 'A' && Key->UnicodeChar <= 'Z') {\r
}\r
}\r
\r
- if (KeyDescriptor->AffectedAttribute & EFI_AFFECTED_BY_NUM_LOCK) {\r
-\r
- if ((UsbKeyboardDevice->NumLockOn != 0) && (UsbKeyboardDevice->ShiftOn == 0)) {\r
-\r
+ if ((KeyDescriptor->AffectedAttribute & EFI_AFFECTED_BY_NUM_LOCK) != 0) {\r
+ //\r
+ // For key affected by NumLock, if NumLock is on and Shift is not pressed, then it means\r
+ // normal key, instead of original control key. So the ScanCode should be cleaned.\r
+ // Otherwise, it means control key, so preserve the EFI Scan Code and clear the unicode keycode.\r
+ //\r
+ if ((UsbKeyboardDevice->NumLockOn) && (!(UsbKeyboardDevice->ShiftOn))) {\r
Key->ScanCode = SCAN_NULL;\r
-\r
} else {\r
Key->UnicodeChar = 0x00;\r
}\r
Key->UnicodeChar = 0x00;\r
}\r
\r
+ //\r
+ // Not valid for key without both unicode key code and EFI Scan Code.\r
+ //\r
if (Key->UnicodeChar == 0 && Key->ScanCode == SCAN_NULL) {\r
return EFI_NOT_READY;\r
}\r
//\r
// Save Shift/Toggle state\r
//\r
- if (UsbKeyboardDevice->LeftCtrlOn == 1) {\r
+ if (UsbKeyboardDevice->LeftCtrlOn) {\r
UsbKeyboardDevice->KeyState.KeyShiftState |= EFI_LEFT_CONTROL_PRESSED;\r
}\r
- if (UsbKeyboardDevice->RightCtrlOn == 1) {\r
+ if (UsbKeyboardDevice->RightCtrlOn) {\r
UsbKeyboardDevice->KeyState.KeyShiftState |= EFI_RIGHT_CONTROL_PRESSED;\r
}\r
- if (UsbKeyboardDevice->LeftAltOn == 1) {\r
+ if (UsbKeyboardDevice->LeftAltOn) {\r
UsbKeyboardDevice->KeyState.KeyShiftState |= EFI_LEFT_ALT_PRESSED;\r
}\r
- if (UsbKeyboardDevice->RightAltOn == 1) {\r
+ if (UsbKeyboardDevice->RightAltOn) {\r
UsbKeyboardDevice->KeyState.KeyShiftState |= EFI_RIGHT_ALT_PRESSED;\r
}\r
- if (UsbKeyboardDevice->LeftShiftOn == 1) {\r
+ if (UsbKeyboardDevice->LeftShiftOn) {\r
UsbKeyboardDevice->KeyState.KeyShiftState |= EFI_LEFT_SHIFT_PRESSED;\r
}\r
- if (UsbKeyboardDevice->RightShiftOn == 1) {\r
+ if (UsbKeyboardDevice->RightShiftOn) {\r
UsbKeyboardDevice->KeyState.KeyShiftState |= EFI_RIGHT_SHIFT_PRESSED;\r
}\r
- if (UsbKeyboardDevice->LeftLogoOn == 1) {\r
+ if (UsbKeyboardDevice->LeftLogoOn) {\r
UsbKeyboardDevice->KeyState.KeyShiftState |= EFI_LEFT_LOGO_PRESSED;\r
}\r
- if (UsbKeyboardDevice->RightLogoOn == 1) {\r
+ if (UsbKeyboardDevice->RightLogoOn) {\r
UsbKeyboardDevice->KeyState.KeyShiftState |= EFI_RIGHT_LOGO_PRESSED;\r
}\r
- if (UsbKeyboardDevice->MenuKeyOn == 1) {\r
+ if (UsbKeyboardDevice->MenuKeyOn) {\r
UsbKeyboardDevice->KeyState.KeyShiftState |= EFI_MENU_KEY_PRESSED;\r
}\r
- if (UsbKeyboardDevice->SysReqOn == 1) {\r
+ if (UsbKeyboardDevice->SysReqOn) {\r
UsbKeyboardDevice->KeyState.KeyShiftState |= EFI_SYS_REQ_PRESSED;\r
}\r
\r
- if (UsbKeyboardDevice->ScrollOn == 1) {\r
+ if (UsbKeyboardDevice->ScrollOn) {\r
UsbKeyboardDevice->KeyState.KeyToggleState |= EFI_SCROLL_LOCK_ACTIVE;\r
}\r
- if (UsbKeyboardDevice->NumLockOn == 1) {\r
+ if (UsbKeyboardDevice->NumLockOn) {\r
UsbKeyboardDevice->KeyState.KeyToggleState |= EFI_NUM_LOCK_ACTIVE;\r
}\r
- if (UsbKeyboardDevice->CapsOn == 1) {\r
+ if (UsbKeyboardDevice->CapsOn) {\r
UsbKeyboardDevice->KeyState.KeyToggleState |= EFI_CAPS_LOCK_ACTIVE;\r
}\r
\r
\r
\r
/**\r
- Resets USB Keyboard Buffer.\r
-\r
- @param KeyboardBuffer Points to the USB Keyboard Buffer.\r
+ Resets USB keyboard buffer.\r
\r
- @retval EFI_SUCCESS Init key buffer successfully.\r
+ @param KeyboardBuffer Points to the USB keyboard buffer.\r
\r
**/\r
-EFI_STATUS\r
+VOID\r
EFIAPI\r
InitUSBKeyBuffer (\r
- IN OUT USB_KB_BUFFER *KeyboardBuffer\r
+ OUT USB_KB_BUFFER *KeyboardBuffer\r
)\r
{\r
ZeroMem (KeyboardBuffer, sizeof (USB_KB_BUFFER));\r
\r
- KeyboardBuffer->bHead = KeyboardBuffer->bTail;\r
-\r
- return EFI_SUCCESS;\r
+ KeyboardBuffer->BufferHead = KeyboardBuffer->BufferTail;\r
}\r
\r
\r
/**\r
- Check whether USB Keyboard buffer is empty.\r
+ Check whether USB keyboard buffer is empty.\r
\r
- @param KeyboardBuffer USB Keyboard Buffer.\r
+ @param KeyboardBuffer USB keyboard buffer\r
\r
- @retval TRUE Key buffer is empty.\r
- @retval FALSE Key buffer is not empty.\r
+ @retval TRUE Keyboard buffer is empty.\r
+ @retval FALSE Keyboard buffer is not empty.\r
\r
**/\r
BOOLEAN\r
)\r
{\r
//\r
- // meet FIFO empty condition\r
+ // Meet FIFO empty condition\r
//\r
- return (BOOLEAN) (KeyboardBuffer->bHead == KeyboardBuffer->bTail);\r
+ return (BOOLEAN) (KeyboardBuffer->BufferHead == KeyboardBuffer->BufferTail);\r
}\r
\r
\r
/**\r
- Check whether USB Keyboard buffer is full.\r
+ Check whether USB keyboard buffer is full.\r
\r
- @param KeyboardBuffer USB Keyboard Buffer.\r
+ @param KeyboardBuffer USB keyboard buffer\r
\r
- @retval TRUE Key buffer is full.\r
- @retval FALSE Key buffer is not full.\r
+ @retval TRUE Keyboard buffer is full.\r
+ @retval FALSE Keyboard buffer is not full.\r
\r
**/\r
BOOLEAN\r
IN USB_KB_BUFFER *KeyboardBuffer\r
)\r
{\r
- return (BOOLEAN)(((KeyboardBuffer->bTail + 1) % (MAX_KEY_ALLOWED + 1)) ==\r
- KeyboardBuffer->bHead);\r
+ return (BOOLEAN)(((KeyboardBuffer->BufferTail + 1) % (MAX_KEY_ALLOWED + 1)) == KeyboardBuffer->BufferHead);\r
}\r
\r
\r
/**\r
- Inserts a key code into keyboard buffer.\r
+ Inserts a keycode into keyboard buffer.\r
\r
- @param KeyboardBuffer Points to the USB Keyboard Buffer.\r
- @param Key Key code\r
- @param Down Special key\r
-\r
- @retval EFI_SUCCESS Success\r
+ @param KeyboardBuffer Points to the USB keyboard buffer.\r
+ @param Key Keycode to insert.\r
+ @param Down TRUE means key is pressed.\r
+ FALSE means key is released.\r
\r
**/\r
-EFI_STATUS\r
+VOID\r
EFIAPI\r
InsertKeyCode (\r
IN OUT USB_KB_BUFFER *KeyboardBuffer,\r
IN UINT8 Key,\r
- IN UINT8 Down\r
+ IN BOOLEAN Down\r
)\r
{\r
USB_KEY UsbKey;\r
\r
//\r
- // if keyboard buffer is full, throw the\r
+ // If keyboard buffer is full, throw the\r
// first key out of the keyboard buffer.\r
//\r
if (IsUSBKeyboardBufferFull (KeyboardBuffer)) {\r
RemoveKeyCode (KeyboardBuffer, &UsbKey);\r
}\r
\r
- KeyboardBuffer->buffer[KeyboardBuffer->bTail].KeyCode = Key;\r
- KeyboardBuffer->buffer[KeyboardBuffer->bTail].Down = Down;\r
+ ASSERT (KeyboardBuffer->BufferTail <= MAX_KEY_ALLOWED);\r
+\r
+ KeyboardBuffer->Buffer[KeyboardBuffer->BufferTail].KeyCode = Key;\r
+ KeyboardBuffer->Buffer[KeyboardBuffer->BufferTail].Down = Down;\r
\r
//\r
- // adjust the tail pointer of the FIFO keyboard buffer.\r
+ // Adjust the tail pointer of the FIFO keyboard buffer.\r
//\r
- KeyboardBuffer->bTail = (UINT8) ((KeyboardBuffer->bTail + 1) % (MAX_KEY_ALLOWED + 1));\r
-\r
- return EFI_SUCCESS;\r
+ KeyboardBuffer->BufferTail = (UINT8) ((KeyboardBuffer->BufferTail + 1) % (MAX_KEY_ALLOWED + 1));\r
}\r
\r
\r
/**\r
- Pops a key code off from keyboard buffer.\r
+ Remove a keycode from keyboard buffer and return it.\r
\r
- @param KeyboardBuffer Points to the USB Keyboard Buffer.\r
- @param UsbKey Points to the buffer that contains a usb key code.\r
+ @param KeyboardBuffer Points to the USB keyboard buffer.\r
+ @param UsbKey Points to the buffer that contains keycode for output.\r
\r
- @retval EFI_SUCCESS Success\r
- @retval EFI_DEVICE_ERROR Hardware Error\r
+ @retval EFI_SUCCESS Keycode successfully removed from keyboard buffer.\r
+ @retval EFI_DEVICE_ERROR Keyboard buffer is empty.\r
\r
**/\r
EFI_STATUS\r
EFIAPI\r
RemoveKeyCode (\r
IN OUT USB_KB_BUFFER *KeyboardBuffer,\r
- OUT USB_KEY *UsbKey\r
+ OUT USB_KEY *UsbKey\r
)\r
{\r
if (IsUSBKeyboardBufferEmpty (KeyboardBuffer)) {\r
return EFI_DEVICE_ERROR;\r
}\r
\r
- UsbKey->KeyCode = KeyboardBuffer->buffer[KeyboardBuffer->bHead].KeyCode;\r
- UsbKey->Down = KeyboardBuffer->buffer[KeyboardBuffer->bHead].Down;\r
+ ASSERT (KeyboardBuffer->BufferHead <= MAX_KEY_ALLOWED);\r
+\r
+ UsbKey->KeyCode = KeyboardBuffer->Buffer[KeyboardBuffer->BufferHead].KeyCode;\r
+ UsbKey->Down = KeyboardBuffer->Buffer[KeyboardBuffer->BufferHead].Down;\r
\r
//\r
- // adjust the head pointer of the FIFO keyboard buffer.\r
+ // Adjust the head pointer of the FIFO keyboard buffer.\r
//\r
- KeyboardBuffer->bHead = (UINT8) ((KeyboardBuffer->bHead + 1) % (MAX_KEY_ALLOWED + 1));\r
+ KeyboardBuffer->BufferHead = (UINT8) ((KeyboardBuffer->BufferHead + 1) % (MAX_KEY_ALLOWED + 1));\r
\r
return EFI_SUCCESS;\r
}\r
\r
\r
/**\r
- Sets USB Keyboard LED state.\r
+ Sets USB keyboard LED state.\r
\r
@param UsbKeyboardDevice The USB_KB_DEV instance.\r
\r
- @retval EFI_SUCCESS Success\r
-\r
**/\r
-EFI_STATUS\r
+VOID\r
EFIAPI\r
SetKeyLED (\r
IN USB_KB_DEV *UsbKeyboardDevice\r
//\r
// Set each field in Led map.\r
//\r
- Led.NumLock = (UINT8) UsbKeyboardDevice->NumLockOn;\r
- Led.CapsLock = (UINT8) UsbKeyboardDevice->CapsOn;\r
- Led.ScrollLock = (UINT8) UsbKeyboardDevice->ScrollOn;\r
+ Led.NumLock = (UINT8) ((UsbKeyboardDevice->NumLockOn) ? 1 : 0);\r
+ Led.CapsLock = (UINT8) ((UsbKeyboardDevice->CapsOn) ? 1 : 0);\r
+ Led.ScrollLock = (UINT8) ((UsbKeyboardDevice->ScrollOn) ? 1 : 0);\r
Led.Resrvd = 0;\r
\r
ReportId = 0;\r
//\r
- // call Set Report Request to lighten the LED.\r
+ // Call Set_Report Request to lighten the LED.\r
//\r
UsbSetReportRequest (\r
UsbKeyboardDevice->UsbIo,\r
1,\r
(UINT8 *) &Led\r
);\r
-\r
- return EFI_SUCCESS;\r
}\r
\r
\r
/**\r
- Timer handler for Repeat Key timer.\r
+ Handler for Repeat Key event.\r
+\r
+ This function is the handler for Repeat Key event triggered\r
+ by timer.\r
+ After a repeatable key is pressed, the event would be triggered\r
+ with interval of USBKBD_REPEAT_DELAY. Once the event is triggered,\r
+ following trigger will come with interval of USBKBD_REPEAT_RATE.\r
\r
@param Event The Repeat Key event.\r
@param Context Points to the USB_KB_DEV instance.\r
\r
-\r
**/\r
VOID\r
EFIAPI\r
//\r
if (UsbKeyboardDevice->RepeatKey != 0) {\r
//\r
- // Inserts one Repeat key into keyboard buffer,\r
+ // Inserts the repeat key into keyboard buffer,\r
//\r
InsertKeyCode (\r
&(UsbKeyboardDevice->KeyboardBuffer),\r
UsbKeyboardDevice->RepeatKey,\r
- 1\r
+ TRUE\r
);\r
\r
//\r
- // set repeate rate for repeat key generation.\r
+ // Set repeat rate for next repeat key generation.\r
//\r
gBS->SetTimer (\r
- UsbKeyboardDevice->RepeatTimer,\r
- TimerRelative,\r
- USBKBD_REPEAT_RATE\r
- );\r
-\r
+ UsbKeyboardDevice->RepeatTimer,\r
+ TimerRelative,\r
+ USBKBD_REPEAT_RATE\r
+ );\r
}\r
}\r
\r
\r
/**\r
- Timer handler for Delayed Recovery timer.\r
+ Handler for Delayed Recovery event.\r
+\r
+ This function is the handler for Delayed Recovery event triggered\r
+ by timer.\r
+ After a device error occurs, the event would be triggered\r
+ with interval of EFI_USB_INTERRUPT_DELAY. EFI_USB_INTERRUPT_DELAY\r
+ is defined in USB standard for error handling.\r
\r
@param Event The Delayed Recovery event.\r
@param Context Points to the USB_KB_DEV instance.\r
\r
-\r
**/\r
VOID\r
EFIAPI\r
\r
PacketSize = (UINT8) (UsbKeyboardDevice->IntEndpointDescriptor.MaxPacketSize);\r
\r
+ //\r
+ // Re-submit Asynchronous Interrupt Transfer for recovery.\r
+ //\r
UsbIo->UsbAsyncInterruptTransfer (\r
- UsbIo,\r
- UsbKeyboardDevice->IntEndpointDescriptor.EndpointAddress,\r
- TRUE,\r
- UsbKeyboardDevice->IntEndpointDescriptor.Interval,\r
- PacketSize,\r
- KeyboardHandler,\r
- UsbKeyboardDevice\r
- );\r
+ UsbIo,\r
+ UsbKeyboardDevice->IntEndpointDescriptor.EndpointAddress,\r
+ TRUE,\r
+ UsbKeyboardDevice->IntEndpointDescriptor.Interval,\r
+ PacketSize,\r
+ KeyboardHandler,\r
+ UsbKeyboardDevice\r
+ );\r
}\r