#include "Ps2Keyboard.h"\r
\r
struct {\r
- UINT16 ScanCode; ///< follows value defined in Scan Code Set1\r
+ UINT8 ScanCode; ///< follows value defined in Scan Code Set1\r
UINT16 EfiScanCode;\r
CHAR16 UnicodeChar;\r
CHAR16 ShiftUnicodeChar;\r
SCAN_NULL,\r
0x0000,\r
0x0000\r
- }, \r
- {\r
- SCANCODE_PAUSE_MAKE, //Pause key\r
- SCAN_PAUSE,\r
- 0x0000,\r
- 0x0000\r
- }, \r
+ },\r
{\r
TABLE_END,\r
TABLE_END,\r
{\r
EFI_STATUS Status;\r
UINT16 ScanCode;\r
- BOOLEAN Extended;\r
- BOOLEAN Extended1;\r
+ BOOLEAN Extend0;\r
+ BOOLEAN Extend1;\r
UINTN Index;\r
EFI_KEY_DATA KeyData;\r
LIST_ENTRY *Link;\r
KEYBOARD_CONSOLE_IN_EX_NOTIFY *CurrentNotify;\r
//\r
- // 6 bytes most\r
+ // 3 bytes most\r
//\r
- UINT8 ScancodeArr[6];\r
+ UINT8 ScancodeArr[3];\r
UINT32 ScancodeArrPos;\r
\r
//\r
// available in the buffer\r
//\r
while (TRUE) {\r
- Extended = FALSE;\r
- Extended1 = FALSE;\r
- Status = GetScancodeBufHead (&ConsoleIn->ScancodeQueue, 1, ScancodeArr);\r
- //\r
- // point to the current position in ScancodeArr\r
- //\r
- ScancodeArrPos = 0;\r
+ Extend0 = FALSE;\r
+ Extend1 = FALSE;\r
+ ScancodeArrPos = 0;\r
+ Status = GetScancodeBufHead (&ConsoleIn->ScancodeQueue, ScancodeArrPos + 1, ScancodeArr);\r
if (EFI_ERROR (Status)) {\r
return ;\r
}\r
\r
- if (ScancodeArr[ScancodeArrPos] == SCANCODE_EXTENDED) {\r
- Extended = TRUE;\r
- Status = GetScancodeBufHead (&ConsoleIn->ScancodeQueue, 2, ScancodeArr);\r
- ScancodeArrPos = 1;\r
+ if (ScancodeArr[ScancodeArrPos] == SCANCODE_EXTENDED0) {\r
+ //\r
+ // E0 to look ahead 2 bytes\r
+ //\r
+ Extend0 = TRUE;\r
+ ScancodeArrPos = 1;\r
+ Status = GetScancodeBufHead (&ConsoleIn->ScancodeQueue, ScancodeArrPos + 1, ScancodeArr);\r
if (EFI_ERROR (Status)) {\r
return ;\r
}\r
- }\r
- //\r
- // Checks for key scancode for PAUSE:E1-1D/45-E1/9D-C5\r
- // if present, ignore them\r
- //\r
- if (ScancodeArr[ScancodeArrPos] == SCANCODE_EXTENDED1) {\r
- Extended1 = TRUE;\r
+ } else if (ScancodeArr[ScancodeArrPos] == SCANCODE_EXTENDED1) {\r
//\r
- // Try to read the whole bytes of scancode for PAUSE key\r
+ // E1 to look ahead 3 bytes\r
//\r
- Status = GetScancodeBufHead (&ConsoleIn->ScancodeQueue, 6, ScancodeArr);\r
- ScancodeArrPos = 5;\r
+ Extend1 = TRUE;\r
+ ScancodeArrPos = 2;\r
+ Status = GetScancodeBufHead (&ConsoleIn->ScancodeQueue, ScancodeArrPos + 1, ScancodeArr);\r
if (EFI_ERROR (Status)) {\r
return ;\r
}\r
// if we reach this position, scancodes for a key is in buffer now,pop them\r
//\r
Status = PopScancodeBufHead (&ConsoleIn->ScancodeQueue, ScancodeArrPos + 1, ScancodeArr);\r
- if (EFI_ERROR (Status)) {\r
- return ;\r
- }\r
+ ASSERT_EFI_ERROR (Status);\r
\r
- if (!Extended1) {\r
- //\r
- // store the last available byte, this byte of scancode will be checked\r
- //\r
- ScanCode = ScancodeArr[ScancodeArrPos];\r
- \r
+ //\r
+ // store the last available byte, this byte of scancode will be checked\r
+ //\r
+ ScanCode = ScancodeArr[ScancodeArrPos];\r
+\r
+ if (!Extend1) {\r
//\r
// Check for special keys and update the driver state.\r
//\r
switch (ScanCode) {\r
\r
case SCANCODE_CTRL_MAKE:\r
- ConsoleIn->Ctrl = TRUE;\r
- break;\r
- \r
+ if (Extend0) {\r
+ ConsoleIn->RightCtrl = TRUE;\r
+ } else {\r
+ ConsoleIn->LeftCtrl = TRUE;\r
+ }\r
+ break; \r
case SCANCODE_CTRL_BREAK:\r
- ConsoleIn->Ctrl = FALSE;\r
+ if (Extend0) {\r
+ ConsoleIn->RightCtrl = FALSE;\r
+ } else {\r
+ ConsoleIn->LeftCtrl = FALSE;\r
+ }\r
break;\r
- \r
+\r
case SCANCODE_ALT_MAKE:\r
- ConsoleIn->Alt = TRUE;\r
- break;\r
- \r
+ if (Extend0) {\r
+ ConsoleIn->RightAlt = TRUE;\r
+ } else {\r
+ ConsoleIn->LeftAlt = TRUE;\r
+ }\r
+ break; \r
case SCANCODE_ALT_BREAK:\r
- ConsoleIn->Alt = FALSE;\r
+ if (Extend0) {\r
+ ConsoleIn->RightAlt = FALSE;\r
+ } else {\r
+ ConsoleIn->LeftAlt = FALSE;\r
+ }\r
break;\r
- \r
+\r
case SCANCODE_LEFT_SHIFT_MAKE:\r
- if (!Extended) {\r
- ConsoleIn->Shift = TRUE;\r
- ConsoleIn->LeftShift = TRUE;\r
- } \r
- break;\r
- case SCANCODE_RIGHT_SHIFT_MAKE:\r
- if (!Extended) {\r
- ConsoleIn->Shift = TRUE;\r
- ConsoleIn->RightShift = TRUE;\r
+ //\r
+ // To avoid recognize PRNT_SCRN key as a L_SHIFT key\r
+ // because PRNT_SCRN key generates E0 followed by L_SHIFT scan code\r
+ //\r
+ if (!Extend0) {\r
+ ConsoleIn->LeftShift = TRUE;\r
}\r
break;\r
- \r
case SCANCODE_LEFT_SHIFT_BREAK:\r
- if (!Extended) {\r
- ConsoleIn->Shift = FALSE;\r
+ if (!Extend0) {\r
ConsoleIn->LeftShift = FALSE;\r
- } else {\r
- ConsoleIn->SysReq = FALSE;\r
- } \r
+ }\r
+ break;\r
+\r
+ case SCANCODE_RIGHT_SHIFT_MAKE:\r
+ ConsoleIn->RightShift = TRUE;\r
break;\r
case SCANCODE_RIGHT_SHIFT_BREAK:\r
- if (!Extended) {\r
- ConsoleIn->Shift = FALSE;\r
- ConsoleIn->RightShift = FALSE;\r
- }\r
+ ConsoleIn->RightShift = FALSE;\r
break;\r
\r
case SCANCODE_LEFT_LOGO_MAKE:\r
ConsoleIn->LeftLogo = TRUE;\r
- break; \r
+ break;\r
case SCANCODE_LEFT_LOGO_BREAK:\r
ConsoleIn->LeftLogo = FALSE;\r
- break; \r
+ break;\r
+\r
case SCANCODE_RIGHT_LOGO_MAKE:\r
ConsoleIn->RightLogo = TRUE;\r
break;\r
case SCANCODE_RIGHT_LOGO_BREAK:\r
ConsoleIn->RightLogo = FALSE;\r
- break; \r
+ break;\r
+\r
case SCANCODE_MENU_MAKE:\r
ConsoleIn->Menu = TRUE;\r
break;\r
case SCANCODE_MENU_BREAK:\r
ConsoleIn->Menu = FALSE;\r
- break; \r
+ break;\r
+\r
case SCANCODE_SYS_REQ_MAKE:\r
- if (Extended) {\r
+ if (Extend0) {\r
ConsoleIn->SysReq = TRUE;\r
}\r
break;\r
+ case SCANCODE_SYS_REQ_BREAK:\r
+ if (Extend0) {\r
+ ConsoleIn->SysReq = FALSE;\r
+ }\r
+ break;\r
+\r
+ case SCANCODE_SYS_REQ_MAKE_WITH_ALT:\r
+ ConsoleIn->SysReq = TRUE;\r
+ break;\r
+ case SCANCODE_SYS_REQ_BREAK_WITH_ALT:\r
+ ConsoleIn->SysReq = FALSE;\r
+ break;\r
+\r
case SCANCODE_CAPS_LOCK_MAKE:\r
ConsoleIn->CapsLock = (BOOLEAN)!ConsoleIn->CapsLock;\r
UpdateStatusLights (ConsoleIn);\r
UpdateStatusLights (ConsoleIn);\r
break;\r
case SCANCODE_SCROLL_LOCK_MAKE:\r
- ConsoleIn->ScrollLock = (BOOLEAN)!ConsoleIn->ScrollLock;\r
- UpdateStatusLights (ConsoleIn);\r
- break;\r
- }\r
- //\r
- // If this is above the valid range, ignore it\r
- //\r
- if (ScanCode >= SCANCODE_MAX_MAKE) {\r
- continue;\r
- } else {\r
+ if (!Extend0) {\r
+ ConsoleIn->ScrollLock = (BOOLEAN)!ConsoleIn->ScrollLock;\r
+ UpdateStatusLights (ConsoleIn);\r
+ }\r
break;\r
}\r
+ }\r
+ \r
+ //\r
+ // If this is above the valid range, ignore it\r
+ //\r
+ if (ScanCode >= SCANCODE_MAX_MAKE) {\r
+ continue;\r
} else {\r
- //\r
- // Store the last 2 available byte to check if it is Pause key\r
- //\r
- ScanCode = (UINT16) (ScancodeArr[ScancodeArrPos] + (ScancodeArr[ScancodeArrPos - 1] << 8));\r
- if (ScanCode == SCANCODE_PAUSE_MAKE) {\r
- break;\r
- }\r
+ break;\r
}\r
}\r
\r
//\r
// Handle Ctrl+Alt+Del hotkey\r
//\r
- if (ConsoleIn->Alt && ConsoleIn->Ctrl && ScanCode == SCANCODE_DELETE_MAKE) {\r
+ if ((ConsoleIn->LeftCtrl || ConsoleIn->RightCtrl) &&\r
+ (ConsoleIn->LeftAlt || ConsoleIn->RightAlt ) &&\r
+ ScanCode == SCANCODE_DELETE_MAKE\r
+ ) {\r
gRT->ResetSystem (EfiResetWarm, EFI_SUCCESS, 0, NULL);\r
}\r
\r
+ //\r
+ // Save the Shift/Toggle state\r
+ //\r
+ KeyData.KeyState.KeyShiftState = (UINT32) (EFI_SHIFT_STATE_VALID\r
+ | (ConsoleIn->LeftCtrl ? EFI_LEFT_CONTROL_PRESSED : 0)\r
+ | (ConsoleIn->RightCtrl ? EFI_RIGHT_CONTROL_PRESSED : 0)\r
+ | (ConsoleIn->LeftAlt ? EFI_LEFT_ALT_PRESSED : 0)\r
+ | (ConsoleIn->RightAlt ? EFI_RIGHT_ALT_PRESSED : 0)\r
+ | (ConsoleIn->LeftShift ? EFI_LEFT_SHIFT_PRESSED : 0)\r
+ | (ConsoleIn->RightShift ? EFI_RIGHT_SHIFT_PRESSED : 0)\r
+ | (ConsoleIn->LeftLogo ? EFI_LEFT_LOGO_PRESSED : 0)\r
+ | (ConsoleIn->RightLogo ? EFI_RIGHT_LOGO_PRESSED : 0)\r
+ | (ConsoleIn->Menu ? EFI_MENU_KEY_PRESSED : 0)\r
+ | (ConsoleIn->SysReq ? EFI_SYS_REQ_PRESSED : 0)\r
+ )\r
+ ;\r
+ KeyData.KeyState.KeyToggleState = (EFI_KEY_TOGGLE_STATE) (EFI_TOGGLE_STATE_VALID\r
+ | (ConsoleIn->CapsLock ? EFI_CAPS_LOCK_ACTIVE : 0)\r
+ | (ConsoleIn->NumLock ? EFI_NUM_LOCK_ACTIVE : 0)\r
+ | (ConsoleIn->ScrollLock ? EFI_SCROLL_LOCK_ACTIVE : 0)\r
+ )\r
+ ;\r
KeyData.Key.ScanCode = SCAN_NULL;\r
KeyData.Key.UnicodeChar = CHAR_NULL;\r
- KeyData.KeyState.KeyShiftState = EFI_SHIFT_STATE_VALID;\r
- KeyData.KeyState.KeyToggleState = EFI_TOGGLE_STATE_VALID;\r
\r
//\r
- // Treat Numeric Key Pad "/" specially\r
+ // Key Pad "/" shares the same scancode as that of "/" except Key Pad "/" has E0 prefix\r
//\r
- if (Extended && ScanCode == 0x35) {\r
+ if (Extend0 && ScanCode == 0x35) {\r
KeyData.Key.UnicodeChar = L'/';\r
KeyData.Key.ScanCode = SCAN_NULL;\r
+\r
+ //\r
+ // PAUSE shares the same scancode as that of NUM except PAUSE has E1 prefix\r
+ //\r
+ } else if (Extend1 && ScanCode == SCANCODE_NUM_LOCK_MAKE) {\r
+ KeyData.Key.UnicodeChar = CHAR_NULL;\r
+ KeyData.Key.ScanCode = SCAN_PAUSE;\r
+\r
+ //\r
+ // PAUSE shares the same scancode as that of SCROLL except PAUSE (CTRL pressed) has E0 prefix\r
+ //\r
+ } else if (Extend0 && ScanCode == SCANCODE_SCROLL_LOCK_MAKE) {\r
+ KeyData.Key.UnicodeChar = CHAR_NULL;\r
+ KeyData.Key.ScanCode = SCAN_PAUSE;\r
+\r
+ //\r
+ // PRNT_SCRN shares the same scancode as that of Key Pad "*" except PRNT_SCRN has E0 prefix\r
+ //\r
+ } else if (Extend0 && ScanCode == SCANCODE_SYS_REQ_MAKE) {\r
+ KeyData.Key.UnicodeChar = CHAR_NULL;\r
+ KeyData.Key.ScanCode = SCAN_NULL;\r
+\r
+ //\r
+ // Except the above special case, all others can be handled by convert table\r
+ //\r
} else {\r
- //\r
- // Convert Keyboard ScanCode into an EFI Key\r
- //\r
- for (Index = 0; ConvertKeyboardScanCodeToEfiKey[Index].ScanCode != TABLE_END; Index += 1) {\r
+ for (Index = 0; ConvertKeyboardScanCodeToEfiKey[Index].ScanCode != TABLE_END; Index++) {\r
if (ScanCode == ConvertKeyboardScanCodeToEfiKey[Index].ScanCode) {\r
KeyData.Key.ScanCode = ConvertKeyboardScanCodeToEfiKey[Index].EfiScanCode;\r
KeyData.Key.UnicodeChar = ConvertKeyboardScanCodeToEfiKey[Index].UnicodeChar;\r
\r
- if (ConsoleIn->Shift && \r
+ if ((ConsoleIn->LeftShift || ConsoleIn->RightShift) && \r
(ConvertKeyboardScanCodeToEfiKey[Index].UnicodeChar != ConvertKeyboardScanCodeToEfiKey[Index].ShiftUnicodeChar)) {\r
KeyData.Key.UnicodeChar = ConvertKeyboardScanCodeToEfiKey[Index].ShiftUnicodeChar;\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
- ConsoleIn->LeftShift = FALSE;\r
- ConsoleIn->RightShift = FALSE;\r
+ KeyData.KeyState.KeyShiftState &= ~(EFI_LEFT_SHIFT_PRESSED | EFI_RIGHT_SHIFT_PRESSED);\r
}\r
//\r
// alphabetic key is affected by CapsLock State\r
// distinguish numeric key pad keys' 'up symbol' and 'down symbol'\r
//\r
if (ScanCode >= 0x47 && ScanCode <= 0x53) {\r
- if (ConsoleIn->NumLock && !ConsoleIn->Shift && !Extended) {\r
+ if (ConsoleIn->NumLock && !(ConsoleIn->LeftShift || ConsoleIn->RightShift) && !Extend0) {\r
KeyData.Key.ScanCode = SCAN_NULL;\r
} else if (ScanCode != 0x4a && ScanCode != 0x4e) {\r
KeyData.Key.UnicodeChar = CHAR_NULL;\r
return ;\r
}\r
\r
- //\r
- // Save the Shift/Toggle state\r
- //\r
- if (ConsoleIn->Ctrl) {\r
- KeyData.KeyState.KeyShiftState |= (Extended) ? EFI_RIGHT_CONTROL_PRESSED : EFI_LEFT_CONTROL_PRESSED;\r
- } \r
- if (ConsoleIn->Alt) { \r
- KeyData.KeyState.KeyShiftState |= (Extended) ? EFI_RIGHT_ALT_PRESSED : EFI_LEFT_ALT_PRESSED;\r
- } \r
- if (ConsoleIn->LeftShift) { \r
- KeyData.KeyState.KeyShiftState |= EFI_LEFT_SHIFT_PRESSED;\r
- } \r
- if (ConsoleIn->RightShift) { \r
- KeyData.KeyState.KeyShiftState |= EFI_RIGHT_SHIFT_PRESSED;\r
- } \r
- if (ConsoleIn->LeftLogo) { \r
- KeyData.KeyState.KeyShiftState |= EFI_LEFT_LOGO_PRESSED;\r
- } \r
- if (ConsoleIn->RightLogo) { \r
- KeyData.KeyState.KeyShiftState |= EFI_RIGHT_LOGO_PRESSED;\r
- } \r
- if (ConsoleIn->Menu) { \r
- KeyData.KeyState.KeyShiftState |= EFI_MENU_KEY_PRESSED;\r
- } \r
- if (ConsoleIn->SysReq) { \r
- KeyData.KeyState.KeyShiftState |= EFI_SYS_REQ_PRESSED;\r
- } \r
- if (ConsoleIn->CapsLock) {\r
- KeyData.KeyState.KeyToggleState |= EFI_CAPS_LOCK_ACTIVE;\r
- }\r
- if (ConsoleIn->NumLock) {\r
- KeyData.KeyState.KeyToggleState |= EFI_NUM_LOCK_ACTIVE;\r
- }\r
- if (ConsoleIn->ScrollLock) {\r
- KeyData.KeyState.KeyToggleState |= EFI_SCROLL_LOCK_ACTIVE;\r
- }\r
-\r
//\r
// Invoke notification functions if exist\r
//\r
//\r
// Translate the CTRL-Alpha characters to their corresponding control value (ctrl-a = 0x0001 through ctrl-Z = 0x001A)\r
//\r
- if (ConsoleIn->Ctrl) {\r
+ if (ConsoleIn->LeftCtrl || ConsoleIn->RightCtrl) {\r
if (KeyData.Key.UnicodeChar >= L'a' && KeyData.Key.UnicodeChar <= L'z') {\r
KeyData.Key.UnicodeChar = (UINT16) (KeyData.Key.UnicodeChar - L'a' + 1);\r
} else if (KeyData.Key.UnicodeChar >= L'A' && KeyData.Key.UnicodeChar <= L'Z') {\r
//\r
// Reset the status indicators\r
//\r
- ConsoleIn->Ctrl = FALSE;\r
- ConsoleIn->Alt = FALSE;\r
- ConsoleIn->Shift = FALSE;\r
ConsoleIn->CapsLock = FALSE;\r
ConsoleIn->NumLock = FALSE;\r
ConsoleIn->ScrollLock = FALSE;\r
+ ConsoleIn->LeftCtrl = FALSE;\r
+ ConsoleIn->RightCtrl = FALSE;\r
+ ConsoleIn->LeftAlt = FALSE;\r
+ ConsoleIn->RightAlt = FALSE; \r
ConsoleIn->LeftShift = FALSE;\r
ConsoleIn->RightShift = FALSE;\r
ConsoleIn->LeftLogo = FALSE;\r