예제 #1
0
/* --- 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);
}
예제 #2
0
파일: misc.c 프로젝트: svn2github/GtkAda
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;
}