+0.5.2 (12/??/2012):
+-------------------
+
+- Added identifying screen header to line editor.
+
+- Added "textmode" refind.conf parameter to set the text mode used in
+ text-only displays, and for the line editor and boot-time handoff
+ display even in graphics mode.
+
+- Fixed bug that caused tools (shell, etc.) to launch when they were
+ highlighted and F2 or Insert was pressed.
+
+- Added hints text to rEFInd main menu and sub-menus. This can be disabled
+ by setting the new "hints" option to the "hideui" token in refind.conf.
+
+- Added "boot with minimal options" entry to refind_linux.conf file
+ generated by install.sh. This entry boots without the options extracted
+ from the /etc/default/grub file.
+
+- Fixed bug in install.sh that prevented creation of refind_linux.conf file
+ on Linux systems.
+
+0.5.1.1 (12/12/2012):
+---------------------
+
+- Fixed bug in install.sh that prevented it from working on OS X.
+
0.5.1 (12/11/2012):
-------------------
<td>None or <tt>0</tt></td>
<td>rEFInd defaults to a graphical mode; however, if you prefer to do without the flashy graphics, you can run it in text mode by including this option. Passing any option but <tt>0</tt> causes text mode to be used; passing a <tt>0</tt> causes graphics mode to be used. (This could be useful if you want to override a text-mode setting in an included secondary configuration file.)</td>
</tr>
+<tr>
+ <td><tt>textmode</tt></td>
+ <td>text mode number</td>
+ <td>Sets the text-mode video resolution to be used in conjunction with <tt>textonly</tt> or for the line editor and program-launch screens. This option takes a single-digit code. Mode <tt>0</tt> is guaranteed to be present and should be 80x25. Mode <tt>1</tt> is supposed to be either invalid or 80x50, but some systems use this number for something else. Higher values are system-specific. If you set this option to an invalid value, rEFInd pauses during startup to tell you of that fact. Note that on some computers, setting this value without also using <tt>textonly</tt> results in an incorrect graphics video mode being set. Pressing the Esc key corrects the problem.</td>
+</tr>
<tr>
<td><tt>resolution</tt></td>
<td>Two integer values</td>
#
# 0.5.2 -- Changed --drivers to --alldrivers and added --nodrivers option;
# changed default driver installation behavior in Linux to install
-# the driver needed to read /boot
+# the driver needed to read /boot (if available)
# 0.5.1.2 -- Fixed bug that caused failure to generate refind_linux.conf file
# 0.5.1.1 -- Fixed bug that caused script failure under OS X
# 0.5.1 -- Added --shim & --localkeys options & create sample refind_linux.conf
DefaultOptions="$GRUB_CMDLINE_LINUX $GRUB_CMDLINE_LINUX_DEFAULT"
echo "\"Boot with standard options\" \"ro root=$RootFS $DefaultOptions \"" > $RLConfFile
echo "\"Boot to single-user mode\" \"ro root=$RootFS $DefaultOptions single\"" >> $RLConfFile
+ echo "\"Boot with minimal options\" \"ro root=$RootFS\"" >> $RLConfFile
fi
}
VOID egDisplayMessage(IN CHAR16 *Text, EG_PIXEL *BGColor);
VOID egScreenShot(VOID);
//UINT32 egGetGraphicsMode(VOID);
-
+UINT32 egSetTextMode(UINT32 RequestedMode);
#endif /* __LIBEG_LIBEG_H__ */
#include "libegint.h"
#include "../refind/screen.h"
+#include "../refind/lib.h"
#include "../include/refit_call_wrapper.h"
#include <efiUgaDraw.h>
}
}
-// // Returns current graphics mode number
-// UINT32 egGetGraphicsMode(VOID) {
-// UINT32 retval = 0;
-//
-// if (GraphicsOutput != NULL) {
-// retval = GraphicsOutput->Mode->Mode;
-// }
-//
-// return retval;
-// } // UINT32 egGetGraphicsMode()
-
// Sets the screen resolution to the specified value, if possible.
// If the specified value is not valid, displays a warning with the valid
// modes on UEFI systems, or silently fails on EFI 1.x systems. Note that
if ((Status == EFI_SUCCESS) && (Size >= sizeof(*Info)) &&
(Info->HorizontalResolution == ScreenWidth) && (Info->VerticalResolution == ScreenHeight)) {
Status = refit_call2_wrapper(GraphicsOutput->SetMode, GraphicsOutput, ModeNum);
-// if (Status == EFI_SUCCESS)
-// Status = refit_call2_wrapper(ST->ConOut->SetMode, ST->ConOut, ModeNum);
ModeSet = (Status == EFI_SUCCESS);
} // if
ModeNum++;
egScreenHeight = ScreenHeight;
} else {// If unsuccessful, display an error message for the user....
SwitchToText(FALSE);
- Print(L"Error setting mode %d x %d; using default mode!\nAvailable modes are:\n", ScreenWidth, ScreenHeight);
+ Print(L"Error setting graphics mode %d x %d; using default mode!\nAvailable modes are:\n", ScreenWidth, ScreenHeight);
ModeNum = 0;
Status = EFI_SUCCESS;
while (Status == EFI_SUCCESS) {
// TODO: Find a list of supported modes and display it.
// NOTE: Below doesn't actually appear unless we explicitly switch to text mode.
// This is just a placeholder until something better can be done....
- Print(L"Error setting mode %d x %d; unsupported mode!\n");
+ Print(L"Error setting graphics mode %d x %d; unsupported mode!\n");
} // if/else
} // if/else if
return (ModeSet);
*ScreenHeight = egScreenHeight;
}
+// Set a text mode
+// Returns the mode that was actually set.
+UINT32 egSetTextMode(UINT32 RequestedMode) {
+ UINTN i = 0, Width, Height;
+ UINT32 UsedMode = ST->ConOut->Mode->Mode;
+ EFI_STATUS Status;
+ BOOLEAN GoOn = TRUE;
+
+ if (RequestedMode != ST->ConOut->Mode->Mode) {
+ Status = refit_call2_wrapper(ST->ConOut->SetMode, ST->ConOut, RequestedMode);
+ if (Status == EFI_SUCCESS) {
+ UsedMode = RequestedMode;
+ } else {
+ SwitchToText(FALSE);
+ Print(L"Error setting text mode %d; available modes are:\n", ST->ConOut->Mode->Mode);
+ while (GoOn) {
+ Status = refit_call4_wrapper(ST->ConOut->QueryMode, ST->ConOut, i, &Width, &Height);
+ if (Status == EFI_SUCCESS)
+ Print(L"Mode: %d: %d x %d\n", i, Width, Height);
+ else if (i > 1)
+ GoOn = 0;
+ i++;
+ }
+ PauseForKey();
+ SwitchToGraphics();
+ } // if/else successful change
+ } // if need to change mode
+ return UsedMode;
+} // UINT32 egSetTextMode()
+
CHAR16 * egScreenDescription(VOID)
{
- CHAR16 *Temp;
+ CHAR16 *GraphicsInfo, *TextInfo = NULL;
+
+ GraphicsInfo = AllocateZeroPool(256 * sizeof(CHAR16));
+ if (GraphicsInfo == NULL)
+ return L"memory allocation error";
if (egHasGraphics) {
if (GraphicsOutput != NULL) {
- Temp = AllocateZeroPool(256 * sizeof(CHAR16));
- SPrint(Temp, 255, L"Graphics Output (UEFI), %dx%d", egScreenWidth, egScreenHeight);
- return Temp;
+ SPrint(GraphicsInfo, 255, L"Graphics Output (UEFI), %dx%d", egScreenWidth, egScreenHeight);
} else if (UgaDraw != NULL) {
- Temp = AllocateZeroPool(256 * sizeof(CHAR16));
- SPrint(Temp, 255, L"UGA Draw (EFI 1.10), %dx%d", egScreenWidth, egScreenHeight);
- return Temp;
+ GraphicsInfo = AllocateZeroPool(256 * sizeof(CHAR16));
+ SPrint(GraphicsInfo, 255, L"UGA Draw (EFI 1.10), %dx%d", egScreenWidth, egScreenHeight);
} else {
+ MyFreePool(GraphicsInfo);
+ MyFreePool(TextInfo);
return L"Internal Error";
}
+ if (!AllowGraphicsMode) { // graphics-capable HW, but in text mode
+ TextInfo = AllocateZeroPool(256 * sizeof(CHAR16));
+ SPrint(TextInfo, 255, L"(in %dx%d text mode)", ConWidth, ConHeight);
+ MergeStrings(&GraphicsInfo, TextInfo, L' ');
+ }
} else {
- return L"Text Console";
+ SPrint(GraphicsInfo, 255, L"Text-foo console, %dx%d", ConWidth, ConHeight);
}
+ MyFreePool(TextInfo);
+ return GraphicsInfo;
}
BOOLEAN egHasGraphicsMode(VOID)
DefaultOptions="$GRUB_CMDLINE_LINUX $GRUB_CMDLINE_LINUX_DEFAULT"
echo "\"Boot with standard options\" \"ro root=$RootFS $DefaultOptions \"" > $RLConfFile
echo "\"Boot to single-user mode\" \"ro root=$RootFS $DefaultOptions single\"" >> $RLConfFile
+ echo "\"Boot with minimal options\" \"ro root=$RootFS\"" >> $RLConfFile
else
echo "Existing $RLConfFile found! Not overwriting!"
echo "To force overwriting, pass the --force option."
# Hide user interface elements for personal preference or to increase
# security:
# banner - the rEFInd title banner
-# label - text label in the menu
+# label - boot option text label in the menu
# singleuser - remove the submenu options to boot Mac OS X in single-user
# or verbose modes; affects ONLY MacOS X
# hwtest - the submenu option to run Apple's hardware test
# arrows - scroll arrows on the OS selection tag line
+# hints - brief command summary in the menu
# all - all of the above
#
#hideui singleuser
#
#textonly
+# Set the EFI text mode to be used for textual displays. This option
+# takes a single digit that refers to a mode number. The default is 0
+# (80x25), 1 is sometimes 80x50, and higher numbers are system-specific
+# modes. If you specify an invalid mode, rEFInd pauses during boot to
+# inform you of valid modes.
+# CAUTION: On VirtualBox, and perhaps on some real computers, specifying
+# a text mode and uncommenting the "textonly" option while NOT specifying
+# a resolution can result in an unusable display in the booted OS.
+# Default is 0
+#
+#textmode 2
+
# Set the screen's video resolution. Pass this option two values,
# corresponding to the X and Y resolutions. Note that not all resolutions
# are supported. On UEFI systems, passing an incorrect value results in a
GlobalConfig.HideUIFlags |= HIDEUI_FLAG_HWTEST;
} else if (StriCmp(FlagName, L"arrows") == 0) {
GlobalConfig.HideUIFlags |= HIDEUI_FLAG_ARROWS;
+ } else if (StriCmp(FlagName, L"hints") == 0) {
+ GlobalConfig.HideUIFlags |= HIDEUI_FLAG_HINTS;
} else if (StriCmp(FlagName, L"all") == 0) {
GlobalConfig.HideUIFlags = HIDEUI_ALL;
} else {
GlobalConfig.TextOnly = TRUE;
}
+ } else if (StriCmp(TokenList[0], L"textmode") == 0) {
+ HandleInt(TokenList, TokenCount, &(GlobalConfig.RequestedTextMode));
+
} else if ((StriCmp(TokenList[0], L"resolution") == 0) && (TokenCount == 3)) {
GlobalConfig.RequestedScreenWidth = Atoi(TokenList[1]);
GlobalConfig.RequestedScreenHeight = Atoi(TokenList[2]);
#define HIDEUI_FLAG_SINGLEUSER (0x0004)
#define HIDEUI_FLAG_HWTEST (0x0008)
#define HIDEUI_FLAG_ARROWS (0x0010)
+#define HIDEUI_FLAG_HINTS (0x0020)
#define HIDEUI_ALL ((0xffff))
#define CONFIG_FILE_NAME L"refind.conf"
BOOLEAN ScanAllLinux;
UINTN RequestedScreenWidth;
UINTN RequestedScreenHeight;
+ UINTN RequestedTextMode;
UINTN Timeout;
UINTN HideUIFlags;
UINTN MaxTags; // max. number of OS entries to show simultaneously in graphics mode
static REFIT_MENU_SCREEN MainMenu = { L"Main Menu", NULL, 0, NULL, 0, NULL, 0, L"Automatic boot" };
static REFIT_MENU_SCREEN AboutMenu = { L"About", NULL, 0, NULL, 0, NULL, 0, NULL };
-REFIT_CONFIG GlobalConfig = { FALSE, FALSE, 0, 0, 20, 0, 0, GRAPHICS_FOR_OSX, LEGACY_TYPE_MAC, 0,
+REFIT_CONFIG GlobalConfig = { FALSE, FALSE, 0, 0, 0, 20, 0, 0, GRAPHICS_FOR_OSX, LEGACY_TYPE_MAC, 0,
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
{TAG_SHELL, TAG_APPLE_RECOVERY, TAG_MOK_TOOL, TAG_ABOUT, TAG_SHUTDOWN, TAG_REBOOT, 0, 0, 0, 0, 0 }};
if (AboutMenu.EntryCount == 0) {
AboutMenu.TitleImage = BuiltinIcon(BUILTIN_ICON_FUNC_ABOUT);
- AddMenuInfoLine(&AboutMenu, L"rEFInd Version 0.5.1");
+ AddMenuInfoLine(&AboutMenu, L"rEFInd Version 0.5.1.3");
AddMenuInfoLine(&AboutMenu, L"");
AddMenuInfoLine(&AboutMenu, L"Copyright (c) 2006-2010 Christoph Pfisterer");
AddMenuInfoLine(&AboutMenu, L"Copyright (c) 2012 Roderick W. Smith");
#define MENU_FUNCTION_PAINT_ALL (2)
#define MENU_FUNCTION_PAINT_SELECTION (3)
#define MENU_FUNCTION_PAINT_TIMEOUT (4)
+#define MENU_FUNCTION_PAINT_HINTS (5)
typedef VOID (*MENU_STYLE_FUNC)(IN REFIT_MENU_SCREEN *Screen, IN SCROLL_STATE *State, IN UINTN Function, IN CHAR16 *ParamText);
State.CurrentSelection = DefaultEntryIndex;
UpdateScroll(&State, SCROLL_NONE);
}
+ State.PaintAll = TRUE;
while (!MenuExit) {
// update the screen
MenuPosY = 4;
if (Screen->InfoLineCount > 0)
MenuPosY += Screen->InfoLineCount + 1;
- MenuHeight = ConHeight - MenuPosY;
+ MenuHeight = ConHeight - MenuPosY - 2;
if (Screen->TimeoutSeconds > 0)
MenuHeight -= 2;
InitScroll(State, Screen->EntryCount, MenuHeight);
if (MenuWidth < ItemWidth)
MenuWidth = ItemWidth;
}
- if (MenuWidth > ConWidth - 6)
- MenuWidth = ConWidth - 6;
+ MenuWidth += 2;
+ if (MenuWidth > ConWidth - 3)
+ MenuWidth = ConWidth - 3;
// prepare strings for display
DisplayStrings = AllocatePool(sizeof(CHAR16 *) * Screen->EntryCount);
refit_call2_wrapper(ST->ConOut->OutputString, ST->ConOut, ArrowDown);
else
refit_call2_wrapper(ST->ConOut->OutputString, ST->ConOut, L" ");
+ if (!(GlobalConfig.HideUIFlags & HIDEUI_FLAG_HINTS)) {
+ refit_call3_wrapper(ST->ConOut->SetCursorPosition, ST->ConOut, 0, ConHeight - 1);
+ refit_call2_wrapper(ST->ConOut->OutputString, ST->ConOut,
+ L"arrow keys to move cursor; Enter to boot; Insert or F2 for more options");
+ }
break;
case MENU_FUNCTION_PAINT_SELECTION:
if (ParamText[0] == 0) {
// clear message
refit_call2_wrapper(ST->ConOut->SetAttribute, ST->ConOut, ATTR_BASIC);
- refit_call3_wrapper(ST->ConOut->SetCursorPosition, ST->ConOut, 0, ConHeight - 1);
+ refit_call3_wrapper(ST->ConOut->SetCursorPosition, ST->ConOut, 0, ConHeight - 2);
refit_call2_wrapper(ST->ConOut->OutputString, ST->ConOut, BlankLine + 1);
} else {
// paint or update message
refit_call2_wrapper(ST->ConOut->SetAttribute, ST->ConOut, ATTR_ERROR);
- refit_call3_wrapper(ST->ConOut->SetCursorPosition, ST->ConOut, 3, ConHeight - 1);
+ refit_call3_wrapper(ST->ConOut->SetCursorPosition, ST->ConOut, 3, ConHeight - 2);
SPrint(TimeoutMessage, 255, L"%s ", ParamText);
refit_call2_wrapper(ST->ConOut->OutputString, ST->ConOut, TimeoutMessage);
}
DrawMenuText(Screen->Entries[i]->Title, (i == State->CurrentSelection) ? MenuWidth : 0,
EntriesPosX, EntriesPosY + i * TEXT_LINE_HEIGHT);
}
+ if (!(GlobalConfig.HideUIFlags & HIDEUI_FLAG_HINTS)) {
+ DrawMenuText(L"arrow keys to move cursor; Enter to boot;", 0,
+ (UGAWidth - (41 * FONT_CELL_WIDTH)) / 2, UGAHeight - (FONT_CELL_HEIGHT * 3));
+ DrawMenuText(L"Insert or F2 to edit options", 0,
+ (UGAWidth - (28 * FONT_CELL_WIDTH)) / 2, UGAHeight - (FONT_CELL_HEIGHT * 2));
+ }
break;
case MENU_FUNCTION_PAINT_SELECTION:
if (!(GlobalConfig.HideUIFlags & HIDEUI_FLAG_LABEL))
DrawMainMenuText(Screen->Entries[State->CurrentSelection]->Title,
(UGAWidth - LAYOUT_TEXT_WIDTH) >> 1, textPosY);
+
+ if (!(GlobalConfig.HideUIFlags & HIDEUI_FLAG_HINTS)) {
+ DrawMainMenuText(L"arrow keys to move cursor; Enter to boot;",
+ (UGAWidth - LAYOUT_TEXT_WIDTH) / 2, UGAHeight - (FONT_CELL_HEIGHT * 3));
+ DrawMainMenuText(L"Insert or F2 for more options",
+ (UGAWidth - LAYOUT_TEXT_WIDTH) / 2, UGAHeight - (FONT_CELL_HEIGHT * 2));
+ } // if
} // static VOID PaintAll()
// Move the selection to State->CurrentSelection, adjusting icon row if necessary...
static BOOLEAN EditOptions(LOADER_ENTRY *MenuEntry) {
UINTN x_max, y_max;
CHAR16 *EditedOptions;
- 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,
- L"Use cursor keys to edit, Esc to exit, Enter to boot with edited options");
-
- if (line_edit(MenuEntry->LoadOptions, &EditedOptions, x_max, 1)) {
+ if (line_edit(MenuEntry->LoadOptions, &EditedOptions, x_max)) {
MyFreePool(MenuEntry->LoadOptions);
MenuEntry->LoadOptions = EditedOptions;
retval = TRUE;
MenuExit = RunGenericMenu(Screen, MainStyle, DefaultEntryIndex, &TempChosenEntry);
Screen->TimeoutSeconds = 0;
- if (MenuExit == MENU_EXIT_DETAILS && TempChosenEntry->SubScreen != NULL) {
- 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
- }
+ if (MenuExit == MENU_EXIT_DETAILS) {
+ if (TempChosenEntry->SubScreen != NULL) {
+ 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
+ } else { // no sub-screen; ignore keypress
+ MenuExit = 0;
+ }
+ } // Enter sub-screen
}
if (ChosenEntry)
#include "screen.h"
#include "config.h"
#include "libegint.h"
+#include "lib.h"
#include "../include/refit_call_wrapper.h"
#include "../include/egemb_refind_banner.h"
UINTN ConWidth;
UINTN ConHeight;
-CHAR16 *BlankLine;
+CHAR16 *BlankLine = NULL;
static VOID DrawScreenHeader(IN CHAR16 *Title);
static BOOLEAN haveError = FALSE;
+static VOID PrepareBlankLine(VOID) {
+ UINTN i;
+
+ MyFreePool(BlankLine);
+ // make a buffer for a whole text line
+ BlankLine = AllocatePool((ConWidth + 1) * sizeof(CHAR16));
+ for (i = 0; i < ConWidth; i++)
+ BlankLine[i] = ' ';
+ BlankLine[i] = 0;
+}
+
//
// Screen initialization and switching
//
VOID InitScreen(VOID)
{
- UINTN i;
-
// initialize libeg
egInitScreen();
ConHeight = 25;
}
- // make a buffer for a whole text line
- BlankLine = AllocatePool((ConWidth + 1) * sizeof(CHAR16));
- for (i = 0; i < ConWidth; i++)
- BlankLine[i] = ' ';
- BlankLine[i] = 0;
+ PrepareBlankLine();
// show the banner (even when in graphics mode)
DrawScreenHeader(L"Initializing...");
VOID SetupScreen(VOID)
{
+ GlobalConfig.RequestedTextMode = egSetTextMode(GlobalConfig.RequestedTextMode);
+
if ((GlobalConfig.RequestedScreenWidth > 0) && (GlobalConfig.RequestedScreenHeight > 0) &&
egSetScreenSize(GlobalConfig.RequestedScreenWidth, GlobalConfig.RequestedScreenHeight)) {
UGAWidth = GlobalConfig.RequestedScreenWidth;
ConWidth = 80;
ConHeight = 25;
}
+ PrepareBlankLine();
}
VOID SwitchToGraphics(VOID)
(*first)++;
}
-BOOLEAN line_edit(CHAR16 *line_in, CHAR16 **line_out, UINTN x_max, UINTN y_pos) {
+BOOLEAN line_edit(CHAR16 *line_in, CHAR16 **line_out, UINTN x_max) {
CHAR16 *line;
UINTN size;
UINTN len;
UINTN first;
+ UINTN y_pos = 3;
CHAR16 *print;
UINTN cursor;
BOOLEAN exit;
BOOLEAN enter;
+ DrawScreenHeader(L"Line Editor");
+ refit_call3_wrapper(ST->ConOut->SetCursorPosition, ST->ConOut, (ConWidth - 71) / 2, ConHeight - 1);
+ 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_in)
line_in = L"";
size = StrLen(line_in) + 1024;
//VOID BltImageComposite(IN EG_IMAGE *BaseImage, IN EG_IMAGE *TopImage, IN UINTN XPos, IN UINTN YPos);
VOID BltImageCompositeBadge(IN EG_IMAGE *BaseImage, IN EG_IMAGE *TopImage, IN EG_IMAGE *BadgeImage, IN UINTN XPos, IN UINTN YPos);
-BOOLEAN line_edit(CHAR16 *line_in, CHAR16 **line_out, UINTN x_max, UINTN y_pos);
+BOOLEAN line_edit(CHAR16 *line_in, CHAR16 **line_out, UINTN x_max);
#endif