]> git.ozlabs.org Git - petitboot/blobdiff - ui/ncurses/nc-sysinfo.c
ui/ncurses: Improve update handling in nested screens
[petitboot] / ui / ncurses / nc-sysinfo.c
index 1d7bd1e2834cf8b499517a8320be44dcb68529f0..ac8ece785f6533a3708233de608c6652941e1cde 100644 (file)
@@ -15,8 +15,9 @@
  *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
  */
 
-#define _GNU_SOURCE
-
+#if defined(HAVE_CONFIG_H)
+#include "config.h"
+#endif
 
 #include <string.h>
 
 #include <types/types.h>
 #include <log/log.h>
 #include <util/util.h>
+#include <i18n/i18n.h>
 
-#include "config.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;
+extern const struct help_text sysinfo_help_text;
 
-       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, ...)
+struct nc_scr *sysinfo_screen_scr(struct sysinfo_screen *screen)
 {
-       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 mac_str(struct interface_info *info, char *buf, unsigned int buflen)
+static void if_info_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;
+       return mac_str(info->hwaddr, info->hwaddr_size, buf, buflen);
 }
 
 static void sysinfo_screen_populate(struct sysinfo_screen *screen,
@@ -156,83 +53,62 @@ 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...");
+               line(_("Waiting for system information..."));
                return;
        }
 
-       line("%-12s %s", "System type:", sysinfo->type ?: "");
-       line("%-12s %s", "System id:",   sysinfo->identifier ?: "");
+       line("%-12s %s", _("System type:"), sysinfo->type ?: "");
+       line("%-12s %s", _("System id:"),   sysinfo->identifier ?: "");
 
        if (sysinfo->n_blockdevs) {
                line(NULL);
-               line("Storage devices");
+               line(_("Storage devices"));
        }
 
        for (i = 0; i < sysinfo->n_blockdevs; i++) {
                struct blockdev_info *info = sysinfo->blockdevs[i];
 
                line("%s:", info->name);
-               line(" UUID:       %s", info->uuid);
-               line(" mounted at: %s", info->mountpoint);
+               line(_(" UUID:       %s"), info->uuid);
+               line(_(" mounted at: %s"), info->mountpoint);
                line(NULL);
        }
 
        if (sysinfo->n_interfaces) {
                line(NULL);
-               line("Network 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));
+               if_info_mac_str(info, macbuf, sizeof(macbuf));
 
                line("%s:", info->name);
-               line(" MAC: %s", macbuf);
+               line(_(" MAC:  %s"), macbuf);
+               /* TRANSLATORS: these "up" / "down" strings refer to the
+                * link status for a network connection. */
+               line(_(" link: %s"), info->link ? _("up") : _("down"));
                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);
+
+       if (screen->text_scr.cui->help_screen)
+               screen->text_scr.need_update = true;
+       else
+               text_screen_draw(&screen->text_scr);
 }
 
 struct sysinfo_screen *sysinfo_screen_init(struct cui *cui,
@@ -242,23 +118,12 @@ 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);
+       text_screen_init(&screen->text_scr, cui,
+                       _("Petitboot System Information"), on_exit);
+       text_screen_set_help(&screen->text_scr,
+                       _("System Information"), &sysinfo_help_text);
 
-       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);
+       sysinfo_screen_update(screen, sysinfo);
 
        return screen;
 }