gimp r25026 - in branches/weskaggs: . app app/actions app/core app/display app/gegl app/gui app/pdb app/tools app/widgets cursors cursors/xbm devel-docs docs libgimpwidgets plug-ins/common plug-ins/jpeg plug-ins/print plug-ins/pygimp plug-ins/script-fu plug-ins/script-fu/scripts po po-libgimp po-plug-ins po-python po-script-fu po-tips tools/pdbgen tools/pdbgen/pdb



Author: weskaggs
Date: Tue Mar  4 03:15:17 2008
New Revision: 25026
URL: http://svn.gnome.org/viewvc/gimp?rev=25026&view=rev

Log:
Bill Skaggs  <weskaggs primate ucdavis edu>

	Merge 24892:25025 from trunk.


Added:
   branches/weskaggs/app/version.c
      - copied unchanged from r25025, /trunk/app/version.c
   branches/weskaggs/app/version.h
      - copied unchanged from r25025, /trunk/app/version.h
   branches/weskaggs/cursors/tool-polygon-select.png
      - copied unchanged from r25025, /trunk/cursors/tool-polygon-select.png
   branches/weskaggs/cursors/xbm/tool-polygon-select-mask.xbm
      - copied unchanged from r25025, /trunk/cursors/xbm/tool-polygon-select-mask.xbm
   branches/weskaggs/cursors/xbm/tool-polygon-select.xbm
      - copied unchanged from r25025, /trunk/cursors/xbm/tool-polygon-select.xbm
   branches/weskaggs/plug-ins/print/print-utils.c
      - copied unchanged from r25025, /trunk/plug-ins/print/print-utils.c
   branches/weskaggs/plug-ins/print/print-utils.h
      - copied unchanged from r25025, /trunk/plug-ins/print/print-utils.h
Modified:
   branches/weskaggs/ChangeLog
   branches/weskaggs/INSTALL
   branches/weskaggs/NEWS
   branches/weskaggs/app/Makefile.am
   branches/weskaggs/app/actions/edit-actions.c
   branches/weskaggs/app/actions/plug-in-actions.c
   branches/weskaggs/app/app.c
   branches/weskaggs/app/batch.c
   branches/weskaggs/app/core/gimp.c
   branches/weskaggs/app/core/gimpcurve.c
   branches/weskaggs/app/core/gimpcurve.h
   branches/weskaggs/app/core/gimpdrawable-curves.c
   branches/weskaggs/app/core/gimpdrawable-transform.c
   branches/weskaggs/app/display/gimpdisplayshell-callbacks.c
   branches/weskaggs/app/display/gimpdisplayshell-coords.c
   branches/weskaggs/app/display/gimpdisplayshell-draw.c
   branches/weskaggs/app/display/gimpdisplayshell-transform.c
   branches/weskaggs/app/display/gimpdisplayshell-transform.h
   branches/weskaggs/app/gegl/gimpcurvesconfig.c
   branches/weskaggs/app/gui/gui-vtable.c
   branches/weskaggs/app/gui/gui.c
   branches/weskaggs/app/gui/ige-mac-menu.c
   branches/weskaggs/app/gui/ige-mac-menu.h
   branches/weskaggs/app/main.c
   branches/weskaggs/app/pdb/brushes_cmds.c
   branches/weskaggs/app/pdb/context_cmds.c
   branches/weskaggs/app/pdb/display_cmds.c
   branches/weskaggs/app/pdb/fonts_cmds.c
   branches/weskaggs/app/pdb/gradients_cmds.c
   branches/weskaggs/app/pdb/palettes_cmds.c
   branches/weskaggs/app/pdb/patterns_cmds.c
   branches/weskaggs/app/tools/gimpcurvestool.c
   branches/weskaggs/app/tools/gimpdrawtool.c
   branches/weskaggs/app/tools/gimpdrawtool.h
   branches/weskaggs/app/tools/gimpforegroundselecttool.c
   branches/weskaggs/app/tools/gimpfreeselecttool.c
   branches/weskaggs/app/tools/gimpgegltool.c
   branches/weskaggs/app/tools/gimpgegltool.h
   branches/weskaggs/app/tools/gimpimagemaptool.c
   branches/weskaggs/app/tools/gimpiscissorstool.c
   branches/weskaggs/app/tools/gimppolygonselecttool.c
   branches/weskaggs/app/tools/gimprectangletool.c
   branches/weskaggs/app/tools/gimptransformtool.c
   branches/weskaggs/app/tools/gimpvectortool.c
   branches/weskaggs/app/widgets/gimpcontainerpopup.c
   branches/weskaggs/app/widgets/gimpcursor.c
   branches/weskaggs/app/widgets/gimpcurveview.c
   branches/weskaggs/app/widgets/gimppaletteview.c
   branches/weskaggs/app/widgets/widgets-enums.h
   branches/weskaggs/configure.in
   branches/weskaggs/cursors/Makefile.am
   branches/weskaggs/cursors/gimp-tool-cursors.xcf
   branches/weskaggs/devel-docs/ChangeLog
   branches/weskaggs/devel-docs/parasites.txt
   branches/weskaggs/docs/gimp.1.in
   branches/weskaggs/libgimpwidgets/gimpchainbutton.c
   branches/weskaggs/libgimpwidgets/gimpcolorhexentry.c
   branches/weskaggs/libgimpwidgets/gimpnumberpairentry.c
   branches/weskaggs/plug-ins/common/struc.c
   branches/weskaggs/plug-ins/common/tileit.c
   branches/weskaggs/plug-ins/common/wind.c
   branches/weskaggs/plug-ins/jpeg/jpeg-exif.c
   branches/weskaggs/plug-ins/print/Makefile.am
   branches/weskaggs/plug-ins/print/print-draw-page.c
   branches/weskaggs/plug-ins/print/print-draw-page.h
   branches/weskaggs/plug-ins/print/print-page-layout.c
   branches/weskaggs/plug-ins/print/print-page-layout.h
   branches/weskaggs/plug-ins/print/print-page-setup.c
   branches/weskaggs/plug-ins/print/print-page-setup.h
   branches/weskaggs/plug-ins/print/print-preview.c
   branches/weskaggs/plug-ins/print/print-preview.h
   branches/weskaggs/plug-ins/print/print-settings.c
   branches/weskaggs/plug-ins/print/print-settings.h
   branches/weskaggs/plug-ins/print/print.c
   branches/weskaggs/plug-ins/print/print.h
   branches/weskaggs/plug-ins/pygimp/gimpmodule.c
   branches/weskaggs/plug-ins/script-fu/script-fu-console.c
   branches/weskaggs/plug-ins/script-fu/scripts/frosty-logo.scm
   branches/weskaggs/plug-ins/script-fu/scripts/glossy.scm
   branches/weskaggs/po-libgimp/ChangeLog
   branches/weskaggs/po-libgimp/it.po
   branches/weskaggs/po-libgimp/nb.po
   branches/weskaggs/po-libgimp/nl.po
   branches/weskaggs/po-libgimp/oc.po
   branches/weskaggs/po-libgimp/ru.po
   branches/weskaggs/po-plug-ins/ChangeLog
   branches/weskaggs/po-plug-ins/fi.po
   branches/weskaggs/po-plug-ins/hu.po
   branches/weskaggs/po-plug-ins/nb.po
   branches/weskaggs/po-plug-ins/oc.po
   branches/weskaggs/po-plug-ins/ru.po
   branches/weskaggs/po-python/ChangeLog
   branches/weskaggs/po-python/it.po
   branches/weskaggs/po-python/nb.po
   branches/weskaggs/po-python/nl.po
   branches/weskaggs/po-python/oc.po
   branches/weskaggs/po-python/ru.po
   branches/weskaggs/po-script-fu/ChangeLog
   branches/weskaggs/po-script-fu/it.po
   branches/weskaggs/po-script-fu/nb.po
   branches/weskaggs/po-script-fu/oc.po
   branches/weskaggs/po-script-fu/ru.po
   branches/weskaggs/po-tips/ChangeLog
   branches/weskaggs/po-tips/nl.po
   branches/weskaggs/po-tips/oc.po
   branches/weskaggs/po-tips/ru.po
   branches/weskaggs/po/ChangeLog
   branches/weskaggs/po/POTFILES.in
   branches/weskaggs/po/bg.po
   branches/weskaggs/po/fi.po
   branches/weskaggs/po/nb.po
   branches/weskaggs/po/nl.po
   branches/weskaggs/po/oc.po
   branches/weskaggs/po/ru.po
   branches/weskaggs/po/sr.po
   branches/weskaggs/po/sr Latn po
   branches/weskaggs/tools/pdbgen/app.pl
   branches/weskaggs/tools/pdbgen/pdb/display.pdb

Modified: branches/weskaggs/INSTALL
==============================================================================
--- branches/weskaggs/INSTALL	(original)
+++ branches/weskaggs/INSTALL	Tue Mar  4 03:15:17 2008
@@ -28,8 +28,9 @@
   1. You need to have installed a recent version of pkg-config available
      from http://www.freedesktop.org/software/pkgconfig/.  
 
-  2. You need to have installed GEGL trunk. To check out GEGL trunk:
-     svn co http://svn.gnome.org/svn/gegl/trunk gegl-trunk
+  2. You need to have GEGL version 0.0.16 or newer. You can get it from
+     http://gegl.org/ or check it out from the subversion repository:
+     http://svn.gnome.org/svn/gegl/trunk
 
   3. You need to have installed GTK+ version 2.12.1 or newer.  GIMP
      also need a recent versions of GLib (>= 2.14.1) and Pango (>= 1.12.2).

Modified: branches/weskaggs/NEWS
==============================================================================
--- branches/weskaggs/NEWS	(original)
+++ branches/weskaggs/NEWS	Tue Mar  4 03:15:17 2008
@@ -6,22 +6,7 @@
 This is the unstable development branch of GIMP.
 
 
-Changes in GIMP 2.4.1
+Changes in GIMP 2.5.0
 =====================
 
-- fixed a minor display rendering problem
-- improved the workaround for broken graphics card drivers (bug #421466)
-- fixed a crash with broken scripts and plug-ins (bug #490055)
-- fixed potential syntax error in configure script (bug #490068)
-- fixed parsing of floating point numbers in Script-Fu (bug #490198)
-- fixed potential crash when converting an indexed image to RGB (bug #490048)
-- update the histogram while doing color corrections (bug #490182)
-- fixed another crash with broken plug-ins (bug #490617)
-- fixed problems on Win32 when GIMP is installed into a non-ASCII path
-- fixed handling of truncated ASCII PNM files (bug #490827)
-- make sure that there's always a cursor, even for small brushes (bug #491272)
-- fixed line-drawing with a tablet and the Shift key (bug #164240)
-- added code to use the system monitor profile on OS X (bug #488170)
-- show changes to the rounded corners in the Rectangle Select tool (bug #418284)
-- reduced rounding errors in the display render routines (bug #490785)
-- translation updates (ca, de, et, lt, mk, pa, sv)
+ (there has been no release in the 2.5 development series yet)

Modified: branches/weskaggs/app/Makefile.am
==============================================================================
--- branches/weskaggs/app/Makefile.am	(original)
+++ branches/weskaggs/app/Makefile.am	Tue Mar  4 03:15:17 2008
@@ -51,6 +51,8 @@
 	sanity.h	\
 	units.c		\
 	units.h		\
+	version.c	\
+	version.h	\
 	gimp-log.c	\
 	gimp-log.h	\
 	gimp-intl.h
@@ -88,13 +90,15 @@
 	$(GEGL_CFLAGS)		\
 	-I$(includedir)
 
-AM_LDFLAGS = $(mwindows) $(munix) \
+AM_LDFLAGS = $(munix) \
 	$(CARBON_LDFLAGS)			\
 	-u $(SYMPREFIX)xcf_init			\
 	-u $(SYMPREFIX)internal_procs_init	\
 	-u $(SYMPREFIX)gimp_coords_mix		\
 	-u $(SYMPREFIX)gimp_plug_in_manager_restore
 
+gimp_2_5_LDFLAGS = $(AM_LDFLAGS) $(mwindows) 
+
 gimp_2_5_LDADD = \
 	gui/libappgui.a			\
 	actions/libappactions.a		\

Modified: branches/weskaggs/app/actions/edit-actions.c
==============================================================================
--- branches/weskaggs/app/actions/edit-actions.c	(original)
+++ branches/weskaggs/app/actions/edit-actions.c	Tue Mar  4 03:15:17 2008
@@ -117,7 +117,7 @@
     GIMP_HELP_EDIT_COPY },
 
   { "edit-copy-visible", NULL, /* GIMP_STOCK_COPY_VISIBLE, */
-    N_("Copy _Visible"), "",
+    N_("Copy _Visible"), "<control><shift>C",
     N_("Copy the selected region to the clipboard"),
     G_CALLBACK (edit_copy_visible_cmd_callback),
     GIMP_HELP_EDIT_COPY_VISIBLE },
@@ -135,7 +135,7 @@
     GIMP_HELP_EDIT_PASTE_INTO },
 
   { "edit-paste-as-new", GIMP_STOCK_PASTE_AS_NEW,
-    N_("Paste as New"), NULL,
+    N_("Paste as New"), "<control><shift>V",
     N_("Create a new image from the content of the clipboard"),
     G_CALLBACK (edit_paste_as_new_cmd_callback),
     GIMP_HELP_EDIT_PASTE_AS_NEW },
@@ -147,13 +147,13 @@
     GIMP_HELP_EDIT_PASTE_AS_NEW },
 
   { "edit-named-cut", GTK_STOCK_CUT,
-    N_("Cu_t Named..."), "<control><shift>X",
+    N_("Cu_t Named..."), "",
     N_("Move the selected pixels to a named buffer"),
     G_CALLBACK (edit_named_cut_cmd_callback),
     GIMP_HELP_BUFFER_CUT },
 
   { "edit-named-copy", GTK_STOCK_COPY,
-    N_("_Copy Named..."), "<control><shift>C",
+    N_("_Copy Named..."), "",
     N_("Copy the selected pixels to a named buffer"),
     G_CALLBACK (edit_named_copy_cmd_callback),
     GIMP_HELP_BUFFER_COPY },
@@ -165,7 +165,7 @@
     GIMP_HELP_BUFFER_COPY },
 
   { "edit-named-paste", GTK_STOCK_PASTE,
-    N_("_Paste Named..."), "<control><shift>V",
+    N_("_Paste Named..."), "",
     N_("Paste the content of a named buffer"),
     G_CALLBACK (edit_named_paste_cmd_callback),
     GIMP_HELP_BUFFER_PASTE },

Modified: branches/weskaggs/app/actions/plug-in-actions.c
==============================================================================
--- branches/weskaggs/app/actions/plug-in-actions.c	(original)
+++ branches/weskaggs/app/actions/plug-in-actions.c	Tue Mar  4 03:15:17 2008
@@ -491,9 +491,21 @@
 
   if (proc)
     {
+      GtkAction   *actual_action;
       const gchar *label;
       gchar       *repeat;
       gchar       *reshow;
+      gboolean     sensitive = FALSE;
+
+      /*  copy the sensitivity of the plug-in procedure's actual action
+       *  instead of calling plug_in_actions_update() because doing the
+       *  latter would set the sensitivity of this image's action on
+       *  all images' actions. See bug #517683.
+       */
+      actual_action = gtk_action_group_get_action (GTK_ACTION_GROUP (group),
+                                                   GIMP_OBJECT (proc)->name);
+      if (actual_action)
+        sensitive = gtk_action_get_sensitive (actual_action);
 
       label = gimp_plug_in_procedure_get_label (proc);
 
@@ -503,6 +515,9 @@
       gimp_action_group_set_action_label (group, "plug-in-repeat", repeat);
       gimp_action_group_set_action_label (group, "plug-in-reshow", reshow);
 
+      gimp_action_group_set_action_sensitive (group, "plug-in-repeat", sensitive);
+      gimp_action_group_set_action_sensitive (group, "plug-in-reshow", sensitive);
+
       g_free (repeat);
       g_free (reshow);
     }
@@ -512,20 +527,32 @@
                                           _("Repeat Last"));
       gimp_action_group_set_action_label (group, "plug-in-reshow",
                                           _("Re-Show Last"));
+
+      gimp_action_group_set_action_sensitive (group, "plug-in-repeat", FALSE);
+      gimp_action_group_set_action_sensitive (group, "plug-in-reshow", FALSE);
     }
 
   for (i = 0; i < gimp_plug_in_manager_history_length (manager); i++)
     {
       GtkAction *action;
-      gchar     *name = g_strdup_printf ("plug-in-recent-%02d", i + 1);
+      GtkAction *actual_action;
+      gchar     *name      = g_strdup_printf ("plug-in-recent-%02d", i + 1);
+      gboolean   sensitive = FALSE;
 
       action = gtk_action_group_get_action (GTK_ACTION_GROUP (group), name);
       g_free (name);
 
       proc = gimp_plug_in_manager_history_nth (manager, i);
 
+      /*  see comment above  */
+      actual_action = gtk_action_group_get_action (GTK_ACTION_GROUP (group),
+                                                   GIMP_OBJECT (proc)->name);
+      if (actual_action)
+        sensitive = gtk_action_get_sensitive (actual_action);
+
       g_object_set (action,
                     "visible",   TRUE,
+                    "sensitive", sensitive,
                     "procedure", proc,
                     "label",     gimp_plug_in_procedure_get_label (proc),
                     "stock-id",  gimp_plug_in_procedure_get_stock_id (proc),
@@ -546,9 +573,6 @@
                     "procedure", NULL,
                     NULL);
     }
-
-  /* update sensitivity of the actions */
-  plug_in_actions_update (group, manager->gimp);
 }
 
 static gboolean

Modified: branches/weskaggs/app/app.c
==============================================================================
--- branches/weskaggs/app/app.c	(original)
+++ branches/weskaggs/app/app.c	Tue Mar  4 03:15:17 2008
@@ -278,7 +278,7 @@
                          GMainLoop *loop)
 {
   if (gimp->be_verbose)
-    g_print ("EXIT: app_exit_after_callback\n");
+    g_print ("EXIT: %s\n", G_STRFUNC);
 
   /*
    *  In stable releases, we simply call exit() here. This speeds up

Modified: branches/weskaggs/app/batch.c
==============================================================================
--- branches/weskaggs/app/batch.c	(original)
+++ branches/weskaggs/app/batch.c	Tue Mar  4 03:15:17 2008
@@ -21,11 +21,11 @@
 #include <string.h>
 #include <stdlib.h>
 
-#include <glib-object.h>
+#include <gegl.h>
 
 #include "core/core-types.h"
 
-#include "base/base.h"
+#include "base/tile-swap.h"
 
 #include "core/gimp.h"
 #include "core/gimpparamspecs.h"
@@ -41,8 +41,7 @@
 #define BATCH_DEFAULT_EVAL_PROC   "plug-in-script-fu-eval"
 
 
-static gboolean  batch_exit_after_callback (Gimp          *gimp,
-                                            gboolean       kill_it);
+static gboolean  batch_exit_after_callback (Gimp          *gimp);
 static void      batch_run_cmd             (Gimp          *gimp,
                                             const gchar   *proc_name,
                                             GimpProcedure *procedure,
@@ -118,15 +117,23 @@
 }
 
 
+/*
+ * The purpose of this handler is to exit GIMP cleanly when the batch
+ * procedure calls the gimp-exit procedure. Without this callback, the
+ * message "batch command experienced an execution error" would appear
+ * and gimp would hang forever.
+ */
 static gboolean
-batch_exit_after_callback (Gimp     *gimp,
-                           gboolean  kill_it)
+batch_exit_after_callback (Gimp *gimp)
 {
   if (gimp->be_verbose)
-    g_print ("EXIT: %s\n", G_STRLOC);
+    g_print ("EXIT: %s\n", G_STRFUNC);
+
+  gegl_exit ();
+
+  /*  make sure that the swap files are removed before we quit */
+  tile_swap_exit ();
 
-  /*  make sure that the swap file is removed before we quit */
-  base_exit ();
   exit (EXIT_SUCCESS);
 
   return TRUE;

Modified: branches/weskaggs/app/core/gimp.c
==============================================================================
--- branches/weskaggs/app/core/gimp.c	(original)
+++ branches/weskaggs/app/core/gimp.c	Tue Mar  4 03:15:17 2008
@@ -258,7 +258,7 @@
   Gimp *gimp = GIMP (object);
 
   if (gimp->be_verbose)
-    g_print ("EXIT: gimp_dispose\n");
+    g_print ("EXIT: %s\n", G_STRFUNC);
 
   if (gimp->brush_factory)
     gimp_data_factory_data_free (gimp->brush_factory);
@@ -281,7 +281,7 @@
   Gimp *gimp = GIMP (object);
 
   if (gimp->be_verbose)
-    g_print ("EXIT: gimp_finalize\n");
+    g_print ("EXIT: %s\n", G_STRFUNC);
 
   gimp_contexts_exit (gimp);
 
@@ -526,7 +526,7 @@
   GimpData *clipboard_pattern;
 
   if (gimp->be_verbose)
-    g_print ("INIT: gimp_real_initialize\n");
+    g_print ("INIT: %s\n", G_STRFUNC);
 
   status_callback (_("Initialization"), NULL, 0.0);
 
@@ -617,7 +617,7 @@
                    GimpInitStatusFunc  status_callback)
 {
   if (gimp->be_verbose)
-    g_print ("INIT: gimp_real_restore\n");
+    g_print ("INIT: %s\n", G_STRFUNC);
 
   gimp_plug_in_manager_restore (gimp->plug_in_manager,
                                 gimp_get_user_context (gimp), status_callback);
@@ -630,7 +630,7 @@
   GError *error = NULL;
 
   if (gimp->be_verbose)
-    g_print ("EXIT: gimp_real_exit\n");
+    g_print ("EXIT: %s\n", G_STRFUNC);
 
   gimp_plug_in_manager_exit (gimp->plug_in_manager);
   gimp_modules_unload (gimp);
@@ -778,7 +778,7 @@
   g_return_if_fail (gimp->edit_config == NULL);
 
   if (gimp->be_verbose)
-    g_print ("INIT: gimp_load_config\n");
+    g_print ("INIT: %s\n", G_STRFUNC);
 
   /*  this needs to be done before gimprc loading because gimprc can
    *  use user defined units
@@ -810,7 +810,7 @@
   g_return_if_fail (GIMP_IS_CORE_CONFIG (gimp->config));
 
   if (gimp->be_verbose)
-    g_print ("INIT: gimp_initialize\n");
+    g_print ("INIT: %s\n", G_STRFUNC);
 
   g_signal_emit (gimp, gimp_signals[INITIALIZE], 0, status_callback);
 }
@@ -825,7 +825,7 @@
   g_return_if_fail (status_callback != NULL);
 
   if (gimp->be_verbose)
-    g_print ("INIT: gimp_restore\n");
+    g_print ("INIT: %s\n", G_STRFUNC);
 
   /*  initialize  the global parasite table  */
   status_callback (_("Looking for data files"), _("Parasites"), 0.0);
@@ -890,7 +890,7 @@
   gimp->exiting = TRUE;
 
   if (gimp->be_verbose)
-    g_print ("EXIT: gimp_exit\n");
+    g_print ("EXIT: %s\n", G_STRFUNC);
 
   g_signal_emit (gimp, gimp_signals[EXIT], 0,
                  force ? TRUE : FALSE,

Modified: branches/weskaggs/app/core/gimpcurve.c
==============================================================================
--- branches/weskaggs/app/core/gimpcurve.c	(original)
+++ branches/weskaggs/app/core/gimpcurve.c	Tue Mar  4 03:15:17 2008
@@ -38,8 +38,10 @@
 {
   PROP_0,
   PROP_CURVE_TYPE,
+  PROP_N_POINTS,
   PROP_POINTS,
-  PROP_CURVE
+  PROP_N_SAMPLES,
+  PROP_SAMPLES
 };
 
 
@@ -81,6 +83,11 @@
 static gchar    * gimp_curve_get_extension    (GimpData      *data);
 static GimpData * gimp_curve_duplicate        (GimpData      *data);
 
+static void       gimp_curve_set_n_points     (GimpCurve     *curve,
+                                               gint           n_points);
+static void       gimp_curve_set_n_samples    (GimpCurve     *curve,
+                                               gint           n_samples);
+
 static void       gimp_curve_calculate        (GimpCurve     *curve);
 static void       gimp_curve_plot             (GimpCurve     *curve,
                                                gint           p1,
@@ -126,14 +133,26 @@
                                                       GIMP_PARAM_READWRITE |
                                                       G_PARAM_CONSTRUCT));
 
+  g_object_class_install_property (object_class, PROP_N_POINTS,
+                                   g_param_spec_int ("n-points", NULL, NULL,
+                                                     17, 17, 17,
+                                                     GIMP_PARAM_READWRITE |
+                                                     G_PARAM_CONSTRUCT_ONLY));
+
   g_object_class_install_property (object_class, PROP_POINTS,
                                    g_param_spec_boolean ("points", NULL, NULL,
                                                          FALSE,
                                                          GIMP_PARAM_READWRITE |
                                                          G_PARAM_CONSTRUCT));
 
-  g_object_class_install_property (object_class, PROP_CURVE,
-                                   g_param_spec_boolean ("curve", NULL, NULL,
+  g_object_class_install_property (object_class, PROP_N_SAMPLES,
+                                   g_param_spec_int ("n-samples", NULL, NULL,
+                                                     256, 256, 256,
+                                                     GIMP_PARAM_READWRITE |
+                                                     G_PARAM_CONSTRUCT_ONLY));
+
+  g_object_class_install_property (object_class, PROP_SAMPLES,
+                                   g_param_spec_boolean ("samples", NULL, NULL,
                                                          FALSE,
                                                          GIMP_PARAM_READWRITE |
                                                          G_PARAM_CONSTRUCT));
@@ -142,7 +161,6 @@
 static void
 gimp_curve_init (GimpCurve *curve)
 {
-  gimp_curve_reset (curve, TRUE);
 }
 
 static void
@@ -150,6 +168,18 @@
 {
   GimpCurve *curve = GIMP_CURVE (object);
 
+  if (curve->points)
+    {
+      g_free (curve->points);
+      curve->points = NULL;
+    }
+
+  if (curve->samples)
+    {
+      g_free (curve->samples);
+      curve->samples = NULL;
+    }
+
   G_OBJECT_CLASS (parent_class)->finalize (object);
 }
 
@@ -167,8 +197,18 @@
       gimp_curve_set_curve_type (curve, g_value_get_enum (value));
       break;
 
+    case PROP_N_POINTS:
+      gimp_curve_set_n_points (curve, g_value_get_int (value));
+      break;
+
     case PROP_POINTS:
-    case PROP_CURVE:
+      break;
+
+    case PROP_N_SAMPLES:
+      gimp_curve_set_n_samples (curve, g_value_get_int (value));
+      break;
+
+    case PROP_SAMPLES:
       break;
 
     default:
@@ -191,8 +231,18 @@
       g_value_set_enum (value, curve->curve_type);
       break;
 
+    case PROP_N_POINTS:
+      g_value_set_int (value, curve->n_points);
+      break;
+
     case PROP_POINTS:
-    case PROP_CURVE:
+      break;
+
+    case PROP_N_SAMPLES:
+      g_value_set_int (value, curve->n_samples);
+      break;
+
+    case PROP_SAMPLES:
       break;
 
     default:
@@ -208,6 +258,9 @@
   GimpCurve *curve   = GIMP_CURVE (object);
   gint64     memsize = 0;
 
+  memsize += curve->n_points  * sizeof (GimpVector2);
+  memsize += curve->n_samples * sizeof (gdouble);
+
   return memsize + GIMP_OBJECT_CLASS (parent_class)->get_memsize (object,
                                                                   gui_size);
 }
@@ -327,30 +380,32 @@
 
   g_return_if_fail (GIMP_IS_CURVE (curve));
 
-  if (reset_type)
-    curve->curve_type = GIMP_CURVE_SMOOTH;
+  g_object_freeze_notify (G_OBJECT (curve));
+
+  for (i = 0; i < curve->n_samples; i++)
+    curve->samples[i] = (gdouble) i / (gdouble) (curve->n_samples - 1);
 
-  for (i = 0; i < 256; i++)
-    curve->curve[i] = (gdouble) i / 255.0;
+  g_object_notify (G_OBJECT (curve), "samples");
 
-  for (i = 0; i < GIMP_CURVE_NUM_POINTS; i++)
+  curve->points[0].x = 0.0;
+  curve->points[0].y = 0.0;
+
+  for (i = 1; i < curve->n_points - 1; i++)
     {
       curve->points[i].x = -1.0;
       curve->points[i].y = -1.0;
     }
 
-  curve->points[0].x  = 0.0;
-  curve->points[0].y  = 0.0;
-  curve->points[GIMP_CURVE_NUM_POINTS - 1].x = 1.0;
-  curve->points[GIMP_CURVE_NUM_POINTS - 1].y = 1.0;
-
-  g_object_freeze_notify (G_OBJECT (curve));
+  curve->points[curve->n_points - 1].x = 1.0;
+  curve->points[curve->n_points - 1].y = 1.0;
 
   g_object_notify (G_OBJECT (curve), "points");
-  g_object_notify (G_OBJECT (curve), "curve");
 
   if (reset_type)
-    g_object_notify (G_OBJECT (curve), "curve-type");
+    {
+      curve->curve_type = GIMP_CURVE_SMOOTH;
+      g_object_notify (G_OBJECT (curve), "curve-type");
+    }
 
   g_object_thaw_notify (G_OBJECT (curve));
 
@@ -371,17 +426,28 @@
 
       if (curve_type == GIMP_CURVE_SMOOTH)
         {
+          gint n_points;
           gint i;
 
-          /*  pick representative points from the curve and make them
-           *  control points
+          for (i = 0; i < curve->n_points; i++)
+            {
+              curve->points[i].x = -1;
+              curve->points[i].y = -1;
+            }
+
+          /*  pick some points from the curve and make them control
+           *  points
            */
-          for (i = 0; i <= 8; i++)
+          n_points = CLAMP (9, curve->n_points / 2, curve->n_points);
+
+          for (i = 0; i < n_points; i++)
             {
-              gint32 index = CLAMP0255 (i * 32);
+              gint sample = i * (curve->n_samples - 1) / (n_points - 1);
+              gint point  = i * (curve->n_points  - 1) / (n_points - 1);
 
-              curve->points[i * 2].x = (gdouble) index / 255.0;
-              curve->points[i * 2].y = curve->curve[index];
+              curve->points[point].x = ((gdouble) sample /
+                                        (gdouble) (curve->n_samples - 1));
+              curve->points[point].y = curve->samples[sample];
             }
 
           g_object_notify (G_OBJECT (curve), "points");
@@ -403,7 +469,82 @@
   return curve->curve_type;
 }
 
-#define MIN_DISTANCE (8.0 / 255.0)
+static void
+gimp_curve_set_n_points (GimpCurve *curve,
+                         gint       n_points)
+{
+  g_return_if_fail (GIMP_IS_CURVE (curve));
+
+  if (n_points != curve->n_points)
+    {
+      gint i;
+
+      g_object_freeze_notify (G_OBJECT (curve));
+
+      curve->n_points = n_points;
+      g_object_notify (G_OBJECT (curve), "n-points");
+
+      curve->points = g_renew (GimpVector2, curve->points, curve->n_points);
+
+      curve->points[0].x = 0.0;
+      curve->points[0].y = 0.0;
+
+      for (i = 1; i < curve->n_points - 1; i++)
+        {
+          curve->points[i].x = -1.0;
+          curve->points[i].y = -1.0;
+        }
+
+      curve->points[curve->n_points - 1].x = 1.0;
+      curve->points[curve->n_points - 1].y = 1.0;
+
+      g_object_notify (G_OBJECT (curve), "points");
+
+      g_object_thaw_notify (G_OBJECT (curve));
+    }
+}
+
+gint
+gimp_curve_get_n_points (GimpCurve *curve)
+{
+  g_return_val_if_fail (GIMP_IS_CURVE (curve), 0);
+
+  return curve->n_points;
+}
+
+static void
+gimp_curve_set_n_samples (GimpCurve *curve,
+                          gint       n_samples)
+{
+  g_return_if_fail (GIMP_IS_CURVE (curve));
+
+  if (n_samples != curve->n_samples)
+    {
+      gint i;
+
+      g_object_freeze_notify (G_OBJECT (curve));
+
+      curve->n_samples = n_samples;
+      g_object_notify (G_OBJECT (curve), "n-samples");
+
+      curve->samples = g_renew (gdouble, curve->samples, curve->n_samples);
+
+      for (i = 0; i < curve->n_samples; i++)
+        curve->samples[i] = (gdouble) i / (gdouble) (curve->n_samples - 1);
+
+      g_object_notify (G_OBJECT (curve), "samples");
+
+      g_object_thaw_notify (G_OBJECT (curve));
+    }
+}
+
+gint
+gimp_curve_get_n_samples (GimpCurve *curve)
+{
+  g_return_val_if_fail (GIMP_IS_CURVE (curve), 0);
+
+  return curve->n_samples;
+}
 
 gint
 gimp_curve_get_closest_point (GimpCurve *curve,
@@ -415,7 +556,7 @@
 
   g_return_val_if_fail (GIMP_IS_CURVE (curve), 0);
 
-  for (i = 0; i < GIMP_CURVE_NUM_POINTS; i++)
+  for (i = 0; i < curve->n_points; i++)
     {
       if (curve->points[i].x >= 0.0 &&
           fabs (x - curve->points[i].x) < distance)
@@ -425,8 +566,8 @@
         }
     }
 
-  if (distance > MIN_DISTANCE)
-    closest_point = ((gint) (x * 255.999) + 8) / 16;
+  if (distance > (1.0 / (curve->n_points * 2.0)))
+    closest_point = ROUND (x * (gdouble) (curve->n_points - 1));
 
   return closest_point;
 }
@@ -438,6 +579,9 @@
                       gdouble    y)
 {
   g_return_if_fail (GIMP_IS_CURVE (curve));
+  g_return_if_fail (point >= 0 && point < curve->n_points);
+  g_return_if_fail (x == -1.0 || (x >= 0 && x <= 1.0));
+  g_return_if_fail (y == -1.0 || (y >= 0 && y <= 1.0));
 
   if (curve->curve_type == GIMP_CURVE_FREE)
     return;
@@ -460,6 +604,8 @@
                        gdouble    y)
 {
   g_return_if_fail (GIMP_IS_CURVE (curve));
+  g_return_if_fail (point >= 0 && point < curve->n_points);
+  g_return_if_fail (y >= 0 && y <= 1.0);
 
   if (curve->curve_type == GIMP_CURVE_FREE)
     return;
@@ -482,6 +628,7 @@
                       gdouble   *y)
 {
   g_return_if_fail (GIMP_IS_CURVE (curve));
+  g_return_if_fail (point >= 0 && point < curve->n_points);
 
   if (curve->curve_type == GIMP_CURVE_FREE)
     return;
@@ -496,15 +643,17 @@
                       gdouble    y)
 {
   g_return_if_fail (GIMP_IS_CURVE (curve));
+  g_return_if_fail (x >= 0 && x <= 1.0);
+  g_return_if_fail (y >= 0 && y <= 1.0);
 
   if (curve->curve_type == GIMP_CURVE_SMOOTH)
     return;
 
   g_object_freeze_notify (G_OBJECT (curve));
 
-  curve->curve[(gint) (x * 255.999)] = y;
+  curve->samples[ROUND (x * (gdouble) (curve->n_samples - 1))] = y;
 
-  g_object_notify (G_OBJECT (curve), "curve");
+  g_object_notify (G_OBJECT (curve), "samples");
 
   g_object_thaw_notify (G_OBJECT (curve));
 
@@ -521,19 +670,19 @@
 
   if (x < 0.0)
     {
-      value = curve->curve[0];
+      value = curve->samples[0];
     }
   else if (x >= 1.0)
     {
-      value = curve->curve[255];
+      value = curve->samples[curve->n_samples - 1];
     }
   else /* interpolate the curve */
     {
-      gint    index = floor (x * 255.0);
-      gdouble f     = x * 255.0 - index;
+      gint    index = floor (x * (gdouble) (curve->n_samples - 1));
+      gdouble f     = x * (gdouble) (curve->n_samples - 1) - index;
 
-      value = ((1.0 - f) * curve->curve[index    ] +
-                      f  * curve->curve[index + 1]);
+      value = ((1.0 - f) * curve->samples[index    ] +
+                      f  * curve->samples[index + 1]);
     }
 
   return value;
@@ -541,15 +690,20 @@
 
 void
 gimp_curve_get_uchar (GimpCurve *curve,
-                      guchar    *dest_array)
+                      gint       n_samples,
+                      guchar    *samples)
 {
   gint i;
 
   g_return_if_fail (GIMP_IS_CURVE (curve));
-  g_return_if_fail (dest_array != NULL);
+#ifdef __GNUC__
+#warning: FIXME: support n_samples != curve->n_samples
+#endif
+  g_return_if_fail (n_samples == curve->n_samples);
+  g_return_if_fail (samples != NULL);
 
-  for (i = 0; i < 256; i++)
-    dest_array[i] = curve->curve[i] * 255.999;
+  for (i = 0; i < curve->n_samples; i++)
+    samples[i] = curve->samples[i] * 255.999;
 }
 
 
@@ -559,7 +713,7 @@
 gimp_curve_calculate (GimpCurve *curve)
 {
   gint i;
-  gint points[GIMP_CURVE_NUM_POINTS];
+  gint points[curve->n_points];
   gint num_pts;
   gint p1, p2, p3, p4;
 
@@ -571,18 +725,27 @@
     case GIMP_CURVE_SMOOTH:
       /*  cycle through the curves  */
       num_pts = 0;
-      for (i = 0; i < GIMP_CURVE_NUM_POINTS; i++)
+      for (i = 0; i < curve->n_points; i++)
         if (curve->points[i].x >= 0.0)
           points[num_pts++] = i;
 
       /*  Initialize boundary curve points */
       if (num_pts != 0)
         {
-          for (i = 0; i < (gint) (curve->points[points[0]].x * 255.999); i++)
-            curve->curve[i] = curve->points[points[0]].y;
+          GimpVector2 point;
+          gint        boundary;
 
-          for (i = (gint) (curve->points[points[num_pts - 1]].x * 255.999); i < 256; i++)
-            curve->curve[i] = curve->points[points[num_pts - 1]].y;
+          point    = curve->points[points[0]];
+          boundary = ROUND (point.x * (gdouble) (curve->n_samples - 1));
+
+          for (i = 0; i < boundary; i++)
+            curve->samples[i] = point.y;
+
+          point    = curve->points[points[num_pts - 1]];
+          boundary = ROUND (point.x * (gdouble) (curve->n_samples - 1));
+
+          for (i = boundary; i < curve->n_samples; i++)
+            curve->samples[i] = point.y;
         }
 
       for (i = 0; i < num_pts - 1; i++)
@@ -601,10 +764,10 @@
           gdouble x = curve->points[points[i]].x;
           gdouble y = curve->points[points[i]].y;
 
-          curve->curve[(gint) (x * 255.999)] = y;
+          curve->samples[ROUND (x * (gdouble) (curve->n_samples - 1))] = y;
         }
 
-      g_object_notify (G_OBJECT (curve), "curve");
+      g_object_notify (G_OBJECT (curve), "samples");
       break;
 
     case GIMP_CURVE_FREE:
@@ -632,7 +795,6 @@
   gdouble x0, x3;
   gdouble y0, y1, y2, y3;
   gdouble dx, dy;
-  gdouble y, t;
   gdouble slope;
 
   /* the outer control points for the bezier curve. */
@@ -706,14 +868,19 @@
    * finally calculate the y(t) values for the given bezier values. We can
    * use homogenously distributed values for t, since x(t) increases linearily.
    */
-  for (i = 0; i <= (gint) (dx * 255.999); i++)
+  for (i = 0; i <= ROUND (dx * (gdouble) (curve->n_samples - 1)); i++)
     {
-      t = i / dx / 255.0;
+      gdouble y, t;
+      gint    index;
+
+      t = i / dx / (gdouble) (curve->n_samples - 1);
       y =     y0 * (1-t) * (1-t) * (1-t) +
           3 * y1 * (1-t) * (1-t) * t     +
           3 * y2 * (1-t) * t     * t     +
               y3 * t     * t     * t;
 
-      curve->curve[(gint) (x0 * 255.999) + i] = CLAMP (y, 0.0, 1.0);
+      index = ROUND (x0 * (gdouble) (curve->n_samples - 1)) + i;
+
+      curve->samples[index] = CLAMP (y, 0.0, 1.0);
     }
 }

Modified: branches/weskaggs/app/core/gimpcurve.h
==============================================================================
--- branches/weskaggs/app/core/gimpcurve.h	(original)
+++ branches/weskaggs/app/core/gimpcurve.h	Tue Mar  4 03:15:17 2008
@@ -24,9 +24,6 @@
 #include "libgimpmath/gimpvector.h"
 
 
-#define GIMP_CURVE_NUM_POINTS 17 /* TODO: get rid of this limit */
-
-
 #define GIMP_TYPE_CURVE            (gimp_curve_get_type ())
 #define GIMP_CURVE(obj)            (G_TYPE_CHECK_INSTANCE_CAST ((obj), GIMP_TYPE_CURVE, GimpCurve))
 #define GIMP_CURVE_CLASS(klass)    (G_TYPE_CHECK_CLASS_CAST ((klass), GIMP_TYPE_CURVE, GimpCurveClass))
@@ -43,8 +40,11 @@
 
   GimpCurveType  curve_type;
 
-  GimpVector2    points[GIMP_CURVE_NUM_POINTS];
-  gdouble        curve[256];
+  gint           n_points;
+  GimpVector2   *points;
+
+  gint           n_samples;
+  gdouble       *samples;
 };
 
 struct _GimpCurveClass
@@ -65,6 +65,9 @@
                                               GimpCurveType  curve_type);
 GimpCurveType   gimp_curve_get_curve_type    (GimpCurve     *curve);
 
+gint            gimp_curve_get_n_points      (GimpCurve     *curve);
+gint            gimp_curve_get_n_samples     (GimpCurve     *curve);
+
 gint            gimp_curve_get_closest_point (GimpCurve     *curve,
                                               gdouble        x);
 
@@ -88,7 +91,8 @@
                                               gdouble        x);
 
 void            gimp_curve_get_uchar         (GimpCurve     *curve,
-                                              guchar        *dest_array);
+                                              gint           n_samples,
+                                              guchar        *samples);
 
 
 #endif /* __GIMP_CURVE_H__ */

