ui/ncurses: Add basic config editor
authorJeremy Kerr <jk@ozlabs.org>
Mon, 21 Oct 2013 10:59:12 +0000 (18:59 +0800)
committerJeremy Kerr <jk@ozlabs.org>
Thu, 14 Nov 2013 02:23:25 +0000 (13:23 +1100)
This change adds a simple configuration editor to the ncurses UI.

Signed-off-by: Jeremy Kerr <jk@ozlabs.org>
ui/ncurses/Makefile.am
ui/ncurses/generic-main.c
ui/ncurses/nc-config.c [new file with mode: 0644]
ui/ncurses/nc-config.h [new file with mode: 0644]
ui/ncurses/nc-cui.c
ui/ncurses/nc-cui.h
ui/ncurses/nc-menu.c
ui/ncurses/nc-scr.h

index a341780281b467cd04f2cbaee7483238c8863fc8..61ed67e7cf5a5e66090111555179ad0fa9f20bdb 100644 (file)
@@ -29,6 +29,8 @@ common_libs = \
 noinst_LTLIBRARIES = libpbnc.la
 
 libpbnc_la_SOURCES = \
+       nc-config.c \
+       nc-config.h \
        nc-cui.c \
        nc-cui.h \
        nc-boot-editor.c \
index 9d8ebb9b766e6804ef026211bd200d84d280c85c..feff506cd67e8d8e1c36e45a03c10b60a213bca9 100644 (file)
@@ -132,6 +132,12 @@ static int pmenu_sysinfo(struct pmenu_item *item)
        return 0;
 }
 
+static int pmenu_config(struct pmenu_item *item)
+{
+       cui_show_config(cui_from_item(item));
+       return 0;
+}
+
 /**
  * pb_mm_init - Setup the main menu instance.
  */
@@ -142,7 +148,7 @@ static struct pmenu *pb_mm_init(struct pb_cui *pb_cui)
        struct pmenu *m;
        struct pmenu_item *i;
 
