]> git.proxmox.com Git - mirror_edk2.git/blobdiff - MdeModulePkg/Universal/Console/TerminalDxe/TerminalConIn.c
Fix the terminal driver to call hotkey callback even no one is calling ReadKeyStroke
[mirror_edk2.git] / MdeModulePkg / Universal / Console / TerminalDxe / TerminalConIn.c
index 1c5fd7be4731804f5cdb96808cd6ddfc8228b586..b5dbaf92807241387ed031fd5ac89f9b7dbd5533 100644 (file)
@@ -1,7 +1,7 @@
 /** @file\r
   Implementation for EFI_SIMPLE_TEXT_INPUT_PROTOCOL protocol.\r
 \r
 /** @file\r
   Implementation for EFI_SIMPLE_TEXT_INPUT_PROTOCOL protocol.\r
 \r
-Copyright (c) 2006 - 2010, Intel Corporation. All rights reserved.<BR>\r
+Copyright (c) 2006 - 2011, Intel Corporation. All rights reserved.<BR>\r
 This program and the accompanying materials\r
 are licensed and made available under the terms and conditions of the BSD License\r
 which accompanies this distribution.  The full text of the license may be found at\r
 This program and the accompanying materials\r
 are licensed and made available under the terms and conditions of the BSD License\r
 which accompanies this distribution.  The full text of the license may be found at\r
@@ -26,8 +26,6 @@ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
 \r
   @retval EFI_SUCCESS              The keystroke information was returned.\r
   @retval EFI_NOT_READY            There was no keystroke data available.\r
 \r
   @retval EFI_SUCCESS              The keystroke information was returned.\r
   @retval EFI_NOT_READY            There was no keystroke data available.\r
-  @retval EFI_DEVICE_ERROR         The keystroke information was not returned due\r
-                                   to hardware errors.\r
   @retval EFI_INVALID_PARAMETER    KeyData is NULL.\r
 \r
 **/\r
   @retval EFI_INVALID_PARAMETER    KeyData is NULL.\r
 \r
 **/\r
