Render each column to the ncurses raw buffer first, this buffer
contains ncurses {char:attr} elements which will be printed
to the screen after ui_table_row_show() will
be called (at the end of columns rendering by flowtop).

The reason of this change is to have easy way to
make horizontal scrolling over this buffer.

Approach is used from the 'htop' tool.

Signed-off-by: Vadim Kochan <vadi...@gmail.com>
---
 flowtop.c |  9 +++++++
 ui.c      | 84 ++++++++++++++++++++++++++++++++++++++++++++++++++++-----------
 ui.h      |  8 ++++++
 3 files changed, 87 insertions(+), 14 deletions(-)

diff --git a/flowtop.c b/flowtop.c
index 405bfd8..d98a7b6 100644
--- a/flowtop.c
+++ b/flowtop.c
@@ -1017,10 +1017,19 @@ static void draw_flow_entry(const struct flow_entry *n)
 
        print_flow_peer_info(n, show_src ? FLOW_DIR_SRC : FLOW_DIR_DST);
 
+       ui_table_row_show(&flows_tbl);
+
        if (show_src) {
                ui_table_row_add(&flows_tbl);
 
+               ui_table_row_print(&flows_tbl, TBL_FLOW_PROCESS, "");
+               ui_table_row_print(&flows_tbl, TBL_FLOW_PID, "");
+               ui_table_row_print(&flows_tbl, TBL_FLOW_PROTO, "");
+               ui_table_row_print(&flows_tbl, TBL_FLOW_STATE, "");
+               ui_table_row_print(&flows_tbl, TBL_FLOW_TIME, "");
+
                print_flow_peer_info(n, FLOW_DIR_DST);
+               ui_table_row_show(&flows_tbl);
        }
 }
 
diff --git a/ui.c b/ui.c
index 46062d4..348a131 100644
--- a/ui.c
+++ b/ui.c
@@ -6,8 +6,52 @@
 #include <curses.h>
 
 #include "ui.h"
+#include "str.h"
 #include "xmalloc.h"
 
+static struct ui_text *ui_text_alloc(size_t len)
+{
+       struct ui_text *text;
+
+       text = xzmalloc(sizeof(*text));
+       text->str = xzmalloc(sizeof(chtype) * len + 1);
+       text->len = len;
+
+       return text;
+}
+
+static void ui_text_len_set(struct ui_text *text, size_t len)
+{
+       if (text->len == len)
+               return;
+
+       if (text->slen + len > text->len) {
+               text->str = xrealloc(text->str, sizeof(chtype) * len + 1);
+               text->len = len;
+       }
+
+       text->slen = min(len, text->slen);
+       text->str[text->slen] = 0;
+}
+
+static void ui_text_attr_insert(struct ui_text *text, int idx, int attr, const 
char *str)
+{
+       size_t slen = strlen(str);
+       uint32_t i, j;
+
+       if (idx + slen > text->len)
+               ui_text_len_set(text, idx + slen);
+
+       for (j = 0, i = idx; i < idx + slen; i++, j++)
+               text->str[i] = str[j] | attr;
+}
+
+static void ui_text_free(struct ui_text *text)
+{
+       xfree(text->str);
+       xfree(text);
+}
+
 void ui_table_init(struct ui_table *tbl)
 {
        memset(tbl, 0, sizeof(*tbl));
@@ -18,6 +62,7 @@ void ui_table_init(struct ui_table *tbl)
        tbl->width   = COLS;
        tbl->height  = LINES - 2;
        tbl->col_pad = 1;
+       tbl->row     = ui_text_alloc(tbl->width);
 
        INIT_LIST_HEAD(&tbl->cols);
 }
@@ -28,6 +73,8 @@ void ui_table_uninit(struct ui_table *tbl)
 
        list_for_each_entry_safe(col, tmp, &tbl->cols, entry)
                xfree(col);
+
+       ui_text_free(tbl->row);
 }
 
 void ui_table_pos_set(struct ui_table *tbl, int y, int x)
