gobject-introspection 3.4.2 → 3.4.6
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 +10 -3
- data/ext/gobject-introspection/rb-gi-arguments-in.c +27 -107
- data/ext/gobject-introspection/rb-gi-arguments-out.c +20 -2
- data/ext/gobject-introspection/rb-gi-arguments.c +215 -17
- 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 +58 -10
- 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
@@ -105,10 +105,11 @@ rb_gi_arguments_out_free_array_c_interface(RBGIArguments *args,
|
|
105
105
|
case GI_TRANSFER_EVERYTHING:
|
106
106
|
default:
|
107
107
|
rb_raise(rb_eNotImpError,
|
108
|
-
"TODO: [%s] %s free GIArgument(%s)[%s]",
|
108
|
+
"TODO: [%s] %s free GIArgument(%s/%s)[%s]",
|
109
109
|
metadata->name,
|
110
110
|
rb_gi_direction_to_string(metadata->direction),
|
111
111
|
g_type_tag_to_string(metadata->type.tag),
|
112
|
+
rb_gi_array_type_to_string(metadata->array_type),
|
112
113
|
rb_gi_transfer_to_string(metadata->transfer));
|
113
114
|
}
|
114
115
|
xfree(target);
|
@@ -120,17 +121,34 @@ rb_gi_arguments_out_free_array_array_interface_struct(RBGIArguments *args,
|
|
120
121
|
gpointer user_data)
|
121
122
|
{
|
122
123
|
GArray *target = metadata->out_arg->v_pointer;
|
124
|
+
GType gtype = metadata->element_type.interface_gtype;
|
123
125
|
switch (metadata->transfer) {
|
124
126
|
case GI_TRANSFER_NOTHING:
|
125
127
|
break;
|
126
128
|
case GI_TRANSFER_CONTAINER:
|
129
|
+
break;
|
127
130
|
case GI_TRANSFER_EVERYTHING:
|
131
|
+
if (gtype == G_TYPE_NONE) {
|
132
|
+
/* If the target struct is raw (not GType-ed) struct, we
|
133
|
+
* can't know how to free fields in the target struct. We
|
134
|
+
* assume that the target struct doesn't allocate nothing
|
135
|
+
* for its fields.
|
136
|
+
*
|
137
|
+
* e.g.: The attributes out argument in
|
138
|
+
* vte_terminal_get_text_range():
|
139
|
+
* https://developer.gnome.org/vte/unstable/VteTerminal.html#vte-terminal-get-text-range
|
140
|
+
*/
|
141
|
+
break;
|
142
|
+
}
|
128
143
|
default:
|
129
144
|
rb_raise(rb_eNotImpError,
|
130
|
-
"TODO: [%s] %s free GIArgument(%s)[%s]",
|
145
|
+
"TODO: [%s] %s free GIArgument(%s/%s)[interface(%s)](%s)[%s]",
|
131
146
|
metadata->name,
|
132
147
|
rb_gi_direction_to_string(metadata->direction),
|
133
148
|
g_type_tag_to_string(metadata->type.tag),
|
149
|
+
rb_gi_array_type_to_string(metadata->array_type),
|
150
|
+
g_info_type_to_string(metadata->element_type.interface_type),
|
151
|
+
g_type_name(metadata->element_type.interface_gtype),
|
134
152
|
rb_gi_transfer_to_string(metadata->transfer));
|
135
153
|
}
|
136
154
|
g_array_free(target, TRUE);
|
@@ -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
|
@@ -23,16 +23,7 @@
|
|
23
23
|
static gboolean
|
24
24
|
rb_gi_arg_info_may_be_null(GIArgInfo *arg_info)
|
25
25
|
{
|
26
|
-
#if GI_CHECK_VERSION(1, 42, 0)
|
27
26
|
return g_arg_info_may_be_null(arg_info);
|
28
|
-
#else
|
29
|
-
/*
|
30
|
-
GObject Introspection < 1.42 doesn't support "(nullable)" yet.
|
31
|
-
So, we assume that all argument may be NULL. It's danger but
|
32
|
-
convenient.
|
33
|
-
*/
|
34
|
-
return TRUE;
|
35
|
-
#endif
|
36
27
|
}
|
37
28
|
|
38
29
|
static gboolean
|
@@ -506,6 +497,48 @@ rb_gi_arguments_get_rb_out_args(RBGIArguments *args)
|
|
506
497
|
return rb_gi_arguments_out_to_ruby(args);
|
507
498
|
}
|
508
499
|
|
500
|
+
void
|
501
|
+
rb_gi_arguments_fill_raw_out_gerror(RBGIArguments *args,
|
502
|
+
VALUE rb_error)
|
503
|
+
{
|
504
|
+
if (!g_callable_info_can_throw_gerror(args->info)) {
|
505
|
+
return;
|
506
|
+
}
|
507
|
+
|
508
|
+
gint n_args = g_callable_info_get_n_args(args->info);
|
509
|
+
/* GError ** isn't listed in args. */
|
510
|
+
GError **gerror = *((gpointer *)(args->raw_args[n_args]));
|
511
|
+
VALUE cGLibError = rb_const_get(mGLib, rb_intern("Error"));
|
512
|
+
if (NIL_P(rb_error)) {
|
513
|
+
g_set_error(gerror,
|
514
|
+
RBG_RUBY_ERROR,
|
515
|
+
RBG_RUBY_ERROR_UNKNOWN,
|
516
|
+
"Unknown error");
|
517
|
+
} else {
|
518
|
+
VALUE message = rb_funcall(rb_error, rb_intern("message"), 0);
|
519
|
+
VALUE backtrace = rb_funcall(rb_error, rb_intern("backtrace"), 0);
|
520
|
+
VALUE formatted_backtrace =
|
521
|
+
rb_ary_join(backtrace, rb_str_new_cstr(" \n"));
|
522
|
+
if (CBOOL2RVAL(rb_obj_is_kind_of(rb_error, cGLibError))) {
|
523
|
+
VALUE domain = rb_funcall(rb_error, rb_intern("domain"), 0);
|
524
|
+
VALUE code = rb_funcall(rb_error, rb_intern("code"), 0);
|
525
|
+
g_set_error(gerror,
|
526
|
+
g_quark_from_string(RVAL2CSTR(domain)),
|
527
|
+
NUM2INT(code),
|
528
|
+
"%s\n %s\n",
|
529
|
+
RVAL2CSTR(message),
|
530
|
+
RVAL2CSTR(formatted_backtrace));
|
531
|
+
} else {
|
532
|
+
g_set_error(gerror,
|
533
|
+
RBG_RUBY_ERROR,
|
534
|
+
RBG_RUBY_ERROR_UNKNOWN,
|
535
|
+
"%s\n %s\n",
|
536
|
+
RVAL2CSTR(message),
|
537
|
+
RVAL2CSTR(formatted_backtrace));
|
538
|
+
}
|
539
|
+
}
|
540
|
+
}
|
541
|
+
|
509
542
|
static void
|
510
543
|
rb_gi_arguments_fill_raw_result_interface(RBGIArguments *args,
|
511
544
|
VALUE rb_result,
|
@@ -586,6 +619,160 @@ rb_gi_arguments_fill_raw_result_interface(RBGIArguments *args,
|
|
586
619
|
g_base_info_unref(interface_info);
|
587
620
|
}
|
588
621
|
|
622
|
+
static void
|
623
|
+
rb_gi_arguments_fill_raw_result_glist_interface(
|
624
|
+
RBGIArguments *args,
|
625
|
+
VALUE rb_result,
|
626
|
+
gpointer raw_result,
|
627
|
+
GITypeInfo *type_info,
|
628
|
+
GITypeInfo *element_type_info,
|
629
|
+
G_GNUC_UNUSED GITransfer transfer /* TODO */,
|
630
|
+
gboolean is_return_value)
|
631
|
+
{
|
632
|
+
GIFFIReturnValue *ffi_return_value = raw_result;
|
633
|
+
GIBaseInfo *interface_info;
|
634
|
+
GIInfoType interface_type;
|
635
|
+
const gchar *interface_name;
|
636
|
+
GType gtype;
|
637
|
+
GList *list = NULL;
|
638
|
+
|
639
|
+
interface_info = g_type_info_get_interface(element_type_info);
|
640
|
+
interface_type = g_base_info_get_type(interface_info);
|
641
|
+
interface_name = g_info_type_to_string(interface_type);
|
642
|
+
gtype = g_registered_type_info_get_g_type(interface_info);
|
643
|
+
|
644
|
+
switch (interface_type) {
|
645
|
+
case GI_INFO_TYPE_INVALID:
|
646
|
+
case GI_INFO_TYPE_FUNCTION:
|
647
|
+
case GI_INFO_TYPE_CALLBACK:
|
648
|
+
case GI_INFO_TYPE_STRUCT:
|
649
|
+
case GI_INFO_TYPE_BOXED:
|
650
|
+
case GI_INFO_TYPE_ENUM:
|
651
|
+
case GI_INFO_TYPE_FLAGS:
|
652
|
+
g_base_info_unref(interface_info);
|
653
|
+
g_base_info_unref(element_type_info);
|
654
|
+
rb_raise(rb_eNotImpError,
|
655
|
+
"TODO: %s::%s: out raw result(glist)[interface(%s)](%s)",
|
656
|
+
g_base_info_get_namespace(args->info),
|
657
|
+
g_base_info_get_name(args->info),
|
658
|
+
interface_name,
|
659
|
+
g_type_name(gtype));
|
660
|
+
break;
|
661
|
+
case GI_INFO_TYPE_OBJECT:
|
662
|
+
list = RVAL2GOBJGLIST(rb_result);
|
663
|
+
if (transfer == GI_TRANSFER_EVERYTHING) {
|
664
|
+
g_list_foreach(list, (GFunc)g_object_ref, NULL);
|
665
|
+
}
|
666
|
+
break;
|
667
|
+
case GI_INFO_TYPE_INTERFACE:
|
668
|
+
case GI_INFO_TYPE_CONSTANT:
|
669
|
+
case GI_INFO_TYPE_INVALID_0:
|
670
|
+
case GI_INFO_TYPE_UNION:
|
671
|
+
case GI_INFO_TYPE_VALUE:
|
672
|
+
case GI_INFO_TYPE_SIGNAL:
|
673
|
+
case GI_INFO_TYPE_VFUNC:
|
674
|
+
case GI_INFO_TYPE_PROPERTY:
|
675
|
+
case GI_INFO_TYPE_FIELD:
|
676
|
+
case GI_INFO_TYPE_ARG:
|
677
|
+
case GI_INFO_TYPE_TYPE:
|
678
|
+
case GI_INFO_TYPE_UNRESOLVED:
|
679
|
+
g_base_info_unref(interface_info);
|
680
|
+
g_base_info_unref(element_type_info);
|
681
|
+
rb_raise(rb_eNotImpError,
|
682
|
+
"TODO: %s::%s: out raw result(glist)[interface(%s)](%s)",
|
683
|
+
g_base_info_get_namespace(args->info),
|
684
|
+
g_base_info_get_name(args->info),
|
685
|
+
interface_name,
|
686
|
+
g_type_name(gtype));
|
687
|
+
break;
|
688
|
+
default:
|
689
|
+
g_base_info_unref(interface_info);
|
690
|
+
g_base_info_unref(element_type_info);
|
691
|
+
g_assert_not_reached();
|
692
|
+
break;
|
693
|
+
}
|
694
|
+
|
695
|
+
if (is_return_value) {
|
696
|
+
ffi_return_value->v_ulong = (gulong)list;
|
697
|
+
} else {
|
698
|
+
*((gpointer *)raw_result) = list;
|
699
|
+
}
|
700
|
+
}
|
701
|
+
|
702
|
+
static void
|
703
|
+
rb_gi_arguments_fill_raw_result_glist(RBGIArguments *args,
|
704
|
+
VALUE rb_result,
|
705
|
+
gpointer raw_result,
|
706
|
+
GITypeInfo *type_info,
|
707
|
+
GITransfer transfer,
|
708
|
+
gboolean is_return_value)
|
709
|
+
{
|
710
|
+
GIFFIReturnValue *ffi_return_value = raw_result;
|
711
|
+
GITypeInfo *element_type_info;
|
712
|
+
GITypeTag element_type_tag;
|
713
|
+
|
714
|
+
element_type_info = g_type_info_get_param_type(type_info, 0);
|
715
|
+
element_type_tag = g_type_info_get_tag(element_type_info);
|
716
|
+
|
717
|
+
if (is_return_value) {
|
718
|
+
ffi_return_value->v_ulong = (gulong)NULL;
|
719
|
+
} else {
|
720
|
+
*((gpointer *)raw_result) = NULL;
|
721
|
+
}
|
722
|
+
|
723
|
+
switch (element_type_tag) {
|
724
|
+
case GI_TYPE_TAG_VOID:
|
725
|
+
case GI_TYPE_TAG_BOOLEAN:
|
726
|
+
case GI_TYPE_TAG_INT8:
|
727
|
+
case GI_TYPE_TAG_UINT8:
|
728
|
+
case GI_TYPE_TAG_INT16:
|
729
|
+
case GI_TYPE_TAG_UINT16:
|
730
|
+
case GI_TYPE_TAG_INT32:
|
731
|
+
case GI_TYPE_TAG_UINT32:
|
732
|
+
case GI_TYPE_TAG_INT64:
|
733
|
+
case GI_TYPE_TAG_UINT64:
|
734
|
+
case GI_TYPE_TAG_FLOAT:
|
735
|
+
case GI_TYPE_TAG_DOUBLE:
|
736
|
+
case GI_TYPE_TAG_GTYPE:
|
737
|
+
case GI_TYPE_TAG_UTF8:
|
738
|
+
case GI_TYPE_TAG_FILENAME:
|
739
|
+
case GI_TYPE_TAG_ARRAY:
|
740
|
+
g_base_info_unref(element_type_info);
|
741
|
+
rb_raise(rb_eNotImpError,
|
742
|
+
"TODO: %s::%s: out raw result(GList)[%s]",
|
743
|
+
g_base_info_get_namespace(args->info),
|
744
|
+
g_base_info_get_name(args->info),
|
745
|
+
g_type_tag_to_string(element_type_tag));
|
746
|
+
break;
|
747
|
+
case GI_TYPE_TAG_INTERFACE:
|
748
|
+
rb_gi_arguments_fill_raw_result_glist_interface(
|
749
|
+
args,
|
750
|
+
rb_result,
|
751
|
+
raw_result,
|
752
|
+
type_info,
|
753
|
+
element_type_info,
|
754
|
+
transfer,
|
755
|
+
is_return_value);
|
756
|
+
break;
|
757
|
+
case GI_TYPE_TAG_GLIST:
|
758
|
+
case GI_TYPE_TAG_GSLIST:
|
759
|
+
case GI_TYPE_TAG_GHASH:
|
760
|
+
case GI_TYPE_TAG_ERROR:
|
761
|
+
case GI_TYPE_TAG_UNICHAR:
|
762
|
+
g_base_info_unref(element_type_info);
|
763
|
+
rb_raise(rb_eNotImpError,
|
764
|
+
"TODO: %s::%s: out raw result(GList)[%s]",
|
765
|
+
g_base_info_get_namespace(args->info),
|
766
|
+
g_base_info_get_name(args->info),
|
767
|
+
g_type_tag_to_string(element_type_tag));
|
768
|
+
break;
|
769
|
+
default:
|
770
|
+
g_base_info_unref(element_type_info);
|
771
|
+
g_assert_not_reached();
|
772
|
+
break;
|
773
|
+
}
|
774
|
+
}
|
775
|
+
|
589
776
|
/*
|
590
777
|
We need to cast from different type for return value. (We don't
|
591
778
|
need it for out arguments.) Because of libffi specification:
|
@@ -704,12 +891,16 @@ rb_gi_arguments_fill_raw_result(RBGIArguments *args,
|
|
704
891
|
}
|
705
892
|
break;
|
706
893
|
case GI_TYPE_TAG_UTF8:
|
707
|
-
|
708
|
-
|
709
|
-
|
710
|
-
|
711
|
-
|
712
|
-
|
894
|
+
{
|
895
|
+
gchar *result = (gchar *)RVAL2CSTR_ACCEPT_SYMBOL(rb_result);
|
896
|
+
if (transfer == GI_TRANSFER_EVERYTHING) {
|
897
|
+
result = g_strdup(result);
|
898
|
+
}
|
899
|
+
if (is_return_value) {
|
900
|
+
ffi_return_value->v_ulong = (gulong)result;
|
901
|
+
} else {
|
902
|
+
*((gchar **)raw_result) = (gchar *)result;
|
903
|
+
}
|
713
904
|
}
|
714
905
|
break;
|
715
906
|
case GI_TYPE_TAG_FILENAME:
|
@@ -748,6 +939,13 @@ rb_gi_arguments_fill_raw_result(RBGIArguments *args,
|
|
748
939
|
is_return_value);
|
749
940
|
break;
|
750
941
|
case GI_TYPE_TAG_GLIST:
|
942
|
+
rb_gi_arguments_fill_raw_result_glist(args,
|
943
|
+
rb_result,
|
944
|
+
raw_result,
|
945
|
+
type_info,
|
946
|
+
transfer,
|
947
|
+
is_return_value);
|
948
|
+
break;
|
751
949
|
case GI_TYPE_TAG_GSLIST:
|
752
950
|
case GI_TYPE_TAG_GHASH:
|
753
951
|
rb_raise(rb_eNotImpError,
|
@@ -842,7 +1040,7 @@ rb_gi_arguments_fill_raw_results(RBGIArguments *args,
|
|
842
1040
|
rb_gi_arguments_fill_raw_result(args,
|
843
1041
|
RARRAY_AREF(rb_results, i_rb_result),
|
844
1042
|
argument->v_pointer,
|
845
|
-
|
1043
|
+
type_info,
|
846
1044
|
transfer,
|
847
1045
|
FALSE);
|
848
1046
|
i_rb_result++;
|
@@ -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
|
@@ -160,6 +160,15 @@ rg_namespace(VALUE self)
|
|
160
160
|
return CSTR2RVAL(g_base_info_get_namespace(info));
|
161
161
|
}
|
162
162
|
|
163
|
+
static VALUE
|
164
|
+
rg_container(VALUE self)
|
165
|
+
{
|
166
|
+
GIBaseInfo *info;
|
167
|
+
|
168
|
+
info = SELF(self);
|
169
|
+
return rb_gi_base_info_to_ruby(g_base_info_get_container(info));
|
170
|
+
}
|
171
|
+
|
163
172
|
static VALUE
|
164
173
|
rg_operator_aref(VALUE self, VALUE name)
|
165
174
|
{
|
@@ -201,6 +210,7 @@ rb_gi_base_info_init(VALUE rb_mGI)
|
|
201
210
|
RG_DEF_METHOD(type, 0);
|
202
211
|
RG_DEF_METHOD(name, 0);
|
203
212
|
RG_DEF_METHOD(namespace, 0);
|
213
|
+
RG_DEF_METHOD(container, 0);
|
204
214
|
RG_DEF_METHOD_OPERATOR("[]", aref, 1);
|
205
215
|
RG_DEF_METHOD(each, 0);
|
206
216
|
|
@@ -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_cGICallableInfo
|
24
|
-
#define SELF(self) (
|
24
|
+
#define SELF(self) RVAL2GI_CALLABLE_INFO(self)
|
25
25
|
|
26
26
|
GType
|
27
27
|
gi_callable_info_get_type(void)
|
@@ -35,6 +35,13 @@ gi_callable_info_get_type(void)
|
|
35
35
|
return type;
|
36
36
|
}
|
37
37
|
|
38
|
+
static VALUE
|
39
|
+
rg_can_throw_gerror_p(VALUE self)
|
40
|
+
{
|
41
|
+
GICallableInfo *info = SELF(self);
|
42
|
+
return CBOOL2RVAL(g_callable_info_can_throw_gerror(info));
|
43
|
+
}
|
44
|
+
|
38
45
|
static VALUE
|
39
46
|
rg_return_type(VALUE self)
|
40
47
|
{
|
@@ -91,6 +98,7 @@ rb_gi_callable_info_init(VALUE rb_mGI, VALUE rb_cGIBaseInfo)
|
|
91
98
|
G_DEF_CLASS_WITH_PARENT(GI_TYPE_CALLABLE_INFO, "CallableInfo", rb_mGI,
|
92
99
|
rb_cGIBaseInfo);
|
93
100
|
|
101
|
+
RG_DEF_METHOD_P(can_throw_gerror, 0);
|
94
102
|
RG_DEF_METHOD(return_type, 0);
|
95
103
|
RG_DEF_METHOD(caller_owns, 0);
|
96
104
|
RG_DEF_METHOD_P(may_return_null, 0);
|
@@ -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
|
@@ -28,17 +28,171 @@ struct RBGICallbackData_ {
|
|
28
28
|
VALUE rb_owner;
|
29
29
|
};
|
30
30
|
|
31
|
+
typedef struct {
|
32
|
+
RBGIArguments *args;
|
33
|
+
RBGICallback *callback;
|
34
|
+
RBGICallbackData *callback_data;
|
35
|
+
void *return_value;
|
36
|
+
VALUE rb_return_value;
|
37
|
+
} RBGICallbackInvokeData;
|
38
|
+
|
31
39
|
static GPtrArray *callback_finders;
|
32
40
|
static VALUE mGLibObject = Qnil;
|
33
41
|
static VALUE mGI = Qnil;
|
34
42
|
|
43
|
+
static VALUE
|
44
|
+
rb_gi_callback_invoke_without_protect(VALUE user_data)
|
45
|
+
{
|
46
|
+
RBGICallbackInvokeData *data = (RBGICallbackInvokeData *)user_data;
|
47
|
+
VALUE rb_args = rb_gi_arguments_in_to_ruby(data->args);
|
48
|
+
|
49
|
+
if (data->callback->method_name) {
|
50
|
+
ID id___send__;
|
51
|
+
VALUE rb_receiver = rb_ary_shift(rb_args);
|
52
|
+
CONST_ID(id___send__, "__send__");
|
53
|
+
rb_ary_unshift(rb_args, rb_str_new_cstr(data->callback->method_name));
|
54
|
+
data->rb_return_value =
|
55
|
+
rb_funcallv(rb_receiver,
|
56
|
+
id___send__,
|
57
|
+
RARRAY_LENINT(rb_args),
|
58
|
+
RARRAY_CONST_PTR(rb_args));
|
59
|
+
} else {
|
60
|
+
ID id_call;
|
61
|
+
CONST_ID(id_call, "call");
|
62
|
+
VALUE rb_callback =
|
63
|
+
rb_gi_callback_data_get_rb_callback(data->callback_data);
|
64
|
+
data->rb_return_value =
|
65
|
+
rb_funcallv(rb_callback,
|
66
|
+
id_call,
|
67
|
+
RARRAY_LENINT(rb_args),
|
68
|
+
RARRAY_CONST_PTR(rb_args));
|
69
|
+
}
|
70
|
+
|
71
|
+
return Qnil;
|
72
|
+
}
|
73
|
+
|
74
|
+
static VALUE
|
75
|
+
rb_gi_callback_invoke_fill_raw_results(VALUE user_data)
|
76
|
+
{
|
77
|
+
RBGICallbackInvokeData *data = (RBGICallbackInvokeData *)user_data;
|
78
|
+
rb_gi_arguments_fill_raw_results(data->args,
|
79
|
+
data->rb_return_value,
|
80
|
+
data->return_value);
|
81
|
+
return Qnil;
|
82
|
+
}
|
83
|
+
|
84
|
+
static VALUE
|
85
|
+
rb_gi_callback_invoke(VALUE user_data)
|
86
|
+
{
|
87
|
+
RBGICallbackInvokeData *data = (RBGICallbackInvokeData *)user_data;
|
88
|
+
int state = 0;
|
89
|
+
rb_protect(rb_gi_callback_invoke_without_protect,
|
90
|
+
user_data,
|
91
|
+
&state);
|
92
|
+
if (state != 0) {
|
93
|
+
VALUE error = rb_errinfo();
|
94
|
+
rb_gi_arguments_fill_raw_out_gerror(data->args, error);
|
95
|
+
rb_protect(rb_gi_callback_invoke_fill_raw_results,
|
96
|
+
user_data,
|
97
|
+
&state);
|
98
|
+
} else {
|
99
|
+
rb_protect(rb_gi_callback_invoke_fill_raw_results,
|
100
|
+
user_data,
|
101
|
+
&state);
|
102
|
+
if (state != 0) {
|
103
|
+
VALUE error = rb_errinfo();
|
104
|
+
rb_gi_arguments_fill_raw_out_gerror(data->args, error);
|
105
|
+
}
|
106
|
+
}
|
107
|
+
return Qnil;
|
108
|
+
}
|
109
|
+
|
110
|
+
static void
|
111
|
+
rb_gi_ffi_closure_callback(G_GNUC_UNUSED ffi_cif *cif,
|
112
|
+
void *return_value,
|
113
|
+
void **raw_args,
|
114
|
+
void *data)
|
115
|
+
{
|
116
|
+
RBGICallback *callback = data;
|
117
|
+
RBGICallbackData *callback_data = NULL;
|
118
|
+
RBGIArguments args;
|
119
|
+
|
120
|
+
rb_gi_arguments_init(&args,
|
121
|
+
callback->callback_info,
|
122
|
+
Qnil,
|
123
|
+
Qnil,
|
124
|
+
raw_args);
|
125
|
+
{
|
126
|
+
guint i;
|
127
|
+
|
128
|
+
for (i = 0; i < args.metadata->len; i++) {
|
129
|
+
RBGIArgMetadata *metadata;
|
130
|
+
|
131
|
+
metadata = g_ptr_array_index(args.metadata, i);
|
132
|
+
if (!metadata->closure_p) {
|
133
|
+
continue;
|
134
|
+
}
|
135
|
+
|
136
|
+
callback_data = *((RBGICallbackData **)(raw_args[i]));
|
137
|
+
break;
|
138
|
+
}
|
139
|
+
|
140
|
+
if (!callback_data && args.metadata->len > 0) {
|
141
|
+
RBGIArgMetadata *metadata;
|
142
|
+
|
143
|
+
i = args.metadata->len - 1;
|
144
|
+
metadata = g_ptr_array_index(args.metadata, i);
|
145
|
+
if (metadata->type.tag == GI_TYPE_TAG_VOID &&
|
146
|
+
metadata->type.pointer_p &&
|
147
|
+
strcmp(metadata->name, "data") == 0) {
|
148
|
+
callback_data = *((RBGICallbackData **)(raw_args[i]));
|
149
|
+
}
|
150
|
+
}
|
151
|
+
}
|
152
|
+
|
153
|
+
{
|
154
|
+
RBGICallbackInvokeData data;
|
155
|
+
data.args = &args;
|
156
|
+
data.callback = callback;
|
157
|
+
data.callback_data = callback_data;
|
158
|
+
data.return_value = return_value;
|
159
|
+
data.rb_return_value = Qnil;
|
160
|
+
rbgutil_invoke_callback(rb_gi_callback_invoke, (VALUE)&data);
|
161
|
+
}
|
162
|
+
rb_gi_arguments_clear(&args);
|
163
|
+
|
164
|
+
if (callback_data) {
|
165
|
+
RBGIArgMetadata *callback_metadata =
|
166
|
+
rb_gi_callback_data_get_metadata(callback_data);
|
167
|
+
if (callback_metadata->scope_type == GI_SCOPE_TYPE_ASYNC) {
|
168
|
+
rb_gi_callback_data_free(callback_data);
|
169
|
+
}
|
170
|
+
}
|
171
|
+
}
|
172
|
+
|
173
|
+
RBGICallback *
|
174
|
+
rb_gi_callback_new(GICallbackInfo *callback_info,
|
175
|
+
const gchar *method_name)
|
176
|
+
{
|
177
|
+
RBGICallback *callback = RB_ZALLOC(RBGICallback);
|
178
|
+
callback->callback_info = callback_info;
|
179
|
+
g_base_info_ref(callback->callback_info);
|
180
|
+
callback->method_name = g_strdup(method_name);
|
181
|
+
callback->closure =
|
182
|
+
g_callable_info_prepare_closure(callback->callback_info,
|
183
|
+
&(callback->cif),
|
184
|
+
rb_gi_ffi_closure_callback,
|
185
|
+
callback);
|
186
|
+
return callback;
|
187
|
+
}
|
188
|
+
|
35
189
|
static void
|
36
190
|
rb_gi_callback_free(RBGICallback *callback)
|
37
191
|
{
|
38
192
|
g_callable_info_free_closure(callback->callback_info,
|
39
193
|
callback->closure);
|
194
|
+
g_free(callback->method_name);
|
40
195
|
g_base_info_unref(callback->callback_info);
|
41
|
-
g_base_info_unref(callback->type_info);
|
42
196
|
xfree(callback);
|
43
197
|
}
|
44
198
|
|