X-Git-Url: https://git.proxmox.com/?p=mirror_edk2.git;a=blobdiff_plain;f=MdeModulePkg%2FBus%2FUsb%2FUsbKbDxe%2FKeyBoard.c;h=000430ae78d3353e635d27b6cd350cbb1e39af39;hp=48972ae0a6367831d5ddf067517472ca36c05b12;hb=c8ad2d7a296c851c2a91519f80dab479df0fdf46;hpb=c92e277d99335fa827994e410a3dc0830904a264 diff --git a/MdeModulePkg/Bus/Usb/UsbKbDxe/KeyBoard.c b/MdeModulePkg/Bus/Usb/UsbKbDxe/KeyBoard.c index 48972ae0a6..000430ae78 100644 --- a/MdeModulePkg/Bus/Usb/UsbKbDxe/KeyBoard.c +++ b/MdeModulePkg/Bus/Usb/UsbKbDxe/KeyBoard.c @@ -1,8 +1,8 @@ /** @file Helper functions for USB Keyboard Driver. -Copyright (c) 2004 - 2008, Intel Corporation -All rights reserved. This program and the accompanying materials +Copyright (c) 2004 - 2011, Intel Corporation. All rights reserved.
+This program and the accompanying materials are licensed and made available under the terms and conditions of the BSD License which accompanies this distribution. The full text of the license may be found at http://opensource.org/licenses/bsd-license.php @@ -14,126 +14,138 @@ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. #include "KeyBoard.h" -// -// Default English keyboard layout -// Format:, , , , -// -// According to Universal Serial Bus HID Usage Tables document ver 1.12, -// a Boot Keyboard should support the keycode range from 0x0 to 0x65 and 0xE0 to 0xE7. -// 0x0 to 0x3 are reserved for typical keyboard status or keyboard errors, so they are excluded. -// -UINT8 KeyboardLayoutTable[NUMBER_OF_VALID_USB_KEYCODE][5] = { - {EfiKeyC1, 'a', 'A', EFI_NULL_MODIFIER, EFI_AFFECTED_BY_STANDARD_SHIFT | EFI_AFFECTED_BY_CAPS_LOCK}, // 0x04 - {EfiKeyB5, 'b', 'B', EFI_NULL_MODIFIER, EFI_AFFECTED_BY_STANDARD_SHIFT | EFI_AFFECTED_BY_CAPS_LOCK}, // 0x05 - {EfiKeyB3, 'c', 'C', EFI_NULL_MODIFIER, EFI_AFFECTED_BY_STANDARD_SHIFT | EFI_AFFECTED_BY_CAPS_LOCK}, // 0x06 - {EfiKeyC3, 'd', 'D', EFI_NULL_MODIFIER, EFI_AFFECTED_BY_STANDARD_SHIFT | EFI_AFFECTED_BY_CAPS_LOCK}, // 0x07 - {EfiKeyD3, 'e', 'E', EFI_NULL_MODIFIER, EFI_AFFECTED_BY_STANDARD_SHIFT | EFI_AFFECTED_BY_CAPS_LOCK}, // 0x08 - {EfiKeyC4, 'f', 'F', EFI_NULL_MODIFIER, EFI_AFFECTED_BY_STANDARD_SHIFT | EFI_AFFECTED_BY_CAPS_LOCK}, // 0x09 - {EfiKeyC5, 'g', 'G', EFI_NULL_MODIFIER, EFI_AFFECTED_BY_STANDARD_SHIFT | EFI_AFFECTED_BY_CAPS_LOCK}, // 0x0A - {EfiKeyC6, 'h', 'H', EFI_NULL_MODIFIER, EFI_AFFECTED_BY_STANDARD_SHIFT | EFI_AFFECTED_BY_CAPS_LOCK}, // 0x0B - {EfiKeyD8, 'i', 'I', EFI_NULL_MODIFIER, EFI_AFFECTED_BY_STANDARD_SHIFT | EFI_AFFECTED_BY_CAPS_LOCK}, // 0x0C - {EfiKeyC7, 'j', 'J', EFI_NULL_MODIFIER, EFI_AFFECTED_BY_STANDARD_SHIFT | EFI_AFFECTED_BY_CAPS_LOCK}, // 0x0D - {EfiKeyC8, 'k', 'K', EFI_NULL_MODIFIER, EFI_AFFECTED_BY_STANDARD_SHIFT | EFI_AFFECTED_BY_CAPS_LOCK}, // 0x0E - {EfiKeyC9, 'l', 'L', EFI_NULL_MODIFIER, EFI_AFFECTED_BY_STANDARD_SHIFT | EFI_AFFECTED_BY_CAPS_LOCK}, // 0x0F - {EfiKeyB7, 'm', 'M', EFI_NULL_MODIFIER, EFI_AFFECTED_BY_STANDARD_SHIFT | EFI_AFFECTED_BY_CAPS_LOCK}, // 0x10 - {EfiKeyB6, 'n', 'N', EFI_NULL_MODIFIER, EFI_AFFECTED_BY_STANDARD_SHIFT | EFI_AFFECTED_BY_CAPS_LOCK}, // 0x11 - {EfiKeyD9, 'o', 'O', EFI_NULL_MODIFIER, EFI_AFFECTED_BY_STANDARD_SHIFT | EFI_AFFECTED_BY_CAPS_LOCK}, // 0x12 - {EfiKeyD10, 'p', 'P', EFI_NULL_MODIFIER, EFI_AFFECTED_BY_STANDARD_SHIFT | EFI_AFFECTED_BY_CAPS_LOCK}, // 0x13 - {EfiKeyD1, 'q', 'Q', EFI_NULL_MODIFIER, EFI_AFFECTED_BY_STANDARD_SHIFT | EFI_AFFECTED_BY_CAPS_LOCK}, // 0x14 - {EfiKeyD4, 'r', 'R', EFI_NULL_MODIFIER, EFI_AFFECTED_BY_STANDARD_SHIFT | EFI_AFFECTED_BY_CAPS_LOCK}, // 0x15 - {EfiKeyC2, 's', 'S', EFI_NULL_MODIFIER, EFI_AFFECTED_BY_STANDARD_SHIFT | EFI_AFFECTED_BY_CAPS_LOCK}, // 0x16 - {EfiKeyD5, 't', 'T', EFI_NULL_MODIFIER, EFI_AFFECTED_BY_STANDARD_SHIFT | EFI_AFFECTED_BY_CAPS_LOCK}, // 0x17 - {EfiKeyD7, 'u', 'U', EFI_NULL_MODIFIER, EFI_AFFECTED_BY_STANDARD_SHIFT | EFI_AFFECTED_BY_CAPS_LOCK}, // 0x18 - {EfiKeyB4, 'v', 'V', EFI_NULL_MODIFIER, EFI_AFFECTED_BY_STANDARD_SHIFT | EFI_AFFECTED_BY_CAPS_LOCK}, // 0x19 - {EfiKeyD2, 'w', 'W', EFI_NULL_MODIFIER, EFI_AFFECTED_BY_STANDARD_SHIFT | EFI_AFFECTED_BY_CAPS_LOCK}, // 0x1A - {EfiKeyB2, 'x', 'X', EFI_NULL_MODIFIER, EFI_AFFECTED_BY_STANDARD_SHIFT | EFI_AFFECTED_BY_CAPS_LOCK}, // 0x1B - {EfiKeyD6, 'y', 'Y', EFI_NULL_MODIFIER, EFI_AFFECTED_BY_STANDARD_SHIFT | EFI_AFFECTED_BY_CAPS_LOCK}, // 0x1C - {EfiKeyB1, 'z', 'Z', EFI_NULL_MODIFIER, EFI_AFFECTED_BY_STANDARD_SHIFT | EFI_AFFECTED_BY_CAPS_LOCK}, // 0x1D - {EfiKeyE1, '1', '!', EFI_NULL_MODIFIER, EFI_AFFECTED_BY_STANDARD_SHIFT}, // 0x1E - {EfiKeyE2, '2', '@', EFI_NULL_MODIFIER, EFI_AFFECTED_BY_STANDARD_SHIFT}, // 0x1F - {EfiKeyE3, '3', '#', EFI_NULL_MODIFIER, EFI_AFFECTED_BY_STANDARD_SHIFT}, // 0x20 - {EfiKeyE4, '4', '$', EFI_NULL_MODIFIER, EFI_AFFECTED_BY_STANDARD_SHIFT}, // 0x21 - {EfiKeyE5, '5', '%', EFI_NULL_MODIFIER, EFI_AFFECTED_BY_STANDARD_SHIFT}, // 0x22 - {EfiKeyE6, '6', '^', EFI_NULL_MODIFIER, EFI_AFFECTED_BY_STANDARD_SHIFT}, // 0x23 - {EfiKeyE7, '7', '&', EFI_NULL_MODIFIER, EFI_AFFECTED_BY_STANDARD_SHIFT}, // 0x24 - {EfiKeyE8, '8', '*', EFI_NULL_MODIFIER, EFI_AFFECTED_BY_STANDARD_SHIFT}, // 0x25 - {EfiKeyE9, '9', '(', EFI_NULL_MODIFIER, EFI_AFFECTED_BY_STANDARD_SHIFT}, // 0x26 - {EfiKeyE10, '0', ')', EFI_NULL_MODIFIER, EFI_AFFECTED_BY_STANDARD_SHIFT}, // 0x27 - {EfiKeyEnter, 0x0d, 0x0d, EFI_NULL_MODIFIER, 0}, // 0x28 Enter - {EfiKeyEsc, 0x1b, 0x1b, EFI_NULL_MODIFIER, 0}, // 0x29 Esc - {EfiKeyBackSpace, 0x08, 0x08, EFI_NULL_MODIFIER, 0}, // 0x2A Backspace - {EfiKeyTab, 0x09, 0x09, EFI_NULL_MODIFIER, 0}, // 0x2B Tab - {EfiKeySpaceBar, ' ', ' ', EFI_NULL_MODIFIER, 0}, // 0x2C Spacebar - {EfiKeyE11, '-', '_', EFI_NULL_MODIFIER, EFI_AFFECTED_BY_STANDARD_SHIFT}, // 0x2D - {EfiKeyE12, '=', '+', EFI_NULL_MODIFIER, EFI_AFFECTED_BY_STANDARD_SHIFT}, // 0x2E - {EfiKeyD11, '[', '{', EFI_NULL_MODIFIER, EFI_AFFECTED_BY_STANDARD_SHIFT}, // 0x2F - {EfiKeyD12, ']', '}', EFI_NULL_MODIFIER, EFI_AFFECTED_BY_STANDARD_SHIFT}, // 0x30 - {EfiKeyD13, '\\', '|', EFI_NULL_MODIFIER, EFI_AFFECTED_BY_STANDARD_SHIFT}, // 0x31 - {EfiKeyC12, '\\', '|', EFI_NULL_MODIFIER, EFI_AFFECTED_BY_STANDARD_SHIFT}, // 0x32 Keyboard Non-US # and ~ - {EfiKeyC10, ';', ':', EFI_NULL_MODIFIER, EFI_AFFECTED_BY_STANDARD_SHIFT}, // 0x33 - {EfiKeyC11, '\'', '"', EFI_NULL_MODIFIER, EFI_AFFECTED_BY_STANDARD_SHIFT}, // 0x34 - {EfiKeyE0, '`', '~', EFI_NULL_MODIFIER, EFI_AFFECTED_BY_STANDARD_SHIFT}, // 0x35 Keyboard Grave Accent and Tlide - {EfiKeyB8, ',', '<', EFI_NULL_MODIFIER, EFI_AFFECTED_BY_STANDARD_SHIFT}, // 0x36 - {EfiKeyB9, '.', '>', EFI_NULL_MODIFIER, EFI_AFFECTED_BY_STANDARD_SHIFT}, // 0x37 - {EfiKeyB10, '/', '?', EFI_NULL_MODIFIER, EFI_AFFECTED_BY_STANDARD_SHIFT}, // 0x38 - {EfiKeyCapsLock, 0x00, 0x00, EFI_CAPS_LOCK_MODIFIER, 0}, // 0x39 CapsLock - {EfiKeyF1, 0x00, 0x00, EFI_FUNCTION_KEY_ONE_MODIFIER, 0}, // 0x3A - {EfiKeyF2, 0x00, 0x00, EFI_FUNCTION_KEY_TWO_MODIFIER, 0}, // 0x3B - {EfiKeyF3, 0x00, 0x00, EFI_FUNCTION_KEY_THREE_MODIFIER, 0}, // 0x3C - {EfiKeyF4, 0x00, 0x00, EFI_FUNCTION_KEY_FOUR_MODIFIER, 0}, // 0x3D - {EfiKeyF5, 0x00, 0x00, EFI_FUNCTION_KEY_FIVE_MODIFIER, 0}, // 0x3E - {EfiKeyF6, 0x00, 0x00, EFI_FUNCTION_KEY_SIX_MODIFIER, 0}, // 0x3F - {EfiKeyF7, 0x00, 0x00, EFI_FUNCTION_KEY_SEVEN_MODIFIER, 0}, // 0x40 - {EfiKeyF8, 0x00, 0x00, EFI_FUNCTION_KEY_EIGHT_MODIFIER, 0}, // 0x41 - {EfiKeyF9, 0x00, 0x00, EFI_FUNCTION_KEY_NINE_MODIFIER, 0}, // 0x42 - {EfiKeyF10, 0x00, 0x00, EFI_FUNCTION_KEY_TEN_MODIFIER, 0}, // 0x43 - {EfiKeyF11, 0x00, 0x00, EFI_FUNCTION_KEY_ELEVEN_MODIFIER, 0}, // 0x44 F11 - {EfiKeyF12, 0x00, 0x00, EFI_FUNCTION_KEY_TWELVE_MODIFIER, 0}, // 0x45 F12 - {EfiKeyPrint, 0x00, 0x00, EFI_PRINT_MODIFIER, 0}, // 0x46 PrintScreen - {EfiKeySLck, 0x00, 0x00, EFI_SCROLL_LOCK_MODIFIER, 0}, // 0x47 Scroll Lock - {EfiKeyPause, 0x00, 0x00, EFI_PAUSE_MODIFIER, 0}, // 0x48 Pause - {EfiKeyIns, 0x00, 0x00, EFI_INSERT_MODIFIER, 0}, // 0x49 - {EfiKeyHome, 0x00, 0x00, EFI_HOME_MODIFIER, 0}, // 0x4A - {EfiKeyPgUp, 0x00, 0x00, EFI_PAGE_UP_MODIFIER, 0}, // 0x4B - {EfiKeyDel, 0x00, 0x00, EFI_DELETE_MODIFIER, 0}, // 0x4C - {EfiKeyEnd, 0x00, 0x00, EFI_END_MODIFIER, 0}, // 0x4D - {EfiKeyPgDn, 0x00, 0x00, EFI_PAGE_DOWN_MODIFIER, 0}, // 0x4E - {EfiKeyRightArrow, 0x00, 0x00, EFI_RIGHT_ARROW_MODIFIER, 0}, // 0x4F - {EfiKeyLeftArrow, 0x00, 0x00, EFI_LEFT_ARROW_MODIFIER, 0}, // 0x50 - {EfiKeyDownArrow, 0x00, 0x00, EFI_DOWN_ARROW_MODIFIER, 0}, // 0x51 - {EfiKeyUpArrow, 0x00, 0x00, EFI_UP_ARROW_MODIFIER, 0}, // 0x52 - {EfiKeyNLck, 0x00, 0x00, EFI_NUM_LOCK_MODIFIER, 0}, // 0x53 NumLock - {EfiKeySlash, '/', '/', EFI_NULL_MODIFIER, 0}, // 0x54 - {EfiKeyAsterisk, '*', '*', EFI_NULL_MODIFIER, 0}, // 0x55 - {EfiKeyMinus, '-', '-', EFI_NULL_MODIFIER, 0}, // 0x56 - {EfiKeyPlus, '+', '+', EFI_NULL_MODIFIER, 0}, // 0x57 - {EfiKeyEnter, 0x0d, 0x0d, EFI_NULL_MODIFIER, 0}, // 0x58 - {EfiKeyOne, '1', '1', EFI_END_MODIFIER, EFI_AFFECTED_BY_STANDARD_SHIFT | EFI_AFFECTED_BY_NUM_LOCK}, // 0x59 - {EfiKeyTwo, '2', '2', EFI_DOWN_ARROW_MODIFIER, EFI_AFFECTED_BY_STANDARD_SHIFT | EFI_AFFECTED_BY_NUM_LOCK}, // 0x5A - {EfiKeyThree, '3', '3', EFI_PAGE_DOWN_MODIFIER, EFI_AFFECTED_BY_STANDARD_SHIFT | EFI_AFFECTED_BY_NUM_LOCK}, // 0x5B - {EfiKeyFour, '4', '4', EFI_LEFT_ARROW_MODIFIER, EFI_AFFECTED_BY_STANDARD_SHIFT | EFI_AFFECTED_BY_NUM_LOCK}, // 0x5C - {EfiKeyFive, '5', '5', EFI_NULL_MODIFIER, EFI_AFFECTED_BY_STANDARD_SHIFT | EFI_AFFECTED_BY_NUM_LOCK}, // 0x5D - {EfiKeySix, '6', '6', EFI_RIGHT_ARROW_MODIFIER, EFI_AFFECTED_BY_STANDARD_SHIFT | EFI_AFFECTED_BY_NUM_LOCK}, // 0x5E - {EfiKeySeven, '7', '7', EFI_HOME_MODIFIER, EFI_AFFECTED_BY_STANDARD_SHIFT | EFI_AFFECTED_BY_NUM_LOCK}, // 0x5F - {EfiKeyEight, '8', '8', EFI_UP_ARROW_MODIFIER, EFI_AFFECTED_BY_STANDARD_SHIFT | EFI_AFFECTED_BY_NUM_LOCK}, // 0x60 - {EfiKeyNine, '9', '9', EFI_PAGE_UP_MODIFIER, EFI_AFFECTED_BY_STANDARD_SHIFT | EFI_AFFECTED_BY_NUM_LOCK}, // 0x61 - {EfiKeyZero, '0', '0', EFI_INSERT_MODIFIER, EFI_AFFECTED_BY_STANDARD_SHIFT | EFI_AFFECTED_BY_NUM_LOCK}, // 0x62 - {EfiKeyPeriod, '.', '.', EFI_DELETE_MODIFIER, EFI_AFFECTED_BY_STANDARD_SHIFT | EFI_AFFECTED_BY_NUM_LOCK}, // 0x63 - {EfiKeyB0, '\\', '|', EFI_NULL_MODIFIER, EFI_AFFECTED_BY_STANDARD_SHIFT}, // 0x64 Keyboard Non-US \ and | - {EfiKeyA4, 0x00, 0x00, EFI_MENU_MODIFIER, 0}, // 0x65 Keyboard Application - - {EfiKeyLCtrl, 0, 0, EFI_LEFT_CONTROL_MODIFIER, 0}, // 0xe0 - {EfiKeyLShift, 0, 0, EFI_LEFT_SHIFT_MODIFIER, 0}, // 0xe1 - {EfiKeyLAlt, 0, 0, EFI_LEFT_ALT_MODIFIER, 0}, // 0xe2 - {EfiKeyA0, 0, 0, EFI_LEFT_LOGO_MODIFIER, 0}, // 0xe3 - {EfiKeyRCtrl, 0, 0, EFI_RIGHT_CONTROL_MODIFIER, 0}, // 0xe4 - {EfiKeyRShift, 0, 0, EFI_RIGHT_SHIFT_MODIFIER, 0}, // 0xe5 - {EfiKeyA2, 0, 0, EFI_RIGHT_ALT_MODIFIER, 0}, // 0xe6 - {EfiKeyA3, 0, 0, EFI_RIGHT_LOGO_MODIFIER, 0}, // 0xe7 +USB_KEYBOARD_LAYOUT_PACK_BIN mUsbKeyboardLayoutBin = { + sizeof (USB_KEYBOARD_LAYOUT_PACK_BIN), // Binary size + + // + // EFI_HII_PACKAGE_HEADER + // + { + sizeof (USB_KEYBOARD_LAYOUT_PACK_BIN) - sizeof (UINT32), + EFI_HII_PACKAGE_KEYBOARD_LAYOUT + }, + 1, // LayoutCount + sizeof (USB_KEYBOARD_LAYOUT_PACK_BIN) - sizeof (UINT32) - sizeof (EFI_HII_PACKAGE_HEADER) - sizeof (UINT16), // LayoutLength + USB_KEYBOARD_LAYOUT_KEY_GUID, // KeyGuid + sizeof (UINT16) + sizeof (EFI_GUID) + sizeof (UINT32) + sizeof (UINT8) + (USB_KEYBOARD_KEY_COUNT * sizeof (EFI_KEY_DESCRIPTOR)), // LayoutDescriptorStringOffset + USB_KEYBOARD_KEY_COUNT, // DescriptorCount + { + // + // EFI_KEY_DESCRIPTOR (total number is USB_KEYBOARD_KEY_COUNT) + // + {EfiKeyC1, 'a', 'A', 0, 0, EFI_NULL_MODIFIER, EFI_AFFECTED_BY_STANDARD_SHIFT | EFI_AFFECTED_BY_CAPS_LOCK}, + {EfiKeyB5, 'b', 'B', 0, 0, EFI_NULL_MODIFIER, EFI_AFFECTED_BY_STANDARD_SHIFT | EFI_AFFECTED_BY_CAPS_LOCK}, + {EfiKeyB3, 'c', 'C', 0, 0, EFI_NULL_MODIFIER, EFI_AFFECTED_BY_STANDARD_SHIFT | EFI_AFFECTED_BY_CAPS_LOCK}, + {EfiKeyC3, 'd', 'D', 0, 0, EFI_NULL_MODIFIER, EFI_AFFECTED_BY_STANDARD_SHIFT | EFI_AFFECTED_BY_CAPS_LOCK}, + {EfiKeyD3, 'e', 'E', 0, 0, EFI_NULL_MODIFIER, EFI_AFFECTED_BY_STANDARD_SHIFT | EFI_AFFECTED_BY_CAPS_LOCK}, + {EfiKeyC4, 'f', 'F', 0, 0, EFI_NULL_MODIFIER, EFI_AFFECTED_BY_STANDARD_SHIFT | EFI_AFFECTED_BY_CAPS_LOCK}, + {EfiKeyC5, 'g', 'G', 0, 0, EFI_NULL_MODIFIER, EFI_AFFECTED_BY_STANDARD_SHIFT | EFI_AFFECTED_BY_CAPS_LOCK}, + {EfiKeyC6, 'h', 'H', 0, 0, EFI_NULL_MODIFIER, EFI_AFFECTED_BY_STANDARD_SHIFT | EFI_AFFECTED_BY_CAPS_LOCK}, + {EfiKeyD8, 'i', 'I', 0, 0, EFI_NULL_MODIFIER, EFI_AFFECTED_BY_STANDARD_SHIFT | EFI_AFFECTED_BY_CAPS_LOCK}, + {EfiKeyC7, 'j', 'J', 0, 0, EFI_NULL_MODIFIER, EFI_AFFECTED_BY_STANDARD_SHIFT | EFI_AFFECTED_BY_CAPS_LOCK}, + {EfiKeyC8, 'k', 'K', 0, 0, EFI_NULL_MODIFIER, EFI_AFFECTED_BY_STANDARD_SHIFT | EFI_AFFECTED_BY_CAPS_LOCK}, + {EfiKeyC9, 'l', 'L', 0, 0, EFI_NULL_MODIFIER, EFI_AFFECTED_BY_STANDARD_SHIFT | EFI_AFFECTED_BY_CAPS_LOCK}, + {EfiKeyB7, 'm', 'M', 0, 0, EFI_NULL_MODIFIER, EFI_AFFECTED_BY_STANDARD_SHIFT | EFI_AFFECTED_BY_CAPS_LOCK}, + {EfiKeyB6, 'n', 'N', 0, 0, EFI_NULL_MODIFIER, EFI_AFFECTED_BY_STANDARD_SHIFT | EFI_AFFECTED_BY_CAPS_LOCK}, + {EfiKeyD9, 'o', 'O', 0, 0, EFI_NULL_MODIFIER, EFI_AFFECTED_BY_STANDARD_SHIFT | EFI_AFFECTED_BY_CAPS_LOCK}, + {EfiKeyD10, 'p', 'P', 0, 0, EFI_NULL_MODIFIER, EFI_AFFECTED_BY_STANDARD_SHIFT | EFI_AFFECTED_BY_CAPS_LOCK}, + {EfiKeyD1, 'q', 'Q', 0, 0, EFI_NULL_MODIFIER, EFI_AFFECTED_BY_STANDARD_SHIFT | EFI_AFFECTED_BY_CAPS_LOCK}, + {EfiKeyD4, 'r', 'R', 0, 0, EFI_NULL_MODIFIER, EFI_AFFECTED_BY_STANDARD_SHIFT | EFI_AFFECTED_BY_CAPS_LOCK}, + {EfiKeyC2, 's', 'S', 0, 0, EFI_NULL_MODIFIER, EFI_AFFECTED_BY_STANDARD_SHIFT | EFI_AFFECTED_BY_CAPS_LOCK}, + {EfiKeyD5, 't', 'T', 0, 0, EFI_NULL_MODIFIER, EFI_AFFECTED_BY_STANDARD_SHIFT | EFI_AFFECTED_BY_CAPS_LOCK}, + {EfiKeyD7, 'u', 'U', 0, 0, EFI_NULL_MODIFIER, EFI_AFFECTED_BY_STANDARD_SHIFT | EFI_AFFECTED_BY_CAPS_LOCK}, + {EfiKeyB4, 'v', 'V', 0, 0, EFI_NULL_MODIFIER, EFI_AFFECTED_BY_STANDARD_SHIFT | EFI_AFFECTED_BY_CAPS_LOCK}, + {EfiKeyD2, 'w', 'W', 0, 0, EFI_NULL_MODIFIER, EFI_AFFECTED_BY_STANDARD_SHIFT | EFI_AFFECTED_BY_CAPS_LOCK}, + {EfiKeyB2, 'x', 'X', 0, 0, EFI_NULL_MODIFIER, EFI_AFFECTED_BY_STANDARD_SHIFT | EFI_AFFECTED_BY_CAPS_LOCK}, + {EfiKeyD6, 'y', 'Y', 0, 0, EFI_NULL_MODIFIER, EFI_AFFECTED_BY_STANDARD_SHIFT | EFI_AFFECTED_BY_CAPS_LOCK}, + {EfiKeyB1, 'z', 'Z', 0, 0, EFI_NULL_MODIFIER, EFI_AFFECTED_BY_STANDARD_SHIFT | EFI_AFFECTED_BY_CAPS_LOCK}, + {EfiKeyE1, '1', '!', 0, 0, EFI_NULL_MODIFIER, EFI_AFFECTED_BY_STANDARD_SHIFT}, + {EfiKeyE2, '2', '@', 0, 0, EFI_NULL_MODIFIER, EFI_AFFECTED_BY_STANDARD_SHIFT}, + {EfiKeyE3, '3', '#', 0, 0, EFI_NULL_MODIFIER, EFI_AFFECTED_BY_STANDARD_SHIFT}, + {EfiKeyE4, '4', '$', 0, 0, EFI_NULL_MODIFIER, EFI_AFFECTED_BY_STANDARD_SHIFT}, + {EfiKeyE5, '5', '%', 0, 0, EFI_NULL_MODIFIER, EFI_AFFECTED_BY_STANDARD_SHIFT}, + {EfiKeyE6, '6', '^', 0, 0, EFI_NULL_MODIFIER, EFI_AFFECTED_BY_STANDARD_SHIFT}, + {EfiKeyE7, '7', '&', 0, 0, EFI_NULL_MODIFIER, EFI_AFFECTED_BY_STANDARD_SHIFT}, + {EfiKeyE8, '8', '*', 0, 0, EFI_NULL_MODIFIER, EFI_AFFECTED_BY_STANDARD_SHIFT}, + {EfiKeyE9, '9', '(', 0, 0, EFI_NULL_MODIFIER, EFI_AFFECTED_BY_STANDARD_SHIFT}, + {EfiKeyE10, '0', ')', 0, 0, EFI_NULL_MODIFIER, EFI_AFFECTED_BY_STANDARD_SHIFT}, + {EfiKeyEnter, 0x0d, 0x0d, 0, 0, EFI_NULL_MODIFIER, 0}, + {EfiKeyEsc, 0x1b, 0x1b, 0, 0, EFI_NULL_MODIFIER, 0}, + {EfiKeyBackSpace, 0x08, 0x08, 0, 0, EFI_NULL_MODIFIER, 0}, + {EfiKeyTab, 0x09, 0x09, 0, 0, EFI_NULL_MODIFIER, 0}, + {EfiKeySpaceBar, ' ', ' ', 0, 0, EFI_NULL_MODIFIER, 0}, + {EfiKeyE11, '-', '_', 0, 0, EFI_NULL_MODIFIER, EFI_AFFECTED_BY_STANDARD_SHIFT}, + {EfiKeyE12, '=', '+', 0, 0, EFI_NULL_MODIFIER, EFI_AFFECTED_BY_STANDARD_SHIFT}, + {EfiKeyD11, '[', '{', 0, 0, EFI_NULL_MODIFIER, EFI_AFFECTED_BY_STANDARD_SHIFT}, + {EfiKeyD12, ']', '}', 0, 0, EFI_NULL_MODIFIER, EFI_AFFECTED_BY_STANDARD_SHIFT}, + {EfiKeyD13, '\\', '|', 0, 0, EFI_NULL_MODIFIER, EFI_AFFECTED_BY_STANDARD_SHIFT}, + {EfiKeyC10, ';', ':', 0, 0, EFI_NULL_MODIFIER, EFI_AFFECTED_BY_STANDARD_SHIFT}, + {EfiKeyC11, '\'', '"', 0, 0, EFI_NULL_MODIFIER, EFI_AFFECTED_BY_STANDARD_SHIFT}, + {EfiKeyE0, '`', '~', 0, 0, EFI_NULL_MODIFIER, EFI_AFFECTED_BY_STANDARD_SHIFT}, + {EfiKeyB8, ',', '<', 0, 0, EFI_NULL_MODIFIER, EFI_AFFECTED_BY_STANDARD_SHIFT}, + {EfiKeyB9, '.', '>', 0, 0, EFI_NULL_MODIFIER, EFI_AFFECTED_BY_STANDARD_SHIFT}, + {EfiKeyB10, '/', '?', 0, 0, EFI_NULL_MODIFIER, EFI_AFFECTED_BY_STANDARD_SHIFT}, + {EfiKeyCapsLock, 0x00, 0x00, 0, 0, EFI_CAPS_LOCK_MODIFIER, 0}, + {EfiKeyF1, 0x00, 0x00, 0, 0, EFI_FUNCTION_KEY_ONE_MODIFIER, 0}, + {EfiKeyF2, 0x00, 0x00, 0, 0, EFI_FUNCTION_KEY_TWO_MODIFIER, 0}, + {EfiKeyF3, 0x00, 0x00, 0, 0, EFI_FUNCTION_KEY_THREE_MODIFIER, 0}, + {EfiKeyF4, 0x00, 0x00, 0, 0, EFI_FUNCTION_KEY_FOUR_MODIFIER, 0}, + {EfiKeyF5, 0x00, 0x00, 0, 0, EFI_FUNCTION_KEY_FIVE_MODIFIER, 0}, + {EfiKeyF6, 0x00, 0x00, 0, 0, EFI_FUNCTION_KEY_SIX_MODIFIER, 0}, + {EfiKeyF7, 0x00, 0x00, 0, 0, EFI_FUNCTION_KEY_SEVEN_MODIFIER, 0}, + {EfiKeyF8, 0x00, 0x00, 0, 0, EFI_FUNCTION_KEY_EIGHT_MODIFIER, 0}, + {EfiKeyF9, 0x00, 0x00, 0, 0, EFI_FUNCTION_KEY_NINE_MODIFIER, 0}, + {EfiKeyF10, 0x00, 0x00, 0, 0, EFI_FUNCTION_KEY_TEN_MODIFIER, 0}, + {EfiKeyF11, 0x00, 0x00, 0, 0, EFI_FUNCTION_KEY_ELEVEN_MODIFIER, 0}, + {EfiKeyF12, 0x00, 0x00, 0, 0, EFI_FUNCTION_KEY_TWELVE_MODIFIER, 0}, + {EfiKeyPrint, 0x00, 0x00, 0, 0, EFI_PRINT_MODIFIER, 0}, + {EfiKeySLck, 0x00, 0x00, 0, 0, EFI_SCROLL_LOCK_MODIFIER, 0}, + {EfiKeyPause, 0x00, 0x00, 0, 0, EFI_PAUSE_MODIFIER, 0}, + {EfiKeyIns, 0x00, 0x00, 0, 0, EFI_INSERT_MODIFIER, 0}, + {EfiKeyHome, 0x00, 0x00, 0, 0, EFI_HOME_MODIFIER, 0}, + {EfiKeyPgUp, 0x00, 0x00, 0, 0, EFI_PAGE_UP_MODIFIER, 0}, + {EfiKeyDel, 0x00, 0x00, 0, 0, EFI_DELETE_MODIFIER, 0}, + {EfiKeyEnd, 0x00, 0x00, 0, 0, EFI_END_MODIFIER, 0}, + {EfiKeyPgDn, 0x00, 0x00, 0, 0, EFI_PAGE_DOWN_MODIFIER, 0}, + {EfiKeyRightArrow, 0x00, 0x00, 0, 0, EFI_RIGHT_ARROW_MODIFIER, 0}, + {EfiKeyLeftArrow, 0x00, 0x00, 0, 0, EFI_LEFT_ARROW_MODIFIER, 0}, + {EfiKeyDownArrow, 0x00, 0x00, 0, 0, EFI_DOWN_ARROW_MODIFIER, 0}, + {EfiKeyUpArrow, 0x00, 0x00, 0, 0, EFI_UP_ARROW_MODIFIER, 0}, + {EfiKeyNLck, 0x00, 0x00, 0, 0, EFI_NUM_LOCK_MODIFIER, 0}, + {EfiKeySlash, '/', '/', 0, 0, EFI_NULL_MODIFIER, 0}, + {EfiKeyAsterisk, '*', '*', 0, 0, EFI_NULL_MODIFIER, 0}, + {EfiKeyMinus, '-', '-', 0, 0, EFI_NULL_MODIFIER, 0}, + {EfiKeyPlus, '+', '+', 0, 0, EFI_NULL_MODIFIER, 0}, + {EfiKeyEnter, 0x0d, 0x0d, 0, 0, EFI_NULL_MODIFIER, 0}, + {EfiKeyOne, '1', '1', 0, 0, EFI_END_MODIFIER, EFI_AFFECTED_BY_STANDARD_SHIFT | EFI_AFFECTED_BY_NUM_LOCK}, + {EfiKeyTwo, '2', '2', 0, 0, EFI_DOWN_ARROW_MODIFIER, EFI_AFFECTED_BY_STANDARD_SHIFT | EFI_AFFECTED_BY_NUM_LOCK}, + {EfiKeyThree, '3', '3', 0, 0, EFI_PAGE_DOWN_MODIFIER, EFI_AFFECTED_BY_STANDARD_SHIFT | EFI_AFFECTED_BY_NUM_LOCK}, + {EfiKeyFour, '4', '4', 0, 0, EFI_LEFT_ARROW_MODIFIER, EFI_AFFECTED_BY_STANDARD_SHIFT | EFI_AFFECTED_BY_NUM_LOCK}, + {EfiKeyFive, '5', '5', 0, 0, EFI_NULL_MODIFIER, EFI_AFFECTED_BY_STANDARD_SHIFT | EFI_AFFECTED_BY_NUM_LOCK}, + {EfiKeySix, '6', '6', 0, 0, EFI_RIGHT_ARROW_MODIFIER, EFI_AFFECTED_BY_STANDARD_SHIFT | EFI_AFFECTED_BY_NUM_LOCK}, + {EfiKeySeven, '7', '7', 0, 0, EFI_HOME_MODIFIER, EFI_AFFECTED_BY_STANDARD_SHIFT | EFI_AFFECTED_BY_NUM_LOCK}, + {EfiKeyEight, '8', '8', 0, 0, EFI_UP_ARROW_MODIFIER, EFI_AFFECTED_BY_STANDARD_SHIFT | EFI_AFFECTED_BY_NUM_LOCK}, + {EfiKeyNine, '9', '9', 0, 0, EFI_PAGE_UP_MODIFIER, EFI_AFFECTED_BY_STANDARD_SHIFT | EFI_AFFECTED_BY_NUM_LOCK}, + {EfiKeyZero, '0', '0', 0, 0, EFI_INSERT_MODIFIER, EFI_AFFECTED_BY_STANDARD_SHIFT | EFI_AFFECTED_BY_NUM_LOCK}, + {EfiKeyPeriod, '.', '.', 0, 0, EFI_DELETE_MODIFIER, EFI_AFFECTED_BY_STANDARD_SHIFT | EFI_AFFECTED_BY_NUM_LOCK}, + {EfiKeyA4, 0x00, 0x00, 0, 0, EFI_MENU_MODIFIER, 0}, + {EfiKeyLCtrl, 0, 0, 0, 0, EFI_LEFT_CONTROL_MODIFIER, 0}, + {EfiKeyLShift, 0, 0, 0, 0, EFI_LEFT_SHIFT_MODIFIER, 0}, + {EfiKeyLAlt, 0, 0, 0, 0, EFI_LEFT_ALT_MODIFIER, 0}, + {EfiKeyA0, 0, 0, 0, 0, EFI_LEFT_LOGO_MODIFIER, 0}, + {EfiKeyRCtrl, 0, 0, 0, 0, EFI_RIGHT_CONTROL_MODIFIER, 0}, + {EfiKeyRShift, 0, 0, 0, 0, EFI_RIGHT_SHIFT_MODIFIER, 0}, + {EfiKeyA2, 0, 0, 0, 0, EFI_RIGHT_ALT_MODIFIER, 0}, + {EfiKeyA3, 0, 0, 0, 0, EFI_RIGHT_LOGO_MODIFIER, 0}, + }, + 1, // DescriptionCount + {'e', 'n', '-', 'U', 'S'}, // RFC4646 language code + ' ', // Space + {'E', 'n', 'g', 'l', 'i', 's', 'h', ' ', 'K', 'e', 'y', 'b', 'o', 'a', 'r', 'd', '\0'}, // DescriptionString[] }; // -// EFI_KEY to USB Keycode convertion table +// EFI_KEY to USB Keycode conversion table // EFI_KEY is defined in UEFI spec. // USB Keycode is defined in USB HID Firmware spec. // @@ -284,43 +296,63 @@ UINT8 ModifierValueToEfiScanCodeConvertionTable[] = { SCAN_F10, // EFI_FUNCTION_KEY_TEN_MODIFIER SCAN_F11, // EFI_FUNCTION_KEY_ELEVEN_MODIFIER SCAN_F12, // EFI_FUNCTION_KEY_TWELVE_MODIFIER + SCAN_NULL, // EFI_PRINT_MODIFIER + SCAN_NULL, // EFI_SYS_REQUEST_MODIFIER + SCAN_NULL, // EFI_SCROLL_LOCK_MODIFIER + SCAN_PAUSE // EFI_PAUSE_MODIFIER }; -EFI_GUID mKeyboardLayoutEventGuid = EFI_HII_SET_KEYBOARD_LAYOUT_EVENT_GUID; - /** - Initialize Key Convertion Table by using default keyboard layout. + Initialize Key Convention Table by using default keyboard layout. @param UsbKeyboardDevice The USB_KB_DEV instance. + @retval EFI_SUCCESS The default keyboard layout was installed successfully + @retval Others Failure to install default keyboard layout. **/ -VOID -EFIAPI -LoadDefaultKeyboardLayout ( - IN OUT USB_KB_DEV *UsbKeyboardDevice +EFI_STATUS +InstallDefaultKeyboardLayout ( + IN OUT USB_KB_DEV *UsbKeyboardDevice ) { - UINTN Index; - EFI_KEY_DESCRIPTOR *KeyDescriptor; + EFI_STATUS Status; + EFI_HII_DATABASE_PROTOCOL *HiiDatabase; + EFI_HII_HANDLE HiiHandle; // - // Construct KeyConvertionTable by default keyboard layout + // Locate Hii database protocol // - KeyDescriptor = &UsbKeyboardDevice->KeyConvertionTable[0]; - - for (Index = 0; Index < (NUMBER_OF_VALID_USB_KEYCODE); Index++) { - KeyDescriptor->Key = (EFI_KEY) KeyboardLayoutTable[Index][0]; - KeyDescriptor->Unicode = KeyboardLayoutTable[Index][1]; - KeyDescriptor->ShiftedUnicode = KeyboardLayoutTable[Index][2]; - KeyDescriptor->AltGrUnicode = 0; - KeyDescriptor->ShiftedAltGrUnicode = 0; - KeyDescriptor->Modifier = KeyboardLayoutTable[Index][3]; - KeyDescriptor->AffectedAttribute = KeyboardLayoutTable[Index][4]; + Status = gBS->LocateProtocol ( + &gEfiHiiDatabaseProtocolGuid, + NULL, + (VOID **) &HiiDatabase + ); + if (EFI_ERROR (Status)) { + return Status; + } - KeyDescriptor++; + // + // Install Keyboard Layout package to HII database + // + HiiHandle = HiiAddPackages ( + &gUsbKeyboardLayoutPackageGuid, + UsbKeyboardDevice->ControllerHandle, + &mUsbKeyboardLayoutBin, + NULL + ); + if (HiiHandle == NULL) { + return EFI_OUT_OF_RESOURCES; } + + // + // Set current keyboard layout + // + Status = HiiDatabase->SetKeyboardLayout (HiiDatabase, &gUsbKeyboardLayoutKeyGuid); + + return Status; } + /** Uses USB I/O to check whether the device is a USB keyboard device. @@ -331,7 +363,6 @@ LoadDefaultKeyboardLayout ( **/ BOOLEAN -EFIAPI IsUSBKeyboard ( IN EFI_USB_IO_PROTOCOL *UsbIo ) @@ -369,7 +400,6 @@ IsUSBKeyboard ( **/ EFI_HII_KEYBOARD_LAYOUT * -EFIAPI GetCurrentKeyboardLayout ( VOID ) @@ -432,7 +462,6 @@ GetCurrentKeyboardLayout ( **/ EFI_KEY_DESCRIPTOR * -EFIAPI GetKeyDescriptor ( IN USB_KB_DEV *UsbKeyboardDevice, IN UINT8 KeyCode @@ -470,7 +499,6 @@ GetKeyDescriptor ( **/ USB_NS_KEY * -EFIAPI FindUsbNsKey ( IN USB_KB_DEV *UsbKeyboardDevice, IN EFI_KEY_DESCRIPTOR *KeyDescriptor @@ -511,7 +539,6 @@ FindUsbNsKey ( **/ EFI_KEY_DESCRIPTOR * -EFIAPI FindPhysicalKey ( IN USB_NS_KEY *UsbNsKey, IN EFI_KEY_DESCRIPTOR *KeyDescriptor @@ -566,6 +593,9 @@ SetKeyboardLayoutEvent ( UINT8 KeyCode; UsbKeyboardDevice = (USB_KB_DEV *) Context; + if (UsbKeyboardDevice->Signature != USB_KB_DEV_SIGNATURE) { + return; + } // // Try to get current keyboard layout from HII database @@ -611,9 +641,9 @@ SetKeyboardLayoutEvent ( // KeyCount = 0; NsKey = KeyDescriptor + 1; - for (Index2 = Index + 1; Index2 < KeyboardLayout->DescriptorCount; Index2++) { + for (Index2 = (UINT8) Index + 1; Index2 < KeyboardLayout->DescriptorCount; Index2++) { CopyMem (&TempKey, NsKey, sizeof (EFI_KEY_DESCRIPTOR)); - if (TempKey.Modifier & EFI_NS_KEY_DEPENDENCY_MODIFIER) { + if (TempKey.Modifier == EFI_NS_KEY_DEPENDENCY_MODIFIER) { KeyCount++; } else { break; @@ -656,7 +686,6 @@ SetKeyboardLayoutEvent ( **/ VOID -EFIAPI ReleaseKeyboardLayoutResources ( IN OUT USB_KB_DEV *UsbKeyboardDevice ) @@ -695,7 +724,6 @@ ReleaseKeyboardLayoutResources ( **/ EFI_STATUS -EFIAPI InitKeyboardLayout ( OUT USB_KB_DEV *UsbKeyboardDevice ) @@ -719,7 +747,7 @@ InitKeyboardLayout ( TPL_NOTIFY, SetKeyboardLayoutEvent, UsbKeyboardDevice, - &mKeyboardLayoutEventGuid, + &gEfiHiiKeyBoardLayoutGuid, &UsbKeyboardDevice->KeyboardLayoutEvent ); if (EFI_ERROR (Status)) { @@ -745,7 +773,7 @@ InitKeyboardLayout ( // If no keyboard layout can be retrieved from HII database, and default layout // is enabled, then load the default keyboard layout. // - LoadDefaultKeyboardLayout (UsbKeyboardDevice); + InstallDefaultKeyboardLayout (UsbKeyboardDevice); } return EFI_SUCCESS; @@ -762,12 +790,11 @@ InitKeyboardLayout ( **/ EFI_STATUS -EFIAPI InitUSBKeyboard ( IN OUT USB_KB_DEV *UsbKeyboardDevice ) { - UINT8 ConfigValue; + UINT16 ConfigValue; UINT8 Protocol; UINT8 ReportId; UINT8 Duration; @@ -776,19 +803,32 @@ InitUSBKeyboard ( REPORT_STATUS_CODE_WITH_DEVICE_PATH ( EFI_PROGRESS_CODE, - PcdGet32 (PcdStatusCodeValueKeyboardSelfTest), + (EFI_PERIPHERAL_KEYBOARD | EFI_P_KEYBOARD_PC_SELF_TEST), UsbKeyboardDevice->DevicePath ); - InitUSBKeyBuffer (&(UsbKeyboardDevice->KeyboardBuffer)); + InitQueue (&UsbKeyboardDevice->UsbKeyQueue, sizeof (USB_KEY)); + InitQueue (&UsbKeyboardDevice->EfiKeyQueue, sizeof (EFI_KEY_DATA)); // - // Uses default configuration to configure the USB keyboard device. + // Use the config out of the descriptor + // Assumed the first config is the correct one and this is not always the case + // + Status = UsbGetConfiguration ( + UsbKeyboardDevice->UsbIo, + &ConfigValue, + &TransferResult + ); + if (EFI_ERROR (Status)) { + ConfigValue = 0x01; + } + + // + // Uses default configuration to configure the USB Keyboard device. // - ConfigValue = 0x01; Status = UsbSetConfiguration ( UsbKeyboardDevice->UsbIo, - (UINT16) ConfigValue, + ConfigValue, &TransferResult ); if (EFI_ERROR (Status)) { @@ -799,7 +839,7 @@ InitUSBKeyboard ( // REPORT_STATUS_CODE_WITH_DEVICE_PATH ( EFI_ERROR_CODE | EFI_ERROR_MINOR, - PcdGet32 (PcdStatusCodeValueKeyboardInterfaceError), + (EFI_PERIPHERAL_KEYBOARD | EFI_P_EC_INTERFACE_ERROR), UsbKeyboardDevice->DevicePath ); @@ -879,7 +919,7 @@ InitUSBKeyboard ( gBS->CreateEvent ( EVT_TIMER | EVT_NOTIFY_SIGNAL, - TPL_NOTIFY, + TPL_CALLBACK, USBKeyboardRepeatHandler, UsbKeyboardDevice, &UsbKeyboardDevice->RepeatTimer @@ -939,12 +979,10 @@ KeyboardHandler ( UINT8 CurModifierMap; UINT8 OldModifierMap; UINT8 Mask; - UINT8 Index; + UINTN Index; UINT8 Index2; - BOOLEAN Down; BOOLEAN KeyRelease; BOOLEAN KeyPress; - UINT8 SavedTail; USB_KEY UsbKey; UINT8 NewRepeatKey; UINT32 UsbStatus; @@ -965,7 +1003,7 @@ KeyboardHandler ( // REPORT_STATUS_CODE_WITH_DEVICE_PATH ( EFI_ERROR_CODE | EFI_ERROR_MINOR, - PcdGet32 (PcdStatusCodeValueKeyboardInputError), + (EFI_PERIPHERAL_KEYBOARD | EFI_P_EC_INPUT_ERROR), UsbKeyboardDevice->DevicePath ); @@ -1072,8 +1110,9 @@ KeyboardHandler ( // otherwise it is a non-zero value. // Insert the changed modifier key into key buffer. // - Down = (BOOLEAN) ((CurModifierMap & Mask) != 0); - InsertKeyCode (&(UsbKeyboardDevice->KeyboardBuffer), (UINT8) (0xe0 + Index), Down); + UsbKey.KeyCode = (UINT8) (0xe0 + Index); + UsbKey.Down = (BOOLEAN) ((CurModifierMap & Mask) != 0); + Enqueue (&UsbKeyboardDevice->UsbKeyQueue, &UsbKey, sizeof (UsbKey)); } } @@ -1105,11 +1144,9 @@ KeyboardHandler ( } if (KeyRelease) { - InsertKeyCode ( - &(UsbKeyboardDevice->KeyboardBuffer), - OldKeyCodeBuffer[Index], - FALSE - ); + UsbKey.KeyCode = OldKeyCodeBuffer[Index]; + UsbKey.Down = FALSE; + Enqueue (&UsbKeyboardDevice->UsbKeyQueue, &UsbKey, sizeof (UsbKey)); // // The original repeat key is released. // @@ -1157,7 +1194,9 @@ KeyboardHandler ( } if (KeyPress) { - InsertKeyCode (&(UsbKeyboardDevice->KeyboardBuffer), CurKeyCodeBuffer[Index], TRUE); + UsbKey.KeyCode = CurKeyCodeBuffer[Index]; + UsbKey.Down = TRUE; + Enqueue (&UsbKeyboardDevice->UsbKeyQueue, &UsbKey, sizeof (UsbKey)); // // Handle repeat key @@ -1187,71 +1226,6 @@ KeyboardHandler ( UsbKeyboardDevice->LastKeyCodeArray[Index] = CurKeyCodeBuffer[Index]; } - // - // Pre-process KeyboardBuffer to check if Ctrl + Alt + Del is pressed. - // - SavedTail = UsbKeyboardDevice->KeyboardBuffer.BufferTail; - Index = UsbKeyboardDevice->KeyboardBuffer.BufferHead; - while (Index != SavedTail) { - RemoveKeyCode (&(UsbKeyboardDevice->KeyboardBuffer), &UsbKey); - - KeyDescriptor = GetKeyDescriptor (UsbKeyboardDevice, UsbKey.KeyCode); - - switch (KeyDescriptor->Modifier) { - - case EFI_LEFT_CONTROL_MODIFIER: - case EFI_RIGHT_CONTROL_MODIFIER: - if (UsbKey.Down) { - UsbKeyboardDevice->CtrlOn = TRUE; - } else { - UsbKeyboardDevice->CtrlOn = FALSE; - } - break; - - case EFI_LEFT_ALT_MODIFIER: - case EFI_RIGHT_ALT_MODIFIER: - if (UsbKey.Down) { - UsbKeyboardDevice->AltOn = TRUE; - } else { - UsbKeyboardDevice->AltOn = FALSE; - } - break; - - case EFI_ALT_GR_MODIFIER: - if (UsbKey.Down) { - UsbKeyboardDevice->AltGrOn = TRUE; - } else { - UsbKeyboardDevice->AltGrOn = FALSE; - } - break; - - // - // For Del Key, check if Ctrl + Alt + Del occurs for reset. - // - case EFI_DELETE_MODIFIER: - if (UsbKey.Down) { - if ((UsbKeyboardDevice->CtrlOn) && (UsbKeyboardDevice->AltOn)) { - gRT->ResetSystem (EfiResetWarm, EFI_SUCCESS, 0, NULL); - } - } - break; - - default: - break; - } - - // - // Insert the key back to the buffer, - // so the key sequence will not be destroyed. - // - InsertKeyCode ( - &(UsbKeyboardDevice->KeyboardBuffer), - UsbKey.KeyCode, - UsbKey.Down - ); - Index = UsbKeyboardDevice->KeyboardBuffer.BufferHead; - - } // // If there is new key pressed, update the RepeatKey value, and set the // timer to repeate delay timer @@ -1288,7 +1262,6 @@ KeyboardHandler ( **/ EFI_STATUS -EFIAPI USBParseKey ( IN OUT USB_KB_DEV *UsbKeyboardDevice, OUT UINT8 *KeyCode @@ -1299,11 +1272,11 @@ USBParseKey ( *KeyCode = 0; - while (!IsUSBKeyboardBufferEmpty (&UsbKeyboardDevice->KeyboardBuffer)) { + while (!IsQueueEmpty (&UsbKeyboardDevice->UsbKeyQueue)) { // // Pops one raw data off. // - RemoveKeyCode (&(UsbKeyboardDevice->KeyboardBuffer), &UsbKey); + Dequeue (&UsbKeyboardDevice->UsbKeyQueue, &UsbKey, sizeof (UsbKey)); KeyDescriptor = GetKeyDescriptor (UsbKeyboardDevice, UsbKey.KeyCode); ASSERT (KeyDescriptor != NULL); @@ -1504,20 +1477,6 @@ USBParseKey ( continue; break; - // - // F11, F12, PrintScreen, Pause/Break - // could not be retrieved via SimpleTextInEx protocol - // - case EFI_FUNCTION_KEY_ELEVEN_MODIFIER: - case EFI_FUNCTION_KEY_TWELVE_MODIFIER: - case EFI_PAUSE_MODIFIER: - case EFI_BREAK_MODIFIER: - // - // Fall through - // - continue; - break; - default: break; } @@ -1544,7 +1503,7 @@ USBParseKey ( @param UsbKeyboardDevice The USB_KB_DEV instance. @param KeyCode Indicates the key code that will be interpreted. - @param Key A pointer to a buffer that is filled in with + @param KeyData A pointer to a buffer that is filled in with the keystroke information for the key that was pressed. @@ -1556,14 +1515,16 @@ USBParseKey ( **/ EFI_STATUS -EFIAPI UsbKeyCodeToEfiInputKey ( - IN USB_KB_DEV *UsbKeyboardDevice, - IN UINT8 KeyCode, - OUT EFI_INPUT_KEY *Key + IN USB_KB_DEV *UsbKeyboardDevice, + IN UINT8 KeyCode, + OUT EFI_KEY_DATA *KeyData ) { - EFI_KEY_DESCRIPTOR *KeyDescriptor; + EFI_KEY_DESCRIPTOR *KeyDescriptor; + LIST_ENTRY *Link; + LIST_ENTRY *NotifyList; + KEYBOARD_CONSOLE_IN_EX_NOTIFY *CurrentNotify; // // KeyCode must in the range of 0x4 to 0x65 @@ -1598,16 +1559,16 @@ UsbKeyCodeToEfiInputKey ( // // Make sure modifier of Key Descriptor is in the valid range according to UEFI spec. // - if (KeyDescriptor->Modifier > EFI_FUNCTION_KEY_TWELVE_MODIFIER) { + if (KeyDescriptor->Modifier >= (sizeof (ModifierValueToEfiScanCodeConvertionTable) / sizeof (UINT8))) { return EFI_DEVICE_ERROR; } - Key->ScanCode = ModifierValueToEfiScanCodeConvertionTable[KeyDescriptor->Modifier]; - Key->UnicodeChar = KeyDescriptor->Unicode; + KeyData->Key.ScanCode = ModifierValueToEfiScanCodeConvertionTable[KeyDescriptor->Modifier]; + KeyData->Key.UnicodeChar = KeyDescriptor->Unicode; if ((KeyDescriptor->AffectedAttribute & EFI_AFFECTED_BY_STANDARD_SHIFT)!= 0) { if (UsbKeyboardDevice->ShiftOn) { - Key->UnicodeChar = KeyDescriptor->ShiftedUnicode; + KeyData->Key.UnicodeChar = KeyDescriptor->ShiftedUnicode; // // Need not return associated shift state if a class of printable characters that @@ -1619,248 +1580,278 @@ UsbKeyCodeToEfiInputKey ( } if (UsbKeyboardDevice->AltGrOn) { - Key->UnicodeChar = KeyDescriptor->ShiftedAltGrUnicode; + KeyData->Key.UnicodeChar = KeyDescriptor->ShiftedAltGrUnicode; } } else { // // Shift off // - Key->UnicodeChar = KeyDescriptor->Unicode; + KeyData->Key.UnicodeChar = KeyDescriptor->Unicode; if (UsbKeyboardDevice->AltGrOn) { - Key->UnicodeChar = KeyDescriptor->AltGrUnicode; + KeyData->Key.UnicodeChar = KeyDescriptor->AltGrUnicode; } } } if ((KeyDescriptor->AffectedAttribute & EFI_AFFECTED_BY_CAPS_LOCK) != 0) { if (UsbKeyboardDevice->CapsOn) { - if (Key->UnicodeChar == KeyDescriptor->Unicode) { - Key->UnicodeChar = KeyDescriptor->ShiftedUnicode; - } else if (Key->UnicodeChar == KeyDescriptor->ShiftedUnicode) { - Key->UnicodeChar = KeyDescriptor->Unicode; + if (KeyData->Key.UnicodeChar == KeyDescriptor->Unicode) { + KeyData->Key.UnicodeChar = KeyDescriptor->ShiftedUnicode; + } else if (KeyData->Key.UnicodeChar == KeyDescriptor->ShiftedUnicode) { + KeyData->Key.UnicodeChar = KeyDescriptor->Unicode; } } } - // - // Translate the CTRL-Alpha characters to their corresponding control value - // (ctrl-a = 0x0001 through ctrl-Z = 0x001A) - // - if (UsbKeyboardDevice->CtrlOn) { - if (Key->UnicodeChar >= 'a' && Key->UnicodeChar <= 'z') { - Key->UnicodeChar = (UINT8) (Key->UnicodeChar - 'a' + 1); - } else if (Key->UnicodeChar >= 'A' && Key->UnicodeChar <= 'Z') { - Key->UnicodeChar = (UINT8) (Key->UnicodeChar - 'A' + 1); - } - } - - if (KeyDescriptor->AffectedAttribute & EFI_AFFECTED_BY_NUM_LOCK) { + if ((KeyDescriptor->AffectedAttribute & EFI_AFFECTED_BY_NUM_LOCK) != 0) { // // For key affected by NumLock, if NumLock is on and Shift is not pressed, then it means // normal key, instead of original control key. So the ScanCode should be cleaned. // Otherwise, it means control key, so preserve the EFI Scan Code and clear the unicode keycode. // if ((UsbKeyboardDevice->NumLockOn) && (!(UsbKeyboardDevice->ShiftOn))) { - Key->ScanCode = SCAN_NULL; + KeyData->Key.ScanCode = SCAN_NULL; } else { - Key->UnicodeChar = 0x00; + KeyData->Key.UnicodeChar = 0x00; } } // // Translate Unicode 0x1B (ESC) to EFI Scan Code // - if (Key->UnicodeChar == 0x1B && Key->ScanCode == SCAN_NULL) { - Key->ScanCode = SCAN_ESC; - Key->UnicodeChar = 0x00; + if (KeyData->Key.UnicodeChar == 0x1B && KeyData->Key.ScanCode == SCAN_NULL) { + KeyData->Key.ScanCode = SCAN_ESC; + KeyData->Key.UnicodeChar = 0x00; } // // Not valid for key without both unicode key code and EFI Scan Code. // - if (Key->UnicodeChar == 0 && Key->ScanCode == SCAN_NULL) { + if (KeyData->Key.UnicodeChar == 0 && KeyData->Key.ScanCode == SCAN_NULL) { return EFI_NOT_READY; } - // // Save Shift/Toggle state // + KeyData->KeyState.KeyShiftState = EFI_SHIFT_STATE_VALID; + KeyData->KeyState.KeyToggleState = EFI_TOGGLE_STATE_VALID; + if (UsbKeyboardDevice->LeftCtrlOn) { - UsbKeyboardDevice->KeyState.KeyShiftState |= EFI_LEFT_CONTROL_PRESSED; + KeyData->KeyState.KeyShiftState |= EFI_LEFT_CONTROL_PRESSED; } if (UsbKeyboardDevice->RightCtrlOn) { - UsbKeyboardDevice->KeyState.KeyShiftState |= EFI_RIGHT_CONTROL_PRESSED; + KeyData->KeyState.KeyShiftState |= EFI_RIGHT_CONTROL_PRESSED; } if (UsbKeyboardDevice->LeftAltOn) { - UsbKeyboardDevice->KeyState.KeyShiftState |= EFI_LEFT_ALT_PRESSED; + KeyData->KeyState.KeyShiftState |= EFI_LEFT_ALT_PRESSED; } if (UsbKeyboardDevice->RightAltOn) { - UsbKeyboardDevice->KeyState.KeyShiftState |= EFI_RIGHT_ALT_PRESSED; + KeyData->KeyState.KeyShiftState |= EFI_RIGHT_ALT_PRESSED; } if (UsbKeyboardDevice->LeftShiftOn) { - UsbKeyboardDevice->KeyState.KeyShiftState |= EFI_LEFT_SHIFT_PRESSED; + KeyData->KeyState.KeyShiftState |= EFI_LEFT_SHIFT_PRESSED; } if (UsbKeyboardDevice->RightShiftOn) { - UsbKeyboardDevice->KeyState.KeyShiftState |= EFI_RIGHT_SHIFT_PRESSED; + KeyData->KeyState.KeyShiftState |= EFI_RIGHT_SHIFT_PRESSED; } if (UsbKeyboardDevice->LeftLogoOn) { - UsbKeyboardDevice->KeyState.KeyShiftState |= EFI_LEFT_LOGO_PRESSED; + KeyData->KeyState.KeyShiftState |= EFI_LEFT_LOGO_PRESSED; } if (UsbKeyboardDevice->RightLogoOn) { - UsbKeyboardDevice->KeyState.KeyShiftState |= EFI_RIGHT_LOGO_PRESSED; + KeyData->KeyState.KeyShiftState |= EFI_RIGHT_LOGO_PRESSED; } if (UsbKeyboardDevice->MenuKeyOn) { - UsbKeyboardDevice->KeyState.KeyShiftState |= EFI_MENU_KEY_PRESSED; + KeyData->KeyState.KeyShiftState |= EFI_MENU_KEY_PRESSED; } if (UsbKeyboardDevice->SysReqOn) { - UsbKeyboardDevice->KeyState.KeyShiftState |= EFI_SYS_REQ_PRESSED; + KeyData->KeyState.KeyShiftState |= EFI_SYS_REQ_PRESSED; } if (UsbKeyboardDevice->ScrollOn) { - UsbKeyboardDevice->KeyState.KeyToggleState |= EFI_SCROLL_LOCK_ACTIVE; + KeyData->KeyState.KeyToggleState |= EFI_SCROLL_LOCK_ACTIVE; } if (UsbKeyboardDevice->NumLockOn) { - UsbKeyboardDevice->KeyState.KeyToggleState |= EFI_NUM_LOCK_ACTIVE; + KeyData->KeyState.KeyToggleState |= EFI_NUM_LOCK_ACTIVE; } if (UsbKeyboardDevice->CapsOn) { - UsbKeyboardDevice->KeyState.KeyToggleState |= EFI_CAPS_LOCK_ACTIVE; + KeyData->KeyState.KeyToggleState |= EFI_CAPS_LOCK_ACTIVE; } - return EFI_SUCCESS; + // + // Invoke notification functions if the key is registered. + // + NotifyList = &UsbKeyboardDevice->NotifyList; + for (Link = GetFirstNode (NotifyList); !IsNull (NotifyList, Link); Link = GetNextNode (NotifyList, Link)) { + CurrentNotify = CR (Link, KEYBOARD_CONSOLE_IN_EX_NOTIFY, NotifyEntry, USB_KB_CONSOLE_IN_EX_NOTIFY_SIGNATURE); + if (IsKeyRegistered (&CurrentNotify->KeyData, KeyData)) { + CurrentNotify->KeyNotificationFn (KeyData); + } + } + + // + // Translate the CTRL-Alpha characters to their corresponding control value + // (ctrl-a = 0x0001 through ctrl-Z = 0x001A) + // + if (UsbKeyboardDevice->CtrlOn) { + if (KeyData->Key.UnicodeChar >= 'a' && KeyData->Key.UnicodeChar <= 'z') { + KeyData->Key.UnicodeChar = (UINT8) (KeyData->Key.UnicodeChar - 'a' + 1); + } else if (KeyData->Key.UnicodeChar >= 'A' && KeyData->Key.UnicodeChar <= 'Z') { + KeyData->Key.UnicodeChar = (UINT8) (KeyData->Key.UnicodeChar - 'A' + 1); + } + } + return EFI_SUCCESS; } /** - Resets USB keyboard buffer. + Create the queue. - @param KeyboardBuffer Points to the USB keyboard buffer. + @param Queue Points to the queue. + @param ItemSize Size of the single item. **/ VOID -EFIAPI -InitUSBKeyBuffer ( - OUT USB_KB_BUFFER *KeyboardBuffer +InitQueue ( + IN OUT USB_SIMPLE_QUEUE *Queue, + IN UINTN ItemSize ) { - ZeroMem (KeyboardBuffer, sizeof (USB_KB_BUFFER)); + UINTN Index; + + Queue->ItemSize = ItemSize; + Queue->Head = 0; + Queue->Tail = 0; + + if (Queue->Buffer[0] != NULL) { + FreePool (Queue->Buffer[0]); + } + + Queue->Buffer[0] = AllocatePool (sizeof (Queue->Buffer) / sizeof (Queue->Buffer[0]) * ItemSize); + ASSERT (Queue->Buffer[0] != NULL); + + for (Index = 1; Index < sizeof (Queue->Buffer) / sizeof (Queue->Buffer[0]); Index++) { + Queue->Buffer[Index] = ((UINT8 *) Queue->Buffer[Index - 1]) + ItemSize; + } +} + +/** + Destroy the queue - KeyboardBuffer->BufferHead = KeyboardBuffer->BufferTail; + @param Queue Points to the queue. +**/ +VOID +DestroyQueue ( + IN OUT USB_SIMPLE_QUEUE *Queue + ) +{ + FreePool (Queue->Buffer[0]); } /** - Check whether USB keyboard buffer is empty. + Check whether the queue is empty. - @param KeyboardBuffer USB keyboard buffer + @param Queue Points to the queue. - @retval TRUE Keyboard buffer is empty. - @retval FALSE Keyboard buffer is not empty. + @retval TRUE Queue is empty. + @retval FALSE Queue is not empty. **/ BOOLEAN -EFIAPI -IsUSBKeyboardBufferEmpty ( - IN USB_KB_BUFFER *KeyboardBuffer +IsQueueEmpty ( + IN USB_SIMPLE_QUEUE *Queue ) { // // Meet FIFO empty condition // - return (BOOLEAN) (KeyboardBuffer->BufferHead == KeyboardBuffer->BufferTail); + return (BOOLEAN) (Queue->Head == Queue->Tail); } /** - Check whether USB keyboard buffer is full. + Check whether the queue is full. - @param KeyboardBuffer USB keyboard buffer + @param Queue Points to the queue. - @retval TRUE Keyboard buffer is full. - @retval FALSE Keyboard buffer is not full. + @retval TRUE Queue is full. + @retval FALSE Queue is not full. **/ BOOLEAN -EFIAPI -IsUSBKeyboardBufferFull ( - IN USB_KB_BUFFER *KeyboardBuffer +IsQueueFull ( + IN USB_SIMPLE_QUEUE *Queue ) { - return (BOOLEAN)(((KeyboardBuffer->BufferTail + 1) % (MAX_KEY_ALLOWED + 1)) == KeyboardBuffer->BufferHead); + return (BOOLEAN) (((Queue->Tail + 1) % (MAX_KEY_ALLOWED + 1)) == Queue->Head); } /** - Inserts a keycode into keyboard buffer. - - @param KeyboardBuffer Points to the USB keyboard buffer. - @param Key Keycode to insert. - @param Down TRUE means key is pressed. - FALSE means key is released. + Enqueue the item to the queue. + @param Queue Points to the queue. + @param Item Points to the item to be enqueued. + @param ItemSize Size of the item. **/ VOID -EFIAPI -InsertKeyCode ( - IN OUT USB_KB_BUFFER *KeyboardBuffer, - IN UINT8 Key, - IN BOOLEAN Down +Enqueue ( + IN OUT USB_SIMPLE_QUEUE *Queue, + IN VOID *Item, + IN UINTN ItemSize ) { - USB_KEY UsbKey; - + ASSERT (ItemSize == Queue->ItemSize); // // If keyboard buffer is full, throw the // first key out of the keyboard buffer. // - if (IsUSBKeyboardBufferFull (KeyboardBuffer)) { - RemoveKeyCode (KeyboardBuffer, &UsbKey); + if (IsQueueFull (Queue)) { + Queue->Head = (Queue->Head + 1) % (MAX_KEY_ALLOWED + 1); } - ASSERT (KeyboardBuffer->BufferTail <= MAX_KEY_ALLOWED); - - KeyboardBuffer->Buffer[KeyboardBuffer->BufferTail].KeyCode = Key; - KeyboardBuffer->Buffer[KeyboardBuffer->BufferTail].Down = Down; + CopyMem (Queue->Buffer[Queue->Tail], Item, ItemSize); // // Adjust the tail pointer of the FIFO keyboard buffer. // - KeyboardBuffer->BufferTail = (UINT8) ((KeyboardBuffer->BufferTail + 1) % (MAX_KEY_ALLOWED + 1)); + Queue->Tail = (Queue->Tail + 1) % (MAX_KEY_ALLOWED + 1); } /** - Remove a keycode from keyboard buffer and return it. + Dequeue a item from the queue. - @param KeyboardBuffer Points to the USB keyboard buffer. - @param UsbKey Points to the buffer that contains keycode for output. + @param Queue Points to the queue. + @param Item Receives the item. + @param ItemSize Size of the item. - @retval EFI_SUCCESS Keycode successfully removed from keyboard buffer. - @retval EFI_DEVICE_ERROR Keyboard buffer is empty. + @retval EFI_SUCCESS Item was successfully dequeued. + @retval EFI_DEVICE_ERROR The queue is empty. **/ EFI_STATUS -EFIAPI -RemoveKeyCode ( - IN OUT USB_KB_BUFFER *KeyboardBuffer, - OUT USB_KEY *UsbKey +Dequeue ( + IN OUT USB_SIMPLE_QUEUE *Queue, + OUT VOID *Item, + IN UINTN ItemSize ) { - if (IsUSBKeyboardBufferEmpty (KeyboardBuffer)) { + ASSERT (Queue->ItemSize == ItemSize); + + if (IsQueueEmpty (Queue)) { return EFI_DEVICE_ERROR; } - ASSERT (KeyboardBuffer->BufferHead <= MAX_KEY_ALLOWED); - - UsbKey->KeyCode = KeyboardBuffer->Buffer[KeyboardBuffer->BufferHead].KeyCode; - UsbKey->Down = KeyboardBuffer->Buffer[KeyboardBuffer->BufferHead].Down; + CopyMem (Item, Queue->Buffer[Queue->Head], ItemSize); // // Adjust the head pointer of the FIFO keyboard buffer. // - KeyboardBuffer->BufferHead = (UINT8) ((KeyboardBuffer->BufferHead + 1) % (MAX_KEY_ALLOWED + 1)); + Queue->Head = (Queue->Head + 1) % (MAX_KEY_ALLOWED + 1); return EFI_SUCCESS; } @@ -1873,7 +1864,6 @@ RemoveKeyCode ( **/ VOID -EFIAPI SetKeyLED ( IN USB_KB_DEV *UsbKeyboardDevice ) @@ -1925,6 +1915,7 @@ USBKeyboardRepeatHandler ( ) { USB_KB_DEV *UsbKeyboardDevice; + USB_KEY UsbKey; UsbKeyboardDevice = (USB_KB_DEV *) Context; @@ -1935,11 +1926,9 @@ USBKeyboardRepeatHandler ( // // Inserts the repeat key into keyboard buffer, // - InsertKeyCode ( - &(UsbKeyboardDevice->KeyboardBuffer), - UsbKeyboardDevice->RepeatKey, - TRUE - ); + UsbKey.KeyCode = UsbKeyboardDevice->RepeatKey; + UsbKey.Down = TRUE; + Enqueue (&UsbKeyboardDevice->UsbKeyQueue, &UsbKey, sizeof (UsbKey)); // // Set repeat rate for next repeat key generation.