/pidgin/main: 53d0fee7c971: Fix whiteboard to work on both gtk2 ...

Tomasz Wasilczyk twasilczyk at pidgin.im
Wed Feb 12 14:57:08 EST 2014


Changeset: 53d0fee7c9710a985cd907fb7b968e5a7152e524
Author:	 Tomasz Wasilczyk <twasilczyk at pidgin.im>
Date:	 2014-02-12 20:57 +0100
Branch:	 default
URL: https://hg.pidgin.im/pidgin/main/rev/53d0fee7c971

Description:

Fix whiteboard to work on both gtk2 and gtk3

diffstat:

 pidgin/gtk3compat.h    |   23 +++++
 pidgin/gtkwhiteboard.c |  225 +++++++++++++++++++++---------------------------
 2 files changed, 120 insertions(+), 128 deletions(-)

diffs (truncated from 380 to 300 lines):

diff --git a/pidgin/gtk3compat.h b/pidgin/gtk3compat.h
--- a/pidgin/gtk3compat.h
+++ b/pidgin/gtk3compat.h
@@ -60,6 +60,29 @@ static inline GtkWidget * gtk_font_choos
 #define GDK_IS_QUARTZ_WINDOW(window) TRUE
 #endif
 
+static inline GdkPixbuf *
+gdk_pixbuf_get_from_surface(cairo_surface_t *surface, gint src_x, gint src_y,
+	gint width, gint height)
+{
+	GdkPixmap *pixmap;
+	GdkPixbuf *pixbuf;
+	cairo_t *cr;
+
+	pixmap = gdk_pixmap_new(NULL, width, height, 24);
+
+	cr = gdk_cairo_create(pixmap);
+	cairo_set_source_surface(cr, surface, -src_x, -src_y);
+	cairo_paint(cr);
+	cairo_destroy(cr);
+
+	pixbuf = gdk_pixbuf_get_from_drawable(NULL, pixmap,
+		gdk_drawable_get_colormap(pixmap), 0, 0, 0, 0, width, height);
+
+	g_object_unref(pixmap);
+
+	return pixbuf;
+}
+
 static inline GtkWidget *
 gtk_box_new(GtkOrientation orientation, gint spacing)
 {
diff --git a/pidgin/gtkwhiteboard.c b/pidgin/gtkwhiteboard.c
--- a/pidgin/gtkwhiteboard.c
+++ b/pidgin/gtkwhiteboard.c
@@ -30,14 +30,9 @@
 #include "gtkwhiteboard.h"
 #include "gtkutils.h"
 
-#if GTK_CHECK_VERSION(3,0,0)
-#define GdkPixType GdkPixbuf
-#else
-#define GdkPixType GdkPixmap
-#endif
 struct _PidginWhiteboardPrivate {
-	GdkPixType *pix;
-	cairo_t   *cr;
+	cairo_t *cr;
+	cairo_surface_t *surface;
 };
 
 /******************************************************************************
@@ -51,7 +46,14 @@ static gboolean whiteboard_close_cb(GtkW
 /*static void pidginwhiteboard_button_start_press(GtkButton *button, gpointer data); */
 
 static gboolean pidgin_whiteboard_configure_event(GtkWidget *widget, GdkEventConfigure *event, gpointer data);
-static gboolean pidgin_whiteboard_expose_event(GtkWidget *widget, GdkEventExpose *event, gpointer data);
+static gboolean
+pidgin_whiteboard_draw_event(GtkWidget *widget, cairo_t *cr,
+	gpointer _gtkwb);
+#if !GTK_CHECK_VERSION(3,0,0)
+static gboolean
+pidgin_whiteboard_expose_event(GtkWidget *widget, GdkEventExpose *event,
+	gpointer _gtkwb);
+#endif
 
 static gboolean pidgin_whiteboard_brush_down(GtkWidget *widget, GdkEventButton *event, gpointer data);
 static gboolean pidgin_whiteboard_brush_motion(GtkWidget *widget, GdkEventMotion *event, gpointer data);
@@ -216,11 +218,19 @@ static void pidgin_whiteboard_create(Pur
 	gtk_widget_show(drawing_area);
 
 	/* Signals used to handle backing pixmap */
+#if GTK_CHECK_VERSION(3,0,0)
+	g_signal_connect(G_OBJECT(drawing_area), "draw",
+		G_CALLBACK(pidgin_whiteboard_draw_event), gtkwb);
+
+	g_signal_connect(G_OBJECT(drawing_area), "configure-event",
+		G_CALLBACK(pidgin_whiteboard_configure_event), gtkwb);
+#else
 	g_signal_connect(G_OBJECT(drawing_area), "expose_event",
-					 G_CALLBACK(pidgin_whiteboard_expose_event), gtkwb);
+		G_CALLBACK(pidgin_whiteboard_expose_event), gtkwb);
 
 	g_signal_connect(G_OBJECT(drawing_area), "configure_event",
-					 G_CALLBACK(pidgin_whiteboard_configure_event), gtkwb);
+		G_CALLBACK(pidgin_whiteboard_configure_event), gtkwb);
+#endif
 
 	/* Event signals */
 	g_signal_connect(G_OBJECT(drawing_area), "button_press_event",
@@ -293,11 +303,13 @@ static void pidgin_whiteboard_destroy(Pu
 	/* TODO Ask if user wants to save picture before the session is closed */
 
 	/* Clear graphical memory */
-	if (gtkwb->priv->pix) {
-		cairo_t *cr = gtkwb->priv->cr;
-		if (cr)
-			cairo_destroy(cr);
-		g_object_unref(gtkwb->priv->pix);
+	if (gtkwb->priv->cr) {
+		cairo_destroy(gtkwb->priv->cr);
+		gtkwb->priv->cr = NULL;
+	}
+	if (gtkwb->priv->surface) {
+		cairo_surface_destroy(gtkwb->priv->surface);
+		gtkwb->priv->surface = NULL;
 	}
 
 	colour_dialog = g_object_get_data(G_OBJECT(gtkwb->window), "colour-dialog");
@@ -369,69 +381,54 @@ static void pidginwhiteboard_button_star
 static gboolean pidgin_whiteboard_configure_event(GtkWidget *widget, GdkEventConfigure *event, gpointer data)
 {
 	PidginWhiteboard *gtkwb = (PidginWhiteboard*)data;
-	GdkPixType *pix = gtkwb->priv->pix;
 	cairo_t *cr;
-	GdkWindow *window = gtk_widget_get_window(widget);
 	GtkAllocation allocation;
 
-	if (pix) {
-		cr = gtkwb->priv->cr;
-		if (cr)
-			cairo_destroy(cr);
-		g_object_unref(pix);
-	}
+	if (gtkwb->priv->cr)
+		cairo_destroy(gtkwb->priv->cr);
+	if (gtkwb->priv->surface)
+		cairo_surface_destroy(gtkwb->priv->surface);
 
 	gtk_widget_get_allocation(widget, &allocation);
 
-#if GTK_CHECK_VERSION(3,0,0)
-	pix = gdk_pixbuf_new(GDK_COLORSPACE_RGB,
-	                     FALSE, gdk_visual_get_depth(GDK_VISUAL(window)),
-	                     allocation.width, allocation.height);
-#else
-	pix = gdk_pixmap_new(window,
-	                     allocation.width,
-	                     allocation.height,
-	                     -1);
-#endif
-
-	gtkwb->priv->pix = pix;
-
-#if GTK_CHECK_VERSION(3,0,0)
-	cr = gdk_cairo_create(window);
-#else
-	cr = gdk_cairo_create(GDK_DRAWABLE(pix));
-#endif
-	gtkwb->priv->cr = cr;
+	gtkwb->priv->surface = cairo_image_surface_create(CAIRO_FORMAT_RGB24,
+		allocation.width, allocation.height);
+	gtkwb->priv->cr = cr = cairo_create(gtkwb->priv->surface);
 	gdk_cairo_set_source_color(cr, &gtk_widget_get_style(widget)->white);
-	cairo_rectangle(cr,
-	                0, 0,
-	                allocation.width, allocation.height);
+	cairo_rectangle(cr, 0, 0, allocation.width, allocation.height);
 	cairo_fill(cr);
 
 	return TRUE;
 }
 
-static gboolean pidgin_whiteboard_expose_event(GtkWidget *widget, GdkEventExpose *event, gpointer data)
+static gboolean
+pidgin_whiteboard_draw_event(GtkWidget *widget, cairo_t *cr,
+	gpointer _gtkwb)
 {
-	PidginWhiteboard *gtkwb = (PidginWhiteboard*)(data);
-	GdkPixType *pix = gtkwb->priv->pix;
+	PidginWhiteboard *gtkwb = _gtkwb;
+
+	cairo_set_source_surface(cr, gtkwb->priv->surface, 0, 0);
+	cairo_paint(cr);
+
+	return FALSE;
+}
+
+#if !GTK_CHECK_VERSION(3,0,0)
+static gboolean
+pidgin_whiteboard_expose_event(GtkWidget *widget, GdkEventExpose *event,
+	gpointer _gtkwb)
+{
 	cairo_t *cr;
 
-#if GTK_CHECK_VERSION(3,0,0)
-	cr = gdk_cairo_create(gtk_widget_get_window(widget));
-	gdk_cairo_set_source_pixbuf(cr, pix, 0, 0);
-#else
 	cr = gdk_cairo_create(GDK_DRAWABLE(widget->window));
-	gdk_cairo_set_source_pixmap(cr, pix, 0, 0);
-#endif
-	cairo_rectangle(cr,
-	                event->area.x, event->area.y,
-	                event->area.width, event->area.height);
-	cairo_fill(cr);
+
+	pidgin_whiteboard_draw_event(widget, cr, _gtkwb);
+
 	cairo_destroy(cr);
 
 	return FALSE;
 }
+#endif
 
 static gboolean pidgin_whiteboard_brush_down(GtkWidget *widget, GdkEventButton *event, gpointer data)
 {
@@ -450,7 +447,7 @@ static gboolean pidgin_whiteboard_brush_
 
 	BrushState = PIDGIN_BRUSH_STATE_DOWN;
 
-	if(event->button == 1 && gtkwb->priv->pix != NULL)
+	if(event->button == 1 && gtkwb->priv->cr != NULL)
 	{
 		/* Check if draw_list has contents; if so, clear it */
 		if(draw_list)
@@ -506,7 +503,7 @@ static gboolean pidgin_whiteboard_brush_
 		state = event->state;
 	}
 
-	if(state & GDK_BUTTON1_MASK && gtkwb->priv->pix != NULL)
+	if(state & GDK_BUTTON1_MASK && gtkwb->priv->cr != NULL)
 	{
 		if((BrushState != PIDGIN_BRUSH_STATE_DOWN) && (BrushState != PIDGIN_BRUSH_STATE_MOTION))
 		{
@@ -586,7 +583,7 @@ static gboolean pidgin_whiteboard_brush_
 	}
 	BrushState = PIDGIN_BRUSH_STATE_UP;
 
-	if(event->button == 1 && gtkwb->priv->pix != NULL)
+	if(event->button == 1 && gtkwb->priv->cr != NULL)
 	{
 		/* If the brush was never moved, express two sets of two deltas That's a
 		 * 'point,' but not for Yahoo!
@@ -740,17 +737,13 @@ static void pidgin_whiteboard_clear(Purp
 
 	gtk_widget_get_allocation(drawing_area, &allocation);
 
-	gdk_cairo_set_source_color(cr, &gtk_widget_get_style(drawing_area)->white);
-	cairo_rectangle(cr,
-	                0, 0,
-	                allocation.width,
-	                allocation.height);
+	gdk_cairo_set_source_color(cr,
+		&gtk_widget_get_style(drawing_area)->white);
+	cairo_rectangle(cr, 0, 0, allocation.width, allocation.height);
 	cairo_fill(cr);
 
-	gtk_widget_queue_draw_area(drawing_area,
-	                           0, 0,
-	                           allocation.width,
-	                           allocation.height);
+	gtk_widget_queue_draw_area(drawing_area, 0, 0,
+		allocation.width, allocation.height);
 }
 
 static void pidgin_whiteboard_button_clear_press(GtkWidget *widget, gpointer data)
@@ -777,68 +770,52 @@ static void pidgin_whiteboard_button_cle
 	}
 }
 
-static void pidgin_whiteboard_button_save_press(GtkWidget *widget, gpointer data)
+static void
+pidgin_whiteboard_button_save_press(GtkWidget *widget, gpointer _gtkwb)
 {
-	PidginWhiteboard *gtkwb = (PidginWhiteboard*)(data);
+	PidginWhiteboard *gtkwb = _gtkwb;
 	GdkPixbuf *pixbuf;
-
 	GtkWidget *dialog;
-
 	int result;
 
-	dialog = gtk_file_chooser_dialog_new (_("Save File"),
-										  GTK_WINDOW(gtkwb->window),
-										  GTK_FILE_CHOOSER_ACTION_SAVE,
-										  GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL,
-										  GTK_STOCK_SAVE, GTK_RESPONSE_ACCEPT,
-										  NULL);
+	dialog = gtk_file_chooser_dialog_new(_("Save File"),
+		GTK_WINDOW(gtkwb->window), GTK_FILE_CHOOSER_ACTION_SAVE,
+		GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL, GTK_STOCK_SAVE,
+		GTK_RESPONSE_ACCEPT, NULL);
 
-	/* gtk_file_chooser_set_do_overwrite_confirmation(GTK_FILE_CHOOSER(dialog), (gboolean)(TRUE)); */
+	gtk_file_chooser_set_do_overwrite_confirmation(
+		GTK_FILE_CHOOSER(dialog), TRUE);
 
-	/* if(user_edited_a_new_document) */
-	{
-	/* gtk_file_chooser_set_current_folder(GTK_FILE_CHOOSER(dialog), default_folder_for_saving); */
-		gtk_file_chooser_set_current_name(GTK_FILE_CHOOSER(dialog), "whiteboard.jpg");
-	}
-	/*
-	else
-		gtk_file_chooser_set_filename (GTK_FILE_CHOOSER (dialog), filename_for_existing_document);
-	*/
+	gtk_file_chooser_set_current_name(
+		GTK_FILE_CHOOSER(dialog), "whiteboard.png");



More information about the Commits mailing list