Add pointless initialisations to placate a gcc warning.
[sgt/puzzles] / gtk.c
diff --git a/gtk.c b/gtk.c
index 0b3355e..c156651 100644 (file)
--- a/gtk.c
+++ b/gtk.c
@@ -40,6 +40,8 @@
 # define USE_CAIRO
 #endif
 
+/* #undef USE_CAIRO */
+/* #define NO_THICK_LINE */
 #ifdef DEBUGGING
 static FILE *debug_fp = NULL;
 
@@ -123,11 +125,13 @@ struct frontend {
     cairo_t *cr;
     cairo_surface_t *image;
     GdkPixmap *pixmap;
+    GdkColor background;              /* for painting outside puzzle area */
 #else
     GdkPixmap *pixmap;
     GdkGC *gc;
     GdkColor *colours;
     GdkColormap *colmap;
+    int backgroundindex;              /* which of colours[] is background */
 #endif
     int ncolours;
     int bbox_l, bbox_r, bbox_u, bbox_d;
@@ -236,18 +240,18 @@ static void set_colour(frontend *fe, int colour)
 static void set_window_background(frontend *fe, int colour)
 {
     GdkColormap *colmap;
-    GdkColor backg;
 
     colmap = gdk_colormap_get_system();
-    backg.red = fe->colours[3*colour + 0] * 65535;
-    backg.green = fe->colours[3*colour + 1] * 65535;
-    backg.blue = fe->colours[3*colour + 2] * 65535;
-    if (!gdk_colormap_alloc_color(colmap, &backg, FALSE, FALSE)) {
+    fe->background.red = fe->colours[3*colour + 0] * 65535;
+    fe->background.green = fe->colours[3*colour + 1] * 65535;
+    fe->background.blue = fe->colours[3*colour + 2] * 65535;
+    if (!gdk_colormap_alloc_color(colmap, &fe->background, FALSE, FALSE)) {
        g_error("couldn't allocate background (#%02x%02x%02x)\n",
-               backg.red >> 8, backg.green >> 8, backg.blue >> 8);
+               fe->background.red >> 8, fe->background.green >> 8,
+               fe->background.blue >> 8);
     }
-    gdk_window_set_background(fe->area->window, &backg);
-    gdk_window_set_background(fe->window->window, &backg);
+    gdk_window_set_background(fe->area->window, &fe->background);
+    gdk_window_set_background(fe->window->window, &fe->background);
 }
 
 static PangoLayout *make_pango_layout(frontend *fe)
@@ -297,6 +301,18 @@ static void do_draw_line(frontend *fe, int x1, int y1, int x2, int y2)
     cairo_stroke(fe->cr);
 }
 
+static void do_draw_thick_line(frontend *fe, float thickness,
+                              float x1, float y1, float x2, float y2)
+{
+    cairo_save(fe->cr);
+    cairo_set_line_width(fe->cr, thickness);
+    cairo_new_path(fe->cr);
+    cairo_move_to(fe->cr, x1, y1);
+    cairo_line_to(fe->cr, x2, y2);
+    cairo_stroke(fe->cr);
+    cairo_restore(fe->cr);
+}
+
 static void do_draw_poly(frontend *fe, int *coords, int npoints,
                         int fillcolour, int outlinecolour)
 {
@@ -394,15 +410,6 @@ static void teardown_backing_store(frontend *fe)
     fe->image = NULL;
 }
 
