summaryrefslogtreecommitdiff
path: root/ui/gtk/tcp_graph.c
diff options
context:
space:
mode:
Diffstat (limited to 'ui/gtk/tcp_graph.c')
-rw-r--r--ui/gtk/tcp_graph.c8346
1 files changed, 4180 insertions, 4166 deletions
diff --git a/ui/gtk/tcp_graph.c b/ui/gtk/tcp_graph.c
index 363f713167..e688aad108 100644
--- a/ui/gtk/tcp_graph.c
+++ b/ui/gtk/tcp_graph.c
@@ -55,316 +55,323 @@
#include "ui/gtk/old-gtk-compat.h"
-#define TCP_SYN(flags) ( flags & TH_SYN )
-#define TCP_ACK(flags) ( flags & TH_ACK )
-#define TCP_FIN(flags) ( flags & TH_FIN )
+#define TCP_SYN(flags) ( flags & TH_SYN )
+#define TCP_ACK(flags) ( flags & TH_ACK )
+#define TCP_FIN(flags) ( flags & TH_FIN )
-#define TXT_WIDTH 850
-#define TXT_HEIGHT 550
+#define TXT_WIDTH 850
+#define TXT_HEIGHT 550
/* for compare_headers() */
/* segment went the same direction as the currently selected one */
-#define COMPARE_CURR_DIR 0
-#define COMPARE_ANY_DIR 1
+#define COMPARE_CURR_DIR 0
+#define COMPARE_ANY_DIR 1
/* initialize_axis() */
-#define AXIS_HORIZONTAL 0
-#define AXIS_VERTICAL 1
+#define AXIS_HORIZONTAL 0
+#define AXIS_VERTICAL 1
#define WINDOW_TITLE_LENGTH 256
-#define MOUSE_BUTTON_LEFT 1
-#define MOUSE_BUTTON_MIDDLE 2
-#define MOUSE_BUTTON_RIGHT 3
+#define MOUSE_BUTTON_LEFT 1
+#define MOUSE_BUTTON_MIDDLE 2
+#define MOUSE_BUTTON_RIGHT 3
struct segment {
- struct segment *next;
- guint32 num;
- guint32 rel_secs;
- guint32 rel_usecs;
- guint32 abs_secs;
- guint32 abs_usecs;
-
- guint32 th_seq;
- guint32 th_ack;
- guint16 th_flags;
- guint32 th_win; /* make it 32 bits so we can handle some scaling */
- guint32 th_seglen;
- guint16 th_sport;
- guint16 th_dport;
- address ip_src;
- address ip_dst;
-
- guint8 num_sack_ranges;
- guint32 sack_left_edge[MAX_TCP_SACK_RANGES];
- guint32 sack_right_edge[MAX_TCP_SACK_RANGES];
+ struct segment *next;
+ guint32 num;
+ guint32 rel_secs;
+ guint32 rel_usecs;
+ guint32 abs_secs;
+ guint32 abs_usecs;
+
+ guint32 th_seq;
+ guint32 th_ack;
+ guint16 th_flags;
+ guint32 th_win; /* make it 32 bits so we can handle some scaling */
+ guint32 th_seglen;
+ guint16 th_sport;
+ guint16 th_dport;
+ address ip_src;
+ address ip_dst;
+
+ guint8 num_sack_ranges;
+ guint32 sack_left_edge[MAX_TCP_SACK_RANGES];
+ guint32 sack_right_edge[MAX_TCP_SACK_RANGES];
};
struct rect {
- double x, y, width, height;
+ double x, y, width, height;
};
struct line {
- double x1, y1, x2, y2;
+ double x1, y1, x2, y2;
};
struct irect {
- int x, y, width, height;
+ int x, y, width, height;
};
struct ipoint {
- int x, y;
+ int x, y;
};
struct zoomfactor {
- double x, y;
+ double x, y;
};
typedef enum {
- ELMT_NONE=0,
- ELMT_RECT=1,
- ELMT_LINE=2,
- ELMT_ELLIPSE=3
+ ELMT_NONE=0,
+ ELMT_RECT=1,
+ ELMT_LINE=2,
+ ELMT_ELLIPSE=3
} ElementType;
struct rect_params {
- struct rect dim;
- gint filled;
+ struct rect dim;
+ gint filled;
};
struct line_params {
- struct line dim;
+ struct line dim;
};
struct ellipse_params {
- struct rect dim;
+ struct rect dim;
};
struct element {
- ElementType type;
- GdkColor *elment_color_p;
- struct segment *parent;
- union {
- struct ellipse_params ellipse;
- struct rect_params rect;
- struct line_params line;
- } p;
+ ElementType type;
+ GdkColor *elment_color_p;
+ struct segment *parent;
+ union {
+ struct ellipse_params ellipse;
+ struct rect_params rect;
+ struct line_params line;
+ } p;
};
struct element_list {
- struct element_list *next;
- struct element *elements;
+ struct element_list *next;
+ struct element *elements;
};
struct axis {
- struct graph *g; /* which graph we belong to */
- GtkWidget *drawing_area;
+ struct graph *g; /* which graph we belong to */
+ GtkWidget *drawing_area;
#if GTK_CHECK_VERSION(2,22,0)
- cairo_surface_t *surface[2];
+ cairo_surface_t *surface[2];
#else
- GdkPixmap *pixmap[2];
+ GdkPixmap *pixmap[2];
#endif
- int displayed;
-#define AXIS_ORIENTATION 1 << 0
- int flags;
- /* dim and orig (relative to origin of window) of axis' pixmap */
- struct irect p;
- /* dim and orig (relative to origin of axis' pixmap) of scale itself */
- struct irect s;
- gdouble min, max;
- gdouble major, minor; /* major and minor ticks */
- const char **label;
+ int displayed;
+#define AXIS_ORIENTATION 1 << 0
+ int flags;
+ /* dim and orig (relative to origin of window) of axis' pixmap */
+ struct irect p;
+ /* dim and orig (relative to origin of axis' pixmap) of scale itself */
+ struct irect s;
+ gdouble min, max;
+ gdouble major, minor; /* major and minor ticks */
+ const char **label;
};
-#define HAXIS_INIT_HEIGHT 70
-#define VAXIS_INIT_WIDTH 100
-#define TITLEBAR_HEIGHT 50
-#define RMARGIN_WIDTH 30
+#define HAXIS_INIT_HEIGHT 70
+#define VAXIS_INIT_WIDTH 100
+#define TITLEBAR_HEIGHT 50
+#define RMARGIN_WIDTH 30
struct style_tseq_tcptrace {
- GdkColor seq_color;
- GdkColor ack_color[2];
- GdkColor sack_color[2];
- int flags;
+ GdkColor seq_color;
+ GdkColor ack_color[2];
+ GdkColor sack_color[2];
+ int flags;
};
struct style_tseq_stevens {
- int seq_width;
- int seq_height;
- int flags;
+ int seq_width;
+ int seq_height;
+ int flags;
};
struct style_tput {
- int width, height;
- int nsegs;
- int flags;
+ int width, height;
+ int nsegs;
+ int flags;
};
struct style_rtt {
- int width, height;
- int flags;
+ int width, height;
+ int flags;
};
struct style_wscale {
- int win_width;
- int win_height;
- int flags;
+ int win_width;
+ int win_height;
+ int flags;
};
/* style flags */
-#define SEQ_ORIGIN 0x1
+#define SEQ_ORIGIN 0x1
/* show absolute sequence numbers (not differences from isn) */
-#define SEQ_ORIGIN_ZERO 0x1
-#define SEQ_ORIGIN_ISN 0x0
-#define TIME_ORIGIN 0x10
+#define SEQ_ORIGIN_ZERO 0x1
+#define SEQ_ORIGIN_ISN 0x0
+#define TIME_ORIGIN 0x10
/* show time from beginning of capture as opposed to time from beginning
* of the connection */
-#define TIME_ORIGIN_CAP 0x10
-#define TIME_ORIGIN_CONN 0x0
+#define TIME_ORIGIN_CAP 0x10
+#define TIME_ORIGIN_CONN 0x0
/* this is used by rtt module only */
struct unack {
- struct unack *next;
- double time;
- unsigned int seqno;
+ struct unack *next;
+ double time;
+ unsigned int seqno;
};
struct cross {
- int x, y;
- int draw; /* indicates whether we should draw cross at all */
- int erase_needed;
- GtkToggleButton *on_toggle;
- GtkToggleButton *off_toggle;
+ int x, y;
+ int draw; /* indicates whether we should draw cross at all */
+ int erase_needed;
+ GtkToggleButton *on_toggle;
+ GtkToggleButton *off_toggle;
};
struct bounds {
- double x0, y0, width, height;
+ double x0, y0, width, height;
};
struct zoom {
- double x, y;
+ double x, y;
};
struct zooms {
- double x, y;
- double step_x, step_y;
- struct zoom initial;
-#define ZOOM_OUT (1 << 0)
-#define ZOOM_HLOCK (1 << 1)
-#define ZOOM_VLOCK (1 << 2)
-#define ZOOM_STEPS_SAME (1 << 3)
-#define ZOOM_STEPS_KEEP_RATIO (1 << 4)
- int flags;
- /* unfortunately, we need them both because gtk_toggle_button_set_active ()
- * with second argument FALSE doesn't do anything, somehow */
- struct {
- GtkToggleButton *in_toggle;
- GtkToggleButton *out_toggle;
- GtkEntry *h_zoom;
- GtkEntry *v_zoom;
- GtkSpinButton *h_step;
- GtkSpinButton *v_step;
- } widget;
+ double x, y;
+ double step_x, step_y;
+ struct zoom initial;
+#define ZOOM_OUT (1 << 0)
+#define ZOOM_HLOCK (1 << 1)
+#define ZOOM_VLOCK (1 << 2)
+#define ZOOM_STEPS_SAME (1 << 3)
+#define ZOOM_STEPS_KEEP_RATIO (1 << 4)
+ int flags;
+ /* unfortunately, we need them both because gtk_toggle_button_set_active()
+ * with second argument FALSE doesn't do anything, somehow */
+ struct {
+ GtkToggleButton *in_toggle;
+ GtkToggleButton *out_toggle;
+ GtkEntry *h_zoom;
+ GtkEntry *v_zoom;
+ GtkSpinButton *h_step;
+ GtkSpinButton *v_step;
+ } widget;
};
struct grab {
- int grabbed;
- int x, y;
+ int grabbed;
+ int x, y;
};
struct magnify {
- int active;
- int x, y;
- struct ipoint offset;
- int width, height;
- struct zoom zoom;
- struct graph *g;
-#define MAGZOOMS_SAME (1U << 0)
-#define MAGZOOMS_SAME_RATIO (1U << 1)
-#define MAGZOOMS_IGNORE (1U << 31)
- guint flags;
- struct {
- GtkSpinButton *h_zoom, *v_zoom;
- } widget;
+ int active;
+ int x, y;
+ struct ipoint offset;
+ int width, height;
+ struct zoom zoom;
+ struct graph *g;
+#define MAGZOOMS_SAME (1U << 0)
+#define MAGZOOMS_SAME_RATIO (1U << 1)
+#define MAGZOOMS_IGNORE (1U << 31)
+ guint flags;
+ struct {
+ GtkSpinButton *h_zoom, *v_zoom;
+ } widget;
};
struct graph {
-#define GRAPH_TSEQ_STEVENS 0
-#define GRAPH_TSEQ_TCPTRACE 1
-#define GRAPH_THROUGHPUT 2
-#define GRAPH_RTT 3
-#define GRAPH_WSCALE 4
- int type;
-#define GRAPH_DESTROYED (1 << 0)
-#define GRAPH_INIT_ON_TYPE_CHANGE (1 << 1)
- int flags;
- GtkWidget *toplevel; /* keypress handler needs this */
- GtkWidget *drawing_area;
- GtkWidget *text; /* text widget for seg list - probably
- * temporary
- */
- PangoFontDescription *font; /* font used for annotations etc. */
+#define GRAPH_TSEQ_STEVENS 0
+#define GRAPH_TSEQ_TCPTRACE 1
+#define GRAPH_THROUGHPUT 2
+#define GRAPH_RTT 3
+#define GRAPH_WSCALE 4
+ int type;
+#define GRAPH_DESTROYED (1 << 0)
+#define GRAPH_INIT_ON_TYPE_CHANGE (1 << 1)
+ int flags;
+ GtkWidget *toplevel; /* keypress handler needs this */
+ GtkWidget *drawing_area;
+ GtkWidget *text; /* text widget for seg list - probably
+ * temporary
+ */
+ PangoFontDescription *font; /* font used for annotations etc. */
#if GTK_CHECK_VERSION(2,22,0)
- cairo_surface_t *title_surface;
- cairo_surface_t *surface[2];
+ cairo_surface_t *title_surface;
+ cairo_surface_t *surface[2];
#else
- GdkPixmap *title_pixmap;
- GdkPixmap *pixmap[2];
+ GdkPixmap *title_pixmap;
+ GdkPixmap *pixmap[2];
#endif
- int displayed; /* which of both pixmaps is on screen right now */
- struct {
- GtkWidget *control_panel;
- /* this belongs to style structs of graph types that make use of it */
- GtkToggleButton *time_orig_conn, *seq_orig_isn;
- } gui;
- const char **title;
- /* Next 4 attribs describe the graph in natural units, before any scaling.
- * For example, if we want to display graph of TCP conversation that
- * started 112.309845 s after beginning of the capture and ran until
- * 479.093582 s, 237019 B went through the connection (in one direction)
- * starting with isn 31934022, then (bounds.x0, bounds.y0)=(112.309845,
- * 31934022) and (bounds.width, bounds.height)=(366.783737, 237019). */
- struct bounds bounds;
- /* dimensions and position of the graph, both expressed already in pixels.
- * x and y give the position of upper left corner of the graph relative
- * to origin of the graph window, size is basically bounds*zoom */
- struct irect geom;
- /* viewport (=graph window area which is reserved for graph itself), its
- * size and position relative to origin of the graph window */
- struct irect wp;
- /* whether and where the graph has been 'grabbed' and may now be moved */
- struct grab grab;
- /* If we need to display 237019 sequence numbers (=bytes) onto say 500
- * pixels, we have to scale the graph down by factor of 0.002109. This
- * number would be zoom.y. Obviously, both directions have separate zooms.*/
- struct zooms zoom;
- struct cross cross;
- gboolean zoomrect_erase_needed;
- struct magnify magnify;
- struct axis *x_axis, *y_axis;
- struct segment *segments;
-
- /* The stream this graph will show */
- address src_address;
- guint16 src_port;
- address dst_address;
- guint16 dst_port;
-
- struct element_list *elists; /* element lists */
- union {
- struct style_tseq_stevens tseq_stevens;
- struct style_tseq_tcptrace tseq_tcptrace;
- struct style_tput tput;
- struct style_rtt rtt;
- struct style_wscale wscale;
- } s;
- /* This allows keyboard to set the radio button */
- struct {
- GtkToggleButton *graph_rtt, *graph_tput, *graph_tseqstevens, *graph_tseqttrace;
- GtkToggleButton *graph_wscale;
- } gt;
+ int displayed; /* which of both pixmaps is on screen right now */
+ struct {
+ GtkWidget *control_panel;
+ /* this belongs to style structs of graph types that make use of it */
+ GtkToggleButton *time_orig_conn, *seq_orig_isn;
+ } gui;
+ const char **title;
+
+ /* Next 4 attribs describe the graph in natural units, before any scaling.
+ * For example, if we want to display graph of TCP conversation that
+ * started 112.309845 s after beginning of the capture and ran until
+ * 479.093582 s, 237019 B went through the connection (in one direction)
+ * starting with isn 31934022, then (bounds.x0, bounds.y0)=(112.309845,
+ * 31934022) and (bounds.width, bounds.height)=(366.783737, 237019). */
+ struct bounds bounds;
+
+ /* dimensions and position of the graph, both expressed already in pixels.
+ * x and y give the position of upper left corner of the graph relative
+ * to origin of the graph window, size is basically bounds*zoom */
+ struct irect geom;
+
+ /* viewport (=graph window area which is reserved for graph itself), its
+ * size and position relative to origin of the graph window */
+ struct irect wp;
+
+ /* whether and where the graph has been 'grabbed' and may now be moved */
+ struct grab grab;
+
+ /* If we need to display 237019 sequence numbers (=bytes) onto say 500
+ * pixels, we have to scale the graph down by factor of 0.002109. This
+ * number would be zoom.y. Obviously, both directions have separate zooms.*/
+ struct zooms zoom;
+
+ struct cross cross;
+ gboolean zoomrect_erase_needed;
+ struct magnify magnify;
+ struct axis *x_axis, *y_axis;
+ struct segment *segments;
+
+ /* The stream this graph will show */
+ address src_address;
+ guint16 src_port;
+ address dst_address;
+ guint16 dst_port;
+
+ struct element_list *elists; /* element lists */
+ union {
+ struct style_tseq_stevens tseq_stevens;
+ struct style_tseq_tcptrace tseq_tcptrace;
+ struct style_tput tput;
+ struct style_rtt rtt;
+ struct style_wscale wscale;
+ } s;
+ /* This allows keyboard to set the radio button */
+ struct {
+ GtkToggleButton *graph_rtt, *graph_tput, *graph_tseqstevens, *graph_tseqttrace;
+ GtkToggleButton *graph_wscale;
+ } gt;
};
+
#if !GTK_CHECK_VERSION(3,0,0)
static GdkGC *xor_gc = NULL;
#endif
@@ -372,11 +379,11 @@ static int refnum=0;
#define debug(section) if (debugging & section)
/* print function entry points */
-#define DBS_FENTRY (1 << 0)
-#define DBS_AXES_TICKS (1 << 1)
-#define DBS_AXES_DRAWING (1 << 2)
-#define DBS_GRAPH_DRAWING (1 << 3)
-#define DBS_TPUT_ELMTS (1 << 4)
+#define DBS_FENTRY (1 << 0)
+#define DBS_AXES_TICKS (1 << 1)
+#define DBS_AXES_DRAWING (1 << 2)
+#define DBS_GRAPH_DRAWING (1 << 3)
+#define DBS_TPUT_ELMTS (1 << 4)
/*static int debugging = DBS_FENTRY;*/
static int debugging = 0;
/*static int debugging = DBS_AXES_TICKS;*/
@@ -384,137 +391,137 @@ static int debugging = 0;
/*static int debugging = DBS_GRAPH_DRAWING;*/
/*static int debugging = DBS_TPUT_ELMTS;*/
-static void create_gui (struct graph * );
+static void create_gui(struct graph * );
#if 0
-static void create_text_widget (struct graph * );
-static void display_text (struct graph * );
+static void create_text_widget(struct graph * );
+static void display_text(struct graph * );
#endif
-static void create_drawing_area (struct graph * );
-static void control_panel_create (struct graph * );
-static GtkWidget *control_panel_create_zoom_group (struct graph * );
-static GtkWidget *control_panel_create_magnify_group (struct graph * );
-static GtkWidget *control_panel_create_cross_group (struct graph * );
-static GtkWidget *control_panel_create_zoomlock_group (struct graph * );
-static GtkWidget *control_panel_create_graph_type_group (struct graph * );
-static void control_panel_add_zoom_page (struct graph * , GtkWidget * );
-static void control_panel_add_magnify_page (struct graph * , GtkWidget * );
-static void control_panel_add_origin_page (struct graph * , GtkWidget * );
-static void control_panel_add_cross_page (struct graph * , GtkWidget * );
-static void control_panel_add_graph_type_page (struct graph * , GtkWidget * );
-static void callback_toplevel_destroy (GtkWidget * , gpointer );
+static void create_drawing_area(struct graph * );
+static void control_panel_create(struct graph * );
+static GtkWidget *control_panel_create_zoom_group(struct graph * );
+static GtkWidget *control_panel_create_magnify_group(struct graph * );
+static GtkWidget *control_panel_create_cross_group(struct graph * );
+static GtkWidget *control_panel_create_zoomlock_group(struct graph * );
+static GtkWidget *control_panel_create_graph_type_group(struct graph * );
+static void control_panel_add_zoom_page(struct graph * , GtkWidget * );
+static void control_panel_add_magnify_page(struct graph * , GtkWidget * );
+static void control_panel_add_origin_page(struct graph * , GtkWidget * );
+static void control_panel_add_cross_page(struct graph * , GtkWidget * );
+static void control_panel_add_graph_type_page(struct graph * , GtkWidget * );
+static void callback_toplevel_destroy(GtkWidget * , gpointer );
static gboolean callback_delete_event(GtkWidget * , GdkEvent * , gpointer);
-static void callback_close (GtkWidget * , gpointer );
-static void callback_time_origin (GtkWidget * , gpointer );
-static void callback_seq_origin (GtkWidget * , gpointer );
-static void callback_zoomlock_h (GtkWidget * , gpointer );
-static void callback_zoomlock_v (GtkWidget * , gpointer );
-static void callback_zoom_inout (GtkWidget * , gpointer );
-static void callback_zoom_step (GtkWidget * , gpointer );
-static void callback_zoom_flags (GtkWidget * , gpointer );
-static void callback_cross_on_off (GtkWidget * , gpointer );
-static void callback_mag_width (GtkWidget * , gpointer );
-static void callback_mag_height (GtkWidget * , gpointer );
-static void callback_mag_x (GtkWidget * , gpointer );
-static void callback_mag_y (GtkWidget * , gpointer );
-static void callback_mag_zoom (GtkWidget * , gpointer );
-static void callback_mag_flags (GtkWidget * , gpointer );
-static void callback_graph_type (GtkWidget * , gpointer );
-static void callback_graph_init_on_typechg (GtkWidget * , gpointer );
-static void callback_create_help (GtkWidget * , gpointer );
-static void get_mouse_position (GtkWidget *, int *pointer_x, int *pointer_y, GdkModifierType *mask);
-static void update_zoom_spins (struct graph * );
-static struct tcpheader *select_tcpip_session (capture_file *, struct segment * );
-static int compare_headers (address *saddr1, address *daddr1, guint16 sport1, guint16 dport1, const address *saddr2, const address *daddr2, guint16 sport2, guint16 dport2, int dir);
-static int get_num_dsegs (struct graph * );
-static int get_num_acks (struct graph *, int * );
-static void graph_type_dependent_initialize (struct graph * );
-static struct graph *graph_new (void);
-static void graph_destroy (struct graph * );
-static void graph_initialize_values (struct graph * );
-static void graph_init_sequence (struct graph * );
-static void draw_element_line (struct graph * , struct element * , cairo_t *cr, GdkColor *new_color);
-static void draw_element_ellipse (struct graph * , struct element * , cairo_t *cr);
-static void graph_display (struct graph * );
-static void graph_pixmaps_create (struct graph * );
-static void graph_pixmaps_switch (struct graph * );
-static void graph_pixmap_draw (struct graph * );
-static void graph_pixmap_display (struct graph * );
-static void graph_element_lists_make (struct graph * );
-static void graph_element_lists_free (struct graph * );
-static void graph_element_lists_initialize (struct graph * );
-static void graph_title_pixmap_create (struct graph * );
-static void graph_title_pixmap_draw (struct graph * );
-static void graph_title_pixmap_display (struct graph * );
-static void graph_segment_list_get (struct graph *, gboolean stream_known );
-static void graph_segment_list_free (struct graph * );
-static void graph_select_segment (struct graph * , int , int );
-static int line_detect_collision (struct element * , int , int );
-static int ellipse_detect_collision (struct element * , int , int );
-static void axis_pixmaps_create (struct axis * );
-static void axis_pixmaps_switch (struct axis * );
-static void axis_display (struct axis * );
-static void v_axis_pixmap_draw (struct axis * );
-static void h_axis_pixmap_draw (struct axis * );
-static void axis_pixmap_display (struct axis * );
-static void axis_compute_ticks (struct axis * , double , double , int );
-static double axis_zoom_get (struct axis * , int );
-static void axis_ticks_up (int * , int * );
-static void axis_ticks_down (int * , int * );
-static void axis_destroy (struct axis * );
-static int get_label_dim (struct axis * , int , double );
-static void toggle_crosshairs (struct graph *g);
-static void toggle_time_origin (struct graph * );
-static void toggle_seq_origin (struct graph * );
-static void restore_initial_graph_view (struct graph *g);
-static void cross_draw (struct graph * , int , int );
-static void cross_erase (struct graph * );
-static void zoomrect_draw (struct graph * , int , int );
-static void zoomrect_erase (struct graph * );
-static void magnify_move (struct graph * , int , int );
-static void magnify_create (struct graph * , int , int );
-static void magnify_destroy (struct graph * );
-static void magnify_draw (struct graph * );
-static void magnify_get_geom (struct graph * , int , int );
-static gboolean configure_event (GtkWidget * , GdkEventConfigure * , gpointer );
+static void callback_close(GtkWidget * , gpointer );
+static void callback_time_origin(GtkWidget * , gpointer );
+static void callback_seq_origin(GtkWidget * , gpointer );
+static void callback_zoomlock_h(GtkWidget * , gpointer );
+static void callback_zoomlock_v(GtkWidget * , gpointer );
+static void callback_zoom_inout(GtkWidget * , gpointer );
+static void callback_zoom_step(GtkWidget * , gpointer );
+static void callback_zoom_flags(GtkWidget * , gpointer );
+static void callback_cross_on_off(GtkWidget * , gpointer );
+static void callback_mag_width(GtkWidget * , gpointer );
+static void callback_mag_height(GtkWidget * , gpointer );
+static void callback_mag_x(GtkWidget * , gpointer );
+static void callback_mag_y(GtkWidget * , gpointer );
+static void callback_mag_zoom(GtkWidget * , gpointer );
+static void callback_mag_flags(GtkWidget * , gpointer );
+static void callback_graph_type(GtkWidget * , gpointer );
+static void callback_graph_init_on_typechg(GtkWidget * , gpointer );
+static void callback_create_help(GtkWidget * , gpointer );
+static void get_mouse_position(GtkWidget *, int *pointer_x, int *pointer_y, GdkModifierType *mask);
+static void update_zoom_spins(struct graph * );
+static struct tcpheader *select_tcpip_session(capture_file *, struct segment * );
+static int compare_headers(address *saddr1, address *daddr1, guint16 sport1, guint16 dport1, const address *saddr2, const address *daddr2, guint16 sport2, guint16 dport2, int dir);
+static int get_num_dsegs(struct graph * );
+static int get_num_acks(struct graph *, int * );
+static void graph_type_dependent_initialize(struct graph * );
+static struct graph *graph_new(void);
+static void graph_destroy(struct graph * );
+static void graph_initialize_values(struct graph * );
+static void graph_init_sequence(struct graph * );
+static void draw_element_line(struct graph * , struct element * , cairo_t *cr, GdkColor *new_color);
+static void draw_element_ellipse(struct graph * , struct element * , cairo_t *cr);
+static void graph_display(struct graph * );
+static void graph_pixmaps_create(struct graph * );
+static void graph_pixmaps_switch(struct graph * );
+static void graph_pixmap_draw(struct graph * );
+static void graph_pixmap_display(struct graph * );
+static void graph_element_lists_make(struct graph * );
+static void graph_element_lists_free(struct graph * );
+static void graph_element_lists_initialize(struct graph * );
+static void graph_title_pixmap_create(struct graph * );
+static void graph_title_pixmap_draw(struct graph * );
+static void graph_title_pixmap_display(struct graph * );
+static void graph_segment_list_get(struct graph *, gboolean stream_known );
+static void graph_segment_list_free(struct graph * );
+static void graph_select_segment(struct graph * , int , int );
+static int line_detect_collision(struct element * , int , int );
+static int ellipse_detect_collision(struct element * , int , int );
+static void axis_pixmaps_create(struct axis * );
+static void axis_pixmaps_switch(struct axis * );
+static void axis_display(struct axis * );
+static void v_axis_pixmap_draw(struct axis * );
+static void h_axis_pixmap_draw(struct axis * );
+static void axis_pixmap_display(struct axis * );
+static void axis_compute_ticks(struct axis * , double , double , int );
+static double axis_zoom_get(struct axis * , int );
+static void axis_ticks_up(int * , int * );
+static void axis_ticks_down(int * , int * );
+static void axis_destroy(struct axis * );
+static int get_label_dim(struct axis * , int , double );
+static void toggle_crosshairs(struct graph *g);
+static void toggle_time_origin(struct graph * );
+static void toggle_seq_origin(struct graph * );
+static void restore_initial_graph_view(struct graph *g);
+static void cross_draw(struct graph * , int , int );
+static void cross_erase(struct graph * );
+static void zoomrect_draw(struct graph * , int , int );
+static void zoomrect_erase(struct graph * );
+static void magnify_move(struct graph * , int , int );
+static void magnify_create(struct graph * , int , int );
+static void magnify_destroy(struct graph * );
+static void magnify_draw(struct graph * );
+static void magnify_get_geom(struct graph * , int , int );
+static gboolean configure_event(GtkWidget * , GdkEventConfigure * , gpointer );
#if GTK_CHECK_VERSION(3,0,0)
static gboolean draw_event(GtkWidget *widget, cairo_t *cr, gpointer user_data);
#else
-static gboolean expose_event (GtkWidget * , GdkEventExpose * , gpointer );
+static gboolean expose_event(GtkWidget * , GdkEventExpose * , gpointer );
#endif
-static gboolean button_press_event (GtkWidget * , GdkEventButton * , gpointer );
-static gboolean button_release_event (GtkWidget * , GdkEventButton * , gpointer );
-static gboolean motion_notify_event (GtkWidget * , GdkEventMotion * , gpointer );
-static gboolean leave_notify_event (GtkWidget * , GdkEventCrossing * , gpointer );
-static gboolean enter_notify_event (GtkWidget * , GdkEventCrossing * , gpointer );
-static gboolean key_press_event (GtkWidget * , GdkEventKey * , gpointer );
-static gboolean key_release_event (GtkWidget * , GdkEventKey * , gpointer );
-static void tseq_initialize (struct graph * );
-static void tseq_get_bounds (struct graph * );
-static void tseq_stevens_read_config (struct graph * );
-static void tseq_stevens_make_elmtlist (struct graph * );
-static void tseq_stevens_toggle_seq_origin (struct graph * );
-static void tseq_stevens_toggle_time_origin (struct graph * );
-static void tseq_tcptrace_read_config (struct graph * );
-static void tseq_tcptrace_make_elmtlist (struct graph * );
-static void tseq_tcptrace_toggle_seq_origin (struct graph * );
-static void tseq_tcptrace_toggle_time_origin (struct graph * );
-static void tput_initialize (struct graph * );
-static void tput_read_config (struct graph * );
-static void tput_make_elmtlist (struct graph * );
-static void tput_toggle_time_origin (struct graph * );
-static void rtt_read_config (struct graph * );
-static void rtt_initialize (struct graph * );
-static int rtt_is_retrans (struct unack * , unsigned int );
-static struct unack *rtt_get_new_unack (double , unsigned int );
-static void rtt_put_unack_on_list (struct unack ** , struct unack * );
-static void rtt_delete_unack_from_list (struct unack ** , struct unack * );
-static void rtt_make_elmtlist (struct graph * );
-static void rtt_toggle_seq_origin (struct graph * );
+static gboolean button_press_event(GtkWidget * , GdkEventButton * , gpointer );
+static gboolean button_release_event(GtkWidget * , GdkEventButton * , gpointer );
+static gboolean motion_notify_event(GtkWidget * , GdkEventMotion * , gpointer );
+static gboolean leave_notify_event(GtkWidget * , GdkEventCrossing * , gpointer );
+static gboolean enter_notify_event(GtkWidget * , GdkEventCrossing * , gpointer );
+static gboolean key_press_event(GtkWidget * , GdkEventKey * , gpointer );
+static gboolean key_release_event(GtkWidget * , GdkEventKey * , gpointer );
+static void tseq_initialize(struct graph * );
+static void tseq_get_bounds(struct graph * );
+static void tseq_stevens_read_config(struct graph * );
+static void tseq_stevens_make_elmtlist(struct graph * );
+static void tseq_stevens_toggle_seq_origin(struct graph * );
+static void tseq_stevens_toggle_time_origin(struct graph * );
+static void tseq_tcptrace_read_config(struct graph * );
+static void tseq_tcptrace_make_elmtlist(struct graph * );
+static void tseq_tcptrace_toggle_seq_origin(struct graph * );
+static void tseq_tcptrace_toggle_time_origin(struct graph * );
+static void tput_initialize(struct graph * );
+static void tput_read_config(struct graph * );
+static void tput_make_elmtlist(struct graph * );
+static void tput_toggle_time_origin(struct graph * );
+static void rtt_read_config(struct graph * );
+static void rtt_initialize(struct graph * );
+static int rtt_is_retrans(struct unack * , unsigned int );
+static struct unack *rtt_get_new_unack(double , unsigned int );
+static void rtt_put_unack_on_list(struct unack ** , struct unack * );
+static void rtt_delete_unack_from_list(struct unack ** , struct unack * );
+static void rtt_make_elmtlist(struct graph * );
+static void rtt_toggle_seq_origin(struct graph * );
static void wscale_initialize(struct graph *);
static void wscale_read_config(struct graph *);
static void wscale_make_elmtlist(struct graph *);
#if defined(_WIN32) && !defined(__MINGW32__)
-static int rint (double ); /* compiler template for Windows */
+static int rint(double ); /* compiler template for Windows */
#endif
/* This should arguably be part of the graph, but in practice you can
@@ -529,513 +536,514 @@ static struct irect zoomrect;
/* #define ORIGINAL_WIN32_BUTTONS 1 */
/* XXX - what about OS X? */
+/* XXX: Needs work to ensire that the columns line up properly in both Gtk2 & Gtk3 */
+/* What is the proper way to do this ?? */
static char helptext[] =
- "Here's what you can do:\n"
- "\n"
+ "Here's what you can do:\n"
+ "\n"
#ifdef ORIGINAL_WIN32_BUTTONS
- " <Ctrl>-Left Mouse Button selects segment under cursor in Wireshark's packet list\n"
- "\n"
- " Left Mouse Button zooms in (towards area under mouse pointer)\n"
- " <Shift>-Left Mouse Button zooms out\n"
- "\n"
- " Right Mouse Button moves the graph (if zoomed in)\n"
- " <Ctrl>-Right Mouse Button displays a portion of graph under cursor magnified\n"
+ " <Ctrl>-Left Mouse Button selects segment under cursor in Wireshark's packet list\n"
+ "\n"
+ " Left Mouse Button zooms in (towards area under mouse pointer)\n"
+ " <Shift>-Left Mouse Button zooms out\n"
+ "\n"
+ " Right Mouse Button moves the graph (if zoomed in)\n"
+ " <Ctrl>-Right Mouse Button displays a portion of graph under cursor magnified\n"
#else /* !ORIGINAL_WIN32_BUTTONS */
- " Left Mouse Button selects segment under cursor in Wireshark's packet list\n"
- " can also drag to zoom in on a rectangular region\n"
- "\n"
- " Middle Mouse Button zooms in (towards area under cursor)\n"
- " <Shift>-Middle Mouse Button zooms out\n"
- "\n"
- " Right Mouse Button moves the graph (if zoomed in)\n"
- " <Ctrl>-Right Mouse Button displays a portion of graph under cursor magnified\n"
+ " Left Mouse Button selects segment under cursor in Wireshark's packet list\n"
+ " can also drag to zoom in on a rectangular region\n"
+ "\n"
+ " Middle Mouse Button zooms in (towards area under cursor)\n"
+ " <Shift>-Middle Mouse Button zooms out\n"
+ "\n"
+ " Right Mouse Button moves the graph (if zoomed in)\n"
+ " <Ctrl>-Right Mouse Button displays a portion of graph under cursor magnified\n"
#endif
- "\n"
- "\n"
- " '1' display Round Trip Time Graph\n"
- " '2' display Throughput Graph\n"
- " '3' display Time/Sequence Graph (Stevens)\n"
- " '4' display Time/Sequence Graph (tcptrace)\n"
- " '5' display Window Scaling Graph\n"
- "\n"
- " <Space bar> toggles crosshairs on/off\n"
- "\n"
- " 'i' or '+' zoom in (towards area under mouse pointer)\n"
- " 'o' or '-' zoom out\n"
- " 'r' or <Home> restore graph to initial state (zoom out max)\n"
- " 's' toggles relative/absolute sequence numbers\n"
- " 't' toggles time origin\n"
- " 'g' go to frame under cursor in Wireshark's packet list (if possible)\n"
- "\n"
- " <Left> move view left by 100 pixels (if zoomed in)\n"
- " <Right> move view right 100 pixels (if zoomed in)\n"
- " <Up> move view up by 100 pixels (if zoomed in)\n"
- " <Down> move view down by 100 pixels (if zoomed in)\n"
- "\n"
- " <Shift><Left> move view left by 10 pixels (if zoomed in)\n"
- " <Shift><Right> move view right 10 pixels (if zoomed in)\n"
- " <Shift><Up> move view up by 10 pixels (if zoomed in)\n"
- " <Shift><Down> move view down by 10 pixels (if zoomed in)\n"
- "\n"
- " <Ctrl><Left> move view left by 1 pixel (if zoomed in)\n"
- " <Ctrl><Right> move view right 1 pixel (if zoomed in)\n"
- " <Ctrl><Up> move view up by 1 pixel (if zoomed in)\n"
- " <Ctrl><Down> move view down by 1 pixel (if zoomed in)\n"
+ "\n"
+ "\n"
+ " '1' display Round Trip Time Graph\n"
+ " '2' display Throughput Graph\n"
+ " '3' display Time/Sequence Graph (Stevens)\n"
+ " '4' display Time/Sequence Graph (tcptrace)\n"
+ " '5' display Window Scaling Graph\n"
+ "\n"
+ " <Space bar> toggles crosshairs on/off\n"
+ "\n"
+ " 'i' or '+' zoom in (towards area under mouse pointer)\n"
+ " 'o' or '-' zoom out\n"
+ " 'r' or <Home> restore graph to initial state (zoom out max)\n"
+ " 's' toggles relative/absolute sequence numbers\n"
+ " 't' toggles time origin\n"
+ " 'g' go to frame under cursor in Wireshark's packet list (if possible)\n"
+ "\n"
+ " <Left> move view left by 100 pixels (if zoomed in)\n"
+ " <Right> move view right 100 pixels (if zoomed in)\n"
+ " <Up> move view up by 100 pixels (if zoomed in)\n"
+ " <Down> move view down by 100 pixels (if zoomed in)\n"
+ "\n"
+ " <Shift><Left> move view left by 10 pixels (if zoomed in)\n"
+ " <Shift><Right> move view right 10 pixels (if zoomed in)\n"
+ " <Shift><Up> move view up by 10 pixels (if zoomed in)\n"
+ " <Shift><Down> move view down by 10 pixels (if zoomed in)\n"
+ "\n"
+ " <Ctrl><Left> move view left by 1 pixel (if zoomed in)\n"
+ " <Ctrl><Right> move view right 1 pixel (if zoomed in)\n"
+ " <Ctrl><Up> move view up by 1 pixel (if zoomed in)\n"
+ " <Ctrl><Down> move view down by 1 pixel (if zoomed in)\n"
;
#if 0
-static void debug_coord (struct graph *g, const char *c)
+static void debug_coord(struct graph *g, const char *c)
{
- static guint count = 0;
+ static guint count = 0;
- count++;
- printf("%u: %s\n", count, c);
- printf("%u: g->geom.width %d\n", count, g->geom.width);
- printf("%u: g->geom.height %d\n", count, g->geom.height);
- printf("%u: g->geom.x %d\n", count, g->geom.x);
- printf("%u: g->geom.y %d\n", count, g->geom.y);
+ count++;
+ printf("%u: %s\n", count, c);
+ printf("%u: g->geom.width %d\n", count, g->geom.width);
+ printf("%u: g->geom.height %d\n", count, g->geom.height);
+ printf("%u: g->geom.x %d\n", count, g->geom.x);
+ printf("%u: g->geom.y %d\n", count, g->geom.y);
- printf("%u: g->wp.width %d\n", count, g->wp.width);
- printf("%u: g->wp.height %d\n", count, g->wp.height);
- printf("%u: g->wp.x %d\n", count, g->wp.x);
- printf("%u: g->wp.y %d\n", count, g->wp.y);
- printf("---------------\n");
+ printf("%u: g->wp.width %d\n", count, g->wp.width);
+ printf("%u: g->wp.height %d\n", count, g->wp.height);
+ printf("%u: g->wp.x %d\n", count, g->wp.x);
+ printf("%u: g->wp.y %d\n", count, g->wp.y);
+ printf("---------------\n");
}
#endif
static void set_busy_cursor(GdkWindow *w)
{
- GdkCursor* cursor;
+ GdkCursor *cursor;
- cursor = gdk_cursor_new(GDK_WATCH);
- gdk_window_set_cursor(w, cursor);
- gdk_flush();
+ cursor = gdk_cursor_new(GDK_WATCH);
+ gdk_window_set_cursor(w, cursor);
+ gdk_flush();
#if GTK_CHECK_VERSION(3,0,0)
- g_object_unref(cursor);
+ g_object_unref(cursor);
#else
- gdk_cursor_unref(cursor);
+ gdk_cursor_unref(cursor);
#endif
}
static void unset_busy_cursor(GdkWindow *w, gboolean cross)
{
- GdkCursor* cursor;
+ GdkCursor *cursor;
- if(cross){
- cursor = gdk_cursor_new(GDK_CROSSHAIR);
- gdk_window_set_cursor(w, cursor);
- gdk_flush();
+ if (cross) {
+ cursor = gdk_cursor_new(GDK_CROSSHAIR);
+ gdk_window_set_cursor(w, cursor);
+ gdk_flush();
#if GTK_CHECK_VERSION(3,0,0)
- g_object_unref(cursor);
+ g_object_unref(cursor);
#else
- gdk_cursor_unref(cursor);
+ gdk_cursor_unref(cursor);
#endif
- }else{
- gdk_window_set_cursor(w, NULL);
- gdk_flush();
- }
+ } else {
+ gdk_window_set_cursor(w, NULL);
+ gdk_flush();
+ }
}
-void tcp_graph_cb (GtkAction *action, gpointer user_data _U_)
+void tcp_graph_cb(GtkAction *action, gpointer user_data _U_)
{
- struct segment current;
- struct graph *g;
- const gchar *name;
- guint graph_type;
+ struct segment current;
+ struct graph *g;
+ const gchar *name;
+ guint graph_type;
- name = gtk_action_get_name (action);
- if(strcmp(name, "/StatisticsMenu/TCPStreamGraphMenu/Time-Sequence-Graph-Stevens") == 0){
- graph_type = GRAPH_TSEQ_STEVENS;
- }else if(strcmp(name, "/StatisticsMenu/TCPStreamGraphMenu/Time-Sequence-Graph-tcptrace") == 0){
- graph_type = GRAPH_TSEQ_TCPTRACE;
- }else if(strcmp(name, "/StatisticsMenu/TCPStreamGraphMenu/Throughput-Graph") == 0){
- graph_type = GRAPH_THROUGHPUT;
- }else if(strcmp(name, "/StatisticsMenu/TCPStreamGraphMenu/RTT-Graph") == 0){
- graph_type = GRAPH_RTT;
- }else if(strcmp(name, "/StatisticsMenu/TCPStreamGraphMenu/Window-Scaling-Graph") == 0){
- graph_type = GRAPH_WSCALE;
- }else{
- return;
- }
+ name = gtk_action_get_name(action);
+ if (strcmp(name, "/StatisticsMenu/TCPStreamGraphMenu/Time-Sequence-Graph-Stevens") == 0) {
+ graph_type = GRAPH_TSEQ_STEVENS;
+ } else if (strcmp(name, "/StatisticsMenu/TCPStreamGraphMenu/Time-Sequence-Graph-tcptrace") == 0) {
+ graph_type = GRAPH_TSEQ_TCPTRACE;
+ } else if (strcmp(name, "/StatisticsMenu/TCPStreamGraphMenu/Throughput-Graph") == 0) {
+ graph_type = GRAPH_THROUGHPUT;
+ } else if (strcmp(name, "/StatisticsMenu/TCPStreamGraphMenu/RTT-Graph") == 0) {
+ graph_type = GRAPH_RTT;
+ } else if (strcmp(name, "/StatisticsMenu/TCPStreamGraphMenu/Window-Scaling-Graph") == 0) {
+ graph_type = GRAPH_WSCALE;
+ } else {
+ return;
+ }
- debug(DBS_FENTRY) puts ("tcp_graph_cb()");
+ debug(DBS_FENTRY) puts("tcp_graph_cb()");
- if (!select_tcpip_session (&cfile, &current)) {
- return;
- }
+ if (!select_tcpip_session(&cfile, &current)) {
+ return;
+ }
- if (! (g = graph_new()))
- return;
+ if (! (g = graph_new()))
+ return;
- refnum++;
- graph_initialize_values (g);
+ refnum++;
+ graph_initialize_values(g);
- g->type = graph_type;
+ g->type = graph_type;
- graph_segment_list_get(g, FALSE);
- create_gui(g);
- /* display_text(g); */
- graph_init_sequence(g);
+ graph_segment_list_get(g, FALSE);
+ create_gui(g);
+ /* display_text(g); */
+ graph_init_sequence(g);
}
void tcp_graph_known_stream_launch(address *src_address, guint16 src_port,
address *dst_address, guint16 dst_port)
{
- struct graph *g;
+ struct graph *g;
- if (!(g = graph_new())) {
- return;
- }
+ if (!(g = graph_new())) {
+ return;
+ }
- refnum++;
- graph_initialize_values(g);
+ refnum++;
+ graph_initialize_values(g);
- /* Can set stream info for graph now */
- COPY_ADDRESS(&g->src_address, src_address);
- g->src_port = src_port;
- COPY_ADDRESS(&g->dst_address, dst_address);
- g->dst_port = dst_port;
+ /* Can set stream info for graph now */
+ COPY_ADDRESS(&g->src_address, src_address);
+ g->src_port = src_port;
+ COPY_ADDRESS(&g->dst_address, dst_address);
+ g->dst_port = dst_port;
- /* This graph type is arguably the most useful, so start there */
- g->type = GRAPH_TSEQ_TCPTRACE;
+ /* This graph type is arguably the most useful, so start there */
+ g->type = GRAPH_TSEQ_TCPTRACE;
- /* Get our list of segments from the packet list */
- graph_segment_list_get(g, TRUE);
+ /* Get our list of segments from the packet list */
+ graph_segment_list_get(g, TRUE);
- create_gui(g);
- graph_init_sequence(g);
+ create_gui(g);
+ graph_init_sequence(g);
}
-static void create_gui (struct graph *g)
+static void create_gui(struct graph *g)
{
- /* ToDo: Ensure that drawing area window doesn't
- * (completely) cover the contraol_panel window.
- */
- debug(DBS_FENTRY) puts ("create_gui()");
- /* create_text_widget(g); */
- control_panel_create (g);
- create_drawing_area(g);
+ /* ToDo: Ensure that drawing area window doesn't
+ * (completely) cover the contraol_panel window.
+ */
+ debug(DBS_FENTRY) puts("create_gui()");
+ /* create_text_widget(g); */
+ control_panel_create(g);
+ create_drawing_area(g);
}
-static void create_drawing_area (struct graph *g)
+static void create_drawing_area(struct graph *g)
{
#if GTK_CHECK_VERSION(3,0,0)
- GtkStyleContext *context;
+ GtkStyleContext *context;
#else
- GdkColormap *colormap;
- GdkColor color;
+ GdkColormap *colormap;
+ GdkColor color;
#endif
- char *display_name;
- char window_title[WINDOW_TITLE_LENGTH];
- GtkAllocation widget_alloc;
+ char *display_name;
+ char window_title[WINDOW_TITLE_LENGTH];
+ GtkAllocation widget_alloc;
#if 0
- /* Prep. to include the controls in the graph window */
- GtkWidget *frame;
- GtkWidget *vbox;
- GtkWidget *hbox;
+ /* Prep. to include the controls in the graph window */
+ GtkWidget *frame;
+ GtkWidget *vbox;
+ GtkWidget *hbox;
#endif
- debug(DBS_FENTRY) puts ("create_drawing_area()");
-
- /* Set title of window with file + conversation details */
- display_name = cf_get_display_name(&cfile);
- g_snprintf (window_title, WINDOW_TITLE_LENGTH, "TCP Graph %d: %s %s:%d -> %s:%d",
- refnum,
- display_name,
- ep_address_to_str(&g->src_address),
- g->src_port,
- ep_address_to_str(&g->dst_address),
- g->dst_port
- );
- g_free(display_name);
- g->toplevel = dlg_window_new ("Tcp Graph");
- gtk_window_set_title(GTK_WINDOW(g->toplevel), window_title);
- gtk_widget_set_name (g->toplevel, "Test Graph");
-
- /* Create the drawing area */
- g->drawing_area = gtk_drawing_area_new ();
- g->x_axis->drawing_area = g->y_axis->drawing_area = g->drawing_area;
- gtk_widget_set_size_request (g->drawing_area,
- g->wp.width + g->wp.x + RMARGIN_WIDTH,
- g->wp.height + g->wp.y + g->x_axis->s.height);
- gtk_widget_show (g->drawing_area);
+ debug(DBS_FENTRY) puts("create_drawing_area()");
+
+ /* Set title of window with file + conversation details */
+ display_name = cf_get_display_name(&cfile);
+ g_snprintf(window_title, WINDOW_TITLE_LENGTH, "TCP Graph %d: %s %s:%d -> %s:%d",
+ refnum,
+ display_name,
+ ep_address_to_str(&g->src_address),
+ g->src_port,
+ ep_address_to_str(&g->dst_address),
+ g->dst_port
+ );
+ g_free(display_name);
+ g->toplevel = dlg_window_new("Tcp Graph");
+ gtk_window_set_title(GTK_WINDOW(g->toplevel), window_title);
+ gtk_widget_set_name(g->toplevel, "Test Graph");
+
+ /* Create the drawing area */
+ g->drawing_area = gtk_drawing_area_new();
+ g->x_axis->drawing_area = g->y_axis->drawing_area = g->drawing_area;
+ gtk_widget_set_size_request(g->drawing_area,
+ g->wp.width + g->wp.x + RMARGIN_WIDTH,
+ g->wp.height + g->wp.y + g->x_axis->s.height);
+ gtk_widget_show(g->drawing_area);
#if GTK_CHECK_VERSION(3,0,0)
- g_signal_connect(g->drawing_area, "draw", G_CALLBACK(draw_event), g);
+ g_signal_connect(g->drawing_area, "draw", G_CALLBACK(draw_event), g);
#else
- g_signal_connect(g->drawing_area, "expose_event", G_CALLBACK(expose_event), g);
+ g_signal_connect(g->drawing_area, "expose_event", G_CALLBACK(expose_event), g);
#endif
- /* this has to be done later, after the widget has been shown */
- /*
- g_signal_connect(g->drawing_area,"configure_event", G_CALLBACK(configure_event), g);
- */
-
- g_signal_connect(g->drawing_area, "button_press_event",
- G_CALLBACK(button_press_event), g);
- g_signal_connect(g->drawing_area, "button_release_event",
- G_CALLBACK(button_release_event), g);
- g_signal_connect(g->drawing_area, "motion_notify_event",
- G_CALLBACK(motion_notify_event), g);
- g_signal_connect(g->drawing_area, "leave_notify_event",
- G_CALLBACK(leave_notify_event), g);
- g_signal_connect(g->drawing_area, "enter_notify_event",
- G_CALLBACK(enter_notify_event), g);
- g_signal_connect(g->toplevel, "destroy", G_CALLBACK(callback_toplevel_destroy), g);
- /* why doesn't drawing area send key_press_signals? */
- g_signal_connect(g->toplevel, "key_press_event", G_CALLBACK(key_press_event), g);
- g_signal_connect(g->toplevel, "key_release_event", G_CALLBACK(key_release_event),
- g);
- gtk_widget_set_events(g->toplevel, GDK_KEY_PRESS_MASK|GDK_KEY_RELEASE_MASK);
-
- gtk_widget_set_events (g->drawing_area,
- GDK_EXPOSURE_MASK
- | GDK_LEAVE_NOTIFY_MASK
- | GDK_ENTER_NOTIFY_MASK
- | GDK_BUTTON_PRESS_MASK
- | GDK_BUTTON_RELEASE_MASK
- | GDK_POINTER_MOTION_MASK
- | GDK_POINTER_MOTION_HINT_MASK);
+ /* this has to be done later, after the widget has been shown */
+ /*
+ g_signal_connect(g->drawing_area, "configure_event", G_CALLBACK(configure_event), g);
+ */
+
+ g_signal_connect(g->drawing_area, "button_press_event",
+ G_CALLBACK(button_press_event), g);
+ g_signal_connect(g->drawing_area, "button_release_event",
+ G_CALLBACK(button_release_event), g);
+ g_signal_connect(g->drawing_area, "motion_notify_event",
+ G_CALLBACK(motion_notify_event), g);
+ g_signal_connect(g->drawing_area, "leave_notify_event",
+ G_CALLBACK(leave_notify_event), g);
+ g_signal_connect(g->drawing_area, "enter_notify_event",
+ G_CALLBACK(enter_notify_event), g);
+ g_signal_connect(g->toplevel, "destroy", G_CALLBACK(callback_toplevel_destroy), g);
+ /* why doesn't drawing area send key_press_signals? */
+ g_signal_connect(g->toplevel, "key_press_event", G_CALLBACK(key_press_event), g);
+ g_signal_connect(g->toplevel, "key_release_event", G_CALLBACK(key_release_event),
+ g);
+ gtk_widget_set_events(g->toplevel, GDK_KEY_PRESS_MASK|GDK_KEY_RELEASE_MASK);
+
+ gtk_widget_set_events(g->drawing_area,
+ GDK_EXPOSURE_MASK
+ | GDK_LEAVE_NOTIFY_MASK
+ | GDK_ENTER_NOTIFY_MASK
+ | GDK_BUTTON_PRESS_MASK
+ | GDK_BUTTON_RELEASE_MASK
+ | GDK_POINTER_MOTION_MASK
+ | GDK_POINTER_MOTION_HINT_MASK);
#if 0
- /* Prep. to include the controls in the graph window */
+ /* Prep. to include the controls in the graph window */
- vbox = ws_gtk_box_new(GTK_ORIENTATION_VERTICAL, 0, FALSE);
- gtk_container_add (GTK_CONTAINER (g->toplevel), vbox);
- gtk_container_set_border_width (GTK_CONTAINER (g->toplevel), 5);
- gtk_widget_show (vbox);
+ vbox = ws_gtk_box_new(GTK_ORIENTATION_VERTICAL, 0, FALSE);
+ gtk_container_add(GTK_CONTAINER(g->toplevel), vbox);
+ gtk_container_set_border_width(GTK_CONTAINER(g->toplevel), 5);
+ gtk_widget_show(vbox);
- frame = gtk_frame_new (NULL);
- gtk_frame_set_shadow_type (GTK_FRAME (frame), GTK_SHADOW_ETCHED_IN);
- gtk_container_add (GTK_CONTAINER (frame), g->drawing_area);
- gtk_box_pack_start (GTK_BOX (vbox), frame, TRUE, TRUE, 0);
- gtk_widget_show (frame);
+ frame = gtk_frame_new(NULL);
+ gtk_frame_set_shadow_type(GTK_FRAME(frame), GTK_SHADOW_ETCHED_IN);
+ gtk_container_add(GTK_CONTAINER(frame), g->drawing_area);
+ gtk_box_pack_start(GTK_BOX(vbox), frame, TRUE, TRUE, 0);
+ gtk_widget_show(frame);
- /*gtk_box_pack_start (GTK_BOX (vbox), g->gui.control_panel, FALSE, FALSE, 0);*/
+ /*gtk_box_pack_start(GTK_BOX(vbox), g->gui.control_panel, FALSE, FALSE, 0);*/
- hbox=ws_gtk_box_new(GTK_ORIENTATION_HORIZONTAL, 3, FALSE);
- gtk_box_pack_start(GTK_BOX(vbox), hbox, FALSE, FALSE, 5);
- gtk_container_set_border_width(GTK_CONTAINER(hbox), 3);
- gtk_box_set_child_packing(GTK_BOX(vbox), hbox, FALSE, FALSE, 0, GTK_PACK_START);
- gtk_widget_show(hbox);
+ hbox = ws_gtk_box_new(GTK_ORIENTATION_HORIZONTAL, 3, FALSE);
+ gtk_box_pack_start(GTK_BOX(vbox), hbox, FALSE, FALSE, 5);
+ gtk_container_set_border_width(GTK_CONTAINER(hbox), 3);
+ gtk_box_set_child_packing(GTK_BOX(vbox), hbox, FALSE, FALSE, 0, GTK_PACK_START);
+ gtk_widget_show(hbox);
- create_ctrl_area(g, hbox);
+ create_ctrl_area(g, hbox);
#endif
- gtk_container_add (GTK_CONTAINER (g->toplevel), g->drawing_area);
- gtk_widget_show (g->toplevel);
+ gtk_container_add(GTK_CONTAINER(g->toplevel), g->drawing_area);
+ gtk_widget_show(g->toplevel);
- /* in case we didn't get what we asked for */
- gtk_widget_get_allocation(GTK_WIDGET (g->drawing_area), &widget_alloc);
- g->wp.width = widget_alloc.width - g->wp.x - RMARGIN_WIDTH;
- g->wp.height = widget_alloc.height - g->wp.y - g->x_axis->s.height;
+ /* in case we didn't get what we asked for */
+ gtk_widget_get_allocation(GTK_WIDGET(g->drawing_area), &widget_alloc);
+ g->wp.width = widget_alloc.width - g->wp.x - RMARGIN_WIDTH;
+ g->wp.height = widget_alloc.height - g->wp.y - g->x_axis->s.height;
#if GTK_CHECK_VERSION(3,0,0)
- context = gtk_widget_get_style_context (g->drawing_area);
- gtk_style_context_get (context, GTK_STATE_FLAG_NORMAL,
- GTK_STYLE_PROPERTY_FONT, &g->font,
- NULL);
+ context = gtk_widget_get_style_context(g->drawing_area);
+ gtk_style_context_get(context, GTK_STATE_FLAG_NORMAL,
+ GTK_STYLE_PROPERTY_FONT, &g->font,
+ NULL);
#else
- g->font = gtk_widget_get_style(g->drawing_area)->font_desc;
-
- colormap = gtk_widget_get_colormap(GTK_WIDGET(g->drawing_area));
- if (!xor_gc) {
- xor_gc = gdk_gc_new (gtk_widget_get_window(g->drawing_area));
- gdk_gc_set_function (xor_gc, GDK_XOR);
- if (!gdk_color_parse ("gray15", &color)) {
- /*
- * XXX - do more than just warn.
- */
- simple_dialog(ESD_TYPE_WARN, ESD_BTN_OK,
- "Could not parse color gray15.");
- }
- if (!gdk_colormap_alloc_color (colormap, &color, FALSE, TRUE)) {
- /*
- * XXX - do more than just warn.
- */
- simple_dialog(ESD_TYPE_WARN, ESD_BTN_OK,
- "Could not allocate color gray15.");
- }
- gdk_gc_set_foreground (xor_gc, &color);
- }
-
- /* this is probably quite an ugly way to get rid of the first configure
- * event
- * immediately after gtk_widget_show (window) drawing_area gets a configure
- * event which is handled during the next return to gtk_main which is
- * probably the gdk_gc_new() call. configure handler calls
- * graph_element_lists_make() which is not good because the graph struct is
- * not fully set up yet - namely we're not sure about actual geometry
- * and we don't have the GC's at all. so we just postpone installation
- * of configure handler until we're ready to deal with it.
- *
- * !!! NEMLLO BY TO BYT NA KONCI graph_init_sequence()? !!!
- *
- */
+ g->font = gtk_widget_get_style(g->drawing_area)->font_desc;
+
+ colormap = gtk_widget_get_colormap(GTK_WIDGET(g->drawing_area));
+ if (!xor_gc) {
+ xor_gc = gdk_gc_new(gtk_widget_get_window(g->drawing_area));
+ gdk_gc_set_function(xor_gc, GDK_XOR);
+ if (!gdk_color_parse("gray15", &color)) {
+ /*
+ * XXX - do more than just warn.
+ */
+ simple_dialog(ESD_TYPE_WARN, ESD_BTN_OK,
+ "Could not parse color gray15.");
+ }
+ if (!gdk_colormap_alloc_color(colormap, &color, FALSE, TRUE)) {
+ /*
+ * XXX - do more than just warn.
+ */
+ simple_dialog(ESD_TYPE_WARN, ESD_BTN_OK,
+ "Could not allocate color gray15.");
+ }
+ gdk_gc_set_foreground(xor_gc, &color);
+ }
+
+ /* this is probably quite an ugly way to get rid of the first configure
+ * event
+ * immediately after gtk_widget_show(window) drawing_area gets a configure
+ * event which is handled during the next return to gtk_main which is
+ * probably the gdk_gc_new() call. configure handler calls
+ * graph_element_lists_make() which is not good because the graph struct is
+ * not fully set up yet - namely we're not sure about actual geometry
+ * and we don't have the GC's at all. so we just postpone installation
+ * of configure handler until we're ready to deal with it.
+ *
+ * !!! NEMLLO BY TO BYT NA KONCI graph_init_sequence()? !!!
+ *
+ */
#endif
- g_signal_connect(g->drawing_area, "configure_event", G_CALLBACK(configure_event),
- g);
+ g_signal_connect(g->drawing_area, "configure_event", G_CALLBACK(configure_event),
+ g);
- /* puts ("exiting create_drawing_area()"); */
+ /* puts("exiting create_drawing_area()"); */
}
-static void callback_toplevel_destroy (GtkWidget *widget _U_, gpointer data)
+static void callback_toplevel_destroy(GtkWidget *widget _U_, gpointer data)
{
- struct graph *g = (struct graph * )data;
+ struct graph *g = (struct graph *)data;
- if (!(g->flags & GRAPH_DESTROYED)) {
- g->flags |= GRAPH_DESTROYED;
- graph_destroy ((struct graph * )data);
- }
+ if (!(g->flags & GRAPH_DESTROYED)) {
+ g->flags |= GRAPH_DESTROYED;
+ graph_destroy((struct graph *)data);
+ }
}
-static void control_panel_create (struct graph *g)
+static void control_panel_create(struct graph *g)
{
- GtkWidget *toplevel, *notebook;
- GtkWidget *top_vb;
- GtkWidget *help_bt, *close_bt, *bbox;
- char window_title[WINDOW_TITLE_LENGTH];
+ GtkWidget *toplevel, *notebook;
+ GtkWidget *top_vb;
+ GtkWidget *help_bt, *close_bt, *bbox;
+ char window_title[WINDOW_TITLE_LENGTH];
- debug(DBS_FENTRY) puts ("control_panel_create()");
+ debug(DBS_FENTRY) puts("control_panel_create()");
- notebook = gtk_notebook_new ();
- control_panel_add_zoom_page (g, notebook);
- control_panel_add_magnify_page (g, notebook);
- control_panel_add_origin_page (g, notebook);
- control_panel_add_cross_page (g, notebook);
- control_panel_add_graph_type_page (g, notebook);
+ notebook = gtk_notebook_new();
+ control_panel_add_zoom_page(g, notebook);
+ control_panel_add_magnify_page(g, notebook);
+ control_panel_add_origin_page(g, notebook);
+ control_panel_add_cross_page(g, notebook);
+ control_panel_add_graph_type_page(g, notebook);
- g_snprintf (window_title, WINDOW_TITLE_LENGTH,
- "Graph %d - Control - Wireshark", refnum);
- toplevel = dlg_window_new ("tcp-graph-control");
- gtk_window_set_title(GTK_WINDOW(toplevel), window_title);
+ g_snprintf(window_title, WINDOW_TITLE_LENGTH,
+ "Graph %d - Control - Wireshark", refnum);
+ toplevel = dlg_window_new("tcp-graph-control");
+ gtk_window_set_title(GTK_WINDOW(toplevel), window_title);
- gtk_window_set_resizable(GTK_WINDOW(toplevel), FALSE); /* XXX: Acceptable ? */
+ gtk_window_set_resizable(GTK_WINDOW(toplevel), FALSE); /* XXX: Acceptable ? */
- top_vb = ws_gtk_box_new(GTK_ORIENTATION_VERTICAL, 0, FALSE);
- gtk_container_add(GTK_CONTAINER(toplevel), top_vb);
+ top_vb = ws_gtk_box_new(GTK_ORIENTATION_VERTICAL, 0, FALSE);
+ gtk_container_add(GTK_CONTAINER(toplevel), top_vb);
- gtk_box_pack_start(GTK_BOX(top_vb), notebook, FALSE, FALSE, 5);
+ gtk_box_pack_start(GTK_BOX(top_vb), notebook, FALSE, FALSE, 5);
- /* Button row. */
- bbox = dlg_button_row_new(GTK_STOCK_HELP, GTK_STOCK_CLOSE, NULL);
+ /* Button row. */
+ bbox = dlg_button_row_new(GTK_STOCK_HELP, GTK_STOCK_CLOSE, NULL);
gtk_box_pack_start(GTK_BOX(top_vb), bbox, FALSE, FALSE, 5);
- help_bt = g_object_get_data(G_OBJECT(bbox), GTK_STOCK_HELP);
- g_signal_connect(help_bt, "clicked", G_CALLBACK(callback_create_help), g);
+ help_bt = g_object_get_data(G_OBJECT(bbox), GTK_STOCK_HELP);
+ g_signal_connect(help_bt, "clicked", G_CALLBACK(callback_create_help), g);
- close_bt = g_object_get_data(G_OBJECT(bbox), GTK_STOCK_CLOSE);
- window_set_cancel_button(toplevel, close_bt, NULL);
- g_signal_connect(close_bt, "clicked", G_CALLBACK(callback_close), g);
+ close_bt = g_object_get_data(G_OBJECT(bbox), GTK_STOCK_CLOSE);
+ window_set_cancel_button(toplevel, close_bt, NULL);
+ g_signal_connect(close_bt, "clicked", G_CALLBACK(callback_close), g);
- g_signal_connect(toplevel, "delete_event", G_CALLBACK(callback_delete_event), g);
- g_signal_connect(toplevel, "destroy", G_CALLBACK(callback_toplevel_destroy), g);
+ g_signal_connect(toplevel, "delete_event", G_CALLBACK(callback_delete_event), g);
+ g_signal_connect(toplevel, "destroy", G_CALLBACK(callback_toplevel_destroy), g);
- gtk_widget_show_all (toplevel);
- window_present(toplevel);
+ gtk_widget_show_all(toplevel);
+ window_present(toplevel);
- g->gui.control_panel = toplevel;
+ g->gui.control_panel = toplevel;
}
-static void control_panel_add_zoom_page (struct graph *g, GtkWidget *n)
+static void control_panel_add_zoom_page(struct graph *g, GtkWidget *n)
{
- GtkWidget *zoom_frame;
- GtkWidget *zoom_lock_frame;
- GtkWidget *label;
- GtkWidget *box;
+ GtkWidget *zoom_frame;
+ GtkWidget *zoom_lock_frame;
+ GtkWidget *label;
+ GtkWidget *box;
- zoom_frame = control_panel_create_zoom_group (g);
- gtk_container_set_border_width (GTK_CONTAINER (zoom_frame), 5);
- zoom_lock_frame = control_panel_create_zoomlock_group (g);
- gtk_container_set_border_width (GTK_CONTAINER (zoom_lock_frame), 5);
- box = ws_gtk_box_new(GTK_ORIENTATION_VERTICAL, 0, FALSE);
- gtk_box_pack_start (GTK_BOX (box), zoom_frame, TRUE, TRUE, 0);
- gtk_box_pack_start (GTK_BOX (box), zoom_lock_frame, TRUE, TRUE, 0);
- gtk_widget_show (box);
- label = gtk_label_new ("Zoom");
- gtk_notebook_append_page (GTK_NOTEBOOK (n), box, label);
+ zoom_frame = control_panel_create_zoom_group(g);
+ gtk_container_set_border_width(GTK_CONTAINER(zoom_frame), 5);
+ zoom_lock_frame = control_panel_create_zoomlock_group(g);
+ gtk_container_set_border_width(GTK_CONTAINER(zoom_lock_frame), 5);
+ box = ws_gtk_box_new(GTK_ORIENTATION_VERTICAL, 0, FALSE);
+ gtk_box_pack_start(GTK_BOX(box), zoom_frame, TRUE, TRUE, 0);
+ gtk_box_pack_start(GTK_BOX(box), zoom_lock_frame, TRUE, TRUE, 0);
+ gtk_widget_show(box);
+ label = gtk_label_new("Zoom");
+ gtk_notebook_append_page(GTK_NOTEBOOK(n), box, label);
}
-static void control_panel_add_magnify_page (struct graph *g, GtkWidget *n)
+static void control_panel_add_magnify_page(struct graph *g, GtkWidget *n)
{
- GtkWidget *mag_frame, *label;
+ GtkWidget *mag_frame, *label;
- mag_frame = control_panel_create_magnify_group (g);
- gtk_container_set_border_width (GTK_CONTAINER (mag_frame), 5);
- label = gtk_label_new ("Magnify");
- gtk_notebook_append_page (GTK_NOTEBOOK (n), mag_frame, label);
+ mag_frame = control_panel_create_magnify_group(g);
+ gtk_container_set_border_width(GTK_CONTAINER(mag_frame), 5);
+ label = gtk_label_new("Magnify");
+ gtk_notebook_append_page(GTK_NOTEBOOK(n), mag_frame, label);
}
-static void control_panel_add_origin_page (struct graph *g, GtkWidget *n)
+static void control_panel_add_origin_page(struct graph *g, GtkWidget *n)
{
- GtkWidget *time_orig_cap, *time_orig_conn, *time_orig_box, *time_orig_frame;
- GtkWidget *seq_orig_isn, *seq_orig_zero, *seq_orig_box, *seq_orig_frame;
- GtkWidget *box, *label;
+ GtkWidget *time_orig_cap, *time_orig_conn, *time_orig_box, *time_orig_frame;
+ GtkWidget *seq_orig_isn, *seq_orig_zero, *seq_orig_box, *seq_orig_frame;
+ GtkWidget *box, *label;
- /* time origin box */
- time_orig_cap =
- gtk_radio_button_new_with_label (NULL, "beginning of capture");
- time_orig_conn = gtk_radio_button_new_with_label (
- gtk_radio_button_get_group (GTK_RADIO_BUTTON (time_orig_cap)),
- "beginning of this TCP connection");
- gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (time_orig_conn), TRUE);
- time_orig_box = ws_gtk_box_new(GTK_ORIENTATION_VERTICAL, 0, FALSE);
- gtk_box_pack_start (GTK_BOX (time_orig_box), time_orig_conn, TRUE, TRUE, 0);
- gtk_box_pack_start (GTK_BOX (time_orig_box), time_orig_cap, TRUE, TRUE, 0);
- time_orig_frame = gtk_frame_new ("Time origin");
- gtk_container_set_border_width (GTK_CONTAINER (time_orig_frame), 5);
- gtk_container_add (GTK_CONTAINER (time_orig_frame), time_orig_box);
+ /* time origin box */
+ time_orig_cap = gtk_radio_button_new_with_label(NULL, "beginning of capture");
+ time_orig_conn = gtk_radio_button_new_with_label(
+ gtk_radio_button_get_group(GTK_RADIO_BUTTON(time_orig_cap)),
+ "beginning of this TCP connection");
+ gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(time_orig_conn), TRUE);
+ time_orig_box = ws_gtk_box_new(GTK_ORIENTATION_VERTICAL, 0, FALSE);
+ gtk_box_pack_start(GTK_BOX(time_orig_box), time_orig_conn, TRUE, TRUE, 0);
+ gtk_box_pack_start(GTK_BOX(time_orig_box), time_orig_cap, TRUE, TRUE, 0);
+ time_orig_frame = gtk_frame_new("Time origin");
+ gtk_container_set_border_width(GTK_CONTAINER(time_orig_frame), 5);
+ gtk_container_add(GTK_CONTAINER(time_orig_frame), time_orig_box);
- /* sequence number origin group */
- seq_orig_isn =
- gtk_radio_button_new_with_label (NULL, "initial sequence number");
- seq_orig_zero = gtk_radio_button_new_with_label (gtk_radio_button_get_group (
- GTK_RADIO_BUTTON (seq_orig_isn)), "0 (=absolute)");
- gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (seq_orig_isn), TRUE);
- seq_orig_box = ws_gtk_box_new(GTK_ORIENTATION_VERTICAL, 0, FALSE);
- gtk_box_pack_start (GTK_BOX (seq_orig_box), seq_orig_isn, TRUE, TRUE, 0);
- gtk_box_pack_start (GTK_BOX (seq_orig_box), seq_orig_zero, TRUE, TRUE, 0);
- seq_orig_frame = gtk_frame_new ("Sequence number origin");
- gtk_container_set_border_width (GTK_CONTAINER (seq_orig_frame), 5);
- gtk_container_add (GTK_CONTAINER (seq_orig_frame), seq_orig_box);
+ /* sequence number origin group */
+ seq_orig_isn = gtk_radio_button_new_with_label(NULL, "initial sequence number");
+ seq_orig_zero = gtk_radio_button_new_with_label(
+ gtk_radio_button_get_group(GTK_RADIO_BUTTON(seq_orig_isn)),
+ "0 (=absolute)");
+ gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(seq_orig_isn), TRUE);
+ seq_orig_box = ws_gtk_box_new(GTK_ORIENTATION_VERTICAL, 0, FALSE);
+ gtk_box_pack_start(GTK_BOX(seq_orig_box), seq_orig_isn, TRUE, TRUE, 0);
+ gtk_box_pack_start(GTK_BOX(seq_orig_box), seq_orig_zero, TRUE, TRUE, 0);
+ seq_orig_frame = gtk_frame_new("Sequence number origin");
+ gtk_container_set_border_width(GTK_CONTAINER(seq_orig_frame), 5);
+ gtk_container_add(GTK_CONTAINER(seq_orig_frame), seq_orig_box);
- g->gui.time_orig_conn = (GtkToggleButton * )time_orig_conn;
- g->gui.seq_orig_isn = (GtkToggleButton * )seq_orig_isn;
+ g->gui.time_orig_conn = (GtkToggleButton * )time_orig_conn;
+ g->gui.seq_orig_isn = (GtkToggleButton * )seq_orig_isn;
- g_signal_connect(time_orig_conn, "toggled", G_CALLBACK(callback_time_origin), g);
- g_signal_connect(seq_orig_isn, "toggled", G_CALLBACK(callback_seq_origin), g);
+ g_signal_connect(time_orig_conn, "toggled", G_CALLBACK(callback_time_origin), g);
+ g_signal_connect(seq_orig_isn, "toggled", G_CALLBACK(callback_seq_origin), g);
- box = ws_gtk_box_new(GTK_ORIENTATION_VERTICAL, 0, FALSE);
- gtk_container_set_border_width (GTK_CONTAINER (box), 5);
- gtk_box_pack_start (GTK_BOX (box), time_orig_frame, TRUE, TRUE, 0);
- gtk_box_pack_start (GTK_BOX (box), seq_orig_frame, TRUE, TRUE, 0);
- gtk_widget_show (box);
- label = gtk_label_new ("Origin");
- gtk_notebook_append_page (GTK_NOTEBOOK (n), box, label);
+ box = ws_gtk_box_new(GTK_ORIENTATION_VERTICAL, 0, FALSE);
+ gtk_container_set_border_width(GTK_CONTAINER(box), 5);
+ gtk_box_pack_start(GTK_BOX(box), time_orig_frame, TRUE, TRUE, 0);
+ gtk_box_pack_start(GTK_BOX(box), seq_orig_frame, TRUE, TRUE, 0);
+ gtk_widget_show(box);
+ label = gtk_label_new("Origin");
+ gtk_notebook_append_page(GTK_NOTEBOOK(n), box, label);
}
static void control_panel_add_cross_page (struct graph *g, GtkWidget *n)
{
- GtkWidget *cross_frame, *label;
+ GtkWidget *cross_frame, *label;
- cross_frame = control_panel_create_cross_group (g);
- gtk_container_set_border_width (GTK_CONTAINER (cross_frame), 5);
- label = gtk_label_new ("Cross");
- gtk_notebook_append_page (GTK_NOTEBOOK (n), cross_frame, label);
+ cross_frame = control_panel_create_cross_group(g);
+ gtk_container_set_border_width(GTK_CONTAINER(cross_frame), 5);
+ label = gtk_label_new("Cross");
+ gtk_notebook_append_page(GTK_NOTEBOOK(n), cross_frame, label);
}
-static void control_panel_add_graph_type_page (struct graph *g, GtkWidget *n)
+static void control_panel_add_graph_type_page(struct graph *g, GtkWidget *n)
{
- GtkWidget *frame, *label;
+ GtkWidget *frame, *label;
- frame = control_panel_create_graph_type_group (g);
- gtk_container_set_border_width (GTK_CONTAINER (frame), 5);
- label = gtk_label_new ("Graph type");
- gtk_notebook_append_page (GTK_NOTEBOOK (n), frame, label);
+ frame = control_panel_create_graph_type_group(g);
+ gtk_container_set_border_width(GTK_CONTAINER(frame), 5);
+ label = gtk_label_new("Graph type");
+ gtk_notebook_append_page(GTK_NOTEBOOK(n), frame, label);
}
/* Treat this as a cancel, by calling "callback_close()" */
@@ -1043,930 +1051,931 @@ static gboolean
callback_delete_event(GtkWidget *widget _U_, GdkEvent *event _U_,
gpointer data)
{
- callback_close(NULL, data);
- return FALSE;
+ callback_close(NULL, data);
+ return FALSE;
}
-static void callback_close (GtkWidget *widget _U_, gpointer data)
+static void callback_close(GtkWidget *widget _U_, gpointer data)
{
- struct graph *g = (struct graph * )data;
+ struct graph *g = (struct graph * )data;
- if (!(g->flags & GRAPH_DESTROYED)) {
- g->flags |= GRAPH_DESTROYED;
- graph_destroy ((struct graph * )data);
- }
+ if (!(g->flags & GRAPH_DESTROYED)) {
+ g->flags |= GRAPH_DESTROYED;
+ graph_destroy((struct graph * )data);
+ }
}
static void callback_create_help(GtkWidget *widget _U_, gpointer data _U_)
{
- GtkWidget *toplevel, *vbox, *text, *scroll, *bbox, *close_bt;
- GtkTextBuffer *buf;
+ GtkWidget *toplevel, *vbox, *text, *scroll, *bbox, *close_bt;
+ GtkTextBuffer *buf;
- toplevel = dlg_window_new ("Help for TCP graphing");
- gtk_window_set_default_size(GTK_WINDOW(toplevel), 500, 400);
+ toplevel = dlg_window_new("Help for TCP graphing");
+ gtk_window_set_default_size(GTK_WINDOW(toplevel), 500, 400);
- vbox = ws_gtk_box_new(GTK_ORIENTATION_VERTICAL, 0, FALSE);
- gtk_container_set_border_width(GTK_CONTAINER(vbox), 12);
- gtk_container_add (GTK_CONTAINER (toplevel), vbox);
+ vbox = ws_gtk_box_new(GTK_ORIENTATION_VERTICAL, 0, FALSE);
+ gtk_container_set_border_width(GTK_CONTAINER(vbox), 12);
+ gtk_container_add(GTK_CONTAINER(toplevel), vbox);
- scroll = scrolled_window_new (NULL, NULL);
- gtk_scrolled_window_set_shadow_type(GTK_SCROLLED_WINDOW(scroll),
- GTK_SHADOW_IN);
- gtk_box_pack_start (GTK_BOX (vbox), scroll, TRUE, TRUE, 0);
- text = gtk_text_view_new();
- gtk_text_view_set_editable(GTK_TEXT_VIEW(text), FALSE);
- buf = gtk_text_view_get_buffer(GTK_TEXT_VIEW(text));
- gtk_text_buffer_set_text(buf, helptext, -1);
- gtk_container_add (GTK_CONTAINER (scroll), text);
+ scroll = scrolled_window_new(NULL, NULL);
+ gtk_scrolled_window_set_shadow_type(GTK_SCROLLED_WINDOW(scroll),
+ GTK_SHADOW_IN);
+ gtk_box_pack_start(GTK_BOX(vbox), scroll, TRUE, TRUE, 0);
+ text = gtk_text_view_new();
+ gtk_text_view_set_editable(GTK_TEXT_VIEW(text), FALSE);
+ buf = gtk_text_view_get_buffer(GTK_TEXT_VIEW(text));
+ gtk_text_buffer_set_text(buf, helptext, -1);
+ gtk_container_add(GTK_CONTAINER(scroll), text);
- /* Button row. */
- bbox = dlg_button_row_new(GTK_STOCK_CLOSE, NULL);
- gtk_box_pack_start (GTK_BOX (vbox), bbox, FALSE, FALSE, 0);
- gtk_widget_show(bbox);
+ /* Button row. */
+ bbox = dlg_button_row_new(GTK_STOCK_CLOSE, NULL);
+ gtk_box_pack_start(GTK_BOX(vbox), bbox, FALSE, FALSE, 0);
+ gtk_widget_show(bbox);
- close_bt = g_object_get_data(G_OBJECT(bbox), GTK_STOCK_CLOSE);
- window_set_cancel_button(toplevel, close_bt, window_cancel_button_cb);
+ close_bt = g_object_get_data(G_OBJECT(bbox), GTK_STOCK_CLOSE);
+ window_set_cancel_button(toplevel, close_bt, window_cancel_button_cb);
- g_signal_connect(toplevel, "delete_event", G_CALLBACK(window_delete_event_cb), NULL);
+ g_signal_connect(toplevel, "delete_event", G_CALLBACK(window_delete_event_cb), NULL);
- gtk_widget_show_all (toplevel);
- window_present(toplevel);
+ gtk_widget_show_all(toplevel);
+ window_present(toplevel);
}
static void get_mouse_position(GtkWidget *widget, int *pointer_x, int *pointer_y, GdkModifierType *mask)
{
#if GTK_CHECK_VERSION(3,0,0)
- gdk_window_get_device_position (gtk_widget_get_window(widget),
- gdk_device_manager_get_client_pointer(
- gdk_display_get_device_manager(
- gtk_widget_get_display(GTK_WIDGET(widget)))),
- pointer_x, pointer_y, mask);
+ gdk_window_get_device_position(gtk_widget_get_window(widget),
+ gdk_device_manager_get_client_pointer(
+ gdk_display_get_device_manager(
+ gtk_widget_get_display(GTK_WIDGET(widget)))),
+ pointer_x, pointer_y, mask);
#else
- gdk_window_get_pointer (gtk_widget_get_window(widget), pointer_x, pointer_y, mask);
+ gdk_window_get_pointer(gtk_widget_get_window(widget), pointer_x, pointer_y, mask);
#endif
}
-static void callback_time_origin (GtkWidget *toggle _U_, gpointer data)
-{
- toggle_time_origin ((struct graph * )data);
-}
-
-static void callback_seq_origin (GtkWidget *toggle _U_, gpointer data)
-{
- toggle_seq_origin ((struct graph * )data);
-}
-
-static GtkWidget *control_panel_create_zoom_group (struct graph *g)
+static void callback_time_origin(GtkWidget *toggle _U_, gpointer data)
+{
+ toggle_time_origin((struct graph * )data);
+}
+
+static void callback_seq_origin(GtkWidget *toggle _U_, gpointer data)
+{
+ toggle_seq_origin((struct graph * )data);
+}
+
+static GtkWidget *control_panel_create_zoom_group(struct graph *g)
{
- GtkWidget *zoom_in, *zoom_out, *zoom_box, *zoom_frame;
- GtkAdjustment *zoom_h_adj, *zoom_v_adj;
- GtkWidget *zoom_inout_box, *zoom_h_step_label, *zoom_h_step;
- GtkWidget *zoom_v_step_label, *zoom_v_step;
- GtkWidget *zoom_separator1, *zoom_separator2, *zoom_step_grid, *zoom_grid;
- GtkWidget *zoom_ratio_toggle, *zoom_same_toggle;
- GtkWidget *zoom_h_entry, *zoom_v_entry;
- GtkWidget *zoom_h_label, *zoom_v_label;
-
- zoom_in = gtk_radio_button_new_with_label (NULL, "in");
- zoom_out = gtk_radio_button_new_with_label (
- gtk_radio_button_get_group (GTK_RADIO_BUTTON (zoom_in)), "out");
- gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (zoom_in), TRUE);
- zoom_inout_box = ws_gtk_box_new(GTK_ORIENTATION_HORIZONTAL, 0, FALSE);
- gtk_box_pack_start (GTK_BOX (zoom_inout_box), zoom_in, FALSE, FALSE, 10);
- gtk_box_pack_start (GTK_BOX (zoom_inout_box), zoom_out, FALSE, FALSE, 0);
+ GtkWidget *zoom_in, *zoom_out, *zoom_box, *zoom_frame;
+ GtkAdjustment *zoom_h_adj, *zoom_v_adj;
+ GtkWidget *zoom_inout_box, *zoom_h_step_label, *zoom_h_step;
+ GtkWidget *zoom_v_step_label, *zoom_v_step;
+ GtkWidget *zoom_separator1, *zoom_separator2, *zoom_step_grid, *zoom_grid;
+ GtkWidget *zoom_ratio_toggle, *zoom_same_toggle;
+ GtkWidget *zoom_h_entry, *zoom_v_entry;
+ GtkWidget *zoom_h_label, *zoom_v_label;
- zoom_separator1 = gtk_separator_new (GTK_ORIENTATION_HORIZONTAL);
+ zoom_in = gtk_radio_button_new_with_label(NULL, "in");
+ zoom_out = gtk_radio_button_new_with_label(
+ gtk_radio_button_get_group(GTK_RADIO_BUTTON(zoom_in)), "out");
+ gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(zoom_in), TRUE);
+ zoom_inout_box = ws_gtk_box_new(GTK_ORIENTATION_HORIZONTAL, 0, FALSE);
+ gtk_box_pack_start(GTK_BOX(zoom_inout_box), zoom_in, FALSE, FALSE, 10);
+ gtk_box_pack_start(GTK_BOX(zoom_inout_box), zoom_out, FALSE, FALSE, 0);
- zoom_h_entry = gtk_entry_new ();
- gtk_entry_set_text (GTK_ENTRY (zoom_h_entry), "1.000");
- gtk_editable_set_editable (GTK_EDITABLE (zoom_h_entry), FALSE);
- zoom_h_label = gtk_label_new ("Horizontal:");
+ zoom_separator1 = gtk_separator_new(GTK_ORIENTATION_HORIZONTAL);
- zoom_v_entry = gtk_entry_new ();
- gtk_entry_set_text (GTK_ENTRY (zoom_v_entry), "1.000");
- gtk_editable_set_editable (GTK_EDITABLE (zoom_v_entry), FALSE);
- zoom_v_label = gtk_label_new ("Vertical:");
-
- g->zoom.widget.h_zoom = (GtkEntry * )zoom_h_entry;
- g->zoom.widget.v_zoom = (GtkEntry * )zoom_v_entry;
-
- zoom_grid = ws_gtk_grid_new();
- ws_gtk_grid_attach_extended(GTK_GRID(zoom_grid), zoom_h_label, 0, 0, 1, 1,
- GTK_FILL|GTK_EXPAND, 0, 5, 0);
- ws_gtk_grid_attach_extended(GTK_GRID(zoom_grid), zoom_h_entry, 1, 0, 1, 1,
- GTK_FILL|GTK_EXPAND, 0, 5, 0);
- ws_gtk_grid_attach_extended(GTK_GRID(zoom_grid), zoom_v_label, 0, 1, 1, 1,
- GTK_FILL|GTK_EXPAND, 0, 5, 0);
- ws_gtk_grid_attach_extended(GTK_GRID(zoom_grid), zoom_v_entry, 1, 1, 1, 1,
- GTK_FILL|GTK_EXPAND, 0, 5, 0);
-
- zoom_separator2 = gtk_separator_new (GTK_ORIENTATION_HORIZONTAL);
-
- zoom_h_adj = (GtkAdjustment * )gtk_adjustment_new ((gfloat)1.2, 1.0, 5, (gfloat)0.1, 1, 0);
- zoom_h_step = gtk_spin_button_new (zoom_h_adj, 0, 1);
- gtk_spin_button_set_numeric (GTK_SPIN_BUTTON (zoom_h_step), TRUE);
- zoom_h_step_label = gtk_label_new ("Horizontal step:");
-
- zoom_v_adj = (GtkAdjustment * )gtk_adjustment_new ((gfloat)1.2, 1.0, 5, (gfloat)0.1, 1, 0);
- zoom_v_step = gtk_spin_button_new (zoom_v_adj, 0, 1);
- gtk_spin_button_set_numeric (GTK_SPIN_BUTTON (zoom_v_step), TRUE);
- zoom_v_step_label = gtk_label_new ("Vertical step:");
-
- g->zoom.widget.h_step = (GtkSpinButton * )zoom_h_step;
- g->zoom.widget.v_step = (GtkSpinButton * )zoom_v_step;
-
- zoom_same_toggle = gtk_check_button_new_with_label("Keep them the same");
- zoom_ratio_toggle = gtk_check_button_new_with_label("Preserve their ratio");
- g_object_set_data(G_OBJECT(zoom_same_toggle), "flag", (gpointer)ZOOM_STEPS_SAME);
- g_object_set_data(G_OBJECT(zoom_ratio_toggle), "flag",
- (gpointer)ZOOM_STEPS_KEEP_RATIO);
- g_signal_connect(zoom_same_toggle, "clicked", G_CALLBACK(callback_zoom_flags), g);
- g_signal_connect(zoom_ratio_toggle, "clicked", G_CALLBACK(callback_zoom_flags), g);
-
- zoom_step_grid = ws_gtk_grid_new();
- ws_gtk_grid_attach_extended(GTK_GRID(zoom_step_grid), zoom_h_step_label, 0, 0, 1, 1,
- GTK_FILL|GTK_EXPAND, 0, 5, 0);
- ws_gtk_grid_attach_extended(GTK_GRID(zoom_step_grid), zoom_h_step, 1, 0, 1, 1,
- GTK_FILL|GTK_EXPAND, 0, 5, 0);
- ws_gtk_grid_attach_extended(GTK_GRID(zoom_step_grid), zoom_v_step_label, 0, 1, 1, 1,
- GTK_FILL|GTK_EXPAND, 0, 5, 0);
- ws_gtk_grid_attach_extended(GTK_GRID(zoom_step_grid), zoom_v_step, 1, 1, 1, 1,
- GTK_FILL|GTK_EXPAND, 0, 5, 0);
- ws_gtk_grid_attach_extended(GTK_GRID(zoom_step_grid), zoom_same_toggle, 0, 2, 2, 1,
- GTK_FILL|GTK_EXPAND, 0, 5, 0);
- ws_gtk_grid_attach_extended(GTK_GRID(zoom_step_grid), zoom_ratio_toggle, 0, 3, 2, 1,
- GTK_FILL|GTK_EXPAND, 0, 5, 0);
-
- zoom_box = ws_gtk_box_new(GTK_ORIENTATION_VERTICAL, 0, FALSE);
- gtk_box_pack_start (GTK_BOX (zoom_box), zoom_inout_box, TRUE, TRUE, 0);
- gtk_box_pack_start (GTK_BOX (zoom_box), zoom_separator1, TRUE, TRUE, 0);
- gtk_box_pack_start(GTK_BOX(zoom_box), zoom_grid, TRUE, TRUE, 0);
- gtk_box_pack_start (GTK_BOX (zoom_box), zoom_separator2, TRUE, TRUE, 0);
- gtk_box_pack_start(GTK_BOX(zoom_box), zoom_step_grid, TRUE, TRUE, 0);
- zoom_frame = gtk_frame_new ("Zoom");
- gtk_container_add (GTK_CONTAINER (zoom_frame), zoom_box);
-
- g_object_set_data(G_OBJECT(zoom_h_step), "direction", GINT_TO_POINTER(0));
- g_object_set_data(G_OBJECT(zoom_v_step), "direction", GINT_TO_POINTER(1));
-
- g_signal_connect(zoom_in, "toggled", G_CALLBACK(callback_zoom_inout), g);
- g_signal_connect(zoom_h_step, "changed", G_CALLBACK(callback_zoom_step), g);
- g_signal_connect(zoom_v_step, "changed", G_CALLBACK(callback_zoom_step), g);
-
- g->zoom.widget.in_toggle = (GtkToggleButton * )zoom_in;
- g->zoom.widget.out_toggle = (GtkToggleButton * )zoom_out;
- return zoom_frame;
-}
-
-static void callback_zoom_inout (GtkWidget *toggle, gpointer data)
-{
- struct graph *g = (struct graph * )data;
-
- if (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON (toggle)))
- g->zoom.flags &= ~ZOOM_OUT;
- else
- g->zoom.flags |= ZOOM_OUT;
-}
-
-static void callback_zoom_step (GtkWidget *spin, gpointer data)
-{
- struct graph *g = (struct graph * )data;
- double value;
- int direction;
- double *zoom_this, *zoom_other;
- GtkSpinButton *widget_this, *widget_other;
- double old_this;
-
- direction = GPOINTER_TO_INT(g_object_get_data(G_OBJECT(spin), "direction"));
- value = gtk_spin_button_get_value (GTK_SPIN_BUTTON (spin));
-
- if (direction) {
- zoom_this = &g->zoom.step_y;
- zoom_other = &g->zoom.step_x;
- widget_this = g->zoom.widget.v_step;
- widget_other = g->zoom.widget.h_step;
- } else {
- zoom_this = &g->zoom.step_x;
- zoom_other = &g->zoom.step_y;
- widget_this = g->zoom.widget.h_step;
- widget_other = g->zoom.widget.v_step;
- }
-
- old_this = *zoom_this;
- *zoom_this = value;
- if (g->zoom.flags & ZOOM_STEPS_SAME) {
- *zoom_other = value;
- gtk_spin_button_set_value (widget_other, (gfloat) *zoom_other);
- } else if (g->zoom.flags & ZOOM_STEPS_KEEP_RATIO) {
- double old_other = *zoom_other;
- *zoom_other *= value / old_this;
- if (*zoom_other < 1.0) {
- *zoom_other = 1.0;
- *zoom_this = old_this * 1.0 / old_other;
- gtk_spin_button_set_value (widget_this, (gfloat) *zoom_this);
- } else if (*zoom_other > 5.0) {
- *zoom_other = 5.0;
- *zoom_this = old_this * 5.0 / old_other;
- gtk_spin_button_set_value (widget_this, (gfloat) *zoom_this);
- }
- gtk_spin_button_set_value (widget_other, (gfloat) *zoom_other);
- }
-}
-
-static void callback_zoom_flags (GtkWidget *toggle, gpointer data)
-{
- struct graph *g = (struct graph * )data;
- int flag = GPOINTER_TO_INT(g_object_get_data(G_OBJECT(toggle), "flag"));
-
- if (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON (toggle)))
- g->zoom.flags |= flag;
- else
- g->zoom.flags &= ~flag;
-}
-
-static void update_zoom_spins (struct graph *g)
-{
- char s[32];
-
- g_snprintf (s, sizeof(s), "%.3f", g->zoom.x / g->zoom.initial.x);
- gtk_entry_set_text (g->zoom.widget.h_zoom, s);
- g_snprintf (s, sizeof(s), "%.3f", g->zoom.y / g->zoom.initial.y);
- gtk_entry_set_text (g->zoom.widget.v_zoom, s);
-}
-
-static GtkWidget *control_panel_create_magnify_group (struct graph *g)
-{
- GtkWidget *mag_width_label, *mag_width;
- GtkWidget *mag_height_label, *mag_height;
- GtkWidget *mag_x_label, *mag_x;
- GtkWidget *mag_y_label, *mag_y;
- GtkWidget *mag_wh_grid, *mag_zoom_frame, *mag_zoom_grid;
- GtkWidget *mag_h_zoom_label, *mag_h_zoom;
- GtkWidget *mag_v_zoom_label, *mag_v_zoom;
- GtkWidget *mag_zoom_same, *mag_zoom_ratio;
- GtkAdjustment *mag_width_adj, *mag_height_adj, *mag_x_adj, *mag_y_adj;
- GtkAdjustment *mag_h_zoom_adj, *mag_v_zoom_adj;
- GtkWidget *mag_box, *mag_frame;
-
- mag_width_label = gtk_label_new ("Width:");
- mag_width_adj = (GtkAdjustment * )gtk_adjustment_new (250,100,600,1,10,0);
- mag_width = gtk_spin_button_new (mag_width_adj, 0, 0);
-
- mag_height_label = gtk_label_new ("Height:");
- mag_height_adj = (GtkAdjustment * )gtk_adjustment_new (250,100,600,1,10,0);
- mag_height = gtk_spin_button_new (mag_height_adj, 0, 0);
-
- mag_x_label = gtk_label_new ("X:");
- mag_x_adj = (GtkAdjustment * )gtk_adjustment_new (0,-1000,1000,1,10,0);
- mag_x = gtk_spin_button_new (mag_x_adj, 0, 0);
-
- mag_y_label = gtk_label_new ("Y:");
- mag_y_adj = (GtkAdjustment * )gtk_adjustment_new (0,-1000,1000,1,10,0);
- mag_y = gtk_spin_button_new (mag_y_adj, 0, 0);
-
- mag_wh_grid = ws_gtk_grid_new();
- ws_gtk_grid_attach_extended(GTK_GRID(mag_wh_grid), mag_width_label, 0, 0, 1, 1,
- GTK_FILL|GTK_EXPAND, 0, 5, 0);
- ws_gtk_grid_attach_extended(GTK_GRID(mag_wh_grid), mag_width, 1, 0, 1, 1,
- GTK_FILL|GTK_EXPAND, 0, 5, 0);
- ws_gtk_grid_attach_extended(GTK_GRID(mag_wh_grid), mag_height_label, 0, 1, 1, 1,
- GTK_FILL|GTK_EXPAND, 0, 5, 0);
- ws_gtk_grid_attach_extended(GTK_GRID(mag_wh_grid), mag_height, 1, 1, 1, 1,
- GTK_FILL|GTK_EXPAND, 0, 5, 0);
- ws_gtk_grid_attach_extended(GTK_GRID(mag_wh_grid), mag_x_label, 0, 2, 1, 1,
- GTK_FILL|GTK_EXPAND, 0, 5, 0);
- ws_gtk_grid_attach_extended(GTK_GRID(mag_wh_grid), mag_x, 1, 2, 1, 1,
- GTK_FILL|GTK_EXPAND, 0, 5, 0);
- ws_gtk_grid_attach_extended(GTK_GRID(mag_wh_grid), mag_y_label, 0, 3, 1, 1,
- GTK_FILL|GTK_EXPAND, 0, 5, 0);
- ws_gtk_grid_attach_extended(GTK_GRID(mag_wh_grid), mag_y, 1, 3, 1, 1,
- GTK_FILL|GTK_EXPAND, 0, 5, 0);
-
- mag_h_zoom_label = gtk_label_new ("Horizontal:");
- mag_h_zoom_adj = (GtkAdjustment *)gtk_adjustment_new(10.0, 1.0, 25.0, (gfloat)0.1, 1, 0);
- mag_h_zoom = gtk_spin_button_new (mag_h_zoom_adj, 0, 1);
-
- mag_v_zoom_label = gtk_label_new ("Vertical:");
- mag_v_zoom_adj = (GtkAdjustment *)gtk_adjustment_new(10.0, 1.0, 25.0, (gfloat)0.1, 1, 0);
- mag_v_zoom = gtk_spin_button_new (mag_v_zoom_adj, 0, 1);
-
- mag_zoom_same = gtk_check_button_new_with_label ("Keep them the same");
- mag_zoom_ratio = gtk_check_button_new_with_label("Preserve their ratio");
-
- mag_zoom_grid = ws_gtk_grid_new();
- ws_gtk_grid_attach_extended(GTK_GRID(mag_zoom_grid), mag_h_zoom_label, 0, 0, 1, 1,
- GTK_FILL|GTK_EXPAND, 0, 0, 0);
- ws_gtk_grid_attach_extended(GTK_GRID(mag_zoom_grid), mag_h_zoom, 1, 0, 1, 1,
- GTK_FILL|GTK_EXPAND, 0, 0, 0);
- ws_gtk_grid_attach_extended(GTK_GRID(mag_zoom_grid), mag_v_zoom_label, 0, 1 , 1, 1,
- GTK_FILL|GTK_EXPAND, 0, 0, 0);
- ws_gtk_grid_attach_extended(GTK_GRID(mag_zoom_grid), mag_v_zoom, 1, 1, 1, 1,
- GTK_FILL|GTK_EXPAND, 0, 0, 0);
- ws_gtk_grid_attach_extended(GTK_GRID(mag_zoom_grid), mag_zoom_same, 0, 2, 2, 1,
- GTK_FILL|GTK_EXPAND, 0, 0, 0);
- ws_gtk_grid_attach_extended(GTK_GRID(mag_zoom_grid), mag_zoom_ratio, 0, 3, 2, 1,
- GTK_FILL|GTK_EXPAND, 0, 0, 0);
-
- mag_zoom_frame = gtk_frame_new ("Magnify zoom");
- gtk_container_add(GTK_CONTAINER(mag_zoom_frame), mag_zoom_grid);
- gtk_container_set_border_width (GTK_CONTAINER (mag_zoom_frame), 3);
-
- mag_box = ws_gtk_box_new(GTK_ORIENTATION_VERTICAL, 0, FALSE);
- gtk_box_pack_start(GTK_BOX(mag_box), mag_wh_grid, TRUE, TRUE, 0);
- gtk_box_pack_start (GTK_BOX (mag_box), mag_zoom_frame, TRUE, TRUE, 0);
- mag_frame = gtk_frame_new ("Magnify");
- gtk_container_add (GTK_CONTAINER (mag_frame), mag_box);
-
- g->magnify.widget.h_zoom = (GtkSpinButton * )mag_h_zoom;
- g->magnify.widget.v_zoom = (GtkSpinButton * )mag_v_zoom;
- g_object_set_data(G_OBJECT(mag_h_zoom), "direction", GINT_TO_POINTER(0));
- g_object_set_data(G_OBJECT(mag_v_zoom), "direction", GINT_TO_POINTER(1));
- g_object_set_data(G_OBJECT(mag_zoom_same), "flag", (gpointer)MAGZOOMS_SAME);
- g_object_set_data(G_OBJECT(mag_zoom_ratio), "flag", (gpointer)MAGZOOMS_SAME_RATIO);
-
- g_signal_connect(mag_width, "changed", G_CALLBACK(callback_mag_width), g);
- g_signal_connect(mag_height, "changed", G_CALLBACK(callback_mag_height), g);
- g_signal_connect(mag_x, "changed", G_CALLBACK(callback_mag_x), g);
- g_signal_connect(mag_y, "changed", G_CALLBACK(callback_mag_y), g);
- g_signal_connect(mag_h_zoom, "changed", G_CALLBACK(callback_mag_zoom), g);
- g_signal_connect(mag_v_zoom, "changed", G_CALLBACK(callback_mag_zoom), g);
- g_signal_connect(mag_zoom_same, "clicked", G_CALLBACK(callback_mag_flags), g);
- g_signal_connect(mag_zoom_ratio, "clicked", G_CALLBACK(callback_mag_flags), g);
-
- return mag_frame;
-}
-
-static void callback_mag_width (GtkWidget *spin, gpointer data)
-{
- struct graph *g = (struct graph * )data;
-
- g->magnify.width = gtk_spin_button_get_value_as_int (GTK_SPIN_BUTTON(spin));
-}
-
-static void callback_mag_height (GtkWidget *spin, gpointer data)
-{
- struct graph *g = (struct graph * )data;
-
- g->magnify.height = gtk_spin_button_get_value_as_int(GTK_SPIN_BUTTON(spin));
-}
-
-static void callback_mag_x (GtkWidget *spin, gpointer data)
-{
- struct graph *g = (struct graph * )data;
-
- g->magnify.offset.x=gtk_spin_button_get_value_as_int(GTK_SPIN_BUTTON(spin));
-}
-
-static void callback_mag_y (GtkWidget *spin, gpointer data)
-{
- struct graph *g = (struct graph * )data;
-
- g->magnify.offset.y=gtk_spin_button_get_value_as_int(GTK_SPIN_BUTTON(spin));
-}
-
-static void callback_mag_zoom (GtkWidget *spin, gpointer data)
-{
- struct graph *g = (struct graph * )data;
- double value;
- int direction;
- double *zoom_this, *zoom_other;
- GtkSpinButton *widget_this, *widget_other;
- double old_this;
-
- if (g->magnify.flags & MAGZOOMS_IGNORE) {
- printf ("refusing callback for %s zoom widget.\n", (GtkSpinButton * )spin==g->magnify.widget.h_zoom ? "horizontal" : "vertical");
- g->magnify.flags &= ~MAGZOOMS_IGNORE;
- return;
- }
- direction = GPOINTER_TO_INT(g_object_get_data(G_OBJECT(spin), "direction"));
- value = gtk_spin_button_get_value (GTK_SPIN_BUTTON (spin));
+ zoom_h_entry = gtk_entry_new();
+ gtk_entry_set_text(GTK_ENTRY(zoom_h_entry), "1.000");
+ gtk_editable_set_editable(GTK_EDITABLE(zoom_h_entry), FALSE);
+ zoom_h_label = gtk_label_new("Horizontal:");
- if (direction) {
- zoom_this = &g->magnify.zoom.y;
- zoom_other = &g->magnify.zoom.x;
- widget_this = g->magnify.widget.v_zoom;
- widget_other = g->magnify.widget.h_zoom;
- } else {
- zoom_this = &g->magnify.zoom.x;
- zoom_other = &g->magnify.zoom.y;
- widget_this = g->magnify.widget.h_zoom;
- widget_other = g->magnify.widget.v_zoom;
- }
+ zoom_v_entry = gtk_entry_new();
+ gtk_entry_set_text(GTK_ENTRY(zoom_v_entry), "1.000");
+ gtk_editable_set_editable(GTK_EDITABLE(zoom_v_entry), FALSE);
+ zoom_v_label = gtk_label_new("Vertical:");
+
+ g->zoom.widget.h_zoom = (GtkEntry * )zoom_h_entry;
+ g->zoom.widget.v_zoom = (GtkEntry * )zoom_v_entry;
+
+ zoom_grid = ws_gtk_grid_new();
+ ws_gtk_grid_attach_extended(GTK_GRID(zoom_grid), zoom_h_label, 0, 0, 1, 1,
+ GTK_FILL|GTK_EXPAND, 0, 5, 0);
+ ws_gtk_grid_attach_extended(GTK_GRID(zoom_grid), zoom_h_entry, 1, 0, 1, 1,
+ GTK_FILL|GTK_EXPAND, 0, 5, 0);
+ ws_gtk_grid_attach_extended(GTK_GRID(zoom_grid), zoom_v_label, 0, 1, 1, 1,
+ GTK_FILL|GTK_EXPAND, 0, 5, 0);
+ ws_gtk_grid_attach_extended(GTK_GRID(zoom_grid), zoom_v_entry, 1, 1, 1, 1,
+ GTK_FILL|GTK_EXPAND, 0, 5, 0);
+
+ zoom_separator2 = gtk_separator_new(GTK_ORIENTATION_HORIZONTAL);
+
+ zoom_h_adj = (GtkAdjustment * )gtk_adjustment_new((gfloat)1.2, 1.0, 5, (gfloat)0.1, 1, 0);
+ zoom_h_step = gtk_spin_button_new(zoom_h_adj, 0, 1);
+ gtk_spin_button_set_numeric(GTK_SPIN_BUTTON(zoom_h_step), TRUE);
+ zoom_h_step_label = gtk_label_new("Horizontal step:");
+
+ zoom_v_adj = (GtkAdjustment * )gtk_adjustment_new((gfloat)1.2, 1.0, 5, (gfloat)0.1, 1, 0);
+ zoom_v_step = gtk_spin_button_new(zoom_v_adj, 0, 1);
+ gtk_spin_button_set_numeric(GTK_SPIN_BUTTON(zoom_v_step), TRUE);
+ zoom_v_step_label = gtk_label_new("Vertical step:");
+
+ g->zoom.widget.h_step = (GtkSpinButton * )zoom_h_step;
+ g->zoom.widget.v_step = (GtkSpinButton * )zoom_v_step;
+
+ zoom_same_toggle = gtk_check_button_new_with_label("Keep them the same");
+ zoom_ratio_toggle = gtk_check_button_new_with_label("Preserve their ratio");
+ g_object_set_data(G_OBJECT(zoom_same_toggle), "flag", (gpointer)ZOOM_STEPS_SAME);
+ g_object_set_data(G_OBJECT(zoom_ratio_toggle), "flag",
+ (gpointer)ZOOM_STEPS_KEEP_RATIO);
+ g_signal_connect(zoom_same_toggle, "clicked", G_CALLBACK(callback_zoom_flags), g);
+ g_signal_connect(zoom_ratio_toggle, "clicked", G_CALLBACK(callback_zoom_flags), g);
+
+ zoom_step_grid = ws_gtk_grid_new();
+ ws_gtk_grid_attach_extended(GTK_GRID(zoom_step_grid), zoom_h_step_label, 0, 0, 1, 1,
+ GTK_FILL|GTK_EXPAND, 0, 5, 0);
+ ws_gtk_grid_attach_extended(GTK_GRID(zoom_step_grid), zoom_h_step, 1, 0, 1, 1,
+ GTK_FILL|GTK_EXPAND, 0, 5, 0);
+ ws_gtk_grid_attach_extended(GTK_GRID(zoom_step_grid), zoom_v_step_label, 0, 1, 1, 1,
+ GTK_FILL|GTK_EXPAND, 0, 5, 0);
+ ws_gtk_grid_attach_extended(GTK_GRID(zoom_step_grid), zoom_v_step, 1, 1, 1, 1,
+ GTK_FILL|GTK_EXPAND, 0, 5, 0);
+ ws_gtk_grid_attach_extended(GTK_GRID(zoom_step_grid), zoom_same_toggle, 0, 2, 2, 1,
+ GTK_FILL|GTK_EXPAND, 0, 5, 0);
+ ws_gtk_grid_attach_extended(GTK_GRID(zoom_step_grid), zoom_ratio_toggle, 0, 3, 2, 1,
+ GTK_FILL|GTK_EXPAND, 0, 5, 0);
+
+ zoom_box = ws_gtk_box_new(GTK_ORIENTATION_VERTICAL, 0, FALSE);
+ gtk_box_pack_start(GTK_BOX(zoom_box), zoom_inout_box, TRUE, TRUE, 0);
+ gtk_box_pack_start(GTK_BOX(zoom_box), zoom_separator1, TRUE, TRUE, 0);
+ gtk_box_pack_start(GTK_BOX(zoom_box), zoom_grid, TRUE, TRUE, 0);
+ gtk_box_pack_start(GTK_BOX(zoom_box), zoom_separator2, TRUE, TRUE, 0);
+ gtk_box_pack_start(GTK_BOX(zoom_box), zoom_step_grid, TRUE, TRUE, 0);
+ zoom_frame = gtk_frame_new("Zoom");
+ gtk_container_add(GTK_CONTAINER(zoom_frame), zoom_box);
+
+ g_object_set_data(G_OBJECT(zoom_h_step), "direction", GINT_TO_POINTER(0));
+ g_object_set_data(G_OBJECT(zoom_v_step), "direction", GINT_TO_POINTER(1));
+
+ g_signal_connect(zoom_in, "toggled", G_CALLBACK(callback_zoom_inout), g);
+ g_signal_connect(zoom_h_step, "changed", G_CALLBACK(callback_zoom_step), g);
+ g_signal_connect(zoom_v_step, "changed", G_CALLBACK(callback_zoom_step), g);
+
+ g->zoom.widget.in_toggle = (GtkToggleButton * )zoom_in;
+ g->zoom.widget.out_toggle = (GtkToggleButton * )zoom_out;
+ return zoom_frame;
+}
+
+static void callback_zoom_inout(GtkWidget *toggle, gpointer data)
+{
+ struct graph *g = (struct graph * )data;
+
+ if (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(toggle)))
+ g->zoom.flags &= ~ZOOM_OUT;
+ else
+ g->zoom.flags |= ZOOM_OUT;
+}
+
+static void callback_zoom_step(GtkWidget *spin, gpointer data)
+{
+ struct graph *g = (struct graph * )data;
+ double value;
+ int direction;
+ double *zoom_this, *zoom_other;
+ GtkSpinButton *widget_this, *widget_other;
+ double old_this;
+
+ direction = GPOINTER_TO_INT(g_object_get_data(G_OBJECT(spin), "direction"));
+ value = gtk_spin_button_get_value(GTK_SPIN_BUTTON(spin));
+
+ if (direction) {
+ zoom_this = &g->zoom.step_y;
+ zoom_other = &g->zoom.step_x;
+ widget_this = g->zoom.widget.v_step;
+ widget_other = g->zoom.widget.h_step;
+ } else {
+ zoom_this = &g->zoom.step_x;
+ zoom_other = &g->zoom.step_y;
+ widget_this = g->zoom.widget.h_step;
+ widget_other = g->zoom.widget.v_step;
+ }
+
+ old_this = *zoom_this;
+ *zoom_this = value;
+ if (g->zoom.flags & ZOOM_STEPS_SAME) {
+ *zoom_other = value;
+ gtk_spin_button_set_value(widget_other, (gfloat) *zoom_other);
+ } else if (g->zoom.flags & ZOOM_STEPS_KEEP_RATIO) {
+ double old_other = *zoom_other;
+ *zoom_other *= value / old_this;
+ if (*zoom_other < 1.0) {
+ *zoom_other = 1.0;
+ *zoom_this = old_this * 1.0 / old_other;
+ gtk_spin_button_set_value(widget_this, (gfloat) *zoom_this);
+ } else if (*zoom_other > 5.0) {
+ *zoom_other = 5.0;
+ *zoom_this = old_this * 5.0 / old_other;
+ gtk_spin_button_set_value(widget_this, (gfloat) *zoom_this);
+ }
+ gtk_spin_button_set_value(widget_other, (gfloat) *zoom_other);
+ }
+}
+
+static void callback_zoom_flags(GtkWidget *toggle, gpointer data)
+{
+ struct graph *g = (struct graph * )data;
+ int flag = GPOINTER_TO_INT(g_object_get_data(G_OBJECT(toggle), "flag"));
+
+ if (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(toggle)))
+ g->zoom.flags |= flag;
+ else
+ g->zoom.flags &= ~flag;
+}
+
+static void update_zoom_spins(struct graph *g)
+{
+ char s[32];
+
+ g_snprintf(s, sizeof(s), "%.3f", g->zoom.x / g->zoom.initial.x);
+ gtk_entry_set_text(g->zoom.widget.h_zoom, s);
+ g_snprintf(s, sizeof(s), "%.3f", g->zoom.y / g->zoom.initial.y);
+ gtk_entry_set_text(g->zoom.widget.v_zoom, s);
+}
+
+static GtkWidget *control_panel_create_magnify_group(struct graph *g)
+{
+ GtkWidget *mag_width_label, *mag_width;
+ GtkWidget *mag_height_label, *mag_height;
+ GtkWidget *mag_x_label, *mag_x;
+ GtkWidget *mag_y_label, *mag_y;
+ GtkWidget *mag_wh_grid, *mag_zoom_frame, *mag_zoom_grid;
+ GtkWidget *mag_h_zoom_label, *mag_h_zoom;
+ GtkWidget *mag_v_zoom_label, *mag_v_zoom;
+ GtkWidget *mag_zoom_same, *mag_zoom_ratio;
+ GtkAdjustment *mag_width_adj, *mag_height_adj, *mag_x_adj, *mag_y_adj;
+ GtkAdjustment *mag_h_zoom_adj, *mag_v_zoom_adj;
+ GtkWidget *mag_box, *mag_frame;
+
+ mag_width_label = gtk_label_new("Width:");
+ mag_width_adj = (GtkAdjustment * )gtk_adjustment_new(250, 100, 600, 1, 10, 0);
+ mag_width = gtk_spin_button_new(mag_width_adj, 0, 0);
+
+ mag_height_label = gtk_label_new("Height:");
+ mag_height_adj = (GtkAdjustment * )gtk_adjustment_new(250, 100, 600, 1, 10, 0);
+ mag_height = gtk_spin_button_new(mag_height_adj, 0, 0);
+
+ mag_x_label = gtk_label_new("X:");
+ mag_x_adj = (GtkAdjustment * )gtk_adjustment_new(0, -1000, 1000, 1, 10, 0);
+ mag_x = gtk_spin_button_new(mag_x_adj, 0, 0);
+
+ mag_y_label = gtk_label_new("Y:");
+ mag_y_adj = (GtkAdjustment * )gtk_adjustment_new(0, -1000, 1000, 1, 10, 0);
+ mag_y = gtk_spin_button_new(mag_y_adj, 0, 0);
+
+ mag_wh_grid = ws_gtk_grid_new();
+ ws_gtk_grid_attach_extended(GTK_GRID(mag_wh_grid), mag_width_label, 0, 0, 1, 1,
+ GTK_FILL|GTK_EXPAND, 0, 5, 0);
+ ws_gtk_grid_attach_extended(GTK_GRID(mag_wh_grid), mag_width, 1, 0, 1, 1,
+ GTK_FILL|GTK_EXPAND, 0, 5, 0);
+ ws_gtk_grid_attach_extended(GTK_GRID(mag_wh_grid), mag_height_label, 0, 1, 1, 1,
+ GTK_FILL|GTK_EXPAND, 0, 5, 0);
+ ws_gtk_grid_attach_extended(GTK_GRID(mag_wh_grid), mag_height, 1, 1, 1, 1,
+ GTK_FILL|GTK_EXPAND, 0, 5, 0);
+ ws_gtk_grid_attach_extended(GTK_GRID(mag_wh_grid), mag_x_label, 0, 2, 1, 1,
+ GTK_FILL|GTK_EXPAND, 0, 5, 0);
+ ws_gtk_grid_attach_extended(GTK_GRID(mag_wh_grid), mag_x, 1, 2, 1, 1,
+ GTK_FILL|GTK_EXPAND, 0, 5, 0);
+ ws_gtk_grid_attach_extended(GTK_GRID(mag_wh_grid), mag_y_label, 0, 3, 1, 1,
+ GTK_FILL|GTK_EXPAND, 0, 5, 0);
+ ws_gtk_grid_attach_extended(GTK_GRID(mag_wh_grid), mag_y, 1, 3, 1, 1,
+ GTK_FILL|GTK_EXPAND, 0, 5, 0);
+
+ mag_h_zoom_label = gtk_label_new("Horizontal:");
+ mag_h_zoom_adj = (GtkAdjustment *)gtk_adjustment_new(10.0, 1.0, 25.0, (gfloat)0.1, 1, 0);
+ mag_h_zoom = gtk_spin_button_new(mag_h_zoom_adj, 0, 1);
+
+ mag_v_zoom_label = gtk_label_new("Vertical:");
+ mag_v_zoom_adj = (GtkAdjustment *)gtk_adjustment_new(10.0, 1.0, 25.0, (gfloat)0.1, 1, 0);
+ mag_v_zoom = gtk_spin_button_new(mag_v_zoom_adj, 0, 1);
+
+ mag_zoom_same = gtk_check_button_new_with_label("Keep them the same");
+ mag_zoom_ratio = gtk_check_button_new_with_label("Preserve their ratio");
+
+ mag_zoom_grid = ws_gtk_grid_new();
+ ws_gtk_grid_attach_extended(GTK_GRID(mag_zoom_grid), mag_h_zoom_label, 0, 0, 1, 1,
+ GTK_FILL|GTK_EXPAND, 0, 0, 0);
+ ws_gtk_grid_attach_extended(GTK_GRID(mag_zoom_grid), mag_h_zoom, 1, 0, 1, 1,
+ GTK_FILL|GTK_EXPAND, 0, 0, 0);
+ ws_gtk_grid_attach_extended(GTK_GRID(mag_zoom_grid), mag_v_zoom_label, 0, 1 , 1, 1,
+ GTK_FILL|GTK_EXPAND, 0, 0, 0);
+ ws_gtk_grid_attach_extended(GTK_GRID(mag_zoom_grid), mag_v_zoom, 1, 1, 1, 1,
+ GTK_FILL|GTK_EXPAND, 0, 0, 0);
+ ws_gtk_grid_attach_extended(GTK_GRID(mag_zoom_grid), mag_zoom_same, 0, 2, 2, 1,
+ GTK_FILL|GTK_EXPAND, 0, 0, 0);
+ ws_gtk_grid_attach_extended(GTK_GRID(mag_zoom_grid), mag_zoom_ratio, 0, 3, 2, 1,
+ GTK_FILL|GTK_EXPAND, 0, 0, 0);
+
+ mag_zoom_frame = gtk_frame_new("Magnify zoom");
+ gtk_container_add(GTK_CONTAINER(mag_zoom_frame), mag_zoom_grid);
+ gtk_container_set_border_width(GTK_CONTAINER(mag_zoom_frame), 3);
+
+ mag_box = ws_gtk_box_new(GTK_ORIENTATION_VERTICAL, 0, FALSE);
+ gtk_box_pack_start(GTK_BOX(mag_box), mag_wh_grid, TRUE, TRUE, 0);
+ gtk_box_pack_start(GTK_BOX(mag_box), mag_zoom_frame, TRUE, TRUE, 0);
+ mag_frame = gtk_frame_new("Magnify");
+ gtk_container_add(GTK_CONTAINER(mag_frame), mag_box);
+
+ g->magnify.widget.h_zoom = (GtkSpinButton * )mag_h_zoom;
+ g->magnify.widget.v_zoom = (GtkSpinButton * )mag_v_zoom;
+ g_object_set_data(G_OBJECT(mag_h_zoom), "direction", GINT_TO_POINTER(0));
+ g_object_set_data(G_OBJECT(mag_v_zoom), "direction", GINT_TO_POINTER(1));
+ g_object_set_data(G_OBJECT(mag_zoom_same), "flag", (gpointer)MAGZOOMS_SAME);
+ g_object_set_data(G_OBJECT(mag_zoom_ratio), "flag", (gpointer)MAGZOOMS_SAME_RATIO);
+
+ g_signal_connect(mag_width, "changed", G_CALLBACK(callback_mag_width), g);
+ g_signal_connect(mag_height, "changed", G_CALLBACK(callback_mag_height), g);
+ g_signal_connect(mag_x, "changed", G_CALLBACK(callback_mag_x), g);
+ g_signal_connect(mag_y, "changed", G_CALLBACK(callback_mag_y), g);
+ g_signal_connect(mag_h_zoom, "changed", G_CALLBACK(callback_mag_zoom), g);
+ g_signal_connect(mag_v_zoom, "changed", G_CALLBACK(callback_mag_zoom), g);
+ g_signal_connect(mag_zoom_same, "clicked", G_CALLBACK(callback_mag_flags), g);
+ g_signal_connect(mag_zoom_ratio, "clicked", G_CALLBACK(callback_mag_flags), g);
+
+ return mag_frame;
+}
+
+static void callback_mag_width(GtkWidget *spin, gpointer data)
+{
+ struct graph *g = (struct graph * )data;
+
+ g->magnify.width = gtk_spin_button_get_value_as_int(GTK_SPIN_BUTTON(spin));
+}
+
+static void callback_mag_height(GtkWidget *spin, gpointer data)
+{
+ struct graph *g = (struct graph * )data;
+
+ g->magnify.height = gtk_spin_button_get_value_as_int(GTK_SPIN_BUTTON(spin));
+}
+
+static void callback_mag_x(GtkWidget *spin, gpointer data)
+{
+ struct graph *g = (struct graph * )data;
+
+ g->magnify.offset.x = gtk_spin_button_get_value_as_int(GTK_SPIN_BUTTON(spin));
+}
+
+static void callback_mag_y(GtkWidget *spin, gpointer data)
+{
+ struct graph *g = (struct graph * )data;
+
+ g->magnify.offset.y = gtk_spin_button_get_value_as_int(GTK_SPIN_BUTTON(spin));
+}
+
+static void callback_mag_zoom(GtkWidget *spin, gpointer data)
+{
+ struct graph *g = (struct graph * )data;
+ double value;
+ int direction;
+ double *zoom_this, *zoom_other;
+ GtkSpinButton *widget_this, *widget_other;
+ double old_this;
+
+ if (g->magnify.flags & MAGZOOMS_IGNORE) {
+ printf("refusing callback for %s zoom widget.\n",
+ ((GtkSpinButton * )spin == g->magnify.widget.h_zoom) ? "horizontal" : "vertical");
+ g->magnify.flags &= ~MAGZOOMS_IGNORE;
+ return;
+ }
+ direction = GPOINTER_TO_INT(g_object_get_data(G_OBJECT(spin), "direction"));
+ value = gtk_spin_button_get_value(GTK_SPIN_BUTTON(spin));
- old_this = *zoom_this;
- *zoom_this = value;
- if (g->magnify.flags & MAGZOOMS_SAME) {
- *zoom_other = value;
- /* g->magnify.flags |= MAGZOOMS_IGNORE; */
- gtk_spin_button_set_value (widget_other, (gfloat) *zoom_other);
- } else if (g->magnify.flags & MAGZOOMS_SAME_RATIO) {
- double old_other = *zoom_other;
- *zoom_other *= value / old_this;
- if (*zoom_other < 1.0) {
- *zoom_other = 1.0;
- *zoom_this = old_this * 1.0 / old_other;
- /* g->magnify.flags |= MAGZOOMS_IGNORE; */
- gtk_spin_button_set_value (widget_this, (gfloat) *zoom_this);
- } else if (*zoom_other > 25.0) {
- *zoom_other = 25.0;
- *zoom_this = old_this * 25.0 / old_other;
- /* g->magnify.flags |= MAGZOOMS_IGNORE; */
- gtk_spin_button_set_value (widget_this, (gfloat) *zoom_this);
- }
- /* g->magnify.flags |= MAGZOOMS_IGNORE; */
- gtk_spin_button_set_value (widget_other, (gfloat) *zoom_other);
- }
+ if (direction) {
+ zoom_this = &g->magnify.zoom.y;
+ zoom_other = &g->magnify.zoom.x;
+ widget_this = g->magnify.widget.v_zoom;
+ widget_other = g->magnify.widget.h_zoom;
+ } else {
+ zoom_this = &g->magnify.zoom.x;
+ zoom_other = &g->magnify.zoom.y;
+ widget_this = g->magnify.widget.h_zoom;
+ widget_other = g->magnify.widget.v_zoom;
+ }
+
+ old_this = *zoom_this;
+ *zoom_this = value;
+ if (g->magnify.flags & MAGZOOMS_SAME) {
+ *zoom_other = value;
+ /* g->magnify.flags |= MAGZOOMS_IGNORE; */
+ gtk_spin_button_set_value(widget_other, (gfloat) *zoom_other);
+ } else if (g->magnify.flags & MAGZOOMS_SAME_RATIO) {
+ double old_other = *zoom_other;
+ *zoom_other *= value / old_this;
+ if (*zoom_other < 1.0) {
+ *zoom_other = 1.0;
+ *zoom_this = old_this * 1.0 / old_other;
+ /* g->magnify.flags |= MAGZOOMS_IGNORE; */
+ gtk_spin_button_set_value(widget_this, (gfloat) *zoom_this);
+ } else if (*zoom_other > 25.0) {
+ *zoom_other = 25.0;
+ *zoom_this = old_this * 25.0 / old_other;
+ /* g->magnify.flags |= MAGZOOMS_IGNORE; */
+ gtk_spin_button_set_value(widget_this, (gfloat) *zoom_this);
+ }
+ /* g->magnify.flags |= MAGZOOMS_IGNORE; */
+ gtk_spin_button_set_value(widget_other, (gfloat) *zoom_other);
+ }
}
-static void callback_mag_flags (GtkWidget *toggle, gpointer data)
+static void callback_mag_flags(GtkWidget *toggle, gpointer data)
{
- struct graph *g = (struct graph * )data;
- int flag = GPOINTER_TO_INT(g_object_get_data(G_OBJECT(toggle), "flag"));
+ struct graph *g = (struct graph * )data;
+ int flag = GPOINTER_TO_INT(g_object_get_data(G_OBJECT(toggle), "flag"));
- if (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON (toggle)))
- g->magnify.flags |= flag;
- else
- g->magnify.flags &= ~flag;
+ if (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(toggle)))
+ g->magnify.flags |= flag;
+ else
+ g->magnify.flags &= ~flag;
}
-static GtkWidget *control_panel_create_zoomlock_group (struct graph *g)
+static GtkWidget *control_panel_create_zoomlock_group(struct graph *g)
{
- GtkWidget *zoom_lock_h, *zoom_lock_v, *zoom_lock_none, *zoom_lock_box;
- GtkWidget *zoom_lock_frame;
+ GtkWidget *zoom_lock_h, *zoom_lock_v, *zoom_lock_none, *zoom_lock_box;
+ GtkWidget *zoom_lock_frame;
- zoom_lock_none = gtk_radio_button_new_with_label (NULL, "none");
- zoom_lock_h = gtk_radio_button_new_with_label (
- gtk_radio_button_get_group (GTK_RADIO_BUTTON (zoom_lock_none)),
- "horizontal");
- zoom_lock_v = gtk_radio_button_new_with_label (
- gtk_radio_button_get_group (GTK_RADIO_BUTTON (zoom_lock_none)),
- "vertical");
- gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (zoom_lock_none), TRUE);
- zoom_lock_box = ws_gtk_box_new(GTK_ORIENTATION_HORIZONTAL, 0, FALSE);
- gtk_box_pack_start(GTK_BOX(zoom_lock_box), zoom_lock_none,
- TRUE, TRUE, 0);
- gtk_box_pack_start(GTK_BOX(zoom_lock_box), zoom_lock_h, TRUE, TRUE, 0);
- gtk_box_pack_start(GTK_BOX(zoom_lock_box), zoom_lock_v, TRUE, TRUE, 0);
- zoom_lock_frame = gtk_frame_new ("Zoom lock:");
- gtk_container_add (GTK_CONTAINER (zoom_lock_frame), zoom_lock_box);
-
- g_signal_connect(zoom_lock_h, "toggled", G_CALLBACK(callback_zoomlock_h), g);
- g_signal_connect(zoom_lock_v, "toggled", G_CALLBACK(callback_zoomlock_v), g);
-
- return zoom_lock_frame;
-}
-
-static void callback_zoomlock_h (GtkWidget *toggle, gpointer data)
-{
- struct graph *g = (struct graph * )data;
-
- if (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON (toggle)))
- g->zoom.flags |= ZOOM_HLOCK;
- else
- g->zoom.flags &= ~ZOOM_HLOCK;
-}
-
-static void callback_zoomlock_v (GtkWidget *toggle, gpointer data)
-{
- struct graph *g = (struct graph * )data;
-
- if (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON (toggle)))
- g->zoom.flags |= ZOOM_VLOCK;
- else
- g->zoom.flags &= ~ZOOM_VLOCK;
-}
-
-static GtkWidget *control_panel_create_cross_group (struct graph *g)
-{
- GtkWidget *on, *off, *box, *frame, *vbox, *label;
-
- label = gtk_label_new ("Crosshairs:");
- off = gtk_radio_button_new_with_label (NULL, "off");
- on = gtk_radio_button_new_with_label (
- gtk_radio_button_get_group (GTK_RADIO_BUTTON (off)), "on");
- gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (off), TRUE);
- box = ws_gtk_box_new(GTK_ORIENTATION_HORIZONTAL, 0, FALSE);
- gtk_box_pack_start (GTK_BOX (box), label, FALSE, FALSE, 10);
- gtk_box_pack_start (GTK_BOX (box), off, FALSE, FALSE, 10);
- gtk_box_pack_start (GTK_BOX (box), on, FALSE, FALSE, 0);
- vbox = ws_gtk_box_new(GTK_ORIENTATION_VERTICAL, 0, FALSE);
- gtk_box_pack_start (GTK_BOX (vbox), box, FALSE, FALSE, 15);
- /* frame = gtk_frame_new ("Cross:"); */
- frame = gtk_frame_new (NULL);
- gtk_container_add (GTK_CONTAINER (frame), vbox);
-
- g_signal_connect(on, "toggled", G_CALLBACK(callback_cross_on_off), g);
-
- g->cross.on_toggle = (GtkToggleButton * )on;
- g->cross.off_toggle = (GtkToggleButton * )off;
-
- return frame;
-}
-static void callback_cross_on_off (GtkWidget *toggle, gpointer data)
-{
- struct graph *g = (struct graph * )data;
-
- if (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON (toggle))) {
- int x, y;
- g->cross.draw = TRUE;
- get_mouse_position(g->drawing_area, &x, &y, 0);
- cross_draw (g, x, y);
- } else {
- g->cross.draw = FALSE;
- if (g->cross.erase_needed) {
- cross_erase (g);
- }
- }
-}
-
-static GtkWidget *control_panel_create_graph_type_group (struct graph *g)
-{
- GtkWidget *graph_tseqttrace, *graph_tseqstevens;
- GtkWidget *graph_tput, *graph_rtt, *graph_sep, *graph_init, *graph_box;
- GtkWidget *graph_frame;
- GtkWidget *graph_wscale;
-
- graph_tput = gtk_radio_button_new_with_label (NULL, "Throughput");
- graph_tseqttrace = gtk_radio_button_new_with_label (
- gtk_radio_button_get_group (GTK_RADIO_BUTTON (graph_tput)),
- "Time/Sequence (tcptrace-style)");
- graph_tseqstevens = gtk_radio_button_new_with_label (
- gtk_radio_button_get_group (GTK_RADIO_BUTTON (graph_tput)),
- "Time/Sequence (Stevens'-style)");
- graph_rtt = gtk_radio_button_new_with_label (
- gtk_radio_button_get_group (GTK_RADIO_BUTTON (graph_tput)),
- "Round-trip Time");
- graph_wscale = gtk_radio_button_new_with_label (
- gtk_radio_button_get_group (GTK_RADIO_BUTTON (graph_tput)),
- "Window Scaling");
-
- switch (g->type) {
- case GRAPH_TSEQ_STEVENS:
- gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(graph_tseqstevens),TRUE);
- break;
- case GRAPH_TSEQ_TCPTRACE:
- gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON(graph_tseqttrace),TRUE);
- break;
- case GRAPH_THROUGHPUT:
- gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON(graph_tput), TRUE);
- break;
- case GRAPH_RTT:
- gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON(graph_rtt), TRUE);
- break;
- case GRAPH_WSCALE:
- gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON(graph_wscale), TRUE);
- break;
- }
- graph_init = gtk_check_button_new_with_label ("Init on change");
- graph_sep = gtk_separator_new (GTK_ORIENTATION_HORIZONTAL);
- graph_box = ws_gtk_box_new(GTK_ORIENTATION_VERTICAL, 0, FALSE);
- gtk_box_pack_start (GTK_BOX (graph_box), graph_rtt, TRUE, TRUE, 0);
- gtk_box_pack_start (GTK_BOX (graph_box), graph_tput, TRUE, TRUE, 0);
- gtk_box_pack_start (GTK_BOX (graph_box), graph_tseqstevens, TRUE, TRUE, 0);
- gtk_box_pack_start (GTK_BOX (graph_box), graph_tseqttrace, TRUE, TRUE, 0);
- gtk_box_pack_start (GTK_BOX (graph_box), graph_wscale, TRUE, TRUE, 0);
- gtk_box_pack_start (GTK_BOX (graph_box), graph_sep, TRUE, TRUE, 0);
- gtk_box_pack_start (GTK_BOX (graph_box), graph_init, TRUE, TRUE, 0);
- graph_frame = gtk_frame_new ("Graph type:");
- gtk_container_add (GTK_CONTAINER (graph_frame), graph_box);
-
- g_object_set_data(G_OBJECT(graph_tseqstevens), "new-graph-type",
- GINT_TO_POINTER(GRAPH_TSEQ_STEVENS));
- g_object_set_data(G_OBJECT(graph_tseqttrace), "new-graph-type",
- GINT_TO_POINTER(GRAPH_TSEQ_TCPTRACE));
- g_object_set_data(G_OBJECT(graph_tput), "new-graph-type",
- GINT_TO_POINTER(GRAPH_THROUGHPUT));
- g_object_set_data(G_OBJECT(graph_rtt), "new-graph-type",
- GINT_TO_POINTER(GRAPH_RTT));
- g_object_set_data(G_OBJECT(graph_wscale), "new-graph-type",
- GINT_TO_POINTER(GRAPH_WSCALE));
-
- g->gt.graph_wscale = (GtkToggleButton *)graph_wscale;
- g->gt.graph_rtt = (GtkToggleButton * )graph_rtt;
- g->gt.graph_tput = (GtkToggleButton * )graph_tput;
- g->gt.graph_tseqstevens = (GtkToggleButton * )graph_tseqstevens;
- g->gt.graph_tseqttrace = (GtkToggleButton * )graph_tseqttrace;
-
- g_signal_connect(graph_tseqttrace, "toggled", G_CALLBACK(callback_graph_type), g);
- g_signal_connect(graph_tseqstevens, "toggled", G_CALLBACK(callback_graph_type), g);
- g_signal_connect(graph_tput, "toggled", G_CALLBACK(callback_graph_type), g);
- g_signal_connect(graph_rtt, "toggled", G_CALLBACK(callback_graph_type), g);
- g_signal_connect(graph_wscale, "toggled", G_CALLBACK(callback_graph_type), g);
- g_signal_connect(graph_init, "toggled", G_CALLBACK(callback_graph_init_on_typechg), g);
-
- return graph_frame;
-}
-
-static void callback_graph_type (GtkWidget *toggle, gpointer data)
-{
- int old_type, new_type;
- struct graph *g = (struct graph * )data;
-
- new_type = GPOINTER_TO_INT(g_object_get_data(G_OBJECT(toggle),"new-graph-type"));
-
- if (!gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON (toggle)))
- return;
-
- old_type = g->type;
- g->type = new_type;
-
- graph_element_lists_free (g);
- graph_element_lists_initialize (g);
-
- if (old_type == GRAPH_THROUGHPUT || new_type == GRAPH_THROUGHPUT) {
- /* throughput graph uses differently constructed segment list so we
- * need to recreate it */
- graph_segment_list_free (g);
- graph_segment_list_get (g, TRUE);
- }
-
- if (g->flags & GRAPH_INIT_ON_TYPE_CHANGE) {
- g->geom.width = g->wp.width;
- g->geom.height = g->wp.height;
- g->geom.x = g->wp.x;
- g->geom.y = g->wp.y;
- }
- g->x_axis->min = g->y_axis->min = 0;
- gtk_toggle_button_set_active (g->gui.time_orig_conn, TRUE);
- gtk_toggle_button_set_active (g->gui.seq_orig_isn, TRUE);
- graph_init_sequence (g);
-}
-
-static void callback_graph_init_on_typechg (GtkWidget *toggle _U_, gpointer data)
-{
- ((struct graph * )data)->flags ^= GRAPH_INIT_ON_TYPE_CHANGE;
-}
-
-static struct graph *graph_new (void)
-{
- struct graph *g;
-
- g = (struct graph * )g_malloc0 (sizeof (struct graph));
- graph_element_lists_initialize (g);
-
- g->x_axis = (struct axis * )g_malloc0 (sizeof (struct axis));
- g->y_axis = (struct axis * )g_malloc0 (sizeof (struct axis));
- g->x_axis->g = g;
- g->x_axis->flags = 0;
- g->x_axis->flags |= AXIS_ORIENTATION;
- g->x_axis->s.x = g->x_axis->s.y = 0;
- g->x_axis->s.height = HAXIS_INIT_HEIGHT;
- g->x_axis->p.x = VAXIS_INIT_WIDTH;
- g->x_axis->p.height = HAXIS_INIT_HEIGHT;
- g->y_axis->g = g;
- g->y_axis->flags = 0;
- g->y_axis->flags &= ~AXIS_ORIENTATION;
- g->y_axis->p.x = g->y_axis->p.y = 0;
- g->y_axis->p.width = VAXIS_INIT_WIDTH;
- g->y_axis->s.x = 0;
- g->y_axis->s.y = TITLEBAR_HEIGHT;
- g->y_axis->s.width = VAXIS_INIT_WIDTH;
-
- return g;
-}
-
-static void graph_initialize_values (struct graph *g)
-{
- g->geom.width = g->wp.width = 750;
- g->geom.height = g->wp.height = 550;
- g->geom.x = g->wp.x = VAXIS_INIT_WIDTH;
- g->geom.y = g->wp.y = TITLEBAR_HEIGHT;
- g->flags = 0;
- /* g->zoom.x = g->zoom.y = 1.0; */
- g->zoom.step_x = g->zoom.step_y = 1.2;
- g->zoom.flags = 0;
- g->cross.draw = g->cross.erase_needed = FALSE;
- g->zoomrect_erase_needed = FALSE;
- g->grab.grabbed = 0;
- g->magnify.active = 0;
- g->magnify.offset.x = g->magnify.offset.y = 0;
- g->magnify.width = g->magnify.height = 250;
- g->magnify.zoom.x = g->magnify.zoom.y = 10.0;
- g->magnify.flags = 0;
-}
-
-static void graph_init_sequence (struct graph *g)
-{
- debug(DBS_FENTRY) puts ("graph_init_sequence()");
-
- graph_type_dependent_initialize (g);
- g->zoom.initial.x = g->zoom.x;
- g->zoom.initial.y = g->zoom.y;
- graph_element_lists_make (g);
- g->x_axis->s.width = g->wp.width;
- g->x_axis->p.width = g->x_axis->s.width + RMARGIN_WIDTH;
- g->x_axis->p.y = TITLEBAR_HEIGHT + g->wp.height;
- g->x_axis->s.height = g->x_axis->p.height = HAXIS_INIT_HEIGHT;
- g->y_axis->s.height = g->wp.height;
- g->y_axis->p.height = g->wp.height + TITLEBAR_HEIGHT;
- graph_pixmaps_create (g);
- axis_pixmaps_create (g->y_axis);
- axis_pixmaps_create (g->x_axis);
- graph_title_pixmap_create (g);
- graph_title_pixmap_draw (g);
- graph_title_pixmap_display (g);
- graph_display (g);
- axis_display (g->y_axis);
- axis_display (g->x_axis);
-}
-
-static void graph_type_dependent_initialize (struct graph *g)
-{
- switch (g->type) {
- case GRAPH_TSEQ_STEVENS:
- case GRAPH_TSEQ_TCPTRACE:
- tseq_initialize (g);
- break;
- case GRAPH_THROUGHPUT:
- tput_initialize (g);
- break;
- case GRAPH_RTT:
- rtt_initialize (g);
- break;
- case GRAPH_WSCALE:
- wscale_initialize (g);
- break;
- default:
- break;
- }
-}
-
-static void graph_destroy (struct graph *g)
-{
- debug(DBS_FENTRY) puts ("graph_destroy()");
-
- axis_destroy (g->x_axis);
- axis_destroy (g->y_axis);
- /* window_destroy (g->drawing_area); */
- window_destroy (g->gui.control_panel);
- window_destroy (g->toplevel);
- /* window_destroy (g->text); */
+ zoom_lock_none = gtk_radio_button_new_with_label(NULL, "none");
+ zoom_lock_h = gtk_radio_button_new_with_label(
+ gtk_radio_button_get_group(GTK_RADIO_BUTTON(zoom_lock_none)),
+ "horizontal");
+ zoom_lock_v = gtk_radio_button_new_with_label(
+ gtk_radio_button_get_group(GTK_RADIO_BUTTON(zoom_lock_none)),
+ "vertical");
+ gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(zoom_lock_none), TRUE);
+ zoom_lock_box = ws_gtk_box_new(GTK_ORIENTATION_HORIZONTAL, 0, FALSE);
+ gtk_box_pack_start(GTK_BOX(zoom_lock_box), zoom_lock_none, TRUE, TRUE, 0);
+ gtk_box_pack_start(GTK_BOX(zoom_lock_box), zoom_lock_h, TRUE, TRUE, 0);
+ gtk_box_pack_start(GTK_BOX(zoom_lock_box), zoom_lock_v, TRUE, TRUE, 0);
+ zoom_lock_frame = gtk_frame_new("Zoom lock:");
+ gtk_container_add(GTK_CONTAINER(zoom_lock_frame), zoom_lock_box);
+
+ g_signal_connect(zoom_lock_h, "toggled", G_CALLBACK(callback_zoomlock_h), g);
+ g_signal_connect(zoom_lock_v, "toggled", G_CALLBACK(callback_zoomlock_v), g);
+
+ return zoom_lock_frame;
+}
+
+static void callback_zoomlock_h(GtkWidget *toggle, gpointer data)
+{
+ struct graph *g = (struct graph * )data;
+
+ if (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(toggle)))
+ g->zoom.flags |= ZOOM_HLOCK;
+ else
+ g->zoom.flags &= ~ZOOM_HLOCK;
+}
+
+static void callback_zoomlock_v(GtkWidget *toggle, gpointer data)
+{
+ struct graph *g = (struct graph * )data;
+
+ if (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(toggle)))
+ g->zoom.flags |= ZOOM_VLOCK;
+ else
+ g->zoom.flags &= ~ZOOM_VLOCK;
+}
+
+static GtkWidget *control_panel_create_cross_group(struct graph *g)
+{
+ GtkWidget *on, *off, *box, *frame, *vbox, *label;
+
+ label = gtk_label_new("Crosshairs:");
+ off = gtk_radio_button_new_with_label(NULL, "off");
+ on = gtk_radio_button_new_with_label(
+ gtk_radio_button_get_group(GTK_RADIO_BUTTON(off)), "on");
+ gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(off), TRUE);
+ box = ws_gtk_box_new(GTK_ORIENTATION_HORIZONTAL, 0, FALSE);
+ gtk_box_pack_start(GTK_BOX(box), label, FALSE, FALSE, 10);
+ gtk_box_pack_start(GTK_BOX(box), off, FALSE, FALSE, 10);
+ gtk_box_pack_start(GTK_BOX(box), on, FALSE, FALSE, 0);
+ vbox = ws_gtk_box_new(GTK_ORIENTATION_VERTICAL, 0, FALSE);
+ gtk_box_pack_start(GTK_BOX(vbox), box, FALSE, FALSE, 15);
+ /* frame = gtk_frame_new("Cross:"); */
+ frame = gtk_frame_new(NULL);
+ gtk_container_add(GTK_CONTAINER(frame), vbox);
+
+ g_signal_connect(on, "toggled", G_CALLBACK(callback_cross_on_off), g);
+
+ g->cross.on_toggle = (GtkToggleButton * )on;
+ g->cross.off_toggle = (GtkToggleButton * )off;
+
+ return frame;
+}
+static void callback_cross_on_off(GtkWidget *toggle, gpointer data)
+{
+ struct graph *g = (struct graph * )data;
+
+ if (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(toggle))) {
+ int x, y;
+ g->cross.draw = TRUE;
+ get_mouse_position(g->drawing_area, &x, &y, 0);
+ cross_draw(g, x, y);
+ } else {
+ g->cross.draw = FALSE;
+ if (g->cross.erase_needed) {
+ cross_erase(g);
+ }
+ }
+}
+
+static GtkWidget *control_panel_create_graph_type_group(struct graph *g)
+{
+ GtkWidget *graph_tseqttrace, *graph_tseqstevens;
+ GtkWidget *graph_tput, *graph_rtt, *graph_sep, *graph_init, *graph_box;
+ GtkWidget *graph_frame;
+ GtkWidget *graph_wscale;
+
+ graph_tput = gtk_radio_button_new_with_label(NULL, "Throughput");
+ graph_tseqttrace = gtk_radio_button_new_with_label(
+ gtk_radio_button_get_group(GTK_RADIO_BUTTON(graph_tput)),
+ "Time/Sequence (tcptrace-style)");
+ graph_tseqstevens = gtk_radio_button_new_with_label(
+ gtk_radio_button_get_group(GTK_RADIO_BUTTON(graph_tput)),
+ "Time/Sequence (Stevens'-style)");
+ graph_rtt = gtk_radio_button_new_with_label(
+ gtk_radio_button_get_group(GTK_RADIO_BUTTON(graph_tput)),
+ "Round-trip Time");
+ graph_wscale = gtk_radio_button_new_with_label(
+ gtk_radio_button_get_group(GTK_RADIO_BUTTON(graph_tput)),
+ "Window Scaling");
+
+ switch (g->type) {
+ case GRAPH_TSEQ_STEVENS:
+ gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(graph_tseqstevens), TRUE);
+ break;
+ case GRAPH_TSEQ_TCPTRACE:
+ gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(graph_tseqttrace), TRUE);
+ break;
+ case GRAPH_THROUGHPUT:
+ gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(graph_tput), TRUE);
+ break;
+ case GRAPH_RTT:
+ gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(graph_rtt), TRUE);
+ break;
+ case GRAPH_WSCALE:
+ gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(graph_wscale), TRUE);
+ break;
+ }
+ graph_init = gtk_check_button_new_with_label("Init on change");
+ graph_sep = gtk_separator_new(GTK_ORIENTATION_HORIZONTAL);
+ graph_box = ws_gtk_box_new(GTK_ORIENTATION_VERTICAL, 0, FALSE);
+ gtk_box_pack_start(GTK_BOX(graph_box), graph_rtt, TRUE, TRUE, 0);
+ gtk_box_pack_start(GTK_BOX(graph_box), graph_tput, TRUE, TRUE, 0);
+ gtk_box_pack_start(GTK_BOX(graph_box), graph_tseqstevens, TRUE, TRUE, 0);
+ gtk_box_pack_start(GTK_BOX(graph_box), graph_tseqttrace, TRUE, TRUE, 0);
+ gtk_box_pack_start(GTK_BOX(graph_box), graph_wscale, TRUE, TRUE, 0);
+ gtk_box_pack_start(GTK_BOX(graph_box), graph_sep, TRUE, TRUE, 0);
+ gtk_box_pack_start(GTK_BOX(graph_box), graph_init, TRUE, TRUE, 0);
+ graph_frame = gtk_frame_new("Graph type:");
+ gtk_container_add(GTK_CONTAINER(graph_frame), graph_box);
+
+ g_object_set_data(G_OBJECT(graph_tseqstevens), "new-graph-type",
+ GINT_TO_POINTER(GRAPH_TSEQ_STEVENS));
+ g_object_set_data(G_OBJECT(graph_tseqttrace), "new-graph-type",
+ GINT_TO_POINTER(GRAPH_TSEQ_TCPTRACE));
+ g_object_set_data(G_OBJECT(graph_tput), "new-graph-type",
+ GINT_TO_POINTER(GRAPH_THROUGHPUT));
+ g_object_set_data(G_OBJECT(graph_rtt), "new-graph-type",
+ GINT_TO_POINTER(GRAPH_RTT));
+ g_object_set_data(G_OBJECT(graph_wscale), "new-graph-type",
+ GINT_TO_POINTER(GRAPH_WSCALE));
+
+ g->gt.graph_wscale = (GtkToggleButton * )graph_wscale;
+ g->gt.graph_rtt = (GtkToggleButton * )graph_rtt;
+ g->gt.graph_tput = (GtkToggleButton * )graph_tput;
+ g->gt.graph_tseqstevens = (GtkToggleButton * )graph_tseqstevens;
+ g->gt.graph_tseqttrace = (GtkToggleButton * )graph_tseqttrace;
+
+ g_signal_connect(graph_tseqttrace, "toggled", G_CALLBACK(callback_graph_type), g);
+ g_signal_connect(graph_tseqstevens, "toggled", G_CALLBACK(callback_graph_type), g);
+ g_signal_connect(graph_tput, "toggled", G_CALLBACK(callback_graph_type), g);
+ g_signal_connect(graph_rtt, "toggled", G_CALLBACK(callback_graph_type), g);
+ g_signal_connect(graph_wscale, "toggled", G_CALLBACK(callback_graph_type), g);
+ g_signal_connect(graph_init, "toggled", G_CALLBACK(callback_graph_init_on_typechg), g);
+
+ return graph_frame;
+}
+
+static void callback_graph_type(GtkWidget *toggle, gpointer data)
+{
+ int old_type, new_type;
+ struct graph *g = (struct graph * )data;
+
+ new_type = GPOINTER_TO_INT(g_object_get_data(G_OBJECT(toggle), "new-graph-type"));
+
+ if (!gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(toggle)))
+ return;
+
+ old_type = g->type;
+ g->type = new_type;
+
+ graph_element_lists_free(g);
+ graph_element_lists_initialize(g);
+
+ if ((old_type == GRAPH_THROUGHPUT) || (new_type == GRAPH_THROUGHPUT)) {
+ /* throughput graph uses differently constructed segment list so we
+ * need to recreate it */
+ graph_segment_list_free(g);
+ graph_segment_list_get(g, TRUE);
+ }
+
+ if (g->flags & GRAPH_INIT_ON_TYPE_CHANGE) {
+ g->geom.width = g->wp.width;
+ g->geom.height = g->wp.height;
+ g->geom.x = g->wp.x;
+ g->geom.y = g->wp.y;
+ }
+ g->x_axis->min = g->y_axis->min = 0;
+ gtk_toggle_button_set_active(g->gui.time_orig_conn, TRUE);
+ gtk_toggle_button_set_active(g->gui.seq_orig_isn, TRUE);
+ graph_init_sequence(g);
+}
+
+static void callback_graph_init_on_typechg(GtkWidget *toggle _U_, gpointer data)
+{
+ ((struct graph * )data)->flags ^= GRAPH_INIT_ON_TYPE_CHANGE;
+}
+
+static struct graph *graph_new(void)
+{
+ struct graph *g;
+
+ g = (struct graph * )g_malloc0(sizeof(struct graph));
+ graph_element_lists_initialize(g);
+
+ g->x_axis = (struct axis * )g_malloc0(sizeof(struct axis));
+ g->y_axis = (struct axis * )g_malloc0(sizeof(struct axis));
+ g->x_axis->g = g;
+ g->x_axis->flags = 0;
+ g->x_axis->flags |= AXIS_ORIENTATION;
+ g->x_axis->s.x = g->x_axis->s.y = 0;
+ g->x_axis->s.height = HAXIS_INIT_HEIGHT;
+ g->x_axis->p.x = VAXIS_INIT_WIDTH;
+ g->x_axis->p.height = HAXIS_INIT_HEIGHT;
+ g->y_axis->g = g;
+ g->y_axis->flags = 0;
+ g->y_axis->flags &= ~AXIS_ORIENTATION;
+ g->y_axis->p.x = g->y_axis->p.y = 0;
+ g->y_axis->p.width = VAXIS_INIT_WIDTH;
+ g->y_axis->s.x = 0;
+ g->y_axis->s.y = TITLEBAR_HEIGHT;
+ g->y_axis->s.width = VAXIS_INIT_WIDTH;
+
+ return g;
+}
+
+static void graph_initialize_values(struct graph *g)
+{
+ g->geom.width = g->wp.width = 750;
+ g->geom.height = g->wp.height = 550;
+ g->geom.x = g->wp.x = VAXIS_INIT_WIDTH;
+ g->geom.y = g->wp.y = TITLEBAR_HEIGHT;
+ g->flags = 0;
+ /* g->zoom.x = g->zoom.y = 1.0; */
+ g->zoom.step_x = g->zoom.step_y = 1.2;
+ g->zoom.flags = 0;
+ g->cross.draw = g->cross.erase_needed = FALSE;
+ g->zoomrect_erase_needed = FALSE;
+ g->grab.grabbed = 0;
+ g->magnify.active = 0;
+ g->magnify.offset.x = g->magnify.offset.y = 0;
+ g->magnify.width = g->magnify.height = 250;
+ g->magnify.zoom.x = g->magnify.zoom.y = 10.0;
+ g->magnify.flags = 0;
+}
+
+static void graph_init_sequence(struct graph *g)
+{
+ debug(DBS_FENTRY) puts("graph_init_sequence()");
+
+ graph_type_dependent_initialize(g);
+ g->zoom.initial.x = g->zoom.x;
+ g->zoom.initial.y = g->zoom.y;
+ graph_element_lists_make(g);
+ g->x_axis->s.width = g->wp.width;
+ g->x_axis->p.width = g->x_axis->s.width + RMARGIN_WIDTH;
+ g->x_axis->p.y = TITLEBAR_HEIGHT + g->wp.height;
+ g->x_axis->s.height = g->x_axis->p.height = HAXIS_INIT_HEIGHT;
+ g->y_axis->s.height = g->wp.height;
+ g->y_axis->p.height = g->wp.height + TITLEBAR_HEIGHT;
+ graph_pixmaps_create(g);
+ axis_pixmaps_create(g->y_axis);
+ axis_pixmaps_create(g->x_axis);
+ graph_title_pixmap_create(g);
+ graph_title_pixmap_draw(g);
+ graph_title_pixmap_display(g);
+ graph_display(g);
+ axis_display(g->y_axis);
+ axis_display(g->x_axis);
+}
+
+static void graph_type_dependent_initialize(struct graph *g)
+{
+ switch (g->type) {
+ case GRAPH_TSEQ_STEVENS:
+ case GRAPH_TSEQ_TCPTRACE:
+ tseq_initialize(g);
+ break;
+ case GRAPH_THROUGHPUT:
+ tput_initialize(g);
+ break;
+ case GRAPH_RTT:
+ rtt_initialize(g);
+ break;
+ case GRAPH_WSCALE:
+ wscale_initialize(g);
+ break;
+ default:
+ break;
+ }
+}
+
+static void graph_destroy(struct graph *g)
+{
+ debug(DBS_FENTRY) puts("graph_destroy()");
+
+ axis_destroy(g->x_axis);
+ axis_destroy(g->y_axis);
+ /* window_destroy(g->drawing_area); */
+ window_destroy(g->gui.control_panel);
+ window_destroy(g->toplevel);
+ /* window_destroy(g->text); */
#if GTK_CHECK_VERSION(2,22,0)
- if(g->title_surface){
- cairo_surface_destroy (g->title_surface);
- }
- if(g->surface[0]){
- cairo_surface_destroy (g->surface[0]);
- }
- if(g->surface[1]){
- cairo_surface_destroy (g->surface[1]);
- }
+ if (g->title_surface) {
+ cairo_surface_destroy(g->title_surface);
+ }
+ if (g->surface[0]) {
+ cairo_surface_destroy(g->surface[0]);
+ }
+ if (g->surface[1]) {
+ cairo_surface_destroy(g->surface[1]);
+ }
#else
- g_object_unref (g->pixmap[0]);
- g_object_unref (g->pixmap[1]);
+ g_object_unref(g->pixmap[0]);
+ g_object_unref(g->pixmap[1]);
#endif /* GTK_CHECK_VERSION(2,22,0) */
- g_free (g->x_axis);
- g_free (g->y_axis);
- g_free ( (gpointer) (g->title) );
- graph_segment_list_free (g);
- graph_element_lists_free (g);
+ g_free(g->x_axis);
+ g_free(g->y_axis);
+ g_free((gpointer )(g->title));
+ graph_segment_list_free(g);
+ graph_element_lists_free(g);
- g_free (g);
+ g_free(g);
}
typedef struct _tcp_scan_t {
- struct segment *current;
- int direction;
- struct graph *g;
- struct segment *last;
+ struct segment *current;
+ int direction;
+ struct graph *g;
+ struct segment *last;
} tcp_scan_t;
static int
tapall_tcpip_packet(void *pct, packet_info *pinfo, epan_dissect_t *edt _U_, const void *vip)
{
- tcp_scan_t *ts=(tcp_scan_t *)pct;
- struct graph *g = ts->g;
- const struct tcpheader *tcphdr = (const struct tcpheader *)vip;
-
- if (compare_headers(&g->src_address, &g->dst_address,
- g->src_port, g->dst_port,
- &tcphdr->ip_src, &tcphdr->ip_dst,
- tcphdr->th_sport, tcphdr->th_dport,
- ts->direction)) {
-
- struct segment *segment = g_malloc(sizeof (struct segment));
- segment->next = NULL;
- segment->num = pinfo->fd->num;
- segment->rel_secs = (guint32) pinfo->fd->rel_ts.secs;
- segment->rel_usecs = pinfo->fd->rel_ts.nsecs/1000;
- segment->abs_secs = (guint32) pinfo->fd->abs_ts.secs;
- segment->abs_usecs = pinfo->fd->abs_ts.nsecs/1000;
- segment->th_seq=tcphdr->th_seq;
- segment->th_ack=tcphdr->th_ack;
- segment->th_win=tcphdr->th_win;
- segment->th_flags=tcphdr->th_flags;
- segment->th_sport=tcphdr->th_sport;
- segment->th_dport=tcphdr->th_dport;
- segment->th_seglen=tcphdr->th_seglen;
- COPY_ADDRESS(&segment->ip_src, &tcphdr->ip_src);
- COPY_ADDRESS(&segment->ip_dst, &tcphdr->ip_dst);
-
- segment->num_sack_ranges = MIN(MAX_TCP_SACK_RANGES, tcphdr->num_sack_ranges);
- if (segment->num_sack_ranges > 0) {
- /* Copy entries in the order they happen */
- memcpy(&segment->sack_left_edge, &tcphdr->sack_left_edge, sizeof(segment->sack_left_edge));
- memcpy(&segment->sack_right_edge, &tcphdr->sack_right_edge, sizeof(segment->sack_right_edge));
- }
-
- if (ts->g->segments) {
- ts->last->next = segment;
- } else {
- ts->g->segments = segment;
- }
- ts->last = segment;
- }
-
- return 0;
+ tcp_scan_t *ts = (tcp_scan_t *)pct;
+ struct graph *g = ts->g;
+ const struct tcpheader *tcphdr = (const struct tcpheader *)vip;
+
+ if (compare_headers(&g->src_address, &g->dst_address,
+ g->src_port, g->dst_port,
+ &tcphdr->ip_src, &tcphdr->ip_dst,
+ tcphdr->th_sport, tcphdr->th_dport,
+ ts->direction))
+ {
+ struct segment *segment = g_malloc(sizeof(struct segment));
+ segment->next = NULL;
+ segment->num = pinfo->fd->num;
+ segment->rel_secs = (guint32)pinfo->fd->rel_ts.secs;
+ segment->rel_usecs = pinfo->fd->rel_ts.nsecs/1000;
+ segment->abs_secs = (guint32)pinfo->fd->abs_ts.secs;
+ segment->abs_usecs = pinfo->fd->abs_ts.nsecs/1000;
+ segment->th_seq = tcphdr->th_seq;
+ segment->th_ack = tcphdr->th_ack;
+ segment->th_win = tcphdr->th_win;
+ segment->th_flags = tcphdr->th_flags;
+ segment->th_sport = tcphdr->th_sport;
+ segment->th_dport = tcphdr->th_dport;
+ segment->th_seglen = tcphdr->th_seglen;
+ COPY_ADDRESS(&segment->ip_src, &tcphdr->ip_src);
+ COPY_ADDRESS(&segment->ip_dst, &tcphdr->ip_dst);
+
+ segment->num_sack_ranges = MIN(MAX_TCP_SACK_RANGES, tcphdr->num_sack_ranges);
+ if (segment->num_sack_ranges > 0) {
+ /* Copy entries in the order they happen */
+ memcpy(&segment->sack_left_edge, &tcphdr->sack_left_edge, sizeof(segment->sack_left_edge));
+ memcpy(&segment->sack_right_edge, &tcphdr->sack_right_edge, sizeof(segment->sack_right_edge));
+ }
+
+ if (ts->g->segments) {
+ ts->last->next = segment;
+ } else {
+ ts->g->segments = segment;
+ }
+ ts->last = segment;
+ }
+
+ return 0;
}
/* here we collect all the external data we will ever need */
-static void graph_segment_list_get (struct graph *g, gboolean stream_known)
-{
- struct segment current;
- GString *error_string;
- tcp_scan_t ts;
-
- debug(DBS_FENTRY) puts ("graph_segment_list_get()");
-
- if (!stream_known) {
- select_tcpip_session (&cfile, &current);
- if (g->type == GRAPH_THROUGHPUT)
- ts.direction = COMPARE_CURR_DIR;
- else
- ts.direction = COMPARE_ANY_DIR;
-
- /* Remember stream info in graph */
- COPY_ADDRESS(&g->src_address, &current.ip_src);
- g->src_port = current.th_sport;
- COPY_ADDRESS(&g->dst_address, &current.ip_dst);
- g->dst_port = current.th_dport;
- }
-
- /* rescan all the packets and pick up all interesting tcp headers.
- * we only filter for TCP here for speed and do the actual compare
- * in the tap listener
- */
- ts.current=&current;
- ts.g=g;
- ts.last=NULL;
- error_string=register_tap_listener("tcp", &ts, "tcp", 0, NULL, tapall_tcpip_packet, NULL);
- if(error_string){
- fprintf(stderr, "wireshark: Couldn't register tcp_graph tap: %s\n",
- error_string->str);
- g_string_free(error_string, TRUE);
- exit(1);
- }
- cf_retap_packets(&cfile);
- remove_tap_listener(&ts);
+static void graph_segment_list_get(struct graph *g, gboolean stream_known)
+{
+ struct segment current;
+ GString *error_string;
+ tcp_scan_t ts;
+
+ debug(DBS_FENTRY) puts("graph_segment_list_get()");
+
+ if (!stream_known) {
+ select_tcpip_session(&cfile, &current);
+ if (g->type == GRAPH_THROUGHPUT)
+ ts.direction = COMPARE_CURR_DIR;
+ else
+ ts.direction = COMPARE_ANY_DIR;
+
+ /* Remember stream info in graph */
+ COPY_ADDRESS(&g->src_address, &current.ip_src);
+ g->src_port = current.th_sport;
+ COPY_ADDRESS(&g->dst_address, &current.ip_dst);
+ g->dst_port = current.th_dport;
+ }
+
+ /* rescan all the packets and pick up all interesting tcp headers.
+ * we only filter for TCP here for speed and do the actual compare
+ * in the tap listener
+ */
+ ts.current = &current;
+ ts.g = g;
+ ts.last = NULL;
+ error_string = register_tap_listener("tcp", &ts, "tcp", 0, NULL, tapall_tcpip_packet, NULL);
+ if (error_string) {
+ fprintf(stderr, "wireshark: Couldn't register tcp_graph tap: %s\n",
+ error_string->str);
+ g_string_free(error_string, TRUE);
+ exit(1); /* XXX: fix this */
+ }
+ cf_retap_packets(&cfile);
+ remove_tap_listener(&ts);
}
typedef struct _th_t {
- int num_hdrs;
- #define MAX_SUPPORTED_TCP_HEADERS 8
- struct tcpheader *tcphdrs[MAX_SUPPORTED_TCP_HEADERS];
+ int num_hdrs;
+ #define MAX_SUPPORTED_TCP_HEADERS 8
+ struct tcpheader *tcphdrs[MAX_SUPPORTED_TCP_HEADERS];
} th_t;
static int
tap_tcpip_packet(void *pct, packet_info *pinfo _U_, epan_dissect_t *edt _U_, const void *vip)
{
- int n;
- gboolean is_unique = TRUE;
- th_t *th=pct;
- const struct tcpheader *header = (const struct tcpheader *)vip;
+ int n;
+ gboolean is_unique = TRUE;
+ th_t *th = pct;
+ const struct tcpheader *header = (const struct tcpheader *)vip;
- /* Check new header details against any/all stored ones */
- for (n=0; n < th->num_hdrs; n++) {
- struct tcpheader *stored = th->tcphdrs[n];
+ /* Check new header details against any/all stored ones */
+ for (n=0; n < th->num_hdrs; n++) {
+ struct tcpheader *stored = th->tcphdrs[n];
- if (compare_headers(&stored->ip_src, &stored->ip_dst,
- stored->th_sport, stored->th_dport,
- &header->ip_src, &header->ip_dst,
- header->th_sport, stored->th_dport,
- COMPARE_CURR_DIR)) {
- is_unique = FALSE;
- break;
- }
- }
+ if (compare_headers(&stored->ip_src, &stored->ip_dst,
+ stored->th_sport, stored->th_dport,
+ &header->ip_src, &header->ip_dst,
+ header->th_sport, stored->th_dport,
+ COMPARE_CURR_DIR))
+ {
+ is_unique = FALSE;
+ break;
+ }
+ }
- /* Add address if unique and have space for it */
- if (is_unique && (th->num_hdrs < MAX_SUPPORTED_TCP_HEADERS)) {
- /* Need to take a deep copy of the tap struct, it may not be valid
- to read after this function returns? */
- th->tcphdrs[th->num_hdrs] = g_malloc(sizeof(struct tcpheader));
- *(th->tcphdrs[th->num_hdrs]) = *header;
- COPY_ADDRESS(&th->tcphdrs[th->num_hdrs]->ip_src, &header->ip_src);
- COPY_ADDRESS(&th->tcphdrs[th->num_hdrs]->ip_dst, &header->ip_dst);
+ /* Add address if unique and have space for it */
+ if (is_unique && (th->num_hdrs < MAX_SUPPORTED_TCP_HEADERS)) {
+ /* Need to take a deep copy of the tap struct, it may not be valid
+ to read after this function returns? */
+ th->tcphdrs[th->num_hdrs] = g_malloc(sizeof(struct tcpheader));
+ *(th->tcphdrs[th->num_hdrs]) = *header;
+ COPY_ADDRESS(&th->tcphdrs[th->num_hdrs]->ip_src, &header->ip_src);
+ COPY_ADDRESS(&th->tcphdrs[th->num_hdrs]->ip_dst, &header->ip_dst);
- th->num_hdrs++;
- }
+ th->num_hdrs++;
+ }
- return 0;
+ return 0;
}
@@ -1975,1313 +1984,1310 @@ tap_tcpip_packet(void *pct, packet_info *pinfo _U_, epan_dissect_t *edt _U_, con
* then present the user with a dialog where the user can select WHICH tcp
* session to graph.
*/
-static struct tcpheader *select_tcpip_session (capture_file *cf, struct segment *hdrs)
-{
- frame_data *fdata;
- epan_dissect_t edt;
- dfilter_t *sfcode;
- GString *error_string;
- th_t th = {0, {NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL}};
-
- fdata = cf->current_frame;
-
- /* no real filter yet */
- if (!dfilter_compile("tcp", &sfcode)) {
- simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK, "%s", dfilter_error_msg);
- return NULL;
- }
-
- /* dissect the current frame */
- if (!cf_read_frame(cf, fdata))
- return NULL; /* error reading the frame */
-
-
- error_string=register_tap_listener("tcp", &th, NULL, 0, NULL, tap_tcpip_packet, NULL);
- if(error_string){
- fprintf(stderr, "wireshark: Couldn't register tcp_graph tap: %s\n",
- error_string->str);
- g_string_free(error_string, TRUE);
- exit(1);
- }
-
- epan_dissect_init(&edt, TRUE, FALSE);
- epan_dissect_prime_dfilter(&edt, sfcode);
- epan_dissect_run_with_taps(&edt, &cf->phdr, cf->pd, fdata, NULL);
- epan_dissect_cleanup(&edt);
- remove_tap_listener(&th);
-
- if(th.num_hdrs==0){
- /* This "shouldn't happen", as our menu items shouldn't
- * even be enabled if the selected packet isn't a TCP
- * segment, as tcp_graph_selected_packet_enabled() is used
- * to determine whether to enable any of our menu items. */
- simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK,
- "Selected packet isn't a TCP segment");
- return NULL;
- }
- /* XXX fix this later, we should show a dialog allowing the user
- to select which session he wants here
- */
- if(th.num_hdrs>1){
- /* can only handle a single tcp layer yet */
- simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK,
- "The selected packet has more than one TCP unique conversation "
- "in it.");
- return NULL;
- }
-
- /* For now, still always choose the first/only one */
- hdrs->num = fdata->num;
- hdrs->rel_secs = (guint32) fdata->rel_ts.secs;
- hdrs->rel_usecs = fdata->rel_ts.nsecs/1000;
- hdrs->abs_secs = (guint32) fdata->abs_ts.secs;
- hdrs->abs_usecs = fdata->abs_ts.nsecs/1000;
- hdrs->th_seq=th.tcphdrs[0]->th_seq;
- hdrs->th_ack=th.tcphdrs[0]->th_ack;
- hdrs->th_win=th.tcphdrs[0]->th_win;
- hdrs->th_flags=th.tcphdrs[0]->th_flags;
- hdrs->th_sport=th.tcphdrs[0]->th_sport;
- hdrs->th_dport=th.tcphdrs[0]->th_dport;
- hdrs->th_seglen=th.tcphdrs[0]->th_seglen;
- COPY_ADDRESS(&hdrs->ip_src, &th.tcphdrs[0]->ip_src);
- COPY_ADDRESS(&hdrs->ip_dst, &th.tcphdrs[0]->ip_dst);
- return th.tcphdrs[0];
-
-}
-
-static int compare_headers (address *saddr1, address *daddr1, guint16 sport1, guint16 dport1, const address *saddr2, const address *daddr2, guint16 sport2, guint16 dport2, int dir)
-{
- int dir1, dir2;
-
- dir1 = ((!(CMP_ADDRESS(saddr1, saddr2))) &&
- (!(CMP_ADDRESS(daddr1, daddr2))) &&
- (sport1==sport2) &&
- (dport1==dport2));
-
- if(dir==COMPARE_CURR_DIR){
- return dir1;
- } else {
- dir2 = ((!(CMP_ADDRESS(saddr1, daddr2))) &&
- (!(CMP_ADDRESS(daddr1, saddr2))) &&
- (sport1==dport2) &&
- (dport1==sport2));
- return dir1 || dir2;
- }
-}
-
-static void graph_segment_list_free (struct graph *g)
-{
- struct segment *segment;
-
- while (g->segments) {
- segment = g->segments->next;
- g_free (g->segments);
- g->segments = segment;
- }
- g->segments = NULL;
-}
-
-static void graph_element_lists_initialize (struct graph *g)
-{
- g->elists = (struct element_list *)g_malloc0 (sizeof (struct element_list));
-}
-
-static void graph_element_lists_make (struct graph *g)
-{
- debug(DBS_FENTRY) puts ("graph_element_lists_make()");
-
- switch (g->type) {
- case GRAPH_TSEQ_STEVENS:
- tseq_stevens_make_elmtlist (g);
- break;
- case GRAPH_TSEQ_TCPTRACE:
- tseq_tcptrace_make_elmtlist (g);
- break;
- case GRAPH_THROUGHPUT:
- tput_make_elmtlist (g);
- break;
- case GRAPH_RTT:
- rtt_make_elmtlist (g);
- break;
- case GRAPH_WSCALE:
- wscale_make_elmtlist (g);
- break;
- default:
- printf ("graph_element_lists_make: unknown graph type: %d\n", g->type);
- break;
- }
-}
-
-static void graph_element_lists_free (struct graph *g)
-{
- struct element_list *list, *next_list;
-
- for (list=g->elists; list; list=next_list) {
- g_free (list->elements);
- next_list = list->next;
- g_free (list);
- }
- g->elists = NULL; /* just to make debugging easier */
-}
+static struct tcpheader *select_tcpip_session(capture_file *cf, struct segment *hdrs)
+{
+ frame_data *fdata;
+ epan_dissect_t edt;
+ dfilter_t *sfcode;
+ GString *error_string;
+ th_t th = {0, {NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL}};
+
+ fdata = cf->current_frame;
+
+ /* no real filter yet */
+ if (!dfilter_compile("tcp", &sfcode)) {
+ simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK, "%s", dfilter_error_msg);
+ return NULL;
+ }
+
+ /* dissect the current frame */
+ if (!cf_read_frame(cf, fdata))
+ return NULL; /* error reading the frame */
+
+
+ error_string=register_tap_listener("tcp", &th, NULL, 0, NULL, tap_tcpip_packet, NULL);
+ if (error_string) {
+ fprintf(stderr, "wireshark: Couldn't register tcp_graph tap: %s\n",
+ error_string->str);
+ g_string_free(error_string, TRUE);
+ exit(1);
+ }
+
+ epan_dissect_init(&edt, TRUE, FALSE);
+ epan_dissect_prime_dfilter(&edt, sfcode);
+ epan_dissect_run_with_taps(&edt, &cf->phdr, cf->pd, fdata, NULL);
+ epan_dissect_cleanup(&edt);
+ remove_tap_listener(&th);
+
+ if (th.num_hdrs == 0) {
+ /* This "shouldn't happen", as our menu items shouldn't
+ * even be enabled if the selected packet isn't a TCP
+ * segment, as tcp_graph_selected_packet_enabled() is used
+ * to determine whether to enable any of our menu items. */
+ simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK,
+ "Selected packet isn't a TCP segment");
+ return NULL;
+ }
+ /* XXX fix this later, we should show a dialog allowing the user
+ to select which session he wants here
+ */
+ if (th.num_hdrs > 1) {
+ /* can only handle a single tcp layer yet */
+ simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK,
+ "The selected packet has more than one TCP unique conversation "
+ "in it.");
+ return NULL;
+ }
+
+ /* For now, still always choose the first/only one */
+ hdrs->num = fdata->num;
+ hdrs->rel_secs = (guint32) fdata->rel_ts.secs;
+ hdrs->rel_usecs = fdata->rel_ts.nsecs/1000;
+ hdrs->abs_secs = (guint32) fdata->abs_ts.secs;
+ hdrs->abs_usecs = fdata->abs_ts.nsecs/1000;
+ hdrs->th_seq = th.tcphdrs[0]->th_seq;
+ hdrs->th_ack = th.tcphdrs[0]->th_ack;
+ hdrs->th_win = th.tcphdrs[0]->th_win;
+ hdrs->th_flags = th.tcphdrs[0]->th_flags;
+ hdrs->th_sport = th.tcphdrs[0]->th_sport;
+ hdrs->th_dport = th.tcphdrs[0]->th_dport;
+ hdrs->th_seglen = th.tcphdrs[0]->th_seglen;
+ COPY_ADDRESS(&hdrs->ip_src, &th.tcphdrs[0]->ip_src);
+ COPY_ADDRESS(&hdrs->ip_dst, &th.tcphdrs[0]->ip_dst);
+ return th.tcphdrs[0];
+
+}
+
+static int compare_headers(address *saddr1, address *daddr1, guint16 sport1, guint16 dport1, const address *saddr2, const address *daddr2, guint16 sport2, guint16 dport2, int dir)
+{
+ int dir1, dir2;
+
+ dir1 = ((!(CMP_ADDRESS(saddr1, saddr2))) &&
+ (!(CMP_ADDRESS(daddr1, daddr2))) &&
+ (sport1==sport2) &&
+ (dport1==dport2));
+
+ if (dir == COMPARE_CURR_DIR) {
+ return dir1;
+ } else {
+ dir2 = ((!(CMP_ADDRESS(saddr1, daddr2))) &&
+ (!(CMP_ADDRESS(daddr1, saddr2))) &&
+ (sport1 == dport2) &&
+ (dport1 == sport2));
+ return dir1 || dir2;
+ }
+}
+
+static void graph_segment_list_free(struct graph *g)
+{
+ struct segment *segment;
+
+ while (g->segments) {
+ segment = g->segments->next;
+ g_free(g->segments);
+ g->segments = segment;
+ }
+ g->segments = NULL;
+}
+
+static void graph_element_lists_initialize(struct graph *g)
+{
+ g->elists = (struct element_list *)g_malloc0(sizeof(struct element_list));
+}
+
+static void graph_element_lists_make(struct graph *g)
+{
+ debug(DBS_FENTRY) puts("graph_element_lists_make()");
+
+ switch (g->type) {
+ case GRAPH_TSEQ_STEVENS:
+ tseq_stevens_make_elmtlist(g);
+ break;
+ case GRAPH_TSEQ_TCPTRACE:
+ tseq_tcptrace_make_elmtlist(g);
+ break;
+ case GRAPH_THROUGHPUT:
+ tput_make_elmtlist(g);
+ break;
+ case GRAPH_RTT:
+ rtt_make_elmtlist(g);
+ break;
+ case GRAPH_WSCALE:
+ wscale_make_elmtlist(g);
+ break;
+ default:
+ printf("graph_element_lists_make: unknown graph type: %d\n", g->type);
+ break;
+ }
+}
+
+static void graph_element_lists_free(struct graph *g)
+{
+ struct element_list *list, *next_list;
+
+ for (list=g->elists; list; list=next_list) {
+ g_free(list->elements);
+ next_list = list->next;
+ g_free(list);
+ }
+ g->elists = NULL; /* just to make debugging easier */
+}
-static void graph_title_pixmap_create (struct graph *g)
+static void graph_title_pixmap_create(struct graph *g)
{
#if GTK_CHECK_VERSION(2,22,0)
- if(g->title_surface){
- cairo_surface_destroy (g->title_surface);
- g->title_surface = NULL;
- }
+ if (g->title_surface) {
+ cairo_surface_destroy(g->title_surface);
+ g->title_surface = NULL;
+ }
- g->title_surface = gdk_window_create_similar_surface (gtk_widget_get_window(g->drawing_area),
- CAIRO_CONTENT_COLOR,
- g->x_axis->p.width,
- g->wp.y);
+ g->title_surface = gdk_window_create_similar_surface(gtk_widget_get_window(g->drawing_area),
+ CAIRO_CONTENT_COLOR,
+ g->x_axis->p.width,
+ g->wp.y);
#else
- if (g->title_pixmap)
- g_object_unref (g->title_pixmap);
+ if (g->title_pixmap)
+ g_object_unref(g->title_pixmap);
- g->title_pixmap = gdk_pixmap_new (gtk_widget_get_window(g->drawing_area),
- g->x_axis->p.width, g->wp.y, -1);
+ g->title_pixmap = gdk_pixmap_new(gtk_widget_get_window(g->drawing_area),
+ g->x_axis->p.width, g->wp.y, -1);
#endif
}
-static void graph_title_pixmap_draw (struct graph *g)
+static void graph_title_pixmap_draw(struct graph *g)
{
- int i;
- cairo_t *cr;
+ int i;
+ cairo_t *cr;
#if GTK_CHECK_VERSION(2,22,0)
- cr = cairo_create (g->title_surface);
+ cr = cairo_create(g->title_surface);
#else
- cr = gdk_cairo_create (g->title_pixmap);
+ cr = gdk_cairo_create(g->title_pixmap);
#endif
- cairo_set_source_rgb (cr, 1, 1, 1); /* set fill color */
- cairo_rectangle (cr, 0, 0, g->x_axis->p.width, g->wp.y);
- cairo_fill (cr);
- cairo_set_source_rgb (cr, 0, 0, 0); /* set text color */
+ cairo_set_source_rgb(cr, 1, 1, 1); /* set fill color */
+ cairo_rectangle(cr, 0, 0, g->x_axis->p.width, g->wp.y);
+ cairo_fill(cr);
+ cairo_set_source_rgb(cr, 0, 0, 0); /* set text color */
- for (i=0; g->title[i]; i++) {
- gint w, h;
- PangoLayout *layout;
- layout = gtk_widget_create_pango_layout(g->drawing_area,
- g->title[i]);
- pango_layout_get_pixel_size(layout, &w, &h);
- cairo_move_to (cr, g->wp.width/2 - w/2, 20 + i*(h+3));
- pango_cairo_show_layout (cr, layout);
- g_object_unref(G_OBJECT(layout));
- }
- cairo_destroy (cr);
+ for (i=0; g->title[i]; i++) {
+ gint w, h;
+ PangoLayout *layout;
+ layout = gtk_widget_create_pango_layout(g->drawing_area,
+ g->title[i]);
+ pango_layout_get_pixel_size(layout, &w, &h);
+ cairo_move_to(cr, g->wp.width/2 - w/2, 20 + i*(h+3));
+ pango_cairo_show_layout(cr, layout);
+ g_object_unref(G_OBJECT(layout));
+ }
+ cairo_destroy(cr);
}
-static void graph_title_pixmap_display (struct graph *g)
+static void graph_title_pixmap_display(struct graph *g)
{
- cairo_t *cr;
+ cairo_t *cr;
- cr = gdk_cairo_create (gtk_widget_get_window(g->drawing_area));
+ cr = gdk_cairo_create(gtk_widget_get_window(g->drawing_area));
#if GTK_CHECK_VERSION(2,22,0)
- cairo_set_source_surface (cr, g->title_surface, g->wp.x, 0);
+ cairo_set_source_surface(cr, g->title_surface, g->wp.x, 0);
#else
- gdk_cairo_set_source_pixmap (cr, g->title_pixmap, g->wp.x, 0);
+ gdk_cairo_set_source_pixmap(cr, g->title_pixmap, g->wp.x, 0);
#endif
- cairo_rectangle (cr, g->wp.x, 0, g->x_axis->p.width, g->wp.y);
- cairo_fill (cr);
- cairo_destroy (cr);
+ cairo_rectangle(cr, g->wp.x, 0, g->x_axis->p.width, g->wp.y);
+ cairo_fill(cr);
+ cairo_destroy(cr);
}
-static void graph_pixmaps_create (struct graph *g)
+static void graph_pixmaps_create(struct graph *g)
{
- debug(DBS_FENTRY) puts ("graph_pixmaps_create()");
+ debug(DBS_FENTRY) puts("graph_pixmaps_create()");
#if GTK_CHECK_VERSION(2,22,0)
- if(g->surface[0]){
- cairo_surface_destroy (g->surface[0]);
- g->surface[0] = NULL;
- }
-
- if(g->surface[1]){
- cairo_surface_destroy (g->surface[1]);
- g->surface[1] = NULL;
- }
-
- g->surface[0] = gdk_window_create_similar_surface (gtk_widget_get_window(g->drawing_area),
- CAIRO_CONTENT_COLOR,
- g->wp.width,
- g->wp.height);
-
- g->surface[1] = gdk_window_create_similar_surface (gtk_widget_get_window(g->drawing_area),
- CAIRO_CONTENT_COLOR,
- g->wp.width,
- g->wp.height);
-
- g->displayed = 0;
+ if (g->surface[0]) {
+ cairo_surface_destroy(g->surface[0]);
+ g->surface[0] = NULL;
+ }
+
+ if (g->surface[1]) {
+ cairo_surface_destroy(g->surface[1]);
+ g->surface[1] = NULL;
+ }
+
+ g->surface[0] = gdk_window_create_similar_surface(gtk_widget_get_window(g->drawing_area),
+ CAIRO_CONTENT_COLOR,
+ g->wp.width,
+ g->wp.height);
+
+ g->surface[1] = gdk_window_create_similar_surface(gtk_widget_get_window(g->drawing_area),
+ CAIRO_CONTENT_COLOR,
+ g->wp.width,
+ g->wp.height);
+
+ g->displayed = 0;
#else
- if (g->pixmap[0])
- g_object_unref (g->pixmap[0]);
- if (g->pixmap[1])
- g_object_unref (g->pixmap[1]);
+ if (g->pixmap[0])
+ g_object_unref(g->pixmap[0]);
+ if (g->pixmap[1])
+ g_object_unref(g->pixmap[1]);
- g->pixmap[0] = gdk_pixmap_new (gtk_widget_get_window(g->drawing_area),
- g->wp.width, g->wp.height, -1);
- g->pixmap[1] = gdk_pixmap_new (gtk_widget_get_window(g->drawing_area),
- g->wp.width, g->wp.height, -1);
+ g->pixmap[0] = gdk_pixmap_new(gtk_widget_get_window(g->drawing_area),
+ g->wp.width, g->wp.height, -1);
+ g->pixmap[1] = gdk_pixmap_new(gtk_widget_get_window(g->drawing_area),
+ g->wp.width, g->wp.height, -1);
- g->displayed = 0;
+ g->displayed = 0;
#endif /* GTK_CHECK_VERSION(2,22,0) */
}
-static void graph_display (struct graph *g)
+static void graph_display(struct graph *g)
{
- set_busy_cursor (gtk_widget_get_window(g->drawing_area));
- graph_pixmap_draw (g);
- unset_busy_cursor (gtk_widget_get_window(g->drawing_area), g->cross.draw);
- graph_pixmaps_switch (g);
- graph_pixmap_display (g);
+ set_busy_cursor(gtk_widget_get_window(g->drawing_area));
+ graph_pixmap_draw(g);
+ unset_busy_cursor(gtk_widget_get_window(g->drawing_area), g->cross.draw);
+ graph_pixmaps_switch(g);
+ graph_pixmap_display(g);
}
-static void graph_pixmap_display (struct graph *g)
+static void graph_pixmap_display(struct graph *g)
{
- cairo_t *cr;
+ cairo_t *cr;
- cr = gdk_cairo_create (gtk_widget_get_window(g->drawing_area));
+ cr = gdk_cairo_create(gtk_widget_get_window(g->drawing_area));
#if GTK_CHECK_VERSION(2,22,0)
- cairo_set_source_surface (cr, g->surface[g->displayed], g->wp.x, g->wp.y);
+ cairo_set_source_surface(cr, g->surface[g->displayed], g->wp.x, g->wp.y);
#else
- gdk_cairo_set_source_pixmap (cr, g->pixmap[g->displayed], g->wp.x, g->wp.y);
+ gdk_cairo_set_source_pixmap(cr, g->pixmap[g->displayed], g->wp.x, g->wp.y);
#endif /* GTK_CHECK_VERSION(2,22,0) */
- cairo_rectangle (cr, g->wp.x, g->wp.y, g->wp.width, g->wp.height);
- cairo_fill (cr);
- cairo_destroy (cr);
- if (g->cross.erase_needed) {
- cross_erase(g);
- }
+ cairo_rectangle(cr, g->wp.x, g->wp.y, g->wp.width, g->wp.height);
+ cairo_fill(cr);
+ cairo_destroy(cr);
+ if (g->cross.erase_needed) {
+ cross_erase(g);
+ }
}
-static void graph_pixmaps_switch (struct graph *g)
+static void graph_pixmaps_switch(struct graph *g)
{
- g->displayed = 1 ^ g->displayed;
+ g->displayed = 1 ^ g->displayed;
}
-static void graph_pixmap_draw (struct graph *g)
+static void graph_pixmap_draw(struct graph *g)
{
- struct element_list *list;
- struct element *e;
- int not_disp;
- cairo_t *cr;
- GdkColor *current_line_color = NULL;
- GdkColor *color_to_set = NULL;
- gboolean line_stroked = TRUE;
+ struct element_list *list;
+ struct element *e;
+ int not_disp;
+ cairo_t *cr;
+ GdkColor *current_line_color = NULL;
+ GdkColor *color_to_set = NULL;
+ gboolean line_stroked = TRUE;
- debug(DBS_FENTRY) puts ("graph_pixmap_draw()");
- not_disp = 1 ^ g->displayed;
+ debug(DBS_FENTRY) puts("graph_pixmap_draw()");
+ not_disp = 1 ^ g->displayed;
#if GTK_CHECK_VERSION(2,22,0)
- cr = cairo_create (g->surface[not_disp]);
+ cr = cairo_create(g->surface[not_disp]);
#else
- cr = gdk_cairo_create (g->pixmap[not_disp]);
+ cr = gdk_cairo_create(g->pixmap[not_disp]);
#endif /* GTK_CHECK_VERSION(2,22,0) */
- cairo_set_source_rgb (cr, 1, 1, 1);
- cairo_rectangle (cr, 0, 0, g->wp.width, g->wp.height);
- cairo_fill (cr);
-
- /* Want line width 1 for all elements */
- cairo_set_line_width (cr, 1.0);
-
- for (list=g->elists; list; list=list->next)
- for (e=list->elements; e->type != ELMT_NONE; e++) {
- switch (e->type) {
- case ELMT_RECT:
- current_line_color = NULL;
- break;
-
- case ELMT_LINE:
- /* Work out if we need to change colour */
- if (current_line_color == e->elment_color_p) {
- /* No change needed */
- color_to_set = NULL;
- }
- else {
- /* Changing colour */
- current_line_color = color_to_set = e->elment_color_p;
- }
-
- /* Draw the line */
- draw_element_line (g, e, cr, color_to_set);
- line_stroked = FALSE;
- break;
-
- case ELMT_ELLIPSE:
- if (!line_stroked) {
- cairo_stroke(cr);
- line_stroked = TRUE;
- }
- draw_element_ellipse (g, e, cr);
- break;
-
- default:
- break;
- }
- }
-
- /* Make sure any remaining lines get drawn */
- if (!line_stroked)
- cairo_stroke (cr);
-
- cairo_destroy (cr);
-}
-
-static void draw_element_line (struct graph *g, struct element *e, cairo_t *cr,
- GdkColor *new_color)
-{
- int xx1, xx2, yy1, yy2;
-
- debug(DBS_GRAPH_DRAWING) printf ("line element: (%.2f,%.2f)->(%.2f,%.2f), "
- "seg %d ... ", e->p.line.dim.x1, e->p.line.dim.y1,
- e->p.line.dim.x2, e->p.line.dim.y2, e->parent->num);
-
- /* Set our new colour (if changed) */
- if (new_color != NULL) {
- /* First draw any previous lines with old colour */
- cairo_stroke(cr);
- gdk_cairo_set_source_color(cr, new_color);
- }
-
- xx1 = (int )rint (e->p.line.dim.x1 + g->geom.x - g->wp.x);
- xx2 = (int )rint (e->p.line.dim.x2 + g->geom.x - g->wp.x);
- yy1 = (int )rint ((g->geom.height-1-e->p.line.dim.y1) + g->geom.y-g->wp.y);
- yy2 = (int )rint ((g->geom.height-1-e->p.line.dim.y2) + g->geom.y-g->wp.y);
-
- /* If line completely out of the area, we won't show it */
- if ((xx1<0 && xx2<0) || (xx1>=g->wp.width && xx2>=g->wp.width) ||
- (yy1<0 && yy2<0) || (yy1>=g->wp.height && yy2>=g->wp.height)) {
- debug(DBS_GRAPH_DRAWING) printf (" refusing: (%d,%d)->(%d,%d)\n",
- xx1, yy1, xx2, yy2);
- return;
- }
-
- /* If one end of the line is out of bounds, don't worry. Cairo will
- clip the line to the outside of g->wp at the correct angle! */
-
- debug(DBS_GRAPH_DRAWING) printf ("line: (%d,%d)->(%d,%d)\n", xx1, yy1, xx2,yy2);
-
- g_assert(e->elment_color_p!=NULL);
-
- cairo_move_to(cr, xx1+0.5, yy1+0.5);
- cairo_line_to(cr, xx2+0.5, yy2+0.5);
-}
-
-static void draw_element_ellipse (struct graph *g, struct element *e, cairo_t *cr)
+ cairo_set_source_rgb(cr, 1, 1, 1);
+ cairo_rectangle(cr, 0, 0, g->wp.width, g->wp.height);
+ cairo_fill(cr);
+
+ /* Want line width 1 for all elements */
+ cairo_set_line_width(cr, 1.0);
+
+ for (list=g->elists; list; list=list->next) {
+ for (e=list->elements; e->type != ELMT_NONE; e++) {
+ switch (e->type) {
+ case ELMT_RECT:
+ current_line_color = NULL;
+ break;
+
+ case ELMT_LINE:
+ /* Work out if we need to change colour */
+ if (current_line_color == e->elment_color_p) {
+ /* No change needed */
+ color_to_set = NULL;
+ }
+ else {
+ /* Changing colour */
+ current_line_color = color_to_set = e->elment_color_p;
+ }
+
+ /* Draw the line */
+ draw_element_line(g, e, cr, color_to_set);
+ line_stroked = FALSE;
+ break;
+
+ case ELMT_ELLIPSE:
+ if (!line_stroked) {
+ cairo_stroke(cr);
+ line_stroked = TRUE;
+ }
+ draw_element_ellipse(g, e, cr);
+ break;
+
+ default:
+ break;
+ }
+ }
+ }
+
+ /* Make sure any remaining lines get drawn */
+ if (!line_stroked)
+ cairo_stroke(cr);
+
+ cairo_destroy(cr);
+}
+
+static void draw_element_line(struct graph *g, struct element *e, cairo_t *cr,
+ GdkColor *new_color)
+{
+ int xx1, xx2, yy1, yy2;
+
+ debug(DBS_GRAPH_DRAWING) printf("line element: (%.2f,%.2f)->(%.2f,%.2f), "
+ "seg %d ... ", e->p.line.dim.x1, e->p.line.dim.y1,
+ e->p.line.dim.x2, e->p.line.dim.y2, e->parent->num);
+
+ /* Set our new colour (if changed) */
+ if (new_color != NULL) {
+ /* First draw any previous lines with old colour */
+ cairo_stroke(cr);
+ gdk_cairo_set_source_color(cr, new_color);
+ }
+
+ xx1 = (int )rint(e->p.line.dim.x1 + g->geom.x - g->wp.x);
+ xx2 = (int )rint(e->p.line.dim.x2 + g->geom.x - g->wp.x);
+ yy1 = (int )rint((g->geom.height-1-e->p.line.dim.y1) + g->geom.y-g->wp.y);
+ yy2 = (int )rint((g->geom.height-1-e->p.line.dim.y2) + g->geom.y-g->wp.y);
+
+ /* If line completely out of the area, we won't show it */
+ if (((xx1 < 0) && (xx2 < 0)) || ((xx1 >= g->wp.width) && (xx2 >= g->wp.width)) ||
+ ((yy1 < 0) && (yy2 < 0)) || ((yy1 >= g->wp.height) && (yy2 >= g->wp.height))) {
+ debug(DBS_GRAPH_DRAWING) printf(" refusing: (%d,%d)->(%d,%d)\n",
+ xx1, yy1, xx2, yy2);
+ return;
+ }
+
+ /* If one end of the line is out of bounds, don't worry. Cairo will
+ clip the line to the outside of g->wp at the correct angle! */
+
+ debug(DBS_GRAPH_DRAWING) printf("line: (%d,%d)->(%d,%d)\n", xx1, yy1, xx2, yy2);
+
+ g_assert(e->elment_color_p!=NULL);
+
+ cairo_move_to(cr, xx1+0.5, yy1+0.5);
+ cairo_line_to(cr, xx2+0.5, yy2+0.5);
+}
+
+static void draw_element_ellipse(struct graph *g, struct element *e, cairo_t *cr)
+{
+ gdouble w = e->p.ellipse.dim.width;
+ gdouble h = e->p.ellipse.dim.height;
+ gdouble x = e->p.ellipse.dim.x + g->geom.x - g->wp.x;
+ gdouble y = g->geom.height-1 - e->p.ellipse.dim.y + g->geom.y - g->wp.y;
+
+ debug(DBS_GRAPH_DRAWING) printf("ellipse: (x, y) -> (w, h): (%f, %f) -> (%f, %f)\n", x, y, w, h);
+
+ cairo_save(cr);
+ cairo_set_source_rgb(cr, 0, 0, 0);
+ cairo_translate(cr, x + w / 2., y + h / 2.);
+ cairo_scale(cr, w / 2., h / 2.);
+ cairo_arc(cr, 0., 0., 1., 0., 2 * G_PI);
+ cairo_fill(cr);
+ cairo_restore(cr);
+}
+
+static void axis_pixmaps_create(struct axis *axis)
{
- gdouble w = e->p.ellipse.dim.width;
- gdouble h = e->p.ellipse.dim.height;
- gdouble x = e->p.ellipse.dim.x + g->geom.x - g->wp.x;
- gdouble y = g->geom.height-1 - e->p.ellipse.dim.y + g->geom.y - g->wp.y;
-
- debug(DBS_GRAPH_DRAWING) printf ("ellipse: (x, y) -> (w, h): (%f, %f) -> (%f, %f)\n", x, y, w, h);
-
- cairo_save(cr);
- cairo_set_source_rgb(cr, 0, 0, 0);
- cairo_translate (cr, x + w / 2., y + h / 2.);
- cairo_scale (cr, w / 2., h / 2.);
- cairo_arc (cr, 0., 0., 1., 0., 2 * G_PI);
- cairo_fill(cr);
- cairo_restore(cr);
-}
-
-static void axis_pixmaps_create (struct axis *axis)
-{
- debug(DBS_FENTRY) puts ("axis_pixmaps_create()");
+ debug(DBS_FENTRY) puts("axis_pixmaps_create()");
#if GTK_CHECK_VERSION(2,22,0)
- if(axis->surface[0]){
- cairo_surface_destroy (axis->surface[0]);
- axis->surface[0] = NULL;
- }
- if(axis->surface[1]){
- cairo_surface_destroy (axis->surface[1]);
- axis->surface[1] = NULL;
- }
- axis->surface[0] = gdk_window_create_similar_surface (gtk_widget_get_window(axis->drawing_area),
- CAIRO_CONTENT_COLOR,
- axis->p.width,
- axis->p.height);
-
- axis->surface[1] = gdk_window_create_similar_surface (gtk_widget_get_window(axis->drawing_area),
- CAIRO_CONTENT_COLOR,
- axis->p.width,
- axis->p.height);
-
- axis->displayed = 0;
+ if (axis->surface[0]) {
+ cairo_surface_destroy(axis->surface[0]);
+ axis->surface[0] = NULL;
+ }
+ if (axis->surface[1]) {
+ cairo_surface_destroy(axis->surface[1]);
+ axis->surface[1] = NULL;
+ }
+ axis->surface[0] = gdk_window_create_similar_surface(gtk_widget_get_window(axis->drawing_area),
+ CAIRO_CONTENT_COLOR,
+ axis->p.width,
+ axis->p.height);
+
+ axis->surface[1] = gdk_window_create_similar_surface(gtk_widget_get_window(axis->drawing_area),
+ CAIRO_CONTENT_COLOR,
+ axis->p.width,
+ axis->p.height);
+
+ axis->displayed = 0;
#else
- if (axis->pixmap[0])
- g_object_unref (axis->pixmap[0]);
- if (axis->pixmap[1])
- g_object_unref (axis->pixmap[1]);
+ if (axis->pixmap[0])
+ g_object_unref(axis->pixmap[0]);
+ if (axis->pixmap[1])
+ g_object_unref(axis->pixmap[1]);
- axis->pixmap[0] = gdk_pixmap_new (gtk_widget_get_window(axis->drawing_area),
- axis->p.width, axis->p.height, -1);
- axis->pixmap[1] = gdk_pixmap_new (gtk_widget_get_window(axis->drawing_area),
- axis->p.width, axis->p.height, -1);
+ axis->pixmap[0] = gdk_pixmap_new(gtk_widget_get_window(axis->drawing_area),
+ axis->p.width, axis->p.height, -1);
+ axis->pixmap[1] = gdk_pixmap_new(gtk_widget_get_window(axis->drawing_area),
+ axis->p.width, axis->p.height, -1);
- axis->displayed = 0;
+ axis->displayed = 0;
#endif
}
-static void axis_destroy (struct axis *axis)
+static void axis_destroy(struct axis *axis)
{
#if GTK_CHECK_VERSION(2,22,0)
- if(axis->surface[0]){
- cairo_surface_destroy (axis->surface[0]);
- axis->surface[0] = NULL;
- }
- if(axis->surface[1]){
- cairo_surface_destroy (axis->surface[1]);
- axis->surface[1] = NULL;
- }
+ if (axis->surface[0]) {
+ cairo_surface_destroy(axis->surface[0]);
+ axis->surface[0] = NULL;
+ }
+ if (axis->surface[1]) {
+ cairo_surface_destroy(axis->surface[1]);
+ axis->surface[1] = NULL;
+ }
#else
- g_object_unref (axis->pixmap[0]);
- g_object_unref (axis->pixmap[1]);
+ g_object_unref(axis->pixmap[0]);
+ g_object_unref(axis->pixmap[1]);
#endif
- g_free ( (gpointer) (axis->label) );
+ g_free( (gpointer) (axis->label) );
}
-static void axis_display (struct axis *axis)
+static void axis_display(struct axis *axis)
{
- if (axis->flags & AXIS_ORIENTATION)
- h_axis_pixmap_draw (axis);
- else
- v_axis_pixmap_draw (axis);
- axis_pixmaps_switch (axis);
- axis_pixmap_display (axis);
+ if (axis->flags & AXIS_ORIENTATION)
+ h_axis_pixmap_draw(axis);
+ else
+ v_axis_pixmap_draw(axis);
+ axis_pixmaps_switch(axis);
+ axis_pixmap_display(axis);
}
-static void v_axis_pixmap_draw (struct axis *axis)
+static void v_axis_pixmap_draw(struct axis *axis)
{
- struct graph *g = axis->g;
- int i;
- double major_tick;
- int not_disp, rdigits, offset, imin, imax;
- double bottom, top, j, fl, corr;
- PangoLayout *layout;
- cairo_t *cr;
+ struct graph *g = axis->g;
+ int i;
+ double major_tick;
+ int not_disp, rdigits, offset, imin, imax;
+ double bottom, top, j, fl, corr;
+ PangoLayout *layout;
+ cairo_t *cr;
- debug(DBS_FENTRY) puts ("v_axis_pixmap_draw()");
- bottom = (g->geom.height - (g->wp.height + g->wp.y + (-g->geom.y))) /
- (double )g->geom.height * g->bounds.height;
- bottom += axis->min;
- top = (g->geom.height - (g->wp.y + (-g->geom.y))) /
- (double )g->geom.height * g->bounds.height;
- top += axis->min;
- axis_compute_ticks (axis, bottom, top, AXIS_VERTICAL);
+ debug(DBS_FENTRY) puts("v_axis_pixmap_draw()");
+ bottom = (g->geom.height - (g->wp.height + g->wp.y + (-g->geom.y))) /
+ (double )g->geom.height * g->bounds.height;
+ bottom += axis->min;
+ top = (g->geom.height - (g->wp.y + (-g->geom.y))) /
+ (double )g->geom.height * g->bounds.height;
+ top += axis->min;
+ axis_compute_ticks(axis, bottom, top, AXIS_VERTICAL);
- j = axis->major - floor (axis->major);
- for (rdigits=0; rdigits<=6; rdigits++) {
- j *= 10;
- if (j<=0.000001)
- break;
- j = j - floor (j);
- }
+ j = axis->major - floor(axis->major);
+ for (rdigits=0; rdigits <= 6; rdigits++) {
+ j *= 10;
+ if (j <= 0.000001)
+ break;
+ j = j - floor(j);
+ }
- not_disp = 1 ^ axis->displayed;
+ not_disp = 1 ^ axis->displayed;
#if GTK_CHECK_VERSION(2,22,0)
- cr = cairo_create (axis->surface[not_disp]);
+ cr = cairo_create(axis->surface[not_disp]);
#else
- cr = gdk_cairo_create (axis->pixmap[not_disp]);
+ cr = gdk_cairo_create(axis->pixmap[not_disp]);
#endif
- cairo_set_source_rgb (cr, 1, 1, 1);
- cairo_rectangle (cr, 0, 0, axis->p.width, axis->p.height);
- cairo_fill (cr);
-
- /* axis */
- cairo_set_source_rgb (cr, 0, 0, 0);
- cairo_set_line_width (cr, 1.0);
- cairo_move_to(cr, axis->p.width - 1.5, (axis->p.height-axis->s.height)/2.0);
- cairo_line_to(cr, axis->s.width - 1.5, axis->p.height);
-
- offset = g->wp.y + (-g->geom.y);
- fl = floor (axis->min / axis->major) * axis->major;
- corr = rint ((axis->min - fl) * g->zoom.y);
-
- /* major ticks */
- major_tick = axis->major * g->zoom.y;
- imin = (int) ((g->geom.height - offset + corr - g->wp.height) / major_tick + 1);
- imax = (int) ((g->geom.height - offset + corr) / major_tick);
- for (i=imin; i <= imax; i++) {
- gint w, h;
- char desc[32];
- int y = (int) (g->geom.height-1 - (int )rint (i * major_tick) -
- offset + corr + axis->s.y);
-
- debug(DBS_AXES_DRAWING) printf("%f @ %d\n",
- i*axis->major + fl, y);
- if (y < 0 || y > axis->p.height)
- continue;
-
- cairo_move_to(cr, axis->p.width - 15, y+0.5);
- cairo_line_to(cr, axis->s.width - 1, y+0.5);
-
- g_snprintf (desc, sizeof(desc), "%.*f", rdigits, i*axis->major + fl);
- layout = gtk_widget_create_pango_layout (g->drawing_area, desc);
- pango_layout_get_pixel_size (layout, &w, &h);
- cairo_move_to (cr, axis->s.width-14-4-w, y - h/2);
- pango_cairo_show_layout (cr, layout);
- g_object_unref (G_OBJECT(layout));
- }
- /* minor ticks */
- if (axis->minor) {
- double minor_tick = axis->minor * g->zoom.y;
- imin = (int) ((g->geom.height - offset + corr - g->wp.height)/minor_tick + 1);
- imax = (int) ((g->geom.height - offset + corr) / minor_tick);
- for (i=imin; i <= imax; i++) {
- int y = (int) (g->geom.height-1 - (int )rint (i*minor_tick) -
- offset + corr + axis->s.y);
-
- debug (DBS_AXES_DRAWING) printf ("%f @ %d\n", i*axis->minor+fl, y);
- if (y > 0 && y < axis->p.height) {
- cairo_move_to(cr, axis->s.width - 8, y+0.5);
- cairo_line_to(cr, axis->s.width - 1, y+0.5);
- }
- }
- }
- for (i=0; axis->label[i]; i++) {
- gint w, h;
- layout = gtk_widget_create_pango_layout(g->drawing_area,
- axis->label[i]);
- pango_layout_get_pixel_size(layout, &w, &h);
- cairo_move_to (cr, (axis->p.width - w)/2, TITLEBAR_HEIGHT-10 - i*(h+3) - h);
- pango_cairo_show_layout (cr, layout);
- g_object_unref(G_OBJECT(layout));
- }
- cairo_stroke (cr);
- cairo_destroy (cr);
-}
-
-static void h_axis_pixmap_draw (struct axis *axis)
-{
- struct graph *g = axis->g;
- int i;
- double major_tick, minor_tick;
- int not_disp, rdigits, offset, imin, imax;
- double left, right, j, fl, corr;
- PangoLayout *layout;
- cairo_t *cr;
-
- debug(DBS_FENTRY) puts ("h_axis_pixmap_draw()");
- left = (g->wp.x-g->geom.x) /
- (double )g->geom.width * g->bounds.width;
- left += axis->min;
- right = (g->wp.x-g->geom.x+g->wp.width) /
- (double )g->geom.width * g->bounds.width;
- right += axis->min;
- axis_compute_ticks (axis, left, right, AXIS_HORIZONTAL);
-
- j = axis->major - floor (axis->major);
- for (rdigits=0; rdigits<=6; rdigits++) {
- j *= 10;
- if (j<=0.000001)
- break;
- j = j - floor (j);
- }
-
- not_disp = 1 ^ axis->displayed;
+ cairo_set_source_rgb(cr, 1, 1, 1);
+ cairo_rectangle(cr, 0, 0, axis->p.width, axis->p.height);
+ cairo_fill(cr);
+
+ /* axis */
+ cairo_set_source_rgb(cr, 0, 0, 0);
+ cairo_set_line_width(cr, 1.0);
+ cairo_move_to(cr, axis->p.width - 1.5, (axis->p.height-axis->s.height)/2.0);
+ cairo_line_to(cr, axis->s.width - 1.5, axis->p.height);
+
+ offset = g->wp.y + (-g->geom.y);
+ fl = floor(axis->min / axis->major) * axis->major;
+ corr = rint((axis->min - fl) * g->zoom.y);
+
+ /* major ticks */
+ major_tick = axis->major * g->zoom.y;
+ imin = (int) ((g->geom.height - offset + corr - g->wp.height) / major_tick + 1);
+ imax = (int) ((g->geom.height - offset + corr) / major_tick);
+ for (i=imin; i <= imax; i++) {
+ gint w, h;
+ char desc[32];
+ int y = (int) (g->geom.height - 1 - (int )rint(i * major_tick) -
+ offset + corr + axis->s.y);
+
+ debug(DBS_AXES_DRAWING) printf("%f @ %d\n",
+ (i * axis->major) + fl, y);
+ if ((y < 0) || (y > axis->p.height))
+ continue;
+
+ cairo_move_to(cr, axis->p.width - 15, y + 0.5);
+ cairo_line_to(cr, axis->s.width - 1, y + 0.5);
+
+ g_snprintf(desc, sizeof(desc), "%.*f", rdigits, i*axis->major + fl);
+ layout = gtk_widget_create_pango_layout(g->drawing_area, desc);
+ pango_layout_get_pixel_size(layout, &w, &h);
+ cairo_move_to(cr, axis->s.width-14-4-w, y - h/2);
+ pango_cairo_show_layout(cr, layout);
+ g_object_unref(G_OBJECT(layout));
+ }
+ /* minor ticks */
+ if (axis->minor) {
+ double minor_tick = axis->minor * g->zoom.y;
+ imin = (int) ((g->geom.height - offset + corr - g->wp.height)/minor_tick + 1);
+ imax = (int) ((g->geom.height - offset + corr) / minor_tick);
+ for (i=imin; i <= imax; i++) {
+ int y = (int) (g->geom.height-1 - (int )rint (i*minor_tick) -
+ offset + corr + axis->s.y);
+
+ debug(DBS_AXES_DRAWING) printf("%f @ %d\n", i*axis->minor+fl, y);
+ if ((y > 0) && (y < axis->p.height)) {
+ cairo_move_to(cr, axis->s.width - 8, y+0.5);
+ cairo_line_to(cr, axis->s.width - 1, y+0.5);
+ }
+ }
+ }
+ for (i=0; axis->label[i]; i++) {
+ gint w, h;
+ layout = gtk_widget_create_pango_layout(g->drawing_area,
+ axis->label[i]);
+ pango_layout_get_pixel_size(layout, &w, &h);
+ cairo_move_to(cr,(axis->p.width - w)/2, TITLEBAR_HEIGHT-10 - i*(h+3) - h);
+ pango_cairo_show_layout(cr, layout);
+ g_object_unref(G_OBJECT(layout));
+ }
+ cairo_stroke(cr);
+ cairo_destroy(cr);
+}
+
+static void h_axis_pixmap_draw(struct axis *axis)
+{
+ struct graph *g = axis->g;
+ int i;
+ double major_tick, minor_tick;
+ int not_disp, rdigits, offset, imin, imax;
+ double left, right, j, fl, corr;
+ PangoLayout *layout;
+ cairo_t *cr;
+
+ debug(DBS_FENTRY) puts("h_axis_pixmap_draw()");
+ left = (g->wp.x-g->geom.x) / (double )g->geom.width * g->bounds.width;
+ left += axis->min;
+ right = (g->wp.x - g->geom.x + g->wp.width) / (double )g->geom.width * g->bounds.width;
+ right += axis->min;
+ axis_compute_ticks(axis, left, right, AXIS_HORIZONTAL);
+
+ j = axis->major - floor(axis->major);
+ for (rdigits=0; rdigits <= 6; rdigits++) {
+ j *= 10;
+ if (j <= 0.000001)
+ break;
+ j = j - floor(j);
+ }
+
+ not_disp = 1 ^ axis->displayed;
#if GTK_CHECK_VERSION(2,22,0)
- cr = cairo_create (axis->surface[not_disp]);
+ cr = cairo_create(axis->surface[not_disp]);
#else
- cr = gdk_cairo_create (axis->pixmap[not_disp]);
+ cr = gdk_cairo_create(axis->pixmap[not_disp]);
#endif
- cairo_set_source_rgb (cr, 1, 1, 1);
- cairo_rectangle (cr, 0, 0, axis->p.width, axis->p.height);
- cairo_fill (cr);
-
- /* axis */
- cairo_set_source_rgb (cr, 0, 0, 0);
- cairo_set_line_width (cr, 1.0);
- cairo_move_to(cr, 0, 0.5);
- cairo_line_to(cr, axis->s.width + (axis->p.width-axis->s.width)/2.0, 0.5);
-
- offset = g->wp.x - g->geom.x;
-
- fl = floor (axis->min / axis->major) * axis->major;
- corr = rint ((axis->min - fl) * g->zoom.x);
-
- /* major ticks */
- major_tick = axis->major*g->zoom.x;
- imin = (int) ((offset + corr) / major_tick + 1);
- imax = (int) ((offset + corr + axis->s.width) / major_tick);
- for (i=imin; i <= imax; i++) {
- char desc[32];
- int w, h;
- int x = (int ) (rint (i * major_tick) - offset - corr);
-
- /* printf ("%f @ %d\n", i*axis->major + fl, x); */
- if (x < 0 || x > axis->s.width)
- continue;
- cairo_move_to(cr, x+0.5, 0);
- cairo_line_to(cr, x+0.5, 15);
-
- g_snprintf (desc, sizeof(desc), "%.*f", rdigits, i*axis->major + fl);
- layout = gtk_widget_create_pango_layout(g->drawing_area, desc);
- pango_layout_get_pixel_size(layout, &w, &h);
- cairo_move_to (cr, x - w/2, 15+4);
- pango_cairo_show_layout (cr, layout);
- g_object_unref(G_OBJECT(layout));
- }
- if (axis->minor > 0) {
- /* minor ticks */
- minor_tick = axis->minor*g->zoom.x;
- imin = (int) ((offset + corr) / minor_tick + 1);
- imax = (int) ((offset + corr + g->wp.width) / minor_tick);
- for (i=imin; i <= imax; i++) {
- int x = (int) (rint (i * minor_tick) - offset - corr);
- if (x > 0 && x < axis->s.width){
- cairo_move_to(cr, x+0.5, 0);
- cairo_line_to(cr, x+0.5, 8);
- }
- }
- }
- for (i=0; axis->label[i]; i++) {
- gint w, h;
- layout = gtk_widget_create_pango_layout(g->drawing_area,
- axis->label[i]);
- pango_layout_get_pixel_size(layout, &w, &h);
- cairo_move_to (cr, axis->s.width - w - 50, 15+h+15 + i*(h+3));
- pango_cairo_show_layout (cr, layout);
- g_object_unref(G_OBJECT(layout));
- }
- cairo_stroke (cr);
- cairo_destroy (cr);
-}
-
-static void axis_pixmaps_switch (struct axis *axis)
-{
- axis->displayed = 1 ^ axis->displayed;
-}
-
-static void axis_pixmap_display (struct axis *axis)
-{
- cairo_t *cr;
-
- cr = gdk_cairo_create (gtk_widget_get_window(axis->drawing_area));
+ cairo_set_source_rgb(cr, 1, 1, 1);
+ cairo_rectangle(cr, 0, 0, axis->p.width, axis->p.height);
+ cairo_fill(cr);
+
+ /* axis */
+ cairo_set_source_rgb(cr, 0, 0, 0);
+ cairo_set_line_width(cr, 1.0);
+ cairo_move_to(cr, 0, 0.5);
+ cairo_line_to(cr, axis->s.width + (axis->p.width-axis->s.width)/2.0, 0.5);
+
+ offset = g->wp.x - g->geom.x;
+
+ fl = floor(axis->min / axis->major) * axis->major;
+ corr = rint((axis->min - fl) * g->zoom.x);
+
+ /* major ticks */
+ major_tick = axis->major*g->zoom.x;
+ imin = (int) ((offset + corr) / major_tick + 1);
+ imax = (int) ((offset + corr + axis->s.width) / major_tick);
+ for (i=imin; i <= imax; i++) {
+ char desc[32];
+ int w, h;
+ int x = (int ) (rint(i * major_tick) - offset - corr);
+
+ /* printf("%f @ %d\n", i*axis->major + fl, x); */
+ if ((x < 0) || (x > axis->s.width))
+ continue;
+ cairo_move_to(cr, x+0.5, 0);
+ cairo_line_to(cr, x+0.5, 15);
+
+ g_snprintf(desc, sizeof(desc), "%.*f", rdigits, i*axis->major + fl);
+ layout = gtk_widget_create_pango_layout(g->drawing_area, desc);
+ pango_layout_get_pixel_size(layout, &w, &h);
+ cairo_move_to(cr, x - w/2, 15+4);
+ pango_cairo_show_layout(cr, layout);
+ g_object_unref(G_OBJECT(layout));
+ }
+ if (axis->minor > 0) {
+ /* minor ticks */
+ minor_tick = axis->minor*g->zoom.x;
+ imin = (int) ((offset + corr) / minor_tick + 1);
+ imax = (int) ((offset + corr + g->wp.width) / minor_tick);
+ for (i=imin; i <= imax; i++) {
+ int x = (int) (rint(i * minor_tick) - offset - corr);
+ if ((x > 0) && (x < axis->s.width)) {
+ cairo_move_to(cr, x+0.5, 0);
+ cairo_line_to(cr, x+0.5, 8);
+ }
+ }
+ }
+ for (i=0; axis->label[i]; i++) {
+ gint w, h;
+ layout = gtk_widget_create_pango_layout(g->drawing_area,
+ axis->label[i]);
+ pango_layout_get_pixel_size(layout, &w, &h);
+ cairo_move_to(cr, axis->s.width - w - 50, 15+h+15 + i*(h+3));
+ pango_cairo_show_layout(cr, layout);
+ g_object_unref(G_OBJECT(layout));
+ }
+ cairo_stroke(cr);
+ cairo_destroy(cr);
+}
+
+static void axis_pixmaps_switch(struct axis *axis)
+{
+ axis->displayed = 1 ^ axis->displayed;
+}
+
+static void axis_pixmap_display(struct axis *axis)
+{
+ cairo_t *cr;
+
+ cr = gdk_cairo_create(gtk_widget_get_window(axis->drawing_area));
#if GTK_CHECK_VERSION(2,22,0)
- cairo_set_source_surface (cr, axis->surface[axis->displayed], axis->p.x, axis->p.y);
+ cairo_set_source_surface(cr, axis->surface[axis->displayed], axis->p.x, axis->p.y);
#else
- gdk_cairo_set_source_pixmap (cr, axis->pixmap[axis->displayed], axis->p.x, axis->p.y);
+ gdk_cairo_set_source_pixmap(cr, axis->pixmap[axis->displayed], axis->p.x, axis->p.y);
#endif
- cairo_rectangle (cr, axis->p.x, axis->p.y, axis->p.width, axis->p.height);
- cairo_fill (cr);
- cairo_destroy (cr);
-
-}
-
-static void axis_compute_ticks (struct axis *axis, double x0, double xmax, int dir)
-{
- int i, j, ii, jj, ms;
- double zoom, x, steps[3]={ 0.1, 0.5 };
- int dim, check_needed, diminished;
- double majthresh[2]={2.0, 3.0};
-
- debug((DBS_FENTRY | DBS_AXES_TICKS)) puts ("axis_compute_ticks()");
- debug(DBS_AXES_TICKS)
- printf ("x0=%f xmax=%f dir=%s\n", x0,xmax, dir?"VERTICAL":"HORIZONTAL");
-
- zoom = axis_zoom_get (axis, dir);
- x = xmax-x0;
- for (i=-9; i<=12; i++) {
- if (x / pow (10, i) < 1)
- break;
- }
- --i;
- ms = (int )(x / pow (10, i));
-
- if (ms > 5) {
- j = 0;
- ++i;
- } else if (ms > 2)
- j = 1;
- else
- j = 0;
-
- axis->major = steps[j] * pow (10, i);
-
- debug(DBS_AXES_TICKS) printf ("zoom=%.1f, x=%f -> i=%d -> ms=%d -> j=%d ->"
- " axis->major=%f\n", zoom, x, i, ms, j, axis->major);
-
- /* let's compute minor ticks */
- jj = j;
- ii = i;
- axis_ticks_down (&ii, &jj);
- axis->minor = steps[jj] * pow (10, ii);
- /* we don't want minors if they would be less than 10 pixels apart */
- if (axis->minor*zoom < 10) {
- debug(DBS_AXES_TICKS) printf ("refusing axis->minor of %f: "
- "axis->minor*zoom == %f\n", axis->minor, axis->minor*zoom);
- axis->minor = 0;
- }
-
- check_needed = TRUE;
- diminished = FALSE;
- while (check_needed) {
- check_needed = FALSE;
- dim = get_label_dim (axis, dir, xmax);
- debug(DBS_AXES_TICKS) printf ("axis->major==%.1f, axis->minor==%.1f =>"
- " axis->major*zoom/dim==%f, axis->minor*zoom/dim==%f\n",
- axis->major, axis->minor, axis->major*zoom/dim,
- axis->minor*zoom/dim);
-
- /* corrections: if majors are less than majthresh[dir] times label
- * dimension apart, we need to use bigger ones */
- if (axis->major*zoom / dim < majthresh[dir]) {
- axis_ticks_up (&ii, &jj);
- axis->minor = axis->major;
- axis_ticks_up (&i, &j);
- axis->major = steps[j] * pow (10, i);
- check_needed = TRUE;
- debug(DBS_AXES_TICKS) printf ("axis->major enlarged to %.1f\n",
- axis->major);
- }
- /* if minor ticks are bigger than majthresh[dir] times label dimension,
- * we could promote them to majors as well */
- if (axis->minor*zoom / dim > majthresh[dir] && !diminished) {
- axis_ticks_down (&i, &j);
- axis->major = axis->minor;
- axis_ticks_down (&ii, &jj);
- axis->minor = steps[jj] * pow (10, ii);
- check_needed = TRUE;
- diminished = TRUE;
-
- debug(DBS_AXES_TICKS) printf ("axis->minor diminished to %.1f\n",
- axis->minor);
-
- if (axis->minor*zoom < 10) {
- debug(DBS_AXES_TICKS) printf ("refusing axis->minor of %f: "
- "axis->minor*zoom == %f\n", axis->minor, axis->minor*zoom);
- axis->minor = 0;
- }
- }
- }
-
- debug(DBS_AXES_TICKS) printf ("corrected: axis->major == %.1f -> "
- "axis->minor == %.1f\n", axis->major, axis->minor);
-}
-
-static void axis_ticks_up (int *i, int *j)
-{
- (*j)++;
- if (*j>1) {
- (*i)++;
- *j=0;
- }
-}
-
-static void axis_ticks_down (int *i, int *j)
-{
- (*j)--;
- if (*j<0) {
- (*i)--;
- *j=1;
- }
-}
-
-static int get_label_dim (struct axis *axis, int dir, double label)
-{
- double y;
- char str[32];
- int rdigits, dim;
- PangoLayout *layout;
-
- /* First, let's compute how many digits to the right of radix
- * we need to print */
- y = axis->major - floor (axis->major);
- for (rdigits=0; rdigits<=6; rdigits++) {
- y *= 10;
- if (y<=0.000001)
- break;
- y = y - floor (y);
- }
- g_snprintf (str, sizeof(str), "%.*f", rdigits, label);
- switch (dir) {
- case AXIS_HORIZONTAL:
- layout = gtk_widget_create_pango_layout(axis->g->drawing_area,
- str);
- pango_layout_get_pixel_size(layout, &dim, NULL);
- g_object_unref(G_OBJECT(layout));
- break;
- case AXIS_VERTICAL:
- layout = gtk_widget_create_pango_layout(axis->g->drawing_area,
- str);
- pango_layout_get_pixel_size(layout, NULL, &dim);
- g_object_unref(G_OBJECT(layout));
- break;
- default:
- puts ("initialize axis: an axis must be either horizontal or vertical");
- return -1;
- }
- return dim;
-}
-
-static double axis_zoom_get (struct axis *axis, int dir)
-{
- switch (dir) {
- case AXIS_HORIZONTAL:
- return axis->g->zoom.x;
- case AXIS_VERTICAL:
- return axis->g->zoom.y;
- default:
- return -1;
- }
-}
-
-static void graph_select_segment (struct graph *g, int x, int y)
-{
- struct element_list *list;
- struct element *e;
- guint num = 0;
-
- debug(DBS_FENTRY) puts ("graph_select_segment()");
-
- x -= g->geom.x;
- y = g->geom.height-1 - (y - g->geom.y);
-
- set_busy_cursor (gtk_widget_get_window(g->drawing_area));
-
- for (list=g->elists; list; list=list->next)
- for (e=list->elements; e->type != ELMT_NONE; e++) {
- switch (e->type) {
- case ELMT_RECT:
- break;
- case ELMT_LINE:
- if (line_detect_collision (e, x, y)) {
- num = e->parent->num;
- }
- break;
- case ELMT_ELLIPSE:
- if (ellipse_detect_collision (e, x, y)) {
- num = e->parent->num;
- }
- break;
- default:
- break;
- }
- }
-
-
- if (num) {
- cf_goto_frame(&cfile, num);
- }
- unset_busy_cursor (gtk_widget_get_window(g->drawing_area), g->cross.draw);
-}
-
-static int line_detect_collision (struct element *e, int x, int y)
-{
- int xx1, yy1, xx2, yy2;
-
- if (e->p.line.dim.x1 < e->p.line.dim.x2) {
- xx1 = (int )rint (e->p.line.dim.x1);
- xx2 = (int )rint (e->p.line.dim.x2);
- } else {
- xx1 = (int )rint (e->p.line.dim.x2);
- xx2 = (int )rint (e->p.line.dim.x1);
- }
- if (e->p.line.dim.y1 < e->p.line.dim.y2) {
- yy1 = (int )rint (e->p.line.dim.y1);
- yy2 = (int )rint (e->p.line.dim.y2);
- } else {
- yy1 = (int )rint (e->p.line.dim.y2);
- yy2 = (int )rint (e->p.line.dim.y1);
- }
- /*
- printf ("line: (%d,%d)->(%d,%d), clicked: (%d,%d)\n", xx1, yy1, xx2, yy2, x, y);
- */
- if ((xx1==x && xx2==x && yy1<=y && y<=yy2)||(yy1==y && yy2==y && xx1<=x && x<=xx2))
- return TRUE;
- else
- return FALSE;
-}
-
-static int ellipse_detect_collision (struct element *e, int x, int y)
-{
- int xx1, yy1, xx2, yy2;
-
- xx1 = (int )rint (e->p.ellipse.dim.x);
- xx2 = (int )rint (e->p.ellipse.dim.x + e->p.ellipse.dim.width);
- yy1 = (int )rint (e->p.ellipse.dim.y - e->p.ellipse.dim.height);
- yy2 = (int )rint (e->p.ellipse.dim.y);
- /*
- printf ("ellipse: (%d,%d)->(%d,%d), clicked: (%d,%d)\n", xx1, yy1, xx2, yy2, x, y);
- */
- if (xx1<=x && x<=xx2 && yy1<=y && y<=yy2)
- return TRUE;
- else
- return FALSE;
+ cairo_rectangle(cr, axis->p.x, axis->p.y, axis->p.width, axis->p.height);
+ cairo_fill(cr);
+ cairo_destroy(cr);
+
+}
+
+static void axis_compute_ticks(struct axis *axis, double x0, double xmax, int dir)
+{
+ int i, j, ii, jj, ms;
+ double zoom, x, steps[3] = { 0.1, 0.5 };
+ int dim, check_needed, diminished;
+ double majthresh[2] = {2.0, 3.0};
+
+ debug((DBS_FENTRY | DBS_AXES_TICKS)) puts("axis_compute_ticks()");
+ debug(DBS_AXES_TICKS)
+ printf("x0=%f xmax=%f dir=%s\n", x0,xmax, dir?"VERTICAL":"HORIZONTAL");
+
+ zoom = axis_zoom_get(axis, dir);
+ x = xmax-x0;
+ for (i=-9; i <= 12; i++) {
+ if (x / pow(10, i) < 1)
+ break;
+ }
+ --i;
+ ms = (int )(x / pow(10, i));
+
+ if (ms > 5) {
+ j = 0;
+ ++i;
+ } else if (ms > 2)
+ j = 1;
+ else
+ j = 0;
+
+ axis->major = steps[j] * pow(10, i);
+
+ debug(DBS_AXES_TICKS) printf("zoom=%.1f, x=%f -> i=%d -> ms=%d -> j=%d ->"
+ " axis->major=%f\n", zoom, x, i, ms, j, axis->major);
+
+ /* let's compute minor ticks */
+ jj = j;
+ ii = i;
+ axis_ticks_down(&ii, &jj);
+ axis->minor = steps[jj] * pow(10, ii);
+ /* we don't want minors if they would be less than 10 pixels apart */
+ if (axis->minor*zoom < 10) {
+ debug(DBS_AXES_TICKS) printf("refusing axis->minor of %f: "
+ "axis->minor*zoom == %f\n", axis->minor, axis->minor*zoom);
+ axis->minor = 0;
+ }
+
+ check_needed = TRUE;
+ diminished = FALSE;
+ while (check_needed) {
+ check_needed = FALSE;
+ dim = get_label_dim(axis, dir, xmax);
+ debug(DBS_AXES_TICKS) printf("axis->major==%.1f, axis->minor==%.1f =>"
+ " axis->major*zoom/dim==%f, axis->minor*zoom/dim==%f\n",
+ axis->major, axis->minor, axis->major*zoom/dim,
+ axis->minor*zoom/dim);
+
+ /* corrections: if majors are less than majthresh[dir] times label
+ * dimension apart, we need to use bigger ones */
+ if (axis->major*zoom / dim < majthresh[dir]) {
+ axis_ticks_up(&ii, &jj);
+ axis->minor = axis->major;
+ axis_ticks_up(&i, &j);
+ axis->major = steps[j] * pow(10, i);
+ check_needed = TRUE;
+ debug(DBS_AXES_TICKS) printf("axis->major enlarged to %.1f\n",
+ axis->major);
+ }
+ /* if minor ticks are bigger than majthresh[dir] times label dimension,
+ * we could promote them to majors as well */
+ if (((axis->minor * zoom / dim) > majthresh[dir]) && !diminished) {
+ axis_ticks_down(&i, &j);
+ axis->major = axis->minor;
+ axis_ticks_down(&ii, &jj);
+ axis->minor = steps[jj] * pow(10, ii);
+ check_needed = TRUE;
+ diminished = TRUE;
+
+ debug(DBS_AXES_TICKS) printf("axis->minor diminished to %.1f\n",
+ axis->minor);
+
+ if (axis->minor*zoom < 10) {
+ debug(DBS_AXES_TICKS) printf("refusing axis->minor of %f:"
+ " axis->minor*zoom == %f\n",
+ axis->minor, axis->minor*zoom);
+ axis->minor = 0;
+ }
+ }
+ }
+
+ debug(DBS_AXES_TICKS) printf("corrected: axis->major == %.1f ->"
+ " axis->minor == %.1f\n", axis->major, axis->minor);
+}
+
+static void axis_ticks_up(int *i, int *j)
+{
+ (*j)++;
+ if (*j > 1) {
+ (*i)++;
+ *j = 0;
+ }
+}
+
+static void axis_ticks_down(int *i, int *j)
+{
+ (*j)--;
+ if (*j < 0) {
+ (*i)--;
+ *j = 1;
+ }
+}
+
+static int get_label_dim(struct axis *axis, int dir, double label)
+{
+ double y;
+ char str[32];
+ int rdigits, dim;
+ PangoLayout *layout;
+
+ /* First, let's compute how many digits to the right of radix
+ * we need to print */
+ y = axis->major - floor(axis->major);
+ for (rdigits=0; rdigits <= 6; rdigits++) {
+ y *= 10;
+ if (y <= 0.000001)
+ break;
+ y = y - floor(y);
+ }
+ g_snprintf(str, sizeof(str), "%.*f", rdigits, label);
+ switch (dir) {
+ case AXIS_HORIZONTAL:
+ layout = gtk_widget_create_pango_layout(axis->g->drawing_area, str);
+ pango_layout_get_pixel_size(layout, &dim, NULL);
+ g_object_unref(G_OBJECT(layout));
+ break;
+ case AXIS_VERTICAL:
+ layout = gtk_widget_create_pango_layout(axis->g->drawing_area,
+ str);
+ pango_layout_get_pixel_size(layout, NULL, &dim);
+ g_object_unref(G_OBJECT(layout));
+ break;
+ default:
+ puts("initialize axis: an axis must be either horizontal or vertical");
+ return -1;
+ }
+ return dim;
+}
+
+static double axis_zoom_get(struct axis *axis, int dir)
+{
+ switch (dir) {
+ case AXIS_HORIZONTAL:
+ return axis->g->zoom.x;
+ case AXIS_VERTICAL:
+ return axis->g->zoom.y;
+ default:
+ return -1;
+ }
+}
+
+static void graph_select_segment(struct graph *g, int x, int y)
+{
+ struct element_list *list;
+ struct element *e;
+ guint num = 0;
+
+ debug(DBS_FENTRY) puts("graph_select_segment()");
+
+ x -= g->geom.x;
+ y = g->geom.height-1 - (y - g->geom.y);
+
+ set_busy_cursor(gtk_widget_get_window(g->drawing_area));
+
+ for (list=g->elists; list; list=list->next) {
+ for (e=list->elements; e->type != ELMT_NONE; e++) {
+ switch (e->type) {
+ case ELMT_RECT:
+ break;
+ case ELMT_LINE:
+ if (line_detect_collision(e, x, y)) {
+ num = e->parent->num;
+ }
+ break;
+ case ELMT_ELLIPSE:
+ if (ellipse_detect_collision(e, x, y)) {
+ num = e->parent->num;
+ }
+ break;
+ default:
+ break;
+ }
+ }
+ }
+
+ if (num) {
+ cf_goto_frame(&cfile, num);
+ }
+ unset_busy_cursor(gtk_widget_get_window(g->drawing_area), g->cross.draw);
+}
+
+static int line_detect_collision(struct element *e, int x, int y)
+{
+ int xx1, yy1, xx2, yy2;
+
+ if (e->p.line.dim.x1 < e->p.line.dim.x2) {
+ xx1 = (int )rint(e->p.line.dim.x1);
+ xx2 = (int )rint(e->p.line.dim.x2);
+ } else {
+ xx1 = (int )rint(e->p.line.dim.x2);
+ xx2 = (int )rint(e->p.line.dim.x1);
+ }
+ if (e->p.line.dim.y1 < e->p.line.dim.y2) {
+ yy1 = (int )rint(e->p.line.dim.y1);
+ yy2 = (int )rint(e->p.line.dim.y2);
+ } else {
+ yy1 = (int )rint(e->p.line.dim.y2);
+ yy2 = (int )rint(e->p.line.dim.y1);
+ }
+ /*
+ printf("line: (%d,%d)->(%d,%d), clicked: (%d,%d)\n", xx1, yy1, xx2, yy2, x, y);
+ */
+ if (((xx1 == x) && (xx2 == x) && (yy1 <= y) && (y <= yy2)) ||
+ ((yy1 == y) && (yy2 == y) && (xx1 <= x) && (x <= xx2)))
+ return TRUE;
+ else
+ return FALSE;
+}
+
+static int ellipse_detect_collision(struct element *e, int x, int y)
+{
+ int xx1, yy1, xx2, yy2;
+
+ xx1 = (int )rint(e->p.ellipse.dim.x);
+ xx2 = (int )rint(e->p.ellipse.dim.x + e->p.ellipse.dim.width);
+ yy1 = (int )rint(e->p.ellipse.dim.y - e->p.ellipse.dim.height);
+ yy2 = (int )rint(e->p.ellipse.dim.y);
+ /*
+ printf("ellipse: (%d,%d)->(%d,%d), clicked: (%d,%d)\n", xx1, yy1, xx2, yy2, x, y);
+ */
+ if ((xx1 <= x) && (x <= xx2) && (yy1 <= y) && (y <= yy2))
+ return TRUE;
+ else
+ return FALSE;
}
-static void cross_draw (struct graph *g, int x, int y)
+static void cross_draw(struct graph *g, int x, int y)
{
- /* Shouldn't draw twice onto the same position if haven't erased in the
- meantime! */
- if (g->cross.erase_needed && (g->cross.x == x) && (g->cross.y == y)) {
- return;
- }
+ /* Shouldn't draw twice onto the same position if haven't erased in the
+ meantime! */
+ if (g->cross.erase_needed && (g->cross.x == x) && (g->cross.y == y)) {
+ return;
+ }
+
+ /* Draw the cross */
+ if ((x > g->wp.x + 0.5) && (x < g->wp.x+g->wp.width) &&
+ (y > g->wp.y) && (y < g->wp.y+g->wp.height)) {
+
+ cairo_t *cr = gdk_cairo_create(gtk_widget_get_window(g->drawing_area));
+ gdk_cairo_set_source_color(cr, &g->s.tseq_tcptrace.seq_color);
+ cairo_set_line_width(cr, 1.0);
+
+ /* Horizonal line */
+ cairo_move_to(cr, g->wp.x, y);
+ cairo_line_to(cr, g->wp.x + g->wp.width, y);
+
+ /* Vertical line */
+ cairo_move_to(cr, x, g->wp.y);
+ cairo_line_to(cr, x, g->wp.y + g->wp.height);
+ cairo_stroke(cr);
+ cairo_destroy(cr);
+ }
+
+ g->cross.x = x;
+ g->cross.y = y;
+ g->cross.erase_needed = TRUE;
+}
+
+static void zoomrect_draw(struct graph *g, int x, int y)
+{
+ if ((x > g->wp.x + 0.5) && (x < g->wp.x+g->wp.width) &&
+ (y > g->wp.y) && (y < g->wp.y+g->wp.height)) {
+
+ cairo_t *cr = gdk_cairo_create(gtk_widget_get_window(g->drawing_area));
+ gdk_cairo_set_source_color(cr, &g->s.tseq_tcptrace.seq_color);
+ cairo_set_line_width(cr, 1.0);
+
+ /* Do outline of rect */
+ cairo_rectangle(cr, zoomrect.x, zoomrect.y, x-zoomrect.x, y-zoomrect.y);
+ cairo_stroke(cr);
+ cairo_destroy(cr);
+ }
+
+ g->zoomrect_erase_needed = TRUE;
+}
+
+static void zoomrect_erase(struct graph *g)
+{
+ /* Just redraw what is in the pixmap buffer */
+ graph_pixmap_display(g);
+ g->zoomrect_erase_needed = FALSE;
+}
+
+static void cross_erase(struct graph *g)
+{
+ int x = g->cross.x;
+ int y = g->cross.y;
+
+ g->cross.erase_needed = FALSE;
+
+ if ((x > g->wp.x) && (x < g->wp.x+g->wp.width) &&
+ (y >= g->wp.y) && (y < g->wp.y+g->wp.height)) {
+
+ /* Just redraw what is in the pixmap buffer */
+ graph_pixmap_display(g);
+ }
+}
+
+static void magnify_move(struct graph *g, int x, int y)
+{
+ struct ipoint pos, offsetpos;
+
+ get_mouse_position(g->toplevel, &pos.x, &pos.y, NULL);
+ g->magnify.x = pos.x + x - g->magnify.width/2;
+ g->magnify.y = pos.y + y - g->magnify.height/2;
+ offsetpos.x = g->magnify.x + g->magnify.offset.x;
+ offsetpos.x = offsetpos.x >= 0 ? offsetpos.x : 0;
+ offsetpos.y = g->magnify.y + g->magnify.offset.y;
+ offsetpos.y = offsetpos.y >= 0 ? offsetpos.y : 0;
+ magnify_get_geom(g, x, y);
+ magnify_draw(g);
+}
+
+static void magnify_create(struct graph *g, int x, int y)
+{
+ struct graph *mg;
+ struct ipoint pos, offsetpos;
+ GdkEvent *e = NULL;
+ struct element_list *list, *new_list;
+
+ mg = g->magnify.g = (struct graph * )g_malloc(sizeof(struct graph));
+ memcpy((void * )mg, (void * )g, sizeof(struct graph));
- /* Draw the cross */
- if (x > g->wp.x+0.5 && x < g->wp.x+g->wp.width &&
- y > g->wp.y && y < g->wp.y+g->wp.height) {
+ mg->toplevel = dlg_window_new("tcp graph magnify");
+ mg->drawing_area = mg->toplevel;
+ gtk_window_set_default_size(GTK_WINDOW(mg->toplevel), g->magnify.width, g->magnify.height);
+ gtk_widget_set_events(mg->drawing_area, GDK_EXPOSURE_MASK
+ /* | GDK_ENTER_NOTIFY_MASK */
+ /* | GDK_ALL_EVENTS_MASK */
+ );
+
+ mg->wp.x = 0;
+ mg->wp.y = 0;
+ mg->wp.width = g->magnify.width;
+ mg->wp.height = g->magnify.height;
+ mg->geom.width = (int )rint(g->geom.width * g->magnify.zoom.x);
+ mg->geom.height = (int )rint(g->geom.height * g->magnify.zoom.y);
+ mg->zoom.x = (mg->geom.width - 1) / g->bounds.width;
+ mg->zoom.y = (mg->geom.height- 1) / g->bounds.height;
+
+ /* in order to keep original element lists intact we need our own */
+ graph_element_lists_initialize(mg);
+ list = g->elists->next;
+ new_list = mg->elists;
+ for ( ; list; list=list->next) {
+ new_list->next = (struct element_list * )g_malloc(sizeof(struct element_list));
+ new_list = new_list->next;
+ new_list->next = NULL;
+ new_list->elements = NULL;
+ }
+ graph_element_lists_make(mg);
- cairo_t *cr = gdk_cairo_create(gtk_widget_get_window(g->drawing_area));
- gdk_cairo_set_source_color(cr, &g->s.tseq_tcptrace.seq_color);
- cairo_set_line_width(cr, 1.0);
-
- /* Horizonal line */
- cairo_move_to(cr, g->wp.x, y);
- cairo_line_to(cr, g->wp.x + g->wp.width, y);
-
- /* Vertical line */
- cairo_move_to(cr, x, g->wp.y);
- cairo_line_to(cr, x, g->wp.y + g->wp.height);
- cairo_stroke(cr);
- cairo_destroy(cr);
- }
-
- g->cross.x = x;
- g->cross.y = y;
- g->cross.erase_needed = TRUE;
-}
-
-static void zoomrect_draw (struct graph *g, int x, int y)
-{
- if (x > g->wp.x+0.5 && x < g->wp.x+g->wp.width &&
- y > g->wp.y && y < g->wp.y+g->wp.height) {
-
- cairo_t *cr = gdk_cairo_create(gtk_widget_get_window(g->drawing_area));
- gdk_cairo_set_source_color(cr, &g->s.tseq_tcptrace.seq_color);
- cairo_set_line_width(cr, 1.0);
-
- /* Do outline of rect */
- cairo_rectangle(cr, zoomrect.x, zoomrect.y, x-zoomrect.x, y-zoomrect.y);
- cairo_stroke(cr);
- cairo_destroy(cr);
- }
-
- g->zoomrect_erase_needed = TRUE;
-}
-
-static void zoomrect_erase (struct graph *g)
-{
- /* Just redraw what is in the pixmap buffer */
- graph_pixmap_display(g);
- g->zoomrect_erase_needed = FALSE;
-}
-
-static void cross_erase (struct graph *g)
-{
- int x = g->cross.x;
- int y = g->cross.y;
-
- g->cross.erase_needed = FALSE;
-
- if (x > g->wp.x && x < g->wp.x+g->wp.width &&
- y >= g->wp.y && y < g->wp.y+g->wp.height) {
-
- /* Just redraw what is in the pixmap buffer */
- graph_pixmap_display(g);
- }
-}
-
-static void magnify_move (struct graph *g, int x, int y)
-{
- struct ipoint pos, offsetpos;
-
- get_mouse_position(g->toplevel, &pos.x, &pos.y, NULL);
- g->magnify.x = pos.x + x - g->magnify.width/2;
- g->magnify.y = pos.y + y - g->magnify.height/2;
- offsetpos.x = g->magnify.x + g->magnify.offset.x;
- offsetpos.x = offsetpos.x >= 0 ? offsetpos.x : 0;
- offsetpos.y = g->magnify.y + g->magnify.offset.y;
- offsetpos.y = offsetpos.y >= 0 ? offsetpos.y : 0;
- magnify_get_geom (g, x, y);
- magnify_draw (g);
-}
-
-static void magnify_create (struct graph *g, int x, int y)
-{
- struct graph *mg;
- struct element_list *list, *new_list;
- struct ipoint pos, offsetpos;
- GdkEvent *e=NULL;
-
- mg = g->magnify.g = (struct graph * )g_malloc (sizeof (struct graph));
- memcpy ((void * )mg, (void * )g, sizeof (struct graph));
-
- mg->toplevel = dlg_window_new("tcp graph magnify");
- mg->drawing_area = mg->toplevel;
- gtk_window_set_default_size(GTK_WINDOW(mg->toplevel), g->magnify.width, g->magnify.height);
- gtk_widget_set_events (mg->drawing_area, GDK_EXPOSURE_MASK
- /* | GDK_ENTER_NOTIFY_MASK */
- /* | GDK_ALL_EVENTS_MASK */
- );
-
- mg->wp.x = 0;
- mg->wp.y = 0;
- mg->wp.width = g->magnify.width;
- mg->wp.height = g->magnify.height;
- mg->geom.width = (int )rint (g->geom.width * g->magnify.zoom.x);
- mg->geom.height = (int )rint (g->geom.height * g->magnify.zoom.y);
- mg->zoom.x = (mg->geom.width - 1) / g->bounds.width;
- mg->zoom.y = (mg->geom.height- 1) / g->bounds.height;
-
- /* in order to keep original element lists intact we need our own */
- graph_element_lists_initialize (mg);
- list = g->elists->next;
- new_list = mg->elists;
- for ( ; list; list=list->next) {
- new_list->next =
- (struct element_list * )g_malloc (sizeof (struct element_list));
- new_list = new_list->next;
- new_list->next = NULL;
- new_list->elements = NULL;
- }
- graph_element_lists_make (mg);
-
- get_mouse_position(g->toplevel, &pos.x, &pos.y, NULL);
- g->magnify.x = pos.x + x - g->magnify.width/2;
- g->magnify.y = pos.y + y - g->magnify.height/2;
- offsetpos.x = g->magnify.x + g->magnify.offset.x;
- offsetpos.x = offsetpos.x >= 0 ? offsetpos.x : 0;
- offsetpos.y = g->magnify.y + g->magnify.offset.y;
- offsetpos.y = offsetpos.y >= 0 ? offsetpos.y : 0;
- gtk_window_set_position (GTK_WINDOW(mg->drawing_area), GTK_WIN_POS_NONE);
- magnify_get_geom (g, x, y);
-
- gtk_widget_show (mg->drawing_area);
-
- /* we need to wait for the first expose event before we start drawing */
- while (!gdk_events_pending ());
- do {
- e = gdk_event_get ();
- if (e) {
- if (e->any.type == GDK_EXPOSE) {
- gdk_event_free (e);
- break;
- }
- gdk_event_free (e);
- }
- } while (e);
+ get_mouse_position(g->toplevel, &pos.x, &pos.y, NULL);
+ g->magnify.x = pos.x + x - g->magnify.width/2;
+ g->magnify.y = pos.y + y - g->magnify.height/2;
+ offsetpos.x = g->magnify.x + g->magnify.offset.x;
+ offsetpos.x = offsetpos.x >= 0 ? offsetpos.x : 0;
+ offsetpos.y = g->magnify.y + g->magnify.offset.y;
+ offsetpos.y = offsetpos.y >= 0 ? offsetpos.y : 0;
+ gtk_window_set_position(GTK_WINDOW(mg->drawing_area), GTK_WIN_POS_NONE);
+ magnify_get_geom(g, x, y);
+
+ gtk_widget_show(mg->drawing_area);
+
+ /* we need to wait for the first expose event before we start drawing */
+ while (!gdk_events_pending());
+ do {
+ e = gdk_event_get();
+ if (e) {
+ if (e->any.type == GDK_EXPOSE) {
+ gdk_event_free(e);
+ break;
+ }
+ gdk_event_free(e);
+ }
+ } while (e);
#if GTK_CHECK_VERSION(2,22,0)
- mg->surface[0] = mg->surface[1] = NULL;
+ mg->surface[0] = mg->surface[1] = NULL;
#else
- mg->pixmap[0] = mg->pixmap[1] = NULL;
+ mg->pixmap[0] = mg->pixmap[1] = NULL;
#endif /* GTK_CHECK_VERSION(2,22,0) */
- graph_pixmaps_create (mg);
- magnify_draw (g);
- g->magnify.active = 1;
+ graph_pixmaps_create(mg);
+ magnify_draw(g);
+ g->magnify.active = 1;
}
-static void magnify_destroy (struct graph *g)
+static void magnify_destroy(struct graph *g)
{
- struct element_list *list;
- struct graph *mg = g->magnify.g;
+ struct element_list *list;
+ struct graph *mg = g->magnify.g;
- window_destroy (GTK_WIDGET (mg->drawing_area));
+ window_destroy(GTK_WIDGET(mg->drawing_area));
#if GTK_CHECK_VERSION(2,22,0)
- if(mg->surface[0]){
- cairo_surface_destroy (mg->surface[0]);
- }
- if(mg->surface[1]){
- cairo_surface_destroy (mg->surface[1]);
- }
+ if (mg->surface[0]) {
+ cairo_surface_destroy(mg->surface[0]);
+ }
+ if (mg->surface[1]) {
+ cairo_surface_destroy(mg->surface[1]);
+ }
#else
- g_object_unref (mg->pixmap[0]);
- g_object_unref (mg->pixmap[1]);
+ g_object_unref(mg->pixmap[0]);
+ g_object_unref(mg->pixmap[1]);
#endif /* GTK_CHECK_VERSION(2,22,0) */
- for (list=mg->elists; list; list=list->next)
- g_free (list->elements);
+ for (list=mg->elists; list; list=list->next)
+ g_free(list->elements);
- if (mg->elists) {
- while (mg->elists->next) {
- list = mg->elists->next->next;
- g_free (mg->elists->next);
- mg->elists->next = list;
- }
- }
- g_free (g->magnify.g);
- g->magnify.active = 0;
+ if (mg->elists) {
+ while (mg->elists->next) {
+ list = mg->elists->next->next;
+ g_free(mg->elists->next);
+ mg->elists->next = list;
+ }
+ }
+ g_free(g->magnify.g);
+ g->magnify.active = 0;
}
-static void magnify_get_geom (struct graph *g, int x, int y)
+static void magnify_get_geom(struct graph *g, int x, int y)
{
- int posx, posy;
+ int posx, posy;
- get_mouse_position(g->toplevel, &posx, &posy, NULL);
+ get_mouse_position(g->toplevel, &posx, &posy, NULL);
- g->magnify.g->geom.x = g->geom.x;
- g->magnify.g->geom.y = g->geom.y;
+ g->magnify.g->geom.x = g->geom.x;
+ g->magnify.g->geom.y = g->geom.y;
- g->magnify.g->geom.x -=
- (int )rint ((g->magnify.g->geom.width - g->geom.width) *
- ((x-g->geom.x)/(double )g->geom.width));
- g->magnify.g->geom.y -=
- (int )rint ((g->magnify.g->geom.height - g->geom.height) *
- ((y-g->geom.y)/(double )g->geom.height));
+ g->magnify.g->geom.x -= (int )rint((g->magnify.g->geom.width - g->geom.width) *
+ ((x-g->geom.x)/(double )g->geom.width));
+ g->magnify.g->geom.y -= (int )rint((g->magnify.g->geom.height - g->geom.height) *
+ ((y-g->geom.y)/(double )g->geom.height));
- /* we have coords of origin of graph relative to origin of g->toplevel.
- * now we need them to relate to origin of magnify window */
- g->magnify.g->geom.x -= (g->magnify.x - posx);
- g->magnify.g->geom.y -= (g->magnify.y - posy);
+ /* we have coords of origin of graph relative to origin of g->toplevel.
+ * now we need them to relate to origin of magnify window */
+ g->magnify.g->geom.x -= (g->magnify.x - posx);
+ g->magnify.g->geom.y -= (g->magnify.y - posy);
}
-static void magnify_draw (struct graph *g)
+static void magnify_draw(struct graph *g)
{
- cairo_t *cr;
- int not_disp = 1 ^ g->magnify.g->displayed;
+ cairo_t *cr;
+ int not_disp = 1 ^ g->magnify.g->displayed;
- graph_pixmap_draw (g->magnify.g);
- /* graph pixmap is almost ready, just add border */
+ graph_pixmap_draw(g->magnify.g);
+ /* graph pixmap is almost ready, just add border */
#if GTK_CHECK_VERSION(2,22,0)
- cr = cairo_create (g->magnify.g->surface[not_disp]);
+ cr = cairo_create(g->magnify.g->surface[not_disp]);
#else
- cr = gdk_cairo_create (g->magnify.g->pixmap[not_disp]);
+ cr = gdk_cairo_create(g->magnify.g->pixmap[not_disp]);
#endif /* GTK_CHECK_VERSION(2,22,0) */
- cairo_set_line_width (cr, 1.0);
- cairo_move_to(cr, 0, 0);
- cairo_line_to(cr, g->magnify.width - 1, 0);
- cairo_stroke(cr);
-
- cairo_move_to(cr, g->magnify.width - 1, 0);
- cairo_line_to(cr, g->magnify.width - 1, g->magnify.height);
- cairo_stroke(cr);
-
- cairo_move_to(cr, 0, 0);
- cairo_line_to(cr, 0,g->magnify.height - 1);
- cairo_stroke(cr);
-
- cairo_move_to(cr, 0, g->magnify.height - 1);
- cairo_line_to(cr, g->magnify.width - 1, g->magnify.height - 1);
- cairo_stroke(cr);
- cairo_destroy(cr);
-
- graph_pixmaps_switch (g->magnify.g);
- graph_pixmap_display (g->magnify.g);
-
-}
-
-static gboolean configure_event (GtkWidget *widget _U_, GdkEventConfigure *event, gpointer user_data)
-{
- struct graph *g = user_data;
- struct {
- double x, y;
- } zoom;
- int cur_g_width, cur_g_height;
- int cur_wp_width, cur_wp_height;
-
- debug(DBS_FENTRY) puts ("configure_event()");
-
- cur_wp_width = g->wp.width;
- cur_wp_height = g->wp.height;
- g->wp.width = event->width - g->y_axis->p.width - RMARGIN_WIDTH;
- g->wp.height = event->height - g->x_axis->p.height - g->wp.y;
- g->x_axis->s.width = g->wp.width;
- g->x_axis->p.width = g->wp.width + RMARGIN_WIDTH;
- g->y_axis->p.height = g->wp.height + g->wp.y;
- g->y_axis->s.height = g->wp.height;
- g->x_axis->p.y = g->y_axis->p.height;
- zoom.x = (double )g->wp.width / cur_wp_width;
- zoom.y = (double )g->wp.height / cur_wp_height;
- cur_g_width = g->geom.width;
- cur_g_height = g->geom.height;
- g->geom.width = (int )rint (g->geom.width * zoom.x);
- g->geom.height = (int )rint (g->geom.height * zoom.y);
- g->zoom.x = (double )(g->geom.width - 1) / g->bounds.width;
- g->zoom.y = (double )(g->geom.height -1) / g->bounds.height;
- /* g->zoom.initial.x = g->zoom.x; */
- /* g->zoom.initial.y = g->zoom.y; */
-
- g->geom.x = (int) (g->wp.x - (double )g->geom.width/cur_g_width *
- (g->wp.x - g->geom.x));
- g->geom.y = (int) (g->wp.y - (double )g->geom.height/cur_g_height *
- (g->wp.y - g->geom.y));
+ cairo_set_line_width(cr, 1.0);
+ cairo_move_to(cr, 0, 0);
+ cairo_line_to(cr, g->magnify.width - 1, 0);
+ cairo_stroke(cr);
+
+ cairo_move_to(cr, g->magnify.width - 1, 0);
+ cairo_line_to(cr, g->magnify.width - 1, g->magnify.height);
+ cairo_stroke(cr);
+
+ cairo_move_to(cr, 0, 0);
+ cairo_line_to(cr, 0, g->magnify.height - 1);
+ cairo_stroke(cr);
+
+ cairo_move_to(cr, 0, g->magnify.height - 1);
+ cairo_line_to(cr, g->magnify.width - 1, g->magnify.height - 1);
+ cairo_stroke(cr);
+ cairo_destroy(cr);
+
+ graph_pixmaps_switch(g->magnify.g);
+ graph_pixmap_display(g->magnify.g);
+
+}
+
+static gboolean configure_event(GtkWidget *widget _U_, GdkEventConfigure *event, gpointer user_data)
+{
+ struct graph *g = user_data;
+ struct {
+ double x, y;
+ } zoom;
+ int cur_g_width, cur_g_height;
+ int cur_wp_width, cur_wp_height;
+
+ debug(DBS_FENTRY) puts("configure_event()");
+
+ cur_wp_width = g->wp.width;
+ cur_wp_height = g->wp.height;
+ g->wp.width = event->width - g->y_axis->p.width - RMARGIN_WIDTH;
+ g->wp.height = event->height - g->x_axis->p.height - g->wp.y;
+ g->x_axis->s.width = g->wp.width;
+ g->x_axis->p.width = g->wp.width + RMARGIN_WIDTH;
+ g->y_axis->p.height = g->wp.height + g->wp.y;
+ g->y_axis->s.height = g->wp.height;
+ g->x_axis->p.y = g->y_axis->p.height;
+ zoom.x = (double )g->wp.width / cur_wp_width;
+ zoom.y = (double )g->wp.height / cur_wp_height;
+ cur_g_width = g->geom.width;
+ cur_g_height = g->geom.height;
+ g->geom.width = (int )rint(g->geom.width * zoom.x);
+ g->geom.height = (int )rint(g->geom.height * zoom.y);
+ g->zoom.x = (double )(g->geom.width - 1) / g->bounds.width;
+ g->zoom.y = (double )(g->geom.height -1) / g->bounds.height;
+ /* g->zoom.initial.x = g->zoom.x; */
+ /* g->zoom.initial.y = g->zoom.y; */
+
+ g->geom.x = (int) (g->wp.x - (double )g->geom.width/cur_g_width *
+ (g->wp.x - g->geom.x));
+ g->geom.y = (int) (g->wp.y - (double )g->geom.height/cur_g_height *
+ (g->wp.y - g->geom.y));
#if 0
- printf ("configure: graph: (%d,%d), (%d,%d); viewport: (%d,%d), (%d,%d); "
- "zooms: (%f,%f)\n", g->geom.x, g->geom.y, g->geom.width,
- g->geom.height, g->wp.x, g->wp.y, g->wp.width, g->wp.height,
- g->zoom.x, g->zoom.y);
+ printf("configure: graph: (%d,%d), (%d,%d); viewport: (%d,%d), (%d,%d);"
+ " zooms: (%f,%f)\n", g->geom.x, g->geom.y, g->geom.width,
+ g->geom.height, g->wp.x, g->wp.y, g->wp.width, g->wp.height,
+ g->zoom.x, g->zoom.y);
#endif
- update_zoom_spins (g);
- graph_element_lists_make (g);
- graph_pixmaps_create (g);
- graph_title_pixmap_create (g);
- axis_pixmaps_create (g->y_axis);
- axis_pixmaps_create (g->x_axis);
- /* we don't do actual drawing here; we leave it to expose handler */
- graph_pixmap_draw (g);
- graph_pixmaps_switch (g);
- graph_title_pixmap_draw (g);
- h_axis_pixmap_draw (g->x_axis);
- axis_pixmaps_switch (g->x_axis);
- v_axis_pixmap_draw (g->y_axis);
- axis_pixmaps_switch (g->y_axis);
- return TRUE;
+ update_zoom_spins(g);
+ graph_element_lists_make(g);
+ graph_pixmaps_create(g);
+ graph_title_pixmap_create(g);
+ axis_pixmaps_create(g->y_axis);
+ axis_pixmaps_create(g->x_axis);
+ /* we don't do actual drawing here; we leave it to expose handler */
+ graph_pixmap_draw(g);
+ graph_pixmaps_switch(g);
+ graph_title_pixmap_draw(g);
+ h_axis_pixmap_draw(g->x_axis);
+ axis_pixmaps_switch(g->x_axis);
+ v_axis_pixmap_draw(g->y_axis);
+ axis_pixmaps_switch(g->y_axis);
+ return TRUE;
}
#if GTK_CHECK_VERSION(3,0,0)
static gboolean
draw_event(GtkWidget *widget _U_, cairo_t *cr, gpointer user_data)
{
- struct graph *g = user_data;
+ struct graph *g = user_data;
- debug(DBS_FENTRY) puts ("draw_event()");
+ debug(DBS_FENTRY) puts("draw_event()");
- /* lower left corner */
- cairo_set_source_rgb (cr, 1, 1, 1);
- cairo_rectangle (cr, 0, g->wp.y + g->wp.height, g->y_axis->p.width, g->x_axis->p.height);
- cairo_fill (cr);
+ /* lower left corner */
+ cairo_set_source_rgb(cr, 1, 1, 1);
+ cairo_rectangle(cr, 0, g->wp.y + g->wp.height, g->y_axis->p.width, g->x_axis->p.height);
+ cairo_fill(cr);
- /* right margin */
- cairo_rectangle (cr, g->wp.x + g->wp.width, g->wp.y, RMARGIN_WIDTH, g->wp.height);
- cairo_fill (cr);
+ /* right margin */
+ cairo_rectangle(cr, g->wp.x + g->wp.width, g->wp.y, RMARGIN_WIDTH, g->wp.height);
+ cairo_fill(cr);
- /* Should these routines be copied here, or be given the cairo_t ?? */
- graph_pixmap_display (g);
- graph_title_pixmap_display (g);
- axis_pixmap_display (g->x_axis);
- axis_pixmap_display (g->y_axis);
+ /* Should these routines be copied here, or be given the cairo_t ?? */
+ graph_pixmap_display(g);
+ graph_title_pixmap_display(g);
+ axis_pixmap_display(g->x_axis);
+ axis_pixmap_display(g->y_axis);
- return TRUE;
+ return TRUE;
}
#else
-static gboolean expose_event (GtkWidget *widget, GdkEventExpose *event, gpointer user_data)
+static gboolean expose_event(GtkWidget *widget, GdkEventExpose *event, gpointer user_data)
{
- struct graph *g = user_data;
- cairo_t *cr;
+ struct graph *g = user_data;
+ cairo_t *cr;
- debug(DBS_FENTRY) puts ("expose_event()");
+ debug(DBS_FENTRY) puts("expose_event()");
- if (event->count)
- return TRUE;
+ if (event->count)
+ return TRUE;
- /* lower left corner */
- cr = gdk_cairo_create (gtk_widget_get_window(widget));
- cairo_set_source_rgb (cr, 1, 1, 1);
- cairo_rectangle (cr, 0, g->wp.y + g->wp.height, g->y_axis->p.width, g->x_axis->p.height);
- cairo_fill (cr);
- cairo_destroy(cr);
- cr = NULL;
+ /* lower left corner */
+ cr = gdk_cairo_create(gtk_widget_get_window(widget));
+ cairo_set_source_rgb(cr, 1, 1, 1);
+ cairo_rectangle(cr, 0, g->wp.y + g->wp.height, g->y_axis->p.width, g->x_axis->p.height);
+ cairo_fill(cr);
+ cairo_destroy(cr);
+ cr = NULL;
- /* right margin */
- cr = gdk_cairo_create (gtk_widget_get_window(widget));
- cairo_set_source_rgb (cr, 1, 1, 1);
- cairo_rectangle (cr, g->wp.x + g->wp.width, g->wp.y, RMARGIN_WIDTH, g->wp.height);
- cairo_fill (cr);
- cairo_destroy(cr);
- cr = NULL;
+ /* right margin */
+ cr = gdk_cairo_create(gtk_widget_get_window(widget));
+ cairo_set_source_rgb(cr, 1, 1, 1);
+ cairo_rectangle(cr, g->wp.x + g->wp.width, g->wp.y, RMARGIN_WIDTH, g->wp.height);
+ cairo_fill(cr);
+ cairo_destroy(cr);
+ cr = NULL;
- graph_pixmap_display (g);
- graph_title_pixmap_display (g);
- axis_pixmap_display (g->x_axis);
- axis_pixmap_display (g->y_axis);
+ graph_pixmap_display(g);
+ graph_title_pixmap_display(g);
+ axis_pixmap_display(g->x_axis);
+ axis_pixmap_display(g->y_axis);
- return TRUE;
+ return TRUE;
}
#endif
@@ -3291,727 +3297,727 @@ static void
perform_zoom(struct graph *g, struct zoomfactor *zf,
int origin_x, int origin_y, int redraw)
{
- int cur_width = g->geom.width, cur_height = g->geom.height;
-
- /* Multiply by x and y factors */
- g->geom.width = (int )rint (g->geom.width * zf->x);
- g->geom.height = (int )rint (g->geom.height * zf->y);
-
- /* If already fully-zoomed out, don't waste time re-drawing */
- if ((g->geom.width <= g->wp.width) &&
- (g->geom.height <= g->wp.height)) {
- return;
- }
-
- if (g->geom.width < g->wp.width) {
- g->geom.width = g->wp.width;
- }
- if (g->geom.height < g->wp.height) {
- g->geom.height = g->wp.height;
- }
-
- /* Divide to work out new zoom */
- g->zoom.x = (g->geom.width - 1) / g->bounds.width;
- g->zoom.y = (g->geom.height- 1) / g->bounds.height;
-
- /* Move origin to keep mouse position at centre of view */
- g->geom.x -= (int)rint ((g->geom.width - cur_width) *
- ((origin_x - g->geom.x)/(double )cur_width));
- g->geom.y -= (int)rint ((g->geom.height - cur_height) *
- ((origin_y - g->geom.y)/(double )cur_height));
-
- if (g->geom.x > g->wp.x)
- g->geom.x = g->wp.x;
- if (g->geom.y > g->wp.y)
- g->geom.y = g->wp.y;
- if (g->wp.x + g->wp.width > g->geom.x + g->geom.width)
- g->geom.x = g->wp.width + g->wp.x - g->geom.width;
- if (g->wp.y + g->wp.height > g->geom.y + g->geom.height)
- g->geom.y = g->wp.height + g->wp.y - g->geom.height;
-
- if (redraw == ZOOM_NOREDRAW)
- return;
-
- graph_element_lists_make(g);
- g->cross.erase_needed = FALSE;
- graph_display(g);
- axis_display(g->y_axis);
- axis_display(g->x_axis);
- update_zoom_spins(g);
-
- if (g->cross.draw) {
- g->cross.erase_needed = FALSE;
- cross_draw(g, origin_x, origin_y);
- }
+ int cur_width = g->geom.width, cur_height = g->geom.height;
+
+ /* Multiply by x and y factors */
+ g->geom.width = (int )rint(g->geom.width * zf->x);
+ g->geom.height = (int )rint(g->geom.height * zf->y);
+
+ /* If already fully-zoomed out, don't waste time re-drawing */
+ if ((g->geom.width <= g->wp.width) &&
+ (g->geom.height <= g->wp.height)) {
+ return;
+ }
+
+ if (g->geom.width < g->wp.width) {
+ g->geom.width = g->wp.width;
+ }
+ if (g->geom.height < g->wp.height) {
+ g->geom.height = g->wp.height;
+ }
+
+ /* Divide to work out new zoom */
+ g->zoom.x = (g->geom.width - 1) / g->bounds.width;
+ g->zoom.y = (g->geom.height- 1) / g->bounds.height;
+
+ /* Move origin to keep mouse position at centre of view */
+ g->geom.x -= (int)rint((g->geom.width - cur_width) *
+ ((origin_x - g->geom.x)/(double )cur_width));
+ g->geom.y -= (int)rint((g->geom.height - cur_height) *
+ ((origin_y - g->geom.y)/(double )cur_height));
+
+ if (g->geom.x > g->wp.x)
+ g->geom.x = g->wp.x;
+ if (g->geom.y > g->wp.y)
+ g->geom.y = g->wp.y;
+ if (g->wp.x + g->wp.width > g->geom.x + g->geom.width)
+ g->geom.x = g->wp.width + g->wp.x - g->geom.width;
+ if (g->wp.y + g->wp.height > g->geom.y + g->geom.height)
+ g->geom.y = g->wp.height + g->wp.y - g->geom.height;
+
+ if (redraw == ZOOM_NOREDRAW)
+ return;
+
+ graph_element_lists_make(g);
+ g->cross.erase_needed = FALSE;
+ graph_display(g);
+ axis_display(g->y_axis);
+ axis_display(g->x_axis);
+ update_zoom_spins(g);
+
+ if (g->cross.draw) {
+ g->cross.erase_needed = FALSE;
+ cross_draw(g, origin_x, origin_y);
+ }
}
static void
get_zoomfactor(struct graph *g, struct zoomfactor *zf, double step_x,
- double step_y)
-{
- if (g->zoom.flags & ZOOM_OUT) {
- /*
- * If can't zoom out anymore don't waste time redrawing
- * the whole graph!
- */
- if ((g->geom.height <= g->wp.height) &&
- (g->geom.width <= g->wp.width)) {
- zf->x = 1.0;
- zf->y = 1.0;
- return;
- }
- if (g->zoom.flags & ZOOM_HLOCK)
- zf->x = 1.0;
- else
- zf->x = 1 / step_x;
- if (g->zoom.flags & ZOOM_VLOCK)
- zf->y = 1.0;
- else
- zf->y = 1 / step_y;
- } else {
- if (g->zoom.flags & ZOOM_HLOCK)
- zf->x = 1.0;
- else
- zf->x = step_x;
- if (g->zoom.flags & ZOOM_VLOCK)
- zf->y = 1.0;
- else
- zf->y = step_y;
- }
+ double step_y)
+{
+ if (g->zoom.flags & ZOOM_OUT) {
+ /*
+ * If can't zoom out anymore don't waste time redrawing
+ * the whole graph!
+ */
+ if ((g->geom.height <= g->wp.height) &&
+ (g->geom.width <= g->wp.width)) {
+ zf->x = 1.0;
+ zf->y = 1.0;
+ return;
+ }
+ if (g->zoom.flags & ZOOM_HLOCK)
+ zf->x = 1.0;
+ else
+ zf->x = 1 / step_x;
+ if (g->zoom.flags & ZOOM_VLOCK)
+ zf->y = 1.0;
+ else
+ zf->y = 1 / step_y;
+ } else {
+ if (g->zoom.flags & ZOOM_HLOCK)
+ zf->x = 1.0;
+ else
+ zf->x = step_x;
+ if (g->zoom.flags & ZOOM_VLOCK)
+ zf->y = 1.0;
+ else
+ zf->y = step_y;
+ }
}
static void
do_zoom_rectangle(struct graph *g, struct irect lcl_zoomrect)
{
- int cur_width = g->wp.width, cur_height = g->wp.height;
- struct irect geom1 = g->geom;
- struct zoomfactor factor;
-
- /* Left hand too much to the right */
- if (lcl_zoomrect.x > g->wp.x + g->wp.width)
- return;
- /* Right hand not far enough */
- if (lcl_zoomrect.x + lcl_zoomrect.width < g->wp.x)
- return;
- /* Left hand too much to the left */
- if (lcl_zoomrect.x < g->wp.x) {
- int dx = g->wp.x - lcl_zoomrect.x;
- lcl_zoomrect.x += dx;
- lcl_zoomrect.width -= dx;
- }
- /* Right hand too much to the right */
- if (lcl_zoomrect.x + lcl_zoomrect.width > g->wp.x + g->wp.width) {
- int dx = lcl_zoomrect.width + lcl_zoomrect.x - g->wp.x - g->wp.width;
- lcl_zoomrect.width -= dx;
- }
-
- /* Top too low */
- if (lcl_zoomrect.y > g->wp.y + g->wp.height)
- return;
- /* Bottom too high */
- if (lcl_zoomrect.y + lcl_zoomrect.height < g->wp.y)
- return;
- /* Top too high */
- if (lcl_zoomrect.y < g->wp.y) {
- int dy = g->wp.y - lcl_zoomrect.y;
- lcl_zoomrect.y += dy;
- lcl_zoomrect.height -= dy;
- }
- /* Bottom too low */
- if (lcl_zoomrect.y + lcl_zoomrect.height > g->wp.y + g->wp.height) {
- int dy = lcl_zoomrect.height + lcl_zoomrect.y - g->wp.y - g->wp.height;
- lcl_zoomrect.height -= dy;
- }
+ int cur_width = g->wp.width, cur_height = g->wp.height;
+ struct irect geom1 = g->geom;
+ struct zoomfactor factor;
+
+ /* Left hand too much to the right */
+ if (lcl_zoomrect.x > g->wp.x + g->wp.width)
+ return;
+ /* Right hand not far enough */
+ if (lcl_zoomrect.x + lcl_zoomrect.width < g->wp.x)
+ return;
+ /* Left hand too much to the left */
+ if (lcl_zoomrect.x < g->wp.x) {
+ int dx = g->wp.x - lcl_zoomrect.x;
+ lcl_zoomrect.x += dx;
+ lcl_zoomrect.width -= dx;
+ }
+ /* Right hand too much to the right */
+ if (lcl_zoomrect.x + lcl_zoomrect.width > g->wp.x + g->wp.width) {
+ int dx = lcl_zoomrect.width + lcl_zoomrect.x - g->wp.x - g->wp.width;
+ lcl_zoomrect.width -= dx;
+ }
+
+ /* Top too low */
+ if (lcl_zoomrect.y > g->wp.y + g->wp.height)
+ return;
+ /* Bottom too high */
+ if (lcl_zoomrect.y + lcl_zoomrect.height < g->wp.y)
+ return;
+ /* Top too high */
+ if (lcl_zoomrect.y < g->wp.y) {
+ int dy = g->wp.y - lcl_zoomrect.y;
+ lcl_zoomrect.y += dy;
+ lcl_zoomrect.height -= dy;
+ }
+ /* Bottom too low */
+ if (lcl_zoomrect.y + lcl_zoomrect.height > g->wp.y + g->wp.height) {
+ int dy = lcl_zoomrect.height + lcl_zoomrect.y - g->wp.y - g->wp.height;
+ lcl_zoomrect.height -= dy;
+ }
/*
- printf("before:\n"
- "\tgeom: (%d, %d)+(%d x %d)\n"
+ printf("before:\n"
+ "\tgeom: (%d, %d)+(%d x %d)\n"
*/
- get_zoomfactor(g, &factor, (double)cur_width / lcl_zoomrect.width,
- (double)cur_height / lcl_zoomrect.height);
+ get_zoomfactor(g, &factor, (double)cur_width / lcl_zoomrect.width,
+ (double)cur_height / lcl_zoomrect.height);
/*
- printf("Zoomfactor: %f x %f\n", factor.x, factor.y);
+ printf("Zoomfactor: %f x %f\n", factor.x, factor.y);
*/
- perform_zoom(g, &factor,
- lcl_zoomrect.x, lcl_zoomrect.y,
- ZOOM_NOREDRAW);
+ perform_zoom(g, &factor,
+ lcl_zoomrect.x, lcl_zoomrect.y,
+ ZOOM_NOREDRAW);
/*
- printf("middle:\n"
- "\tgeom: (%d, %d)+(%d x %d)\n"
- "\twp: (%d, %d)+(%d x %d)\n"
- "\tzoomrect: (%d, %d)+(%d x %d)\n",
- g->geom.x, g->geom.y,
- g->geom.width, g->geom.height,
- g->wp.x, g->wp.y, g->wp.width, g->wp.height,
- lcl_zoomrect.x, lcl_zoomrect.y, lcl_zoomrect.width, lcl_zoomrect.height);
+ printf("middle:\n"
+ "\tgeom: (%d, %d)+(%d x %d)\n"
+ "\twp: (%d, %d)+(%d x %d)\n"
+ "\tzoomrect: (%d, %d)+(%d x %d)\n",
+ g->geom.x, g->geom.y,
+ g->geom.width, g->geom.height,
+ g->wp.x, g->wp.y, g->wp.width, g->wp.height,
+ lcl_zoomrect.x, lcl_zoomrect.y, lcl_zoomrect.width, lcl_zoomrect.height);
*/
- g->geom.x = (int)(geom1.x * (1 + factor.x) -
- lcl_zoomrect.x * factor.x - (geom1.x - g->wp.x));
- g->geom.y = (int)(geom1.y * (1 + factor.y) -
- lcl_zoomrect.y * factor.y - (geom1.y - g->wp.y));
+ g->geom.x = (int)(geom1.x * (1 + factor.x) -
+ lcl_zoomrect.x * factor.x - (geom1.x - g->wp.x));
+ g->geom.y = (int)(geom1.y * (1 + factor.y) -
+ lcl_zoomrect.y * factor.y - (geom1.y - g->wp.y));
/*
- printf("after:\n"
- "\tgeom: (%d, %d)+(%d x %d)\n"
- "\twp: (%d, %d)+(%d x %d)\n"
- "\tzoomrect: (%d, %d)+(%d x %d)\n",
- g->geom.x, g->geom.y,
- g->geom.width, g->geom.height,
- g->wp.x, g->wp.y, g->wp.width, g->wp.height,
- lcl_zoomrect.x, lcl_zoomrect.y, lcl_zoomrect.width, lcl_zoomrect.height);
+ printf("after:\n"
+ "\tgeom: (%d, %d)+(%d x %d)\n"
+ "\twp: (%d, %d)+(%d x %d)\n"
+ "\tzoomrect: (%d, %d)+(%d x %d)\n",
+ g->geom.x, g->geom.y,
+ g->geom.width, g->geom.height,
+ g->wp.x, g->wp.y, g->wp.width, g->wp.height,
+ lcl_zoomrect.x, lcl_zoomrect.y, lcl_zoomrect.width, lcl_zoomrect.height);
*/
- graph_element_lists_make(g);
- g->cross.erase_needed = FALSE;
- graph_display(g);
- axis_display(g->y_axis);
- axis_display(g->x_axis);
- update_zoom_spins(g);
+ graph_element_lists_make(g);
+ g->cross.erase_needed = FALSE;
+ graph_display(g);
+ axis_display(g->y_axis);
+ axis_display(g->x_axis);
+ update_zoom_spins(g);
}
-static void do_zoom_mouse (struct graph *g, GdkEventButton *event)
+static void do_zoom_mouse(struct graph *g, GdkEventButton *event)
{
- struct zoomfactor factor;
+ struct zoomfactor factor;
- get_zoomfactor(g, &factor, g->zoom.step_x, g->zoom.step_y);
- perform_zoom(g, &factor, (int)event->x, (int)event->y, ZOOM_REDRAW);
+ get_zoomfactor(g, &factor, g->zoom.step_x, g->zoom.step_y);
+ perform_zoom(g, &factor, (int)event->x, (int)event->y, ZOOM_REDRAW);
}
-static void do_zoom_keyboard (struct graph *g)
+static void do_zoom_keyboard(struct graph *g)
{
- int pointer_x, pointer_y;
- struct zoomfactor factor;
+ int pointer_x, pointer_y;
+ struct zoomfactor factor;
- get_mouse_position (g->drawing_area, &pointer_x, &pointer_y, NULL);
- get_zoomfactor(g, &factor, g->zoom.step_x, g->zoom.step_y);
- perform_zoom(g, &factor, pointer_x, pointer_y, ZOOM_REDRAW);
+ get_mouse_position(g->drawing_area, &pointer_x, &pointer_y, NULL);
+ get_zoomfactor(g, &factor, g->zoom.step_x, g->zoom.step_y);
+ perform_zoom(g, &factor, pointer_x, pointer_y, ZOOM_REDRAW);
}
-static void do_zoom_in_keyboard (struct graph *g)
+static void do_zoom_in_keyboard(struct graph *g)
{
- gtk_toggle_button_set_active (g->zoom.widget.in_toggle, TRUE);
- do_zoom_keyboard (g);
+ gtk_toggle_button_set_active(g->zoom.widget.in_toggle, TRUE);
+ do_zoom_keyboard(g);
}
-static void do_zoom_out_keyboard (struct graph *g)
+static void do_zoom_out_keyboard(struct graph *g)
{
- gtk_toggle_button_set_active (g->zoom.widget.out_toggle, TRUE);
- do_zoom_keyboard (g);
- gtk_toggle_button_set_active (g->zoom.widget.in_toggle, TRUE);
+ gtk_toggle_button_set_active(g->zoom.widget.out_toggle, TRUE);
+ do_zoom_keyboard(g);
+ gtk_toggle_button_set_active(g->zoom.widget.in_toggle, TRUE);
}
-static void do_select_segment (struct graph *g)
+static void do_select_segment(struct graph *g)
{
- int pointer_x, pointer_y;
+ int pointer_x, pointer_y;
- get_mouse_position(g->drawing_area, &pointer_x, &pointer_y, NULL);
- graph_select_segment (g, pointer_x, pointer_y);
+ get_mouse_position(g->drawing_area, &pointer_x, &pointer_y, NULL);
+ graph_select_segment(g, pointer_x, pointer_y);
}
-static void do_wscale_graph (struct graph *g)
+static void do_wscale_graph(struct graph *g)
{
- gtk_toggle_button_set_active (g->gt.graph_wscale, TRUE);
+ gtk_toggle_button_set_active(g->gt.graph_wscale, TRUE);
}
-static void do_rtt_graph (struct graph *g)
+static void do_rtt_graph(struct graph *g)
{
- gtk_toggle_button_set_active (g->gt.graph_rtt, TRUE);
+ gtk_toggle_button_set_active(g->gt.graph_rtt, TRUE);
}
-static void do_throughput_graph (struct graph *g)
+static void do_throughput_graph(struct graph *g)
{
- gtk_toggle_button_set_active (g->gt.graph_tput, TRUE);
+ gtk_toggle_button_set_active(g->gt.graph_tput, TRUE);
}
-static void do_ts_graph_stevens (struct graph *g)
+static void do_ts_graph_stevens(struct graph *g)
{
- gtk_toggle_button_set_active (g->gt.graph_tseqstevens, TRUE);
+ gtk_toggle_button_set_active(g->gt.graph_tseqstevens, TRUE);
}
-static void do_ts_graph_tcptrace (struct graph *g)
+static void do_ts_graph_tcptrace(struct graph *g)
{
- gtk_toggle_button_set_active (g->gt.graph_tseqttrace, TRUE);
+ gtk_toggle_button_set_active(g->gt.graph_tseqttrace, TRUE);
}
-static void do_magnify_create (struct graph *g)
+static void do_magnify_create(struct graph *g)
{
- int pointer_x, pointer_y;
+ int pointer_x, pointer_y;
- get_mouse_position(g->drawing_area, &pointer_x, &pointer_y, NULL);
- magnify_create (g, (int )rint (pointer_x), (int )rint (pointer_y));
+ get_mouse_position(g->drawing_area, &pointer_x, &pointer_y, NULL);
+ magnify_create(g, (int )rint(pointer_x), (int )rint(pointer_y));
}
-static void do_key_motion (struct graph *g)
+static void do_key_motion(struct graph *g)
{
- if (g->geom.x > g->wp.x)
- g->geom.x = g->wp.x;
- if (g->geom.y > g->wp.y)
- g->geom.y = g->wp.y;
- if (g->wp.x + g->wp.width > g->geom.x + g->geom.width)
- g->geom.x = g->wp.width + g->wp.x - g->geom.width;
- if (g->wp.y + g->wp.height > g->geom.y + g->geom.height)
- g->geom.y = g->wp.height + g->wp.y - g->geom.height;
- g->cross.erase_needed = FALSE;
- graph_display (g);
- axis_display (g->y_axis);
- axis_display (g->x_axis);
- if (g->cross.draw) {
- int pointer_x, pointer_y;
+ if (g->geom.x > g->wp.x)
+ g->geom.x = g->wp.x;
+ if (g->geom.y > g->wp.y)
+ g->geom.y = g->wp.y;
+ if (g->wp.x + g->wp.width > g->geom.x + g->geom.width)
+ g->geom.x = g->wp.width + g->wp.x - g->geom.width;
+ if (g->wp.y + g->wp.height > g->geom.y + g->geom.height)
+ g->geom.y = g->wp.height + g->wp.y - g->geom.height;
+ g->cross.erase_needed = FALSE;
+ graph_display(g);
+ axis_display(g->y_axis);
+ axis_display(g->x_axis);
+ if (g->cross.draw) {
+ int pointer_x, pointer_y;
- get_mouse_position(g->drawing_area, &pointer_x, &pointer_y, NULL);
- g->cross.erase_needed = FALSE;
- cross_draw (g, pointer_x, pointer_y);
- }
+ get_mouse_position(g->drawing_area, &pointer_x, &pointer_y, NULL);
+ g->cross.erase_needed = FALSE;
+ cross_draw(g, pointer_x, pointer_y);
+ }
}
-static void do_key_motion_up (struct graph *g, int step)
+static void do_key_motion_up(struct graph *g, int step)
{
- g->geom.y += step;
- do_key_motion (g);
+ g->geom.y += step;
+ do_key_motion(g);
}
-static void do_key_motion_down (struct graph *g, int step)
+static void do_key_motion_down(struct graph *g, int step)
{
- g->geom.y -= step;
- do_key_motion (g);
+ g->geom.y -= step;
+ do_key_motion(g);
}
-static void do_key_motion_left (struct graph *g, int step)
+static void do_key_motion_left(struct graph *g, int step)
{
- g->geom.x += step;
- do_key_motion (g);
+ g->geom.x += step;
+ do_key_motion(g);
}
-static void do_key_motion_right (struct graph *g, int step)
+static void do_key_motion_right(struct graph *g, int step)
{
- g->geom.x -= step;
- do_key_motion (g);
+ g->geom.x -= step;
+ do_key_motion(g);
}
-static gboolean button_press_event (GtkWidget *widget _U_, GdkEventButton *event, gpointer user_data)
+static gboolean button_press_event(GtkWidget *widget _U_, GdkEventButton *event, gpointer user_data)
{
- struct graph *g = user_data;
+ struct graph *g = user_data;
- debug(DBS_FENTRY) puts ("button_press_event()");
+ debug(DBS_FENTRY) puts("button_press_event()");
- if (event->button == MOUSE_BUTTON_RIGHT) {
- if (event->state & GDK_CONTROL_MASK) {
- magnify_create (g, (int )rint (event->x), (int )rint (event->y));
- } else {
- g->grab.x = (int )rint (event->x) - g->geom.x;
- g->grab.y = (int )rint (event->y) - g->geom.y;
- g->grab.grabbed = TRUE;
- }
+ if (event->button == MOUSE_BUTTON_RIGHT) {
+ if (event->state & GDK_CONTROL_MASK) {
+ magnify_create(g, (int )rint(event->x), (int )rint(event->y));
+ } else {
+ g->grab.x = (int )rint(event->x) - g->geom.x;
+ g->grab.y = (int )rint(event->y) - g->geom.y;
+ g->grab.grabbed = TRUE;
+ }
#ifdef ORIGINAL_WIN32_BUTTONS
- /* Windows mouse control: */
- /* [<ctrl>-left] - select packet */
- /* [left] - zoom in */
- /* [<shift>-left] - zoom out */
- } else if (event->button == MOUSE_BUTTON_LEFT) {
- if (event->state & GDK_CONTROL_MASK) {
- graph_select_segment (g, (int)event->x, (int)event->y);
- } else {
+ /* Windows mouse control: */
+ /* [<ctrl>-left] - select packet */
+ /* [left] - zoom in */
+ /* [<shift>-left] - zoom out */
+ } else if (event->button == MOUSE_BUTTON_LEFT) {
+ if (event->state & GDK_CONTROL_MASK) {
+ graph_select_segment(g, (int)event->x, (int)event->y);
+ } else {
#else /* !ORIGINAL_WIN32_BUTTONS */
- } else if (event->button == MOUSE_BUTTON_MIDDLE) {
+ } else if (event->button == MOUSE_BUTTON_MIDDLE) {
#endif
- /* Shift means we should zoom out */
- if (event->state & GDK_SHIFT_MASK) {
- gtk_toggle_button_set_active (g->zoom.widget.out_toggle, TRUE);
- }
- else {
- gtk_toggle_button_set_active (g->zoom.widget.in_toggle, TRUE);
- }
- do_zoom_mouse(g, event);
+ /* Shift means we should zoom out */
+ if (event->state & GDK_SHIFT_MASK) {
+ gtk_toggle_button_set_active(g->zoom.widget.out_toggle, TRUE);
+ }
+ else {
+ gtk_toggle_button_set_active(g->zoom.widget.in_toggle, TRUE);
+ }
+ do_zoom_mouse(g, event);
#ifndef ORIGINAL_WIN32_BUTTONS
- } else if (event->button == MOUSE_BUTTON_LEFT) {
- /* See if we're on an element that links to a frame */
- graph_select_segment (g, (int )event->x, (int )event->y);
+ } else if (event->button == MOUSE_BUTTON_LEFT) {
+ /* See if we're on an element that links to a frame */
+ graph_select_segment(g, (int )event->x, (int )event->y);
- /* Record the origin of the zoom rectangle */
- zoomrect.x = (int)event->x;
- zoomrect.y = (int)event->y;
+ /* Record the origin of the zoom rectangle */
+ zoomrect.x = (int)event->x;
+ zoomrect.y = (int)event->y;
#else /* ORIGINAL_WIN32_BUTTONS*/
- }
+ }
#endif
- }
- return TRUE;
-}
-
-static gboolean motion_notify_event (GtkWidget *widget _U_, GdkEventMotion *event, gpointer user_data)
-{
- struct graph *g = user_data;
- int x, y;
- GdkModifierType state;
-
- /* debug(DBS_FENTRY) puts ("motion_notify_event()"); */
-
- if (event->is_hint)
- get_mouse_position(g->drawing_area, &x, &y, &state);
- else {
- x = (int) event->x;
- y = (int) event->y;
- state = event->state;
- }
-
- /* Testing just (state & GDK_BUTTON1_MASK) is not enough since when button1
- * is pressed while pointer is in motion, we will receive one more motion
- * notify *before* we get the button press. This last motion notify works
- * with stale grab coordinates */
- if (state & GDK_BUTTON3_MASK) {
- if (g->grab.grabbed) {
- g->geom.x = x-g->grab.x;
- g->geom.y = y-g->grab.y;
-
- if (g->geom.x > g->wp.x)
- g->geom.x = g->wp.x;
- if (g->geom.y > g->wp.y)
- g->geom.y = g->wp.y;
- if (g->wp.x + g->wp.width > g->geom.x + g->geom.width)
- g->geom.x = g->wp.width + g->wp.x - g->geom.width;
- if (g->wp.y + g->wp.height > g->geom.y + g->geom.height)
- g->geom.y = g->wp.height + g->wp.y - g->geom.height;
- g->cross.erase_needed = FALSE;
- graph_display (g);
- axis_display (g->y_axis);
- axis_display (g->x_axis);
- if (g->cross.draw) {
- cross_draw (g, x, y);
- }
- } else if (g->magnify.active)
- magnify_move (g, x, y);
- } else if (state & GDK_BUTTON1_MASK) {
-
- /* TODO: not sure we really want to jump to frames unless we release? */
- graph_select_segment (g, x, y);
-
- /* Update cross if necessary */
- if (g->cross.erase_needed)
- cross_erase (g);
- if (g->cross.draw)
- cross_draw (g, x, y);
-
- /* Draw bounded box for zoomrect being chosen! */
- if (g->zoomrect_erase_needed) {
- zoomrect_erase (g);
- }
- zoomrect_draw (g, x, y);
- } else {
- if (g->cross.erase_needed)
- cross_erase (g);
- if (g->cross.draw) {
- cross_draw (g, x, y);
- }
- }
-
- return TRUE;
-}
-
-static gboolean button_release_event (GtkWidget *widget _U_, GdkEventButton *event, gpointer user_data)
-{
- struct graph *g = user_data;
-
- debug(DBS_FENTRY) puts ("button_release_event()");
-
- if (event->button == MOUSE_BUTTON_RIGHT)
- g->grab.grabbed = FALSE;
-
- if (event->button == MOUSE_BUTTON_LEFT) {
- int xx1 = zoomrect.x;
- int xx2 = (int)event->x;
- int yy1 = zoomrect.y;
- int yy2 = (int)event->y;
- zoomrect.x = MIN(xx1, xx2);
- zoomrect.width = abs(xx1 - xx2);
- zoomrect.y = MIN(yy1, yy2);
- zoomrect.height = abs(yy1 - yy2);
-
- /* Finish selecting a region to zoom in on.
- Take care not to choose a too-small area (by accident?) */
- if (zoomrect.width > 3 && zoomrect.height > 3) {
- int oldflags = g->zoom.flags;
-
- debug(DBS_GRAPH_DRAWING) printf("Zoom in from (%d, %d) - (%d, %d)\n",
- zoomrect.x, zoomrect.y,
- zoomrect.width, zoomrect.height);
-
- g->zoom.flags &= ~ZOOM_OUT;
- do_zoom_rectangle(g, zoomrect);
- g->zoom.flags = oldflags;
- }
- }
-
- if (g->magnify.active)
- magnify_destroy (g);
- return TRUE;
-}
-
-static gboolean key_press_event (GtkWidget *widget _U_, GdkEventKey *event, gpointer user_data)
-{
- struct graph *g = user_data;
- int step;
-
- debug(DBS_FENTRY) puts ("key_press_event()");
-
- if((event->state & GDK_CONTROL_MASK) && (event->state & GDK_SHIFT_MASK))
- step = 0;
- else if (event->state & GDK_CONTROL_MASK)
- step = 1;
- else if (event->state & GDK_SHIFT_MASK)
- step = 10;
- else
- step = 100;
-
- switch (event->keyval) {
- case ' ':
- toggle_crosshairs (g);
- break;
- case 't':
- toggle_time_origin (g);
- break;
- case 's':
- toggle_seq_origin (g);
- break;
- case 'r':
- case GDK_Home:
- restore_initial_graph_view (g);
- break;
- case 'i':
- case '+':
- do_zoom_in_keyboard (g);
- break;
- case 'o':
- case '-':
- do_zoom_out_keyboard (g);
- break;
- case 'm':
- do_magnify_create (g);
- break;
- case 'g':
- do_select_segment (g);
- break;
- case '1':
- do_rtt_graph (g);
- break;
- case '2':
- do_throughput_graph (g);
- break;
- case '3':
- do_ts_graph_stevens (g);
- break;
- case '4':
- do_ts_graph_tcptrace (g);
- break;
- case '5':
- do_wscale_graph(g);
- break;
- case GDK_Left:
- do_key_motion_left (g, step);
- break;
- case GDK_Up:
- do_key_motion_up (g, step);
- break;
- case GDK_Right:
- do_key_motion_right (g, step);
- break;
- case GDK_Down:
- do_key_motion_down (g, step);
- break;
- case GDK_F1:
- callback_create_help (NULL, NULL);
- break;
- default:
- break;
- }
-
- return TRUE;
-}
-
-static gboolean key_release_event (GtkWidget *widget _U_, GdkEventKey *event, gpointer user_data)
-{
- struct graph *g = user_data;
-
- debug(DBS_FENTRY) puts ("key_release_event()");
-
- if (event->keyval == GDK_Shift_L || event->keyval == GDK_ISO_Prev_Group) {
- /* g->zoom.flags &= ~ZOOM_OUT; */
- gtk_toggle_button_set_active (g->zoom.widget.in_toggle, TRUE);
- }
- return TRUE;
-}
-
-
-static gboolean leave_notify_event (GtkWidget *widget _U_, GdkEventCrossing *event _U_, gpointer user_data)
-{
- struct graph *g = user_data;
-
- if (g->cross.erase_needed)
- cross_erase (g);
-
- return TRUE;
-}
-
-static gboolean enter_notify_event (GtkWidget *widget, GdkEventCrossing *event _U_, gpointer user_data)
-{
- struct graph *g = user_data;
-
- graph_pixmap_display (g);
- if (g->cross.draw) {
- int x, y;
- get_mouse_position(widget, &x, &y, NULL);
- cross_draw (g, x, y);
- }
- return TRUE;
-}
-
-static void toggle_crosshairs (struct graph *g)
-{
- g->cross.draw ^= 1;
- if (g->cross.draw) {
- int x, y;
- get_mouse_position(g->drawing_area, &x, &y, NULL);
- cross_draw (g, x, y);
- } else if (g->cross.erase_needed) {
- cross_erase (g);
- }
- /* toggle buttons emit their "toggled" signals so don't bother doing
- * any real work here, it will be done in signal handlers */
- if (g->cross.draw)
- gtk_toggle_button_set_active (g->cross.on_toggle, TRUE);
- else
- gtk_toggle_button_set_active (g->cross.off_toggle, TRUE);
-}
-
-static void toggle_time_origin (struct graph *g)
-{
- switch (g->type) {
- case GRAPH_TSEQ_STEVENS:
- tseq_stevens_toggle_time_origin (g);
- break;
- case GRAPH_TSEQ_TCPTRACE:
- tseq_tcptrace_toggle_time_origin (g);
- break;
- case GRAPH_THROUGHPUT:
- tput_toggle_time_origin (g);
- break;
- default:
- break;
- }
- axis_display (g->x_axis);
-}
-
-static void toggle_seq_origin (struct graph *g)
-{
- switch (g->type) {
- case GRAPH_TSEQ_STEVENS:
- tseq_stevens_toggle_seq_origin (g);
- axis_display (g->y_axis);
- break;
- case GRAPH_TSEQ_TCPTRACE:
- tseq_tcptrace_toggle_seq_origin (g);
- axis_display (g->y_axis);
- break;
- case GRAPH_RTT:
- rtt_toggle_seq_origin (g);
- axis_display (g->x_axis);
- break;
- default:
- break;
- }
+ }
+ return TRUE;
+}
+
+static gboolean motion_notify_event(GtkWidget *widget _U_, GdkEventMotion *event, gpointer user_data)
+{
+ struct graph *g = user_data;
+ int x, y;
+ GdkModifierType state;
+
+ /* debug(DBS_FENTRY) puts("motion_notify_event()"); */
+
+ if (event->is_hint)
+ get_mouse_position(g->drawing_area, &x, &y, &state);
+ else {
+ x = (int) event->x;
+ y = (int) event->y;
+ state = event->state;
+ }
+
+ /* Testing just (state & GDK_BUTTON1_MASK) is not enough since when button1
+ * is pressed while pointer is in motion, we will receive one more motion
+ * notify *before* we get the button press. This last motion notify works
+ * with stale grab coordinates */
+ if (state & GDK_BUTTON3_MASK) {
+ if (g->grab.grabbed) {
+ g->geom.x = x-g->grab.x;
+ g->geom.y = y-g->grab.y;
+
+ if (g->geom.x > g->wp.x)
+ g->geom.x = g->wp.x;
+ if (g->geom.y > g->wp.y)
+ g->geom.y = g->wp.y;
+ if (g->wp.x + g->wp.width > g->geom.x + g->geom.width)
+ g->geom.x = g->wp.width + g->wp.x - g->geom.width;
+ if (g->wp.y + g->wp.height > g->geom.y + g->geom.height)
+ g->geom.y = g->wp.height + g->wp.y - g->geom.height;
+ g->cross.erase_needed = FALSE;
+ graph_display(g);
+ axis_display(g->y_axis);
+ axis_display(g->x_axis);
+ if (g->cross.draw) {
+ cross_draw(g, x, y);
+ }
+ } else if (g->magnify.active)
+ magnify_move(g, x, y);
+ } else if (state & GDK_BUTTON1_MASK) {
+
+ /* TODO: not sure we really want to jump to frames unless we release? */
+ graph_select_segment(g, x, y);
+
+ /* Update cross if necessary */
+ if (g->cross.erase_needed)
+ cross_erase(g);
+ if (g->cross.draw)
+ cross_draw(g, x, y);
+
+ /* Draw bounded box for zoomrect being chosen! */
+ if (g->zoomrect_erase_needed) {
+ zoomrect_erase(g);
+ }
+ zoomrect_draw(g, x, y);
+ } else {
+ if (g->cross.erase_needed)
+ cross_erase(g);
+ if (g->cross.draw) {
+ cross_draw(g, x, y);
+ }
+ }
+
+ return TRUE;
+}
+
+static gboolean button_release_event(GtkWidget *widget _U_, GdkEventButton *event, gpointer user_data)
+{
+ struct graph *g = user_data;
+
+ debug(DBS_FENTRY) puts("button_release_event()");
+
+ if (event->button == MOUSE_BUTTON_RIGHT)
+ g->grab.grabbed = FALSE;
+
+ if (event->button == MOUSE_BUTTON_LEFT) {
+ int xx1 = zoomrect.x;
+ int xx2 = (int)event->x;
+ int yy1 = zoomrect.y;
+ int yy2 = (int)event->y;
+ zoomrect.x = MIN(xx1, xx2);
+ zoomrect.width = abs(xx1 - xx2);
+ zoomrect.y = MIN(yy1, yy2);
+ zoomrect.height = abs(yy1 - yy2);
+
+ /* Finish selecting a region to zoom in on.
+ Take care not to choose a too-small area (by accident?) */
+ if ((zoomrect.width > 3) && (zoomrect.height > 3)) {
+ int oldflags = g->zoom.flags;
+
+ debug(DBS_GRAPH_DRAWING) printf("Zoom in from (%d, %d) - (%d, %d)\n",
+ zoomrect.x, zoomrect.y,
+ zoomrect.width, zoomrect.height);
+
+ g->zoom.flags &= ~ZOOM_OUT;
+ do_zoom_rectangle(g, zoomrect);
+ g->zoom.flags = oldflags;
+ }
+ }
+
+ if (g->magnify.active)
+ magnify_destroy(g);
+ return TRUE;
+}
+
+static gboolean key_press_event(GtkWidget *widget _U_, GdkEventKey *event, gpointer user_data)
+{
+ struct graph *g = user_data;
+ int step;
+
+ debug(DBS_FENTRY) puts("key_press_event()");
+
+ if ((event->state & GDK_CONTROL_MASK) && (event->state & GDK_SHIFT_MASK))
+ step = 0;
+ else if (event->state & GDK_CONTROL_MASK)
+ step = 1;
+ else if (event->state & GDK_SHIFT_MASK)
+ step = 10;
+ else
+ step = 100;
+
+ switch (event->keyval) {
+ case ' ':
+ toggle_crosshairs(g);
+ break;
+ case 't':
+ toggle_time_origin(g);
+ break;
+ case 's':
+ toggle_seq_origin(g);
+ break;
+ case 'r':
+ case GDK_Home:
+ restore_initial_graph_view(g);
+ break;
+ case 'i':
+ case '+':
+ do_zoom_in_keyboard(g);
+ break;
+ case 'o':
+ case '-':
+ do_zoom_out_keyboard(g);
+ break;
+ case 'm':
+ do_magnify_create(g);
+ break;
+ case 'g':
+ do_select_segment(g);
+ break;
+ case '1':
+ do_rtt_graph(g);
+ break;
+ case '2':
+ do_throughput_graph(g);
+ break;
+ case '3':
+ do_ts_graph_stevens(g);
+ break;
+ case '4':
+ do_ts_graph_tcptrace(g);
+ break;
+ case '5':
+ do_wscale_graph(g);
+ break;
+ case GDK_Left:
+ do_key_motion_left(g, step);
+ break;
+ case GDK_Up:
+ do_key_motion_up(g, step);
+ break;
+ case GDK_Right:
+ do_key_motion_right(g, step);
+ break;
+ case GDK_Down:
+ do_key_motion_down(g, step);
+ break;
+ case GDK_F1:
+ callback_create_help(NULL, NULL);
+ break;
+ default:
+ break;
+ }
+
+ return TRUE;
+}
+
+static gboolean key_release_event(GtkWidget *widget _U_, GdkEventKey *event, gpointer user_data)
+{
+ struct graph *g = user_data;
+
+ debug(DBS_FENTRY) puts("key_release_event()");
+
+ if ((event->keyval == GDK_Shift_L) || (event->keyval == GDK_ISO_Prev_Group)) {
+ /* g->zoom.flags &= ~ZOOM_OUT; */
+ gtk_toggle_button_set_active(g->zoom.widget.in_toggle, TRUE);
+ }
+ return TRUE;
+}
+
+
+static gboolean leave_notify_event(GtkWidget *widget _U_, GdkEventCrossing *event _U_, gpointer user_data)
+{
+ struct graph *g = user_data;
+
+ if (g->cross.erase_needed)
+ cross_erase(g);
+
+ return TRUE;
+}
+
+static gboolean enter_notify_event(GtkWidget *widget, GdkEventCrossing *event _U_, gpointer user_data)
+{
+ struct graph *g = user_data;
+
+ graph_pixmap_display(g);
+ if (g->cross.draw) {
+ int x, y;
+ get_mouse_position(widget, &x, &y, NULL);
+ cross_draw(g, x, y);
+ }
+ return TRUE;
+}
+
+static void toggle_crosshairs(struct graph *g)
+{
+ g->cross.draw ^= 1;
+ if (g->cross.draw) {
+ int x, y;
+ get_mouse_position(g->drawing_area, &x, &y, NULL);
+ cross_draw(g, x, y);
+ } else if (g->cross.erase_needed) {
+ cross_erase(g);
+ }
+ /* toggle buttons emit their "toggled" signals so don't bother doing
+ * any real work here, it will be done in signal handlers */
+ if (g->cross.draw)
+ gtk_toggle_button_set_active(g->cross.on_toggle, TRUE);
+ else
+ gtk_toggle_button_set_active(g->cross.off_toggle, TRUE);
+}
+
+static void toggle_time_origin(struct graph *g)
+{
+ switch (g->type) {
+ case GRAPH_TSEQ_STEVENS:
+ tseq_stevens_toggle_time_origin(g);
+ break;
+ case GRAPH_TSEQ_TCPTRACE:
+ tseq_tcptrace_toggle_time_origin(g);
+ break;
+ case GRAPH_THROUGHPUT:
+ tput_toggle_time_origin(g);
+ break;
+ default:
+ break;
+ }
+ axis_display(g->x_axis);
+}
+
+static void toggle_seq_origin(struct graph *g)
+{
+ switch (g->type) {
+ case GRAPH_TSEQ_STEVENS:
+ tseq_stevens_toggle_seq_origin(g);
+ axis_display(g->y_axis);
+ break;
+ case GRAPH_TSEQ_TCPTRACE:
+ tseq_tcptrace_toggle_seq_origin(g);
+ axis_display(g->y_axis);
+ break;
+ case GRAPH_RTT:
+ rtt_toggle_seq_origin(g);
+ axis_display(g->x_axis);
+ break;
+ default:
+ break;
+ }
}
-static void restore_initial_graph_view (struct graph *g)
+static void restore_initial_graph_view(struct graph *g)
{
- g->geom.width = g->wp.width;
- g->geom.height = g->wp.height;
- g->geom.x = g->wp.x;
- g->geom.y = g->wp.y;
- graph_init_sequence (g);
+ g->geom.width = g->wp.width;
+ g->geom.height = g->wp.height;
+ g->geom.x = g->wp.x;
+ g->geom.y = g->wp.y;
+ graph_init_sequence(g);
- if (g->cross.draw) {
- g->cross.erase_needed = FALSE;
- }
+ if (g->cross.draw) {
+ g->cross.erase_needed = FALSE;
+ }
}
-static int get_num_dsegs (struct graph *g)
+static int get_num_dsegs(struct graph *g)
{
- int count;
- struct segment *tmp;
+ int count;
+ struct segment *tmp;
- for (tmp=g->segments, count=0; tmp; tmp=tmp->next) {
- if(compare_headers(&g->src_address, &g->dst_address,
- g->src_port, g->dst_port,
- &tmp->ip_src, &tmp->ip_dst,
- tmp->th_sport, tmp->th_dport,
- COMPARE_CURR_DIR)) {
- count++;
- }
- }
- return count;
-}
-
-static int get_num_acks (struct graph *g, int *num_sack_ranges)
-{
- int count;
- struct segment *tmp;
-
- for (tmp=g->segments, count=0; tmp; tmp=tmp->next) {
- if(!compare_headers(&g->src_address, &g->dst_address,
- g->src_port, g->dst_port,
- &tmp->ip_src, &tmp->ip_dst,
- tmp->th_sport, tmp->th_dport,
- COMPARE_CURR_DIR)) {
- count++;
- *num_sack_ranges += tmp->num_sack_ranges;
- }
- }
- return count;
+ for (tmp=g->segments, count=0; tmp; tmp=tmp->next) {
+ if (compare_headers(&g->src_address, &g->dst_address,
+ g->src_port, g->dst_port,
+ &tmp->ip_src, &tmp->ip_dst,
+ tmp->th_sport, tmp->th_dport,
+ COMPARE_CURR_DIR)) {
+ count++;
+ }
+ }
+ return count;
+}
+
+static int get_num_acks(struct graph *g, int *num_sack_ranges)
+{
+ int count;
+ struct segment *tmp;
+
+ for (tmp = g->segments, count=0; tmp; tmp = tmp->next) {
+ if (!compare_headers(&g->src_address, &g->dst_address,
+ g->src_port, g->dst_port,
+ &tmp->ip_src, &tmp->ip_dst,
+ tmp->th_sport, tmp->th_dport,
+ COMPARE_CURR_DIR)) {
+ count++;
+ *num_sack_ranges += tmp->num_sack_ranges;
+ }
+ }
+ return count;
}
/*
* Stevens-style time-sequence grapH
*/
-static void tseq_stevens_read_config (struct graph *g)
+static void tseq_stevens_read_config(struct graph *g)
{
- debug(DBS_FENTRY) puts ("tseq_stevens_read_config()");
+ debug(DBS_FENTRY) puts("tseq_stevens_read_config()");
- g->s.tseq_stevens.seq_width = 4;
- g->s.tseq_stevens.seq_height = 4;
- g->s.tseq_stevens.flags = 0;
+ g->s.tseq_stevens.seq_width = 4;
+ g->s.tseq_stevens.seq_height = 4;
+ g->s.tseq_stevens.flags = 0;
- g->title = (const char ** )g_malloc (2 * sizeof (char *));
- g->title[0] = "Time/Sequence Graph (Stevens)";
- g->title[1] = NULL;
- g->y_axis->label = (const char ** )g_malloc (3 * sizeof (char * ));
- g->y_axis->label[0] = "number[B]";
- g->y_axis->label[1] = "Sequence";
- g->y_axis->label[2] = NULL;
- g->x_axis->label = (const char ** )g_malloc (2 * sizeof (char * ));
- g->x_axis->label[0] = "Time[s]";
- g->x_axis->label[1] = NULL;
+ g->title = (const char ** )g_malloc(2 * sizeof(char *));
+ g->title[0] = "Time/Sequence Graph (Stevens)";
+ g->title[1] = NULL;
+ g->y_axis->label = (const char ** )g_malloc(3 * sizeof(char * ));
+ g->y_axis->label[0] = "number[B]";
+ g->y_axis->label[1] = "Sequence";
+ g->y_axis->label[2] = NULL;
+ g->x_axis->label = (const char ** )g_malloc(2 * sizeof(char * ));
+ g->x_axis->label[0] = "Time[s]";
+ g->x_axis->label[1] = NULL;
}
/* Used by both 'stevens' and 'tcptrace' */
-static void tseq_initialize (struct graph *g)
+static void tseq_initialize(struct graph *g)
{
- debug(DBS_FENTRY) puts ("tseq_initialize()");
- tseq_get_bounds (g);
+ debug(DBS_FENTRY) puts("tseq_initialize()");
+ tseq_get_bounds(g);
- g->x_axis->min = 0;
- g->y_axis->min = 0;
+ g->x_axis->min = 0;
+ g->y_axis->min = 0;
- switch (g->type) {
- case GRAPH_TSEQ_STEVENS:
- tseq_stevens_read_config(g);
- break;
- case GRAPH_TSEQ_TCPTRACE:
- tseq_tcptrace_read_config(g);
- break;
- }
+ switch (g->type) {
+ case GRAPH_TSEQ_STEVENS:
+ tseq_stevens_read_config(g);
+ break;
+ case GRAPH_TSEQ_TCPTRACE:
+ tseq_tcptrace_read_config(g);
+ break;
+ }
}
@@ -4025,897 +4031,905 @@ static void tseq_initialize (struct graph *g)
/* ToDo: worry about handling cases such as trying to plot seq of just 1 frame */
-static void tseq_get_bounds (struct graph *g)
-{
- struct segment *tmp;
- double tim;
- gboolean data_frame_seen=FALSE;
- double data_tim_low=0;
- double data_tim_high=0;
- guint32 data_seq_cur;
- guint32 data_seq_nxt;
- guint32 data_seq_low=0;
- guint32 data_seq_high=0;
- gboolean ack_frame_seen=FALSE;
- double ack_tim_low=0;
- double ack_tim_high=0;
- guint32 ack_seq_cur;
- guint32 ack_seq_low=0;
- guint32 win_seq_cur;
- guint32 win_seq_high=0;
-
- /* go thru all segments to determine "bounds" */
- for (tmp=g->segments; tmp; tmp=tmp->next) {
- if(compare_headers(&g->src_address, &g->dst_address,
- g->src_port, g->dst_port,
- &tmp->ip_src, &tmp->ip_dst,
- tmp->th_sport, tmp->th_dport,
- COMPARE_CURR_DIR)) {
-
- /* "data" seg */
- tim = tmp->rel_secs + tmp->rel_usecs / 1000000.0;
- data_seq_cur = tmp->th_seq;
- data_seq_nxt = data_seq_cur + tmp->th_seglen;
- if (! data_frame_seen) {
- data_tim_low = data_tim_high = tim;
- data_seq_low = data_seq_cur;
- data_seq_high = data_seq_nxt;
- data_frame_seen = TRUE;
- }
- if (tim < data_tim_low) data_tim_low = tim;
- if (tim > data_tim_high) data_tim_high = tim;
- if (data_seq_cur < data_seq_low) data_seq_low = data_seq_cur;
- if (data_seq_nxt > data_seq_high) data_seq_high = data_seq_nxt;
- }
- else { /* ack seg */
- /* skip ack processing if no ACK (e.g. in RST) */
- if (TCP_ACK (tmp->th_flags)) {
- tim = tmp->rel_secs + tmp->rel_usecs / 1000000.0;
- ack_seq_cur = tmp->th_ack;
- win_seq_cur = ack_seq_cur + tmp->th_win;
- if (! ack_frame_seen) {
- ack_tim_low = ack_tim_high = tim;
- ack_seq_low = ack_seq_cur;
- win_seq_high = win_seq_cur;
- ack_frame_seen = TRUE;
- }
- if (tim < ack_tim_low) ack_tim_low = tim;
- if (tim > ack_tim_high) ack_tim_high = tim;
- if (ack_seq_cur < ack_seq_low) ack_seq_low = ack_seq_cur;
- if (win_seq_cur > win_seq_high) win_seq_high = win_seq_cur;
- }
- }
- }
-
- /* if 'stevens': use only data segments to determine bounds */
- /* if 'tcptrace': use both data and ack segments to determine bounds */
- switch (g->type) {
- case GRAPH_TSEQ_STEVENS:
- g->bounds.x0 = data_tim_low;
- g->bounds.width = data_tim_high - data_tim_low;
- g->bounds.y0 = data_seq_low;
- g->bounds.height = data_seq_high - data_seq_low;
- break;
- case GRAPH_TSEQ_TCPTRACE:
- /* If (ack_frame_seen == false) -> use 'data' segments.
- * Else If (data_frame_seen == false) -> use 'ack' segments.
- * Else -> use both data and ack segments.
- */
- g->bounds.x0 = ((data_tim_low <= ack_tim_low && data_frame_seen) || (! ack_frame_seen)) ? data_tim_low : ack_tim_low;
- g->bounds.width = (((data_tim_high >= ack_tim_high && data_frame_seen) || (! ack_frame_seen)) ? data_tim_high : ack_tim_high) - g->bounds.x0;
- g->bounds.y0 = ((data_seq_low <= ack_seq_low && data_frame_seen) || (! ack_frame_seen)) ? data_seq_low : ack_seq_low;
- g->bounds.height = (((data_seq_high >= win_seq_high && data_frame_seen) || (! ack_frame_seen)) ? data_seq_high : win_seq_high) - g->bounds.y0;
- break;
- }
-
- g->zoom.x = (g->geom.width - 1) / g->bounds.width;
- g->zoom.y = (g->geom.height -1) / g->bounds.height;
-}
-
-
-static void tseq_stevens_make_elmtlist (struct graph *g)
-{
- struct segment *tmp;
- struct element *elements, *e;
- double xx0 = g->bounds.x0, yy0 = g->bounds.y0;
- guint32 seq_base = (guint32) yy0;
- guint32 seq_cur;
-
- debug(DBS_FENTRY) puts ("tseq_stevens_make_elmtlist()");
- if (g->elists->elements == NULL) {
- int n = 1 + get_num_dsegs (g);
- e = elements = (struct element * )g_malloc (n*sizeof (struct element));
- } else
- e = elements = g->elists->elements;
-
- for (tmp=g->segments; tmp; tmp=tmp->next) {
- double secs, seqno;
-
- if(!compare_headers(&g->src_address, &g->dst_address,
- g->src_port, g->dst_port,
- &tmp->ip_src, &tmp->ip_dst,
- tmp->th_sport, tmp->th_dport,
- COMPARE_CURR_DIR)) {
- continue;
- }
- /* data seg */
- seq_cur = tmp->th_seq - seq_base;
- secs = g->zoom.x * (tmp->rel_secs + tmp->rel_usecs / 1000000.0 - xx0);
- seqno = g->zoom.y * seq_cur;
-
- e->type = ELMT_ELLIPSE;
- e->parent = tmp;
- e->p.ellipse.dim.width = g->s.tseq_stevens.seq_width;
- e->p.ellipse.dim.height = g->s.tseq_stevens.seq_height;
- e->p.ellipse.dim.x = secs - g->s.tseq_stevens.seq_width/2.0;
- e->p.ellipse.dim.y = seqno + g->s.tseq_stevens.seq_height/2.0;
- e++;
- }
- e->type = ELMT_NONE;
- g->elists->elements = elements;
-}
-
-static void tseq_stevens_toggle_seq_origin (struct graph *g)
-{
- g->s.tseq_stevens.flags ^= SEQ_ORIGIN;
-
- if ((g->s.tseq_stevens.flags & SEQ_ORIGIN) == SEQ_ORIGIN_ZERO)
- g->y_axis->min = g->bounds.y0;
- else /* g->tseq_stevens.flags & SEQ_ORIGIN == SEQ_ORIGIN_ISN */
- g->y_axis->min = 0;
-}
-
-static void tseq_stevens_toggle_time_origin (struct graph *g)
-{
- g->s.tseq_stevens.flags ^= TIME_ORIGIN;
-
- if ((g->s.tseq_stevens.flags & TIME_ORIGIN) == TIME_ORIGIN_CAP)
- g->x_axis->min = g->bounds.x0;
- else /* g->tseq_stevens.flags & TIME_ORIGIN == TIME_ORIGIN_CONN */
- g->x_axis->min = 0;
+static void tseq_get_bounds(struct graph *g)
+{
+ struct segment *tmp;
+ double tim;
+ gboolean data_frame_seen = FALSE;
+ double data_tim_low = 0;
+ double data_tim_high = 0;
+ guint32 data_seq_cur;
+ guint32 data_seq_nxt;
+ guint32 data_seq_low = 0;
+ guint32 data_seq_high = 0;
+ gboolean ack_frame_seen = FALSE;
+ double ack_tim_low = 0;
+ double ack_tim_high = 0;
+ guint32 ack_seq_cur;
+ guint32 ack_seq_low = 0;
+ guint32 win_seq_cur;
+ guint32 win_seq_high = 0;
+
+ /* go thru all segments to determine "bounds" */
+ for (tmp=g->segments; tmp; tmp=tmp->next) {
+ if (compare_headers(&g->src_address, &g->dst_address,
+ g->src_port, g->dst_port,
+ &tmp->ip_src, &tmp->ip_dst,
+ tmp->th_sport, tmp->th_dport,
+ COMPARE_CURR_DIR)) {
+
+ /* "data" seg */
+ tim = tmp->rel_secs + tmp->rel_usecs / 1000000.0;
+ data_seq_cur = tmp->th_seq;
+ data_seq_nxt = data_seq_cur + tmp->th_seglen;
+ if (! data_frame_seen) {
+ data_tim_low = data_tim_high = tim;
+ data_seq_low = data_seq_cur;
+ data_seq_high = data_seq_nxt;
+ data_frame_seen = TRUE;
+ }
+ if (tim < data_tim_low) data_tim_low = tim;
+ if (tim > data_tim_high) data_tim_high = tim;
+ if (data_seq_cur < data_seq_low) data_seq_low = data_seq_cur;
+ if (data_seq_nxt > data_seq_high) data_seq_high = data_seq_nxt;
+ }
+ else { /* ack seg */
+ /* skip ack processing if no ACK (e.g. in RST) */
+ if (TCP_ACK(tmp->th_flags)) {
+ tim = tmp->rel_secs + tmp->rel_usecs / 1000000.0;
+ ack_seq_cur = tmp->th_ack;
+ win_seq_cur = ack_seq_cur + tmp->th_win;
+ if (! ack_frame_seen) {
+ ack_tim_low = ack_tim_high = tim;
+ ack_seq_low = ack_seq_cur;
+ win_seq_high = win_seq_cur;
+ ack_frame_seen = TRUE;
+ }
+ if (tim < ack_tim_low) ack_tim_low = tim;
+ if (tim > ack_tim_high) ack_tim_high = tim;
+ if (ack_seq_cur < ack_seq_low) ack_seq_low = ack_seq_cur;
+ if (win_seq_cur > win_seq_high) win_seq_high = win_seq_cur;
+ }
+ }
+ }
+
+ /* if 'stevens': use only data segments to determine bounds */
+ /* if 'tcptrace': use both data and ack segments to determine bounds */
+ switch (g->type) {
+ case GRAPH_TSEQ_STEVENS:
+ g->bounds.x0 = data_tim_low;
+ g->bounds.width = data_tim_high - data_tim_low;
+ g->bounds.y0 = data_seq_low;
+ g->bounds.height = data_seq_high - data_seq_low;
+ break;
+ case GRAPH_TSEQ_TCPTRACE:
+ /* If (ack_frame_seen == false) -> use 'data' segments.
+ * Else If (data_frame_seen == false) -> use 'ack' segments.
+ * Else -> use both data and ack segments.
+ */
+ g->bounds.x0 = (((data_tim_low <= ack_tim_low) && data_frame_seen) || (! ack_frame_seen))
+ ? data_tim_low : ack_tim_low;
+ g->bounds.width = ((((data_tim_high >= ack_tim_high) && data_frame_seen) || (! ack_frame_seen))
+ ? data_tim_high : ack_tim_high) - g->bounds.x0;
+ g->bounds.y0 = (((data_seq_low <= ack_seq_low) && data_frame_seen) || (! ack_frame_seen))
+ ? data_seq_low : ack_seq_low;
+ g->bounds.height = ((((data_seq_high >= win_seq_high) && data_frame_seen) || (! ack_frame_seen))
+ ? data_seq_high : win_seq_high) - g->bounds.y0;
+ break;
+ }
+
+ g->zoom.x = (g->geom.width - 1) / g->bounds.width;
+ g->zoom.y = (g->geom.height -1) / g->bounds.height;
+}
+
+
+static void tseq_stevens_make_elmtlist(struct graph *g)
+{
+ struct segment *tmp;
+ struct element *elements, *e;
+ double xx0 = g->bounds.x0, yy0 = g->bounds.y0;
+ guint32 seq_base = (guint32) yy0;
+ guint32 seq_cur;
+
+ debug(DBS_FENTRY) puts("tseq_stevens_make_elmtlist()");
+ if (g->elists->elements == NULL) {
+ int n = 1 + get_num_dsegs(g);
+ e = elements = (struct element * )g_malloc(n*sizeof(struct element));
+ } else
+ e = elements = g->elists->elements;
+
+ for (tmp = g->segments; tmp; tmp = tmp->next) {
+ double secs, seqno;
+
+ if (!compare_headers(&g->src_address, &g->dst_address,
+ g->src_port, g->dst_port,
+ &tmp->ip_src, &tmp->ip_dst,
+ tmp->th_sport, tmp->th_dport,
+ COMPARE_CURR_DIR)) {
+ continue;
+ }
+ /* data seg */
+ seq_cur = tmp->th_seq - seq_base;
+ secs = g->zoom.x * (tmp->rel_secs + tmp->rel_usecs / 1000000.0 - xx0);
+ seqno = g->zoom.y * seq_cur;
+
+ e->type = ELMT_ELLIPSE;
+ e->parent = tmp;
+ e->p.ellipse.dim.width = g->s.tseq_stevens.seq_width;
+ e->p.ellipse.dim.height = g->s.tseq_stevens.seq_height;
+ e->p.ellipse.dim.x = secs - g->s.tseq_stevens.seq_width/2.0;
+ e->p.ellipse.dim.y = seqno + g->s.tseq_stevens.seq_height/2.0;
+ e++;
+ }
+ e->type = ELMT_NONE;
+ g->elists->elements = elements;
+}
+
+static void tseq_stevens_toggle_seq_origin(struct graph *g)
+{
+ g->s.tseq_stevens.flags ^= SEQ_ORIGIN;
+
+ if ((g->s.tseq_stevens.flags & SEQ_ORIGIN) == SEQ_ORIGIN_ZERO)
+ g->y_axis->min = g->bounds.y0;
+ else /* g->tseq_stevens.flags & SEQ_ORIGIN == SEQ_ORIGIN_ISN */
+ g->y_axis->min = 0;
+}
+
+static void tseq_stevens_toggle_time_origin(struct graph *g)
+{
+ g->s.tseq_stevens.flags ^= TIME_ORIGIN;
+
+ if ((g->s.tseq_stevens.flags & TIME_ORIGIN) == TIME_ORIGIN_CAP)
+ g->x_axis->min = g->bounds.x0;
+ else /* g->tseq_stevens.flags & TIME_ORIGIN == TIME_ORIGIN_CONN */
+ g->x_axis->min = 0;
}
/*
* tcptrace-style time-sequence graph
*/
-static void tseq_tcptrace_read_config (struct graph *g)
-{
- /* Black */
- g->s.tseq_tcptrace.seq_color.pixel=0;
- g->s.tseq_tcptrace.seq_color.red=0;
- g->s.tseq_tcptrace.seq_color.green=0;
- g->s.tseq_tcptrace.seq_color.blue=0;
-
- /* LightSlateGray */
- g->s.tseq_tcptrace.ack_color[0].pixel=0;
- g->s.tseq_tcptrace.ack_color[0].red=0x7777;
- g->s.tseq_tcptrace.ack_color[0].green=0x8888;
- g->s.tseq_tcptrace.ack_color[0].blue=0x9999;
-
- /* LightGray */
- g->s.tseq_tcptrace.ack_color[1].pixel=0;
- g->s.tseq_tcptrace.ack_color[1].red=0xd3d3;
- g->s.tseq_tcptrace.ack_color[1].green=0xd3d3;
- g->s.tseq_tcptrace.ack_color[1].blue=0xd3d3;
-
- /* Light blue */
- g->s.tseq_tcptrace.sack_color[0].pixel=0;
- g->s.tseq_tcptrace.sack_color[0].red=0x0;
- g->s.tseq_tcptrace.sack_color[0].green=0x0;
- g->s.tseq_tcptrace.sack_color[0].blue=0xffff;
-
- /* Darker blue */
- g->s.tseq_tcptrace.sack_color[1].pixel=0;
- g->s.tseq_tcptrace.sack_color[1].red=0x0;
- g->s.tseq_tcptrace.sack_color[1].green=0x0;
- g->s.tseq_tcptrace.sack_color[1].blue=0x9888;
-
- g->s.tseq_tcptrace.flags = 0;
-
- /* Allocate first list, but not elements */
- g->elists->next = (struct element_list * )
- g_malloc (sizeof (struct element_list));
- g->elists->next->next = NULL;
- g->elists->next->elements = NULL;
-
- g->title = (const char ** )g_malloc (2 * sizeof (char *));
- g->title[0] = "Time/Sequence Graph (tcptrace)";
- g->title[1] = NULL;
- g->y_axis->label = (const char ** )g_malloc (3 * sizeof (char * ));
- g->y_axis->label[0] = "number[B]";
- g->y_axis->label[1] = "Sequence";
- g->y_axis->label[2] = NULL;
- g->x_axis->label = (const char ** )g_malloc (2 * sizeof (char * ));
- g->x_axis->label[0] = "Time[s]";
- g->x_axis->label[1] = NULL;
-}
-
-static void tseq_tcptrace_make_elmtlist (struct graph *g)
-{
- struct segment *tmp;
- struct element *elements0, *e0; /* list of elmts with prio 0 */
- struct element *elements1, *e1; /* list of elmts with prio 1 */
- double xx0, yy0;
- double p_t = 0; /* ackno, window and time of previous segment */
- double p_ackno = 0, p_win = 0;
- gboolean ack_seen=FALSE;
- int toggle=0;
- guint32 seq_base;
- guint32 seq_cur;
- int num_sack_ranges = 0;
-
- debug(DBS_FENTRY) puts ("tseq_tcptrace_make_elmtlist()");
-
- if (g->elists->elements == NULL ) {
- /* 3 elements per data segment */
- int n = 1 + 3*get_num_dsegs(g);
- e0 = elements0 = (struct element * )g_malloc (n*sizeof (struct element));
- } else {
- /* Existing array */
- e0 = elements0 = g->elists->elements;
- }
-
- if (g->elists->next->elements == NULL) {
- /* 4 elements per ACK, but only one for each SACK range */
- int n = 1 + 4*get_num_acks(g, &num_sack_ranges);
- n += num_sack_ranges;
- e1 = elements1 = (struct element * )g_malloc (n*sizeof (struct element));
- } else {
- /* Existing array */
- e1 = elements1 = g->elists->next->elements;
- }
-
- xx0 = g->bounds.x0;
- yy0 = g->bounds.y0;
- seq_base = (guint32) yy0;
-
- for (tmp=g->segments; tmp; tmp=tmp->next) {
- double secs, data;
- double x;
-
- secs = tmp->rel_secs + tmp->rel_usecs / 1000000.0;
- x = secs - xx0;
- x *= g->zoom.x;
- if(compare_headers(&g->src_address, &g->dst_address,
- g->src_port, g->dst_port,
- &tmp->ip_src, &tmp->ip_dst,
- tmp->th_sport, tmp->th_dport,
- COMPARE_CURR_DIR)) {
- /* forward direction (data) -> we need seqno and amount of data */
- double yy1, yy2;
-
- seq_cur = tmp->th_seq - seq_base;
- if (TCP_SYN (tmp->th_flags) || TCP_FIN (tmp->th_flags))
- data = 1;
- else
- data = tmp->th_seglen;
-
- yy1 = g->zoom.y * (seq_cur);
- yy2 = g->zoom.y * (seq_cur + data);
- e0->type = ELMT_LINE;
- e0->parent = tmp;
- /* Set the drawing color */
- e0->elment_color_p = &g->s.tseq_tcptrace.seq_color;
- e0->p.line.dim.x1 = e0->p.line.dim.x2 = x;
- e0->p.line.dim.y1 = yy1;
- e0->p.line.dim.y2 = yy2;
- e0++;
- e0->type = ELMT_LINE;
- e0->parent = tmp;
- /* Set the drawing color */
- e0->elment_color_p = &g->s.tseq_tcptrace.seq_color;
- e0->p.line.dim.x1 = x - 1;
- e0->p.line.dim.x2 = x + 1;
- e0->p.line.dim.y1 = e0->p.line.dim.y2 = yy1;
- e0++;
- e0->type = ELMT_LINE;
- e0->parent = tmp;
- /* Set the drawing color */
- e0->elment_color_p = &g->s.tseq_tcptrace.seq_color;
- e0->p.line.dim.x1 = x + 1;
- e0->p.line.dim.x2 = x - 1;
- e0->p.line.dim.y1 = e0->p.line.dim.y2 = yy2;
- e0++;
- } else {
- double ackno, win;
- if (! TCP_ACK (tmp->th_flags))
- /* SYN's and RST's do not necessarily have ACK's*/
- continue;
- /* backward direction -> we need ackno and window */
- seq_cur = tmp->th_ack - seq_base;
- ackno = seq_cur * g->zoom.y;
- win = tmp->th_win * g->zoom.y;
-
- /* ack line */
- if (ack_seen == TRUE) { /* don't plot the first ack */
-
- /* Horizonal: time of previous ACK to now (at new ACK) */
- e1->type = ELMT_LINE;
- e1->parent = tmp;
- /* Set the drawing color */
- e1->elment_color_p = &g->s.tseq_tcptrace.ack_color[toggle];
- e1->p.line.dim.x1 = p_t;
- e1->p.line.dim.y1 = p_ackno;
- e1->p.line.dim.x2 = x;
- e1->p.line.dim.y2 = p_ackno;
- e1++;
-
- /* Vertical: from previous ACKNO to current one (at current time) */
- e1->type = ELMT_LINE;
- e1->parent = tmp;
- /* Set the drawing color */
- e1->elment_color_p = &g->s.tseq_tcptrace.ack_color[toggle];
- e1->p.line.dim.x1 = x;
- e1->p.line.dim.y1 = p_ackno;
- e1->p.line.dim.x2 = x;
- e1->p.line.dim.y2 = ackno!=p_ackno || ackno<4 ? ackno : ackno-4;
- e1++;
-
- /* Horizontal: window line */
- e1->type = ELMT_LINE;
- e1->parent = tmp;
- /* Set the drawing color */
- e1->elment_color_p = &g->s.tseq_tcptrace.ack_color[toggle];
- e1->p.line.dim.x1 = p_t;
- e1->p.line.dim.y1 = p_win + p_ackno;
- e1->p.line.dim.x2 = x;
- e1->p.line.dim.y2 = p_win + p_ackno;
- e1++;
-
- /* Vertical: old window to new window */
- e1->type = ELMT_LINE;
- e1->parent = tmp;
- /* Set the drawing color */
- e1->elment_color_p = &g->s.tseq_tcptrace.ack_color[toggle];
- e1->p.line.dim.x1 = x;
- e1->p.line.dim.y1 = p_win + p_ackno;
- e1->p.line.dim.x2 = x;
- e1->p.line.dim.y2 = win + ackno;
- e1++;
-
- /* Toggle color to use for ACKs... */
- toggle = 1^toggle;
- }
- ack_seen = TRUE;
- p_ackno = ackno;
- p_win = win;
- p_t = x;
-
- /* Now any SACK entries */
- if (tmp->num_sack_ranges) {
- int n;
-
- for (n=0; n < tmp->num_sack_ranges; n++) {
- double left_edge = (tmp->sack_left_edge[n] - seq_base) * g->zoom.y;
- double right_edge = (tmp->sack_right_edge[n] - seq_base) * g->zoom.y;
-
- /* Vertical: just show range of SACK.
- Have experimented with sorting ranges and showing in red regions
- between SACKs, but when TCP is limited by option bytes and needs to
- miss out ranges, this can be pretty confusing as we end up apparently
- NACKing what has been received... */
- e1->type = ELMT_LINE;
- e1->parent = tmp;
- /* Set the drawing color. First range is significant, so use
- separate colour */
- e1->elment_color_p = (n==0) ? &g->s.tseq_tcptrace.sack_color[0] :
- &g->s.tseq_tcptrace.sack_color[1];
- e1->p.line.dim.x1 = x;
- e1->p.line.dim.y1 = right_edge;
- e1->p.line.dim.x2 = x;
- e1->p.line.dim.y2 = left_edge;
- e1++;
- }
- }
- }
- }
-
- /* Terminate both lists */
- e0->type = ELMT_NONE;
- e1->type = ELMT_NONE;
-
- g->elists->elements = elements0;
- g->elists->next->elements = elements1;
- g->elists->next->next = NULL;
-}
-
-static void tseq_tcptrace_toggle_seq_origin (struct graph *g)
-{
- g->s.tseq_tcptrace.flags ^= SEQ_ORIGIN;
-
- if ((g->s.tseq_tcptrace.flags & SEQ_ORIGIN) == SEQ_ORIGIN_ZERO)
- g->y_axis->min = g->bounds.y0;
- else /* g->tseq_stevens.flags & SEQ_ORIGIN == SEQ_ORIGIN_ISN */
- g->y_axis->min = 0;
-}
-
-static void tseq_tcptrace_toggle_time_origin (struct graph *g)
-{
- g->s.tseq_tcptrace.flags ^= TIME_ORIGIN;
-
- if ((g->s.tseq_tcptrace.flags & TIME_ORIGIN) == TIME_ORIGIN_CAP)
- g->x_axis->min = g->bounds.x0;
- else /* g->tseq_stevens.flags & TIME_ORIGIN == TIME_ORIGIN_CONN */
- g->x_axis->min = 0;
+static void tseq_tcptrace_read_config(struct graph *g)
+{
+ /* Black */
+ g->s.tseq_tcptrace.seq_color.pixel = 0;
+ g->s.tseq_tcptrace.seq_color.red = 0;
+ g->s.tseq_tcptrace.seq_color.green = 0;
+ g->s.tseq_tcptrace.seq_color.blue = 0;
+
+ /* LightSlateGray */
+ g->s.tseq_tcptrace.ack_color[0].pixel = 0;
+ g->s.tseq_tcptrace.ack_color[0].red = 0x7777;
+ g->s.tseq_tcptrace.ack_color[0].green = 0x8888;
+ g->s.tseq_tcptrace.ack_color[0].blue = 0x9999;
+
+ /* LightGray */
+ g->s.tseq_tcptrace.ack_color[1].pixel = 0;
+ g->s.tseq_tcptrace.ack_color[1].red = 0xd3d3;
+ g->s.tseq_tcptrace.ack_color[1].green = 0xd3d3;
+ g->s.tseq_tcptrace.ack_color[1].blue = 0xd3d3;
+
+ /* Light blue */
+ g->s.tseq_tcptrace.sack_color[0].pixel = 0;
+ g->s.tseq_tcptrace.sack_color[0].red = 0x0;
+ g->s.tseq_tcptrace.sack_color[0].green = 0x0;
+ g->s.tseq_tcptrace.sack_color[0].blue = 0xffff;
+
+ /* Darker blue */
+ g->s.tseq_tcptrace.sack_color[1].pixel = 0;
+ g->s.tseq_tcptrace.sack_color[1].red = 0x0;
+ g->s.tseq_tcptrace.sack_color[1].green = 0x0;
+ g->s.tseq_tcptrace.sack_color[1].blue = 0x9888;
+
+ g->s.tseq_tcptrace.flags = 0;
+
+ /* Allocate first list, but not elements */
+ g->elists->next = (struct element_list * )
+ g_malloc(sizeof(struct element_list));
+ g->elists->next->next = NULL;
+ g->elists->next->elements = NULL;
+
+ g->title = (const char ** )g_malloc(2 * sizeof(char *));
+ g->title[0] = "Time/Sequence Graph (tcptrace)";
+ g->title[1] = NULL;
+ g->y_axis->label = (const char ** )g_malloc(3 * sizeof(char * ));
+ g->y_axis->label[0] = "number[B]";
+ g->y_axis->label[1] = "Sequence";
+ g->y_axis->label[2] = NULL;
+ g->x_axis->label = (const char ** )g_malloc(2 * sizeof(char * ));
+ g->x_axis->label[0] = "Time[s]";
+ g->x_axis->label[1] = NULL;
+}
+
+static void tseq_tcptrace_make_elmtlist(struct graph *g)
+{
+ struct segment *tmp;
+ struct element *elements0, *e0; /* list of elmts with prio 0 */
+ struct element *elements1, *e1; /* list of elmts with prio 1 */
+ double xx0, yy0;
+ double p_t = 0; /* ackno, window and time of previous segment */
+ double p_ackno = 0, p_win = 0;
+ gboolean ack_seen = FALSE;
+ int toggle = 0;
+ guint32 seq_base;
+ guint32 seq_cur;
+ int num_sack_ranges = 0;
+
+ debug(DBS_FENTRY) puts("tseq_tcptrace_make_elmtlist()");
+
+ if (g->elists->elements == NULL ) {
+ /* 3 elements per data segment */
+ int n = 1 + 3*get_num_dsegs(g);
+ e0 = elements0 = (struct element * )g_malloc(n * sizeof(struct element));
+ } else {
+ /* Existing array */
+ e0 = elements0 = g->elists->elements;
+ }
+
+ if (g->elists->next->elements == NULL) {
+ /* 4 elements per ACK, but only one for each SACK range */
+ int n = 1 + 4*get_num_acks(g, &num_sack_ranges);
+ n += num_sack_ranges;
+ e1 = elements1 = (struct element * )g_malloc(n * sizeof(struct element));
+ } else {
+ /* Existing array */
+ e1 = elements1 = g->elists->next->elements;
+ }
+
+ xx0 = g->bounds.x0;
+ yy0 = g->bounds.y0;
+ seq_base = (guint32) yy0;
+
+ for (tmp = g->segments; tmp; tmp = tmp->next) {
+ double secs, data;
+ double x;
+
+ secs = tmp->rel_secs + tmp->rel_usecs / 1000000.0;
+ x = secs - xx0;
+ x *= g->zoom.x;
+ if (compare_headers(&g->src_address, &g->dst_address,
+ g->src_port, g->dst_port,
+ &tmp->ip_src, &tmp->ip_dst,
+ tmp->th_sport, tmp->th_dport,
+ COMPARE_CURR_DIR)) {
+ /* forward direction (data) -> we need seqno and amount of data */
+ double yy1, yy2;
+
+ seq_cur = tmp->th_seq - seq_base;
+ if (TCP_SYN(tmp->th_flags) || TCP_FIN(tmp->th_flags))
+ data = 1;
+ else
+ data = tmp->th_seglen;
+
+ yy1 = g->zoom.y * (seq_cur);
+ yy2 = g->zoom.y * (seq_cur + data);
+ e0->type = ELMT_LINE;
+ e0->parent = tmp;
+ /* Set the drawing color */
+ e0->elment_color_p = &g->s.tseq_tcptrace.seq_color;
+ e0->p.line.dim.x1 = e0->p.line.dim.x2 = x;
+ e0->p.line.dim.y1 = yy1;
+ e0->p.line.dim.y2 = yy2;
+ e0++;
+ e0->type = ELMT_LINE;
+ e0->parent = tmp;
+ /* Set the drawing color */
+ e0->elment_color_p = &g->s.tseq_tcptrace.seq_color;
+ e0->p.line.dim.x1 = x - 1;
+ e0->p.line.dim.x2 = x + 1;
+ e0->p.line.dim.y1 = e0->p.line.dim.y2 = yy1;
+ e0++;
+ e0->type = ELMT_LINE;
+ e0->parent = tmp;
+ /* Set the drawing color */
+ e0->elment_color_p = &g->s.tseq_tcptrace.seq_color;
+ e0->p.line.dim.x1 = x + 1;
+ e0->p.line.dim.x2 = x - 1;
+ e0->p.line.dim.y1 = e0->p.line.dim.y2 = yy2;
+ e0++;
+ } else {
+ double ackno, win;
+ if (! TCP_ACK(tmp->th_flags))
+ /* SYN's and RST's do not necessarily have ACK's*/
+ continue;
+ /* backward direction -> we need ackno and window */
+ seq_cur = tmp->th_ack - seq_base;
+ ackno = seq_cur * g->zoom.y;
+ win = tmp->th_win * g->zoom.y;
+
+ /* ack line */
+ if (ack_seen == TRUE) { /* don't plot the first ack */
+
+ /* Horizonal: time of previous ACK to now (at new ACK) */
+ e1->type = ELMT_LINE;
+ e1->parent = tmp;
+ /* Set the drawing color */
+ e1->elment_color_p = &g->s.tseq_tcptrace.ack_color[toggle];
+ e1->p.line.dim.x1 = p_t;
+ e1->p.line.dim.y1 = p_ackno;
+ e1->p.line.dim.x2 = x;
+ e1->p.line.dim.y2 = p_ackno;
+ e1++;
+
+ /* Vertical: from previous ACKNO to current one (at current time) */
+ e1->type = ELMT_LINE;
+ e1->parent = tmp;
+ /* Set the drawing color */
+ e1->elment_color_p = &g->s.tseq_tcptrace.ack_color[toggle];
+ e1->p.line.dim.x1 = x;
+ e1->p.line.dim.y1 = p_ackno;
+ e1->p.line.dim.x2 = x;
+ e1->p.line.dim.y2 = ((ackno != p_ackno) || (ackno < 4)) ? ackno : ackno - 4;
+ e1++;
+
+ /* Horizontal: window line */
+ e1->type = ELMT_LINE;
+ e1->parent = tmp;
+ /* Set the drawing color */
+ e1->elment_color_p = &g->s.tseq_tcptrace.ack_color[toggle];
+ e1->p.line.dim.x1 = p_t;
+ e1->p.line.dim.y1 = p_win + p_ackno;
+ e1->p.line.dim.x2 = x;
+ e1->p.line.dim.y2 = p_win + p_ackno;
+ e1++;
+
+ /* Vertical: old window to new window */
+ e1->type = ELMT_LINE;
+ e1->parent = tmp;
+ /* Set the drawing color */
+ e1->elment_color_p = &g->s.tseq_tcptrace.ack_color[toggle];
+ e1->p.line.dim.x1 = x;
+ e1->p.line.dim.y1 = p_win + p_ackno;
+ e1->p.line.dim.x2 = x;
+ e1->p.line.dim.y2 = win + ackno;
+ e1++;
+
+ /* Toggle color to use for ACKs... */
+ toggle = 1^toggle;
+ }
+ ack_seen = TRUE;
+ p_ackno = ackno;
+ p_win = win;
+ p_t = x;
+
+ /* Now any SACK entries */
+ if (tmp->num_sack_ranges) {
+ int n;
+
+ for (n=0; n < tmp->num_sack_ranges; n++) {
+ double left_edge = (tmp->sack_left_edge[n] - seq_base) * g->zoom.y;
+ double right_edge = (tmp->sack_right_edge[n] - seq_base) * g->zoom.y;
+
+ /* Vertical: just show range of SACK.
+ Have experimented with sorting ranges and showing in red regions
+ between SACKs, but when TCP is limited by option bytes and needs to
+ miss out ranges, this can be pretty confusing as we end up apparently
+ NACKing what has been received... */
+ e1->type = ELMT_LINE;
+ e1->parent = tmp;
+ /* Set the drawing color. First range is significant, so use
+ separate colour */
+ e1->elment_color_p = (n==0) ? &g->s.tseq_tcptrace.sack_color[0] :
+ &g->s.tseq_tcptrace.sack_color[1];
+ e1->p.line.dim.x1 = x;
+ e1->p.line.dim.y1 = right_edge;
+ e1->p.line.dim.x2 = x;
+ e1->p.line.dim.y2 = left_edge;
+ e1++;
+ }
+ }
+ }
+ }
+
+ /* Terminate both lists */
+ e0->type = ELMT_NONE;
+ e1->type = ELMT_NONE;
+
+ g->elists->elements = elements0;
+ g->elists->next->elements = elements1;
+ g->elists->next->next = NULL;
+}
+
+static void tseq_tcptrace_toggle_seq_origin(struct graph *g)
+{
+ g->s.tseq_tcptrace.flags ^= SEQ_ORIGIN;
+
+ if ((g->s.tseq_tcptrace.flags & SEQ_ORIGIN) == SEQ_ORIGIN_ZERO)
+ g->y_axis->min = g->bounds.y0;
+ else /* g->tseq_stevens.flags & SEQ_ORIGIN == SEQ_ORIGIN_ISN */
+ g->y_axis->min = 0;
+}
+
+static void tseq_tcptrace_toggle_time_origin(struct graph *g)
+{
+ g->s.tseq_tcptrace.flags ^= TIME_ORIGIN;
+
+ if ((g->s.tseq_tcptrace.flags & TIME_ORIGIN) == TIME_ORIGIN_CAP)
+ g->x_axis->min = g->bounds.x0;
+ else /* g->tseq_stevens.flags & TIME_ORIGIN == TIME_ORIGIN_CONN */
+ g->x_axis->min = 0;
}
/*
* throughput graph
*/
-static void tput_make_elmtlist (struct graph *g)
-{
- struct segment *tmp, *oldest;
- struct element *elements, *e;
- int i, sum=0;
- double dtime, tput;
- int num_sack_ranges;
-
- if (g->elists->elements == NULL) {
- int n = 1 + get_num_dsegs (g) + get_num_acks (g, &num_sack_ranges);
- e = elements = (struct element * )g_malloc (n*sizeof (struct element));
- } else
- e = elements = g->elists->elements;
-
- for (oldest=g->segments,tmp=g->segments->next,i=0; tmp; tmp=tmp->next,i++) {
- double time_val = tmp->rel_secs + tmp->rel_usecs/1000000.0;
- dtime = time_val - (oldest->rel_secs + oldest->rel_usecs/1000000.0);
- if (i>g->s.tput.nsegs) {
- sum -= oldest->th_seglen;
- oldest=oldest->next;
- }
- sum += tmp->th_seglen;
- tput = sum / dtime;
- /* debug(DBS_TPUT_ELMTS) printf ("tput=%f\n", tput); */
-
- e->type = ELMT_ELLIPSE;
- e->parent = tmp;
- e->p.ellipse.dim.width = g->s.tput.width;
- e->p.ellipse.dim.height = g->s.tput.height;
- e->p.ellipse.dim.x = g->zoom.x*(time_val - g->bounds.x0) - g->s.tput.width/2.0;
- e->p.ellipse.dim.y = g->zoom.y*tput + g->s.tput.height/2.0;
- e++;
- }
- e->type = ELMT_NONE;
- g->elists->elements = elements;
+static void tput_make_elmtlist(struct graph *g)
+{
+ struct segment *tmp, *oldest;
+ struct element *elements, *e;
+ int i, sum = 0;
+ double dtime, tput;
+ int num_sack_ranges;
+
+ if (g->elists->elements == NULL) {
+ int n = 1 + get_num_dsegs(g) + get_num_acks(g, &num_sack_ranges);
+ e = elements = (struct element * )g_malloc(n * sizeof(struct element));
+ } else
+ e = elements = g->elists->elements;
+
+ for (oldest=g->segments, tmp=g->segments->next, i=0; tmp; tmp=tmp->next, i++) {
+ double time_val = tmp->rel_secs + tmp->rel_usecs/1000000.0;
+ dtime = time_val - (oldest->rel_secs + oldest->rel_usecs/1000000.0);
+ if (i>g->s.tput.nsegs) {
+ sum -= oldest->th_seglen;
+ oldest = oldest->next;
+ }
+ sum += tmp->th_seglen;
+ tput = sum / dtime;
+ /* debug(DBS_TPUT_ELMTS) printf("tput=%f\n", tput); */
+
+ e->type = ELMT_ELLIPSE;
+ e->parent = tmp;
+ e->p.ellipse.dim.width = g->s.tput.width;
+ e->p.ellipse.dim.height = g->s.tput.height;
+ e->p.ellipse.dim.x = g->zoom.x*(time_val - g->bounds.x0) - g->s.tput.width/2.0;
+ e->p.ellipse.dim.y = g->zoom.y*tput + g->s.tput.height/2.0;
+ e++;
+ }
+ e->type = ELMT_NONE;
+ g->elists->elements = elements;
}
/* Purpose of <graph_type>_initialize functions:
* - find maximum and minimum for both axes
* - call setup routine for style struct */
-static void tput_initialize (struct graph *g)
-{
- struct segment *tmp, *oldest, *last;
- int i, sum=0;
- double dtime, tput, tputmax=0;
- double t, t0, tmax = 0, yy0, ymax;
-
- debug(DBS_FENTRY) puts ("tput_initialize()");
-
- tput_read_config(g);
-
- for (last=g->segments; last->next; last=last->next);
- for (oldest=g->segments,tmp=g->segments->next,i=0; tmp; tmp=tmp->next,i++) {
- dtime = tmp->rel_secs + tmp->rel_usecs/1000000.0 -
- (oldest->rel_secs + oldest->rel_usecs/1000000.0);
- if (i>g->s.tput.nsegs) {
- sum -= oldest->th_seglen;
- oldest=oldest->next;
- }
- sum += tmp->th_seglen;
- tput = sum / dtime;
- debug(DBS_TPUT_ELMTS) printf ("tput=%f\n", tput);
- if (tput > tputmax)
- tputmax = tput;
- t = tmp->rel_secs + tmp->rel_usecs / 1000000.0;
- if (t > tmax)
- tmax = t;
- }
-
- t0 = g->segments->rel_secs + g->segments->rel_usecs / 1000000.0;
- yy0 = 0;
- ymax = tputmax;
-
- g->bounds.x0 = t0;
- g->bounds.y0 = yy0;
- g->bounds.width = tmax - t0;
- g->bounds.height = ymax - yy0;
- g->zoom.x = (g->geom.width - 1) / g->bounds.width;
- g->zoom.y = (g->geom.height -1) / g->bounds.height;
-}
-
-static void tput_read_config (struct graph *g)
-{
- debug(DBS_FENTRY) puts ("tput_read_config()");
-
- g->s.tput.width = 4;
- g->s.tput.height = 4;
- g->s.tput.nsegs = 20;
-
- g->title = (const char ** )g_malloc (2 * sizeof (char *));
- g->title[0] = "Throughput Graph";
- g->title[1] = NULL;
- g->y_axis->label = (const char ** )g_malloc (3 * sizeof (char * ));
- g->y_axis->label[0] = "[B/s]";
- g->y_axis->label[1] = "Throughput";
- g->y_axis->label[2] = NULL;
- g->x_axis->label = (const char ** )g_malloc (2 * sizeof (char * ));
- g->x_axis->label[0] = "Time[s]";
- g->x_axis->label[1] = NULL;
- g->s.tput.flags = 0;
-}
-
-static void tput_toggle_time_origin (struct graph *g)
-{
- g->s.tput.flags ^= TIME_ORIGIN;
-
- if ((g->s.tput.flags & TIME_ORIGIN) == TIME_ORIGIN_CAP)
- g->x_axis->min = g->bounds.x0;
- else /* g->s.tput.flags & TIME_ORIGIN == TIME_ORIGIN_CONN */
- g->x_axis->min = 0;
-}
-
-/* RTT graph */
-
-static void rtt_read_config (struct graph *g)
-{
- debug(DBS_FENTRY) puts ("rtt_read_config()");
-
- g->s.rtt.width = 4;
- g->s.rtt.height = 4;
- g->s.rtt.flags = 0;
-
- g->title = (const char ** )g_malloc (2 * sizeof (char *));
- g->title[0] = "Round Trip Time Graph";
- g->title[1] = NULL;
- g->y_axis->label = (const char ** )g_malloc (3 * sizeof (char * ));
- g->y_axis->label[0] = "RTT [s]";
- g->y_axis->label[1] = NULL;
- g->x_axis->label = (const char ** )g_malloc (2 * sizeof (char * ));
- g->x_axis->label[0] = "Sequence Number[B]";
- g->x_axis->label[1] = NULL;
-}
-
-static void rtt_initialize (struct graph *g)
+static void tput_initialize(struct graph *g)
{
- struct segment *tmp, *first=NULL;
- struct unack *unack = NULL, *u;
- double rttmax=0;
- double xx0, yy0, ymax;
- guint32 xmax = 0;
- guint32 seq_base = 0;
-
- debug(DBS_FENTRY) puts ("rtt_initialize()");
+ struct segment *tmp, *oldest/*, *last*/;
+ int i, sum = 0;
+ double dtime, tput, tputmax = 0;
+ double t, t0, tmax = 0, yy0, ymax;
- rtt_read_config (g);
+ debug(DBS_FENTRY) puts("tput_initialize()");
- for (tmp=g->segments; tmp; tmp=tmp->next) {
- if(compare_headers(&g->src_address, &g->dst_address,
- g->src_port, g->dst_port,
- &tmp->ip_src, &tmp->ip_dst,
- tmp->th_sport, tmp->th_dport,
- COMPARE_CURR_DIR)) {
- guint32 seqno = tmp->th_seq;
+ tput_read_config(g);
- if (!first) {
- first= tmp;
- seq_base = seqno;
- }
- seqno -= seq_base;
- if (tmp->th_seglen && !rtt_is_retrans (unack, seqno)) {
- double time_val = tmp->rel_secs + tmp->rel_usecs / 1000000.0;
- u = rtt_get_new_unack (time_val, seqno);
- if (!u) return;
- rtt_put_unack_on_list (&unack, u);
- }
-
- if (seqno + tmp->th_seglen > xmax)
- xmax = seqno + tmp->th_seglen;
- } else if (first) {
- guint32 ackno = tmp->th_ack -seq_base;
- double time_val = tmp->rel_secs + tmp->rel_usecs / 1000000.0;
- struct unack *v;
-
- for (u=unack; u; u=v)
- if (ackno > u->seqno) {
- double rtt = time_val - u->time;
- if (rtt > rttmax)
- rttmax = rtt;
- v=u->next;
- rtt_delete_unack_from_list (&unack, u);
- } else
- v=u->next;
- }
- }
-
- xx0 = seq_base;
- yy0 = 0;
- ymax = rttmax;
-
- g->bounds.x0 = xx0;
- g->bounds.y0 = yy0;
- g->bounds.width = xmax;
- g->bounds.height = ymax - yy0;
- g->zoom.x = g->geom.width / g->bounds.width;
- g->zoom.y = g->geom.height / g->bounds.height;
-}
-
-static int rtt_is_retrans (struct unack *list, unsigned int seqno)
-{
- struct unack *u;
-
- for (u=list; u; u=u->next)
- if (u->seqno== seqno)
- return TRUE;
-
- return FALSE;
-}
-
-static struct unack *rtt_get_new_unack (double time_val, unsigned int seqno)
-{
- struct unack *u;
-
- u = (struct unack * )g_malloc (sizeof (struct unack));
- if (!u)
- return NULL;
- u->next = NULL;
- u->time = time_val;
- u->seqno = seqno;
- return u;
-}
-
-static void rtt_put_unack_on_list (struct unack **l, struct unack *new)
-{
- struct unack *u, *list = *l;
-
- for (u=list; u; u=u->next)
- if (!u->next)
- break;
-
- if (u)
- u->next = new;
- else
- *l = new;
-}
-
-static void rtt_delete_unack_from_list (struct unack **l, struct unack *dead)
-{
- struct unack *u, *list = *l;
-
- if (!dead || !list)
- return;
-
- if (dead==list) {
- *l = list->next;
- g_free (list);
- } else
- for (u=list; u; u=u->next)
- if (u->next == dead) {
- u->next = u->next->next;
- g_free (dead);
- break;
- }
-}
-
-static void rtt_make_elmtlist (struct graph *g)
-{
- struct segment *tmp;
- struct unack *unack = NULL, *u;
- struct element *elements, *e;
- guint32 seq_base = (guint32) g->bounds.x0;
-
- debug(DBS_FENTRY) puts ("rtt_make_elmtlist()");
-
- if (g->elists->elements == NULL) {
- int n = 1 + get_num_dsegs (g);
- e = elements = (struct element * )g_malloc (n*sizeof (struct element));
- } else {
- e = elements = g->elists->elements;
- }
-
- for (tmp=g->segments; tmp; tmp=tmp->next) {
- if(compare_headers(&g->src_address, &g->dst_address,
- g->src_port, g->dst_port,
- &tmp->ip_src, &tmp->ip_dst,
- tmp->th_sport, tmp->th_dport,
- COMPARE_CURR_DIR)) {
- guint32 seqno = tmp->th_seq -seq_base;
-
- if (tmp->th_seglen && !rtt_is_retrans (unack, seqno)) {
- double time_val = tmp->rel_secs + tmp->rel_usecs / 1000000.0;
- u = rtt_get_new_unack (time_val, seqno);
- if (!u) return;
- rtt_put_unack_on_list (&unack, u);
- }
- } else {
- guint32 ackno = tmp->th_ack -seq_base;
- double time_val = tmp->rel_secs + tmp->rel_usecs / 1000000.0;
- struct unack *v;
+#if 0
+ for (last=g->segments; last->next; last=last->next); /* XXX: does nothing useful ? */
+#endif
+ for (oldest=g->segments, tmp=g->segments->next, i=0; tmp; tmp=tmp->next, i++) {
+ dtime = tmp->rel_secs + tmp->rel_usecs/1000000.0 -
+ (oldest->rel_secs + oldest->rel_usecs/1000000.0);
+ if (i > g->s.tput.nsegs) {
+ sum -= oldest->th_seglen;
+ oldest = oldest->next;
+ }
+ sum += tmp->th_seglen;
+ tput = sum / dtime;
+ debug(DBS_TPUT_ELMTS) printf("tput=%f\n", tput);
+ if (tput > tputmax)
+ tputmax = tput;
+ t = tmp->rel_secs + tmp->rel_usecs / 1000000.0;
+ if (t > tmax)
+ tmax = t;
+ }
+
+ t0 = g->segments->rel_secs + g->segments->rel_usecs / 1000000.0;
+ yy0 = 0;
+ ymax = tputmax;
+
+ g->bounds.x0 = t0;
+ g->bounds.y0 = yy0;
+ g->bounds.width = tmax - t0;
+ g->bounds.height = ymax - yy0;
+ g->zoom.x = (g->geom.width - 1) / g->bounds.width;
+ g->zoom.y = (g->geom.height -1) / g->bounds.height;
+}
+
+static void tput_read_config(struct graph *g)
+{
+ debug(DBS_FENTRY) puts("tput_read_config()");
+
+ g->s.tput.width = 4;
+ g->s.tput.height = 4;
+ g->s.tput.nsegs = 20;
+
+ g->title = (const char ** )g_malloc(2 * sizeof(char *));
+ g->title[0] = "Throughput Graph";
+ g->title[1] = NULL;
+ g->y_axis->label = (const char ** )g_malloc(3 * sizeof(char * ));
+ g->y_axis->label[0] = "[B/s]";
+ g->y_axis->label[1] = "Throughput";
+ g->y_axis->label[2] = NULL;
+ g->x_axis->label = (const char ** )g_malloc(2 * sizeof(char * ));
+ g->x_axis->label[0] = "Time[s]";
+ g->x_axis->label[1] = NULL;
+ g->s.tput.flags = 0;
+}
+
+static void tput_toggle_time_origin(struct graph *g)
+{
+ g->s.tput.flags ^= TIME_ORIGIN;
+
+ if ((g->s.tput.flags & TIME_ORIGIN) == TIME_ORIGIN_CAP)
+ g->x_axis->min = g->bounds.x0;
+ else /* g->s.tput.flags & TIME_ORIGIN == TIME_ORIGIN_CONN */
+ g->x_axis->min = 0;
+}
- for (u=unack; u; u=v)
- if (ackno > u->seqno) {
- double rtt = time_val - u->time;
+/* RTT graph */
- e->type = ELMT_ELLIPSE;
- e->parent = tmp;
- e->p.ellipse.dim.width = g->s.rtt.width;
- e->p.ellipse.dim.height = g->s.rtt.height;
- e->p.ellipse.dim.x = g->zoom.x * u->seqno - g->s.rtt.width/2.0;
- e->p.ellipse.dim.y = g->zoom.y * rtt + g->s.rtt.height/2.0;
- e++;
+static void rtt_read_config(struct graph *g)
+{
+ debug(DBS_FENTRY) puts("rtt_read_config()");
+
+ g->s.rtt.width = 4;
+ g->s.rtt.height = 4;
+ g->s.rtt.flags = 0;
+
+ g->title = (const char ** )g_malloc(2 * sizeof(char *));
+ g->title[0] = "Round Trip Time Graph";
+ g->title[1] = NULL;
+ g->y_axis->label = (const char ** )g_malloc(3 * sizeof(char * ));
+ g->y_axis->label[0] = "RTT [s]";
+ g->y_axis->label[1] = NULL;
+ g->x_axis->label = (const char ** )g_malloc(2 * sizeof(char * ));
+ g->x_axis->label[0] = "Sequence Number[B]";
+ g->x_axis->label[1] = NULL;
+}
+
+static void rtt_initialize(struct graph *g)
+{
+ struct segment *tmp, *first = NULL;
+ struct unack *unack = NULL, *u;
+ double rttmax = 0;
+ double xx0, yy0, ymax;
+ guint32 xmax = 0;
+ guint32 seq_base = 0;
+
+ debug(DBS_FENTRY) puts("rtt_initialize()");
- v=u->next;
- rtt_delete_unack_from_list (&unack, u);
- } else
- v=u->next;
- }
- }
- e->type = ELMT_NONE;
- g->elists->elements = elements;
-}
+ rtt_read_config(g);
+
+ for (tmp=g->segments; tmp; tmp=tmp->next) {
+ if (compare_headers(&g->src_address, &g->dst_address,
+ g->src_port, g->dst_port,
+ &tmp->ip_src, &tmp->ip_dst,
+ tmp->th_sport, tmp->th_dport,
+ COMPARE_CURR_DIR)) {
+ guint32 seqno = tmp->th_seq;
+
+ if (!first) {
+ first = tmp;
+ seq_base = seqno;
+ }
+ seqno -= seq_base;
+ if (tmp->th_seglen && !rtt_is_retrans(unack, seqno)) {
+ double time_val = tmp->rel_secs + tmp->rel_usecs / 1000000.0;
+ u = rtt_get_new_unack(time_val, seqno);
+ if (!u) return;
+ rtt_put_unack_on_list(&unack, u);
+ }
+
+ if (seqno + tmp->th_seglen > xmax)
+ xmax = seqno + tmp->th_seglen;
+ } else if (first) {
+ guint32 ackno = tmp->th_ack -seq_base;
+ double time_val = tmp->rel_secs + tmp->rel_usecs / 1000000.0;
+ struct unack *v;
+
+ for (u=unack; u; u=v) {
+ if (ackno > u->seqno) {
+ double rtt = time_val - u->time;
+ if (rtt > rttmax)
+ rttmax = rtt;
+ v = u->next;
+ rtt_delete_unack_from_list(&unack, u);
+ } else
+ v = u->next;
+ }
+ }
+ }
+
+ xx0 = seq_base;
+ yy0 = 0;
+ ymax = rttmax;
+
+ g->bounds.x0 = xx0;
+ g->bounds.y0 = yy0;
+ g->bounds.width = xmax;
+ g->bounds.height = ymax - yy0;
+ g->zoom.x = g->geom.width / g->bounds.width;
+ g->zoom.y = g->geom.height / g->bounds.height;
+}
+
+static int rtt_is_retrans(struct unack *list, unsigned int seqno)
+{
+ struct unack *u;
+
+ for (u=list; u; u=u->next) {
+ if (u->seqno == seqno)
+ return TRUE;
+ }
+ return FALSE;
+}
+
+static struct unack *rtt_get_new_unack(double time_val, unsigned int seqno)
+{
+ struct unack *u;
+
+ u = (struct unack * )g_malloc(sizeof(struct unack));
+ if (!u)
+ return NULL;
+ u->next = NULL;
+ u->time = time_val;
+ u->seqno = seqno;
+ return u;
+}
+
+static void rtt_put_unack_on_list(struct unack **l, struct unack *new)
+{
+ struct unack *u, *list = *l;
+
+ for (u=list; u; u=u->next) {
+ if (!u->next)
+ break;
+ }
+ if (u)
+ u->next = new;
+ else
+ *l = new;
+}
+
+static void rtt_delete_unack_from_list(struct unack **l, struct unack *dead)
+{
+ struct unack *u, *list = *l;
+
+ if (!dead || !list)
+ return;
+
+ if (dead == list) {
+ *l = list->next;
+ g_free(list);
+ } else {
+ for (u=list; u; u=u->next) {
+ if (u->next == dead) {
+ u->next = u->next->next;
+ g_free(dead);
+ break;
+ }
+ }
+ }
+}
+
+static void rtt_make_elmtlist(struct graph *g)
+{
+ struct segment *tmp;
+ struct unack *unack = NULL, *u;
+ struct element *elements, *e;
+ guint32 seq_base = (guint32) g->bounds.x0;
+
+ debug(DBS_FENTRY) puts("rtt_make_elmtlist()");
+
+ if (g->elists->elements == NULL) {
+ int n = 1 + get_num_dsegs(g);
+ e = elements = (struct element * )g_malloc(n * sizeof(struct element));
+ } else {
+ e = elements = g->elists->elements;
+ }
+
+ for (tmp=g->segments; tmp; tmp=tmp->next) {
+ if (compare_headers(&g->src_address, &g->dst_address,
+ g->src_port, g->dst_port,
+ &tmp->ip_src, &tmp->ip_dst,
+ tmp->th_sport, tmp->th_dport,
+ COMPARE_CURR_DIR)) {
+ guint32 seqno = tmp->th_seq -seq_base;
+
+ if (tmp->th_seglen && !rtt_is_retrans(unack, seqno)) {
+ double time_val = tmp->rel_secs + tmp->rel_usecs / 1000000.0;
+ u = rtt_get_new_unack(time_val, seqno);
+ if (!u) return;
+ rtt_put_unack_on_list(&unack, u);
+ }
+ } else {
+ guint32 ackno = tmp->th_ack -seq_base;
+ double time_val = tmp->rel_secs + tmp->rel_usecs / 1000000.0;
+ struct unack *v;
-static void rtt_toggle_seq_origin (struct graph *g)
-{
- g->s.rtt.flags ^= SEQ_ORIGIN;
+ for (u=unack; u; u=v) {
+ if (ackno > u->seqno) {
+ double rtt = time_val - u->time;
- if ((g->s.rtt.flags & SEQ_ORIGIN) == SEQ_ORIGIN_ZERO)
- g->x_axis->min = g->bounds.x0;
- else
- g->x_axis->min = 0;
+ e->type = ELMT_ELLIPSE;
+ e->parent = tmp;
+ e->p.ellipse.dim.width = g->s.rtt.width;
+ e->p.ellipse.dim.height = g->s.rtt.height;
+ e->p.ellipse.dim.x = g->zoom.x * u->seqno - g->s.rtt.width/2.0;
+ e->p.ellipse.dim.y = g->zoom.y * rtt + g->s.rtt.height/2.0;
+ e++;
+
+ v = u->next;
+ rtt_delete_unack_from_list(&unack, u);
+ } else
+ v = u->next;
+ }
+ }
+ }
+ e->type = ELMT_NONE;
+ g->elists->elements = elements;
+}
+
+static void rtt_toggle_seq_origin(struct graph *g)
+{
+ g->s.rtt.flags ^= SEQ_ORIGIN;
+
+ if ((g->s.rtt.flags & SEQ_ORIGIN) == SEQ_ORIGIN_ZERO)
+ g->x_axis->min = g->bounds.x0;
+ else
+ g->x_axis->min = 0;
}
/* WSCALE Graph */
-static void wscale_read_config(struct graph* g)
+static void wscale_read_config(struct graph *g)
{
- debug(DBS_FENTRY) puts ("wscale_read_config()");
+ debug(DBS_FENTRY) puts("wscale_read_config()");
- g->s.wscale.win_width = 4;
- g->s.wscale.win_height = 4;
- g->s.wscale.flags = 0;
+ g->s.wscale.win_width = 4;
+ g->s.wscale.win_height = 4;
+ g->s.wscale.flags = 0;
- g->title = (const char ** )g_malloc (2 * sizeof (char *));
- g->title[0] = "Window Scaling Graph";
- g->title[1] = NULL;
- g->y_axis->label = (const char ** )g_malloc (3 * sizeof (char * ));
- g->y_axis->label[0] = "[bytes]";
- g->y_axis->label[1] = "Windowsize";
- g->y_axis->label[2] = NULL;
- g->x_axis->label = (const char ** )g_malloc (2 * sizeof (char * ));
- g->x_axis->label[0] = "Time [s]";
- g->x_axis->label[1] = NULL;
+ g->title = (const char ** )g_malloc(2 * sizeof(char *));
+ g->title[0] = "Window Scaling Graph";
+ g->title[1] = NULL;
+ g->y_axis->label = (const char ** )g_malloc(3 * sizeof(char * ));
+ g->y_axis->label[0] = "[bytes]";
+ g->y_axis->label[1] = "Windowsize";
+ g->y_axis->label[2] = NULL;
+ g->x_axis->label = (const char ** )g_malloc(2 * sizeof(char * ));
+ g->x_axis->label[0] = "Time [s]";
+ g->x_axis->label[1] = NULL;
}
/*
(1) Find maximum and minimum values for Window-Size(scaled) and seconds
(2) call function to define window related values
*/
-static void wscale_initialize(struct graph* g)
+static void wscale_initialize(struct graph *g)
{
- struct segment* segm = NULL;
- guint32 wsize_max = 0;
- guint32 wsize_min = 0;
- gdouble sec_max = 0.0;
- gdouble sec_base = -1.0;
+ struct segment *segm = NULL;
+ guint32 wsize_max = 0;
+ guint32 wsize_min = 0;
+ gdouble sec_max = 0.0;
+ gdouble sec_base = -1.0;
- wscale_read_config (g);
+ wscale_read_config(g);
- debug(DBS_FENTRY) puts ("wscale_initialize()");
+ debug(DBS_FENTRY) puts("wscale_initialize()");
- for (segm = g->segments; segm; segm = segm->next)
- {
- if (compare_headers(&g->src_address, &g->dst_address,
- g->src_port, g->dst_port,
- &segm->ip_src, &segm->ip_dst,
- segm->th_sport, segm->th_dport,
- COMPARE_CURR_DIR))
- {
- gdouble sec = segm->rel_secs + ( segm->rel_usecs / 1000000.0 );
- guint16 flags = segm->th_flags;
- guint32 wsize = segm->th_win;
+ for (segm=g->segments; segm; segm=segm->next) {
+ if (compare_headers(&g->src_address, &g->dst_address,
+ g->src_port, g->dst_port,
+ &segm->ip_src, &segm->ip_dst,
+ segm->th_sport, segm->th_dport,
+ COMPARE_CURR_DIR))
+ {
+ gdouble sec = segm->rel_secs + ( segm->rel_usecs / 1000000.0 );
+ guint16 flags = segm->th_flags;
+ guint32 wsize = segm->th_win;
- /* only data segments */
- if ( (flags & (TH_SYN|TH_RST)) == 0 )
- if ( wsize > wsize_max )
- wsize_max = wsize;
+ /* only data segments */
+ if ( (flags & (TH_SYN|TH_RST)) == 0 )
+ if ( wsize > wsize_max )
+ wsize_max = wsize;
- /* remind time of first probe */
- if ( sec_base < 0 && sec > 0 )
- sec_base = sec;
+ /* remind time of first probe */
+ if ((sec_base < 0) && (sec > 0))
+ sec_base = sec;
- if ( sec_max < sec )
- sec_max = sec;
+ if ( sec_max < sec )
+ sec_max = sec;
- }
+ }
- }
+ }
- g->bounds.x0 = 0;
- g->bounds.y0 = wsize_min;
- g->bounds.width = sec_max - sec_base + 5;
- g->bounds.height = wsize_max + 5;
- g->zoom.x = g->geom.width / g->bounds.width;
- g->zoom.y = g->geom.height / g->bounds.height;
+ g->bounds.x0 = 0;
+ g->bounds.y0 = wsize_min;
+ g->bounds.width = sec_max - sec_base + 5;
+ g->bounds.height = wsize_max + 5;
+ g->zoom.x = g->geom.width / g->bounds.width;
+ g->zoom.y = g->geom.height / g->bounds.height;
}
/*
(1) Fill & allocate memory for segments times elements,
*/
-static void wscale_make_elmtlist(struct graph* g)
-{
- struct segment* segm = NULL;
- struct element* elements = NULL;
- struct element* e = NULL;
- gdouble sec_base = -1.0;
-
- debug(DBS_FENTRY) puts ("wscale_make_elmtlist()");
-
- /* Allocate memory for elements if not already done */
- if (g->elists->elements == NULL)
- {
- int n = 1 + get_num_dsegs(g);
- e = elements = (struct element*)g_malloc(n*sizeof(struct element));
- }
- else
- e = elements = g->elists->elements;
-
-
- for ( segm = g->segments; segm; segm = segm->next )
- {
- if (compare_headers(&g->src_address, &g->dst_address,
- g->src_port, g->dst_port,
- &segm->ip_src, &segm->ip_dst,
- segm->th_sport, segm->th_dport,
- COMPARE_CURR_DIR))
- {
- gdouble sec = segm->rel_secs + (segm->rel_usecs / 1000000.0);
- guint16 flags = segm->th_flags;
- guint32 wsize = segm->th_win;
-
- /* remind time of first probe */
- if ( sec_base < 0 && sec > 0 )
- sec_base = sec;
-
- /* only data or ack segments */
- if ( (flags & (TH_SYN|TH_RST)) == 0 )
- {
- e->type = ELMT_ELLIPSE;
- e->parent = segm;
- e->p.ellipse.dim.width = g->s.wscale.win_width;
- e->p.ellipse.dim.height = g->s.wscale.win_height;
- e->p.ellipse.dim.x = g->zoom.x * (sec - sec_base) - g->s.wscale.win_width / 2.0;
- e->p.ellipse.dim.y = g->zoom.y * wsize - g->s.wscale.win_height / 2.0;
- e++;
- }
- }
- }
- /* finished populating element list */
- e->type = ELMT_NONE;
- g->elists->elements = elements;
+static void wscale_make_elmtlist(struct graph *g)
+{
+ struct segment *segm = NULL;
+ struct element *elements = NULL;
+ struct element *e = NULL;
+ gdouble sec_base = -1.0;
+
+ debug(DBS_FENTRY) puts("wscale_make_elmtlist()");
+
+ /* Allocate memory for elements if not already done */
+ if (g->elists->elements == NULL)
+ {
+ int n = 1 + get_num_dsegs(g);
+ e = elements = (struct element*)g_malloc(n*sizeof(struct element));
+ }
+ else
+ e = elements = g->elists->elements;
+
+
+ for ( segm=g->segments; segm; segm=segm->next ) {
+ if (compare_headers(&g->src_address, &g->dst_address,
+ g->src_port, g->dst_port,
+ &segm->ip_src, &segm->ip_dst,
+ segm->th_sport, segm->th_dport,
+ COMPARE_CURR_DIR))
+ {
+ gdouble sec = segm->rel_secs + (segm->rel_usecs / 1000000.0);
+ guint16 flags = segm->th_flags;
+ guint32 wsize = segm->th_win;
+
+ /* remind time of first probe */
+ if ((sec_base < 0) && (sec > 0))
+ sec_base = sec;
+
+ /* only data or ack segments */
+ if ( (flags & (TH_SYN|TH_RST)) == 0 )
+ {
+ e->type = ELMT_ELLIPSE;
+ e->parent = segm;
+ e->p.ellipse.dim.width = g->s.wscale.win_width;
+ e->p.ellipse.dim.height = g->s.wscale.win_height;
+ e->p.ellipse.dim.x = g->zoom.x * (sec - sec_base) - g->s.wscale.win_width / 2.0;
+ e->p.ellipse.dim.y = g->zoom.y * wsize - g->s.wscale.win_height / 2.0;
+ e++;
+ }
+ }
+ }
+ /* finished populating element list */
+ e->type = ELMT_NONE;
+ g->elists->elements = elements;
}
#if defined(_WIN32) && !defined(__MINGW32__)
/* replacement of Unix rint() for Windows */
-static int rint (double x)
+static int rint(double x)
{
- char *buf;
- int i,dec,sig;
+ char *buf;
+ int i, dec, sig;
- buf = _fcvt(x, 0, &dec, &sig);
- i = atoi(buf);
- if(sig == 1) {
- i = i * -1;
- }
- return(i);
+ buf = _fcvt(x, 0, &dec, &sig);
+ i = atoi(buf);
+ if (sig == 1) {
+ i = i * -1;
+ }
+ return(i);
}
#endif
gboolean tcp_graph_selected_packet_enabled(frame_data *current_frame, epan_dissect_t *edt, gpointer callback_data _U_)
{
- return current_frame != NULL ? (edt->pi.ipproto == IP_PROTO_TCP) : FALSE;
+ return current_frame != NULL ? (edt->pi.ipproto == IP_PROTO_TCP) : FALSE;
}