3 * Copyright 2006, Iskratel , Slovenia
4 * By Jakob Bratkovic <j.bratkovic@iskratel.si> and
5 * Miha Jemec <m.jemec@iskratel.si>
9 * based on rtp_stream_dlg.c
10 * Copyright 2003, Alcatel Business Systems
11 * By Lars Ruoff <lars.ruoff@gmx.net>
13 * Wireshark - Network traffic analyzer
14 * By Gerald Combs <gerald@wireshark.org>
15 * Copyright 1998 Gerald Combs
17 * This program is free software; you can redistribute it and/or
18 * modify it under the terms of the GNU General Public License
19 * as published by the Free Software Foundation; either version 2
20 * of the License, or (at your option) any later version.
22 * This program is distributed in the hope that it will be useful,
23 * but WITHOUT ANY WARRANTY; without even the implied warranty of
24 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
25 * GNU General Public License for more details.
27 * You should have received a copy of the GNU General Public License
28 * along with this program; if not, write to the Free Software
29 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
41 #include "epan/filesystem.h"
42 #include <epan/address.h>
43 #include <epan/addr_resolv.h>
44 #include <epan/strutil.h>
46 #include "../globals.h"
47 #include "../stat_menu.h"
48 #include "ui/simple_dialog.h"
50 #include "ui/gtk/mcast_stream_dlg.h"
51 #include "ui/gtk/mcast_stream.h"
52 #include "ui/gtk/gui_stat_menu.h"
53 #include "ui/gtk/dlg_utils.h"
54 #include "ui/gtk/gui_utils.h"
55 #include "ui/gtk/gtkglobals.h"
57 /* Capture callback data keys */
58 #define E_MCAST_ENTRY_1 "burst_interval"
59 #define E_MCAST_ENTRY_2 "burst_alarm"
60 #define E_MCAST_ENTRY_3 "buffer_alarm"
61 #define E_MCAST_ENTRY_4 "stream_speed"
62 #define E_MCAST_ENTRY_5 "total_speed"
64 static const gchar FWD_LABEL_TEXT[] = "Select a stream with left mouse button";
65 static const gchar PAR_LABEL_TEXT[] = "\nBurst int: ms Burst alarm: pps Buffer alarm: KB Stream empty speed: Mbps Total empty speed: Mbps\n";
67 /****************************************************************************/
68 static GtkWidget *mcast_stream_dlg = NULL;
69 static GtkWidget *mcast_params_dlg = NULL;
71 static GtkListStore *list_store = NULL;
72 static GtkTreeIter list_iter;
73 static GtkWidget *list_w = NULL;
74 static GtkWidget *top_label = NULL;
75 static GtkWidget *label_fwd = NULL;
76 static GtkWidget *label_par = NULL;
77 static GtkWidget *bt_filter = NULL;
79 static mcast_stream_info_t* selected_stream_fwd = NULL; /* current selection */
80 static GList *last_list = NULL;
82 static guint32 streams_nb = 0; /* number of displayed streams */
99 NUM_COLS /* The number of columns */
102 /****************************************************************************/
104 /****************************************************************************/
106 mcaststream_on_destroy(GObject *object _U_, gpointer user_data _U_)
108 /* Remove the stream tap listener */
109 remove_tap_listener_mcast_stream();
111 /* Is there a params window open? */
112 if (mcast_params_dlg != NULL)
113 window_destroy(mcast_params_dlg);
115 /* Clean up memory used by stream tap */
116 mcaststream_reset((mcaststream_tapinfo_t*)mcaststream_get_info());
118 /* Note that we no longer have a "Mcast Streams" dialog box. */
119 mcast_stream_dlg = NULL;
123 /****************************************************************************/
125 mcaststream_on_unselect(GtkButton *button _U_, gpointer user_data _U_)
127 GtkTreeSelection *selection = gtk_tree_view_get_selection(GTK_TREE_VIEW(list_w));
128 gtk_tree_selection_unselect_all(selection);
130 selected_stream_fwd = NULL;
131 gtk_label_set_text(GTK_LABEL(label_fwd), FWD_LABEL_TEXT);
132 gtk_widget_set_sensitive(bt_filter, FALSE);
136 /****************************************************************************/
138 mcaststream_on_filter(GtkButton *button _U_, gpointer user_data _U_)
140 gchar *filter_string_fwd = NULL;
143 if (selected_stream_fwd==NULL)
146 if (selected_stream_fwd->src_addr.type==AT_IPv6){
147 g_strlcpy(ip_version,"v6",sizeof(ip_version));
149 ip_version[0] = '\0';
151 filter_string_fwd = g_strdup_printf(
152 "(ip%s.src==%s && udp.srcport==%u && ip%s.dst==%s && udp.dstport==%u)",
154 ep_address_to_str(&(selected_stream_fwd->src_addr)),
155 selected_stream_fwd->src_port,
157 ep_address_to_str(&(selected_stream_fwd->dest_addr)),
158 selected_stream_fwd->dest_port);
160 gtk_entry_set_text(GTK_ENTRY(main_display_filter_widget), filter_string_fwd);
161 g_free(filter_string_fwd);
164 main_filter_packets(&cfile, filter_string, FALSE);
165 mcaststream_dlg_update(mcaststream_get_info()->strinfo_list);
169 /****************************************************************************/
170 /* when the user selects a row in the stream list */
172 mcaststream_on_select_row(GtkTreeSelection *selection, gpointer data _U_)
174 gchar label_text[80];
176 if (gtk_tree_selection_get_selected(selection, NULL, &list_iter))
178 gtk_tree_model_get(GTK_TREE_MODEL(list_store), &list_iter, MC_COL_DATA, &selected_stream_fwd, -1);
179 g_snprintf(label_text, sizeof(label_text), "Selected: %s:%u -> %s:%u",
180 get_addr_name(&(selected_stream_fwd->src_addr)),
181 selected_stream_fwd->src_port,
182 get_addr_name(&(selected_stream_fwd->dest_addr)),
183 selected_stream_fwd->dest_port
185 gtk_label_set_text(GTK_LABEL(label_fwd), label_text);
186 gtk_widget_set_sensitive(bt_filter, TRUE);
188 selected_stream_fwd = NULL;
189 gtk_label_set_text(GTK_LABEL(label_fwd), FWD_LABEL_TEXT);
190 gtk_widget_set_sensitive(bt_filter, FALSE);
195 /****************************************************************************/
197 /****************************************************************************/
199 mcast_params_destroy_cb(GtkWidget *win _U_, gpointer user_data _U_)
201 /* Note that we no longer have a mcast params dialog box. */
202 mcast_params_dlg = NULL;
207 mcast_params_ok_cb(GtkWidget *ok_bt _U_, gpointer parent_w)
209 GtkWidget *fnumber_te;
210 const gchar *fnumber_text;
214 fnumber_te = (GtkWidget *)g_object_get_data(G_OBJECT(parent_w), E_MCAST_ENTRY_1);
215 fnumber_text = gtk_entry_get_text(GTK_ENTRY(fnumber_te));
216 fnumber = strtoul(fnumber_text, &p, 10);
217 if ( (p == fnumber_text || *p != '\0') || (fnumber <= 0) || (fnumber > 1000) ) {
218 simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK, "The burst interval should be between 1 and 1000 ms.");
221 mcast_stream_burstint = fnumber;
223 fnumber_te = (GtkWidget *)g_object_get_data(G_OBJECT(parent_w), E_MCAST_ENTRY_2);
224 fnumber_text = gtk_entry_get_text(GTK_ENTRY(fnumber_te));
225 fnumber = strtoul(fnumber_text, &p, 10);
226 if ( (p == fnumber_text || *p != '\0') || (fnumber <= 0) ) {
227 simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK, "The burst alarm threshold you entered isn't valid.");
230 mcast_stream_trigger = fnumber;
232 fnumber_te = (GtkWidget *)g_object_get_data(G_OBJECT(parent_w), E_MCAST_ENTRY_3);
233 fnumber_text = gtk_entry_get_text(GTK_ENTRY(fnumber_te));
234 fnumber = strtoul(fnumber_text, &p, 10);
235 if ( (p == fnumber_text || *p != '\0') || (fnumber <= 0) ) {
236 simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK, "The buffer alarm threshold you entered isn't valid.");
239 mcast_stream_bufferalarm = fnumber;
241 fnumber_te = (GtkWidget *)g_object_get_data(G_OBJECT(parent_w), E_MCAST_ENTRY_4);
242 fnumber_text = gtk_entry_get_text(GTK_ENTRY(fnumber_te));
243 fnumber = strtoul(fnumber_text, &p, 10);
244 if ( (p == fnumber_text || *p != '\0') || (fnumber <= 0) || (fnumber > 10000000) ) {
245 simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK, "The stream empty speed should be between 1 and 10000000");
248 mcast_stream_emptyspeed = fnumber;
250 fnumber_te = (GtkWidget *)g_object_get_data(G_OBJECT(parent_w), E_MCAST_ENTRY_5);
251 fnumber_text = gtk_entry_get_text(GTK_ENTRY(fnumber_te));
252 fnumber = strtoul(fnumber_text, &p, 10);
253 if ( (p == fnumber_text || *p != '\0') || (fnumber <= 0) || (fnumber > 10000000) ) {
254 simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK, "The total empty speed should be between 1 and 10000000");
257 mcast_stream_cumulemptyspeed = fnumber;
259 window_destroy(GTK_WIDGET(parent_w));
261 /* Clean up memory used by stream tap */
262 mcaststream_reset((mcaststream_tapinfo_t*)mcaststream_get_info());
263 /* retap all packets */
264 cf_retap_packets(&cfile);
270 mcast_on_params(GtkButton *button _U_, gpointer data _U_)
273 GtkWidget *label, *hbuttonbox, *table;
274 GtkWidget *ok_bt, *cancel_bt;
275 GtkWidget *entry1, *entry2, *entry3, *entry4, *entry5;
276 gchar label_text[51];
278 if (mcast_params_dlg != NULL) {
279 /* There's already a Params dialog box; reactivate it. */
280 reactivate_window(mcast_params_dlg);
284 mcast_params_dlg = dlg_window_new("Wireshark: Set parameters for Multicast Stream Analysis");
285 gtk_window_set_destroy_with_parent(GTK_WINDOW(mcast_params_dlg), TRUE);
286 gtk_window_set_default_size(GTK_WINDOW(mcast_params_dlg), 210, 210);
288 gtk_widget_show(mcast_params_dlg);
290 /* Container for each row of widgets */
291 main_vb =ws_gtk_box_new(GTK_ORIENTATION_VERTICAL, 3, FALSE);
292 gtk_container_set_border_width(GTK_CONTAINER(main_vb), 2);
293 gtk_container_add(GTK_CONTAINER(mcast_params_dlg), main_vb);
294 gtk_widget_show(main_vb);
296 table = gtk_table_new(6, 2, FALSE);
297 gtk_container_add (GTK_CONTAINER (main_vb), table);
299 label = gtk_label_new(" Burst measurement interval (ms) ");
300 gtk_table_attach_defaults(GTK_TABLE(table), label, 0, 1, 0, 1);
301 entry1 = gtk_entry_new();
302 g_snprintf(label_text, sizeof(label_text), "%u", mcast_stream_burstint);
303 gtk_entry_set_text(GTK_ENTRY(entry1), label_text);
304 gtk_table_attach_defaults(GTK_TABLE(table), entry1, 1, 2, 0, 1);
305 label = gtk_label_new(" Burst alarm threshold (packets) ");
306 gtk_table_attach_defaults(GTK_TABLE(table), label, 0, 1, 1, 2);
307 entry2 = gtk_entry_new();
308 g_snprintf(label_text, sizeof(label_text), "%u", mcast_stream_trigger);
309 gtk_entry_set_text(GTK_ENTRY(entry2), label_text);
310 gtk_table_attach_defaults(GTK_TABLE(table), entry2, 1, 2, 1, 2);
311 label = gtk_label_new(" Buffer alarm threshold (bytes) ");
312 gtk_table_attach_defaults(GTK_TABLE(table), label, 0, 1, 2, 3);
313 entry3 = gtk_entry_new();
314 g_snprintf(label_text, sizeof(label_text), "%u", mcast_stream_bufferalarm);
315 gtk_entry_set_text(GTK_ENTRY(entry3), label_text);
316 gtk_table_attach_defaults(GTK_TABLE(table), entry3, 1, 2, 2, 3);
317 label = gtk_label_new(" Stream empty speed (kbit/s) ");
318 gtk_table_attach_defaults(GTK_TABLE(table), label, 0, 1, 3, 4);
319 entry4 = gtk_entry_new();
320 g_snprintf(label_text, sizeof(label_text), "%u", mcast_stream_emptyspeed);
321 gtk_entry_set_text(GTK_ENTRY(entry4), label_text);
322 gtk_table_attach_defaults(GTK_TABLE(table), entry4, 1, 2, 3, 4);
323 label = gtk_label_new(" Total empty speed (kbit/s) ");
324 gtk_table_attach_defaults(GTK_TABLE(table), label, 0, 1, 4, 5);
325 entry5 = gtk_entry_new();
326 g_snprintf(label_text, sizeof(label_text), "%u", mcast_stream_cumulemptyspeed);
327 gtk_entry_set_text(GTK_ENTRY(entry5), label_text);
328 gtk_table_attach_defaults(GTK_TABLE(table), entry5, 1, 2, 4, 5);
330 gtk_widget_show (table);
333 hbuttonbox = gtk_hbutton_box_new();
334 gtk_table_attach_defaults(GTK_TABLE(table), hbuttonbox, 0, 2, 5, 6);
335 ok_bt = gtk_button_new_from_stock(GTK_STOCK_OK);
336 gtk_container_add (GTK_CONTAINER(hbuttonbox), ok_bt);
337 cancel_bt = gtk_button_new_from_stock(GTK_STOCK_CANCEL);
338 gtk_container_add (GTK_CONTAINER(hbuttonbox), cancel_bt);
339 #if GTK_CHECK_VERSION(2,18,0)
340 gtk_widget_set_can_default(cancel_bt, TRUE);
342 GTK_WIDGET_SET_FLAGS(cancel_bt, GTK_CAN_DEFAULT);
344 gtk_button_box_set_layout(GTK_BUTTON_BOX(hbuttonbox), GTK_BUTTONBOX_END);
345 gtk_box_set_spacing(GTK_BOX(hbuttonbox), 0);
347 g_signal_connect(mcast_params_dlg, "delete_event", G_CALLBACK(window_delete_event_cb), NULL);
348 g_signal_connect(mcast_params_dlg, "destroy", G_CALLBACK(mcast_params_destroy_cb), NULL);
349 g_signal_connect(ok_bt, "clicked", G_CALLBACK(mcast_params_ok_cb), mcast_params_dlg);
350 window_set_cancel_button(mcast_params_dlg, cancel_bt, window_cancel_button_cb);
352 /* Attach pointers to needed widgets */
353 g_object_set_data(G_OBJECT(mcast_params_dlg), E_MCAST_ENTRY_1, entry1);
354 g_object_set_data(G_OBJECT(mcast_params_dlg), E_MCAST_ENTRY_2, entry2);
355 g_object_set_data(G_OBJECT(mcast_params_dlg), E_MCAST_ENTRY_3, entry3);
356 g_object_set_data(G_OBJECT(mcast_params_dlg), E_MCAST_ENTRY_4, entry4);
357 g_object_set_data(G_OBJECT(mcast_params_dlg), E_MCAST_ENTRY_5, entry5);
359 gtk_widget_show_all(mcast_params_dlg);
360 window_present(mcast_params_dlg);
364 /****************************************************************************/
365 /* append a line to list */
367 add_to_list_store(mcast_stream_info_t* strinfo)
369 gchar label_text[256];
370 gchar *data[NUM_COLS];
374 /* save the current locale */
375 savelocale = setlocale(LC_NUMERIC, NULL);
376 /* switch to "C" locale to avoid problems with localized decimal separators
377 in g_snprintf("%f") functions */
378 setlocale(LC_NUMERIC, "C");
379 data[0] = g_strdup(get_addr_name(&(strinfo->src_addr)));
380 data[1] = g_strdup_printf("%u", strinfo->src_port);
381 data[2] = g_strdup(get_addr_name(&(strinfo->dest_addr)));
382 data[3] = g_strdup_printf("%u", strinfo->dest_port);
383 data[4] = g_strdup_printf("%u", strinfo->npackets);
384 data[5] = g_strdup_printf("%u /s", strinfo->apackets);
385 data[6] = g_strdup_printf("%2.1f Mbps", strinfo->average_bw);
386 data[7] = g_strdup_printf("%2.1f Mbps", strinfo->element.maxbw);
387 data[8] = g_strdup_printf("%u / %dms", strinfo->element.topburstsize, mcast_stream_burstint);
388 data[9] = g_strdup_printf("%u", strinfo->element.numbursts);
389 data[10] = g_strdup_printf("%.1f KB", (float)strinfo->element.topbuffusage/1000);
390 data[11] = g_strdup_printf("%u", strinfo->element.numbuffalarms);
392 /* restore previous locale setting */
393 setlocale(LC_NUMERIC, savelocale);
395 /* Acquire an iterator */
396 gtk_list_store_append(list_store, &list_iter);
398 /* Fill the new row */
399 gtk_list_store_set(list_store, &list_iter,
400 MC_COL_SRC_ADDR, data[0],
401 MC_COL_SRC_PORT, data[1],
402 MC_COL_DST_ADDR, data[2],
403 MC_COL_DST_PORT, data[3],
404 MC_COL_PACKETS, data[4],
406 MC_COL_AVG_BW, data[6],
407 MC_COL_MAX_BW, data[7],
408 MC_COL_MAX_BURST, data[8],
409 MC_COL_BURST_ALARM, data[9],
410 MC_COL_MAX_BUFFER, data[10],
411 MC_COL_BUFFER_ALARM, data[11],
412 MC_COL_DATA, strinfo,
415 for (i = 0; i < NUM_COLS-1; i++)
418 /* Update the top label with the number of detected streams */
419 g_snprintf(label_text, sizeof(label_text),
420 "Detected %d Multicast streams, Average Bw: %.1f Mbps Max Bw: %.1f Mbps Max burst: %d / %dms Max buffer: %.1f KB",
422 mcaststream_get_info()->allstreams->average_bw, mcaststream_get_info()->allstreams->element.maxbw,
423 mcaststream_get_info()->allstreams->element.topburstsize, mcast_stream_burstint,
424 (float)(mcaststream_get_info()->allstreams->element.topbuffusage)/1000);
425 gtk_label_set_text(GTK_LABEL(top_label), label_text);
427 g_snprintf(label_text, sizeof(label_text), "\nBurst int: %u ms Burst alarm: %u pps Buffer alarm: %u Bytes Stream empty speed: %u Kbps Total empty speed: %u Kbps\n",
428 mcast_stream_burstint, mcast_stream_trigger, mcast_stream_bufferalarm, mcast_stream_emptyspeed, mcast_stream_cumulemptyspeed);
429 gtk_label_set_text(GTK_LABEL(label_par), label_text);
432 /****************************************************************************/
433 /* Create list view */
435 create_list_view(void)
437 GtkTreeViewColumn *column;
438 GtkCellRenderer *renderer;
439 GtkTreeSortable *sortable;
440 GtkTreeView *list_view;
441 GtkTreeSelection *selection;
443 /* Create the store */
444 list_store = gtk_list_store_new(NUM_COLS, /* Total number of columns */
445 G_TYPE_STRING, /* Source address */
446 G_TYPE_STRING, /* Source port */
447 G_TYPE_STRING, /* Destination address */
448 G_TYPE_STRING, /* Destination port */
449 G_TYPE_STRING, /* Packets */
450 G_TYPE_STRING, /* Packets per second */
451 G_TYPE_STRING, /* Average bandwidth */
452 G_TYPE_STRING, /* Max. bandwidth */
453 G_TYPE_STRING, /* Max. burst */
454 G_TYPE_STRING, /* Burst alarms */
455 G_TYPE_STRING, /* Max. buffers */
456 G_TYPE_STRING, /* Buffer alarms */
457 G_TYPE_POINTER /* Data */
461 list_w = gtk_tree_view_new_with_model(GTK_TREE_MODEL(list_store));
463 list_view = GTK_TREE_VIEW(list_w);
464 sortable = GTK_TREE_SORTABLE(list_store);
466 /* Speed up the list display */
467 gtk_tree_view_set_fixed_height_mode(list_view, TRUE);
469 /* Setup the sortable columns */
470 gtk_tree_sortable_set_sort_column_id(sortable, MC_COL_SRC_ADDR, GTK_SORT_ASCENDING);
471 gtk_tree_view_set_headers_clickable(list_view, FALSE);
473 /* The view now holds a reference. We can get rid of our own reference */
474 g_object_unref(G_OBJECT(list_store));
477 * Create the first column packet, associating the "text" attribute of the
478 * cell_renderer to the first column of the model
480 renderer = gtk_cell_renderer_text_new();
481 column = gtk_tree_view_column_new_with_attributes("Src IP addr", renderer,
482 "text", MC_COL_SRC_ADDR,
484 gtk_tree_view_column_set_sort_column_id(column, MC_COL_SRC_ADDR);
485 gtk_tree_view_column_set_resizable(column, TRUE);
486 gtk_tree_view_column_set_sizing(column, GTK_TREE_VIEW_COLUMN_FIXED);
487 gtk_tree_view_column_set_min_width(column, 60);
488 gtk_tree_view_column_set_fixed_width(column, 100);
489 /* Add the column to the view. */
490 gtk_tree_view_append_column(list_view, column);
493 renderer = gtk_cell_renderer_text_new();
494 column = gtk_tree_view_column_new_with_attributes("Src port", renderer,
495 "text", MC_COL_SRC_PORT,
497 gtk_tree_view_column_set_sort_column_id(column, MC_COL_SRC_PORT);
498 gtk_tree_view_column_set_resizable(column, TRUE);
499 gtk_tree_view_column_set_sizing(column, GTK_TREE_VIEW_COLUMN_FIXED);
500 gtk_tree_view_column_set_min_width(column, 60);
501 gtk_tree_view_column_set_fixed_width(column, 80);
502 gtk_tree_view_append_column(list_view, column);
504 /* Destination address */
505 renderer = gtk_cell_renderer_text_new();
506 column = gtk_tree_view_column_new_with_attributes("Dst IP addr", renderer,
507 "text", MC_COL_DST_ADDR,
509 gtk_tree_view_column_set_sort_column_id(column, MC_COL_DST_ADDR);
510 gtk_tree_view_column_set_resizable(column, TRUE);
511 gtk_tree_view_column_set_sizing(column, GTK_TREE_VIEW_COLUMN_FIXED);
512 gtk_tree_view_column_set_min_width(column, 60);
513 gtk_tree_view_column_set_fixed_width(column, 100);
514 gtk_tree_view_append_column(list_view, column);
516 /* Destination port */
517 renderer = gtk_cell_renderer_text_new();
518 column = gtk_tree_view_column_new_with_attributes("Dst port", renderer,
519 "text", MC_COL_DST_PORT,
521 gtk_tree_view_column_set_sort_column_id(column, MC_COL_DST_PORT);
522 gtk_tree_view_column_set_resizable(column, TRUE);
523 gtk_tree_view_column_set_sizing(column, GTK_TREE_VIEW_COLUMN_FIXED);
524 gtk_tree_view_column_set_min_width(column, 60);
525 gtk_tree_view_column_set_fixed_width(column, 80);
526 gtk_tree_view_append_column(list_view, column);
529 renderer = gtk_cell_renderer_text_new();
530 column = gtk_tree_view_column_new_with_attributes("Packets", renderer,
531 "text", MC_COL_PACKETS,
533 gtk_tree_view_column_set_sort_column_id(column, MC_COL_PACKETS);
534 gtk_tree_view_column_set_resizable(column, TRUE);
535 gtk_tree_view_column_set_sizing(column, GTK_TREE_VIEW_COLUMN_FIXED);
536 gtk_tree_view_column_set_min_width(column, 60);
537 gtk_tree_view_column_set_fixed_width(column, 80);
538 gtk_tree_view_append_column(list_view, column);
541 renderer = gtk_cell_renderer_text_new();
542 column = gtk_tree_view_column_new_with_attributes("Packets/s", renderer,
545 gtk_tree_view_column_set_sort_column_id(column, MC_COL_PPS);
546 gtk_tree_view_column_set_resizable(column, TRUE);
547 gtk_tree_view_column_set_sizing(column, GTK_TREE_VIEW_COLUMN_FIXED);
548 gtk_tree_view_column_set_min_width(column, 60);
549 gtk_tree_view_column_set_fixed_width(column, 90);
550 gtk_tree_view_append_column(list_view, column);
552 /* Average bandwidth */
553 renderer = gtk_cell_renderer_text_new();
554 column = gtk_tree_view_column_new_with_attributes("Avg Bw", renderer,
555 "text", MC_COL_AVG_BW,
557 gtk_tree_view_column_set_sort_column_id(column, MC_COL_AVG_BW);
558 gtk_tree_view_column_set_resizable(column, TRUE);
559 gtk_tree_view_column_set_sizing(column, GTK_TREE_VIEW_COLUMN_FIXED);
560 gtk_tree_view_column_set_min_width(column, 70);
561 gtk_tree_view_column_set_fixed_width(column, 80);
562 gtk_tree_view_append_column(list_view, column);
565 renderer = gtk_cell_renderer_text_new();
566 column = gtk_tree_view_column_new_with_attributes("Max Bw", renderer,
567 "text", MC_COL_MAX_BW,
569 gtk_tree_view_column_set_sort_column_id(column, MC_COL_MAX_BW);
570 gtk_tree_view_column_set_resizable(column, TRUE);
571 gtk_tree_view_column_set_sizing(column, GTK_TREE_VIEW_COLUMN_FIXED);
572 gtk_tree_view_column_set_min_width(column, 70);
573 gtk_tree_view_column_set_fixed_width(column, 80);
574 gtk_tree_view_append_column(list_view, column);
577 renderer = gtk_cell_renderer_text_new();
578 column = gtk_tree_view_column_new_with_attributes("Max bursts", renderer,
579 "text", MC_COL_MAX_BURST,
581 gtk_tree_view_column_set_sort_column_id(column, MC_COL_MAX_BURST);
582 gtk_tree_view_column_set_resizable(column, TRUE);
583 gtk_tree_view_column_set_sizing(column, GTK_TREE_VIEW_COLUMN_FIXED);
584 gtk_tree_view_column_set_min_width(column, 70);
585 gtk_tree_view_column_set_fixed_width(column, 100);
586 gtk_tree_view_append_column(list_view, column);
589 renderer = gtk_cell_renderer_text_new();
590 column = gtk_tree_view_column_new_with_attributes("Burst alarms", renderer,
591 "text", MC_COL_BURST_ALARM,
593 gtk_tree_view_column_set_sort_column_id(column, MC_COL_BURST_ALARM);
594 gtk_tree_view_column_set_resizable(column, TRUE);
595 gtk_tree_view_column_set_sizing(column, GTK_TREE_VIEW_COLUMN_FIXED);
596 gtk_tree_view_column_set_min_width(column, 90);
597 gtk_tree_view_column_set_fixed_width(column, 110);
598 gtk_tree_view_append_column(list_view, column);
601 renderer = gtk_cell_renderer_text_new();
602 column = gtk_tree_view_column_new_with_attributes("Max buffers", renderer,
603 "text", MC_COL_MAX_BUFFER,
605 gtk_tree_view_column_set_sort_column_id(column, MC_COL_MAX_BUFFER);
606 gtk_tree_view_column_set_resizable(column, TRUE);
607 gtk_tree_view_column_set_sizing(column, GTK_TREE_VIEW_COLUMN_FIXED);
608 gtk_tree_view_column_set_min_width(column, 90);
609 gtk_tree_view_column_set_fixed_width(column, 100);
610 gtk_tree_view_append_column(list_view, column);
613 renderer = gtk_cell_renderer_text_new();
614 column = gtk_tree_view_column_new_with_attributes("Buffer alarms", renderer,
615 "text", MC_COL_BUFFER_ALARM,
617 gtk_tree_view_column_set_sort_column_id(column, MC_COL_BUFFER_ALARM);
618 gtk_tree_view_column_set_resizable(column, TRUE);
619 gtk_tree_view_column_set_sizing(column, GTK_TREE_VIEW_COLUMN_FIXED);
620 gtk_tree_view_column_set_min_width(column, 90);
621 gtk_tree_view_column_set_fixed_width(column, 120);
622 gtk_tree_view_append_column(list_view, column);
624 /* Now enable the sorting of each column */
625 gtk_tree_view_set_rules_hint(list_view, TRUE);
626 gtk_tree_view_set_headers_clickable(list_view, TRUE);
628 /* Setup the selection handler */
629 selection = gtk_tree_view_get_selection(list_view);
630 gtk_tree_selection_set_mode(selection, GTK_SELECTION_SINGLE);
632 g_signal_connect(G_OBJECT(selection), "changed", /* (un)select_row */
633 G_CALLBACK(mcaststream_on_select_row),
639 /****************************************************************************/
642 mcaststream_dlg_create(void)
644 GtkWidget *mcaststream_dlg_w;
646 GtkWidget *scrolledwindow;
647 GtkWidget *hbuttonbox;
648 /*GtkWidget *bt_unselect;*/
649 GtkWidget *bt_params;
652 const gchar *title_name_ptr;
655 title_name_ptr = cf_get_display_name(&cfile);
656 win_name = g_strdup_printf("%s - UDP Multicast Streams", title_name_ptr);
657 mcaststream_dlg_w = dlg_window_new(win_name);
659 gtk_window_set_default_size(GTK_WINDOW(mcaststream_dlg_w), 620, 400);
661 main_vb = ws_gtk_box_new(GTK_ORIENTATION_VERTICAL, 0, FALSE);
662 gtk_container_add(GTK_CONTAINER(mcaststream_dlg_w), main_vb);
663 gtk_container_set_border_width (GTK_CONTAINER (main_vb), 12);
665 top_label = gtk_label_new ("Detected 0 Multicast streams");
666 gtk_box_pack_start (GTK_BOX (main_vb), top_label, FALSE, FALSE, 8);
668 scrolledwindow = scrolled_window_new (NULL, NULL);
669 gtk_box_pack_start (GTK_BOX (main_vb), scrolledwindow, TRUE, TRUE, 0);
672 gtk_container_add(GTK_CONTAINER(scrolledwindow), list_w);
674 gtk_widget_show(mcaststream_dlg_w);
676 label_fwd = gtk_label_new (FWD_LABEL_TEXT);
677 gtk_box_pack_start (GTK_BOX (main_vb), label_fwd, FALSE, FALSE, 0);
679 label_par = gtk_label_new (PAR_LABEL_TEXT);
680 gtk_box_pack_start (GTK_BOX (main_vb), label_par, FALSE, FALSE, 0);
683 hbuttonbox = gtk_hbutton_box_new ();
684 gtk_box_pack_start (GTK_BOX (main_vb), hbuttonbox, FALSE, FALSE, 0);
685 gtk_button_box_set_layout (GTK_BUTTON_BOX (hbuttonbox), GTK_BUTTONBOX_END);
686 gtk_box_set_spacing (GTK_BOX (hbuttonbox), 0);
688 /*bt_unselect = gtk_button_new_with_label ("Unselect");
689 gtk_container_add (GTK_CONTAINER (hbuttonbox), bt_unselect);
690 gtk_widget_set_tooltip_text (bt_unselect, "Undo stream selection");*/
692 bt_params = gtk_button_new_with_label ("Set parameters");
693 gtk_container_add (GTK_CONTAINER (hbuttonbox), bt_params);
694 gtk_widget_set_tooltip_text (bt_params, "Set buffer, limit and speed parameters");
696 bt_filter = gtk_button_new_with_label ("Prepare Filter");
697 gtk_container_add (GTK_CONTAINER (hbuttonbox), bt_filter);
698 gtk_widget_set_tooltip_text (bt_filter, "Prepare a display filter of the selected stream");
700 bt_close = gtk_button_new_from_stock(GTK_STOCK_CLOSE);
701 gtk_container_add (GTK_CONTAINER (hbuttonbox), bt_close);
702 gtk_widget_set_tooltip_text (bt_close, "Close this dialog");
703 #if GTK_CHECK_VERSION(2,18,0)
704 gtk_widget_set_can_default(bt_close, TRUE);
706 GTK_WIDGET_SET_FLAGS(bt_close, GTK_CAN_DEFAULT);
709 /*g_signal_connect(bt_unselect, "clicked", G_CALLBACK(mcaststream_on_unselect), NULL);*/
710 g_signal_connect(bt_params, "clicked", G_CALLBACK(mcast_on_params), NULL);
711 g_signal_connect(bt_filter, "clicked", G_CALLBACK(mcaststream_on_filter), NULL);
712 window_set_cancel_button(mcaststream_dlg_w, bt_close, window_cancel_button_cb);
714 g_signal_connect(mcaststream_dlg_w, "delete_event", G_CALLBACK(window_delete_event_cb), NULL);
715 g_signal_connect(mcaststream_dlg_w, "destroy", G_CALLBACK(mcaststream_on_destroy), NULL);
717 gtk_widget_show_all(mcaststream_dlg_w);
718 window_present(mcaststream_dlg_w);
720 mcaststream_on_unselect(NULL, NULL);
722 mcast_stream_dlg = mcaststream_dlg_w;
729 /****************************************************************************/
731 /****************************************************************************/
733 /****************************************************************************/
734 /* update the contents of the dialog box clist */
735 /* list: pointer to list of mcast_stream_info_t* */
737 mcaststream_dlg_update(GList *list)
739 if (mcast_stream_dlg != NULL) {
740 gtk_list_store_clear(list_store);
743 list = g_list_first(list);
746 add_to_list_store((mcast_stream_info_t*)(list->data));
747 list = g_list_next(list);
750 mcaststream_on_unselect(NULL, NULL);
757 /****************************************************************************/
758 /* update the contents of the dialog box clist */
759 /* list: pointer to list of mcast_stream_info_t* */
761 mcaststream_dlg_show(GList *list)
763 if (mcast_stream_dlg != NULL) {
764 /* There's already a dialog box; reactivate it. */
765 reactivate_window(mcast_stream_dlg);
766 /* Another list since last call? */
767 if (list != last_list) {
768 mcaststream_dlg_update(list);
772 /* Create and show the dialog box */
773 mcaststream_dlg_create();
774 mcaststream_dlg_update(list);
779 /****************************************************************************/
780 /* entry point when called via the GTK menu */
782 mcaststream_launch(GtkAction *action _U_, gpointer user_data _U_)
784 /* Register the tap listener */
785 register_tap_listener_mcast_stream();
787 /* Scan for Mcast streams (redissect all packets) */
790 /* Show the dialog box with the list of streams */
791 mcaststream_dlg_show(mcaststream_get_info()->strinfo_list);
793 /* Tap listener will be removed and cleaned up in mcaststream_on_destroy */
796 /****************************************************************************/
798 register_tap_listener_mcast_stream_dlg(void)