1 /* GTK - The GIMP Toolkit
2 * Copyright (C) 1995-1997 Peter Mattis, Spencer Kimball and Josh MacDonald
4 * This library is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU Library General Public
6 * License as published by the Free Software Foundation; either
7 * version 2 of the License, or (at your option) any later version.
9 * This library is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 * Library General Public License for more details.
14 * You should have received a copy of the GNU Library General Public
15 * License along with this library; if not, write to the Free
16 * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
19 #include "gtksignal.h"
26 #define GTK_RUN_TYPE(x) ((x) & GTK_RUN_MASK)
29 typedef struct _GtkSignal GtkSignal;
30 typedef struct _GtkSignalInfo GtkSignalInfo;
31 typedef struct _GtkHandler GtkHandler;
32 typedef struct _GtkHandlerInfo GtkHandlerInfo;
33 typedef struct _GtkEmission GtkEmission;
35 typedef void (*GtkSignalMarshaller0) (GtkObject *object,
49 GtkSignalRunType run_type;
50 GtkSignalMarshaller marshaller;
60 guint object_signal : 1;
67 GtkSignalDestroy destroy_func;
72 struct _GtkHandlerInfo
75 GtkSignalMarshaller marshaller;
79 GtkSignalRunType run_type;
91 static void gtk_signal_init (void);
92 static guint gtk_signal_hash (gint *key);
93 static gint gtk_signal_compare (gint *a,
95 static guint gtk_signal_info_hash (GtkSignalInfo *a);
96 static gint gtk_signal_info_compare (GtkSignalInfo *a,
98 static GtkHandler* gtk_signal_handler_new (void);
99 static void gtk_signal_handler_ref (GtkHandler *handler);
100 static void gtk_signal_handler_unref (GtkHandler *handler,
102 static void gtk_signal_handler_insert (GtkObject *object,
103 GtkHandler *handler);
104 static void gtk_signal_real_emit (GtkObject *object,
107 static GtkHandler* gtk_signal_get_handlers (GtkObject *object,
109 static gint gtk_signal_connect_by_type (GtkObject *object,
114 GtkSignalDestroy destroy_func,
117 static GtkEmission* gtk_emission_new (void);
118 static void gtk_emission_destroy (GtkEmission *emission);
119 static void gtk_emission_add (GList **emissions,
122 static void gtk_emission_remove (GList **emissions,
125 static gint gtk_emission_check (GList *emissions,
128 static gint gtk_handlers_run (GtkHandler *handlers,
129 GtkHandlerInfo *info,
131 static void gtk_params_get (GtkArg *params,
133 GtkType *param_types,
138 static gint initialize = TRUE;
139 static GHashTable *signal_hash_table = NULL;
140 static GHashTable *signal_info_hash_table = NULL;
141 static guint next_signal = 1;
142 static guint next_handler_id = 1;
144 static const gchar *handler_key = "gtk-signal-handlers";
146 static GMemChunk *handler_mem_chunk = NULL;
147 static GMemChunk *emission_mem_chunk = NULL;
149 static GList *current_emissions = NULL;
150 static GList *stop_emissions = NULL;
151 static GList *restart_emissions = NULL;
153 static GtkSignalMarshal marshal = NULL;
154 static GtkSignalDestroy destroy = NULL;
158 gtk_signal_new (const gchar *name,
159 GtkSignalRunType run_type,
161 gint function_offset,
162 GtkSignalMarshaller marshaller,
172 g_return_val_if_fail (nparams < 16, 0);
176 params = g_new (GtkType, nparams);
178 va_start (args, nparams);
180 for (i = 0; i < nparams; i++)
181 params[i] = va_arg (args, GtkType);
188 return_id = gtk_signal_newv (name,
203 gtk_signal_newv (const gchar *name,
204 GtkSignalRunType run_type,
206 gint function_offset,
207 GtkSignalMarshaller marshaller,
217 g_return_val_if_fail (name != NULL, 0);
218 g_return_val_if_fail (marshaller != NULL, 0);
219 g_return_val_if_fail (nparams < 16, 0);
221 g_return_val_if_fail (params != NULL, 0);
226 info.name = (char*)name;
227 info.object_type = object_type;
229 type = g_hash_table_lookup (signal_info_hash_table, &info);
232 g_warning ("signal \"%s\" already exists in the \"%s\" class ancestry\n",
233 name, gtk_type_name (object_type));
237 signal = g_new (GtkSignal, 1);
238 signal->info.name = g_strdup (name);
239 signal->info.object_type = object_type;
240 signal->info.signal_type = next_signal++;
241 signal->function_offset = function_offset;
242 signal->run_type = run_type;
243 signal->marshaller = marshaller;
244 signal->return_val = return_val;
245 signal->nparams = nparams;
249 signal->params = g_new (GtkType, nparams);
251 for (i = 0; i < nparams; i++)
252 signal->params[i] = params[i];
255 signal->params = NULL;
257 g_hash_table_insert (signal_hash_table, &signal->info.signal_type, signal);
258 g_hash_table_insert (signal_info_hash_table, &signal->info, &signal->info.signal_type);
260 return signal->info.signal_type;
264 gtk_signal_query (gint signal_num)
266 GtkSignalQuery *query;
269 signal = g_hash_table_lookup (signal_hash_table, &signal_num);
272 query = g_new (GtkSignalQuery, 1);
274 query->object_type = signal->info.object_type;
275 query->signal_name = signal->info.name;
276 query->is_user_signal = signal->function_offset == 0;
277 query->run_type = signal->run_type;
278 query->return_val = signal->return_val;
279 query->nparams = signal->nparams;
280 query->params = signal->params;
289 gtk_signal_lookup (const gchar *name,
295 g_return_val_if_fail (name != NULL, 0);
300 info.name = (char*)name;
304 info.object_type = object_type;
306 type = g_hash_table_lookup (signal_info_hash_table, &info);
310 object_type = gtk_type_parent (object_type);
317 gtk_signal_name (gint signal_num)
321 signal = g_hash_table_lookup (signal_hash_table, &signal_num);
323 return signal->info.name;
329 gtk_signal_emit (GtkObject *object,
335 g_return_if_fail (object != NULL);
340 va_start (args, signal_type);
342 gtk_signal_real_emit (object, signal_type, args);
348 gtk_signal_emit_by_name (GtkObject *object,
355 g_return_if_fail (object != NULL);
360 type = gtk_signal_lookup (name, GTK_OBJECT_TYPE (object));
364 va_start (args, name);
366 gtk_signal_real_emit (object, type, args);
373 gtk_signal_emit_stop (GtkObject *object,
376 g_return_if_fail (object != NULL);
377 g_return_if_fail (signal_type >= 1);
382 if (gtk_emission_check (current_emissions, object, signal_type))
383 gtk_emission_add (&stop_emissions, object, signal_type);
387 gtk_signal_emit_stop_by_name (GtkObject *object,
392 g_return_if_fail (object != NULL);
393 g_return_if_fail (name != NULL);
398 type = gtk_signal_lookup (name, GTK_OBJECT_TYPE (object));
400 gtk_signal_emit_stop (object, type);
404 gtk_signal_connect (GtkObject *object,
411 g_return_val_if_fail (object != NULL, 0);
416 type = gtk_signal_lookup (name, GTK_OBJECT_TYPE (object));
419 g_warning ("could not find signal type \"%s\" in the \"%s\" class ancestry",
420 name, gtk_type_name (GTK_OBJECT_TYPE (object)));
424 return gtk_signal_connect_by_type (object, type, FALSE,
425 func, func_data, NULL,
430 gtk_signal_connect_after (GtkObject *object,
437 g_return_val_if_fail (object != NULL, 0);
442 type = gtk_signal_lookup (name, GTK_OBJECT_TYPE (object));
445 g_warning ("could not find signal type \"%s\" in the \"%s\" class ancestry",
446 name, gtk_type_name (GTK_OBJECT_TYPE (object)));
450 return gtk_signal_connect_by_type (object, type, FALSE,
451 func, func_data, NULL,
456 gtk_signal_connect_interp (GtkObject *object,
458 GtkCallbackMarshal func,
460 GtkDestroyNotify destroy_func,
465 g_return_val_if_fail (object != NULL, 0);
470 type = gtk_signal_lookup (name, GTK_OBJECT_TYPE (object));
473 g_warning ("could not find signal type \"%s\" in the \"%s\" class ancestry",
474 name, gtk_type_name (GTK_OBJECT_TYPE (object)));
478 return gtk_signal_connect_by_type (object, type, FALSE,
479 (GtkSignalFunc) func, func_data,
480 destroy_func, after, TRUE);
484 gtk_signal_connect_object (GtkObject *object,
487 GtkObject *slot_object)
491 g_return_val_if_fail (object != NULL, 0);
492 /* slot_object needs to be treated as ordinary pointer */
497 type = gtk_signal_lookup (name, GTK_OBJECT_TYPE (object));
500 g_warning ("could not find signal type \"%s\" in the \"%s\" class ancestry",
501 name, gtk_type_name (GTK_OBJECT_TYPE (object)));
505 return gtk_signal_connect_by_type (object, type, TRUE,
506 func, slot_object, NULL,
511 gtk_signal_connect_object_after (GtkObject *object,
514 GtkObject *slot_object)
518 g_return_val_if_fail (object != NULL, 0);
523 type = gtk_signal_lookup (name, GTK_OBJECT_TYPE (object));
526 g_warning ("could not find signal type \"%s\" in the \"%s\" class ancestry",
527 name, gtk_type_name (GTK_OBJECT_TYPE (object)));
531 return gtk_signal_connect_by_type (object, type, TRUE,
532 func, slot_object, NULL,
536 typedef struct _GtkDisconnectInfo GtkDisconnectInfo;
537 struct _GtkDisconnectInfo
540 gint disconnect_handler1;
543 gint disconnect_handler2;
547 gtk_alive_disconnecter (GtkDisconnectInfo *info)
549 g_return_val_if_fail (info != NULL, 0);
551 gtk_signal_disconnect (info->object1, info->disconnect_handler1);
552 gtk_signal_disconnect (info->object1, info->signal_handler);
553 gtk_signal_disconnect (info->object2, info->disconnect_handler2);
560 gtk_signal_connect_while_alive (GtkObject *object,
564 GtkObject *alive_object)
566 GtkDisconnectInfo *info;
568 g_return_if_fail (object != NULL);
569 g_return_if_fail (GTK_IS_OBJECT (object));
570 g_return_if_fail (signal != NULL);
571 g_return_if_fail (func != NULL);
572 g_return_if_fail (alive_object != NULL);
573 g_return_if_fail (GTK_IS_OBJECT (alive_object));
575 info = g_new (GtkDisconnectInfo, 1);
576 info->object1 = object;
577 info->object2 = alive_object;
579 info->signal_handler = gtk_signal_connect (object, signal, func, func_data);
580 info->disconnect_handler1 = gtk_signal_connect_object (info->object1,
582 GTK_SIGNAL_FUNC (gtk_alive_disconnecter),
584 info->disconnect_handler2 = gtk_signal_connect_object (info->object2,
586 GTK_SIGNAL_FUNC (gtk_alive_disconnecter),
591 gtk_signal_connect_object_while_alive (GtkObject *object,
594 GtkObject *alive_object)
596 GtkDisconnectInfo *info;
598 g_return_if_fail (object != NULL);
599 g_return_if_fail (GTK_IS_OBJECT (object));
600 g_return_if_fail (signal != NULL);
601 g_return_if_fail (func != NULL);
602 g_return_if_fail (alive_object != NULL);
603 g_return_if_fail (GTK_IS_OBJECT (alive_object));
605 info = g_new (GtkDisconnectInfo, 1);
606 info->object1 = object;
607 info->object2 = alive_object;
609 info->signal_handler = gtk_signal_connect_object (object, signal, func, alive_object);
610 info->disconnect_handler1 = gtk_signal_connect_object (info->object1,
612 GTK_SIGNAL_FUNC (gtk_alive_disconnecter),
614 info->disconnect_handler2 = gtk_signal_connect_object (info->object2,
616 GTK_SIGNAL_FUNC (gtk_alive_disconnecter),
621 gtk_signal_disconnect (GtkObject *object,
626 g_return_if_fail (object != NULL);
627 g_return_if_fail (an_id > 0);
629 handler = gtk_object_get_data (object, handler_key);
633 if (handler->id == an_id)
636 handler->blocked = TRUE;
637 gtk_signal_handler_unref (handler, object);
640 handler = handler->next;
643 g_warning ("gtk_signal_disconnect(): could not find handler (%d)", an_id);
647 gtk_signal_disconnect_by_data (GtkObject *object,
653 g_return_if_fail (object != NULL);
656 handler = gtk_object_get_data (object, handler_key);
660 GtkHandler *handler_next;
662 handler_next = handler->next;
663 if (handler->func_data == data &&
668 handler->blocked = TRUE;
669 gtk_signal_handler_unref (handler, object);
671 handler = handler_next;
675 g_warning ("gtk_signal_disconnect_by_data(): could not find handler containing data (0x%0lX)", (long) data);
679 gtk_signal_handler_block (GtkObject *object,
684 g_return_if_fail (object != NULL);
685 g_return_if_fail (an_id > 0);
687 tmp = gtk_object_get_data (object, handler_key);
691 if (tmp->id == an_id)
700 g_warning ("gtk_signal_handler_block(): could not find handler (%d)", an_id);
704 gtk_signal_handler_block_by_data (GtkObject *object,
710 g_return_if_fail (object != NULL);
716 handler = gtk_object_get_data (object, handler_key);
720 if (handler->func_data == data &&
724 handler->blocked = TRUE;
727 handler = handler->next;
731 g_warning ("gtk_signal_handler_block_by_data(): could not find handler containing data (0x%0lX)", (long) data);
735 gtk_signal_handler_unblock (GtkObject *object,
740 g_return_if_fail (object != NULL);
741 g_return_if_fail (an_id > 0);
746 handler = gtk_object_get_data (object, handler_key);
750 if (handler->id == an_id)
752 handler->blocked = FALSE;
756 handler = handler->next;
759 g_warning ("gtk_signal_handler_unblock(): could not find handler (%d)", an_id);
763 gtk_signal_handler_unblock_by_data (GtkObject *object,
769 g_return_if_fail (object != NULL);
775 handler = gtk_object_get_data (object, handler_key);
779 if (handler->func_data == data &&
783 handler->blocked = FALSE;
786 handler = handler->next;
790 g_warning ("gtk_signal_handler_unblock_by_data(): could not find handler containing data (0x%0lX)", (long) data);
794 gtk_signal_handlers_destroy (GtkObject *object)
798 /* we make the "optimization" of destroying the first handler in the last
799 * place, since we don't want gtk_signal_handler_unref() to reset the objects
800 * handler_key data on each removal
803 handler = gtk_object_get_data (object, handler_key);
806 handler = handler->next;
811 next = handler->next;
812 gtk_signal_handler_unref (handler, object);
815 handler = gtk_object_get_data (object, handler_key);
816 gtk_signal_handler_unref (handler, object);
821 gtk_signal_default_marshaller (GtkObject *object,
826 GtkSignalMarshaller0 rfunc;
828 rfunc = (GtkSignalMarshaller0) func;
830 (* rfunc) (object, func_data);
834 gtk_signal_set_funcs (GtkSignalMarshal marshal_func,
835 GtkSignalDestroy destroy_func)
837 marshal = marshal_func;
838 destroy = destroy_func;
848 signal_hash_table = g_hash_table_new ((GHashFunc) gtk_signal_hash,
849 (GCompareFunc) gtk_signal_compare);
850 signal_info_hash_table = g_hash_table_new ((GHashFunc) gtk_signal_info_hash,
851 (GCompareFunc) gtk_signal_info_compare);
856 gtk_signal_hash (gint *key)
862 gtk_signal_compare (gint *a,
869 gtk_signal_info_hash (GtkSignalInfo *a)
871 return (g_str_hash (a->name) + a->object_type);
875 gtk_signal_info_compare (GtkSignalInfo *a,
878 return ((a->object_type == b->object_type) &&
879 g_str_equal (a->name, b->name));
883 gtk_signal_handler_new ()
887 if (!handler_mem_chunk)
888 handler_mem_chunk = g_mem_chunk_new ("handler mem chunk", sizeof (GtkHandler),
889 1024, G_ALLOC_AND_FREE);
891 handler = g_chunk_new (GtkHandler, handler_mem_chunk);
894 handler->ref_count = 1;
895 handler->signal_type = 0;
896 handler->blocked = FALSE;
897 handler->object_signal = FALSE;
898 handler->after = FALSE;
899 handler->no_marshal = FALSE;
900 handler->func = NULL;
901 handler->func_data = NULL;
902 handler->destroy_func = NULL;
903 handler->prev = NULL;
904 handler->next = NULL;
910 gtk_signal_handler_ref (GtkHandler *handler)
912 handler->ref_count += 1;
916 gtk_signal_handler_unref (GtkHandler *handler,
919 if (!handler->ref_count)
921 /* FIXME: i wanna get removed some when (maybe at gtk+-1.0?) */
922 g_warning ("gtk_signal_handler_unref(): handler with ref_count==0!");
926 handler->ref_count -= 1;
927 if (handler->ref_count == 0)
929 if (!handler->func && destroy)
930 (* destroy) (handler->func_data);
931 else if (handler->destroy_func)
932 (* handler->destroy_func) (handler->func_data);
936 handler->prev->next = handler->next;
938 gtk_object_set_data (object, handler_key, handler->next);
940 handler->next->prev = handler->prev;
942 g_mem_chunk_free (handler_mem_chunk, handler);
947 gtk_signal_handler_insert (GtkObject *object,
952 /* FIXME: remove */ g_assert (handler->next == NULL);
953 /* FIXME: remove */ g_assert (handler->prev == NULL);
955 tmp = gtk_object_get_data (object, handler_key);
957 gtk_object_set_data (object, handler_key, handler);
961 if (tmp->signal_type < handler->signal_type)
965 tmp->prev->next = handler;
966 handler->prev = tmp->prev;
969 gtk_object_set_data (object, handler_key, handler);
986 gtk_signal_real_emit (GtkObject *object,
991 GtkHandler *handlers;
993 guchar **signal_func_offset;
994 GtkArg params[MAX_PARAMS];
996 g_return_if_fail (object != NULL);
997 g_return_if_fail (signal_type >= 1);
999 signal = g_hash_table_lookup (signal_hash_table, &signal_type);
1000 g_return_if_fail (signal != NULL);
1001 g_return_if_fail (gtk_type_is_a (GTK_OBJECT_TYPE (object),
1002 signal->info.object_type));
1004 if ((signal->run_type & GTK_RUN_NO_RECURSE) &&
1005 gtk_emission_check (current_emissions, object, signal_type))
1007 gtk_emission_add (&restart_emissions, object, signal_type);
1011 gtk_params_get (params, signal->nparams, signal->params,
1012 signal->return_val, args);
1014 gtk_emission_add (¤t_emissions, object, signal_type);
1016 gtk_object_ref (object);
1019 if (GTK_RUN_TYPE (signal->run_type) != GTK_RUN_LAST && signal->function_offset != 0)
1021 signal_func_offset = (guchar**) ((guchar*) object->klass +
1022 signal->function_offset);
1023 if (*signal_func_offset)
1024 (* signal->marshaller) (object, (GtkSignalFunc) *signal_func_offset,
1028 info.object = object;
1029 info.marshaller = signal->marshaller;
1030 info.params = params;
1031 info.param_types = signal->params;
1032 info.return_val = signal->return_val;
1033 info.nparams = signal->nparams;
1034 info.run_type = signal->run_type;
1035 info.signal_type = signal_type;
1037 handlers = gtk_signal_get_handlers (object, signal_type);
1038 switch (gtk_handlers_run (handlers, &info, FALSE))
1046 if (GTK_RUN_TYPE (signal->run_type) != GTK_RUN_FIRST && signal->function_offset != 0)
1048 signal_func_offset = (guchar**) ((guchar*) object->klass +
1049 signal->function_offset);
1050 if (*signal_func_offset)
1051 (* signal->marshaller) (object, (GtkSignalFunc) *signal_func_offset,
1055 handlers = gtk_signal_get_handlers (object, signal_type);
1056 switch (gtk_handlers_run (handlers, &info, TRUE))
1066 gtk_emission_remove (¤t_emissions, object, signal_type);
1068 if (signal->run_type & GTK_RUN_NO_RECURSE)
1069 gtk_emission_remove (&restart_emissions, object, signal_type);
1071 gtk_object_unref (object);
1075 gtk_signal_get_handlers (GtkObject *object,
1078 GtkHandler *handlers;
1080 g_return_val_if_fail (object != NULL, NULL);
1081 g_return_val_if_fail (signal_type >= 1, NULL);
1083 handlers = gtk_object_get_data (object, handler_key);
1087 if (handlers->signal_type == signal_type)
1089 handlers = handlers->next;
1096 gtk_signal_handler_pending (GtkObject *object,
1098 gboolean may_be_blocked)
1100 GtkHandler *handlers;
1103 g_return_val_if_fail (object != NULL, 0);
1104 g_return_val_if_fail (signal_type >= 1, 0);
1106 handlers = gtk_signal_get_handlers (object, signal_type);
1109 while (handlers && handlers->signal_type == signal_type)
1111 if (handlers->id > 0 &&
1113 !handlers->blocked))
1115 handler_id = handlers->id;
1119 handlers = handlers->next;
1126 gtk_signal_connect_by_type (GtkObject *object,
1131 GtkSignalDestroy destroy_func,
1135 GtkObjectClass *class;
1136 GtkHandler *handler;
1139 g_return_val_if_fail (object != NULL, 0);
1140 g_return_val_if_fail (object->klass != NULL, 0);
1142 /* Search through the signals for this object and make
1143 * sure the one we are adding is valid. We need to perform
1144 * the lookup on the objects parents as well. If it isn't
1145 * valid then issue a warning and return.
1148 class = object->klass;
1152 gint *object_signals;
1156 object_signals = class->signals;
1157 nsignals = class->nsignals;
1159 for (i = 0; i < nsignals; i++)
1160 if (object_signals[i] == signal_type)
1166 parent = gtk_type_parent (class->type);
1168 class = gtk_type_class (parent);
1175 g_warning ("could not find signal (%d) in object's list of signals", signal_type);
1179 handler = gtk_signal_handler_new ();
1180 handler->id = next_handler_id++;
1181 handler->signal_type = signal_type;
1182 handler->object_signal = object_signal;
1183 handler->func = func;
1184 handler->func_data = func_data;
1185 handler->destroy_func = destroy_func;
1186 handler->after = after != FALSE;
1187 handler->no_marshal = no_marshal;
1189 gtk_signal_handler_insert (object, handler);
1196 GtkEmission *emission;
1198 if (!emission_mem_chunk)
1199 emission_mem_chunk = g_mem_chunk_new ("emission mem chunk", sizeof (GtkEmission),
1200 1024, G_ALLOC_AND_FREE);
1202 emission = g_chunk_new (GtkEmission, emission_mem_chunk);
1204 emission->object = NULL;
1205 emission->signal_type = 0;
1211 gtk_emission_destroy (GtkEmission *emission)
1213 g_mem_chunk_free (emission_mem_chunk, emission);
1217 gtk_emission_add (GList **emissions,
1221 GtkEmission *emission;
1223 g_return_if_fail (emissions != NULL);
1224 g_return_if_fail (object != NULL);
1226 emission = gtk_emission_new ();
1227 emission->object = object;
1228 emission->signal_type = signal_type;
1230 *emissions = g_list_prepend (*emissions, emission);
1234 gtk_emission_remove (GList **emissions,
1238 GtkEmission *emission;
1241 g_return_if_fail (emissions != NULL);
1242 g_return_if_fail (object != NULL);
1247 emission = tmp->data;
1249 if ((emission->object == object) &&
1250 (emission->signal_type == signal_type))
1252 gtk_emission_destroy (emission);
1253 *emissions = g_list_remove_link (*emissions, tmp);
1263 gtk_emission_check (GList *emissions,
1267 GtkEmission *emission;
1270 g_return_val_if_fail (object != NULL, FALSE);
1275 emission = tmp->data;
1278 if ((emission->object == object) &&
1279 (emission->signal_type == signal_type))
1286 gtk_handlers_run (GtkHandler *handlers,
1287 GtkHandlerInfo *info,
1292 GtkHandler *handlers_next;
1294 gtk_signal_handler_ref (handlers);
1296 if (handlers->signal_type != info->signal_type)
1298 gtk_signal_handler_unref (handlers, info->object);
1302 if (!handlers->blocked && (handlers->after == after))
1306 if (handlers->no_marshal)
1307 (* (GtkCallbackMarshal)handlers->func) (info->object,
1308 handlers->func_data,
1311 else if (handlers->object_signal)
1312 (* info->marshaller) ((GtkObject*) handlers->func_data, /* don't GTK_OBJECT() cast */
1314 handlers->func_data,
1317 (* info->marshaller) (info->object,
1319 handlers->func_data,
1323 (* marshal) (info->object,
1324 handlers->func_data,
1330 if (gtk_emission_check (stop_emissions, info->object,
1333 gtk_emission_remove (&stop_emissions, info->object,
1336 if (info->run_type & GTK_RUN_NO_RECURSE)
1337 gtk_emission_remove (&restart_emissions, info->object,
1339 gtk_signal_handler_unref (handlers, info->object);
1342 else if ((info->run_type & GTK_RUN_NO_RECURSE) &&
1343 gtk_emission_check (restart_emissions, info->object,
1346 gtk_emission_remove (&restart_emissions, info->object,
1348 gtk_signal_handler_unref (handlers, info->object);
1353 handlers_next = handlers->next;
1354 gtk_signal_handler_unref (handlers, info->object);
1355 handlers = handlers_next;
1362 gtk_params_get (GtkArg *params,
1364 GtkType *param_types,
1370 for (i = 0; i < nparams; i++)
1372 params[i].type = param_types[i];
1373 params[i].name = NULL;
1375 switch (GTK_FUNDAMENTAL_TYPE (param_types[i]))
1377 case GTK_TYPE_INVALID:
1382 GTK_VALUE_CHAR(params[i]) = va_arg (args, gint);
1385 GTK_VALUE_BOOL(params[i]) = va_arg (args, gint);
1388 GTK_VALUE_INT(params[i]) = va_arg (args, gint);
1391 GTK_VALUE_UINT(params[i]) = va_arg (args, guint);
1394 GTK_VALUE_ENUM(params[i]) = va_arg (args, gint);
1396 case GTK_TYPE_FLAGS:
1397 GTK_VALUE_FLAGS(params[i]) = va_arg (args, gint);
1400 GTK_VALUE_LONG(params[i]) = va_arg (args, glong);
1402 case GTK_TYPE_ULONG:
1403 GTK_VALUE_ULONG(params[i]) = va_arg (args, gulong);
1405 case GTK_TYPE_FLOAT:
1406 GTK_VALUE_FLOAT(params[i]) = va_arg (args, gfloat);
1408 case GTK_TYPE_DOUBLE:
1409 GTK_VALUE_DOUBLE(params[i]) = va_arg (args, gdouble);
1411 case GTK_TYPE_STRING:
1412 GTK_VALUE_STRING(params[i]) = va_arg (args, gchar*);
1414 case GTK_TYPE_POINTER:
1415 GTK_VALUE_POINTER(params[i]) = va_arg (args, gpointer);
1417 case GTK_TYPE_BOXED:
1418 GTK_VALUE_BOXED(params[i]) = va_arg (args, gpointer);
1420 case GTK_TYPE_SIGNAL:
1421 GTK_VALUE_SIGNAL(params[i]).f = va_arg (args, GtkFunction);
1422 GTK_VALUE_SIGNAL(params[i]).d = va_arg (args, gpointer);
1424 case GTK_TYPE_FOREIGN:
1425 GTK_VALUE_FOREIGN(params[i]).data = va_arg (args, gpointer);
1426 GTK_VALUE_FOREIGN(params[i]).notify =
1427 va_arg (args, GtkDestroyNotify);
1429 case GTK_TYPE_CALLBACK:
1430 GTK_VALUE_CALLBACK(params[i]).marshal =
1431 va_arg (args, GtkCallbackMarshal);
1432 GTK_VALUE_CALLBACK(params[i]).data = va_arg (args, gpointer);
1433 GTK_VALUE_CALLBACK(params[i]).notify =
1434 va_arg (args, GtkDestroyNotify);
1436 case GTK_TYPE_C_CALLBACK:
1437 GTK_VALUE_C_CALLBACK(params[i]).func = va_arg (args, GtkFunction);
1438 GTK_VALUE_C_CALLBACK(params[i]).func_data = va_arg (args, gpointer);
1441 GTK_VALUE_ARGS(params[i]).n_args = va_arg (args, int);
1442 GTK_VALUE_ARGS(params[i]).args = va_arg (args, GtkArg*);
1444 case GTK_TYPE_OBJECT:
1445 GTK_VALUE_OBJECT(params[i]) = va_arg (args, GtkObject*);
1446 g_assert (GTK_VALUE_OBJECT(params[i]) == NULL ||
1447 GTK_CHECK_TYPE (GTK_VALUE_OBJECT(params[i]),
1451 g_error ("unsupported type %s in signal arg",
1452 gtk_type_name (params[i].type));
1457 params[i].type = return_val;
1458 params[i].name = NULL;
1460 switch (GTK_FUNDAMENTAL_TYPE (return_val))
1462 case GTK_TYPE_INVALID:
1467 params[i].d.pointer_data = va_arg (args, gchar*);
1470 params[i].d.pointer_data = va_arg (args, gint*);
1473 params[i].d.pointer_data = va_arg (args, gint*);
1476 params[i].d.pointer_data = va_arg (args, guint*);
1479 params[i].d.pointer_data = va_arg (args, gint*);
1481 case GTK_TYPE_FLAGS:
1482 params[i].d.pointer_data = va_arg (args, gint*);
1485 params[i].d.pointer_data = va_arg (args, glong*);
1487 case GTK_TYPE_ULONG:
1488 params[i].d.pointer_data = va_arg (args, gulong*);
1490 case GTK_TYPE_FLOAT:
1491 params[i].d.pointer_data = va_arg (args, gfloat*);
1493 case GTK_TYPE_DOUBLE:
1494 params[i].d.pointer_data = va_arg (args, gdouble*);
1496 case GTK_TYPE_STRING:
1497 params[i].d.pointer_data = va_arg (args, gchar**);
1499 case GTK_TYPE_POINTER:
1500 params[i].d.pointer_data = va_arg (args, gpointer*);
1502 case GTK_TYPE_BOXED:
1503 params[i].d.pointer_data = va_arg (args, gpointer*);
1505 case GTK_TYPE_OBJECT:
1506 params[i].d.pointer_data = va_arg (args, GtkObject**);
1508 case GTK_TYPE_SIGNAL:
1509 case GTK_TYPE_FOREIGN:
1510 case GTK_TYPE_CALLBACK:
1511 case GTK_TYPE_C_CALLBACK:
1514 g_error ("unsupported type %s in signal return",
1515 gtk_type_name (return_val));