From eedf63f106db415cf5cba5d2c045e58bafe7226e Mon Sep 17 00:00:00 2001 From: Download-Fritz Date: Sat, 28 Sep 2019 15:33:57 +0200 Subject: [PATCH] OcInputLib: Initial import --- Include/Library/OcConfigurationLib.h | 15 + Include/Library/OcInputLib.h | 63 + Include/Protocol/AmiKeycode.h | 59 + Include/Protocol/AmiPointer.h | 82 + .../OcConfigurationLib/OcConfigurationLib.c | 15 + Library/OcInputLib/Keycode/AIK.c | 262 ++ Library/OcInputLib/Keycode/AIK.h | 113 + Library/OcInputLib/Keycode/AIKData.c | 81 + Library/OcInputLib/Keycode/AIKData.h | 57 + Library/OcInputLib/Keycode/AIKMap.c | 2394 +++++++++++++++++ Library/OcInputLib/Keycode/AIKShim.c | 198 ++ Library/OcInputLib/Keycode/AIKShim.h | 72 + Library/OcInputLib/Keycode/AIKSource.c | 212 ++ Library/OcInputLib/Keycode/AIKSource.h | 71 + Library/OcInputLib/Keycode/AIKTarget.c | 196 ++ Library/OcInputLib/Keycode/AIKTarget.h | 116 + Library/OcInputLib/Keycode/AIKTranslate.c | 199 ++ Library/OcInputLib/Keycode/AIKTranslate.h | 126 + Library/OcInputLib/Keycode/AppleHid.txt | 207 ++ Library/OcInputLib/OcInputLib.inf | 86 + Library/OcInputLib/Pointer/AIM.c | 573 ++++ Library/OcInputLib/Pointer/AIM.h | 57 + Library/OcInputLib/Timer/AIT.c | 88 + OcSupportPkg.dec | 7 + OcSupportPkg.dsc | 2 + 25 files changed, 5351 insertions(+) create mode 100644 Include/Library/OcInputLib.h create mode 100644 Include/Protocol/AmiKeycode.h create mode 100644 Include/Protocol/AmiPointer.h create mode 100644 Library/OcInputLib/Keycode/AIK.c create mode 100644 Library/OcInputLib/Keycode/AIK.h create mode 100644 Library/OcInputLib/Keycode/AIKData.c create mode 100644 Library/OcInputLib/Keycode/AIKData.h create mode 100644 Library/OcInputLib/Keycode/AIKMap.c create mode 100644 Library/OcInputLib/Keycode/AIKShim.c create mode 100644 Library/OcInputLib/Keycode/AIKShim.h create mode 100644 Library/OcInputLib/Keycode/AIKSource.c create mode 100644 Library/OcInputLib/Keycode/AIKSource.h create mode 100644 Library/OcInputLib/Keycode/AIKTarget.c create mode 100644 Library/OcInputLib/Keycode/AIKTarget.h create mode 100644 Library/OcInputLib/Keycode/AIKTranslate.c create mode 100644 Library/OcInputLib/Keycode/AIKTranslate.h create mode 100644 Library/OcInputLib/Keycode/AppleHid.txt create mode 100644 Library/OcInputLib/OcInputLib.inf create mode 100644 Library/OcInputLib/Pointer/AIM.c create mode 100644 Library/OcInputLib/Pointer/AIM.h create mode 100644 Library/OcInputLib/Timer/AIT.c diff --git a/Include/Library/OcConfigurationLib.h b/Include/Library/OcConfigurationLib.h index c72c0e9f..650154b3 100644 --- a/Include/Library/OcConfigurationLib.h +++ b/Include/Library/OcConfigurationLib.h @@ -428,6 +428,20 @@ OC_ARRAY (OC_STRING, _, __) OC_DECLARE (OC_UEFI_DRIVER_ARRAY) +/// +/// Input is a set of options to support advanced input. +/// +#define OC_UEFI_INPUT_FIELDS(_, __) \ + _(UINT8 , KeyForgetThreshold , , 0 , ()) \ + _(UINT8 , KeyMergeThreshold , , 0 , ()) \ + _(BOOLEAN , KeySupport , , FALSE , ()) \ + _(OC_STRING , KeySupportMode , , OC_STRING_CONSTR ("", _, __) , OC_DESTR (OC_STRING)) \ + _(BOOLEAN , KeySwap , , FALSE , ()) \ + _(BOOLEAN , PointerSupport , , FALSE , ()) \ + _(OC_STRING , PointerSupportMode , , OC_STRING_CONSTR ("", _, __) , OC_DESTR (OC_STRING)) \ + _(UINT32 , TimerResolution , , 0 , ()) +OC_DECLARE (OC_UEFI_INPUT) + /// /// Prefer own protocol implementation for these protocols. /// @@ -467,6 +481,7 @@ #define OC_UEFI_CONFIG_FIELDS(_, __) \ _(BOOLEAN , ConnectDrivers , , FALSE , ()) \ _(OC_UEFI_DRIVER_ARRAY , Drivers , , OC_CONSTR2 (OC_UEFI_DRIVER_ARRAY, _, __) , OC_DESTR (OC_UEFI_DRIVER_ARRAY)) \ + _(OC_UEFI_INPUT , Input , , OC_CONSTR2 (OC_UEFI_INPUT, _, __) , OC_DESTR (OC_UEFI_INPUT)) \ _(OC_UEFI_PROTOCOLS , Protocols , , OC_CONSTR2 (OC_UEFI_PROTOCOLS, _, __) , OC_DESTR (OC_UEFI_PROTOCOLS)) \ _(OC_UEFI_QUIRKS , Quirks , , OC_CONSTR2 (OC_UEFI_QUIRKS, _, __) , OC_DESTR (OC_UEFI_QUIRKS)) OC_DECLARE (OC_UEFI_CONFIG) diff --git a/Include/Library/OcInputLib.h b/Include/Library/OcInputLib.h new file mode 100644 index 00000000..1e57d913 --- /dev/null +++ b/Include/Library/OcInputLib.h @@ -0,0 +1,63 @@ +/** @file + OC Apple generic input library. + +Copyright (c) 2019, vit9696. All rights reserved.
+This program and the accompanying materials +are licensed and made available under the terms and conditions of the BSD License +which accompanies this distribution. The full text of the license may be found at +http://opensource.org/licenses/bsd-license.php + +THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, +WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. + +**/ + +#ifndef OC_APPLE_GENERIC_INPUT_LIB_H +#define OC_APPLE_GENERIC_INPUT_LIB_H + +typedef enum { + OcInputPointerModeAsus, + OcInputPointerModeMax +} OC_INPUT_POINTER_MODE; + +typedef enum { + OcInputKeyModeAuto, + OcInputKeyModeV1, + OcInputKeyModeV2, + OcInputKeyModeAmi, + OcInputKeyModeMax +} OC_INPUT_KEY_MODE; + +EFI_STATUS +OcAppleGenericInputTimerQuirkInit ( + IN UINT32 TimerResolution + ); + +EFI_STATUS +OcAppleGenericInputTimerQuirkExit ( + VOID + ); + +EFI_STATUS +OcAppleGenericInputPointerInit ( + IN OC_INPUT_POINTER_MODE Mode + ); + +EFI_STATUS +OcAppleGenericInputPointerExit ( + VOID + ); + +EFI_STATUS +OcAppleGenericInputKeycodeInit ( + IN OC_INPUT_KEY_MODE Mode, + IN UINT8 KeyForgotThreshold, + IN UINT8 KeyMergeThreshold + ); + +EFI_STATUS +OcAppleGenericInputKeycodeExit ( + VOID + ); + +#endif // OC_APPLE_GENERIC_INPUT_LIB_H diff --git a/Include/Protocol/AmiKeycode.h b/Include/Protocol/AmiKeycode.h new file mode 100644 index 00000000..f1faf0da --- /dev/null +++ b/Include/Protocol/AmiKeycode.h @@ -0,0 +1,59 @@ +/** @file + Header file for AMI EfiKeycode protocol definitions. + +Copyright (c) 2016, vit9696. All rights reserved.
+This program and the accompanying materials +are licensed and made available under the terms and conditions of the BSD License +which accompanies this distribution. The full text of the license may be found at +http://opensource.org/licenses/bsd-license.php + +THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, +WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. + +**/ +#ifndef AMI_KEYCODE_H +#define AMI_KEYCODE_H + +// 0ADFB62D-FF74-484C-8944-F85C4BEA87A8 +#define AMI_EFIKEYCODE_PROTOCOL_GUID \ + { 0x0ADFB62D, 0xFF74, 0x484C, { 0x89, 0x44, 0xF8, 0x5C, 0x4B, 0xEA, 0x87, 0xA8 } } + +extern EFI_GUID gAmiEfiKeycodeProtocolGuid; + +typedef struct _AMI_EFIKEYCODE_PROTOCOL AMI_EFIKEYCODE_PROTOCOL; + +#ifndef KEY_STATE_EXPOSED +#define KEY_STATE_EXPOSED 0x40 +#endif + +typedef struct { + EFI_INPUT_KEY Key; + EFI_KEY_STATE KeyState; + EFI_KEY EfiKey; + UINT8 EfiKeyIsValid; + UINT8 PS2ScanCode; + UINT8 PS2ScanCodeIsValid; +} AMI_EFI_KEY_DATA; + +typedef EFI_STATUS (EFIAPI *AMI_READ_EFI_KEY) ( + IN AMI_EFIKEYCODE_PROTOCOL *This, + OUT AMI_EFI_KEY_DATA *KeyData + ); + +typedef +EFI_STATUS +(EFIAPI *AMI_RESET_EX) ( + IN AMI_EFIKEYCODE_PROTOCOL *This, + IN BOOLEAN ExtendedVerification + ); + +struct _AMI_EFIKEYCODE_PROTOCOL { + AMI_RESET_EX Reset; + AMI_READ_EFI_KEY ReadEfikey; + EFI_EVENT WaitForKeyEx; + EFI_SET_STATE SetState; + EFI_REGISTER_KEYSTROKE_NOTIFY RegisterKeyNotify; + EFI_UNREGISTER_KEYSTROKE_NOTIFY UnregisterKeyNotify; +}; + +#endif // AMI_KEYCODE_H diff --git a/Include/Protocol/AmiPointer.h b/Include/Protocol/AmiPointer.h new file mode 100644 index 00000000..cfb90393 --- /dev/null +++ b/Include/Protocol/AmiPointer.h @@ -0,0 +1,82 @@ +/** @file + Header file for AMI EfiPointer protocol definitions. + +Copyright (c) 2016, vit9696. All rights reserved.
+This program and the accompanying materials +are licensed and made available under the terms and conditions of the BSD License +which accompanies this distribution. The full text of the license may be found at +http://opensource.org/licenses/bsd-license.php + +THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, +WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. + +**/ +#ifndef AMI_POINTER_H +#define AMI_POINTER_H + +#include + +// 15A10CE7-EAB5-43BF-9042-74432E696377 +#define AMI_EFIPOINTER_PROTOCOL_GUID \ + { 0x15A10CE7, 0xEAB5, 0x43BF, { 0x90, 0x42, 0x74, 0x43, 0x2E, 0x69, 0x63, 0x77 } } + +extern EFI_GUID gAmiEfiPointerProtocolGuid; + +typedef struct _AMI_EFIPOINTER_PROTOCOL AMI_EFIPOINTER_PROTOCOL; + +// Unless Changed == 1, no data is provided +typedef struct { + UINT8 Absolute; + UINT8 One; + UINT8 Changed; + UINT8 Reserved; + INT32 PositionX; + INT32 PositionY; + INT32 PositionZ; +} AMI_POINTER_POSITION_STATE_DATA; + +OC_STATIC_ASSERT ( + sizeof (AMI_POINTER_POSITION_STATE_DATA) == 16, + "AMI_POINTER_POSITION_STATE_DATA is expected to be 16 bytes" + ); + +// Unless Changed == 1, no data is provided +typedef struct { + UINT8 Changed; + UINT8 LeftButton; + UINT8 MiddleButton; + UINT8 RightButton; +} AMI_POINTER_BUTTON_STATE_DATA; + +OC_STATIC_ASSERT ( + sizeof (AMI_POINTER_BUTTON_STATE_DATA) == 4, + "AMI_POINTER_BUTTON_STATE_DATA is expected to be 4 bytes" + ); + +typedef +VOID +(EFIAPI *AMI_EFIPOINTER_RESET) ( + IN AMI_EFIPOINTER_PROTOCOL *This + ); + +typedef +VOID +(EFIAPI *AMI_EFIPOINTER_GET_BUTTON_STATE) ( + IN AMI_EFIPOINTER_PROTOCOL *This, + OUT AMI_POINTER_BUTTON_STATE_DATA *State + ); + +typedef +VOID +(EFIAPI *AMI_EFIPOINTER_GET_POSITION_STATE) ( + IN AMI_EFIPOINTER_PROTOCOL *This, + OUT AMI_POINTER_POSITION_STATE_DATA *State + ); + +struct _AMI_EFIPOINTER_PROTOCOL { + AMI_EFIPOINTER_RESET Reset; + AMI_EFIPOINTER_GET_POSITION_STATE GetPositionState; + AMI_EFIPOINTER_GET_BUTTON_STATE GetButtonState; +}; + +#endif // AMI_POINTER_H diff --git a/Library/OcConfigurationLib/OcConfigurationLib.c b/Library/OcConfigurationLib/OcConfigurationLib.c index 64cc8d84..8947525f 100644 --- a/Library/OcConfigurationLib/OcConfigurationLib.c +++ b/Library/OcConfigurationLib/OcConfigurationLib.c @@ -63,6 +63,7 @@ OC_STRUCTORS (OC_PLATFORM_SMBIOS_CONFIG, ()) OC_STRUCTORS (OC_PLATFORM_CONFIG, ()) OC_ARRAY_STRUCTORS (OC_UEFI_DRIVER_ARRAY) +OC_STRUCTORS (OC_UEFI_INPUT, ()) OC_STRUCTORS (OC_UEFI_PROTOCOLS, ()) OC_STRUCTORS (OC_UEFI_QUIRKS, ()) OC_STRUCTORS (OC_UEFI_CONFIG, ()) @@ -518,11 +519,25 @@ mUefiProtocolsSchema[] = { OC_SCHEMA_BOOLEAN_IN ("UnicodeCollation", OC_GLOBAL_CONFIG, Uefi.Protocols.UnicodeCollation) }; +STATIC +OC_SCHEMA +mUefiInputSchema[] = { + OC_SCHEMA_INTEGER_IN ("KeyForgetThreshold", OC_GLOBAL_CONFIG, Uefi.Input.KeyForgetThreshold), + OC_SCHEMA_INTEGER_IN ("KeyMergeThreshold", OC_GLOBAL_CONFIG, Uefi.Input.KeyMergeThreshold), + OC_SCHEMA_BOOLEAN_IN ("KeySupport", OC_GLOBAL_CONFIG, Uefi.Input.KeySupport), + OC_SCHEMA_STRING_IN ("KeySupportMode", OC_GLOBAL_CONFIG, Uefi.Input.KeySupportMode), + OC_SCHEMA_BOOLEAN_IN ("KeySwap", OC_GLOBAL_CONFIG, Uefi.Input.KeySwap), + OC_SCHEMA_BOOLEAN_IN ("PointerSupport", OC_GLOBAL_CONFIG, Uefi.Input.PointerSupport), + OC_SCHEMA_STRING_IN ("PointerSupportMode", OC_GLOBAL_CONFIG, Uefi.Input.PointerSupportMode), + OC_SCHEMA_INTEGER_IN ("TimerResolution", OC_GLOBAL_CONFIG, Uefi.Input.TimerResolution) +}; + STATIC OC_SCHEMA mUefiConfigurationSchema[] = { OC_SCHEMA_BOOLEAN_IN ("ConnectDrivers", OC_GLOBAL_CONFIG, Uefi.ConnectDrivers), OC_SCHEMA_ARRAY_IN ("Drivers", OC_GLOBAL_CONFIG, Uefi.Drivers, &mUefiDriversSchema), + OC_SCHEMA_DICT ("Input", mUefiInputSchema), OC_SCHEMA_DICT ("Protocols", mUefiProtocolsSchema), OC_SCHEMA_DICT ("Quirks", mUefiQuirksSchema) }; diff --git a/Library/OcInputLib/Keycode/AIK.c b/Library/OcInputLib/Keycode/AIK.c new file mode 100644 index 00000000..34aa34ad --- /dev/null +++ b/Library/OcInputLib/Keycode/AIK.c @@ -0,0 +1,262 @@ +/** @file + AmiEfiKeycode to KeyMapDb translator. + +Copyright (c) 2018, vit9696. All rights reserved.
+This program and the accompanying materials +are licensed and made available under the terms and conditions of the BSD License +which accompanies this distribution. The full text of the license may be found at +http://opensource.org/licenses/bsd-license.php + +THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, +WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. + +**/ + +#include + +#include "AIK.h" + +#include +#include +#include + +AIK_SELF gAikSelf; + +STATIC +VOID +EFIAPI +AIKProtocolArriveHandler ( + IN EFI_EVENT Event, + IN VOID *Context + ) +{ + EFI_STATUS Status; + AIK_SELF *Keycode; + + Keycode = (AIK_SELF *) Context; + + if (Keycode == NULL || Keycode->OurJobIsDone) { + DEBUG ((DEBUG_INFO, "AIKProtocolArriveHandler got null handler or called when done\n")); + return; + } + + Status = AIKInstall (Keycode); + if (!EFI_ERROR (Status)) { + // + // We are successful, so can remove the protocol polling event if any + // + AIKProtocolArriveUninstall (Keycode); + } else { + DEBUG ((DEBUG_INFO, "AIKProtocolArriveHandler AIKInstall failed - %r\n", Status)); + } +} + +EFI_STATUS +AIKProtocolArriveInstall ( + AIK_SELF *Keycode + ) +{ + EFI_STATUS Status; + VOID *Registration; + + Status = EFI_SUCCESS; + + if (Keycode->KeyMapDbArriveEvent == NULL) { + Status = gBS->CreateEvent (EVT_NOTIFY_SIGNAL, TPL_NOTIFY, AIKProtocolArriveHandler, Keycode, &Keycode->KeyMapDbArriveEvent); + + if (EFI_ERROR (Status)) { + DEBUG ((DEBUG_INFO, "KeyMapDbArriveEvent creation failed - %r\n", Status)); + } else { + Status = gBS->RegisterProtocolNotify (&gAppleKeyMapDatabaseProtocolGuid, Keycode->KeyMapDbArriveEvent, &Registration); + + if (EFI_ERROR (Status)) { + DEBUG ((DEBUG_INFO, "KeyMapDbArriveEvent registration failed - %r\n", Status)); + gBS->CloseEvent (Keycode->KeyMapDbArriveEvent); + Keycode->KeyMapDbArriveEvent = NULL; + } + } + } + + return Status; +} + +VOID +AIKProtocolArriveUninstall ( + AIK_SELF *Keycode + ) +{ + if (Keycode->KeyMapDbArriveEvent != NULL) { + gBS->CloseEvent (Keycode->KeyMapDbArriveEvent); + Keycode->KeyMapDbArriveEvent = NULL; + } +} + +VOID +EFIAPI +AIKPollKeyboardHandler ( + IN EFI_EVENT Event, + IN VOID *Context + ) +{ + AIK_SELF *Keycode; + UINT64 Counter; + UINTN Index; + AMI_EFI_KEY_DATA KeyData; + EFI_STATUS Status; + + Keycode = (AIK_SELF *) Context; + if (Keycode == NULL || Keycode->OurJobIsDone) { + DEBUG ((DEBUG_INFO, "AIKPollKeyboardHandler got null handler or called when done\n")); + return; + } + + Keycode->InPollKeyboardEvent = TRUE; + + // + // Counter is here for debugging purposes only. + // + Counter = AIKTargetRefresh (&Keycode->Target); + + // + // Some implementations return "partial key", which is a modifier without + // a key. When a modifier is held, we will get partial keys infinitely, so make sure + // we break after some time. + // + Index = 0; + + do { + Status = AIKSourceGrabEfiKey ( + &Keycode->Source, + &KeyData + ); + if (!EFI_ERROR (Status)) { + (VOID) Counter; + DEBUG ((DEBUG_VERBOSE, "Read key with scan 0x%X and unicode 0x%X at %Lu\n", + KeyData.Key.ScanCode, KeyData.Key.UnicodeChar, Counter + )); + AIKDataWriteEntry (&Keycode->Data, &KeyData); + AIKTargetWriteEntry (&Keycode->Target, &KeyData); + } + + Index++; + } while (!EFI_ERROR (Status) && Index < AIK_KEY_POLL_LIMIT); + + AIKTargetSubmit (&Keycode->Target); + + Keycode->InPollKeyboardEvent = FALSE; +} + +EFI_STATUS +AIKInstall ( + AIK_SELF *Keycode + ) +{ + EFI_STATUS Status; + + Status = AIKTargetInstall ( + &Keycode->Target, + Keycode->KeyForgotThreshold, + Keycode->KeyMergeThreshold + ); + + if (EFI_ERROR (Status)) { + // + // Working AppleKeyMapAggregator is not here yet. + // + return Status; + } + + Status = AIKSourceInstall (&Keycode->Source, Keycode->Mode); + + if (EFI_ERROR (Status)) { + // + // Cannot work with these sources. + // + AIKTargetUninstall (&Keycode->Target); + return Status; + } + + AIKDataReset (&Keycode->Data); + + Status = gBS->CreateEvent ( + EVT_TIMER | EVT_NOTIFY_SIGNAL, TPL_NOTIFY, + AIKPollKeyboardHandler, + Keycode, &Keycode->PollKeyboardEvent + ); + + if (!EFI_ERROR (Status)) { + Status = gBS->SetTimer (Keycode->PollKeyboardEvent, TimerPeriodic, AIK_KEY_POLL_INTERVAL); + if (EFI_ERROR (Status)) { + DEBUG ((DEBUG_INFO, "AIKPollKeyboardHandler timer setting failed - %r\n", Status)); + gBS->CloseEvent (Keycode->PollKeyboardEvent); + Keycode->PollKeyboardEvent = NULL; + } + } else { + DEBUG ((DEBUG_INFO, "AIKPollKeyboardHandler event creation failed - %r\n", Status)); + } + + if (EFI_ERROR (Status)) { + AIKSourceUninstall (&Keycode->Source); + AIKTargetUninstall (&Keycode->Target); + } + + return Status; +} + +VOID +AIKUninstall ( + AIK_SELF *Keycode + ) +{ + Keycode->OurJobIsDone = TRUE; + + AIKProtocolArriveUninstall (Keycode); + + if (Keycode->PollKeyboardEvent) { + gBS->SetTimer (Keycode->PollKeyboardEvent, TimerCancel, 0); + gBS->CloseEvent (Keycode->PollKeyboardEvent); + Keycode->PollKeyboardEvent = NULL; + } + + AIKSourceUninstall (&Keycode->Source); + AIKTargetUninstall (&Keycode->Target); +} + +EFI_STATUS +OcAppleGenericInputKeycodeInit ( + IN OC_INPUT_KEY_MODE Mode, + IN UINT8 KeyForgotThreshold, + IN UINT8 KeyMergeThreshold + ) +{ + EFI_STATUS Status; + + AIKTranslateConfigure (); + + gAikSelf.Mode = Mode; + gAikSelf.KeyForgotThreshold = KeyForgotThreshold; + gAikSelf.KeyMergeThreshold = KeyMergeThreshold; + Status = AIKInstall (&gAikSelf); + if (EFI_ERROR (Status)) { + DEBUG ((DEBUG_INFO, "AIKInstall failed - %r\n", Status)); + + // + // No AppleKeyMapAggregator present, install on its availability. + // + Status = AIKProtocolArriveInstall (&gAikSelf); + if (EFI_ERROR (Status)) { + DEBUG ((DEBUG_INFO, "AIK is NOT waiting for protocols - %r\n", Status)); + } + } + + return Status; +} + +EFI_STATUS +OcAppleGenericInputKeycodeExit ( + VOID + ) +{ + AIKUninstall (&gAikSelf); + return EFI_SUCCESS; +} diff --git a/Library/OcInputLib/Keycode/AIK.h b/Library/OcInputLib/Keycode/AIK.h new file mode 100644 index 00000000..dabef5e4 --- /dev/null +++ b/Library/OcInputLib/Keycode/AIK.h @@ -0,0 +1,113 @@ +/** @file + Header file for AmiEfiKeycode to KeyMapDb translator. + +Copyright (c) 2018, vit9696. All rights reserved.
+This program and the accompanying materials +are licensed and made available under the terms and conditions of the BSD License +which accompanies this distribution. The full text of the license may be found at +http://opensource.org/licenses/bsd-license.php + +THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, +WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. + +**/ +#ifndef AIK_SELF_H +#define AIK_SELF_H + +#include "AIKData.h" +#include "AIKSource.h" +#include "AIKTarget.h" +#include "AIKTranslate.h" + +#include +#include + +// +// Maximum amount of keys polled at once +// +#define AIK_KEY_POLL_LIMIT (AIK_TARGET_BUFFER_SIZE) + +// +// Defines key polling frequency +// +#define AIK_KEY_POLL_INTERVAL EFI_TIMER_PERIOD_MILLISECONDS(10) + +typedef struct { + // + // Input mode + // + OC_INPUT_KEY_MODE Mode; + + // + // Remove key if it was not submitted after this value. + // + UINT8 KeyForgotThreshold; + + // + // Assume simultaneous press if within this value. + // + UINT8 KeyMergeThreshold; + + // + // Input sources + // + AIK_SOURCE Source; + + // + // Output targets + // + AIK_TARGET Target; + + // + // Key data + // + AIK_DATA Data; + + // + // AppleKeyMapAggregator polling event + // + EFI_EVENT KeyMapDbArriveEvent; + + // + // Keyboard input polling event + // + EFI_EVENT PollKeyboardEvent; + + // + // Indicates keyboard input polling event to avoid reentrancy if any + // + BOOLEAN InPollKeyboardEvent; + + // + // Indicates we are done for any event in case it gets fired. + // Not really needed, put in case of bogus firmwares. + // + BOOLEAN OurJobIsDone; +} AIK_SELF; + +// +// This is only used in Shims, where no other way exists. +// +extern AIK_SELF gAikSelf; + +EFI_STATUS +AIKProtocolArriveInstall ( + AIK_SELF *Keycode + ); + +VOID +AIKProtocolArriveUninstall ( + AIK_SELF *Keycode + ); + +EFI_STATUS +AIKInstall ( + AIK_SELF *Keycode + ); + +VOID +AIKUninstall ( + AIK_SELF *Keycode + ); + +#endif diff --git a/Library/OcInputLib/Keycode/AIKData.c b/Library/OcInputLib/Keycode/AIKData.c new file mode 100644 index 00000000..0611fb3c --- /dev/null +++ b/Library/OcInputLib/Keycode/AIKData.c @@ -0,0 +1,81 @@ +/** @file + Key code ring + +Copyright (c) 2018, vit9696. All rights reserved.
+This program and the accompanying materials +are licensed and made available under the terms and conditions of the BSD License +which accompanies this distribution. The full text of the license may be found at +http://opensource.org/licenses/bsd-license.php + +THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, +WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. + +**/ + +#include "AIKData.h" + +#include +#include + +VOID +AIKDataReset ( + IN OUT AIK_DATA *Data + ) +{ + Data->KeyBufferHead = Data->KeyBufferTail = Data->KeyBuffer; + Data->KeyBufferSize = 0; +} + +BOOLEAN +AIKDataEmpty ( + IN AIK_DATA *Data + ) +{ + return Data->KeyBufferSize == 0; +} + +EFI_STATUS +AIKDataReadEntry ( + IN OUT AIK_DATA *Data, + OUT AMI_EFI_KEY_DATA *KeyData + ) +{ + if (Data->KeyBufferSize == 0) { + return EFI_NOT_READY; + } + + CopyMem (KeyData, Data->KeyBufferTail, sizeof (*KeyData)); + + Data->KeyBufferSize--; + Data->KeyBufferTail++; + if (Data->KeyBufferTail == &Data->KeyBuffer[AIK_DATA_BUFFER_SIZE]) { + Data->KeyBufferTail = Data->KeyBuffer; + } + + return EFI_SUCCESS; +} + +VOID +AIKDataWriteEntry ( + IN OUT AIK_DATA *Data, + IN AMI_EFI_KEY_DATA *KeyData + ) +{ + // + // Eat the first entry if we have no room + // + if (Data->KeyBufferSize == AIK_DATA_BUFFER_SIZE) { + Data->KeyBufferSize--; + Data->KeyBufferTail++; + if (Data->KeyBufferTail == &Data->KeyBuffer[AIK_DATA_BUFFER_SIZE]) { + Data->KeyBufferTail = Data->KeyBuffer; + } + } + + Data->KeyBufferSize++; + CopyMem (Data->KeyBufferHead, KeyData, sizeof (*KeyData)); + Data->KeyBufferHead++; + if (Data->KeyBufferHead == &Data->KeyBuffer[AIK_DATA_BUFFER_SIZE]) { + Data->KeyBufferHead = Data->KeyBuffer; + } +} diff --git a/Library/OcInputLib/Keycode/AIKData.h b/Library/OcInputLib/Keycode/AIKData.h new file mode 100644 index 00000000..81937194 --- /dev/null +++ b/Library/OcInputLib/Keycode/AIKData.h @@ -0,0 +1,57 @@ +/** @file + Key code ring + +Copyright (c) 2018, vit9696. All rights reserved.
+This program and the accompanying materials +are licensed and made available under the terms and conditions of the BSD License +which accompanies this distribution. The full text of the license may be found at +http://opensource.org/licenses/bsd-license.php + +THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, +WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. + +**/ + +#ifndef AIK_DATA_H +#define AIK_DATA_H + +#include + +// +// Maximum amount of keys queued for non-Apple protocols +// +#define AIK_DATA_BUFFER_SIZE 12 + +typedef struct { + // + // Stored key buffer for responding to non-Apple protocols + // + AMI_EFI_KEY_DATA KeyBuffer[AIK_DATA_BUFFER_SIZE]; + AMI_EFI_KEY_DATA *KeyBufferHead; + AMI_EFI_KEY_DATA *KeyBufferTail; + UINTN KeyBufferSize; +} AIK_DATA; + +VOID +AIKDataReset ( + IN OUT AIK_DATA *Data + ); + +BOOLEAN +AIKDataEmpty ( + IN AIK_DATA *Data + ); + +EFI_STATUS +AIKDataReadEntry ( + IN OUT AIK_DATA *Data, + OUT AMI_EFI_KEY_DATA *KeyData + ); + +VOID +AIKDataWriteEntry ( + IN OUT AIK_DATA *Data, + IN AMI_EFI_KEY_DATA *KeyData + ); + +#endif diff --git a/Library/OcInputLib/Keycode/AIKMap.c b/Library/OcInputLib/Keycode/AIKMap.c new file mode 100644 index 00000000..3e3e6dc7 --- /dev/null +++ b/Library/OcInputLib/Keycode/AIKMap.c @@ -0,0 +1,2394 @@ +/** @file + Key mapping tables. + +Copyright (c) 2018, vit9696. All rights reserved.
+This program and the accompanying materials +are licensed and made available under the terms and conditions of the BSD License +which accompanies this distribution. The full text of the license may be found at +http://opensource.org/licenses/bsd-license.php + +THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, +WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. + +**/ + +#include "AIKTranslate.h" + +#include + +#define AIK_DEBUG_STR DEBUG_POINTER + +// Conversion table +AIK_PS2KEY_TO_USB +gAikPs2KeyToUsbMap[AIK_MAX_PS2KEY_NUM] = { + { + UsbHidUndefined, + NULL, + NULL + }, // 0x00 + { + UsbHidUsageIdKbKpKeyEsc, + AIK_DEBUG_STR("Esc"), + AIK_DEBUG_STR("^ Esc ^") + }, // 0x01 + { + UsbHidUsageIdKbKpKeyOne, + AIK_DEBUG_STR("1"), + AIK_DEBUG_STR("!") + }, // 0x02 + { + UsbHidUsageIdKbKpKeyTwo, + AIK_DEBUG_STR("2"), + AIK_DEBUG_STR("@") + }, // 0x03 + { + UsbHidUsageIdKbKpKeyThree, + AIK_DEBUG_STR("3"), + AIK_DEBUG_STR("#") + }, // 0x04 + { + UsbHidUsageIdKbKpKeyFour, + AIK_DEBUG_STR("4"), + AIK_DEBUG_STR("$") + }, // 0x05 + { + UsbHidUsageIdKbKpKeyFive, + AIK_DEBUG_STR("5"), + AIK_DEBUG_STR("%") + }, // 0x06 + { + UsbHidUsageIdKbKpKeySix, + AIK_DEBUG_STR("6"), + AIK_DEBUG_STR("^") + }, // 0x07 + { + UsbHidUsageIdKbKpKeySeven, + AIK_DEBUG_STR("7"), + AIK_DEBUG_STR("&") + }, // 0x08 + { + UsbHidUsageIdKbKpKeyEight, + AIK_DEBUG_STR("8"), + AIK_DEBUG_STR("*") + }, // 0x09 + { + UsbHidUsageIdKbKpKeyNine, + AIK_DEBUG_STR("9"), + AIK_DEBUG_STR("(") + }, // 0x0A + { + UsbHidUsageIdKbKpKeyZero, + AIK_DEBUG_STR("0"), + AIK_DEBUG_STR(")") + }, // 0x0B + { + UsbHidUsageIdKbKpKeyMinus, + AIK_DEBUG_STR("-"), + AIK_DEBUG_STR("_") + }, // 0x0C + { + UsbHidUsageIdKbKpKeyEquals, + AIK_DEBUG_STR("="), + AIK_DEBUG_STR("+") + }, // 0x0D + { + UsbHidUsageIdKbKpKeyBackSpace, + AIK_DEBUG_STR("Backspace"), + AIK_DEBUG_STR("^ Backspace ^") + }, // 0x0E + { + UsbHidUsageIdKbKpKeyTab, + AIK_DEBUG_STR("Tab"), + AIK_DEBUG_STR("^ Tab ^") + }, // 0x0F + { + UsbHidUsageIdKbKpKeyQ, + AIK_DEBUG_STR("q"), + AIK_DEBUG_STR("Q") + }, // 0x10 + { + UsbHidUsageIdKbKpKeyW, + AIK_DEBUG_STR("w"), + AIK_DEBUG_STR("W") + }, // 0x11 + { + UsbHidUsageIdKbKpKeyE, + AIK_DEBUG_STR("e"), + AIK_DEBUG_STR("E") + }, // 0x12 + { + UsbHidUsageIdKbKpKeyR, + AIK_DEBUG_STR("r"), + AIK_DEBUG_STR("R") + }, // 0x13 + { + UsbHidUsageIdKbKpKeyT, + AIK_DEBUG_STR("t"), + AIK_DEBUG_STR("T") + }, // 0x14 + { + UsbHidUsageIdKbKpKeyY, + AIK_DEBUG_STR("y"), + AIK_DEBUG_STR("Y") + }, // 0x15 + { + UsbHidUsageIdKbKpKeyU, + AIK_DEBUG_STR("u"), + AIK_DEBUG_STR("U") + }, // 0x16 + { + UsbHidUsageIdKbKpKeyI, + AIK_DEBUG_STR("i"), + AIK_DEBUG_STR("I") + }, // 0x17 + { + UsbHidUsageIdKbKpKeyO, + AIK_DEBUG_STR("o"), + AIK_DEBUG_STR("O") + }, // 0x18 + { + UsbHidUsageIdKbKpKeyP, + AIK_DEBUG_STR("p"), + AIK_DEBUG_STR("P") + }, // 0x19 + { + UsbHidUsageIdKbKpKeyLeftBracket, + AIK_DEBUG_STR("["), + AIK_DEBUG_STR("{") + }, // 0x1A + { + UsbHidUsageIdKbKpKeyRightBracket, + AIK_DEBUG_STR("]"), + AIK_DEBUG_STR("}") + }, // 0x1B + { + UsbHidUsageIdKbKpKeyEnter, + AIK_DEBUG_STR("Enter"), + AIK_DEBUG_STR("^ Enter ^") + }, // 0x1C + { + UsbHidUndefined, + NULL, + NULL + }, // 0x1D + { + UsbHidUsageIdKbKpKeyA, + AIK_DEBUG_STR("a"), + AIK_DEBUG_STR("A") + }, // 0x1E + { + UsbHidUsageIdKbKpKeyS, + AIK_DEBUG_STR("s"), + AIK_DEBUG_STR("S") + }, // 0x1F + { + UsbHidUsageIdKbKpKeyD, + AIK_DEBUG_STR("d"), + AIK_DEBUG_STR("D") + }, // 0x20 + { + UsbHidUsageIdKbKpKeyF, + AIK_DEBUG_STR("f"), + AIK_DEBUG_STR("F") + }, // 0x21 + { + UsbHidUsageIdKbKpKeyG, + AIK_DEBUG_STR("g"), + AIK_DEBUG_STR("G") + }, // 0x22 + { + UsbHidUsageIdKbKpKeyH, + AIK_DEBUG_STR("h"), + AIK_DEBUG_STR("H") + }, // 0x23 + { + UsbHidUsageIdKbKpKeyJ, + AIK_DEBUG_STR("j"), + AIK_DEBUG_STR("J") + }, // 0x24 + { + UsbHidUsageIdKbKpKeyK, + AIK_DEBUG_STR("k"), + AIK_DEBUG_STR("K") + }, // 0x25 + { + UsbHidUsageIdKbKpKeyL, + AIK_DEBUG_STR("l"), + AIK_DEBUG_STR("L") + }, // 0x26 + { + UsbHidUsageIdKbKpKeySemicolon, + AIK_DEBUG_STR(";"), + AIK_DEBUG_STR(":") + }, // 0x27 + { + UsbHidUsageIdKbKpKeyQuotation, + AIK_DEBUG_STR("'"), + AIK_DEBUG_STR("\""), + }, // 0x28 + { + UsbHidUsageIdKbKpKeyAcute, + AIK_DEBUG_STR("`"), + AIK_DEBUG_STR("~") + }, // 0x29 + { + UsbHidUndefined, + NULL, + NULL + }, // 0x2A + { + UsbHidUsageIdKbKpKeyBackslash, + AIK_DEBUG_STR("\\"), + AIK_DEBUG_STR("|") + }, // 0x2B + { + UsbHidUsageIdKbKpKeyZ, + AIK_DEBUG_STR("z"), + AIK_DEBUG_STR("Z") + }, // 0x2C + { + UsbHidUsageIdKbKpKeyX, + AIK_DEBUG_STR("x"), + AIK_DEBUG_STR("X") + }, // 0x2D + { + UsbHidUsageIdKbKpKeyC, + AIK_DEBUG_STR("c"), + AIK_DEBUG_STR("C") + }, // 0x2E + { + UsbHidUsageIdKbKpKeyV, + AIK_DEBUG_STR("v"), + AIK_DEBUG_STR("V") + }, // 0x2F + { + UsbHidUsageIdKbKpKeyB, + AIK_DEBUG_STR("b"), + AIK_DEBUG_STR("B") + }, // 0x30 + { + UsbHidUsageIdKbKpKeyN, + AIK_DEBUG_STR("n"), + AIK_DEBUG_STR("N") + }, // 0x31 + { + UsbHidUsageIdKbKpKeyM, + AIK_DEBUG_STR("m"), + AIK_DEBUG_STR("M") + }, // 0x32 + { + UsbHidUsageIdKbKpKeyComma, + AIK_DEBUG_STR(","), + AIK_DEBUG_STR("<") + }, // 0x33 + { + UsbHidUsageIdKbKpKeyPeriod, + AIK_DEBUG_STR("."), + AIK_DEBUG_STR(">") + }, // 0x34 + { + UsbHidUsageIdKbKpKeySlash, + AIK_DEBUG_STR("/"), + AIK_DEBUG_STR("?") + }, // 0x35 + { + UsbHidUndefined, + NULL, + NULL + }, // 0x36 + { + UsbHidUsageIdKbKpPadKeyAsterisk, + AIK_DEBUG_STR("*"), + AIK_DEBUG_STR("^ * ^") + }, // 0x37 + { + UsbHidUndefined, + NULL, + NULL + }, // 0x38 + { + UsbHidUsageIdKbKpKeySpaceBar, + AIK_DEBUG_STR("Spacebar"), + AIK_DEBUG_STR("^ Spacebar ^") + }, // 0x39 + { + UsbHidUsageIdKbKpKeyCLock, + AIK_DEBUG_STR("CapsLock"), + AIK_DEBUG_STR("^ CapsLock ^") + }, // 0x3A + { + UsbHidUsageIdKbKpKeyF1, + AIK_DEBUG_STR("F1"), + AIK_DEBUG_STR("^ F1 ^") + }, // 0x3B + { + UsbHidUsageIdKbKpKeyF2, + AIK_DEBUG_STR("F2"), + AIK_DEBUG_STR("^ F2 ^") + }, // 0x3C + { + UsbHidUsageIdKbKpKeyF3, + AIK_DEBUG_STR("F3"), + AIK_DEBUG_STR("^ F3 ^") + }, // 0x3D + { + UsbHidUsageIdKbKpKeyF4, + AIK_DEBUG_STR("F4"), + AIK_DEBUG_STR("^ F4 ^") + }, // 0x3E + { + UsbHidUsageIdKbKpKeyF5, + AIK_DEBUG_STR("F5"), + AIK_DEBUG_STR("^ F5 ^") + }, // 0x3F + { + UsbHidUsageIdKbKpKeyF6, + AIK_DEBUG_STR("F6"), + AIK_DEBUG_STR("^ F6 ^") + }, // 0x40 + { + UsbHidUsageIdKbKpKeyF7, + AIK_DEBUG_STR("F7"), + AIK_DEBUG_STR("^ F7 ^") + }, // 0x41 + { + UsbHidUsageIdKbKpKeyF8, + AIK_DEBUG_STR("F8"), + AIK_DEBUG_STR("^ F8 ^") + }, // 0x42 + { + UsbHidUsageIdKbKpKeyF9, + AIK_DEBUG_STR("F9"), + AIK_DEBUG_STR("^ F9 ^") + }, // 0x43 + { + UsbHidUsageIdKbKpKeyF10, + AIK_DEBUG_STR("F10"), + AIK_DEBUG_STR("^ F10 ^") + }, // 0x44 + { + UsbHidUsageIdKbKpPadKeyNLck, + AIK_DEBUG_STR("NumLock"), + AIK_DEBUG_STR("^ NumLock ^") + }, // 0x45 + { + UsbHidUsageIdKbKpKeySLock, + AIK_DEBUG_STR("Scroll Lock"), + AIK_DEBUG_STR("^ Scroll Lock ^") + }, // 0x46 + { + UsbHidUsageIdKbKpKeyHome, + AIK_DEBUG_STR("Home"), + AIK_DEBUG_STR("^ Home ^") + }, // 0x47 + { + UsbHidUsageIdKbKpKeyUpArrow, + AIK_DEBUG_STR("Up"), + AIK_DEBUG_STR("^ Up ^") + }, // 0x48 + { + UsbHidUsageIdKbKpKeyPgUp, + AIK_DEBUG_STR("PageUp"), + AIK_DEBUG_STR("^ PageUp ^") + }, // 0x49 + { + UsbHidUsageIdKbKpPadKeyMinus, + AIK_DEBUG_STR("-"), + AIK_DEBUG_STR("^ - ^") + }, // 0x4A + { + UsbHidUsageIdKbKpKeyLeftArrow, + AIK_DEBUG_STR("Left"), + AIK_DEBUG_STR("^ Left ^") + }, // 0x4B + { + UsbHidUsageIdKbKpPadKeyFive, + AIK_DEBUG_STR("5"), + AIK_DEBUG_STR("^ 5 ^") + }, // 0x4C + { + UsbHidUsageIdKbKpKeyRightArrow, + AIK_DEBUG_STR("Right"), + AIK_DEBUG_STR("^ Right ^") + }, // 0x4D + { + UsbHidUsageIdKbKpPadKeyPlus, + AIK_DEBUG_STR("+"), + AIK_DEBUG_STR("^ + ^") + }, // 0x4E + { + UsbHidUsageIdKbKpKeyEnd, + AIK_DEBUG_STR("End"), + AIK_DEBUG_STR("^ End ^") + }, // 0x4F + { + UsbHidUsageIdKbKpKeyDownArrow, + AIK_DEBUG_STR("Down"), + AIK_DEBUG_STR("^ Down ^") + }, // 0x50 + { + UsbHidUsageIdKbKpKeyPgDn, + AIK_DEBUG_STR("PageDown"), + AIK_DEBUG_STR("^ PageDown ^") + }, // 0x51 + { + UsbHidUsageIdKbKpKeyIns, + AIK_DEBUG_STR("Insert"), + AIK_DEBUG_STR("^ Insert ^") + }, // 0x52 + { + UsbHidUsageIdKbKpKeyDel, + AIK_DEBUG_STR("Delete"), + AIK_DEBUG_STR("^ Delete ^") + }, // 0x53 + { + UsbHidUndefined, + NULL, + NULL + }, // 0x54 + { + UsbHidUndefined, + NULL, + NULL + }, // 0x55 + { + UsbHidUndefined, + NULL, + NULL + }, // 0x56 + { + UsbHidUsageIdKbKpKeyF11, + AIK_DEBUG_STR("F11"), + AIK_DEBUG_STR("^ F11 ^") + }, // 0x57 + { + UsbHidUsageIdKbKpKeyF12, + AIK_DEBUG_STR("F12"), + AIK_DEBUG_STR("^ F12 ^") + }, // 0x58 + { + UsbHidUndefined, + NULL, + NULL + }, // 0x59 + { + UsbHidUndefined, + NULL, + NULL + }, // 0x5A + { + UsbHidUndefined, + NULL, + NULL + }, // 0x5B + { + UsbHidUndefined, + NULL, + NULL + }, // 0x5C + { + UsbHidUndefined, + NULL, + NULL + }, // 0x5D + { + UsbHidUndefined, + NULL, + NULL + }, // 0x5E + { + UsbHidUndefined, + NULL, + NULL + }, // 0x5F + { + UsbHidUndefined, + NULL, + NULL + }, // 0x60 + { + UsbHidUndefined, + NULL, + NULL + }, // 0x61 + { + UsbHidUndefined, + NULL, + NULL + }, // 0x62 + { + UsbHidUndefined, + NULL, + NULL + }, // 0x63 + { + UsbHidUndefined, + NULL, + NULL + }, // 0x64 + { + UsbHidUndefined, + NULL, + NULL + }, // 0x65 + { + UsbHidUndefined, + NULL, + NULL + }, // 0x66 + { + UsbHidUndefined, + NULL, + NULL + }, // 0x67 + { + UsbHidUndefined, + NULL, + NULL + }, // 0x68 + { + UsbHidUndefined, + NULL, + NULL + }, // 0x69 + { + UsbHidUndefined, + NULL, + NULL + }, // 0x6A + { + UsbHidUndefined, + NULL, + NULL + }, // 0x6B + { + UsbHidUndefined, + NULL, + NULL + }, // 0x6C + { + UsbHidUndefined, + NULL, + NULL + }, // 0x6D + { + UsbHidUndefined, + NULL, + NULL + }, // 0x6E + { + UsbHidUndefined, + NULL, + NULL + }, // 0x6F + { + UsbHidUndefined, + NULL, + NULL + }, // 0x70 + { + UsbHidUndefined, + NULL, + NULL + }, // 0x71 + { + UsbHidUndefined, + NULL, + NULL + }, // 0x72 + { + UsbHidUndefined, + NULL, + NULL + }, // 0x73 + { + UsbHidUndefined, + NULL, + NULL + }, // 0x74 + { + UsbHidUndefined, + NULL, + NULL + }, // 0x75 + { + UsbHidUndefined, + NULL, + NULL + }, // 0x76 + { + UsbHidUndefined, + NULL, + NULL + }, // 0x77 + { + UsbHidUndefined, + NULL, + NULL + }, // 0x78 + { + UsbHidUndefined, + NULL, + NULL + }, // 0x79 + { + UsbHidUndefined, + NULL, + NULL + }, // 0x7A + { + UsbHidUndefined, + NULL, + NULL + }, // 0x7B + { + UsbHidUndefined, + NULL, + NULL + }, // 0x7C + { + UsbHidUndefined, + NULL, + NULL + }, // 0x7D + { + UsbHidUndefined, + NULL, + NULL + }, // 0x7E + { + UsbHidUndefined, + NULL, + NULL + } // 0x7F +}; + +AIK_ASCII_TO_USB +gAikAsciiToUsbMap[AIK_MAX_ASCII_NUM] = { + { + UsbHidUndefined, + 0, + AIK_DEBUG_STR("NUL") + }, + { + UsbHidUndefined, + 0, + AIK_DEBUG_STR("SOH") + }, + { + UsbHidUndefined, + 0, + AIK_DEBUG_STR("STX") + }, + { + UsbHidUndefined, + 0, + AIK_DEBUG_STR("ETX") + }, + { + UsbHidUndefined, + 0, + AIK_DEBUG_STR("EOT") + }, + { + UsbHidUndefined, + 0, + AIK_DEBUG_STR("ENQ") + }, + { + UsbHidUndefined, + 0, + AIK_DEBUG_STR("ACK") + }, + { + UsbHidUndefined, + 0, + AIK_DEBUG_STR("BEL") + }, + { + UsbHidUsageIdKbKpKeyBackSpace, + 0, + AIK_DEBUG_STR("BS") + }, + { + UsbHidUsageIdKbKpKeyTab, + 0, + AIK_DEBUG_STR("HT") + }, + { + UsbHidUndefined, + 0, + AIK_DEBUG_STR("LF") + }, + { + UsbHidUndefined, + 0, + AIK_DEBUG_STR("VT") + }, + { + UsbHidUndefined, + 0, + AIK_DEBUG_STR("FF") + }, + { + UsbHidUsageIdKbKpKeyEnter, + 0, + AIK_DEBUG_STR("CR") + }, + { + UsbHidUndefined, + 0, + AIK_DEBUG_STR("SO") + }, + { + UsbHidUndefined, + 0, + AIK_DEBUG_STR("SI") + }, + { + UsbHidUndefined, + 0, + AIK_DEBUG_STR("DLE") + }, + { + UsbHidUndefined, + 0, + AIK_DEBUG_STR("DC1") + }, + { + UsbHidUndefined, + 0, + AIK_DEBUG_STR("DC2") + }, + { + UsbHidUndefined, + 0, + AIK_DEBUG_STR("DC3") + }, + { + UsbHidUndefined, + 0, + AIK_DEBUG_STR("DC4") + }, + { + UsbHidUndefined, + 0, + AIK_DEBUG_STR("NAK") + }, + { + UsbHidUndefined, + 0, + AIK_DEBUG_STR("SYN") + }, + { + UsbHidUndefined, + 0, + AIK_DEBUG_STR("ETB") + }, + { + UsbHidUndefined, + 0, + AIK_DEBUG_STR("CAN") + }, + { + UsbHidUndefined, + 0, + AIK_DEBUG_STR("EM") + }, + { + UsbHidUndefined, + 0, + AIK_DEBUG_STR("SUB") + }, + { + UsbHidUsageIdKbKpKeyEsc, + 0, + AIK_DEBUG_STR("ESC") + }, + { + UsbHidUndefined, + 0, + AIK_DEBUG_STR("FS") + }, + { + UsbHidUndefined, + 0, + AIK_DEBUG_STR("GS") + }, + { + UsbHidUndefined, + 0, + AIK_DEBUG_STR("RS") + }, + { + UsbHidUndefined, + 0, + AIK_DEBUG_STR("US") + }, + { + UsbHidUsageIdKbKpKeySpaceBar, + 0, + AIK_DEBUG_STR("SP") + }, + { + UsbHidUsageIdKbKpKeyOne, + EFI_SHIFT_STATE_VALID | EFI_LEFT_SHIFT_PRESSED, + AIK_DEBUG_STR("!") + }, + { + UsbHidUsageIdKbKpKeyQuotation, + EFI_SHIFT_STATE_VALID | EFI_LEFT_SHIFT_PRESSED, + AIK_DEBUG_STR("\"") + }, + { + UsbHidUsageIdKbKpKeyThree, + EFI_SHIFT_STATE_VALID | EFI_LEFT_SHIFT_PRESSED, + AIK_DEBUG_STR("#") + }, + { + UsbHidUsageIdKbKpKeyFour, + EFI_SHIFT_STATE_VALID | EFI_LEFT_SHIFT_PRESSED, + AIK_DEBUG_STR("$") + }, + { + UsbHidUsageIdKbKpKeyFive, + EFI_SHIFT_STATE_VALID | EFI_LEFT_SHIFT_PRESSED, + AIK_DEBUG_STR("%") + }, + { + UsbHidUsageIdKbKpKeySeven, + EFI_SHIFT_STATE_VALID | EFI_LEFT_SHIFT_PRESSED, + AIK_DEBUG_STR("&") + }, + { + UsbHidUsageIdKbKpKeyQuotation, + 0, + AIK_DEBUG_STR("'") + }, + { + UsbHidUsageIdKbKpKeyNine, + EFI_SHIFT_STATE_VALID | EFI_LEFT_SHIFT_PRESSED, + AIK_DEBUG_STR("(") + }, + { + UsbHidUsageIdKbKpKeyZero, + EFI_SHIFT_STATE_VALID | EFI_LEFT_SHIFT_PRESSED, + AIK_DEBUG_STR(")") + }, + { + UsbHidUsageIdKbKpKeyEight, + EFI_SHIFT_STATE_VALID | EFI_LEFT_SHIFT_PRESSED, + AIK_DEBUG_STR("*") + }, + { + UsbHidUsageIdKbKpKeyEquals, + EFI_SHIFT_STATE_VALID | EFI_LEFT_SHIFT_PRESSED, + AIK_DEBUG_STR("+") + }, + { + UsbHidUsageIdKbKpKeyComma, + 0, + AIK_DEBUG_STR(",") + }, + { + UsbHidUsageIdKbKpKeyMinus, + 0, + AIK_DEBUG_STR("-") + }, + { + UsbHidUsageIdKbKpKeyPeriod, + 0, + AIK_DEBUG_STR(".") + }, + { + UsbHidUsageIdKbKpKeySlash, + 0, + AIK_DEBUG_STR("/") + }, + { + UsbHidUsageIdKbKpKeyZero, + 0, + AIK_DEBUG_STR("0") + }, + { + UsbHidUsageIdKbKpKeyOne, + 0, + AIK_DEBUG_STR("1") + }, + { + UsbHidUsageIdKbKpKeyTwo, + 0, + AIK_DEBUG_STR("2") + }, + { + UsbHidUsageIdKbKpKeyThree, + 0, + AIK_DEBUG_STR("3") + }, + { + UsbHidUsageIdKbKpKeyFour, + 0, + AIK_DEBUG_STR("4") + }, + { + UsbHidUsageIdKbKpKeyFive, + 0, + AIK_DEBUG_STR("5") + }, + { + UsbHidUsageIdKbKpKeySix, + 0, + AIK_DEBUG_STR("6") + }, + { + UsbHidUsageIdKbKpKeySeven, + 0, + AIK_DEBUG_STR("7") + }, + { + UsbHidUsageIdKbKpKeyEight, + 0, + AIK_DEBUG_STR("8") + }, + { + UsbHidUsageIdKbKpKeyNine, + 0, + AIK_DEBUG_STR("9") + }, + { + UsbHidUsageIdKbKpKeySemicolon, + EFI_SHIFT_STATE_VALID | EFI_LEFT_SHIFT_PRESSED, + AIK_DEBUG_STR(":") + }, + { + UsbHidUsageIdKbKpKeySemicolon, + 0, + AIK_DEBUG_STR(";") + }, + { + UsbHidUsageIdKbKpKeyComma, + EFI_SHIFT_STATE_VALID | EFI_LEFT_SHIFT_PRESSED, + AIK_DEBUG_STR("<") + }, + { + UsbHidUsageIdKbKpKeyEquals, + 0, + AIK_DEBUG_STR("=") + }, + { + UsbHidUsageIdKbKpKeyPeriod, + EFI_SHIFT_STATE_VALID | EFI_LEFT_SHIFT_PRESSED, + AIK_DEBUG_STR(">") + }, + { + UsbHidUsageIdKbKpKeySlash, + EFI_SHIFT_STATE_VALID | EFI_LEFT_SHIFT_PRESSED, + AIK_DEBUG_STR("?") + }, + { + UsbHidUsageIdKbKpKeyTwo, + EFI_SHIFT_STATE_VALID | EFI_LEFT_SHIFT_PRESSED, + AIK_DEBUG_STR("@") + }, + { + UsbHidUsageIdKbKpKeyA, + EFI_SHIFT_STATE_VALID | EFI_LEFT_SHIFT_PRESSED, + AIK_DEBUG_STR("A") + }, + { + UsbHidUsageIdKbKpKeyB, + EFI_SHIFT_STATE_VALID | EFI_LEFT_SHIFT_PRESSED, + AIK_DEBUG_STR("B") + }, + { + UsbHidUsageIdKbKpKeyC, + EFI_SHIFT_STATE_VALID | EFI_LEFT_SHIFT_PRESSED, + AIK_DEBUG_STR("C") + }, + { + UsbHidUsageIdKbKpKeyD, + EFI_SHIFT_STATE_VALID | EFI_LEFT_SHIFT_PRESSED, + AIK_DEBUG_STR("D") + }, + { + UsbHidUsageIdKbKpKeyE, + EFI_SHIFT_STATE_VALID | EFI_LEFT_SHIFT_PRESSED, + AIK_DEBUG_STR("E") + }, + { + UsbHidUsageIdKbKpKeyF, + EFI_SHIFT_STATE_VALID | EFI_LEFT_SHIFT_PRESSED, + AIK_DEBUG_STR("F") + }, + { + UsbHidUsageIdKbKpKeyG, + EFI_SHIFT_STATE_VALID | EFI_LEFT_SHIFT_PRESSED, + AIK_DEBUG_STR("G") + }, + { + UsbHidUsageIdKbKpKeyH, + EFI_SHIFT_STATE_VALID | EFI_LEFT_SHIFT_PRESSED, + AIK_DEBUG_STR("H") + }, + { + UsbHidUsageIdKbKpKeyI, + EFI_SHIFT_STATE_VALID | EFI_LEFT_SHIFT_PRESSED, + AIK_DEBUG_STR("I") + }, + { + UsbHidUsageIdKbKpKeyJ, + EFI_SHIFT_STATE_VALID | EFI_LEFT_SHIFT_PRESSED, + AIK_DEBUG_STR("J") + }, + { + UsbHidUsageIdKbKpKeyK, + EFI_SHIFT_STATE_VALID | EFI_LEFT_SHIFT_PRESSED, + AIK_DEBUG_STR("K") + }, + { + UsbHidUsageIdKbKpKeyL, + EFI_SHIFT_STATE_VALID | EFI_LEFT_SHIFT_PRESSED, + AIK_DEBUG_STR("L") + }, + { + UsbHidUsageIdKbKpKeyM, + EFI_SHIFT_STATE_VALID | EFI_LEFT_SHIFT_PRESSED, + AIK_DEBUG_STR("M") + }, + { + UsbHidUsageIdKbKpKeyN, + EFI_SHIFT_STATE_VALID | EFI_LEFT_SHIFT_PRESSED, + AIK_DEBUG_STR("N") + }, + { + UsbHidUsageIdKbKpKeyO, + EFI_SHIFT_STATE_VALID | EFI_LEFT_SHIFT_PRESSED, + AIK_DEBUG_STR("O") + }, + { + UsbHidUsageIdKbKpKeyP, + EFI_SHIFT_STATE_VALID | EFI_LEFT_SHIFT_PRESSED, + AIK_DEBUG_STR("P") + }, + { + UsbHidUsageIdKbKpKeyQ, + EFI_SHIFT_STATE_VALID | EFI_LEFT_SHIFT_PRESSED, + AIK_DEBUG_STR("Q") + }, + { + UsbHidUsageIdKbKpKeyR, + EFI_SHIFT_STATE_VALID | EFI_LEFT_SHIFT_PRESSED, + AIK_DEBUG_STR("R") + }, + { + UsbHidUsageIdKbKpKeyS, + EFI_SHIFT_STATE_VALID | EFI_LEFT_SHIFT_PRESSED, + AIK_DEBUG_STR("S") + }, + { + UsbHidUsageIdKbKpKeyT, + EFI_SHIFT_STATE_VALID | EFI_LEFT_SHIFT_PRESSED, + AIK_DEBUG_STR("T") + }, + { + UsbHidUsageIdKbKpKeyU, + EFI_SHIFT_STATE_VALID | EFI_LEFT_SHIFT_PRESSED, + AIK_DEBUG_STR("U") + }, + { + UsbHidUsageIdKbKpKeyV, + EFI_SHIFT_STATE_VALID | EFI_LEFT_SHIFT_PRESSED, + AIK_DEBUG_STR("V") + }, + { + UsbHidUsageIdKbKpKeyW, + EFI_SHIFT_STATE_VALID | EFI_LEFT_SHIFT_PRESSED, + AIK_DEBUG_STR("W") + }, + { + UsbHidUsageIdKbKpKeyX, + EFI_SHIFT_STATE_VALID | EFI_LEFT_SHIFT_PRESSED, + AIK_DEBUG_STR("X") + }, + { + UsbHidUsageIdKbKpKeyY, + EFI_SHIFT_STATE_VALID | EFI_LEFT_SHIFT_PRESSED, + AIK_DEBUG_STR("Y") + }, + { + UsbHidUsageIdKbKpKeyZ, + EFI_SHIFT_STATE_VALID | EFI_LEFT_SHIFT_PRESSED, + AIK_DEBUG_STR("Z") + }, + { + UsbHidUsageIdKbKpKeyLeftBracket, + 0, + AIK_DEBUG_STR("[") + }, + { + UsbHidUsageIdKbKpKeyBackslash, + 0, + AIK_DEBUG_STR("\\") + }, + { + UsbHidUsageIdKbKpKeyRightBracket, + 0, + AIK_DEBUG_STR("]") + }, + { + UsbHidUsageIdKbKpKeyRightBracket, + 0, + AIK_DEBUG_STR("^") + }, + { + UsbHidUsageIdKbKpKeyMinus, + EFI_SHIFT_STATE_VALID | EFI_LEFT_SHIFT_PRESSED, + AIK_DEBUG_STR("_") + }, + { + UsbHidUsageIdKbKpKeyAcute, + 0, + AIK_DEBUG_STR("`") + }, + { + UsbHidUsageIdKbKpKeyA, + 0, + AIK_DEBUG_STR("a") + }, + { + UsbHidUsageIdKbKpKeyB, + 0, + AIK_DEBUG_STR("b") + }, + { + UsbHidUsageIdKbKpKeyC, + 0, + AIK_DEBUG_STR("c") + }, + { + UsbHidUsageIdKbKpKeyD, + 0, + AIK_DEBUG_STR("d") + }, + { + UsbHidUsageIdKbKpKeyE, + 0, + AIK_DEBUG_STR("e") + }, + { + UsbHidUsageIdKbKpKeyF, + 0, + AIK_DEBUG_STR("f") + }, + { + UsbHidUsageIdKbKpKeyG, + 0, + AIK_DEBUG_STR("g") + }, + { + UsbHidUsageIdKbKpKeyH, + 0, + AIK_DEBUG_STR("h") + }, + { + UsbHidUsageIdKbKpKeyI, + 0, + AIK_DEBUG_STR("i") + }, + { + UsbHidUsageIdKbKpKeyJ, + 0, + AIK_DEBUG_STR("j") + }, + { + UsbHidUsageIdKbKpKeyK, + 0, + AIK_DEBUG_STR("k") + }, + { + UsbHidUsageIdKbKpKeyL, + 0, + AIK_DEBUG_STR("l") + }, + { + UsbHidUsageIdKbKpKeyM, + 0, + AIK_DEBUG_STR("m") + }, + { + UsbHidUsageIdKbKpKeyN, + 0, + AIK_DEBUG_STR("n") + }, + { + UsbHidUsageIdKbKpKeyO, + 0, + AIK_DEBUG_STR("o") + }, + { + UsbHidUsageIdKbKpKeyP, + 0, + AIK_DEBUG_STR("p") + }, + { + UsbHidUsageIdKbKpKeyQ, + 0, + AIK_DEBUG_STR("q") + }, + { + UsbHidUsageIdKbKpKeyR, + 0, + AIK_DEBUG_STR("r") + }, + { + UsbHidUsageIdKbKpKeyS, + 0, + AIK_DEBUG_STR("s") + }, + { + UsbHidUsageIdKbKpKeyT, + 0, + AIK_DEBUG_STR("t") + }, + { + UsbHidUsageIdKbKpKeyU, + 0, + AIK_DEBUG_STR("u") + }, + { + UsbHidUsageIdKbKpKeyV, + 0, + AIK_DEBUG_STR("v") + }, + { + UsbHidUsageIdKbKpKeyW, + 0, + AIK_DEBUG_STR("w") + }, + { + UsbHidUsageIdKbKpKeyX, + 0, + AIK_DEBUG_STR("x") + }, + { + UsbHidUsageIdKbKpKeyY, + 0, + AIK_DEBUG_STR("y") + }, + { + UsbHidUsageIdKbKpKeyZ, + 0, + AIK_DEBUG_STR("z") + }, + { + UsbHidUsageIdKbKpKeyRightBracket, + EFI_SHIFT_STATE_VALID | EFI_LEFT_SHIFT_PRESSED, + AIK_DEBUG_STR("{") + }, + { + UsbHidUsageIdKbKpKeyBackslash, + EFI_SHIFT_STATE_VALID | EFI_LEFT_SHIFT_PRESSED, + AIK_DEBUG_STR("|") + }, + { + UsbHidUsageIdKbKpKeyRightBracket, + EFI_SHIFT_STATE_VALID | EFI_LEFT_SHIFT_PRESSED, + AIK_DEBUG_STR("}") + }, + { + UsbHidUsageIdKbKpKeyAcute, + EFI_SHIFT_STATE_VALID | EFI_LEFT_SHIFT_PRESSED, + AIK_DEBUG_STR("~") + }, + { + UsbHidUsageIdKbKpKeyDel, + 0, + AIK_DEBUG_STR("DEL") + }, +}; + +AIK_EFIKEY_TO_USB +gAikEfiKeyToUsbMap[AIK_MAX_EFIKEY_NUM] = { + { + UsbHidUndefined, + EFI_SHIFT_STATE_VALID | EFI_LEFT_CONTROL_PRESSED, + AIK_DEBUG_STR("EfiKeyLCtrl") + }, + { + UsbHidUndefined, + 0, + AIK_DEBUG_STR("EfiKeyA0") + }, + { + UsbHidUndefined, + EFI_SHIFT_STATE_VALID | EFI_LEFT_ALT_PRESSED, + AIK_DEBUG_STR("EfiKeyLAlt") + }, + { + UsbHidUsageIdKbKpKeySpaceBar, + 0, + AIK_DEBUG_STR("EfiKeySpaceBar") + }, + { + UsbHidUndefined, + 0, + AIK_DEBUG_STR("EfiKeyA2") + }, + { + UsbHidUndefined, + 0, + AIK_DEBUG_STR("EfiKeyA3") + }, + { + UsbHidUndefined, + 0, + AIK_DEBUG_STR("EfiKeyA4") + }, + { + UsbHidUndefined, + EFI_SHIFT_STATE_VALID | EFI_RIGHT_CONTROL_PRESSED, + AIK_DEBUG_STR("EfiKeyRCtrl") + }, + { + UsbHidUsageIdKbKpKeyLeftArrow, + 0, + AIK_DEBUG_STR("EfiKeyLeftArrow") + }, + { + UsbHidUsageIdKbKpKeyDownArrow, + 0, + AIK_DEBUG_STR("EfiKeyDownArrow") + }, + { + UsbHidUsageIdKbKpKeyRightArrow, + 0, + AIK_DEBUG_STR("EfiKeyRightArrow") + }, + { + UsbHidUsageIdKbKpKeyZero, + 0, + AIK_DEBUG_STR("EfiKeyZero") + }, + { + UsbHidUsageIdKbKpKeyPeriod, + 0, + AIK_DEBUG_STR("EfiKeyPeriod") + }, + { + UsbHidUsageIdKbKpKeyEnter, + 0, + AIK_DEBUG_STR("EfiKeyEnter") + }, + { + UsbHidUndefined, + EFI_SHIFT_STATE_VALID | EFI_LEFT_SHIFT_PRESSED, + AIK_DEBUG_STR("EfiKeyLShift") + }, + { + UsbHidUndefined, + 0, + AIK_DEBUG_STR("EfiKeyB0") + }, + { + UsbHidUndefined, + 0, + AIK_DEBUG_STR("EfiKeyB1") + }, + { + UsbHidUndefined, + 0, + AIK_DEBUG_STR("EfiKeyB2") + }, + { + UsbHidUndefined, + 0, + AIK_DEBUG_STR("EfiKeyB3") + }, + { + UsbHidUndefined, + 0, + AIK_DEBUG_STR("EfiKeyB4") + }, + { + UsbHidUndefined, + 0, + AIK_DEBUG_STR("EfiKeyB5") + }, + { + UsbHidUndefined, + 0, + AIK_DEBUG_STR("EfiKeyB6") + }, + { + UsbHidUndefined, + 0, + AIK_DEBUG_STR("EfiKeyB7") + }, + { + UsbHidUndefined, + 0, + AIK_DEBUG_STR("EfiKeyB8") + }, + { + UsbHidUndefined, + 0, + AIK_DEBUG_STR("EfiKeyB9") + }, + { + UsbHidUndefined, + 0, + AIK_DEBUG_STR("EfiKeyB10") + }, + { + UsbHidUndefined, + EFI_SHIFT_STATE_VALID | EFI_RIGHT_SHIFT_PRESSED, + AIK_DEBUG_STR("EfiKeyRshift") + }, + { + UsbHidUsageIdKbKpKeyUpArrow, + 0, + AIK_DEBUG_STR("EfiKeyUpArrow") + }, + { + UsbHidUsageIdKbKpKeyOne, + 0, + AIK_DEBUG_STR("EfiKeyOne") + }, + { + UsbHidUsageIdKbKpKeyTwo, + 0, + AIK_DEBUG_STR("EfiKeyTwo") + }, + { + UsbHidUsageIdKbKpKeyThree, + 0, + AIK_DEBUG_STR("EfiKeyThree") + }, + { + UsbHidUsageIdKbKpKeyCLock, + 0, + AIK_DEBUG_STR("EfiKeyCapsLock") + }, + { + UsbHidUndefined, + 0, + AIK_DEBUG_STR("EfiKeyC1") + }, + { + UsbHidUndefined, + 0, + AIK_DEBUG_STR("EfiKeyC2") + }, + { + UsbHidUndefined, + 0, + AIK_DEBUG_STR("EfiKeyC3") + }, + { + UsbHidUndefined, + 0, + AIK_DEBUG_STR("EfiKeyC4") + }, + { + UsbHidUndefined, + 0, + AIK_DEBUG_STR("EfiKeyC5") + }, + { + UsbHidUndefined, + 0, + AIK_DEBUG_STR("EfiKeyC6") + }, + { + UsbHidUndefined, + 0, + AIK_DEBUG_STR("EfiKeyC7") + }, + { + UsbHidUndefined, + 0, + AIK_DEBUG_STR("EfiKeyC8") + }, + { + UsbHidUndefined, + 0, + AIK_DEBUG_STR("EfiKeyC9") + }, + { + UsbHidUndefined, + 0, + AIK_DEBUG_STR("EfiKeyC10") + }, + { + UsbHidUndefined, + 0, + AIK_DEBUG_STR("EfiKeyC11") + }, + { + UsbHidUndefined, + 0, + AIK_DEBUG_STR("EfiKeyC12") + }, + { + UsbHidUsageIdKbKpKeyFour, + 0, + AIK_DEBUG_STR("EfiKeyFour") + }, + { + UsbHidUsageIdKbKpKeyFive, + 0, + AIK_DEBUG_STR("EfiKeyFive") + }, + { + UsbHidUsageIdKbKpKeySix, + 0, + AIK_DEBUG_STR("EfiKeySix") + }, + { + UsbHidUsageIdKbKpPadKeyPlus, + 0, + AIK_DEBUG_STR("EfiKeyPlus") + }, + { + UsbHidUsageIdKbKpKeyTab, + 0, + AIK_DEBUG_STR("EfiKeyTab") + }, + { + UsbHidUndefined, + 0, + AIK_DEBUG_STR("EfiKeyD1") + }, + { + UsbHidUndefined, + 0, + AIK_DEBUG_STR("EfiKeyD2") + }, + { + UsbHidUndefined, + 0, + AIK_DEBUG_STR("EfiKeyD3") + }, + { + UsbHidUndefined, + 0, + AIK_DEBUG_STR("EfiKeyD4") + }, + { + UsbHidUndefined, + 0, + AIK_DEBUG_STR("EfiKeyD5") + }, + { + UsbHidUndefined, + 0, + AIK_DEBUG_STR("EfiKeyD6") + }, + { + UsbHidUndefined, + 0, + AIK_DEBUG_STR("EfiKeyD7") + }, + { + UsbHidUndefined, + 0, + AIK_DEBUG_STR("EfiKeyD8") + }, + { + UsbHidUndefined, + 0, + AIK_DEBUG_STR("EfiKeyD9") + }, + { + UsbHidUndefined, + 0, + AIK_DEBUG_STR("EfiKeyD10") + }, + { + UsbHidUndefined, + 0, + AIK_DEBUG_STR("EfiKeyD11") + }, + { + UsbHidUndefined, + 0, + AIK_DEBUG_STR("EfiKeyD12") + }, + { + UsbHidUndefined, + 0, + AIK_DEBUG_STR("EfiKeyD13") + }, + { + UsbHidUsageIdKbKpKeyDel, + 0, + AIK_DEBUG_STR("EfiKeyDel") + }, + { + UsbHidUsageIdKbKpKeyEnd, + 0, + AIK_DEBUG_STR("EfiKeyEnd") + }, + { + UsbHidUsageIdKbKpKeyPgDn, + 0, + AIK_DEBUG_STR("EfiKeyPgDn") + }, + { + UsbHidUsageIdKbKpKeySeven, + 0, + AIK_DEBUG_STR("EfiKeySeven") + }, + { + UsbHidUsageIdKbKpKeyEight, + 0, + AIK_DEBUG_STR("EfiKeyEight") + }, + { + UsbHidUsageIdKbKpKeyNine, + 0, + AIK_DEBUG_STR("EfiKeyNine") + }, + { + UsbHidUndefined, + 0, + AIK_DEBUG_STR("EfiKeyE0") + }, + { + UsbHidUndefined, + 0, + AIK_DEBUG_STR("EfiKeyE1") + }, + { + UsbHidUndefined, + 0, + AIK_DEBUG_STR("EfiKeyE2") + }, + { + UsbHidUndefined, + 0, + AIK_DEBUG_STR("EfiKeyE3") + }, + { + UsbHidUndefined, + 0, + AIK_DEBUG_STR("EfiKeyE4") + }, + { + UsbHidUndefined, + 0, + AIK_DEBUG_STR("EfiKeyE5") + }, + { + UsbHidUndefined, + 0, + AIK_DEBUG_STR("EfiKeyE6") + }, + { + UsbHidUndefined, + 0, + AIK_DEBUG_STR("EfiKeyE7") + }, + { + UsbHidUndefined, + 0, + AIK_DEBUG_STR("EfiKeyE8") + }, + { + UsbHidUndefined, + 0, + AIK_DEBUG_STR("EfiKeyE9") + }, + { + UsbHidUndefined, + 0, + AIK_DEBUG_STR("EfiKeyE10") + }, + { + UsbHidUndefined, + 0, + AIK_DEBUG_STR("EfiKeyE11") + }, + { + UsbHidUndefined, + 0, + AIK_DEBUG_STR("EfiKeyE12") + }, + { + UsbHidUsageIdKbKpKeyBackSpace, + 0, + AIK_DEBUG_STR("EfiKeyBackSpace") + }, + { + UsbHidUsageIdKbKpKeyIns, + 0, + AIK_DEBUG_STR("EfiKeyIns") + }, + { + UsbHidUsageIdKbKpKeyHome, + 0, + AIK_DEBUG_STR("EfiKeyHome") + }, + { + UsbHidUsageIdKbKpKeyPgUp, + 0, + AIK_DEBUG_STR("EfiKeyPgUp") + }, + { + UsbHidUsageIdKbKpPadKeyNLck, + 0, + AIK_DEBUG_STR("EfiKeyNLck") + }, + { + UsbHidUsageIdKbKpKeySlash, + 0, + AIK_DEBUG_STR("EfiKeySlash") + }, + { + UsbHidUsageIdKbKpPadKeyAsterisk, + 0, + AIK_DEBUG_STR("EfiKeyAsterisk") + }, + { + UsbHidUsageIdKbKpPadKeyMinus, + 0, + AIK_DEBUG_STR("EfiKeyMinus") + }, + { + UsbHidUsageIdKbKpKeyEsc, + 0, + AIK_DEBUG_STR("EfiKeyEsc") + }, + { + UsbHidUsageIdKbKpKeyF1, + 0, + AIK_DEBUG_STR("EfiKeyF1") + }, + { + UsbHidUsageIdKbKpKeyF2, + 0, + AIK_DEBUG_STR("EfiKeyF2") + }, + { + UsbHidUsageIdKbKpKeyF3, + 0, + AIK_DEBUG_STR("EfiKeyF3") + }, + { + UsbHidUsageIdKbKpKeyF4, + 0, + AIK_DEBUG_STR("EfiKeyF4") + }, + { + UsbHidUsageIdKbKpKeyF5, + 0, + AIK_DEBUG_STR("EfiKeyF5") + }, + { + UsbHidUsageIdKbKpKeyF6, + 0, + AIK_DEBUG_STR("EfiKeyF6") + }, + { + UsbHidUsageIdKbKpKeyF7, + 0, + AIK_DEBUG_STR("EfiKeyF7") + }, + { + UsbHidUsageIdKbKpKeyF8, + 0, + AIK_DEBUG_STR("EfiKeyF8") + }, + { + UsbHidUsageIdKbKpKeyF9, + 0, + AIK_DEBUG_STR("EfiKeyF9") + }, + { + UsbHidUsageIdKbKpKeyF10, + 0, + AIK_DEBUG_STR("EfiKeyF10") + }, + { + UsbHidUsageIdKbKpKeyF11, + 0, + AIK_DEBUG_STR("EfiKeyF11") + }, + { + UsbHidUsageIdKbKpKeyF12, + 0, + AIK_DEBUG_STR("EfiKeyF12") + }, + { + UsbHidUsageIdKbKpKeyF13, + 0, + AIK_DEBUG_STR("EfiKeyPrint") + }, + { + UsbHidUsageIdKbKpKeySLock, + 0, + AIK_DEBUG_STR("EfiKeySLck") + }, + { + UsbHidUsageIdKbKpKeyPause, + 0, + AIK_DEBUG_STR("EfiKeyPause") + }, + { + UsbHidUndefined, + 0, + AIK_DEBUG_STR("Unk105") + }, + { + UsbHidUndefined, + 0, + AIK_DEBUG_STR("Unk106") + }, + { + UsbHidUndefined, + 0, + AIK_DEBUG_STR("Unk107") + }, + { + UsbHidUndefined, + 0, + AIK_DEBUG_STR("Unk108") + }, + { + UsbHidUndefined, + 0, + AIK_DEBUG_STR("Unk109") + }, + { + UsbHidUndefined, + 0, + AIK_DEBUG_STR("Unk110") + }, + { + UsbHidUndefined, + 0, + AIK_DEBUG_STR("Unk111") + }, + { + UsbHidUndefined, + 0, + AIK_DEBUG_STR("Unk112") + }, + { + UsbHidUndefined, + 0, + AIK_DEBUG_STR("Unk113") + }, + { + UsbHidUndefined, + 0, + AIK_DEBUG_STR("Unk114") + }, + { + UsbHidUndefined, + 0, + AIK_DEBUG_STR("Unk115") + }, + { + UsbHidUndefined, + 0, + AIK_DEBUG_STR("Unk116") + }, + { + UsbHidUndefined, + 0, + AIK_DEBUG_STR("Unk117") + }, + { + UsbHidUndefined, + 0, + AIK_DEBUG_STR("Unk118") + }, + { + UsbHidUndefined, + 0, + AIK_DEBUG_STR("Unk119") + }, + { + UsbHidUndefined, + 0, + AIK_DEBUG_STR("Unk120") + }, + { + UsbHidUndefined, + 0, + AIK_DEBUG_STR("Unk121") + }, + { + UsbHidUndefined, + 0, + AIK_DEBUG_STR("Unk122") + }, + { + UsbHidUndefined, + 0, + AIK_DEBUG_STR("Unk123") + }, + { + UsbHidUndefined, + 0, + AIK_DEBUG_STR("Unk124") + }, + { + UsbHidUndefined, + 0, + AIK_DEBUG_STR("Unk125") + }, + { + UsbHidUndefined, + 0, + AIK_DEBUG_STR("Unk126") + }, + { + UsbHidUndefined, + 0, + AIK_DEBUG_STR("Unk127") + } +}; + +AIK_SCANCODE_TO_USB +gAikScanCodeToUsbMap[AIK_MAX_SCANCODE_NUM] = { + { + UsbHidUndefined, + NULL + }, + { + UsbHidUsageIdKbKpKeyUpArrow, + AIK_DEBUG_STR("Move cursor up 1 row") + }, + { + UsbHidUsageIdKbKpKeyDownArrow, + AIK_DEBUG_STR("Move cursor down 1 row") + }, + { + UsbHidUsageIdKbKpKeyRightArrow, + AIK_DEBUG_STR("Move cursor right 1 column") + }, + { + UsbHidUsageIdKbKpKeyLeftArrow, + AIK_DEBUG_STR("Move cursor left 1 column") + }, + { + UsbHidUsageIdKbKpKeyHome, + AIK_DEBUG_STR("Home") + }, + { + UsbHidUsageIdKbKpKeyEnd, + AIK_DEBUG_STR("End") + }, + { + UsbHidUsageIdKbKpKeyIns, + AIK_DEBUG_STR("Insert") + }, + { + UsbHidUsageIdKbKpKeyDel, + AIK_DEBUG_STR("Delete") + }, + { + UsbHidUsageIdKbKpKeyPgUp, + AIK_DEBUG_STR("Page Up") + }, + { + UsbHidUsageIdKbKpKeyPgDn, + AIK_DEBUG_STR("Page Down") + }, + { + UsbHidUsageIdKbKpKeyF1, + AIK_DEBUG_STR("Function 1") + }, + { + UsbHidUsageIdKbKpKeyF2, + AIK_DEBUG_STR("Function 2") + }, + { + UsbHidUsageIdKbKpKeyF3, + AIK_DEBUG_STR("Function 3") + }, + { + UsbHidUsageIdKbKpKeyF4, + AIK_DEBUG_STR("Function 4") + }, + { + UsbHidUsageIdKbKpKeyF5, + AIK_DEBUG_STR("Function 5") + }, + { + UsbHidUsageIdKbKpKeyF6, + AIK_DEBUG_STR("Function 6") + }, + { + UsbHidUsageIdKbKpKeyF7, + AIK_DEBUG_STR("Function 7") + }, + { + UsbHidUsageIdKbKpKeyF8, + AIK_DEBUG_STR("Function 8") + }, + { + UsbHidUsageIdKbKpKeyF9, + AIK_DEBUG_STR("Function 9") + }, + { + UsbHidUsageIdKbKpKeyF10, + AIK_DEBUG_STR("Function 10") + }, + { + UsbHidUsageIdKbKpKeyF11, + AIK_DEBUG_STR("Function 11") + }, + { + UsbHidUsageIdKbKpKeyF12, + AIK_DEBUG_STR("Function 12") + }, + { + UsbHidUsageIdKbKpKeyEsc, + AIK_DEBUG_STR("Escape") + } +}; + +CONST CHAR8 * +gAikModifiersToNameMap[AIK_MAX_MODIFIERS_NUM] = { + NULL, + AIK_DEBUG_STR("LCTRL"), + AIK_DEBUG_STR("LSHIFT"), + AIK_DEBUG_STR("LSHIFT|LCTRL"), + AIK_DEBUG_STR("LALT"), + AIK_DEBUG_STR("LCTRL|LALT"), + AIK_DEBUG_STR("LSHIFT|LALT"), + AIK_DEBUG_STR("LSHIFT|LCTRL|LALT"), + AIK_DEBUG_STR("LGUI"), + AIK_DEBUG_STR("LCTRL|LGUI"), + AIK_DEBUG_STR("LSHIFT|LGUI"), + AIK_DEBUG_STR("LSHIFT|LCTRL|LGUI"), + AIK_DEBUG_STR("LALT|LGUI"), + AIK_DEBUG_STR("LCTRL|LALT|LGUI"), + AIK_DEBUG_STR("LSHIFT|LALT|LGUI"), + AIK_DEBUG_STR("LSHIFT|LCTRL|LALT|LGUI"), + AIK_DEBUG_STR("RCTRL"), + AIK_DEBUG_STR("RCTRL|LCTRL"), + AIK_DEBUG_STR("LSHIFT|RCTRL"), + AIK_DEBUG_STR("LSHIFT|RCTRL|LCTRL"), + AIK_DEBUG_STR("RCTRL|LALT"), + AIK_DEBUG_STR("RCTRL|LCTRL|LALT"), + AIK_DEBUG_STR("LSHIFT|RCTRL|LALT"), + AIK_DEBUG_STR("LSHIFT|RCTRL|LCTRL|LALT"), + AIK_DEBUG_STR("RCTRL|LGUI"), + AIK_DEBUG_STR("RCTRL|LCTRL|LGUI"), + AIK_DEBUG_STR("LSHIFT|RCTRL|LGUI"), + AIK_DEBUG_STR("LSHIFT|RCTRL|LCTRL|LGUI"), + AIK_DEBUG_STR("RCTRL|LALT|LGUI"), + AIK_DEBUG_STR("RCTRL|LCTRL|LALT|LGUI"), + AIK_DEBUG_STR("LSHIFT|RCTRL|LALT|LGUI"), + AIK_DEBUG_STR("LSHIFT|RCTRL|LCTRL|LALT|LGUI"), + AIK_DEBUG_STR("RSHIFT"), + AIK_DEBUG_STR("RSHIFT|LCTRL"), + AIK_DEBUG_STR("RSHIFT|LSHIFT"), + AIK_DEBUG_STR("RSHIFT|LSHIFT|LCTRL"), + AIK_DEBUG_STR("RSHIFT|LALT"), + AIK_DEBUG_STR("RSHIFT|LCTRL|LALT"), + AIK_DEBUG_STR("RSHIFT|LSHIFT|LALT"), + AIK_DEBUG_STR("RSHIFT|LSHIFT|LCTRL|LALT"), + AIK_DEBUG_STR("RSHIFT|LGUI"), + AIK_DEBUG_STR("RSHIFT|LCTRL|LGUI"), + AIK_DEBUG_STR("RSHIFT|LSHIFT|LGUI"), + AIK_DEBUG_STR("RSHIFT|LSHIFT|LCTRL|LGUI"), + AIK_DEBUG_STR("RSHIFT|LALT|LGUI"), + AIK_DEBUG_STR("RSHIFT|LCTRL|LALT|LGUI"), + AIK_DEBUG_STR("RSHIFT|LSHIFT|LALT|LGUI"), + AIK_DEBUG_STR("RSHIFT|LSHIFT|LCTRL|LALT|LGUI"), + AIK_DEBUG_STR("RSHIFT|RCTRL"), + AIK_DEBUG_STR("RSHIFT|RCTRL|LCTRL"), + AIK_DEBUG_STR("RSHIFT|LSHIFT|RCTRL"), + AIK_DEBUG_STR("RSHIFT|LSHIFT|RCTRL|LCTRL"), + AIK_DEBUG_STR("RSHIFT|RCTRL|LALT"), + AIK_DEBUG_STR("RSHIFT|RCTRL|LCTRL|LALT"), + AIK_DEBUG_STR("RSHIFT|LSHIFT|RCTRL|LALT"), + AIK_DEBUG_STR("RSHIFT|LSHIFT|RCTRL|LCTRL|LALT"), + AIK_DEBUG_STR("RSHIFT|RCTRL|LGUI"), + AIK_DEBUG_STR("RSHIFT|RCTRL|LCTRL|LGUI"), + AIK_DEBUG_STR("RSHIFT|LSHIFT|RCTRL|LGUI"), + AIK_DEBUG_STR("RSHIFT|LSHIFT|RCTRL|LCTRL|LGUI"), + AIK_DEBUG_STR("RSHIFT|RCTRL|LALT|LGUI"), + AIK_DEBUG_STR("RSHIFT|RCTRL|LCTRL|LALT|LGUI"), + AIK_DEBUG_STR("RSHIFT|LSHIFT|RCTRL|LALT|LGUI"), + AIK_DEBUG_STR("RSHIFT|LSHIFT|RCTRL|LCTRL|LALT|LGUI"), + AIK_DEBUG_STR("RALT"), + AIK_DEBUG_STR("LCTRL|RALT"), + AIK_DEBUG_STR("LSHIFT|RALT"), + AIK_DEBUG_STR("LSHIFT|LCTRL|RALT"), + AIK_DEBUG_STR("RALT|LALT"), + AIK_DEBUG_STR("LCTRL|RALT|LALT"), + AIK_DEBUG_STR("LSHIFT|RALT|LALT"), + AIK_DEBUG_STR("LSHIFT|LCTRL|RALT|LALT"), + AIK_DEBUG_STR("RALT|LGUI"), + AIK_DEBUG_STR("LCTRL|RALT|LGUI"), + AIK_DEBUG_STR("LSHIFT|RALT|LGUI"), + AIK_DEBUG_STR("LSHIFT|LCTRL|RALT|LGUI"), + AIK_DEBUG_STR("RALT|LALT|LGUI"), + AIK_DEBUG_STR("LCTRL|RALT|LALT|LGUI"), + AIK_DEBUG_STR("LSHIFT|RALT|LALT|LGUI"), + AIK_DEBUG_STR("LSHIFT|LCTRL|RALT|LALT|LGUI"), + AIK_DEBUG_STR("RCTRL|RALT"), + AIK_DEBUG_STR("RCTRL|LCTRL|RALT"), + AIK_DEBUG_STR("LSHIFT|RCTRL|RALT"), + AIK_DEBUG_STR("LSHIFT|RCTRL|LCTRL|RALT"), + AIK_DEBUG_STR("RCTRL|RALT|LALT"), + AIK_DEBUG_STR("RCTRL|LCTRL|RALT|LALT"), + AIK_DEBUG_STR("LSHIFT|RCTRL|RALT|LALT"), + AIK_DEBUG_STR("LSHIFT|RCTRL|LCTRL|RALT|LALT"), + AIK_DEBUG_STR("RCTRL|RALT|LGUI"), + AIK_DEBUG_STR("RCTRL|LCTRL|RALT|LGUI"), + AIK_DEBUG_STR("LSHIFT|RCTRL|RALT|LGUI"), + AIK_DEBUG_STR("LSHIFT|RCTRL|LCTRL|RALT|LGUI"), + AIK_DEBUG_STR("RCTRL|RALT|LALT|LGUI"), + AIK_DEBUG_STR("RCTRL|LCTRL|RALT|LALT|LGUI"), + AIK_DEBUG_STR("LSHIFT|RCTRL|RALT|LALT|LGUI"), + AIK_DEBUG_STR("LSHIFT|RCTRL|LCTRL|RALT|LALT|LGUI"), + AIK_DEBUG_STR("RSHIFT|RALT"), + AIK_DEBUG_STR("RSHIFT|LCTRL|RALT"), + AIK_DEBUG_STR("RSHIFT|LSHIFT|RALT"), + AIK_DEBUG_STR("RSHIFT|LSHIFT|LCTRL|RALT"), + AIK_DEBUG_STR("RSHIFT|RALT|LALT"), + AIK_DEBUG_STR("RSHIFT|LCTRL|RALT|LALT"), + AIK_DEBUG_STR("RSHIFT|LSHIFT|RALT|LALT"), + AIK_DEBUG_STR("RSHIFT|LSHIFT|LCTRL|RALT|LALT"), + AIK_DEBUG_STR("RSHIFT|RALT|LGUI"), + AIK_DEBUG_STR("RSHIFT|LCTRL|RALT|LGUI"), + AIK_DEBUG_STR("RSHIFT|LSHIFT|RALT|LGUI"), + AIK_DEBUG_STR("RSHIFT|LSHIFT|LCTRL|RALT|LGUI"), + AIK_DEBUG_STR("RSHIFT|RALT|LALT|LGUI"), + AIK_DEBUG_STR("RSHIFT|LCTRL|RALT|LALT|LGUI"), + AIK_DEBUG_STR("RSHIFT|LSHIFT|RALT|LALT|LGUI"), + AIK_DEBUG_STR("RSHIFT|LSHIFT|LCTRL|RALT|LALT|LGUI"), + AIK_DEBUG_STR("RSHIFT|RCTRL|RALT"), + AIK_DEBUG_STR("RSHIFT|RCTRL|LCTRL|RALT"), + AIK_DEBUG_STR("RSHIFT|LSHIFT|RCTRL|RALT"), + AIK_DEBUG_STR("RSHIFT|LSHIFT|RCTRL|LCTRL|RALT"), + AIK_DEBUG_STR("RSHIFT|RCTRL|RALT|LALT"), + AIK_DEBUG_STR("RSHIFT|RCTRL|LCTRL|RALT|LALT"), + AIK_DEBUG_STR("RSHIFT|LSHIFT|RCTRL|RALT|LALT"), + AIK_DEBUG_STR("RSHIFT|LSHIFT|RCTRL|LCTRL|RALT|LALT"), + AIK_DEBUG_STR("RSHIFT|RCTRL|RALT|LGUI"), + AIK_DEBUG_STR("RSHIFT|RCTRL|LCTRL|RALT|LGUI"), + AIK_DEBUG_STR("RSHIFT|LSHIFT|RCTRL|RALT|LGUI"), + AIK_DEBUG_STR("RSHIFT|LSHIFT|RCTRL|LCTRL|RALT|LGUI"), + AIK_DEBUG_STR("RSHIFT|RCTRL|RALT|LALT|LGUI"), + AIK_DEBUG_STR("RSHIFT|RCTRL|LCTRL|RALT|LALT|LGUI"), + AIK_DEBUG_STR("RSHIFT|LSHIFT|RCTRL|RALT|LALT|LGUI"), + AIK_DEBUG_STR("RSHIFT|LSHIFT|RCTRL|LCTRL|RALT|LALT|LGUI"), + AIK_DEBUG_STR("RGUI"), + AIK_DEBUG_STR("LCTRL|RGUI"), + AIK_DEBUG_STR("LSHIFT|RGUI"), + AIK_DEBUG_STR("LSHIFT|LCTRL|RGUI"), + AIK_DEBUG_STR("LALT|RGUI"), + AIK_DEBUG_STR("LCTRL|LALT|RGUI"), + AIK_DEBUG_STR("LSHIFT|LALT|RGUI"), + AIK_DEBUG_STR("LSHIFT|LCTRL|LALT|RGUI"), + AIK_DEBUG_STR("RGUI|LGUI"), + AIK_DEBUG_STR("LCTRL|RGUI|LGUI"), + AIK_DEBUG_STR("LSHIFT|RGUI|LGUI"), + AIK_DEBUG_STR("LSHIFT|LCTRL|RGUI|LGUI"), + AIK_DEBUG_STR("LALT|RGUI|LGUI"), + AIK_DEBUG_STR("LCTRL|LALT|RGUI|LGUI"), + AIK_DEBUG_STR("LSHIFT|LALT|RGUI|LGUI"), + AIK_DEBUG_STR("LSHIFT|LCTRL|LALT|RGUI|LGUI"), + AIK_DEBUG_STR("RCTRL|RGUI"), + AIK_DEBUG_STR("RCTRL|LCTRL|RGUI"), + AIK_DEBUG_STR("LSHIFT|RCTRL|RGUI"), + AIK_DEBUG_STR("LSHIFT|RCTRL|LCTRL|RGUI"), + AIK_DEBUG_STR("RCTRL|LALT|RGUI"), + AIK_DEBUG_STR("RCTRL|LCTRL|LALT|RGUI"), + AIK_DEBUG_STR("LSHIFT|RCTRL|LALT|RGUI"), + AIK_DEBUG_STR("LSHIFT|RCTRL|LCTRL|LALT|RGUI"), + AIK_DEBUG_STR("RCTRL|RGUI|LGUI"), + AIK_DEBUG_STR("RCTRL|LCTRL|RGUI|LGUI"), + AIK_DEBUG_STR("LSHIFT|RCTRL|RGUI|LGUI"), + AIK_DEBUG_STR("LSHIFT|RCTRL|LCTRL|RGUI|LGUI"), + AIK_DEBUG_STR("RCTRL|LALT|RGUI|LGUI"), + AIK_DEBUG_STR("RCTRL|LCTRL|LALT|RGUI|LGUI"), + AIK_DEBUG_STR("LSHIFT|RCTRL|LALT|RGUI|LGUI"), + AIK_DEBUG_STR("LSHIFT|RCTRL|LCTRL|LALT|RGUI|LGUI"), + AIK_DEBUG_STR("RSHIFT|RGUI"), + AIK_DEBUG_STR("RSHIFT|LCTRL|RGUI"), + AIK_DEBUG_STR("RSHIFT|LSHIFT|RGUI"), + AIK_DEBUG_STR("RSHIFT|LSHIFT|LCTRL|RGUI"), + AIK_DEBUG_STR("RSHIFT|LALT|RGUI"), + AIK_DEBUG_STR("RSHIFT|LCTRL|LALT|RGUI"), + AIK_DEBUG_STR("RSHIFT|LSHIFT|LALT|RGUI"), + AIK_DEBUG_STR("RSHIFT|LSHIFT|LCTRL|LALT|RGUI"), + AIK_DEBUG_STR("RSHIFT|RGUI|LGUI"), + AIK_DEBUG_STR("RSHIFT|LCTRL|RGUI|LGUI"), + AIK_DEBUG_STR("RSHIFT|LSHIFT|RGUI|LGUI"), + AIK_DEBUG_STR("RSHIFT|LSHIFT|LCTRL|RGUI|LGUI"), + AIK_DEBUG_STR("RSHIFT|LALT|RGUI|LGUI"), + AIK_DEBUG_STR("RSHIFT|LCTRL|LALT|RGUI|LGUI"), + AIK_DEBUG_STR("RSHIFT|LSHIFT|LALT|RGUI|LGUI"), + AIK_DEBUG_STR("RSHIFT|LSHIFT|LCTRL|LALT|RGUI|LGUI"), + AIK_DEBUG_STR("RSHIFT|RCTRL|RGUI"), + AIK_DEBUG_STR("RSHIFT|RCTRL|LCTRL|RGUI"), + AIK_DEBUG_STR("RSHIFT|LSHIFT|RCTRL|RGUI"), + AIK_DEBUG_STR("RSHIFT|LSHIFT|RCTRL|LCTRL|RGUI"), + AIK_DEBUG_STR("RSHIFT|RCTRL|LALT|RGUI"), + AIK_DEBUG_STR("RSHIFT|RCTRL|LCTRL|LALT|RGUI"), + AIK_DEBUG_STR("RSHIFT|LSHIFT|RCTRL|LALT|RGUI"), + AIK_DEBUG_STR("RSHIFT|LSHIFT|RCTRL|LCTRL|LALT|RGUI"), + AIK_DEBUG_STR("RSHIFT|RCTRL|RGUI|LGUI"), + AIK_DEBUG_STR("RSHIFT|RCTRL|LCTRL|RGUI|LGUI"), + AIK_DEBUG_STR("RSHIFT|LSHIFT|RCTRL|RGUI|LGUI"), + AIK_DEBUG_STR("RSHIFT|LSHIFT|RCTRL|LCTRL|RGUI|LGUI"), + AIK_DEBUG_STR("RSHIFT|RCTRL|LALT|RGUI|LGUI"), + AIK_DEBUG_STR("RSHIFT|RCTRL|LCTRL|LALT|RGUI|LGUI"), + AIK_DEBUG_STR("RSHIFT|LSHIFT|RCTRL|LALT|RGUI|LGUI"), + AIK_DEBUG_STR("RSHIFT|LSHIFT|RCTRL|LCTRL|LALT|RGUI|LGUI"), + AIK_DEBUG_STR("RALT|RGUI"), + AIK_DEBUG_STR("LCTRL|RALT|RGUI"), + AIK_DEBUG_STR("LSHIFT|RALT|RGUI"), + AIK_DEBUG_STR("LSHIFT|LCTRL|RALT|RGUI"), + AIK_DEBUG_STR("RALT|LALT|RGUI"), + AIK_DEBUG_STR("LCTRL|RALT|LALT|RGUI"), + AIK_DEBUG_STR("LSHIFT|RALT|LALT|RGUI"), + AIK_DEBUG_STR("LSHIFT|LCTRL|RALT|LALT|RGUI"), + AIK_DEBUG_STR("RALT|RGUI|LGUI"), + AIK_DEBUG_STR("LCTRL|RALT|RGUI|LGUI"), + AIK_DEBUG_STR("LSHIFT|RALT|RGUI|LGUI"), + AIK_DEBUG_STR("LSHIFT|LCTRL|RALT|RGUI|LGUI"), + AIK_DEBUG_STR("RALT|LALT|RGUI|LGUI"), + AIK_DEBUG_STR("LCTRL|RALT|LALT|RGUI|LGUI"), + AIK_DEBUG_STR("LSHIFT|RALT|LALT|RGUI|LGUI"), + AIK_DEBUG_STR("LSHIFT|LCTRL|RALT|LALT|RGUI|LGUI"), + AIK_DEBUG_STR("RCTRL|RALT|RGUI"), + AIK_DEBUG_STR("RCTRL|LCTRL|RALT|RGUI"), + AIK_DEBUG_STR("LSHIFT|RCTRL|RALT|RGUI"), + AIK_DEBUG_STR("LSHIFT|RCTRL|LCTRL|RALT|RGUI"), + AIK_DEBUG_STR("RCTRL|RALT|LALT|RGUI"), + AIK_DEBUG_STR("RCTRL|LCTRL|RALT|LALT|RGUI"), + AIK_DEBUG_STR("LSHIFT|RCTRL|RALT|LALT|RGUI"), + AIK_DEBUG_STR("LSHIFT|RCTRL|LCTRL|RALT|LALT|RGUI"), + AIK_DEBUG_STR("RCTRL|RALT|RGUI|LGUI"), + AIK_DEBUG_STR("RCTRL|LCTRL|RALT|RGUI|LGUI"), + AIK_DEBUG_STR("LSHIFT|RCTRL|RALT|RGUI|LGUI"), + AIK_DEBUG_STR("LSHIFT|RCTRL|LCTRL|RALT|RGUI|LGUI"), + AIK_DEBUG_STR("RCTRL|RALT|LALT|RGUI|LGUI"), + AIK_DEBUG_STR("RCTRL|LCTRL|RALT|LALT|RGUI|LGUI"), + AIK_DEBUG_STR("LSHIFT|RCTRL|RALT|LALT|RGUI|LGUI"), + AIK_DEBUG_STR("LSHIFT|RCTRL|LCTRL|RALT|LALT|RGUI|LGUI"), + AIK_DEBUG_STR("RSHIFT|RALT|RGUI"), + AIK_DEBUG_STR("RSHIFT|LCTRL|RALT|RGUI"), + AIK_DEBUG_STR("RSHIFT|LSHIFT|RALT|RGUI"), + AIK_DEBUG_STR("RSHIFT|LSHIFT|LCTRL|RALT|RGUI"), + AIK_DEBUG_STR("RSHIFT|RALT|LALT|RGUI"), + AIK_DEBUG_STR("RSHIFT|LCTRL|RALT|LALT|RGUI"), + AIK_DEBUG_STR("RSHIFT|LSHIFT|RALT|LALT|RGUI"), + AIK_DEBUG_STR("RSHIFT|LSHIFT|LCTRL|RALT|LALT|RGUI"), + AIK_DEBUG_STR("RSHIFT|RALT|RGUI|LGUI"), + AIK_DEBUG_STR("RSHIFT|LCTRL|RALT|RGUI|LGUI"), + AIK_DEBUG_STR("RSHIFT|LSHIFT|RALT|RGUI|LGUI"), + AIK_DEBUG_STR("RSHIFT|LSHIFT|LCTRL|RALT|RGUI|LGUI"), + AIK_DEBUG_STR("RSHIFT|RALT|LALT|RGUI|LGUI"), + AIK_DEBUG_STR("RSHIFT|LCTRL|RALT|LALT|RGUI|LGUI"), + AIK_DEBUG_STR("RSHIFT|LSHIFT|RALT|LALT|RGUI|LGUI"), + AIK_DEBUG_STR("RSHIFT|LSHIFT|LCTRL|RALT|LALT|RGUI|LGUI"), + AIK_DEBUG_STR("RSHIFT|RCTRL|RALT|RGUI"), + AIK_DEBUG_STR("RSHIFT|RCTRL|LCTRL|RALT|RGUI"), + AIK_DEBUG_STR("RSHIFT|LSHIFT|RCTRL|RALT|RGUI"), + AIK_DEBUG_STR("RSHIFT|LSHIFT|RCTRL|LCTRL|RALT|RGUI"), + AIK_DEBUG_STR("RSHIFT|RCTRL|RALT|LALT|RGUI"), + AIK_DEBUG_STR("RSHIFT|RCTRL|LCTRL|RALT|LALT|RGUI"), + AIK_DEBUG_STR("RSHIFT|LSHIFT|RCTRL|RALT|LALT|RGUI"), + AIK_DEBUG_STR("RSHIFT|LSHIFT|RCTRL|LCTRL|RALT|LALT|RGUI"), + AIK_DEBUG_STR("RSHIFT|RCTRL|RALT|RGUI|LGUI"), + AIK_DEBUG_STR("RSHIFT|RCTRL|LCTRL|RALT|RGUI|LGUI"), + AIK_DEBUG_STR("RSHIFT|LSHIFT|RCTRL|RALT|RGUI|LGUI"), + AIK_DEBUG_STR("RSHIFT|LSHIFT|RCTRL|LCTRL|RALT|RGUI|LGUI"), + AIK_DEBUG_STR("RSHIFT|RCTRL|RALT|LALT|RGUI|LGUI"), + AIK_DEBUG_STR("RSHIFT|RCTRL|LCTRL|RALT|LALT|RGUI|LGUI"), + AIK_DEBUG_STR("RSHIFT|LSHIFT|RCTRL|RALT|LALT|RGUI|LGUI"), +}; + +CONST CHAR8 * +gAikAppleKeyToNameMap[AIK_MAX_APPLEKEY_NUM] = { + AIK_DEBUG_STR("AppleHidUsbKbUsageKeyA"), + AIK_DEBUG_STR("AppleHidUsbKbUsageKeyB"), + AIK_DEBUG_STR("AppleHidUsbKbUsageKeyC"), + AIK_DEBUG_STR("AppleHidUsbKbUsageKeyD"), + AIK_DEBUG_STR("AppleHidUsbKbUsageKeyE"), + AIK_DEBUG_STR("AppleHidUsbKbUsageKeyF"), + AIK_DEBUG_STR("AppleHidUsbKbUsageKeyG"), + AIK_DEBUG_STR("AppleHidUsbKbUsageKeyH"), + AIK_DEBUG_STR("AppleHidUsbKbUsageKeyI"), + AIK_DEBUG_STR("AppleHidUsbKbUsageKeyJ"), + AIK_DEBUG_STR("AppleHidUsbKbUsageKeyK"), + AIK_DEBUG_STR("AppleHidUsbKbUsageKeyL"), + AIK_DEBUG_STR("AppleHidUsbKbUsageKeyM"), + AIK_DEBUG_STR("AppleHidUsbKbUsageKeyN"), + AIK_DEBUG_STR("AppleHidUsbKbUsageKeyO"), + AIK_DEBUG_STR("AppleHidUsbKbUsageKeyP"), + AIK_DEBUG_STR("AppleHidUsbKbUsageKeyQ"), + AIK_DEBUG_STR("AppleHidUsbKbUsageKeyR"), + AIK_DEBUG_STR("AppleHidUsbKbUsageKeyS"), + AIK_DEBUG_STR("AppleHidUsbKbUsageKeyT"), + AIK_DEBUG_STR("AppleHidUsbKbUsageKeyU"), + AIK_DEBUG_STR("AppleHidUsbKbUsageKeyV"), + AIK_DEBUG_STR("AppleHidUsbKbUsageKeyW"), + AIK_DEBUG_STR("AppleHidUsbKbUsageKeyX"), + AIK_DEBUG_STR("AppleHidUsbKbUsageKeyY"), + AIK_DEBUG_STR("AppleHidUsbKbUsageKeyZ"), + AIK_DEBUG_STR("AppleHidUsbKbUsageKeyOne"), + AIK_DEBUG_STR("AppleHidUsbKbUsageKeyTwo"), + AIK_DEBUG_STR("AppleHidUsbKbUsageKeyThree"), + AIK_DEBUG_STR("AppleHidUsbKbUsageKeyFour"), + AIK_DEBUG_STR("AppleHidUsbKbUsageKeyFive"), + AIK_DEBUG_STR("AppleHidUsbKbUsageKeySix"), + AIK_DEBUG_STR("AppleHidUsbKbUsageKeySeven"), + AIK_DEBUG_STR("AppleHidUsbKbUsageKeyEight"), + AIK_DEBUG_STR("AppleHidUsbKbUsageKeyNine"), + AIK_DEBUG_STR("AppleHidUsbKbUsageKeyZero"), + AIK_DEBUG_STR("AppleHidUsbKbUsageKeyEnter"), + AIK_DEBUG_STR("AppleHidUsbKbUsageKeyEscape"), + AIK_DEBUG_STR("AppleHidUsbKbUsageKeyBackSpace"), + AIK_DEBUG_STR("AppleHidUsbKbUsageKeyTab"), + AIK_DEBUG_STR("AppleHidUsbKbUsageKeySpaceBar"), + AIK_DEBUG_STR("AppleHidUsbKbUsageKeyMinus"), + AIK_DEBUG_STR("AppleHidUsbKbUsageKeyEquals"), + AIK_DEBUG_STR("AppleHidUsbKbUsageKeyLeftBracket"), + AIK_DEBUG_STR("AppleHidUsbKbUsageKeyRightBracket"), + AIK_DEBUG_STR("AppleHidUsbKbUsageKeyBackslash"), + AIK_DEBUG_STR("AppleHidUsbKbUsageKeyNonUsHash"), + AIK_DEBUG_STR("AppleHidUsbKbUsageKeySemicolon"), + AIK_DEBUG_STR("AppleHidUsbKbUsageKeyQuotation"), + AIK_DEBUG_STR("AppleHidUsbKbUsageKeyAcute"), + AIK_DEBUG_STR("AppleHidUsbKbUsageKeyComma"), + AIK_DEBUG_STR("AppleHidUsbKbUsageKeyPeriod"), + AIK_DEBUG_STR("AppleHidUsbKbUsageKeySlash"), + AIK_DEBUG_STR("AppleHidUsbKbUsageKeyCLock"), + AIK_DEBUG_STR("AppleHidUsbKbUsageKeyF1"), + AIK_DEBUG_STR("AppleHidUsbKbUsageKeyF2"), + AIK_DEBUG_STR("AppleHidUsbKbUsageKeyF3"), + AIK_DEBUG_STR("AppleHidUsbKbUsageKeyF4"), + AIK_DEBUG_STR("AppleHidUsbKbUsageKeyF5"), + AIK_DEBUG_STR("AppleHidUsbKbUsageKeyF6"), + AIK_DEBUG_STR("AppleHidUsbKbUsageKeyF7"), + AIK_DEBUG_STR("AppleHidUsbKbUsageKeyF8"), + AIK_DEBUG_STR("AppleHidUsbKbUsageKeyF9"), + AIK_DEBUG_STR("AppleHidUsbKbUsageKeyF10"), + AIK_DEBUG_STR("AppleHidUsbKbUsageKeyF11"), + AIK_DEBUG_STR("AppleHidUsbKbUsageKeyF12"), + AIK_DEBUG_STR("AppleHidUsbKbUsageKeyPrint"), + AIK_DEBUG_STR("AppleHidUsbKbUsageKeySLock"), + AIK_DEBUG_STR("AppleHidUsbKbUsageKeyPause"), + AIK_DEBUG_STR("AppleHidUsbKbUsageKeyIns"), + AIK_DEBUG_STR("AppleHidUsbKbUsageKeyHome"), + AIK_DEBUG_STR("AppleHidUsbKbUsageKeyPgUp"), + AIK_DEBUG_STR("AppleHidUsbKbUsageKeyDel"), + AIK_DEBUG_STR("AppleHidUsbKbUsageKeyEnd"), + AIK_DEBUG_STR("AppleHidUsbKbUsageKeyPgDn"), + AIK_DEBUG_STR("AppleHidUsbKbUsageKeyRightArrow"), + AIK_DEBUG_STR("AppleHidUsbKbUsageKeyLeftArrow"), + AIK_DEBUG_STR("AppleHidUsbKbUsageKeyDownArrow"), + AIK_DEBUG_STR("AppleHidUsbKbUsageKeyUpArrow"), +}; diff --git a/Library/OcInputLib/Keycode/AIKShim.c b/Library/OcInputLib/Keycode/AIKShim.c new file mode 100644 index 00000000..c9b4094a --- /dev/null +++ b/Library/OcInputLib/Keycode/AIKShim.c @@ -0,0 +1,198 @@ +/** @file + Key shimming code + +Copyright (c) 2018, vit9696. All rights reserved.
+This program and the accompanying materials +are licensed and made available under the terms and conditions of the BSD License +which accompanies this distribution. The full text of the license may be found at +http://opensource.org/licenses/bsd-license.php + +THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, +WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. + +**/ + +#include "AIK.h" +#include "AIKShim.h" + +#include +#include +#include + +EFI_STATUS +EFIAPI +AIKShimAmiKeycodeReset ( + IN AMI_EFIKEYCODE_PROTOCOL *This, + IN BOOLEAN ExtendedVerification + ) +{ + if (This == NULL || gAikSelf.OurJobIsDone) { + return EFI_INVALID_PARAMETER; + } + + if (This == gAikSelf.Source.AmiKeycode && !gAikSelf.InPollKeyboardEvent) { + // + // Do not touch any protocol but ours. + // + AIKDataReset (&gAikSelf.Data); + } + + return gAikSelf.Source.AmiReset (This, ExtendedVerification); +} + +EFI_STATUS +EFIAPI +AIKShimAmiKeycodeReadEfikey ( + IN AMI_EFIKEYCODE_PROTOCOL *This, + OUT AMI_EFI_KEY_DATA *KeyData + ) +{ + DEBUG ((DEBUG_VERBOSE, "AIKAmiKeycodeReadEfikey %p %p ours %p event %d", + This, KeyData, gAikSelf.Source.AmiKeycode, gAikSelf.InPollKeyboardEvent)); + + if (This == NULL || KeyData == NULL || gAikSelf.OurJobIsDone) { + return EFI_INVALID_PARAMETER; + } + + if (This == gAikSelf.Source.AmiKeycode && !gAikSelf.InPollKeyboardEvent) { + // + // Do not touch any protocol but ours. + // + return AIKDataReadEntry (&gAikSelf.Data, KeyData); + } + + return gAikSelf.Source.AmiReadEfikey (This, KeyData); +} + +EFI_STATUS +EFIAPI +AIKShimTextInputReset ( + IN EFI_SIMPLE_TEXT_INPUT_PROTOCOL *This, + IN BOOLEAN ExtendedVerification + ) +{ + if (This == NULL || gAikSelf.OurJobIsDone) { + return EFI_INVALID_PARAMETER; + } + + if (This == gAikSelf.Source.TextInput && !gAikSelf.InPollKeyboardEvent) { + // + // Do not touch any protocol but ours. + // + AIKDataReset (&gAikSelf.Data); + } + + return gAikSelf.Source.TextReset (This, ExtendedVerification); +} + +EFI_STATUS +EFIAPI +AIKShimTextInputReadKeyStroke ( + IN EFI_SIMPLE_TEXT_INPUT_PROTOCOL *This, + OUT EFI_INPUT_KEY *Key + ) +{ + EFI_STATUS Status; + AMI_EFI_KEY_DATA AmiKeyData; + + DEBUG ((DEBUG_VERBOSE, "AIKTextInputReadKeyStroke %p %p ours %p event %d", + This, Key, gAikSelf.Source.TextInput, gAikSelf.InPollKeyboardEvent)); + + if (This == NULL || Key == NULL || gAikSelf.OurJobIsDone) { + return EFI_INVALID_PARAMETER; + } + + if (This == gAikSelf.Source.TextInput && !gAikSelf.InPollKeyboardEvent) { + // + // Do not touch any protocol but ours. + // + Status = AIKDataReadEntry (&gAikSelf.Data, &AmiKeyData); + if (!EFI_ERROR (Status)) { + // + // 'Partial' keys should not be returned by SimpleTextInput protocols. + // + if (AmiKeyData.Key.ScanCode == 0 && AmiKeyData.Key.UnicodeChar == 0 + && (AmiKeyData.KeyState.KeyToggleState & KEY_STATE_EXPOSED)) { + Status = EFI_NOT_READY; + } else { + CopyMem (Key, &AmiKeyData.Key, sizeof (AmiKeyData.Key)); + } + } + + return Status; + } + + return gAikSelf.Source.TextReadKeyStroke (This, Key); +} + +EFI_STATUS +EFIAPI +AIKShimTextInputResetEx ( + IN EFI_SIMPLE_TEXT_INPUT_EX_PROTOCOL *This, + IN BOOLEAN ExtendedVerification + ) +{ + if (This == NULL || gAikSelf.OurJobIsDone) { + return EFI_INVALID_PARAMETER; + } + + if (This == gAikSelf.Source.TextInputEx && !gAikSelf.InPollKeyboardEvent) { + // + // Do not touch any protocol but ours. + // + AIKDataReset (&gAikSelf.Data); + } + + return gAikSelf.Source.TextResetEx (This, ExtendedVerification); +} + +EFI_STATUS +EFIAPI +AIKShimTextInputReadKeyStrokeEx ( + IN EFI_SIMPLE_TEXT_INPUT_EX_PROTOCOL *This, + OUT EFI_KEY_DATA *KeyData + ) +{ + EFI_STATUS Status; + AMI_EFI_KEY_DATA AmiKeyData; + + DEBUG ((DEBUG_VERBOSE, "AIKTextInputReadKeyStrokeEx %p %p ours %p event %d", + This, KeyData, gAikSelf.Source.TextInputEx, gAikSelf.InPollKeyboardEvent)); + + if (This == NULL || KeyData == NULL || gAikSelf.OurJobIsDone) { + return EFI_INVALID_PARAMETER; + } + + if (This == gAikSelf.Source.TextInputEx && !gAikSelf.InPollKeyboardEvent) { + // + // Do not touch any protocol but ours. + // + Status = AIKDataReadEntry (&gAikSelf.Data, &AmiKeyData); + if (!EFI_ERROR (Status)) { + CopyMem (&KeyData->Key, &AmiKeyData.Key, sizeof (AmiKeyData.Key)); + CopyMem (&KeyData->KeyState, &AmiKeyData.KeyState, sizeof (AmiKeyData.KeyState)); + } + + return Status; + } + + return gAikSelf.Source.TextReadKeyStrokeEx (This, KeyData); +} + +VOID +EFIAPI +AIKShimWaitForKeyHandler ( + IN EFI_EVENT Event, + IN VOID *Context + ) +{ + if (gAikSelf.OurJobIsDone) { + DEBUG ((DEBUG_INFO, "AIKShimWaitForKeyHandler got null handler or called when done\n")); + return; + } + + if (!AIKDataEmpty (&gAikSelf.Data)) { + DEBUG ((DEBUG_VERBOSE, "Caught KeyBufferSize non-zero\n")); + gBS->SignalEvent (Event); + } +} diff --git a/Library/OcInputLib/Keycode/AIKShim.h b/Library/OcInputLib/Keycode/AIKShim.h new file mode 100644 index 00000000..72d6cf63 --- /dev/null +++ b/Library/OcInputLib/Keycode/AIKShim.h @@ -0,0 +1,72 @@ +/** @file + Key shimming code + +Copyright (c) 2018, vit9696. All rights reserved.
+This program and the accompanying materials +are licensed and made available under the terms and conditions of the BSD License +which accompanies this distribution. The full text of the license may be found at +http://opensource.org/licenses/bsd-license.php + +THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, +WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. + +**/ + +#ifndef AIK_SHIM_H +#define AIK_SHIM_H + +#include +#include +#include + +EFI_STATUS +EFIAPI +AIKShimAmiKeycodeReset ( + IN AMI_EFIKEYCODE_PROTOCOL *This, + IN BOOLEAN ExtendedVerification + ); + +EFI_STATUS +EFIAPI +AIKShimAmiKeycodeReadEfikey ( + IN AMI_EFIKEYCODE_PROTOCOL *This, + OUT AMI_EFI_KEY_DATA *KeyData + ); + +EFI_STATUS +EFIAPI +AIKShimTextInputReset ( + IN EFI_SIMPLE_TEXT_INPUT_PROTOCOL *This, + IN BOOLEAN ExtendedVerification + ); + +EFI_STATUS +EFIAPI +AIKShimTextInputReadKeyStroke ( + IN EFI_SIMPLE_TEXT_INPUT_PROTOCOL *This, + OUT EFI_INPUT_KEY *Key + ); + +EFI_STATUS +EFIAPI +AIKShimTextInputResetEx ( + IN EFI_SIMPLE_TEXT_INPUT_EX_PROTOCOL *This, + IN BOOLEAN ExtendedVerification + ); + +EFI_STATUS +EFIAPI +AIKShimTextInputReadKeyStrokeEx ( + IN EFI_SIMPLE_TEXT_INPUT_EX_PROTOCOL *This, + OUT EFI_KEY_DATA *KeyData + ); + +VOID +EFIAPI +AIKShimWaitForKeyHandler ( + IN EFI_EVENT Event, + IN VOID *Context + ); + +#endif + diff --git a/Library/OcInputLib/Keycode/AIKSource.c b/Library/OcInputLib/Keycode/AIKSource.c new file mode 100644 index 00000000..609f73cb --- /dev/null +++ b/Library/OcInputLib/Keycode/AIKSource.c @@ -0,0 +1,212 @@ +/** @file + Key provider + +Copyright (c) 2018, vit9696. All rights reserved.
+This program and the accompanying materials +are licensed and made available under the terms and conditions of the BSD License +which accompanies this distribution. The full text of the license may be found at +http://opensource.org/licenses/bsd-license.php + +THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, +WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. + +**/ + +#include "AIKSource.h" +#include "AIKShim.h" + +#include +#include +#include +#include + +EFI_STATUS +AIKSourceGrabEfiKey ( + AIK_SOURCE *Source, + AMI_EFI_KEY_DATA *KeyData + ) +{ + EFI_STATUS Status; + EFI_EVENT Event; + + ZeroMem (KeyData, sizeof (*KeyData)); + + if (Source->AmiKeycode != NULL && Source->AmiReadEfikey) { + Status = Source->AmiReadEfikey (Source->AmiKeycode, KeyData); + Event = Source->AmiKeycode->WaitForKeyEx; + } else if (Source->TextInputEx != NULL && Source->TextReadKeyStrokeEx) { + Status = Source->TextReadKeyStrokeEx (Source->TextInputEx, (EFI_KEY_DATA *) KeyData); + Event = Source->TextInputEx->WaitForKeyEx; + } else if (Source->TextInput != NULL && Source->TextReadKeyStroke) { + Status = Source->TextReadKeyStroke (Source->TextInput, &KeyData->Key); + Event = Source->TextInput->WaitForKey; + } else { + // + // Should never happen. + // + Status = EFI_NOT_FOUND; + Event = NULL; + } + + if (Event != NULL) { + gBS->SignalEvent (Event); + } + + return Status; +} + +EFI_STATUS +AIKSourceInstall ( + AIK_SOURCE *Source, + OC_INPUT_KEY_MODE Mode + ) +{ + EFI_STATUS Status; + + if (Source->AmiKeycode != NULL || Source->TextInput != NULL || Source->TextInputEx != NULL) { + return EFI_SUCCESS; + } + + Source->ConSplitHandler = gST->ConsoleInHandle; + + if (Mode == OcInputKeyModeAuto || Mode == OcInputKeyModeAmi) { + Status = gBS->HandleProtocol (Source->ConSplitHandler, &gAmiEfiKeycodeProtocolGuid, + (VOID * *)& Source->AmiKeycode); + if (EFI_ERROR (Status)) { + DEBUG ((DEBUG_INFO, "AmiEfiKeycodeProtocol is unavailable on gST->ConsoleHandle - %r\n", Status)); + } + } + + if (Mode == OcInputKeyModeAuto || Mode == OcInputKeyModeV1) { + Status = gBS->HandleProtocol (Source->ConSplitHandler, &gEfiSimpleTextInProtocolGuid, + (VOID * *)& Source->TextInput); + if (EFI_ERROR (Status)) { + DEBUG ((DEBUG_INFO, "EfiSimpleTextInProtocol is unavailable on gST->ConsoleHandle - %r\n", Status)); + } + } + + if (Mode == OcInputKeyModeAuto || Mode == OcInputKeyModeV2) { + Status = gBS->HandleProtocol (Source->ConSplitHandler, &gEfiSimpleTextInputExProtocolGuid, + (VOID * *)& Source->TextInputEx); + if (EFI_ERROR (Status)) { + DEBUG ((DEBUG_INFO, "EfiSimpleTextInputExProtocol is unavailable on gST->ConsoleHandle - %r\n", Status)); + } + } + + if (Source->AmiKeycode == NULL && Source->TextInput == NULL && Source->TextInputEx == NULL) { + DEBUG ((DEBUG_INFO, "No ConSplitter input protocol is unavailable\n")); + return EFI_NOT_FOUND; + } + + DEBUG ((DEBUG_INFO, "gST->ConIn %p vs found %p\n", gST->ConIn, Source->TextInput)); + + // + // We additionally reset the protocols as our buffers are empty, and we do not want old data. + // + if (Source->AmiKeycode) { + Source->AmiKeycode->Reset (Source->AmiKeycode, FALSE); + Source->AmiReset = Source->AmiKeycode->Reset; + Source->AmiReadEfikey = Source->AmiKeycode->ReadEfikey; + Source->AmiWait = Source->AmiKeycode->WaitForKeyEx; + Source->AmiKeycode->Reset = AIKShimAmiKeycodeReset; + Source->AmiKeycode->ReadEfikey = AIKShimAmiKeycodeReadEfikey; + Status = gBS->CreateEvent ( + EVT_NOTIFY_WAIT, TPL_NOTIFY, AIKShimWaitForKeyHandler, + NULL, &Source->AmiKeycode->WaitForKeyEx + ); + if (EFI_ERROR (Status)) { + DEBUG ((DEBUG_INFO, "AmiEfiKeycodeProtocol WaitForKey replace failed - %r", Status)); + Source->AmiKeycode->WaitForKeyEx = Source->AmiWait; + Source->AmiWait = NULL; + } + } + + if (Source->TextInput) { + Source->TextInput->Reset (Source->TextInput, FALSE); + Source->TextReset = Source->TextInput->Reset; + Source->TextReadKeyStroke = Source->TextInput->ReadKeyStroke; + Source->TextWait = Source->TextInput->WaitForKey; + Source->TextInput->Reset = AIKShimTextInputReset; + Source->TextInput->ReadKeyStroke = AIKShimTextInputReadKeyStroke; + Status = gBS->CreateEvent ( + EVT_NOTIFY_WAIT, TPL_NOTIFY, AIKShimWaitForKeyHandler, + NULL, &Source->TextInput->WaitForKey + ); + if (EFI_ERROR (Status)) { + DEBUG ((DEBUG_INFO, "EfiSimpleTextInProtocol WaitForKey replace failed - %r", Status)); + Source->TextInput->WaitForKey = Source->TextWait; + Source->TextWait = NULL; + } + } + + if (Source->TextInputEx) { + Source->TextInputEx->Reset (Source->TextInputEx, FALSE); + Source->TextResetEx = Source->TextInputEx->Reset; + Source->TextWaitEx = Source->TextInputEx->WaitForKeyEx; + Source->TextReadKeyStrokeEx = Source->TextInputEx->ReadKeyStrokeEx; + Source->TextInputEx->Reset = AIKShimTextInputResetEx; + Source->TextInputEx->ReadKeyStrokeEx = AIKShimTextInputReadKeyStrokeEx; + Status = gBS->CreateEvent ( + EVT_NOTIFY_WAIT, TPL_NOTIFY, AIKShimWaitForKeyHandler, + NULL, &Source->TextInputEx->WaitForKeyEx + ); + if (EFI_ERROR (Status)) { + DEBUG ((DEBUG_INFO, "EfiSimpleTextInputExProtocol WaitForKey replace failed - %r", Status)); + Source->TextInputEx->WaitForKeyEx = Source->TextWaitEx; + Source->TextWaitEx = NULL; + } + } + + return EFI_SUCCESS; +} + +VOID +AIKSourceUninstall ( + AIK_SOURCE *Source + ) +{ + if (Source->AmiKeycode) { + Source->AmiKeycode->Reset = Source->AmiReset; + Source->AmiKeycode->ReadEfikey = Source->AmiReadEfikey; + if (Source->AmiWait != NULL && Source->AmiWait != Source->AmiKeycode->WaitForKeyEx) { + gBS->CloseEvent (Source->AmiKeycode->WaitForKeyEx); + Source->AmiKeycode->WaitForKeyEx = Source->AmiWait; + } + Source->AmiReset = NULL; + Source->AmiReadEfikey = NULL; + Source->AmiWait = NULL; + Source->AmiKeycode = NULL; + } + + if (Source->TextInput) { + Source->TextInput->Reset = Source->TextReset; + Source->TextInput->ReadKeyStroke = Source->TextReadKeyStroke; + if (Source->TextWait != NULL && Source->TextWait != Source->TextInput->WaitForKey) { + gBS->CloseEvent (Source->TextInput->WaitForKey); + Source->TextInput->WaitForKey = Source->TextWait; + } + Source->TextInput = NULL; + Source->TextReset = NULL; + Source->TextWait = NULL; + Source->TextReadKeyStroke = NULL; + } + + if (Source->TextInputEx) { + Source->TextInputEx->Reset = Source->TextResetEx; + Source->TextInputEx->ReadKeyStrokeEx = Source->TextReadKeyStrokeEx; + if (Source->TextWaitEx != NULL && Source->TextWaitEx != Source->TextInputEx->WaitForKeyEx) { + gBS->CloseEvent (Source->TextInputEx->WaitForKeyEx); + Source->TextInputEx->WaitForKeyEx = Source->TextWaitEx; + } + Source->TextInputEx = NULL; + Source->TextResetEx = NULL; + Source->TextWaitEx = NULL; + Source->TextReadKeyStrokeEx = NULL; + } + + if (Source->ConSplitHandler != NULL) { + gBS->DisconnectController (Source->ConSplitHandler, NULL, NULL); + Source->ConSplitHandler = NULL; + } +} + diff --git a/Library/OcInputLib/Keycode/AIKSource.h b/Library/OcInputLib/Keycode/AIKSource.h new file mode 100644 index 00000000..b2b477ad --- /dev/null +++ b/Library/OcInputLib/Keycode/AIKSource.h @@ -0,0 +1,71 @@ +/** @file + Key provider + +Copyright (c) 2018, vit9696. All rights reserved.
+This program and the accompanying materials +are licensed and made available under the terms and conditions of the BSD License +which accompanies this distribution. The full text of the license may be found at +http://opensource.org/licenses/bsd-license.php + +THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, +WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. + +**/ + +#ifndef AIK_SOURCE_H +#define AIK_SOURCE_H + +#include +#include +#include + +#include + +typedef struct { + // + // Preserved handle of gST->ConsoleInHandle + // + EFI_HANDLE ConSplitHandler; + + // + // Solved input protocol instances from ConSplitHandler + // We override their ReadKey and Reset handlers and implement + // them ourselves via polled data from one of these protocols. + // Polled proto is prioritised as present: AMI, EX, Legacy. + // + AMI_EFIKEYCODE_PROTOCOL *AmiKeycode; + EFI_SIMPLE_TEXT_INPUT_PROTOCOL *TextInput; + EFI_SIMPLE_TEXT_INPUT_EX_PROTOCOL *TextInputEx; + + // + // Original implementations of the protocols. + // + AMI_RESET_EX AmiReset; + AMI_READ_EFI_KEY AmiReadEfikey; + EFI_EVENT AmiWait; + EFI_INPUT_RESET TextReset; + EFI_EVENT TextWait; + EFI_INPUT_READ_KEY TextReadKeyStroke; + EFI_INPUT_RESET_EX TextResetEx; + EFI_INPUT_READ_KEY_EX TextReadKeyStrokeEx; + EFI_EVENT TextWaitEx; +} AIK_SOURCE; + +EFI_STATUS +AIKSourceGrabEfiKey ( + AIK_SOURCE *Source, + AMI_EFI_KEY_DATA *KeyData + ); + +EFI_STATUS +AIKSourceInstall ( + AIK_SOURCE *Source, + OC_INPUT_KEY_MODE Mode + ); + +VOID +AIKSourceUninstall ( + AIK_SOURCE *Source + ); + +#endif diff --git a/Library/OcInputLib/Keycode/AIKTarget.c b/Library/OcInputLib/Keycode/AIKTarget.c new file mode 100644 index 00000000..0521e51a --- /dev/null +++ b/Library/OcInputLib/Keycode/AIKTarget.c @@ -0,0 +1,196 @@ +/** @file + Key consumer + +Copyright (c) 2018, vit9696. All rights reserved.
+This program and the accompanying materials +are licensed and made available under the terms and conditions of the BSD License +which accompanies this distribution. The full text of the license may be found at +http://opensource.org/licenses/bsd-license.php + +THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, +WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. + +**/ + +#include "AIKTarget.h" +#include "AIKTranslate.h" + +#include +#include +#include + +EFI_STATUS +AIKTargetInstall ( + IN OUT AIK_TARGET *Target, + IN UINT8 KeyForgotThreshold, + IN UINT8 KeyMergeThreshold + ) +{ + EFI_STATUS Status; + + Status = EFI_SUCCESS; + + Target->KeyForgotThreshold = KeyForgotThreshold; + Target->KeyMergeThreshold = KeyMergeThreshold; + + if (Target->KeyMapDb == NULL) { + Status = gBS->LocateProtocol (&gAppleKeyMapDatabaseProtocolGuid, NULL, (VOID **) &Target->KeyMapDb); + + if (EFI_ERROR (Status)) { + DEBUG ((DEBUG_INFO, "AppleKeyMapDatabaseProtocol is unavailable - %r\n", Status)); + return EFI_NOT_FOUND; + } + + Status = Target->KeyMapDb->CreateKeyStrokesBuffer ( + Target->KeyMapDb, AIK_TARGET_BUFFER_SIZE, &Target->KeyMapDbIndex + ); + + if (EFI_ERROR (Status)) { + DEBUG ((DEBUG_INFO, "CreateKeyStrokesBuffer failed - %r\n", Status)); + Target->KeyMapDb = NULL; + } + } + + return Status; +} + +VOID +AIKTargetUninstall ( + IN OUT AIK_TARGET *Target + ) +{ + if (Target->KeyMapDb != NULL) { + Target->KeyMapDb->RemoveKeyStrokesBuffer (Target->KeyMapDb, Target->KeyMapDbIndex); + Target->KeyMapDb = NULL; + } + + Target->NumberOfKeys = 0; + Target->Modifiers = 0; + Target->ModifierCounter = 0; + ZeroMem (Target->Keys, sizeof (Target->Keys)); + ZeroMem (Target->KeyCounters, sizeof (Target->KeyCounters)); +} + +UINT64 +AIKTargetRefresh ( + IN OUT AIK_TARGET *Target + ) +{ + UINTN Index; + UINTN Left; + + Target->Counter++; + + for (Index = 0; Index < Target->NumberOfKeys; Index++) { + // + // We reported this key Target->KeyForgetThreshold times, time to say goodbye. + // + if (Target->KeyCounters[Index] + Target->KeyForgotThreshold <= Target->Counter) { + Left = Target->NumberOfKeys - (Index + 1); + if (Left > 0) { + CopyMem ( + &Target->KeyCounters[Index], + &Target->KeyCounters[Index+1], + sizeof (Target->KeyCounters[0]) * Left); + CopyMem ( + &Target->Keys[Index], + &Target->Keys[Index+1], + sizeof (Target->Keys[0]) * Left); + } + Target->NumberOfKeys--; + } + } + + // + // No keys were pressed, so we did not enter AIKTargetWriteEntry. + // However, we still need to reset modifiers after time. + // + if (Target->ModifierCounter + Target->KeyForgotThreshold <= Target->Counter) { + Target->Modifiers = 0; + } + + return Target->Counter; +} + +VOID +AIKTargetWriteEntry ( + IN OUT AIK_TARGET *Target, + IN AMI_EFI_KEY_DATA *KeyData + ) +{ + APPLE_MODIFIER_MAP Modifiers; + APPLE_KEY_CODE Key; + UINTN Index; + UINTN InsertIndex; + UINT64 OldestCounter; + + AIKTranslate (KeyData, &Modifiers, &Key); + + Target->Modifiers = Modifiers; + Target->ModifierCounter = Target->Counter; + + if (Key == UsbHidUndefined) { + // + // This is just a modifier or an unsupported key. + // + return; + } + + for (Index = 0; Index < Target->NumberOfKeys; Index++) { + if (Target->Keys[Index] == Key) { + // + // This key was added previously, just update its counter. + // + Target->KeyCounters[Index] = Target->Counter; + return; + } + } + + InsertIndex = Target->NumberOfKeys; + + // + // This should not happen, but we have no room, replace the oldest key. + // + if (InsertIndex == AIK_TARGET_BUFFER_SIZE) { + InsertIndex = 0; + OldestCounter = Target->KeyCounters[InsertIndex]; + for (Index = 1; Index < Target->NumberOfKeys; Index++) { + if (OldestCounter > Target->KeyCounters[Index]) { + OldestCounter = Target->KeyCounters[Index]; + InsertIndex = Index; + } + } + Target->NumberOfKeys--; + } + + // + // Insert the new key + // + Target->Keys[InsertIndex] = Key; + Target->KeyCounters[InsertIndex] = Target->Counter; + Target->NumberOfKeys++; +} + +VOID +AIKTargetSubmit ( + IN OUT AIK_TARGET *Target + ) +{ + EFI_STATUS Status; + + if (Target->KeyMapDb != NULL) { + Status = Target->KeyMapDb->SetKeyStrokeBufferKeys ( + Target->KeyMapDb, + Target->KeyMapDbIndex, + Target->Modifiers, + Target->NumberOfKeys, + Target->Keys + ); + } else { + Status = EFI_NOT_FOUND; + } + + if (EFI_ERROR (Status)) { + DEBUG ((DEBUG_INFO, "Failed to submit keys to AppleMapDb - %r", Status)); + } +} diff --git a/Library/OcInputLib/Keycode/AIKTarget.h b/Library/OcInputLib/Keycode/AIKTarget.h new file mode 100644 index 00000000..ca4abdda --- /dev/null +++ b/Library/OcInputLib/Keycode/AIKTarget.h @@ -0,0 +1,116 @@ +/** @file + Key consumer + +Copyright (c) 2018, vit9696. All rights reserved.
+This program and the accompanying materials +are licensed and made available under the terms and conditions of the BSD License +which accompanies this distribution. The full text of the license may be found at +http://opensource.org/licenses/bsd-license.php + +THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, +WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. + +**/ + +#ifndef AIK_TARGET_H +#define AIK_TARGET_H + +#include +#include +#include + +// +// Maximum amount of keys reported to Apple protocols +// +#define AIK_TARGET_BUFFER_SIZE 6 + +// +// Known values for key repeat (single key hold): +// VMware - 2, APTIO V - 3 or 4 +// Known values for different keys (quick press one after other): +// VMware - 6+, APTIO V - 10+ +// Known values for simultaneous keys (dual key hold): +// VMware - 2, APTIO V - 1 +// + +typedef struct { + // + // Apple output protocol we submit data to. + // + APPLE_KEY_MAP_DATABASE_PROTOCOL *KeyMapDb; + + // + // Apple output buffer index + // + UINTN KeyMapDbIndex; + + // + // Apple modifier map (previously reported) + // + APPLE_MODIFIER_MAP Modifiers; + + // + // Previously reported Apple modifiers timestamp + // + UINT64 ModifierCounter; + + // + // Previously reported Apple active keys + // + APPLE_KEY_CODE Keys[AIK_TARGET_BUFFER_SIZE]; + + // + // Previously reported Apple key timestamps + // + UINT64 KeyCounters[AIK_TARGET_BUFFER_SIZE]; + + // + // Amount of active keys previously reported + // + UINTN NumberOfKeys; + + // + // Timestamp counter incremented every refresh + // + UINT64 Counter; + + // + // Remove key if it was not submitted after this value. + // + UINT8 KeyForgotThreshold; + + // + // Assume simultaneous press if within this value. + // + UINT8 KeyMergeThreshold; +} AIK_TARGET; + +EFI_STATUS +AIKTargetInstall ( + IN OUT AIK_TARGET *Target, + IN UINT8 KeyForgotThreshold, + IN UINT8 KeyMergeThreshold + ); + +VOID +AIKTargetUninstall ( + IN OUT AIK_TARGET *Target + ); + +UINT64 +AIKTargetRefresh ( + IN OUT AIK_TARGET *Target + ); + +VOID +AIKTargetWriteEntry ( + IN OUT AIK_TARGET *Target, + IN AMI_EFI_KEY_DATA *KeyData + ); + +VOID +AIKTargetSubmit ( + IN OUT AIK_TARGET *Target + ); + +#endif diff --git a/Library/OcInputLib/Keycode/AIKTranslate.c b/Library/OcInputLib/Keycode/AIKTranslate.c new file mode 100644 index 00000000..a2b68228 --- /dev/null +++ b/Library/OcInputLib/Keycode/AIKTranslate.c @@ -0,0 +1,199 @@ +/** @file + Key translator + +Copyright (c) 2018, vit9696. All rights reserved.
+This program and the accompanying materials +are licensed and made available under the terms and conditions of the BSD License +which accompanies this distribution. The full text of the license may be found at +http://opensource.org/licenses/bsd-license.php + +THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, +WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. + +**/ + +#include "AIKTranslate.h" + +#include + +STATIC +APPLE_MODIFIER_MAP mModifierRemap[AIK_MODIFIER_MAX]; + +STATIC +VOID +AIKTranslateModifiers ( + IN AMI_EFI_KEY_DATA *KeyData, + OUT APPLE_MODIFIER_MAP *Modifiers + ) +{ + UINT32 KeyShiftState; + + KeyShiftState = KeyData->KeyState.KeyShiftState; + + *Modifiers = 0; + + // + // Handle EFI_SIMPLE_TEXT_INPUT_EX_PROTOCOL Shift support, which is not included + // in KeyShiftState on APTIO and VMware. + // UPD: Recent APTIO V also does not include it in its own protocol. + // + if ((KeyShiftState & EFI_SHIFT_STATE_VALID) && KeyData->Key.UnicodeChar < AIK_MAX_EFIKEY_NUM) { + KeyShiftState |= gAikAsciiToUsbMap[KeyData->Key.UnicodeChar].ShiftState; + } + + // + // Handle legacy EFI_SIMPLE_TEXT_INPUT_PROTOCOL by guessing from EfiKey + // + if ((KeyShiftState & EFI_SHIFT_STATE_VALID) != EFI_SHIFT_STATE_VALID + && KeyData->Key.UnicodeChar < AIK_MAX_EFIKEY_NUM) { + KeyShiftState = gAikAsciiToUsbMap[KeyData->Key.UnicodeChar].ShiftState; + } + + if (KeyShiftState & EFI_SHIFT_STATE_VALID) { + if (KeyShiftState & EFI_RIGHT_SHIFT_PRESSED) { + *Modifiers |= mModifierRemap[AIK_RIGHT_SHIFT]; + } + if (KeyShiftState & EFI_LEFT_SHIFT_PRESSED) { + *Modifiers |= mModifierRemap[AIK_LEFT_SHIFT]; + } + if (KeyShiftState & EFI_RIGHT_CONTROL_PRESSED) { + *Modifiers |= mModifierRemap[AIK_RIGHT_CONTROL]; + } + if (KeyShiftState & EFI_LEFT_CONTROL_PRESSED) { + *Modifiers |= mModifierRemap[AIK_LEFT_CONTROL]; + } + if (KeyShiftState & EFI_RIGHT_ALT_PRESSED) { + *Modifiers |= mModifierRemap[AIK_RIGHT_ALT]; + } + if (KeyShiftState & EFI_LEFT_ALT_PRESSED) { + *Modifiers |= mModifierRemap[AIK_LEFT_ALT]; + } + if (KeyShiftState & EFI_RIGHT_LOGO_PRESSED) { + *Modifiers |= mModifierRemap[AIK_RIGHT_GUI]; + } + if (KeyShiftState & EFI_LEFT_LOGO_PRESSED) { + *Modifiers |= mModifierRemap[AIK_LEFT_GUI]; + } + } +} + +STATIC +VOID +AIKTranslateNumpad ( + IN OUT UINT8 *UsbKey, + IN EFI_KEY EfiKey + ) +{ + switch (EfiKey) { + case EfiKeyZero: + *UsbKey = UsbHidUsageIdKbKpKeyZero; + break; + case EfiKeyOne: + *UsbKey = UsbHidUsageIdKbKpKeyOne; + break; + case EfiKeyTwo: + *UsbKey = UsbHidUsageIdKbKpKeyTwo; + break; + case EfiKeyThree: + *UsbKey = UsbHidUsageIdKbKpKeyThree; + break; + case EfiKeyFour: + *UsbKey = UsbHidUsageIdKbKpKeyFour; + break; + case EfiKeyFive: + *UsbKey = UsbHidUsageIdKbKpKeyFive; + break; + case EfiKeySix: + *UsbKey = UsbHidUsageIdKbKpKeySix; + break; + case EfiKeySeven: + *UsbKey = UsbHidUsageIdKbKpKeySeven; + break; + case EfiKeyEight: + *UsbKey = UsbHidUsageIdKbKpKeyEight; + break; + case EfiKeyNine: + *UsbKey = UsbHidUsageIdKbKpKeyNine; + break; + default: + break; + } +} + +VOID +AIKTranslateConfigure ( + VOID + ) +{ + UINTN Index; + CONST APPLE_MODIFIER_MAP DefaultModifierMap[AIK_MODIFIER_MAX] = { + USB_HID_KB_KP_MODIFIER_RIGHT_SHIFT, + USB_HID_KB_KP_MODIFIER_LEFT_SHIFT, + USB_HID_KB_KP_MODIFIER_RIGHT_CONTROL, + USB_HID_KB_KP_MODIFIER_LEFT_CONTROL, + USB_HID_KB_KP_MODIFIER_RIGHT_ALT, + USB_HID_KB_KP_MODIFIER_LEFT_ALT, + USB_HID_KB_KP_MODIFIER_RIGHT_GUI, + USB_HID_KB_KP_MODIFIER_LEFT_GUI + }; + + //TODO: This should be user-configurable, perhaps via a nvram variable. + + // You can swap Alt with Gui, to get Apple layout on a PC keyboard + CONST UINTN DefaultModifierConfig[AIK_MODIFIER_MAX/2] = { + AIK_RIGHT_SHIFT, + AIK_RIGHT_CONTROL, + AIK_RIGHT_ALT, + AIK_RIGHT_GUI + }; + + for (Index = 0; Index < AIK_MODIFIER_MAX/2; Index++) { + mModifierRemap[Index*2] = DefaultModifierMap[DefaultModifierConfig[Index]]; + mModifierRemap[Index*2+1] = DefaultModifierMap[DefaultModifierConfig[Index]+1]; + } +} + +VOID +AIKTranslate ( + IN AMI_EFI_KEY_DATA *KeyData, + OUT APPLE_MODIFIER_MAP *Modifiers, + OUT APPLE_KEY_CODE *Key + ) +{ + AIK_PS2KEY_TO_USB Ps2Key; + + AIKTranslateModifiers (KeyData, Modifiers); + + *Key = UsbHidUndefined; + + // + // Firstly check for APTIO protocol, which reported a PS/2 key to us. + // Otherwise try to decode UnicodeChar and Scancode from simple input. + // + if (KeyData->PS2ScanCodeIsValid == 1 && KeyData->PS2ScanCode < AIK_MAX_PS2KEY_NUM) { + Ps2Key = gAikPs2KeyToUsbMap[KeyData->PS2ScanCode]; + if (Ps2Key.UsbCode != UsbHidUndefined) { + // + // We need to process numpad keys separately. + // + AIKTranslateNumpad (&Ps2Key.UsbCode, KeyData->EfiKey); + *Key = APPLE_HID_USB_KB_KP_USAGE (Ps2Key.UsbCode); + } + } else if (KeyData->Key.UnicodeChar >= 0 + && KeyData->Key.UnicodeChar < AIK_MAX_ASCII_NUM + && gAikAsciiToUsbMap[KeyData->Key.UnicodeChar].UsbCode != UsbHidUndefined) { + *Key = APPLE_HID_USB_KB_KP_USAGE (gAikAsciiToUsbMap[KeyData->Key.UnicodeChar].UsbCode); + } else if (KeyData->Key.ScanCode < AIK_MAX_SCANCODE_NUM + && gAikScanCodeToUsbMap[KeyData->Key.ScanCode].UsbCode != UsbHidUndefined) { + *Key = APPLE_HID_USB_KB_KP_USAGE (gAikScanCodeToUsbMap[KeyData->Key.ScanCode].UsbCode); + } + + if (*Key != UsbHidUndefined) { + DEBUG ((DEBUG_VERBOSE, "\nAIKTranslate P1 MOD %a APPLE 0x%X (%a) PS2 0x%X Ps2Name %a\n", + AIK_MODIFIERS_TO_NAME (*Modifiers), *Key, AIK_APPLEKEY_TO_NAME (*Key), + KeyData->PS2ScanCode, AIK_PS2KEY_TO_NAME (KeyData->PS2ScanCode, *Modifiers))); + DEBUG ((DEBUG_VERBOSE, "AIKTranslate P2 AsciiName %a ScanName %a EfiKey %a Scan 0x%X Uni 0x%X SState 0x%X\n", + AIK_ASCII_TO_NAME (KeyData->Key.UnicodeChar), AIK_SCANCODE_TO_NAME (KeyData->Key.ScanCode), + AIK_EFIKEY_TO_NAME (KeyData->EfiKey), KeyData->Key.ScanCode, KeyData->Key.UnicodeChar, KeyData->KeyState.KeyShiftState)); + } +} diff --git a/Library/OcInputLib/Keycode/AIKTranslate.h b/Library/OcInputLib/Keycode/AIKTranslate.h new file mode 100644 index 00000000..e8538f0b --- /dev/null +++ b/Library/OcInputLib/Keycode/AIKTranslate.h @@ -0,0 +1,126 @@ +/** @file + Key translator + +Copyright (c) 2018, vit9696. All rights reserved.
+This program and the accompanying materials +are licensed and made available under the terms and conditions of the BSD License +which accompanies this distribution. The full text of the license may be found at +http://opensource.org/licenses/bsd-license.php + +THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, +WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. + +**/ + +#ifndef AIK_TRANSLATE_H +#define AIK_TRANSLATE_H + +#include +#include + +#define AIK_MAX_PS2KEY_NUM 128 +#define AIK_MAX_EFIKEY_NUM 128 +#define AIK_MAX_ASCII_NUM 128 +#define AIK_MAX_SCANCODE_NUM 24 + +#define AIK_MAX_MODIFIERS_NUM ( \ + USB_HID_KB_KP_MODIFIER_RIGHT_SHIFT \ + | USB_HID_KB_KP_MODIFIER_LEFT_SHIFT \ + | USB_HID_KB_KP_MODIFIER_RIGHT_CONTROL \ + | USB_HID_KB_KP_MODIFIER_LEFT_CONTROL \ + | USB_HID_KB_KP_MODIFIER_RIGHT_ALT \ + | USB_HID_KB_KP_MODIFIER_LEFT_ALT \ + | USB_HID_KB_KP_MODIFIER_RIGHT_GUI \ + | USB_HID_KB_KP_MODIFIER_LEFT_GUI \ + ) + +#define AIK_APPLEKEY_MIN AppleHidUsbKbUsageKeyA +#define AIK_APPLEKEY_MAX AppleHidUsbKbUsageKeyUpArrow +#define AIK_MAX_APPLEKEY_NUM ((AIK_APPLEKEY_MAX) - (AIK_APPLEKEY_MIN) + 1) + +typedef struct { + UINT8 UsbCode; + CONST CHAR8 *KeyName; + CONST CHAR8 *ShiftKeyName; +} AIK_PS2KEY_TO_USB; + +typedef struct { + UINT8 UsbCode; + UINT32 ShiftState; + CONST CHAR8 *KeyName; +} AIK_EFIKEY_TO_USB; + +typedef struct { + UINT8 UsbCode; + UINT32 ShiftState; + CONST CHAR8 *KeyName; +} AIK_ASCII_TO_USB; + +typedef struct { + UINT8 UsbCode; + CONST CHAR8 *KeyName; +} AIK_SCANCODE_TO_USB; + +extern AIK_PS2KEY_TO_USB gAikPs2KeyToUsbMap[AIK_MAX_PS2KEY_NUM]; +extern AIK_EFIKEY_TO_USB gAikEfiKeyToUsbMap[AIK_MAX_EFIKEY_NUM]; +extern AIK_ASCII_TO_USB gAikAsciiToUsbMap[AIK_MAX_ASCII_NUM]; +extern AIK_SCANCODE_TO_USB gAikScanCodeToUsbMap[AIK_MAX_SCANCODE_NUM]; +extern CONST CHAR8 * gAikModifiersToNameMap[AIK_MAX_MODIFIERS_NUM]; +extern CONST CHAR8 * gAikAppleKeyToNameMap[AIK_MAX_APPLEKEY_NUM]; + +#define AIK_PS2KEY_TO_NAME(k, m) \ + (((k) < AIK_MAX_PS2KEY_NUM && gAikPs2KeyToUsbMap[k].KeyName) \ + ? (((m) & (EFI_LEFT_SHIFT_PRESSED|EFI_RIGHT_SHIFT_PRESSED)) \ + ? gAikPs2KeyToUsbMap[k].ShiftKeyName : gAikPs2KeyToUsbMap[k].KeyName) \ + : "") + +#define AIK_EFIKEY_TO_NAME(k) \ + (((k) < AIK_MAX_EFIKEY_NUM && gAikEfiKeyToUsbMap[k].KeyName) \ + ? gAikEfiKeyToUsbMap[k].KeyName \ + : "") + +#define AIK_ASCII_TO_NAME(k) \ + (((k) >= 0 && (k) < AIK_MAX_ASCII_NUM && gAikAsciiToUsbMap[k].KeyName) \ + ? gAikAsciiToUsbMap[k].KeyName \ + : "") + +#define AIK_SCANCODE_TO_NAME(k) \ + (((k) < AIK_MAX_SCANCODE_NUM && gAikScanCodeToUsbMap[k].KeyName) \ + ? gAikScanCodeToUsbMap[k].KeyName \ + : "") + +#define AIK_MODIFIERS_TO_NAME(k) \ + (((k) < AIK_MAX_MODIFIERS_NUM && gAikModifiersToNameMap[k]) \ + ? gAikModifiersToNameMap[k] \ + : "") + +#define AIK_APPLEKEY_TO_NAME(k) \ + (((k) >= AIK_APPLEKEY_MIN && (k) <= AIK_APPLEKEY_MAX && gAikAppleKeyToNameMap[(k) - AIK_APPLEKEY_MIN]) \ + ? gAikAppleKeyToNameMap[(k) - AIK_APPLEKEY_MIN] \ + : "") + +enum { + AIK_RIGHT_SHIFT, + AIK_LEFT_SHIFT, + AIK_RIGHT_CONTROL, + AIK_LEFT_CONTROL, + AIK_RIGHT_ALT, + AIK_LEFT_ALT, + AIK_RIGHT_GUI, + AIK_LEFT_GUI, + AIK_MODIFIER_MAX +}; + +VOID +AIKTranslateConfigure ( + VOID + ); + +VOID +AIKTranslate ( + IN AMI_EFI_KEY_DATA *KeyData, + OUT APPLE_MODIFIER_MAP *Modifiers, + OUT APPLE_KEY_CODE *Key + ); + +#endif diff --git a/Library/OcInputLib/Keycode/AppleHid.txt b/Library/OcInputLib/Keycode/AppleHid.txt new file mode 100644 index 00000000..b78b7d9e --- /dev/null +++ b/Library/OcInputLib/Keycode/AppleHid.txt @@ -0,0 +1,207 @@ +AppleHidUsbKbUsageKeyA = 0x7004 +AppleHidUsbKbUsageKeyB = 0x7005 +AppleHidUsbKbUsageKeyC = 0x7006 +AppleHidUsbKbUsageKeyD = 0x7007 +AppleHidUsbKbUsageKeyE = 0x7008 +AppleHidUsbKbUsageKeyF = 0x7009 +AppleHidUsbKbUsageKeyG = 0x700A +AppleHidUsbKbUsageKeyH = 0x700B +AppleHidUsbKbUsageKeyI = 0x700C +AppleHidUsbKbUsageKeyJ = 0x700D +AppleHidUsbKbUsageKeyK = 0x700E +AppleHidUsbKbUsageKeyL = 0x700F +AppleHidUsbKbUsageKeyM = 0x7010 +AppleHidUsbKbUsageKeyN = 0x7011 +AppleHidUsbKbUsageKeyO = 0x7012 +AppleHidUsbKbUsageKeyP = 0x7013 +AppleHidUsbKbUsageKeyQ = 0x7014 +AppleHidUsbKbUsageKeyR = 0x7015 +AppleHidUsbKbUsageKeyS = 0x7016 +AppleHidUsbKbUsageKeyT = 0x7017 +AppleHidUsbKbUsageKeyU = 0x7018 +AppleHidUsbKbUsageKeyV = 0x7019 +AppleHidUsbKbUsageKeyW = 0x701A +AppleHidUsbKbUsageKeyX = 0x701B +AppleHidUsbKbUsageKeyY = 0x701C +AppleHidUsbKbUsageKeyZ = 0x701D +AppleHidUsbKbUsageKeyOne = 0x701E +AppleHidUsbKbUsageKeyTwo = 0x701F +AppleHidUsbKbUsageKeyThree = 0x7020 +AppleHidUsbKbUsageKeyFour = 0x7021 +AppleHidUsbKbUsageKeyFive = 0x7022 +AppleHidUsbKbUsageKeySix = 0x7023 +AppleHidUsbKbUsageKeySeven = 0x7024 +AppleHidUsbKbUsageKeyEight = 0x7025 +AppleHidUsbKbUsageKeyNine = 0x7026 +AppleHidUsbKbUsageKeyZero = 0x7027 +AppleHidUsbKbUsageKeyEnter = 0x7028 +AppleHidUsbKbUsageKeyEscape = 0x7029 +AppleHidUsbKbUsageKeyBackSpace = 0x702A +AppleHidUsbKbUsageKeyTab = 0x702B +AppleHidUsbKbUsageKeySpaceBar = 0x702C +AppleHidUsbKbUsageKeyMinus = 0x702D +AppleHidUsbKbUsageKeyEquals = 0x702E +AppleHidUsbKbUsageKeyLeftBracket = 0x702F +AppleHidUsbKbUsageKeyRightBracket = 0x7030 +AppleHidUsbKbUsageKeyBackslash = 0x7031 +AppleHidUsbKbUsageKeyNonUsHash = 0x7032 +AppleHidUsbKbUsageKeySemicolon = 0x7033 +AppleHidUsbKbUsageKeyQuotation = 0x7034 +AppleHidUsbKbUsageKeyAcute = 0x7035 +AppleHidUsbKbUsageKeyComma = 0x7036 +AppleHidUsbKbUsageKeyPeriod = 0x7037 +AppleHidUsbKbUsageKeySlash = 0x7038 +AppleHidUsbKbUsageKeyCLock = 0x7039 +AppleHidUsbKbUsageKeyF1 = 0x703A +AppleHidUsbKbUsageKeyF2 = 0x703B +AppleHidUsbKbUsageKeyF3 = 0x703C +AppleHidUsbKbUsageKeyF4 = 0x703D +AppleHidUsbKbUsageKeyF5 = 0x703E +AppleHidUsbKbUsageKeyF6 = 0x703F +AppleHidUsbKbUsageKeyF7 = 0x7040 +AppleHidUsbKbUsageKeyF8 = 0x7041 +AppleHidUsbKbUsageKeyF9 = 0x7042 +AppleHidUsbKbUsageKeyF10 = 0x7043 +AppleHidUsbKbUsageKeyF11 = 0x7044 +AppleHidUsbKbUsageKeyF12 = 0x7045 +AppleHidUsbKbUsageKeyPrint = 0x7046 +AppleHidUsbKbUsageKeySLock = 0x7047 +AppleHidUsbKbUsageKeyPause = 0x7048 +AppleHidUsbKbUsageKeyIns = 0x7049 +AppleHidUsbKbUsageKeyHome = 0x704A +AppleHidUsbKbUsageKeyPgUp = 0x704B +AppleHidUsbKbUsageKeyDel = 0x704C +AppleHidUsbKbUsageKeyEnd = 0x704D +AppleHidUsbKbUsageKeyPgDn = 0x704E +AppleHidUsbKbUsageKeyRightArrow = 0x704F +AppleHidUsbKbUsageKeyLeftArrow = 0x7050 +AppleHidUsbKbUsageKeyDownArrow = 0x7051 +AppleHidUsbKbUsageKeyUpArrow = 0x7052 +AppleHidUsbKbUsageKeyPadNLck = 0x7053 +AppleHidUsbKbUsageKeyPadSlash = 0x7054 +AppleHidUsbKbUsageKeyPadAsterisk = 0x7055 +AppleHidUsbKbUsageKeyPadMinus = 0x7056 +AppleHidUsbKbUsageKeyPadPlus = 0x7057 +AppleHidUsbKbUsageKeyPadEnter = 0x7058 +AppleHidUsbKbUsageKeyPadOne = 0x7059 +AppleHidUsbKbUsageKeyPadTwo = 0x705A +AppleHidUsbKbUsageKeyPadThree = 0x705B +AppleHidUsbKbUsageKeyPadFour = 0x705C +AppleHidUsbKbUsageKeyPadFive = 0x705D +AppleHidUsbKbUsageKeyPadSix = 0x705E +AppleHidUsbKbUsageKeyPadSeven = 0x705F +AppleHidUsbKbUsageKeyPadEight = 0x7060 +AppleHidUsbKbUsageKeyPadNine = 0x7061 +AppleHidUsbKbUsageKeyPadIns = 0x7062 +AppleHidUsbKbUsageKeyPadDel = 0x7063 +AppleHidUsbKbUsageKeyPadNonUsBackslash = 0x7064 +AppleHidUsbKbUsageKeyPadApplication = 0x7065 +AppleHidUsbKbUsageKeyPadPower = 0x7066 +AppleHidUsbKbUsageKeyPadEquals = 0x7067 +AppleHidUsbKbUsageKeyF13 = 0x7068 +AppleHidUsbKbUsageKeyF14 = 0x7069 +AppleHidUsbKbUsageKeyF15 = 0x706A +AppleHidUsbKbUsageKeyF16 = 0x706B +AppleHidUsbKbUsageKeyF17 = 0x706C +AppleHidUsbKbUsageKeyF18 = 0x706D +AppleHidUsbKbUsageKeyF19 = 0x706E +AppleHidUsbKbUsageKeyF20 = 0x706F +AppleHidUsbKbUsageKeyF21 = 0x7070 +AppleHidUsbKbUsageKeyF22 = 0x7071 +AppleHidUsbKbUsageKeyF23 = 0x7072 +AppleHidUsbKbUsageKeyF24 = 0x7073 +AppleHidUsbKbUsageKeyExecute = 0x7074 +AppleHidUsbKbUsageKeyHelp = 0x7075 +AppleHidUsbKbUsageKeyMenu = 0x7076 +AppleHidUsbKbUsageKeySelect = 0x7077 +AppleHidUsbKbUsageKeyStop = 0x7078 +AppleHidUsbKbUsageKeyAgain = 0x7079 +AppleHidUsbKbUsageKeyUndo = 0x707A +AppleHidUsbKbUsageKeyCut = 0x707B +AppleHidUsbKbUsageKeyCopy = 0x707C +AppleHidUsbKbUsageKeyPaste = 0x707D +AppleHidUsbKbUsageKeyFind = 0x707E +AppleHidUsbKbUsageKeyMute = 0x707F +AppleHidUsbKbUsageKeyVolumeUp = 0x7080 +AppleHidUsbKbUsageKeyVolumeDown = 0x7081 +AppleHidUsbKbUsageLockingKeyCLock = 0x7082 +AppleHidUsbKbusageLockingKeyNLock = 0x7083 +AppleHidUsbKbUsageLockingKeySLock = 0x7084 +AppleHidUsbKbUsageKeyPadComma = 0x7085 +AppleHidUsbKbUsageKeyPadEqualSign = 0x7086 +AppleHidUsbKbUsageKeyInternational1 = 0x7087 +AppleHidUsbKbUsageKeyInternational2 = 0x7088 +AppleHidUsbKbUsageKeyInternational3 = 0x7089 +AppleHidUsbKbUsageKeyInternational4 = 0x708A +AppleHidUsbKbUsageKeyInternational5 = 0x708B +AppleHidUsbKbUsageKeyInternational6 = 0x708C +AppleHidUsbKbUsageKeyInternational7 = 0x708D +AppleHidUsbKbUsageKeyInternational8 = 0x708E +AppleHidUsbKbUsageKeyInternational9 = 0x708F +AppleHidUsbKbUsageKeyLang1 = 0x7090 +AppleHidUsbKbUsageKeyLang2 = 0x7091 +AppleHidUsbKbUsageKeyLang3 = 0x7092 +AppleHidUsbKbUsageKeyLang4 = 0x7093 +AppleHidUsbKbUsageKeyLang5 = 0x7094 +AppleHidUsbKbUsageKeyLang6 = 0x7095 +AppleHidUsbKbUsageKeyLang7 = 0x7096 +AppleHidUsbKbUsageKeyLang8 = 0x7097 +AppleHidUsbKbUsageKeyLang9 = 0x7098 +AppleHidUsbKbUsageKeyAlternateErase = 0x7099 +AppleHidUsbKbUsageKeySysReq = 0x709A +AppleHidUsbKbUsageKeyCancel = 0x709B +AppleHidUsbKbUsageKeyClear = 0x709C +AppleHidUsbKbUsageKeyPrior = 0x709D +AppleHidUsbKbUsageKeyReturn = 0x709E +AppleHidUsbKbUsageKeySeparator = 0x709F +AppleHidUsbKbUsageKeyOut = 0x70A0 +AppleHidUsbKbUsageKeyOper = 0x70A1 +AppleHidUsbKbUsageKeyClearAgain = 0x70A2 +AppleHidUsbKbUsageKeyCrSel = 0x70A3 +AppleHidUsbKbUsageKeyExSel = 0x70A4 +AppleHidUsbKbUsageKeyPadDoubleZero = 0x70B0 +AppleHidUsbKbUsageKeyTrippleZero = 0x70B1 +AppleHidUsbKbUsageKeyThousandsSeparator = 0x70B2 +AppleHidUsbKbUsageKeyDecimalSeparator = 0x70B3 +AppleHidUsbKbUsageKeyCurrencyUnit = 0x70B4 +AppleHidUsbKbUsageKeyCurrencySubUnit = 0x70B5 +AppleHidUsbKbUsageKeyPadLeftBracket = 0x70B6 +AppleHidUsbKbUsageKeyPadRightBracket = 0x70B7 +AppleHidUsbKbUsageKeyPadCurlyLeftBracket = 0x70B8 +AppleHidUsbKbUsageKeyPadCurlyRightBracket = 0x70B9 +AppleHidUsbKbUsageKeyPadTab = 0x70BA +AppleHidUsbKbUsageKeyPadBackspace = 0x70BB +AppleHidUsbKbUsageKeyPadA = 0x70BC +AppleHidUsbKbUsageKeyPadB = 0x70BD +AppleHidUsbKbUsageKeyPadC = 0x70BE +AppleHidUsbKbUsageKeyPadD = 0x70BF +AppleHidUsbKbUsageKeyPadE = 0x70C0 +AppleHidUsbKbUsageKeyPadF = 0x70C1 +AppleHidUsbKbUsageKeyPadXor = 0x70C2 +AppleHidUsbKbUsageKeyPadCaret = 0x70C3 +AppleHidUsbKbUsageKeyPadPercent = 0x70C4 +AppleHidUsbKbUsageKeyPadLeftAngleBracket = 0x70C5 +AppleHidUsbKbUsageKeyPadRightAngleBracket = 0x70C6 +AppleHidUsbKbUsageKeyPadBitwiseAnd = 0x70C7 +AppleHidUsbKbUsageKeyPadLogicalAnd = 0x70C8 +AppleHidUsbKbUsageKeyPadBitwiseOr = 0x70C9 +AppleHidUsbKbUsageKeyPadLogicalOr = 0x70CA +AppleHidUsbKbUsageKeyPadColon = 0x70CB +AppleHidUsbKbUsageKeyPadHash = 0x70CC +AppleHidUsbKbUsageKeyPadSpace = 0x70CD +AppleHidUsbKbUsageKeyPadAt = 0x70CE +AppleHidUsbKbUsageKeyPadExclamationMark = 0x70CF +AppleHidUsbKbUsageKeyPadMemoryStore = 0x70D0 +AppleHidUsbKbUsageKeyPadMemoryRecall = 0x70D1 +AppleHidUsbKbUsageKeyPadMemoryClear = 0x70D2 +AppleHidUsbKbUsageKeyPadMemoryAdd = 0x70D3 +AppleHidUsbKbUsageKeyPadMemorySubtract = 0x70D4 +AppleHidUsbKbUsageKeyPadMemoryMultiply = 0x70D5 +AppleHidUsbKbUsageKeyPadMemoryDivide = 0x70D6 +AppleHidUsbKbUsageKeyPadSign = 0x70D7 +AppleHidUsbKbUsageKeyPadClear = 0x70D8 +AppleHidUsbKbUsageKeyPadClearEntry = 0x70D9 +AppleHidUsbKbUsageKeyPadBinary = 0x70DA +AppleHidUsbKbUsageKeyPadOctal = 0x70DB +AppleHidUsbKbUsageKeyPadDecimal = 0x70DC +AppleHidUsbKbUsageKeyPadHexadecimal = 0x70DD diff --git a/Library/OcInputLib/OcInputLib.inf b/Library/OcInputLib/OcInputLib.inf new file mode 100644 index 00000000..bd90b97b --- /dev/null +++ b/Library/OcInputLib/OcInputLib.inf @@ -0,0 +1,86 @@ +## @file +# Copyright (c) 2016, vit9696. All rights reserved.
+# +# This program and the accompanying materials +# are licensed and made available under the terms and conditions of the BSD License +# which accompanies this distribution. The full text of the license may be found at +# http://opensource.org/licenses/bsd-license.php + +# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, +# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. +# +# +## + +[Defines] + INF_VERSION = 0x00010005 + BASE_NAME = OcInputLib + FILE_GUID = F39652DB-3D7E-49CC-A66B-E99AC74F5D37 + MODULE_TYPE = UEFI_DRIVER + VERSION_STRING = 1.0 + LIBRARY_CLASS = OcInputLib|DXE_CORE DXE_SMM_CORE UEFI_DRIVER UEFI_APPLICATION DXE_DRIVER DXE_RUNTIME_DRIVER DXE_SMM_DRIVER DXE_SAL_DRIVER + +[Sources] + Keycode/AIK.h + Keycode/AIK.c + Keycode/AIKData.c + Keycode/AIKData.h + Keycode/AIKMap.c + Keycode/AIKShim.c + Keycode/AIKShim.h + Keycode/AIKSource.c + Keycode/AIKSource.h + Keycode/AIKTarget.c + Keycode/AIKTarget.h + Keycode/AIKTranslate.c + Keycode/AIKTranslate.h + Pointer/AIM.h + Pointer/AIM.c + Timer/AIT.c + +[Packages] + EfiPkg/EfiPkg.dec + MdeModulePkg/MdeModulePkg.dec + MdePkg/MdePkg.dec + OcSupportPkg/OcSupportPkg.dec + +[LibraryClasses] + BaseMemoryLib + DebugLib + HiiLib + MemoryAllocationLib + OcGuardLib + PcdLib + UefiBootServicesTableLib + UefiDriverEntryPoint + UefiLib + UefiRuntimeServicesTableLib + UefiUsbLib + +[Guids] + # + # Event registered to EFI_HII_SET_KEYBOARD_LAYOUT_EVENT_GUID group, + # which will be triggered by EFI_HII_DATABASE_PROTOCOL.SetKeyboardLayout(). + # + gEfiHiiKeyBoardLayoutGuid ## SOMETIMES_CONSUMES ## Event + gUsbKeyboardLayoutPackageGuid ## SOMETIMES_CONSUMES ## HII + gUsbKeyboardLayoutKeyGuid ## SOMETIMES_PRODUCES ## UNDEFINED + gAppleKeyboardPlatformInfoGuid ## SOMETIMES_CONSUMES + +[Protocols] + gEfiUsbIoProtocolGuid ## TO_START + gEfiDevicePathProtocolGuid ## TO_START + gEfiSimpleTextInProtocolGuid ## BY_START + gEfiSimpleTextInputExProtocolGuid ## BY_START + gEfiSimplePointerProtocolGuid ## BY_START + gEfiTimerArchProtocolGuid ## BY_START + # + # If HII Database Protocol exists, then keyboard layout from HII database is used. + # Otherwise, USB keyboard module tries to use its carried default layout. + # + gEfiHiiDatabaseProtocolGuid ## SOMETIMES_CONSUMES + gAppleKeyMapDatabaseProtocolGuid ## SOMETIMES_CONSUMES + gApplePlatformInfoDatabaseProtocolGuid ## SOMETMES_CONSUMES + gEfiKeyboardInfoProtocolGuid ## SOMETIMES_PRODUCES + gAmiEfiPointerProtocolGuid ## SOMETMES_CONSUMES + gAmiEfiKeycodeProtocolGuid ## SOMETMES_CONSUMES diff --git a/Library/OcInputLib/Pointer/AIM.c b/Library/OcInputLib/Pointer/AIM.c new file mode 100644 index 00000000..93916a8a --- /dev/null +++ b/Library/OcInputLib/Pointer/AIM.c @@ -0,0 +1,573 @@ +/** @file + AmiEfiPointer to EfiPointer translator. + +Copyright (c) 2016, vit9696. All rights reserved.
+This program and the accompanying materials +are licensed and made available under the terms and conditions of the BSD License +which accompanies this distribution. The full text of the license may be found at +http://opensource.org/licenses/bsd-license.php + +THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, +WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. + +**/ + +#include + +#include "AIM.h" + +#include +#include +#include +#include + +STATIC AMI_SHIM_POINTER mAmiShimPointer; + +STATIC UINT8 gIndex = 0; +STATIC UINT8 gXCounts[5] = {0, 0, 0, 0, 0}; +STATIC UINT8 gYCounts[5] = {0, 0, 0, 0, 0}; + +UINT8 +EFIAPI +Abs ( + IN INT32 Value + ) +{ + return (UINT8)(Value < 0 ? -Value : Value); +} + +INT32 +EFIAPI +InternalClamp ( + IN INT32 Value, + IN INT32 Min, + IN INT32 Max + ) +{ + if (Value > Max) { + return Max; + } else if (Value < Min) { + return Min; + } + return Value; +} + +VOID +EFIAPI +AmiShimPointerFilterOut ( + IN OUT UINT8 *AbsX, + IN OUT UINT8 *AbsY, + IN OUT INT32 *X, + IN OUT INT32 *Y + ) +{ + UINT8 Index; + + if (*AbsX == 0) { + gXCounts[gIndex] = 1; + } else if (*AbsX <= 2) { + for (Index = 0; Index < 5; Index++) { + if (!gXCounts[Index]) + break; + } + + if (Index == 5) { + *AbsX = 0; + *X = 0; + } + + gXCounts[gIndex] = 0; + } + + if (*AbsY == 0) { + gYCounts[gIndex] = 1; + } else if (*AbsY <= 2) { + for (Index = 0; Index < 5; Index++) { + if (!gYCounts[Index]) + break; + } + + if (Index == 5) { + *AbsY = 0; + *Y = 0; + } + + gYCounts[gIndex] = 0; + } + + gIndex = gIndex < 4 ? gIndex + 1 : 0; +} + +#ifdef AMI_SHIM_POINTER_AMI_SMOOTHING + +STATIC UINT8 gAbsRange[8] = {42, 36, 30, 24, 18, 12, 6, 1}; +STATIC INT32 gMultipliers[8] = {8, 7, 6, 5, 4, 3, 2, 1}; +STATIC INT32 gIndices[8] = {2, 2, 2, 2, 2, 2, 2, 0}; + +INT32 +AmiShimPointerScale ( + IN INT32 Value, + IN UINT8 AbsValue + ) +{ + UINT8 TmpIndex; + + for (TmpIndex = 0; TmpIndex < 8; TmpIndex++) { + if (AbsValue >= gAbsRange[TmpIndex]) { + break; + } + } + + if (TmpIndex != 8) { + if (Value >= 0) { + Value = gIndices[TmpIndex] + Value * gMultipliers[TmpIndex]; + } else { + Value = Value * gMultipliers[TmpIndex] - gIndices[TmpIndex]; + } + } + + return Value; +} + +VOID +EFIAPI +AmiShimPointerSmooth ( + IN OUT INT32 *X, + IN OUT INT32 *Y, + IN OUT INT32 *Z + ) +{ + UINT8 AbsX, AbsY; + + *X = Clamp (*X, -16, 16); + *Y = Clamp (*Y, -16, 16); + // According to AMI it should not be reported + *Z = 0; + AbsX = Abs (*X); + AbsY = Abs (*Y); + + if (*X == 0 && *Y == 0) { + return; + } + + AmiShimPointerFilterOut (&AbsX, &AbsY, X, Y); + + *X = AmiShimPointerScale(*X, AbsX); + *Y = AmiShimPointerScale(*Y, AbsY); + + *X *= AIM_SCALE_FACTOR; + *Y *= AIM_SCALE_FACTOR; +} + +#else + +STATIC UINT8 gAbsRange[4] = {80, 64, 48, 1}; +STATIC INT32 gMultipliers[4] = {4, 3, 2, 1}; + +VOID +EFIAPI +AmiShimPointerBoostValue ( + IN OUT INT32 *Value, + IN INT32 AbsValue + ) +{ + UINTN Index; + for (Index = 0; Index < 4; Index++) { + if (gAbsRange[Index] > AbsValue) { + *Value *= gMultipliers[Index]; + return; + } + } +} + +VOID +EFIAPI +AmiShimPointerSmooth ( + IN OUT INT32 *X, + IN OUT INT32 *Y, + IN OUT INT32 *Z + ) +{ + UINT8 AbsX, AbsY; + + *X = InternalClamp(*X, -96, 96); + *Y = InternalClamp(*Y, -96, 96); + *Z = 0; + + AbsX = Abs (*X); + AbsY = Abs (*Y); + + if (*X == 0 && *Y == 0) { + return; + } + + AmiShimPointerFilterOut (&AbsX, &AbsY, X, Y); + + AmiShimPointerBoostValue(X, AbsX); + AmiShimPointerBoostValue(Y, AbsY); +} + +#endif + +VOID +EFIAPI +AmiShimPointerPositionHandler ( + IN EFI_EVENT Event, + IN VOID *Context + ) +{ + UINTN Index; + AMI_SHIM_POINTER_INSTANCE *Pointer; + AMI_POINTER_POSITION_STATE_DATA PositionState; + + // Do not poll until somebody actually starts using the mouse + // Otherwise first move will be quite random + if (!mAmiShimPointer.UsageStarted) { + return; + } + + // This is important to do quickly and separately, because AMI stores positioning data in INT8. + // If we move the mouse quickly it will overflow and return invalid data. + for (Index = 0; Index < AIM_MAX_POINTERS; Index++) { + Pointer = &mAmiShimPointer.PointerMap[Index]; + if (Pointer->DeviceHandle != NULL) { + PositionState.Changed = 0; + Pointer->EfiPointer->GetPositionState (Pointer->EfiPointer, &PositionState); + if (PositionState.Changed == 1) { + if (PositionState.Absolute == 0) { + DEBUG ((DEBUG_VERBOSE, "Position: %d %d %d %d\n", + PositionState.Changed, PositionState.PositionX, PositionState.PositionY, PositionState.PositionZ)); + AmiShimPointerSmooth(&PositionState.PositionX, &PositionState.PositionY, &PositionState.PositionZ); + if (PositionState.PositionX != 0 || PositionState.PositionY != 0 || PositionState.PositionZ != 0) { + Pointer->PositionX += PositionState.PositionX; + Pointer->PositionY += PositionState.PositionY; + Pointer->PositionZ += PositionState.PositionZ; + Pointer->PositionChanged = TRUE; + } + } else { + //FIXME: Add support for devices with absolute positioning + } + } + } + } +} + +EFI_STATUS +EFIAPI +AmiShimPointerUpdateState ( + IN AMI_SHIM_POINTER_INSTANCE *Pointer, + OUT EFI_SIMPLE_POINTER_STATE *State + ) +{ + AMI_POINTER_BUTTON_STATE_DATA ButtonState; + + if (!mAmiShimPointer.UsageStarted) { + mAmiShimPointer.UsageStarted = TRUE; + AmiShimPointerPositionHandler(NULL, NULL); + } + + ButtonState.Changed = 0; + Pointer->EfiPointer->GetButtonState (Pointer->EfiPointer, &ButtonState); + + if (ButtonState.Changed == 0 && Pointer->PositionChanged == 0) { + return EFI_NOT_READY; + } + + DEBUG ((DEBUG_VERBOSE, "Button: %d %d %d %d, Position: %d %d %d %d\n", + ButtonState.Changed, ButtonState.LeftButton, ButtonState.MiddleButton, ButtonState.RightButton, + Pointer->PositionChanged, Pointer->PositionX, Pointer->PositionY, Pointer->PositionZ)); + + if (ButtonState.Changed) { + State->LeftButton = ButtonState.LeftButton; + State->RightButton = ButtonState.RightButton; + } else { + State->LeftButton = State->RightButton = FALSE; + } + + if (Pointer->PositionChanged) { + State->RelativeMovementX = Pointer->PositionX; + State->RelativeMovementY = Pointer->PositionY; + State->RelativeMovementZ = Pointer->PositionZ; + } else { + State->RelativeMovementX = State->RelativeMovementY = State->RelativeMovementZ = 0; + } + + Pointer->PositionChanged = 0; + Pointer->PositionX = Pointer->PositionY = Pointer->PositionZ = 0; + + return EFI_SUCCESS; +} + +EFI_STATUS +EFIAPI +AmiShimPointerGetState ( + IN EFI_SIMPLE_POINTER_PROTOCOL *This, + IN OUT EFI_SIMPLE_POINTER_STATE *State + ) +{ + EFI_STATUS Status; + UINTN Index; + AMI_SHIM_POINTER_INSTANCE *Pointer; + + if (This == NULL || State == NULL) { + return EFI_INVALID_PARAMETER; + } + + for (Index = 0, Pointer = mAmiShimPointer.PointerMap; Index < AIM_MAX_POINTERS; Index++, Pointer++) { + if (Pointer->SimplePointer == This) { + break; + } + } + + if (Index != AIM_MAX_POINTERS) { + Status = AmiShimPointerUpdateState (Pointer, State); + + if (!EFI_ERROR (Status)) { + if (State->RelativeMovementX != 0 || + State->RelativeMovementY != 0 || + State->RelativeMovementZ != 0) { + DEBUG ((DEBUG_VERBOSE, "Received[%p] %d %d %d <%d, %d>\n", This, State->RelativeMovementX, State->RelativeMovementY, State->RelativeMovementZ, + State->LeftButton, State->RightButton)); + } else { + DEBUG ((DEBUG_VERBOSE, "Received[%p] %d %d %d\n", This, State->RelativeMovementX, State->RelativeMovementY, State->RelativeMovementZ)); + } + } + } else { + DEBUG ((DEBUG_VERBOSE, "Received unknown this %p\n", This)); + Status = EFI_INVALID_PARAMETER; + } + + return Status; +} + +EFI_STATUS +EFIAPI +AmiShimPointerTimerSetup ( + VOID + ) +{ + EFI_STATUS Status; + + if (mAmiShimPointer.TimersInitialised) { + return EFI_ALREADY_STARTED; + } + + Status = gBS->CreateEvent (EVT_TIMER | EVT_NOTIFY_SIGNAL, TPL_NOTIFY, AmiShimPointerPositionHandler, NULL, &mAmiShimPointer.PositionEvent); + + if (EFI_ERROR (Status)) { + DEBUG ((DEBUG_INFO, "AmiShimPointerPositionHandler event creation failed %d\n", Status)); + return Status; + } + + Status = gBS->SetTimer (mAmiShimPointer.PositionEvent, TimerPeriodic, AIM_POSITION_POLL_INTERVAL); + + if (EFI_ERROR (Status)) { + DEBUG ((DEBUG_INFO, "AmiShimPointerPositionHandler timer setting failed %d\n", Status)); + gBS->CloseEvent (mAmiShimPointer.PositionEvent); + return Status; + } + + mAmiShimPointer.TimersInitialised = TRUE; + + return EFI_SUCCESS; +} + +EFI_STATUS +EFIAPI +AmiShimPointerTimerUninstall ( + VOID + ) +{ + EFI_STATUS Status; + + if (!mAmiShimPointer.TimersInitialised) { + return EFI_SUCCESS; + } + + if (mAmiShimPointer.PositionEvent != NULL) { + Status = gBS->SetTimer (mAmiShimPointer.PositionEvent, TimerCancel, 0); + if (!EFI_ERROR (Status)) { + gBS->CloseEvent (mAmiShimPointer.PositionEvent); + mAmiShimPointer.PositionEvent = NULL; + } else { + DEBUG((DEBUG_INFO, "AmiShimPointerPositionHandler timer unsetting failed %d\n", Status)); + } + } + + mAmiShimPointer.TimersInitialised = FALSE; + + return EFI_SUCCESS; +} + +EFI_STATUS +EFIAPI +AmiShimPointerInstallOnHandle ( + IN EFI_HANDLE DeviceHandle, + IN AMI_EFIPOINTER_PROTOCOL *EfiPointer, + IN EFI_SIMPLE_POINTER_PROTOCOL *SimplePointer + ) +{ + UINTN Index; + AMI_SHIM_POINTER_INSTANCE *Pointer; + AMI_SHIM_POINTER_INSTANCE *FreePointer; + + FreePointer = NULL; + + for (Index = 0; Index < AIM_MAX_POINTERS; Index++) { + Pointer = &mAmiShimPointer.PointerMap[Index]; + if (Pointer->DeviceHandle == NULL && FreePointer == NULL) { + FreePointer = Pointer; + } else if (Pointer->DeviceHandle == DeviceHandle) { + return EFI_ALREADY_STARTED; + } + } + + if (FreePointer == NULL) { + return EFI_OUT_OF_RESOURCES; + } + + DEBUG ((DEBUG_INFO, "Installed onto %X\n", DeviceHandle)); + FreePointer->DeviceHandle = DeviceHandle; + FreePointer->EfiPointer = EfiPointer; + FreePointer->SimplePointer = SimplePointer; + if (FreePointer->SimplePointer->GetState == AmiShimPointerGetState) { + FreePointer->OriginalGetState = NULL; + DEBUG ((DEBUG_INFO, "Function is already hooked\n")); + } else { + FreePointer->OriginalGetState = FreePointer->SimplePointer->GetState; + FreePointer->SimplePointer->GetState = AmiShimPointerGetState; + } + + return EFI_SUCCESS; +} + +EFI_STATUS +EFIAPI +AmiShimPointerInstall ( + VOID + ) +{ + EFI_STATUS Status; + UINTN NoHandles; + EFI_HANDLE *Handles; + UINTN Index; + BOOLEAN Installed; + AMI_EFIPOINTER_PROTOCOL *EfiPointer; + EFI_SIMPLE_POINTER_PROTOCOL *SimplePointer; + + Status = gBS->LocateHandleBuffer (ByProtocol, &gAmiEfiPointerProtocolGuid, NULL, &NoHandles, &Handles); + if (EFI_ERROR(Status)) { + return EFI_NOT_FOUND; + } + + DEBUG ((DEBUG_INFO, "Found %d Handles located by protocol\n", NoHandles)); + + Installed = FALSE; + + for (Index = 0; Index < NoHandles; Index++) { + Status = gBS->HandleProtocol (Handles[Index], &gAmiEfiPointerProtocolGuid, (VOID **)&EfiPointer); + if (EFI_ERROR(Status)) { + DEBUG ((DEBUG_INFO, "Handle %d has no AmiEfiPointerl %d\n", Index, Status)); + continue; + } + + Status = gBS->HandleProtocol (Handles[Index], &gEfiSimplePointerProtocolGuid, (VOID **)&SimplePointer); + if (EFI_ERROR(Status)) { + DEBUG ((DEBUG_INFO, "Handle %d has no EfiSimplePointer %d\n", Index, Status)); + continue; + } + + Status = AmiShimPointerInstallOnHandle (Handles[Index], EfiPointer, SimplePointer); + if (EFI_ERROR(Status)) { + DEBUG ((DEBUG_INFO, "Handle %d failed to get installed %d\n", Index, Status)); + continue; + } + + Installed = TRUE; + } + + gBS->FreePool (Handles); + + if (!Installed) { + return EFI_NOT_FOUND; + } + + if (!mAmiShimPointer.TimersInitialised) { + return AmiShimPointerTimerSetup(); + } + + return EFI_SUCCESS; +} + +EFI_STATUS +EFIAPI +AmiShimPointerUninstall ( + VOID + ) +{ + UINTN Index; + AMI_SHIM_POINTER_INSTANCE *Pointer; + + AmiShimPointerTimerUninstall(); + + for (Index = 0; Index < AIM_MAX_POINTERS; Index++) { + Pointer = &mAmiShimPointer.PointerMap[Index]; + if (Pointer->DeviceHandle != NULL) { + Pointer->SimplePointer->GetState = Pointer->OriginalGetState; + gBS->DisconnectController(Pointer->DeviceHandle, NULL, NULL); + Pointer->DeviceHandle = NULL; + } + } + + return EFI_SUCCESS; +} + +VOID +EFIAPI +AmiShimPointerArriveHandler ( + IN EFI_EVENT Event, + IN VOID *Context + ) +{ + AmiShimPointerInstall(); +} + +EFI_STATUS +OcAppleGenericInputPointerInit ( + IN OC_INPUT_POINTER_MODE Mode + ) +{ + EFI_STATUS Status; + VOID *Registration; + + // + // Currently, ASUS is the only supported mode, hence it is not verified. + // The caller is required to pass a valid mode. + // + + Status = gBS->CreateEvent (EVT_NOTIFY_SIGNAL, TPL_NOTIFY, AmiShimPointerArriveHandler, NULL, &mAmiShimPointer.ProtocolArriveEvent); + + if (EFI_ERROR (Status)) { + DEBUG ((DEBUG_INFO, "AmiShimPointerArriveHandler event creation failed %d\n", Status)); + return Status; + } + + // EfiSimplePointer gets installed after AMI proprietary protocol + Status = gBS->RegisterProtocolNotify (&gEfiSimplePointerProtocolGuid, mAmiShimPointer.ProtocolArriveEvent, &Registration); + + if (EFI_ERROR (Status)) { + DEBUG ((DEBUG_INFO, "AmiShimProtocolArriveHandler protocol registration failed %d\n", Status)); + gBS->CloseEvent (mAmiShimPointer.ProtocolArriveEvent); + return Status; + } + + return AmiShimPointerInstall(); +} + +EFI_STATUS +OcAppleGenericInputPointerExit ( + VOID + ) +{ + return AmiShimPointerUninstall(); +} diff --git a/Library/OcInputLib/Pointer/AIM.h b/Library/OcInputLib/Pointer/AIM.h new file mode 100644 index 00000000..96dfc138 --- /dev/null +++ b/Library/OcInputLib/Pointer/AIM.h @@ -0,0 +1,57 @@ +/** @file + Header file for AmiEfiPointer to EfiPointer translator. + +Copyright (c) 2016, vit9696. All rights reserved.
+This program and the accompanying materials +are licensed and made available under the terms and conditions of the BSD License +which accompanies this distribution. The full text of the license may be found at +http://opensource.org/licenses/bsd-license.php + +THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, +WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. + +**/ + +#ifndef AIM_SELF_H +#define AIM_SELF_H + +#include +#include +#include + +// +// Taken from APTIO IV Z87. +// +#define AIM_MAX_POINTERS 6 + +// +// APTIO IV Z87 has 66666 here. +// Slightly lower resolution results in sometimes overflowng mouse. +// +#define AIM_POSITION_POLL_INTERVAL 66666 + +// +// Position movement boost. +// +#define AIM_SCALE_FACTOR 1 + +typedef struct { + EFI_HANDLE DeviceHandle; + AMI_EFIPOINTER_PROTOCOL *EfiPointer; + EFI_SIMPLE_POINTER_PROTOCOL *SimplePointer; + EFI_SIMPLE_POINTER_GET_STATE OriginalGetState; + BOOLEAN PositionChanged; + INT32 PositionX; + INT32 PositionY; + INT32 PositionZ; +} AMI_SHIM_POINTER_INSTANCE; + +typedef struct { + BOOLEAN TimersInitialised; + BOOLEAN UsageStarted; + EFI_EVENT ProtocolArriveEvent; + EFI_EVENT PositionEvent; + AMI_SHIM_POINTER_INSTANCE PointerMap[AIM_MAX_POINTERS]; +} AMI_SHIM_POINTER; + +#endif diff --git a/Library/OcInputLib/Timer/AIT.c b/Library/OcInputLib/Timer/AIT.c new file mode 100644 index 00000000..d0def75a --- /dev/null +++ b/Library/OcInputLib/Timer/AIT.c @@ -0,0 +1,88 @@ +/** @file + Timer booster + +Copyright (c) 2018, vit9696. All rights reserved.
+This program and the accompanying materials +are licensed and made available under the terms and conditions of the BSD License +which accompanies this distribution. The full text of the license may be found at +http://opensource.org/licenses/bsd-license.php + +THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, +WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. + +**/ + +#include + +#include +#include +#include +#include + +STATIC UINTN mOriginalTimerPeriod; +STATIC EFI_TIMER_ARCH_PROTOCOL *mTimerProtocol; + +EFI_STATUS +OcAppleGenericInputTimerQuirkInit ( + IN UINT32 TimerResolution + ) +{ + EFI_STATUS Status; + // + // Refresh rate needs to be increased to poll mouse and keyboard frequently enough + // + Status = gBS->LocateProtocol (&gEfiTimerArchProtocolGuid, NULL, (VOID **)&mTimerProtocol); + if (!EFI_ERROR (Status)) { + Status = mTimerProtocol->GetTimerPeriod (mTimerProtocol, &mOriginalTimerPeriod); + if (!EFI_ERROR (Status)) { + DEBUG ((DEBUG_INFO, "AIFTimerBoostInit Current timer is %u\n", mOriginalTimerPeriod)); + if (mOriginalTimerPeriod > TimerResolution) { + Status = mTimerProtocol->SetTimerPeriod (mTimerProtocol, TimerResolution); + if (!EFI_ERROR (Status)) { + DEBUG ((DEBUG_INFO, "AIFTimerBoostInit changed period %d to %d\n", + mOriginalTimerPeriod, TimerResolution)); + } else { + DEBUG ((DEBUG_INFO, "AIFTimerBoostInit failed to change period %d to %d, error - %r\n", + mOriginalTimerPeriod, TimerResolution, Status)); + mTimerProtocol = NULL; + } + } else { + mTimerProtocol = NULL; + } + } else { + DEBUG ((DEBUG_INFO, "AIFTimerBoostInit failed to obtain previous period - %r\n", Status)); + } + } else { + DEBUG ((DEBUG_INFO, "AIFTimerBoostInit gEfiTimerArchProtocolGuid not found - %r\n", Status)); + } + + return Status; +} + +EFI_STATUS +OcAppleGenericInputTimerQuirkExit ( + VOID + ) +{ + EFI_STATUS Status; + + Status = EFI_SUCCESS; + + if (mTimerProtocol != NULL) { + // + // You are not allowed to call this on APTIO IV, as it results in an interrupt with 0x0 pointer + // handler during XNU boot. + // + // Status = mTimerProtocol->SetTimerPeriod (mTimerProtocol, mOriginalTimerPeriod); + // if (!EFI_ERROR (Status)) { + // DEBUG ((DEBUG_INFO, "AmiShimTimerBoostExit changed period %d to %d\n", + // AIT_TIMER_PERIOD, mOriginalTimerPeriod)); + // } else { + // DEBUG ((DEBUG_INFO, "AmiShimTimerBoostExit failed to change period %d to %d, error - %r\n", + // AIT_TIMER_PERIOD, mOriginalTimerPeriod, Status)); + // } + mTimerProtocol = NULL; + } + + return Status; +} diff --git a/OcSupportPkg.dec b/OcSupportPkg.dec index e98a3bde..0be863a8 100644 --- a/OcSupportPkg.dec +++ b/OcSupportPkg.dec @@ -53,6 +53,13 @@ ## Include/Protocol/FirmwareVolume.h gEfiFirmwareVolumeProtocolGuid = { 0x389F751F, 0x1838, 0x4388, { 0x83, 0x90, 0xcd, 0x81, 0x54, 0xbd, 0x27, 0xf8 }} + ## Include/Protocol/AmiPointer.h + gAmiEfiPointerProtocolGuid = { 0x15A10CE7, 0xEAB5, 0x43BF, { 0x90, 0x42, 0x74, 0x43, 0x2E, 0x69, 0x63, 0x77 } } + + + ## Include/Protocol/AmiKeycode.h + gAmiEfiKeycodeProtocolGuid = { 0x0ADFB62D, 0xFF74, 0x484C, { 0x89, 0x44, 0xF8, 0x5C, 0x4B, 0xEA, 0x87, 0xA8 } } + [PcdsFeatureFlag] ## Indicates if Apple Thunderbolt NHI protocol is called during device property export.

