Add ui_tab API to create ui tab control to switch between
different ui tables which may contain different aggregated
info per unique pid/port/proto/dst/src.

Meanwhile there is only 1 ui tab entry for flows table.

Added some missing cds_list_{next,prev,last}_entry functions
into list.h header.

Signed-off-by: Vadim Kochan <vadi...@gmail.com>
---
 flowtop.c | 26 +++++++++++++++--
 list.h    | 19 +++++++++++++
 ui.c      | 95 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++-
 ui.h      | 30 ++++++++++++++++++++
 4 files changed, 166 insertions(+), 4 deletions(-)
 create mode 100644 list.h

diff --git a/flowtop.c b/flowtop.c
index b2d6546..78ac253 100644
--- a/flowtop.c
+++ b/flowtop.c
@@ -133,6 +133,8 @@ static struct flow_list flow_list;
 static struct sysctl_params_ctx sysctl = { -1, -1 };
 
 static unsigned int cols, rows;
+static WINDOW *screen;
+static int skip_lines;
 
 static unsigned int interval = 1;
 static bool show_src = false;
@@ -156,6 +158,10 @@ enum tbl_flow_col {
 
 static struct ui_table flows_tbl;
 
+enum tab_entry {
+       TAB_FLOWS,
+};
+
 static const char *short_options = "vhTUsDIS46ut:nGb";
 static const struct option long_options[] = {
        {"ipv4",        no_argument,            NULL, '4'},
@@ -1197,11 +1203,15 @@ static void flows_table_init(struct ui_table *tbl)
        ui_table_header_color_set(&flows_tbl, COLOR(BLACK, GREEN));
 }
 
+static void tab_main_on_open(struct ui_tab *tab, enum ui_tab_event_t evt, 
uint32_t id)
+{
+       draw_flows(screen, &flow_list, skip_lines);
+}
+
 static void presenter(void)
 {
        bool show_help = false;
-       int skip_lines = 0;
-       WINDOW *screen;
+       struct ui_tab *tab_main;
 
        lookup_init(LT_PORTS_TCP);
        lookup_init(LT_PORTS_UDP);
@@ -1219,6 +1229,12 @@ static void presenter(void)
 
         flows_table_init(&flows_tbl);
 
+       tab_main = ui_tab_create();
+       ui_tab_event_cb_set(tab_main, tab_main_on_open);
+       ui_tab_pos_set(tab_main, 2, 0);
+       ui_tab_active_color_set(tab_main, COLOR(BLACK, GREEN));
+       ui_tab_entry_add(tab_main, TAB_FLOWS, "Flows");
+
        rcu_register_thread();
        while (!sigint) {
                int ch;
@@ -1278,6 +1294,9 @@ static void presenter(void)
                        show_option_toggle(ch);
                        do_reload_flows = true;
                        break;
+               case '\t':
+                       ui_tab_event_send(tab_main, UI_EVT_SELECT_NEXT);
+                       break;
                default:
                        fflush(stdin);
                        break;
@@ -1288,13 +1307,14 @@ static void presenter(void)
                if (show_help)
                        draw_help();
                else
-                       draw_flows(screen, &flow_list, skip_lines);
+                       ui_tab_show(tab_main);
 
                draw_footer();
        }
        rcu_unregister_thread();
 
        ui_table_uninit(&flows_tbl);
+       ui_tab_destroy(tab_main);
 
        screen_end();
        lookup_cleanup(LT_PORTS_UDP);
diff --git a/list.h b/list.h
new file mode 100644
index 0000000..44dc8a2
--- /dev/null
+++ b/list.h
@@ -0,0 +1,19 @@
+#ifndef LIST_H
+#define LIST_H
+
+#ifndef cds_list_last_entry
+#define cds_list_last_entry(ptr, type, member) \
+       cds_list_entry((ptr)->prev, type, member)
+#endif
+
+#ifndef cds_list_next_entry
+#define cds_list_next_entry(pos, member) \
+       cds_list_entry((pos)->member.next, typeof(*(pos)), member)
+#endif
+
+#ifndef cds_list_prev_entry
+#define cds_list_prev_entry(pos, member) \
+       cds_list_entry((pos)->member.prev, typeof(*(pos)), member)
+#endif
+
+#endif /* LIST_H */
diff --git a/ui.c b/ui.c
index 78d1560..d8e0213 100644
--- a/ui.c
+++ b/ui.c
@@ -7,6 +7,8 @@
 
 #include "ui.h"
 #include "str.h"
+#include "list.h"
+#include "screen.h"
 #include "xmalloc.h"
 
 static struct ui_text *ui_text_alloc(size_t len)
@@ -62,6 +64,7 @@ void ui_table_init(struct ui_table *tbl)
        tbl->height  = LINES - 2;
        tbl->col_pad = 1;
        tbl->row     = ui_text_alloc(tbl->width);
+       tbl->delim   = " ";
 
        CDS_INIT_LIST_HEAD(&tbl->cols);
 }
@@ -134,6 +137,11 @@ void ui_table_col_align_set(struct ui_table *tbl, int 
col_id, enum ui_align alig
        col->align = align;
 }
 
+void ui_table_col_delim_set(struct ui_table *tbl, char *delim)
+{
+       tbl->delim = delim;
+}
+
 void ui_table_row_add(struct ui_table *tbl)
 {
        tbl->rows_y++;
@@ -166,7 +174,7 @@ static void __ui_table_row_print(struct ui_table *tbl, 
struct ui_col *col,
        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, " ");
+       slprintf(tmp, sizeof(tmp), "%*s", tbl->col_pad, tbl->delim);
        ui_text_attr_insert(tbl->row, col->pos + col->len, color, tmp);
 }
 
@@ -214,3 +222,88 @@ void ui_table_event_send(struct ui_table *tbl, enum 
ui_event_id evt_id)
                        tbl->scroll_x = 0;
        }
 }
