gir_ffi 0.5.1 → 0.5.2
Sign up to get free protection for your applications and to get access to all the features.
- 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'
|