]> Pileus Git - ~andy/gtk/commitdiff
new user signal, and possibility to query signal information.
authorTim Janik <timj@src.gnome.org>
Thu, 29 Jan 1998 20:44:14 +0000 (20:44 +0000)
committerTim Janik <timj@src.gnome.org>
Thu, 29 Jan 1998 20:44:14 +0000 (20:44 +0000)
-timj

gtk/gtkobject.c
gtk/gtkobject.h
gtk/gtksignal.c
gtk/gtksignal.h
gtk/gtktypeutils.c

index e307538deca3b53c2140968f4fe4183fcf6ca17e..8a28f9063beb5bd64677bab15a1570d63c761a19 100644 (file)
@@ -256,10 +256,65 @@ gtk_object_class_add_signals (GtkObjectClass *class,
   for (i = 0; i < nsignals; i++)
     new_signals[class->nsignals + i] = signals[i];
 
+  g_free (class->signals);
   class->signals = new_signals;
   class->nsignals += nsignals;
 }
 
+/*****************************************
+ * gtk_object_class_add_user_signal:
+ *
+ *   arguments:
+ *
+ *   results:
+ *****************************************/
+
+gint
+gtk_object_class_add_user_signal (GtkObjectClass     *class,
+                                 const gchar        *name,
+                                 GtkSignalMarshaller marshaller,
+                                 GtkType             return_val,
+                                 gint                nparams,
+                                 ...)
+{
+  GtkType *params;
+  guint i;
+  va_list args;
+  gint signal_id;
+
+  g_return_val_if_fail (class != NULL, 0);
+
+  if (nparams > 0)
+    {
+      params = g_new (GtkType, nparams);
+
+      va_start (args, nparams);
+
+      for (i = 0; i < nparams; i++)
+       params[i] = va_arg (args, GtkType);
+
+      va_end (args);
+    }
+  else
+    params = NULL;
+
+  signal_id = gtk_signal_newv (name,
+                              0,
+                              class->type,
+                              0,
+                              marshaller,
+                              return_val,
+                              nparams,
+                              params);
+
+  g_free (params);
+
+  if (signal_id)
+    gtk_object_class_add_signals (class, &signal_id, 1);
+
+  return signal_id;
+}
+
 /*****************************************
  * gtk_object_ref:
  *
index a7ae98a2a33a65a17b0e5c3a5463dcdb416a1204..97a77fc3fde06dd36848be2175cc0aaf96a1a51c 100644 (file)
@@ -161,6 +161,18 @@ struct _GtkObjectClass
 };
 
 
+/* For the purpose of user signals we need the signal function
+ * and signal marshaller signatures already in this place.
+ */
+#define GTK_SIGNAL_FUNC(f)  ((GtkSignalFunc) f)
+
+typedef void (*GtkSignalFunc)       (void);
+typedef void (*GtkSignalMarshaller) (GtkObject      *object,
+                                    GtkSignalFunc   func,
+                                    gpointer        func_data,
+                                    GtkArg         *args);
+
+
 /* Get the type identifier for GtkObject's.
  */
 guint  gtk_object_get_type             (void);
@@ -171,6 +183,15 @@ void       gtk_object_class_add_signals    (GtkObjectClass *klass,
                                         gint           *signals,
                                         gint            nsignals);
 
+/* Append a user defined signal without default handler to a class.
+ */
+gint    gtk_object_class_add_user_signal (GtkObjectClass     *klass,
+                                         const gchar        *name,
+                                         GtkSignalMarshaller marshaller,
+                                         GtkType             return_val,
+                                         gint                nparams,
+                                         ...);
+
 GtkObject*     gtk_object_new          (guint          type,
                                         ...);
 