Modified: branches/weskaggs/app/core/gimpdrawable-curves.c
==============================================================================
--- branches/weskaggs/app/core/gimpdrawable-curves.c	(original)
+++ branches/weskaggs/app/core/gimpdrawable-curves.c	Tue Mar  4 03:15:17 2008
@@ -80,13 +80,18 @@
 
   gimp_data_freeze (GIMP_DATA (curve));
 
+#ifdef __GNUC__
+#warning FIXME: create a curves object with the right number of points
+#endif
   /*  unset the last point  */
-  gimp_curve_set_point (curve, GIMP_CURVE_NUM_POINTS - 1, -1, -1);
+  gimp_curve_set_point (curve, curve->n_points - 1, -1, -1);
 
-  for (i = 0; i < n_points / 2; i++)
+  n_points = MIN (n_points / 2, curve->n_points);
+
+  for (i = 0; i < n_points; i++)
     gimp_curve_set_point (curve, i,
-                          points[i * 2],
-                          points[i * 2 + 1]);
+                          (gdouble) points[i * 2]     / 255.0,
+                          (gdouble) points[i * 2 + 1] / 255.0);
 
   gimp_data_thaw (GIMP_DATA (curve));
 
@@ -129,7 +134,7 @@
 
   for (i = 0; i < 256; i++)
     gimp_curve_set_curve (curve,
-                          (gdouble) i / 255.0,
+                          (gdouble) i         / 255.0,
                           (gdouble) points[i] / 255.0);
 
   gimp_data_thaw (GIMP_DATA (curve));

Modified: branches/weskaggs/app/core/gimpdrawable-transform.c
==============================================================================
--- branches/weskaggs/app/core/gimpdrawable-transform.c	(original)
+++ branches/weskaggs/app/core/gimpdrawable-transform.c	Tue Mar  4 03:15:17 2008
@@ -580,7 +580,7 @@
       new_tiles = gimp_drawable_transform_tiles_affine (drawable, context,
                                                         orig_tiles,
                                                         matrix,
-                                                        GIMP_TRANSFORM_FORWARD,
+                                                        direction,
                                                         interpolation_type,
                                                         recursion_level,
                                                         clip_result,

Modified: branches/weskaggs/app/display/gimpdisplayshell-callbacks.c
==============================================================================
--- branches/weskaggs/app/display/gimpdisplayshell-callbacks.c	(original)
+++ branches/weskaggs/app/display/gimpdisplayshell-callbacks.c	Tue Mar  4 03:15:17 2008
@@ -81,7 +81,7 @@
 #include "gimp-intl.h"
 
 
-#define DEFAULT_EVENT_SMOOTHING  0.7
+#define DEFAULT_EVENT_SMOOTHING  0.98
 #define DEFAULT_EVENT_FILTER  0.5
 
 /*  local function prototypes  */
@@ -141,7 +141,8 @@
 
             if (event->type == GDK_KEY_PRESS)
               {
-                if (kevent->keyval == GDK_space && shell->space_release_pending)
+                if ((kevent->keyval == GDK_space ||
+                     kevent->keyval == GDK_KP_Space) && shell->space_release_pending)
                   {
                     shell->space_pressed         = TRUE;
                     shell->space_release_pending = FALSE;
@@ -149,7 +150,8 @@
               }
             else
               {
-                if (kevent->keyval == GDK_space && shell->space_pressed)
+                if ((kevent->keyval == GDK_space ||
+                     kevent->keyval == GDK_KP_Space) && shell->space_pressed)
                   {
                     shell->space_pressed         = FALSE;
                     shell->space_release_pending = TRUE;
@@ -164,12 +166,15 @@
           case GDK_Left:      case GDK_Right:
           case GDK_Up:        case GDK_Down:
           case GDK_space:
+          case GDK_KP_Space:
           case GDK_Tab:
           case GDK_ISO_Left_Tab:
           case GDK_Alt_L:     case GDK_Alt_R:
           case GDK_Shift_L:   case GDK_Shift_R:
           case GDK_Control_L: case GDK_Control_R:
-          case GDK_Return:    case GDK_KP_Enter:
+          case GDK_Return:
+          case GDK_KP_Enter:
+          case GDK_ISO_Enter:
           case GDK_BackSpace: case GDK_Delete:
             break;
 
@@ -1291,9 +1296,10 @@
             /* Early removal of useless events saves CPU time.
              * Smoothing is 0.0 here for coasting.
              */
+
             if (gimp_display_shell_eval_event (shell,
-                                               &image_coords, 
-                                               0.0, 
+                                               &image_coords,
+                                               0.0,
                                                DEFAULT_EVENT_FILTER,
                                                time))
               {
@@ -1349,6 +1355,7 @@
               {
               case GDK_Return:
               case GDK_KP_Enter:
+              case GDK_ISO_Enter:
               case GDK_BackSpace:
               case GDK_Delete:
               case GDK_Escape:
@@ -1372,6 +1379,7 @@
                 break;
 
               case GDK_space:
+              case GDK_KP_Space:
                 gimp_display_shell_space_pressed (shell, state, time);
                 return_val = TRUE;
                 break;
@@ -1463,6 +1471,7 @@
             switch (kevent->keyval)
               {
               case GDK_space:
+              case GDK_KP_Space:
                 gimp_display_shell_space_released (shell, state, time);
                 return_val = TRUE;
                 break;

Modified: branches/weskaggs/app/display/gimpdisplayshell-coords.c
==============================================================================
--- branches/weskaggs/app/display/gimpdisplayshell-coords.c	(original)
+++ branches/weskaggs/app/display/gimpdisplayshell-coords.c	Tue Mar  4 03:15:17 2008
@@ -190,9 +190,8 @@
  *
  * This function evaluates the event to decide if the change is
  * big enough to need handling and returns FALSE, if change is less
- * than one image pixel or when smoothed event distance covers less
- * than one pixel taking a whole lot of load off any draw tools that
- * have no use for these sub-pixel events anyway. If the event is
+ * than set filter level taking a whole lot of load off any draw tools
+ * that have no use for these events anyway. If the event is
  * seen fit at first look, it is evaluated for speed and smoothed.
  * Due to lousy time resolution of events pretty strong smoothing is
  * applied to timestamps for sensible speed result. This function is
@@ -216,6 +215,22 @@
   const gdouble  smooth_factor = 0.3;
   guint32        thistime      = time;
   gdouble        dist;
+  gdouble        filter;
+  gdouble        inertia;
+
+  /* Event filtering & smoothing causes problems with cursor tracking
+   * when zoomed above screen resolution so we need to supress it.
+   */
+  if (shell->scale_x > 1.0 || shell->scale_y > 1.0)
+    {
+     filter  = filter_treshhold / (MAX (shell->scale_x, shell->scale_y));
+     inertia = 0.0;
+    }
+  else
+    {
+      filter  = filter_treshhold;
+      inertia = inertia_factor;
+    }
 
   if (shell->last_disp_motion_time == 0)
     {
@@ -234,7 +249,7 @@
       /* Events with distances less than the filter_threshold are not
          worth handling.
        */
-      if (fabs (dx) < filter_treshhold && fabs (dy) < filter_treshhold)
+      if (fabs (dx) < filter && fabs (dy) < filter)
         return FALSE;
 
       coords->delta_time = thistime - shell->last_disp_motion_time;
@@ -261,12 +276,12 @@
           coords->velocity = MIN (coords->velocity, 1.0);
         }
 
-      if (inertia_factor > 0 && coords->distance > 0)
+      if (inertia > 0 && coords->distance > 0)
         {
           /* Apply smoothing to X and Y. */
 
           /* This tells how far from the pointer can stray from the line */
-          gdouble max_deviation = SQR (20 * inertia_factor);
+          gdouble max_deviation = SQR (20 * inertia);
           gdouble cur_deviation = max_deviation;
           gdouble sin_avg;
           gdouble sin_old;
@@ -279,13 +294,13 @@
 
           sin_new = coords->delta_x / coords->distance;
           sin_old = shell->last_coords.delta_x / shell->last_coords.distance;
-          sin_avg = sin (asin (sin_old) * inertia_factor +
-                         asin (sin_new) * (1 - inertia_factor));
+          sin_avg = sin (asin (sin_old) * inertia +
+                         asin (sin_new) * (1 - inertia));
 
           cos_new = coords->delta_y / coords->distance;
           cos_old = shell->last_coords.delta_y / shell->last_coords.distance;
-          cos_avg = cos (acos (cos_old) * inertia_factor +
-                         acos (cos_new) * (1 - inertia_factor));
+          cos_avg = cos (acos (cos_old) * inertia +
+                         acos (cos_new) * (1 - inertia));
 
           coords->delta_x = sin_avg * coords->distance;
           coords->delta_y = cos_avg * coords->distance;
@@ -322,7 +337,7 @@
                   shell->last_coords.velocity,
                   coords->pressure,
                   coords->distance - dist,
-                  inertia_factor);
+                  inertia);
 #endif
     }
 

Modified: branches/weskaggs/app/display/gimpdisplayshell-draw.c
==============================================================================
--- branches/weskaggs/app/display/gimpdisplayshell-draw.c	(original)
+++ branches/weskaggs/app/display/gimpdisplayshell-draw.c	Tue Mar  4 03:15:17 2008
@@ -395,8 +395,7 @@
   coords = g_new (GdkPoint, MAX (2, num_points));
 
   gimp_display_shell_transform_points (shell,
-                                       (const gdouble *) points, coords,
-                                       num_points, FALSE);
+                                       points, coords, num_points, FALSE);
 
   if (num_points == 1)
     {

Modified: branches/weskaggs/app/display/gimpdisplayshell-transform.c
==============================================================================
--- branches/weskaggs/app/display/gimpdisplayshell-transform.c	(original)
+++ branches/weskaggs/app/display/gimpdisplayshell-transform.c	Tue Mar  4 03:15:17 2008
@@ -276,7 +276,7 @@
 /**
  * gimp_display_shell_transform_points:
  * @shell:       a #GimpDisplayShell
- * @points:      array of x, y coordinate pairs
+ * @points:      array of GimpVectors2 coordinate pairs
  * @coords:      returns the corresponding display coordinates
  * @n_points:    number of points
  * @use_offsets: if %TRUE, the source coordinates are in the coordinate
@@ -286,11 +286,11 @@
  * objects can be rendered at the correct points on the display.
  **/
 void
-gimp_display_shell_transform_points (GimpDisplayShell *shell,
-                                     const gdouble    *points,
-                                     GdkPoint         *coords,
-                                     gint              n_points,
-                                     gboolean          use_offsets)
+gimp_display_shell_transform_points (GimpDisplayShell  *shell,
+                                     const GimpVector2 *points,
+                                     GdkPoint          *coords,
+                                     gint               n_points,
+                                     gboolean           use_offsets)
 {
   gint offset_x = 0;
   gint offset_y = 0;
@@ -308,8 +308,8 @@
 
   for (i = 0; i < n_points ; i++)
     {
-      gdouble x = points[i*2]   + offset_x;
-      gdouble y = points[i*2+1] + offset_y;
+      gdouble x = points[i].x + offset_x;
+      gdouble y = points[i].y + offset_y;
 
       x = x * shell->x_src_dec / shell->x_dest_inc;
       y = y * shell->y_src_dec / shell->y_dest_inc;

Modified: branches/weskaggs/app/display/gimpdisplayshell-transform.h
==============================================================================
--- branches/weskaggs/app/display/gimpdisplayshell-transform.h	(original)
+++ branches/weskaggs/app/display/gimpdisplayshell-transform.h	Tue Mar  4 03:15:17 2008
@@ -27,54 +27,54 @@
                                                  GimpCoords       *display_coords,
                                                  GimpCoords       *image_coords);
 
-void  gimp_display_shell_transform_xy         (GimpDisplayShell *shell,
-                                               gdouble           x,
-                                               gdouble           y,
-                                               gint             *nx,
-                                               gint             *ny,
-                                               gboolean          use_offsets);
-void  gimp_display_shell_untransform_xy       (GimpDisplayShell *shell,
-                                               gint              x,
-                                               gint              y,
-                                               gint             *nx,
-                                               gint             *ny,
-                                               gboolean          round,
-                                               gboolean          use_offsets);
-
-void  gimp_display_shell_transform_xy_f       (GimpDisplayShell *shell,
-                                               gdouble           x,
-                                               gdouble           y,
-                                               gdouble          *nx,
-                                               gdouble          *ny,
-                                               gboolean          use_offsets);
-void  gimp_display_shell_untransform_xy_f     (GimpDisplayShell *shell,
-                                               gdouble           x,
-                                               gdouble           y,
-                                               gdouble          *nx,
-                                               gdouble          *ny,
-                                               gboolean          use_offsets);
-
-void  gimp_display_shell_transform_points     (GimpDisplayShell *shell,
-                                               const gdouble    *points,
-                                               GdkPoint         *coords,
-                                               gint              n_points,
-                                               gboolean          use_offsets);
-void  gimp_display_shell_transform_coords     (GimpDisplayShell *shell,
-                                               const GimpCoords *image_coords,
-                                               GdkPoint         *disp_coords,
-                                               gint              n_coords,
-                                               gboolean          use_offsets);
-void  gimp_display_shell_transform_segments   (GimpDisplayShell *shell,
-                                               const BoundSeg   *src_segs,
-                                               GdkSegment       *dest_segs,
-                                               gint              n_segs,
-                                               gboolean          use_offsets);
-
-void  gimp_display_shell_untransform_viewport (GimpDisplayShell *shell,
-                                               gint             *x,
-                                               gint             *y,
-                                               gint             *width,
-                                               gint             *height);
+void  gimp_display_shell_transform_xy         (GimpDisplayShell  *shell,
+                                               gdouble            x,
+                                               gdouble            y,
+                                               gint              *nx,
+                                               gint              *ny,
+                                               gboolean           use_offsets);
+void  gimp_display_shell_untransform_xy       (GimpDisplayShell  *shell,
+                                               gint               x,
+                                               gint               y,
+                                               gint              *nx,
+                                               gint              *ny,
+                                               gboolean           round,
+                                               gboolean           use_offsets);
+
+void  gimp_display_shell_transform_xy_f       (GimpDisplayShell  *shell,
+                                               gdouble            x,
+                                               gdouble            y,
+                                               gdouble           *nx,
+                                               gdouble           *ny,
+                                               gboolean           use_offsets);
+void  gimp_display_shell_untransform_xy_f     (GimpDisplayShell  *shell,
+                                               gdouble            x,
+                                               gdouble            y,
+                                               gdouble           *nx,
+                                               gdouble           *ny,
+                                               gboolean           use_offsets);
+
+void  gimp_display_shell_transform_points     (GimpDisplayShell  *shell,
+                                               const GimpVector2 *points,
+                                               GdkPoint          *coords,
+                                               gint               n_points,
+                                               gboolean           use_offsets);
+void  gimp_display_shell_transform_coords     (GimpDisplayShell  *shell,
+                                               const GimpCoords  *image_coords,
+                                               GdkPoint          *disp_coords,
+                                               gint               n_coords,
+                                               gboolean           use_offsets);
+void  gimp_display_shell_transform_segments   (GimpDisplayShell  *shell,
+                                               const BoundSeg    *src_segs,
+                                               GdkSegment        *dest_segs,
+                                               gint               n_segs,
+                                               gboolean           use_offsets);
+
+void  gimp_display_shell_untransform_viewport (GimpDisplayShell  *shell,
+                                               gint              *x,
+                                               gint              *y,
+                                               gint              *width,
+                                               gint              *height);
 
 
 #endif /* __GIMP_DISPLAY_SHELL_TRANSFORM_H__ */

Modified: branches/weskaggs/app/gegl/gimpcurvesconfig.c
==============================================================================
--- branches/weskaggs/app/gegl/gimpcurvesconfig.c	(original)
+++ branches/weskaggs/app/gegl/gimpcurvesconfig.c	Tue Mar  4 03:15:17 2008
@@ -201,9 +201,9 @@
             gimp_config_sync (G_OBJECT (src_curve), G_OBJECT (dest_curve), 0);
 
             memcpy (dest_curve->points, src_curve->points,
-                    sizeof (src_curve->points));
-            memcpy (dest_curve->curve, src_curve->curve,
-                    sizeof (src_curve->curve));
+                    sizeof (GimpVector2) * src_curve->n_points);
+            memcpy (dest_curve->samples, src_curve->samples,
+                    sizeof (gdouble) * src_curve->n_samples);
           }
       }
       break;
@@ -235,9 +235,9 @@
             return FALSE;
 
           if (memcmp (a_curve->points, b_curve->points,
-                      sizeof (b_curve->points)) ||
-              memcmp (a_curve->curve, b_curve->curve,
-                      sizeof (b_curve->curve)))
+                      sizeof (GimpVector2) * b_curve->n_points) ||
+              memcmp (a_curve->samples, b_curve->samples,
+                      sizeof (gdouble) * b_curve->n_samples))
             return FALSE;
         }
       else if (a_curve || b_curve)
