From: Haojian Zhuang <haojian.zhuang@linaro.org>
To: Leif Lindholm <leif.lindholm@linaro.org>
Cc: "ard.biesheuvel@linaro.org" <ard.biesheuvel@linaro.org>,
"linaro-uefi@lists.linaro.org" <linaro-uefi@lists.linaro.org>,
"edk2-devel@lists.01.org" <edk2-devel@lists.01.org>
Subject: Re: [PATCH] EmbeddedPkg/Drivers: add virtual keyboard driver
Date: Wed, 28 Feb 2018 01:03:07 +0000 [thread overview]
Message-ID: <9a4bc569-d5b6-b935-fc72-2271e68a6a38@linaro.org> (raw)
In-Reply-To: <20180227122847.fr2zq6nurtrlstqh@bivouac.eciton.net>
On 02/27/2018 08:28 PM, Leif Lindholm wrote:
> 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.)
OK. I'll append more comments in it.
>
>> 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
OK. I'll follow it.
>
>> 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?
>
Oh, I'll rename it to Virtual Keyboard Driver for consistent.
>> + },
>
> Any chance of a "zh-chs" entry?
>
Thanks. "zh-chs" may be inconvenient for others. "eng;en" is good for
everyone.
>> +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) {
>
OK
>> + //
>> + // 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.
OK
>
>> + 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.
>
OK
>> + FALSE
>> + );
>> + if (EFI_ERROR (Status)) {
>> + DEBUG ((EFI_D_ERROR, "[KBD]Reset Failed. Status - %r\n", Status));
>
> Use DEBUG_ERROR (PatchCheck.py warns about this).
>
OK
>> +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.
>
OK
>> + // 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.
>
OK
>> +
>> + @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.
>
OK
>> + 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?
>
OK. I'll change it.
>> + 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.
I'll move it into EmbeddedPkg instead.
>
>> @@ -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?
>
OK
Best Regards
Haojian
next prev parent reply other threads:[~2018-02-28 0:57 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
2018-02-28 1:03 ` Haojian Zhuang [this message]
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=9a4bc569-d5b6-b935-fc72-2271e68a6a38@linaro.org \
--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