]> git.ozlabs.org Git - petitboot/blobdiff - ui/ncurses/nc-cui.c
Make read-only guarantee user-settable
[petitboot] / ui / ncurses / nc-cui.c
index 4f03409fac2ed81723ca7e3dcdd607f6f30a0a78..56e7653af112c67e8f0afc67c6fc45b4d6cb794e 100644 (file)
 #include "nc-cui.h"
 #include "nc-boot-editor.h"
 #include "nc-config.h"
+#include "nc-add-url.h"
 #include "nc-sysinfo.h"
 #include "nc-lang.h"
 #include "nc-helpscreen.h"
+#include "nc-subset.h"
 
 extern const struct help_text main_menu_help_text;
 
@@ -68,6 +70,16 @@ static void cui_start(void)
         */
        define_key("\x1b[Z", KEY_BTAB);
 
+       /* We'll define a few other keys too since they're commonly
+        * used for navigation but the escape character will cause
+        * Petitboot to exit if they're left undefined */
+       define_key("\x1b\x5b\x35\x7e", KEY_PPAGE);
+       define_key("\x1b\x5b\x36\x7e", KEY_NPAGE);
+       define_key("\x1b\x4f\x48", KEY_HOME);
+       define_key("\x1b\x4f\x46", KEY_END);
+       define_key("OH", KEY_HOME);
+       define_key("OF", KEY_END);
+
        while (getch() != ERR)          /* flush stdin */
                (void)0;
 }
