Make --screenshot work even in (Cairo) GTK2 builds.

I had occasion recently to want to take a puzzle screenshot on a
machine that didn't have the GTK3 libraries installed, but is advanced
enough to build the GTK2+Cairo version of the puzzles. That _ought_ to
be good enough to take screenshots using bare Cairo without GTK; I
think the only reason why I didn't bother to support it before is
because on GTK2, frontend_default_colours() queries the widget style
to choose a shade of grey. But we have a fixed fallback shade of grey
to use on GTK3, so it's easy to just use that same fallback in
headless GTK2.
This commit is contained in:
Simon Tatham
2019-11-13 19:23:07 +00:00
parent 26a40781e6
commit 1c0c49dd5c

53
gtk.c
View File

@ -247,15 +247,19 @@ void get_random_seed(void **randseed, int *randseedsize)
void frontend_default_colour(frontend *fe, float *output) void frontend_default_colour(frontend *fe, float *output)
{ {
#if !GTK_CHECK_VERSION(3,0,0) #if !GTK_CHECK_VERSION(3,0,0)
/* if (!fe->headless) {
* Use the widget style's default background colour as the /*
* background for the puzzle drawing area. * If we have a widget and it has a style that specifies a
*/ * default background colour, use that as the background for
GdkColor col = gtk_widget_get_style(fe->window)->bg[GTK_STATE_NORMAL]; * the puzzle drawing area.
output[0] = col.red / 65535.0; */
output[1] = col.green / 65535.0; GdkColor col = gtk_widget_get_style(fe->window)->bg[GTK_STATE_NORMAL];
output[2] = col.blue / 65535.0; output[0] = col.red / 65535.0;
#else output[1] = col.green / 65535.0;
output[2] = col.blue / 65535.0;
}
#endif
/* /*
* GTK 3 has decided that there's no such thing as a 'default * GTK 3 has decided that there's no such thing as a 'default
* background colour' any more, because widget styles might set * background colour' any more, because widget styles might set
@ -263,9 +267,11 @@ void frontend_default_colour(frontend *fe, float *output)
* image. We don't want to get into overlaying our entire puzzle * image. We don't want to get into overlaying our entire puzzle
* on an arbitrary background image, so we'll just make up a * on an arbitrary background image, so we'll just make up a
* reasonable shade of grey. * reasonable shade of grey.
*
* This is also what we do on GTK 2 in headless mode, where we
* don't have a widget style to query.
*/ */
output[0] = output[1] = output[2] = 0.9F; output[0] = output[1] = output[2] = 0.9F;
#endif
} }
void gtk_status_bar(void *handle, const char *text) void gtk_status_bar(void *handle, const char *text)
@ -512,23 +518,24 @@ static void wipe_and_maybe_destroy_cairo(frontend *fe, cairo_t *cr,
static void setup_backing_store(frontend *fe) static void setup_backing_store(frontend *fe)
{ {
#ifndef USE_CAIRO_WITHOUT_PIXMAP #ifndef USE_CAIRO_WITHOUT_PIXMAP
if (fe->headless) { if (!fe->headless) {
fprintf(stderr, "headless mode does not work with GDK pixmaps\n"); fe->pixmap = gdk_pixmap_new(gtk_widget_get_window(fe->area),
exit(1); fe->pw, fe->ph, -1);
} else {
fe->pixmap = NULL;
} }
fe->pixmap = gdk_pixmap_new(gtk_widget_get_window(fe->area),
fe->pw, fe->ph, -1);
#endif #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);
wipe_and_maybe_destroy_cairo(fe, cairo_create(fe->image), true); wipe_and_maybe_destroy_cairo(fe, cairo_create(fe->image), true);
#ifndef USE_CAIRO_WITHOUT_PIXMAP #ifndef USE_CAIRO_WITHOUT_PIXMAP
wipe_and_maybe_destroy_cairo(fe, gdk_cairo_create(fe->pixmap), true); if (!fe->headless)
wipe_and_maybe_destroy_cairo(fe, gdk_cairo_create(fe->pixmap), true);
#endif #endif
#if GTK_CHECK_VERSION(3,22,0)
if (!fe->headless) { if (!fe->headless) {
#if GTK_CHECK_VERSION(3,22,0)
GdkWindow *gdkwin; GdkWindow *gdkwin;
cairo_region_t *region; cairo_region_t *region;
GdkDrawingContext *drawctx; GdkDrawingContext *drawctx;
@ -541,11 +548,11 @@ static void setup_backing_store(frontend *fe)
wipe_and_maybe_destroy_cairo(fe, cr, false); wipe_and_maybe_destroy_cairo(fe, cr, false);
gdk_window_end_draw_frame(gdkwin, drawctx); gdk_window_end_draw_frame(gdkwin, drawctx);
cairo_region_destroy(region); cairo_region_destroy(region);
}
#else #else
wipe_and_maybe_destroy_cairo( wipe_and_maybe_destroy_cairo(
fe, gdk_cairo_create(gtk_widget_get_window(fe->area)), true); fe, gdk_cairo_create(gtk_widget_get_window(fe->area)), true);
#endif #endif
}
} }
static bool backing_store_ok(frontend *fe) static bool backing_store_ok(frontend *fe)
@ -2501,9 +2508,9 @@ static frontend *new_window(
fe = snew(frontend); fe = snew(frontend);
memset(fe, 0, sizeof(frontend)); memset(fe, 0, sizeof(frontend));
#if !GTK_CHECK_VERSION(3,0,0) #ifndef USE_CAIRO
if (headless) { if (headless) {
fprintf(stderr, "headless mode not supported below GTK 3\n"); fprintf(stderr, "headless mode not supported for non-Cairo drawing\n");
exit(1); exit(1);
} }
#else #else