2 * netsniff-ng - the packet sniffing beast
3 * Subject to the GPL, version 2.
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);
24 static void ui_text_len_set(struct ui_text
*text
, size_t len
)
29 if (text
->slen
+ len
> text
->len
) {
30 text
->str
= xrealloc(text
->str
, sizeof(chtype
) * len
+ 1);
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
);
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
)
56 void ui_table_init(struct ui_table
*tbl
)
58 memset(tbl
, 0, sizeof(*tbl
));
60 getsyx(tbl
->y
, tbl
->x
);
64 tbl
->height
= LINES
- 2;
66 tbl
->row
= ui_text_alloc(tbl
->width
);
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
)
79 ui_text_free(tbl
->row
);
82 void ui_table_pos_set(struct ui_table
*tbl
, int y
, int x
)
89 static struct ui_col
*ui_table_col_get(struct ui_table
*tbl
, uint32_t id
)
93 cds_list_for_each_entry(col
, &tbl
->cols
, entry
) {
101 static void __ui_table_pos_update(struct ui_table
*tbl
)
106 cds_list_for_each_entry(col
, &tbl
->cols
, entry
) {
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
));
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
);
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
);
140 void ui_table_col_delim_set(struct ui_table
*tbl
, const char *delim
)
145 void ui_table_row_add(struct ui_table
*tbl
)
150 void ui_table_clear(struct ui_table
*tbl
)
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
)
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
)
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
)
218 case UI_EVT_SCROLL_RIGHT
:
219 tbl
->scroll_x
+= SCROLL_X_STEP
;
222 case UI_EVT_SCROLL_LEFT
:
223 tbl
->scroll_x
-= SCROLL_X_STEP
;
224 if (tbl
->scroll_x
< 0)
228 case UI_EVT_SCROLL_UP
:
230 if (tbl
->scroll_y
< 0)
234 case UI_EVT_SCROLL_DOWN
:
238 default: /* pass the rest events */
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
)
260 bug_on(!tbl
->data_iter
);
261 bug_on(!tbl
->data_bind
);
264 ui_table_header_print(tbl
);
268 data
= tbl
->data_iter(NULL
);
269 for (; data
; data
= tbl
->data_iter(data
)) {
272 if (i
++ < tbl
->scroll_y
)
275 tbl
->data_bind(tbl
, data
);
278 if (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)
296 tab
= xzmalloc(sizeof(*tab
));
298 ui_table_init(&tab
->tbl
);
299 ui_table_col_delim_set(&tab
->tbl
, "|");
305 void ui_tab_destroy(struct ui_tab
*tab
)
307 ui_table_uninit(&tab
->tbl
);
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
);
327 void ui_tab_show(struct ui_tab
*tab
)
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
)
344 ui_table_col_add(&tab
->tbl
, id
, name
, strlen(name
) + 1);
346 col
= ui_table_col_get(&tab
->tbl
, id
);
351 if (tab
->active
== col
)
352 ui_table_col_color_set(&tab
->tbl
, id
, tab
->color
);
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
)
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
);
369 next
= cds_list_next_entry(curr
, entry
);
371 curr
->color
= tab
->color
| A_REVERSE
;
372 next
->color
= tab
->color
;