@@ -288,10 +288,10 @@
         {
           gimp_config_sync (G_OBJECT (src_curve), G_OBJECT (dest_curve), 0);
 
-          memcpy (dest_curve->points,
-                  src_curve->points, sizeof (src_curve->points));
-          memcpy (dest_curve->curve,
-                  src_curve->curve, sizeof (src_curve->curve));
+          memcpy (dest_curve->points, src_curve->points,
+                  sizeof (GimpVector2) * src_curve->n_points);
+          memcpy (dest_curve->samples, src_curve->samples,
+                  sizeof (gdouble) * src_curve->n_samples);
         }
     }
 
@@ -322,6 +322,8 @@
   gimp_curve_reset (config->curve[config->channel], TRUE);
 }
 
+#define GIMP_CURVE_N_CRUFT_POINTS 17
+
 gboolean
 gimp_curves_config_load_cruft (GimpCurvesConfig  *config,
                                gpointer           fp,
@@ -331,8 +333,8 @@
   gint   i, j;
   gint   fields;
   gchar  buf[50];
-  gint   index[5][GIMP_CURVE_NUM_POINTS];
-  gint   value[5][GIMP_CURVE_NUM_POINTS];
+  gint   index[5][GIMP_CURVE_N_CRUFT_POINTS];
+  gint   value[5][GIMP_CURVE_N_CRUFT_POINTS];
 
   g_return_val_if_fail (GIMP_IS_CURVES_CONFIG (config), FALSE);
   g_return_val_if_fail (file != NULL, FALSE);
@@ -348,7 +350,7 @@
 
   for (i = 0; i < 5; i++)
     {
-      for (j = 0; j < GIMP_CURVE_NUM_POINTS; j++)
+      for (j = 0; j < GIMP_CURVE_N_CRUFT_POINTS; j++)
         {
           fields = fscanf (file, "%d %d ", &index[i][j], &value[i][j]);
           if (fields != 2)
@@ -372,7 +374,7 @@
 
       gimp_curve_set_curve_type (curve, GIMP_CURVE_SMOOTH);
 
-      for (j = 0; j < GIMP_CURVE_NUM_POINTS; j++)
+      for (j = 0; j < GIMP_CURVE_N_CRUFT_POINTS; j++)
         gimp_curve_set_point (curve, j,
                               (gdouble) index[i][j] / 255.0,
                               (gdouble) value[i][j] / 255.0);
@@ -404,27 +406,46 @@
 
       if (curve->curve_type == GIMP_CURVE_FREE)
         {
-          /* pick representative points from the curve and make them
-           * control points
+          gint n_points;
+
+          for (j = 0; j < curve->n_points; j++)
+            {
+              curve->points[j].x = -1;
+              curve->points[j].y = -1;
+            }
+
+          /* pick some points from the curve and make them control
+           * points
            */
-          for (j = 0; j <= 8; j++)
+          n_points = CLAMP (9, curve->n_points / 2, curve->n_points);
+
+          for (j = 0; j < n_points; j++)
             {
-              gint32 index = CLAMP0255 (j * 32);
+              gint sample = j * (curve->n_samples - 1) / (n_points - 1);
+              gint point  = j * (curve->n_points  - 1) / (n_points - 1);
 
-              curve->points[j * 2].x = (gdouble) index / 255.0;
-              curve->points[j * 2].y = curve->curve[index];
+              curve->points[point].x = ((gdouble) sample /
+                                        (gdouble) (curve->n_samples - 1));
+              curve->points[point].y = curve->samples[sample];
             }
         }
 
-      for (j = 0; j < GIMP_CURVE_NUM_POINTS; j++)
+      for (j = 0; j < curve->n_points; j++)
         {
           gdouble x, y;
 
           gimp_curve_get_point (curve, j, &x, &y);
 
-          fprintf (file, "%d %d ",
-                   (gint) (x * 255.999),
-                   (gint) (y * 255.999));
+          if (x < 0.0 || y < 0.0)
+            {
+              fprintf (file, "%d %d ", -1, -1);
+            }
+          else
+            {
+              fprintf (file, "%d %d ",
+                       (gint) (x * 255.999),
+                       (gint) (y * 255.999));
+            }
         }
 
       fprintf (file, "\n");
@@ -451,12 +472,14 @@
        channel++)
     {
       gimp_curve_get_uchar (config->curve[channel],
+                            sizeof (cruft->curve[channel]),
                             cruft->curve[channel]);
     }
 
   if (! is_color)
     {
       gimp_curve_get_uchar (config->curve[GIMP_HISTOGRAM_ALPHA],
+                            sizeof (cruft->curve[1]),
                             cruft->curve[1]);
     }
 }

Modified: branches/weskaggs/app/gui/gui-vtable.c
==============================================================================
--- branches/weskaggs/app/gui/gui-vtable.c	(original)
+++ branches/weskaggs/app/gui/gui-vtable.c	Tue Mar  4 03:15:17 2008
@@ -290,6 +290,8 @@
 
   image_managers = gimp_ui_managers_from_name ("<Image>");
 
+  g_return_val_if_fail (image_managers != NULL, NULL);
+
   display = gimp_display_new (image, unit, scale,
                               global_menu_factory,
                               image_managers->data);

Modified: branches/weskaggs/app/gui/gui.c
==============================================================================
--- branches/weskaggs/app/gui/gui.c	(original)
+++ branches/weskaggs/app/gui/gui.c	Tue Mar  4 03:15:17 2008
@@ -333,7 +333,7 @@
   g_return_if_fail (GIMP_IS_GIMP (gimp));
 
   if (gimp->be_verbose)
-    g_print ("INIT: gui_initialize_after_callback\n");
+    g_print ("INIT: %s\n", G_STRFUNC);
 
 #if defined (GDK_WINDOWING_X11)
   name = "DISPLAY";
@@ -367,7 +367,7 @@
   GimpGuiConfig     *gui_config     = GIMP_GUI_CONFIG (gimp->config);
 
   if (gimp->be_verbose)
-    g_print ("INIT: gui_restore_callback\n");
+    g_print ("INIT: %s\n", G_STRFUNC);
 
   gui_vtable_init (gimp);
 
@@ -442,7 +442,7 @@
   GimpGuiConfig *gui_config = GIMP_GUI_CONFIG (gimp->config);
 
   if (gimp->be_verbose)
-    g_print ("INIT: gui_restore_after_callback\n");
+    g_print ("INIT: %s\n", G_STRFUNC);
 
   gimp->message_handler = GIMP_MESSAGE_BOX;
 
@@ -535,7 +535,7 @@
   GimpGuiConfig  *gui_config = GIMP_GUI_CONFIG (gimp->config);
 
   if (gimp->be_verbose)
-    g_print ("EXIT: gui_exit_callback\n");
+    g_print ("EXIT: %s\n", G_STRFUNC);
 
   if (! force && gimp_displays_dirty (gimp))
     {
@@ -586,7 +586,7 @@
                          gboolean  force)
 {
   if (gimp->be_verbose)
-    g_print ("EXIT: gui_exit_after_callback\n");
+    g_print ("EXIT: %s\n", G_STRFUNC);
 
   g_signal_handlers_disconnect_by_func (gimp->config,
                                         gui_show_help_button_notify,

Modified: branches/weskaggs/app/gui/ige-mac-menu.c
==============================================================================
--- branches/weskaggs/app/gui/ige-mac-menu.c	(original)
+++ branches/weskaggs/app/gui/ige-mac-menu.c	Tue Mar  4 03:15:17 2008
@@ -1,14 +1,15 @@
 /* GTK+ Integration for the Mac OS X Menubar.
  *
  * Copyright (C) 2007 Pioneer Research Center USA, Inc.
+ * Copyright (C) 2007 Imendio AB
  *
  * For further information, see:
  * http://developer.imendio.com/projects/gtk-macosx/menubar
  *
  * This library is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2 of the License, or (at your option) any later version.
+ * License as published by the Free Software Foundation; version 2.1
+ * of the License.
  *
  * This library is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
@@ -28,15 +29,14 @@
 #ifdef GDK_WINDOWING_QUARTZ
 
 #include <gdk/gdkkeysyms.h>
-
 #include <Carbon/Carbon.h>
 
 #include "ige-mac-menu.h"
 
-
 /* TODO
  *
- * - Sync adding/removing/reordering items
+ * - Adding a standard Window menu (Minimize etc)?
+ * - Sync reordering items? Does that work now?
  * - Create on demand? (can this be done with gtk+? ie fill in menu
      items when the menu is opened)
  * - Figure out what to do per app/window...
@@ -117,6 +117,7 @@
 typedef struct
 {
   MenuRef menu;
+  guint   toplevel : 1;
 } CarbonMenu;
 
 static GQuark carbon_menu_quark = 0;
@@ -141,7 +142,8 @@
 
 static void
 carbon_menu_connect (GtkWidget *menu,
-		     MenuRef    menuRef)
+		     MenuRef    menuRef,
+                     gboolean   toplevel)
 {
   CarbonMenu *carbon_menu = carbon_menu_get (menu);
 
@@ -154,7 +156,8 @@
 			       (GDestroyNotify) carbon_menu_free);
     }
 
-  carbon_menu->menu = menuRef;
+  carbon_menu->menu     = menuRef;
+  carbon_menu->toplevel = toplevel;
 }
 
 
@@ -578,6 +581,8 @@
 static void
 setup_menu_event_handler (void)
 {
+  static gboolean is_setup = FALSE;
+
   EventHandlerUPP menu_event_handler_upp;
   EventHandlerRef menu_event_handler_ref;
   const EventTypeSpec menu_events[] = {
@@ -587,6 +592,9 @@
     { kEventClassMenu, kEventMenuClosed }
   };
 
+  if (is_setup)
+    return;
+
   /* FIXME: We might have to install one per window? */
 
   menu_event_handler_upp = NewEventHandlerUPP (menu_event_handler_func);
@@ -599,6 +607,8 @@
   RemoveEventHandler(menu_event_handler_ref);
   DisposeEventHandlerUPP(menu_event_handler_upp);
 #endif
+
+  is_setup = TRUE;
 }
 
 static void
@@ -614,7 +624,7 @@
   if (debug)
     g_printerr ("%s: syncing shell %p\n", G_STRFUNC, menu_shell);
 
-  carbon_menu_connect (GTK_WIDGET (menu_shell), carbon_menu);
+  carbon_menu_connect (GTK_WIDGET (menu_shell), carbon_menu, toplevel);
 
   children = gtk_container_get_children (GTK_CONTAINER (menu_shell));
 
@@ -701,8 +711,8 @@
   g_list_free (children);
 }
 
-
-static gulong emission_hook_id = 0;
+static gulong emission_hook_id    = 0;
+static gint   emission_hook_count = 0;
 
 static gboolean
 parent_set_emission_hook (GSignalInvocationHint *ihint,
@@ -742,7 +752,7 @@
 
 	      sync_menu_shell (GTK_MENU_SHELL (menu_shell),
 			       carbon_menu->menu,
-			       carbon_menu->menu == (MenuRef) data,
+			       carbon_menu->toplevel,
 			       FALSE);
 	    }
         }
@@ -755,9 +765,15 @@
 parent_set_emission_hook_remove (GtkWidget *widget,
 				 gpointer   data)
 {
+  emission_hook_count--;
+
+  if (emission_hook_count > 0)
+    return;
+
   g_signal_remove_emission_hook (g_signal_lookup ("parent-set",
 						  GTK_TYPE_WIDGET),
 				 emission_hook_id);
+  emission_hook_id = 0;
 }
 
 
@@ -768,8 +784,8 @@
 void
 ige_mac_menu_set_menu_bar (GtkMenuShell *menu_shell)
 {
-  MenuRef carbon_menubar;
-  guint   hook_id;
+  CarbonMenu *current_menu;
+  MenuRef     carbon_menubar;
 
   g_return_if_fail (GTK_IS_MENU_SHELL (menu_shell));
 
@@ -779,17 +795,29 @@
   if (carbon_menu_item_quark == 0)
     carbon_menu_item_quark = g_quark_from_static_string ("CarbonMenuItem");
 
+  current_menu = carbon_menu_get (GTK_WIDGET (menu_shell));
+  if (current_menu)
+    {
+      SetRootMenu (current_menu->menu);
+      return;
+    }
+
   CreateNewMenu (0 /*id*/, 0 /*options*/, &carbon_menubar);
   SetRootMenu (carbon_menubar);
 
   setup_menu_event_handler ();
 
-  emission_hook_id =
-    g_signal_add_emission_hook (g_signal_lookup ("parent-set",
-						 GTK_TYPE_WIDGET),
-				0,
-				parent_set_emission_hook,
-				carbon_menubar, NULL);
+  if (emission_hook_id == 0)
+    {
+      emission_hook_id =
+        g_signal_add_emission_hook (g_signal_lookup ("parent-set",
+                                                     GTK_TYPE_WIDGET),
+                                    0,
+                                    parent_set_emission_hook,
+                                    NULL, NULL);
+    }
+
+  emission_hook_count++;
 
   g_signal_connect (menu_shell, "destroy",
 		    G_CALLBACK (parent_set_emission_hook_remove),
@@ -806,6 +834,8 @@
 
   g_return_if_fail (GTK_IS_MENU_ITEM (menu_item));
 
+  setup_menu_event_handler ();
+
   if (GetIndMenuItemWithCommandID (NULL, kHICommandQuit, 1,
                                    &appmenu, &index) == noErr)
     {
@@ -849,6 +879,8 @@
   g_return_if_fail (group != NULL);
   g_return_if_fail (GTK_IS_MENU_ITEM (menu_item));
 
+  setup_menu_event_handler ();
+
   if (GetIndMenuItemWithCommandID (NULL, kHICommandHide, 1,
                                    &appmenu, NULL) != noErr)
     {

Modified: branches/weskaggs/app/gui/ige-mac-menu.h
==============================================================================
--- branches/weskaggs/app/gui/ige-mac-menu.h	(original)
+++ branches/weskaggs/app/gui/ige-mac-menu.h	Tue Mar  4 03:15:17 2008
@@ -1,14 +1,15 @@
 /* GTK+ Integration for the Mac OS X Menubar.
  *
  * Copyright (C) 2007 Pioneer Research Center USA, Inc.
+ * Copyright (C) 2007 Imendio AB
  *
  * For further information, see:
  * http://developer.imendio.com/projects/gtk-macosx/menubar
  *
  * This library is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2 of the License, or (at your option) any later version.
+ * License as published by the Free Software Foundation; version 2.1
+ * of the License.
  *
  * This library is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of

Modified: branches/weskaggs/app/main.c
==============================================================================
--- branches/weskaggs/app/main.c	(original)
+++ branches/weskaggs/app/main.c	Tue Mar  4 03:15:17 2008
@@ -68,6 +68,7 @@
 #include "errors.h"
 #include "sanity.h"
 #include "units.h"
+#include "version.h"
 
 #ifdef G_OS_WIN32
 #include <windows.h>
@@ -309,6 +310,20 @@
   g_set_prgname (basename);
   g_free (basename);
 
+  /* Check argv[] for "--verbose" first */
+  for (i = 1; i < argc; i++)
+    {
+      const gchar *arg = argv[i];
+
+      if (arg[0] != '-')
+        continue;
+
+      if ((strcmp (arg, "--verbose") == 0) || (strcmp (arg, "-v") == 0))
+        {
+          be_verbose = TRUE;
+        }
+    }
+
   /* Check argv[] for "--no-interface" before trying to initialize gtk+. */
   for (i = 1; i < argc; i++)
     {
@@ -323,7 +338,6 @@
         }
       else if ((strcmp (arg, "--version") == 0) || (strcmp (arg, "-v") == 0))
         {
-          gimp_open_console_window ();
           gimp_show_version_and_exit ();
         }
 #if defined (G_OS_WIN32) && !defined (GIMP_CONSOLE_COMPILATION)
@@ -553,17 +567,10 @@
 }
 
 static void
-gimp_show_version (void)
-{
-  gimp_open_console_window ();
-  g_print (_("%s version %s"), GIMP_NAME, GIMP_VERSION);
-  g_print ("\n");
-}
-
-static void
 gimp_show_version_and_exit (void)
 {
-  gimp_show_version ();
+  gimp_open_console_window ();
+  gimp_version_show (be_verbose);
 
   app_exit (EXIT_SUCCESS);
 }
@@ -571,7 +578,8 @@
 static void
 gimp_show_license_and_exit (void)
 {
-  gimp_show_version ();
+  gimp_open_console_window ();
+  gimp_version_show (be_verbose);
 
   g_print ("\n");
   g_print (GIMP_LICENSE);

Modified: branches/weskaggs/app/pdb/brushes_cmds.c
==============================================================================
--- branches/weskaggs/app/pdb/brushes_cmds.c	(original)
+++ branches/weskaggs/app/pdb/brushes_cmds.c	Tue Mar  4 03:15:17 2008
@@ -49,6 +49,7 @@
                          GError            **error)
 {
   gimp_data_factory_data_refresh (gimp->brush_factory);
+
   return gimp_procedure_get_return_values (procedure, TRUE);
 }
 

Modified: branches/weskaggs/app/pdb/context_cmds.c
==============================================================================
--- branches/weskaggs/app/pdb/context_cmds.c	(original)
+++ branches/weskaggs/app/pdb/context_cmds.c	Tue Mar  4 03:15:17 2008
@@ -248,6 +248,7 @@
                                     GError            **error)
 {
   gimp_context_set_default_colors (context);
+
   return gimp_procedure_get_return_values (procedure, TRUE);
 }
 
@@ -260,6 +261,7 @@
                              GError            **error)
 {
   gimp_context_swap_colors (context);
+
   return gimp_procedure_get_return_values (procedure, TRUE);
 }
 

Modified: branches/weskaggs/app/pdb/display_cmds.c
==============================================================================
--- branches/weskaggs/app/pdb/display_cmds.c	(original)
+++ branches/weskaggs/app/pdb/display_cmds.c	Tue Mar  4 03:15:17 2008
@@ -84,7 +84,9 @@
             g_object_unref (image);
         }
       else
-        success = FALSE;
+        {
+          success = FALSE;
+        }
     }
 
   return_vals = gimp_procedure_get_return_values (procedure, success);
@@ -153,6 +155,7 @@
                         GError            **error)
 {
   gimp_container_foreach (gimp->images, (GFunc) gimp_image_flush, NULL);
+
   return gimp_procedure_get_return_values (procedure, TRUE);
 }
 

Modified: branches/weskaggs/app/pdb/fonts_cmds.c
==============================================================================
--- branches/weskaggs/app/pdb/fonts_cmds.c	(original)
+++ branches/weskaggs/app/pdb/fonts_cmds.c	Tue Mar  4 03:15:17 2008
@@ -44,6 +44,7 @@
                        GError            **error)
 {
   gimp_fonts_load (gimp);
+
   return gimp_procedure_get_return_values (procedure, TRUE);
 }
 

Modified: branches/weskaggs/app/pdb/gradients_cmds.c
==============================================================================
--- branches/weskaggs/app/pdb/gradients_cmds.c	(original)
+++ branches/weskaggs/app/pdb/gradients_cmds.c	Tue Mar  4 03:15:17 2008
@@ -48,6 +48,7 @@
                            GError            **error)
 {
   gimp_data_factory_data_refresh (gimp->gradient_factory);
+
   return gimp_procedure_get_return_values (procedure, TRUE);
 }
 

Modified: branches/weskaggs/app/pdb/palettes_cmds.c
==============================================================================
--- branches/weskaggs/app/pdb/palettes_cmds.c	(original)
+++ branches/weskaggs/app/pdb/palettes_cmds.c	Tue Mar  4 03:15:17 2008
@@ -50,6 +50,7 @@
                           GError            **error)
 {
   gimp_data_factory_data_refresh (gimp->palette_factory);
+
   return gimp_procedure_get_return_values (procedure, TRUE);
 }
 

Modified: branches/weskaggs/app/pdb/patterns_cmds.c
==============================================================================
--- branches/weskaggs/app/pdb/patterns_cmds.c	(original)
+++ branches/weskaggs/app/pdb/patterns_cmds.c	Tue Mar  4 03:15:17 2008
@@ -49,6 +49,7 @@
                           GError            **error)
 {
   gimp_data_factory_data_refresh (gimp->pattern_factory);
+
   return gimp_procedure_get_return_values (procedure, TRUE);
 }
 

Modified: branches/weskaggs/app/tools/gimpcurvestool.c
==============================================================================
--- branches/weskaggs/app/tools/gimpcurvestool.c	(original)
+++ branches/weskaggs/app/tools/gimpcurvestool.c	Tue Mar  4 03:15:17 2008
@@ -637,7 +637,7 @@
         case GIMP_HISTOGRAM_VALUE:
         case GIMP_HISTOGRAM_ALPHA:
         case GIMP_HISTOGRAM_RGB:
-          gimp_curve_get_uchar (curve, r);
+          gimp_curve_get_uchar (curve, sizeof (r), r);
 
           gimp_color_bar_set_buffers (GIMP_COLOR_BAR (tool->xrange),
                                       r, r, r);
@@ -646,9 +646,12 @@
         case GIMP_HISTOGRAM_RED:
         case GIMP_HISTOGRAM_GREEN:
         case GIMP_HISTOGRAM_BLUE:
-          gimp_curve_get_uchar (config->curve[GIMP_HISTOGRAM_RED],   r);
-          gimp_curve_get_uchar (config->curve[GIMP_HISTOGRAM_GREEN], g);
-          gimp_curve_get_uchar (config->curve[GIMP_HISTOGRAM_BLUE],  b);
+          gimp_curve_get_uchar (config->curve[GIMP_HISTOGRAM_RED],
+                                sizeof (r), r);
+          gimp_curve_get_uchar (config->curve[GIMP_HISTOGRAM_GREEN],
+                                sizeof (g), g);
+          gimp_curve_get_uchar (config->curve[GIMP_HISTOGRAM_BLUE],
+                                sizeof (b), b);
 
           gimp_color_bar_set_buffers (GIMP_COLOR_BAR (tool->xrange),
                                       r, g, b);

Modified: branches/weskaggs/app/tools/gimpdrawtool.c
==============================================================================
--- branches/weskaggs/app/tools/gimpdrawtool.c	(original)
+++ branches/weskaggs/app/tools/gimpdrawtool.c	Tue Mar  4 03:15:17 2008
@@ -1592,18 +1592,18 @@
 }
 
 void
-gimp_draw_tool_draw_lines (GimpDrawTool  *draw_tool,
-                           const gdouble *points,
-                           gint           n_points,
-                           gboolean       filled,
-                           gboolean       use_offsets)
+gimp_draw_tool_draw_lines (GimpDrawTool      *draw_tool,
+                           const GimpVector2 *points,
+                           gint               n_points,
+                           gboolean           filled,
+                           gboolean           use_offsets)
 {
   GimpDisplayShell *shell;
   GdkPoint         *coords;
 
   g_return_if_fail (GIMP_IS_DRAW_TOOL (draw_tool));
 
-  if (n_points == 0)
+  if (points == NULL || n_points == 0)
     return;
 
   shell = GIMP_DISPLAY_SHELL (draw_tool->display->shell);

Modified: branches/weskaggs/app/tools/gimpdrawtool.h
==============================================================================
--- branches/weskaggs/app/tools/gimpdrawtool.h	(original)
+++ branches/weskaggs/app/tools/gimpdrawtool.h	Tue Mar  4 03:15:17 2008
@@ -226,7 +226,7 @@
                                                     GimpVectors     **ret_vectors);
 
 void       gimp_draw_tool_draw_lines               (GimpDrawTool     *draw_tool,
-                                                    const gdouble    *points,
+                                                    const GimpVector2 *points,
                                                     gint              n_points,
                                                     gboolean          filled,
                                                     gboolean          use_offsets);

Modified: branches/weskaggs/app/tools/gimpforegroundselecttool.c
==============================================================================
--- branches/weskaggs/app/tools/gimpforegroundselecttool.c	(original)
+++ branches/weskaggs/app/tools/gimpforegroundselecttool.c	Tue Mar  4 03:15:17 2008
@@ -398,8 +398,9 @@
 
   switch (kevent->keyval)
     {
-    case GDK_KP_Enter:
     case GDK_Return:
+    case GDK_KP_Enter:
+    case GDK_ISO_Enter:
       gimp_foreground_select_tool_apply (fg_select, display);
       return TRUE;
 

Modified: branches/weskaggs/app/tools/gimpfreeselecttool.c
==============================================================================
--- branches/weskaggs/app/tools/gimpfreeselecttool.c	(original)
+++ branches/weskaggs/app/tools/gimpfreeselecttool.c	Tue Mar  4 03:15:17 2008
@@ -281,8 +281,7 @@
   GimpFreeSelectTool *free_sel = GIMP_FREE_SELECT_TOOL (draw_tool);
 
   gimp_draw_tool_draw_lines (draw_tool,
-                             (const gdouble *) free_sel->points,
-                             free_sel->num_points,
+                             free_sel->points, free_sel->num_points,
                              FALSE, FALSE);
 }
 

Modified: branches/weskaggs/app/tools/gimpgegltool.c
==============================================================================
--- branches/weskaggs/app/tools/gimpgegltool.c	(original)
+++ branches/weskaggs/app/tools/gimpgegltool.c	Tue Mar  4 03:15:17 2008
@@ -278,10 +278,18 @@
   gtk_label_set_mnemonic_widget (GTK_LABEL (label), combo);
 
   /*  The options vbox  */
-  tool->options_box = gtk_vbox_new (FALSE, 6);
-  gtk_box_pack_start (GTK_BOX (image_map_tool->main_vbox), tool->options_box,
+  tool->options_frame = gimp_frame_new (_("Operation Settings"));
+  gtk_box_pack_start (GTK_BOX (image_map_tool->main_vbox), tool->options_frame,
                       FALSE, FALSE, 0);
-  gtk_widget_show (tool->options_box);
+  gtk_widget_show (tool->options_frame);
+
+  tool->options_table = gtk_label_new ("Select an operation from the list above");
+  gimp_label_set_attributes (GTK_LABEL (tool->options_table),
+                             PANGO_ATTR_STYLE, PANGO_STYLE_ITALIC,
+                             -1);
+  gtk_misc_set_padding (GTK_MISC (tool->options_table), 0, 4);
+  gtk_container_add (GTK_CONTAINER (tool->options_frame), tool->options_table);
+  gtk_widget_show (tool->options_table);
 }
 
 static void
@@ -450,11 +458,21 @@
   return NULL;
 }
 
+static GValue *
+gimp_gegl_tool_config_value_new (GParamSpec *pspec)
+{
+  GValue *value = g_slice_new0 (GValue);
+
+  g_value_init (value, pspec->value_type);
+
+  return value;
+}
+
 static void
 gimp_gegl_tool_config_value_free (GValue *value)
 {
   g_value_unset (value);
-  g_free (value);
+  g_slice_free (GValue, value);
 }
 
 static GHashTable *
@@ -476,25 +494,32 @@
   return properties;
 }
 
-static void
-gimp_gegl_tool_config_set_property (GObject      *object,
-                                    guint         property_id,
-                                    const GValue *value,
-                                    GParamSpec   *pspec)
+static GValue *
+gimp_gegl_tool_config_value_get (GObject    *object,
+                                 GParamSpec *pspec)
 {
   GHashTable *properties = gimp_gegl_tool_config_get_properties (object);
-  GValue     *val;
+  GValue     *value;
 
-  val = g_hash_table_lookup (properties, pspec->name);
+  value = g_hash_table_lookup (properties, pspec->name);
 
-  if (! val)
+  if (! value)
     {
-      val = g_new0 (GValue, 1);
-      g_hash_table_insert (properties, g_strdup (pspec->name), val);
-
-      g_value_init (val, pspec->value_type);
+      value = gimp_gegl_tool_config_value_new (pspec);
+      g_hash_table_insert (properties, g_strdup (pspec->name), value);
     }
 
+  return value;
+}
+
+static void
+gimp_gegl_tool_config_set_property (GObject      *object,
+                                    guint         property_id,
+                                    const GValue *value,
+                                    GParamSpec   *pspec)
+{
+  GValue *val = gimp_gegl_tool_config_value_get (object, pspec);
+
   g_value_copy (value, val);
 }
 
@@ -504,19 +529,7 @@
                                     GValue     *value,
                                     GParamSpec *pspec)
 {
-  GHashTable *properties = gimp_gegl_tool_config_get_properties (object);
-  GValue     *val;
-
-  val = g_hash_table_lookup (properties, pspec->name);
-
-  if (! val)
-    {
-      val = g_new0 (GValue, 1);
-      g_hash_table_insert (properties, g_strdup (pspec->name), val);
-
-      g_value_init (val, pspec->value_type);
-      g_param_value_set_default (pspec, val);
-    }
+  GValue *val = gimp_gegl_tool_config_value_get (object, pspec);
 
   g_value_copy (val, value);
 }
@@ -660,7 +673,7 @@
 
   if (tool->options_table)
     {
-      gtk_container_remove (GTK_CONTAINER (tool->options_box),
+      gtk_container_remove (GTK_CONTAINER (tool->options_frame),
                             tool->options_table);
       tool->options_table = NULL;
     }
@@ -675,8 +688,8 @@
         gimp_prop_table_new (G_OBJECT (tool->config),
                              G_TYPE_FROM_INSTANCE (tool->config),
                              GIMP_CONTEXT (GIMP_TOOL_GET_OPTIONS (tool)));
-      gtk_box_pack_start (GTK_BOX (tool->options_box), tool->options_table,
-                          FALSE, FALSE, 0);
+      gtk_container_add (GTK_CONTAINER (tool->options_frame),
+                         tool->options_table);
       gtk_widget_show (tool->options_table);
     }
 

