GTK 3 prep: make the server-side backing pixmap optional.

When GDK_DISABLE_DEPRECATED is defined, we now don't have fe->pixmap;
instead we just maintain our client-side window contents in fe->image,
and draw from there directly to the window in the expose handler.
This commit is contained in:
Simon Tatham
2015-10-03 12:28:02 +01:00
parent 07906104a2
commit fd7882fb45

80
gtk.c
View File

@ -39,6 +39,9 @@
#endif #endif
#if GTK_CHECK_VERSION(2,8,0) #if GTK_CHECK_VERSION(2,8,0)
# define USE_CAIRO # define USE_CAIRO
# if defined(GDK_DISABLE_DEPRECATED)
# define USE_CAIRO_WITHOUT_PIXMAP
# endif
#endif #endif
/* #undef USE_CAIRO */ /* #undef USE_CAIRO */
@ -126,7 +129,9 @@ struct frontend {
const float *colours; const float *colours;
cairo_t *cr; cairo_t *cr;
cairo_surface_t *image; cairo_surface_t *image;
#ifndef USE_CAIRO_WITHOUT_PIXMAP
GdkPixmap *pixmap; GdkPixmap *pixmap;
#endif
GdkColor background; /* for painting outside puzzle area */ GdkColor background; /* for painting outside puzzle area */
#else #else
GdkPixmap *pixmap; GdkPixmap *pixmap;
@ -212,20 +217,22 @@ static void setup_drawing(frontend *fe)
static void teardown_drawing(frontend *fe) static void teardown_drawing(frontend *fe)
{ {
cairo_t *cr;
cairo_destroy(fe->cr); cairo_destroy(fe->cr);
fe->cr = NULL; fe->cr = NULL;
cr = gdk_cairo_create(fe->pixmap); #ifndef USE_CAIRO_WITHOUT_PIXMAP
cairo_set_source_surface(cr, fe->image, 0, 0); {
cairo_rectangle(cr, cairo_t *cr = gdk_cairo_create(fe->pixmap);
fe->bbox_l - 1, cairo_set_source_surface(cr, fe->image, 0, 0);
fe->bbox_u - 1, cairo_rectangle(cr,
fe->bbox_r - fe->bbox_l + 2, fe->bbox_l - 1,
fe->bbox_d - fe->bbox_u + 2); fe->bbox_u - 1,
cairo_fill(cr); fe->bbox_r - fe->bbox_l + 2,
cairo_destroy(cr); fe->bbox_d - fe->bbox_u + 2);
cairo_fill(cr);
cairo_destroy(cr);
}
#endif
} }
static void snaffle_colours(frontend *fe) static void snaffle_colours(frontend *fe)
@ -382,28 +389,28 @@ static void clear_backing_store(frontend *fe)
fe->image = NULL; fe->image = NULL;
} }
static void wipe_and_destroy_cairo(frontend *fe, cairo_t *cr)
{
cairo_set_source_rgb(cr, fe->colours[0], fe->colours[1], fe->colours[2]);
cairo_paint(cr);
cairo_destroy(cr);
}
static void setup_backing_store(frontend *fe) static void setup_backing_store(frontend *fe)
{ {
cairo_t *cr; #ifndef USE_CAIRO_WITHOUT_PIXMAP
int i;
fe->pixmap = gdk_pixmap_new(gtk_widget_get_window(fe->area), fe->pixmap = gdk_pixmap_new(gtk_widget_get_window(fe->area),
fe->pw, fe->ph, -1); fe->pw, fe->ph, -1);
#endif
fe->image = cairo_image_surface_create(CAIRO_FORMAT_RGB24, fe->image = cairo_image_surface_create(CAIRO_FORMAT_RGB24,
fe->pw, fe->ph); fe->pw, fe->ph);
for (i = 0; i < 3; i++) { wipe_and_destroy_cairo(fe, cairo_create(fe->image));
switch (i) { #ifndef USE_CAIRO_WITHOUT_PIXMAP
case 0: cr = cairo_create(fe->image); break; wipe_and_destroy_cairo(fe, gdk_cairo_create(fe->pixmap));
case 1: cr = gdk_cairo_create(fe->pixmap); break; #endif
case 2: cr = gdk_cairo_create(gtk_widget_get_window(fe->area)); wipe_and_destroy_cairo(fe, gdk_cairo_create
break; (gtk_widget_get_window(fe->area)));
}
cairo_set_source_rgb(cr,
fe->colours[0], fe->colours[1], fe->colours[2]);
cairo_paint(cr);
cairo_destroy(cr);
}
} }
static int backing_store_ok(frontend *fe) static int backing_store_ok(frontend *fe)
@ -414,7 +421,9 @@ static int backing_store_ok(frontend *fe)
static void teardown_backing_store(frontend *fe) static void teardown_backing_store(frontend *fe)
{ {
cairo_surface_destroy(fe->image); cairo_surface_destroy(fe->image);
#ifndef USE_CAIRO_WITHOUT_PIXMAP
gdk_pixmap_unref(fe->pixmap); gdk_pixmap_unref(fe->pixmap);
#endif
fe->image = NULL; fe->image = NULL;
} }
@ -668,6 +677,7 @@ static void teardown_backing_store(frontend *fe)
#endif #endif
#ifndef USE_CAIRO_WITHOUT_PIXMAP
static void repaint_rectangle(frontend *fe, GtkWidget *widget, static void repaint_rectangle(frontend *fe, GtkWidget *widget,
int x, int y, int w, int h) int x, int y, int w, int h)
{ {
@ -703,6 +713,7 @@ static void repaint_rectangle(frontend *fe, GtkWidget *widget,
x - fe->ox, y - fe->oy, x, y, w, h); x - fe->ox, y - fe->oy, x, y, w, h);
gdk_gc_unref(gc); gdk_gc_unref(gc);
} }
#endif
/* ---------------------------------------------------------------------- /* ----------------------------------------------------------------------
* Pango font functions. * Pango font functions.
@ -983,11 +994,19 @@ void gtk_end_draw(void *handle)
teardown_drawing(fe); teardown_drawing(fe);
if (fe->bbox_l < fe->bbox_r && fe->bbox_u < fe->bbox_d) { if (fe->bbox_l < fe->bbox_r && fe->bbox_u < fe->bbox_d) {
#ifdef USE_CAIRO_WITHOUT_PIXMAP
gtk_widget_queue_draw_area(fe->area,
fe->bbox_l - 1 + fe->ox,
fe->bbox_u - 1 + fe->oy,
fe->bbox_r - fe->bbox_l + 2,
fe->bbox_d - fe->bbox_u + 2);
#else
repaint_rectangle(fe, fe->area, repaint_rectangle(fe, fe->area,
fe->bbox_l - 1 + fe->ox, fe->bbox_l - 1 + fe->ox,
fe->bbox_u - 1 + fe->oy, fe->bbox_u - 1 + fe->oy,
fe->bbox_r - fe->bbox_l + 2, fe->bbox_r - fe->bbox_l + 2,
fe->bbox_d - fe->bbox_u + 2); fe->bbox_d - fe->bbox_u + 2);
#endif
} }
} }
@ -1185,9 +1204,18 @@ static gint expose_area(GtkWidget *widget, GdkEventExpose *event,
frontend *fe = (frontend *)data; frontend *fe = (frontend *)data;
if (backing_store_ok(fe)) { if (backing_store_ok(fe)) {
#ifdef USE_CAIRO_WITHOUT_PIXMAP
cairo_t *cr = gdk_cairo_create(gtk_widget_get_window(widget));
cairo_set_source_surface(cr, fe->image, fe->ox, fe->oy);
cairo_rectangle(cr, event->area.x, event->area.y,
event->area.width, event->area.height);
cairo_fill(cr);
cairo_destroy(cr);
#else
repaint_rectangle(fe, widget, repaint_rectangle(fe, widget,
event->area.x, event->area.y, event->area.x, event->area.y,
event->area.width, event->area.height); event->area.width, event->area.height);
#endif
} }
return TRUE; return TRUE;
} }