]> Pileus Git - ~andy/gtk/blobdiff - gtk/gtksignal.c
Remove reallocate-redraws property. This is something that only a widget
[~andy/gtk] / gtk / gtksignal.c
index be83a4ec0425c95992c10d94baa8390fb2d9caba..b7ed0fb1fc24970964e1bd5cd5aeae1c6cc7540d 100644 (file)
  * Copyright (C) 1995-1997 Peter Mattis, Spencer Kimball and Josh MacDonald
  *
  * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Library General Public
+ * 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.
  *
  * This library is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * Library General Public License for more details.
+ * Lesser General Public License for more details.
  *
- * You should have received a copy of the GNU Library General Public
- * License along with this library; if not, write to the Free
- * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
  */
-#include <stdarg.h>
-#include "gtksignal.h"
 
+#include       "gtksignal.h"
+#include       "gtkargcollector.c"
+#include       "gtkmarshal.c"
 
-#define MAX_PARAMS       20
-#define DONE             1
-#define RESTART          2
 
-#define GTK_RUN_TYPE(x)  ((x) & GTK_RUN_MASK)
-
-
-typedef struct _GtkSignal       GtkSignal;
-typedef struct _GtkSignalInfo   GtkSignalInfo;
-typedef struct _GtkHandler     GtkHandler;
-typedef struct _GtkHandlerInfo  GtkHandlerInfo;
-typedef struct _GtkEmission     GtkEmission;
-
-typedef void (*GtkSignalMarshaller0) (GtkObject *object,
-                                     gpointer   data);
-
-struct _GtkSignalInfo
-{
-  gchar *name;
-  GtkType object_type;
-  guint signal_type;
-};
-
-struct _GtkSignal
-{
-  GtkSignalInfo info;
-  guint function_offset;
-  GtkSignalRunType run_type;
-  GtkSignalMarshaller marshaller;
-  GtkType return_val;
-  GtkType *params;
-  guint nparams;
-};
+/* the real parameter limit is of course given by GSignal, bu we need
+ * an upper limit for the implementations. so this should be adjusted
+ * with any future changes on the GSignal side of things.
+ */
+#define        SIGNAL_MAX_PARAMS       12
 
-struct _GtkHandler
-{
-  guint id : 28;
-  guint blocked : 1;
-  guint object_signal : 1;
-  guint after : 1;
-  guint no_marshal : 1;
-  guint16 ref_count;
-  guint16 signal_type;
-  GtkSignalFunc func;
-  gpointer func_data;
-  GtkSignalDestroy destroy_func;
-  GtkHandler *prev;
-  GtkHandler *next;
-};
 
