ifpps: use uint32_t instead of u32
[netsniff-ng.git] / ui.c
blob6eeff83a414b2b4ab3306b62e33ce612723e5eac
1 /*
2 * netsniff-ng - the packet sniffing beast
3 * Subject to the GPL, version 2.
4 */
6 #include <curses.h>
8 #include "ui.h"
9 #include "str.h"
10 #include "screen.h"
11 #include "xmalloc.h"
12 #include "urcu-list-compat.h"
14 static struct ui_text *ui_text_alloc(size_t len)
16 struct ui_text *text = xzmalloc(sizeof(*text));
18 text->str = xzmalloc(sizeof(chtype) * len + 1);
19 text->len = len;
21 return text;
24 static void ui_text_len_set(struct ui_text *text, size_t len)
26 if (text->len == len)
27 return;
29 if (text->slen + len > text->len) {
30 text->str = xrealloc(text->str, sizeof(chtype) * len + 1);
31 text->len = len;
34 text->slen = min(len, text->slen);
35 text->str[text->slen] = 0;
38 static void ui_text_attr_insert(struct ui_text *text, int idx, int attr, const char *str)
40 size_t slen = strlen(str);
41 uint32_t i, j;
43 if (idx + slen > text->len)
44 ui_text_len_set(text, idx + slen);
46 for (j = 0, i = idx; i < idx + slen; i++, j++)
47 text->str[i] = str[j] | attr;
50 static void ui_text_free(struct ui_text *text)
52 xfree(text->str);
53 xfree(text);
56 void ui_table_init(struct ui_table *tbl)
58 memset(tbl, 0, sizeof(*tbl));
60 getsyx(tbl->y, tbl->x);
62 tbl->rows_y = tbl->y;
63 tbl->width = COLS;
64 tbl->height = LINES - 2;
65 tbl->col_pad = 1;
66 tbl->row = ui_text_alloc(tbl->width);
67 tbl->delim = " ";
69 CDS_INIT_LIST_HEAD(&tbl->cols);
72 void ui_table_uninit(struct ui_table *tbl)
74 struct ui_col *col, *tmp;
76 cds_list_for_each_entry_safe(col, tmp, &tbl->cols, entry)
77 xfree(col);
79 ui_text_free(tbl->row);
82 void ui_table_pos_set(struct ui_table *tbl, int y, int x)
84 tbl->y = y;
85 tbl->x = x;
86 tbl->rows_y = y;
89 static struct ui_col *ui_table_col_get(struct ui_table *tbl, uint32_t id)
91 struct ui_col *col;
93 cds_list_for_each_entry(col, &tbl->cols, entry) {
94 if (col->id == id)
95 return col;
98 bug();
101 static void __ui_table_pos_update(struct ui_table *tbl)
103 struct ui_col *col;
104 uint32_t pos = 0;
106 cds_list_for_each_entry(col, &tbl->cols, entry) {
107 col->pos = pos;
108 pos += col->len + tbl->col_pad;
112 void ui_table_col_add(struct ui_table *tbl, uint32_t id, const char *name, uint32_t len)
114 struct ui_col *col = xzmalloc(sizeof(*col));
116 col->id = id;
117 col->name = name;
118 col->len = len;
119 col->align = UI_ALIGN_LEFT;
121 cds_list_add_tail(&col->entry, &tbl->cols);
123 __ui_table_pos_update(tbl);
126 void ui_table_col_color_set(struct ui_table *tbl, int col_id, int color)
128 struct ui_col *col = ui_table_col_get(tbl, col_id);
130 col->color = color;
133 void ui_table_col_align_set(struct ui_table *tbl, int col_id, enum ui_align align)
135 struct ui_col *col = ui_table_col_get(tbl, col_id);
137 col->align = align;
140 void ui_table_col_delim_set(struct ui_table *tbl, const char *delim)
142 tbl->delim = delim;
145 void ui_table_row_add(struct ui_table *tbl)
147 tbl->rows_y++;
150 void ui_table_clear(struct ui_table *tbl)
152 int y;
154 tbl->rows_y = tbl->y;
156 for (y = tbl->y + 1; y < tbl->y + tbl->height; y++) {
157 mvprintw(y, tbl->x, "%*s", tbl->width, " ");
161 #define UI_ALIGN_COL(col) (((col)->align == UI_ALIGN_LEFT) ? "%-*.*s" : "%*.*s")
163 void ui_table_row_show(struct ui_table *tbl)
165 mvaddchstr(tbl->rows_y, tbl->x, tbl->row->str + tbl->scroll_x);
166 ui_text_len_set(tbl->row, 0);
169 static void __ui_table_row_print(struct ui_table *tbl, struct ui_col *col,
170 int color, const char *str)
172 char tmp[128];
174 slprintf(tmp, sizeof(tmp), UI_ALIGN_COL(col), col->len, col->len, str);
175 ui_text_attr_insert(tbl->row, col->pos, color, tmp);
177 slprintf(tmp, sizeof(tmp), "%*s", tbl->col_pad, tbl->delim);
178 ui_text_attr_insert(tbl->row, col->pos + col->len, color, tmp);
181 void ui_table_row_col_set(struct ui_table *tbl, uint32_t col_id, const char *str)
183 struct ui_col *col = ui_table_col_get(tbl, col_id);
185 __ui_table_row_print(tbl, col, col->color, str);
188 void ui_table_header_color_set(struct ui_table *tbl, int color)
190 tbl->hdr_color = color;
193 void ui_table_height_set(struct ui_table *tbl, int height)
195 tbl->height = height;
198 void ui_table_header_print(struct ui_table *tbl)
200 struct ui_col *col;
202 attron(tbl->hdr_color);
203 mvprintw(tbl->y, tbl->x, "%*s", tbl->width, " ");
204 attroff(tbl->hdr_color);
206 cds_list_for_each_entry(col, &tbl->cols, entry) {
207 __ui_table_row_print(tbl, col, tbl->hdr_color, col->name);
210 ui_table_row_show(tbl);
213 #define SCROLL_X_STEP 10
215 void ui_table_event_send(struct ui_table *tbl, enum ui_event_id evt_id)
217 switch (evt_id) {
218 case UI_EVT_SCROLL_RIGHT:
219 tbl->scroll_x += SCROLL_X_STEP;
220 break;
222 case UI_EVT_SCROLL_LEFT:
223 tbl->scroll_x -= SCROLL_X_STEP;
224 if (tbl->scroll_x < 0)
225 tbl->scroll_x = 0;
226 break;
228 case UI_EVT_SCROLL_UP:
229 tbl->scroll_y--;
230 if (tbl->scroll_y < 0)
231 tbl->scroll_y = 0;
232 break;
234 case UI_EVT_SCROLL_DOWN:
235 tbl->scroll_y++;
236 break;
238 default: /* pass the rest events */
239 return;
243 void ui_table_data_iter_set(struct ui_table *tbl, void * (* iter)(void *data))
245 tbl->data_iter = iter;
248 void ui_table_data_bind_set(struct ui_table *tbl,
249 void (* bind)(struct ui_table *tbl, const void *data))
251 tbl->data_bind = bind;
254 void ui_table_data_bind(struct ui_table *tbl)
256 void *data;
257 int i = 0;
259 bug_on(!tbl);
260 bug_on(!tbl->data_iter);
261 bug_on(!tbl->data_bind);
263 ui_table_clear(tbl);
264 ui_table_header_print(tbl);
266 tbl->data_count = 0;
268 data = tbl->data_iter(NULL);
269 for (; data; data = tbl->data_iter(data)) {
270 tbl->data_count++;
272 if (i++ < tbl->scroll_y)
273 continue;
275 tbl->data_bind(tbl, data);
278 if (tbl->scroll_y > i)
279 tbl->scroll_y = i;
282 int ui_table_data_count(struct ui_table *tbl)
284 return tbl->data_count;
287 int ui_table_scroll_height(struct ui_table *tbl)
289 return tbl->scroll_y;
292 struct ui_tab *ui_tab_create(void)
294 struct ui_tab *tab;
296 tab = xzmalloc(sizeof(*tab));
298 ui_table_init(&tab->tbl);
299 ui_table_col_delim_set(&tab->tbl, "|");
300 tab->tbl.width = 0;
302 return tab;
305 void ui_tab_destroy(struct ui_tab *tab)
307 ui_table_uninit(&tab->tbl);
308 xfree(tab);
311 void ui_tab_pos_set(struct ui_tab *tab, int y, int x)
313 ui_table_pos_set(&tab->tbl, y, x);
316 void ui_tab_event_cb_set(struct ui_tab *tab, ui_tab_event_cb cb)
318 tab->on_tab_event = cb;
321 void ui_tab_active_color_set(struct ui_tab *tab, int color)
323 ui_table_header_color_set(&tab->tbl, color);
324 tab->color = color;
327 void ui_tab_show(struct ui_tab *tab)
329 struct ui_col *col;
331 if (tab->on_tab_event)
332 tab->on_tab_event(tab, UI_TAB_EVT_OPEN, tab->active->id);
334 cds_list_for_each_entry(col, &tab->tbl.cols, entry)
335 __ui_table_row_print(&tab->tbl, col, col->color, col->name);
337 ui_table_row_show(&tab->tbl);
340 void ui_tab_entry_add(struct ui_tab *tab, uint32_t id, const char *name)
342 struct ui_col *col;
344 ui_table_col_add(&tab->tbl, id, name, strlen(name) + 1);
346 col = ui_table_col_get(&tab->tbl, id);
348 if (!tab->active)
349 tab->active = col;
351 if (tab->active == col)
352 ui_table_col_color_set(&tab->tbl, id, tab->color);
353 else
354 ui_table_col_color_set(&tab->tbl, id, tab->color | A_REVERSE);
357 void ui_tab_event_send(struct ui_tab *tab, uint32_t id)
359 struct ui_col *curr, *next;
361 if (id != UI_EVT_SELECT_NEXT)
362 return;
364 curr = tab->active;
366 if (curr == cds_list_last_entry(&tab->tbl.cols, struct ui_col, entry))
367 next = cds_list_first_entry(&tab->tbl.cols, struct ui_col, entry);
368 else
369 next = cds_list_next_entry(curr, entry);
371 curr->color = tab->color | A_REVERSE;
372 next->color = tab->color;
374 tab->active = next;