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;

+}