-static void repaint_rectangle(frontend *fe, GtkWidget *widget,
-                             int x, int y, int w, int h)
-{
-    gdk_draw_pixmap(widget->window,
-                   widget->style->fg_gc[GTK_WIDGET_STATE(fe->area)],
-                   fe->pixmap,
-                   x - fe->ox, y - fe->oy, x, y, w, h);
-}
-
 #endif
 
 /* ----------------------------------------------------------------------
@@ -452,6 +459,7 @@ static void snaffle_colours(frontend *fe)
 
 static void set_window_background(frontend *fe, int colour)
 {
+    fe->backgroundindex = colour;
     gdk_window_set_background(fe->area->window, &fe->colours[colour]);
     gdk_window_set_background(fe->window->window, &fe->colours[colour]);
 }
@@ -518,6 +526,25 @@ static void do_draw_line(frontend *fe, int x1, int y1, int x2, int y2)
     gdk_draw_line(fe->pixmap, fe->gc, x1, y1, x2, y2);
 }
 
+static void do_draw_thick_line(frontend *fe, float thickness,
+                              float x1, float y1, float x2, float y2)
+{
+    GdkGCValues save;
+
+    gdk_gc_get_values(fe->gc, &save);
+    gdk_gc_set_line_attributes(fe->gc,
+                              thickness,
+                              GDK_LINE_SOLID,
+                              GDK_CAP_BUTT,
+                              GDK_JOIN_BEVEL);
+    gdk_draw_line(fe->pixmap, fe->gc, x1, y1, x2, y2);
+    gdk_gc_set_line_attributes(fe->gc,
+                              save.line_width,
+                              save.line_style,
+                              save.cap_style,
+                              save.join_style);
+}
+
 static void do_draw_poly(frontend *fe, int *coords, int npoints,
                         int fillcolour, int outlinecolour)
 {
@@ -631,17 +658,44 @@ static void teardown_backing_store(frontend *fe)
     fe->pixmap = NULL;
 }
 
+#endif
+
 static void repaint_rectangle(frontend *fe, GtkWidget *widget,
                              int x, int y, int w, int h)
 {
-    gdk_draw_pixmap(widget->window,
-                   widget->style->fg_gc[GTK_WIDGET_STATE(fe->area)],
-                   fe->pixmap,
+    GdkGC *gc = gdk_gc_new(widget->window);
+#ifdef USE_CAIRO
+    gdk_gc_set_foreground(gc, &fe->background);
+#else
+    gdk_gc_set_foreground(gc, &fe->colours[fe->backgroundindex]);
+#endif
+    if (x < fe->ox) {
+       gdk_draw_rectangle(widget->window, gc,
+                          TRUE, x, y, fe->ox - x, h);
+       w -= (fe->ox - x);
+       x = fe->ox;
+    }
+    if (y < fe->oy) {
+       gdk_draw_rectangle(widget->window, gc,
+                          TRUE, x, y, w, fe->oy - y);
+       h -= (fe->oy - y);
+       y = fe->oy;
+    }
+    if (w > fe->pw) {
+       gdk_draw_rectangle(widget->window, gc,
+                          TRUE, x + fe->pw, y, w - fe->pw, h);
+       w = fe->pw;
+    }
+    if (h > fe->ph) {
+       gdk_draw_rectangle(widget->window, gc,
+                          TRUE, x, y + fe->ph, w, h - fe->ph);
+       h = fe->ph;
+    }
+    gdk_draw_pixmap(widget->window, gc, fe->pixmap,
                    x - fe->ox, y - fe->oy, x, y, w, h);
+    gdk_gc_unref(gc);
 }
 
-#endif
-
 /* ----------------------------------------------------------------------
  * Pango font functions.
  */
@@ -850,6 +904,14 @@ void gtk_draw_line(void *handle, int x1, int y1, int x2, int y2, int colour)
     do_draw_line(fe, x1, y1, x2, y2);
 }
 
+void gtk_draw_thick_line(void *handle, float thickness,
+                        float x1, float y1, float x2, float y2, int colour)
+{
+    frontend *fe = (frontend *)handle;
+    set_colour(fe, colour);
+    do_draw_thick_line(fe, thickness, x1, y1, x2, y2);
+}
+
 void gtk_draw_poly(void *handle, int *coords, int npoints,
                   int fillcolour, int outlinecolour)
 {
@@ -955,6 +1017,11 @@ const struct drawing_api gtk_drawing = {
 #else
     NULL,
 #endif
+#ifdef NO_THICK_LINE
+    NULL,
+#else
+    gtk_draw_thick_line,
+#endif
 };
 
 static void destroy(GtkWidget *widget, gpointer data)
@@ -2631,13 +2698,23 @@ int main(int argc, char **argv)
                char *realname = snewn(40 + strlen(savefile) +
                                       strlen(savesuffix), char);
                sprintf(realname, "%s%d%s", savefile, i, savesuffix);
+
+                if (soln) {
+                    char *err = midend_solve(me);
+                    if (err) {
+                        fprintf(stderr, "%s: unable to show solution: %s\n",
+                                realname, err);
+                        return 1;
+                    }
+                }
+
                ctx.fp = fopen(realname, "w");
                if (!ctx.fp) {
                    fprintf(stderr, "%s: open: %s\n", realname,
                            strerror(errno));
                    return 1;
                }
-               sfree(realname);
+                ctx.error = 0;
                midend_serialise(me, savefile_write, &ctx);
                if (ctx.error) {
                    fprintf(stderr, "%s: write: %s\n", realname,
@@ -2649,6 +2726,7 @@ int main(int argc, char **argv)
                            strerror(errno));
                    return 1;
                }
+               sfree(realname);
            }
            if (!doc && !savefile) {
                id = midend_get_game_id(me);