Refactoring patch from Ben Hutchings: move all the Gtk resize code into one
[sgt/puzzles] / gtk.c
diff --git a/gtk.c b/gtk.c
index d9b9a27..30389e9 100644 (file)
--- a/gtk.c
+++ b/gtk.c
@@ -15,6 +15,8 @@
 #include <gtk/gtk.h>
 #include <gdk/gdkkeysyms.h>
 
+#include <gdk-pixbuf/gdk-pixbuf.h>
+
 #include <gdk/gdkx.h>
 #include <X11/Xlib.h>
 #include <X11/Xutil.h>
@@ -1098,15 +1100,10 @@ static void get_size(frontend *fe, int *px, int *py)
        gdk_window_resize(GTK_WIDGET(win)->window, x, y)
 #endif
 
-static void menu_preset_event(GtkMenuItem *menuitem, gpointer data)
+static void resize_fe(frontend *fe)
 {
-    frontend *fe = (frontend *)data;
-    game_params *params =
-        (game_params *)gtk_object_get_data(GTK_OBJECT(menuitem), "user-data");
     int x, y;
 
-    midend_set_params(fe->me, params);
-    midend_new_game(fe->me);
     get_size(fe, &x, &y);
     fe->w = x;
     fe->h = y;
@@ -1118,6 +1115,17 @@ static void menu_preset_event(GtkMenuItem *menuitem, gpointer data)
     }
 }
 
+static void menu_preset_event(GtkMenuItem *menuitem, gpointer data)
+{
+    frontend *fe = (frontend *)data;
+    game_params *params =
+        (game_params *)gtk_object_get_data(GTK_OBJECT(menuitem), "user-data");
+
+    midend_set_params(fe->me, params);
+    midend_new_game(fe->me);
+    resize_fe(fe);
+}
+
 GdkAtom compound_text_atom, utf8_string_atom;
 int paste_initialised = FALSE;
 
@@ -1323,7 +1331,6 @@ static void menu_load_event(GtkMenuItem *menuitem, gpointer data)
 {
     frontend *fe = (frontend *)data;
     char *name, *err;
-    int x, y;
 
     name = file_selector(fe, "Enter name of saved game file to load", FALSE);
 
@@ -1345,16 +1352,7 @@ static void menu_load_event(GtkMenuItem *menuitem, gpointer data)
             return;
         }
 
-        get_size(fe, &x, &y);
-        fe->w = x;
-        fe->h = y;
-        gtk_drawing_area_size(GTK_DRAWING_AREA(fe->area), x, y);
-        {
-            GtkRequisition req;
-            gtk_widget_size_request(GTK_WIDGET(fe->window), &req);
-            gtk_window_resize(GTK_WINDOW(fe->window), req.width, req.height);
-        }
-
+        resize_fe(fe);
     }
 }
 
@@ -1381,21 +1379,12 @@ static void menu_config_event(GtkMenuItem *menuitem, gpointer data)
     frontend *fe = (frontend *)data;
     int which = GPOINTER_TO_INT(gtk_object_get_data(GTK_OBJECT(menuitem),
                                                    "user-data"));
-    int x, y;
 
     if (!get_config(fe, which))
        return;
 
     midend_new_game(fe->me);
-    get_size(fe, &x, &y);
-    fe->w = x;
-    fe->h = y;
-    gtk_drawing_area_size(GTK_DRAWING_AREA(fe->area), x, y);
-    {
-        GtkRequisition req;
-        gtk_widget_size_request(GTK_WIDGET(fe->window), &req);
-        gtk_window_resize(GTK_WINDOW(fe->window), req.width, req.height);
-    }
+    resize_fe(fe);
 }
 
 static void menu_about_event(GtkMenuItem *menuitem, gpointer data)
@@ -1458,8 +1447,12 @@ static frontend *new_window(char *arg, int argtype, char **error)
     frontend *fe;
     GtkBox *vbox;
     GtkWidget *menubar, *menu, *menuitem;
+    GdkPixmap *iconpm;
+    GList *iconlist;
     int x, y, n;
     char errbuf[1024];
+    extern char *const *const xpm_icons[];
+    extern const int n_xpm_icons;
 
     fe = snew(frontend);
 
@@ -1610,12 +1603,12 @@ static frontend *new_window(char *arg, int argtype, char **error)
     }
 
     add_menu_separator(GTK_CONTAINER(menu));
-    menuitem = gtk_menu_item_new_with_label("Load");
+    menuitem = gtk_menu_item_new_with_label("Load...");
     gtk_container_add(GTK_CONTAINER(menu), menuitem);
     gtk_signal_connect(GTK_OBJECT(menuitem), "activate",
                       GTK_SIGNAL_FUNC(menu_load_event), fe);
     gtk_widget_show(menuitem);
