mirror of
https://github.com/acidanthera/OpenCorePkg.git
synced 2025-12-08 19:25:01 +00:00
OcInputLib: Initial import
This commit is contained in:
parent
4740f35ff9
commit
eedf63f106
@ -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)
|
||||
|
||||
63
Include/Library/OcInputLib.h
Normal file
63
Include/Library/OcInputLib.h
Normal file
@ -0,0 +1,63 @@
|
||||
/** @file
|
||||
OC Apple generic input library.
|
||||
|
||||
Copyright (c) 2019, vit9696. All rights reserved.<BR>
|
||||
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
|
||||
59
Include/Protocol/AmiKeycode.h
Normal file
59
Include/Protocol/AmiKeycode.h
Normal file
@ -0,0 +1,59 @@
|
||||
/** @file
|
||||
Header file for AMI EfiKeycode protocol definitions.
|
||||
|
||||
Copyright (c) 2016, vit9696. All rights reserved.<BR>
|
||||
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
|
||||
82
Include/Protocol/AmiPointer.h
Normal file
82
Include/Protocol/AmiPointer.h
Normal file
@ -0,0 +1,82 @@
|
||||
/** @file
|
||||
Header file for AMI EfiPointer protocol definitions.
|
||||
|
||||
Copyright (c) 2016, vit9696. All rights reserved.<BR>
|
||||
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 <Library/OcGuardLib.h>
|
||||
|
||||
// 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
|
||||
@ -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)
|
||||
};
|
||||
|
||||
262
Library/OcInputLib/Keycode/AIK.c
Normal file
262
Library/OcInputLib/Keycode/AIK.c
Normal file
@ -0,0 +1,262 @@
|
||||
/** @file
|
||||
AmiEfiKeycode to KeyMapDb translator.
|
||||
|
||||
Copyright (c) 2018, vit9696. All rights reserved.<BR>
|
||||
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 <Uefi.h>
|
||||
|
||||
#include "AIK.h"
|
||||
|
||||
#include <Library/DebugLib.h>
|
||||
#include <Library/OcInputLib.h>
|
||||
#include <Library/UefiBootServicesTableLib.h>
|
||||
|
||||
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;
|
||||
}
|
||||
113
Library/OcInputLib/Keycode/AIK.h
Normal file
113
Library/OcInputLib/Keycode/AIK.h
Normal file
@ -0,0 +1,113 @@
|
||||
/** @file
|
||||
Header file for AmiEfiKeycode to KeyMapDb translator.
|
||||
|
||||
Copyright (c) 2018, vit9696. All rights reserved.<BR>
|
||||
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 <Library/OcInputLib.h>
|
||||
#include <Library/UefiLib.h>
|
||||
|
||||
//
|
||||
// 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
|
||||
81
Library/OcInputLib/Keycode/AIKData.c
Normal file
81
Library/OcInputLib/Keycode/AIKData.c
Normal file
@ -0,0 +1,81 @@
|
||||
/** @file
|
||||
Key code ring
|
||||
|
||||
Copyright (c) 2018, vit9696. All rights reserved.<BR>
|
||||
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 <Library/BaseMemoryLib.h>
|
||||
#include <Library/DebugLib.h>
|
||||
|
||||
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;
|
||||
}
|
||||
}
|
||||
57
Library/OcInputLib/Keycode/AIKData.h
Normal file
57
Library/OcInputLib/Keycode/AIKData.h
Normal file
@ -0,0 +1,57 @@
|
||||
/** @file
|
||||
Key code ring
|
||||
|
||||
Copyright (c) 2018, vit9696. All rights reserved.<BR>
|
||||
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 <Protocol/AmiKeycode.h>
|
||||
|
||||
//
|
||||
// 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
|
||||
2394
Library/OcInputLib/Keycode/AIKMap.c
Normal file
2394
Library/OcInputLib/Keycode/AIKMap.c
Normal file
File diff suppressed because it is too large
Load Diff
198
Library/OcInputLib/Keycode/AIKShim.c
Normal file
198
Library/OcInputLib/Keycode/AIKShim.c
Normal file
@ -0,0 +1,198 @@
|
||||
/** @file
|
||||
Key shimming code
|
||||
|
||||
Copyright (c) 2018, vit9696. All rights reserved.<BR>
|
||||
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 <Library/BaseMemoryLib.h>
|
||||
#include <Library/DebugLib.h>
|
||||
#include <Library/UefiBootServicesTableLib.h>
|
||||
|
||||
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);
|
||||
}
|
||||
}
|
||||
72
Library/OcInputLib/Keycode/AIKShim.h
Normal file
72
Library/OcInputLib/Keycode/AIKShim.h
Normal file
@ -0,0 +1,72 @@
|
||||
/** @file
|
||||
Key shimming code
|
||||
|
||||
Copyright (c) 2018, vit9696. All rights reserved.<BR>
|
||||
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 <Protocol/AmiKeycode.h>
|
||||
#include <Protocol/SimpleTextIn.h>
|
||||
#include <Protocol/SimpleTextInEx.h>
|
||||
|
||||
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
|
||||
|
||||
212
Library/OcInputLib/Keycode/AIKSource.c
Normal file
212
Library/OcInputLib/Keycode/AIKSource.c
Normal file
@ -0,0 +1,212 @@
|
||||
/** @file
|
||||
Key provider
|
||||
|
||||
Copyright (c) 2018, vit9696. All rights reserved.<BR>
|
||||
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 <Library/BaseMemoryLib.h>
|
||||
#include <Library/DebugLib.h>
|
||||
#include <Library/OcInputLib.h>
|
||||
#include <Library/UefiBootServicesTableLib.h>
|
||||
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
||||
71
Library/OcInputLib/Keycode/AIKSource.h
Normal file
71
Library/OcInputLib/Keycode/AIKSource.h
Normal file
@ -0,0 +1,71 @@
|
||||
/** @file
|
||||
Key provider
|
||||
|
||||
Copyright (c) 2018, vit9696. All rights reserved.<BR>
|
||||
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 <Protocol/AmiKeycode.h>
|
||||
#include <Protocol/SimpleTextIn.h>
|
||||
#include <Protocol/SimpleTextInEx.h>
|
||||
|
||||
#include <Library/OcInputLib.h>
|
||||
|
||||
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
|
||||
196
Library/OcInputLib/Keycode/AIKTarget.c
Normal file
196
Library/OcInputLib/Keycode/AIKTarget.c
Normal file
@ -0,0 +1,196 @@
|
||||
/** @file
|
||||
Key consumer
|
||||
|
||||
Copyright (c) 2018, vit9696. All rights reserved.<BR>
|
||||
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 <Library/BaseMemoryLib.h>
|
||||
#include <Library/DebugLib.h>
|
||||
#include <Library/UefiBootServicesTableLib.h>
|
||||
|
||||
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));
|
||||
}
|
||||
}
|
||||
116
Library/OcInputLib/Keycode/AIKTarget.h
Normal file
116
Library/OcInputLib/Keycode/AIKTarget.h
Normal file
@ -0,0 +1,116 @@
|
||||
/** @file
|
||||
Key consumer
|
||||
|
||||
Copyright (c) 2018, vit9696. All rights reserved.<BR>
|
||||
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 <IndustryStandard/AppleHid.h>
|
||||
#include <Protocol/AppleKeyMapDatabase.h>
|
||||
#include <Protocol/AmiKeycode.h>
|
||||
|
||||
//
|
||||
// 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
|
||||
199
Library/OcInputLib/Keycode/AIKTranslate.c
Normal file
199
Library/OcInputLib/Keycode/AIKTranslate.c
Normal file
@ -0,0 +1,199 @@
|
||||
/** @file
|
||||
Key translator
|
||||
|
||||
Copyright (c) 2018, vit9696. All rights reserved.<BR>
|
||||
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 <Library/DebugLib.h>
|
||||
|
||||
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));
|
||||
}
|
||||
}
|
||||
126
Library/OcInputLib/Keycode/AIKTranslate.h
Normal file
126
Library/OcInputLib/Keycode/AIKTranslate.h
Normal file
@ -0,0 +1,126 @@
|
||||
/** @file
|
||||
Key translator
|
||||
|
||||
Copyright (c) 2018, vit9696. All rights reserved.<BR>
|
||||
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 <IndustryStandard/AppleHid.h>
|
||||
#include <Protocol/AmiKeycode.h>
|
||||
|
||||
#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) \
|
||||
: "<ps2key>")
|
||||
|
||||
#define AIK_EFIKEY_TO_NAME(k) \
|
||||
(((k) < AIK_MAX_EFIKEY_NUM && gAikEfiKeyToUsbMap[k].KeyName) \
|
||||
? gAikEfiKeyToUsbMap[k].KeyName \
|
||||
: "<efikey>")
|
||||
|
||||
#define AIK_ASCII_TO_NAME(k) \
|
||||
(((k) >= 0 && (k) < AIK_MAX_ASCII_NUM && gAikAsciiToUsbMap[k].KeyName) \
|
||||
? gAikAsciiToUsbMap[k].KeyName \
|
||||
: "<ascii>")
|
||||
|
||||
#define AIK_SCANCODE_TO_NAME(k) \
|
||||
(((k) < AIK_MAX_SCANCODE_NUM && gAikScanCodeToUsbMap[k].KeyName) \
|
||||
? gAikScanCodeToUsbMap[k].KeyName \
|
||||
: "<scancode>")
|
||||
|
||||
#define AIK_MODIFIERS_TO_NAME(k) \
|
||||
(((k) < AIK_MAX_MODIFIERS_NUM && gAikModifiersToNameMap[k]) \
|
||||
? gAikModifiersToNameMap[k] \
|
||||
: "<none>")
|
||||
|
||||
#define AIK_APPLEKEY_TO_NAME(k) \
|
||||
(((k) >= AIK_APPLEKEY_MIN && (k) <= AIK_APPLEKEY_MAX && gAikAppleKeyToNameMap[(k) - AIK_APPLEKEY_MIN]) \
|
||||
? gAikAppleKeyToNameMap[(k) - AIK_APPLEKEY_MIN] \
|
||||
: "<aapl>")
|
||||
|
||||
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
|
||||
207
Library/OcInputLib/Keycode/AppleHid.txt
Normal file
207
Library/OcInputLib/Keycode/AppleHid.txt
Normal file
@ -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
|
||||
86
Library/OcInputLib/OcInputLib.inf
Normal file
86
Library/OcInputLib/OcInputLib.inf
Normal file
@ -0,0 +1,86 @@
|
||||
## @file
|
||||
# Copyright (c) 2016, vit9696. All rights reserved.<BR>
|
||||
#
|
||||
# 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
|
||||
573
Library/OcInputLib/Pointer/AIM.c
Normal file
573
Library/OcInputLib/Pointer/AIM.c
Normal file
@ -0,0 +1,573 @@
|
||||
/** @file
|
||||
AmiEfiPointer to EfiPointer translator.
|
||||
|
||||
Copyright (c) 2016, vit9696. All rights reserved.<BR>
|
||||
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 <Uefi.h>
|
||||
|
||||
#include "AIM.h"
|
||||
|
||||
#include <Library/BaseMemoryLib.h>
|
||||
#include <Library/DebugLib.h>
|
||||
#include <Library/OcInputLib.h>
|
||||
#include <Library/UefiBootServicesTableLib.h>
|
||||
|
||||
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();
|
||||
}
|
||||
57
Library/OcInputLib/Pointer/AIM.h
Normal file
57
Library/OcInputLib/Pointer/AIM.h
Normal file
@ -0,0 +1,57 @@
|
||||
/** @file
|
||||
Header file for AmiEfiPointer to EfiPointer translator.
|
||||
|
||||
Copyright (c) 2016, vit9696. All rights reserved.<BR>
|
||||
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 <Library/UefiLib.h>
|
||||
#include <Protocol/AmiPointer.h>
|
||||
#include <Protocol/SimplePointer.h>
|
||||
|
||||
//
|
||||
// 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
|
||||
88
Library/OcInputLib/Timer/AIT.c
Normal file
88
Library/OcInputLib/Timer/AIT.c
Normal file
@ -0,0 +1,88 @@
|
||||
/** @file
|
||||
Timer booster
|
||||
|
||||
Copyright (c) 2018, vit9696. All rights reserved.<BR>
|
||||
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 <Uefi.h>
|
||||
|
||||
#include <Library/DebugLib.h>
|
||||
#include <Library/UefiBootServicesTableLib.h>
|
||||
#include <Library/UefiLib.h>
|
||||
#include <Protocol/Timer.h>
|
||||
|
||||
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;
|
||||
}
|
||||
@ -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.<BR><BR>
|
||||
# TRUE - Apple Thunderbolt NHI protocol will be called.<BR>
|
||||
|
||||
@ -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
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user