@@ -37,26 +35,10 @@ ReadKeyStrokeWorker (
   OUT EFI_KEY_DATA *KeyData\r
   )\r
 {\r
   OUT EFI_KEY_DATA *KeyData\r
   )\r
 {\r
-  EFI_STATUS                      Status;\r
-  LIST_ENTRY                      *Link;\r
-  LIST_ENTRY                      *NotifyList;\r
-  TERMINAL_CONSOLE_IN_EX_NOTIFY   *CurrentNotify;\r
-\r
   if (KeyData == NULL) {\r
     return EFI_INVALID_PARAMETER;\r
   }\r
 \r
   if (KeyData == NULL) {\r
     return EFI_INVALID_PARAMETER;\r
   }\r
 \r
-  //\r
-  // Initialize *Key to nonsense value.\r
-  //\r
-  KeyData->Key.ScanCode    = SCAN_NULL;\r
-  KeyData->Key.UnicodeChar = 0;\r
-\r
-  Status = TerminalConInCheckForKey (&TerminalDevice->SimpleInput);\r
-  if (EFI_ERROR (Status)) {\r
-    return EFI_NOT_READY;\r
-  }\r
-\r
   if (!EfiKeyFiFoRemoveOneKey (TerminalDevice, &KeyData->Key)) {\r
     return EFI_NOT_READY;\r
   }\r
   if (!EfiKeyFiFoRemoveOneKey (TerminalDevice, &KeyData->Key)) {\r
     return EFI_NOT_READY;\r
   }\r
@@ -64,21 +46,6 @@ ReadKeyStrokeWorker (
   KeyData->KeyState.KeyShiftState  = 0;\r
   KeyData->KeyState.KeyToggleState = 0;\r
 \r
   KeyData->KeyState.KeyShiftState  = 0;\r
   KeyData->KeyState.KeyToggleState = 0;\r
 \r
-  //\r
-  // Invoke notification functions if exist\r
-  //\r
-  NotifyList = &TerminalDevice->NotifyList;\r
-  for (Link = GetFirstNode (NotifyList); !IsNull (NotifyList,Link); Link = GetNextNode (NotifyList,Link)) {\r
-    CurrentNotify = CR (\r
-                      Link,\r
-                      TERMINAL_CONSOLE_IN_EX_NOTIFY,\r
-                      NotifyEntry,\r
-                      TERMINAL_CONSOLE_IN_EX_NOTIFY_SIGNATURE\r
-                      );\r
-    if (IsKeyRegistered (&CurrentNotify->KeyData, KeyData)) {\r
-      CurrentNotify->KeyNotificationFn (KeyData);\r
-    }\r
-  }\r
 \r
   return EFI_SUCCESS;\r
 \r
 \r
   return EFI_SUCCESS;\r
 \r
@@ -226,12 +193,7 @@ TerminalConInWaitForKeyEx (
   IN  VOID            *Context\r
   )\r
 {\r
   IN  VOID            *Context\r
   )\r
 {\r
-  TERMINAL_DEV            *TerminalDevice;\r
-\r
-  TerminalDevice  = TERMINAL_CON_IN_EX_DEV_FROM_THIS (Context);\r
-\r
-  TerminalConInWaitForKey (Event, &TerminalDevice->SimpleInput);\r
-\r
+  TerminalConInWaitForKey (Event, Context);\r
 }\r
 \r
 //\r
 }\r
 \r
 //\r
@@ -532,43 +494,37 @@ TerminalConInWaitForKey (
   // Someone is waiting on the keystroke event, if there's\r
   // a key pending, signal the event\r
   //\r
   // Someone is waiting on the keystroke event, if there's\r
   // a key pending, signal the event\r
   //\r
-  // Context is the pointer to EFI_SIMPLE_TEXT_INPUT_PROTOCOL\r
-  //\r
-  if (!EFI_ERROR (TerminalConInCheckForKey (Context))) {\r
+  if (!IsEfiKeyFiFoEmpty ((TERMINAL_DEV *) Context)) {\r
 \r
     gBS->SignalEvent (Event);\r
   }\r
 }\r
 \r
 \r
     gBS->SignalEvent (Event);\r
   }\r
 }\r
 \r
-\r
 /**\r
 /**\r
-  Check for a pending key in the Efi Key FIFO or Serial device buffer.\r
-\r
-  @param  This                     Indicates the calling context.\r
-\r
-  @retval EFI_SUCCESS              There is key pending.\r
-  @retval EFI_NOT_READY            There is no key pending.\r
-  @retval EFI_DEVICE_ERROR         If Serial IO is not attached to serial device.\r
+  Timer handler to poll the key from serial.\r
 \r
 \r
+  @param  Event                    Indicates the event that invoke this function.\r
+  @param  Context                  Indicates the calling context.\r
 **/\r
 **/\r
-EFI_STATUS\r
-TerminalConInCheckForKey (\r
-  IN  EFI_SIMPLE_TEXT_INPUT_PROTOCOL  *This\r
+VOID\r
+EFIAPI\r
+TerminalConInTimerHandler (\r
+  IN EFI_EVENT            Event,\r
+  IN VOID                 *Context\r
   )\r
 {\r
   EFI_STATUS              Status;\r
   TERMINAL_DEV            *TerminalDevice;\r
   )\r
 {\r
   EFI_STATUS              Status;\r
   TERMINAL_DEV            *TerminalDevice;\r
-  UINT32                  Control;\r
   UINT8                   Input;\r
   EFI_SERIAL_IO_MODE      *Mode;\r
   EFI_SERIAL_IO_PROTOCOL  *SerialIo;\r
   UINTN                   SerialInTimeOut;\r
 \r
   UINT8                   Input;\r
   EFI_SERIAL_IO_MODE      *Mode;\r
   EFI_SERIAL_IO_PROTOCOL  *SerialIo;\r
   UINTN                   SerialInTimeOut;\r
 \r
-  TerminalDevice  = TERMINAL_CON_IN_DEV_FROM_THIS (This);\r
+  TerminalDevice  = (TERMINAL_DEV *) Context;\r
 \r
   SerialIo        = TerminalDevice->SerialIo;\r
   if (SerialIo == NULL) {\r
 \r
   SerialIo        = TerminalDevice->SerialIo;\r
   if (SerialIo == NULL) {\r
-    return EFI_DEVICE_ERROR;\r
+    return ;\r
   }\r
   //\r
   //  if current timeout value for serial device is not identical with\r
   }\r
   //\r
   //  if current timeout value for serial device is not identical with\r
@@ -602,28 +558,7 @@ TerminalConInCheckForKey (
       TerminalDevice->SerialInTimeOut = SerialInTimeOut;\r
     }\r
   }\r
       TerminalDevice->SerialInTimeOut = SerialInTimeOut;\r
     }\r
   }\r
