gobject-introspection 3.4.0 → 3.4.5

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 (34) hide show
  1. checksums.yaml +4 -4
  2. data/ext/gobject-introspection/extconf.rb +1 -4
  3. data/ext/gobject-introspection/rb-gi-argument.c +10 -3
  4. data/ext/gobject-introspection/rb-gi-arguments-in.c +82 -122
  5. data/ext/gobject-introspection/rb-gi-arguments-out.c +31 -11
  6. data/ext/gobject-introspection/rb-gi-arguments.c +217 -18
  7. data/ext/gobject-introspection/rb-gi-base-info.c +11 -1
  8. data/ext/gobject-introspection/rb-gi-callable-info.c +10 -2
  9. data/ext/gobject-introspection/rb-gi-callback.c +156 -2
  10. data/ext/gobject-introspection/rb-gi-conversions.h +6 -6
  11. data/ext/gobject-introspection/rb-gi-interface-info.c +1 -7
  12. data/ext/gobject-introspection/rb-gi-loader.c +58 -10
  13. data/ext/gobject-introspection/rb-gi-object-info.c +11 -1
  14. data/ext/gobject-introspection/rb-gi-private-arguments-in.h +3 -1
  15. data/ext/gobject-introspection/rb-gi-private-arguments.h +6 -2
  16. data/ext/gobject-introspection/rb-gi-private-callback.h +6 -3
  17. data/ext/gobject-introspection/rb-gi-private.h +1 -0
  18. data/ext/gobject-introspection/rb-gi-repository.c +1 -1
  19. data/ext/gobject-introspection/rb-gi-struct-info.c +15 -3
  20. data/ext/gobject-introspection/rb-gi-vfunc-info.c +2 -2
  21. data/ext/gobject-introspection/rb-gobject-introspection.c +231 -0
  22. data/lib/gobject-introspection/loader.rb +66 -2
  23. data/lib/gobject-introspection/type-tag.rb +2 -0
  24. data/test/gobject-introspection-test-utils.rb +2 -2
  25. data/test/run-test.rb +18 -25
  26. data/test/test-base-info.rb +5 -1
  27. data/test/test-callable-info.rb +16 -2
  28. data/test/test-loader.rb +53 -7
  29. data/test/test-object-info.rb +5 -1
  30. data/test/test-struct-info.rb +6 -1
  31. metadata +5 -8
  32. data/ext/gobject-introspection/gobject-introspection-enum-types.c +0 -230
  33. data/ext/gobject-introspection/gobject-introspection-enum-types.h +0 -42
  34. data/ext/gobject-introspection/rbgiversion.h +0 -24
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 439904c07c9ece750e11324a9e7220e92703960c464e3096b592b4a0c60089ed
4
- data.tar.gz: 43364a70a42e79df745fa61912d528b47442025f42b7456ee950dbcad7b259e6
3
+ metadata.gz: '073080df7a1c63c600038ca2b3f5edce7e4b090c580b530bed49ab72afc02310'
4
+ data.tar.gz: 9cb1dd9c3f5badc0c0a917206d42d18783626db421a701a8737fa7398c7cefa5
5
5
  SHA512:
6
- metadata.gz: 96504ea3a2364df9625cf2b3846479f07cf0dbea4aeb81b5761aca751959476db272a15479c64d244ad72ab77f0b21698a3896ebec0efb1bdac56cc2f444958d
7
- data.tar.gz: 9b8b9e7ad2545423e95baa93241ba7ac4679cf5e5871361ffe58f503f3abb4b8997da90d2e85ec17423ead5abe80aa2a54b4ca6c6d1d024fd399bc67be0d157f
6
+ metadata.gz: 8e0ca0522ffbc58c6276455fb7d27c90afc1d959881af569c63b17607bd46cb6fca3463a74699ac1b8f244ec159d5c09edd736eb67641631ed5da48cebff4c8f
7
+ data.tar.gz: f2d8856c0cb47cf65cd54753a2d0dcad71a4c2519a64ccd5a9f515ba5c8eb42dfe6dea034f7498ca8eeac438e79b83ff84bae139bcc7e799693f55aeb43347b7
@@ -1,6 +1,6 @@
1
1
  #!/usr/bin/env ruby
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
@@ -62,9 +62,6 @@ end
62
62
  # TODO: Remove this when we dropped support for GObject Introspection < 1.60
