From nobody Sat Apr 27 04:59:59 2024 Delivered-To: importer@patchew.org Received-SPF: pass (zohomail.com: domain of groups.io designates 66.175.222.12 as permitted sender) client-ip=66.175.222.12; envelope-from=bounce+27952+56348+1787277+3901457@groups.io; helo=web01.groups.io; Authentication-Results: mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of groups.io designates 66.175.222.12 as permitted sender) smtp.mailfrom=bounce+27952+56348+1787277+3901457@groups.io; dmarc=fail(p=none dis=none) header.from=intel.com ARC-Seal: i=1; a=rsa-sha256; t=1585183444; cv=none; d=zohomail.com; s=zohoarc; b=MOZ793XQ2xUrMOVc3L/7s/4+SZ0/SEgbCocjImM/iDVsDAEhOQ9+zVof7GMZgq04CLyjOrlhuzp7ih860BwFK07tMSl1PrHWOOSZbD56rsD0TaYPiQVCdvoPyY/a3P+4yGcHPtN8lAgSpoRpICniTIu6X48kghUSdnapGrp+YuM= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1585183444; h=Content-Transfer-Encoding:Date:From:List-Id:List-Unsubscribe:MIME-Version:Message-ID:Reply-To:Sender:Subject:To; bh=CH1R5CORgEfrHQfR5j8r7xNncXd2ObxmBfTsZaSaW1M=; b=f5k9viqagzltl8c/L3/8+LsHxr1NXB5FwlysOqYbWB5Ve/Nv51NMgyeVZ+p8ZTRiGimhnFuAeVf622fvd5T4N8vGsy/e+P2hqgm6HzZ9OWoDiAADBoXZgg9D1cYRXi8wv5fq/0AO3FtWRUANT4JtxEwLqXuGgBHiBByrZ1jZ1h0= ARC-Authentication-Results: i=1; mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of groups.io designates 66.175.222.12 as permitted sender) smtp.mailfrom=bounce+27952+56348+1787277+3901457@groups.io; dmarc=fail header.from= (p=none dis=none) header.from= Received: from web01.groups.io (web01.groups.io [66.175.222.12]) by mx.zohomail.com with SMTPS id 1585183444204341.47234682460953; Wed, 25 Mar 2020 17:44:04 -0700 (PDT) Return-Path: X-Received: by 127.0.0.2 with SMTP id 24zRYY1788612xhXBCPmLy9O; Wed, 25 Mar 2020 17:44:03 -0700 X-Received: from mga17.intel.com (mga17.intel.com [192.55.52.151]) by mx.groups.io with SMTP id smtpd.web12.27977.1585183440842938739 for ; Wed, 25 Mar 2020 17:44:01 -0700 IronPort-SDR: TZR6wYVjSqopVMzcT0Xj2NQF4kY8ksGkDFyumkm2rOQycLxOnknV68uk+tDxuQ2NSrN5HaBQfw wqBbAIDOiZNQ== X-Amp-Result: SKIPPED(no attachment in message) X-Amp-File-Uploaded: False X-Received: from orsmga006.jf.intel.com ([10.7.209.51]) by fmsmga107.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 25 Mar 2020 17:44:00 -0700 IronPort-SDR: uX2UcMCKtEy9Lqv2WfuNkoAsnxxLyAC0QBrRaSDEXbmDM4d6U1g6AiDq/Gvw+tZzxhIBw/84AQ 9r3RLBWgsviA== X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.72,306,1580803200"; d="scan'208";a="250583829" X-Received: from shwdejointlab96.ccr.corp.intel.com ([10.239.133.162]) by orsmga006.jf.intel.com with ESMTP; 25 Mar 2020 17:43:55 -0700 From: "Tan, Ming" To: devel@edk2.groups.io Subject: [edk2-devel] [PATCH] Features/Intel/UserInterface: Add VirtualKeyboardFeaturePkg Date: Thu, 26 Mar 2020 08:43:44 +0800 Message-Id: <20200326004344.5060-1-ming.tan@intel.com> MIME-Version: 1.0 Precedence: Bulk List-Unsubscribe: Sender: devel@edk2.groups.io List-Id: Mailing-List: list devel@edk2.groups.io; contact devel+owner@edk2.groups.io Reply-To: devel@edk2.groups.io,ming.tan@intel.com X-Gm-Message-State: rYYk6aUYPkXaxbTyPzYjZm2qx1787277AA= Content-Transfer-Encoding: quoted-printable DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=groups.io; q=dns/txt; s=20140610; t=1585183443; bh=7lcYql7q3+7zXLUNeYim8llfDND6eoDUuMsg07x8RlM=; h=Date:From:Reply-To:Subject:To; b=Uh2zgCVeGgwaqsnZPhm8EJoGKwfZYgSCdxdEnU5MEAqSLzUb0lhayJCot7jWXN+zwJs WlNtOGtpPtz6FVFUs53Ey9z9JeJVCs+dcLmmNmqoJyoh7MOj1P6sSpzKq8dDgHc5fDxMf ozHoo5dRXiH+ZN1aODOTvz6FHdQsCkGz4qo= X-ZohoMail-DKIM: pass (identity @groups.io) Content-Type: text/plain; charset="utf-8" REF: https://bugzilla.tianocore.org/show_bug.cgi?id=3D2603 It add a VirtualKeyboardDxe driver. It is used with a touch panel, simulate a keyboard in the screen. Signed-off-by: Ming Tan Reviewed-by: Eric Dong --- .../Include/PostMemory.fdf | 10 + .../Include/PreMemory.fdf | 8 + .../Include/VirtualKeyboardFeature.dsc | 96 ++ .../VirtualKeyboardFeaturePkg/Readme.md | 95 ++ .../CapitalLetterKeyboard.bmp | Bin 0 -> 330454 bytes .../VirtualKeyboardDxe/ComponentName.c | 159 ++ .../VirtualKeyboardDxe/ComponentName.h | 95 ++ .../VirtualKeyboardDxe/DigitKeyboard.bmp | Bin 0 -> 330454 bytes .../VirtualKeyboardDxe/FullIcon.bmp | Bin 0 -> 5454 bytes .../VirtualKeyboardDxe/Keyboard.c | 1400 +++++++++++++++++ .../VirtualKeyboardDxe/KeyboardLayout.c | 1364 ++++++++++++++++ .../VirtualKeyboardDxe/KeyboardLayout.idf | 12 + .../VirtualKeyboardDxe/SimpleIcon.bmp | Bin 0 -> 2814 bytes .../VirtualKeyboardDxe/SimpleKeyboard.bmp | Bin 0 -> 30054 bytes .../VirtualKeyboardDxe/VirtualKeyboard.h | 777 +++++++++ .../VirtualKeyboardDriver.c | 541 +++++++ .../VirtualKeyboardDxe/VirtualKeyboardDxe.inf | 77 + .../VirtualKeyboardFeaturePkg.dec | 26 + .../VirtualKeyboardFeaturePkg.dsc | 30 + 19 files changed, 4690 insertions(+) create mode 100644 Features/Intel/UserInterface/VirtualKeyboardFeaturePkg/= Include/PostMemory.fdf create mode 100644 Features/Intel/UserInterface/VirtualKeyboardFeaturePkg/= Include/PreMemory.fdf create mode 100644 Features/Intel/UserInterface/VirtualKeyboardFeaturePkg/= Include/VirtualKeyboardFeature.dsc create mode 100644 Features/Intel/UserInterface/VirtualKeyboardFeaturePkg/= Readme.md create mode 100644 Features/Intel/UserInterface/VirtualKeyboardFeaturePkg/= VirtualKeyboardDxe/CapitalLetterKeyboard.bmp create mode 100644 Features/Intel/UserInterface/VirtualKeyboardFeaturePkg/= VirtualKeyboardDxe/ComponentName.c create mode 100644 Features/Intel/UserInterface/VirtualKeyboardFeaturePkg/= VirtualKeyboardDxe/ComponentName.h create mode 100644 Features/Intel/UserInterface/VirtualKeyboardFeaturePkg/= VirtualKeyboardDxe/DigitKeyboard.bmp create mode 100644 Features/Intel/UserInterface/VirtualKeyboardFeaturePkg/= VirtualKeyboardDxe/FullIcon.bmp create mode 100644 Features/Intel/UserInterface/VirtualKeyboardFeaturePkg/= VirtualKeyboardDxe/Keyboard.c create mode 100644 Features/Intel/UserInterface/VirtualKeyboardFeaturePkg/= VirtualKeyboardDxe/KeyboardLayout.c create mode 100644 Features/Intel/UserInterface/VirtualKeyboardFeaturePkg/= VirtualKeyboardDxe/KeyboardLayout.idf create mode 100644 Features/Intel/UserInterface/VirtualKeyboardFeaturePkg/= VirtualKeyboardDxe/SimpleIcon.bmp create mode 100644 Features/Intel/UserInterface/VirtualKeyboardFeaturePkg/= VirtualKeyboardDxe/SimpleKeyboard.bmp create mode 100644 Features/Intel/UserInterface/VirtualKeyboardFeaturePkg/= VirtualKeyboardDxe/VirtualKeyboard.h create mode 100644 Features/Intel/UserInterface/VirtualKeyboardFeaturePkg/= VirtualKeyboardDxe/VirtualKeyboardDriver.c create mode 100644 Features/Intel/UserInterface/VirtualKeyboardFeaturePkg/= VirtualKeyboardDxe/VirtualKeyboardDxe.inf create mode 100644 Features/Intel/UserInterface/VirtualKeyboardFeaturePkg/= VirtualKeyboardFeaturePkg.dec create mode 100644 Features/Intel/UserInterface/VirtualKeyboardFeaturePkg/= VirtualKeyboardFeaturePkg.dsc diff --git a/Features/Intel/UserInterface/VirtualKeyboardFeaturePkg/Include= /PostMemory.fdf b/Features/Intel/UserInterface/VirtualKeyboardFeaturePkg/In= clude/PostMemory.fdf new file mode 100644 index 0000000000..bf4a4d5078 --- /dev/null +++ b/Features/Intel/UserInterface/VirtualKeyboardFeaturePkg/Include/PostMe= mory.fdf @@ -0,0 +1,10 @@ +## @file +# FDF file for post-memory modules that enable Virtual Keyboard. +# +# Copyright (c) 2020, Intel Corporation. All rights reserved.
+# +# SPDX-License-Identifier: BSD-2-Clause-Patent +# +## + + INF UserInterface/VirtualKeyboardFeaturePkg/VirtualKeyboardDxe/VirtualKe= yboardDxe.inf diff --git a/Features/Intel/UserInterface/VirtualKeyboardFeaturePkg/Include= /PreMemory.fdf b/Features/Intel/UserInterface/VirtualKeyboardFeaturePkg/Inc= lude/PreMemory.fdf new file mode 100644 index 0000000000..c39a057f94 --- /dev/null +++ b/Features/Intel/UserInterface/VirtualKeyboardFeaturePkg/Include/PreMem= ory.fdf @@ -0,0 +1,8 @@ +## @file +# FDF file for pre-memory modules that enable Virtual Keyboard. +# +# Copyright (c) 2020, Intel Corporation. All rights reserved.
+# +# SPDX-License-Identifier: BSD-2-Clause-Patent +# +## diff --git a/Features/Intel/UserInterface/VirtualKeyboardFeaturePkg/Include= /VirtualKeyboardFeature.dsc b/Features/Intel/UserInterface/VirtualKeyboardF= eaturePkg/Include/VirtualKeyboardFeature.dsc new file mode 100644 index 0000000000..c10fb2d567 --- /dev/null +++ b/Features/Intel/UserInterface/VirtualKeyboardFeaturePkg/Include/Virtua= lKeyboardFeature.dsc @@ -0,0 +1,96 @@ +## @file +# This is a build description file for the Virtual Keyboard feature. +# This file should be included into another package DSC file to build this= feature. +# +# The DEC files are used by the utilities that parse DSC and +# INF files to generate AutoGen.c and AutoGen.h files +# for the build infrastructure. +# +# Copyright (c) 2020, Intel Corporation. All rights reserved.
+# +# SPDX-License-Identifier: BSD-2-Clause-Patent +# +## + +##########################################################################= ###### +# +# Defines Section - statements that will be processed to create a Makefile. +# +##########################################################################= ###### +[Defines] +!ifndef $(PEI_ARCH) + !error "PEI_ARCH must be specified to build this feature!" +!endif +!ifndef $(DXE_ARCH) + !error "DXE_ARCH must be specified to build this feature!" +!endif + +##########################################################################= ###### +# +# Library Class section - list of all Library Classes needed by this featu= re. +# +##########################################################################= ###### +[LibraryClasses] + ####################################### + # Edk2 Packages + ####################################### + BaseLib|MdePkg/Library/BaseLib/BaseLib.inf + BaseMemoryLib|MdePkg/Library/BaseMemoryLib/BaseMemoryLib.inf + DebugLib|MdePkg/Library/BaseDebugLibNull/BaseDebugLibNull.inf + UefiBootServicesTableLib|MdePkg/Library/UefiBootServicesTableLib/UefiBoo= tServicesTableLib.inf + UefiDriverEntryPoint|MdePkg/Library/UefiDriverEntryPoint/UefiDriverEntry= Point.inf + UefiLib|MdePkg/Library/UefiLib/UefiLib.inf + PcdLib|MdePkg/Library/BasePcdLibNull/BasePcdLibNull.inf + HiiLib|MdeModulePkg/Library/UefiHiiLib/UefiHiiLib.inf + DevicePathLib|MdePkg/Library/UefiDevicePathLib/UefiDevicePathLib.inf + PrintLib|MdePkg/Library/BasePrintLib/BasePrintLib.inf + UefiHiiServicesLib|MdeModulePkg/Library/UefiHiiServicesLib/UefiHiiServic= esLib.inf + UefiRuntimeServicesTableLib|MdePkg/Library/UefiRuntimeServicesTableLib/U= efiRuntimeServicesTableLib.inf + +[LibraryClasses.common.UEFI_DRIVER] + ####################################### + # Edk2 Packages + ####################################### + MemoryAllocationLib|MdePkg/Library/UefiMemoryAllocationLib/UefiMemoryAll= ocationLib.inf + +##########################################################################= ######################### +# +# Components Section - list of the modules and components that will be pro= cessed by compilation +# tools and the EDK II tools to generate PE32/PE32+/C= off image files. +# +# Note: The EDK II DSC file is not used to specify how compiled binary ima= ges get placed +# into firmware volume images. This section is just a list of module= s to compile from +# source into UEFI-compliant binaries. +# It is the FDF file that contains information on combining binary f= iles into firmware +# volume images, whose concept is beyond UEFI and is described in PI= specification. +# Binary modules do not need to be listed in this section, as they s= hould be +# specified in the FDF file. For example: Shell binary (Shell_Full.e= fi), FAT binary (Fat.efi), +# Logo (Logo.bmp), and etc. +# There may also be modules listed in this section that are not requ= ired in the FDF file, +# When a module listed here is excluded from FDF file, then UEFI-com= pliant binary will be +# generated for it, but the binary will not be put into any firmware= volume. +# +##########################################################################= ######################### +# +# Feature DXE Components +# +[Components.X64] + ##################################### + # Virtual Keyboard Feature Package + ##################################### + UserInterface/VirtualKeyboardFeaturePkg/VirtualKeyboardDxe/VirtualKeyboa= rdDxe.inf + +##########################################################################= ######################### +# +# BuildOptions Section - Define the module specific tool chain flags that = should be used as +# the default flags for a module. These flags are a= ppended to any +# standard flags that are defined by the build proc= ess. They can be +# applied for any modules or only those modules wit= h the specific +# module style (EDK or EDKII) specified in [Compone= nts] section. +# +# For advanced features, it is recommended to enabl= e [BuildOptions] in +# the applicable INF file so it does not affect the= whole board package +# build when this DSC file is active. +# +##########################################################################= ######################### +[BuildOptions] diff --git a/Features/Intel/UserInterface/VirtualKeyboardFeaturePkg/Readme.= md b/Features/Intel/UserInterface/VirtualKeyboardFeaturePkg/Readme.md new file mode 100644 index 0000000000..17a3a00215 --- /dev/null +++ b/Features/Intel/UserInterface/VirtualKeyboardFeaturePkg/Readme.md @@ -0,0 +1,95 @@ +# Overview +* **Feature Name:** Virtual Keyboard +* **PI Phase(s) Supported:** DXE +* **SMM Required?** No + +## Purpose +This feature provides a DXE virtual keyboard driver, used with a touch pan= el. + +# High-Level Theory of Operation +This driver will use the following protocol: + gEfiAbsolutePointerProtocolGuid + gEfiTouchPanelGuid + gEfiGraphicsOutputProtocolGuid + +It will show a picture like a keyboard in the graphic output, then detect +position when user touch the touch panel, then calculate the key which the +user want to type. + +## Firmware Volumes +*_TODO_* +A bulleted list of the firmware volumes that feature module(s) are placed = in. + +## Modules +VirtualKeyboardDxe: The main driver of virtual keyboard + +## +*_TODO_* +Each module in the feature should have a section that describes the module= in a level of detail that is useful +to better understand the module source code. + +## +*_TODO_* +Each library in the feature should have a section that describes the libra= ry in a level of detail that is useful +to better understand the library source code. + +## Key Functions +*_TODO_* +A bulleted list of key functions for interacting with the feature. + +Not all features need to be listed. Only functions exposed through externa= l interfaces that are important for feature +users to be aware of. + +## Configuration +*_TODO_* +Information that is useful for configuring the feature. + +Not all configuration options need to be listed. This section is used to p= rovide more background on configuration +options than possible elsewhere. + +## Data Flows +*_TODO_* +Architecturally defined data structures and flows for the feature. + +## Control Flows +*_TODO_* +Key control flows for the feature. + +## Build Flows +*_TODO_* +Any special build flows should be described in this section. + +This is particularly useful for features that use custom build tools or re= quire non-standard tool configuration. If the +standard flow in the feature package template is used, this section may be= empty. + +## Test Point Results +*_TODO_* +The test(s) that can verify porting is complete for the feature. + +Each feature must describe at least one test point to verify the feature i= s successful. If the test point is not +implemented, this should be stated. + +## Functional Exit Criteria +*_TODO_* +The testable functionality for the feature. + +This section should provide an ordered list of criteria that a board integ= rator can reference to ensure the feature is +functional on their board. + +## Feature Enabling Checklist +*_TODO_* +An ordered list of required activities to achieve desired functionality fo= r the feature. + +## Performance Impact +A general expectation for the impact on overall boot performance due to us= ing this feature. + +This section is expected to provide guidance on: +* How to estimate performance impact due to the feature +* How to measure performance impact of the feature +* How to manage performance impact of the feature + +## Common Optimizations +*_TODO_* +Common size or performance tuning options for this feature. + +This section is recommended but not required. If not used, the contents sh= ould be left empty. diff --git a/Features/Intel/UserInterface/VirtualKeyboardFeaturePkg/Virtual= KeyboardDxe/CapitalLetterKeyboard.bmp b/Features/Intel/UserInterface/Virtua= lKeyboardFeaturePkg/VirtualKeyboardDxe/CapitalLetterKeyboard.bmp new file mode 100644 index 0000000000000000000000000000000000000000..759c3d46a9f0cf6a69fa98563cd= 04f7a082d3b4d GIT binary patch literal 330454 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 Ka0)zo_WuC{9xg=3Dy literal 0 HcmV?d00001 diff --git a/Features/Intel/UserInterface/VirtualKeyboardFeaturePkg/Virtual= KeyboardDxe/ComponentName.c b/Features/Intel/UserInterface/VirtualKeyboardF= eaturePkg/VirtualKeyboardDxe/ComponentName.c new file mode 100644 index 0000000000..6ac28ab90b --- /dev/null +++ b/Features/Intel/UserInterface/VirtualKeyboardFeaturePkg/VirtualKeyboar= dDxe/ComponentName.c @@ -0,0 +1,159 @@ +/** @file + Virtual Keyboard driver name. + + Copyright (c) 2012 - 2020, Intel Corporation. All rights reserved.
+ SPDX-License-Identifier: BSD-2-Clause-Patent + +**/ + +#include "VirtualKeyboard.h" + +// +// EFI Component Name Protocol +// +GLOBAL_REMOVE_IF_UNREFERENCED EFI_COMPONENT_NAME_PROTOCOL gVirtualKeyboard= ComponentName =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) VirtualKeyboardComponentNameGe= tDriverName, + (EFI_COMPONENT_NAME2_GET_CONTROLLER_NAME) VirtualKeyboardComponentNameGe= tControllerName, + "en" +}; + +// +// Table of driver names +// +GLOBAL_REMOVE_IF_UNREFERENCED EFI_UNICODE_STRING_TABLE mVirtualKeyboardDri= verNameTable[] =3D { + { + "eng;en", + L"UEFI Virtual Keyboard Driver" + }, + { + NULL, + NULL + } +}; + +// +// Controller name string table +// +GLOBAL_REMOVE_IF_UNREFERENCED EFI_UNICODE_STRING_TABLE mVirtualKeyboardCon= trollerNameStringTable[] =3D { + { + "eng", + L"UEFI Virtual Keyboard Driver" + }, + { + NULL, + NULL + } +}; + +/** + Retrieves a Unicode string that is the user-readable name of the EFI Dri= ver. + + @param[in] This A pointer to the EFI_COMPONENT_NAME_PROTOC= OL instance. + @param[in] Language A pointer to a three-character ISO 639-2 l= anguage identifier. + This is the language of the driver name th= at that the caller + is requesting, and it must match one of th= e languages specified + in SupportedLanguages. The number of lang= uages supported by a + driver is up to the driver writer. + @param[out] DriverName A pointer to the Unicode string to return.= This Unicode string + is the name of the driver specified by Thi= s in the language + specified by Language. + + @retval EFI_SUCCESS The Unicode string for the Driver specifie= d by This + and the language specified by Language was= returned + in DriverName. + @retval EFI_INVALID_PARAMETER Language is NULL. + @retval EFI_INVALID_PARAMETER DriverName is NULL. + @retval EFI_UNSUPPORTED The driver specified by This does not 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 an EFI Driver. + + @param[in] This A pointer to the EFI_COMPONENT_NAME_PROTOC= OL instance. + @param[in] ControllerHandle The handle of a controller that the driver= specified by + This is managing. This handle specifies t= he controller + whose name is to be returned. + @param[in] ChildHandle The handle of the child controller to retr= ieve the name + of. This is an optional parameter that ma= y be NULL. It + will be NULL for device drivers. It will = also be NULL + for a bus drivers that wish to retrieve th= e name of the + bus controller. It will not be NULL for a= bus driver + that wishes to retrieve the name of a chil= d controller. + @param[in] Language A pointer to a three character ISO 639-2 l= anguage + identifier. This is the language of the c= ontroller name + that the caller is requesting, and it must= match one + of the languages specified in SupportedLan= guages. The + number of languages supported by a driver = is up to the + driver writer. + @param[out] ControllerName A pointer to the Unicode string to return.= This Unicode + string is the name of the controller speci= fied by + ControllerHandle and ChildHandle in the la= nguage specified + by Language, from the point of view of the= driver specified + by This. + + @retval EFI_SUCCESS The Unicode string for the user-readable n= ame in the + language specified by Language for the dri= ver + specified by This was returned in DriverNa= me. + @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 ControllerHand= le 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 + ) +{ + // + // ChildHandle must be NULL for a Device Driver + // + if (ChildHandle !=3D NULL) { + return EFI_UNSUPPORTED; + } + return LookupUnicodeString2 ( + Language, + This->SupportedLanguages, + mVirtualKeyboardControllerNameStringTable, + ControllerName, + (BOOLEAN)(This =3D=3D &gVirtualKeyboardComponentName) + ); +} diff --git a/Features/Intel/UserInterface/VirtualKeyboardFeaturePkg/Virtual= KeyboardDxe/ComponentName.h b/Features/Intel/UserInterface/VirtualKeyboardF= eaturePkg/VirtualKeyboardDxe/ComponentName.h new file mode 100644 index 0000000000..327ce9f9cb --- /dev/null +++ b/Features/Intel/UserInterface/VirtualKeyboardFeaturePkg/VirtualKeyboar= dDxe/ComponentName.h @@ -0,0 +1,95 @@ +/** @file + Header file for Virtual Keyboard driver name. + + Copyright (c) 2012 - 2020, Intel Corporation. All rights reserved.
+ SPDX-License-Identifier: BSD-2-Clause-Patent + +**/ + +#ifndef _VIRTUAL_KEYBOARD_COMPONENT_NAME_H_ +#define _VIRTUAL_KEYBOARD_COMPONENT_NAME_H_ + +#include +#include +#include + +/** + Retrieves a Unicode string that is the user-readable name of the EFI Dri= ver. + + @param[in] This A pointer to the EFI_COMPONENT_NAME_PROTOC= OL instance. + @param[in] Language A pointer to a three-character ISO 639-2 l= anguage identifier. + This is the language of the driver name th= at that the caller + is requesting, and it must match one of th= e languages specified + in SupportedLanguages. The number of lang= uages supported by a + driver is up to the driver writer. + @param[out] DriverName A pointer to the Unicode string to return.= This Unicode string + is the name of the driver specified by Thi= s in the language + specified by Language. + + @retval EFI_SUCCESS The Unicode string for the Driver specifie= d by This + and the language specified by Language was= returned + in DriverName. + @retval EFI_INVALID_PARAMETER Language is NULL. + @retval EFI_INVALID_PARAMETER DriverName is NULL. + @retval EFI_UNSUPPORTED The driver specified by This does not 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 an EFI Driver. + + @param[in] This A pointer to the EFI_COMPONENT_NAME_PROTOC= OL instance. + @param[in] ControllerHandle The handle of a controller that the driver= specified by + This is managing. This handle specifies t= he controller + whose name is to be returned. + @param[in] ChildHandle The handle of the child controller to retr= ieve the name + of. This is an optional parameter that ma= y be NULL. It + will be NULL for device drivers. It will = also be NULL + for a bus drivers that wish to retrieve th= e name of the + bus controller. It will not be NULL for a= bus driver + that wishes to retrieve the name of a chil= d controller. + @param[in] Language A pointer to a three character ISO 639-2 l= anguage + identifier. This is the language of the c= ontroller name + that the caller is requesting, and it must= match one + of the languages specified in SupportedLan= guages. The + number of languages supported by a driver = is up to the + driver writer. + @param[out] ControllerName A pointer to the Unicode string to return.= This Unicode + string is the name of the controller speci= fied by + ControllerHandle and ChildHandle in the la= nguage specified + by Language, from the point of view of the= driver specified + by This. + + @retval EFI_SUCCESS The Unicode string for the user-readable n= ame in the + language specified by Language for the dri= ver + specified by This was returned in DriverNa= me. + @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 ControllerHand= le 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 + ); +#endif diff --git a/Features/Intel/UserInterface/VirtualKeyboardFeaturePkg/Virtual= KeyboardDxe/DigitKeyboard.bmp b/Features/Intel/UserInterface/VirtualKeyboar= dFeaturePkg/VirtualKeyboardDxe/DigitKeyboard.bmp new file mode 100644 index 0000000000000000000000000000000000000000..b64d62034817e7407120ee2181c= 935e07bef5a8c GIT binary patch literal 330454 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 literal 0 HcmV?d00001 diff --git a/Features/Intel/UserInterface/VirtualKeyboardFeaturePkg/Virtual= KeyboardDxe/FullIcon.bmp b/Features/Intel/UserInterface/VirtualKeyboardFeat= urePkg/VirtualKeyboardDxe/FullIcon.bmp new file mode 100644 index 0000000000000000000000000000000000000000..b940505c8bc74ad6550bc322629= d7975c1e1c1fc GIT binary patch literal 5454 zcmdUyTS!(}6o56!L@l#1k<1H~<*msK=3DEYIGfJHUFgo!=3D$AR-O~g3Ln$_Tv5C7@{FW zuaziT6L~3b87f|a5!5uTbW}2D5<@ff*ZKTcvp6&*5#z(Z`TxV--&uR@b@o|%t#u-Q zirH&rZa;AK<^LmpPyW_cZd|Rb+&wdS8R##V7QBl$KC>^RJ%0hvQTJfsOsFMO;BsL#Bc+kVc!`)T3UMd?j1wg!omWC#w~`ctE&(Mwy2?ed3l+I z(9eooA!}=3DE5V1`y85$b0#P}@x{Fk}?ZEkdDXJ>gplgWhtz!<)L`xf%y!v{{T5P2hW zb93BNlHq>@sNRc zcW<~^OiawqojboXH;fq@8{?$x*|P_=3Detv!kG&D5G6vWP+JqzLViCT`^qeqV*iHV8G zh&^&eA4+&A%_;b~o=3DrNWMV^-|sqoaPQ>eOg=3DZ+Grg~Y|hDe3L)g%}S$PWa-*i*4Js zi40~VK%Jvg$RLo+%uFR>vr(nRhmNC+sL@6FBM-=3D9}Th`=3D{|eSMD}J$m@?VL5SB9aK{g>XWpzG?ZVye3?E3{`Bcn zNJ2uwkt0Vq#Wcdgt5>f$-~j;vsKsp%XlZF7Pca3tix)3K%FD}{&f+AF_V#v2YHBJn zVvk(Wh7v*tHK#?!XA7+P>zg-nI@L&PYb!N2hngXN$Qy*v=3Ds3EwH-R`XxEas^eTrKPI;{{8!qpr9ZnQr?h2l^{Sy(4iz&W2}~% zKQb~>Wu)fU@V-fWMmgVBn|!By$>w9nj_Gn@Gx=3DA^SK4e$N&n+_%GcZc4g36Gn?JkH z)JPOL#tkth0ytY#RaK<|1W!moL4gwPLX1VrXZ?A4dRnJQF<|^OCWE8o`0?W^Be7bC zbT|?CbA8K3+_-V$2JTc+Qj(LC!;lK|w}0EUYu6y0N^a55&(G)JL->fu%gckXmPC@9 zH*Xdf7emNv;v1p^wPFv|JGT&^kmF+wC2USsRu+U4EuL`e)~%wVA_yD{kzt4)l+dAo p86F + SPDX-License-Identifier: BSD-2-Clause-Patent + +**/ + +#include "VirtualKeyboard.h" + +/** + Notify all keyboards pressed specific key need to hidden Virtual + Keyboard. + + @param[in] KeyData Keyboard pressed specific key data + + @retval EFI_SUCCESS Success for the function. + @retval EFI_NOT_FOUND Not found Virtual Keyboard protocol. + +**/ +EFI_STATUS +EFIAPI +VkNotifyKeyCallback ( + IN EFI_KEY_DATA *KeyData + ) +{ + EFI_STATUS Status; + VK_CONTEXT *VkContext; + UINTN MaxColumn; + UINTN MaxRow; + UINT32 HorizontalPixel; + UINT32 VerticalPixel; + + DEBUG ((DEBUG_VK_ROUTINE_ENTRY_EXIT, "VkNotifyKeyCallback Start\n")); + + Status =3D gBS->LocateProtocol (&gEfiCallerIdGuid, NULL, (VOID **) &VkCo= ntext); + if (EFI_ERROR (Status)) { + return Status; + } + + gST->ConOut->QueryMode ( + gST->ConOut, + gST->ConOut->Mode->Mode, + &MaxColumn, + &MaxRow + ); + HorizontalPixel =3D VkContext->GraphicsOutput->Mode->Info->HorizontalRes= olution; + VerticalPixel =3D VkContext->GraphicsOutput->Mode->Info->VerticalResol= ution; + + // + // CursorRow and CursorColumn are started from 0, so need to add 2 not 1. + // + if (((UINTN)(gST->ConOut->Mode->CursorColumn * EFI_GLYPH_WIDTH) < VkCont= ext->SimIconBackWidth) && + ((UINTN)((gST->ConOut->Mode->CursorRow + 2) * EFI_GLYPH_HEIGHT) > (V= erticalPixel - VkContext->SimIconBackHeight))) { + SaveVkIconBackgroundBltBuffer (VkContext, VkDisplayAttributeSimpleBott= om); + } else if (((UINTN)((gST->ConOut->Mode->CursorColumn + 2) * EFI_GLYPH_WI= DTH) > (HorizontalPixel - VkContext->FullIconBackWidth)) && + ((UINTN)((gST->ConOut->Mode->CursorRow + 2) * EFI_GLYPH_HEIGH= T) > (VerticalPixel - VkContext->FullIconBackHeight))){ + SaveVkIconBackgroundBltBuffer (VkContext, VkDisplayAttributeFullBottom= ); + } + + // + // Hide icon/keyboard to prevent screen scroll up. + // + if ((KeyData->Key.UnicodeChar =3D=3D CHAR_CARRIAGE_RETURN) || + (KeyData->Key.ScanCode =3D=3D SCAN_ESC) || + ((gST->ConOut->Mode->CursorColumn >=3D (INT32) (MaxColumn - 2)) && + (gST->ConOut->Mode->CursorRow =3D=3D (INT32) (MaxRow - 1)))) { + HideVkBody (VkContext); + HideVkIcon (VkContext); + VkContext->IconReDrawCheck =3D 0; + } + + DEBUG ((DEBUG_VK_ROUTINE_ENTRY_EXIT, "VkNotifyKeyCallback End\n")); + return EFI_SUCCESS; +} + +/** + Judge whether is a registed key. + + @param[in] RegsiteredData A pointer to a buffer that is filled in with= the keystroke + state data for the key that was registered. + @param[in] 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; +} + +/** + Pop the key from the keybuffer. + + @param[in, out] VkContext Address of an VK_CONTEXT structure. + @param[out] KeyData The EFI stand key infomation when code get = the key will put + correct mapping key. + + @retval EFI_SUCCESS The keystroke information was returned. + @retval EFI_NOT_READY The keystroke data is empty. + +**/ +EFI_STATUS +VkPopTheKey ( + IN OUT VK_CONTEXT *VkContext, + OUT EFI_KEY_DATA *KeyData OPTIONAL + ) +{ + EFI_STATUS Status; + UINT8 IndexSt; + UINT8 IndexEd; + + DEBUG ((DEBUG_VK_ROUTINE_ENTRY_EXIT, "VkPopTheKey Start\n")); + // + // KeyBuffer + // [ 0 ] + // [ 1 ]<-*IndexSt/IndexEd + // [ 2 ] + // [ ... ] + // [MAX_KEY_BUF_SIZE - 1] + // + Status =3D EFI_SUCCESS; + IndexSt =3D VkContext->KeyStartIndex; + IndexEd =3D VkContext->KeyEndIndex; + + if (IndexEd =3D=3D IndexSt) { + DEBUG ((DEBUG_VK_KEYS, "ERROR - Keyboard buffer is empty.\n")); + Status =3D EFI_NOT_READY; + goto Error; + } + + DEBUG ((DEBUG_VK_KEYS | DEBUG_INFO, "VkPopTheKey Unicode: %08x\n", Vk= Context->Keybuffer[IndexSt].Key.UnicodeChar)); + DEBUG ((DEBUG_VK_KEYS | DEBUG_INFO, "VkPopTheKey ScanCode: %08x\n", Vk= Context->Keybuffer[IndexSt].Key.ScanCode)); + DEBUG ((DEBUG_VK_KEYS | DEBUG_INFO, "VkPopTheKey ShiftState: %08x\n", Vk= Context->Keybuffer[IndexSt].KeyState.KeyShiftState)); + DEBUG ((DEBUG_VK_KEYS | DEBUG_INFO, "VkPopTheKey ToggleState:%08x\n", Vk= Context->Keybuffer[IndexSt].KeyState.KeyToggleState)); + + if (KeyData !=3D NULL) { + *KeyData =3D VkContext->Keybuffer[IndexSt]; + } + VkContext->KeyStartIndex =3D ++IndexSt % MAX_KEY_BUF_SIZE; + + DEBUG ((DEBUG_VK_ROUTINE_ENTRY_EXIT, "VkPopTheKey Success, Status: %r\n"= , Status)); + goto End; + +Error: + DEBUG ((DEBUG_VK_ROUTINE_ENTRY_EXIT, "VkPopTheKey Failed, Status: %r\n",= Status)); + +End: + DEBUG ((DEBUG_VK_ROUTINE_ENTRY_EXIT, "VkPopTheKey End\n")); + return Status; +} + +/** + Push the event mapping key index to the input key buffer. + + @param[in, out] VkContext Address of an VK_CONTEXT structure. + @param[in] Unicode The font's unicode number. + + @retval EFI_SUCCESS The maping key index did put the key buffer. + +**/ +EFI_STATUS +VkPushTheKey ( + IN OUT VK_CONTEXT *VkContext, + IN UINT16 Unicode + ) +{ + UINT8 IndexSt; + UINT8 IndexEd; + EFI_KEY_DATA KeyData; + EFI_STATUS Status; + LIST_ENTRY *Link; + VK_NOTIFY *CurrentNotify; + + DEBUG ((DEBUG_VK_ROUTINE_ENTRY_EXIT, "VkPushTheKey Start\n")); + // + // KeyBuffer + // [ 0 ] + // [ 1 ]<-IndexSt/*IndexEd + // [ 2 ] + // [ ... ] + // [MAX_KEY_BUF_SIZE - 1] + // + IndexSt =3D VkContext->KeyStartIndex; + IndexEd =3D VkContext->KeyEndIndex; + + Status =3D EFI_SUCCESS; + + // + // Check Keyboard Buffer if is full that will pop the first key + // + if (VkContext->IsSupportPartialKey && + ((VkContext->KeyEndIndex + 2) % MAX_KEY_BUF_SIZE) =3D=3D IndexSt) { + VkPopTheKey (VkContext, NULL); + } + + if (((VkContext->KeyEndIndex + 1) % MAX_KEY_BUF_SIZE) =3D=3D IndexSt) { + VkPopTheKey (VkContext, NULL); + } + + KeyData.Key.ScanCode =3D SCAN_NULL; + KeyData.Key.UnicodeChar =3D CHAR_NULL; + KeyData.KeyState.KeyShiftState =3D EFI_SHIFT_STATE_VALID; + KeyData.KeyState.KeyToggleState =3D VkContext->KeyToggleState; + KeyData.KeyState.KeyToggleState &=3D ~EFI_CAPS_LOCK_ACTIVE; + KeyData.KeyState.KeyToggleState |=3D VkContext->IsCapsLockFlag ? EFI_CAP= S_LOCK_ACTIVE : 0; + + switch (Unicode) { + case VkKeyShift: + VkContext->IsShiftKeyFlag =3D !VkContext->IsShiftKeyFlag; + if (VkContext->PageNumber >=3D VkPage2 && VkContext->PageNumber <=3D V= kPage3) { + VkContext->IsShiftKeyFlag ? VkContext->PageNumber++ : VkContext->Pag= eNumber--; + } + VkContext->IsRedrawUpdateUI =3D TRUE; + break; + + case VkKeyTwoPage: + switch (VkContext->PageNumber) { + case VkPage0: + case VkPage1: + VkContext->IsShiftKeyFlag =3D FALSE; + VkContext->PageNumber =3D VkContext->IsShiftKeyFlag ? VkPage3 : = VkPage2; + break; + + case VkPage2: + case VkPage3: + VkContext->IsShiftKeyFlag =3D FALSE; + VkContext->PageNumber =3D VkContext->IsCapsLockFlag ? VkPage1 : = VkPage0; + break; + + default: + break; + } + VkContext->IsRedrawUpdateUI =3D TRUE; + break; + + case VkKeyCapslock: + VkContext->IsCapsLockFlag =3D !VkContext->IsCapsLockFlag; + if (VkContext->PageNumber >=3D VkPage0 && VkContext->PageNumber <=3D V= kPage1) { + VkContext->IsCapsLockFlag ? VkContext->PageNumber++ : VkContext->Pag= eNumber--; + } + KeyData.KeyState.KeyToggleState &=3D ~EFI_CAPS_LOCK_ACTIVE; + KeyData.KeyState.KeyToggleState |=3D VkContext->IsCapsLockFlag ? EFI_C= APS_LOCK_ACTIVE : 0; + VkContext->IsRedrawUpdateUI =3D TRUE; + break; + + default: + if ((Unicode & VkKeyScanMask) !=3D 0) { + KeyData.Key.ScanCode =3D Unicode & ~VkKeyScanMask; + } else { + KeyData.Key.UnicodeChar =3D Unicode; + } + break; + } + + if (KeyData.Key.ScanCode =3D=3D SCAN_NULL && KeyData.Key.UnicodeChar =3D= =3D CHAR_NULL) { + if (!VkContext->IsSupportPartialKey) { + goto End; + } + } + + for (Link =3D GetFirstNode (&VkContext->NotifyList); !IsNull (&VkContext= ->NotifyList, Link); Link =3D GetNextNode (&VkContext->NotifyList, Link)) { + CurrentNotify =3D CR (Link, VK_NOTIFY, NotifyEntry, VK_NOTIFY_SIGNATUR= E); + // + // The key notification function needs to run at TPL_CALLBACK + // while current TPL is TPL_NOTIFY. It will be invoked in + // VkKeyNotifyProcessHandler() which runs at TPL_CALLBACK. + // + if (IsKeyRegistered (&CurrentNotify->KeyData, &KeyData)) { + VkContext->Keybuffer[IndexEd] =3D KeyData; + VkContext->KeyEndIndex =3D ++IndexEd % MAX_KEY_BUF_SIZE; + gBS->SignalEvent (VkContext->KeyNotifyProcessEvent); + } + } + VkContext->Keybuffer[IndexEd] =3D KeyData; + VkContext->KeyEndIndex =3D ++IndexEd % MAX_KEY_BUF_SIZE; + + DEBUG ((DEBUG_VK_TIMER_ENTRY_EXIT, "VkPushTheKey Success, Status: %r\n",= Status)); + goto End; + +End: + DEBUG ((DEBUG_VK_TIMER_ENTRY_EXIT, "VkPushTheKey End\n")); + return Status; +} + +/** + Process key notify. + + @param[in] Event Indicates the event that invoke this fu= nction. + @param[in] Context Indicates the calling context. + +**/ +VOID +EFIAPI +VkKeyNotifyProcessHandler ( + IN EFI_EVENT Event, + IN VOID *Context + ) +{ + EFI_STATUS Status; + VK_CONTEXT *VkContext; + EFI_KEY_DATA KeyData; + LIST_ENTRY *Link; + LIST_ENTRY *NotifyList; + VK_NOTIFY *CurrentNotify; + EFI_TPL OldTpl; + + DEBUG ((DEBUG_VK_ROUTINE_ENTRY_EXIT, "VkKeyNotifyProcessHandler Start\n"= )); + VkContext =3D (VK_CONTEXT *) Context; + OldTpl =3D gBS->RaiseTPL (TPL_NOTIFY); + + // + // Invoke notification functions. + // + NotifyList =3D &VkContext->NotifyList; + Status =3D VkPopTheKey (VkContext, &KeyData); + if (EFI_ERROR (Status)) { + goto Error; + } + + for (Link =3D GetFirstNode (NotifyList); !IsNull (NotifyList, Link); Lin= k =3D GetNextNode (NotifyList, Link)) { + CurrentNotify =3D CR (Link, VK_NOTIFY, NotifyEntry, VK_NOTIFY_SIGNATUR= E); + if (IsKeyRegistered (&CurrentNotify->KeyData, &KeyData)) { + CurrentNotify->KeyNotificationFn (&KeyData); + } + } + + DEBUG ((DEBUG_VK_ROUTINE_ENTRY_EXIT, "VkKeyNotifyProcessHandler Success,= Status: %r\n", Status)); + goto End; + +Error: + DEBUG ((DEBUG_VK_ROUTINE_ENTRY_EXIT, "VkKeyNotifyProcessHandler Failed, = Status: %r\n", Status)); + +End: + gBS->RestoreTPL (OldTpl); + DEBUG ((DEBUG_VK_ROUTINE_ENTRY_EXIT, "VkKeyNotifyProcessHandler End\n")); +} + +/** + Push the event mapping key index to the input key buffer. + + @param[in] VkContext Address of an VK_CONTEXT structure. + @param[out] KeyItem Key Item. + @param[out] Index Index of Key Item. + @param[in] TouchX X position of finger touch. + @param[in] TouchY Y position of finger touch. + + @retval TRUE Touch on Virtual Keyboard. + @retval FALSE Not touch on Virtual Keyboard. + +**/ +BOOLEAN +IsTouchVk ( + IN VK_CONTEXT *VkContext, + OUT VK_STRUCT *KeyItem, + OUT UINT32 *Index, + IN UINT32 TouchX, + IN UINT32 TouchY + ) +{ + for (*Index =3D 0; *Index < VkContext->NumOfKeysInfo; (*Index)++) { + if (VkContext->KeyboardBodyPtr[*Index].DisStartX < TouchX && + VkContext->KeyboardBodyPtr[*Index].DisEndX > TouchX && + VkContext->KeyboardBodyPtr[*Index].DisStartY < TouchY && + VkContext->KeyboardBodyPtr[*Index].DisEndY > TouchY) { + break; + } + } + if (*Index !=3D VkContext->NumOfKeysInfo) { + *KeyItem =3D VkContext->KeyboardBodyPtr[*Index]; + } + + return *Index !=3D VkContext->NumOfKeysInfo; +} + +VOID +EFIAPI +VkReadyToBootCallBack ( + IN EFI_EVENT Event, + IN VOID *Context + ) +{ + VK_CONTEXT *VkContext; + VkContext =3D (VK_CONTEXT *)Context; + + HideVkBody (VkContext); + VkContext->TargetKeyboardDisplay =3D VkDisplayAttributeNone; +} + +/** + Timer event + + This routine is called at TPL_VK_SYNC. + + This routine polls for touch panel input. + + @param[in] Event Event whose notification function is being invoked. + @param[in] Context Pointer to the notification function's context, + which is implementation-dependent. Context correspon= ds + to NotifyContext in CreateEventEx(). + +**/ +VOID +EFIAPI +VkTimer ( + IN EFI_EVENT Event, + IN VOID *Context + ) +{ + EFI_ABSOLUTE_POINTER_PROTOCOL *AbsolutePointer; + EFI_ABSOLUTE_POINTER_STATE Point; + EFI_STATUS Status; + UINT32 TouchX; + UINT32 TouchY; + VK_CONTEXT *VkContext; + UINT32 Index; + VK_STRUCT KeyItem; + UINT32 Font; + + DEBUG ((DEBUG_VK_TIMER_ENTRY_EXIT, "VkTimer Start\n")); + VkContext =3D (VK_CONTEXT *)Context; + + // + // Update keyboard UI layout + // + CheckIconCleared (VkContext); + CheckScreenCleared (VkContext); + CheckBackgroundChanged (VkContext); + if (VkContext->IsRedrawUpdateUI) { + HideVkBody (VkContext); + DrawKeyboardLayout (VkContext); + VkContext->IsRedrawUpdateUI =3D FALSE; + } + + // + // Error handle for invalid information + // + AbsolutePointer =3D VkContext->AbsolutePointer; + Status =3D gBS->CheckEvent (AbsolutePointer->WaitForInput); + if (EFI_ERROR (Status)) { + DEBUG ((DEBUG_VK_TIMER_ENTRY_EXIT | DEBUG_VK_POINTS, "ERROR - VkContex= t->AbsolutePointer->WaitForInput->CheckEvent failed! Status: %r\n", Status)= ); + goto Error; + } + + Status =3D AbsolutePointer->GetState (AbsolutePointer, &Point); + if (EFI_ERROR (Status)) { + DEBUG ((DEBUG_VK_TIMER_ENTRY_EXIT | DEBUG_VK_POINTS, "ERROR - GetState= failed, Status: %r\n", Status)); + goto Error; + } + + if (VkContext->AbsolutePointer->Mode->AbsoluteMaxX <=3D Point.CurrentX) { + DEBUG (( + DEBUG_VK_TIMER_ENTRY_EXIT | DEBUG_VK_POINTS, + "ERROR - X value exceeds maximum: X: 0x%016Lx, MaxX: 0x%016Lx\n", + Point.CurrentX, + VkContext->AbsolutePointer->Mode->AbsoluteMaxX + )); + Status =3D EFI_PROTOCOL_ERROR; + goto Error; + } + if (VkContext->AbsolutePointer->Mode->AbsoluteMaxY <=3D Point.CurrentY) { + DEBUG (( + DEBUG_VK_TIMER_ENTRY_EXIT | DEBUG_VK_POINTS, + "ERROR - Y value exceeds maximum: Y: 0x%016Lx, MaxY: 0x%016Lx\n", + Point.CurrentY, + VkContext->AbsolutePointer->Mode->AbsoluteMaxY + )); + Status =3D EFI_PROTOCOL_ERROR; + goto Error; + } + + // + // Update the touch active status + // + VkContext->TouchActive =3D ((Point.ActiveButtons & EFI_ABSP_TouchActive)= !=3D 0) ? TRUE : FALSE; + if (!VkContext->TouchActive) { + VkContext->KeyPressed =3D FALSE; + } + ConvertCoordinate (VkContext, Point, &TouchX, &TouchY); + + if (!VkContext->KeyPressed && + VkContext->TouchActive && + IsTouchVk (VkContext, &KeyItem, &Index, TouchX, TouchY)) { + VkGetMappingFont (VkContext, KeyItem, &Font); + DEBUG ((DEBUG_VK_TIMER_ENTRY_EXIT | DEBUG_INFO, "VK = Touch event is trigger!\n" )); + DEBUG ((DEBUG_VK_TIMER_ENTRY_EXIT | DEBUG_INFO | DEBUG_VK_POINTS, "Tou= chActive: 0x%04x \n", VkContext->TouchActive)); + DEBUG ((DEBUG_VK_TIMER_ENTRY_EXIT | DEBUG_INFO | DEBUG_VK_POINTS, "Cur= rentKeyboardDisplay: 0x%04x \n", VkContext->CurrentKeyboardDisplay)); + DEBUG ((DEBUG_VK_TIMER_ENTRY_EXIT | DEBUG_INFO | DEBUG_VK_POINTS, "X: = 0x%016Lx\n", Point.CurrentX)); + DEBUG ((DEBUG_VK_TIMER_ENTRY_EXIT | DEBUG_INFO | DEBUG_VK_POINTS, "Y: = 0x%016Lx\n", Point.CurrentY)); + DEBUG ((DEBUG_VK_TIMER_ENTRY_EXIT | DEBUG_INFO | DEBUG_VK_POINTS, "Z: = 0x%016Lx\n", Point.CurrentZ)); + DEBUG ((DEBUG_VK_TIMER_ENTRY_EXIT | DEBUG_INFO | DEBUG_VK_POINTS, "But= tons: 0x%08x \n", Point.ActiveButtons)); + DEBUG ((DEBUG_VK_TIMER_ENTRY_EXIT | DEBUG_INFO | DEBUG_VK_POINTS, "Map= Key Index: 0x%04x \n", Index)); + DEBUG ((DEBUG_VK_TIMER_ENTRY_EXIT | DEBUG_INFO | DEBUG_VK_POINTS, "Key= Unicode: 0x%08x \n", Font)); + + switch (Font) { + // + // Touch the small keyboard icon, show/hide the keyboard. + // + case VkKeyTypeMaximum: + KeyboardLayoutHandler (VkContext, Index); + break; + + // + // Touch the key raw. + // + default: + if (VkContext->CurrentKeyboardDisplay =3D=3D VkDisplayAttributeNone)= { + break; + } + VkPushTheKey (VkContext, (UINT16) Font); + } + VkContext->KeyPressed =3D TRUE; + } + + DEBUG ((DEBUG_VK_TIMER_ENTRY_EXIT, "VkTimer Success, Status: %r\n", Stat= us)); + goto End; + +Error: + DEBUG ((DEBUG_VK_TIMER_ENTRY_EXIT, "VkTimer Failed, Status: %r\n", Statu= s)); + +End: + DEBUG ((DEBUG_VK_TIMER_ENTRY_EXIT, "VkTimer End\n")); + return; +} + +/** + VkTouchWaitForKey - SignalEvent when the keybuffer has keys. + + @param[in] Event Event whose notification function is being invoked. + @param[in] Context Pointer to the notification function's context, + which is implementation-dependent. Context correspo= nds + to NotifyContext in CreateEventEx(). + +**/ +VOID +EFIAPI +VkTouchWaitForKey ( + IN EFI_EVENT Event, + IN VOID *Context + ) +{ + VK_CONTEXT *VkContext; + + DEBUG ((DEBUG_VK_ROUTINE_ENTRY_EXIT, "VkTouchWaitForKey Start\n")); + VkContext =3D (VK_CONTEXT*) Context; + + if (VkContext->KeyStartIndex !=3D VkContext->KeyEndIndex) { + DEBUG ((DEBUG_VK_KEYS, "Signal VkTouchWaitForKey\n")); + gBS->SignalEvent (Event); + } + + DEBUG ((DEBUG_VK_ROUTINE_ENTRY_EXIT, "VkTouchWaitForKey End\n")); +} + +/** + Get image file data from BIOS image through specific ImageId. + + @param[in] VkContext Address of an VK_CONTEXT structure. + @param[in] ImageId Guid to get specific image file used. + + @retval EFI_IMAGE_INPUT Image data on BIOS image. + +**/ +EFI_IMAGE_INPUT* +VkGetImage ( + IN VK_CONTEXT *VkContext, + IN EFI_IMAGE_ID ImageId + ) +{ + EFI_STATUS Status; + EFI_IMAGE_INPUT Image; + EFI_IMAGE_INPUT *VkImage; + + + Status =3D VkContext->HiiImageEx->GetImageEx ( + VkContext->HiiImageEx, + VkContext->HiiHandle, + ImageId, + &Image + ); + if (EFI_ERROR (Status)) { + ASSERT_EFI_ERROR (Status); + } + + VkImage =3D AllocateCopyPool (sizeof (EFI_IMAGE_INPUT), &Image); + if (VkImage =3D=3D NULL) { + ASSERT_EFI_ERROR (EFI_OUT_OF_RESOURCES); + return NULL; + } + + return VkImage; +} + +/** + Dump partial debug message on VkContext. + + @param[in] VkContext Address of an VK_CONTEXT structure. + +**/ +VOID +VkDumpContext ( + IN VK_CONTEXT *VkContext + ) +{ + DEBUG (( + DEBUG_VK_ROUTINE_ENTRY_EXIT, + "VkContext->Signature: 0x%016x\n", + VkContext->Signature + )); + DEBUG (( + DEBUG_VK_ROUTINE_ENTRY_EXIT, + "VkContext->Controller: 0x%016x\n", + VkContext->Controller + )); + DEBUG (( + DEBUG_VK_ROUTINE_ENTRY_EXIT | DEBUG_VK_GRAPHICS_INFO, + "VkContext->GraphicsOutput->Mode->MaxMode: 0x%08x\n", + VkContext->GraphicsOutput->Mode->MaxMode + )); + DEBUG (( + DEBUG_VK_ROUTINE_ENTRY_EXIT | DEBUG_VK_GRAPHICS_INFO, + "VkContext->GraphicsOutput->Mode->Mode: 0x%08x\n", + VkContext->GraphicsOutput->Mode->Mode + )); + DEBUG (( + DEBUG_VK_ROUTINE_ENTRY_EXIT | DEBUG_VK_GRAPHICS_INFO, + "VkContext->GraphicsOutput->Mode->Info->HorizontalResolution: 0x%08x\n= ", + VkContext->GraphicsOutput->Mode->Info->HorizontalResolution + )); + DEBUG (( + DEBUG_VK_ROUTINE_ENTRY_EXIT | DEBUG_VK_GRAPHICS_INFO, + "VkContext->GraphicsOutput->Mode->Info->VerticalResolution: 0x%08x\n", + VkContext->GraphicsOutput->Mode->Info->VerticalResolution + )); + DEBUG (( + DEBUG_VK_ROUTINE_ENTRY_EXIT | DEBUG_VK_POINTS, + "VkContext->AbsolutePointer->Mode X: 0x%016Lx - 0x%016Lx\n", + VkContext->AbsolutePointer->Mode->AbsoluteMinX, + VkContext->AbsolutePointer->Mode->AbsoluteMaxX + )); + DEBUG (( + DEBUG_VK_ROUTINE_ENTRY_EXIT | DEBUG_VK_POINTS, + "VkContext->AbsolutePointer->Mode Y: 0x%016Lx - 0x%016Lx\n", + VkContext->AbsolutePointer->Mode->AbsoluteMinY, + VkContext->AbsolutePointer->Mode->AbsoluteMaxY + )); + DEBUG (( + DEBUG_VK_ROUTINE_ENTRY_EXIT | DEBUG_VK_POINTS, + "VkContext->AbsolutePointer->Mode Z: 0x%016Lx - 0x%016Lx\n", + VkContext->AbsolutePointer->Mode->AbsoluteMinZ, + VkContext->AbsolutePointer->Mode->AbsoluteMaxZ + )); + DEBUG (( + DEBUG_VK_ROUTINE_ENTRY_EXIT | DEBUG_VK_POINTS, + "VkContext->AbsolutePointer->Mode->Attributes: 0x%08x\n", + VkContext->AbsolutePointer->Mode->Attributes + )); +} + +/** + Start the virtual keyboard driver + + This routine allocates the necessary resources for the driver. + + This routine is called by VirtualKeyboardDriverStart to complete the dri= ver + initialization. + + @param[in, out] VkContext Address of an VK_CONTEXT structure + @param[in] Controller Handle of device to work with. + + @retval EFI_SUCCESS Driver API properly initialized + +**/ +EFI_STATUS +VkApiStart ( + IN OUT VK_CONTEXT *VkContext, + IN EFI_HANDLE Controller + ) +{ + EFI_STATUS Status; + EFI_SIMPLE_TEXT_INPUT_EX_PROTOCOL *SimpleEx; + EFI_KEY_DATA KeyData; + EFI_HANDLE NotifyHandle; + EFI_EVENT ReadyToBootEvent; + + DEBUG ((DEBUG_VK_ROUTINE_ENTRY_EXIT, "VkApiStart Start\n")); + + Status =3D gBS->CreateEvent ( + EVT_NOTIFY_SIGNAL, + TPL_CALLBACK, + VkKeyNotifyProcessHandler, + VkContext, + &VkContext->KeyNotifyProcessEvent + ); + if (EFI_ERROR (Status)) { + DEBUG ((DEBUG_VK_ROUTINE_ENTRY_EXIT | DEBUG_ERROR, "ERROR - Failed to = create VkContext->KeyNotifyProcessEvent, Status: %r\n", Status)); + goto Error; + } + + Status =3D gBS->CreateEvent ( + EVT_NOTIFY_WAIT, + TPL_NOTIFY, + VkTouchWaitForKey, + VkContext, + &(VkContext->SimpleTextIn.WaitForKey) + ); + if (EFI_ERROR (Status)) { + DEBUG ((DEBUG_VK_ROUTINE_ENTRY_EXIT | DEBUG_ERROR, "ERROR - Failed to = create VkContext->SimpleTextIn.WaitForKey, Status: %r\n", Status)); + goto Error; + } + + Status =3D gBS->CreateEvent ( + EVT_NOTIFY_WAIT, + TPL_NOTIFY, + VkTouchWaitForKey, + VkContext, + &(VkContext->SimpleTextInEx.WaitForKeyEx) + ); + if (EFI_ERROR (Status)) { + DEBUG ((DEBUG_VK_ROUTINE_ENTRY_EXIT | DEBUG_ERROR, "ERROR - Failed to = create VkContext->SimpleTextInEx.WaitForKeyEx, Status %r\n", Status)); + goto Error; + } + + Status =3D gBS->CreateEvent ( + EVT_TIMER | EVT_NOTIFY_SIGNAL, + TPL_VK_SYNC, + VkTimer, + (VOID *)VkContext, + &(VkContext->TimerEvent) + ); + if (EFI_ERROR (Status)) { + DEBUG ((DEBUG_VK_ROUTINE_ENTRY_EXIT | DEBUG_ERROR, "ERROR - Failed to = create the timer event, Status: %r\n", Status)); + goto Error; + } + + Status =3D gBS->SetTimer ( + VkContext->TimerEvent, + TimerPeriodic, + (UINT64) VK_POLL_INTERVAL + ); + if (EFI_ERROR (Status)) { + DEBUG ((DEBUG_VK_ROUTINE_ENTRY_EXIT | DEBUG_ERROR, "ERROR - Failed to = set the timer event, Status: %r\n", Status)); + goto Error; + } + + // + // Create event to clear keyboard before boot into OS. + // + Status =3D EfiCreateEventReadyToBootEx ( + TPL_CALLBACK, + VkReadyToBootCallBack, + (VOID *)VkContext, + &ReadyToBootEvent + ); + if (EFI_ERROR (Status)) { + DEBUG ((DEBUG_VK_ROUTINE_ENTRY_EXIT | DEBUG_ERROR, "ERROR - Failed to = create ReadyToBootEvent, Status: %r\n", Status)); + goto Error; + } + + Status =3D gBS->LocateProtocol ( + &gEfiHiiImageExProtocolGuid, + NULL, + (VOID **) &VkContext->HiiImageEx + ); + if (EFI_ERROR (Status)) { + DEBUG ((DEBUG_VK_ROUTINE_ENTRY_EXIT | DEBUG_ERROR, "ERROR - Failed to = open HiiImageEx protocol, Status: %r\n", Status)); + goto Error; + } + + // + // Initialize VkContext + // + VkContext->Signature =3D VK_SIGNATURE; + VkContext->Controller =3D Controller; + VkContext->SimpleTextIn.Reset =3D VkKeyboardReset; + VkContext->SimpleTextIn.ReadKeyStroke =3D VkKeyboardReadKeyStrok= e; + VkContext->SimpleTextInEx.Reset =3D VkKeyboardResetEx; + VkContext->SimpleTextInEx.ReadKeyStrokeEx =3D VkKeyboardReadKeyStrok= eEx; + VkContext->SimpleTextInEx.SetState =3D VkKeyboardSetState; + VkContext->SimpleTextInEx.RegisterKeyNotify =3D VkKeyboardRegisterKeyN= otify; + VkContext->SimpleTextInEx.UnregisterKeyNotify =3D VkKeyboardUnregisterKe= yNotify; + VkContext->IsIconShowed =3D FALSE; + VkContext->IsBackgroundChanged =3D FALSE; + VkContext->PageNumber =3D 0; + VkContext->CurrentKeyboardDisplay =3D VkDisplayAttributeNone; + VkContext->TargetKeyboardDisplay =3D VkDisplayAttributeNone; + VkContext->VkBodyBackgroundBltBuffer =3D NULL; + VkContext->VkBodyCompoundBltBuffer =3D NULL; + VkContext->VkBodyBltSize =3D 0; + VkContext->VkBodyBltStartX =3D 0; + VkContext->VkBodyBltStartY =3D 0; + VkContext->VkBodyBltHeight =3D 0; + VkContext->VkBodyBltWidth =3D 0; + VkContext->IconBltBuffer =3D NULL; + VkContext->IconBltSize =3D 0; + VkContext->IconReDrawCheck =3D 0; + VkContext->FullIconUpdatedFlag =3D FALSE; + VkContext->SimIconUpdatedFlag =3D FALSE; + VkContext->KeyStartIndex =3D 0; + VkContext->KeyEndIndex =3D 0; + VkContext->KeyToggleState =3D EFI_TOGGLE_STATE_VALID; + VkContext->SmallIcon =3D VkGetImage (VkContext,= IMAGE_TOKEN (IMG_VK_SIMPLEICON)); + VkContext->FullIcon =3D VkGetImage (VkContext,= IMAGE_TOKEN (IMG_VK_FULLICON)); + VkContext->SimKeyBody =3D VkGetImage (VkContext,= IMAGE_TOKEN (IMG_VK_SIMPLEKEYBOARD)); + VkContext->DigKeyBody =3D VkGetImage (VkContext,= IMAGE_TOKEN (IMG_VK_DIGITKEYBOARD)); + VkContext->CapLeKeyBody =3D VkGetImage (VkContext,= IMAGE_TOKEN (IMG_VK_CAPITALLETTERKEYBOARD)); + + InitializeListHead (&VkContext->NotifyList); + + Status =3D SetCharacterPosition (VkContext, 800, 600); + ASSERT_EFI_ERROR (Status); + + Status =3D DrawKeyboardLayout (VkContext); + ASSERT_EFI_ERROR (Status); + + Status =3D HideVkBody (VkContext); + ASSERT_EFI_ERROR (Status); + + Status =3D HideVkIcon (VkContext); + ASSERT_EFI_ERROR (Status); + + DEBUG_CODE ( + VkDumpContext (VkContext); + ); + + Status =3D gBS->HandleProtocol ( + gST->ConsoleInHandle, + &gEfiSimpleTextInputExProtocolGuid, + (VOID **)&SimpleEx + ); + if (EFI_ERROR (Status)) { + DEBUG ((DEBUG_VK_ROUTINE_ENTRY_EXIT | DEBUG_ERROR, "ERROR - Failed to = found ConIn Protocol, Status: %r\n", Status)); + goto Error; + } + + KeyData.KeyState.KeyToggleState =3D 0; + KeyData.KeyState.KeyShiftState =3D 0; + KeyData.Key.ScanCode =3D SCAN_ESC; + KeyData.Key.UnicodeChar =3D CHAR_NULL; + NotifyHandle =3D NULL; + Status =3D SimpleEx->RegisterKeyNotify ( + SimpleEx, + &KeyData, + VkNotifyKeyCallback, + &NotifyHandle + ); + if (EFI_ERROR (Status)) { + DEBUG ((DEBUG_VK_ROUTINE_ENTRY_EXIT | DEBUG_ERROR, "ERROR - Failed to = register 'Esc', Status: %r\n", Status)); + goto Error; + } + + KeyData.KeyState.KeyToggleState =3D 0; + KeyData.KeyState.KeyShiftState =3D 0; + KeyData.Key.ScanCode =3D SCAN_NULL; + KeyData.Key.UnicodeChar =3D CHAR_CARRIAGE_RETURN; + Status =3D SimpleEx->RegisterKeyNotify ( + SimpleEx, + &KeyData, + VkNotifyKeyCallback, + &NotifyHandle + ); + if (EFI_ERROR (Status)) { + DEBUG ((DEBUG_VK_ROUTINE_ENTRY_EXIT | DEBUG_ERROR, "ERROR - Failed to = register 'Enter', Status: %r\n", Status)); + goto Error; + } + + for (KeyData.Key.UnicodeChar =3D L' '; KeyData.Key.UnicodeChar <=3D L'~'= ; KeyData.Key.UnicodeChar++) { + Status =3D SimpleEx->RegisterKeyNotify ( + SimpleEx, + &KeyData, + VkNotifyKeyCallback, + &NotifyHandle + ); + if (EFI_ERROR (Status)) { + DEBUG (( + DEBUG_VK_ROUTINE_ENTRY_EXIT | DEBUG_ERROR, + "ERROR - Failed to register '%c', Status: %r\n", + KeyData.Key.UnicodeChar, + Status + )); + break; + } + } + if (EFI_ERROR(Status)) { + goto Error; + } + + DEBUG ((DEBUG_VK_ROUTINE_ENTRY_EXIT, "VkApiStart Success, Status: %r\n",= Status)); + goto End; + +Error: + VkApiStop (VkContext); + DEBUG ((DEBUG_VK_ROUTINE_ENTRY_EXIT, "VkApiStart Failed, Status: %r\n", = Status)); + +End: + DEBUG ((DEBUG_VK_ROUTINE_ENTRY_EXIT, "VkApiStart End\n")); + return Status; +} + +/** + Stop the virtual keyboard driver + + This routine releases the resources allocated by VKApiStart. + + This routine is called by VirtualKeyboardDriverStop to initiate the driv= er + shutdown. + + @param[in] VkContext Address of an VK_CONTEXT structure + +**/ +VOID +VkApiStop ( + IN VK_CONTEXT *VkContext + ) +{ + EFI_STATUS Status; + VK_NOTIFY *NotifyNode; + LIST_ENTRY *NotifyList; + + DEBUG ((DEBUG_VK_ROUTINE_ENTRY_EXIT, "VkApiStop Start\n")); + + Status =3D gBS->SetTimer (VkContext->TimerEvent, TimerCancel, 0); + ASSERT_EFI_ERROR (Status); + + if (VkContext->KeyNotifyProcessEvent !=3D NULL) { + Status =3D gBS->CloseEvent (VkContext->KeyNotifyProcessEvent); + ASSERT_EFI_ERROR (Status); + VkContext->KeyNotifyProcessEvent =3D NULL; + } + + if (VkContext->TimerEvent !=3D NULL) { + Status =3D gBS->CloseEvent (VkContext->TimerEvent); + ASSERT_EFI_ERROR (Status); + VkContext->TimerEvent =3D NULL; + } + + if (VkContext->SimpleTextIn.WaitForKey !=3D NULL) { + Status =3D gBS->CloseEvent (VkContext->SimpleTextIn.WaitForKey); + ASSERT_EFI_ERROR (Status); + VkContext->SimpleTextIn.WaitForKey =3D NULL; + } + + if (VkContext->SimpleTextInEx.WaitForKeyEx !=3D NULL) { + Status =3D gBS->CloseEvent (VkContext->SimpleTextInEx.WaitForKeyEx); + ASSERT_EFI_ERROR (Status); + VkContext->SimpleTextInEx.WaitForKeyEx =3D NULL; + } + + NotifyList =3D &VkContext->NotifyList; + if (NotifyList !=3D NULL) { + while (!IsListEmpty (NotifyList)) { + NotifyNode =3D CR (NotifyList->ForwardLink, VK_NOTIFY, NotifyEntry, = VK_NOTIFY_SIGNATURE); + RemoveEntryList (NotifyList->ForwardLink); + gBS->FreePool (NotifyNode); + } + } + + DEBUG ((DEBUG_VK_ROUTINE_ENTRY_EXIT, "VkApiStop End\n")); +} + +/** + Reset the input device and optionally run diagnostics + + @param[in] This Protocol instance pointer. + @param[in] ExtendedVerification Driver may perform diagnostics on reset. + + @retval EFI_SUCCESS The device was reset. + @retval EFI_DEVICE_ERROR The device is not functioning properly a= nd could not be reset. + +**/ +EFI_STATUS +EFIAPI +VkKeyboardReset ( + IN EFI_SIMPLE_TEXT_INPUT_PROTOCOL *This, + IN BOOLEAN ExtendedVerification + ) +{ + EFI_STATUS Status; + + DEBUG ((DEBUG_VK_ROUTINE_ENTRY_EXIT, "VkKeyboardReset Start\n")); + Status =3D EFI_SUCCESS; + DEBUG ((DEBUG_VK_ROUTINE_ENTRY_EXIT, "VkKeyboardReset End\n")); + return Status; +} + +/** + Resets the input device hardware. + + The Reset() function resets the input device hardware. As part + of initialization process, the firmware/device will make a quick + but reasonable attempt to verify that the device is functioning. + If the ExtendedVerification flag is TRUE the firmware may take + an extended amount of time to verify the device is operating on + reset. Otherwise the reset operation is to occur as quickly as + possible. The hardware verification process is not defined by + this specification and is left up to the platform firmware or + driver to implement. + + @param[in] This A pointer to the EFI_SIMPLE_TEXT_INPUT_E= X_PROTOCOL instance. + + @param[in] ExtendedVerification Indicates that the driver may perform a = more exhaustive + verification operation of the device dur= ing reset. + + @retval EFI_SUCCESS The device was reset. + @retval EFI_DEVICE_ERROR The device is not functioning correctly = and could not be reset. + +**/ +EFI_STATUS +EFIAPI +VkKeyboardResetEx ( + IN EFI_SIMPLE_TEXT_INPUT_EX_PROTOCOL *This, + IN BOOLEAN ExtendedVerification + ) +{ + EFI_STATUS Status; + VK_CONTEXT *VkContext; + + DEBUG ((DEBUG_VK_ROUTINE_ENTRY_EXIT, "VkKeyboardResetEx Start\n")); + + Status =3D EFI_SUCCESS; + if (This =3D=3D NULL) { + Status =3D EFI_INVALID_PARAMETER; + goto Error; + } + + VkContext =3D VK_CONTEXT_FROM_SIMPLETEXTINEX_PROTOCOL (This); + + Status =3D VkContext->SimpleTextIn.Reset (&VkContext->SimpleTextIn, Exte= ndedVerification); + if (EFI_ERROR (Status)) { + DEBUG ((DEBUG_VK_KEYS, "ERROR - Failed to VK reset, Status: %r\n", Sta= tus)); + goto Error; + } + + DEBUG ((DEBUG_VK_ROUTINE_ENTRY_EXIT, "VkKeyboardResetEx Success, Status:= %r\n", Status)); + goto End; + +Error: + DEBUG ((DEBUG_VK_ROUTINE_ENTRY_EXIT, "VkKeyboardResetEx Failed, Status: = %r\n", Status)); + +End: + DEBUG ((DEBUG_VK_ROUTINE_ENTRY_EXIT, "VkKeyboardResetEx End\n")); + return Status; +} + +/** + Reads the next keystroke from the input device. The WaitForKey Event can + be used to test for existence of a keystroke via WaitForEvent () call. + + @param[in] This Protocol instance pointer. + @param[out] Key Driver may perform diagnostics on reset. + + @retval EFI_SUCCESS The keystroke information was returned. + @retval EFI_NOT_READY There was no keystroke data available. + @retval EFI_DEVICE_ERROR The keystroke information was not returned due = to + hardware errors. + +**/ +EFI_STATUS +EFIAPI +VkKeyboardReadKeyStroke ( + IN EFI_SIMPLE_TEXT_INPUT_PROTOCOL *This, + OUT EFI_INPUT_KEY *Key + ) +{ + EFI_STATUS Status; + VK_CONTEXT *VkContext; + EFI_KEY_DATA TmpKeyData; + EFI_TPL OldTpl; + + DEBUG ((DEBUG_VK_ROUTINE_ENTRY_EXIT, "VkKeyboardReadKeyStroke Start\n")); + + OldTpl =3D gBS->RaiseTPL (TPL_NOTIFY); + if (This =3D=3D NULL || Key =3D=3D NULL) { + Status =3D EFI_INVALID_PARAMETER; + goto Error; + } + + VkContext =3D VK_CONTEXT_FROM_PROTOCOL (This); + + Status =3D VkKeyboardReadKeyStrokeEx (&VkContext->SimpleTextInEx, &TmpKe= yData); + if (EFI_ERROR (Status)) { + goto Error; + } + *Key =3D TmpKeyData.Key; + + + DEBUG ((DEBUG_VK_ROUTINE_ENTRY_EXIT, "VkKeyboardReadKeyStroke Success, S= tatus: %r\n", Status)); + goto End; + +Error: + DEBUG ((DEBUG_VK_ROUTINE_ENTRY_EXIT, "VkKeyboardReadKeyStroke Failed, St= atus: %r\n", Status)); + +End: + gBS->RestoreTPL (OldTpl); + DEBUG ((DEBUG_VK_ROUTINE_ENTRY_EXIT, "VkKeyboardReadKeyStroke End\n")); + return Status; +} + +/** + Reads the next keystroke from the input device. + + @param[in] This Protocol instance pointer. + @param[out] KeyData A pointer to a buffer that is filled in w= ith 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 available. + @retval EFI_INVALID_PARAMETER This or KeyData is NULL. + +**/ +EFI_STATUS +EFIAPI +VkKeyboardReadKeyStrokeEx ( + IN EFI_SIMPLE_TEXT_INPUT_EX_PROTOCOL *This, + OUT EFI_KEY_DATA *KeyData + ) +{ + VK_CONTEXT *VkContext; + EFI_STATUS Status; + EFI_TPL OldTpl; + EFI_KEY_DATA TmpKeyData; + + DEBUG ((DEBUG_VK_ROUTINE_ENTRY_EXIT, "VkKeyboardReadKeyStrokeEx Start\n"= )); + + OldTpl =3D gBS->RaiseTPL (TPL_NOTIFY); + if (This =3D=3D NULL || KeyData =3D=3D NULL) { + Status =3D EFI_INVALID_PARAMETER; + goto Error; + } + + VkContext =3D VK_CONTEXT_FROM_SIMPLETEXTINEX_PROTOCOL (This); + + while (TRUE) { + Status =3D VkPopTheKey (VkContext, &TmpKeyData); + if (EFI_ERROR (Status)) { + DEBUG ((DEBUG_VK_KEYS, "ERROR - Failed to VkPopTheKey check whether = keybuffer is empty, Status: %r\n", Status)); + goto Error; + } + if (TmpKeyData.Key.ScanCode !=3D SCAN_NULL || TmpKeyData.Key.UnicodeCh= ar !=3D CHAR_NULL) { + break; + } + } + *KeyData =3D TmpKeyData; + + DEBUG ((DEBUG_VK_ROUTINE_ENTRY_EXIT, "VkKeyboardReadKeyStrokeEx Success,= Status: %r\n", Status)); + goto End; + +Error: + DEBUG ((DEBUG_VK_ROUTINE_ENTRY_EXIT, "VkKeyboardReadKeyStrokeEx Failed, = Status: %r\n", Status)); + +End: + gBS->RestoreTPL (OldTpl); + DEBUG ((DEBUG_VK_ROUTINE_ENTRY_EXIT, "VkKeyboardReadKeyStrokeEx End\n")); + return Status; +} + +/** + Set certain state for the input device. + + @param[in] This Protocol instance pointer. + @param[in] KeyToggleState A pointer to the EFI_KEY_TOGGLE_STATE to= set the + state for the input device. + + @retval EFI_SUCCESS The device state was set appropriately. + @retval EFI_INVALID_PARAMETER This or KeyToggleState is NULL. + +**/ +EFI_STATUS +EFIAPI +VkKeyboardSetState ( + IN EFI_SIMPLE_TEXT_INPUT_EX_PROTOCOL *This, + IN EFI_KEY_TOGGLE_STATE *KeyToggleState + ) +{ + EFI_STATUS Status; + VK_CONTEXT *VkContext; + + DEBUG ((DEBUG_VK_ROUTINE_ENTRY_EXIT, "VkKeyboardSetState Start\n")); + + Status =3D EFI_SUCCESS; + if (This =3D=3D NULL || KeyToggleState =3D=3D NULL) { + Status =3D EFI_INVALID_PARAMETER; + goto Error; + } + + VkContext =3D VK_CONTEXT_FROM_SIMPLETEXTINEX_PROTOCOL (This); + + VkContext->KeyToggleState =3D *KeyToggleState; + VkContext->IsCapsLockFlag =3D (*KeyToggleState & EFI_CAPS_LOCK_ACTI= VE) =3D=3D EFI_CAPS_LOCK_ACTIVE; + VkContext->IsSupportPartialKey =3D (*KeyToggleState & EFI_KEY_STATE_EXPO= SED) =3D=3D EFI_KEY_STATE_EXPOSED; + + if (VkContext->PageNumber >=3D VkPage0 && VkContext->PageNumber <=3D VkP= age1) { + VkContext->PageNumber =3D VkContext->IsCapsLockFlag ? VkPage1 : VkPage= 0; + } + + HideVkBody (VkContext); + DrawKeyboardLayout (VkContext); + + DEBUG ((DEBUG_VK_KEYS | DEBUG_INFO, "VkContext->KeyToggleState: %02= x\n", VkContext->KeyToggleState)); + DEBUG ((DEBUG_VK_KEYS | DEBUG_INFO, "VkContext->IsCapsLockFlag: %02= x\n", VkContext->IsCapsLockFlag)); + DEBUG ((DEBUG_VK_KEYS | DEBUG_INFO, "VkContext->IsSupportPartialKey: %02= x\n", VkContext->IsSupportPartialKey)); + + DEBUG ((DEBUG_VK_ROUTINE_ENTRY_EXIT, "VkKeyboardSetState Success, Status= : %r\n", Status)); + goto End; + +Error: + DEBUG ((DEBUG_VK_ROUTINE_ENTRY_EXIT, "VkKeyboardSetState Failed, Status:= %r\n", Status)); + +End: + DEBUG ((DEBUG_VK_ROUTINE_ENTRY_EXIT, "VkKeyboardSetState End\n")); + return Status; +} + +/** + Register a notification function for a particular keystroke for the inpu= t device. + + @param[in] This Protocol instance pointer. + @param[in] KeyData A pointer to a buffer that is fi= lled in with the keystroke + information data for the key tha= t was pressed. + @param[in] KeyNotificationFunction Points to the function to be cal= led when the key + sequence is typed specified by K= eyData. + @param[out] NotifyHandle Points to the unique handle assi= gned to the registered notification. + + @retval EFI_SUCCESS The notification function was re= gistered successfully. + @retval EFI_OUT_OF_RESOURCES Unable to allocate resources for= necessary data structures. + @retval EFI_INVALID_PARAMETER KeyData or NotifyHandle or KeyNo= tificationFunction is NULL. + +**/ +EFI_STATUS +EFIAPI +VkKeyboardRegisterKeyNotify ( + IN EFI_SIMPLE_TEXT_INPUT_EX_PROTOCOL *This, + IN EFI_KEY_DATA *KeyData, + IN EFI_KEY_NOTIFY_FUNCTION KeyNotificationFunction, + OUT EFI_HANDLE *NotifyHandle + ) +{ + EFI_STATUS Status; + EFI_TPL OldTpl; + VK_CONTEXT *VkContext; + LIST_ENTRY *Link; + VK_NOTIFY *CurrentNotify; + VK_NOTIFY *NewNotify; + + DEBUG ((DEBUG_VK_ROUTINE_ENTRY_EXIT, "VkKeyboardRegisterKeyNotify Start\= n")); + + // + // Enter critical section + // + OldTpl =3D gBS->RaiseTPL (TPL_NOTIFY); + Status =3D EFI_SUCCESS; + if (This =3D=3D NULL || KeyData =3D=3D NULL || NotifyHandle =3D=3D NULL = || KeyNotificationFunction =3D=3D NULL) { + Status =3D EFI_INVALID_PARAMETER; + goto Error; + } + VkContext =3D VK_CONTEXT_FROM_SIMPLETEXTINEX_PROTOCOL (This); + + + // + // Return EFI_SUCCESS if the (KeyData, NotificationFunction) is already = registered. + // + for (Link =3D VkContext->NotifyList.ForwardLink; Link !=3D &VkContext->N= otifyList; Link =3D Link->ForwardLink) { + CurrentNotify =3D CR (Link, VK_NOTIFY, NotifyEntry, VK_NOTIFY_SIGNATUR= E); + if (IsKeyRegistered (&CurrentNotify->KeyData, KeyData)) { + if (CurrentNotify->KeyNotificationFn =3D=3D KeyNotificationFunction)= { + *NotifyHandle =3D CurrentNotify; + Status =3D EFI_SUCCESS; + goto End; + } + } + } + + // + // Allocate resource to save the notification function + // + NewNotify =3D (VK_NOTIFY *) AllocateZeroPool (sizeof (VK_NOTIFY)); + if (NewNotify =3D=3D NULL) { + Status =3D EFI_OUT_OF_RESOURCES; + goto Error; + } + + NewNotify->Signature =3D VK_NOTIFY_SIGNATURE; + NewNotify->KeyNotificationFn =3D KeyNotificationFunction; + CopyMem (&NewNotify->KeyData, KeyData, sizeof (EFI_KEY_DATA)); + InsertTailList (&VkContext->NotifyList, &NewNotify->NotifyEntry); + + *NotifyHandle =3D NewNotify; + Status =3D EFI_SUCCESS; + + DEBUG ((DEBUG_VK_ROUTINE_ENTRY_EXIT, "VkKeyboardRegisterKeyNotify Succes= s, Status: %r\n", Status)); + goto End; + +Error: + DEBUG ((DEBUG_VK_ROUTINE_ENTRY_EXIT, "VkKeyboardRegisterKeyNotify Failed= , Status: %r\n", Status)); + +End: + // + // Leave critical section and return + // + gBS->RestoreTPL (OldTpl); + DEBUG ((DEBUG_VK_ROUTINE_ENTRY_EXIT, "VkKeyboardRegisterKeyNotify End\n"= )); + return Status; +} + +/** + Remove a registered notification function from a particular keystroke. + + @param[in] This Protocol instance pointer. + @param[in] NotificationHandle The handle of the notification function b= eing unregistered. + + @retval EFI_SUCCESS The notification function was unregistere= d successfully. + @retval EFI_INVALID_PARAMETER The NotificationHandle is invalid + +**/ +EFI_STATUS +EFIAPI +VkKeyboardUnregisterKeyNotify ( + IN EFI_SIMPLE_TEXT_INPUT_EX_PROTOCOL *This, + IN EFI_HANDLE NotificationHandle + ) +{ + EFI_STATUS Status; + VK_CONTEXT *VkContext; + EFI_TPL OldTpl; + LIST_ENTRY *Link; + VK_NOTIFY *CurrentNotify; + BOOLEAN IsFindNotifyHandle; + + DEBUG ((DEBUG_VK_ROUTINE_ENTRY_EXIT, "VkKeyboardUnregisterKeyNotify Star= t\n")); + + // + // Enter critical section + // + OldTpl =3D gBS->RaiseTPL (TPL_NOTIFY); + Status =3D EFI_SUCCESS; + if (This =3D=3D NULL || NotificationHandle =3D=3D NULL) { + Status =3D EFI_INVALID_PARAMETER; + goto Error; + } + VkContext =3D VK_CONTEXT_FROM_SIMPLETEXTINEX_PROTOCOL (This); + + IsFindNotifyHandle =3D FALSE; + for (Link =3D VkContext->NotifyList.ForwardLink; Link !=3D &VkContext->N= otifyList; Link =3D Link->ForwardLink) { + CurrentNotify =3D CR (Link, VK_NOTIFY, NotifyEntry, VK_NOTIFY_SIGNATUR= E); + if (CurrentNotify =3D=3D NotificationHandle) { + // + // Remove the notification function from NotifyList and free resourc= es + // + RemoveEntryList (&CurrentNotify->NotifyEntry); + + gBS->FreePool (CurrentNotify); + IsFindNotifyHandle =3D TRUE; + break; + } + } + + if (!IsFindNotifyHandle) { + Status =3D EFI_INVALID_PARAMETER; + goto Error; + } + + DEBUG ((DEBUG_VK_ROUTINE_ENTRY_EXIT, "VkKeyboardUnregisterKeyNotify Succ= ess, Status: %r\n", Status)); + goto End; + +Error: + DEBUG ((DEBUG_VK_ROUTINE_ENTRY_EXIT, "VkKeyboardUnregisterKeyNotify Fail= ed, Status: %r\n", Status)); + +End: + // + // Leave critical section and return + // + gBS->RestoreTPL (OldTpl); + DEBUG ((DEBUG_VK_ROUTINE_ENTRY_EXIT, "VkKeyboardUnregisterKeyNotify End\= n")); + return Status; +} diff --git a/Features/Intel/UserInterface/VirtualKeyboardFeaturePkg/Virtual= KeyboardDxe/KeyboardLayout.c b/Features/Intel/UserInterface/VirtualKeyboard= FeaturePkg/VirtualKeyboardDxe/KeyboardLayout.c new file mode 100644 index 0000000000..dcf78985ee --- /dev/null +++ b/Features/Intel/UserInterface/VirtualKeyboardFeaturePkg/VirtualKeyboar= dDxe/KeyboardLayout.c @@ -0,0 +1,1364 @@ +/** @file + Virtural Keyboard Layout Engine + + Copyright (c) 2012 - 2020, Intel Corporation. All rights reserved.
    + SPDX-License-Identifier: BSD-2-Clause-Patent + +**/ + +#include "VirtualKeyboard.h" + +// +// 1.FullKeyboardBody +// Follow below design +// (1).\KeyboardLayout\CapitalLetterKeyboard.bmp +// (2).\KeyboardLayout\DigitKeyboard.bmp +// Based on keyboard's (startX, startY) +// +// Page0Font +// +---+---+---+---+---+---+---+---+---+---+---+ +// | q | w | e | r | t | y | u | i | o | p | | ? |F11|F12|Enter| Line 2 +// +-----+---+---+---+---+---+---+---+---+---+-+ +// | Esc |12#| Space | | | _ | + | | Line 3 +// +-----+---+-------------------+---+---+---+-+ +// +// 2.Screen Corner +// Follow below design +// (1).\KeyboardLayout\SimpleIcon.bmp # Screen Corner A/B +// (2).\KeyboardLayout\FullIcon.bmp # Screen Corner C/D +// +-+------------------------------------+-+ +// |A| |C| +// +-+ +-+ +// | | +// | | +// | | +// | | +// | | +// | | +// +-+ +-+ +// |B| |D| +// +-+------------------------------------+-+ +// +VK_STRUCT mFullKeyboardBody[] =3D { + // StartX StartY EndX EndY Page0Font Page1Font = Page2Font Page3Font + // Line 0 + { 0x0000, 0x0000, 0x0032, 0x0032, {L'q', L'Q', = L'1', L'!' }}, + { 0x0032, 0x0000, 0x0064, 0x0032, {L'w', L'W', = L'2', L'@' }}, + { 0x0064, 0x0000, 0x0096, 0x0032, {L'e', L'E', = L'3', L'#' }}, + { 0x0096, 0x0000, 0x00C8, 0x0032, {L'r', L'R', = L'4', L'$' }}, + { 0x00C8, 0x0000, 0x00FA, 0x0032, {L't', L'T', = L'5', L'%' }}, + { 0x00FA, 0x0000, 0x012C, 0x0032, {L'y', L'Y', = L'6', L'^' }}, + { 0x012C, 0x0000, 0x015E, 0x0032, {L'u', L'U', = L'7', L'&' }}, + { 0x015E, 0x0000, 0x0190, 0x0032, {L'i', L'I', = L'8', L'*' }}, + { 0x0190, 0x0000, 0x01C2, 0x0032, {L'o', L'O', = L'9', L'(' }}, + { 0x01C2, 0x0000, 0x01F4, 0x0032, {L'p', L'P', = L'0', L')' }}, + { 0x01F4, 0x0000, 0x0226, 0x0032, {VkKeyBackspace, VkKeyBackspace,= VkKeyBackspace, VkKeyBackspace }}, + // Line 1 + { 0x0000, 0x0032, 0x0019, 0x0064, {VkKeyNull, VkKeyNull, = VkKeyNull, VkKeyNull }}, + { 0x0019, 0x0032, 0x004B, 0x0064, {L'a', L'A', = VkKeyF1, VkKeyF1 }}, + { 0x004B, 0x0032, 0x007D, 0x0064, {L's', L'S', = VkKeyF2, VkKeyF2 }}, + { 0x007D, 0x0032, 0x00AF, 0x0064, {L'd', L'D', = VkKeyF3, VkKeyF3 }}, + { 0x00AF, 0x0032, 0x00E1, 0x0064, {L'f', L'F', = VkKeyF4, VkKeyF4 }}, + { 0x00E1, 0x0032, 0x0113, 0x0064, {L'g', L'G', = VkKeyF5, VkKeyF5 }}, + { 0x0113, 0x0032, 0x0145, 0x0064, {L'h', L'H', = VkKeyF6, VkKeyF6 }}, + { 0x0145, 0x0032, 0x0177, 0x0064, {L'j', L'J', = VkKeyF7, VkKeyF7 }}, + { 0x0177, 0x0032, 0x01A9, 0x0064, {L'k', L'K', = VkKeyF8, VkKeyF8 }}, + { 0x01A9, 0x0032, 0x01DB, 0x0064, {L'l', L'L', = VkKeyF9, VkKeyF9 }}, + { 0x01DB, 0x0032, 0x020D, 0x0064, {VkKeyF2, VkKeyF2, = VkKeyF10, VkKeyF10 }}, + // Line 2 + { 0x0000, 0x0064, 0x004B, 0x0096, {VkKeyCapslock, VkKeyCapslock, = VkKeyShift, VkKeyShift }}, + { 0x004B, 0x0064, 0x007D, 0x0096, {L'z', L'Z', = L'`', L'~' }}, + { 0x007D, 0x0064, 0x00AF, 0x0096, {L'x', L'X', = L';', L':' }}, + { 0x00AF, 0x0064, 0x00E1, 0x0096, {L'c', L'C', = L'\'', L'"' }}, + { 0x00E1, 0x0064, 0x0113, 0x0096, {L'v', L'V', = L',', L'<' }}, + { 0x0113, 0x0064, 0x0145, 0x0096, {L'b', L'B', = L'.', L'>' }}, + { 0x0145, 0x0064, 0x0177, 0x0096, {L'n', L'N', = L'/', L'?' }}, + { 0x0177, 0x0064, 0x01A9, 0x0096, {L'm', L'M', = VkKeyF11, VkKeyF11 }}, + { 0x01A9, 0x0064, 0x01DB, 0x0096, {VkKeyUp, VkKeyUp, = VkKeyF12, VkKeyF12 }}, + { 0x01DB, 0x0064, 0x0226, 0x0096, {VkKeyEnter, VkKeyEnter, = VkKeyEnter, VkKeyEnter }}, + // Line 3 + { 0x0000, 0x0096, 0x004B, 0x00C8, {VkKeyEsc, VkKeyEsc, = VkKeyEsc, VkKeyEsc }}, + { 0x004B, 0x0096, 0x007D, 0x00C8, {VkKeyTwoPage, VkKeyTwoPage, = VkKeyTwoPage, VkKeyTwoPage }}, + { 0x007D, 0x0096, 0x0177, 0x00C8, {L' ', L' ', = L' ', L' ' }}, + { 0x0177, 0x0096, 0x01A9, 0x00C8, {VkKeyLeft, VkKeyLeft, = L'\\', L'|' }}, + { 0x01A9, 0x0096, 0x01DB, 0x00C8, {VkKeyDown, VkKeyDown, = L'-', L'_' }}, + { 0x01DB, 0x0096, 0x020D, 0x00C8, {VkKeyRight, VkKeyRight, = L'=3D', L'+' }}, + // Screen Corner A + { 0x0000, 0x0000, 0x001E, 0x001E, {VkKeyTypeMaximum, VkKeyTypeMaximu= m, VkKeyTypeMaximum, VkKeyTypeMaximum}}, + // Screen Corner B + { 0x0000, 0x023A, 0x001E, 0x0258, {VkKeyTypeMaximum, VkKeyTypeMaximu= m, VkKeyTypeMaximum, VkKeyTypeMaximum}}, + // Screen Corner C + { 0x02E4, 0x0000, 0x0320, 0x001E, {VkKeyTypeMaximum, VkKeyTypeMaximu= m, VkKeyTypeMaximum, VkKeyTypeMaximum}}, + // Screen Corner D + { 0x02E4, 0x023A, 0x0320, 0x0258, {VkKeyTypeMaximum, VkKeyTypeMaximu= m, VkKeyTypeMaximum, VkKeyTypeMaximum}} +}; + +// +// 1.SimpleKeyboardBody +// Follow below design +// (1).\KeyboardLayout\SimpleKeyboard.bmp +// Based on keyboard's (startX, startY) +// +-----+-----+ +// | Esc |Enter| Line 0 +// +-----+-----+ +// | Up | Down| Line 1 +// +-----+-----+ +// +// 2.Screen Corner +// Follow below design +// (1).\KeyboardLayout\SimpleIcon.bmp # Screen Corner A/B +// (2).\KeyboardLayout\FullIcon.bmp # Screen Corner C/D +// +-+------------------------------------+-+ +// |A| |C| +// +-+ +-+ +// | | +// | | +// | | +// | | +// | | +// | | +// +-+ +-+ +// |B| |D| +// +-+------------------------------------+-+ +// +VK_STRUCT mSimpleKeyboardBody[] =3D { + // StartX StartY EndX EndY Page0Font Page1Font = Page2Font Page3Font + // Line 0 + { 0x0000, 0x0000, 0x0032, 0x0032, {VkKeyEsc, VkKeyEsc, = VkKeyEsc, VkKeyEsc }}, + { 0x0032, 0x0000, 0x0064, 0x0032, {VkKeyEnter, VkKeyEnter, = VkKeyEnter, VkKeyEnter }}, + // Line 1 + { 0x0000, 0x0032, 0x0032, 0x0064, {VkKeyUp, VkKeyUp, = VkKeyUp, VkKeyUp }}, + { 0x0032, 0x0032, 0x0064, 0x0064, {VkKeyDown, VkKeyDown, = VkKeyDown, VkKeyDown }}, + // Screen Corner A + { 0x0000, 0x0000, 0x001E, 0x001E, {VkKeyTypeMaximum, VkKeyTypeMaximu= m, VkKeyTypeMaximum, VkKeyTypeMaximum}}, + // Screen Corner B + { 0x0000, 0x023A, 0x001E, 0x0258, {VkKeyTypeMaximum, VkKeyTypeMaximu= m, VkKeyTypeMaximum, VkKeyTypeMaximum}}, + // Screen Corner C + { 0x02E4, 0x0000, 0x0320, 0x001E, {VkKeyTypeMaximum, VkKeyTypeMaximu= m, VkKeyTypeMaximum, VkKeyTypeMaximum}}, + // Screen Corner D + { 0x02E4, 0x023A, 0x0320, 0x0258, {VkKeyTypeMaximum, VkKeyTypeMaximu= m, VkKeyTypeMaximum, VkKeyTypeMaximum}} +}; + +EFI_STATUS +ModifyShiftKeyColor ( + IN VK_CONTEXT *VkContext, + IN OUT EFI_GRAPHICS_OUTPUT_BLT_PIXEL **BltBuffer + ) +{ + EFI_GRAPHICS_OUTPUT_BLT_PIXEL *TempBltBuffer; + UINTN BltSize; + BOOLEAN IsPressed; + + TempBltBuffer =3D *BltBuffer; + BltSize =3D VkContext->VkBodyBltHeight * VkContext->VkBodyBltWidth; + IsPressed =3D VkContext->PageNumber <=3D VkPage1 ? + VkContext->IsCapsLockFlag : + VkContext->IsShiftKeyFlag; + + while (BltSize-- !=3D 0) { + // + // Color gradient issue + // + if (((TempBltBuffer->Red - TempBltBuffer->Green) > 0x20) && + ((TempBltBuffer->Red - TempBltBuffer->Blue) > 0x20)) { + if (IsPressed) { + TempBltBuffer->Red =3D 0; + TempBltBuffer->Green =3D 255; + TempBltBuffer->Blue =3D 255; + } else { + TempBltBuffer->Red =3D 255; + TempBltBuffer->Green =3D 255; + TempBltBuffer->Blue =3D 255; + } + } + TempBltBuffer++; + } + + return EFI_SUCCESS; +} + +EFI_STATUS +MakeKeyboardTransparent ( + IN VK_CONTEXT *VkContext, + IN BOOLEAN IsTransparent, + IN EFI_GRAPHICS_OUTPUT_BLT_PIXEL *BltIn, + IN OUT EFI_GRAPHICS_OUTPUT_BLT_PIXEL **BltOut + ) +{ + EFI_GRAPHICS_OUTPUT_BLT_PIXEL *Compound; + EFI_GRAPHICS_OUTPUT_BLT_PIXEL *Keyboard; + EFI_GRAPHICS_OUTPUT_BLT_PIXEL *Background; + UINTN BltSize; + + if (*BltOut =3D=3D NULL) { + *BltOut =3D AllocateZeroPool (VkContext->VkBodyBltSize); + if (*BltOut =3D=3D NULL) { + return EFI_OUT_OF_RESOURCES; + } + } + Compound =3D *BltOut; + Keyboard =3D BltIn; + Background =3D VkContext->VkBodyBackgroundBltBuffer; + BltSize =3D VkContext->VkBodyBltHeight * VkContext->VkBodyBltWidth; + while (BltSize-- !=3D 0) { + if (IsTransparent) { + Compound->Red =3D (Keyboard->Red * TRANSPARENCY_WEIGHT) / 100 + (B= ackground->Red * (100 - TRANSPARENCY_WEIGHT)) / 100; + Compound->Green =3D (Keyboard->Green * TRANSPARENCY_WEIGHT) / 100 + = (Background->Green * (100 - TRANSPARENCY_WEIGHT)) / 100; + Compound->Blue =3D (Keyboard->Blue * TRANSPARENCY_WEIGHT) / 100 + (= Background->Blue * (100 - TRANSPARENCY_WEIGHT)) / 100; + } else { + *Compound =3D *Keyboard; + } + Compound++; + Keyboard++; + Background++; + } + + return EFI_SUCCESS; +} + +EFI_STATUS +EFIAPI +SaveVkBodyBackgroundBltBuffer ( + IN VK_CONTEXT *VkContext, + IN UINTN BltSize + ) +{ + EFI_STATUS Status; + EFI_GRAPHICS_OUTPUT_BLT_PIXEL *CurrentBltBuffer; + EFI_GRAPHICS_OUTPUT_BLT_PIXEL *CurrentBltBufferSave; + EFI_GRAPHICS_OUTPUT_BLT_PIXEL *OldBltBuffer; + EFI_GRAPHICS_OUTPUT_BLT_PIXEL *OldBltBufferSave; + EFI_GRAPHICS_OUTPUT_BLT_PIXEL *Compound; + EFI_GRAPHICS_OUTPUT_BLT_PIXEL *Background; + UINTN Size; + + CurrentBltBufferSave =3D NULL; + OldBltBufferSave =3D NULL; + + // + // Save original blt buffer first. + // + OldBltBuffer =3D AllocateZeroPool (VkContext->VkBodyBltSize); + if (OldBltBuffer =3D=3D NULL) { + return EFI_OUT_OF_RESOURCES; + } + if (VkContext->VkBodyBackgroundBltBuffer !=3D NULL) { + CopyMem (OldBltBuffer, VkContext->VkBodyBackgroundBltBuffer, VkContext= ->VkBodyBltSize); + } + + if (VkContext->VkBodyBackgroundBltBuffer =3D=3D NULL) { + VkContext->VkBodyBltSize =3D BltSize; + VkContext->VkBodyBackgroundBltBuffer =3D AllocateZeroPool (VkContext->= VkBodyBltSize); + ASSERT (VkContext->VkBodyBackgroundBltBuffer !=3D NULL); + if (VkContext->VkBodyBackgroundBltBuffer =3D=3D NULL) { + return EFI_OUT_OF_RESOURCES; + } + } else if (BltSize > VkContext->VkBodyBltSize) { + VkContext->VkBodyBltSize =3D BltSize; + FreePool (VkContext->VkBodyBackgroundBltBuffer); + VkContext->VkBodyBackgroundBltBuffer =3D NULL; + VkContext->VkBodyBackgroundBltBuffer =3D AllocateZeroPool (VkContext->= VkBodyBltSize); + ASSERT (VkContext->VkBodyBackgroundBltBuffer !=3D NULL); + if (VkContext->VkBodyBackgroundBltBuffer =3D=3D NULL) { + return EFI_OUT_OF_RESOURCES; + } + } else { + ZeroMem (VkContext->VkBodyBackgroundBltBuffer, VkContext->VkBodyBltSiz= e); + } + + CurrentBltBuffer =3D NULL; + if (VkContext->IsBackgroundChanged =3D=3D TRUE) { + // + // Background changed, merge current visioning blt buffer with old bac= kground blt buffer. + // + Compound =3D VkContext->VkBodyCompoundBltBuffer; + Background =3D VkContext->VkBodyBackgroundBltBuffer; + CurrentBltBuffer =3D AllocateZeroPool (VkContext->VkBodyBltSize); + ASSERT (CurrentBltBuffer !=3D NULL); + if (CurrentBltBuffer =3D=3D NULL) { + return EFI_OUT_OF_RESOURCES; + } + Status =3D VkContext->GraphicsOutput->Blt ( + VkContext->GraphicsOutput, + CurrentBltBuffer, + EfiBltVideoToBltBuffer, + VkContext->VkBodyBltStartX, + VkContext->VkBodyBltStartY, + 0, + 0, + VkContext->VkBodyBltWidth, + VkContext->VkBodyBltHeight, + VkContext->VkBodyBltWidth * size= of (EFI_GRAPHICS_OUTPUT_BLT_PIXEL) + ); + CurrentBltBufferSave =3D CurrentBltBuffer; + OldBltBufferSave =3D OldBltBuffer; + Size =3D VkContext->VkBodyBltHeight * VkContext->VkBodyBltWidth; + while (Size-- !=3D 0) { + if ((Compound->Red !=3D CurrentBltBuffer->Red) || + (Compound->Green !=3D CurrentBltBuffer->Green) || + (Compound->Blue !=3D CurrentBltBuffer->Blue)) { + *Background =3D *CurrentBltBuffer; + } else { + *Background =3D *OldBltBuffer; + } + Compound++; + Background++; + CurrentBltBuffer++; + OldBltBuffer++; + } + } else { + // + // Background NOT changed, save it to VkBodyBackgroundBltBuffer direct= ly. + // + Status =3D VkContext->GraphicsOutput->Blt ( + VkContext->GraphicsOutput, + VkContext->VkBodyBackgroundBltBu= ffer, + EfiBltVideoToBltBuffer, + VkContext->VkBodyBltStartX, + VkContext->VkBodyBltStartY, + 0, + 0, + VkContext->VkBodyBltWidth, + VkContext->VkBodyBltHeight, + VkContext->VkBodyBltWidth * size= of (EFI_GRAPHICS_OUTPUT_BLT_PIXEL) + ); + } + + if (CurrentBltBufferSave !=3D NULL) { + FreePool (CurrentBltBufferSave); + } + if (OldBltBufferSave !=3D NULL) { + FreePool (OldBltBufferSave); + } + + return Status; +} + +EFI_STATUS +EFIAPI +RestoreVkBodyBackgroundBltBuffer ( + IN VK_CONTEXT *VkContext + ) +{ + EFI_STATUS Status; + + if (VkContext->VkBodyBackgroundBltBuffer =3D=3D NULL) { + return EFI_UNSUPPORTED; + } + + Status =3D VkContext->GraphicsOutput->Blt ( + VkContext->GraphicsOutput, + VkContext->VkBodyBackgroundBltBuff= er, + EfiBltBufferToVideo, + 0, + 0, + VkContext->VkBodyBltStartX, + VkContext->VkBodyBltStartY, + VkContext->VkBodyBltWidth, + VkContext->VkBodyBltHeight, + VkContext->VkBodyBltWidth * sizeof= (EFI_GRAPHICS_OUTPUT_BLT_PIXEL) + ); + + FreePool (VkContext->VkBodyBackgroundBltBuffer); + VkContext->VkBodyBackgroundBltBuffer =3D NULL; + + return Status; +} + +EFI_STATUS +SetCharacterPosition ( + IN VK_CONTEXT *VkContext, + IN UINT32 DestX, + IN UINT32 DestY + ) +{ + UINTN Index; + VK_STRUCT *KeyArryPtr; + UINT32 KeyArrySize; + + switch (VkContext->TargetKeyboardDisplay) { + case VkDisplayAttributeSimpleTop: + case VkDisplayAttributeSimpleBottom: + KeyArryPtr =3D mSimpleKeyboardBody; + KeyArrySize =3D DIM (mSimpleKeyboardBody); + break; + + case VkDisplayAttributeFullBottom: + case VkDisplayAttributeFullTop: + KeyArryPtr =3D mFullKeyboardBody; + KeyArrySize =3D DIM (mFullKeyboardBody); + break; + + case VkDisplayAttributeNone: + KeyArryPtr =3D mFullKeyboardBody; + KeyArrySize =3D DIM (mFullKeyboardBody); + break; + + default: + return EFI_UNSUPPORTED; + } + + for (Index =3D 0; Index < KeyArrySize; Index++) { + VkContext->KeyboardBodyPtr[Index] =3D KeyArryPtr[Index]; + } + VkContext->NumOfKeysInfo =3D KeyArrySize; + + for (Index =3D 0; Index < (VkContext->NumOfKeysInfo - 4); Index++) { + VkContext->KeyboardBodyPtr[Index].DisStartX +=3D (UINT16)DestX; + VkContext->KeyboardBodyPtr[Index].DisStartY +=3D (UINT16)DestY; + VkContext->KeyboardBodyPtr[Index].DisEndX +=3D (UINT16)DestX; + VkContext->KeyboardBodyPtr[Index].DisEndY +=3D (UINT16)DestY; + } + + return EFI_SUCCESS; +} + +EFI_STATUS +EFIAPI +SaveVkIconBackgroundBltBuffer ( + IN VK_CONTEXT *VkContext, + IN VK_DISPLAY_ATTRIBUTE IconType + ) +{ + EFI_STATUS Status; + EFI_GRAPHICS_OUTPUT_BLT_PIXEL *GraphicBlt; + UINTN BltSize; + UINTN Height; + UINTN Width; + INTN StartX; + INTN StartY; + EFI_GRAPHICS_OUTPUT_BLT_PIXEL *TempIconBackBuffer; + EFI_GRAPHICS_OUTPUT_BLT_PIXEL *IconBackBuffer; + EFI_GRAPHICS_OUTPUT_BLT_PIXEL *Compound; + UINTN Size; + BOOLEAN SaveCursor; + + Status =3D EFI_SUCCESS; + StartX =3D 0; + StartY =3D 0; + TempIconBackBuffer =3D NULL; + IconBackBuffer =3D NULL; + Compound =3D NULL; + + if ((IconType =3D=3D VkDisplayAttributeFullTop) || + (IconType =3D=3D VkDisplayAttributeSimpleTop)) { + return EFI_SUCCESS; + } + + SaveCursor =3D gST->ConOut->Mode->CursorVisible; + gST->ConOut->EnableCursor (gST->ConOut, FALSE); + + if (IconType =3D=3D VkDisplayAttributeFullBottom) { + GraphicBlt =3D VkContext->FullIcon->Bitmap; + BltSize =3D VkContext->FullIcon->Height * VkContext->FullIcon->Widt= h * sizeof (EFI_GRAPHICS_OUTPUT_BLT_PIXEL); + Height =3D VkContext->FullIcon->Height; + Width =3D VkContext->FullIcon->Width; + StartX =3D VkContext->FullIconBackStartX; + StartY =3D VkContext->FullIconBackStartY; + } else if (IconType =3D=3D VkDisplayAttributeSimpleBottom) { + GraphicBlt =3D VkContext->SmallIcon->Bitmap; + BltSize =3D VkContext->SmallIcon->Height * VkContext->SmallIcon->Wi= dth * sizeof (EFI_GRAPHICS_OUTPUT_BLT_PIXEL); + Height =3D VkContext->SmallIcon->Height; + Width =3D VkContext->SmallIcon->Width; + StartX =3D VkContext->SimIconBackStartX; + StartY =3D VkContext->SimIconBackStartY; + } else { + gST->ConOut->EnableCursor (gST->ConOut, SaveCursor); + return EFI_UNSUPPORTED; + } + + IconBackBuffer =3D AllocateZeroPool (BltSize); + if (IconBackBuffer =3D=3D NULL) { + gST->ConOut->EnableCursor (gST->ConOut, SaveCursor); + return EFI_OUT_OF_RESOURCES; + } + TempIconBackBuffer =3D IconBackBuffer; + Status =3D VkContext->GraphicsOutput->Blt ( + VkContext->GraphicsOutput, + IconBackBuffer, + EfiBltVideoToBltBuffer, + StartX, + StartY, + 0, + 0, + Width, + Height, + Width * sizeof (EFI_GRAPHICS_OUTPU= T_BLT_PIXEL) + ); + + if (IconType =3D=3D VkDisplayAttributeFullBottom) { + // + // Store full icon background framebuffer + // + VkContext->FullIconBackHeight =3D Height; + VkContext->FullIconBackWidth =3D Width; + if (VkContext->FullIconUpdatedFlag =3D=3D FALSE) { + // + // No icon draw, save the buffer directly. + // + if (VkContext->FullIconBackBuffer =3D=3D NULL) { + VkContext->FullIconBackBuffer =3D AllocateZeroPool (BltSize); + VkContext->FullIconBackSize =3D BltSize; + } + CopyMem (VkContext->FullIconBackBuffer, IconBackBuffer, BltSize); + VkContext->FullIconUpdatedFlag =3D TRUE; + } else { + if (CompareMem (VkContext->FullIconBackBuffer, IconBackBuffer, BltSi= ze) !=3D 0) { + Compound =3D VkContext->FullIconBackBuffer; + Size =3D Height * Width; + while (Size-- !=3D 0) { + if ((GraphicBlt->Red !=3D IconBackBuffer->Red) || + (GraphicBlt->Green !=3D IconBackBuffer->Green) || + (GraphicBlt->Blue !=3D IconBackBuffer->Blue)) { + *Compound =3D *IconBackBuffer; + } + Compound++; + GraphicBlt++; + IconBackBuffer++; + } + } + } + } else if (IconType =3D=3D VkDisplayAttributeSimpleBottom) { + // + // Store simple icon background framebuffer + // + VkContext->SimIconBackHeight =3D Height; + VkContext->SimIconBackWidth =3D Width; + if (VkContext->SimIconUpdatedFlag =3D=3D FALSE) { + // + // No icon draw, save the buffer directly. + // + if (VkContext->SimIconBackBuffer =3D=3D NULL) { + VkContext->SimIconBackBuffer =3D AllocateZeroPool (BltSize); + VkContext->SimIconBackSize =3D BltSize; + } + CopyMem (VkContext->SimIconBackBuffer, IconBackBuffer, BltSize); + VkContext->SimIconUpdatedFlag =3D TRUE; + } else { + if (CompareMem (VkContext->SimIconBackBuffer, IconBackBuffer, BltSiz= e) !=3D 0) { + Compound =3D VkContext->SimIconBackBuffer; + Size =3D Height * Width; + while (Size-- !=3D 0) { + if ((GraphicBlt->Red !=3D IconBackBuffer->Red) || + (GraphicBlt->Green !=3D IconBackBuffer->Green) || + (GraphicBlt->Blue !=3D IconBackBuffer->Blue)) { + *Compound =3D *IconBackBuffer; + } + Compound++; + GraphicBlt++; + IconBackBuffer++; + } + } + } + } + + if (TempIconBackBuffer !=3D NULL) FreePool (TempIconBackBuffer); + + gST->ConOut->EnableCursor (gST->ConOut, SaveCursor); + return Status; +} + +/** + Use to draw the keyboard icon. + + @param[in] VkContext Pointer to virtual keyboard's context + @param[in] VkImage Image of keyboard to display on the screen. + @param[in] Attribute Attribute of keyboard to display on the screen. + + @retval EFI_SUCCESS ConsoleControl has been flipped to graphic= s and keyboard icon displayed. + @retval EFI_UNSUPPORTED KeyboardFile not found + @retval EFI_INVALID_PARAMETER Attribute is unknown. + +**/ +EFI_STATUS +EFIAPI +DrawVkIcon ( + IN VK_CONTEXT *VkContext, + IN EFI_IMAGE_INPUT *VkImage, + IN VK_DISPLAY_ATTRIBUTE Attribute + ) +{ + EFI_STATUS Status; + UINT32 SizeOfX; + UINT32 SizeOfY; + INTN DestX; + INTN DestY; + UINTN CoordinateX; + UINTN CoordinateY; + EFI_GRAPHICS_OUTPUT_PROTOCOL *GraphicsOutput; + EFI_GRAPHICS_OUTPUT_BLT_PIXEL *Blt; + UINTN BltSize; + UINTN Height; + UINTN Width; + + Status =3D EFI_SUCCESS; + GraphicsOutput =3D VkContext->GraphicsOutput; + SizeOfX =3D GraphicsOutput->Mode->Info->HorizontalResolution; + SizeOfY =3D GraphicsOutput->Mode->Info->VerticalResolution; + CoordinateX =3D 0; + CoordinateY =3D 0; + Height =3D VkImage->Height; + Width =3D VkImage->Width; + Blt =3D VkImage->Bitmap; + BltSize =3D sizeof (EFI_GRAPHICS_OUTPUT_BLT_PIXEL) * (UINT32)(Wid= th * Height); + + // + // Calculate the display position according to Attribute. + // + switch (Attribute) { + case VkDisplayAttributeSimpleTop: + DestX =3D CoordinateX; + DestY =3D CoordinateY; + break; + + case VkDisplayAttributeFullTop: + DestX =3D (SizeOfX - Width - CoordinateX); + DestY =3D CoordinateY;; + break; + + case VkDisplayAttributeFullBottom: + DestX =3D (SizeOfX - Width - CoordinateX); + DestY =3D (SizeOfY - Height - CoordinateY); + VkContext->FullIconBackStartX =3D DestX; + VkContext->FullIconBackStartY =3D DestY; + break; + + case VkDisplayAttributeSimpleBottom: + DestX =3D CoordinateX; + DestY =3D (SizeOfY - Height - CoordinateY); + + // + // Save to check icon/screen cleared + // + if (VkContext->IconBltBuffer =3D=3D NULL) { + VkContext->IconBltSize =3D BltSize; + VkContext->IconBltWidth =3D Width; + VkContext->IconBltHeight =3D Height; + VkContext->IconBltBuffer =3D AllocateZeroPool (BltSize); + } + CopyMem (VkContext->IconBltBuffer, Blt, VkContext->IconBltSize); + + VkContext->SimIconBackStartX =3D DestX; + VkContext->SimIconBackStartY =3D DestY; + break; + + case VkDisplayAttributeNone: + return EFI_SUCCESS; + + default: + return EFI_INVALID_PARAMETER; + } + + if ((DestX >=3D 0) && (DestY >=3D 0)) { + // + // Store icon background framebuffer + // + SaveVkIconBackgroundBltBuffer (VkContext, Attribute); + Status =3D GraphicsOutput->Blt ( + GraphicsOutput, + Blt, + EfiBltBufferToVideo, + 0, + 0, + (UINTN) DestX, + (UINTN) DestY, + Width, + Height, + Width * sizeof (EFI_GRAPHICS_OUTPUT_BLT_PIX= EL) + ); + } + + return Status; +} + +/** + Use to draw the keyboard. + + @param[in] VkContext Pointer to virtual keyboard's context + @param[in] VkImage Image of keyboard to display on the screen. + @param[in] Attribute Attribute of keyboard to display on the screen. + + @retval EFI_SUCCESS ConsoleControl has been flipped to graphic= s and keyboard displayed. + @retval EFI_UNSUPPORTED KeyboardFile not found + @retval EFI_INVALID_PARAMETER Attribute is unknown. + +**/ +EFI_STATUS +EFIAPI +DrawVkBody ( + IN VK_CONTEXT *VkContext, + IN EFI_IMAGE_INPUT *VkImage, + IN VK_DISPLAY_ATTRIBUTE Attribute + ) +{ + EFI_STATUS Status; + UINT32 SizeOfX; + UINT32 SizeOfY; + INTN DestX; + INTN DestY; + UINTN BltSize; + UINTN Height; + UINTN Width; + UINTN CoordinateY; + EFI_GRAPHICS_OUTPUT_BLT_PIXEL *BltIn; + EFI_GRAPHICS_OUTPUT_PROTOCOL *GraphicsOutput; + + Status =3D EFI_SUCCESS; + GraphicsOutput =3D VkContext->GraphicsOutput; + SizeOfX =3D GraphicsOutput->Mode->Info->HorizontalResolution; + SizeOfY =3D GraphicsOutput->Mode->Info->VerticalResolution; + CoordinateY =3D 0; + Height =3D VkImage->Height; + Width =3D VkImage->Width; + BltSize =3D sizeof (EFI_GRAPHICS_OUTPUT_BLT_PIXEL) * (UINT32)(Wid= th * Height); + BltIn =3D AllocateCopyPool (BltSize, VkImage->Bitmap); + + if (BltIn =3D=3D NULL) { + return EFI_OUT_OF_RESOURCES; + } + + // + // Calculate the display position according to Attribute. + // + switch (Attribute) { + case VkDisplayAttributeSimpleTop: + DestX =3D ((SizeOfX / 2) - Width) / 4; + DestY =3D CoordinateY; + VkContext->CurrentKeyboardDisplay =3D VkDisplayAttributeSimpleTop; + break; + + case VkDisplayAttributeSimpleBottom: + DestX =3D ((SizeOfX / 2) - Width) / 4; + DestY =3D (SizeOfY - Height - CoordinateY); + VkContext->CurrentKeyboardDisplay =3D VkDisplayAttributeSimpleBottom; + break; + + case VkDisplayAttributeFullTop: + DestX =3D (SizeOfX - Width) / 2; + DestY =3D CoordinateY; + VkContext->CurrentKeyboardDisplay =3D VkDisplayAttributeFullTop; + break; + + case VkDisplayAttributeFullBottom: + DestX =3D (SizeOfX - Width) / 2; + DestY =3D (SizeOfY - Height - CoordinateY); + VkContext->CurrentKeyboardDisplay =3D VkDisplayAttributeFullBottom; + break; + + case VkDisplayAttributeNone: + VkContext->CurrentKeyboardDisplay =3D VkDisplayAttributeNone; + goto DVKBODY_Exit; + + default: + VkContext->CurrentKeyboardDisplay =3D VkDisplayAttributeNone; + Status =3D EFI_INVALID_PARAMETER; + goto DVKBODY_Exit; + } + if ((DestX >=3D 0) && (DestY >=3D 0)) { + SetCharacterPosition (VkContext, (UINT32)DestX, (UINT32)DestY); + + // + // Store current framebuffer + // + VkContext->VkBodyBltStartX =3D DestX; + VkContext->VkBodyBltStartY =3D DestY; + VkContext->VkBodyBltHeight =3D Height; + VkContext->VkBodyBltWidth =3D Width; + SaveVkBodyBackgroundBltBuffer (VkContext, BltSize); + + // + // Free compound buffer first. + // + if (VkContext->VkBodyCompoundBltBuffer !=3D NULL) { + FreePool (VkContext->VkBodyCompoundBltBuffer); + } + VkContext->VkBodyCompoundBltBuffer =3D NULL; + ModifyShiftKeyColor (VkContext, &BltIn); + MakeKeyboardTransparent (VkContext, TRUE, BltIn, &(VkContext->VkBodyCo= mpoundBltBuffer)); + + // + // Draw keyboard body + // + Status =3D GraphicsOutput->Blt ( + GraphicsOutput, + VkContext->VkBodyCompoundBltBuffer, + EfiBltBufferToVideo, + 0, + 0, + (UINTN) DestX, + (UINTN) DestY, + Width, + Height, + Width * sizeof (EFI_GRAPHICS_OUTPUT_BLT_PIX= EL) + ); + } + + +DVKBODY_Exit: + if (BltIn !=3D NULL) { + FreePool (BltIn); + } + + return Status; +} + +/** + Clear the keyboard body + + @param VkContext Code context. + + @retval EFI_SUCCESS Clear rectangle is done. + +**/ +EFI_STATUS +HideVkBody ( + IN VK_CONTEXT *VkContext + ) +{ + RestoreVkBodyBackgroundBltBuffer (VkContext); + VkContext->CurrentKeyboardDisplay =3D VkDisplayAttributeNone; + + return EFI_SUCCESS; +} + + +/** + Clear the keyboard icon + + @param VkContext Code context. + + @retval EFI_SUCCESS Clear rectangle is done. + +**/ +EFI_STATUS +HideVkIcon ( + IN VK_CONTEXT *VkContext + ) +{ + EFI_STATUS Status; + + if ((VkContext->FullIconBackBuffer =3D=3D NULL) || (VkContext->SimIconBa= ckBuffer =3D=3D NULL)) { + return EFI_UNSUPPORTED; + } + + if ((VkContext->FullIconUpdatedFlag =3D=3D FALSE) || (VkContext->SimIcon= UpdatedFlag =3D=3D FALSE)) { + return EFI_UNSUPPORTED; + } + Status =3D VkContext->GraphicsOutput->Blt ( + VkContext->GraphicsOutput, + VkContext->FullIconBackBuffer, + EfiBltBufferToVideo, + 0, + 0, + VkContext->FullIconBackStartX, + VkContext->FullIconBackStartY, + VkContext->FullIconBackWidth, + VkContext->FullIconBackHeight, + VkContext->FullIconBackWidth * siz= eof (EFI_GRAPHICS_OUTPUT_BLT_PIXEL) + ); + + ZeroMem (VkContext->FullIconBackBuffer, VkContext->FullIconBackSize); + VkContext->FullIconUpdatedFlag =3D FALSE; + + + Status =3D VkContext->GraphicsOutput->Blt ( + VkContext->GraphicsOutput, + VkContext->SimIconBackBuffer, + EfiBltBufferToVideo, + 0, + 0, + VkContext->SimIconBackStartX, + VkContext->SimIconBackStartY, + VkContext->SimIconBackWidth, + VkContext->SimIconBackHeight, + VkContext->SimIconBackWidth * size= of (EFI_GRAPHICS_OUTPUT_BLT_PIXEL) + ); + if (!EFI_ERROR (Status)) { + if (VkContext->ScreenCheckBuffer =3D=3D NULL) { + VkContext->ScreenCheckBufferSize =3D VkContext->SimIconBackHeight * + VkContext->SimIconBackWidth * + sizeof (EFI_GRAPHICS_OUTPUT_BLT_P= IXEL); + VkContext->ScreenCheckBuffer =3D AllocateZeroPool (VkContext->Screen= CheckBufferSize); + } + + CopyMem ( + VkContext->ScreenCheckBuffer, + VkContext->SimIconBackBuffer, + (VkContext->SimIconBackHeight * VkContext->SimIconBackWidth * sizeof= (EFI_GRAPHICS_OUTPUT_BLT_PIXEL)) + ); + } + ZeroMem (VkContext->SimIconBackBuffer, VkContext->SimIconBackSize); + VkContext->SimIconUpdatedFlag =3D FALSE; + + return EFI_SUCCESS; +} + +/** + Draw key board on the display + + @param[in] VkContext Graphic Protocol for draw the alphabet. + + @retval EFI_SUCCESS Draw keyboard was done. + @retval EFI_UNSUPPORTED Did not get key mapping table. + +**/ +EFI_STATUS +DrawKeyboardLayout ( + IN VK_CONTEXT *VkContext + ) +{ + EFI_STATUS Status; + if (!VkContext->IsIconShowed) { + Status =3D DrawVkIcon (VkContext, VkContext->SmallIcon, VkDisplayAttri= buteSimpleTop); + ASSERT_EFI_ERROR (Status); + + Status =3D DrawVkIcon (VkContext, VkContext->SmallIcon, VkDisplayAttri= buteSimpleBottom); + ASSERT_EFI_ERROR (Status); + + Status =3D DrawVkIcon (VkContext, VkContext->FullIcon, VkDisplayAttri= buteFullTop); + ASSERT_EFI_ERROR (Status); + + Status =3D DrawVkIcon (VkContext, VkContext->FullIcon, VkDisplayAttri= buteFullBottom); + ASSERT_EFI_ERROR (Status); + VkContext->IsIconShowed =3D TRUE; + } + + if (VkContext->TargetKeyboardDisplay !=3D VkContext->CurrentKeyboardDisp= lay) { + switch (VkContext->TargetKeyboardDisplay) { + case VkDisplayAttributeSimpleTop: + case VkDisplayAttributeSimpleBottom: + DrawVkBody (VkContext, VkContext->SimKeyBody, VkContext->TargetKeybo= ardDisplay); + break; + + case VkDisplayAttributeFullTop: + case VkDisplayAttributeFullBottom: + if (VkContext->PageNumber <=3D VkPage1) { + DrawVkBody (VkContext, VkContext->CapLeKeyBody, VkContext->TargetK= eyboardDisplay); + } else { + DrawVkBody (VkContext, VkContext->DigKeyBody, VkContext->TargetKey= boardDisplay); + } + + case VkDisplayAttributeNone: + break; + + default: + break; + } + } + + return EFI_SUCCESS; +} + +EFI_STATUS +KeyboardLayoutHandler ( + IN VK_CONTEXT *VkContext, + IN UINT32 Index + ) +{ + EFI_STATUS Status; + + Status =3D EFI_SUCCESS; + + if (Index =3D=3D (VkContext->NumOfKeysInfo - 4)) { + // + // Touch the LeftTop icon + // + if (VkContext->CurrentKeyboardDisplay =3D=3D VkDisplayAttributeSimpleT= op) { + VkContext->TargetKeyboardDisplay =3D VkDisplayAttributeNone; + } else { + VkContext->TargetKeyboardDisplay =3D VkDisplayAttributeSimpleTop; + } + } else if (Index =3D=3D (VkContext->NumOfKeysInfo - 3)) { + // + // Touch the LeftBottom icon + // + if (VkContext->CurrentKeyboardDisplay =3D=3D VkDisplayAttributeSimpleB= ottom) { + VkContext->TargetKeyboardDisplay =3D VkDisplayAttributeNone; + } else { + VkContext->TargetKeyboardDisplay =3D VkDisplayAttributeSimpleBottom; + } + } else if (Index =3D=3D (VkContext->NumOfKeysInfo - 2)) { + // + // Touch the RightTop icon + // + if (VkContext->CurrentKeyboardDisplay =3D=3D VkDisplayAttributeFullTop= ) { + VkContext->TargetKeyboardDisplay =3D VkDisplayAttributeNone; + } else { + VkContext->TargetKeyboardDisplay =3D VkDisplayAttributeFullTop; + } + } else { + // + // Touch the RightBottom icon + // + if (VkContext->CurrentKeyboardDisplay =3D=3D VkDisplayAttributeFullBot= tom) { + VkContext->TargetKeyboardDisplay =3D VkDisplayAttributeNone; + } else { + VkContext->TargetKeyboardDisplay =3D VkDisplayAttributeFullBottom; + } + } + + if (VkContext->TargetKeyboardDisplay =3D=3D VkDisplayAttributeNone) { + // + // Just hide the current keyboard + // + HideVkBody (VkContext); + VkContext->KeyTouchedTimeOut =3D VK_REPEAT_TIMEOUT; + + } else { + // + // If current keyboard status is NOT none, + // hide current keyboard first and then draw the target keyboard + // + if (VkContext->CurrentKeyboardDisplay !=3D VkDisplayAttributeNone) { + HideVkBody (VkContext); + } + Status =3D DrawKeyboardLayout (VkContext); + } + + return Status; +} + +/** + This routine is used to check if icon has been cleared. + + @param[in] VkContext Pointer to virtual keyboard's context + + @retval EFI_SUCCESS Function completed. + +**/ +EFI_STATUS +CheckIconCleared ( + IN VK_CONTEXT *VkContext + ) +{ + EFI_STATUS Status; + UINT32 VerticalResolution; + EFI_GRAPHICS_OUTPUT_BLT_PIXEL *BltBuffer; + + Status =3D EFI_SUCCESS; + BltBuffer =3D NULL; + VkContext->IconReDrawCheck++; + if (VkContext->IconReDrawCheck <=3D 10) { + // + // Check it every 10 * 100ms. + // + return Status; + } + + // + // Check if right-bottomed region is black, if yes, clean screen happene= d, need to re-draw keyboard. + // + VerticalResolution =3D VkContext->GraphicsOutput->Mode->Info->Vertica= lResolution; + BltBuffer =3D AllocateZeroPool (VkContext->IconBltSize); + if (BltBuffer =3D=3D NULL) { + return EFI_OUT_OF_RESOURCES; + } + Status =3D VkContext->GraphicsOutput->Blt ( + VkContext->GraphicsOutput, + BltBuffer, + EfiBltVideoToBltBuffer, + 0, + (VerticalResolution - VkContext->I= conBltHeight), + 0, + 0, + VkContext->IconBltWidth, + VkContext->IconBltHeight, + VkContext->IconBltWidth * sizeof (= EFI_GRAPHICS_OUTPUT_BLT_PIXEL) + ); + if (EFI_ERROR (Status)) { + FreePool (BltBuffer); + return Status; + } + VkContext->IsIconShowed =3D TRUE; + if (VkContext->IconBltBuffer =3D=3D NULL) { + // + // No icon has been drawn. + // + VkContext->IsIconShowed =3D FALSE; + } else { + if (CompareMem (BltBuffer, VkContext->IconBltBuffer, VkContext->IconBl= tSize) !=3D 0) { + // + // Icon has been overridden, need to re-draw. + // + VkContext->IsIconShowed =3D FALSE; + } + } + + if (VkContext->IsIconShowed =3D=3D FALSE) { + if (VkContext->ScreenCheckBuffer !=3D NULL) { + if (CompareMem (BltBuffer, VkContext->ScreenCheckBuffer, VkContext->= IconBltSize) =3D=3D 0) { + // + // Icon has been overridden, force to re-draw the keyboard. + // + Status =3D DrawKeyboardLayout (VkContext); + } else { + // + // Save blt buffer of icon position and use it to check if icon is= overridden. + // + CopyMem (VkContext->ScreenCheckBuffer, BltBuffer, VkContext->IconB= ltSize); + } + } else { + // + // Draw the keyboard. + // + Status =3D DrawKeyboardLayout (VkContext); + } + } + + if (BltBuffer !=3D NULL) { + FreePool (BltBuffer); + } + + VkContext->IconReDrawCheck =3D 0; + + return Status; +} + +/** + ConvertCoordinate - Convert the touch panel's coordinate to display's co= ordinate. + + @param[in] VkContext Virtual Keyboard context. + @param[in] Point The coordinate reported from touch pan= el. + @param[out] TouchX The coordinate X converted to display = panel. + @param[out] TouchY The coordinate Y converted to display = panel.. + + @retval EFI_SUCCESS Convert success. + +**/ +EFI_STATUS +ConvertCoordinate ( + IN VK_CONTEXT *VkContext, + IN EFI_ABSOLUTE_POINTER_STATE Point, + OUT UINT32 *TouchX, + OUT UINT32 *TouchY + ) +{ + UINT64 AbsoluteMaxX; + UINT64 AbsoluteMaxY; + UINT32 HorizontalResolution; + UINT32 VerticalResolution; + + AbsoluteMaxX =3D VkContext->AbsolutePointer->Mode->AbsoluteMaxX; + AbsoluteMaxY =3D VkContext->AbsolutePointer->Mode->AbsoluteMaxY; + HorizontalResolution =3D VkContext->GraphicsOutput->Mode->Info->Horizont= alResolution; + VerticalResolution =3D VkContext->GraphicsOutput->Mode->Info->Vertical= Resolution; + *TouchX =3D (UINT32) MultU64x32 (Point.CurrentX, Horizontal= Resolution) / (UINT32) AbsoluteMaxX; + *TouchY =3D (UINT32) MultU64x32 (Point.CurrentY, VerticalRe= solution) / (UINT32) AbsoluteMaxY; + + return EFI_SUCCESS; +} + +/** + This routine is used to check if screen has been cleared. + + @param[in] VkContext Pointer to virtual keyboard's context + + @retval EFI_SUCCESS Function completed. + +**/ +EFI_STATUS +CheckScreenCleared ( + IN VK_CONTEXT *VkContext + ) +{ + EFI_STATUS Status; + UINT32 HorizontalResolution; + UINT32 VerticalResolution; + EFI_GRAPHICS_OUTPUT_BLT_PIXEL *BltBuffer; + EFI_GRAPHICS_OUTPUT_BLT_PIXEL *BltBufferIndex; + UINTN BltSize; + BOOLEAN IsScreenCleared; + + // + // Check left-bottom side. + // If IconBltBuffer is null, checking is meaningless. + // + if (VkContext->IconBltBuffer =3D=3D NULL) { + return EFI_SUCCESS; + } + + IsScreenCleared =3D FALSE; + Status =3D EFI_SUCCESS; + if ((gST->ConOut->Mode->CursorColumn =3D=3D 0) && (gST->ConOut->Mode->Cu= rsorRow =3D=3D 0)) { + // + // System may call gST->ConOut->ClearScreen + // + HorizontalResolution =3D VkContext->GraphicsOutput->Mode->Info->Horiz= ontalResolution; + VerticalResolution =3D VkContext->GraphicsOutput->Mode->Info->Verti= calResolution; + BltBuffer =3D AllocateZeroPool (VkContext->IconBltSize); + if (BltBuffer =3D=3D NULL) { + return EFI_OUT_OF_RESOURCES; + } + + BltBufferIndex =3D BltBuffer; + Status =3D VkContext->GraphicsOutput->Blt ( + VkContext->GraphicsOutput, + BltBuffer, + EfiBltVideoToBltBuffer, + (HorizontalResolution - VkContex= t->IconBltWidth), + (VerticalResolution - VkContext-= >IconBltHeight), + 0, + 0, + VkContext->IconBltWidth, + VkContext->IconBltHeight, + VkContext->IconBltWidth * sizeof= (EFI_GRAPHICS_OUTPUT_BLT_PIXEL) + ); + if (EFI_ERROR (Status)) { + FreePool (BltBuffer); + return Status; + } + BltSize =3D VkContext->IconBltHeight * VkContext->IconBltWidth; + IsScreenCleared =3D TRUE; + while (BltSize-- !=3D 0) { + if ((BltBufferIndex->Red !=3D 0) || (BltBufferIndex->Green !=3D 0) |= | (BltBufferIndex->Blue !=3D 0)) { + IsScreenCleared =3D FALSE; + break; + } + BltBufferIndex++; + } + FreePool (BltBuffer); + } + + if (IsScreenCleared =3D=3D TRUE) { + VkContext->IsIconShowed =3D FALSE; + VkContext->CurrentKeyboardDisplay =3D VkDisplayAttributeNone; + + if (VkContext->VkBodyBackgroundBltBuffer !=3D NULL) { + FreePool (VkContext->VkBodyBackgroundBltBuffer); + VkContext->VkBodyBackgroundBltBuffer =3D NULL; + } + + if (VkContext->VkBodyCompoundBltBuffer !=3D NULL) { + FreePool (VkContext->VkBodyCompoundBltBuffer); + VkContext->VkBodyCompoundBltBuffer =3D NULL; + } + + if (VkContext->IconBltBuffer !=3D NULL) { + FreePool (VkContext->IconBltBuffer); + VkContext->IconBltBuffer =3D NULL; + } + + } + + return Status; +} + +/** + This routine is used to check if background beneath virtual keyboard has= been cleared. + + @param[in] VkContext Pointer to virtual keyboard's context + + @retval EFI_SUCCESS Function completed. + +**/ +EFI_STATUS +CheckBackgroundChanged ( + IN VK_CONTEXT *VkContext + ) +{ + EFI_STATUS Status; + EFI_GRAPHICS_OUTPUT_BLT_PIXEL *BltBuffer; + + Status =3D EFI_SUCCESS; + VkContext->IsBackgroundChanged =3D FALSE; + + if ((VkContext->CurrentKeyboardDisplay =3D=3D VkDisplayAttributeNone) ||= (VkContext->VkBodyCompoundBltBuffer =3D=3D NULL)) { + return EFI_SUCCESS; + } + + BltBuffer =3D AllocateZeroPool (VkContext->VkBodyBltSize); + if (BltBuffer =3D=3D NULL) { + return EFI_OUT_OF_RESOURCES; + } + Status =3D VkContext->GraphicsOutput->Blt ( + VkContext->GraphicsOutput, + BltBuffer, + EfiBltVideoToBltBuffer, + VkContext->VkBodyBltStartX, + VkContext->VkBodyBltStartY, + 0, + 0, + VkContext->VkBodyBltWidth, + VkContext->VkBodyBltHeight, + VkContext->VkBodyBltWidth * sizeof= (EFI_GRAPHICS_OUTPUT_BLT_PIXEL) + ); + if (EFI_ERROR (Status)) { + FreePool (BltBuffer); + return Status; + } + if (CompareMem (BltBuffer, VkContext->VkBodyCompoundBltBuffer, VkContext= ->VkBodyBltSize) !=3D 0) { + VkContext->IsBackgroundChanged =3D TRUE; + VkContext->CurrentKeyboardDisplay =3D VkDisplayAttributeNone; + DrawKeyboardLayout (VkContext); + } + + if (BltBuffer !=3D NULL) { + FreePool (BltBuffer); + } + + return Status; +} + +/** + Get unicode by VkContext->PageNumber and VkContext->KeyboardBodyPtr. + + @param[in] VkContext Address of an VK_CONTEXT structure. + @param[in] KeyItem Key Item. + @param[out] FontPtr Follow VkContext->PageNumber to transla= te + font unicode. + + @retval EFI_SUCCESS Finish translating FontPtr. + @retval EFI_INVALID_PARAMETER VkContext or FontPtr is NULL. + +**/ +EFI_STATUS +VkGetMappingFont ( + IN VK_CONTEXT *VkContext, + IN VK_STRUCT KeyItem, + OUT UINT32 *FontPtr + ) +{ + if ((VkContext =3D=3D NULL) || (FontPtr =3D=3D NULL) || (VkContext->Page= Number>=3DVkPageMaximum)) { + return EFI_INVALID_PARAMETER; + } + *FontPtr =3D (UINT32) KeyItem.PageFont[VkContext->PageNumber]; + + return EFI_SUCCESS; +} diff --git a/Features/Intel/UserInterface/VirtualKeyboardFeaturePkg/Virtual= KeyboardDxe/KeyboardLayout.idf b/Features/Intel/UserInterface/VirtualKeyboa= rdFeaturePkg/VirtualKeyboardDxe/KeyboardLayout.idf new file mode 100644 index 0000000000..995bd0d859 --- /dev/null +++ b/Features/Intel/UserInterface/VirtualKeyboardFeaturePkg/VirtualKeyboar= dDxe/KeyboardLayout.idf @@ -0,0 +1,12 @@ +// /** @file +// Virtual Keyboard Layout +// +// Copyright (c) 2019 - 2020, Intel Corporation. All rights reserved.
    +// +// SPDX-License-Identifier: BSD-2-Clause-Patent +// +#image IMG_VK_CAPITALLETTERKEYBOARD TRANSPARENT CapitalLetterKeyboard.bmp +#image IMG_VK_DIGITKEYBOARD TRANSPARENT DigitKeyboard.bmp +#image IMG_VK_FULLICON TRANSPARENT FullIcon.bmp +#image IMG_VK_SIMPLEICON TRANSPARENT SimpleIcon.bmp +#image IMG_VK_SIMPLEKEYBOARD TRANSPARENT SimpleKeyboard.bmp diff --git a/Features/Intel/UserInterface/VirtualKeyboardFeaturePkg/Virtual= KeyboardDxe/SimpleIcon.bmp b/Features/Intel/UserInterface/VirtualKeyboardFe= aturePkg/VirtualKeyboardDxe/SimpleIcon.bmp new file mode 100644 index 0000000000000000000000000000000000000000..16816f031eb98bf8169c7119b95= ea3ed1371f41d GIT binary patch literal 2814 zcmeHDu?>JQ41<*mn3%bM1K9bStAMDgEvtknP%#v#jj+gU5{W9DB#Qt~ueEazM`sKHo|BsLM z*}=3D!|d)xXGP=3DM>Qqv~}j(Q%zBZCbCb!q%%qN2e-vPQf-|Q&6HB3RQjm|E3w{+S+w% zYin*i0t!_jQj?oqlAkf?LVK=3DJsLDy2n^ps~Z)2roqTN_UCMnMvSsfl8o}ZtmguxGO znO4`d{2JWZ*?D<+u{>{YZwChlZiscU0;t#5R|q>jJ#~_JSRpIUod!YKNlf8ttQ@Ee zuF6?;f=3Dc14nU!8VjgQ;A#aJz?xu9Zo)yc|%dU|?#cz7^4@9*zdS65nKtgZ@KIZ%&} zkNf-k_xJZ?b#!!ec6LTwpa&0rY1YOng4*5P-QM1ItU%`S^3vfNn-%Y2%uuPTzZX>| z;DCw(C!ZEba>G|ZkLD+t49ndj%{_~>EoXB>8{ zWDOcCJgg?kKsmbX=3DqVa1C^wX7Vj6f1&4e9f#BS0^h4RUs>^IQKZ| z=3DH`aiF#sVGIQbnBoc!oo&-Kc#P7znEt4>hpUK=3DY++2Ojqz18;_uCK3WCH8a2iZad> zvWmC}M-2z6&bqQ9an+@iVnx+lS9x5qq8cj@h}D$>h2T1`S5_ysKR!Oz1<1$W8e?{2 z1rEfO0fn%}%4!C<@}O4C%2Z|cIB~XRVqB9gALopRzY_P(k5t-sW#5a&DL4;RIe+G` zvC6=3D4O^dPON$G10URQ29qaIF>l}W;W)QR^^PF2$prjjPB%86`;jlfU@`Yz!y;^SP# z7^QDcr>bxF@#0n3c%$^qOjUh5jva5p#vY|_{-&y&SYy>#l@lnBY<1OGl@lnBY<1OG zl@lnB{B(6y_^nPkf$~Vl3QCsW%11{ehtpmuRTi(2YU81j9xiF~t2yTBRK?a3gOjCE z(u*;jy*gDP61{BC?lkb{f%p#tJS;a-2{)CMy=3D`)FaZ!$lk@c{`i(Y&!htuz648n>U zY(=3D=3Dez6lv4Q_sKLJ8Z~_Vt`s~IzhJvwMipgHVrGcHDT<9l}M*k^;7gO*^z+aA}jqn zVhxCI;ie*yYHx3kl3+Mh+C+JH?~8w>Yw>tSxxjXEa>8CZklCwY1^xEopADJs7w4Tuv4hGPBg)mQsuzcnV3pcf<%wljSw{_6f!*qA8OT$p_Nc$9 zicC_T#wtZ7`WvgrB;{$WQe>jPv5HJmp2jLg#`z5t_RhcFL#mpNFqJe}RZe6(>?H65 D{aYn_ literal 0 HcmV?d00001 diff --git a/Features/Intel/UserInterface/VirtualKeyboardFeaturePkg/Virtual= KeyboardDxe/VirtualKeyboard.h b/Features/Intel/UserInterface/VirtualKeyboar= dFeaturePkg/VirtualKeyboardDxe/VirtualKeyboard.h new file mode 100644 index 0000000000..debd4346c7 --- /dev/null +++ b/Features/Intel/UserInterface/VirtualKeyboardFeaturePkg/VirtualKeyboar= dDxe/VirtualKeyboard.h @@ -0,0 +1,777 @@ +/** @file + Header file for Virtual Keyboard driver. + + Copyright (c) 2012 - 2020, Intel Corporation. All rights reserved.
    + SPDX-License-Identifier: BSD-2-Clause-Patent + +**/ + +#ifndef _VIRTUAL_KEYBOARD_H_ +#define _VIRTUAL_KEYBOARD_H_ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "ComponentName.h" + +// +// Global Variables +// +extern EFI_DRIVER_BINDING_PROTOCOL gVirtualKeyboardDriverBinding; +extern EFI_COMPONENT_NAME_PROTOCOL gVirtualKeyboardComponentName; +extern EFI_COMPONENT_NAME2_PROTOCOL gVirtualKeyboardComponentName2; + +/// +/// Debug raw data points +/// +#define DEBUG_VK_POINTS 0x40000000 + +/// +/// Debug data point scaling +/// +#define DEBUG_VK_POINT_SCALING 0x20000000 + +/// +/// Debug key press +/// +#define DEBUG_VK_KEYS 0x10000000 + +/// +/// Debug routine entry and exit +/// +#define DEBUG_VK_ROUTINE_ENTRY_EXIT 0x08000000 + +/// +/// Display the graphics info +/// +#define DEBUG_VK_GRAPHICS_INFO 0x04000000 + +/// +/// Display the timer entry and exit +/// +#define DEBUG_VK_TIMER_ENTRY_EXIT 0x00100000 + +/// +/// Signature +/// +#define VK_SIGNATURE SIGNATURE_32 ('V', 'K', 'e', 'y') +#define VK_NOTIFY_SIGNATURE SIGNATURE_32 ('V', 'K', 'n', 's') + +/// +/// Poll interval +/// +#define VK_POLL_INTERVAL (1000 * 1000) + +/// +/// Define the touch timeout in poll intervals +/// +#define VK_REPEAT_TIMEOUT 5 + +/// +/// TPL used to synchronize add/remove from list +/// +#define TPL_VK_SYNC TPL_NOTIFY + +/// +/// Dimension of an array ( number of elements ) +/// +#define DIM(x) ( sizeof ( x ) / sizeof ( x [ 0 ])) + +/// +/// Define Key buffer +/// +#define MAX_KEY_BUF_SIZE 64 + +/// +/// Define Transparent Weight +/// +#define TRANSPARENCY_WEIGHT 50 + +typedef struct _VK_CONTEXT VK_CONTEXT; + +typedef enum _VK_KEY_TYPE { + VkKeyNull =3D 0x0000 | CHAR_NULL, + VkKeyBackspace =3D 0x0000 | CHAR_BACKSPACE, + VkKeyTab =3D 0x0000 | CHAR_TAB, + VkKeyEnter =3D 0x0000 | CHAR_CARRIAGE_RETURN, + VkKeyScanMask =3D 0x1000, + VkKeyEsc =3D 0x1000 | SCAN_ESC, + VkKeyLeft =3D 0x1000 | SCAN_LEFT, + VkKeyRight =3D 0x1000 | SCAN_RIGHT, + VkKeyUp =3D 0x1000 | SCAN_UP, + VkKeyDown =3D 0x1000 | SCAN_DOWN, + VkKeyF1 =3D 0x1000 | SCAN_F1, + VkKeyF2 =3D 0x1000 | SCAN_F2, + VkKeyF3 =3D 0x1000 | SCAN_F3, + VkKeyF4 =3D 0x1000 | SCAN_F4, + VkKeyF5 =3D 0x1000 | SCAN_F5, + VkKeyF6 =3D 0x1000 | SCAN_F6, + VkKeyF7 =3D 0x1000 | SCAN_F7, + VkKeyF8 =3D 0x1000 | SCAN_F8, + VkKeyF9 =3D 0x1000 | SCAN_F9, + VkKeyF10 =3D 0x1000 | SCAN_F10, + VkKeyF11 =3D 0x1000 | SCAN_F11, + VkKeyF12 =3D 0x1000 | SCAN_F12, + VkKeySpecificMask =3D 0x2000, + VkKeyShift =3D 0x2000 | 0x0000, + VkKeyCapslock =3D 0x2000 | 0x0001, + VkKeyTwoPage =3D 0x2000 | 0x0002, + VkKeyTypeMaximum =3D 0xFFFF +} VK_KEY_TYPE; + +typedef enum _VK_PAGE_TYPE { + // + // +---+---+---+---+---+---+---+---+---+---+---+ + // | q | w | e | r | t | y | u | i | o | p | | ? |F11|F12|Enter| Line 2 + // +-----+---+---+---+---+---+---+---+---+---+-+ + // | Esc |12#| Space | | | _ | + | | Line 3 + // +-----+---+-------------------+---+---+---+-+ + // + VkPage3, + VkPageMaximum +} VK_PAGE_TYPE; + +typedef enum VK_DISPLAY_ATTRIBUTE { + VkDisplayAttributeNone, /// No keyboard displayed + VkDisplayAttributeFullTop, /// Full keyboard display at top + VkDisplayAttributeFullBottom, /// Full keyboard display at bottom + VkDisplayAttributeSimpleTop, /// Simple keyboard display at top + VkDisplayAttributeSimpleBottom, /// Simple keyboard display at bottom + VkDisplayAttributeMaximum +} VK_DISPLAY_ATTRIBUTE; + +typedef struct _VK_STRUCT { + UINT16 DisStartX; + UINT16 DisStartY; + UINT16 DisEndX; + UINT16 DisEndY; + VK_KEY_TYPE PageFont[VkPageMaximum]; +} VK_STRUCT; + +typedef struct _VK_NOTIFY { + UINTN Signature; + EFI_KEY_DATA KeyData; + EFI_KEY_NOTIFY_FUNCTION KeyNotificationFn; + LIST_ENTRY NotifyEntry; +} VK_NOTIFY; + +/// +/// Virtual Keyboard context +/// +struct _VK_CONTEXT { + /// + /// Structure identification + /// + UINTN Signature; + + /// + /// Controller Handle + /// + EFI_HANDLE Controller; + + /// + /// Upper level API + /// + EFI_SIMPLE_TEXT_INPUT_PROTOCOL SimpleTextIn; + + /// + /// Simple Text In EX + /// + EFI_SIMPLE_TEXT_INPUT_EX_PROTOCOL SimpleTextInEx; + + /// + /// Lower level APIs + /// + EFI_ABSOLUTE_POINTER_PROTOCOL *AbsolutePointer; + EFI_GRAPHICS_OUTPUT_PROTOCOL *GraphicsOutput; + + /// + /// Flag when the last poll indicated a touch event + /// + BOOLEAN TouchActive; + + /// + /// Time to poll for touch input + /// + EFI_EVENT TimerEvent; + + /// + /// HII handle to get image data used + /// + EFI_HII_HANDLE HiiHandle; + EFI_HII_IMAGE_EX_PROTOCOL *HiiImageEx; + + /// + /// Keyboard body background buffer information + /// + EFI_GRAPHICS_OUTPUT_BLT_PIXEL *VkBodyBackgroundBltBuffer; + EFI_GRAPHICS_OUTPUT_BLT_PIXEL *VkBodyCompoundBltBuffer; + UINTN VkBodyBltSize; + UINTN VkBodyBltStartX; + UINTN VkBodyBltStartY; + UINTN VkBodyBltHeight; + UINTN VkBodyBltWidth; + BOOLEAN IsBackgroundChanged; + + /// + /// Icon buffer information + /// + EFI_GRAPHICS_OUTPUT_BLT_PIXEL *IconBltBuffer; + UINTN IconBltSize; + UINTN IconBltHeight; + UINTN IconBltWidth; + + /// + /// Full icon background buffer information + /// + EFI_GRAPHICS_OUTPUT_BLT_PIXEL *FullIconBackBuffer; + UINTN FullIconBackStartX; + UINTN FullIconBackStartY; + UINTN FullIconBackHeight; + UINTN FullIconBackWidth; + UINTN FullIconBackSize; + BOOLEAN FullIconUpdatedFlag; + + /// + /// Simple icon background buffer information + /// + EFI_GRAPHICS_OUTPUT_BLT_PIXEL *SimIconBackBuffer; + UINTN SimIconBackStartX; + UINTN SimIconBackStartY; + UINTN SimIconBackHeight; + UINTN SimIconBackWidth; + UINTN SimIconBackSize; + BOOLEAN SimIconUpdatedFlag; + + /// + /// Small Icon + /// + EFI_IMAGE_INPUT *SmallIcon; + + /// + /// Full Icon + /// + EFI_IMAGE_INPUT *FullIcon; + + /// + /// Simple Key body + /// + EFI_IMAGE_INPUT *SimKeyBody; + + /// + /// Digital key body + /// + EFI_IMAGE_INPUT *DigKeyBody; + + /// + /// Capital Letter Key board + /// + EFI_IMAGE_INPUT *CapLeKeyBody; + + /// + /// Screen check buffer. + /// This is used to check if screen is kept scrolling up. + /// + EFI_GRAPHICS_OUTPUT_BLT_PIXEL *ScreenCheckBuffer; + UINTN ScreenCheckBufferSize; + + /// + /// Key state + /// + BOOLEAN KeyPressed; + + /// + /// Keyboard display status + /// + VK_DISPLAY_ATTRIBUTE CurrentKeyboardDisplay; + VK_DISPLAY_ATTRIBUTE TargetKeyboardDisplay; + + /// + /// Keyboard icon display status + /// + BOOLEAN IsIconShowed; + UINT8 IconReDrawCheck; + + /// + /// Keyboard body Image address + /// Size of KeyboardBodyPtr must larger than mFullKeyboardBody + /// + UINT32 NumOfKeysInfo; + VK_STRUCT KeyboardBodyPtr[50]; + + /// + /// KeyBuffer + /// + EFI_EVENT KeyNotifyProcessEvent; + EFI_KEY_TOGGLE_STATE KeyToggleState; + EFI_KEY_DATA Keybuffer[MAX_KEY_BUF_SIZE]; + UINT8 KeyStartIndex; + UINT8 KeyEndIndex; + UINT16 KeyTouchedTimeOut; + BOOLEAN IsShiftKeyFlag; + BOOLEAN IsCapsLockFlag; + BOOLEAN IsSupportPartialKey; + BOOLEAN IsRedrawUpdateUI; + VK_PAGE_TYPE PageNumber; + LIST_ENTRY NotifyList; +}; + +/// +/// Locate VK_CONTEXT from protocol +/// +#define VK_CONTEXT_FROM_PROTOCOL(a) CR (a, VK_CONTEXT, Simp= leTextIn, VK_SIGNATURE) +#define VK_CONTEXT_FROM_SIMPLETEXTINEX_PROTOCOL(a) CR (a, VK_CONTEXT, Simp= leTextInEx, VK_SIGNATURE) +#define VK_CONTEXT_FROM_VKBD_PROTOCOL(a) CR (a, VK_CONTEXT, Vkbd= Protocol, VK_SIGNATURE) + +/** + Start the virtual keyboard driver + + This routine allocates the necessary resources for the driver. + + This routine is called by VirtualKeyboardDriverStart to complete the dri= ver + initialization. + + @param[in, out] VkContext Address of an VK_CONTEXT structure + @param[in] Controller Handle of device to work with. + + @retval EFI_SUCCESS Driver API properly initialized + +**/ +EFI_STATUS +VkApiStart ( + IN VK_CONTEXT *VkContext, + IN EFI_HANDLE Controller + ); + +/** + Stop the virtual keyboard driver + + This routine releases the resources allocated by VKApiStart. + + This routine is called by VirtualKeyboardDriverStop to initiate the driv= er + shutdown. + + @param[in] VkContext Address of an VK_CONTEXT structure + +**/ +VOID +VkApiStop ( + IN VK_CONTEXT *VkContext + ); + +/** + Resets the input device hardware. + + The Reset() function resets the input device hardware. As part + of initialization process, the firmware/device will make a quick + but reasonable attempt to verify that the device is functioning. + If the ExtendedVerification flag is TRUE the firmware may take + an extended amount of time to verify the device is operating on + reset. Otherwise the reset operation is to occur as quickly as + possible. The hardware verification process is not defined by + this specification and is left up to the platform firmware or + driver to implement. + + @param[in] This A pointer to the EFI_SIMPLE_TEXT_INPUT_E= X_PROTOCOL instance. + + @param[in] ExtendedVerification Indicates that the driver may perform a = more exhaustive + verification operation of the device dur= ing reset. + + @retval EFI_SUCCESS The device was reset. + @retval EFI_DEVICE_ERROR The device is not functioning correctly = and could not be reset. + +**/ +EFI_STATUS +EFIAPI +VkKeyboardReset ( + IN EFI_SIMPLE_TEXT_INPUT_PROTOCOL *This, + IN BOOLEAN ExtendedVerification + ); + +/** + Reads the next keystroke from the input device. The WaitForKey Event can + be used to test for existence of a keystroke via WaitForEvent () call. + + @param[in] This Protocol instance pointer. + @param[out] Key Driver may perform diagnostics on reset. + + @retval EFI_SUCCESS The keystroke information was returned. + @retval EFI_NOT_READY There was no keystroke data available. + @retval EFI_DEVICE_ERROR The keystroke information was not returned due = to + hardware errors. + +**/ +EFI_STATUS +EFIAPI +VkKeyboardReadKeyStroke ( + IN EFI_SIMPLE_TEXT_INPUT_PROTOCOL *This, + OUT EFI_INPUT_KEY *Key + ); + +/** + Resets the input device hardware. + + The Reset() function resets the input device hardware. As part + of initialization process, the firmware/device will make a quick + but reasonable attempt to verify that the device is functioning. + If the ExtendedVerification flag is TRUE the firmware may take + an extended amount of time to verify the device is operating on + reset. Otherwise the reset operation is to occur as quickly as + possible. The hardware verification process is not defined by + this specification and is left up to the platform firmware or + driver to implement. + + @param[in] This A pointer to the EFI_SIMPLE_TEXT_INPUT_E= X_PROTOCOL instance. + + @param[in] ExtendedVerification Indicates that the driver may perform a = more exhaustive + verification operation of the device dur= ing reset. + + @retval EFI_SUCCESS The device was reset. + @retval EFI_DEVICE_ERROR The device is not functioning correctly = and could not be reset. + +**/ +EFI_STATUS +EFIAPI +VkKeyboardResetEx ( + IN EFI_SIMPLE_TEXT_INPUT_EX_PROTOCOL *This, + IN BOOLEAN ExtendedVerification + ); + +/** + Reads the next keystroke from the input device. + + @param[in] This Protocol instance pointer. + @param[out] KeyData A pointer to a buffer that is filled in w= ith 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 available. + @retval EFI_INVALID_PARAMETER This or KeyData is NULL. + +**/ +EFI_STATUS +EFIAPI +VkKeyboardReadKeyStrokeEx ( + IN EFI_SIMPLE_TEXT_INPUT_EX_PROTOCOL *This, + OUT EFI_KEY_DATA *KeyData + ); + +/** + Set certain state for the input device. + + @param[in] This Protocol instance pointer. + @param[in] KeyToggleState A pointer to the EFI_KEY_TOGGLE_STATE to= set the + state for the input device. + + @retval EFI_SUCCESS The device state was set appropriately. + @retval EFI_INVALID_PARAMETER This or KeyToggleState is NULL. + +**/ +EFI_STATUS +EFIAPI +VkKeyboardSetState ( + 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[in] This Protocol instance pointer. + @param[in] KeyData A pointer to a buffer that is fi= lled in with the keystroke + information data for the key tha= t was pressed. + @param[in] KeyNotificationFunction Points to the function to be cal= led when the key + sequence is typed specified by K= eyData. + @param[out] NotifyHandle Points to the unique handle assi= gned to the registered notification. + + @retval EFI_SUCCESS The notification function was re= gistered successfully. + @retval EFI_OUT_OF_RESOURCES Unable to allocate resources for= necessary data structures. + @retval EFI_INVALID_PARAMETER KeyData or NotifyHandle or KeyNo= tificationFunction is NULL. + +**/ +EFI_STATUS +EFIAPI +VkKeyboardRegisterKeyNotify ( + IN EFI_SIMPLE_TEXT_INPUT_EX_PROTOCOL *This, + IN EFI_KEY_DATA *KeyData, + IN EFI_KEY_NOTIFY_FUNCTION KeyNotificationFunction, + OUT EFI_HANDLE *NotifyHandle + ); + +/** + Remove a registered notification function from a particular keystroke. + + @param[in] This Protocol instance pointer. + @param[in] NotificationHandle The handle of the notification function b= eing unregistered. + + @retval EFI_SUCCESS The notification function was unregistere= d successfully. + @retval EFI_INVALID_PARAMETER The NotificationHandle is invalid + +**/ +EFI_STATUS +EFIAPI +VkKeyboardUnregisterKeyNotify ( + IN EFI_SIMPLE_TEXT_INPUT_EX_PROTOCOL *This, + IN EFI_HANDLE NotificationHandle + ); + +/** + Draw key board on the display + + @param[in] VkContext Graphic Protocol for draw the alphabet. + + @retval EFI_SUCCESS Draw keyboard was done. + @retval EFI_UNSUPPORTED Did not get key mapping table. + +**/ +EFI_STATUS +DrawKeyboardLayout ( + IN VK_CONTEXT *VkContext + ); + +/** + Clear the keyboard body + + @param[in] VkContext Code context. + + @retval EFI_SUCCESS Clear rectangle is done. + +**/ +EFI_STATUS +HideVkBody ( + IN VK_CONTEXT *VkContext + ); + +/** + Clear the keyboard icon + + @param[in] VkContext Code context. + + @retval EFI_SUCCESS Clear rectangle is done. + +**/ +EFI_STATUS +HideVkIcon ( + IN VK_CONTEXT *VkContext + ); + +/** + Use to draw the keyboard icon. + + @param[in] VkContext Pointer to virtual keyboard's context + @param[in] VkImage Image of keyboard to display on the screen. + @param[in] Attribute Attribute of keyboard to display on the screen. + + @retval EFI_SUCCESS ConsoleControl has been flipped to graphic= s and keyboard icon displayed. + @retval EFI_UNSUPPORTED KeyboardFile not found + @retval EFI_INVALID_PARAMETER Attribute is unknown. + +**/ +EFI_STATUS +EFIAPI +DrawVkIcon ( + IN VK_CONTEXT *VkContext, + IN EFI_IMAGE_INPUT *VkImage, + IN VK_DISPLAY_ATTRIBUTE Attribute + ); + +/** + Use to draw the keyboard. + + @param[in] VkContext Pointer to virtual keyboard's context + @param[in] VkImage Image of keyboard to display on the screen. + @param[in] Attribute Attribute of keyboard to display on the screen. + + @retval EFI_SUCCESS ConsoleControl has been flipped to graphic= s and keyboard displayed. + @retval EFI_UNSUPPORTED KeyboardFile not found + @retval EFI_INVALID_PARAMETER Attribute is unknown. + +**/ +EFI_STATUS +EFIAPI +DrawVkBody ( + IN VK_CONTEXT *VkContext, + IN EFI_IMAGE_INPUT *VkImage, + IN VK_DISPLAY_ATTRIBUTE Attribute + ); + +/** + Get unicode by VkContext->PageNumber and VkContext->KeyboardBodyPtr. + + @param[in] VkContext Address of an VK_CONTEXT structure. + @param[in] KeyItem Key Item. + @param[out] FontPtr Follow VkContext->PageNumber to transla= te + font unicode. + + @retval EFI_SUCCESS Finish translating FontPtr. + @retval EFI_INVALID_PARAMETER VkContext or FontPtr is NULL. + +**/ +EFI_STATUS +VkGetMappingFont ( + IN VK_CONTEXT *VkContext, + IN VK_STRUCT KeyItem, + OUT UINT32 *FontPtr + ); + +/** + This routine is used to check if icon has been cleared. + + @param[in] VkContext Pointer to virtual keyboard's context + + @retval EFI_SUCCESS Function completed. + +**/ +EFI_STATUS +CheckIconCleared ( + IN VK_CONTEXT *VkContext + ); + +/** + ConvertCoordinate - Convert the touch panel's coordinate to display's co= ordinate. + + @param[in] VkContext Virtual Keyboard context. + @param[in] Point The coordinate reported from touch pan= el. + @param[out] TouchX The coordinate X converted to display = panel. + @param[out] TouchY The coordinate Y converted to display = panel.. + + @retval EFI_SUCCESS Convert success. + +**/ +EFI_STATUS +ConvertCoordinate ( + IN VK_CONTEXT *VkContext, + IN EFI_ABSOLUTE_POINTER_STATE Point, + OUT UINT32 *TouchX, + OUT UINT32 *TouchY + ); + +/** + This routine is used to check if screen has been cleared. + + @param[in] VkContext Pointer to virtual keyboard's context + + @retval EFI_SUCCESS Function completed. + +**/ +EFI_STATUS +CheckScreenCleared ( + IN VK_CONTEXT *VkContext + ); + +/** + This routine is used to check if background beneath virtual keyboard has= been cleared. + + @param[in] VkContext Pointer to virtual keyboard's context + + @retval EFI_SUCCESS Function completed. + +**/ +EFI_STATUS +CheckBackgroundChanged ( + IN VK_CONTEXT *VkContext + ); + +/** + To prevent screen keyboard layout occur scroll up + + @param[in] VkContext Address of an VK_CONTEXT structure. + +**/ +VOID +PreventScreenScrollUp ( + IN OUT VK_CONTEXT *VkContext + ); + +EFI_STATUS +SetCharacterPosition ( + IN VK_CONTEXT *VkContext, + IN UINT32 DestX, + IN UINT32 DestY + ); + +EFI_STATUS +KeyboardLayoutHandler ( + IN VK_CONTEXT *VkContext, + IN UINT32 Index + ); + +EFI_STATUS +EFIAPI +SaveVkBodyBackgroundBltBuffer ( + IN VK_CONTEXT *VkContext, + IN UINTN BltSize + ); + +EFI_STATUS +EFIAPI +RestoreVkBodyBackgroundBltBuffer ( + IN VK_CONTEXT *VkContext + ); + +EFI_STATUS +EFIAPI +SaveVkIconBackgroundBltBuffer ( + IN VK_CONTEXT *VkContext, + IN VK_DISPLAY_ATTRIBUTE IconType + ); +#endif diff --git a/Features/Intel/UserInterface/VirtualKeyboardFeaturePkg/Virtual= KeyboardDxe/VirtualKeyboardDriver.c b/Features/Intel/UserInterface/VirtualK= eyboardFeaturePkg/VirtualKeyboardDxe/VirtualKeyboardDriver.c new file mode 100644 index 0000000000..42ad493a9f --- /dev/null +++ b/Features/Intel/UserInterface/VirtualKeyboardFeaturePkg/VirtualKeyboar= dDxe/VirtualKeyboardDriver.c @@ -0,0 +1,541 @@ +/** @file + Virtual Keyboard driver. + + Copyright (c) 2012 - 2020, Intel Corporation. All rights reserved.
    + SPDX-License-Identifier: BSD-2-Clause-Patent + +**/ + +#include "VirtualKeyboard.h" + +UINT32 mOrigConOutRow =3D 0; +UINT32 mOrigSetupConOutRow =3D 0; +EFI_HII_HANDLE mHiiHandle =3D NULL; + +EFI_STATUS +EFIAPI +VirtualKeyboardDriverSupported ( + IN EFI_DRIVER_BINDING_PROTOCOL *This, + IN EFI_HANDLE Controller, + IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath + ); + +EFI_STATUS +EFIAPI +VirtualKeyboardDriverStart ( + IN EFI_DRIVER_BINDING_PROTOCOL *This, + IN EFI_HANDLE Controller, + IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath + ); + +EFI_STATUS +EFIAPI +VirtualKeyboardDriverStop ( + IN EFI_DRIVER_BINDING_PROTOCOL *This, + IN EFI_HANDLE Controller, + IN UINTN NumberOfChildren, + IN EFI_HANDLE *ChildHandleBuffer + ); + +EFI_DRIVER_BINDING_PROTOCOL gVirtualKeyboardDriverBinding =3D { + VirtualKeyboardDriverSupported, + VirtualKeyboardDriverStart, + VirtualKeyboardDriverStop, + 0x10, + NULL, + NULL +}; + +/** + This is the declaration of an EFI image entry point. This entry point is + the same for UEFI Applications, UEFI OS Loaders, and UEFI Drivers includ= ing + both device drivers and bus drivers. + + @param ImageHandle The firmware allocated handle for the UEFI= image. + @param SystemTable A pointer to the EFI System Table. + + @retval EFI_SUCCESS The operation completed successfully. + @retval Others An unexpected error occurred. + +**/ +EFI_STATUS +EFIAPI +VirtualKeyboardDriverEntryPoint ( + IN EFI_HANDLE ImageHandle, + IN EFI_SYSTEM_TABLE *SystemTable + ) +{ + EFI_STATUS Status; + + DEBUG ((DEBUG_VK_ROUTINE_ENTRY_EXIT, "VirtualKeyboardDriverEntryPoint St= art\n")); + // + // Install UEFI Driver Model protocol(s). + // + Status =3D EfiLibInstallDriverBindingComponentName2 ( + ImageHandle, + SystemTable, + &gVirtualKeyboardDriverBinding, + ImageHandle, + &gVirtualKeyboardComponentName, + &gVirtualKeyboardComponentName2 + ); + ASSERT_EFI_ERROR (Status); + + mHiiHandle =3D HiiAddPackages ( + &gEfiCallerIdGuid, + NULL, + VirtualKeyboardDxeImages, + NULL + ); + ASSERT (mHiiHandle !=3D NULL); + + mOrigConOutRow =3D PcdGet32 (PcdConOutRow); + mOrigSetupConOutRow =3D PcdGet32 (PcdSetupConOutRow); + + DEBUG ((DEBUG_VK_ROUTINE_ENTRY_EXIT, "VirtualKeyboardDriverEntryPoint En= d\n")); + return Status; +} + +/** + Verify the controller type + + This routine determines if the pointer and GOP are available. + + This routine is called by the UEFI driver framework during connect + processing. + + @param[in] DriverBinding Protocol instance pointer. + @param[in] Controller Handle of device to test. + @param[in] RemainingDevicePath Not used. + + @retval EFI_SUCCESS This driver supports this device. + @retval other This driver does not support this device. + +**/ +EFI_STATUS +EFIAPI +VirtualKeyboardDriverSupported ( + IN EFI_DRIVER_BINDING_PROTOCOL *This, + IN EFI_HANDLE Controller, + IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath + ) +{ + EFI_GRAPHICS_OUTPUT_PROTOCOL *GraphicsOutput; + EFI_STATUS Status; + + DEBUG ((DEBUG_VK_ROUTINE_ENTRY_EXIT, "VirtualKeyboardDriverSupported Sta= rt\n")); + + // + // Verify that the driver is not already started + // + Status =3D gBS->OpenProtocol ( + Controller, + &gEfiCallerIdGuid, + NULL, + This->DriverBindingHandle, + Controller, + EFI_OPEN_PROTOCOL_TEST_PROTOCOL + ); + if (!EFI_ERROR (Status)) { + Status =3D EFI_ALREADY_STARTED; + DEBUG ((DEBUG_VK_ROUTINE_ENTRY_EXIT, "ERROR - VK has already initializ= ed\n")); + goto Error; + } + + // + // Determine if the pointer protocol is available. + // This should be installed in touch driver. + // + Status =3D gBS->OpenProtocol ( + Controller, + &gEfiAbsolutePointerProtocolGuid, + NULL, + This->DriverBindingHandle, + Controller, + EFI_OPEN_PROTOCOL_TEST_PROTOCOL + ); + if (EFI_ERROR (Status)) { + DEBUG ((DEBUG_VK_ROUTINE_ENTRY_EXIT, "ERROR - VK Absolute pointer prot= ocol not found\n")); + goto Error; + } + + Status =3D gBS->OpenProtocol ( + Controller, + &gEfiTouchPanelGuid, + NULL, + This->DriverBindingHandle, + Controller, + EFI_OPEN_PROTOCOL_TEST_PROTOCOL + ); + if (EFI_ERROR (Status)) { + DEBUG ((DEBUG_VK_ROUTINE_ENTRY_EXIT, "ERROR - VK Touch Panel Guid not = found\n")); + goto Error; + } + + // + // Determine if the graphics output protocol is available + // + Status =3D gBS->HandleProtocol ( + gST->ConsoleOutHandle, + &gEfiGraphicsOutputProtocolGuid, + (VOID **)&GraphicsOutput + ); + if (EFI_ERROR (Status)) { + DEBUG ((DEBUG_VK_ROUTINE_ENTRY_EXIT, "ERROR - VK Graphics output proto= col not found\n")); + goto Error; + } + + DEBUG ((DEBUG_VK_ROUTINE_ENTRY_EXIT | DEBUG_INFO, "VirtualKeyboardDriver= Supported Success, Status: %r\n", Status)); + goto End; + +Error: + DEBUG ((DEBUG_VK_ROUTINE_ENTRY_EXIT, "VirtualKeyboardDriverSupported Fai= led, Status: %r\n", Status)); + +End: + DEBUG ((DEBUG_VK_ROUTINE_ENTRY_EXIT, "VirtualKeyboardDriverSupported End= \n")); + return Status; +} + +/** + Connect to the controller + + This routine initializes an instance of the virutal keyboard driver for = this + controller. + + This routine is called by the UEFI driver framework during connect + processing if the controller passes the tests in I2cBusDriverSupported. + + @param[in] DriverBinding Protocol instance pointer. + @param[in] Controller Handle of device to work with. + @param[in] RemainingDevicePath Not used, always produce all possible ch= ildren. + + @retval EFI_SUCCESS This driver is added to Controller. + @retval other This driver does not support this device. + +**/ +EFI_STATUS +EFIAPI +VirtualKeyboardDriverStart ( + IN EFI_DRIVER_BINDING_PROTOCOL *This, + IN EFI_HANDLE Controller, + IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath + ) +{ + VK_CONTEXT *VkContext; + EFI_STATUS Status; + + DEBUG ((DEBUG_VK_ROUTINE_ENTRY_EXIT | DEBUG_INFO, "VirtualKeyboardDriver= Start Start\n")); + + VkContext =3D AllocateZeroPool (sizeof (VK_CONTEXT)); + if (VkContext =3D=3D NULL) { + DEBUG ((DEBUG_VK_ROUTINE_ENTRY_EXIT | DEBUG_ERROR, "ERROR - No memory = for virtual keyboard driver\n")); + Status =3D EFI_OUT_OF_RESOURCES; + ASSERT_EFI_ERROR (Status); + goto Error; + } + + Status =3D gBS->OpenProtocol ( + Controller, + &gEfiAbsolutePointerProtocolGuid, + (VOID**) &VkContext->AbsolutePointer, + This->DriverBindingHandle, + Controller, + EFI_OPEN_PROTOCOL_BY_DRIVER + ); + if (EFI_ERROR (Status)) { + DEBUG ((DEBUG_VK_ROUTINE_ENTRY_EXIT | DEBUG_ERROR, "ERROR - Failed to = open absolute pointer protocol, Status: %r\n", Status)); + goto Error; + } + + Status =3D gBS->OpenProtocol ( + Controller, + &gEfiTouchPanelGuid, + NULL, + This->DriverBindingHandle, + Controller, + EFI_OPEN_PROTOCOL_TEST_PROTOCOL + ); + if (EFI_ERROR (Status)) { + DEBUG ((DEBUG_VK_ROUTINE_ENTRY_EXIT | DEBUG_ERROR, "ERROR - TouchPanel= GUID not found, Status: %r\n", Status)); + goto Error; + } + + Status =3D gBS->HandleProtocol ( + gST->ConsoleOutHandle, + &gEfiGraphicsOutputProtocolGuid, + (VOID**) &VkContext->GraphicsOutput + ); + if (EFI_ERROR (Status)) { + DEBUG ((DEBUG_VK_ROUTINE_ENTRY_EXIT | DEBUG_ERROR, "ERROR - Graphics o= utput protocol not available, Status: %r\n", Status)); + goto Error; + } + + VkContext->HiiHandle =3D mHiiHandle; + Status =3D VkApiStart (VkContext, Controller); + if (EFI_ERROR (Status)) { + DEBUG ((DEBUG_VK_ROUTINE_ENTRY_EXIT | DEBUG_ERROR, "ERROR - Failed to = VkApiStart, Status: %r\n", Status)); + goto Error; + } + + Status =3D gBS->InstallMultipleProtocolInterfaces ( + &Controller, + &gEfiCallerIdGuid, + VkContext, + &gEfiSimpleTextInProtocolGuid, + &VkContext->SimpleTextIn, + &gEfiSimpleTextInputExProtocolGuid, + &VkContext->SimpleTextInEx, + &gEfiConsoleInDeviceGuid, + NULL, + NULL + ); + if (EFI_ERROR (Status)) { + DEBUG ((DEBUG_VK_ROUTINE_ENTRY_EXIT | DEBUG_ERROR, "ERROR - Failed to = install VK protocols, Status: %r\n", Status)); + ASSERT_EFI_ERROR (Status); + goto Error; + } + + DEBUG ((DEBUG_VK_ROUTINE_ENTRY_EXIT | DEBUG_INFO, "VirtualKeyboardDriver= Start Success, Status: %r\n", Status)); + goto End; + +Error: + if (VkContext !=3D NULL) { + FreePool (VkContext); + } + + gBS->CloseProtocol ( + Controller, + &gEfiAbsolutePointerProtocolGuid, + This->DriverBindingHandle, + Controller + ); + + // + // Restore setting if connect device fail. + // + PcdSet32S (PcdConOutRow, mOrigConOutRow); + PcdSet32S (PcdSetupConOutRow, mOrigSetupConOutRow); + + DEBUG ((DEBUG_VK_ROUTINE_ENTRY_EXIT, "VirtualKeyboardDriverStart Failed,= Status: %r\n", Status)); + +End: + DEBUG ((DEBUG_VK_ROUTINE_ENTRY_EXIT, "VirtualKeyboardDriverStart End\n")= ); + + return Status; +} + +/** + Disconnect from the controller. + + This routine disconnects from the controller. + + This routine is called by DriverUnload when the I2C bus driver + is being unloaded. + + @param[in] DriverBinding Protocol instance pointer. + @param[in] Controller Handle of device to stop driver on. + @param[in] NumberOfChildren How many children need to be stopped. + @param[in] ChildHandleBuffer Not used. + + @retval EFI_SUCCESS This driver is removed Controller. + @retval EFI_DEVICE_ERROR The device could not be stopped due to a= device error. + @retval other This driver was not removed from this de= vice. + +**/ +EFI_STATUS +EFIAPI +VirtualKeyboardDriverStop ( + IN EFI_DRIVER_BINDING_PROTOCOL *This, + IN EFI_HANDLE Controller, + IN UINTN NumberOfChildren, + IN EFI_HANDLE *ChildHandleBuffer + ) +{ + VK_CONTEXT *VkContext; + EFI_STATUS Status; + + DEBUG ((DEBUG_VK_ROUTINE_ENTRY_EXIT, "VirtualKeyboardDriverStop Start\n"= )); + + Status =3D gBS->OpenProtocol ( + Controller, + &gEfiCallerIdGuid, + (VOID**)&VkContext, + This->DriverBindingHandle, + Controller, + EFI_OPEN_PROTOCOL_BY_DRIVER | EFI_OPEN_PROTOCOL_EXCLUSIVE + ); + if (EFI_ERROR (Status)) { + Status =3D EFI_SUCCESS; + goto Success; + } + + // + // Done with the driver protocol + // + Status =3D gBS->CloseProtocol ( + Controller, + &gEfiCallerIdGuid, + This->DriverBindingHandle, + Controller + ); + if (EFI_ERROR (Status)) { + DEBUG ((DEBUG_VK_ROUTINE_ENTRY_EXIT, "ERROR - Failed to close the VK p= rotocol, Status: %r\n", Status)); + goto Error; + } + + // + // Remove ConsoleIn protocols first to close the link in ConSplitter + // + Status =3D gBS->OpenProtocol ( + Controller, + &gEfiConsoleInDeviceGuid, + NULL, + This->DriverBindingHandle, + Controller, + EFI_OPEN_PROTOCOL_TEST_PROTOCOL + ); + if (EFI_ERROR (Status)) { + DEBUG ((DEBUG_VK_ROUTINE_ENTRY_EXIT, "ERROR - Failed to uninstall the = protocols, Status: %r\n", Status)); + goto Error; + } + + // + // Remove the remaining protocols + // + Status =3D gBS->UninstallMultipleProtocolInterfaces ( + Controller, + &gEfiCallerIdGuid, + VkContext, + &gEfiSimpleTextInProtocolGuid, + &VkContext->SimpleTextIn, + &gEfiSimpleTextInputExProtocolGuid, + &VkContext->SimpleTextInEx, + &gEfiConsoleInDeviceGuid, + NULL, + NULL + ); + if (EFI_ERROR (Status)) { + DEBUG ((DEBUG_VK_ROUTINE_ENTRY_EXIT, "ERROR - Failed to uninstall the = protocols, Status: %r\n", Status)); + goto Error; + } + + // + // Stop the driver + // + VkApiStop (VkContext); + + // + // Release the pointer protocol upon failure + // + Status =3D gBS->CloseProtocol ( + Controller, + &gEfiAbsolutePointerProtocolGuid, + This->DriverBindingHandle, + Controller + ); + if (EFI_ERROR (Status)) { + DEBUG ((DEBUG_VK_ROUTINE_ENTRY_EXIT, "ERROR - Failed to close absolute= pointer protocol, Status: %r\n", Status)); + goto Error; + } + + // + // Release VkContext + // + if (VkContext !=3D NULL) { + FreePool (VkContext); + } + +Success: + DEBUG ((DEBUG_VK_ROUTINE_ENTRY_EXIT, "VirtualKeyboardDriverStop Success,= Status: %r\n", Status)); + goto End; + +Error: + DEBUG ((DEBUG_VK_ROUTINE_ENTRY_EXIT, "VirtualKeyboardDriverStop Failed, = Status: %r\n", Status)); + +End: + DEBUG ((DEBUG_VK_ROUTINE_ENTRY_EXIT, "VirtualKeyboardDriverStop End\n")); + return Status; +} + +/** + Unloads an image. + + @param[in] ImageHandle Handle that identifies the image to be unl= oaded. + + @retval EFI_SUCCESS The image has been unloaded. + @retval EFI_INVALID_PARAMETER ImageHandle is not a valid image handle. + +**/ +EFI_STATUS +EFIAPI +VirtualKeyboardDriverUnload ( + IN EFI_HANDLE ImageHandle + ) +{ + EFI_STATUS Status; + EFI_HANDLE *HandleBuffer; + UINTN HandleCount; + UINTN Index; + + DEBUG ((DEBUG_VK_ROUTINE_ENTRY_EXIT, "VirtualKeyboardDriverUnload Start\= n")); + + // + // Retrieve array of all handles in the handle database + // + Status =3D gBS->LocateHandleBuffer ( + AllHandles, + NULL, + NULL, + &HandleCount, + &HandleBuffer + ); + if (EFI_ERROR (Status)) { + DEBUG ((DEBUG_VK_ROUTINE_ENTRY_EXIT, "ERROR - Failed to locate handle = buffer, Status: %r\n", Status)); + ASSERT_EFI_ERROR (Status); + goto Error; + } + + // + // Disconnect the current driver from handles in the handle database + // + for (Index =3D 0; Index < HandleCount; Index++) { + gBS->DisconnectController (HandleBuffer[Index], ImageHandle, NULL); + } + + // + // Free the array of handles + // + if (HandleBuffer !=3D NULL) { + FreePool (HandleBuffer); + } + + // + // Uninstall protocols installed in the driver entry point + // + Status =3D gBS->UninstallMultipleProtocolInterfaces ( + ImageHandle, + &gEfiDriverBindingProtocolGuid, + &gVirtualKeyboardDriverBinding, + &gEfiComponentNameProtocolGuid, + &gVirtualKeyboardComponentName, + &gEfiComponentName2ProtocolGuid, + &gVirtualKeyboardComponentName2, + NULL + ); + if (EFI_ERROR (Status)) { + ASSERT_EFI_ERROR (Status); + goto Error; + } + + HiiRemovePackages (mHiiHandle); + + DEBUG ((DEBUG_VK_ROUTINE_ENTRY_EXIT, "VirtualKeyboardDriverUnload Succes= s, Status: %r\n", Status)); + goto End; + +Error: + DEBUG ((DEBUG_VK_ROUTINE_ENTRY_EXIT, "VirtualKeyboardDriverUnload Failed= , Status: %r\n", Status)); + +End: + DEBUG ((DEBUG_VK_ROUTINE_ENTRY_EXIT, "VirtualKeyboardDriverUnload End\n"= )); + return Status; +} diff --git a/Features/Intel/UserInterface/VirtualKeyboardFeaturePkg/Virtual= KeyboardDxe/VirtualKeyboardDxe.inf b/Features/Intel/UserInterface/VirtualKe= yboardFeaturePkg/VirtualKeyboardDxe/VirtualKeyboardDxe.inf new file mode 100644 index 0000000000..9ecc99d5a7 --- /dev/null +++ b/Features/Intel/UserInterface/VirtualKeyboardFeaturePkg/VirtualKeyboar= dDxe/VirtualKeyboardDxe.inf @@ -0,0 +1,77 @@ +## @file +# Instance of virtual keyboard driver binding protocol. +# +# Compliant with efi driver model, 1. VirtualKeyboardDriverSupported +# determines if the pointer and GOP are available. 2. +# VirtualKeyboardDriverStart initializes an instance of the virtual +# keyboard driver for a particular controller. 3. +# VirtualKeyboardDriverStop is called by DriverUnload when the I2C bus +# driver is being unload. +# +# Copyright (c) 2012 - 2020, Intel Corporation. All rights reserved.
    +# SPDX-License-Identifier: BSD-2-Clause-Patent +# +## + +[Defines] + INF_VERSION =3D 0x00010017 + BASE_NAME =3D VirtualKeyboardDxe + FILE_GUID =3D E4735AAC-9C27-493f-86EA-9EFF43D7ADCD + VERSION_STRING =3D 1.0 + MODULE_TYPE =3D UEFI_DRIVER + ENTRY_POINT =3D VirtualKeyboardDriverEntryPoint + UNLOAD_IMAGE =3D VirtualKeyboardDriverUnload + +# +# VALID_ARCHITECTURES =3D IA32 X64 +# DRIVER_BINDING =3D gVirtualKeyboardDriverBinding; +# COMPONENT_NAME =3D gVirtualKeyboardComponentName; +# COMPONENT_NAME2 =3D gVirtualKeyboardComponentName2; +# + +[LibraryClasses] + BaseMemoryLib + DebugLib + MemoryAllocationLib + UefiBootServicesTableLib + UefiDriverEntryPoint + UefiLib + PcdLib + HiiLib + +[Packages] + MdePkg/MdePkg.dec + MdeModulePkg/MdeModulePkg.dec + UserInterface/VirtualKeyboardFeaturePkg/VirtualKeyboardFeaturePkg.dec + +[Pcd] + gEfiMdeModulePkgTokenSpaceGuid.PcdConOutRow + gEfiMdeModulePkgTokenSpaceGuid.PcdSetupConOutRow + +[Sources] + CapitalLetterKeyboard.bmp + DigitKeyboard.bmp + FullIcon.bmp + SimpleIcon.bmp + SimpleKeyboard.bmp + KeyboardLayout.idf + KeyboardLayout.c + ComponentName.c + Keyboard.c + VirtualKeyboard.h + VirtualKeyboardDriver.c + +[Protocols] + gEfiAbsolutePointerProtocolGuid ## TO_START + gEfiDriverBindingProtocolGuid ## PRODUCES + gEfiGraphicsOutputProtocolGuid ## TO_START + gEfiSimpleTextInProtocolGuid ## BY_START + gEfiSimpleTextInputExProtocolGuid ## BY_START + gEfiHiiImageExProtocolGuid ## TO_START + +[Guids] + gEfiConsoleInDeviceGuid ## SOMETIMES_PRODUCES + gEfiTouchPanelGuid ## TO_START + +[Depex] + gEfiHiiDatabaseProtocolGuid diff --git a/Features/Intel/UserInterface/VirtualKeyboardFeaturePkg/Virtual= KeyboardFeaturePkg.dec b/Features/Intel/UserInterface/VirtualKeyboardFeatur= ePkg/VirtualKeyboardFeaturePkg.dec new file mode 100644 index 0000000000..2742a04a8f --- /dev/null +++ b/Features/Intel/UserInterface/VirtualKeyboardFeaturePkg/VirtualKeyboar= dFeaturePkg.dec @@ -0,0 +1,26 @@ +## @file +# This package provides advanced feature functionality for User Authentica= tion support. +# This package should only depend on EDK II Core packages, IntelSiliconPkg= , and MinPlatformPkg. +# +# The DEC files are used by the utilities that parse DSC and +# INF files to generate AutoGen.c and AutoGen.h files +# for the build infrastructure. +# +# Copyright (c) 2020, Intel Corporation. All rights reserved.
    +# +# SPDX-License-Identifier: BSD-2-Clause-Patent +# +## + +[Defines] + DEC_SPECIFICATION =3D 0x00010017 + PACKAGE_NAME =3D VirtualKeyboardFeaturePkg + PACKAGE_GUID =3D A40DFD69-3552-40E8-8D3D-89741B03B9E1 + PACKAGE_VERSION =3D 0.1 + +[Includes] + Include + +[Guids] + ## GUID used for VirtualKeyboardDriver to open TouchPanel protocol. + gEfiTouchPanelGuid =3D { 0x91b1d27b, 0xe12= 6, 0x48d1, { 0x82, 0x34, 0xd2, 0x8b, 0x81, 0xc8, 0x83, 0x62 }} diff --git a/Features/Intel/UserInterface/VirtualKeyboardFeaturePkg/Virtual= KeyboardFeaturePkg.dsc b/Features/Intel/UserInterface/VirtualKeyboardFeatur= ePkg/VirtualKeyboardFeaturePkg.dsc new file mode 100644 index 0000000000..ab3605fa15 --- /dev/null +++ b/Features/Intel/UserInterface/VirtualKeyboardFeaturePkg/VirtualKeyboar= dFeaturePkg.dsc @@ -0,0 +1,30 @@ +## @file +# This is a build description file for the User Authentication advanced fe= ature. +# This package should only depend on EDK II Core packages, IntelSiliconPkg= , and MinPlatformPkg. +# +# The DEC files are used by the utilities that parse DSC and +# INF files to generate AutoGen.c and AutoGen.h files +# for the build infrastructure. +# +# Copyright (c) 2020, Intel Corporation. All rights reserved.
    +# +# SPDX-License-Identifier: BSD-2-Clause-Patent +# +## + +[Defines] + PLATFORM_NAME =3D VirtualKeyboardFeaturePkg + PLATFORM_GUID =3D 6D396683-C82B-41D5-84E7-BB6E13B7C2BF + PLATFORM_VERSION =3D 0.1 + DSC_SPECIFICATION =3D 0x00010005 + OUTPUT_DIRECTORY =3D Build/$(PLATFORM_NAME) + SUPPORTED_ARCHITECTURES =3D IA32|X64 + BUILD_TARGETS =3D DEBUG|RELEASE|NOOPT + SKUID_IDENTIFIER =3D DEFAULT + PEI_ARCH =3D IA32 + DXE_ARCH =3D X64 + +# +# This package always builds the feature. +# +!include Include/VirtualKeyboardFeature.dsc --=20 2.24.0.windows.2 -=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D- Groups.io Links: You receive all messages sent to this group. View/Reply Online (#56348): https://edk2.groups.io/g/devel/message/56348 Mute This Topic: https://groups.io/mt/72555278/1787277 Group Owner: devel+owner@edk2.groups.io Unsubscribe: https://edk2.groups.io/g/devel/unsub [importer@patchew.org] -=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-