Modified: branches/weskaggs/app/tools/gimpgegltool.h
==============================================================================
--- branches/weskaggs/app/tools/gimpgegltool.h	(original)
+++ branches/weskaggs/app/tools/gimpgegltool.h	Tue Mar  4 03:15:17 2008
@@ -43,7 +43,7 @@
 
   /* dialog */
   GtkWidget        *operation_combo;
-  GtkWidget        *options_box;
+  GtkWidget        *options_frame;
   GtkWidget        *options_table;
 };
 

Modified: branches/weskaggs/app/tools/gimpimagemaptool.c
==============================================================================
--- branches/weskaggs/app/tools/gimpimagemaptool.c	(original)
+++ branches/weskaggs/app/tools/gimpimagemaptool.c	Tue Mar  4 03:15:17 2008
@@ -289,9 +289,6 @@
       GimpImageMapToolClass *klass;
       GtkWidget             *shell;
       GtkWidget             *vbox;
-      GtkWidget             *hbox;
-      GtkWidget             *label;
-      GtkWidget             *combo;
       GtkWidget             *toggle;
       const gchar           *stock_id;
 
@@ -324,26 +321,34 @@
       gtk_container_set_border_width (GTK_CONTAINER (vbox), 6);
       gtk_container_add (GTK_CONTAINER (GTK_DIALOG (shell)->vbox), vbox);
 
-      hbox = gtk_hbox_new (FALSE, 4);
-      gtk_box_pack_start (GTK_BOX (image_map_tool->main_vbox), hbox,
-                          FALSE, FALSE, 0);
-      gtk_widget_show (hbox);
-
-      label = gtk_label_new (_("Recent Settings:"));
-      gtk_box_pack_start (GTK_BOX (hbox), label, FALSE, FALSE, 0);
-      gtk_widget_show (label);
-
-      combo = gimp_container_combo_box_new (klass->recent_settings,
-                                            GIMP_CONTEXT (tool_info->tool_options),
-                                            16, 0);
-      gtk_box_pack_start (GTK_BOX (hbox), combo, TRUE, TRUE, 0);
-      gtk_widget_show (combo);
-
-      gimp_help_set_help_data (combo, _("Pick a setting from the list"), NULL);
-
-      g_signal_connect_after (combo, "select-item",
-                              G_CALLBACK (gimp_image_map_tool_recent_selected),
-                              image_map_tool);
+      if (image_map_tool->config)
+        {
+          GtkWidget *hbox;
+          GtkWidget *label;
+          GtkWidget *combo;
+
+          hbox = gtk_hbox_new (FALSE, 4);
+          gtk_box_pack_start (GTK_BOX (image_map_tool->main_vbox), hbox,
+                              FALSE, FALSE, 0);
+          gtk_widget_show (hbox);
+
+          label = gtk_label_new (_("Recent Settings:"));
+          gtk_box_pack_start (GTK_BOX (hbox), label, FALSE, FALSE, 0);
+          gtk_widget_show (label);
+
+          combo = gimp_container_combo_box_new (klass->recent_settings,
+                                                GIMP_CONTEXT (tool_info->tool_options),
+                                                16, 0);
+          gtk_box_pack_start (GTK_BOX (hbox), combo, TRUE, TRUE, 0);
+          gtk_widget_show (combo);
+
+          gimp_help_set_help_data (combo, _("Pick a setting from the list"),
+                                   NULL);
+
+          g_signal_connect_after (combo, "select-item",
+                                  G_CALLBACK (gimp_image_map_tool_recent_selected),
+                                  image_map_tool);
+        }
 
       /*  The preview toggle  */
       toggle = gimp_prop_check_button_new (G_OBJECT (tool_info->tool_options),
@@ -476,8 +481,9 @@
     {
       switch (kevent->keyval)
         {
-        case GDK_KP_Enter:
         case GDK_Return:
+        case GDK_KP_Enter:
+        case GDK_ISO_Enter:
           gimp_image_map_tool_response (NULL, GTK_RESPONSE_OK, image_map_tool);
           return TRUE;
 

Modified: branches/weskaggs/app/tools/gimpiscissorstool.c
==============================================================================
--- branches/weskaggs/app/tools/gimpiscissorstool.c	(original)
+++ branches/weskaggs/app/tools/gimpiscissorstool.c	Tue Mar  4 03:15:17 2008
@@ -882,23 +882,23 @@
 iscissors_draw_curve (GimpDrawTool *draw_tool,
                       ICurve       *curve)
 {
-  gdouble  *points;
-  gpointer *point;
-  gint      i, len;
+  GimpVector2 *points;
+  gpointer    *point;
+  gint         i, len;
 
   if (! curve->points)
     return;
 
   len = curve->points->len;
 
-  points = g_new (gdouble, 2 * len);
+  points = g_new (GimpVector2, len);
 
   for (i = 0, point = curve->points->pdata; i < len; i++, point++)
     {
       guint32 coords = GPOINTER_TO_INT (*point);
 
-      points[i * 2]     = (coords & 0x0000ffff);
-      points[i * 2 + 1] = (coords >> 16);
+      points[i].x = (coords & 0x0000ffff);
+      points[i].y = (coords >> 16);
     }
 
   gimp_draw_tool_draw_lines (draw_tool, points, len, FALSE, FALSE);
@@ -1060,8 +1060,9 @@
 
   switch (kevent->keyval)
     {
-    case GDK_KP_Enter:
     case GDK_Return:
+    case GDK_KP_Enter:
+    case GDK_ISO_Enter:
       if (iscissors->connected && iscissors->mask)
         {
           gimp_iscissors_tool_apply (iscissors, display);

Modified: branches/weskaggs/app/tools/gimppolygonselecttool.c
==============================================================================
--- branches/weskaggs/app/tools/gimppolygonselecttool.c	(original)
+++ branches/weskaggs/app/tools/gimppolygonselecttool.c	Tue Mar  4 03:15:17 2008
@@ -49,7 +49,8 @@
 
 #define DEFAULT_MAX_INC         1024
 
-#define POINT_GRAB_THRESHOLD_SQ 100
+#define HANDLE_SIZE             10
+#define POINT_GRAB_THRESHOLD_SQ SQR(HANDLE_SIZE / 2)
 
 
 struct _GimpPolygonSelectTool
@@ -74,13 +75,14 @@
   GimpVector2       *points;
 
   /* The number of points used for the actual selection. */
-  gint               num_points;
+  gint               n_points;
 
   gint               max_segs;
 };
 
 
 static void         gimp_polygon_select_tool_finalize       (GObject               *object);
+
 static void         gimp_polygon_select_tool_control        (GimpTool              *tool,
                                                              GimpToolAction         action,
                                                              GimpDisplay           *display);
@@ -89,6 +91,10 @@
                                                              GdkModifierType        state,
                                                              gboolean               proximity,
                                                              GimpDisplay           *display);
+static void         gimp_polygon_select_tool_cursor_update  (GimpTool              *tool,
+                                                             GimpCoords            *coords,
+                                                             GdkModifierType        state,
+                                                             GimpDisplay           *display);
 static void         gimp_polygon_select_tool_button_press   (GimpTool              *tool,
                                                              GimpCoords            *coords,
                                                              guint32                time,
@@ -124,7 +130,7 @@
                                                              gdouble                x,
                                                              gdouble                y);
 static void         gimp_polygon_select_tool_remove_last    (GimpPolygonSelectTool *poly_sel_tool);
-static void         gimp_polygon_select_tool_select_closet_point
+static void         gimp_polygon_select_tool_select_closest_point
                                                             (GimpPolygonSelectTool *poly_sel_tool,
                                                              GimpDisplay           *display,
                                                              GimpCoords            *coords);
@@ -136,7 +142,6 @@
 G_DEFINE_TYPE (GimpPolygonSelectTool, gimp_polygon_select_tool,
                GIMP_TYPE_SELECTION_TOOL);
 
-
 #define parent_class gimp_polygon_select_tool_parent_class
 
 
@@ -168,6 +173,7 @@
 
   tool_class->control        = gimp_polygon_select_tool_control;
   tool_class->oper_update    = gimp_polygon_select_tool_oper_update;
+  tool_class->cursor_update  = gimp_polygon_select_tool_cursor_update;
   tool_class->button_press   = gimp_polygon_select_tool_button_press;
   tool_class->motion         = gimp_polygon_select_tool_motion;
   tool_class->button_release = gimp_polygon_select_tool_button_release;
@@ -186,9 +192,10 @@
   gimp_tool_control_set_scroll_lock (tool->control, FALSE);
   gimp_tool_control_set_wants_click (tool->control, TRUE);
   gimp_tool_control_set_tool_cursor (tool->control,
-                                     GIMP_TOOL_CURSOR_FREE_SELECT);
+                                     GIMP_TOOL_CURSOR_POLYGON_SELECT);
 
   poly_sel_tool->points   = NULL;
+  poly_sel_tool->n_points = 0;
   poly_sel_tool->max_segs = 0;
 }
 
@@ -238,9 +245,9 @@
     {
       gboolean hovering_first_point;
 
-      gimp_polygon_select_tool_select_closet_point (poly_sel_tool,
-                                                    display,
-                                                    coords);
+      gimp_polygon_select_tool_select_closest_point (poly_sel_tool,
+                                                     display,
+                                                     coords);
 
       hovering_first_point = gimp_polygon_select_tool_should_close (poly_sel_tool,
                                                                     display,
@@ -248,8 +255,8 @@
 
       gimp_draw_tool_pause (GIMP_DRAW_TOOL (tool));
 
-      if (poly_sel_tool->num_points == 0 ||
-          (poly_sel_tool->grabbed_point && !hovering_first_point))
+      if (poly_sel_tool->n_points == 0 ||
+          (poly_sel_tool->grabbed_point && ! hovering_first_point))
         {
           poly_sel_tool->show_pending_point = FALSE;
         }
@@ -273,6 +280,28 @@
 }
 
 static void
+gimp_polygon_select_tool_cursor_update (GimpTool        *tool,
+                                        GimpCoords      *coords,
+                                        GdkModifierType  state,
+                                        GimpDisplay     *display)
+{
+  GimpPolygonSelectTool *poly_sel_tool = GIMP_POLYGON_SELECT_TOOL (tool);
+
+  if (poly_sel_tool->grabbed_point &&
+      ! gimp_polygon_select_tool_should_close (poly_sel_tool, display, coords))
+    {
+      gimp_tool_set_cursor (tool, display,
+                            gimp_tool_control_get_cursor (tool->control),
+                            gimp_tool_control_get_tool_cursor (tool->control),
+                            GIMP_CURSOR_MODIFIER_MOVE);
+
+      return;
+    }
+
+  GIMP_TOOL_CLASS (parent_class)->cursor_update (tool, coords, state, display);
+}
+
+static void
 gimp_polygon_select_tool_button_press (GimpTool        *tool,
                                        GimpCoords      *coords,
                                        guint32          time,
@@ -342,6 +371,8 @@
 {
   GimpPolygonSelectTool *poly_sel_tool = GIMP_POLYGON_SELECT_TOOL (tool);
 
+  gimp_draw_tool_pause (GIMP_DRAW_TOOL (poly_sel_tool));
+
   switch (release_type)
     {
     case GIMP_BUTTON_RELEASE_CLICK:
@@ -349,8 +380,7 @@
                                                  display,
                                                  coords))
         {
-          gimp_polygon_select_tool_commit (poly_sel_tool,
-                                           display);
+          gimp_polygon_select_tool_commit (poly_sel_tool, display);
           break;
         }
 
@@ -359,7 +389,8 @@
     case GIMP_BUTTON_RELEASE_NORMAL:
       if (! poly_sel_tool->grabbed_point)
         {
-          gimp_polygon_select_tool_add_point (poly_sel_tool, coords->x, coords->y);
+          gimp_polygon_select_tool_add_point (poly_sel_tool,
+                                              coords->x, coords->y);
         }
       else
         {
@@ -370,16 +401,10 @@
       break;
 
     case GIMP_BUTTON_RELEASE_CANCEL:
-      {
-        gimp_draw_tool_pause (GIMP_DRAW_TOOL (poly_sel_tool));
-
-        if (poly_sel_tool->grabbed_point)
-          {
-            *poly_sel_tool->grabbed_point = poly_sel_tool->saved_grabbed_point;
-          }
-
-        gimp_draw_tool_resume (GIMP_DRAW_TOOL (poly_sel_tool));
-      }
+      if (poly_sel_tool->grabbed_point)
+        {
+          *poly_sel_tool->grabbed_point = poly_sel_tool->saved_grabbed_point;
+        }
       break;
 
     case GIMP_BUTTON_RELEASE_NO_MOTION:
@@ -395,6 +420,8 @@
         }
       break;
     }
+
+  gimp_draw_tool_resume (GIMP_DRAW_TOOL (poly_sel_tool));
 }
 
 static gboolean
@@ -403,32 +430,28 @@
                                     GimpDisplay *display)
 {
   GimpPolygonSelectTool *poly_sel_tool = GIMP_POLYGON_SELECT_TOOL (tool);
-  gboolean            handled_key   = FALSE;
 
   switch (kevent->keyval)
     {
     case GDK_BackSpace:
       gimp_polygon_select_tool_remove_last (poly_sel_tool);
-      handled_key = TRUE;
-      break;
+      return TRUE;
 
-    case GDK_KP_Enter:
     case GDK_Return:
+    case GDK_KP_Enter:
+    case GDK_ISO_Enter:
       gimp_polygon_select_tool_commit (poly_sel_tool, display);
-      handled_key = TRUE;
-      break;
+      return TRUE;
 
     case GDK_Escape:
       gimp_polygon_select_tool_halt (poly_sel_tool);
-      handled_key = TRUE;
-      break;
+      return TRUE;
 
     default:
-      handled_key = FALSE;
       break;
     }
 
-  return handled_key;
+  return FALSE;
 }
 
 static void
@@ -444,7 +467,7 @@
 
   tool->display = display;
 
-  poly_sel_tool->num_points         = 0;
+  poly_sel_tool->n_points           = 0;
   poly_sel_tool->grabbed_point      = NULL;
   poly_sel_tool->show_pending_point = FALSE;
 
@@ -455,7 +478,7 @@
 gimp_polygon_select_tool_commit (GimpPolygonSelectTool *poly_sel_tool,
                                  GimpDisplay           *display)
 {
-  if (poly_sel_tool->num_points >= 3)
+  if (poly_sel_tool->n_points >= 3)
     {
       gimp_polygon_select_tool_select (poly_sel_tool, display);
     }
@@ -479,9 +502,9 @@
 
   poly_sel_tool->grabbed_point      = NULL;
   poly_sel_tool->show_pending_point = FALSE;
-  poly_sel_tool->num_points         = 0;
+  poly_sel_tool->n_points           = 0;
 
-  tool->display            = NULL;
+  tool->display = NULL;
 }
 
 static void
@@ -490,15 +513,25 @@
   GimpPolygonSelectTool *poly_sel_tool = GIMP_POLYGON_SELECT_TOOL (draw_tool);
 
   gimp_draw_tool_draw_lines (draw_tool,
-                             (const gdouble *) poly_sel_tool->points,
-                             poly_sel_tool->num_points,
+                             poly_sel_tool->points, poly_sel_tool->n_points,
                              FALSE, FALSE);
 
+  if (poly_sel_tool->grabbed_point)
+    {
+      gimp_draw_tool_draw_handle (draw_tool, GIMP_HANDLE_CIRCLE,
+                                  poly_sel_tool->grabbed_point->x,
+                                  poly_sel_tool->grabbed_point->y,
+                                  HANDLE_SIZE, HANDLE_SIZE,
+                                  GTK_ANCHOR_CENTER, FALSE);
+    }
+
   if (poly_sel_tool->show_pending_point)
     {
+      GimpVector2 last = poly_sel_tool->points[poly_sel_tool->n_points - 1];
+
       gimp_draw_tool_draw_line (draw_tool,
-                                poly_sel_tool->points[poly_sel_tool->num_points - 1].x,
-                                poly_sel_tool->points[poly_sel_tool->num_points - 1].y,
+                                last.x,
+                                last.y,
                                 poly_sel_tool->pending_point.x,
                                 poly_sel_tool->pending_point.y,
                                 FALSE);
@@ -512,10 +545,10 @@
   g_return_if_fail (GIMP_IS_POLYGON_SELECT_TOOL (poly_sel_tool));
   g_return_if_fail (GIMP_IS_DISPLAY (display));
 
-  GIMP_POLYGON_SELECT_TOOL_GET_CLASS (poly_sel_tool)->select (poly_sel_tool, display);
+  GIMP_POLYGON_SELECT_TOOL_GET_CLASS (poly_sel_tool)->select (poly_sel_tool,
+                                                              display);
 }
 
-
 static void
 gimp_polygon_select_tool_real_select (GimpPolygonSelectTool *poly_sel_tool,
                                       GimpDisplay           *display)
@@ -524,7 +557,7 @@
 
   gimp_channel_select_polygon (gimp_image_get_mask (display->image),
                                Q_("command|Polygon Select"),
-                               poly_sel_tool->num_points,
+                               poly_sel_tool->n_points,
                                poly_sel_tool->points,
                                options->operation,
                                options->antialias,
@@ -539,7 +572,7 @@
                                     gdouble                x,
                                     gdouble                y)
 {
-  if (poly_sel_tool->num_points >= poly_sel_tool->max_segs)
+  if (poly_sel_tool->n_points >= poly_sel_tool->max_segs)
     {
       poly_sel_tool->max_segs += DEFAULT_MAX_INC;
 
@@ -547,10 +580,10 @@
                                          sizeof (GimpVector2) * poly_sel_tool->max_segs);
     }
 
-  poly_sel_tool->points[poly_sel_tool->num_points].x = x;
-  poly_sel_tool->points[poly_sel_tool->num_points].y = y;
+  poly_sel_tool->points[poly_sel_tool->n_points].x = x;
+  poly_sel_tool->points[poly_sel_tool->n_points].y = y;
 
-  return &poly_sel_tool->points[poly_sel_tool->num_points++];
+  return &poly_sel_tool->points[poly_sel_tool->n_points++];
 }
 
 static void
@@ -560,9 +593,9 @@
 
   gimp_draw_tool_pause (draw_tool);
 
-  poly_sel_tool->num_points--;
+  poly_sel_tool->n_points--;
 
-  if (poly_sel_tool->num_points == 0)
+  if (poly_sel_tool->n_points == 0)
     {
       gimp_polygon_select_tool_halt (poly_sel_tool);
     }
@@ -571,32 +604,40 @@
 }
 
 static void
