aboutsummaryrefslogtreecommitdiffstats
path: root/ui/gtk/io_stat.c
diff options
context:
space:
mode:
Diffstat (limited to 'ui/gtk/io_stat.c')
-rw-r--r--ui/gtk/io_stat.c2197
1 files changed, 0 insertions, 2197 deletions
diff --git a/ui/gtk/io_stat.c b/ui/gtk/io_stat.c
deleted file mode 100644
index b4c54ce..0000000
--- a/ui/gtk/io_stat.c
+++ /dev/null
@@ -1,2197 +0,0 @@
-/* io_stat.c
- * io_stat 2002 Ronnie Sahlberg
- *
- * Wireshark - Network traffic analyzer
- * By Gerald Combs <gerald@wireshark.org>
- * Copyright 1998 Gerald Combs
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version 2
- * of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
- */
-
-
-#include "config.h"
-
-#include <string.h>
-#include <math.h>
-#include <gtk/gtk.h>
-
-#include <epan/epan_dissect.h>
-#include <epan/stat_tap_ui.h>
-#include <epan/tap.h>
-
-#include "ui/io_graph_item.h"
-#include "ui/simple_dialog.h"
-
-#include "ui/gtk/gui_stat_menu.h"
-#include "ui/gtk/old-gtk-compat.h"
-#include "ui/gtk/gui_utils.h"
-#include "ui/gtk/stock_icons.h"
-#include "ui/gtk/dlg_utils.h"
-#include "ui/gtk/filter_dlg.h"
-#include "ui/gtk/help_dlg.h"
-#include "ui/gtk/pixmap_save.h"
-#include "ui/gtk/main.h"
-#include "ui/gtk/filter_autocomplete.h"
-#include "ui/main_statusbar.h"
-
-#include "globals.h"
-
-void register_tap_listener_gtk_iostat(void);
-
-#define MAX_GRAPHS 5
-
-#define MAX_YSCALE 28
-#define LOGARITHMIC_YSCALE 0
-#define AUTO_MAX_YSCALE 1
-#define DEFAULT_YSCALE_INDEX 1
-static guint32 yscale_max[MAX_YSCALE] = {LOGARITHMIC_YSCALE, AUTO_MAX_YSCALE, 10, 20,
- 50, 100, 200, 500, 1000, 2000, 5000, 10000, 20000,
- 50000, 100000, 200000, 500000, 1000000, 2000000,
- 5000000, 10000000, 20000000, 50000000, 100000000,
- 200000000, 500000000, 1000000000, 2000000000};
-
-#define NO_FILTER_ORDER 0
-#define MAX_MOVING_AVERAGE_ORDER 10
-static guint32 moving_average_orders[MAX_MOVING_AVERAGE_ORDER] = {NO_FILTER_ORDER, 4, 8, 16,
- 32, 64, 128, 256, 512, 1024};
-#define NO_FILTER 0
-#define MOVING_AVERAGE_FILTER 1
-#define GRAPH_NOFILTER 0
-#define GRAPH_FOLLOWFILTER 1
-
-#define MAX_PIXELS_PER_TICK 4
-#define DEFAULT_PIXELS_PER_TICK_INDEX 2
-static guint32 pixels_per_tick[MAX_PIXELS_PER_TICK] = {1, 2, 5, 10};
-
-
-#define DEFAULT_PLOT_STYLE 0
-#define PLOT_STYLE_LINE 0
-#define PLOT_STYLE_IMPULSE 1
-#define PLOT_STYLE_FILLED_BAR 2
-#define PLOT_STYLE_DOT 3
-#define MAX_PLOT_STYLES 4
-static const char *plot_style_name[MAX_PLOT_STYLES] = {
- "Line",
- "Impulse",
- "FBar",
- "Dot",
-};
-
-/*
- * XXX - "Count types" and "calc types" are combined in io_graph_item_unit_t
- * in io_graph_item_t. The Qt port treats these as a single Y Axis "value unit"
- * type. Should we do the same here?
- */
-#define DEFAULT_COUNT_TYPE 0
-#define COUNT_TYPE_FRAMES 0
-#define COUNT_TYPE_BYTES 1
-#define COUNT_TYPE_BITS 2
-#define COUNT_TYPE_ADVANCED 3
-#define MAX_COUNT_TYPES 4
-static const char *count_type_names[MAX_COUNT_TYPES] = {
- "Packets/Tick",
- "Bytes/Tick",
- "Bits/Tick",
- "Advanced..."};
-
-/* unit is in ms */
-#define MAX_TICK_VALUES 7
-#define DEFAULT_TICK_VALUE_INDEX 3
-static const guint tick_interval_values[MAX_TICK_VALUES] = { 1, 10, 100, 1000, 10000, 60000, 600000 };
-
-#define CALC_TYPE_SUM 0
-#define CALC_TYPE_COUNT_FRAMES 1
-#define CALC_TYPE_COUNT_FIELDS 2
-#define CALC_TYPE_MAX 3
-#define CALC_TYPE_MIN 4
-#define CALC_TYPE_AVG 5
-#define CALC_TYPE_LOAD 6
-#define MAX_CALC_TYPES 7
-#define DEFAULT_CALC_TYPE 0
-static const char *calc_type_names[MAX_CALC_TYPES] = {
- "SUM(*)",
- "COUNT FRAMES(*)",
- "COUNT FIELDS(*)",
- "MAX(*)",
- "MIN(*)",
- "AVG(*)",
- "LOAD(*)"};
-
-#define CALC_TYPE_TO_ITEM_UNIT(ct) ((io_graph_item_unit_t)(ct + IOG_ITEM_UNIT_CALC_SUM))
-
-/* Unused? */
-#if 0
-typedef struct _io_stat_calc_type_t {
- struct _io_stat_graph_t *gio;
- int calc_type;
-} io_stat_calc_type_t;
-#endif
-
-typedef struct _io_stat_graph_t {
- struct _io_stat_t *io;
- io_graph_item_t *items;
- int plot_style;
- gboolean display;
- GtkWidget *display_button;
- GtkWidget *filter_field;
- GtkWidget *advanced_buttons;
- int calc_type;
- int hf_index;
- GtkWidget *calc_field;
- GdkColor color;
- GdkRGBA rgba_color;
- construct_args_t *args;
- GtkWidget *filter_bt;
-
- gboolean follow_smooth;
- GtkWidget *follow_smooth_toggle;
-} io_stat_graph_t;
-
-
-typedef struct _io_stat_t {
- gsize space_items; /* space for items allocated */
- gboolean needs_redraw;
- guint32 interval; /* measurement interval in ms */
- guint32 last_interval; /* the last *displayed* interval */
- guint32 max_interval; /* the maximum interval based on the capture duration */
- guint32 num_items; /* total number of items in all intervals (zero relative) */
- guint32 left_x_border;
- guint32 right_x_border;
- gboolean view_as_time;
- nstime_t start_time;
-
- struct _io_stat_graph_t graphs[MAX_GRAPHS];
- GtkWidget *window;
- GtkWidget *draw_area;
-#if GTK_CHECK_VERSION(2,22,0)
- cairo_surface_t *surface;
-#else
- GdkPixmap *pixmap;
-#endif
- GtkAdjustment *scrollbar_adjustment;
- GtkWidget *scrollbar;
-
- int surface_width;
- int surface_height;
- int pixels_per_tick;
- int max_y_units;
- int count_type;
-
- guint32 filter_order;
- int filter_type;
-} io_stat_t;
-
-
-static void init_io_stat_window(io_stat_t *io);
-static void filter_callback(GtkWidget *widget _U_, gpointer user_data);
-
-static void
-io_stat_set_title(io_stat_t *io)
-{
- if (!io->window) {
- return;
- }
- set_window_title(io->window, "Wireshark IO Graphs");
-}
-
-static void
-io_stat_reset(io_stat_t *io)
-{
- int i;
-
- io->needs_redraw = TRUE;
- for (i=0; i<MAX_GRAPHS; i++) {
- reset_io_graph_items(io->graphs[i].items, io->num_items);
- }
- io->last_interval = 0xffffffff;
- io->max_interval = 0;
- io->num_items = 0;
- io->start_time.secs = 0;
- io->start_time.nsecs = 0;
- io_stat_set_title(io);
-}
-
-static void
-tap_iostat_reset(void *g)
-{
- io_stat_graph_t *gio = (io_stat_graph_t *)g;
-
- io_stat_reset(gio->io);
-}
-
-static gboolean
-tap_iostat_packet(void *g, packet_info *pinfo, epan_dissect_t *edt, const void *dummy _U_)
-{
- io_stat_graph_t *graph = (io_stat_graph_t *)g;
- io_stat_t *io = graph->io;
- epan_dissect_t *adv_edt = NULL;
- unsigned int idx;
-
- /* we sometimes get called when the graph is disabled.
- this is a bug since the tap listener should be removed first */
- if (!graph->display) {
- return FALSE;
- }
-
- io->needs_redraw = TRUE;
-
- {
- int idx_signed;
- idx_signed = get_io_graph_index(pinfo, io->interval);
-
- /* some sanity checks */
- if (idx_signed < 0) {
- return FALSE;
- } else {
- idx = idx_signed;
- }
- }
-
- /* update num_items */
- if (idx + 1 > io->num_items) {
- if (idx + 1 > io->space_items) {
- /* reallocate graphs */
- static const gsize exp_inc_limit = 1000000;
- static const gsize step = 100000;
- const gsize new_size = (gsize)((idx < exp_inc_limit)?pow(2.0, log(idx + 1)/log(2.0) + 1):(idx + step));
- if (io->space_items == 0) {
- /* nothing allocated yet */
- int i;
- for (i = 0; i < MAX_GRAPHS; i++) {
- io->graphs[i].items = (io_graph_item_t *)g_malloc(sizeof(io->graphs[i].items[0]) * new_size);
- reset_io_graph_items(io->graphs[i].items, new_size);
- }
- } else {
- /* resize */
- int i;
- for (i = 0; i < MAX_GRAPHS; i++) {
- io->graphs[i].items = (io_graph_item_t *)g_realloc(io->graphs[i].items, sizeof(io->graphs[i].items[0]) * new_size);
- reset_io_graph_items(&io->graphs[i].items[io->space_items], new_size - io->space_items);
- }
- }
- io->space_items = new_size;
- }
- io->num_items = idx + 1;
- }
-
- /* set start time */
- if ((io->start_time.secs == 0) && (io->start_time.nsecs == 0)) {
- nstime_delta(&io->start_time, &pinfo->abs_ts, &pinfo->rel_ts);
- }
-
- /* For ADVANCED mode we need to keep track of some more stuff than just frame and byte counts */
- if (io->count_type == COUNT_TYPE_ADVANCED) {
- adv_edt = edt;
- }
-
- if (!update_io_graph_item(graph->items, idx, pinfo, adv_edt, graph->hf_index, CALC_TYPE_TO_ITEM_UNIT(graph->calc_type), io->interval)) {
- return FALSE;
- }
-
- return TRUE;
-}
-
-static guint64
-get_it_value(io_stat_t *io, int graph, int idx)
-{
- guint64 value = 0; /* FIXME: loss of precision, visible on the graph for small values */
- int adv_type;
- io_graph_item_t *it;
- guint32 interval;
-
- g_assert(graph < MAX_GRAPHS);
- if (((guint)idx > io->num_items + 1) || (0 == io->num_items)) {
- return 0;
- }
-
- it = &io->graphs[graph].items[idx];
-
- switch (io->count_type) {
- case COUNT_TYPE_FRAMES:
- return it->frames;
- case COUNT_TYPE_BYTES:
- return it->bytes;
- case COUNT_TYPE_BITS:
- return (it->bytes * 8);
- case COUNT_TYPE_ADVANCED:
- switch (io->graphs[graph].calc_type) {
- case CALC_TYPE_COUNT_FRAMES:
- return it->frames;
- case CALC_TYPE_COUNT_FIELDS:
- return it->fields;
- default:
- /* If it's COUNT_TYPE_ADVANCED but not one of the
- * generic ones we'll get it when we switch on the
- * adv_type below. */
- break;
- }
- break;
- }
-
- adv_type = proto_registrar_get_ftype(io->graphs[graph].hf_index);
- switch (adv_type) {
- case FT_UINT8:
- case FT_UINT16:
- case FT_UINT24:
- case FT_UINT32:
- case FT_UINT64:
- case FT_INT8:
- case FT_INT16:
- case FT_INT24:
- case FT_INT32:
- case FT_INT64:
- switch (io->graphs[graph].calc_type) {
- case CALC_TYPE_SUM:
- value = it->int_tot;
- break;
- case CALC_TYPE_MAX:
- value = it->int_max;
- break;
- case CALC_TYPE_MIN:
- value = it->int_min;
- break;
- case CALC_TYPE_AVG:
- if (it->fields) {
- value = it->int_tot/it->fields;
- } else {
- value = 0;
- }
- break;
- default:
- break;
- }
- break;
- case FT_FLOAT:
- switch (io->graphs[graph].calc_type) {
- case CALC_TYPE_SUM:
- value = (guint64)it->float_tot;
- break;
- case CALC_TYPE_MAX:
- value = (guint64)it->float_max;
- break;
- case CALC_TYPE_MIN:
- value = (guint64)it->float_min;
- break;
- case CALC_TYPE_AVG:
- if (it->fields) {
- value = (guint64)it->float_tot/it->fields;
- } else {
- value = 0;
- }
- break;
- default:
- break;
- }
- break;
- case FT_DOUBLE:
- switch (io->graphs[graph].calc_type) {
- case CALC_TYPE_SUM:
- value = (guint64)it->double_tot;
- break;
- case CALC_TYPE_MAX:
- value = (guint64)it->double_max;
- break;
- case CALC_TYPE_MIN:
- value = (guint64)it->double_min;
- break;
- case CALC_TYPE_AVG:
- if (it->fields) {
- value = (guint64)it->double_tot/it->fields;
- } else {
- value = 0;
- }
- break;
- default:
- break;
- }
- break;
- case FT_RELATIVE_TIME:
- switch (io->graphs[graph].calc_type) {
- case CALC_TYPE_MAX:
- value = (guint64) (it->time_max.secs*1000000 + it->time_max.nsecs/1000);
- break;
- case CALC_TYPE_MIN:
- value = (guint64) (it->time_min.secs*1000000 + it->time_min.nsecs/1000);
- break;
- case CALC_TYPE_SUM:
- value = (guint64) (it->time_tot.secs*1000000 + it->time_tot.nsecs/1000);
- break;
- case CALC_TYPE_AVG:
- if (it->fields) {
- guint64 t; /* time in us */
-
- t = it->time_tot.secs;
- t = t*1000000+it->time_tot.nsecs/1000;
- value = (guint64) (t/it->fields);
- } else {
- value = 0;
- }
- break;
- case CALC_TYPE_LOAD:
- if (idx == (int)io->num_items) {
- interval = (guint32)((cfile.elapsed_time.secs*1000) +
- ((cfile.elapsed_time.nsecs+500000)/1000000));
- interval -= (io->interval * idx);
- } else {
- interval = io->interval;
- }
- value = (guint64) ((it->time_tot.secs*1000000 + it->time_tot.nsecs/1000) / interval);
- break;
- default:
- break;
- }
- break;
- default:
- break;
- }
- return value;
-}
-
-static void
-print_time_scale_string(char *buf, int buf_len, guint32 t, guint32 t_max, gboolean log_flag)
-{
- if ((t_max >= 10000000) || (log_flag && (t_max >= 1000000))) {
- g_snprintf(buf, buf_len, "%ds", t/1000000);
- } else if (t_max >= 1000000) {
- g_snprintf(buf, buf_len, "%d.%1ds", t/1000000, (t%1000000)/100000);
- } else if ((t_max >= 10000) || (log_flag && (t_max >= 1000))) {
- g_snprintf(buf, buf_len, "%dms", t/1000);
- } else if (t_max >= 1000) {
- g_snprintf(buf, buf_len, "%d.%1dms", t/1000,(t%1000)/100);
- } else {
- g_snprintf(buf, buf_len, "%dus", t);
- }
-}
-
-static void
-print_interval_string(char *buf, int buf_len, guint32 interval, io_stat_t *io,
- gboolean ext)
-{
- if (io->view_as_time) {
- struct tm *tmp;
- time_t sec_val = interval/1000 + io->start_time.secs;
- gint32 nsec_val = interval%1000 + io->start_time.nsecs/1000000;
-
- if (nsec_val >= 1000) {
- sec_val++;
- nsec_val -= 1000;
- }
- tmp = localtime (&sec_val);
- if (tmp != NULL) {
- if (io->interval >= 1000) {
- g_snprintf(buf, buf_len, "%02d:%02d:%02d", tmp->tm_hour, tmp->tm_min, tmp->tm_sec);
- } else if (io->interval >= 100) {
- g_snprintf(buf, buf_len, "%02d:%02d:%02d.%1d", tmp->tm_hour, tmp->tm_min, tmp->tm_sec, nsec_val/100);
- } else if (io->interval >= 10) {
- g_snprintf(buf, buf_len, "%02d:%02d:%02d.%02d", tmp->tm_hour, tmp->tm_min, tmp->tm_sec, nsec_val/10);
- } else {
- g_snprintf(buf, buf_len, "%02d:%02d:%02d.%03d", tmp->tm_hour, tmp->tm_min, tmp->tm_sec, nsec_val);
- }
- } else
- g_snprintf(buf, buf_len, "Time not representable");
- } else {
- if (!ext) {
- g_snprintf(buf, buf_len, "%d.%03d", interval/1000,interval%1000);
- } else if (io->interval >= 60000) {
- g_snprintf(buf, buf_len, "%dm", interval/60000);
- } else if (io->interval >= 1000) {
- g_snprintf(buf, buf_len, "%ds", interval/1000);
- } else if (io->interval >= 100) {
- g_snprintf(buf, buf_len, "%d.%1ds", interval/1000,(interval/100)%10);
- } else if (io->interval >= 10) {
- g_snprintf(buf, buf_len, "%d.%02ds", interval/1000,(interval/10)%100);
- } else {
- g_snprintf(buf, buf_len, "%d.%03ds", interval/1000,interval%1000);
- }
- }
-}
-
-static void
-io_stat_draw(io_stat_t *io)
-{
- int i, tics, ystart, ys;
- guint32 last_interval, first_interval, interval_delta;
- gint32 current_interval;
- guint32 top_y_border;
- guint32 bottom_y_border;
- PangoLayout *layout;
- int label_width, label_height;
- guint32 draw_width, draw_height;
- char label_string[45];
- GtkAllocation widget_alloc;
-
- /* new variables */
- guint64 max_value; /* max value of seen data */
- guint32 max_y; /* max value of the Y scale */
- gboolean draw_y_as_time;
- gboolean draw_y_as_load;
- cairo_t *cr;
-
- if (!io->needs_redraw) {
- return;
- }
- io->needs_redraw = FALSE;
- /*
- * Set max_interval to duration rounded to the nearest ms. Add the Tick Interval so the last
- * interval will be displayed. For example, if duration = 11.844 secs and 'Tick Interval' == 1,
- * max_interval = 12000; if 0.1, 11900; if 0.01, 11850; and if 0.001, 11845.
- */
- io->max_interval = (guint32)((cfile.elapsed_time.secs*1000) +
- ((cfile.elapsed_time.nsecs+500000)/1000000) +
- io->interval);
- io->max_interval = (io->max_interval / io->interval) * io->interval;
-
- /*
- * find the max value so we can autoscale the y axis
- */
- max_value = 0;
- for (i=0; i<MAX_GRAPHS; i++) {
- int idx;
-
- if (!io->graphs[i].display) {
- continue;
- }
- for (idx=0; (guint32)(idx) < io->num_items; idx++) {
- guint64 val;
-
- val = get_it_value(io, i, idx);
-
- /* keep track of the max value we have encountered */
- if (val>max_value) {
- max_value = val;
- }
- }
- }
-
- /*
- * Clear out old plot
- */
-#if GTK_CHECK_VERSION(2,22,0)
- cr = cairo_create (io->surface);
-#else
- cr = gdk_cairo_create (io->pixmap);
-#endif
- cairo_set_source_rgb (cr, 1, 1, 1);
- gtk_widget_get_allocation(io->draw_area, &widget_alloc);
- cairo_rectangle (cr, 0, 0, widget_alloc.width,widget_alloc.height);
- cairo_fill (cr);
- cairo_destroy (cr);
- /*
- * Calculate the y scale we should use
- */
- if (io->max_y_units == AUTO_MAX_YSCALE) {
- max_y = yscale_max[MAX_YSCALE-1];
- for (i=MAX_YSCALE-1; i>1; i--) {
- if (max_value < yscale_max[i]) {
- max_y = yscale_max[i];
- }
- }
- } else if (io->max_y_units == LOGARITHMIC_YSCALE) {
- max_y = 1000000000;
- for (i=1000000000; i>1; i/=10) {
- if (max_value<(guint32)i) {
- max_y = i;
- }
- }
- } else {
- /* the user had specified an explicit y scale to use */
- max_y = io->max_y_units;
- }
-
- /*
- * If we use ADVANCED and all the graphs are plotting
- * either MIN/MAX/AVG of an FT_RELATIVE_TIME field
- * then we will do some some special processing for the
- * labels for the Y axis below:
- * we will append the time unit " s" " ms" or " us"
- * and we will present the unit in decimal
- */
- draw_y_as_time = FALSE;
- draw_y_as_load = FALSE;
- if (io->count_type == COUNT_TYPE_ADVANCED) {
- draw_y_as_time = TRUE;
- for (i=0; i<MAX_GRAPHS; i++) {
- int adv_type;
-
- if (!io->graphs[i].display) {
- continue;
- }
- if (io->graphs[i].calc_type == CALC_TYPE_LOAD) {
- draw_y_as_load = TRUE;
- }
-
- adv_type = proto_registrar_get_ftype(io->graphs[i].hf_index);
- switch (adv_type) {
- case FT_RELATIVE_TIME:
- switch (io->graphs[i].calc_type) {
- case CALC_TYPE_SUM:
- case CALC_TYPE_MAX:
- case CALC_TYPE_MIN:
- case CALC_TYPE_AVG:
- break;
- default:
- draw_y_as_time = FALSE;
- }
- break;
- default:
- draw_y_as_time = FALSE;
- }
- }
- }
-
- /*
- * Calculate size of borders surrounding the plot
- * The border on the right side needs to be adjusted depending
- * on the width of the text labels. For simplicity we assume that the
- * top y scale label will be the widest one
- */
- if (draw_y_as_time) {
- if (io->max_y_units == LOGARITHMIC_YSCALE) {
- print_time_scale_string(label_string, sizeof(label_string), 100000, 100000, TRUE); /* 100 ms */
- } else {
- print_time_scale_string(label_string, sizeof(label_string), max_y, max_y, FALSE);
- }
- } else {
- g_snprintf(label_string, sizeof(label_string), "%d", max_y);
- }
- layout = gtk_widget_create_pango_layout(io->draw_area, label_string);
- pango_layout_get_pixel_size(layout, &label_width, &label_height);
-
- io->left_x_border = 10;
- io->right_x_border = label_width + 20;
- top_y_border = 10;
- bottom_y_border = label_height + 20;
-
- /*
- * Calculate the size of the drawing area for the actual plot
- */
- draw_width = io->surface_width-io->right_x_border - io->left_x_border;
- draw_height = io->surface_height-top_y_border - bottom_y_border;
-
- /* Draw the y axis and labels
- * (we always draw the y scale with 11 ticks along the axis)
- */
-#if GTK_CHECK_VERSION(2,22,0)
- cr = cairo_create (io->surface);
-#else
- cr = gdk_cairo_create (io->pixmap);
-#endif
- cairo_set_line_width (cr, 1.0);
- cairo_move_to(cr, io->surface_width-io->right_x_border+1.5, top_y_border + 0.5);
- cairo_line_to(cr, io->surface_width-io->right_x_border+1.5, io->surface_height-bottom_y_border + 0.5);
- cairo_stroke(cr);
- if (io->max_y_units == LOGARITHMIC_YSCALE) {
- tics = (int)log10((double)max_y);
- ystart = draw_height/10;
- ys = -1;
- } else {
- tics = 10;
- ystart = ys = 0;
- }
-
- for (i=ys; i<=tics; i++) {
- int xwidth, lwidth, ypos;
-
- xwidth = 5;
- if (io->max_y_units == LOGARITHMIC_YSCALE) {
- if (i == ys) {
- /* position for the 0 value */
- ypos = io->surface_height-bottom_y_border;
- } else if (i == tics) {
- /* position for the top value, do not draw logarithmic tics above graph */
- ypos = io->surface_height-bottom_y_border-draw_height;
- } else {
- int j;
- /* draw the logarithmic tics */
- for (j=2; j<10; j++) {
- ypos = (int)(io->surface_height
- - bottom_y_border
- - (draw_height - ystart) * (i + log10((double)j))/tics
- - ystart);
- /* draw the tick */
- cairo_move_to(cr, io->surface_width-io->right_x_border+1.5, ypos+0.5);
- cairo_line_to(cr, io->surface_width-io->right_x_border+1.5+xwidth,ypos+0.5);
- cairo_stroke(cr);
- }
- ypos = io->surface_height-bottom_y_border-(draw_height-ystart)*i/tics-ystart;
- }
- /* all "main" logarithmic lines are slightly longer */
- xwidth = 10;
- } else {
- if (!(i%5)) {
- /* first, middle and last tick are slightly longer */
- xwidth = 10;
- }
- ypos = io->surface_height-bottom_y_border-draw_height*i/10;
- }
- /* draw the tick */
- cairo_move_to(cr, io->surface_width-io->right_x_border+1.5, ypos+0.5);
- cairo_line_to(cr, io->surface_width-io->right_x_border+1.5+xwidth,ypos+0.5);
- cairo_stroke(cr);
- /* draw the labels */
- if (xwidth == 10) {
- guint32 value;
- if (io->max_y_units == LOGARITHMIC_YSCALE) {
- value = (guint32)(max_y / pow(10,tics-i));
- if (draw_y_as_time) {
- print_time_scale_string(label_string, sizeof(label_string), value, value, TRUE);
- } else if (draw_y_as_load) {
- g_snprintf(label_string, sizeof(label_string), "%d.%1d", value/1000, (value/100)%10);
- } else {
- g_snprintf(label_string, sizeof(label_string), "%d", value);
- }
- } else {
- value = (max_y/10)*i;
- if (draw_y_as_time) {
- print_time_scale_string(label_string, sizeof(label_string), value, max_y, FALSE);
- } else if (draw_y_as_load) {
- g_snprintf(label_string, sizeof(label_string), "%d.%1d", value/1000, (value/100)%10);
- } else {
- g_snprintf(label_string, sizeof(label_string), "%d", value);
- }
- }
-
- pango_layout_set_text(layout, label_string, -1);
- pango_layout_get_pixel_size(layout, &lwidth, NULL);
-
- cairo_move_to (cr, io->surface_width-io->right_x_border+15+label_width-lwidth, ypos-label_height/2);
- pango_cairo_show_layout (cr, layout);
-
- }
- }
-
- /* If we have not specified the last_interval via the GUI, just pick the current end of the
- * capture so that it scrolls nicely when doing live captures.
- */
- if (io->last_interval == 0xffffffff) {
- last_interval = io->max_interval;
- } else {
- last_interval = io->last_interval;
- }
-
- /*XXX*/
- /* plot the x-scale */
- cairo_move_to(cr, io->left_x_border+0.5, io->surface_height-bottom_y_border+1.5);
- cairo_line_to(cr, io->surface_width-io->right_x_border+1.5,io->surface_height-bottom_y_border+1.5);
- cairo_stroke(cr);
- if ((last_interval/io->interval) >= draw_width/io->pixels_per_tick) {
- first_interval = (last_interval/io->interval)-draw_width/io->pixels_per_tick+1;
- first_interval *= io->interval;
- } else {
- first_interval = 0;
- }
-
- interval_delta = (100/io->pixels_per_tick)*io->interval;
- for (current_interval = last_interval;
- current_interval >= (gint32)first_interval;
- current_interval = current_interval-io->interval) {
- int x, xlen;
-
- /* if pixels_per_tick is 1 or 2, only draw every 10 ticks */
- /* if pixels_per_tick is 5, only draw every 5 ticks */
- if (((io->pixels_per_tick < 5) && (current_interval % (10*io->interval))) ||
- ((io->pixels_per_tick == 5) && (current_interval % (5*io->interval)))) {
- continue;
- }
-
- if (!(current_interval%interval_delta)) {
- xlen = 10;
- } else if (!(current_interval%(interval_delta/2))) {
- xlen = 8;
- } else {
- xlen = 5;
- }
- x = draw_width+io->left_x_border-((last_interval-current_interval)/io->interval)*io->pixels_per_tick;
- cairo_move_to(cr, x-1-io->pixels_per_tick/2+0.5, io->surface_height-bottom_y_border+1.5);
- cairo_line_to(cr, x-1-io->pixels_per_tick/2+0.5, io->surface_height-bottom_y_border+xlen+1.5);
- cairo_stroke(cr);
- if (xlen == 10) {
- int lwidth, x_pos;
- print_interval_string (label_string, sizeof(label_string), current_interval, io, TRUE);
- pango_layout_set_text(layout, label_string, -1);
- pango_layout_get_pixel_size(layout, &lwidth, NULL);
-
- if ((x-1-io->pixels_per_tick/2-lwidth/2) < 5) {
- x_pos = 5;
- } else if ((x-1-io->pixels_per_tick/2+lwidth/2) > (io->surface_width-5)) {
- x_pos = io->surface_width-lwidth-5;
- } else {
- x_pos = x-1-io->pixels_per_tick/2-lwidth/2;
- }
- cairo_move_to (cr, x_pos, io->surface_height-bottom_y_border+15);
- pango_cairo_show_layout (cr, layout);
- }
-
- }
- cairo_destroy (cr);
- cr = NULL;
- g_object_unref(G_OBJECT(layout));
-
- /*
- * Loop over all graphs and draw them
- */
-#if GTK_CHECK_VERSION(2,22,0)
- cr = cairo_create (io->surface);
-#else
- cr = gdk_cairo_create (io->pixmap);
-#endif
- cairo_set_line_width (cr, 1.0);
-
- for (i=MAX_GRAPHS-1; i>=0; i--) {
- guint64 val;
- guint32 interval, x_pos, y_pos, prev_x_pos, prev_y_pos;
- /* Moving average variables */
- guint32 mavg_in_average_count = 0, mavg_left = 0, mavg_right = 0;
- guint64 mavg_cumulated = 0;
- guint64 mavg_to_remove = 0, mavg_to_add = 0;
-
- if (!io->graphs[i].display) {
- continue;
- }
-
- if ((io->graphs[i].follow_smooth == GRAPH_FOLLOWFILTER) &&
- (io->filter_type == MOVING_AVERAGE_FILTER)) {
- /* "Warm-up phase" - calculate average on some data not displayed;
- just to make sure average on leftmost and rightmost displayed
- values is as reliable as possible
- */
- guint64 warmup_interval;
-
- if (first_interval/io->interval > io->filter_order/2) {
- warmup_interval = first_interval/io->interval - io->filter_order/2;
- warmup_interval *= io->interval;
- } else {
- warmup_interval = 0;
- }
- mavg_to_remove = warmup_interval;
- for (; warmup_interval < first_interval; warmup_interval += io->interval) {
- mavg_cumulated += get_it_value(io, i, (int)warmup_interval/io->interval);
- mavg_in_average_count++;
- mavg_left++;
- }
- mavg_cumulated += get_it_value(io, i, (int)warmup_interval/io->interval);
- mavg_in_average_count++;
- for (warmup_interval += io->interval;
- ((warmup_interval < (first_interval + (io->filter_order/2) * (guint64)io->interval)) &&
- (warmup_interval <= (io->num_items * (guint64)io->interval)));
- warmup_interval += io->interval) {
-
- mavg_cumulated += get_it_value(io, i, (int)warmup_interval / io->interval);
- mavg_in_average_count++;
- mavg_right++;
- }
- mavg_to_add = warmup_interval;
- }
-
- /* initialize prev x/y to the value of the first interval */
- prev_x_pos = draw_width-1 -
- io->pixels_per_tick * ((last_interval - first_interval) / io->interval) +
- io->left_x_border;
- val = get_it_value(io, i, first_interval / io->interval);
-
- if ((io->graphs[i].follow_smooth == GRAPH_FOLLOWFILTER) &&
- (io->filter_type == MOVING_AVERAGE_FILTER) &&
- (mavg_in_average_count > 0)) {
- val = mavg_cumulated / mavg_in_average_count;
- }
-
- if (val>max_y) {
- prev_y_pos = 0;
- } else if (io->max_y_units == LOGARITHMIC_YSCALE) {
- if (val == 0) {
- prev_y_pos = (guint32)(draw_height - 1 + top_y_border);
- } else {
- prev_y_pos = (guint32) (
- (draw_height - ystart)-1 -
- ((log10((double)((gint64)val)) * (draw_height - ystart)) / log10((double)max_y)) +
- top_y_border
- );
- }
- } else {
- prev_y_pos = (guint32)(draw_height-1-(val*draw_height)/max_y+top_y_border);
- }
-
- for (interval = first_interval;
- interval < last_interval;
- interval += io->interval) {
- x_pos = draw_width-1-io->pixels_per_tick*((last_interval-interval)/io->interval)+io->left_x_border;
-
- val = get_it_value(io, i, interval/io->interval);
- /* Moving average calculation */
- if ((io->graphs[i].follow_smooth == GRAPH_FOLLOWFILTER) &&
- (io->filter_type == MOVING_AVERAGE_FILTER)) {
- if (interval != first_interval) {
- mavg_left++;
- if (mavg_left > io->filter_order/2) {
- mavg_left--;
- mavg_in_average_count--;
- mavg_cumulated -= get_it_value(io, i, (int)mavg_to_remove/io->interval);
- mavg_to_remove += io->interval;
- }
- if (mavg_to_add<=(guint64)io->num_items*io->interval) {
- mavg_in_average_count++;
- mavg_cumulated += get_it_value(io, i, (int)mavg_to_add/io->interval);
- mavg_to_add += io->interval;
- } else {
- mavg_right--;
- }
- }
- if (mavg_in_average_count > 0) {
- val = mavg_cumulated / mavg_in_average_count;
- }
- }
-
- if (val>max_y) {
- y_pos = 0;
- } else if (io->max_y_units == LOGARITHMIC_YSCALE) {
- if (val == 0) {
- y_pos = (guint32)(draw_height-1+top_y_border);
- } else {
- y_pos = (guint32) (
- (draw_height - ystart) - 1 -
- (log10((double)(gint64)val) * (draw_height - ystart)) / log10((double)max_y) +
- top_y_border
- );
- }
- } else {
- y_pos = (guint32)(draw_height - 1 -
- ((val * draw_height) / max_y) +
- top_y_border);
- }
-
- switch (io->graphs[i].plot_style) {
- case PLOT_STYLE_LINE:
- /* Don't draw anything if the segment entirely above the top of the graph
- */
- if ( (prev_y_pos != 0) || (y_pos != 0) ) {
- cairo_move_to(cr, prev_x_pos+0.5, prev_y_pos+0.5);
- cairo_line_to(cr, x_pos+0.5, y_pos+0.5);
- gdk_cairo_set_source_rgba (cr, &io->graphs[i].rgba_color);
- cairo_stroke(cr);
- }
- break;
- case PLOT_STYLE_IMPULSE:
- if (val) {
- cairo_move_to(cr, x_pos+0.5, draw_height-1+top_y_border+0.5);
- cairo_line_to(cr, x_pos+0.5, y_pos+0.5);
- gdk_cairo_set_source_rgba (cr, &io->graphs[i].rgba_color);
- cairo_stroke(cr);
- }
- break;
- case PLOT_STYLE_FILLED_BAR:
- if (val) {
- cairo_rectangle (cr,
- x_pos-(gdouble)io->pixels_per_tick/2+0.5,
- y_pos+0.5,
- io->pixels_per_tick,
- draw_height-1+top_y_border-y_pos);
- gdk_cairo_set_source_rgba (cr, &io->graphs[i].rgba_color);
- cairo_fill (cr);
- }
- break;
- case PLOT_STYLE_DOT:
- if (val) {
- cairo_arc (cr,
- x_pos+0.5,
- y_pos+0.5,
- (gdouble)io->pixels_per_tick/2,
- 0,
- 2 * G_PI);
- gdk_cairo_set_source_rgba (cr, &io->graphs[i].rgba_color);
- cairo_fill (cr);
- }
- break;
- }
-
- prev_y_pos = y_pos;
- prev_x_pos = x_pos;
- }
- }
- cairo_destroy (cr);
-
- cr = gdk_cairo_create (gtk_widget_get_window(io->draw_area));
-
-#if GTK_CHECK_VERSION(2,22,0)
- cairo_set_source_surface (cr, io->surface, 0, 0);
-#else
- ws_gdk_cairo_set_source_pixmap (cr, io->pixmap, 0, 0);
-#endif
- cairo_rectangle (cr, 0, 0, io->surface_width, io->surface_height);
- cairo_fill (cr);
-
- cairo_destroy (cr);
-
- /* update the scrollbar */
- if (io->max_interval == 0) {
- gtk_adjustment_set_upper(io->scrollbar_adjustment, (gdouble) io->interval);
- gtk_adjustment_set_step_increment(io->scrollbar_adjustment, (gdouble) (io->interval/10));
- gtk_adjustment_set_page_increment(io->scrollbar_adjustment, (gdouble) io->interval);
- } else {
- gtk_adjustment_set_upper(io->scrollbar_adjustment, (gdouble) io->max_interval);
- gtk_adjustment_set_step_increment(io->scrollbar_adjustment, (gdouble) ((last_interval-first_interval)/10));
- gtk_adjustment_set_page_increment(io->scrollbar_adjustment, (gdouble) (last_interval-first_interval));
- }
- gtk_adjustment_set_page_size(io->scrollbar_adjustment, gtk_adjustment_get_page_increment(io->scrollbar_adjustment));
- gtk_adjustment_set_value(io->scrollbar_adjustment, (gdouble)first_interval);
- gtk_adjustment_changed(io->scrollbar_adjustment);
- gtk_adjustment_value_changed(io->scrollbar_adjustment);
-
-}
-
-static void
-io_stat_redraw(io_stat_t *io)
-{
- io->needs_redraw = TRUE;
- io_stat_draw(io);
-}
-
-static void
-tap_iostat_draw(void *g)
-{
- io_stat_graph_t *git = (io_stat_graph_t *)g;
-
- io_stat_draw(git->io);
-}
-
-/* ok we get called with both the filter and the field.
- make sure the field is part of the filter.
- (make sure and just append it)
- the field MUST be part of the filter or else we won't
- be able to pick up the field values after the edt tree has been
- pruned
-*/
-static GString *
-enable_graph(io_stat_graph_t *gio, const char *filter, const char *field)
-{
- GString *real_filter = NULL;
- GString *err_msg;
-
- gio->display = TRUE;
-
- if (filter) {
- /* skip all whitespaces */
- while (*filter) {
- if (*filter == ' ') {
- filter++;
- continue;
- }
- if (*filter == '\t') {
- filter++;
- continue;
- }
- break;
- }
- if (*filter) {
- real_filter = g_string_new("");
- g_string_printf(real_filter, "(%s)", filter);
- }
- }
- if (field) {
- /* skip all whitespaces */
- while (*field) {
- if (*field == ' ') {
- field++;
- continue;
- }
- if (*field == '\t') {
- field++;
- continue;
- }
- break;
- }
- if (*field) {
- if (real_filter) {
- g_string_append_printf(real_filter, " && (%s)", field);
- } else {
- real_filter = g_string_new(field);
- }
- }
- }
- err_msg = register_tap_listener("frame", gio, real_filter ? real_filter->str : NULL,
- TL_REQUIRES_PROTO_TREE, tap_iostat_reset, tap_iostat_packet,
- tap_iostat_draw);
- if (real_filter)
- g_string_free(real_filter, TRUE);
- return err_msg;
-}
-
-static void
-disable_graph(io_stat_graph_t *gio)
-{
- if (gio->display) {
- gio->display = FALSE;
- remove_tap_listener(gio);
- gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(gio->display_button),
- FALSE);
- }
-}
-
-static void
-iostat_init(const char *opt_arg _U_, void* userdata _U_)
-{
- io_stat_t *io;
- int i = 0;
- static GdkColor col[MAX_GRAPHS] = {
- {0, 0x0000, 0x0000, 0x0000}, /* Black */
- {0, 0xffff, 0x0000, 0x0000}, /* Red */
- {0, 0x0000, 0xffff, 0x0000}, /* Green */
- {0, 0x0000, 0x0000, 0xffff}, /* Blue */
- {0, 0xffff, 0x5000, 0xffff} /* Light brilliant magenta */
- };
-
- static GdkRGBA rgba_col[MAX_GRAPHS] = {
- {0.0, 0.0, 0.0, 1.0}, /* Black */
- {1.0, 0.0, 0.1, 1.0}, /* Red */
- {0.0, 1.0, 0.0, 1.0}, /* Green */
- {0.0, 0.0, 1.0, 1.0}, /* Blue */
- {1.0, 0.314, 1.0, 1.0} /* Light brilliant magenta */
- };
-
- GString *error_string;
-
- io = g_new(io_stat_t,1);
- io->needs_redraw = TRUE;
- io->interval = tick_interval_values[DEFAULT_TICK_VALUE_INDEX];
- io->window = NULL;
- io->draw_area = NULL;
-#if GTK_CHECK_VERSION(2,22,0)
- io->surface = NULL;
-#else
- io->pixmap = NULL;
-#endif
- io->scrollbar = NULL;
- io->scrollbar_adjustment = NULL;
- io->surface_width = 500;
- io->surface_height = 200;
- io->pixels_per_tick = pixels_per_tick[DEFAULT_PIXELS_PER_TICK_INDEX];
- io->max_y_units = AUTO_MAX_YSCALE;
- io->count_type = 0;
- io->last_interval = 0xffffffff;
- io->max_interval = 0;
- io->num_items = 0;
- io->space_items = 0;
- io->left_x_border = 0;
- io->right_x_border = 500;
- io->view_as_time = FALSE;
- io->start_time.secs = 0;
- io->start_time.nsecs = 0;
- io->filter_type = NO_FILTER;
-
- for (i=0; i<MAX_GRAPHS; i++) {
- io->graphs[i].plot_style = DEFAULT_PLOT_STYLE;
- io->graphs[i].color.pixel = col[i].pixel;
- io->graphs[i].color.red = col[i].red;
- io->graphs[i].color.green = col[i].green;
- io->graphs[i].color.blue = col[i].blue;
- io->graphs[i].rgba_color.red = rgba_col[i].red;
- io->graphs[i].rgba_color.green = rgba_col[i].green;
- io->graphs[i].rgba_color.blue = rgba_col[i].blue;
- io->graphs[i].rgba_color.alpha = rgba_col[i].alpha;
- io->graphs[i].display = 0;
- io->graphs[i].display_button = NULL;
- io->graphs[i].filter_field = NULL;
- io->graphs[i].advanced_buttons = NULL;
- io->graphs[i].io = io;
-
- io->graphs[i].args = g_new(construct_args_t,1);
- io->graphs[i].args->title = NULL;
- io->graphs[i].args->wants_apply_button = TRUE;
- io->graphs[i].args->activate_on_ok = TRUE;
- io->graphs[i].args->modal_and_transient = FALSE;
-
- io->graphs[i].filter_bt = NULL;
-
- io->graphs[i].follow_smooth = GRAPH_FOLLOWFILTER;
- }
- io_stat_reset(io);
-
- error_string = enable_graph(&io->graphs[0], NULL, NULL);
- /* Can't attach io_stat tap ! */
- g_assert(error_string == NULL);
-#if 0
- if (error_string) {
-
- fprintf(stderr, "wireshark: Can't attach io_stat tap: %s\n",
- error_string->str);
- g_string_free(error_string, TRUE);
- io->graphs[0].display = 0;
- io->graphs[0].display_button = NULL;
- io->graphs[0].filter_field = NULL;
- io->graphs[0].advanced_buttons = NULL;
- exit(10);
- }
-#endif
- /* build the GUI */
- init_io_stat_window(io);
-
- cf_retap_packets(&cfile);
- gdk_window_raise(gtk_widget_get_window(io->window));
- io_stat_redraw(io);
-}
-
-static void
-draw_area_destroy_cb(GtkWidget *widget _U_, gpointer user_data)
-{
- io_stat_t *io = (io_stat_t *)user_data;
- int i;
- GtkWidget *save_bt = (GtkWidget *)g_object_get_data(G_OBJECT(io->window), "save_bt");
- surface_info_t *surface_info = (surface_info_t *)g_object_get_data(G_OBJECT(save_bt), "surface-info");
-
- g_free(surface_info);
-
- for (i=0; i<MAX_GRAPHS; i++) {
- if (io->graphs[i].display) {
- remove_tap_listener(&io->graphs[i]);
-
- g_free( (gpointer) (io->graphs[i].args->title) );
- io->graphs[i].args->title = NULL;
-
- g_free(io->graphs[i].args);
- io->graphs[i].args = NULL;
- }
- g_free(io->graphs[i].items);
- }
- g_free(io);
-
- return;
-}
-
-static gboolean
-pixmap_clicked_event(GtkWidget *widget _U_, GdkEventButton *event, gpointer g)
-{
- io_stat_t *io = (io_stat_t *)g;
- io_stat_graph_t *graph;
- io_graph_item_t *it;
- guint32 draw_width, interval, last_interval;
- guint32 frame_num = 0;
- int i;
- gboolean load = FALSE, outstanding_call = FALSE;
-
- draw_width = io->surface_width - io->right_x_border - io->left_x_border;
-
- if ((event->x <= (draw_width + io->left_x_border + 1 - (draw_width/io->pixels_per_tick)*io->pixels_per_tick)) ||
- (event->x >= (draw_width + io->left_x_border - io->pixels_per_tick/2))) {
- /* Outside draw area */
- return FALSE;
- }
-
- /*
- * An interval in the IO Graph drawing area has been clicked. If left-clicked (button 1), the frame
- * with the first response in that interval or if left-clicked (button 3) the last is highlighted.
- */
-#if GTK_CHECK_VERSION(2,22,0)
- if (((event->button == 1) || (event->button == 3)) && (io->surface != NULL))
-#else
- if (((event->button == 1) || (event->button == 3)) && (io->pixmap != NULL))
-#endif
- {
- if (io->last_interval == 0xffffffff)
- last_interval = io->max_interval;
- else
- last_interval = io->last_interval;
-
- /* Get the interval that was clicked */
- if ((last_interval / io->interval) <
- ((draw_width + io->left_x_border - event->x -
- io->pixels_per_tick / 2 - 1) / io->pixels_per_tick)) {
- interval = 0;
- }
- else {
- interval = (guint32) (
- (last_interval / io->interval) -
- ((draw_width + io->left_x_border - event->x -
- io->pixels_per_tick / 2 - 1) / io->pixels_per_tick));
- }
-
- /* Determine the lowest or highest frame number depending on whether button 1 or 3 was clicked,
- * respectively, among the up to 5 currently displayed graphs. */
- for (i=0; i<MAX_GRAPHS; i++) {
- graph = &io->graphs[i];
- if (graph->display) {
- it = &graph->items[interval];
- if (event->button == 1) {
- if ((frame_num == 0) || (it->first_frame_in_invl < frame_num))
- frame_num = it->first_frame_in_invl;
- } else {
- if (it->last_frame_in_invl > frame_num)
- frame_num = it->last_frame_in_invl;
- }
- if (graph->calc_type == CALC_TYPE_LOAD) {
- load = TRUE;
- if (it->time_tot.secs + it->time_tot.nsecs > 0)
- outstanding_call = TRUE;
- }
- }
- }
-
- /* XXX - If the frame numbers of *calls* can somehow be determined, the first call or
- * response, whichever is first, and the last call or response, whichever is last,
- * could be highlighted. */
- if ((frame_num == 0) && load && outstanding_call) {
- statusbar_push_temporary_msg(
- "There is no response but at least one call is outstanding in this interval.");
- return FALSE;
- }
-
- if (frame_num != 0)
- cf_goto_frame(&cfile, frame_num);
- }
- return TRUE;
-}
-
-/* create a new backing pixmap of the appropriate size */
-static gboolean
-draw_area_configure_event(GtkWidget *widget, GdkEventConfigure *event _U_, gpointer user_data)
-{
- io_stat_t *io = (io_stat_t *)user_data;
- GtkWidget *save_bt;
- GtkAllocation widget_alloc;
- cairo_t *cr;
-#if GTK_CHECK_VERSION(2,22,0)
- surface_info_t *surface_info = g_new(surface_info_t, 1);
-#endif
-
-#if GTK_CHECK_VERSION(2,22,0)
- if (io->surface) {
- cairo_surface_destroy (io->surface);
- io->surface = NULL;
- }
-#else
- if (io->pixmap) {
- g_object_unref(io->pixmap);
- io->pixmap = NULL;
- }
-#endif
-
- gtk_widget_get_allocation(widget, &widget_alloc);
-#if GTK_CHECK_VERSION(2,22,0)
- io->surface = gdk_window_create_similar_surface (gtk_widget_get_window(widget),
- CAIRO_CONTENT_COLOR,
- widget_alloc.width,
- widget_alloc.height);
-
-#else
- io->pixmap = gdk_pixmap_new(gtk_widget_get_window(widget),
- widget_alloc.width,
- widget_alloc.height,
- -1);
-#endif
- io->surface_width = widget_alloc.width;
- io->surface_height = widget_alloc.height;
-
- save_bt = (GtkWidget *)g_object_get_data(G_OBJECT(io->window), "save_bt");
-#if GTK_CHECK_VERSION(2,22,0)
- surface_info->surface = io->surface;
- surface_info->width = widget_alloc.width;
- surface_info->height = widget_alloc.height;
- g_object_set_data(G_OBJECT(save_bt), "surface-info", surface_info);
- gtk_widget_set_sensitive(save_bt, TRUE);
-
- cr = cairo_create (io->surface);
-#else
- g_object_set_data(G_OBJECT(save_bt), "pixmap", io->pixmap);
- gtk_widget_set_sensitive(save_bt, TRUE);
-
- cr = gdk_cairo_create (io->pixmap);
-#endif
- cairo_rectangle (cr, 0, 0, widget_alloc.width, widget_alloc.height);
- cairo_set_source_rgb (cr, 1, 1, 1);
- cairo_fill (cr);
- cairo_destroy (cr);
-
- io_stat_redraw(io);
- return TRUE;
-}
-
-static void
-scrollbar_changed(GtkWidget *widget _U_, gpointer user_data)
-{
- io_stat_t *io = (io_stat_t *)user_data;
- guint32 mi;
-
- mi = (guint32) (gtk_adjustment_get_value(io->scrollbar_adjustment)
- + gtk_adjustment_get_page_size(io->scrollbar_adjustment));
-
- if (io->last_interval == mi) {
- return;
- }
-
- io->last_interval = (mi/io->interval) * io->interval;
- io_stat_redraw(io);
- return;
-}
-#if GTK_CHECK_VERSION(3,0,0)
-static gboolean
-draw_area_draw(GtkWidget *widget, cairo_t *cr, gpointer user_data)
-{
- io_stat_t *io = (io_stat_t *)user_data;
- GtkAllocation allocation;
-
- gtk_widget_get_allocation (widget, &allocation);
- cairo_set_source_surface (cr, io->surface, 0, 0);
- cairo_rectangle (cr, 0, 0, allocation.width, allocation.width);
- cairo_fill (cr);
-
- return FALSE;
-}
-#else
-/* redraw the screen from the backing pixmap */
-static gboolean
-draw_area_expose_event(GtkWidget *widget, GdkEventExpose *event, gpointer user_data)
-{
- io_stat_t *io = (io_stat_t *)user_data;
- cairo_t *cr = gdk_cairo_create (gtk_widget_get_window(widget));
-
-#if GTK_CHECK_VERSION(2,22,0)
- cairo_set_source_surface (cr, io->surface, 0, 0);
-#else
- ws_gdk_cairo_set_source_pixmap (cr, io->pixmap, 0, 0);
-#endif
- cairo_rectangle (cr, event->area.x, event->area.y, event->area.width, event->area.height);
- cairo_fill (cr);
-
- cairo_destroy (cr);
-
- return FALSE;
-}
-#endif
-static void
-create_draw_area(io_stat_t *io, GtkWidget *box)
-{
- io->draw_area = gtk_drawing_area_new();
- g_signal_connect(io->draw_area, "destroy", G_CALLBACK(draw_area_destroy_cb), io);
-
- gtk_widget_set_size_request(io->draw_area, io->surface_width, io->surface_height);
-
- /* signals needed to handle backing pixmap */
-#if GTK_CHECK_VERSION(3,0,0)
- g_signal_connect(io->draw_area, "draw", G_CALLBACK(draw_area_draw), io);
-#else
- g_signal_connect(io->draw_area, "expose-event", G_CALLBACK(draw_area_expose_event), io);
-#endif
- g_signal_connect(io->draw_area, "configure-event", G_CALLBACK(draw_area_configure_event), io);
- gtk_widget_add_events (io->draw_area, GDK_BUTTON_PRESS_MASK);
- g_signal_connect(io->draw_area, "button-press-event", G_CALLBACK(pixmap_clicked_event), io);
-
- gtk_widget_show(io->draw_area);
- gtk_box_pack_start(GTK_BOX(box), io->draw_area, TRUE, TRUE, 0);
-
- /* create the associated scrollbar */
- io->scrollbar_adjustment = (GtkAdjustment *)gtk_adjustment_new(0,0,0,0,0,0);
- io->scrollbar = gtk_scrollbar_new(GTK_ORIENTATION_HORIZONTAL, io->scrollbar_adjustment);
- gtk_widget_show(io->scrollbar);
- gtk_box_pack_start(GTK_BOX(box), io->scrollbar, FALSE, FALSE, 0);
- g_signal_connect(io->scrollbar_adjustment, "value-changed", G_CALLBACK(scrollbar_changed), io);
-}
-
-static void
-tick_interval_select(GtkWidget *item, gpointer user_data)
-{
- io_stat_t *io = (io_stat_t *)user_data;
- int i;
-
- i = gtk_combo_box_get_active (GTK_COMBO_BOX(item));
-
- io->interval = tick_interval_values[i];
- cf_retap_packets(&cfile);
- gdk_window_raise(gtk_widget_get_window(io->window));
- io_stat_redraw(io);
-}
-
-static void
-pixels_per_tick_select(GtkWidget *item, gpointer user_data)
-{
- io_stat_t *io = (io_stat_t *)user_data;
- int i;
-
- i = gtk_combo_box_get_active (GTK_COMBO_BOX(item));
- io->pixels_per_tick = pixels_per_tick[i];
- io_stat_redraw(io);
-}
-
-static void
-plot_style_select(GtkWidget *item, gpointer user_data)
-{
- io_stat_graph_t *ppt = (io_stat_graph_t *)user_data;
- int val;
-
- val = gtk_combo_box_get_active (GTK_COMBO_BOX(item));
-
- ppt->plot_style = val;
-
- io_stat_redraw(ppt->io);
-}
-
-static GtkWidget *
-create_pixels_per_tick_menu_items(io_stat_t *io)
-{
- char str[5];
- GtkWidget *combo_box;
- int i;
-
- combo_box = gtk_combo_box_text_new ();
-
- for (i=0; i<MAX_PIXELS_PER_TICK; i++) {
- g_snprintf(str, sizeof(str), "%u", pixels_per_tick[i]);
- gtk_combo_box_text_append_text (GTK_COMBO_BOX_TEXT (combo_box), str);
- }
- gtk_combo_box_set_active(GTK_COMBO_BOX(combo_box), DEFAULT_PIXELS_PER_TICK_INDEX);
- g_signal_connect(combo_box, "changed", G_CALLBACK(pixels_per_tick_select), io);
-
- return combo_box;
-}
-
-static void
-yscale_select(GtkWidget *item, gpointer user_data)
-{
- io_stat_t *io = (io_stat_t *)user_data;
- int i;
-
- i = gtk_combo_box_get_active (GTK_COMBO_BOX(item));
-
- io->max_y_units = yscale_max[i];
- io_stat_redraw(io);
-}
-
-static void
-filter_select(GtkWidget *item, gpointer user_data)
-{
- io_stat_t *io = (io_stat_t *)user_data;
- int i;
-
- i = gtk_combo_box_get_active (GTK_COMBO_BOX(item));
-
- if (i == NO_FILTER_ORDER) {
- io->filter_type = NO_FILTER;
- } else {
- io->filter_type = MOVING_AVERAGE_FILTER;
- io->filter_order = moving_average_orders[i];
- }
- io_stat_redraw(io);
-}
-
-static GtkWidget *
-create_tick_interval_menu_items(io_stat_t *io)
-{
- GtkWidget *combo_box;
- char str[15];
- int i;
-
- combo_box = gtk_combo_box_text_new ();
-
- for (i=0; i<MAX_TICK_VALUES; i++) {
- if (tick_interval_values[i] >= 60000) {
- g_snprintf(str, sizeof(str), "%u min", tick_interval_values[i]/60000);
- } else if (tick_interval_values[i] >= 1000) {
- g_snprintf(str, sizeof(str), "%u sec", tick_interval_values[i]/1000);
- } else if (tick_interval_values[i] >= 100) {
- g_snprintf(str, sizeof(str), "0.%1u sec", (tick_interval_values[i]/100)%10);
- } else if (tick_interval_values[i] >= 10) {
- g_snprintf(str, sizeof(str), "0.%02u sec", (tick_interval_values[i]/10)%10);
- } else {
- g_snprintf(str, sizeof(str), "0.%03u sec", (tick_interval_values[i])%10);
- }
- gtk_combo_box_text_append_text (GTK_COMBO_BOX_TEXT (combo_box), str);
- }
- gtk_combo_box_set_active(GTK_COMBO_BOX(combo_box), DEFAULT_TICK_VALUE_INDEX);
- g_signal_connect(combo_box, "changed", G_CALLBACK(tick_interval_select), io);
-
- return combo_box;
-}
-
-static GtkWidget *
-create_yscale_max_menu_items(io_stat_t *io)
-{
- char str[15];
- GtkWidget *combo_box;
- int i;
-
- combo_box = gtk_combo_box_text_new ();
- for (i=0; i<MAX_YSCALE; i++) {
- if (yscale_max[i] == LOGARITHMIC_YSCALE) {
- g_strlcpy(str, "Logarithmic", sizeof(str));
- } else if (yscale_max[i] == AUTO_MAX_YSCALE) {
- g_strlcpy(str, "Auto", sizeof(str));
- } else {
- g_snprintf(str, sizeof(str), "%u", yscale_max[i]);
- }
- gtk_combo_box_text_append_text (GTK_COMBO_BOX_TEXT (combo_box), str);
- }
- gtk_combo_box_set_active(GTK_COMBO_BOX(combo_box), DEFAULT_YSCALE_INDEX);
- g_signal_connect(combo_box, "changed", G_CALLBACK(yscale_select), io);
- return combo_box;
-}
-
-static GtkWidget *
-create_filter_menu_items(io_stat_t *io)
-{
- char str[15];
- GtkWidget *combo_box;
- int i;
-
- combo_box = gtk_combo_box_text_new ();
-
- for (i=0; i<MAX_MOVING_AVERAGE_ORDER; i++) {
- if (i == NO_FILTER_ORDER) {
- g_strlcpy(str, "No filter", sizeof(str));
- } else {
- g_snprintf(str, sizeof(str), "M.avg %u", moving_average_orders[i]);
- }
- gtk_combo_box_text_append_text (GTK_COMBO_BOX_TEXT (combo_box), str);
- }
- gtk_combo_box_set_active(GTK_COMBO_BOX(combo_box), 0);
- g_signal_connect(combo_box, "changed", G_CALLBACK(filter_select), io);
- return combo_box;
-}
-
-static void
-count_type_select(GtkWidget *item, gpointer user_data)
-{
- io_stat_t *io = (io_stat_t *)user_data;
- int i;
- GtkAllocation widget_alloc;
- static gboolean advanced_visible = FALSE;
-
- io->count_type = gtk_combo_box_get_active (GTK_COMBO_BOX(item));
-
- if (io->count_type == COUNT_TYPE_ADVANCED) {
- for (i=0; i<MAX_GRAPHS; i++) {
- disable_graph(&io->graphs[i]);
- gtk_widget_show(io->graphs[i].advanced_buttons);
- /* redraw the entire window so the unhidden widgets show up, hopefully */
- gtk_widget_get_allocation(io->window, &widget_alloc);
- gtk_widget_queue_draw_area(io->window,
- 0,
- 0,
- widget_alloc.width,
- widget_alloc.height);
- }
- advanced_visible = TRUE;
- io_stat_redraw(io);
- } else if (advanced_visible) {
- for (i=0; i<MAX_GRAPHS; i++) {
- gtk_widget_hide(io->graphs[i].advanced_buttons);
- filter_callback(item, &io->graphs[i]);
- }
- advanced_visible = FALSE;
- } else {
- io_stat_redraw(io);
- }
-}
-
-static GtkWidget *
-create_frames_or_bytes_menu_items(io_stat_t *io)
-{
- GtkWidget *combo_box;
- int i;
-
- combo_box = gtk_combo_box_text_new ();
-
- for (i=0; i<MAX_COUNT_TYPES; i++) {
- gtk_combo_box_text_append_text (GTK_COMBO_BOX_TEXT (combo_box), count_type_names[i]);
- }
- gtk_combo_box_set_active(GTK_COMBO_BOX(combo_box), DEFAULT_COUNT_TYPE);
- g_signal_connect(combo_box, "changed", G_CALLBACK(count_type_select), io);
- return combo_box;
-}
-
-static void
-create_ctrl_menu(io_stat_t *io, GtkWidget *box, const char *name, GtkWidget * (*func)(io_stat_t *io))
-{
- GtkWidget *hbox;
- GtkWidget *label;
- GtkWidget *combo_box;
-
- hbox = ws_gtk_box_new(GTK_ORIENTATION_HORIZONTAL, 0, FALSE);
- gtk_box_pack_start(GTK_BOX(box), hbox, FALSE, FALSE, 0);
- gtk_widget_show(hbox);
-
- label = gtk_label_new(name);
- gtk_widget_show(label);
- gtk_box_pack_start(GTK_BOX(hbox), label, FALSE, FALSE, 0);
-
- combo_box = (*func)(io);
- gtk_box_pack_end(GTK_BOX(hbox), combo_box, FALSE, FALSE, 0);
- gtk_widget_show(combo_box);
-}
-
-static void
-view_as_time_toggle_dest(GtkWidget *widget _U_, gpointer user_data)
-{
- io_stat_t *io = (io_stat_t *)user_data;
-
- io->view_as_time = io->view_as_time ? FALSE : TRUE;
-
- io_stat_redraw(io);
-}
-
-static void
-create_ctrl_area(io_stat_t *io, GtkWidget *box)
-{
- GtkWidget *frame_vbox;
- GtkWidget *frame;
- GtkWidget *vbox;
- GtkWidget *view_cb;
-
- frame_vbox = ws_gtk_box_new(GTK_ORIENTATION_VERTICAL, 0, FALSE);
- gtk_box_pack_start(GTK_BOX(box), frame_vbox, FALSE, FALSE, 0);
- gtk_widget_show(frame_vbox);
-
- frame = gtk_frame_new("X Axis");
- gtk_container_add(GTK_CONTAINER(frame_vbox), frame);
- gtk_widget_show(frame);
-
- vbox = ws_gtk_box_new(GTK_ORIENTATION_VERTICAL, 0, FALSE);
- gtk_container_add(GTK_CONTAINER(frame), vbox);
- gtk_container_set_border_width(GTK_CONTAINER(vbox), 3);
- gtk_widget_show(vbox);
-
- create_ctrl_menu(io, vbox, "Tick interval:", create_tick_interval_menu_items);
- create_ctrl_menu(io, vbox, "Pixels per tick:", create_pixels_per_tick_menu_items);
-
- view_cb = gtk_check_button_new_with_mnemonic("_View as time of day");
- gtk_container_add(GTK_CONTAINER(vbox), view_cb);
- gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(view_cb), io->view_as_time);
- g_signal_connect(view_cb, "toggled", G_CALLBACK(view_as_time_toggle_dest), io);
- gtk_widget_show(view_cb);
-
- frame = gtk_frame_new("Y Axis");
- gtk_container_add(GTK_CONTAINER(frame_vbox), frame);
- gtk_widget_show(frame);
-
- vbox = ws_gtk_box_new(GTK_ORIENTATION_VERTICAL, 0, FALSE);
- gtk_container_add(GTK_CONTAINER(frame), vbox);
- gtk_container_set_border_width(GTK_CONTAINER(vbox), 3);
- gtk_widget_show(vbox);
-
- create_ctrl_menu(io, vbox, "Unit:", create_frames_or_bytes_menu_items);
- create_ctrl_menu(io, vbox, "Scale:", create_yscale_max_menu_items);
- create_ctrl_menu(io, vbox, "Smooth:", create_filter_menu_items);
-
- return;
-}
-
-static void
-filter_callback(GtkWidget *widget, gpointer user_data)
-{
- io_stat_graph_t *gio = (io_stat_graph_t *)user_data;
- const char *filter;
- dfilter_t *dfilter;
- gchar *err_msg;
- const char *field_name = NULL;
-
- /* this graph is not active, just update display and redraw */
- if (!gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(gio->display_button))) {
- disable_graph(gio);
- io_stat_redraw(gio->io);
- return;
- }
-
- /* first check if the field string is valid */
- if (gio->io->count_type == COUNT_TYPE_ADVANCED) {
- GString *err_str;
- field_name = gtk_entry_get_text(GTK_ENTRY(gio->calc_field));
-
- err_str = check_field_unit(field_name, &gio->hf_index, CALC_TYPE_TO_ITEM_UNIT(gio->calc_type));
-
- if (err_str) {
- /* warn and bail out */
- simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK, "%s", err_str->str);
- g_string_free(err_str, TRUE);
- disable_graph(gio);
- io_stat_redraw(gio->io);
- return;
- }
- }
-
-
- /* first check if the filter string is valid. */
- filter = gtk_entry_get_text(GTK_ENTRY(gio->filter_field));
- if (!dfilter_compile(filter, &dfilter, &err_msg)) {
- bad_dfilter_alert_box(gtk_widget_get_toplevel(widget),
- filter, err_msg);
- g_free(err_msg);
- disable_graph(gio);
- io_stat_redraw(gio->io);
- return;
- }
- dfilter_free(dfilter);
-
- /* ok, we have a valid filter and the graph is active.
- first just try to delete any previous settings and then apply
- the new ones.
- */
- remove_tap_listener(gio);
-
- io_stat_reset(gio->io);
- enable_graph(gio, filter, field_name);
- cf_retap_packets(&cfile);
- gdk_window_raise(gtk_widget_get_window(gio->io->window));
- io_stat_redraw(gio->io);
-
- return;
-}
-
-static void
-calc_type_select(GtkWidget *item, gpointer user_data)
-{
- io_stat_graph_t *gio = (io_stat_graph_t *)user_data;
-
- gio->calc_type = gtk_combo_box_get_active (GTK_COMBO_BOX(item));
-
- /* disable the graph */
- disable_graph(gio);
- io_stat_redraw(gio->io);
-}
-
-static GtkWidget *
-create_calc_types_menu_items(io_stat_graph_t *gio)
-{
- GtkWidget *combo_box;
- int i;
-
- combo_box = gtk_combo_box_text_new ();
- for (i=0; i<MAX_CALC_TYPES; i++) {
- gtk_combo_box_text_append_text (GTK_COMBO_BOX_TEXT (combo_box), calc_type_names[i]);
- }
- gtk_combo_box_set_active(GTK_COMBO_BOX(combo_box), DEFAULT_CALC_TYPE);
- g_signal_connect(combo_box, "changed", G_CALLBACK(calc_type_select), gio);
- return combo_box;
-}
-
-static void
-create_advanced_menu(io_stat_graph_t *gio, GtkWidget *box, const char *name, GtkWidget *(*func)(io_stat_graph_t *io))
-{
- GtkWidget *hbox;
- GtkWidget *label;
- GtkWidget *combo_box;
-
- hbox = ws_gtk_box_new(GTK_ORIENTATION_HORIZONTAL, 0, FALSE);
- gtk_box_pack_start(GTK_BOX(box), hbox, FALSE, FALSE, 0);
- gtk_widget_show(hbox);
-
- label = gtk_label_new(name);
- gtk_widget_show(label);
- gtk_box_pack_start(GTK_BOX(hbox), label, FALSE, FALSE, 0);
-
- combo_box = (*func)(gio);
- gtk_box_pack_end(GTK_BOX(hbox), combo_box, FALSE, FALSE, 0);
- gtk_widget_show(combo_box);
-}
-
-static void
-create_advanced_field(io_stat_graph_t *gio, GtkWidget *box)
-{
- gio->calc_field = gtk_entry_new();
- gtk_box_pack_start(GTK_BOX(box), gio->calc_field, TRUE, TRUE, 0);
- gtk_widget_show(gio->calc_field);
- g_signal_connect(gio->calc_field, "activate", G_CALLBACK(filter_callback), gio);
- g_object_set_data (G_OBJECT(gio->calc_field), E_FILT_FIELD_NAME_ONLY_KEY, (gpointer)"");
- g_signal_connect(gio->calc_field, "changed", G_CALLBACK(filter_te_syntax_check_cb), NULL);
- g_object_set_data(G_OBJECT(box), E_FILT_AUTOCOMP_PTR_KEY, NULL);
- g_signal_connect(gio->calc_field, "key-press-event", G_CALLBACK (filter_string_te_key_pressed_cb), NULL);
- g_signal_connect(gio->io->window, "key-press-event", G_CALLBACK (filter_parent_dlg_key_pressed_cb), NULL);
- colorize_filter_te_as_empty(gio->calc_field);
-}
-
-static void
-create_advanced_box(io_stat_graph_t *gio, GtkWidget *box)
-{
- GtkWidget *hbox;
-
- hbox = ws_gtk_box_new(GTK_ORIENTATION_HORIZONTAL, 0, FALSE);
- gio->advanced_buttons = hbox;
- gtk_box_pack_start(GTK_BOX(box), hbox, TRUE, TRUE, 0);
- gtk_widget_hide(hbox);
-
- gio->calc_type = CALC_TYPE_SUM;
- create_advanced_menu(gio, hbox, "Calc:", create_calc_types_menu_items);
- create_advanced_field(gio, hbox);
-}
-
-static void
-filter_button_clicked(GtkWidget *w, gpointer user_data)
-{
- io_stat_graph_t *gio = (io_stat_graph_t *)user_data;
-
- display_filter_construct_cb(w, gio->args);
- return;
-}
-
-static void
-smooth_filter_toggled(GtkWidget *w, gpointer user_data)
-{
- io_stat_graph_t *gio = (io_stat_graph_t *)user_data;
-
- gio->follow_smooth =
- gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(w));
- io_stat_redraw(gio->io);
-}
-
-static void
-create_filter_box(io_stat_graph_t *gio, GtkWidget *box, int num)
-{
- GtkWidget *combo_box;
- GtkWidget *hbox;
- GtkWidget *label;
- GtkWidget *smooth;
- char str[256];
- int i;
-
- hbox = ws_gtk_box_new(GTK_ORIENTATION_HORIZONTAL, 3, FALSE);
- gtk_box_pack_start(GTK_BOX(box), hbox, FALSE, FALSE, 0);
- gtk_widget_show(hbox);
-
- g_snprintf(str, sizeof(str), "Graph %d", num);
- gio->display_button = gtk_toggle_button_new_with_label(str);
- gtk_box_pack_start(GTK_BOX(hbox), gio->display_button, FALSE, FALSE, 0);
- gtk_widget_show(gio->display_button);
- gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(gio->display_button), gio->display);
- g_signal_connect(gio->display_button, "toggled", G_CALLBACK(filter_callback), gio);
-
- label = gtk_label_new("Color");
- gtk_widget_show(label);
- gtk_box_pack_start(GTK_BOX(hbox), label, FALSE, FALSE, 0);
-
-#if GTK_CHECK_VERSION(3,0,0)
- gtk_widget_override_color(label, (GtkStateFlags)GTK_STATE_FLAG_NORMAL, &gio->rgba_color);
- /* XXX gtk_widget_override_color() takes flags not state */
- gtk_widget_override_color(label, (GtkStateFlags)GTK_STATE_ACTIVE, &gio->rgba_color);
- gtk_widget_override_color(label, (GtkStateFlags)GTK_STATE_PRELIGHT, &gio->rgba_color);
- gtk_widget_override_color(label, (GtkStateFlags)GTK_STATE_SELECTED, &gio->rgba_color);
- gtk_widget_override_color(label, (GtkStateFlags)GTK_STATE_INSENSITIVE, &gio->rgba_color);
-#else
- gtk_widget_modify_fg(label, GTK_STATE_NORMAL, &gio->color);
- gtk_widget_modify_fg(label, GTK_STATE_ACTIVE, &gio->color);
- gtk_widget_modify_fg(label, GTK_STATE_PRELIGHT, &gio->color);
- gtk_widget_modify_fg(label, GTK_STATE_SELECTED, &gio->color);
- gtk_widget_modify_fg(label, GTK_STATE_INSENSITIVE, &gio->color);
-#endif
-/* g_signal_connect(gio->display_button, "toggled", G_CALLBACK(filter_callback), gio);*/
-
-
- /* filter prefs dialog */
- gio->filter_bt = ws_gtk_button_new_from_stock(WIRESHARK_STOCK_DISPLAY_FILTER_ENTRY);
-
- g_snprintf(str, sizeof(str), "Wireshark: Display Filter IO-Stat (Filter:%d)", num);
- g_free( (gpointer) (gio->args->title) );
- gio->args->title = g_strdup(str);
-
- g_signal_connect(gio->filter_bt, "clicked", G_CALLBACK(filter_button_clicked), gio);
- g_signal_connect(gio->filter_bt, "destroy", G_CALLBACK(filter_button_destroy_cb), NULL);
-
- gtk_box_pack_start(GTK_BOX(hbox), gio->filter_bt, FALSE, TRUE, 0);
- gtk_widget_show(gio->filter_bt);
-
- gio->filter_field = gtk_entry_new();
- /* filter prefs dialog */
- g_object_set_data(G_OBJECT(gio->filter_bt), E_FILT_TE_PTR_KEY, gio->filter_field);
- /* filter prefs dialog */
-
- gtk_box_pack_start(GTK_BOX(hbox), gio->filter_field, TRUE, TRUE, 0);
- gtk_widget_show(gio->filter_field);
- g_signal_connect(gio->filter_field, "activate", G_CALLBACK(filter_callback), gio);
- g_signal_connect(gio->filter_field, "changed", G_CALLBACK(filter_te_syntax_check_cb), NULL);
- g_object_set_data(G_OBJECT(box), E_FILT_AUTOCOMP_PTR_KEY, NULL);
- g_signal_connect(gio->filter_field, "key-press-event", G_CALLBACK (filter_string_te_key_pressed_cb), NULL);
- g_signal_connect(gio->io->window, "key-press-event", G_CALLBACK (filter_parent_dlg_key_pressed_cb), NULL);
- colorize_filter_te_as_empty(gio->filter_field);
-
- create_advanced_box(gio, hbox);
-
- /*
- * create PlotStyle menu
- */
- g_snprintf(str, sizeof(str), " Style:");
- label = gtk_label_new(str);
- gtk_widget_show(label);
- gtk_box_pack_start(GTK_BOX(hbox), label, FALSE, FALSE, 0);
-
- combo_box = gtk_combo_box_text_new ();
- for (i=0; i<MAX_PLOT_STYLES; i++) {
- gtk_combo_box_text_append_text (GTK_COMBO_BOX_TEXT (combo_box), plot_style_name[i]);
- }
- gtk_combo_box_set_active(GTK_COMBO_BOX(combo_box), DEFAULT_PLOT_STYLE);
- g_signal_connect(combo_box, "changed", G_CALLBACK(plot_style_select), &gio->io->graphs[num-1]);
-
- gtk_box_pack_start(GTK_BOX(hbox), combo_box, FALSE, FALSE, 0);
- gtk_widget_show(combo_box);
-
- /*
- * Create smooth followfilter option
- */
- smooth = gtk_check_button_new_with_mnemonic("Smooth");
- gtk_widget_set_tooltip_text(smooth, "Only has effect if a smothing filter is set");
- gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(smooth),
- gio->follow_smooth);
- g_signal_connect(smooth, "toggled", G_CALLBACK(smooth_filter_toggled),
- gio);
- gtk_widget_show(smooth);
- gtk_box_pack_end(GTK_BOX(hbox), smooth, FALSE, FALSE, 0);
-
- return;
-}
-
-static void
-create_filter_area(io_stat_t *io, GtkWidget *box)
-{
- GtkWidget *frame;
- GtkWidget *vbox;
- int i;
-
- frame = gtk_frame_new("Graphs");
- gtk_box_pack_start(GTK_BOX(box), frame, TRUE, TRUE, 0);
- gtk_widget_show(frame);
-
- vbox = ws_gtk_box_new(GTK_ORIENTATION_VERTICAL, 1, FALSE);
- gtk_container_add(GTK_CONTAINER(frame), vbox);
- gtk_container_set_border_width(GTK_CONTAINER(vbox), 3);
- gtk_widget_show(vbox);
-
- for (i=0; i<MAX_GRAPHS; i++) {
- create_filter_box(&io->graphs[i], vbox, i+1);
- }
-
- return;
-}
-
-static void
-copy_as_csv_cb(GtkWindow *copy_bt _U_, gpointer user_data)
-{
- guint32 i, interval;
- guint64 val;
- char string[15];
- GtkClipboard *cb;
- GString *CSV_str = g_string_new("");
- io_stat_t *io = (io_stat_t *)user_data;
-
- g_string_append(CSV_str, "\"Interval start\"");
- for (i=0; i<MAX_GRAPHS; i++) {
- if (io->graphs[i].display) {
- g_string_append_printf(CSV_str, ",\"Graph %d\"", i+1);
- }
- }
- g_string_append(CSV_str,"\n");
-
- for (interval=0; interval<io->max_interval; interval+=io->interval) {
- print_interval_string (string, sizeof(string), interval, io, FALSE);
- g_string_append_printf(CSV_str, "\"%s\"", string);
- for (i=0; i<MAX_GRAPHS; i++) {
- if (io->graphs[i].display) {
- val = get_it_value(io, i, interval/io->interval);
- g_string_append_printf(CSV_str, ",\"%" G_GINT64_MODIFIER "d\"", val);
- }
- }
- g_string_append(CSV_str,"\n");
- }
-
- /* Now that we have the CSV data, copy it into the default clipboard */
- cb = gtk_clipboard_get(GDK_SELECTION_CLIPBOARD); /* Get the default clipboard */
- gtk_clipboard_set_text(cb, CSV_str->str, -1); /* Copy the CSV data into the clipboard */
- g_string_free(CSV_str, TRUE); /* Free the memory */
-}
-
-static void
-init_io_stat_window(io_stat_t *io)
-{
- GtkWidget *vbox;
- GtkWidget *hbox;
- GtkWidget *bbox;
- GtkWidget *close_bt, *help_bt;
- GtkWidget *copy_bt;
- GtkWidget *save_bt;
-
- /* create the main window, transient_for top_level */
- io->window = dlg_window_new("I/O Graphs");
- gtk_window_set_destroy_with_parent (GTK_WINDOW(io->window), TRUE);
-
- vbox = ws_gtk_box_new(GTK_ORIENTATION_VERTICAL, 0, FALSE);
- gtk_container_add(GTK_CONTAINER(io->window), vbox);
- gtk_widget_show(vbox);
-
- create_draw_area(io, vbox);
-
- 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_widget_show(hbox);
-
- create_filter_area(io, hbox);
- create_ctrl_area(io, hbox);
-
- io_stat_set_title(io);
-
- bbox = dlg_button_row_new(GTK_STOCK_CLOSE, GTK_STOCK_SAVE,
- GTK_STOCK_COPY, GTK_STOCK_HELP, NULL);
- gtk_box_pack_start(GTK_BOX(vbox), bbox, FALSE, FALSE, 0);
- gtk_widget_show(bbox);
-
- close_bt = (GtkWidget *)g_object_get_data(G_OBJECT(bbox), GTK_STOCK_CLOSE);
- window_set_cancel_button(io->window, close_bt, window_cancel_button_cb);
- gtk_widget_set_tooltip_text(close_bt, "Close this dialog");
- save_bt = (GtkWidget *)g_object_get_data(G_OBJECT(bbox), GTK_STOCK_SAVE);
- gtk_widget_set_sensitive(save_bt, FALSE);
- gtk_widget_set_tooltip_text(save_bt, "Save the displayed graph to a file");
- g_signal_connect(save_bt, "clicked", G_CALLBACK(pixmap_save_cb), NULL);
- g_object_set_data(G_OBJECT(io->window), "save_bt", save_bt);
-
- copy_bt = (GtkWidget *)g_object_get_data(G_OBJECT(bbox), GTK_STOCK_COPY);
- gtk_widget_set_tooltip_text(copy_bt,
- "Copy values from selected graphs to the clipboard in"
- " CSV (Comma Separated Values) format");
- g_signal_connect(copy_bt, "clicked", G_CALLBACK(copy_as_csv_cb), io);
-
- help_bt = (GtkWidget *)g_object_get_data(G_OBJECT(bbox), GTK_STOCK_HELP);
- g_signal_connect(help_bt, "clicked", G_CALLBACK(topic_cb), (gpointer)HELP_STATS_IO_GRAPH_DIALOG);
- gtk_widget_set_tooltip_text (help_bt, "Show topic specific help");
- g_signal_connect(io->window, "delete-event", G_CALLBACK(window_delete_event_cb), NULL);
-
- gtk_widget_show(io->window);
- window_present(io->window);
-}
-
-void
-gui_iostat_cb(GtkAction *action _U_, gpointer user_data _U_)
-{
- iostat_init(NULL,NULL);
-}
-
-static stat_tap_ui iostat_ui = {
- REGISTER_STAT_GROUP_GENERIC,
- NULL,
- "io,stat",
- iostat_init,
- 0,
- NULL
-};
-
-void
-register_tap_listener_gtk_iostat(void)
-{
- register_stat_tap_ui(&iostat_ui, NULL);
-}
-
-/*
- * Editor modelines - http://www.wireshark.org/tools/modelines.html
- *
- * Local variables:
- * c-basic-offset: 4
- * tab-width: 8
- * indent-tabs-mode: nil
- * End:
- *
- * vi: set shiftwidth=4 tabstop=8 expandtab:
- * :indentSize=4:tabSize=8:noTabs=true:
- */