From: Leif Lindholm <leif.lindholm@linaro.org>
To: Haojian Zhuang <haojian.zhuang@linaro.org>
Cc: ard.biesheuvel@linaro.org, linaro-uefi@lists.linaro.org,
edk2-devel@lists.01.org
Subject: Re: [PATCH] EmbeddedPkg/Drivers: add virtual keyboard driver
Date: Tue, 27 Feb 2018 12:28:47 +0000 [thread overview]
Message-ID: <20180227122847.fr2zq6nurtrlstqh@bivouac.eciton.net> (raw)
In-Reply-To: <1519635156-21954-1-git-send-email-haojian.zhuang@linaro.org>
On Mon, Feb 26, 2018 at 04:52:36PM +0800, Haojian Zhuang wrote:
> The virtual keyboard could simulate a keyboard. User could simulate
> a key value when pattern is matched.
How? This is over 2000 lines of new code, please give a little bit
more description of what it does and how it is intended to be used.
(It sounds like is could be a useful feature, but I can only find out
what it is intended to do by reading the code, which isn't what review
is supposed to be.)
> Contributed-under: TianoCore Contribution Agreement 1.1
> Signed-off-by: Haojian Zhuang <haojian.zhuang@linaro.org>
> ---
> .../Drivers/VirtualKeyboardDxe/ComponentName.c | 184 ++++
> .../Drivers/VirtualKeyboardDxe/ComponentName.h | 154 +++
> .../Drivers/VirtualKeyboardDxe/VirtualKeyboard.c | 1117 ++++++++++++++++++++
> .../Drivers/VirtualKeyboardDxe/VirtualKeyboard.h | 544 ++++++++++
> .../VirtualKeyboardDxe/VirtualKeyboardDxe.dec | 39 +
> .../VirtualKeyboardDxe/VirtualKeyboardDxe.inf | 61 ++
> .../Include/Protocol/PlatformVirtualKeyboard.h | 65 ++
Please generate patches with
--stat=1000 --stat-graph-width=20
and
--subject-prefix="PATCH edk2-platforms"
(In general following the guide at)
https://github.com/tianocore/tianocore.github.io/wiki/Laszlo's-unkempt-git-guide-for-edk2-contributors-and-maintainers
> 7 files changed, 2164 insertions(+)
> create mode 100644 EmbeddedPkg/Drivers/VirtualKeyboardDxe/ComponentName.c
> create mode 100644 EmbeddedPkg/Drivers/VirtualKeyboardDxe/ComponentName.h
> create mode 100644 EmbeddedPkg/Drivers/VirtualKeyboardDxe/VirtualKeyboard.c
> create mode 100644 EmbeddedPkg/Drivers/VirtualKeyboardDxe/VirtualKeyboard.h
> create mode 100644 EmbeddedPkg/Drivers/VirtualKeyboardDxe/VirtualKeyboardDxe.dec
> create mode 100644 EmbeddedPkg/Drivers/VirtualKeyboardDxe/VirtualKeyboardDxe.inf
> create mode 100644 EmbeddedPkg/Include/Protocol/PlatformVirtualKeyboard.h
>
> diff --git a/EmbeddedPkg/Drivers/VirtualKeyboardDxe/ComponentName.c b/EmbeddedPkg/Drivers/VirtualKeyboardDxe/ComponentName.c
> new file mode 100644
> index 0000000..2935307
> --- /dev/null
> +++ b/EmbeddedPkg/Drivers/VirtualKeyboardDxe/ComponentName.c
> @@ -0,0 +1,184 @@
> +/** @file
> +
> +Copyright (c) 2006 - 2011, Intel Corporation. All rights reserved.<BR>
> +Copyright (c) 2018, Linaro Ltd. 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.
> +
> +**/
> +
> +#include "VirtualKeyboard.h"
> +
> +//
> +// EFI Component Name Protocol
> +//
> +GLOBAL_REMOVE_IF_UNREFERENCED EFI_COMPONENT_NAME_PROTOCOL gVirtualKeyboardComponentName = {
> + VirtualKeyboardComponentNameGetDriverName,
> + VirtualKeyboardComponentNameGetControllerName,
> + "eng"
> +};
> +
> +//
> +// EFI Component Name 2 Protocol
> +//
> +GLOBAL_REMOVE_IF_UNREFERENCED EFI_COMPONENT_NAME2_PROTOCOL gVirtualKeyboardComponentName2 = {
> + (EFI_COMPONENT_NAME2_GET_DRIVER_NAME) VirtualKeyboardComponentNameGetDriverName,
> + (EFI_COMPONENT_NAME2_GET_CONTROLLER_NAME) VirtualKeyboardComponentNameGetControllerName,
> + "en"
> +};
> +
> +
> +GLOBAL_REMOVE_IF_UNREFERENCED EFI_UNICODE_STRING_TABLE mVirtualKeyboardDriverNameTable[] = {
> + {
> + "eng;en",
> + L"RAM Keyboard Driver"
What is a RAM Keyboard Driver?
> + },
Any chance of a "zh-chs" entry?
> + {
> + NULL,
> + NULL
> + }
> +};
> +
> +/**
> + Retrieves a Unicode string that is the user readable name of the driver.
> +
> + This function retrieves the user readable name of a driver in the form of a
> + Unicode string. If the driver specified by This has a user readable name in
> + the language specified by Language, then a pointer to the driver name is
> + returned in DriverName, and EFI_SUCCESS is returned. If the driver specified
> + by This does not support the language specified by Language,
> + then EFI_UNSUPPORTED is returned.
> +
> + @param This[in] A pointer to the EFI_COMPONENT_NAME2_PROTOCOL or
> + EFI_COMPONENT_NAME_PROTOCOL instance.
> +
> + @param Language[in] A pointer to a Null-terminated ASCII string
> + array indicating the language. This is the
> + language of the driver name that the caller is
> + requesting, and it must match one of the
> + languages specified in SupportedLanguages. The
> + number of languages supported by a driver is up
> + to the driver writer. Language is specified
> + in RFC 4646 or ISO 639-2 language code format.
> +
> + @param DriverName[out] A pointer to the Unicode string to return.
> + This Unicode string is the name of the
> + driver specified by This in the language
> + specified by Language.
> +
> + @retval EFI_SUCCESS The Unicode string for the Driver specified by
> + This and the language specified by Language was
> + returned in DriverName.
> +
> + @retval EFI_INVALID_PARAMETER Language is NULL.
> +
> + @retval EFI_INVALID_PARAMETER DriverName is NULL.
> +
> + @retval EFI_UNSUPPORTED The driver specified by This does not support
> + the language specified by Language.
> +
> +**/
> +EFI_STATUS
> +EFIAPI
> +VirtualKeyboardComponentNameGetDriverName (
> + IN EFI_COMPONENT_NAME_PROTOCOL *This,
> + IN CHAR8 *Language,
> + OUT CHAR16 **DriverName
> + )
> +{
> + return LookupUnicodeString2 (
> + Language,
> + This->SupportedLanguages,
> + mVirtualKeyboardDriverNameTable,
> + DriverName,
> + (BOOLEAN)(This == &gVirtualKeyboardComponentName)
> + );
> +}
> +
> +/**
> + Retrieves a Unicode string that is the user readable name of the controller
> + that is being managed by a driver.
> +
> + This function retrieves the user readable name of the controller specified by
> + ControllerHandle and ChildHandle in the form of a Unicode string. If the
> + driver specified by This has a user readable name in the language specified by
> + Language, then a pointer to the controller name is returned in ControllerName,
> + and EFI_SUCCESS is returned. If the driver specified by This is not currently
> + managing the controller specified by ControllerHandle and ChildHandle,
> + then EFI_UNSUPPORTED is returned. If the driver specified by This does not
> + support the language specified by Language, then EFI_UNSUPPORTED is returned.
> +
> + @param This[in] A pointer to the EFI_COMPONENT_NAME2_PROTOCOL or
> + EFI_COMPONENT_NAME_PROTOCOL instance.
> +
> + @param ControllerHandle[in] The handle of a controller that the driver
> + specified by This is managing. This handle
> + specifies the controller whose name is to be
> + returned.
> +
> + @param ChildHandle[in] The handle of the child controller to retrieve
> + the name of. This is an optional parameter that
> + may be NULL. It will be NULL for device
> + drivers. It will also be NULL for a bus drivers
> + that wish to retrieve the name of the bus
> + controller. It will not be NULL for a bus
> + driver that wishes to retrieve the name of a
> + child controller.
> +
> + @param Language[in] A pointer to a Null-terminated ASCII string
> + array indicating the language. This is the
> + language of the driver name that the caller is
> + requesting, and it must match one of the
> + languages specified in SupportedLanguages. The
> + number of languages supported by a driver is up
> + to the driver writer. Language is specified in
> + RFC 4646 or ISO 639-2 language code format.
> +
> + @param ControllerName[out] A pointer to the Unicode string to return.
> + This Unicode string is the name of the
> + controller specified by ControllerHandle and
> + ChildHandle in the language specified by
> + Language from the point of view of the driver
> + specified by This.
> +
> + @retval EFI_SUCCESS The Unicode string for the user readable name in
> + the language specified by Language for the
> + driver specified by This was returned in
> + DriverName.
> +
> + @retval EFI_INVALID_PARAMETER ControllerHandle is NULL.
> +
> + @retval EFI_INVALID_PARAMETER ChildHandle is not NULL and it is not a valid
> + EFI_HANDLE.
> +
> + @retval EFI_INVALID_PARAMETER Language is NULL.
> +
> + @retval EFI_INVALID_PARAMETER ControllerName is NULL.
> +
> + @retval EFI_UNSUPPORTED The driver specified by This is not currently
> + managing the controller specified by
> + ControllerHandle and ChildHandle.
> +
> + @retval EFI_UNSUPPORTED The driver specified by This does not support
> + the language specified by Language.
> +
> +**/
> +EFI_STATUS
> +EFIAPI
> +VirtualKeyboardComponentNameGetControllerName (
> + IN EFI_COMPONENT_NAME_PROTOCOL *This,
> + IN EFI_HANDLE ControllerHandle,
> + IN EFI_HANDLE ChildHandle OPTIONAL,
> + IN CHAR8 *Language,
> + OUT CHAR16 **ControllerName
> + )
> +{
> + return EFI_UNSUPPORTED;
> +}
> diff --git a/EmbeddedPkg/Drivers/VirtualKeyboardDxe/ComponentName.h b/EmbeddedPkg/Drivers/VirtualKeyboardDxe/ComponentName.h
> new file mode 100644
> index 0000000..94bef28
> --- /dev/null
> +++ b/EmbeddedPkg/Drivers/VirtualKeyboardDxe/ComponentName.h
> @@ -0,0 +1,154 @@
> +/** @file
> +
> +Copyright (c) 2006 - 2011, Intel Corporation. All rights reserved.<BR>
> +Copyright (c) 2018, Linaro Ltd. 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.
> +
> +**/
> +
> +#ifndef _VIRTUAL_KEYBOARD_COMPONENT_NAME_H_
> +#define _VIRTUAL_KEYBOARD_COMPONENT_NAME_H_
> +
> +
> +extern EFI_COMPONENT_NAME_PROTOCOL gVirtualKeyboardComponentName;
> +extern EFI_COMPONENT_NAME2_PROTOCOL gVirtualKeyboardComponentName2;
> +
> +//
> +// EFI Component Name Functions
> +//
> +/**
> + Retrieves a Unicode string that is the user readable name of the driver.
> +
> + This function retrieves the user readable name of a driver in the form of a
> + Unicode string. If the driver specified by This has a user readable name in
> + the language specified by Language, then a pointer to the driver name is
> + returned in DriverName, and EFI_SUCCESS is returned. If the driver specified
> + by This does not support the language specified by Language,
> + then EFI_UNSUPPORTED is returned.
> +
> + @param This[in] A pointer to the EFI_COMPONENT_NAME2_PROTOCOL or
> + EFI_COMPONENT_NAME_PROTOCOL instance.
> +
> + @param Language[in] A pointer to a Null-terminated ASCII string
> + array indicating the language. This is the
> + language of the driver name that the caller is
> + requesting, and it must match one of the
> + languages specified in SupportedLanguages. The
> + number of languages supported by a driver is up
> + to the driver writer. Language is specified
> + in RFC 4646 or ISO 639-2 language code format.
> +
> + @param DriverName[out] A pointer to the Unicode string to return.
> + This Unicode string is the name of the
> + driver specified by This in the language
> + specified by Language.
> +
> + @retval EFI_SUCCESS The Unicode string for the Driver specified by
> + This and the language specified by Language was
> + returned in DriverName.
> +
> + @retval EFI_INVALID_PARAMETER Language is NULL.
> +
> + @retval EFI_INVALID_PARAMETER DriverName is NULL.
> +
> + @retval EFI_UNSUPPORTED The driver specified by This does not support
> + the language specified by Language.
> +
> +**/
> +EFI_STATUS
> +EFIAPI
> +VirtualKeyboardComponentNameGetDriverName (
> + IN EFI_COMPONENT_NAME_PROTOCOL *This,
> + IN CHAR8 *Language,
> + OUT CHAR16 **DriverName
> + );
> +
> +
> +/**
> + Retrieves a Unicode string that is the user readable name of the controller
> + that is being managed by a driver.
> +
> + This function retrieves the user readable name of the controller specified by
> + ControllerHandle and ChildHandle in the form of a Unicode string. If the
> + driver specified by This has a user readable name in the language specified by
> + Language, then a pointer to the controller name is returned in ControllerName,
> + and EFI_SUCCESS is returned. If the driver specified by This is not currently
> + managing the controller specified by ControllerHandle and ChildHandle,
> + then EFI_UNSUPPORTED is returned. If the driver specified by This does not
> + support the language specified by Language, then EFI_UNSUPPORTED is returned.
> +
> + @param This[in] A pointer to the EFI_COMPONENT_NAME2_PROTOCOL or
> + EFI_COMPONENT_NAME_PROTOCOL instance.
> +
> + @param ControllerHandle[in] The handle of a controller that the driver
> + specified by This is managing. This handle
> + specifies the controller whose name is to be
> + returned.
> +
> + @param ChildHandle[in] The handle of the child controller to retrieve
> + the name of. This is an optional parameter that
> + may be NULL. It will be NULL for device
> + drivers. It will also be NULL for a bus drivers
> + that wish to retrieve the name of the bus
> + controller. It will not be NULL for a bus
> + driver that wishes to retrieve the name of a
> + child controller.
> +
> + @param Language[in] A pointer to a Null-terminated ASCII string
> + array indicating the language. This is the
> + language of the driver name that the caller is
> + requesting, and it must match one of the
> + languages specified in SupportedLanguages. The
> + number of languages supported by a driver is up
> + to the driver writer. Language is specified in
> + RFC 4646 or ISO 639-2 language code format.
> +
> + @param ControllerName[out] A pointer to the Unicode string to return.
> + This Unicode string is the name of the
> + controller specified by ControllerHandle and
> + ChildHandle in the language specified by
> + Language from the point of view of the driver
> + specified by This.
> +
> + @retval EFI_SUCCESS The Unicode string for the user readable name in
> + the language specified by Language for the
> + driver specified by This was returned in
> + DriverName.
> +
> + @retval EFI_INVALID_PARAMETER ControllerHandle is NULL.
> +
> + @retval EFI_INVALID_PARAMETER ChildHandle is not NULL and it is not a valid
> + EFI_HANDLE.
> +
> + @retval EFI_INVALID_PARAMETER Language is NULL.
> +
> + @retval EFI_INVALID_PARAMETER ControllerName is NULL.
> +
> + @retval EFI_UNSUPPORTED The driver specified by This is not currently
> + managing the controller specified by
> + ControllerHandle and ChildHandle.
> +
> + @retval EFI_UNSUPPORTED The driver specified by This does not support
> + the language specified by Language.
> +
> +**/
> +EFI_STATUS
> +EFIAPI
> +VirtualKeyboardComponentNameGetControllerName (
> + IN EFI_COMPONENT_NAME_PROTOCOL *This,
> + IN EFI_HANDLE ControllerHandle,
> + IN EFI_HANDLE ChildHandle OPTIONAL,
> + IN CHAR8 *Language,
> + OUT CHAR16 **ControllerName
> + );
> +
> +
> +#endif
> diff --git a/EmbeddedPkg/Drivers/VirtualKeyboardDxe/VirtualKeyboard.c b/EmbeddedPkg/Drivers/VirtualKeyboardDxe/VirtualKeyboard.c
> new file mode 100644
> index 0000000..b2c84ba
> --- /dev/null
> +++ b/EmbeddedPkg/Drivers/VirtualKeyboardDxe/VirtualKeyboard.c
> @@ -0,0 +1,1117 @@
> +/** @file
> + VirtualKeyboard driver
> +
> +Copyright (c) 2006 - 2016, Intel Corporation. All rights reserved.<BR>
> +Copyright (c) 2018, Linaro Ltd. 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.
> +
> +**/
> +
> +#include "VirtualKeyboard.h"
> +
> +//
> +// RAM Keyboard Driver Binding Protocol Instance
> +//
> +EFI_DRIVER_BINDING_PROTOCOL gVirtualKeyboardDriverBinding = {
> + VirtualKeyboardDriverBindingSupported,
> + VirtualKeyboardDriverBindingStart,
> + VirtualKeyboardDriverBindingStop,
> + 0x10,
> + NULL,
> + NULL
> +};
> +
> +//
> +// EFI Driver Binding Protocol Functions
> +//
> +
> +/**
> + Check whether the driver supports this device.
> +
> + @param This The Udriver binding protocol.
> + @param Controller The controller handle to check.
> + @param RemainingDevicePath The remaining device path.
> +
> + @retval EFI_SUCCESS The driver supports this controller.
> + @retval other This device isn't supported.
> +
> +**/
> +EFI_STATUS
> +EFIAPI
> +VirtualKeyboardDriverBindingSupported (
> + IN EFI_DRIVER_BINDING_PROTOCOL *This,
> + IN EFI_HANDLE Controller,
> + IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath
> + )
> +{
> + EFI_STATUS Status;
> + PLATFORM_VIRTUAL_KBD_PROTOCOL *PlatformVirtual;
> +
> + Status = gBS->OpenProtocol (
> + Controller,
> + &gPlatformVirtualKeyboardProtocolGuid,
> + (VOID **) &PlatformVirtual,
> + This->DriverBindingHandle,
> + Controller,
> + EFI_OPEN_PROTOCOL_BY_DRIVER
> + );
> + if (EFI_ERROR (Status)) {
> + return Status;
> + }
> + gBS->CloseProtocol (
> + Controller,
> + &gPlatformVirtualKeyboardProtocolGuid,
> + This->DriverBindingHandle,
> + Controller
> + );
> + return Status;
> +}
> +
> +/**
> + Starts the device with this driver.
> +
> + @param This The driver binding instance.
> + @param Controller Handle of device to bind driver to.
> + @param RemainingDevicePath Optional parameter use to pick a specific child
> + device to start.
> +
> + @retval EFI_SUCCESS The controller is controlled by the driver.
> + @retval Other This controller cannot be started.
> +
> +**/
> +EFI_STATUS
> +EFIAPI
> +VirtualKeyboardDriverBindingStart (
> + IN EFI_DRIVER_BINDING_PROTOCOL *This,
> + IN EFI_HANDLE Controller,
> + IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath
> + )
> +{
> + EFI_STATUS Status;
> + VIRTUAL_KEYBOARD_DEV *VirtualKeyboardPrivate;
> + PLATFORM_VIRTUAL_KBD_PROTOCOL *PlatformVirtual;
> +
> + Status = gBS->OpenProtocol (
> + Controller,
> + &gPlatformVirtualKeyboardProtocolGuid,
> + (VOID **) &PlatformVirtual,
> + This->DriverBindingHandle,
> + Controller,
> + EFI_OPEN_PROTOCOL_BY_DRIVER
> + );
> + if (EFI_ERROR (Status)) {
> + return Status;
> + }
> +
> + //
> + // Allocate the private device structure
> + //
> + VirtualKeyboardPrivate = (VIRTUAL_KEYBOARD_DEV *) AllocateZeroPool (sizeof (VIRTUAL_KEYBOARD_DEV));
> + if (NULL == VirtualKeyboardPrivate) {
No jeopardy-comparisons please. if (VirtualKeyboardPrivate == NULL) {
> + Status = EFI_OUT_OF_RESOURCES;
> + goto Done;
> + }
> +
> + //
> + // Initialize the private device structure
> + //
> + VirtualKeyboardPrivate->Signature = VIRTUAL_KEYBOARD_DEV_SIGNATURE;
> + VirtualKeyboardPrivate->Handle = Controller;
> + VirtualKeyboardPrivate->PlatformVirtual = PlatformVirtual;
> + VirtualKeyboardPrivate->Queue.Front = 0;
> + VirtualKeyboardPrivate->Queue.Rear = 0;
> + VirtualKeyboardPrivate->QueueForNotify.Front = 0;
> + VirtualKeyboardPrivate->QueueForNotify.Rear = 0;
> +
> + VirtualKeyboardPrivate->SimpleTextIn.Reset = VirtualKeyboardReset;
> + VirtualKeyboardPrivate->SimpleTextIn.ReadKeyStroke = VirtualKeyboardReadKeyStroke;
> +
> + VirtualKeyboardPrivate->SimpleTextInputEx.Reset = VirtualKeyboardResetEx;
> + VirtualKeyboardPrivate->SimpleTextInputEx.ReadKeyStrokeEx = VirtualKeyboardReadKeyStrokeEx;
> + VirtualKeyboardPrivate->SimpleTextInputEx.SetState = VirtualKeyboardSetState;
> +
> + VirtualKeyboardPrivate->SimpleTextInputEx.RegisterKeyNotify = VirtualKeyboardRegisterKeyNotify;
> + VirtualKeyboardPrivate->SimpleTextInputEx.UnregisterKeyNotify = VirtualKeyboardUnregisterKeyNotify;
> + InitializeListHead (&VirtualKeyboardPrivate->NotifyList);
> +
> + Status = PlatformVirtual->Register ();
> + if (EFI_ERROR (Status)) {
> + goto Done;
> + }
> +
> + //
> + // Report that the keyboard is being enabled
> + //
> + REPORT_STATUS_CODE (
> + EFI_PROGRESS_CODE,
> + EFI_PERIPHERAL_KEYBOARD | EFI_P_PC_ENABLE
> + );
> +
> + //
> + // Setup the WaitForKey event
> + //
> + Status = gBS->CreateEvent (
> + EVT_NOTIFY_WAIT,
> + TPL_NOTIFY,
> + VirtualKeyboardWaitForKey,
> + &(VirtualKeyboardPrivate->SimpleTextIn),
> + &((VirtualKeyboardPrivate->SimpleTextIn).WaitForKey)
> + );
> + if (EFI_ERROR (Status)) {
> + (VirtualKeyboardPrivate->SimpleTextIn).WaitForKey = NULL;
> + goto Done;
> + }
> + Status = gBS->CreateEvent (
> + EVT_NOTIFY_WAIT,
> + TPL_NOTIFY,
> + VirtualKeyboardWaitForKeyEx,
> + &(VirtualKeyboardPrivate->SimpleTextInputEx),
> + &(VirtualKeyboardPrivate->SimpleTextInputEx.WaitForKeyEx)
> + );
> + if (EFI_ERROR (Status)) {
> + VirtualKeyboardPrivate->SimpleTextInputEx.WaitForKeyEx = NULL;
> + goto Done;
> + }
> +
> + //
> + // Setup a periodic timer, used for reading keystrokes at a fixed interval
> + //
> + Status = gBS->CreateEvent (
> + EVT_TIMER | EVT_NOTIFY_SIGNAL,
> + TPL_NOTIFY,
> + VirtualKeyboardTimerHandler,
> + VirtualKeyboardPrivate,
> + &VirtualKeyboardPrivate->TimerEvent
> + );
> + if (EFI_ERROR (Status)) {
> + Status = EFI_OUT_OF_RESOURCES;
The whitespace before = does not look quite right.
Please address throughout.
> + goto Done;
> + }
> +
> + Status = gBS->SetTimer (
> + VirtualKeyboardPrivate->TimerEvent,
> + TimerPeriodic,
> + KEYBOARD_TIMER_INTERVAL
> + );
> + if (EFI_ERROR (Status)) {
> + Status = EFI_OUT_OF_RESOURCES;
> + goto Done;
> + }
> +
> + Status = gBS->CreateEvent (
> + EVT_NOTIFY_SIGNAL,
> + TPL_CALLBACK,
> + KeyNotifyProcessHandler,
> + VirtualKeyboardPrivate,
> + &VirtualKeyboardPrivate->KeyNotifyProcessEvent
> + );
> + if (EFI_ERROR (Status)) {
> + Status = EFI_OUT_OF_RESOURCES;
> + goto Done;
> + }
> +
> + //
> + // Reset the keyboard device
> + //
> + Status = VirtualKeyboardPrivate->SimpleTextInputEx.Reset (
> + &VirtualKeyboardPrivate->SimpleTextInputEx,
Funky indentation.
According to coding style, it's missing 3 spaces.
> + FALSE
> + );
> + if (EFI_ERROR (Status)) {
> + DEBUG ((EFI_D_ERROR, "[KBD]Reset Failed. Status - %r\n", Status));
Use DEBUG_ERROR (PatchCheck.py warns about this).
> + goto Done;
> + }
> + //
> + // Install protocol interfaces for the keyboard device.
> + //
> + Status = gBS->InstallMultipleProtocolInterfaces (
> + &Controller,
> + &gEfiSimpleTextInProtocolGuid,
> + &VirtualKeyboardPrivate->SimpleTextIn,
> + &gEfiSimpleTextInputExProtocolGuid,
> + &VirtualKeyboardPrivate->SimpleTextInputEx,
> + NULL
> + );
> +
> +Done:
> + if (EFI_ERROR (Status)) {
> + if (VirtualKeyboardPrivate != NULL) {
> + if ((VirtualKeyboardPrivate->SimpleTextIn).WaitForKey != NULL) {
> + gBS->CloseEvent ((VirtualKeyboardPrivate->SimpleTextIn).WaitForKey);
> + }
> +
> + if ((VirtualKeyboardPrivate->SimpleTextInputEx).WaitForKeyEx != NULL) {
> + gBS->CloseEvent ((VirtualKeyboardPrivate->SimpleTextInputEx).WaitForKeyEx);
> + }
> +
> + if (VirtualKeyboardPrivate->KeyNotifyProcessEvent != NULL) {
> + gBS->CloseEvent (VirtualKeyboardPrivate->KeyNotifyProcessEvent);
> + }
> +
> + VirtualKeyboardFreeNotifyList (&VirtualKeyboardPrivate->NotifyList);
> +
> + if (VirtualKeyboardPrivate->TimerEvent != NULL) {
> + gBS->CloseEvent (VirtualKeyboardPrivate->TimerEvent);
> + }
> + FreePool (VirtualKeyboardPrivate);
> + }
> + }
> +
> + gBS->CloseProtocol (
> + Controller,
> + &gPlatformVirtualKeyboardProtocolGuid,
> + This->DriverBindingHandle,
> + Controller
> + );
> +
> + return Status;
> +}
> +
> +/**
> + Stop the device handled by this driver.
> +
> + @param This The driver binding protocol.
> + @param Controller The controller to release.
> + @param NumberOfChildren The number of handles in ChildHandleBuffer.
> + @param ChildHandleBuffer The array of child handle.
> +
> + @retval EFI_SUCCESS The device was stopped.
> + @retval EFI_DEVICE_ERROR The device could not be stopped due to a device error.
> + @retval Others Fail to uninstall protocols attached on the device.
> +
> +**/
> +EFI_STATUS
> +EFIAPI
> +VirtualKeyboardDriverBindingStop (
> + IN EFI_DRIVER_BINDING_PROTOCOL *This,
> + IN EFI_HANDLE Controller,
> + IN UINTN NumberOfChildren,
> + IN EFI_HANDLE *ChildHandleBuffer
> + )
> +{
> + return EFI_SUCCESS;
> +}
> +
> +
> +/**
> + Enqueue the key.
> +
> + @param Queue The queue to be enqueued.
> + @param KeyData The key data to be enqueued.
> +
> + @retval EFI_NOT_READY The queue is full.
> + @retval EFI_SUCCESS Successfully enqueued the key data.
> +
> +**/
> +EFI_STATUS
> +Enqueue (
> + IN SIMPLE_QUEUE *Queue,
> + IN EFI_KEY_DATA *KeyData
> + )
> +{
> + if ((Queue->Rear + 1) % QUEUE_MAX_COUNT == Queue->Front) {
> + return EFI_NOT_READY;
> + }
> +
> + CopyMem (&Queue->Buffer[Queue->Rear], KeyData, sizeof (EFI_KEY_DATA));
> + Queue->Rear = (Queue->Rear + 1) % QUEUE_MAX_COUNT;
> +
> + return EFI_SUCCESS;
> +}
> +
> +/**
> + Dequeue the key.
> +
> + @param Queue The queue to be dequeued.
> + @param KeyData The key data to be dequeued.
> +
> + @retval EFI_NOT_READY The queue is empty.
> + @retval EFI_SUCCESS Successfully dequeued the key data.
> +
> +**/
> +EFI_STATUS
> +Dequeue (
> + IN SIMPLE_QUEUE *Queue,
> + IN EFI_KEY_DATA *KeyData
> + )
> +{
> + if (Queue->Front == Queue->Rear) {
> + return EFI_NOT_READY;
> + }
> +
> + CopyMem (KeyData, &Queue->Buffer[Queue->Front], sizeof (EFI_KEY_DATA));
> + Queue->Front = (Queue->Front + 1) % QUEUE_MAX_COUNT;
> +
> + return EFI_SUCCESS;
> +}
> +
> +/**
> + Check whether the queue is empty.
> +
> + @param Queue The queue to be checked.
> +
> + @retval EFI_NOT_READY The queue is empty.
> + @retval EFI_SUCCESS The queue is not empty.
> +
> +**/
> +EFI_STATUS
> +CheckQueue (
> + IN SIMPLE_QUEUE *Queue
> + )
> +{
> + if (Queue->Front == Queue->Rear) {
> + return EFI_NOT_READY;
> + }
> +
> + return EFI_SUCCESS;
> +}
> +
> +/**
> + Check key buffer to get the key stroke status.
> +
> + @param This Pointer of the protocol EFI_SIMPLE_TEXT_IN_PROTOCOL.
> +
> + @retval EFI_SUCCESS A key is being pressed now.
> + @retval Other No key is now pressed.
> +
> +**/
> +EFI_STATUS
> +EFIAPI
> +VirtualKeyboardCheckForKey (
> + IN EFI_SIMPLE_TEXT_INPUT_PROTOCOL *This
> + )
> +{
> + VIRTUAL_KEYBOARD_DEV *VirtualKeyboardPrivate;
> +
> + VirtualKeyboardPrivate = VIRTUAL_KEYBOARD_DEV_FROM_THIS (This);
> +
> + return CheckQueue (&VirtualKeyboardPrivate->Queue);
> +}
> +
> +/**
> + Free keyboard notify list.
> +
> + @param ListHead The list head
> +
> + @retval EFI_SUCCESS Free the notify list successfully
> + @retval EFI_INVALID_PARAMETER ListHead is invalid.
> +
> +**/
> +EFI_STATUS
> +VirtualKeyboardFreeNotifyList (
> + IN OUT LIST_ENTRY *ListHead
> + )
> +{
> + VIRTUAL_KEYBOARD_CONSOLE_IN_EX_NOTIFY *NotifyNode;
> +
> + if (ListHead == NULL) {
> + return EFI_INVALID_PARAMETER;
> + }
> + while (!IsListEmpty (ListHead)) {
> + NotifyNode = CR (
> + ListHead->ForwardLink,
> + VIRTUAL_KEYBOARD_CONSOLE_IN_EX_NOTIFY,
> + NotifyEntry,
> + VIRTUAL_KEYBOARD_CONSOLE_IN_EX_NOTIFY_SIGNATURE
> + );
> + RemoveEntryList (ListHead->ForwardLink);
> + gBS->FreePool (NotifyNode);
> + }
> +
> + return EFI_SUCCESS;
> +}
> +
> +/**
> + Judge whether is a registed key
> +
> + @param RegsiteredData A pointer to a buffer that is filled in with the keystroke
> + state data for the key that was registered.
> + @param InputData A pointer to a buffer that is filled in with the keystroke
> + state data for the key that was pressed.
> +
> + @retval TRUE Key be pressed matches a registered key.
> + @retval FLASE Match failed.
> +
> +**/
> +BOOLEAN
> +IsKeyRegistered (
> + IN EFI_KEY_DATA *RegsiteredData,
> + IN EFI_KEY_DATA *InputData
> + )
> +
> +{
> + 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;
> +
> +}
> +
> +/**
> + Event notification function for SIMPLE_TEXT_IN.WaitForKey event
> + Signal the event if there is key available
> +
> + @param Event the event object
> + @param Context waitting context
> +
> +**/
> +VOID
> +EFIAPI
> +VirtualKeyboardWaitForKey (
> + IN EFI_EVENT Event,
> + IN VOID *Context
> + )
> +{
> + //
> + // Stall 1ms to give a chance to let other driver interrupt this routine for their timer event.
> + // Csm will be used to check whether there is a key pending, but the csm will disable all
Well, this makes it clear this driver is based on
IntelFrameworkModulePkg/Csm/BiosThunk/KeyboardDxe/.
I cannot really comment on whether that was the best starting point,
but please delete all and any references to CSM and eficompatibility -
these are fundamentally irrelevant for any non-x86 platforms.
> + // interrupt before switch to compatibility16, which mean all the efiCompatibility timer
> + // event will stop work during the compatibility16. And If a caller recursivly invoke this function,
> + // e.g. UI setup or Shell, other drivers which are driven by timer event will have a bad performance during this period,
> + // e.g. usb keyboard driver.
> + // Add a stall period can greatly increate other driver performance during the WaitForKey is recursivly invoked.
> + // 1ms delay will make little impact to the thunk keyboard driver, and user can not feel the delay at all when input.
> + //
> + gBS->Stall (1000);
> + //
> + // Use TimerEvent callback function to check whether there's any key pressed
> + //
> + VirtualKeyboardTimerHandler (NULL, VIRTUAL_KEYBOARD_DEV_FROM_THIS (Context));
> +
> + if (!EFI_ERROR (VirtualKeyboardCheckForKey (Context))) {
> + gBS->SignalEvent (Event);
> + }
> +}
> +
> +/**
> + Event notification function for SIMPLE_TEXT_INPUT_EX_PROTOCOL.WaitForKeyEx event
> + Signal the event if there is key available
> +
> + @param Event event object
> + @param Context waiting context
> +
> +**/
> +VOID
> +EFIAPI
> +VirtualKeyboardWaitForKeyEx (
> + IN EFI_EVENT Event,
> + IN VOID *Context
> + )
> +
> +{
> + VIRTUAL_KEYBOARD_DEV *VirtualKeyboardPrivate;
> +
> + VirtualKeyboardPrivate = TEXT_INPUT_EX_VIRTUAL_KEYBOARD_DEV_FROM_THIS (Context);
> + VirtualKeyboardWaitForKey (Event, &VirtualKeyboardPrivate->SimpleTextIn);
> +
> +}
> +
> +//
> +// EFI Simple Text In Protocol Functions
> +//
> +/**
> + Reset the Keyboard and do BAT test for it, if (ExtendedVerification == TRUE) then do some extra keyboard validations.
There are a few really long lines in this patch. Please try to keep
to no more than 80 characters were feasible. Applies throughout.
> +
> + @param This Pointer of simple text Protocol.
> + @param ExtendedVerification Whether perform the extra validation of keyboard. True: perform; FALSE: skip.
> +
> + @retval EFI_SUCCESS The command byte is written successfully.
> + @retval EFI_DEVICE_ERROR Errors occurred during resetting keyboard.
> +
> +**/
> +EFI_STATUS
> +EFIAPI
> +VirtualKeyboardReset (
> + IN EFI_SIMPLE_TEXT_INPUT_PROTOCOL *This,
> + IN BOOLEAN ExtendedVerification
> + )
> +{
> + VIRTUAL_KEYBOARD_DEV *VirtualKeyboardPrivate;
> + EFI_STATUS Status;
> + EFI_TPL OldTpl;
> +
> + VirtualKeyboardPrivate = VIRTUAL_KEYBOARD_DEV_FROM_THIS (This);
> +
> + //
> + // Raise TPL to avoid mouse operation impact
> + //
> + OldTpl = gBS->RaiseTPL (TPL_NOTIFY);
> +
> + if (VirtualKeyboardPrivate->PlatformVirtual && VirtualKeyboardPrivate->PlatformVirtual->Reset) {
if (VirtualKeyboardPrivate->PlatformVirtual &&
VirtualKeyboardPrivate->PlatformVirtual->Reset) {
And so on.
> + Status = VirtualKeyboardPrivate->PlatformVirtual->Reset ();
> + } else {
> + Status = EFI_INVALID_PARAMETER;
> + }
> +
> + //
> + // resume priority of task level
> + //
> + gBS->RestoreTPL (OldTpl);
> +
> + return Status;
> +}
> +
> +/**
> + Reset the input device and optionaly run diagnostics
> +
> + @param This Protocol instance pointer.
> + @param ExtendedVerification Driver may perform diagnostics on reset.
> +
> + @retval EFI_SUCCESS The device was reset.
> + @retval EFI_DEVICE_ERROR The device is not functioning properly and could-
> + not be reset.
> +
> +**/
> +EFI_STATUS
> +EFIAPI
> +VirtualKeyboardResetEx (
> + IN EFI_SIMPLE_TEXT_INPUT_EX_PROTOCOL *This,
> + IN BOOLEAN ExtendedVerification
> + )
> +{
> + VIRTUAL_KEYBOARD_DEV *VirtualKeyboardPrivate;
Spacing does not match subsequent lines.
> + EFI_STATUS Status;
> + EFI_TPL OldTpl;
> +
> + VirtualKeyboardPrivate = TEXT_INPUT_EX_VIRTUAL_KEYBOARD_DEV_FROM_THIS (This);
> +
> + Status = VirtualKeyboardPrivate->SimpleTextIn.Reset (
> + &VirtualKeyboardPrivate->SimpleTextIn,
Funky indentation.
> + ExtendedVerification
> + );
> + if (EFI_ERROR (Status)) {
> + return EFI_DEVICE_ERROR;
> + }
> +
> + OldTpl = gBS->RaiseTPL (TPL_NOTIFY);
> +
> + gBS->RestoreTPL (OldTpl);
> +
> + return EFI_SUCCESS;
> +
> +}
> +
> +/**
> + Reads the next keystroke from the input device. The WaitForKey Event can
> + be used to test for existance of a keystroke via WaitForEvent () call.
> +
> + @param VirtualKeyboardPrivate Virtualkeyboard driver private structure.
> + @param KeyData A pointer to a buffer that is filled in with the keystroke
> + state data for the key that was pressed.
> +
> + @retval EFI_SUCCESS The keystroke information was returned.
> + @retval EFI_NOT_READY There was no keystroke data availiable.
> + @retval EFI_DEVICE_ERROR The keystroke information was not returned due to
> + hardware errors.
> + @retval EFI_INVALID_PARAMETER KeyData is NULL.
> +
> +**/
> +EFI_STATUS
> +KeyboardReadKeyStrokeWorker (
> + IN VIRTUAL_KEYBOARD_DEV *VirtualKeyboardPrivate,
> + OUT EFI_KEY_DATA *KeyData
> + )
> +{
> + EFI_STATUS Status;
> + EFI_TPL OldTpl;
> + if (KeyData == NULL) {
> + return EFI_INVALID_PARAMETER;
> + }
> +
> + //
> + // Use TimerEvent callback function to check whether there's any key pressed
> + //
> +
> + //
> + // Stall 1ms to give a chance to let other driver interrupt this routine for their timer event.
> + // Csm will be used to check whether there is a key pending, but the csm will disable all
> + // interrupt before switch to compatibility16, which mean all the efiCompatibility timer
> + // event will stop work during the compatibility16. And If a caller recursivly invoke this function,
> + // e.g. OS loader, other drivers which are driven by timer event will have a bad performance during this period,
> + // e.g. usb keyboard driver.
> + // Add a stall period can greatly increate other driver performance during the WaitForKey is recursivly invoked.
> + // 1ms delay will make little impact to the thunk keyboard driver, and user can not feel the delay at all when input.
> + //
> + gBS->Stall (1000);
> +
> + OldTpl = gBS->RaiseTPL (TPL_NOTIFY);
> +
> + VirtualKeyboardTimerHandler (NULL, VirtualKeyboardPrivate);
> + //
> + // If there's no key, just return
> + //
> + Status = CheckQueue (&VirtualKeyboardPrivate->Queue);
> + if (EFI_ERROR (Status)) {
> + gBS->RestoreTPL (OldTpl);
> + return EFI_NOT_READY;
> + }
> +
> + Status = Dequeue (&VirtualKeyboardPrivate->Queue, KeyData);
> +
> + gBS->RestoreTPL (OldTpl);
> +
> + return EFI_SUCCESS;
> +}
> +
> +/**
> + Read out the scan code of the key that has just been stroked.
> +
> + @param This Pointer of simple text Protocol.
> + @param Key Pointer for store the key that read out.
> +
> + @retval EFI_SUCCESS The key is read out successfully.
> + @retval other The key reading failed.
> +
> +**/
> +EFI_STATUS
> +EFIAPI
> +VirtualKeyboardReadKeyStroke (
> + IN EFI_SIMPLE_TEXT_INPUT_PROTOCOL *This,
> + OUT EFI_INPUT_KEY *Key
> + )
> +{
> + VIRTUAL_KEYBOARD_DEV *VirtualKeyboardPrivate;
> + EFI_STATUS Status;
> + EFI_KEY_DATA KeyData;
> +
> + VirtualKeyboardPrivate = VIRTUAL_KEYBOARD_DEV_FROM_THIS (This);
> +
> + Status = KeyboardReadKeyStrokeWorker (VirtualKeyboardPrivate, &KeyData);
> + if (EFI_ERROR (Status)) {
> + return Status;
> + }
> +
> + //
> + // Convert the 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;
> +}
> +
> +/**
> + Reads the next keystroke from the input device. The WaitForKey Event can
> + be used to test for existance of a keystroke via WaitForEvent () call.
> +
> + @param This Protocol instance pointer.
> + @param KeyData A pointer to a buffer that is filled in with the keystroke
> + state data for the key that was pressed.
> +
> + @retval EFI_SUCCESS The keystroke information was returned.
> + @retval EFI_NOT_READY There was no keystroke data availiable.
> + @retval EFI_DEVICE_ERROR The keystroke information was not returned due to
> + hardware errors.
> + @retval EFI_INVALID_PARAMETER KeyData is NULL.
> +
> +**/
> +EFI_STATUS
> +EFIAPI
> +VirtualKeyboardReadKeyStrokeEx (
> + IN EFI_SIMPLE_TEXT_INPUT_EX_PROTOCOL *This,
> + OUT EFI_KEY_DATA *KeyData
> + )
> +{
> + VIRTUAL_KEYBOARD_DEV *VirtualKeyboardPrivate;
> +
> + if (KeyData == NULL) {
> + return EFI_INVALID_PARAMETER;
> + }
> +
> + VirtualKeyboardPrivate = TEXT_INPUT_EX_VIRTUAL_KEYBOARD_DEV_FROM_THIS (This);
> +
> + return KeyboardReadKeyStrokeWorker (VirtualKeyboardPrivate, KeyData);
> +
> +}
> +
> +/**
> + Set certain state for the input device.
> +
> + @param This Protocol instance pointer.
> + @param KeyToggleState A pointer to the EFI_KEY_TOGGLE_STATE to set the-
> + state for the input device.
> +
> + @retval EFI_SUCCESS The device state was set successfully.
> + @retval EFI_DEVICE_ERROR The device is not functioning correctly and could-
> + not have the setting adjusted.
> + @retval EFI_UNSUPPORTED The device does not have the ability to set its state.
> + @retval EFI_INVALID_PARAMETER KeyToggleState is NULL.
> +
> +**/
> +EFI_STATUS
> +EFIAPI
> +VirtualKeyboardSetState (
> + IN EFI_SIMPLE_TEXT_INPUT_EX_PROTOCOL *This,
> + IN EFI_KEY_TOGGLE_STATE *KeyToggleState
> + )
> +{
> + if (KeyToggleState == NULL) {
> + return EFI_INVALID_PARAMETER;
> + }
> +
> + //
> + // Thunk keyboard driver doesn't support partial keystroke.
> + //
> + if ((*KeyToggleState & EFI_TOGGLE_STATE_VALID) != EFI_TOGGLE_STATE_VALID ||
> + (*KeyToggleState & EFI_KEY_STATE_EXPOSED) == EFI_KEY_STATE_EXPOSED
> + ) {
> + return EFI_UNSUPPORTED;
> + }
> +
This function has no side effects, and it's an emulated keyboard (how
could a partial keystroke happen?). Why does it do anything other than
return SUCCESS?
> + return EFI_SUCCESS;
> +}
> +
> +/**
> + Register a notification function for a particular keystroke for the input device.
> +
> + @param This Protocol instance pointer.
> + @param KeyData A pointer to a buffer that is filled in with the keystroke
> + information data for the key that was pressed.
> + @param KeyNotificationFunction Points to the function to be called when the key
> + sequence is typed specified by KeyData.
> + @param NotifyHandle Points to the unique handle assigned to the registered notification.
> +
> +
> + @retval EFI_SUCCESS The notification function was registered successfully.
> + @retval EFI_OUT_OF_RESOURCES Unable to allocate resources for necesssary data structures.
> + @retval EFI_INVALID_PARAMETER KeyData or NotifyHandle is NULL.
> +
> +**/
> +EFI_STATUS
> +EFIAPI
> +VirtualKeyboardRegisterKeyNotify (
> + IN EFI_SIMPLE_TEXT_INPUT_EX_PROTOCOL *This,
> + IN EFI_KEY_DATA *KeyData,
> + IN EFI_KEY_NOTIFY_FUNCTION KeyNotificationFunction,
> + OUT VOID **NotifyHandle
> + )
> +{
> + EFI_STATUS Status;
> + VIRTUAL_KEYBOARD_DEV *VirtualKeyboardPrivate;
> + EFI_TPL OldTpl;
> + VIRTUAL_KEYBOARD_CONSOLE_IN_EX_NOTIFY *NewNotify;
> + LIST_ENTRY *Link;
> + VIRTUAL_KEYBOARD_CONSOLE_IN_EX_NOTIFY *CurrentNotify;
> +
> + if (KeyData == NULL || NotifyHandle == NULL || KeyNotificationFunction == NULL) {
> + return EFI_INVALID_PARAMETER;
> + }
> +
> + VirtualKeyboardPrivate = TEXT_INPUT_EX_VIRTUAL_KEYBOARD_DEV_FROM_THIS (This);
> +
> + //
> + // Enter critical section
> + //
> + OldTpl = gBS->RaiseTPL (TPL_NOTIFY);
> +
> + //
> + // Return EFI_SUCCESS if the (KeyData, NotificationFunction) is already registered.
> + //
> + for (Link = VirtualKeyboardPrivate->NotifyList.ForwardLink; Link != &VirtualKeyboardPrivate->NotifyList; Link = Link->ForwardLink) {
> + CurrentNotify = CR (
> + Link,
> + VIRTUAL_KEYBOARD_CONSOLE_IN_EX_NOTIFY,
> + NotifyEntry,
> + VIRTUAL_KEYBOARD_CONSOLE_IN_EX_NOTIFY_SIGNATURE
> + );
> + if (IsKeyRegistered (&CurrentNotify->KeyData, KeyData)) {
> + if (CurrentNotify->KeyNotificationFn == KeyNotificationFunction) {
> + *NotifyHandle = CurrentNotify;
> + Status = EFI_SUCCESS;
> + goto Exit;
> + }
> + }
> + }
> +
> + //
> + // Allocate resource to save the notification function
> + //
> +
> + NewNotify = (VIRTUAL_KEYBOARD_CONSOLE_IN_EX_NOTIFY *) AllocateZeroPool (sizeof (VIRTUAL_KEYBOARD_CONSOLE_IN_EX_NOTIFY));
> + if (NewNotify == NULL) {
> + Status = EFI_OUT_OF_RESOURCES;
> + goto Exit;
> + }
> +
> + NewNotify->Signature = VIRTUAL_KEYBOARD_CONSOLE_IN_EX_NOTIFY_SIGNATURE;
> + NewNotify->KeyNotificationFn = KeyNotificationFunction;
> + CopyMem (&NewNotify->KeyData, KeyData, sizeof (EFI_KEY_DATA));
> + InsertTailList (&VirtualKeyboardPrivate->NotifyList, &NewNotify->NotifyEntry);
> +
> + *NotifyHandle = NewNotify;
> + Status = EFI_SUCCESS;
> +
> +Exit:
> + //
> + // Leave critical section and return
> + //
> + gBS->RestoreTPL (OldTpl);
> + return Status;
> +
> +}
> +
> +/**
> + Remove a registered notification function from a particular keystroke.
> +
> + @param This Protocol instance pointer.
> + @param NotificationHandle The handle of the notification function being unregistered.
> +
> + @retval EFI_SUCCESS The notification function was unregistered successfully.
> + @retval EFI_INVALID_PARAMETER The NotificationHandle is invalid.
> +
> +**/
> +EFI_STATUS
> +EFIAPI
> +VirtualKeyboardUnregisterKeyNotify (
> + IN EFI_SIMPLE_TEXT_INPUT_EX_PROTOCOL *This,
> + IN VOID *NotificationHandle
> + )
> +{
> + EFI_STATUS Status;
> + VIRTUAL_KEYBOARD_DEV *VirtualKeyboardPrivate;
> + EFI_TPL OldTpl;
> + LIST_ENTRY *Link;
> + VIRTUAL_KEYBOARD_CONSOLE_IN_EX_NOTIFY *CurrentNotify;
> +
> + //
> + // Check incoming notification handle
> + //
> + if (NotificationHandle == NULL) {
> + return EFI_INVALID_PARAMETER;
> + }
> +
> + if (((VIRTUAL_KEYBOARD_CONSOLE_IN_EX_NOTIFY *) NotificationHandle)->Signature != VIRTUAL_KEYBOARD_CONSOLE_IN_EX_NOTIFY_SIGNATURE) {
> + return EFI_INVALID_PARAMETER;
> + }
> +
> + VirtualKeyboardPrivate = TEXT_INPUT_EX_VIRTUAL_KEYBOARD_DEV_FROM_THIS (This);
> +
> + //
> + // Enter critical section
> + //
> + OldTpl = gBS->RaiseTPL (TPL_NOTIFY);
> +
> + for (Link = VirtualKeyboardPrivate->NotifyList.ForwardLink; Link != &VirtualKeyboardPrivate->NotifyList; Link = Link->ForwardLink) {
> + CurrentNotify = CR (
> + Link,
> + VIRTUAL_KEYBOARD_CONSOLE_IN_EX_NOTIFY,
> + NotifyEntry,
> + VIRTUAL_KEYBOARD_CONSOLE_IN_EX_NOTIFY_SIGNATURE
> + );
> + if (CurrentNotify == NotificationHandle) {
> + //
> + // Remove the notification function from NotifyList and free resources
> + //
> + RemoveEntryList (&CurrentNotify->NotifyEntry);
> +
> + Status = EFI_SUCCESS;
> + goto Exit;
> + }
> + }
> +
> + //
> + // Can not find the specified Notification Handle
> + //
> + Status = EFI_INVALID_PARAMETER;
> +
> +Exit:
> + //
> + // Leave critical section and return
> + //
> + gBS->RestoreTPL (OldTpl);
> + return Status;
> +}
> +
> +/**
> + Timer event handler: read a series of scancodes from 8042
> + and put them into memory scancode buffer.
> + it read as much scancodes to either fill
> + the memory buffer or empty the keyboard buffer.
> + It is registered as running under TPL_NOTIFY
> +
> + @param Event The timer event
> + @param Context A KEYBOARD_CONSOLE_IN_DEV pointer
> +
> +**/
> +VOID
> +EFIAPI
> +VirtualKeyboardTimerHandler (
> + IN EFI_EVENT Event,
> + IN VOID *Context
> + )
> +{
> + EFI_TPL OldTpl;
> + LIST_ENTRY *Link;
> + EFI_KEY_DATA KeyData;
Please make these variable names line up with the ones below.
> + VIRTUAL_KEYBOARD_CONSOLE_IN_EX_NOTIFY *CurrentNotify;
> + VIRTUAL_KEYBOARD_DEV *VirtualKeyboardPrivate;
> + VIRTUAL_KBD_KEY VirtualKey;
> +
> + VirtualKeyboardPrivate = Context;
> +
> + //
> + // Enter critical section
> + //
> + OldTpl = gBS->RaiseTPL (TPL_NOTIFY);
> +
> + if (VirtualKeyboardPrivate->PlatformVirtual &&
> + VirtualKeyboardPrivate->PlatformVirtual->Query) {
> + if (VirtualKeyboardPrivate->PlatformVirtual->Query (&VirtualKey) == FALSE) {
> + goto Exit;
> + }
> + // Found key
> + KeyData.Key.ScanCode = VirtualKey.Key.ScanCode;
> + KeyData.Key.UnicodeChar = VirtualKey.Key.UnicodeChar;
> + KeyData.KeyState.KeyShiftState = EFI_SHIFT_STATE_VALID;
> + KeyData.KeyState.KeyToggleState = EFI_TOGGLE_STATE_VALID;
> + if (VirtualKeyboardPrivate->PlatformVirtual->Clear) {
> + VirtualKeyboardPrivate->PlatformVirtual->Clear (&VirtualKey);
> + }
> + } else {
> + goto Exit;
> + }
> +
> + //
> + // Signal KeyNotify process event if this key pressed matches any key registered.
> + //
> + for (Link = VirtualKeyboardPrivate->NotifyList.ForwardLink; Link != &VirtualKeyboardPrivate->NotifyList; Link = Link->ForwardLink) {
> + CurrentNotify = CR (
> + Link,
> + VIRTUAL_KEYBOARD_CONSOLE_IN_EX_NOTIFY,
> + NotifyEntry,
> + VIRTUAL_KEYBOARD_CONSOLE_IN_EX_NOTIFY_SIGNATURE
> + );
> + if (IsKeyRegistered (&CurrentNotify->KeyData, &KeyData)) {
> + //
> + // The key notification function needs to run at TPL_CALLBACK
> + // while current TPL is TPL_NOTIFY. It will be invoked in
> + // KeyNotifyProcessHandler() which runs at TPL_CALLBACK.
> + //
> + Enqueue (&VirtualKeyboardPrivate->QueueForNotify, &KeyData);
> + gBS->SignalEvent (VirtualKeyboardPrivate->KeyNotifyProcessEvent);
> + }
> + }
> +
> + Enqueue (&VirtualKeyboardPrivate->Queue, &KeyData);
> +
> +Exit:
> + //
> + // Leave critical section and return
> + //
> + gBS->RestoreTPL (OldTpl);
> +}
> +
> +/**
> + Process key notify.
> +
> + @param Event Indicates the event that invoke this function.
> + @param Context Indicates the calling context.
> +**/
> +VOID
> +EFIAPI
> +KeyNotifyProcessHandler (
> + IN EFI_EVENT Event,
> + IN VOID *Context
> + )
> +{
> + EFI_STATUS Status;
> + VIRTUAL_KEYBOARD_DEV *VirtualKeyboardPrivate;
> + EFI_KEY_DATA KeyData;
> + LIST_ENTRY *Link;
> + LIST_ENTRY *NotifyList;
> + VIRTUAL_KEYBOARD_CONSOLE_IN_EX_NOTIFY *CurrentNotify;
> + EFI_TPL OldTpl;
Please make variable names line up.
> +
> + VirtualKeyboardPrivate = (VIRTUAL_KEYBOARD_DEV *) Context;
> +
> + //
> + // Invoke notification functions.
> + //
> + NotifyList = &VirtualKeyboardPrivate->NotifyList;
> + while (TRUE) {
> + //
> + // Enter critical section
> + //
> + OldTpl = gBS->RaiseTPL (TPL_NOTIFY);
> + Status = Dequeue (&VirtualKeyboardPrivate->QueueForNotify, &KeyData);
> + //
> + // Leave critical section
> + //
> + gBS->RestoreTPL (OldTpl);
> + if (EFI_ERROR (Status)) {
> + break;
> + }
> + for (Link = GetFirstNode (NotifyList); !IsNull (NotifyList, Link); Link = GetNextNode (NotifyList, Link)) {
> + CurrentNotify = CR (Link, VIRTUAL_KEYBOARD_CONSOLE_IN_EX_NOTIFY, NotifyEntry, VIRTUAL_KEYBOARD_CONSOLE_IN_EX_NOTIFY_SIGNATURE);
> + if (IsKeyRegistered (&CurrentNotify->KeyData, &KeyData)) {
> + CurrentNotify->KeyNotificationFn (&KeyData);
> + }
> + }
> + }
> +}
> +
> +/**
> + The user Entry Point for module VirtualKeyboard. The user code starts with this function.
> +
> + @param[in] ImageHandle The firmware allocated handle for the EFI image.
> + @param[in] SystemTable A pointer to the EFI System Table.
> +
> + @retval EFI_SUCCESS The entry point is executed successfully.
> + @retval other Some error occurs when executing this entry point.
> +
> +**/
> +EFI_STATUS
> +EFIAPI
> +InitializeVirtualKeyboard(
> + IN EFI_HANDLE ImageHandle,
> + IN EFI_SYSTEM_TABLE *SystemTable
> + )
> +{
> + EFI_STATUS Status;
> +
> + //
> + // Install driver model protocol(s).
> + //
> + Status = EfiLibInstallDriverBindingComponentName2 (
> + ImageHandle,
> + SystemTable,
> + &gVirtualKeyboardDriverBinding,
> + ImageHandle,
> + &gVirtualKeyboardComponentName,
> + &gVirtualKeyboardComponentName2
> + );
> + ASSERT_EFI_ERROR (Status);
> +
> + return Status;
> +}
> diff --git a/EmbeddedPkg/Drivers/VirtualKeyboardDxe/VirtualKeyboard.h b/EmbeddedPkg/Drivers/VirtualKeyboardDxe/VirtualKeyboard.h
> new file mode 100644
> index 0000000..c8e256d
> --- /dev/null
> +++ b/EmbeddedPkg/Drivers/VirtualKeyboardDxe/VirtualKeyboard.h
> @@ -0,0 +1,544 @@
> +/** @file
> +
> +Copyright (c) 2006 - 2016, Intel Corporation. All rights reserved.<BR>
> +Copyright (c) 2018, Linaro Ltd. 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.
> +
> +**/
> +
> +#ifndef _VIRTUAL_KEYBOARD_H_
> +#define _VIRTUAL_KEYBOARD_H_
> +
> +
> +#include <Guid/StatusCodeDataTypeId.h>
> +#include <Protocol/DevicePath.h>
> +#include <Protocol/PlatformVirtualKeyboard.h>
> +#include <Protocol/SimpleTextIn.h>
> +#include <Protocol/SimpleTextInEx.h>
> +
> +#include <Library/BaseLib.h>
> +#include <Library/BaseMemoryLib.h>
> +#include <Library/DebugLib.h>
> +#include <Library/MemoryAllocationLib.h>
> +#include <Library/IoLib.h>
> +#include <Library/PcdLib.h>
> +#include <Library/ReportStatusCodeLib.h>
> +#include <Library/UefiBootServicesTableLib.h>
> +#include <Library/UefiDriverEntryPoint.h>
> +#include <Library/UefiLib.h>
> +
> +//
> +// Driver Binding Externs
> +//
> +extern EFI_DRIVER_BINDING_PROTOCOL gVirtualKeyboardDriverBinding;
> +extern EFI_COMPONENT_NAME_PROTOCOL gVirtualKeyboardComponentName;
> +extern EFI_COMPONENT_NAME2_PROTOCOL gVirtualKeyboardComponentName2;
> +
> +
> +//
> +// VIRTUAL Keyboard Defines
> +//
> +#define CHAR_SCANCODE 0xe0
> +#define CHAR_ESC 0x1b
> +
> +#define KEYBOARD_TIMEOUT 65536 // 0.07s
> +#define KEYBOARD_WAITFORVALUE_TIMEOUT 1000000 // 1s
> +#define KEYBOARD_BAT_TIMEOUT 4000000 // 4s
> +#define KEYBOARD_TIMER_INTERVAL 500000 // 0.5s
> +
> +#define QUEUE_MAX_COUNT 32
> +
> +#define KEYBOARD_SCAN_CODE_MAX_COUNT 32
> +
> +//
> +// VIRTUAL Keyboard Device Structure
> +//
> +#define VIRTUAL_KEYBOARD_DEV_SIGNATURE SIGNATURE_32 ('V', 'K', 'B', 'D')
> +#define VIRTUAL_KEYBOARD_CONSOLE_IN_EX_NOTIFY_SIGNATURE SIGNATURE_32 ('v', 'k', 'c', 'n')
> +
> +typedef struct _VIRTUAL_KEYBOARD_CONSOLE_IN_EX_NOTIFY {
> + UINTN Signature;
> + EFI_KEY_DATA KeyData;
> + EFI_KEY_NOTIFY_FUNCTION KeyNotificationFn;
> + LIST_ENTRY NotifyEntry;
> +} VIRTUAL_KEYBOARD_CONSOLE_IN_EX_NOTIFY;
> +
> +typedef struct {
> + UINTN Front;
> + UINTN Rear;
> + EFI_KEY_DATA Buffer[QUEUE_MAX_COUNT];
> +} SIMPLE_QUEUE;
> +
> +typedef struct {
> + UINT8 Buffer[KEYBOARD_SCAN_CODE_MAX_COUNT];
> + UINTN Head;
> + UINTN Tail;
> +} SCAN_CODE_QUEUE;
> +
> +typedef struct {
> + UINTN Signature;
> + EFI_HANDLE Handle;
> + PLATFORM_VIRTUAL_KBD_PROTOCOL *PlatformVirtual;
> + EFI_SIMPLE_TEXT_INPUT_PROTOCOL SimpleTextIn;
> + EFI_SIMPLE_TEXT_INPUT_EX_PROTOCOL SimpleTextInputEx;
> +
> + //
> + // Buffer storing EFI_KEY_DATA
> + //
> + SIMPLE_QUEUE Queue;
> + SIMPLE_QUEUE QueueForNotify;
> +
> + //
> + // Notification Function List
> + //
> + LIST_ENTRY NotifyList;
> + EFI_EVENT KeyNotifyProcessEvent;
> + EFI_EVENT TimerEvent;
> +} VIRTUAL_KEYBOARD_DEV;
> +
> +#define VIRTUAL_KEYBOARD_DEV_FROM_THIS(a) CR (a, VIRTUAL_KEYBOARD_DEV, SimpleTextIn, VIRTUAL_KEYBOARD_DEV_SIGNATURE)
> +#define TEXT_INPUT_EX_VIRTUAL_KEYBOARD_DEV_FROM_THIS(a) \
> + CR (a, \
> + VIRTUAL_KEYBOARD_DEV, \
> + SimpleTextInputEx, \
> + VIRTUAL_KEYBOARD_DEV_SIGNATURE \
> + )
> +
> +//
> +// Global Variables
> +//
> +extern EFI_DRIVER_BINDING_PROTOCOL gVirtualKeyboardDriverBinding;
> +
> +//
> +// Driver Binding Protocol functions
> +//
> +
> +/**
> + Check whether the driver supports this device.
> +
> + @param This The Udriver binding protocol.
> + @param Controller The controller handle to check.
> + @param RemainingDevicePath The remaining device path.
> +
> + @retval EFI_SUCCESS The driver supports this controller.
> + @retval other This device isn't supported.
> +
> +**/
> +EFI_STATUS
> +EFIAPI
> +VirtualKeyboardDriverBindingSupported (
> + IN EFI_DRIVER_BINDING_PROTOCOL *This,
> + IN EFI_HANDLE Controller,
> + IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath
> + );
> +
> +/**
> + Starts the device with this driver.
> +
> + @param This The driver binding instance.
> + @param Controller Handle of device to bind driver to.
> + @param RemainingDevicePath Optional parameter use to pick a specific child
> + device to start.
> +
> + @retval EFI_SUCCESS The controller is controlled by the driver.
> + @retval Other This controller cannot be started.
> +
> +**/
> +EFI_STATUS
> +EFIAPI
> +VirtualKeyboardDriverBindingStart (
> + IN EFI_DRIVER_BINDING_PROTOCOL *This,
> + IN EFI_HANDLE Controller,
> + IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath
> + );
> +
> +/**
> + Stop the device handled by this driver.
> +
> + @param This The driver binding protocol.
> + @param Controller The controller to release.
> + @param NumberOfChildren The number of handles in ChildHandleBuffer.
> + @param ChildHandleBuffer The array of child handle.
> +
> + @retval EFI_SUCCESS The device was stopped.
> + @retval EFI_DEVICE_ERROR The device could not be stopped due to a device error.
> + @retval Others Fail to uninstall protocols attached on the device.
> +
> +**/
> +EFI_STATUS
> +EFIAPI
> +VirtualKeyboardDriverBindingStop (
> + IN EFI_DRIVER_BINDING_PROTOCOL *This,
> + IN EFI_HANDLE Controller,
> + IN UINTN NumberOfChildren,
> + IN EFI_HANDLE *ChildHandleBuffer
> + );
> +
> +/**
> + Retrieves a Unicode string that is the user readable name of the driver.
> +
> + This function retrieves the user readable name of a driver in the form of a
> + Unicode string. If the driver specified by This has a user readable name in
> + the language specified by Language, then a pointer to the driver name is
> + returned in DriverName, and EFI_SUCCESS is returned. If the driver specified
> + by This does not support the language specified by Language,
> + then EFI_UNSUPPORTED is returned.
> +
> + @param This[in] A pointer to the EFI_COMPONENT_NAME2_PROTOCOL or
> + EFI_COMPONENT_NAME_PROTOCOL instance.
> +
> + @param Language[in] A pointer to a Null-terminated ASCII string
> + array indicating the language. This is the
> + language of the driver name that the caller is
> + requesting, and it must match one of the
> + languages specified in SupportedLanguages. The
> + number of languages supported by a driver is up
> + to the driver writer. Language is specified
> + in RFC 4646 or ISO 639-2 language code format.
> +
> + @param DriverName[out] A pointer to the Unicode string to return.
> + This Unicode string is the name of the
> + driver specified by This in the language
> + specified by Language.
> +
> + @retval EFI_SUCCESS The Unicode string for the Driver specified by
> + This and the language specified by Language was
> + returned in DriverName.
> +
> + @retval EFI_INVALID_PAVIRTUALETER Language is NULL.
> +
> + @retval EFI_INVALID_PAVIRTUALETER DriverName is NULL.
> +
> + @retval EFI_UNSUPPORTED The driver specified by This does not support
> + the language specified by Language.
> +
> +**/
> +EFI_STATUS
> +EFIAPI
> +VirtualKeyboardComponentNameGetDriverName (
> + IN EFI_COMPONENT_NAME_PROTOCOL *This,
> + IN CHAR8 *Language,
> + OUT CHAR16 **DriverName
> + );
> +
> +
> +/**
> + Retrieves a Unicode string that is the user readable name of the controller
> + that is being managed by a driver.
> +
> + This function retrieves the user readable name of the controller specified by
> + ControllerHandle and ChildHandle in the form of a Unicode string. If the
> + driver specified by This has a user readable name in the language specified by
> + Language, then a pointer to the controller name is returned in ControllerName,
> + and EFI_SUCCESS is returned. If the driver specified by This is not currently
> + managing the controller specified by ControllerHandle and ChildHandle,
> + then EFI_UNSUPPORTED is returned. If the driver specified by This does not
> + support the language specified by Language, then EFI_UNSUPPORTED is returned.
> +
> + @param This[in] A pointer to the EFI_COMPONENT_NAME2_PROTOCOL or
> + EFI_COMPONENT_NAME_PROTOCOL instance.
> +
> + @param ControllerHandle[in] The handle of a controller that the driver
> + specified by This is managing. This handle
> + specifies the controller whose name is to be
> + returned.
> +
> + @param ChildHandle[in] The handle of the child controller to retrieve
> + the name of. This is an optional parameter that
> + may be NULL. It will be NULL for device
> + drivers. It will also be NULL for a bus drivers
> + that wish to retrieve the name of the bus
> + controller. It will not be NULL for a bus
> + driver that wishes to retrieve the name of a
> + child controller.
> +
> + @param Language[in] A pointer to a Null-terminated ASCII string
> + array indicating the language. This is the
> + language of the driver name that the caller is
> + requesting, and it must match one of the
> + languages specified in SupportedLanguages. The
> + number of languages supported by a driver is up
> + to the driver writer. Language is specified in
> + RFC 4646 or ISO 639-2 language code format.
> +
> + @param ControllerName[out] A pointer to the Unicode string to return.
> + This Unicode string is the name of the
> + controller specified by ControllerHandle and
> + ChildHandle in the language specified by
> + Language from the point of view of the driver
> + specified by This.
> +
> + @retval EFI_SUCCESS The Unicode string for the user readable name in
> + the language specified by Language for the
> + driver specified by This was returned in
> + DriverName.
> +
> + @retval EFI_INVALID_PAVIRTUALETER ControllerHandle is NULL.
> +
> + @retval EFI_INVALID_PAVIRTUALETER ChildHandle is not NULL and it is not a valid
> + EFI_HANDLE.
> +
> + @retval EFI_INVALID_PAVIRTUALETER Language is NULL.
> +
> + @retval EFI_INVALID_PAVIRTUALETER ControllerName is NULL.
> +
> + @retval EFI_UNSUPPORTED The driver specified by This is not currently
> + managing the controller specified by
> + ControllerHandle and ChildHandle.
> +
> + @retval EFI_UNSUPPORTED The driver specified by This does not support
> + the language specified by Language.
> +
> +**/
> +EFI_STATUS
> +EFIAPI
> +VirtualKeyboardComponentNameGetControllerName (
> + IN EFI_COMPONENT_NAME_PROTOCOL *This,
> + IN EFI_HANDLE ControllerHandle,
> + IN EFI_HANDLE ChildHandle OPTIONAL,
> + IN CHAR8 *Language,
> + OUT CHAR16 **ControllerName
> + );
> +
> +
> +//
> +// Simple Text Input Protocol functions
> +//
> +/**
> + Reset the Keyboard and do BAT test for it, if (ExtendedVerification == TRUE) then do some extra keyboard validations.
> +
> + @param This Pointer of simple text Protocol.
> + @param ExtendedVerification Whether perform the extra validation of keyboard. True: perform; FALSE: skip.
> +
> + @retval EFI_SUCCESS The command byte is written successfully.
> + @retval EFI_DEVICE_ERROR Errors occurred during resetting keyboard.
> +
> +**/
> +EFI_STATUS
> +EFIAPI
> +VirtualKeyboardReset (
> + IN EFI_SIMPLE_TEXT_INPUT_PROTOCOL *This,
> + IN BOOLEAN ExtendedVerification
> + );
> +
> +/**
> + Reset the input device and optionaly run diagnostics
> +
> + @param This Protocol instance pointer.
> + @param ExtendedVerification Driver may perform diagnostics on reset.
> +
> + @retval EFI_SUCCESS The device was reset.
> + @retval EFI_DEVICE_ERROR The device is not functioning properly and could
Trailing whitespace. (PatchCheck.py warns about this.)
> + not be reset.
> +
> +**/
> +EFI_STATUS
> +EFIAPI
> +VirtualKeyboardResetEx (
> + IN EFI_SIMPLE_TEXT_INPUT_EX_PROTOCOL *This,
> + IN BOOLEAN ExtendedVerification
> + );
> +
> +/**
> + Set certain state for the input device.
> +
> + @param This Protocol instance pointer.
> + @param KeyToggleState A pointer to the EFI_KEY_TOGGLE_STATE to set the
> + state for the input device.
> +
> + @retval EFI_SUCCESS The device state was set successfully.
> + @retval EFI_DEVICE_ERROR The device is not functioning correctly and could
> + not have the setting adjusted.
> + @retval EFI_UNSUPPORTED The device does not have the ability to set its state.
> + @retval EFI_INVALID_PAVIRTUALETER KeyToggleState is NULL.
> +
> +**/
> +EFI_STATUS
> +EFIAPI
> +VirtualKeyboardSetState (
> + IN EFI_SIMPLE_TEXT_INPUT_EX_PROTOCOL *This,
> + IN EFI_KEY_TOGGLE_STATE *KeyToggleState
> + );
> +
> +/**
> + Register a notification function for a particular keystroke for the input device.
> +
> + @param This Protocol instance pointer.
> + @param KeyData A pointer to a buffer that is filled in with the keystroke
> + information data for the key that was pressed.
> + @param KeyNotificationFunction Points to the function to be called when the key
> + sequence is typed specified by KeyData.
> + @param NotifyHandle Points to the unique handle assigned to the registered notification.
> +
> +
> + @retval EFI_SUCCESS The notification function was registered successfully.
> + @retval EFI_OUT_OF_RESOURCES Unable to allocate resources for necesssary data structures.
> + @retval EFI_INVALID_PAVIRTUALETER KeyData or NotifyHandle is NULL.
> +
> +**/
> +EFI_STATUS
> +EFIAPI
> +VirtualKeyboardRegisterKeyNotify (
> + IN EFI_SIMPLE_TEXT_INPUT_EX_PROTOCOL *This,
> + IN EFI_KEY_DATA *KeyData,
> + IN EFI_KEY_NOTIFY_FUNCTION KeyNotificationFunction,
> + OUT VOID **NotifyHandle
> + );
> +
> +/**
> + Remove a registered notification function from a particular keystroke.
> +
> + @param This Protocol instance pointer.
> + @param NotificationHandle The handle of the notification function being unregistered.
> +
> + @retval EFI_SUCCESS The notification function was unregistered successfully.
> + @retval EFI_INVALID_PAVIRTUALETER The NotificationHandle is invalid.
> +
> +**/
> +EFI_STATUS
> +EFIAPI
> +VirtualKeyboardUnregisterKeyNotify (
> + IN EFI_SIMPLE_TEXT_INPUT_EX_PROTOCOL *This,
> + IN VOID *NotificationHandle
> + );
> +
> +//
> +// Private worker functions
> +//
> +/**
> + Free keyboard notify list.
> +
> + @param ListHead The list head
> +
> + @retval EFI_SUCCESS Free the notify list successfully
> + @retval EFI_INVALID_PAVIRTUALETER ListHead is invalid.
> +
> +**/
> +EFI_STATUS
> +VirtualKeyboardFreeNotifyList (
> + IN OUT LIST_ENTRY *ListHead
> + );
> +
> +/**
> + Check if key is registered.
> +
> + @param RegsiteredData A pointer to a buffer that is filled in with the keystroke
> + state data for the key that was registered.
> + @param InputData A pointer to a buffer that is filled in with the keystroke
> + state data for the key that was pressed.
> +
> + @retval TRUE Key be pressed matches a registered key.
> + @retval FLASE Match failed.
> +
> +**/
> +BOOLEAN
> +IsKeyRegistered (
> + IN EFI_KEY_DATA *RegsiteredData,
> + IN EFI_KEY_DATA *InputData
> + );
> +
> +/**
> + Waiting on the keyboard event, if there's any key pressed by the user, signal the event
> +
> + @param Event The event that be siganlled when any key has been stroked.
> + @param Context Pointer of the protocol EFI_SIMPLE_TEXT_INPUT_PROTOCOL.
> +
> +**/
> +VOID
> +EFIAPI
> +VirtualKeyboardWaitForKey (
> + IN EFI_EVENT Event,
> + IN VOID *Context
> + );
> +
> +/**
> + Waiting on the keyboard event, if there's any key pressed by the user, signal the event
> +
> + @param Event The event that be siganlled when any key has been stroked.
> + @param Context Pointer of the protocol EFI_SIMPLE_TEXT_INPUT_EX_PROTOCOL.
> +
> +**/
> +VOID
> +EFIAPI
> +VirtualKeyboardWaitForKeyEx (
> + IN EFI_EVENT Event,
> + IN VOID *Context
> + );
> +
> +/**
> + Timer event handler: read a series of key stroke from 8042
> + and put them into memory key buffer.
> + It is registered as running under TPL_NOTIFY
> +
> + @param Event The timer event
> + @param Context A VIRTUAL_KEYBOARD_DEV pointer
> +
> +**/
> +VOID
> +EFIAPI
> +VirtualKeyboardTimerHandler (
> + IN EFI_EVENT Event,
> + IN VOID *Context
> + );
> +
> +/**
> + Process key notify.
> +
> + @param Event Indicates the event that invoke this function.
> + @param Context Indicates the calling context.
> +**/
> +VOID
> +EFIAPI
> +KeyNotifyProcessHandler (
> + IN EFI_EVENT Event,
> + IN VOID *Context
> + );
> +
> +/**
> + Read out the scan code of the key that has just been stroked.
> +
> + @param This Pointer of simple text Protocol.
> + @param Key Pointer for store the key that read out.
> +
> + @retval EFI_SUCCESS The key is read out successfully.
> + @retval other The key reading failed.
> +
> +**/
> +EFI_STATUS
> +EFIAPI
> +VirtualKeyboardReadKeyStroke (
> + IN EFI_SIMPLE_TEXT_INPUT_PROTOCOL *This,
> + OUT EFI_INPUT_KEY *Key
> + );
> +
> +/**
> + Reads the next keystroke from the input device. The WaitForKey Event can
> + be used to test for existance of a keystroke via WaitForEvent () call.
> +
> + @param This Protocol instance pointer.
> + @param KeyData A pointer to a buffer that is filled in with the keystroke
> + state data for the key that was pressed.
> +
> + @retval EFI_SUCCESS The keystroke information was returned.
> + @retval EFI_NOT_READY There was no keystroke data availiable.
> + @retval EFI_DEVICE_ERROR The keystroke information was not returned due to
> + hardware errors.
> + @retval EFI_INVALID_PAVIRTUALETER KeyData is NULL.
> +
> +**/
> +EFI_STATUS
> +EFIAPI
> +VirtualKeyboardReadKeyStrokeEx (
> + IN EFI_SIMPLE_TEXT_INPUT_EX_PROTOCOL *This,
> + OUT EFI_KEY_DATA *KeyData
> + );
> +
> +#endif /* _VIRTUAL_KEYBOARD_H_ */
> diff --git a/EmbeddedPkg/Drivers/VirtualKeyboardDxe/VirtualKeyboardDxe.dec b/EmbeddedPkg/Drivers/VirtualKeyboardDxe/VirtualKeyboardDxe.dec
> new file mode 100644
> index 0000000..065f4f2
> --- /dev/null
> +++ b/EmbeddedPkg/Drivers/VirtualKeyboardDxe/VirtualKeyboardDxe.dec
Could you add the two guids to EmbeddededPkg instead?
Or just gPlatformVirtualKeyboardProtocolGuid, I don't see any use of
gVirtualKeyboardDxeTokenSpaceGuid.
> @@ -0,0 +1,39 @@
> +#/** @file
> +# Framework Module Development Environment Industry Standards
> +#
> +# This Package provides headers and libraries that conform to EFI/PI Industry standards.
> +# Copyright (c) 2007, Intel Corporation. All rights reserved.<BR>
> +# Copyright (c) 2012-2014, ARM Ltd. All rights reserved.<BR>
> +# Copyright (c) 2018, Linaro. 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.
> +#
> +#**/
> +
> +[Defines]
> + DEC_SPECIFICATION = 0x00010019
> + PACKAGE_NAME = VirtualKeyboardDxePkg
> + PACKAGE_GUID = 774326bc-20d0-4203-97e4-10dc17f7dc1a
> + PACKAGE_VERSION = 0.1
> +
> +################################################################################
> +#
> +# Include Section - list of Include Paths that are provided by this package.
> +# Comments are used for Keywords and Module Types.
> +#
> +# Supported Module Types:
> +# BASE SEC PEI_CORE PEIM DXE_CORE DXE_DRIVER DXE_RUNTIME_DRIVER DXE_SMM_DRIVER DXE_SAL_DRIVER UEFI_DRIVER UEFI_APPLICATION
> +#
> +################################################################################
> +
> +[Guids.common]
> + gVirtualKeyboardDxeTokenSpaceGuid = { 0x80caf901, 0x0cf6, 0x4c09, { 0x89, 0x84, 0x61, 0xd1, 0xf3, 0xd2, 0x54, 0x39 }}
> +
> +[Protocols.common]
> + gPlatformVirtualKeyboardProtocolGuid = { 0x0e3606d2, 0x1dc3, 0x4e6f, { 0xbe, 0x65, 0x39, 0x49, 0x82, 0xa2, 0x65, 0x47 }}
> diff --git a/EmbeddedPkg/Drivers/VirtualKeyboardDxe/VirtualKeyboardDxe.inf b/EmbeddedPkg/Drivers/VirtualKeyboardDxe/VirtualKeyboardDxe.inf
> new file mode 100644
> index 0000000..a7e5bd0
> --- /dev/null
> +++ b/EmbeddedPkg/Drivers/VirtualKeyboardDxe/VirtualKeyboardDxe.inf
> @@ -0,0 +1,61 @@
> +## @file
> +# Virtual Keyboard driver.
> +#
> +# Copyright (c) 2018, Linaro Ltd. 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.
> +#
> +##
> +
> +[Defines]
> + INF_VERSION = 0x00010019
> + BASE_NAME = VirtualKeyboardDxe
> + FILE_GUID = 88079b18-b42b-44aa-a6f2-b83911075e89
> + MODULE_TYPE = UEFI_DRIVER
> + VERSION_STRING = 1.0
> + ENTRY_POINT = InitializeVirtualKeyboard
> +
> +#
> +# The following information is for reference only and not required by the build tools.
> +#
> +# VALID_ARCHITECTURES = AARCH64
Well, it's emulated, so I would hope it's valid for all architectures?
/
Leif
> +#
> +# DRIVER_BINDING = gVirtualKeyboardDriverBinding
> +# COMPONENT_NAME = gVirtualKeyboardComponentName
> +#
> +
> +[Sources.common]
> + ComponentName.c
> + VirtualKeyboard.c
> +
> +[Packages]
> + EmbeddedPkg/Drivers/VirtualKeyboardDxe/VirtualKeyboardDxe.dec
> + EmbeddedPkg/EmbeddedPkg.dec
> + MdePkg/MdePkg.dec
> + MdeModulePkg/MdeModulePkg.dec
> +
> +[LibraryClasses]
> + BaseLib
> + BaseMemoryLib
> + DebugLib
> + IoLib
> + ReportStatusCodeLib
> + UefiDriverEntryPoint
> + UefiBootServicesTableLib
> + UefiLib
> +
> +[Protocols]
> + gEfiDriverBindingProtocolGuid
> + gEfiSimpleTextInProtocolGuid
> + gEfiSimpleTextInputExProtocolGuid
> + gPlatformVirtualKeyboardProtocolGuid
> +
> +[Depex]
> + TRUE
> diff --git a/EmbeddedPkg/Include/Protocol/PlatformVirtualKeyboard.h b/EmbeddedPkg/Include/Protocol/PlatformVirtualKeyboard.h
> new file mode 100644
> index 0000000..bea3128
> --- /dev/null
> +++ b/EmbeddedPkg/Include/Protocol/PlatformVirtualKeyboard.h
> @@ -0,0 +1,65 @@
> +/** @file
> +
> + Copyright (c) 2018, Linaro. All rights reserved.
> +
> + 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.
> +
> +**/
> +
> +#ifndef __PLATFORM_VIRTUAL_KEYBOARD_H__
> +#define __PLATFORM_VIRTUAL_KEYBOARD_H__
> +
> +//
> +// Protocol interface structure
> +//
> +typedef struct _PLATFORM_VIRTUAL_KBD_PROTOCOL PLATFORM_VIRTUAL_KBD_PROTOCOL;
> +
> +typedef struct _VIRTUAL_KBD_KEY VIRTUAL_KBD_KEY;
> +
> +#define VIRTUAL_KEYBOARD_KEY_SIGNATURE SIGNATURE_32 ('v', 'k', 'b', 'd')
> +
> +struct _VIRTUAL_KBD_KEY {
> + UINTN Signature;
> + EFI_INPUT_KEY Key;
> +};
> +
> +typedef
> +EFI_STATUS
> +(EFIAPI *PLATFORM_VIRTUAL_KBD_REGISTER) (
> + IN VOID
> + );
> +
> +typedef
> +EFI_STATUS
> +(EFIAPI *PLATFORM_VIRTUAL_KBD_RESET) (
> + IN VOID
> + );
> +
> +typedef
> +BOOLEAN
> +(EFIAPI *PLATFORM_VIRTUAL_KBD_QUERY) (
> + IN VIRTUAL_KBD_KEY *VirtualKey
> + );
> +
> +typedef
> +EFI_STATUS
> +(EFIAPI *PLATFORM_VIRTUAL_KBD_CLEAR) (
> + IN VIRTUAL_KBD_KEY *VirtualKey
> + );
> +
> +struct _PLATFORM_VIRTUAL_KBD_PROTOCOL {
> + PLATFORM_VIRTUAL_KBD_REGISTER Register;
> + PLATFORM_VIRTUAL_KBD_RESET Reset;
> + PLATFORM_VIRTUAL_KBD_QUERY Query;
> + PLATFORM_VIRTUAL_KBD_CLEAR Clear;
> +};
> +
> +extern EFI_GUID gPlatformVirtualKeyboardProtocolGuid;
> +
> +#endif /* __PLATFORM_VIRTUAL_KEYBOARD_H__ */
> --
> 2.7.4
>
next prev parent reply other threads:[~2018-02-27 12:22 UTC|newest]
Thread overview: 4+ messages / expand[flat|nested] mbox.gz Atom feed top
2018-02-26 8:52 [PATCH] EmbeddedPkg/Drivers: add virtual keyboard driver Haojian Zhuang
2018-02-27 12:28 ` Leif Lindholm [this message]
2018-02-28 1:03 ` Haojian Zhuang
2018-02-28 13:36 ` Leif Lindholm
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-list from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20180227122847.fr2zq6nurtrlstqh@bivouac.eciton.net \
--to=devel@edk2.groups.io \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox