gir_ffi 0.0.6 → 0.0.7

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