63
63
  make_version_header("GI", package_id, ".")
64
64
 
65
- gi_headers = ["girepository.h"]
66
- have_func("g_interface_info_find_signal", gi_headers)
67
-
68
65
  enum_type_prefix = "gobject-introspection-enum-types"
69
66
  include_paths = PKGConfig.cflags_only_I(package_id)
70
67
  headers = include_paths.split.inject([]) do |result, path|
@@ -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
@@ -2011,11 +2011,18 @@ rb_gi_return_argument_to_ruby(GICallableInfo *callable_info,
2011
2011
  GITypeInfo return_value_info;
2012
2012
 
2013
2013
  may_return_null = g_callable_info_may_return_null(callable_info);
2014
+ g_callable_info_load_return_type(callable_info, &return_value_info);
2014
2015
  if (may_return_null && !argument->v_pointer) {
2015
- return Qnil;
2016
+ GITypeTag return_value_tag = g_type_info_get_tag(&return_value_info);
2017
+ switch (return_value_tag) {
2018
+ case GI_TYPE_TAG_GLIST:
2019
+ case GI_TYPE_TAG_GSLIST:
2020
+ return rb_ary_new();
2021
+ default:
2022
+ return Qnil;
2023
+ }
2016
2024
  }
2017
2025
 
2018
- g_callable_info_load_return_type(callable_info, &return_value_info);
2019
2026
  rb_argument = rb_gi_argument_to_ruby(argument, FALSE, &return_value_info,
2020
2027
  in_args, out_args, args_metadata);
2021
2028
  switch (g_callable_info_get_caller_owns(callable_info)) {
@@ -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
@@ -27,13 +27,7 @@ rb_gi_callback_data_destroy_notify(gpointer data)
27
27
  rb_gi_callback_data_free(callback_data);
28
28
  }
29
29
 
30
- typedef struct {
31
- RBGIArguments *args;
32
- RBGICallback *callback;
33
- RBGICallbackData *callback_data;
34
- } RBGICallbackInvokeData;
35
-
36
- static VALUE
30
+ VALUE
37
31
  rb_gi_arguments_in_to_ruby(RBGIArguments *args)
38
32
  {
39
33
  VALUE rb_in_args;
@@ -68,85 +62,6 @@ rb_gi_arguments_in_to_ruby(RBGIArguments *args)
68
62
  return rb_in_args;
69
63
  }
70
64
 
71
- static VALUE
72
- rb_gi_callback_invoke(VALUE user_data)
73
- {
74
- RBGICallbackInvokeData *data = (RBGICallbackInvokeData *)user_data;
75
- ID id_call;
76
- VALUE rb_callback = rb_gi_callback_data_get_rb_callback(data->callback_data);
77
- VALUE rb_args = rb_gi_arguments_in_to_ruby(data->args);
78
-
79
- CONST_ID(id_call, "call");
80
- return rb_funcallv(rb_callback,
81
- id_call,
82
- RARRAY_LENINT(rb_args),
83
- RARRAY_CONST_PTR(rb_args));
84
- }
85
-
86
- static void
87
- rb_gi_ffi_closure_callback(G_GNUC_UNUSED ffi_cif *cif,
88
- void *return_value,
89
- void **raw_args,
90
- void *data)
91
- {
92
- RBGICallback *callback = data;
93
- RBGICallbackData *callback_data = NULL;
94
- RBGIArguments args;
95
- VALUE rb_results;
96
-
97
- rb_gi_arguments_init(&args,
98
- callback->callback_info,
99
- Qnil,
100
- Qnil,
101
- raw_args);
102
- {
103
- guint i;
104
-
105
- for (i = 0; i < args.metadata->len; i++) {
106
- RBGIArgMetadata *metadata;
107
-
108
- metadata = g_ptr_array_index(args.metadata, i);
109
- if (!metadata->closure_p) {
110
- continue;
111
- }
112
-
113
- callback_data = *((RBGICallbackData **)(raw_args[i]));
114
- break;
115
- }
116
-
117
- if (!callback_data && args.metadata->len > 0) {
118
- RBGIArgMetadata *metadata;
119
-
120
- i = args.metadata->len - 1;
121
- metadata = g_ptr_array_index(args.metadata, i);
122
- if (metadata->type.tag == GI_TYPE_TAG_VOID &&
123
- metadata->pointer_p &&
124
- strcmp(metadata->name, "data") == 0) {
125
- callback_data = *((RBGICallbackData **)(raw_args[i]));
126
- }
127
- }
128
- }
129
-
130
- {
131
- RBGICallbackInvokeData data;
132
- data.args = &args;
133
- data.callback = callback;
134
- data.callback_data = callback_data;
135
- rb_results = rbgutil_invoke_callback(rb_gi_callback_invoke,
136
- (VALUE)&data);
137
- }
138
- rb_gi_arguments_fill_raw_results(&args, rb_results, return_value);
139
- rb_gi_arguments_clear(&args);
140
-
141
- {
142
- RBGIArgMetadata *callback_metadata =
143
- rb_gi_callback_data_get_metadata(callback_data);
144
- if (callback_metadata->scope_type == GI_SCOPE_TYPE_ASYNC) {
145
- rb_gi_callback_data_free(callback_data);
146
- }
147
- }
148
- }
149
-
150
65
  static void
151
66
  rb_gi_arguments_in_init_arg_ruby_callback(RBGIArguments *args,
152
67
  RBGIArgMetadata *metadata)
@@ -187,14 +102,11 @@ rb_gi_arguments_in_init_arg_ruby_callback(RBGIArguments *args,
187
102
  if (callback_function) {
188
103
  callback_argument->v_pointer = callback_function;
189
104
  } else {
190
- callback = RB_ZALLOC(RBGICallback);
191
- callback->type_info = g_arg_info_get_type(arg_info);
192
- callback->callback_info = g_type_info_get_interface(callback->type_info);
193
- callback->closure =
194
- g_callable_info_prepare_closure(callback->callback_info,
195
- &(callback->cif),
196
- rb_gi_ffi_closure_callback,
197
- callback);
105
+ GITypeInfo *type_info = g_arg_info_get_type(arg_info);
106
+ GICallbackInfo *callback_info = g_type_info_get_interface(type_info);
107
+ callback = rb_gi_callback_new(callback_info, NULL);
108
+ g_base_info_unref(callback_info);
109
+ g_base_info_unref(type_info);
198
110
  callback_argument->v_pointer = callback->closure;
199
111
  }
200
112
 
@@ -682,7 +594,7 @@ rb_gi_arguments_in_init_arg_ruby_array_c_gtype(RBGIArguments *args,
682
594
  raw_array = ALLOC_N(GType, n_elements);
683
595
  for (i = 0; i < n_elements; i++) {
684
596
  VALUE rb_type = RARRAY_AREF(rb_array, i);
685
- raw_array[i] = rbgobj_gtype_get(rb_type);
597
+ raw_array[i] = rbgobj_gtype_from_ruby(rb_type);
686
598
  }
687
599
 
688
600
  rb_gi_arguments_in_init_arg_ruby_array_c_generic(args,
@@ -721,26 +633,50 @@ rb_gi_arguments_in_init_arg_ruby_array_c_interface_struct(RBGIArguments *args,
721
633
  {
722
634
  GIStructInfo *struct_info =
723
635
  (GIStructInfo *)(metadata->element_type.interface_info);
724
- guint8 *raw_array;
725
- gsize struct_size;
726
636
  long i, n_elements;
727
637
 
728
638
  n_elements = RARRAY_LEN(rb_array);
729
- struct_size = g_struct_info_get_size(struct_info);
730
- raw_array = ALLOC_N(guint8, struct_size * n_elements);
731
- for (i = 0; i < n_elements; i++) {
732
- VALUE rb_element = RARRAY_AREF(rb_array, i);
733
- gpointer element;
734
- element = rb_gi_struct_info_from_ruby(struct_info, rb_element);
735
- memcpy(raw_array + (struct_size * i),
736
- element,
737
- struct_size);
639
+ if (metadata->element_type.pointer_p) {
640
+ if (metadata->transfer != GI_TRANSFER_NOTHING) {
641
+ rb_raise(rb_eNotImpError,
642
+ "TODO: [%s::%s] %s "
643
+ "Ruby -> GIArgument(array/%s)[interface(%s)](%s)[%s]",
644
+ args->name,
645
+ metadata->name,
646
+ rb_gi_direction_to_string(metadata->direction),
647
+ rb_gi_array_type_to_string(metadata->array_type),
648
+ g_info_type_to_string(metadata->element_type.interface_type),
649
+ g_type_name(metadata->element_type.interface_gtype),
650
+ rb_gi_transfer_to_string(metadata->transfer));
651
+ }
652
+ gpointer *raw_array = ALLOC_N(gpointer, n_elements);
653
+ for (i = 0; i < n_elements; i++) {
654
+ VALUE rb_element = RARRAY_AREF(rb_array, i);
655
+ gpointer element;
656
+ element = rb_gi_struct_info_from_ruby(struct_info, rb_element);
657
+ raw_array[i] = element;
658
+ }
659
+ rb_gi_arguments_in_init_arg_ruby_array_c_generic(args,
660
+ metadata,
661
+ rb_array,
662
+ raw_array);
663
+ } else {
664
+ gsize struct_size = g_struct_info_get_size(struct_info);
665
+ guint8 *raw_array = ALLOC_N(guint8, struct_size * n_elements);
666
+ for (i = 0; i < n_elements; i++) {
667
+ VALUE rb_element = RARRAY_AREF(rb_array, i);
668
+ gpointer element;
669
+ element = rb_gi_struct_info_from_ruby(struct_info, rb_element);
670
+ memcpy(raw_array + (struct_size * i),
671
+ element,
672
+ struct_size);
673
+ }
674
+ rb_gi_arguments_in_init_arg_ruby_array_c_generic(args,
675
+ metadata,
676
+ rb_array,
677
+ raw_array);
738
678
  }
739
679
 
740
- rb_gi_arguments_in_init_arg_ruby_array_c_generic(args,
741
- metadata,
742
- rb_array,
743
- raw_array);
744
680
  metadata->free_func = rb_gi_arguments_in_free_array_c_interface_struct;
745
681
  }
746
682
 
@@ -980,7 +916,15 @@ rb_gi_arguments_in_init_arg_ruby_array_c(RBGIArguments *args,
980
916
  rb_arg);
981
917
  break;
982
918
  case GI_TYPE_TAG_UTF8:
983
- {
919
+ /* Workaround for rsvg_handle_set_stylesheet():
920
+ https://gitlab.gnome.org/GNOME/librsvg/-/issues/596 */
921
+ if (strcmp(metadata->name, "css") == 0) {
922
+ metadata->in_arg->v_pointer = (char *)RVAL2CSTR(rb_arg);
923
+ rb_gi_arguments_in_init_arg_ruby_array_set_length(args,
924
+ metadata,
925
+ RSTRING_LEN(rb_arg));
926
+ metadata->free_func = NULL;
927
+ } else {
984
928
  GIArgument *array_argument = metadata->in_arg;
985
929
  gchar **raw_array;
986
930
  long length;
@@ -1230,15 +1174,6 @@ rb_gi_arguments_in_init_arg_ruby_interface(RBGIArguments *args,
1230
1174
  rb_gi_transfer_to_string(metadata->transfer));
1231
1175
  break;
1232
1176
  case GI_INFO_TYPE_STRUCT:
1233
- if (metadata->transfer != GI_TRANSFER_NOTHING) {
1234
- rb_raise(rb_eNotImpError,
1235
- "TODO: [%s] %s Ruby -> GIArgument(interface)[%s][%s][%s]",
1236
- metadata->name,
1237
- rb_gi_direction_to_string(metadata->direction),
1238
- g_info_type_to_string(metadata->type.interface_type),
1239
- g_type_name(metadata->type.interface_gtype),
1240
- rb_gi_transfer_to_string(metadata->transfer));
1241
- }
1242
1177
  metadata->free_func = rb_gi_arguments_in_free_interface_struct;
1243
1178
  if (metadata->type.interface_gtype == G_TYPE_VALUE) {
1244
1179
  GValue *gvalue;
@@ -1645,7 +1580,15 @@ rb_gi_arguments_in_init_arg_ruby_ghash_body(VALUE value_data)
1645
1580
  case GI_TYPE_TAG_FLOAT:
1646
1581
  case GI_TYPE_TAG_DOUBLE:
1647
1582
  case GI_TYPE_TAG_GTYPE:
1583
+ rb_raise(rb_eNotImpError,
1584
+ "TODO: Ruby -> GIArgument(GHash)[value][%s]",
1585
+ g_type_tag_to_string(metadata->value_type.tag));
1586
+ break;
1648
1587
  case GI_TYPE_TAG_UTF8:
1588
+ value_destroy_func = g_free;
1589
+ value_ruby_to_c_func = ruby_to_c_utf8;
1590
+ value_ruby_to_c_data.context = "Ruby -> GIArgument(GHash)[value][utf8]";
1591
+ break;
1649
1592
  case GI_TYPE_TAG_FILENAME:
1650
1593
  case GI_TYPE_TAG_ARRAY:
1651
1594
  rb_raise(rb_eNotImpError,
@@ -2029,13 +1972,30 @@ rb_gi_arguments_in_init_arg_ruby(RBGIArguments *args,
2029
1972
  case GI_TYPE_TAG_UNICHAR:
2030
1973
  {
2031
1974
  gunichar *target;
1975
+ VALUE rb_unichar;
2032
1976
  if (metadata->direction == GI_DIRECTION_INOUT) {
2033
1977
  target = ALLOC(gunichar);
2034
1978
  metadata->in_arg->v_pointer = target;
2035
1979
  } else {
2036
1980
  target = &(metadata->in_arg->v_uint32);
2037
1981
  }
2038
- *target = NUM2UINT(metadata->rb_arg);
1982
+ if (RB_TYPE_P(metadata->rb_arg, RUBY_T_STRING)) {
1983
+ VALUE rb_codepoints;
1984
+ if (rb_str_strlen(metadata->rb_arg) != 1) {
1985
+ rb_raise(rb_eArgError,
1986
+ "[%s][%s] must be one character: %+" PRIsVALUE,
1987
+ metadata->name,
1988
+ g_type_tag_to_string(metadata->type.tag),
1989
+ metadata->rb_arg);
1990
+ }
1991
+ rb_codepoints = rb_funcall(metadata->rb_arg,
1992
+ rb_intern("codepoints"),
1993
+ 0);
1994
+ rb_unichar = RARRAY_PTR(rb_codepoints)[0];
1995
+ } else {
1996
+ rb_unichar = metadata->rb_arg;
1997
+ }
1998
+ *target = NUM2UINT(rb_unichar);
2039
1999
  }
2040
2000
  break;
2041
2001
  default:
@@ -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);
@@ -505,16 +523,18 @@ rb_gi_arguments_out_init_arg_interface(RBGIArguments *args,
505
523
  g_info_type_to_string(metadata->type.interface_type));
506
524
  break;
507
525
  case GI_INFO_TYPE_STRUCT:
508
- {
509
- gsize struct_size;
510
-
511
- /* Should we care gtype?
512
- Related: rb_gi_arguments_out_arg_clear_interface() */
513
- struct_size = g_struct_info_get_size(metadata->type.interface_info);
526
+ /* Should we care gtype? */
527
+ if (metadata->type.pointer_p) {
528
+ gpointer *struct_location = RB_ALLOC(gpointer);
529
+ *struct_location = NULL;
530
+ argument->v_pointer = struct_location;
531
+ } else {
532
+ gsize struct_size =
533
+ g_struct_info_get_size(metadata->type.interface_info);
514
534
  argument->v_pointer = xmalloc(struct_size);
515
535
  memset(argument->v_pointer, 0, struct_size);
516
- metadata->free_func = rb_gi_arguments_out_free_interface_struct;
517
536
  }
537
+ metadata->free_func = rb_gi_arguments_out_free_interface_struct;
518
538
  break;
519
539
  case GI_INFO_TYPE_BOXED:
520
540
  rb_raise(rb_eNotImpError,
@@ -584,7 +604,7 @@ rb_gi_arguments_out_init_arg(RBGIArguments *args,
584
604
  memset(argument, 0, sizeof(GIArgument));
585
605
  switch (metadata->type.tag) {
586
606
  case GI_TYPE_TAG_VOID:
587
- if (metadata->pointer_p) {
607
+ if (metadata->type.pointer_p) {
588
608
  gpointer *pointer = ALLOC(gpointer);
589
609
  *pointer = NULL;
590
610
  argument->v_pointer = pointer;
@@ -800,7 +820,7 @@ rb_gi_arguments_out_to_ruby_arg(RBGIArguments *args,
800
820
  memset(&normalized_argument, 0, sizeof(GIArgument));
801
821
  switch (metadata->type.tag) {
802
822
  case GI_TYPE_TAG_VOID:
803
- if (metadata->pointer_p) {
823
+ if (metadata->type.pointer_p) {
804
824
  normalized_argument.v_pointer = *((gpointer *)(argument->v_pointer));
805
825
  }
806
826
  break;
@@ -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
@@ -57,12 +48,14 @@ rb_gi_arg_metadata_type_init(RBGIArgMetadataType *type,
57
48
  GITypeInfo *type_info)
58
49
  {
59
50
  type->info = type_info;
51
+ type->pointer_p = FALSE;
60
52
  type->tag = GI_TYPE_TAG_VOID;
61
53
  type->interface_info = NULL;
62
54
  type->interface_type = GI_INFO_TYPE_INVALID;
63
55
  type->interface_gtype = G_TYPE_INVALID;
64
56
 
65
57
  if (type->info) {
58
+ type->pointer_p = g_type_info_is_pointer(type->info);
66
59
  type->tag = g_type_info_get_tag(type->info);
67
60
  }
68
61
  if (type->tag == GI_TYPE_TAG_INTERFACE) {
@@ -114,7 +107,6 @@ rb_gi_arg_metadata_new(GICallableInfo *callable_info, gint i)
114
107
  metadata->array_p = (metadata->type.tag == GI_TYPE_TAG_ARRAY);
115
108
  metadata->array_length_p = FALSE;
116
109
  metadata->may_be_null_p = rb_gi_arg_info_may_be_null(arg_info);
117
- metadata->pointer_p = g_type_info_is_pointer(type_info);
118
110
  metadata->caller_allocates_p = g_arg_info_is_caller_allocates(arg_info);
119
111
  metadata->zero_terminated_p = FALSE;
120
112
  metadata->output_buffer_p = rb_gi_arg_info_is_output_buffer(arg_info);
@@ -505,6 +497,48 @@ rb_gi_arguments_get_rb_out_args(RBGIArguments *args)
505
497
  return rb_gi_arguments_out_to_ruby(args);
506
498
  }
507
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
+
508
542
  static void
509
543
  rb_gi_arguments_fill_raw_result_interface(RBGIArguments *args,
510
544
  VALUE rb_result,
@@ -585,6 +619,160 @@ rb_gi_arguments_fill_raw_result_interface(RBGIArguments *args,
585
619
  g_base_info_unref(interface_info);
586
620
  }
587
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
+
588
776
  /*
589
777
  We need to cast from different type for return value. (We don't
590
778
  need it for out arguments.) Because of libffi specification:
@@ -703,12 +891,16 @@ rb_gi_arguments_fill_raw_result(RBGIArguments *args,
703
891
  }
704
892
  break;
705
893
  case GI_TYPE_TAG_UTF8:
706
- if (is_return_value) {
707
- ffi_return_value->v_ulong =
708
- (gulong)RVAL2CSTR_ACCEPT_SYMBOL(rb_result);
709
- } else {
710
- *((gchar **)raw_result) =
711
- (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
+ }
712
904
  }
713
905
  break;
714
906
  case GI_TYPE_TAG_FILENAME:
@@ -747,6 +939,13 @@ rb_gi_arguments_fill_raw_result(RBGIArguments *args,
747
939
  is_return_value);
748
940
  break;
749
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;
750
949
  case GI_TYPE_TAG_GSLIST:
751
950
  case GI_TYPE_TAG_GHASH:
752
951
  rb_raise(rb_eNotImpError,
@@ -841,7 +1040,7 @@ rb_gi_arguments_fill_raw_results(RBGIArguments *args,
841
1040
  rb_gi_arguments_fill_raw_result(args,
842
1041
  RARRAY_AREF(rb_results, i_rb_result),
843
1042
  argument->v_pointer,
844
- return_type_info,
1043
+ type_info,
845
1044
  transfer,
846
1045
  FALSE);
847
1046
  i_rb_result++;