]> code.delx.au - refind/blobdiff - refind/menu.c
Improvements to install.sh; check for valid loader for MOK and memory
[refind] / refind / menu.c
index 427deda0f70121e6f88903d88f5c0ee42911da71..ab39137035cead101f3296d7b2fe022b0a40a4dd 100644 (file)
@@ -361,12 +361,12 @@ static UINTN RunGenericMenu(IN REFIT_MENU_SCREEN *Screen, IN MENU_STYLE_FUNC Sty
     UINTN index;
     INTN ShortcutEntry;
     BOOLEAN HaveTimeout = FALSE;
+    BOOLEAN WaitForRelease = FALSE;
     UINTN TimeoutCountdown = 0;
     INTN PreviousTime = -1, CurrentTime, TimeSinceKeystroke = 0;
     CHAR16 TimeoutMessage[256];
     CHAR16 KeyAsString[2];
     UINTN MenuExit;
-//     EG_PIXEL Black = { 0x0, 0x0, 0x0, 0 };
 
     if (Screen->TimeoutSeconds > 0) {
         HaveTimeout = TRUE;
@@ -382,6 +382,25 @@ static UINTN RunGenericMenu(IN REFIT_MENU_SCREEN *Screen, IN MENU_STYLE_FUNC Sty
         if (GlobalConfig.ScreensaverTime != -1)
            UpdateScroll(&State, SCROLL_NONE);
     }
+
+    if (Screen->TimeoutSeconds == -1) {
+        Status = refit_call2_wrapper(ST->ConIn->ReadKeyStroke, ST->ConIn, &key);
+        if (Status == EFI_NOT_READY) {
+            MenuExit = MENU_EXIT_TIMEOUT;
+        } else {
+            KeyAsString[0] = key.UnicodeChar;
+            KeyAsString[1] = 0;
+            ShortcutEntry = FindMenuShortcutEntry(Screen, KeyAsString);
+            if (ShortcutEntry >= 0) {
+                State.CurrentSelection = ShortcutEntry;
+                MenuExit = MENU_EXIT_ENTER;
+            } else {
+                WaitForRelease = TRUE;
+                HaveTimeout = FALSE;
+            }
+        }
+    }
+
     if (GlobalConfig.ScreensaverTime != -1)
         State.PaintAll = TRUE;
 
@@ -395,6 +414,19 @@ static UINTN RunGenericMenu(IN REFIT_MENU_SCREEN *Screen, IN MENU_STYLE_FUNC Sty
             State.PaintSelection = FALSE;
         }
 
+        if (WaitForRelease) {
+            Status = refit_call2_wrapper(ST->ConIn->ReadKeyStroke, ST->ConIn, &key);
+            if (Status == EFI_SUCCESS) {
+                // reset, because otherwise the buffer gets queued with keystrokes
+                refit_call2_wrapper(ST->ConIn->Reset, ST->ConIn, FALSE);
+                refit_call1_wrapper(BS->Stall, 100000);
+            } else {
+                WaitForRelease = FALSE;
+                refit_call2_wrapper(ST->ConIn->Reset, ST->ConIn, TRUE);
+            }
+            continue;
+        }
+
         if (HaveTimeout) {
             CurrentTime = (TimeoutCountdown + 5) / 10;
             if (CurrentTime != PreviousTime) {
@@ -980,7 +1012,7 @@ static VOID PaintSelection(IN REFIT_MENU_SCREEN *Screen, IN SCROLL_STATE *State,
 } // static VOID MoveSelection(VOID)
 
 // Display a 48x48 icon at the specified location. Uses the image specified by
-// ExternalFilename if it's available, or BuiltInImage if it's not. The 
+// ExternalFilename if it's available, or BuiltInImage if it's not. The
 // Y position is specified as the center value, and so is adjusted by half
 // the icon's height. The X position is set along the icon's left
 // edge if Alignment == ALIGN_LEFT, and along the right edge if
@@ -1156,11 +1188,12 @@ UINTN RunMenu(IN REFIT_MENU_SCREEN *Screen, OUT REFIT_MENU_ENTRY **ChosenEntry)
     return RunGenericMenu(Screen, Style, &DefaultEntry, ChosenEntry);
 }
 
-UINTN RunMainMenu(IN REFIT_MENU_SCREEN *Screen, IN CHAR16* DefaultSelection, OUT REFIT_MENU_ENTRY **ChosenEntry)
+UINTN RunMainMenu(REFIT_MENU_SCREEN *Screen, CHAR16** DefaultSelection, REFIT_MENU_ENTRY **ChosenEntry)
 {
     MENU_STYLE_FUNC Style = TextMenuStyle;
     MENU_STYLE_FUNC MainStyle = TextMenuStyle;
     REFIT_MENU_ENTRY *TempChosenEntry;
+    CHAR16 *MenuTitle;
     UINTN MenuExit = 0;
     INTN DefaultEntryIndex = -1;
     INTN DefaultSubmenuIndex = -1;
@@ -1168,9 +1201,9 @@ UINTN RunMainMenu(IN REFIT_MENU_SCREEN *Screen, IN CHAR16* DefaultSelection, OUT
     TileSizes[0] = (GlobalConfig.IconSizes[ICON_SIZE_BIG] * 9) / 8;
     TileSizes[1] = (GlobalConfig.IconSizes[ICON_SIZE_SMALL] * 4) / 3;
 
-    if (DefaultSelection != NULL) {
+    if ((DefaultSelection != NULL) && (*DefaultSelection != NULL)) {
         // Find a menu entry that includes *DefaultSelection as a substring
-        DefaultEntryIndex = FindMenuShortcutEntry(Screen, DefaultSelection);
+        DefaultEntryIndex = FindMenuShortcutEntry(Screen, *DefaultSelection);
     }
 
     if (AllowGraphicsMode) {
@@ -1182,6 +1215,7 @@ UINTN RunMainMenu(IN REFIT_MENU_SCREEN *Screen, IN CHAR16* DefaultSelection, OUT
         MenuExit = RunGenericMenu(Screen, MainStyle, &DefaultEntryIndex, &TempChosenEntry);
         Screen->TimeoutSeconds = 0;
 
+        MenuTitle = StrDuplicate(TempChosenEntry->Title);
         if (MenuExit == MENU_EXIT_DETAILS) {
             if (TempChosenEntry->SubScreen != NULL) {
                MenuExit = RunGenericMenu(TempChosenEntry->SubScreen, Style, &DefaultSubmenuIndex, &TempChosenEntry);
@@ -1199,5 +1233,9 @@ UINTN RunMainMenu(IN REFIT_MENU_SCREEN *Screen, IN CHAR16* DefaultSelection, OUT
 
     if (ChosenEntry)
         *ChosenEntry = TempChosenEntry;
+    if (DefaultSelection) {
+       MyFreePool(*DefaultSelection);
+       *DefaultSelection = MenuTitle;
+    } // if
     return MenuExit;
 } /* UINTN RunMainMenu() */