[gimp/wip/Jehan/signals-GIMP: 4/4] app, libgimp: support passing arguments to signals from core to libgimp.



commit a6b78b46acc5d36ad8bcb1067933659c04abb71e
Author: Jehan <jehan girinstud io>
Date:   Tue Aug 20 12:03:42 2019 +0200

    app, libgimp: support passing arguments to signals from core to libgimp.
    
    And add a new signal demonstrating this new support: "added-layer" will
    pass the newly added GimpLayer and the originally passed name to the
    plug-ins.

 app/core/gimpimage.c            | 13 +++++++++++-
 app/core/gimpitem.c             |  2 +-
 app/plug-in/gimpplugin.c        | 15 ++++++++++----
 app/plug-in/gimpplugin.h        |  3 ++-
 app/plug-in/gimppluginmanager.c | 46 ++++++++++++++++++++++++++++++++++++++---
 app/plug-in/gimppluginmanager.h |  4 +++-
 libgimp/gimpdisplay.c           |  5 +++--
 libgimp/gimpdisplay.h           | 11 +++++-----
 libgimp/gimpimage.c             | 44 +++++++++++++++++++++++++++++++++++++--
 libgimp/gimpimage.h             | 14 ++++++++-----
 libgimp/gimpitem.c              |  5 +++--
 libgimp/gimpitem.h              | 11 +++++-----
 libgimp/gimpplugin-private.c    | 14 ++++++++++---
 libgimpbase/gimpprotocol.c      |  8 +++++++
 libgimpbase/gimpprotocol.h      |  2 ++
 15 files changed, 162 insertions(+), 35 deletions(-)
---
diff --git a/app/core/gimpimage.c b/app/core/gimpimage.c
index e06c44dbd8..cf7dc3cc16 100644
--- a/app/core/gimpimage.c
+++ b/app/core/gimpimage.c
@@ -70,6 +70,7 @@
 #include "gimplayermask.h"
 #include "gimplayerstack.h"
 #include "gimpmarshal.h"
+#include "gimpparamspecs.h"
 #include "gimpparasitelist.h"
 #include "gimppickable.h"
 #include "gimpprojectable.h"
@@ -1043,7 +1044,7 @@ gimp_image_finalize (GObject *object)
 
   gimp_plug_in_manager_emit_signal (image->gimp->plug_in_manager,
                                     object, gimp_image_get_ID (image),
-                                    "destroyed");
+                                    "destroyed", G_TYPE_NONE);
 
   if (private->colormap)
     gimp_image_colormap_free (image);
@@ -4344,6 +4345,7 @@ gimp_image_add_layer (GimpImage *image,
                       gboolean   push_undo)
 {
   GimpImagePrivate *private;
+  gchar            *add_name;
   gboolean          old_has_alpha;
 
   g_return_val_if_fail (GIMP_IS_IMAGE (image), FALSE);
@@ -4374,6 +4376,7 @@ gimp_image_add_layer (GimpImage *image,
                                     layer,
                                     gimp_image_get_active_layer (image));
 
+  add_name = g_strdup (gimp_object_get_name (GIMP_OBJECT (layer)));
   gimp_item_tree_add_item (private->layers, GIMP_ITEM (layer),
                            GIMP_ITEM (parent), position);
 
@@ -4387,6 +4390,14 @@ gimp_image_add_layer (GimpImage *image,
   if (old_has_alpha != gimp_image_has_alpha (image))
     private->flush_accum.alpha_changed = TRUE;
 
+  gimp_plug_in_manager_emit_signal (image->gimp->plug_in_manager,
+                                    G_OBJECT (image), gimp_image_get_ID (image),
+                                    "added-layer",
+                                    GIMP_TYPE_LAYER_ID, gimp_item_get_ID (GIMP_ITEM (layer)),
+                                    G_TYPE_STRING, add_name,
+                                    G_TYPE_NONE);
+  g_free (add_name);
+
   return TRUE;
 }
 
diff --git a/app/core/gimpitem.c b/app/core/gimpitem.c
index 03d6d742fe..133f2e5f6a 100644
--- a/app/core/gimpitem.c
+++ b/app/core/gimpitem.c
@@ -377,7 +377,7 @@ gimp_item_finalize (GObject *object)
 
   gimp_plug_in_manager_emit_signal (private->image->gimp->plug_in_manager,
                                     object, gimp_item_get_ID (GIMP_ITEM (object)),
-                                    "destroyed");
+                                    "destroyed", G_TYPE_NONE);
 
   if (private->offset_nodes)
     {
diff --git a/app/plug-in/gimpplugin.c b/app/plug-in/gimpplugin.c
index ee51dd3fb3..9a30805b9f 100644
--- a/app/plug-in/gimpplugin.c
+++ b/app/plug-in/gimpplugin.c
@@ -72,6 +72,8 @@
 #include "libgimpbase/gimpprotocol.h"
 #include "libgimpbase/gimpwire.h"
 
+#include "libgimp/gimpgpparams.h"
+
 #include "plug-in-types.h"
 
 #include "core/gimp.h"
@@ -1048,10 +1050,11 @@ gimp_plug_in_get_error_handler (GimpPlugIn *plug_in)
 }
 
 void
