gobject-introspection 3.4.3 → 3.4.9

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (33) hide show
  1. checksums.yaml +4 -4
  2. data/ext/gobject-introspection/extconf.rb +1 -4
  3. data/ext/gobject-introspection/gobject-introspection-enum-types.c +230 -0
  4. data/ext/gobject-introspection/gobject-introspection-enum-types.h +42 -0
  5. data/ext/gobject-introspection/rb-gi-argument.c +11 -4
  6. data/ext/gobject-introspection/rb-gi-arguments-in.c +28 -108
  7. data/ext/gobject-introspection/rb-gi-arguments-out.c +20 -2
  8. data/ext/gobject-introspection/rb-gi-arguments.c +244 -18
  9. data/ext/gobject-introspection/rb-gi-base-info.c +11 -1
  10. data/ext/gobject-introspection/rb-gi-callable-info.c +10 -2
  11. data/ext/gobject-introspection/rb-gi-callback.c +156 -2
  12. data/ext/gobject-introspection/rb-gi-conversions.h +6 -6
  13. data/ext/gobject-introspection/rb-gi-interface-info.c +1 -7
  14. data/ext/gobject-introspection/rb-gi-loader.c +60 -12
  15. data/ext/gobject-introspection/rb-gi-object-info.c +11 -1
  16. data/ext/gobject-introspection/rb-gi-private-arguments-in.h +3 -1
  17. data/ext/gobject-introspection/rb-gi-private-arguments.h +5 -1
  18. data/ext/gobject-introspection/rb-gi-private-callback.h +6 -3
  19. data/ext/gobject-introspection/rb-gi-private.h +1 -0
  20. data/ext/gobject-introspection/rb-gi-repository.c +1 -1
  21. data/ext/gobject-introspection/rb-gi-struct-info.c +15 -3
  22. data/ext/gobject-introspection/rb-gi-vfunc-info.c +2 -2
  23. data/ext/gobject-introspection/rb-gobject-introspection.c +231 -0
  24. data/ext/gobject-introspection/rbgiversion.h +24 -0
  25. data/lib/gobject-introspection/loader.rb +65 -1
  26. data/test/gobject-introspection-test-utils.rb +2 -2
  27. data/test/run-test.rb +18 -25
  28. data/test/test-base-info.rb +5 -1
  29. data/test/test-callable-info.rb +16 -2
  30. data/test/test-loader.rb +53 -7
  31. data/test/test-object-info.rb +5 -1
  32. data/test/test-struct-info.rb +6 -1
  33. metadata +8 -5
@@ -1,6 +1,6 @@
1
1
  /* -*- c-file-style: "ruby"; indent-tabs-mode: nil -*- */
