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"
45 #include <epan/strutil.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 60
60 #define RIGHT_BORDER 10
62 #define BOTTOM_BORDER 50
64 #define SUB_32(a, b) a-b
73 struct data_chunk_header {
83 struct init_chunk_header {
99 struct sack_chunk_header {
111 static gboolean label_set = FALSE;
112 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;
116 #if defined(_WIN32) && !defined(__MINGW32__)
117 static int rint (double ); /* compiler template for Windows */
120 static void draw_sack_graph(struct sctp_udata *u_data)
123 GList *list=NULL, *tlist;
124 guint16 gap_start=0, gap_end=0, i, j, nr;
128 GdkColor red_color = {0, 65535, 0, 0};
129 GdkColor green_color = {0, 0, 65535, 0};
130 GdkGC *red_gc, *green_gc;
131 struct sack_chunk_header *sack_header;
133 guint32 max_num, diff;
135 red_gc = gdk_gc_new(u_data->io->draw_area->window);
136 gdk_gc_set_rgb_fg_color(red_gc, &red_color);
138 green_gc = gdk_gc_new(u_data->io->draw_area->window);
139 gdk_gc_set_rgb_fg_color(green_gc, &green_color);
144 list = g_list_last(u_data->assoc->sack2);
145 if (u_data->io->tmp==FALSE)
147 min_tsn=u_data->assoc->min_tsn2;
148 max_tsn=u_data->assoc->max_tsn2;
152 min_tsn=u_data->assoc->min_tsn2+u_data->io->tmp_min_tsn2;
153 max_tsn=u_data->assoc->min_tsn2+u_data->io->tmp_max_tsn2;
156 else if (u_data->dir==1)
158 list = g_list_last(u_data->assoc->sack1);
159 if (u_data->io->tmp==FALSE)
161 min_tsn=u_data->assoc->min_tsn1;
162 max_tsn=u_data->assoc->max_tsn1;
166 min_tsn=u_data->assoc->min_tsn1+u_data->io->tmp_min_tsn1;
167 max_tsn=u_data->assoc->min_tsn1+u_data->io->tmp_max_tsn1;
173 sack = (tsn_t*) (list->data);
174 tlist = g_list_first(sack->tsns);
177 type = ((struct chunk_header *)tlist->data)->type;
179 if (type == SCTP_SACK_CHUNK_ID)
181 sack_header =(struct sack_chunk_header *)tlist->data;
182 nr=g_ntohs(sack_header->nr_of_gaps);
183 tsnumber = g_ntohl(sack_header->cum_tsn_ack);
185 if (sack->secs>=u_data->io->x1_tmp_sec)
189 gap = &sack_header->gaps[0];
192 gap_start=g_ntohs(gap->start);
193 gap_end = g_ntohs(gap->end);
194 max_num=gap_end+tsnumber;
195 for (j=gap_start; j<=gap_end; j++)
197 if (u_data->io->uoff)
198 diff = sack->secs - u_data->io->min_x;
200 diff=sack->secs*1000000+sack->usecs-u_data->io->min_x;
201 xvalue = (guint32)(LEFT_BORDER+u_data->io->offset+u_data->io->x_interval*diff);
202 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));
203 if (xvalue >= LEFT_BORDER+u_data->io->offset &&
204 xvalue <= u_data->io->pixmap_width-RIGHT_BORDER+u_data->io->offset &&
205 yvalue >= TOP_BORDER-u_data->io->offset &&
206 yvalue <= u_data->io->pixmap_height-BOTTOM_BORDER-u_data->io->offset)
207 gdk_draw_arc(u_data->io->pixmap,green_gc,TRUE,
210 POINT_SIZE, POINT_SIZE,0, (64*360) );
218 if (tsnumber>=min_tsn)
220 if (u_data->io->uoff)
221 diff = sack->secs - u_data->io->min_x;
223 diff=sack->secs*1000000+sack->usecs-u_data->io->min_x;
224 xvalue = (guint32)(LEFT_BORDER+u_data->io->offset+u_data->io->x_interval*diff);
225 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));
226 if (xvalue >= LEFT_BORDER+u_data->io->offset &&
227 xvalue <= u_data->io->pixmap_width-RIGHT_BORDER+u_data->io->offset &&
228 yvalue >= TOP_BORDER-u_data->io->offset &&
229 yvalue <= u_data->io->pixmap_height-BOTTOM_BORDER-u_data->io->offset)
230 gdk_draw_arc(u_data->io->pixmap,red_gc,TRUE,
233 POINT_SIZE, POINT_SIZE,0, (64*360) );
236 tlist = g_list_next(tlist);
239 list = g_list_previous(list);
241 g_object_unref(G_OBJECT(red_gc));
242 g_object_unref(G_OBJECT(green_gc));
246 static void draw_tsn_graph(struct sctp_udata *u_data)
249 GList *list=NULL, *tlist;
252 guint32 min_secs=0, diff;
257 list = g_list_last(u_data->assoc->tsn1);
258 if (u_data->io->tmp==FALSE)
260 min_tsn=u_data->assoc->min_tsn1;
261 max_tsn=u_data->assoc->max_tsn1;
265 min_tsn=u_data->assoc->min_tsn1+u_data->io->tmp_min_tsn1;
266 max_tsn=u_data->assoc->min_tsn1+u_data->io->tmp_max_tsn1;
269 else if (u_data->dir==2)
271 list = g_list_last(u_data->assoc->tsn2);
272 if (u_data->io->tmp==FALSE)
274 min_tsn=u_data->assoc->min_tsn2;
275 max_tsn=u_data->assoc->max_tsn2;
279 min_tsn=u_data->assoc->min_tsn2+u_data->io->tmp_min_tsn2;
280 max_tsn=u_data->assoc->min_tsn2+u_data->io->tmp_max_tsn2;
286 tsn = (tsn_t*) (list->data);
287 tlist = g_list_first(tsn->tsns);
290 type = ((struct chunk_header *)tlist->data)->type;
291 if (type == SCTP_DATA_CHUNK_ID)
292 tsnumber = g_ntohl(((struct data_chunk_header *)tlist->data)->tsn);
293 if (tsnumber>=min_tsn && tsnumber<=max_tsn && tsn->secs>=min_secs)
295 if (u_data->io->uoff)
296 diff = tsn->secs - u_data->io->min_x;
298 diff=tsn->secs*1000000+tsn->usecs-u_data->io->min_x;
299 xvalue = (guint32)(LEFT_BORDER+u_data->io->offset+u_data->io->x_interval*diff);
300 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));
301 if (xvalue >= LEFT_BORDER+u_data->io->offset &&
302 xvalue <= u_data->io->pixmap_width-RIGHT_BORDER+u_data->io->offset &&
303 yvalue >= TOP_BORDER-u_data->io->offset &&
304 yvalue <= u_data->io->pixmap_height-BOTTOM_BORDER-u_data->io->offset)
305 gdk_draw_arc(u_data->io->pixmap,u_data->io->draw_area->style->black_gc,TRUE,
308 POINT_SIZE, POINT_SIZE, 0, (64*360));
310 tlist = g_list_next(tlist);
312 list = g_list_previous(list);
317 static void sctp_graph_draw(struct sctp_udata *u_data)
320 guint32 distance=5, i, e, sec, w, start, a, b, j;
321 gint label_width, label_height;
322 char label_string[15];
324 gboolean write_label = FALSE;
327 if (u_data->io->x1_tmp_sec==0 && u_data->io->x1_tmp_usec==0)
328 u_data->io->offset=0;
330 u_data->io->offset=5;
332 if (u_data->io->x2_tmp_sec - u_data->io->x1_tmp_sec > 1500)
334 u_data->io->min_x=u_data->io->x1_tmp_sec;
335 u_data->io->max_x=u_data->io->x2_tmp_sec;
336 u_data->io->uoff = TRUE;
340 u_data->io->min_x=(guint32)(u_data->io->x1_tmp_sec*1000000.0+u_data->io->x1_tmp_usec);
341 u_data->io->max_x=(guint32)(u_data->io->x2_tmp_sec*1000000.0+u_data->io->x2_tmp_usec);
342 u_data->io->uoff = FALSE;
345 u_data->io->tmp_width=u_data->io->max_x-u_data->io->min_x;
349 if (u_data->io->tmp==FALSE)
351 if (u_data->assoc->tsn1!=NULL || u_data->assoc->sack1!=NULL)
352 u_data->io->max_y=u_data->io->tmp_max_tsn1 - u_data->io->tmp_min_tsn1;
354 u_data->io->max_y= 0;
355 u_data->io->min_y = 0;
359 u_data->io->max_y = u_data->io->tmp_max_tsn1;
360 u_data->io->min_y = u_data->io->tmp_min_tsn1;
363 else if (u_data->dir==2)
365 if (u_data->io->tmp==FALSE)
367 if (u_data->assoc->tsn2!=NULL || u_data->assoc->sack2!=NULL)
368 u_data->io->max_y=u_data->io->tmp_max_tsn2 -u_data->io->tmp_min_tsn2;
370 u_data->io->max_y= 0;
371 u_data->io->min_y = 0;
375 u_data->io->max_y = u_data->io->tmp_max_tsn2;
376 u_data->io->min_y = u_data->io->tmp_min_tsn2;
380 gdk_draw_rectangle(u_data->io->pixmap,
381 u_data->io->draw_area->style->white_gc,
384 u_data->io->draw_area->allocation.width,
385 u_data->io->draw_area->allocation.height);
389 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);
390 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);
391 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);
392 u_data->io->axis_width=u_data->io->pixmap_width-LEFT_BORDER-RIGHT_BORDER-u_data->io->offset;
394 /* try to avoid dividing by zero */
395 if(u_data->io->tmp_width>0){
396 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*/
398 u_data->io->x_interval = (float)(u_data->io->axis_width);
401 e=0; /*number of decimals of x_interval*/
402 if (u_data->io->x_interval<1)
404 dis=1/u_data->io->x_interval;
411 for (i=0; i<=e+1; i++)
412 distance*=10; /*distance per 100 pixels*/
417 g_snprintf(label_string, 15, "%d", 0);
418 memcpy(label_string,(gchar *)g_locale_to_utf8(label_string, -1 , NULL, NULL, NULL), 15);
419 layout = gtk_widget_create_pango_layout(u_data->io->draw_area, label_string);
420 pango_layout_get_pixel_size(layout, &label_width, &label_height);
422 if (u_data->io->x1_tmp_usec==0)
423 sec=u_data->io->x1_tmp_sec;
425 sec=u_data->io->x1_tmp_sec+1;
428 if (u_data->io->offset!=0)
430 g_snprintf(label_string, 15, "%u", u_data->io->x1_tmp_sec);
432 memcpy(label_string,(gchar *)g_locale_to_utf8(label_string, -1 , NULL, NULL, NULL), 15);
433 pango_layout_set_text(layout, label_string, -1);
434 pango_layout_get_pixel_size(layout, &lwidth, NULL);
436 gdk_draw_layout(u_data->io->pixmap,u_data->io->draw_area->style->black_gc,
438 u_data->io->pixmap_height-BOTTOM_BORDER+20,
442 w=(guint32)(500/(guint32)(distance*u_data->io->x_interval)); /*there will be a label for every w_th tic*/
447 if (w==4 || w==3 || w==2)
450 a=distance/10; /*distance between two tics*/
451 b = (guint32)((u_data->io->min_x/100000))%10; /* start for labels*/
460 if (!u_data->io->uoff)
464 start=u_data->io->min_x/1000000*1000000;
470 start=u_data->io->min_x/100000;
474 b = (guint32)((start/100000))%10;
479 start = u_data->io->min_x;
486 for (i=start, j=b; i<=u_data->io->max_x; i+=a, j++)
488 if (!u_data->io->uoff)
489 if (i>=u_data->io->min_x && i%1000000!=0)
492 g_snprintf(label_string, 15, "%d", i%1000000);
496 memcpy(label_string,(gchar *)g_locale_to_utf8(label_string, -1 , NULL, NULL, NULL), 15);
497 pango_layout_set_text(layout, label_string, -1);
498 pango_layout_get_pixel_size(layout, &lwidth, NULL);
499 gdk_draw_layout(u_data->io->pixmap,u_data->io->draw_area->style->black_gc,
500 (guint32)(LEFT_BORDER+u_data->io->offset+(i-u_data->io->min_x)*u_data->io->x_interval-lwidth/2),
501 u_data->io->pixmap_height-BOTTOM_BORDER+10,
504 gdk_draw_line(u_data->io->pixmap,u_data->io->draw_area->style->black_gc,
505 (guint32)(LEFT_BORDER+u_data->io->offset+(i-u_data->io->min_x)*u_data->io->x_interval),
506 u_data->io->pixmap_height-BOTTOM_BORDER,
507 (guint32)(LEFT_BORDER+u_data->io->offset+(i-u_data->io->min_x)*u_data->io->x_interval),
508 u_data->io->pixmap_height-BOTTOM_BORDER+length);
511 if (!u_data->io->uoff)
513 if (i%1000000==0 && j%w==0)
529 gdk_draw_line(u_data->io->pixmap,u_data->io->draw_area->style->black_gc,
530 (guint32)(LEFT_BORDER+u_data->io->offset+(i-u_data->io->min_x)*u_data->io->x_interval),
531 u_data->io->pixmap_height-BOTTOM_BORDER,
532 (guint32)(LEFT_BORDER+u_data->io->offset+(i-u_data->io->min_x)*u_data->io->x_interval),
533 u_data->io->pixmap_height-BOTTOM_BORDER+10);
535 g_snprintf(label_string, 15, "%d", sec);
536 memcpy(label_string,(gchar *)g_locale_to_utf8(label_string, -1 , NULL, NULL, NULL), 15);
537 pango_layout_set_text(layout, label_string, -1);
538 pango_layout_get_pixel_size(layout, &lwidth, NULL);
540 gdk_draw_layout(u_data->io->pixmap,u_data->io->draw_area->style->black_gc,
541 (guint32)(LEFT_BORDER+u_data->io->offset+(i-u_data->io->min_x)*u_data->io->x_interval-10),
542 u_data->io->pixmap_height-BOTTOM_BORDER+20,
549 g_strlcpy(label_string, "sec", 15);
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,
555 u_data->io->draw_area->style->black_gc,
556 u_data->io->pixmap_width-RIGHT_BORDER-10,
557 u_data->io->pixmap_height-BOTTOM_BORDER+30,
563 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);
564 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);
565 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);
567 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));
570 if (u_data->io->y_interval<1)
572 dis=1/u_data->io->y_interval;
580 distance=distance*10;
582 else if (u_data->io->y_interval<2)
585 if (u_data->io->max_y>0)
587 for (i=u_data->io->min_y/distance*distance; i<=u_data->io->max_y; i+=distance/5)
589 if (i>=u_data->io->min_y)
592 g_snprintf(label_string, 15, "%d", i);
593 if (i%distance==0 || (distance<=5 && u_data->io->y_interval>10))
597 memcpy(label_string,(gchar *)g_locale_to_utf8(label_string, -1 , NULL, NULL, NULL), 15);
598 pango_layout_set_text(layout, label_string, -1);
599 pango_layout_get_pixel_size(layout, &lwidth, NULL);
600 gdk_draw_layout(u_data->io->pixmap,u_data->io->draw_area->style->black_gc,
601 LEFT_BORDER-length-lwidth-5,
602 (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),
605 gdk_draw_line(u_data->io->pixmap,u_data->io->draw_area->style->black_gc,LEFT_BORDER-length,
606 (guint32)(u_data->io->pixmap_height-BOTTOM_BORDER-u_data->io->offset-(i-u_data->io->min_y)*u_data->io->y_interval),
608 (guint32)(u_data->io->pixmap_height-BOTTOM_BORDER-u_data->io->offset-(i-u_data->io->min_y)*u_data->io->y_interval));
612 else if ((u_data->dir==1 && u_data->assoc->n_array_tsn1==0) || (u_data->dir==2 && u_data->assoc->n_array_tsn2==0))
613 simple_dialog(ESD_TYPE_INFO, ESD_BTN_OK, "No Data Chunks sent");
617 static void sctp_graph_redraw(struct sctp_udata *u_data)
621 u_data->io->needs_redraw=TRUE;
623 sctp_graph_draw(u_data);
624 switch (u_data->io->graph_type)
627 draw_sack_graph(u_data);
628 draw_tsn_graph(u_data);
631 draw_tsn_graph(u_data);
634 draw_sack_graph(u_data);
637 ios=(sctp_graph_t *)OBJECT_GET_DATA(u_data->io->draw_area, "sctp_graph_t");
644 gdk_draw_pixmap(u_data->io->draw_area->window,
645 u_data->io->draw_area->style->fg_gc[GTK_WIDGET_STATE(u_data->io->draw_area)],
649 u_data->io->draw_area->allocation.width,
650 u_data->io->draw_area->allocation.height);
654 static void on_sack_bt(GtkWidget *widget _U_, struct sctp_udata *u_data)
657 u_data = (struct sctp_udata *) u_data;
658 u_data->io->graph_type=2;
659 sctp_graph_redraw(u_data);
662 static void on_tsn_bt(GtkWidget *widget _U_, struct sctp_udata *u_data)
665 u_data->io->graph_type=1;
666 sctp_graph_redraw(u_data);
669 static void on_both_bt(GtkWidget *widget _U_, struct sctp_udata *u_data)
672 u_data->io->graph_type=0;
673 sctp_graph_redraw(u_data);
677 sctp_graph_close_cb(GtkWidget* widget _U_, gpointer u_data)
679 struct sctp_udata *udata;
682 udata = (struct sctp_udata *)u_data;
684 gtk_grab_remove(GTK_WIDGET(udata->io->window));
685 gtk_widget_destroy(GTK_WIDGET(udata->io->window));
690 configure_event(GtkWidget *widget, GdkEventConfigure *event _U_, struct sctp_udata *u_data)
696 if(u_data->io->pixmap){
697 gdk_pixmap_unref(u_data->io->pixmap);
698 u_data->io->pixmap=NULL;
701 u_data->io->pixmap=gdk_pixmap_new(widget->window,
702 widget->allocation.width,
703 widget->allocation.height,
705 u_data->io->pixmap_width=widget->allocation.width;
706 u_data->io->pixmap_height=widget->allocation.height;
708 gdk_draw_rectangle(u_data->io->pixmap,
709 widget->style->white_gc,
712 widget->allocation.width,
713 widget->allocation.height);
714 sctp_graph_redraw(u_data);
719 expose_event(GtkWidget *widget, GdkEventExpose *event)
723 ios=(sctp_graph_t *)OBJECT_GET_DATA(widget, "sctp_graph_t");
728 gdk_draw_pixmap(widget->window,
729 widget->style->fg_gc[GTK_WIDGET_STATE(widget)],
731 event->area.x, event->area.y,
732 event->area.x, event->area.y,
733 event->area.width, event->area.height);
740 on_zoomin_bt (GtkWidget *widget _U_, struct sctp_udata *u_data)
742 sctp_min_max_t *tmp_minmax;
744 if (u_data->io->rectangle_present==TRUE)
746 tmp_minmax = g_malloc(sizeof(sctp_min_max_t));
748 u_data->io->tmp_min_tsn1=u_data->io->y1_tmp+u_data->io->min_y;
749 u_data->io->tmp_max_tsn1=u_data->io->y2_tmp+1+u_data->io->min_y;
750 u_data->io->tmp_min_tsn2=u_data->io->tmp_min_tsn1;
751 u_data->io->tmp_max_tsn2=u_data->io->tmp_max_tsn1;
752 tmp_minmax->tmp_min_secs=u_data->io->x1_tmp_sec;
753 tmp_minmax->tmp_min_usecs= u_data->io->x1_tmp_usec;
754 tmp_minmax->tmp_max_secs= u_data->io->x2_tmp_sec;
755 tmp_minmax->tmp_max_usecs= u_data->io->x2_tmp_usec;
756 tmp_minmax->tmp_min_tsn1=u_data->io->tmp_min_tsn1;
757 tmp_minmax->tmp_max_tsn1=u_data->io->tmp_max_tsn1;
758 tmp_minmax->tmp_min_tsn2=u_data->io->tmp_min_tsn2;
759 tmp_minmax->tmp_max_tsn2=u_data->io->tmp_max_tsn2;
760 u_data->assoc->min_max = g_slist_prepend(u_data->assoc->min_max, tmp_minmax);
761 u_data->io->length = g_slist_length(u_data->assoc->min_max);
762 u_data->io->tmp=TRUE;
763 u_data->io->rectangle=FALSE;
764 u_data->io->rectangle_present=FALSE;
765 gtk_widget_set_sensitive(zoomout_bt, TRUE);
766 sctp_graph_redraw(u_data);
770 simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK, "Please draw a rectangle around the area you want to zoom in!");
775 zoomin_bt (struct sctp_udata *u_data)
777 sctp_min_max_t *tmp_minmax;
779 tmp_minmax = g_malloc(sizeof(sctp_min_max_t));
781 u_data->io->tmp_min_tsn1=u_data->io->y1_tmp+u_data->io->min_y;
782 u_data->io->tmp_max_tsn1=u_data->io->y2_tmp+1+u_data->io->min_y;
783 u_data->io->tmp_min_tsn2=u_data->io->tmp_min_tsn1;
784 u_data->io->tmp_max_tsn2=u_data->io->tmp_max_tsn1;
785 tmp_minmax->tmp_min_secs=u_data->io->x1_tmp_sec;
786 tmp_minmax->tmp_min_usecs= u_data->io->x1_tmp_usec;
787 tmp_minmax->tmp_max_secs= u_data->io->x2_tmp_sec;
788 tmp_minmax->tmp_max_usecs= u_data->io->x2_tmp_usec;
789 tmp_minmax->tmp_min_tsn1=u_data->io->tmp_min_tsn1;
790 tmp_minmax->tmp_max_tsn1=u_data->io->tmp_max_tsn1;
791 tmp_minmax->tmp_min_tsn2=u_data->io->tmp_min_tsn2;
792 tmp_minmax->tmp_max_tsn2=u_data->io->tmp_max_tsn2;
793 u_data->assoc->min_max = g_slist_prepend(u_data->assoc->min_max, tmp_minmax);
794 u_data->io->length = g_slist_length(u_data->assoc->min_max);
795 u_data->io->tmp=TRUE;
796 u_data->io->rectangle=FALSE;
797 u_data->io->rectangle_present=FALSE;
798 gtk_widget_set_sensitive(zoomout_bt, TRUE);
799 sctp_graph_redraw(u_data);
806 on_zoomout_bt (GtkWidget *widget _U_, struct sctp_udata *u_data)
808 sctp_min_max_t *tmp_minmax, *mm;
811 l = g_slist_length(u_data->assoc->min_max);
813 if (u_data->assoc->min_max!=NULL)
815 mm=(sctp_min_max_t *)((u_data->assoc->min_max)->data);
816 u_data->assoc->min_max=g_slist_remove(u_data->assoc->min_max, mm);
820 tmp_minmax = (sctp_min_max_t *)u_data->assoc->min_max->data;
821 u_data->io->x1_tmp_sec=tmp_minmax->tmp_min_secs;
822 u_data->io->x1_tmp_usec=tmp_minmax->tmp_min_usecs;
823 u_data->io->x2_tmp_sec=tmp_minmax->tmp_max_secs;
824 u_data->io->x2_tmp_usec=tmp_minmax->tmp_max_usecs;
825 u_data->io->tmp_min_tsn1=tmp_minmax->tmp_min_tsn1;
826 u_data->io->tmp_max_tsn1=tmp_minmax->tmp_max_tsn1;
827 u_data->io->tmp_min_tsn2=tmp_minmax->tmp_min_tsn2;
828 u_data->io->tmp_max_tsn2=tmp_minmax->tmp_max_tsn2;
829 u_data->io->tmp=TRUE;
833 u_data->io->x1_tmp_sec=u_data->assoc->min_secs;
834 u_data->io->x1_tmp_usec=u_data->assoc->min_usecs;
835 u_data->io->x2_tmp_sec=u_data->assoc->max_secs;
836 u_data->io->x2_tmp_usec=u_data->assoc->max_usecs;
837 u_data->io->tmp_min_tsn1=u_data->assoc->min_tsn1;
838 u_data->io->tmp_max_tsn1=u_data->assoc->max_tsn1;
839 u_data->io->tmp_min_tsn2=u_data->assoc->min_tsn2;
840 u_data->io->tmp_max_tsn2=u_data->assoc->max_tsn2;
841 u_data->io->tmp=FALSE;
846 u_data->io->x1_tmp_sec=u_data->assoc->min_secs;
847 u_data->io->x1_tmp_usec=u_data->assoc->min_usecs;
848 u_data->io->x2_tmp_sec=u_data->assoc->max_secs;
849 u_data->io->x2_tmp_usec=u_data->assoc->max_usecs;
850 u_data->io->tmp_min_tsn1=u_data->assoc->min_tsn1;
851 u_data->io->tmp_max_tsn1=u_data->assoc->max_tsn1;
852 u_data->io->tmp_min_tsn2=u_data->assoc->min_tsn2;
853 u_data->io->tmp_max_tsn2=u_data->assoc->max_tsn2;
854 u_data->io->tmp=FALSE;
856 if (g_slist_length(u_data->assoc->min_max)==1)
857 gtk_widget_set_sensitive(zoomout_bt, FALSE);
858 sctp_graph_redraw(u_data);
862 on_button_press (GtkWidget *widget _U_, GdkEventButton *event, struct sctp_udata *u_data)
866 if (u_data->io->rectangle==TRUE)
868 gdk_draw_rectangle(u_data->io->pixmap,u_data->io->draw_area->style->white_gc,
870 (gint)floor(MIN(u_data->io->x_old,u_data->io->x_new)),
871 (gint)floor(MIN(u_data->io->y_old,u_data->io->y_new)),
872 (gint)floor(abs((long)(u_data->io->x_new-u_data->io->x_old))),
873 (gint)floor(abs((long)(u_data->io->y_new-u_data->io->y_old))));
874 ios=(sctp_graph_t *)OBJECT_GET_DATA(u_data->io->draw_area, "sctp_graph_t");
880 gdk_draw_pixmap(u_data->io->draw_area->window,
881 u_data->io->draw_area->style->fg_gc[GTK_WIDGET_STATE(u_data->io->draw_area)],
885 (gint)(abs((long)(u_data->io->x_new-u_data->io->x_old))),
886 (gint)(abs((long)(u_data->io->y_new-u_data->io->y_old))));
887 sctp_graph_redraw(u_data);
889 u_data->io->x_old=event->x;
890 u_data->io->y_old=event->y;
891 if (u_data->io->y_old>u_data->io->pixmap_height-BOTTOM_BORDER-u_data->io->offset-POINT_SIZE)
892 u_data->io->y_old=u_data->io->pixmap_height-BOTTOM_BORDER-u_data->io->offset-POINT_SIZE;
893 if (u_data->io->x_old<LEFT_BORDER+u_data->io->offset)
894 u_data->io->x_old=LEFT_BORDER+u_data->io->offset;
895 u_data->io->rectangle=FALSE;
902 on_button_release (GtkWidget *widget _U_, GdkEventButton *event, struct sctp_udata *u_data)
905 guint32 helpx, helpy, x1_tmp, x2_tmp, y_value, t_size=0, s_size=0, i, y_tolerance;
906 gint label_width, label_height;
907 gdouble x_value, position, s_diff=0, t_diff=0, x_tolerance=0.0001;
909 char label_string[30];
911 GPtrArray *tsnlist = NULL, *sacklist=NULL;
912 struct tsn_sort *tsn, *sack=NULL;
913 gboolean sack_found = FALSE;
916 g_snprintf(label_string, 15, "%d", 0);
917 memcpy(label_string,(gchar *)g_locale_to_utf8(label_string, -1 , NULL, NULL, NULL), 15);
918 layout = gtk_widget_create_pango_layout(u_data->io->draw_area, label_string);
919 pango_layout_get_pixel_size(layout, &label_width, &label_height);
921 if (event->y>u_data->io->pixmap_height-BOTTOM_BORDER-u_data->io->offset)
922 event->y = u_data->io->pixmap_height-BOTTOM_BORDER-u_data->io->offset;
923 if (event->x < LEFT_BORDER+u_data->io->offset)
924 event->x = LEFT_BORDER+u_data->io->offset;
925 if (abs((long)(event->x-u_data->io->x_old))>10 || abs((long)(event->y-u_data->io->y_old))>10)
927 u_data->io->rect_x_min = (gint)floor(MIN(u_data->io->x_old,event->x));
928 u_data->io->rect_x_max = (gint)ceil(MAX(u_data->io->x_old,event->x));
929 u_data->io->rect_y_min = (gint)floor(MIN(u_data->io->y_old,event->y));
930 u_data->io->rect_y_max = (gint)ceil(MAX(u_data->io->y_old,event->y))+POINT_SIZE;
931 gdk_draw_rectangle(u_data->io->pixmap,u_data->io->draw_area->style->black_gc,
933 u_data->io->rect_x_min, u_data->io->rect_y_min,
934 u_data->io->rect_x_max - u_data->io->rect_x_min,
935 u_data->io->rect_y_max - u_data->io->rect_y_min);
936 ios=(sctp_graph_t *)OBJECT_GET_DATA(u_data->io->draw_area, "sctp_graph_t");
942 gdk_draw_pixmap(u_data->io->draw_area->window,
943 u_data->io->draw_area->style->fg_gc[GTK_WIDGET_STATE(u_data->io->draw_area)],
947 u_data->io->draw_area->allocation.width,
948 u_data->io->draw_area->allocation.height);
950 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));
951 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));
952 helpx=MIN(x1_tmp, x2_tmp);
958 if (u_data->io->uoff)
960 if (x2_tmp - x1_tmp <= 1500)
961 u_data->io->uoff = FALSE;
962 u_data->io->x1_tmp_sec=(guint32)x1_tmp;
963 u_data->io->x1_tmp_usec=0;
964 u_data->io->x2_tmp_sec=(guint32)x2_tmp;
965 u_data->io->x2_tmp_usec=0;
969 u_data->io->x1_tmp_sec=(guint32)x1_tmp/1000000;
970 u_data->io->x1_tmp_usec=x1_tmp%1000000;
971 u_data->io->x2_tmp_sec=(guint32)x2_tmp/1000000;
972 u_data->io->x2_tmp_usec=x2_tmp%1000000;
974 u_data->io->x1_akt_sec = u_data->io->x1_tmp_sec;
975 u_data->io->x1_akt_usec = u_data->io->x1_tmp_usec;
976 u_data->io->x2_akt_sec = u_data->io->x2_tmp_sec;
977 u_data->io->x2_akt_usec = u_data->io->x2_tmp_usec;
979 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);
980 u_data->io->y2_tmp=(guint32)((u_data->io->pixmap_height-BOTTOM_BORDER-u_data->io->offset-event->y)/u_data->io->y_interval);
981 helpy = MIN(u_data->io->y1_tmp, u_data->io->y2_tmp);
982 u_data->io->y2_tmp = MAX(u_data->io->y1_tmp, u_data->io->y2_tmp);
983 u_data->io->y1_tmp = helpy;
984 u_data->io->x_new=event->x;
985 u_data->io->y_new=event->y;
986 u_data->io->rectangle=TRUE;
987 u_data->io->rectangle_present=TRUE;
991 if (u_data->io->rectangle_present==TRUE)
993 u_data->io->rectangle_present=FALSE;
994 if (event->x >= u_data->io->rect_x_min && event->x <= u_data->io->rect_x_max &&
995 event->y >= u_data->io->rect_y_min && event->y <= u_data->io->rect_y_max)
999 u_data->io->x1_tmp_sec = u_data->io->x1_akt_sec;
1000 u_data->io->x1_tmp_usec = u_data->io->x1_akt_usec;
1001 u_data->io->x2_tmp_sec = u_data->io->x2_akt_sec;
1002 u_data->io->x2_tmp_usec = u_data->io->x2_akt_usec;
1003 sctp_graph_redraw(u_data);
1009 sctp_graph_redraw(u_data);
1013 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;
1014 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;
1015 text_color = u_data->io->draw_area->style->black_gc;
1017 if (u_data->dir == 1)
1019 tsnlist = u_data->assoc->sort_tsn1;
1020 t_size = u_data->assoc->n_data_chunks_ep1;
1021 sacklist = u_data->assoc->sort_sack1;
1022 s_size = u_data->assoc->n_sack_chunks_ep1;
1026 tsnlist = u_data->assoc->sort_tsn2;
1027 t_size = u_data->assoc->n_data_chunks_ep2;
1028 sacklist = u_data->assoc->sort_sack2;
1029 s_size = u_data->assoc->n_sack_chunks_ep2;
1031 x_tolerance = (gdouble)((u_data->io->tmp_width / u_data->io->axis_width*1.0))*5/1000000.0;
1032 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);
1035 else if (y_tolerance > 5)
1038 for (i=0; i<s_size; i++)
1040 sack = (struct tsn_sort*)(g_ptr_array_index(sacklist, i));
1041 if ((guint32)abs(sack->tsnumber - y_value)<y_tolerance)
1043 s_diff = fabs((sack->secs+sack->usecs/1000000.0)- x_value);
1044 if (s_diff < x_tolerance)
1050 for (i=0; i<t_size; i++)
1052 tsn = (struct tsn_sort*)(g_ptr_array_index(tsnlist, i));
1053 if ((guint32)abs(tsn->tsnumber - y_value)<y_tolerance)
1055 t_diff = fabs((tsn->secs+tsn->usecs/1000000.0)- x_value);
1056 if (sack_found && s_diff < t_diff)
1058 cf_goto_frame(&cfile, sack->framenumber);
1059 x_value = sack->secs+sack->usecs/1000000.0;
1060 y_value = sack->tsnumber;
1062 else if (t_diff < x_tolerance)
1064 cf_goto_frame(&cfile, tsn->framenumber);
1065 x_value = tsn->secs+tsn->usecs/1000000.0;
1066 y_value = tsn->tsnumber;
1072 g_snprintf(label_string, 30, "(%.6lf, %u)", x_value, y_value);
1076 gdk_draw_line(u_data->io->pixmap,text_color, (gint)(event->x-2), (gint)(event->y), (gint)(event->x+2), (gint)(event->y));
1077 gdk_draw_line(u_data->io->pixmap,text_color, (gint)(event->x), (gint)(event->y-2), (gint)(event->x), (gint)(event->y+2));
1078 if (event->x+150>=u_data->io->pixmap_width)
1079 position = event->x - 150;
1081 position = event->x + 5;
1084 memcpy(label_string,(gchar *)g_locale_to_utf8(label_string, -1 , NULL, NULL, NULL), 15);
1085 pango_layout_set_text(layout, label_string, -1);
1086 pango_layout_get_pixel_size(layout, &lwidth, NULL);
1088 gdk_draw_layout(u_data->io->pixmap,text_color,
1090 (gint)(event->y-10),
1093 ios=(sctp_graph_t *)OBJECT_GET_DATA(u_data->io->draw_area, "sctp_graph_t");
1098 gdk_draw_pixmap(u_data->io->draw_area->window,
1099 u_data->io->draw_area->style->fg_gc[GTK_WIDGET_STATE(u_data->io->draw_area)],
1103 u_data->io->draw_area->allocation.width,
1104 u_data->io->draw_area->allocation.height);
1111 static void init_sctp_graph_window(struct sctp_udata *u_data)
1115 GtkWidget *bt_close, *sack_bt, *tsn_bt, *both_bt, *zoomin_bt;
1116 GtkTooltips *tooltip_in, *tooltip_out;
1118 /* create the main window */
1120 u_data->io->window=gtk_window_new(GTK_WINDOW_TOPLEVEL);
1122 gtk_widget_set_name(u_data->io->window, "SCTP Graphics");
1124 vbox=gtk_vbox_new(FALSE, 0);
1125 gtk_container_add(GTK_CONTAINER(u_data->io->window), vbox);
1126 gtk_widget_show(vbox);
1128 create_draw_area(vbox, u_data);
1130 sctp_graph_set_title(u_data);
1132 hbox = gtk_hbutton_box_new();
1133 gtk_box_pack_start(GTK_BOX(vbox), hbox, FALSE, FALSE, 0);
1134 gtk_container_set_border_width(GTK_CONTAINER(hbox), 10);
1135 gtk_button_box_set_layout(GTK_BUTTON_BOX (hbox), GTK_BUTTONBOX_SPREAD);
1136 gtk_button_box_set_spacing(GTK_BUTTON_BOX (hbox), 0);
1137 gtk_box_set_child_packing(GTK_BOX(vbox), hbox, FALSE, FALSE, 0, GTK_PACK_START);
1138 gtk_widget_show(hbox);
1140 sack_bt = gtk_button_new_with_label ("Show Sacks");
1141 gtk_box_pack_start(GTK_BOX(hbox), sack_bt, FALSE, FALSE, 0);
1142 gtk_widget_show(sack_bt);
1144 gtk_signal_connect(GTK_OBJECT(sack_bt), "clicked", (GtkSignalFunc)on_sack_bt, u_data);
1146 tsn_bt = gtk_button_new_with_label ("Show TSNs");
1147 gtk_box_pack_start(GTK_BOX(hbox), tsn_bt, FALSE, FALSE, 0);
1148 gtk_widget_show(tsn_bt);
1149 SIGNAL_CONNECT(tsn_bt, "clicked", on_tsn_bt, u_data);
1151 both_bt = gtk_button_new_with_label ("Show both");
1152 gtk_box_pack_start(GTK_BOX(hbox), both_bt, FALSE, FALSE, 0);
1153 gtk_widget_show(both_bt);
1154 SIGNAL_CONNECT(both_bt, "clicked", on_both_bt, u_data);
1156 zoomin_bt = gtk_button_new_with_label ("Zoom in");
1157 gtk_box_pack_start(GTK_BOX(hbox), zoomin_bt, FALSE, FALSE, 0);
1158 gtk_widget_show(zoomin_bt);
1159 SIGNAL_CONNECT(zoomin_bt, "clicked", on_zoomin_bt, u_data);
1160 tooltip_in = gtk_tooltips_new();
1161 gtk_tooltips_set_tip(tooltip_in, zoomin_bt, "Zoom in the area you have selected", NULL);
1163 zoomout_bt = gtk_button_new_with_label ("Zoom out");
1164 gtk_box_pack_start(GTK_BOX(hbox), zoomout_bt, FALSE, FALSE, 0);
1165 gtk_widget_show(zoomout_bt);
1166 SIGNAL_CONNECT(zoomout_bt, "clicked", on_zoomout_bt, u_data);
1167 tooltip_out = gtk_tooltips_new();
1168 gtk_tooltips_set_tip(tooltip_out, zoomout_bt, "Zoom out one step", NULL);
1169 gtk_widget_set_sensitive(zoomout_bt, FALSE);
1171 bt_close = BUTTON_NEW_FROM_STOCK(GTK_STOCK_CLOSE);
1172 gtk_box_pack_start(GTK_BOX(hbox), bt_close, FALSE, FALSE, 0);
1173 gtk_widget_show(bt_close);
1174 SIGNAL_CONNECT(bt_close, "clicked", sctp_graph_close_cb, u_data);
1176 gtk_signal_connect(GTK_OBJECT(u_data->io->draw_area),"button_press_event",(GtkSignalFunc)on_button_press, u_data);
1177 gtk_signal_connect(GTK_OBJECT(u_data->io->draw_area),"button_release_event",(GtkSignalFunc)on_button_release, u_data);
1178 gtk_widget_set_events(u_data->io->draw_area, GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK | GDK_EXPOSURE_MASK);
1180 gtk_widget_show(u_data->io->window);
1183 static void sctp_graph_set_title(struct sctp_udata *u_data)
1187 if(!u_data->io->window)
1191 title = g_strdup_printf("SCTP TSNs and Sacks over Time: %s Port1 %u Port2 %u Endpoint %u",
1192 cf_get_display_name(&cfile), u_data->parent->assoc->port1, u_data->parent->assoc->port2, u_data->dir);
1193 gtk_window_set_title(GTK_WINDOW(u_data->io->window), title);
1198 gtk_sctpgraph_init(struct sctp_udata *u_data)
1202 sctp_min_max_t* tmp_minmax;
1204 io=g_malloc(sizeof(sctp_graph_t));
1205 io->needs_redraw=TRUE;
1206 io->x_interval=1000;
1210 io->pixmap_width=800;
1211 io->pixmap_height=600;
1215 u_data->io->x1_tmp_sec=u_data->assoc->min_secs;
1216 u_data->io->x1_tmp_usec=u_data->assoc->min_usecs;
1217 u_data->io->x2_tmp_sec=u_data->assoc->max_secs;
1218 u_data->io->x2_tmp_usec=u_data->assoc->max_usecs;
1219 u_data->io->tmp_min_tsn1=u_data->assoc->min_tsn1;
1220 u_data->io->tmp_max_tsn1=u_data->assoc->max_tsn1;
1221 u_data->io->tmp_min_tsn2=u_data->assoc->min_tsn2;
1222 u_data->io->tmp_max_tsn2=u_data->assoc->max_tsn2;
1223 u_data->io->tmp=FALSE;
1225 tmp_minmax = g_malloc(sizeof(sctp_min_max_t));
1226 tmp_minmax->tmp_min_secs = u_data->assoc->min_secs;
1227 tmp_minmax->tmp_min_usecs=u_data->assoc->min_usecs;
1228 tmp_minmax->tmp_max_secs=u_data->assoc->max_secs;
1229 tmp_minmax->tmp_max_usecs=u_data->assoc->max_usecs;
1230 tmp_minmax->tmp_min_tsn2=u_data->assoc->min_tsn2;
1231 tmp_minmax->tmp_min_tsn1=u_data->assoc->min_tsn1;
1232 tmp_minmax->tmp_max_tsn1=u_data->assoc->max_tsn1;
1233 tmp_minmax->tmp_max_tsn2=u_data->assoc->max_tsn2;
1234 u_data->assoc->min_max = g_slist_prepend(u_data->assoc->min_max, tmp_minmax);
1237 init_sctp_graph_window(u_data);
1238 sctp_graph_redraw(u_data);
1244 quit(GtkObject *object _U_, gpointer user_data)
1246 struct sctp_udata *u_data=(struct sctp_udata*)user_data;
1248 decrease_childcount(u_data->parent);
1249 remove_child(u_data, u_data->parent);
1253 u_data->assoc->min_max = NULL;
1259 static void create_draw_area(GtkWidget *box, struct sctp_udata *u_data)
1262 u_data->io->draw_area=gtk_drawing_area_new();
1263 SIGNAL_CONNECT(u_data->io->draw_area, "destroy", quit, u_data);
1264 OBJECT_SET_DATA(u_data->io->draw_area, "sctp_graph_t", u_data->io);
1266 WIDGET_SET_SIZE(u_data->io->draw_area, u_data->io->pixmap_width, u_data->io->pixmap_height);
1268 /* signals needed to handle backing pixmap */
1269 SIGNAL_CONNECT(u_data->io->draw_area, "expose_event", expose_event, NULL);
1270 SIGNAL_CONNECT(u_data->io->draw_area, "configure_event", configure_event, u_data);
1272 gtk_widget_show(u_data->io->draw_area);
1273 gtk_box_pack_start(GTK_BOX(box), u_data->io->draw_area, TRUE, TRUE, 0);
1278 void create_graph(guint16 dir, struct sctp_analyse* userdata)
1280 struct sctp_udata *u_data;
1282 u_data=g_malloc(sizeof(struct sctp_udata));
1283 u_data->assoc=g_malloc(sizeof(sctp_assoc_info_t));
1284 u_data->assoc=userdata->assoc;
1287 u_data->parent = userdata;
1288 if ((u_data->dir==1 && u_data->assoc->n_array_tsn1==0)|| (u_data->dir==2 && u_data->assoc->n_array_tsn2==0))
1289 simple_dialog(ESD_TYPE_INFO, ESD_BTN_OK, "No Data Chunks sent");
1292 set_child(u_data, u_data->parent);
1293 increase_childcount(u_data->parent);
1294 gtk_sctpgraph_init(u_data);
1298 #if defined(_WIN32) && !defined(__MINGW32__)
1299 /* replacement of Unix rint() for Windows */
1300 static int rint (double x)
1305 buf = _fcvt(x, 0, &dec, &sig);