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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
34 #include "epan/filesystem.h"
35 #include <epan/strutil.h>
37 #include "../globals.h"
38 #include "../ui_util.h"
39 #include "../simple_dialog.h"
41 #include "gtk/dlg_utils.h"
43 #include "gtk/sctp_stat.h"
45 #include "gtk/old-gtk-compat.h"
47 #define DEFAULT_PIXELS_PER_TICK 2
48 #define MAX_PIXELS_PER_TICK 4
49 #define AUTO_MAX_YSCALE 0
50 #define MAX_TICK_VALUES 5
51 #define DEFAULT_TICK_VALUE 3
53 #define MAX_COUNT_TYPES 3
55 #define COUNT_TYPE_FRAMES 0
56 #define COUNT_TYPE_BYTES 1
57 #define COUNT_TYPE_ADVANCED 2
59 #define LEFT_BORDER 80
60 #define RIGHT_BORDER 20
62 #define BOTTOM_BORDER 50
64 #define SUB_32(a, b) a-b
72 struct data_chunk_header {
82 struct init_chunk_header {
93 struct sack_chunk_header {
109 static gboolean label_set = FALSE;
110 static guint32 max_tsn=0, min_tsn=0;
113 static void sctp_graph_set_title(struct sctp_udata *u_data);
114 static void create_draw_area(GtkWidget *box, struct sctp_udata *u_data);
115 static GtkWidget *zoomout_bt;
117 static void draw_sack_graph(struct sctp_udata *u_data)
119 GdkColor red_color = {0, 65535, 0, 0};
120 GdkColor green_color = {0, 0, 65535, 0};
122 GPtrArray *array = NULL;
123 guint32 i, size = 0, start=0, end;
124 gboolean more = FALSE;
128 if (u_data->dir == 1)
130 array = u_data->assoc->sort_sack1;
131 size=u_data->assoc->n_sack_chunks_ep1;
132 if (u_data->io->tmp == FALSE)
135 max_tsn = u_data->assoc->max_bytes1;
139 min_tsn = u_data->io->tmp_min_tsn1;
140 max_tsn = u_data->io->tmp_max_tsn1;
143 else if (u_data->dir == 2)
145 array = u_data->assoc->sort_sack2;
146 size = u_data->assoc->n_sack_chunks_ep2;
147 if (u_data->io->tmp == FALSE)
150 max_tsn = u_data->assoc->max_bytes2;
154 min_tsn = u_data->io->tmp_min_tsn2;
155 max_tsn = u_data->io->tmp_max_tsn2;
159 width = u_data->io->max_x - u_data->io->min_x;
161 for (i=0; i<size; i++)
163 if (u_data->io->uoff)
164 diff = (gint)((struct tsn_sort*)(g_ptr_array_index(array, i)))->secs - u_data->io->min_x;
166 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;
167 end = start + ((struct tsn_sort*)(g_ptr_array_index(array, i)))->length;
174 if (start >= min_tsn && diff > 0 && diff <= width)
176 #if GTK_CHECK_VERSION(2,22,0)
177 cr = cairo_create (u_data->io->surface);
179 cr = gdk_cairo_create (u_data->io->pixmap);
181 gdk_cairo_set_source_color (cr, &red_color);
182 cairo_set_line_width (cr, 1.0);
184 LEFT_BORDER+u_data->io->offset+u_data->io->x_interval*diff+0.5,
185 u_data->io->surface_height-BOTTOM_BORDER-u_data->io->offset-((SUB_32(start,min_tsn))*u_data->io->y_interval)+0.5);
187 LEFT_BORDER+u_data->io->offset+u_data->io->x_interval*diff+0.5,
188 u_data->io->surface_height-BOTTOM_BORDER-u_data->io->offset-((SUB_32(end,min_tsn))*u_data->io->y_interval)+0.5);
193 #if GTK_CHECK_VERSION(2,22,0)
194 cr = cairo_create (u_data->io->surface);
196 cr = gdk_cairo_create (u_data->io->pixmap);
198 gdk_cairo_set_source_color (cr, &green_color);
199 cairo_set_line_width (cr, 1.0);
201 LEFT_BORDER+u_data->io->offset+u_data->io->x_interval*diff+0.5,
202 u_data->io->surface_height-BOTTOM_BORDER-u_data->io->offset-((SUB_32(end,min_tsn))*u_data->io->y_interval)+0.5);
204 LEFT_BORDER+u_data->io->offset+u_data->io->x_interval*diff,
205 u_data->io->surface_height-BOTTOM_BORDER-u_data->io->offset-((SUB_32(end+10,min_tsn))*u_data->io->y_interval)+0.5);
216 static void draw_tsn_graph(struct sctp_udata *u_data)
218 GPtrArray *array = NULL;
219 guint32 i, size = 0, start, end;
223 if (u_data->dir == 1)
225 array = u_data->assoc->sort_tsn1;
226 size = u_data->assoc->n_data_chunks_ep1;
227 if (u_data->io->tmp == FALSE)
230 max_tsn = u_data->assoc->max_bytes1;
234 min_tsn = u_data->io->tmp_min_tsn1;
235 max_tsn = u_data->io->tmp_max_tsn1;
238 else if (u_data->dir == 2)
240 array = u_data->assoc->sort_tsn2;
241 size = u_data->assoc->n_data_chunks_ep2;
242 if (u_data->io->tmp == FALSE)
245 max_tsn = u_data->assoc->max_bytes2;
249 min_tsn = u_data->io->tmp_min_tsn2;
250 max_tsn = u_data->io->tmp_max_tsn2;
253 width = u_data->io->max_x - u_data->io->min_x;
255 for (i=0; i<size; i++)
257 if (u_data->io->uoff)
258 diff = (gint)((struct tsn_sort*)(g_ptr_array_index(array, i)))->secs -u_data->io->min_x;
260 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;
261 start = ((struct tsn_sort*)(g_ptr_array_index(array, i)))->offset;
262 end = start + ((struct tsn_sort*)(g_ptr_array_index(array, i)))->length;
263 if (start >= min_tsn && diff > 0 && diff <= width){
264 #if GTK_CHECK_VERSION(2,22,0)
265 cr = cairo_create (u_data->io->surface);
267 cr = gdk_cairo_create (u_data->io->pixmap);
269 cairo_set_line_width (cr, 1.0);
271 (LEFT_BORDER+u_data->io->offset+u_data->io->x_interval*diff)+0.5,
272 (u_data->io->surface_height-BOTTOM_BORDER-u_data->io->offset-((SUB_32(start,min_tsn))*u_data->io->y_interval))+0.5);
274 (LEFT_BORDER+u_data->io->offset+u_data->io->x_interval*diff)+0.5,
275 (u_data->io->surface_height-BOTTOM_BORDER-u_data->io->offset-((SUB_32(end,min_tsn))*u_data->io->y_interval))+0.5);
284 static void sctp_graph_draw(struct sctp_udata *u_data)
287 guint32 distance=5, i, e, sec, w, start, a, j, b;
288 gint label_width, label_height;
289 char label_string[15];
291 gboolean write_label = FALSE;
293 GtkAllocation widget_alloc;
296 if (u_data->io->x1_tmp_sec == 0 && u_data->io->x1_tmp_usec == 0)
297 u_data->io->offset = 0;
299 u_data->io->offset = 5;
301 if (u_data->io->x2_tmp_sec - u_data->io->x1_tmp_sec > 1500)
303 u_data->io->min_x=u_data->io->x1_tmp_sec;
304 u_data->io->max_x=u_data->io->x2_tmp_sec;
305 u_data->io->uoff = TRUE;
309 u_data->io->min_x=((guint32) (u_data->io->x1_tmp_sec*1000000.0))+u_data->io->x1_tmp_usec;
310 u_data->io->max_x=((guint32) (u_data->io->x2_tmp_sec*1000000.0))+u_data->io->x2_tmp_usec;
311 u_data->io->uoff = FALSE;
314 u_data->io->tmp_width = u_data->io->max_x - u_data->io->min_x;
316 if (u_data->dir == 1)
318 if (u_data->io->tmp == FALSE)
320 if (u_data->assoc->sort_tsn1 != NULL)
321 u_data->io->max_y = u_data->io->tmp_max_tsn1 - u_data->io->tmp_min_tsn1;
323 u_data->io->max_y = 0;
324 u_data->io->min_y = 0;
328 u_data->io->max_y = u_data->io->tmp_max_tsn1;
329 u_data->io->min_y = u_data->io->tmp_min_tsn1;
332 else if (u_data->dir == 2)
334 if (u_data->io->tmp == FALSE)
336 if (u_data->assoc->tsn2 != NULL)
337 u_data->io->max_y = u_data->io->tmp_max_tsn2 - u_data->io->tmp_min_tsn2;
339 u_data->io->max_y = 0;
340 u_data->io->min_y = 0;
344 u_data->io->max_y = u_data->io->tmp_max_tsn2;
345 u_data->io->min_y = u_data->io->tmp_min_tsn2;
349 #if GTK_CHECK_VERSION(2,22,0)
350 cr = cairo_create (u_data->io->surface);
352 cr = gdk_cairo_create (u_data->io->pixmap);
354 cairo_set_source_rgb (cr, 1, 1, 1);
355 gtk_widget_get_allocation(u_data->io->draw_area, &widget_alloc);
360 widget_alloc.height);
366 #if GTK_CHECK_VERSION(2,22,0)
367 cr = cairo_create (u_data->io->surface);
369 cr = gdk_cairo_create (u_data->io->pixmap);
371 cairo_set_line_width (cr, 1.0);
372 cairo_move_to(cr, LEFT_BORDER+u_data->io->offset+0.5, u_data->io->surface_height - BOTTOM_BORDER+0.5);
373 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);
375 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);
376 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);
378 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);
379 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);
383 u_data->io->axis_width = u_data->io->surface_width - LEFT_BORDER - RIGHT_BORDER - u_data->io->offset;
385 if(u_data->io->tmp_width>0){
386 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*/
388 u_data->io->x_interval = (float)(u_data->io->axis_width);
392 if (u_data->io->x_interval < 1)
394 dis = 1 / u_data->io->x_interval;
401 for (i=0; i<=e+1; i++)
407 g_snprintf(label_string, sizeof(label_string), "%d", 0);
408 memcpy(label_string,(gchar *)g_locale_to_utf8(label_string, -1 , NULL, NULL, NULL), 15);
409 layout = gtk_widget_create_pango_layout(u_data->io->draw_area, label_string);
410 pango_layout_get_pixel_size(layout, &label_width, &label_height);
412 if (u_data->io->x1_tmp_usec == 0)
413 sec = u_data->io->x1_tmp_sec;
415 sec = u_data->io->x1_tmp_sec+1;
417 if (u_data->io->offset != 0)
419 g_snprintf(label_string, sizeof(label_string), "%u", u_data->io->x1_tmp_sec);
420 memcpy(label_string,(gchar *)g_locale_to_utf8(label_string, -1 , NULL, NULL, NULL), sizeof(label_string));
421 pango_layout_set_text(layout, label_string, -1);
422 pango_layout_get_pixel_size(layout, &lwidth, NULL);
424 #if GTK_CHECK_VERSION(2,22,0)
425 cr = cairo_create (u_data->io->surface);
427 cr = gdk_cairo_create (u_data->io->pixmap);
429 cairo_move_to (cr, LEFT_BORDER - 25, u_data->io->surface_height - BOTTOM_BORDER + 20);
430 pango_cairo_show_layout (cr, layout);
435 w = (guint32)(500 / (guint32)(distance * u_data->io->x_interval));
438 if (w == 4 || w==3 || w==2)
442 b = (guint32)((u_data->io->min_x/100000))%10; /* start for labels*/
450 if (!u_data->io->uoff)
454 start=u_data->io->min_x/1000000*1000000;
460 start=u_data->io->min_x/100000;
464 b = (guint32)((start/100000))%10;
469 start = u_data->io->min_x;
476 for (i=start, j=b; i<=u_data->io->max_x; i+=a, j++)
478 if (!u_data->io->uoff)
479 if (i >= u_data->io->min_x && i % 1000000 != 0)
482 g_snprintf(label_string, sizeof(label_string), "%d", i%1000000);
488 memcpy(label_string,(gchar *)g_locale_to_utf8(label_string, -1 , NULL, NULL, NULL), sizeof(label_string));
489 pango_layout_set_text(layout, label_string, -1);
490 pango_layout_get_pixel_size(layout, &lwidth, NULL);
491 #if GTK_CHECK_VERSION(2,22,0)
492 cr = cairo_create (u_data->io->surface);
494 cr = gdk_cairo_create (u_data->io->pixmap);
497 LEFT_BORDER + u_data->io->offset + (i - u_data->io->min_x) * u_data->io->x_interval - lwidth / 2,
498 u_data->io->surface_height - BOTTOM_BORDER + 10);
499 pango_cairo_show_layout (cr, layout);
503 #if GTK_CHECK_VERSION(2,22,0)
504 cr = cairo_create (u_data->io->surface);
506 cr = gdk_cairo_create (u_data->io->pixmap);
508 cairo_set_line_width (cr, 1.0);
510 LEFT_BORDER + u_data->io->offset + (i - u_data->io->min_x) * u_data->io->x_interval + 0.5,
511 u_data->io->surface_height - BOTTOM_BORDER + 0.5);
513 LEFT_BORDER + u_data->io->offset + (i - u_data->io->min_x) * u_data->io->x_interval + 0.5,
514 u_data->io->surface_height - BOTTOM_BORDER + length + 0.5);
519 if (!u_data->io->uoff)
521 if (i%1000000==0 && j%w==0)
537 #if GTK_CHECK_VERSION(2,22,0)
538 cr = cairo_create (u_data->io->surface);
540 cr = gdk_cairo_create (u_data->io->pixmap);
542 cairo_set_line_width (cr, 1.0);
544 LEFT_BORDER + u_data->io->offset + (i - u_data->io->min_x) * u_data->io->x_interval + 0.5,
545 u_data->io->surface_height - BOTTOM_BORDER + 0.5);
547 LEFT_BORDER + u_data->io->offset + (i - u_data->io->min_x) * u_data->io->x_interval + 0.5,
548 u_data->io->surface_height - BOTTOM_BORDER + 10 + 0.5);
552 g_snprintf(label_string, sizeof(label_string), "%d", sec);
553 memcpy(label_string,(gchar *)g_locale_to_utf8(label_string, -1 , NULL, NULL, NULL), sizeof(label_string));
554 pango_layout_set_text(layout, label_string, -1);
555 pango_layout_get_pixel_size(layout, &lwidth, NULL);
556 #if GTK_CHECK_VERSION(2,22,0)
557 cr = cairo_create (u_data->io->surface);
559 cr = gdk_cairo_create (u_data->io->pixmap);
562 (LEFT_BORDER + u_data->io->offset + (i - u_data->io->min_x) * u_data->io->x_interval-10),
563 u_data->io->surface_height - BOTTOM_BORDER + 20);
564 pango_cairo_show_layout (cr, layout);
572 g_strlcpy(label_string, "sec", sizeof(label_string));
574 memcpy(label_string,(gchar *)g_locale_to_utf8(label_string, -1 , NULL, NULL, NULL), sizeof(label_string));
575 pango_layout_set_text(layout, label_string, -1);
576 pango_layout_get_pixel_size(layout, &lwidth, NULL);
577 #if GTK_CHECK_VERSION(2,22,0)
578 cr = cairo_create (u_data->io->surface);
580 cr = gdk_cairo_create (u_data->io->pixmap);
583 u_data->io->surface_width - RIGHT_BORDER - 10,
584 u_data->io->surface_height - BOTTOM_BORDER + 30);
585 pango_cairo_show_layout (cr, layout);
592 #if GTK_CHECK_VERSION(2,22,0)
593 cr = cairo_create (u_data->io->surface);
595 cr = gdk_cairo_create (u_data->io->pixmap);
597 cairo_set_line_width (cr, 1.0);
598 cairo_move_to(cr, LEFT_BORDER + 0.5, TOP_BORDER - u_data->io->offset + 0.5);
599 cairo_line_to(cr, LEFT_BORDER + 0.5, u_data->io->surface_height - BOTTOM_BORDER - u_data->io->offset + 0.5);
601 cairo_move_to(cr, LEFT_BORDER + 0.5, TOP_BORDER - u_data->io->offset + 0.5);
602 cairo_line_to(cr, LEFT_BORDER - 5 + 0.5, TOP_BORDER - u_data->io->offset + 5 + 0.5);
604 cairo_move_to(cr, LEFT_BORDER + 0.5, TOP_BORDER - u_data->io->offset + 0.5);
605 cairo_line_to(cr, LEFT_BORDER +5 + 0.5, TOP_BORDER - u_data->io->offset + 5 + 0.5);
609 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));
612 if (u_data->io->y_interval < 1)
614 dis = 1 / u_data->io->y_interval;
622 distance = distance * 10;
624 else if (u_data->io->y_interval<2)
627 if (u_data->io->max_y > 0)
629 for (i=u_data->io->min_y/distance*distance; i<=u_data->io->max_y; i+=distance/5)
631 if (i >= u_data->io->min_y)
634 g_snprintf(label_string, sizeof(label_string), "%d", i);
636 if (i%distance == 0 || (distance <= 5 && u_data->io->y_interval > 10))
640 memcpy(label_string,(gchar *)g_locale_to_utf8(label_string, -1 , NULL, NULL, NULL), sizeof(label_string));
641 pango_layout_set_text(layout, label_string, -1);
642 pango_layout_get_pixel_size(layout, &lwidth, NULL);
643 #if GTK_CHECK_VERSION(2,22,0)
644 cr = cairo_create (u_data->io->surface);
646 cr = gdk_cairo_create (u_data->io->pixmap);
649 LEFT_BORDER - length - lwidth - 5,
650 u_data->io->surface_height - BOTTOM_BORDER - u_data->io->offset - (i - u_data->io->min_y) * u_data->io->y_interval - 3);
651 pango_cairo_show_layout (cr, layout);
655 #if GTK_CHECK_VERSION(2,22,0)
656 cr = cairo_create (u_data->io->surface);
658 cr = gdk_cairo_create (u_data->io->pixmap);
660 cairo_set_line_width (cr, 1.0);
662 LEFT_BORDER - length + 0.5,
663 u_data->io->surface_height - BOTTOM_BORDER - u_data->io->offset - (i - u_data->io->min_y) * u_data->io->y_interval + 0.5);
666 u_data->io->surface_height - BOTTOM_BORDER - u_data->io->offset - (i - u_data->io->min_y) * u_data->io->y_interval + 0.5);
673 simple_dialog(ESD_TYPE_INFO, ESD_BTN_OK, "No Data Chunks sent");
675 g_object_unref(G_OBJECT(layout));
679 static void sctp_graph_redraw(struct sctp_udata *u_data)
682 GtkAllocation widget_alloc;
685 u_data->io->needs_redraw = TRUE;
687 sctp_graph_draw(u_data);
688 switch (u_data->io->graph_type)
691 draw_sack_graph(u_data);
692 draw_tsn_graph(u_data);
695 draw_tsn_graph(u_data);
698 draw_sack_graph(u_data);
702 ios=(sctp_graph_t *)g_object_get_data(G_OBJECT(u_data->io->draw_area), "sctp_graph_t");
703 g_assert(ios != NULL);
705 cr = gdk_cairo_create (gtk_widget_get_window(u_data->io->draw_area));
707 #if GTK_CHECK_VERSION(2,22,0)
708 cairo_set_source_surface (cr, ios->surface, 0, 0);
710 gdk_cairo_set_source_pixmap (cr, ios->pixmap, 0, 0);
712 gtk_widget_get_allocation(u_data->io->draw_area, &widget_alloc);
713 cairo_rectangle (cr, 0, 0, widget_alloc.width, widget_alloc.height);
720 static void on_sack_bt(GtkWidget *widget _U_, struct sctp_udata *u_data)
722 u_data = (struct sctp_udata *) u_data;
723 u_data->io->graph_type = 2;
724 sctp_graph_redraw(u_data);
727 static void on_tsn_bt(GtkWidget *widget _U_, struct sctp_udata *u_data)
729 u_data->io->graph_type = 1;
730 sctp_graph_redraw(u_data);
733 static void on_both_bt(GtkWidget *widget _U_, struct sctp_udata *u_data)
735 u_data->io->graph_type = 0;
736 sctp_graph_redraw(u_data);
740 sctp_graph_close_cb(GtkWidget* widget _U_, gpointer u_data)
742 struct sctp_udata *udata;
744 udata = (struct sctp_udata *)u_data;
745 gtk_grab_remove(GTK_WIDGET(udata->io->window));
746 gtk_widget_destroy(GTK_WIDGET(udata->io->window));
752 on_configure_event(GtkWidget *widget, GdkEventConfigure *event _U_, gpointer user_data)
754 struct sctp_udata *u_data = user_data;
755 GtkAllocation widget_alloc;
758 g_assert(u_data->io != NULL);
760 #if GTK_CHECK_VERSION(2,22,0)
761 if(u_data->io->surface){
762 cairo_surface_destroy (u_data->io->surface);
763 u_data->io->surface=NULL;
765 gtk_widget_get_allocation(widget, &widget_alloc);
766 u_data->io->surface = gdk_window_create_similar_surface (gtk_widget_get_window(widget),
769 widget_alloc.height);
771 if(u_data->io->pixmap){
772 g_object_unref(u_data->io->pixmap);
773 u_data->io->pixmap = NULL;
775 gtk_widget_get_allocation(widget, &widget_alloc);
776 u_data->io->pixmap = gdk_pixmap_new(gtk_widget_get_window(widget),
781 u_data->io->surface_width = widget_alloc.width;
782 u_data->io->surface_height = widget_alloc.height;
784 #if GTK_CHECK_VERSION(2,22,0)
785 cr = cairo_create (u_data->io->surface);
787 cr = gdk_cairo_create (u_data->io->pixmap);
789 cairo_rectangle (cr, 0, 0, widget_alloc.width, widget_alloc.height);
790 cairo_set_source_rgb (cr, 1, 1, 1);
794 sctp_graph_redraw(u_data);
798 #if GTK_CHECK_VERSION(3,0,0)
800 on_draw_area_draw_event(GtkWidget *widget, cairo_t *cr, gpointer user_data)
802 sctp_graph_t *ios = user_data;
803 GtkAllocation allocation;
805 gtk_widget_get_allocation (widget, &allocation);
806 cairo_set_source_surface (cr, ios->surface, 0, 0);
807 cairo_rectangle (cr, 0, 0, allocation.width, allocation.width);
814 on_expose_event(GtkWidget *widget, GdkEventExpose *event, gpointer user_data)
816 sctp_graph_t *ios = user_data;
819 g_assert(ios != NULL);
821 cr = gdk_cairo_create (gtk_widget_get_window(widget));
823 #if GTK_CHECK_VERSION(2,22,0)
824 cairo_set_source_surface (cr, ios->surface, 0, 0);
826 gdk_cairo_set_source_pixmap (cr, ios->pixmap, 0, 0);
828 cairo_rectangle (cr, event->area.x, event->area.y, event->area.width, event->area.height);
838 on_zoomin_bt (GtkWidget *widget _U_, struct sctp_udata *u_data)
840 sctp_min_max_t *tmp_minmax;
842 if (u_data->io->rectangle==TRUE)
844 tmp_minmax = g_malloc(sizeof(sctp_min_max_t));
846 u_data->io->tmp_min_tsn1=u_data->io->y1_tmp+u_data->io->min_y;
847 u_data->io->tmp_max_tsn1=u_data->io->y2_tmp+1+u_data->io->min_y;
849 u_data->io->tmp_min_tsn2=u_data->io->tmp_min_tsn1;
850 u_data->io->tmp_max_tsn2=u_data->io->tmp_max_tsn1;
851 tmp_minmax->tmp_min_secs=u_data->io->x1_tmp_sec;
852 tmp_minmax->tmp_min_usecs= u_data->io->x1_tmp_usec;
853 tmp_minmax->tmp_max_secs= u_data->io->x2_tmp_sec;
854 tmp_minmax->tmp_max_usecs= u_data->io->x2_tmp_usec;
855 tmp_minmax->tmp_min_tsn1=u_data->io->tmp_min_tsn1;
856 tmp_minmax->tmp_max_tsn1=u_data->io->tmp_max_tsn1;
857 tmp_minmax->tmp_min_tsn2=u_data->io->tmp_min_tsn2;
858 tmp_minmax->tmp_max_tsn2=u_data->io->tmp_max_tsn2;
859 u_data->assoc->min_max = g_slist_prepend(u_data->assoc->min_max, tmp_minmax);
860 u_data->io->length = g_slist_length(u_data->assoc->min_max);
861 u_data->io->tmp=TRUE;
862 u_data->io->rectangle=FALSE;
863 gtk_widget_set_sensitive(zoomout_bt, TRUE);
864 sctp_graph_redraw(u_data);
868 simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK, "Please draw a rectangle around the area you want to zoom in!");
873 zoomin_bt_fcn (struct sctp_udata *u_data)
875 sctp_min_max_t *tmp_minmax;
877 tmp_minmax = g_malloc(sizeof(sctp_min_max_t));
879 u_data->io->tmp_min_tsn1=u_data->io->y1_tmp+u_data->io->min_y;
880 u_data->io->tmp_max_tsn1=u_data->io->y2_tmp+1+u_data->io->min_y;
882 u_data->io->tmp_min_tsn2=u_data->io->tmp_min_tsn1;
883 u_data->io->tmp_max_tsn2=u_data->io->tmp_max_tsn1;
884 tmp_minmax->tmp_min_secs=u_data->io->x1_tmp_sec;
885 tmp_minmax->tmp_min_usecs=u_data->io->x1_tmp_usec;
886 tmp_minmax->tmp_max_secs=u_data->io->x2_tmp_sec;
887 tmp_minmax->tmp_max_usecs=u_data->io->x2_tmp_usec;
888 tmp_minmax->tmp_min_tsn1=u_data->io->tmp_min_tsn1;
889 tmp_minmax->tmp_max_tsn1=u_data->io->tmp_max_tsn1;
890 tmp_minmax->tmp_min_tsn2=u_data->io->tmp_min_tsn2;
891 tmp_minmax->tmp_max_tsn2=u_data->io->tmp_max_tsn2;
892 u_data->assoc->min_max = g_slist_prepend(u_data->assoc->min_max, tmp_minmax);
893 u_data->io->length = g_slist_length(u_data->assoc->min_max);
894 u_data->io->tmp=TRUE;
895 u_data->io->rectangle=FALSE;
896 gtk_widget_set_sensitive(zoomout_bt, TRUE);
897 sctp_graph_redraw(u_data);
901 on_zoomout_bt (GtkWidget *widget _U_, struct sctp_udata *u_data)
903 sctp_min_max_t *tmp_minmax, *mm;
906 l = g_slist_length(u_data->assoc->min_max);
908 if (u_data->assoc->min_max!=NULL)
910 mm=(sctp_min_max_t *)((u_data->assoc->min_max)->data);
911 u_data->assoc->min_max=g_slist_remove(u_data->assoc->min_max, mm);
916 tmp_minmax = (sctp_min_max_t *)u_data->assoc->min_max->data;
917 u_data->io->x1_tmp_sec=tmp_minmax->tmp_min_secs;
918 u_data->io->x1_tmp_usec=tmp_minmax->tmp_min_usecs;
919 u_data->io->x2_tmp_sec=tmp_minmax->tmp_max_secs;
920 u_data->io->x2_tmp_usec=tmp_minmax->tmp_max_usecs;
921 u_data->io->tmp_min_tsn1=tmp_minmax->tmp_min_tsn1;
922 u_data->io->tmp_max_tsn1=tmp_minmax->tmp_max_tsn1;
923 u_data->io->tmp_min_tsn2=tmp_minmax->tmp_min_tsn2;
924 u_data->io->tmp_max_tsn2=tmp_minmax->tmp_max_tsn2;
925 u_data->io->tmp=TRUE;
929 u_data->io->x1_tmp_sec=u_data->assoc->min_secs;
930 u_data->io->x1_tmp_usec=u_data->assoc->min_usecs;
931 u_data->io->x2_tmp_sec=u_data->assoc->max_secs;
932 u_data->io->x2_tmp_usec=u_data->assoc->max_usecs;
933 u_data->io->tmp_min_tsn1=0;
934 u_data->io->tmp_max_tsn1=u_data->assoc->max_bytes1;
935 u_data->io->tmp_min_tsn2=0;
936 u_data->io->tmp_max_tsn2=u_data->assoc->max_bytes2;
937 u_data->io->tmp=FALSE;
942 u_data->io->x1_tmp_sec=u_data->assoc->min_secs;
943 u_data->io->x1_tmp_usec=u_data->assoc->min_usecs;
944 u_data->io->x2_tmp_sec=u_data->assoc->max_secs;
945 u_data->io->x2_tmp_usec=u_data->assoc->max_usecs;
946 u_data->io->tmp_min_tsn1=0;
947 u_data->io->tmp_max_tsn1=u_data->assoc->max_bytes1;
948 u_data->io->tmp_min_tsn2=0;
949 u_data->io->tmp_max_tsn2=u_data->assoc->max_bytes2;
950 u_data->io->tmp=FALSE;
952 if (g_slist_length(u_data->assoc->min_max)==1)
953 gtk_widget_set_sensitive(zoomout_bt, FALSE);
954 sctp_graph_redraw(u_data);
959 on_button_press_event (GtkWidget *widget _U_, GdkEventButton *event, gpointer user_data)
961 struct sctp_udata *u_data = user_data;
965 if (u_data->io->rectangle==TRUE)
967 #if GTK_CHECK_VERSION(2,22,0)
968 cr = cairo_create (u_data->io->surface);
970 cr = gdk_cairo_create (u_data->io->pixmap);
973 floor(MIN(u_data->io->x_old,u_data->io->x_new)),
974 floor(MIN(u_data->io->y_old,u_data->io->y_new)),
975 abs((long)(u_data->io->x_new-u_data->io->x_old)),
976 abs((long)(u_data->io->y_new-u_data->io->y_old)));
977 cairo_set_source_rgb (cr, 1, 1, 1);
982 ios=(sctp_graph_t *)g_object_get_data(G_OBJECT(u_data->io->draw_area), "sctp_graph_t");
983 g_assert(ios != NULL);
985 cr = gdk_cairo_create (gtk_widget_get_window(u_data->io->draw_area));
987 #if GTK_CHECK_VERSION(2,22,0)
988 cairo_set_source_surface (cr, ios->surface, 0, 0);
990 gdk_cairo_set_source_pixmap (cr, ios->pixmap, 0, 0);
992 cairo_rectangle (cr, 0, 0, abs((long)(u_data->io->x_new-u_data->io->x_old)), abs((long)(u_data->io->y_new-u_data->io->y_old)));
997 sctp_graph_redraw(u_data);
1000 u_data->io->x_old=event->x;
1001 u_data->io->y_old=event->y;
1002 if (u_data->io->y_old>u_data->io->surface_height-BOTTOM_BORDER-u_data->io->offset)
1003 u_data->io->y_old=u_data->io->surface_height-BOTTOM_BORDER-u_data->io->offset;
1004 if (u_data->io->x_old<LEFT_BORDER+u_data->io->offset)
1005 u_data->io->x_old=LEFT_BORDER+u_data->io->offset;
1006 u_data->io->rectangle=FALSE;
1013 on_button_release_event (GtkWidget *widget _U_, GdkEventButton *event, gpointer user_data)
1015 struct sctp_udata *u_data = user_data;
1017 guint32 helpx, helpy, x1_tmp, x2_tmp, y_value;
1018 gint label_width, label_height;
1019 gdouble x_value, position, tfirst;
1021 char label_string[30];
1022 GList *tsnlist=NULL;
1023 tsn_t *tsn, *tmptsn;
1024 PangoLayout *layout;
1025 GtkAllocation widget_alloc;
1028 g_snprintf(label_string, 15, "%d", 0);
1029 memcpy(label_string,(gchar *)g_locale_to_utf8(label_string, -1 , NULL, NULL, NULL), 15);
1030 layout = gtk_widget_create_pango_layout(u_data->io->draw_area, label_string);
1031 pango_layout_get_pixel_size(layout, &label_width, &label_height);
1033 if (event->y > u_data->io->surface_height-BOTTOM_BORDER-u_data->io->offset)
1034 event->y = u_data->io->surface_height-BOTTOM_BORDER-u_data->io->offset;
1035 if (event->x < LEFT_BORDER+u_data->io->offset)
1036 event->x = LEFT_BORDER+u_data->io->offset;
1038 if (abs((long)(event->x-u_data->io->x_old))>10 || abs((long)(event->y-u_data->io->y_old))>10)
1040 u_data->io->rect_x_min = (guint32) floor(MIN(u_data->io->x_old,event->x));
1041 u_data->io->rect_x_max = (guint32) ceil(MAX(u_data->io->x_old,event->x));
1042 u_data->io->rect_y_min = (guint32) floor(MIN(u_data->io->y_old,event->y));
1043 u_data->io->rect_y_max = (guint32) ceil(MAX(u_data->io->y_old,event->y));
1045 #if GTK_CHECK_VERSION(2,22,0)
1046 cr = cairo_create (u_data->io->surface);
1048 cr = gdk_cairo_create (u_data->io->pixmap);
1050 cairo_rectangle (cr,
1051 u_data->io->rect_x_min+0.5,
1052 u_data->io->rect_y_min+0.5,
1053 u_data->io->rect_x_max - u_data->io->rect_x_min,
1054 u_data->io->rect_y_max - u_data->io->rect_y_min);
1055 cairo_set_line_width (cr, 1.0);
1059 ios=(sctp_graph_t *)g_object_get_data(G_OBJECT(u_data->io->draw_area), "sctp_graph_t");
1060 g_assert(ios != NULL);
1062 cr = gdk_cairo_create (gtk_widget_get_window(u_data->io->draw_area));
1064 #if GTK_CHECK_VERSION(2,22,0)
1065 cairo_set_source_surface (cr, ios->surface, 0, 0);
1067 gdk_cairo_set_source_pixmap (cr, ios->pixmap, 0, 0);
1069 gtk_widget_get_allocation(u_data->io->draw_area, &widget_alloc);
1070 cairo_rectangle (cr, 0, 0, widget_alloc.width, widget_alloc.height);
1075 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));
1076 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));
1077 helpx=MIN(x1_tmp, x2_tmp);
1083 if (u_data->io->uoff)
1085 if (x2_tmp - x1_tmp <= 1500)
1086 u_data->io->uoff = FALSE;
1087 u_data->io->x1_tmp_sec=(guint32)x1_tmp;
1088 u_data->io->x1_tmp_usec=0;
1089 u_data->io->x2_tmp_sec=(guint32)x2_tmp;
1090 u_data->io->x2_tmp_usec=0;
1094 u_data->io->x1_tmp_sec=(guint32)x1_tmp/1000000;
1095 u_data->io->x1_tmp_usec=x1_tmp%1000000;
1096 u_data->io->x2_tmp_sec=(guint32)x2_tmp/1000000;
1097 u_data->io->x2_tmp_usec=x2_tmp%1000000;
1099 u_data->io->x1_akt_sec = u_data->io->x1_tmp_sec;
1100 u_data->io->x1_akt_usec = u_data->io->x1_tmp_usec;
1101 u_data->io->x2_akt_sec = u_data->io->x2_tmp_sec;
1102 u_data->io->x2_akt_usec = u_data->io->x2_tmp_usec;
1104 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);
1105 u_data->io->y2_tmp=(guint32)((u_data->io->surface_height-BOTTOM_BORDER-u_data->io->offset-event->y)/u_data->io->y_interval);
1106 helpy = MIN(u_data->io->y1_tmp, u_data->io->y2_tmp);
1107 u_data->io->y2_tmp = MAX(u_data->io->y1_tmp, u_data->io->y2_tmp);
1108 u_data->io->y1_tmp = helpy;
1109 u_data->io->x_new=event->x;
1110 u_data->io->y_new=event->y;
1111 u_data->io->rectangle=TRUE;
1112 u_data->io->rectangle_present=TRUE;
1116 if (u_data->io->rectangle_present==TRUE)
1118 u_data->io->rectangle_present=FALSE;
1119 if (event->x >= u_data->io->rect_x_min && event->x <= u_data->io->rect_x_max &&
1120 event->y >= u_data->io->rect_y_min && event->y <= u_data->io->rect_y_max)
1121 zoomin_bt_fcn(u_data);
1124 u_data->io->x1_tmp_sec = u_data->io->x1_akt_sec;
1125 u_data->io->x1_tmp_usec = u_data->io->x1_akt_usec;
1126 u_data->io->x2_tmp_sec = u_data->io->x2_akt_sec;
1127 u_data->io->x2_tmp_usec = u_data->io->x2_akt_usec;
1128 sctp_graph_redraw(u_data);
1134 sctp_graph_redraw(u_data);
1138 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;
1139 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;
1141 if (u_data->dir == 1)
1142 tsnlist = g_list_last(u_data->assoc->tsn1);
1144 tsnlist = g_list_last(u_data->assoc->tsn2);
1146 tsn = (tsn_t*) (tsnlist->data);
1147 tmptsn =(tsn_t*)(tsnlist->data);
1148 tfirst = tsn->secs + tsn->usecs/1000000.0;
1152 tsnlist = g_list_previous(tsnlist);
1153 tsn = (tsn_t*) (tsnlist->data);
1154 if (tsn->secs+tsn->usecs/1000000.0<x_value)
1156 tfirst = tsn->secs+tsn->usecs/1000000.0;
1161 if ((tfirst+tsn->secs+tsn->usecs/1000000.0)/2.0<x_value)
1163 x_value = tsn->secs+tsn->usecs/1000000.0;
1167 x_value = tmptsn->secs+tmptsn->usecs/1000000.0;
1171 cf_goto_frame(&cfile, tmptsn->frame_number);
1172 g_snprintf(label_string, sizeof(label_string), "(%.6f, %u)", x_value, y_value);
1175 #if GTK_CHECK_VERSION(2,22,0)
1176 cr = cairo_create (u_data->io->surface);
1178 cr = gdk_cairo_create (u_data->io->pixmap);
1180 cairo_set_line_width (cr, 1.0);
1190 #if GTK_CHECK_VERSION(2,22,0)
1191 cr = cairo_create (u_data->io->surface);
1193 cr = gdk_cairo_create (u_data->io->pixmap);
1195 cairo_set_line_width (cr, 1.0);
1204 if (event->x+150>=u_data->io->surface_width)
1205 position = event->x - 150;
1207 position = event->x + 5;
1209 memcpy(label_string,(gchar *)g_locale_to_utf8(label_string, -1 , NULL, NULL, NULL), 15);
1210 pango_layout_set_text(layout, label_string, -1);
1211 pango_layout_get_pixel_size(layout, &lwidth, NULL);
1213 #if GTK_CHECK_VERSION(2,22,0)
1214 cr = cairo_create (u_data->io->surface);
1216 cr = gdk_cairo_create (u_data->io->pixmap);
1221 pango_cairo_show_layout (cr, layout);
1225 ios=(sctp_graph_t *)g_object_get_data(G_OBJECT(u_data->io->draw_area), "sctp_graph_t");
1226 g_assert(ios != NULL);
1228 cr = gdk_cairo_create (gtk_widget_get_window(u_data->io->draw_area));
1230 #if GTK_CHECK_VERSION(2,22,0)
1231 cairo_set_source_surface (cr, ios->surface, 0, 0);
1233 gdk_cairo_set_source_pixmap (cr, ios->pixmap, 0, 0);
1235 gtk_widget_get_allocation(u_data->io->draw_area, &widget_alloc);
1236 cairo_rectangle (cr, 0, 0, widget_alloc.width, widget_alloc.height);
1243 g_object_unref(G_OBJECT(layout));
1247 static void init_sctp_graph_window(struct sctp_udata *u_data)
1251 GtkWidget *bt_close, *sack_bt, *tsn_bt, *both_bt, *zoomin_bt;
1253 /* create the main window */
1255 u_data->io->window = dlg_window_new("SCTP Graphics"); /* transient_for top_level */
1256 gtk_window_set_destroy_with_parent (GTK_WINDOW(u_data->io->window), TRUE);
1258 vbox=gtk_vbox_new(FALSE, 0);
1259 gtk_container_add(GTK_CONTAINER(u_data->io->window), vbox);
1260 gtk_widget_show(vbox);
1262 create_draw_area(vbox, u_data);
1264 sctp_graph_set_title(u_data);
1266 hbox = gtk_hbutton_box_new();
1267 gtk_box_pack_start(GTK_BOX(vbox), hbox, FALSE, FALSE, 0);
1268 gtk_container_set_border_width(GTK_CONTAINER(hbox), 10);
1269 gtk_button_box_set_layout(GTK_BUTTON_BOX (hbox), GTK_BUTTONBOX_SPREAD);
1270 gtk_box_set_spacing(GTK_BOX (hbox), 0);
1271 gtk_box_set_child_packing(GTK_BOX(vbox), hbox, FALSE, FALSE, 0, GTK_PACK_START);
1272 gtk_widget_show(hbox);
1274 sack_bt = gtk_button_new_with_label ("Adv. Rec. Window");
1275 gtk_box_pack_start(GTK_BOX(hbox), sack_bt, FALSE, FALSE, 0);
1276 gtk_widget_show(sack_bt);
1278 g_signal_connect(sack_bt, "clicked", G_CALLBACK(on_sack_bt), u_data);
1280 tsn_bt = gtk_button_new_with_label ("Data bytes sent");
1281 gtk_box_pack_start(GTK_BOX(hbox), tsn_bt, FALSE, FALSE, 0);
1282 gtk_widget_show(tsn_bt);
1283 g_signal_connect(tsn_bt, "clicked", G_CALLBACK(on_tsn_bt), u_data);
1285 both_bt = gtk_button_new_with_label ("Show both");
1286 gtk_box_pack_start(GTK_BOX(hbox), both_bt, FALSE, FALSE, 0);
1287 gtk_widget_show(both_bt);
1288 g_signal_connect(both_bt, "clicked", G_CALLBACK(on_both_bt), u_data);
1290 zoomin_bt = gtk_button_new_with_label ("Zoom in");
1291 gtk_box_pack_start(GTK_BOX(hbox), zoomin_bt, FALSE, FALSE, 0);
1292 gtk_widget_show(zoomin_bt);
1293 g_signal_connect(zoomin_bt, "clicked", G_CALLBACK(on_zoomin_bt), u_data);
1294 gtk_widget_set_tooltip_text(zoomin_bt, "Zoom in the area you have selected");
1296 zoomout_bt = gtk_button_new_with_label ("Zoom out");
1297 gtk_box_pack_start(GTK_BOX(hbox), zoomout_bt, FALSE, FALSE, 0);
1298 gtk_widget_show(zoomout_bt);
1299 g_signal_connect(zoomout_bt, "clicked", G_CALLBACK(on_zoomout_bt), u_data);
1300 gtk_widget_set_tooltip_text(zoomout_bt, "Zoom out one step");
1301 gtk_widget_set_sensitive(zoomout_bt, FALSE);
1303 bt_close = gtk_button_new_from_stock(GTK_STOCK_CLOSE);
1304 gtk_box_pack_start(GTK_BOX(hbox), bt_close, FALSE, FALSE, 0);
1305 gtk_widget_show(bt_close);
1306 g_signal_connect(bt_close, "clicked", G_CALLBACK(sctp_graph_close_cb), u_data);
1308 g_signal_connect(u_data->io->draw_area,"button_press_event",G_CALLBACK(on_button_press_event), u_data);
1309 g_signal_connect(u_data->io->draw_area,"button_release_event",G_CALLBACK(on_button_release_event), u_data);
1310 gtk_widget_set_events(u_data->io->draw_area, GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK | GDK_EXPOSURE_MASK);
1311 /* dlg_set_cancel(u_data->io->window, bt_close); */
1313 gtk_widget_show(u_data->io->window);
1316 static void sctp_graph_set_title(struct sctp_udata *u_data)
1320 if(!u_data->io->window)
1324 title = g_strdup_printf("SCTP Data and Adv.Rcv.Window over Time: %s Port1 %u Port2 %u Endpoint %u",
1325 cf_get_display_name(&cfile), u_data->parent->assoc->port1, u_data->parent->assoc->port2, u_data->dir);
1326 gtk_window_set_title(GTK_WINDOW(u_data->io->window), title);
1332 gtk_sctpgraph_init(struct sctp_udata *u_data)
1335 sctp_min_max_t* tmp_minmax;
1337 io=g_malloc(sizeof(sctp_graph_t));
1338 io->needs_redraw=TRUE;
1339 io->x_interval=1000;
1342 #if GTK_CHECK_VERSION(2,22,0)
1347 io->surface_width=800;
1348 io->surface_height=600;
1353 u_data->io->x1_tmp_sec=u_data->assoc->min_secs;
1354 u_data->io->x1_tmp_usec=u_data->assoc->min_usecs;
1355 u_data->io->x2_tmp_sec=u_data->assoc->max_secs;
1356 u_data->io->x2_tmp_usec=u_data->assoc->max_usecs;
1357 u_data->io->tmp_min_tsn1=0;
1358 u_data->io->tmp_max_tsn1=u_data->assoc->max_bytes1;
1359 u_data->io->tmp_min_tsn2=0;
1360 u_data->io->tmp_max_tsn2=u_data->assoc->max_bytes2;
1361 u_data->io->tmp=FALSE;
1362 tmp_minmax = g_malloc(sizeof(sctp_min_max_t));
1363 tmp_minmax->tmp_min_secs = u_data->assoc->min_secs;
1364 tmp_minmax->tmp_min_usecs=u_data->assoc->min_usecs;
1365 tmp_minmax->tmp_max_secs=u_data->assoc->max_secs;
1366 tmp_minmax->tmp_max_usecs=u_data->assoc->max_usecs;
1367 tmp_minmax->tmp_min_tsn2=u_data->io->tmp_min_tsn2;
1368 tmp_minmax->tmp_min_tsn1=u_data->io->tmp_min_tsn1;
1369 tmp_minmax->tmp_max_tsn1=u_data->io->tmp_max_tsn1;
1370 tmp_minmax->tmp_max_tsn2=u_data->io->tmp_max_tsn2;
1371 u_data->assoc->min_max = g_slist_prepend(u_data->assoc->min_max, tmp_minmax);
1374 init_sctp_graph_window(u_data);
1375 sctp_graph_redraw(u_data);
1380 quit(GObject *object _U_, gpointer user_data)
1382 struct sctp_udata *u_data=user_data;
1384 decrease_childcount(u_data->parent);
1385 remove_child(u_data, u_data->parent);
1387 u_data->assoc->min_max = NULL;
1392 static void create_draw_area(GtkWidget *box, struct sctp_udata *u_data)
1394 u_data->io->draw_area=gtk_drawing_area_new();
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=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=g_malloc(sizeof(struct sctp_udata));
1524 u_data->assoc=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);