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