-gimp_plug_in_emit_signal (GimpPlugIn   *plug_in,
-                          GObject      *object,
-                          gint32        id,
-                          const gchar  *name)
+gimp_plug_in_emit_signal (GimpPlugIn     *plug_in,
+                          GObject        *object,
+                          gint32          id,
+                          const gchar    *name,
+                          GimpValueArray *params)
 {
   if (plug_in->open)
     {
@@ -1071,8 +1074,12 @@ gimp_plug_in_emit_signal (GimpPlugIn   *plug_in,
           signal.type = type;
           signal.id   = id;
           signal.name = (gchar *) name;
+          signal.params = _gimp_value_array_to_gp_params (params, FALSE);
+          signal.nparams = gimp_value_array_length (params);
 
           gp_signal_write (plug_in->my_write, &signal, plug_in);
+
+          g_free (signal.params);
         }
     }
 }
diff --git a/app/plug-in/gimpplugin.h b/app/plug-in/gimpplugin.h
index 82a6a51b11..d4614fa9a2 100644
--- a/app/plug-in/gimpplugin.h
+++ b/app/plug-in/gimpplugin.h
@@ -122,6 +122,7 @@ GimpPDBErrorHandler
 void          gimp_plug_in_emit_signal       (GimpPlugIn             *plug_in,
                                               GObject                *object,
                                               gint32                  id,
-                                              const gchar            *name);
+                                              const gchar            *name,
+                                              GimpValueArray         *params);
 
 #endif /* __GIMP_PLUG_IN_H__ */
diff --git a/app/plug-in/gimppluginmanager.c b/app/plug-in/gimppluginmanager.c
index e9479d4ffa..7e10fd2f33 100644
--- a/app/plug-in/gimppluginmanager.c
+++ b/app/plug-in/gimppluginmanager.c
@@ -23,6 +23,8 @@
 
 #include <gdk-pixbuf/gdk-pixbuf.h>
 #include <gegl.h>
+#include <glib-object.h>
+#include <gobject/gvaluecollector.h>
 
 #include "libgimpbase/gimpbase.h"
 #include "libgimpconfig/gimpconfig.h"
@@ -429,10 +431,48 @@ void
 gimp_plug_in_manager_emit_signal (GimpPlugInManager *manager,
                                   GObject           *object,
                                   gint32             id,
-                                  const gchar       *name)
+                                  const gchar       *name,
+                                  GType              first_type,
+                                  ...)
 {
-  GSList *iter = manager->open_plug_ins;
+  GSList         *iter = manager->open_plug_ins;
+  GimpValueArray *params;
+  GType           param_type;
+  va_list         va_args;
+
+  va_start (va_args, first_type);
+
+  param_type = first_type;
+  params = gimp_value_array_new (param_type == G_TYPE_NONE ? 0 : 1);
+
+  while (param_type != G_TYPE_NONE)
+    {
+      GValue  value = G_VALUE_INIT;
+      gchar  *error = NULL;
+
+      g_value_init (&value, param_type);
+      G_VALUE_COLLECT (&value, va_args, G_VALUE_NOCOPY_CONTENTS, &error);
+
+      if (error)
+        {
+          g_critical ("%s: %s", G_STRFUNC, error);
+          g_free (error);
+          g_value_unset (&value);
+          gimp_value_array_unref (params);
+
+          return;
+        }
+
+      gimp_value_array_append (params, &value);
+      g_value_unset (&value);
+
+      param_type = va_arg (va_args, GType);
+    }
+
+  va_end (va_args);
 
   for (; iter; iter = iter->next)
-    gimp_plug_in_emit_signal (iter->data, object, id, name);
+    gimp_plug_in_emit_signal (iter->data, object, id, name, params);
+
+  gimp_value_array_unref (params);
 }