-gimp_polygon_select_tool_select_closet_point (GimpPolygonSelectTool *poly_sel_tool,
-                                              GimpDisplay           *display,
-                                              GimpCoords            *coords)
-{
-  GimpDrawTool *draw_tool        = GIMP_DRAW_TOOL (poly_sel_tool);
-  gdouble       shortest_dist_sq;
+gimp_polygon_select_tool_select_closest_point (GimpPolygonSelectTool *poly_sel_tool,
+                                               GimpDisplay           *display,
+                                               GimpCoords            *coords)
+{
+  GimpDrawTool *draw_tool     = GIMP_DRAW_TOOL (poly_sel_tool);
+  gdouble       shortest_dist = POINT_GRAB_THRESHOLD_SQ;
+  GimpVector2  *grabbed_point = NULL;
   int           i;
 
-  poly_sel_tool->grabbed_point = NULL;
-  shortest_dist_sq    = POINT_GRAB_THRESHOLD_SQ;
-
-  for (i = 0; i < poly_sel_tool->num_points; i++)
+  for (i = 0; i < poly_sel_tool->n_points; i++)
     {
-      gdouble dist_sq;
+      gdouble dist;
 
-      dist_sq = gimp_draw_tool_calc_distance_square (draw_tool,
-                                                     display,
-                                                     coords->x,
-                                                     coords->y,
-                                                     poly_sel_tool->points[i].x,
-                                                     poly_sel_tool->points[i].y);
-      if (dist_sq < shortest_dist_sq)
+      dist = gimp_draw_tool_calc_distance_square (draw_tool,
+                                                  display,
+                                                  coords->x,
+                                                  coords->y,
+                                                  poly_sel_tool->points[i].x,
+                                                  poly_sel_tool->points[i].y);
+
+      if (dist < shortest_dist)
         {
-          poly_sel_tool->grabbed_point = &poly_sel_tool->points[i];
+          grabbed_point = &poly_sel_tool->points[i];
         }
     }
+
+  if (grabbed_point != poly_sel_tool->grabbed_point)
+    {
+      gimp_draw_tool_pause(draw_tool);
+
+      poly_sel_tool->grabbed_point = grabbed_point;
+
+      gimp_draw_tool_resume(draw_tool);
+    }
 }
 
 static gboolean
@@ -604,19 +645,20 @@
                                        GimpDisplay           *display,
                                        GimpCoords            *coords)
 {
-  gboolean should_close  = FALSE;
+  gboolean should_close = FALSE;
 
-  if (poly_sel_tool->num_points > 0)
+  if (poly_sel_tool->n_points > 0)
     {
-      gdouble dist_sq;
+      gdouble dist;
 
-      dist_sq = gimp_draw_tool_calc_distance_square (GIMP_DRAW_TOOL (poly_sel_tool),
-                                                     display,
-                                                     coords->x,
-                                                     coords->y,
-                                                     poly_sel_tool->points[0].x,
-                                                     poly_sel_tool->points[0].y);
-      should_close = dist_sq < POINT_GRAB_THRESHOLD_SQ;
+      dist = gimp_draw_tool_calc_distance_square (GIMP_DRAW_TOOL (poly_sel_tool),
+                                                  display,
+                                                  coords->x,
+                                                  coords->y,
+                                                  poly_sel_tool->points[0].x,
+                                                  poly_sel_tool->points[0].y);
+
+      should_close = dist < POINT_GRAB_THRESHOLD_SQ;
     }
 
   return should_close;

Modified: branches/weskaggs/app/tools/gimprectangletool.c
==============================================================================
--- branches/weskaggs/app/tools/gimprectangletool.c	(original)
+++ branches/weskaggs/app/tools/gimprectangletool.c	Tue Mar  4 03:15:17 2008
@@ -1350,8 +1350,9 @@
       dy = 1;
       break;
 
-    case GDK_KP_Enter:
     case GDK_Return:
+    case GDK_KP_Enter:
+    case GDK_ISO_Enter:
       if (gimp_rectangle_tool_execute (rect_tool))
         gimp_rectangle_tool_halt (rect_tool);
       return TRUE;

Modified: branches/weskaggs/app/tools/gimptransformtool.c
==============================================================================
--- branches/weskaggs/app/tools/gimptransformtool.c	(original)
+++ branches/weskaggs/app/tools/gimptransformtool.c	Tue Mar  4 03:15:17 2008
@@ -505,8 +505,9 @@
     {
       switch (kevent->keyval)
         {
-        case GDK_KP_Enter:
         case GDK_Return:
+        case GDK_KP_Enter:
+        case GDK_ISO_Enter:
           gimp_transform_tool_response (NULL, GTK_RESPONSE_OK, trans_tool);
           return TRUE;
 

Modified: branches/weskaggs/app/tools/gimpvectortool.c
==============================================================================
--- branches/weskaggs/app/tools/gimpvectortool.c	(original)
+++ branches/weskaggs/app/tools/gimpvectortool.c	Tue Mar  4 03:15:17 2008
@@ -767,8 +767,9 @@
 
   switch (kevent->keyval)
     {
-    case GDK_KP_Enter:
     case GDK_Return:
+    case GDK_KP_Enter:
+    case GDK_ISO_Enter:
       gimp_vector_tool_to_selection_extended (vector_tool, kevent->state);
       break;
 

Modified: branches/weskaggs/app/widgets/gimpcontainerpopup.c
==============================================================================
--- branches/weskaggs/app/widgets/gimpcontainerpopup.c	(original)
+++ branches/weskaggs/app/widgets/gimpcontainerpopup.c	Tue Mar  4 03:15:17 2008
@@ -123,8 +123,12 @@
                                 "confirm", 0);
   gtk_binding_entry_add_signal (binding_set, GDK_KP_Enter, 0,
                                 "confirm", 0);
+  gtk_binding_entry_add_signal (binding_set, GDK_ISO_Enter, 0,
+                                "confirm", 0);
   gtk_binding_entry_add_signal (binding_set, GDK_space, 0,
                                 "confirm", 0);
+  gtk_binding_entry_add_signal (binding_set, GDK_KP_Space, 0,
+                                "confirm", 0);
 }
 
 static void

Modified: branches/weskaggs/app/widgets/gimpcursor.c
==============================================================================
--- branches/weskaggs/app/widgets/gimpcursor.c	(original)
+++ branches/weskaggs/app/widgets/gimpcursor.c	Tue Mar  4 03:15:17 2008
@@ -66,6 +66,8 @@
 #include "cursors/xbm/tool-ellipse-select-mask.xbm"
 #include "cursors/xbm/tool-free-select.xbm"
 #include "cursors/xbm/tool-free-select-mask.xbm"
+#include "cursors/xbm/tool-polygon-select.xbm"
+#include "cursors/xbm/tool-polygon-select-mask.xbm"
 #include "cursors/xbm/tool-fuzzy-select.xbm"
 #include "cursors/xbm/tool-fuzzy-select-mask.xbm"
 #include "cursors/xbm/tool-paths.xbm"
@@ -305,6 +307,12 @@
     tool_free_select, NULL, NULL, NULL
   },
   {
+    tool_polygon_select_bits, tool_polygon_select_mask_bits,
+    tool_polygon_select_width, tool_polygon_select_height,
+    0, 0,
+    tool_polygon_select, NULL, NULL, NULL
+  },
+  {
     tool_fuzzy_select_bits, tool_fuzzy_select_mask_bits,
     tool_fuzzy_select_width, tool_fuzzy_select_height,
     0, 0,

Modified: branches/weskaggs/app/widgets/gimpcurveview.c
==============================================================================
--- branches/weskaggs/app/widgets/gimpcurveview.c	(original)
+++ branches/weskaggs/app/widgets/gimpcurveview.c	Tue Mar  4 03:15:17 2008
@@ -394,7 +394,7 @@
       gdk_cairo_set_source_color (cr, &style->text[GTK_STATE_NORMAL]);
 
       /*  Draw the unselected points  */
-      for (i = 0; i < GIMP_CURVE_NUM_POINTS; i++)
+      for (i = 0; i < view->curve->n_points; i++)
         {
           if (i == view->selected)
             continue;
@@ -481,7 +481,7 @@
       cairo_stroke (cr);
 
       g_snprintf (buf, sizeof (buf), "x:%3d y:%3d",
-                  (gint) (view->cursor_x * 255.999),
+                  (gint) (view->cursor_x         * 255.999),
                   (gint) ((1.0 - view->cursor_y) * 255.999));
       pango_layout_set_text (view->cursor_layout, buf, -1);
 
@@ -567,7 +567,7 @@
         }
 
       view->rightmost = 2.0;
-      for (i = closest_point + 1; i < GIMP_CURVE_NUM_POINTS; i++)
+      for (i = closest_point + 1; i < curve->n_points; i++)
         {
           gdouble point_x;
 
@@ -667,7 +667,9 @@
 
           if (x > view->leftmost && x < view->rightmost)
             {
-              closest_point = ((gint) (x * 255.999) + 8) / 16;
+              gint n_points = gimp_curve_get_n_points (curve);
+
+              closest_point = ROUND (x * (gdouble) (n_points - 1));
 
               gimp_curve_get_point (curve, closest_point, &point_x, NULL);
 
@@ -684,6 +686,7 @@
     case GIMP_CURVE_FREE:
       if (view->grabbed)
         {
+          gint    n_samples = gimp_curve_get_n_samples (curve);
           gdouble x1, x2;
           gdouble y1, y2;
 
@@ -704,14 +707,19 @@
 
           if (x2 != x1)
             {
+              gint from = ROUND (x1 * (gdouble) (n_samples - 1));
+              gint to   = ROUND (x2 * (gdouble) (n_samples - 1));
               gint i;
 
               gimp_data_freeze (GIMP_DATA (curve));
 
-              for (i = (gint) (x1 * 255.999); i <= (gint) (x2 * 255.999); i++)
-                gimp_curve_set_curve (curve,
-                                      (gdouble) i / 255.0,
-                                      1.0 - (y1 + ((y2 - y1) * ((gdouble) i / 255.0 - x1)) / (x2 - x1)));
+              for (i = from; i <= to; i++)
+                {
+                  gdouble xpos = (gdouble) i / (gdouble) (n_samples - 1);
+                  gdouble ypos = (y1 + ((y2 - y1) * (xpos - x1)) / (x2 - x1));
+
+                  gimp_curve_set_curve (curve, xpos, 1.0 - ypos);
+                }
 
               gimp_data_thaw (GIMP_DATA (curve));
             }
@@ -783,7 +791,7 @@
       break;
 
     case GDK_Right:
-      for (i = i + 1; i < GIMP_CURVE_NUM_POINTS && ! retval; i++)
+      for (i = i + 1; i < curve->n_points && ! retval; i++)
         {
           gimp_curve_get_point (curve, i, &x, NULL);
 

Modified: branches/weskaggs/app/widgets/gimppaletteview.c
==============================================================================
--- branches/weskaggs/app/widgets/gimppaletteview.c	(original)
+++ branches/weskaggs/app/widgets/gimppaletteview.c	Tue Mar  4 03:15:17 2008
@@ -266,9 +266,11 @@
   GimpPaletteView *view = GIMP_PALETTE_VIEW (widget);
 
   if (view->selected &&
-      (kevent->keyval == GDK_space  ||
-       kevent->keyval == GDK_Return ||
-       kevent->keyval == GDK_KP_Enter))
+      (kevent->keyval == GDK_space    ||
+       kevent->keyval == GDK_KP_Space ||
+       kevent->keyval == GDK_Return   ||
+       kevent->keyval == GDK_KP_Enter ||
+       kevent->keyval == GDK_ISO_Enter))
     {
       g_signal_emit (view, view_signals[ENTRY_CLICKED], 0,
                      view->selected, kevent->state);

Modified: branches/weskaggs/app/widgets/widgets-enums.h
==============================================================================
--- branches/weskaggs/app/widgets/widgets-enums.h	(original)
+++ branches/weskaggs/app/widgets/widgets-enums.h	Tue Mar  4 03:15:17 2008
@@ -229,6 +229,7 @@
   GIMP_TOOL_CURSOR_RECT_SELECT,
   GIMP_TOOL_CURSOR_ELLIPSE_SELECT,
   GIMP_TOOL_CURSOR_FREE_SELECT,
+  GIMP_TOOL_CURSOR_POLYGON_SELECT,
   GIMP_TOOL_CURSOR_FUZZY_SELECT,
   GIMP_TOOL_CURSOR_PATHS,
   GIMP_TOOL_CURSOR_PATHS_ANCHOR,

Modified: branches/weskaggs/configure.in
==============================================================================
--- branches/weskaggs/configure.in	(original)
+++ branches/weskaggs/configure.in	Tue Mar  4 03:15:17 2008
@@ -40,7 +40,7 @@
 m4_define([gimp_full_name], [GNU Image Manipulation Program])
 
 # required versions of other packages
-m4_define([gegl_required_version], [0.0.15])
+m4_define([gegl_required_version], [0.0.16])
 m4_define([glib_required_version], [2.14.1])
 m4_define([gtk_required_version], [2.12.1])
 m4_define([gdk_pixbuf_required_version], [gtk_required_version])
@@ -139,9 +139,11 @@
 AC_DEFINE_UNQUOTED(GETTEXT_PACKAGE, "$GETTEXT_PACKAGE",
                    [The prefix for our gettext translation domains.])
 
+# Determine a C compiler to use
+AC_PROG_CC
+AM_PROG_CC_C_O
 
 # Initialize libtool
-AC_PROG_CC
 AM_DISABLE_STATIC
 AC_LIBTOOL_WIN32_DLL
 AM_PROG_LIBTOOL
@@ -247,7 +249,6 @@
 
 # Checks for programs.
 AC_ISC_POSIX
-AM_PROG_CC_STDC
 AC_PROG_INSTALL
 AC_PROG_MAKE_SET
 
@@ -1828,6 +1829,9 @@
 GIMP_MKENUMS="\$(PERL) \$(top_srcdir)/tools/gimp-mkenums"
 AC_SUBST(GIMP_MKENUMS)
 
+#Add required trailing ; to list
+MIME_TYPES="$MIME_TYPES;"
+
 AC_SUBST(MIME_TYPES)
 
 

Modified: branches/weskaggs/cursors/Makefile.am
==============================================================================
--- branches/weskaggs/cursors/Makefile.am	(original)
+++ branches/weskaggs/cursors/Makefile.am	Tue Mar  4 03:15:17 2008
@@ -59,6 +59,7 @@
 	tool-paths-segment.png		\
 	tool-pencil.png			\
 	tool-perspective.png		\
+	tool-polygon-select.png		\
 	tool-rect-select.png		\
 	tool-resize.png			\
 	tool-rotate.png			\
@@ -136,6 +137,8 @@
 	xbm/tool-ellipse-select-mask.xbm	\
 	xbm/tool-free-select.xbm		\
 	xbm/tool-free-select-mask.xbm		\
+	xbm/tool-polygon-select.xbm		\
+	xbm/tool-polygon-select-mask.xbm	\
 	xbm/tool-fuzzy-select.xbm		\
 	xbm/tool-fuzzy-select-mask.xbm		\
 	xbm/tool-paths-anchor.xbm		\

Modified: branches/weskaggs/cursors/gimp-tool-cursors.xcf
==============================================================================
Binary files. No diff available.

Modified: branches/weskaggs/devel-docs/parasites.txt
==============================================================================
--- branches/weskaggs/devel-docs/parasites.txt	(original)
+++ branches/weskaggs/devel-docs/parasites.txt	Tue Mar  4 03:15:17 2008
@@ -194,13 +194,28 @@
         for use as a parasite.
 
 "decompose-data" (IMAGE, NONPERSISTENT) 
-        Starting with GIMP 2.3, this is added to images produced by
+        Starting with GIMP 2.4, this is added to images produced by
         the decompose plug-in, and contains information necessary to
         recompose the original source RGB layer from the resulting
         grayscale layers.  It is ascii; a typical example would be
         "source=2 type=RGBA 4 5 6 7".  This means that layer 2 was
         decomposed in RGBA mode, giving rise to layers 4, 5, 6, and 7.
 
+"print-settings" (IMAGE, NONPERSISTENT) 
+        This parasite is stored by the Print plug-in and holds settings
+        done in the Print dialog. It also has a version field so that
+        changes to the parasite can be done. GIMP 2.4 used version 0.3.
+        The format is GKeyFile. A lot of the contents are identical to
+        what is stored in ~/.gimp-2.x/print-settings but the parasite
+        has some additional image-related fields.
+
+"print-page-setup" (IMAGE, NONPERSISTENT) 
+        This parasite is stored by the Print plug-in and holds settings
+        done in the Page Setup dialog. The format is GKeyFile as created
+        from GtkPageSetup. The content is identical to what is stored in
+	~/.gimp-2.x/print-page-setup.
+
+
 ------------------------------------------------------------------
 *** KNOWN LAYER/DRAWABLE PARASITES:
 

Modified: branches/weskaggs/docs/gimp.1.in
==============================================================================
--- branches/weskaggs/docs/gimp.1.in	(original)
+++ branches/weskaggs/docs/gimp.1.in	Tue Mar  4 03:15:17 2008
@@ -1,4 +1,4 @@
-.TH GIMP 1 "Januar 23 2007" "Version @GIMP_VERSION@" "GIMP Manual Pages"
+.TH GIMP 1 "February 23 2008" "Version @GIMP_VERSION@" "GIMP Manual Pages"
 
 .SH NAME
 gimp - an image manipulation and paint program.
@@ -61,7 +61,8 @@
 Show GTK+ command\-line options.
 .TP 8
 .B \-v, \-\-version
-Output version information and exit.
+Output version information and exit. When combined with the \-\-verbose
+option, version information about libraries used by GIMP is shown as well.
 .TP 8
 .B \-\-license
 Output license information and exit.

Modified: branches/weskaggs/libgimpwidgets/gimpchainbutton.c
==============================================================================
--- branches/weskaggs/libgimpwidgets/gimpchainbutton.c	(original)
+++ branches/weskaggs/libgimpwidgets/gimpchainbutton.c	Tue Mar  4 03:15:17 2008
@@ -56,11 +56,11 @@
 
 static void      gimp_chain_button_clicked_callback (GtkWidget       *widget,
                                                      GimpChainButton *button);
-static gboolean  gimp_chain_button_draw_lines       (GtkWidget       *widget,
-                                                     GdkEventExpose  *eevent,
-                                                     GimpChainButton *button);
 static void      gimp_chain_button_update_image     (GimpChainButton *button);
 
+static GtkWidget * gimp_chain_line_new            (GimpChainPosition  position,
+                                                   gint               which);
+
 
 G_DEFINE_TYPE (GimpChainButton, gimp_chain_button, GTK_TYPE_TABLE)
 
@@ -117,25 +117,16 @@
 {
   button->position = GIMP_CHAIN_TOP;
   button->active   = FALSE;
-
-  button->line1    = gtk_drawing_area_new ();
-  button->line2    = gtk_drawing_area_new ();
   button->image    = gtk_image_new ();
-
   button->button   = gtk_button_new ();
 
   gtk_button_set_relief (GTK_BUTTON (button->button), GTK_RELIEF_NONE);
   gtk_container_add (GTK_CONTAINER (button->button), button->image);
+  gtk_widget_show (button->image);
 
   g_signal_connect (button->button, "clicked",
                     G_CALLBACK (gimp_chain_button_clicked_callback),
                     button);
-  g_signal_connect (button->line1, "expose-event",
-                    G_CALLBACK (gimp_chain_button_draw_lines),
-                    button);
-  g_signal_connect (button->line2, "expose-event",
-                    G_CALLBACK (gimp_chain_button_draw_lines),
-                    button);
 }
 
 static GObject *
@@ -150,8 +141,10 @@
 
   button = GIMP_CHAIN_BUTTON (object);
 
+  button->line1 = gimp_chain_line_new (button->position, 1);
+  button->line2 = gimp_chain_line_new (button->position, -1);
+
   gimp_chain_button_update_image (button);
-  gtk_widget_show (button->image);
 
   if (button->position & GIMP_CHAIN_LEFT) /* are we a vertical chainbutton? */
     {
@@ -296,42 +289,101 @@
   g_signal_emit (button, gimp_chain_button_signals[TOGGLED], 0);
 }
 
+static void
+gimp_chain_button_update_image (GimpChainButton *button)
+{
+  guint i;
+
+  i = ((button->position & GIMP_CHAIN_LEFT) << 1) + (button->active ? 0 : 1);
+
+  gtk_image_set_from_stock (GTK_IMAGE (button->image),
+                            gimp_chain_stock_items[i],
+                            GTK_ICON_SIZE_BUTTON);
+}
+
+
+/* GimpChainLine is a simple no-window widget for drawing the lines.
+ *
+ * Originally this used to be a GtkDrawingArea but this turned out to
+ * be a bad idea. We don't need an extra window to draw on and we also
+ * don't need any input events.
+ */
+
+static GType     gimp_chain_line_get_type     (void) G_GNUC_CONST;
+static gboolean  gimp_chain_line_expose_event (GtkWidget       *widget,
+                                               GdkEventExpose  *event);
+
+struct _GimpChainLine
+{
+  GtkWidget          parent_instance;
+  GimpChainPosition  position;
+  gint               which;
+};
+
+typedef struct _GimpChainLine  GimpChainLine;
+typedef GtkWidgetClass         GimpChainLineClass;
+
+G_DEFINE_TYPE (GimpChainLine, gimp_chain_line, GTK_TYPE_WIDGET)
+
+static void
+gimp_chain_line_class_init (GimpChainLineClass *klass)
+{
+  GtkWidgetClass *widget_class = GTK_WIDGET_CLASS (klass);
+
+  widget_class->expose_event = gimp_chain_line_expose_event;
+}
+
+static void
+gimp_chain_line_init (GimpChainLine *line)
+{
+  GTK_WIDGET_SET_FLAGS (line, GTK_NO_WINDOW);
+}
+
+static GtkWidget *
+gimp_chain_line_new (GimpChainPosition  position,
+                     gint               which)
+{
+  GimpChainLine *line = g_object_new (gimp_chain_line_get_type (), NULL);
+
+  line->position = position;
+  line->which    = which;
+
+  return GTK_WIDGET (line);
+}
+
 static gboolean
-gimp_chain_button_draw_lines (GtkWidget       *widget,
-                              GdkEventExpose  *eevent,
-                              GimpChainButton *button)
+gimp_chain_line_expose_event (GtkWidget       *widget,
+                              GdkEventExpose  *event)
 {
+  GimpChainLine     *line = ((GimpChainLine *) widget);
   GdkPoint           points[3];
   GdkPoint           buf;
-  GtkShadowType             shadow;
+  GtkShadowType      shadow;
   GimpChainPosition  position;
-  gint               which_line;
 
 #define SHORT_LINE 4
-  /* don't set this too high, there's no check against drawing outside
-     the widgets bounds yet (and probably never will be) */
-
-  g_return_val_if_fail (GIMP_IS_CHAIN_BUTTON (button), FALSE);
-
-  points[0].x = widget->allocation.width / 2;
-  points[0].y = widget->allocation.height / 2;
+  points[0].x = widget->allocation.x + widget->allocation.width  / 2;
+  points[0].y = widget->allocation.y + widget->allocation.height / 2;
 
-  which_line = (widget == button->line1) ? 1 : -1;
-
-  position = button->position;
+  position = line->position;
 
   if (gtk_widget_get_direction (widget) == GTK_TEXT_DIR_RTL)
-    switch (position)
-      {
-      case GIMP_CHAIN_LEFT:
-        position = GIMP_CHAIN_RIGHT;
-        break;
-      case GIMP_CHAIN_RIGHT:
-        position = GIMP_CHAIN_LEFT;
-        break;
-      default:
-        break;
-      }
+    {
+      switch (position)
+        {
+        case GIMP_CHAIN_TOP:
+        case GIMP_CHAIN_BOTTOM:
+          break;
+
+        case GIMP_CHAIN_LEFT:
+          position = GIMP_CHAIN_RIGHT;
+          break;
+
+        case GIMP_CHAIN_RIGHT:
+          position = GIMP_CHAIN_LEFT;
+          break;
+        }
+    }
 
   switch (position)
     {
@@ -340,67 +392,64 @@
       points[1].x = points[0].x - SHORT_LINE;
       points[1].y = points[0].y;
       points[2].x = points[1].x;
-      points[2].y = (which_line == 1) ? widget->allocation.height - 1 : 0;
+      points[2].y = (line->which == 1 ?
+                     widget->allocation.y + widget->allocation.height - 1 :
+                     widget->allocation.y);
       shadow = GTK_SHADOW_ETCHED_IN;
       break;
+
     case GIMP_CHAIN_RIGHT:
       points[0].x -= SHORT_LINE;
       points[1].x = points[0].x + SHORT_LINE;
       points[1].y = points[0].y;
       points[2].x = points[1].x;
-      points[2].y = (which_line == 1) ? widget->allocation.height - 1 : 0;
+      points[2].y = (line->which == 1 ?
+                     widget->allocation.y + widget->allocation.height - 1 :
+                     widget->allocation.y);
       shadow = GTK_SHADOW_ETCHED_OUT;
       break;
+
     case GIMP_CHAIN_TOP:
       points[0].y += SHORT_LINE;
       points[1].x = points[0].x;
       points[1].y = points[0].y - SHORT_LINE;
-      points[2].x = (which_line == 1) ? widget->allocation.width - 1 : 0;
+      points[2].x = (line->which == 1 ?
+                     widget->allocation.x + widget->allocation.width - 1 :
+                     widget->allocation.x);
       points[2].y = points[1].y;
       shadow = GTK_SHADOW_ETCHED_OUT;
       break;
+
     case GIMP_CHAIN_BOTTOM:
       points[0].y -= SHORT_LINE;
       points[1].x = points[0].x;
       points[1].y = points[0].y + SHORT_LINE;
-      points[2].x = (which_line == 1) ? widget->allocation.width - 1 : 0;
+      points[2].x = (line->which == 1 ?
+                     widget->allocation.x + widget->allocation.width - 1 :
+                     widget->allocation.x);
       points[2].y = points[1].y;
       shadow = GTK_SHADOW_ETCHED_IN;
       break;
+
     default:
       return FALSE;
     }
 
-  if ( ((shadow == GTK_SHADOW_ETCHED_OUT) && (which_line == -1)) ||
-       ((shadow == GTK_SHADOW_ETCHED_IN) && (which_line == 1)) )
+  if ( ((shadow == GTK_SHADOW_ETCHED_OUT) && (line->which == -1)) ||
+       ((shadow == GTK_SHADOW_ETCHED_IN)  && (line->which == 1)) )
     {
       buf = points[0];
       points[0] = points[2];
       points[2] = buf;
     }
 
-  gtk_paint_polygon (widget->style,
-                     widget->window,
-                     GTK_STATE_NORMAL,
+  gtk_paint_polygon (widget->style, widget->window, GTK_STATE_NORMAL,
                      shadow,
-                     &eevent->area,
+                     &event->area,
                      widget,
                      "chainbutton",
-                     points,
-                     3,
+                     points, 3,
                      FALSE);
 
   return TRUE;
 }
-
-static void
-gimp_chain_button_update_image (GimpChainButton *button)
-{
-  guint i;
-
-  i = ((button->position & GIMP_CHAIN_LEFT) << 1) + (button->active ? 0 : 1);
-
-  gtk_image_set_from_stock (GTK_IMAGE (button->image),
-                            gimp_chain_stock_items[i],
-                            GTK_ICON_SIZE_BUTTON);
-}

Modified: branches/weskaggs/libgimpwidgets/gimpcolorhexentry.c
==============================================================================
--- branches/weskaggs/libgimpwidgets/gimpcolorhexentry.c	(original)
+++ branches/weskaggs/libgimpwidgets/gimpcolorhexentry.c	Tue Mar  4 03:15:17 2008
@@ -216,39 +216,48 @@
                              GdkEvent  *event)
 {
   GimpColorHexEntry *entry = GIMP_COLOR_HEX_ENTRY (widget);
-  const gchar       *text;
-  gchar              buffer[8];
-  guchar             r, g, b;
 
   switch (event->type)
     {
     case GDK_KEY_PRESS:
-      if (((GdkEventKey *) event)->keyval != GDK_Return)
-        break;
-      /*  else fall through  */
+      {
+        GdkEventKey *kevent = (GdkEventKey *) event;
 
-    case GDK_FOCUS_CHANGE:
-      text = gtk_entry_get_text (GTK_ENTRY (widget));
-
-      gimp_rgb_get_uchar (&entry->color, &r, &g, &b);
-      g_snprintf (buffer, sizeof (buffer), "%.2x%.2x%.2x", r, g, b);
+        if (kevent->keyval != GDK_Return   &&
+            kevent->keyval != GDK_KP_Enter &&
+            kevent->keyval != GDK_ISO_Enter)
+          break;
+        /*  else fall through  */
+      }
 
-      if (g_ascii_strcasecmp (buffer, text) != 0)
-        {
-          GimpRGB  color;
-          gsize    len = strlen (text);
-
-          if (len > 0 &&
-              (gimp_rgb_parse_hex (&color, text, len) ||
-               gimp_rgb_parse_name (&color, text, -1)))
-            {
-              gimp_color_hex_entry_set_color (entry, &color);
-            }
-          else
-            {
-              gtk_entry_set_text (GTK_ENTRY (entry), buffer);
-            }
-        }
+    case GDK_FOCUS_CHANGE:
+      {
+        const gchar *text;
+        gchar        buffer[8];
+        guchar       r, g, b;
+
+        text = gtk_entry_get_text (GTK_ENTRY (widget));
+
+        gimp_rgb_get_uchar (&entry->color, &r, &g, &b);
+        g_snprintf (buffer, sizeof (buffer), "%.2x%.2x%.2x", r, g, b);
+
+        if (g_ascii_strcasecmp (buffer, text) != 0)
+          {
+            GimpRGB  color;
+            gsize    len = strlen (text);
+
+            if (len > 0 &&
+                (gimp_rgb_parse_hex (&color, text, len) ||
+                 gimp_rgb_parse_name (&color, text, -1)))
+              {
+                gimp_color_hex_entry_set_color (entry, &color);
+              }
+            else
+              {
+                gtk_entry_set_text (GTK_ENTRY (entry), buffer);
+              }
+          }
+      }
       break;
 
     default:

Modified: branches/weskaggs/libgimpwidgets/gimpnumberpairentry.c
==============================================================================
--- branches/weskaggs/libgimpwidgets/gimpnumberpairentry.c	(original)
+++ branches/weskaggs/libgimpwidgets/gimpnumberpairentry.c	Tue Mar  4 03:15:17 2008
@@ -818,7 +818,9 @@
       {
         GdkEventKey *kevent = (GdkEventKey *) event;
 
-        if (kevent->keyval != GDK_Return)
+        if (kevent->keyval != GDK_Return   &&
+            kevent->keyval != GDK_KP_Enter &&
+            kevent->keyval != GDK_ISO_Enter)
           break;
 
         /* If parsing was done due to widgets focus being lost, we only change

Modified: branches/weskaggs/plug-ins/common/struc.c
==============================================================================
--- branches/weskaggs/plug-ins/common/struc.c	(original)
+++ branches/weskaggs/plug-ins/common/struc.c	Tue Mar  4 03:15:17 2008
@@ -1374,15 +1374,13 @@
        *  faster, since fewer pixels need to be operated on).
        */
       if (! gimp_drawable_mask_intersect (drawable->drawable_id,
-                                          &x1, &y1, &x2, &y2))
+                                          &x1, &y1, &width, &height))
         return;
 
-      /* Get the size of the input image. (This will/must be the same
-       *  as the size of the output image.
-       */
-      width = x2 - x1;
-      height = y2 - y1;
+      x2 = x1 + width;
+      y2 = y1 + height;
     }
+
   bytes = drawable->bpp;
 
   /*  allocate row buffers  */

Modified: branches/weskaggs/plug-ins/common/tileit.c
==============================================================================
--- branches/weskaggs/plug-ins/common/tileit.c	(original)
+++ branches/weskaggs/plug-ins/common/tileit.c	Tue Mar  4 03:15:17 2008
@@ -257,14 +257,15 @@
   has_alpha = gimp_drawable_has_alpha (tileitdrawable->drawable_id);
 
   if (! gimp_drawable_mask_intersect (drawable->drawable_id,
-                                      &sel_x1, &sel_y1, &sel_x2, &sel_y2))
+                                      &sel_x1,    &sel_y1,
+                                      &sel_width, &sel_height))
     {
       g_message (_("Region selected for filter is empty."));
       return;
     }
 
-  sel_width  = sel_x2 - sel_x1;
-  sel_height = sel_y2 - sel_y1;
+  sel_x2 = sel_x1 + sel_width;
+  sel_y2 = sel_y1 + sel_height;
 
   /* Calculate preview size */
 

Modified: branches/weskaggs/plug-ins/common/wind.c
==============================================================================
--- branches/weskaggs/plug-ins/common/wind.c	(original)
+++ branches/weskaggs/plug-ins/common/wind.c	Tue Mar  4 03:15:17 2008
@@ -310,18 +310,20 @@
   else
     {
       if (gimp_drawable_mask_intersect (drawable->drawable_id,
-                                        &x1, &y1, &x2, &y2))
+                                        &x1, &y1, &width, &height))
         {
           gimp_progress_init (_("Rendering blast"));
 
-          width = x2 - x1;
-          height = y2 - y1;
+          x2 = x1 + width;
+          y2 = y1 + height;
 
           gimp_pixel_rgn_init (&dest_region, drawable,
                                x1, y1, width, height, TRUE, TRUE);
         }
       else
-        return;
+        {
+          return;
+        }
     }
 
   gimp_pixel_rgn_init (&src_region,  drawable,
@@ -356,7 +358,9 @@
       else
         {
           gimp_pixel_rgn_set_row (&dest_region, buffer, x1, row, width);
-          gimp_progress_update ((double) (row - y1)/ (double) (height));
+
+          if (row % 8 == 0)
+            gimp_progress_update ((double) (row - y1)/ (double) (height));
         }
 
       if (marker)
@@ -437,18 +441,21 @@
     }
   else
     {
-      if (gimp_drawable_mask_intersect (drawable->drawable_id, &x1, &y1, &x2, &y2))
+      if (gimp_drawable_mask_intersect (drawable->drawable_id,
+                                        &x1, &y1, &width, &height))
         {
           gimp_progress_init (_("Rendering wind"));
 
-          width = x2 - x1;
-          height = y2 - y1;
+          x2 = x1 + width;
+          y2 = y1 + height;
 
           gimp_pixel_rgn_init (&dest_region, drawable,
                                x1, y1, width, height, TRUE, TRUE);
         }
       else
-        return;
+        {
+          return;
+        }
     }
 
   gimp_pixel_rgn_init (&src_region, drawable,
@@ -478,7 +485,9 @@
       else
         {
           gimp_pixel_rgn_set_row (&dest_region, sb, x1, row, width);
-          gimp_progress_update ((double) (row - y1)/ (double) (height));
+
+          if (row % 8 == 0)
+            gimp_progress_update ((double) (row - y1)/ (double) (height));
         }
     }
 

Modified: branches/weskaggs/plug-ins/jpeg/jpeg-exif.c
==============================================================================
--- branches/weskaggs/plug-ins/jpeg/jpeg-exif.c	(original)
+++ branches/weskaggs/plug-ins/jpeg/jpeg-exif.c	Tue Mar  4 03:15:17 2008
@@ -152,13 +152,13 @@
     }
 
   /* set the width and height */
-  if ((entry = exif_content_get_entry (exif_data->ifd[EXIF_IFD_0],
+  if ((entry = exif_content_get_entry (exif_data->ifd[EXIF_IFD_EXIF],
                                        EXIF_TAG_PIXEL_X_DIMENSION)))
     {
       exif_set_long (entry->data, byte_order,
                      (ExifLong) gimp_image_width (image_ID));
     }
-  if ((entry = exif_content_get_entry (exif_data->ifd[EXIF_IFD_0],
+  if ((entry = exif_content_get_entry (exif_data->ifd[EXIF_IFD_EXIF],
                                        EXIF_TAG_PIXEL_Y_DIMENSION)))
     {
       exif_set_long (entry->data, byte_order,

Modified: branches/weskaggs/plug-ins/print/Makefile.am
==============================================================================
--- branches/weskaggs/plug-ins/print/Makefile.am	(original)
+++ branches/weskaggs/plug-ins/print/Makefile.am	Tue Mar  4 03:15:17 2008
@@ -49,4 +49,6 @@
 	print-preview.c		\
 	print-preview.h		\
 	print-settings.c	\
-	print-settings.h
+	print-settings.h	\
+	print-utils.c		\
+	print-utils.h

Modified: branches/weskaggs/plug-ins/print/print-draw-page.c
==============================================================================
--- branches/weskaggs/plug-ins/print/print-draw-page.c	(original)
+++ branches/weskaggs/plug-ins/print/print-draw-page.c	Tue Mar  4 03:15:17 2008
@@ -27,139 +27,179 @@
 #include "libgimp/stdplugins-intl.h"
 
 
-#define EPSILON 0.0001
+static cairo_surface_t * print_cairo_surface_from_drawable (gint32 drawable_ID);
 
-#define INT_MULT(a,b,t)  ((t) = (a) * (b) + 0x80, ((((t) >> 8) + (t)) >> 8))
-#define INT_BLEND(a,b,alpha,tmp)  (INT_MULT((a) - (b), alpha, tmp) + (b))
-
-
-static void  convert_from_rgb  (guchar *pixels,
-                                gint    width);
-static void  convert_from_rgba (guchar *pixels,
-                                gint    width);
+static inline void       convert_from_gray  (const guchar *src,
+                                             guchar       *dest,
+                                             gint          pixels);
+static inline void       convert_from_graya (const guchar *src,
+                                             guchar       *dest,
+                                             gint          pixels);
+static inline void       convert_from_rgb   (const guchar *src,
+                                             guchar       *dest,
+                                             gint          pixels);
+static inline void       convert_from_rgba  (const guchar *src,
+                                             guchar       *dest,
+                                             gint          pixels);
 
 
 gboolean
-draw_page_cairo (GtkPrintContext *context,
+print_draw_page (GtkPrintContext *context,
                  PrintData       *data)
 {
-  GimpDrawable    *drawable = gimp_drawable_get (data->drawable_id);
-  GimpPixelRgn     region;
   cairo_t         *cr;
   cairo_surface_t *surface;
-  guchar          *pixels;
   gdouble          cr_width;
   gdouble          cr_height;
   gdouble          cr_dpi_x;
   gdouble          cr_dpi_y;
-  gint             width;
-  gint             height;
-  gint             stride;
-  gint             y;
-  gdouble          scale_x;
-  gdouble          scale_y;
-
-  width  = drawable->width;
-  height = drawable->height;
-
-  gimp_tile_cache_ntiles (width / gimp_tile_width () + 1);
 
   cr = gtk_print_context_get_cairo_context (context);
 
+  surface = print_cairo_surface_from_drawable (data->drawable_id);
+
   cr_width  = gtk_print_context_get_width  (context);
   cr_height = gtk_print_context_get_height (context);
   cr_dpi_x  = gtk_print_context_get_dpi_x  (context);
   cr_dpi_y  = gtk_print_context_get_dpi_y  (context);
 
-  scale_x = cr_dpi_x / data->xres;
-  scale_y = cr_dpi_y / data->yres;
-
   cairo_translate (cr,
                    data->offset_x / cr_dpi_x * 72.0,
                    data->offset_y / cr_dpi_y * 72.0);
-  cairo_scale (cr, scale_x, scale_y);
+  cairo_scale (cr,
+               cr_dpi_x / data->xres, cr_dpi_y / data->yres);
 
-  gimp_pixel_rgn_init (&region, drawable, 0, 0, width, height, FALSE, FALSE);
+  cairo_rectangle (cr,
+                   0, 0,
+                   cairo_image_surface_get_width (surface),
+                   cairo_image_surface_get_height (surface));
+  cairo_set_source_surface (cr, surface, 0, 0);
+  cairo_fill (cr);
+  cairo_surface_destroy (surface);
 
-  surface = cairo_image_surface_create (CAIRO_FORMAT_RGB24, width, height);
+  return TRUE;
+}
+
+static cairo_surface_t *
+print_cairo_surface_from_drawable (gint32 drawable_ID)
+{
+  GimpDrawable    *drawable = gimp_drawable_get (drawable_ID);
+  GimpPixelRgn     region;
+  cairo_surface_t *surface;
+  const gint       width    = drawable->width;
+  const gint       height   = drawable->height;
+  guchar          *pixels;
+  gint             stride;
+  guint            count    = 0;
+  guint            done     = 0;
+  gpointer         pr;
+
+  surface = cairo_image_surface_create (gimp_drawable_has_alpha (drawable_ID) ?
+                                        CAIRO_FORMAT_ARGB32 :
+                                        CAIRO_FORMAT_RGB24,
+                                        width, height);
 
   pixels = cairo_image_surface_get_data (surface);
   stride = cairo_image_surface_get_stride (surface);
 
-  for (y = 0; y < height; y++, pixels += stride)
+  gimp_pixel_rgn_init (&region, drawable, 0, 0, width, height, FALSE, FALSE);
+
+  for (pr = gimp_pixel_rgns_register (1, &region);
+       pr != NULL;
+       pr = gimp_pixel_rgns_process (pr))
     {
-      gimp_pixel_rgn_get_row (&region, pixels, 0, y, width);
+      const guchar *src  = region.data;
+      guchar       *dest = pixels + region.y * stride + region.x * 4;
+      gint          y;
 
-      switch (drawable->bpp)
+      for (y = 0; y < region.h; y++)
         {
-        case 3:
-          convert_from_rgb (pixels, width);
-          break;
-        case 4:
-          convert_from_rgba (pixels, width);
-          break;
-        }
+          switch (region.bpp)
+            {
+            case 1:
+              convert_from_gray (src, dest, region.w);
+              break;
+
+            case 2:
+              convert_from_graya (src, dest, region.w);
+              break;
+
+            case 3:
+              convert_from_rgb (src, dest, region.w);
+              break;
+
+            case 4:
+              convert_from_rgba (src, dest, region.w);
+              break;
+            }
 
-      if (y % 16 == 0)
-        gimp_progress_update ((gdouble) y / (gdouble) height);
-    }
+          src  += region.rowstride;
+          dest += stride;
+        }
 
-  cairo_set_source_surface (cr, surface, 0, 0);
-  cairo_rectangle (cr, 0, 0, width, height);
-  cairo_fill (cr);
-  cairo_surface_destroy (surface);
+      done += region.h * region.w;
 
-  gimp_progress_update (1.0);
+      if (count++ % 16 == 0)
+        gimp_progress_update ((gdouble) done / (width * height));
+    }
 
   gimp_drawable_detach (drawable);
 
-  return TRUE;
+  return surface;
 }
 
-static void
-convert_from_rgb (guchar *pixels,
-                  gint    width)
-{
-  guint32 *cairo_data = (guint32 *) pixels;
-  guchar  *p;
-  gint     i;
-
-  for (i = width - 1, p = pixels + 3 * width - 1; i >= 0; i--)
+static inline void
+convert_from_gray (const guchar *src,
+                   guchar       *dest,
+                   gint          pixels)
+{
+  while (pixels--)
     {
-      guint32 b = *p--;
-      guint32 g = *p--;
-      guint32 r = *p--;
+      GIMP_CAIRO_RGB24_SET_PIXEL (dest, src[0], src[0], src[0]);
 
-      cairo_data[i] = 0xFF000000 | (r << 16) | (g << 8) | b;
+      src  += 1;
+      dest += 4;
     }
 }
 
-static void
-convert_from_rgba (guchar *pixels,
-                   gint    width)
-{
-  guint32 *cairo_data = (guint32 *) pixels;
-  guchar  *p;
-  gint     i;
-
-  for (i = 0, p = pixels; i < width; i++)
+static inline void
+convert_from_graya (const guchar *src,
+                    guchar       *dest,
+                    gint          pixels)
+{
+  while (pixels--)
     {
-      guint32 r = *p++;
-      guint32 g = *p++;
-      guint32 b = *p++;
-      guint32 a = *p++;
+      GIMP_CAIRO_ARGB32_SET_PIXEL (dest, src[0], src[0], src[0], src[1]);
 
-      if (a != 255)
-        {
-          guint32 tmp;
+      src  += 2;
+      dest += 4;
+    }
+}
 
-          /* composite on a white background */
+static inline void
+convert_from_rgb (const guchar *src,
+                  guchar       *dest,
+                  gint          pixels)
+{
+  while (pixels--)
+    {
+      GIMP_CAIRO_RGB24_SET_PIXEL (dest, src[0], src[1], src[2]);
 
-          r = INT_BLEND (r, 255, a, tmp);
-          g = INT_BLEND (g, 255, a, tmp);
-          b = INT_BLEND (b, 255, a, tmp);
-        }
+      src  += 3;
+      dest += 4;
+    }
+}
+
+static inline void
+convert_from_rgba (const guchar *src,
+                   guchar       *dest,
+                   gint          pixels)
+{
+  while (pixels--)
+    {
+      GIMP_CAIRO_ARGB32_SET_PIXEL (dest, src[0], src[1], src[2], src[3]);
 
-      cairo_data[i] = 0xFF000000 | (r << 16) | (g << 8) | b;
+      src  += 4;
+      dest += 4;
     }
 }

Modified: branches/weskaggs/plug-ins/print/print-draw-page.h
==============================================================================
--- branches/weskaggs/plug-ins/print/print-draw-page.h	(original)
+++ branches/weskaggs/plug-ins/print/print-draw-page.h	Tue Mar  4 03:15:17 2008
@@ -16,5 +16,5 @@
  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
  */
 
-gboolean draw_page_cairo (GtkPrintContext *context,
+gboolean print_draw_page (GtkPrintContext *context,
                           PrintData       *data);

Modified: branches/weskaggs/plug-ins/print/print-page-layout.c
==============================================================================
--- branches/weskaggs/plug-ins/print/print-page-layout.c	(original)
+++ branches/weskaggs/plug-ins/print/print-page-layout.c	Tue Mar  4 03:15:17 2008
@@ -58,7 +58,7 @@
 };
 
 
-static void        print_page_setup_notify       (GtkPrintOperation *operation);
+static void        print_page_setup_notify            (GtkPrintOperation *operation);
 
 static GtkWidget * print_size_frame                   (PrintData    *data,
                                                        GtkSizeGroup *label_group,
@@ -94,15 +94,12 @@
 
 
 GtkWidget *
-print_page_layout_gui (PrintData *data)
+print_page_layout_gui (PrintData   *data,
+                       const gchar *help_id)
 {
-  GtkWidget    *layout;
   GtkWidget    *main_hbox;
   GtkWidget    *main_vbox;
-  GtkWidget    *hbox;
-  GtkWidget    *vbox;
   GtkWidget    *button;
-  GtkWidget    *label;
   GtkWidget    *frame;
   GtkPageSetup *setup;
   GtkSizeGroup *label_group;
@@ -121,43 +118,15 @@
       gtk_print_operation_set_default_page_setup (data->operation, setup);
     }
 
-  layout = gtk_vbox_new (FALSE, 6);
-  gtk_container_set_border_width (GTK_CONTAINER (layout), 12);
-
-  hbox = gtk_hbox_new (FALSE, 6);
-  gtk_box_pack_start (GTK_BOX (layout), hbox, FALSE, FALSE, 0);
-  gtk_widget_show (hbox);
-
-  /* label for the printable area */
-
-  label = gtk_label_new (_("Printable area:"));
-  gtk_box_pack_start (GTK_BOX (hbox), label, FALSE, FALSE, 0);
-  gtk_widget_show (label);
-
-  label = gtk_label_new (NULL);
-  gtk_misc_set_alignment (GTK_MISC (label), 0.0, 0.5);
-  gimp_label_set_attributes (GTK_LABEL (label),
-                             PANGO_ATTR_STYLE, PANGO_STYLE_ITALIC,
-                             -1);
-  info.area_label = label;
-
-  gtk_box_pack_start (GTK_BOX (hbox), info.area_label, TRUE, TRUE, 0);
-  gtk_widget_show (info.area_label);
-
   /*  main hbox  */
   main_hbox = gtk_hbox_new (FALSE, 12);
-  gtk_box_pack_start (GTK_BOX (layout), main_hbox, TRUE, TRUE, 0);
-  gtk_widget_show (main_hbox);
+  gtk_container_set_border_width (GTK_CONTAINER (main_hbox), 12);
 
   /*  main vbox  */
   main_vbox = gtk_vbox_new (FALSE, 12);
   gtk_box_pack_start (GTK_BOX (main_hbox), main_vbox, FALSE, FALSE, 0);
   gtk_widget_show (main_vbox);
 
-  vbox = gtk_vbox_new (FALSE, 6);
-  gtk_box_pack_start (GTK_BOX (main_vbox), vbox, FALSE, FALSE, 0);
-  gtk_widget_show (vbox);
-
   label_group = gtk_size_group_new (GTK_SIZE_GROUP_HORIZONTAL);
   entry_group = gtk_size_group_new (GTK_SIZE_GROUP_HORIZONTAL);
 
@@ -186,10 +155,15 @@
                     NULL);
   gtk_widget_show (button);
 
-  info.preview = gimp_print_preview_new (setup, data->drawable_id);
-  gimp_print_preview_set_use_full_page (GIMP_PRINT_PREVIEW(info.preview),
-                                        data->use_full_page);
-  gtk_box_pack_start (GTK_BOX (main_hbox), info.preview, TRUE, TRUE, 0);
+  /* preview */
+  frame = gimp_frame_new (_("Preview"));
+  gtk_box_pack_start (GTK_BOX (main_hbox), frame, TRUE, TRUE, 0);
+  gtk_widget_show (frame);
+
+  info.preview = print_preview_new (setup, data->drawable_id);
+  print_preview_set_use_full_page (PRINT_PREVIEW (info.preview),
+                                   data->use_full_page);
+  gtk_container_add (GTK_CONTAINER (frame), info.preview);
   gtk_widget_show (info.preview);
 
   g_signal_connect (info.preview, "offsets-changed",
@@ -200,12 +174,12 @@
 
   g_signal_connect_object (data->operation, "notify::default-page-setup",
                            G_CALLBACK (print_page_setup_notify),
-                           layout, 0);
+                           main_hbox, 0);
 
-  return layout;
-}
+  gimp_help_connect (main_hbox, gimp_standard_help_func, help_id, NULL);
 
-#define SB_WIDTH 8
+  return main_hbox;
+}
 
 static void
 print_page_setup_notify (GtkPrintOperation *operation)
@@ -214,13 +188,13 @@
 
   setup = gtk_print_operation_get_default_page_setup (operation);
 
-  gimp_print_preview_set_page_setup (GIMP_PRINT_PREVIEW (info.preview),
-                                     setup);
-
   print_size_info_set_page_setup (&info);
+  print_preview_set_page_setup (PRINT_PREVIEW (info.preview), setup);
 }
 
 
+#define SB_WIDTH 8
+
 static GtkWidget *
 print_size_frame (PrintData    *data,
                   GtkSizeGroup *label_group,
@@ -639,9 +613,9 @@
       print_size_info_update_offsets ();
 
       if (info.preview)
-        gimp_print_preview_set_image_offsets (GIMP_PRINT_PREVIEW (info.preview),
-                                              info.data->offset_x,
-                                              info.data->offset_y);
+        print_preview_set_image_offsets (PRINT_PREVIEW (info.preview),
+                                         info.data->offset_x,
+                                         info.data->offset_y);
     }
 }
 
@@ -704,9 +678,9 @@
   info.data->offset_x = gimp_size_entry_get_refval (info.size_entry, LEFT);
   info.data->offset_y = gimp_size_entry_get_refval (info.size_entry, TOP);
 
-  gimp_print_preview_set_image_offsets (GIMP_PRINT_PREVIEW (info.preview),
-                                        info.data->offset_x,
-                                        info.data->offset_y);
+  print_preview_set_image_offsets (PRINT_PREVIEW (info.preview),
+                                   info.data->offset_x,
+                                   info.data->offset_y);
 }
 
 static void
@@ -747,8 +721,7 @@
 
   print_size_info_set_page_setup (&info);
 
-  gimp_print_preview_set_use_full_page (GIMP_PRINT_PREVIEW(info.preview),
-                                        active);
+  print_preview_set_use_full_page (PRINT_PREVIEW(info.preview), active);
 }
 
 static void
@@ -820,12 +793,12 @@
 
   print_size_info_update_offsets ();
 
-  gimp_print_preview_set_image_dpi (GIMP_PRINT_PREVIEW (info->preview),
-                                    data->xres, data->yres);
-  gimp_print_preview_set_image_offsets (GIMP_PRINT_PREVIEW (info->preview),
-                                        data->offset_x, data->offset_y);
-  gimp_print_preview_set_image_offsets_max (GIMP_PRINT_PREVIEW (info->preview),
-                                            offset_x_max, offset_y_max);
+  print_preview_set_image_dpi (PRINT_PREVIEW (info->preview),
+                               data->xres, data->yres);
+  print_preview_set_image_offsets (PRINT_PREVIEW (info->preview),
+                                   data->offset_x, data->offset_y);
+  print_preview_set_image_offsets_max (PRINT_PREVIEW (info->preview),
+                                       offset_x_max, offset_y_max);
 }
 
 static void
@@ -833,8 +806,6 @@
 {
   GtkPageSetup *setup;
   PrintData    *data = info->data;
-  gchar        *format;
-  gchar        *text;
   gdouble       page_width;
   gdouble       page_height;
   gdouble       x;
@@ -849,15 +820,21 @@
   page_width  *= gimp_unit_get_factor (data->unit);
   page_height *= gimp_unit_get_factor (data->unit);
 
-  format = g_strdup_printf ("%%.%df x %%.%df %s",
-                            gimp_unit_get_digits (data->unit),
-                            gimp_unit_get_digits (data->unit),
-                            gimp_unit_get_plural (data->unit));
-  text = g_strdup_printf (format, page_width, page_height);
-  g_free (format);
+  if (info->area_label)
+    {
+      gchar *format;
+      gchar *text;
+
+      format = g_strdup_printf ("%%.%df x %%.%df %s",
+                                gimp_unit_get_digits (data->unit),
+                                gimp_unit_get_digits (data->unit),
+                                gimp_unit_get_plural (data->unit));
+      text = g_strdup_printf (format, page_width, page_height);
+      g_free (format);
 
-  gtk_label_set_text (GTK_LABEL (info->area_label), text);
-  g_free (text);
+      gtk_label_set_text (GTK_LABEL (info->area_label), text);
+      g_free (text);
+    }
 
   x = page_width;
   y = page_height;
@@ -870,17 +847,19 @@
       if (ratio_x < ratio_y)
         y = (gdouble) info->image_height * ratio_x;
       else
-        x = (gdouble) info->image_width * ratio_y;
+        x = (gdouble) info->image_width  * ratio_y;
     }
 
-  gimp_size_entry_set_value_boundaries (info->size_entry, WIDTH,  0.0, x);
-  gimp_size_entry_set_value_boundaries (info->size_entry, HEIGHT, 0.0, y);
+  gimp_size_entry_set_value_boundaries (info->size_entry, WIDTH,
+                                        page_width  / 100.0, x);
+  gimp_size_entry_set_value_boundaries (info->size_entry, HEIGHT,
+                                        page_height / 100.0, y);
 
   print_size_info_get_page_dimensions (info,
                                        &page_width, &page_height,
                                        GTK_UNIT_POINTS);
 
-  x = (gdouble) info->image_width / page_width * 72.0;
+  x = (gdouble) info->image_width  / page_width  * 72.0;
   y = (gdouble) info->image_height / page_height * 72.0;
 
   if (info->chain && gimp_chain_button_get_active (info->chain))
@@ -894,7 +873,4 @@
                                          x, GIMP_MAX_RESOLUTION);
   gimp_size_entry_set_refval_boundaries (info->resolution_entry, 1,
                                          y, GIMP_MAX_RESOLUTION);
-
-  /* FIXME: is this still needed at all? */
-  data->orientation = gtk_page_setup_get_orientation (setup);
 }

Modified: branches/weskaggs/plug-ins/print/print-page-layout.h
==============================================================================
--- branches/weskaggs/plug-ins/print/print-page-layout.h	(original)
+++ branches/weskaggs/plug-ins/print/print-page-layout.h	Tue Mar  4 03:15:17 2008
@@ -16,5 +16,6 @@
  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
  */
 
-GtkWidget * print_page_layout_gui (PrintData *data);
+GtkWidget * print_page_layout_gui (PrintData   *data,
+                                   const gchar *help_id);
 

Modified: branches/weskaggs/plug-ins/print/print-page-setup.c
==============================================================================
--- branches/weskaggs/plug-ins/print/print-page-setup.c	(original)
+++ branches/weskaggs/plug-ins/print/print-page-setup.c	Tue Mar  4 03:15:17 2008
@@ -22,6 +22,9 @@
 #include <libgimp/gimpui.h>
 
 #include "print-page-setup.h"
+#include "print-utils.h"
+
+#define PRINT_PAGE_SETUP_NAME  "print-page-setup"
 
 
 void
@@ -41,49 +44,56 @@
   gtk_print_operation_set_default_page_setup (operation, setup);
 }
 