@@ -172,6 +184,7 @@ static void cui_boot_editor_on_exit(struct cui *cui,
 {
        struct pmenu *menu = cui->main;
        struct cui_opt_data *cod;
+       int idx, top, rows, cols;
        static int user_idx = 0;
 
        /* Was the edit cancelled? */
@@ -210,6 +223,22 @@ static void cui_boot_editor_on_exit(struct cui *cui,
 
                /* Re-attach the items array. */
                set_menu_items(menu->ncm, menu->items);
+
+               /* If our index is above the current top row, align
+                * us to the new top. Otherwise, align us to the new
+                * bottom */
+               menu_format(cui->main->ncm, &rows, &cols);
+               top = top_row(cui->main->ncm);
+               idx = item_index(item->nci);
+
+               if (top >= idx)
+                       top = idx;
+               else
+                       top = idx < rows ? 0 : idx - rows + 1;
+
+               set_top_row(cui->main->ncm, top);
+               set_current_item(item->pmenu->ncm, item->nci);
+
                nc_scr_post(&menu->scr);
        } else {
                cod = item->data;
@@ -217,7 +246,6 @@ static void cui_boot_editor_on_exit(struct cui *cui,
 
        cod->bd = talloc_steal(cod, bd);
 
-       set_current_item(item->pmenu->ncm, item->nci);
 out:
        cui_set_current(cui, &cui->main->scr);
        talloc_free(cui->boot_editor);
@@ -281,6 +309,19 @@ void cui_show_lang(struct cui *cui)
        cui_set_current(cui, lang_screen_scr(cui->lang_screen));
 }
 
+static void cui_add_url_exit(struct cui *cui)
+{
+       cui_set_current(cui, &cui->main->scr);
+       talloc_free(cui->add_url_screen);
+       cui->add_url_screen = NULL;
+}
+
+void cui_show_add_url(struct cui *cui)
+{
+       cui->add_url_screen = add_url_screen_init(cui, cui_add_url_exit);
+       cui_set_current(cui, add_url_screen_scr(cui->add_url_screen));
+}
+
 static void cui_help_exit(struct cui *cui)
 {
        cui_set_current(cui, help_screen_return_scr(cui->help_screen));
@@ -304,6 +345,29 @@ void cui_show_help(struct cui *cui, const char *title,
                cui_set_current(cui, help_screen_scr(cui->help_screen));
 }
 
+static void cui_subset_exit(struct cui *cui)
+{
+       cui_set_current(cui, subset_screen_return_scr(cui->subset_screen));
+       talloc_free(cui->subset_screen);
+       cui->subset_screen = NULL;
+}
+
+void cui_show_subset(struct cui *cui, const char *title,
+                    void *arg)
+{
+       if (!cui->current)
+               return;
+
+       if (cui->subset_screen)
+               return;
+
+       cui->subset_screen = subset_screen_init(cui, cui->current,
+                       title, arg, cui_subset_exit);
+
+       if (cui->subset_screen)
+               cui_set_current(cui, subset_screen_scr(cui->subset_screen));
+}
+
 /**
  * cui_set_current - Set the currently active screen and redraw it.
  */
@@ -514,7 +578,7 @@ static int cui_boot_option_add(struct device *dev, struct boot_option *opt,
                /* If our index is above the current top row, align
                 * us to the new top. Otherwise, align us to the new
                 * bottom */
-               top = top < idx ? idx - rows : idx;
+               top = top < idx ? idx - rows + 1 : idx;
 
                set_top_row(cui->main->ncm, top);
                set_current_item(cui->main->ncm, selected);
@@ -538,6 +602,7 @@ static void cui_device_remove(struct device *dev, void *arg)
        struct cui *cui = cui_from_arg(arg);
        struct boot_option *opt;
        unsigned int i;
+       int rows, cols, top, last;
        int result;
 
        pb_log("%s: %p %s\n", __func__, dev, dev->id);
@@ -574,6 +639,15 @@ static void cui_device_remove(struct device *dev, void *arg)
 
        result = set_menu_items(cui->main->ncm, cui->main->items);
 
+       /* Move cursor to 'Exit' menu entry */
+       menu_format(cui->main->ncm, &rows, &cols);
+       last = cui->main->item_count - 1;
+       set_current_item(cui->main->ncm, cui->main->items[last]);
+       if (!item_visible(cui->main->items[last])) {
+               top = last < rows ? 0 : last - rows + 1;
+               set_top_row(cui->main->ncm, top);
+       }
+
        if (result)
                pb_log("%s: set_menu_items failed: %d\n", __func__, result);
 
@@ -684,6 +758,11 @@ int cui_send_config(struct cui *cui, struct config *config)
        return discover_client_send_config(cui->client, config);
 }
 
+int cui_send_url(struct cui *cui, char * url)
+{
+       return discover_client_send_url(cui->client, url);
+}
+
 void cui_send_reinit(struct cui *cui)
 {
        discover_client_send_reinit(cui->client);
@@ -713,6 +792,12 @@ static int menu_reinit_execute(struct pmenu_item *item)
        return 0;
 }
 
+static int menu_add_url_execute(struct pmenu_item *item)
+{
+       cui_show_add_url(cui_from_item(item));
+       return 0;
+}
+
 /**
  * pb_mm_init - Setup the main menu instance.
  */
@@ -722,7 +807,7 @@ static struct pmenu *main_menu_init(struct cui *cui)
        struct pmenu *m;
        int result;
 
-       m = pmenu_init(cui, 6, cui_on_exit);
+       m = pmenu_init(cui, 7, cui_on_exit);
        if (!m) {
                pb_log("%s: failed\n", __func__);
                return NULL;
@@ -760,9 +845,13 @@ static struct pmenu *main_menu_init(struct cui *cui)
        i->on_execute = menu_reinit_execute;
        pmenu_item_insert(m, i, 4);
 
+       i = pmenu_item_create(m, _("Retrieve config from URL"));
+       i->on_execute = menu_add_url_execute;
+       pmenu_item_insert(m, i, 5);
+
        i = pmenu_item_create(m, _("Exit to shell"));
        i->on_execute = pmenu_exit_cb;
-       pmenu_item_insert(m, i, 5);
+       pmenu_item_insert(m, i, 6);
 
        result = pmenu_setup(m);