@@ -52,7 +99,7 @@ static struct ui_col *ui_table_col_get(struct ui_table *tbl, 
uint32_t id)
 static void __ui_table_pos_update(struct ui_table *tbl)
 {
        struct ui_col *col;
-       uint32_t pos = tbl->x;
+       uint32_t pos = 0;
 
        list_for_each_entry(col, &tbl->cols, entry) {
                col->pos  = pos;
@@ -106,20 +153,29 @@ void ui_table_clear(struct ui_table *tbl)
 
 #define UI_ALIGN_COL(col) (((col)->align == UI_ALIGN_LEFT) ? "%-*.*s" : 
"%*.*s")
 
+void ui_table_row_show(struct ui_table *tbl)
+{
+       mvaddchstr(tbl->rows_y, tbl->x, tbl->row->str);
+       ui_text_len_set(tbl->row, 0);
+}
+
 static void __ui_table_row_print(struct ui_table *tbl, struct ui_col *col,
-                                const char *str)
+                                int color, const char *str)
 {
-       mvprintw(tbl->rows_y, col->pos, UI_ALIGN_COL(col), col->len, col->len, 
str);
-       mvprintw(tbl->rows_y, col->pos + col->len, "%*s", tbl->col_pad, " ");
+       char tmp[128];
+
+       slprintf(tmp, sizeof(tmp), UI_ALIGN_COL(col), col->len, col->len, str);
+       ui_text_attr_insert(tbl->row, col->pos, color, tmp);
+
+       slprintf(tmp, sizeof(tmp), "%*s", tbl->col_pad, " ");
+       ui_text_attr_insert(tbl->row, col->pos + col->len, color, tmp);
 }
 
 void ui_table_row_print(struct ui_table *tbl, uint32_t col_id, const char *str)
 {
        struct ui_col *col = ui_table_col_get(tbl, col_id);
 
-       attron(col->color);
-       __ui_table_row_print(tbl, col, str);
-       attroff(col->color);
+       __ui_table_row_print(tbl, col, col->color, str);
 }
 
 void ui_table_header_color_set(struct ui_table *tbl, int color)
@@ -138,16 +194,16 @@ void ui_table_header_print(struct ui_table *tbl)
        int max_width = tbl->width;
        int width = 0;
 
-       attron(tbl->hdr_color);
-
-       mvprintw(tbl->y, tbl->x, "%-*.*s", max_width - tbl->x, max_width - 
tbl->x, "");
-       mvprintw(tbl->y, tbl->x, "");
-
        list_for_each_entry(col, &tbl->cols, entry) {
-               __ui_table_row_print(tbl, col, col->name);
-               width += col->len + tbl->col_pad;
+               __ui_table_row_print(tbl, col, tbl->hdr_color, col->name);
+
+               if (width + col->len + tbl->col_pad < max_width)
+                       width += col->len + tbl->col_pad;
        }
 
+       ui_table_row_show(tbl);
+
+       attron(tbl->hdr_color);
        mvprintw(tbl->y, width, "%*s", max_width - width, " ");
        attroff(tbl->hdr_color);
 }
diff --git a/ui.h b/ui.h
index ff55606..7f4814c 100644
--- a/ui.h
+++ b/ui.h
@@ -11,6 +11,12 @@ enum ui_align {
        UI_ALIGN_RIGHT,
 };
 
+struct ui_text {
+       chtype *str;
+       size_t slen;
+       size_t len;
+};
+
 struct ui_col {
        struct list_head entry;
        uint32_t id;
@@ -26,6 +32,7 @@ struct ui_table {
        int x;
        int rows_y;
        struct list_head cols;
+       struct ui_text *row;
        int hdr_color;
        int col_pad;
        int width;
@@ -44,6 +51,7 @@ extern void ui_table_col_color_set(struct ui_table *tbl, int 
col_id, int color);
 extern void ui_table_col_align_set(struct ui_table *tbl, int col_id, enum 
ui_align align);
 
 extern void ui_table_row_add(struct ui_table *tbl);
+extern void ui_table_row_show(struct ui_table *tbl);
 extern void ui_table_row_print(struct ui_table *tbl, uint32_t col_id,
                               const char *str);
 
-- 
2.9.2

-- 
You received this message because you are subscribed to the Google Groups 
"netsniff-ng" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to netsniff-ng+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

Reply via email to