summaryrefslogtreecommitdiffstats
path: root/ui
diff options
context:
space:
mode:
authorSamuel Mendoza-Jonas <sam@mendozajonas.com>2017-12-18 16:39:50 +1100
committerSamuel Mendoza-Jonas <sam@mendozajonas.com>2018-01-10 13:34:54 +1100
commit2dfbd9811d1e14911a6476850aada94b88a0dbdd (patch)
tree721429d3d18b8b2fdbf568b63fd99c774f27c421 /ui
parenta2d5a3e3cb55fe3583acaae44fabc7c3d7f8df50 (diff)
downloadtalos-petitboot-2dfbd9811d1e14911a6476850aada94b88a0dbdd.tar.gz
talos-petitboot-2dfbd9811d1e14911a6476850aada94b88a0dbdd.zip
ui/ncurses: Allow multiple hot key handlers per pmenu
The main menu and plugin menu are separate screens but they share the pmenu_process_key() handler. This means all the key shortcuts intended for the main menu can also be used in the plugin menu, which is particularly odd for "add new boot option" for example. To work around this extend the 'hot_key' functionality in pmenu to allow multiple handlers. This allows all pmenus to have the usual navigation and action keys, and then add extra handlers as needed. For example, ps3_mm_init() needs main menu shortcuts as well as some PS3-specific shortcuts, whereas plugin_menu_init() only needs the generic key handler. This changes the functionality of pmenu_process_key() such that if a hot_key_fn successfully handles a key, pmenu_process_key() returns instead of continuing to process the key. This does not affect the current usage. Signed-off-by: Samuel Mendoza-Jonas <sam@mendozajonas.com>
Diffstat (limited to 'ui')
-rw-r--r--ui/ncurses/nc-cui.c9
-rw-r--r--ui/ncurses/nc-menu.c48
-rw-r--r--ui/ncurses/nc-menu.h7
-rw-r--r--ui/ncurses/ps3-main.c10
4 files changed, 57 insertions, 17 deletions
diff --git a/ui/ncurses/nc-cui.c b/ui/ncurses/nc-cui.c
index 72a056d..f9f8247 100644
--- a/ui/ncurses/nc-cui.c
+++ b/ui/ncurses/nc-cui.c
@@ -1242,6 +1242,14 @@ static struct pmenu *main_menu_init(struct cui *cui)
return NULL;
}
+ m->n_hot_keys = 1;
+ m->hot_keys = talloc_array(m, hot_key_fn, m->n_hot_keys);
+ if (!m->hot_keys) {
+ pb_log("%s: failed to allocate hot_keys\n", __func__);
+ talloc_free(m);
+ return NULL;
+ }
+ m->hot_keys[0] = pmenu_main_hot_keys;
m->on_new = cui_item_new;
m->scr.frame.ltitle = talloc_asprintf(m,
@@ -1325,7 +1333,6 @@ static struct pmenu *plugin_menu_init(struct cui *cui)
int result;
m = pmenu_init(cui, 2, cui_plugin_menu_exit);
- m->on_new = cui_item_new;
m->scr.frame.ltitle = talloc_asprintf(m, _("Petitboot Plugins"));
m->scr.frame.rtitle = talloc_asprintf(m, NULL);
m->scr.frame.help = talloc_strdup(m,
diff --git a/ui/ncurses/nc-menu.c b/ui/ncurses/nc-menu.c
index 54d82ff..a6c2b15 100644
--- a/ui/ncurses/nc-menu.c
+++ b/ui/ncurses/nc-menu.c
@@ -374,6 +374,34 @@ static void pmenu_move_cursor(struct pmenu *menu, int req)
}
/**
+ * pmenu_main_hot_keys - Hot keys for the main boot menu
+ */
+int pmenu_main_hot_keys(struct pmenu *menu, struct pmenu_item *item, int c)
+{
+ struct nc_scr *scr = &menu->scr;
+ (void)item;
+
+ switch (c) {
+ case 'i':
+ cui_show_sysinfo(cui_from_arg(scr->ui_ctx));
+ break;
+ case 'c':
+ cui_show_config(cui_from_arg(scr->ui_ctx));
+ break;
+ case 'l':
+ cui_show_lang(cui_from_arg(scr->ui_ctx));
+ break;
+ case 'g':
+ cui_show_statuslog(cui_from_arg(scr->ui_ctx));
+ break;
+ default:
+ return 0;
+ }
+
+ return c;
+}
+
+/**
* pmenu_process_key - Process a user keystroke.
*/
@@ -381,11 +409,15 @@ static void pmenu_process_key(struct nc_scr *scr, int key)
{
struct pmenu *menu = pmenu_from_scr(scr);
struct pmenu_item *item = pmenu_find_selected(menu);
+ unsigned int i;
nc_scr_status_free(&menu->scr);
- if (menu->hot_key)
- key = menu->hot_key(menu, item, key);
+ if (menu->hot_keys)
+ for (i = 0; i < menu->n_hot_keys; i++) {
+ if (menu->hot_keys[i](menu, item, key))
+ return;
+ }
switch (key) {
case 27: /* ESC */
@@ -433,18 +465,6 @@ static void pmenu_process_key(struct nc_scr *scr, int key)
if (item->on_execute)
item->on_execute(item);
break;
- case 'i':
- cui_show_sysinfo(cui_from_arg(scr->ui_ctx));
- break;
- case 'c':
- cui_show_config(cui_from_arg(scr->ui_ctx));
- break;
- case 'l':
- cui_show_lang(cui_from_arg(scr->ui_ctx));
- break;
- case 'g':
- cui_show_statuslog(cui_from_arg(scr->ui_ctx));
- break;
case KEY_F(1):
case 'h':
if (menu->help_text)
diff --git a/ui/ncurses/nc-menu.h b/ui/ncurses/nc-menu.h
index 54f83af..4d9e188 100644
--- a/ui/ncurses/nc-menu.h
+++ b/ui/ncurses/nc-menu.h
@@ -76,6 +76,10 @@ static inline struct cui_opt_data *cod_from_item(struct pmenu_item *item)
return item->data;
}
+typedef int (*hot_key_fn)(struct pmenu *menu, struct pmenu_item *item, int c);
+
+int pmenu_main_hot_keys(struct pmenu *menu, struct pmenu_item *item, int c);
+
/**
* struct pmenu - Data structure defining complete menu.
* @insert_pt: Index in nc item array.
@@ -90,7 +94,8 @@ struct pmenu {
unsigned int insert_pt;
const char *help_title;
const struct help_text *help_text;
- int (*hot_key)(struct pmenu *menu, struct pmenu_item *item, int c);
+ hot_key_fn *hot_keys;
+ unsigned int n_hot_keys;
void (*on_exit)(struct pmenu *menu);
void (*on_new)(struct pmenu *menu);
};
diff --git a/ui/ncurses/ps3-main.c b/ui/ncurses/ps3-main.c
index 7bded78..f60a05e 100644
--- a/ui/ncurses/ps3-main.c
+++ b/ui/ncurses/ps3-main.c
@@ -411,7 +411,15 @@ static struct pmenu *ps3_mm_init(struct ps3_cui *ps3_cui)
return NULL;
}
- m->hot_key = ps3_hot_key;
+ m->n_hot_keys = 2;
+ m->hot_keys = talloc_array(m, hot_key_fn *, m->n_hot_keys);
+ if (!m->hot_keys) {
+ pb_log("%s: failed to allocate hot_keys\n", __func__);
+ talloc_free(m);
+ return NULL;
+ }
+ m->hot_keys[0] = ps3_hot_key;
+ m->hot_keys[1] = pmenu_main_hot_keys;
m->on_new = cui_item_new;
#if defined(DEBUG)
OpenPOWER on IntegriCloud