--- /dev/null
+/** @file\r
+\r
+Copyright (c) 2006 - 2011, Intel Corporation. All rights reserved.<BR>\r
+Copyright (c) 2018, Linaro Ltd. All rights reserved.<BR>\r
+\r
+This program and the accompanying materials\r
+are licensed and made available under the terms and conditions\r
+of the BSD License which accompanies this distribution. The\r
+full text of the license may be found at\r
+http://opensource.org/licenses/bsd-license.php\r
+\r
+THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
+WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
+\r
+**/\r
+\r
+#include "VirtualKeyboard.h"\r
+\r
+//\r
+// EFI Component Name Protocol\r
+//\r
+GLOBAL_REMOVE_IF_UNREFERENCED EFI_COMPONENT_NAME_PROTOCOL gVirtualKeyboardComponentName = {\r
+ VirtualKeyboardComponentNameGetDriverName,\r
+ VirtualKeyboardComponentNameGetControllerName,\r
+ "eng"\r
+};\r
+\r
+//\r
+// EFI Component Name 2 Protocol\r
+//\r
+GLOBAL_REMOVE_IF_UNREFERENCED EFI_COMPONENT_NAME2_PROTOCOL gVirtualKeyboardComponentName2 = {\r
+ (EFI_COMPONENT_NAME2_GET_DRIVER_NAME) VirtualKeyboardComponentNameGetDriverName,\r
+ (EFI_COMPONENT_NAME2_GET_CONTROLLER_NAME) VirtualKeyboardComponentNameGetControllerName,\r
+ "en"\r
+};\r
+\r
+\r
+GLOBAL_REMOVE_IF_UNREFERENCED EFI_UNICODE_STRING_TABLE mVirtualKeyboardDriverNameTable[] = {\r
+ {\r
+ "eng;en",\r
+ L"Virtual Keyboard Driver"\r
+ },\r
+ {\r
+ "zh-CHS",\r
+ L"虚拟键盘驱动程序"\r
+ },\r
+ {\r
+ NULL,\r
+ NULL\r
+ }\r
+};\r
+\r
+/**\r
+ Retrieves a Unicode string that is the user readable name of the driver.\r
+\r
+ This function retrieves the user readable name of a driver in the form of a\r
+ Unicode string. If the driver specified by This has a user readable name in\r
+ the language specified by Language, then a pointer to the driver name is\r
+ returned in DriverName, and EFI_SUCCESS is returned. If the driver specified\r
+ by This does not support the language specified by Language,\r
+ then EFI_UNSUPPORTED is returned.\r
+\r
+ @param This[in] A pointer to the EFI_COMPONENT_NAME2_PROTOCOL or\r
+ EFI_COMPONENT_NAME_PROTOCOL instance.\r
+\r
+ @param Language[in] A pointer to a Null-terminated ASCII string\r
+ array indicating the language. This is the\r
+ language of the driver name that the caller is\r
+ requesting, and it must match one of the\r
+ languages specified in SupportedLanguages. The\r
+ number of languages supported by a driver is up\r
+ to the driver writer. Language is specified\r
+ in RFC 4646 or ISO 639-2 language code format.\r
+\r
+ @param DriverName[out] A pointer to the Unicode string to return.\r
+ This Unicode string is the name of the\r
+ driver specified by This in the language\r
+ specified by Language.\r
+\r
+ @retval EFI_SUCCESS The Unicode string for the Driver specified by\r
+ This and the language specified by Language was\r
+ returned in DriverName.\r
+\r
+ @retval EFI_INVALID_PARAMETER Language is NULL.\r
+\r
+ @retval EFI_INVALID_PARAMETER DriverName is NULL.\r
+\r
+ @retval EFI_UNSUPPORTED The driver specified by This does not support\r
+ the language specified by Language.\r
+\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+VirtualKeyboardComponentNameGetDriverName (\r
+ IN EFI_COMPONENT_NAME_PROTOCOL *This,\r
+ IN CHAR8 *Language,\r
+ OUT CHAR16 **DriverName\r
+ )\r
+{\r
+ return LookupUnicodeString2 (\r
+ Language,\r
+ This->SupportedLanguages,\r
+ mVirtualKeyboardDriverNameTable,\r
+ DriverName,\r
+ (BOOLEAN)(This == &gVirtualKeyboardComponentName)\r
+ );\r
+}\r
+\r
+/**\r
+ Retrieves a Unicode string that is the user readable name of the controller\r
+ that is being managed by a driver.\r
+\r
+ This function retrieves the user readable name of the controller specified by\r
+ ControllerHandle and ChildHandle in the form of a Unicode string. If the\r
+ driver specified by This has a user readable name in the language specified by\r
+ Language, then a pointer to the controller name is returned in ControllerName,\r
+ and EFI_SUCCESS is returned. If the driver specified by This is not currently\r
+ managing the controller specified by ControllerHandle and ChildHandle,\r
+ then EFI_UNSUPPORTED is returned. If the driver specified by This does not\r
+ support the language specified by Language, then EFI_UNSUPPORTED is returned.\r
+\r
+ @param This[in] A pointer to the EFI_COMPONENT_NAME2_PROTOCOL or\r
+ EFI_COMPONENT_NAME_PROTOCOL instance.\r
+\r
+ @param ControllerHandle[in] The handle of a controller that the driver\r
+ specified by This is managing. This handle\r
+ specifies the controller whose name is to be\r
+ returned.\r
+\r
+ @param ChildHandle[in] The handle of the child controller to retrieve\r
+ the name of. This is an optional parameter that\r
+ may be NULL. It will be NULL for device\r
+ drivers. It will also be NULL for a bus drivers\r
+ that wish to retrieve the name of the bus\r
+ controller. It will not be NULL for a bus\r
+ driver that wishes to retrieve the name of a\r
+ child controller.\r
+\r
+ @param Language[in] A pointer to a Null-terminated ASCII string\r
+ array indicating the language. This is the\r
+ language of the driver name that the caller is\r
+ requesting, and it must match one of the\r
+ languages specified in SupportedLanguages. The\r
+ number of languages supported by a driver is up\r
+ to the driver writer. Language is specified in\r
+ RFC 4646 or ISO 639-2 language code format.\r
+\r
+ @param ControllerName[out] A pointer to the Unicode string to return.\r
+ This Unicode string is the name of the\r
+ controller specified by ControllerHandle and\r
+ ChildHandle in the language specified by\r
+ Language from the point of view of the driver\r
+ specified by This.\r
+\r
+ @retval EFI_SUCCESS The Unicode string for the user readable name in\r
+ the language specified by Language for the\r
+ driver specified by This was returned in\r
+ DriverName.\r
+\r
+ @retval EFI_INVALID_PARAMETER ControllerHandle is NULL.\r
+\r
+ @retval EFI_INVALID_PARAMETER ChildHandle is not NULL and it is not a valid\r
+ EFI_HANDLE.\r
+\r
+ @retval EFI_INVALID_PARAMETER Language is NULL.\r
+\r
+ @retval EFI_INVALID_PARAMETER ControllerName is NULL.\r
+\r
+ @retval EFI_UNSUPPORTED The driver specified by This is not currently\r
+ managing the controller specified by\r
+ ControllerHandle and ChildHandle.\r
+\r
+ @retval EFI_UNSUPPORTED The driver specified by This does not support\r
+ the language specified by Language.\r
+\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+VirtualKeyboardComponentNameGetControllerName (\r
+ IN EFI_COMPONENT_NAME_PROTOCOL *This,\r
+ IN EFI_HANDLE ControllerHandle,\r
+ IN EFI_HANDLE ChildHandle OPTIONAL,\r
+ IN CHAR8 *Language,\r
+ OUT CHAR16 **ControllerName\r
+ )\r
+{\r
+ return EFI_UNSUPPORTED;\r
+}\r
--- /dev/null
+/** @file\r
+\r
+Copyright (c) 2006 - 2011, Intel Corporation. All rights reserved.<BR>\r
+Copyright (c) 2018, Linaro Ltd. All rights reserved.<BR>\r
+\r
+This program and the accompanying materials\r
+are licensed and made available under the terms and conditions\r
+of the BSD License which accompanies this distribution. The\r
+full text of the license may be found at\r
+http://opensource.org/licenses/bsd-license.php\r
+\r
+THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
+WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
+\r
+**/\r
+\r
+#ifndef _VIRTUAL_KEYBOARD_COMPONENT_NAME_H_\r
+#define _VIRTUAL_KEYBOARD_COMPONENT_NAME_H_\r
+\r
+\r
+extern EFI_COMPONENT_NAME_PROTOCOL gVirtualKeyboardComponentName;\r
+extern EFI_COMPONENT_NAME2_PROTOCOL gVirtualKeyboardComponentName2;\r
+\r
+//\r
+// EFI Component Name Functions\r
+//\r
+/**\r
+ Retrieves a Unicode string that is the user readable name of the driver.\r
+\r
+ This function retrieves the user readable name of a driver in the form of a\r
+ Unicode string. If the driver specified by This has a user readable name in\r
+ the language specified by Language, then a pointer to the driver name is\r
+ returned in DriverName, and EFI_SUCCESS is returned. If the driver specified\r
+ by This does not support the language specified by Language,\r
+ then EFI_UNSUPPORTED is returned.\r
+\r
+ @param This[in] A pointer to the EFI_COMPONENT_NAME2_PROTOCOL or\r
+ EFI_COMPONENT_NAME_PROTOCOL instance.\r
+\r
+ @param Language[in] A pointer to a Null-terminated ASCII string\r
+ array indicating the language. This is the\r
+ language of the driver name that the caller is\r
+ requesting, and it must match one of the\r
+ languages specified in SupportedLanguages. The\r
+ number of languages supported by a driver is up\r
+ to the driver writer. Language is specified\r
+ in RFC 4646 or ISO 639-2 language code format.\r
+\r
+ @param DriverName[out] A pointer to the Unicode string to return.\r
+ This Unicode string is the name of the\r
+ driver specified by This in the language\r
+ specified by Language.\r
+\r
+ @retval EFI_SUCCESS The Unicode string for the Driver specified by\r
+ This and the language specified by Language was\r
+ returned in DriverName.\r
+\r
+ @retval EFI_INVALID_PARAMETER Language is NULL.\r
+\r
+ @retval EFI_INVALID_PARAMETER DriverName is NULL.\r
+\r
+ @retval EFI_UNSUPPORTED The driver specified by This does not support\r
+ the language specified by Language.\r
+\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+VirtualKeyboardComponentNameGetDriverName (\r
+ IN EFI_COMPONENT_NAME_PROTOCOL *This,\r
+ IN CHAR8 *Language,\r
+ OUT CHAR16 **DriverName\r
+ );\r
+\r
+\r
+/**\r
+ Retrieves a Unicode string that is the user readable name of the controller\r
+ that is being managed by a driver.\r
+\r
+ This function retrieves the user readable name of the controller specified by\r
+ ControllerHandle and ChildHandle in the form of a Unicode string. If the\r
+ driver specified by This has a user readable name in the language specified by\r
+ Language, then a pointer to the controller name is returned in ControllerName,\r
+ and EFI_SUCCESS is returned. If the driver specified by This is not currently\r
+ managing the controller specified by ControllerHandle and ChildHandle,\r
+ then EFI_UNSUPPORTED is returned. If the driver specified by This does not\r
+ support the language specified by Language, then EFI_UNSUPPORTED is returned.\r
+\r
+ @param This[in] A pointer to the EFI_COMPONENT_NAME2_PROTOCOL or\r
+ EFI_COMPONENT_NAME_PROTOCOL instance.\r
+\r
+ @param ControllerHandle[in] The handle of a controller that the driver\r
+ specified by This is managing. This handle\r
+ specifies the controller whose name is to be\r
+ returned.\r
+\r
+ @param ChildHandle[in] The handle of the child controller to retrieve\r
+ the name of. This is an optional parameter that\r
+ may be NULL. It will be NULL for device\r
+ drivers. It will also be NULL for a bus drivers\r
+ that wish to retrieve the name of the bus\r
+ controller. It will not be NULL for a bus\r
+ driver that wishes to retrieve the name of a\r
+ child controller.\r
+\r
+ @param Language[in] A pointer to a Null-terminated ASCII string\r
+ array indicating the language. This is the\r
+ language of the driver name that the caller is\r
+ requesting, and it must match one of the\r
+ languages specified in SupportedLanguages. The\r
+ number of languages supported by a driver is up\r
+ to the driver writer. Language is specified in\r
+ RFC 4646 or ISO 639-2 language code format.\r
+\r
+ @param ControllerName[out] A pointer to the Unicode string to return.\r
+ This Unicode string is the name of the\r
+ controller specified by ControllerHandle and\r
+ ChildHandle in the language specified by\r
+ Language from the point of view of the driver\r
+ specified by This.\r
+\r
+ @retval EFI_SUCCESS The Unicode string for the user readable name in\r
+ the language specified by Language for the\r
+ driver specified by This was returned in\r
+ DriverName.\r
+\r
+ @retval EFI_INVALID_PARAMETER ControllerHandle is NULL.\r
+\r
+ @retval EFI_INVALID_PARAMETER ChildHandle is not NULL and it is not a valid\r
+ EFI_HANDLE.\r
+\r
+ @retval EFI_INVALID_PARAMETER Language is NULL.\r
+\r
+ @retval EFI_INVALID_PARAMETER ControllerName is NULL.\r
+\r
+ @retval EFI_UNSUPPORTED The driver specified by This is not currently\r
+ managing the controller specified by\r
+ ControllerHandle and ChildHandle.\r
+\r
+ @retval EFI_UNSUPPORTED The driver specified by This does not support\r
+ the language specified by Language.\r
+\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+VirtualKeyboardComponentNameGetControllerName (\r
+ IN EFI_COMPONENT_NAME_PROTOCOL *This,\r
+ IN EFI_HANDLE ControllerHandle,\r
+ IN EFI_HANDLE ChildHandle OPTIONAL,\r
+ IN CHAR8 *Language,\r
+ OUT CHAR16 **ControllerName\r
+ );\r
+\r
+\r
+#endif\r
--- /dev/null
+/** @file\r
+ VirtualKeyboard driver\r
+\r
+Copyright (c) 2006 - 2016, Intel Corporation. All rights reserved.<BR>\r
+Copyright (c) 2018, Linaro Ltd. All rights reserved.<BR>\r
+\r
+This program and the accompanying materials\r
+are licensed and made available under the terms and conditions\r
+of the BSD License which accompanies this distribution. The\r
+full text of the license may be found at\r
+http://opensource.org/licenses/bsd-license.php\r
+\r
+THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
+WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
+\r
+**/\r
+\r
+#include "VirtualKeyboard.h"\r
+\r
+//\r
+// RAM Keyboard Driver Binding Protocol Instance\r
+//\r
+EFI_DRIVER_BINDING_PROTOCOL gVirtualKeyboardDriverBinding = {\r
+ VirtualKeyboardDriverBindingSupported,\r
+ VirtualKeyboardDriverBindingStart,\r
+ VirtualKeyboardDriverBindingStop,\r
+ 0x10,\r
+ NULL,\r
+ NULL\r
+};\r
+\r
+//\r
+// EFI Driver Binding Protocol Functions\r
+//\r
+\r
+/**\r
+ Check whether the driver supports this device.\r
+\r
+ @param This The Udriver binding protocol.\r
+ @param Controller The controller handle to check.\r
+ @param RemainingDevicePath The remaining device path.\r
+\r
+ @retval EFI_SUCCESS The driver supports this controller.\r
+ @retval other This device isn't supported.\r
+\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+VirtualKeyboardDriverBindingSupported (\r
+ IN EFI_DRIVER_BINDING_PROTOCOL *This,\r
+ IN EFI_HANDLE Controller,\r
+ IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath\r
+ )\r
+{\r
+ EFI_STATUS Status;\r
+ PLATFORM_VIRTUAL_KBD_PROTOCOL *PlatformVirtual;\r
+\r
+ Status = gBS->OpenProtocol (\r
+ Controller,\r
+ &gPlatformVirtualKeyboardProtocolGuid,\r
+ (VOID **) &PlatformVirtual,\r
+ This->DriverBindingHandle,\r
+ Controller,\r
+ EFI_OPEN_PROTOCOL_BY_DRIVER\r
+ );\r
+ if (EFI_ERROR (Status)) {\r
+ return Status;\r
+ }\r
+ gBS->CloseProtocol (\r
+ Controller,\r
+ &gPlatformVirtualKeyboardProtocolGuid,\r
+ This->DriverBindingHandle,\r
+ Controller\r
+ );\r
+ return Status;\r
+}\r
+\r
+/**\r
+ Starts the device with this driver.\r
+\r
+ @param This The driver binding instance.\r
+ @param Controller Handle of device to bind driver to.\r
+ @param RemainingDevicePath Optional parameter use to pick a specific child\r
+ device to start.\r
+\r
+ @retval EFI_SUCCESS The controller is controlled by the driver.\r
+ @retval Other This controller cannot be started.\r
+\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+VirtualKeyboardDriverBindingStart (\r
+ IN EFI_DRIVER_BINDING_PROTOCOL *This,\r
+ IN EFI_HANDLE Controller,\r
+ IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath\r
+ )\r
+{\r
+ EFI_STATUS Status;\r
+ VIRTUAL_KEYBOARD_DEV *VirtualKeyboardPrivate;\r
+ PLATFORM_VIRTUAL_KBD_PROTOCOL *PlatformVirtual;\r
+\r
+ Status = gBS->OpenProtocol (\r
+ Controller,\r
+ &gPlatformVirtualKeyboardProtocolGuid,\r
+ (VOID **) &PlatformVirtual,\r
+ This->DriverBindingHandle,\r
+ Controller,\r
+ EFI_OPEN_PROTOCOL_BY_DRIVER\r
+ );\r
+ if (EFI_ERROR (Status)) {\r
+ return Status;\r
+ }\r
+\r
+ //\r
+ // Allocate the private device structure\r
+ //\r
+ VirtualKeyboardPrivate = (VIRTUAL_KEYBOARD_DEV *) AllocateZeroPool (sizeof (VIRTUAL_KEYBOARD_DEV));\r
+ if (VirtualKeyboardPrivate == NULL) {\r
+ Status = EFI_OUT_OF_RESOURCES;\r
+ goto Done;\r
+ }\r
+\r
+ //\r
+ // Initialize the private device structure\r
+ //\r
+ VirtualKeyboardPrivate->Signature = VIRTUAL_KEYBOARD_DEV_SIGNATURE;\r
+ VirtualKeyboardPrivate->Handle = Controller;\r
+ VirtualKeyboardPrivate->PlatformVirtual = PlatformVirtual;\r
+ VirtualKeyboardPrivate->Queue.Front = 0;\r
+ VirtualKeyboardPrivate->Queue.Rear = 0;\r
+ VirtualKeyboardPrivate->QueueForNotify.Front = 0;\r
+ VirtualKeyboardPrivate->QueueForNotify.Rear = 0;\r
+\r
+ VirtualKeyboardPrivate->SimpleTextIn.Reset = VirtualKeyboardReset;\r
+ VirtualKeyboardPrivate->SimpleTextIn.ReadKeyStroke = VirtualKeyboardReadKeyStroke;\r
+\r
+ VirtualKeyboardPrivate->SimpleTextInputEx.Reset = VirtualKeyboardResetEx;\r
+ VirtualKeyboardPrivate->SimpleTextInputEx.ReadKeyStrokeEx = VirtualKeyboardReadKeyStrokeEx;\r
+ VirtualKeyboardPrivate->SimpleTextInputEx.SetState = VirtualKeyboardSetState;\r
+\r
+ VirtualKeyboardPrivate->SimpleTextInputEx.RegisterKeyNotify = VirtualKeyboardRegisterKeyNotify;\r
+ VirtualKeyboardPrivate->SimpleTextInputEx.UnregisterKeyNotify = VirtualKeyboardUnregisterKeyNotify;\r
+ InitializeListHead (&VirtualKeyboardPrivate->NotifyList);\r
+\r
+ Status = PlatformVirtual->Register ();\r
+ if (EFI_ERROR (Status)) {\r
+ goto Done;\r
+ }\r
+\r
+ //\r
+ // Report that the keyboard is being enabled\r
+ //\r
+ REPORT_STATUS_CODE (\r
+ EFI_PROGRESS_CODE,\r
+ EFI_PERIPHERAL_KEYBOARD | EFI_P_PC_ENABLE\r
+ );\r
+\r
+ //\r
+ // Setup the WaitForKey event\r
+ //\r
+ Status = gBS->CreateEvent (\r
+ EVT_NOTIFY_WAIT,\r
+ TPL_NOTIFY,\r
+ VirtualKeyboardWaitForKey,\r
+ &(VirtualKeyboardPrivate->SimpleTextIn),\r
+ &((VirtualKeyboardPrivate->SimpleTextIn).WaitForKey)\r
+ );\r
+ if (EFI_ERROR (Status)) {\r
+ (VirtualKeyboardPrivate->SimpleTextIn).WaitForKey = NULL;\r
+ goto Done;\r
+ }\r
+ Status = gBS->CreateEvent (\r
+ EVT_NOTIFY_WAIT,\r
+ TPL_NOTIFY,\r
+ VirtualKeyboardWaitForKeyEx,\r
+ &(VirtualKeyboardPrivate->SimpleTextInputEx),\r
+ &(VirtualKeyboardPrivate->SimpleTextInputEx.WaitForKeyEx)\r
+ );\r
+ if (EFI_ERROR (Status)) {\r
+ VirtualKeyboardPrivate->SimpleTextInputEx.WaitForKeyEx = NULL;\r
+ goto Done;\r
+ }\r
+\r
+ //\r
+ // Setup a periodic timer, used for reading keystrokes at a fixed interval\r
+ //\r
+ Status = gBS->CreateEvent (\r
+ EVT_TIMER | EVT_NOTIFY_SIGNAL,\r
+ TPL_NOTIFY,\r
+ VirtualKeyboardTimerHandler,\r
+ VirtualKeyboardPrivate,\r
+ &VirtualKeyboardPrivate->TimerEvent\r
+ );\r
+ if (EFI_ERROR (Status)) {\r
+ Status = EFI_OUT_OF_RESOURCES;\r
+ goto Done;\r
+ }\r
+\r
+ Status = gBS->SetTimer (\r
+ VirtualKeyboardPrivate->TimerEvent,\r
+ TimerPeriodic,\r
+ KEYBOARD_TIMER_INTERVAL\r
+ );\r
+ if (EFI_ERROR (Status)) {\r
+ Status = EFI_OUT_OF_RESOURCES;\r
+ goto Done;\r
+ }\r
+\r
+ Status = gBS->CreateEvent (\r
+ EVT_NOTIFY_SIGNAL,\r
+ TPL_CALLBACK,\r
+ KeyNotifyProcessHandler,\r
+ VirtualKeyboardPrivate,\r
+ &VirtualKeyboardPrivate->KeyNotifyProcessEvent\r
+ );\r
+ if (EFI_ERROR (Status)) {\r
+ Status = EFI_OUT_OF_RESOURCES;\r
+ goto Done;\r
+ }\r
+\r
+ //\r
+ // Reset the keyboard device\r
+ //\r
+ Status = VirtualKeyboardPrivate->SimpleTextInputEx.Reset (\r
+ &VirtualKeyboardPrivate->SimpleTextInputEx,\r
+ FALSE\r
+ );\r
+ if (EFI_ERROR (Status)) {\r
+ DEBUG ((DEBUG_ERROR, "[KBD]Reset Failed. Status - %r\n", Status));\r
+ goto Done;\r
+ }\r
+ //\r
+ // Install protocol interfaces for the keyboard device.\r
+ //\r
+ Status = gBS->InstallMultipleProtocolInterfaces (\r
+ &Controller,\r
+ &gEfiSimpleTextInProtocolGuid,\r
+ &VirtualKeyboardPrivate->SimpleTextIn,\r
+ &gEfiSimpleTextInputExProtocolGuid,\r
+ &VirtualKeyboardPrivate->SimpleTextInputEx,\r
+ NULL\r
+ );\r
+\r
+Done:\r
+ if (EFI_ERROR (Status)) {\r
+ if (VirtualKeyboardPrivate != NULL) {\r
+ if ((VirtualKeyboardPrivate->SimpleTextIn).WaitForKey != NULL) {\r
+ gBS->CloseEvent ((VirtualKeyboardPrivate->SimpleTextIn).WaitForKey);\r
+ }\r
+\r
+ if ((VirtualKeyboardPrivate->SimpleTextInputEx).WaitForKeyEx != NULL) {\r
+ gBS->CloseEvent (\r
+ (VirtualKeyboardPrivate->SimpleTextInputEx).WaitForKeyEx\r
+ );\r
+ }\r
+\r
+ if (VirtualKeyboardPrivate->KeyNotifyProcessEvent != NULL) {\r
+ gBS->CloseEvent (VirtualKeyboardPrivate->KeyNotifyProcessEvent);\r
+ }\r
+\r
+ VirtualKeyboardFreeNotifyList (&VirtualKeyboardPrivate->NotifyList);\r
+\r
+ if (VirtualKeyboardPrivate->TimerEvent != NULL) {\r
+ gBS->CloseEvent (VirtualKeyboardPrivate->TimerEvent);\r
+ }\r
+ FreePool (VirtualKeyboardPrivate);\r
+ }\r
+ }\r
+\r
+ gBS->CloseProtocol (\r
+ Controller,\r
+ &gPlatformVirtualKeyboardProtocolGuid,\r
+ This->DriverBindingHandle,\r
+ Controller\r
+ );\r
+\r
+ return Status;\r
+}\r
+\r
+/**\r
+ Stop the device handled by this driver.\r
+\r
+ @param This The driver binding protocol.\r
+ @param Controller The controller to release.\r
+ @param NumberOfChildren The number of handles in ChildHandleBuffer.\r
+ @param ChildHandleBuffer The array of child handle.\r
+\r
+ @retval EFI_SUCCESS The device was stopped.\r
+ @retval EFI_DEVICE_ERROR The device could not be stopped due to a\r
+ device error.\r
+ @retval Others Fail to uninstall protocols attached on the\r
+ device.\r
+\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+VirtualKeyboardDriverBindingStop (\r
+ IN EFI_DRIVER_BINDING_PROTOCOL *This,\r
+ IN EFI_HANDLE Controller,\r
+ IN UINTN NumberOfChildren,\r
+ IN EFI_HANDLE *ChildHandleBuffer\r
+ )\r
+{\r
+ return EFI_SUCCESS;\r
+}\r
+\r
+\r
+/**\r
+ Enqueue the key.\r
+\r
+ @param Queue The queue to be enqueued.\r
+ @param KeyData The key data to be enqueued.\r
+\r
+ @retval EFI_NOT_READY The queue is full.\r
+ @retval EFI_SUCCESS Successfully enqueued the key data.\r
+\r
+**/\r
+EFI_STATUS\r
+Enqueue (\r
+ IN SIMPLE_QUEUE *Queue,\r
+ IN EFI_KEY_DATA *KeyData\r
+ )\r
+{\r
+ if ((Queue->Rear + 1) % QUEUE_MAX_COUNT == Queue->Front) {\r
+ return EFI_NOT_READY;\r
+ }\r
+\r
+ CopyMem (&Queue->Buffer[Queue->Rear], KeyData, sizeof (EFI_KEY_DATA));\r
+ Queue->Rear = (Queue->Rear + 1) % QUEUE_MAX_COUNT;\r
+\r
+ return EFI_SUCCESS;\r
+}\r
+\r
+/**\r
+ Dequeue the key.\r
+\r
+ @param Queue The queue to be dequeued.\r
+ @param KeyData The key data to be dequeued.\r
+\r
+ @retval EFI_NOT_READY The queue is empty.\r
+ @retval EFI_SUCCESS Successfully dequeued the key data.\r
+\r
+**/\r
+EFI_STATUS\r
+Dequeue (\r
+ IN SIMPLE_QUEUE *Queue,\r
+ IN EFI_KEY_DATA *KeyData\r
+ )\r
+{\r
+ if (Queue->Front == Queue->Rear) {\r
+ return EFI_NOT_READY;\r
+ }\r
+\r
+ CopyMem (KeyData, &Queue->Buffer[Queue->Front], sizeof (EFI_KEY_DATA));\r
+ Queue->Front = (Queue->Front + 1) % QUEUE_MAX_COUNT;\r
+\r
+ return EFI_SUCCESS;\r
+}\r
+\r
+/**\r
+ Check whether the queue is empty.\r
+\r
+ @param Queue The queue to be checked.\r
+\r
+ @retval EFI_NOT_READY The queue is empty.\r
+ @retval EFI_SUCCESS The queue is not empty.\r
+\r
+**/\r
+EFI_STATUS\r
+CheckQueue (\r
+ IN SIMPLE_QUEUE *Queue\r
+ )\r
+{\r
+ if (Queue->Front == Queue->Rear) {\r
+ return EFI_NOT_READY;\r
+ }\r
+\r
+ return EFI_SUCCESS;\r
+}\r
+\r
+/**\r
+ Check key buffer to get the key stroke status.\r
+\r
+ @param This Pointer of the protocol EFI_SIMPLE_TEXT_IN_PROTOCOL.\r
+\r
+ @retval EFI_SUCCESS A key is being pressed now.\r
+ @retval Other No key is now pressed.\r
+\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+VirtualKeyboardCheckForKey (\r
+ IN EFI_SIMPLE_TEXT_INPUT_PROTOCOL *This\r
+ )\r
+{\r
+ VIRTUAL_KEYBOARD_DEV *VirtualKeyboardPrivate;\r
+\r
+ VirtualKeyboardPrivate = VIRTUAL_KEYBOARD_DEV_FROM_THIS (This);\r
+\r
+ return CheckQueue (&VirtualKeyboardPrivate->Queue);\r
+}\r
+\r
+/**\r
+ Free keyboard notify list.\r
+\r
+ @param ListHead The list head\r
+\r
+ @retval EFI_SUCCESS Free the notify list successfully\r
+ @retval EFI_INVALID_PARAMETER ListHead is invalid.\r
+\r
+**/\r
+EFI_STATUS\r
+VirtualKeyboardFreeNotifyList (\r
+ IN OUT LIST_ENTRY *ListHead\r
+ )\r
+{\r
+ VIRTUAL_KEYBOARD_CONSOLE_IN_EX_NOTIFY *NotifyNode;\r
+\r
+ if (ListHead == NULL) {\r
+ return EFI_INVALID_PARAMETER;\r
+ }\r
+ while (!IsListEmpty (ListHead)) {\r
+ NotifyNode = CR (\r
+ ListHead->ForwardLink,\r
+ VIRTUAL_KEYBOARD_CONSOLE_IN_EX_NOTIFY,\r
+ NotifyEntry,\r
+ VIRTUAL_KEYBOARD_CONSOLE_IN_EX_NOTIFY_SIGNATURE\r
+ );\r
+ RemoveEntryList (ListHead->ForwardLink);\r
+ gBS->FreePool (NotifyNode);\r
+ }\r
+\r
+ return EFI_SUCCESS;\r
+}\r
+\r
+/**\r
+ Judge whether is a registed key\r
+\r
+ @param RegsiteredData A pointer to a buffer that is filled in with\r
+ the keystroke state data for the key that was\r
+ registered.\r
+ @param InputData A pointer to a buffer that is filled in with\r
+ the keystroke state data for the key that was\r
+ pressed.\r
+\r
+ @retval TRUE Key be pressed matches a registered key.\r
+ @retval FLASE Match failed.\r
+\r
+**/\r
+BOOLEAN\r
+IsKeyRegistered (\r
+ IN EFI_KEY_DATA *RegsiteredData,\r
+ IN EFI_KEY_DATA *InputData\r
+ )\r
+\r
+{\r
+ ASSERT (RegsiteredData != NULL && InputData != NULL);\r
+\r
+ if ((RegsiteredData->Key.ScanCode != InputData->Key.ScanCode) ||\r
+ (RegsiteredData->Key.UnicodeChar != InputData->Key.UnicodeChar)) {\r
+ return FALSE;\r
+ }\r
+\r
+ //\r
+ // Assume KeyShiftState/KeyToggleState = 0 in Registered key data means\r
+ // these state could be ignored.\r
+ //\r
+ if ((RegsiteredData->KeyState.KeyShiftState != 0) &&\r
+ (RegsiteredData->KeyState.KeyShiftState != InputData->KeyState.KeyShiftState)) {\r
+ return FALSE;\r
+ }\r
+ if ((RegsiteredData->KeyState.KeyToggleState != 0) &&\r
+ (RegsiteredData->KeyState.KeyToggleState != InputData->KeyState.KeyToggleState)) {\r
+ return FALSE;\r
+ }\r
+\r
+ return TRUE;\r
+\r
+}\r
+\r
+/**\r
+ Event notification function for SIMPLE_TEXT_IN.WaitForKey event\r
+ Signal the event if there is key available\r
+\r
+ @param Event the event object\r
+ @param Context waitting context\r
+\r
+**/\r
+VOID\r
+EFIAPI\r
+VirtualKeyboardWaitForKey (\r
+ IN EFI_EVENT Event,\r
+ IN VOID *Context\r
+ )\r
+{\r
+ //\r
+ // Stall 1ms to give a chance to let other driver interrupt this routine\r
+ // for their timer event.\r
+ // e.g. UI setup or Shell, other drivers which are driven by timer event\r
+ // will have a bad performance during this period,\r
+ // e.g. usb keyboard driver.\r
+ // Add a stall period can greatly increate other driver performance during\r
+ // the WaitForKey is recursivly invoked. 1ms delay will make little impact\r
+ // to the thunk keyboard driver, and user can not feel the delay at all when\r
+ // input.\r
+ //\r
+ gBS->Stall (1000);\r
+ //\r
+ // Use TimerEvent callback function to check whether there's any key pressed\r
+ //\r
+ VirtualKeyboardTimerHandler (NULL, VIRTUAL_KEYBOARD_DEV_FROM_THIS (Context));\r
+\r
+ if (!EFI_ERROR (VirtualKeyboardCheckForKey (Context))) {\r
+ gBS->SignalEvent (Event);\r
+ }\r
+}\r
+\r
+/**\r
+ Event notification function for SIMPLE_TEXT_INPUT_EX_PROTOCOL.WaitForKeyEx\r
+ event. Signal the event if there is key available\r
+\r
+ @param Event event object\r
+ @param Context waiting context\r
+\r
+**/\r
+VOID\r
+EFIAPI\r
+VirtualKeyboardWaitForKeyEx (\r
+ IN EFI_EVENT Event,\r
+ IN VOID *Context\r
+ )\r
+\r
+{\r
+ VIRTUAL_KEYBOARD_DEV *VirtualKeyboardPrivate;\r
+\r
+ VirtualKeyboardPrivate = TEXT_INPUT_EX_VIRTUAL_KEYBOARD_DEV_FROM_THIS (Context);\r
+ VirtualKeyboardWaitForKey (Event, &VirtualKeyboardPrivate->SimpleTextIn);\r
+\r
+}\r
+\r
+//\r
+// EFI Simple Text In Protocol Functions\r
+//\r
+/**\r
+ Reset the Keyboard and do BAT test for it, if (ExtendedVerification == TRUE)\r
+ then do some extra keyboard validations.\r
+\r
+ @param This Pointer of simple text Protocol.\r
+ @param ExtendedVerification Whether perform the extra validation of\r
+ keyboard. True: perform; FALSE: skip.\r
+\r
+ @retval EFI_SUCCESS The command byte is written successfully.\r
+ @retval EFI_DEVICE_ERROR Errors occurred during resetting keyboard.\r
+\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+VirtualKeyboardReset (\r
+ IN EFI_SIMPLE_TEXT_INPUT_PROTOCOL *This,\r
+ IN BOOLEAN ExtendedVerification\r
+ )\r
+{\r
+ VIRTUAL_KEYBOARD_DEV *VirtualKeyboardPrivate;\r
+ EFI_STATUS Status;\r
+ EFI_TPL OldTpl;\r
+\r
+ VirtualKeyboardPrivate = VIRTUAL_KEYBOARD_DEV_FROM_THIS (This);\r
+\r
+ //\r
+ // Raise TPL to avoid mouse operation impact\r
+ //\r
+ OldTpl = gBS->RaiseTPL (TPL_NOTIFY);\r
+\r
+ if (VirtualKeyboardPrivate->PlatformVirtual &&\r
+ VirtualKeyboardPrivate->PlatformVirtual->Reset) {\r
+ Status = VirtualKeyboardPrivate->PlatformVirtual->Reset ();\r
+ } else {\r
+ Status = EFI_INVALID_PARAMETER;\r
+ }\r
+\r
+ //\r
+ // resume priority of task level\r
+ //\r
+ gBS->RestoreTPL (OldTpl);\r
+\r
+ return Status;\r
+}\r
+\r
+/**\r
+ Reset the input device and optionaly run diagnostics\r
+\r
+ @param This Protocol instance pointer.\r
+ @param ExtendedVerification Driver may perform diagnostics on reset.\r
+\r
+ @retval EFI_SUCCESS The device was reset.\r
+ @retval EFI_DEVICE_ERROR The device is not functioning properly and\r
+ could not be reset.\r
+\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+VirtualKeyboardResetEx (\r
+ IN EFI_SIMPLE_TEXT_INPUT_EX_PROTOCOL *This,\r
+ IN BOOLEAN ExtendedVerification\r
+ )\r
+{\r
+ VIRTUAL_KEYBOARD_DEV *VirtualKeyboardPrivate;\r
+ EFI_STATUS Status;\r
+ EFI_TPL OldTpl;\r
+\r
+ VirtualKeyboardPrivate = TEXT_INPUT_EX_VIRTUAL_KEYBOARD_DEV_FROM_THIS (This);\r
+\r
+ Status = VirtualKeyboardPrivate->SimpleTextIn.Reset (\r
+ &VirtualKeyboardPrivate->SimpleTextIn,\r
+ ExtendedVerification\r
+ );\r
+ if (EFI_ERROR (Status)) {\r
+ return EFI_DEVICE_ERROR;\r
+ }\r
+\r
+ OldTpl = gBS->RaiseTPL (TPL_NOTIFY);\r
+\r
+ gBS->RestoreTPL (OldTpl);\r
+\r
+ return EFI_SUCCESS;\r
+\r
+}\r
+\r
+/**\r
+ Reads the next keystroke from the input device. The WaitForKey Event can\r
+ be used to test for existance of a keystroke via WaitForEvent () call.\r
+\r
+ @param VirtualKeyboardPrivate Virtualkeyboard driver private structure.\r
+ @param KeyData A pointer to a buffer that is filled in\r
+ with the keystroke state data for the key\r
+ that was pressed.\r
+\r
+ @retval EFI_SUCCESS The keystroke information was returned.\r
+ @retval EFI_NOT_READY There was no keystroke data availiable.\r
+ @retval EFI_DEVICE_ERROR The keystroke information was not returned\r
+ due to hardware errors.\r
+ @retval EFI_INVALID_PARAMETER KeyData is NULL.\r
+\r
+**/\r
+EFI_STATUS\r
+KeyboardReadKeyStrokeWorker (\r
+ IN VIRTUAL_KEYBOARD_DEV *VirtualKeyboardPrivate,\r
+ OUT EFI_KEY_DATA *KeyData\r
+ )\r
+{\r
+ EFI_STATUS Status;\r
+ EFI_TPL OldTpl;\r
+ if (KeyData == NULL) {\r
+ return EFI_INVALID_PARAMETER;\r
+ }\r
+\r
+ //\r
+ // Use TimerEvent callback function to check whether there's any key pressed\r
+ //\r
+\r
+ //\r
+ // Stall 1ms to give a chance to let other driver interrupt this routine for\r
+ // their timer event.\r
+ // e.g. OS loader, other drivers which are driven by timer event will have a\r
+ // bad performance during this period,\r
+ // e.g. usb keyboard driver.\r
+ // Add a stall period can greatly increate other driver performance during\r
+ // the WaitForKey is recursivly invoked. 1ms delay will make little impact\r
+ // to the thunk keyboard driver, and user can not feel the delay at all when\r
+ // input.\r
+ //\r
+ gBS->Stall (1000);\r
+\r
+ OldTpl = gBS->RaiseTPL (TPL_NOTIFY);\r
+\r
+ VirtualKeyboardTimerHandler (NULL, VirtualKeyboardPrivate);\r
+ //\r
+ // If there's no key, just return\r
+ //\r
+ Status = CheckQueue (&VirtualKeyboardPrivate->Queue);\r
+ if (EFI_ERROR (Status)) {\r
+ gBS->RestoreTPL (OldTpl);\r
+ return EFI_NOT_READY;\r
+ }\r
+\r
+ Status = Dequeue (&VirtualKeyboardPrivate->Queue, KeyData);\r
+\r
+ gBS->RestoreTPL (OldTpl);\r
+\r
+ return EFI_SUCCESS;\r
+}\r
+\r
+/**\r
+ Read out the scan code of the key that has just been stroked.\r
+\r
+ @param This Pointer of simple text Protocol.\r
+ @param Key Pointer for store the key that read out.\r
+\r
+ @retval EFI_SUCCESS The key is read out successfully.\r
+ @retval other The key reading failed.\r
+\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+VirtualKeyboardReadKeyStroke (\r
+ IN EFI_SIMPLE_TEXT_INPUT_PROTOCOL *This,\r
+ OUT EFI_INPUT_KEY *Key\r
+ )\r
+{\r
+ VIRTUAL_KEYBOARD_DEV *VirtualKeyboardPrivate;\r
+ EFI_STATUS Status;\r
+ EFI_KEY_DATA KeyData;\r
+\r
+ VirtualKeyboardPrivate = VIRTUAL_KEYBOARD_DEV_FROM_THIS (This);\r
+\r
+ Status = KeyboardReadKeyStrokeWorker (VirtualKeyboardPrivate, &KeyData);\r
+ if (EFI_ERROR (Status)) {\r
+ return Status;\r
+ }\r
+\r
+ //\r
+ // Convert the Ctrl+[a-z] to Ctrl+[1-26]\r
+ //\r
+ if ((KeyData.KeyState.KeyShiftState & (EFI_LEFT_CONTROL_PRESSED | EFI_RIGHT_CONTROL_PRESSED)) != 0) {\r
+ if (KeyData.Key.UnicodeChar >= L'a' &&\r
+ KeyData.Key.UnicodeChar <= L'z') {\r
+ KeyData.Key.UnicodeChar = (CHAR16) (KeyData.Key.UnicodeChar - L'a' + 1);\r
+ } else if (KeyData.Key.UnicodeChar >= L'A' &&\r
+ KeyData.Key.UnicodeChar <= L'Z') {\r
+ KeyData.Key.UnicodeChar = (CHAR16) (KeyData.Key.UnicodeChar - L'A' + 1);\r
+ }\r
+ }\r
+\r
+ CopyMem (Key, &KeyData.Key, sizeof (EFI_INPUT_KEY));\r
+\r
+ return EFI_SUCCESS;\r
+}\r
+\r
+/**\r
+ Reads the next keystroke from the input device. The WaitForKey Event can\r
+ be used to test for existance of a keystroke via WaitForEvent () call.\r
+\r
+ @param This Protocol instance pointer.\r
+ @param KeyData A pointer to a buffer that is filled in with the\r
+ keystroke state data for the key that was pressed.\r
+\r
+ @retval EFI_SUCCESS The keystroke information was returned.\r
+ @retval EFI_NOT_READY There was no keystroke data availiable.\r
+ @retval EFI_DEVICE_ERROR The keystroke information was not returned\r
+ due to hardware errors.\r
+ @retval EFI_INVALID_PARAMETER KeyData is NULL.\r
+\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+VirtualKeyboardReadKeyStrokeEx (\r
+ IN EFI_SIMPLE_TEXT_INPUT_EX_PROTOCOL *This,\r
+ OUT EFI_KEY_DATA *KeyData\r
+ )\r
+{\r
+ VIRTUAL_KEYBOARD_DEV *VirtualKeyboardPrivate;\r
+\r
+ if (KeyData == NULL) {\r
+ return EFI_INVALID_PARAMETER;\r
+ }\r
+\r
+ VirtualKeyboardPrivate = TEXT_INPUT_EX_VIRTUAL_KEYBOARD_DEV_FROM_THIS (This);\r
+\r
+ return KeyboardReadKeyStrokeWorker (VirtualKeyboardPrivate, KeyData);\r
+\r
+}\r
+\r
+/**\r
+ Set certain state for the input device.\r
+\r
+ @param This Protocol instance pointer.\r
+ @param KeyToggleState A pointer to the EFI_KEY_TOGGLE_STATE to set the\r
+ state for the input device.\r
+\r
+ @retval EFI_SUCCESS The device state was set successfully.\r
+ @retval EFI_DEVICE_ERROR The device is not functioning correctly and\r
+ could not have the setting adjusted.\r
+ @retval EFI_UNSUPPORTED The device does not have the ability to set\r
+ its state.\r
+ @retval EFI_INVALID_PARAMETER KeyToggleState is NULL.\r
+\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+VirtualKeyboardSetState (\r
+ IN EFI_SIMPLE_TEXT_INPUT_EX_PROTOCOL *This,\r
+ IN EFI_KEY_TOGGLE_STATE *KeyToggleState\r
+ )\r
+{\r
+ if (KeyToggleState == NULL) {\r
+ return EFI_INVALID_PARAMETER;\r
+ }\r
+\r
+ return EFI_SUCCESS;\r
+}\r
+\r
+/**\r
+ Register a notification function for a particular keystroke for the\r
+ input device.\r
+\r
+ @param This Protocol instance pointer.\r
+ @param KeyData A pointer to a buffer that is filled in with\r
+ the keystroke information data for the key\r
+ that was pressed.\r
+ @param KeyNotificationFunction Points to the function to be called when the\r
+ key sequence is typed specified by KeyData.\r
+ @param NotifyHandle Points to the unique handle assigned to the\r
+ registered notification.\r
+\r
+\r
+ @retval EFI_SUCCESS The notification function was registered\r
+ successfully.\r
+ @retval EFI_OUT_OF_RESOURCES Unable to allocate resources for necesssary\r
+ data structures.\r
+ @retval EFI_INVALID_PARAMETER KeyData or NotifyHandle is NULL.\r
+\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+VirtualKeyboardRegisterKeyNotify (\r
+ IN EFI_SIMPLE_TEXT_INPUT_EX_PROTOCOL *This,\r
+ IN EFI_KEY_DATA *KeyData,\r
+ IN EFI_KEY_NOTIFY_FUNCTION KeyNotificationFunction,\r
+ OUT VOID **NotifyHandle\r
+ )\r
+{\r
+ EFI_STATUS Status;\r
+ VIRTUAL_KEYBOARD_DEV *VirtualKeyboardPrivate;\r
+ EFI_TPL OldTpl;\r
+ VIRTUAL_KEYBOARD_CONSOLE_IN_EX_NOTIFY *NewNotify;\r
+ LIST_ENTRY *Link;\r
+ VIRTUAL_KEYBOARD_CONSOLE_IN_EX_NOTIFY *CurrentNotify;\r
+\r
+ if (KeyData == NULL ||\r
+ NotifyHandle == NULL ||\r
+ KeyNotificationFunction == NULL) {\r
+ return EFI_INVALID_PARAMETER;\r
+ }\r
+\r
+ VirtualKeyboardPrivate = TEXT_INPUT_EX_VIRTUAL_KEYBOARD_DEV_FROM_THIS (This);\r
+\r
+ //\r
+ // Enter critical section\r
+ //\r
+ OldTpl = gBS->RaiseTPL (TPL_NOTIFY);\r
+\r
+ //\r
+ // Return EFI_SUCCESS if the (KeyData, NotificationFunction) is already\r
+ // registered.\r
+ //\r
+ for (Link = VirtualKeyboardPrivate->NotifyList.ForwardLink;\r
+ Link != &VirtualKeyboardPrivate->NotifyList;\r
+ Link = Link->ForwardLink) {\r
+ CurrentNotify = CR (\r
+ Link,\r
+ VIRTUAL_KEYBOARD_CONSOLE_IN_EX_NOTIFY,\r
+ NotifyEntry,\r
+ VIRTUAL_KEYBOARD_CONSOLE_IN_EX_NOTIFY_SIGNATURE\r
+ );\r
+ if (IsKeyRegistered (&CurrentNotify->KeyData, KeyData)) {\r
+ if (CurrentNotify->KeyNotificationFn == KeyNotificationFunction) {\r
+ *NotifyHandle = CurrentNotify;\r
+ Status = EFI_SUCCESS;\r
+ goto Exit;\r
+ }\r
+ }\r
+ }\r
+\r
+ //\r
+ // Allocate resource to save the notification function\r
+ //\r
+\r
+ NewNotify = (VIRTUAL_KEYBOARD_CONSOLE_IN_EX_NOTIFY *) AllocateZeroPool (sizeof (VIRTUAL_KEYBOARD_CONSOLE_IN_EX_NOTIFY));\r
+ if (NewNotify == NULL) {\r
+ Status = EFI_OUT_OF_RESOURCES;\r
+ goto Exit;\r
+ }\r
+\r
+ NewNotify->Signature = VIRTUAL_KEYBOARD_CONSOLE_IN_EX_NOTIFY_SIGNATURE;\r
+ NewNotify->KeyNotificationFn = KeyNotificationFunction;\r
+ CopyMem (&NewNotify->KeyData, KeyData, sizeof (EFI_KEY_DATA));\r
+ InsertTailList (&VirtualKeyboardPrivate->NotifyList, &NewNotify->NotifyEntry);\r
+\r
+ *NotifyHandle = NewNotify;\r
+ Status = EFI_SUCCESS;\r
+\r
+Exit:\r
+ //\r
+ // Leave critical section and return\r
+ //\r
+ gBS->RestoreTPL (OldTpl);\r
+ return Status;\r
+\r
+}\r
+\r
+/**\r
+ Remove a registered notification function from a particular keystroke.\r
+\r
+ @param This Protocol instance pointer.\r
+ @param NotificationHandle The handle of the notification function\r
+ being unregistered.\r
+\r
+ @retval EFI_SUCCESS The notification function was unregistered\r
+ successfully.\r
+ @retval EFI_INVALID_PARAMETER The NotificationHandle is invalid.\r
+\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+VirtualKeyboardUnregisterKeyNotify (\r
+ IN EFI_SIMPLE_TEXT_INPUT_EX_PROTOCOL *This,\r
+ IN VOID *NotificationHandle\r
+ )\r
+{\r
+ EFI_STATUS Status;\r
+ VIRTUAL_KEYBOARD_DEV *VirtualKeyboardPrivate;\r
+ EFI_TPL OldTpl;\r
+ LIST_ENTRY *Link;\r
+ VIRTUAL_KEYBOARD_CONSOLE_IN_EX_NOTIFY *CurrentNotify;\r
+\r
+ //\r
+ // Check incoming notification handle\r
+ //\r
+ if (NotificationHandle == NULL) {\r
+ return EFI_INVALID_PARAMETER;\r
+ }\r
+\r
+ if (((VIRTUAL_KEYBOARD_CONSOLE_IN_EX_NOTIFY *) NotificationHandle)->Signature !=\r
+ VIRTUAL_KEYBOARD_CONSOLE_IN_EX_NOTIFY_SIGNATURE) {\r
+ return EFI_INVALID_PARAMETER;\r
+ }\r
+\r
+ VirtualKeyboardPrivate = TEXT_INPUT_EX_VIRTUAL_KEYBOARD_DEV_FROM_THIS (This);\r
+\r
+ //\r
+ // Enter critical section\r
+ //\r
+ OldTpl = gBS->RaiseTPL (TPL_NOTIFY);\r
+\r
+ for (Link = VirtualKeyboardPrivate->NotifyList.ForwardLink;\r
+ Link != &VirtualKeyboardPrivate->NotifyList;\r
+ Link = Link->ForwardLink) {\r
+ CurrentNotify = CR (\r
+ Link,\r
+ VIRTUAL_KEYBOARD_CONSOLE_IN_EX_NOTIFY,\r
+ NotifyEntry,\r
+ VIRTUAL_KEYBOARD_CONSOLE_IN_EX_NOTIFY_SIGNATURE\r
+ );\r
+ if (CurrentNotify == NotificationHandle) {\r
+ //\r
+ // Remove the notification function from NotifyList and free resources\r
+ //\r
+ RemoveEntryList (&CurrentNotify->NotifyEntry);\r
+\r
+ Status = EFI_SUCCESS;\r
+ goto Exit;\r
+ }\r
+ }\r
+\r
+ //\r
+ // Can not find the specified Notification Handle\r
+ //\r
+ Status = EFI_INVALID_PARAMETER;\r
+\r
+Exit:\r
+ //\r
+ // Leave critical section and return\r
+ //\r
+ gBS->RestoreTPL (OldTpl);\r
+ return Status;\r
+}\r
+\r
+/**\r
+ Timer event handler: read a series of scancodes from 8042\r
+ and put them into memory scancode buffer.\r
+ it read as much scancodes to either fill\r
+ the memory buffer or empty the keyboard buffer.\r
+ It is registered as running under TPL_NOTIFY\r
+\r
+ @param Event The timer event\r
+ @param Context A KEYBOARD_CONSOLE_IN_DEV pointer\r
+\r
+**/\r
+VOID\r
+EFIAPI\r
+VirtualKeyboardTimerHandler (\r
+ IN EFI_EVENT Event,\r
+ IN VOID *Context\r
+ )\r
+{\r
+ EFI_TPL OldTpl;\r
+ LIST_ENTRY *Link;\r
+ EFI_KEY_DATA KeyData;\r
+ VIRTUAL_KEYBOARD_CONSOLE_IN_EX_NOTIFY *CurrentNotify;\r
+ VIRTUAL_KEYBOARD_DEV *VirtualKeyboardPrivate;\r
+ VIRTUAL_KBD_KEY VirtualKey;\r
+\r
+ VirtualKeyboardPrivate = Context;\r
+\r
+ //\r
+ // Enter critical section\r
+ //\r
+ OldTpl = gBS->RaiseTPL (TPL_NOTIFY);\r
+\r
+ if (VirtualKeyboardPrivate->PlatformVirtual &&\r
+ VirtualKeyboardPrivate->PlatformVirtual->Query) {\r
+ if (VirtualKeyboardPrivate->PlatformVirtual->Query (&VirtualKey) ==\r
+ FALSE) {\r
+ goto Exit;\r
+ }\r
+ // Found key\r
+ KeyData.Key.ScanCode = VirtualKey.Key.ScanCode;\r
+ KeyData.Key.UnicodeChar = VirtualKey.Key.UnicodeChar;\r
+ KeyData.KeyState.KeyShiftState = EFI_SHIFT_STATE_VALID;\r
+ KeyData.KeyState.KeyToggleState = EFI_TOGGLE_STATE_VALID;\r
+ if (VirtualKeyboardPrivate->PlatformVirtual->Clear) {\r
+ VirtualKeyboardPrivate->PlatformVirtual->Clear (&VirtualKey);\r
+ }\r
+ } else {\r
+ goto Exit;\r
+ }\r
+\r
+ //\r
+ // Signal KeyNotify process event if this key pressed matches any key registered.\r
+ //\r
+ for (Link = VirtualKeyboardPrivate->NotifyList.ForwardLink;\r
+ Link != &VirtualKeyboardPrivate->NotifyList;\r
+ Link = Link->ForwardLink) {\r
+ CurrentNotify = CR (\r
+ Link,\r
+ VIRTUAL_KEYBOARD_CONSOLE_IN_EX_NOTIFY,\r
+ NotifyEntry,\r
+ VIRTUAL_KEYBOARD_CONSOLE_IN_EX_NOTIFY_SIGNATURE\r
+ );\r
+ if (IsKeyRegistered (&CurrentNotify->KeyData, &KeyData)) {\r
+ //\r
+ // The key notification function needs to run at TPL_CALLBACK\r
+ // while current TPL is TPL_NOTIFY. It will be invoked in\r
+ // KeyNotifyProcessHandler() which runs at TPL_CALLBACK.\r
+ //\r
+ Enqueue (&VirtualKeyboardPrivate->QueueForNotify, &KeyData);\r
+ gBS->SignalEvent (VirtualKeyboardPrivate->KeyNotifyProcessEvent);\r
+ }\r
+ }\r
+\r
+ Enqueue (&VirtualKeyboardPrivate->Queue, &KeyData);\r
+\r
+Exit:\r
+ //\r
+ // Leave critical section and return\r
+ //\r
+ gBS->RestoreTPL (OldTpl);\r
+}\r
+\r
+/**\r
+ Process key notify.\r
+\r
+ @param Event Indicates the event that invoke this function.\r
+ @param Context Indicates the calling context.\r
+**/\r
+VOID\r
+EFIAPI\r
+KeyNotifyProcessHandler (\r
+ IN EFI_EVENT Event,\r
+ IN VOID *Context\r
+ )\r
+{\r
+ EFI_STATUS Status;\r
+ VIRTUAL_KEYBOARD_DEV *VirtualKeyboardPrivate;\r
+ EFI_KEY_DATA KeyData;\r
+ LIST_ENTRY *Link;\r
+ LIST_ENTRY *NotifyList;\r
+ VIRTUAL_KEYBOARD_CONSOLE_IN_EX_NOTIFY *CurrentNotify;\r
+ EFI_TPL OldTpl;\r
+\r
+ VirtualKeyboardPrivate = (VIRTUAL_KEYBOARD_DEV *) Context;\r
+\r
+ //\r
+ // Invoke notification functions.\r
+ //\r
+ NotifyList = &VirtualKeyboardPrivate->NotifyList;\r
+ while (TRUE) {\r
+ //\r
+ // Enter critical section\r
+ //\r
+ OldTpl = gBS->RaiseTPL (TPL_NOTIFY);\r
+ Status = Dequeue (&VirtualKeyboardPrivate->QueueForNotify, &KeyData);\r
+ //\r
+ // Leave critical section\r
+ //\r
+ gBS->RestoreTPL (OldTpl);\r
+ if (EFI_ERROR (Status)) {\r
+ break;\r
+ }\r
+ for (Link = GetFirstNode (NotifyList);\r
+ !IsNull (NotifyList, Link);\r
+ Link = GetNextNode (NotifyList, Link)) {\r
+ CurrentNotify = CR (Link,\r
+ VIRTUAL_KEYBOARD_CONSOLE_IN_EX_NOTIFY,\r
+ NotifyEntry,\r
+ VIRTUAL_KEYBOARD_CONSOLE_IN_EX_NOTIFY_SIGNATURE\r
+ );\r
+ if (IsKeyRegistered (&CurrentNotify->KeyData, &KeyData)) {\r
+ CurrentNotify->KeyNotificationFn (&KeyData);\r
+ }\r
+ }\r
+ }\r
+}\r
+\r
+/**\r
+ The user Entry Point for module VirtualKeyboard. The user code starts with\r
+ this function.\r
+\r
+ @param[in] ImageHandle The firmware allocated handle for the EFI image.\r
+ @param[in] SystemTable A pointer to the EFI System Table.\r
+\r
+ @retval EFI_SUCCESS The entry point is executed successfully.\r
+ @retval other Some error occurs when executing this entry point.\r
+\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+InitializeVirtualKeyboard(\r
+ IN EFI_HANDLE ImageHandle,\r
+ IN EFI_SYSTEM_TABLE *SystemTable\r
+ )\r
+{\r
+ EFI_STATUS Status;\r
+\r
+ //\r
+ // Install driver model protocol(s).\r
+ //\r
+ Status = EfiLibInstallDriverBindingComponentName2 (\r
+ ImageHandle,\r
+ SystemTable,\r
+ &gVirtualKeyboardDriverBinding,\r
+ ImageHandle,\r
+ &gVirtualKeyboardComponentName,\r
+ &gVirtualKeyboardComponentName2\r
+ );\r
+ ASSERT_EFI_ERROR (Status);\r
+\r
+ return Status;\r
+}\r
--- /dev/null
+/** @file\r
+\r
+Copyright (c) 2006 - 2016, Intel Corporation. All rights reserved.<BR>\r
+Copyright (c) 2018, Linaro Ltd. All rights reserved.<BR>\r
+\r
+This program and the accompanying materials\r
+are licensed and made available under the terms and conditions\r
+of the BSD License which accompanies this distribution. The\r
+full text of the license may be found at\r
+http://opensource.org/licenses/bsd-license.php\r
+\r
+THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
+WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
+\r
+**/\r
+\r
+#ifndef _VIRTUAL_KEYBOARD_H_\r
+#define _VIRTUAL_KEYBOARD_H_\r
+\r
+\r
+#include <Guid/StatusCodeDataTypeId.h>\r
+#include <Protocol/DevicePath.h>\r
+#include <Protocol/PlatformVirtualKeyboard.h>\r
+#include <Protocol/SimpleTextIn.h>\r
+#include <Protocol/SimpleTextInEx.h>\r
+\r
+#include <Library/BaseLib.h>\r
+#include <Library/BaseMemoryLib.h>\r
+#include <Library/DebugLib.h>\r
+#include <Library/MemoryAllocationLib.h>\r
+#include <Library/IoLib.h>\r
+#include <Library/PcdLib.h>\r
+#include <Library/ReportStatusCodeLib.h>\r
+#include <Library/UefiBootServicesTableLib.h>\r
+#include <Library/UefiDriverEntryPoint.h>\r
+#include <Library/UefiLib.h>\r
+\r
+//\r
+// Driver Binding Externs\r
+//\r
+extern EFI_DRIVER_BINDING_PROTOCOL gVirtualKeyboardDriverBinding;\r
+extern EFI_COMPONENT_NAME_PROTOCOL gVirtualKeyboardComponentName;\r
+extern EFI_COMPONENT_NAME2_PROTOCOL gVirtualKeyboardComponentName2;\r
+\r
+\r
+//\r
+// VIRTUAL Keyboard Defines\r
+//\r
+#define CHAR_SCANCODE 0xe0\r
+#define CHAR_ESC 0x1b\r
+\r
+#define KEYBOARD_TIMEOUT 65536 // 0.07s\r
+#define KEYBOARD_WAITFORVALUE_TIMEOUT 1000000 // 1s\r
+#define KEYBOARD_BAT_TIMEOUT 4000000 // 4s\r
+#define KEYBOARD_TIMER_INTERVAL 500000 // 0.5s\r
+\r
+#define QUEUE_MAX_COUNT 32\r
+\r
+#define KEYBOARD_SCAN_CODE_MAX_COUNT 32\r
+\r
+//\r
+// VIRTUAL Keyboard Device Structure\r
+//\r
+#define VIRTUAL_KEYBOARD_DEV_SIGNATURE SIGNATURE_32 ('V', 'K', 'B', 'D')\r
+#define VIRTUAL_KEYBOARD_CONSOLE_IN_EX_NOTIFY_SIGNATURE SIGNATURE_32 ('v', 'k', 'c', 'n')\r
+\r
+typedef struct _VIRTUAL_KEYBOARD_CONSOLE_IN_EX_NOTIFY {\r
+ UINTN Signature;\r
+ EFI_KEY_DATA KeyData;\r
+ EFI_KEY_NOTIFY_FUNCTION KeyNotificationFn;\r
+ LIST_ENTRY NotifyEntry;\r
+} VIRTUAL_KEYBOARD_CONSOLE_IN_EX_NOTIFY;\r
+\r
+typedef struct {\r
+ UINTN Front;\r
+ UINTN Rear;\r
+ EFI_KEY_DATA Buffer[QUEUE_MAX_COUNT];\r
+} SIMPLE_QUEUE;\r
+\r
+typedef struct {\r
+ UINT8 Buffer[KEYBOARD_SCAN_CODE_MAX_COUNT];\r
+ UINTN Head;\r
+ UINTN Tail;\r
+} SCAN_CODE_QUEUE;\r
+\r
+typedef struct {\r
+ UINTN Signature;\r
+ EFI_HANDLE Handle;\r
+ PLATFORM_VIRTUAL_KBD_PROTOCOL *PlatformVirtual;\r
+ EFI_SIMPLE_TEXT_INPUT_PROTOCOL SimpleTextIn;\r
+ EFI_SIMPLE_TEXT_INPUT_EX_PROTOCOL SimpleTextInputEx;\r
+\r
+ //\r
+ // Buffer storing EFI_KEY_DATA\r
+ //\r
+ SIMPLE_QUEUE Queue;\r
+ SIMPLE_QUEUE QueueForNotify;\r
+\r
+ //\r
+ // Notification Function List\r
+ //\r
+ LIST_ENTRY NotifyList;\r
+ EFI_EVENT KeyNotifyProcessEvent;\r
+ EFI_EVENT TimerEvent;\r
+} VIRTUAL_KEYBOARD_DEV;\r
+\r
+#define VIRTUAL_KEYBOARD_DEV_FROM_THIS(a) CR (a, VIRTUAL_KEYBOARD_DEV, SimpleTextIn, VIRTUAL_KEYBOARD_DEV_SIGNATURE)\r
+#define TEXT_INPUT_EX_VIRTUAL_KEYBOARD_DEV_FROM_THIS(a) \\r
+ CR (a, \\r
+ VIRTUAL_KEYBOARD_DEV, \\r
+ SimpleTextInputEx, \\r
+ VIRTUAL_KEYBOARD_DEV_SIGNATURE \\r
+ )\r
+\r
+//\r
+// Global Variables\r
+//\r
+extern EFI_DRIVER_BINDING_PROTOCOL gVirtualKeyboardDriverBinding;\r
+\r
+//\r
+// Driver Binding Protocol functions\r
+//\r
+\r
+/**\r
+ Check whether the driver supports this device.\r
+\r
+ @param This The Udriver binding protocol.\r
+ @param Controller The controller handle to check.\r
+ @param RemainingDevicePath The remaining device path.\r
+\r
+ @retval EFI_SUCCESS The driver supports this controller.\r
+ @retval other This device isn't supported.\r
+\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+VirtualKeyboardDriverBindingSupported (\r
+ IN EFI_DRIVER_BINDING_PROTOCOL *This,\r
+ IN EFI_HANDLE Controller,\r
+ IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath\r
+ );\r
+\r
+/**\r
+ Starts the device with this driver.\r
+\r
+ @param This The driver binding instance.\r
+ @param Controller Handle of device to bind driver to.\r
+ @param RemainingDevicePath Optional parameter use to pick a specific child\r
+ device to start.\r
+\r
+ @retval EFI_SUCCESS The controller is controlled by the driver.\r
+ @retval Other This controller cannot be started.\r
+\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+VirtualKeyboardDriverBindingStart (\r
+ IN EFI_DRIVER_BINDING_PROTOCOL *This,\r
+ IN EFI_HANDLE Controller,\r
+ IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath\r
+ );\r
+\r
+/**\r
+ Stop the device handled by this driver.\r
+\r
+ @param This The driver binding protocol.\r
+ @param Controller The controller to release.\r
+ @param NumberOfChildren The number of handles in ChildHandleBuffer.\r
+ @param ChildHandleBuffer The array of child handle.\r
+\r
+ @retval EFI_SUCCESS The device was stopped.\r
+ @retval EFI_DEVICE_ERROR The device could not be stopped due to a device error.\r
+ @retval Others Fail to uninstall protocols attached on the device.\r
+\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+VirtualKeyboardDriverBindingStop (\r
+ IN EFI_DRIVER_BINDING_PROTOCOL *This,\r
+ IN EFI_HANDLE Controller,\r
+ IN UINTN NumberOfChildren,\r
+ IN EFI_HANDLE *ChildHandleBuffer\r
+ );\r
+\r
+/**\r
+ Retrieves a Unicode string that is the user readable name of the driver.\r
+\r
+ This function retrieves the user readable name of a driver in the form of a\r
+ Unicode string. If the driver specified by This has a user readable name in\r
+ the language specified by Language, then a pointer to the driver name is\r
+ returned in DriverName, and EFI_SUCCESS is returned. If the driver specified\r
+ by This does not support the language specified by Language,\r
+ then EFI_UNSUPPORTED is returned.\r
+\r
+ @param This[in] A pointer to the EFI_COMPONENT_NAME2_PROTOCOL or\r
+ EFI_COMPONENT_NAME_PROTOCOL instance.\r
+\r
+ @param Language[in] A pointer to a Null-terminated ASCII string\r
+ array indicating the language. This is the\r
+ language of the driver name that the caller is\r
+ requesting, and it must match one of the\r
+ languages specified in SupportedLanguages. The\r
+ number of languages supported by a driver is up\r
+ to the driver writer. Language is specified\r
+ in RFC 4646 or ISO 639-2 language code format.\r
+\r
+ @param DriverName[out] A pointer to the Unicode string to return.\r
+ This Unicode string is the name of the\r
+ driver specified by This in the language\r
+ specified by Language.\r
+\r
+ @retval EFI_SUCCESS The Unicode string for the Driver specified by\r
+ This and the language specified by Language was\r
+ returned in DriverName.\r
+\r
+ @retval EFI_INVALID_PAVIRTUALETER Language is NULL.\r
+\r
+ @retval EFI_INVALID_PAVIRTUALETER DriverName is NULL.\r
+\r
+ @retval EFI_UNSUPPORTED The driver specified by This does not support\r
+ the language specified by Language.\r
+\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+VirtualKeyboardComponentNameGetDriverName (\r
+ IN EFI_COMPONENT_NAME_PROTOCOL *This,\r
+ IN CHAR8 *Language,\r
+ OUT CHAR16 **DriverName\r
+ );\r
+\r
+\r
+/**\r
+ Retrieves a Unicode string that is the user readable name of the controller\r
+ that is being managed by a driver.\r
+\r
+ This function retrieves the user readable name of the controller specified by\r
+ ControllerHandle and ChildHandle in the form of a Unicode string. If the\r
+ driver specified by This has a user readable name in the language specified by\r
+ Language, then a pointer to the controller name is returned in ControllerName,\r
+ and EFI_SUCCESS is returned. If the driver specified by This is not currently\r
+ managing the controller specified by ControllerHandle and ChildHandle,\r
+ then EFI_UNSUPPORTED is returned. If the driver specified by This does not\r
+ support the language specified by Language, then EFI_UNSUPPORTED is returned.\r
+\r
+ @param This[in] A pointer to the EFI_COMPONENT_NAME2_PROTOCOL or\r
+ EFI_COMPONENT_NAME_PROTOCOL instance.\r
+\r
+ @param ControllerHandle[in] The handle of a controller that the driver\r
+ specified by This is managing. This handle\r
+ specifies the controller whose name is to be\r
+ returned.\r
+\r
+ @param ChildHandle[in] The handle of the child controller to retrieve\r
+ the name of. This is an optional parameter that\r
+ may be NULL. It will be NULL for device\r
+ drivers. It will also be NULL for a bus drivers\r
+ that wish to retrieve the name of the bus\r
+ controller. It will not be NULL for a bus\r
+ driver that wishes to retrieve the name of a\r
+ child controller.\r
+\r
+ @param Language[in] A pointer to a Null-terminated ASCII string\r
+ array indicating the language. This is the\r
+ language of the driver name that the caller is\r
+ requesting, and it must match one of the\r
+ languages specified in SupportedLanguages. The\r
+ number of languages supported by a driver is up\r
+ to the driver writer. Language is specified in\r
+ RFC 4646 or ISO 639-2 language code format.\r
+\r
+ @param ControllerName[out] A pointer to the Unicode string to return.\r
+ This Unicode string is the name of the\r
+ controller specified by ControllerHandle and\r
+ ChildHandle in the language specified by\r
+ Language from the point of view of the driver\r
+ specified by This.\r
+\r
+ @retval EFI_SUCCESS The Unicode string for the user readable name in\r
+ the language specified by Language for the\r
+ driver specified by This was returned in\r
+ DriverName.\r
+\r
+ @retval EFI_INVALID_PAVIRTUALETER ControllerHandle is NULL.\r
+\r
+ @retval EFI_INVALID_PAVIRTUALETER ChildHandle is not NULL and it is not a valid\r
+ EFI_HANDLE.\r
+\r
+ @retval EFI_INVALID_PAVIRTUALETER Language is NULL.\r
+\r
+ @retval EFI_INVALID_PAVIRTUALETER ControllerName is NULL.\r
+\r
+ @retval EFI_UNSUPPORTED The driver specified by This is not currently\r
+ managing the controller specified by\r
+ ControllerHandle and ChildHandle.\r
+\r
+ @retval EFI_UNSUPPORTED The driver specified by This does not support\r
+ the language specified by Language.\r
+\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+VirtualKeyboardComponentNameGetControllerName (\r
+ IN EFI_COMPONENT_NAME_PROTOCOL *This,\r
+ IN EFI_HANDLE ControllerHandle,\r
+ IN EFI_HANDLE ChildHandle OPTIONAL,\r
+ IN CHAR8 *Language,\r
+ OUT CHAR16 **ControllerName\r
+ );\r
+\r
+\r
+//\r
+// Simple Text Input Protocol functions\r
+//\r
+/**\r
+ Reset the Keyboard and do BAT test for it, if (ExtendedVerification == TRUE) then do some extra keyboard validations.\r
+\r
+ @param This Pointer of simple text Protocol.\r
+ @param ExtendedVerification Whether perform the extra validation of keyboard. True: perform; FALSE: skip.\r
+\r
+ @retval EFI_SUCCESS The command byte is written successfully.\r
+ @retval EFI_DEVICE_ERROR Errors occurred during resetting keyboard.\r
+\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+VirtualKeyboardReset (\r
+ IN EFI_SIMPLE_TEXT_INPUT_PROTOCOL *This,\r
+ IN BOOLEAN ExtendedVerification\r
+ );\r
+\r
+/**\r
+ Reset the input device and optionaly run diagnostics\r
+\r
+ @param This Protocol instance pointer.\r
+ @param ExtendedVerification Driver may perform diagnostics on reset.\r
+\r
+ @retval EFI_SUCCESS The device was reset.\r
+ @retval EFI_DEVICE_ERROR The device is not functioning properly and could\r
+ not be reset.\r
+\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+VirtualKeyboardResetEx (\r
+ IN EFI_SIMPLE_TEXT_INPUT_EX_PROTOCOL *This,\r
+ IN BOOLEAN ExtendedVerification\r
+ );\r
+\r
+/**\r
+ Set certain state for the input device.\r
+\r
+ @param This Protocol instance pointer.\r
+ @param KeyToggleState A pointer to the EFI_KEY_TOGGLE_STATE to set the\r
+ state for the input device.\r
+\r
+ @retval EFI_SUCCESS The device state was set successfully.\r
+ @retval EFI_DEVICE_ERROR The device is not functioning correctly and could\r
+ not have the setting adjusted.\r
+ @retval EFI_UNSUPPORTED The device does not have the ability to set its state.\r
+ @retval EFI_INVALID_PAVIRTUALETER KeyToggleState is NULL.\r
+\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+VirtualKeyboardSetState (\r
+ IN EFI_SIMPLE_TEXT_INPUT_EX_PROTOCOL *This,\r
+ IN EFI_KEY_TOGGLE_STATE *KeyToggleState\r
+ );\r
+\r
+/**\r
+ Register a notification function for a particular keystroke for the input device.\r
+\r
+ @param This Protocol instance pointer.\r
+ @param KeyData A pointer to a buffer that is filled in with the keystroke\r
+ information data for the key that was pressed.\r
+ @param KeyNotificationFunction Points to the function to be called when the key\r
+ sequence is typed specified by KeyData.\r
+ @param NotifyHandle Points to the unique handle assigned to the registered notification.\r
+\r
+\r
+ @retval EFI_SUCCESS The notification function was registered successfully.\r
+ @retval EFI_OUT_OF_RESOURCES Unable to allocate resources for necesssary data structures.\r
+ @retval EFI_INVALID_PAVIRTUALETER KeyData or NotifyHandle is NULL.\r
+\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+VirtualKeyboardRegisterKeyNotify (\r
+ IN EFI_SIMPLE_TEXT_INPUT_EX_PROTOCOL *This,\r
+ IN EFI_KEY_DATA *KeyData,\r
+ IN EFI_KEY_NOTIFY_FUNCTION KeyNotificationFunction,\r
+ OUT VOID **NotifyHandle\r
+ );\r
+\r
+/**\r
+ Remove a registered notification function from a particular keystroke.\r
+\r
+ @param This Protocol instance pointer.\r
+ @param NotificationHandle The handle of the notification function being unregistered.\r
+\r
+ @retval EFI_SUCCESS The notification function was unregistered successfully.\r
+ @retval EFI_INVALID_PAVIRTUALETER The NotificationHandle is invalid.\r
+\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+VirtualKeyboardUnregisterKeyNotify (\r
+ IN EFI_SIMPLE_TEXT_INPUT_EX_PROTOCOL *This,\r
+ IN VOID *NotificationHandle\r
+ );\r
+\r
+//\r
+// Private worker functions\r
+//\r
+/**\r
+ Free keyboard notify list.\r
+\r
+ @param ListHead The list head\r
+\r
+ @retval EFI_SUCCESS Free the notify list successfully\r
+ @retval EFI_INVALID_PAVIRTUALETER ListHead is invalid.\r
+\r
+**/\r
+EFI_STATUS\r
+VirtualKeyboardFreeNotifyList (\r
+ IN OUT LIST_ENTRY *ListHead\r
+ );\r
+\r
+/**\r
+ Check if key is registered.\r
+\r
+ @param RegsiteredData A pointer to a buffer that is filled in with the keystroke\r
+ state data for the key that was registered.\r
+ @param InputData A pointer to a buffer that is filled in with the keystroke\r
+ state data for the key that was pressed.\r
+\r
+ @retval TRUE Key be pressed matches a registered key.\r
+ @retval FLASE Match failed.\r
+\r
+**/\r
+BOOLEAN\r
+IsKeyRegistered (\r
+ IN EFI_KEY_DATA *RegsiteredData,\r
+ IN EFI_KEY_DATA *InputData\r
+ );\r
+\r
+/**\r
+ Waiting on the keyboard event, if there's any key pressed by the user, signal the event\r
+\r
+ @param Event The event that be siganlled when any key has been stroked.\r
+ @param Context Pointer of the protocol EFI_SIMPLE_TEXT_INPUT_PROTOCOL.\r
+\r
+**/\r
+VOID\r
+EFIAPI\r
+VirtualKeyboardWaitForKey (\r
+ IN EFI_EVENT Event,\r
+ IN VOID *Context\r
+ );\r
+\r
+/**\r
+ Waiting on the keyboard event, if there's any key pressed by the user, signal the event\r
+\r
+ @param Event The event that be siganlled when any key has been stroked.\r
+ @param Context Pointer of the protocol EFI_SIMPLE_TEXT_INPUT_EX_PROTOCOL.\r
+\r
+**/\r
+VOID\r
+EFIAPI\r
+VirtualKeyboardWaitForKeyEx (\r
+ IN EFI_EVENT Event,\r
+ IN VOID *Context\r
+ );\r
+\r
+/**\r
+ Timer event handler: read a series of key stroke from 8042\r
+ and put them into memory key buffer.\r
+ It is registered as running under TPL_NOTIFY\r
+\r
+ @param Event The timer event\r
+ @param Context A VIRTUAL_KEYBOARD_DEV pointer\r
+\r
+**/\r
+VOID\r
+EFIAPI\r
+VirtualKeyboardTimerHandler (\r
+ IN EFI_EVENT Event,\r
+ IN VOID *Context\r
+ );\r
+\r
+/**\r
+ Process key notify.\r
+\r
+ @param Event Indicates the event that invoke this function.\r
+ @param Context Indicates the calling context.\r
+**/\r
+VOID\r
+EFIAPI\r
+KeyNotifyProcessHandler (\r
+ IN EFI_EVENT Event,\r
+ IN VOID *Context\r
+ );\r
+\r
+/**\r
+ Read out the scan code of the key that has just been stroked.\r
+\r
+ @param This Pointer of simple text Protocol.\r
+ @param Key Pointer for store the key that read out.\r
+\r
+ @retval EFI_SUCCESS The key is read out successfully.\r
+ @retval other The key reading failed.\r
+\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+VirtualKeyboardReadKeyStroke (\r
+ IN EFI_SIMPLE_TEXT_INPUT_PROTOCOL *This,\r
+ OUT EFI_INPUT_KEY *Key\r
+ );\r
+\r
+/**\r
+ Reads the next keystroke from the input device. The WaitForKey Event can\r
+ be used to test for existance of a keystroke via WaitForEvent () call.\r
+\r
+ @param This Protocol instance pointer.\r
+ @param KeyData A pointer to a buffer that is filled in with the keystroke\r
+ state data for the key that was pressed.\r
+\r
+ @retval EFI_SUCCESS The keystroke information was returned.\r
+ @retval EFI_NOT_READY There was no keystroke data availiable.\r
+ @retval EFI_DEVICE_ERROR The keystroke information was not returned due to\r
+ hardware errors.\r
+ @retval EFI_INVALID_PAVIRTUALETER KeyData is NULL.\r
+\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+VirtualKeyboardReadKeyStrokeEx (\r
+ IN EFI_SIMPLE_TEXT_INPUT_EX_PROTOCOL *This,\r
+ OUT EFI_KEY_DATA *KeyData\r
+ );\r
+\r
+#endif /* _VIRTUAL_KEYBOARD_H_ */\r
--- /dev/null
+## @file\r
+# Virtual Keyboard driver.\r
+#\r
+# Copyright (c) 2018, Linaro Ltd. All rights reserved.<BR>\r
+#\r
+# This program and the accompanying materials\r
+# are licensed and made available under the terms and conditions\r
+# of the BSD License which accompanies this distribution. The\r
+# full text of the license may be found at\r
+# http://opensource.org/licenses/bsd-license.php\r
+#\r
+# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
+# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
+#\r
+##\r
+\r
+[Defines]\r
+ INF_VERSION = 0x00010019\r
+ BASE_NAME = VirtualKeyboardDxe\r
+ FILE_GUID = 88079b18-b42b-44aa-a6f2-b83911075e89\r
+ MODULE_TYPE = UEFI_DRIVER\r
+ VERSION_STRING = 1.0\r
+ ENTRY_POINT = InitializeVirtualKeyboard\r
+\r
+#\r
+# The following information is for reference only and not required by the build tools.\r
+#\r
+# VALID_ARCHITECTURES = IA32 X64 IPF ARM AARCH64\r
+#\r
+# DRIVER_BINDING = gVirtualKeyboardDriverBinding\r
+# COMPONENT_NAME = gVirtualKeyboardComponentName\r
+#\r
+\r
+[Sources.common]\r
+ ComponentName.c\r
+ VirtualKeyboard.c\r
+\r
+[Packages]\r
+ EmbeddedPkg/EmbeddedPkg.dec\r
+ MdeModulePkg/MdeModulePkg.dec\r
+ MdePkg/MdePkg.dec\r
+\r
+[LibraryClasses]\r
+ BaseLib\r
+ BaseMemoryLib\r
+ DebugLib\r
+ IoLib\r
+ ReportStatusCodeLib\r
+ UefiBootServicesTableLib\r
+ UefiDriverEntryPoint\r
+ UefiLib\r
+\r
+[Protocols]\r
+ gEfiDriverBindingProtocolGuid\r
+ gEfiSimpleTextInProtocolGuid\r
+ gEfiSimpleTextInputExProtocolGuid\r
+ gPlatformVirtualKeyboardProtocolGuid\r
+\r
+[Depex]\r
+ TRUE\r
gAndroidFastbootPlatformProtocolGuid = { 0x524685a0, 0x89a0, 0x11e3, {0x9d, 0x4d, 0xbf, 0xa9, 0xf6, 0xa4, 0x03, 0x08}}\r
gUsbDeviceProtocolGuid = { 0x021bd2ca, 0x51d2, 0x11e3, {0x8e, 0x56, 0xb7, 0x54, 0x17, 0xc7, 0x0b, 0x44 }}\r
gPlatformGpioProtocolGuid = { 0x52ce9845, 0x5af4, 0x43e2, {0xba, 0xfd, 0x23, 0x08, 0x12, 0x54, 0x7a, 0xc2 }}\r
+ gPlatformVirtualKeyboardProtocolGuid = { 0x0e3606d2, 0x1dc3, 0x4e6f, { 0xbe, 0x65, 0x39, 0x49, 0x82, 0xa2, 0x65, 0x47 }}\r
gAndroidBootImgProtocolGuid = { 0x9859bb19, 0x407c, 0x4f8b, {0xbc, 0xe1, 0xf8, 0xda, 0x65, 0x65, 0xf4, 0xa5 }}\r
\r
[Ppis]\r
--- /dev/null
+/** @file\r
+\r
+ Copyright (c) 2018, Linaro. All rights reserved.\r
+\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
+ http://opensource.org/licenses/bsd-license.php\r
+\r
+ THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
+ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
+\r
+**/\r
+\r
+#ifndef __PLATFORM_VIRTUAL_KEYBOARD_H__\r
+#define __PLATFORM_VIRTUAL_KEYBOARD_H__\r
+\r
+//\r
+// Protocol interface structure\r
+//\r
+typedef struct _PLATFORM_VIRTUAL_KBD_PROTOCOL PLATFORM_VIRTUAL_KBD_PROTOCOL;\r
+\r
+typedef struct _VIRTUAL_KBD_KEY VIRTUAL_KBD_KEY;\r
+\r
+#define VIRTUAL_KEYBOARD_KEY_SIGNATURE SIGNATURE_32 ('v', 'k', 'b', 'd')\r
+\r
+struct _VIRTUAL_KBD_KEY {\r
+ UINTN Signature;\r
+ EFI_INPUT_KEY Key;\r
+};\r
+\r
+typedef\r
+EFI_STATUS\r
+(EFIAPI *PLATFORM_VIRTUAL_KBD_REGISTER) (\r
+ IN VOID\r
+ );\r
+\r
+typedef\r
+EFI_STATUS\r
+(EFIAPI *PLATFORM_VIRTUAL_KBD_RESET) (\r
+ IN VOID\r
+ );\r
+\r
+typedef\r
+BOOLEAN\r
+(EFIAPI *PLATFORM_VIRTUAL_KBD_QUERY) (\r
+ IN VIRTUAL_KBD_KEY *VirtualKey\r
+ );\r
+\r
+typedef\r
+EFI_STATUS\r
+(EFIAPI *PLATFORM_VIRTUAL_KBD_CLEAR) (\r
+ IN VIRTUAL_KBD_KEY *VirtualKey\r
+ );\r
+\r
+struct _PLATFORM_VIRTUAL_KBD_PROTOCOL {\r
+ PLATFORM_VIRTUAL_KBD_REGISTER Register;\r
+ PLATFORM_VIRTUAL_KBD_RESET Reset;\r
+ PLATFORM_VIRTUAL_KBD_QUERY Query;\r
+ PLATFORM_VIRTUAL_KBD_CLEAR Clear;\r
+};\r
+\r
+extern EFI_GUID gPlatformVirtualKeyboardProtocolGuid;\r
+\r
+#endif /* __PLATFORM_VIRTUAL_KEYBOARD_H__ */\r