index 00a54fb1666214d4a1f46c097512556a08c4c8d2..2857262954c010b963f13dfc36d693419f4ccdf7 100644 (file)
@@ -161,15 +161,60 @@ gtk_signal_new (const gchar         *name,
                ...)
 {
   GtkType *params;
+  guint i;
+  va_list args;
+  gint return_id;
+
+  g_return_val_if_fail (nparams < 16, 0);
+
+  if (nparams > 0)
+    {
+      params = g_new (GtkType, nparams);
+
+      va_start (args, nparams);
+
+      for (i = 0; i < nparams; i++)
+       params[i] = va_arg (args, GtkType);
+
+      va_end (args);
+    }
+  else
+    params = NULL;
+
+  return_id = gtk_signal_newv (name,
+                              run_type,
+                              object_type,
+                              function_offset,
+                              marshaller,
+                              return_val,
+                              nparams,
+                              params);
+
+  g_free (params);
+
+  return return_id;
+}
+
+gint
+gtk_signal_newv (const gchar         *name,
+                GtkSignalRunType     run_type,
+                gint                 object_type,
+                gint                 function_offset,
+                GtkSignalMarshaller  marshaller,
+                GtkType              return_val,
+                gint                 nparams,
+                GtkType             *params)
+{
   GtkSignal *signal;
   GtkSignalInfo info;
   gint *type;
-  gint i;
-  va_list args;
+  guint i;
 
   g_return_val_if_fail (name != NULL, 0);
   g_return_val_if_fail (marshaller != NULL, 0);
-  g_return_val_if_fail (nparams < 10, 0);
+  g_return_val_if_fail (nparams < 16, 0);
+  if (nparams)
+    g_return_val_if_fail (params != NULL, 0);
 
   if (initialize)
     gtk_signal_init ();
@@ -186,35 +231,56 @@ gtk_signal_new (const gchar         *name,
     }
 
   signal = g_new (GtkSignal, 1);
-  signal->info.name = g_strdup(name);
+  signal->info.name = g_strdup (name);
   signal->info.object_type = object_type;
   signal->info.signal_type = next_signal++;
   signal->function_offset = function_offset;
   signal->run_type = run_type;
   signal->marshaller = marshaller;
   signal->return_val = return_val;
-  signal->params = NULL;
   signal->nparams = nparams;
 
-  g_hash_table_insert (signal_hash_table, &signal->info.signal_type, signal);
-  g_hash_table_insert (signal_info_hash_table, &signal->info, &signal->info.signal_type);
-
   if (nparams > 0)
     {
       signal->params = g_new (GtkType, nparams);
-      params = signal->params;
-
-      va_start (args, nparams);
 
       for (i = 0; i < nparams; i++)
-       params[i] = va_arg (args, GtkType);
-
-      va_end (args);
+       signal->params[i] = params[i];
     }
+  else
+    signal->params = NULL;
+
+  g_hash_table_insert (signal_hash_table, &signal->info.signal_type, signal);
+  g_hash_table_insert (signal_info_hash_table, &signal->info, &signal->info.signal_type);
 
   return signal->info.signal_type;
 }
 
+GtkSignalQuery*
+gtk_signal_query (gint                 signal_num)
+{
+  GtkSignalQuery *query;
+  GtkSignal *signal;
+
+  signal = g_hash_table_lookup (signal_hash_table, &signal_num);
+  if (signal)
+    {
+      query = g_new (GtkSignalQuery, 1);
+
+      query->object_type = signal->info.object_type;
+      query->signal_name = signal->info.name;
+      query->is_user_signal = signal->function_offset == 0;
+      query->run_type = signal->run_type;
+      query->return_val = signal->return_val;
+      query->nparams = signal->nparams;
+      query->params = signal->params;
+    }
+  else
+    query = NULL;
+
+  return query;
+}
+
 gint
 gtk_signal_lookup (const gchar *name,
                   gint         object_type)
