gobject-introspection 3.4.3 → 3.4.9
Sign up to get free protection for your applications and to get access to all the features.
- 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__ */
|