-gboolean
+void
 print_page_setup_load (GtkPrintOperation *operation,
                        gint32             image_ID)
 {
-  GtkPageSetup *setup;
-  gchar        *filename;
+  GKeyFile *key_file;
 
-  filename = g_build_filename (gimp_directory (), "print-page-setup", NULL);
+  g_return_if_fail (GTK_IS_PRINT_OPERATION (operation));
 
-  setup = gtk_page_setup_new_from_file (filename, NULL);
+  key_file = print_utils_key_file_load_from_parasite (image_ID,
+                                                      PRINT_PAGE_SETUP_NAME);
 
-  g_free (filename);
+  if (! key_file)
+    key_file = print_utils_key_file_load_from_rcfile (PRINT_PAGE_SETUP_NAME);
 
-  if (setup)
+  if (key_file)
     {
-      gtk_print_operation_set_default_page_setup (operation, setup);
-      g_object_unref (setup);
+      GtkPageSetup *setup;
 
-      return TRUE;
-    }
+      setup = gtk_page_setup_new_from_key_file (key_file,
+                                                PRINT_PAGE_SETUP_NAME, NULL);
+
+      if (setup)
+        {
+          gtk_print_operation_set_default_page_setup (operation, setup);
+          g_object_unref (setup);
+        }
 
-  return FALSE;
+      g_key_file_free (key_file);
+    }
 }
 
 void
-print_page_setup_save (GtkPrintOperation *operation)
+print_page_setup_save (GtkPrintOperation *operation,
+                       gint32             image_ID)
 {
   GtkPageSetup *setup;
-  gchar        *filename;
-  GError       *error = NULL;
+  GKeyFile     *key_file;
 
-  setup = gtk_print_operation_get_default_page_setup (operation);
+  g_return_if_fail (GTK_IS_PRINT_OPERATION (operation));
 
-  filename = g_build_filename (gimp_directory (), "print-page-setup", NULL);
+  key_file = g_key_file_new ();
 
-  gtk_page_setup_to_file (setup, filename, &error);
+  setup = gtk_print_operation_get_default_page_setup (operation);
 
-  if (error)
-    {
-      g_message ("Error saving page setup as resource file: %s",
-                 error->message);
-      g_error_free (error);
-    }
+  gtk_page_setup_to_key_file (setup, key_file, PRINT_PAGE_SETUP_NAME);
+
+  print_utils_key_file_save_as_parasite (key_file,
+                                         image_ID, PRINT_PAGE_SETUP_NAME);
+  print_utils_key_file_save_as_rcfile (key_file,
+                                       PRINT_PAGE_SETUP_NAME);
 
-  g_free (filename);
+  g_key_file_free (key_file);
 }

Modified: branches/weskaggs/plug-ins/print/print-page-setup.h
==============================================================================
--- branches/weskaggs/plug-ins/print/print-page-setup.h	(original)
+++ branches/weskaggs/plug-ins/print/print-page-setup.h	Tue Mar  4 03:15:17 2008
@@ -17,9 +17,10 @@
  */
 
 
-void      print_page_setup_dialog (GtkPrintOperation *operation);
-gboolean  print_page_setup_load   (GtkPrintOperation *operation,
-                                   gint32             image_ID);
-void      print_page_setup_save   (GtkPrintOperation *operation);
+void   print_page_setup_dialog (GtkPrintOperation *operation);
+void   print_page_setup_load   (GtkPrintOperation *operation,
+                                gint32             image_ID);
+void   print_page_setup_save   (GtkPrintOperation *operation,
+                                gint32             image_ID);
 
 

Modified: branches/weskaggs/plug-ins/print/print-preview.c
==============================================================================
--- branches/weskaggs/plug-ins/print/print-preview.c	(original)
+++ branches/weskaggs/plug-ins/print/print-preview.c	Tue Mar  4 03:15:17 2008
@@ -24,9 +24,6 @@
 #include "print-preview.h"
 
 
-#define DRAWING_AREA_SIZE 200
-
-
 enum
 {
   OFFSETS_CHANGED,
@@ -34,36 +31,91 @@
 };
 
 
-static void      gimp_print_preview_finalize         (GObject          *object);
+#define SIZE_REQUEST  200
+
+
+struct _PrintPreview
+{
+  GtkEventBox      parent_instance;
+
+  GdkCursor       *cursor;
+
+  GtkPageSetup    *page;
+  cairo_surface_t *thumbnail;
+  gboolean         dragging;
+  gboolean         inside;
+
+  GimpDrawable    *drawable;
 
-static void      gimp_print_preview_size_allocate    (GtkWidget        *widget,
-                                                      GtkAllocation    *allocation,
-                                                      GimpPrintPreview *preview);
-static void      gimp_print_preview_realize          (GtkWidget        *widget);
-static gboolean  gimp_print_preview_event            (GtkWidget        *widget,
-                                                      GdkEvent         *event,
-                                                      GimpPrintPreview *preview);
+  gdouble          image_offset_x;
+  gdouble          image_offset_y;
+  gdouble          image_offset_x_max;
+  gdouble          image_offset_y_max;
+  gdouble          image_width;
+  gdouble          image_height;
 
-static gboolean  gimp_print_preview_expose_event     (GtkWidget        *widget,
-                                                      GdkEventExpose   *eevent,
-                                                      GimpPrintPreview *preview);
+  gboolean         use_full_page;
+
+  /* for mouse drags */
+  gdouble          orig_offset_x;
+  gdouble          orig_offset_y;
+  gint             start_x;
+  gint             start_y;
+};
+
+struct _PrintPreviewClass
+{
+  GtkEventBoxClass  parent_class;
+
+  void (* offsets_changed)  (PrintPreview *print_preview,
+                             gint          offset_x,
+                             gint          offset_y);
+};
 
-static gdouble   gimp_print_preview_get_scale        (GimpPrintPreview *preview);
 
-static void      gimp_print_preview_get_page_margins (GimpPrintPreview *preview,
-                                                      gdouble          *left_margin,
-                                                      gdouble          *right_margin,
-                                                      gdouble          *top_margin,
-                                                      gdouble          *bottom_margin);
+static void      print_preview_finalize             (GObject        *object);
 
-static void      print_preview_queue_draw            (GimpPrintPreview *preview);
+static void      print_preview_realize              (GtkWidget      *widget);
+static void      print_preview_unrealize            (GtkWidget      *widget);
+static void      print_preview_size_request         (GtkWidget      *widget,
+                                                     GtkRequisition *requisition);
+static void      print_preview_size_allocate        (GtkWidget      *widget,
+                                                     GtkAllocation  *allocation);
+static gboolean  print_preview_expose_event         (GtkWidget      *widget,
+                                                     GdkEventExpose *event);
+static gboolean  print_preview_button_press_event   (GtkWidget      *widget,
+                                                     GdkEventButton *event);
+static gboolean  print_preview_button_release_event (GtkWidget      *widget,
+                                                     GdkEventButton *event);
+static gboolean  print_preview_motion_notify_event  (GtkWidget      *widget,
+                                                     GdkEventMotion *event);
+
+static gboolean  print_preview_is_inside            (PrintPreview   *preview,
+                                                     gdouble         x,
+                                                     gdouble         y);
+static void      print_preview_set_inside           (PrintPreview   *preview,
+                                                     gboolean        inside);
+
+static gdouble   print_preview_get_scale            (PrintPreview   *preview);
+
+static void      print_preview_get_page_size        (PrintPreview   *preview,
+                                                     gdouble        *paper_width,
+                                                     gdouble        *paper_height);
+static void      print_preview_get_page_margins     (PrintPreview   *preview,
+                                                     gdouble        *left_margin,
+                                                     gdouble        *right_margin,
+                                                     gdouble        *top_margin,
+                                                     gdouble        *bottom_margin);
+static cairo_surface_t * print_preview_get_thumbnail (GimpDrawable  *drawable,
+                                                      gint           width,
+                                                      gint           height);
 
 
-G_DEFINE_TYPE (GimpPrintPreview, gimp_print_preview, GTK_TYPE_ASPECT_FRAME)
+G_DEFINE_TYPE (PrintPreview, print_preview, GTK_TYPE_EVENT_BOX)
 
-#define parent_class gimp_print_preview_parent_class
+#define parent_class print_preview_parent_class
 
-static guint gimp_print_preview_signals[LAST_SIGNAL] = { 0 };
+static guint print_preview_signals[LAST_SIGNAL] = { 0 };
 
 
 #define g_marshal_value_peek_double(v)   (v)->data[0].v_double
@@ -107,65 +159,52 @@
 }
 
 static void
-gimp_print_preview_class_init (GimpPrintPreviewClass *klass)
+print_preview_class_init (PrintPreviewClass *klass)
 {
-  GObjectClass *object_class = G_OBJECT_CLASS (klass);
+  GObjectClass   *object_class = G_OBJECT_CLASS (klass);
+  GtkWidgetClass *widget_class = GTK_WIDGET_CLASS (klass);
 
-  gimp_print_preview_signals[OFFSETS_CHANGED] =
+  print_preview_signals[OFFSETS_CHANGED] =
     g_signal_new ("offsets-changed",
                   G_TYPE_FROM_CLASS (klass),
                   G_SIGNAL_RUN_FIRST,
-                  G_STRUCT_OFFSET (GimpPrintPreviewClass, offsets_changed),
+                  G_STRUCT_OFFSET (PrintPreviewClass, offsets_changed),
                   NULL, NULL,
                   marshal_VOID__DOUBLE_DOUBLE,
                   G_TYPE_NONE, 2,
                   G_TYPE_DOUBLE,
                   G_TYPE_DOUBLE);
 
-  object_class->finalize = gimp_print_preview_finalize;
+  object_class->finalize             = print_preview_finalize;
+
+  widget_class->realize              = print_preview_realize;
+  widget_class->unrealize            = print_preview_unrealize;
+  widget_class->size_request         = print_preview_size_request;
+  widget_class->size_allocate        = print_preview_size_allocate;
+  widget_class->expose_event         = print_preview_expose_event;
+  widget_class->button_press_event   = print_preview_button_press_event;
+  widget_class->button_release_event = print_preview_button_release_event;
+  widget_class->motion_notify_event  = print_preview_motion_notify_event;
 
   klass->offsets_changed = NULL;
 }
 
 static void
-gimp_print_preview_init (GimpPrintPreview *preview)
+print_preview_init (PrintPreview *preview)
 {
-  preview->page               = NULL;
-  preview->pixbuf             = NULL;
-  preview->dragging           = FALSE;
-  preview->image_offset_x     = 0.0;
-  preview->image_offset_y     = 0.0;
-  preview->image_offset_x_max = 0.0;
-  preview->image_offset_y_max = 0.0;
-  preview->image_xres         = 1.0;
-  preview->image_yres         = 1.0;
-  preview->use_full_page      = FALSE;
-
-  preview->area = gtk_drawing_area_new();
-  gtk_container_add (GTK_CONTAINER (preview), preview->area);
-  gtk_widget_show (preview->area);
-
-  gtk_widget_add_events (GTK_WIDGET (preview->area), GDK_BUTTON_PRESS_MASK);
-
-  g_signal_connect (preview->area, "size-allocate",
-                    G_CALLBACK (gimp_print_preview_size_allocate),
-                    preview);
-  g_signal_connect (preview->area, "realize",
-                    G_CALLBACK (gimp_print_preview_realize),
-                    NULL);
-  g_signal_connect (preview->area, "event",
-                    G_CALLBACK (gimp_print_preview_event),
-                    preview);
-  g_signal_connect (preview->area, "expose-event",
-                    G_CALLBACK (gimp_print_preview_expose_event),
-                    preview);
+  gtk_event_box_set_visible_window (GTK_EVENT_BOX (preview), FALSE);
+
+  gtk_widget_add_events (GTK_WIDGET (preview),
+                         GDK_BUTTON_PRESS_MASK   |
+                         GDK_BUTTON_RELEASE_MASK |
+                         GDK_POINTER_MOTION_MASK);
 }
 
 
 static void
-gimp_print_preview_finalize (GObject *object)
+print_preview_finalize (GObject *object)
 {
-  GimpPrintPreview *preview = GIMP_PRINT_PREVIEW (object);
+  PrintPreview *preview = PRINT_PREVIEW (object);
 
   if (preview->drawable)
     {
@@ -173,10 +212,10 @@
       preview->drawable = NULL;
     }
 
-  if (preview->pixbuf)
+  if (preview->thumbnail)
     {
-      g_object_unref (preview->pixbuf);
-      preview->pixbuf = NULL;
+      cairo_surface_destroy (preview->thumbnail);
+      preview->thumbnail = NULL;
     }
 
   if (preview->page)
@@ -185,372 +224,510 @@
       preview->page = NULL;
     }
 
