hikey: Add UEFI sources for reference
UEFI needs to be built outside Android build system.
Please follow the instructions in README.
The sources correspond to:
https://github.com/96boards/edk2/commit/14eae0c12e71fd33c4c0fc51e4475e8db02566cf
https://github.com/96boards/arm-trusted-firmware/commit/e9b4909dcd75fc4ae7041cfb83d28ab9adb7afdf
https://github.com/96boards/l-loader/commit/6b784ad5c4ab00e2b1c6f53cd5f74054e5d00a78
https://git.linaro.org/uefi/uefi-tools.git/commit/abe618f8ab72034fff1ce46c9c006a2c6bd40a7e
Change-Id: Ieeefdb63e673e0c8e64e0a1f02c7bddc63b2c7fb
Signed-off-by: Vishal Bhoj <vishal.bhoj@linaro.org>
diff --git a/uefi/linaro-edk2/Nt32Pkg/WinNtGopDxe/WinNtGopInput.c b/uefi/linaro-edk2/Nt32Pkg/WinNtGopDxe/WinNtGopInput.c
new file mode 100644
index 0000000..6a0f4b7
--- /dev/null
+++ b/uefi/linaro-edk2/Nt32Pkg/WinNtGopDxe/WinNtGopInput.c
@@ -0,0 +1,1046 @@
+/** @file
+
+Copyright (c) 2006 - 2012, Intel Corporation. All rights reserved.<BR>
+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
+
+THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+Module Name:
+
+ WinNtGopInput.c
+
+Abstract:
+
+ This file produces the Simple Text In for an Gop window.
+
+ This stuff is linked at the hip to the Window, since the window
+ processing is done in a thread kicked off in WinNtGopImplementation.c
+
+ Since the window information is processed in an other thread we need
+ a keyboard Queue to pass data about. The Simple Text In code just
+ takes data off the Queue. The WinProc message loop takes keyboard input
+ and places it in the Queue.
+
+
+**/
+
+
+#include "WinNtGop.h"
+
+
+/**
+ TODO: Add function description
+
+ @param Private TODO: add argument description
+
+ @retval EFI_SUCCESS TODO: Add description for return value
+
+**/
+EFI_STATUS
+GopPrivateCreateQ (
+ IN GOP_PRIVATE_DATA *Private,
+ IN GOP_QUEUE_FIXED *Queue
+ )
+{
+ Private->WinNtThunk->InitializeCriticalSection (&Queue->Cs);
+ Queue->Front = 0;
+ Queue->Rear = 0;
+ return EFI_SUCCESS;
+}
+
+
+/**
+ TODO: Add function description
+
+ @param Private TODO: add argument description
+
+ @retval EFI_SUCCESS TODO: Add description for return value
+
+**/
+EFI_STATUS
+GopPrivateDestroyQ (
+ IN GOP_PRIVATE_DATA *Private,
+ IN GOP_QUEUE_FIXED *Queue
+ )
+{
+ Queue->Front = 0;
+ Queue->Rear = 0;
+ Private->WinNtThunk->DeleteCriticalSection (&Queue->Cs);
+ return EFI_SUCCESS;
+}
+
+
+/**
+ TODO: Add function description
+
+ @param Private TODO: add argument description
+ @param Key TODO: add argument description
+
+ @retval EFI_NOT_READY TODO: Add description for return value
+ @retval EFI_SUCCESS TODO: Add description for return value
+
+**/
+EFI_STATUS
+GopPrivateAddQ (
+ IN GOP_PRIVATE_DATA *Private,
+ IN GOP_QUEUE_FIXED *Queue,
+ IN EFI_KEY_DATA *KeyData
+ )
+{
+ Private->WinNtThunk->EnterCriticalSection (&Queue->Cs);
+
+ if ((Queue->Rear + 1) % MAX_Q == Queue->Front) {
+ Private->WinNtThunk->LeaveCriticalSection (&Queue->Cs);
+ return EFI_NOT_READY;
+ }
+
+ CopyMem (&Queue->Q[Queue->Rear], KeyData, sizeof (EFI_KEY_DATA));
+ Queue->Rear = (Queue->Rear + 1) % MAX_Q;
+
+ Private->WinNtThunk->LeaveCriticalSection (&Queue->Cs);
+ return EFI_SUCCESS;
+}
+
+
+/**
+ TODO: Add function description
+
+ @param Private TODO: add argument description
+ @param Key TODO: add argument description
+
+ @retval EFI_NOT_READY TODO: Add description for return value
+ @retval EFI_SUCCESS TODO: Add description for return value
+
+**/
+EFI_STATUS
+GopPrivateDeleteQ (
+ IN GOP_PRIVATE_DATA *Private,
+ IN GOP_QUEUE_FIXED *Queue,
+ OUT EFI_KEY_DATA *Key
+ )
+{
+ Private->WinNtThunk->EnterCriticalSection (&Queue->Cs);
+
+ if (Queue->Front == Queue->Rear) {
+ Private->WinNtThunk->LeaveCriticalSection (&Queue->Cs);
+ return EFI_NOT_READY;
+ }
+
+ CopyMem (Key, &Queue->Q[Queue->Front], sizeof (EFI_KEY_DATA));
+ Queue->Front = (Queue->Front + 1) % MAX_Q;
+
+ if (Key->Key.ScanCode == SCAN_NULL && Key->Key.UnicodeChar == CHAR_NULL) {
+ if (!Private->IsPartialKeySupport) {
+ //
+ // If partial keystrok is not enabled, don't return the partial keystroke.
+ //
+ Private->WinNtThunk->LeaveCriticalSection (&Queue->Cs);
+ ZeroMem (Key, sizeof (EFI_KEY_DATA));
+ return EFI_NOT_READY;
+ }
+ }
+ Private->WinNtThunk->LeaveCriticalSection (&Queue->Cs);
+ return EFI_SUCCESS;
+}
+
+
+/**
+ TODO: Add function description
+
+ @param Private TODO: add argument description
+
+ @retval EFI_NOT_READY TODO: Add description for return value
+ @retval EFI_SUCCESS TODO: Add description for return value
+
+**/
+EFI_STATUS
+GopPrivateCheckQ (
+ IN GOP_QUEUE_FIXED *Queue
+ )
+{
+ if (Queue->Front == Queue->Rear) {
+ return EFI_NOT_READY;
+ }
+
+ return EFI_SUCCESS;
+}
+
+BOOLEAN
+GopPrivateIsKeyRegistered (
+ IN EFI_KEY_DATA *RegsiteredData,
+ IN EFI_KEY_DATA *InputData
+ )
+/*++
+
+Routine Description:
+
+Arguments:
+
+ RegsiteredData - A pointer to a buffer that is filled in with the keystroke
+ state data for the key that was registered.
+ InputData - A pointer to a buffer that is filled in with the keystroke
+ state data for the key that was pressed.
+
+Returns:
+ TRUE - Key be pressed matches a registered key.
+ FLASE - Match failed.
+
+--*/
+{
+ ASSERT (RegsiteredData != NULL && InputData != NULL);
+
+ if ((RegsiteredData->Key.ScanCode != InputData->Key.ScanCode) ||
+ (RegsiteredData->Key.UnicodeChar != InputData->Key.UnicodeChar)) {
+ return FALSE;
+ }
+
+ //
+ // Assume KeyShiftState/KeyToggleState = 0 in Registered key data means these state could be ignored.
+ //
+ if (RegsiteredData->KeyState.KeyShiftState != 0 &&
+ RegsiteredData->KeyState.KeyShiftState != InputData->KeyState.KeyShiftState) {
+ return FALSE;
+ }
+ if (RegsiteredData->KeyState.KeyToggleState != 0 &&
+ RegsiteredData->KeyState.KeyToggleState != InputData->KeyState.KeyToggleState) {
+ return FALSE;
+ }
+
+ return TRUE;
+
+}
+
+
+VOID
+GopPrivateInvokeRegisteredFunction (
+ IN GOP_PRIVATE_DATA *Private,
+ IN EFI_KEY_DATA *KeyData
+ )
+/*++
+
+Routine Description:
+
+ This function updates the status light of NumLock, ScrollLock and CapsLock.
+
+Arguments:
+
+ Private - The private structure of WinNt Gop device.
+ KeyData - A pointer to a buffer that is filled in with the keystroke
+ state data for the key that was pressed.
+
+Returns:
+
+ EFI_SUCCESS - The status light is updated successfully.
+
+--*/
+{
+ LIST_ENTRY *Link;
+ WIN_NT_GOP_SIMPLE_TEXTIN_EX_NOTIFY *CurrentNotify;
+
+ for (Link = Private->NotifyList.ForwardLink; Link != &Private->NotifyList; Link = Link->ForwardLink) {
+ CurrentNotify = CR (
+ Link,
+ WIN_NT_GOP_SIMPLE_TEXTIN_EX_NOTIFY,
+ NotifyEntry,
+ WIN_NT_GOP_SIMPLE_TEXTIN_EX_NOTIFY_SIGNATURE
+ );
+ if (GopPrivateIsKeyRegistered (&CurrentNotify->KeyData, KeyData)) {
+ CurrentNotify->KeyNotificationFn (KeyData);
+ }
+ }
+}
+
+VOID
+WinNtGopSimpleTextInTimerHandler (
+ IN EFI_EVENT Event,
+ IN VOID *Context
+ )
+{
+ GOP_PRIVATE_DATA *Private;
+ EFI_KEY_DATA KeyData;
+
+ Private = (GOP_PRIVATE_DATA *)Context;
+ while (GopPrivateDeleteQ (Private, &Private->QueueForNotify, &KeyData) == EFI_SUCCESS) {
+ GopPrivateInvokeRegisteredFunction (Private, &KeyData);
+ }
+}
+
+/**
+ TODO: Add function description
+
+ @param Private TODO: add argument description
+ @param Key TODO: add argument description
+
+ @retval EFI_NOT_READY TODO: Add description for return value
+ @retval EFI_SUCCESS TODO: Add description for return value
+
+**/
+EFI_STATUS
+GopPrivateAddKey (
+ IN GOP_PRIVATE_DATA *Private,
+ IN EFI_INPUT_KEY Key
+ )
+{
+ EFI_KEY_DATA KeyData;
+
+ KeyData.Key = Key;
+
+ KeyData.KeyState.KeyShiftState = EFI_SHIFT_STATE_VALID;
+ KeyData.KeyState.KeyToggleState = EFI_TOGGLE_STATE_VALID;
+
+ //
+ // Record Key shift state and toggle state
+ //
+ if (Private->LeftCtrl) {
+ KeyData.KeyState.KeyShiftState |= EFI_LEFT_CONTROL_PRESSED;
+ }
+ if (Private->RightCtrl) {
+ KeyData.KeyState.KeyShiftState |= EFI_RIGHT_CONTROL_PRESSED;
+ }
+ if (Private->LeftAlt) {
+ KeyData.KeyState.KeyShiftState |= EFI_LEFT_ALT_PRESSED;
+ }
+ if (Private->RightAlt) {
+ KeyData.KeyState.KeyShiftState |= EFI_RIGHT_ALT_PRESSED;
+ }
+ if (Private->LeftShift) {
+ KeyData.KeyState.KeyShiftState |= EFI_LEFT_SHIFT_PRESSED;
+ }
+ if (Private->RightShift) {
+ KeyData.KeyState.KeyShiftState |= EFI_RIGHT_SHIFT_PRESSED;
+ }
+ if (Private->LeftLogo) {
+ KeyData.KeyState.KeyShiftState |= EFI_LEFT_LOGO_PRESSED;
+ }
+ if (Private->RightLogo) {
+ KeyData.KeyState.KeyShiftState |= EFI_RIGHT_LOGO_PRESSED;
+ }
+ if (Private->Menu) {
+ KeyData.KeyState.KeyShiftState |= EFI_MENU_KEY_PRESSED;
+ }
+ if (Private->SysReq) {
+ KeyData.KeyState.KeyShiftState |= EFI_SYS_REQ_PRESSED;
+ }
+ if (Private->CapsLock) {
+ KeyData.KeyState.KeyToggleState |= EFI_CAPS_LOCK_ACTIVE;
+ }
+ if (Private->NumLock) {
+ KeyData.KeyState.KeyToggleState |= EFI_NUM_LOCK_ACTIVE;
+ }
+ if (Private->ScrollLock) {
+ KeyData.KeyState.KeyToggleState |= EFI_SCROLL_LOCK_ACTIVE;
+ }
+ if (Private->IsPartialKeySupport) {
+ KeyData.KeyState.KeyToggleState |= EFI_KEY_STATE_EXPOSED;
+ }
+
+ //
+ // Convert Ctrl+[1-26] to Ctrl+[A-Z]
+ //
+ if ((Private->LeftCtrl || Private->RightCtrl) &&
+ (KeyData.Key.UnicodeChar >= 1) && (KeyData.Key.UnicodeChar <= 26)
+ ) {
+ if ((Private->LeftShift || Private->RightShift) == Private->CapsLock) {
+ KeyData.Key.UnicodeChar = (CHAR16)(KeyData.Key.UnicodeChar + L'a' - 1);
+ } else {
+ KeyData.Key.UnicodeChar = (CHAR16)(KeyData.Key.UnicodeChar + L'A' - 1);
+ }
+ }
+
+ //
+ // Unmask the Shift bit for printable char
+ //
+ if (((KeyData.Key.UnicodeChar >= L'a') && (KeyData.Key.UnicodeChar <= L'z')) ||
+ ((KeyData.Key.UnicodeChar >= L'A') && (KeyData.Key.UnicodeChar <= L'Z'))
+ ) {
+ KeyData.KeyState.KeyShiftState &= ~(EFI_LEFT_SHIFT_PRESSED | EFI_RIGHT_SHIFT_PRESSED);
+ }
+
+ GopPrivateAddQ (Private, &Private->QueueForNotify, &KeyData);
+
+ GopPrivateAddQ (Private, &Private->QueueForRead, &KeyData);
+
+ return EFI_SUCCESS;
+}
+
+EFI_STATUS
+GopPrivateUpdateStatusLight (
+ IN GOP_PRIVATE_DATA *Private
+ )
+/*++
+
+Routine Description:
+
+ This function updates the status light of NumLock, ScrollLock and CapsLock.
+
+Arguments:
+
+ Private - The private structure of WinNt console In/Out.
+
+Returns:
+
+ EFI_SUCCESS - The status light is updated successfully.
+
+--*/
+{
+ //
+ // BUGBUG:Only SendInput/keybd_event function can toggle
+ // NumLock, CapsLock and ScrollLock keys.
+ // Neither of these functions is included in EFI_WIN_NT_THUNK_PROTOCOL.
+ // Thus, return immediately without operation.
+ //
+ return EFI_SUCCESS;
+
+}
+
+
+EFI_STATUS
+GopPrivateResetWorker (
+ IN GOP_PRIVATE_DATA *Private
+ )
+/*++
+
+Routine Description:
+
+ This function is a worker function for SimpleTextIn/SimpleTextInEx.Reset().
+
+Arguments:
+
+ Private - WinNT GOP private structure
+
+Returns:
+
+ EFI_SUCCESS - Reset successfully
+
+--*/
+{
+ EFI_KEY_DATA KeyData;
+ EFI_TPL OldTpl;
+
+ //
+ // Enter critical section
+ //
+ OldTpl = gBS->RaiseTPL (TPL_NOTIFY);
+
+ //
+ // A reset is draining the Queue
+ //
+ while (GopPrivateDeleteQ (Private, &Private->QueueForRead, &KeyData) == EFI_SUCCESS)
+ ;
+ while (GopPrivateDeleteQ (Private, &Private->QueueForNotify, &KeyData) == EFI_SUCCESS)
+ ;
+
+ Private->LeftShift = FALSE;
+ Private->RightShift = FALSE;
+ Private->LeftAlt = FALSE;
+ Private->RightAlt = FALSE;
+ Private->LeftCtrl = FALSE;
+ Private->RightCtrl = FALSE;
+ Private->LeftLogo = FALSE;
+ Private->RightLogo = FALSE;
+ Private->Menu = FALSE;
+ Private->SysReq = FALSE;
+
+ Private->CapsLock = FALSE;
+ Private->NumLock = FALSE;
+ Private->ScrollLock = FALSE;
+ Private->IsPartialKeySupport = FALSE;
+
+ Private->KeyState.KeyShiftState = EFI_SHIFT_STATE_VALID;
+ Private->KeyState.KeyToggleState = EFI_TOGGLE_STATE_VALID;
+
+ //
+ // Leave critical section and return
+ //
+ gBS->RestoreTPL (OldTpl);
+
+ return EFI_SUCCESS;
+}
+
+EFI_STATUS
+GopPrivateReadKeyStrokeWorker (
+ IN GOP_PRIVATE_DATA *Private,
+ OUT EFI_KEY_DATA *KeyData
+ )
+/*++
+
+ Routine Description:
+ Reads the next keystroke from the input device. The WaitForKey Event can
+ be used to test for existance of a keystroke via WaitForEvent () call.
+
+ Arguments:
+ Private - The private structure of WinNt Gop device.
+ KeyData - A pointer to a buffer that is filled in with the keystroke
+ state data for the key that was pressed.
+
+ Returns:
+ EFI_SUCCESS - The keystroke information was returned.
+ EFI_NOT_READY - There was no keystroke data availiable.
+ EFI_DEVICE_ERROR - The keystroke information was not returned due to
+ hardware errors.
+ EFI_INVALID_PARAMETER - KeyData is NULL.
+
+--*/
+{
+ EFI_STATUS Status;
+ EFI_TPL OldTpl;
+
+ if (KeyData == NULL) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ //
+ // Enter critical section
+ //
+ OldTpl = gBS->RaiseTPL (TPL_NOTIFY);
+
+ //
+ // Call hot key callback before telling caller there is a key available
+ //
+ WinNtGopSimpleTextInTimerHandler (NULL, Private);
+
+ Status = GopPrivateCheckQ (&Private->QueueForRead);
+ if (!EFI_ERROR (Status)) {
+ //
+ // If a Key press exists try and read it.
+ //
+ Status = GopPrivateDeleteQ (Private, &Private->QueueForRead, KeyData);
+ if (!EFI_ERROR (Status)) {
+ //
+ // If partial keystroke is not enabled, check whether it is value key. If not return
+ // EFI_NOT_READY.
+ //
+ if (!Private->IsPartialKeySupport) {
+ if (KeyData->Key.ScanCode == SCAN_NULL && KeyData->Key.UnicodeChar == CHAR_NULL) {
+ Status = EFI_NOT_READY;
+ }
+ }
+ }
+ }
+
+ //
+ // Leave critical section and return
+ //
+ gBS->RestoreTPL (OldTpl);
+
+ return Status;
+
+}
+
+
+//
+// Simple Text In implementation.
+//
+
+
+/**
+ TODO: Add function description
+
+ @param This TODO: add argument description
+ @param ExtendedVerification TODO: add argument description
+
+ @retval EFI_SUCCESS TODO: Add description for return value
+
+**/
+EFI_STATUS
+EFIAPI
+WinNtGopSimpleTextInReset (
+ IN EFI_SIMPLE_TEXT_INPUT_PROTOCOL *This,
+ IN BOOLEAN ExtendedVerification
+ )
+{
+ GOP_PRIVATE_DATA *Private;
+
+ Private = GOP_PRIVATE_DATA_FROM_TEXT_IN_THIS (This);
+
+ return GopPrivateResetWorker (Private);
+}
+
+
+/**
+ TODO: Add function description
+
+ @param This TODO: add argument description
+ @param Key TODO: add argument description
+
+ @return TODO: add return values
+
+**/
+EFI_STATUS
+EFIAPI
+WinNtGopSimpleTextInReadKeyStroke (
+ IN EFI_SIMPLE_TEXT_INPUT_PROTOCOL *This,
+ OUT EFI_INPUT_KEY *Key
+ )
+{
+ GOP_PRIVATE_DATA *Private;
+ EFI_STATUS Status;
+ EFI_KEY_DATA KeyData;
+
+ Private = GOP_PRIVATE_DATA_FROM_TEXT_IN_THIS (This);
+ //
+ // Considering if the partial keystroke is enabled, there maybe a partial
+ // keystroke in the queue, so here skip the partial keystroke and get the
+ // next key from the queue
+ //
+ while (1) {
+ Status = GopPrivateReadKeyStrokeWorker (Private, &KeyData);
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+ if (KeyData.Key.ScanCode == SCAN_NULL && KeyData.Key.UnicodeChar == CHAR_NULL) {
+ continue;
+ }
+ //
+ // Convert Ctrl+[A-Z] to Ctrl+[1-26]
+ //
+ if ((KeyData.KeyState.KeyShiftState & (EFI_LEFT_CONTROL_PRESSED | EFI_RIGHT_CONTROL_PRESSED)) != 0) {
+ if ((KeyData.Key.UnicodeChar >= L'a') && (KeyData.Key.UnicodeChar <= L'z')) {
+ KeyData.Key.UnicodeChar = (CHAR16) (KeyData.Key.UnicodeChar - L'a' + 1);
+ } else if ((KeyData.Key.UnicodeChar >= L'A') && (KeyData.Key.UnicodeChar <= L'Z')) {
+ KeyData.Key.UnicodeChar = (CHAR16) (KeyData.Key.UnicodeChar - L'A' + 1);
+ }
+ }
+ CopyMem (Key, &KeyData.Key, sizeof (EFI_INPUT_KEY));
+ return EFI_SUCCESS;
+ }
+}
+
+
+/**
+ TODO: Add function description
+
+ @param Event TODO: add argument description
+ @param Context TODO: add argument description
+
+ @return TODO: add return values
+
+**/
+VOID
+EFIAPI
+WinNtGopSimpleTextInWaitForKey (
+ IN EFI_EVENT Event,
+ IN VOID *Context
+ )
+{
+ GOP_PRIVATE_DATA *Private;
+ EFI_STATUS Status;
+ EFI_TPL OldTpl;
+ EFI_KEY_DATA KeyData;
+
+ Private = (GOP_PRIVATE_DATA *) Context;
+
+ //
+ // Enter critical section
+ //
+ OldTpl = gBS->RaiseTPL (TPL_NOTIFY);
+
+ //
+ // Call hot key callback before telling caller there is a key available
+ //
+ WinNtGopSimpleTextInTimerHandler (NULL, Private);
+
+ //
+ // WaitforKey doesn't suppor the partial key.
+ // Considering if the partial keystroke is enabled, there maybe a partial
+ // keystroke in the queue, so here skip the partial keystroke and get the
+ // next key from the queue
+ //
+ while (1) {
+ Status = GopPrivateCheckQ (&Private->QueueForRead);
+ if (!EFI_ERROR (Status)) {
+ //
+ // If a there is a key in the queue and it is not partial keystroke, signal event.
+ //
+ if (Private->QueueForRead.Q[Private->QueueForRead.Front].Key.ScanCode == SCAN_NULL &&
+ Private->QueueForRead.Q[Private->QueueForRead.Front].Key.UnicodeChar == CHAR_NULL) {
+ GopPrivateDeleteQ (Private,&Private->QueueForRead,&KeyData);
+ continue;
+ }
+ gBS->SignalEvent (Event);
+ } else {
+ //
+ // We need to sleep or NT will schedule this thread with such high
+ // priority that WinProc thread will never run and we will not see
+ // keyboard input. This Sleep makes the syste run 10x faster, so don't
+ // remove it.
+ //
+ Private->WinNtThunk->Sleep (1);
+ }
+ break;
+ }
+
+ //
+ // Leave critical section and return
+ //
+ gBS->RestoreTPL (OldTpl);
+}
+
+//
+// Simple Text Input Ex protocol functions
+//
+
+EFI_STATUS
+EFIAPI
+WinNtGopSimpleTextInExResetEx (
+ IN EFI_SIMPLE_TEXT_INPUT_EX_PROTOCOL *This,
+ IN BOOLEAN ExtendedVerification
+ )
+/*++
+
+ Routine Description:
+ Reset the input device and optionaly run diagnostics
+
+ Arguments:
+ This - Protocol instance pointer.
+ ExtendedVerification - Driver may perform diagnostics on reset.
+
+ Returns:
+ EFI_SUCCESS - The device was reset.
+
+--*/
+{
+ GOP_PRIVATE_DATA *Private;
+
+ Private = GOP_PRIVATE_DATA_FROM_TEXT_IN_EX_THIS (This);
+
+ return GopPrivateResetWorker (Private);
+}
+
+EFI_STATUS
+EFIAPI
+WinNtGopSimpleTextInExReadKeyStrokeEx (
+ IN EFI_SIMPLE_TEXT_INPUT_EX_PROTOCOL *This,
+ OUT EFI_KEY_DATA *KeyData
+ )
+/*++
+
+ Routine Description:
+ Reads the next keystroke from the input device. The WaitForKey Event can
+ be used to test for existance of a keystroke via WaitForEvent () call.
+
+ Arguments:
+ This - Protocol instance pointer.
+ KeyData - A pointer to a buffer that is filled in with the keystroke
+ state data for the key that was pressed.
+
+ Returns:
+ EFI_SUCCESS - The keystroke information was returned.
+ EFI_NOT_READY - There was no keystroke data availiable.
+ EFI_DEVICE_ERROR - The keystroke information was not returned due to
+ hardware errors.
+ EFI_INVALID_PARAMETER - KeyData is NULL.
+
+--*/
+{
+ GOP_PRIVATE_DATA *Private;
+
+ if (KeyData == NULL) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ Private = GOP_PRIVATE_DATA_FROM_TEXT_IN_EX_THIS (This);
+
+ return GopPrivateReadKeyStrokeWorker (Private, KeyData);
+
+}
+
+EFI_STATUS
+EFIAPI
+WinNtGopSimpleTextInExSetState (
+ IN EFI_SIMPLE_TEXT_INPUT_EX_PROTOCOL *This,
+ IN EFI_KEY_TOGGLE_STATE *KeyToggleState
+ )
+/*++
+
+ Routine Description:
+ Set certain state for the input device.
+
+ Arguments:
+ This - Protocol instance pointer.
+ KeyToggleState - A pointer to the EFI_KEY_TOGGLE_STATE to set the
+ state for the input device.
+
+ Returns:
+ EFI_SUCCESS - The device state was set successfully.
+ EFI_DEVICE_ERROR - The device is not functioning correctly and could
+ not have the setting adjusted.
+ EFI_UNSUPPORTED - The device does not have the ability to set its state.
+ EFI_INVALID_PARAMETER - KeyToggleState is NULL.
+
+--*/
+{
+ EFI_STATUS Status;
+ GOP_PRIVATE_DATA *Private;
+
+ if (KeyToggleState == NULL) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ Private = GOP_PRIVATE_DATA_FROM_TEXT_IN_EX_THIS (This);
+
+ if (((Private->KeyState.KeyToggleState & EFI_TOGGLE_STATE_VALID) != EFI_TOGGLE_STATE_VALID) ||
+ ((*KeyToggleState & EFI_TOGGLE_STATE_VALID) != EFI_TOGGLE_STATE_VALID)) {
+ return EFI_UNSUPPORTED;
+ }
+
+ Private->ScrollLock = FALSE;
+ Private->NumLock = FALSE;
+ Private->CapsLock = FALSE;
+ Private->IsPartialKeySupport = FALSE;
+
+ if ((*KeyToggleState & EFI_SCROLL_LOCK_ACTIVE) == EFI_SCROLL_LOCK_ACTIVE) {
+ Private->ScrollLock = TRUE;
+ }
+ if ((*KeyToggleState & EFI_NUM_LOCK_ACTIVE) == EFI_NUM_LOCK_ACTIVE) {
+ Private->NumLock = TRUE;
+ }
+ if ((*KeyToggleState & EFI_CAPS_LOCK_ACTIVE) == EFI_CAPS_LOCK_ACTIVE) {
+ Private->CapsLock = TRUE;
+ }
+ if ((*KeyToggleState & EFI_KEY_STATE_EXPOSED) == EFI_KEY_STATE_EXPOSED) {
+ Private->IsPartialKeySupport = TRUE;
+ }
+
+ Status = GopPrivateUpdateStatusLight (Private);
+ if (EFI_ERROR (Status)) {
+ return EFI_DEVICE_ERROR;
+ }
+
+ Private->KeyState.KeyToggleState = *KeyToggleState;
+ return EFI_SUCCESS;
+
+}
+
+EFI_STATUS
+EFIAPI
+WinNtGopSimpleTextInExRegisterKeyNotify (
+ IN EFI_SIMPLE_TEXT_INPUT_EX_PROTOCOL *This,
+ IN EFI_KEY_DATA *KeyData,
+ IN EFI_KEY_NOTIFY_FUNCTION KeyNotificationFunction,
+ OUT VOID **NotifyHandle
+ )
+/*++
+
+ Routine Description:
+ Register a notification function for a particular keystroke for the input device.
+
+ Arguments:
+ This - Protocol instance pointer.
+ KeyData - A pointer to a buffer that is filled in with the keystroke
+ information data for the key that was pressed.
+ KeyNotificationFunction - Points to the function to be called when the key
+ sequence is typed specified by KeyData.
+ NotifyHandle - Points to the unique handle assigned to the registered notification.
+
+ Returns:
+ EFI_SUCCESS - The notification function was registered successfully.
+ EFI_OUT_OF_RESOURCES - Unable to allocate resources for necesssary data structures.
+ EFI_INVALID_PARAMETER - KeyData or NotifyHandle is NULL.
+
+--*/
+{
+ GOP_PRIVATE_DATA *Private;
+ WIN_NT_GOP_SIMPLE_TEXTIN_EX_NOTIFY *CurrentNotify;
+ LIST_ENTRY *Link;
+ WIN_NT_GOP_SIMPLE_TEXTIN_EX_NOTIFY *NewNotify;
+
+ if (KeyData == NULL || KeyNotificationFunction == NULL || NotifyHandle == NULL) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ Private = GOP_PRIVATE_DATA_FROM_TEXT_IN_EX_THIS (This);
+
+ //
+ // Return EFI_SUCCESS if the (KeyData, NotificationFunction) is already registered.
+ //
+ for (Link = Private->NotifyList.ForwardLink; Link != &Private->NotifyList; Link = Link->ForwardLink) {
+ CurrentNotify = CR (
+ Link,
+ WIN_NT_GOP_SIMPLE_TEXTIN_EX_NOTIFY,
+ NotifyEntry,
+ WIN_NT_GOP_SIMPLE_TEXTIN_EX_NOTIFY_SIGNATURE
+ );
+ if (GopPrivateIsKeyRegistered (&CurrentNotify->KeyData, KeyData)) {
+ if (CurrentNotify->KeyNotificationFn == KeyNotificationFunction) {
+ *NotifyHandle = CurrentNotify;
+ return EFI_SUCCESS;
+ }
+ }
+ }
+
+ //
+ // Allocate resource to save the notification function
+ //
+ NewNotify = (WIN_NT_GOP_SIMPLE_TEXTIN_EX_NOTIFY *) AllocateZeroPool (sizeof (WIN_NT_GOP_SIMPLE_TEXTIN_EX_NOTIFY));
+ if (NewNotify == NULL) {
+ return EFI_OUT_OF_RESOURCES;
+ }
+
+ NewNotify->Signature = WIN_NT_GOP_SIMPLE_TEXTIN_EX_NOTIFY_SIGNATURE;
+ NewNotify->KeyNotificationFn = KeyNotificationFunction;
+ CopyMem (&NewNotify->KeyData, KeyData, sizeof (EFI_KEY_DATA));
+ InsertTailList (&Private->NotifyList, &NewNotify->NotifyEntry);
+
+ *NotifyHandle = NewNotify;
+
+ return EFI_SUCCESS;
+
+}
+
+EFI_STATUS
+EFIAPI
+WinNtGopSimpleTextInExUnregisterKeyNotify (
+ IN EFI_SIMPLE_TEXT_INPUT_EX_PROTOCOL *This,
+ IN VOID *NotificationHandle
+ )
+/*++
+
+ Routine Description:
+ Remove a registered notification function from a particular keystroke.
+
+ Arguments:
+ This - Protocol instance pointer.
+ NotificationHandle - The handle of the notification function being unregistered.
+
+ Returns:
+ EFI_SUCCESS - The notification function was unregistered successfully.
+ EFI_INVALID_PARAMETER - The NotificationHandle is invalid.
+
+--*/
+{
+ GOP_PRIVATE_DATA *Private;
+ LIST_ENTRY *Link;
+ WIN_NT_GOP_SIMPLE_TEXTIN_EX_NOTIFY *CurrentNotify;
+
+ if (NotificationHandle == NULL) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ Private = GOP_PRIVATE_DATA_FROM_TEXT_IN_EX_THIS (This);
+
+ for (Link = Private->NotifyList.ForwardLink; Link != &Private->NotifyList; Link = Link->ForwardLink) {
+ CurrentNotify = CR (
+ Link,
+ WIN_NT_GOP_SIMPLE_TEXTIN_EX_NOTIFY,
+ NotifyEntry,
+ WIN_NT_GOP_SIMPLE_TEXTIN_EX_NOTIFY_SIGNATURE
+ );
+ if (CurrentNotify == NotificationHandle) {
+ //
+ // Remove the notification function from NotifyList and free resources
+ //
+ RemoveEntryList (&CurrentNotify->NotifyEntry);
+
+ gBS->FreePool (CurrentNotify);
+ return EFI_SUCCESS;
+ }
+ }
+
+ //
+ // Can not find the specified Notification Handle
+ //
+ return EFI_INVALID_PARAMETER;
+}
+
+
+/**
+ TODO: Add function description
+
+ @param Private TODO: add argument description
+
+ @return TODO: add return values
+
+**/
+EFI_STATUS
+WinNtGopInitializeSimpleTextInForWindow (
+ IN GOP_PRIVATE_DATA *Private
+ )
+{
+ EFI_STATUS Status;
+
+ GopPrivateCreateQ (Private, &Private->QueueForRead);
+ GopPrivateCreateQ (Private, &Private->QueueForNotify);
+
+ //
+ // Initialize Simple Text In protoocol
+ //
+ Private->SimpleTextIn.Reset = WinNtGopSimpleTextInReset;
+ Private->SimpleTextIn.ReadKeyStroke = WinNtGopSimpleTextInReadKeyStroke;
+
+ Status = gBS->CreateEvent (
+ EVT_NOTIFY_WAIT,
+ TPL_NOTIFY,
+ WinNtGopSimpleTextInWaitForKey,
+ Private,
+ &Private->SimpleTextIn.WaitForKey
+ );
+
+
+ Private->SimpleTextInEx.Reset = WinNtGopSimpleTextInExResetEx;
+ Private->SimpleTextInEx.ReadKeyStrokeEx = WinNtGopSimpleTextInExReadKeyStrokeEx;
+ Private->SimpleTextInEx.SetState = WinNtGopSimpleTextInExSetState;
+ Private->SimpleTextInEx.RegisterKeyNotify = WinNtGopSimpleTextInExRegisterKeyNotify;
+ Private->SimpleTextInEx.UnregisterKeyNotify = WinNtGopSimpleTextInExUnregisterKeyNotify;
+
+ Private->SimpleTextInEx.Reset (&Private->SimpleTextInEx, FALSE);
+
+ InitializeListHead (&Private->NotifyList);
+
+ Status = gBS->CreateEvent (
+ EVT_NOTIFY_WAIT,
+ TPL_NOTIFY,
+ WinNtGopSimpleTextInWaitForKey,
+ Private,
+ &Private->SimpleTextInEx.WaitForKeyEx
+ );
+ ASSERT_EFI_ERROR (Status);
+
+ //
+ // Create the Timer to trigger hot key notifications
+ //
+ Status = gBS->CreateEvent (
+ EVT_TIMER | EVT_NOTIFY_SIGNAL,
+ TPL_NOTIFY,
+ WinNtGopSimpleTextInTimerHandler,
+ Private,
+ &Private->TimerEvent
+ );
+ ASSERT_EFI_ERROR (Status);
+
+ Status = gBS->SetTimer (
+ Private->TimerEvent,
+ TimerPeriodic,
+ KEYBOARD_TIMER_INTERVAL
+ );
+ ASSERT_EFI_ERROR (Status);
+
+ return Status;
+}
+
+
+
+/**
+ TODO: Add function description
+
+ @param Private TODO: add argument description
+
+ @retval EFI_SUCCESS TODO: Add description for return value
+
+**/
+EFI_STATUS
+WinNtGopDestroySimpleTextInForWindow (
+ IN GOP_PRIVATE_DATA *Private
+ )
+{
+ gBS->CloseEvent (Private->TimerEvent);
+
+ GopPrivateDestroyQ (Private, &Private->QueueForRead);
+ GopPrivateDestroyQ (Private, &Private->QueueForNotify);
+
+ return EFI_SUCCESS;
+}