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
)
217 if (evt_id
== UI_EVT_SCROLL_RIGHT
) {
218 tbl
->scroll_x
+= SCROLL_X_STEP
;
219 } else if (evt_id
== UI_EVT_SCROLL_LEFT
) {
220 tbl
->scroll_x
-= SCROLL_X_STEP
;
221 if (tbl
->scroll_x
< 0)
226 struct ui_tab
*ui_tab_create(void)
230 tab
= xzmalloc(sizeof(*tab
));
232 ui_table_init(&tab
->tbl
);
233 ui_table_col_delim_set(&tab
->tbl
, "|");
239 void ui_tab_destroy(struct ui_tab
*tab
)
241 ui_table_uninit(&tab
->tbl
);
245 void ui_tab_pos_set(struct ui_tab
*tab
, int y
, int x
)
247 ui_table_pos_set(&tab
->tbl
, y
, x
);
250 void ui_tab_event_cb_set(struct ui_tab
*tab
, ui_tab_event_cb cb
)
252 tab
->on_tab_event
= cb
;
255 void ui_tab_active_color_set(struct ui_tab
*tab
, int color
)
257 ui_table_header_color_set(&tab
->tbl
, color
);
261 void ui_tab_show(struct ui_tab
*tab
)
265 if (tab
->on_tab_event
)
266 tab
->on_tab_event(tab
, UI_TAB_EVT_OPEN
, tab
->active
->id
);
268 cds_list_for_each_entry(col
, &tab
->tbl
.cols
, entry
)
269 __ui_table_row_print(&tab
->tbl
, col
, col
->color
, col
->name
);
271 ui_table_row_show(&tab
->tbl
);
274 void ui_tab_entry_add(struct ui_tab
*tab
, uint32_t id
, const char *name
)
278 ui_table_col_add(&tab
->tbl
, id
, name
, strlen(name
) + 1);
280 col
= ui_table_col_get(&tab
->tbl
, id
);
285 if (tab
->active
== col
)
286 ui_table_col_color_set(&tab
->tbl
, id
, tab
->color
);
288 ui_table_col_color_set(&tab
->tbl
, id
, tab
->color
| A_REVERSE
);
291 void ui_tab_event_send(struct ui_tab
*tab
, uint32_t id
)
293 struct ui_col
*curr
, *next
;
295 if (id
!= UI_EVT_SELECT_NEXT
)
300 if (curr
== cds_list_last_entry(&tab
->tbl
.cols
, struct ui_col
, entry
))
301 next
= cds_list_first_entry(&tab
->tbl
.cols
, struct ui_col
, entry
);
303 next
= cds_list_next_entry(curr
, entry
);
305 curr
->color
= tab
->color
| A_REVERSE
;
306 next
->color
= tab
->color
;