[gimp] Issue #526: Import/Export Windows cursor files (.CUR).



commit b301dbee783d6855f72159310af48e0f32ca6731
Author: Jehan <jehan girinstud io>
Date:   Thu Feb 10 18:20:41 2022 +0100

    Issue #526: Import/Export Windows cursor files (.CUR).
    
    MR !565 was only a partial implementation as it was assuming all cursors
    had the same hot spot coordinates in the file, which is false more often
    than not (since usually it's several sizes for the same image, hence
    coordinates move). I should have realized this before merging.
    With this new commit, we actually loads the hot spot coordinates per
    cursor, stores them as per-layer parasites, then exports with per-cursor
    coordinates.
    
    Also it makes the procedure API use int32 array (should be int16 but we
    removed the support, now I think it may have been a mistake) which shows
    the ugliness of our array support once again with additional size args
    per array (even if it's the same size). Also I realize that our support
    of arrays with config object is not good. This is also something we'll
    have to look at.

 plug-ins/file-ico/ico-dialog.c |  83 ++++++++--------
 plug-ins/file-ico/ico-load.c   |  31 +++---
 plug-ins/file-ico/ico-save.c   | 211 +++++++++++++++++++++++++++++++----------
 plug-ins/file-ico/ico-save.h   |  12 +--
 plug-ins/file-ico/ico.c        |  61 +++++++++---
 plug-ins/file-ico/ico.h        |  10 +-
 6 files changed, 275 insertions(+), 133 deletions(-)
---
diff --git a/plug-ins/file-ico/ico-dialog.c b/plug-ins/file-ico/ico-dialog.c
index 6172149aa7..625000e929 100644
--- a/plug-ins/file-ico/ico-dialog.c
+++ b/plug-ins/file-ico/ico-dialog.c
@@ -49,9 +49,6 @@ ico_dialog_new (IcoSaveInfo *info)
   GtkWidget     *frame;
   GtkWidget     *scrolled_window;
   GtkWidget     *viewport;
-  GtkWidget     *grid;
-  GtkAdjustment *adj;
-  GtkWidget     *spinbutton;
   GtkWidget     *warning;
 
   dialog = gimp_export_dialog_new (_("Windows Icon"),
@@ -74,46 +71,6 @@ ico_dialog_new (IcoSaveInfo *info)
                       main_vbox, TRUE, TRUE, 0);
   gtk_widget_show (main_vbox);
 
-  /* Cursor */
-  if (info->is_cursor)
-    {
-      frame = gimp_frame_new (_("Cursor Hot spot"));
-      gtk_box_pack_start (GTK_BOX (main_vbox), frame, FALSE, FALSE, 4);
-      gtk_widget_show (frame);
-
-      grid = gtk_grid_new ();
-      gtk_grid_set_row_spacing (GTK_GRID (grid), 6);
-      gtk_grid_set_column_spacing (GTK_GRID (grid), 6);
-      gtk_container_add (GTK_CONTAINER (frame), grid);
-      gtk_widget_show (grid);
-
-      adj = (GtkAdjustment *)
-             gtk_adjustment_new (info->hot_spot_x, 0,
-                                 G_MAXUINT16, 1, 10, 0);
-      spinbutton = gimp_spin_button_new (adj, 1.0, 0);
-      gtk_spin_button_set_range (GTK_SPIN_BUTTON (spinbutton),
-                                 0, G_MAXUINT16);
-      gimp_grid_attach_aligned (GTK_GRID (grid), 0, 0,
-                                _("Hot spot _X:"), 0.0, 0.5,
-                                spinbutton, 1);
-      g_signal_connect (adj, "value-changed",
-                        G_CALLBACK (gimp_int_adjustment_update),
-                        &info->hot_spot_x);
-
-      adj = (GtkAdjustment *)
-             gtk_adjustment_new (info->hot_spot_y, 0,
-                                 G_MAXUINT16, 1, 10, 0);
-      spinbutton = gimp_spin_button_new (adj, 1.0, 0);
-      gtk_spin_button_set_range (GTK_SPIN_BUTTON (spinbutton),
-                                 0, G_MAXUINT16);
-      gimp_grid_attach_aligned (GTK_GRID (grid), 0, 1,
-                                _("Hot spot _Y:"), 0.0, 0.5,
-                                spinbutton, 1);
-      g_signal_connect (adj, "value-changed",
-                        G_CALLBACK (gimp_int_adjustment_update),
-                        &info->hot_spot_y);
-    }
-
   /* Cursor */
   frame = gimp_frame_new (_("Icon Details"));
   gtk_box_pack_start (GTK_BOX (main_vbox), frame, TRUE, TRUE, 4);
@@ -501,6 +458,46 @@ ico_dialog_add_icon (GtkWidget    *dialog,
   ico_dialog_update_icon_preview (dialog, layer, info->depths[layer_num]);
 
   ico_dialog_check_compat (dialog, info);
+
+  /* Cursor */
+  if (info->is_cursor)
+    {
+      GtkWidget     *grid;
+      GtkAdjustment *adj;
+      GtkWidget     *spinbutton;
+
+      grid = gtk_grid_new ();
+      gtk_grid_set_row_spacing (GTK_GRID (grid), 6);
+      gtk_grid_set_column_spacing (GTK_GRID (grid), 6);
+      gtk_box_pack_start (GTK_BOX (hbox), grid, FALSE, FALSE, 0);
+      gtk_widget_show (grid);
+
+      adj = (GtkAdjustment *)
+             gtk_adjustment_new (info->hot_spot_x[layer_num], 0,
+                                 G_MAXUINT16, 1, 10, 0);
+      spinbutton = gimp_spin_button_new (adj, 1.0, 0);
+      gtk_spin_button_set_range (GTK_SPIN_BUTTON (spinbutton),
+                                 0, G_MAXUINT16);
+      gimp_grid_attach_aligned (GTK_GRID (grid), 0, 0,
+                                _("Hot spot _X:"), 0.0, 0.5,
+                                spinbutton, 1);
+      g_signal_connect (adj, "value-changed",
+                        G_CALLBACK (gimp_int_adjustment_update),
+                        &info->hot_spot_x[layer_num]);
+
+      adj = (GtkAdjustment *)
+             gtk_adjustment_new (info->hot_spot_y[layer_num], 0,
+                                 G_MAXUINT16, 1, 10, 0);
+      spinbutton = gimp_spin_button_new (adj, 1.0, 0);
+      gtk_spin_button_set_range (GTK_SPIN_BUTTON (spinbutton),
+                                 0, G_MAXUINT16);
+      gimp_grid_attach_aligned (GTK_GRID (grid), 0, 1,
+                                _("Hot spot _Y:"), 0.0, 0.5,
+                                spinbutton, 1);
+      g_signal_connect (adj, "value-changed",
+                        G_CALLBACK (gimp_int_adjustment_update),
+                        &info->hot_spot_y[layer_num]);
+    }
 }
 
 static void
diff --git a/plug-ins/file-ico/ico-load.c b/plug-ins/file-ico/ico-load.c
index abe4f2a915..36c3b402bb 100644
--- a/plug-ins/file-ico/ico-load.c
+++ b/plug-ins/file-ico/ico-load.c
@@ -664,7 +664,6 @@ ico_load_image (GFile        *file,
   guchar        *buf;
   guint          icon_count;
   gint           maxsize;
-  GimpParasite  *parasite;
   gchar         *str;
 
   gimp_progress_init_printf (_("Opening '%s'"),
@@ -716,23 +715,27 @@ ico_load_image (GFile        *file,
   image = gimp_image_new (max_width, max_height, GIMP_RGB);
   gimp_image_set_file (image, file);
 
-  /* Save CUR hot spot information */
-  if (header.resource_type == 2)
-    {
-      str = g_strdup_printf ("%d %d", info[0].planes, info[0].bpp);
-      parasite = gimp_parasite_new ("cur-hot-spot",
-                                    GIMP_PARASITE_PERSISTENT,
-                                    strlen (str) + 1, (gpointer) str);
-      g_free (str);
-      gimp_image_attach_parasite (image, parasite);
-      gimp_parasite_free (parasite);
-    }
-
   maxsize = max_width * max_height * 4;
   buf = g_new (guchar, max_width * max_height * 4);
   for (i = 0; i < icon_count; i++)
     {
-      ico_load_layer (fp, image, i, buf, maxsize, info+i);
+      GimpLayer *layer;
+
+      layer = ico_load_layer (fp, image, i, buf, maxsize, info+i);
+
+      /* Save CUR hot spot information */
+      if (header.resource_type == 2)
+        {
+          GimpParasite *parasite;
+
+          str = g_strdup_printf ("%d %d", info[i].planes, info[i].bpp);
+          parasite = gimp_parasite_new ("cur-hot-spot",
+                                        GIMP_PARASITE_PERSISTENT,
+                                        strlen (str) + 1, (gpointer) str);
+          g_free (str);
+          gimp_item_attach_parasite (GIMP_ITEM (layer), parasite);
+          gimp_parasite_free (parasite);
+        }
     }
   g_free (buf);
   g_free (info);
diff --git a/plug-ins/file-ico/ico-save.c b/plug-ins/file-ico/ico-save.c
index 3f366e0145..4993166732 100644
--- a/plug-ins/file-ico/ico-save.c
+++ b/plug-ins/file-ico/ico-save.c
@@ -72,6 +72,25 @@ static void     ico_image_get_reduced_buf (GimpDrawable *layer,
                                            guchar      **cmap_out,
                                            guchar      **buf_out);
 
+static gboolean ico_save_init             (GimpImage    *image,
+                                           gint32        run_mode,
+                                           IcoSaveInfo  *info,
+                                           gint          n_hot_spot_x,
+                                           gint32       *hot_spot_x,
+                                           gint          n_hot_spot_y,
+                                           gint32       *hot_spot_y,
+                                           GError      **error);
+static GimpPDBStatusType
+                shared_save_image         (GFile         *file,
+                                           GimpImage     *image,
+                                           gint32         run_mode,
+                                           gint          *n_hot_spot_x,
+                                           gint32       **hot_spot_x,
+                                           gint          *n_hot_spot_y,
+                                           gint32       **hot_spot_y,
+                                           GError       **error,
+                                           IcoSaveInfo   *info);
+
 
 static gint
 ico_write_int32 (FILE     *fp,
@@ -155,9 +174,15 @@ ico_write_int8 (FILE     *fp,
 }
 
 
-static void
+static gboolean
 ico_save_init (GimpImage   *image,
-               IcoSaveInfo *info)
+               gint32       run_mode,
+               IcoSaveInfo *info,
+               gint         n_hot_spot_x,
+               gint32      *hot_spot_x,
+               gint         n_hot_spot_y,
+               gint32      *hot_spot_y,
+               GError     **error)
 {
   GList     *iter;
   gint       num_colors;
@@ -169,6 +194,51 @@ ico_save_init (GimpImage   *image,
   info->depths         = g_new (gint, info->num_icons);
   info->default_depths = g_new (gint, info->num_icons);
   info->compress       = g_new (gboolean, info->num_icons);
+  info->hot_spot_x     = g_new0 (gint, info->num_icons);
+  info->hot_spot_y     = g_new0 (gint, info->num_icons);
+
+  if (run_mode == GIMP_RUN_NONINTERACTIVE &&
+      (n_hot_spot_x != info->num_icons ||
+       n_hot_spot_y != info->num_icons))
+    {
+      /* While it is acceptable for interactive and last values run (in
+       * such case, we just drop the previous values), we expect
+       * non-interactive calls to have exactly the right numbers of
+       * hot-spot values set.
+       */
+      g_set_error (error, G_FILE_ERROR, g_file_error_from_errno (errno),
+                   _("Called non-interactively with %d and %d hotspot "
+                     "coordinates with an image of %d icons."),
+                   n_hot_spot_x, n_hot_spot_y, info->num_icons);
+
+      return FALSE;
+    }
+
+  /* Only use existing values if we have exactly the same number of
+   * icons. Drop previous/saved values otherwise.
+   */
+  if (hot_spot_x && n_hot_spot_x == info->num_icons)
+    {
+      /* XXX This is the limit of our array arguments not self-aware of
+       * their length (the separate args may be "lying" with a wrong
+       * call). We may end up with a segfault if the arg array was not
+       * big enough. There is not much we can really do here. I thought
+       * about g_renew() but it won't initialize to 0 if the arg is
+       * smaller. Also we don't want to free the original array.
+       */
+      for (iter = info->layers, i = 0;
+           iter;
+           iter = g_list_next (iter), i++)
+        info->hot_spot_x[i] = hot_spot_x[i];
+    }
+
+  if (hot_spot_y && n_hot_spot_y == info->num_icons)
+    {
+      for (iter = info->layers, i = 0;
+           iter;
+           iter = g_list_next (iter), i++)
+        info->hot_spot_y[i] = hot_spot_y[i];
+    }
 
   /* Limit the color depths to values that don't cause any color loss
    * -- the user should pick these anyway, so we can save her some
@@ -225,6 +295,8 @@ ico_save_init (GimpImage   *image,
   /* set with default values */
   memcpy (info->depths, info->default_depths,
           sizeof (gint) * info->num_icons);
+
+  return TRUE;
 }
 
 
@@ -237,37 +309,41 @@ ico_save_dialog (GimpImage      *image,
   GList         *iter;
   gint           i;
   gint           response;
-  GimpParasite  *parasite = NULL;
 
   gimp_ui_init (PLUG_IN_BINARY);
 
-  /* Loading hot spots for cursors if applicable */
-  parasite = gimp_image_get_parasite (image, "cur-hot-spot");
-
-  if (parasite)
-    {
-      gchar   *parasite_data;
-      guint32  parasite_size;
-      gint x, y;
-
-      parasite_data = (gchar *) gimp_parasite_get_data (parasite, &parasite_size);
-      parasite_data = g_strndup (parasite_data, parasite_size);
-
-      if (sscanf (parasite_data, "%i %i", &x, &y) == 2)
-        {
-          info->hot_spot_x = x;
-          info->hot_spot_y = y;
-        }
-
-      gimp_parasite_free (parasite);
-      g_free (parasite_data);
-    }
-
   dialog = ico_dialog_new (info);
   for (iter = info->layers, i = 0;
        iter;
        iter = g_list_next (iter), i++)
     {
+      if (info->is_cursor)
+        {
+          GimpParasite *parasite = NULL;
+
+          /* Loading hot spots for cursors if applicable */
+          parasite = gimp_item_get_parasite (GIMP_ITEM (iter->data), "cur-hot-spot");
+
+          if (parasite)
+            {
+              gchar   *parasite_data;
+              guint32  parasite_size;
+              gint x, y;
+
+              parasite_data = (gchar *) gimp_parasite_get_data (parasite, &parasite_size);
+              parasite_data = g_strndup (parasite_data, parasite_size);
+
+              if (sscanf (parasite_data, "%i %i", &x, &y) == 2)
+                {
+                  info->hot_spot_x[i] = x;
+                  info->hot_spot_y[i] = y;
+                }
+
+              gimp_parasite_free (parasite);
+              g_free (parasite_data);
+            }
+        }
+
       /* if (gimp_layer_get_visible(layers[i])) */
       ico_dialog_add_icon (dialog, iter->data, i);
     }
@@ -1080,6 +1156,8 @@ ico_save_info_free (IcoSaveInfo  *info)
   g_free (info->default_depths);
   g_free (info->compress);
   g_list_free (info->layers);
+  g_free (info->hot_spot_x);
+  g_free (info->hot_spot_y);
   memset (info, 0, sizeof (IcoSaveInfo));
 }
 
@@ -1089,42 +1167,51 @@ ico_save_image (GFile      *file,
                 gint32      run_mode,
                 GError    **error)
 {
-  IcoSaveInfo    info;
+  IcoSaveInfo info;
 
   D(("*** Exporting Microsoft icon file %s\n",
      gimp_file_get_utf8_name (file)));
 
   info.is_cursor = FALSE;
 
-  return shared_save_image (file, image, run_mode, error, &info);
+  return shared_save_image (file, image, run_mode,
+                            0, NULL, 0, NULL,
+                            error, &info);
 }
 
 GimpPDBStatusType
 cur_save_image (GFile      *file,
                 GimpImage  *image,
                 gint32      run_mode,
-                gint32      hot_spot_x,
-                gint32      hot_spot_y,
+                gint       *n_hot_spot_x,
+                gint32    **hot_spot_x,
+                gint       *n_hot_spot_y,
+                gint32    **hot_spot_y,
                 GError    **error)
 {
-  IcoSaveInfo  info;
+  IcoSaveInfo info;
 
   D(("*** Exporting Microsoft cursor file %s\n",
      gimp_file_get_utf8_name (file)));
 
   info.is_cursor = TRUE;
-  info.hot_spot_x = hot_spot_x;
-  info.hot_spot_y = hot_spot_y;
 
-  return shared_save_image (file, image, run_mode, error, &info);
+  return shared_save_image (file, image, run_mode,
+                            n_hot_spot_x, hot_spot_x,
+                            n_hot_spot_y, hot_spot_y,
+                            error, &info);
 }
 
 GimpPDBStatusType
-shared_save_image (GFile *file,
-                   GimpImage     *image,
-                   gint32         run_mode,
-                   GError       **error,
-                   IcoSaveInfo   *info)
+shared_save_image (GFile        *file,
+                   GimpImage    *image,
+                   gint32        run_mode,
+                   gint         *n_hot_spot_x,
+                   gint32      **hot_spot_x,
+                   gint         *n_hot_spot_y,
+                   gint32      **hot_spot_y,
+                   GError      **error,
+                   IcoSaveInfo  *info)
 {
   FILE          *fp;
   GList         *iter;
@@ -1137,7 +1224,15 @@ shared_save_image (GFile *file,
   GimpParasite  *parasite = NULL;
   gchar         *str;
 
-  ico_save_init (image, info);
+  if (! ico_save_init (image, run_mode, info,
+                       n_hot_spot_x ? *n_hot_spot_x : 0,
+                       hot_spot_x   ? *hot_spot_x   : NULL,
+                       n_hot_spot_y ? *n_hot_spot_y : 0,
+                       hot_spot_y   ? *hot_spot_y   : NULL,
+                       error))
+    {
+      return GIMP_PDB_EXECUTION_ERROR;
+    }
 
   if (run_mode == GIMP_RUN_INTERACTIVE)
     {
@@ -1210,8 +1305,8 @@ shared_save_image (GFile *file,
       /* .cur file reuses these fields for cursor offsets */
       if (info->is_cursor)
         {
-          entries[i].planes = info->hot_spot_x;
-          entries[i].bpp = info->hot_spot_y;
+          entries[i].planes = info->hot_spot_x[i];
+          entries[i].bpp = info->hot_spot_y[i];
         }
       entries[i].offset = ftell (fp);
 
@@ -1251,14 +1346,34 @@ shared_save_image (GFile *file,
   /* Updating parasite hot spots if needed */
   if (info->is_cursor)
     {
-      str = g_strdup_printf ("%d %d", info->hot_spot_x, info->hot_spot_y);
-      parasite = gimp_parasite_new ("cur-hot-spot",
-                                    GIMP_PARASITE_PERSISTENT,
-                                    strlen (str) + 1, (gpointer) str);
-      g_free (str);
-      gimp_image_attach_parasite (image, parasite);
-      gimp_parasite_free (parasite);
+      for (iter = info->layers, i = 0;
+           iter;
+           iter = g_list_next (iter), i++)
+        {
+          str = g_strdup_printf ("%d %d", info->hot_spot_x[i], info->hot_spot_y[i]);
+          parasite = gimp_parasite_new ("cur-hot-spot",
+                                        GIMP_PARASITE_PERSISTENT,
+                                        strlen (str) + 1, (gpointer) str);
+          g_free (str);
+          gimp_item_attach_parasite (GIMP_ITEM (iter->data), parasite);
+          gimp_parasite_free (parasite);
+        }
+    }
+
+  if (hot_spot_x)
+    {
+      *hot_spot_x = info->hot_spot_x;
+      info->hot_spot_x = NULL;
+    }
+  if (hot_spot_y)
+    {
+      *hot_spot_y = info->hot_spot_y;
+      info->hot_spot_y = NULL;
     }
+  if (n_hot_spot_x)
+    *n_hot_spot_x = info->num_icons;
+  if (n_hot_spot_y)
+    *n_hot_spot_y = info->num_icons;
 
   ico_save_info_free (info);
   fclose (fp);
diff --git a/plug-ins/file-ico/ico-save.h b/plug-ins/file-ico/ico-save.h
index 920feb05d5..1e1ed82dc9 100644
--- a/plug-ins/file-ico/ico-save.h
+++ b/plug-ins/file-ico/ico-save.h
@@ -30,16 +30,12 @@ GimpPDBStatusType ico_save_image          (GFile         *file,
 GimpPDBStatusType cur_save_image          (GFile         *file,
                                            GimpImage     *image,
                                            gint32         run_mode,
-                                           gint32         hot_spot_x,
-                                           gint32         hot_spot_y,
+                                           gint          *n_hot_spot_x,
+                                           gint32       **hot_spot_x,
+                                           gint          *n_hot_spot_y,
+                                           gint32       **hot_spot_y,
                                            GError       **error);
 
-GimpPDBStatusType shared_save_image       (GFile         *file,
-                                           GimpImage     *image,
-                                           gint32         run_mode,
-                                           GError       **error,
-                                           IcoSaveInfo   *info);
-
 gboolean          ico_cmap_contains_black (const guchar  *cmap,
                                            gint           num_colors);
 
diff --git a/plug-ins/file-ico/ico.c b/plug-ins/file-ico/ico.c
index 728c70bed9..4a63aedad7 100644
--- a/plug-ins/file-ico/ico.c
+++ b/plug-ins/file-ico/ico.c
@@ -255,17 +255,25 @@ ico_create_procedure (GimpPlugIn  *plug_in,
       gimp_file_procedure_set_extensions (GIMP_FILE_PROCEDURE (procedure),
                                           "cur");
 
-      GIMP_PROC_ARG_INT (procedure, "hot-spot-x",
-                         "Hot spot X",
-                         "X coordinate of hot spot",
-                         0, G_MAXUINT16, 0,
+      GIMP_PROC_ARG_INT (procedure, "n-hot-spot-x",
+                         "Number of hot spot's X coordinates",
+                         "Number of hot spot's X coordinates",
+                         0, G_MAXINT, 0,
                          G_PARAM_READWRITE);
-
-      GIMP_PROC_ARG_INT (procedure, "hot-spot-y",
-                         "Hot spot Y",
-                         "Y coordinate of hot spot",
-                         0, G_MAXUINT16, 0,
+      GIMP_PROC_ARG_INT32_ARRAY (procedure, "hot-spot-x",
+                                 "Hot spot X",
+                                 "X coordinates of hot spot (one per layer)",
+                                 G_PARAM_READWRITE);
+
+      GIMP_PROC_ARG_INT (procedure, "n-hot-spot-y",
+                         "Number of hot spot's Y coordinates",
+                         "Number of hot spot's Y coordinates",
+                         0, G_MAXINT, 0,
                          G_PARAM_READWRITE);
+      GIMP_PROC_ARG_INT32_ARRAY (procedure, "hot-spot-y",
+                                 "Hot spot Y",
+                                 "Y coordinates of hot spot (one per layer)",
+                                 G_PARAM_READWRITE);
     }
 
   return procedure;
@@ -374,9 +382,11 @@ cur_save (GimpProcedure        *procedure,
 {
   GimpProcedureConfig *config;
   GimpPDBStatusType    status;
-  GError              *error      = NULL;
-  gint                 hot_spot_x = 0;
-  gint                 hot_spot_y = 0;
+  GError              *error        = NULL;
+  gint32              *hot_spot_x   = NULL;
+  gint32              *hot_spot_y   = NULL;
+  gint                 n_hot_spot_x = 0;
+  gint                 n_hot_spot_y = 0;
 
   INIT_I18N ();
   gegl_init (NULL, NULL);
@@ -385,11 +395,32 @@ cur_save (GimpProcedure        *procedure,
   gimp_procedure_config_begin_run (config, image, run_mode, args);
 
   g_object_get (config,
-                "hot-spot-x",  &hot_spot_x,
-                "hot-spot-y",  &hot_spot_y,
+                "n-hot-spot-x", &n_hot_spot_x,
+                "n-hot-spot-y", &n_hot_spot_y,
+                "hot-spot-x",   &hot_spot_x,
+                "hot-spot-y",   &hot_spot_y,
                 NULL);
 
-  status = cur_save_image (file, image, run_mode, hot_spot_x, hot_spot_y, &error);
+  status = cur_save_image (file, image, run_mode,
+                           &n_hot_spot_x, &hot_spot_x,
+                           &n_hot_spot_y, &hot_spot_y,
+                           &error);
+
+  if (status == GIMP_PDB_SUCCESS)
+    {
+      /* XXX: seems libgimpconfig is not able to serialize
+       * GimpInt32Array args yet anyway. Still leave this here for now,
+       * as reminder of missing feature when we see the warnings.
+       */
+      g_object_set (config,
+                    "n-hot-spot-x", n_hot_spot_x,
+                    "n-hot-spot-y", n_hot_spot_y,
+                    /*"hot-spot-x",   hot_spot_x,*/
+                    /*"hot-spot-y",   hot_spot_y,*/
+                    NULL);
+      g_free (hot_spot_x);
+      g_free (hot_spot_y);
+    }
 
   gimp_procedure_config_end_run (config, status);
   g_object_unref (config);
diff --git a/plug-ins/file-ico/ico.h b/plug-ins/file-ico/ico.h
index 972dd19ceb..07465d853b 100644
--- a/plug-ins/file-ico/ico.h
+++ b/plug-ins/file-ico/ico.h
@@ -50,11 +50,11 @@ typedef struct _IcoFileHeader
 typedef struct _IcoFileEntry
 {
   guint8        width;      /* Width of icon in pixels */
-  guint8        height;    /* Height of icon in pixels */
+  guint8        height;     /* Height of icon in pixels */
   guint8        num_colors; /* Number of colors of paletted image */
   guint8        reserved;   /* Must be 0 */
-  guint16       planes;     /* Must be 1 */
-  guint16       bpp;        /* 1, 4, 8, 24 or 32 bits per pixel */
+  guint16       planes;     /* Must be 1 for ICO, x position of hot spot for CUR */
+  guint16       bpp;        /* 1, 4, 8, 24 or 32 bits per pixel for ICO, y position of hot spot for CUR */
   guint32       size;       /* Size of icon (including data header) */
   guint32       offset;     /* Absolute offset of data in a file */
  } IcoFileEntry;
@@ -93,8 +93,8 @@ typedef struct _IcoSaveInfo
     GList       *layers;
     gint         num_icons;
     gboolean     is_cursor;
-    gint         hot_spot_x;
-    gint         hot_spot_y;
+    gint        *hot_spot_x;
+    gint        *hot_spot_y;
 } IcoSaveInfo;
 
 


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