2
2
  /*
3
- * Copyright (C) 2012-2018 Ruby-GNOME2 Project Team
3
+ * Copyright (C) 2012-2021 Ruby-GNOME Project Team
4
4
  *
5
5
  * This library is free software; you can redistribute it and/or
6
6
  * modify it under the terms of the GNU Lesser General Public
@@ -39,7 +39,7 @@ rg_s_define_class(int argc, VALUE *argv, G_GNUC_UNUSED VALUE klass)
39
39
  "size", &rb_size,
40
40
  NULL);
41
41
 
42
- gtype = NUM2ULONG(rb_to_int(rb_gtype));
42
+ gtype = rbgobj_gtype_from_ruby(rb_gtype);
43
43
  rb_class = G_DEF_CLASS_WITH_PARENT(gtype, RVAL2CSTR(rb_name),
44
44
  rb_module, rb_parent);
45
45
  if (!NIL_P(rb_size)) {
@@ -54,7 +54,7 @@ rg_s_define_interface(G_GNUC_UNUSED VALUE klass,
54
54
  {
55
55
  GType gtype;
56
56
 
57
- gtype = rbgobj_gtype_get(rb_gtype);
57
+ gtype = rbgobj_gtype_from_ruby(rb_gtype);
58
58
  return G_DEF_INTERFACE(gtype, RVAL2CSTR(rb_name), rb_module);
59
59
  }
60
60
 
@@ -70,7 +70,7 @@ struct_alloc(VALUE klass)
70
70
  is_owned = FALSE;
71
71
  } else {
72
72
  size_t size;
73
- size = NUM2ULONG(rb_size);
73
+ size = NUM2ULL(rb_size);
74
74
  instance = xcalloc(1, size);
75
75
  is_owned = TRUE;
76
76
  }
@@ -133,12 +133,63 @@ rg_s_define_error(int argc, VALUE *argv, G_GNUC_UNUSED VALUE klass)
133
133
  }
134
134
 
135
135
  if (!NIL_P(rb_gtype)) {
136
- gtype = NUM2ULONG(rb_funcall(rb_gtype, rb_intern("to_i"), 0));
136
+ gtype = rbgobj_gtype_from_ruby(rb_gtype);
137
137
  }
138
138
 
139
139
  return G_DEF_ERROR(domain, name, rb_module, rb_parent, gtype);
140
140
  }
141
141
 
142
+ static VALUE
143
+ rg_s_implement_virtual_function(G_GNUC_UNUSED VALUE klass,
144
+ VALUE rb_field_info,
145
+ VALUE rb_implementor_gtype,
146
+ VALUE rb_vtable_gtype,
147
+ VALUE rb_method_name)
148
+ {
149
+ GIFieldInfo *field_info;
150
+ GType implementor_gtype;
151
+ GType vtable_gtype;
152
+ const gchar *method_name;
153
+ RBGICallback *callback;
154
+
155
+ field_info = RVAL2GI_FIELD_INFO(rb_field_info);
156
+ implementor_gtype = rbgobj_gtype_from_ruby(rb_implementor_gtype);
157
+ vtable_gtype = rbgobj_gtype_from_ruby(rb_vtable_gtype);
158
+ method_name = RVAL2CSTR(rb_method_name);
159
+
160
+ {
161
+ GITypeInfo *type_info;
162
+ GICallbackInfo *callback_info;
163
+
164
+ type_info = g_field_info_get_type(field_info);
165
+ callback_info = g_type_info_get_interface(type_info);
166
+ callback = rb_gi_callback_new(callback_info, method_name);
167
+ g_base_info_unref(callback_info);
168
+ g_base_info_unref(type_info);
169
+ }
170
+
171
+ {
172
+ gpointer implementor_struct;
173
+ gpointer vtable_struct;
174
+ gint offset;
175
+ gpointer *method_address;
176
+
177
+ implementor_struct = g_type_class_ref(implementor_gtype);
178
+ if (G_TYPE_IS_INTERFACE(vtable_gtype)) {
179
+ vtable_struct = g_type_interface_peek(implementor_struct,
180
+ vtable_gtype);
181
+ } else {
182
+ vtable_struct = implementor_struct;
183
+ }
184
+ offset = g_field_info_get_offset(field_info);
185
+ method_address = G_STRUCT_MEMBER_P(vtable_struct, offset);
186
+ *method_address = callback->closure;
187
+ g_type_class_unref(implementor_struct);
188
+ }
189
+
190
+ return Qnil;
191
+ }
192
+
142
193
  typedef struct {
143
194
  GType type;
144
195
  VALUE rb_converters;
@@ -173,12 +224,10 @@ rg_s_register_boxed_class_converter(VALUE klass, VALUE rb_gtype)
173
224
  {
174
225
  RGConvertTable table;
175
226
  BoxedInstance2RObjData *data;
176
- ID id_to_i;
177
227
  VALUE boxed_class_converters;
178
228
 
179
229
  memset(&table, 0, sizeof(RGConvertTable));
180
- CONST_ID(id_to_i, "to_i");
181
- table.type = NUM2ULONG(rb_funcall(rb_gtype, id_to_i, 0));
230
+ table.type = rbgobj_gtype_from_ruby(rb_gtype);
182
231
  table.klass = Qnil;
183
232
  table.instance2robj = boxed_instance2robj;
184
233
 
@@ -243,12 +292,10 @@ rg_s_register_object_class_converter(VALUE klass, VALUE rb_gtype)
243
292
  {
244
293
  RGConvertTable table;
245
294
  ObjectInstance2RObjData *data;
246
- ID id_to_i;
247
295
  VALUE object_class_converters;
248
296
 
249
297
  memset(&table, 0, sizeof(RGConvertTable));
250
- CONST_ID(id_to_i, "to_i");
251
- table.type = NUM2ULONG(rb_funcall(rb_gtype, id_to_i, 0));
298
+ table.type = rbgobj_gtype_from_ruby(rb_gtype);
252
299
  table.klass = Qnil;
253
300
  table.instance2robj = object_instance2robj;
254
301
 
@@ -318,7 +365,7 @@ rg_s_instantiate_gobject_pointer(G_GNUC_UNUSED VALUE klass,
318
365
  {
319
366
  GObject *gobject;
320
367
 
321
- gobject = GUINT_TO_POINTER(NUM2ULONG(rb_gobject_pointer));
368
+ gobject = (gpointer)(NUM2ULL(rb_gobject_pointer));
322
369
 
323
370
  return GOBJ2RVAL(gobject);
324
371
  }
@@ -337,6 +384,7 @@ rb_gi_loader_init(VALUE rb_mGI)
337
384
  RG_DEF_SMETHOD(define_interface, 3);
338
385
  RG_DEF_SMETHOD(define_struct, -1);
339
386
  RG_DEF_SMETHOD(define_error, -1);
387
+ RG_DEF_SMETHOD(implement_virtual_function, 4);
340
388
  RG_DEF_SMETHOD(register_boxed_class_converter, 1);
341
389
  RG_DEF_SMETHOD(register_object_class_converter, 1);
342
390
  RG_DEF_SMETHOD(register_constant_rename_map, 2);
@@ -1,6 +1,6 @@
1
1
  /* -*- c-file-style: "ruby"; indent-tabs-mode: nil -*- */
