* Implement support for user input of additional safe mode options that

aren't otherwise exposed via the safe mode menus. The option can be 
found under the debug options menu, where additional settings can be 
added one at a time with the same syntax used in kernel settings files 
(i.e. disable_acpi on). 

Scrolling of the input buffer is not yet supported (will implement that 
soon), so currently the input is clamped to the size of one line. This 
shouldn't be a problem for our current set of options though.



git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@41577 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
Rene Gollent
2011-05-19 01:38:02 +00:00
parent 13fd92e6a0
commit d2b49a0031
9 changed files with 214 additions and 35 deletions
+2
View File
@@ -68,6 +68,8 @@ class MenuItem;
extern void platform_add_menus(Menu *menu);
extern void platform_update_menu_item(Menu *menu, MenuItem *item);
extern void platform_run_menu(Menu *menu);
extern size_t platform_get_user_input_text(Menu *menu, const char *prompt,
char *buffer, size_t bufferSize);
#endif
@@ -36,6 +36,7 @@ enum {
// ASCII
TEXT_CONSOLE_NO_KEY = '\0',
TEXT_CONSOLE_KEY_RETURN = '\r',
TEXT_CONSOLE_KEY_BACKSPACE = '\b',
TEXT_CONSOLE_KEY_ESCAPE = 0x1b,
TEXT_CONSOLE_KEY_SPACE = ' ',
@@ -64,6 +65,8 @@ extern void console_clear_screen(void);
extern int32 console_width(void);
extern int32 console_height(void);
extern void console_set_cursor(int32 x, int32 y);
extern void console_show_cursor(void);
extern void console_hide_cursor(void);
extern void console_set_color(int32 foreground, int32 background);
extern int console_wait_for_key(void);
@@ -1,15 +1,18 @@
/*
* Copyright 2005, Ingo Weinhold <[email protected]>.
* All rights reserved. Distributed under the terms of the MIT License.
*/
#ifndef GENERIC_TEXT_MENU_H
#define GENERIC_TEXT_MENU_H
class Menu;
class MenuItem;
void platform_generic_update_text_menu_item(Menu *menu, MenuItem *item);
void platform_generic_run_text_menu(Menu *menu);
#endif /* GENERIC_TEXT_MENU_H */
/*
* Copyright 2011, Rene Gollent <[email protected]>.
* Copyright 2005, Ingo Weinhold <[email protected]>.
* All rights reserved. Distributed under the terms of the MIT License.
*/
#ifndef GENERIC_TEXT_MENU_H
#define GENERIC_TEXT_MENU_H
class Menu;
class MenuItem;
void platform_generic_update_text_menu_item(Menu* menu, MenuItem* item);
void platform_generic_run_text_menu(Menu* menu);
size_t platform_generic_get_user_input_text(Menu* menu, const char* prompt,
char* buffer, size_t bufferSize);
#endif /* GENERIC_TEXT_MENU_H */
+42 -11
View File
@@ -1,5 +1,6 @@
/*
* Copyright 2003-2010, Axel Dörfler, [email protected].
* Copyright 2011, Rene Gollent, [email protected].
* Distributed under the terms of the MIT License.
*/
@@ -39,6 +40,9 @@
#endif
static char sSafeModeOptionsBuffer[2048];
MenuItem::MenuItem(const char *label, Menu *subMenu)
:
fLabel(strdup(label)),
@@ -516,6 +520,26 @@ debug_menu_display_syslog(Menu* menu, MenuItem* item)
}
static bool
debug_menu_add_advanced_option(Menu* menu, MenuItem* item)
{
char buffer[128];
const char* prompt = "Option: ";
size_t size = platform_get_user_input_text(menu, prompt, buffer,
sizeof(buffer) - 1);
if (size > 0) {
buffer[size] = '\n';
uint32 pos = strlen(sSafeModeOptionsBuffer);
if (pos + size < sizeof(sSafeModeOptionsBuffer))
strlcat(sSafeModeOptionsBuffer, buffer,
sizeof(sSafeModeOptionsBuffer));
}
return true;
}
static status_t
save_syslog_to_volume(Directory* directory)
{
@@ -829,6 +853,14 @@ add_debug_menu()
"disk. Currently only FAT32 volumes are supported.");
}
menu->AddSeparatorItem();
menu->AddItem(item = new(nothrow) MenuItem(
"Add advanced debug option"));
item->SetType(MENU_ITEM_NO_CHOICE);
item->SetTarget(&debug_menu_add_advanced_option);
item->SetHelpText(
"Allows advanced debugging options to be entered directly.");
menu->AddSeparatorItem();
menu->AddItem(item = new(nothrow) MenuItem("Return to main menu"));
@@ -837,9 +869,10 @@ add_debug_menu()
static void
apply_safe_mode_options(Menu* menu, char *buffer, size_t bufferSize)
apply_safe_mode_options(Menu* menu)
{
int32 pos = strlen(buffer);
int32 pos = strlen(sSafeModeOptionsBuffer);
size_t bufferSize = sizeof(sSafeModeOptionsBuffer);
MenuItemIterator iterator = menu->ItemIterator();
while (MenuItem* item = iterator.Next()) {
@@ -847,8 +880,8 @@ apply_safe_mode_options(Menu* menu, char *buffer, size_t bufferSize)
|| item->Data() == NULL || (uint32)pos >= bufferSize)
continue;
size_t totalBytes = snprintf(buffer + pos, bufferSize - pos,
"%s true\n", (const char*)item->Data());
size_t totalBytes = snprintf(sSafeModeOptionsBuffer + pos,
bufferSize - pos, "%s true\n", (const char*)item->Data());
pos += std::min(totalBytes, bufferSize - pos - 1);
}
}
@@ -872,6 +905,8 @@ user_menu(Directory** _bootVolume)
TRACE(("user_menu: enter\n"));
memset(sSafeModeOptionsBuffer, 0, sizeof(sSafeModeOptionsBuffer));
// Add boot volume
menu->AddItem(item = new(std::nothrow) MenuItem("Select boot volume",
add_boot_volume_menu(*_bootVolume)));
@@ -906,13 +941,9 @@ user_menu(Directory** _bootVolume)
if (item->Data() != NULL)
*_bootVolume = (Directory*)item->Data();
char buffer[2048];
memset(buffer, 0, sizeof(buffer));
apply_safe_mode_options(safeModeMenu, buffer, sizeof(buffer));
apply_safe_mode_options(debugMenu, buffer, sizeof(buffer));
add_safe_mode_settings(buffer);
apply_safe_mode_options(safeModeMenu);
apply_safe_mode_options(debugMenu);
add_safe_mode_settings(sSafeModeOptionsBuffer);
delete menu;
+23 -2
View File
@@ -1,11 +1,13 @@
/*
* Copyright 2004-2005, Axel Dörfler, axeld@pinc-software.de. All rights reserved.
* Copyright 2011, Rene Gollent, rene@gollent.com. All rights reserved.
* Distributed under the terms of the MIT License.
*/
#include "console.h"
#include "keyboard.h"
#include "video.h"
#include <SupportDefs.h>
#include <util/kernel_cpp.h>
@@ -116,7 +118,7 @@ console_height(void)
}
void
void
console_set_cursor(int32 x, int32 y)
{
if (y >= (int32)sScreenHeight)
@@ -129,10 +131,25 @@ console_set_cursor(int32 x, int32 y)
x = 0;
sScreenOffset = x + y * sScreenWidth;
video_move_text_cursor(x, y);
}
void
void
console_show_cursor(void)
{
video_show_text_cursor();
}
void
console_hide_cursor(void)
{
video_hide_text_cursor();
}
void
console_set_color(int32 foreground, int32 background)
{
sColor = (background & 0xf) << 12 | (foreground & 0xf) << 8;
@@ -150,6 +167,10 @@ console_wait_for_key(void)
return TEXT_CONSOLE_KEY_UP;
case BIOS_KEY_DOWN:
return TEXT_CONSOLE_KEY_DOWN;
case BIOS_KEY_LEFT:
return TEXT_CONSOLE_KEY_LEFT;
case BIOS_KEY_RIGHT:
return TEXT_CONSOLE_KEY_RIGHT;
case BIOS_KEY_PAGE_UP:
return TEXT_CONSOLE_KEY_PAGE_UP;
case BIOS_KEY_PAGE_DOWN:
@@ -1,5 +1,6 @@
/*
* Copyright 2004-2010, Axel Dörfler, axeld@pinc-software.de.
* Copyright 2011, Rene Gollent, rene@gollent.com.
* Distributed under the terms of the MIT License.
*/
@@ -111,3 +112,11 @@ platform_run_menu(Menu* menu)
platform_generic_run_text_menu(menu);
}
size_t
platform_get_user_input_text(Menu* menu, const char* prompt, char *buffer,
size_t bufferSize)
{
return platform_generic_get_user_input_text(menu, prompt, buffer,
bufferSize);
}
+30 -1
View File
@@ -2,6 +2,7 @@
* Copyright 2004-2009, Axel Dörfler, axeld@pinc-software.de.
* Copyright 2008, Stephan Aßmus <superstippi@gmx.de>
* Copyright 2008, Philippe Saint-Pierre <stpere@gmail.com>
* Copyright 2011, Rene Gollent, rene@gollent.com.
* Distributed under the terms of the MIT License.
*/
@@ -696,7 +697,35 @@ set_text_mode(void)
regs.eax = 0x0003;
call_bios(0x10, &regs);
// turns off text cursor
video_hide_text_cursor();
}
void
video_move_text_cursor(int x, int y)
{
bios_regs regs;
regs.eax = 0x0200;
regs.ebx = 0;
regs.edx = (y << 8) | x;
call_bios(0x10, &regs);
}
void
video_show_text_cursor(void)
{
bios_regs regs;
regs.eax = 0x0100;
regs.ecx = 0x0607;
call_bios(0x10, &regs);
}
void
video_hide_text_cursor(void)
{
bios_regs regs;
regs.eax = 0x0100;
regs.ecx = 0x2000;
call_bios(0x10, &regs);
+9 -3
View File
@@ -1,7 +1,9 @@
/*
** Copyright 2004, Axel Dörfler, axeld@pinc-software.de. All rights reserved.
** Distributed under the terms of the Haiku License.
*/
* Copyright 2004, Axel Dörfler, axeld@pinc-software.de. All rights reserved.
* Copyright 2011, Rene Gollent, rene@gollent.com. All rights reserved.
*
* Distributed under the terms of the Haiku License.
*/
#ifndef VIDEO_H
#define VIDEO_H
@@ -15,4 +17,8 @@ class MenuItem;
bool video_mode_hook(Menu *menu, MenuItem *item);
Menu *video_mode_menu();
void video_move_text_cursor(int x, int y);
void video_show_text_cursor(void);
void video_hide_text_cursor(void);
#endif /* VIDEO_H */
+78 -3
View File
@@ -1,5 +1,6 @@
/*
* Copyright 2004-2010, Axel Dörfler, axeld@pinc-software.de.
* Copyright 2011, Rene Gollent, rene@gollent.com.
* Distributed under the terms of the MIT License.
*/
@@ -57,13 +58,15 @@ print_spacing(int32 count)
static void
print_centered(int32 line, const char *text)
print_centered(int32 line, const char *text, bool resetPosition = true)
{
console_set_cursor(console_width() / 2 - strlen(text) / 2, line);
printf("%s", text);
console_set_cursor(0, 0);
// this avoids unwanted line feeds
if (resetPosition) {
console_set_cursor(0, 0);
// this avoids unwanted line feeds
}
}
@@ -508,3 +511,75 @@ platform_generic_run_text_menu(Menu *menu)
// platform_switch_to_logo();
}
size_t
platform_generic_get_user_input_text(Menu* menu, const char* prompt,
char* buffer, size_t bufferSize)
{
size_t pos = 0;
memset(buffer, 0, bufferSize);
int32 promptLength = strlen(prompt);
int32 line = console_height() / 2;
int32 x = kOffsetX + 1;
console_set_cursor(0, line);
console_set_color(kSelectedItemColor, kSelectedItemBackgroundColor);
print_spacing(console_width());
console_set_color(kTextColor, kBackgroundColor);
console_set_cursor(0, line);
print_spacing(x);
printf(prompt);
x += promptLength;
console_set_color(kSelectedItemColor, kSelectedItemBackgroundColor);
console_show_cursor();
console_set_cursor(x, line);
int key = 0;
size_t dataLength = 0;
while (true) {
key = console_wait_for_key();
if (key == TEXT_CONSOLE_KEY_RETURN || key == TEXT_CONSOLE_KEY_ESCAPE)
break;
else if (key >= TEXT_CONSOLE_CURSOR_KEYS_START
&& key < TEXT_CONSOLE_CURSOR_KEYS_END)
{
switch (key) {
case TEXT_CONSOLE_KEY_LEFT:
if (pos != 0)
pos--;
break;
case TEXT_CONSOLE_KEY_RIGHT:
if (pos < dataLength)
pos++;
break;
default:
break;
}
} else if (key == TEXT_CONSOLE_KEY_BACKSPACE) {
if (pos != 0) {
pos--;
dataLength--;
buffer[pos] = '\0';
console_set_cursor(x + pos, line);
printf(" ");
}
// only accept printable ascii characters
} else if (key > 32 || key == TEXT_CONSOLE_KEY_SPACE) {
// don't allow the input to exceed either the buffer size
// or screen width
// TODO: support scrolling the line to allow larger inputs
if (x < (console_width() - 1) && pos < (bufferSize - 1)) {
buffer[pos++] = key;
printf("%c", key);
dataLength++;
}
}
console_set_cursor(x + pos, line);
}
console_hide_cursor();
draw_menu(menu);
return key == TEXT_CONSOLE_KEY_RETURN ? pos : 0;
}