From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received-SPF: Pass (sender SPF authorized) identity=mailfrom; client-ip=2607:f8b0:400e:c05::236; helo=mail-pg0-x236.google.com; envelope-from=haojian.zhuang@linaro.org; receiver=edk2-devel@lists.01.org Received: from mail-pg0-x236.google.com (mail-pg0-x236.google.com [IPv6:2607:f8b0:400e:c05::236]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by ml01.01.org (Postfix) with ESMTPS id A34D5209574D3 for ; Tue, 27 Feb 2018 16:57:04 -0800 (PST) Received: by mail-pg0-x236.google.com with SMTP id y26so314449pgv.4 for ; Tue, 27 Feb 2018 17:03:11 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; h=from:to:cc:subject:thread-topic:thread-index:date:message-id :references:in-reply-to:reply-to:accept-language:content-language :content-id:content-transfer-encoding:mime-version; bh=lKprDRcYAiGP2mHGqmN0j0pkV9ooikGTURrGIOUtSes=; b=QnJDejWDIG8tzf9PjbHV/QqGUerfUNqMr865aPOm9EXHmtidbidFgK/gpBhWNpy8+M qsVZtfbYRYsUrGmvED+CeUEXcVPujiOXyRl9PiDU/Z5LnvjjnblVl1KQhNT2YxRxxRJo Ob4TIA/YasGyR4ZmjNhk4oPj/EU00QAHPUhUc= X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:thread-topic:thread-index :date:message-id:references:in-reply-to:reply-to:accept-language :content-language:content-id:content-transfer-encoding:mime-version; bh=lKprDRcYAiGP2mHGqmN0j0pkV9ooikGTURrGIOUtSes=; b=P79Db+oLot5QzZo0VLyDh+/+HmnQiB+jK7VSejxpQ8RVKhhydLPMq0O8dFovJstYI5 EXIv6uW+hWKukyObPGzPMDvSpJxDqYWii3pk8aUwHG7cEwqSX96SC5SkkLKts+dhX+zD YGxE7ttZJ0rgoiYFXEMWHPH6KdqgHyP4Ve+t5jPHxEk86VHetsmVPLnYcl3G5VK1a7fX bFY0oyQPBKvL8rvE1EFYa3v4NMCdUdPYIr3LKAWTeMZbNtcAtJ+p95CUiY3xD+zmIJ0B vs4k0VG9279+fMo23lBre4Z4zqeSL0SFBRTOHG2bEevHffdx62VK2fQ5UfTkwXjKxtGs w6DQ== X-Gm-Message-State: APf1xPD6aAc02xh5/Od8LU69Sr9qlkuUDh+Bg0VEnjLK3Q7in+sBD8Mr KeOXqXAshPA/hT8ityb5TF5k2A== X-Google-Smtp-Source: AH8x224laRUMAg4hdTAiWdexD/HkDgMQNjgB2cZNxoYgjsgIqeKa3PTM5MetC2uyOJLl097ysldoBw== X-Received: by 10.98.9.130 with SMTP id 2mr15917478pfj.149.1519779789609; Tue, 27 Feb 2018 17:03:09 -0800 (PST) Received: from CY1PR15MB0730.namprd15.prod.outlook.com ([132.245.253.237]) by smtp.gmail.com with ESMTPSA id s78sm459358pfe.162.2018.02.27.17.03.07 (version=TLS1_2 cipher=ECDHE-RSA-AES128-SHA bits=128/128); Tue, 27 Feb 2018 17:03:08 -0800 (PST) From: Haojian Zhuang To: Leif Lindholm CC: "ard.biesheuvel@linaro.org" , "linaro-uefi@lists.linaro.org" , "edk2-devel@lists.01.org" Thread-Topic: [edk2][PATCH] EmbeddedPkg/Drivers: add virtual keyboard driver Thread-Index: AQHTrt8x9u1uFRX6bUyHrPrbV2DOt6O4L0iAgADSoYA= X-MS-Exchange-MessageSentRepresentingType: 2 Date: Wed, 28 Feb 2018 01:03:07 +0000 Message-ID: <9a4bc569-d5b6-b935-fc72-2271e68a6a38@linaro.org> References: <1519635156-21954-1-git-send-email-haojian.zhuang@linaro.org> <20180227122847.fr2zq6nurtrlstqh@bivouac.eciton.net> In-Reply-To: <20180227122847.fr2zq6nurtrlstqh@bivouac.eciton.net> Reply-To: "haojian.zhuang@linaro.org" Accept-Language: en-US X-MS-Has-Attach: X-MS-Exchange-Organization-SCL: -1 X-MS-TNEF-Correlator: X-MS-Exchange-Organization-RecordReviewCfmType: 0 x-ms-exchange-imapappendstamp: CY1PR15MB0730.namprd15.prod.outlook.com (15.20.0527.021) MIME-Version: 1.0 Subject: Re: [PATCH] EmbeddedPkg/Drivers: add virtual keyboard driver X-BeenThere: edk2-devel@lists.01.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: EDK II Development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Wed, 28 Feb 2018 00:57:05 -0000 Content-Language: en-US Content-Type: text/plain; charset="iso-8859-1" Content-ID: Content-Transfer-Encoding: quoted-printable 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. >=20 > 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. >=20 > (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. >=20 >> Contributed-under: TianoCore Contribution Agreement 1.1 >> Signed-off-by: Haojian Zhuang >> --- >> .../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 ++ >=20 > Please generate patches with > --stat=3D1000 --stat-graph-width=3D20 > and > --subject-prefix=3D"PATCH edk2-platforms" >=20 > (In general following the guide at) > https://github.com/tianocore/tianocore.github.io/wiki/Laszlo's-unkempt-gi= t-guide-for-edk2-contributors-and-maintainers OK. I'll follow it. >=20 >> 7 files changed, 2164 insertions(+) >> create mode 100644 EmbeddedPkg/Drivers/VirtualKeyboardDxe/ComponentNam= e.c >> create mode 100644 EmbeddedPkg/Drivers/VirtualKeyboardDxe/ComponentNam= e.h >> create mode 100644 EmbeddedPkg/Drivers/VirtualKeyboardDxe/VirtualKeybo= ard.c >> create mode 100644 EmbeddedPkg/Drivers/VirtualKeyboardDxe/VirtualKeybo= ard.h >> create mode 100644 EmbeddedPkg/Drivers/VirtualKeyboardDxe/VirtualKeybo= ardDxe.dec >> create mode 100644 EmbeddedPkg/Drivers/VirtualKeyboardDxe/VirtualKeybo= ardDxe.inf >> create mode 100644 EmbeddedPkg/Include/Protocol/PlatformVirtualKeyboar= d.h >> >> diff --git a/EmbeddedPkg/Drivers/VirtualKeyboardDxe/ComponentName.c b/Em= beddedPkg/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.
>> +Copyright (c) 2018, Linaro Ltd. 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 IM= PLIED. >> + >> +**/ >> + >> +#include "VirtualKeyboard.h" >> + >> +// >> +// EFI Component Name Protocol >> +// >> +GLOBAL_REMOVE_IF_UNREFERENCED EFI_COMPONENT_NAME_PROTOCOL gVirtualKeyb= oardComponentName =3D { >> + VirtualKeyboardComponentNameGetDriverName, >> + VirtualKeyboardComponentNameGetControllerName, >> + "eng" >> +}; >> + >> +// >> +// EFI Component Name 2 Protocol >> +// >> +GLOBAL_REMOVE_IF_UNREFERENCED EFI_COMPONENT_NAME2_PROTOCOL gVirtualKeyb= oardComponentName2 =3D { >> + (EFI_COMPONENT_NAME2_GET_DRIVER_NAME) VirtualKeyboardComponentNameGet= DriverName, >> + (EFI_COMPONENT_NAME2_GET_CONTROLLER_NAME) VirtualKeyboardComponentNam= eGetControllerName, >> + "en" >> +}; >> + >> + >> +GLOBAL_REMOVE_IF_UNREFERENCED EFI_UNICODE_STRING_TABLE mVirtualKeyboard= DriverNameTable[] =3D { >> + { >> + "eng;en", >> + L"RAM Keyboard Driver" >=20 > What is a RAM Keyboard Driver? >=20 Oh, I'll rename it to Virtual Keyboard Driver for consistent. >> + }, >=20 > Any chance of a "zh-chs" entry? >=20 Thanks. "zh-chs" may be inconvenient for others. "eng;en" is good for=20 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 =3D 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 =3D (VIRTUAL_KEYBOARD_DEV *) AllocateZeroPool = (sizeof (VIRTUAL_KEYBOARD_DEV)); >> + if (NULL =3D=3D VirtualKeyboardPrivate) { >=20 > No jeopardy-comparisons please. if (VirtualKeyboardPrivate =3D=3D NULL) { >=20 OK >> + // >> + // Setup a periodic timer, used for reading keystrokes at a fixed int= erval >> + // >> + Status =3D gBS->CreateEvent ( >> + EVT_TIMER | EVT_NOTIFY_SIGNAL, >> + TPL_NOTIFY, >> + VirtualKeyboardTimerHandler, >> + VirtualKeyboardPrivate, >> + &VirtualKeyboardPrivate->TimerEvent >> + ); >> + if (EFI_ERROR (Status)) { >> + Status =3D EFI_OUT_OF_RESOURCES; >=20 > The whitespace before =3D does not look quite right. > Please address throughout. OK >=20 >> + goto Done; >> + } >> + >> + Status =3D gBS->SetTimer ( >> + VirtualKeyboardPrivate->TimerEvent, >> + TimerPeriodic, >> + KEYBOARD_TIMER_INTERVAL >> + ); >> + if (EFI_ERROR (Status)) { >> + Status =3D EFI_OUT_OF_RESOURCES; >> + goto Done; >> + } >> + >> + Status =3D gBS->CreateEvent ( >> + EVT_NOTIFY_SIGNAL, >> + TPL_CALLBACK, >> + KeyNotifyProcessHandler, >> + VirtualKeyboardPrivate, >> + &VirtualKeyboardPrivate->KeyNotifyProcessEvent >> + ); >> + if (EFI_ERROR (Status)) { >> + Status =3D EFI_OUT_OF_RESOURCES; >> + goto Done; >> + } >> + >> + // >> + // Reset the keyboard device >> + // >> + Status =3D VirtualKeyboardPrivate->SimpleTextInputEx.Reset ( >> + &VirtualKeyboardPri= vate->SimpleTextInputEx, >=20 > Funky indentation. > According to coding style, it's missing 3 spaces. >=20 OK >> + FALSE >> + ); >> + if (EFI_ERROR (Status)) { >> + DEBUG ((EFI_D_ERROR, "[KBD]Reset Failed. Status - %r\n", Status)); >=20 > Use DEBUG_ERROR (PatchCheck.py warns about this). >=20 OK >> +VOID >> +EFIAPI >> +VirtualKeyboardWaitForKey ( >> + IN EFI_EVENT Event, >> + IN VOID *Context >> + ) >> +{ >> + // >> + // Stall 1ms to give a chance to let other driver interrupt this rout= ine for their timer event. >> + // Csm will be used to check whether there is a key pending, but the = csm will disable all >=20 > 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. >=20 OK >> + // interrupt before switch to compatibility16, which mean all the efi= Compatibility timer >> + // event will stop work during the compatibility16. And If a caller r= ecursivly invoke this function, >> + // e.g. UI setup or Shell, other drivers which are driven by timer ev= ent will have a bad performance during this period, >> + // e.g. usb keyboard driver. >> + // Add a stall period can greatly increate other driver performance d= uring the WaitForKey is recursivly invoked. >> + // 1ms delay will make little impact to the thunk keyboard driver, an= d 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 (Co= ntext)); >> + >> + if (!EFI_ERROR (VirtualKeyboardCheckForKey (Context))) { >> + gBS->SignalEvent (Event); >> + } >> +} >> + >> +/** >> + Event notification function for SIMPLE_TEXT_INPUT_EX_PROTOCOL.WaitFor= KeyEx 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 =3D TEXT_INPUT_EX_VIRTUAL_KEYBOARD_DEV_FROM_TH= IS (Context); >> + VirtualKeyboardWaitForKey (Event, &VirtualKeyboardPrivate->SimpleText= In); >> + >> +} >> + >> +// >> +// EFI Simple Text In Protocol Functions >> +// >> +/** >> + Reset the Keyboard and do BAT test for it, if (ExtendedVerification = =3D=3D TRUE) then do some extra keyboard validations. >=20 > There are a few really long lines in this patch. Please try to keep > to no more than 80 characters were feasible. Applies throughout. >=20 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 successfull= y. >> + @retval EFI_DEVICE_ERROR Errors occurred during resetting keyboa= rd. >> + >> +**/ >> +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 =3D VIRTUAL_KEYBOARD_DEV_FROM_THIS (This); >> + >> + // >> + // Raise TPL to avoid mouse operation impact >> + // >> + OldTpl =3D gBS->RaiseTPL (TPL_NOTIFY); >> + >> + if (VirtualKeyboardPrivate->PlatformVirtual && VirtualKeyboardPrivate= ->PlatformVirtual->Reset) { >=20 > if (VirtualKeyboardPrivate->PlatformVirtual && > VirtualKeyboardPrivate->PlatformVirtual->Reset) { >=20 > And so on. >=20 OK >> + Status =3D VirtualKeyboardPrivate->PlatformVirtual->Reset (); >> + } else { >> + Status =3D 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; >=20 > Spacing does not match subsequent lines. >=20 >> + EFI_STATUS Status; >> + EFI_TPL OldTpl; >> + >> + VirtualKeyboardPrivate =3D TEXT_INPUT_EX_VIRTUAL_KEYBOARD_DEV_FROM_TH= IS (This); >> + >> + Status =3D VirtualKeyboardPrivate->SimpleTextIn.Reset ( >> + &VirtualKeyboardPrivate-= >SimpleTextIn, >=20 > Funky indentation. >=20 >> + ExtendedVerification >> + ); >> + if (EFI_ERROR (Status)) { >> + return EFI_DEVICE_ERROR; >> + } >> + >> + OldTpl =3D 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 struc= ture. >> + @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 retur= ned 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 =3D=3D 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 rout= ine 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 efi= Compatibility timer >> + // event will stop work during the compatibility16. And If a caller r= ecursivly 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 d= uring the WaitForKey is recursivly invoked. >> + // 1ms delay will make little impact to the thunk keyboard driver, an= d user can not feel the delay at all when input. >> + // >> + gBS->Stall (1000); >> + >> + OldTpl =3D gBS->RaiseTPL (TPL_NOTIFY); >> + >> + VirtualKeyboardTimerHandler (NULL, VirtualKeyboardPrivate); >> + // >> + // If there's no key, just return >> + // >> + Status =3D CheckQueue (&VirtualKeyboardPrivate->Queue); >> + if (EFI_ERROR (Status)) { >> + gBS->RestoreTPL (OldTpl); >> + return EFI_NOT_READY; >> + } >> + >> + Status =3D 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 =3D VIRTUAL_KEYBOARD_DEV_FROM_THIS (This); >> + >> + Status =3D KeyboardReadKeyStrokeWorker (VirtualKeyboardPrivate, &KeyD= ata); >> + 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)) !=3D 0) { >> + if (KeyData.Key.UnicodeChar >=3D L'a' && KeyData.Key.UnicodeChar <= =3D L'z') { >> + KeyData.Key.UnicodeChar =3D (CHAR16) (KeyData.Key.UnicodeChar - L= 'a' + 1); >> + } else if (KeyData.Key.UnicodeChar >=3D L'A' && KeyData.Key.Unicode= Char <=3D L'Z') { >> + KeyData.Key.UnicodeChar =3D (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 retu= rned 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 =3D=3D NULL) { >> + return EFI_INVALID_PARAMETER; >> + } >> + >> + VirtualKeyboardPrivate =3D TEXT_INPUT_EX_VIRTUAL_KEYBOARD_DEV_FROM_TH= IS (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 se= t 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 =3D=3D NULL) { >> + return EFI_INVALID_PARAMETER; >> + } >> + >> + // >> + // Thunk keyboard driver doesn't support partial keystroke. >> + // >> + if ((*KeyToggleState & EFI_TOGGLE_STATE_VALID) !=3D EFI_TOGGLE_STATE_= VALID || >> + (*KeyToggleState & EFI_KEY_STATE_EXPOSED) =3D=3D EFI_KEY_STATE_EX= POSED >> + ) { >> + return EFI_UNSUPPORTED; >> + } >> + >=20 > 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? >=20 OK. I'll change it. >> + return EFI_SUCCESS; >> +} >> + >> +/** >> + Register a notification function for a particular keystroke for the i= nput 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 w= hen the key >> + sequence is typed specified by KeyDat= a. >> + @param NotifyHandle Points to the unique handle assigned = to the registered notification. >> + >> + >> + @retval EFI_SUCCESS The notification function was registe= red successfully. >> + @retval EFI_OUT_OF_RESOURCES Unable to allocate resources for nece= sssary 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 =3D=3D NULL || NotifyHandle =3D=3D NULL || KeyNotificatio= nFunction =3D=3D NULL) { >> + return EFI_INVALID_PARAMETER; >> + } >> + >> + VirtualKeyboardPrivate =3D TEXT_INPUT_EX_VIRTUAL_KEYBOARD_DEV_FROM_TH= IS (This); >> + >> + // >> + // Enter critical section >> + // >> + OldTpl =3D gBS->RaiseTPL (TPL_NOTIFY); >> + >> + // >> + // Return EFI_SUCCESS if the (KeyData, NotificationFunction) is alrea= dy registered. >> + // >> + for (Link =3D VirtualKeyboardPrivate->NotifyList.ForwardLink; Link != =3D &VirtualKeyboardPrivate->NotifyList; Link =3D Link->ForwardLink) { >> + CurrentNotify =3D CR ( >> + Link, >> + VIRTUAL_KEYBOARD_CONSOLE_IN_EX_NOTIFY, >> + NotifyEntry, >> + VIRTUAL_KEYBOARD_CONSOLE_IN_EX_NOTIFY_SIGNATURE >> + ); >> + if (IsKeyRegistered (&CurrentNotify->KeyData, KeyData)) { >> + if (CurrentNotify->KeyNotificationFn =3D=3D KeyNotificationFuncti= on) { >> + *NotifyHandle =3D CurrentNotify; >> + Status =3D EFI_SUCCESS; >> + goto Exit; >> + } >> + } >> + } >> + >> + // >> + // Allocate resource to save the notification function >> + // >> + >> + NewNotify =3D (VIRTUAL_KEYBOARD_CONSOLE_IN_EX_NOTIFY *) AllocateZeroP= ool (sizeof (VIRTUAL_KEYBOARD_CONSOLE_IN_EX_NOTIFY)); >> + if (NewNotify =3D=3D NULL) { >> + Status =3D EFI_OUT_OF_RESOURCES; >> + goto Exit; >> + } >> + >> + NewNotify->Signature =3D VIRTUAL_KEYBOARD_CONSOLE_IN_EX_NOTIF= Y_SIGNATURE; >> + NewNotify->KeyNotificationFn =3D KeyNotificationFunction; >> + CopyMem (&NewNotify->KeyData, KeyData, sizeof (EFI_KEY_DATA)); >> + InsertTailList (&VirtualKeyboardPrivate->NotifyList, &NewNotify->Noti= fyEntry); >> + >> + *NotifyHandle =3D NewNotify; >> + Status =3D 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 unregis= tered 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 =3D=3D NULL) { >> + return EFI_INVALID_PARAMETER; >> + } >> + >> + if (((VIRTUAL_KEYBOARD_CONSOLE_IN_EX_NOTIFY *) NotificationHandle)->S= ignature !=3D VIRTUAL_KEYBOARD_CONSOLE_IN_EX_NOTIFY_SIGNATURE) { >> + return EFI_INVALID_PARAMETER; >> + } >> + >> + VirtualKeyboardPrivate =3D TEXT_INPUT_EX_VIRTUAL_KEYBOARD_DEV_FROM_TH= IS (This); >> + >> + // >> + // Enter critical section >> + // >> + OldTpl =3D gBS->RaiseTPL (TPL_NOTIFY); >> + >> + for (Link =3D VirtualKeyboardPrivate->NotifyList.ForwardLink; Link != =3D &VirtualKeyboardPrivate->NotifyList; Link =3D Link->ForwardLink) { >> + CurrentNotify =3D CR ( >> + Link, >> + VIRTUAL_KEYBOARD_CONSOLE_IN_EX_NOTIFY, >> + NotifyEntry, >> + VIRTUAL_KEYBOARD_CONSOLE_IN_EX_NOTIFY_SIGNATURE >> + ); >> + if (CurrentNotify =3D=3D NotificationHandle) { >> + // >> + // Remove the notification function from NotifyList and free reso= urces >> + // >> + RemoveEntryList (&CurrentNotify->NotifyEntry); >> + >> + Status =3D EFI_SUCCESS; >> + goto Exit; >> + } >> + } >> + >> + // >> + // Can not find the specified Notification Handle >> + // >> + Status =3D 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; >=20 > Please make these variable names line up with the ones below. >=20 >> + VIRTUAL_KEYBOARD_CONSOLE_IN_EX_NOTIFY *CurrentNotify; >> + VIRTUAL_KEYBOARD_DEV *VirtualKeyboardPrivate; >> + VIRTUAL_KBD_KEY VirtualKey; >> + >> + VirtualKeyboardPrivate =3D Context; >> + >> + // >> + // Enter critical section >> + // >> + OldTpl =3D gBS->RaiseTPL (TPL_NOTIFY); >> + >> + if (VirtualKeyboardPrivate->PlatformVirtual && >> + VirtualKeyboardPrivate->PlatformVirtual->Query) { >> + if (VirtualKeyboardPrivate->PlatformVirtual->Query (&VirtualKey) = =3D=3D FALSE) { >> + goto Exit; >> + } >> + // Found key >> + KeyData.Key.ScanCode =3D VirtualKey.Key.ScanCode; >> + KeyData.Key.UnicodeChar =3D VirtualKey.Key.UnicodeChar; >> + KeyData.KeyState.KeyShiftState =3D EFI_SHIFT_STATE_VALID; >> + KeyData.KeyState.KeyToggleState =3D 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 =3D VirtualKeyboardPrivate->NotifyList.ForwardLink; Link != =3D &VirtualKeyboardPrivate->NotifyList; Link =3D Link->ForwardLink) { >> + CurrentNotify =3D 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 fu= nction. >> + @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; >=20 > Please make variable names line up. >=20 >> + >> + VirtualKeyboardPrivate =3D (VIRTUAL_KEYBOARD_DEV *) Context; >> + >> + // >> + // Invoke notification functions. >> + // >> + NotifyList =3D &VirtualKeyboardPrivate->NotifyList; >> + while (TRUE) { >> + // >> + // Enter critical section >> + // >> + OldTpl =3D gBS->RaiseTPL (TPL_NOTIFY); >> + Status =3D Dequeue (&VirtualKeyboardPrivate->QueueForNotify, &KeyDa= ta); >> + // >> + // Leave critical section >> + // >> + gBS->RestoreTPL (OldTpl); >> + if (EFI_ERROR (Status)) { >> + break; >> + } >> + for (Link =3D GetFirstNode (NotifyList); !IsNull (NotifyList, Link)= ; Link =3D GetNextNode (NotifyList, Link)) { >> + CurrentNotify =3D 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 i= mage. >> + @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 =3D 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.
>> +Copyright (c) 2018, Linaro Ltd. 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 IM= PLIED. >> + >> +**/ >> + >> +#ifndef _VIRTUAL_KEYBOARD_H_ >> +#define _VIRTUAL_KEYBOARD_H_ >> + >> + >> +#include >> +#include >> +#include >> +#include >> +#include >> + >> +#include >> +#include >> +#include >> +#include >> +#include >> +#include >> +#include >> +#include >> +#include >> +#include >> + >> +// >> +// 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 speci= fic child >> + device to start. >> + >> + @retval EFI_SUCCESS The controller is controlled by the dr= iver. >> + @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 ChildHandleBu= ffer. >> + @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 o= n 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 driv= er. >> + >> + This function retrieves the user readable name of a driver in the for= m of a >> + Unicode string. If the driver specified by This has a user readable n= ame 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 sp= ecified >> + 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_PR= OTOCOL or >> + EFI_COMPONENT_NAME_PROTOCOL instance. >> + >> + @param Language[in] A pointer to a Null-terminated ASCII st= ring >> + array indicating the language. This is = the >> + language of the driver name that the ca= ller is >> + requesting, and it must match one of th= e >> + languages specified in SupportedLanguag= es. The >> + number of languages supported by a driv= er is up >> + to the driver writer. Language is speci= fied >> + in RFC 4646 or ISO 639-2 language code = format. >> + >> + @param DriverName[out] A pointer to the Unicode string to retu= rn. >> + This Unicode string is the name of the >> + driver specified by This in the languag= e >> + specified by Language. >> + >> + @retval EFI_SUCCESS The Unicode string for the Driver speci= fied by >> + This and the language specified by Lang= uage 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 s= upport >> + 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 cont= roller >> + that is being managed by a driver. >> + >> + This function retrieves the user readable name of the controller spec= ified 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 spe= cified by >> + Language, then a pointer to the controller name is returned in Contro= llerName, >> + 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 do= es not >> + support the language specified by Language, then EFI_UNSUPPORTED is r= eturned. >> + >> + @param This[in] A pointer to the EFI_COMPONENT_NAME2_PR= OTOCOL or >> + EFI_COMPONENT_NAME_PROTOCOL instance. >> + >> + @param ControllerHandle[in] The handle of a controller that the dri= ver >> + specified by This is managing. This ha= ndle >> + specifies the controller whose name is = to be >> + returned. >> + >> + @param ChildHandle[in] The handle of the child controller to r= etrieve >> + the name of. This is an optional param= eter that >> + may be NULL. It will be NULL for devic= e >> + drivers. It will also be NULL for a bu= s drivers >> + that wish to retrieve the name of the b= us >> + 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 st= ring >> + array indicating the language. This is= the >> + language of the driver name that the ca= ller is >> + requesting, and it must match one of th= e >> + languages specified in SupportedLanguag= es. The >> + number of languages supported by a driv= er is up >> + to the driver writer. Language is speci= fied in >> + RFC 4646 or ISO 639-2 language code for= mat. >> + >> + @param ControllerName[out] A pointer to the Unicode string to retu= rn. >> + This Unicode string is the name of the >> + controller specified by ControllerHandl= e and >> + ChildHandle in the language specified b= y >> + Language from the point of view of the = driver >> + specified by This. >> + >> + @retval EFI_SUCCESS The Unicode string for the user readabl= e name in >> + the language specified by Language for = the >> + driver specified by This was returned i= n >> + DriverName. >> + >> + @retval EFI_INVALID_PAVIRTUALETER ControllerHandle is NULL. >> + >> + @retval EFI_INVALID_PAVIRTUALETER ChildHandle is not NULL and it is n= ot 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 cur= rently >> + managing the controller specified by >> + ControllerHandle and ChildHandle. >> + >> + @retval EFI_UNSUPPORTED The driver specified by This does not s= upport >> + 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 = =3D=3D 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 successfull= y. >> + @retval EFI_DEVICE_ERROR Errors occurred during resetting keyboa= rd. >> + >> +**/ >> +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 >=20 > Trailing whitespace. (PatchCheck.py warns about this.) >=20 >> + 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 se= t 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 i= nput 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 w= hen the key >> + sequence is typed specified by KeyDat= a. >> + @param NotifyHandle Points to the unique handle assigned = to the registered notification. >> + >> + >> + @retval EFI_SUCCESS The notification function was registe= red successfully. >> + @retval EFI_OUT_OF_RESOURCES Unable to allocate resources for nece= sssary 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 unregis= tered 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 wit= h the keystroke >> + state data for the key that was registered. >> + @param InputData A pointer to a buffer that is filled in wit= h 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_PRO= TOCOL. >> + >> +**/ >> +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 st= roked. >> + @param Context Pointer of the protocol EFI_SIMPLE_TEXT_INPUT_EX_PRO= TOCOL. >> + >> +**/ >> +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 fu= nction. >> + @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 retu= rned 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.d= ec b/EmbeddedPkg/Drivers/VirtualKeyboardDxe/VirtualKeyboardDxe.dec >> new file mode 100644 >> index 0000000..065f4f2 >> --- /dev/null >> +++ b/EmbeddedPkg/Drivers/VirtualKeyboardDxe/VirtualKeyboardDxe.dec >=20 > 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. >=20 >> @@ -0,0 +1,39 @@ >> +#/** @file >> +# Framework Module Development Environment Industry Standards >> +# >> +# This Package provides headers and libraries that conform to EFI/PI In= dustry standards. >> +# Copyright (c) 2007, Intel Corporation. All rights reserved.
>> +# Copyright (c) 2012-2014, ARM Ltd. All rights reserved.
>> +# 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" BAS= IS, >> +# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS = OR IMPLIED. >> +# >> +#**/ >> + >> +[Defines] >> + DEC_SPECIFICATION =3D 0x00010019 >> + PACKAGE_NAME =3D VirtualKeyboardDxePkg >> + PACKAGE_GUID =3D 774326bc-20d0-4203-97e4-10dc17f7dc= 1a >> + PACKAGE_VERSION =3D 0.1 >> + >> +#######################################################################= ######### >> +# >> +# Include Section - list of Include Paths that are provided by this pac= kage. >> +# Comments are used for Keywords and Module Types. >> +# >> +# Supported Module Types: >> +# BASE SEC PEI_CORE PEIM DXE_CORE DXE_DRIVER DXE_RUNTIME_DRIVER DXE_SM= M_DRIVER DXE_SAL_DRIVER UEFI_DRIVER UEFI_APPLICATION >> +# >> +#######################################################################= ######### >> + >> +[Guids.common] >> + gVirtualKeyboardDxeTokenSpaceGuid =3D { 0x80caf901, 0x0cf6, 0x4c09= , { 0x89, 0x84, 0x61, 0xd1, 0xf3, 0xd2, 0x54, 0x39 }} >> + >> +[Protocols.common] >> + gPlatformVirtualKeyboardProtocolGuid =3D { 0x0e3606d2, 0x1dc3, 0x4e6f= , { 0xbe, 0x65, 0x39, 0x49, 0x82, 0xa2, 0x65, 0x47 }} >> diff --git a/EmbeddedPkg/Drivers/VirtualKeyboardDxe/VirtualKeyboardDxe.i= nf 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.
>> +# >> +# 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 =3D 0x00010019 >> + BASE_NAME =3D VirtualKeyboardDxe >> + FILE_GUID =3D 88079b18-b42b-44aa-a6f2-b83911075e= 89 >> + MODULE_TYPE =3D UEFI_DRIVER >> + VERSION_STRING =3D 1.0 >> + ENTRY_POINT =3D InitializeVirtualKeyboard >> + >> +# >> +# The following information is for reference only and not required by t= he build tools. >> +# >> +# VALID_ARCHITECTURES =3D AARCH64 >=20 > Well, it's emulated, so I would hope it's valid for all architectures? >=20 OK Best Regards Haojian