-    menuitem = gtk_menu_item_new_with_label("Save");
+    menuitem = gtk_menu_item_new_with_label("Save...");
     gtk_container_add(GTK_CONTAINER(menu), menuitem);
     gtk_signal_connect(GTK_OBJECT(menuitem), "activate",
                       GTK_SIGNAL_FUNC(menu_save_event), fe);
@@ -1745,6 +1738,21 @@ static frontend *new_window(char *arg, int argtype, char **error)
                           GDK_BUTTON_RELEASE_MASK |
                          GDK_BUTTON_MOTION_MASK);
 
+    if (n_xpm_icons) {
+       gtk_widget_realize(fe->window);
+       iconpm = gdk_pixmap_create_from_xpm_d(fe->window->window, NULL,
+                                             NULL, (gchar **)xpm_icons[0]);
+       gdk_window_set_icon(fe->window->window, NULL, iconpm, NULL);
+       iconlist = NULL;
+       for (n = 0; n < n_xpm_icons; n++) {
+           iconlist =
+               g_list_append(iconlist,
+                             gdk_pixbuf_new_from_xpm_data((const gchar **)
+                                                          xpm_icons[n]));
+       }
+       gdk_window_set_icon_list(fe->window->window, iconlist);
+    }
+
     gtk_widget_show(fe->area);
     gtk_widget_show(fe->window);
 
@@ -1783,7 +1791,7 @@ int main(int argc, char **argv)
     float redo_proportion = 0.0F;
     char *arg = NULL;
     int argtype = ARG_EITHER;
-    int output_window_id = FALSE;
+    char *screenshot_file = NULL;
     int doing_opts = TRUE;
     int ac = argc;
     char **av = argv;
@@ -1881,15 +1889,22 @@ int main(int argc, char **argv)
                        pname);
                return 1;
            }
-       } else if (doing_opts && !strcmp(p, "--windowid")) {
+       } else if (doing_opts && !strcmp(p, "--screenshot")) {
            /*
             * Another internal option for the icon building
-            * script. This causes the window ID of the central
+            * script. This causes a screenshot of the central
             * drawing area (i.e. not including the menu bar or
-            * status bar) to be printed on standard output once
-            * the window has been drawn.
+            * status bar) to be saved to a PNG file once the
+            * window has been drawn, and then the application
+            * quits immediately.
             */
-           output_window_id = TRUE;
+           if (--ac > 0) {
+               screenshot_file = *++av;
+           } else {
+               fprintf(stderr, "%s: no argument supplied to '--screenshot'\n",
+                       pname);
+               return 1;
+           }
        } else if (doing_opts && (!strcmp(p, "--with-solutions") ||
                                  !strcmp(p, "--with-solution") ||
                                  !strcmp(p, "--with-solns") ||
@@ -1926,6 +1941,11 @@ int main(int argc, char **argv)
        }
     }
 
+    if (*errbuf) {
+       fputs(errbuf, stderr);
+       return 1;
+    }
+
     /*
      * Special standalone mode for generating puzzle IDs on the
      * command line. Useful for generating puzzles to be printed
@@ -1953,11 +1973,6 @@ int main(int argc, char **argv)
        char *id;
        document *doc = NULL;
 
-       if (*errbuf) {
-           fputs(errbuf, stderr);
-           return 1;
-       }
-
        n = ngenerate;
 
        me = midend_new(NULL, &thegame, NULL, NULL);
@@ -2050,7 +2065,7 @@ int main(int argc, char **argv)
            return 1;
        }
 
-       if (output_window_id) {
+       if (screenshot_file) {
            /*
             * Some puzzles will not redraw their entire area if
             * given a partially completed animation, which means
@@ -2067,10 +2082,17 @@ int main(int argc, char **argv)
            midend_freeze_timer(fe->me, redo_proportion);
        }
 
-       if (output_window_id) {
+       if (screenshot_file) {
+           GdkPixbuf *pb;
+            GError *gerror = NULL;
+
            midend_redraw(fe->me);
-           printf("%p\n", (void *)GDK_WINDOW_XWINDOW(fe->area->window));
-           fflush(stdout);
+
+           pb = gdk_pixbuf_get_from_drawable(NULL, fe->pixmap,
+                                             NULL, 0, 0, 0, 0, -1, -1);
+           gdk_pixbuf_save(pb, screenshot_file, "png", &gerror, NULL);
+
+           exit(0);
        }
 
        gtk_main();