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.
34 #include "epan/filesystem.h"
35 #include <epan/strutil.h>
37 #include "../globals.h"
38 #include "ui/ui_util.h"
39 #include "ui/simple_dialog.h"
41 #include "ui/gtk/dlg_utils.h"
42 #include "ui/gtk/gui_utils.h"
43 #include "ui/gtk/main.h"
44 #include "ui/tap-sctp-analysis.h"
45 #include "ui/gtk/sctp_stat_gtk.h"
47 #include "ui/gtk/old-gtk-compat.h"
49 #define DEFAULT_PIXELS_PER_TICK 2
50 #define MAX_PIXELS_PER_TICK 4
51 #define AUTO_MAX_YSCALE 0
52 #define MAX_TICK_VALUES 5
53 #define DEFAULT_TICK_VALUE 3
55 #define MAX_COUNT_TYPES 3
57 #define COUNT_TYPE_FRAMES 0
58 #define COUNT_TYPE_BYTES 1
59 #define COUNT_TYPE_ADVANCED 2
61 #define LEFT_BORDER 80
62 #define RIGHT_BORDER 20
64 #define BOTTOM_BORDER 50
66 #define SUB_32(a, b) a-b
74 struct data_chunk_header
{
84 struct init_chunk_header
{
95 struct sack_chunk_header
{
111 static gboolean label_set
= FALSE
;
112 static guint32 max_tsn
=0, min_tsn
=0;
115 static void sctp_graph_set_title(struct sctp_udata
*u_data
);
116 static void create_draw_area(GtkWidget
*box
, struct sctp_udata
*u_data
);
117 static GtkWidget
*zoomout_bt
;
119 static void draw_sack_graph(struct sctp_udata
*u_data
)
121 GdkRGBA red_color
= {1.0, 0.0, 0.0, 1.0};
122 GdkRGBA green_color
= {0.0, 1.0, 0.0, 1.0};
124 GPtrArray
*array
= NULL
;
125 guint32 i
, size
= 0, start
=0, end
;
126 gboolean more
= FALSE
;
130 if (u_data
->dir
== 1)
132 array
= u_data
->assoc
->sort_sack1
;
133 size
=u_data
->assoc
->n_sack_chunks_ep1
;
134 if (u_data
->io
->tmp
== FALSE
)
137 max_tsn
= u_data
->assoc
->max_bytes1
;
141 min_tsn
= u_data
->io
->tmp_min_tsn1
;
142 max_tsn
= u_data
->io
->tmp_max_tsn1
;
145 else if (u_data
->dir
== 2)
147 array
= u_data
->assoc
->sort_sack2
;
148 size
= u_data
->assoc
->n_sack_chunks_ep2
;
149 if (u_data
->io
->tmp
== FALSE
)
152 max_tsn
= u_data
->assoc
->max_bytes2
;
156 min_tsn
= u_data
->io
->tmp_min_tsn2
;
157 max_tsn
= u_data
->io
->tmp_max_tsn2
;
161 width
= u_data
->io
->max_x
- u_data
->io
->min_x
;
163 for (i
=0; i
<size
; i
++)
165 if (u_data
->io
->uoff
)
166 diff
= (gint
)((struct tsn_sort
*)(g_ptr_array_index(array
, i
)))->secs
- u_data
->io
->min_x
;
168 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
;
169 end
= start
+ ((struct tsn_sort
*)(g_ptr_array_index(array
, i
)))->length
;
176 if (start
>= min_tsn
&& diff
> 0 && diff
<= width
)
178 #if GTK_CHECK_VERSION(2,22,0)
179 cr
= cairo_create (u_data
->io
->surface
);
181 cr
= gdk_cairo_create (u_data
->io
->pixmap
);
183 gdk_cairo_set_source_rgba (cr
, &red_color
);
184 cairo_set_line_width (cr
, 1.0);
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(start
,min_tsn
))*u_data
->io
->y_interval
)+0.5);
189 LEFT_BORDER
+u_data
->io
->offset
+u_data
->io
->x_interval
*diff
+0.5,
190 u_data
->io
->surface_height
-BOTTOM_BORDER
-u_data
->io
->offset
-((SUB_32(end
,min_tsn
))*u_data
->io
->y_interval
)+0.5);
195 #if GTK_CHECK_VERSION(2,22,0)
196 cr
= cairo_create (u_data
->io
->surface
);
198 cr
= gdk_cairo_create (u_data
->io
->pixmap
);
200 gdk_cairo_set_source_rgba (cr
, &green_color
);
201 cairo_set_line_width (cr
, 1.0);
203 LEFT_BORDER
+u_data
->io
->offset
+u_data
->io
->x_interval
*diff
+0.5,
204 u_data
->io
->surface_height
-BOTTOM_BORDER
-u_data
->io
->offset
-((SUB_32(end
,min_tsn
))*u_data
->io
->y_interval
)+0.5);
206 LEFT_BORDER
+u_data
->io
->offset
+u_data
->io
->x_interval
*diff
,
207 u_data
->io
->surface_height
-BOTTOM_BORDER
-u_data
->io
->offset
-((SUB_32(end
+10,min_tsn
))*u_data
->io
->y_interval
)+0.5);
218 static void draw_tsn_graph(struct sctp_udata
*u_data
)
220 GPtrArray
*array
= NULL
;
221 guint32 i
, size
= 0, start
, end
;
225 if (u_data
->dir
== 1)
227 array
= u_data
->assoc
->sort_tsn1
;
228 size
= u_data
->assoc
->n_data_chunks_ep1
;
229 if (u_data
->io
->tmp
== FALSE
)
232 max_tsn
= u_data
->assoc
->max_bytes1
;
236 min_tsn
= u_data
->io
->tmp_min_tsn1
;
237 max_tsn
= u_data
->io
->tmp_max_tsn1
;
240 else if (u_data
->dir
== 2)
242 array
= u_data
->assoc
->sort_tsn2
;
243 size
= u_data
->assoc
->n_data_chunks_ep2
;
244 if (u_data
->io
->tmp
== FALSE
)
247 max_tsn
= u_data
->assoc
->max_bytes2
;
251 min_tsn
= u_data
->io
->tmp_min_tsn2
;
252 max_tsn
= u_data
->io
->tmp_max_tsn2
;
255 width
= u_data
->io
->max_x
- u_data
->io
->min_x
;
257 for (i
=0; i
<size
; i
++)
259 if (u_data
->io
->uoff
)
260 diff
= (gint
)((struct tsn_sort
*)(g_ptr_array_index(array
, i
)))->secs
-u_data
->io
->min_x
;
262 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
;
263 start
= ((struct tsn_sort
*)(g_ptr_array_index(array
, i
)))->offset
;
264 end
= start
+ ((struct tsn_sort
*)(g_ptr_array_index(array
, i
)))->length
;
265 if (start
>= min_tsn
&& diff
> 0 && diff
<= width
){
266 #if GTK_CHECK_VERSION(2,22,0)
267 cr
= cairo_create (u_data
->io
->surface
);
269 cr
= gdk_cairo_create (u_data
->io
->pixmap
);
271 cairo_set_line_width (cr
, 1.0);
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(start
,min_tsn
))*u_data
->io
->y_interval
))+0.5);
276 (LEFT_BORDER
+u_data
->io
->offset
+u_data
->io
->x_interval
*diff
)+0.5,
277 (u_data
->io
->surface_height
-BOTTOM_BORDER
-u_data
->io
->offset
-((SUB_32(end
,min_tsn
))*u_data
->io
->y_interval
))+0.5);
286 static void sctp_graph_draw(struct sctp_udata
*u_data
)
289 guint32 distance
=5, i
, e
, sec
, w
, start
, a
, j
, b
;
290 gint label_width
, label_height
;
291 char label_string
[15];
293 gboolean write_label
= FALSE
;
295 GtkAllocation widget_alloc
;
298 if (u_data
->io
->x1_tmp_sec
== 0 && u_data
->io
->x1_tmp_usec
== 0)
299 u_data
->io
->offset
= 0;
301 u_data
->io
->offset
= 5;
303 if (u_data
->io
->x2_tmp_sec
- u_data
->io
->x1_tmp_sec
> 1500)
305 u_data
->io
->min_x
=u_data
->io
->x1_tmp_sec
;
306 u_data
->io
->max_x
=u_data
->io
->x2_tmp_sec
;
307 u_data
->io
->uoff
= TRUE
;
311 u_data
->io
->min_x
=((guint32
) (u_data
->io
->x1_tmp_sec
*1000000.0))+u_data
->io
->x1_tmp_usec
;
312 u_data
->io
->max_x
=((guint32
) (u_data
->io
->x2_tmp_sec
*1000000.0))+u_data
->io
->x2_tmp_usec
;
313 u_data
->io
->uoff
= FALSE
;
316 u_data
->io
->tmp_width
= u_data
->io
->max_x
- u_data
->io
->min_x
;
318 if (u_data
->dir
== 1)
320 if (u_data
->io
->tmp
== FALSE
)
322 if (u_data
->assoc
->sort_tsn1
!= NULL
)
323 u_data
->io
->max_y
= u_data
->io
->tmp_max_tsn1
- u_data
->io
->tmp_min_tsn1
;
325 u_data
->io
->max_y
= 0;
326 u_data
->io
->min_y
= 0;
330 u_data
->io
->max_y
= u_data
->io
->tmp_max_tsn1
;
331 u_data
->io
->min_y
= u_data
->io
->tmp_min_tsn1
;
334 else if (u_data
->dir
== 2)
336 if (u_data
->io
->tmp
== FALSE
)
338 if (u_data
->assoc
->tsn2
!= NULL
)
339 u_data
->io
->max_y
= u_data
->io
->tmp_max_tsn2
- u_data
->io
->tmp_min_tsn2
;
341 u_data
->io
->max_y
= 0;
342 u_data
->io
->min_y
= 0;
346 u_data
->io
->max_y
= u_data
->io
->tmp_max_tsn2
;
347 u_data
->io
->min_y
= u_data
->io
->tmp_min_tsn2
;
351 #if GTK_CHECK_VERSION(2,22,0)
352 cr
= cairo_create (u_data
->io
->surface
);
354 cr
= gdk_cairo_create (u_data
->io
->pixmap
);
356 cairo_set_source_rgb (cr
, 1, 1, 1);
357 gtk_widget_get_allocation(u_data
->io
->draw_area
, &widget_alloc
);
362 widget_alloc
.height
);
367 #if GTK_CHECK_VERSION(2,22,0)
368 cr
= cairo_create (u_data
->io
->surface
);
370 cr
= gdk_cairo_create (u_data
->io
->pixmap
);
372 cairo_set_line_width (cr
, 1.0);
373 cairo_move_to(cr
, LEFT_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
+0.5, u_data
->io
->surface_height
- BOTTOM_BORDER
+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+0.5, u_data
->io
->surface_height
- BOTTOM_BORDER
- 5+0.5);
379 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);
380 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);
384 u_data
->io
->axis_width
= u_data
->io
->surface_width
- LEFT_BORDER
- RIGHT_BORDER
- u_data
->io
->offset
;
386 if(u_data
->io
->tmp_width
>0){
387 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*/
389 u_data
->io
->x_interval
= (float)(u_data
->io
->axis_width
);
393 if (u_data
->io
->x_interval
< 1)
395 dis
= 1 / u_data
->io
->x_interval
;
402 for (i
=0; i
<=e
+1; i
++)
408 g_snprintf(label_string
, sizeof(label_string
), "%d", 0);
409 memcpy(label_string
,(gchar
*)g_locale_to_utf8(label_string
, -1 , NULL
, NULL
, NULL
), 15);
410 layout
= gtk_widget_create_pango_layout(u_data
->io
->draw_area
, label_string
);
411 pango_layout_get_pixel_size(layout
, &label_width
, &label_height
);
413 if (u_data
->io
->x1_tmp_usec
== 0)
414 sec
= u_data
->io
->x1_tmp_sec
;
416 sec
= u_data
->io
->x1_tmp_sec
+1;
418 if (u_data
->io
->offset
!= 0)
420 g_snprintf(label_string
, sizeof(label_string
), "%u", u_data
->io
->x1_tmp_sec
);
421 memcpy(label_string
,(gchar
*)g_locale_to_utf8(label_string
, -1 , NULL
, NULL
, NULL
), sizeof(label_string
));
422 pango_layout_set_text(layout
, label_string
, -1);
423 pango_layout_get_pixel_size(layout
, &lwidth
, NULL
);
425 #if GTK_CHECK_VERSION(2,22,0)
426 cr
= cairo_create (u_data
->io
->surface
);
428 cr
= gdk_cairo_create (u_data
->io
->pixmap
);
430 cairo_move_to (cr
, LEFT_BORDER
- 25, u_data
->io
->surface_height
- BOTTOM_BORDER
+ 20);
431 pango_cairo_show_layout (cr
, layout
);
436 w
= (guint32
)(500 / (guint32
)(distance
* u_data
->io
->x_interval
));
439 if (w
== 4 || w
==3 || w
==2)
443 b
= (guint32
)((u_data
->io
->min_x
/100000))%10; /* start for labels*/
451 if (!u_data
->io
->uoff
)
455 start
=u_data
->io
->min_x
/1000000*1000000;
461 start
=u_data
->io
->min_x
/100000;
465 b
= (guint32
)((start
/100000))%10;
470 start
= u_data
->io
->min_x
;
477 for (i
=start
, j
=b
; i
<=u_data
->io
->max_x
; i
+=a
, j
++)
479 if (!u_data
->io
->uoff
)
480 if (i
>= u_data
->io
->min_x
&& i
% 1000000 != 0)
483 g_snprintf(label_string
, sizeof(label_string
), "%d", i
%1000000);
489 memcpy(label_string
,(gchar
*)g_locale_to_utf8(label_string
, -1 , NULL
, NULL
, NULL
), sizeof(label_string
));
490 pango_layout_set_text(layout
, label_string
, -1);
491 pango_layout_get_pixel_size(layout
, &lwidth
, NULL
);
492 #if GTK_CHECK_VERSION(2,22,0)
493 cr
= cairo_create (u_data
->io
->surface
);
495 cr
= gdk_cairo_create (u_data
->io
->pixmap
);
498 LEFT_BORDER
+ u_data
->io
->offset
+ (i
- u_data
->io
->min_x
) * u_data
->io
->x_interval
- lwidth
/ 2,
499 u_data
->io
->surface_height
- BOTTOM_BORDER
+ 10);
500 pango_cairo_show_layout (cr
, layout
);
504 #if GTK_CHECK_VERSION(2,22,0)
505 cr
= cairo_create (u_data
->io
->surface
);
507 cr
= gdk_cairo_create (u_data
->io
->pixmap
);
509 cairo_set_line_width (cr
, 1.0);
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
+ 0.5);
514 LEFT_BORDER
+ u_data
->io
->offset
+ (i
- u_data
->io
->min_x
) * u_data
->io
->x_interval
+ 0.5,
515 u_data
->io
->surface_height
- BOTTOM_BORDER
+ length
+ 0.5);
520 if (!u_data
->io
->uoff
)
522 if (i
%1000000==0 && j
%w
==0)
538 #if GTK_CHECK_VERSION(2,22,0)
539 cr
= cairo_create (u_data
->io
->surface
);
541 cr
= gdk_cairo_create (u_data
->io
->pixmap
);
543 cairo_set_line_width (cr
, 1.0);
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
+ 0.5);
548 LEFT_BORDER
+ u_data
->io
->offset
+ (i
- u_data
->io
->min_x
) * u_data
->io
->x_interval
+ 0.5,
549 u_data
->io
->surface_height
- BOTTOM_BORDER
+ 10 + 0.5);
553 g_snprintf(label_string
, sizeof(label_string
), "%d", sec
);
554 memcpy(label_string
,(gchar
*)g_locale_to_utf8(label_string
, -1 , NULL
, NULL
, NULL
), sizeof(label_string
));
555 pango_layout_set_text(layout
, label_string
, -1);
556 pango_layout_get_pixel_size(layout
, &lwidth
, NULL
);
557 #if GTK_CHECK_VERSION(2,22,0)
558 cr
= cairo_create (u_data
->io
->surface
);
560 cr
= gdk_cairo_create (u_data
->io
->pixmap
);
563 (LEFT_BORDER
+ u_data
->io
->offset
+ (i
- u_data
->io
->min_x
) * u_data
->io
->x_interval
-10),
564 u_data
->io
->surface_height
- BOTTOM_BORDER
+ 20);
565 pango_cairo_show_layout (cr
, layout
);
573 g_strlcpy(label_string
, "sec", sizeof(label_string
));
575 memcpy(label_string
,(gchar
*)g_locale_to_utf8(label_string
, -1 , NULL
, NULL
, NULL
), sizeof(label_string
));
576 pango_layout_set_text(layout
, label_string
, -1);
577 pango_layout_get_pixel_size(layout
, &lwidth
, NULL
);
578 #if GTK_CHECK_VERSION(2,22,0)
579 cr
= cairo_create (u_data
->io
->surface
);
581 cr
= gdk_cairo_create (u_data
->io
->pixmap
);
584 u_data
->io
->surface_width
- RIGHT_BORDER
- 10,
585 u_data
->io
->surface_height
- BOTTOM_BORDER
+ 30);
586 pango_cairo_show_layout (cr
, layout
);
593 #if GTK_CHECK_VERSION(2,22,0)
594 cr
= cairo_create (u_data
->io
->surface
);
596 cr
= gdk_cairo_create (u_data
->io
->pixmap
);
598 cairo_set_line_width (cr
, 1.0);
599 cairo_move_to(cr
, LEFT_BORDER
+ 0.5, TOP_BORDER
- u_data
->io
->offset
+ 0.5);
600 cairo_line_to(cr
, LEFT_BORDER
+ 0.5, u_data
->io
->surface_height
- BOTTOM_BORDER
- u_data
->io
->offset
+ 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);
605 cairo_move_to(cr
, LEFT_BORDER
+ 0.5, TOP_BORDER
- u_data
->io
->offset
+ 0.5);
606 cairo_line_to(cr
, LEFT_BORDER
+5 + 0.5, TOP_BORDER
- u_data
->io
->offset
+ 5 + 0.5);
610 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
));
613 if (u_data
->io
->y_interval
< 1)
615 dis
= 1 / u_data
->io
->y_interval
;
623 distance
= distance
* 10;
625 else if (u_data
->io
->y_interval
<2)
628 if (u_data
->io
->max_y
> 0)
630 for (i
=u_data
->io
->min_y
/distance
*distance
; i
<=u_data
->io
->max_y
; i
+=distance
/5)
632 if (i
>= u_data
->io
->min_y
)
635 g_snprintf(label_string
, sizeof(label_string
), "%d", i
);
637 if (i
%distance
== 0 || (distance
<= 5 && u_data
->io
->y_interval
> 10))
641 memcpy(label_string
,(gchar
*)g_locale_to_utf8(label_string
, -1 , NULL
, NULL
, NULL
), sizeof(label_string
));
642 pango_layout_set_text(layout
, label_string
, -1);
643 pango_layout_get_pixel_size(layout
, &lwidth
, NULL
);
644 #if GTK_CHECK_VERSION(2,22,0)
645 cr
= cairo_create (u_data
->io
->surface
);
647 cr
= gdk_cairo_create (u_data
->io
->pixmap
);
650 LEFT_BORDER
- length
- lwidth
- 5,
651 u_data
->io
->surface_height
- BOTTOM_BORDER
- u_data
->io
->offset
- (i
- u_data
->io
->min_y
) * u_data
->io
->y_interval
- 3);
652 pango_cairo_show_layout (cr
, layout
);
656 #if GTK_CHECK_VERSION(2,22,0)
657 cr
= cairo_create (u_data
->io
->surface
);
659 cr
= gdk_cairo_create (u_data
->io
->pixmap
);
661 cairo_set_line_width (cr
, 1.0);
663 LEFT_BORDER
- length
+ 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);
667 u_data
->io
->surface_height
- BOTTOM_BORDER
- u_data
->io
->offset
- (i
- u_data
->io
->min_y
) * u_data
->io
->y_interval
+ 0.5);
674 simple_dialog(ESD_TYPE_INFO
, ESD_BTN_OK
, "No Data Chunks sent");
676 g_object_unref(G_OBJECT(layout
));
680 static void sctp_graph_redraw(struct sctp_udata
*u_data
)
683 GtkAllocation widget_alloc
;
686 u_data
->io
->needs_redraw
= TRUE
;
688 sctp_graph_draw(u_data
);
689 switch (u_data
->io
->graph_type
)
692 draw_sack_graph(u_data
);
693 draw_tsn_graph(u_data
);
696 draw_tsn_graph(u_data
);
699 draw_sack_graph(u_data
);
703 ios
=(sctp_graph_t
*)g_object_get_data(G_OBJECT(u_data
->io
->draw_area
), "sctp_graph_t");
704 g_assert(ios
!= NULL
);
706 cr
= gdk_cairo_create (gtk_widget_get_window(u_data
->io
->draw_area
));
708 #if GTK_CHECK_VERSION(2,22,0)
709 cairo_set_source_surface (cr
, ios
->surface
, 0, 0);
711 gdk_cairo_set_source_pixmap (cr
, ios
->pixmap
, 0, 0);
713 gtk_widget_get_allocation(u_data
->io
->draw_area
, &widget_alloc
);
714 cairo_rectangle (cr
, 0, 0, widget_alloc
.width
, widget_alloc
.height
);
721 static void on_sack_bt(GtkWidget
*widget _U_
, struct sctp_udata
*u_data
)
723 u_data
= (struct sctp_udata
*) u_data
;
724 u_data
->io
->graph_type
= 2;
725 sctp_graph_redraw(u_data
);
728 static void on_tsn_bt(GtkWidget
*widget _U_
, struct sctp_udata
*u_data
)
730 u_data
->io
->graph_type
= 1;
731 sctp_graph_redraw(u_data
);
734 static void on_both_bt(GtkWidget
*widget _U_
, struct sctp_udata
*u_data
)
736 u_data
->io
->graph_type
= 0;
737 sctp_graph_redraw(u_data
);
741 sctp_graph_close_cb(GtkWidget
* widget _U_
, gpointer u_data
)
743 struct sctp_udata
*udata
;
745 udata
= (struct sctp_udata
*)u_data
;
746 gtk_grab_remove(GTK_WIDGET(udata
->io
->window
));
747 gtk_widget_destroy(GTK_WIDGET(udata
->io
->window
));
753 on_configure_event(GtkWidget
*widget
, GdkEventConfigure
*event _U_
, gpointer user_data
)
755 struct sctp_udata
*u_data
= (struct sctp_udata
*)user_data
;
756 GtkAllocation widget_alloc
;
759 g_assert(u_data
->io
!= NULL
);
761 #if GTK_CHECK_VERSION(2,22,0)
762 if(u_data
->io
->surface
){
763 cairo_surface_destroy (u_data
->io
->surface
);
764 u_data
->io
->surface
=NULL
;
766 gtk_widget_get_allocation(widget
, &widget_alloc
);
767 u_data
->io
->surface
= gdk_window_create_similar_surface (gtk_widget_get_window(widget
),
770 widget_alloc
.height
);
772 if(u_data
->io
->pixmap
){
773 g_object_unref(u_data
->io
->pixmap
);
774 u_data
->io
->pixmap
= NULL
;
776 gtk_widget_get_allocation(widget
, &widget_alloc
);
777 u_data
->io
->pixmap
= gdk_pixmap_new(gtk_widget_get_window(widget
),
782 u_data
->io
->surface_width
= widget_alloc
.width
;
783 u_data
->io
->surface_height
= widget_alloc
.height
;
785 #if GTK_CHECK_VERSION(2,22,0)
786 cr
= cairo_create (u_data
->io
->surface
);
788 cr
= gdk_cairo_create (u_data
->io
->pixmap
);
790 cairo_rectangle (cr
, 0, 0, widget_alloc
.width
, widget_alloc
.height
);
791 cairo_set_source_rgb (cr
, 1, 1, 1);
795 sctp_graph_redraw(u_data
);
799 #if GTK_CHECK_VERSION(3,0,0)
801 on_draw_area_draw_event(GtkWidget
*widget
, cairo_t
*cr
, gpointer user_data
)
803 sctp_graph_t
*ios
= (sctp_graph_t
*)user_data
;
804 GtkAllocation allocation
;
806 gtk_widget_get_allocation (widget
, &allocation
);
807 cairo_set_source_surface (cr
, ios
->surface
, 0, 0);
808 cairo_rectangle (cr
, 0, 0, allocation
.width
, allocation
.width
);
815 on_expose_event(GtkWidget
*widget
, GdkEventExpose
*event
, gpointer user_data
)
817 sctp_graph_t
*ios
= (sctp_graph_t
*)user_data
;
820 g_assert(ios
!= NULL
);
822 cr
= gdk_cairo_create (gtk_widget_get_window(widget
));
824 #if GTK_CHECK_VERSION(2,22,0)
825 cairo_set_source_surface (cr
, ios
->surface
, 0, 0);
827 gdk_cairo_set_source_pixmap (cr
, ios
->pixmap
, 0, 0);
829 cairo_rectangle (cr
, event
->area
.x
, event
->area
.y
, event
->area
.width
, event
->area
.height
);
839 on_zoomin_bt (GtkWidget
*widget _U_
, struct sctp_udata
*u_data
)
841 sctp_min_max_t
*tmp_minmax
;
843 if (u_data
->io
->rectangle
==TRUE
)
845 tmp_minmax
= (sctp_min_max_t
*)g_malloc(sizeof(sctp_min_max_t
));
847 u_data
->io
->tmp_min_tsn1
=u_data
->io
->y1_tmp
+u_data
->io
->min_y
;
848 u_data
->io
->tmp_max_tsn1
=u_data
->io
->y2_tmp
+1+u_data
->io
->min_y
;
850 u_data
->io
->tmp_min_tsn2
=u_data
->io
->tmp_min_tsn1
;
851 u_data
->io
->tmp_max_tsn2
=u_data
->io
->tmp_max_tsn1
;
852 tmp_minmax
->tmp_min_secs
=u_data
->io
->x1_tmp_sec
;
853 tmp_minmax
->tmp_min_usecs
= u_data
->io
->x1_tmp_usec
;
854 tmp_minmax
->tmp_max_secs
= u_data
->io
->x2_tmp_sec
;
855 tmp_minmax
->tmp_max_usecs
= u_data
->io
->x2_tmp_usec
;
856 tmp_minmax
->tmp_min_tsn1
=u_data
->io
->tmp_min_tsn1
;
857 tmp_minmax
->tmp_max_tsn1
=u_data
->io
->tmp_max_tsn1
;
858 tmp_minmax
->tmp_min_tsn2
=u_data
->io
->tmp_min_tsn2
;
859 tmp_minmax
->tmp_max_tsn2
=u_data
->io
->tmp_max_tsn2
;
860 u_data
->assoc
->min_max
= g_slist_prepend(u_data
->assoc
->min_max
, tmp_minmax
);
861 u_data
->io
->length
= g_slist_length(u_data
->assoc
->min_max
);
862 u_data
->io
->tmp
=TRUE
;
863 u_data
->io
->rectangle
=FALSE
;
864 gtk_widget_set_sensitive(zoomout_bt
, TRUE
);
865 sctp_graph_redraw(u_data
);
869 simple_dialog(ESD_TYPE_ERROR
, ESD_BTN_OK
, "Please draw a rectangle around the area you want to zoom in.");
874 zoomin_bt_fcn (struct sctp_udata
*u_data
)
876 sctp_min_max_t
*tmp_minmax
;
878 tmp_minmax
= (sctp_min_max_t
*)g_malloc(sizeof(sctp_min_max_t
));
880 u_data
->io
->tmp_min_tsn1
=u_data
->io
->y1_tmp
+u_data
->io
->min_y
;
881 u_data
->io
->tmp_max_tsn1
=u_data
->io
->y2_tmp
+1+u_data
->io
->min_y
;
883 u_data
->io
->tmp_min_tsn2
=u_data
->io
->tmp_min_tsn1
;
884 u_data
->io
->tmp_max_tsn2
=u_data
->io
->tmp_max_tsn1
;
885 tmp_minmax
->tmp_min_secs
=u_data
->io
->x1_tmp_sec
;
886 tmp_minmax
->tmp_min_usecs
=u_data
->io
->x1_tmp_usec
;
887 tmp_minmax
->tmp_max_secs
=u_data
->io
->x2_tmp_sec
;
888 tmp_minmax
->tmp_max_usecs
=u_data
->io
->x2_tmp_usec
;
889 tmp_minmax
->tmp_min_tsn1
=u_data
->io
->tmp_min_tsn1
;
890 tmp_minmax
->tmp_max_tsn1
=u_data
->io
->tmp_max_tsn1
;
891 tmp_minmax
->tmp_min_tsn2
=u_data
->io
->tmp_min_tsn2
;
892 tmp_minmax
->tmp_max_tsn2
=u_data
->io
->tmp_max_tsn2
;
893 u_data
->assoc
->min_max
= g_slist_prepend(u_data
->assoc
->min_max
, tmp_minmax
);
894 u_data
->io
->length
= g_slist_length(u_data
->assoc
->min_max
);
895 u_data
->io
->tmp
=TRUE
;
896 u_data
->io
->rectangle
=FALSE
;
897 gtk_widget_set_sensitive(zoomout_bt
, TRUE
);
898 sctp_graph_redraw(u_data
);
902 on_zoomout_bt (GtkWidget
*widget _U_
, struct sctp_udata
*u_data
)
904 sctp_min_max_t
*tmp_minmax
, *mm
;
907 l
= g_slist_length(u_data
->assoc
->min_max
);
909 if (u_data
->assoc
->min_max
!=NULL
)
911 mm
=(sctp_min_max_t
*)((u_data
->assoc
->min_max
)->data
);
912 u_data
->assoc
->min_max
=g_slist_remove(u_data
->assoc
->min_max
, mm
);
917 tmp_minmax
= (sctp_min_max_t
*)u_data
->assoc
->min_max
->data
;
918 u_data
->io
->x1_tmp_sec
=tmp_minmax
->tmp_min_secs
;
919 u_data
->io
->x1_tmp_usec
=tmp_minmax
->tmp_min_usecs
;
920 u_data
->io
->x2_tmp_sec
=tmp_minmax
->tmp_max_secs
;
921 u_data
->io
->x2_tmp_usec
=tmp_minmax
->tmp_max_usecs
;
922 u_data
->io
->tmp_min_tsn1
=tmp_minmax
->tmp_min_tsn1
;
923 u_data
->io
->tmp_max_tsn1
=tmp_minmax
->tmp_max_tsn1
;
924 u_data
->io
->tmp_min_tsn2
=tmp_minmax
->tmp_min_tsn2
;
925 u_data
->io
->tmp_max_tsn2
=tmp_minmax
->tmp_max_tsn2
;
926 u_data
->io
->tmp
=TRUE
;
930 u_data
->io
->x1_tmp_sec
=u_data
->assoc
->min_secs
;
931 u_data
->io
->x1_tmp_usec
=u_data
->assoc
->min_usecs
;
932 u_data
->io
->x2_tmp_sec
=u_data
->assoc
->max_secs
;
933 u_data
->io
->x2_tmp_usec
=u_data
->assoc
->max_usecs
;
934 u_data
->io
->tmp_min_tsn1
=0;
935 u_data
->io
->tmp_max_tsn1
=u_data
->assoc
->max_bytes1
;
936 u_data
->io
->tmp_min_tsn2
=0;
937 u_data
->io
->tmp_max_tsn2
=u_data
->assoc
->max_bytes2
;
938 u_data
->io
->tmp
=FALSE
;
943 u_data
->io
->x1_tmp_sec
=u_data
->assoc
->min_secs
;
944 u_data
->io
->x1_tmp_usec
=u_data
->assoc
->min_usecs
;
945 u_data
->io
->x2_tmp_sec
=u_data
->assoc
->max_secs
;
946 u_data
->io
->x2_tmp_usec
=u_data
->assoc
->max_usecs
;
947 u_data
->io
->tmp_min_tsn1
=0;
948 u_data
->io
->tmp_max_tsn1
=u_data
->assoc
->max_bytes1
;
949 u_data
->io
->tmp_min_tsn2
=0;
950 u_data
->io
->tmp_max_tsn2
=u_data
->assoc
->max_bytes2
;
951 u_data
->io
->tmp
=FALSE
;
953 if (g_slist_length(u_data
->assoc
->min_max
)==1)
954 gtk_widget_set_sensitive(zoomout_bt
, FALSE
);
955 sctp_graph_redraw(u_data
);
960 on_button_press_event (GtkWidget
*widget _U_
, GdkEventButton
*event
, gpointer user_data
)
962 struct sctp_udata
*u_data
= (struct sctp_udata
*)user_data
;
966 if (u_data
->io
->rectangle
==TRUE
)
968 #if GTK_CHECK_VERSION(2,22,0)
969 cr
= cairo_create (u_data
->io
->surface
);
971 cr
= gdk_cairo_create (u_data
->io
->pixmap
);
974 floor(MIN(u_data
->io
->x_old
,u_data
->io
->x_new
)),
975 floor(MIN(u_data
->io
->y_old
,u_data
->io
->y_new
)),
976 abs((int)(u_data
->io
->x_new
-u_data
->io
->x_old
)),
977 abs((int)(u_data
->io
->y_new
-u_data
->io
->y_old
)));
978 cairo_set_source_rgb (cr
, 1, 1, 1);
983 ios
=(sctp_graph_t
*)g_object_get_data(G_OBJECT(u_data
->io
->draw_area
), "sctp_graph_t");
984 g_assert(ios
!= NULL
);
986 cr
= gdk_cairo_create (gtk_widget_get_window(u_data
->io
->draw_area
));
988 #if GTK_CHECK_VERSION(2,22,0)
989 cairo_set_source_surface (cr
, ios
->surface
, 0, 0);
991 gdk_cairo_set_source_pixmap (cr
, ios
->pixmap
, 0, 0);
993 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
)));
998 sctp_graph_redraw(u_data
);
1001 u_data
->io
->x_old
=event
->x
;
1002 u_data
->io
->y_old
=event
->y
;
1003 if (u_data
->io
->y_old
>u_data
->io
->surface_height
-BOTTOM_BORDER
-u_data
->io
->offset
)
1004 u_data
->io
->y_old
=u_data
->io
->surface_height
-BOTTOM_BORDER
-u_data
->io
->offset
;
1005 if (u_data
->io
->x_old
<LEFT_BORDER
+u_data
->io
->offset
)
1006 u_data
->io
->x_old
=LEFT_BORDER
+u_data
->io
->offset
;
1007 u_data
->io
->rectangle
=FALSE
;
1014 on_button_release_event (GtkWidget
*widget _U_
, GdkEventButton
*event
, gpointer user_data
)
1016 struct sctp_udata
*u_data
= (struct sctp_udata
*)user_data
;
1018 guint32 helpx
, helpy
, x1_tmp
, x2_tmp
, y_value
;
1019 gint label_width
, label_height
;
1020 gdouble x_value
, position
, tfirst
;
1022 char label_string
[30];
1023 GList
*tsnlist
=NULL
;
1024 tsn_t
*tsn
, *tmptsn
;
1025 PangoLayout
*layout
;
1026 GtkAllocation widget_alloc
;
1029 g_snprintf(label_string
, 15, "%d", 0);
1030 memcpy(label_string
,(gchar
*)g_locale_to_utf8(label_string
, -1 , NULL
, NULL
, NULL
), 15);
1031 layout
= gtk_widget_create_pango_layout(u_data
->io
->draw_area
, label_string
);
1032 pango_layout_get_pixel_size(layout
, &label_width
, &label_height
);
1034 if (event
->y
> u_data
->io
->surface_height
-BOTTOM_BORDER
-u_data
->io
->offset
)
1035 event
->y
= u_data
->io
->surface_height
-BOTTOM_BORDER
-u_data
->io
->offset
;
1036 if (event
->x
< LEFT_BORDER
+u_data
->io
->offset
)
1037 event
->x
= LEFT_BORDER
+u_data
->io
->offset
;
1039 if (abs((int)(event
->x
-u_data
->io
->x_old
))>10 || abs((int)(event
->y
-u_data
->io
->y_old
))>10)
1041 u_data
->io
->rect_x_min
= (guint32
) floor(MIN(u_data
->io
->x_old
,event
->x
));
1042 u_data
->io
->rect_x_max
= (guint32
) ceil(MAX(u_data
->io
->x_old
,event
->x
));
1043 u_data
->io
->rect_y_min
= (guint32
) floor(MIN(u_data
->io
->y_old
,event
->y
));
1044 u_data
->io
->rect_y_max
= (guint32
) ceil(MAX(u_data
->io
->y_old
,event
->y
));
1046 #if GTK_CHECK_VERSION(2,22,0)
1047 cr
= cairo_create (u_data
->io
->surface
);
1049 cr
= gdk_cairo_create (u_data
->io
->pixmap
);
1051 cairo_rectangle (cr
,
1052 u_data
->io
->rect_x_min
+0.5,
1053 u_data
->io
->rect_y_min
+0.5,
1054 u_data
->io
->rect_x_max
- u_data
->io
->rect_x_min
,
1055 u_data
->io
->rect_y_max
- u_data
->io
->rect_y_min
);
1056 cairo_set_line_width (cr
, 1.0);
1060 ios
=(sctp_graph_t
*)g_object_get_data(G_OBJECT(u_data
->io
->draw_area
), "sctp_graph_t");
1061 g_assert(ios
!= NULL
);
1063 cr
= gdk_cairo_create (gtk_widget_get_window(u_data
->io
->draw_area
));
1065 #if GTK_CHECK_VERSION(2,22,0)
1066 cairo_set_source_surface (cr
, ios
->surface
, 0, 0);
1068 gdk_cairo_set_source_pixmap (cr
, ios
->pixmap
, 0, 0);
1070 gtk_widget_get_allocation(u_data
->io
->draw_area
, &widget_alloc
);
1071 cairo_rectangle (cr
, 0, 0, widget_alloc
.width
, widget_alloc
.height
);
1076 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
));
1077 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
));
1078 helpx
=MIN(x1_tmp
, x2_tmp
);
1084 if (u_data
->io
->uoff
)
1086 if (x2_tmp
- x1_tmp
<= 1500)
1087 u_data
->io
->uoff
= FALSE
;
1088 u_data
->io
->x1_tmp_sec
=(guint32
)x1_tmp
;
1089 u_data
->io
->x1_tmp_usec
=0;
1090 u_data
->io
->x2_tmp_sec
=(guint32
)x2_tmp
;
1091 u_data
->io
->x2_tmp_usec
=0;
1095 u_data
->io
->x1_tmp_sec
=(guint32
)x1_tmp
/1000000;
1096 u_data
->io
->x1_tmp_usec
=x1_tmp
%1000000;
1097 u_data
->io
->x2_tmp_sec
=(guint32
)x2_tmp
/1000000;
1098 u_data
->io
->x2_tmp_usec
=x2_tmp
%1000000;
1100 u_data
->io
->x1_akt_sec
= u_data
->io
->x1_tmp_sec
;
1101 u_data
->io
->x1_akt_usec
= u_data
->io
->x1_tmp_usec
;
1102 u_data
->io
->x2_akt_sec
= u_data
->io
->x2_tmp_sec
;
1103 u_data
->io
->x2_akt_usec
= u_data
->io
->x2_tmp_usec
;
1105 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
);
1106 u_data
->io
->y2_tmp
=(guint32
)((u_data
->io
->surface_height
-BOTTOM_BORDER
-u_data
->io
->offset
-event
->y
)/u_data
->io
->y_interval
);
1107 helpy
= MIN(u_data
->io
->y1_tmp
, u_data
->io
->y2_tmp
);
1108 u_data
->io
->y2_tmp
= MAX(u_data
->io
->y1_tmp
, u_data
->io
->y2_tmp
);
1109 u_data
->io
->y1_tmp
= helpy
;
1110 u_data
->io
->x_new
=event
->x
;
1111 u_data
->io
->y_new
=event
->y
;
1112 u_data
->io
->rectangle
=TRUE
;
1113 u_data
->io
->rectangle_present
=TRUE
;
1117 if (u_data
->io
->rectangle_present
==TRUE
)
1119 u_data
->io
->rectangle_present
=FALSE
;
1120 if (event
->x
>= u_data
->io
->rect_x_min
&& event
->x
<= u_data
->io
->rect_x_max
&&
1121 event
->y
>= u_data
->io
->rect_y_min
&& event
->y
<= u_data
->io
->rect_y_max
)
1122 zoomin_bt_fcn(u_data
);
1125 u_data
->io
->x1_tmp_sec
= u_data
->io
->x1_akt_sec
;
1126 u_data
->io
->x1_tmp_usec
= u_data
->io
->x1_akt_usec
;
1127 u_data
->io
->x2_tmp_sec
= u_data
->io
->x2_akt_sec
;
1128 u_data
->io
->x2_tmp_usec
= u_data
->io
->x2_akt_usec
;
1129 sctp_graph_redraw(u_data
);
1135 sctp_graph_redraw(u_data
);
1139 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;
1140 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
;
1142 if (u_data
->dir
== 1)
1143 tsnlist
= g_list_last(u_data
->assoc
->tsn1
);
1145 tsnlist
= g_list_last(u_data
->assoc
->tsn2
);
1147 tsn
= (tsn_t
*) (tsnlist
->data
);
1148 tmptsn
=(tsn_t
*)(tsnlist
->data
);
1149 tfirst
= tsn
->secs
+ tsn
->usecs
/1000000.0;
1151 for (tsnlist
= g_list_previous(tsnlist
); tsnlist
; 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
=ws_gtk_box_new(GTK_ORIENTATION_VERTICAL
, 0, FALSE
);
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_button_box_new(GTK_ORIENTATION_HORIZONTAL
);
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_widget_show(hbox
);
1273 sack_bt
= gtk_button_new_with_label ("Adv. Rec. Window");
1274 gtk_box_pack_start(GTK_BOX(hbox
), sack_bt
, FALSE
, FALSE
, 0);
1275 gtk_widget_show(sack_bt
);
1277 g_signal_connect(sack_bt
, "clicked", G_CALLBACK(on_sack_bt
), u_data
);
1279 tsn_bt
= gtk_button_new_with_label ("Data bytes sent");
1280 gtk_box_pack_start(GTK_BOX(hbox
), tsn_bt
, FALSE
, FALSE
, 0);
1281 gtk_widget_show(tsn_bt
);
1282 g_signal_connect(tsn_bt
, "clicked", G_CALLBACK(on_tsn_bt
), u_data
);
1284 both_bt
= gtk_button_new_with_label ("Show both");
1285 gtk_box_pack_start(GTK_BOX(hbox
), both_bt
, FALSE
, FALSE
, 0);
1286 gtk_widget_show(both_bt
);
1287 g_signal_connect(both_bt
, "clicked", G_CALLBACK(on_both_bt
), u_data
);
1289 zoomin_bt
= gtk_button_new_with_label ("Zoom in");
1290 gtk_box_pack_start(GTK_BOX(hbox
), zoomin_bt
, FALSE
, FALSE
, 0);
1291 gtk_widget_show(zoomin_bt
);
1292 g_signal_connect(zoomin_bt
, "clicked", G_CALLBACK(on_zoomin_bt
), u_data
);
1293 gtk_widget_set_tooltip_text(zoomin_bt
, "Zoom in the area you have selected");
1295 zoomout_bt
= gtk_button_new_with_label ("Zoom out");
1296 gtk_box_pack_start(GTK_BOX(hbox
), zoomout_bt
, FALSE
, FALSE
, 0);
1297 gtk_widget_show(zoomout_bt
);
1298 g_signal_connect(zoomout_bt
, "clicked", G_CALLBACK(on_zoomout_bt
), u_data
);
1299 gtk_widget_set_tooltip_text(zoomout_bt
, "Zoom out one step");
1300 gtk_widget_set_sensitive(zoomout_bt
, FALSE
);
1302 bt_close
= gtk_button_new_from_stock(GTK_STOCK_CLOSE
);
1303 gtk_box_pack_start(GTK_BOX(hbox
), bt_close
, FALSE
, FALSE
, 0);
1304 gtk_widget_show(bt_close
);
1305 g_signal_connect(bt_close
, "clicked", G_CALLBACK(sctp_graph_close_cb
), u_data
);
1307 g_signal_connect(u_data
->io
->draw_area
,"button_press_event",G_CALLBACK(on_button_press_event
), u_data
);
1308 g_signal_connect(u_data
->io
->draw_area
,"button_release_event",G_CALLBACK(on_button_release_event
), u_data
);
1309 gtk_widget_set_events(u_data
->io
->draw_area
, GDK_BUTTON_PRESS_MASK
| GDK_BUTTON_RELEASE_MASK
| GDK_EXPOSURE_MASK
);
1310 /* dlg_set_cancel(u_data->io->window, bt_close); */
1312 gtk_widget_show(u_data
->io
->window
);
1315 static void sctp_graph_set_title(struct sctp_udata
*u_data
)
1320 if(!u_data
->io
->window
)
1324 display_name
= cf_get_display_name(&cfile
);
1325 title
= g_strdup_printf("SCTP Data and Adv.Rcv.Window over Time: %s Port1 %u Port2 %u Endpoint %u",
1326 display_name
, u_data
->parent
->assoc
->port1
, u_data
->parent
->assoc
->port2
, u_data
->dir
);
1327 g_free(display_name
);
1328 gtk_window_set_title(GTK_WINDOW(u_data
->io
->window
), title
);
1334 gtk_sctpgraph_init(struct sctp_udata
*u_data
)
1337 sctp_min_max_t
* tmp_minmax
;
1339 io
=(sctp_graph_t
*)g_malloc(sizeof(sctp_graph_t
));
1340 io
->needs_redraw
=TRUE
;
1341 io
->x_interval
=1000;
1344 #if GTK_CHECK_VERSION(2,22,0)
1349 io
->surface_width
=800;
1350 io
->surface_height
=600;
1355 u_data
->io
->x1_tmp_sec
=u_data
->assoc
->min_secs
;
1356 u_data
->io
->x1_tmp_usec
=u_data
->assoc
->min_usecs
;
1357 u_data
->io
->x2_tmp_sec
=u_data
->assoc
->max_secs
;
1358 u_data
->io
->x2_tmp_usec
=u_data
->assoc
->max_usecs
;
1359 u_data
->io
->tmp_min_tsn1
=0;
1360 u_data
->io
->tmp_max_tsn1
=u_data
->assoc
->max_bytes1
;
1361 u_data
->io
->tmp_min_tsn2
=0;
1362 u_data
->io
->tmp_max_tsn2
=u_data
->assoc
->max_bytes2
;
1363 u_data
->io
->tmp
=FALSE
;
1364 tmp_minmax
= (sctp_min_max_t
*)g_malloc(sizeof(sctp_min_max_t
));
1365 tmp_minmax
->tmp_min_secs
= u_data
->assoc
->min_secs
;
1366 tmp_minmax
->tmp_min_usecs
=u_data
->assoc
->min_usecs
;
1367 tmp_minmax
->tmp_max_secs
=u_data
->assoc
->max_secs
;
1368 tmp_minmax
->tmp_max_usecs
=u_data
->assoc
->max_usecs
;
1369 tmp_minmax
->tmp_min_tsn2
=u_data
->io
->tmp_min_tsn2
;
1370 tmp_minmax
->tmp_min_tsn1
=u_data
->io
->tmp_min_tsn1
;
1371 tmp_minmax
->tmp_max_tsn1
=u_data
->io
->tmp_max_tsn1
;
1372 tmp_minmax
->tmp_max_tsn2
=u_data
->io
->tmp_max_tsn2
;
1373 u_data
->assoc
->min_max
= g_slist_prepend(u_data
->assoc
->min_max
, tmp_minmax
);
1376 init_sctp_graph_window(u_data
);
1377 sctp_graph_redraw(u_data
);
1382 quit(GObject
*object _U_
, gpointer user_data
)
1384 struct sctp_udata
*u_data
=(struct sctp_udata
*)user_data
;
1386 decrease_childcount(u_data
->parent
);
1387 remove_child(u_data
, u_data
->parent
);
1389 u_data
->assoc
->min_max
= NULL
;
1394 static void create_draw_area(GtkWidget
*box
, struct sctp_udata
*u_data
)
1396 u_data
->io
->draw_area
=gtk_drawing_area_new();
1397 g_object_set_data(G_OBJECT(u_data
->io
->draw_area
), "sctp_graph_t", u_data
->io
);
1398 g_signal_connect(u_data
->io
->draw_area
, "destroy", G_CALLBACK(quit
), u_data
);
1400 gtk_widget_set_size_request(u_data
->io
->draw_area
, u_data
->io
->surface_width
, u_data
->io
->surface_height
);
1402 /* signals needed to handle backing pixmap */
1403 #if GTK_CHECK_VERSION(3,0,0)
1404 g_signal_connect(u_data
->io
->draw_area
, "draw", G_CALLBACK(on_draw_area_draw_event
), u_data
->io
);
1406 g_signal_connect(u_data
->io
->draw_area
, "expose_event", G_CALLBACK(on_expose_event
), u_data
->io
);
1408 g_signal_connect(u_data
->io
->draw_area
, "configure_event", G_CALLBACK(on_configure_event
), u_data
);
1410 gtk_widget_show(u_data
->io
->draw_area
);
1411 gtk_box_pack_start(GTK_BOX(box
), u_data
->io
->draw_area
, TRUE
, TRUE
, 0);
1414 static void insertion(GPtrArray
*array
, guint32 N
)
1418 struct tsn_sort
*help
=NULL
;
1422 v
= ((struct tsn_sort
*)(g_ptr_array_index(array
,i
)))->tsnumber
;
1424 while (j
>=1 && ((struct tsn_sort
*)(g_ptr_array_index(array
, j
-1)))->tsnumber
> v
)
1426 help
=(struct tsn_sort
*)g_ptr_array_index(array
, j
);
1427 g_ptr_array_index(array
, j
)=g_ptr_array_index(array
, j
-1);
1428 g_ptr_array_index(array
, j
-1)=help
;
1431 ((struct tsn_sort
*)(g_ptr_array_index(array
, j
)))->tsnumber
=v
;
1435 static void set_arw_offsets(struct sctp_udata
*u_data
)
1437 GPtrArray
*s_array
=NULL
, *t_array
=NULL
;
1440 if (u_data
->dir
==1 && u_data
->assoc
->n_sack_chunks_ep1
>0)
1442 s_array
=u_data
->assoc
->sort_sack1
;
1443 t_array
=u_data
->assoc
->sort_tsn1
;
1444 insertion(s_array
,u_data
->assoc
->n_sack_chunks_ep1
);
1446 for (i
=0; i
<u_data
->assoc
->n_sack_chunks_ep1
; i
++)
1448 while (((struct tsn_sort
*)(g_ptr_array_index(s_array
, i
)))->tsnumber
> ((struct tsn_sort
*)(g_ptr_array_index(t_array
, j
)))->tsnumber
)
1452 ((struct tsn_sort
*)(g_ptr_array_index(s_array
,i
)))->offset
= ((struct tsn_sort
*)(g_ptr_array_index(t_array
, j
)))->offset
1453 + ((struct tsn_sort
*)(g_ptr_array_index(t_array
, j
)))->length
;
1456 u_data
->assoc
->sort_sack1
=s_array
;
1459 if (u_data
->dir
==2 && u_data
->assoc
->n_sack_chunks_ep2
>0)
1461 s_array
=u_data
->assoc
->sort_sack2
;
1462 t_array
=u_data
->assoc
->sort_tsn2
;
1463 insertion(s_array
,u_data
->assoc
->n_sack_chunks_ep2
);
1465 for (i
=0; i
<u_data
->assoc
->n_sack_chunks_ep2
; i
++)
1467 while (((struct tsn_sort
*)(g_ptr_array_index(s_array
, i
)))->tsnumber
> ((struct tsn_sort
*)(g_ptr_array_index(t_array
,j
)))->tsnumber
)
1471 ((struct tsn_sort
*)(g_ptr_array_index(s_array
, i
)))->offset
= ((struct tsn_sort
*)(g_ptr_array_index(t_array
, j
)))->offset
1472 + ((struct tsn_sort
*)(g_ptr_array_index(t_array
, j
)))->length
;
1474 u_data
->assoc
->sort_sack2
=s_array
;
1478 static void compute_offsets(struct sctp_udata
*u_data
)
1480 struct tsn_sort t_sort
;
1481 GPtrArray
*array
=NULL
;
1486 if (u_data
->dir
==1 && u_data
->assoc
->n_array_tsn1
>0)
1488 array
=u_data
->assoc
->sort_tsn1
;
1489 insertion(array
,u_data
->assoc
->n_array_tsn1
);
1491 for (i
=0; i
<u_data
->assoc
->n_array_tsn1
; i
++)
1493 ((struct tsn_sort
*)(g_ptr_array_index(array
, i
)))->offset
=sum
;
1494 t_sort
.tsnumber
=((struct tsn_sort
*)(g_ptr_array_index(array
, i
)))->tsnumber
;
1495 if (t_sort
.tsnumber
>tsntmp
)
1496 sum
+=((struct tsn_sort
*)(g_ptr_array_index(array
, i
)))->length
;
1497 tsntmp
=t_sort
.tsnumber
;
1499 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
;
1500 u_data
->assoc
->sort_tsn1
=array
;
1502 if (u_data
->dir
==2 && u_data
->assoc
->n_array_tsn2
>0)
1505 array
=u_data
->assoc
->sort_tsn2
;
1506 insertion(array
,u_data
->assoc
->n_array_tsn2
);
1508 for (i
=0; i
<u_data
->assoc
->n_array_tsn2
; i
++)
1510 ((struct tsn_sort
*)(g_ptr_array_index(array
,i
)))->offset
=sum
;
1511 t_sort
.tsnumber
=((struct tsn_sort
*)(g_ptr_array_index(array
, i
)))->tsnumber
;
1512 if (t_sort
.tsnumber
>tsntmp
)
1513 sum
+=((struct tsn_sort
*)(g_ptr_array_index(array
, i
)))->length
;
1514 tsntmp
=t_sort
.tsnumber
;
1517 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
;
1518 u_data
->assoc
->sort_tsn2
=array
;
1522 void create_byte_graph(guint16 dir
, struct sctp_analyse
* userdata
)
1524 struct sctp_udata
*u_data
;
1526 u_data
=(struct sctp_udata
*)g_malloc(sizeof(struct sctp_udata
));
1527 u_data
->assoc
=(sctp_assoc_info_t
*)g_malloc(sizeof(sctp_assoc_info_t
));
1528 u_data
->assoc
=userdata
->assoc
;
1531 u_data
->parent
= userdata
;
1532 if ((u_data
->dir
==1 && (u_data
->assoc
->n_array_tsn1
==0))|| (u_data
->dir
==2 && (u_data
->assoc
->n_array_tsn2
==0)))
1533 simple_dialog(ESD_TYPE_INFO
, ESD_BTN_OK
, "No Data Chunks sent");
1536 set_child(u_data
, u_data
->parent
);
1537 increase_childcount(u_data
->parent
);
1538 compute_offsets(u_data
);
1539 set_arw_offsets(u_data
);
1540 gtk_sctpgraph_init(u_data
);