-  //\r
-  //  Check whether serial buffer is empty.\r
-  //\r
-  Status = SerialIo->GetControl (SerialIo, &Control);\r
-\r
-  if ((Control & EFI_SERIAL_INPUT_BUFFER_EMPTY) != 0) {\r
-    //\r
-    // Translate all the raw data in RawFIFO into EFI Key,\r
-    // according to different terminal type supported.\r
-    //\r
-    TranslateRawDataToEfiKey (TerminalDevice);\r
 \r
 \r
-    //\r
-    //  if there is pre-fetched Efi Key in EfiKeyFIFO buffer,\r
-    //  return directly.\r
-    //\r
-    if (!IsEfiKeyFiFoEmpty (TerminalDevice)) {\r
-      return EFI_SUCCESS;\r
-    } else {\r
-      return EFI_NOT_READY;\r
-    }\r
-  }\r
   //\r
   // Fetch all the keys in the serial buffer,\r
   // and insert the byte stream into RawFIFO.\r
   //\r
   // Fetch all the keys in the serial buffer,\r
   // and insert the byte stream into RawFIFO.\r
@@ -651,12 +586,6 @@ TerminalConInCheckForKey (
   // according to different terminal type supported.\r
   //\r
   TranslateRawDataToEfiKey (TerminalDevice);\r
   // according to different terminal type supported.\r
   //\r
   TranslateRawDataToEfiKey (TerminalDevice);\r
-\r
-  if (IsEfiKeyFiFoEmpty (TerminalDevice)) {\r
-    return EFI_NOT_READY;\r
-  }\r
-\r
-  return EFI_SUCCESS;\r
 }\r
 \r
 /**\r
 }\r
 \r
 /**\r
@@ -837,15 +766,37 @@ IsRawFiFoFull (
 **/\r
 BOOLEAN\r
 EfiKeyFiFoInsertOneKey (\r
 **/\r
 BOOLEAN\r
 EfiKeyFiFoInsertOneKey (\r
-  TERMINAL_DEV      *TerminalDevice,\r
-  EFI_INPUT_KEY     Key\r
+  TERMINAL_DEV                    *TerminalDevice,\r
+  EFI_INPUT_KEY                   *Key\r
   )\r
 {\r
   )\r
 {\r
-  UINT8 Tail;\r
+  UINT8                           Tail;\r
+  LIST_ENTRY                      *Link;\r
+  LIST_ENTRY                      *NotifyList;\r
+  TERMINAL_CONSOLE_IN_EX_NOTIFY   *CurrentNotify;\r
+  EFI_KEY_DATA                    KeyData;\r
 \r
   Tail = TerminalDevice->EfiKeyFiFo->Tail;\r
 \r
   Tail = TerminalDevice->EfiKeyFiFo->Tail;\r
-  ASSERT (Tail < FIFO_MAX_NUMBER + 1);\r
 \r
 \r
+  CopyMem (&KeyData.Key, Key, sizeof (EFI_INPUT_KEY));\r
+  KeyData.KeyState.KeyShiftState  = 0;\r
+  KeyData.KeyState.KeyToggleState = 0;\r
+\r
+  //\r
+  // Invoke notification functions if exist\r
+  //\r
+  NotifyList = &TerminalDevice->NotifyList;\r
+  for (Link = GetFirstNode (NotifyList); !IsNull (NotifyList,Link); Link = GetNextNode (NotifyList,Link)) {\r
+    CurrentNotify = CR (\r
+                      Link,\r
+                      TERMINAL_CONSOLE_IN_EX_NOTIFY,\r
+                      NotifyEntry,\r
+                      TERMINAL_CONSOLE_IN_EX_NOTIFY_SIGNATURE\r
+                      );\r
+    if (IsKeyRegistered (&CurrentNotify->KeyData, &KeyData)) {\r
+      CurrentNotify->KeyNotificationFn (&KeyData);\r
+    }\r
+  }\r
   if (IsEfiKeyFiFoFull (TerminalDevice)) {\r
     //\r
     // Efi Key FIFO is full\r
   if (IsEfiKeyFiFoFull (TerminalDevice)) {\r
     //\r
     // Efi Key FIFO is full\r
@@ -853,9 +804,9 @@ EfiKeyFiFoInsertOneKey (
     return FALSE;\r
   }\r
 \r
     return FALSE;\r
   }\r
 \r
-  TerminalDevice->EfiKeyFiFo->Data[Tail] = Key;\r
+  CopyMem (&TerminalDevice->EfiKeyFiFo->Data[Tail], Key, sizeof (EFI_INPUT_KEY));\r
 \r
 \r
-  TerminalDevice->EfiKeyFiFo->Tail       = (UINT8) ((Tail + 1) % (FIFO_MAX_NUMBER + 1));\r
+  TerminalDevice->EfiKeyFiFo->Tail = (UINT8) ((Tail + 1) % (FIFO_MAX_NUMBER + 1));\r
 \r
   return TRUE;\r
 }\r
 \r
   return TRUE;\r
 }\r
@@ -1113,31 +1064,31 @@ UnicodeToEfiKeyFlushState (
   if ((InputState & INPUT_STATE_ESC) != 0) {\r
     Key.ScanCode    = SCAN_ESC;\r
     Key.UnicodeChar = 0;\r
   if ((InputState & INPUT_STATE_ESC) != 0) {\r
     Key.ScanCode    = SCAN_ESC;\r
     Key.UnicodeChar = 0;\r
-    EfiKeyFiFoInsertOneKey (TerminalDevice, Key);\r
+    EfiKeyFiFoInsertOneKey (TerminalDevice, &Key);\r
   }\r
 \r
   if ((InputState & INPUT_STATE_CSI) != 0) {\r
     Key.ScanCode    = SCAN_NULL;\r
     Key.UnicodeChar = CSI;\r
   }\r
 \r
   if ((InputState & INPUT_STATE_CSI) != 0) {\r
     Key.ScanCode    = SCAN_NULL;\r
     Key.UnicodeChar = CSI;\r
-    EfiKeyFiFoInsertOneKey (TerminalDevice, Key);\r
+    EfiKeyFiFoInsertOneKey (TerminalDevice, &Key);\r
   }\r
 \r
   if ((InputState & INPUT_STATE_LEFTOPENBRACKET) != 0) {\r
     Key.ScanCode    = SCAN_NULL;\r
     Key.UnicodeChar = LEFTOPENBRACKET;\r
   }\r
 \r
   if ((InputState & INPUT_STATE_LEFTOPENBRACKET) != 0) {\r
     Key.ScanCode    = SCAN_NULL;\r
     Key.UnicodeChar = LEFTOPENBRACKET;\r
-    EfiKeyFiFoInsertOneKey (TerminalDevice, Key);\r
+    EfiKeyFiFoInsertOneKey (TerminalDevice, &Key);\r
   }\r
 \r
   if ((InputState & INPUT_STATE_O) != 0) {\r
     Key.ScanCode    = SCAN_NULL;\r
     Key.UnicodeChar = 'O';\r
   }\r
 \r
   if ((InputState & INPUT_STATE_O) != 0) {\r
     Key.ScanCode    = SCAN_NULL;\r
     Key.UnicodeChar = 'O';\r
-    EfiKeyFiFoInsertOneKey (TerminalDevice, Key);\r
+    EfiKeyFiFoInsertOneKey (TerminalDevice, &Key);\r
   }\r
 \r
   if ((InputState & INPUT_STATE_2) != 0) {\r
     Key.ScanCode    = SCAN_NULL;\r
     Key.UnicodeChar = '2';\r
   }\r
 \r
   if ((InputState & INPUT_STATE_2) != 0) {\r
     Key.ScanCode    = SCAN_NULL;\r
     Key.UnicodeChar = '2';\r
-    EfiKeyFiFoInsertOneKey (TerminalDevice, Key);\r
+    EfiKeyFiFoInsertOneKey (TerminalDevice, &Key);\r
   }\r
 \r
   //\r
   }\r
 \r
   //\r
@@ -1368,7 +1319,7 @@ UnicodeToEfiKey (
 \r
       if (Key.ScanCode != SCAN_NULL) {\r
         Key.UnicodeChar = 0;\r
 \r
       if (Key.ScanCode != SCAN_NULL) {\r
         Key.UnicodeChar = 0;\r
-        EfiKeyFiFoInsertOneKey (TerminalDevice,Key);\r
+        EfiKeyFiFoInsertOneKey (TerminalDevice, &Key);\r
         TerminalDevice->InputState = INPUT_STATE_DEFAULT;\r
         UnicodeToEfiKeyFlushState (TerminalDevice);\r
         continue;\r
         TerminalDevice->InputState = INPUT_STATE_DEFAULT;\r
         UnicodeToEfiKeyFlushState (TerminalDevice);\r
         continue;\r
@@ -1423,7 +1374,7 @@ UnicodeToEfiKey (
 \r
       if (Key.ScanCode != SCAN_NULL) {\r
         Key.UnicodeChar = 0;\r
 \r
       if (Key.ScanCode != SCAN_NULL) {\r
         Key.UnicodeChar = 0;\r
-        EfiKeyFiFoInsertOneKey (TerminalDevice,Key);\r
+        EfiKeyFiFoInsertOneKey (TerminalDevice, &Key);\r
         TerminalDevice->InputState = INPUT_STATE_DEFAULT;\r
         UnicodeToEfiKeyFlushState (TerminalDevice);\r
         continue;\r
         TerminalDevice->InputState = INPUT_STATE_DEFAULT;\r
         UnicodeToEfiKeyFlushState (TerminalDevice);\r
         continue;\r
@@ -1561,7 +1512,7 @@ UnicodeToEfiKey (
 \r
       if (Key.ScanCode != SCAN_NULL) {\r
         Key.UnicodeChar = 0;\r
 \r
       if (Key.ScanCode != SCAN_NULL) {\r
         Key.UnicodeChar = 0;\r
-        EfiKeyFiFoInsertOneKey (TerminalDevice,Key);\r
+        EfiKeyFiFoInsertOneKey (TerminalDevice, &Key);\r
         TerminalDevice->InputState = INPUT_STATE_DEFAULT;\r
         UnicodeToEfiKeyFlushState (TerminalDevice);\r
         continue;\r
         TerminalDevice->InputState = INPUT_STATE_DEFAULT;\r
         UnicodeToEfiKeyFlushState (TerminalDevice);\r
         continue;\r
@@ -1613,6 +1564,6 @@ UnicodeToEfiKey (
       Key.UnicodeChar = UnicodeChar;\r
     }\r
 \r
       Key.UnicodeChar = UnicodeChar;\r
     }\r
 \r
-    EfiKeyFiFoInsertOneKey (TerminalDevice,Key);\r
+    EfiKeyFiFoInsertOneKey (TerminalDevice, &Key);\r
   }\r
 }\r
   }\r
 }\r