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.
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