diff --git a/app/plug-in/gimppluginmanager.h b/app/plug-in/gimppluginmanager.h
index 1192083d7b..43cf2b5d00 100644
--- a/app/plug-in/gimppluginmanager.h
+++ b/app/plug-in/gimppluginmanager.h
@@ -117,7 +117,9 @@ void    gimp_plug_in_manager_plug_in_pop          (GimpPlugInManager   *manager)
 void    gimp_plug_in_manager_emit_signal          (GimpPlugInManager   *manager,
                                                    GObject             *object,
                                                    gint32               id,
-                                                   const gchar         *name);
+                                                   const gchar         *name,
+                                                   GType                first_type,
+                                                   ...);
 
 
 #endif  /* __GIMP_PLUG_IN_MANAGER_H__ */
diff --git a/libgimp/gimpdisplay.c b/libgimp/gimpdisplay.c
index 7c1fbbec0a..37cffdd8d3 100644
--- a/libgimp/gimpdisplay.c
+++ b/libgimp/gimpdisplay.c
@@ -190,8 +190,9 @@ gimp_display_get_by_id (gint32 display_id)
 
 G_GNUC_INTERNAL
 void
-_gimp_display_process_signal (gint32       display_id,
-                              const gchar *name)
+_gimp_display_process_signal (gint32          display_id,
+                              const gchar    *name,
+                              GimpValueArray *arguments)
 {
   GimpDisplay *display = NULL;
 
diff --git a/libgimp/gimpdisplay.h b/libgimp/gimpdisplay.h
index 1709e4407c..7cf64e0392 100644
--- a/libgimp/gimpdisplay.h
+++ b/libgimp/gimpdisplay.h
@@ -64,15 +64,16 @@ struct _GimpDisplayClass
   void (*_gimp_reserved9) (void);
 };
 
-GType         gimp_display_get_type     (void) G_GNUC_CONST;
+GType         gimp_display_get_type        (void) G_GNUC_CONST;
 
-gint32        gimp_display_get_id       (GimpDisplay    *display);
-GimpDisplay * gimp_display_get_by_id    (gint32          display_id);
+gint32        gimp_display_get_id          (GimpDisplay    *display);
+GimpDisplay * gimp_display_get_by_id       (gint32          display_id);
 
 
 G_GNUC_INTERNAL
-void          _gimp_display_process_signal (gint32        display_id,
-                                            const gchar  *name);
+void          _gimp_display_process_signal (gint32          display_id,
+                                            const gchar    *name,
+                                            GimpValueArray *arguments);
 
 
 G_END_DECLS
diff --git a/libgimp/gimpimage.c b/libgimp/gimpimage.c
index 7355ac7ceb..2207b7169a 100644
--- a/libgimp/gimpimage.c
+++ b/libgimp/gimpimage.c
@@ -27,6 +27,7 @@
 enum
 {
   DESTROYED,
+  ADDED_LAYER,
   LAST_SIGNAL
 };
 
@@ -89,6 +90,27 @@ gimp_image_class_init (GimpImageClass *klass)
                   g_cclosure_marshal_VOID__VOID,
                   G_TYPE_NONE, 0);
 