-struct _GtkHandlerInfo
-{
-  GtkObject *object;
-  GtkSignalMarshaller marshaller;
-  GtkArg *params;
-  GtkType *param_types;
-  GtkType return_val;
-  GtkSignalRunType run_type;
-  guint nparams;
-  guint signal_type;
-};
-
-struct _GtkEmission
+/* --- functions --- */
+guint
+gtk_signal_newv (const gchar         *name,
+                GtkSignalRunType     signal_flags,
+                GtkType              object_type,
+                guint                function_offset,
+                GtkSignalMarshaller  marshaller,
+                GtkType              return_val,
+                guint                n_params,
+                GtkType             *params)
 {
-  GtkObject *object;
-  guint signal_type;
-};
-
-
-static void         gtk_signal_init            (void);
-static guint        gtk_signal_hash            (guint         *key);
-static gint         gtk_signal_compare         (guint         *a,
-                                               guint         *b);
-static guint        gtk_signal_info_hash       (GtkSignalInfo *a);
-static gint         gtk_signal_info_compare    (GtkSignalInfo *a,
-                                               GtkSignalInfo *b);
-static GtkHandler*  gtk_signal_handler_new     (void);
-static void         gtk_signal_handler_ref     (GtkHandler    *handler);
-static void         gtk_signal_handler_unref   (GtkHandler    *handler,
-                                               GtkObject     *object);
-static void         gtk_signal_handler_insert  (GtkObject     *object,
-                                               GtkHandler    *handler);
-static void         gtk_signal_real_emit       (GtkObject     *object,
-                                               guint          signal_type,
-                                               va_list        args);
-static GtkHandler*  gtk_signal_get_handlers    (GtkObject     *object,
-                                               guint          signal_type);
-static guint        gtk_signal_connect_by_type (GtkObject     *object,
-                                               guint          signal_type,
-                                               GtkSignalFunc  func,
-                                               gpointer       func_data,
-                                               GtkSignalDestroy destroy_func,
-                                               gint           object_signal,
-                                               gint           after,
-                                               gint           no_marshal);
-static GtkEmission* gtk_emission_new           (void);
-static void         gtk_emission_destroy       (GtkEmission    *emission);
-static void         gtk_emission_add           (GList         **emissions,
-                                               GtkObject      *object,
-                                               guint           signal_type);
-static void         gtk_emission_remove        (GList         **emissions,
-                                               GtkObject      *object,
-                                               guint           signal_type);
-static gint         gtk_emission_check         (GList          *emissions,
-                                               GtkObject      *object,
-                                               guint           signal_type);
-static gint         gtk_handlers_run           (GtkHandler     *handlers,
-                                               GtkHandlerInfo *info,
-                                               gint            after);
-static void         gtk_params_get             (GtkArg         *params,
-                                               guint           nparams,
-                                               GtkType        *param_types,
-                                               GtkType         return_val,
-                                               va_list         args);
-
-
-static gint initialize = TRUE;
-static GHashTable *signal_hash_table = NULL;
-static GHashTable *signal_info_hash_table = NULL;
-static guint next_signal = 1;
-static guint next_handler_id = 1;
-
-static const gchar *handler_key = "gtk-signal-handlers";
-
-static GMemChunk *handler_mem_chunk = NULL;
-static GMemChunk *emission_mem_chunk = NULL;
-
-static GList *current_emissions = NULL;
-static GList *stop_emissions = NULL;
-static GList *restart_emissions = NULL;
-
-static GtkSignalMarshal marshal = NULL;
-static GtkSignalDestroy destroy = NULL;
-
+  GClosure *closure;
+  
+  g_return_val_if_fail (n_params < SIGNAL_MAX_PARAMS, 0);
+  
+  closure = g_signal_type_cclosure_new (object_type, function_offset);
+  
+  return g_signal_newv (name, object_type, signal_flags, closure, NULL, NULL, marshaller, return_val, n_params, params);
+}
 
 guint
 gtk_signal_new (const gchar         *name,
-               GtkSignalRunType     run_type,
+               GtkSignalRunType     signal_flags,
                GtkType              object_type,
                guint                function_offset,
                GtkSignalMarshaller  marshaller,
                GtkType              return_val,
-               guint                nparams,
+               guint                n_params,
                ...)
 {
   GtkType *params;
-  guint i;
-  va_list args;
-  guint return_id;
-  
-  g_return_val_if_fail (nparams < 16, 0);
+  guint signal_id;
   
-  if (nparams > 0)
+  if (n_params)
     {
-      params = g_new (GtkType, nparams);
-      
-      va_start (args, nparams);
+      va_list args;
+      guint i;
       
-      for (i = 0; i < nparams; i++)
+      params = g_new (GtkType, n_params);
+      va_start (args, n_params);
+      for (i = 0; i < n_params; i++)
        params[i] = va_arg (args, GtkType);
-      
       va_end (args);
     }
   else
     params = NULL;
-  
-  return_id = gtk_signal_newv (name,
-                              run_type,
+  signal_id = gtk_signal_newv (name,
+                              signal_flags,
                               object_type,
                               function_offset,
                               marshaller,
                               return_val,
-                              nparams,
+                              n_params,
                               params);
-  
   g_free (params);
   
-  return return_id;
-}
-
-guint
-gtk_signal_newv (const gchar         *name,
-                GtkSignalRunType     run_type,
-                GtkType              object_type,
-                guint                function_offset,
-                GtkSignalMarshaller  marshaller,
-                GtkType              return_val,
-                guint                nparams,
-                GtkType             *params)
-{
-  GtkSignal *signal;
-  GtkSignalInfo info;
-  guint *type;
-  guint i;
-  
-  g_return_val_if_fail (name != NULL, 0);
-  g_return_val_if_fail (marshaller != NULL, 0);
-  g_return_val_if_fail (nparams < 16, 0);
-  if (nparams)
-    g_return_val_if_fail (params != NULL, 0);
-  
-  if (initialize)
-    gtk_signal_init ();
-  
-  info.name = (char*)name;
-  info.object_type = object_type;
-  
-  type = g_hash_table_lookup (signal_info_hash_table, &info);
-  if (type)
-    {
-      g_warning ("gtk_signal_newv(): signal \"%s\" already exists in the `%s' class ancestry\n",
-                name, gtk_type_name (object_type));
-      return 0;
-    }
-  
-  signal = g_new (GtkSignal, 1);
-  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->nparams = nparams;
-  
-  if (nparams > 0)
-    {
-      signal->params = g_new (GtkType, nparams);
-      
-      for (i = 0; i < nparams; i++)
-       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 (guint signal_id)
-{
-  GtkSignalQuery *query;
-  GtkSignal *signal;
-  
-  g_return_val_if_fail (signal_id >= 1, NULL);
-  
-  signal = g_hash_table_lookup (signal_hash_table, &signal_id);
-  if (signal)
-    {
-      query = g_new (GtkSignalQuery, 1);
-      
-      query->object_type = signal->info.object_type;
-      query->signal_id = signal_id;
-      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;
-}
-
-guint
-gtk_signal_lookup (const gchar *name,
-                  GtkType      object_type)
-{
-  GtkSignalInfo info;
-  
-  g_return_val_if_fail (name != NULL, 0);
-  g_return_val_if_fail (gtk_type_is_a (object_type, GTK_TYPE_OBJECT), 0);
-  
-  if (initialize)
-    gtk_signal_init ();
-  
-  info.name = (char*)name;
-  
-  while (object_type)
-    {
-      guint *type;
-      
-      info.object_type = object_type;
-      
-      type = g_hash_table_lookup (signal_info_hash_table, &info);
-      if (type)
-       return *type;
-      
-      object_type = gtk_type_parent (object_type);
-    }
-  
-  return 0;
-}
-
-gchar*
-gtk_signal_name (guint signal_id)
-{
-  GtkSignal *signal;
-  
-  g_return_val_if_fail (signal_id >= 1, NULL);
-  
-  signal = g_hash_table_lookup (signal_hash_table, &signal_id);
-  if (signal)
-    return signal->info.name;
-  
-  return NULL;
+  return signal_id;
 }
 
 void
-gtk_signal_emit (GtkObject *object,
-                guint       signal_id,
-                ...)
+gtk_signal_emit_stop_by_name (GtkObject   *object,
+                             const gchar *name)
 {
-  va_list args;
-  
-  g_return_if_fail (object != NULL);
-  g_return_if_fail (signal_id >= 1);
-  
-  if (initialize)
-    gtk_signal_init ();
-  
-  va_start (args, signal_id);
-  
-  gtk_signal_real_emit (object, signal_id, args);
+  g_return_if_fail (GTK_IS_OBJECT (object));
   
-  va_end (args);
+  g_signal_stop_emission (object, g_signal_lookup (name, G_OBJECT_TYPE (object)), 0);
 }
 
 void
-gtk_signal_emit_by_name (GtkObject       *object,
-                        const gchar     *name,
-                        ...)
+gtk_signal_connect_object_while_alive (GtkObject    *object,
+                                      const gchar  *signal,
+                                      GtkSignalFunc func,
+                                      GtkObject    *alive_object)
 {
-  guint type;
-  va_list args;
-  
-  g_return_if_fail (object != NULL);
-  g_return_if_fail (name != NULL);
-  
-  if (initialize)
-    gtk_signal_init ();
-  
-  type = gtk_signal_lookup (name, GTK_OBJECT_TYPE (object));
+  g_return_if_fail (GTK_IS_OBJECT (object));
   
-  if (type >= 1)
-    {
-      va_start (args, name);
-      
-      gtk_signal_real_emit (object, type, args);
-      
-      va_end (args);
-    }
-  else
-    {
-      g_warning ("gtk_signal_emit_by_name(): could not find signal \"%s\" in the `%s' class ancestry",
-                name, gtk_type_name (GTK_OBJECT_TYPE (object)));
-    }
+  g_signal_connect_closure_by_id (object,
+                                 g_signal_lookup (signal, G_OBJECT_TYPE (object)), 0,
+                                 g_cclosure_new_object_swap (func, alive_object),
+                                 FALSE);
 }
 
 void
-gtk_signal_emit_stop (GtkObject *object,
-                     guint       signal_id)
+gtk_signal_connect_while_alive (GtkObject    *object,
+                               const gchar  *signal,
+                               GtkSignalFunc func,
+                               gpointer      func_data,
+                               GtkObject    *alive_object)
 {
-  g_return_if_fail (object != NULL);
-  g_return_if_fail (signal_id >= 1);
-  
-  if (initialize)
-    gtk_signal_init ();
-  
-  if (gtk_emission_check (current_emissions, object, signal_id))
-    gtk_emission_add (&stop_emissions, object, signal_id);
-  else
-    g_warning ("gtk_signal_emit_stop(): no current emission (%u) for object `%s'",
-              signal_id, gtk_type_name (GTK_OBJECT_TYPE (object)));
-}
+  GClosure *closure;
 
-void
-gtk_signal_emit_stop_by_name (GtkObject       *object,
-                             const gchar     *name)
-{
-  guint type;
-  
-  g_return_if_fail (object != NULL);
-  g_return_if_fail (name != NULL);
-  
-  if (initialize)
-    gtk_signal_init ();
-  
-  type = gtk_signal_lookup (name, GTK_OBJECT_TYPE (object));
-  if (type)
-    gtk_signal_emit_stop (object, type);
-  else
-    g_warning ("gtk_signal_emit_stop_by_name(): could not find signal \"%s\" in the `%s' class ancestry",
-              name, gtk_type_name (GTK_OBJECT_TYPE (object)));
-}
+  g_return_if_fail (GTK_IS_OBJECT (object));
 
-guint
-gtk_signal_connect (GtkObject     *object,
-                   const gchar   *name,
-                   GtkSignalFunc  func,
-                   gpointer       func_data)
-{
-  guint type;
-  
-  g_return_val_if_fail (object != NULL, 0);
-  
-  if (initialize)
-    gtk_signal_init ();
-  
-  type = gtk_signal_lookup (name, GTK_OBJECT_TYPE (object));
-  if (!type)
-    {
-      g_warning ("gtk_signal_connect(): could not find signal \"%s\" in the `%s' class ancestry",
-                name, gtk_type_name (GTK_OBJECT_TYPE (object)));
-      return 0;
-    }
-  
-  return gtk_signal_connect_by_type (object, type, 
-                                    func, func_data, NULL,
-                                    FALSE, FALSE, FALSE);
+  closure = g_cclosure_new (func, func_data, NULL);
+  g_object_watch_closure (G_OBJECT (alive_object), closure);
+  g_signal_connect_closure_by_id (object,
+                                 g_signal_lookup (signal, G_OBJECT_TYPE (object)), 0,
+                                 closure,
+                                 FALSE);
 }
 
 guint
-gtk_signal_connect_after (GtkObject     *object,
-                         const gchar   *name,
-                         GtkSignalFunc  func,
-                         gpointer       func_data)
-{
-  guint type;
-  
-  g_return_val_if_fail (object != NULL, 0);
-  
-  if (initialize)
-    gtk_signal_init ();
-  
-  type = gtk_signal_lookup (name, GTK_OBJECT_TYPE (object));
-  if (!type)
-    {
-      g_warning ("gtk_signal_connect_after(): could not find signal \"%s\" in the `%s' class ancestry",
-                name, gtk_type_name (GTK_OBJECT_TYPE (object)));
-      return 0;
-    }
-  
-  return gtk_signal_connect_by_type (object, type, 
-                                    func, func_data, NULL,
-                                    FALSE, TRUE, FALSE);
-}
-
-guint   
 gtk_signal_connect_full (GtkObject           *object,
                         const gchar         *name,
                         GtkSignalFunc        func,
-                        GtkCallbackMarshal   marshal,
-                        gpointer             func_data,
+                        GtkCallbackMarshal   unsupported,
+                        gpointer             data,
                         GtkDestroyNotify     destroy_func,
                         gint                 object_signal,
                         gint                 after)
 {
-  guint type;
-  
-  g_return_val_if_fail (object != NULL, 0);
-  
-  if (initialize)
-    gtk_signal_init ();
-  
-  type = gtk_signal_lookup (name, GTK_OBJECT_TYPE (object));
-  if (!type)
-    {
-      g_warning ("gtk_signal_connect_full(): could not find signal \"%s\" in the `%s' class ancestry",
-                name, gtk_type_name (GTK_OBJECT_TYPE (object)));
-      return 0;
-    }
+  g_return_val_if_fail (GTK_IS_OBJECT (object), 0);
+  g_return_val_if_fail (unsupported == NULL, 0);
   
-  if (marshal)
-    return gtk_signal_connect_by_type (object, type, (GtkSignalFunc) marshal, 
-                                      func_data, destroy_func, 
-                                      object_signal, after, TRUE);
-  else
-    return gtk_signal_connect_by_type (object, type, func, 
-                                      func_data, destroy_func, 
-                                      object_signal, after, FALSE);
-}
-
-guint
-gtk_signal_connect_interp (GtkObject         *object,
-                          const gchar       *name,
-                          GtkCallbackMarshal func,
-                          gpointer           func_data,
-                          GtkDestroyNotify   destroy_func,
-                          gint               after)
-{
-  return gtk_signal_connect_full (object, name, NULL, func,
-                                 func_data, destroy_func, FALSE, after);
-}
-
-guint
-gtk_signal_connect_object (GtkObject     *object,
-                          const gchar   *name,
-                          GtkSignalFunc  func,
-                          GtkObject     *slot_object)
-{
-  guint type;
-  
-  g_return_val_if_fail (object != NULL, 0);
-  /* slot_object needs to be treated as ordinary pointer */
-  
-  if (initialize)
-    gtk_signal_init ();
-  
-  type = gtk_signal_lookup (name, GTK_OBJECT_TYPE (object));
-  if (!type)
-    {
-      g_warning ("gtk_signal_connect_object(): could not find signal \"%s\" in the `%s' class ancestry",
-                name, gtk_type_name (GTK_OBJECT_TYPE (object)));
-      return 0;
-    }
-  
-  return gtk_signal_connect_by_type (object, type, 
-                                    func, slot_object, NULL,
-                                    TRUE, FALSE, FALSE);
-}
-
-guint
-gtk_signal_connect_object_after (GtkObject     *object,
-                                const gchar   *name,
-                                GtkSignalFunc  func,
-                                GtkObject     *slot_object)
-{
-  guint type;
-  
-  g_return_val_if_fail (object != NULL, 0);
-  
-  if (initialize)
-    gtk_signal_init ();
-  
-  type = gtk_signal_lookup (name, GTK_OBJECT_TYPE (object));
-  if (!type)
-    {
-      g_warning ("gtk_signal_connect_object_after(): could not find signal \"%s\" in the `%s' class ancestry",
-                name, gtk_type_name (GTK_OBJECT_TYPE (object)));
-      return 0;
-    }
-  
-  return gtk_signal_connect_by_type (object, type, 
-                                    func, slot_object, NULL,
-                                    TRUE, TRUE, FALSE);
-}
-
-typedef struct _GtkDisconnectInfo       GtkDisconnectInfo;
-struct _GtkDisconnectInfo
-{
-  GtkObject     *object1;
-  guint          disconnect_handler1;
-  guint          signal_handler;
-  GtkObject     *object2;
-  guint          disconnect_handler2;
-};
-
-static guint
-gtk_alive_disconnecter (GtkDisconnectInfo *info)
-{
-  g_return_val_if_fail (info != NULL, 0);
-  
-  gtk_signal_disconnect (info->object1, info->disconnect_handler1);
-  gtk_signal_disconnect (info->object1, info->signal_handler);
-  gtk_signal_disconnect (info->object2, info->disconnect_handler2);
-  g_free (info);
-  
-  return 0;
+  return g_signal_connect_closure_by_id (object,
+                                        g_signal_lookup (name, G_OBJECT_TYPE (object)), 0,
+                                        (object_signal
+                                         ? g_cclosure_new_swap
+                                         : g_cclosure_new) (func,
+                                                            data,
+                                                            (GClosureNotify) destroy_func),
+                                        after);
 }
 
 void
-gtk_signal_connect_while_alive (GtkObject        *object,
-                               const gchar      *signal,
-                               GtkSignalFunc     func,
-                               gpointer          func_data,
-                               GtkObject        *alive_object)
+gtk_signal_compat_matched (GtkObject       *object,
+                          GtkSignalFunc    func,
+                          gpointer         data,
+                          GSignalMatchType match,
+                          guint            action)
 {
-  GtkDisconnectInfo *info;
+  guint n_handlers;
   
-  g_return_if_fail (object != NULL);
   g_return_if_fail (GTK_IS_OBJECT (object));
-  g_return_if_fail (signal != NULL);
-  g_return_if_fail (func != NULL);
-  g_return_if_fail (alive_object != NULL);
-  g_return_if_fail (GTK_IS_OBJECT (alive_object));
-  
-  info = g_new (GtkDisconnectInfo, 1);
-  info->object1 = object;
-  info->object2 = alive_object;
-  
-  info->signal_handler = gtk_signal_connect (object, signal, func, func_data);
-  info->disconnect_handler1 = gtk_signal_connect_object (info->object1,
-                                                        "destroy",
-                                                        GTK_SIGNAL_FUNC (gtk_alive_disconnecter),
-                                                        (GtkObject*) info);
-  info->disconnect_handler2 = gtk_signal_connect_object (info->object2,
-                                                        "destroy",
-                                                        GTK_SIGNAL_FUNC (gtk_alive_disconnecter),
-                                                        (GtkObject*) info);
-}
 
-void
-gtk_signal_connect_object_while_alive (GtkObject        *object,
-                                      const gchar      *signal,
-                                      GtkSignalFunc     func,
-                                      GtkObject        *alive_object)
-{
-  GtkDisconnectInfo *info;
-  
-  g_return_if_fail (object != NULL);
-  g_return_if_fail (GTK_IS_OBJECT (object));
-  g_return_if_fail (signal != NULL);
-  g_return_if_fail (func != NULL);
-  g_return_if_fail (alive_object != NULL);
-  g_return_if_fail (GTK_IS_OBJECT (alive_object));
-  
-  info = g_new (GtkDisconnectInfo, 1);
-  info->object1 = object;
-  info->object2 = alive_object;
-  
-  info->signal_handler = gtk_signal_connect_object (object, signal, func, alive_object);
-  info->disconnect_handler1 = gtk_signal_connect_object (info->object1,
-                                                        "destroy",
-                                                        GTK_SIGNAL_FUNC (gtk_alive_disconnecter),
-                                                        (GtkObject*) info);
-  info->disconnect_handler2 = gtk_signal_connect_object (info->object2,
-                                                        "destroy",
-                                                        GTK_SIGNAL_FUNC (gtk_alive_disconnecter),
-                                                        (GtkObject*) info);
-}
-
-void
-gtk_signal_disconnect (GtkObject *object,
-                      guint      handler_id)
-{
-  GtkHandler *handler;
-  
-  g_return_if_fail (object != NULL);
-  g_return_if_fail (handler_id > 0);
-  
-  handler = gtk_object_get_data (object, handler_key);
-  
-  while (handler)
+  switch (action)
     {
-      if (handler->id == handler_id)
-       {
-         handler->id = 0;
-         handler->blocked = TRUE;
-         gtk_signal_handler_unref (handler, object);
-         return;
-       }
-      handler = handler->next;
+    case 0:  n_handlers = g_signal_handlers_disconnect_matched (object, match, 0, 0, NULL, func, data);         break;
+    case 1:  n_handlers = g_signal_handlers_block_matched (object, match, 0, 0, NULL, func, data);      break;
+    case 2:  n_handlers = g_signal_handlers_unblock_matched (object, match, 0, 0, NULL, func, data);    break;
+    default: n_handlers = 0;                                                                            break;
     }
   
-  g_warning ("gtk_signal_disconnect(): could not find handler (%u)", handler_id);
+  if (!n_handlers)
+    g_warning ("unable to find signal handler for object(%s:%p) with func(%p) and data(%p)",
+              G_OBJECT_TYPE_NAME (object), object, func, data);
 }
 
-void
-gtk_signal_disconnect_by_data (GtkObject *object,
-                              gpointer   data)
+static inline gboolean
+gtk_arg_to_value (GtkArg *arg,
+                 GValue *value)
 {
-  GtkHandler *handler;
-  gint found_one;
-  
-  g_return_if_fail (object != NULL);
-  
-  found_one = FALSE;
-  handler = gtk_object_get_data (object, handler_key);
-  
-  while (handler)
+  switch (G_TYPE_FUNDAMENTAL (arg->type))
     {
-      GtkHandler *handler_next;
-      
-      handler_next = handler->next;
-      if (handler->func_data == data &&
-         handler->id > 0)
-       {
-         found_one = TRUE;
-         handler->id = 0;
-         handler->blocked = TRUE;
-         gtk_signal_handler_unref (handler, object);
-       }
-      handler = handler_next;
+    case G_TYPE_CHAR:          g_value_set_char (value, GTK_VALUE_CHAR (*arg));        break;
+    case G_TYPE_UCHAR:         g_value_set_uchar (value, GTK_VALUE_UCHAR (*arg));      break;
+    case G_TYPE_BOOLEAN:       g_value_set_boolean (value, GTK_VALUE_BOOL (*arg));     break;
+    case G_TYPE_INT:           g_value_set_int (value, GTK_VALUE_INT (*arg));          break;
+    case G_TYPE_UINT:          g_value_set_uint (value, GTK_VALUE_UINT (*arg));        break;
+    case G_TYPE_LONG:          g_value_set_long (value, GTK_VALUE_LONG (*arg));        break;
+    case G_TYPE_ULONG:         g_value_set_ulong (value, GTK_VALUE_ULONG (*arg));      break;
+    case G_TYPE_ENUM:          g_value_set_enum (value, GTK_VALUE_ENUM (*arg));        break;
+    case G_TYPE_FLAGS:         g_value_set_flags (value, GTK_VALUE_FLAGS (*arg));      break;
+    case G_TYPE_FLOAT:         g_value_set_float (value, GTK_VALUE_FLOAT (*arg));      break;
+    case G_TYPE_DOUBLE:                g_value_set_double (value, GTK_VALUE_DOUBLE (*arg));    break;
+    case G_TYPE_STRING:                g_value_set_string (value, GTK_VALUE_STRING (*arg));    break;
+    case G_TYPE_BOXED:         g_value_set_boxed (value, GTK_VALUE_BOXED (*arg));      break;
+    case G_TYPE_POINTER:       g_value_set_pointer (value, GTK_VALUE_POINTER (*arg));  break;
+    case G_TYPE_OBJECT:                g_value_set_object (value, GTK_VALUE_POINTER (*arg));   break;
+    default:
+      return FALSE;
+    }
+  return TRUE;
+}
+
+static inline gboolean
+gtk_arg_static_to_value (GtkArg *arg,
+                        GValue *value)
+{
+  switch (G_TYPE_FUNDAMENTAL (arg->type))
+    {
+    case G_TYPE_CHAR:          g_value_set_char (value, GTK_VALUE_CHAR (*arg));                break;
+    case G_TYPE_UCHAR:         g_value_set_uchar (value, GTK_VALUE_UCHAR (*arg));              break;
+    case G_TYPE_BOOLEAN:       g_value_set_boolean (value, GTK_VALUE_BOOL (*arg));             break;
+    case G_TYPE_INT:           g_value_set_int (value, GTK_VALUE_INT (*arg));                  break;
+    case G_TYPE_UINT:          g_value_set_uint (value, GTK_VALUE_UINT (*arg));                break;
+    case G_TYPE_LONG:          g_value_set_long (value, GTK_VALUE_LONG (*arg));                break;
+    case G_TYPE_ULONG:         g_value_set_ulong (value, GTK_VALUE_ULONG (*arg));              break;
+    case G_TYPE_ENUM:          g_value_set_enum (value, GTK_VALUE_ENUM (*arg));                break;
+    case G_TYPE_FLAGS:         g_value_set_flags (value, GTK_VALUE_FLAGS (*arg));              break;
+    case G_TYPE_FLOAT:         g_value_set_float (value, GTK_VALUE_FLOAT (*arg));              break;
+    case G_TYPE_DOUBLE:                g_value_set_double (value, GTK_VALUE_DOUBLE (*arg));            break;
+    case G_TYPE_STRING:                g_value_set_static_string (value, GTK_VALUE_STRING (*arg));     break;
+    case G_TYPE_BOXED:         g_value_set_static_boxed (value, GTK_VALUE_BOXED (*arg));       break;
+    case G_TYPE_POINTER:       g_value_set_pointer (value, GTK_VALUE_POINTER (*arg));          break;
+    case G_TYPE_OBJECT:                g_value_set_object (value, GTK_VALUE_POINTER (*arg));           break;
+    default:
+      return FALSE;
+    }
+  return TRUE;
+}
+
+static inline gboolean
+gtk_arg_set_from_value (GtkArg  *arg,
+                       GValue  *value,
+                       gboolean copy_string)
+{
+  switch (G_TYPE_FUNDAMENTAL (arg->type))
+    {
+    case G_TYPE_CHAR:          GTK_VALUE_CHAR (*arg) = g_value_get_char (value);       break;
+    case G_TYPE_UCHAR:         GTK_VALUE_UCHAR (*arg) = g_value_get_uchar (value);     break;
+    case G_TYPE_BOOLEAN:       GTK_VALUE_BOOL (*arg) = g_value_get_boolean (value);    break;
+    case G_TYPE_INT:           GTK_VALUE_INT (*arg) = g_value_get_int (value);         break;
+    case G_TYPE_UINT:          GTK_VALUE_UINT (*arg) = g_value_get_uint (value);       break;
+    case G_TYPE_LONG:          GTK_VALUE_LONG (*arg) = g_value_get_long (value);       break;
+    case G_TYPE_ULONG:         GTK_VALUE_ULONG (*arg) = g_value_get_ulong (value);     break;
+    case G_TYPE_ENUM:          GTK_VALUE_ENUM (*arg) = g_value_get_enum (value);       break;
+    case G_TYPE_FLAGS:         GTK_VALUE_FLAGS (*arg) = g_value_get_flags (value);     break;
+    case G_TYPE_FLOAT:         GTK_VALUE_FLOAT (*arg) = g_value_get_float (value);     break;
+    case G_TYPE_DOUBLE:                GTK_VALUE_DOUBLE (*arg) = g_value_get_double (value);   break;
+    case G_TYPE_BOXED:         GTK_VALUE_BOXED (*arg) = g_value_get_boxed (value);     break;
+    case G_TYPE_POINTER:       GTK_VALUE_POINTER (*arg) = g_value_get_pointer (value); break;
+    case G_TYPE_OBJECT:                GTK_VALUE_POINTER (*arg) = g_value_get_object (value);  break;
+    case G_TYPE_STRING:                if (copy_string)
+      GTK_VALUE_STRING (*arg) = g_value_dup_string (value);
+    else
+      GTK_VALUE_STRING (*arg) = g_value_get_string (value);
+    break;
+    default:
+      return FALSE;
+    }
+  return TRUE;
+}
+
+static inline gboolean
+gtk_argloc_set_from_value (GtkArg  *arg,
+                          GValue  *value,
+                          gboolean copy_string)
+{
+  switch (G_TYPE_FUNDAMENTAL (arg->type))
+    {
+    case G_TYPE_CHAR:          *GTK_RETLOC_CHAR (*arg) = g_value_get_char (value);       break;
+    case G_TYPE_UCHAR:         *GTK_RETLOC_UCHAR (*arg) = g_value_get_uchar (value);     break;
+    case G_TYPE_BOOLEAN:       *GTK_RETLOC_BOOL (*arg) = g_value_get_boolean (value);    break;
+    case G_TYPE_INT:           *GTK_RETLOC_INT (*arg) = g_value_get_int (value);         break;
+    case G_TYPE_UINT:          *GTK_RETLOC_UINT (*arg) = g_value_get_uint (value);       break;
+    case G_TYPE_LONG:          *GTK_RETLOC_LONG (*arg) = g_value_get_long (value);       break;
+    case G_TYPE_ULONG:         *GTK_RETLOC_ULONG (*arg) = g_value_get_ulong (value);     break;
+    case G_TYPE_ENUM:          *GTK_RETLOC_ENUM (*arg) = g_value_get_enum (value);       break;
+    case G_TYPE_FLAGS:         *GTK_RETLOC_FLAGS (*arg) = g_value_get_flags (value);     break;
+    case G_TYPE_FLOAT:         *GTK_RETLOC_FLOAT (*arg) = g_value_get_float (value);     break;
+    case G_TYPE_DOUBLE:                *GTK_RETLOC_DOUBLE (*arg) = g_value_get_double (value);   break;
+    case G_TYPE_BOXED:         *GTK_RETLOC_BOXED (*arg) = g_value_get_boxed (value);     break;
+    case G_TYPE_POINTER:       *GTK_RETLOC_POINTER (*arg) = g_value_get_pointer (value); break;
+    case G_TYPE_OBJECT:                *GTK_RETLOC_POINTER (*arg) = g_value_get_object (value);  break;
+    case G_TYPE_STRING:                if (copy_string)
+      *GTK_RETLOC_STRING (*arg) = g_value_dup_string (value);
+    else
+      *GTK_RETLOC_STRING (*arg) = g_value_get_string (value);
+    break;
+    default:
+      return FALSE;
     }
-  
-  if (!found_one)
-    g_warning ("gtk_signal_disconnect_by_data(): could not find handler containing data (0x%0lX)", (long) data);
+  return TRUE;
 }
 
 void
-gtk_signal_handler_block (GtkObject *object,
-                         guint      handler_id)
+gtk_signal_emitv (GtkObject *object,
+                 guint      signal_id,
+                 GtkArg    *args)
 {
-  GtkHandler *tmp;
+  GSignalQuery query;
+  GValue params[SIGNAL_MAX_PARAMS + 1] = { { 0, }, };
+  GValue rvalue = { 0, };
+  guint i;
   
-  g_return_if_fail (object != NULL);
-  g_return_if_fail (handler_id > 0);
+  g_return_if_fail (GTK_IS_OBJECT (object));
   
-  tmp = gtk_object_get_data (object, handler_key);
+  g_signal_query (signal_id, &query);
+  g_return_if_fail (query.signal_id != 0);
+  g_return_if_fail (g_type_is_a (GTK_OBJECT_TYPE (object), query.itype));
+  g_return_if_fail (query.n_params < SIGNAL_MAX_PARAMS);
+  if (query.n_params > 0)
+    g_return_if_fail (args != NULL);
   
-  while (tmp)
+  g_value_init (params + 0, GTK_OBJECT_TYPE (object));
+  g_value_set_object (params + 0, G_OBJECT (object));
+  for (i = 0; i < query.n_params; i++)
     {
-      if (tmp->id == handler_id)
+      GValue *value = params + 1 + i;
+      GtkArg *arg = args + i;
+      
+      g_value_init (value, arg->type & ~G_SIGNAL_TYPE_STATIC_SCOPE);
+      if (!gtk_arg_static_to_value (arg, value))
        {
-         tmp->blocked = TRUE;
+         g_warning ("%s: failed to convert arg type `%s' to value type `%s'",
+                    G_STRLOC, g_type_name (arg->type & ~G_SIGNAL_TYPE_STATIC_SCOPE),
+                    g_type_name (G_VALUE_TYPE (value)));
          return;
        }
-      
-      tmp = tmp->next;
     }
+  if (query.return_type != G_TYPE_NONE)
+    g_value_init (&rvalue, query.return_type);
   
-  g_warning ("gtk_signal_handler_block(): could not find handler (%u)", handler_id);
-}
-
-void
-gtk_signal_handler_block_by_data (GtkObject *object,
-                                 gpointer   data)
-{
-  GtkHandler *handler;
-  gint found_one;
-  
-  g_return_if_fail (object != NULL);
-  
-  if (initialize)
-    gtk_signal_init ();
+  g_signal_emitv (params, signal_id, 0, &rvalue);
   
-  found_one = FALSE;
-  handler = gtk_object_get_data (object, handler_key);
-  
-  while (handler)
+  if (query.return_type != G_TYPE_NONE)
     {
-      if (handler->func_data == data &&
-         handler->id > 0)
-       {
-         found_one = TRUE;
-         handler->blocked = TRUE;
-       }
-      
-      handler = handler->next;
+      gtk_argloc_set_from_value (args + query.n_params, &rvalue, TRUE);
+      g_value_unset (&rvalue);
     }
-  
-  if (!found_one)
-    g_warning ("gtk_signal_handler_block_by_data(): could not find handler containing data (0x%0lX)", (long) data);
+  for (i = 0; i < query.n_params; i++)
+    g_value_unset (params + 1 + i);
+  g_value_unset (params + 0);
 }
 
-void
-gtk_signal_handler_unblock (GtkObject *object,
-                           guint      handler_id)
+static gboolean
+gtk_signal_collect_args (GtkArg        *args,
+                        guint          n_args,
+                        const GtkType *arg_types,
+                        GtkType        return_type,
+                        va_list        var_args)
 {
-  GtkHandler *handler;
-  
-  g_return_if_fail (object != NULL);
-  g_return_if_fail (handler_id > 0);
+  register GtkArg *last_arg;
+  register gboolean failed = FALSE;
   
-  if (initialize)
-    gtk_signal_init ();
-  
-  handler = gtk_object_get_data (object, handler_key);
-  
-  while (handler)
+  for (last_arg = args + n_args; args < last_arg; args++)
     {
-      if (handler->id == handler_id)
-       {
-         handler->blocked = FALSE;
-         return;
-       }
+      register gchar *error;
       
-      handler = handler->next;
-    }
-  
-  g_warning ("gtk_signal_handler_unblock(): could not find handler (%u)", handler_id);
-}
-
-void
-gtk_signal_handler_unblock_by_data (GtkObject *object,
-                                   gpointer   data)
-{
-  GtkHandler *handler;
-  gint found_one;
-  
-  g_return_if_fail (object != NULL);
-  
-  if (initialize)
-    gtk_signal_init ();
-  
-  found_one = FALSE;
-  handler = gtk_object_get_data (object, handler_key);
-  
-  while (handler)
-    {
-      if (handler->func_data == data &&
-         handler->id > 0)
+      args->name = NULL;
+      args->type = *(arg_types++);
+      GTK_ARG_COLLECT_VALUE (args,
+                            var_args,
+                            error);
+      if (error)
        {
-         found_one = TRUE;
-         handler->blocked = FALSE;
+         failed = TRUE;
+         g_warning ("gtk_signal_collect_args(): %s", error);
+         g_free (error);
        }
-      
-      handler = handler->next;
     }
   
-  if (!found_one)
-    g_warning ("gtk_signal_handler_unblock_by_data(): could not find handler containing data (0x%0lX)", (long) data);
-}
-
-void
-gtk_signal_handlers_destroy (GtkObject *object)
-{
-  GtkHandler *handler;
-  
-  /* we make the "optimization" of destroying the first handler in the last
-   * place, since we don't want gtk_signal_handler_unref() to reset the objects
-   * handler_key data on each removal
-   */
+  args->type = return_type;
+  args->name = NULL;
   
-  handler = gtk_object_get_data (object, handler_key);
-  if (handler)
+  return_type = GTK_FUNDAMENTAL_TYPE (return_type);
+  if (return_type != G_TYPE_NONE)
     {
-      handler = handler->next;
-      while (handler)
+      if (return_type != 0) /* FIXME: check for IS_ARG */
        {
-         GtkHandler *next;
+         GTK_VALUE_POINTER (*args) = va_arg (var_args, gpointer);
          
-         next = handler->next;
-         gtk_signal_handler_unref (handler, object);
-         handler = next;
+         if (GTK_VALUE_POINTER (*args) == NULL)
+           {
+             failed = TRUE;
+             g_warning ("gtk_signal_collect_args(): invalid NULL pointer for return argument type `%s'",
+                        gtk_type_name (args->type));
+           }
        }
-      handler = gtk_object_get_data (object, handler_key);
-      gtk_signal_handler_unref (handler, object);
-    }
-}
-
-void
-gtk_signal_default_marshaller (GtkObject      *object,
-                              GtkSignalFunc   func,
-                              gpointer        func_data,
-                              GtkArg         *params)
-{
-  GtkSignalMarshaller0 rfunc;
-  
-  rfunc = (GtkSignalMarshaller0) func;
-  
-  (* rfunc) (object, func_data);
-}
-
-void
-gtk_signal_set_funcs (GtkSignalMarshal marshal_func,
-                     GtkSignalDestroy destroy_func)
-{
-  marshal = marshal_func;
-  destroy = destroy_func;
-}
-
-
-static void
-gtk_signal_init ()
-{
-  if (initialize)
-    {
-      initialize = FALSE;
-      signal_hash_table = g_hash_table_new ((GHashFunc) gtk_signal_hash,
-                                           (GCompareFunc) gtk_signal_compare);
-      signal_info_hash_table = g_hash_table_new ((GHashFunc) gtk_signal_info_hash,
-                                                (GCompareFunc) gtk_signal_info_compare);
-    }
-}
-
-static guint
-gtk_signal_hash (guint *key)
-{
-  return *key;
-}
-
-static gint
-gtk_signal_compare (guint *a,
-                   guint *b)
-{
-  return (*a == *b);
-}
-
-static guint
-gtk_signal_info_hash (GtkSignalInfo *a)
-{
-  return (g_str_hash (a->name) + a->object_type);
-}
-
-static gint
-gtk_signal_info_compare (GtkSignalInfo *a,
-                        GtkSignalInfo *b)
-{
-  return ((a->object_type == b->object_type) &&
-         g_str_equal (a->name, b->name));
-}
-
-static GtkHandler*
-gtk_signal_handler_new ()
-{
-  GtkHandler *handler;
-  
-  if (!handler_mem_chunk)
-    handler_mem_chunk = g_mem_chunk_new ("handler mem chunk", sizeof (GtkHandler),
-                                        1024, G_ALLOC_AND_FREE);
-  
-  handler = g_chunk_new (GtkHandler, handler_mem_chunk);
-  
-  handler->id = 0;
-  handler->ref_count = 1;
-  handler->signal_type = 0;
-  handler->blocked = FALSE;
-  handler->object_signal = FALSE;
-  handler->after = FALSE;
-  handler->no_marshal = FALSE;
-  handler->func = NULL;
-  handler->func_data = NULL;
-  handler->destroy_func = NULL;
-  handler->prev = NULL;
-  handler->next = NULL;
-  
-  return handler;
-}
-
-static void
-gtk_signal_handler_ref (GtkHandler *handler)
-{
-  handler->ref_count += 1;
-}
-
-static void
-gtk_signal_handler_unref (GtkHandler *handler,
-                         GtkObject  *object)
-{
-  if (!handler->ref_count)
-    {
-      /* FIXME: i wanna get removed some when */
-      g_warning ("gtk_signal_handler_unref(): handler with ref_count==0!");
-      return;
-    }
-  
-  handler->ref_count -= 1;
-  if (handler->ref_count == 0)
-    {
-      if (!handler->func && destroy)
-       (* destroy) (handler->func_data);
-      else if (handler->destroy_func)
-       (* handler->destroy_func) (handler->func_data);
-      
-      
-      if (handler->prev)
-       handler->prev->next = handler->next;
       else
-       gtk_object_set_data (object, handler_key, handler->next);
-      if (handler->next)
-       handler->next->prev = handler->prev;
-      
-      g_mem_chunk_free (handler_mem_chunk, handler);
-    }
-}
-
-static void
-gtk_signal_handler_insert (GtkObject  *object,
-                          GtkHandler *handler)
-{
-  GtkHandler *tmp;
-  
-  /* FIXME: remove */ g_assert (handler->next == NULL);
-  /* FIXME: remove */ g_assert (handler->prev == NULL);
-  
-  tmp = gtk_object_get_data (object, handler_key);
-  if (!tmp)
-    gtk_object_set_data (object, handler_key, handler);
-  else
-    while (tmp)
-      {
-       if (tmp->signal_type < handler->signal_type)
-         {
-           if (tmp->prev)
-             {
-               tmp->prev->next = handler;
-               handler->prev = tmp->prev;
-             }
-           else
-             gtk_object_set_data (object, handler_key, handler);
-           tmp->prev = handler;
-           handler->next = tmp;
-           break;
-         }
-       
-       if (!tmp->next)
-         {
-           tmp->next = handler;
-           handler->prev = tmp;
-           break;
-         }
-       tmp = tmp->next;
-      }
-}
-
-static void
-gtk_signal_real_emit (GtkObject *object,
-                     guint      signal_type,
-                     va_list    args)
-{
-  GtkSignal *signal;
-  GtkHandler *handlers;
-  GtkHandlerInfo info;
-  guchar **signal_func_offset;
-  GtkArg         params[MAX_PARAMS];
-  
-  signal = g_hash_table_lookup (signal_hash_table, &signal_type);
-  g_return_if_fail (signal != NULL);
-  g_return_if_fail (gtk_type_is_a (GTK_OBJECT_TYPE (object),
-                                  signal->info.object_type));
-  
-  if ((signal->run_type & GTK_RUN_NO_RECURSE) &&
-      gtk_emission_check (current_emissions, object, signal_type))
-    {
-      gtk_emission_add (&restart_emissions, object, signal_type);
-      return;
-    }
-  
-  gtk_params_get (params, signal->nparams, signal->params,
-                 signal->return_val, args);
-  
-  gtk_emission_add (&current_emissions, object, signal_type);
-  
-  gtk_object_ref (object);
-  
-restart:
-  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)
-       (* signal->marshaller) (object, (GtkSignalFunc) *signal_func_offset,
-                               NULL, params);
-    }
-  
-  info.object = object;
-  info.marshaller = signal->marshaller;
-  info.params = params;
-  info.param_types = signal->params;
-  info.return_val = signal->return_val;
-  info.nparams = signal->nparams;
-  info.run_type = signal->run_type;
-  info.signal_type = signal_type;
-  
-  handlers = gtk_signal_get_handlers (object, signal_type);
-  switch (gtk_handlers_run (handlers, &info, FALSE))
-    {
-    case DONE:
-      goto done;
-    case RESTART:
-      goto restart;
-    }
-  
-  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)
-       (* signal->marshaller) (object, (GtkSignalFunc) *signal_func_offset,
-                               NULL, params);
-    }
-  
-  handlers = gtk_signal_get_handlers (object, signal_type);
-  switch (gtk_handlers_run (handlers, &info, TRUE))
-    {
-    case DONE:
-      goto done;
-    case RESTART:
-      goto restart;
-    }
-  
-done:
-  
-  gtk_emission_remove (&current_emissions, object, signal_type);
-  
-  if (signal->run_type & GTK_RUN_NO_RECURSE)
-    gtk_emission_remove (&restart_emissions, object, signal_type);
-  
-  gtk_object_unref (object);
-}
-
-static GtkHandler*
-gtk_signal_get_handlers (GtkObject *object,
-                        guint      signal_type)
-{
-  GtkHandler *handlers;
-  
-  g_return_val_if_fail (object != NULL, NULL);
-  g_return_val_if_fail (signal_type >= 1, NULL);
-  
-  handlers = gtk_object_get_data (object, handler_key);
-  
-  while (handlers)
-    {
-      if (handlers->signal_type == signal_type)
-       return handlers;
-      handlers = handlers->next;
-    }
-  
-  return NULL;
-}
-
-guint
-gtk_signal_handler_pending (GtkObject           *object,
-                           guint                signal_id,
-                           gboolean             may_be_blocked)
-{
-  GtkHandler *handlers;
-  guint handler_id;
-  
-  g_return_val_if_fail (object != NULL, 0);
-  g_return_val_if_fail (signal_id >= 1, 0);
-  
-  handlers = gtk_signal_get_handlers (object, signal_id);
-  
-  handler_id = 0;
-  while (handlers && handlers->signal_type == signal_id)
-    {
-      if (handlers->id > 0 &&
-         (may_be_blocked ||
-          !handlers->blocked))
        {
-         handler_id = handlers->id;
-         break;
+         failed = TRUE;
+         g_warning ("gtk_signal_collect_args(): unsupported return argument type `%s'",
+                    gtk_type_name (args->type));
        }
-      
-      handlers = handlers->next;
     }
+  else
+    GTK_VALUE_POINTER (*args) = NULL;
   
-  return handler_id;
+  return failed;
 }
 
