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.
- checksums.yaml +4 -4
- data/ext/gobject-introspection/extconf.rb +1 -4
- data/ext/gobject-introspection/gobject-introspection-enum-types.c +230 -0
- data/ext/gobject-introspection/gobject-introspection-enum-types.h +42 -0
- data/ext/gobject-introspection/rb-gi-argument.c +11 -4
- data/ext/gobject-introspection/rb-gi-arguments-in.c +28 -108
- data/ext/gobject-introspection/rb-gi-arguments-out.c +20 -2
- data/ext/gobject-introspection/rb-gi-arguments.c +244 -18
- data/ext/gobject-introspection/rb-gi-base-info.c +11 -1
- data/ext/gobject-introspection/rb-gi-callable-info.c +10 -2
- data/ext/gobject-introspection/rb-gi-callback.c +156 -2
- data/ext/gobject-introspection/rb-gi-conversions.h +6 -6
- data/ext/gobject-introspection/rb-gi-interface-info.c +1 -7
- data/ext/gobject-introspection/rb-gi-loader.c +60 -12
- data/ext/gobject-introspection/rb-gi-object-info.c +11 -1
- data/ext/gobject-introspection/rb-gi-private-arguments-in.h +3 -1
- data/ext/gobject-introspection/rb-gi-private-arguments.h +5 -1
- data/ext/gobject-introspection/rb-gi-private-callback.h +6 -3
- data/ext/gobject-introspection/rb-gi-private.h +1 -0
- data/ext/gobject-introspection/rb-gi-repository.c +1 -1
- data/ext/gobject-introspection/rb-gi-struct-info.c +15 -3
- data/ext/gobject-introspection/rb-gi-vfunc-info.c +2 -2
- data/ext/gobject-introspection/rb-gobject-introspection.c +231 -0
- data/ext/gobject-introspection/rbgiversion.h +24 -0
- data/lib/gobject-introspection/loader.rb +65 -1
- data/test/gobject-introspection-test-utils.rb +2 -2
- data/test/run-test.rb +18 -25
- data/test/test-base-info.rb +5 -1
- data/test/test-callable-info.rb +16 -2
- data/test/test-loader.rb +53 -7
- data/test/test-object-info.rb +5 -1
- data/test/test-struct-info.rb +6 -1
- metadata +8 -5
@@ -1,6 +1,6 @@
|
|
1
1
|
/* -*- c-file-style: "ruby"; indent-tabs-mode: nil -*- */
|
2
2
|
/*
|
3
|
-
* Copyright (C) 2012-
|
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 =
|
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 =
|
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 =
|
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 =
|
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
|
-
|
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
|
-
|
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 =
|
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-
|
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
|
-
|
@@ -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 =
|
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-
|
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 =
|
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 =
|
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-
|
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)
|
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__ */
|