* 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:
@@ -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 */
|
||||
|
||||
@@ -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;
|
||||
|
||||
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
@@ -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, ®s);
|
||||
|
||||
// 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, ®s);
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
video_show_text_cursor(void)
|
||||
{
|
||||
bios_regs regs;
|
||||
regs.eax = 0x0100;
|
||||
regs.ecx = 0x0607;
|
||||
call_bios(0x10, ®s);
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
video_hide_text_cursor(void)
|
||||
{
|
||||
bios_regs regs;
|
||||
regs.eax = 0x0100;
|
||||
regs.ecx = 0x2000;
|
||||
call_bios(0x10, ®s);
|
||||
|
||||
@@ -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 */
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user