ui/ncurses: Abstract text-screen code from sysinfo screen
authorJeremy Kerr <jk@ozlabs.org>
Mon, 9 Dec 2013 03:30:19 +0000 (11:30 +0800)
committerJeremy Kerr <jk@ozlabs.org>
Fri, 31 Jan 2014 00:46:34 +0000 (08:46 +0800)
We want to implement help screens, which are very similar to the sysinfo
screen - show a set of lines, and allow scrolling.

This change splits the text-screen rendering code into a new nc-textinfo
module.

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

index 61ed67e7cf5a5e66090111555179ad0fa9f20bdb..c03bdb7f9b42b0933fff75ebfb83a0ed061d6045 100644 (file)
@@ -41,6 +41,8 @@ libpbnc_la_SOURCES = \
        nc-scr.h \
        nc-sysinfo.c \
        nc-sysinfo.h \
+       nc-textscreen.c \
+       nc-textscreen.h \
        nc-widgets.c \
        nc-widgets.h
 
index 060ee4045972e3b94b7b590fd0c499ef57091611..50cce33106838428e1be7e2d867e397eee4f5eff 100644 (file)
@@ -44,7 +44,7 @@ enum pb_nc_sig {
        pb_pmenu_sig            = 222,
        pb_item_sig             = 333,
        pb_boot_editor_sig      = 444,
-       pb_sysinfo_screen_sig   = 555,
+       pb_text_screen_sig      = 555,
        pb_config_screen_sig    = 666,
        pb_removed_sig          = -777,
 };
index 1a3d3f5227b0c704ec8e140b70573c616ba4afd0..e907e3dc88ae6836affdc0bf312780f47da446f8 100644 (file)
 #include <util/util.h>
 
 #include "nc-cui.h"
+#include "nc-textscreen.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 *);
+       struct text_screen text_scr;
 };
 
-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)
+struct nc_scr *sysinfo_screen_scr(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++;
+       return text_screen_scr(&screen->text_scr);
 }
 
 static void if_info_mac_str(struct interface_info *info,
@@ -138,9 +50,9 @@ static void sysinfo_screen_populate(struct sysinfo_screen *screen,
 {
        unsigned int i;
 
-       sysinfo_clear(screen);
+       text_screen_clear(&screen->text_scr);
 
-#define line(...) sysinfo_screen_append_line(screen, __VA_ARGS__)
+#define line(...) text_screen_append_line(&screen->text_scr, __VA_ARGS__)
        if (!sysinfo) {
                line("Waiting for system information...");
                return;
@@ -183,39 +95,11 @@ static void sysinfo_screen_populate(struct sysinfo_screen *screen,
 #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);
+       text_screen_draw(&screen->text_scr);
 }
 
 struct sysinfo_screen *sysinfo_screen_init(struct cui *cui,
@@ -225,23 +109,10 @@ struct sysinfo_screen *sysinfo_screen_init(struct cui *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;
+       text_screen_init(&screen->text_scr, cui,
+                       "Petitboot System Information", 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);
+       sysinfo_screen_update(screen, sysinfo);
 
        return screen;
 }
diff --git a/ui/ncurses/nc-textscreen.c b/ui/ncurses/nc-textscreen.c
new file mode 100644 (file)
index 0000000..3b0d01d
--- /dev/null
@@ -0,0 +1,167 @@
+/*
+ *  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
+ */
+
+#if defined(HAVE_CONFIG_H)
+#include "config.h"
+#endif
+
+#include <string.h>
+
+#include <talloc/talloc.h>
+#include <types/types.h>
+#include <log/log.h>
+#include <util/util.h>
+
+#include "nc-cui.h"
+#include "nc-textscreen.h"
+
+struct text_screen *text_screen_from_scr(struct nc_scr *scr)
+{
+       struct text_screen *text_screen;
+       assert(scr->sig == pb_text_screen_sig);
+       text_screen = container_of(scr, struct text_screen, scr);
+       return text_screen;
+}
+
+void text_screen_draw(struct text_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 text_screen_scroll(struct text_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)
+               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);
+}
+
+void text_screen_clear(struct text_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);
+}
+
+void text_screen_append_line(struct text_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++;
+}
+
+
+void text_screen_process_key(struct nc_scr *scr, int key)
+{
+       struct text_screen *screen = text_screen_from_scr(scr);
+
+       switch (key) {
+       case 'x':
+               screen->on_exit(screen->cui);
+               break;
+       case KEY_DOWN:
+       case KEY_UP:
+               text_screen_scroll(screen, key);
+               break;
+       default:
+               break;
+       }
+}
+
+static void text_screen_resize(struct nc_scr *scr)
+{
+       struct text_screen *screen = text_screen_from_scr(scr);
+       text_screen_draw(screen);
+}
+
+struct nc_scr *text_screen_scr(struct text_screen *screen)
+{
+       return &screen->scr;
+}
+
+static int text_screen_post(struct nc_scr *scr)
+{
+       nc_scr_frame_draw(scr);
+       redrawwin(scr->main_ncw);
+       wrefresh(scr->main_ncw);
+       return 0;
+}
+
+void text_screen_init(struct text_screen *screen, struct cui *cui,
+               const char *title, void (*on_exit)(struct cui *))
+{
+       nc_scr_init(&screen->scr, pb_text_screen_sig, 0,
+                       cui, text_screen_process_key,
+                       text_screen_post, NULL, text_screen_resize);
+
+       screen->cui = cui;
+       screen->on_exit = on_exit;
+
+       screen->scr.frame.ltitle = talloc_strdup(screen, title);
+       screen->scr.frame.rtitle = NULL;
+       screen->scr.frame.help = "x=exit";
+       scrollok(screen->scr.sub_ncw, true);
+}
diff --git a/ui/ncurses/nc-textscreen.h b/ui/ncurses/nc-textscreen.h
new file mode 100644 (file)
index 0000000..92c6bfe
--- /dev/null
@@ -0,0 +1,50 @@
+/*
+ *  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_TEXTSCREEN_H
+#define _NC_TEXTSCREEN_H
+
+#include "types/types.h"
+#include "nc-cui.h"
+
+struct text_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 *);
+};
+
+void text_screen_init(struct text_screen *screen, struct cui *cui,
+               const char *title, void (*on_exit)(struct cui *));
+
+struct text_screen *text_screen_from_scr(struct nc_scr *scr);
+struct nc_scr *text_screen_scr(struct text_screen *screen);
+
+/* content modification */
+void text_screen_clear(struct text_screen *screen);
+void text_screen_append_line(struct text_screen *screen,
+               const char *fmt, ...) __attribute__((format(printf, 2, 3)));
+
+/* interaction */
+void text_screen_process_key(struct nc_scr *scr, int key);
+void text_screen_draw(struct text_screen *screen);
+
+
+#endif /* defined _NC_TEXTSCREEN_H */