/
ffi-gobject.rb
106 lines (84 loc) · 3.31 KB
/
ffi-gobject.rb
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
# NOTE: Do not require this file directly. Require 'gir_ffi' instead.
#
GirFFI.setup :GObject
require 'ffi-gobject/base'
require 'ffi-gobject/value'
require 'ffi-gobject/initially_unowned'
require 'ffi-gobject/closure'
require 'ffi-gobject/object'
require 'ffi-gobject/object_class'
require 'ffi-gobject/ruby_closure'
require 'gir_ffi/builders/user_defined_builder'
# Module representing GLib's GObject namespace.
module GObject
def self.type_from_instance_pointer inst_ptr
return nil if inst_ptr.null?
klsptr = inst_ptr.get_pointer 0
# TODO: Cache the message name somewhere.
klsptr.send "get_#{GirFFI::TypeMap::TAG_TYPE_MAP[:GType]}", 0
end
def self.type_from_instance instance
type_from_instance_pointer instance.to_ptr
end
def self.object_class_from_instance instance
object_class_from_instance_pointer instance.to_ptr
end
def self.object_class_from_instance_pointer inst_ptr
return nil if inst_ptr.null?
klsptr = inst_ptr.get_pointer 0
ObjectClass.wrap klsptr
end
def self.signal_lookup_from_instance signal, object
signal_lookup signal, type_from_instance(object)
end
def self.signal_emit object, detailed_signal, *args
signal, detail = detailed_signal.split('::')
signal_id = signal_lookup_from_instance signal, object
detail_quark = GLib.quark_from_string(detail)
sig_info = object.class.find_signal signal
argument_gvalues = sig_info.arguments_to_gvalues object, args
return_gvalue = sig_info.gvalue_for_return_value
signal_emitv argument_gvalues, signal_id, detail_quark, return_gvalue
return_gvalue
end
def self.signal_connect object, detailed_signal, data = nil, &block
raise ArgumentError, 'Block needed' unless block_given?
signal_name, _ = detailed_signal.split('::')
sig_info = object.class.find_signal signal_name
closure = sig_info.wrap_in_closure { |*args| block.call(*args << data) }
# TODO: Provide _after variant
signal_connect_closure object, detailed_signal, closure, false
end
# Smells of :reek:LongParameterList: due to the C interface.
# rubocop:disable Metrics/ParameterLists
def self.param_spec_int name, nick, blurb, minimum, maximum, default_value, flags
ptr = Lib.g_param_spec_int(name, nick, blurb, minimum, maximum,
default_value, flags)
ParamSpecInt.wrap(ptr)
end
load_class :Callback
load_class :ClosureNotify
load_class :ConnectFlags
load_class :ClosureMarshal
load_class :ParamFlags
# NOTE: This Lib module is set up in `gir_ffi-base/gobject/lib.rb`.
module Lib
attach_function :g_object_ref_sink, [:pointer], :void
attach_function :g_array_get_type, [], :size_t
attach_function :g_byte_array_get_type, [], :size_t
attach_function :g_hash_table_get_type, [], :size_t
attach_function :g_strv_get_type, [], :size_t
attach_function :g_signal_connect_data,
[:pointer, :string, Callback, :pointer, ClosureNotify, ConnectFlags],
:ulong
attach_function :g_closure_set_marshal,
[:pointer, ClosureMarshal], :void
attach_function :g_param_spec_int,
[:string, :string, :string, :int32, :int32, :int32, ParamFlags],
:pointer
end
TYPE_ARRAY = Lib.g_array_get_type
TYPE_BYTE_ARRAY = Lib.g_byte_array_get_type
TYPE_HASH_TABLE = Lib.g_hash_table_get_type
TYPE_STRV = Lib.g_strv_get_type
end