-  G_OBJECT_CLASS (gimp_print_preview_parent_class)->finalize (object);
+  G_OBJECT_CLASS (print_preview_parent_class)->finalize (object);
+}
+
+static void
+print_preview_realize (GtkWidget *widget)
+{
+  PrintPreview *preview = PRINT_PREVIEW (widget);
+
+  GTK_WIDGET_CLASS (print_preview_parent_class)->realize (widget);
+
+  preview->cursor = gdk_cursor_new_for_display (gtk_widget_get_display (widget),
+                                                GDK_HAND1);
+}
+
+static void
+print_preview_unrealize (GtkWidget *widget)
+{
+  PrintPreview *preview = PRINT_PREVIEW (widget);
+
+  if (preview->cursor)
+    gdk_cursor_unref (preview->cursor);
+
+  GTK_WIDGET_CLASS (print_preview_parent_class)->unrealize (widget);
+}
+
+static void
+print_preview_size_request (GtkWidget      *widget,
+                            GtkRequisition *requisition)
+{
+  PrintPreview *preview = PRINT_PREVIEW (widget);
+  gdouble       paper_width;
+  gdouble       paper_height;
+  gint          border  = GTK_CONTAINER (widget)->border_width + 1;
+
+  print_preview_get_page_size (preview, &paper_width, &paper_height);
+
+  if (paper_width > paper_height)
+    {
+      requisition->height = SIZE_REQUEST;
+      requisition->width  = paper_width * SIZE_REQUEST / paper_height;
+      requisition->width  = MIN (requisition->width, 2 * SIZE_REQUEST);
+    }
+  else
+    {
+      requisition->width  = SIZE_REQUEST;
+      requisition->height = paper_height * SIZE_REQUEST / paper_width;
+      requisition->height = MIN (requisition->height, 2 * SIZE_REQUEST);
+    }
+
+  requisition->width  += 2 * border;
+  requisition->height += 2 * border;
+}
+
+static void
+print_preview_size_allocate (GtkWidget     *widget,
+                             GtkAllocation *allocation)
+{
+  PrintPreview *preview = PRINT_PREVIEW (widget);
+
+  GTK_WIDGET_CLASS (print_preview_parent_class)->size_allocate (widget,
+                                                                allocation);
+
+  if (preview->thumbnail)
+    {
+      cairo_surface_destroy (preview->thumbnail);
+      preview->thumbnail = NULL;
+    }
+}
+
+static gboolean
+print_preview_button_press_event (GtkWidget      *widget,
+                                  GdkEventButton *event)
+{
+  PrintPreview *preview = PRINT_PREVIEW (widget);
+
+  if (event->type == GDK_BUTTON_PRESS && event->button == 1 && preview->inside)
+    {
+      GdkCursor *cursor;
+
+      cursor = gdk_cursor_new_for_display (gtk_widget_get_display (widget),
+                                           GDK_FLEUR);
+
+      if (gdk_pointer_grab (event->window, FALSE,
+                            (GDK_BUTTON1_MOTION_MASK |
+                             GDK_BUTTON_RELEASE_MASK),
+                            NULL, cursor, event->time) == GDK_GRAB_SUCCESS)
+        {
+          preview->orig_offset_x = preview->image_offset_x;
+          preview->orig_offset_y = preview->image_offset_y;
+
+          preview->start_x = event->x;
+          preview->start_y = event->y;
+
+          preview->dragging = TRUE;
+        }
+
+      gdk_cursor_unref (cursor);
+    }
+
+  return FALSE;
+}
+
+static gboolean
+print_preview_button_release_event (GtkWidget      *widget,
+                                    GdkEventButton *event)
+{
+  PrintPreview *preview = PRINT_PREVIEW (widget);
+
+  if (preview->dragging)
+    {
+      gdk_display_pointer_ungrab (gtk_widget_get_display (widget),
+                                  event->time);
+      preview->dragging = FALSE;
+
+      print_preview_set_inside (preview,
+                                print_preview_is_inside (preview,
+                                                         event->x, event->y));
+    }
+
+  return FALSE;
+}
+
+static gboolean
+print_preview_motion_notify_event (GtkWidget      *widget,
+                                   GdkEventMotion *event)
+{
+  PrintPreview *preview = PRINT_PREVIEW (widget);
+
+  if (preview->dragging)
+    {
+      gdouble scale = print_preview_get_scale (preview);
+      gdouble offset_x;
+      gdouble offset_y;
+
+      offset_x = (preview->orig_offset_x +
+                  (event->x - preview->start_x) / scale);
+      offset_y = (preview->orig_offset_y +
+                  (event->y - preview->start_y) / scale);
+
+      offset_x = CLAMP (offset_x, 0, preview->image_offset_x_max);
+      offset_y = CLAMP (offset_y, 0, preview->image_offset_y_max);
+
+      if (preview->image_offset_x != offset_x ||
+          preview->image_offset_y != offset_y)
+        {
+          print_preview_set_image_offsets (preview,
+                                           offset_x, offset_y);
+
+          g_signal_emit (preview,
+                         print_preview_signals[OFFSETS_CHANGED], 0,
+                         preview->image_offset_x,
+                         preview->image_offset_y);
+        }
+    }
+  else
+    {
+      print_preview_set_inside (preview,
+                                print_preview_is_inside (preview,
+                                                         event->x, event->y));
+    }
+
+  return FALSE;
+}
+
+static gboolean
+print_preview_expose_event (GtkWidget      *widget,
+                            GdkEventExpose *event)
+{
+  PrintPreview *preview = PRINT_PREVIEW (widget);
+  cairo_t      *cr;
+  gdouble       paper_width;
+  gdouble       paper_height;
+  gdouble       left_margin;
+  gdouble       right_margin;
+  gdouble       top_margin;
+  gdouble       bottom_margin;
+  gdouble       scale;
+  gint          border = GTK_CONTAINER (widget)->border_width + 1;
+
+  print_preview_get_page_size (preview, &paper_width, &paper_height);
+  print_preview_get_page_margins (preview,
+                                  &left_margin, &right_margin,
+                                  &top_margin,  &bottom_margin);
+
+  scale = print_preview_get_scale (preview);
+
+  cr = gdk_cairo_create (widget->window);
+
+  cairo_translate (cr,
+                   widget->allocation.x + border,
+                   widget->allocation.y + border);
+
+  if (gtk_widget_get_direction (widget) == GTK_TEXT_DIR_RTL)
+    {
+      gint width = widget->allocation.width - 2 * border;
+
+      cairo_translate (cr, width - scale * paper_width, 0);
+    }
+
+  cairo_set_line_width (cr, 1.0);
+
+  /* draw page background */
+  cairo_rectangle (cr, 0, 0, scale * paper_width, scale * paper_height);
+
+  gdk_cairo_set_source_color (cr, &widget->style->black);
+  cairo_stroke_preserve (cr);
+
+  gdk_cairo_set_source_color (cr, &widget->style->white);
+  cairo_fill (cr);
+
+  /* draw page_margins */
+  cairo_rectangle (cr,
+                   scale * left_margin,
+                   scale * top_margin,
+                   scale * (paper_width - left_margin - right_margin),
+                   scale * (paper_height - top_margin - bottom_margin));
+
+  gdk_cairo_set_source_color (cr, &widget->style->mid[widget->state]);
+  cairo_stroke (cr);
+
+  cairo_translate (cr,
+                   scale * (left_margin + preview->image_offset_x),
+                   scale * (top_margin  + preview->image_offset_y));
+
+  if (preview->dragging || preview->inside)
+    {
+      cairo_rectangle (cr,
+                       0, 0,
+                       scale * preview->image_width,
+                       scale * preview->image_height);
+
+      gdk_cairo_set_source_color (cr, &widget->style->black);
+      cairo_stroke (cr);
+    }
+
+  if (preview->thumbnail == NULL &&
+      gimp_drawable_is_valid (preview->drawable->drawable_id))
+    {
+      preview->thumbnail =
+        print_preview_get_thumbnail (preview->drawable,
+                                     MIN (widget->allocation.width,  1024),
+                                     MIN (widget->allocation.height, 1024));
+    }
+
+  if (preview->thumbnail != NULL)
+    {
+      gdouble scale_x;
+      gdouble scale_y;
+
+      scale_x = (preview->image_width  /
+                 cairo_image_surface_get_width (preview->thumbnail));
+      scale_y = (preview->image_height /
+                 cairo_image_surface_get_height (preview->thumbnail));
+
+      cairo_rectangle (cr, 0, 0, preview->image_width, preview->image_height);
+
+      cairo_scale (cr, scale_x * scale, scale_y * scale);
+
+      cairo_set_source_surface (cr, preview->thumbnail, 0, 0);
+      cairo_fill (cr);
+    }
+
+  cairo_destroy (cr);
+
+  return FALSE;
 }
 
 /**
- * gimp_print_preview_new:
+ * print_preview_new:
  * @page: page setup
  * @drawable_id: the drawable to print
  *
- * Creates a new #GimpPrintPreview widget.
+ * Creates a new #PrintPreview widget.
  *
- * Return value: the new #GimpPrintPreview widget.
+ * Return value: the new #PrintPreview widget.
  **/
 GtkWidget *
-gimp_print_preview_new (GtkPageSetup *page,
-                        gint32        drawable_id)
+print_preview_new (GtkPageSetup *page,
+                   gint32        drawable_id)
 {
-  GimpPrintPreview *preview;
-  gfloat            ratio;
+  PrintPreview *preview;
 
-  preview = g_object_new (GIMP_TYPE_PRINT_PREVIEW, NULL);
+  g_return_val_if_fail (GTK_IS_PAGE_SETUP (page), NULL);
 
-  preview->drawable = gimp_drawable_get (drawable_id);
+  preview = g_object_new (PRINT_TYPE_PREVIEW, NULL);
 
-  if (page != NULL)
-    preview->page = gtk_page_setup_copy (page);
-  else
-    preview->page = gtk_page_setup_new ();
-
-  ratio = (gtk_page_setup_get_paper_width (preview->page, GTK_UNIT_POINTS) /
-           gtk_page_setup_get_paper_height (preview->page, GTK_UNIT_POINTS));
-
-  gtk_aspect_frame_set (GTK_ASPECT_FRAME (preview), 0.5, 0.5, ratio, FALSE);
+  preview->drawable = gimp_drawable_get (drawable_id);
 
-  gtk_widget_set_size_request (preview->area,
-                               DRAWING_AREA_SIZE, DRAWING_AREA_SIZE);
+  print_preview_set_page_setup (preview, page);
 
   return GTK_WIDGET (preview);
 }
 
 /**
- * gimp_print_preview_set_image_dpi:
- * @preview: a #GimpPrintPreview.
+ * print_preview_set_image_dpi:
+ * @preview: a #PrintPreview.
  * @xres: the X resolution
  * @yres: the Y resolution
  *
  * Sets the resolution of the image/drawable displayed by the
- * #GimpPrintPreview.
+ * #PrintPreview.
  **/
 void
-gimp_print_preview_set_image_dpi (GimpPrintPreview *preview,
-                                  gdouble           xres,
-                                  gdouble           yres)
+print_preview_set_image_dpi (PrintPreview *preview,
+                             gdouble       xres,
+                             gdouble       yres)
 {
-  g_return_if_fail (GIMP_IS_PRINT_PREVIEW (preview));
+  gdouble width;
+  gdouble height;
+
+  g_return_if_fail (PRINT_IS_PREVIEW (preview));
+  g_return_if_fail (xres > 0.0 && yres > 0.0);
 
-  if (preview->image_xres != xres || preview->image_yres != yres)
+  width  = preview->drawable->width  * 72.0 / xres;
+  height = preview->drawable->height * 72.0 / yres;
+
+  if (width != preview->image_width || height != preview->image_height)
     {
-      preview->image_xres = xres;
-      preview->image_yres = yres;
+      preview->image_width  = width;
+      preview->image_height = height;
 
-      print_preview_queue_draw (preview);
+      gtk_widget_queue_draw (GTK_WIDGET (preview));
     }
 }
 
 /**
- * gimp_print_preview_set_page_setup:
- * @preview: a #GimpPrintPreview.
+ * print_preview_set_page_setup:
+ * @preview: a #PrintPreview.
  * @page: the page setup to use
  *
- * Sets the page setup to use by the #GimpPrintPreview.
+ * Sets the page setup to use by the #PrintPreview.
  **/
 void
-gimp_print_preview_set_page_setup (GimpPrintPreview *preview,
-                                   GtkPageSetup     *page)
+print_preview_set_page_setup (PrintPreview *preview,
+                              GtkPageSetup *page)
 {
-  gfloat ratio;
+  g_return_if_fail (PRINT_IS_PREVIEW (preview));
+  g_return_if_fail (GTK_IS_PAGE_SETUP (page));
 
   if (preview->page)
     g_object_unref (preview->page);
 
   preview->page = gtk_page_setup_copy (page);
 
-  ratio = (gtk_page_setup_get_paper_width (page, GTK_UNIT_POINTS) /
-           gtk_page_setup_get_paper_height (page, GTK_UNIT_POINTS));
-
-  gtk_aspect_frame_set (GTK_ASPECT_FRAME (preview), 0.5, 0.5, ratio, FALSE);
-
-  print_preview_queue_draw (preview);
+  gtk_widget_queue_resize (GTK_WIDGET (preview));
 }
 
 /**
- * gimp_print_preview_set_image_offsets:
- * @preview: a #GimpPrintPreview.
+ * print_preview_set_image_offsets:
+ * @preview: a #PrintPreview.
  * @offset_x: the X offset
  * @offset_y: the Y offset
  *
- * Sets the offsets of the image/drawable displayed by the #GimpPrintPreview.
+ * Sets the offsets of the image/drawable displayed by the #PrintPreview.
  * It does not emit the "offsets-changed" signal.
  **/
 void
-gimp_print_preview_set_image_offsets (GimpPrintPreview *preview,
-                                      gdouble           offset_x,
-                                      gdouble           offset_y)
+print_preview_set_image_offsets (PrintPreview *preview,
+                                 gdouble       offset_x,
+                                 gdouble       offset_y)
 {
-  g_return_if_fail (GIMP_IS_PRINT_PREVIEW (preview));
+  g_return_if_fail (PRINT_IS_PREVIEW (preview));
 
   preview->image_offset_x = offset_x;
   preview->image_offset_y = offset_y;
 
-  print_preview_queue_draw (preview);
+  gtk_widget_queue_draw (GTK_WIDGET (preview));
 }
 
 /**
- * gimp_print_preview_set_image_offsets_max:
- * @preview: a #GimpPrintPreview.
+ * print_preview_set_image_offsets_max:
+ * @preview: a #PrintPreview.
  * @offset_x_max: the maximum X offset allowed
  * @offset_y_max: the maximum Y offset allowed
  *
  * Sets the maximum offsets of the image/drawable displayed by the
- * #GimpPrintPreview.  It does not emit the "offsets-changed" signal.
+ * #PrintPreview.  It does not emit the "offsets-changed" signal.
  **/
 void
-gimp_print_preview_set_image_offsets_max (GimpPrintPreview *preview,
-                                          gdouble           offset_x_max,
-                                          gdouble           offset_y_max)
+print_preview_set_image_offsets_max (PrintPreview *preview,
+                                     gdouble       offset_x_max,
+                                     gdouble       offset_y_max)
 {
-  g_return_if_fail (GIMP_IS_PRINT_PREVIEW (preview));
+  g_return_if_fail (PRINT_IS_PREVIEW (preview));
 
   preview->image_offset_x_max = offset_x_max;
   preview->image_offset_y_max = offset_y_max;
 
-  print_preview_queue_draw (preview);
+  gtk_widget_queue_draw (GTK_WIDGET (preview));
 }
 
 /**
- * gimp_print_preview_set_use_full_page:
- * @preview: a #GimpPrintPreview.
+ * print_preview_set_use_full_page:
+ * @preview: a #PrintPreview.
  * @full_page: TRUE to ignore the page margins
  *
  * If @full_page is TRUE, the page margins are ignored and the full page
  * can be used to setup printing.
  **/
 void
-gimp_print_preview_set_use_full_page (GimpPrintPreview *preview,
-                                      gboolean          full_page)
+print_preview_set_use_full_page (PrintPreview *preview,
+                                 gboolean      full_page)
 {
-  g_return_if_fail (GIMP_IS_PRINT_PREVIEW (preview));
+  g_return_if_fail (PRINT_IS_PREVIEW (preview));
 
   preview->use_full_page = full_page;
 
-  print_preview_queue_draw (preview);
-}
-
-static void
-gimp_print_preview_realize (GtkWidget *widget)
-{
-  GdkCursor *cursor;
-
-  cursor = gdk_cursor_new_for_display (gtk_widget_get_display (widget),
-                                       GDK_FLEUR);
-  gdk_window_set_cursor (widget->window, cursor);
-  gdk_cursor_unref (cursor);
+  gtk_widget_queue_draw (GTK_WIDGET (preview));
 }
 
 static gboolean