2
2
  /*
3
- * Copyright (C) 2012 Ruby-GNOME2 Project Team
3
+ * Copyright (C) 2012-2021 Ruby-GNOME Project Team
4
4
  *
5
5
  * This library is free software; you can redistribute it and/or
6
6
  * modify it under the terms of the GNU Lesser General Public
@@ -272,6 +272,15 @@ rg_get_constant(VALUE self, VALUE rb_n)
272
272
  return GI_BASE_INFO2RVAL_WITH_UNREF(g_object_info_get_constant(info, n));
273
273
  }
274
274
 
275
+ static VALUE
276
+ rg_class_struct(VALUE self)
277
+ {
278
+ GIObjectInfo *info;
279
+
280
+ info = SELF(self);
281
+ return GI_BASE_INFO2RVAL_WITH_UNREF(g_object_info_get_class_struct(info));
282
+ }
283
+
275
284
  static VALUE
276
285
  rg_unref_function(VALUE self)
277
286
  {
@@ -338,6 +347,7 @@ rb_gi_object_info_init(VALUE rb_mGI, VALUE rb_cGIRegisteredTypeInfo)
338
347
  RG_DEF_METHOD(get_vfunc, 1);
339
348
  RG_DEF_METHOD(n_constants, 0);
340
349
  RG_DEF_METHOD(get_constant, 1);
350
+ RG_DEF_METHOD(class_struct, 0);
341
351
  RG_DEF_METHOD(unref_function, 0);
342
352
  RG_DEF_METHOD(ref_function, 0);
343
353
  RG_DEF_METHOD(set_value_function, 0);
@@ -1,6 +1,6 @@
1
1
  /* -*- c-file-style: "ruby"; indent-tabs-mode: nil -*- */