# TRUE - Apple Thunderbolt NHI protocol will be called.
diff --git a/OcSupportPkg.dsc b/OcSupportPkg.dsc index ef4adf34..c4d3840a 100644 --- a/OcSupportPkg.dsc +++ b/OcSupportPkg.dsc @@ -57,6 +57,7 @@ OcAppleDerLib|OcSupportPkg/Library/OcAppleDerLib/OcAppleDerLib.inf OcAppleDiskImageLib|OcSupportPkg/Library/OcAppleDiskImageLib/OcAppleDiskImageLib.inf OcAppleEventLib|OcSupportPkg/Library/OcAppleEventLib/OcAppleEventLib.inf + OcInputLib|OcSupportPkg/Library/OcInputLib/OcInputLib.inf OcAppleImageConversionLib|OcSupportPkg/Library/OcAppleImageConversionLib/OcAppleImageConversionLib.inf OcAppleImageVerificationLib|OcSupportPkg/Library/OcAppleImageVerificationLib/OcAppleImageVerificationLib.inf OcAppleKernelLib|OcSupportPkg/Library/OcAppleKernelLib/OcAppleKernelLib.inf @@ -102,6 +103,7 @@ OcSupportPkg/Library/OcAppleDerLib/OcAppleDerLib.inf OcSupportPkg/Library/OcAppleDiskImageLib/OcAppleDiskImageLib.inf OcSupportPkg/Library/OcAppleEventLib/OcAppleEventLib.inf + OcSupportPkg/Library/OcInputLib/OcInputLib.inf OcSupportPkg/Library/OcAppleImageConversionLib/OcAppleImageConversionLib.inf OcSupportPkg/Library/OcAppleImageVerificationLib/OcAppleImageVerificationLib.inf OcSupportPkg/Library/OcAppleKernelLib/OcAppleKernelLib.inf