-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_by_id (object, gtk_handler_quark);
-
- while (handler)
- {
- if (handler->id == handler_id)
- {
- handler->id = 0;
- handler->blocked += 1;
- gtk_signal_handler_unref (handler, object);
- return;
- }
- handler = handler->next;
- }
-
- g_warning ("gtk_signal_disconnect(): could not find handler (%u)", handler_id);
-}
-
-void
-gtk_signal_disconnect_by_func (GtkObject *object,
- GtkSignalFunc func,
- gpointer data)
-{
- GtkHandler *handler;
- gint found_one;
-
- g_return_if_fail (object != NULL);
- g_return_if_fail (func != NULL);
-
- found_one = FALSE;
- handler = gtk_object_get_data_by_id (object, gtk_handler_quark);
-
- while (handler)
- {
- GtkHandler *handler_next;
-
- handler_next = handler->next;
- if ((handler->id > 0) &&
- (handler->func == func) &&
- (handler->func_data == data))
- {
- found_one = TRUE;
- handler->id = 0;
- handler->blocked += 1;
- gtk_signal_handler_unref (handler, object);
- }
- handler = handler_next;
- }
-
- if (!found_one)
- g_warning ("gtk_signal_disconnect_by_func(): could not find handler (0x%0lX) containing data (0x%0lX)", (long) func, (long) data);
-}
-
-void
-gtk_signal_disconnect_by_data (GtkObject *object,
- gpointer data)
-{
- GtkHandler *handler;
- gint found_one;
-
- g_return_if_fail (object != NULL);
-
- found_one = FALSE;
- handler = gtk_object_get_data_by_id (object, gtk_handler_quark);
-
- while (handler)
- {
- GtkHandler *handler_next;
-
- handler_next = handler->next;
- if ((handler->id > 0) &&
- (handler->func_data == data))
- {
- found_one = TRUE;
- handler->id = 0;
- handler->blocked += 1;
- gtk_signal_handler_unref (handler, object);
- }
- handler = handler_next;
- }
-
- if (!found_one)
- g_warning ("gtk_signal_disconnect_by_data(): could not find handler containing data (0x%0lX)", (long) data);
-}
-
-void
-gtk_signal_handler_block (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_by_id (object, gtk_handler_quark);
-
- while (handler)
- {
- if (handler->id == handler_id)
- {
- handler->blocked += 1;
- return;
- }
- handler = handler->next;
- }
-
- g_warning ("gtk_signal_handler_block(): could not find handler (%u)", handler_id);
-}
-
-void
-gtk_signal_handler_block_by_func (GtkObject *object,
- GtkSignalFunc func,
- gpointer data)
-{
- GtkHandler *handler;
- gint found_one;
-
- g_return_if_fail (object != NULL);
- g_return_if_fail (func != NULL);
-
- found_one = FALSE;
- handler = gtk_object_get_data_by_id (object, gtk_handler_quark);
-
- while (handler)
- {
- if ((handler->id > 0) &&
- (handler->func == func) &&
- (handler->func_data == data))
- {
- found_one = TRUE;
- handler->blocked += 1;
- }
- handler = handler->next;
- }
-
- if (!found_one)
- g_warning ("gtk_signal_handler_block_by_func(): could not find handler (0x%0lX) containing data (0x%0lX)", (long) func, (long) data);
-}
-
-void
-gtk_signal_handler_block_by_data (GtkObject *object,
- gpointer data)
-{
- GtkHandler *handler;
- gint found_one;
-
- g_return_if_fail (object != NULL);
-
- found_one = FALSE;
- handler = gtk_object_get_data_by_id (object, gtk_handler_quark);
-
- while (handler)
- {
- if ((handler->id > 0) &&
- (handler->func_data == data))
- {
- found_one = TRUE;
- handler->blocked += 1;
- }
- handler = handler->next;
- }
-
- if (!found_one)
- g_warning ("gtk_signal_handler_block_by_data(): could not find handler containing data (0x%0lX)", (long) data);
-}
-
-void
-gtk_signal_handler_unblock (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_by_id (object, gtk_handler_quark);
-
- while (handler)
- {
- if (handler->id == handler_id)
- {
- if (handler->blocked > 0)
- handler->blocked -= 1;
- else
- g_warning ("gtk_signal_handler_unblock(): handler (%u) is not blocked", handler_id);
- return;
- }
- handler = handler->next;
- }
-
- g_warning ("gtk_signal_handler_unblock(): could not find handler (%u)", handler_id);
-}
-
-void
-gtk_signal_handler_unblock_by_func (GtkObject *object,
- GtkSignalFunc func,
- gpointer data)
-{
- GtkHandler *handler;
- gint found_one;
-
- g_return_if_fail (object != NULL);
- g_return_if_fail (func != NULL);
-
- found_one = FALSE;
- handler = gtk_object_get_data_by_id (object, gtk_handler_quark);
-
- while (handler)
- {
- if ((handler->id > 0) &&
- (handler->func == func) &&
- (handler->func_data == data) &&
- (handler->blocked > 0))
- {
- handler->blocked -= 1;
- found_one = TRUE;
- }
- handler = handler->next;
- }
-
- if (!found_one)
- g_warning ("gtk_signal_handler_unblock_by_func(): could not find blocked handler (0x%0lX) containing data (0x%0lX)", (long) func, (long) data);
-}
-
-void
-gtk_signal_handler_unblock_by_data (GtkObject *object,
- gpointer data)
-{
- GtkHandler *handler;
- gint found_one;
-
- g_return_if_fail (object != NULL);
-
- found_one = FALSE;
- handler = gtk_object_get_data_by_id (object, gtk_handler_quark);
-
- while (handler)
- {
- if ((handler->id > 0) &&
- (handler->func_data == data) &&
- (handler->blocked > 0))
- {
- handler->blocked -= 1;
- found_one = TRUE;
- }
- handler = handler->next;
- }
-
- if (!found_one)
- g_warning ("gtk_signal_handler_unblock_by_data(): could not find blocked 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
- */
-
- handler = gtk_object_get_data_by_id (object, gtk_handler_quark);
- if (handler)
- {
- handler = handler->next;
- while (handler)
- {
- GtkHandler *next;
-
- next = handler->next;
- if (handler->id > 0)
- gtk_signal_handler_unref (handler, object);
- handler = next;
- }
- handler = gtk_object_get_data_by_id (object, gtk_handler_quark);
- if (handler->id > 0)
- gtk_signal_handler_unref (handler, object);
- }
-}
-
-void
-gtk_signal_set_funcs (GtkSignalMarshal marshal_func,
- GtkSignalDestroy destroy_func)
-{
- global_marshaller = marshal_func;
- global_destroy_notify = destroy_func;
-}
-
-static guint
-gtk_signal_hash (gconstpointer h)
-{
- register const GtkSignalHash *hash = h;
-
- return hash->object_type ^ hash->quark;
-}
-
-static gint
-gtk_signal_compare (gconstpointer h1,
- gconstpointer h2)
-{
- register const GtkSignalHash *hash1 = h1;
- register const GtkSignalHash *hash2 = h2;
-
- return (hash1->quark == hash2->quark &&
- hash1->object_type == hash2->object_type);
-}
-
-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_mem_chunk_free (gtk_disconnect_info_mem_chunk, info);
-
- return 0;
-}
-
-static GtkHandler*
-gtk_signal_handler_new (void)
-{
- GtkHandler *handler;
-
- if (!gtk_handler_free_list)
- {
- GtkHandler *handler_block;
- guint i;
-
- handler_block = g_new0 (GtkHandler, HANDLER_BLOCK_SIZE);
- for (i = 1; i < HANDLER_BLOCK_SIZE; i++)
- {
- (handler_block + i)->next = gtk_handler_free_list;
- gtk_handler_free_list = (handler_block + i);
- }
-
- handler = handler_block;
- }
- else
- {
- handler = gtk_handler_free_list;
- gtk_handler_free_list = handler->next;
- }
-
- handler->id = 0;
- handler->blocked = 0;
- handler->signal_id = 0;
- handler->object_signal = FALSE;
- handler->after = FALSE;
- handler->no_marshal = FALSE;
- handler->ref_count = 1;
- 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 somewhen */
- g_warning ("gtk_signal_handler_unref(): handler with ref_count==0!");
- return;
- }
-
- handler->ref_count -= 1;
-
- if (handler->ref_count == 0)
- {
- if (handler->destroy_func)
- (* handler->destroy_func) (handler->func_data);
- else if (!handler->func && global_destroy_notify)
- (* global_destroy_notify) (handler->func_data);
-
- if (handler->prev)
- handler->prev->next = handler->next;
- else if (handler->next)
- gtk_object_set_data_by_id (object, gtk_handler_quark, handler->next);
- else
- {
- GTK_OBJECT_UNSET_FLAGS (object, GTK_CONNECTED);
- gtk_object_set_data_by_id (object, gtk_handler_quark, NULL);
- }
- if (handler->next)
- handler->next->prev = handler->prev;
-
- handler->next = gtk_handler_free_list;
- gtk_handler_free_list = 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_by_id (object, gtk_handler_quark);
- if (!tmp)
- {
- GTK_OBJECT_SET_FLAGS (object, GTK_CONNECTED);
- gtk_object_set_data_by_id (object, gtk_handler_quark, handler);
- }
- else
- while (tmp)
- {
- if (tmp->signal_id < handler->signal_id)
- {
- if (tmp->prev)
- {
- tmp->prev->next = handler;
- handler->prev = tmp->prev;
- }
- else
- gtk_object_set_data_by_id (object, gtk_handler_quark, handler);
- tmp->prev = handler;
- handler->next = tmp;
- break;
- }
-
- if (!tmp->next)
- {
- tmp->next = handler;
- handler->prev = tmp;
- break;
- }
- tmp = tmp->next;
- }
-}
-
-
-#ifdef G_ENABLE_DEBUG
-/* value typically set via gdb */
-static GtkObject *gtk_trace_signal_object = NULL;
-#endif /* G_ENABLE_DEBUG */
-
-
-static void
-gtk_signal_real_emit (GtkObject *object,
- guint signal_id,
- GtkArg *params)
-{
- GtkSignal signal;
- GtkHandler *handlers;
- GtkSignalFunc signal_func;
- GtkEmission *emission;
-
- /* gtk_handlers_run() expects a reentrant GtkSignal*, so we allocate
- * it locally on the stack. we save some lookups ourselves with this as well.
- */
- signal = *LOOKUP_SIGNAL_ID (signal_id);
- if (signal.function_offset)
- signal_func = G_STRUCT_MEMBER (GtkSignalFunc, ((GTypeInstance*) object)->g_class, signal.function_offset);
- else
- signal_func = NULL;
-
-#ifdef G_ENABLE_DEBUG
- if (gtk_debug_flags & GTK_DEBUG_SIGNALS ||
- object == gtk_trace_signal_object)
- g_message ("%s::%s emitted (object=%p class-method=%p)\n",
- gtk_type_name (GTK_OBJECT_TYPE (object)),
- signal.name,
- object,
- signal_func);
-#endif /* G_ENABLE_DEBUG */
-
- if (signal.signal_flags & GTK_RUN_NO_RECURSE)
- {
- gint state;
-
- state = gtk_emission_check (current_emissions, object, signal_id);
- if (state)
- {
- if (state > 1)
- g_warning ("gtk_signal_real_emit(): emission (%u) for object `%s' cannot be restarted from emission hook",
- signal_id,
- gtk_type_name (GTK_OBJECT_TYPE (object)));
- else if (!gtk_emission_check (restart_emissions, object, signal_id))
- gtk_emission_add (&restart_emissions, object, signal_id);
-
- return;
- }
- }
-
- gtk_object_ref (object);
-
- gtk_emission_add (¤t_emissions, object, signal_id);
- emission = current_emissions;
-
- emission_restart:
-
- if (signal.signal_flags & GTK_RUN_FIRST && signal_func)
- {
- signal.marshaller (object, signal_func, NULL, params);
-
- if (stop_emissions && gtk_emission_check (stop_emissions, object, signal_id))
- {
- gtk_emission_remove (&stop_emissions, object, signal_id);
- goto emission_done;
- }
- else if (restart_emissions &&
- signal.signal_flags & GTK_RUN_NO_RECURSE &&
- gtk_emission_check (restart_emissions, object, signal_id))
- {
- gtk_emission_remove (&restart_emissions, object, signal_id);
-
- goto emission_restart;
- }
- }
-
- if (signal.hook_list && !GTK_OBJECT_DESTROYED (object))
- {
- GtkEmissionHookData data;
-
- data.object = object;
- data.n_params = signal.nparams;
- data.params = params;
- data.signal_id = signal_id;
- emission->in_hook = 1;
- g_hook_list_marshal_check (signal.hook_list, TRUE, gtk_emission_hook_marshaller, &data);
- emission->in_hook = 0;
- }
-
- if (GTK_OBJECT_CONNECTED (object))
- {
- handlers = gtk_signal_get_handlers (object, signal_id);
- if (handlers)
- {
- gint return_val;
-
- return_val = gtk_handlers_run (handlers, &signal, object, params, FALSE);
- switch (return_val)
- {
- case EMISSION_CONTINUE:
- break;
- case EMISSION_RESTART:
- goto emission_restart;
- case EMISSION_DONE:
- goto emission_done;
- }
- }
- }
-
- if (signal.signal_flags & GTK_RUN_LAST && signal_func)
- {
- signal.marshaller (object, signal_func, NULL, params);
-
- if (stop_emissions && gtk_emission_check (stop_emissions, object, signal_id))
- {
- gtk_emission_remove (&stop_emissions, object, signal_id);
- goto emission_done;
- }
- else if (restart_emissions &&
- signal.signal_flags & GTK_RUN_NO_RECURSE &&
- gtk_emission_check (restart_emissions, object, signal_id))
- {
- gtk_emission_remove (&restart_emissions, object, signal_id);
-
- goto emission_restart;
- }
- }
-
- if (GTK_OBJECT_CONNECTED (object))
- {
- handlers = gtk_signal_get_handlers (object, signal_id);
- if (handlers)
- {
- gint return_val;
-
- return_val = gtk_handlers_run (handlers, &signal, object, params, TRUE);
- switch (return_val)
- {
- case EMISSION_CONTINUE:
- break;
- case EMISSION_RESTART:
- goto emission_restart;
- case EMISSION_DONE:
- goto emission_done;
- }
- }
- }
-
- emission_done:
- if (restart_emissions && signal.signal_flags & GTK_RUN_NO_RECURSE)
- gtk_emission_remove (&restart_emissions, object, signal_id);
-
- gtk_emission_remove (¤t_emissions, object, signal_id);
-
- gtk_object_unref (object);
-}
-
-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);
-
- if (GTK_OBJECT_CONNECTED (object))
- handlers = gtk_signal_get_handlers (object, signal_id);
- else
- return 0;
-
- handler_id = 0;
- while (handlers && handlers->signal_id == signal_id)
- {
- if (handlers->id > 0 &&
- (may_be_blocked || handlers->blocked == FALSE))
- {
- handler_id = handlers->id;
- break;
- }
-
- handlers = handlers->next;
- }
-
- return handler_id;
-}
-
-guint
-gtk_signal_handler_pending_by_func (GtkObject *object,
- guint signal_id,
- gboolean may_be_blocked,
- GtkSignalFunc func,
- gpointer data)
-{
- GtkHandler *handlers;
- guint handler_id;
-
- g_return_val_if_fail (object != NULL, 0);
- g_return_val_if_fail (func != NULL, 0);
- g_return_val_if_fail (signal_id >= 1, 0);
-
- if (GTK_OBJECT_CONNECTED (object))
- handlers = gtk_signal_get_handlers (object, signal_id);
- else
- return 0;
-
- handler_id = 0;
- while (handlers && handlers->signal_id == signal_id)
- {
- if (handlers->id > 0 &&
- handlers->func == func &&
- handlers->func_data == data &&
- (may_be_blocked || handlers->blocked == 0))
- {
- handler_id = handlers->id;
- break;
- }
-
- handlers = handlers->next;
- }
-
- return handler_id;
-}
-
-gint
-gtk_signal_handler_pending_by_id (GtkObject *object,
- guint handler_id,
- gboolean may_be_blocked)
-{
- GtkHandler *handlers;
-
- g_return_val_if_fail (object != NULL, FALSE);
- g_return_val_if_fail (handler_id >= 1, FALSE);
-
- if (GTK_OBJECT_CONNECTED (object))
- handlers = gtk_object_get_data_by_id (object, gtk_handler_quark);
- else
- return FALSE;
-
- while (handlers)
- {
- if (handlers->id == handler_id)
- return may_be_blocked || handlers->blocked == 0;
-
- handlers = handlers->next;
- }
-
- return FALSE;
-}
-
-guint
-gtk_signal_add_emission_hook (guint signal_id,
- GtkEmissionHook hook_func,
- gpointer data)
-{
- return gtk_signal_add_emission_hook_full (signal_id, hook_func, data, NULL);
-}
-
-guint
-gtk_signal_add_emission_hook_full (guint signal_id,
- GtkEmissionHook hook_func,
- gpointer data,
- GDestroyNotify destroy)
-{
- static guint seq_hook_id = 1;
- GtkSignal *signal;
- GHook *hook;
-
- g_return_val_if_fail (signal_id > 0, 0);
- g_return_val_if_fail (hook_func != NULL, 0);
-
- signal = LOOKUP_SIGNAL_ID (signal_id);
- g_return_val_if_fail (signal != NULL, 0);
- if (signal->signal_flags & GTK_RUN_NO_HOOKS)
- {
- g_warning ("gtk_signal_add_emission_hook_full(): signal \"%s\" does not support emission hooks",
- signal->name);
- return 0;
- }
-
- if (!signal->hook_list)
- {
- signal->hook_list = g_new (GHookList, 1);
- g_hook_list_init (signal->hook_list, sizeof (GHook));
- }
-
- hook = g_hook_alloc (signal->hook_list);
- hook->data = data;
- hook->func = hook_func;
- hook->destroy = destroy;
-
- signal->hook_list->seq_id = seq_hook_id;
- g_hook_prepend (signal->hook_list, hook);
- seq_hook_id = signal->hook_list->seq_id;
-
- return hook->hook_id;
-}
-
-void
-gtk_signal_remove_emission_hook (guint signal_id,
- guint hook_id)
-{
- GtkSignal *signal;
-
- g_return_if_fail (signal_id > 0);
- g_return_if_fail (hook_id > 0);
-
- signal = LOOKUP_SIGNAL_ID (signal_id);
- g_return_if_fail (signal != NULL);
-
- if (!signal->hook_list || !g_hook_destroy (signal->hook_list, hook_id))
- g_warning ("gtk_signal_remove_emission_hook(): could not find hook (%u)", hook_id);
-}
-
-static gboolean
-gtk_emission_hook_marshaller (GHook *hook,
- gpointer data_p)
-{
- GtkEmissionHookData *data = data_p;
- GtkEmissionHook func;
-
- func = hook->func;
-
- if (!GTK_OBJECT_DESTROYED (data->object))
- return func (data->object, data->signal_id,
- data->n_params, data->params,
- hook->data);
- else
- return TRUE;
-}
-
-static guint
-gtk_signal_connect_by_type (GtkObject *object,
- guint signal_id,
- GtkSignalFunc func,
- gpointer func_data,
- GtkSignalDestroy destroy_func,
- gint object_signal,
- gint after,
- gint no_marshal)
-{
- GtkObjectClass *class;
- GtkHandler *handler;
- gint found_it;
- GtkSignal *signal;
-
- g_return_val_if_fail (GTK_IS_OBJECT (object), 0);
-
- signal = LOOKUP_SIGNAL_ID (signal_id);
-
- /* 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.
- * As of now (1998-05-27) this lookup shouldn't be neccessarry
- * anymore since gtk_signal_lookup() has been reworked to only
- * return correct signal ids per class-branch.
- */
- found_it = FALSE;
- class = GTK_OBJECT_GET_CLASS (object);
- 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_id)
- {
- found_it = TRUE;
- break;
- }
-
- parent = g_type_parent (GTK_CLASS_TYPE (class));
- if (GTK_TYPE_IS_OBJECT (parent))
- class = g_type_class_peek (parent);
- else
- class = NULL;
- }
-
- if (!found_it)
- {
- g_warning ("gtk_signal_connect_by_type(): could not find signal id (%u) in the `%s' class ancestry",
- signal_id,
- GTK_OBJECT_TYPE_NAME (object));
- return 0;
- }
-
- handler = gtk_signal_handler_new ();
- handler->id = gtk_handler_id++;
- handler->signal_id = signal_id;
- handler->object_signal = object_signal != FALSE;
- handler->func = func;
- handler->func_data = func_data;
- handler->destroy_func = destroy_func;
- handler->after = after != FALSE;
- handler->no_marshal = no_marshal;
-
- gtk_signal_handler_insert (object, handler);
- return handler->id;
-}
-
-static GtkEmission*
-gtk_emission_new (void)
-{
- GtkEmission *emission;
-
- if (!gtk_free_emissions)
- {
- GtkEmission *emission_block;
- guint i;
-
- emission_block = g_new0 (GtkEmission, EMISSION_BLOCK_SIZE);
- for (i = 1; i < EMISSION_BLOCK_SIZE; i++)
- {
- (emission_block + i)->next = gtk_free_emissions;
- gtk_free_emissions = (emission_block + i);
- }
-
- emission = emission_block;
- }
- else
- {
- emission = gtk_free_emissions;
- gtk_free_emissions = emission->next;
- }
-
- emission->object = NULL;
- emission->signal_id = 0;
- emission->in_hook = 0;
- emission->next = NULL;
-
- return emission;
-}
-
-static void
-gtk_emission_add (GtkEmission **emissions,
- GtkObject *object,
- guint signal_id)
-{
- GtkEmission *emission;
-
- g_return_if_fail (emissions != NULL);
- g_return_if_fail (object != NULL);
-
- emission = gtk_emission_new ();
- emission->object = object;
- emission->signal_id = signal_id;
-
- emission->next = *emissions;
- *emissions = emission;
-}
-
-static void
-gtk_emission_remove (GtkEmission **emissions,
- GtkObject *object,
- guint signal_id)
-{
- GtkEmission *emission, *last;
-
- g_return_if_fail (emissions != NULL);
-
- last = NULL;
- emission = *emissions;
- while (emission)
- {
- if (emission->object == object && emission->signal_id == signal_id)
- {
- if (last)
- last->next = emission->next;
- else
- *emissions = emission->next;
-
- emission->next = gtk_free_emissions;
- gtk_free_emissions = emission;
- break;
- }
-
- last = emission;
- emission = last->next;
- }
-}
-
-static gint
-gtk_emission_check (GtkEmission *emission,
- GtkObject *object,
- guint signal_id)
-{
- while (emission)
- {
- if (emission->object == object && emission->signal_id == signal_id)
- return 1 + emission->in_hook;
- emission = emission->next;
- }
- return FALSE;
-}
-
-static gint
-gtk_handlers_run (GtkHandler *handlers,
- GtkSignal *signal,
- GtkObject *object,
- GtkArg *params,
- gint after)
-{
- /* *signal is a local copy on the stack of gtk_signal_real_emit(),
- * so we don't need to look it up every time we invoked a function.
- */
- while (handlers && handlers->signal_id == signal->signal_id)
- {
- GtkHandler *handlers_next;
-
- gtk_signal_handler_ref (handlers);
-
- if (!handlers->blocked && handlers->after == after)
- {
- if (handlers->func)
- {
- if (handlers->no_marshal)
- (* (GtkCallbackMarshal) handlers->func) (object,
- handlers->func_data,
- signal->nparams,
- params);
- else if (handlers->object_signal)
- /* don't cast with GTK_OBJECT () */
- (* signal->marshaller) ((GtkObject*) handlers->func_data,
- handlers->func,
- object,
- params);
- else
- (* signal->marshaller) (object,
- handlers->func,
- handlers->func_data,
- params);
- }
- else if (global_marshaller)
- (* global_marshaller) (object,
- handlers->func_data,
- signal->nparams,
- params,
- signal->params,
- signal->return_val);
-
- if (stop_emissions && gtk_emission_check (stop_emissions,
- object,
- signal->signal_id))
- {
- gtk_emission_remove (&stop_emissions, object, signal->signal_id);
-
- gtk_signal_handler_unref (handlers, object);
-
- return EMISSION_DONE;
- }
- else if (restart_emissions &&
- signal->signal_flags & GTK_RUN_NO_RECURSE &&
- gtk_emission_check (restart_emissions, object, signal->signal_id))
- {
- gtk_emission_remove (&restart_emissions, object, signal->signal_id);
-
- gtk_signal_handler_unref (handlers, object);
-
- return EMISSION_RESTART;
- }
- }
-
- handlers_next = handlers->next;
- gtk_signal_handler_unref (handlers, object);
- handlers = handlers_next;
- }
-
- return EMISSION_CONTINUE;
-}
-
-static gboolean
-gtk_signal_collect_params (GtkArg *params,
- guint n_params,
- GtkType *param_types,
- GtkType return_type,
- va_list var_args)
-{
- register GtkArg *last_param;
- register gboolean failed = FALSE;
-
- for (last_param = params + n_params; params < last_param; params++)
- {
- register gchar *error;
-
- params->name = NULL;
- params->type = *(param_types++);
- GTK_ARG_COLLECT_VALUE (params,
- var_args,
- error);
- if (error)
- {
- failed = TRUE;
- g_warning ("gtk_signal_collect_params(): %s", error);
- g_free (error);
- }
- }
-
- params->type = return_type;
- params->name = NULL;
-
- return_type = GTK_FUNDAMENTAL_TYPE (return_type);
- if (return_type != GTK_TYPE_NONE)
- {
- if (return_type != 0) // FIXME: check for IS_PARAM
- {
- GTK_VALUE_POINTER (*params) = va_arg (var_args, gpointer);
-
- if (GTK_VALUE_POINTER (*params) == NULL)
- {
- failed = TRUE;
- g_warning ("gtk_signal_collect_params(): invalid NULL pointer for return argument type `%s'",
- gtk_type_name (params->type));
- }
- }
- else
- {
- failed = TRUE;
- g_warning ("gtk_signal_collect_params(): unsupported return argument type `%s'",
- gtk_type_name (params->type));
- }
- }
- else
- GTK_VALUE_POINTER (*params) = NULL;
-
- return failed;
-}