提交 8299c889 编写于 作者: D Download-Fritz

OcAppleKeyMapLib and OcAppleEventLib: Initial import

上级 ea27502f
/** @file
Copyright (C) 2019, Download-Fritz. All rights reserved.
This program and the accompanying materials
are licensed and made available under the terms and conditions of the BSD License
which accompanies this distribution. The full text of the license may be found at
http://opensource.org/licenses/bsd-license.php
THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
**/
#ifndef OC_APPLE_EVENT_LIB_H
#define OC_APPLE_EVENT_LIB_H
#include <IndustryStandard/AppleHid.h>
#include <Protocol/AppleEvent.h>
/**
Install and initialise Apple Event protocol.
@param[in] Reinstall Overwrite installed protocol.
@retval installed or located protocol or NULL.
**/
APPLE_EVENT_PROTOCOL *
OcAppleEventInstallProtocol (
IN BOOLEAN Reinstall
);
#endif // OC_APPLE_EVENT_LIB_H
/** @file
Copyright (C) 2019, Download-Fritz. All rights reserved.
This program and the accompanying materials
are licensed and made available under the terms and conditions of the BSD License
which accompanies this distribution. The full text of the license may be found at
http://opensource.org/licenses/bsd-license.php
THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
**/
#ifndef OC_APPLE_KEY_MAP_LIB_H
#define OC_APPLE_KEY_MAP_LIB_H
#include <Protocol/AppleKeyMapDatabase.h>
#include <Protocol/AppleKeyMapAggregator.h>
/**
Install and initialise Apple Key Map protocols.
@param[out] KeyMapDatabase On success, installed or located protocol.
@param[out] KeyMapAggregator On success, installed or located protocol.
@param[in] Reinstall Overwrite installed protocols.
@returns Success status
**/
BOOLEAN
OcAppleKeyMapInstallProtocols (
OUT APPLE_KEY_MAP_DATABASE_PROTOCOL **KeyMapDatabase,
OUT APPLE_KEY_MAP_AGGREGATOR_PROTOCOL **KeyMapAggregator,
IN BOOLEAN Reinstall
);
#endif // OC_APPLE_KEY_MAP_LIB_H
/** @file
AppleEventDxe
Copyright (c) 2018, vit9696
All rights reserved.
This program and the accompanying materials
are licensed and made available under the terms and conditions of the BSD License
which accompanies this distribution. The full text of the license may be found at
http://opensource.org/licenses/bsd-license.php
THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
**/
#include <AppleMacEfi.h>
#include <Library/BaseLib.h>
#include <Library/DebugLib.h>
#include <Library/MemoryAllocationLib.h>
#include <Library/UefiBootServicesTableLib.h>
#include "AppleEventInternal.h"
// APPLE_EVENT_HANDLE_PRIVATE_SIGNATURE
#define APPLE_EVENT_HANDLE_PRIVATE_SIGNATURE \
SIGNATURE_32 ('A', 'L', 's', 't')
// APPLE_EVENT_HANDLE_PRIVATE_FROM_LIST_ENTRY
#define APPLE_EVENT_HANDLE_PRIVATE_FROM_LIST_ENTRY(Handle) \
CR ( \
(Handle), \
APPLE_EVENT_HANDLE_PRIVATE, \
Link, \
APPLE_EVENT_HANDLE_PRIVATE_SIGNATURE \
)
// APPLE_EVENT_HANDLE_PRIVATE
typedef struct {
UINT32 Signature; ///<
LIST_ENTRY Link; ///<
BOOLEAN Ready; ///<
BOOLEAN Registered; ///<
APPLE_EVENT_TYPE EventType; ///<
APPLE_EVENT_NOTIFY_FUNCTION NotifyFunction; ///<
VOID *NotifyContext; ///<
CHAR8 *Name; ///<
} APPLE_EVENT_HANDLE_PRIVATE;
// mEventHandles
STATIC
LIST_ENTRY mEventHandles = INITIALIZE_LIST_HEAD_VARIABLE (mEventHandles);
// mNumberOfEventHandles
STATIC UINTN mNumberOfEventHandles = 0;
// EventLibCreateTimerEvent
EFI_EVENT
EventLibCreateTimerEvent (
IN EFI_EVENT_NOTIFY NotifyFunction,
IN VOID *NotifyContext,
IN UINT64 TriggerTime,
IN BOOLEAN SignalPeriodic,
IN EFI_TPL NotifyTpl
)
{
EFI_EVENT Event;
EFI_STATUS Status;
DEBUG ((DEBUG_VERBOSE, "EventLibCreateTimerEvent\n"));
Event = NULL;
if (NotifyTpl >= TPL_CALLBACK) {
Status = gBS->CreateEvent (
((NotifyFunction != NULL)
? (EVT_TIMER | EVT_NOTIFY_SIGNAL)
: EVT_TIMER),
NotifyTpl,
NotifyFunction,
NotifyContext,
&Event
);
if (!EFI_ERROR (Status)) {
Status = gBS->SetTimer (
Event,
(SignalPeriodic ? TimerPeriodic : TimerRelative),
TriggerTime
);
if (EFI_ERROR (Status)) {
gBS->CloseEvent (Event);
Event = NULL;
}
}
}
return Event;
}
// EventLibCreateNotifyTimerEvent
EFI_EVENT
EventLibCreateNotifyTimerEvent (
IN EFI_EVENT_NOTIFY NotifyFunction,
IN VOID *NotifyContext,
IN UINT64 TriggerTime,
IN BOOLEAN SignalPeriodic
)
{
DEBUG ((DEBUG_VERBOSE, "EventLibCreateNotifyTimerEvent\n"));
return EventLibCreateTimerEvent (
NotifyFunction,
NotifyContext,
TriggerTime,
SignalPeriodic,
TPL_NOTIFY
);
}
// EventLibCancelEvent
VOID
EventLibCancelEvent (
IN EFI_EVENT Event
)
{
EFI_STATUS Status;
DEBUG ((DEBUG_VERBOSE, "EventLibCancelEvent\n"));
Status = gBS->SetTimer (Event, TimerCancel, 0);
if (!EFI_ERROR (Status)) {
gBS->CloseEvent (Event);
}
}
// EventSignalEvents
VOID
EventSignalEvents (
IN APPLE_EVENT_INFORMATION *EventInformation
)
{
LIST_ENTRY *EventHandleEntry;
APPLE_EVENT_HANDLE_PRIVATE *EventHandle;
DEBUG ((DEBUG_VERBOSE, "EventSignalEvents\n"));
EventHandleEntry = GetFirstNode (&mEventHandles);
while (!IsNull (&mEventHandles, EventHandleEntry)) {
EventHandle = APPLE_EVENT_HANDLE_PRIVATE_FROM_LIST_ENTRY (
EventHandleEntry
);
if (EventHandle->Registered
&& EventHandle->Ready
&& ((EventInformation->EventType & EventHandle->EventType) != 0)
&& (EventHandle->NotifyFunction != NULL)) {
EventHandle->NotifyFunction (
EventInformation,
EventHandle->NotifyContext
);
}
EventHandleEntry = GetNextNode (&mEventHandles, EventHandleEntry);
}
}
// InternalFlagAllEventsReady
VOID
InternalFlagAllEventsReady (
VOID
)
{
LIST_ENTRY *EventHandleEntry;
APPLE_EVENT_HANDLE_PRIVATE *EventHandle;
DEBUG ((DEBUG_VERBOSE, "InternalFlagAllEventsReady\n"));
EventHandleEntry = GetFirstNode (&mEventHandles);
if (!IsListEmpty (&mEventHandles)) {
do {
EventHandle = APPLE_EVENT_HANDLE_PRIVATE_FROM_LIST_ENTRY (
EventHandleEntry
);
EventHandle->Ready = TRUE;
EventHandleEntry = GetNextNode (&mEventHandles, EventHandleEntry);
} while (!IsNull (&mEventHandles, EventHandleEntry));
}
}
// InternalSignalEvents
VOID
InternalSignalEvents (
IN APPLE_EVENT_INFORMATION *Information
)
{
LIST_ENTRY *EventHandleEntry;
APPLE_EVENT_HANDLE_PRIVATE *EventHandle;
DEBUG ((DEBUG_VERBOSE, "InternalSignalEvents\n"));
EventHandleEntry = GetFirstNode (&mEventHandles);
if (!IsListEmpty (&mEventHandles)) {
do {
EventHandle = APPLE_EVENT_HANDLE_PRIVATE_FROM_LIST_ENTRY (
EventHandleEntry
);
if (EventHandle->Registered && EventHandle->Ready
&& (EventHandle->EventType & Information->EventType)
&& EventHandle->NotifyFunction != NULL) {
EventHandle->NotifyFunction (
Information,
EventHandle->NotifyContext
);
}
EventHandleEntry = GetNextNode (&mEventHandles, EventHandleEntry);
} while (!IsNull (&mEventHandles, EventHandleEntry));
}
}
// InternalRemoveUnregisteredEvents
VOID
InternalRemoveUnregisteredEvents (
VOID
)
{
LIST_ENTRY *EventHandleEntry;
LIST_ENTRY *NextEventHandleEntry;
APPLE_EVENT_HANDLE_PRIVATE *EventHandle;
DEBUG ((DEBUG_VERBOSE, "InternalRemoveUnregisteredEvents\n"));
EventHandleEntry = GetFirstNode (&mEventHandles);
if (!IsListEmpty (&mEventHandles)) {
do {
NextEventHandleEntry = GetNextNode (&mEventHandles, EventHandleEntry);
EventHandle = APPLE_EVENT_HANDLE_PRIVATE_FROM_LIST_ENTRY (
EventHandleEntry
);
if (!EventHandle->Registered) {
if (EventHandle->Name != NULL) {
FreePool ((VOID *)EventHandle->Name);
}
RemoveEntryList (&EventHandle->Link);
FreePool ((VOID *)EventHandle);
}
EventHandleEntry = NextEventHandleEntry;
} while (!IsNull (&mEventHandles, NextEventHandleEntry));
}
}
// InternalCreatePollEvents
STATIC
EFI_STATUS
InternalCreatePollEvents (
VOID
)
{
EFI_STATUS Status;
DEBUG ((DEBUG_VERBOSE, "InternalCreatePollEvents\n"));
Status = EventCreateSimplePointerPollEvent ();
if (!EFI_ERROR (Status)) {
Status = EventCreateKeyStrokePollEvent ();
if (EFI_ERROR (Status)) {
EventCancelSimplePointerPollEvent ();
}
}
return Status;
}
// InternalCancelPollEvents
VOID
InternalCancelPollEvents (
VOID
)
{
DEBUG ((DEBUG_VERBOSE, "InternalCancelPollEvents\n"));
EventCancelSimplePointerPollEvent ();
EventCancelKeyStrokePollEvent ();
}
// EventRegisterHandler
EFI_STATUS
EFIAPI
EventRegisterHandler (
IN APPLE_EVENT_TYPE Type,
IN APPLE_EVENT_NOTIFY_FUNCTION NotifyFunction,
OUT APPLE_EVENT_HANDLE *Handle,
IN VOID *NotifyContext
)
{
EFI_STATUS Status;
APPLE_EVENT_HANDLE_PRIVATE *EventHandle;
DEBUG ((DEBUG_VERBOSE, "EventRegisterHandler\n"));
Status = EFI_INVALID_PARAMETER;
if ((Handle != NULL)
&& (NotifyFunction != NULL)
&& (Type != APPLE_EVENT_TYPE_NONE)) {
*Handle = NULL;
InternalRemoveUnregisteredEvents ();
Status = EFI_SUCCESS;
if (mNumberOfEventHandles == 0) {
Status = InternalCreatePollEvents ();
if (EFI_ERROR (Status)) {
goto Done;
}
}
EventHandle = AllocatePool (sizeof (*EventHandle));
Status = EFI_OUT_OF_RESOURCES;
if (EventHandle != NULL) {
EventHandle->Signature = APPLE_EVENT_HANDLE_PRIVATE_SIGNATURE;
EventHandle->Ready = FALSE;
EventHandle->Registered = TRUE;
EventHandle->EventType = Type;
EventHandle->NotifyFunction = NotifyFunction;
EventHandle->NotifyContext = NotifyContext;
EventHandle->Name = NULL;
++mNumberOfEventHandles;
InsertTailList (&mEventHandles, &EventHandle->Link);
*Handle = EventHandle;
Status = EFI_SUCCESS;
}
}
Done:
return Status;
}
// EventUnregisterHandler
EFI_STATUS
EFIAPI
EventUnregisterHandler (
IN APPLE_EVENT_HANDLE Handle
)
{
EFI_STATUS Status;
LIST_ENTRY *EventHandleEntry;
APPLE_EVENT_HANDLE_PRIVATE *EventHandle;
DEBUG ((DEBUG_VERBOSE, "EventUnregisterHandler\n"));
Status = EFI_INVALID_PARAMETER;
EventHandleEntry = GetFirstNode (&mEventHandles);
while (!IsNull (&mEventHandles, EventHandleEntry)) {
EventHandle = APPLE_EVENT_HANDLE_PRIVATE_FROM_LIST_ENTRY (
EventHandleEntry
);
if (((UINTN)EventHandle == (UINTN)Handle)
|| ((UINTN)Handle == (UINTN)-1)) {
EventHandle->Registered = FALSE;
--mNumberOfEventHandles;
Status = EFI_SUCCESS;
if ((UINTN)Handle != (UINTN)-1) {
break;
}
}
EventHandleEntry = GetNextNode (&mEventHandles, EventHandleEntry);
}
if (mNumberOfEventHandles == 0) {
InternalCancelPollEvents ();
}
return Status;
}
// EventSetCursorPosition
/** This function is used to change the position of the cursor on the screen.
@param[in] Position The position where to position the cursor.
@retval EFI_INVALID_PARAMETER Position is invalid.
**/
EFI_STATUS
EFIAPI
EventSetCursorPosition (
IN DIMENSION *Position
)
{
DEBUG ((DEBUG_VERBOSE, "EventSetCursorPosition\n"));
return EventSetCursorPositionImpl (Position);
}
// EventSetEventName
/** This function is used to assign a name to an event.
@param[in, out] Handle
@param[in] Name
@retval EFI_SUCCESS The event name was assigned successfully.
@retval EFI_INVALID_PARAMETER EventHandle or EventName is NULL.
@retval EFI_OUT_OF_RESOURCES There are not enough resources to allocate the
event name.
**/
EFI_STATUS
EFIAPI
EventSetEventName (
IN OUT APPLE_EVENT_HANDLE Handle,
IN CHAR8 *Name
)
{
EFI_STATUS Status;
UINTN AllocationSize;
CHAR8 *EventName;
DEBUG ((DEBUG_VERBOSE, "EventSetEventName\n"));
Status = EFI_INVALID_PARAMETER;
if ((Handle != NULL) && (Name != NULL)) {
AllocationSize = AsciiStrSize (Name);
EventName = AllocateZeroPool (AllocationSize);
((APPLE_EVENT_HANDLE_PRIVATE *)Handle)->Name = EventName;
Status = EFI_OUT_OF_RESOURCES;
if (EventName != NULL) {
AsciiStrCpyS (EventName, AllocationSize, Name);
Status = EFI_SUCCESS;
}
}
return Status;
}
// EventIsCapsLockOnImpl
/** Retrieves the state of the CapsLock key.
@param[in, out] CLockOn This parameter indicates the state of the CapsLock
key.
@retval EFI_SUCCESS The CapsLock state was successfully returned
in CLockOn.
@retval EFI_INVALID_PARAMETER CLockOn is NULL.
**/
EFI_STATUS
EFIAPI
EventIsCapsLockOn (
IN OUT BOOLEAN *CLockOn
)
{
DEBUG ((DEBUG_VERBOSE, "EventIsCapsLockOn\n"));
return EventIsCapsLockOnImpl (CLockOn);
}
// InternalUnregisterHandlers
STATIC
VOID
InternalUnregisterHandlers (
VOID
)
{
DEBUG ((DEBUG_VERBOSE, "InternalUnregisterHandlers\n"));
EventSimplePointerDesctructor ();
InternalRemoveUnregisteredEvents ();
if (!IsListEmpty (&mEventHandles)) {
EventUnregisterHandler ((APPLE_EVENT_HANDLE_PRIVATE *)((UINTN)-1));
}
}
// mAppleEventProtocol
STATIC APPLE_EVENT_PROTOCOL mAppleEventProtocol = {
APPLE_EVENT_PROTOCOL_REVISION,
EventRegisterHandler,
EventUnregisterHandler,
EventSetCursorPosition,
EventSetEventName,
EventIsCapsLockOn
};
// AppleEventUnload
EFI_STATUS
EFIAPI
AppleEventUnload (
VOID
)
{
EFI_STATUS Status;
DEBUG ((DEBUG_VERBOSE, "AppleEventUnload\n"));
EventCloseSimplePointerInstallNotifyEvent ();
InternalSignalAndCloseQueueEvent ();
InternalUnregisterHandlers ();
InternalCancelPollEvents ();
Status = gBS->UninstallProtocolInterface (
gImageHandle,
&gAppleEventProtocolGuid,
(VOID *)&mAppleEventProtocol
);
return Status;
}
/**
Install and initialise Apple Event protocol.
@param[in] Reinstall Overwrite installed protocol.
@retval installed or located protocol or NULL.
**/
APPLE_EVENT_PROTOCOL *
OcAppleEventInstallProtocol (
IN BOOLEAN Reinstall
)
{
EFI_STATUS Status;
APPLE_EVENT_PROTOCOL *Protocol;
DEBUG ((DEBUG_VERBOSE, "OcAppleEventInstallProtocol\n"));
if (Reinstall) {
Status = UninstallAllProtocolInstances (&gAppleEventProtocolGuid);
if (EFI_ERROR (Status)) {
DEBUG ((DEBUG_ERROR, "OCAE: Uninstall failed: %r\n", Status));
return NULL;
}
} else {
Status = gBS->LocateProtocol (
&gAppleEventProtocolGuid,
NULL,
(VOID *) &Protocol
);
if (!EFI_ERROR (Status)) {
return Protocol;
}
}
//
// Apple code supports unloading, ours does not.
//
Status = gBS->InstallProtocolInterface (
&gImageHandle,
&gAppleEventProtocolGuid,
EFI_NATIVE_INTERFACE,
(VOID *)&mAppleEventProtocol
);
if (!EFI_ERROR (Status)) {
InternalCreateQueueEvent ();
Status = EventCreateSimplePointerInstallNotifyEvent ();
}
if (EFI_ERROR (Status)) {
AppleEventUnload ();
return NULL;
}
return &mAppleEventProtocol;
}
/** @file
AppleEventDxe
Copyright (c) 2018, vit9696
All rights reserved.
This program and the accompanying materials
are licensed and made available under the terms and conditions of the BSD License
which accompanies this distribution. The full text of the license may be found at
http://opensource.org/licenses/bsd-license.php
THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
**/
#ifndef APPLE_EVENT_INTERNAL_H_
#define APPLE_EVENT_INTERNAL_H_
#include <IndustryStandard/AppleHid.h>
#include <Protocol/AppleEvent.h>
// EventCreateKeyStrokePollEvent
EFI_STATUS
EventCreateKeyStrokePollEvent (
VOID
);
// EventCancelKeyStrokePollEvent
VOID
EventCancelKeyStrokePollEvent (
VOID
);
// EventIsCapsLockOnImpl
/** Retrieves the state of the CapsLock key.
@param[in, out] CLockOn This parameter indicates the state of the CapsLock
key.
@retval EFI_SUCCESS The CapsLock state was successfully returned
in CLockOn.
@retval EFI_INVALID_PARAMETER CLockOn is NULL.
**/
EFI_STATUS
EFIAPI
EventIsCapsLockOnImpl (
IN OUT BOOLEAN *CLockOn
);
// EventCreateSimplePointerInstallNotifyEvent
EFI_STATUS
EventCreateSimplePointerInstallNotifyEvent (
VOID
);
// EventCreateSimplePointerInstallNotifyEvent
VOID
EventCloseSimplePointerInstallNotifyEvent (
VOID
);
// EventCancelSimplePointerPollEvent
VOID
EventCancelSimplePointerPollEvent (
VOID
);
// EventCreateSimplePointerPollEvent
EFI_STATUS
EventCreateSimplePointerPollEvent (
VOID
);
// EventSimplePointerDesctructor
VOID
EventSimplePointerDesctructor (
VOID
);
// EventCreateAppleEventQueueInfo
APPLE_EVENT_INFORMATION *
EventCreateAppleEventQueueInfo (
IN APPLE_EVENT_DATA EventData,
IN APPLE_EVENT_TYPE EventType,
IN DIMENSION *PointerPosition,
IN APPLE_MODIFIER_MAP Modifiers
);
// EventAddEventToQueue
VOID
EventAddEventToQueue (
IN APPLE_EVENT_INFORMATION *Information
);
// EventCreateEventQueue
EFI_STATUS
EventCreateEventQueue (
IN APPLE_EVENT_DATA EventData,
IN APPLE_EVENT_TYPE EventType,
IN APPLE_MODIFIER_MAP Modifiers
);
// InternalSignalAndCloseQueueEvent
VOID
InternalSignalAndCloseQueueEvent (
VOID
);
// EventSetCursorPositionImpl
EFI_STATUS
EventSetCursorPositionImpl (
IN DIMENSION *Position
);
// InternalCreateQueueEvent
VOID
InternalCreateQueueEvent (
VOID
);
// InternalFlagAllEventsReady
VOID
InternalFlagAllEventsReady (
VOID
);
// InternalSignalEvents
VOID
InternalSignalEvents (
IN APPLE_EVENT_INFORMATION *Information
);
// InternalRemoveUnregisteredEvents
VOID
InternalRemoveUnregisteredEvents (
VOID
);
// InternalGetModifierStrokes
APPLE_MODIFIER_MAP
InternalGetModifierStrokes (
VOID
);
// EventInputKeyFromAppleKeyCode
VOID
EventInputKeyFromAppleKeyCode (
IN APPLE_KEY_CODE AppleKeyCode,
OUT EFI_INPUT_KEY *InputKey,
IN BOOLEAN Shifted
);
#endif // APPLE_EVENT_INTERNAL_H_
/** @file
AppleEventDxe
Copyright (c) 2018, vit9696
All rights reserved.
This program and the accompanying materials
are licensed and made available under the terms and conditions of the BSD License
which accompanies this distribution. The full text of the license may be found at
http://opensource.org/licenses/bsd-license.php
THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
**/
#include <AppleMacEfi.h>
#include <Library/DebugLib.h>
#include "AppleEventInternal.h"
// APPLE_KEY_DESCRIPTOR
typedef struct {
APPLE_KEY_CODE AppleKeyCode;
EFI_INPUT_KEY InputKey;
EFI_INPUT_KEY ShiftedInputKey;
} APPLE_KEY_DESCRIPTOR;
// gAppleHidUsbKbUsageKeyMap
/// The default United States key map for Apple keyboards.
STATIC APPLE_KEY_DESCRIPTOR mAppleKeyMap[] = {
{
AppleHidUsbKbUsageKeyA,
{ SCAN_NULL, L'a' },
{ SCAN_NULL, L'A' }
},
{
AppleHidUsbKbUsageKeyB,
{ SCAN_NULL, L'b' },
{ SCAN_NULL, L'B' }
},
{
AppleHidUsbKbUsageKeyC,
{ SCAN_NULL, L'c' },
{ SCAN_NULL, L'C' }
},
{
AppleHidUsbKbUsageKeyD,
{ SCAN_NULL, L'd' },
{ SCAN_NULL, L'D' }
},
{
AppleHidUsbKbUsageKeyE,
{ SCAN_NULL, L'e' },
{ SCAN_NULL, L'E' }
},
{
AppleHidUsbKbUsageKeyF,
{ SCAN_NULL, L'f' },
{ SCAN_NULL, L'F' }
},
{
AppleHidUsbKbUsageKeyG,
{ SCAN_NULL, L'g' },
{ SCAN_NULL, L'G' }
},
{
AppleHidUsbKbUsageKeyH,
{ SCAN_NULL, L'h' },
{ SCAN_NULL, L'H' }
},
{
AppleHidUsbKbUsageKeyI,
{ SCAN_NULL, L'i' },
{ SCAN_NULL, L'I' }
},
{
AppleHidUsbKbUsageKeyJ,
{ SCAN_NULL, L'j' },
{ SCAN_NULL, L'J' }
},
{
AppleHidUsbKbUsageKeyK,
{ SCAN_NULL, L'k' },
{ SCAN_NULL, L'K' }
},
{
AppleHidUsbKbUsageKeyL,
{ SCAN_NULL, L'l' },
{ SCAN_NULL, L'L' }
},
{
AppleHidUsbKbUsageKeyM,
{ SCAN_NULL, L'm' },
{ SCAN_NULL, L'M' }
},
{
AppleHidUsbKbUsageKeyN,
{ SCAN_NULL, L'n' },
{ SCAN_NULL, L'N' }
},
{
AppleHidUsbKbUsageKeyO,
{ SCAN_NULL, L'o' },
{ SCAN_NULL, L'O' }
},
{
AppleHidUsbKbUsageKeyP,
{ SCAN_NULL, L'p' },
{ SCAN_NULL, L'P' }
},
{
AppleHidUsbKbUsageKeyQ,
{ SCAN_NULL, L'q' },
{ SCAN_NULL, L'Q' }
},
{
AppleHidUsbKbUsageKeyR,
{ SCAN_NULL, L'r' },
{ SCAN_NULL, L'R' }
},
{
AppleHidUsbKbUsageKeyS,
{ SCAN_NULL, L's' },
{ SCAN_NULL, L'S' }
},
{
AppleHidUsbKbUsageKeyT,
{ SCAN_NULL, L't' },
{ SCAN_NULL, L'T' }
},
{
AppleHidUsbKbUsageKeyU,
{ SCAN_NULL, L'u' },
{ SCAN_NULL, L'U' }
},
{
AppleHidUsbKbUsageKeyV,
{ SCAN_NULL, L'v' },
{ SCAN_NULL, L'V' }
},
{
AppleHidUsbKbUsageKeyW,
{ SCAN_NULL, L'w' },
{ SCAN_NULL, L'W' }
},
{
AppleHidUsbKbUsageKeyX,
{ SCAN_NULL, L'x' },
{ SCAN_NULL, L'X' }
},
{
AppleHidUsbKbUsageKeyY,
{ SCAN_NULL, L'y' },
{ SCAN_NULL, L'Y' }
},
{
AppleHidUsbKbUsageKeyZ,
{ SCAN_NULL, L'z' },
{ SCAN_NULL, L'Z' }
},
{
AppleHidUsbKbUsageKeyOne,
{ SCAN_NULL, L'1' },
{ SCAN_NULL, L'!' }
},
{
AppleHidUsbKbUsageKeyTwo,
{ SCAN_NULL, L'2' },
{ SCAN_NULL, L'@' }
},
{
AppleHidUsbKbUsageKeyThree,
{ SCAN_NULL, L'3' },
{ SCAN_NULL, L'#' }
},
{
AppleHidUsbKbUsageKeyFour,
{ SCAN_NULL, L'4' },
{ SCAN_NULL, L'$' }
},
{
AppleHidUsbKbUsageKeyFive,
{ SCAN_NULL, L'5' },
{ SCAN_NULL, L'%' }
},
{
AppleHidUsbKbUsageKeySix,
{ SCAN_NULL, L'6' },
{ SCAN_NULL, L'^' }
},
{
AppleHidUsbKbUsageKeySeven,
{ SCAN_NULL, L'7' },
{ SCAN_NULL, L'&' }
},
{
AppleHidUsbKbUsageKeyEight,
{ SCAN_NULL, L'8' },
{ SCAN_NULL, L'*' }
},
{
AppleHidUsbKbUsageKeyNine,
{ SCAN_NULL, L'9' },
{ SCAN_NULL, L'(' }
},
{
AppleHidUsbKbUsageKeyZero,
{ SCAN_NULL, L'0' },
{ SCAN_NULL, L')' }
},
{
AppleHidUsbKbUsageKeyEnter,
{ SCAN_NULL, CHAR_CARRIAGE_RETURN },
{ SCAN_NULL, CHAR_CARRIAGE_RETURN }
},
{
AppleHidUsbKbUsageKeyEscape,
{ SCAN_ESC, CHAR_NULL },
{ SCAN_ESC, CHAR_NULL }
},
{
AppleHidUsbKbUsageKeyBackSpace,
{ SCAN_NULL, CHAR_BACKSPACE },
{ SCAN_NULL, CHAR_BACKSPACE }
},
{
AppleHidUsbKbUsageKeyTab,
{ SCAN_NULL, CHAR_TAB },
{ SCAN_NULL, CHAR_TAB }
},
{
AppleHidUsbKbUsageKeySpaceBar,
{ SCAN_NULL, L' ' },
{ SCAN_NULL, L' ' }
},
{
AppleHidUsbKbUsageKeyMinus,
{ SCAN_NULL, L'-' },
{ SCAN_NULL, L'_' }
},
{
AppleHidUsbKbUsageKeyEquals,
{ SCAN_NULL, L'=' },
{ SCAN_NULL, L'+' }
},
{
AppleHidUsbKbUsageKeyLeftBracket,
{ SCAN_NULL, L'[' },
{ SCAN_NULL, L'{' }
},
{
AppleHidUsbKbUsageKeyRightBracket,
{ SCAN_NULL, L']' },
{ SCAN_NULL, L'}' }
},
{
AppleHidUsbKbUsageKeyBackslash,
{ SCAN_NULL, L'\\' },
{ SCAN_NULL, L'|' }
},
{
AppleHidUsbKbUsageKeySemicolon,
{ SCAN_NULL, L';' },
{ SCAN_NULL, L':' }
},
{
AppleHidUsbKbUsageKeyQuotation,
{ SCAN_NULL, L'\'' },
{ SCAN_NULL, L'"' }
},
{
AppleHidUsbKbUsageKeyAcute,
{ SCAN_NULL, L'`' },
{ SCAN_NULL, L'~' }
},
{
AppleHidUsbKbUsageKeyComma,
{ SCAN_NULL, L',' },
{ SCAN_NULL, L'<' }
},
{
AppleHidUsbKbUsageKeyPeriod,
{ SCAN_NULL, L'.' },
{ SCAN_NULL, L'>' }
},
{
AppleHidUsbKbUsageKeySlash,
{ SCAN_NULL, L'/' },
{ SCAN_NULL, L'?' }
},
// BUG: AppleHidUsbKbUsageKeyCLock is missing.
{
AppleHidUsbKbUsageKeyF1,
{ SCAN_F1, CHAR_NULL },
{ SCAN_F1, CHAR_NULL }
},
{
AppleHidUsbKbUsageKeyF2,
{ SCAN_F2, CHAR_NULL },
{ SCAN_F2, CHAR_NULL }
},
{
AppleHidUsbKbUsageKeyF3,
{ SCAN_F3, CHAR_NULL },
{ SCAN_F3, CHAR_NULL }
},
{
AppleHidUsbKbUsageKeyF4,
{ SCAN_F4, CHAR_NULL },
{ SCAN_F4, CHAR_NULL }
},
{
AppleHidUsbKbUsageKeyF5,
{ SCAN_F5, CHAR_NULL },
{ SCAN_F5, CHAR_NULL }
},
{
AppleHidUsbKbUsageKeyF6,
{ SCAN_F6, CHAR_NULL },
{ SCAN_F6, CHAR_NULL }
},
{
AppleHidUsbKbUsageKeyF7,
{ SCAN_F7, CHAR_NULL },
{ SCAN_F7, CHAR_NULL }
},
{
AppleHidUsbKbUsageKeyF8,
{ SCAN_F8, CHAR_NULL },
{ SCAN_F8, CHAR_NULL }
},
{
AppleHidUsbKbUsageKeyF9,
{ SCAN_F9, CHAR_NULL },
{ SCAN_F9, CHAR_NULL }
},
{
AppleHidUsbKbUsageKeyF10,
{ SCAN_F10, CHAR_NULL },
{ SCAN_F10, CHAR_NULL }
},
{
AppleHidUsbKbUsageKeyF11,
{ SCAN_F11, CHAR_NULL },
{ SCAN_F11, CHAR_NULL }
},
{
AppleHidUsbKbUsageKeyF12,
{ SCAN_F12, CHAR_NULL },
{ SCAN_F12, CHAR_NULL }
},
// BUG: AppleHidUsbKbUsageKeyPrint, AppleHidUsbKbUsageKeySLock, AppleHidUsbKbUsageKeyPause missing.
{
AppleHidUsbKbUsageKeyIns,
{ SCAN_INSERT, CHAR_NULL },
{ SCAN_INSERT, CHAR_NULL }
},
{
AppleHidUsbKbUsageKeyHome,
{ SCAN_HOME, CHAR_NULL },
{ SCAN_HOME, CHAR_NULL }
},
{
AppleHidUsbKbUsageKeyPgUp,
{ SCAN_PAGE_UP, CHAR_NULL },
{ SCAN_PAGE_UP, CHAR_NULL }
},
{
AppleHidUsbKbUsageKeyDel,
{ SCAN_DELETE, CHAR_NULL },
{ SCAN_DELETE, CHAR_NULL }
},
{
AppleHidUsbKbUsageKeyEnd,
{ SCAN_END, CHAR_NULL },
{ SCAN_END, CHAR_NULL }
},
{
AppleHidUsbKbUsageKeyPgDn,
{ SCAN_PAGE_DOWN, CHAR_NULL },
{ SCAN_PAGE_DOWN, CHAR_NULL }
},
{
AppleHidUsbKbUsageKeyRightArrow,
{ SCAN_RIGHT, CHAR_NULL },
{ SCAN_RIGHT, CHAR_NULL }
},
{
AppleHidUsbKbUsageKeyLeftArrow,
{ SCAN_LEFT, CHAR_NULL },
{ SCAN_LEFT, CHAR_NULL }
},
{
AppleHidUsbKbUsageKeyDownArrow,
{ SCAN_DOWN, CHAR_NULL },
{ SCAN_DOWN, CHAR_NULL }
},
{
AppleHidUsbKbUsageKeyUpArrow,
{ SCAN_UP, CHAR_NULL },
{ SCAN_UP, CHAR_NULL }
},
// BUG: UsbHidUsageIdKbKpPadKeyNLck is missing.
{
AppleHidUsbKbUsageKeyPadSlash,
{ AppleScanKeypadSlash, L'/' },
{ AppleScanKeypadSlash, L'/' }
},
{
AppleHidUsbKbUsageKeyPadAsterisk,
{ AppleScanKeypadAsterisk, L'*' },
{ AppleScanKeypadAsterisk, L'*' }
},
{
AppleHidUsbKbUsageKeyPadMinus,
{ AppleScanKeypadMinus, L'-' },
{ AppleScanKeypadMinus, L'-' }
},
{
AppleHidUsbKbUsageKeyPadPlus,
{ AppleScanKeypadPlus, L'+' },
{ AppleScanKeypadPlus, L'+' }
},
{
AppleHidUsbKbUsageKeyPadEnter,
{ AppleScanKeypadEnter, CHAR_CARRIAGE_RETURN },
{ AppleScanKeypadEnter, CHAR_CARRIAGE_RETURN }
},
{
AppleHidUsbKbUsageKeyPadOne,
{ AppleScanKeypadOne, L'1' },
{ AppleScanKeypadOne, L'1' }
},
{
AppleHidUsbKbUsageKeyPadTwo,
{ AppleScanKeypadTwo, L'2' },
{ AppleScanKeypadTwo, L'2' }
},
{
AppleHidUsbKbUsageKeyPadThree,
{ AppleScanKeypadThree, L'3' },
{ AppleScanKeypadThree, L'3' }
},
{
AppleHidUsbKbUsageKeyPadFour,
{ AppleScanKeypadFour, L'4' },
{ AppleScanKeypadFour, L'4' }
},
{
AppleHidUsbKbUsageKeyPadFive,
{ AppleScanKeypadFive, L'5' },
{ AppleScanKeypadFive, L'5' }
},
{
AppleHidUsbKbUsageKeyPadSix,
{ AppleScanKeypadSix, L'6' },
{ AppleScanKeypadSix, L'6' }
},
{
AppleHidUsbKbUsageKeyPadSeven,
{ AppleScanKeypadSeven, L'7' },
{ AppleScanKeypadSeven, L'7' }
},
{
AppleHidUsbKbUsageKeyPadEight,
{ AppleScanKeypadEight, L'8' },
{ AppleScanKeypadEight, L'8' }
},
{
AppleHidUsbKbUsageKeyPadNine,
{ AppleScanKeypadNine, L'9' },
{ AppleScanKeypadNine, L'9' }
},
{
AppleHidUsbKbUsageKeyPadIns,
{ AppleScanKeypadIns, L'0' },
{ AppleScanKeypadIns, L'0' }
},
{
AppleHidUsbKbUsageKeyPadDel,
{ AppleScanKeypadDel, L'.' },
{ AppleScanKeypadDel, L'.' }
},
{
AppleHidUsbKbUsageKeyPadEquals,
{ AppleScanKeypadEquals, L'=' },
{ AppleScanKeypadEquals, L'=' }
}
};
// EventInputKeyFromAppleKeyCode
VOID
EventInputKeyFromAppleKeyCode (
IN APPLE_KEY_CODE AppleKeyCode,
OUT EFI_INPUT_KEY *InputKey,
IN BOOLEAN Shifted
)
{
UINTN Index;
APPLE_KEY_DESCRIPTOR *Key;
DEBUG ((DEBUG_VERBOSE, "EventInputKeyFromAppleKeyCode\n"));
Key = &mAppleKeyMap[0];
for (Index = 0; Index < ARRAY_SIZE (mAppleKeyMap); ++Index) {
if (Key->AppleKeyCode == AppleKeyCode) {
*InputKey = (Shifted ? Key->ShiftedInputKey : Key->InputKey);
return;
}
++Key;
}
InputKey->ScanCode = SCAN_NULL;
InputKey->UnicodeChar = CHAR_NULL;
}
/** @file
AppleEventDxe
Copyright (c) 2018, vit9696
All rights reserved.
This program and the accompanying materials
are licensed and made available under the terms and conditions of the BSD License
which accompanies this distribution. The full text of the license may be found at
http://opensource.org/licenses/bsd-license.php
THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
**/
#include <AppleMacEfi.h>
#include <Library/BaseLib.h>
#include <Library/BaseMemoryLib.h>
#include <Library/DebugLib.h>
#include <Library/MemoryAllocationLib.h>
#include <Library/UefiBootServicesTableLib.h>
#include <Library/UefiLib.h>
#include <Library/UefiRuntimeServicesTableLib.h>
#include "AppleEventInternal.h"
// APPLE_EVENT_QUEUE_SIGNATURE
#define APPLE_EVENT_QUEUE_SIGNATURE SIGNATURE_32 ('A', 'E', 'v', 'Q')
// APPLE_EVENT_QUEUE_FROM_LIST_ENTRY
#define APPLE_EVENT_QUEUE_FROM_LIST_ENTRY(ListEntry) \
CR ((ListEntry), APPLE_EVENT_QUEUE, Link, APPLE_EVENT_QUEUE_SIGNATURE)
// APPLE_EVENT_QUEUE
typedef struct {
UINT32 Signature; ///<
LIST_ENTRY Link; ///<
APPLE_EVENT_INFORMATION *Information; ///<
} APPLE_EVENT_QUEUE;
// mQueueEvent
STATIC EFI_EVENT mQueueEvent = NULL;
// mQueueEventCreated
STATIC BOOLEAN mQueueEventCreated = FALSE;
// mEventQueueList
STATIC LIST_ENTRY mQueue = INITIALIZE_LIST_HEAD_VARIABLE (mQueue);
// mQueueLock
STATIC EFI_LOCK mQueueLock = {
0,
0,
FALSE
};
// InternalSignalAndCloseQueueEvent
VOID
InternalSignalAndCloseQueueEvent (
VOID
)
{
DEBUG ((DEBUG_VERBOSE, "InternalSignalAndCloseQueueEvent\n"));
gBS->SignalEvent (mQueueEvent);
if (mQueueEventCreated && (mQueueEvent != NULL)) {
gBS->CloseEvent (mQueueEvent);
}
}
// InternalQueueEventNotifyFunction
STATIC
VOID
EFIAPI
InternalQueueEventNotifyFunction (
IN EFI_EVENT Event,
IN VOID *Context
)
{
EFI_STATUS Status;
LIST_ENTRY *EventQueueEntry;
APPLE_EVENT_QUEUE *EventQueue;
DEBUG ((DEBUG_VERBOSE, "InternalQueueEventNotifyFunction\n"));
if (mQueueEventCreated) {
do {
Status = EfiAcquireLockOrFail (&mQueueLock);
} while (EFI_ERROR (Status));
InternalFlagAllEventsReady ();
EventQueueEntry = GetFirstNode (&mQueue);
while (!IsNull (&mQueue, EventQueueEntry)) {
EventQueue = APPLE_EVENT_QUEUE_FROM_LIST_ENTRY (EventQueueEntry);
InternalSignalEvents (EventQueue->Information);
if (((EventQueue->Information->EventType & APPLE_ALL_KEYBOARD_EVENTS) != 0)
&& (EventQueue->Information->EventData.KeyData != NULL)) {
FreePool (
(VOID *)EventQueue->Information->EventData.KeyData
);
}
EventQueueEntry = RemoveEntryList (EventQueueEntry);
FreePool ((VOID *)EventQueue->Information);
FreePool ((VOID *)EventQueue);
}
InternalRemoveUnregisteredEvents ();
EfiReleaseLock (&mQueueLock);
}
}
// InternalCreateQueueEvent
VOID
InternalCreateQueueEvent (
VOID
)
{
EFI_STATUS Status;
DEBUG ((DEBUG_VERBOSE, "InternalCreateQueueEvent\n"));
EfiInitializeLock (&mQueueLock, TPL_NOTIFY);
Status = gBS->CreateEvent (
EVT_NOTIFY_SIGNAL,
TPL_NOTIFY,
InternalQueueEventNotifyFunction,
NULL,
&mQueueEvent
);
if (!EFI_ERROR (Status)) {
mQueueEventCreated = TRUE;
}
}
// EventCreateAppleEventQueueInfo
APPLE_EVENT_INFORMATION *
EventCreateAppleEventQueueInfo (
IN APPLE_EVENT_DATA EventData,
IN APPLE_EVENT_TYPE EventType,
IN DIMENSION *PointerPosition,
IN APPLE_MODIFIER_MAP Modifiers
)
{
APPLE_EVENT_INFORMATION *QueueInfo;
EFI_TIME CreationTime;
DEBUG ((DEBUG_VERBOSE, "EventCreateAppleEventQueueInfo\n"));
QueueInfo = AllocateZeroPool (sizeof (*QueueInfo));
if (QueueInfo != NULL) {
gRT->GetTime (&CreationTime, NULL);
QueueInfo->EventType = EventType;
QueueInfo->EventData = EventData;
QueueInfo->Modifiers = Modifiers;
QueueInfo->CreationTime.Year = CreationTime.Year;
QueueInfo->CreationTime.Month = CreationTime.Month;
QueueInfo->CreationTime.Day = CreationTime.Day;
QueueInfo->CreationTime.Hour = CreationTime.Hour;
QueueInfo->CreationTime.Minute = CreationTime.Minute;
QueueInfo->CreationTime.Second = CreationTime.Second;
QueueInfo->CreationTime.Pad1 = CreationTime.Pad1;
if (PointerPosition != NULL) {
CopyMem (
(VOID *)&QueueInfo->PointerPosition,
(VOID *)PointerPosition,
sizeof (*PointerPosition)
);
}
} else {
DEBUG ((DEBUG_VERBOSE, "EventCreateAppleEventQueueInfo alloc failure\n"));
}
return QueueInfo;
}
// EventAddEventToQueue
VOID
EventAddEventToQueue (
IN APPLE_EVENT_INFORMATION *Information
)
{
EFI_STATUS Status;
APPLE_EVENT_QUEUE *EventQueue;
DEBUG ((DEBUG_VERBOSE, "EventAddEventToQueue\n"));
if (mQueueEventCreated) {
do {
Status = EfiAcquireLockOrFail (&mQueueLock);
} while (EFI_ERROR (Status));
EventQueue = AllocateZeroPool (sizeof (*EventQueue));
if (EventQueue != NULL) {
EventQueue->Signature = APPLE_EVENT_QUEUE_SIGNATURE;
EventQueue->Information = Information;
InsertTailList (&mQueue, &EventQueue->Link);
} else {
DEBUG ((DEBUG_VERBOSE, "EventAddEventToQueue alloc failure\n"));
}
EfiReleaseLock (&mQueueLock);
gBS->SignalEvent (mQueueEvent);
}
}
// EventCreateEventQueue
EFI_STATUS
EventCreateEventQueue (
IN APPLE_EVENT_DATA EventData,
IN APPLE_EVENT_TYPE EventType,
IN APPLE_MODIFIER_MAP Modifiers
)
{
EFI_STATUS Status;
APPLE_EVENT_INFORMATION *Information;
DEBUG ((DEBUG_VERBOSE, "EventCreateEventQueue\n"));
Status = EFI_INVALID_PARAMETER;
if (EventData.Raw != 0 || Modifiers != 0) {
Information = EventCreateAppleEventQueueInfo (
EventData,
EventType,
NULL,
Modifiers
);
Status = EFI_OUT_OF_RESOURCES;
if (Information != NULL) {
EventAddEventToQueue (Information);
Status = EFI_SUCCESS;
} else {
DEBUG ((DEBUG_VERBOSE, "EventCreateEventQueue alloc failure\n"));
}
}
return Status;
}
/** @file
AppleEventDxe
Copyright (c) 2018, vit9696
All rights reserved.
This program and the accompanying materials
are licensed and made available under the terms and conditions of the BSD License
which accompanies this distribution. The full text of the license may be found at
http://opensource.org/licenses/bsd-license.php
THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
**/
#include <AppleMacEfi.h>
#include <IndustryStandard/AppleHid.h>
#include <Protocol/AppleKeyMapAggregator.h>
#include <Protocol/ConsoleControl.h>
#include <Library/AppleEventLib.h>
#include <Library/BaseMemoryLib.h>
#include <Library/DebugLib.h>
#include <Library/MemoryAllocationLib.h>
#include <Library/UefiBootServicesTableLib.h>
#include <Library/UefiLib.h>
#include "AppleEventInternal.h"
// KEY_STROKE_DELAY
#define KEY_STROKE_DELAY 5
// KEY_STROKE_POLL_FREQUENCY
#define KEY_STROKE_POLL_FREQUENCY EFI_TIMER_PERIOD_MILLISECONDS (10)
// KEY_STROKE_INFORMATION
typedef struct {
APPLE_KEY_CODE AppleKeyCode; ///<
UINTN NumberOfStrokes; ///<
BOOLEAN CurrentStroke; ///<
} KEY_STROKE_INFORMATION;
// mCLockOn
STATIC BOOLEAN mCLockOn = FALSE;
// mKeyStrokePollEvent
STATIC EFI_EVENT mKeyStrokePollEvent = NULL;
// mModifiers
STATIC APPLE_MODIFIER_MAP mModifiers = 0;
// mPreviousModifiers
STATIC APPLE_MODIFIER_MAP mPreviousModifiers = 0;
// mInitialized
STATIC BOOLEAN mInitialized = FALSE;
// mKeyInformation
STATIC KEY_STROKE_INFORMATION mKeyStrokeInfo[10];
// mCLockChanged
STATIC BOOLEAN mCLockChanged = FALSE;
// mAppleKeyMapAggregator
STATIC APPLE_KEY_MAP_AGGREGATOR_PROTOCOL *mKeyMapAggregator = NULL;
// InternalGetAppleKeyStrokes
STATIC
EFI_STATUS
InternalGetAppleKeyStrokes (
OUT APPLE_MODIFIER_MAP *Modifiers,
OUT UINTN *NumberOfKeyCodes,
OUT APPLE_KEY_CODE **KeyCodes
)
{
EFI_STATUS Status;
DEBUG ((DEBUG_VERBOSE, "InternalGetAppleKeyStrokes\n"));
Status = EFI_UNSUPPORTED;
if (mKeyMapAggregator != NULL) {
Status = EFI_INVALID_PARAMETER;
if ((Modifiers != NULL)
&& (NumberOfKeyCodes != NULL)
&& (KeyCodes != NULL)) {
*NumberOfKeyCodes = 0;
*KeyCodes = NULL;
Status = mKeyMapAggregator->GetKeyStrokes (
mKeyMapAggregator,
Modifiers,
NumberOfKeyCodes,
NULL
);
if (!EFI_ERROR (Status) || Status == EFI_BUFFER_TOO_SMALL) {
if (*NumberOfKeyCodes == 0) {
*KeyCodes = NULL;
} else {
*KeyCodes = AllocateZeroPool (
*NumberOfKeyCodes * sizeof (**KeyCodes)
);
if (*KeyCodes == NULL) {
*NumberOfKeyCodes = 0;
Status = EFI_OUT_OF_RESOURCES;
DEBUG ((DEBUG_VERBOSE, "InternalGetAppleKeyStrokes alloc failure\n"));
} else {
Status = mKeyMapAggregator->GetKeyStrokes (
mKeyMapAggregator,
Modifiers,
NumberOfKeyCodes,
*KeyCodes
);
if (EFI_ERROR (Status)) {
FreePool ((VOID *)*KeyCodes);
*KeyCodes = NULL;
*NumberOfKeyCodes = 0;
}
}
}
}
}
}
return Status;
}
// InternalGetModifierStrokes
APPLE_MODIFIER_MAP
InternalGetModifierStrokes (
VOID
)
{
APPLE_MODIFIER_MAP Modifiers;
EFI_STATUS Status;
UINTN NumberOfKeyCodes;
APPLE_KEY_CODE *KeyCodes;
DEBUG ((DEBUG_VERBOSE, "InternalGetModifierStrokes\n"));
Status = InternalGetAppleKeyStrokes (
&Modifiers,
&NumberOfKeyCodes,
&KeyCodes
);
if (!EFI_ERROR (Status)) {
if (KeyCodes != NULL) {
FreePool ((VOID *)KeyCodes);
}
} else {
Modifiers = 0;
}
return Modifiers;
}
// InternalAppleKeyEventDataFromInputKey
STATIC
EFI_STATUS
InternalAppleKeyEventDataFromInputKey (
OUT APPLE_EVENT_DATA *EventData,
IN APPLE_KEY_CODE *AppleKeyCode,
IN EFI_INPUT_KEY *InputKey
)
{
EFI_STATUS Status;
APPLE_KEY_EVENT_DATA *KeyEventData;
DEBUG ((DEBUG_VERBOSE, "InternalAppleKeyEventDataFromInputKey\n"));
Status = EFI_INVALID_PARAMETER;
if ((EventData != NULL) && (AppleKeyCode != NULL) && (InputKey != NULL)) {
KeyEventData = AllocateZeroPool (sizeof (*KeyEventData));
Status = EFI_OUT_OF_RESOURCES;
if (KeyEventData != NULL) {
KeyEventData->NumberOfKeyPairs = 1;
KeyEventData->InputKey = *InputKey;
CopyMem (
(VOID *)&KeyEventData->AppleKeyCode,
(VOID *)AppleKeyCode,
sizeof (*AppleKeyCode)
);
EventData->KeyData = KeyEventData;
Status = EFI_SUCCESS;
}
}
return Status;
}
// InternalGetAndRemoveReleasedKeys
STATIC
UINTN
InternalGetAndRemoveReleasedKeys (
IN CONST UINTN *NumberOfKeyCodes,
IN CONST APPLE_KEY_CODE *KeyCodes,
OUT APPLE_KEY_CODE **ReleasedKeys
)
{
UINTN NumberOfReleasedKeys;
UINTN Index;
UINTN Index2;
APPLE_KEY_CODE ReleasedKeysBuffer[12];
UINTN ReleasedKeysSize;
DEBUG ((DEBUG_VERBOSE, "InternalGetAndRemoveReleasedKeys\n"));
NumberOfReleasedKeys = 0;
for (Index = 0; Index < ARRAY_SIZE (mKeyStrokeInfo); ++Index) {
for (Index2 = 0; Index2 < *NumberOfKeyCodes; ++Index2) {
if (mKeyStrokeInfo[Index].AppleKeyCode == KeyCodes[Index2]) {
break;
}
}
if (*NumberOfKeyCodes == Index2) {
if (mKeyStrokeInfo[Index].AppleKeyCode != 0) {
ReleasedKeysBuffer[NumberOfReleasedKeys] = mKeyStrokeInfo[Index].AppleKeyCode;
++NumberOfReleasedKeys;
}
ZeroMem (
&mKeyStrokeInfo[Index],
sizeof (mKeyStrokeInfo[Index])
);
}
}
// Add CLock to released keys if applicable and set bool to FALSE.
if (mCLockChanged) {
for (Index = 0; Index < *NumberOfKeyCodes; ++Index) {
if (KeyCodes[Index] == AppleHidUsbKbUsageKeyCLock) {
break;
}
}
if (*NumberOfKeyCodes == Index) {
mCLockChanged = FALSE;
ReleasedKeysBuffer[NumberOfReleasedKeys] = AppleHidUsbKbUsageKeyCLock;
++NumberOfReleasedKeys;
}
}
// Allocate a heap buffer to return.
*ReleasedKeys = NULL;
if (NumberOfReleasedKeys > 0) {
ReleasedKeysSize = (sizeof (**ReleasedKeys) * NumberOfReleasedKeys);
*ReleasedKeys = AllocateZeroPool (ReleasedKeysSize);
if (*ReleasedKeys != NULL) {
CopyMem (
(VOID *)*ReleasedKeys,
(VOID *)&ReleasedKeysBuffer[0],
ReleasedKeysSize
);
} else {
NumberOfReleasedKeys = 0;
}
}
return NumberOfReleasedKeys;
}
// InternalIsCLockOn
STATIC
BOOLEAN
InternalIsCLockOn (
IN CONST UINTN *NumberOfKeyCodes,
IN CONST APPLE_KEY_CODE *KeyCodes
)
{
BOOLEAN CLockOn;
UINTN Index;
UINTN Index2;
KEY_STROKE_INFORMATION *KeyInfo;
DEBUG ((DEBUG_VERBOSE, "InternalIsCLockOn\n"));
//
// Check against invalid usage
//
if (NumberOfKeyCodes == NULL
|| (*NumberOfKeyCodes != 0 && KeyCodes == NULL)) {
return FALSE;
}
//
// Return the previous value by default
//
CLockOn = mCLockOn;
for (Index = 0; Index < *NumberOfKeyCodes; ++Index) {
KeyInfo = NULL;
for (Index2 = 0; Index2 < ARRAY_SIZE (mKeyStrokeInfo); ++Index2) {
if (mKeyStrokeInfo[Index2].AppleKeyCode == KeyCodes[Index]) {
KeyInfo = &mKeyStrokeInfo[Index2];
break;
}
}
if (KeyInfo == NULL
&& KeyCodes[Index] == AppleHidUsbKbUsageKeyCLock
&& !mCLockChanged) {
CLockOn = (BOOLEAN) mCLockOn == FALSE;
break;
}
}
return CLockOn;
}
// InternalGetCurrentStroke
STATIC
KEY_STROKE_INFORMATION *
InternalGetCurrentStroke (
VOID
)
{
KEY_STROKE_INFORMATION *KeyInfo;
UINTN Index;
DEBUG ((DEBUG_VERBOSE, "InternalGetCurrentStroke\n"));
KeyInfo = NULL;
for (Index = 0; Index < ARRAY_SIZE (mKeyStrokeInfo); ++Index) {
if (mKeyStrokeInfo[Index].CurrentStroke) {
KeyInfo = &mKeyStrokeInfo[Index];
break;
}
}
return KeyInfo;
}
// InternalGetCurrentKeyStroke
STATIC
EFI_STATUS
InternalGetCurrentKeyStroke (
IN APPLE_MODIFIER_MAP Modifiers,
IN OUT UINTN *NumberOfKeyCodes,
IN OUT APPLE_KEY_CODE *KeyCodes,
IN OUT EFI_INPUT_KEY *Key
)
{
EFI_STATUS Status;
KEY_STROKE_INFORMATION *KeyInfo;
UINTN Index;
UINTN NumberOfReleasedKeys;
APPLE_KEY_CODE *ReleasedKeys;
BOOLEAN CLockOn;
APPLE_MODIFIER_MAP AppleModifiers;
BOOLEAN ShiftPressed;
EFI_INPUT_KEY InputKey;
APPLE_EVENT_DATA AppleEventData;
UINTN NewKeyIndex;
BOOLEAN AcceptStroke;
BOOLEAN Shifted;
DEBUG ((DEBUG_VERBOSE, "InternalGetCurrentKeyStroke\n"));
if (mModifiers != Modifiers) {
for (Index = 0; Index < ARRAY_SIZE (mKeyStrokeInfo); ++Index) {
mKeyStrokeInfo[Index].CurrentStroke = FALSE;
}
}
NumberOfReleasedKeys = InternalGetAndRemoveReleasedKeys (
NumberOfKeyCodes,
KeyCodes,
&ReleasedKeys
);
CLockOn = InternalIsCLockOn (NumberOfKeyCodes, KeyCodes);
AppleModifiers = Modifiers;
if (CLockOn) {
AppleModifiers |= APPLE_MODIFIERS_SHIFT;
}
ShiftPressed = (BOOLEAN)((AppleModifiers & APPLE_MODIFIERS_SHIFT) != 0);
for (Index = 0; Index < NumberOfReleasedKeys; ++Index) {
EventInputKeyFromAppleKeyCode (
ReleasedKeys[Index],
&InputKey,
ShiftPressed
);
AppleEventData.KeyData = NULL;
Status = InternalAppleKeyEventDataFromInputKey (
&AppleEventData,
&ReleasedKeys[Index],
&InputKey
);
if (EFI_ERROR (Status)) {
break;
}
EventCreateEventQueue (
AppleEventData,
APPLE_EVENT_TYPE_KEY_UP,
AppleModifiers
);
}
if (ReleasedKeys != NULL) {
FreePool ((VOID *)ReleasedKeys);
}
if (CLockOn != mCLockOn) {
mCLockOn = CLockOn;
mCLockChanged = TRUE;
}
//
// Increase the number of strokes for all currently pressed keys.
//
for (NewKeyIndex = 0; NewKeyIndex < *NumberOfKeyCodes; ++NewKeyIndex) {
KeyInfo = NULL;
for (Index = 0; Index < ARRAY_SIZE (mKeyStrokeInfo); ++Index) {
if (mKeyStrokeInfo[Index].AppleKeyCode == KeyCodes[NewKeyIndex]) {
KeyInfo = &mKeyStrokeInfo[Index];
KeyInfo->NumberOfStrokes++;
break;
}
}
//
// Indicates a key has been pressed which is not part of mKeyInformation.
//
if (KeyInfo == NULL) {
//
// If a new key is pressed, cancel all previous inputs.
//
for (Index = 0; Index < ARRAY_SIZE (mKeyStrokeInfo); ++Index) {
mKeyStrokeInfo[Index].CurrentStroke = FALSE;
}
//
// Insert the new key into a buffer
//
for (Index = 0; Index < ARRAY_SIZE (mKeyStrokeInfo); ++Index) {
if (mKeyStrokeInfo[Index].AppleKeyCode == 0) {
KeyInfo = &mKeyStrokeInfo[Index];
KeyInfo->AppleKeyCode = KeyCodes[NewKeyIndex];
KeyInfo->CurrentStroke = TRUE;
KeyInfo->NumberOfStrokes = 0;
break;
}
}
// CHECKME: is it intentional?
break;
}
}
KeyInfo = InternalGetCurrentStroke ();
Status = EFI_NOT_READY;
if ((KeyInfo != NULL) || (mModifiers != Modifiers)) {
mModifiers = Modifiers;
//
// Verify the timeframe the key has been pressed.
//
if (KeyInfo != NULL) {
AcceptStroke = (BOOLEAN)(
(KeyInfo->NumberOfStrokes < (KEY_STROKE_DELAY * 10))
? (KeyInfo->NumberOfStrokes == 0)
: ((KeyInfo->NumberOfStrokes % KEY_STROKE_DELAY) == 0)
);
if (AcceptStroke) {
*NumberOfKeyCodes = 1;
*KeyCodes = KeyInfo->AppleKeyCode;
Shifted = (BOOLEAN)(
(IS_APPLE_KEY_LETTER (KeyInfo->AppleKeyCode) && CLockOn)
!= ((mModifiers & APPLE_MODIFIERS_SHIFT) != 0)
);
EventInputKeyFromAppleKeyCode (
KeyInfo->AppleKeyCode,
Key,
Shifted
);
Status = EFI_SUCCESS;
}
} else {
//
// Report that no keys were pressed.
//
*NumberOfKeyCodes = 0;
Status = EFI_SUCCESS;
}
}
return Status;
}
// CreateAppleKeyCodeDescriptorsFromKeyStrokes
STATIC
EFI_STATUS
InternalAppleEventDataFromCurrentKeyStroke (
IN OUT APPLE_EVENT_DATA *EventData,
IN OUT APPLE_MODIFIER_MAP *Modifiers
)
{
EFI_STATUS Status;
EFI_INPUT_KEY InputKey;
APPLE_KEY_CODE *KeyCodes;
APPLE_MODIFIER_MAP AppleModifiers;
UINTN NumberOfKeyCodes;
EFI_CONSOLE_CONTROL_PROTOCOL *ConsoleControl;
EFI_CONSOLE_CONTROL_SCREEN_MODE Mode;
UINTN Index;
DEBUG ((DEBUG_VERBOSE, "InternalAppleEventDataFromCurrentKeyStroke\n"));
ZeroMem (&InputKey, sizeof (InputKey));
KeyCodes = NULL;
Status = EFI_UNSUPPORTED;
if ((mKeyMapAggregator != NULL)
&& (EventData != NULL)
&& (Modifiers != NULL)) {
AppleModifiers = 0;
NumberOfKeyCodes = 0;
InternalGetAppleKeyStrokes (
&AppleModifiers,
&NumberOfKeyCodes,
&KeyCodes
);
Mode = EfiConsoleControlScreenGraphics;
Status = gBS->LocateProtocol (
&gEfiConsoleControlProtocolGuid,
NULL,
(VOID *)&ConsoleControl
);
if (!EFI_ERROR (Status)) {
ConsoleControl->GetMode (ConsoleControl, &Mode, NULL, NULL);
}
if (Mode == EfiConsoleControlScreenGraphics) {
for (Index = 0; Index < (NumberOfKeyCodes + 1); ++Index) {
Status = gST->ConIn->ReadKeyStroke (gST->ConIn, &InputKey);
if (EFI_ERROR (Status)) {
break;
}
}
}
*Modifiers = AppleModifiers;
Status = InternalGetCurrentKeyStroke (
AppleModifiers,
&NumberOfKeyCodes,
KeyCodes,
&InputKey
);
if (!EFI_ERROR (Status)) {
Status = EFI_SUCCESS;
if (NumberOfKeyCodes > 0) {
InternalAppleKeyEventDataFromInputKey (EventData, KeyCodes, &InputKey);
}
}
if (KeyCodes) {
FreePool (KeyCodes);
}
}
return Status;
}
// InternalKeyStrokePollNotifyFunction
STATIC
VOID
EFIAPI
InternalKeyStrokePollNotifyFunction (
IN EFI_EVENT Event,
IN VOID *Context
)
{
EFI_STATUS Status;
APPLE_EVENT_DATA EventData;
APPLE_MODIFIER_MAP Modifiers;
APPLE_MODIFIER_MAP PartialModifers;
DEBUG ((DEBUG_VERBOSE, "InternalKeyStrokePollNotifyFunction\n"));
EventData.KeyData = NULL;
Modifiers = 0;
Status = InternalAppleEventDataFromCurrentKeyStroke (
&EventData,
&Modifiers
);
if (!EFI_ERROR (Status)) {
if (EventData.KeyData != NULL) {
EventCreateEventQueue (EventData, APPLE_EVENT_TYPE_KEY_DOWN, Modifiers);
}
if (mPreviousModifiers != Modifiers) {
PartialModifers = ((mPreviousModifiers ^ Modifiers) & mPreviousModifiers);
if (PartialModifers != 0) {
EventData.KeyData = NULL;
EventCreateEventQueue (
EventData,
APPLE_EVENT_TYPE_MODIFIER_UP,
PartialModifers
);
}
PartialModifers = ((mPreviousModifiers ^ Modifiers) & Modifiers);
if (PartialModifers != 0) {
EventData.KeyData = NULL;
EventCreateEventQueue (
EventData,
APPLE_EVENT_TYPE_MODIFIER_DOWN,
PartialModifers
);
}
mPreviousModifiers = Modifiers;
}
}
}
// InternalInitializeKeyHandler
STATIC
VOID
InternalInitializeKeyHandler (
VOID
)
{
DEBUG ((DEBUG_VERBOSE, "InternalInitializeKeyHandler\n"));
if (!mInitialized) {
mInitialized = TRUE;
ZeroMem ((VOID *)&mKeyStrokeInfo[0], sizeof (mKeyStrokeInfo));
mModifiers = 0;
mCLockOn = FALSE;
mCLockChanged = FALSE;
}
}
// EventCreateKeyStrokePollEvent
EFI_STATUS
EventCreateKeyStrokePollEvent (
VOID
)
{
EFI_STATUS Status;
DEBUG ((DEBUG_VERBOSE, "EventCreateKeyStrokePollEvent\n"));
Status = gBS->LocateProtocol (
&gAppleKeyMapAggregatorProtocolGuid,
NULL,
(VOID **)&mKeyMapAggregator
);
if (!EFI_ERROR (Status)) {
InternalInitializeKeyHandler ();
mKeyStrokePollEvent = EventLibCreateNotifyTimerEvent (
InternalKeyStrokePollNotifyFunction,
NULL,
KEY_STROKE_POLL_FREQUENCY,
TRUE
);
Status = ((mKeyStrokePollEvent == NULL)
? EFI_OUT_OF_RESOURCES
: EFI_SUCCESS);
}
return Status;
}
// EventCancelKeyStrokePollEvent
VOID
EventCancelKeyStrokePollEvent (
VOID
)
{
DEBUG ((DEBUG_VERBOSE, "EventCancelKeyStrokePollEvent\n"));
EventLibCancelEvent (mKeyStrokePollEvent);
mKeyStrokePollEvent = NULL;
}
// EventIsCapsLockOnImpl
/** Retrieves the state of the CapsLock key.
@param[in, out] CLockOn This parameter indicates the state of the CapsLock
key.
@retval EFI_SUCCESS The CapsLock state was successfully returned
in CLockOn.
@retval EFI_INVALID_PARAMETER CLockOn is NULL.
**/
EFI_STATUS
EFIAPI
EventIsCapsLockOnImpl (
IN OUT BOOLEAN *CLockOn
)
{
EFI_STATUS Status;
DEBUG ((DEBUG_VERBOSE, "EventIsCapsLockOnImpl\n"));
Status = EFI_INVALID_PARAMETER;
if (CLockOn != NULL) {
*CLockOn = mCLockOn;
Status = EFI_SUCCESS;
}
return Status;
}
/** @file
AppleEventDxe
Copyright (c) 2018, vit9696
All rights reserved.
This program and the accompanying materials
are licensed and made available under the terms and conditions of the BSD License
which accompanies this distribution. The full text of the license may be found at
http://opensource.org/licenses/bsd-license.php
THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
**/
#include <AppleMacEfi.h>
#include <Library/BaseLib.h>
#include <Library/DebugLib.h>
#include <Library/MemoryAllocationLib.h>
#include <Library/OcMiscLib.h>
#include <Library/UefiBootServicesTableLib.h>
#include "AppleEventInternal.h"
// APPLE_EVENT_HANDLE_PRIVATE_SIGNATURE
#define APPLE_EVENT_HANDLE_PRIVATE_SIGNATURE \
SIGNATURE_32 ('A', 'L', 's', 't')
// APPLE_EVENT_HANDLE_PRIVATE_FROM_LIST_ENTRY
#define APPLE_EVENT_HANDLE_PRIVATE_FROM_LIST_ENTRY(Handle) \
CR ( \
(Handle), \
APPLE_EVENT_HANDLE_PRIVATE, \
Link, \
APPLE_EVENT_HANDLE_PRIVATE_SIGNATURE \
)
// APPLE_EVENT_HANDLE_PRIVATE
typedef struct {
UINT32 Signature; ///<
LIST_ENTRY Link; ///<
BOOLEAN Ready; ///<
BOOLEAN Registered; ///<
APPLE_EVENT_TYPE EventType; ///<
APPLE_EVENT_NOTIFY_FUNCTION NotifyFunction; ///<
VOID *NotifyContext; ///<
CHAR8 *Name; ///<
} APPLE_EVENT_HANDLE_PRIVATE;
// mEventHandles
STATIC
LIST_ENTRY mEventHandles = INITIALIZE_LIST_HEAD_VARIABLE (mEventHandles);
// mNumberOfEventHandles
STATIC UINTN mNumberOfEventHandles = 0;
// EventLibCreateTimerEvent
EFI_EVENT
EventLibCreateTimerEvent (
IN EFI_EVENT_NOTIFY NotifyFunction,
IN VOID *NotifyContext,
IN UINT64 TriggerTime,
IN BOOLEAN SignalPeriodic,
IN EFI_TPL NotifyTpl
)
{
EFI_EVENT Event;
EFI_STATUS Status;
DEBUG ((DEBUG_VERBOSE, "EventLibCreateTimerEvent\n"));
Event = NULL;
if (NotifyTpl >= TPL_CALLBACK) {
Status = gBS->CreateEvent (
((NotifyFunction != NULL)
? (EVT_TIMER | EVT_NOTIFY_SIGNAL)
: EVT_TIMER),
NotifyTpl,
NotifyFunction,
NotifyContext,
&Event
);
if (!EFI_ERROR (Status)) {
Status = gBS->SetTimer (
Event,
(SignalPeriodic ? TimerPeriodic : TimerRelative),
TriggerTime
);
if (EFI_ERROR (Status)) {
gBS->CloseEvent (Event);
Event = NULL;
}
}
}
return Event;
}
// EventLibCreateNotifyTimerEvent
EFI_EVENT
EventLibCreateNotifyTimerEvent (
IN EFI_EVENT_NOTIFY NotifyFunction,
IN VOID *NotifyContext,
IN UINT64 TriggerTime,
IN BOOLEAN SignalPeriodic
)
{
DEBUG ((DEBUG_VERBOSE, "EventLibCreateNotifyTimerEvent\n"));
return EventLibCreateTimerEvent (
NotifyFunction,
NotifyContext,
TriggerTime,
SignalPeriodic,
TPL_NOTIFY
);
}
// EventLibCancelEvent
VOID
EventLibCancelEvent (
IN EFI_EVENT Event
)
{
EFI_STATUS Status;
DEBUG ((DEBUG_VERBOSE, "EventLibCancelEvent\n"));
Status = gBS->SetTimer (Event, TimerCancel, 0);
if (!EFI_ERROR (Status)) {
gBS->CloseEvent (Event);
}
}
// EventSignalEvents
VOID
EventSignalEvents (
IN APPLE_EVENT_INFORMATION *EventInformation
)
{
LIST_ENTRY *EventHandleEntry;
APPLE_EVENT_HANDLE_PRIVATE *EventHandle;
DEBUG ((DEBUG_VERBOSE, "EventSignalEvents\n"));
EventHandleEntry = GetFirstNode (&mEventHandles);
while (!IsNull (&mEventHandles, EventHandleEntry)) {
EventHandle = APPLE_EVENT_HANDLE_PRIVATE_FROM_LIST_ENTRY (
EventHandleEntry
);
if (EventHandle->Registered
&& EventHandle->Ready
&& ((EventInformation->EventType & EventHandle->EventType) != 0)
&& (EventHandle->NotifyFunction != NULL)) {
EventHandle->NotifyFunction (
EventInformation,
EventHandle->NotifyContext
);
}
EventHandleEntry = GetNextNode (&mEventHandles, EventHandleEntry);
}
}
// InternalFlagAllEventsReady
VOID
InternalFlagAllEventsReady (
VOID
)
{
LIST_ENTRY *EventHandleEntry;
APPLE_EVENT_HANDLE_PRIVATE *EventHandle;
DEBUG ((DEBUG_VERBOSE, "InternalFlagAllEventsReady\n"));
EventHandleEntry = GetFirstNode (&mEventHandles);
if (!IsListEmpty (&mEventHandles)) {
do {
EventHandle = APPLE_EVENT_HANDLE_PRIVATE_FROM_LIST_ENTRY (
EventHandleEntry
);
EventHandle->Ready = TRUE;
EventHandleEntry = GetNextNode (&mEventHandles, EventHandleEntry);
} while (!IsNull (&mEventHandles, EventHandleEntry));
}
}
// InternalSignalEvents
VOID
InternalSignalEvents (
IN APPLE_EVENT_INFORMATION *Information
)
{
LIST_ENTRY *EventHandleEntry;
APPLE_EVENT_HANDLE_PRIVATE *EventHandle;
DEBUG ((DEBUG_VERBOSE, "InternalSignalEvents\n"));
EventHandleEntry = GetFirstNode (&mEventHandles);
if (!IsListEmpty (&mEventHandles)) {
do {
EventHandle = APPLE_EVENT_HANDLE_PRIVATE_FROM_LIST_ENTRY (
EventHandleEntry
);
if (EventHandle->Registered && EventHandle->Ready
&& (EventHandle->EventType & Information->EventType)
&& EventHandle->NotifyFunction != NULL) {
EventHandle->NotifyFunction (
Information,
EventHandle->NotifyContext
);
}
EventHandleEntry = GetNextNode (&mEventHandles, EventHandleEntry);
} while (!IsNull (&mEventHandles, EventHandleEntry));
}
}
// InternalRemoveUnregisteredEvents
VOID
InternalRemoveUnregisteredEvents (
VOID
)
{
LIST_ENTRY *EventHandleEntry;
LIST_ENTRY *NextEventHandleEntry;
APPLE_EVENT_HANDLE_PRIVATE *EventHandle;
DEBUG ((DEBUG_VERBOSE, "InternalRemoveUnregisteredEvents\n"));
EventHandleEntry = GetFirstNode (&mEventHandles);
if (!IsListEmpty (&mEventHandles)) {
do {
NextEventHandleEntry = GetNextNode (&mEventHandles, EventHandleEntry);
EventHandle = APPLE_EVENT_HANDLE_PRIVATE_FROM_LIST_ENTRY (
EventHandleEntry
);
if (!EventHandle->Registered) {
if (EventHandle->Name != NULL) {
FreePool ((VOID *)EventHandle->Name);
}
RemoveEntryList (&EventHandle->Link);
FreePool ((VOID *)EventHandle);
}
EventHandleEntry = NextEventHandleEntry;
} while (!IsNull (&mEventHandles, NextEventHandleEntry));
}
}
// InternalCreatePollEvents
STATIC
EFI_STATUS
InternalCreatePollEvents (
VOID
)
{
EFI_STATUS Status;
DEBUG ((DEBUG_VERBOSE, "InternalCreatePollEvents\n"));
Status = EventCreateSimplePointerPollEvent ();
if (!EFI_ERROR (Status)) {
Status = EventCreateKeyStrokePollEvent ();
if (EFI_ERROR (Status)) {
EventCancelSimplePointerPollEvent ();
}
}
return Status;
}
// InternalCancelPollEvents
VOID
InternalCancelPollEvents (
VOID
)
{
DEBUG ((DEBUG_VERBOSE, "InternalCancelPollEvents\n"));
EventCancelSimplePointerPollEvent ();
EventCancelKeyStrokePollEvent ();
}
// EventRegisterHandler
EFI_STATUS
EFIAPI
EventRegisterHandler (
IN APPLE_EVENT_TYPE Type,
IN APPLE_EVENT_NOTIFY_FUNCTION NotifyFunction,
OUT APPLE_EVENT_HANDLE *Handle,
IN VOID *NotifyContext
)
{
EFI_STATUS Status;
APPLE_EVENT_HANDLE_PRIVATE *EventHandle;
DEBUG ((DEBUG_VERBOSE, "EventRegisterHandler\n"));
Status = EFI_INVALID_PARAMETER;
if ((Handle != NULL)
&& (NotifyFunction != NULL)
&& (Type != APPLE_EVENT_TYPE_NONE)) {
*Handle = NULL;
InternalRemoveUnregisteredEvents ();
Status = EFI_SUCCESS;
if (mNumberOfEventHandles == 0) {
Status = InternalCreatePollEvents ();
if (EFI_ERROR (Status)) {
goto Done;
}
}
EventHandle = AllocatePool (sizeof (*EventHandle));
Status = EFI_OUT_OF_RESOURCES;
if (EventHandle != NULL) {
EventHandle->Signature = APPLE_EVENT_HANDLE_PRIVATE_SIGNATURE;
EventHandle->Ready = FALSE;
EventHandle->Registered = TRUE;
EventHandle->EventType = Type;
EventHandle->NotifyFunction = NotifyFunction;
EventHandle->NotifyContext = NotifyContext;
EventHandle->Name = NULL;
++mNumberOfEventHandles;
InsertTailList (&mEventHandles, &EventHandle->Link);
*Handle = EventHandle;
Status = EFI_SUCCESS;
}
}
Done:
return Status;
}
// EventUnregisterHandler
EFI_STATUS
EFIAPI
EventUnregisterHandler (
IN APPLE_EVENT_HANDLE Handle
)
{
EFI_STATUS Status;
LIST_ENTRY *EventHandleEntry;
APPLE_EVENT_HANDLE_PRIVATE *EventHandle;
DEBUG ((DEBUG_VERBOSE, "EventUnregisterHandler\n"));
Status = EFI_INVALID_PARAMETER;
EventHandleEntry = GetFirstNode (&mEventHandles);
while (!IsNull (&mEventHandles, EventHandleEntry)) {
EventHandle = APPLE_EVENT_HANDLE_PRIVATE_FROM_LIST_ENTRY (
EventHandleEntry
);
if (((UINTN)EventHandle == (UINTN)Handle)
|| ((UINTN)Handle == (UINTN)-1)) {
EventHandle->Registered = FALSE;
--mNumberOfEventHandles;
Status = EFI_SUCCESS;
if ((UINTN)Handle != (UINTN)-1) {
break;
}
}
EventHandleEntry = GetNextNode (&mEventHandles, EventHandleEntry);
}
if (mNumberOfEventHandles == 0) {
InternalCancelPollEvents ();
}
return Status;
}
// EventSetCursorPosition
/** This function is used to change the position of the cursor on the screen.
@param[in] Position The position where to position the cursor.
@retval EFI_INVALID_PARAMETER Position is invalid.
**/
EFI_STATUS
EFIAPI
EventSetCursorPosition (
IN DIMENSION *Position
)
{
DEBUG ((DEBUG_VERBOSE, "EventSetCursorPosition\n"));
return EventSetCursorPositionImpl (Position);
}
// EventSetEventName
/** This function is used to assign a name to an event.
@param[in, out] Handle
@param[in] Name
@retval EFI_SUCCESS The event name was assigned successfully.
@retval EFI_INVALID_PARAMETER EventHandle or EventName is NULL.
@retval EFI_OUT_OF_RESOURCES There are not enough resources to allocate the
event name.
**/
EFI_STATUS
EFIAPI
EventSetEventName (
IN OUT APPLE_EVENT_HANDLE Handle,
IN CHAR8 *Name
)
{
EFI_STATUS Status;
UINTN AllocationSize;
CHAR8 *EventName;
DEBUG ((DEBUG_VERBOSE, "EventSetEventName\n"));
Status = EFI_INVALID_PARAMETER;
if ((Handle != NULL) && (Name != NULL)) {
AllocationSize = AsciiStrSize (Name);
EventName = AllocateZeroPool (AllocationSize);
((APPLE_EVENT_HANDLE_PRIVATE *)Handle)->Name = EventName;
Status = EFI_OUT_OF_RESOURCES;
if (EventName != NULL) {
AsciiStrCpyS (EventName, AllocationSize, Name);
Status = EFI_SUCCESS;
}
}
return Status;
}
// EventIsCapsLockOnImpl
/** Retrieves the state of the CapsLock key.
@param[in, out] CLockOn This parameter indicates the state of the CapsLock
key.
@retval EFI_SUCCESS The CapsLock state was successfully returned
in CLockOn.
@retval EFI_INVALID_PARAMETER CLockOn is NULL.
**/
EFI_STATUS
EFIAPI
EventIsCapsLockOn (
IN OUT BOOLEAN *CLockOn
)
{
DEBUG ((DEBUG_VERBOSE, "EventIsCapsLockOn\n"));
return EventIsCapsLockOnImpl (CLockOn);
}
// InternalUnregisterHandlers
STATIC
VOID
InternalUnregisterHandlers (
VOID
)
{
DEBUG ((DEBUG_VERBOSE, "InternalUnregisterHandlers\n"));
EventSimplePointerDesctructor ();
InternalRemoveUnregisteredEvents ();
if (!IsListEmpty (&mEventHandles)) {
EventUnregisterHandler ((APPLE_EVENT_HANDLE_PRIVATE *)((UINTN)-1));
}
}
// mAppleEventProtocol
STATIC APPLE_EVENT_PROTOCOL mAppleEventProtocol = {
APPLE_EVENT_PROTOCOL_REVISION,
EventRegisterHandler,
EventUnregisterHandler,
EventSetCursorPosition,
EventSetEventName,
EventIsCapsLockOn
};
// AppleEventUnload
EFI_STATUS
EFIAPI
AppleEventUnload (
VOID
)
{
EFI_STATUS Status;
DEBUG ((DEBUG_VERBOSE, "AppleEventUnload\n"));
EventCloseSimplePointerInstallNotifyEvent ();
InternalSignalAndCloseQueueEvent ();
InternalUnregisterHandlers ();
InternalCancelPollEvents ();
Status = gBS->UninstallProtocolInterface (
gImageHandle,
&gAppleEventProtocolGuid,
(VOID *)&mAppleEventProtocol
);
return Status;
}
/**
Install and initialise Apple Event protocol.
@param[in] Reinstall Overwrite installed protocol.
@retval installed or located protocol or NULL.
**/
APPLE_EVENT_PROTOCOL *
OcAppleEventInstallProtocol (
IN BOOLEAN Reinstall
)
{
EFI_STATUS Status;
APPLE_EVENT_PROTOCOL *Protocol;
DEBUG ((DEBUG_VERBOSE, "OcAppleEventInstallProtocol\n"));
if (Reinstall) {
Status = UninstallAllProtocolInstances (&gAppleEventProtocolGuid);
if (EFI_ERROR (Status)) {
DEBUG ((DEBUG_ERROR, "OCAE: Uninstall failed: %r\n", Status));
return NULL;
}
} else {
Status = gBS->LocateProtocol (
&gAppleEventProtocolGuid,
NULL,
(VOID *) &Protocol
);
if (!EFI_ERROR (Status)) {
return Protocol;
}
}
//
// Apple code supports unloading, ours does not.
//
Status = gBS->InstallProtocolInterface (
&gImageHandle,
&gAppleEventProtocolGuid,
EFI_NATIVE_INTERFACE,
(VOID *)&mAppleEventProtocol
);
if (!EFI_ERROR (Status)) {
InternalCreateQueueEvent ();
Status = EventCreateSimplePointerInstallNotifyEvent ();
}
if (EFI_ERROR (Status)) {
AppleEventUnload ();
return NULL;
}
return &mAppleEventProtocol;
}
## @file
#
# Component description file for the library producing the Apple Event protocol.
#
# Copyright (C) 2019, Download-Fritz. All rights reserved.<BR>
#
# All rights reserved.
#
# This program and the accompanying materials
# are licensed and made available under the terms and conditions of the BSD License
# which accompanies this distribution. The full text of the license may be found at
# http://opensource.org/licenses/bsd-license.php
#
# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
#
##
[Defines]
INF_VERSION = 0x00010005
BASE_NAME = OcAppleEventLib
FILE_GUID = 4587D92C-0225-4D5C-8E6F-D86303202001
MODULE_TYPE = DXE_DRIVER
VERSION_STRING = 1.0
LIBRARY_CLASS = OcAppleEventLib|DXE_DRIVER DXE_RUNTIME_DRIVER UEFI_DRIVER UEFI_APPLICATION DXE_SMM_DRIVER
#
# The following information is for reference only and not required by the build tools.
#
# VALID_ARCHITECTURES = IA32 X64 IPF EBC
#
[Sources]
AppleEventInternal.h
AppleKeyMap.c
EventQueue.c
KeyHandler.c
OcAppleEventLib.c
PointerHandler.c
[Packages]
OcSupportPkg/OcSupportPkg.dec
MdePkg/MdePkg.dec
EfiPkg/EfiPkg.dec
[Protocols]
gAppleKeyMapDatabaseProtocolGuid ## SOMETIMES_CONSUMES
gAppleKeyMapAggregatorProtocolGuid ## SOMETIMES_CONSUMES
gEfiConsoleControlProtocolGuid ## SOMETIMES_CONSUMES
gEfiGraphicsOutputProtocolGuid ## SOMETIMES_CONSUMES
gEfiUgaDrawProtocolGuid ## SOMETIMES_CONSUMES
gEfiSimplePointerProtocolGuid ## SOMETIMES_CONSUMES
[LibraryClasses]
BaseLib
BaseMemoryLib
DebugLib
OcMiscLib
MemoryAllocationLib
UefiBootServicesTableLib
UefiLib
UefiRuntimeServicesTableLib
此差异已折叠。
/** @file
AppleKeyMapAggregator
Copyright (c) 2018, vit9696
All rights reserved.
This program and the accompanying materials
are licensed and made available under the terms and conditions of the BSD License
which accompanies this distribution. The full text of the license may be found at
http://opensource.org/licenses/bsd-license.php
THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
**/
#include <AppleMacEfi.h>
#include <IndustryStandard/AppleHid.h>
#include <Protocol/AppleKeyMapAggregator.h>
#include <Protocol/AppleKeyMapDatabase.h>
#include <Library/BaseLib.h>
#include <Library/BaseMemoryLib.h>
#include <Library/DebugLib.h>
#include <Library/MemoryAllocationLib.h>
#include <Library/OcMiscLib.h>
#include <Library/UefiBootServicesTableLib.h>
// KEY_MAP_AGGREGATOR_DATA_SIGNATURE
#define KEY_MAP_AGGREGATOR_DATA_SIGNATURE \
SIGNATURE_32 ('K', 'e', 'y', 'A')
// KEY_MAP_AGGREGATOR_DATA_FROM_AGGREGATOR_THIS
#define KEY_MAP_AGGREGATOR_DATA_FROM_AGGREGATOR_THIS(This) \
CR ( \
(This), \
KEY_MAP_AGGREGATOR_DATA, \
Aggregator, \
KEY_MAP_AGGREGATOR_DATA_SIGNATURE \
)
// KEY_MAP_AGGREGATOR_DATA_FROM_DATABASE_THIS
#define KEY_MAP_AGGREGATOR_DATA_FROM_DATABASE_THIS(This) \
CR ( \
(This), \
KEY_MAP_AGGREGATOR_DATA, \
Database, \
KEY_MAP_AGGREGATOR_DATA_SIGNATURE \
)
// KEY_MAP_AGGREGATOR_DATA
typedef struct {
UINTN Signature;
UINTN NextKeyStrokeIndex;
APPLE_KEY_CODE *KeyCodeBuffer;
UINTN KeyCodeBufferLength;
LIST_ENTRY KeyStrokesInfoList;
APPLE_KEY_MAP_DATABASE_PROTOCOL Database;
APPLE_KEY_MAP_AGGREGATOR_PROTOCOL Aggregator;
} KEY_MAP_AGGREGATOR_DATA;
// APPLE_KEY_STROKES_INFO_SIGNATURE
#define APPLE_KEY_STROKES_INFO_SIGNATURE SIGNATURE_32 ('K', 'e', 'y', 'S')
// APPLE_KEY_STROKES_INFO_FROM_LIST_ENTRY
#define APPLE_KEY_STROKES_INFO_FROM_LIST_ENTRY(Entry) \
CR ( \
(Entry), \
APPLE_KEY_STROKES_INFO, \
Link, \
APPLE_KEY_STROKES_INFO_SIGNATURE \
)
#define SIZE_OF_APPLE_KEY_STROKES_INFO \
OFFSET_OF (APPLE_KEY_STROKES_INFO, KeyCodes)
// APPLE_KEY_STROKES_INFO
typedef struct {
UINTN Signature;
LIST_ENTRY Link;
UINTN Index;
UINTN KeyCodeBufferLength;
UINTN NumberOfKeyCodes;
APPLE_MODIFIER_MAP Modifiers;
APPLE_KEY_CODE KeyCodes[];
} APPLE_KEY_STROKES_INFO;
// InternalGetKeyStrokesByIndex
STATIC
APPLE_KEY_STROKES_INFO *
InternalGetKeyStrokesByIndex (
IN KEY_MAP_AGGREGATOR_DATA *KeyMapAggregatorData,
IN UINTN Index
)
{
APPLE_KEY_STROKES_INFO *KeyStrokesInfo;
LIST_ENTRY *Entry;
APPLE_KEY_STROKES_INFO *KeyStrokesInfoWalker;
KeyStrokesInfo = NULL;
for (
Entry = GetFirstNode (&KeyMapAggregatorData->KeyStrokesInfoList);
!IsNull (&KeyMapAggregatorData->KeyStrokesInfoList, Entry);
Entry = GetNextNode (&KeyMapAggregatorData->KeyStrokesInfoList, Entry)
) {
KeyStrokesInfoWalker = APPLE_KEY_STROKES_INFO_FROM_LIST_ENTRY (Entry);
if (KeyStrokesInfoWalker->Index == Index) {
KeyStrokesInfo = KeyStrokesInfoWalker;
break;
}
}
return KeyStrokesInfo;
}
// InternalMinSort
STATIC
VOID
InternalMinSort (
IN OUT UINT16 *Operand,
IN UINTN NumberOfChilds
)
{
UINTN Index;
UINTN Index2;
UINT16 FirstChild;
for (Index = 0; Index < NumberOfChilds; ++Index) {
for (Index2 = (Index + 1); Index2 < NumberOfChilds; ++Index2) {
FirstChild = Operand[Index];
if (FirstChild > Operand[Index2]) {
Operand[Index] = Operand[Index2];
Operand[Index2] = FirstChild;
}
}
}
}
// InternalGetKeyStrokes
/** Returns all pressed keys and key modifiers into the appropiate buffers.
@param[in] This A pointer to the protocol instance.
@param[out] Modifiers The modifiers manipulating the given keys.
@param[out] NumberOfKeyCodes On input the number of keys allocated.
On output the number of keys returned into
KeyCodes.
@param[out] KeyCodes A Pointer to a caller-allocated the pressed
keys get returned in.
@retval EFI_SUCCESS The pressed keys have been returned into
KeyCodes.
@retval EFI_BUFFER_TOO_SMALL The memory required to return the value exceeds
the size of the allocated Buffer.
The required number of keys to allocate to
complete the operation has been returned into
NumberOfKeyCodes.
@retval other An error returned by a sub-operation.
**/
STATIC
EFI_STATUS
EFIAPI
InternalGetKeyStrokes (
IN APPLE_KEY_MAP_AGGREGATOR_PROTOCOL *This,
OUT APPLE_MODIFIER_MAP *Modifiers,
OUT UINTN *NumberOfKeyCodes,
IN OUT APPLE_KEY_CODE *KeyCodes OPTIONAL
)
{
EFI_STATUS Status;
KEY_MAP_AGGREGATOR_DATA *KeyMapAggregatorData;
LIST_ENTRY *Entry;
APPLE_KEY_STROKES_INFO *KeyStrokesInfo;
BOOLEAN Result;
APPLE_MODIFIER_MAP DbModifiers;
UINTN DbNumberOfKeyCodestrokes;
UINTN Index;
UINTN Index2;
APPLE_KEY_CODE Key;
KeyMapAggregatorData = KEY_MAP_AGGREGATOR_DATA_FROM_AGGREGATOR_THIS (This);
DbModifiers = 0;
DbNumberOfKeyCodestrokes = 0;
for (
Entry = GetFirstNode (&KeyMapAggregatorData->KeyStrokesInfoList);
!IsNull (&KeyMapAggregatorData->KeyStrokesInfoList, Entry);
Entry = GetNextNode (&KeyMapAggregatorData->KeyStrokesInfoList, Entry)
) {
KeyStrokesInfo = APPLE_KEY_STROKES_INFO_FROM_LIST_ENTRY (Entry);
DbModifiers |= KeyStrokesInfo->Modifiers;
for (Index = 0; Index < KeyStrokesInfo->NumberOfKeyCodes; ++Index) {
Key = KeyStrokesInfo->KeyCodes[Index];
for (Index2 = 0; Index2 < DbNumberOfKeyCodestrokes; ++Index2) {
if (KeyMapAggregatorData->KeyCodeBuffer[Index2] == Key) {
break;
}
}
if (Index2 == DbNumberOfKeyCodestrokes) {
KeyMapAggregatorData->KeyCodeBuffer[DbNumberOfKeyCodestrokes] = Key;
++DbNumberOfKeyCodestrokes;
}
}
}
Result = (BOOLEAN)(DbNumberOfKeyCodestrokes > *NumberOfKeyCodes);
*NumberOfKeyCodes = DbNumberOfKeyCodestrokes;
Status = EFI_BUFFER_TOO_SMALL;
if (!Result) {
*Modifiers = DbModifiers;
Status = EFI_SUCCESS;
if (KeyCodes != NULL) {
CopyMem (
(VOID *)KeyCodes,
(VOID *)KeyMapAggregatorData->KeyCodeBuffer,
(DbNumberOfKeyCodestrokes * sizeof (*KeyCodes))
);
}
}
return Status;
}
// InternalContainsKeyStrokes
/** Returns whether or not a list of keys and their modifiers are part of the
database of pressed keys.
@param[in] This A pointer to the protocol instance.
@param[in] Modifiers The modifiers manipulating the given keys.
@param[in] NumberOfKeyCodes The number of keys present in KeyCodes.
@param[in, out] KeyCodes The list of keys to check for. The children
may be sorted in the process.
@param[in] ExactMatch Specifies whether Modifiers and KeyCodes should be
exact matches or just contained.
@return Returns whether or not a list of keys and their
modifiers are part of the database of pressed keys.
@retval EFI_SUCCESS The queried keys are part of the database.
@retval EFI_NOT_FOUND The queried keys could not be found.
**/
STATIC
EFI_STATUS
EFIAPI
InternalContainsKeyStrokes (
IN APPLE_KEY_MAP_AGGREGATOR_PROTOCOL *This,
IN APPLE_MODIFIER_MAP Modifiers,
IN UINTN NumberOfKeyCodes,
IN OUT APPLE_KEY_CODE *KeyCodes,
IN BOOLEAN ExactMatch
)
{
EFI_STATUS Status;
UINTN DbNumberOfKeyCodes;
APPLE_MODIFIER_MAP DbModifiers;
APPLE_KEY_CODE DbKeyCodes[8];
INTN Result;
UINTN Index;
UINTN DbIndex;
DbNumberOfKeyCodes = ARRAY_SIZE (DbKeyCodes);
Status = This->GetKeyStrokes (
This,
&DbModifiers,
&DbNumberOfKeyCodes,
DbKeyCodes
);
if (EFI_ERROR (Status)) {
return Status;
}
if (ExactMatch) {
if ((DbModifiers != Modifiers)
|| (DbNumberOfKeyCodes != NumberOfKeyCodes)) {
return EFI_NOT_FOUND;
}
InternalMinSort ((UINT16 *)KeyCodes, NumberOfKeyCodes);
InternalMinSort ((UINT16 *)DbKeyCodes, DbNumberOfKeyCodes);
Result = CompareMem (
(VOID *)KeyCodes,
(VOID *)DbKeyCodes,
(NumberOfKeyCodes * sizeof (*KeyCodes))
);
if (Result != 0) {
return EFI_NOT_FOUND;
}
} else {
if ((DbModifiers & Modifiers) == Modifiers) {
return EFI_NOT_FOUND;
}
for (Index = 0; Index < NumberOfKeyCodes; ++Index) {
for (DbIndex = 0; DbIndex < DbNumberOfKeyCodes; ++DbIndex) {
if (KeyCodes[Index] == DbKeyCodes[DbIndex]) {
break;
}
}
if (DbNumberOfKeyCodes == DbIndex) {
return EFI_NOT_FOUND;
}
}
}
return EFI_SUCCESS;
}
// KeyMapCreateKeyStrokesBuffer
/** Creates a new key set with a given number of keys allocated. The index
within the database is returned.
@param[in] This A pointer to the protocol instance.
@param[in] BufferLength The amount of keys to allocate for the key set.
@param[out] Index The assigned index of the created key set.
@return Returned is the status of the operation.
@retval EFI_SUCCESS A key set with the given number of keys
allocated has been created.
@retval EFI_OUT_OF_RESOURCES The memory necessary to complete the operation
could not be allocated.
@retval other An error returned by a sub-operation.
**/
STATIC
EFI_STATUS
EFIAPI
InternalCreateKeyStrokesBuffer (
IN APPLE_KEY_MAP_DATABASE_PROTOCOL *This,
IN UINTN BufferLength,
OUT UINTN *Index
)
{
EFI_STATUS Status;
KEY_MAP_AGGREGATOR_DATA *KeyMapAggregatorData;
UINTN TotalBufferLength;
APPLE_KEY_CODE *Buffer;
APPLE_KEY_STROKES_INFO *KeyStrokesInfo;
KeyMapAggregatorData = KEY_MAP_AGGREGATOR_DATA_FROM_DATABASE_THIS (This);
if (KeyMapAggregatorData->KeyCodeBuffer != NULL) {
gBS->FreePool ((VOID *)KeyMapAggregatorData->KeyCodeBuffer);
}
TotalBufferLength = (KeyMapAggregatorData->KeyCodeBufferLength + BufferLength);
KeyMapAggregatorData->KeyCodeBufferLength = TotalBufferLength;
Buffer = AllocateZeroPool (TotalBufferLength * sizeof (*Buffer));
KeyMapAggregatorData->KeyCodeBuffer = Buffer;
Status = EFI_OUT_OF_RESOURCES;
if (Buffer != NULL) {
KeyStrokesInfo = AllocateZeroPool (
SIZE_OF_APPLE_KEY_STROKES_INFO
+ (BufferLength * sizeof (*Buffer))
);
Status = EFI_OUT_OF_RESOURCES;
if (KeyStrokesInfo != NULL) {
KeyStrokesInfo->Signature = APPLE_KEY_STROKES_INFO_SIGNATURE;
KeyStrokesInfo->KeyCodeBufferLength = BufferLength;
KeyStrokesInfo->Index = KeyMapAggregatorData->NextKeyStrokeIndex++;
InsertTailList (
&KeyMapAggregatorData->KeyStrokesInfoList,
&KeyStrokesInfo->Link
);
Status = EFI_SUCCESS;
*Index = KeyStrokesInfo->Index;
}
}
return Status;
}
// KeyMapRemoveKeyStrokesBuffer
/** Removes a key set specified by its index from the database.
@param[in] This A pointer to the protocol instance.
@param[in] Index The index of the key set to remove.
@return Returned is the status of the operation.
@retval EFI_SUCCESS The specified key set has been removed.
@retval EFI_NOT_FOUND No key set could be found for the given index.
@retval other An error returned by a sub-operation.
**/
STATIC
EFI_STATUS
EFIAPI
InternalRemoveKeyStrokesBuffer (
IN APPLE_KEY_MAP_DATABASE_PROTOCOL *This,
IN UINTN Index
)
{
EFI_STATUS Status;
KEY_MAP_AGGREGATOR_DATA *KeyMapAggregatorData;
APPLE_KEY_STROKES_INFO *KeyStrokesInfo;
KeyMapAggregatorData = KEY_MAP_AGGREGATOR_DATA_FROM_DATABASE_THIS (This);
KeyStrokesInfo = InternalGetKeyStrokesByIndex (
KeyMapAggregatorData,
Index
);
Status = EFI_NOT_FOUND;
if (KeyStrokesInfo != NULL) {
KeyMapAggregatorData->KeyCodeBufferLength -= KeyStrokesInfo->KeyCodeBufferLength;
RemoveEntryList (&KeyStrokesInfo->Link);
gBS->FreePool ((VOID *)KeyStrokesInfo);
Status = EFI_SUCCESS;
}
return Status;
}
// KeyMapSetKeyStrokeBufferKeys
/** Sets the keys of a key set specified by its index to the given KeyCodes
Buffer.
@param[in] This A pointer to the protocol instance.
@param[in] Index The index of the key set to edit.
@param[in] Modifiers The key modifiers manipulating the given keys.
@param[in] NumberOfKeyCodes The number of keys contained in KeyCodes.
@param[in] KeyCodes An array of keys to add to the specified key
set.
@return Returned is the status of the operation.
@retval EFI_SUCCESS The given keys were set for the specified key
set.
@retval EFI_OUT_OF_RESOURCES The memory necessary to complete the operation
could not be allocated.
@retval EFI_NOT_FOUND No key set could be found for the given index.
@retval other An error returned by a sub-operation.
**/
STATIC
EFI_STATUS
EFIAPI
InternalSetKeyStrokeBufferKeys (
IN APPLE_KEY_MAP_DATABASE_PROTOCOL *This,
IN UINTN Index,
IN APPLE_MODIFIER_MAP Modifiers,
IN UINTN NumberOfKeyCodes,
IN APPLE_KEY_CODE *KeyCodes
)
{
EFI_STATUS Status;
KEY_MAP_AGGREGATOR_DATA *KeyMapAggregatorData;
APPLE_KEY_STROKES_INFO *KeyStrokesInfo;
KeyMapAggregatorData = KEY_MAP_AGGREGATOR_DATA_FROM_DATABASE_THIS (This);
KeyStrokesInfo = InternalGetKeyStrokesByIndex (
KeyMapAggregatorData,
Index
);
Status = EFI_NOT_FOUND;
if (KeyStrokesInfo != NULL) {
Status = EFI_OUT_OF_RESOURCES;
if (KeyStrokesInfo->KeyCodeBufferLength >= NumberOfKeyCodes) {
KeyStrokesInfo->NumberOfKeyCodes = NumberOfKeyCodes;
KeyStrokesInfo->Modifiers = Modifiers;
CopyMem (
(VOID *)&KeyStrokesInfo->KeyCodes[0],
(VOID *)KeyCodes,
(NumberOfKeyCodes * sizeof (*KeyCodes))
);
Status = EFI_SUCCESS;
}
}
return Status;
}
/**
Install and initialise Apple Key Map protocols.
@param[out] KeyMapDatabase On success, installed or located protocol.
@param[out] KeyMapAggregator On success, installed or located protocol.
@param[in] Reinstall Overwrite installed protocols.
@returns Success status
**/
BOOLEAN
OcAppleKeyMapInstallProtocols (
OUT APPLE_KEY_MAP_DATABASE_PROTOCOL **KeyMapDatabase,
OUT APPLE_KEY_MAP_AGGREGATOR_PROTOCOL **KeyMapAggregator,
IN BOOLEAN Reinstall
)
{
EFI_STATUS Status;
EFI_STATUS Status2;
KEY_MAP_AGGREGATOR_DATA *KeyMapAggregatorData;
APPLE_KEY_MAP_DATABASE_PROTOCOL *Database;
APPLE_KEY_MAP_AGGREGATOR_PROTOCOL *Aggregator;
ASSERT (KeyMapDatabase != NULL);
ASSERT (KeyMapAggregator != NULL);
if (Reinstall) {
Status = UninstallAllProtocolInstances (&gAppleKeyMapDatabaseProtocolGuid);
Status2 = UninstallAllProtocolInstances (&gAppleKeyMapAggregatorProtocolGuid);
if (EFI_ERROR (Status) || EFI_ERROR (Status2)) {
DEBUG ((DEBUG_ERROR, "OCKM: Uninstall failed: %r/%r\n", Status, Status2));
return FALSE;
}
} else {
Status = gBS->LocateProtocol (
&gAppleKeyMapDatabaseProtocolGuid,
NULL,
(VOID *)&Database
);
Status2 = gBS->LocateProtocol (
&gAppleKeyMapAggregatorProtocolGuid,
NULL,
(VOID *)&Aggregator
);
if (!EFI_ERROR (Status) && !EFI_ERROR (Status2)) {
*KeyMapDatabase = Database;
*KeyMapAggregator = Aggregator;
return TRUE;
} else if (!EFI_ERROR (Status) || !EFI_ERROR (Status2)) {
return FALSE;
}
}
KeyMapAggregatorData = AllocateZeroPool (sizeof (*KeyMapAggregatorData));
if (KeyMapAggregatorData == NULL) {
return FALSE;
}
KeyMapAggregatorData->Signature = KEY_MAP_AGGREGATOR_DATA_SIGNATURE;
KeyMapAggregatorData->NextKeyStrokeIndex = 3000;
KeyMapAggregatorData->Database.Revision = APPLE_KEY_MAP_DATABASE_PROTOCOL_REVISION;
KeyMapAggregatorData->Database.CreateKeyStrokesBuffer = InternalCreateKeyStrokesBuffer;
KeyMapAggregatorData->Database.RemoveKeyStrokesBuffer = InternalRemoveKeyStrokesBuffer;
KeyMapAggregatorData->Database.SetKeyStrokeBufferKeys = InternalSetKeyStrokeBufferKeys;
KeyMapAggregatorData->Aggregator.Revision = APPLE_KEY_MAP_AGGREGATOR_PROTOCOL_REVISION;
KeyMapAggregatorData->Aggregator.GetKeyStrokes = InternalGetKeyStrokes;
KeyMapAggregatorData->Aggregator.ContainsKeyStrokes = InternalContainsKeyStrokes;
InitializeListHead (&KeyMapAggregatorData->KeyStrokesInfoList);
Status = gBS->InstallMultipleProtocolInterfaces (
&gImageHandle,
&gAppleKeyMapDatabaseProtocolGuid,
(VOID *)&KeyMapAggregatorData->Database,
&gAppleKeyMapAggregatorProtocolGuid,
(VOID *)&KeyMapAggregatorData->Aggregator,
NULL
);
if (EFI_ERROR (Status)) {
FreePool (KeyMapAggregatorData);
return FALSE;
}
*KeyMapDatabase = &KeyMapAggregatorData->Database;
*KeyMapAggregator = &KeyMapAggregatorData->Aggregator;
return TRUE;
}
## @file
#
# Component description file for the library producing the Apple Event protocol.
#
# Copyright (C) 2019, Download-Fritz. All rights reserved.<BR>
#
# All rights reserved.
#
# This program and the accompanying materials
# are licensed and made available under the terms and conditions of the BSD License
# which accompanies this distribution. The full text of the license may be found at
# http://opensource.org/licenses/bsd-license.php
#
# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
#
##
[Defines]
INF_VERSION = 0x00010005
BASE_NAME = OcAppleKeyMapLib
FILE_GUID = 3A5CA054-2A65-4A00-AE58-B61BAFD6CF9A
MODULE_TYPE = DXE_DRIVER
VERSION_STRING = 1.0
LIBRARY_CLASS = OcAppleKeyMapLib|DXE_DRIVER DXE_RUNTIME_DRIVER UEFI_DRIVER UEFI_APPLICATION DXE_SMM_DRIVER
#
# The following information is for reference only and not required by the build tools.
#
# VALID_ARCHITECTURES = IA32 X64 IPF EBC
#
[Sources]
OcAppleKeyMapLib.c
[Packages]
OcSupportPkg/OcSupportPkg.dec
MdePkg/MdePkg.dec
EfiPkg/EfiPkg.dec
[Protocols]
gAppleKeyMapDatabaseProtocolGuid ## SOMETIMES_PRODUCES
gAppleKeyMapAggregatorProtocolGuid ## SOMETIMES_PRODUCES
[LibraryClasses]
BaseLib
BaseMemoryLib
DebugLib
OcMiscLib
MemoryAllocationLib
UefiBootServicesTableLib
......@@ -89,6 +89,9 @@
## @libraryclass
OcAppleDiskImageLib|Include/Library/OcAppleDiskImageLib.h
## @libraryclass
OcAppleEventLib|Include/Library/OcAppleEventLib.h
## @libraryclass
OcAppleImageConversionLib|Include/Library/OcAppleImageConversionLib.h
......@@ -98,6 +101,9 @@
## @libraryclass
OcAppleKernelLib|Include/Library/OcAppleKernelLib.h
## @libraryclass
OcAppleKeyMapLib|Include/Library/OcAppleKeyMapLib.h
## @libraryclass
OcAppleKeysLib|Include/Library/OcAppleKeysLib.h
......
......@@ -56,9 +56,11 @@
OcAppleChunklistLib|OcSupportPkg/Library/OcAppleChunklistLib/OcAppleChunklistLib.inf
OcAppleDerLib|OcSupportPkg/Library/OcAppleDerLib/OcAppleDerLib.inf
OcAppleDiskImageLib|OcSupportPkg/Library/OcAppleDiskImageLib/OcAppleDiskImageLib.inf
OcAppleEventLib|OcSupportPkg/Library/OcAppleEventLib/OcAppleEventLib.inf
OcAppleImageConversionLib|OcSupportPkg/Library/OcAppleImageConversionLib/OcAppleImageConversionLib.inf
OcAppleImageVerificationLib|OcSupportPkg/Library/OcAppleImageVerificationLib/OcAppleImageVerificationLib.inf
OcAppleKernelLib|OcSupportPkg/Library/OcAppleKernelLib/OcAppleKernelLib.inf
OcAppleKeyMapLib|OcSupportPkg/Library/OcAppleKeyMapLib/OcAppleKeyMapLib.inf
OcAppleKeysLib|OcSupportPkg/Library/OcAppleKeysLib/OcAppleKeysLib.inf
OcAppleRamDiskLib|OcSupportPkg/Library/OcAppleRamDiskLib/OcAppleRamDiskLib.inf
OcAppleSecureBootLib|OcSupportPkg/Library/OcAppleSecureBootLib/OcAppleSecureBootLib.inf
......@@ -99,9 +101,11 @@
OcSupportPkg/Library/OcAppleChunklistLib/OcAppleChunklistLib.inf
OcSupportPkg/Library/OcAppleDerLib/OcAppleDerLib.inf
OcSupportPkg/Library/OcAppleDiskImageLib/OcAppleDiskImageLib.inf
OcSupportPkg/Library/OcAppleEventLib/OcAppleEventLib.inf
OcSupportPkg/Library/OcAppleImageConversionLib/OcAppleImageConversionLib.inf
OcSupportPkg/Library/OcAppleImageVerificationLib/OcAppleImageVerificationLib.inf
OcSupportPkg/Library/OcAppleKernelLib/OcAppleKernelLib.inf
OcSupportPkg/Library/OcAppleKeyMapLib/OcAppleKeyMapLib.inf
OcSupportPkg/Library/OcAppleRamDiskLib/OcAppleRamDiskLib.inf
OcSupportPkg/Library/OcAppleSecureBootLib/OcAppleSecureBootLib.inf
OcSupportPkg/Library/OcAppleUserInterfaceThemeLib/OcAppleUserInterfaceThemeLib.inf
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册