-static guint
-gtk_signal_connect_by_type (GtkObject       *object,
-                           guint            signal_type,
-                           GtkSignalFunc    func,
-                           gpointer         func_data,
-                           GtkSignalDestroy destroy_func,
-                           gint             object_signal,
-                           gint             after,
-                           gint             no_marshal)
+#if 0
+void
+gtk_signal_emit (GtkObject *object,
+                guint      signal_id,
+                ...)
 {
-  GtkObjectClass *class;
-  GtkHandler *handler;
-  gint found_it;
+  GtkArg args[SIGNAL_MAX_PARAMS + 1];
+  GSignalQuery query;
+  gboolean abort;
+  va_list var_args;
   
-  g_return_val_if_fail (object != NULL, 0);
-  g_return_val_if_fail (object->klass != NULL, 0);
-  
-  /* Search through the signals for this object and make
-   *  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.
-   */
-  found_it = FALSE;
-  class = object->klass;
-  while (class)
-    {
-      GtkType parent;
-      guint *object_signals;
-      guint 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;
-    }
+  g_return_if_fail (GTK_IS_OBJECT (object));
   
-  if (!found_it)
-    {
-      g_warning ("gtk_signal_connect_by_type(): could not find signal id (%u) in the `%s' class ancestry",
-                signal_type,
-                gtk_type_name (class->type));
-      return 0;
-    }
+  g_signal_query (signal_id, &query);
+  g_return_if_fail (query.signal_id != 0);
+  g_return_if_fail (query.n_params < SIGNAL_MAX_PARAMS);
   
-  handler = gtk_signal_handler_new ();
-  handler->id = next_handler_id++;
-  handler->signal_type = signal_type;
-  handler->object_signal = object_signal;
-  handler->func = func;
-  handler->func_data = func_data;
-  handler->destroy_func = destroy_func;
-  handler->after = after != FALSE;
-  handler->no_marshal = no_marshal;
+  va_start (var_args, signal_id);
+  abort = gtk_signal_collect_args (args,
+                                  query.n_params,
+                                  query.param_types,
+                                  query.return_type,
+                                  var_args);
+  va_end (var_args);
   
-  gtk_signal_handler_insert (object, handler);
-  return handler->id;
+  if (!abort)
+    gtk_signal_emitv (object, signal_id, args);
 }
