shithub: puzzles

Download patch

ref: 1c0c49dd5cd8df6ae87f7be5371be84589fa2662
parent: 26a40781e6a3d64a32f8f98529b62917dd32d389
author: Simon Tatham <anakin@pobox.com>
date: Wed Nov 13 14:23:07 EST 2019

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.

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