From 8837310ce73c6558049edd7763e6e655eba3863f Mon Sep 17 00:00:00 2001 From: Rene Gollent Date: Tue, 24 May 2011 03:21:51 +0000 Subject: [PATCH] * Slightly alter the semantics of the input gathering function to take the menu item it's associated with rather than an input string. This allows it to calculate the position to start the input at, as well as the correct line to place it on. The previous solution always put the input at the center line, which happened to be the right place by happy coincidence unless one also had the menu items for viewing/saving the debug syslog present. * Implement input buffer scrolling, and consequently lift the previous size limit on user input (it is now only limited by the size of the passed in buffer). * Implement parsing of the input buffer to allow it to handle comma-separated options. Thus, one can now input things like "disable_smp true, serial_debug_output false" and it will be handled properly. git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@41706 a95241bf-73f2-0310-859d-f6bbb57e9c96 --- headers/private/kernel/boot/platform.h | 2 +- .../kernel/boot/platform/generic/text_menu.h | 2 +- src/system/boot/loader/menu.cpp | 31 ++++++-- src/system/boot/platform/amiga_m68k/menu.cpp | 6 +- src/system/boot/platform/atari_m68k/menu.cpp | 4 +- src/system/boot/platform/bios_ia32/menu.cpp | 4 +- .../boot/platform/generic/text_menu.cpp | 71 ++++++++++++++----- .../boot/platform/openfirmware/menu.cpp | 4 +- src/system/boot/platform/u-boot/menu.cpp | 4 +- 9 files changed, 90 insertions(+), 38 deletions(-) diff --git a/headers/private/kernel/boot/platform.h b/headers/private/kernel/boot/platform.h index 3071c50316..f4549990bb 100644 --- a/headers/private/kernel/boot/platform.h +++ b/headers/private/kernel/boot/platform.h @@ -68,7 +68,7 @@ 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, +extern size_t platform_get_user_input_text(Menu *menu, MenuItem *item, char *buffer, size_t bufferSize); #endif diff --git a/headers/private/kernel/boot/platform/generic/text_menu.h b/headers/private/kernel/boot/platform/generic/text_menu.h index 437a2a41fd..791aee8be3 100644 --- a/headers/private/kernel/boot/platform/generic/text_menu.h +++ b/headers/private/kernel/boot/platform/generic/text_menu.h @@ -12,7 +12,7 @@ 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, +size_t platform_generic_get_user_input_text(Menu* menu, MenuItem* item, char* buffer, size_t bufferSize); #endif /* GENERIC_TEXT_MENU_H */ diff --git a/src/system/boot/loader/menu.cpp b/src/system/boot/loader/menu.cpp index b150e890ab..5068adb403 100644 --- a/src/system/boot/loader/menu.cpp +++ b/src/system/boot/loader/menu.cpp @@ -523,18 +523,35 @@ 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: "; + char buffer[256]; - size_t size = platform_get_user_input_text(menu, prompt, buffer, + size_t size = platform_get_user_input_text(menu, item, buffer, sizeof(buffer) - 1); if (size > 0) { - buffer[size] = '\n'; + char* token = NULL; + char *bufferOffset = buffer; + char *separator = NULL; uint32 pos = strlen(sSafeModeOptionsBuffer); - if (pos + size < sizeof(sSafeModeOptionsBuffer)) - strlcat(sSafeModeOptionsBuffer, buffer, - sizeof(sSafeModeOptionsBuffer)); + do { + token = bufferOffset; + separator = strchr(bufferOffset, ','); + if (separator != NULL) { + *separator = '\0'; + bufferOffset = separator + 1; + } else { + token = bufferOffset; + bufferOffset = NULL; + } + uint32 length = strlen(token) + 1; + if (pos + length < sizeof(sSafeModeOptionsBuffer)) { + strlcat(sSafeModeOptionsBuffer, token, + sizeof(sSafeModeOptionsBuffer)); + sSafeModeOptionsBuffer[pos + length - 1] = '\n'; + pos += length; + } else + break; + } while (token != NULL); } return true; diff --git a/src/system/boot/platform/amiga_m68k/menu.cpp b/src/system/boot/platform/amiga_m68k/menu.cpp index 227d798f63..ec82229d26 100644 --- a/src/system/boot/platform/amiga_m68k/menu.cpp +++ b/src/system/boot/platform/amiga_m68k/menu.cpp @@ -51,7 +51,7 @@ platform_add_menus(Menu *menu) } -void +void platform_update_menu_item(Menu *menu, MenuItem *item) { platform_generic_update_text_menu_item(menu, item); @@ -65,9 +65,9 @@ platform_run_menu(Menu *menu) } size_t -platform_get_user_input_text(Menu* menu, const char* prompt, char *buffer, +platform_get_user_input_text(Menu *menu, MenuItem *item, char *buffer, size_t bufferSize) { - return platform_generic_get_user_input_text(menu, prompt, buffer, + return platform_generic_get_user_input_text(menu, item, buffer, bufferSize); } diff --git a/src/system/boot/platform/atari_m68k/menu.cpp b/src/system/boot/platform/atari_m68k/menu.cpp index 429951dbb6..57a448b746 100644 --- a/src/system/boot/platform/atari_m68k/menu.cpp +++ b/src/system/boot/platform/atari_m68k/menu.cpp @@ -67,9 +67,9 @@ platform_run_menu(Menu *menu) size_t -platform_get_user_input_text(Menu* menu, const char* prompt, char *buffer, +platform_get_user_input_text(Menu *menu, MenuItem *item, char *buffer, size_t bufferSize) { - return platform_generic_get_user_input_text(menu, prompt, buffer, + return platform_generic_get_user_input_text(menu, item, buffer, bufferSize); } diff --git a/src/system/boot/platform/bios_ia32/menu.cpp b/src/system/boot/platform/bios_ia32/menu.cpp index d26879f1aa..6d59614896 100644 --- a/src/system/boot/platform/bios_ia32/menu.cpp +++ b/src/system/boot/platform/bios_ia32/menu.cpp @@ -114,9 +114,9 @@ platform_run_menu(Menu* menu) size_t -platform_get_user_input_text(Menu* menu, const char* prompt, char* buffer, +platform_get_user_input_text(Menu* menu, MenuItem* item, char* buffer, size_t bufferSize) { - return platform_generic_get_user_input_text(menu, prompt, buffer, + return platform_generic_get_user_input_text(menu, item, buffer, bufferSize); } diff --git a/src/system/boot/platform/generic/text_menu.cpp b/src/system/boot/platform/generic/text_menu.cpp index 5181792ad0..c845502c43 100644 --- a/src/system/boot/platform/generic/text_menu.cpp +++ b/src/system/boot/platform/generic/text_menu.cpp @@ -513,15 +513,20 @@ 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) +platform_generic_get_user_input_text(Menu* menu, MenuItem* item, char* buffer, + size_t bufferSize) { size_t pos = 0; memset(buffer, 0, bufferSize); - int32 promptLength = strlen(prompt); - int32 line = console_height() / 2; + int32 promptLength = strlen(item->Label()) + 2; + int32 line = menu->IndexOf(item) - sMenuOffset; + if (line < 0 || line >= menu_height()) + return 0; + + line += kFirstLine; + console_set_cursor(kOffsetX, line); int32 x = kOffsetX + 1; console_set_cursor(0, line); console_set_color(kSelectedItemColor, kSelectedItemBackgroundColor); @@ -529,12 +534,15 @@ platform_generic_get_user_input_text(Menu* menu, const char* prompt, console_set_color(kTextColor, kBackgroundColor); console_set_cursor(0, line); print_spacing(x); - printf(prompt); + printf(item->Label()); + printf(": "); x += promptLength; console_set_color(kSelectedItemColor, kSelectedItemBackgroundColor); console_show_cursor(); console_set_cursor(x, line); + int32 scrollOffset = 0; + bool doScroll = false; int key = 0; size_t dataLength = 0; while (true) { @@ -546,35 +554,62 @@ platform_generic_get_user_input_text(Menu* menu, const char* prompt, { switch (key) { case TEXT_CONSOLE_KEY_LEFT: - if (pos != 0) + if (pos > 0) pos--; + else if (scrollOffset > 0) { + scrollOffset--; + doScroll = true; + } break; case TEXT_CONSOLE_KEY_RIGHT: - if (pos < dataLength) - pos++; + if (pos < dataLength) { + if (x + (int32)pos == console_width() - 1) { + scrollOffset++; + doScroll = true; + } else + pos++; + } break; default: break; } } else if (key == TEXT_CONSOLE_KEY_BACKSPACE) { - if (pos != 0) { - pos--; + if (pos != 0 || scrollOffset > 0) { + if (pos > 0) + pos--; + else if (scrollOffset > 0) + scrollOffset--; dataLength--; - buffer[pos] = '\0'; + int32 offset = pos + scrollOffset; + memmove(buffer + offset, buffer + offset + 1, dataLength - offset); console_set_cursor(x + pos, line); - printf(" "); + putchar(' '); + // if this was a mid-line backspace, the line will need to be redrawn + if (pos + scrollOffset < dataLength) + doScroll = true; } // 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); + if (pos < (bufferSize - 1)) { + buffer[pos + scrollOffset] = key; + if (x + (int32)pos < console_width() - 1) { + putchar(key); + pos++; + } else { + scrollOffset++; + doScroll = true; + } + dataLength++; } } + + if (doScroll) { + console_set_cursor(x, line); + for (int32 i = x; i < console_width() - 1; i++) + putchar(buffer[scrollOffset + i - x]); + doScroll = false; + } console_set_cursor(x + pos, line); } diff --git a/src/system/boot/platform/openfirmware/menu.cpp b/src/system/boot/platform/openfirmware/menu.cpp index 03e69d3f81..47f9c6ff48 100644 --- a/src/system/boot/platform/openfirmware/menu.cpp +++ b/src/system/boot/platform/openfirmware/menu.cpp @@ -40,9 +40,9 @@ platform_run_menu(Menu *menu) size_t -platform_get_user_input_text(Menu *menu, const char *prompt, char *buffer, +platform_get_user_input_text(Menu *menu, MenuItem *item, char *buffer, size_t bufferSize) { - return platform_generic_get_user_input_text(menu, prompt, buffer, + return platform_generic_get_user_input_text(menu, item, buffer, bufferSize); } diff --git a/src/system/boot/platform/u-boot/menu.cpp b/src/system/boot/platform/u-boot/menu.cpp index 10c3c226a4..f366fb139d 100644 --- a/src/system/boot/platform/u-boot/menu.cpp +++ b/src/system/boot/platform/u-boot/menu.cpp @@ -75,8 +75,8 @@ platform_run_menu(Menu *menu) void -platform_get_user_input_text(Menu *menu, const char *prompt, char *buffer, +platform_get_user_input_text(Menu *menu, MenuItem *item, char *buffer, size_t bufferSize) { - platform_generic_get_user_input_text(menu, prompt, buffer, bufferSize); + platform_generic_get_user_input_text(menu, item, buffer, bufferSize); }