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.
35 #include "epan/filesystem.h"
36 #include <epan/strutil.h>
38 #include "../globals.h"
40 #include "../ui_util.h"
41 #include "../simple_dialog.h"
43 #include "gtk/dlg_utils.h"
45 #include "gtk/sctp_stat.h"
48 #define DEFAULT_PIXELS_PER_TICK 2
49 #define MAX_PIXELS_PER_TICK 4
50 #define AUTO_MAX_YSCALE 0
51 #define MAX_TICK_VALUES 5
52 #define DEFAULT_TICK_VALUE 3
54 #define MAX_COUNT_TYPES 3
56 #define COUNT_TYPE_FRAMES 0
57 #define COUNT_TYPE_BYTES 1
58 #define COUNT_TYPE_ADVANCED 2
60 #define LEFT_BORDER 60
61 #define RIGHT_BORDER 10
63 #define BOTTOM_BORDER 50
65 #define SUB_32(a, b) a-b
74 struct data_chunk_header {
84 struct init_chunk_header {
100 struct sack_chunk_header {
112 static gboolean label_set = FALSE;
113 static guint32 max_tsn=0, min_tsn=0;
114 static void sctp_graph_set_title(struct sctp_udata *u_data);
115 static void create_draw_area(GtkWidget *box, struct sctp_udata *u_data);
116 static GtkWidget *zoomout_bt;
117 #if defined(_WIN32) && !defined(__MINGW32__)
118 static int rint (double ); /* compiler template for Windows */
121 static void draw_sack_graph(struct sctp_udata *u_data)
124 GList *list=NULL, *tlist;
125 guint16 gap_start=0, gap_end=0, i, j, nr;
129 GdkColor red_color = {0, 65535, 0, 0};
130 GdkColor green_color = {0, 0, 65535, 0};
131 GdkGC *red_gc, *green_gc;
132 struct sack_chunk_header *sack_header;
134 guint32 max_num, diff;
136 red_gc = gdk_gc_new(u_data->io->draw_area->window);
137 gdk_gc_set_rgb_fg_color(red_gc, &red_color);
139 green_gc = gdk_gc_new(u_data->io->draw_area->window);
140 gdk_gc_set_rgb_fg_color(green_gc, &green_color);
145 list = g_list_last(u_data->assoc->sack2);
146 if (u_data->io->tmp==FALSE)
148 min_tsn=u_data->assoc->min_tsn2;
149 max_tsn=u_data->assoc->max_tsn2;
153 min_tsn=u_data->assoc->min_tsn2+u_data->io->tmp_min_tsn2;
154 max_tsn=u_data->assoc->min_tsn2+u_data->io->tmp_max_tsn2;
157 else if (u_data->dir==1)
159 list = g_list_last(u_data->assoc->sack1);
160 if (u_data->io->tmp==FALSE)
162 min_tsn=u_data->assoc->min_tsn1;
163 max_tsn=u_data->assoc->max_tsn1;
167 min_tsn=u_data->assoc->min_tsn1+u_data->io->tmp_min_tsn1;
168 max_tsn=u_data->assoc->min_tsn1+u_data->io->tmp_max_tsn1;
174 sack = (tsn_t*) (list->data);
175 tlist = g_list_first(sack->tsns);
178 type = ((struct chunk_header *)tlist->data)->type;
180 if (type == SCTP_SACK_CHUNK_ID)
182 sack_header =(struct sack_chunk_header *)tlist->data;
183 nr=g_ntohs(sack_header->nr_of_gaps);
184 tsnumber = g_ntohl(sack_header->cum_tsn_ack);
186 if (sack->secs>=u_data->io->x1_tmp_sec)
190 gap = &sack_header->gaps[0];
193 gap_start=g_ntohs(gap->start);
194 gap_end = g_ntohs(gap->end);
195 max_num=gap_end+tsnumber;
196 for (j=gap_start; j<=gap_end; j++)
198 if (u_data->io->uoff)
199 diff = sack->secs - u_data->io->min_x;
201 diff=sack->secs*1000000+sack->usecs-u_data->io->min_x;
202 xvalue = (guint32)(LEFT_BORDER+u_data->io->offset+u_data->io->x_interval*diff);
203 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));
204 if (xvalue >= LEFT_BORDER+u_data->io->offset &&
205 xvalue <= u_data->io->pixmap_width-RIGHT_BORDER+u_data->io->offset &&
206 yvalue >= TOP_BORDER-u_data->io->offset &&
207 yvalue <= u_data->io->pixmap_height-BOTTOM_BORDER-u_data->io->offset)
208 gdk_draw_arc(u_data->io->pixmap,green_gc,TRUE,
211 POINT_SIZE, POINT_SIZE,0, (64*360) );
219 if (tsnumber>=min_tsn)
221 if (u_data->io->uoff)
222 diff = sack->secs - u_data->io->min_x;
224 diff=sack->secs*1000000+sack->usecs-u_data->io->min_x;
225 xvalue = (guint32)(LEFT_BORDER+u_data->io->offset+u_data->io->x_interval*diff);
226 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));
227 if (xvalue >= LEFT_BORDER+u_data->io->offset &&
228 xvalue <= u_data->io->pixmap_width-RIGHT_BORDER+u_data->io->offset &&
229 yvalue >= TOP_BORDER-u_data->io->offset &&
230 yvalue <= u_data->io->pixmap_height-BOTTOM_BORDER-u_data->io->offset)
231 gdk_draw_arc(u_data->io->pixmap,red_gc,TRUE,
234 POINT_SIZE, POINT_SIZE,0, (64*360) );
237 tlist = g_list_next(tlist);
240 list = g_list_previous(list);
242 g_object_unref(G_OBJECT(red_gc));
243 g_object_unref(G_OBJECT(green_gc));
247 static void draw_tsn_graph(struct sctp_udata *u_data)
250 GList *list=NULL, *tlist;
253 guint32 min_secs=0, diff;
258 list = g_list_last(u_data->assoc->tsn1);
259 if (u_data->io->tmp==FALSE)
261 min_tsn=u_data->assoc->min_tsn1;
262 max_tsn=u_data->assoc->max_tsn1;
266 min_tsn=u_data->assoc->min_tsn1+u_data->io->tmp_min_tsn1;
267 max_tsn=u_data->assoc->min_tsn1+u_data->io->tmp_max_tsn1;
270 else if (u_data->dir==2)
272 list = g_list_last(u_data->assoc->tsn2);
273 if (u_data->io->tmp==FALSE)
275 min_tsn=u_data->assoc->min_tsn2;
276 max_tsn=u_data->assoc->max_tsn2;
280 min_tsn=u_data->assoc->min_tsn2+u_data->io->tmp_min_tsn2;
281 max_tsn=u_data->assoc->min_tsn2+u_data->io->tmp_max_tsn2;
287 tsn = (tsn_t*) (list->data);
288 tlist = g_list_first(tsn->tsns);
291 type = ((struct chunk_header *)tlist->data)->type;
292 if (type == SCTP_DATA_CHUNK_ID)
293 tsnumber = g_ntohl(((struct data_chunk_header *)tlist->data)->tsn);
294 if (tsnumber>=min_tsn && tsnumber<=max_tsn && tsn->secs>=min_secs)
296 if (u_data->io->uoff)
297 diff = tsn->secs - u_data->io->min_x;
299 diff=tsn->secs*1000000+tsn->usecs-u_data->io->min_x;
300 xvalue = (guint32)(LEFT_BORDER+u_data->io->offset+u_data->io->x_interval*diff);
301 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));
302 if (xvalue >= LEFT_BORDER+u_data->io->offset &&
303 xvalue <= u_data->io->pixmap_width-RIGHT_BORDER+u_data->io->offset &&
304 yvalue >= TOP_BORDER-u_data->io->offset &&
305 yvalue <= u_data->io->pixmap_height-BOTTOM_BORDER-u_data->io->offset)
306 gdk_draw_arc(u_data->io->pixmap,u_data->io->draw_area->style->black_gc,TRUE,
309 POINT_SIZE, POINT_SIZE, 0, (64*360));
311 tlist = g_list_next(tlist);
313 list = g_list_previous(list);
318 static void sctp_graph_draw(struct sctp_udata *u_data)
321 guint32 distance=5, i, e, sec, w, start, a, b, j;
322 gint label_width, label_height;
323 char label_string[15];
325 gboolean write_label = FALSE;
328 if (u_data->io->x1_tmp_sec==0 && u_data->io->x1_tmp_usec==0)
329 u_data->io->offset=0;
331 u_data->io->offset=5;
333 if (u_data->io->x2_tmp_sec - u_data->io->x1_tmp_sec > 1500)
335 u_data->io->min_x=u_data->io->x1_tmp_sec;
336 u_data->io->max_x=u_data->io->x2_tmp_sec;
337 u_data->io->uoff = TRUE;
341 u_data->io->min_x=(guint32)(u_data->io->x1_tmp_sec*1000000.0+u_data->io->x1_tmp_usec);
342 u_data->io->max_x=(guint32)(u_data->io->x2_tmp_sec*1000000.0+u_data->io->x2_tmp_usec);
343 u_data->io->uoff = FALSE;
346 u_data->io->tmp_width=u_data->io->max_x-u_data->io->min_x;
350 if (u_data->io->tmp==FALSE)
352 if (u_data->assoc->tsn1!=NULL || u_data->assoc->sack1!=NULL)
353 u_data->io->max_y=u_data->io->tmp_max_tsn1 - u_data->io->tmp_min_tsn1;
355 u_data->io->max_y= 0;
356 u_data->io->min_y = 0;
360 u_data->io->max_y = u_data->io->tmp_max_tsn1;
361 u_data->io->min_y = u_data->io->tmp_min_tsn1;
364 else if (u_data->dir==2)
366 if (u_data->io->tmp==FALSE)
368 if (u_data->assoc->tsn2!=NULL || u_data->assoc->sack2!=NULL)
369 u_data->io->max_y=u_data->io->tmp_max_tsn2 -u_data->io->tmp_min_tsn2;
371 u_data->io->max_y= 0;
372 u_data->io->min_y = 0;
376 u_data->io->max_y = u_data->io->tmp_max_tsn2;
377 u_data->io->min_y = u_data->io->tmp_min_tsn2;
381 gdk_draw_rectangle(u_data->io->pixmap,
382 u_data->io->draw_area->style->white_gc,
385 u_data->io->draw_area->allocation.width,
386 u_data->io->draw_area->allocation.height);
390 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);
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 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);
393 u_data->io->axis_width=u_data->io->pixmap_width-LEFT_BORDER-RIGHT_BORDER-u_data->io->offset;
395 /* try to avoid dividing by zero */
396 if(u_data->io->tmp_width>0){
397 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*/
399 u_data->io->x_interval = (float)(u_data->io->axis_width);
402 e=0; /*number of decimals of x_interval*/
403 if (u_data->io->x_interval<1)
405 dis=1/u_data->io->x_interval;
412 for (i=0; i<=e+1; i++)
413 distance*=10; /*distance per 100 pixels*/
418 g_snprintf(label_string, sizeof(label_string), "%d", 0);
419 memcpy(label_string,(gchar *)g_locale_to_utf8(label_string, -1 , NULL, NULL, NULL), sizeof(label_string));
420 layout = gtk_widget_create_pango_layout(u_data->io->draw_area, label_string);
421 pango_layout_get_pixel_size(layout, &label_width, &label_height);
423 if (u_data->io->x1_tmp_usec==0)
424 sec=u_data->io->x1_tmp_sec;
426 sec=u_data->io->x1_tmp_sec+1;
429 if (u_data->io->offset!=0)
431 g_snprintf(label_string, sizeof(label_string), "%u", u_data->io->x1_tmp_sec);
433 memcpy(label_string,(gchar *)g_locale_to_utf8(label_string, -1 , NULL, NULL, NULL), sizeof(label_string));
434 pango_layout_set_text(layout, label_string, -1);
435 pango_layout_get_pixel_size(layout, &lwidth, NULL);
437 gdk_draw_layout(u_data->io->pixmap,u_data->io->draw_area->style->black_gc,
439 u_data->io->pixmap_height-BOTTOM_BORDER+20,
443 w=(guint32)(500/(guint32)(distance*u_data->io->x_interval)); /*there will be a label for every w_th tic*/
448 if (w==4 || w==3 || w==2)
451 a=distance/10; /*distance between two tics*/
452 b = (guint32)((u_data->io->min_x/100000))%10; /* start for labels*/
461 if (!u_data->io->uoff)
465 start=u_data->io->min_x/1000000*1000000;
471 start=u_data->io->min_x/100000;
475 b = (guint32)((start/100000))%10;
480 start = u_data->io->min_x;
487 for (i=start, j=b; i<=u_data->io->max_x; i+=a, j++)
489 if (!u_data->io->uoff)
490 if (i>=u_data->io->min_x && i%1000000!=0)
493 g_snprintf(label_string, sizeof(label_string), "%d", i%1000000);
497 memcpy(label_string,(gchar *)g_locale_to_utf8(label_string, -1 , NULL, NULL, NULL), sizeof(label_string));
498 pango_layout_set_text(layout, label_string, -1);
499 pango_layout_get_pixel_size(layout, &lwidth, NULL);
500 gdk_draw_layout(u_data->io->pixmap,u_data->io->draw_area->style->black_gc,
501 (guint32)(LEFT_BORDER+u_data->io->offset+(i-u_data->io->min_x)*u_data->io->x_interval-lwidth/2),
502 u_data->io->pixmap_height-BOTTOM_BORDER+10,
505 gdk_draw_line(u_data->io->pixmap,u_data->io->draw_area->style->black_gc,
506 (guint32)(LEFT_BORDER+u_data->io->offset+(i-u_data->io->min_x)*u_data->io->x_interval),
507 u_data->io->pixmap_height-BOTTOM_BORDER,
508 (guint32)(LEFT_BORDER+u_data->io->offset+(i-u_data->io->min_x)*u_data->io->x_interval),
509 u_data->io->pixmap_height-BOTTOM_BORDER+length);
512 if (!u_data->io->uoff)
514 if (i%1000000==0 && j%w==0)
530 gdk_draw_line(u_data->io->pixmap,u_data->io->draw_area->style->black_gc,
531 (guint32)(LEFT_BORDER+u_data->io->offset+(i-u_data->io->min_x)*u_data->io->x_interval),
532 u_data->io->pixmap_height-BOTTOM_BORDER,
533 (guint32)(LEFT_BORDER+u_data->io->offset+(i-u_data->io->min_x)*u_data->io->x_interval),
534 u_data->io->pixmap_height-BOTTOM_BORDER+10);
536 g_snprintf(label_string, sizeof(label_string), "%d", sec);
537 memcpy(label_string,(gchar *)g_locale_to_utf8(label_string, -1 , NULL, NULL, NULL), sizeof(label_string));
538 pango_layout_set_text(layout, label_string, -1);
539 pango_layout_get_pixel_size(layout, &lwidth, NULL);
541 gdk_draw_layout(u_data->io->pixmap,u_data->io->draw_area->style->black_gc,
542 (guint32)(LEFT_BORDER+u_data->io->offset+(i-u_data->io->min_x)*u_data->io->x_interval-10),
543 u_data->io->pixmap_height-BOTTOM_BORDER+20,
550 g_strlcpy(label_string, "sec", sizeof(label_string));
552 memcpy(label_string,(gchar *)g_locale_to_utf8(label_string, -1 , NULL, NULL, NULL), sizeof(label_string));
553 pango_layout_set_text(layout, label_string, -1);
554 pango_layout_get_pixel_size(layout, &lwidth, NULL);
555 gdk_draw_layout(u_data->io->pixmap,
556 u_data->io->draw_area->style->black_gc,
557 u_data->io->pixmap_width-RIGHT_BORDER-10,
558 u_data->io->pixmap_height-BOTTOM_BORDER+30,
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,u_data->io->pixmap_height-BOTTOM_BORDER-u_data->io->offset);
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);
566 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);
568 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));
571 if (u_data->io->y_interval<1)
573 dis=1/u_data->io->y_interval;
581 distance=distance*10;
583 else if (u_data->io->y_interval<2)
586 if (u_data->io->max_y>0)
588 for (i=u_data->io->min_y/distance*distance; i<=u_data->io->max_y; i+=distance/5)
590 if (i>=u_data->io->min_y)
593 g_snprintf(label_string, sizeof(label_string), "%d", i);
594 if (i%distance==0 || (distance<=5 && u_data->io->y_interval>10))
598 memcpy(label_string,(gchar *)g_locale_to_utf8(label_string, -1 , NULL, NULL, NULL), sizeof(label_string));
599 pango_layout_set_text(layout, label_string, -1);
600 pango_layout_get_pixel_size(layout, &lwidth, NULL);
601 gdk_draw_layout(u_data->io->pixmap,u_data->io->draw_area->style->black_gc,
602 LEFT_BORDER-length-lwidth-5,
603 (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),
606 gdk_draw_line(u_data->io->pixmap,u_data->io->draw_area->style->black_gc,LEFT_BORDER-length,
607 (guint32)(u_data->io->pixmap_height-BOTTOM_BORDER-u_data->io->offset-(i-u_data->io->min_y)*u_data->io->y_interval),
609 (guint32)(u_data->io->pixmap_height-BOTTOM_BORDER-u_data->io->offset-(i-u_data->io->min_y)*u_data->io->y_interval));
613 else if ((u_data->dir==1 && u_data->assoc->n_array_tsn1==0) || (u_data->dir==2 && u_data->assoc->n_array_tsn2==0))
614 simple_dialog(ESD_TYPE_INFO, ESD_BTN_OK, "No Data Chunks sent");
618 static void sctp_graph_redraw(struct sctp_udata *u_data)
622 u_data->io->needs_redraw=TRUE;
624 sctp_graph_draw(u_data);
625 switch (u_data->io->graph_type)
628 draw_sack_graph(u_data);
629 draw_tsn_graph(u_data);
632 draw_tsn_graph(u_data);
635 draw_sack_graph(u_data);
638 ios=(sctp_graph_t *)g_object_get_data(G_OBJECT(u_data->io->draw_area), "sctp_graph_t");
645 gdk_draw_pixmap(u_data->io->draw_area->window,
646 u_data->io->draw_area->style->fg_gc[GTK_WIDGET_STATE(u_data->io->draw_area)],
650 u_data->io->draw_area->allocation.width,
651 u_data->io->draw_area->allocation.height);
655 static void on_sack_bt(GtkWidget *widget _U_, struct sctp_udata *u_data)
658 u_data = (struct sctp_udata *) u_data;
659 u_data->io->graph_type=2;
660 sctp_graph_redraw(u_data);
663 static void on_tsn_bt(GtkWidget *widget _U_, struct sctp_udata *u_data)
666 u_data->io->graph_type=1;
667 sctp_graph_redraw(u_data);
670 static void on_both_bt(GtkWidget *widget _U_, struct sctp_udata *u_data)
673 u_data->io->graph_type=0;
674 sctp_graph_redraw(u_data);
678 sctp_graph_close_cb(GtkWidget* widget _U_, gpointer u_data)
680 struct sctp_udata *udata;
683 udata = (struct sctp_udata *)u_data;
685 gtk_grab_remove(GTK_WIDGET(udata->io->window));
686 gtk_widget_destroy(GTK_WIDGET(udata->io->window));
691 configure_event(GtkWidget *widget, GdkEventConfigure *event _U_, struct sctp_udata *u_data)
697 if(u_data->io->pixmap){
698 gdk_pixmap_unref(u_data->io->pixmap);
699 u_data->io->pixmap=NULL;
702 u_data->io->pixmap=gdk_pixmap_new(widget->window,
703 widget->allocation.width,
704 widget->allocation.height,
706 u_data->io->pixmap_width=widget->allocation.width;
707 u_data->io->pixmap_height=widget->allocation.height;
709 gdk_draw_rectangle(u_data->io->pixmap,
710 widget->style->white_gc,
713 widget->allocation.width,
714 widget->allocation.height);
715 sctp_graph_redraw(u_data);
720 expose_event(GtkWidget *widget, GdkEventExpose *event)
724 ios=(sctp_graph_t *)g_object_get_data(G_OBJECT(widget), "sctp_graph_t");
729 gdk_draw_pixmap(widget->window,
730 widget->style->fg_gc[GTK_WIDGET_STATE(widget)],
732 event->area.x, event->area.y,
733 event->area.x, event->area.y,
734 event->area.width, event->area.height);
741 on_zoomin_bt (GtkWidget *widget _U_, struct sctp_udata *u_data)
743 sctp_min_max_t *tmp_minmax;
745 if (u_data->io->rectangle_present==TRUE)
747 tmp_minmax = g_malloc(sizeof(sctp_min_max_t));
749 u_data->io->tmp_min_tsn1=u_data->io->y1_tmp+u_data->io->min_y;
750 u_data->io->tmp_max_tsn1=u_data->io->y2_tmp+1+u_data->io->min_y;
751 u_data->io->tmp_min_tsn2=u_data->io->tmp_min_tsn1;
752 u_data->io->tmp_max_tsn2=u_data->io->tmp_max_tsn1;
753 tmp_minmax->tmp_min_secs=u_data->io->x1_tmp_sec;
754 tmp_minmax->tmp_min_usecs= u_data->io->x1_tmp_usec;
755 tmp_minmax->tmp_max_secs= u_data->io->x2_tmp_sec;
756 tmp_minmax->tmp_max_usecs= u_data->io->x2_tmp_usec;
757 tmp_minmax->tmp_min_tsn1=u_data->io->tmp_min_tsn1;
758 tmp_minmax->tmp_max_tsn1=u_data->io->tmp_max_tsn1;
759 tmp_minmax->tmp_min_tsn2=u_data->io->tmp_min_tsn2;
760 tmp_minmax->tmp_max_tsn2=u_data->io->tmp_max_tsn2;
761 u_data->assoc->min_max = g_slist_prepend(u_data->assoc->min_max, tmp_minmax);
762 u_data->io->length = g_slist_length(u_data->assoc->min_max);
763 u_data->io->tmp=TRUE;
764 u_data->io->rectangle=FALSE;
765 u_data->io->rectangle_present=FALSE;
766 gtk_widget_set_sensitive(zoomout_bt, TRUE);
767 sctp_graph_redraw(u_data);
771 simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK, "Please draw a rectangle around the area you want to zoom in!");
776 zoomin_bt (struct sctp_udata *u_data)
778 sctp_min_max_t *tmp_minmax;
780 tmp_minmax = g_malloc(sizeof(sctp_min_max_t));
782 u_data->io->tmp_min_tsn1=u_data->io->y1_tmp+u_data->io->min_y;
783 u_data->io->tmp_max_tsn1=u_data->io->y2_tmp+1+u_data->io->min_y;
784 u_data->io->tmp_min_tsn2=u_data->io->tmp_min_tsn1;
785 u_data->io->tmp_max_tsn2=u_data->io->tmp_max_tsn1;
786 tmp_minmax->tmp_min_secs=u_data->io->x1_tmp_sec;
787 tmp_minmax->tmp_min_usecs= u_data->io->x1_tmp_usec;
788 tmp_minmax->tmp_max_secs= u_data->io->x2_tmp_sec;
789 tmp_minmax->tmp_max_usecs= u_data->io->x2_tmp_usec;
790 tmp_minmax->tmp_min_tsn1=u_data->io->tmp_min_tsn1;
791 tmp_minmax->tmp_max_tsn1=u_data->io->tmp_max_tsn1;
792 tmp_minmax->tmp_min_tsn2=u_data->io->tmp_min_tsn2;
793 tmp_minmax->tmp_max_tsn2=u_data->io->tmp_max_tsn2;
794 u_data->assoc->min_max = g_slist_prepend(u_data->assoc->min_max, tmp_minmax);
795 u_data->io->length = g_slist_length(u_data->assoc->min_max);
796 u_data->io->tmp=TRUE;
797 u_data->io->rectangle=FALSE;
798 u_data->io->rectangle_present=FALSE;
799 gtk_widget_set_sensitive(zoomout_bt, TRUE);
800 sctp_graph_redraw(u_data);
807 on_zoomout_bt (GtkWidget *widget _U_, struct sctp_udata *u_data)
809 sctp_min_max_t *tmp_minmax, *mm;
812 l = g_slist_length(u_data->assoc->min_max);
814 if (u_data->assoc->min_max!=NULL)
816 mm=(sctp_min_max_t *)((u_data->assoc->min_max)->data);
817 u_data->assoc->min_max=g_slist_remove(u_data->assoc->min_max, mm);
821 tmp_minmax = (sctp_min_max_t *)u_data->assoc->min_max->data;
822 u_data->io->x1_tmp_sec=tmp_minmax->tmp_min_secs;
823 u_data->io->x1_tmp_usec=tmp_minmax->tmp_min_usecs;
824 u_data->io->x2_tmp_sec=tmp_minmax->tmp_max_secs;
825 u_data->io->x2_tmp_usec=tmp_minmax->tmp_max_usecs;
826 u_data->io->tmp_min_tsn1=tmp_minmax->tmp_min_tsn1;
827 u_data->io->tmp_max_tsn1=tmp_minmax->tmp_max_tsn1;
828 u_data->io->tmp_min_tsn2=tmp_minmax->tmp_min_tsn2;
829 u_data->io->tmp_max_tsn2=tmp_minmax->tmp_max_tsn2;
830 u_data->io->tmp=TRUE;
834 u_data->io->x1_tmp_sec=u_data->assoc->min_secs;
835 u_data->io->x1_tmp_usec=u_data->assoc->min_usecs;
836 u_data->io->x2_tmp_sec=u_data->assoc->max_secs;
837 u_data->io->x2_tmp_usec=u_data->assoc->max_usecs;
838 u_data->io->tmp_min_tsn1=u_data->assoc->min_tsn1;
839 u_data->io->tmp_max_tsn1=u_data->assoc->max_tsn1;
840 u_data->io->tmp_min_tsn2=u_data->assoc->min_tsn2;
841 u_data->io->tmp_max_tsn2=u_data->assoc->max_tsn2;
842 u_data->io->tmp=FALSE;
847 u_data->io->x1_tmp_sec=u_data->assoc->min_secs;
848 u_data->io->x1_tmp_usec=u_data->assoc->min_usecs;
849 u_data->io->x2_tmp_sec=u_data->assoc->max_secs;
850 u_data->io->x2_tmp_usec=u_data->assoc->max_usecs;
851 u_data->io->tmp_min_tsn1=u_data->assoc->min_tsn1;
852 u_data->io->tmp_max_tsn1=u_data->assoc->max_tsn1;
853 u_data->io->tmp_min_tsn2=u_data->assoc->min_tsn2;
854 u_data->io->tmp_max_tsn2=u_data->assoc->max_tsn2;
855 u_data->io->tmp=FALSE;
857 if (g_slist_length(u_data->assoc->min_max)==1)
858 gtk_widget_set_sensitive(zoomout_bt, FALSE);
859 sctp_graph_redraw(u_data);
863 on_button_press (GtkWidget *widget _U_, GdkEventButton *event, struct sctp_udata *u_data)
867 if (u_data->io->rectangle==TRUE)
869 gdk_draw_rectangle(u_data->io->pixmap,u_data->io->draw_area->style->white_gc,
871 (gint)floor(MIN(u_data->io->x_old,u_data->io->x_new)),
872 (gint)floor(MIN(u_data->io->y_old,u_data->io->y_new)),
873 (gint)floor(abs((long)(u_data->io->x_new-u_data->io->x_old))),
874 (gint)floor(abs((long)(u_data->io->y_new-u_data->io->y_old))));
875 ios=(sctp_graph_t *)g_object_get_data(G_OBJECT(u_data->io->draw_area), "sctp_graph_t");
881 gdk_draw_pixmap(u_data->io->draw_area->window,
882 u_data->io->draw_area->style->fg_gc[GTK_WIDGET_STATE(u_data->io->draw_area)],
886 (gint)(abs((long)(u_data->io->x_new-u_data->io->x_old))),
887 (gint)(abs((long)(u_data->io->y_new-u_data->io->y_old))));
888 sctp_graph_redraw(u_data);
890 u_data->io->x_old=event->x;
891 u_data->io->y_old=event->y;
892 if (u_data->io->y_old>u_data->io->pixmap_height-BOTTOM_BORDER-u_data->io->offset-POINT_SIZE)
893 u_data->io->y_old=u_data->io->pixmap_height-BOTTOM_BORDER-u_data->io->offset-POINT_SIZE;
894 if (u_data->io->x_old<LEFT_BORDER+u_data->io->offset)
895 u_data->io->x_old=LEFT_BORDER+u_data->io->offset;
896 u_data->io->rectangle=FALSE;
903 on_button_release (GtkWidget *widget _U_, GdkEventButton *event, struct sctp_udata *u_data)
906 guint32 helpx, helpy, x1_tmp, x2_tmp, y_value, t_size=0, s_size=0, i, y_tolerance;
907 gint label_width, label_height;
908 gdouble x_value, position, s_diff=0, t_diff=0, x_tolerance=0.0001;
910 char label_string[30];
912 GPtrArray *tsnlist = NULL, *sacklist=NULL;
913 struct tsn_sort *tsn, *sack=NULL;
914 gboolean sack_found = FALSE;
917 g_snprintf(label_string, 15, "%d", 0);
918 memcpy(label_string,(gchar *)g_locale_to_utf8(label_string, -1 , NULL, NULL, NULL), 15);
919 layout = gtk_widget_create_pango_layout(u_data->io->draw_area, label_string);
920 pango_layout_get_pixel_size(layout, &label_width, &label_height);
922 if (event->y>u_data->io->pixmap_height-BOTTOM_BORDER-u_data->io->offset)
923 event->y = u_data->io->pixmap_height-BOTTOM_BORDER-u_data->io->offset;
924 if (event->x < LEFT_BORDER+u_data->io->offset)
925 event->x = LEFT_BORDER+u_data->io->offset;
926 if (abs((long)(event->x-u_data->io->x_old))>10 || abs((long)(event->y-u_data->io->y_old))>10)
928 u_data->io->rect_x_min = (gint)floor(MIN(u_data->io->x_old,event->x));
929 u_data->io->rect_x_max = (gint)ceil(MAX(u_data->io->x_old,event->x));
930 u_data->io->rect_y_min = (gint)floor(MIN(u_data->io->y_old,event->y));
931 u_data->io->rect_y_max = (gint)ceil(MAX(u_data->io->y_old,event->y))+POINT_SIZE;
932 gdk_draw_rectangle(u_data->io->pixmap,u_data->io->draw_area->style->black_gc,
934 u_data->io->rect_x_min, u_data->io->rect_y_min,
935 u_data->io->rect_x_max - u_data->io->rect_x_min,
936 u_data->io->rect_y_max - u_data->io->rect_y_min);
937 ios=(sctp_graph_t *)g_object_get_data(G_OBJECT(u_data->io->draw_area), "sctp_graph_t");
943 gdk_draw_pixmap(u_data->io->draw_area->window,
944 u_data->io->draw_area->style->fg_gc[GTK_WIDGET_STATE(u_data->io->draw_area)],
948 u_data->io->draw_area->allocation.width,
949 u_data->io->draw_area->allocation.height);
951 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));
952 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));
953 helpx=MIN(x1_tmp, x2_tmp);
959 if (u_data->io->uoff)
961 if (x2_tmp - x1_tmp <= 1500)
962 u_data->io->uoff = FALSE;
963 u_data->io->x1_tmp_sec=(guint32)x1_tmp;
964 u_data->io->x1_tmp_usec=0;
965 u_data->io->x2_tmp_sec=(guint32)x2_tmp;
966 u_data->io->x2_tmp_usec=0;
970 u_data->io->x1_tmp_sec=(guint32)x1_tmp/1000000;
971 u_data->io->x1_tmp_usec=x1_tmp%1000000;
972 u_data->io->x2_tmp_sec=(guint32)x2_tmp/1000000;
973 u_data->io->x2_tmp_usec=x2_tmp%1000000;
975 u_data->io->x1_akt_sec = u_data->io->x1_tmp_sec;
976 u_data->io->x1_akt_usec = u_data->io->x1_tmp_usec;
977 u_data->io->x2_akt_sec = u_data->io->x2_tmp_sec;
978 u_data->io->x2_akt_usec = u_data->io->x2_tmp_usec;
980 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);
981 u_data->io->y2_tmp=(guint32)((u_data->io->pixmap_height-BOTTOM_BORDER-u_data->io->offset-event->y)/u_data->io->y_interval);
982 helpy = MIN(u_data->io->y1_tmp, u_data->io->y2_tmp);
983 u_data->io->y2_tmp = MAX(u_data->io->y1_tmp, u_data->io->y2_tmp);
984 u_data->io->y1_tmp = helpy;
985 u_data->io->x_new=event->x;
986 u_data->io->y_new=event->y;
987 u_data->io->rectangle=TRUE;
988 u_data->io->rectangle_present=TRUE;
992 if (u_data->io->rectangle_present==TRUE)
994 u_data->io->rectangle_present=FALSE;
995 if (event->x >= u_data->io->rect_x_min && event->x <= u_data->io->rect_x_max &&
996 event->y >= u_data->io->rect_y_min && event->y <= u_data->io->rect_y_max)
1000 u_data->io->x1_tmp_sec = u_data->io->x1_akt_sec;
1001 u_data->io->x1_tmp_usec = u_data->io->x1_akt_usec;
1002 u_data->io->x2_tmp_sec = u_data->io->x2_akt_sec;
1003 u_data->io->x2_tmp_usec = u_data->io->x2_akt_usec;
1004 sctp_graph_redraw(u_data);
1010 sctp_graph_redraw(u_data);
1014 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;
1015 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;
1016 text_color = u_data->io->draw_area->style->black_gc;
1018 if (u_data->dir == 1)
1020 tsnlist = u_data->assoc->sort_tsn1;
1021 t_size = u_data->assoc->n_data_chunks_ep1;
1022 sacklist = u_data->assoc->sort_sack1;
1023 s_size = u_data->assoc->n_sack_chunks_ep1;
1027 tsnlist = u_data->assoc->sort_tsn2;
1028 t_size = u_data->assoc->n_data_chunks_ep2;
1029 sacklist = u_data->assoc->sort_sack2;
1030 s_size = u_data->assoc->n_sack_chunks_ep2;
1032 x_tolerance = (gdouble)((u_data->io->tmp_width / u_data->io->axis_width*1.0))*5/1000000.0;
1033 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);
1036 else if (y_tolerance > 5)
1039 for (i=0; i<s_size; i++)
1041 sack = (struct tsn_sort*)(g_ptr_array_index(sacklist, i));
1042 if ((guint32)abs(sack->tsnumber - y_value)<y_tolerance)
1044 s_diff = fabs((sack->secs+sack->usecs/1000000.0)- x_value);
1045 if (s_diff < x_tolerance)
1051 for (i=0; i<t_size; i++)
1053 tsn = (struct tsn_sort*)(g_ptr_array_index(tsnlist, i));
1054 if ((guint32)abs(tsn->tsnumber - y_value)<y_tolerance)
1056 t_diff = fabs((tsn->secs+tsn->usecs/1000000.0)- x_value);
1057 if (sack_found && s_diff < t_diff)
1059 cf_goto_frame(&cfile, sack->framenumber);
1060 x_value = sack->secs+sack->usecs/1000000.0;
1061 y_value = sack->tsnumber;
1063 else if (t_diff < x_tolerance)
1065 cf_goto_frame(&cfile, tsn->framenumber);
1066 x_value = tsn->secs+tsn->usecs/1000000.0;
1067 y_value = tsn->tsnumber;
1073 g_snprintf(label_string, sizeof(label_string), "(%.6lf, %u)", x_value, y_value);
1077 gdk_draw_line(u_data->io->pixmap,text_color, (gint)(event->x-2), (gint)(event->y), (gint)(event->x+2), (gint)(event->y));
1078 gdk_draw_line(u_data->io->pixmap,text_color, (gint)(event->x), (gint)(event->y-2), (gint)(event->x), (gint)(event->y+2));
1079 if (event->x+150>=u_data->io->pixmap_width)
1080 position = event->x - 150;
1082 position = event->x + 5;
1085 memcpy(label_string,(gchar *)g_locale_to_utf8(label_string, -1 , NULL, NULL, NULL), 15);
1086 pango_layout_set_text(layout, label_string, -1);
1087 pango_layout_get_pixel_size(layout, &lwidth, NULL);
1089 gdk_draw_layout(u_data->io->pixmap,text_color,
1091 (gint)(event->y-10),
1094 ios=(sctp_graph_t *)g_object_get_data(G_OBJECT(u_data->io->draw_area), "sctp_graph_t");
1099 gdk_draw_pixmap(u_data->io->draw_area->window,
1100 u_data->io->draw_area->style->fg_gc[GTK_WIDGET_STATE(u_data->io->draw_area)],
1104 u_data->io->draw_area->allocation.width,
1105 u_data->io->draw_area->allocation.height);
1112 static void init_sctp_graph_window(struct sctp_udata *u_data)
1116 GtkWidget *bt_close, *sack_bt, *tsn_bt, *both_bt, *zoomin_bt;
1117 GtkTooltips *tooltip_in, *tooltip_out;
1119 /* create the main window */
1121 u_data->io->window=gtk_window_new(GTK_WINDOW_TOPLEVEL);
1123 gtk_widget_set_name(u_data->io->window, "SCTP Graphics");
1125 vbox=gtk_vbox_new(FALSE, 0);
1126 gtk_container_add(GTK_CONTAINER(u_data->io->window), vbox);
1127 gtk_widget_show(vbox);
1129 create_draw_area(vbox, u_data);
1131 sctp_graph_set_title(u_data);
1133 hbox = gtk_hbutton_box_new();
1134 gtk_box_pack_start(GTK_BOX(vbox), hbox, FALSE, FALSE, 0);
1135 gtk_container_set_border_width(GTK_CONTAINER(hbox), 10);
1136 gtk_button_box_set_layout(GTK_BUTTON_BOX (hbox), GTK_BUTTONBOX_SPREAD);
1137 gtk_box_set_spacing(GTK_BOX (hbox), 0);
1138 gtk_box_set_child_packing(GTK_BOX(vbox), hbox, FALSE, FALSE, 0, GTK_PACK_START);
1139 gtk_widget_show(hbox);
1141 sack_bt = gtk_button_new_with_label ("Show Sacks");
1142 gtk_box_pack_start(GTK_BOX(hbox), sack_bt, FALSE, FALSE, 0);
1143 gtk_widget_show(sack_bt);
1145 g_signal_connect(sack_bt, "clicked", G_CALLBACK(on_sack_bt), u_data);
1147 tsn_bt = gtk_button_new_with_label ("Show TSNs");
1148 gtk_box_pack_start(GTK_BOX(hbox), tsn_bt, FALSE, FALSE, 0);
1149 gtk_widget_show(tsn_bt);
1150 g_signal_connect(tsn_bt, "clicked", G_CALLBACK(on_tsn_bt), u_data);
1152 both_bt = gtk_button_new_with_label ("Show both");
1153 gtk_box_pack_start(GTK_BOX(hbox), both_bt, FALSE, FALSE, 0);
1154 gtk_widget_show(both_bt);
1155 g_signal_connect(both_bt, "clicked", G_CALLBACK(on_both_bt), u_data);
1157 zoomin_bt = gtk_button_new_with_label ("Zoom in");
1158 gtk_box_pack_start(GTK_BOX(hbox), zoomin_bt, FALSE, FALSE, 0);
1159 gtk_widget_show(zoomin_bt);
1160 g_signal_connect(zoomin_bt, "clicked", G_CALLBACK(on_zoomin_bt), u_data);
1161 tooltip_in = gtk_tooltips_new();
1162 gtk_tooltips_set_tip(tooltip_in, zoomin_bt, "Zoom in the area you have selected", NULL);
1164 zoomout_bt = gtk_button_new_with_label ("Zoom out");
1165 gtk_box_pack_start(GTK_BOX(hbox), zoomout_bt, FALSE, FALSE, 0);
1166 gtk_widget_show(zoomout_bt);
1167 g_signal_connect(zoomout_bt, "clicked", G_CALLBACK(on_zoomout_bt), u_data);
1168 tooltip_out = gtk_tooltips_new();
1169 gtk_tooltips_set_tip(tooltip_out, zoomout_bt, "Zoom out one step", NULL);
1170 gtk_widget_set_sensitive(zoomout_bt, FALSE);
1172 bt_close = gtk_button_new_from_stock(GTK_STOCK_CLOSE);
1173 gtk_box_pack_start(GTK_BOX(hbox), bt_close, FALSE, FALSE, 0);
1174 gtk_widget_show(bt_close);
1175 g_signal_connect(bt_close, "clicked", G_CALLBACK(sctp_graph_close_cb), u_data);
1177 g_signal_connect(u_data->io->draw_area,"button_press_event",G_CALLBACK(on_button_press), u_data);
1178 g_signal_connect(u_data->io->draw_area,"button_release_event",G_CALLBACK(on_button_release), u_data);
1179 gtk_widget_set_events(u_data->io->draw_area, GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK | GDK_EXPOSURE_MASK);
1181 gtk_widget_show(u_data->io->window);
1184 static void sctp_graph_set_title(struct sctp_udata *u_data)
1188 if(!u_data->io->window)
1192 title = g_strdup_printf("SCTP TSNs and Sacks over Time: %s Port1 %u Port2 %u Endpoint %u",
1193 cf_get_display_name(&cfile), u_data->parent->assoc->port1, u_data->parent->assoc->port2, u_data->dir);
1194 gtk_window_set_title(GTK_WINDOW(u_data->io->window), title);
1199 gtk_sctpgraph_init(struct sctp_udata *u_data)
1203 sctp_min_max_t* tmp_minmax;
1205 io=g_malloc(sizeof(sctp_graph_t));
1206 io->needs_redraw=TRUE;
1207 io->x_interval=1000;
1211 io->pixmap_width=800;
1212 io->pixmap_height=600;
1216 u_data->io->x1_tmp_sec=u_data->assoc->min_secs;
1217 u_data->io->x1_tmp_usec=u_data->assoc->min_usecs;
1218 u_data->io->x2_tmp_sec=u_data->assoc->max_secs;
1219 u_data->io->x2_tmp_usec=u_data->assoc->max_usecs;
1220 u_data->io->tmp_min_tsn1=u_data->assoc->min_tsn1;
1221 u_data->io->tmp_max_tsn1=u_data->assoc->max_tsn1;
1222 u_data->io->tmp_min_tsn2=u_data->assoc->min_tsn2;
1223 u_data->io->tmp_max_tsn2=u_data->assoc->max_tsn2;
1224 u_data->io->tmp=FALSE;
1226 tmp_minmax = g_malloc(sizeof(sctp_min_max_t));
1227 tmp_minmax->tmp_min_secs = u_data->assoc->min_secs;
1228 tmp_minmax->tmp_min_usecs=u_data->assoc->min_usecs;
1229 tmp_minmax->tmp_max_secs=u_data->assoc->max_secs;
1230 tmp_minmax->tmp_max_usecs=u_data->assoc->max_usecs;
1231 tmp_minmax->tmp_min_tsn2=u_data->assoc->min_tsn2;
1232 tmp_minmax->tmp_min_tsn1=u_data->assoc->min_tsn1;
1233 tmp_minmax->tmp_max_tsn1=u_data->assoc->max_tsn1;
1234 tmp_minmax->tmp_max_tsn2=u_data->assoc->max_tsn2;
1235 u_data->assoc->min_max = g_slist_prepend(u_data->assoc->min_max, tmp_minmax);
1238 init_sctp_graph_window(u_data);
1239 sctp_graph_redraw(u_data);
1245 quit(GtkObject *object _U_, gpointer user_data)
1247 struct sctp_udata *u_data=(struct sctp_udata*)user_data;
1249 decrease_childcount(u_data->parent);
1250 remove_child(u_data, u_data->parent);
1254 u_data->assoc->min_max = NULL;
1260 static void create_draw_area(GtkWidget *box, struct sctp_udata *u_data)
1263 u_data->io->draw_area=gtk_drawing_area_new();
1264 g_signal_connect(u_data->io->draw_area, "destroy", G_CALLBACK(quit), u_data);
1265 g_object_set_data(G_OBJECT(u_data->io->draw_area), "sctp_graph_t", u_data->io);
1267 gtk_widget_set_size_request(u_data->io->draw_area, u_data->io->pixmap_width, u_data->io->pixmap_height);
1269 /* signals needed to handle backing pixmap */
1270 g_signal_connect(u_data->io->draw_area, "expose_event", G_CALLBACK(expose_event), NULL);
1271 g_signal_connect(u_data->io->draw_area, "configure_event", G_CALLBACK(configure_event), u_data);
1273 gtk_widget_show(u_data->io->draw_area);
1274 gtk_box_pack_start(GTK_BOX(box), u_data->io->draw_area, TRUE, TRUE, 0);
1279 void create_graph(guint16 dir, struct sctp_analyse* userdata)
1281 struct sctp_udata *u_data;
1283 u_data=g_malloc(sizeof(struct sctp_udata));
1284 u_data->assoc=g_malloc(sizeof(sctp_assoc_info_t));
1285 u_data->assoc=userdata->assoc;
1288 u_data->parent = userdata;
1289 if ((u_data->dir==1 && u_data->assoc->n_array_tsn1==0)|| (u_data->dir==2 && u_data->assoc->n_array_tsn2==0))
1290 simple_dialog(ESD_TYPE_INFO, ESD_BTN_OK, "No Data Chunks sent");
1293 set_child(u_data, u_data->parent);
1294 increase_childcount(u_data->parent);
1295 gtk_sctpgraph_init(u_data);
1299 #if defined(_WIN32) && !defined(__MINGW32__)
1300 /* replacement of Unix rint() for Windows */
1301 static int rint (double x)
1306 buf = _fcvt(x, 0, &dec, &sig);