+  /**
+   * GimpImageClass::added-layer:
+   * @image:    a #GimpImage
+   * @layer:    the new #GimpLayer
+   * @add_name: the string passed initially as @layer name. It may be
+   *            different from the actual name @layer has now.
+   *
+   * This signal will be emitted just after a new layer has been added
+   * to @image.
+   */
+  signals[ADDED_LAYER] =
+    g_signal_new ("added-layer",
+                  G_TYPE_FROM_CLASS (klass),
+                  G_SIGNAL_RUN_FIRST,
+                  G_STRUCT_OFFSET (GimpImageClass, new_layer),
+                  NULL, NULL,
+                  g_cclosure_marshal_VOID__OBJECT,
+                  G_TYPE_NONE, 2,
+                  GIMP_TYPE_LAYER,
+                  G_TYPE_STRING);
+
   props[PROP_ID] =
     g_param_spec_int ("id",
                       "The image id",
@@ -542,8 +564,9 @@ gimp_image_set_metadata (GimpImage    *image,
 
 
 void
-_gimp_image_process_signal (gint32       image_id,
-                            const gchar *name)
+_gimp_image_process_signal (gint32          image_id,
+                            const gchar    *name,
+                            GimpValueArray *params)
 {
   GimpImage *image = NULL;
 
@@ -567,6 +590,23 @@ _gimp_image_process_signal (gint32       image_id,
       g_signal_emit (image, signals[DESTROYED], 0);
       g_object_unref (image);
     }
+  else if (g_strcmp0 (name, "added-layer") == 0)
+    {
+      GimpItem    *layer;
+      const gchar *name;
+      GValue      *value;
+
+      g_return_if_fail (gimp_value_array_length (params) == 2                          &&
+                        GIMP_VALUE_HOLDS_LAYER_ID (gimp_value_array_index (params, 0)) &&
+                        G_VALUE_HOLDS_STRING (gimp_value_array_index (params, 1)));
+
+      value = gimp_value_array_index (params, 0);
+      layer = gimp_item_get_by_id (gimp_value_get_layer_id (value));
+      value = gimp_value_array_index (params, 1);
+      name  = g_value_get_string (value);
+
+      g_signal_emit (image, signals[ADDED_LAYER], 0, layer, name);
+    }
 }
 
 
diff --git a/libgimp/gimpimage.h b/libgimp/gimpimage.h
index cdec1f5882..d2dd455e52 100644
--- a/libgimp/gimpimage.h
+++ b/libgimp/gimpimage.h
@@ -52,7 +52,10 @@ struct _GimpImageClass
   GObjectClass parent_class;
 
   /* Signals. */
-  void (* destroyed) (GimpImage *image);
+  void (* destroyed) (GimpImage   *image);
+  void (* new_layer) (GimpImage   *image,
+                      GimpLayer   *layer,
+                      const gchar *add_name);
 
   /* Padding for future expansion */
   void (*_gimp_reserved1) (void);
@@ -68,15 +71,16 @@ struct _GimpImageClass
 
 GType          gimp_image_get_type           (void) G_GNUC_CONST;
 
-gint32         gimp_image_get_id             (GimpImage    *image);
-GimpImage    * gimp_image_get_by_id          (gint32        image_id);
+gint32         gimp_image_get_id             (GimpImage      *image);
+GimpImage    * gimp_image_get_by_id          (gint32          image_id);
 
 GList        * gimp_image_list               (void);
 
 
 G_GNUC_INTERNAL
-void           _gimp_image_process_signal    (gint32        image_id,
-                                              const gchar  *name);
+void           _gimp_image_process_signal    (gint32          image_id,
+                                              const gchar    *name,
+                                              GimpValueArray *params);
 
 
 #ifndef GIMP_DEPRECATED_REPLACE_NEW_API
diff --git a/libgimp/gimpitem.c b/libgimp/gimpitem.c
index ba111a944a..aeec1110ec 100644
--- a/libgimp/gimpitem.c
+++ b/libgimp/gimpitem.c
@@ -294,8 +294,9 @@ gimp_item_get_children (GimpItem *item)
 
 
 void
-_gimp_item_process_signal (gint32       item_id,
-                           const gchar *name)
+_gimp_item_process_signal (gint32          item_id,
+                           const gchar    *name,
+                           GimpValueArray *params)
 {
   GimpItem *item = NULL;
 
diff --git a/libgimp/gimpitem.h b/libgimp/gimpitem.h
index 65c2035425..2d825a7e46 100644
--- a/libgimp/gimpitem.h
+++ b/libgimp/gimpitem.h
@@ -67,15 +67,16 @@ struct _GimpItemClass
   void (*_gimp_reserved9) (void);
 };
 
-GType         gimp_item_get_type     (void) G_GNUC_CONST;
+GType         gimp_item_get_type         (void) G_GNUC_CONST;
 
-gint32        gimp_item_get_id       (GimpItem    *item);
-GimpItem    * gimp_item_get_by_id    (gint32       item_id);
+gint32        gimp_item_get_id           (GimpItem       *item);
+GimpItem    * gimp_item_get_by_id        (gint32          item_id);
 
 
 G_GNUC_INTERNAL
-void          _gimp_item_process_signal    (gint32        item_id,
-                                            const gchar  *name);
+void          _gimp_item_process_signal  (gint32          item_id,
+                                          const gchar    *name,
+                                          GimpValueArray *params);
 
 
 #ifndef GIMP_DEPRECATED_REPLACE_NEW_API
diff --git a/libgimp/gimpplugin-private.c b/libgimp/gimpplugin-private.c
index 31c50adeec..22b927bc12 100644
--- a/libgimp/gimpplugin-private.c
+++ b/libgimp/gimpplugin-private.c
@@ -356,22 +356,30 @@ static void
 gimp_plug_in_signal (GimpPlugIn *plug_in,
                      GPSignal   *signal)
 {
+  GimpValueArray *arguments;
+
+  arguments = _gimp_gp_params_to_value_array (NULL,
+                                              NULL, 0,
+                                              signal->params,
+                                              signal->nparams,
+                                              FALSE, FALSE);
   switch (signal->type)
     {
     case GP_SIGNAL_TYPE_IMAGE:
-      _gimp_image_process_signal (signal->id, signal->name);
+      _gimp_image_process_signal (signal->id, signal->name, arguments);
       break;
     case GP_SIGNAL_TYPE_ITEM:
-      _gimp_item_process_signal (signal->id, signal->name);
+      _gimp_item_process_signal (signal->id, signal->name, arguments);
       break;
     case GP_SIGNAL_TYPE_DISPLAY:
-      _gimp_display_process_signal (signal->id, signal->name);
+      _gimp_display_process_signal (signal->id, signal->name, arguments);
       break;
 
     case GP_SIGNAL_TYPE_NONE:
       g_warning ("Unexpected signal without type received (should not happen)");
       break;
     }
+  gimp_value_array_unref (arguments);
 }
 
 static void
diff --git a/libgimpbase/gimpprotocol.c b/libgimpbase/gimpprotocol.c
index a39b2e3756..4b2662f03d 100644
--- a/libgimpbase/gimpprotocol.c
+++ b/libgimpbase/gimpprotocol.c
@@ -1993,6 +1993,10 @@ _gp_signal_read (GIOChannel      *channel,
                                 &signal->name, 1, user_data))
     goto cleanup;
 
+  _gp_params_read (channel,
+                   &signal->params, (guint *) &signal->nparams,
+                   user_data);
+
   msg->data = signal;
   return;
 
@@ -2019,6 +2023,8 @@ _gp_signal_write (GIOChannel      *channel,
   if (! _gimp_wire_write_string (channel,
                                  &signal->name, 1, user_data))
     return;
+
+  _gp_params_write (channel, signal->params, signal->nparams, user_data);
 }
 
 static void
@@ -2028,7 +2034,9 @@ _gp_signal_destroy (GimpWireMessage *msg)
 
   if (signal)
     {
+      _gp_params_destroy (signal->params, signal->nparams);
       g_free (signal->name);
+
       g_slice_free (GPSignal, signal);
     }
 }
diff --git a/libgimpbase/gimpprotocol.h b/libgimpbase/gimpprotocol.h
index 6b50d95ea2..0d56e941cb 100644
--- a/libgimpbase/gimpprotocol.h
+++ b/libgimpbase/gimpprotocol.h
@@ -300,6 +300,8 @@ struct _GPSignal
   guint32       id;
   gchar        *name;
 
+  guint32       nparams;
+  GPParam      *params;
 };
 
 void      gp_init                   (void);


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