From nobody Thu May 2 15:49:39 2024 Delivered-To: importer@patchew.org Authentication-Results: mx.zohomail.com; dkim=fail; spf=none (zoho.com: 198.145.21.10 is neither permitted nor denied by domain of lists.01.org) smtp.mailfrom=edk2-devel-bounces@lists.01.org; dmarc=fail(p=none dis=none) header.from=linaro.org Return-Path: Received: from ml01.01.org (ml01.01.org [198.145.21.10]) by mx.zohomail.com with SMTPS id 1519635177607418.7809417047014; Mon, 26 Feb 2018 00:52:57 -0800 (PST) Received: from [127.0.0.1] (localhost [IPv6:::1]) by ml01.01.org (Postfix) with ESMTP id 089EE209574E7; Mon, 26 Feb 2018 00:46:46 -0800 (PST) Received: from mail-pl0-x232.google.com (mail-pl0-x232.google.com [IPv6:2607:f8b0:400e:c01::232]) (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 A8714209574C5 for ; Mon, 26 Feb 2018 00:46:44 -0800 (PST) Received: by mail-pl0-x232.google.com with SMTP id v9-v6so6890773plp.12 for ; Mon, 26 Feb 2018 00:52:49 -0800 (PST) Received: from localhost.localdomain ([64.64.108.97]) by smtp.gmail.com with ESMTPSA id c185sm3817246pfb.72.2018.02.26.00.52.42 (version=TLS1_2 cipher=ECDHE-RSA-AES128-SHA bits=128/128); Mon, 26 Feb 2018 00:52:46 -0800 (PST) X-Original-To: edk2-devel@lists.01.org Received-SPF: none (zoho.com: 198.145.21.10 is neither permitted nor denied by domain of lists.01.org) client-ip=198.145.21.10; envelope-from=edk2-devel-bounces@lists.01.org; helo=ml01.01.org; Received-SPF: Pass (sender SPF authorized) identity=mailfrom; client-ip=2607:f8b0:400e:c01::232; helo=mail-pl0-x232.google.com; envelope-from=haojian.zhuang@linaro.org; receiver=edk2-devel@lists.01.org DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; h=from:to:cc:subject:date:message-id; bh=rRgARgXQF5ENnkLJX1kljMvmquWXq3WjoV40HqQubYM=; b=GOhd2NARBIU6FIjtDIfuSX5HSika7Ty6N8peKYA9273iJGI0SwALHhxoeoNEtsvOHN hx15ORqVH0aNva0oWjgKbKk62XSYgCJ8Qlg+IC1X1wTPQzl/vsfiYKISVeMBKXa5+DCk 1mJRhNbWrg42df/3Xxwe4wNT9S4rtFSWP6cgY= 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:date:message-id; bh=rRgARgXQF5ENnkLJX1kljMvmquWXq3WjoV40HqQubYM=; b=IlC8kYJ+4mw1jZ/r+io3KHG/p2AIRA86SNJTZqrFmm5BJ6EFquE6qSn2PZBC34S0aI NIBTaB64pmIZ9SxY71k2FrH2y8I1rvW9q8i7QmSwEetLQ9DfQb2i7/n7QLFXDOedOota yCW70xeg42FoopTA9K866WHVM2Bs7KrK9UORrZRTBqg2iUtaaytskhvx7CBfdrARBQJa weyc7yc1sTtGEryfG2pgeil4L6c78lJ+vfRGtngoJfrjbeNsIhoKEYctudmFe/DNi2/M Yrw9yEqwXDkxpx6f/dvYC/2gOv0kOGr+r/WL7PgyIZg/nlhemc08am1PTx1Cm+b8az1R NFeg== X-Gm-Message-State: APf1xPCwoHmmZn7WZ+lnZYDleHSzbqxVxF/ZWeG7ti26G2ZLjig2gnB6 FuqXGcBD+N4KdrlF05xIqTTAgw== X-Google-Smtp-Source: AH8x226KBL+NIztyDnGzJShEsQRyuoW1kllRcdO11jfzpyjt2A0iEZ7CdmkggrQzhgqA18rJokR8jA== X-Received: by 2002:a17:902:8341:: with SMTP id z1-v6mr10113627pln.386.1519635167351; Mon, 26 Feb 2018 00:52:47 -0800 (PST) From: Haojian Zhuang To: leif.lindholm@linaro.org, ard.biesheuvel@linaro.org, linaro-uefi@lists.linaro.org, edk2-devel@lists.01.org Date: Mon, 26 Feb 2018 16:52:36 +0800 Message-Id: <1519635156-21954-1-git-send-email-haojian.zhuang@linaro.org> X-Mailer: git-send-email 2.7.4 Subject: [edk2] [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: , Cc: Haojian Zhuang MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Errors-To: edk2-devel-bounces@lists.01.org Sender: "edk2-devel" X-ZohoMail-DKIM: fail (Header signature does not verify) X-ZohoMail: RDKM_2 RSF_4 Z_629925259 SPT_0 Content-Type: text/plain; charset="utf-8" The virtual keyboard could simulate a keyboard. User could simulate a key value when pattern is matched. 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 ++ 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/VirtualKeyboardD= xe.dec create mode 100644 EmbeddedPkg/Drivers/VirtualKeyboardDxe/VirtualKeyboardD= xe.inf create mode 100644 EmbeddedPkg/Include/Protocol/PlatformVirtualKeyboard.h diff --git a/EmbeddedPkg/Drivers/VirtualKeyboardDxe/ComponentName.c b/Embed= dedPkg/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 IMPLI= ED. + +**/ + +#include "VirtualKeyboard.h" + +// +// EFI Component Name Protocol +// +GLOBAL_REMOVE_IF_UNREFERENCED EFI_COMPONENT_NAME_PROTOCOL gVirtualKeyboar= dComponentName =3D { + VirtualKeyboardComponentNameGetDriverName, + VirtualKeyboardComponentNameGetControllerName, + "eng" +}; + +// +// EFI Component Name 2 Protocol +// +GLOBAL_REMOVE_IF_UNREFERENCED EFI_COMPONENT_NAME2_PROTOCOL gVirtualKeyboar= dComponentName2 =3D { + (EFI_COMPONENT_NAME2_GET_DRIVER_NAME) VirtualKeyboardComponentNameGetDri= verName, + (EFI_COMPONENT_NAME2_GET_CONTROLLER_NAME) VirtualKeyboardComponentNameGe= tControllerName, + "en" +}; + + +GLOBAL_REMOVE_IF_UNREFERENCED EFI_UNICODE_STRING_TABLE mVirtualKeyboardDri= verNameTable[] =3D { + { + "eng;en", + L"RAM Keyboard Driver" + }, + { + NULL, + NULL + } +}; + +/** + Retrieves a Unicode string that is the user readable name of the driver. + + This function retrieves the user readable name of a driver in the form o= f 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 speci= fied + 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_PROTO= COL 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 calle= r 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 for= mat. + + @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 specifie= d by + This and the language specified by Languag= e was + returned in DriverName. + + @retval EFI_INVALID_PARAMETER Language is NULL. + + @retval EFI_INVALID_PARAMETER DriverName is NULL. + + @retval EFI_UNSUPPORTED The driver specified by This does not supp= ort + the language specified by Language. + +**/ +EFI_STATUS +EFIAPI +VirtualKeyboardComponentNameGetDriverName ( + IN EFI_COMPONENT_NAME_PROTOCOL *This, + IN CHAR8 *Language, + OUT CHAR16 **DriverName + ) +{ + return LookupUnicodeString2 ( + Language, + This->SupportedLanguages, + mVirtualKeyboardDriverNameTable, + DriverName, + (BOOLEAN)(This =3D=3D &gVirtualKeyboardComponentName) + ); +} + +/** + Retrieves a Unicode string that is the user readable name of the control= ler + that is being managed by a driver. + + This function retrieves the user readable name of the controller specifi= ed 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 specif= ied by + Language, then a pointer to the controller name is returned in Controlle= rName, + and EFI_SUCCESS is returned. If the driver specified by This is not cur= rently + 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 retu= rned. + + @param This[in] A pointer to the EFI_COMPONENT_NAME2_PROTO= COL 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 retr= ieve + the name of. This is an optional paramete= r that + may be NULL. It will be NULL for device + drivers. It will also be NULL for a bus d= rivers + 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 calle= r 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 specifie= d 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 a= nd + ChildHandle in the language specified by + Language from the point of view of the dri= ver + specified by This. + + @retval EFI_SUCCESS The Unicode string for the user readable n= ame in + the language specified by Language for the + driver specified by This was returned in + DriverName. + + @retval EFI_INVALID_PARAMETER ControllerHandle is NULL. + + @retval EFI_INVALID_PARAMETER ChildHandle is not NULL and it is not a va= lid + EFI_HANDLE. + + @retval EFI_INVALID_PARAMETER Language is NULL. + + @retval EFI_INVALID_PARAMETER ControllerName is NULL. + + @retval EFI_UNSUPPORTED The driver specified by This is not curren= tly + managing the controller specified by + ControllerHandle and ChildHandle. + + @retval EFI_UNSUPPORTED The driver specified by This does not supp= ort + the language specified by Language. + +**/ +EFI_STATUS +EFIAPI +VirtualKeyboardComponentNameGetControllerName ( + IN EFI_COMPONENT_NAME_PROTOCOL *This, + IN EFI_HANDLE ControllerHandle, + IN EFI_HANDLE ChildHandle O= PTIONAL, + IN CHAR8 *Language, + OUT CHAR16 **ControllerName + ) +{ + return EFI_UNSUPPORTED; +} diff --git a/EmbeddedPkg/Drivers/VirtualKeyboardDxe/ComponentName.h b/Embed= dedPkg/Drivers/VirtualKeyboardDxe/ComponentName.h new file mode 100644 index 0000000..94bef28 --- /dev/null +++ b/EmbeddedPkg/Drivers/VirtualKeyboardDxe/ComponentName.h @@ -0,0 +1,154 @@ +/** @file + +Copyright (c) 2006 - 2011, Intel Corporation. All rights reserved.
+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 IMPLI= ED. + +**/ + +#ifndef _VIRTUAL_KEYBOARD_COMPONENT_NAME_H_ +#define _VIRTUAL_KEYBOARD_COMPONENT_NAME_H_ + + +extern EFI_COMPONENT_NAME_PROTOCOL gVirtualKeyboardComponentName; +extern EFI_COMPONENT_NAME2_PROTOCOL gVirtualKeyboardComponentName2; + +// +// EFI Component Name Functions +// +/** + Retrieves a Unicode string that is the user readable name of the driver. + + This function retrieves the user readable name of a driver in the form o= f 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 speci= fied + 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_PROTO= COL 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 calle= r 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 for= mat. + + @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 specifie= d by + This and the language specified by Languag= e was + returned in DriverName. + + @retval EFI_INVALID_PARAMETER Language is NULL. + + @retval EFI_INVALID_PARAMETER DriverName is NULL. + + @retval EFI_UNSUPPORTED The driver specified by This does not supp= ort + 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 control= ler + that is being managed by a driver. + + This function retrieves the user readable name of the controller specifi= ed 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 specif= ied by + Language, then a pointer to the controller name is returned in Controlle= rName, + and EFI_SUCCESS is returned. If the driver specified by This is not cur= rently + 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 retu= rned. + + @param This[in] A pointer to the EFI_COMPONENT_NAME2_PROTO= COL 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 retr= ieve + the name of. This is an optional paramete= r that + may be NULL. It will be NULL for device + drivers. It will also be NULL for a bus d= rivers + 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 calle= r 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 specifie= d 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 a= nd + ChildHandle in the language specified by + Language from the point of view of the dri= ver + specified by This. + + @retval EFI_SUCCESS The Unicode string for the user readable n= ame in + the language specified by Language for the + driver specified by This was returned in + DriverName. + + @retval EFI_INVALID_PARAMETER ControllerHandle is NULL. + + @retval EFI_INVALID_PARAMETER ChildHandle is not NULL and it is not a va= lid + EFI_HANDLE. + + @retval EFI_INVALID_PARAMETER Language is NULL. + + @retval EFI_INVALID_PARAMETER ControllerName is NULL. + + @retval EFI_UNSUPPORTED The driver specified by This is not curren= tly + managing the controller specified by + ControllerHandle and ChildHandle. + + @retval EFI_UNSUPPORTED The driver specified by This does not supp= ort + the language specified by Language. + +**/ +EFI_STATUS +EFIAPI +VirtualKeyboardComponentNameGetControllerName ( + IN EFI_COMPONENT_NAME_PROTOCOL *This, + IN EFI_HANDLE ControllerHandle, + IN EFI_HANDLE ChildHandle O= PTIONAL, + IN CHAR8 *Language, + OUT CHAR16 **ControllerName + ); + + +#endif diff --git a/EmbeddedPkg/Drivers/VirtualKeyboardDxe/VirtualKeyboard.c b/Emb= eddedPkg/Drivers/VirtualKeyboardDxe/VirtualKeyboard.c new file mode 100644 index 0000000..b2c84ba --- /dev/null +++ b/EmbeddedPkg/Drivers/VirtualKeyboardDxe/VirtualKeyboard.c @@ -0,0 +1,1117 @@ +/** @file + VirtualKeyboard driver + +Copyright (c) 2006 - 2016, Intel Corporation. All rights reserved.
+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 IMPLI= ED. + +**/ + +#include "VirtualKeyboard.h" + +// +// RAM Keyboard Driver Binding Protocol Instance +// +EFI_DRIVER_BINDING_PROTOCOL gVirtualKeyboardDriverBinding =3D { + VirtualKeyboardDriverBindingSupported, + VirtualKeyboardDriverBindingStart, + VirtualKeyboardDriverBindingStop, + 0x10, + NULL, + NULL +}; + +// +// EFI Driver Binding Protocol Functions +// + +/** + Check whether the driver supports this device. + + @param This The Udriver binding protocol. + @param Controller The controller handle to check. + @param RemainingDevicePath The remaining device path. + + @retval EFI_SUCCESS The driver supports this controller. + @retval other This device isn't supported. + +**/ +EFI_STATUS +EFIAPI +VirtualKeyboardDriverBindingSupported ( + IN EFI_DRIVER_BINDING_PROTOCOL *This, + IN EFI_HANDLE Controller, + IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath + ) +{ + EFI_STATUS Status; + PLATFORM_VIRTUAL_KBD_PROTOCOL *PlatformVirtual; + + Status =3D gBS->OpenProtocol ( + Controller, + &gPlatformVirtualKeyboardProtocolGuid, + (VOID **) &PlatformVirtual, + This->DriverBindingHandle, + Controller, + EFI_OPEN_PROTOCOL_BY_DRIVER + ); + if (EFI_ERROR (Status)) { + return Status; + } + gBS->CloseProtocol ( + Controller, + &gPlatformVirtualKeyboardProtocolGuid, + This->DriverBindingHandle, + Controller + ); + return Status; +} + +/** + Starts the device with this driver. + + @param This The driver binding instance. + @param Controller Handle of device to bind driver to. + @param RemainingDevicePath Optional parameter use to pick a specific= child + device to start. + + @retval EFI_SUCCESS The controller is controlled by the drive= r. + @retval Other This controller cannot be started. + +**/ +EFI_STATUS +EFIAPI +VirtualKeyboardDriverBindingStart ( + IN EFI_DRIVER_BINDING_PROTOCOL *This, + IN EFI_HANDLE Controller, + IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath + ) +{ + EFI_STATUS Status; + VIRTUAL_KEYBOARD_DEV *VirtualKeyboardPrivate; + PLATFORM_VIRTUAL_KBD_PROTOCOL *PlatformVirtual; + + Status =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 (si= zeof (VIRTUAL_KEYBOARD_DEV)); + if (NULL =3D=3D VirtualKeyboardPrivate) { + Status =3D EFI_OUT_OF_RESOURCES; + goto Done; + } + + // + // Initialize the private device structure + // + VirtualKeyboardPrivate->Signature =3D VIRTUAL_KEYBOARD_= DEV_SIGNATURE; + VirtualKeyboardPrivate->Handle =3D Controller; + VirtualKeyboardPrivate->PlatformVirtual =3D PlatformVirtual; + VirtualKeyboardPrivate->Queue.Front =3D 0; + VirtualKeyboardPrivate->Queue.Rear =3D 0; + VirtualKeyboardPrivate->QueueForNotify.Front =3D 0; + VirtualKeyboardPrivate->QueueForNotify.Rear =3D 0; + + VirtualKeyboardPrivate->SimpleTextIn.Reset =3D VirtualKeyboardRe= set; + VirtualKeyboardPrivate->SimpleTextIn.ReadKeyStroke =3D VirtualKeyboardRe= adKeyStroke; + + VirtualKeyboardPrivate->SimpleTextInputEx.Reset =3D Virtua= lKeyboardResetEx; + VirtualKeyboardPrivate->SimpleTextInputEx.ReadKeyStrokeEx =3D Virtua= lKeyboardReadKeyStrokeEx; + VirtualKeyboardPrivate->SimpleTextInputEx.SetState =3D Virtua= lKeyboardSetState; + + VirtualKeyboardPrivate->SimpleTextInputEx.RegisterKeyNotify =3D Virtua= lKeyboardRegisterKeyNotify; + VirtualKeyboardPrivate->SimpleTextInputEx.UnregisterKeyNotify =3D Virtua= lKeyboardUnregisterKeyNotify; + InitializeListHead (&VirtualKeyboardPrivate->NotifyList); + + Status =3D PlatformVirtual->Register (); + if (EFI_ERROR (Status)) { + goto Done; + } + + // + // Report that the keyboard is being enabled + // + REPORT_STATUS_CODE ( + EFI_PROGRESS_CODE, + EFI_PERIPHERAL_KEYBOARD | EFI_P_PC_ENABLE + ); + + // + // Setup the WaitForKey event + // + Status =3D gBS->CreateEvent ( + EVT_NOTIFY_WAIT, + TPL_NOTIFY, + VirtualKeyboardWaitForKey, + &(VirtualKeyboardPrivate->SimpleTextIn), + &((VirtualKeyboardPrivate->SimpleTextIn).WaitForKey) + ); + if (EFI_ERROR (Status)) { + (VirtualKeyboardPrivate->SimpleTextIn).WaitForKey =3D NULL; + goto Done; + } + Status =3D gBS->CreateEvent ( + EVT_NOTIFY_WAIT, + TPL_NOTIFY, + VirtualKeyboardWaitForKeyEx, + &(VirtualKeyboardPrivate->SimpleTextInputEx), + &(VirtualKeyboardPrivate->SimpleTextInputEx.WaitForKeyEx) + ); + if (EFI_ERROR (Status)) { + VirtualKeyboardPrivate->SimpleTextInputEx.WaitForKeyEx =3D NULL; + goto Done; + } + + // + // Setup a periodic timer, used for reading keystrokes at a fixed interv= al + // + 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; + 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 ( + &VirtualKeyboardPrivat= e->SimpleTextInputEx, + FALSE + ); + if (EFI_ERROR (Status)) { + DEBUG ((EFI_D_ERROR, "[KBD]Reset Failed. Status - %r\n", Status)); + goto Done; + } + // + // Install protocol interfaces for the keyboard device. + // + Status =3D gBS->InstallMultipleProtocolInterfaces ( + &Controller, + &gEfiSimpleTextInProtocolGuid, + &VirtualKeyboardPrivate->SimpleTextIn, + &gEfiSimpleTextInputExProtocolGuid, + &VirtualKeyboardPrivate->SimpleTextInputEx, + NULL + ); + +Done: + if (EFI_ERROR (Status)) { + if (VirtualKeyboardPrivate !=3D NULL) { + if ((VirtualKeyboardPrivate->SimpleTextIn).WaitForKey !=3D NULL) { + gBS->CloseEvent ((VirtualKeyboardPrivate->SimpleTextIn).WaitForKey= ); + } + + if ((VirtualKeyboardPrivate->SimpleTextInputEx).WaitForKeyEx !=3D NU= LL) { + gBS->CloseEvent ((VirtualKeyboardPrivate->SimpleTextInputEx).WaitF= orKeyEx); + } + + if (VirtualKeyboardPrivate->KeyNotifyProcessEvent !=3D NULL) { + gBS->CloseEvent (VirtualKeyboardPrivate->KeyNotifyProcessEvent); + } + + VirtualKeyboardFreeNotifyList (&VirtualKeyboardPrivate->NotifyList); + + if (VirtualKeyboardPrivate->TimerEvent !=3D NULL) { + gBS->CloseEvent (VirtualKeyboardPrivate->TimerEvent); + } + FreePool (VirtualKeyboardPrivate); + } + } + + gBS->CloseProtocol ( + Controller, + &gPlatformVirtualKeyboardProtocolGuid, + This->DriverBindingHandle, + Controller + ); + + return Status; +} + +/** + Stop the device handled by this driver. + + @param This The driver binding protocol. + @param Controller The controller to release. + @param NumberOfChildren The number of handles in ChildHandleBuffe= r. + @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 t= he device. + +**/ +EFI_STATUS +EFIAPI +VirtualKeyboardDriverBindingStop ( + IN EFI_DRIVER_BINDING_PROTOCOL *This, + IN EFI_HANDLE Controller, + IN UINTN NumberOfChildren, + IN EFI_HANDLE *ChildHandleBuffer + ) +{ + return EFI_SUCCESS; +} + + +/** + Enqueue the key. + + @param Queue The queue to be enqueued. + @param KeyData The key data to be enqueued. + + @retval EFI_NOT_READY The queue is full. + @retval EFI_SUCCESS Successfully enqueued the key data. + +**/ +EFI_STATUS +Enqueue ( + IN SIMPLE_QUEUE *Queue, + IN EFI_KEY_DATA *KeyData + ) +{ + if ((Queue->Rear + 1) % QUEUE_MAX_COUNT =3D=3D Queue->Front) { + return EFI_NOT_READY; + } + + CopyMem (&Queue->Buffer[Queue->Rear], KeyData, sizeof (EFI_KEY_DATA)); + Queue->Rear =3D (Queue->Rear + 1) % QUEUE_MAX_COUNT; + + return EFI_SUCCESS; +} + +/** + Dequeue the key. + + @param Queue The queue to be dequeued. + @param KeyData The key data to be dequeued. + + @retval EFI_NOT_READY The queue is empty. + @retval EFI_SUCCESS Successfully dequeued the key data. + +**/ +EFI_STATUS +Dequeue ( + IN SIMPLE_QUEUE *Queue, + IN EFI_KEY_DATA *KeyData + ) +{ + if (Queue->Front =3D=3D Queue->Rear) { + return EFI_NOT_READY; + } + + CopyMem (KeyData, &Queue->Buffer[Queue->Front], sizeof (EFI_KEY_DATA)); + Queue->Front =3D (Queue->Front + 1) % QUEUE_MAX_COUNT; + + return EFI_SUCCESS; +} + +/** + Check whether the queue is empty. + + @param Queue The queue to be checked. + + @retval EFI_NOT_READY The queue is empty. + @retval EFI_SUCCESS The queue is not empty. + +**/ +EFI_STATUS +CheckQueue ( + IN SIMPLE_QUEUE *Queue + ) +{ + if (Queue->Front =3D=3D Queue->Rear) { + return EFI_NOT_READY; + } + + return EFI_SUCCESS; +} + +/** + Check key buffer to get the key stroke status. + + @param This Pointer of the protocol EFI_SIMPLE_TEXT_IN_PROTOCOL. + + @retval EFI_SUCCESS A key is being pressed now. + @retval Other No key is now pressed. + +**/ +EFI_STATUS +EFIAPI +VirtualKeyboardCheckForKey ( + IN EFI_SIMPLE_TEXT_INPUT_PROTOCOL *This + ) +{ + VIRTUAL_KEYBOARD_DEV *VirtualKeyboardPrivate; + + VirtualKeyboardPrivate =3D VIRTUAL_KEYBOARD_DEV_FROM_THIS (This); + + return CheckQueue (&VirtualKeyboardPrivate->Queue); +} + +/** + Free keyboard notify list. + + @param ListHead The list head + + @retval EFI_SUCCESS Free the notify list successfully + @retval EFI_INVALID_PARAMETER ListHead is invalid. + +**/ +EFI_STATUS +VirtualKeyboardFreeNotifyList ( + IN OUT LIST_ENTRY *ListHead + ) +{ + VIRTUAL_KEYBOARD_CONSOLE_IN_EX_NOTIFY *NotifyNode; + + if (ListHead =3D=3D NULL) { + return EFI_INVALID_PARAMETER; + } + while (!IsListEmpty (ListHead)) { + NotifyNode =3D CR ( + ListHead->ForwardLink, + VIRTUAL_KEYBOARD_CONSOLE_IN_EX_NOTIFY, + NotifyEntry, + VIRTUAL_KEYBOARD_CONSOLE_IN_EX_NOTIFY_SIGNATURE + ); + RemoveEntryList (ListHead->ForwardLink); + gBS->FreePool (NotifyNode); + } + + return EFI_SUCCESS; +} + +/** + Judge whether is a registed key + + @param RegsiteredData A pointer to a buffer that is filled in with= the keystroke + state data for the key that was registered. + @param InputData A pointer to a buffer that is filled in with= the keystroke + state data for the key that was pressed. + + @retval TRUE Key be pressed matches a registered key. + @retval FLASE Match failed. + +**/ +BOOLEAN +IsKeyRegistered ( + IN EFI_KEY_DATA *RegsiteredData, + IN EFI_KEY_DATA *InputData + ) + +{ + ASSERT (RegsiteredData !=3D NULL && InputData !=3D NULL); + + if ((RegsiteredData->Key.ScanCode !=3D InputData->Key.ScanCode) || + (RegsiteredData->Key.UnicodeChar !=3D InputData->Key.UnicodeChar)) { + return FALSE; + } + + // + // Assume KeyShiftState/KeyToggleState =3D 0 in Registered key data mean= s these state could be ignored. + // + if (RegsiteredData->KeyState.KeyShiftState !=3D 0 && + RegsiteredData->KeyState.KeyShiftState !=3D InputData->KeyState.KeyS= hiftState) { + return FALSE; + } + if (RegsiteredData->KeyState.KeyToggleState !=3D 0 && + RegsiteredData->KeyState.KeyToggleState !=3D InputData->KeyState.Key= ToggleState) { + return FALSE; + } + + return TRUE; + +} + +/** + Event notification function for SIMPLE_TEXT_IN.WaitForKey event + Signal the event if there is key available + + @param Event the event object + @param Context waitting context + +**/ +VOID +EFIAPI +VirtualKeyboardWaitForKey ( + IN EFI_EVENT Event, + IN VOID *Context + ) +{ + // + // Stall 1ms to give a chance to let other driver interrupt this routine= for their timer event. + // Csm will be used to check whether there is a key pending, but the csm= will disable all + // interrupt before switch to compatibility16, which mean all the efiCom= patibility timer + // event will stop work during the compatibility16. And If a caller recu= rsivly 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 duri= ng the WaitForKey is recursivly invoked. + // 1ms delay will make little impact to the thunk keyboard driver, and u= ser can not feel the delay at all when input. + // + gBS->Stall (1000); + // + // Use TimerEvent callback function to check whether there's any key pre= ssed + // + VirtualKeyboardTimerHandler (NULL, VIRTUAL_KEYBOARD_DEV_FROM_THIS (Conte= xt)); + + if (!EFI_ERROR (VirtualKeyboardCheckForKey (Context))) { + gBS->SignalEvent (Event); + } +} + +/** + Event notification function for SIMPLE_TEXT_INPUT_EX_PROTOCOL.WaitForKey= Ex 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_THIS = (Context); + VirtualKeyboardWaitForKey (Event, &VirtualKeyboardPrivate->SimpleTextIn); + +} + +// +// 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. + + @param This Pointer of simple text Protocol. + @param ExtendedVerification Whether perform the extra validation of ke= yboard. 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 =3D VIRTUAL_KEYBOARD_DEV_FROM_THIS (This); + + // + // Raise TPL to avoid mouse operation impact + // + OldTpl =3D gBS->RaiseTPL (TPL_NOTIFY); + + if (VirtualKeyboardPrivate->PlatformVirtual && VirtualKeyboardPrivate->P= latformVirtual->Reset) { + 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; + EFI_STATUS Status; + EFI_TPL OldTpl; + + VirtualKeyboardPrivate =3D TEXT_INPUT_EX_VIRTUAL_KEYBOARD_DEV_FROM_THIS = (This); + + Status =3D VirtualKeyboardPrivate->SimpleTextIn.Reset ( + &VirtualKeyboardPrivate->Si= mpleTextIn, + 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 structur= e. + @param KeyData A pointer to a buffer that is filled in wi= th 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 =3D=3D NULL) { + return EFI_INVALID_PARAMETER; + } + + // + // Use TimerEvent callback function to check whether there's any key pre= ssed + // + + // + // 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 efiCom= patibility timer + // event will stop work during the compatibility16. And If a caller recu= rsivly invoke this function, + // e.g. OS loader, other drivers which are driven by timer event will ha= ve a bad performance during this period, + // e.g. usb keyboard driver. + // Add a stall period can greatly increate other driver performance duri= ng the WaitForKey is recursivly invoked. + // 1ms delay will make little impact to the thunk keyboard driver, and u= ser 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, &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_RI= GHT_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.UnicodeCha= r <=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 ke= ystroke + 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 returne= d 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_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 t= he- + state for the input device. + + @retval EFI_SUCCESS The device state was set successfully. + @retval EFI_DEVICE_ERROR The device is not functioning correctly an= d could- + not have the setting adjusted. + @retval EFI_UNSUPPORTED The device does not have the ability to se= t 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_VAL= ID || + (*KeyToggleState & EFI_KEY_STATE_EXPOSED) =3D=3D EFI_KEY_STATE_EXPOS= ED + ) { + return EFI_UNSUPPORTED; + } + + return EFI_SUCCESS; +} + +/** + Register a notification function for a particular keystroke for the inpu= t 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 pr= essed. + @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 necesss= ary 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 || KeyNotificationFu= nction =3D=3D NULL) { + return EFI_INVALID_PARAMETER; + } + + VirtualKeyboardPrivate =3D TEXT_INPUT_EX_VIRTUAL_KEYBOARD_DEV_FROM_THIS = (This); + + // + // Enter critical section + // + OldTpl =3D gBS->RaiseTPL (TPL_NOTIFY); + + // + // Return EFI_SUCCESS if the (KeyData, NotificationFunction) is already = 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 KeyNotificationFunction)= { + *NotifyHandle =3D CurrentNotify; + Status =3D EFI_SUCCESS; + goto Exit; + } + } + } + + // + // Allocate resource to save the notification function + // + + NewNotify =3D (VIRTUAL_KEYBOARD_CONSOLE_IN_EX_NOTIFY *) AllocateZeroPool= (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_NOTIFY_S= IGNATURE; + NewNotify->KeyNotificationFn =3D KeyNotificationFunction; + CopyMem (&NewNotify->KeyData, KeyData, sizeof (EFI_KEY_DATA)); + InsertTailList (&VirtualKeyboardPrivate->NotifyList, &NewNotify->NotifyE= ntry); + + *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 bei= ng unregistered. + + @retval EFI_SUCCESS The notification function was unregister= ed 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)->Sign= ature !=3D VIRTUAL_KEYBOARD_CONSOLE_IN_EX_NOTIFY_SIGNATURE) { + return EFI_INVALID_PARAMETER; + } + + VirtualKeyboardPrivate =3D TEXT_INPUT_EX_VIRTUAL_KEYBOARD_DEV_FROM_THIS = (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 resourc= es + // + 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; + 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 re= gistered. + // + 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 funct= ion. + @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; + + 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, &KeyData); + // + // Leave critical section + // + gBS->RestoreTPL (OldTpl); + if (EFI_ERROR (Status)) { + break; + } + for (Link =3D GetFirstNode (NotifyList); !IsNull (NotifyList, Link); L= ink =3D GetNextNode (NotifyList, Link)) { + CurrentNotify =3D CR (Link, VIRTUAL_KEYBOARD_CONSOLE_IN_EX_NOTIFY, N= otifyEntry, 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 wi= th this function. + + @param[in] ImageHandle The firmware allocated handle for the EFI imag= e. + @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 po= int. + +**/ +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/Emb= eddedPkg/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 IMPLI= ED. + +**/ + +#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, Si= mpleTextIn, 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 drive= r. + @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 ChildHandleBuffe= r. + @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 t= he 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 o= f 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 speci= fied + 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_PROTO= COL 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 calle= r 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 for= mat. + + @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 specifie= d by + This and the language specified by Languag= e 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 supp= ort + 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 control= ler + that is being managed by a driver. + + This function retrieves the user readable name of the controller specifi= ed 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 specif= ied by + Language, then a pointer to the controller name is returned in Controlle= rName, + and EFI_SUCCESS is returned. If the driver specified by This is not cur= rently + 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 retu= rned. + + @param This[in] A pointer to the EFI_COMPONENT_NAME2_PROTO= COL 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 retr= ieve + the name of. This is an optional paramete= r that + may be NULL. It will be NULL for device + drivers. It will also be NULL for a bus d= rivers + 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 calle= r 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 specifie= d 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 a= nd + ChildHandle in the language specified by + Language from the point of view of the dri= ver + specified by This. + + @retval EFI_SUCCESS The Unicode string for the user readable n= ame 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 curren= tly + managing the controller specified by + ControllerHandle and ChildHandle. + + @retval EFI_UNSUPPORTED The driver specified by This does not supp= ort + 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 ke= yboard. 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=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 set t= he + state for the input device. + + @retval EFI_SUCCESS The device state was set successfully. + @retval EFI_DEVICE_ERROR The device is not functioning correctly an= d could + not have the setting adjusted. + @retval EFI_UNSUPPORTED The device does not have the ability to se= t 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 inpu= t 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 pr= essed. + @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 necesss= ary 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 bei= ng unregistered. + + @retval EFI_SUCCESS The notification function was unregister= ed 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 t= he keystroke + state data for the key that was registered. + @param InputData A pointer to a buffer that is filled in with t= he 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, s= ignal 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_PROTOC= OL. + +**/ +VOID +EFIAPI +VirtualKeyboardWaitForKey ( + IN EFI_EVENT Event, + IN VOID *Context + ); + +/** + Waiting on the keyboard event, if there's any key pressed by the user, s= ignal the event + + @param Event The event that be siganlled when any key has been strok= ed. + @param Context Pointer of the protocol EFI_SIMPLE_TEXT_INPUT_EX_PROTOC= OL. + +**/ +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 funct= ion. + @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 ke= ystroke + 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 returne= d 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 @@ -0,0 +1,39 @@ +#/** @file +# Framework Module Development Environment Industry Standards +# +# This Package provides headers and libraries that conform to EFI/PI Indus= try 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 ava= ilable under +# the terms and conditions of the BSD License which accompanies this di= stribution. +# 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 =3D 0x00010019 + PACKAGE_NAME =3D VirtualKeyboardDxePkg + PACKAGE_GUID =3D 774326bc-20d0-4203-97e4-10dc17f7dc1a + PACKAGE_VERSION =3D 0.1 + +##########################################################################= ###### +# +# Include Section - list of Include Paths that are provided by this packag= e. +# 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_D= RIVER 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.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.
+# +# 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 IMP= LIED. +# +## + +[Defines] + INF_VERSION =3D 0x00010019 + BASE_NAME =3D VirtualKeyboardDxe + FILE_GUID =3D 88079b18-b42b-44aa-a6f2-b83911075e89 + 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 the = build tools. +# +# VALID_ARCHITECTURES =3D AARCH64 +# +# DRIVER_BINDING =3D gVirtualKeyboardDriverBinding +# COMPONENT_NAME =3D gVirtualKeyboardComponentName +# + +[Sources.common] + ComponentName.c + VirtualKeyboard.c + +[Packages] + EmbeddedPkg/Drivers/VirtualKeyboardDxe/VirtualKeyboardDxe.dec + EmbeddedPkg/EmbeddedPkg.dec + MdePkg/MdePkg.dec + MdeModulePkg/MdeModulePkg.dec + +[LibraryClasses] + BaseLib + BaseMemoryLib + DebugLib + IoLib + ReportStatusCodeLib + UefiDriverEntryPoint + UefiBootServicesTableLib + UefiLib + +[Protocols] + gEfiDriverBindingProtocolGuid + gEfiSimpleTextInProtocolGuid + gEfiSimpleTextInputExProtocolGuid + gPlatformVirtualKeyboardProtocolGuid + +[Depex] + TRUE diff --git a/EmbeddedPkg/Include/Protocol/PlatformVirtualKeyboard.h b/Embed= dedPkg/Include/Protocol/PlatformVirtualKeyboard.h new file mode 100644 index 0000000..bea3128 --- /dev/null +++ b/EmbeddedPkg/Include/Protocol/PlatformVirtualKeyboard.h @@ -0,0 +1,65 @@ +/** @file + + Copyright (c) 2018, Linaro. All rights reserved. + + This program and the accompanying materials + are licensed and made available under the terms and conditions of the BS= D License + which accompanies this distribution. The full text of the license may b= e 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 IMP= LIED. + +**/ + +#ifndef __PLATFORM_VIRTUAL_KEYBOARD_H__ +#define __PLATFORM_VIRTUAL_KEYBOARD_H__ + +// +// Protocol interface structure +// +typedef struct _PLATFORM_VIRTUAL_KBD_PROTOCOL PLATFORM_VIRTUAL_KBD_PROTOC= OL; + +typedef struct _VIRTUAL_KBD_KEY VIRTUAL_KBD_KEY; + +#define VIRTUAL_KEYBOARD_KEY_SIGNATURE SIGNATURE_32 ('v', 'k', 'b'= , 'd') + +struct _VIRTUAL_KBD_KEY { + UINTN Signature; + EFI_INPUT_KEY Key; +}; + +typedef +EFI_STATUS +(EFIAPI *PLATFORM_VIRTUAL_KBD_REGISTER) ( + IN VOID + ); + +typedef +EFI_STATUS +(EFIAPI *PLATFORM_VIRTUAL_KBD_RESET) ( + IN VOID + ); + +typedef +BOOLEAN +(EFIAPI *PLATFORM_VIRTUAL_KBD_QUERY) ( + IN VIRTUAL_KBD_KEY *VirtualKey + ); + +typedef +EFI_STATUS +(EFIAPI *PLATFORM_VIRTUAL_KBD_CLEAR) ( + IN VIRTUAL_KBD_KEY *VirtualKey + ); + +struct _PLATFORM_VIRTUAL_KBD_PROTOCOL { + PLATFORM_VIRTUAL_KBD_REGISTER Register; + PLATFORM_VIRTUAL_KBD_RESET Reset; + PLATFORM_VIRTUAL_KBD_QUERY Query; + PLATFORM_VIRTUAL_KBD_CLEAR Clear; +}; + +extern EFI_GUID gPlatformVirtualKeyboardProtocolGuid; + +#endif /* __PLATFORM_VIRTUAL_KEYBOARD_H__ */ --=20 2.7.4 _______________________________________________ edk2-devel mailing list edk2-devel@lists.01.org https://lists.01.org/mailman/listinfo/edk2-devel