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.
37 #include "epan/filesystem.h"
39 #include "dlg_utils.h"
42 #include "compat_macros.h"
43 #include "simple_dialog.h"
44 #include "sctp_stat.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 60
59 #define RIGHT_BORDER 10
61 #define BOTTOM_BORDER 50
63 #define SUB_32(a, b) a-b
72 struct data_chunk_header {
82 struct init_chunk_header {
98 struct sack_chunk_header {
110 static gboolean label_set = FALSE;
111 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;
115 #if defined(_WIN32) && !defined(__MINGW32__)
116 static int rint (double ); /* compiler template for Windows */
119 static void draw_sack_graph(struct sctp_udata *u_data)
122 GList *list=NULL, *tlist;
123 guint16 gap_start=0, gap_end=0, i, j, nr;
127 GdkColor red_color = {0, 65535, 0, 0};
128 GdkColor green_color = {0, 0, 65535, 0};
129 GdkGC *red_gc, *green_gc;
130 struct sack_chunk_header *sack_header;
132 guint32 max_num, diff;
133 #if GTK_MAJOR_VERSION < 2
134 GdkColormap *colormap;
137 red_gc = gdk_gc_new(u_data->io->draw_area->window);
138 #if GTK_MAJOR_VERSION < 2
139 colormap = gtk_widget_get_colormap (u_data->io->draw_area);
140 if (!gdk_color_alloc (colormap, &red_color))
142 g_warning ("Couldn't allocate color");
145 gdk_gc_set_foreground(red_gc, &red_color);
147 gdk_gc_set_rgb_fg_color(red_gc, &red_color);
150 green_gc = gdk_gc_new(u_data->io->draw_area->window);
151 #if GTK_MAJOR_VERSION < 2
152 colormap = gtk_widget_get_colormap (u_data->io->draw_area);
153 if (!gdk_color_alloc (colormap, &green_color))
155 g_warning ("Couldn't allocate color");
158 gdk_gc_set_foreground(green_gc, &green_color);
160 gdk_gc_set_rgb_fg_color(green_gc, &green_color);
166 list = g_list_last(u_data->assoc->sack2);
167 if (u_data->io->tmp==FALSE)
169 min_tsn=u_data->assoc->min_tsn2;
170 max_tsn=u_data->assoc->max_tsn2;
174 min_tsn=u_data->assoc->min_tsn2+u_data->io->tmp_min_tsn2;
175 max_tsn=u_data->assoc->min_tsn2+u_data->io->tmp_max_tsn2;
178 else if (u_data->dir==1)
180 list = g_list_last(u_data->assoc->sack1);
181 if (u_data->io->tmp==FALSE)
183 min_tsn=u_data->assoc->min_tsn1;
184 max_tsn=u_data->assoc->max_tsn1;
188 min_tsn=u_data->assoc->min_tsn1+u_data->io->tmp_min_tsn1;
189 max_tsn=u_data->assoc->min_tsn1+u_data->io->tmp_max_tsn1;
195 sack = (tsn_t*) (list->data);
196 tlist = g_list_first(sack->tsns);
199 type = ((struct chunk_header *)tlist->data)->type;
201 if (type == SCTP_SACK_CHUNK_ID)
203 sack_header =(struct sack_chunk_header *)tlist->data;
204 nr=g_ntohs(sack_header->nr_of_gaps);
205 tsnumber = g_ntohl(sack_header->cum_tsn_ack);
207 if (sack->secs>=u_data->io->x1_tmp_sec)
211 gap = &sack_header->gaps[0];
214 gap_start=g_ntohs(gap->start);
215 gap_end = g_ntohs(gap->end);
216 max_num=gap_end+tsnumber;
217 for (j=gap_start; j<=gap_end; j++)
219 if (u_data->io->uoff)
220 diff = sack->secs - u_data->io->min_x;
222 diff=sack->secs*1000000+sack->usecs-u_data->io->min_x;
223 xvalue = (guint32)(LEFT_BORDER+u_data->io->offset+u_data->io->x_interval*diff);
224 yvalue = (guint32)(u_data->io->pixmap_height-BOTTOM_BORDER-POINT_SIZE-u_data->io->offset-((SUB_32(j+tsnumber,min_tsn))*u_data->io->y_interval));
225 if (xvalue >= LEFT_BORDER+u_data->io->offset &&
226 xvalue <= u_data->io->pixmap_width-RIGHT_BORDER+u_data->io->offset &&
227 yvalue >= TOP_BORDER-u_data->io->offset &&
228 yvalue <= u_data->io->pixmap_height-BOTTOM_BORDER-u_data->io->offset)
229 gdk_draw_arc(u_data->io->pixmap,green_gc,TRUE,
232 POINT_SIZE, POINT_SIZE,0, (64*360) );
240 if (tsnumber>=min_tsn)
242 if (u_data->io->uoff)
243 diff = sack->secs - u_data->io->min_x;
245 diff=sack->secs*1000000+sack->usecs-u_data->io->min_x;
246 xvalue = (guint32)(LEFT_BORDER+u_data->io->offset+u_data->io->x_interval*diff);
247 yvalue = (guint32)(u_data->io->pixmap_height-BOTTOM_BORDER-POINT_SIZE -u_data->io->offset-((SUB_32(tsnumber,min_tsn))*u_data->io->y_interval));
248 if (xvalue >= LEFT_BORDER+u_data->io->offset &&
249 xvalue <= u_data->io->pixmap_width-RIGHT_BORDER+u_data->io->offset &&
250 yvalue >= TOP_BORDER-u_data->io->offset &&
251 yvalue <= u_data->io->pixmap_height-BOTTOM_BORDER-u_data->io->offset)
252 gdk_draw_arc(u_data->io->pixmap,red_gc,TRUE,
255 POINT_SIZE, POINT_SIZE,0, (64*360) );
258 tlist = g_list_next(tlist);
261 list = g_list_previous(list);
263 #if GTK_MAJOR_VERSION >= 2
264 g_object_unref(G_OBJECT(red_gc));
265 g_object_unref(G_OBJECT(green_gc));
270 static void draw_tsn_graph(struct sctp_udata *u_data)
273 GList *list=NULL, *tlist;
276 guint32 min_secs=0, diff;
281 list = g_list_last(u_data->assoc->tsn1);
282 if (u_data->io->tmp==FALSE)
284 min_tsn=u_data->assoc->min_tsn1;
285 max_tsn=u_data->assoc->max_tsn1;
289 min_tsn=u_data->assoc->min_tsn1+u_data->io->tmp_min_tsn1;
290 max_tsn=u_data->assoc->min_tsn1+u_data->io->tmp_max_tsn1;
293 else if (u_data->dir==2)
295 list = g_list_last(u_data->assoc->tsn2);
296 if (u_data->io->tmp==FALSE)
298 min_tsn=u_data->assoc->min_tsn2;
299 max_tsn=u_data->assoc->max_tsn2;
303 min_tsn=u_data->assoc->min_tsn2+u_data->io->tmp_min_tsn2;
304 max_tsn=u_data->assoc->min_tsn2+u_data->io->tmp_max_tsn2;
310 tsn = (tsn_t*) (list->data);
311 tlist = g_list_first(tsn->tsns);
314 type = ((struct chunk_header *)tlist->data)->type;
315 if (type == SCTP_DATA_CHUNK_ID)
316 tsnumber = g_ntohl(((struct data_chunk_header *)tlist->data)->tsn);
317 if (tsnumber>=min_tsn && tsnumber<=max_tsn && tsn->secs>=min_secs)
319 if (u_data->io->uoff)
320 diff = tsn->secs - u_data->io->min_x;
322 diff=tsn->secs*1000000+tsn->usecs-u_data->io->min_x;
323 xvalue = (guint32)(LEFT_BORDER+u_data->io->offset+u_data->io->x_interval*diff);
324 yvalue = (guint32)(u_data->io->pixmap_height-BOTTOM_BORDER-POINT_SIZE-u_data->io->offset-((SUB_32(tsnumber,min_tsn))*u_data->io->y_interval));
325 if (xvalue >= LEFT_BORDER+u_data->io->offset &&
326 xvalue <= u_data->io->pixmap_width-RIGHT_BORDER+u_data->io->offset &&
327 yvalue >= TOP_BORDER-u_data->io->offset &&
328 yvalue <= u_data->io->pixmap_height-BOTTOM_BORDER-u_data->io->offset)
329 gdk_draw_arc(u_data->io->pixmap,u_data->io->draw_area->style->black_gc,TRUE,
332 POINT_SIZE, POINT_SIZE, 0, (64*360));
334 tlist = g_list_next(tlist);
336 list = g_list_previous(list);
341 static void sctp_graph_draw(struct sctp_udata *u_data)
344 guint32 distance=5, i, e, sec, w, start, a, b, j;
345 gint label_width, label_height;
346 char label_string[15];
348 gboolean write_label = FALSE;
350 #if GTK_MAJOR_VERSION < 2
356 if (u_data->io->x1_tmp_sec==0 && u_data->io->x1_tmp_usec==0)
357 u_data->io->offset=0;
359 u_data->io->offset=5;
361 if (u_data->io->x2_tmp_sec - u_data->io->x1_tmp_sec > 1500)
363 u_data->io->min_x=u_data->io->x1_tmp_sec;
364 u_data->io->max_x=u_data->io->x2_tmp_sec;
365 u_data->io->uoff = TRUE;
369 u_data->io->min_x=(guint32)(u_data->io->x1_tmp_sec*1000000.0+u_data->io->x1_tmp_usec);
370 u_data->io->max_x=(guint32)(u_data->io->x2_tmp_sec*1000000.0+u_data->io->x2_tmp_usec);
371 u_data->io->uoff = FALSE;
374 u_data->io->tmp_width=u_data->io->max_x-u_data->io->min_x;
378 if (u_data->io->tmp==FALSE)
380 if (u_data->assoc->tsn1!=NULL || u_data->assoc->sack1!=NULL)
381 u_data->io->max_y=u_data->io->tmp_max_tsn1 - u_data->io->tmp_min_tsn1;
383 u_data->io->max_y= 0;
384 u_data->io->min_y = 0;
388 u_data->io->max_y = u_data->io->tmp_max_tsn1;
389 u_data->io->min_y = u_data->io->tmp_min_tsn1;
392 else if (u_data->dir==2)
394 if (u_data->io->tmp==FALSE)
396 if (u_data->assoc->tsn2!=NULL || u_data->assoc->sack2!=NULL)
397 u_data->io->max_y=u_data->io->tmp_max_tsn2 -u_data->io->tmp_min_tsn2;
399 u_data->io->max_y= 0;
400 u_data->io->min_y = 0;
404 u_data->io->max_y = u_data->io->tmp_max_tsn2;
405 u_data->io->min_y = u_data->io->tmp_min_tsn2;
409 gdk_draw_rectangle(u_data->io->pixmap,
410 u_data->io->draw_area->style->white_gc,
413 u_data->io->draw_area->allocation.width,
414 u_data->io->draw_area->allocation.height);
418 gdk_draw_line(u_data->io->pixmap,u_data->io->draw_area->style->black_gc, LEFT_BORDER+u_data->io->offset,u_data->io->pixmap_height-BOTTOM_BORDER,u_data->io->pixmap_width-RIGHT_BORDER+u_data->io->offset, u_data->io->pixmap_height-BOTTOM_BORDER);
419 gdk_draw_line(u_data->io->pixmap,u_data->io->draw_area->style->black_gc,u_data->io->pixmap_width-RIGHT_BORDER+u_data->io->offset, u_data->io->pixmap_height-BOTTOM_BORDER, u_data->io->pixmap_width-RIGHT_BORDER+u_data->io->offset-5, u_data->io->pixmap_height-BOTTOM_BORDER-5);
420 gdk_draw_line(u_data->io->pixmap,u_data->io->draw_area->style->black_gc,u_data->io->pixmap_width-RIGHT_BORDER+u_data->io->offset, u_data->io->pixmap_height-BOTTOM_BORDER, u_data->io->pixmap_width-RIGHT_BORDER+u_data->io->offset-5, u_data->io->pixmap_height-BOTTOM_BORDER+5);
421 u_data->io->axis_width=u_data->io->pixmap_width-LEFT_BORDER-RIGHT_BORDER-u_data->io->offset;
423 /* try to avoid dividing by zero */
424 if(u_data->io->tmp_width>0){
425 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*/
427 u_data->io->x_interval = (float)(u_data->io->axis_width);
430 e=0; /*number of decimals of x_interval*/
431 if (u_data->io->x_interval<1)
433 dis=1/u_data->io->x_interval;
440 for (i=0; i<=e+1; i++)
441 distance*=10; /*distance per 100 pixels*/
446 #if GTK_MAJOR_VERSION < 2
447 font = u_data->io->draw_area->style->font;
450 #if GTK_MAJOR_VERSION < 2
451 label_width=gdk_string_width(font, label_string);
452 label_height=gdk_string_height(font, label_string);
454 g_snprintf(label_string, 15, "%d", 0);
455 memcpy(label_string,(gchar *)g_locale_to_utf8(label_string, -1 , NULL, NULL, NULL), 15);
456 layout = gtk_widget_create_pango_layout(u_data->io->draw_area, label_string);
457 pango_layout_get_pixel_size(layout, &label_width, &label_height);
461 if (u_data->io->x1_tmp_usec==0)
462 sec=u_data->io->x1_tmp_sec;
464 sec=u_data->io->x1_tmp_sec+1;
467 if (u_data->io->offset!=0)
469 g_snprintf(label_string, 15, "%u", u_data->io->x1_tmp_sec);
471 #if GTK_MAJOR_VERSION < 2
472 lwidth=gdk_string_width(font, label_string);
473 gdk_draw_string(u_data->io->pixmap,font,u_data->io->draw_area->style->black_gc,
475 u_data->io->pixmap_height-BOTTOM_BORDER+20,
478 memcpy(label_string,(gchar *)g_locale_to_utf8(label_string, -1 , NULL, NULL, NULL), 15);
479 pango_layout_set_text(layout, label_string, -1);
480 pango_layout_get_pixel_size(layout, &lwidth, NULL);
482 gdk_draw_layout(u_data->io->pixmap,u_data->io->draw_area->style->black_gc,
484 u_data->io->pixmap_height-BOTTOM_BORDER+20,
489 w=(guint32)(500/(guint32)(distance*u_data->io->x_interval)); /*there will be a label for every w_th tic*/
494 if (w==4 || w==3 || w==2)
497 a=distance/10; /*distance between two tics*/
498 b = (guint32)((u_data->io->min_x/100000))%10; /* start for labels*/
507 if (!u_data->io->uoff)
511 start=u_data->io->min_x/1000000*1000000;
517 start=u_data->io->min_x/100000;
521 b = (guint32)((start/100000))%10;
526 start = u_data->io->min_x;
533 for (i=start, j=b; i<=u_data->io->max_x; i+=a, j++)
535 if (!u_data->io->uoff)
536 if (i>=u_data->io->min_x && i%1000000!=0)
539 g_snprintf(label_string, 15, "%d", i%1000000);
544 #if GTK_MAJOR_VERSION < 2
545 lwidth=gdk_string_width(font, label_string);
546 gdk_draw_string(u_data->io->pixmap,font,u_data->io->draw_area->style->black_gc,
547 (guint32)(LEFT_BORDER+u_data->io->offset+(i-u_data->io->min_x)*u_data->io->x_interval-lwidth/2),
548 u_data->io->pixmap_height-BOTTOM_BORDER+10,
551 memcpy(label_string,(gchar *)g_locale_to_utf8(label_string, -1 , NULL, NULL, NULL), 15);
552 pango_layout_set_text(layout, label_string, -1);
553 pango_layout_get_pixel_size(layout, &lwidth, NULL);
554 gdk_draw_layout(u_data->io->pixmap,u_data->io->draw_area->style->black_gc,
555 (guint32)(LEFT_BORDER+u_data->io->offset+(i-u_data->io->min_x)*u_data->io->x_interval-lwidth/2),
556 u_data->io->pixmap_height-BOTTOM_BORDER+10,
560 gdk_draw_line(u_data->io->pixmap,u_data->io->draw_area->style->black_gc,
561 (guint32)(LEFT_BORDER+u_data->io->offset+(i-u_data->io->min_x)*u_data->io->x_interval),
562 u_data->io->pixmap_height-BOTTOM_BORDER,
563 (guint32)(LEFT_BORDER+u_data->io->offset+(i-u_data->io->min_x)*u_data->io->x_interval),
564 u_data->io->pixmap_height-BOTTOM_BORDER+length);
567 if (!u_data->io->uoff)
569 if (i%1000000==0 && j%w==0)
585 gdk_draw_line(u_data->io->pixmap,u_data->io->draw_area->style->black_gc,
586 (guint32)(LEFT_BORDER+u_data->io->offset+(i-u_data->io->min_x)*u_data->io->x_interval),
587 u_data->io->pixmap_height-BOTTOM_BORDER,
588 (guint32)(LEFT_BORDER+u_data->io->offset+(i-u_data->io->min_x)*u_data->io->x_interval),
589 u_data->io->pixmap_height-BOTTOM_BORDER+10);
591 g_snprintf(label_string, 15, "%d", sec);
592 #if GTK_MAJOR_VERSION < 2
593 lwidth=gdk_string_width(font, label_string);
594 gdk_draw_string(u_data->io->pixmap,font,u_data->io->draw_area->style->black_gc,
595 (guint32)(LEFT_BORDER+u_data->io->offset+(i-u_data->io->min_x)*u_data->io->x_interval-10),
596 u_data->io->pixmap_height-BOTTOM_BORDER+20,
599 memcpy(label_string,(gchar *)g_locale_to_utf8(label_string, -1 , NULL, NULL, NULL), 15);
600 pango_layout_set_text(layout, label_string, -1);
601 pango_layout_get_pixel_size(layout, &lwidth, NULL);
603 gdk_draw_layout(u_data->io->pixmap,u_data->io->draw_area->style->black_gc,
604 (guint32)(LEFT_BORDER+u_data->io->offset+(i-u_data->io->min_x)*u_data->io->x_interval-10),
605 u_data->io->pixmap_height-BOTTOM_BORDER+20,
613 strcpy(label_string, "sec");
615 #if GTK_MAJOR_VERSION < 2
616 lwidth=gdk_string_width(font, label_string);
617 gdk_draw_string(u_data->io->pixmap,
619 u_data->io->draw_area->style->black_gc,
620 u_data->io->pixmap_width-RIGHT_BORDER-10,
621 u_data->io->pixmap_height-BOTTOM_BORDER+30,
624 memcpy(label_string,(gchar *)g_locale_to_utf8(label_string, -1 , NULL, NULL, NULL), 15);
625 pango_layout_set_text(layout, label_string, -1);
626 pango_layout_get_pixel_size(layout, &lwidth, NULL);
627 gdk_draw_layout(u_data->io->pixmap,
628 u_data->io->draw_area->style->black_gc,
629 u_data->io->pixmap_width-RIGHT_BORDER-10,
630 u_data->io->pixmap_height-BOTTOM_BORDER+30,
637 gdk_draw_line(u_data->io->pixmap,u_data->io->draw_area->style->black_gc, LEFT_BORDER,TOP_BORDER-u_data->io->offset,LEFT_BORDER,u_data->io->pixmap_height-BOTTOM_BORDER-u_data->io->offset);
638 gdk_draw_line(u_data->io->pixmap,u_data->io->draw_area->style->black_gc,LEFT_BORDER,TOP_BORDER-u_data->io->offset, LEFT_BORDER-5, TOP_BORDER-u_data->io->offset+5);
639 gdk_draw_line(u_data->io->pixmap,u_data->io->draw_area->style->black_gc,LEFT_BORDER,TOP_BORDER-u_data->io->offset, LEFT_BORDER+5, TOP_BORDER-u_data->io->offset+5);
641 u_data->io->y_interval = (float)(((u_data->io->pixmap_height-TOP_BORDER-BOTTOM_BORDER)*1.0)/(u_data->io->max_y-u_data->io->min_y));
644 if (u_data->io->y_interval<1)
646 dis=1/u_data->io->y_interval;
654 distance=distance*10;
656 else if (u_data->io->y_interval<2)
659 if (u_data->io->max_y>0)
661 for (i=u_data->io->min_y/distance*distance; i<=u_data->io->max_y; i+=distance/5)
663 if (i>=u_data->io->min_y)
666 g_snprintf(label_string, 15, "%d", i);
667 if (i%distance==0 || (distance<=5 && u_data->io->y_interval>10))
671 #if GTK_MAJOR_VERSION < 2
672 lwidth=gdk_string_width(font, label_string);
673 gdk_draw_string(u_data->io->pixmap,font,u_data->io->draw_area->style->black_gc,
674 LEFT_BORDER-length-lwidth-5,
675 (guint32)(u_data->io->pixmap_height-BOTTOM_BORDER-u_data->io->offset-(i-u_data->io->min_y)*u_data->io->y_interval-POINT_SIZE),
678 memcpy(label_string,(gchar *)g_locale_to_utf8(label_string, -1 , NULL, NULL, NULL), 15);
679 pango_layout_set_text(layout, label_string, -1);
680 pango_layout_get_pixel_size(layout, &lwidth, NULL);
681 gdk_draw_layout(u_data->io->pixmap,u_data->io->draw_area->style->black_gc,
682 LEFT_BORDER-length-lwidth-5,
683 (guint32)(u_data->io->pixmap_height-BOTTOM_BORDER-u_data->io->offset-(i-u_data->io->min_y)*u_data->io->y_interval-POINT_SIZE),
687 gdk_draw_line(u_data->io->pixmap,u_data->io->draw_area->style->black_gc,LEFT_BORDER-length,
688 (guint32)(u_data->io->pixmap_height-BOTTOM_BORDER-u_data->io->offset-(i-u_data->io->min_y)*u_data->io->y_interval),
690 (guint32)(u_data->io->pixmap_height-BOTTOM_BORDER-u_data->io->offset-(i-u_data->io->min_y)*u_data->io->y_interval));
694 else if ((u_data->dir==1 && u_data->assoc->n_array_tsn1==0) || (u_data->dir==2 && u_data->assoc->n_array_tsn2==0))
695 simple_dialog(ESD_TYPE_INFO, ESD_BTN_OK, "No Data Chunks sent");
699 static void sctp_graph_redraw(struct sctp_udata *u_data)
703 u_data->io->needs_redraw=TRUE;
705 sctp_graph_draw(u_data);
706 switch (u_data->io->graph_type)
709 draw_sack_graph(u_data);
710 draw_tsn_graph(u_data);
713 draw_tsn_graph(u_data);
716 draw_sack_graph(u_data);
719 ios=(sctp_graph_t *)OBJECT_GET_DATA(u_data->io->draw_area, "sctp_graph_t");
726 gdk_draw_pixmap(u_data->io->draw_area->window,
727 u_data->io->draw_area->style->fg_gc[GTK_WIDGET_STATE(u_data->io->draw_area)],
731 u_data->io->draw_area->allocation.width,
732 u_data->io->draw_area->allocation.height);
736 static void on_sack_bt(GtkWidget *widget _U_, struct sctp_udata *u_data)
739 u_data = (struct sctp_udata *) u_data;
740 u_data->io->graph_type=2;
741 sctp_graph_redraw(u_data);
744 static void on_tsn_bt(GtkWidget *widget _U_, struct sctp_udata *u_data)
747 u_data->io->graph_type=1;
748 sctp_graph_redraw(u_data);
751 static void on_both_bt(GtkWidget *widget _U_, struct sctp_udata *u_data)
754 u_data->io->graph_type=0;
755 sctp_graph_redraw(u_data);
759 sctp_graph_close_cb(GtkWidget* widget _U_, gpointer u_data)
761 struct sctp_udata *udata;
764 udata = (struct sctp_udata *)u_data;
766 gtk_grab_remove(GTK_WIDGET(udata->io->window));
767 gtk_widget_destroy(GTK_WIDGET(udata->io->window));
772 configure_event(GtkWidget *widget, GdkEventConfigure *event _U_, struct sctp_udata *u_data)
778 if(u_data->io->pixmap){
779 gdk_pixmap_unref(u_data->io->pixmap);
780 u_data->io->pixmap=NULL;
783 u_data->io->pixmap=gdk_pixmap_new(widget->window,
784 widget->allocation.width,
785 widget->allocation.height,
787 u_data->io->pixmap_width=widget->allocation.width;
788 u_data->io->pixmap_height=widget->allocation.height;
790 gdk_draw_rectangle(u_data->io->pixmap,
791 widget->style->white_gc,
794 widget->allocation.width,
795 widget->allocation.height);
796 sctp_graph_redraw(u_data);
801 expose_event(GtkWidget *widget, GdkEventExpose *event)
805 ios=(sctp_graph_t *)OBJECT_GET_DATA(widget, "sctp_graph_t");
810 gdk_draw_pixmap(widget->window,
811 widget->style->fg_gc[GTK_WIDGET_STATE(widget)],
813 event->area.x, event->area.y,
814 event->area.x, event->area.y,
815 event->area.width, event->area.height);
822 on_zoomin_bt (GtkWidget *widget _U_, struct sctp_udata *u_data)
824 sctp_min_max_t *tmp_minmax;
826 if (u_data->io->rectangle_present==TRUE)
828 tmp_minmax = g_malloc(sizeof(sctp_min_max_t));
830 u_data->io->tmp_min_tsn1=u_data->io->y1_tmp+u_data->io->min_y;
831 u_data->io->tmp_max_tsn1=u_data->io->y2_tmp+1+u_data->io->min_y;
832 u_data->io->tmp_min_tsn2=u_data->io->tmp_min_tsn1;
833 u_data->io->tmp_max_tsn2=u_data->io->tmp_max_tsn1;
834 tmp_minmax->tmp_min_secs=u_data->io->x1_tmp_sec;
835 tmp_minmax->tmp_min_usecs= u_data->io->x1_tmp_usec;
836 tmp_minmax->tmp_max_secs= u_data->io->x2_tmp_sec;
837 tmp_minmax->tmp_max_usecs= u_data->io->x2_tmp_usec;
838 tmp_minmax->tmp_min_tsn1=u_data->io->tmp_min_tsn1;
839 tmp_minmax->tmp_max_tsn1=u_data->io->tmp_max_tsn1;
840 tmp_minmax->tmp_min_tsn2=u_data->io->tmp_min_tsn2;
841 tmp_minmax->tmp_max_tsn2=u_data->io->tmp_max_tsn2;
842 u_data->assoc->min_max = g_slist_prepend(u_data->assoc->min_max, tmp_minmax);
843 u_data->io->length = g_slist_length(u_data->assoc->min_max);
844 u_data->io->tmp=TRUE;
845 u_data->io->rectangle=FALSE;
846 u_data->io->rectangle_present=FALSE;
847 gtk_widget_set_sensitive(zoomout_bt, TRUE);
848 sctp_graph_redraw(u_data);
852 simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK, "Please draw a rectangle around the area you want to zoom in!");
857 zoomin_bt (struct sctp_udata *u_data)
859 sctp_min_max_t *tmp_minmax;
861 tmp_minmax = g_malloc(sizeof(sctp_min_max_t));
863 u_data->io->tmp_min_tsn1=u_data->io->y1_tmp+u_data->io->min_y;
864 u_data->io->tmp_max_tsn1=u_data->io->y2_tmp+1+u_data->io->min_y;
865 u_data->io->tmp_min_tsn2=u_data->io->tmp_min_tsn1;
866 u_data->io->tmp_max_tsn2=u_data->io->tmp_max_tsn1;
867 tmp_minmax->tmp_min_secs=u_data->io->x1_tmp_sec;
868 tmp_minmax->tmp_min_usecs= u_data->io->x1_tmp_usec;
869 tmp_minmax->tmp_max_secs= u_data->io->x2_tmp_sec;
870 tmp_minmax->tmp_max_usecs= u_data->io->x2_tmp_usec;
871 tmp_minmax->tmp_min_tsn1=u_data->io->tmp_min_tsn1;
872 tmp_minmax->tmp_max_tsn1=u_data->io->tmp_max_tsn1;
873 tmp_minmax->tmp_min_tsn2=u_data->io->tmp_min_tsn2;
874 tmp_minmax->tmp_max_tsn2=u_data->io->tmp_max_tsn2;
875 u_data->assoc->min_max = g_slist_prepend(u_data->assoc->min_max, tmp_minmax);
876 u_data->io->length = g_slist_length(u_data->assoc->min_max);
877 u_data->io->tmp=TRUE;
878 u_data->io->rectangle=FALSE;
879 u_data->io->rectangle_present=FALSE;
880 gtk_widget_set_sensitive(zoomout_bt, TRUE);
881 sctp_graph_redraw(u_data);
888 on_zoomout_bt (GtkWidget *widget _U_, struct sctp_udata *u_data)
890 sctp_min_max_t *tmp_minmax, *mm;
893 l = g_slist_length(u_data->assoc->min_max);
895 if (u_data->assoc->min_max!=NULL)
897 mm=(sctp_min_max_t *)((u_data->assoc->min_max)->data);
898 u_data->assoc->min_max=g_slist_remove(u_data->assoc->min_max, mm);
902 tmp_minmax = (sctp_min_max_t *)u_data->assoc->min_max->data;
903 u_data->io->x1_tmp_sec=tmp_minmax->tmp_min_secs;
904 u_data->io->x1_tmp_usec=tmp_minmax->tmp_min_usecs;
905 u_data->io->x2_tmp_sec=tmp_minmax->tmp_max_secs;
906 u_data->io->x2_tmp_usec=tmp_minmax->tmp_max_usecs;
907 u_data->io->tmp_min_tsn1=tmp_minmax->tmp_min_tsn1;
908 u_data->io->tmp_max_tsn1=tmp_minmax->tmp_max_tsn1;
909 u_data->io->tmp_min_tsn2=tmp_minmax->tmp_min_tsn2;
910 u_data->io->tmp_max_tsn2=tmp_minmax->tmp_max_tsn2;
911 u_data->io->tmp=TRUE;
915 u_data->io->x1_tmp_sec=u_data->assoc->min_secs;
916 u_data->io->x1_tmp_usec=u_data->assoc->min_usecs;
917 u_data->io->x2_tmp_sec=u_data->assoc->max_secs;
918 u_data->io->x2_tmp_usec=u_data->assoc->max_usecs;
919 u_data->io->tmp_min_tsn1=u_data->assoc->min_tsn1;
920 u_data->io->tmp_max_tsn1=u_data->assoc->max_tsn1;
921 u_data->io->tmp_min_tsn2=u_data->assoc->min_tsn2;
922 u_data->io->tmp_max_tsn2=u_data->assoc->max_tsn2;
923 u_data->io->tmp=FALSE;
928 u_data->io->x1_tmp_sec=u_data->assoc->min_secs;
929 u_data->io->x1_tmp_usec=u_data->assoc->min_usecs;
930 u_data->io->x2_tmp_sec=u_data->assoc->max_secs;
931 u_data->io->x2_tmp_usec=u_data->assoc->max_usecs;
932 u_data->io->tmp_min_tsn1=u_data->assoc->min_tsn1;
933 u_data->io->tmp_max_tsn1=u_data->assoc->max_tsn1;
934 u_data->io->tmp_min_tsn2=u_data->assoc->min_tsn2;
935 u_data->io->tmp_max_tsn2=u_data->assoc->max_tsn2;
936 u_data->io->tmp=FALSE;
938 if (g_slist_length(u_data->assoc->min_max)==1)
939 gtk_widget_set_sensitive(zoomout_bt, FALSE);
940 sctp_graph_redraw(u_data);
944 on_button_press (GtkWidget *widget _U_, GdkEventButton *event, struct sctp_udata *u_data)
948 if (u_data->io->rectangle==TRUE)
950 gdk_draw_rectangle(u_data->io->pixmap,u_data->io->draw_area->style->white_gc,
952 (gint)floor(MIN(u_data->io->x_old,u_data->io->x_new)),
953 (gint)floor(MIN(u_data->io->y_old,u_data->io->y_new)),
954 (gint)floor(abs((long)(u_data->io->x_new-u_data->io->x_old))),
955 (gint)floor(abs((long)(u_data->io->y_new-u_data->io->y_old))));
956 ios=(sctp_graph_t *)OBJECT_GET_DATA(u_data->io->draw_area, "sctp_graph_t");
962 gdk_draw_pixmap(u_data->io->draw_area->window,
963 u_data->io->draw_area->style->fg_gc[GTK_WIDGET_STATE(u_data->io->draw_area)],
967 (gint)(abs((long)(u_data->io->x_new-u_data->io->x_old))),
968 (gint)(abs((long)(u_data->io->y_new-u_data->io->y_old))));
969 sctp_graph_redraw(u_data);
971 u_data->io->x_old=event->x;
972 u_data->io->y_old=event->y;
973 if (u_data->io->y_old>u_data->io->pixmap_height-BOTTOM_BORDER-u_data->io->offset-POINT_SIZE)
974 u_data->io->y_old=u_data->io->pixmap_height-BOTTOM_BORDER-u_data->io->offset-POINT_SIZE;
975 if (u_data->io->x_old<LEFT_BORDER+u_data->io->offset)
976 u_data->io->x_old=LEFT_BORDER+u_data->io->offset;
977 u_data->io->rectangle=FALSE;
984 on_button_release (GtkWidget *widget _U_, GdkEventButton *event, struct sctp_udata *u_data)
987 guint32 helpx, helpy, x1_tmp, x2_tmp, y_value, t_size=0, s_size=0, i, y_tolerance;
988 gint label_width, label_height;
989 gdouble x_value, position, s_diff=0, t_diff=0, x_tolerance=0.0001;
991 char label_string[30];
993 GPtrArray *tsnlist = NULL, *sacklist=NULL;
994 struct tsn_sort *tsn, *sack=NULL;
995 gboolean sack_found = FALSE;
997 #if GTK_MAJOR_VERSION < 2
1000 PangoLayout *layout;
1003 #if GTK_MAJOR_VERSION < 2
1004 font = u_data->io->draw_area->style->font;
1007 #if GTK_MAJOR_VERSION < 2
1008 label_width=gdk_string_width(font, label_string);
1009 label_height=gdk_string_height(font, label_string);
1011 g_snprintf(label_string, 15, "%d", 0);
1012 memcpy(label_string,(gchar *)g_locale_to_utf8(label_string, -1 , NULL, NULL, NULL), 15);
1013 layout = gtk_widget_create_pango_layout(u_data->io->draw_area, label_string);
1014 pango_layout_get_pixel_size(layout, &label_width, &label_height);
1018 if (event->y>u_data->io->pixmap_height-BOTTOM_BORDER-u_data->io->offset)
1019 event->y = u_data->io->pixmap_height-BOTTOM_BORDER-u_data->io->offset;
1020 if (event->x < LEFT_BORDER+u_data->io->offset)
1021 event->x = LEFT_BORDER+u_data->io->offset;
1022 if (abs((long)(event->x-u_data->io->x_old))>10 || abs((long)(event->y-u_data->io->y_old))>10)
1024 u_data->io->rect_x_min = (gint)floor(MIN(u_data->io->x_old,event->x));
1025 u_data->io->rect_x_max = (gint)ceil(MAX(u_data->io->x_old,event->x));
1026 u_data->io->rect_y_min = (gint)floor(MIN(u_data->io->y_old,event->y));
1027 u_data->io->rect_y_max = (gint)ceil(MAX(u_data->io->y_old,event->y))+POINT_SIZE;
1028 gdk_draw_rectangle(u_data->io->pixmap,u_data->io->draw_area->style->black_gc,
1030 u_data->io->rect_x_min, u_data->io->rect_y_min,
1031 u_data->io->rect_x_max - u_data->io->rect_x_min,
1032 u_data->io->rect_y_max - u_data->io->rect_y_min);
1033 ios=(sctp_graph_t *)OBJECT_GET_DATA(u_data->io->draw_area, "sctp_graph_t");
1039 gdk_draw_pixmap(u_data->io->draw_area->window,
1040 u_data->io->draw_area->style->fg_gc[GTK_WIDGET_STATE(u_data->io->draw_area)],
1044 u_data->io->draw_area->allocation.width,
1045 u_data->io->draw_area->allocation.height);
1047 x1_tmp=(unsigned int)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));
1048 x2_tmp=(unsigned int)floor(u_data->io->min_x+((event->x-LEFT_BORDER-u_data->io->offset)*u_data->io->tmp_width/u_data->io->axis_width));
1049 helpx=MIN(x1_tmp, x2_tmp);
1055 if (u_data->io->uoff)
1057 if (x2_tmp - x1_tmp <= 1500)
1058 u_data->io->uoff = FALSE;
1059 u_data->io->x1_tmp_sec=(guint32)x1_tmp;
1060 u_data->io->x1_tmp_usec=0;
1061 u_data->io->x2_tmp_sec=(guint32)x2_tmp;
1062 u_data->io->x2_tmp_usec=0;
1066 u_data->io->x1_tmp_sec=(guint32)x1_tmp/1000000;
1067 u_data->io->x1_tmp_usec=x1_tmp%1000000;
1068 u_data->io->x2_tmp_sec=(guint32)x2_tmp/1000000;
1069 u_data->io->x2_tmp_usec=x2_tmp%1000000;
1071 u_data->io->x1_akt_sec = u_data->io->x1_tmp_sec;
1072 u_data->io->x1_akt_usec = u_data->io->x1_tmp_usec;
1073 u_data->io->x2_akt_sec = u_data->io->x2_tmp_sec;
1074 u_data->io->x2_akt_usec = u_data->io->x2_tmp_usec;
1076 u_data->io->y1_tmp=(guint32)((u_data->io->pixmap_height-BOTTOM_BORDER-u_data->io->offset-u_data->io->y_old)/u_data->io->y_interval);
1077 u_data->io->y2_tmp=(guint32)((u_data->io->pixmap_height-BOTTOM_BORDER-u_data->io->offset-event->y)/u_data->io->y_interval);
1078 helpy = MIN(u_data->io->y1_tmp, u_data->io->y2_tmp);
1079 u_data->io->y2_tmp = MAX(u_data->io->y1_tmp, u_data->io->y2_tmp);
1080 u_data->io->y1_tmp = helpy;
1081 u_data->io->x_new=event->x;
1082 u_data->io->y_new=event->y;
1083 u_data->io->rectangle=TRUE;
1084 u_data->io->rectangle_present=TRUE;
1088 if (u_data->io->rectangle_present==TRUE)
1090 u_data->io->rectangle_present=FALSE;
1091 if (event->x >= u_data->io->rect_x_min && event->x <= u_data->io->rect_x_max &&
1092 event->y >= u_data->io->rect_y_min && event->y <= u_data->io->rect_y_max)
1096 u_data->io->x1_tmp_sec = u_data->io->x1_akt_sec;
1097 u_data->io->x1_tmp_usec = u_data->io->x1_akt_usec;
1098 u_data->io->x2_tmp_sec = u_data->io->x2_akt_sec;
1099 u_data->io->x2_tmp_usec = u_data->io->x2_akt_usec;
1100 sctp_graph_redraw(u_data);
1106 sctp_graph_redraw(u_data);
1110 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->pixmap_width-LEFT_BORDER-RIGHT_BORDER-u_data->io->offset))+u_data->io->x1_tmp_sec+u_data->io->x1_tmp_usec/1000000.0;
1111 y_value = (gint)rint((u_data->io->pixmap_height-BOTTOM_BORDER-u_data->io->offset-event->y) * (max_tsn - min_tsn) / (u_data->io->pixmap_height-BOTTOM_BORDER-u_data->io->offset)) + min_tsn;
1112 text_color = u_data->io->draw_area->style->black_gc;
1114 if (u_data->dir == 1)
1116 tsnlist = u_data->assoc->sort_tsn1;
1117 t_size = u_data->assoc->n_data_chunks_ep1;
1118 sacklist = u_data->assoc->sort_sack1;
1119 s_size = u_data->assoc->n_sack_chunks_ep1;
1123 tsnlist = u_data->assoc->sort_tsn2;
1124 t_size = u_data->assoc->n_data_chunks_ep2;
1125 sacklist = u_data->assoc->sort_sack2;
1126 s_size = u_data->assoc->n_sack_chunks_ep2;
1128 x_tolerance = (gdouble)((u_data->io->tmp_width / u_data->io->axis_width*1.0))*5/1000000.0;
1129 y_tolerance = (guint32)(((u_data->io->max_y - u_data->io->min_y) / (u_data->io->pixmap_height-TOP_BORDER-BOTTOM_BORDER-u_data->io->offset)) * 2.0);
1132 else if (y_tolerance > 5)
1135 for (i=0; i<s_size; i++)
1137 sack = (struct tsn_sort*)(g_ptr_array_index(sacklist, i));
1138 if ((guint32)abs(sack->tsnumber - y_value)<y_tolerance)
1140 s_diff = fabs((sack->secs+sack->usecs/1000000.0)- x_value);
1141 if (s_diff < x_tolerance)
1147 for (i=0; i<t_size; i++)
1149 tsn = (struct tsn_sort*)(g_ptr_array_index(tsnlist, i));
1150 if ((guint32)abs(tsn->tsnumber - y_value)<y_tolerance)
1152 t_diff = fabs((tsn->secs+tsn->usecs/1000000.0)- x_value);
1153 if (sack_found && s_diff < t_diff)
1155 cf_goto_frame(&cfile, sack->framenumber);
1156 x_value = sack->secs+sack->usecs/1000000.0;
1157 y_value = sack->tsnumber;
1159 else if (t_diff < x_tolerance)
1161 cf_goto_frame(&cfile, tsn->framenumber);
1162 x_value = tsn->secs+tsn->usecs/1000000.0;
1163 y_value = tsn->tsnumber;
1169 g_snprintf(label_string, 30, "(%.6lf, %u)", x_value, y_value);
1173 gdk_draw_line(u_data->io->pixmap,text_color, (gint)(event->x-2), (gint)(event->y), (gint)(event->x+2), (gint)(event->y));
1174 gdk_draw_line(u_data->io->pixmap,text_color, (gint)(event->x), (gint)(event->y-2), (gint)(event->x), (gint)(event->y+2));
1175 if (event->x+150>=u_data->io->pixmap_width)
1176 position = event->x - 150;
1178 position = event->x + 5;
1181 #if GTK_MAJOR_VERSION < 2
1182 lwidth=gdk_string_width(font, label_string);
1183 gdk_draw_string(u_data->io->pixmap,font,text_color,
1185 (gint)(event->y-10),
1188 memcpy(label_string,(gchar *)g_locale_to_utf8(label_string, -1 , NULL, NULL, NULL), 15);
1189 pango_layout_set_text(layout, label_string, -1);
1190 pango_layout_get_pixel_size(layout, &lwidth, NULL);
1192 gdk_draw_layout(u_data->io->pixmap,text_color,
1194 (gint)(event->y-10),
1198 ios=(sctp_graph_t *)OBJECT_GET_DATA(u_data->io->draw_area, "sctp_graph_t");
1203 gdk_draw_pixmap(u_data->io->draw_area->window,
1204 u_data->io->draw_area->style->fg_gc[GTK_WIDGET_STATE(u_data->io->draw_area)],
1208 u_data->io->draw_area->allocation.width,
1209 u_data->io->draw_area->allocation.height);
1216 static void init_sctp_graph_window(struct sctp_udata *u_data)
1220 GtkWidget *bt_close, *sack_bt, *tsn_bt, *both_bt, *zoomin_bt;
1221 GtkTooltips *tooltip_in, *tooltip_out;
1223 /* create the main window */
1225 u_data->io->window=gtk_window_new(GTK_WINDOW_TOPLEVEL);
1227 gtk_widget_set_name(u_data->io->window, "SCTP Graphics");
1229 vbox=gtk_vbox_new(FALSE, 0);
1230 gtk_container_add(GTK_CONTAINER(u_data->io->window), vbox);
1231 gtk_widget_show(vbox);
1233 create_draw_area(vbox, u_data);
1235 sctp_graph_set_title(u_data);
1237 hbox = gtk_hbutton_box_new();
1238 gtk_box_pack_start(GTK_BOX(vbox), hbox, FALSE, FALSE, 0);
1239 gtk_container_set_border_width(GTK_CONTAINER(hbox), 10);
1240 gtk_button_box_set_layout(GTK_BUTTON_BOX (hbox), GTK_BUTTONBOX_SPREAD);
1241 gtk_button_box_set_spacing(GTK_BUTTON_BOX (hbox), 0);
1242 gtk_box_set_child_packing(GTK_BOX(vbox), hbox, FALSE, FALSE, 0, GTK_PACK_START);
1243 gtk_widget_show(hbox);
1245 sack_bt = gtk_button_new_with_label ("Show Sacks");
1246 gtk_box_pack_start(GTK_BOX(hbox), sack_bt, FALSE, FALSE, 0);
1247 gtk_widget_show(sack_bt);
1249 gtk_signal_connect(GTK_OBJECT(sack_bt), "clicked", (GtkSignalFunc)on_sack_bt, u_data);
1251 tsn_bt = gtk_button_new_with_label ("Show TSNs");
1252 gtk_box_pack_start(GTK_BOX(hbox), tsn_bt, FALSE, FALSE, 0);
1253 gtk_widget_show(tsn_bt);
1254 SIGNAL_CONNECT(tsn_bt, "clicked", on_tsn_bt, u_data);
1256 both_bt = gtk_button_new_with_label ("Show both");
1257 gtk_box_pack_start(GTK_BOX(hbox), both_bt, FALSE, FALSE, 0);
1258 gtk_widget_show(both_bt);
1259 SIGNAL_CONNECT(both_bt, "clicked", on_both_bt, u_data);
1261 zoomin_bt = gtk_button_new_with_label ("Zoom in");
1262 gtk_box_pack_start(GTK_BOX(hbox), zoomin_bt, FALSE, FALSE, 0);
1263 gtk_widget_show(zoomin_bt);
1264 SIGNAL_CONNECT(zoomin_bt, "clicked", on_zoomin_bt, u_data);
1265 tooltip_in = gtk_tooltips_new();
1266 gtk_tooltips_set_tip(tooltip_in, zoomin_bt, "Zoom in the area you have selected", NULL);
1268 zoomout_bt = gtk_button_new_with_label ("Zoom out");
1269 gtk_box_pack_start(GTK_BOX(hbox), zoomout_bt, FALSE, FALSE, 0);
1270 gtk_widget_show(zoomout_bt);
1271 SIGNAL_CONNECT(zoomout_bt, "clicked", on_zoomout_bt, u_data);
1272 tooltip_out = gtk_tooltips_new();
1273 gtk_tooltips_set_tip(tooltip_out, zoomout_bt, "Zoom out one step", NULL);
1274 gtk_widget_set_sensitive(zoomout_bt, FALSE);
1276 bt_close = BUTTON_NEW_FROM_STOCK(GTK_STOCK_CLOSE);
1277 gtk_box_pack_start(GTK_BOX(hbox), bt_close, FALSE, FALSE, 0);
1278 gtk_widget_show(bt_close);
1279 SIGNAL_CONNECT(bt_close, "clicked", sctp_graph_close_cb, u_data);
1281 gtk_signal_connect(GTK_OBJECT(u_data->io->draw_area),"button_press_event",(GtkSignalFunc)on_button_press, u_data);
1282 gtk_signal_connect(GTK_OBJECT(u_data->io->draw_area),"button_release_event",(GtkSignalFunc)on_button_release, u_data);
1283 gtk_widget_set_events(u_data->io->draw_area, GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK | GDK_EXPOSURE_MASK);
1285 gtk_widget_show(u_data->io->window);
1288 static void sctp_graph_set_title(struct sctp_udata *u_data)
1292 if(!u_data->io->window)
1296 title = g_strdup_printf("SCTP TSNs and Sacks over Time: %s Port1 %u Port2 %u Endpoint %u",
1297 cf_get_display_name(&cfile), u_data->parent->assoc->port1, u_data->parent->assoc->port2, u_data->dir);
1298 gtk_window_set_title(GTK_WINDOW(u_data->io->window), title);
1303 gtk_sctpgraph_init(struct sctp_udata *u_data)
1307 sctp_min_max_t* tmp_minmax;
1309 io=g_malloc(sizeof(sctp_graph_t));
1310 io->needs_redraw=TRUE;
1311 io->x_interval=1000;
1315 io->pixmap_width=800;
1316 io->pixmap_height=600;
1320 u_data->io->x1_tmp_sec=u_data->assoc->min_secs;
1321 u_data->io->x1_tmp_usec=u_data->assoc->min_usecs;
1322 u_data->io->x2_tmp_sec=u_data->assoc->max_secs;
1323 u_data->io->x2_tmp_usec=u_data->assoc->max_usecs;
1324 u_data->io->tmp_min_tsn1=u_data->assoc->min_tsn1;
1325 u_data->io->tmp_max_tsn1=u_data->assoc->max_tsn1;
1326 u_data->io->tmp_min_tsn2=u_data->assoc->min_tsn2;
1327 u_data->io->tmp_max_tsn2=u_data->assoc->max_tsn2;
1328 u_data->io->tmp=FALSE;
1330 tmp_minmax = g_malloc(sizeof(sctp_min_max_t));
1331 tmp_minmax->tmp_min_secs = u_data->assoc->min_secs;
1332 tmp_minmax->tmp_min_usecs=u_data->assoc->min_usecs;
1333 tmp_minmax->tmp_max_secs=u_data->assoc->max_secs;
1334 tmp_minmax->tmp_max_usecs=u_data->assoc->max_usecs;
1335 tmp_minmax->tmp_min_tsn2=u_data->assoc->min_tsn2;
1336 tmp_minmax->tmp_min_tsn1=u_data->assoc->min_tsn1;
1337 tmp_minmax->tmp_max_tsn1=u_data->assoc->max_tsn1;
1338 tmp_minmax->tmp_max_tsn2=u_data->assoc->max_tsn2;
1339 u_data->assoc->min_max = g_slist_prepend(u_data->assoc->min_max, tmp_minmax);
1342 init_sctp_graph_window(u_data);
1343 sctp_graph_redraw(u_data);
1349 quit(GtkObject *object _U_, gpointer user_data)
1351 struct sctp_udata *u_data=(struct sctp_udata*)user_data;
1353 decrease_childcount(u_data->parent);
1354 remove_child(u_data, u_data->parent);
1358 u_data->assoc->min_max = NULL;
1364 static void create_draw_area(GtkWidget *box, struct sctp_udata *u_data)
1367 u_data->io->draw_area=gtk_drawing_area_new();
1368 SIGNAL_CONNECT(u_data->io->draw_area, "destroy", quit, u_data);
1369 OBJECT_SET_DATA(u_data->io->draw_area, "sctp_graph_t", u_data->io);
1371 WIDGET_SET_SIZE(u_data->io->draw_area, u_data->io->pixmap_width, u_data->io->pixmap_height);
1373 /* signals needed to handle backing pixmap */
1374 SIGNAL_CONNECT(u_data->io->draw_area, "expose_event", expose_event, NULL);
1375 SIGNAL_CONNECT(u_data->io->draw_area, "configure_event", configure_event, u_data);
1377 gtk_widget_show(u_data->io->draw_area);
1378 gtk_box_pack_start(GTK_BOX(box), u_data->io->draw_area, TRUE, TRUE, 0);
1383 void create_graph(guint16 dir, struct sctp_analyse* userdata)
1385 struct sctp_udata *u_data;
1387 u_data=g_malloc(sizeof(struct sctp_udata));
1388 u_data->assoc=g_malloc(sizeof(sctp_assoc_info_t));
1389 u_data->assoc=userdata->assoc;
1392 u_data->parent = userdata;
1393 if ((u_data->dir==1 && u_data->assoc->n_array_tsn1==0)|| (u_data->dir==2 && u_data->assoc->n_array_tsn2==0))
1394 simple_dialog(ESD_TYPE_INFO, ESD_BTN_OK, "No Data Chunks sent");
1397 set_child(u_data, u_data->parent);
1398 increase_childcount(u_data->parent);
1399 gtk_sctpgraph_init(u_data);
1403 #if defined(_WIN32) && !defined(__MINGW32__)
1404 /* replacement of Unix rint() for Windows */
1405 static int rint (double x)
1410 buf = _fcvt(x, 0, &dec, &sig);