aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAnders Broman <anders.broman@ericsson.com>2011-08-14 21:40:25 +0000
committerAnders Broman <anders.broman@ericsson.com>2011-08-14 21:40:25 +0000
commit05178612dee5abf2e00655b69e32f09658625f34 (patch)
treee9d9774bde269ab0cfbf348c956ee9704a775a19
parenta17cde69ecf02d30ed345493f91dbbb837ddee7f (diff)
downloadwireshark-05178612dee5abf2e00655b69e32f09658625f34.tar.gz
wireshark-05178612dee5abf2e00655b69e32f09658625f34.tar.bz2
wireshark-05178612dee5abf2e00655b69e32f09658625f34.zip
Make save IO graph work, I had to make a local copy of
GTK 3.0 function gdk_pixbuf_get_from_surface() put in gui_util.c svn path=/trunk/; revision=38541
-rw-r--r--gtk/gui_utils.c181
-rw-r--r--gtk/gui_utils.h9
-rw-r--r--gtk/io_stat.c74
-rw-r--r--gtk/pixmap_save.c20
-rw-r--r--gtk/pixmap_save.h5
5 files changed, 253 insertions, 36 deletions
diff --git a/gtk/gui_utils.c b/gtk/gui_utils.c
index 7a9cdcf276..d6c21e4a21 100644
--- a/gtk/gui_utils.c
+++ b/gtk/gui_utils.c
@@ -1697,3 +1697,184 @@ ws_combo_box_set_active_iter(GtkComboBox *combo_box, GtkTreeIter *iter)
{
gtk_combo_box_set_active_iter(combo_box, iter);
}
+
+
+/* Copy functions from GTK 3.0 to be used if GTK version is 2.22 or 2.24 to be able save Graphs to file */
+#if GTK_CHECK_VERSION(2,22,0)
+#if !GTK_CHECK_VERSION(3,0,0)
+static cairo_format_t
+gdk_cairo_format_for_content (cairo_content_t content)
+{
+ switch (content)
+ {
+ case CAIRO_CONTENT_COLOR:
+ return CAIRO_FORMAT_RGB24;
+ case CAIRO_CONTENT_ALPHA:
+ return CAIRO_FORMAT_A8;
+ case CAIRO_CONTENT_COLOR_ALPHA:
+ default:
+ return CAIRO_FORMAT_ARGB32;
+ }
+}
+
+static cairo_surface_t *
+gdk_cairo_surface_coerce_to_image (cairo_surface_t *surface,
+ cairo_content_t content,
+ int src_x,
+ int src_y,
+ int width,
+ int height)
+{
+ cairo_surface_t *copy;
+ cairo_t *cr;
+
+ copy = cairo_image_surface_create (gdk_cairo_format_for_content (content),
+ width,
+ height);
+
+ cr = cairo_create (copy);
+ cairo_set_operator (cr, CAIRO_OPERATOR_SOURCE);
+ cairo_set_source_surface (cr, surface, -src_x, -src_y);
+ cairo_paint (cr);
+ cairo_destroy (cr);
+
+ return copy;
+}
+
+static void
+convert_alpha (guchar *dest_data,
+ int dest_stride,
+ guchar *src_data,
+ int src_stride,
+ int src_x,
+ int src_y,
+ int width,
+ int height)
+{
+ int x, y;
+
+ src_data += src_stride * src_y + src_x * 4;
+
+ for (y = 0; y < height; y++) {
+ guint32 *src = (guint32 *) src_data;
+
+ for (x = 0; x < width; x++) {
+ guint alpha = src[x] >> 24;
+
+ if (alpha == 0)
+ {
+ dest_data[x * 4 + 0] = 0;
+ dest_data[x * 4 + 1] = 0;
+ dest_data[x * 4 + 2] = 0;
+ }
+ else
+ {
+ dest_data[x * 4 + 0] = (((src[x] & 0xff0000) >> 16) * 255 + alpha / 2) / alpha;
+ dest_data[x * 4 + 1] = (((src[x] & 0x00ff00) >> 8) * 255 + alpha / 2) / alpha;
+ dest_data[x * 4 + 2] = (((src[x] & 0x0000ff) >> 0) * 255 + alpha / 2) / alpha;
+ }
+ dest_data[x * 4 + 3] = alpha;
+ }
+
+ src_data += src_stride;
+ dest_data += dest_stride;
+ }
+}
+
+static void
+convert_no_alpha (guchar *dest_data,
+ int dest_stride,
+ guchar *src_data,
+ int src_stride,
+ int src_x,
+ int src_y,
+ int width,
+ int height)
+{
+ int x, y;
+
+ src_data += src_stride * src_y + src_x * 4;
+
+ for (y = 0; y < height; y++) {
+ guint32 *src = (guint32 *) src_data;
+
+ for (x = 0; x < width; x++) {
+ dest_data[x * 3 + 0] = src[x] >> 16;
+ dest_data[x * 3 + 1] = src[x] >> 8;
+ dest_data[x * 3 + 2] = src[x];
+ }
+
+ src_data += src_stride;
+ dest_data += dest_stride;
+ }
+}
+
+/**
+ * gdk_pixbuf_get_from_surface:
+ * @surface: surface to copy from
+ * @src_x: Source X coordinate within @surface
+ * @src_y: Source Y coordinate within @surface
+ * @width: Width in pixels of region to get
+ * @height: Height in pixels of region to get
+ *
+ * Transfers image data from a #cairo_surface_t and converts it to an RGB(A)
+ * representation inside a #GdkPixbuf. This allows you to efficiently read
+ * individual pixels from cairo surfaces. For #GdkWindows, use
+ * gdk_pixbuf_get_from_window() instead.
+ *
+ * This function will create an RGB pixbuf with 8 bits per channel.
+ * The pixbuf will contain an alpha channel if the @surface contains one.
+ *
+ * Return value: (transfer full): A newly-created pixbuf with a reference
+ * count of 1, or %NULL on error
+ */
+GdkPixbuf *
+gdk_pixbuf_get_from_surface (cairo_surface_t *surface,
+ gint src_x,
+ gint src_y,
+ gint width,
+ gint height)
+{
+ cairo_content_t content;
+ GdkPixbuf *dest;
+
+ /* General sanity checks */
+ g_return_val_if_fail (surface != NULL, NULL);
+ g_return_val_if_fail (width > 0 && height > 0, NULL);
+
+ content = cairo_surface_get_content (surface) | CAIRO_CONTENT_COLOR;
+ dest = gdk_pixbuf_new (GDK_COLORSPACE_RGB,
+ !!(content & CAIRO_CONTENT_ALPHA),
+ 8,
+ width, height);
+
+ surface = gdk_cairo_surface_coerce_to_image (surface, content,
+ src_x, src_y,
+ width, height);
+ cairo_surface_flush (surface);
+ if (cairo_surface_status (surface) || dest == NULL)
+ {
+ cairo_surface_destroy (surface);
+ return NULL;
+ }
+
+ if (gdk_pixbuf_get_has_alpha (dest))
+ convert_alpha (gdk_pixbuf_get_pixels (dest),
+ gdk_pixbuf_get_rowstride (dest),
+ cairo_image_surface_get_data (surface),
+ cairo_image_surface_get_stride (surface),
+ 0, 0,
+ width, height);
+ else
+ convert_no_alpha (gdk_pixbuf_get_pixels (dest),
+ gdk_pixbuf_get_rowstride (dest),
+ cairo_image_surface_get_data (surface),
+ cairo_image_surface_get_stride (surface),
+ 0, 0,
+ width, height);
+
+ cairo_surface_destroy (surface);
+ return dest;
+}
+#endif /* !GTK_CHECK_VERSION(3,0,0) */
+#endif /* GTK_CHECK_VERSION(2,22,0) */ \ No newline at end of file
diff --git a/gtk/gui_utils.h b/gtk/gui_utils.h
index 5e24f646ae..ffe6cf4197 100644
--- a/gtk/gui_utils.h
+++ b/gtk/gui_utils.h
@@ -526,4 +526,13 @@ void ws_combo_box_set_active(GtkComboBox *combo_box, gint idx);
void
ws_combo_box_set_active_iter(GtkComboBox *combo_box, GtkTreeIter *iter);
+#if GTK_CHECK_VERSION(2,22,0)
+#if !GTK_CHECK_VERSION(3,0,0)
+GdkPixbuf *gdk_pixbuf_get_from_surface (cairo_surface_t *surface,
+ gint src_x,
+ gint src_y,
+ gint width,
+ gint height);
+#endif
+#endif
#endif /* __GUI_UTIL__H__ */
diff --git a/gtk/io_stat.c b/gtk/io_stat.c
index b325af5ac4..4813162ae2 100644
--- a/gtk/io_stat.c
+++ b/gtk/io_stat.c
@@ -175,8 +175,8 @@ typedef struct _io_stat_t {
GtkWidget *scrollbar;
guint first_frame_num[NUM_IO_ITEMS];
guint last_frame_num;
- int surface_width;
- int surface_height;
+ int pixmap_width;
+ int pixmap_height;
int pixels_per_tick;
int max_y_units;
int count_type;
@@ -854,8 +854,8 @@ io_stat_draw(io_stat_t *io)
/*
* 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_width=io->pixmap_width-io->right_x_border-io->left_x_border;
+ draw_height=io->pixmap_height-top_y_border-bottom_y_border;
/*
@@ -870,7 +870,7 @@ io_stat_draw(io_stat_t *io)
#else
cr = gdk_cairo_create (io->pixmap);
#endif
- cairo_move_to (cr, 5, io->surface_height-bottom_y_border-draw_height-label_height/2);
+ 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;
@@ -886,8 +886,8 @@ io_stat_draw(io_stat_t *io)
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_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){
@@ -906,15 +906,15 @@ io_stat_draw(io_stat_t *io)
if(io->max_y_units==LOGARITHMIC_YSCALE){
if(i==ys) {
/* position for the 0 value */
- ypos=io->surface_height-bottom_y_border;
+ 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->surface_height-bottom_y_border-draw_height;
+ 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->surface_height-bottom_y_border-(draw_height-ystart)*(i+log10((double)j))/tics-ystart);
+ 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);
@@ -922,12 +922,12 @@ io_stat_draw(io_stat_t *io)
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, ypos+0.5);
- cairo_line_to(cr, io->surface_width-io->right_x_border+1.5+xwidth,ypos+0.5);
+ 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->surface_height-bottom_y_border-(draw_height-ystart)*i/tics-ystart;
+ ypos=io->pixmap_height-bottom_y_border-(draw_height-ystart)*i/tics-ystart;
}
/* all "main" logarithmic lines are slightly longer */
xwidth=10;
@@ -936,7 +936,7 @@ io_stat_draw(io_stat_t *io)
/* first, middle and last tick are slightly longer */
xwidth=10;
}
- ypos=io->surface_height-bottom_y_border-draw_height*i/10;
+ ypos=io->pixmap_height-bottom_y_border-draw_height*i/10;
}
/* draw the tick */
#if GTK_CHECK_VERSION(2,22,0)
@@ -945,8 +945,8 @@ io_stat_draw(io_stat_t *io)
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, ypos+0.5);
- cairo_line_to(cr, io->surface_width-io->right_x_border+1.5+xwidth,ypos+0.5);
+ 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 */
@@ -976,7 +976,7 @@ io_stat_draw(io_stat_t *io)
#else
cr = gdk_cairo_create (io->pixmap);
#endif
- cairo_move_to (cr, io->surface_width-io->right_x_border+15+label_width-lwidth, ypos-label_height/2);
+ 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;
@@ -1006,8 +1006,8 @@ io_stat_draw(io_stat_t *io)
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->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_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){
@@ -1042,8 +1042,8 @@ io_stat_draw(io_stat_t *io)
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->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_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){
@@ -1054,8 +1054,8 @@ io_stat_draw(io_stat_t *io)
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 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;
}
@@ -1064,7 +1064,7 @@ io_stat_draw(io_stat_t *io)
#else
cr = gdk_cairo_create (io->pixmap);
#endif
- cairo_move_to (cr, x_pos, io->surface_height-bottom_y_border+15);
+ cairo_move_to (cr, x_pos, io->pixmap_height-bottom_y_border+15);
pango_cairo_show_layout (cr, layout);
cairo_destroy (cr);
cr = NULL;
@@ -1199,7 +1199,7 @@ io_stat_draw(io_stat_t *io)
#else
gdk_cairo_set_source_pixmap (cr, io->pixmap, 0, 0);
#endif
- cairo_rectangle (cr, 0, 0, io->surface_width, io->surface_height);
+ cairo_rectangle (cr, 0, 0, io->pixmap_width, io->pixmap_height);
cairo_fill (cr);
cairo_destroy (cr);
@@ -1333,8 +1333,8 @@ iostat_init(const char *optarg _U_, void* userdata _U_)
#endif
io->scrollbar=NULL;
io->scrollbar_adjustment=NULL;
- io->surface_width=500;
- io->surface_height=200;
+ io->pixmap_width=500;
+ io->pixmap_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;
@@ -1396,6 +1396,10 @@ draw_area_destroy_cb(GtkWidget *widget _U_, gpointer user_data)
{
io_stat_t *io = user_data;
int i;
+ 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");
+
+ g_free(surface_info);
for(i=0;i<MAX_GRAPHS;i++){
if(io->graphs[i].display){
@@ -1422,7 +1426,7 @@ pixmap_clicked_event(GtkWidget *widget _U_, GdkEventButton *event, gpointer user
guint32 draw_width, interval, last_interval;
guint frame_num;
- draw_width=io->surface_width-io->right_x_border-io->left_x_border;
+ draw_width=io->pixmap_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))) {
@@ -1463,6 +1467,9 @@ draw_area_configure_event(GtkWidget *widget, GdkEventConfigure *event _U_, gpoin
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){
@@ -1489,12 +1496,15 @@ draw_area_configure_event(GtkWidget *widget, GdkEventConfigure *event _U_, gpoin
widget_alloc.height,
-1);
#endif
- io->surface_width=widget_alloc.width;
- io->surface_height=widget_alloc.height;
+ io->pixmap_width=widget_alloc.width;
+ io->pixmap_height=widget_alloc.height;
save_bt = g_object_get_data(G_OBJECT(io->window), "save_bt");
#if GTK_CHECK_VERSION(2,22,0)
- g_object_set_data(G_OBJECT(save_bt), "surface", io->surface);
+ 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);
@@ -1560,7 +1570,7 @@ 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);
+ gtk_widget_set_size_request(io->draw_area, io->pixmap_width, io->pixmap_height);
/* signals needed to handle backing pixmap */
g_signal_connect(io->draw_area, "expose-event", G_CALLBACK(draw_area_expose_event), io);
diff --git a/gtk/pixmap_save.c b/gtk/pixmap_save.c
index 741833b3a1..3491c6beb9 100644
--- a/gtk/pixmap_save.c
+++ b/gtk/pixmap_save.c
@@ -40,7 +40,11 @@
#include "gtk/file_dlg.h"
#include "gtk/old-gtk-compat.h"
-
+#if GTK_CHECK_VERSION(2,22,0)
+#if !GTK_CHECK_VERSION(3,0,0)
+#include "gtk/gui_utils.h"
+#endif
+#endif
static GtkWidget *save_as_w;
static void
@@ -55,7 +59,7 @@ pixbuf_save_button_cb(GtkWidget *save_as_w_lcl, GdkPixbuf *pixbuf)
{
gchar *filename, *file_type;
GtkWidget *type_cm, *simple_w;
- GError *error = NULL;
+ GError *error = NULL;
gboolean ret;
filename = gtk_file_chooser_get_filename(GTK_FILE_CHOOSER(save_as_w_lcl));
@@ -95,7 +99,11 @@ pixbuf_save_button_cb(GtkWidget *save_as_w_lcl, GdkPixbuf *pixbuf)
void
pixmap_save_cb(GtkWidget *w, gpointer pixmap_ptr _U_)
{
- GdkPixmap *pixmap = g_object_get_data(G_OBJECT(w), "pixmap");
+#if GTK_CHECK_VERSION(2,22,0)
+ surface_info_t *surface_info = g_object_get_data(G_OBJECT(w), "surface-info");
+#else
+ GdkPixmap *pixmap = g_object_get_data(G_OBJECT(w), "pixmap");
+#endif
GdkPixbuf *pixbuf;
GdkPixbufFormat *pixbuf_format;
GtkWidget *main_vb, *save_as_type_hb, *type_lb, *type_cm;
@@ -106,9 +114,13 @@ pixmap_save_cb(GtkWidget *w, gpointer pixmap_ptr _U_)
guint format_index = 0;
guint default_index = 0;
+#if GTK_CHECK_VERSION(2,22,0)
+ pixbuf = gdk_pixbuf_get_from_surface (surface_info->surface,
+ 0, 0, surface_info->width, surface_info->height);
+#else
pixbuf = gdk_pixbuf_get_from_drawable(NULL, pixmap, NULL,
0, 0, 0, 0, -1, -1);
-
+#endif
if(!pixbuf) {
simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK,
"%sCould not get image from graph%s",
diff --git a/gtk/pixmap_save.h b/gtk/pixmap_save.h
index 700c088976..ec92f4f984 100644
--- a/gtk/pixmap_save.h
+++ b/gtk/pixmap_save.h
@@ -30,4 +30,9 @@
* asking for options to save the graph with (such as file type). */
void pixmap_save_cb(GtkWidget *w, gpointer pixmap_ptr);
+typedef struct _surface_info_t {
+ cairo_surface_t *surface;
+ gint width;
+ gint height;
+} surface_info_t;
#endif /* __PIXMAP_SAVE_H__ */