+ }\r
+}\r
+\r
+VOID\r
+WinNtGopSimpleTextInTimerHandler (\r
+ IN EFI_EVENT Event,\r
+ IN VOID *Context\r
+ )\r
+{\r
+ GOP_PRIVATE_DATA *Private;\r
+ EFI_KEY_DATA KeyData;\r
+\r
+ Private = (GOP_PRIVATE_DATA *)Context;\r
+ while (GopPrivateDeleteQ (Private, &Private->QueueForNotify, &KeyData) == EFI_SUCCESS) {\r
+ GopPrivateInvokeRegisteredFunction (Private, &KeyData);\r
+ }\r
+}\r
+\r
+/**\r
+ Initialize the key state.\r
+\r
+ @param Private The GOP_PRIVATE_DATA instance.\r
+ @param KeyState A pointer to receive the key state information.\r
+**/\r
+VOID\r
+InitializeKeyState (\r
+ IN GOP_PRIVATE_DATA *Private,\r
+ IN EFI_KEY_STATE *KeyState\r
+ )\r
+{\r
+ KeyState->KeyShiftState = EFI_SHIFT_STATE_VALID;\r
+ KeyState->KeyToggleState = EFI_TOGGLE_STATE_VALID;\r
+\r
+ //\r
+ // Record Key shift state and toggle state\r
+ //\r
+ if (Private->LeftCtrl) {\r
+ KeyState->KeyShiftState |= EFI_LEFT_CONTROL_PRESSED;\r
+ }\r
+ if (Private->RightCtrl) {\r
+ KeyState->KeyShiftState |= EFI_RIGHT_CONTROL_PRESSED;\r
+ }\r
+ if (Private->LeftAlt) {\r
+ KeyState->KeyShiftState |= EFI_LEFT_ALT_PRESSED;\r
+ }\r
+ if (Private->RightAlt) {\r
+ KeyState->KeyShiftState |= EFI_RIGHT_ALT_PRESSED;\r
+ }\r
+ if (Private->LeftShift) {\r
+ KeyState->KeyShiftState |= EFI_LEFT_SHIFT_PRESSED;\r
+ }\r
+ if (Private->RightShift) {\r
+ KeyState->KeyShiftState |= EFI_RIGHT_SHIFT_PRESSED;\r
+ }\r
+ if (Private->LeftLogo) {\r
+ KeyState->KeyShiftState |= EFI_LEFT_LOGO_PRESSED;\r
+ }\r
+ if (Private->RightLogo) {\r
+ KeyState->KeyShiftState |= EFI_RIGHT_LOGO_PRESSED;\r
+ }\r
+ if (Private->Menu) {\r
+ KeyState->KeyShiftState |= EFI_MENU_KEY_PRESSED;\r
+ }\r
+ if (Private->SysReq) {\r
+ KeyState->KeyShiftState |= EFI_SYS_REQ_PRESSED;\r
+ }\r
+ if (Private->CapsLock) {\r
+ KeyState->KeyToggleState |= EFI_CAPS_LOCK_ACTIVE;\r
+ }\r
+ if (Private->NumLock) {\r
+ KeyState->KeyToggleState |= EFI_NUM_LOCK_ACTIVE;\r
+ }\r
+ if (Private->ScrollLock) {\r
+ KeyState->KeyToggleState |= EFI_SCROLL_LOCK_ACTIVE;\r
+ }\r
+ if (Private->IsPartialKeySupport) {\r
+ KeyState->KeyToggleState |= EFI_KEY_STATE_EXPOSED;\r
+ }\r
+}\r
+\r
+/**\r
+ TODO: Add function description\r
+\r
+ @param Private TODO: add argument description\r
+ @param Key TODO: add argument description\r
+\r
+ @retval EFI_NOT_READY TODO: Add description for return value\r
+ @retval EFI_SUCCESS TODO: Add description for return value\r
+\r
+**/\r
+EFI_STATUS\r
+GopPrivateAddKey (\r
+ IN GOP_PRIVATE_DATA *Private,\r
+ IN EFI_INPUT_KEY Key\r
+ )\r
+{\r
+ EFI_KEY_DATA KeyData;\r
+\r
+ KeyData.Key = Key;\r
+ InitializeKeyState (Private, &KeyData.KeyState);\r
+\r
+ //\r
+ // Convert Ctrl+[1-26] to Ctrl+[A-Z]\r
+ //\r
+ if ((Private->LeftCtrl || Private->RightCtrl) &&\r
+ (KeyData.Key.UnicodeChar >= 1) && (KeyData.Key.UnicodeChar <= 26)\r
+ ) {\r
+ if ((Private->LeftShift || Private->RightShift) == Private->CapsLock) {\r
+ KeyData.Key.UnicodeChar = (CHAR16)(KeyData.Key.UnicodeChar + L'a' - 1);\r
+ } else {\r
+ KeyData.Key.UnicodeChar = (CHAR16)(KeyData.Key.UnicodeChar + L'A' - 1);\r
+ }\r
+ }\r
+\r
+ //\r
+ // Unmask the Shift bit for printable char\r
+ //\r
+ if (((KeyData.Key.UnicodeChar >= L'a') && (KeyData.Key.UnicodeChar <= L'z')) ||\r
+ ((KeyData.Key.UnicodeChar >= L'A') && (KeyData.Key.UnicodeChar <= L'Z'))\r
+ ) {\r
+ KeyData.KeyState.KeyShiftState &= ~(EFI_LEFT_SHIFT_PRESSED | EFI_RIGHT_SHIFT_PRESSED);\r
+ }\r
+\r
+ GopPrivateAddQ (Private, &Private->QueueForNotify, &KeyData);\r
+\r
+ GopPrivateAddQ (Private, &Private->QueueForRead, &KeyData);\r
+\r
+ return EFI_SUCCESS;\r