2
2
  /*
3
- * Copyright (C) 2019 Ruby-GNOME Project Team
3
+ * Copyright (C) 2019-2021 Ruby-GNOME Project Team
4
4
  *
5
5
  * This library is free software; you can redistribute it and/or
6
6
  * modify it under the terms of the GNU Lesser General Public
@@ -20,6 +20,8 @@
20
20
 
21
21
  #pragma once
22
22
 
23
+ G_GNUC_INTERNAL VALUE
24
+ rb_gi_arguments_in_to_ruby(RBGIArguments *args);
23
25
  G_GNUC_INTERNAL void
24
26
  rb_gi_arguments_in_init(RBGIArguments *args);
25
27
  G_GNUC_INTERNAL void
@@ -1,6 +1,6 @@
1
1
  /* -*- c-file-style: "ruby"; indent-tabs-mode: nil -*- */
2
2
  /*
3
- * Copyright (C) 2019 Ruby-GNOME Project Team
3
+ * Copyright (C) 2019-2021 Ruby-GNOME Project Team
4
4
  *
5
5
  * This library is free software; you can redistribute it and/or
6
6
  * modify it under the terms of the GNU Lesser General Public
@@ -101,6 +101,10 @@ G_GNUC_INTERNAL VALUE
101
101
  rb_gi_arguments_get_rb_return_value(RBGIArguments *args,
102
102
  GIArgument *return_value);
103
103
 
104
+ G_GNUC_INTERNAL void
105
+ rb_gi_arguments_fill_raw_out_gerror(RBGIArguments *args,
106
+ VALUE rb_error);
107
+
104
108
  G_GNUC_INTERNAL void
105
109
  rb_gi_arguments_fill_raw_results(RBGIArguments *args,
106
110
  VALUE rb_results,
@@ -1,6 +1,6 @@
1
1
  /* -*- c-file-style: "ruby"; indent-tabs-mode: nil -*- */
2
2
  /*
3
- * Copyright (C) 2019 Ruby-GNOME Project Team
3
+ * Copyright (C) 2019-2021 Ruby-GNOME Project Team
4
4
  *
5
5
  * This library is free software; you can redistribute it and/or
6
6
  * modify it under the terms of the GNU Lesser General Public
@@ -22,8 +22,8 @@
22
22
 
23
23
  typedef struct RBGICallback_ {
24
24
  GIArgInfo *arg_info;
25
- GITypeInfo *type_info;
26
25
  GICallbackInfo *callback_info;
26
+ gchar *method_name;
27
27
  ffi_cif cif;
28
28
  ffi_closure *closure;
29
29
  } RBGICallback;
@@ -34,8 +34,11 @@ rb_gi_callback_init(VALUE rb_mGI);
34
34
  G_GNUC_INTERNAL gpointer
35
35
  rb_gi_callback_find(GIArgInfo *info);
36
36
 
37
+ G_GNUC_INTERNAL RBGICallback *
38
+ rb_gi_callback_new(GICallbackInfo *callback_info,
39
+ const gchar *method_name);
40
+
37
41
  G_GNUC_INTERNAL RBGICallbackData *
38
42
  rb_gi_callback_data_new(RBGIArguments *args,
39
43
  RBGICallback *callback,
40
44
  RBGIArgMetadata *metadata);
41
-
@@ -22,6 +22,7 @@
22
22
 
23
23
  #include <ruby.h>
24
24
  #include <rbgobject.h>
25
+ #include <rbglib2conversions.h>
25
26
  #include <glib-enum-types.h>
26
27
 
27
28
  #include <girffi.h>
@@ -228,7 +228,7 @@ rg_find(int argc, VALUE *argv, VALUE self)
228
228
  VALUE rb_gtype;
229
229
  GType gtype;
230
230
  rb_gtype = argv[0];
231
- gtype = NUM2UINT(rb_gtype);
231
+ gtype = rbgobj_gtype_from_ruby(rb_gtype);
232
232
  info = g_irepository_find_by_gtype(SELF(self), gtype);
233
233
  } else {
234
234
  VALUE rb_namespace, rb_name;
@@ -1,6 +1,6 @@
1
1
  /* -*- c-file-style: "ruby"; indent-tabs-mode: nil -*- */