-       m = pmenu_init(pb_cui->cui, 3, cui_on_exit);
+       m = pmenu_init(pb_cui->cui, 4, cui_on_exit);
 
        if (!m) {
                pb_log("%s: failed\n", __func__);
@@ -162,7 +168,9 @@ static struct pmenu *pb_mm_init(struct pb_cui *pb_cui)
        item_opts_off(i->nci, O_SELECTABLE);
        i = pmenu_item_init(m, 1, "System information");
        i->on_execute = pmenu_sysinfo;
-       i = pmenu_item_init(m, 2, "Exit to shell");
+       i = pmenu_item_init(m, 2, "System configuration");
+       i->on_execute = pmenu_config;
+       i = pmenu_item_init(m, 3, "Exit to shell");
        i->on_execute = pmenu_exit_cb;
 
        result = pmenu_setup(m);
diff --git a/ui/ncurses/nc-config.c b/ui/ncurses/nc-config.c
new file mode 100644 (file)
index 0000000..b7985aa
--- /dev/null
@@ -0,0 +1,213 @@
+/*
+ *  Copyright (C) 2013 IBM Corporation
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; version 2 of the License.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program; if not, write to the Free Software
+ *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ */
+
+#define _GNU_SOURCE
+
+
+#include <string.h>
+
+#include <talloc/talloc.h>
+#include <types/types.h>
+#include <log/log.h>
+
+#include "config.h"
+#include "nc-cui.h"
+#include "nc-config.h"
+#include "nc-widgets.h"
+
+#define N_FIELDS       9
+
+struct config_screen {
+       struct nc_scr           scr;
+       struct cui              *cui;
+       struct nc_widgetset     *widgetset;
+       bool                    exit;
+       void                    (*on_exit)(struct cui *);
+
+       int                     label_x;
+       int                     field_x;
+
+       struct {
+               struct nc_widget_checkbox       *autoboot_f;
+               struct nc_widget_label          *autoboot_l;
+               struct nc_widget_textbox        *timeout_f;
+               struct nc_widget_label          *timeout_l;
+
+               struct nc_widget_label          *network_l;
+               struct nc_widget_label          *iface_l;
+               struct nc_widget_select         *iface_f;
+
+               struct nc_widget_button         *ok_b;
+               struct nc_widget_button         *cancel_b;
+       } widgets;
+};
+
+static struct config_screen *config_screen_from_scr(struct nc_scr *scr)
+{
+       struct config_screen *config_screen;
+
+       assert(scr->sig == pb_config_screen_sig);
+       config_screen = (struct config_screen *)
+               ((char *)scr - (size_t)&((struct config_screen *)0)->scr);
+       assert(config_screen->scr.sig == pb_config_screen_sig);
+       return config_screen;
+}
+
+static void config_screen_process_key(struct nc_scr *scr, int key)
+{
+       struct config_screen *screen = config_screen_from_scr(scr);
+       bool handled;
+
+       handled = widgetset_process_key(screen->widgetset, key);
+       if (screen->exit)
+               screen->on_exit(screen->cui);
+       else if (handled)
+               wrefresh(screen->scr.main_ncw);
+}
+
+static void config_screen_resize(struct nc_scr *scr)
+{
+       struct config_screen *screen = config_screen_from_scr(scr);
+       (void)screen;
+}
+
+static int config_screen_post(struct nc_scr *scr)
+{
+       struct config_screen *screen = config_screen_from_scr(scr);
+       widgetset_post(screen->widgetset);
+       nc_scr_frame_draw(scr);
+       wrefresh(scr->main_ncw);
+       return 0;
+}
+
+static int config_screen_unpost(struct nc_scr *scr)
+{
+       struct config_screen *screen = config_screen_from_scr(scr);
+       widgetset_unpost(screen->widgetset);
+       return 0;
+}
+
+struct nc_scr *config_screen_scr(struct config_screen *screen)
+{
+       return &screen->scr;
+}
+
+static void ok_click(void *arg)
+{
+       struct config_screen *screen = arg;
+       /* todo: save config */
+       screen->on_exit(screen->cui);
+}
+
+static void cancel_click(void *arg)
+{
+       struct config_screen *screen = arg;
+       screen->exit = true;
+}
+
+static int layout_pair(struct config_screen *screen, int y,
+               struct nc_widget_label *label,
+               struct nc_widget *field)
+{
+       struct nc_widget *label_w = widget_label_base(label);
+       widget_move(label_w, y, screen->label_x);
+       widget_move(field, y, screen->field_x);
+       return max(widget_height(label_w), widget_height(field));
+}
+
+static void config_screen_layout_widgets(struct config_screen *screen)
+{
+       int y;
+
+       y = 1;
+
+       y += layout_pair(screen, y, screen->widgets.autoboot_l,
+                       widget_checkbox_base(screen->widgets.autoboot_f));
+
+       y += layout_pair(screen, y, screen->widgets.timeout_l,
+                       widget_textbox_base(screen->widgets.timeout_f));
+
+       y++;
+
+       widget_move(widget_button_base(screen->widgets.ok_b),
+                       y, screen->field_x);
+       widget_move(widget_button_base(screen->widgets.cancel_b),
+                       y, screen->field_x + 10);
+}
+
+static void config_screen_setup_widgets(struct config_screen *screen,
+               const struct config *config,
+               const struct system_info *sysinfo)
+{
+       struct nc_widgetset *set = screen->widgetset;
+       char *str;
+
+       (void)sysinfo;
+
+       build_assert(sizeof(screen->widgets) / sizeof(struct widget *)
+                       == N_FIELDS);
+
+       screen->widgets.autoboot_l = widget_new_label(set, 0, 0, "Autoboot:");
+       screen->widgets.autoboot_f = widget_new_checkbox(set, 0, 0,
+                                       config->autoboot_enabled);
+
+       str = talloc_asprintf(screen, "%d", config->autoboot_timeout_sec);
+       screen->widgets.timeout_l = widget_new_label(set, 0, 0, "Timeout:");
+       screen->widgets.timeout_f = widget_new_textbox(set, 0, 0, 5, str);
+
+       screen->widgets.ok_b = widget_new_button(set, 0, 0, 6, "OK",
+                       ok_click, screen);
+       screen->widgets.cancel_b = widget_new_button(set, 0, 0, 6, "Cancel",
+                       cancel_click, screen);
+
+}
+
+struct config_screen *config_screen_init(struct cui *cui,
+               const struct config *config,
+               const struct system_info *sysinfo,
+               void (*on_exit)(struct cui *))
+{
+       struct config_screen *screen;
+
+       screen = talloc_zero(cui, struct config_screen);
+       nc_scr_init(&screen->scr, pb_config_screen_sig, 0,
+                       cui, config_screen_process_key,
+                       config_screen_post, config_screen_unpost,
+                       config_screen_resize);
+
+       screen->cui = cui;
+       screen->on_exit = on_exit;
+       screen->label_x = 2;
+       screen->field_x = 16;
+
+       screen->scr.frame.ltitle = talloc_strdup(screen,
+                       "Petitboot System Configuration");
+       screen->scr.frame.rtitle = NULL;
+       screen->scr.frame.help = talloc_strdup(screen,
+                       "tab=next, shift+tab=previous");
+       nc_scr_frame_draw(&screen->scr);
+
+       screen->widgetset = widgetset_create(screen, screen->scr.main_ncw,
+                       screen->scr.sub_ncw);
+       config_screen_setup_widgets(screen, config, sysinfo);
+       config_screen_layout_widgets(screen);
+
+       wrefresh(screen->scr.main_ncw);
+       scrollok(screen->scr.sub_ncw, true);
+
+       return screen;
+}
diff --git a/ui/ncurses/nc-config.h b/ui/ncurses/nc-config.h
new file mode 100644 (file)
index 0000000..71e0ea4
--- /dev/null
@@ -0,0 +1,35 @@
+/*
+ *  Copyright (C) 2013 IBM Corporation
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; version 2 of the License.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program; if not, write to the Free Software
+ *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ */
+
+#ifndef _NC_CONFIG_H
+#define _NC_CONFIG_H
+
+#include "types/types.h"
+#include "nc-cui.h"
+
+struct config_screen;
+
+struct config_screen *config_screen_init(struct cui *cui,
+               const struct config *config,
+               const struct system_info *sysinfo,
+               void (*on_exit)(struct cui *));
+
+struct nc_scr *config_screen_scr(struct config_screen *screen);
+void config_screen_update(struct config_screen *screen,
+               const struct config *config);
+
+#endif /* defined _NC_CONFIG_H */
index 6aa2a2869cf0b971c9e41fd6684cf4ba1f5838c5..d74c1a46ece00804e4049835a907c0ad2e20e4e2 100644 (file)
@@ -34,6 +34,7 @@
 #include "process/process.h"
 #include "ui/common/discover-client.h"
 #include "nc-cui.h"
+#include "nc-config.h"
 #include "nc-sysinfo.h"
 
 static struct cui_opt_data *cod_from_item(struct pmenu_item *item)
@@ -251,6 +252,20 @@ void cui_show_sysinfo(struct cui *cui)
        cui_set_current(cui, sysinfo_screen_scr(cui->sysinfo_screen));
 }
 
