gir_ffi 0.1.0 → 0.2.0
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 +14 -0
- data/TODO.rdoc +10 -5
- data/lib/ffi-glib.rb +7 -73
- data/lib/ffi-glib/array.rb +29 -4
- data/lib/ffi-glib/byte_array.rb +15 -1
- data/lib/ffi-glib/hash_table.rb +31 -24
- data/lib/ffi-glib/list.rb +28 -0
- data/lib/ffi-glib/list_methods.rb +10 -2
- data/lib/ffi-glib/ptr_array.rb +39 -0
- data/lib/ffi-glib/s_list.rb +29 -0
- data/lib/ffi-gobject.rb +49 -22
- data/lib/ffi-gobject/closure.rb +4 -3
- data/lib/ffi-gobject/helper.rb +20 -43
- data/lib/ffi-gobject/initially_unowned.rb +2 -0
- data/lib/ffi-gobject/object.rb +54 -0
- data/lib/ffi-gobject/ruby_closure.rb +22 -16
- data/lib/ffi-gobject/value.rb +54 -19
- data/lib/ffi-gobject_introspection/i_constant_info.rb +17 -1
- data/lib/ffi-gobject_introspection/i_field_info.rb +8 -0
- data/lib/ffi-gobject_introspection/i_property_info.rb +3 -1
- data/lib/ffi-gobject_introspection/lib.rb +19 -2
- data/lib/gir_ffi/arg_helper.rb +7 -45
- data/lib/gir_ffi/builder.rb +1 -1
- data/lib/gir_ffi/builder/argument.rb +148 -107
- data/lib/gir_ffi/builder/argument/base.rb +5 -5
- data/lib/gir_ffi/builder/argument/in_base.rb +2 -2
- data/lib/gir_ffi/builder/argument/in_out_base.rb +2 -3
- data/lib/gir_ffi/builder/argument/out_base.rb +2 -3
- data/lib/gir_ffi/builder/function.rb +11 -17
- data/lib/gir_ffi/builder/module.rb +26 -0
- data/lib/gir_ffi/builder/type.rb +5 -0
- data/lib/gir_ffi/builder/type/base.rb +2 -0
- data/lib/gir_ffi/builder/type/callback.rb +18 -3
- data/lib/gir_ffi/builder/type/constant.rb +4 -12
- data/lib/gir_ffi/builder/type/enum.rb +15 -6
- data/lib/gir_ffi/builder/type/interface.rb +4 -0
- data/lib/gir_ffi/builder/type/object.rb +11 -0
- data/lib/gir_ffi/builder/type/struct_based.rb +14 -4
- data/lib/gir_ffi/builder/type/union.rb +13 -7
- data/lib/gir_ffi/builder/type/with_layout.rb +59 -8
- data/lib/gir_ffi/class_base.rb +8 -1
- data/lib/gir_ffi/in_out_pointer.rb +17 -18
- data/lib/gir_ffi/in_pointer.rb +8 -1
- data/lib/gir_ffi/type_map.rb +12 -0
- data/lib/gir_ffi/variable_name_generator.rb +12 -0
- data/lib/gir_ffi/version.rb +1 -1
- data/test/ffi-glib/array_test.rb +54 -0
- data/test/ffi-glib/byte_array_test.rb +21 -0
- data/test/ffi-glib/glib_overrides_test.rb +1 -46
- data/test/ffi-glib/hash_table_test.rb +24 -0
- data/test/ffi-glib/list_test.rb +46 -0
- data/test/ffi-glib/ptr_array_test.rb +51 -0
- data/test/ffi-glib/s_list_test.rb +46 -0
- data/test/ffi-gobject/g_object_overrides_test.rb +8 -8
- data/test/ffi-gobject/gobject_test.rb +26 -0
- data/test/ffi-gobject/object_test.rb +12 -0
- data/test/ffi-gobject_introspection/i_constant_info_test.rb +5 -1
- data/test/ffi-gobject_introspection/lib_test.rb +56 -0
- data/test/integration/generated_gimarshallingtests_test.rb +118 -76
- data/test/integration/generated_regress_test.rb +220 -62
- data/test/integration/pretty_print_test.rb +11 -0
- data/test/type_builder_test.rb +0 -48
- data/test/unintrospectable_type_builder_test.rb +8 -2
- data/test/unit/builder_test.rb +1 -1
- data/test/unit/callback_builder_test.rb +19 -0
- data/test/unit/constant_builder_test.rb +11 -0
- data/test/unit/enum_builder_test.rb +25 -0
- data/test/unit/function_builder_test.rb +17 -0
- data/test/unit/in_out_pointer_test.rb +11 -0
- data/test/unit/in_pointer_test.rb +6 -2
- data/test/unit/interface_builder_test.rb +17 -0
- data/test/unit/module_builder_test.rb +95 -0
- data/test/unit/object_type_builder_test.rb +24 -0
- data/test/unit/struct_builder_test.rb +106 -0
- data/test/unit/union_builder_test.rb +17 -0
- data/test/unit/variable_name_generator_test.rb +16 -0
- metadata +102 -75
- data/test/module_builder_test.rb +0 -53
data/lib/ffi-gobject/closure.rb
CHANGED
@@ -1,12 +1,13 @@
|
|
1
1
|
module GObject
|
2
2
|
load_class :Closure
|
3
3
|
|
4
|
+
# Overrides for GClosure, GObject's base class for closure objects.
|
4
5
|
class Closure
|
5
6
|
def set_marshal marshal
|
6
|
-
|
7
|
+
callback = GirFFI::CallbackHelper.wrap_in_callback_args_mapper(
|
7
8
|
"GObject", "ClosureMarshal", marshal)
|
8
|
-
|
9
|
-
|
9
|
+
Lib::CALLBACKS << callback
|
10
|
+
Lib.g_closure_set_marshal self, callback
|
10
11
|
end
|
11
12
|
end
|
12
13
|
end
|
data/lib/ffi-gobject/helper.rb
CHANGED
@@ -1,12 +1,17 @@
|
|
1
1
|
module GObject
|
2
2
|
module Helper
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
3
|
+
def self.signal_callback klass, signal, &block
|
4
|
+
sig = klass._find_signal signal
|
5
|
+
|
6
|
+
rettype = GirFFI::Builder.itypeinfo_to_ffitype sig.return_type
|
7
|
+
argtypes = GirFFI::Builder.ffi_argument_types_for_signal sig
|
8
|
+
callback_block = Helper.signal_callback_args(sig, klass, &block)
|
9
|
+
|
10
|
+
FFI::Function.new rettype, argtypes, &callback_block
|
11
|
+
end
|
8
12
|
|
9
13
|
def self.signal_callback_args sig, klass, &block
|
14
|
+
raise ArgumentError, "Block needed" if block.nil?
|
10
15
|
return Proc.new do |*args|
|
11
16
|
mapped = cast_back_signal_arguments sig, klass, *args
|
12
17
|
block.call(*mapped)
|
@@ -35,27 +40,8 @@ module GObject
|
|
35
40
|
end
|
36
41
|
|
37
42
|
def self.signal_argument_to_gvalue info, arg
|
38
|
-
|
39
|
-
|
40
|
-
val = gvalue_for_type_info arg_type
|
41
|
-
|
42
|
-
if arg_type.tag == :interface
|
43
|
-
interface = arg_type.interface
|
44
|
-
case interface.info_type
|
45
|
-
when :struct
|
46
|
-
val.set_boxed arg
|
47
|
-
when :object
|
48
|
-
val.set_instance arg
|
49
|
-
when :enum
|
50
|
-
val.set_enum arg
|
51
|
-
else
|
52
|
-
raise NotImplementedError, interface.info_type
|
53
|
-
end
|
54
|
-
else
|
55
|
-
val.set_ruby_value arg
|
56
|
-
end
|
57
|
-
|
58
|
-
return val
|
43
|
+
val = gvalue_for_type_info info.argument_type
|
44
|
+
val.set_value arg
|
59
45
|
end
|
60
46
|
|
61
47
|
def self.gvalue_for_type_info info
|
@@ -66,9 +52,10 @@ module GObject
|
|
66
52
|
when :void
|
67
53
|
return nil
|
68
54
|
else
|
69
|
-
|
55
|
+
TYPE_TAG_TO_GTYPE[tag]
|
70
56
|
end
|
71
|
-
|
57
|
+
raise "GType not found for type info with tag #{tag}" unless gtype
|
58
|
+
Value.new.tap {|val| val.init gtype}
|
72
59
|
end
|
73
60
|
|
74
61
|
def self.gvalue_for_signal_return_value signal, object
|
@@ -80,24 +67,14 @@ module GObject
|
|
80
67
|
|
81
68
|
# TODO: Generate cast back methods using existing Argument builders.
|
82
69
|
def self.cast_back_signal_arguments signalinfo, klass, *args
|
83
|
-
|
70
|
+
instance = klass.wrap args.shift
|
71
|
+
user_data = GirFFI::ArgHelper::OBJECT_STORE[args.pop.address]
|
84
72
|
|
85
|
-
|
86
|
-
|
87
|
-
instance = klass.wrap instptr
|
88
|
-
result << instance
|
89
|
-
|
90
|
-
# Extra arguments
|
91
|
-
signalinfo.args.each do |info|
|
92
|
-
result << cast_signal_argument(info, args.shift)
|
73
|
+
extra_arguments = signalinfo.args.zip(args).map do |info, arg|
|
74
|
+
cast_signal_argument(info, arg)
|
93
75
|
end
|
94
76
|
|
95
|
-
|
96
|
-
arg = args.shift
|
97
|
-
arg = GirFFI::ArgHelper::OBJECT_STORE[arg.address]
|
98
|
-
result << arg
|
99
|
-
|
100
|
-
return result
|
77
|
+
return [instance, *extra_arguments].push user_data
|
101
78
|
end
|
102
79
|
|
103
80
|
def self.cast_signal_argument info, arg
|
@@ -1,6 +1,8 @@
|
|
1
1
|
module GObject
|
2
2
|
load_class :InitiallyUnowned
|
3
3
|
|
4
|
+
# Overrides for GInitiallyUnowned, GObject's base class for objects that
|
5
|
+
# start with a floating reference.
|
4
6
|
class InitiallyUnowned
|
5
7
|
def self.constructor_wrap ptr
|
6
8
|
super.tap {|obj| ::GObject.object_ref_sink obj}
|
@@ -0,0 +1,54 @@
|
|
1
|
+
module GObject
|
2
|
+
load_class :Object
|
3
|
+
|
4
|
+
# Overrides for GObject, GObject's generic base class.
|
5
|
+
class Object
|
6
|
+
_setup_instance_method "get_property"
|
7
|
+
_setup_instance_method "set_property"
|
8
|
+
|
9
|
+
def get_property_with_override property_name
|
10
|
+
prop = self.class._find_property property_name
|
11
|
+
type = prop.property_type
|
12
|
+
v = Helper.gvalue_for_type_info type
|
13
|
+
get_property_without_override property_name, v
|
14
|
+
|
15
|
+
val = v.ruby_value
|
16
|
+
case type.tag
|
17
|
+
when :ghash
|
18
|
+
GLib::HashTable.wrap type.param_type(0).tag, type.param_type(1).tag,
|
19
|
+
val.to_ptr
|
20
|
+
when :glist
|
21
|
+
GLib::List.wrap type.param_type(0).tag, val
|
22
|
+
else
|
23
|
+
val
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
def set_property_with_override property_name, value
|
28
|
+
prop = self.class._find_property property_name
|
29
|
+
type = prop.property_type
|
30
|
+
v = Helper.gvalue_for_type_info type
|
31
|
+
|
32
|
+
case type.tag
|
33
|
+
when :glist
|
34
|
+
lst = GLib::List.from_array type.param_type(0).tag, value
|
35
|
+
v.set_value lst.to_ptr
|
36
|
+
when :ghash
|
37
|
+
hsh = GLib::HashTable.from_hash type.param_type(0).tag,
|
38
|
+
type.param_type(1).tag, value
|
39
|
+
v.set_value hsh.to_ptr
|
40
|
+
else
|
41
|
+
v.set_value value
|
42
|
+
end
|
43
|
+
|
44
|
+
set_property_without_override property_name, v
|
45
|
+
end
|
46
|
+
|
47
|
+
alias get_property_without_override get_property
|
48
|
+
alias get_property get_property_with_override
|
49
|
+
|
50
|
+
alias set_property_without_override set_property
|
51
|
+
alias set_property set_property_with_override
|
52
|
+
end
|
53
|
+
end
|
54
|
+
|
@@ -6,13 +6,21 @@ module GObject
|
|
6
6
|
class RubyClosure < Closure
|
7
7
|
BLOCK_STORE = {}
|
8
8
|
|
9
|
+
# Extend the standard GClosure layout with a field block_id to store
|
10
|
+
# the object_id of the associated block.
|
9
11
|
class Struct < FFI::Struct
|
10
12
|
layout :parent, Closure::Struct, 0,
|
11
|
-
:
|
13
|
+
:block_id, :int64
|
12
14
|
end
|
13
15
|
|
14
16
|
def block
|
15
|
-
|
17
|
+
BLOCK_STORE[@struct[:block_id]]
|
18
|
+
end
|
19
|
+
|
20
|
+
def block= block
|
21
|
+
id = block.object_id
|
22
|
+
BLOCK_STORE[id] = block
|
23
|
+
@struct[:block_id] = id
|
16
24
|
end
|
17
25
|
|
18
26
|
def invoke_block *args
|
@@ -21,27 +29,25 @@ module GObject
|
|
21
29
|
|
22
30
|
def self.new &block
|
23
31
|
raise ArgumentError unless block_given?
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
32
|
+
|
33
|
+
closure = wrap(new_simple(self::Struct.size, nil).to_ptr)
|
34
|
+
closure.block = block
|
35
|
+
closure.set_marshal Proc.new {|*args| marshaller(*args)}
|
36
|
+
|
37
|
+
return closure
|
30
38
|
end
|
31
39
|
|
32
40
|
def self.marshaller(closure, return_value, n_param_values,
|
33
41
|
param_values, invocation_hint, marshal_data)
|
34
|
-
rclosure =
|
42
|
+
rclosure = wrap(closure.to_ptr)
|
35
43
|
|
36
|
-
args =
|
37
|
-
|
38
|
-
gv = ::GObject::Value.wrap(param_values.to_ptr +
|
39
|
-
i * ::GObject::Value::Struct.size)
|
40
|
-
args << gv.ruby_value
|
44
|
+
args = n_param_values.times.map {|idx|
|
45
|
+
Value.wrap(param_values.to_ptr + idx * Value::Struct.size).ruby_value
|
41
46
|
}
|
42
47
|
|
43
|
-
|
44
|
-
|
48
|
+
result = rclosure.invoke_block(*args)
|
49
|
+
|
50
|
+
return_value.set_ruby_value(result) unless return_value.nil?
|
45
51
|
end
|
46
52
|
end
|
47
53
|
end
|
data/lib/ffi-gobject/value.rb
CHANGED
@@ -1,21 +1,38 @@
|
|
1
1
|
module GObject
|
2
2
|
load_class :Value
|
3
3
|
|
4
|
+
# Overrides for GValue, GObject's generic value container structure.
|
4
5
|
class Value
|
5
6
|
def set_ruby_value val
|
6
7
|
if current_gtype == 0
|
7
8
|
init_for_ruby_value val
|
8
9
|
end
|
9
10
|
|
10
|
-
|
11
|
-
|
11
|
+
set_value val
|
12
|
+
end
|
13
|
+
|
14
|
+
def set_value val
|
15
|
+
case current_fundamental_type
|
16
|
+
when TYPE_BOOLEAN
|
12
17
|
set_boolean val
|
13
|
-
when
|
18
|
+
when TYPE_INT
|
14
19
|
set_int val
|
15
|
-
when
|
20
|
+
when TYPE_STRING
|
16
21
|
set_string val
|
22
|
+
when TYPE_FLOAT
|
23
|
+
set_float val
|
24
|
+
when TYPE_DOUBLE
|
25
|
+
set_double val
|
26
|
+
when TYPE_BOXED
|
27
|
+
set_boxed val
|
28
|
+
when TYPE_OBJECT
|
29
|
+
set_instance val
|
30
|
+
when TYPE_POINTER
|
31
|
+
set_pointer val
|
32
|
+
when TYPE_ENUM
|
33
|
+
set_enum val
|
17
34
|
else
|
18
|
-
|
35
|
+
raise "Don't know how to handle #{current_gtype_name}"
|
19
36
|
end
|
20
37
|
self
|
21
38
|
end
|
@@ -23,36 +40,54 @@ module GObject
|
|
23
40
|
def init_for_ruby_value val
|
24
41
|
case val
|
25
42
|
when true, false
|
26
|
-
init
|
43
|
+
init TYPE_BOOLEAN
|
27
44
|
when Integer
|
28
|
-
init
|
45
|
+
init TYPE_INT
|
29
46
|
end
|
30
47
|
self
|
31
48
|
end
|
32
49
|
|
33
50
|
def current_gtype
|
34
|
-
|
51
|
+
@struct[:g_type]
|
52
|
+
end
|
53
|
+
|
54
|
+
def current_fundamental_type
|
55
|
+
GObject.type_fundamental current_gtype
|
35
56
|
end
|
36
57
|
|
37
58
|
def current_gtype_name
|
38
|
-
|
59
|
+
GObject.type_name current_gtype
|
39
60
|
end
|
40
61
|
|
41
62
|
def ruby_value
|
42
|
-
case
|
43
|
-
when
|
63
|
+
case current_fundamental_type
|
64
|
+
when TYPE_BOOLEAN
|
44
65
|
get_boolean
|
45
|
-
when
|
66
|
+
when TYPE_INT
|
46
67
|
get_int
|
47
|
-
when
|
68
|
+
when TYPE_STRING
|
48
69
|
get_string
|
49
|
-
when
|
50
|
-
|
51
|
-
when
|
52
|
-
|
53
|
-
|
70
|
+
when TYPE_FLOAT
|
71
|
+
get_float
|
72
|
+
when TYPE_DOUBLE
|
73
|
+
get_double
|
74
|
+
when TYPE_OBJECT
|
75
|
+
get_object
|
76
|
+
when TYPE_BOXED
|
77
|
+
boxed = get_boxed
|
78
|
+
case current_gtype_name.to_sym
|
79
|
+
when :GStrv
|
80
|
+
# FIXME: Extract this method to even lower level module.
|
81
|
+
GirFFI::ArgHelper.strv_to_utf8_array boxed
|
82
|
+
when :GHashTable
|
83
|
+
GLib::HashTable.wrap :gpointer, :gpointer, boxed
|
84
|
+
else
|
85
|
+
GirFFI::ArgHelper.wrap_object_pointer_by_gtype boxed, current_gtype
|
86
|
+
end
|
87
|
+
when TYPE_POINTER
|
88
|
+
get_pointer
|
54
89
|
else
|
55
|
-
|
90
|
+
raise "Don't know how to handle #{current_gtype_name}"
|
56
91
|
end
|
57
92
|
end
|
58
93
|
|
@@ -1,12 +1,28 @@
|
|
1
1
|
module GObjectIntrospection
|
2
2
|
# Wraps a GIConstantInfo struct; represents an constant.
|
3
3
|
class IConstantInfo < IBaseInfo
|
4
|
-
|
4
|
+
TYPE_TAG_TO_UNION_MEMBER = {
|
5
|
+
:gint32 => :v_int32,
|
6
|
+
:gdouble => :v_double,
|
7
|
+
:utf8 => :v_string
|
8
|
+
}
|
9
|
+
|
10
|
+
def value_union
|
5
11
|
val = Lib::GIArgument.new
|
6
12
|
Lib.g_constant_info_get_value @gobj, val
|
7
13
|
return val
|
8
14
|
end
|
9
15
|
|
16
|
+
def value
|
17
|
+
tag = constant_type.tag
|
18
|
+
val = value_union[TYPE_TAG_TO_UNION_MEMBER[tag]]
|
19
|
+
if RUBY_VERSION >= "1.9" and tag == :utf8
|
20
|
+
val.force_encoding("utf-8")
|
21
|
+
else
|
22
|
+
val
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
10
26
|
def constant_type
|
11
27
|
ITypeInfo.wrap(Lib.g_constant_info_get_type @gobj)
|
12
28
|
end
|
@@ -1,7 +1,9 @@
|
|
1
1
|
module GObjectIntrospection
|
2
2
|
# Wraps a GIPropertyInfo struct.
|
3
3
|
# Represents a property of an IObjectInfo or an IInterfaceInfo.
|
4
|
-
# Not implemented yet.
|
5
4
|
class IPropertyInfo < IBaseInfo
|
5
|
+
def property_type
|
6
|
+
ITypeInfo.wrap(Lib.g_property_info_get_type @gobj)
|
7
|
+
end
|
6
8
|
end
|
7
9
|
end
|
@@ -3,7 +3,19 @@ require 'ffi'
|
|
3
3
|
module GObjectIntrospection
|
4
4
|
module Lib
|
5
5
|
extend FFI::Library
|
6
|
-
|
6
|
+
begin
|
7
|
+
ffi_lib "girepository-1.0.so.1"
|
8
|
+
rescue LoadError
|
9
|
+
begin
|
10
|
+
ffi_lib "girepository-1.0.so.0"
|
11
|
+
warn "This old version of gobject-introspection is not supported by GirFFI."
|
12
|
+
warn "Please upgrade to at least version 0.10.0."
|
13
|
+
rescue LoadError
|
14
|
+
ffi_lib "girepository-1.0"
|
15
|
+
warn "This platform and/or version of gobject-introspection are not supported by GirFFI."
|
16
|
+
warn "Please file bugs for any errors found."
|
17
|
+
end
|
18
|
+
end
|
7
19
|
|
8
20
|
# IRepository
|
9
21
|
enum :IRepositoryLoadFlags, [:LAZY, (1<<0)]
|
@@ -148,7 +160,8 @@ module GObjectIntrospection
|
|
148
160
|
:readable, (1 << 0),
|
149
161
|
:writable, (1 << 1)
|
150
162
|
]
|
151
|
-
|
163
|
+
# TODO: return type is bitfield :IFieldInfoFlags
|
164
|
+
attach_function :g_field_info_get_flags, [:pointer], :int
|
152
165
|
attach_function :g_field_info_get_size, [:pointer], :int
|
153
166
|
attach_function :g_field_info_get_offset, [:pointer], :int
|
154
167
|
attach_function :g_field_info_get_type, [:pointer], :pointer
|
@@ -253,5 +266,9 @@ module GObjectIntrospection
|
|
253
266
|
#
|
254
267
|
attach_function :g_constant_info_get_type, [:pointer], :pointer
|
255
268
|
attach_function :g_constant_info_get_value, [:pointer, :pointer], :int
|
269
|
+
|
270
|
+
# IPropertyInfo
|
271
|
+
#
|
272
|
+
attach_function :g_property_info_get_type, [:pointer], :pointer
|
256
273
|
end
|
257
274
|
end
|