+#endif
 
-static GtkEmission*
-gtk_emission_new ()
+void
+gtk_signal_emit (GtkObject *object,
+                guint      signal_id,
+                ...)
 {
-  GtkEmission *emission;
-  
-  if (!emission_mem_chunk)
-    emission_mem_chunk = g_mem_chunk_new ("emission mem chunk", sizeof (GtkEmission),
-                                         1024, G_ALLOC_AND_FREE);
+  va_list var_args;
   
-  emission = g_chunk_new (GtkEmission, emission_mem_chunk);
-  
-  emission->object = NULL;
-  emission->signal_type = 0;
-  
-  return emission;
-}
+  g_return_if_fail (GTK_IS_OBJECT (object));
 
-static void
-gtk_emission_destroy (GtkEmission *emission)
-{
-  g_mem_chunk_free (emission_mem_chunk, emission);
+  va_start (var_args, signal_id);
+  g_signal_emit_valist (G_OBJECT (object), signal_id, 0, var_args);
+  va_end (var_args);
 }
 
-static void
-gtk_emission_add (GList     **emissions,
-                 GtkObject  *object,
-                 guint       signal_type)
+void
+gtk_signal_emit_by_name (GtkObject   *object,
+                        const gchar *name,
+                        ...)
 {
-  GtkEmission *emission;
+  GtkArg args[SIGNAL_MAX_PARAMS + 1];
+  GSignalQuery query;
+  gboolean abort;
+  va_list var_args;
   
-  g_return_if_fail (emissions != NULL);
-  g_return_if_fail (object != NULL);
-  
-  emission = gtk_emission_new ();
-  emission->object = object;
-  emission->signal_type = signal_type;
+  g_return_if_fail (GTK_IS_OBJECT (object));
+  g_return_if_fail (name != NULL);
   
-  *emissions = g_list_prepend (*emissions, emission);
-}
-
-static void
-gtk_emission_remove (GList     **emissions,
-                    GtkObject  *object,
-                    guint       signal_type)
-{
-  GtkEmission *emission;
-  GList *tmp;
+  g_signal_query (g_signal_lookup (name, GTK_OBJECT_TYPE (object)), &query);
+  g_return_if_fail (query.signal_id != 0);
+  g_return_if_fail (query.n_params < SIGNAL_MAX_PARAMS);
   
-  g_return_if_fail (emissions != NULL);
+  va_start (var_args, name);
+  abort = gtk_signal_collect_args (args,
+                                  query.n_params,
+                                  query.param_types,
+                                  query.return_type,
+                                  var_args);
+  va_end (var_args);
   
-  tmp = *emissions;
-  while (tmp)
-    {
-      emission = tmp->data;
-      
-      if ((emission->object == object) &&
-         (emission->signal_type == signal_type))
-       {
-         gtk_emission_destroy (emission);
-         *emissions = g_list_remove_link (*emissions, tmp);
-         g_list_free (tmp);
-         break;
-       }
-      
-      tmp = tmp->next;
-    }
+  if (!abort)
+    gtk_signal_emitv (object, query.signal_id, args);
 }
 
