[haiku-commits] r36310 - in haiku/trunk: headers/private/kernel/boot src/system/boot/loader src/system/boot/platform/generic

  • From: axeld@xxxxxxxxxxxxxxxx
  • To: haiku-commits@xxxxxxxxxxxxx
  • Date: Thu, 15 Apr 2010 20:07:40 +0200 (CEST)

Author: axeld
Date: 2010-04-15 20:07:40 +0200 (Thu, 15 Apr 2010)
New Revision: 36310
Changeset: http://dev.haiku-os.org/changeset/36310/haiku
Ticket: http://dev.haiku-os.org/ticket/5312

Modified:
   haiku/trunk/headers/private/kernel/boot/menu.h
   haiku/trunk/src/system/boot/loader/menu.cpp
   haiku/trunk/src/system/boot/platform/generic/text_menu.cpp
Log:
* Added shortcut handling to the boot loader menu (in preparation of adopting
  ticket #5312).
* Added shortcut 'b' to continue booting, 'r' to reboot.
* Consolidated asterisk style.


Modified: haiku/trunk/headers/private/kernel/boot/menu.h
===================================================================
--- haiku/trunk/headers/private/kernel/boot/menu.h      2010-04-15 18:02:06 UTC 
(rev 36309)
+++ haiku/trunk/headers/private/kernel/boot/menu.h      2010-04-15 18:07:40 UTC 
(rev 36310)
@@ -13,7 +13,8 @@
 class Menu;
 class MenuItem;
 
-typedef bool (*menu_item_hook)(Menu *, MenuItem *);
+typedef bool (*menu_item_hook)(Menu* menu, MenuItem* item);
+typedef void (*shortcut_hook)(char key);
 
 
 enum menu_item_type {
@@ -52,6 +53,9 @@
                        void                            SetHelpText(const char* 
text);
                        const char*                     HelpText() const { 
return fHelpText; }
 
+                       void                            SetShortcut(char key);
+                       char                            Shortcut() const { 
return fShortcut; }
+
                        const char*                     Label() const { return 
fLabel; }
                        Menu*                           Submenu() const { 
return fSubMenu; }
 
@@ -70,6 +74,7 @@
                        Menu*                           fSubMenu;
                        const void*                     fData;
                        const char*                     fHelpText;
+                       char                            fShortcut;
 };
 
 
@@ -122,13 +127,23 @@
                                                                        { 
fChoiceText = text; }
                        const char*                     ChoiceText() const { 
return fChoiceText; }
 
-                       void Run();
+                       void                            AddShortcut(char key, 
shortcut_hook function);
+                       shortcut_hook           FindShortcut(char key) const;
+                       MenuItem*                       FindItemByShortcut(char 
key);
 
+                       void                            Run();
+
 private:
                        friend class MenuItem;
                        void                            Draw(MenuItem* item);
 
 private:
+                       struct shortcut {
+                               shortcut*               next;
+                               shortcut_hook   function;
+                               char                    key;
+                       };
+
                        const char*                     fTitle;
                        const char*                     fChoiceText;
                        int32                           fCount;
@@ -136,6 +151,7 @@
                        MenuItemList            fItems;
                        menu_type                       fType;
                        MenuItem*                       fSuperItem;
+                       shortcut*                       fShortcuts;
 };
 
 

Modified: haiku/trunk/src/system/boot/loader/menu.cpp
===================================================================
--- haiku/trunk/src/system/boot/loader/menu.cpp 2010-04-15 18:02:06 UTC (rev 
36309)
+++ haiku/trunk/src/system/boot/loader/menu.cpp 2010-04-15 18:07:40 UTC (rev 
36310)
@@ -151,23 +151,29 @@
 }
 
 
-/** This sets a help text that is shown when the item is
- *     selected.
- *     Note, unlike the label, the string is not copied, it's
- *     just referenced and has to stay valid as long as the
- *     item's menu is being used.
- */
-
+/*!    This sets a help text that is shown when the item is
+       selected.
+       Note, unlike the label, the string is not copied, it's
+       just referenced and has to stay valid as long as the
+       item's menu is being used.
+*/
 void
-MenuItem::SetHelpText(const char *text)
+MenuItem::SetHelpText(const char* text)
 {
        fHelpText = text;
 }
 
 
 void
