/* --- 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) { GClosure *closure; g_return_val_if_fail (n_params < SIGNAL_MAX_PARAMS, 0); closure = function_offset ? g_signal_type_cclosure_new (object_type, function_offset) : NULL; return g_signal_newv (name, object_type, (GSignalFlags)signal_flags, closure, NULL, NULL, marshaller, return_val, n_params, params); }
int ada_initialize_class_record (GType ancestor, gint nsignals, char* signals[], GType parameters[], gint max_parameters, GType returns[], gint max_returns, AdaGObjectClass klass, gchar* type_name) { // Make this function thread-safe and ensure we only initialize the class // once if (g_once_init_enter (&klass->type)) { /* Note: The memory allocated in this function is never freed. No need to worry, since this is only allocated once per user's widget type, and might be used until the end of the application */ GTypeQuery query; int j; /* We need to know the ancestor's class/instance sizes */ g_type_query (ancestor, &query); /************************* * This code is the equivalent of type_name@@_get_type in C. In Ada, the * type will be accessible only once at least one instance of it has * been created (whereas in C the GType is created at elaboration time). *************************/ GTypeInfo info; info.class_size = query.class_size + nsignals * sizeof (void*); //+ sizeof (AdaGObjectClass); info.base_init = NULL; info.base_finalize = NULL; info.class_init = (GClassInitFunc)(&ada_class_record_init); info.class_finalize = NULL; info.class_data = (gconstpointer)klass; info.instance_size = query.instance_size; info.n_preallocs = 0; info.instance_init = NULL; info.value_table = NULL; GType new_type = g_type_register_static ( ancestor /* parent_type */, type_name /* type_name */, &info /* info */, 0 /* flags */); /************************* * This code is generally called by g_object_new (which itself is called * from type_name_new() in C). Its result is to create and initialized * (via class_init) the class the first time an instance of it is * created. In Ada, we do not us a _class_init, so we initialize the * signals immediately after creating the class. *************************/ for (j = 0; j < nsignals; j++) { int count = 0; GClosure *closure; while (count < max_parameters && (parameters [j * max_parameters + count] != G_TYPE_NONE)) { count++; } closure = g_signal_type_cclosure_new (new_type, query.class_size + j * sizeof (void*)); /* offset */ GType return_type = G_TYPE_NONE; GSignalAccumulator acc = NULL; if (j < max_returns) { return_type = returns[j]; if (return_type == G_TYPE_BOOLEAN) { acc = g_signal_accumulator_true_handled; } } /* id = */ g_signal_newv (signals[j], /* signal_name */ new_type, /* itype */ G_SIGNAL_RUN_LAST, /* signal_flags */ closure, /* class_closure */ acc, /* accumulator */ NULL, /* accu_data */ g_cclosure_marshal_VOID__VOID, /* c_marshaller, unused at the Ada level ??? This probably makes the widget unusable from C */ return_type, /* return_type */ count, /* n_params */ parameters + j * max_parameters); /* param_types */ } /* Do not call g_type_class_ref here, since that would prevent us * from adding interfaces later on. Instead, rely on the class_init * function */ g_once_init_leave (&klass->type, new_type); // sets klass->type return 1; } return 0; }