*
* 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
-#ifdef HAVE_CONFIG_H
-# include "config.h"
-#endif
+#include "config.h"
#include <stdio.h>
#include <string.h>
typedef struct _io_stat_graph_t {
struct _io_stat_t *io;
- io_item_t items[NUM_IO_ITEMS];
+ gpointer items[NUM_IO_ITEMS];
int plot_style;
gboolean display;
GtkWidget *display_button;
GtkAdjustment *scrollbar_adjustment;
GtkWidget *scrollbar;
- int pixmap_width;
- int pixmap_height;
+ int surface_width;
+ int surface_height;
int pixels_per_tick;
int max_y_units;
int count_type;
for(i=0;i<MAX_GRAPHS;i++){
for(j=0;j<NUM_IO_ITEMS;j++){
io_item_t *ioi;
- ioi=&io->graphs[i].items[j];
+ ioi=io->graphs[i].items[j];
ioi->frames=0;
ioi->bytes=0;
}
/* Point to the appropriate io_item_t struct */
- it = &graph->items[idx];
+ it = graph->items[idx];
/* Set the first and last frame num in current interval matching the target field+filter */
if (it->first_frame_in_invl == 0) {
pt = t;
}
while(t){
- graph->items[j].time_tot.nsecs += (int) (pt * 1000);
- if(graph->items[j].time_tot.nsecs > 1000000000){
- graph->items[j].time_tot.secs++;
- graph->items[j].time_tot.nsecs -= 1000000000;
+ io_item_t *item;
+
+ item = (io_item_t*)graph->items[j];
+ item->time_tot.nsecs += (int) (pt * 1000);
+ if(item->time_tot.nsecs > 1000000000){
+ item->time_tot.secs++;
+ item->time_tot.nsecs -= 1000000000;
}
if(j==0){
}
break;
default:
- /*
- * "Can't happen"; see the "check that the
- * type is compatible" check in
- * filter_callback().
- */
- g_assert_not_reached();
+ if(graph->calc_type == CALC_TYPE_COUNT_FRAMES ||
+ graph->calc_type == CALC_TYPE_COUNT_FIELDS) {
+ /*
+ * It's not an integeresque type, but
+ * all we want to do is count it, so
+ * that's all right.
+ */
+ it->fields++;
+ }
+ else {
+ /*
+ * "Can't happen"; see the "check that the
+ * type is compatible" check in
+ * filter_callback().
+ */
+ g_assert_not_reached();
+ }
break;
}
}
static guint64
get_it_value(io_stat_t *io, int graph, int idx)
{
- double value=0;
+ guint64 value=0; /* FIXME: loss of precision, visible on the graph for small values */
int adv_type;
io_item_t *it;
guint32 interval;
- it = &io->graphs[graph].items[idx];
+ it = io->graphs[graph].items[idx];
switch(io->count_type){
case COUNT_TYPE_FRAMES:
return it->bytes;
case COUNT_TYPE_BITS:
return (it->bytes * 8);
- }
-
-
- adv_type=proto_registrar_get_ftype(io->graphs[graph].hf_index);
- switch(adv_type){
- case FT_NONE:
+ case COUNT_TYPE_ADVANCED:
switch(io->graphs[graph].calc_type){
case CALC_TYPE_COUNT_FRAMES:
- value=it->frames;
- break;
+ return it->frames;
case CALC_TYPE_COUNT_FIELDS:
- value=it->fields;
- break;
+ 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 CALC_TYPE_SUM:
value=it->int_tot;
break;
- case CALC_TYPE_COUNT_FRAMES:
- value=it->frames;
- break;
- case CALC_TYPE_COUNT_FIELDS:
- value=it->fields;
- break;
case CALC_TYPE_MAX:
value=it->int_max;
break;
case FT_FLOAT:
switch(io->graphs[graph].calc_type){
case CALC_TYPE_SUM:
- value=it->float_tot;
- break;
- case CALC_TYPE_COUNT_FRAMES:
- value=it->frames;
- break;
- case CALC_TYPE_COUNT_FIELDS:
- value=it->fields;
+ value=(guint64)it->float_tot;
break;
case CALC_TYPE_MAX:
- value=it->float_max;
+ value=(guint64)it->float_max;
break;
case CALC_TYPE_MIN:
- value=it->float_min;
+ value=(guint64)it->float_min;
break;
case CALC_TYPE_AVG:
if(it->fields){
- value=it->float_tot/it->fields;
+ value=(guint64)it->float_tot/it->fields;
} else {
value=0;
}
case FT_DOUBLE:
switch(io->graphs[graph].calc_type){
case CALC_TYPE_SUM:
- value=it->double_tot;
- break;
- case CALC_TYPE_COUNT_FRAMES:
- value=it->frames;
- break;
- case CALC_TYPE_COUNT_FIELDS:
- value=it->fields;
+ value=(guint64)it->double_tot;
break;
case CALC_TYPE_MAX:
- value=it->double_max;
+ value=(guint64)it->double_max;
break;
case CALC_TYPE_MIN:
- value=it->double_min;
+ value=(guint64)it->double_min;
break;
case CALC_TYPE_AVG:
if(it->fields){
- value=it->double_tot/it->fields;
+ value=(guint64)it->double_tot/it->fields;
} else {
value=0;
}
break;
case FT_RELATIVE_TIME:
switch(io->graphs[graph].calc_type){
- case CALC_TYPE_COUNT_FRAMES:
- value=it->frames;
- break;
- case CALC_TYPE_COUNT_FIELDS:
- value=it->fields;
- break;
case CALC_TYPE_MAX:
- value=(guint32) (it->time_max.secs*1000000 + it->time_max.nsecs/1000);
+ value=(guint64) (it->time_max.secs*1000000 + it->time_max.nsecs/1000);
break;
case CALC_TYPE_MIN:
- value=(guint32) (it->time_min.secs*1000000 + it->time_min.nsecs/1000);
+ value=(guint64) (it->time_min.secs*1000000 + it->time_min.nsecs/1000);
break;
case CALC_TYPE_SUM:
- value=(guint32) (it->time_tot.secs*1000000 + it->time_tot.nsecs/1000);
+ value=(guint64) (it->time_tot.secs*1000000 + it->time_tot.nsecs/1000);
break;
case CALC_TYPE_AVG:
if(it->fields){
t=it->time_tot.secs;
t=t*1000000+it->time_tot.nsecs/1000;
- value=(guint32) (t/it->fields);
+ value=(guint64) (t/it->fields);
} else {
value=0;
}
} else {
interval = io->interval;
}
- value = (guint32) ((it->time_tot.secs*1000000 + it->time_tot.nsecs/1000) / interval);
+ value = (guint64) ((it->time_tot.secs*1000000 + it->time_tot.nsecs/1000) / interval);
break;
default:
break;
default:
break;
}
- return (guint64)value; /* FIXME: loss of precision, visible on the graph for small values */
+ return value;
}
static void
}
static void
-io_stat_draw(io_stat_t *io)
+ 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 */
- guint32 num_time_intervals; /* number of intervals relative to 1 */
- guint32 max_value; /* max value of seen data */
- guint32 max_y; /* max value of the Y scale */
- gboolean draw_y_as_time;
- 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 length of the intervals we have data for
- * so we know how large arrays we need to malloc()
- */
- num_time_intervals = io->num_items+1;
-
- /* XXX move this check to _packet() */
- if(num_time_intervals > NUM_IO_ITEMS){
- simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK, "IO-Stat error. There are too many entries, bailing out");
- return;
- }
-
- /*
- * 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) < num_time_intervals; 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;
- 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;
- }
- 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, 15, 100000, 100000, TRUE); /* 100 ms */
- } else {
- print_time_scale_string(label_string, 15, max_y, max_y, FALSE);
- }
- } else {
- g_snprintf(label_string, 15, "%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->pixmap_width-io->right_x_border - io->left_x_border;
- draw_height = io->pixmap_height-top_y_border - bottom_y_border;
-
- /*
- * Add a warning if too many entries
- */
- if (num_time_intervals >= NUM_IO_ITEMS-1) {
- g_snprintf (label_string, 45, "Warning: Graph limited to %d entries", NUM_IO_ITEMS);
- pango_layout_set_text(layout, label_string, -1);
-
-#if GTK_CHECK_VERSION(2,22,0)
- cr = cairo_create (io->surface);
-#else
- cr = gdk_cairo_create (io->pixmap);
-#endif
- cairo_move_to (cr, 5, io->pixmap_height-bottom_y_border-draw_height-label_height/2);
- pango_cairo_show_layout (cr, layout);
- cairo_destroy (cr);
- cr = NULL;
- }
-
- /* 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->pixmap_width-io->right_x_border+1.5, top_y_border + 0.5);
- cairo_line_to(cr, io->pixmap_width-io->right_x_border+1.5, io->pixmap_height-bottom_y_border + 0.5);
- cairo_stroke(cr);
- cairo_destroy(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->pixmap_height-bottom_y_border;
- } else if (i==tics) {
- /* position for the top value, do not draw logarithmic tics above graph */
- ypos=io->pixmap_height-bottom_y_border-draw_height;
- } else {
- int j;
- /* draw the logarithmic tics */
- for(j=2; j<10; j++) {
- ypos=(int)(io->pixmap_height-bottom_y_border-(draw_height-ystart)*(i+log10((double)j))/tics-ystart);
- /* draw the tick */
-#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->pixmap_width-io->right_x_border+1.5, ypos+0.5);
- cairo_line_to(cr, io->pixmap_width-io->right_x_border+1.5+xwidth,ypos+0.5);
- cairo_stroke(cr);
- cairo_destroy(cr);
- }
- ypos=io->pixmap_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->pixmap_height-bottom_y_border-draw_height*i/10;
- }
- /* draw the tick */
+ 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 */
+ guint32 num_time_intervals; /* number of intervals relative to 1 */
+ guint64 max_value; /* max value of seen data */
+ guint32 max_y; /* max value of the Y scale */
+ gboolean draw_y_as_time;
+ 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 length of the intervals we have data for
+ * so we know how large arrays we need to malloc()
+ */
+ num_time_intervals = io->num_items+1;
+
+ /* XXX move this check to _packet() */
+ if(num_time_intervals > NUM_IO_ITEMS){
+ simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK, "IO-Stat error. There are too many entries, bailing out");
+ return;
+ }
+
+ /*
+ * 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) < num_time_intervals; 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);
+ cr = cairo_create (io->surface);
#else
- cr = gdk_cairo_create (io->pixmap);
+ cr = gdk_cairo_create (io->pixmap);
#endif
- cairo_set_line_width (cr, 1.0);
- cairo_move_to(cr, io->pixmap_width-io->right_x_border+1.5, ypos+0.5);
- cairo_line_to(cr, io->pixmap_width-io->right_x_border+1.5+xwidth,ypos+0.5);
- cairo_stroke(cr);
- cairo_destroy(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, 15, value, value, TRUE);
- } else {
- g_snprintf(label_string, 15, "%d", value);
- }
- } else {
- value = (max_y/10)*i;
- if(draw_y_as_time){
- print_time_scale_string(label_string, 15, value, max_y, FALSE);
- } else {
- g_snprintf(label_string, 15, "%d", value);
- }
- }
-
- pango_layout_set_text(layout, label_string, -1);
- pango_layout_get_pixel_size(layout, &lwidth, NULL);
-
-#if GTK_CHECK_VERSION(2,22,0)
- cr = cairo_create (io->surface);
-#else
- cr = gdk_cairo_create (io->pixmap);
-#endif
- cairo_move_to (cr, io->pixmap_width-io->right_x_border+15+label_width-lwidth, ypos-label_height/2);
- pango_cairo_show_layout (cr, layout);
- cairo_destroy (cr);
- cr = NULL;
-
- }
- }
+ 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;
+ 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;
+ }
+ 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, 15, 100000, 100000, TRUE); /* 100 ms */
+ } else {
+ print_time_scale_string(label_string, 15, max_y, max_y, FALSE);
+ }
+ } else {
+ g_snprintf(label_string, 15, "%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;
+
+ /*
+ * Add a warning if too many entries
+ */
+ if (num_time_intervals >= NUM_IO_ITEMS-1) {
+ g_snprintf (label_string, 45, "Warning: Graph limited to %d entries", NUM_IO_ITEMS);
+ pango_layout_set_text(layout, label_string, -1);
- /* 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 */
#if GTK_CHECK_VERSION(2,22,0)
- cr = cairo_create (io->surface);
+ cr = cairo_create (io->surface);
#else
- cr = gdk_cairo_create (io->pixmap);
+ cr = gdk_cairo_create (io->pixmap);
#endif
- cairo_set_line_width (cr, 1.0);
- cairo_move_to(cr, io->left_x_border+0.5, io->pixmap_height-bottom_y_border+1.5);
- cairo_line_to(cr, io->pixmap_width-io->right_x_border+1.5,io->pixmap_height-bottom_y_border+1.5);
- cairo_stroke(cr);
- cairo_destroy(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, 5, io->surface_height-bottom_y_border-draw_height-label_height/2);
+ pango_cairo_show_layout (cr, layout);
+ cairo_destroy (cr);
+ cr = NULL;
+ }
+
+ /* 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);
+ cr = cairo_create (io->surface);
#else
- cr = gdk_cairo_create (io->pixmap);
+ cr = gdk_cairo_create (io->pixmap);
#endif
- cairo_set_line_width (cr, 1.0);
- cairo_move_to(cr, x-1-io->pixels_per_tick/2+0.5, io->pixmap_height-bottom_y_border+1.5);
- cairo_line_to(cr, x-1-io->pixels_per_tick/2+0.5, io->pixmap_height-bottom_y_border+xlen+1.5);
- cairo_stroke(cr);
- cairo_destroy(cr);
- if(xlen==10){
- int lwidth, x_pos;
- print_interval_string (label_string, 15, 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->pixmap_width-5)) {
- x_pos=io->pixmap_width-lwidth-5;
- } else {
- x_pos=x-1-io->pixels_per_tick/2-lwidth/2;
- }
+ 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, 15, value, value, TRUE);
+ } else {
+ g_snprintf(label_string, 15, "%d", value);
+ }
+ } else {
+ value = (max_y/10)*i;
+ if(draw_y_as_time){
+ print_time_scale_string(label_string, 15, value, max_y, FALSE);
+ } else {
+ g_snprintf(label_string, 15, "%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, 15, 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);
+ cr = cairo_create (io->surface);
#else
- cr = gdk_cairo_create (io->pixmap);
+ cr = gdk_cairo_create (io->pixmap);
#endif
- cairo_move_to (cr, x_pos, io->pixmap_height-bottom_y_border+15);
- pango_cairo_show_layout (cr, layout);
- cairo_destroy (cr);
- cr = NULL;
- }
+ cairo_set_line_width (cr, 1.0);
- }
- g_object_unref(G_OBJECT(layout));
-
- /*
- * Loop over all graphs and draw them
- */
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;
- guint32 mavg_to_remove = 0, mavg_to_add = 0;
-
- if(!io->graphs[i].display){
- continue;
- }
-
- if(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, warmup_interval/io->interval);
- mavg_in_average_count++;
- mavg_left++;
- }
- mavg_cumulated += get_it_value(io, i, warmup_interval/io->interval);
- mavg_in_average_count++;
- for(warmup_interval += io->interval;
- ((warmup_interval < (first_interval + (io->filter_order/2) * io->interval)) &&
- (warmup_interval <= (io->num_items * io->interval)));
- warmup_interval += io->interval) {
-
- mavg_cumulated += get_it_value(io, i, 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->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->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, mavg_to_remove/io->interval);
- mavg_to_remove += io->interval;
- }
- if (mavg_to_add<=io->num_items*io->interval){
- mavg_in_average_count++;
- mavg_cumulated += get_it_value(io, i, 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:
- /* Dont draw anything if the segment entirely above the top of the graph
- */
- if( (prev_y_pos!=0) || (y_pos!=0) ){
-#if GTK_CHECK_VERSION(2,22,0)
- cr = cairo_create (io->surface);
-#else
- cr = gdk_cairo_create (io->pixmap);
-#endif
- gdk_cairo_set_source_color (cr, &io->graphs[i].color);
- cairo_set_line_width (cr, 1.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);
- cairo_stroke(cr);
- cairo_destroy(cr);
- }
- break;
- case PLOT_STYLE_IMPULSE:
- if(val){
-#if GTK_CHECK_VERSION(2,22,0)
- cr = cairo_create (io->surface);
-#else
- cr = gdk_cairo_create (io->pixmap);
-#endif
- gdk_cairo_set_source_color (cr, &io->graphs[i].color);
- cairo_set_line_width (cr, 1.0);
- 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);
- cairo_stroke(cr);
- cairo_destroy(cr);
- }
- break;
- case PLOT_STYLE_FILLED_BAR:
- if(val){
-#if GTK_CHECK_VERSION(2,22,0)
- cr = cairo_create (io->surface);
-#else
- cr = gdk_cairo_create (io->pixmap);
-#endif
- 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_color (cr, &io->graphs[i].color);
- cairo_fill (cr);
- cairo_destroy (cr);
- }
- break;
- case PLOT_STYLE_DOT:
- if(val){
-#if GTK_CHECK_VERSION(2,22,0)
- cr = cairo_create (io->surface);
-#else
- cr = gdk_cairo_create (io->pixmap);
-#endif
- 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_color (cr, &io->graphs[i].color);
- cairo_fill (cr);
- cairo_destroy (cr);
- }
- break;
- }
-
- prev_y_pos=y_pos;
- prev_x_pos=x_pos;
- }
- }
+ 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->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->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->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:
+ /* Dont 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_color (cr, &io->graphs[i].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_color (cr, &io->graphs[i].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_color (cr, &io->graphs[i].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_color (cr, &io->graphs[i].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));
+ 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);
+ cairo_set_source_surface (cr, io->surface, 0, 0);
#else
- gdk_cairo_set_source_pixmap (cr, io->pixmap, 0, 0);
+ gdk_cairo_set_source_pixmap (cr, io->pixmap, 0, 0);
#endif
- cairo_rectangle (cr, 0, 0, io->pixmap_width, io->pixmap_height);
- cairo_fill (cr);
-
- cairo_destroy (cr);
-
- /* update the scrollbar */
- if (io->max_interval == 0) {
- gtk_adjustment_set_upper(io->scrollbar_adjustment, (gfloat) io->interval);
- gtk_adjustment_set_step_increment(io->scrollbar_adjustment, (gfloat) (io->interval/10));
- gtk_adjustment_set_page_increment(io->scrollbar_adjustment, (gfloat) io->interval);
- } else {
- gtk_adjustment_set_upper(io->scrollbar_adjustment, (gfloat) io->max_interval);
- gtk_adjustment_set_step_increment(io->scrollbar_adjustment, (gfloat) ((last_interval-first_interval)/10));
- gtk_adjustment_set_page_increment(io->scrollbar_adjustment, (gfloat) (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, (gfloat)first_interval);
- gtk_adjustment_changed(io->scrollbar_adjustment);
- gtk_adjustment_value_changed(io->scrollbar_adjustment);
+ 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, (gfloat) io->interval);
+ gtk_adjustment_set_step_increment(io->scrollbar_adjustment, (gfloat) (io->interval/10));
+ gtk_adjustment_set_page_increment(io->scrollbar_adjustment, (gfloat) io->interval);
+ } else {
+ gtk_adjustment_set_upper(io->scrollbar_adjustment, (gfloat) io->max_interval);
+ gtk_adjustment_set_step_increment(io->scrollbar_adjustment, (gfloat) ((last_interval-first_interval)/10));
+ gtk_adjustment_set_page_increment(io->scrollbar_adjustment, (gfloat) (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, (gfloat)first_interval);
+ gtk_adjustment_changed(io->scrollbar_adjustment);
+ gtk_adjustment_value_changed(io->scrollbar_adjustment);
}
{
if (gio->display) {
gio->display=FALSE;
- protect_thread_critical_region();
remove_tap_listener(gio);
- unprotect_thread_critical_region();
gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(gio->display_button),
FALSE);
}
}
static void
-iostat_init(const char *optarg _U_, void* userdata _U_)
+iostat_init(const char *opt_arg _U_, void* userdata _U_)
{
io_stat_t *io;
- int i=0;
+ int i=0, j=0;
static GdkColor col[MAX_GRAPHS] = {
{0, 0x0000, 0x0000, 0x0000}, /* Black */
{0, 0xffff, 0x0000, 0x0000}, /* Red */
#endif
GString *error_string;
- io=g_malloc(sizeof(io_stat_t));
+ io=g_new(io_stat_t,1);
io->needs_redraw=TRUE;
io->interval=tick_interval_values[DEFAULT_TICK_VALUE_INDEX];
io->window=NULL;
#endif
io->scrollbar=NULL;
io->scrollbar_adjustment=NULL;
- io->pixmap_width=500;
- io->pixmap_height=200;
+ 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->graphs[i].advanced_buttons=NULL;
io->graphs[i].io=io;
- io->graphs[i].args=g_malloc(sizeof(construct_args_t));
+ 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;
+
+ for(j=0;j<NUM_IO_ITEMS;j++){
+ io->graphs[i].items[j] = g_new(io_item_t,1);
+ }
}
io_stat_reset(io);
error_string=enable_graph(&io->graphs[0], NULL, NULL);
- g_assert((error_string == NULL) && "Can't attach io_stat tap !");
+ /* Can't attach io_stat tap ! */
+ g_assert(error_string == NULL);
#if 0
if(error_string){
draw_area_destroy_cb(GtkWidget *widget _U_, gpointer user_data)
{
io_stat_t *io = user_data;
- int i;
+ int i,j;
GtkWidget *save_bt = g_object_get_data(G_OBJECT(io->window), "save_bt");
surface_info_t *surface_info = g_object_get_data(G_OBJECT(save_bt), "surface-info");
for(i=0;i<MAX_GRAPHS;i++){
if(io->graphs[i].display){
- protect_thread_critical_region();
remove_tap_listener(&io->graphs[i]);
- unprotect_thread_critical_region();
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;
+ for(j=0;j<NUM_IO_ITEMS;j++){
+ g_free(io->graphs[i].items[j]);
+ io->graphs[i].items[j]=NULL;
+ }
}
}
g_free(io);
int i;
gboolean load=FALSE, outstanding_call=FALSE;
- draw_width = io->pixmap_width - io->right_x_border - io->left_x_border;
+ 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))) {
last_interval = io->last_interval;
/* Get the interval that was clicked */
- interval = (guint32) (
- (last_interval / io->interval) -
- ((draw_width + io->left_x_border - event->x-io->pixels_per_tick / 2 - 1) / io->pixels_per_tick)
- );
+ 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];
+ 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;
widget_alloc.height,
-1);
#endif
- io->pixmap_width=widget_alloc.width;
- io->pixmap_height=widget_alloc.height;
+ io->surface_width=widget_alloc.width;
+ io->surface_height=widget_alloc.height;
save_bt = g_object_get_data(G_OBJECT(io->window), "save_bt");
#if GTK_CHECK_VERSION(2,22,0)
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->pixmap_width, io->pixmap_height);
+ 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)
first just try to delete any previous settings and then apply
the new ones.
*/
- protect_thread_critical_region();
remove_tap_listener(gio);
- unprotect_thread_critical_region();
io_stat_reset(gio->io);
enable_graph(gio, filter, field);
gtk_box_pack_start(GTK_BOX(hbox), label, FALSE, FALSE, 0);
#if GTK_CHECK_VERSION(3,0,0)
- gtk_widget_override_color(label, GTK_STATE_NORMAL, &gio->rgba_color);
+ gtk_widget_override_color(label, GTK_STATE_FLAG_NORMAL, &gio->rgba_color);
+ /* XXX gtk_widget_override_color() takes flags not state */
gtk_widget_override_color(label, GTK_STATE_ACTIVE, &gio->rgba_color);
gtk_widget_override_color(label, GTK_STATE_PRELIGHT, &gio->rgba_color);
gtk_widget_override_color(label, GTK_STATE_SELECTED, &gio->rgba_color);
create_draw_area(io, vbox);
hbox=ws_gtk_box_new(GTK_ORIENTATION_HORIZONTAL, 3, FALSE);
- gtk_box_pack_end(GTK_BOX(vbox), hbox, FALSE, FALSE, 5);
+ 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);