From 9af9dc134395c8bdfb8ac4fde65e18922a57fd09 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marvin=20H=C3=A4user?= <8659494+mhaeuser@users.noreply.github.com> Date: Thu, 1 Apr 2021 12:41:51 +0200 Subject: [PATCH] OpenCanopy: Support VoiceOver for TAB navigation --- Include/Acidanthera/Protocol/OcAudio.h | 4 +- Library/OcMainLib/OpenCoreUefiAudio.c | 6 +++ Platform/OpenCanopy/GuiApp.h | 8 ++++ Platform/OpenCanopy/OpenCanopy.c | 64 ++++++++++++++++++++++---- Platform/OpenCanopy/Views/BootPicker.c | 4 ++ Platform/OpenCanopy/Views/Common.c | 11 +++++ Platform/OpenCanopy/Views/Password.c | 3 ++ 7 files changed, 90 insertions(+), 10 deletions(-) diff --git a/Include/Acidanthera/Protocol/OcAudio.h b/Include/Acidanthera/Protocol/OcAudio.h index 49238a45..9fbbd3c1 100644 --- a/Include/Acidanthera/Protocol/OcAudio.h +++ b/Include/Acidanthera/Protocol/OcAudio.h @@ -102,8 +102,10 @@ typedef enum { OcVoiceOverAudioFileUEFI_Shell = 0x1047, OcVoiceOverAudioFileWelcome = 0x1048, OcVoiceOverAudioFileWindows = 0x1049, + OcVoiceOverAudioFileShutDown = 0x104A, + OcVoiceOverAudioFileRestart = 0x104B, - OcVoiceOverAudioFileMax = 0x104A, + OcVoiceOverAudioFileMax = 0x104C, } OC_VOICE_OVER_AUDIO_FILE; STATIC_ASSERT (OcVoiceOverAudioFileIndexMax - OcVoiceOverAudioFileIndexBase == 9 + 26, "Invalid index count"); diff --git a/Library/OcMainLib/OpenCoreUefiAudio.c b/Library/OcMainLib/OpenCoreUefiAudio.c index 754bcf7c..4d26d2b3 100644 --- a/Library/OcMainLib/OpenCoreUefiAudio.c +++ b/Library/OcMainLib/OpenCoreUefiAudio.c @@ -168,6 +168,12 @@ OcAudioGetFilePath ( case OcVoiceOverAudioFileWindows: BasePath = "Windows"; break; + case OcVoiceOverAudioFileShutDown: + BasePath = "ShutDown"; + break; + case OcVoiceOverAudioFileRestart: + BasePath = "Restart"; + break; default: BasePath = NULL; break; diff --git a/Platform/OpenCanopy/GuiApp.h b/Platform/OpenCanopy/GuiApp.h index bd1fed2b..bff8779a 100644 --- a/Platform/OpenCanopy/GuiApp.h +++ b/Platform/OpenCanopy/GuiApp.h @@ -100,6 +100,13 @@ typedef enum { ICON_TYPE_COUNT = 2, } ICON_TYPE; +enum { + CanopyVoSelectedEntry, + CanopyVoFocusPassword, + CanopyVoFocusShutDown, + CanopyVoFocusRestart +}; + typedef struct _BOOT_PICKER_GUI_CONTEXT { GUI_IMAGE Background; GUI_IMAGE Icons[ICON_NUM_TOTAL][ICON_TYPE_COUNT]; @@ -114,6 +121,7 @@ typedef struct _BOOT_PICKER_GUI_CONTEXT { BOOLEAN DoneIntroAnimation; BOOLEAN ReadyToBoot; UINT8 Scale; + UINT8 VoAction; INT32 CursorOffsetX; INT32 CursorOffsetY; INT32 AudioPlaybackTimeout; diff --git a/Platform/OpenCanopy/OpenCanopy.c b/Platform/OpenCanopy/OpenCanopy.c index 29ee8f55..acb43e86 100644 --- a/Platform/OpenCanopy/OpenCanopy.c +++ b/Platform/OpenCanopy/OpenCanopy.c @@ -1206,15 +1206,61 @@ GuiDrawLoop ( 1000000 )); if (DrawContext->GuiContext->AudioPlaybackTimeout <= 0) { - DrawContext->GuiContext->PickerContext->PlayAudioFile ( - DrawContext->GuiContext->PickerContext, - OcVoiceOverAudioFileSelected, - FALSE - ); - DrawContext->GuiContext->PickerContext->PlayAudioEntry ( - DrawContext->GuiContext->PickerContext, - DrawContext->GuiContext->BootEntry - ); + switch (DrawContext->GuiContext->VoAction) { + case CanopyVoSelectedEntry: + { + DrawContext->GuiContext->PickerContext->PlayAudioFile ( + DrawContext->GuiContext->PickerContext, + OcVoiceOverAudioFileSelected, + FALSE + ); + DrawContext->GuiContext->PickerContext->PlayAudioEntry ( + DrawContext->GuiContext->PickerContext, + DrawContext->GuiContext->BootEntry + ); + break; + } + + case CanopyVoFocusPassword: + { + DrawContext->GuiContext->PickerContext->PlayAudioFile ( + DrawContext->GuiContext->PickerContext, + OcVoiceOverAudioFileEnterPassword, + TRUE + ); + break; + } + + case CanopyVoFocusShutDown: + { + DrawContext->GuiContext->PickerContext->PlayAudioFile ( + DrawContext->GuiContext->PickerContext, + OcVoiceOverAudioFileShutDown, + TRUE + ); + break; + } + + case CanopyVoFocusRestart: + { + DrawContext->GuiContext->PickerContext->PlayAudioFile ( + DrawContext->GuiContext->PickerContext, + OcVoiceOverAudioFileRestart, + TRUE + ); + break; + } + + default: + { + ASSERT (FALSE); + break; + } + } + // + // Avoid playing twice if we reach precisely 0. + // + DrawContext->GuiContext->AudioPlaybackTimeout = -1; } } diff --git a/Platform/OpenCanopy/Views/BootPicker.c b/Platform/OpenCanopy/Views/BootPicker.c index af7b1131..1ee16612 100644 --- a/Platform/OpenCanopy/Views/BootPicker.c +++ b/Platform/OpenCanopy/Views/BootPicker.c @@ -211,6 +211,7 @@ InternalBootPickerSelectEntry ( // Set voice timeout to N frames from now. // DrawContext->GuiContext->AudioPlaybackTimeout = OC_VOICE_OVER_IDLE_TIMEOUT_MS; + DrawContext->GuiContext->VoAction = CanopyVoSelectedEntry; DrawContext->GuiContext->BootEntry = NewEntry->Context; } } @@ -1057,6 +1058,9 @@ InternalBootPickerFocus ( mBootPickerSelectorContainer.Obj.Opacity = 0; } else { mBootPickerSelectorContainer.Obj.Opacity = 0xFF; + + DrawContext->GuiContext->AudioPlaybackTimeout = 0; + DrawContext->GuiContext->VoAction = CanopyVoSelectedEntry; } GuiRequestDraw ( diff --git a/Platform/OpenCanopy/Views/Common.c b/Platform/OpenCanopy/Views/Common.c index ad33200e..737604a9 100644 --- a/Platform/OpenCanopy/Views/Common.c +++ b/Platform/OpenCanopy/Views/Common.c @@ -1,5 +1,7 @@ #include +#include + #include #include "../OpenCanopy.h" @@ -546,6 +548,15 @@ InternalCommonActionButtonFocus ( mCommonFocus.Obj.OffsetX = This->OffsetX + ((INT32) This->Width - (INT32) mCommonFocus.Obj.Width) / 2; mCommonFocus.Obj.OffsetY = This->OffsetY + ((INT32) This->Height - (INT32) mCommonFocus.Obj.Height) / 2; + + DrawContext->GuiContext->AudioPlaybackTimeout = 0; + + if (This == &mCommonShutDown.Hdr.Obj) { + DrawContext->GuiContext->VoAction = CanopyVoFocusShutDown; + } else { + ASSERT (This == &mCommonRestart.Hdr.Obj); + DrawContext->GuiContext->VoAction = CanopyVoFocusRestart; + } } GuiRequestDrawCrop ( diff --git a/Platform/OpenCanopy/Views/Password.c b/Platform/OpenCanopy/Views/Password.c index 402ff23e..49680ad7 100644 --- a/Platform/OpenCanopy/Views/Password.c +++ b/Platform/OpenCanopy/Views/Password.c @@ -343,6 +343,9 @@ InternalPasswordBoxFocus ( { if (Focus) { mPasswordBoxContainer.Obj.Opacity = 0xFF; + + DrawContext->GuiContext->AudioPlaybackTimeout = 0; + DrawContext->GuiContext->VoAction = CanopyVoFocusPassword; } else { mPasswordBoxContainer.Obj.Opacity = 0x100 / 2; }