summaryrefslogtreecommitdiffstats
path: root/ui/ncurses
diff options
context:
space:
mode:
Diffstat (limited to 'ui/ncurses')
-rw-r--r--ui/ncurses/Makefile.am4
-rw-r--r--ui/ncurses/generic-main.c14
-rw-r--r--ui/ncurses/nc-cui.c21
-rw-r--r--ui/ncurses/nc-cui.h2
-rw-r--r--ui/ncurses/nc-menu.c5
-rw-r--r--ui/ncurses/nc-scr.h11
-rw-r--r--ui/ncurses/nc-sysinfo.c249
-rw-r--r--ui/ncurses/nc-sysinfo.h34
8 files changed, 332 insertions, 8 deletions
diff --git a/ui/ncurses/Makefile.am b/ui/ncurses/Makefile.am
index 64b6eb1..ac4ca46 100644
--- a/ui/ncurses/Makefile.am
+++ b/ui/ncurses/Makefile.am
@@ -36,7 +36,9 @@ libpbnc_la_SOURCES = \
nc-menu.c \
nc-menu.h \
nc-scr.c \
- nc-scr.h
+ nc-scr.h \
+ nc-sysinfo.c \
+ nc-sysinfo.h
sbin_PROGRAMS = petitboot-nc
diff --git a/ui/ncurses/generic-main.c b/ui/ncurses/generic-main.c
index 49a96cb..9d8ebb9 100644
--- a/ui/ncurses/generic-main.c
+++ b/ui/ncurses/generic-main.c
@@ -126,6 +126,12 @@ struct pb_cui {
struct cui *cui;
};
+static int pmenu_sysinfo(struct pmenu_item *item)
+{
+ cui_show_sysinfo(cui_from_item(item));
+ return 0;
+}
+
/**
* pb_mm_init - Setup the main menu instance.
*/
@@ -136,7 +142,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, 1, cui_on_exit);
+ m = pmenu_init(pb_cui->cui, 3, cui_on_exit);
if (!m) {
pb_log("%s: failed\n", __func__);
@@ -152,7 +158,11 @@ static struct pmenu *pb_mm_init(struct pb_cui *pb_cui)
"Enter=accept, e=edit, n=new, x=exit");
m->scr.frame.status = talloc_strdup(m, "Welcome to Petitboot");
- i = pmenu_item_init(m, 0, "Exit to Shell");
+ i = pmenu_item_init(m, 0, " ");
+ 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->on_execute = pmenu_exit_cb;
result = pmenu_setup(m);
diff --git a/ui/ncurses/nc-cui.c b/ui/ncurses/nc-cui.c
index b734cdc..5f41196 100644
--- a/ui/ncurses/nc-cui.c
+++ b/ui/ncurses/nc-cui.c
@@ -34,6 +34,7 @@
#include "process/process.h"
#include "ui/common/discover-client.h"
#include "nc-cui.h"
+#include "nc-sysinfo.h"
static struct cui_opt_data *cod_from_item(struct pmenu_item *item)
{
@@ -236,6 +237,20 @@ void cui_item_new(struct pmenu *menu)
cui_set_current(cui, &boot_editor->scr);
}
+static void cui_sysinfo_exit(struct cui *cui)
+{
+ cui_set_current(cui, &cui->main->scr);
+ talloc_free(cui->sysinfo_screen);
+ cui->sysinfo_screen = NULL;
+}
+
+void cui_show_sysinfo(struct cui *cui)
+{
+ cui->sysinfo_screen = sysinfo_screen_init(cui, cui->sysinfo,
+ cui_sysinfo_exit);
+ cui_set_current(cui, sysinfo_screen_scr(cui->sysinfo_screen));
+}
+
/**
* cui_set_current - Set the currently active screen and redraw it.
*/
@@ -506,6 +521,12 @@ static void cui_update_sysinfo(struct system_info *sysinfo, void *arg)
{
struct cui *cui = cui_from_arg(arg);
cui->sysinfo = talloc_steal(cui, sysinfo);
+
+ /* if we're currently displaying the system info screen, inform it
+ * of the updated information. */
+ if (cui->sysinfo_screen)
+ sysinfo_screen_update(cui->sysinfo_screen, sysinfo);
+
cui_update_mm_title(cui);
}
diff --git a/ui/ncurses/nc-cui.h b/ui/ncurses/nc-cui.h
index 730e721..d1edd79 100644
--- a/ui/ncurses/nc-cui.h
+++ b/ui/ncurses/nc-cui.h
@@ -56,6 +56,7 @@ struct cui {
struct waitset *waitset;
struct discover_client *client;
struct system_info *sysinfo;
+ struct sysinfo_screen *sysinfo_screen;
struct pjs *pjs;
void *platform_info;
unsigned int default_item;
@@ -69,6 +70,7 @@ struct nc_scr *cui_set_current(struct cui *cui, struct nc_scr *scr);
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);
/* convenience routines */
diff --git a/ui/ncurses/nc-menu.c b/ui/ncurses/nc-menu.c
index 4dba0ad..dc46807 100644
--- a/ui/ncurses/nc-menu.c
+++ b/ui/ncurses/nc-menu.c
@@ -27,6 +27,7 @@
#include "log/log.h"
#include "talloc/talloc.h"
#include "ui/common/ui-system.h"
+#include "nc-cui.h"
#include "nc-menu.h"
/**
@@ -242,6 +243,8 @@ 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));
default:
menu_driver(menu->ncm, key);
break;
@@ -378,6 +381,8 @@ int pmenu_setup(struct pmenu *menu)
/* Makes menu scrollable. */
set_menu_format(menu->ncm, LINES - nc_scr_frame_lines, 1);
+ set_menu_grey(menu->ncm, A_NORMAL);
+
return 0;
}
diff --git a/ui/ncurses/nc-scr.h b/ui/ncurses/nc-scr.h
index 4f9de59..e3ed20a 100644
--- a/ui/ncurses/nc-scr.h
+++ b/ui/ncurses/nc-scr.h
@@ -40,11 +40,12 @@
enum pb_nc_sig {
- pb_cui_sig = 111,
- pb_pmenu_sig = 222,
- pb_item_sig = 333,
- pb_boot_editor_sig = 444,
- pb_removed_sig = -555,
+ pb_cui_sig = 111,
+ pb_pmenu_sig = 222,
+ pb_item_sig = 333,
+ pb_boot_editor_sig = 444,
+ pb_sysinfo_screen_sig = 555,
+ pb_removed_sig = -666,
};
static inline void nc_flush_keys(void)
diff --git a/ui/ncurses/nc-sysinfo.c b/ui/ncurses/nc-sysinfo.c
new file mode 100644
index 0000000..4cba9a9
--- /dev/null
+++ b/ui/ncurses/nc-sysinfo.c
@@ -0,0 +1,249 @@
+/*
+ * 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 <util/util.h>
+
+#include "config.h"
+#include "nc-cui.h"
+#include "nc-sysinfo.h"
+
+struct sysinfo_screen {
+ struct nc_scr scr;
+ struct cui *cui;
+ char **lines;
+ int n_lines;
+ int n_alloc_lines;
+ int scroll_y;
+ void (*on_exit)(struct cui *);
+};
+
+static struct sysinfo_screen *sysinfo_screen_from_scr(struct nc_scr *scr)
+{
+ struct sysinfo_screen *sysinfo_screen;
+
+ assert(scr->sig == pb_sysinfo_screen_sig);
+ sysinfo_screen = (struct sysinfo_screen *)
+ ((char *)scr - (size_t)&((struct sysinfo_screen *)0)->scr);
+ assert(sysinfo_screen->scr.sig == pb_sysinfo_screen_sig);
+ return sysinfo_screen;
+}
+
+static void sysinfo_screen_draw(struct sysinfo_screen *screen)
+{
+ int max_y, i;
+
+ max_y = getmaxy(screen->scr.sub_ncw);
+
+ max_y = min(max_y, screen->scroll_y + screen->n_lines);
+
+ for (i = screen->scroll_y; i < max_y; i++)
+ mvwaddstr(screen->scr.sub_ncw, i, 1, screen->lines[i]);
+
+ wrefresh(screen->scr.sub_ncw);
+}
+
+static void sysinfo_screen_scroll(struct sysinfo_screen *screen, int key)
+{
+ int win_lines = getmaxy(screen->scr.sub_ncw);
+ int delta;
+
+ if (key == KEY_UP)
+ delta = -1;
+ else if (key == KEY_DOWN)
+ delta = 1;
+ else
+ return;
+
+ if (screen->scroll_y + delta < 0)
+ return;
+ if (screen->scroll_y + delta + win_lines > screen->n_lines - 1)
+ return;
+
+ screen->scroll_y += delta;
+ wscrl(screen->scr.sub_ncw, delta);
+
+ if (delta > 0) {
+ mvwaddstr(screen->scr.sub_ncw, win_lines - 1, 1,
+ screen->lines[screen->scroll_y+win_lines-1]);
+ } else if (delta < 0) {
+ mvwaddstr(screen->scr.sub_ncw, 0, 1,
+ screen->lines[screen->scroll_y]);
+ }
+
+ wrefresh(screen->scr.sub_ncw);
+}
+
+static void sysinfo_clear(struct sysinfo_screen *screen)
+{
+ talloc_free(screen->lines);
+ screen->n_lines = 0;
+ screen->n_alloc_lines = 16;
+ screen->lines = talloc_array(screen, char *, screen->n_alloc_lines);
+}
+
+static __attribute__((format(printf, 2, 3))) void sysinfo_screen_append_line(
+ struct sysinfo_screen *screen, const char *fmt, ...)
+{
+ char *line;
+ va_list ap;
+
+ if (fmt) {
+ va_start(ap, fmt);
+ line = talloc_vasprintf(screen->lines, fmt, ap);
+ va_end(ap);
+ } else {
+ line = "";
+ }
+
+ if (screen->n_lines == screen->n_alloc_lines) {
+ screen->n_alloc_lines *= 2;
+ screen->lines = talloc_realloc(screen, screen->lines,
+ char *, screen->n_alloc_lines);
+ }
+
+ screen->lines[screen->n_lines] = line;
+ screen->n_lines++;
+}
+
+static void mac_str(struct interface_info *info, char *buf, unsigned int buflen)
+{
+ unsigned int i;
+ char *pos;
+
+ assert(buflen > sizeof("unknown"));
+
+ if (!info->hwaddr_size || info->hwaddr_size * 3 + 1 > buflen) {
+ strcpy(buf, "unknown");
+ return;
+ }
+
+ pos = buf;
+
+ for (i = 0; i < info->hwaddr_size; i++) {
+ snprintf(pos, 4, "%02x:", info->hwaddr[i]);
+ pos += 3;
+ }
+
+ *(pos - 1) = '\0';
+
+ return;
+}
+
+static void sysinfo_screen_populate(struct sysinfo_screen *screen,
+ const struct system_info *sysinfo)
+{
+ unsigned int i;
+
+ sysinfo_clear(screen);
+
+#define line(...) sysinfo_screen_append_line(screen, __VA_ARGS__)
+ if (!sysinfo) {
+ line("Waiting for system information...");
+ return;
+ }
+
+ line("%-12s %s", "System type:", sysinfo->type ?: "");
+ line("%-12s %s", "System id:", sysinfo->identifier ?: "");
+
+ line(NULL);
+ if (sysinfo->n_interfaces)
+ line("Network interfaces");
+
+ for (i = 0; i < sysinfo->n_interfaces; i++) {
+ struct interface_info *info = sysinfo->interfaces[i];
+ char macbuf[32];
+
+ mac_str(info, macbuf, sizeof(macbuf));
+
+ line("%s:", info->name);
+ line(" MAC: %s", macbuf);
+ line(NULL);
+ }
+
+#undef line
+}
+
+static void sysinfo_screen_process_key(struct nc_scr *scr, int key)
+{
+ struct sysinfo_screen *screen = sysinfo_screen_from_scr(scr);
+
+ switch (key) {
+ case 'x':
+ screen->on_exit(screen->cui);
+ break;
+ case KEY_DOWN:
+ case KEY_UP:
+ sysinfo_screen_scroll(screen, key);
+ break;
+ default:
+ break;
+ }
+}
+
+static void sysinfo_screen_resize(struct nc_scr *scr)
+{
+ struct sysinfo_screen *screen = sysinfo_screen_from_scr(scr);
+ sysinfo_screen_draw(screen);
+}
+
+struct nc_scr *sysinfo_screen_scr(struct sysinfo_screen *screen)
+{
+ return &screen->scr;
+}
+
+void sysinfo_screen_update(struct sysinfo_screen *screen,
+ const struct system_info *sysinfo)
+{
+ sysinfo_screen_populate(screen, sysinfo);
+ sysinfo_screen_draw(screen);
+}
+
+struct sysinfo_screen *sysinfo_screen_init(struct cui *cui,
+ const struct system_info *sysinfo,
+ void (*on_exit)(struct cui *))
+{
+ struct sysinfo_screen *screen;
+
+ screen = talloc_zero(cui, struct sysinfo_screen);
+ nc_scr_init(&screen->scr, pb_sysinfo_screen_sig, 0,
+ cui, sysinfo_screen_process_key,
+ NULL, NULL, sysinfo_screen_resize);
+
+ screen->cui = cui;
+ screen->on_exit = on_exit;
+
+ screen->scr.frame.ltitle = talloc_strdup(screen,
+ "Petitboot System Information");
+ screen->scr.frame.rtitle = NULL;
+ screen->scr.frame.help = talloc_strdup(screen, "x=exit");
+ nc_scr_frame_draw(&screen->scr);
+
+ sysinfo_screen_populate(screen, sysinfo);
+ wrefresh(screen->scr.main_ncw);
+ scrollok(screen->scr.sub_ncw, true);
+ sysinfo_screen_draw(screen);
+
+ return screen;
+}
diff --git a/ui/ncurses/nc-sysinfo.h b/ui/ncurses/nc-sysinfo.h
new file mode 100644
index 0000000..5407bf8
--- /dev/null
+++ b/ui/ncurses/nc-sysinfo.h
@@ -0,0 +1,34 @@
+/*
+ * 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_SYSINFO_H
+#define _NC_SYSINFO_H
+
+#include "types/types.h"
+#include "nc-cui.h"
+
+struct sysinfo_screen;
+
+struct sysinfo_screen *sysinfo_screen_init(struct cui *cui,
+ const struct system_info *sysinfo,
+ void (*on_exit)(struct cui *));
+
+struct nc_scr *sysinfo_screen_scr(struct sysinfo_screen *screen);
+void sysinfo_screen_update(struct sysinfo_screen *screen,
+ const struct system_info *sysinfo);
+
+#endif /* defined _NC_SYSINFO_H */
OpenPOWER on IntegriCloud