15#include <Library/BaseLib.h>
16#include <Library/MemoryAllocationLib.h>
25#include <Library/UefiBootServicesTableLib.h>
26#include <Library/UefiRuntimeServicesTableLib.h>
40 IN EFI_HANDLE BootEntryProtocolHandle,
49 ApplyHotkeysContext = Context;
51 if (BootEntryProtocol->CheckHotKeys) {
52 BootId = BootEntryProtocol->CheckHotKeys (
56 ApplyHotkeysContext->
Keys
60 PickerContext->HotKeyProtocolHandle = BootEntryProtocolHandle;
61 PickerContext->HotKeyEntryId = BootId;
63 ApplyHotkeysContext->
Result = EFI_SUCCESS;
81 EFI_HANDLE *EntryProtocolHandles;
82 UINTN EntryProtocolHandleCount;
85 ApplyHotkeysContext.
NumKeys = NumKeys;
86 ApplyHotkeysContext.
Modifiers = Modifiers;
87 ApplyHotkeysContext.
Keys = Keys;
88 ApplyHotkeysContext.
Result = EFI_NOT_FOUND;
95 EntryProtocolHandleCount,
102 return ApplyHotkeysContext.
Result;
131 if (Context->TakeoffDelay > 0) {
132 gBS->Stall (Context->TakeoffDelay);
145 if (EFI_ERROR (Status)) {
146 DEBUG ((DEBUG_ERROR,
"OCHK: GetKeyStrokes - %r\n", Status));
162 if (!EFI_ERROR (Status)) {
177 if (HasCommand && HasKeyR) {
178 DEBUG ((DEBUG_INFO,
"OCHK: CMD+R causes recovery to boot\n"));
180 }
else if (HasKeyX) {
181 DEBUG ((DEBUG_INFO,
"OCHK: X causes macOS to boot\n"));
183 }
else if (HasOption) {
184 DEBUG ((DEBUG_INFO,
"OCHK: OPT causes picker to show\n"));
186 }
else if (HasEscape || HasZero) {
187 DEBUG ((DEBUG_INFO,
"OCHK: ESC/0 causes picker to show as OC extension\n"));
230 UINTN NumKeysDoNotRepeat;
246 BOOLEAN WantsZeroSlide;
247 UINT32 CsrActiveConfig;
248 UINTN CsrActiveConfigSize;
250 ASSERT (Context->HotKeyContext->KeyMap != NULL);
251 ASSERT (Context->HotKeyContext->TypingContext != NULL);
252 ASSERT (Context->HotKeyContext->DoNotRepeatContext != NULL);
253 ASSERT (PickerKeyInfo != NULL);
257 PickerKeyInfo->UnicodeChar = CHAR_NULL;
263 Status = Context->HotKeyContext->KeyMap->GetKeyStrokes (
264 Context->HotKeyContext->KeyMap,
270 if (EFI_ERROR (Status)) {
271 DEBUG ((DEBUG_WARN,
"OCHK: AKMA GetKeyStrokes - %r\n", Status));
290 NumKeysDoNotRepeat =
ARRAY_SIZE (KeysDoNotRepeat);
292 Context->HotKeyContext->DoNotRepeatContext,
293 &ModifiersDoNotRepeat,
301 if (EFI_ERROR (Status)) {
302 DEBUG ((DEBUG_WARN,
"OCHK: GetUpDownKeys for DoNotRepeatContext - %r\n", Status));
307 if (Context->KbDebug != NULL) {
308 Context->KbDebug->Show (NumKeys, AkmaNumKeys, Modifiers);
318 if (Context->AllowSetDefault) {
338 if ( ((Modifiers & ~ValidBootModifiers) == 0)
348 if ( Context->AllowSetDefault
387 if (HasCommand && HasKeyV) {
389 DEBUG ((DEBUG_INFO,
"OCHK: CMD+V means -v\n"));
399 if (HasCommand && HasKeyC && HasKeyMinus) {
401 DEBUG ((DEBUG_INFO,
"OCHK: CMD+C+MINUS means -no_compat_check\n"));
411 if (HasCommand && HasKeyK) {
412 if (AsciiStrStr (Context->AppleBootArgs,
"kcsuffix=release") == NULL) {
413 DEBUG ((DEBUG_INFO,
"OCHK: CMD+K means kcsuffix=release\n"));
430 if (HasCommand && HasKeyS) {
431 WantsZeroSlide = HasKeyMinus;
433 if (WantsZeroSlide) {
435 CsrActiveConfigSize =
sizeof (CsrActiveConfig);
436 Status =
gRT->GetVariable (
437 L
"csr-active-config",
440 &CsrActiveConfigSize,
451 if (WantsZeroSlide) {
452 if (AsciiStrStr (Context->AppleBootArgs,
"slide=0") == NULL) {
453 DEBUG ((DEBUG_INFO,
"OCHK: CMD+S+MINUS means slide=0\n"));
457 DEBUG ((DEBUG_INFO,
"OCHK: CMD+S means -s\n"));
551 if ((Modifiers & ~ValidBootModifiers) == 0) {
581 DEBUG ((DEBUG_INFO,
"OCHK: Shift means -x\n"));
679 UINT64 LoopDelayStart;
682 OldOcModifiers = PickerKeyInfo->OcModifiers;
698 (PickerKeyInfo->OcModifiers != OldOcModifiers) ||
699 (PickerKeyInfo->UnicodeChar != CHAR_NULL))
706 if ((CurrTime != 0) && (CurrTime >= EndTime)) {
719 if (Context->KbDebug != NULL) {
720 Context->KbDebug->InstrumentLoopDelay (LoopDelayStart,
AsmReadTsc ());
726 return PickerKeyInfo->OcModifiers != OldOcModifiers;
739 DEBUG ((DEBUG_INFO,
"OCHK: InitHotKeys\n"));
746 Context->KbDebug = NULL;
748 Context->HotKeyContext = AllocatePool (
sizeof (*(Context->HotKeyContext)));
749 if (Context->HotKeyContext == NULL) {
750 return EFI_OUT_OF_RESOURCES;
762 if (Context->HotKeyContext->KeyMap == NULL) {
763 FreePool (Context->HotKeyContext);
764 Context->HotKeyContext = NULL;
765 return EFI_NOT_FOUND;
772 &Context->HotKeyContext->DoNotRepeatContext,
773 Context->HotKeyContext->KeyMap,
780 if (EFI_ERROR (Status)) {
781 DEBUG ((DEBUG_ERROR,
"OCHK: Init non-repeating context - %r\n", Status));
782 FreePool (Context->HotKeyContext);
783 Context->HotKeyContext = NULL;
792 if (EFI_ERROR (Status)) {
793 DEBUG ((DEBUG_ERROR,
"OCHK: Register typing handler - %r\n", Status));
795 FreePool (Context->HotKeyContext);
796 Context->HotKeyContext = NULL;
816 if (Context == NULL) {
820 DEBUG ((DEBUG_INFO,
"OCHK: FreeHotKeys\n"));
822 ASSERT (Context->HotKeyContext != NULL);
827 FreePool (Context->HotKeyContext);
828 Context->HotKeyContext = NULL;
#define CSR_ALLOW_UNRESTRICTED_NVRAM
#define APPLE_MODIFIER_RIGHT_OPTION
#define APPLE_MODIFIERS_NONE
#define APPLE_MODIFIERS_COMMAND
@ AppleHidUsbKbUsageKeyPadMinus
@ AppleHidUsbKbUsageKeyEnter
@ AppleHidUsbKbUsageKeySpaceBar
@ AppleHidUsbKbUsageKeyPgUp
@ AppleHidUsbKbUsageKeyEquals
@ AppleHidUsbKbUsageKeyRightArrow
@ AppleHidUsbKbUsageKeyF1
@ AppleHidUsbKbUsageKeyEnd
@ AppleHidUsbKbUsageKeyTab
@ AppleHidUsbKbUsageKeyDownArrow
@ AppleHidUsbKbUsageKeyUpArrow
@ AppleHidUsbKbUsageKeyHome
@ AppleHidUsbKbUsageKeyPgDn
@ AppleHidUsbKbUsageKeyEscape
@ AppleHidUsbKbUsageKeyBackSpace
@ AppleHidUsbKbUsageKeyReturn
@ AppleHidUsbKbUsageKeyMinus
@ AppleHidUsbKbUsageKeyF13
@ AppleHidUsbKbUsageKeyF5
@ AppleHidUsbKbUsageKeyOne
@ AppleHidUsbKbUsageKeyF12
@ AppleHidUsbKbUsageKeyF24
@ AppleHidUsbKbUsageKeyZero
@ AppleHidUsbKbUsageKeyPadEnter
@ AppleHidUsbKbUsageKeyNine
@ AppleHidUsbKbUsageKeyLeftArrow
APPLE_HID_USAGE APPLE_KEY_CODE
#define APPLE_MODIFIERS_CONTROL
UINT16 APPLE_MODIFIER_MAP
#define APPLE_MODIFIERS_SHIFT
#define APPLE_MODIFIER_LEFT_COMMAND
#define APPLE_MODIFIER_RIGHT_COMMAND
#define APPLE_MODIFIER_LEFT_OPTION
EFI_GUID gAppleKeyMapAggregatorProtocolGuid
#define ARRAY_SIZE(Array)
EFI_GUID gAppleBootVariableGuid
VOID OcFreeHotKeys(IN OC_PICKER_CONTEXT *Context)
STATIC BOOLEAN EFIAPI CheckHotKeysForProtocolInstance(IN OUT OC_PICKER_CONTEXT *PickerContext, IN EFI_HANDLE BootEntryProtocolHandle, IN OC_BOOT_ENTRY_PROTOCOL *BootEntryProtocol, IN VOID *Context)
EFI_STATUS OcInitHotKeys(IN OUT OC_PICKER_CONTEXT *Context)
STATIC EFI_STATUS ApplyBootEntryProtocolHotKeys(IN OUT OC_PICKER_CONTEXT *PickerContext, IN UINTN NumKeys, IN APPLE_MODIFIER_MAP Modifiers, IN APPLE_KEY_CODE *Keys)
STATIC VOID EFIAPI GetPickerKeyInfo(IN OUT OC_PICKER_CONTEXT *Context, IN OC_PICKER_KEY_MAP KeyFilter, OUT OC_PICKER_KEY_INFO *PickerKeyInfo)
STATIC UINT64 EFIAPI WaitForPickerKeyInfoGetEndTime(IN UINT64 Timeout)
STATIC BOOLEAN EFIAPI WaitForPickerKeyInfo(IN OUT OC_PICKER_CONTEXT *Context, IN UINT64 EndTime, IN OC_PICKER_KEY_MAP KeyFilter, IN OUT OC_PICKER_KEY_INFO *PickerKeyInfo)
VOID OcLoadPickerHotKeys(IN OUT OC_PICKER_CONTEXT *Context)
STATIC VOID EFIAPI PickerFlushTypingBuffer(IN OUT OC_PICKER_CONTEXT *Context)
#define OC_HELD_KEYS_DEFAULT_SIZE
EFI_STATUS OcInitKeyRepeatContext(OUT OC_KEY_REPEAT_CONTEXT **Context, IN APPLE_KEY_MAP_AGGREGATOR_PROTOCOL *KeyMap, IN UINTN MaxKeysHeld, IN UINT64 InitialDelay, IN UINT64 SubsequentDelay, IN BOOLEAN PreventInitialRepeat)
EFI_STATUS EFIAPI OcGetUpDownKeys(IN OUT OC_KEY_REPEAT_CONTEXT *RepeatContext, OUT APPLE_MODIFIER_MAP *Modifiers, IN OUT UINTN *NumKeysUp, OUT APPLE_KEY_CODE *KeysUp OPTIONAL, IN OUT UINTN *NumKeysDown, OUT APPLE_KEY_CODE *KeysDown OPTIONAL, IN UINT64 CurrentTime)
VOID OcFreeKeyRepeatContext(OC_KEY_REPEAT_CONTEXT **Context)
#define OC_KEY_MAP_DEFAULT_SIZE
BOOLEAN OcKeyMapHasKey(IN CONST APPLE_KEY_CODE *Keys, IN UINTN NumKeys, IN CONST APPLE_KEY_CODE KeyCode)
STATIC_ASSERT(BYTES_PER_PIXEL==sizeof(UINT32), "Non 4-byte pixels are unsupported!")
VOID OcConsumeBootEntryProtocol(IN OUT OC_PICKER_CONTEXT *PickerContext, IN EFI_HANDLE *EntryProtocolHandles, IN UINTN EntryProtocolHandleCount, IN OC_CONSUME_ENTRY_PROTOCOL_ACTION Action, IN VOID *Context)
#define OC_INPUT_TYPING_BACKSPACE
Clear last typed character while typing (press backspace)
#define OC_MODIFIERS_NONE
@ OcPickerBootAppleRecovery
#define OC_INPUT_TYPING_CONFIRM
Confirm input while typing (press enter)
#define OC_INPUT_DOWN
Move down.
#define OC_INPUT_NO_ACTION
Some other key.
#define OC_INPUT_TIMEOUT
Timeout.
#define OC_MODIFIERS_SET_DEFAULT
VOID OcLocateBootEntryProtocolHandles(IN OUT EFI_HANDLE **EntryProtocolHandles, IN OUT UINTN *EntryProtocolHandleCount)
#define OC_PICKER_KEYS_VOICE_OVER
#define OC_INPUT_TYPING_LEFT
Move left while typing (UI does not have to support)
#define OC_INPUT_LEFT
Move left.
#define OC_MODIFIERS_REVERSE_SWITCH_FOCUS
#define OC_INPUT_INTERNAL
Accepted internal hotkey (e.g. Apple)
VOID OcFreeBootEntryProtocolHandles(EFI_HANDLE **EntryProtocolHandles)
#define OC_INPUT_TYPING_RIGHT
Move right while typing (UI does not have to support)
#define OC_PICKER_KEYS_TAB_CONTROL
#define OC_INPUT_CONTINUE
Continue (press enter)
#define OC_PICKER_KEYS_HOTKEYS
#define OC_INPUT_ABORTED
Esc or 0.
CONST CHAR8 * OcGetArgumentFromCmd(IN CONST CHAR8 *CommandLine, IN CONST CHAR8 *Argument, IN CONST UINTN ArgumentLength, OUT UINTN *ValueLength OPTIONAL)
#define OC_INPUT_BOTTOM
Move to bottom.
#define OC_PICKER_KEYS_TYPING
#define OC_INPUT_MORE
Show more entries (press space)
#define OC_INPUT_SWITCH_FOCUS
Switch UI focus (tab and shift+tab)
#define OC_INPUT_FUNCTIONAL(x)
Function hotkeys.
#define OC_INPUT_RIGHT
Move right.
BOOLEAN OcAppendArgumentToCmd(IN OUT OC_PICKER_CONTEXT *Context OPTIONAL, IN OUT CHAR8 *CommandLine, IN CONST CHAR8 *Argument, IN CONST UINTN ArgumentLength)
#define OC_INPUT_UP
Move up.
#define OC_INPUT_TOP
Move to top.
#define OC_INPUT_VOICE_OVER
Toggle VoiceOver (press CMD+F5)
#define OC_INPUT_TYPING_CLEAR_ALL
Clear current input while typing (press esc)
#define ASSERT_EQUALS(Expression, ExpectedValue)
VOID * OcGetProtocol(IN EFI_GUID *Protocol, IN UINTN ErrorLevel, IN CONST CHAR8 *CallerName OPTIONAL, IN CONST CHAR8 *ProtocolName OPTIONAL)
#define L_STR_LEN(String)
#define OC_MINIMAL_CPU_DELAY
EFI_STATUS OcUnregisterTypingHandler(IN OC_TYPING_CONTEXT **Context)
EFI_STATUS OcRegisterTypingHandler(OUT OC_TYPING_CONTEXT **Context)
VOID OcGetNextKeystroke(IN OC_TYPING_CONTEXT *Context, OUT APPLE_MODIFIER_MAP *Modifiers, OUT APPLE_KEY_CODE *AppleKeyCode, OUT CHAR16 *UnicodeChar)
VOID OcFlushTypingBuffer(IN OC_TYPING_CONTEXT *Context)
EFI_RUNTIME_SERVICES * gRT
UINT64 EFIAPI AsmReadTsc(VOID)
UINT64 EFIAPI GetTimeInNanoSecond(IN UINT64 Ticks)
UINT64 EFIAPI GetPerformanceCounter(VOID)
UINTN EFIAPI MicroSecondDelay(IN UINTN MicroSeconds)
KEY_MAP_GET_KEY_STROKES GetKeyStrokes
APPLE_MODIFIER_MAP Modifiers