* 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 (¤t_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 (¤t_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);
}