@@ -871,7 +937,7 @@ gtk_signal_real_emit (GtkObject *object,
       gtk_emission_add (&current_emissions, object, signal_type);
 
     restart:
-      if (GTK_RUN_TYPE (signal->run_type) != GTK_RUN_LAST)
+      if (GTK_RUN_TYPE (signal->run_type) != GTK_RUN_LAST && signal->function_offset != 0)
        {
          signal_func_offset = (guchar**) ((guchar*) object->klass + signal->function_offset);
          if (*signal_func_offset)
@@ -898,7 +964,7 @@ gtk_signal_real_emit (GtkObject *object,
          goto restart;
        }
 
-      if (GTK_RUN_TYPE (signal->run_type) != GTK_RUN_FIRST)
+      if (GTK_RUN_TYPE (signal->run_type) != GTK_RUN_FIRST && signal->function_offset != 0)
        {
          signal_func_offset = (guchar**) ((guchar*) object->klass + signal->function_offset);
          if (*signal_func_offset)
@@ -965,31 +1031,44 @@ gtk_signal_connect_by_type (GtkObject       *object,
                            gint             after,
                            gint             no_marshal)
 {
+  GtkObjectClass *class;
   GtkHandler *handler;
-  gint *object_signals;
-  gint nsignals;
   gint found_it;
-  gint i;
 
   g_return_val_if_fail (object != NULL, 0);
   g_return_val_if_fail (object->klass != NULL, 0);
-  g_return_val_if_fail (object->klass->signals != NULL, 0);
 
   /* Search through the signals for this object and make
-   *  sure the one we are adding is valid. If it isn't then
-   *  issue a warning and return.
+   *  sure the one we are adding is valid. We need to perform
+   *  the lookup on the objects parents as well. If it isn't
+   *  valid then issue a warning and return.
    */
-  object_signals = object->klass->signals;
-  nsignals = object->klass->nsignals;
   found_it = FALSE;
-
-  for (i = 0; i < nsignals; i++)
-    if (object_signals[i] == signal_type)
-      {
-       found_it = TRUE;
-       break;
-      }
-
+  class = object->klass;
+  while (class)
+    {
+      GtkType parent;
+      gint *object_signals;
+      gint  nsignals;
+      guint i;
+      
+      object_signals = class->signals;
+      nsignals = class->nsignals;
+      
+      for (i = 0; i < nsignals; i++)
+       if (object_signals[i] == signal_type)
+         {
+           found_it = TRUE;
+           break;
+         }
+      
+      parent = gtk_type_parent (class->type);
+      if (parent)
+       class = gtk_type_class (parent);
+      else
+       class = NULL;
+    }
+  
   if (!found_it)
     {
       g_warning ("could not find signal (%d) in object's list of signals", signal_type);
index 68ff999025d09f4000c28c0d9d03d328bb660c83..8519cf9dacaa82c29f6fdbdaa796f5c86d2ff591 100644 (file)
@@ -35,14 +35,7 @@ extern "C" {
 #define GTK_SIGNAL_OFFSET(t, f) ((int) ((char*) &((t*) 0)->f))
 #endif /* offsetof */
 
-#define GTK_SIGNAL_FUNC(f)  ((GtkSignalFunc) f)
-
-
-typedef void (*GtkSignalFunc)       (void);
-typedef void (*GtkSignalMarshaller) (GtkObject      *object,
-                                    GtkSignalFunc   func,
-                                    gpointer        func_data,
-                                    GtkArg         *args);
+  
 typedef void (*GtkSignalMarshal)    (GtkObject      *object,
                                     gpointer        data,
                                     gint            nparams,
@@ -51,6 +44,18 @@ typedef void (*GtkSignalMarshal)    (GtkObject      *object,
                                     GtkType         return_type);
 typedef void (*GtkSignalDestroy)    (gpointer        data);
 
+typedef struct _GtkSignalQuery         GtkSignalQuery;
+
+struct _GtkSignalQuery
+{
+  gint            object_type;
+  const gchar    *signal_name;
+  gboolean        is_user_signal;
+  GtkSignalRunType run_type;
+  GtkType         return_val;
+  guint                   nparams;
+  const GtkType          *params;
+};
 
 gint   gtk_signal_new                     (const gchar         *name,
                                           GtkSignalRunType     run_type,
@@ -60,6 +65,14 @@ gint   gtk_signal_new                     (const gchar         *name,
                                           GtkType              return_val,
                                           gint                 nparams,
                                           ...);
+gint   gtk_signal_newv                    (const gchar         *name,
+                                          GtkSignalRunType     run_type,
+                                          gint                 object_type,
+                                          gint                 function_offset,
+                                          GtkSignalMarshaller  marshaller,
+                                          GtkType              return_val,
+                                          gint                 nparams,
+                                          GtkType             *params);
 gint   gtk_signal_lookup                  (const gchar         *name,
                                           gint                 object_type);
 gchar* gtk_signal_name                    (gint                 signal_num);
@@ -115,6 +128,12 @@ void   gtk_signal_default_marshaller      (GtkObject           *object,
 void   gtk_signal_set_funcs               (GtkSignalMarshal     marshal_func,
                                           GtkSignalDestroy     destroy_func);
 
+/* Report internal information about a signal. The caller has the response
+ *  to invoke a supsequent g_free (returned_data); but must leave the
+ *  contents of GtkSignalQuery untouched.
+ */
+GtkSignalQuery* gtk_signal_query         (gint                 signal_num);
+
 
 #ifdef __cplusplus
 }
index b27b9c6dd497bd0f75511031fcc235909f135efc..599a6f3b6dbfc75f8fe44bb6233043e09a6afa1b 100644 (file)
@@ -356,6 +356,8 @@ gtk_type_class_init (GtkTypeNode *node)
 
       object_class = node->klass;
       object_class->type = node->type;
+      object_class->signals = NULL;
+      object_class->nsignals = 0;
       object_class->n_args = 0;
 
       if (node->type_info.class_init_func)