2 * Copyright 2004, Irene Ruengeler <i.ruengeler [AT] fh-muenster.de>
6 * Wireshark - Network traffic analyzer
7 * By Gerald Combs <gerald@wireshark.org>
8 * Copyright 1998 Gerald Combs
10 * This program is free software; you can redistribute it and/or
11 * modify it under the terms of the GNU General Public License
12 * as published by the Free Software Foundation; either version 2
13 * of the License, or (at your option) any later version.
15 * This program is distributed in the hope that it will be useful,
16 * but WITHOUT ANY WARRANTY; without even the implied warranty of
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 * GNU General Public License for more details.
20 * You should have received a copy of the GNU General Public License
21 * along with this program; if not, write to the Free Software
22 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
32 #include "epan/filesystem.h"
33 #include <epan/strutil.h>
35 #include "../globals.h"
36 #include "ui/ui_util.h"
37 #include "ui/simple_dialog.h"
39 #include "ui/gtk/dlg_utils.h"
40 #include "ui/gtk/gui_utils.h"
41 #include "ui/gtk/main.h"
42 #include "ui/gtk/sctp_stat.h"
44 #include "ui/gtk/old-gtk-compat.h"
46 #define DEFAULT_PIXELS_PER_TICK 2
47 #define MAX_PIXELS_PER_TICK 4
48 #define AUTO_MAX_YSCALE 0
49 #define MAX_TICK_VALUES 5
50 #define DEFAULT_TICK_VALUE 3
52 #define MAX_COUNT_TYPES 3
54 #define COUNT_TYPE_FRAMES 0
55 #define COUNT_TYPE_BYTES 1
56 #define COUNT_TYPE_ADVANCED 2
58 #define LEFT_BORDER 80
59 #define RIGHT_BORDER 20
61 #define BOTTOM_BORDER 50
63 #define SUB_32(a, b) a-b
71 struct data_chunk_header {
81 struct init_chunk_header {
92 struct sack_chunk_header {
108 static gboolean label_set = FALSE;
109 static guint32 max_tsn=0, min_tsn=0;
112 static void sctp_graph_set_title(struct sctp_udata *u_data);
113 static void create_draw_area(GtkWidget *box, struct sctp_udata *u_data);
114 static GtkWidget *zoomout_bt;
116 static void draw_sack_graph(struct sctp_udata *u_data)
118 GdkRGBA red_color = {1.0, 0.0, 0.0, 1.0};
119 GdkRGBA green_color = {0.0, 1.0, 0.0, 1.0};
121 GPtrArray *array = NULL;
122 guint32 i, size = 0, start=0, end;
123 gboolean more = FALSE;
127 if (u_data->dir == 1)
129 array = u_data->assoc->sort_sack1;
130 size=u_data->assoc->n_sack_chunks_ep1;
131 if (u_data->io->tmp == FALSE)
134 max_tsn = u_data->assoc->max_bytes1;
138 min_tsn = u_data->io->tmp_min_tsn1;
139 max_tsn = u_data->io->tmp_max_tsn1;
142 else if (u_data->dir == 2)
144 array = u_data->assoc->sort_sack2;
145 size = u_data->assoc->n_sack_chunks_ep2;
146 if (u_data->io->tmp == FALSE)
149 max_tsn = u_data->assoc->max_bytes2;
153 min_tsn = u_data->io->tmp_min_tsn2;
154 max_tsn = u_data->io->tmp_max_tsn2;
158 width = u_data->io->max_x - u_data->io->min_x;
160 for (i=0; i<size; i++)
162 if (u_data->io->uoff)
163 diff = (gint)((struct tsn_sort*)(g_ptr_array_index(array, i)))->secs - u_data->io->min_x;
165 diff = (gint)((struct tsn_sort*)(g_ptr_array_index(array, i)))->secs * 1000000 + ((struct tsn_sort*)(g_ptr_array_index(array, i)))->usecs - u_data->io->min_x;
166 end = start + ((struct tsn_sort*)(g_ptr_array_index(array, i)))->length;
173 if (start >= min_tsn && diff > 0 && diff <= width)
175 #if GTK_CHECK_VERSION(2,22,0)
176 cr = cairo_create (u_data->io->surface);
178 cr = gdk_cairo_create (u_data->io->pixmap);
180 gdk_cairo_set_source_rgba (cr, &red_color);
181 cairo_set_line_width (cr, 1.0);
183 LEFT_BORDER+u_data->io->offset+u_data->io->x_interval*diff+0.5,
184 u_data->io->surface_height-BOTTOM_BORDER-u_data->io->offset-((SUB_32(start,min_tsn))*u_data->io->y_interval)+0.5);
186 LEFT_BORDER+u_data->io->offset+u_data->io->x_interval*diff+0.5,
187 u_data->io->surface_height-BOTTOM_BORDER-u_data->io->offset-((SUB_32(end,min_tsn))*u_data->io->y_interval)+0.5);
192 #if GTK_CHECK_VERSION(2,22,0)
193 cr = cairo_create (u_data->io->surface);
195 cr = gdk_cairo_create (u_data->io->pixmap);
197 gdk_cairo_set_source_rgba (cr, &green_color);
198 cairo_set_line_width (cr, 1.0);
200 LEFT_BORDER+u_data->io->offset+u_data->io->x_interval*diff+0.5,
201 u_data->io->surface_height-BOTTOM_BORDER-u_data->io->offset-((SUB_32(end,min_tsn))*u_data->io->y_interval)+0.5);
203 LEFT_BORDER+u_data->io->offset+u_data->io->x_interval*diff,
204 u_data->io->surface_height-BOTTOM_BORDER-u_data->io->offset-((SUB_32(end+10,min_tsn))*u_data->io->y_interval)+0.5);
215 static void draw_tsn_graph(struct sctp_udata *u_data)
217 GPtrArray *array = NULL;
218 guint32 i, size = 0, start, end;
222 if (u_data->dir == 1)
224 array = u_data->assoc->sort_tsn1;
225 size = u_data->assoc->n_data_chunks_ep1;
226 if (u_data->io->tmp == FALSE)
229 max_tsn = u_data->assoc->max_bytes1;
233 min_tsn = u_data->io->tmp_min_tsn1;
234 max_tsn = u_data->io->tmp_max_tsn1;
237 else if (u_data->dir == 2)
239 array = u_data->assoc->sort_tsn2;
240 size = u_data->assoc->n_data_chunks_ep2;
241 if (u_data->io->tmp == FALSE)
244 max_tsn = u_data->assoc->max_bytes2;
248 min_tsn = u_data->io->tmp_min_tsn2;
249 max_tsn = u_data->io->tmp_max_tsn2;
252 width = u_data->io->max_x - u_data->io->min_x;
254 for (i=0; i<size; i++)
256 if (u_data->io->uoff)
257 diff = (gint)((struct tsn_sort*)(g_ptr_array_index(array, i)))->secs -u_data->io->min_x;
259 diff = (gint)((struct tsn_sort*)(g_ptr_array_index(array, i)))->secs*1000000 + ((struct tsn_sort*)(g_ptr_array_index(array, i)))->usecs-u_data->io->min_x;
260 start = ((struct tsn_sort*)(g_ptr_array_index(array, i)))->offset;
261 end = start + ((struct tsn_sort*)(g_ptr_array_index(array, i)))->length;
262 if (start >= min_tsn && diff > 0 && diff <= width){
263 #if GTK_CHECK_VERSION(2,22,0)
264 cr = cairo_create (u_data->io->surface);
266 cr = gdk_cairo_create (u_data->io->pixmap);
268 cairo_set_line_width (cr, 1.0);
270 (LEFT_BORDER+u_data->io->offset+u_data->io->x_interval*diff)+0.5,
271 (u_data->io->surface_height-BOTTOM_BORDER-u_data->io->offset-((SUB_32(start,min_tsn))*u_data->io->y_interval))+0.5);
273 (LEFT_BORDER+u_data->io->offset+u_data->io->x_interval*diff)+0.5,
274 (u_data->io->surface_height-BOTTOM_BORDER-u_data->io->offset-((SUB_32(end,min_tsn))*u_data->io->y_interval))+0.5);
283 static void sctp_graph_draw(struct sctp_udata *u_data)
286 guint32 distance=5, i, e, sec, w, start, a, j, b;
287 gint label_width, label_height;
288 char label_string[15];
290 gboolean write_label = FALSE;
292 GtkAllocation widget_alloc;
295 if (u_data->io->x1_tmp_sec == 0 && u_data->io->x1_tmp_usec == 0)
296 u_data->io->offset = 0;
298 u_data->io->offset = 5;
300 if (u_data->io->x2_tmp_sec - u_data->io->x1_tmp_sec > 1500)
302 u_data->io->min_x=u_data->io->x1_tmp_sec;
303 u_data->io->max_x=u_data->io->x2_tmp_sec;
304 u_data->io->uoff = TRUE;
308 u_data->io->min_x=((guint32) (u_data->io->x1_tmp_sec*1000000.0))+u_data->io->x1_tmp_usec;
309 u_data->io->max_x=((guint32) (u_data->io->x2_tmp_sec*1000000.0))+u_data->io->x2_tmp_usec;
310 u_data->io->uoff = FALSE;
313 u_data->io->tmp_width = u_data->io->max_x - u_data->io->min_x;
315 if (u_data->dir == 1)
317 if (u_data->io->tmp == FALSE)
319 if (u_data->assoc->sort_tsn1 != NULL)
320 u_data->io->max_y = u_data->io->tmp_max_tsn1 - u_data->io->tmp_min_tsn1;
322 u_data->io->max_y = 0;
323 u_data->io->min_y = 0;
327 u_data->io->max_y = u_data->io->tmp_max_tsn1;
328 u_data->io->min_y = u_data->io->tmp_min_tsn1;
331 else if (u_data->dir == 2)
333 if (u_data->io->tmp == FALSE)
335 if (u_data->assoc->tsn2 != NULL)
336 u_data->io->max_y = u_data->io->tmp_max_tsn2 - u_data->io->tmp_min_tsn2;
338 u_data->io->max_y = 0;
339 u_data->io->min_y = 0;
343 u_data->io->max_y = u_data->io->tmp_max_tsn2;
344 u_data->io->min_y = u_data->io->tmp_min_tsn2;
348 #if GTK_CHECK_VERSION(2,22,0)
349 cr = cairo_create (u_data->io->surface);
351 cr = gdk_cairo_create (u_data->io->pixmap);
353 cairo_set_source_rgb (cr, 1, 1, 1);
354 gtk_widget_get_allocation(u_data->io->draw_area, &widget_alloc);
359 widget_alloc.height);
364 #if GTK_CHECK_VERSION(2,22,0)
365 cr = cairo_create (u_data->io->surface);
367 cr = gdk_cairo_create (u_data->io->pixmap);
369 cairo_set_line_width (cr, 1.0);
370 cairo_move_to(cr, LEFT_BORDER+u_data->io->offset+0.5, u_data->io->surface_height - BOTTOM_BORDER+0.5);
371 cairo_line_to(cr, u_data->io->surface_width - RIGHT_BORDER + u_data->io->offset+0.5, u_data->io->surface_height - BOTTOM_BORDER+0.5);
373 cairo_move_to(cr, u_data->io->surface_width - RIGHT_BORDER + u_data->io->offset+0.5, u_data->io->surface_height - BOTTOM_BORDER+0.5);
374 cairo_line_to(cr, u_data->io->surface_width - RIGHT_BORDER + u_data->io->offset - 5+0.5, u_data->io->surface_height - BOTTOM_BORDER - 5+0.5);
376 cairo_move_to(cr, u_data->io->surface_width - RIGHT_BORDER + u_data->io->offset + 0.5, u_data->io->surface_height - BOTTOM_BORDER + 0.5);
377 cairo_line_to(cr, u_data->io->surface_width - RIGHT_BORDER + u_data->io->offset - 5.5, u_data->io->surface_height - BOTTOM_BORDER + 5.5);
381 u_data->io->axis_width = u_data->io->surface_width - LEFT_BORDER - RIGHT_BORDER - u_data->io->offset;
383 if(u_data->io->tmp_width>0){
384 u_data->io->x_interval = (float)((u_data->io->axis_width*1.0)/u_data->io->tmp_width); /*distance in pixels between 2 data points*/
386 u_data->io->x_interval = (float)(u_data->io->axis_width);
390 if (u_data->io->x_interval < 1)
392 dis = 1 / u_data->io->x_interval;
399 for (i=0; i<=e+1; i++)
405 g_snprintf(label_string, sizeof(label_string), "%d", 0);
406 memcpy(label_string,(gchar *)g_locale_to_utf8(label_string, -1 , NULL, NULL, NULL), 15);
407 layout = gtk_widget_create_pango_layout(u_data->io->draw_area, label_string);
408 pango_layout_get_pixel_size(layout, &label_width, &label_height);
410 if (u_data->io->x1_tmp_usec == 0)
411 sec = u_data->io->x1_tmp_sec;
413 sec = u_data->io->x1_tmp_sec+1;
415 if (u_data->io->offset != 0)
417 g_snprintf(label_string, sizeof(label_string), "%u", u_data->io->x1_tmp_sec);
418 memcpy(label_string,(gchar *)g_locale_to_utf8(label_string, -1 , NULL, NULL, NULL), sizeof(label_string));
419 pango_layout_set_text(layout, label_string, -1);
420 pango_layout_get_pixel_size(layout, &lwidth, NULL);
422 #if GTK_CHECK_VERSION(2,22,0)
423 cr = cairo_create (u_data->io->surface);
425 cr = gdk_cairo_create (u_data->io->pixmap);
427 cairo_move_to (cr, LEFT_BORDER - 25, u_data->io->surface_height - BOTTOM_BORDER + 20);
428 pango_cairo_show_layout (cr, layout);
433 w = (guint32)(500 / (guint32)(distance * u_data->io->x_interval));
436 if (w == 4 || w==3 || w==2)
440 b = (guint32)((u_data->io->min_x/100000))%10; /* start for labels*/
448 if (!u_data->io->uoff)
452 start=u_data->io->min_x/1000000*1000000;
458 start=u_data->io->min_x/100000;
462 b = (guint32)((start/100000))%10;
467 start = u_data->io->min_x;
474 for (i=start, j=b; i<=u_data->io->max_x; i+=a, j++)
476 if (!u_data->io->uoff)
477 if (i >= u_data->io->min_x && i % 1000000 != 0)
480 g_snprintf(label_string, sizeof(label_string), "%d", i%1000000);
486 memcpy(label_string,(gchar *)g_locale_to_utf8(label_string, -1 , NULL, NULL, NULL), sizeof(label_string));
487 pango_layout_set_text(layout, label_string, -1);
488 pango_layout_get_pixel_size(layout, &lwidth, NULL);
489 #if GTK_CHECK_VERSION(2,22,0)
490 cr = cairo_create (u_data->io->surface);
492 cr = gdk_cairo_create (u_data->io->pixmap);
495 LEFT_BORDER + u_data->io->offset + (i - u_data->io->min_x) * u_data->io->x_interval - lwidth / 2,
496 u_data->io->surface_height - BOTTOM_BORDER + 10);
497 pango_cairo_show_layout (cr, layout);
501 #if GTK_CHECK_VERSION(2,22,0)
502 cr = cairo_create (u_data->io->surface);
504 cr = gdk_cairo_create (u_data->io->pixmap);
506 cairo_set_line_width (cr, 1.0);
508 LEFT_BORDER + u_data->io->offset + (i - u_data->io->min_x) * u_data->io->x_interval + 0.5,
509 u_data->io->surface_height - BOTTOM_BORDER + 0.5);
511 LEFT_BORDER + u_data->io->offset + (i - u_data->io->min_x) * u_data->io->x_interval + 0.5,
512 u_data->io->surface_height - BOTTOM_BORDER + length + 0.5);
517 if (!u_data->io->uoff)
519 if (i%1000000==0 && j%w==0)
535 #if GTK_CHECK_VERSION(2,22,0)
536 cr = cairo_create (u_data->io->surface);
538 cr = gdk_cairo_create (u_data->io->pixmap);
540 cairo_set_line_width (cr, 1.0);
542 LEFT_BORDER + u_data->io->offset + (i - u_data->io->min_x) * u_data->io->x_interval + 0.5,
543 u_data->io->surface_height - BOTTOM_BORDER + 0.5);
545 LEFT_BORDER + u_data->io->offset + (i - u_data->io->min_x) * u_data->io->x_interval + 0.5,
546 u_data->io->surface_height - BOTTOM_BORDER + 10 + 0.5);
550 g_snprintf(label_string, sizeof(label_string), "%d", sec);
551 memcpy(label_string,(gchar *)g_locale_to_utf8(label_string, -1 , NULL, NULL, NULL), sizeof(label_string));
552 pango_layout_set_text(layout, label_string, -1);
553 pango_layout_get_pixel_size(layout, &lwidth, NULL);
554 #if GTK_CHECK_VERSION(2,22,0)
555 cr = cairo_create (u_data->io->surface);
557 cr = gdk_cairo_create (u_data->io->pixmap);
560 (LEFT_BORDER + u_data->io->offset + (i - u_data->io->min_x) * u_data->io->x_interval-10),
561 u_data->io->surface_height - BOTTOM_BORDER + 20);
562 pango_cairo_show_layout (cr, layout);
570 g_strlcpy(label_string, "sec", sizeof(label_string));
572 memcpy(label_string,(gchar *)g_locale_to_utf8(label_string, -1 , NULL, NULL, NULL), sizeof(label_string));
573 pango_layout_set_text(layout, label_string, -1);
574 pango_layout_get_pixel_size(layout, &lwidth, NULL);
575 #if GTK_CHECK_VERSION(2,22,0)
576 cr = cairo_create (u_data->io->surface);
578 cr = gdk_cairo_create (u_data->io->pixmap);
581 u_data->io->surface_width - RIGHT_BORDER - 10,
582 u_data->io->surface_height - BOTTOM_BORDER + 30);
583 pango_cairo_show_layout (cr, layout);
590 #if GTK_CHECK_VERSION(2,22,0)
591 cr = cairo_create (u_data->io->surface);
593 cr = gdk_cairo_create (u_data->io->pixmap);
595 cairo_set_line_width (cr, 1.0);
596 cairo_move_to(cr, LEFT_BORDER + 0.5, TOP_BORDER - u_data->io->offset + 0.5);
597 cairo_line_to(cr, LEFT_BORDER + 0.5, u_data->io->surface_height - BOTTOM_BORDER - u_data->io->offset + 0.5);
599 cairo_move_to(cr, LEFT_BORDER + 0.5, TOP_BORDER - u_data->io->offset + 0.5);
600 cairo_line_to(cr, LEFT_BORDER - 5 + 0.5, TOP_BORDER - u_data->io->offset + 5 + 0.5);
602 cairo_move_to(cr, LEFT_BORDER + 0.5, TOP_BORDER - u_data->io->offset + 0.5);
603 cairo_line_to(cr, LEFT_BORDER +5 + 0.5, TOP_BORDER - u_data->io->offset + 5 + 0.5);
607 u_data->io->y_interval = (float)(((u_data->io->surface_height - TOP_BORDER - BOTTOM_BORDER) * 1.0)/(u_data->io->max_y - u_data->io->min_y));
610 if (u_data->io->y_interval < 1)
612 dis = 1 / u_data->io->y_interval;
620 distance = distance * 10;
622 else if (u_data->io->y_interval<2)
625 if (u_data->io->max_y > 0)
627 for (i=u_data->io->min_y/distance*distance; i<=u_data->io->max_y; i+=distance/5)
629 if (i >= u_data->io->min_y)
632 g_snprintf(label_string, sizeof(label_string), "%d", i);
634 if (i%distance == 0 || (distance <= 5 && u_data->io->y_interval > 10))
638 memcpy(label_string,(gchar *)g_locale_to_utf8(label_string, -1 , NULL, NULL, NULL), sizeof(label_string));
639 pango_layout_set_text(layout, label_string, -1);
640 pango_layout_get_pixel_size(layout, &lwidth, NULL);
641 #if GTK_CHECK_VERSION(2,22,0)
642 cr = cairo_create (u_data->io->surface);
644 cr = gdk_cairo_create (u_data->io->pixmap);
647 LEFT_BORDER - length - lwidth - 5,
648 u_data->io->surface_height - BOTTOM_BORDER - u_data->io->offset - (i - u_data->io->min_y) * u_data->io->y_interval - 3);
649 pango_cairo_show_layout (cr, layout);
653 #if GTK_CHECK_VERSION(2,22,0)
654 cr = cairo_create (u_data->io->surface);
656 cr = gdk_cairo_create (u_data->io->pixmap);
658 cairo_set_line_width (cr, 1.0);
660 LEFT_BORDER - length + 0.5,
661 u_data->io->surface_height - BOTTOM_BORDER - u_data->io->offset - (i - u_data->io->min_y) * u_data->io->y_interval + 0.5);
664 u_data->io->surface_height - BOTTOM_BORDER - u_data->io->offset - (i - u_data->io->min_y) * u_data->io->y_interval + 0.5);
671 simple_dialog(ESD_TYPE_INFO, ESD_BTN_OK, "No Data Chunks sent");
673 g_object_unref(G_OBJECT(layout));
677 static void sctp_graph_redraw(struct sctp_udata *u_data)
680 GtkAllocation widget_alloc;
683 u_data->io->needs_redraw = TRUE;
685 sctp_graph_draw(u_data);
686 switch (u_data->io->graph_type)
689 draw_sack_graph(u_data);
690 draw_tsn_graph(u_data);
693 draw_tsn_graph(u_data);
696 draw_sack_graph(u_data);
700 ios=(sctp_graph_t *)g_object_get_data(G_OBJECT(u_data->io->draw_area), "sctp_graph_t");
701 g_assert(ios != NULL);
703 cr = gdk_cairo_create (gtk_widget_get_window(u_data->io->draw_area));
705 #if GTK_CHECK_VERSION(2,22,0)
706 cairo_set_source_surface (cr, ios->surface, 0, 0);
708 gdk_cairo_set_source_pixmap (cr, ios->pixmap, 0, 0);
710 gtk_widget_get_allocation(u_data->io->draw_area, &widget_alloc);
711 cairo_rectangle (cr, 0, 0, widget_alloc.width, widget_alloc.height);
718 static void on_sack_bt(GtkWidget *widget _U_, struct sctp_udata *u_data)
720 u_data = (struct sctp_udata *) u_data;
721 u_data->io->graph_type = 2;
722 sctp_graph_redraw(u_data);
725 static void on_tsn_bt(GtkWidget *widget _U_, struct sctp_udata *u_data)
727 u_data->io->graph_type = 1;
728 sctp_graph_redraw(u_data);
731 static void on_both_bt(GtkWidget *widget _U_, struct sctp_udata *u_data)
733 u_data->io->graph_type = 0;
734 sctp_graph_redraw(u_data);
738 sctp_graph_close_cb(GtkWidget* widget _U_, gpointer u_data)
740 struct sctp_udata *udata;
742 udata = (struct sctp_udata *)u_data;
743 gtk_grab_remove(GTK_WIDGET(udata->io->window));
744 gtk_widget_destroy(GTK_WIDGET(udata->io->window));
750 on_configure_event(GtkWidget *widget, GdkEventConfigure *event _U_, gpointer user_data)
752 struct sctp_udata *u_data = (struct sctp_udata *)user_data;
753 GtkAllocation widget_alloc;
756 g_assert(u_data->io != NULL);
758 #if GTK_CHECK_VERSION(2,22,0)
759 if(u_data->io->surface){
760 cairo_surface_destroy (u_data->io->surface);
761 u_data->io->surface=NULL;
763 gtk_widget_get_allocation(widget, &widget_alloc);
764 u_data->io->surface = gdk_window_create_similar_surface (gtk_widget_get_window(widget),
767 widget_alloc.height);
769 if(u_data->io->pixmap){
770 g_object_unref(u_data->io->pixmap);
771 u_data->io->pixmap = NULL;
773 gtk_widget_get_allocation(widget, &widget_alloc);
774 u_data->io->pixmap = gdk_pixmap_new(gtk_widget_get_window(widget),
779 u_data->io->surface_width = widget_alloc.width;
780 u_data->io->surface_height = widget_alloc.height;
782 #if GTK_CHECK_VERSION(2,22,0)
783 cr = cairo_create (u_data->io->surface);
785 cr = gdk_cairo_create (u_data->io->pixmap);
787 cairo_rectangle (cr, 0, 0, widget_alloc.width, widget_alloc.height);
788 cairo_set_source_rgb (cr, 1, 1, 1);
792 sctp_graph_redraw(u_data);
796 #if GTK_CHECK_VERSION(3,0,0)
798 on_draw_area_draw_event(GtkWidget *widget, cairo_t *cr, gpointer user_data)
800 sctp_graph_t *ios = (sctp_graph_t *)user_data;
801 GtkAllocation allocation;
803 gtk_widget_get_allocation (widget, &allocation);
804 cairo_set_source_surface (cr, ios->surface, 0, 0);
805 cairo_rectangle (cr, 0, 0, allocation.width, allocation.width);
812 on_expose_event(GtkWidget *widget, GdkEventExpose *event, gpointer user_data)
814 sctp_graph_t *ios = (sctp_graph_t *)user_data;
817 g_assert(ios != NULL);
819 cr = gdk_cairo_create (gtk_widget_get_window(widget));
821 #if GTK_CHECK_VERSION(2,22,0)
822 cairo_set_source_surface (cr, ios->surface, 0, 0);
824 gdk_cairo_set_source_pixmap (cr, ios->pixmap, 0, 0);
826 cairo_rectangle (cr, event->area.x, event->area.y, event->area.width, event->area.height);
836 on_zoomin_bt (GtkWidget *widget _U_, struct sctp_udata *u_data)
838 sctp_min_max_t *tmp_minmax;
840 if (u_data->io->rectangle==TRUE)
842 tmp_minmax = (sctp_min_max_t *)g_malloc(sizeof(sctp_min_max_t));
844 u_data->io->tmp_min_tsn1=u_data->io->y1_tmp+u_data->io->min_y;
845 u_data->io->tmp_max_tsn1=u_data->io->y2_tmp+1+u_data->io->min_y;
847 u_data->io->tmp_min_tsn2=u_data->io->tmp_min_tsn1;
848 u_data->io->tmp_max_tsn2=u_data->io->tmp_max_tsn1;
849 tmp_minmax->tmp_min_secs=u_data->io->x1_tmp_sec;
850 tmp_minmax->tmp_min_usecs= u_data->io->x1_tmp_usec;
851 tmp_minmax->tmp_max_secs= u_data->io->x2_tmp_sec;
852 tmp_minmax->tmp_max_usecs= u_data->io->x2_tmp_usec;
853 tmp_minmax->tmp_min_tsn1=u_data->io->tmp_min_tsn1;
854 tmp_minmax->tmp_max_tsn1=u_data->io->tmp_max_tsn1;
855 tmp_minmax->tmp_min_tsn2=u_data->io->tmp_min_tsn2;
856 tmp_minmax->tmp_max_tsn2=u_data->io->tmp_max_tsn2;
857 u_data->assoc->min_max = g_slist_prepend(u_data->assoc->min_max, tmp_minmax);
858 u_data->io->length = g_slist_length(u_data->assoc->min_max);
859 u_data->io->tmp=TRUE;
860 u_data->io->rectangle=FALSE;
861 gtk_widget_set_sensitive(zoomout_bt, TRUE);
862 sctp_graph_redraw(u_data);
866 simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK, "Please draw a rectangle around the area you want to zoom in.");
871 zoomin_bt_fcn (struct sctp_udata *u_data)
873 sctp_min_max_t *tmp_minmax;
875 tmp_minmax = (sctp_min_max_t *)g_malloc(sizeof(sctp_min_max_t));
877 u_data->io->tmp_min_tsn1=u_data->io->y1_tmp+u_data->io->min_y;
878 u_data->io->tmp_max_tsn1=u_data->io->y2_tmp+1+u_data->io->min_y;
880 u_data->io->tmp_min_tsn2=u_data->io->tmp_min_tsn1;
881 u_data->io->tmp_max_tsn2=u_data->io->tmp_max_tsn1;
882 tmp_minmax->tmp_min_secs=u_data->io->x1_tmp_sec;
883 tmp_minmax->tmp_min_usecs=u_data->io->x1_tmp_usec;
884 tmp_minmax->tmp_max_secs=u_data->io->x2_tmp_sec;
885 tmp_minmax->tmp_max_usecs=u_data->io->x2_tmp_usec;
886 tmp_minmax->tmp_min_tsn1=u_data->io->tmp_min_tsn1;
887 tmp_minmax->tmp_max_tsn1=u_data->io->tmp_max_tsn1;
888 tmp_minmax->tmp_min_tsn2=u_data->io->tmp_min_tsn2;
889 tmp_minmax->tmp_max_tsn2=u_data->io->tmp_max_tsn2;
890 u_data->assoc->min_max = g_slist_prepend(u_data->assoc->min_max, tmp_minmax);
891 u_data->io->length = g_slist_length(u_data->assoc->min_max);
892 u_data->io->tmp=TRUE;
893 u_data->io->rectangle=FALSE;
894 gtk_widget_set_sensitive(zoomout_bt, TRUE);
895 sctp_graph_redraw(u_data);
899 on_zoomout_bt (GtkWidget *widget _U_, struct sctp_udata *u_data)
901 sctp_min_max_t *tmp_minmax, *mm;
904 l = g_slist_length(u_data->assoc->min_max);
906 if (u_data->assoc->min_max!=NULL)
908 mm=(sctp_min_max_t *)((u_data->assoc->min_max)->data);
909 u_data->assoc->min_max=g_slist_remove(u_data->assoc->min_max, mm);
914 tmp_minmax = (sctp_min_max_t *)u_data->assoc->min_max->data;
915 u_data->io->x1_tmp_sec=tmp_minmax->tmp_min_secs;
916 u_data->io->x1_tmp_usec=tmp_minmax->tmp_min_usecs;
917 u_data->io->x2_tmp_sec=tmp_minmax->tmp_max_secs;
918 u_data->io->x2_tmp_usec=tmp_minmax->tmp_max_usecs;
919 u_data->io->tmp_min_tsn1=tmp_minmax->tmp_min_tsn1;
920 u_data->io->tmp_max_tsn1=tmp_minmax->tmp_max_tsn1;
921 u_data->io->tmp_min_tsn2=tmp_minmax->tmp_min_tsn2;
922 u_data->io->tmp_max_tsn2=tmp_minmax->tmp_max_tsn2;
923 u_data->io->tmp=TRUE;
927 u_data->io->x1_tmp_sec=u_data->assoc->min_secs;
928 u_data->io->x1_tmp_usec=u_data->assoc->min_usecs;
929 u_data->io->x2_tmp_sec=u_data->assoc->max_secs;
930 u_data->io->x2_tmp_usec=u_data->assoc->max_usecs;
931 u_data->io->tmp_min_tsn1=0;
932 u_data->io->tmp_max_tsn1=u_data->assoc->max_bytes1;
933 u_data->io->tmp_min_tsn2=0;
934 u_data->io->tmp_max_tsn2=u_data->assoc->max_bytes2;
935 u_data->io->tmp=FALSE;
940 u_data->io->x1_tmp_sec=u_data->assoc->min_secs;
941 u_data->io->x1_tmp_usec=u_data->assoc->min_usecs;
942 u_data->io->x2_tmp_sec=u_data->assoc->max_secs;
943 u_data->io->x2_tmp_usec=u_data->assoc->max_usecs;
944 u_data->io->tmp_min_tsn1=0;
945 u_data->io->tmp_max_tsn1=u_data->assoc->max_bytes1;
946 u_data->io->tmp_min_tsn2=0;
947 u_data->io->tmp_max_tsn2=u_data->assoc->max_bytes2;
948 u_data->io->tmp=FALSE;
950 if (g_slist_length(u_data->assoc->min_max)==1)
951 gtk_widget_set_sensitive(zoomout_bt, FALSE);
952 sctp_graph_redraw(u_data);
957 on_button_press_event (GtkWidget *widget _U_, GdkEventButton *event, gpointer user_data)
959 struct sctp_udata *u_data = (struct sctp_udata *)user_data;
963 if (u_data->io->rectangle==TRUE)
965 #if GTK_CHECK_VERSION(2,22,0)
966 cr = cairo_create (u_data->io->surface);
968 cr = gdk_cairo_create (u_data->io->pixmap);
971 floor(MIN(u_data->io->x_old,u_data->io->x_new)),
972 floor(MIN(u_data->io->y_old,u_data->io->y_new)),
973 abs((int)(u_data->io->x_new-u_data->io->x_old)),
974 abs((int)(u_data->io->y_new-u_data->io->y_old)));
975 cairo_set_source_rgb (cr, 1, 1, 1);
980 ios=(sctp_graph_t *)g_object_get_data(G_OBJECT(u_data->io->draw_area), "sctp_graph_t");
981 g_assert(ios != NULL);
983 cr = gdk_cairo_create (gtk_widget_get_window(u_data->io->draw_area));
985 #if GTK_CHECK_VERSION(2,22,0)
986 cairo_set_source_surface (cr, ios->surface, 0, 0);
988 gdk_cairo_set_source_pixmap (cr, ios->pixmap, 0, 0);
990 cairo_rectangle (cr, 0, 0, abs((int)(u_data->io->x_new-u_data->io->x_old)), abs((int)(u_data->io->y_new-u_data->io->y_old)));
995 sctp_graph_redraw(u_data);
998 u_data->io->x_old=event->x;
999 u_data->io->y_old=event->y;
1000 if (u_data->io->y_old>u_data->io->surface_height-BOTTOM_BORDER-u_data->io->offset)
1001 u_data->io->y_old=u_data->io->surface_height-BOTTOM_BORDER-u_data->io->offset;
1002 if (u_data->io->x_old<LEFT_BORDER+u_data->io->offset)
1003 u_data->io->x_old=LEFT_BORDER+u_data->io->offset;
1004 u_data->io->rectangle=FALSE;
1011 on_button_release_event (GtkWidget *widget _U_, GdkEventButton *event, gpointer user_data)
1013 struct sctp_udata *u_data = (struct sctp_udata *)user_data;
1015 guint32 helpx, helpy, x1_tmp, x2_tmp, y_value;
1016 gint label_width, label_height;
1017 gdouble x_value, position, tfirst;
1019 char label_string[30];
1020 GList *tsnlist=NULL;
1021 tsn_t *tsn, *tmptsn;
1022 PangoLayout *layout;
1023 GtkAllocation widget_alloc;
1026 g_snprintf(label_string, 15, "%d", 0);
1027 memcpy(label_string,(gchar *)g_locale_to_utf8(label_string, -1 , NULL, NULL, NULL), 15);
1028 layout = gtk_widget_create_pango_layout(u_data->io->draw_area, label_string);
1029 pango_layout_get_pixel_size(layout, &label_width, &label_height);
1031 if (event->y > u_data->io->surface_height-BOTTOM_BORDER-u_data->io->offset)
1032 event->y = u_data->io->surface_height-BOTTOM_BORDER-u_data->io->offset;
1033 if (event->x < LEFT_BORDER+u_data->io->offset)
1034 event->x = LEFT_BORDER+u_data->io->offset;
1036 if (abs((int)(event->x-u_data->io->x_old))>10 || abs((int)(event->y-u_data->io->y_old))>10)
1038 u_data->io->rect_x_min = (guint32) floor(MIN(u_data->io->x_old,event->x));
1039 u_data->io->rect_x_max = (guint32) ceil(MAX(u_data->io->x_old,event->x));
1040 u_data->io->rect_y_min = (guint32) floor(MIN(u_data->io->y_old,event->y));
1041 u_data->io->rect_y_max = (guint32) ceil(MAX(u_data->io->y_old,event->y));
1043 #if GTK_CHECK_VERSION(2,22,0)
1044 cr = cairo_create (u_data->io->surface);
1046 cr = gdk_cairo_create (u_data->io->pixmap);
1048 cairo_rectangle (cr,
1049 u_data->io->rect_x_min+0.5,
1050 u_data->io->rect_y_min+0.5,
1051 u_data->io->rect_x_max - u_data->io->rect_x_min,
1052 u_data->io->rect_y_max - u_data->io->rect_y_min);
1053 cairo_set_line_width (cr, 1.0);
1057 ios=(sctp_graph_t *)g_object_get_data(G_OBJECT(u_data->io->draw_area), "sctp_graph_t");
1058 g_assert(ios != NULL);
1060 cr = gdk_cairo_create (gtk_widget_get_window(u_data->io->draw_area));
1062 #if GTK_CHECK_VERSION(2,22,0)
1063 cairo_set_source_surface (cr, ios->surface, 0, 0);
1065 gdk_cairo_set_source_pixmap (cr, ios->pixmap, 0, 0);
1067 gtk_widget_get_allocation(u_data->io->draw_area, &widget_alloc);
1068 cairo_rectangle (cr, 0, 0, widget_alloc.width, widget_alloc.height);
1073 x1_tmp=(guint32) floor(u_data->io->min_x+((u_data->io->x_old-LEFT_BORDER-u_data->io->offset)*u_data->io->tmp_width/u_data->io->axis_width));
1074 x2_tmp=(guint32) floor(u_data->io->min_x+((event->x-LEFT_BORDER-u_data->io->offset)*u_data->io->tmp_width/u_data->io->axis_width));
1075 helpx=MIN(x1_tmp, x2_tmp);
1081 if (u_data->io->uoff)
1083 if (x2_tmp - x1_tmp <= 1500)
1084 u_data->io->uoff = FALSE;
1085 u_data->io->x1_tmp_sec=(guint32)x1_tmp;
1086 u_data->io->x1_tmp_usec=0;
1087 u_data->io->x2_tmp_sec=(guint32)x2_tmp;
1088 u_data->io->x2_tmp_usec=0;
1092 u_data->io->x1_tmp_sec=(guint32)x1_tmp/1000000;
1093 u_data->io->x1_tmp_usec=x1_tmp%1000000;
1094 u_data->io->x2_tmp_sec=(guint32)x2_tmp/1000000;
1095 u_data->io->x2_tmp_usec=x2_tmp%1000000;
1097 u_data->io->x1_akt_sec = u_data->io->x1_tmp_sec;
1098 u_data->io->x1_akt_usec = u_data->io->x1_tmp_usec;
1099 u_data->io->x2_akt_sec = u_data->io->x2_tmp_sec;
1100 u_data->io->x2_akt_usec = u_data->io->x2_tmp_usec;
1102 u_data->io->y1_tmp=(guint32)((u_data->io->surface_height-BOTTOM_BORDER-u_data->io->offset-u_data->io->y_old)/u_data->io->y_interval);
1103 u_data->io->y2_tmp=(guint32)((u_data->io->surface_height-BOTTOM_BORDER-u_data->io->offset-event->y)/u_data->io->y_interval);
1104 helpy = MIN(u_data->io->y1_tmp, u_data->io->y2_tmp);
1105 u_data->io->y2_tmp = MAX(u_data->io->y1_tmp, u_data->io->y2_tmp);
1106 u_data->io->y1_tmp = helpy;
1107 u_data->io->x_new=event->x;
1108 u_data->io->y_new=event->y;
1109 u_data->io->rectangle=TRUE;
1110 u_data->io->rectangle_present=TRUE;
1114 if (u_data->io->rectangle_present==TRUE)
1116 u_data->io->rectangle_present=FALSE;
1117 if (event->x >= u_data->io->rect_x_min && event->x <= u_data->io->rect_x_max &&
1118 event->y >= u_data->io->rect_y_min && event->y <= u_data->io->rect_y_max)
1119 zoomin_bt_fcn(u_data);
1122 u_data->io->x1_tmp_sec = u_data->io->x1_akt_sec;
1123 u_data->io->x1_tmp_usec = u_data->io->x1_akt_usec;
1124 u_data->io->x2_tmp_sec = u_data->io->x2_akt_sec;
1125 u_data->io->x2_tmp_usec = u_data->io->x2_akt_usec;
1126 sctp_graph_redraw(u_data);
1132 sctp_graph_redraw(u_data);
1136 x_value = ((event->x-LEFT_BORDER-u_data->io->offset) * ((u_data->io->x2_tmp_sec+u_data->io->x2_tmp_usec/1000000.0)-(u_data->io->x1_tmp_sec+u_data->io->x1_tmp_usec/1000000.0)) / (u_data->io->surface_width-LEFT_BORDER-RIGHT_BORDER-u_data->io->offset))+u_data->io->x1_tmp_sec+u_data->io->x1_tmp_usec/1000000.0;
1137 y_value = (guint32) floor((u_data->io->surface_height-BOTTOM_BORDER-u_data->io->offset-event->y) * (max_tsn - min_tsn) / (u_data->io->surface_height-BOTTOM_BORDER-u_data->io->offset)) + min_tsn;
1139 if (u_data->dir == 1)
1140 tsnlist = g_list_last(u_data->assoc->tsn1);
1142 tsnlist = g_list_last(u_data->assoc->tsn2);
1144 tsn = (tsn_t*) (tsnlist->data);
1145 tmptsn =(tsn_t*)(tsnlist->data);
1146 tfirst = tsn->secs + tsn->usecs/1000000.0;
1148 for (tsnlist = g_list_previous(tsnlist); tsnlist; tsnlist = g_list_previous(tsnlist))
1150 tsn = (tsn_t*) (tsnlist->data);
1151 if (tsn->secs+tsn->usecs/1000000.0<x_value)
1153 tfirst = tsn->secs+tsn->usecs/1000000.0;
1158 if ((tfirst+tsn->secs+tsn->usecs/1000000.0)/2.0<x_value)
1160 x_value = tsn->secs+tsn->usecs/1000000.0;
1164 x_value = tmptsn->secs+tmptsn->usecs/1000000.0;
1168 cf_goto_frame(&cfile, tmptsn->frame_number);
1169 g_snprintf(label_string, sizeof(label_string), "(%.6f, %u)", x_value, y_value);
1172 #if GTK_CHECK_VERSION(2,22,0)
1173 cr = cairo_create (u_data->io->surface);
1175 cr = gdk_cairo_create (u_data->io->pixmap);
1177 cairo_set_line_width (cr, 1.0);
1187 #if GTK_CHECK_VERSION(2,22,0)
1188 cr = cairo_create (u_data->io->surface);
1190 cr = gdk_cairo_create (u_data->io->pixmap);
1192 cairo_set_line_width (cr, 1.0);
1201 if (event->x+150>=u_data->io->surface_width)
1202 position = event->x - 150;
1204 position = event->x + 5;
1206 memcpy(label_string,(gchar *)g_locale_to_utf8(label_string, -1 , NULL, NULL, NULL), 15);
1207 pango_layout_set_text(layout, label_string, -1);
1208 pango_layout_get_pixel_size(layout, &lwidth, NULL);
1210 #if GTK_CHECK_VERSION(2,22,0)
1211 cr = cairo_create (u_data->io->surface);
1213 cr = gdk_cairo_create (u_data->io->pixmap);
1218 pango_cairo_show_layout (cr, layout);
1222 ios=(sctp_graph_t *)g_object_get_data(G_OBJECT(u_data->io->draw_area), "sctp_graph_t");
1223 g_assert(ios != NULL);
1225 cr = gdk_cairo_create (gtk_widget_get_window(u_data->io->draw_area));
1227 #if GTK_CHECK_VERSION(2,22,0)
1228 cairo_set_source_surface (cr, ios->surface, 0, 0);
1230 gdk_cairo_set_source_pixmap (cr, ios->pixmap, 0, 0);
1232 gtk_widget_get_allocation(u_data->io->draw_area, &widget_alloc);
1233 cairo_rectangle (cr, 0, 0, widget_alloc.width, widget_alloc.height);
1240 g_object_unref(G_OBJECT(layout));
1244 static void init_sctp_graph_window(struct sctp_udata *u_data)
1248 GtkWidget *bt_close, *sack_bt, *tsn_bt, *both_bt, *zoomin_bt;
1250 /* create the main window */
1252 u_data->io->window = dlg_window_new("SCTP Graphics"); /* transient_for top_level */
1253 gtk_window_set_destroy_with_parent (GTK_WINDOW(u_data->io->window), TRUE);
1255 vbox=ws_gtk_box_new(GTK_ORIENTATION_VERTICAL, 0, FALSE);
1256 gtk_container_add(GTK_CONTAINER(u_data->io->window), vbox);
1257 gtk_widget_show(vbox);
1259 create_draw_area(vbox, u_data);
1261 sctp_graph_set_title(u_data);
1263 hbox = gtk_button_box_new(GTK_ORIENTATION_HORIZONTAL);
1264 gtk_box_pack_start(GTK_BOX(vbox), hbox, FALSE, FALSE, 0);
1265 gtk_container_set_border_width(GTK_CONTAINER(hbox), 10);
1266 gtk_button_box_set_layout(GTK_BUTTON_BOX (hbox), GTK_BUTTONBOX_SPREAD);
1267 gtk_box_set_spacing(GTK_BOX (hbox), 0);
1268 gtk_widget_show(hbox);
1270 sack_bt = gtk_button_new_with_label ("Adv. Rec. Window");
1271 gtk_box_pack_start(GTK_BOX(hbox), sack_bt, FALSE, FALSE, 0);
1272 gtk_widget_show(sack_bt);
1274 g_signal_connect(sack_bt, "clicked", G_CALLBACK(on_sack_bt), u_data);
1276 tsn_bt = gtk_button_new_with_label ("Data bytes sent");
1277 gtk_box_pack_start(GTK_BOX(hbox), tsn_bt, FALSE, FALSE, 0);
1278 gtk_widget_show(tsn_bt);
1279 g_signal_connect(tsn_bt, "clicked", G_CALLBACK(on_tsn_bt), u_data);
1281 both_bt = gtk_button_new_with_label ("Show both");
1282 gtk_box_pack_start(GTK_BOX(hbox), both_bt, FALSE, FALSE, 0);
1283 gtk_widget_show(both_bt);
1284 g_signal_connect(both_bt, "clicked", G_CALLBACK(on_both_bt), u_data);
1286 zoomin_bt = gtk_button_new_with_label ("Zoom in");
1287 gtk_box_pack_start(GTK_BOX(hbox), zoomin_bt, FALSE, FALSE, 0);
1288 gtk_widget_show(zoomin_bt);
1289 g_signal_connect(zoomin_bt, "clicked", G_CALLBACK(on_zoomin_bt), u_data);
1290 gtk_widget_set_tooltip_text(zoomin_bt, "Zoom in the area you have selected");
1292 zoomout_bt = gtk_button_new_with_label ("Zoom out");
1293 gtk_box_pack_start(GTK_BOX(hbox), zoomout_bt, FALSE, FALSE, 0);
1294 gtk_widget_show(zoomout_bt);
1295 g_signal_connect(zoomout_bt, "clicked", G_CALLBACK(on_zoomout_bt), u_data);
1296 gtk_widget_set_tooltip_text(zoomout_bt, "Zoom out one step");
1297 gtk_widget_set_sensitive(zoomout_bt, FALSE);
1299 bt_close = gtk_button_new_from_stock(GTK_STOCK_CLOSE);
1300 gtk_box_pack_start(GTK_BOX(hbox), bt_close, FALSE, FALSE, 0);
1301 gtk_widget_show(bt_close);
1302 g_signal_connect(bt_close, "clicked", G_CALLBACK(sctp_graph_close_cb), u_data);
1304 g_signal_connect(u_data->io->draw_area,"button_press_event",G_CALLBACK(on_button_press_event), u_data);
1305 g_signal_connect(u_data->io->draw_area,"button_release_event",G_CALLBACK(on_button_release_event), u_data);
1306 gtk_widget_set_events(u_data->io->draw_area, GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK | GDK_EXPOSURE_MASK);
1307 /* dlg_set_cancel(u_data->io->window, bt_close); */
1309 gtk_widget_show(u_data->io->window);
1312 static void sctp_graph_set_title(struct sctp_udata *u_data)
1317 if(!u_data->io->window)
1321 display_name = cf_get_display_name(&cfile);
1322 title = g_strdup_printf("SCTP Data and Adv.Rcv.Window over Time: %s Port1 %u Port2 %u Endpoint %u",
1323 display_name, u_data->parent->assoc->port1, u_data->parent->assoc->port2, u_data->dir);
1324 g_free(display_name);
1325 gtk_window_set_title(GTK_WINDOW(u_data->io->window), title);
1331 gtk_sctpgraph_init(struct sctp_udata *u_data)
1334 sctp_min_max_t* tmp_minmax;
1336 io=(sctp_graph_t *)g_malloc(sizeof(sctp_graph_t));
1337 io->needs_redraw=TRUE;
1338 io->x_interval=1000;
1341 #if GTK_CHECK_VERSION(2,22,0)
1346 io->surface_width=800;
1347 io->surface_height=600;
1352 u_data->io->x1_tmp_sec=u_data->assoc->min_secs;
1353 u_data->io->x1_tmp_usec=u_data->assoc->min_usecs;
1354 u_data->io->x2_tmp_sec=u_data->assoc->max_secs;
1355 u_data->io->x2_tmp_usec=u_data->assoc->max_usecs;
1356 u_data->io->tmp_min_tsn1=0;
1357 u_data->io->tmp_max_tsn1=u_data->assoc->max_bytes1;
1358 u_data->io->tmp_min_tsn2=0;
1359 u_data->io->tmp_max_tsn2=u_data->assoc->max_bytes2;
1360 u_data->io->tmp=FALSE;
1361 tmp_minmax = (sctp_min_max_t *)g_malloc(sizeof(sctp_min_max_t));
1362 tmp_minmax->tmp_min_secs = u_data->assoc->min_secs;
1363 tmp_minmax->tmp_min_usecs=u_data->assoc->min_usecs;
1364 tmp_minmax->tmp_max_secs=u_data->assoc->max_secs;
1365 tmp_minmax->tmp_max_usecs=u_data->assoc->max_usecs;
1366 tmp_minmax->tmp_min_tsn2=u_data->io->tmp_min_tsn2;
1367 tmp_minmax->tmp_min_tsn1=u_data->io->tmp_min_tsn1;
1368 tmp_minmax->tmp_max_tsn1=u_data->io->tmp_max_tsn1;
1369 tmp_minmax->tmp_max_tsn2=u_data->io->tmp_max_tsn2;
1370 u_data->assoc->min_max = g_slist_prepend(u_data->assoc->min_max, tmp_minmax);
1373 init_sctp_graph_window(u_data);
1374 sctp_graph_redraw(u_data);
1379 quit(GObject *object _U_, gpointer user_data)
1381 struct sctp_udata *u_data=(struct sctp_udata *)user_data;
1383 decrease_childcount(u_data->parent);
1384 remove_child(u_data, u_data->parent);
1386 u_data->assoc->min_max = NULL;
1391 static void create_draw_area(GtkWidget *box, struct sctp_udata *u_data)
1393 u_data->io->draw_area=gtk_drawing_area_new();
1394 g_object_set_data(G_OBJECT(u_data->io->draw_area), "sctp_graph_t", u_data->io);
1395 g_signal_connect(u_data->io->draw_area, "destroy", G_CALLBACK(quit), u_data);
1397 gtk_widget_set_size_request(u_data->io->draw_area, u_data->io->surface_width, u_data->io->surface_height);
1399 /* signals needed to handle backing pixmap */
1400 #if GTK_CHECK_VERSION(3,0,0)
1401 g_signal_connect(u_data->io->draw_area, "draw", G_CALLBACK(on_draw_area_draw_event), u_data->io);
1403 g_signal_connect(u_data->io->draw_area, "expose_event", G_CALLBACK(on_expose_event), u_data->io);
1405 g_signal_connect(u_data->io->draw_area, "configure_event", G_CALLBACK(on_configure_event), u_data);
1407 gtk_widget_show(u_data->io->draw_area);
1408 gtk_box_pack_start(GTK_BOX(box), u_data->io->draw_area, TRUE, TRUE, 0);
1411 static void insertion(GPtrArray *array, guint32 N)
1415 struct tsn_sort *help=NULL;
1419 v = ((struct tsn_sort*)(g_ptr_array_index(array,i)))->tsnumber;
1421 while (j>=1 && ((struct tsn_sort*)(g_ptr_array_index(array, j-1)))->tsnumber > v)
1423 help=(struct tsn_sort *)g_ptr_array_index(array, j);
1424 g_ptr_array_index(array, j)=g_ptr_array_index(array, j-1);
1425 g_ptr_array_index(array, j-1)=help;
1428 ((struct tsn_sort*)(g_ptr_array_index(array, j)))->tsnumber=v;
1432 static void set_arw_offsets(struct sctp_udata *u_data)
1434 GPtrArray *s_array=NULL, *t_array=NULL;
1437 if (u_data->dir==1 && u_data->assoc->n_sack_chunks_ep1>0)
1439 s_array=u_data->assoc->sort_sack1;
1440 t_array=u_data->assoc->sort_tsn1;
1441 insertion(s_array,u_data->assoc->n_sack_chunks_ep1);
1443 for (i=0; i<u_data->assoc->n_sack_chunks_ep1; i++)
1445 while (((struct tsn_sort*)(g_ptr_array_index(s_array, i)))->tsnumber > ((struct tsn_sort*)(g_ptr_array_index(t_array, j)))->tsnumber)
1449 ((struct tsn_sort*)(g_ptr_array_index(s_array,i)))->offset = ((struct tsn_sort*)(g_ptr_array_index(t_array, j)))->offset
1450 + ((struct tsn_sort*)(g_ptr_array_index(t_array, j)))->length;
1453 u_data->assoc->sort_sack1=s_array;
1456 if (u_data->dir==2 && u_data->assoc->n_sack_chunks_ep2>0)
1458 s_array=u_data->assoc->sort_sack2;
1459 t_array=u_data->assoc->sort_tsn2;
1460 insertion(s_array,u_data->assoc->n_sack_chunks_ep2);
1462 for (i=0; i<u_data->assoc->n_sack_chunks_ep2; i++)
1464 while (((struct tsn_sort*)(g_ptr_array_index(s_array, i)))->tsnumber > ((struct tsn_sort*)(g_ptr_array_index(t_array,j)))->tsnumber)
1468 ((struct tsn_sort*)(g_ptr_array_index(s_array, i)))->offset = ((struct tsn_sort*)(g_ptr_array_index(t_array, j)))->offset
1469 + ((struct tsn_sort*)(g_ptr_array_index(t_array, j)))->length;
1471 u_data->assoc->sort_sack2=s_array;
1475 static void compute_offsets(struct sctp_udata *u_data)
1477 struct tsn_sort t_sort;
1478 GPtrArray *array=NULL;
1483 if (u_data->dir==1 && u_data->assoc->n_array_tsn1>0)
1485 array=u_data->assoc->sort_tsn1;
1486 insertion(array,u_data->assoc->n_array_tsn1);
1488 for (i=0; i<u_data->assoc->n_array_tsn1; i++)
1490 ((struct tsn_sort*)(g_ptr_array_index(array, i)))->offset=sum;
1491 t_sort.tsnumber=((struct tsn_sort*)(g_ptr_array_index(array, i)))->tsnumber;
1492 if (t_sort.tsnumber>tsntmp)
1493 sum+=((struct tsn_sort*)(g_ptr_array_index(array, i)))->length;
1494 tsntmp=t_sort.tsnumber;
1496 u_data->assoc->max_bytes1= ((struct tsn_sort*)(g_ptr_array_index(array, i-1)))->offset + ((struct tsn_sort*)(g_ptr_array_index(array, i-1)))->length;
1497 u_data->assoc->sort_tsn1=array;
1499 if (u_data->dir==2 && u_data->assoc->n_array_tsn2>0)
1502 array=u_data->assoc->sort_tsn2;
1503 insertion(array,u_data->assoc->n_array_tsn2);
1505 for (i=0; i<u_data->assoc->n_array_tsn2; i++)
1507 ((struct tsn_sort*)(g_ptr_array_index(array,i)))->offset=sum;
1508 t_sort.tsnumber=((struct tsn_sort*)(g_ptr_array_index(array, i)))->tsnumber;
1509 if (t_sort.tsnumber>tsntmp)
1510 sum+=((struct tsn_sort*)(g_ptr_array_index(array, i)))->length;
1511 tsntmp=t_sort.tsnumber;
1514 u_data->assoc->max_bytes2= ((struct tsn_sort*)(g_ptr_array_index(array, u_data->assoc->n_data_chunks_ep2-1)))->offset + ((struct tsn_sort*)(g_ptr_array_index(array, u_data->assoc->n_data_chunks_ep2-1)))->length;
1515 u_data->assoc->sort_tsn2=array;
1519 void create_byte_graph(guint16 dir, struct sctp_analyse* userdata)
1521 struct sctp_udata *u_data;
1523 u_data=(struct sctp_udata *)g_malloc(sizeof(struct sctp_udata));
1524 u_data->assoc=(sctp_assoc_info_t *)g_malloc(sizeof(sctp_assoc_info_t));
1525 u_data->assoc=userdata->assoc;
1528 u_data->parent = userdata;
1529 if ((u_data->dir==1 && (u_data->assoc->n_array_tsn1==0))|| (u_data->dir==2 && (u_data->assoc->n_array_tsn2==0)))
1530 simple_dialog(ESD_TYPE_INFO, ESD_BTN_OK, "No Data Chunks sent");
1533 set_child(u_data, u_data->parent);
1534 increase_childcount(u_data->parent);
1535 compute_offsets(u_data);
1536 set_arw_offsets(u_data);
1537 gtk_sctpgraph_init(u_data);