-gimp_print_preview_event (GtkWidget        *widget,
-                          GdkEvent         *event,
-                          GimpPrintPreview *preview)
-{
-  static gdouble orig_offset_x = 0.0;
-  static gdouble orig_offset_y = 0.0;
-  static gint    start_x       = 0;
-  static gint    start_y       = 0;
-
-  gdouble        offset_x;
-  gdouble        offset_y;
-  gdouble        scale;
-
-  switch (event->type)
-    {
-    case GDK_BUTTON_PRESS:
-      gdk_pointer_grab (widget->window, FALSE,
-                        (GDK_BUTTON1_MOTION_MASK |
-                         GDK_BUTTON_RELEASE_MASK),
-                        NULL, NULL, event->button.time);
-
-      orig_offset_x = preview->image_offset_x;
-      orig_offset_y = preview->image_offset_y;
-
-      start_x = event->button.x;
-      start_y = event->button.y;
-
-      preview->dragging = TRUE;
-      break;
-
-    case GDK_MOTION_NOTIFY:
-      scale = gimp_print_preview_get_scale (preview);
-
-      offset_x = (orig_offset_x + (event->motion.x - start_x) / scale);
-      offset_y = (orig_offset_y + (event->motion.y - start_y) / scale);
-
-      offset_x = CLAMP (offset_x, 0, preview->image_offset_x_max);
-      offset_y = CLAMP (offset_y, 0, preview->image_offset_y_max);
+print_preview_is_inside (PrintPreview *preview,
+                         gdouble       x,
+                         gdouble       y)
+{
+  GtkWidget *widget = GTK_WIDGET (preview);
+  gdouble    left_margin;
+  gdouble    right_margin;
+  gdouble    top_margin;
+  gdouble    bottom_margin;
+  gdouble    scale;
+  gint       border = GTK_CONTAINER (widget)->border_width + 1;
 
-      if (preview->image_offset_x != offset_x ||
-          preview->image_offset_y != offset_y)
-        {
-          gimp_print_preview_set_image_offsets (preview, offset_x, offset_y);
+  x -= border;
 
-          g_signal_emit (preview,
-                         gimp_print_preview_signals[OFFSETS_CHANGED], 0,
-                         preview->image_offset_x, preview->image_offset_y);
-        }
-      break;
+  scale = print_preview_get_scale (preview);
 
-    case GDK_BUTTON_RELEASE:
-      gdk_display_pointer_ungrab (gtk_widget_get_display (widget),
-                                  event->button.time);
-      start_x = start_y = 0;
-      preview->dragging = FALSE;
+  if (gtk_widget_get_direction (widget) == GTK_TEXT_DIR_RTL)
+    {
+      gdouble paper_width;
+      gdouble paper_height;
+      gint    width = widget->allocation.width - 2 * border;
 
-      print_preview_queue_draw (preview);
-      break;
+      print_preview_get_page_size (preview, &paper_width, &paper_height);
 
-    default:
-      break;
+      x -= width - scale * paper_width;
     }
 
-  return FALSE;
-}
-
-static gboolean
-gimp_print_preview_expose_event (GtkWidget        *widget,
-                                 GdkEventExpose   *eevent,
-                                 GimpPrintPreview *preview)
-{
-  gdouble  paper_width;
-  gdouble  paper_height;
-  gdouble  left_margin;
-  gdouble  right_margin;
-  gdouble  top_margin;
-  gdouble  bottom_margin;
-  gdouble  scale;
-  cairo_t *cr;
-
-  paper_width = gtk_page_setup_get_paper_width (preview->page,
-                                                GTK_UNIT_POINTS);
-  paper_height = gtk_page_setup_get_paper_height (preview->page,
-                                                  GTK_UNIT_POINTS);
-  gimp_print_preview_get_page_margins (preview,
-                                       &left_margin,
-                                       &right_margin,
-                                       &top_margin,
-                                       &bottom_margin);
-
-  cr = gdk_cairo_create (widget->window);
-
-  scale = gimp_print_preview_get_scale (preview);
+  print_preview_get_page_margins (preview,
+                                  &left_margin, &right_margin,
+                                  &top_margin,  &bottom_margin);
 
-  /* draw background */
-  cairo_scale (cr, scale, scale);
-  gdk_cairo_set_source_color (cr, &widget->style->white);
-  cairo_rectangle (cr, 0, 0, paper_width, paper_height);
-  cairo_fill (cr);
-
-  /* draw page_margins */
-  gdk_cairo_set_source_color (cr, &widget->style->black);
-  cairo_rectangle (cr,
-                   left_margin,
-                   top_margin,
-                   paper_width - left_margin - right_margin,
-                   paper_height - top_margin - bottom_margin);
-  cairo_stroke (cr);
+  x = x / scale - left_margin;
+  y = y / scale - top_margin;
 
-  if (preview->dragging)
-    {
-      gdouble width  = preview->drawable->width;
-      gdouble height = preview->drawable->height;
+  return (x > preview->image_offset_x                        &&
+          x < preview->image_offset_x + preview->image_width &&
+          y > preview->image_offset_y                        &&
+          y < preview->image_offset_y + preview->image_height);
+}
 
-      cairo_rectangle (cr,
-                       left_margin + preview->image_offset_x,
-                       top_margin  + preview->image_offset_y,
-                       width  * 72.0 / preview->image_xres,
-                       height * 72.0 / preview->image_yres);
-      cairo_stroke (cr);
-    }
-  else
+static void
+print_preview_set_inside (PrintPreview *preview,
+                          gboolean      inside)
+{
+  if (inside != preview->inside)
     {
-      gint32 drawable_id = preview->drawable->drawable_id;
+      GtkWidget *widget = GTK_WIDGET (preview);
 
-      /* draw image */
-      cairo_translate (cr,
-                       left_margin + preview->image_offset_x,
-                       top_margin  + preview->image_offset_y);
+      preview->inside = inside;
 
-      if (preview->pixbuf == NULL && gimp_drawable_is_valid (drawable_id))
-        {
-          gint width  = MIN (widget->allocation.width, 1024);
-          gint height = MIN (widget->allocation.height, 1024);
-
-          preview->pixbuf = gimp_drawable_get_thumbnail (drawable_id,
-                                                         width, height,
-                                                         GIMP_PIXBUF_KEEP_ALPHA);
-        }
+      if (GTK_WIDGET_DRAWABLE (widget))
+        gdk_window_set_cursor (widget->window,
+                               inside ? preview->cursor : NULL);
 
-      if (preview->pixbuf != NULL)
-        {
-          gdouble scale_x = ((gdouble) preview->drawable->width /
-                             gdk_pixbuf_get_width (preview->pixbuf));
-          gdouble scale_y = ((gdouble) preview->drawable->height /
-                             gdk_pixbuf_get_height (preview->pixbuf));
-
-          if (scale_x < scale_y)
-            scale_x = scale_y;
-          else
-            scale_y = scale_x;
-
-          scale_x = scale_x * 72.0 / preview->image_xres;
-          scale_y = scale_y * 72.0 / preview->image_yres;
-
-          cairo_scale (cr, scale_x, scale_y);
-
-          gdk_cairo_set_source_pixbuf (cr, preview->pixbuf, 0, 0);
-
-          cairo_paint (cr);
-        }
+      gtk_widget_queue_draw (widget);
     }
-
-  cairo_destroy (cr);
-
-  return FALSE;
 }
 
 static gdouble
-gimp_print_preview_get_scale (GimpPrintPreview* preview)
+print_preview_get_scale (PrintPreview *preview)
 {
-  gdouble scale_x;
-  gdouble scale_y;
+  GtkWidget *widget = GTK_WIDGET (preview);
+  gdouble    paper_width;
+  gdouble    paper_height;
+  gdouble    scale_x;
+  gdouble    scale_y;
+  gint       border = GTK_CONTAINER (widget)->border_width + 1;
 
-  scale_x = ((gdouble) preview->area->allocation.width /
-             gtk_page_setup_get_paper_width (preview->page, GTK_UNIT_POINTS));
+  print_preview_get_page_size (preview, &paper_width, &paper_height);
 
-  scale_y = ((gdouble) preview->area->allocation.height /
-             gtk_page_setup_get_paper_height (preview->page, GTK_UNIT_POINTS));
+  scale_x = (gdouble) (widget->allocation.width  - 2 * border) / paper_width;
+  scale_y = (gdouble) (widget->allocation.height - 2 * border) / paper_height;
 
   return MIN (scale_x, scale_y);
 }
 
 static void
-gimp_print_preview_size_allocate (GtkWidget        *widget,
-                                  GtkAllocation    *allocation,
-                                  GimpPrintPreview *preview)
-{
-  if (preview->pixbuf != NULL)
-    {
-      g_object_unref (preview->pixbuf);
-      preview->pixbuf = NULL;
-    }
+print_preview_get_page_size (PrintPreview *preview,
+                             gdouble      *paper_width,
+                             gdouble      *paper_height)
+{
+  *paper_width  = gtk_page_setup_get_paper_width  (preview->page,
+                                                   GTK_UNIT_POINTS);
+  *paper_height = gtk_page_setup_get_paper_height (preview->page,
+                                                   GTK_UNIT_POINTS);
 }
 
 static void
-gimp_print_preview_get_page_margins (GimpPrintPreview *preview,
-                                     gdouble          *left_margin,
-                                     gdouble          *right_margin,
-                                     gdouble          *top_margin,
-                                     gdouble          *bottom_margin)
+print_preview_get_page_margins (PrintPreview *preview,
+                                gdouble      *left_margin,
+                                gdouble      *right_margin,
+                                gdouble      *top_margin,
+                                gdouble      *bottom_margin)
 {
   if (preview->use_full_page)
     {
@@ -561,19 +738,114 @@
     }
   else
     {
-      *left_margin   = gtk_page_setup_get_left_margin (preview->page,
-                                                       GTK_UNIT_POINTS);
-      *right_margin  = gtk_page_setup_get_right_margin (preview->page,
-                                                        GTK_UNIT_POINTS);
-      *top_margin    = gtk_page_setup_get_top_margin (preview->page,
-                                                      GTK_UNIT_POINTS);
+      *left_margin   = gtk_page_setup_get_left_margin   (preview->page,
+                                                         GTK_UNIT_POINTS);
+      *right_margin  = gtk_page_setup_get_right_margin  (preview->page,
+                                                         GTK_UNIT_POINTS);
+      *top_margin    = gtk_page_setup_get_top_margin    (preview->page,
+                                                         GTK_UNIT_POINTS);
       *bottom_margin = gtk_page_setup_get_bottom_margin (preview->page,
                                                          GTK_UNIT_POINTS);
     }
 }
 
-static void
-print_preview_queue_draw (GimpPrintPreview *preview)
-{
-  gtk_widget_queue_draw (GTK_WIDGET (preview->area));
+
+/*  This thumbnail code should eventually end up in libgimpui.  */
+
+static cairo_surface_t *
+print_preview_get_thumbnail (GimpDrawable *drawable,
+                             gint          width,
+                             gint          height)
+{
+  cairo_surface_t *surface;
+  cairo_format_t   format;
+  guchar          *data;
+  guchar          *dest;
+  const guchar    *src;
+  gint             src_stride;
+  gint             dest_stride;
+  gint             y;
+  gint             bpp;
+
+  g_return_val_if_fail (width  > 0 && width  <= 1024, NULL);
+  g_return_val_if_fail (height > 0 && height <= 1024, NULL);
+
+  data = gimp_drawable_get_thumbnail_data (drawable->drawable_id,
+                                           &width, &height, &bpp);
+
+  switch (bpp)
+    {
+    case 1:
+    case 3:
+      format = CAIRO_FORMAT_RGB24;
+      break;
+    case 2:
+    case 4:
+      format = CAIRO_FORMAT_ARGB32;
+      break;
+    default:
+      g_assert_not_reached ();
+      break;
+    }
+
+  surface = cairo_image_surface_create (format, width, height);
+
+  src         = data;
+  src_stride  = width * bpp;
+
+  dest        = cairo_image_surface_get_data (surface);
+  dest_stride = cairo_image_surface_get_stride (surface);
+
+  for (y = 0; y < height; y++)
+    {
+      const guchar *s = src;
+      guchar       *d = dest;
+      gint          w = width;
+
+      switch (bpp)
+        {
+        case 1:
+          while (w--)
+            {
+              GIMP_CAIRO_RGB24_SET_PIXEL (d, s[0], s[0], s[0]);
+              s += 1;
+              d += 4;
+            }
+          break;
+
+        case 2:
+          while (w--)
+            {
+              GIMP_CAIRO_ARGB32_SET_PIXEL (d, s[0], s[0], s[0], s[1]);
+              s += 2;
+              d += 4;
+            }
+          break;
+
+        case 3:
+          while (w--)
+            {
+              GIMP_CAIRO_RGB24_SET_PIXEL (d, s[0], s[1], s[2]);
+              s += 3;
+              d += 4;
+            }
+          break;
+
+        case 4:
+          while (w--)
+            {
+              GIMP_CAIRO_ARGB32_SET_PIXEL (d, s[0], s[1], s[2], s[3]);
+              s += 4;
+              d += 4;
+            }
+          break;
+        }
+
+      src  += src_stride;
+      dest += dest_stride;
+    }
+
+  g_free (data);
+
+  return surface;
 }

Modified: branches/weskaggs/plug-ins/print/print-preview.h
==============================================================================
--- branches/weskaggs/plug-ins/print/print-preview.h	(original)
+++ branches/weskaggs/plug-ins/print/print-preview.h	Tue Mar  4 03:15:17 2008
@@ -16,76 +16,46 @@
  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
  */
 
-#ifndef __GIMP_PRINT_PREVIEW_H__
-#define __GIMP_PRINT_PREVIEW_H__
+#ifndef __PRINT_PREVIEW_H__
+#define __PRINT_PREVIEW_H__
 
 G_BEGIN_DECLS
 
 
-#define GIMP_TYPE_PRINT_PREVIEW            (gimp_print_preview_get_type ())
-#define GIMP_PRINT_PREVIEW(obj)            (G_TYPE_CHECK_INSTANCE_CAST ((obj), GIMP_TYPE_PRINT_PREVIEW, GimpPrintPreview))
-#define GIMP_PRINT_PREVIEW_CLASS(klass)    (G_TYPE_CHECK_CLASS_CAST ((klass), GIMP_TYPE_PRINT_PREVIEW, GimpPrintPreviewClass))
-#define GIMP_IS_PRINT_PREVIEW(obj)         (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GIMP_TYPE_PRINT_PREVIEW))
-#define GIMP_IS_PRINT_PREVIEW_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GIMP_TYPE_PRINT_PREVIEW))
-#define GIMP_PRINT_PREVIEW_GET_CLASS(obj)  (G_TYPE_INSTANCE_GET_CLASS ((obj), GIMP_TYPE_PRINT_PREVIEW, GimpPrintPreviewClass))
+#define PRINT_TYPE_PREVIEW            (print_preview_get_type ())
+#define PRINT_PREVIEW(obj)            (G_TYPE_CHECK_INSTANCE_CAST ((obj), PRINT_TYPE_PREVIEW, PrintPreview))
+#define PRINT_PREVIEW_CLASS(klass)    (G_TYPE_CHECK_CLASS_CAST ((klass), PRINT_TYPE_PREVIEW, PrintPreviewClass))
+#define PRINT_IS_PREVIEW(obj)         (G_TYPE_CHECK_INSTANCE_TYPE ((obj), PRINT_TYPE_PREVIEW))
+#define PRINT_IS_PREVIEW_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), PRINT_TYPE_PREVIEW))
+#define PRINT_PREVIEW_GET_CLASS(obj)  (G_TYPE_INSTANCE_GET_CLASS ((obj), PRINT_TYPE_PREVIEW, PrintPreviewClass))
 
-typedef struct _GimpPrintPreview       GimpPrintPreview;
-typedef struct _GimpPrintPreviewClass  GimpPrintPreviewClass;
+typedef struct _PrintPreview       PrintPreview;
+typedef struct _PrintPreviewClass  PrintPreviewClass;
 
-struct _GimpPrintPreview
-{
-  GtkAspectFrame  parent_instance;
 
-  GtkWidget      *area;
-  GtkPageSetup   *page;
-  GdkPixbuf      *pixbuf;
-  gboolean        dragging;
+GType       print_preview_get_type              (void) G_GNUC_CONST;
 
-  GimpDrawable   *drawable;
+GtkWidget * print_preview_new                   (GtkPageSetup *page,
+                                                 gint32        drawable_id);
 
-  gdouble         image_offset_x;
-  gdouble         image_offset_y;
-  gdouble         image_offset_x_max;
-  gdouble         image_offset_y_max;
-  gdouble         image_xres;
-  gdouble         image_yres;
+void        print_preview_set_image_dpi         (PrintPreview *preview,
+                                                 gdouble       xres,
+                                                 gdouble       yres);
 
-  gboolean        use_full_page;
-};
+void        print_preview_set_page_setup        (PrintPreview *preview,
+                                                 GtkPageSetup *page);
 
-struct _GimpPrintPreviewClass
-{
-  GtkAspectFrameClass  parent_class;
+void        print_preview_set_image_offsets     (PrintPreview *preview,
+                                                 gdouble       offset_x,
+                                                 gdouble       offset_y);
 
-  void (* offsets_changed)  (GimpPrintPreview *print_preview,
-                             gint              offset_x,
-                             gint              offset_y);
-};
+void        print_preview_set_image_offsets_max (PrintPreview *preview,
+                                                 gdouble       offset_x_max,
+                                                 gdouble       offset_y_max);
 
-
-GType       gimp_print_preview_get_type          (void) G_GNUC_CONST;
-
-GtkWidget * gimp_print_preview_new               (GtkPageSetup     *page,
-                                                  gint32            drawable_id);
-
-void        gimp_print_preview_set_image_dpi     (GimpPrintPreview *preview,
-                                                  gdouble           xres,
-                                                  gdouble           yres);
-
-void        gimp_print_preview_set_page_setup    (GimpPrintPreview *preview,
-                                                  GtkPageSetup     *page);
-
-void        gimp_print_preview_set_image_offsets (GimpPrintPreview *preview,
-                                                  gdouble           offset_x,
-                                                  gdouble           offset_y);
-
-void        gimp_print_preview_set_image_offsets_max (GimpPrintPreview *preview,
-                                                      gdouble           offset_x_max,
-                                                      gdouble           offset_y_max);
-
-void        gimp_print_preview_set_use_full_page (GimpPrintPreview *preview,
-                                                  gboolean          full_page);
+void        print_preview_set_use_full_page     (PrintPreview *preview,
+                                                 gboolean      full_page);
 
 G_END_DECLS
 
-#endif /* __GIMP_PRINT_PREVIEW_H__ */
+#endif /* __PRINT_PREVIEW_H__ */

Modified: branches/weskaggs/plug-ins/print/print-settings.c
==============================================================================
--- branches/weskaggs/plug-ins/print/print-settings.c	(original)
+++ branches/weskaggs/plug-ins/print/print-settings.c	Tue Mar  4 03:15:17 2008
@@ -23,20 +23,18 @@
 
 #include "print.h"
 #include "print-settings.h"
+#include "print-utils.h"
 
 
 #define PRINT_SETTINGS_MAJOR_VERSION 0
 #define PRINT_SETTINGS_MINOR_VERSION 4
 
+#define PRINT_SETTINGS_NAME          "print-settings"
 
-static GKeyFile * print_settings_key_file_from_settings      (PrintData         *data);
-
-static void       save_print_settings_resource_file          (GKeyFile          *settings_key_file);
 
-static void       save_print_settings_as_parasite            (GKeyFile          *settings_key_file,
-                                                              gint32             image_ID);
+static GKeyFile * print_settings_key_file_from_settings      (PrintData         *data);
 
-static void       add_print_setting_to_key_file              (const gchar       *key,
+static void       print_settings_add_to_key_file             (const gchar       *key,
                                                               const gchar       *value,
                                                               gpointer           data);
 
@@ -44,10 +42,10 @@
 
 static GKeyFile * print_settings_key_file_from_parasite      (gint32             image_ID);
 
-static gboolean   load_print_settings_from_key_file          (PrintData         *data,
+static gboolean   print_settings_load_from_key_file          (PrintData         *data,
                                                               GKeyFile          *key_file);
 
-static GKeyFile * check_version                              (GKeyFile          *key_file);
+static gboolean   print_settings_check_version               (GKeyFile          *key_file);
 
 /*
  * set GtkPrintSettings from the contents of a "print-settings"
@@ -55,7 +53,7 @@
  * file of the same name
  */
 gboolean
-load_print_settings (PrintData *data)
+print_settings_load (PrintData *data)
 {
   GKeyFile *key_file = print_settings_key_file_from_parasite (data->image_id);
 
@@ -64,7 +62,7 @@
 
   if (key_file)
     {
-      load_print_settings_from_key_file (data, key_file);
+      print_settings_load_from_key_file (data, key_file);
       g_key_file_free (key_file);
       return TRUE;
     }
@@ -77,13 +75,11 @@
  * and as an image parasite
  */
 void
-save_print_settings (PrintData *data)
+print_settings_save (PrintData *data)
 {
-  GKeyFile *key_file;
-
-  key_file = print_settings_key_file_from_settings (data);
+  GKeyFile *key_file = print_settings_key_file_from_settings (data);
 
-  save_print_settings_resource_file (key_file);
+  print_utils_key_file_save_as_rcfile (key_file, PRINT_SETTINGS_NAME);
 
   /* image setup */
   if (gimp_image_is_valid (data->image_id))
@@ -103,7 +99,9 @@
       g_key_file_set_boolean (key_file, "image-setup",
                               "use-full-page", data->use_full_page);
 
-      save_print_settings_as_parasite (key_file, data->image_id);
+      print_utils_key_file_save_as_parasite (key_file,
+                                             data->image_id,
+                                             PRINT_SETTINGS_NAME);
     }
 
   g_key_file_free (key_file);
@@ -119,8 +117,6 @@
   GtkPrintSettings  *settings;
   GKeyFile          *key_file  = g_key_file_new ();
 
-  g_key_file_set_list_separator (key_file, '=');
-
   /* put version information into the file */
   g_key_file_set_integer (key_file, "meta", "major-version",
                           PRINT_SETTINGS_MAJOR_VERSION);
@@ -129,83 +125,25 @@
 
   /* save the contents of the GtkPrintSettings for the operation */
   settings = gtk_print_operation_get_print_settings (operation);
+
   if (settings)
-    gtk_print_settings_foreach (settings, add_print_setting_to_key_file,
-                                key_file);
+    gtk_print_settings_foreach (settings,
+                                print_settings_add_to_key_file, key_file);
 
   return key_file;
 }
 
 /*
- * create a resource file from a GKeyFile holding the settings
- */
-static void
-save_print_settings_resource_file (GKeyFile *settings_key_file)
-{
-  gchar  *filename;
-  gchar  *contents;
-  gsize   length;
-  GError *error = NULL;
-
-  contents = g_key_file_to_data (settings_key_file, &length, &error);
-  if (error)
-    {
-      g_warning ("Unable to get contents of settings key file: %s",
-                 error->message);
-      g_error_free (error);
-      return;
-    }
-
-  filename = g_build_filename (gimp_directory (), "print-settings", NULL);
-
-  if (! g_file_set_contents (filename, contents, length, &error))
-    {
-      g_warning ("Unable to write print settings to '%s': %s",
-                 gimp_filename_to_utf8 (filename), error->message);
-      g_error_free (error);
-    }
-
-  g_free (filename);
-  g_free (contents);
-}
-
-/*
- * create an image parasite called "print-settings" from a GKeyFile
- * holding the print settings
- */
-static void
-save_print_settings_as_parasite (GKeyFile *settings_key_file,
-                                 gint32    image_ID)
-{
-  gchar     *contents;
-  gsize      length;
-  GError    *error = NULL;
-
-  contents = g_key_file_to_data (settings_key_file, &length, &error);
-  if (! contents)
-    {
-      g_warning ("Unable to get contents of settings key file: %s",
-                 error->message);
-      g_error_free (error);
-      return;
-    }
-
-  gimp_image_attach_new_parasite (image_ID, "print-settings",
-                                  0, length, contents);
-  g_free (contents);
-}
-
-/*
  * callback used in gtk_print_settings_foreach loop
  */
 static void
-add_print_setting_to_key_file (const gchar *key,
-                               const gchar *value,
-                               gpointer     data)
+print_settings_add_to_key_file (const gchar *key,
+                                const gchar *value,
+                                gpointer     data)
 {
   GKeyFile *key_file = data;
 
-  g_key_file_set_value (key_file, "print-settings", key, value);
+  g_key_file_set_value (key_file, PRINT_SETTINGS_NAME, key, value);
 }
 
 /*
@@ -214,22 +152,17 @@
 static GKeyFile *
 print_settings_key_file_from_resource_file (void)
 {
-  GKeyFile  *key_file = g_key_file_new ();
-  gchar     *filename;
-
-  g_key_file_set_list_separator (key_file, '=');
+  GKeyFile *key_file;
 
-  filename = g_build_filename (gimp_directory (), "print-settings", NULL);
+  key_file = print_utils_key_file_load_from_rcfile (PRINT_SETTINGS_NAME);
 
-  if (! g_key_file_load_from_file (key_file, filename, G_KEY_FILE_NONE, NULL))
+  if (key_file && ! print_settings_check_version (key_file))
     {
       g_key_file_free (key_file);
-      key_file = NULL;
+      return NULL;
     }
 
-  g_free (filename);
-
-  return check_version (key_file);
+  return key_file;
 }
 
 /* load information from an image parasite called "print-settings"
@@ -239,34 +172,22 @@
 static GKeyFile *
 print_settings_key_file_from_parasite (gint32 image_ID)
 {
-  GimpParasite *parasite;
-  GKeyFile     *key_file;
-
-  parasite = gimp_image_parasite_find (image_ID, "print-settings");
-
-  if (! parasite)
-    return NULL;
-
-  key_file = g_key_file_new ();
+  GKeyFile *key_file;
 
-  g_key_file_set_list_separator (key_file, '=');
+  key_file = print_utils_key_file_load_from_parasite (image_ID,
+                                                      PRINT_SETTINGS_NAME);
 
-  if (! g_key_file_load_from_data (key_file,
-                                   gimp_parasite_data (parasite),
-                                   gimp_parasite_data_size (parasite),
-                                   G_KEY_FILE_NONE, NULL))
+  if (key_file && ! print_settings_check_version (key_file))
     {
       g_key_file_free (key_file);
-      key_file = NULL;;
+      return FALSE;
     }
 
-  gimp_parasite_free (parasite);
-
-  return check_version (key_file);
+  return key_file;
 }
 
 static gboolean
-load_print_settings_from_key_file (PrintData *data,
+print_settings_load_from_key_file (PrintData *data,
                                    GKeyFile  *key_file)
 {
   GtkPrintOperation  *operation = data->operation;
@@ -279,7 +200,7 @@
   if (! settings)
     settings = gtk_print_settings_new ();
 
-  keys = g_key_file_get_keys (key_file, "print-settings", &n_keys, NULL);
+  keys = g_key_file_get_keys (key_file, PRINT_SETTINGS_NAME, &n_keys, NULL);
 
   if (! keys)
     return FALSE;
@@ -288,7 +209,8 @@
     {
       gchar *value;
 
-      value = g_key_file_get_value (key_file, "print-settings", keys[i], NULL);
+      value = g_key_file_get_value (key_file,
+                                    PRINT_SETTINGS_NAME, keys[i], NULL);
 
       if (value)
         {
@@ -340,26 +262,26 @@
   return TRUE;
 }
 
-static GKeyFile *
-check_version (GKeyFile *key_file)
+static gboolean
+print_settings_check_version (GKeyFile *key_file)
 {
   gint  major_version;
   gint  minor_version;
 
-  if (! key_file || ! g_key_file_has_group (key_file, "meta"))
-    return NULL;
+  if (! g_key_file_has_group (key_file, "meta"))
+    return FALSE;
 
   major_version = g_key_file_get_integer (key_file,
                                           "meta", "major-version", NULL);
 
   if (major_version != PRINT_SETTINGS_MAJOR_VERSION)
-    return NULL;
+    return FALSE;
 
   minor_version = g_key_file_get_integer (key_file,
                                           "meta", "minor-version", NULL);
 
   if (minor_version != PRINT_SETTINGS_MINOR_VERSION)
-    return NULL;
+    return FALSE;
 
-  return key_file;
+  return TRUE;
 }

Modified: branches/weskaggs/plug-ins/print/print-settings.h
==============================================================================
--- branches/weskaggs/plug-ins/print/print-settings.h	(original)
+++ branches/weskaggs/plug-ins/print/print-settings.h	Tue Mar  4 03:15:17 2008
@@ -16,5 +16,5 @@
  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
  */
 
-gboolean load_print_settings (PrintData *data);
-void     save_print_settings (PrintData *data);
+gboolean  print_settings_load (PrintData *data);
+void      print_settings_save (PrintData *data);

Modified: branches/weskaggs/plug-ins/print/print.c
==============================================================================
--- branches/weskaggs/plug-ins/print/print.c	(original)
+++ branches/weskaggs/plug-ins/print/print.c	Tue Mar  4 03:15:17 2008
@@ -128,6 +128,11 @@
                           print_args, NULL);
 
   gimp_plugin_menu_register (PAGE_SETUP_PROC_NAME, "<Image>/File/Send");
+
+#if GTK_CHECK_VERSION(2,13,0)
+  gimp_plugin_icon_register (PAGE_SETUP_PROC_NAME, GIMP_ICON_TYPE_STOCK_ID,
+                             (const guint8 *) GTK_STOCK_PAGE_SETUP);
+#endif
 }
 
 static void
@@ -194,6 +199,7 @@
   /* export the image */
   export = gimp_export_image (&image_ID, &drawable_ID, NULL,
                               GIMP_EXPORT_CAN_HANDLE_RGB   |
+                              GIMP_EXPORT_CAN_HANDLE_GRAY  |
                               GIMP_EXPORT_CAN_HANDLE_ALPHA);
 
   if (export == GIMP_EXPORT_CANCEL)
@@ -219,11 +225,13 @@
 
   gimp_image_get_resolution (image_ID, &data.xres, &data.yres);
 
-  load_print_settings (&data);
+  print_settings_load (&data);
 
   if (export != GIMP_EXPORT_EXPORT)
     image_ID = -1;
 
+  gtk_print_operation_set_unit (operation, GTK_UNIT_POINTS);
+
   g_signal_connect (operation, "begin-print",
                     G_CALLBACK (begin_print),
                     &data);
@@ -243,7 +251,7 @@
       gimp_ui_init (PLUG_IN_BINARY, FALSE);
 
       g_signal_connect_swapped (operation, "end-print",
-                                G_CALLBACK (save_print_settings),
+                                G_CALLBACK (print_settings_save),
                                 &data);
 
       g_signal_connect (operation, "create-custom-widget",
@@ -293,7 +301,7 @@
 
   print_page_setup_load (operation, image_ID);
   print_page_setup_dialog (operation);
-  print_page_setup_save (operation);
+  print_page_setup_save (operation, image_ID);
 
   g_object_unref (operation);
 
@@ -378,7 +386,7 @@
   gimp_progress_end ();
 
   /* generate events to solve the problems described in bug #466928 */
-  g_timeout_add (1000, (GSourceFunc) gtk_true, NULL);
+  g_timeout_add_seconds (1, (GSourceFunc) gtk_true, NULL);
 }
 
 static void
@@ -387,7 +395,9 @@
            gint               page_nr,
            PrintData         *data)
 {
-  draw_page_cairo (context, data);
+  print_draw_page (context, data);
+
+  gimp_progress_update (1.0);
 }
 
 /*
@@ -398,7 +408,7 @@
 create_custom_widget (GtkPrintOperation *operation,
                       PrintData         *data)
 {
-  return print_page_layout_gui (data);
+  return print_page_layout_gui (data, PRINT_PROC_NAME);
 }
 
 static void

Modified: branches/weskaggs/plug-ins/print/print.h
==============================================================================
--- branches/weskaggs/plug-ins/print/print.h	(original)
+++ branches/weskaggs/plug-ins/print/print.h	Tue Mar  4 03:15:17 2008
@@ -38,6 +38,5 @@
   PrintCenterMode     center;
   gboolean            use_full_page;
   GtkPrintOperation  *operation;
-  GtkPageOrientation  orientation;
 } PrintData;
 

Modified: branches/weskaggs/plug-ins/pygimp/gimpmodule.c
==============================================================================
--- branches/weskaggs/plug-ins/pygimp/gimpmodule.c	(original)
+++ branches/weskaggs/plug-ins/pygimp/gimpmodule.c	Tue Mar  4 03:15:17 2008
@@ -275,6 +275,34 @@
 }
 
 static PyObject *
+pygimp_exit(PyObject *self, PyObject *args, PyObject *kwargs)
+{
+    gboolean force = FALSE;
+    int nreturn_vals;
+    GimpParam *return_vals;
+
+    static char *kwlist[] = { "force", NULL };
+
+    if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|i:exit", kwlist, &force))
+        return NULL;
+
+    return_vals = gimp_run_procedure("gimp-quit",
+                                     &nreturn_vals,
+                                     GIMP_PDB_INT32, force,
+                                     GIMP_PDB_END);
+
+    if (return_vals[0].data.d_status != GIMP_PDB_SUCCESS) {
+        PyErr_SetString(pygimp_error, "error while exiting");
+        return NULL;
+    }
+
+    gimp_destroy_params(return_vals, nreturn_vals);
+
+    Py_INCREF(Py_None);
+    return Py_None;
+}
+
+static PyObject *
 pygimp_set_data(PyObject *self, PyObject *args)
 {
     char *id, *data;
@@ -1659,6 +1687,7 @@
     {"main",    (PyCFunction)pygimp_main,       METH_VARARGS},
     {"quit",    (PyCFunction)pygimp_quit,       METH_NOARGS},
     {"message", (PyCFunction)pygimp_message,    METH_VARARGS},
+    {"exit",    (PyCFunction)pygimp_exit,       METH_VARARGS | METH_KEYWORDS},
     {"set_data",        (PyCFunction)pygimp_set_data,   METH_VARARGS},
     {"get_data",        (PyCFunction)pygimp_get_data,   METH_VARARGS},
     {"progress_init",   (PyCFunction)pygimp_progress_init,      METH_VARARGS},

Modified: branches/weskaggs/plug-ins/script-fu/script-fu-console.c
==============================================================================
--- branches/weskaggs/plug-ins/script-fu/script-fu-console.c	(original)
+++ branches/weskaggs/plug-ins/script-fu/script-fu-console.c	Tue Mar  4 03:15:17 2008
@@ -564,6 +564,8 @@
   switch (event->keyval)
     {
     case GDK_Return:
+    case GDK_KP_Enter:
+    case GDK_ISO_Enter:
       if (script_fu_cc_is_empty (console))
         return TRUE;
 

Modified: branches/weskaggs/plug-ins/script-fu/scripts/frosty-logo.scm
==============================================================================
--- branches/weskaggs/plug-ins/script-fu/scripts/frosty-logo.scm	(original)
+++ branches/weskaggs/plug-ins/script-fu/scripts/frosty-logo.scm	Tue Mar  4 03:15:17 2008
@@ -10,7 +10,8 @@
         (border (/ size 5))
         (width (+ (car (gimp-drawable-width logo-layer)) border))
         (height (+ (car (gimp-drawable-height logo-layer)) border))
-        (logo-layer-mask (car (gimp-layer-create-mask logo-layer ADD-BLACK-MASK)))
+        (logo-layer-mask (car (gimp-layer-create-mask logo-layer
+                                                      ADD-BLACK-MASK)))
         (sparkle-layer (car (gimp-layer-new img width height RGBA-IMAGE
                                             "Sparkle" 100 NORMAL-MODE)))
         (matte-layer (car (gimp-layer-new img width height RGBA-IMAGE
@@ -30,7 +31,6 @@
     (gimp-image-add-layer img matte-layer 3)
     (gimp-image-add-layer img shadow-layer 4)
     (gimp-image-add-layer img bg-layer 5)
-    (gimp-layer-translate logo-layer border border)
     (gimp-selection-none img)
     (gimp-edit-clear sparkle-layer)
     (gimp-edit-clear matte-layer)
@@ -59,7 +59,6 @@
     (gimp-edit-fill bg-layer BACKGROUND-FILL)
     (gimp-context-set-background '(0 0 0))
     (gimp-edit-fill logo-layer BACKGROUND-FILL)
-;    (gimp-layer-add-mask logo-layer logo-layer-mask)
     (gimp-selection-load selection)
     (gimp-context-set-background '(255 255 255))
     (gimp-edit-fill logo-layer-mask BACKGROUND-FILL)
@@ -78,7 +77,6 @@
     (for-each (lambda (the-layer)
               (gimp-layer-resize the-layer (- width border) (- height border)
                                            (- border) (- border))
-              ; (gimp-layer-translate the-layer border border)
               )
               (list sparkle-layer matte-layer bg-layer)
     )
@@ -88,6 +86,8 @@
 
     (script-fu-util-image-resize-from-layer img logo-layer)
 
+    (gimp-layer-translate bg-layer (- 0 border) (- 0 border))
+
     (gimp-context-pop)
   )
 )
@@ -96,9 +96,45 @@
                                      logo-layer
                                      size
                                      bg-color)
-  (begin
+
+  (let* (
+        (position (- (car(gimp-image-get-layer-position img logo-layer)) 1))
+        (duplicate (car (gimp-layer-new-from-drawable logo-layer img)))
+        (name (car (gimp-layer-get-name logo-layer)))
+        (select (cons-array 4 'byte))
+        (crop 0)
+        (temp 0)
+        )
+
     (gimp-image-undo-group-start img)
-    (apply-frosty-logo-effect img logo-layer size bg-color)
+
+    (gimp-selection-layer-alpha logo-layer)
+    (gimp-image-add-layer img duplicate -1)
+    (gimp-layer-resize-to-image-size duplicate)
+    (gimp-selection-none img)
+    (apply-frosty-logo-effect img duplicate size bg-color)
+    (set! crop (aref (cadr (gimp-image-get-layers img)) (+ position 6)))
+    (set! temp (aref (cadr (gimp-image-get-layers img)) (+ position 3)))
+    (gimp-selection-layer-alpha temp)
+    (aset select 0 (cadr (gimp-selection-bounds img)))
+    (aset select 1 (caddr (gimp-selection-bounds img)))
+    (aset select 2 (cadddr (gimp-selection-bounds img)))
+    (aset select 3 (cadddr (cdr(gimp-selection-bounds img))))
+
+    (gimp-layer-resize crop
+           (+ 20 (- (aref select 2) (aref select 0)))
+           (+ 20 (- (aref select 3) (aref select 1)))
+           (- 0 (+ 0 (aref select 0)))
+           (- 0 (+ 0 (aref select 1))))
+    (gimp-layer-resize duplicate
+           (car (gimp-drawable-width logo-layer))
+           (car (gimp-drawable-height logo-layer))
+           (- 0 (car (gimp-drawable-offsets logo-layer)))
+           (- 0 (cadr (gimp-drawable-offsets logo-layer))))
+    (gimp-image-remove-layer img logo-layer)
+    (gimp-layer-set-name duplicate name)
+
+    (gimp-selection-none img)
     (gimp-image-undo-group-end img)
     (gimp-displays-flush)
   )

Modified: branches/weskaggs/plug-ins/script-fu/scripts/glossy.scm
==============================================================================
--- branches/weskaggs/plug-ins/script-fu/scripts/glossy.scm	(original)
+++ branches/weskaggs/plug-ins/script-fu/scripts/glossy.scm	Tue Mar  4 03:15:17 2008
@@ -74,7 +74,6 @@
         (gimp-context-set-pattern pattern-text)
         (gimp-edit-bucket-fill logo-layer
                                PATTERN-BUCKET-FILL NORMAL-MODE 100 0 FALSE 0 0)
-        (gimp-context-set-pattern old-patterns)
       )
     )
 
@@ -106,7 +105,6 @@
         (gimp-edit-bucket-fill grow-me
                                PATTERN-BUCKET-FILL NORMAL-MODE 100
                                0 FALSE 0 0)
-        (gimp-context-set-pattern old-patterns)
       )
     )
 
@@ -124,7 +122,10 @@
 
     (gimp-selection-none img)
 
-    (plug-in-bump-map RUN-NONINTERACTIVE img grow-me logo-layer
+    (plug-in-bump-map (if (= noninteractive TRUE)
+			  RUN-NONINTERACTIVE
+			  RUN-INTERACTIVE)
+		      img grow-me logo-layer
                       110.0 45.0 3 0 0 0 0 TRUE FALSE 0)
     (gimp-layer-set-mode logo-layer SCREEN-MODE)
 
@@ -134,7 +135,6 @@
         (gimp-context-set-pattern pattern-overlay)
         (gimp-edit-bucket-fill grow-me PATTERN-BUCKET-FILL
                                OVERLAY-MODE 100 0 FALSE 0 0)
-        (gimp-context-set-pattern old-patterns)
         (gimp-selection-none img)
       )
     )

Modified: branches/weskaggs/po/POTFILES.in
==============================================================================
--- branches/weskaggs/po/POTFILES.in	(original)
+++ branches/weskaggs/po/POTFILES.in	Tue Mar  4 03:15:17 2008
@@ -8,6 +8,7 @@
 app/batch.c
 app/main.c
 app/sanity.c
+app/version.c
 
 app/actions/actions.c
 app/actions/brush-editor-actions.c

Modified: branches/weskaggs/tools/pdbgen/app.pl
==============================================================================
--- branches/weskaggs/tools/pdbgen/app.pl	(original)
+++ branches/weskaggs/tools/pdbgen/app.pl	Tue Mar  4 03:15:17 2008
@@ -175,7 +175,12 @@
         $result .= "\n" . ' ' x 2 . "return return_vals;\n";
     }
     else {
-	$result =~ s/_vals =//;
+	if ($success) {
+	    $result =~ s/return_vals =/return/;
+	}
+	else {
+	    $result =~ s/  return_vals =/\n  return/;
+	}
     }
 
     $result =~ s/, success\);$/, TRUE);/m unless $success;

Modified: branches/weskaggs/tools/pdbgen/pdb/display.pdb
==============================================================================
--- branches/weskaggs/tools/pdbgen/pdb/display.pdb	(original)
+++ branches/weskaggs/tools/pdbgen/pdb/display.pdb	Tue Mar  4 03:15:17 2008
@@ -83,7 +83,9 @@
         g_object_unref (image);
     }
   else
-    success = FALSE;
+    {
+      success = FALSE;
+    }
 }
 CODE
     );



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]