From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from mga07.intel.com (mga07.intel.com [134.134.136.100]) by mx.groups.io with SMTP id smtpd.web11.2291.1585731507198405687 for ; Wed, 01 Apr 2020 01:58:27 -0700 Authentication-Results: mx.groups.io; dkim=missing; spf=pass (domain: intel.com, ip: 134.134.136.100, mailfrom: ray.ni@intel.com) IronPort-SDR: zmxYS9HUV+UiMtq2q6Crlu/Ts5G5CkM03GZXb54UHt54xwN8oX2tDJBZg1C8+V037ulJBsgTLC J/VHfr8Z8Xxw== X-Amp-Result: SKIPPED(no attachment in message) X-Amp-File-Uploaded: False Received: from orsmga005.jf.intel.com ([10.7.209.41]) by orsmga105.jf.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 01 Apr 2020 01:58:26 -0700 IronPort-SDR: 3djfeSKDNee0CP5/JBo5TQgaMe0jAkKIa5+D9h4WmaNprkE5EK9LHHrjgN6g/j00POmTuK70JM fbzwRLYglXfg== X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.72,331,1580803200"; d="scan'208";a="422637454" Received: from fmsmsx106.amr.corp.intel.com ([10.18.124.204]) by orsmga005.jf.intel.com with ESMTP; 01 Apr 2020 01:58:25 -0700 Received: from fmsmsx112.amr.corp.intel.com (10.18.116.6) by FMSMSX106.amr.corp.intel.com (10.18.124.204) with Microsoft SMTP Server (TLS) id 14.3.439.0; Wed, 1 Apr 2020 01:58:25 -0700 Received: from shsmsx107.ccr.corp.intel.com (10.239.4.96) by FMSMSX112.amr.corp.intel.com (10.18.116.6) with Microsoft SMTP Server (TLS) id 14.3.439.0; Wed, 1 Apr 2020 01:58:24 -0700 Received: from shsmsx104.ccr.corp.intel.com ([169.254.5.225]) by SHSMSX107.ccr.corp.intel.com ([169.254.9.191]) with mapi id 14.03.0439.000; Wed, 1 Apr 2020 16:58:21 +0800 From: "Ni, Ray" To: "devel@edk2.groups.io" , "Tan, Ming" CC: "Dong, Eric" Subject: Re: [edk2-devel] [PATCH] Features/Intel/UserInterface: Add VirtualKeyboardFeaturePkg Thread-Topic: [edk2-devel] [PATCH] Features/Intel/UserInterface: Add VirtualKeyboardFeaturePkg Thread-Index: AQHWAwewP+kXVx19M06FVwJiUhXvEKhj/UoA Date: Wed, 1 Apr 2020 08:58:21 +0000 Message-ID: <734D49CCEBEEF84792F5B80ED585239D5C4D44D9@SHSMSX104.ccr.corp.intel.com> References: <20200326004344.5060-1-ming.tan@intel.com> In-Reply-To: <20200326004344.5060-1-ming.tan@intel.com> Accept-Language: en-US, zh-CN X-MS-Has-Attach: X-MS-TNEF-Correlator: dlp-product: dlpe-windows dlp-version: 11.2.0.6 dlp-reaction: no-action x-originating-ip: [10.239.127.40] MIME-Version: 1.0 Return-Path: ray.ni@intel.com Content-Language: en-US Content-Type: text/plain; charset="us-ascii" Content-Transfer-Encoding: quoted-printable Ming, 1. Can you update all the "TODO" in Readme.md to fill with detailed informa= tion? 2. gEfiTouchPanelGuid contains the 'Efi' prefix but isn't defined in UEFI o= r PI spec. Can you please rename it to "gEdkiiTouchPanelGuid"? Because there is no header file associated with this GUID, the rename w= ithout changing the GUID value may have no impact to other code. 3. Can you please evaluate all the debug messages controlled by DEBUG_VK_* = macro? Can some debug messages be removed? Can the proper debug error level (ERROR, WARN, INFO, VERBOSE) be assigned to the remai= ning debug messages? I would like to remove all the DEBUG_VK_* macros. 4. Can you please check whether the code can pass ECC check? Thanks, Ray > -----Original Message----- > From: devel@edk2.groups.io On Behalf Of Tan, Ming > Sent: Thursday, March 26, 2020 8:44 AM > To: devel@edk2.groups.io > Subject: [edk2-devel] [PATCH] Features/Intel/UserInterface: Add VirtualKe= yboardFeaturePkg >=20 > REF: https://bugzilla.tianocore.org/show_bug.cgi?id=3D2603 >=20 > It add a VirtualKeyboardDxe driver. > It is used with a touch panel, simulate a keyboard in the screen. >=20 > Signed-off-by: Ming Tan > --- > .../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/VirtualKeyboardFeaturePk= g/Include/PostMemory.fdf > create mode 100644 Features/Intel/UserInterface/VirtualKeyboardFeaturePk= g/Include/PreMemory.fdf > create mode 100644 Features/Intel/UserInterface/VirtualKeyboardFeaturePk= g/Include/VirtualKeyboardFeature.dsc > create mode 100644 Features/Intel/UserInterface/VirtualKeyboardFeaturePk= g/Readme.md > create mode 100644 > Features/Intel/UserInterface/VirtualKeyboardFeaturePkg/VirtualKeyboardDxe= /CapitalLetterKeyboard.bmp > create mode 100644 Features/Intel/UserInterface/VirtualKeyboardFeaturePk= g/VirtualKeyboardDxe/ComponentName.c > create mode 100644 Features/Intel/UserInterface/VirtualKeyboardFeaturePk= g/VirtualKeyboardDxe/ComponentName.h > create mode 100644 Features/Intel/UserInterface/VirtualKeyboardFeaturePk= g/VirtualKeyboardDxe/DigitKeyboard.bmp > create mode 100644 Features/Intel/UserInterface/VirtualKeyboardFeaturePk= g/VirtualKeyboardDxe/FullIcon.bmp > create mode 100644 Features/Intel/UserInterface/VirtualKeyboardFeaturePk= g/VirtualKeyboardDxe/Keyboard.c > create mode 100644 Features/Intel/UserInterface/VirtualKeyboardFeaturePk= g/VirtualKeyboardDxe/KeyboardLayout.c > create mode 100644 Features/Intel/UserInterface/VirtualKeyboardFeaturePk= g/VirtualKeyboardDxe/KeyboardLayout.idf > create mode 100644 Features/Intel/UserInterface/VirtualKeyboardFeaturePk= g/VirtualKeyboardDxe/SimpleIcon.bmp > create mode 100644 Features/Intel/UserInterface/VirtualKeyboardFeaturePk= g/VirtualKeyboardDxe/SimpleKeyboard.bmp > create mode 100644 Features/Intel/UserInterface/VirtualKeyboardFeaturePk= g/VirtualKeyboardDxe/VirtualKeyboard.h > create mode 100644 > Features/Intel/UserInterface/VirtualKeyboardFeaturePkg/VirtualKeyboardDxe= /VirtualKeyboardDriver.c > create mode 100644 Features/Intel/UserInterface/VirtualKeyboardFeaturePk= g/VirtualKeyboardDxe/VirtualKeyboardDxe.inf > create mode 100644 Features/Intel/UserInterface/VirtualKeyboardFeaturePk= g/VirtualKeyboardFeaturePkg.dec > create mode 100644 Features/Intel/UserInterface/VirtualKeyboardFeaturePk= g/VirtualKeyboardFeaturePkg.dsc >=20 > diff --git a/Features/Intel/UserInterface/VirtualKeyboardFeaturePkg/Inclu= de/PostMemory.fdf > b/Features/Intel/UserInterface/VirtualKeyboardFeaturePkg/Include/PostMemo= ry.fdf > new file mode 100644 > index 0000000000..bf4a4d5078 > --- /dev/null > +++ b/Features/Intel/UserInterface/VirtualKeyboardFeaturePkg/Include/Post= Memory.fdf > @@ -0,0 +1,10 @@ > +## @file >=20 > +# FDF file for post-memory modules that enable Virtual Keyboard. >=20 > +# >=20 > +# Copyright (c) 2020, Intel Corporation. All rights reserved.
>=20 > +# >=20 > +# SPDX-License-Identifier: BSD-2-Clause-Patent >=20 > +# >=20 > +## >=20 > + >=20 > + INF UserInterface/VirtualKeyboardFeaturePkg/VirtualKeyboardDxe/Virtual= KeyboardDxe.inf >=20 > diff --git a/Features/Intel/UserInterface/VirtualKeyboardFeaturePkg/Inclu= de/PreMemory.fdf > b/Features/Intel/UserInterface/VirtualKeyboardFeaturePkg/Include/PreMemor= y.fdf > new file mode 100644 > index 0000000000..c39a057f94 > --- /dev/null > +++ b/Features/Intel/UserInterface/VirtualKeyboardFeaturePkg/Include/PreM= emory.fdf > @@ -0,0 +1,8 @@ > +## @file >=20 > +# FDF file for pre-memory modules that enable Virtual Keyboard. >=20 > +# >=20 > +# Copyright (c) 2020, Intel Corporation. All rights reserved.
>=20 > +# >=20 > +# SPDX-License-Identifier: BSD-2-Clause-Patent >=20 > +# >=20 > +## >=20 > diff --git a/Features/Intel/UserInterface/VirtualKeyboardFeaturePkg/Inclu= de/VirtualKeyboardFeature.dsc > b/Features/Intel/UserInterface/VirtualKeyboardFeaturePkg/Include/VirtualK= eyboardFeature.dsc > new file mode 100644 > index 0000000000..c10fb2d567 > --- /dev/null > +++ b/Features/Intel/UserInterface/VirtualKeyboardFeaturePkg/Include/Virt= ualKeyboardFeature.dsc > @@ -0,0 +1,96 @@ > +## @file >=20 > +# This is a build description file for the Virtual Keyboard feature. >=20 > +# This file should be included into another package DSC file to build th= is feature. >=20 > +# >=20 > +# The DEC files are used by the utilities that parse DSC and >=20 > +# INF files to generate AutoGen.c and AutoGen.h files >=20 > +# for the build infrastructure. >=20 > +# >=20 > +# Copyright (c) 2020, Intel Corporation. All rights reserved.
>=20 > +# >=20 > +# SPDX-License-Identifier: BSD-2-Clause-Patent >=20 > +# >=20 > +## >=20 > + >=20 > +########################################################################= ######## >=20 > +# >=20 > +# Defines Section - statements that will be processed to create a Makefi= le. >=20 > +# >=20 > +########################################################################= ######## >=20 > +[Defines] >=20 > +!ifndef $(PEI_ARCH) >=20 > + !error "PEI_ARCH must be specified to build this feature!" >=20 > +!endif >=20 > +!ifndef $(DXE_ARCH) >=20 > + !error "DXE_ARCH must be specified to build this feature!" >=20 > +!endif >=20 > + >=20 > +########################################################################= ######## >=20 > +# >=20 > +# Library Class section - list of all Library Classes needed by this fea= ture. >=20 > +# >=20 > +########################################################################= ######## >=20 > +[LibraryClasses] >=20 > + ####################################### >=20 > + # Edk2 Packages >=20 > + ####################################### >=20 > + BaseLib|MdePkg/Library/BaseLib/BaseLib.inf >=20 > + BaseMemoryLib|MdePkg/Library/BaseMemoryLib/BaseMemoryLib.inf >=20 > + DebugLib|MdePkg/Library/BaseDebugLibNull/BaseDebugLibNull.inf >=20 > + UefiBootServicesTableLib|MdePkg/Library/UefiBootServicesTableLib/UefiB= ootServicesTableLib.inf >=20 > + UefiDriverEntryPoint|MdePkg/Library/UefiDriverEntryPoint/UefiDriverEnt= ryPoint.inf >=20 > + UefiLib|MdePkg/Library/UefiLib/UefiLib.inf >=20 > + PcdLib|MdePkg/Library/BasePcdLibNull/BasePcdLibNull.inf >=20 > + HiiLib|MdeModulePkg/Library/UefiHiiLib/UefiHiiLib.inf >=20 > + DevicePathLib|MdePkg/Library/UefiDevicePathLib/UefiDevicePathLib.inf >=20 > + PrintLib|MdePkg/Library/BasePrintLib/BasePrintLib.inf >=20 > + UefiHiiServicesLib|MdeModulePkg/Library/UefiHiiServicesLib/UefiHiiServ= icesLib.inf >=20 > + UefiRuntimeServicesTableLib|MdePkg/Library/UefiRuntimeServicesTableLib= /UefiRuntimeServicesTableLib.inf >=20 > + >=20 > +[LibraryClasses.common.UEFI_DRIVER] >=20 > + ####################################### >=20 > + # Edk2 Packages >=20 > + ####################################### >=20 > + MemoryAllocationLib|MdePkg/Library/UefiMemoryAllocationLib/UefiMemoryA= llocationLib.inf >=20 > + >=20 > +########################################################################= ########################### >=20 > +# >=20 > +# Components Section - list of the modules and components that will be p= rocessed by compilation >=20 > +# tools and the EDK II tools to generate PE32/PE32+= /Coff image files. >=20 > +# >=20 > +# Note: The EDK II DSC file is not used to specify how compiled binary i= mages get placed >=20 > +# into firmware volume images. This section is just a list of modu= les to compile from >=20 > +# source into UEFI-compliant binaries. >=20 > +# It is the FDF file that contains information on combining binary= files into firmware >=20 > +# volume images, whose concept is beyond UEFI and is described in = PI specification. >=20 > +# Binary modules do not need to be listed in this section, as they= should be >=20 > +# specified in the FDF file. For example: Shell binary (Shell_Full= .efi), FAT binary (Fat.efi), >=20 > +# Logo (Logo.bmp), and etc. >=20 > +# There may also be modules listed in this section that are not re= quired in the FDF file, >=20 > +# When a module listed here is excluded from FDF file, then UEFI-c= ompliant binary will be >=20 > +# generated for it, but the binary will not be put into any firmwa= re volume. >=20 > +# >=20 > +########################################################################= ########################### >=20 > +# >=20 > +# Feature DXE Components >=20 > +# >=20 > +[Components.X64] >=20 > + ##################################### >=20 > + # Virtual Keyboard Feature Package >=20 > + ##################################### >=20 > + UserInterface/VirtualKeyboardFeaturePkg/VirtualKeyboardDxe/VirtualKeyb= oardDxe.inf >=20 > + >=20 > +########################################################################= ########################### >=20 > +# >=20 > +# BuildOptions Section - Define the module specific tool chain flags tha= t should be used as >=20 > +# the default flags for a module. These flags are= appended to any >=20 > +# standard flags that are defined by the build pr= ocess. They can be >=20 > +# applied for any modules or only those modules w= ith the specific >=20 > +# module style (EDK or EDKII) specified in [Compo= nents] section. >=20 > +# >=20 > +# For advanced features, it is recommended to ena= ble [BuildOptions] in >=20 > +# the applicable INF file so it does not affect t= he whole board package >=20 > +# build when this DSC file is active. >=20 > +# >=20 > +########################################################################= ########################### >=20 > +[BuildOptions] >=20 > diff --git a/Features/Intel/UserInterface/VirtualKeyboardFeaturePkg/Readm= e.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 >=20 > +* **Feature Name:** Virtual Keyboard >=20 > +* **PI Phase(s) Supported:** DXE >=20 > +* **SMM Required?** No >=20 > + >=20 > +## Purpose >=20 > +This feature provides a DXE virtual keyboard driver, used with a touch p= anel. >=20 > + >=20 > +# High-Level Theory of Operation >=20 > +This driver will use the following protocol: >=20 > + gEfiAbsolutePointerProtocolGuid >=20 > + gEfiTouchPanelGuid >=20 > + gEfiGraphicsOutputProtocolGuid >=20 > + >=20 > +It will show a picture like a keyboard in the graphic output, then detec= t >=20 > +position when user touch the touch panel, then calculate the key which t= he >=20 > +user want to type. >=20 > + >=20 > +## Firmware Volumes >=20 > +*_TODO_* >=20 > +A bulleted list of the firmware volumes that feature module(s) are place= d in. >=20 > + >=20 > +## Modules >=20 > +VirtualKeyboardDxe: The main driver of virtual keyboard >=20 > + >=20 > +## >=20 > +*_TODO_* >=20 > +Each module in the feature should have a section that describes the modu= le in a level of detail that is useful >=20 > +to better understand the module source code. >=20 > + >=20 > +## >=20 > +*_TODO_* >=20 > +Each library in the feature should have a section that describes the lib= rary in a level of detail that is useful >=20 > +to better understand the library source code. >=20 > + >=20 > +## Key Functions >=20 > +*_TODO_* >=20 > +A bulleted list of key functions for interacting with the feature. >=20 > + >=20 > +Not all features need to be listed. Only functions exposed through exter= nal interfaces that are important for feature >=20 > +users to be aware of. >=20 > + >=20 > +## Configuration >=20 > +*_TODO_* >=20 > +Information that is useful for configuring the feature. >=20 > + >=20 > +Not all configuration options need to be listed. This section is used to= provide more background on configuration >=20 > +options than possible elsewhere. >=20 > + >=20 > +## Data Flows >=20 > +*_TODO_* >=20 > +Architecturally defined data structures and flows for the feature. >=20 > + >=20 > +## Control Flows >=20 > +*_TODO_* >=20 > +Key control flows for the feature. >=20 > + >=20 > +## Build Flows >=20 > +*_TODO_* >=20 > +Any special build flows should be described in this section. >=20 > + >=20 > +This is particularly useful for features that use custom build tools or = require non-standard tool configuration. If the >=20 > +standard flow in the feature package template is used, this section may = be empty. >=20 > + >=20 > +## Test Point Results >=20 > +*_TODO_* >=20 > +The test(s) that can verify porting is complete for the feature. >=20 > + >=20 > +Each feature must describe at least one test point to verify the feature= is successful. If the test point is not >=20 > +implemented, this should be stated. >=20 > + >=20 > +## Functional Exit Criteria >=20 > +*_TODO_* >=20 > +The testable functionality for the feature. >=20 > + >=20 > +This section should provide an ordered list of criteria that a board int= egrator can reference to ensure the feature is >=20 > +functional on their board. >=20 > + >=20 > +## Feature Enabling Checklist >=20 > +*_TODO_* >=20 > +An ordered list of required activities to achieve desired functionality = for the feature. >=20 > + >=20 > +## Performance Impact >=20 > +A general expectation for the impact on overall boot performance due to = using this feature. >=20 > + >=20 > +This section is expected to provide guidance on: >=20 > +* How to estimate performance impact due to the feature >=20 > +* How to measure performance impact of the feature >=20 > +* How to manage performance impact of the feature >=20 > + >=20 > +## Common Optimizations >=20 > +*_TODO_* >=20 > +Common size or performance tuning options for this feature. >=20 > + >=20 > +This section is recommended but not required. If not used, the contents = should be left empty. >=20 > diff --git a/Features/Intel/UserInterface/VirtualKeyboardFeaturePkg/Virtu= alKeyboardDxe/CapitalLetterKeyboard.bmp > b/Features/Intel/UserInterface/VirtualKeyboardFeaturePkg/VirtualKeyboardD= xe/CapitalLetterKeyboard.bmp > new file mode 100644 > index 0000000000000000000000000000000000000000..759c3d46a9f0cf6a69fa98563= cd04f7a082d3b4d > GIT binary patch > literal 330454 > zcmeI5zpw7cao(?FBtU``E>p0M1NK*`gbSt#SOkdw0sRRy;5G#XA}Z1nY7D4|3%XDn > zwkD+z1_K0OWmyK;7zPUgqNK(K1CR{!=3DnT)J=3Dg!Q|&iBW8&wJjxFYJ3~_d7fL*=3DJ^V > z-}gO7m;doU|J}d-7tenG`X2uO-{b%P-FKfo```HcJJ0?t{(ScAe|-D=3DuJP?3|8KpP > z0!x9Vz*1l-a1jNbJ+o;({P4r?-qs5%QU$MMf!9fOTbW<0xfTVkv)UI`zdoE+FJ8RR > z&nug3jI{&#?#@BrKE)IAq+nOI!0V)XLTO#7Pe_65toE%`n-161`8(hF&NORVsipx> > zaUj*(Z@--`t>0 zU{ur9bsP|C-8m zIWaZuP}f;mZT#i96xg7^byj z{N=3Db5*r335R(qdnbbRjUpQ_fUnua>j!KikuHx5Clb?2Ozns%t`tgJTva$E{*P~bYN > zy-yVn&fPsz)%sM^P$xPV)$Ud6K!jR%&WWjMhq}(nYU3Yu)Eazs?9Oj49aZ)!$6sf) > z_o+@S(P@7ARMSu=3DIvCX{Iv~`#b52Z6JJfYnRvZ7Q<0-}a zOXAg3mn2cejOvux5$e^ub52ptf@oSc*>z=3DY3iTA7PfWoR3bpQ>QLUby#L-0B-`|5L > z;weCC*Ho7zQ9PqMWp;#Gcg_JNH7%R$y0SKfdWy~mB!9v~*PSz})zgzYnn?Tmd+ z1xW1?6^aM16G>tyo1&nKLw5A6J7 zau!tT2D^rQ{q@(s_~MIizWL^>ufBTo%{Oaj7dbXZRCU<1o{mb?s7{#$p)T?{=3DM-2A > z60=3DnI#2lUo(+}k!Bb9Tw?Pg!MTk;%j=3D-bXUR##N}h4ZUY7gXv7yMTP_t+&4X@=3DIJe > z_WJtkuits+oxvsCxQ9PXR<;3x+fshq=3DY > zHxG*WM2C+y^lj%Ft1GJg!l_iL3o3PkJ%V%>PUqTjkz;d2HDWloe^jDIb;?`_weFl# > zl$-@|#Wkud=3DXR^jnOe8`e6*o&HOpLAQSBGbG?8EwRO$vhg-kD;>9yk`$L5GCWjMWa > zRH8<8%5(^|?wnJUoCR^kHL5JqTDSRpw4rY`%UoAc?HA58kzf>5>IOSP78g!^ > z?YPLXIiiXT579F!QKLF#Mud8W?;QT{&&ovq{QUFJpFe+IIKcU%k3Q-r!4=3Do2vYgwk > zHk-O>My}azE@!l%Z#BzYS5fV?bf0|kiRRsQWj&;RN+cKsmAb)pF{c-fF{eM zMCBOz%}D#+d+&{gk4n_2Mx!?MBh(pp&gg9BFLJnb$3?3{nkz0VW~uIpIb^62HcDpQ > zIkl<>pE3otq36vt+x05=3DbhM!lih2FR;~pe4#fgTya5lZgi_xry^TH^o)D5;qd-vUU > zwG?s0{p@EyW6#GQe{8?Q#vXUpxyZ3OqEd#f_G_=3Db_St8j5ebH)V!%;}8Wr7+7zlOV > zo%89ZpQbEW@jv{-Kk&B*?RwD)djI|RAp?8h|BwIpkE37zh*_$8Vh$rDb3z9C@G=3D}_ > z37%Gl=3D3t@X8!`tOshq=3DYHz{vz=3Dq|ZtyIuvKjyCjd=3DNhXks-5CE!_EXIJ#I|r-)yS= X > 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 v > zt@En?!)c|noNJHd>S$$SPpP*NhU@QBxq;g32)HSg9ja4QQgU5UYImqOP$L&M{dXHi > zRZQ_Hk4~gQsCDNYOX8-@$4YG0`w_GqU>&LpBSEo;riv@-NY|mVbR*j66{n6p7|XJm > z8hxrFRAh)fr&A$doaIPQu|RvYNvkHwbkeDVQ8lN#nA?d|2(|8 z1FS=3DJVI(Nlp`x%@_3jsgbc{_@qktVTv7FKH*#C5?u*{AcSaRPp>Z3iIwCb?IN8|6a > zjjB1_#oSJ$La24;9827$BY|butoI{mJHVP$T*YOK8>Z^ycT*lu(ds&>SZola^P>OA > z*rXL^?8q{jtKV-_ow+XQb0QT&J>H$uDV)NmnZ`|()r@)Etx0vHtRUT1&L-8?um}Bb > zn5rmmebg856s$=3DwPF=3DVeRcEeC`kY9GP>*-#6vChQXj5gK > zIBy-QNp+;GHk}Ga+oY^*~y!I|rq8 zf)vfARUwXhw6t=3D96wPbaiYN4y7^c-JFbK6i=3DM-i6V2`f3-XCnyI|DDR`ob-(ZbPe6 > zPWKaoSY4eG5TVwc)34I=3DJlEOK*K%pKwCXF+_q^u1I^}dfF^Fk(N ze`rs@m|BZ!D)rK8DiIx)R+M6DEUl&z(ScgMc=3D6(t1OAjCfO&vB=3DZ8Q1A=3Dkanpjsb( > z_~E_?4>1Zbrq-gG%Dc3hN<@dH6{VOOORK3wbf8ureDJ|3*TpG80Ar`<+i$;pFrZyu > zcb{_*^2oKr3x@|hdMM zUpw-7$%3svmjX+HrNB~PDe%w=3D+<(q_=3Dy_KBrNB~PDXphkozYu#Y > z5}kKZsT#Gtw5s*dr%NkUqqdh;wLbdPX>}z(9pcw?cXtjL75Q;(3bv@GiC9`qC8ER9 > zic(CCrPWj-I$XI{S90OlFCW;ob9d)Zzbi59 z{u!O-zoetTBxa-HpM_$kl?J&68&vDgDYEwRqZ_FAmlyPat)*38+@;kkqSfg~KCYlb > zI;*SGCp{PtR9o(xgR|-ILMl93yRg z;zXx}0#)zMIb}8ta!L;CAg4cVR@UkB)&VzBp*%GUBfFll^K=3DtcC*UbQi>fc<(&|L5 > zn)`0FAM5^g=3DhXV#Kdtk*>b=3D%SpKj8sS^FA)pS_7{-xNDWEvmj~ORE#LYVN!H({c0P > zDXL{~bF2p*0ICQ3ob&qYuYd8y7vIS1(@#I;dQy?tx$2!#OpQ%i?WlbWiLZ01rqRxF > z*re52lTPC-s;NYDc#2wK`|#X*AcOj-VOl-VjJv~v>H+SYc-z>;v+f+Nh_mcXyYQ6q > zN02G}CaP()vm6#xU&*D_Sz4X4>FP5+MYRmp126v+RA=3D8gZ@u-_mtTG zif+>@t)Nlorn3PU$EyrMMlkH(M8#1LZ7iz3!n?KV6j-N(Qq z4b>-Ih*7EAHQ1m!_0D zEFTySY1-Vxxs_@<`_!Q$=3D_aa8>pkMUsQT*d)@oWmaOjj!in@uaL!v(EjGfM!syG4g > z2(Qi*=3DA*P~rxA=3Dw-LAm~)p>W0UN~QW{q;NVyi+VO6^Wg74(V3J=3DOfE1n}xx!Bcn-W > z!!d6$SN&)NkoI4Uip-r|vWY5P*F$tJs=3DlhbwPKwVMyG^Q)J;?cK>cVdUQJaT1?d`# > z&JlJx#HdC?9;+Wz<(<>#(y!FM`s%AU-+XgAHr2^G(;Q9%p6=3DiXQ!3}fW>IKUP6p{1 > z7o#F}XGdg&dZJJGhhs!UF4ny?mQ`NE*VEQNmq& zRHD)B)Bde^H5HpXrxru&1AJxZI-3(j0PN > zG~R#zePR?}=3DwaX|pL{}3{rOUii5^FoQaK-Mx@e zg!kTiFV1T{>W0i(XJ@aZRHIo&{aRoytsRDgTIq1=3DW~lr~@2Xvg^zBruba*P1=3D7<&5 > zdEZxS*r#%+P9h?iVZ~NY?E-3ZO64*Y71OhVY;Nmq#jB|bBt03(P|Q9Gl@2kgsKDd) > zfNIyBqlW?W=3D8UZ;`n0kNsq`js$AFG<*wcNfNU-b5QfHkMwpNx?Nt-M>9j;+hyHADT > ztXVy%Mt6>ri*9LwJGPWc*VVBVVBI-T*ome|)Iy?NS9qPrG=3Dnb7Y11HiEfdC!N4#_N > zlyFqm)Ea|0_Da|2I%};E$0d$UJsG(D;qT(JISQ2yF)Geg8>t|>JBztMwf)YSRys-R > zlBbZ-NOL$^hvv zq3 z-lN<(%?$|koLsd;TzIV&f~f3jD;T$bG3h8&I>e}Sx{)2r=3D3vigBJ_i5 z%Q+O+4l@>wG>4;g#Ol@qQb)y))y%WH(RN@dmGiMCBbbp^mh%}k)A-uir@|=3DKtft9j > zFfzL&rUkA@up`xIfkpq5yK}IXjyO}ToCBNGN-GN6&?QK9!&80x&InV~m_cIHhEBn~ > zx$i8G6HTdD;lyxSK@eB)x)+?7&1}|G5h-QkSyW6q3Y88qD$X@Buw;1R&l6vxxzLZf > zw%j?*T1H?!-A5%K3yM8y4oB zMl-bPSy|3!)J)@RXP*kAShKp%+!izvY6YR3Lt5a91UpiV7FhIay}3+v7#vbc6@6k4 > zMI-9yD22lgu&7mJupR>F{_4ELN~^9$?Nd2gLc$mcRZr~#YI92ElBFetN_JJGs46Ml > znw&M2L()k{Cj*AqOVL~@EQc^r(rx^%hFW0Y4 > zOt z4Tq{zr@Pqlu13T3X z?(I7qc7XM%44{yOgfOOVHEN&ADW(h~q3Wq!Ky6N`T(StT`^eJSM|Mr+kW`=3DP$$+tZ > z+3Y%;HhdzRQPC$Fc0a%kMtn*(cVyY+oW8HOfN3 z>`8OT$ZEK=3DlNX)S2}9@!_#ge~NBoVucsnsZdCW+uoR2jb!3>omf;nf`Oyg^3p9-TG > zoN6FDP64G&D=3DRHlvICbC9l8YteX6!U0)pQgV8-aO}r5mB6kIvhtG7`;QT~2)O > zz9Wx)DqRa~m1`u_R*5*pluGlZ^^;~wQDJN4v)(v$VboNLRLoeXl8U(q*5p%#G^*4e > zo!I#1P+Sp~K9!CVxkJNdK`48TCPhCcZQnUs>G8d9Itfc&sp+ZmI6KWD2dd$wV2!h6 > z=3DuA(0#M`M@ONYw&Sd){Q!9*b;b!EAMXr}SCGu28R)Mk9mrYj#R16udUhNlItv%rp2 > zoVsu5nGqA}X6!U0)pS&PV6e>6!tUs!^Y*DsI?g^y5EZ894$eN6t_3z{hcN=3D!DiNoc > zQfa=3Dl$ct^Rz&s_W7^g0bno5y$F4+B(fr_~Z*5p%#G^*4em19p~qz>$~(}3!^Cf&?H > zG<&&zZDQW`ox}1$)buFQz-DXC<5{cnI6KW@jE^23kai| z^RXr)n9;8+HxSJ z9vG~;RHcqSI&YuKq+{v2B9FqRS*Baf*{9OAz-D|HBh-3o7f_p1D$N&XPt&BFwBwKt > zYE7j`oX8A4835^CJn79DaYmuguPT{sRBlEzF^fHd5udsq65`A^anjGsHj4Z%h&C~G > z`_75)05no+lNT&bKln$H*puckPNDJbfYeh;k4*Kn3zOTi*tq1;9JicrE+d* > zGmWpEsaEQsHmBh7StiaXIMV{xSzt#hPTe;&n~!qmq+48%C5V=3D8!Hz^!ENaC^&M@f+ > zP?WBDYL?^s#2T_sl|t62_0%q)Hm6jYvQv(%4r)!MNUr$xWN;gh&3JOUAZVtLM&+Cl > z*7{+%N28|I8;b2WzxfSD#X{mhGP5Tdn7w`H@V(u%(m9VR8kN&ha(0?ShNZ#Hr%JHU > zbVhpegwXSBbiQ_|oR2k0Xol**v^Zmw$uz!prdp|k+62?n$dOocqzNLV1+KHej#Qkw > zZ)lF(f4!1!pl&ccNxF7FeCfK9#NoHWh$Tpt@1b > z=3D9Eeg_*0IoS|!7tQmH0tcTNVBSz7!WCxtXBb+d|%{pyq2R5C4f4&jbqPc$(5_B)5i > zc8uqGRM7}qR9VcSi)>9Qp-9|k+DT8%9y=3DqO#dm~}$~my z5R5803~i2%G)`R@k&09I4L#sBag0y^q>mz1>c&n^M1zMYgyL^Mrb02u)JUmtio};; > zkRhFys4z6kvA__&U`weAe?C%x0+s%oj42fsMF4JaJqq|VHFT@mu~4gI@KdUEE_CX2 > z?p>bd4#hS)qbza?X;f}%gtC4Z?orXCk`B@hK}>tOer;m*_MOAe57SEL4610 zL&l^rI*@cy+h^*jnsG&=3Dl5~WT$~mw}NHY}aJ}dt3cqG_Z#vB=3DaDnuZdR zT#rb!KT>h(zM+Y`hC9dceE<93=3DWjo5DsL4EcGL=3D;g-T3NnjIZjWEpPhK}EKdicbqe > z0SeS2Lh)!yrFRZD_*5t|>sCGG&QTuDLPMw1qsbh!-s&Z!sWh!P7Y#dl@Dv6+3&WDg > z|MjCgE_5IdHSKgZ=3D6$kvj_xOyE_W-_)8%c{Pmx^hPwSojj9^AxS zc9cmhB7GVU`w@xuM=3DH0jPE+?>#6SeB$X+^iVMnTwbBf0k6rx$lvB#AbhXZdk1^ZJf > zMu^6AQV!8P#w^!tDHWK%RebyxXNOUsG5~ex7$Yi zrj@$UMgiMX80<_9o?WOP({uC=3D9m5gLUTG-n#Juf0hvkE)#p-podI+_NhE|r zC@9Wr2Nj!6Ey_7skpojI_sBIJ?Q|mNuT2*@Hv3e%9krI@X#{|gylHiJsB}?HdwS zP6SAM`dTqE4TWJLX=3DnVXgRvdCQYy|H4c7DMqT`S{%Qag{1y!|*IMK-Hpr)A`b&ja$ > zuXvn&w80~G98#-f^A=3DRf6Q`S=3D4C;^;n8i#XjVexRJ zuT4zazH@Z->6=3DasY&Op=3DfW(81WfBd|;V5bRFvA0Y07SJ-Nlz+APd-Xl zH-kLTp?O_1f{PrReJWM5K8-NDZa&RjTHPHguBdP5iJm5ip&~%q)7OfTX{aEYME0jQ > zKu4~Wit|RJo>BelEZ1x)6;#zK(z#N*gPLY))H$M}zvAh>tLumG@yM!GvUv+C<>4$e > zlu(O`4$Uo)LK+oAMZ@j~xWR}|(PQb;!X|J^YXL{mYzj=3D*zH=3D~wC$v(eu;?Tm5aP7} > z2bM`RG>2)@G zK>Cz9t?mdGsoc6cP0eF{W<-FrCsH{#tj=3DBzPf1*<=3D%ZMQh=3DYJ`7S~Lv9Dp{Nn&~#I > zvs{CvR3OJFg{kchs#BwGj;J`w;T=3DD+YL#r>g39qYxuz$BIuu(Vg)}NRqibS!n_Ijn > zIJItn47Z|6YY#!} zrgUIR zo!!~f>F8f)IX$QdmQvyANFq+EMhBHMc8n1f$2vS!V0vWng3^6jt7P*QRE|f*fjvDL > zls|n(V*yi0qjEFGCKd}%{CVOl&cYtdwdKyiI895DLmv59hkIYh$yp}R&>W^oBgSZ# > zGgrKGQd-SU#rNUs!|UEjMqg(E=3DP6RF&~ > zI!(n$)5jnwL+p%H&POF;aK&(Hn2$Q7oNgA^OsP0~G&%>ljjFSp9#mvYsqi$FC_-9K > z2bD8+j1d*bMm(MsDD^ZuhB`X3YL#r>f-3T;R@0L~;p0AKs1(wu=3Du;Rc-ZmDhm z?;I7$!n;FM%N!2r9yKDCNi;NvF=3D@KRM;BV;j8}?bFsrd19hg$NN3Q84R~RRk^NdXw > zIX3%Ls-&jL)w0qegHDzRkoH8XxU^}HCfZ@Ru_;6Bj8x7?CE^r3IHAU z*G#E6do(y#vAJwik!3if2Nl^;Dm+akijdaRLFJ4cV??E69idjyjw7p9$>uGn9E=3Dl6 > z_nJEy^bxQ}2b~2>A&tt-IBJ?QXZ<;v1^uAfc;{e{6QjVa_k@;-vo(h?X}Xg}X8<^P > znHXU_2}~HizlpR3m3!ox7MXu`6dTo)iyWJ(ReY*Fs-$XIWDt*>ZW^$#BNf#c89bkA > z9(_u-fmUWrc{g^4GLB8*eK01wPL{ZpdwpJl}f~b > zY7kQM70U@jIAg~cQR&z^iH;{Wolvz(Hg7=3D{VN|8g$zX(zN`t^oA&ts;K6(>W+wUBs > zb|-pF-RKbIqP0w%tvQTI<1K+ni&SXU7rRsUrF*MUP`O90$u*kMsjQJ)E^=3D(DR`IF! > zsFJ$sm^=3D1Fc{N~RM=3DGaDY-+v;P#eT6Nc2&p(xm > zJ)EehYID{sJ0v)y2Nl^;s#GF^sX<7W!HB^bJI07g$HpWYn4TMs%9?QxYS_Xqs75e` > z)HxZz7DZF3VW(_H z_sBKfdUcAl*wGp5-GaEtvDv3mCG|8)k=3D*sm6-9uwCsHxO$Vh7`Wn(AzV#*LZBbD<} > ziHwu~(m-8oaMq7H$fhpS&ElFVl@50{g_qC^a+1|gX&Ga`mg > zI<-esInRd!%RP?zL160TEoFnT zP^sJ_*PKS~JGjWP*{3>1$q114M5_LhcX*}@u`^ORpHn1?{B9Q4OsQg!x(DPtUXDbY > zDHR+rOHH!%sZKhzM^tX$S&%O5s98{*MN+7WDN-<_Dh58vBT$uhjxOaOpoW^-n!{$& > z7_;eLFDFf-QgOP}sDp2Mn#R}8K2=3Dj0xD_v*y09bFrd4lsE=3DcrIq|&FbvGA=3D^cl_Nf > zt~sT0{+DTvs7{w?({e^sF33Sh*1rooY8F%nNmyM)96U z<~)nq>Px4N@!8X-Lgdbik&hUWs zQ<Uu%pY > z5lpG#)5q$0Dpa-LTc099X^!eFOtnJH4hd)3>d%2{OsUlQV)mlyOI>KytdLICjeJI& > zMl~AsSpA?nObuS-X@LVA7h?Q6{pzI^Hiud=3D|6SeAryv8wQAN0 > zXW#12foe>t)cIoeqUuXsXw|HcX~7o`BTl0#20qFoP#wN=3DMk_wjU*zye*n?viRbRj- > zs#WuZpblI8IZ%x!s+BI`V)m2Ms#zgNj{lMPrqz+i4>1;0>&_XaEc8FQdJikOT*uO? > zul3UEhP7IEj=3DQ+lozt)O#y2xtf}Q5OPOQF^ORJ?-UxB`7QCAOr=3DOF%w)2Q5$|L9Fn > zt!sDws;@xbv#6_wzH zskNx4$}g>^647C4MJcAn(rPLZ9crzP-#Lg-yolipQoVTb!kzk$*aXb|o%7*`A3Eem > zYy!saoJBRw!qRFg5gnFRlwxWut)>#u;mWo8;DZky@se><1LpqD!QW60S0jad6axTE > zAg`T8mF8k;mCBNKF0E2o($1w-Dofh=3DRJ6iL|LC7~0ALr6+&Ol}uRoUpOM#`pQeY|Y > Ka0)zo_WuC{9xg=3Dy >=20 > literal 0 > HcmV?d00001 >=20 > diff --git a/Features/Intel/UserInterface/VirtualKeyboardFeaturePkg/Virtu= alKeyboardDxe/ComponentName.c > b/Features/Intel/UserInterface/VirtualKeyboardFeaturePkg/VirtualKeyboardD= xe/ComponentName.c > new file mode 100644 > index 0000000000..6ac28ab90b > --- /dev/null > +++ b/Features/Intel/UserInterface/VirtualKeyboardFeaturePkg/VirtualKeybo= ardDxe/ComponentName.c > @@ -0,0 +1,159 @@ > +/** @file >=20 > + Virtual Keyboard driver name. >=20 > + >=20 > + Copyright (c) 2012 - 2020, Intel Corporation. All rights reserved.
>=20 > + SPDX-License-Identifier: BSD-2-Clause-Patent >=20 > + >=20 > +**/ >=20 > + >=20 > +#include "VirtualKeyboard.h" >=20 > + >=20 > +// >=20 > +// EFI Component Name Protocol >=20 > +// >=20 > +GLOBAL_REMOVE_IF_UNREFERENCED EFI_COMPONENT_NAME_PROTOCOL gVirtualKeyboa= rdComponentName =3D { >=20 > + VirtualKeyboardComponentNameGetDriverName, >=20 > + VirtualKeyboardComponentNameGetControllerName, >=20 > + "eng" >=20 > +}; >=20 > + >=20 > +// >=20 > +// EFI Component Name 2 Protocol >=20 > +// >=20 > +GLOBAL_REMOVE_IF_UNREFERENCED EFI_COMPONENT_NAME2_PROTOCOL gVirtualKeybo= ardComponentName2 =3D { >=20 > + (EFI_COMPONENT_NAME2_GET_DRIVER_NAME) VirtualKeyboardComponentName= GetDriverName, >=20 > + (EFI_COMPONENT_NAME2_GET_CONTROLLER_NAME) VirtualKeyboardComponentName= GetControllerName, >=20 > + "en" >=20 > +}; >=20 > + >=20 > +// >=20 > +// Table of driver names >=20 > +// >=20 > +GLOBAL_REMOVE_IF_UNREFERENCED EFI_UNICODE_STRING_TABLE mVirtualKeyboardD= riverNameTable[] =3D { >=20 > + { >=20 > + "eng;en", >=20 > + L"UEFI Virtual Keyboard Driver" >=20 > + }, >=20 > + { >=20 > + NULL, >=20 > + NULL >=20 > + } >=20 > +}; >=20 > + >=20 > +// >=20 > +// Controller name string table >=20 > +// >=20 > +GLOBAL_REMOVE_IF_UNREFERENCED EFI_UNICODE_STRING_TABLE mVirtualKeyboardC= ontrollerNameStringTable[] =3D { >=20 > + { >=20 > + "eng", >=20 > + L"UEFI Virtual Keyboard Driver" >=20 > + }, >=20 > + { >=20 > + NULL, >=20 > + NULL >=20 > + } >=20 > +}; >=20 > + >=20 > +/** >=20 > + Retrieves a Unicode string that is the user-readable name of the EFI D= river. >=20 > + >=20 > + @param[in] This A pointer to the EFI_COMPONENT_NAME_PROT= OCOL instance. >=20 > + @param[in] Language A pointer to a three-character ISO 639-2= language identifier. >=20 > + This is the language of the driver name = that that the caller >=20 > + is requesting, and it must match one of = the languages specified >=20 > + in SupportedLanguages. The number of la= nguages supported by a >=20 > + driver is up to the driver writer. >=20 > + @param[out] DriverName A pointer to the Unicode string to retur= n. This Unicode string >=20 > + is the name of the driver specified by T= his in the language >=20 > + specified by Language. >=20 > + >=20 > + @retval EFI_SUCCESS The Unicode string for the Driver specif= ied by This >=20 > + and the language specified by Language w= as returned >=20 > + in DriverName. >=20 > + @retval EFI_INVALID_PARAMETER Language is NULL. >=20 > + @retval EFI_INVALID_PARAMETER DriverName is NULL. >=20 > + @retval EFI_UNSUPPORTED The driver specified by This does not su= pport the >=20 > + language specified by Language. >=20 > + >=20 > +**/ >=20 > +EFI_STATUS >=20 > +EFIAPI >=20 > +VirtualKeyboardComponentNameGetDriverName ( >=20 > + IN EFI_COMPONENT_NAME_PROTOCOL *This, >=20 > + IN CHAR8 *Language, >=20 > + OUT CHAR16 **DriverName >=20 > + ) >=20 > +{ >=20 > + return LookupUnicodeString2 ( >=20 > + Language, >=20 > + This->SupportedLanguages, >=20 > + mVirtualKeyboardDriverNameTable, >=20 > + DriverName, >=20 > + (BOOLEAN)(This =3D=3D &gVirtualKeyboardComponentName) >=20 > + ); >=20 > +} >=20 > + >=20 > +/** >=20 > + Retrieves a Unicode string that is the user readable name of the contr= oller >=20 > + that is being managed by an EFI Driver. >=20 > + >=20 > + @param[in] This A pointer to the EFI_COMPONENT_NAME_PROT= OCOL instance. >=20 > + @param[in] ControllerHandle The handle of a controller that the driv= er specified by >=20 > + This is managing. This handle specifies= the controller >=20 > + whose name is to be returned. >=20 > + @param[in] ChildHandle The handle of the child controller to re= trieve the name >=20 > + of. This is an optional parameter that = may be NULL. It >=20 > + will be NULL for device drivers. It wil= l also be NULL >=20 > + for a bus drivers that wish to retrieve = the name of the >=20 > + bus controller. It will not be NULL for= a bus driver >=20 > + that wishes to retrieve the name of a ch= ild controller. >=20 > + @param[in] Language A pointer to a three character ISO 639-2= language >=20 > + identifier. This is the language of the= controller name >=20 > + that the caller is requesting, and it mu= st match one >=20 > + of the languages specified in SupportedL= anguages. The >=20 > + number of languages supported by a drive= r is up to the >=20 > + driver writer. >=20 > + @param[out] ControllerName A pointer to the Unicode string to retur= n. This Unicode >=20 > + string is the name of the controller spe= cified by >=20 > + ControllerHandle and ChildHandle in the = language specified >=20 > + by Language, from the point of view of t= he driver specified >=20 > + by This. >=20 > + >=20 > + @retval EFI_SUCCESS The Unicode string for the user-readable= name in the >=20 > + language specified by Language for the d= river >=20 > + specified by This was returned in Driver= Name. >=20 > + @retval EFI_INVALID_PARAMETER ControllerHandle is NULL. >=20 > + @retval EFI_INVALID_PARAMETER ChildHandle is not NULL and it is not a = valid EFI_HANDLE. >=20 > + @retval EFI_INVALID_PARAMETER Language is NULL. >=20 > + @retval EFI_INVALID_PARAMETER ControllerName is NULL. >=20 > + @retval EFI_UNSUPPORTED The driver specified by This is not curr= ently managing >=20 > + the controller specified by ControllerHa= ndle and >=20 > + ChildHandle. >=20 > + @retval EFI_UNSUPPORTED The driver specified by This does not su= pport the >=20 > + language specified by Language. >=20 > + >=20 > +**/ >=20 > +EFI_STATUS >=20 > +EFIAPI >=20 > +VirtualKeyboardComponentNameGetControllerName ( >=20 > + IN EFI_COMPONENT_NAME_PROTOCOL *This, >=20 > + IN EFI_HANDLE ControllerHandle, >=20 > + IN EFI_HANDLE ChildHandle, OPTIONAL >=20 > + IN CHAR8 *Language, >=20 > + OUT CHAR16 **ControllerName >=20 > + ) >=20 > +{ >=20 > + // >=20 > + // ChildHandle must be NULL for a Device Driver >=20 > + // >=20 > + if (ChildHandle !=3D NULL) { >=20 > + return EFI_UNSUPPORTED; >=20 > + } >=20 > + return LookupUnicodeString2 ( >=20 > + Language, >=20 > + This->SupportedLanguages, >=20 > + mVirtualKeyboardControllerNameStringTable, >=20 > + ControllerName, >=20 > + (BOOLEAN)(This =3D=3D &gVirtualKeyboardComponentName) >=20 > + ); >=20 > +} >=20 > diff --git a/Features/Intel/UserInterface/VirtualKeyboardFeaturePkg/Virtu= alKeyboardDxe/ComponentName.h > b/Features/Intel/UserInterface/VirtualKeyboardFeaturePkg/VirtualKeyboardD= xe/ComponentName.h > new file mode 100644 > index 0000000000..327ce9f9cb > --- /dev/null > +++ b/Features/Intel/UserInterface/VirtualKeyboardFeaturePkg/VirtualKeybo= ardDxe/ComponentName.h > @@ -0,0 +1,95 @@ > +/** @file >=20 > + Header file for Virtual Keyboard driver name. >=20 > + >=20 > + Copyright (c) 2012 - 2020, Intel Corporation. All rights reserved.
>=20 > + SPDX-License-Identifier: BSD-2-Clause-Patent >=20 > + >=20 > +**/ >=20 > + >=20 > +#ifndef _VIRTUAL_KEYBOARD_COMPONENT_NAME_H_ >=20 > +#define _VIRTUAL_KEYBOARD_COMPONENT_NAME_H_ >=20 > + >=20 > +#include >=20 > +#include >=20 > +#include >=20 > + >=20 > +/** >=20 > + Retrieves a Unicode string that is the user-readable name of the EFI D= river. >=20 > + >=20 > + @param[in] This A pointer to the EFI_COMPONENT_NAME_PROT= OCOL instance. >=20 > + @param[in] Language A pointer to a three-character ISO 639-2= language identifier. >=20 > + This is the language of the driver name = that that the caller >=20 > + is requesting, and it must match one of = the languages specified >=20 > + in SupportedLanguages. The number of la= nguages supported by a >=20 > + driver is up to the driver writer. >=20 > + @param[out] DriverName A pointer to the Unicode string to retur= n. This Unicode string >=20 > + is the name of the driver specified by T= his in the language >=20 > + specified by Language. >=20 > + >=20 > + @retval EFI_SUCCESS The Unicode string for the Driver specif= ied by This >=20 > + and the language specified by Language w= as returned >=20 > + in DriverName. >=20 > + @retval EFI_INVALID_PARAMETER Language is NULL. >=20 > + @retval EFI_INVALID_PARAMETER DriverName is NULL. >=20 > + @retval EFI_UNSUPPORTED The driver specified by This does not su= pport the >=20 > + language specified by Language. >=20 > + >=20 > +**/ >=20 > +EFI_STATUS >=20 > +EFIAPI >=20 > +VirtualKeyboardComponentNameGetDriverName ( >=20 > + IN EFI_COMPONENT_NAME_PROTOCOL *This, >=20 > + IN CHAR8 *Language, >=20 > + OUT CHAR16 **DriverName >=20 > + ); >=20 > + >=20 > +/** >=20 > + Retrieves a Unicode string that is the user readable name of the contr= oller >=20 > + that is being managed by an EFI Driver. >=20 > + >=20 > + @param[in] This A pointer to the EFI_COMPONENT_NAME_PROT= OCOL instance. >=20 > + @param[in] ControllerHandle The handle of a controller that the driv= er specified by >=20 > + This is managing. This handle specifies= the controller >=20 > + whose name is to be returned. >=20 > + @param[in] ChildHandle The handle of the child controller to re= trieve the name >=20 > + of. This is an optional parameter that = may be NULL. It >=20 > + will be NULL for device drivers. It wil= l also be NULL >=20 > + for a bus drivers that wish to retrieve = the name of the >=20 > + bus controller. It will not be NULL for= a bus driver >=20 > + that wishes to retrieve the name of a ch= ild controller. >=20 > + @param[in] Language A pointer to a three character ISO 639-2= language >=20 > + identifier. This is the language of the= controller name >=20 > + that the caller is requesting, and it mu= st match one >=20 > + of the languages specified in SupportedL= anguages. The >=20 > + number of languages supported by a drive= r is up to the >=20 > + driver writer. >=20 > + @param[out] ControllerName A pointer to the Unicode string to retur= n. This Unicode >=20 > + string is the name of the controller spe= cified by >=20 > + ControllerHandle and ChildHandle in the = language specified >=20 > + by Language, from the point of view of t= he driver specified >=20 > + by This. >=20 > + >=20 > + @retval EFI_SUCCESS The Unicode string for the user-readable= name in the >=20 > + language specified by Language for the d= river >=20 > + specified by This was returned in Driver= Name. >=20 > + @retval EFI_INVALID_PARAMETER ControllerHandle is NULL. >=20 > + @retval EFI_INVALID_PARAMETER ChildHandle is not NULL and it is not a = valid EFI_HANDLE. >=20 > + @retval EFI_INVALID_PARAMETER Language is NULL. >=20 > + @retval EFI_INVALID_PARAMETER ControllerName is NULL. >=20 > + @retval EFI_UNSUPPORTED The driver specified by This is not curr= ently managing >=20 > + the controller specified by ControllerHa= ndle and >=20 > + ChildHandle. >=20 > + @retval EFI_UNSUPPORTED The driver specified by This does not su= pport the >=20 > + language specified by Language. >=20 > + >=20 > +**/ >=20 > +EFI_STATUS >=20 > +EFIAPI >=20 > +VirtualKeyboardComponentNameGetControllerName ( >=20 > + IN EFI_COMPONENT_NAME_PROTOCOL *This, >=20 > + IN EFI_HANDLE ControllerHandle, >=20 > + IN EFI_HANDLE ChildHandle, OPTIONAL >=20 > + IN CHAR8 *Language, >=20 > + OUT CHAR16 **ControllerName >=20 > + ); >=20 > +#endif >=20 > diff --git a/Features/Intel/UserInterface/VirtualKeyboardFeaturePkg/Virtu= alKeyboardDxe/DigitKeyboard.bmp > b/Features/Intel/UserInterface/VirtualKeyboardFeaturePkg/VirtualKeyboardD= xe/DigitKeyboard.bmp > new file mode 100644 > index 0000000000000000000000000000000000000000..b64d62034817e7407120ee218= 1c935e07bef5a8c > GIT binary patch > literal 330454 > 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 ;+a > z#1aK^m2pb`+1j7~`Jd|)L_u%=3D& zlWGqB4guw|;9%5IYR;&vAR^*yTHS>RIt|}RScl4Pi?P6BJa!ja45d8WeOzWak$PGl > zl!6sT!Lv52au?MoBsL7HNNi^n)s~vmT?LaR@A#o?!AS0+qNZJGRkm|g71XJzA!wBC > zgiKT#5(xR4gLepYCP8sf!GZC(=3D0L#?v}Yb&Le2Tz-~HX^&!5wB0GOAsz*E$mE)J`p > zn&u8s`#xLiMzMvMkz0|@5Ua*JE@dol(OHMeZi_9mmt$i*F;^DVaQ6|aox;g24>~nA > zN5QKax1C*7qmWovS^!nKiptg;jIst>vhs9y71D$$D6dA90cPiFA!omZp;5LIGP#QF > z@M^c_WQ zyP6wpBtTv_Z);SHCy%O|gjxXNez$hp%y1?BA@F1^5W1*_AaSGxczCIbDpPa#g|~8{ > z@^rb1mL{M=3Dxr#7@3Ip9@(G2Et%J?S!v(G-$tIC4G?{jc4*!9_(0~0hapymL*-UiSY > zFBF#69KMcV-!qVL{dy_M;!`+V<-Y5e8(Ts(vP$JLiaG1*pRGve)Gbu2r%Mi8hsx5G > zoG7Ul zvZGY5V@VAHpREao6EdhUq@*I4%PH&aFP2RLP{F}dsq(jUh|1ZiHe2ry*hgp8fn_I6 > zskWC21ADN*HRl{6aBr{u@V)-+<>WbsY8Y#uq_MoHn%PT!@h* zEN4+q3)S*@mW^14O0Xd;o3E!G zykEBAMpH=3D~Hgex<-l0^?OmOHEj?NUS^@Rh2u-k`@So-;G#2l!>Zp%5@H` > zInMH~O)PMI&54mEYfkl?1IxCc&6*Qa-MMOSw&EOL-Gy#jbS7JPImTmmp@ZR?)eN){ > zOGO>e9B}jJ=3DE|eez@_jwuLYDL3e$BxXl-tnx1V!t8kX#8j&L%|R?j)op&(5( zxyn~U&1mORrxRQ;3{Hkb<%VBV6AMh#9Qf)`i*~USH>;6V4q2KNx`f0@qJ^q!c7=3DlC > zy>)9PHd?5p0AU4yU`Wgo=3DgpuR>ppu2*}8+zpb~FO;W?LqK$(h#E~>y6t1rcnaJ7pH > zI!TH&S5iNqE`tiwt)`_MDDZ(mROQ&K>A?bL&AAPLd z$?U>KQ&*LdQ2C%8SHTkQEL(Y<*fOYwxKBjkhTA@Xw-iavppx=3DBcot7^XRKKubWv43 > zvZeDc|MD-(FC{Fb3@Yd(DYBMV46(zzTv2%oIc}_-y(JTs8+c7kEbu~VPRm8z{$yk& > z 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 z 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 z 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 >=20 > literal 0 > HcmV?d00001 >=20 > diff --git a/Features/Intel/UserInterface/VirtualKeyboardFeaturePkg/Virtu= alKeyboardDxe/FullIcon.bmp > b/Features/Intel/UserInterface/VirtualKeyboardFeaturePkg/VirtualKeyboardD= xe/FullIcon.bmp > new file mode 100644 > index 0000000000000000000000000000000000000000..b940505c8bc74ad6550bc3226= 29d7975c1e1c1fc > 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$K ztZVAFD3jL*2L~Hl`%J6LZf@c|8xF%GjEsyJ{RdKAU2P;=3D(N9lLXQANWU{&7M)&|ib > zoyp0`=3Dg*%vw)L&AuN^pWKyM*7F)?9hXD7tQ#s+ft?p+nwqR!Q;S6L`LJY4m6b#+0u > zZ{MzDW@ct|bX06Ubm)+BvDx0 z>C>^RJ%0hvQTJfsOs z>FMO;BsL#Bc+kVc!` zz4!0mk1<@|ym`YJtZUwgb&HFO@87>)T3UMd?j1wg!omWC#w~`ctE&(Mwy2?ed3l+I > z(9eooA!}=3DE5V1`y85$b0#P}@x{Fk}?ZEkdDXJ>gplgWhtz!<)L`xf%y!v{{T5P2hW > zb93B zPVC;jd#|}UJ39vk2J&_W1_pNR+U4Tnf+xqv$D_QmvU10c9Y_%gFI~C>NlHq>@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(nRhmN z)OBN0;AK(Lu!kbUjv+t@(kW3 zM@RGcw{PE8g3Cc-V`G(wZxHI0;2Zd}4kh?Mc ztU2ZM>C+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=3Ds zflIXS?CeAsLNr5wCQ2ZUjg1V+&N%bq$BzjP{r&wA5{IZo6%hu)p=3DfSy7PXRb5XKA$ > zoHY0B*)!^AlWB#7qOQ(FtkNMJh%w5gq@+M{b8}UOyAX1R5<(?JhoWR^YD&q;lP3|V > zsi{#S-zoUH5=3D{L>3EwH-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=20 > literal 0 > HcmV?d00001 >=20 > diff --git a/Features/Intel/UserInterface/VirtualKeyboardFeaturePkg/Virtu= alKeyboardDxe/Keyboard.c > b/Features/Intel/UserInterface/VirtualKeyboardFeaturePkg/VirtualKeyboardD= xe/Keyboard.c > new file mode 100644 > index 0000000000..a2c9a3bfc4 > --- /dev/null > +++ b/Features/Intel/UserInterface/VirtualKeyboardFeaturePkg/VirtualKeybo= ardDxe/Keyboard.c > @@ -0,0 +1,1400 @@ > +/** @file >=20 > + Virtural Keyboard Control Engine >=20 > + >=20 > + Copyright (c) 2012 - 2020, Intel Corporation. All rights reserved.
    >=20 > + SPDX-License-Identifier: BSD-2-Clause-Patent >=20 > + >=20 > +**/ >=20 > + >=20 > +#include "VirtualKeyboard.h" >=20 > + >=20 > +/** >=20 > + Notify all keyboards pressed specific key need to hidden Virtual >=20 > + Keyboard. >=20 > + >=20 > + @param[in] KeyData Keyboard pressed specific key data >=20 > + >=20 > + @retval EFI_SUCCESS Success for the function. >=20 > + @retval EFI_NOT_FOUND Not found Virtual Keyboard protocol. >=20 > + >=20 > +**/ >=20 > +EFI_STATUS >=20 > +EFIAPI >=20 > +VkNotifyKeyCallback ( >=20 > + IN EFI_KEY_DATA *KeyData >=20 > + ) >=20 > +{ >=20 > + EFI_STATUS Status; >=20 > + VK_CONTEXT *VkContext; >=20 > + UINTN MaxColumn; >=20 > + UINTN MaxRow; >=20 > + UINT32 HorizontalPixel; >=20 > + UINT32 VerticalPixel; >=20 > + >=20 > + DEBUG ((DEBUG_VK_ROUTINE_ENTRY_EXIT, "VkNotifyKeyCallback Start\n")); >=20 > + >=20 > + Status =3D gBS->LocateProtocol (&gEfiCallerIdGuid, NULL, (VOID **) &Vk= Context); >=20 > + if (EFI_ERROR (Status)) { >=20 > + return Status; >=20 > + } >=20 > + >=20 > + gST->ConOut->QueryMode ( >=20 > + gST->ConOut, >=20 > + gST->ConOut->Mode->Mode, >=20 > + &MaxColumn, >=20 > + &MaxRow >=20 > + ); >=20 > + HorizontalPixel =3D VkContext->GraphicsOutput->Mode->Info->HorizontalR= esolution; >=20 > + VerticalPixel =3D VkContext->GraphicsOutput->Mode->Info->VerticalRes= olution; >=20 > + >=20 > + // >=20 > + // CursorRow and CursorColumn are started from 0, so need to add 2 not= 1. >=20 > + // >=20 > + if (((UINTN)(gST->ConOut->Mode->CursorColumn * EFI_GLYPH_WIDTH) < VkCo= ntext->SimIconBackWidth) && >=20 > + ((UINTN)((gST->ConOut->Mode->CursorRow + 2) * EFI_GLYPH_HEIGHT) > = (VerticalPixel - VkContext- > >SimIconBackHeight))) { >=20 > + SaveVkIconBackgroundBltBuffer (VkContext, VkDisplayAttributeSimpleBo= ttom); >=20 > + } else if (((UINTN)((gST->ConOut->Mode->CursorColumn + 2) * EFI_GLYPH_= WIDTH) > (HorizontalPixel - VkContext- > >FullIconBackWidth)) && >=20 > + ((UINTN)((gST->ConOut->Mode->CursorRow + 2) * EFI_GLYPH_HEI= GHT) > (VerticalPixel - VkContext- > >FullIconBackHeight))){ >=20 > + SaveVkIconBackgroundBltBuffer (VkContext, VkDisplayAttributeFullBott= om); >=20 > + } >=20 > + >=20 > + // >=20 > + // Hide icon/keyboard to prevent screen scroll up. >=20 > + // >=20 > + if ((KeyData->Key.UnicodeChar =3D=3D CHAR_CARRIAGE_RETURN) = || >=20 > + (KeyData->Key.ScanCode =3D=3D SCAN_ESC) = || >=20 > + ((gST->ConOut->Mode->CursorColumn >=3D (INT32) (MaxColumn - 2)) && >=20 > + (gST->ConOut->Mode->CursorRow =3D=3D (INT32) (MaxRow - 1)))) { >=20 > + HideVkBody (VkContext); >=20 > + HideVkIcon (VkContext); >=20 > + VkContext->IconReDrawCheck =3D 0; >=20 > + } >=20 > + >=20 > + DEBUG ((DEBUG_VK_ROUTINE_ENTRY_EXIT, "VkNotifyKeyCallback End\n")); >=20 > + return EFI_SUCCESS; >=20 > +} >=20 > + >=20 > +/** >=20 > + Judge whether is a registed key. >=20 > + >=20 > + @param[in] RegsiteredData A pointer to a buffer that is filled in wi= th the keystroke >=20 > + state data for the key that was registered= . >=20 > + @param[in] InputData A pointer to a buffer that is filled in wi= th the keystroke >=20 > + state data for the key that was pressed. >=20 > + >=20 > + @retval TRUE Key be pressed matches a registered key. >=20 > + @retval FLASE Match failed. >=20 > + >=20 > +**/ >=20 > +BOOLEAN >=20 > +IsKeyRegistered ( >=20 > + IN EFI_KEY_DATA *RegsiteredData, >=20 > + IN EFI_KEY_DATA *InputData >=20 > + ) >=20 > +{ >=20 > + ASSERT (RegsiteredData !=3D NULL && InputData !=3D NULL); >=20 > + >=20 > + if ((RegsiteredData->Key.ScanCode !=3D InputData->Key.ScanCode) || >=20 > + (RegsiteredData->Key.UnicodeChar !=3D InputData->Key.UnicodeChar))= { >=20 > + return FALSE; >=20 > + } >=20 > + >=20 > + // >=20 > + // Assume KeyShiftState/KeyToggleState =3D 0 in Registered key data me= ans these state could be ignored. >=20 > + // >=20 > + if (RegsiteredData->KeyState.KeyShiftState !=3D 0 && >=20 > + RegsiteredData->KeyState.KeyShiftState !=3D InputData->KeyState.Ke= yShiftState) { >=20 > + return FALSE; >=20 > + } >=20 > + if (RegsiteredData->KeyState.KeyToggleState !=3D 0 && >=20 > + RegsiteredData->KeyState.KeyToggleState !=3D InputData->KeyState.K= eyToggleState) { >=20 > + return FALSE; >=20 > + } >=20 > + >=20 > + return TRUE; >=20 > +} >=20 > + >=20 > +/** >=20 > + Pop the key from the keybuffer. >=20 > + >=20 > + @param[in, out] VkContext Address of an VK_CONTEXT structure. >=20 > + @param[out] KeyData The EFI stand key infomation when code ge= t the key will put >=20 > + correct mapping key. >=20 > + >=20 > + @retval EFI_SUCCESS The keystroke information was returned. >=20 > + @retval EFI_NOT_READY The keystroke data is empty. >=20 > + >=20 > +**/ >=20 > +EFI_STATUS >=20 > +VkPopTheKey ( >=20 > + IN OUT VK_CONTEXT *VkContext, >=20 > + OUT EFI_KEY_DATA *KeyData OPTIONAL >=20 > + ) >=20 > +{ >=20 > + EFI_STATUS Status; >=20 > + UINT8 IndexSt; >=20 > + UINT8 IndexEd; >=20 > + >=20 > + DEBUG ((DEBUG_VK_ROUTINE_ENTRY_EXIT, "VkPopTheKey Start\n")); >=20 > + // >=20 > + // KeyBuffer >=20 > + // [ 0 ] >=20 > + // [ 1 ]<-*IndexSt/IndexEd >=20 > + // [ 2 ] >=20 > + // [ ... ] >=20 > + // [MAX_KEY_BUF_SIZE - 1] >=20 > + // >=20 > + Status =3D EFI_SUCCESS; >=20 > + IndexSt =3D VkContext->KeyStartIndex; >=20 > + IndexEd =3D VkContext->KeyEndIndex; >=20 > + >=20 > + if (IndexEd =3D=3D IndexSt) { >=20 > + DEBUG ((DEBUG_VK_KEYS, "ERROR - Keyboard buffer is empty.\n")); >=20 > + Status =3D EFI_NOT_READY; >=20 > + goto Error; >=20 > + } >=20 > + >=20 > + DEBUG ((DEBUG_VK_KEYS | DEBUG_INFO, "VkPopTheKey Unicode: %08x\n", = VkContext- > >Keybuffer[IndexSt].Key.UnicodeChar)); >=20 > + DEBUG ((DEBUG_VK_KEYS | DEBUG_INFO, "VkPopTheKey ScanCode: %08x\n", = VkContext- > >Keybuffer[IndexSt].Key.ScanCode)); >=20 > + DEBUG ((DEBUG_VK_KEYS | DEBUG_INFO, "VkPopTheKey ShiftState: %08x\n", = VkContext- > >Keybuffer[IndexSt].KeyState.KeyShiftState)); >=20 > + DEBUG ((DEBUG_VK_KEYS | DEBUG_INFO, "VkPopTheKey ToggleState:%08x\n", = VkContext- > >Keybuffer[IndexSt].KeyState.KeyToggleState)); >=20 > + >=20 > + if (KeyData !=3D NULL) { >=20 > + *KeyData =3D VkContext->Keybuffer[IndexSt]; >=20 > + } >=20 > + VkContext->KeyStartIndex =3D ++IndexSt % MAX_KEY_BUF_SIZE; >=20 > + >=20 > + DEBUG ((DEBUG_VK_ROUTINE_ENTRY_EXIT, "VkPopTheKey Success, Status: %r\= n", Status)); >=20 > + goto End; >=20 > + >=20 > +Error: >=20 > + DEBUG ((DEBUG_VK_ROUTINE_ENTRY_EXIT, "VkPopTheKey Failed, Status: %r\n= ", Status)); >=20 > + >=20 > +End: >=20 > + DEBUG ((DEBUG_VK_ROUTINE_ENTRY_EXIT, "VkPopTheKey End\n")); >=20 > + return Status; >=20 > +} >=20 > + >=20 > +/** >=20 > + Push the event mapping key index to the input key buffer. >=20 > + >=20 > + @param[in, out] VkContext Address of an VK_CONTEXT structure. >=20 > + @param[in] Unicode The font's unicode number. >=20 > + >=20 > + @retval EFI_SUCCESS The maping key index did put the key buff= er. >=20 > + >=20 > +**/ >=20 > +EFI_STATUS >=20 > +VkPushTheKey ( >=20 > + IN OUT VK_CONTEXT *VkContext, >=20 > + IN UINT16 Unicode >=20 > + ) >=20 > +{ >=20 > + UINT8 IndexSt; >=20 > + UINT8 IndexEd; >=20 > + EFI_KEY_DATA KeyData; >=20 > + EFI_STATUS Status; >=20 > + LIST_ENTRY *Link; >=20 > + VK_NOTIFY *CurrentNotify; >=20 > + >=20 > + DEBUG ((DEBUG_VK_ROUTINE_ENTRY_EXIT, "VkPushTheKey Start\n")); >=20 > + // >=20 > + // KeyBuffer >=20 > + // [ 0 ] >=20 > + // [ 1 ]<-IndexSt/*IndexEd >=20 > + // [ 2 ] >=20 > + // [ ... ] >=20 > + // [MAX_KEY_BUF_SIZE - 1] >=20 > + // >=20 > + IndexSt =3D VkContext->KeyStartIndex; >=20 > + IndexEd =3D VkContext->KeyEndIndex; >=20 > + >=20 > + Status =3D EFI_SUCCESS; >=20 > + >=20 > + // >=20 > + // Check Keyboard Buffer if is full that will pop the first key >=20 > + // >=20 > + if (VkContext->IsSupportPartialKey && >=20 > + ((VkContext->KeyEndIndex + 2) % MAX_KEY_BUF_SIZE) =3D=3D IndexSt) { >=20 > + VkPopTheKey (VkContext, NULL); >=20 > + } >=20 > + >=20 > + if (((VkContext->KeyEndIndex + 1) % MAX_KEY_BUF_SIZE) =3D=3D IndexSt) = { >=20 > + VkPopTheKey (VkContext, NULL); >=20 > + } >=20 > + >=20 > + KeyData.Key.ScanCode =3D SCAN_NULL; >=20 > + KeyData.Key.UnicodeChar =3D CHAR_NULL; >=20 > + KeyData.KeyState.KeyShiftState =3D EFI_SHIFT_STATE_VALID; >=20 > + KeyData.KeyState.KeyToggleState =3D VkContext->KeyToggleState; >=20 > + KeyData.KeyState.KeyToggleState &=3D ~EFI_CAPS_LOCK_ACTIVE; >=20 > + KeyData.KeyState.KeyToggleState |=3D VkContext->IsCapsLockFlag ? EFI_C= APS_LOCK_ACTIVE : 0; >=20 > + >=20 > + switch (Unicode) { >=20 > + case VkKeyShift: >=20 > + VkContext->IsShiftKeyFlag =3D !VkContext->IsShiftKeyFlag; >=20 > + if (VkContext->PageNumber >=3D VkPage2 && VkContext->PageNumber <=3D= VkPage3) { >=20 > + VkContext->IsShiftKeyFlag ? VkContext->PageNumber++ : VkContext->P= ageNumber--; >=20 > + } >=20 > + VkContext->IsRedrawUpdateUI =3D TRUE; >=20 > + break; >=20 > + >=20 > + case VkKeyTwoPage: >=20 > + switch (VkContext->PageNumber) { >=20 > + case VkPage0: >=20 > + case VkPage1: >=20 > + VkContext->IsShiftKeyFlag =3D FALSE; >=20 > + VkContext->PageNumber =3D VkContext->IsShiftKeyFlag ? VkPage3 = : VkPage2; >=20 > + break; >=20 > + >=20 > + case VkPage2: >=20 > + case VkPage3: >=20 > + VkContext->IsShiftKeyFlag =3D FALSE; >=20 > + VkContext->PageNumber =3D VkContext->IsCapsLockFlag ? VkPage1 = : VkPage0; >=20 > + break; >=20 > + >=20 > + default: >=20 > + break; >=20 > + } >=20 > + VkContext->IsRedrawUpdateUI =3D TRUE; >=20 > + break; >=20 > + >=20 > + case VkKeyCapslock: >=20 > + VkContext->IsCapsLockFlag =3D !VkContext->IsCapsLockFlag; >=20 > + if (VkContext->PageNumber >=3D VkPage0 && VkContext->PageNumber <=3D= VkPage1) { >=20 > + VkContext->IsCapsLockFlag ? VkContext->PageNumber++ : VkContext->P= ageNumber--; >=20 > + } >=20 > + KeyData.KeyState.KeyToggleState &=3D ~EFI_CAPS_LOCK_ACTIVE; >=20 > + KeyData.KeyState.KeyToggleState |=3D VkContext->IsCapsLockFlag ? EFI= _CAPS_LOCK_ACTIVE : 0; >=20 > + VkContext->IsRedrawUpdateUI =3D TRUE; >=20 > + break; >=20 > + >=20 > + default: >=20 > + if ((Unicode & VkKeyScanMask) !=3D 0) { >=20 > + KeyData.Key.ScanCode =3D Unicode & ~VkKeyScanMask; >=20 > + } else { >=20 > + KeyData.Key.UnicodeChar =3D Unicode; >=20 > + } >=20 > + break; >=20 > + } >=20 > + >=20 > + if (KeyData.Key.ScanCode =3D=3D SCAN_NULL && KeyData.Key.UnicodeChar = =3D=3D CHAR_NULL) { >=20 > + if (!VkContext->IsSupportPartialKey) { >=20 > + goto End; >=20 > + } >=20 > + } >=20 > + >=20 > + for (Link =3D GetFirstNode (&VkContext->NotifyList); !IsNull (&VkConte= xt->NotifyList, Link); Link =3D GetNextNode > (&VkContext->NotifyList, Link)) { >=20 > + CurrentNotify =3D CR (Link, VK_NOTIFY, NotifyEntry, VK_NOTIFY_SIGNAT= URE); >=20 > + // >=20 > + // The key notification function needs to run at TPL_CALLBACK >=20 > + // while current TPL is TPL_NOTIFY. It will be invoked in >=20 > + // VkKeyNotifyProcessHandler() which runs at TPL_CALLBACK. >=20 > + // >=20 > + if (IsKeyRegistered (&CurrentNotify->KeyData, &KeyData)) { >=20 > + VkContext->Keybuffer[IndexEd] =3D KeyData; >=20 > + VkContext->KeyEndIndex =3D ++IndexEd % MAX_KEY_BUF_SIZE; >=20 > + gBS->SignalEvent (VkContext->KeyNotifyProcessEvent); >=20 > + } >=20 > + } >=20 > + VkContext->Keybuffer[IndexEd] =3D KeyData; >=20 > + VkContext->KeyEndIndex =3D ++IndexEd % MAX_KEY_BUF_SIZE; >=20 > + >=20 > + DEBUG ((DEBUG_VK_TIMER_ENTRY_EXIT, "VkPushTheKey Success, Status: %r\n= ", Status)); >=20 > + goto End; >=20 > + >=20 > +End: >=20 > + DEBUG ((DEBUG_VK_TIMER_ENTRY_EXIT, "VkPushTheKey End\n")); >=20 > + return Status; >=20 > +} >=20 > + >=20 > +/** >=20 > + Process key notify. >=20 > + >=20 > + @param[in] Event Indicates the event that invoke this = function. >=20 > + @param[in] Context Indicates the calling context. >=20 > + >=20 > +**/ >=20 > +VOID >=20 > +EFIAPI >=20 > +VkKeyNotifyProcessHandler ( >=20 > + IN EFI_EVENT Event, >=20 > + IN VOID *Context >=20 > + ) >=20 > +{ >=20 > + EFI_STATUS Status; >=20 > + VK_CONTEXT *VkContext; >=20 > + EFI_KEY_DATA KeyData; >=20 > + LIST_ENTRY *Link; >=20 > + LIST_ENTRY *NotifyList; >=20 > + VK_NOTIFY *CurrentNotify; >=20 > + EFI_TPL OldTpl; >=20 > + >=20 > + DEBUG ((DEBUG_VK_ROUTINE_ENTRY_EXIT, "VkKeyNotifyProcessHandler Start\= n")); >=20 > + VkContext =3D (VK_CONTEXT *) Context; >=20 > + OldTpl =3D gBS->RaiseTPL (TPL_NOTIFY); >=20 > + >=20 > + // >=20 > + // Invoke notification functions. >=20 > + // >=20 > + NotifyList =3D &VkContext->NotifyList; >=20 > + Status =3D VkPopTheKey (VkContext, &KeyData); >=20 > + if (EFI_ERROR (Status)) { >=20 > + goto Error; >=20 > + } >=20 > + >=20 > + for (Link =3D GetFirstNode (NotifyList); !IsNull (NotifyList, Link); L= ink =3D GetNextNode (NotifyList, Link)) { >=20 > + CurrentNotify =3D CR (Link, VK_NOTIFY, NotifyEntry, VK_NOTIFY_SIGNAT= URE); >=20 > + if (IsKeyRegistered (&CurrentNotify->KeyData, &KeyData)) { >=20 > + CurrentNotify->KeyNotificationFn (&KeyData); >=20 > + } >=20 > + } >=20 > + >=20 > + DEBUG ((DEBUG_VK_ROUTINE_ENTRY_EXIT, "VkKeyNotifyProcessHandler Succes= s, Status: %r\n", Status)); >=20 > + goto End; >=20 > + >=20 > +Error: >=20 > + DEBUG ((DEBUG_VK_ROUTINE_ENTRY_EXIT, "VkKeyNotifyProcessHandler Failed= , Status: %r\n", Status)); >=20 > + >=20 > +End: >=20 > + gBS->RestoreTPL (OldTpl); >=20 > + DEBUG ((DEBUG_VK_ROUTINE_ENTRY_EXIT, "VkKeyNotifyProcessHandler End\n"= )); >=20 > +} >=20 > + >=20 > +/** >=20 > + Push the event mapping key index to the input key buffer. >=20 > + >=20 > + @param[in] VkContext Address of an VK_CONTEXT structure. >=20 > + @param[out] KeyItem Key Item. >=20 > + @param[out] Index Index of Key Item. >=20 > + @param[in] TouchX X position of finger touch. >=20 > + @param[in] TouchY Y position of finger touch. >=20 > + >=20 > + @retval TRUE Touch on Virtual Keyboard. >=20 > + @retval FALSE Not touch on Virtual Keyboard. >=20 > + >=20 > +**/ >=20 > +BOOLEAN >=20 > +IsTouchVk ( >=20 > + IN VK_CONTEXT *VkContext, >=20 > + OUT VK_STRUCT *KeyItem, >=20 > + OUT UINT32 *Index, >=20 > + IN UINT32 TouchX, >=20 > + IN UINT32 TouchY >=20 > + ) >=20 > +{ >=20 > + for (*Index =3D 0; *Index < VkContext->NumOfKeysInfo; (*Index)++) { >=20 > + if (VkContext->KeyboardBodyPtr[*Index].DisStartX < TouchX && >=20 > + VkContext->KeyboardBodyPtr[*Index].DisEndX > TouchX && >=20 > + VkContext->KeyboardBodyPtr[*Index].DisStartY < TouchY && >=20 > + VkContext->KeyboardBodyPtr[*Index].DisEndY > TouchY) { >=20 > + break; >=20 > + } >=20 > + } >=20 > + if (*Index !=3D VkContext->NumOfKeysInfo) { >=20 > + *KeyItem =3D VkContext->KeyboardBodyPtr[*Index]; >=20 > + } >=20 > + >=20 > + return *Index !=3D VkContext->NumOfKeysInfo; >=20 > +} >=20 > + >=20 > +VOID >=20 > +EFIAPI >=20 > +VkReadyToBootCallBack ( >=20 > + IN EFI_EVENT Event, >=20 > + IN VOID *Context >=20 > + ) >=20 > +{ >=20 > + VK_CONTEXT *VkContext; >=20 > + VkContext =3D (VK_CONTEXT *)Context; >=20 > + >=20 > + HideVkBody (VkContext); >=20 > + VkContext->TargetKeyboardDisplay =3D VkDisplayAttributeNone; >=20 > +} >=20 > + >=20 > +/** >=20 > + Timer event >=20 > + >=20 > + This routine is called at TPL_VK_SYNC. >=20 > + >=20 > + This routine polls for touch panel input. >=20 > + >=20 > + @param[in] Event Event whose notification function is being invoked= . >=20 > + @param[in] Context Pointer to the notification function's context, >=20 > + which is implementation-dependent. Context corresp= onds >=20 > + to NotifyContext in CreateEventEx(). >=20 > + >=20 > +**/ >=20 > +VOID >=20 > +EFIAPI >=20 > +VkTimer ( >=20 > + IN EFI_EVENT Event, >=20 > + IN VOID *Context >=20 > + ) >=20 > +{ >=20 > + EFI_ABSOLUTE_POINTER_PROTOCOL *AbsolutePointer; >=20 > + EFI_ABSOLUTE_POINTER_STATE Point; >=20 > + EFI_STATUS Status; >=20 > + UINT32 TouchX; >=20 > + UINT32 TouchY; >=20 > + VK_CONTEXT *VkContext; >=20 > + UINT32 Index; >=20 > + VK_STRUCT KeyItem; >=20 > + UINT32 Font; >=20 > + >=20 > + DEBUG ((DEBUG_VK_TIMER_ENTRY_EXIT, "VkTimer Start\n")); >=20 > + VkContext =3D (VK_CONTEXT *)Context; >=20 > + >=20 > + // >=20 > + // Update keyboard UI layout >=20 > + // >=20 > + CheckIconCleared (VkContext); >=20 > + CheckScreenCleared (VkContext); >=20 > + CheckBackgroundChanged (VkContext); >=20 > + if (VkContext->IsRedrawUpdateUI) { >=20 > + HideVkBody (VkContext); >=20 > + DrawKeyboardLayout (VkContext); >=20 > + VkContext->IsRedrawUpdateUI =3D FALSE; >=20 > + } >=20 > + >=20 > + // >=20 > + // Error handle for invalid information >=20 > + // >=20 > + AbsolutePointer =3D VkContext->AbsolutePointer; >=20 > + Status =3D gBS->CheckEvent (AbsolutePointer->WaitForInput); >=20 > + if (EFI_ERROR (Status)) { >=20 > + DEBUG ((DEBUG_VK_TIMER_ENTRY_EXIT | DEBUG_VK_POINTS, "ERROR - VkCont= ext->AbsolutePointer->WaitForInput- > >CheckEvent failed! Status: %r\n", Status)); >=20 > + goto Error; >=20 > + } >=20 > + >=20 > + Status =3D AbsolutePointer->GetState (AbsolutePointer, &Point); >=20 > + if (EFI_ERROR (Status)) { >=20 > + DEBUG ((DEBUG_VK_TIMER_ENTRY_EXIT | DEBUG_VK_POINTS, "ERROR - GetSta= te failed, Status: %r\n", Status)); >=20 > + goto Error; >=20 > + } >=20 > + >=20 > + if (VkContext->AbsolutePointer->Mode->AbsoluteMaxX <=3D Point.CurrentX= ) { >=20 > + DEBUG (( >=20 > + DEBUG_VK_TIMER_ENTRY_EXIT | DEBUG_VK_POINTS, >=20 > + "ERROR - X value exceeds maximum: X: 0x%016Lx, MaxX: 0x%016Lx\n", >=20 > + Point.CurrentX, >=20 > + VkContext->AbsolutePointer->Mode->AbsoluteMaxX >=20 > + )); >=20 > + Status =3D EFI_PROTOCOL_ERROR; >=20 > + goto Error; >=20 > + } >=20 > + if (VkContext->AbsolutePointer->Mode->AbsoluteMaxY <=3D Point.CurrentY= ) { >=20 > + DEBUG (( >=20 > + DEBUG_VK_TIMER_ENTRY_EXIT | DEBUG_VK_POINTS, >=20 > + "ERROR - Y value exceeds maximum: Y: 0x%016Lx, MaxY: 0x%016Lx\n", >=20 > + Point.CurrentY, >=20 > + VkContext->AbsolutePointer->Mode->AbsoluteMaxY >=20 > + )); >=20 > + Status =3D EFI_PROTOCOL_ERROR; >=20 > + goto Error; >=20 > + } >=20 > + >=20 > + // >=20 > + // Update the touch active status >=20 > + // >=20 > + VkContext->TouchActive =3D ((Point.ActiveButtons & EFI_ABSP_TouchActiv= e) !=3D 0) ? TRUE : FALSE; >=20 > + if (!VkContext->TouchActive) { >=20 > + VkContext->KeyPressed =3D FALSE; >=20 > + } >=20 > + ConvertCoordinate (VkContext, Point, &TouchX, &TouchY); >=20 > + >=20 > + if (!VkContext->KeyPressed && >=20 > + VkContext->TouchActive && >=20 > + IsTouchVk (VkContext, &KeyItem, &Index, TouchX, TouchY)) { >=20 > + VkGetMappingFont (VkContext, KeyItem, &Font); >=20 > + DEBUG ((DEBUG_VK_TIMER_ENTRY_EXIT | DEBUG_INFO, "V= K Touch event is trigger!\n" )); >=20 > + DEBUG ((DEBUG_VK_TIMER_ENTRY_EXIT | DEBUG_INFO | DEBUG_VK_POINTS, "T= ouchActive: 0x%04x \n", > VkContext->TouchActive)); >=20 > + DEBUG ((DEBUG_VK_TIMER_ENTRY_EXIT | DEBUG_INFO | DEBUG_VK_POINTS, "C= urrentKeyboardDisplay: 0x%04x \n", > VkContext->CurrentKeyboardDisplay)); >=20 > + DEBUG ((DEBUG_VK_TIMER_ENTRY_EXIT | DEBUG_INFO | DEBUG_VK_POINTS, "X= : 0x%016Lx\n", > Point.CurrentX)); >=20 > + DEBUG ((DEBUG_VK_TIMER_ENTRY_EXIT | DEBUG_INFO | DEBUG_VK_POINTS, "Y= : 0x%016Lx\n", > Point.CurrentY)); >=20 > + DEBUG ((DEBUG_VK_TIMER_ENTRY_EXIT | DEBUG_INFO | DEBUG_VK_POINTS, "Z= : 0x%016Lx\n", > Point.CurrentZ)); >=20 > + DEBUG ((DEBUG_VK_TIMER_ENTRY_EXIT | DEBUG_INFO | DEBUG_VK_POINTS, "B= uttons: 0x%08x \n", > Point.ActiveButtons)); >=20 > + DEBUG ((DEBUG_VK_TIMER_ENTRY_EXIT | DEBUG_INFO | DEBUG_VK_POINTS, "M= apKey Index: 0x%04x \n", > Index)); >=20 > + DEBUG ((DEBUG_VK_TIMER_ENTRY_EXIT | DEBUG_INFO | DEBUG_VK_POINTS, "K= ey Unicode: 0x%08x \n", Font)); >=20 > + >=20 > + switch (Font) { >=20 > + // >=20 > + // Touch the small keyboard icon, show/hide the keyboard. >=20 > + // >=20 > + case VkKeyTypeMaximum: >=20 > + KeyboardLayoutHandler (VkContext, Index); >=20 > + break; >=20 > + >=20 > + // >=20 > + // Touch the key raw. >=20 > + // >=20 > + default: >=20 > + if (VkContext->CurrentKeyboardDisplay =3D=3D VkDisplayAttributeNon= e) { >=20 > + break; >=20 > + } >=20 > + VkPushTheKey (VkContext, (UINT16) Font); >=20 > + } >=20 > + VkContext->KeyPressed =3D TRUE; >=20 > + } >=20 > + >=20 > + DEBUG ((DEBUG_VK_TIMER_ENTRY_EXIT, "VkTimer Success, Status: %r\n", St= atus)); >=20 > + goto End; >=20 > + >=20 > +Error: >=20 > + DEBUG ((DEBUG_VK_TIMER_ENTRY_EXIT, "VkTimer Failed, Status: %r\n", Sta= tus)); >=20 > + >=20 > +End: >=20 > + DEBUG ((DEBUG_VK_TIMER_ENTRY_EXIT, "VkTimer End\n")); >=20 > + return; >=20 > +} >=20 > + >=20 > +/** >=20 > + VkTouchWaitForKey - SignalEvent when the keybuffer has keys. >=20 > + >=20 > + @param[in] Event Event whose notification function is being invoked= . >=20 > + @param[in] Context Pointer to the notification function's context, >=20 > + which is implementation-dependent. Context corres= ponds >=20 > + to NotifyContext in CreateEventEx(). >=20 > + >=20 > +**/ >=20 > +VOID >=20 > +EFIAPI >=20 > +VkTouchWaitForKey ( >=20 > + IN EFI_EVENT Event, >=20 > + IN VOID *Context >=20 > + ) >=20 > +{ >=20 > + VK_CONTEXT *VkContext; >=20 > + >=20 > + DEBUG ((DEBUG_VK_ROUTINE_ENTRY_EXIT, "VkTouchWaitForKey Start\n")); >=20 > + VkContext =3D (VK_CONTEXT*) Context; >=20 > + >=20 > + if (VkContext->KeyStartIndex !=3D VkContext->KeyEndIndex) { >=20 > + DEBUG ((DEBUG_VK_KEYS, "Signal VkTouchWaitForKey\n")); >=20 > + gBS->SignalEvent (Event); >=20 > + } >=20 > + >=20 > + DEBUG ((DEBUG_VK_ROUTINE_ENTRY_EXIT, "VkTouchWaitForKey End\n")); >=20 > +} >=20 > + >=20 > +/** >=20 > + Get image file data from BIOS image through specific ImageId. >=20 > + >=20 > + @param[in] VkContext Address of an VK_CONTEXT structure. >=20 > + @param[in] ImageId Guid to get specific image file used. >=20 > + >=20 > + @retval EFI_IMAGE_INPUT Image data on BIOS image. >=20 > + >=20 > +**/ >=20 > +EFI_IMAGE_INPUT* >=20 > +VkGetImage ( >=20 > + IN VK_CONTEXT *VkContext, >=20 > + IN EFI_IMAGE_ID ImageId >=20 > + ) >=20 > +{ >=20 > + EFI_STATUS Status; >=20 > + EFI_IMAGE_INPUT Image; >=20 > + EFI_IMAGE_INPUT *VkImage; >=20 > + >=20 > + >=20 > + Status =3D VkContext->HiiImageEx->GetImageEx ( >=20 > + VkContext->HiiImageEx, >=20 > + VkContext->HiiHandle, >=20 > + ImageId, >=20 > + &Image >=20 > + ); >=20 > + if (EFI_ERROR (Status)) { >=20 > + ASSERT_EFI_ERROR (Status); >=20 > + } >=20 > + >=20 > + VkImage =3D AllocateCopyPool (sizeof (EFI_IMAGE_INPUT), &Image); >=20 > + if (VkImage =3D=3D NULL) { >=20 > + ASSERT_EFI_ERROR (EFI_OUT_OF_RESOURCES); >=20 > + return NULL; >=20 > + } >=20 > + >=20 > + return VkImage; >=20 > +} >=20 > + >=20 > +/** >=20 > + Dump partial debug message on VkContext. >=20 > + >=20 > + @param[in] VkContext Address of an VK_CONTEXT structure. >=20 > + >=20 > +**/ >=20 > +VOID >=20 > +VkDumpContext ( >=20 > + IN VK_CONTEXT *VkContext >=20 > + ) >=20 > +{ >=20 > + DEBUG (( >=20 > + DEBUG_VK_ROUTINE_ENTRY_EXIT, >=20 > + "VkContext->Signature: 0x%016x\n", >=20 > + VkContext->Signature >=20 > + )); >=20 > + DEBUG (( >=20 > + DEBUG_VK_ROUTINE_ENTRY_EXIT, >=20 > + "VkContext->Controller: 0x%016x\n", >=20 > + VkContext->Controller >=20 > + )); >=20 > + DEBUG (( >=20 > + DEBUG_VK_ROUTINE_ENTRY_EXIT | DEBUG_VK_GRAPHICS_INFO, >=20 > + "VkContext->GraphicsOutput->Mode->MaxMode: 0x%08x\n", >=20 > + VkContext->GraphicsOutput->Mode->MaxMode >=20 > + )); >=20 > + DEBUG (( >=20 > + DEBUG_VK_ROUTINE_ENTRY_EXIT | DEBUG_VK_GRAPHICS_INFO, >=20 > + "VkContext->GraphicsOutput->Mode->Mode: 0x%08x\n", >=20 > + VkContext->GraphicsOutput->Mode->Mode >=20 > + )); >=20 > + DEBUG (( >=20 > + DEBUG_VK_ROUTINE_ENTRY_EXIT | DEBUG_VK_GRAPHICS_INFO, >=20 > + "VkContext->GraphicsOutput->Mode->Info->HorizontalResolution: 0x%08x= \n", >=20 > + VkContext->GraphicsOutput->Mode->Info->HorizontalResolution >=20 > + )); >=20 > + DEBUG (( >=20 > + DEBUG_VK_ROUTINE_ENTRY_EXIT | DEBUG_VK_GRAPHICS_INFO, >=20 > + "VkContext->GraphicsOutput->Mode->Info->VerticalResolution: 0x%08x\n= ", >=20 > + VkContext->GraphicsOutput->Mode->Info->VerticalResolution >=20 > + )); >=20 > + DEBUG (( >=20 > + DEBUG_VK_ROUTINE_ENTRY_EXIT | DEBUG_VK_POINTS, >=20 > + "VkContext->AbsolutePointer->Mode X: 0x%016Lx - 0x%016Lx\n", >=20 > + VkContext->AbsolutePointer->Mode->AbsoluteMinX, >=20 > + VkContext->AbsolutePointer->Mode->AbsoluteMaxX >=20 > + )); >=20 > + DEBUG (( >=20 > + DEBUG_VK_ROUTINE_ENTRY_EXIT | DEBUG_VK_POINTS, >=20 > + "VkContext->AbsolutePointer->Mode Y: 0x%016Lx - 0x%016Lx\n", >=20 > + VkContext->AbsolutePointer->Mode->AbsoluteMinY, >=20 > + VkContext->AbsolutePointer->Mode->AbsoluteMaxY >=20 > + )); >=20 > + DEBUG (( >=20 > + DEBUG_VK_ROUTINE_ENTRY_EXIT | DEBUG_VK_POINTS, >=20 > + "VkContext->AbsolutePointer->Mode Z: 0x%016Lx - 0x%016Lx\n", >=20 > + VkContext->AbsolutePointer->Mode->AbsoluteMinZ, >=20 > + VkContext->AbsolutePointer->Mode->AbsoluteMaxZ >=20 > + )); >=20 > + DEBUG (( >=20 > + DEBUG_VK_ROUTINE_ENTRY_EXIT | DEBUG_VK_POINTS, >=20 > + "VkContext->AbsolutePointer->Mode->Attributes: 0x%08x\n", >=20 > + VkContext->AbsolutePointer->Mode->Attributes >=20 > + )); >=20 > +} >=20 > + >=20 > +/** >=20 > + Start the virtual keyboard driver >=20 > + >=20 > + This routine allocates the necessary resources for the driver. >=20 > + >=20 > + This routine is called by VirtualKeyboardDriverStart to complete the d= river >=20 > + initialization. >=20 > + >=20 > + @param[in, out] VkContext Address of an VK_CONTEXT structure >=20 > + @param[in] Controller Handle of device to work with. >=20 > + >=20 > + @retval EFI_SUCCESS Driver API properly initialized >=20 > + >=20 > +**/ >=20 > +EFI_STATUS >=20 > +VkApiStart ( >=20 > + IN OUT VK_CONTEXT *VkContext, >=20 > + IN EFI_HANDLE Controller >=20 > + ) >=20 > +{ >=20 > + EFI_STATUS Status; >=20 > + EFI_SIMPLE_TEXT_INPUT_EX_PROTOCOL *SimpleEx; >=20 > + EFI_KEY_DATA KeyData; >=20 > + EFI_HANDLE NotifyHandle; >=20 > + EFI_EVENT ReadyToBootEvent; >=20 > + >=20 > + DEBUG ((DEBUG_VK_ROUTINE_ENTRY_EXIT, "VkApiStart Start\n")); >=20 > + >=20 > + Status =3D gBS->CreateEvent ( >=20 > + EVT_NOTIFY_SIGNAL, >=20 > + TPL_CALLBACK, >=20 > + VkKeyNotifyProcessHandler, >=20 > + VkContext, >=20 > + &VkContext->KeyNotifyProcessEvent >=20 > + ); >=20 > + if (EFI_ERROR (Status)) { >=20 > + DEBUG ((DEBUG_VK_ROUTINE_ENTRY_EXIT | DEBUG_ERROR, "ERROR - Failed t= o create VkContext- > >KeyNotifyProcessEvent, Status: %r\n", Status)); >=20 > + goto Error; >=20 > + } >=20 > + >=20 > + Status =3D gBS->CreateEvent ( >=20 > + EVT_NOTIFY_WAIT, >=20 > + TPL_NOTIFY, >=20 > + VkTouchWaitForKey, >=20 > + VkContext, >=20 > + &(VkContext->SimpleTextIn.WaitForKey) >=20 > + ); >=20 > + if (EFI_ERROR (Status)) { >=20 > + DEBUG ((DEBUG_VK_ROUTINE_ENTRY_EXIT | DEBUG_ERROR, "ERROR - Failed t= o create VkContext- > >SimpleTextIn.WaitForKey, Status: %r\n", Status)); >=20 > + goto Error; >=20 > + } >=20 > + >=20 > + Status =3D gBS->CreateEvent ( >=20 > + EVT_NOTIFY_WAIT, >=20 > + TPL_NOTIFY, >=20 > + VkTouchWaitForKey, >=20 > + VkContext, >=20 > + &(VkContext->SimpleTextInEx.WaitForKeyEx) >=20 > + ); >=20 > + if (EFI_ERROR (Status)) { >=20 > + DEBUG ((DEBUG_VK_ROUTINE_ENTRY_EXIT | DEBUG_ERROR, "ERROR - Failed t= o create VkContext- > >SimpleTextInEx.WaitForKeyEx, Status %r\n", Status)); >=20 > + goto Error; >=20 > + } >=20 > + >=20 > + Status =3D gBS->CreateEvent ( >=20 > + EVT_TIMER | EVT_NOTIFY_SIGNAL, >=20 > + TPL_VK_SYNC, >=20 > + VkTimer, >=20 > + (VOID *)VkContext, >=20 > + &(VkContext->TimerEvent) >=20 > + ); >=20 > + if (EFI_ERROR (Status)) { >=20 > + DEBUG ((DEBUG_VK_ROUTINE_ENTRY_EXIT | DEBUG_ERROR, "ERROR - Failed t= o create the timer event, Status: %r\n", > Status)); >=20 > + goto Error; >=20 > + } >=20 > + >=20 > + Status =3D gBS->SetTimer ( >=20 > + VkContext->TimerEvent, >=20 > + TimerPeriodic, >=20 > + (UINT64) VK_POLL_INTERVAL >=20 > + ); >=20 > + if (EFI_ERROR (Status)) { >=20 > + DEBUG ((DEBUG_VK_ROUTINE_ENTRY_EXIT | DEBUG_ERROR, "ERROR - Failed t= o set the timer event, Status: %r\n", > Status)); >=20 > + goto Error; >=20 > + } >=20 > + >=20 > + // >=20 > + // Create event to clear keyboard before boot into OS. >=20 > + // >=20 > + Status =3D EfiCreateEventReadyToBootEx ( >=20 > + TPL_CALLBACK, >=20 > + VkReadyToBootCallBack, >=20 > + (VOID *)VkContext, >=20 > + &ReadyToBootEvent >=20 > + ); >=20 > + if (EFI_ERROR (Status)) { >=20 > + DEBUG ((DEBUG_VK_ROUTINE_ENTRY_EXIT | DEBUG_ERROR, "ERROR - Failed t= o create ReadyToBootEvent, > Status: %r\n", Status)); >=20 > + goto Error; >=20 > + } >=20 > + >=20 > + Status =3D gBS->LocateProtocol ( >=20 > + &gEfiHiiImageExProtocolGuid, >=20 > + NULL, >=20 > + (VOID **) &VkContext->HiiImageEx >=20 > + ); >=20 > + if (EFI_ERROR (Status)) { >=20 > + DEBUG ((DEBUG_VK_ROUTINE_ENTRY_EXIT | DEBUG_ERROR, "ERROR - Failed t= o open HiiImageEx protocol, > Status: %r\n", Status)); >=20 > + goto Error; >=20 > + } >=20 > + >=20 > + // >=20 > + // Initialize VkContext >=20 > + // >=20 > + VkContext->Signature =3D VK_SIGNATURE; >=20 > + VkContext->Controller =3D Controller; >=20 > + VkContext->SimpleTextIn.Reset =3D VkKeyboardReset; >=20 > + VkContext->SimpleTextIn.ReadKeyStroke =3D VkKeyboardReadKeyStr= oke; >=20 > + VkContext->SimpleTextInEx.Reset =3D VkKeyboardResetEx; >=20 > + VkContext->SimpleTextInEx.ReadKeyStrokeEx =3D VkKeyboardReadKeyStr= okeEx; >=20 > + VkContext->SimpleTextInEx.SetState =3D VkKeyboardSetState; >=20 > + VkContext->SimpleTextInEx.RegisterKeyNotify =3D VkKeyboardRegisterKe= yNotify; >=20 > + VkContext->SimpleTextInEx.UnregisterKeyNotify =3D VkKeyboardUnregister= KeyNotify; >=20 > + VkContext->IsIconShowed =3D FALSE; >=20 > + VkContext->IsBackgroundChanged =3D FALSE; >=20 > + VkContext->PageNumber =3D 0; >=20 > + VkContext->CurrentKeyboardDisplay =3D VkDisplayAttributeNo= ne; >=20 > + VkContext->TargetKeyboardDisplay =3D VkDisplayAttributeNo= ne; >=20 > + VkContext->VkBodyBackgroundBltBuffer =3D NULL; >=20 > + VkContext->VkBodyCompoundBltBuffer =3D NULL; >=20 > + VkContext->VkBodyBltSize =3D 0; >=20 > + VkContext->VkBodyBltStartX =3D 0; >=20 > + VkContext->VkBodyBltStartY =3D 0; >=20 > + VkContext->VkBodyBltHeight =3D 0; >=20 > + VkContext->VkBodyBltWidth =3D 0; >=20 > + VkContext->IconBltBuffer =3D NULL; >=20 > + VkContext->IconBltSize =3D 0; >=20 > + VkContext->IconReDrawCheck =3D 0; >=20 > + VkContext->FullIconUpdatedFlag =3D FALSE; >=20 > + VkContext->SimIconUpdatedFlag =3D FALSE; >=20 > + VkContext->KeyStartIndex =3D 0; >=20 > + VkContext->KeyEndIndex =3D 0; >=20 > + VkContext->KeyToggleState =3D EFI_TOGGLE_STATE_VAL= ID; >=20 > + VkContext->SmallIcon =3D VkGetImage (VkContex= t, IMAGE_TOKEN (IMG_VK_SIMPLEICON)); >=20 > + VkContext->FullIcon =3D VkGetImage (VkContex= t, IMAGE_TOKEN (IMG_VK_FULLICON)); >=20 > + VkContext->SimKeyBody =3D VkGetImage (VkContex= t, IMAGE_TOKEN (IMG_VK_SIMPLEKEYBOARD)); >=20 > + VkContext->DigKeyBody =3D VkGetImage (VkContex= t, IMAGE_TOKEN (IMG_VK_DIGITKEYBOARD)); >=20 > + VkContext->CapLeKeyBody =3D VkGetImage (VkContex= t, IMAGE_TOKEN (IMG_VK_CAPITALLETTERKEYBOARD)); >=20 > + >=20 > + InitializeListHead (&VkContext->NotifyList); >=20 > + >=20 > + Status =3D SetCharacterPosition (VkContext, 800, 600); >=20 > + ASSERT_EFI_ERROR (Status); >=20 > + >=20 > + Status =3D DrawKeyboardLayout (VkContext); >=20 > + ASSERT_EFI_ERROR (Status); >=20 > + >=20 > + Status =3D HideVkBody (VkContext); >=20 > + ASSERT_EFI_ERROR (Status); >=20 > + >=20 > + Status =3D HideVkIcon (VkContext); >=20 > + ASSERT_EFI_ERROR (Status); >=20 > + >=20 > + DEBUG_CODE ( >=20 > + VkDumpContext (VkContext); >=20 > + ); >=20 > + >=20 > + Status =3D gBS->HandleProtocol ( >=20 > + gST->ConsoleInHandle, >=20 > + &gEfiSimpleTextInputExProtocolGuid, >=20 > + (VOID **)&SimpleEx >=20 > + ); >=20 > + if (EFI_ERROR (Status)) { >=20 > + DEBUG ((DEBUG_VK_ROUTINE_ENTRY_EXIT | DEBUG_ERROR, "ERROR - Failed t= o found ConIn Protocol, Status: %r\n", > Status)); >=20 > + goto Error; >=20 > + } >=20 > + >=20 > + KeyData.KeyState.KeyToggleState =3D 0; >=20 > + KeyData.KeyState.KeyShiftState =3D 0; >=20 > + KeyData.Key.ScanCode =3D SCAN_ESC; >=20 > + KeyData.Key.UnicodeChar =3D CHAR_NULL; >=20 > + NotifyHandle =3D NULL; >=20 > + Status =3D SimpleEx->RegisterKeyNotify ( >=20 > + SimpleEx, >=20 > + &KeyData, >=20 > + VkNotifyKeyCallback, >=20 > + &NotifyHandle >=20 > + ); >=20 > + if (EFI_ERROR (Status)) { >=20 > + DEBUG ((DEBUG_VK_ROUTINE_ENTRY_EXIT | DEBUG_ERROR, "ERROR - Failed t= o register 'Esc', Status: %r\n", Status)); >=20 > + goto Error; >=20 > + } >=20 > + >=20 > + KeyData.KeyState.KeyToggleState =3D 0; >=20 > + KeyData.KeyState.KeyShiftState =3D 0; >=20 > + KeyData.Key.ScanCode =3D SCAN_NULL; >=20 > + KeyData.Key.UnicodeChar =3D CHAR_CARRIAGE_RETURN; >=20 > + Status =3D SimpleEx->RegisterKeyNotify ( >=20 > + SimpleEx, >=20 > + &KeyData, >=20 > + VkNotifyKeyCallback, >=20 > + &NotifyHandle >=20 > + ); >=20 > + if (EFI_ERROR (Status)) { >=20 > + DEBUG ((DEBUG_VK_ROUTINE_ENTRY_EXIT | DEBUG_ERROR, "ERROR - Failed t= o register 'Enter', Status: %r\n", Status)); >=20 > + goto Error; >=20 > + } >=20 > + >=20 > + for (KeyData.Key.UnicodeChar =3D L' '; KeyData.Key.UnicodeChar <=3D L'= ~'; KeyData.Key.UnicodeChar++) { >=20 > + Status =3D SimpleEx->RegisterKeyNotify ( >=20 > + SimpleEx, >=20 > + &KeyData, >=20 > + VkNotifyKeyCallback, >=20 > + &NotifyHandle >=20 > + ); >=20 > + if (EFI_ERROR (Status)) { >=20 > + DEBUG (( >=20 > + DEBUG_VK_ROUTINE_ENTRY_EXIT | DEBUG_ERROR, >=20 > + "ERROR - Failed to register '%c', Status: %r\n", >=20 > + KeyData.Key.UnicodeChar, >=20 > + Status >=20 > + )); >=20 > + break; >=20 > + } >=20 > + } >=20 > + if (EFI_ERROR(Status)) { >=20 > + goto Error; >=20 > + } >=20 > + >=20 > + DEBUG ((DEBUG_VK_ROUTINE_ENTRY_EXIT, "VkApiStart Success, Status: %r\n= ", Status)); >=20 > + goto End; >=20 > + >=20 > +Error: >=20 > + VkApiStop (VkContext); >=20 > + DEBUG ((DEBUG_VK_ROUTINE_ENTRY_EXIT, "VkApiStart Failed, Status: %r\n"= , Status)); >=20 > + >=20 > +End: >=20 > + DEBUG ((DEBUG_VK_ROUTINE_ENTRY_EXIT, "VkApiStart End\n")); >=20 > + return Status; >=20 > +} >=20 > + >=20 > +/** >=20 > + Stop the virtual keyboard driver >=20 > + >=20 > + This routine releases the resources allocated by VKApiStart. >=20 > + >=20 > + This routine is called by VirtualKeyboardDriverStop to initiate the dr= iver >=20 > + shutdown. >=20 > + >=20 > + @param[in] VkContext Address of an VK_CONTEXT structure >=20 > + >=20 > +**/ >=20 > +VOID >=20 > +VkApiStop ( >=20 > + IN VK_CONTEXT *VkContext >=20 > + ) >=20 > +{ >=20 > + EFI_STATUS Status; >=20 > + VK_NOTIFY *NotifyNode; >=20 > + LIST_ENTRY *NotifyList; >=20 > + >=20 > + DEBUG ((DEBUG_VK_ROUTINE_ENTRY_EXIT, "VkApiStop Start\n")); >=20 > + >=20 > + Status =3D gBS->SetTimer (VkContext->TimerEvent, TimerCancel, 0); >=20 > + ASSERT_EFI_ERROR (Status); >=20 > + >=20 > + if (VkContext->KeyNotifyProcessEvent !=3D NULL) { >=20 > + Status =3D gBS->CloseEvent (VkContext->KeyNotifyProcessEvent); >=20 > + ASSERT_EFI_ERROR (Status); >=20 > + VkContext->KeyNotifyProcessEvent =3D NULL; >=20 > + } >=20 > + >=20 > + if (VkContext->TimerEvent !=3D NULL) { >=20 > + Status =3D gBS->CloseEvent (VkContext->TimerEvent); >=20 > + ASSERT_EFI_ERROR (Status); >=20 > + VkContext->TimerEvent =3D NULL; >=20 > + } >=20 > + >=20 > + if (VkContext->SimpleTextIn.WaitForKey !=3D NULL) { >=20 > + Status =3D gBS->CloseEvent (VkContext->SimpleTextIn.WaitForKey); >=20 > + ASSERT_EFI_ERROR (Status); >=20 > + VkContext->SimpleTextIn.WaitForKey =3D NULL; >=20 > + } >=20 > + >=20 > + if (VkContext->SimpleTextInEx.WaitForKeyEx !=3D NULL) { >=20 > + Status =3D gBS->CloseEvent (VkContext->SimpleTextInEx.WaitForKeyEx); >=20 > + ASSERT_EFI_ERROR (Status); >=20 > + VkContext->SimpleTextInEx.WaitForKeyEx =3D NULL; >=20 > + } >=20 > + >=20 > + NotifyList =3D &VkContext->NotifyList; >=20 > + if (NotifyList !=3D NULL) { >=20 > + while (!IsListEmpty (NotifyList)) { >=20 > + NotifyNode =3D CR (NotifyList->ForwardLink, VK_NOTIFY, NotifyEntry= , VK_NOTIFY_SIGNATURE); >=20 > + RemoveEntryList (NotifyList->ForwardLink); >=20 > + gBS->FreePool (NotifyNode); >=20 > + } >=20 > + } >=20 > + >=20 > + DEBUG ((DEBUG_VK_ROUTINE_ENTRY_EXIT, "VkApiStop End\n")); >=20 > +} >=20 > + >=20 > +/** >=20 > + Reset the input device and optionally run diagnostics >=20 > + >=20 > + @param[in] This Protocol instance pointer. >=20 > + @param[in] ExtendedVerification Driver may perform diagnostics on rese= t. >=20 > + >=20 > + @retval EFI_SUCCESS The device was reset. >=20 > + @retval EFI_DEVICE_ERROR The device is not functioning properly= and could not be reset. >=20 > + >=20 > +**/ >=20 > +EFI_STATUS >=20 > +EFIAPI >=20 > +VkKeyboardReset ( >=20 > + IN EFI_SIMPLE_TEXT_INPUT_PROTOCOL *This, >=20 > + IN BOOLEAN ExtendedVerification >=20 > + ) >=20 > +{ >=20 > + EFI_STATUS Status; >=20 > + >=20 > + DEBUG ((DEBUG_VK_ROUTINE_ENTRY_EXIT, "VkKeyboardReset Start\n")); >=20 > + Status =3D EFI_SUCCESS; >=20 > + DEBUG ((DEBUG_VK_ROUTINE_ENTRY_EXIT, "VkKeyboardReset End\n")); >=20 > + return Status; >=20 > +} >=20 > + >=20 > +/** >=20 > + Resets the input device hardware. >=20 > + >=20 > + The Reset() function resets the input device hardware. As part >=20 > + of initialization process, the firmware/device will make a quick >=20 > + but reasonable attempt to verify that the device is functioning. >=20 > + If the ExtendedVerification flag is TRUE the firmware may take >=20 > + an extended amount of time to verify the device is operating on >=20 > + reset. Otherwise the reset operation is to occur as quickly as >=20 > + possible. The hardware verification process is not defined by >=20 > + this specification and is left up to the platform firmware or >=20 > + driver to implement. >=20 > + >=20 > + @param[in] This A pointer to the EFI_SIMPLE_TEXT_INPUT= _EX_PROTOCOL instance. >=20 > + >=20 > + @param[in] ExtendedVerification Indicates that the driver may perform = a more exhaustive >=20 > + verification operation of the device d= uring reset. >=20 > + >=20 > + @retval EFI_SUCCESS The device was reset. >=20 > + @retval EFI_DEVICE_ERROR The device is not functioning correctl= y and could not be reset. >=20 > + >=20 > +**/ >=20 > +EFI_STATUS >=20 > +EFIAPI >=20 > +VkKeyboardResetEx ( >=20 > + IN EFI_SIMPLE_TEXT_INPUT_EX_PROTOCOL *This, >=20 > + IN BOOLEAN ExtendedVerification >=20 > + ) >=20 > +{ >=20 > + EFI_STATUS Status; >=20 > + VK_CONTEXT *VkContext; >=20 > + >=20 > + DEBUG ((DEBUG_VK_ROUTINE_ENTRY_EXIT, "VkKeyboardResetEx Start\n")); >=20 > + >=20 > + Status =3D EFI_SUCCESS; >=20 > + if (This =3D=3D NULL) { >=20 > + Status =3D EFI_INVALID_PARAMETER; >=20 > + goto Error; >=20 > + } >=20 > + >=20 > + VkContext =3D VK_CONTEXT_FROM_SIMPLETEXTINEX_PROTOCOL (This); >=20 > + >=20 > + Status =3D VkContext->SimpleTextIn.Reset (&VkContext->SimpleTextIn, Ex= tendedVerification); >=20 > + if (EFI_ERROR (Status)) { >=20 > + DEBUG ((DEBUG_VK_KEYS, "ERROR - Failed to VK reset, Status: %r\n", S= tatus)); >=20 > + goto Error; >=20 > + } >=20 > + >=20 > + DEBUG ((DEBUG_VK_ROUTINE_ENTRY_EXIT, "VkKeyboardResetEx Success, Statu= s: %r\n", Status)); >=20 > + goto End; >=20 > + >=20 > +Error: >=20 > + DEBUG ((DEBUG_VK_ROUTINE_ENTRY_EXIT, "VkKeyboardResetEx Failed, Status= : %r\n", Status)); >=20 > + >=20 > +End: >=20 > + DEBUG ((DEBUG_VK_ROUTINE_ENTRY_EXIT, "VkKeyboardResetEx End\n")); >=20 > + return Status; >=20 > +} >=20 > + >=20 > +/** >=20 > + Reads the next keystroke from the input device. The WaitForKey Event c= an >=20 > + be used to test for existence of a keystroke via WaitForEvent () call. >=20 > + >=20 > + @param[in] This Protocol instance pointer. >=20 > + @param[out] Key Driver may perform diagnostics on reset. >=20 > + >=20 > + @retval EFI_SUCCESS The keystroke information was returned. >=20 > + @retval EFI_NOT_READY There was no keystroke data available. >=20 > + @retval EFI_DEVICE_ERROR The keystroke information was not returned du= e to >=20 > + hardware errors. >=20 > + >=20 > +**/ >=20 > +EFI_STATUS >=20 > +EFIAPI >=20 > +VkKeyboardReadKeyStroke ( >=20 > + IN EFI_SIMPLE_TEXT_INPUT_PROTOCOL *This, >=20 > + OUT EFI_INPUT_KEY *Key >=20 > + ) >=20 > +{ >=20 > + EFI_STATUS Status; >=20 > + VK_CONTEXT *VkContext; >=20 > + EFI_KEY_DATA TmpKeyData; >=20 > + EFI_TPL OldTpl; >=20 > + >=20 > + DEBUG ((DEBUG_VK_ROUTINE_ENTRY_EXIT, "VkKeyboardReadKeyStroke Start\n"= )); >=20 > + >=20 > + OldTpl =3D gBS->RaiseTPL (TPL_NOTIFY); >=20 > + if (This =3D=3D NULL || Key =3D=3D NULL) { >=20 > + Status =3D EFI_INVALID_PARAMETER; >=20 > + goto Error; >=20 > + } >=20 > + >=20 > + VkContext =3D VK_CONTEXT_FROM_PROTOCOL (This); >=20 > + >=20 > + Status =3D VkKeyboardReadKeyStrokeEx (&VkContext->SimpleTextInEx, &Tmp= KeyData); >=20 > + if (EFI_ERROR (Status)) { >=20 > + goto Error; >=20 > + } >=20 > + *Key =3D TmpKeyData.Key; >=20 > + >=20 > + >=20 > + DEBUG ((DEBUG_VK_ROUTINE_ENTRY_EXIT, "VkKeyboardReadKeyStroke Success,= Status: %r\n", Status)); >=20 > + goto End; >=20 > + >=20 > +Error: >=20 > + DEBUG ((DEBUG_VK_ROUTINE_ENTRY_EXIT, "VkKeyboardReadKeyStroke Failed, = Status: %r\n", Status)); >=20 > + >=20 > +End: >=20 > + gBS->RestoreTPL (OldTpl); >=20 > + DEBUG ((DEBUG_VK_ROUTINE_ENTRY_EXIT, "VkKeyboardReadKeyStroke End\n"))= ; >=20 > + return Status; >=20 > +} >=20 > + >=20 > +/** >=20 > + Reads the next keystroke from the input device. >=20 > + >=20 > + @param[in] This Protocol instance pointer. >=20 > + @param[out] KeyData A pointer to a buffer that is filled in= with the keystroke >=20 > + state data for the key that was pressed= . >=20 > + >=20 > + @retval EFI_SUCCESS The keystroke information was returned. >=20 > + @retval EFI_NOT_READY There was no keystroke data available. >=20 > + @retval EFI_INVALID_PARAMETER This or KeyData is NULL. >=20 > + >=20 > +**/ >=20 > +EFI_STATUS >=20 > +EFIAPI >=20 > +VkKeyboardReadKeyStrokeEx ( >=20 > + IN EFI_SIMPLE_TEXT_INPUT_EX_PROTOCOL *This, >=20 > + OUT EFI_KEY_DATA *KeyData >=20 > + ) >=20 > +{ >=20 > + VK_CONTEXT *VkContext; >=20 > + EFI_STATUS Status; >=20 > + EFI_TPL OldTpl; >=20 > + EFI_KEY_DATA TmpKeyData; >=20 > + >=20 > + DEBUG ((DEBUG_VK_ROUTINE_ENTRY_EXIT, "VkKeyboardReadKeyStrokeEx Start\= n")); >=20 > + >=20 > + OldTpl =3D gBS->RaiseTPL (TPL_NOTIFY); >=20 > + if (This =3D=3D NULL || KeyData =3D=3D NULL) { >=20 > + Status =3D EFI_INVALID_PARAMETER; >=20 > + goto Error; >=20 > + } >=20 > + >=20 > + VkContext =3D VK_CONTEXT_FROM_SIMPLETEXTINEX_PROTOCOL (This); >=20 > + >=20 > + while (TRUE) { >=20 > + Status =3D VkPopTheKey (VkContext, &TmpKeyData); >=20 > + if (EFI_ERROR (Status)) { >=20 > + DEBUG ((DEBUG_VK_KEYS, "ERROR - Failed to VkPopTheKey check whethe= r keybuffer is empty, Status: %r\n", Status)); >=20 > + goto Error; >=20 > + } >=20 > + if (TmpKeyData.Key.ScanCode !=3D SCAN_NULL || TmpKeyData.Key.Unicode= Char !=3D CHAR_NULL) { >=20 > + break; >=20 > + } >=20 > + } >=20 > + *KeyData =3D TmpKeyData; >=20 > + >=20 > + DEBUG ((DEBUG_VK_ROUTINE_ENTRY_EXIT, "VkKeyboardReadKeyStrokeEx Succes= s, Status: %r\n", Status)); >=20 > + goto End; >=20 > + >=20 > +Error: >=20 > + DEBUG ((DEBUG_VK_ROUTINE_ENTRY_EXIT, "VkKeyboardReadKeyStrokeEx Failed= , Status: %r\n", Status)); >=20 > + >=20 > +End: >=20 > + gBS->RestoreTPL (OldTpl); >=20 > + DEBUG ((DEBUG_VK_ROUTINE_ENTRY_EXIT, "VkKeyboardReadKeyStrokeEx End\n"= )); >=20 > + return Status; >=20 > +} >=20 > + >=20 > +/** >=20 > + Set certain state for the input device. >=20 > + >=20 > + @param[in] This Protocol instance pointer. >=20 > + @param[in] KeyToggleState A pointer to the EFI_KEY_TOGGLE_STATE = to set the >=20 > + state for the input device. >=20 > + >=20 > + @retval EFI_SUCCESS The device state was set appropriately= . >=20 > + @retval EFI_INVALID_PARAMETER This or KeyToggleState is NULL. >=20 > + >=20 > +**/ >=20 > +EFI_STATUS >=20 > +EFIAPI >=20 > +VkKeyboardSetState ( >=20 > + IN EFI_SIMPLE_TEXT_INPUT_EX_PROTOCOL *This, >=20 > + IN EFI_KEY_TOGGLE_STATE *KeyToggleState >=20 > + ) >=20 > +{ >=20 > + EFI_STATUS Status; >=20 > + VK_CONTEXT *VkContext; >=20 > + >=20 > + DEBUG ((DEBUG_VK_ROUTINE_ENTRY_EXIT, "VkKeyboardSetState Start\n")); >=20 > + >=20 > + Status =3D EFI_SUCCESS; >=20 > + if (This =3D=3D NULL || KeyToggleState =3D=3D NULL) { >=20 > + Status =3D EFI_INVALID_PARAMETER; >=20 > + goto Error; >=20 > + } >=20 > + >=20 > + VkContext =3D VK_CONTEXT_FROM_SIMPLETEXTINEX_PROTOCOL (This); >=20 > + >=20 > + VkContext->KeyToggleState =3D *KeyToggleState; >=20 > + VkContext->IsCapsLockFlag =3D (*KeyToggleState & EFI_CAPS_LOCK_AC= TIVE) =3D=3D EFI_CAPS_LOCK_ACTIVE; >=20 > + VkContext->IsSupportPartialKey =3D (*KeyToggleState & EFI_KEY_STATE_EX= POSED) =3D=3D EFI_KEY_STATE_EXPOSED; >=20 > + >=20 > + if (VkContext->PageNumber >=3D VkPage0 && VkContext->PageNumber <=3D V= kPage1) { >=20 > + VkContext->PageNumber =3D VkContext->IsCapsLockFlag ? VkPage1 : VkPa= ge0; >=20 > + } >=20 > + >=20 > + HideVkBody (VkContext); >=20 > + DrawKeyboardLayout (VkContext); >=20 > + >=20 > + DEBUG ((DEBUG_VK_KEYS | DEBUG_INFO, "VkContext->KeyToggleState: %= 02x\n", VkContext->KeyToggleState)); >=20 > + DEBUG ((DEBUG_VK_KEYS | DEBUG_INFO, "VkContext->IsCapsLockFlag: %= 02x\n", VkContext->IsCapsLockFlag)); >=20 > + DEBUG ((DEBUG_VK_KEYS | DEBUG_INFO, "VkContext->IsSupportPartialKey: %= 02x\n", VkContext->IsSupportPartialKey)); >=20 > + >=20 > + DEBUG ((DEBUG_VK_ROUTINE_ENTRY_EXIT, "VkKeyboardSetState Success, Stat= us: %r\n", Status)); >=20 > + goto End; >=20 > + >=20 > +Error: >=20 > + DEBUG ((DEBUG_VK_ROUTINE_ENTRY_EXIT, "VkKeyboardSetState Failed, Statu= s: %r\n", Status)); >=20 > + >=20 > +End: >=20 > + DEBUG ((DEBUG_VK_ROUTINE_ENTRY_EXIT, "VkKeyboardSetState End\n")); >=20 > + return Status; >=20 > +} >=20 > + >=20 > +/** >=20 > + Register a notification function for a particular keystroke for the in= put device. >=20 > + >=20 > + @param[in] This Protocol instance pointer. >=20 > + @param[in] KeyData A pointer to a buffer that is = filled in with the keystroke >=20 > + information data for the key t= hat was pressed. >=20 > + @param[in] KeyNotificationFunction Points to the function to be c= alled when the key >=20 > + sequence is typed specified by= KeyData. >=20 > + @param[out] NotifyHandle Points to the unique handle as= signed to the registered notification. >=20 > + >=20 > + @retval EFI_SUCCESS The notification function was = registered successfully. >=20 > + @retval EFI_OUT_OF_RESOURCES Unable to allocate resources f= or necessary data structures. >=20 > + @retval EFI_INVALID_PARAMETER KeyData or NotifyHandle or Key= NotificationFunction is NULL. >=20 > + >=20 > +**/ >=20 > +EFI_STATUS >=20 > +EFIAPI >=20 > +VkKeyboardRegisterKeyNotify ( >=20 > + IN EFI_SIMPLE_TEXT_INPUT_EX_PROTOCOL *This, >=20 > + IN EFI_KEY_DATA *KeyData, >=20 > + IN EFI_KEY_NOTIFY_FUNCTION KeyNotificationFunction, >=20 > + OUT EFI_HANDLE *NotifyHandle >=20 > + ) >=20 > +{ >=20 > + EFI_STATUS Status; >=20 > + EFI_TPL OldTpl; >=20 > + VK_CONTEXT *VkContext; >=20 > + LIST_ENTRY *Link; >=20 > + VK_NOTIFY *CurrentNotify; >=20 > + VK_NOTIFY *NewNotify; >=20 > + >=20 > + DEBUG ((DEBUG_VK_ROUTINE_ENTRY_EXIT, "VkKeyboardRegisterKeyNotify Star= t\n")); >=20 > + >=20 > + // >=20 > + // Enter critical section >=20 > + // >=20 > + OldTpl =3D gBS->RaiseTPL (TPL_NOTIFY); >=20 > + Status =3D EFI_SUCCESS; >=20 > + if (This =3D=3D NULL || KeyData =3D=3D NULL || NotifyHandle =3D=3D NUL= L || KeyNotificationFunction =3D=3D NULL) { >=20 > + Status =3D EFI_INVALID_PARAMETER; >=20 > + goto Error; >=20 > + } >=20 > + VkContext =3D VK_CONTEXT_FROM_SIMPLETEXTINEX_PROTOCOL (This); >=20 > + >=20 > + >=20 > + // >=20 > + // Return EFI_SUCCESS if the (KeyData, NotificationFunction) is alread= y registered. >=20 > + // >=20 > + for (Link =3D VkContext->NotifyList.ForwardLink; Link !=3D &VkContext-= >NotifyList; Link =3D Link->ForwardLink) { >=20 > + CurrentNotify =3D CR (Link, VK_NOTIFY, NotifyEntry, VK_NOTIFY_SIGNAT= URE); >=20 > + if (IsKeyRegistered (&CurrentNotify->KeyData, KeyData)) { >=20 > + if (CurrentNotify->KeyNotificationFn =3D=3D KeyNotificationFunctio= n) { >=20 > + *NotifyHandle =3D CurrentNotify; >=20 > + Status =3D EFI_SUCCESS; >=20 > + goto End; >=20 > + } >=20 > + } >=20 > + } >=20 > + >=20 > + // >=20 > + // Allocate resource to save the notification function >=20 > + // >=20 > + NewNotify =3D (VK_NOTIFY *) AllocateZeroPool (sizeof (VK_NOTIFY)); >=20 > + if (NewNotify =3D=3D NULL) { >=20 > + Status =3D EFI_OUT_OF_RESOURCES; >=20 > + goto Error; >=20 > + } >=20 > + >=20 > + NewNotify->Signature =3D VK_NOTIFY_SIGNATURE; >=20 > + NewNotify->KeyNotificationFn =3D KeyNotificationFunction; >=20 > + CopyMem (&NewNotify->KeyData, KeyData, sizeof (EFI_KEY_DATA)); >=20 > + InsertTailList (&VkContext->NotifyList, &NewNotify->NotifyEntry); >=20 > + >=20 > + *NotifyHandle =3D NewNotify; >=20 > + Status =3D EFI_SUCCESS; >=20 > + >=20 > + DEBUG ((DEBUG_VK_ROUTINE_ENTRY_EXIT, "VkKeyboardRegisterKeyNotify Succ= ess, Status: %r\n", Status)); >=20 > + goto End; >=20 > + >=20 > +Error: >=20 > + DEBUG ((DEBUG_VK_ROUTINE_ENTRY_EXIT, "VkKeyboardRegisterKeyNotify Fail= ed, Status: %r\n", Status)); >=20 > + >=20 > +End: >=20 > + // >=20 > + // Leave critical section and return >=20 > + // >=20 > + gBS->RestoreTPL (OldTpl); >=20 > + DEBUG ((DEBUG_VK_ROUTINE_ENTRY_EXIT, "VkKeyboardRegisterKeyNotify End\= n")); >=20 > + return Status; >=20 > +} >=20 > + >=20 > +/** >=20 > + Remove a registered notification function from a particular keystroke. >=20 > + >=20 > + @param[in] This Protocol instance pointer. >=20 > + @param[in] NotificationHandle The handle of the notification function= being unregistered. >=20 > + >=20 > + @retval EFI_SUCCESS The notification function was unregiste= red successfully. >=20 > + @retval EFI_INVALID_PARAMETER The NotificationHandle is invalid >=20 > + >=20 > +**/ >=20 > +EFI_STATUS >=20 > +EFIAPI >=20 > +VkKeyboardUnregisterKeyNotify ( >=20 > + IN EFI_SIMPLE_TEXT_INPUT_EX_PROTOCOL *This, >=20 > + IN EFI_HANDLE NotificationHandle >=20 > + ) >=20 > +{ >=20 > + EFI_STATUS Status; >=20 > + VK_CONTEXT *VkContext; >=20 > + EFI_TPL OldTpl; >=20 > + LIST_ENTRY *Link; >=20 > + VK_NOTIFY *CurrentNotify; >=20 > + BOOLEAN IsFindNotifyHandle; >=20 > + >=20 > + DEBUG ((DEBUG_VK_ROUTINE_ENTRY_EXIT, "VkKeyboardUnregisterKeyNotify St= art\n")); >=20 > + >=20 > + // >=20 > + // Enter critical section >=20 > + // >=20 > + OldTpl =3D gBS->RaiseTPL (TPL_NOTIFY); >=20 > + Status =3D EFI_SUCCESS; >=20 > + if (This =3D=3D NULL || NotificationHandle =3D=3D NULL) { >=20 > + Status =3D EFI_INVALID_PARAMETER; >=20 > + goto Error; >=20 > + } >=20 > + VkContext =3D VK_CONTEXT_FROM_SIMPLETEXTINEX_PROTOCOL (This); >=20 > + >=20 > + IsFindNotifyHandle =3D FALSE; >=20 > + for (Link =3D VkContext->NotifyList.ForwardLink; Link !=3D &VkContext-= >NotifyList; Link =3D Link->ForwardLink) { >=20 > + CurrentNotify =3D CR (Link, VK_NOTIFY, NotifyEntry, VK_NOTIFY_SIGNAT= URE); >=20 > + if (CurrentNotify =3D=3D NotificationHandle) { >=20 > + // >=20 > + // Remove the notification function from NotifyList and free resou= rces >=20 > + // >=20 > + RemoveEntryList (&CurrentNotify->NotifyEntry); >=20 > + >=20 > + gBS->FreePool (CurrentNotify); >=20 > + IsFindNotifyHandle =3D TRUE; >=20 > + break; >=20 > + } >=20 > + } >=20 > + >=20 > + if (!IsFindNotifyHandle) { >=20 > + Status =3D EFI_INVALID_PARAMETER; >=20 > + goto Error; >=20 > + } >=20 > + >=20 > + DEBUG ((DEBUG_VK_ROUTINE_ENTRY_EXIT, "VkKeyboardUnregisterKeyNotify Su= ccess, Status: %r\n", Status)); >=20 > + goto End; >=20 > + >=20 > +Error: >=20 > + DEBUG ((DEBUG_VK_ROUTINE_ENTRY_EXIT, "VkKeyboardUnregisterKeyNotify Fa= iled, Status: %r\n", Status)); >=20 > + >=20 > +End: >=20 > + // >=20 > + // Leave critical section and return >=20 > + // >=20 > + gBS->RestoreTPL (OldTpl); >=20 > + DEBUG ((DEBUG_VK_ROUTINE_ENTRY_EXIT, "VkKeyboardUnregisterKeyNotify En= d\n")); >=20 > + return Status; >=20 > +} >=20 > diff --git a/Features/Intel/UserInterface/VirtualKeyboardFeaturePkg/Virtu= alKeyboardDxe/KeyboardLayout.c > b/Features/Intel/UserInterface/VirtualKeyboardFeaturePkg/VirtualKeyboardD= xe/KeyboardLayout.c > new file mode 100644 > index 0000000000..dcf78985ee > --- /dev/null > +++ b/Features/Intel/UserInterface/VirtualKeyboardFeaturePkg/VirtualKeybo= ardDxe/KeyboardLayout.c > @@ -0,0 +1,1364 @@ > +/** @file >=20 > + Virtural Keyboard Layout Engine >=20 > + >=20 > + Copyright (c) 2012 - 2020, Intel Corporation. All rights reserved.
    >=20 > + SPDX-License-Identifier: BSD-2-Clause-Patent >=20 > + >=20 > +**/ >=20 > + >=20 > +#include "VirtualKeyboard.h" >=20 > + >=20 > +// >=20 > +// 1.FullKeyboardBody >=20 > +// Follow below design >=20 > +// (1).\KeyboardLayout\CapitalLetterKeyboard.bmp >=20 > +// (2).\KeyboardLayout\DigitKeyboard.bmp >=20 > +// Based on keyboard's (startX, startY) >=20 > +// >=20 > +// Page0Font >=20 > +// +---+---+---+---+---+---+---+---+---+---+---+ >=20 > +// | q | w | e | r | t | y | u | i | o | p |=20 > +// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ >=20 > +// | | a | s | d | f | g | h | j | k | l | F2| | Line 1 >=20 > +// +-+---+---+---+---+---+---+---+---+---+---+-+ >=20 > +// |Caps | z | x | c | v | b | n | m |aU |Enter| Line 2 >=20 > +// +-----+---+---+---+---+---+---+---+---+---+-+ >=20 > +// | Esc |12#| Space |aL |aD |aR | | Line 3 >=20 > +// +-----+---+-------------------+---+---+---+-+ >=20 > +// >=20 > +// Page1Font >=20 > +// +---+---+---+---+---+---+---+---+---+---+---+ >=20 > +// | Q | W | E | R | T | Y | U | I | O | P |=20 > +// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ >=20 > +// | | A | S | D | F | G | H | J | K | L | F2| | Line 1 >=20 > +// +-+---+---+---+---+---+---+---+---+---+---+-+ >=20 > +// |Caps | Z | X | C | V | B | N | M |aU |Enter| Line 2 >=20 > +// +-----+---+---+---+---+---+---+---+---+---+-+ >=20 > +// | Esc |12#| Space |aL |aD |aR | | Line 3 >=20 > +// +-----+---+-------------------+---+---+---+-+ >=20 > +// >=20 > +// Page2Font >=20 > +// +---+---+---+---+---+---+---+---+---+---+---+ >=20 > +// | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 0 |=20 > +// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ >=20 > +// | |F1 |F2 |F3 |F4 |F5 |F6 |F7 |F8 |F9 |F10| | Line 1 >=20 > +// +-+---+---+---+---+---+---+---+---+---+---+-+ >=20 > +// |Shift| . | ; | ' | , | . | / |F11|F12|Enter| Line 2 >=20 > +// +-----+---+---+---+---+---+---+---+---+---+-+ >=20 > +// | Esc |12#| Space | \ | - | =3D | | Line 3 >=20 > +// +-----+---+-------------------+---+---+---+-+ >=20 > +// >=20 > +// Page3Font >=20 > +// +---+---+---+---+---+---+---+---+---+---+---+ >=20 > +// | ! | @ | # | $ | % | ^ | & | * | ( | ) |=20 > +// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ >=20 > +// | |F1 |F2 |F3 |F4 |F5 |F6 |F7 |F8 |F9 |F10| | Line 1 >=20 > +// +-+---+---+---+---+---+---+---+---+---+---+-+ >=20 > +// |Shift| ~ | : | " | < | > | ? |F11|F12|Enter| Line 2 >=20 > +// +-----+---+---+---+---+---+---+---+---+---+-+ >=20 > +// | Esc |12#| Space | | | _ | + | | Line 3 >=20 > +// +-----+---+-------------------+---+---+---+-+ >=20 > +// >=20 > +// 2.Screen Corner >=20 > +// Follow below design >=20 > +// (1).\KeyboardLayout\SimpleIcon.bmp # Screen Corner A/B >=20 > +// (2).\KeyboardLayout\FullIcon.bmp # Screen Corner C/D >=20 > +// +-+------------------------------------+-+ >=20 > +// |A| |C| >=20 > +// +-+ +-+ >=20 > +// | | >=20 > +// | | >=20 > +// | | >=20 > +// | | >=20 > +// | | >=20 > +// | | >=20 > +// +-+ +-+ >=20 > +// |B| |D| >=20 > +// +-+------------------------------------+-+ >=20 > +// >=20 > +VK_STRUCT mFullKeyboardBody[] =3D { >=20 > + // StartX StartY EndX EndY Page0Font Page1Font = Page2Font Page3Font >=20 > + // Line 0 >=20 > + { 0x0000, 0x0000, 0x0032, 0x0032, {L'q', L'Q', = L'1', L'!' }}, >=20 > + { 0x0032, 0x0000, 0x0064, 0x0032, {L'w', L'W', = L'2', L'@' }}, >=20 > + { 0x0064, 0x0000, 0x0096, 0x0032, {L'e', L'E', = L'3', L'#' }}, >=20 > + { 0x0096, 0x0000, 0x00C8, 0x0032, {L'r', L'R', = L'4', L'$' }}, >=20 > + { 0x00C8, 0x0000, 0x00FA, 0x0032, {L't', L'T', = L'5', L'%' }}, >=20 > + { 0x00FA, 0x0000, 0x012C, 0x0032, {L'y', L'Y', = L'6', L'^' }}, >=20 > + { 0x012C, 0x0000, 0x015E, 0x0032, {L'u', L'U', = L'7', L'&' }}, >=20 > + { 0x015E, 0x0000, 0x0190, 0x0032, {L'i', L'I', = L'8', L'*' }}, >=20 > + { 0x0190, 0x0000, 0x01C2, 0x0032, {L'o', L'O', = L'9', L'(' }}, >=20 > + { 0x01C2, 0x0000, 0x01F4, 0x0032, {L'p', L'P', = L'0', L')' }}, >=20 > + { 0x01F4, 0x0000, 0x0226, 0x0032, {VkKeyBackspace, VkKeyBackspac= e, VkKeyBackspace, VkKeyBackspace }}, >=20 > + // Line 1 >=20 > + { 0x0000, 0x0032, 0x0019, 0x0064, {VkKeyNull, VkKeyNull, = VkKeyNull, VkKeyNull }}, >=20 > + { 0x0019, 0x0032, 0x004B, 0x0064, {L'a', L'A', = VkKeyF1, VkKeyF1 }}, >=20 > + { 0x004B, 0x0032, 0x007D, 0x0064, {L's', L'S', = VkKeyF2, VkKeyF2 }}, >=20 > + { 0x007D, 0x0032, 0x00AF, 0x0064, {L'd', L'D', = VkKeyF3, VkKeyF3 }}, >=20 > + { 0x00AF, 0x0032, 0x00E1, 0x0064, {L'f', L'F', = VkKeyF4, VkKeyF4 }}, >=20 > + { 0x00E1, 0x0032, 0x0113, 0x0064, {L'g', L'G', = VkKeyF5, VkKeyF5 }}, >=20 > + { 0x0113, 0x0032, 0x0145, 0x0064, {L'h', L'H', = VkKeyF6, VkKeyF6 }}, >=20 > + { 0x0145, 0x0032, 0x0177, 0x0064, {L'j', L'J', = VkKeyF7, VkKeyF7 }}, >=20 > + { 0x0177, 0x0032, 0x01A9, 0x0064, {L'k', L'K', = VkKeyF8, VkKeyF8 }}, >=20 > + { 0x01A9, 0x0032, 0x01DB, 0x0064, {L'l', L'L', = VkKeyF9, VkKeyF9 }}, >=20 > + { 0x01DB, 0x0032, 0x020D, 0x0064, {VkKeyF2, VkKeyF2, = VkKeyF10, VkKeyF10 }}, >=20 > + // Line 2 >=20 > + { 0x0000, 0x0064, 0x004B, 0x0096, {VkKeyCapslock, VkKeyCapslock= , VkKeyShift, VkKeyShift }}, >=20 > + { 0x004B, 0x0064, 0x007D, 0x0096, {L'z', L'Z', = L'`', L'~' }}, >=20 > + { 0x007D, 0x0064, 0x00AF, 0x0096, {L'x', L'X', = L';', L':' }}, >=20 > + { 0x00AF, 0x0064, 0x00E1, 0x0096, {L'c', L'C', = L'\'', L'"' }}, >=20 > + { 0x00E1, 0x0064, 0x0113, 0x0096, {L'v', L'V', = L',', L'<' }}, >=20 > + { 0x0113, 0x0064, 0x0145, 0x0096, {L'b', L'B', = L'.', L'>' }}, >=20 > + { 0x0145, 0x0064, 0x0177, 0x0096, {L'n', L'N', = L'/', L'?' }}, >=20 > + { 0x0177, 0x0064, 0x01A9, 0x0096, {L'm', L'M', = VkKeyF11, VkKeyF11 }}, >=20 > + { 0x01A9, 0x0064, 0x01DB, 0x0096, {VkKeyUp, VkKeyUp, = VkKeyF12, VkKeyF12 }}, >=20 > + { 0x01DB, 0x0064, 0x0226, 0x0096, {VkKeyEnter, VkKeyEnter, = VkKeyEnter, VkKeyEnter }}, >=20 > + // Line 3 >=20 > + { 0x0000, 0x0096, 0x004B, 0x00C8, {VkKeyEsc, VkKeyEsc, = VkKeyEsc, VkKeyEsc }}, >=20 > + { 0x004B, 0x0096, 0x007D, 0x00C8, {VkKeyTwoPage, VkKeyTwoPage,= VkKeyTwoPage, VkKeyTwoPage }}, >=20 > + { 0x007D, 0x0096, 0x0177, 0x00C8, {L' ', L' ', = L' ', L' ' }}, >=20 > + { 0x0177, 0x0096, 0x01A9, 0x00C8, {VkKeyLeft, VkKeyLeft, = L'\\', L'|' }}, >=20 > + { 0x01A9, 0x0096, 0x01DB, 0x00C8, {VkKeyDown, VkKeyDown, = L'-', L'_' }}, >=20 > + { 0x01DB, 0x0096, 0x020D, 0x00C8, {VkKeyRight, VkKeyRight, = L'=3D', L'+' }}, >=20 > + // Screen Corner A >=20 > + { 0x0000, 0x0000, 0x001E, 0x001E, {VkKeyTypeMaximum, VkKeyTypeMaxi= mum, VkKeyTypeMaximum, > VkKeyTypeMaximum}}, >=20 > + // Screen Corner B >=20 > + { 0x0000, 0x023A, 0x001E, 0x0258, {VkKeyTypeMaximum, VkKeyTypeMaxi= mum, VkKeyTypeMaximum, > VkKeyTypeMaximum}}, >=20 > + // Screen Corner C >=20 > + { 0x02E4, 0x0000, 0x0320, 0x001E, {VkKeyTypeMaximum, VkKeyTypeMaxi= mum, VkKeyTypeMaximum, > VkKeyTypeMaximum}}, >=20 > + // Screen Corner D >=20 > + { 0x02E4, 0x023A, 0x0320, 0x0258, {VkKeyTypeMaximum, VkKeyTypeMaxi= mum, VkKeyTypeMaximum, > VkKeyTypeMaximum}} >=20 > +}; >=20 > + >=20 > +// >=20 > +// 1.SimpleKeyboardBody >=20 > +// Follow below design >=20 > +// (1).\KeyboardLayout\SimpleKeyboard.bmp >=20 > +// Based on keyboard's (startX, startY) >=20 > +// +-----+-----+ >=20 > +// | Esc |Enter| Line 0 >=20 > +// +-----+-----+ >=20 > +// | Up | Down| Line 1 >=20 > +// +-----+-----+ >=20 > +// >=20 > +// 2.Screen Corner >=20 > +// Follow below design >=20 > +// (1).\KeyboardLayout\SimpleIcon.bmp # Screen Corner A/B >=20 > +// (2).\KeyboardLayout\FullIcon.bmp # Screen Corner C/D >=20 > +// +-+------------------------------------+-+ >=20 > +// |A| |C| >=20 > +// +-+ +-+ >=20 > +// | | >=20 > +// | | >=20 > +// | | >=20 > +// | | >=20 > +// | | >=20 > +// | | >=20 > +// +-+ +-+ >=20 > +// |B| |D| >=20 > +// +-+------------------------------------+-+ >=20 > +// >=20 > +VK_STRUCT mSimpleKeyboardBody[] =3D { >=20 > + // StartX StartY EndX EndY Page0Font Page1Font = Page2Font Page3Font >=20 > + // Line 0 >=20 > + { 0x0000, 0x0000, 0x0032, 0x0032, {VkKeyEsc, VkKeyEsc, = VkKeyEsc, VkKeyEsc }}, >=20 > + { 0x0032, 0x0000, 0x0064, 0x0032, {VkKeyEnter, VkKeyEnter, = VkKeyEnter, VkKeyEnter }}, >=20 > + // Line 1 >=20 > + { 0x0000, 0x0032, 0x0032, 0x0064, {VkKeyUp, VkKeyUp, = VkKeyUp, VkKeyUp }}, >=20 > + { 0x0032, 0x0032, 0x0064, 0x0064, {VkKeyDown, VkKeyDown, = VkKeyDown, VkKeyDown }}, >=20 > + // Screen Corner A >=20 > + { 0x0000, 0x0000, 0x001E, 0x001E, {VkKeyTypeMaximum, VkKeyTypeMaxi= mum, VkKeyTypeMaximum, > VkKeyTypeMaximum}}, >=20 > + // Screen Corner B >=20 > + { 0x0000, 0x023A, 0x001E, 0x0258, {VkKeyTypeMaximum, VkKeyTypeMaxi= mum, VkKeyTypeMaximum, > VkKeyTypeMaximum}}, >=20 > + // Screen Corner C >=20 > + { 0x02E4, 0x0000, 0x0320, 0x001E, {VkKeyTypeMaximum, VkKeyTypeMaxi= mum, VkKeyTypeMaximum, > VkKeyTypeMaximum}}, >=20 > + // Screen Corner D >=20 > + { 0x02E4, 0x023A, 0x0320, 0x0258, {VkKeyTypeMaximum, VkKeyTypeMaxi= mum, VkKeyTypeMaximum, > VkKeyTypeMaximum}} >=20 > +}; >=20 > + >=20 > +EFI_STATUS >=20 > +ModifyShiftKeyColor ( >=20 > + IN VK_CONTEXT *VkContext, >=20 > + IN OUT EFI_GRAPHICS_OUTPUT_BLT_PIXEL **BltBuffer >=20 > + ) >=20 > +{ >=20 > + EFI_GRAPHICS_OUTPUT_BLT_PIXEL *TempBltBuffer; >=20 > + UINTN BltSize; >=20 > + BOOLEAN IsPressed; >=20 > + >=20 > + TempBltBuffer =3D *BltBuffer; >=20 > + BltSize =3D VkContext->VkBodyBltHeight * VkContext->VkBodyBltWid= th; >=20 > + IsPressed =3D VkContext->PageNumber <=3D VkPage1 ? >=20 > + VkContext->IsCapsLockFlag : >=20 > + VkContext->IsShiftKeyFlag; >=20 > + >=20 > + while (BltSize-- !=3D 0) { >=20 > + // >=20 > + // Color gradient issue >=20 > + // >=20 > + if (((TempBltBuffer->Red - TempBltBuffer->Green) > 0x20) && >=20 > + ((TempBltBuffer->Red - TempBltBuffer->Blue) > 0x20)) { >=20 > + if (IsPressed) { >=20 > + TempBltBuffer->Red =3D 0; >=20 > + TempBltBuffer->Green =3D 255; >=20 > + TempBltBuffer->Blue =3D 255; >=20 > + } else { >=20 > + TempBltBuffer->Red =3D 255; >=20 > + TempBltBuffer->Green =3D 255; >=20 > + TempBltBuffer->Blue =3D 255; >=20 > + } >=20 > + } >=20 > + TempBltBuffer++; >=20 > + } >=20 > + >=20 > + return EFI_SUCCESS; >=20 > +} >=20 > + >=20 > +EFI_STATUS >=20 > +MakeKeyboardTransparent ( >=20 > + IN VK_CONTEXT *VkContext, >=20 > + IN BOOLEAN IsTransparent, >=20 > + IN EFI_GRAPHICS_OUTPUT_BLT_PIXEL *BltIn, >=20 > + IN OUT EFI_GRAPHICS_OUTPUT_BLT_PIXEL **BltOut >=20 > + ) >=20 > +{ >=20 > + EFI_GRAPHICS_OUTPUT_BLT_PIXEL *Compound; >=20 > + EFI_GRAPHICS_OUTPUT_BLT_PIXEL *Keyboard; >=20 > + EFI_GRAPHICS_OUTPUT_BLT_PIXEL *Background; >=20 > + UINTN BltSize; >=20 > + >=20 > + if (*BltOut =3D=3D NULL) { >=20 > + *BltOut =3D AllocateZeroPool (VkContext->VkBodyBltSize); >=20 > + if (*BltOut =3D=3D NULL) { >=20 > + return EFI_OUT_OF_RESOURCES; >=20 > + } >=20 > + } >=20 > + Compound =3D *BltOut; >=20 > + Keyboard =3D BltIn; >=20 > + Background =3D VkContext->VkBodyBackgroundBltBuffer; >=20 > + BltSize =3D VkContext->VkBodyBltHeight * VkContext->VkBodyBltWidth; >=20 > + while (BltSize-- !=3D 0) { >=20 > + if (IsTransparent) { >=20 > + Compound->Red =3D (Keyboard->Red * TRANSPARENCY_WEIGHT) / 100 + = (Background->Red * (100 - > TRANSPARENCY_WEIGHT)) / 100; >=20 > + Compound->Green =3D (Keyboard->Green * TRANSPARENCY_WEIGHT) / 100 = + (Background->Green * (100 - > TRANSPARENCY_WEIGHT)) / 100; >=20 > + Compound->Blue =3D (Keyboard->Blue * TRANSPARENCY_WEIGHT) / 100 += (Background->Blue * (100 - > TRANSPARENCY_WEIGHT)) / 100; >=20 > + } else { >=20 > + *Compound =3D *Keyboard; >=20 > + } >=20 > + Compound++; >=20 > + Keyboard++; >=20 > + Background++; >=20 > + } >=20 > + >=20 > + return EFI_SUCCESS; >=20 > +} >=20 > + >=20 > +EFI_STATUS >=20 > +EFIAPI >=20 > +SaveVkBodyBackgroundBltBuffer ( >=20 > + IN VK_CONTEXT *VkContext, >=20 > + IN UINTN BltSize >=20 > + ) >=20 > +{ >=20 > + EFI_STATUS Status; >=20 > + EFI_GRAPHICS_OUTPUT_BLT_PIXEL *CurrentBltBuffer; >=20 > + EFI_GRAPHICS_OUTPUT_BLT_PIXEL *CurrentBltBufferSave; >=20 > + EFI_GRAPHICS_OUTPUT_BLT_PIXEL *OldBltBuffer; >=20 > + EFI_GRAPHICS_OUTPUT_BLT_PIXEL *OldBltBufferSave; >=20 > + EFI_GRAPHICS_OUTPUT_BLT_PIXEL *Compound; >=20 > + EFI_GRAPHICS_OUTPUT_BLT_PIXEL *Background; >=20 > + UINTN Size; >=20 > + >=20 > + CurrentBltBufferSave =3D NULL; >=20 > + OldBltBufferSave =3D NULL; >=20 > + >=20 > + // >=20 > + // Save original blt buffer first. >=20 > + // >=20 > + OldBltBuffer =3D AllocateZeroPool (VkContext->VkBodyBltSize); >=20 > + if (OldBltBuffer =3D=3D NULL) { >=20 > + return EFI_OUT_OF_RESOURCES; >=20 > + } >=20 > + if (VkContext->VkBodyBackgroundBltBuffer !=3D NULL) { >=20 > + CopyMem (OldBltBuffer, VkContext->VkBodyBackgroundBltBuffer, VkConte= xt->VkBodyBltSize); >=20 > + } >=20 > + >=20 > + if (VkContext->VkBodyBackgroundBltBuffer =3D=3D NULL) { >=20 > + VkContext->VkBodyBltSize =3D BltSize; >=20 > + VkContext->VkBodyBackgroundBltBuffer =3D AllocateZeroPool (VkContext= ->VkBodyBltSize); >=20 > + ASSERT (VkContext->VkBodyBackgroundBltBuffer !=3D NULL); >=20 > + if (VkContext->VkBodyBackgroundBltBuffer =3D=3D NULL) { >=20 > + return EFI_OUT_OF_RESOURCES; >=20 > + } >=20 > + } else if (BltSize > VkContext->VkBodyBltSize) { >=20 > + VkContext->VkBodyBltSize =3D BltSize; >=20 > + FreePool (VkContext->VkBodyBackgroundBltBuffer); >=20 > + VkContext->VkBodyBackgroundBltBuffer =3D NULL; >=20 > + VkContext->VkBodyBackgroundBltBuffer =3D AllocateZeroPool (VkContext= ->VkBodyBltSize); >=20 > + ASSERT (VkContext->VkBodyBackgroundBltBuffer !=3D NULL); >=20 > + if (VkContext->VkBodyBackgroundBltBuffer =3D=3D NULL) { >=20 > + return EFI_OUT_OF_RESOURCES; >=20 > + } >=20 > + } else { >=20 > + ZeroMem (VkContext->VkBodyBackgroundBltBuffer, VkContext->VkBodyBltS= ize); >=20 > + } >=20 > + >=20 > + CurrentBltBuffer =3D NULL; >=20 > + if (VkContext->IsBackgroundChanged =3D=3D TRUE) { >=20 > + // >=20 > + // Background changed, merge current visioning blt buffer with old b= ackground blt buffer. >=20 > + // >=20 > + Compound =3D VkContext->VkBodyCompoundBltBuffer; >=20 > + Background =3D VkContext->VkBodyBackgroundBltBuffer; >=20 > + CurrentBltBuffer =3D AllocateZeroPool (VkContext->VkBodyBltSize); >=20 > + ASSERT (CurrentBltBuffer !=3D NULL); >=20 > + if (CurrentBltBuffer =3D=3D NULL) { >=20 > + return EFI_OUT_OF_RESOURCES; >=20 > + } >=20 > + Status =3D VkContext->GraphicsOutput->Blt ( >=20 > + VkContext->GraphicsOutput, >=20 > + CurrentBltBuffer, >=20 > + EfiBltVideoToBltBuffer, >=20 > + VkContext->VkBodyBltStartX, >=20 > + VkContext->VkBodyBltStartY, >=20 > + 0, >=20 > + 0, >=20 > + VkContext->VkBodyBltWidth, >=20 > + VkContext->VkBodyBltHeight, >=20 > + VkContext->VkBodyBltWidth * si= zeof (EFI_GRAPHICS_OUTPUT_BLT_PIXEL) >=20 > + ); >=20 > + CurrentBltBufferSave =3D CurrentBltBuffer; >=20 > + OldBltBufferSave =3D OldBltBuffer; >=20 > + Size =3D VkContext->VkBodyBltHeight * VkContext->VkBodyBltWidth; >=20 > + while (Size-- !=3D 0) { >=20 > + if ((Compound->Red !=3D CurrentBltBuffer->Red) || >=20 > + (Compound->Green !=3D CurrentBltBuffer->Green) || >=20 > + (Compound->Blue !=3D CurrentBltBuffer->Blue)) { >=20 > + *Background =3D *CurrentBltBuffer; >=20 > + } else { >=20 > + *Background =3D *OldBltBuffer; >=20 > + } >=20 > + Compound++; >=20 > + Background++; >=20 > + CurrentBltBuffer++; >=20 > + OldBltBuffer++; >=20 > + } >=20 > + } else { >=20 > + // >=20 > + // Background NOT changed, save it to VkBodyBackgroundBltBuffer dire= ctly. >=20 > + // >=20 > + Status =3D VkContext->GraphicsOutput->Blt ( >=20 > + VkContext->GraphicsOutput, >=20 > + VkContext->VkBodyBackgroundBlt= Buffer, >=20 > + EfiBltVideoToBltBuffer, >=20 > + VkContext->VkBodyBltStartX, >=20 > + VkContext->VkBodyBltStartY, >=20 > + 0, >=20 > + 0, >=20 > + VkContext->VkBodyBltWidth, >=20 > + VkContext->VkBodyBltHeight, >=20 > + VkContext->VkBodyBltWidth * si= zeof (EFI_GRAPHICS_OUTPUT_BLT_PIXEL) >=20 > + ); >=20 > + } >=20 > + >=20 > + if (CurrentBltBufferSave !=3D NULL) { >=20 > + FreePool (CurrentBltBufferSave); >=20 > + } >=20 > + if (OldBltBufferSave !=3D NULL) { >=20 > + FreePool (OldBltBufferSave); >=20 > + } >=20 > + >=20 > + return Status; >=20 > +} >=20 > + >=20 > +EFI_STATUS >=20 > +EFIAPI >=20 > +RestoreVkBodyBackgroundBltBuffer ( >=20 > + IN VK_CONTEXT *VkContext >=20 > + ) >=20 > +{ >=20 > + EFI_STATUS Status; >=20 > + >=20 > + if (VkContext->VkBodyBackgroundBltBuffer =3D=3D NULL) { >=20 > + return EFI_UNSUPPORTED; >=20 > + } >=20 > + >=20 > + Status =3D VkContext->GraphicsOutput->Blt ( >=20 > + VkContext->GraphicsOutput, >=20 > + VkContext->VkBodyBackgroundBltBu= ffer, >=20 > + EfiBltBufferToVideo, >=20 > + 0, >=20 > + 0, >=20 > + VkContext->VkBodyBltStartX, >=20 > + VkContext->VkBodyBltStartY, >=20 > + VkContext->VkBodyBltWidth, >=20 > + VkContext->VkBodyBltHeight, >=20 > + VkContext->VkBodyBltWidth * size= of (EFI_GRAPHICS_OUTPUT_BLT_PIXEL) >=20 > + ); >=20 > + >=20 > + FreePool (VkContext->VkBodyBackgroundBltBuffer); >=20 > + VkContext->VkBodyBackgroundBltBuffer =3D NULL; >=20 > + >=20 > + return Status; >=20 > +} >=20 > + >=20 > +EFI_STATUS >=20 > +SetCharacterPosition ( >=20 > + IN VK_CONTEXT *VkContext, >=20 > + IN UINT32 DestX, >=20 > + IN UINT32 DestY >=20 > + ) >=20 > +{ >=20 > + UINTN Index; >=20 > + VK_STRUCT *KeyArryPtr; >=20 > + UINT32 KeyArrySize; >=20 > + >=20 > + switch (VkContext->TargetKeyboardDisplay) { >=20 > + case VkDisplayAttributeSimpleTop: >=20 > + case VkDisplayAttributeSimpleBottom: >=20 > + KeyArryPtr =3D mSimpleKeyboardBody; >=20 > + KeyArrySize =3D DIM (mSimpleKeyboardBody); >=20 > + break; >=20 > + >=20 > + case VkDisplayAttributeFullBottom: >=20 > + case VkDisplayAttributeFullTop: >=20 > + KeyArryPtr =3D mFullKeyboardBody; >=20 > + KeyArrySize =3D DIM (mFullKeyboardBody); >=20 > + break; >=20 > + >=20 > + case VkDisplayAttributeNone: >=20 > + KeyArryPtr =3D mFullKeyboardBody; >=20 > + KeyArrySize =3D DIM (mFullKeyboardBody); >=20 > + break; >=20 > + >=20 > + default: >=20 > + return EFI_UNSUPPORTED; >=20 > + } >=20 > + >=20 > + for (Index =3D 0; Index < KeyArrySize; Index++) { >=20 > + VkContext->KeyboardBodyPtr[Index] =3D KeyArryPtr[Index]; >=20 > + } >=20 > + VkContext->NumOfKeysInfo =3D KeyArrySize; >=20 > + >=20 > + for (Index =3D 0; Index < (VkContext->NumOfKeysInfo - 4); Index++) { >=20 > + VkContext->KeyboardBodyPtr[Index].DisStartX +=3D (UINT16)DestX; >=20 > + VkContext->KeyboardBodyPtr[Index].DisStartY +=3D (UINT16)DestY; >=20 > + VkContext->KeyboardBodyPtr[Index].DisEndX +=3D (UINT16)DestX; >=20 > + VkContext->KeyboardBodyPtr[Index].DisEndY +=3D (UINT16)DestY; >=20 > + } >=20 > + >=20 > + return EFI_SUCCESS; >=20 > +} >=20 > + >=20 > +EFI_STATUS >=20 > +EFIAPI >=20 > +SaveVkIconBackgroundBltBuffer ( >=20 > + IN VK_CONTEXT *VkContext, >=20 > + IN VK_DISPLAY_ATTRIBUTE IconType >=20 > + ) >=20 > +{ >=20 > + EFI_STATUS Status; >=20 > + EFI_GRAPHICS_OUTPUT_BLT_PIXEL *GraphicBlt; >=20 > + UINTN BltSize; >=20 > + UINTN Height; >=20 > + UINTN Width; >=20 > + INTN StartX; >=20 > + INTN StartY; >=20 > + EFI_GRAPHICS_OUTPUT_BLT_PIXEL *TempIconBackBuffer; >=20 > + EFI_GRAPHICS_OUTPUT_BLT_PIXEL *IconBackBuffer; >=20 > + EFI_GRAPHICS_OUTPUT_BLT_PIXEL *Compound; >=20 > + UINTN Size; >=20 > + BOOLEAN SaveCursor; >=20 > + >=20 > + Status =3D EFI_SUCCESS; >=20 > + StartX =3D 0; >=20 > + StartY =3D 0; >=20 > + TempIconBackBuffer =3D NULL; >=20 > + IconBackBuffer =3D NULL; >=20 > + Compound =3D NULL; >=20 > + >=20 > + if ((IconType =3D=3D VkDisplayAttributeFullTop) || >=20 > + (IconType =3D=3D VkDisplayAttributeSimpleTop)) { >=20 > + return EFI_SUCCESS; >=20 > + } >=20 > + >=20 > + SaveCursor =3D gST->ConOut->Mode->CursorVisible; >=20 > + gST->ConOut->EnableCursor (gST->ConOut, FALSE); >=20 > + >=20 > + if (IconType =3D=3D VkDisplayAttributeFullBottom) { >=20 > + GraphicBlt =3D VkContext->FullIcon->Bitmap; >=20 > + BltSize =3D VkContext->FullIcon->Height * VkContext->FullIcon->Wi= dth * sizeof (EFI_GRAPHICS_OUTPUT_BLT_PIXEL); >=20 > + Height =3D VkContext->FullIcon->Height; >=20 > + Width =3D VkContext->FullIcon->Width; >=20 > + StartX =3D VkContext->FullIconBackStartX; >=20 > + StartY =3D VkContext->FullIconBackStartY; >=20 > + } else if (IconType =3D=3D VkDisplayAttributeSimpleBottom) { >=20 > + GraphicBlt =3D VkContext->SmallIcon->Bitmap; >=20 > + BltSize =3D VkContext->SmallIcon->Height * VkContext->SmallIcon->= Width * sizeof (EFI_GRAPHICS_OUTPUT_BLT_PIXEL); >=20 > + Height =3D VkContext->SmallIcon->Height; >=20 > + Width =3D VkContext->SmallIcon->Width; >=20 > + StartX =3D VkContext->SimIconBackStartX; >=20 > + StartY =3D VkContext->SimIconBackStartY; >=20 > + } else { >=20 > + gST->ConOut->EnableCursor (gST->ConOut, SaveCursor); >=20 > + return EFI_UNSUPPORTED; >=20 > + } >=20 > + >=20 > + IconBackBuffer =3D AllocateZeroPool (BltSize); >=20 > + if (IconBackBuffer =3D=3D NULL) { >=20 > + gST->ConOut->EnableCursor (gST->ConOut, SaveCursor); >=20 > + return EFI_OUT_OF_RESOURCES; >=20 > + } >=20 > + TempIconBackBuffer =3D IconBackBuffer; >=20 > + Status =3D VkContext->GraphicsOutput->Blt ( >=20 > + VkContext->GraphicsOutput, >=20 > + IconBackBuffer, >=20 > + EfiBltVideoToBltBuffer, >=20 > + StartX, >=20 > + StartY, >=20 > + 0, >=20 > + 0, >=20 > + Width, >=20 > + Height, >=20 > + Width * sizeof (EFI_GRAPHICS_OUT= PUT_BLT_PIXEL) >=20 > + ); >=20 > + >=20 > + if (IconType =3D=3D VkDisplayAttributeFullBottom) { >=20 > + // >=20 > + // Store full icon background framebuffer >=20 > + // >=20 > + VkContext->FullIconBackHeight =3D Height; >=20 > + VkContext->FullIconBackWidth =3D Width; >=20 > + if (VkContext->FullIconUpdatedFlag =3D=3D FALSE) { >=20 > + // >=20 > + // No icon draw, save the buffer directly. >=20 > + // >=20 > + if (VkContext->FullIconBackBuffer =3D=3D NULL) { >=20 > + VkContext->FullIconBackBuffer =3D AllocateZeroPool (BltSize); >=20 > + VkContext->FullIconBackSize =3D BltSize; >=20 > + } >=20 > + CopyMem (VkContext->FullIconBackBuffer, IconBackBuffer, BltSize); >=20 > + VkContext->FullIconUpdatedFlag =3D TRUE; >=20 > + } else { >=20 > + if (CompareMem (VkContext->FullIconBackBuffer, IconBackBuffer, Blt= Size) !=3D 0) { >=20 > + Compound =3D VkContext->FullIconBackBuffer; >=20 > + Size =3D Height * Width; >=20 > + while (Size-- !=3D 0) { >=20 > + if ((GraphicBlt->Red !=3D IconBackBuffer->Red) || >=20 > + (GraphicBlt->Green !=3D IconBackBuffer->Green) || >=20 > + (GraphicBlt->Blue !=3D IconBackBuffer->Blue)) { >=20 > + *Compound =3D *IconBackBuffer; >=20 > + } >=20 > + Compound++; >=20 > + GraphicBlt++; >=20 > + IconBackBuffer++; >=20 > + } >=20 > + } >=20 > + } >=20 > + } else if (IconType =3D=3D VkDisplayAttributeSimpleBottom) { >=20 > + // >=20 > + // Store simple icon background framebuffer >=20 > + // >=20 > + VkContext->SimIconBackHeight =3D Height; >=20 > + VkContext->SimIconBackWidth =3D Width; >=20 > + if (VkContext->SimIconUpdatedFlag =3D=3D FALSE) { >=20 > + // >=20 > + // No icon draw, save the buffer directly. >=20 > + // >=20 > + if (VkContext->SimIconBackBuffer =3D=3D NULL) { >=20 > + VkContext->SimIconBackBuffer =3D AllocateZeroPool (BltSize); >=20 > + VkContext->SimIconBackSize =3D BltSize; >=20 > + } >=20 > + CopyMem (VkContext->SimIconBackBuffer, IconBackBuffer, BltSize); >=20 > + VkContext->SimIconUpdatedFlag =3D TRUE; >=20 > + } else { >=20 > + if (CompareMem (VkContext->SimIconBackBuffer, IconBackBuffer, BltS= ize) !=3D 0) { >=20 > + Compound =3D VkContext->SimIconBackBuffer; >=20 > + Size =3D Height * Width; >=20 > + while (Size-- !=3D 0) { >=20 > + if ((GraphicBlt->Red !=3D IconBackBuffer->Red) || >=20 > + (GraphicBlt->Green !=3D IconBackBuffer->Green) || >=20 > + (GraphicBlt->Blue !=3D IconBackBuffer->Blue)) { >=20 > + *Compound =3D *IconBackBuffer; >=20 > + } >=20 > + Compound++; >=20 > + GraphicBlt++; >=20 > + IconBackBuffer++; >=20 > + } >=20 > + } >=20 > + } >=20 > + } >=20 > + >=20 > + if (TempIconBackBuffer !=3D NULL) FreePool (TempIconBackBuffer); >=20 > + >=20 > + gST->ConOut->EnableCursor (gST->ConOut, SaveCursor); >=20 > + return Status; >=20 > +} >=20 > + >=20 > +/** >=20 > + Use to draw the keyboard icon. >=20 > + >=20 > + @param[in] VkContext Pointer to virtual keyboard's context >=20 > + @param[in] VkImage Image of keyboard to display on the screen. >=20 > + @param[in] Attribute Attribute of keyboard to display on the screen. >=20 > + >=20 > + @retval EFI_SUCCESS ConsoleControl has been flipped to graph= ics and keyboard icon displayed. >=20 > + @retval EFI_UNSUPPORTED KeyboardFile not found >=20 > + @retval EFI_INVALID_PARAMETER Attribute is unknown. >=20 > + >=20 > +**/ >=20 > +EFI_STATUS >=20 > +EFIAPI >=20 > +DrawVkIcon ( >=20 > + IN VK_CONTEXT *VkContext, >=20 > + IN EFI_IMAGE_INPUT *VkImage, >=20 > + IN VK_DISPLAY_ATTRIBUTE Attribute >=20 > + ) >=20 > +{ >=20 > + EFI_STATUS Status; >=20 > + UINT32 SizeOfX; >=20 > + UINT32 SizeOfY; >=20 > + INTN DestX; >=20 > + INTN DestY; >=20 > + UINTN CoordinateX; >=20 > + UINTN CoordinateY; >=20 > + EFI_GRAPHICS_OUTPUT_PROTOCOL *GraphicsOutput; >=20 > + EFI_GRAPHICS_OUTPUT_BLT_PIXEL *Blt; >=20 > + UINTN BltSize; >=20 > + UINTN Height; >=20 > + UINTN Width; >=20 > + >=20 > + Status =3D EFI_SUCCESS; >=20 > + GraphicsOutput =3D VkContext->GraphicsOutput; >=20 > + SizeOfX =3D GraphicsOutput->Mode->Info->HorizontalResolution; >=20 > + SizeOfY =3D GraphicsOutput->Mode->Info->VerticalResolution; >=20 > + CoordinateX =3D 0; >=20 > + CoordinateY =3D 0; >=20 > + Height =3D VkImage->Height; >=20 > + Width =3D VkImage->Width; >=20 > + Blt =3D VkImage->Bitmap; >=20 > + BltSize =3D sizeof (EFI_GRAPHICS_OUTPUT_BLT_PIXEL) * (UINT32)(W= idth * Height); >=20 > + >=20 > + // >=20 > + // Calculate the display position according to Attribute. >=20 > + // >=20 > + switch (Attribute) { >=20 > + case VkDisplayAttributeSimpleTop: >=20 > + DestX =3D CoordinateX; >=20 > + DestY =3D CoordinateY; >=20 > + break; >=20 > + >=20 > + case VkDisplayAttributeFullTop: >=20 > + DestX =3D (SizeOfX - Width - CoordinateX); >=20 > + DestY =3D CoordinateY;; >=20 > + break; >=20 > + >=20 > + case VkDisplayAttributeFullBottom: >=20 > + DestX =3D (SizeOfX - Width - CoordinateX); >=20 > + DestY =3D (SizeOfY - Height - CoordinateY); >=20 > + VkContext->FullIconBackStartX =3D DestX; >=20 > + VkContext->FullIconBackStartY =3D DestY; >=20 > + break; >=20 > + >=20 > + case VkDisplayAttributeSimpleBottom: >=20 > + DestX =3D CoordinateX; >=20 > + DestY =3D (SizeOfY - Height - CoordinateY); >=20 > + >=20 > + // >=20 > + // Save to check icon/screen cleared >=20 > + // >=20 > + if (VkContext->IconBltBuffer =3D=3D NULL) { >=20 > + VkContext->IconBltSize =3D BltSize; >=20 > + VkContext->IconBltWidth =3D Width; >=20 > + VkContext->IconBltHeight =3D Height; >=20 > + VkContext->IconBltBuffer =3D AllocateZeroPool (BltSize); >=20 > + } >=20 > + CopyMem (VkContext->IconBltBuffer, Blt, VkContext->IconBltSize); >=20 > + >=20 > + VkContext->SimIconBackStartX =3D DestX; >=20 > + VkContext->SimIconBackStartY =3D DestY; >=20 > + break; >=20 > + >=20 > + case VkDisplayAttributeNone: >=20 > + return EFI_SUCCESS; >=20 > + >=20 > + default: >=20 > + return EFI_INVALID_PARAMETER; >=20 > + } >=20 > + >=20 > + if ((DestX >=3D 0) && (DestY >=3D 0)) { >=20 > + // >=20 > + // Store icon background framebuffer >=20 > + // >=20 > + SaveVkIconBackgroundBltBuffer (VkContext, Attribute); >=20 > + Status =3D GraphicsOutput->Blt ( >=20 > + GraphicsOutput, >=20 > + Blt, >=20 > + EfiBltBufferToVideo, >=20 > + 0, >=20 > + 0, >=20 > + (UINTN) DestX, >=20 > + (UINTN) DestY, >=20 > + Width, >=20 > + Height, >=20 > + Width * sizeof (EFI_GRAPHICS_OUTPUT_BLT_P= IXEL) >=20 > + ); >=20 > + } >=20 > + >=20 > + return Status; >=20 > +} >=20 > + >=20 > +/** >=20 > + Use to draw the keyboard. >=20 > + >=20 > + @param[in] VkContext Pointer to virtual keyboard's context >=20 > + @param[in] VkImage Image of keyboard to display on the screen. >=20 > + @param[in] Attribute Attribute of keyboard to display on the screen. >=20 > + >=20 > + @retval EFI_SUCCESS ConsoleControl has been flipped to graph= ics and keyboard displayed. >=20 > + @retval EFI_UNSUPPORTED KeyboardFile not found >=20 > + @retval EFI_INVALID_PARAMETER Attribute is unknown. >=20 > + >=20 > +**/ >=20 > +EFI_STATUS >=20 > +EFIAPI >=20 > +DrawVkBody ( >=20 > + IN VK_CONTEXT *VkContext, >=20 > + IN EFI_IMAGE_INPUT *VkImage, >=20 > + IN VK_DISPLAY_ATTRIBUTE Attribute >=20 > + ) >=20 > +{ >=20 > + EFI_STATUS Status; >=20 > + UINT32 SizeOfX; >=20 > + UINT32 SizeOfY; >=20 > + INTN DestX; >=20 > + INTN DestY; >=20 > + UINTN BltSize; >=20 > + UINTN Height; >=20 > + UINTN Width; >=20 > + UINTN CoordinateY; >=20 > + EFI_GRAPHICS_OUTPUT_BLT_PIXEL *BltIn; >=20 > + EFI_GRAPHICS_OUTPUT_PROTOCOL *GraphicsOutput; >=20 > + >=20 > + Status =3D EFI_SUCCESS; >=20 > + GraphicsOutput =3D VkContext->GraphicsOutput; >=20 > + SizeOfX =3D GraphicsOutput->Mode->Info->HorizontalResolution; >=20 > + SizeOfY =3D GraphicsOutput->Mode->Info->VerticalResolution; >=20 > + CoordinateY =3D 0; >=20 > + Height =3D VkImage->Height; >=20 > + Width =3D VkImage->Width; >=20 > + BltSize =3D sizeof (EFI_GRAPHICS_OUTPUT_BLT_PIXEL) * (UINT32)(W= idth * Height); >=20 > + BltIn =3D AllocateCopyPool (BltSize, VkImage->Bitmap); >=20 > + >=20 > + if (BltIn =3D=3D NULL) { >=20 > + return EFI_OUT_OF_RESOURCES; >=20 > + } >=20 > + >=20 > + // >=20 > + // Calculate the display position according to Attribute. >=20 > + // >=20 > + switch (Attribute) { >=20 > + case VkDisplayAttributeSimpleTop: >=20 > + DestX =3D ((SizeOfX / 2) - Width) / 4; >=20 > + DestY =3D CoordinateY; >=20 > + VkContext->CurrentKeyboardDisplay =3D VkDisplayAttributeSimpleTop; >=20 > + break; >=20 > + >=20 > + case VkDisplayAttributeSimpleBottom: >=20 > + DestX =3D ((SizeOfX / 2) - Width) / 4; >=20 > + DestY =3D (SizeOfY - Height - CoordinateY); >=20 > + VkContext->CurrentKeyboardDisplay =3D VkDisplayAttributeSimpleBottom= ; >=20 > + break; >=20 > + >=20 > + case VkDisplayAttributeFullTop: >=20 > + DestX =3D (SizeOfX - Width) / 2; >=20 > + DestY =3D CoordinateY; >=20 > + VkContext->CurrentKeyboardDisplay =3D VkDisplayAttributeFullTop; >=20 > + break; >=20 > + >=20 > + case VkDisplayAttributeFullBottom: >=20 > + DestX =3D (SizeOfX - Width) / 2; >=20 > + DestY =3D (SizeOfY - Height - CoordinateY); >=20 > + VkContext->CurrentKeyboardDisplay =3D VkDisplayAttributeFullBottom; >=20 > + break; >=20 > + >=20 > + case VkDisplayAttributeNone: >=20 > + VkContext->CurrentKeyboardDisplay =3D VkDisplayAttributeNone; >=20 > + goto DVKBODY_Exit; >=20 > + >=20 > + default: >=20 > + VkContext->CurrentKeyboardDisplay =3D VkDisplayAttributeNone; >=20 > + Status =3D EFI_INVALID_PARAMETER; >=20 > + goto DVKBODY_Exit; >=20 > + } >=20 > + if ((DestX >=3D 0) && (DestY >=3D 0)) { >=20 > + SetCharacterPosition (VkContext, (UINT32)DestX, (UINT32)DestY); >=20 > + >=20 > + // >=20 > + // Store current framebuffer >=20 > + // >=20 > + VkContext->VkBodyBltStartX =3D DestX; >=20 > + VkContext->VkBodyBltStartY =3D DestY; >=20 > + VkContext->VkBodyBltHeight =3D Height; >=20 > + VkContext->VkBodyBltWidth =3D Width; >=20 > + SaveVkBodyBackgroundBltBuffer (VkContext, BltSize); >=20 > + >=20 > + // >=20 > + // Free compound buffer first. >=20 > + // >=20 > + if (VkContext->VkBodyCompoundBltBuffer !=3D NULL) { >=20 > + FreePool (VkContext->VkBodyCompoundBltBuffer); >=20 > + } >=20 > + VkContext->VkBodyCompoundBltBuffer =3D NULL; >=20 > + ModifyShiftKeyColor (VkContext, &BltIn); >=20 > + MakeKeyboardTransparent (VkContext, TRUE, BltIn, &(VkContext->VkBody= CompoundBltBuffer)); >=20 > + >=20 > + // >=20 > + // Draw keyboard body >=20 > + // >=20 > + Status =3D GraphicsOutput->Blt ( >=20 > + GraphicsOutput, >=20 > + VkContext->VkBodyCompoundBltBuffer, >=20 > + EfiBltBufferToVideo, >=20 > + 0, >=20 > + 0, >=20 > + (UINTN) DestX, >=20 > + (UINTN) DestY, >=20 > + Width, >=20 > + Height, >=20 > + Width * sizeof (EFI_GRAPHICS_OUTPUT_BLT_P= IXEL) >=20 > + ); >=20 > + } >=20 > + >=20 > + >=20 > +DVKBODY_Exit: >=20 > + if (BltIn !=3D NULL) { >=20 > + FreePool (BltIn); >=20 > + } >=20 > + >=20 > + return Status; >=20 > +} >=20 > + >=20 > +/** >=20 > + Clear the keyboard body >=20 > + >=20 > + @param VkContext Code context. >=20 > + >=20 > + @retval EFI_SUCCESS Clear rectangle is done. >=20 > + >=20 > +**/ >=20 > +EFI_STATUS >=20 > +HideVkBody ( >=20 > + IN VK_CONTEXT *VkContext >=20 > + ) >=20 > +{ >=20 > + RestoreVkBodyBackgroundBltBuffer (VkContext); >=20 > + VkContext->CurrentKeyboardDisplay =3D VkDisplayAttributeNone; >=20 > + >=20 > + return EFI_SUCCESS; >=20 > +} >=20 > + >=20 > + >=20 > +/** >=20 > + Clear the keyboard icon >=20 > + >=20 > + @param VkContext Code context. >=20 > + >=20 > + @retval EFI_SUCCESS Clear rectangle is done. >=20 > + >=20 > +**/ >=20 > +EFI_STATUS >=20 > +HideVkIcon ( >=20 > + IN VK_CONTEXT *VkContext >=20 > + ) >=20 > +{ >=20 > + EFI_STATUS Status; >=20 > + >=20 > + if ((VkContext->FullIconBackBuffer =3D=3D NULL) || (VkContext->SimIcon= BackBuffer =3D=3D NULL)) { >=20 > + return EFI_UNSUPPORTED; >=20 > + } >=20 > + >=20 > + if ((VkContext->FullIconUpdatedFlag =3D=3D FALSE) || (VkContext->SimIc= onUpdatedFlag =3D=3D FALSE)) { >=20 > + return EFI_UNSUPPORTED; >=20 > + } >=20 > + Status =3D VkContext->GraphicsOutput->Blt ( >=20 > + VkContext->GraphicsOutput, >=20 > + VkContext->FullIconBackBuffer, >=20 > + EfiBltBufferToVideo, >=20 > + 0, >=20 > + 0, >=20 > + VkContext->FullIconBackStartX, >=20 > + VkContext->FullIconBackStartY, >=20 > + VkContext->FullIconBackWidth, >=20 > + VkContext->FullIconBackHeight, >=20 > + VkContext->FullIconBackWidth * s= izeof (EFI_GRAPHICS_OUTPUT_BLT_PIXEL) >=20 > + ); >=20 > + >=20 > + ZeroMem (VkContext->FullIconBackBuffer, VkContext->FullIconBackSize); >=20 > + VkContext->FullIconUpdatedFlag =3D FALSE; >=20 > + >=20 > + >=20 > + Status =3D VkContext->GraphicsOutput->Blt ( >=20 > + VkContext->GraphicsOutput, >=20 > + VkContext->SimIconBackBuffer, >=20 > + EfiBltBufferToVideo, >=20 > + 0, >=20 > + 0, >=20 > + VkContext->SimIconBackStartX, >=20 > + VkContext->SimIconBackStartY, >=20 > + VkContext->SimIconBackWidth, >=20 > + VkContext->SimIconBackHeight, >=20 > + VkContext->SimIconBackWidth * si= zeof (EFI_GRAPHICS_OUTPUT_BLT_PIXEL) >=20 > + ); >=20 > + if (!EFI_ERROR (Status)) { >=20 > + if (VkContext->ScreenCheckBuffer =3D=3D NULL) { >=20 > + VkContext->ScreenCheckBufferSize =3D VkContext->SimIconBackHeight = * >=20 > + VkContext->SimIconBackWidth * >=20 > + sizeof (EFI_GRAPHICS_OUTPUT_BLT= _PIXEL); >=20 > + VkContext->ScreenCheckBuffer =3D AllocateZeroPool (VkContext->Scre= enCheckBufferSize); >=20 > + } >=20 > + >=20 > + CopyMem ( >=20 > + VkContext->ScreenCheckBuffer, >=20 > + VkContext->SimIconBackBuffer, >=20 > + (VkContext->SimIconBackHeight * VkContext->SimIconBackWidth * size= of (EFI_GRAPHICS_OUTPUT_BLT_PIXEL)) >=20 > + ); >=20 > + } >=20 > + ZeroMem (VkContext->SimIconBackBuffer, VkContext->SimIconBackSize); >=20 > + VkContext->SimIconUpdatedFlag =3D FALSE; >=20 > + >=20 > + return EFI_SUCCESS; >=20 > +} >=20 > + >=20 > +/** >=20 > + Draw key board on the display >=20 > + >=20 > + @param[in] VkContext Graphic Protocol for draw the alphabet. >=20 > + >=20 > + @retval EFI_SUCCESS Draw keyboard was done. >=20 > + @retval EFI_UNSUPPORTED Did not get key mapping table. >=20 > + >=20 > +**/ >=20 > +EFI_STATUS >=20 > +DrawKeyboardLayout ( >=20 > + IN VK_CONTEXT *VkContext >=20 > + ) >=20 > +{ >=20 > + EFI_STATUS Status; >=20 > + if (!VkContext->IsIconShowed) { >=20 > + Status =3D DrawVkIcon (VkContext, VkContext->SmallIcon, VkDisplayAtt= ributeSimpleTop); >=20 > + ASSERT_EFI_ERROR (Status); >=20 > + >=20 > + Status =3D DrawVkIcon (VkContext, VkContext->SmallIcon, VkDisplayAtt= ributeSimpleBottom); >=20 > + ASSERT_EFI_ERROR (Status); >=20 > + >=20 > + Status =3D DrawVkIcon (VkContext, VkContext->FullIcon, VkDisplayAtt= ributeFullTop); >=20 > + ASSERT_EFI_ERROR (Status); >=20 > + >=20 > + Status =3D DrawVkIcon (VkContext, VkContext->FullIcon, VkDisplayAtt= ributeFullBottom); >=20 > + ASSERT_EFI_ERROR (Status); >=20 > + VkContext->IsIconShowed =3D TRUE; >=20 > + } >=20 > + >=20 > + if (VkContext->TargetKeyboardDisplay !=3D VkContext->CurrentKeyboardDi= splay) { >=20 > + switch (VkContext->TargetKeyboardDisplay) { >=20 > + case VkDisplayAttributeSimpleTop: >=20 > + case VkDisplayAttributeSimpleBottom: >=20 > + DrawVkBody (VkContext, VkContext->SimKeyBody, VkContext->TargetKey= boardDisplay); >=20 > + break; >=20 > + >=20 > + case VkDisplayAttributeFullTop: >=20 > + case VkDisplayAttributeFullBottom: >=20 > + if (VkContext->PageNumber <=3D VkPage1) { >=20 > + DrawVkBody (VkContext, VkContext->CapLeKeyBody, VkContext->Targe= tKeyboardDisplay); >=20 > + } else { >=20 > + DrawVkBody (VkContext, VkContext->DigKeyBody, VkContext->TargetK= eyboardDisplay); >=20 > + } >=20 > + >=20 > + case VkDisplayAttributeNone: >=20 > + break; >=20 > + >=20 > + default: >=20 > + break; >=20 > + } >=20 > + } >=20 > + >=20 > + return EFI_SUCCESS; >=20 > +} >=20 > + >=20 > +EFI_STATUS >=20 > +KeyboardLayoutHandler ( >=20 > + IN VK_CONTEXT *VkContext, >=20 > + IN UINT32 Index >=20 > + ) >=20 > +{ >=20 > + EFI_STATUS Status; >=20 > + >=20 > + Status =3D EFI_SUCCESS; >=20 > + >=20 > + if (Index =3D=3D (VkContext->NumOfKeysInfo - 4)) { >=20 > + // >=20 > + // Touch the LeftTop icon >=20 > + // >=20 > + if (VkContext->CurrentKeyboardDisplay =3D=3D VkDisplayAttributeSimpl= eTop) { >=20 > + VkContext->TargetKeyboardDisplay =3D VkDisplayAttributeNone; >=20 > + } else { >=20 > + VkContext->TargetKeyboardDisplay =3D VkDisplayAttributeSimpleTop; >=20 > + } >=20 > + } else if (Index =3D=3D (VkContext->NumOfKeysInfo - 3)) { >=20 > + // >=20 > + // Touch the LeftBottom icon >=20 > + // >=20 > + if (VkContext->CurrentKeyboardDisplay =3D=3D VkDisplayAttributeSimpl= eBottom) { >=20 > + VkContext->TargetKeyboardDisplay =3D VkDisplayAttributeNone; >=20 > + } else { >=20 > + VkContext->TargetKeyboardDisplay =3D VkDisplayAttributeSimpleBotto= m; >=20 > + } >=20 > + } else if (Index =3D=3D (VkContext->NumOfKeysInfo - 2)) { >=20 > + // >=20 > + // Touch the RightTop icon >=20 > + // >=20 > + if (VkContext->CurrentKeyboardDisplay =3D=3D VkDisplayAttributeFullT= op) { >=20 > + VkContext->TargetKeyboardDisplay =3D VkDisplayAttributeNone; >=20 > + } else { >=20 > + VkContext->TargetKeyboardDisplay =3D VkDisplayAttributeFullTop; >=20 > + } >=20 > + } else { >=20 > + // >=20 > + // Touch the RightBottom icon >=20 > + // >=20 > + if (VkContext->CurrentKeyboardDisplay =3D=3D VkDisplayAttributeFullB= ottom) { >=20 > + VkContext->TargetKeyboardDisplay =3D VkDisplayAttributeNone; >=20 > + } else { >=20 > + VkContext->TargetKeyboardDisplay =3D VkDisplayAttributeFullBottom; >=20 > + } >=20 > + } >=20 > + >=20 > + if (VkContext->TargetKeyboardDisplay =3D=3D VkDisplayAttributeNone) { >=20 > + // >=20 > + // Just hide the current keyboard >=20 > + // >=20 > + HideVkBody (VkContext); >=20 > + VkContext->KeyTouchedTimeOut =3D VK_REPEAT_TIMEOUT; >=20 > + >=20 > + } else { >=20 > + // >=20 > + // If current keyboard status is NOT none, >=20 > + // hide current keyboard first and then draw the target keyboard >=20 > + // >=20 > + if (VkContext->CurrentKeyboardDisplay !=3D VkDisplayAttributeNone) { >=20 > + HideVkBody (VkContext); >=20 > + } >=20 > + Status =3D DrawKeyboardLayout (VkContext); >=20 > + } >=20 > + >=20 > + return Status; >=20 > +} >=20 > + >=20 > +/** >=20 > + This routine is used to check if icon has been cleared. >=20 > + >=20 > + @param[in] VkContext Pointer to virtual keyboard's context >=20 > + >=20 > + @retval EFI_SUCCESS Function completed. >=20 > + >=20 > +**/ >=20 > +EFI_STATUS >=20 > +CheckIconCleared ( >=20 > + IN VK_CONTEXT *VkContext >=20 > + ) >=20 > +{ >=20 > + EFI_STATUS Status; >=20 > + UINT32 VerticalResolution; >=20 > + EFI_GRAPHICS_OUTPUT_BLT_PIXEL *BltBuffer; >=20 > + >=20 > + Status =3D EFI_SUCCESS; >=20 > + BltBuffer =3D NULL; >=20 > + VkContext->IconReDrawCheck++; >=20 > + if (VkContext->IconReDrawCheck <=3D 10) { >=20 > + // >=20 > + // Check it every 10 * 100ms. >=20 > + // >=20 > + return Status; >=20 > + } >=20 > + >=20 > + // >=20 > + // Check if right-bottomed region is black, if yes, clean screen happe= ned, need to re-draw keyboard. >=20 > + // >=20 > + VerticalResolution =3D VkContext->GraphicsOutput->Mode->Info->Verti= calResolution; >=20 > + BltBuffer =3D AllocateZeroPool (VkContext->IconBltSize); >=20 > + if (BltBuffer =3D=3D NULL) { >=20 > + return EFI_OUT_OF_RESOURCES; >=20 > + } >=20 > + Status =3D VkContext->GraphicsOutput->Blt ( >=20 > + VkContext->GraphicsOutput, >=20 > + BltBuffer, >=20 > + EfiBltVideoToBltBuffer, >=20 > + 0, >=20 > + (VerticalResolution - VkContext-= >IconBltHeight), >=20 > + 0, >=20 > + 0, >=20 > + VkContext->IconBltWidth, >=20 > + VkContext->IconBltHeight, >=20 > + VkContext->IconBltWidth * sizeof= (EFI_GRAPHICS_OUTPUT_BLT_PIXEL) >=20 > + ); >=20 > + if (EFI_ERROR (Status)) { >=20 > + FreePool (BltBuffer); >=20 > + return Status; >=20 > + } >=20 > + VkContext->IsIconShowed =3D TRUE; >=20 > + if (VkContext->IconBltBuffer =3D=3D NULL) { >=20 > + // >=20 > + // No icon has been drawn. >=20 > + // >=20 > + VkContext->IsIconShowed =3D FALSE; >=20 > + } else { >=20 > + if (CompareMem (BltBuffer, VkContext->IconBltBuffer, VkContext->Icon= BltSize) !=3D 0) { >=20 > + // >=20 > + // Icon has been overridden, need to re-draw. >=20 > + // >=20 > + VkContext->IsIconShowed =3D FALSE; >=20 > + } >=20 > + } >=20 > + >=20 > + if (VkContext->IsIconShowed =3D=3D FALSE) { >=20 > + if (VkContext->ScreenCheckBuffer !=3D NULL) { >=20 > + if (CompareMem (BltBuffer, VkContext->ScreenCheckBuffer, VkContext= ->IconBltSize) =3D=3D 0) { >=20 > + // >=20 > + // Icon has been overridden, force to re-draw the keyboard. >=20 > + // >=20 > + Status =3D DrawKeyboardLayout (VkContext); >=20 > + } else { >=20 > + // >=20 > + // Save blt buffer of icon position and use it to check if icon = is overridden. >=20 > + // >=20 > + CopyMem (VkContext->ScreenCheckBuffer, BltBuffer, VkContext->Ico= nBltSize); >=20 > + } >=20 > + } else { >=20 > + // >=20 > + // Draw the keyboard. >=20 > + // >=20 > + Status =3D DrawKeyboardLayout (VkContext); >=20 > + } >=20 > + } >=20 > + >=20 > + if (BltBuffer !=3D NULL) { >=20 > + FreePool (BltBuffer); >=20 > + } >=20 > + >=20 > + VkContext->IconReDrawCheck =3D 0; >=20 > + >=20 > + return Status; >=20 > +} >=20 > + >=20 > +/** >=20 > + ConvertCoordinate - Convert the touch panel's coordinate to display's = coordinate. >=20 > + >=20 > + @param[in] VkContext Virtual Keyboard context. >=20 > + @param[in] Point The coordinate reported from touch p= anel. >=20 > + @param[out] TouchX The coordinate X converted to displa= y panel. >=20 > + @param[out] TouchY The coordinate Y converted to displa= y panel.. >=20 > + >=20 > + @retval EFI_SUCCESS Convert success. >=20 > + >=20 > +**/ >=20 > +EFI_STATUS >=20 > +ConvertCoordinate ( >=20 > + IN VK_CONTEXT *VkContext, >=20 > + IN EFI_ABSOLUTE_POINTER_STATE Point, >=20 > + OUT UINT32 *TouchX, >=20 > + OUT UINT32 *TouchY >=20 > + ) >=20 > +{ >=20 > + UINT64 AbsoluteMaxX; >=20 > + UINT64 AbsoluteMaxY; >=20 > + UINT32 HorizontalResolution; >=20 > + UINT32 VerticalResolution; >=20 > + >=20 > + AbsoluteMaxX =3D VkContext->AbsolutePointer->Mode->AbsoluteMax= X; >=20 > + AbsoluteMaxY =3D VkContext->AbsolutePointer->Mode->AbsoluteMax= Y; >=20 > + HorizontalResolution =3D VkContext->GraphicsOutput->Mode->Info->Horizo= ntalResolution; >=20 > + VerticalResolution =3D VkContext->GraphicsOutput->Mode->Info->Vertic= alResolution; >=20 > + *TouchX =3D (UINT32) MultU64x32 (Point.CurrentX, Horizont= alResolution) / (UINT32) AbsoluteMaxX; >=20 > + *TouchY =3D (UINT32) MultU64x32 (Point.CurrentY, Vertical= Resolution) / (UINT32) AbsoluteMaxY; >=20 > + >=20 > + return EFI_SUCCESS; >=20 > +} >=20 > + >=20 > +/** >=20 > + This routine is used to check if screen has been cleared. >=20 > + >=20 > + @param[in] VkContext Pointer to virtual keyboard's context >=20 > + >=20 > + @retval EFI_SUCCESS Function completed. >=20 > + >=20 > +**/ >=20 > +EFI_STATUS >=20 > +CheckScreenCleared ( >=20 > + IN VK_CONTEXT *VkContext >=20 > + ) >=20 > +{ >=20 > + EFI_STATUS Status; >=20 > + UINT32 HorizontalResolution; >=20 > + UINT32 VerticalResolution; >=20 > + EFI_GRAPHICS_OUTPUT_BLT_PIXEL *BltBuffer; >=20 > + EFI_GRAPHICS_OUTPUT_BLT_PIXEL *BltBufferIndex; >=20 > + UINTN BltSize; >=20 > + BOOLEAN IsScreenCleared; >=20 > + >=20 > + // >=20 > + // Check left-bottom side. >=20 > + // If IconBltBuffer is null, checking is meaningless. >=20 > + // >=20 > + if (VkContext->IconBltBuffer =3D=3D NULL) { >=20 > + return EFI_SUCCESS; >=20 > + } >=20 > + >=20 > + IsScreenCleared =3D FALSE; >=20 > + Status =3D EFI_SUCCESS; >=20 > + if ((gST->ConOut->Mode->CursorColumn =3D=3D 0) && (gST->ConOut->Mode->= CursorRow =3D=3D 0)) { >=20 > + // >=20 > + // System may call gST->ConOut->ClearScreen >=20 > + // >=20 > + HorizontalResolution =3D VkContext->GraphicsOutput->Mode->Info->Hor= izontalResolution; >=20 > + VerticalResolution =3D VkContext->GraphicsOutput->Mode->Info->Ver= ticalResolution; >=20 > + BltBuffer =3D AllocateZeroPool (VkContext->IconBltSize); >=20 > + if (BltBuffer =3D=3D NULL) { >=20 > + return EFI_OUT_OF_RESOURCES; >=20 > + } >=20 > + >=20 > + BltBufferIndex =3D BltBuffer; >=20 > + Status =3D VkContext->GraphicsOutput->Blt ( >=20 > + VkContext->GraphicsOutput, >=20 > + BltBuffer, >=20 > + EfiBltVideoToBltBuffer, >=20 > + (HorizontalResolution - VkCont= ext->IconBltWidth), >=20 > + (VerticalResolution - VkContex= t->IconBltHeight), >=20 > + 0, >=20 > + 0, >=20 > + VkContext->IconBltWidth, >=20 > + VkContext->IconBltHeight, >=20 > + VkContext->IconBltWidth * size= of (EFI_GRAPHICS_OUTPUT_BLT_PIXEL) >=20 > + ); >=20 > + if (EFI_ERROR (Status)) { >=20 > + FreePool (BltBuffer); >=20 > + return Status; >=20 > + } >=20 > + BltSize =3D VkContext->IconBltHeight * VkContext->IconBltWidth; >=20 > + IsScreenCleared =3D TRUE; >=20 > + while (BltSize-- !=3D 0) { >=20 > + if ((BltBufferIndex->Red !=3D 0) || (BltBufferIndex->Green !=3D 0)= || (BltBufferIndex->Blue !=3D 0)) { >=20 > + IsScreenCleared =3D FALSE; >=20 > + break; >=20 > + } >=20 > + BltBufferIndex++; >=20 > + } >=20 > + FreePool (BltBuffer); >=20 > + } >=20 > + >=20 > + if (IsScreenCleared =3D=3D TRUE) { >=20 > + VkContext->IsIconShowed =3D FALSE; >=20 > + VkContext->CurrentKeyboardDisplay =3D VkDisplayAttributeNone; >=20 > + >=20 > + if (VkContext->VkBodyBackgroundBltBuffer !=3D NULL) { >=20 > + FreePool (VkContext->VkBodyBackgroundBltBuffer); >=20 > + VkContext->VkBodyBackgroundBltBuffer =3D NULL; >=20 > + } >=20 > + >=20 > + if (VkContext->VkBodyCompoundBltBuffer !=3D NULL) { >=20 > + FreePool (VkContext->VkBodyCompoundBltBuffer); >=20 > + VkContext->VkBodyCompoundBltBuffer =3D NULL; >=20 > + } >=20 > + >=20 > + if (VkContext->IconBltBuffer !=3D NULL) { >=20 > + FreePool (VkContext->IconBltBuffer); >=20 > + VkContext->IconBltBuffer =3D NULL; >=20 > + } >=20 > + >=20 > + } >=20 > + >=20 > + return Status; >=20 > +} >=20 > + >=20 > +/** >=20 > + This routine is used to check if background beneath virtual keyboard h= as been cleared. >=20 > + >=20 > + @param[in] VkContext Pointer to virtual keyboard's context >=20 > + >=20 > + @retval EFI_SUCCESS Function completed. >=20 > + >=20 > +**/ >=20 > +EFI_STATUS >=20 > +CheckBackgroundChanged ( >=20 > + IN VK_CONTEXT *VkContext >=20 > + ) >=20 > +{ >=20 > + EFI_STATUS Status; >=20 > + EFI_GRAPHICS_OUTPUT_BLT_PIXEL *BltBuffer; >=20 > + >=20 > + Status =3D EFI_SUCCESS; >=20 > + VkContext->IsBackgroundChanged =3D FALSE; >=20 > + >=20 > + if ((VkContext->CurrentKeyboardDisplay =3D=3D VkDisplayAttributeNone) = || (VkContext->VkBodyCompoundBltBuffer =3D=3D > NULL)) { >=20 > + return EFI_SUCCESS; >=20 > + } >=20 > + >=20 > + BltBuffer =3D AllocateZeroPool (VkContext->VkBodyBltSize); >=20 > + if (BltBuffer =3D=3D NULL) { >=20 > + return EFI_OUT_OF_RESOURCES; >=20 > + } >=20 > + Status =3D VkContext->GraphicsOutput->Blt ( >=20 > + VkContext->GraphicsOutput, >=20 > + BltBuffer, >=20 > + EfiBltVideoToBltBuffer, >=20 > + VkContext->VkBodyBltStartX, >=20 > + VkContext->VkBodyBltStartY, >=20 > + 0, >=20 > + 0, >=20 > + VkContext->VkBodyBltWidth, >=20 > + VkContext->VkBodyBltHeight, >=20 > + VkContext->VkBodyBltWidth * size= of (EFI_GRAPHICS_OUTPUT_BLT_PIXEL) >=20 > + ); >=20 > + if (EFI_ERROR (Status)) { >=20 > + FreePool (BltBuffer); >=20 > + return Status; >=20 > + } >=20 > + if (CompareMem (BltBuffer, VkContext->VkBodyCompoundBltBuffer, VkConte= xt->VkBodyBltSize) !=3D 0) { >=20 > + VkContext->IsBackgroundChanged =3D TRUE; >=20 > + VkContext->CurrentKeyboardDisplay =3D VkDisplayAttributeNone; >=20 > + DrawKeyboardLayout (VkContext); >=20 > + } >=20 > + >=20 > + if (BltBuffer !=3D NULL) { >=20 > + FreePool (BltBuffer); >=20 > + } >=20 > + >=20 > + return Status; >=20 > +} >=20 > + >=20 > +/** >=20 > + Get unicode by VkContext->PageNumber and VkContext->KeyboardBodyPtr. >=20 > + >=20 > + @param[in] VkContext Address of an VK_CONTEXT structure. >=20 > + @param[in] KeyItem Key Item. >=20 > + @param[out] FontPtr Follow VkContext->PageNumber to trans= late >=20 > + font unicode. >=20 > + >=20 > + @retval EFI_SUCCESS Finish translating FontPtr. >=20 > + @retval EFI_INVALID_PARAMETER VkContext or FontPtr is NULL. >=20 > + >=20 > +**/ >=20 > +EFI_STATUS >=20 > +VkGetMappingFont ( >=20 > + IN VK_CONTEXT *VkContext, >=20 > + IN VK_STRUCT KeyItem, >=20 > + OUT UINT32 *FontPtr >=20 > + ) >=20 > +{ >=20 > + if ((VkContext =3D=3D NULL) || (FontPtr =3D=3D NULL) || (VkContext->Pa= geNumber>=3DVkPageMaximum)) { >=20 > + return EFI_INVALID_PARAMETER; >=20 > + } >=20 > + *FontPtr =3D (UINT32) KeyItem.PageFont[VkContext->PageNumber]; >=20 > + >=20 > + return EFI_SUCCESS; >=20 > +} >=20 > diff --git a/Features/Intel/UserInterface/VirtualKeyboardFeaturePkg/Virtu= alKeyboardDxe/KeyboardLayout.idf > b/Features/Intel/UserInterface/VirtualKeyboardFeaturePkg/VirtualKeyboardD= xe/KeyboardLayout.idf > new file mode 100644 > index 0000000000..995bd0d859 > --- /dev/null > +++ b/Features/Intel/UserInterface/VirtualKeyboardFeaturePkg/VirtualKeybo= ardDxe/KeyboardLayout.idf > @@ -0,0 +1,12 @@ > +// /** @file >=20 > +// Virtual Keyboard Layout >=20 > +// >=20 > +// Copyright (c) 2019 - 2020, Intel Corporation. All rights reserved. >=20 > +// >=20 > +// SPDX-License-Identifier: BSD-2-Clause-Patent >=20 > +// >=20 > +#image IMG_VK_CAPITALLETTERKEYBOARD TRANSPARENT CapitalLetterKeyboard.bm= p >=20 > +#image IMG_VK_DIGITKEYBOARD TRANSPARENT DigitKeyboard.bmp >=20 > +#image IMG_VK_FULLICON TRANSPARENT FullIcon.bmp >=20 > +#image IMG_VK_SIMPLEICON TRANSPARENT SimpleIcon.bmp >=20 > +#image IMG_VK_SIMPLEKEYBOARD TRANSPARENT SimpleKeyboard.bmp >=20 > diff --git a/Features/Intel/UserInterface/VirtualKeyboardFeaturePkg/Virtu= alKeyboardDxe/SimpleIcon.bmp > b/Features/Intel/UserInterface/VirtualKeyboardFeaturePkg/VirtualKeyboardD= xe/SimpleIcon.bmp > new file mode 100644 > index 0000000000000000000000000000000000000000..16816f031eb98bf8169c7119b= 95ea3ed1371f41d > GIT binary patch > literal 2814 > zcmeHDu?>JQ41<*mn3%bM1K9bStAMDgEvtknP%#v#jj zvz~tHZ083bZvKJwS=3DAedIaS~0$e`HvNI;OvAp=3D5}kZlld1O%z zE{O5qpp83T)f Lcf5u-&Un3EdmJn} >=20 > literal 0 > HcmV?d00001 >=20 > diff --git a/Features/Intel/UserInterface/VirtualKeyboardFeaturePkg/Virtu= alKeyboardDxe/SimpleKeyboard.bmp > b/Features/Intel/UserInterface/VirtualKeyboardFeaturePkg/VirtualKeyboardD= xe/SimpleKeyboard.bmp > new file mode 100644 > index 0000000000000000000000000000000000000000..3004a534f026fe4906e64480f= 2239b7b7923640b > GIT binary patch > literal 30054 > zcmeI4u} z_unb@zyGS-J?$BL#!R;*ta5dA_1~YXjc085>+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 zIZ%04Y^{*h-QAu2QqzUQ;=3D#h{WP*Usj+(^TpM4G5Rn$!ihjUq_F26AqJ&hGn%r!QH > zRjjU7SMk(yDZ$Xz&&W#W0(;bF6OEM;h_;>!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^xEopADJ z;a47C`Z7?1?3ZViT2O?bOyJ}TAuKI@_s_i?g44PHEBmK9gYeNLW3!6+c^M%q78O10 > zHCy!mEqwEve#WR_YY?YT=3DQxzD14Y}ZGUXP=3D>s7w4Tuv4hGPB z3&Sn85w#8!ZKq0Q=3DO^e=3D=3D_<3FT0)k}tv+VZLCxt@F%kw@!FISbtlUPzRkGp| za3od^S2-Vz9F`Rc(9oLcTy!c1Heou37PfF*S$9^K8?^9nm8{4ib6LX;jB!@ToXe7| > zkjHSLdYQA_SPLuOotjQ4Cq4dVG-C845*Qb_XNV|}6W7D&pX(Wxl};@Vt!t2rG&0GA > z4Z;e-;(uv~YMsYQnzCK1JG3x5bvf7t83B1#=3D*wluLCtU-Q@Dm=3D#aWaat7ipmZk2%* > zZgn~}JFp1T6J%Wsb!T@3clsA|u7%ZNQmt2GRZee{Sh=3Df^9d_O+mGjZaUaYj^^0s|Z > z%n9Zbx+{aq=3DCz%v)M%{gWW`V13)Gbn%kT4Pd$sBbvW~9Wdu8htY-_Nyi#5&tUNlcB > zPOWn+b@olTVXR7~-z!Ghu8frq>g)mQsuzcnV3pcf<%wljSw{_6f!*qA8OT$p_Nc$9 > zicC_T#wtZ7`WvgrB;{$WQe>jPv5HJmp2jLg#`z5t_RhcFL#mpNFqJe}RZe6(>?H65 > D{aYn_ >=20 > literal 0 > HcmV?d00001 >=20 > diff --git a/Features/Intel/UserInterface/VirtualKeyboardFeaturePkg/Virtu= alKeyboardDxe/VirtualKeyboard.h > b/Features/Intel/UserInterface/VirtualKeyboardFeaturePkg/VirtualKeyboardD= xe/VirtualKeyboard.h > new file mode 100644 > index 0000000000..debd4346c7 > --- /dev/null > +++ b/Features/Intel/UserInterface/VirtualKeyboardFeaturePkg/VirtualKeybo= ardDxe/VirtualKeyboard.h > @@ -0,0 +1,777 @@ > +/** @file >=20 > + Header file for Virtual Keyboard driver. >=20 > + >=20 > + Copyright (c) 2012 - 2020, Intel Corporation. All rights reserved.
    >=20 > + SPDX-License-Identifier: BSD-2-Clause-Patent >=20 > + >=20 > +**/ >=20 > + >=20 > +#ifndef _VIRTUAL_KEYBOARD_H_ >=20 > +#define _VIRTUAL_KEYBOARD_H_ >=20 > + >=20 > +#include >=20 > +#include >=20 > +#include >=20 > +#include >=20 > +#include >=20 > +#include >=20 > +#include >=20 > +#include >=20 > +#include >=20 > +#include >=20 > +#include >=20 > +#include >=20 > +#include >=20 > +#include >=20 > +#include >=20 > +#include >=20 > +#include >=20 > +#include >=20 > +#include >=20 > +#include "ComponentName.h" >=20 > + >=20 > +// >=20 > +// Global Variables >=20 > +// >=20 > +extern EFI_DRIVER_BINDING_PROTOCOL gVirtualKeyboardDriverBinding; >=20 > +extern EFI_COMPONENT_NAME_PROTOCOL gVirtualKeyboardComponentName; >=20 > +extern EFI_COMPONENT_NAME2_PROTOCOL gVirtualKeyboardComponentName2; >=20 > + >=20 > +/// >=20 > +/// Debug raw data points >=20 > +/// >=20 > +#define DEBUG_VK_POINTS 0x40000000 >=20 > + >=20 > +/// >=20 > +/// Debug data point scaling >=20 > +/// >=20 > +#define DEBUG_VK_POINT_SCALING 0x20000000 >=20 > + >=20 > +/// >=20 > +/// Debug key press >=20 > +/// >=20 > +#define DEBUG_VK_KEYS 0x10000000 >=20 > + >=20 > +/// >=20 > +/// Debug routine entry and exit >=20 > +/// >=20 > +#define DEBUG_VK_ROUTINE_ENTRY_EXIT 0x08000000 >=20 > + >=20 > +/// >=20 > +/// Display the graphics info >=20 > +/// >=20 > +#define DEBUG_VK_GRAPHICS_INFO 0x04000000 >=20 > + >=20 > +/// >=20 > +/// Display the timer entry and exit >=20 > +/// >=20 > +#define DEBUG_VK_TIMER_ENTRY_EXIT 0x00100000 >=20 > + >=20 > +/// >=20 > +/// Signature >=20 > +/// >=20 > +#define VK_SIGNATURE SIGNATURE_32 ('V', 'K', 'e', 'y') >=20 > +#define VK_NOTIFY_SIGNATURE SIGNATURE_32 ('V', 'K', 'n', 's') >=20 > + >=20 > +/// >=20 > +/// Poll interval >=20 > +/// >=20 > +#define VK_POLL_INTERVAL (1000 * 1000) >=20 > + >=20 > +/// >=20 > +/// Define the touch timeout in poll intervals >=20 > +/// >=20 > +#define VK_REPEAT_TIMEOUT 5 >=20 > + >=20 > +/// >=20 > +/// TPL used to synchronize add/remove from list >=20 > +/// >=20 > +#define TPL_VK_SYNC TPL_NOTIFY >=20 > + >=20 > +/// >=20 > +/// Dimension of an array ( number of elements ) >=20 > +/// >=20 > +#define DIM(x) ( sizeof ( x ) / sizeof ( x [ 0 ])) >=20 > + >=20 > +/// >=20 > +/// Define Key buffer >=20 > +/// >=20 > +#define MAX_KEY_BUF_SIZE 64 >=20 > + >=20 > +/// >=20 > +/// Define Transparent Weight >=20 > +/// >=20 > +#define TRANSPARENCY_WEIGHT 50 >=20 > + >=20 > +typedef struct _VK_CONTEXT VK_CONTEXT; >=20 > + >=20 > +typedef enum _VK_KEY_TYPE { >=20 > + VkKeyNull =3D 0x0000 | CHAR_NULL, >=20 > + VkKeyBackspace =3D 0x0000 | CHAR_BACKSPACE, >=20 > + VkKeyTab =3D 0x0000 | CHAR_TAB, >=20 > + VkKeyEnter =3D 0x0000 | CHAR_CARRIAGE_RETURN, >=20 > + VkKeyScanMask =3D 0x1000, >=20 > + VkKeyEsc =3D 0x1000 | SCAN_ESC, >=20 > + VkKeyLeft =3D 0x1000 | SCAN_LEFT, >=20 > + VkKeyRight =3D 0x1000 | SCAN_RIGHT, >=20 > + VkKeyUp =3D 0x1000 | SCAN_UP, >=20 > + VkKeyDown =3D 0x1000 | SCAN_DOWN, >=20 > + VkKeyF1 =3D 0x1000 | SCAN_F1, >=20 > + VkKeyF2 =3D 0x1000 | SCAN_F2, >=20 > + VkKeyF3 =3D 0x1000 | SCAN_F3, >=20 > + VkKeyF4 =3D 0x1000 | SCAN_F4, >=20 > + VkKeyF5 =3D 0x1000 | SCAN_F5, >=20 > + VkKeyF6 =3D 0x1000 | SCAN_F6, >=20 > + VkKeyF7 =3D 0x1000 | SCAN_F7, >=20 > + VkKeyF8 =3D 0x1000 | SCAN_F8, >=20 > + VkKeyF9 =3D 0x1000 | SCAN_F9, >=20 > + VkKeyF10 =3D 0x1000 | SCAN_F10, >=20 > + VkKeyF11 =3D 0x1000 | SCAN_F11, >=20 > + VkKeyF12 =3D 0x1000 | SCAN_F12, >=20 > + VkKeySpecificMask =3D 0x2000, >=20 > + VkKeyShift =3D 0x2000 | 0x0000, >=20 > + VkKeyCapslock =3D 0x2000 | 0x0001, >=20 > + VkKeyTwoPage =3D 0x2000 | 0x0002, >=20 > + VkKeyTypeMaximum =3D 0xFFFF >=20 > +} VK_KEY_TYPE; >=20 > + >=20 > +typedef enum _VK_PAGE_TYPE { >=20 > + // >=20 > + // +---+---+---+---+---+---+---+---+---+---+---+ >=20 > + // | q | w | e | r | t | y | u | i | o | p |=20 > + // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ >=20 > + // | | a | s | d | f | g | h | j | k | l | F2| | Line 1 >=20 > + // +-+---+---+---+---+---+---+---+---+---+---+-+ >=20 > + // |Caps | z | x | c | v | b | n | m |aU |Enter| Line 2 >=20 > + // +-----+---+---+---+---+---+---+---+---+---+-+ >=20 > + // | Esc |12#| Space |aL |aD |aR | | Line 3 >=20 > + // +-----+---+-------------------+---+---+---+-+ >=20 > + // >=20 > + VkPage0, >=20 > + >=20 > + // >=20 > + // +---+---+---+---+---+---+---+---+---+---+---+ >=20 > + // | Q | W | E | R | T | Y | U | I | O | P |=20 > + // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ >=20 > + // | | A | S | D | F | G | H | J | K | L | F2| | Line 1 >=20 > + // +-+---+---+---+---+---+---+---+---+---+---+-+ >=20 > + // |Caps | Z | X | C | V | B | N | M |aU |Enter| Line 2 >=20 > + // +-----+---+---+---+---+---+---+---+---+---+-+ >=20 > + // | Esc |12#| Space |aL |aD |aR | | Line 3 >=20 > + // +-----+---+-------------------+---+---+---+-+ >=20 > + // >=20 > + VkPage1, >=20 > + >=20 > + // >=20 > + // +---+---+---+---+---+---+---+---+---+---+---+ >=20 > + // | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 0 |=20 > + // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ >=20 > + // | |F1 |F2 |F3 |F4 |F5 |F6 |F7 |F8 |F9 |F10| | Line 1 >=20 > + // +-+---+---+---+---+---+---+---+---+---+---+-+ >=20 > + // |Shift| . | ; | ' | , | . | / |F11|F12|Enter| Line 2 >=20 > + // +-----+---+---+---+---+---+---+---+---+---+-+ >=20 > + // | Esc |12#| Space | \ | - | =3D | | Line 3 >=20 > + // +-----+---+-------------------+---+---+---+-+ >=20 > + // >=20 > + VkPage2, >=20 > + >=20 > + // >=20 > + // +---+---+---+---+---+---+---+---+---+---+---+ >=20 > + // | ! | @ | # | $ | % | ^ | & | * | ( | ) |=20 > + // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ >=20 > + // | |F1 |F2 |F3 |F4 |F5 |F6 |F7 |F8 |F9 |F10| | Line 1 >=20 > + // +-+---+---+---+---+---+---+---+---+---+---+-+ >=20 > + // |Shift| ~ | : | " | < | > | ? |F11|F12|Enter| Line 2 >=20 > + // +-----+---+---+---+---+---+---+---+---+---+-+ >=20 > + // | Esc |12#| Space | | | _ | + | | Line 3 >=20 > + // +-----+---+-------------------+---+---+---+-+ >=20 > + // >=20 > + VkPage3, >=20 > + VkPageMaximum >=20 > +} VK_PAGE_TYPE; >=20 > + >=20 > +typedef enum VK_DISPLAY_ATTRIBUTE { >=20 > + VkDisplayAttributeNone, /// No keyboard displayed >=20 > + VkDisplayAttributeFullTop, /// Full keyboard display at top >=20 > + VkDisplayAttributeFullBottom, /// Full keyboard display at bottom >=20 > + VkDisplayAttributeSimpleTop, /// Simple keyboard display at top >=20 > + VkDisplayAttributeSimpleBottom, /// Simple keyboard display at bottom >=20 > + VkDisplayAttributeMaximum >=20 > +} VK_DISPLAY_ATTRIBUTE; >=20 > + >=20 > +typedef struct _VK_STRUCT { >=20 > + UINT16 DisStartX; >=20 > + UINT16 DisStartY; >=20 > + UINT16 DisEndX; >=20 > + UINT16 DisEndY; >=20 > + VK_KEY_TYPE PageFont[VkPageMaximum]; >=20 > +} VK_STRUCT; >=20 > + >=20 > +typedef struct _VK_NOTIFY { >=20 > + UINTN Signature; >=20 > + EFI_KEY_DATA KeyData; >=20 > + EFI_KEY_NOTIFY_FUNCTION KeyNotificationFn; >=20 > + LIST_ENTRY NotifyEntry; >=20 > +} VK_NOTIFY; >=20 > + >=20 > +/// >=20 > +/// Virtual Keyboard context >=20 > +/// >=20 > +struct _VK_CONTEXT { >=20 > + /// >=20 > + /// Structure identification >=20 > + /// >=20 > + UINTN Signature; >=20 > + >=20 > + /// >=20 > + /// Controller Handle >=20 > + /// >=20 > + EFI_HANDLE Controller; >=20 > + >=20 > + /// >=20 > + /// Upper level API >=20 > + /// >=20 > + EFI_SIMPLE_TEXT_INPUT_PROTOCOL SimpleTextIn; >=20 > + >=20 > + /// >=20 > + /// Simple Text In EX >=20 > + /// >=20 > + EFI_SIMPLE_TEXT_INPUT_EX_PROTOCOL SimpleTextInEx; >=20 > + >=20 > + /// >=20 > + /// Lower level APIs >=20 > + /// >=20 > + EFI_ABSOLUTE_POINTER_PROTOCOL *AbsolutePointer; >=20 > + EFI_GRAPHICS_OUTPUT_PROTOCOL *GraphicsOutput; >=20 > + >=20 > + /// >=20 > + /// Flag when the last poll indicated a touch event >=20 > + /// >=20 > + BOOLEAN TouchActive; >=20 > + >=20 > + /// >=20 > + /// Time to poll for touch input >=20 > + /// >=20 > + EFI_EVENT TimerEvent; >=20 > + >=20 > + /// >=20 > + /// HII handle to get image data used >=20 > + /// >=20 > + EFI_HII_HANDLE HiiHandle; >=20 > + EFI_HII_IMAGE_EX_PROTOCOL *HiiImageEx; >=20 > + >=20 > + /// >=20 > + /// Keyboard body background buffer information >=20 > + /// >=20 > + EFI_GRAPHICS_OUTPUT_BLT_PIXEL *VkBodyBackgroundBltBuffer; >=20 > + EFI_GRAPHICS_OUTPUT_BLT_PIXEL *VkBodyCompoundBltBuffer; >=20 > + UINTN VkBodyBltSize; >=20 > + UINTN VkBodyBltStartX; >=20 > + UINTN VkBodyBltStartY; >=20 > + UINTN VkBodyBltHeight; >=20 > + UINTN VkBodyBltWidth; >=20 > + BOOLEAN IsBackgroundChanged; >=20 > + >=20 > + /// >=20 > + /// Icon buffer information >=20 > + /// >=20 > + EFI_GRAPHICS_OUTPUT_BLT_PIXEL *IconBltBuffer; >=20 > + UINTN IconBltSize; >=20 > + UINTN IconBltHeight; >=20 > + UINTN IconBltWidth; >=20 > + >=20 > + /// >=20 > + /// Full icon background buffer information >=20 > + /// >=20 > + EFI_GRAPHICS_OUTPUT_BLT_PIXEL *FullIconBackBuffer; >=20 > + UINTN FullIconBackStartX; >=20 > + UINTN FullIconBackStartY; >=20 > + UINTN FullIconBackHeight; >=20 > + UINTN FullIconBackWidth; >=20 > + UINTN FullIconBackSize; >=20 > + BOOLEAN FullIconUpdatedFlag; >=20 > + >=20 > + /// >=20 > + /// Simple icon background buffer information >=20 > + /// >=20 > + EFI_GRAPHICS_OUTPUT_BLT_PIXEL *SimIconBackBuffer; >=20 > + UINTN SimIconBackStartX; >=20 > + UINTN SimIconBackStartY; >=20 > + UINTN SimIconBackHeight; >=20 > + UINTN SimIconBackWidth; >=20 > + UINTN SimIconBackSize; >=20 > + BOOLEAN SimIconUpdatedFlag; >=20 > + >=20 > + /// >=20 > + /// Small Icon >=20 > + /// >=20 > + EFI_IMAGE_INPUT *SmallIcon; >=20 > + >=20 > + /// >=20 > + /// Full Icon >=20 > + /// >=20 > + EFI_IMAGE_INPUT *FullIcon; >=20 > + >=20 > + /// >=20 > + /// Simple Key body >=20 > + /// >=20 > + EFI_IMAGE_INPUT *SimKeyBody; >=20 > + >=20 > + /// >=20 > + /// Digital key body >=20 > + /// >=20 > + EFI_IMAGE_INPUT *DigKeyBody; >=20 > + >=20 > + /// >=20 > + /// Capital Letter Key board >=20 > + /// >=20 > + EFI_IMAGE_INPUT *CapLeKeyBody; >=20 > + >=20 > + /// >=20 > + /// Screen check buffer. >=20 > + /// This is used to check if screen is kept scrolling up. >=20 > + /// >=20 > + EFI_GRAPHICS_OUTPUT_BLT_PIXEL *ScreenCheckBuffer; >=20 > + UINTN ScreenCheckBufferSize; >=20 > + >=20 > + /// >=20 > + /// Key state >=20 > + /// >=20 > + BOOLEAN KeyPressed; >=20 > + >=20 > + /// >=20 > + /// Keyboard display status >=20 > + /// >=20 > + VK_DISPLAY_ATTRIBUTE CurrentKeyboardDisplay; >=20 > + VK_DISPLAY_ATTRIBUTE TargetKeyboardDisplay; >=20 > + >=20 > + /// >=20 > + /// Keyboard icon display status >=20 > + /// >=20 > + BOOLEAN IsIconShowed; >=20 > + UINT8 IconReDrawCheck; >=20 > + >=20 > + /// >=20 > + /// Keyboard body Image address >=20 > + /// Size of KeyboardBodyPtr must larger than mFullKeyboardBody >=20 > + /// >=20 > + UINT32 NumOfKeysInfo; >=20 > + VK_STRUCT KeyboardBodyPtr[50]; >=20 > + >=20 > + /// >=20 > + /// KeyBuffer >=20 > + /// >=20 > + EFI_EVENT KeyNotifyProcessEvent; >=20 > + EFI_KEY_TOGGLE_STATE KeyToggleState; >=20 > + EFI_KEY_DATA Keybuffer[MAX_KEY_BUF_SIZE]; >=20 > + UINT8 KeyStartIndex; >=20 > + UINT8 KeyEndIndex; >=20 > + UINT16 KeyTouchedTimeOut; >=20 > + BOOLEAN IsShiftKeyFlag; >=20 > + BOOLEAN IsCapsLockFlag; >=20 > + BOOLEAN IsSupportPartialKey; >=20 > + BOOLEAN IsRedrawUpdateUI; >=20 > + VK_PAGE_TYPE PageNumber; >=20 > + LIST_ENTRY NotifyList; >=20 > +}; >=20 > + >=20 > +/// >=20 > +/// Locate VK_CONTEXT from protocol >=20 > +/// >=20 > +#define VK_CONTEXT_FROM_PROTOCOL(a) CR (a, VK_CONTEXT, Si= mpleTextIn, VK_SIGNATURE) >=20 > +#define VK_CONTEXT_FROM_SIMPLETEXTINEX_PROTOCOL(a) CR (a, VK_CONTEXT, Si= mpleTextInEx, VK_SIGNATURE) >=20 > +#define VK_CONTEXT_FROM_VKBD_PROTOCOL(a) CR (a, VK_CONTEXT, Vk= bdProtocol, VK_SIGNATURE) >=20 > + >=20 > +/** >=20 > + Start the virtual keyboard driver >=20 > + >=20 > + This routine allocates the necessary resources for the driver. >=20 > + >=20 > + This routine is called by VirtualKeyboardDriverStart to complete the d= river >=20 > + initialization. >=20 > + >=20 > + @param[in, out] VkContext Address of an VK_CONTEXT structure >=20 > + @param[in] Controller Handle of device to work with. >=20 > + >=20 > + @retval EFI_SUCCESS Driver API properly initialized >=20 > + >=20 > +**/ >=20 > +EFI_STATUS >=20 > +VkApiStart ( >=20 > + IN VK_CONTEXT *VkContext, >=20 > + IN EFI_HANDLE Controller >=20 > + ); >=20 > + >=20 > +/** >=20 > + Stop the virtual keyboard driver >=20 > + >=20 > + This routine releases the resources allocated by VKApiStart. >=20 > + >=20 > + This routine is called by VirtualKeyboardDriverStop to initiate the dr= iver >=20 > + shutdown. >=20 > + >=20 > + @param[in] VkContext Address of an VK_CONTEXT structure >=20 > + >=20 > +**/ >=20 > +VOID >=20 > +VkApiStop ( >=20 > + IN VK_CONTEXT *VkContext >=20 > + ); >=20 > + >=20 > +/** >=20 > + Resets the input device hardware. >=20 > + >=20 > + The Reset() function resets the input device hardware. As part >=20 > + of initialization process, the firmware/device will make a quick >=20 > + but reasonable attempt to verify that the device is functioning. >=20 > + If the ExtendedVerification flag is TRUE the firmware may take >=20 > + an extended amount of time to verify the device is operating on >=20 > + reset. Otherwise the reset operation is to occur as quickly as >=20 > + possible. The hardware verification process is not defined by >=20 > + this specification and is left up to the platform firmware or >=20 > + driver to implement. >=20 > + >=20 > + @param[in] This A pointer to the EFI_SIMPLE_TEXT_INPUT= _EX_PROTOCOL instance. >=20 > + >=20 > + @param[in] ExtendedVerification Indicates that the driver may perform = a more exhaustive >=20 > + verification operation of the device d= uring reset. >=20 > + >=20 > + @retval EFI_SUCCESS The device was reset. >=20 > + @retval EFI_DEVICE_ERROR The device is not functioning correctl= y and could not be reset. >=20 > + >=20 > +**/ >=20 > +EFI_STATUS >=20 > +EFIAPI >=20 > +VkKeyboardReset ( >=20 > + IN EFI_SIMPLE_TEXT_INPUT_PROTOCOL *This, >=20 > + IN BOOLEAN ExtendedVerification >=20 > + ); >=20 > + >=20 > +/** >=20 > + Reads the next keystroke from the input device. The WaitForKey Event c= an >=20 > + be used to test for existence of a keystroke via WaitForEvent () call. >=20 > + >=20 > + @param[in] This Protocol instance pointer. >=20 > + @param[out] Key Driver may perform diagnostics on reset. >=20 > + >=20 > + @retval EFI_SUCCESS The keystroke information was returned. >=20 > + @retval EFI_NOT_READY There was no keystroke data available. >=20 > + @retval EFI_DEVICE_ERROR The keystroke information was not returned du= e to >=20 > + hardware errors. >=20 > + >=20 > +**/ >=20 > +EFI_STATUS >=20 > +EFIAPI >=20 > +VkKeyboardReadKeyStroke ( >=20 > + IN EFI_SIMPLE_TEXT_INPUT_PROTOCOL *This, >=20 > + OUT EFI_INPUT_KEY *Key >=20 > + ); >=20 > + >=20 > +/** >=20 > + Resets the input device hardware. >=20 > + >=20 > + The Reset() function resets the input device hardware. As part >=20 > + of initialization process, the firmware/device will make a quick >=20 > + but reasonable attempt to verify that the device is functioning. >=20 > + If the ExtendedVerification flag is TRUE the firmware may take >=20 > + an extended amount of time to verify the device is operating on >=20 > + reset. Otherwise the reset operation is to occur as quickly as >=20 > + possible. The hardware verification process is not defined by >=20 > + this specification and is left up to the platform firmware or >=20 > + driver to implement. >=20 > + >=20 > + @param[in] This A pointer to the EFI_SIMPLE_TEXT_INPUT= _EX_PROTOCOL instance. >=20 > + >=20 > + @param[in] ExtendedVerification Indicates that the driver may perform = a more exhaustive >=20 > + verification operation of the device d= uring reset. >=20 > + >=20 > + @retval EFI_SUCCESS The device was reset. >=20 > + @retval EFI_DEVICE_ERROR The device is not functioning correctl= y and could not be reset. >=20 > + >=20 > +**/ >=20 > +EFI_STATUS >=20 > +EFIAPI >=20 > +VkKeyboardResetEx ( >=20 > + IN EFI_SIMPLE_TEXT_INPUT_EX_PROTOCOL *This, >=20 > + IN BOOLEAN ExtendedVerification >=20 > + ); >=20 > + >=20 > +/** >=20 > + Reads the next keystroke from the input device. >=20 > + >=20 > + @param[in] This Protocol instance pointer. >=20 > + @param[out] KeyData A pointer to a buffer that is filled in= with the keystroke >=20 > + state data for the key that was pressed= . >=20 > + >=20 > + @retval EFI_SUCCESS The keystroke information was returned. >=20 > + @retval EFI_NOT_READY There was no keystroke data available. >=20 > + @retval EFI_INVALID_PARAMETER This or KeyData is NULL. >=20 > + >=20 > +**/ >=20 > +EFI_STATUS >=20 > +EFIAPI >=20 > +VkKeyboardReadKeyStrokeEx ( >=20 > + IN EFI_SIMPLE_TEXT_INPUT_EX_PROTOCOL *This, >=20 > + OUT EFI_KEY_DATA *KeyData >=20 > + ); >=20 > + >=20 > +/** >=20 > + Set certain state for the input device. >=20 > + >=20 > + @param[in] This Protocol instance pointer. >=20 > + @param[in] KeyToggleState A pointer to the EFI_KEY_TOGGLE_STATE = to set the >=20 > + state for the input device. >=20 > + >=20 > + @retval EFI_SUCCESS The device state was set appropriately= . >=20 > + @retval EFI_INVALID_PARAMETER This or KeyToggleState is NULL. >=20 > + >=20 > +**/ >=20 > +EFI_STATUS >=20 > +EFIAPI >=20 > +VkKeyboardSetState ( >=20 > + IN EFI_SIMPLE_TEXT_INPUT_EX_PROTOCOL *This, >=20 > + IN EFI_KEY_TOGGLE_STATE *KeyToggleState >=20 > + ); >=20 > + >=20 > +/** >=20 > + Register a notification function for a particular keystroke for the in= put device. >=20 > + >=20 > + @param[in] This Protocol instance pointer. >=20 > + @param[in] KeyData A pointer to a buffer that is = filled in with the keystroke >=20 > + information data for the key t= hat was pressed. >=20 > + @param[in] KeyNotificationFunction Points to the function to be c= alled when the key >=20 > + sequence is typed specified by= KeyData. >=20 > + @param[out] NotifyHandle Points to the unique handle as= signed to the registered notification. >=20 > + >=20 > + @retval EFI_SUCCESS The notification function was = registered successfully. >=20 > + @retval EFI_OUT_OF_RESOURCES Unable to allocate resources f= or necessary data structures. >=20 > + @retval EFI_INVALID_PARAMETER KeyData or NotifyHandle or Key= NotificationFunction is NULL. >=20 > + >=20 > +**/ >=20 > +EFI_STATUS >=20 > +EFIAPI >=20 > +VkKeyboardRegisterKeyNotify ( >=20 > + IN EFI_SIMPLE_TEXT_INPUT_EX_PROTOCOL *This, >=20 > + IN EFI_KEY_DATA *KeyData, >=20 > + IN EFI_KEY_NOTIFY_FUNCTION KeyNotificationFunction, >=20 > + OUT EFI_HANDLE *NotifyHandle >=20 > + ); >=20 > + >=20 > +/** >=20 > + Remove a registered notification function from a particular keystroke. >=20 > + >=20 > + @param[in] This Protocol instance pointer. >=20 > + @param[in] NotificationHandle The handle of the notification function= being unregistered. >=20 > + >=20 > + @retval EFI_SUCCESS The notification function was unregiste= red successfully. >=20 > + @retval EFI_INVALID_PARAMETER The NotificationHandle is invalid >=20 > + >=20 > +**/ >=20 > +EFI_STATUS >=20 > +EFIAPI >=20 > +VkKeyboardUnregisterKeyNotify ( >=20 > + IN EFI_SIMPLE_TEXT_INPUT_EX_PROTOCOL *This, >=20 > + IN EFI_HANDLE NotificationHandle >=20 > + ); >=20 > + >=20 > +/** >=20 > + Draw key board on the display >=20 > + >=20 > + @param[in] VkContext Graphic Protocol for draw the alphabet. >=20 > + >=20 > + @retval EFI_SUCCESS Draw keyboard was done. >=20 > + @retval EFI_UNSUPPORTED Did not get key mapping table. >=20 > + >=20 > +**/ >=20 > +EFI_STATUS >=20 > +DrawKeyboardLayout ( >=20 > + IN VK_CONTEXT *VkContext >=20 > + ); >=20 > + >=20 > +/** >=20 > + Clear the keyboard body >=20 > + >=20 > + @param[in] VkContext Code context. >=20 > + >=20 > + @retval EFI_SUCCESS Clear rectangle is done. >=20 > + >=20 > +**/ >=20 > +EFI_STATUS >=20 > +HideVkBody ( >=20 > + IN VK_CONTEXT *VkContext >=20 > + ); >=20 > + >=20 > +/** >=20 > + Clear the keyboard icon >=20 > + >=20 > + @param[in] VkContext Code context. >=20 > + >=20 > + @retval EFI_SUCCESS Clear rectangle is done. >=20 > + >=20 > +**/ >=20 > +EFI_STATUS >=20 > +HideVkIcon ( >=20 > + IN VK_CONTEXT *VkContext >=20 > + ); >=20 > + >=20 > +/** >=20 > + Use to draw the keyboard icon. >=20 > + >=20 > + @param[in] VkContext Pointer to virtual keyboard's context >=20 > + @param[in] VkImage Image of keyboard to display on the screen. >=20 > + @param[in] Attribute Attribute of keyboard to display on the screen. >=20 > + >=20 > + @retval EFI_SUCCESS ConsoleControl has been flipped to graph= ics and keyboard icon displayed. >=20 > + @retval EFI_UNSUPPORTED KeyboardFile not found >=20 > + @retval EFI_INVALID_PARAMETER Attribute is unknown. >=20 > + >=20 > +**/ >=20 > +EFI_STATUS >=20 > +EFIAPI >=20 > +DrawVkIcon ( >=20 > + IN VK_CONTEXT *VkContext, >=20 > + IN EFI_IMAGE_INPUT *VkImage, >=20 > + IN VK_DISPLAY_ATTRIBUTE Attribute >=20 > + ); >=20 > + >=20 > +/** >=20 > + Use to draw the keyboard. >=20 > + >=20 > + @param[in] VkContext Pointer to virtual keyboard's context >=20 > + @param[in] VkImage Image of keyboard to display on the screen. >=20 > + @param[in] Attribute Attribute of keyboard to display on the screen. >=20 > + >=20 > + @retval EFI_SUCCESS ConsoleControl has been flipped to graph= ics and keyboard displayed. >=20 > + @retval EFI_UNSUPPORTED KeyboardFile not found >=20 > + @retval EFI_INVALID_PARAMETER Attribute is unknown. >=20 > + >=20 > +**/ >=20 > +EFI_STATUS >=20 > +EFIAPI >=20 > +DrawVkBody ( >=20 > + IN VK_CONTEXT *VkContext, >=20 > + IN EFI_IMAGE_INPUT *VkImage, >=20 > + IN VK_DISPLAY_ATTRIBUTE Attribute >=20 > + ); >=20 > + >=20 > +/** >=20 > + Get unicode by VkContext->PageNumber and VkContext->KeyboardBodyPtr. >=20 > + >=20 > + @param[in] VkContext Address of an VK_CONTEXT structure. >=20 > + @param[in] KeyItem Key Item. >=20 > + @param[out] FontPtr Follow VkContext->PageNumber to trans= late >=20 > + font unicode. >=20 > + >=20 > + @retval EFI_SUCCESS Finish translating FontPtr. >=20 > + @retval EFI_INVALID_PARAMETER VkContext or FontPtr is NULL. >=20 > + >=20 > +**/ >=20 > +EFI_STATUS >=20 > +VkGetMappingFont ( >=20 > + IN VK_CONTEXT *VkContext, >=20 > + IN VK_STRUCT KeyItem, >=20 > + OUT UINT32 *FontPtr >=20 > + ); >=20 > + >=20 > +/** >=20 > + This routine is used to check if icon has been cleared. >=20 > + >=20 > + @param[in] VkContext Pointer to virtual keyboard's context >=20 > + >=20 > + @retval EFI_SUCCESS Function completed. >=20 > + >=20 > +**/ >=20 > +EFI_STATUS >=20 > +CheckIconCleared ( >=20 > + IN VK_CONTEXT *VkContext >=20 > + ); >=20 > + >=20 > +/** >=20 > + ConvertCoordinate - Convert the touch panel's coordinate to display's = coordinate. >=20 > + >=20 > + @param[in] VkContext Virtual Keyboard context. >=20 > + @param[in] Point The coordinate reported from touch p= anel. >=20 > + @param[out] TouchX The coordinate X converted to displa= y panel. >=20 > + @param[out] TouchY The coordinate Y converted to displa= y panel.. >=20 > + >=20 > + @retval EFI_SUCCESS Convert success. >=20 > + >=20 > +**/ >=20 > +EFI_STATUS >=20 > +ConvertCoordinate ( >=20 > + IN VK_CONTEXT *VkContext, >=20 > + IN EFI_ABSOLUTE_POINTER_STATE Point, >=20 > + OUT UINT32 *TouchX, >=20 > + OUT UINT32 *TouchY >=20 > + ); >=20 > + >=20 > +/** >=20 > + This routine is used to check if screen has been cleared. >=20 > + >=20 > + @param[in] VkContext Pointer to virtual keyboard's context >=20 > + >=20 > + @retval EFI_SUCCESS Function completed. >=20 > + >=20 > +**/ >=20 > +EFI_STATUS >=20 > +CheckScreenCleared ( >=20 > + IN VK_CONTEXT *VkContext >=20 > + ); >=20 > + >=20 > +/** >=20 > + This routine is used to check if background beneath virtual keyboard h= as been cleared. >=20 > + >=20 > + @param[in] VkContext Pointer to virtual keyboard's context >=20 > + >=20 > + @retval EFI_SUCCESS Function completed. >=20 > + >=20 > +**/ >=20 > +EFI_STATUS >=20 > +CheckBackgroundChanged ( >=20 > + IN VK_CONTEXT *VkContext >=20 > + ); >=20 > + >=20 > +/** >=20 > + To prevent screen keyboard layout occur scroll up >=20 > + >=20 > + @param[in] VkContext Address of an VK_CONTEXT structure. >=20 > + >=20 > +**/ >=20 > +VOID >=20 > +PreventScreenScrollUp ( >=20 > + IN OUT VK_CONTEXT *VkContext >=20 > + ); >=20 > + >=20 > +EFI_STATUS >=20 > +SetCharacterPosition ( >=20 > + IN VK_CONTEXT *VkContext, >=20 > + IN UINT32 DestX, >=20 > + IN UINT32 DestY >=20 > + ); >=20 > + >=20 > +EFI_STATUS >=20 > +KeyboardLayoutHandler ( >=20 > + IN VK_CONTEXT *VkContext, >=20 > + IN UINT32 Index >=20 > + ); >=20 > + >=20 > +EFI_STATUS >=20 > +EFIAPI >=20 > +SaveVkBodyBackgroundBltBuffer ( >=20 > + IN VK_CONTEXT *VkContext, >=20 > + IN UINTN BltSize >=20 > + ); >=20 > + >=20 > +EFI_STATUS >=20 > +EFIAPI >=20 > +RestoreVkBodyBackgroundBltBuffer ( >=20 > + IN VK_CONTEXT *VkContext >=20 > + ); >=20 > + >=20 > +EFI_STATUS >=20 > +EFIAPI >=20 > +SaveVkIconBackgroundBltBuffer ( >=20 > + IN VK_CONTEXT *VkContext, >=20 > + IN VK_DISPLAY_ATTRIBUTE IconType >=20 > + ); >=20 > +#endif >=20 > diff --git a/Features/Intel/UserInterface/VirtualKeyboardFeaturePkg/Virtu= alKeyboardDxe/VirtualKeyboardDriver.c > b/Features/Intel/UserInterface/VirtualKeyboardFeaturePkg/VirtualKeyboardD= xe/VirtualKeyboardDriver.c > new file mode 100644 > index 0000000000..42ad493a9f > --- /dev/null > +++ b/Features/Intel/UserInterface/VirtualKeyboardFeaturePkg/VirtualKeybo= ardDxe/VirtualKeyboardDriver.c > @@ -0,0 +1,541 @@ > +/** @file >=20 > + Virtual Keyboard driver. >=20 > + >=20 > + Copyright (c) 2012 - 2020, Intel Corporation. All rights reserved.
    >=20 > + SPDX-License-Identifier: BSD-2-Clause-Patent >=20 > + >=20 > +**/ >=20 > + >=20 > +#include "VirtualKeyboard.h" >=20 > + >=20 > +UINT32 mOrigConOutRow =3D 0; >=20 > +UINT32 mOrigSetupConOutRow =3D 0; >=20 > +EFI_HII_HANDLE mHiiHandle =3D NULL; >=20 > + >=20 > +EFI_STATUS >=20 > +EFIAPI >=20 > +VirtualKeyboardDriverSupported ( >=20 > + IN EFI_DRIVER_BINDING_PROTOCOL *This, >=20 > + IN EFI_HANDLE Controller, >=20 > + IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath >=20 > + ); >=20 > + >=20 > +EFI_STATUS >=20 > +EFIAPI >=20 > +VirtualKeyboardDriverStart ( >=20 > + IN EFI_DRIVER_BINDING_PROTOCOL *This, >=20 > + IN EFI_HANDLE Controller, >=20 > + IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath >=20 > + ); >=20 > + >=20 > +EFI_STATUS >=20 > +EFIAPI >=20 > +VirtualKeyboardDriverStop ( >=20 > + IN EFI_DRIVER_BINDING_PROTOCOL *This, >=20 > + IN EFI_HANDLE Controller, >=20 > + IN UINTN NumberOfChildren, >=20 > + IN EFI_HANDLE *ChildHandleBuffer >=20 > + ); >=20 > + >=20 > +EFI_DRIVER_BINDING_PROTOCOL gVirtualKeyboardDriverBinding =3D { >=20 > + VirtualKeyboardDriverSupported, >=20 > + VirtualKeyboardDriverStart, >=20 > + VirtualKeyboardDriverStop, >=20 > + 0x10, >=20 > + NULL, >=20 > + NULL >=20 > +}; >=20 > + >=20 > +/** >=20 > + This is the declaration of an EFI image entry point. This entry point = is >=20 > + the same for UEFI Applications, UEFI OS Loaders, and UEFI Drivers incl= uding >=20 > + both device drivers and bus drivers. >=20 > + >=20 > + @param ImageHandle The firmware allocated handle for the UE= FI image. >=20 > + @param SystemTable A pointer to the EFI System Table. >=20 > + >=20 > + @retval EFI_SUCCESS The operation completed successfully. >=20 > + @retval Others An unexpected error occurred. >=20 > + >=20 > +**/ >=20 > +EFI_STATUS >=20 > +EFIAPI >=20 > +VirtualKeyboardDriverEntryPoint ( >=20 > + IN EFI_HANDLE ImageHandle, >=20 > + IN EFI_SYSTEM_TABLE *SystemTable >=20 > + ) >=20 > +{ >=20 > + EFI_STATUS Status; >=20 > + >=20 > + DEBUG ((DEBUG_VK_ROUTINE_ENTRY_EXIT, "VirtualKeyboardDriverEntryPoint = Start\n")); >=20 > + // >=20 > + // Install UEFI Driver Model protocol(s). >=20 > + // >=20 > + Status =3D EfiLibInstallDriverBindingComponentName2 ( >=20 > + ImageHandle, >=20 > + SystemTable, >=20 > + &gVirtualKeyboardDriverBinding, >=20 > + ImageHandle, >=20 > + &gVirtualKeyboardComponentName, >=20 > + &gVirtualKeyboardComponentName2 >=20 > + ); >=20 > + ASSERT_EFI_ERROR (Status); >=20 > + >=20 > + mHiiHandle =3D HiiAddPackages ( >=20 > + &gEfiCallerIdGuid, >=20 > + NULL, >=20 > + VirtualKeyboardDxeImages, >=20 > + NULL >=20 > + ); >=20 > + ASSERT (mHiiHandle !=3D NULL); >=20 > + >=20 > + mOrigConOutRow =3D PcdGet32 (PcdConOutRow); >=20 > + mOrigSetupConOutRow =3D PcdGet32 (PcdSetupConOutRow); >=20 > + >=20 > + DEBUG ((DEBUG_VK_ROUTINE_ENTRY_EXIT, "VirtualKeyboardDriverEntryPoint = End\n")); >=20 > + return Status; >=20 > +} >=20 > + >=20 > +/** >=20 > + Verify the controller type >=20 > + >=20 > + This routine determines if the pointer and GOP are available. >=20 > + >=20 > + This routine is called by the UEFI driver framework during connect >=20 > + processing. >=20 > + >=20 > + @param[in] DriverBinding Protocol instance pointer. >=20 > + @param[in] Controller Handle of device to test. >=20 > + @param[in] RemainingDevicePath Not used. >=20 > + >=20 > + @retval EFI_SUCCESS This driver supports this device. >=20 > + @retval other This driver does not support this devi= ce. >=20 > + >=20 > +**/ >=20 > +EFI_STATUS >=20 > +EFIAPI >=20 > +VirtualKeyboardDriverSupported ( >=20 > + IN EFI_DRIVER_BINDING_PROTOCOL *This, >=20 > + IN EFI_HANDLE Controller, >=20 > + IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath >=20 > + ) >=20 > +{ >=20 > + EFI_GRAPHICS_OUTPUT_PROTOCOL *GraphicsOutput; >=20 > + EFI_STATUS Status; >=20 > + >=20 > + DEBUG ((DEBUG_VK_ROUTINE_ENTRY_EXIT, "VirtualKeyboardDriverSupported S= tart\n")); >=20 > + >=20 > + // >=20 > + // Verify that the driver is not already started >=20 > + // >=20 > + Status =3D gBS->OpenProtocol ( >=20 > + Controller, >=20 > + &gEfiCallerIdGuid, >=20 > + NULL, >=20 > + This->DriverBindingHandle, >=20 > + Controller, >=20 > + EFI_OPEN_PROTOCOL_TEST_PROTOCOL >=20 > + ); >=20 > + if (!EFI_ERROR (Status)) { >=20 > + Status =3D EFI_ALREADY_STARTED; >=20 > + DEBUG ((DEBUG_VK_ROUTINE_ENTRY_EXIT, "ERROR - VK has already initial= ized\n")); >=20 > + goto Error; >=20 > + } >=20 > + >=20 > + // >=20 > + // Determine if the pointer protocol is available. >=20 > + // This should be installed in touch driver. >=20 > + // >=20 > + Status =3D gBS->OpenProtocol ( >=20 > + Controller, >=20 > + &gEfiAbsolutePointerProtocolGuid, >=20 > + NULL, >=20 > + This->DriverBindingHandle, >=20 > + Controller, >=20 > + EFI_OPEN_PROTOCOL_TEST_PROTOCOL >=20 > + ); >=20 > + if (EFI_ERROR (Status)) { >=20 > + DEBUG ((DEBUG_VK_ROUTINE_ENTRY_EXIT, "ERROR - VK Absolute pointer pr= otocol not found\n")); >=20 > + goto Error; >=20 > + } >=20 > + >=20 > + Status =3D gBS->OpenProtocol ( >=20 > + Controller, >=20 > + &gEfiTouchPanelGuid, >=20 > + NULL, >=20 > + This->DriverBindingHandle, >=20 > + Controller, >=20 > + EFI_OPEN_PROTOCOL_TEST_PROTOCOL >=20 > + ); >=20 > + if (EFI_ERROR (Status)) { >=20 > + DEBUG ((DEBUG_VK_ROUTINE_ENTRY_EXIT, "ERROR - VK Touch Panel Guid no= t found\n")); >=20 > + goto Error; >=20 > + } >=20 > + >=20 > + // >=20 > + // Determine if the graphics output protocol is available >=20 > + // >=20 > + Status =3D gBS->HandleProtocol ( >=20 > + gST->ConsoleOutHandle, >=20 > + &gEfiGraphicsOutputProtocolGuid, >=20 > + (VOID **)&GraphicsOutput >=20 > + ); >=20 > + if (EFI_ERROR (Status)) { >=20 > + DEBUG ((DEBUG_VK_ROUTINE_ENTRY_EXIT, "ERROR - VK Graphics output pro= tocol not found\n")); >=20 > + goto Error; >=20 > + } >=20 > + >=20 > + DEBUG ((DEBUG_VK_ROUTINE_ENTRY_EXIT | DEBUG_INFO, "VirtualKeyboardDriv= erSupported Success, Status: %r\n", > Status)); >=20 > + goto End; >=20 > + >=20 > +Error: >=20 > + DEBUG ((DEBUG_VK_ROUTINE_ENTRY_EXIT, "VirtualKeyboardDriverSupported F= ailed, Status: %r\n", Status)); >=20 > + >=20 > +End: >=20 > + DEBUG ((DEBUG_VK_ROUTINE_ENTRY_EXIT, "VirtualKeyboardDriverSupported E= nd\n")); >=20 > + return Status; >=20 > +} >=20 > + >=20 > +/** >=20 > + Connect to the controller >=20 > + >=20 > + This routine initializes an instance of the virutal keyboard driver fo= r this >=20 > + controller. >=20 > + >=20 > + This routine is called by the UEFI driver framework during connect >=20 > + processing if the controller passes the tests in I2cBusDriverSupported= . >=20 > + >=20 > + @param[in] DriverBinding Protocol instance pointer. >=20 > + @param[in] Controller Handle of device to work with. >=20 > + @param[in] RemainingDevicePath Not used, always produce all possible = children. >=20 > + >=20 > + @retval EFI_SUCCESS This driver is added to Controller. >=20 > + @retval other This driver does not support this devi= ce. >=20 > + >=20 > +**/ >=20 > +EFI_STATUS >=20 > +EFIAPI >=20 > +VirtualKeyboardDriverStart ( >=20 > + IN EFI_DRIVER_BINDING_PROTOCOL *This, >=20 > + IN EFI_HANDLE Controller, >=20 > + IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath >=20 > + ) >=20 > +{ >=20 > + VK_CONTEXT *VkContext; >=20 > + EFI_STATUS Status; >=20 > + >=20 > + DEBUG ((DEBUG_VK_ROUTINE_ENTRY_EXIT | DEBUG_INFO, "VirtualKeyboardDriv= erStart Start\n")); >=20 > + >=20 > + VkContext =3D AllocateZeroPool (sizeof (VK_CONTEXT)); >=20 > + if (VkContext =3D=3D NULL) { >=20 > + DEBUG ((DEBUG_VK_ROUTINE_ENTRY_EXIT | DEBUG_ERROR, "ERROR - No memor= y for virtual keyboard driver\n")); >=20 > + Status =3D EFI_OUT_OF_RESOURCES; >=20 > + ASSERT_EFI_ERROR (Status); >=20 > + goto Error; >=20 > + } >=20 > + >=20 > + Status =3D gBS->OpenProtocol ( >=20 > + Controller, >=20 > + &gEfiAbsolutePointerProtocolGuid, >=20 > + (VOID**) &VkContext->AbsolutePointer, >=20 > + This->DriverBindingHandle, >=20 > + Controller, >=20 > + EFI_OPEN_PROTOCOL_BY_DRIVER >=20 > + ); >=20 > + if (EFI_ERROR (Status)) { >=20 > + DEBUG ((DEBUG_VK_ROUTINE_ENTRY_EXIT | DEBUG_ERROR, "ERROR - Failed t= o open absolute pointer protocol, > Status: %r\n", Status)); >=20 > + goto Error; >=20 > + } >=20 > + >=20 > + Status =3D gBS->OpenProtocol ( >=20 > + Controller, >=20 > + &gEfiTouchPanelGuid, >=20 > + NULL, >=20 > + This->DriverBindingHandle, >=20 > + Controller, >=20 > + EFI_OPEN_PROTOCOL_TEST_PROTOCOL >=20 > + ); >=20 > + if (EFI_ERROR (Status)) { >=20 > + DEBUG ((DEBUG_VK_ROUTINE_ENTRY_EXIT | DEBUG_ERROR, "ERROR - TouchPan= el GUID not found, Status: %r\n", > Status)); >=20 > + goto Error; >=20 > + } >=20 > + >=20 > + Status =3D gBS->HandleProtocol ( >=20 > + gST->ConsoleOutHandle, >=20 > + &gEfiGraphicsOutputProtocolGuid, >=20 > + (VOID**) &VkContext->GraphicsOutput >=20 > + ); >=20 > + if (EFI_ERROR (Status)) { >=20 > + DEBUG ((DEBUG_VK_ROUTINE_ENTRY_EXIT | DEBUG_ERROR, "ERROR - Graphics= output protocol not available, > Status: %r\n", Status)); >=20 > + goto Error; >=20 > + } >=20 > + >=20 > + VkContext->HiiHandle =3D mHiiHandle; >=20 > + Status =3D VkApiStart (VkContext, Controller); >=20 > + if (EFI_ERROR (Status)) { >=20 > + DEBUG ((DEBUG_VK_ROUTINE_ENTRY_EXIT | DEBUG_ERROR, "ERROR - Failed t= o VkApiStart, Status: %r\n", Status)); >=20 > + goto Error; >=20 > + } >=20 > + >=20 > + Status =3D gBS->InstallMultipleProtocolInterfaces ( >=20 > + &Controller, >=20 > + &gEfiCallerIdGuid, >=20 > + VkContext, >=20 > + &gEfiSimpleTextInProtocolGuid, >=20 > + &VkContext->SimpleTextIn, >=20 > + &gEfiSimpleTextInputExProtocolGuid, >=20 > + &VkContext->SimpleTextInEx, >=20 > + &gEfiConsoleInDeviceGuid, >=20 > + NULL, >=20 > + NULL >=20 > + ); >=20 > + if (EFI_ERROR (Status)) { >=20 > + DEBUG ((DEBUG_VK_ROUTINE_ENTRY_EXIT | DEBUG_ERROR, "ERROR - Failed t= o install VK protocols, Status: %r\n", > Status)); >=20 > + ASSERT_EFI_ERROR (Status); >=20 > + goto Error; >=20 > + } >=20 > + >=20 > + DEBUG ((DEBUG_VK_ROUTINE_ENTRY_EXIT | DEBUG_INFO, "VirtualKeyboardDriv= erStart Success, Status: %r\n", Status)); >=20 > + goto End; >=20 > + >=20 > +Error: >=20 > + if (VkContext !=3D NULL) { >=20 > + FreePool (VkContext); >=20 > + } >=20 > + >=20 > + gBS->CloseProtocol ( >=20 > + Controller, >=20 > + &gEfiAbsolutePointerProtocolGuid, >=20 > + This->DriverBindingHandle, >=20 > + Controller >=20 > + ); >=20 > + >=20 > + // >=20 > + // Restore setting if connect device fail. >=20 > + // >=20 > + PcdSet32S (PcdConOutRow, mOrigConOutRow); >=20 > + PcdSet32S (PcdSetupConOutRow, mOrigSetupConOutRow); >=20 > + >=20 > + DEBUG ((DEBUG_VK_ROUTINE_ENTRY_EXIT, "VirtualKeyboardDriverStart Faile= d, Status: %r\n", Status)); >=20 > + >=20 > +End: >=20 > + DEBUG ((DEBUG_VK_ROUTINE_ENTRY_EXIT, "VirtualKeyboardDriverStart End\n= ")); >=20 > + >=20 > + return Status; >=20 > +} >=20 > + >=20 > +/** >=20 > + Disconnect from the controller. >=20 > + >=20 > + This routine disconnects from the controller. >=20 > + >=20 > + This routine is called by DriverUnload when the I2C bus driver >=20 > + is being unloaded. >=20 > + >=20 > + @param[in] DriverBinding Protocol instance pointer. >=20 > + @param[in] Controller Handle of device to stop driver on. >=20 > + @param[in] NumberOfChildren How many children need to be stopped. >=20 > + @param[in] ChildHandleBuffer Not used. >=20 > + >=20 > + @retval EFI_SUCCESS This driver is removed Controller. >=20 > + @retval EFI_DEVICE_ERROR The device could not be stopped due to= a device error. >=20 > + @retval other This driver was not removed from this = device. >=20 > + >=20 > +**/ >=20 > +EFI_STATUS >=20 > +EFIAPI >=20 > +VirtualKeyboardDriverStop ( >=20 > + IN EFI_DRIVER_BINDING_PROTOCOL *This, >=20 > + IN EFI_HANDLE Controller, >=20 > + IN UINTN NumberOfChildren, >=20 > + IN EFI_HANDLE *ChildHandleBuffer >=20 > + ) >=20 > +{ >=20 > + VK_CONTEXT *VkContext; >=20 > + EFI_STATUS Status; >=20 > + >=20 > + DEBUG ((DEBUG_VK_ROUTINE_ENTRY_EXIT, "VirtualKeyboardDriverStop Start\= n")); >=20 > + >=20 > + Status =3D gBS->OpenProtocol ( >=20 > + Controller, >=20 > + &gEfiCallerIdGuid, >=20 > + (VOID**)&VkContext, >=20 > + This->DriverBindingHandle, >=20 > + Controller, >=20 > + EFI_OPEN_PROTOCOL_BY_DRIVER | EFI_OPEN_PROTOCOL_EXCLUS= IVE >=20 > + ); >=20 > + if (EFI_ERROR (Status)) { >=20 > + Status =3D EFI_SUCCESS; >=20 > + goto Success; >=20 > + } >=20 > + >=20 > + // >=20 > + // Done with the driver protocol >=20 > + // >=20 > + Status =3D gBS->CloseProtocol ( >=20 > + Controller, >=20 > + &gEfiCallerIdGuid, >=20 > + This->DriverBindingHandle, >=20 > + Controller >=20 > + ); >=20 > + if (EFI_ERROR (Status)) { >=20 > + DEBUG ((DEBUG_VK_ROUTINE_ENTRY_EXIT, "ERROR - Failed to close the VK= protocol, Status: %r\n", Status)); >=20 > + goto Error; >=20 > + } >=20 > + >=20 > + // >=20 > + // Remove ConsoleIn protocols first to close the link in ConSplitter >=20 > + // >=20 > + Status =3D gBS->OpenProtocol ( >=20 > + Controller, >=20 > + &gEfiConsoleInDeviceGuid, >=20 > + NULL, >=20 > + This->DriverBindingHandle, >=20 > + Controller, >=20 > + EFI_OPEN_PROTOCOL_TEST_PROTOCOL >=20 > + ); >=20 > + if (EFI_ERROR (Status)) { >=20 > + DEBUG ((DEBUG_VK_ROUTINE_ENTRY_EXIT, "ERROR - Failed to uninstall th= e protocols, Status: %r\n", Status)); >=20 > + goto Error; >=20 > + } >=20 > + >=20 > + // >=20 > + // Remove the remaining protocols >=20 > + // >=20 > + Status =3D gBS->UninstallMultipleProtocolInterfaces ( >=20 > + Controller, >=20 > + &gEfiCallerIdGuid, >=20 > + VkContext, >=20 > + &gEfiSimpleTextInProtocolGuid, >=20 > + &VkContext->SimpleTextIn, >=20 > + &gEfiSimpleTextInputExProtocolGuid, >=20 > + &VkContext->SimpleTextInEx, >=20 > + &gEfiConsoleInDeviceGuid, >=20 > + NULL, >=20 > + NULL >=20 > + ); >=20 > + if (EFI_ERROR (Status)) { >=20 > + DEBUG ((DEBUG_VK_ROUTINE_ENTRY_EXIT, "ERROR - Failed to uninstall th= e protocols, Status: %r\n", Status)); >=20 > + goto Error; >=20 > + } >=20 > + >=20 > + // >=20 > + // Stop the driver >=20 > + // >=20 > + VkApiStop (VkContext); >=20 > + >=20 > + // >=20 > + // Release the pointer protocol upon failure >=20 > + // >=20 > + Status =3D gBS->CloseProtocol ( >=20 > + Controller, >=20 > + &gEfiAbsolutePointerProtocolGuid, >=20 > + This->DriverBindingHandle, >=20 > + Controller >=20 > + ); >=20 > + if (EFI_ERROR (Status)) { >=20 > + DEBUG ((DEBUG_VK_ROUTINE_ENTRY_EXIT, "ERROR - Failed to close absolu= te pointer protocol, Status: %r\n", Status)); >=20 > + goto Error; >=20 > + } >=20 > + >=20 > + // >=20 > + // Release VkContext >=20 > + // >=20 > + if (VkContext !=3D NULL) { >=20 > + FreePool (VkContext); >=20 > + } >=20 > + >=20 > +Success: >=20 > + DEBUG ((DEBUG_VK_ROUTINE_ENTRY_EXIT, "VirtualKeyboardDriverStop Succes= s, Status: %r\n", Status)); >=20 > + goto End; >=20 > + >=20 > +Error: >=20 > + DEBUG ((DEBUG_VK_ROUTINE_ENTRY_EXIT, "VirtualKeyboardDriverStop Failed= , Status: %r\n", Status)); >=20 > + >=20 > +End: >=20 > + DEBUG ((DEBUG_VK_ROUTINE_ENTRY_EXIT, "VirtualKeyboardDriverStop End\n"= )); >=20 > + return Status; >=20 > +} >=20 > + >=20 > +/** >=20 > + Unloads an image. >=20 > + >=20 > + @param[in] ImageHandle Handle that identifies the image to be u= nloaded. >=20 > + >=20 > + @retval EFI_SUCCESS The image has been unloaded. >=20 > + @retval EFI_INVALID_PARAMETER ImageHandle is not a valid image handle. >=20 > + >=20 > +**/ >=20 > +EFI_STATUS >=20 > +EFIAPI >=20 > +VirtualKeyboardDriverUnload ( >=20 > + IN EFI_HANDLE ImageHandle >=20 > + ) >=20 > +{ >=20 > + EFI_STATUS Status; >=20 > + EFI_HANDLE *HandleBuffer; >=20 > + UINTN HandleCount; >=20 > + UINTN Index; >=20 > + >=20 > + DEBUG ((DEBUG_VK_ROUTINE_ENTRY_EXIT, "VirtualKeyboardDriverUnload Star= t\n")); >=20 > + >=20 > + // >=20 > + // Retrieve array of all handles in the handle database >=20 > + // >=20 > + Status =3D gBS->LocateHandleBuffer ( >=20 > + AllHandles, >=20 > + NULL, >=20 > + NULL, >=20 > + &HandleCount, >=20 > + &HandleBuffer >=20 > + ); >=20 > + if (EFI_ERROR (Status)) { >=20 > + DEBUG ((DEBUG_VK_ROUTINE_ENTRY_EXIT, "ERROR - Failed to locate handl= e buffer, Status: %r\n", Status)); >=20 > + ASSERT_EFI_ERROR (Status); >=20 > + goto Error; >=20 > + } >=20 > + >=20 > + // >=20 > + // Disconnect the current driver from handles in the handle database >=20 > + // >=20 > + for (Index =3D 0; Index < HandleCount; Index++) { >=20 > + gBS->DisconnectController (HandleBuffer[Index], ImageHandle, NULL); >=20 > + } >=20 > + >=20 > + // >=20 > + // Free the array of handles >=20 > + // >=20 > + if (HandleBuffer !=3D NULL) { >=20 > + FreePool (HandleBuffer); >=20 > + } >=20 > + >=20 > + // >=20 > + // Uninstall protocols installed in the driver entry point >=20 > + // >=20 > + Status =3D gBS->UninstallMultipleProtocolInterfaces ( >=20 > + ImageHandle, >=20 > + &gEfiDriverBindingProtocolGuid, >=20 > + &gVirtualKeyboardDriverBinding, >=20 > + &gEfiComponentNameProtocolGuid, >=20 > + &gVirtualKeyboardComponentName, >=20 > + &gEfiComponentName2ProtocolGuid, >=20 > + &gVirtualKeyboardComponentName2, >=20 > + NULL >=20 > + ); >=20 > + if (EFI_ERROR (Status)) { >=20 > + ASSERT_EFI_ERROR (Status); >=20 > + goto Error; >=20 > + } >=20 > + >=20 > + HiiRemovePackages (mHiiHandle); >=20 > + >=20 > + DEBUG ((DEBUG_VK_ROUTINE_ENTRY_EXIT, "VirtualKeyboardDriverUnload Succ= ess, Status: %r\n", Status)); >=20 > + goto End; >=20 > + >=20 > +Error: >=20 > + DEBUG ((DEBUG_VK_ROUTINE_ENTRY_EXIT, "VirtualKeyboardDriverUnload Fail= ed, Status: %r\n", Status)); >=20 > + >=20 > +End: >=20 > + DEBUG ((DEBUG_VK_ROUTINE_ENTRY_EXIT, "VirtualKeyboardDriverUnload End\= n")); >=20 > + return Status; >=20 > +} >=20 > diff --git a/Features/Intel/UserInterface/VirtualKeyboardFeaturePkg/Virtu= alKeyboardDxe/VirtualKeyboardDxe.inf > b/Features/Intel/UserInterface/VirtualKeyboardFeaturePkg/VirtualKeyboardD= xe/VirtualKeyboardDxe.inf > new file mode 100644 > index 0000000000..9ecc99d5a7 > --- /dev/null > +++ b/Features/Intel/UserInterface/VirtualKeyboardFeaturePkg/VirtualKeybo= ardDxe/VirtualKeyboardDxe.inf > @@ -0,0 +1,77 @@ > +## @file >=20 > +# Instance of virtual keyboard driver binding protocol. >=20 > +# >=20 > +# Compliant with efi driver model, 1. VirtualKeyboardDriverSupported >=20 > +# determines if the pointer and GOP are available. 2. >=20 > +# VirtualKeyboardDriverStart initializes an instance of the virtual >=20 > +# keyboard driver for a particular controller. 3. >=20 > +# VirtualKeyboardDriverStop is called by DriverUnload when the I2C bus >=20 > +# driver is being unload. >=20 > +# >=20 > +# Copyright (c) 2012 - 2020, Intel Corporation. All rights reserved.
    >=20 > +# SPDX-License-Identifier: BSD-2-Clause-Patent >=20 > +# >=20 > +## >=20 > + >=20 > +[Defines] >=20 > + INF_VERSION =3D 0x00010017 >=20 > + BASE_NAME =3D VirtualKeyboardDxe >=20 > + FILE_GUID =3D E4735AAC-9C27-493f-86EA-9EFF43D7ADC= D >=20 > + VERSION_STRING =3D 1.0 >=20 > + MODULE_TYPE =3D UEFI_DRIVER >=20 > + ENTRY_POINT =3D VirtualKeyboardDriverEntryPoint >=20 > + UNLOAD_IMAGE =3D VirtualKeyboardDriverUnload >=20 > + >=20 > +# >=20 > +# VALID_ARCHITECTURES =3D IA32 X64 >=20 > +# DRIVER_BINDING =3D gVirtualKeyboardDriverBinding; >=20 > +# COMPONENT_NAME =3D gVirtualKeyboardComponentName; >=20 > +# COMPONENT_NAME2 =3D gVirtualKeyboardComponentName2; >=20 > +# >=20 > + >=20 > +[LibraryClasses] >=20 > + BaseMemoryLib >=20 > + DebugLib >=20 > + MemoryAllocationLib >=20 > + UefiBootServicesTableLib >=20 > + UefiDriverEntryPoint >=20 > + UefiLib >=20 > + PcdLib >=20 > + HiiLib >=20 > + >=20 > +[Packages] >=20 > + MdePkg/MdePkg.dec >=20 > + MdeModulePkg/MdeModulePkg.dec >=20 > + UserInterface/VirtualKeyboardFeaturePkg/VirtualKeyboardFeaturePkg.dec >=20 > + >=20 > +[Pcd] >=20 > + gEfiMdeModulePkgTokenSpaceGuid.PcdConOutRow >=20 > + gEfiMdeModulePkgTokenSpaceGuid.PcdSetupConOutRow >=20 > + >=20 > +[Sources] >=20 > + CapitalLetterKeyboard.bmp >=20 > + DigitKeyboard.bmp >=20 > + FullIcon.bmp >=20 > + SimpleIcon.bmp >=20 > + SimpleKeyboard.bmp >=20 > + KeyboardLayout.idf >=20 > + KeyboardLayout.c >=20 > + ComponentName.c >=20 > + Keyboard.c >=20 > + VirtualKeyboard.h >=20 > + VirtualKeyboardDriver.c >=20 > + >=20 > +[Protocols] >=20 > + gEfiAbsolutePointerProtocolGuid ## TO_START >=20 > + gEfiDriverBindingProtocolGuid ## PRODUCES >=20 > + gEfiGraphicsOutputProtocolGuid ## TO_START >=20 > + gEfiSimpleTextInProtocolGuid ## BY_START >=20 > + gEfiSimpleTextInputExProtocolGuid ## BY_START >=20 > + gEfiHiiImageExProtocolGuid ## TO_START >=20 > + >=20 > +[Guids] >=20 > + gEfiConsoleInDeviceGuid ## SOMETIMES_PRODUCES >=20 > + gEfiTouchPanelGuid ## TO_START >=20 > + >=20 > +[Depex] >=20 > + gEfiHiiDatabaseProtocolGuid >=20 > diff --git a/Features/Intel/UserInterface/VirtualKeyboardFeaturePkg/Virtu= alKeyboardFeaturePkg.dec > b/Features/Intel/UserInterface/VirtualKeyboardFeaturePkg/VirtualKeyboardF= eaturePkg.dec > new file mode 100644 > index 0000000000..2742a04a8f > --- /dev/null > +++ b/Features/Intel/UserInterface/VirtualKeyboardFeaturePkg/VirtualKeybo= ardFeaturePkg.dec > @@ -0,0 +1,26 @@ > +## @file >=20 > +# This package provides advanced feature functionality for User Authenti= cation support. >=20 > +# This package should only depend on EDK II Core packages, IntelSiliconP= kg, and MinPlatformPkg. >=20 > +# >=20 > +# The DEC files are used by the utilities that parse DSC and >=20 > +# INF files to generate AutoGen.c and AutoGen.h files >=20 > +# for the build infrastructure. >=20 > +# >=20 > +# Copyright (c) 2020, Intel Corporation. All rights reserved.
    >=20 > +# >=20 > +# SPDX-License-Identifier: BSD-2-Clause-Patent >=20 > +# >=20 > +## >=20 > + >=20 > +[Defines] >=20 > + DEC_SPECIFICATION =3D 0x00010017 >=20 > + PACKAGE_NAME =3D VirtualKeyboardFeaturePkg >=20 > + PACKAGE_GUID =3D A40DFD69-3552-40E8-8D3D-89741B03B9E1 >=20 > + PACKAGE_VERSION =3D 0.1 >=20 > + >=20 > +[Includes] >=20 > + Include >=20 > + >=20 > +[Guids] >=20 > + ## GUID used for VirtualKeyboardDriver to open TouchPanel protocol. >=20 > + gEfiTouchPanelGuid =3D { 0x91b1d27b, 0xe= 126, 0x48d1, { 0x82, 0x34, 0xd2, 0x8b, 0x81, 0xc8, 0x83, 0x62 }} >=20 > diff --git a/Features/Intel/UserInterface/VirtualKeyboardFeaturePkg/Virtu= alKeyboardFeaturePkg.dsc > b/Features/Intel/UserInterface/VirtualKeyboardFeaturePkg/VirtualKeyboardF= eaturePkg.dsc > new file mode 100644 > index 0000000000..ab3605fa15 > --- /dev/null > +++ b/Features/Intel/UserInterface/VirtualKeyboardFeaturePkg/VirtualKeybo= ardFeaturePkg.dsc > @@ -0,0 +1,30 @@ > +## @file >=20 > +# This is a build description file for the User Authentication advanced = feature. >=20 > +# This package should only depend on EDK II Core packages, IntelSiliconP= kg, and MinPlatformPkg. >=20 > +# >=20 > +# The DEC files are used by the utilities that parse DSC and >=20 > +# INF files to generate AutoGen.c and AutoGen.h files >=20 > +# for the build infrastructure. >=20 > +# >=20 > +# Copyright (c) 2020, Intel Corporation. All rights reserved.
    >=20 > +# >=20 > +# SPDX-License-Identifier: BSD-2-Clause-Patent >=20 > +# >=20 > +## >=20 > + >=20 > +[Defines] >=20 > + PLATFORM_NAME =3D VirtualKeyboardFeaturePkg >=20 > + PLATFORM_GUID =3D 6D396683-C82B-41D5-84E7-BB6E13B7C2B= F >=20 > + PLATFORM_VERSION =3D 0.1 >=20 > + DSC_SPECIFICATION =3D 0x00010005 >=20 > + OUTPUT_DIRECTORY =3D Build/$(PLATFORM_NAME) >=20 > + SUPPORTED_ARCHITECTURES =3D IA32|X64 >=20 > + BUILD_TARGETS =3D DEBUG|RELEASE|NOOPT >=20 > + SKUID_IDENTIFIER =3D DEFAULT >=20 > + PEI_ARCH =3D IA32 >=20 > + DXE_ARCH =3D X64 >=20 > + >=20 > +# >=20 > +# This package always builds the feature. >=20 > +# >=20 > +!include Include/VirtualKeyboardFeature.dsc >=20 > -- > 2.24.0.windows.2 >=20 >=20 > -=3D-=3D-=3D-=3D-=3D-=3D > Groups.io Links: You receive all messages sent to this group. >=20 > View/Reply Online (#56348): https://edk2.groups.io/g/devel/message/56348 > Mute This Topic: https://groups.io/mt/72555278/1712937 > Group Owner: devel+owner@edk2.groups.io > Unsubscribe: https://edk2.groups.io/g/devel/unsub [ray.ni@intel.com] > -=3D-=3D-=3D-=3D-=3D-=3D