+static void cui_config_exit(struct cui *cui)
+{
+       cui_set_current(cui, &cui->main->scr);
+       talloc_free(cui->config_screen);
+       cui->config_screen = NULL;
+}
+
+void cui_show_config(struct cui *cui)
+{
+       cui->config_screen = config_screen_init(cui, cui->config,
+                       cui->sysinfo, cui_config_exit);
+       cui_set_current(cui, config_screen_scr(cui->config_screen));
+}
+
 /**
  * cui_set_current - Set the currently active screen and redraw it.
  */
index 0e3708dd80ca4451c45b66dc95e68b93af40895e..752f2db38021a4ec67f751ec89d33190a1fbb745 100644 (file)
@@ -58,6 +58,7 @@ struct cui {
        struct system_info *sysinfo;
        struct sysinfo_screen *sysinfo_screen;
        struct config *config;
+       struct config_screen *config_screen;
        struct pjs *pjs;
        void *platform_info;
        unsigned int default_item;
@@ -72,6 +73,7 @@ int cui_run(struct cui *cui, struct pmenu *main, unsigned int default_item);
 void cui_item_edit(struct pmenu_item *item);
 void cui_item_new(struct pmenu *menu);
 void cui_show_sysinfo(struct cui *cui);
+void cui_show_config(struct cui *cui);
 
 /* convenience routines */
 
index dc4680789d3490ba03a669b59e6e923278077b6d..5dc6469df1b55f9110cf0e2eefa0a6857de9fb5a 100644 (file)
@@ -245,6 +245,10 @@ static void pmenu_process_key(struct nc_scr *scr, int key)
                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;
        default:
                menu_driver(menu->ncm, key);
                break;
index e3ed20a8502d8de3cad30f0fe6d1a3e475a62fb8..060ee4045972e3b94b7b590fd0c499ef57091611 100644 (file)
@@ -45,7 +45,8 @@ enum pb_nc_sig {
        pb_item_sig             = 333,
        pb_boot_editor_sig      = 444,
        pb_sysinfo_screen_sig   = 555,
-       pb_removed_sig          = -666,
+       pb_config_screen_sig    = 666,
+       pb_removed_sig          = -777,
 };
 
 static inline void nc_flush_keys(void)