gobject-introspection 3.4.2 → 3.4.6

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 +10 -3
  6. data/ext/gobject-introspection/rb-gi-arguments-in.c +27 -107
  7. data/ext/gobject-introspection/rb-gi-arguments-out.c +20 -2
  8. data/ext/gobject-introspection/rb-gi-arguments.c +215 -17
  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 +58 -10
  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
@@ -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-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
@@ -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
- if (is_return_value) {
708
- ffi_return_value->v_ulong =
709
- (gulong)RVAL2CSTR_ACCEPT_SYMBOL(rb_result);
710
- } else {
711
- *((gchar **)raw_result) =
712
- (gchar *)RVAL2CSTR_ACCEPT_SYMBOL(rb_result);
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
- return_type_info,
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-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
@@ -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-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_cGICallableInfo
24
- #define SELF(self) ((GICallableInfo *)(RVAL2GI_BASE_INFO(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-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
@@ -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