gir_ffi 0.0.6 → 0.0.7

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 CHANGED
@@ -1,3 +1,15 @@
1
+ == 0.0.7 / 2011-04-01
2
+
3
+ * Support gobject-introspection 0.10, drop support for earlier versions.
4
+ - Use Regress, not Everything, for testing.
5
+ - Deal with functions that are no longer introspectable.
6
+ * Correctly handle constructors that declare their return type different
7
+ from their class.
8
+ * Implement RubyClosure, a GObject::Closure for handling ruby callbacks.
9
+ * Handle GLib's singly and doubly linked lists.
10
+ * Handle callback types defined in-place (like Closure's marshal).
11
+ * Refactoring.
12
+
1
13
  == 0.0.6 / 2011-03-01
2
14
 
3
15
  * Cast returned GObjects to their actual type.
data/TODO.rdoc CHANGED
@@ -25,6 +25,16 @@ overrides will have to be used for the cases where the 'gpointer' actually
25
25
  needs to be a GObject. I consider it an omission in GIRepository that these
26
26
  two cases are not distinguished.
27
27
 
28
+ Update: generic pointers have been declared 'not introspectable', so
29
+ handling them can be removed.
30
+
31
+ == Check binding of GObject:
32
+
33
+ (11:37:03 PM) walters: the basic story is that GObject should be manually bound
34
+ (11:47:02 PM) ebassi: the really necessary bits are: GObject/GInitiallyUnowned memory management; properties accessors; GSignal connection API
35
+ (11:47:15 PM) ebassi: the rest is "nice to have"
36
+ (11:47:37 PM) ebassi: oh, and probably GBinding - but that's just because I wrote it ;-)
37
+
28
38
  == Compatibility with all implementations.
29
39
 
30
40
  Currently, there are the following incompatibilities:
@@ -0,0 +1,16 @@
1
+ # Based on http://www.idle-hacking.com/2010/02/webkit-ruby-and-gtk/
2
+ $LOAD_PATH.unshift File.join(File.dirname(__FILE__), '..', 'lib')
3
+ require 'gir_ffi'
4
+
5
+ GirFFI.setup :Gtk
6
+ GirFFI.setup :WebKit
7
+
8
+ Gtk.init
9
+
10
+ win = Gtk::Window.new :toplevel
11
+ wv = WebKit::WebView.new
12
+ win.add(wv)
13
+ win.show_all
14
+ wv.open('http://www.google.com/')
15
+ GObject.signal_connect(win, "destroy") { Gtk.main_quit }
16
+ Gtk.main
@@ -2,7 +2,9 @@ require 'gir_ffi/allocation_helper'
2
2
 
3
3
  module GirFFI
4
4
  module ArgHelper
5
+ # FIXME: Hideous.
5
6
  def self.object_to_inptr obj
7
+ return obj if obj.is_a? FFI::Pointer
6
8
  return obj.to_ptr if obj.respond_to? :to_ptr
7
9
  return nil if obj.nil?
8
10
  FFI::Pointer.new(obj.object_id)
@@ -18,11 +20,6 @@ module GirFFI
18
20
  typed_array_to_inptr :int32, ary
19
21
  end
20
22
 
21
- # TODO: Use alias.
22
- def self.int_array_to_inptr ary
23
- int32_array_to_inptr ary
24
- end
25
-
26
23
  def self.int16_array_to_inptr ary
27
24
  typed_array_to_inptr :int16, ary
28
25
  end
@@ -41,6 +38,13 @@ module GirFFI
41
38
  AllocationHelper.safe_malloc(len + 1).write_string(str).put_char(len, 0)
42
39
  end
43
40
 
41
+ def self.utf8_array_to_inptr ary
42
+ return nil if ary.nil?
43
+ ptr_ary = ary.map {|str| utf8_to_inptr str}
44
+ ptr_ary << nil
45
+ typed_array_to_inptr :pointer, ptr_ary
46
+ end
47
+
44
48
  def self.gtype_array_to_inptr ary
45
49
  case FFI.type_size(:size_t)
46
50
  when 4
@@ -52,6 +56,19 @@ module GirFFI
52
56
  end
53
57
  end
54
58
 
59
+ def self.gvalue_array_to_inptr ary
60
+ return nil if ary.nil?
61
+ raise NotImplementedError
62
+ end
63
+
64
+ class << self
65
+ alias int_array_to_inptr int32_array_to_inptr
66
+ alias gint8_array_to_inptr int8_array_to_inptr
67
+ alias gint16_array_to_inptr int16_array_to_inptr
68
+ alias gint32_array_to_inptr int32_array_to_inptr
69
+ alias gint64_array_to_inptr int64_array_to_inptr
70
+ end
71
+
55
72
  def self.cleanup_ptr ptr
56
73
  LibC.free ptr
57
74
  end
@@ -75,8 +92,8 @@ module GirFFI
75
92
  ptrs.each { |ptr| LibC.free ptr }
76
93
  end
77
94
 
78
- def self.int_to_inoutptr val
79
- int_pointer.write_int val
95
+ def self.int32_to_inoutptr val
96
+ int32_pointer.write_int32 val
80
97
  end
81
98
 
82
99
  def self.utf8_to_inoutptr str
@@ -84,7 +101,7 @@ module GirFFI
84
101
  pointer_pointer.write_pointer sptr
85
102
  end
86
103
 
87
- def self.int_array_to_inoutptr ary
104
+ def self.int32_array_to_inoutptr ary
88
105
  block = int_array_to_inptr ary
89
106
  pointer_pointer.write_pointer block
90
107
  end
@@ -104,8 +121,16 @@ module GirFFI
104
121
  double_pointer.put_double 0, val
105
122
  end
106
123
 
107
- def self.int_pointer
108
- AllocationHelper.safe_malloc FFI.type_size(:int)
124
+ class << self
125
+ alias int_to_inoutptr int32_to_inoutptr
126
+ alias gint32_to_inoutptr int32_to_inoutptr
127
+ alias int_array_to_inoutptr int32_array_to_inoutptr
128
+ alias gint32_array_to_inoutptr int32_array_to_inoutptr
129
+ alias gdouble_to_inoutptr double_to_inoutptr
130
+ end
131
+
132
+ def self.int32_pointer
133
+ AllocationHelper.safe_malloc FFI.type_size(:int32)
109
134
  end
110
135
 
111
136
  def self.double_pointer
@@ -116,8 +141,14 @@ module GirFFI
116
141
  AllocationHelper.safe_malloc FFI.type_size(:pointer)
117
142
  end
118
143
 
119
- def self.int_outptr
120
- int_pointer.write_int 0
144
+ class << self
145
+ alias int_pointer int32_pointer
146
+ alias gint32_pointer int32_pointer
147
+ alias gdouble_pointer double_pointer
148
+ end
149
+
150
+ def self.int32_outptr
151
+ int32_pointer.write_int32 0
121
152
  end
122
153
 
123
154
  def self.double_outptr
@@ -132,14 +163,20 @@ module GirFFI
132
163
  pointer_outptr
133
164
  end
134
165
 
166
+ class << self
167
+ alias int_outptr int32_outptr
168
+ alias gint32_outptr int32_outptr
169
+ alias gdouble_outptr double_outptr
170
+ end
171
+
135
172
  # Converts an outptr to a pointer.
136
173
  def self.outptr_to_pointer ptr
137
174
  ptr.read_pointer
138
175
  end
139
176
 
140
177
  # Converts an outptr to an int.
141
- def self.outptr_to_int ptr
142
- ptr.read_int
178
+ def self.outptr_to_int32 ptr
179
+ ptr.read_int32
143
180
  end
144
181
 
145
182
  # Converts an outptr to a string.
@@ -162,20 +199,65 @@ module GirFFI
162
199
  end
163
200
 
164
201
  # Converts an outptr to an array of int.
165
- def self.outptr_to_int_array ptr, size
202
+ def self.outptr_to_int32_array ptr, size
166
203
  block = ptr.read_pointer
167
204
  return nil if block.null?
168
- ptr_to_int_array block, size
205
+ ptr_to_int32_array block, size
206
+ end
207
+
208
+ class << self
209
+ alias outptr_to_int outptr_to_int32
210
+ alias outptr_to_int_array outptr_to_int32_array
211
+ alias outptr_to_gint32 outptr_to_int32
212
+ alias outptr_to_gint32_array outptr_to_int32_array
213
+ alias outptr_to_gdouble outptr_to_double
169
214
  end
170
215
 
171
- def self.ptr_to_int_array ptr, size
172
- ptr.read_array_of_int(size)
216
+ def self.ptr_to_int32_array ptr, size
217
+ ptr.read_array_of_int32(size)
173
218
  end
174
219
 
175
220
  def self.ptr_to_utf8 ptr
176
221
  ptr.null? ? nil : ptr.read_string
177
222
  end
178
223
 
224
+ class << self
225
+ alias ptr_to_int_array ptr_to_int32_array
226
+ alias ptr_to_gint32_array ptr_to_int32_array
227
+ end
228
+
229
+ def self.utf8_array_to_glist arr
230
+ return nil if arr.nil?
231
+ arr.inject(nil) { |lst, str|
232
+ GLib.list_append lst, utf8_to_inptr(str) }
233
+ end
234
+
235
+ def self.utf8_array_to_gslist arr
236
+ return nil if arr.nil?
237
+ arr.reverse.inject(nil) { |lst, str|
238
+ GLib.slist_prepend lst, utf8_to_inptr(str) }
239
+ end
240
+
241
+ def self.glist_to_utf8_array ptr
242
+ return [] if ptr.null?
243
+ # FIXME: Quasi-circular dependency on generated module
244
+ list = GLib::List.wrap(ptr)
245
+ str = ptr_to_utf8(list[:data])
246
+ [str] + glist_to_utf8_array(list[:next])
247
+ end
248
+
249
+ def self.gslist_to_utf8_array ptr
250
+ return [] if ptr.null?
251
+ # FIXME: Quasi-circular dependency on generated module
252
+ list = GLib::SList.wrap(ptr)
253
+ str = ptr_to_utf8(list[:data])
254
+ [str] + gslist_to_utf8_array(list[:next])
255
+ end
256
+
257
+ def self.outgslist_to_utf8_array ptr
258
+ gslist_to_utf8_array ptr.read_pointer
259
+ end
260
+
179
261
  def self.wrap_in_callback_args_mapper namespace, name, prc
180
262
  return prc if FFI::Function === prc
181
263
  return nil if prc.nil?
@@ -191,34 +273,44 @@ module GirFFI
191
273
  end
192
274
 
193
275
  def self.map_single_callback_arg arg, info
194
- type = info.type
195
- tag = type.tag
196
-
197
- case tag
276
+ case info.type.tag
198
277
  when :interface
199
- iface = type.interface
200
- if iface.type == :object
201
- object_pointer_to_object arg
202
- else
203
- arg
204
- end
278
+ map_interface_callback_arg arg, info
205
279
  when :utf8
206
280
  ptr_to_utf8 arg
207
281
  when :void
208
- if arg.null?
209
- nil
210
- else
211
- begin
212
- ObjectSpace._id2ref arg.address
213
- rescue RangeError
214
- arg
215
- end
216
- end
282
+ map_void_callback_arg arg
217
283
  else
218
284
  arg
219
285
  end
220
286
  end
221
287
 
288
+ def self.map_interface_callback_arg arg, info
289
+ iface = info.type.interface
290
+ case iface.type
291
+ when :object
292
+ object_pointer_to_object arg
293
+ when :struct
294
+ klass = GirFFI::Builder.build_class iface
295
+ klass.wrap arg
296
+ else
297
+ arg
298
+ end
299
+ end
300
+
301
+ def self.map_void_callback_arg arg
302
+ if arg.null?
303
+ nil
304
+ else
305
+ begin
306
+ # TODO: Use custom object store.
307
+ ObjectSpace._id2ref arg.address
308
+ rescue RangeError
309
+ arg
310
+ end
311
+ end
312
+ end
313
+
222
314
  def self.check_error errpp
223
315
  errp = errpp.read_pointer
224
316
  raise GError.new(errp)[:message] unless errp.null?
@@ -245,7 +337,7 @@ module GirFFI
245
337
  raise RuntimeError, "Unable to find info for type '#{tpname}' (#{tp})"
246
338
  end
247
339
 
248
- klass = GirFFI::Builder.build_class info.namespace, info.name
340
+ klass = GirFFI::Builder.build_class info
249
341
  klass.wrap optr
250
342
  end
251
343