X-Git-Url: https://code.delx.au/refind/blobdiff_plain/a0a4ba44f4dc01c86499c0fc80730940b53f75c6..e0f6b77e5692ec112bb803202ae27f8c5d55de50:/refind/menu.c diff --git a/refind/menu.c b/refind/menu.c index 700f7d8..5f76da4 100644 --- a/refind/menu.c +++ b/refind/menu.c @@ -486,7 +486,7 @@ static UINTN RunGenericMenu(IN REFIT_MENU_SCREEN *Screen, IN MENU_STYLE_FUNC Sty if (ChosenEntry) *ChosenEntry = Screen->Entries[State.CurrentSelection]; return MenuExit; -} /* static UINTN RunGenericMenu( */ +} /* static UINTN RunGenericMenu() */ // // text-mode generic style @@ -526,10 +526,24 @@ static VOID TextMenuStyle(IN REFIT_MENU_SCREEN *Screen, IN SCROLL_STATE *State, // prepare strings for display DisplayStrings = AllocatePool(sizeof(CHAR16 *) * Screen->EntryCount); for (i = 0; i <= State->MaxIndex; i++) { - DisplayStrings[i] = AllocateZeroPool(256 * sizeof(CHAR16)); - SPrint(DisplayStrings[i], 255, L" %-.*s ", MenuWidth, Screen->Entries[i]->Title); - // TODO: use more elaborate techniques for shortening too long strings (ellipses in the middle) - // TODO: account for double-width characters + // Note: Theoretically, SPrint() is a cleaner way to do this; but the + // description of the StrSize parameter to SPrint implies it's measured + // in characters, but in practice both TianoCore and GNU-EFI seem to + // use bytes instead, resulting in truncated displays. I could just + // double the size of the StrSize parameter, but that seems unsafe in + // case a future library change starts treating this as characters, so + // I'm doing it the hard way in this instance. + // TODO: Review the above and possibly change other uses of SPrint() + DisplayStrings[i] = AllocateZeroPool(2 * sizeof(CHAR16)); + DisplayStrings[i][0] = L' '; + MergeStrings(&DisplayStrings[i], Screen->Entries[i]->Title, 0); + if (StrLen(DisplayStrings[i]) > MenuWidth) + DisplayStrings[i][MenuWidth - 1] = 0; +// DisplayStrings[i] = AllocateZeroPool(256 * sizeof(CHAR16)); +// SPrint(DisplayStrings[i], ((MenuWidth < 255) ? MenuWidth : 255) * sizeof(CHAR16), +// L" %s ", Screen->Entries[i]->Title); + // TODO: use more elaborate techniques for shortening too long strings (ellipses in the middle) + // TODO: account for double-width characters } // for // initial painting @@ -705,7 +719,7 @@ static VOID GraphicsMenuStyle(IN REFIT_MENU_SCREEN *Screen, IN SCROLL_STATE *Sta break; } -} +} // static VOID GraphicsMenuStyle() // // graphical main menu style @@ -901,7 +915,39 @@ VOID MainMenuStyle(IN REFIT_MENU_SCREEN *Screen, IN SCROLL_STATE *State, IN UINT break; } -} +} // VOID MainMenuStyle() + +// Enable the user to edit boot loader options. +// Returns TRUE if the user exited with edited options; FALSE if the user +// pressed Esc to terminate the edit. +static BOOLEAN EditOptions(LOADER_ENTRY *MenuEntry) { + UINTN x_max, y_max; + CHAR16 *EditedOptions; +// CHAR16 message[] = L"Use cursor keys to edit, Esc to exit, Enter to boot with edited options"; + EG_PIXEL DarkBackgroundPixel = { 0x0, 0x0, 0x0, 0 }; + BOOLEAN retval = FALSE; + + refit_call4_wrapper(ST->ConOut->QueryMode, ST->ConOut, ST->ConOut->Mode->Mode, &x_max, &y_max); + + if (!GlobalConfig.TextOnly) + SwitchToText(TRUE); + + egClearScreen(&DarkBackgroundPixel); + + refit_call3_wrapper(ST->ConOut->SetCursorPosition, ST->ConOut, 0, y_max - 1); +// refit_call2_wrapper(ST->ConOut->OutputString, ST->ConOut, message); + refit_call2_wrapper(ST->ConOut->OutputString, ST->ConOut, + L"Use cursor keys to edit, Esc to exit, Enter to boot with edited options"); + + if (line_edit(MenuEntry->LoadOptions, &EditedOptions, x_max, 1)) { + MyFreePool(MenuEntry->LoadOptions); + MenuEntry->LoadOptions = EditedOptions; + retval = TRUE; + } // if + if (!GlobalConfig.TextOnly) + SwitchToGraphics(); + return retval; +} // VOID EditOptions() // // user-callable dispatcher functions @@ -944,6 +990,10 @@ UINTN RunMainMenu(IN REFIT_MENU_SCREEN *Screen, IN CHAR16* DefaultSelection, OUT MenuExit = RunGenericMenu(TempChosenEntry->SubScreen, Style, -1, &TempChosenEntry); if (MenuExit == MENU_EXIT_ESCAPE || TempChosenEntry->Tag == TAG_RETURN) MenuExit = 0; + if (MenuExit == MENU_EXIT_DETAILS) { + if (!EditOptions((LOADER_ENTRY *) TempChosenEntry)) + MenuExit = 0; + } // if } }