2
2
  /*
3
- * Copyright (C) 2012-2019 Ruby-GNOME Project Team
3
+ * Copyright (C) 2012-2021 Ruby-GNOME Project Team
4
4
  *
5
5
  * This library is free software; you can redistribute it and/or
6
6
  * modify it under the terms of the GNU Lesser General Public
@@ -84,7 +84,7 @@ rb_gi_struct_get_raw(VALUE rb_struct, GType gtype)
84
84
  if (rb_respond_to(rb_struct_class, rb_intern("gtype"))) {
85
85
  VALUE rb_gtype;
86
86
  rb_gtype = rb_funcall(rb_struct_class, rb_intern("gtype"), 0);
87
- gtype = NUM2ULONG(rb_funcall(rb_gtype, rb_intern("to_i"), 0));
87
+ gtype = rbgobj_gtype_from_ruby(rb_gtype);
88
88
  }
89
89
  }
90
90
  if (gtype == G_TYPE_NONE) {
@@ -146,7 +146,7 @@ rb_gi_struct_info_to_ruby(GIStructInfo *info,
146
146
  GType gtype;
147
147
 
148
148
  rb_gtype = rb_funcall(rb_class, rb_intern("gtype"), 0);
149
- gtype = NUM2ULONG(rb_funcall(rb_gtype, rb_intern("to_i"), 0));
149
+ gtype = rbgobj_gtype_from_ruby(rb_gtype);
150
150
  return BOXED2RVAL(object, gtype);
151
151
  }
152
152
 
@@ -194,6 +194,17 @@ rg_get_field(VALUE self, VALUE rb_n)
194
194
  return GI_BASE_INFO2RVAL_WITH_UNREF(g_struct_info_get_field(info, n));
195
195
  }
196
196
 
197
+ static VALUE
198
+ rg_find_field(VALUE self, VALUE rb_name)
199
+ {
200
+ GIStructInfo *info;
201
+ const gchar *name;
202
+
203
+ info = SELF(self);
204
+ name = RVAL2CSTR(rb_name);
205
+ return GI_BASE_INFO2RVAL_WITH_UNREF(g_struct_info_find_field(info, name));
206
+ }
207
+
197
208
  static VALUE
198
209
  rg_get_field_value(VALUE self, VALUE rb_struct, VALUE rb_n)
199
210
  {
@@ -308,6 +319,7 @@ rb_gi_struct_info_init(VALUE rb_mGI, VALUE rb_cGIRegisteredTypeInfo)
308
319
 
309
320
  RG_DEF_METHOD(n_fields, 0);
310
321
  RG_DEF_METHOD(get_field, 1);
322
+ RG_DEF_METHOD(find_field, 1);
311
323
  RG_DEF_METHOD(get_field_value, 2);
312
324
  RG_DEF_METHOD(set_field_value, 3);
313
325
  RG_DEF_METHOD(n_methods, 0);
@@ -1,6 +1,6 @@
1
1
  /* -*- c-file-style: "ruby"; indent-tabs-mode: nil -*- */