-static gint
-gtk_emission_check (GList     *emissions,
-                   GtkObject *object,
-                   guint      signal_type)
-{
-  GtkEmission *emission;
-  GList *tmp;
-  
-  tmp = emissions;
-  while (tmp)
-    {
-      emission = tmp->data;
-      tmp = tmp->next;
-      
-      if ((emission->object == object) &&
-         (emission->signal_type == signal_type))
-       return TRUE;
-    }
-  return FALSE;
-}
-
-static gint
-gtk_handlers_run (GtkHandler     *handlers,
-                 GtkHandlerInfo *info,
-                 gint            after)
-{
-  while (handlers && handlers->signal_type == info->signal_type)
-    {
-      GtkHandler *handlers_next;
-      
-      gtk_signal_handler_ref (handlers);
-      
-      if (!handlers->blocked && (handlers->after == after))
-       {
-         if (handlers->func)
-           {
-             if (handlers->no_marshal)
-               (* (GtkCallbackMarshal)handlers->func) (info->object,
-                                                       handlers->func_data,
-                                                       info->nparams,
-                                                       info->params);
-             else if (handlers->object_signal)
-               (* info->marshaller) ((GtkObject*) handlers->func_data, /* don't GTK_OBJECT() cast */
-                                     handlers->func,
-                                     handlers->func_data,
-                                     info->params);
-             else
-               (* info->marshaller) (info->object,
-                                     handlers->func,
-                                     handlers->func_data,
-                                     info->params);
-           }
-         else if (marshal)
-           (* marshal) (info->object,
-                        handlers->func_data,
-                        info->nparams,
-                        info->params,
-                        info->param_types,
-                        info->return_val);
-         
-          if (gtk_emission_check (stop_emissions, info->object,
-                                 info->signal_type))
-           {
-             gtk_emission_remove (&stop_emissions, info->object,
-                                  info->signal_type);
-             
-             if (info->run_type & GTK_RUN_NO_RECURSE)
-               gtk_emission_remove (&restart_emissions, info->object,
-                                    info->signal_type);
-             gtk_signal_handler_unref (handlers, info->object);
-             return DONE;
-           }
-         else if ((info->run_type & GTK_RUN_NO_RECURSE) &&
-                  gtk_emission_check (restart_emissions, info->object,
-                                      info->signal_type))
-           {
-             gtk_emission_remove (&restart_emissions, info->object,
-                                  info->signal_type);
-             gtk_signal_handler_unref (handlers, info->object);
-             return RESTART;
-           }
-       }
-      
-      handlers_next = handlers->next;
-      gtk_signal_handler_unref (handlers, info->object);
-      handlers = handlers_next;
-    }
-  
-  return 0;
-}
-
-static void
-gtk_params_get (GtkArg         *params,
-               guint           nparams,
-               GtkType        *param_types,
-               GtkType         return_val,
-               va_list         args)
+void
+gtk_signal_emitv_by_name (GtkObject   *object,
+                         const gchar *name,
+                         GtkArg      *args)
 {
-  gint i;
-  
-  for (i = 0; i < nparams; i++)
-    {
-      params[i].type = param_types[i];
-      params[i].name = NULL;
-      
-      switch (GTK_FUNDAMENTAL_TYPE (param_types[i]))
-       {
-       case GTK_TYPE_INVALID:
-         break;
-       case GTK_TYPE_NONE:
-         break;
-       case GTK_TYPE_CHAR:
-         GTK_VALUE_CHAR(params[i]) = va_arg (args, gint);
-         break;
-       case GTK_TYPE_BOOL:
-         GTK_VALUE_BOOL(params[i]) = va_arg (args, gint);
-         break;
-       case GTK_TYPE_INT:
-         GTK_VALUE_INT(params[i]) = va_arg (args, gint);
-         break;
-       case GTK_TYPE_UINT:
-         GTK_VALUE_UINT(params[i]) = va_arg (args, guint);
-         break;
-       case GTK_TYPE_ENUM:
-         GTK_VALUE_ENUM(params[i]) = va_arg (args, gint);
-         break;
-       case GTK_TYPE_FLAGS:
-         GTK_VALUE_FLAGS(params[i]) = va_arg (args, gint);
-         break;
-       case GTK_TYPE_LONG:
-         GTK_VALUE_LONG(params[i]) = va_arg (args, glong);
-         break;
-       case GTK_TYPE_ULONG:
-         GTK_VALUE_ULONG(params[i]) = va_arg (args, gulong);
-         break;
-       case GTK_TYPE_FLOAT:
-         GTK_VALUE_FLOAT(params[i]) = va_arg (args, gfloat);
-         break;
-       case GTK_TYPE_DOUBLE:
-         GTK_VALUE_DOUBLE(params[i]) = va_arg (args, gdouble);
-         break;
-       case GTK_TYPE_STRING:
-         GTK_VALUE_STRING(params[i]) = va_arg (args, gchar*);
-         break;
-       case GTK_TYPE_POINTER:
-         GTK_VALUE_POINTER(params[i]) = va_arg (args, gpointer);
-         break;
-       case GTK_TYPE_BOXED:
-         GTK_VALUE_BOXED(params[i]) = va_arg (args, gpointer);
-         break;
-       case GTK_TYPE_SIGNAL:
-         GTK_VALUE_SIGNAL(params[i]).f = va_arg (args, GtkFunction);
-         GTK_VALUE_SIGNAL(params[i]).d = va_arg (args, gpointer);
-         break;
-       case GTK_TYPE_FOREIGN:
-         GTK_VALUE_FOREIGN(params[i]).data = va_arg (args, gpointer);
-         GTK_VALUE_FOREIGN(params[i]).notify = 
-           va_arg (args, GtkDestroyNotify);
-         break;
-       case GTK_TYPE_CALLBACK:
-         GTK_VALUE_CALLBACK(params[i]).marshal = 
-           va_arg (args, GtkCallbackMarshal);
-         GTK_VALUE_CALLBACK(params[i]).data = va_arg (args, gpointer);
-         GTK_VALUE_CALLBACK(params[i]).notify =
-           va_arg (args, GtkDestroyNotify);
-         break;
-       case GTK_TYPE_C_CALLBACK:
-         GTK_VALUE_C_CALLBACK(params[i]).func = va_arg (args, GtkFunction);
-         GTK_VALUE_C_CALLBACK(params[i]).func_data = va_arg (args, gpointer);
-         break;
-       case GTK_TYPE_ARGS:
-         GTK_VALUE_ARGS(params[i]).n_args = va_arg (args, gint);
-         GTK_VALUE_ARGS(params[i]).args = va_arg (args, GtkArg*);
-         break;
-       case GTK_TYPE_OBJECT:
-         GTK_VALUE_OBJECT(params[i]) = va_arg (args, GtkObject*);
-         if (GTK_VALUE_OBJECT(params[i]) != NULL &&
-             !GTK_CHECK_TYPE (GTK_VALUE_OBJECT(params[i]), params[i].type))
-           g_warning ("signal arg `%s' is not of type `%s'",
-                      gtk_type_name (GTK_OBJECT_TYPE (GTK_VALUE_OBJECT(params[i]))),
-                      gtk_type_name (params[i].type));
-         break;
-       default:
-         g_error ("unsupported type `%s' in signal arg",
-                  gtk_type_name (params[i].type));
-         break;
-       }
-    }
-  
-  params[i].type = return_val;
-  params[i].name = NULL;
+  g_return_if_fail (GTK_IS_OBJECT (object));
   
-  switch (GTK_FUNDAMENTAL_TYPE (return_val))
-    {
-    case GTK_TYPE_INVALID:
-      break;
-    case GTK_TYPE_NONE:
-      break;
-    case GTK_TYPE_CHAR:
-      params[i].d.pointer_data = va_arg (args, gchar*);
-      break;
-    case GTK_TYPE_BOOL:
-      params[i].d.pointer_data = va_arg (args, gint*);
-      break;
-    case GTK_TYPE_INT:
-      params[i].d.pointer_data = va_arg (args, gint*);
-      break;
-    case GTK_TYPE_UINT:
-      params[i].d.pointer_data = va_arg (args, guint*);
-      break;
-    case GTK_TYPE_ENUM:
-      params[i].d.pointer_data = va_arg (args, gint*);
-      break;
-    case GTK_TYPE_FLAGS:
-      params[i].d.pointer_data = va_arg (args, gint*);
-      break;
-    case GTK_TYPE_LONG:
-      params[i].d.pointer_data = va_arg (args, glong*);
-      break;
-    case GTK_TYPE_ULONG:
-      params[i].d.pointer_data = va_arg (args, gulong*);
-      break;
-    case GTK_TYPE_FLOAT:
-      params[i].d.pointer_data = va_arg (args, gfloat*);
-      break;
-    case GTK_TYPE_DOUBLE:
-      params[i].d.pointer_data = va_arg (args, gdouble*);
-      break;
-    case GTK_TYPE_STRING:
-      params[i].d.pointer_data = va_arg (args, gchar**);
-      break;
-    case GTK_TYPE_POINTER:
-      params[i].d.pointer_data = va_arg (args, gpointer*);
-      break;
-    case GTK_TYPE_BOXED:
-      params[i].d.pointer_data = va_arg (args, gpointer*);
-      break;
-    case GTK_TYPE_OBJECT:
-      params[i].d.pointer_data = va_arg (args, GtkObject**);
-      break;
-    case GTK_TYPE_SIGNAL:
-    case GTK_TYPE_FOREIGN:
-    case GTK_TYPE_CALLBACK:
-    case GTK_TYPE_C_CALLBACK:
-    case GTK_TYPE_ARGS:
-    default:
-      g_error ("unsupported type `%s' in signal return",
-              gtk_type_name (return_val));
-      break;
-    }
+  gtk_signal_emitv (object, g_signal_lookup (name, GTK_OBJECT_TYPE (object)), args);
 }