-MenuItem::SetMenu(Menu *menu)
+MenuItem::SetShortcut(char key)
 {
+       fShortcut = key;
+}
+
+
+void
+MenuItem::SetMenu(Menu* menu)
+{
        fMenu = menu;
 }
 
@@ -175,14 +181,15 @@
 //     #pragma mark -
 
 
-Menu::Menu(menu_type type, const char *title)
+Menu::Menu(menu_type type, const char* title)
        :
        fTitle(title),
        fChoiceText(NULL),
        fCount(0),
        fIsHidden(true),
        fType(type),
-       fSuperItem(NULL)
+       fSuperItem(NULL),
+       fShortcuts(NULL)
 {
 }
 
@@ -199,7 +206,7 @@
 }
 
 
-MenuItem *
+MenuItem*
 Menu::ItemAt(int32 index)
 {
        if (index < 0 || index >= fCount)
@@ -218,13 +225,12 @@
 
 
 int32
-Menu::IndexOf(MenuItem *searchedItem)
+Menu::IndexOf(MenuItem* searchedItem)
 {
-       MenuItemIterator iterator = ItemIterator();
-       MenuItem *item;
        int32 index = 0;
 
-       while ((item = iterator.Next()) != NULL) {
+       MenuItemIterator iterator = ItemIterator();
+       while (MenuItem* item = iterator.Next()) {
                if (item == searchedItem)
                        return index;
 
@@ -242,13 +248,11 @@
 }
 
 
-MenuItem *
-Menu::FindItem(const char *label)
+MenuItem*
+Menu::FindItem(const char* label)
 {
        MenuItemIterator iterator = ItemIterator();
-       MenuItem *item;
-
-       while ((item = iterator.Next()) != NULL) {
+       while (MenuItem* item = iterator.Next()) {
                if (item->Label() != NULL && !strcmp(item->Label(), label))
                        return item;
        }
@@ -257,13 +261,11 @@
 }
 
 
-MenuItem *
+MenuItem*
 Menu::FindMarked()
 {
        MenuItemIterator iterator = ItemIterator();
-       MenuItem *item;
-
-       while ((item = iterator.Next()) != NULL) {
+       while (MenuItem* item = iterator.Next()) {
                if (item->IsMarked())
                        return item;
        }
@@ -272,14 +274,13 @@
 }
 
 
-MenuItem *
-Menu::FindSelected(int32 *_index)
+MenuItem*
+Menu::FindSelected(int32* _index)
 {
-       MenuItemIterator iterator = ItemIterator();
-       MenuItem *item;
        int32 index = 0;
 
-       while ((item = iterator.Next()) != NULL) {
+       MenuItemIterator iterator = ItemIterator();
+       while (MenuItem* item = iterator.Next()) {
                if (item->IsSelected()) {
                        if (_index != NULL)
                                *_index = index;
@@ -294,7 +295,7 @@
 
 
 void
-Menu::AddItem(MenuItem *item)
+Menu::AddItem(MenuItem* item)
 {
        item->fMenu = this;
        fItems.Add(item);
@@ -305,7 +306,7 @@
 status_t
 Menu::AddSeparatorItem()
 {
-       MenuItem *item = new(nothrow) MenuItem();
+       MenuItem* item = new(std::nothrow) MenuItem();
        if (item == NULL)
                return B_NO_MEMORY;
 
@@ -316,16 +317,14 @@
 }
 
 
-MenuItem *
+MenuItem*
 Menu::RemoveItemAt(int32 index)
 {
        if (index < 0 || index >= fCount)
                return NULL;
 
        MenuItemIterator iterator = ItemIterator();
-       MenuItem *item;
-
-       while ((item = iterator.Next()) != NULL) {
+       while (MenuItem* item = iterator.Next()) {
                if (index-- == 0) {
                        RemoveItem(item);
                        return item;
@@ -337,7 +336,7 @@
 
 
 void
-Menu::RemoveItem(MenuItem *item)
+Menu::RemoveItem(MenuItem* item)
 {
        item->fMenu = NULL;
        fItems.Remove(item);
@@ -346,13 +345,54 @@
 
 
 void
-Menu::Draw(MenuItem *item)
+Menu::AddShortcut(char key, shortcut_hook function)
 {
-       if (!IsHidden())
-               platform_update_menu_item(this, item);
+       Menu::shortcut* shortcut = new(std::nothrow) struct Menu::shortcut;
+       if (shortcut == NULL)
+               return;
+
+       shortcut->key = key;
+       shortcut->function = function;
+
+       shortcut->next = fShortcuts;
+       fShortcuts = shortcut;
 }
 
 
+shortcut_hook
+Menu::FindShortcut(char key) const
+{
+       if (key == 0)
+               return NULL;
+
+       const Menu::shortcut* shortcut = fShortcuts;
+       while (shortcut != NULL) {
+               if (shortcut->key == key)
+                       return shortcut->function;
+
+               shortcut = shortcut->next;
+       }
+
+       return NULL;
+}
+
+
+MenuItem*
+Menu::FindItemByShortcut(char key)
+{
+       if (key == 0)
+               return NULL;
+
+       MenuItemList::Iterator iterator = ItemIterator();
+       while (MenuItem* item = iterator.Next()) {
+               if (item->Shortcut() == key)
+                       return item;
+       }
+
+       return NULL;
+}
+
+
 void
 Menu::Run()
 {
@@ -360,6 +400,14 @@
 }
 
 
+void
+Menu::Draw(MenuItem* item)
+{
+       if (!IsHidden())
+               platform_update_menu_item(this, item);
+}
+
+
 //     #pragma mark -
 
 
@@ -415,9 +463,9 @@
 
 
 static bool
-user_menu_boot_volume(Menu *menu, MenuItem *item)
+user_menu_boot_volume(Menu* menu, MenuItem* item)
 {
-       Menu *super = menu->Supermenu();
+       Menu* super = menu->Supermenu();
        if (super == NULL) {
                // huh?
                return true;
@@ -434,7 +482,7 @@
 
 
 static bool
-debug_menu_display_syslog(Menu *menu, MenuItem *item)
+debug_menu_display_syslog(Menu* menu, MenuItem* item)
 {
        ring_buffer* buffer = (ring_buffer*)gKernelArgs.debug_output;
        if (buffer == NULL)
@@ -520,7 +568,7 @@
 
 
 static bool
-debug_menu_toggle_debug_syslog(Menu *menu, MenuItem *item)
+debug_menu_toggle_debug_syslog(Menu* menu, MenuItem* item)
 {
        gKernelArgs.keep_debug_output_buffer = item->IsMarked();
        return true;
@@ -528,7 +576,7 @@
 
 
 static bool
-debug_menu_save_syslog(Menu *menu, MenuItem *item)
+debug_menu_save_syslog(Menu* menu, MenuItem* item)
 {
        Directory* volume = (Directory*)item->Data();
 
@@ -543,17 +591,17 @@
 }
 
 
-static Menu *
-add_boot_volume_menu(Directory *bootVolume)
+static Menu*
+add_boot_volume_menu(Directory* bootVolume)
 {
-       Menu *menu = new(nothrow) Menu(CHOICE_MENU, "Select Boot Volume");
-       MenuItem *item;
-       void *cookie;
+       Menu* menu = new(std::nothrow) Menu(CHOICE_MENU, "Select Boot Volume");
+       MenuItem* item;
+       void* cookie;
        int32 count = 0;
 
        if (gRoot->Open(&cookie, O_RDONLY) == B_OK) {
-               Directory *volume;
-               while (gRoot->GetNextNode(cookie, (Node **)&volume) == B_OK) {
+               Directory* volume;
+               while (gRoot->GetNextNode(cookie, (Node**)&volume) == B_OK) {
                        // only list bootable volumes
                        if (!is_bootable(volume))
                                continue;
@@ -601,11 +649,11 @@
 }
 
 
-static Menu *
+static Menu*
 add_safe_mode_menu()
 {
-       Menu *safeMenu = new(nothrow) Menu(SAFE_MODE_MENU, "Safe Mode Options");
-       MenuItem *item;
+       Menu* safeMenu = new(nothrow) Menu(SAFE_MODE_MENU, "Safe Mode Options");
+       MenuItem* item;
 
        safeMenu->AddItem(item = new(nothrow) MenuItem("Safe mode"));
        item->SetData(B_SAFEMODE_SAFE_MODE);
@@ -704,11 +752,11 @@
 }
 
 
-static Menu *
+static Menu*
 add_debug_menu()
 {
-       Menu *menu = new(nothrow) Menu(STANDARD_MENU, "Debug Options");
-       MenuItem *item;
+       Menu* menu = new(std::nothrow) Menu(STANDARD_MENU, "Debug Options");
+       MenuItem* item;
 
 #if DEBUG_SPINLOCK_LATENCIES
        item = new(std::nothrow) MenuItem("Disable latency checks");
@@ -766,22 +814,21 @@
 
 
 static void
-apply_safe_mode_options(Menu *menu)
+apply_safe_mode_options(Menu* menu)
 {
-       MenuItemIterator iterator = menu->ItemIterator();
-       MenuItem *item;
        char buffer[2048];
        int32 pos = 0;
 
        buffer[0] = '\0';
 
-       while ((item = iterator.Next()) != NULL) {
+       MenuItemIterator iterator = menu->ItemIterator();
+       while (MenuItem* item = iterator.Next()) {
                if (item->Type() == MENU_ITEM_SEPARATOR || !item->IsMarked()
                        || item->Data() == NULL || (uint32)pos > sizeof(buffer))
                        continue;
 
                size_t totalBytes = snprintf(buffer + pos, sizeof(buffer) - pos,
-                       "%s true\n", (const char *)item->Data());
+                       "%s true\n", (const char*)item->Data());
                pos += std::min(totalBytes, sizeof(buffer) - pos - 1);
        }
 
@@ -790,7 +837,7 @@
 
 
 static bool
-user_menu_reboot(Menu *menu, MenuItem *item)
+user_menu_reboot(Menu* menu, MenuItem* item)
 {
        platform_exit();
        return true;
@@ -798,25 +845,25 @@
 
 
 status_t
-user_menu(Directory **_bootVolume)
+user_menu(Directory** _bootVolume)
 {
-       Menu *menu = new(nothrow) Menu(MAIN_MENU);
-       Menu *safeModeMenu = NULL;
-       Menu *debugMenu = NULL;
-       MenuItem *item;
+       Menu* menu = new(std::nothrow) Menu(MAIN_MENU);
+       Menu* safeModeMenu = NULL;
+       Menu* debugMenu = NULL;
+       MenuItem* item;
 
        TRACE(("user_menu: enter\n"));
 
        // Add boot volume
-       menu->AddItem(item = new(nothrow) MenuItem("Select boot volume",
+       menu->AddItem(item = new(std::nothrow) MenuItem("Select boot volume",
                add_boot_volume_menu(*_bootVolume)));
 
        // Add safe mode
-       menu->AddItem(item = new(nothrow) MenuItem("Select safe mode options",
+       menu->AddItem(item = new(std::nothrow) MenuItem("Select safe mode 
options",
                safeModeMenu = add_safe_mode_menu()));
 
        // add debug menu
-       menu->AddItem(item = new(nothrow) MenuItem("Select debug options",
+       menu->AddItem(item = new(std::nothrow) MenuItem("Select debug options",
                debugMenu = add_debug_menu()));
 
        // Add platform dependent menus
@@ -824,20 +871,22 @@
 
        menu->AddSeparatorItem();
 
-       menu->AddItem(item = new(nothrow) MenuItem("Reboot"));
+       menu->AddItem(item = new(std::nothrow) MenuItem("Reboot"));
        item->SetTarget(user_menu_reboot);
+       item->SetShortcut('r');
 
-       menu->AddItem(item = new(nothrow) MenuItem("Continue booting"));
+       menu->AddItem(item = new(std::nothrow) MenuItem("Continue booting"));
        if (*_bootVolume == NULL) {
                item->SetEnabled(false);
                menu->ItemAt(0)->Select(true);
-       }
+       } else
+               item->SetShortcut('b');
 
        menu->Run();
 
        // See if a new boot device has been selected, and propagate that back
        if (item->Data() != NULL)
-               *_bootVolume = (Directory *)item->Data();
+               *_bootVolume = (Directory*)item->Data();
 
        apply_safe_mode_options(safeModeMenu);
        apply_safe_mode_options(debugMenu);

Modified: haiku/trunk/src/system/boot/platform/generic/text_menu.cpp
===================================================================
--- haiku/trunk/src/system/boot/platform/generic/text_menu.cpp  2010-04-15 
18:02:06 UTC (rev 36309)
+++ haiku/trunk/src/system/boot/platform/generic/text_menu.cpp  2010-04-15 
18:07:40 UTC (rev 36310)
@@ -1,5 +1,5 @@
 /*
- * Copyright 2004-2009, Axel Dörfler, axeld@xxxxxxxxxxxxxxxxx All rights 
reserved.
+ * Copyright 2004-2010, Axel Dörfler, axeld@xxxxxxxxxxxxxxxxx
  * Distributed under the terms of the MIT License.
  */
 
@@ -38,6 +38,9 @@
 static int32 sMenuOffset = 0;
 
 
+static void run_menu(Menu* menu);
+
+
 static int32
 menu_height()
 {
@@ -340,8 +343,48 @@
 }
 
 
+static bool
+invoke_item(Menu* menu, MenuItem* item, int32& selected, char key)
+{
+       // leave the menu
+       if (item->Submenu() != NULL && key == TEXT_CONSOLE_KEY_RETURN) {
+               int32 offset = sMenuOffset;
+               menu->Hide();
+
+               run_menu(item->Submenu());
+               if (item->Target() != NULL)
+                       (*item->Target())(menu, item);
+
+               // restore current menu
+               sMenuOffset = offset;
+               menu->FindSelected(&selected);
+               menu->Show();
+               draw_menu(menu);
+       } else if (item->Type() == MENU_ITEM_MARKABLE) {
+               // toggle state
+               item->SetMarked(!item->IsMarked());
+               print_item_at(selected, item);
+
+               if (item->Target() != NULL)
+                       (*item->Target())(menu, item);
+       } else if (key == TEXT_CONSOLE_KEY_RETURN) {
+               // the space key does not exit the menu, only return does
+               if (menu->Type() == CHOICE_MENU
+                       && item->Type() != MENU_ITEM_NO_CHOICE
+                       && item->Type() != MENU_ITEM_TITLE)
+                       item->SetMarked(true);
+
+               if (item->Target() != NULL)
+                       (*item->Target())(menu, item);
+               return true;
+       }
+
+       return false;
+}
+
+
 static void
-run_menu(Menu *menu)
+run_menu(Menu* menu)
 {
        sMenuOffset = 0;
        menu->Show();
@@ -413,43 +456,25 @@
                        }
                } else if (key == TEXT_CONSOLE_KEY_RETURN
                        || key == TEXT_CONSOLE_KEY_SPACE) {
-                       // leave the menu
-                       if (item->Submenu() != NULL && key == 
TEXT_CONSOLE_KEY_RETURN) {
-                               int32 offset = sMenuOffset;
-                               menu->Hide();
-
-                               run_menu(item->Submenu());
-                               if (item->Target() != NULL)
-                                       (*item->Target())(menu, item);
-
-                               // restore current menu
-                               sMenuOffset = offset;
-                               menu->FindSelected(&selected);
-                               menu->Show();
-                               draw_menu(menu);
-                       } else if (item->Type() == MENU_ITEM_MARKABLE) {
-                               // toggle state
-                               item->SetMarked(!item->IsMarked());
-                               print_item_at(selected, item);
-
-                               if (item->Target() != NULL)
-                                       (*item->Target())(menu, item);
-                       } else if (key == TEXT_CONSOLE_KEY_RETURN) {
-                               // the space key does not exit the menu
-
-                               if (menu->Type() == CHOICE_MENU
-                                       && item->Type() != MENU_ITEM_NO_CHOICE
-                                       && item->Type() != MENU_ITEM_TITLE)
-                                       item->SetMarked(true);
-
-                               if (item->Target() != NULL)
-                                       (*item->Target())(menu, item);
-
+                       if (invoke_item(menu, item, selected, key))
                                break;
-                       }
-               } else if (key == TEXT_CONSOLE_KEY_ESCAPE && menu->Type() != 
MAIN_MENU)
+               } else if (key == TEXT_CONSOLE_KEY_ESCAPE
+                       && menu->Type() != MAIN_MENU) {
                        // escape key was hit
                        break;
+               } else {
+                       // Shortcut processing
+                       shortcut_hook function = menu->FindShortcut(key);
+                       if (function != NULL)
+                               function(key);
+                       else {
+                               item = menu->FindItemByShortcut(key);
+                               if (item != NULL && invoke_item(menu, item, 
selected,
+                                               TEXT_CONSOLE_KEY_RETURN)) {
+                                       break;
+                               }
+                       }
+               }
        }
 
        menu->Hide();


Other related posts:

  • » [haiku-commits] r36310 - in haiku/trunk: headers/private/kernel/boot src/system/boot/loader src/system/boot/platform/generic - axeld