2
2
  /*
3
- * Copyright (C) 2012 Ruby-GNOME2 Project Team
3
+ * Copyright (C) 2012-2021 Ruby-GNOME Project Team
4
4
  *
5
5
  * This library is free software; you can redistribute it and/or
6
6
  * modify it under the terms of the GNU Lesser General Public
@@ -21,7 +21,7 @@
21
21
  #include "rb-gi-private.h"
22
22
 
23
23
  #define RG_TARGET_NAMESPACE rb_cGIVFuncInfo
24
- #define SELF(self) RVAL2GI_BASE_INFO(self)
24
+ #define SELF(self) RVAL2GI_VFUNC_INFO(self)
25
25
 
26
26
  GType
27
27
  gi_vfunc_info_get_type(void)
@@ -22,6 +22,15 @@
22
22
 
23
23
  #define RG_TARGET_NAMESPACE rb_mGObjectIntrospection
24
24
 
25
+ typedef struct {
26
+ ID name;
27
+ GICallableInfo *callable_info;
28
+
29
+ ffi_cif cif;
30
+ ffi_closure *closure;
31
+ } RBGIVFuncCallbackData;
32
+
33
+ static ID id_send;
25
34
  static gboolean is_debug_mode = FALSE;
26
35
 
27
36
  gboolean
@@ -30,11 +39,231 @@ rb_gi_is_debug_mode(void)
30
39
  return is_debug_mode;
31
40
  }
32
41
 
42
+ static void
43
+ find_vfunc_info (GIBaseInfo *vfunc_info,
44
+ GType implementor_gtype,
45
+ gpointer *implementor_vtable_ret,
46
+ GIFieldInfo **field_info_ret)
47
+ {
48
+ GIBaseInfo *ancestor_info = NULL;
49
+ GIStructInfo *struct_info = NULL;
50
+ GIFieldInfo *field_info = NULL;
51
+
52
+ ancestor_info = g_base_info_get_container(vfunc_info);
53
+ // ancestor_gtype = g_registered_type_info_get_g_type (
54
+ // (GIRegisteredTypeInfo *) ancestor_info);
55
+ struct_info = g_object_info_get_class_struct((GIObjectInfo*) ancestor_info);
56
+ *implementor_vtable_ret = g_type_class_ref(implementor_gtype);
57
+
58
+ field_info = g_struct_info_find_field(
59
+ struct_info, g_base_info_get_name((GIBaseInfo*) vfunc_info));
60
+
61
+ if (field_info != NULL) {
62
+ GITypeInfo *type_info;
63
+
64
+ type_info = g_field_info_get_type (field_info);
65
+ if (g_type_info_get_tag (type_info) == GI_TYPE_TAG_INTERFACE) {
66
+ *field_info_ret = field_info;
67
+ } else {
68
+ g_base_info_unref (field_info);
69
+ }
70
+ g_base_info_unref (type_info);
71
+ }
72
+
73
+ g_base_info_unref (struct_info);
74
+ }
75
+
76
+ static VALUE
77
+ garg2rval(GIArgument *argument, GITypeTag type_tag)
78
+ {
79
+ switch (type_tag) {
80
+ case GI_TYPE_TAG_INT32:
81
+ return INT2FIX(argument->v_int32);
82
+ default:
83
+ rb_raise(rb_eTypeError, "garg2rval: not implemented");
84
+ break;
85
+ }
86
+ }
87
+
88
+ static void
89
+ rval2garg(VALUE value, GITypeTag type_tag, GIArgument *argument)
90
+ {
91
+ switch (type_tag) {
92
+ case GI_TYPE_TAG_INT32:
93
+ argument->v_int32 = FIX2INT(value);
94
+ break;
95
+ default:
96
+ rb_raise(rb_eTypeError, "rval2garg: not implemented");
97
+ break;
98
+ }
99
+ }
100
+
101
+ static void
102
+ rval2ffiarg(VALUE value, ffi_arg *arg)
103
+ {
104
+ switch (TYPE(value)) {
105
+ case T_NIL:
106
+ break;
107
+ case T_FIXNUM:
108
+ case T_DATA:
109
+ *arg = FIX2INT(value);
110
+ break;
111
+ default:
112
+ rb_raise(rb_eTypeError, "rval2ffiarg: not implemented");
113
+ break;
114
+ }
115
+ }
116
+
117
+ static void
118
+ ffi_callback(G_GNUC_UNUSED ffi_cif *cif,
119
+ void *ret,
120
+ void **raw_args,
121
+ void *raw_data)
122
+ {
123
+ GIArgument **args = NULL;
124
+ RBGIVFuncCallbackData *data = NULL;
125
+ GObject* receiver = NULL;
126
+ VALUE rb_receiver = 0;
127
+ gint n_args = 0, n_in_args = 0, n_out_args = 0;
128
+ size_t i = 0, j = 0;
129
+ VALUE *in_values = NULL;
130
+ VALUE rb_ret;
131
+ GIArgInfo arg_info;
132
+ GITypeInfo type_info;
133
+ GITypeTag type_tag;
134
+ GIDirection direction;
135
+ gboolean ret_type_is_void;
136
+
137
+ args = (GIArgument **) raw_args;
138
+ data = (RBGIVFuncCallbackData *) raw_data;
139
+
140
+ receiver = G_OBJECT(args[0]->v_pointer);
141
+ rb_receiver = GOBJ2RVAL(receiver);
142
+
143
+ n_args = g_callable_info_get_n_args(data->callable_info);
144
+ in_values = (VALUE *) malloc(n_args * sizeof(VALUE));
145
+ in_values[0] = data->name;
146
+ n_in_args++;
147
+
148
+ for (i = 1, j = 1; i < n_args; i++) {
149
+ g_callable_info_load_arg(data->callable_info, i, &arg_info);
150
+ g_arg_info_load_type(&arg_info, &type_info);
151
+ type_tag = g_type_info_get_tag(&type_info);
152
+ direction = g_arg_info_get_direction(&arg_info);
153
+
154
+ if (type_tag == GI_TYPE_TAG_VOID) continue;
155
+
156
+ if (direction == GI_DIRECTION_OUT || direction == GI_DIRECTION_INOUT)
157
+ n_out_args++;
158
+
159
+ if (direction == GI_DIRECTION_OUT) continue;
160
+
161
+ in_values[j] = garg2rval(args[i], type_tag);
162
+ j++; n_in_args++;
163
+ }
164
+
165
+ // result = rb_funcall(rb_receiver, id_send, 1, data->name);
166
+ rb_ret = rb_funcallv(rb_receiver, id_send, n_in_args, in_values);
167
+
168
+ g_callable_info_load_return_type(data->callable_info, &type_info);
169
+ ret_type_is_void = g_type_info_get_tag(&type_info) == GI_TYPE_TAG_VOID;
170
+
171
+ if (n_out_args == 0 && ret_type_is_void) {
172
+ // do nothing
173
+ } else if (n_out_args == 0) {
174
+ rval2ffiarg(rb_ret, ret);
175
+ } else if (n_out_args == 1 && ret_type_is_void) {
176
+ for (i = 1; i < n_args; i++) {
177
+ g_callable_info_load_arg(data->callable_info, i, &arg_info);
178
+ g_arg_info_load_type(&arg_info, &type_info);
179
+ type_tag = g_type_info_get_tag(&type_info);
180
+ direction = g_arg_info_get_direction(&arg_info);
181
+
182
+ if (type_tag == GI_TYPE_TAG_VOID || direction == GI_DIRECTION_IN)
183
+ continue;
184
+
185
+ rval2garg(rb_ret, type_tag, *(GIArgument **) args[i]);
186
+ break;
187
+ }
188
+ } else {
189
+ if (TYPE(rb_ret) != T_ARRAY) {
190
+ rb_raise(rb_eTypeError, "return type should be Array");
191
+ }
192
+
193
+ for (i = 1, j = 0; i < n_args; i++) {
194
+ g_callable_info_load_arg(data->callable_info, i, &arg_info);
195
+ g_arg_info_load_type(&arg_info, &type_info);
196
+ type_tag = g_type_info_get_tag(&type_info);
197
+ direction = g_arg_info_get_direction(&arg_info);
198
+
199
+ if (type_tag == GI_TYPE_TAG_VOID || direction == GI_DIRECTION_IN)
200
+ continue;
201
+
202
+ rval2garg(rb_ary_entry(rb_ret, j), type_tag, *(GIArgument **) args[i]);
203
+ j++;
204
+ }
205
+ }
206
+
207
+ free(in_values);
208
+ }
209
+
210
+ static VALUE
211
+ rb_gi_hook_up_vfunc(G_GNUC_UNUSED VALUE self,
212
+ VALUE rb_name,
213
+ VALUE rb_vfunc_info,
214
+ VALUE rb_gtype)
215
+ {
216
+ GIVFuncInfo *vfunc_info = NULL;
217
+ GType gtype = 0;
218
+ gpointer implementor_vtable = NULL;
219
+ GIFieldInfo *field_info = NULL;
220
+
221
+ vfunc_info = RVAL2GI_BASE_INFO(rb_vfunc_info);
222
+ gtype = NUM2LONG(rb_gtype);
223
+ g_assert(G_TYPE_IS_CLASSED(gtype));
224
+
225
+ find_vfunc_info(vfunc_info, gtype, &implementor_vtable, &field_info);
226
+
227
+ if (field_info != NULL) {
228
+ GITypeInfo *type_info = NULL;
229
+ GIBaseInfo *interface_info = NULL;
230
+ RBGIVFuncCallbackData *data = NULL;
231
+ gint offset = 0;
232
+ gpointer *method_ptr = NULL;
233
+
234
+ type_info = g_field_info_get_type(field_info);
235
+
236
+ interface_info = g_type_info_get_interface(type_info);
237
+ g_assert(g_base_info_get_type(interface_info) == GI_INFO_TYPE_CALLBACK);
238
+
239
+ data = ALLOC(RBGIVFuncCallbackData);
240
+ data->name = rb_name;
241
+ data->callable_info = g_base_info_ref(interface_info);
242
+ data->closure = g_callable_info_prepare_closure(
243
+ interface_info, &(data->cif), ffi_callback, data);
244
+
245
+ if (data->closure) {
246
+ offset = g_field_info_get_offset(field_info);
247
+ method_ptr = G_STRUCT_MEMBER_P(implementor_vtable, offset);
248
+
249
+ *method_ptr = data->closure;
250
+ }
251
+
252
+ g_base_info_unref (interface_info);
253
+ g_base_info_unref (type_info);
254
+ g_base_info_unref (field_info);
255
+ }
256
+
257
+ return Qnil;
258
+ }
259
+
33
260
  void
34
261
  Init_gobject_introspection(void)
35
262
  {
36
263
  VALUE RG_TARGET_NAMESPACE;
37
264
 
265
+ id_send = rb_intern("__send__");
266
+
38
267
  {
39
268
  const char *rb_gi_debug_env = getenv("RB_GI_DEBUG");
40
269
  if (rb_gi_debug_env && strcmp(rb_gi_debug_env, "yes") == 0) {
@@ -59,4 +288,6 @@ Init_gobject_introspection(void)
59
288
  rb_gi_loader_init(RG_TARGET_NAMESPACE);
60
289
 
61
290
  rb_gi_callback_init(RG_TARGET_NAMESPACE);
291
+
292
+ rb_define_module_function(RG_TARGET_NAMESPACE, "hook_up_vfunc", rb_gi_hook_up_vfunc, 3);
62
293
  }
@@ -0,0 +1,24 @@
1
+ /* -*- c-file-style: "ruby"; indent-tabs-mode: nil -*- */
2
+ /************************************************
3
+
4
+ rbgiversion.h -
5
+
6
+ This file was generated by mkmf-gnome2.rb.
7
+
8
+ ************************************************/
9
+
10
+ #ifndef __RBGI_VERSION_H__
11
+ #define __RBGI_VERSION_H__
12
+
13
+ #define GI_MAJOR_VERSION (1)
14
+ #define GI_MINOR_VERSION (46)
15
+ #define GI_MICRO_VERSION (0)
16
+
17
+ #define GI_CHECK_VERSION(major,minor,micro) \
18
+ (GI_MAJOR_VERSION > (major) || \
19
+ (GI_MAJOR_VERSION == (major) && GI_MINOR_VERSION > (minor)) || \
20
+ (GI_MAJOR_VERSION == (major) && GI_MINOR_VERSION == (minor) && \
21
+ GI_MICRO_VERSION >= (micro)))
22
+
23
+
24
+ #endif /* __RBGI_VERSION_H__ */