gir_ffi 0.5.1 → 0.5.2
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.
- data/History.txt +8 -0
- data/lib/ffi-glib/array.rb +1 -1
- data/lib/ffi-glib.rb +7 -12
- data/lib/ffi-gobject/closure.rb +1 -4
- data/lib/ffi-gobject/object.rb +2 -2
- data/lib/ffi-gobject/ruby_style.rb +2 -0
- data/lib/ffi-gobject/value.rb +19 -1
- data/lib/ffi-gobject.rb +14 -9
- data/lib/ffi-gobject_introspection/i_base_info.rb +5 -5
- data/lib/ffi-gobject_introspection/i_repository.rb +1 -1
- data/lib/ffi-gobject_introspection/lib.rb +1 -1
- data/lib/gir_ffi/arg_helper.rb +3 -3
- data/lib/gir_ffi/argument_builder.rb +21 -17
- data/lib/gir_ffi/base_argument_builder.rb +5 -3
- data/lib/gir_ffi/builder/type/object.rb +1 -0
- data/lib/gir_ffi/builder/type/user_defined.rb +2 -3
- data/lib/gir_ffi/builder.rb +2 -2
- data/lib/gir_ffi/builder_helper.rb +2 -2
- data/lib/gir_ffi/callback_helper.rb +9 -9
- data/lib/gir_ffi/function_builder.rb +2 -2
- data/lib/gir_ffi/in_out_pointer.rb +1 -3
- data/lib/gir_ffi/in_pointer.rb +15 -2
- data/lib/gir_ffi/info_ext/i_arg_info.rb +27 -0
- data/lib/gir_ffi/info_ext/i_field_info.rb +1 -0
- data/lib/gir_ffi/info_ext/i_property_info.rb +1 -0
- data/lib/gir_ffi/info_ext/i_registered_type_info.rb +1 -1
- data/lib/gir_ffi/info_ext/i_signal_info.rb +65 -0
- data/lib/gir_ffi/info_ext/i_type_info.rb +15 -0
- data/lib/gir_ffi/info_ext/safe_constant_name.rb +1 -0
- data/lib/gir_ffi/info_ext/safe_function_name.rb +1 -0
- data/lib/gir_ffi/info_ext.rb +2 -0
- data/lib/gir_ffi/module_base.rb +1 -3
- data/lib/gir_ffi/return_value_builder.rb +1 -4
- data/lib/gir_ffi/version.rb +1 -2
- data/lib/gir_ffi/zero_terminated.rb +42 -0
- data/lib/gir_ffi.rb +1 -0
- data/test/ffi-gobject/value_test.rb +30 -1
- data/test/ffi-gobject_introspection/i_object_info_test.rb +4 -4
- data/test/ffi-gobject_test.rb +20 -0
- data/test/gir_ffi/arg_helper_test.rb +4 -4
- data/test/gir_ffi/argument_builder_test.rb +16 -0
- data/test/gir_ffi/builder_test.rb +0 -5
- data/test/gir_ffi/in_pointer_test.rb +20 -1
- data/test/gir_ffi/info_ext/i_arg_info_test.rb +39 -0
- data/test/gir_ffi/info_ext/i_signal_info_test.rb +51 -0
- data/test/gir_ffi/info_ext/i_type_info_test.rb +20 -20
- data/test/gir_ffi/return_value_builder_test.rb +2 -2
- data/test/gir_ffi/zero_terminated_test.rb +48 -0
- data/test/gir_ffi_test_helper.rb +3 -3
- data/test/integration/generated_gimarshallingtests_test.rb +38 -28
- data/test/integration/generated_regress_test.rb +2 -5
- metadata +11 -5
- data/lib/ffi-gobject/helper.rb +0 -114
- data/test/ffi-gobject/helper_test.rb +0 -103
data/History.txt
CHANGED
@@ -1,3 +1,11 @@
|
|
1
|
+
== 0.5.2 / 2013-04-23
|
2
|
+
|
3
|
+
* Handle signal details in GObject.signal_connect and .signal_emit
|
4
|
+
* Make GValue#set_value check object GType compatibility
|
5
|
+
* Eliminate GObject::Helper module
|
6
|
+
* Handle more argument types
|
7
|
+
* Support Ruby 2.0.0
|
8
|
+
|
1
9
|
== 0.5.1 / 2013-02-01
|
2
10
|
|
3
11
|
* Properly handle zero-terminated arrays of :filename
|
data/lib/ffi-glib/array.rb
CHANGED
data/lib/ffi-glib.rb
CHANGED
@@ -22,24 +22,19 @@ module GLib
|
|
22
22
|
|
23
23
|
attach_function :g_list_append, [:pointer, :pointer], :pointer
|
24
24
|
|
25
|
-
attach_function :g_hash_table_foreach,
|
26
|
-
|
27
|
-
attach_function :
|
28
|
-
[HashFunc, EqualFunc], :pointer
|
29
|
-
attach_function :g_hash_table_insert,
|
30
|
-
[:pointer, :pointer, :pointer], :void
|
25
|
+
attach_function :g_hash_table_foreach, [:pointer, HFunc, :pointer], :void
|
26
|
+
attach_function :g_hash_table_new, [HashFunc, EqualFunc], :pointer
|
27
|
+
attach_function :g_hash_table_insert, [:pointer, :pointer, :pointer], :void
|
31
28
|
|
32
29
|
attach_function :g_byte_array_new, [], :pointer
|
33
|
-
attach_function :g_byte_array_append,
|
34
|
-
[:pointer, :pointer, :uint], :pointer
|
30
|
+
attach_function :g_byte_array_append, [:pointer, :pointer, :uint], :pointer
|
35
31
|
|
36
32
|
attach_function :g_array_new, [:int, :int, :uint], :pointer
|
37
|
-
attach_function :g_array_append_vals,
|
38
|
-
|
33
|
+
attach_function :g_array_append_vals, [:pointer, :pointer, :uint], :pointer
|
34
|
+
attach_function :g_array_get_element_size, [:pointer], :uint
|
39
35
|
|
40
36
|
attach_function :g_ptr_array_new, [], :pointer
|
41
37
|
attach_function :g_ptr_array_add, [:pointer, :pointer], :void
|
42
|
-
attach_function :g_ptr_array_foreach, [:pointer, Func, :pointer],
|
43
|
-
:pointer
|
38
|
+
attach_function :g_ptr_array_foreach, [:pointer, Func, :pointer], :pointer
|
44
39
|
end
|
45
40
|
end
|
data/lib/ffi-gobject/closure.rb
CHANGED
@@ -4,10 +4,7 @@ module GObject
|
|
4
4
|
# Overrides for GClosure, GObject's base class for closure objects.
|
5
5
|
class Closure
|
6
6
|
def set_marshal marshal
|
7
|
-
callback = GirFFI::
|
8
|
-
"ClosureMarshal",
|
9
|
-
marshal)
|
10
|
-
GirFFI::CallbackHelper.store_callback callback
|
7
|
+
callback = GirFFI::Callback.from("GObject", "ClosureMarshal", marshal)
|
11
8
|
Lib.g_closure_set_marshal self, callback
|
12
9
|
end
|
13
10
|
end
|
data/lib/ffi-gobject/object.rb
CHANGED
@@ -14,7 +14,7 @@ module GObject
|
|
14
14
|
|
15
15
|
def get_property_with_override property_name
|
16
16
|
type = get_property_type property_name
|
17
|
-
gvalue =
|
17
|
+
gvalue = type.make_g_value
|
18
18
|
|
19
19
|
get_property_without_override property_name, gvalue
|
20
20
|
|
@@ -23,7 +23,7 @@ module GObject
|
|
23
23
|
|
24
24
|
def set_property_with_override property_name, value
|
25
25
|
type = get_property_type property_name
|
26
|
-
gvalue =
|
26
|
+
gvalue = type.make_g_value
|
27
27
|
|
28
28
|
gvalue.set_value adjust_value_to_type(value, type)
|
29
29
|
|
@@ -2,6 +2,7 @@ module GObject
|
|
2
2
|
|
3
3
|
module RubyStyle
|
4
4
|
|
5
|
+
# TODO: Generate accessor methods from GIR at class definition time
|
5
6
|
def method_missing(method, *args)
|
6
7
|
if respond_to?("get_#{method}")
|
7
8
|
return send("get_#{method}", *args)
|
@@ -12,6 +13,7 @@ module GObject
|
|
12
13
|
super
|
13
14
|
end
|
14
15
|
|
16
|
+
# TODO: Move to definition of GObject::Object
|
15
17
|
def signal_connect(event, &block)
|
16
18
|
GObject.signal_connect(self, event, &block)
|
17
19
|
end
|
data/lib/ffi-gobject/value.rb
CHANGED
@@ -17,7 +17,8 @@ module GObject
|
|
17
17
|
TYPE_STRING => :set_string,
|
18
18
|
TYPE_FLOAT => :set_float,
|
19
19
|
TYPE_DOUBLE => :set_double,
|
20
|
-
|
20
|
+
TYPE_PARAM => :set_param,
|
21
|
+
TYPE_OBJECT => :set_instance_enhanced,
|
21
22
|
TYPE_BOXED => :set_boxed,
|
22
23
|
TYPE_POINTER => :set_pointer,
|
23
24
|
TYPE_ENUM => :set_enum
|
@@ -89,10 +90,27 @@ module GObject
|
|
89
90
|
wrap_ruby_value val
|
90
91
|
end
|
91
92
|
end
|
93
|
+
|
94
|
+
def for_g_type g_type
|
95
|
+
return nil if g_type == TYPE_NONE
|
96
|
+
self.new.tap {|it| it.init g_type }
|
97
|
+
end
|
92
98
|
end
|
93
99
|
|
94
100
|
private
|
95
101
|
|
102
|
+
def set_instance_enhanced val
|
103
|
+
check_type_compatibility val
|
104
|
+
set_instance val
|
105
|
+
end
|
106
|
+
|
107
|
+
def check_type_compatibility val
|
108
|
+
return if val.nil?
|
109
|
+
if !GObject::Value.type_compatible(GObject.type_from_instance(val), current_gtype)
|
110
|
+
raise ArgumentError, "#{val.class} is incompatible with #{current_gtype_name}"
|
111
|
+
end
|
112
|
+
end
|
113
|
+
|
96
114
|
def get_boxed_enhanced
|
97
115
|
boxed = get_boxed
|
98
116
|
case current_gtype
|
data/lib/ffi-gobject.rb
CHANGED
@@ -10,7 +10,6 @@ require 'ffi-gobject/initially_unowned'
|
|
10
10
|
require 'ffi-gobject/closure'
|
11
11
|
require 'ffi-gobject/object'
|
12
12
|
require 'ffi-gobject/ruby_closure'
|
13
|
-
require 'ffi-gobject/helper'
|
14
13
|
require 'gir_ffi/builder/type/user_defined'
|
15
14
|
|
16
15
|
module GObject
|
@@ -60,22 +59,28 @@ module GObject
|
|
60
59
|
signal_lookup signal, type_from_instance(object)
|
61
60
|
end
|
62
61
|
|
63
|
-
def self.signal_emit object,
|
62
|
+
def self.signal_emit object, detailed_signal, *args
|
63
|
+
signal, detail = detailed_signal.split('::')
|
64
|
+
sig_info = object.class.find_signal signal
|
65
|
+
|
64
66
|
id = signal_lookup_from_instance signal, object
|
65
|
-
|
66
|
-
|
67
|
+
detail_quark = GLib.quark_from_string(detail)
|
68
|
+
|
69
|
+
arr = sig_info.signal_arguments_to_gvalue_array object, *args
|
70
|
+
rval = sig_info.gvalue_for_signal_return_value
|
67
71
|
|
68
|
-
Lib.g_signal_emitv arr.values, id,
|
72
|
+
Lib.g_signal_emitv arr.values, id, detail_quark, rval
|
69
73
|
|
70
74
|
return rval
|
71
75
|
end
|
72
76
|
|
73
|
-
def self.signal_connect object,
|
74
|
-
|
77
|
+
def self.signal_connect object, detailed_signal, data=nil, &block
|
78
|
+
signal, _ = detailed_signal.split('::')
|
79
|
+
sig_info = object.class.find_signal signal
|
80
|
+
callback = sig_info.signal_callback(&block)
|
75
81
|
GirFFI::CallbackHelper.store_callback callback
|
76
82
|
data_ptr = GirFFI::ArgHelper.object_to_inptr data
|
77
|
-
|
78
|
-
Lib.g_signal_connect_data object, signal, callback, data_ptr, nil, 0
|
83
|
+
Lib.g_signal_connect_data object, detailed_signal, callback, data_ptr, nil, 0
|
79
84
|
end
|
80
85
|
|
81
86
|
def self.param_spec_int(name, nick, blurb, minimum, maximum,
|
@@ -33,11 +33,11 @@ module GObjectIntrospection
|
|
33
33
|
single ||= method[0..-2]
|
34
34
|
count = method.sub(/^(get_)?/, "\\1n_")
|
35
35
|
self.class_eval <<-CODE
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
36
|
+
def #{method}
|
37
|
+
(0..(#{count} - 1)).map do |i|
|
38
|
+
#{single} i
|
39
|
+
end
|
40
|
+
end
|
41
41
|
CODE
|
42
42
|
end
|
43
43
|
|
@@ -168,7 +168,7 @@ module GObjectIntrospection
|
|
168
168
|
attach_function :g_union_info_find_method, [:pointer, :string], :pointer
|
169
169
|
attach_function :g_union_info_get_size, [:pointer], :int
|
170
170
|
attach_function :g_union_info_get_alignment, [:pointer], :int
|
171
|
-
|
171
|
+
|
172
172
|
# IRegisteredTypeInfo
|
173
173
|
attach_function :g_registered_type_info_get_type_name, [:pointer], :string
|
174
174
|
attach_function :g_registered_type_info_get_type_init, [:pointer], :string
|
data/lib/gir_ffi/arg_helper.rb
CHANGED
@@ -17,8 +17,8 @@ module GirFFI
|
|
17
17
|
# FIXME: Hideous
|
18
18
|
# TODO: Move this implementation to InPointer
|
19
19
|
def self.object_to_inptr obj
|
20
|
-
return obj.to_ptr if obj.respond_to? :to_ptr
|
21
20
|
return nil if obj.nil?
|
21
|
+
return obj.to_ptr if obj.respond_to? :to_ptr
|
22
22
|
return obj if obj.is_a? FFI::Pointer
|
23
23
|
|
24
24
|
FFI::Pointer.new(obj.object_id).tap {|ptr|
|
@@ -96,12 +96,12 @@ module GirFFI
|
|
96
96
|
|
97
97
|
def self.check_error errpp
|
98
98
|
err = GLib::Error.wrap(errpp.read_pointer)
|
99
|
-
raise err.message
|
99
|
+
raise err.message if err
|
100
100
|
end
|
101
101
|
|
102
102
|
def self.check_fixed_array_size size, arr, name
|
103
103
|
unless arr.size == size
|
104
|
-
|
104
|
+
raise ArgumentError, "#{name} should have size #{size}"
|
105
105
|
end
|
106
106
|
end
|
107
107
|
|
@@ -31,29 +31,33 @@ module GirFFI
|
|
31
31
|
end
|
32
32
|
|
33
33
|
def post
|
34
|
-
result = []
|
35
34
|
if has_output_value?
|
36
|
-
value =
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
when :enum, :flags
|
41
|
-
"#{argument_class_name}[#{output_conversion_arguments}]"
|
42
|
-
else
|
43
|
-
"#{argument_class_name}.wrap(#{output_conversion_arguments})"
|
44
|
-
end
|
45
|
-
elsif is_fixed_length_array?
|
46
|
-
"#{callarg}.to_sized_array_value #{array_size}"
|
47
|
-
else
|
48
|
-
"#{callarg}.to_value"
|
49
|
-
end
|
50
|
-
result << "#{retname} = #{value}"
|
35
|
+
value = output_value
|
36
|
+
["#{retname} = #{value}"]
|
37
|
+
else
|
38
|
+
[]
|
51
39
|
end
|
52
|
-
result
|
53
40
|
end
|
54
41
|
|
55
42
|
private
|
56
43
|
|
44
|
+
def output_value
|
45
|
+
if is_caller_allocated_object?
|
46
|
+
callarg
|
47
|
+
elsif needs_outgoing_parameter_conversion?
|
48
|
+
case specialized_type_tag
|
49
|
+
when :enum, :flags
|
50
|
+
"#{argument_class_name}[#{output_conversion_arguments}]"
|
51
|
+
else
|
52
|
+
"#{argument_class_name}.wrap(#{output_conversion_arguments})"
|
53
|
+
end
|
54
|
+
elsif is_fixed_length_array?
|
55
|
+
"#{callarg}.to_sized_array_value #{array_size}"
|
56
|
+
else
|
57
|
+
"#{callarg}.to_value"
|
58
|
+
end
|
59
|
+
end
|
60
|
+
|
57
61
|
def is_array_length_parameter?
|
58
62
|
@array_arg
|
59
63
|
end
|
@@ -68,8 +68,10 @@ module GirFFI
|
|
68
68
|
'GLib::PtrArray'
|
69
69
|
when :strv
|
70
70
|
'GLib::Strv'
|
71
|
-
when :c
|
71
|
+
when :c
|
72
72
|
'GirFFI::InPointer'
|
73
|
+
when :zero_terminated
|
74
|
+
'GirFFI::ZeroTerminated'
|
73
75
|
else
|
74
76
|
TAG_TO_WRAPPER_CLASS_MAP[tag]
|
75
77
|
end
|
@@ -129,9 +131,9 @@ module GirFFI
|
|
129
131
|
case specialized_type_tag
|
130
132
|
when :utf8, :void
|
131
133
|
"#{self_t}, #{name}"
|
132
|
-
when :glist, :gslist, :ghash, :array
|
134
|
+
when :glist, :gslist, :ghash, :array, :zero_terminated
|
133
135
|
"#{elm_t}, #{name}"
|
134
|
-
when :c
|
136
|
+
when :c
|
135
137
|
"#{type_specification}, #{name}"
|
136
138
|
when :callback
|
137
139
|
iface = type_info.interface
|
@@ -30,10 +30,9 @@ module GirFFI
|
|
30
30
|
type_info.instance_size += FFI.type_size(:int32)
|
31
31
|
end
|
32
32
|
|
33
|
-
|
33
|
+
@gtype = GObject.type_register_static(parent_type, @klass.name,
|
34
|
+
type_info, 0)
|
34
35
|
|
35
|
-
# TODO: Check that class ultimately derives from GObject.
|
36
|
-
@gtype = new_type
|
37
36
|
@structklass = get_or_define_class @klass, :Struct, layout_superclass
|
38
37
|
setup_class unless already_set_up
|
39
38
|
CACHE[@gtype] = @klass
|
data/lib/gir_ffi/builder.rb
CHANGED
@@ -52,8 +52,8 @@ module GirFFI
|
|
52
52
|
types = info.args.map { |arg| iarginfo_to_ffitype arg }
|
53
53
|
|
54
54
|
if info.info_type == :function
|
55
|
-
|
56
|
-
|
55
|
+
types.unshift :pointer if info.method?
|
56
|
+
types << :pointer if info.throws?
|
57
57
|
end
|
58
58
|
|
59
59
|
types
|
@@ -8,13 +8,13 @@ module GirFFI
|
|
8
8
|
return nil if prc.nil?
|
9
9
|
info = GObjectIntrospection::IRepository.default.find_by_name namespace, name
|
10
10
|
return Callback.new do |*args|
|
11
|
-
|
11
|
+
prc.call(*map_callback_args(args, info))
|
12
12
|
end
|
13
13
|
end
|
14
14
|
|
15
15
|
def self.map_callback_args args, info
|
16
16
|
args.zip(info.args).map { |arg, inf|
|
17
|
-
|
17
|
+
map_single_callback_arg arg, inf.argument_type }
|
18
18
|
end
|
19
19
|
|
20
20
|
# TODO: Use GirFFI::ReturnValue classes for mapping.
|
@@ -23,18 +23,18 @@ module GirFFI
|
|
23
23
|
when :interface
|
24
24
|
map_interface_callback_arg arg, type
|
25
25
|
when :utf8
|
26
|
-
|
26
|
+
ArgHelper.ptr_to_utf8 arg
|
27
27
|
when :void
|
28
28
|
map_void_callback_arg arg
|
29
29
|
when :array
|
30
|
-
|
30
|
+
subtype = type.param_type(0)
|
31
31
|
if subtype.tag == :interface and arg.is_a?(FFI::Pointer)
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
32
|
+
map_interface_callback_arg arg, subtype
|
33
|
+
else
|
34
|
+
raise NotImplementedError
|
35
|
+
end
|
36
36
|
else
|
37
|
-
|
37
|
+
arg
|
38
38
|
end
|
39
39
|
end
|
40
40
|
|
@@ -22,9 +22,9 @@ module GirFFI
|
|
22
22
|
alldata = @data.dup << @rvdata
|
23
23
|
|
24
24
|
alldata.each {|data|
|
25
|
-
|
25
|
+
idx = data.type_info.array_length
|
26
26
|
if idx > -1
|
27
|
-
data.length_arg = @data[idx]
|
27
|
+
data.length_arg = @data[idx]
|
28
28
|
@data[idx].array_arg = data
|
29
29
|
end
|
30
30
|
}
|
@@ -57,15 +57,13 @@ module GirFFI
|
|
57
57
|
private
|
58
58
|
|
59
59
|
def adjust_value_in value
|
60
|
-
return nil_value if value.nil?
|
61
|
-
|
62
60
|
case @value_type
|
63
61
|
when :gboolean
|
64
62
|
(value ? 1 : 0)
|
65
63
|
when :utf8
|
66
64
|
InPointer.from :utf8, value
|
67
65
|
else
|
68
|
-
value
|
66
|
+
value || nil_value
|
69
67
|
end
|
70
68
|
end
|
71
69
|
|
data/lib/gir_ffi/in_pointer.rb
CHANGED
@@ -10,8 +10,14 @@ module GirFFI
|
|
10
10
|
from_utf8_array ary
|
11
11
|
when :interface_pointer
|
12
12
|
from_interface_pointer_array ary
|
13
|
-
|
13
|
+
when Symbol
|
14
14
|
from_basic_type_array type, ary
|
15
|
+
when FFI::Enum
|
16
|
+
from_enum_array type, ary
|
17
|
+
when Array
|
18
|
+
from_interface_pointer_array ary
|
19
|
+
else
|
20
|
+
raise NotImplementedError, type
|
15
21
|
end
|
16
22
|
end
|
17
23
|
|
@@ -49,6 +55,10 @@ module GirFFI
|
|
49
55
|
self.from_array :pointer, ptr_ary
|
50
56
|
end
|
51
57
|
|
58
|
+
def from_enum_array type, ary
|
59
|
+
self.from_array :int32, ary.map {|sym| type.to_native sym, nil }
|
60
|
+
end
|
61
|
+
|
52
62
|
def from_utf8 str
|
53
63
|
len = str.bytesize
|
54
64
|
ptr = AllocationHelper.safe_malloc(len + 1).write_string(str).put_char(len, 0)
|
@@ -57,8 +67,11 @@ module GirFFI
|
|
57
67
|
|
58
68
|
def from_basic_type_array type, ary
|
59
69
|
ffi_type = TypeMap.map_basic_type type
|
60
|
-
block = ArgHelper.allocate_array_of_type ffi_type, ary.length
|
70
|
+
block = ArgHelper.allocate_array_of_type ffi_type, ary.length + 1
|
61
71
|
block.send "put_array_of_#{ffi_type}", 0, ary
|
72
|
+
block.send("put_#{ffi_type}",
|
73
|
+
ary.length * FFI.type_size(ffi_type),
|
74
|
+
(ffi_type == :pointer ? nil : 0))
|
62
75
|
|
63
76
|
self.new block
|
64
77
|
end
|
@@ -0,0 +1,27 @@
|
|
1
|
+
module GirFFI
|
2
|
+
module InfoExt
|
3
|
+
# Extensions for GObjectIntrospection::IArgInfo needed by GirFFI
|
4
|
+
module IArgInfo
|
5
|
+
def cast_signal_argument arg
|
6
|
+
arg_t = self.argument_type
|
7
|
+
if arg_t.tag == :interface
|
8
|
+
iface = arg_t.interface
|
9
|
+
kls = GirFFI::Builder.build_class iface
|
10
|
+
case iface.info_type
|
11
|
+
when :enum, :flags
|
12
|
+
kls[arg]
|
13
|
+
when :interface
|
14
|
+
arg.to_object
|
15
|
+
else
|
16
|
+
kls.wrap(arg)
|
17
|
+
end
|
18
|
+
else
|
19
|
+
arg
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
GObjectIntrospection::IArgInfo.send :include, GirFFI::InfoExt::IArgInfo
|
27
|
+
|
@@ -0,0 +1,65 @@
|
|
1
|
+
module GirFFI
|
2
|
+
module InfoExt
|
3
|
+
# Extensions for GObjectIntrospection::ISignalInfo needed by GirFFI
|
4
|
+
module ISignalInfo
|
5
|
+
# Create a signal hander callback. Wraps the given block in such a way that
|
6
|
+
# arguments and return value are cast correctly to the ruby world and back.
|
7
|
+
#
|
8
|
+
# @param block The body of the signal handler
|
9
|
+
#
|
10
|
+
# @return [FFI::Function] The signal handler, ready to be passed as a
|
11
|
+
# callback to C.
|
12
|
+
def signal_callback &block
|
13
|
+
GirFFI::Builder.build_callback self, &signal_callback_args(&block)
|
14
|
+
end
|
15
|
+
|
16
|
+
# TODO: Generate cast back methods using existing Argument builders.
|
17
|
+
def cast_back_signal_arguments *arguments
|
18
|
+
instance = GirFFI::ArgHelper.object_pointer_to_object arguments.shift
|
19
|
+
user_data = GirFFI::ArgHelper::OBJECT_STORE[arguments.pop.address]
|
20
|
+
|
21
|
+
extra_arguments = self.args.zip(arguments).map do |info, arg|
|
22
|
+
info.cast_signal_argument(arg)
|
23
|
+
end
|
24
|
+
|
25
|
+
return [instance, *extra_arguments].push user_data
|
26
|
+
end
|
27
|
+
|
28
|
+
def signal_callback_args &block
|
29
|
+
raise ArgumentError, "Block needed" unless block
|
30
|
+
return Proc.new do |*args|
|
31
|
+
mapped = cast_back_signal_arguments(*args)
|
32
|
+
block.call(*mapped)
|
33
|
+
end
|
34
|
+
end
|
35
|
+
|
36
|
+
def signal_arguments_to_gvalue_array instance, *rest
|
37
|
+
arr = ::GObject::ValueArray.new self.n_args + 1
|
38
|
+
|
39
|
+
arr.append signal_reciever_to_gvalue instance
|
40
|
+
|
41
|
+
self.args.zip(rest).each do |info, arg|
|
42
|
+
arr.append info.argument_type.make_g_value.set_value(arg)
|
43
|
+
end
|
44
|
+
|
45
|
+
arr
|
46
|
+
end
|
47
|
+
|
48
|
+
def gvalue_for_signal_return_value
|
49
|
+
GObject::Value.for_g_type return_type.g_type
|
50
|
+
end
|
51
|
+
|
52
|
+
private
|
53
|
+
|
54
|
+
def signal_reciever_to_gvalue instance
|
55
|
+
val = ::GObject::Value.new
|
56
|
+
val.init ::GObject.type_from_instance instance
|
57
|
+
val.set_instance instance
|
58
|
+
return val
|
59
|
+
end
|
60
|
+
|
61
|
+
end
|
62
|
+
end
|
63
|
+
end
|
64
|
+
|
65
|
+
GObjectIntrospection::ISignalInfo.send :include, GirFFI::InfoExt::ISignalInfo
|
@@ -2,9 +2,24 @@ require 'gir_ffi/builder_helper'
|
|
2
2
|
|
3
3
|
module GirFFI
|
4
4
|
module InfoExt
|
5
|
+
# Extensions for GObjectIntrospection::IArgInfo needed by GirFFI
|
5
6
|
module ITypeInfo
|
6
7
|
include BuilderHelper
|
7
8
|
|
9
|
+
def g_type
|
10
|
+
tag = self.tag
|
11
|
+
case tag
|
12
|
+
when :interface
|
13
|
+
interface.g_type
|
14
|
+
else
|
15
|
+
GObject::TYPE_TAG_TO_GTYPE[tag]
|
16
|
+
end
|
17
|
+
end
|
18
|
+
|
19
|
+
def make_g_value
|
20
|
+
GObject::Value.for_g_type g_type
|
21
|
+
end
|
22
|
+
|
8
23
|
def layout_specification_type
|
9
24
|
ffitype = GirFFI::Builder.itypeinfo_to_ffitype self
|
10
25
|
case ffitype
|
data/lib/gir_ffi/info_ext.rb
CHANGED
@@ -1,6 +1,8 @@
|
|
1
1
|
require 'gir_ffi/info_ext/safe_constant_name'
|
2
2
|
require 'gir_ffi/info_ext/safe_function_name'
|
3
|
+
require 'gir_ffi/info_ext/i_arg_info'
|
3
4
|
require 'gir_ffi/info_ext/i_field_info'
|
4
5
|
require 'gir_ffi/info_ext/i_property_info'
|
6
|
+
require 'gir_ffi/info_ext/i_signal_info'
|
5
7
|
require 'gir_ffi/info_ext/i_registered_type_info'
|
6
8
|
require 'gir_ffi/info_ext/i_type_info'
|