+
+struct ui_tab *ui_tab_create(void)
+{
+       struct ui_tab *tab;
+
+       tab = xzmalloc(sizeof(*tab));
+
+       ui_table_init(&tab->tbl);
+       ui_table_col_delim_set(&tab->tbl, "|");
+       tab->tbl.width = 0;
+
+       return tab;
+}
+
+void ui_tab_destroy(struct ui_tab *tab)
+{
+       ui_table_uninit(&tab->tbl);
+       xfree(tab);
+}
+
+void ui_tab_pos_set(struct ui_tab *tab, int y, int x)
+{
+       ui_table_pos_set(&tab->tbl, y, x);
+}
+
+void ui_tab_event_cb_set(struct ui_tab *tab, ui_tab_event_cb cb)
+{
+       tab->on_tab_event = cb;
+}
+
+void ui_tab_active_color_set(struct ui_tab *tab, int color)
+{
+       ui_table_header_color_set(&tab->tbl, color);
+       tab->color = color;
+}
+
+void ui_tab_show(struct ui_tab *tab)
+{
+       struct ui_col *col;
+
+       if (tab->on_tab_event)
+               tab->on_tab_event(tab, UI_TAB_EVT_OPEN, tab->active->id);
+
+       cds_list_for_each_entry(col, &tab->tbl.cols, entry)
+               __ui_table_row_print(&tab->tbl, col, col->color, col->name);
+
+       ui_table_row_show(&tab->tbl);
+}
+
+void ui_tab_entry_add(struct ui_tab *tab, uint32_t id, char *name)
+{
+       struct ui_col *col;
+
+       ui_table_col_add(&tab->tbl, id, name, strlen(name) + 1);
+
+       col = ui_table_col_get(&tab->tbl, id);
+
+       if (!tab->active)
+               tab->active = col;
+
+       if (tab->active == col)
+               ui_table_col_color_set(&tab->tbl, id, tab->color);
+       else
+               ui_table_col_color_set(&tab->tbl, id, tab->color | A_REVERSE);
+}
+
+void ui_tab_event_send(struct ui_tab *tab, uint32_t id)
+{
+       struct ui_col *curr, *next;
+
+       if (id != UI_EVT_SELECT_NEXT)
+               return;
+
+       curr = tab->active;
+
+       if (curr == cds_list_last_entry(&tab->tbl.cols, struct ui_col, entry))
+               next = cds_list_first_entry(&tab->tbl.cols, struct ui_col, 
entry);
+       else
+               next = cds_list_next_entry(curr, entry);
+
+       curr->color = tab->color | A_REVERSE;
+       next->color = tab->color;
+
+       tab->active = next;
+}
diff --git a/ui.h b/ui.h
index 9db3c08..eaa68e9 100644
--- a/ui.h
+++ b/ui.h
@@ -9,6 +9,7 @@
 enum ui_event_id {
        UI_EVT_SCROLL_LEFT,
        UI_EVT_SCROLL_RIGHT,
+       UI_EVT_SELECT_NEXT,
 };
 
 enum ui_align {
@@ -43,6 +44,25 @@ struct ui_table {
        int width;
        int height;
        int scroll_x;
+       char *delim;
+};
+
+struct ui_tab;
+
+enum ui_tab_event_t {
+       UI_TAB_EVT_OPEN,
+       UI_TAB_EVT_CLOSE,
+};
+
+typedef void (* ui_tab_event_cb) (struct ui_tab *tab, enum ui_tab_event_t evt,
+                                 uint32_t id);
+
+struct ui_tab {
+       struct ui_col *active;
+       struct ui_table tbl;
+       int color;
+
+       ui_tab_event_cb on_tab_event;
 };
 
 extern void ui_table_init(struct ui_table *tbl);
@@ -55,6 +75,7 @@ extern void ui_table_col_add(struct ui_table *tbl, uint32_t 
id, char *name,
                             uint32_t len);
 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_col_delim_set(struct ui_table *tbl, char *delim);
 
 extern void ui_table_row_add(struct ui_table *tbl);
 extern void ui_table_row_show(struct ui_table *tbl);
@@ -66,4 +87,13 @@ extern void ui_table_header_print(struct ui_table *tbl);
 
 extern void ui_table_event_send(struct ui_table *tbl, enum ui_event_id id);
 
+extern struct ui_tab *ui_tab_create(void);
+extern void ui_tab_destroy(struct ui_tab *tab);
+extern void ui_tab_pos_set(struct ui_tab *tab, int y, int x);
+extern void ui_tab_event_cb_set(struct ui_tab *tab, ui_tab_event_cb cb);
+extern void ui_tab_active_color_set(struct ui_tab *tab, int color);
+extern void ui_tab_show(struct ui_tab *tab);
+extern void ui_tab_entry_add(struct ui_tab *tab, uint32_t id, char *name);
+extern void ui_tab_event_send(struct ui_tab *tab, uint32_t id);
+
 #endif /* UI_H */
-- 
2.11.0

-- 
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