cocoa 0.1.2 → 0.1.3

Sign up to get free protection for your applications and to get access to all the features.
data/lib/cocoa/objc.rb CHANGED
@@ -22,4 +22,266 @@ module ObjC
22
22
  end
23
23
  send(method, id, selector, *args )
24
24
  end
25
+
26
+ def self.String_to_NSString( string )
27
+ nsstring_class = objc_getClass("NSString")
28
+ msgSend(nsstring_class, "stringWithUTF8String:", :string, string )
29
+ end
30
+
31
+ def self.NSString_to_String( nsstring_pointer )
32
+ c_string = msgSend( nsstring_pointer, "UTF8String")
33
+ if c_string.null?
34
+ return "(NULL)"
35
+ else
36
+ return c_string.read_string()
37
+ end
38
+ end
39
+
40
+ def self.object_to_instance ret
41
+ klass_name = NSString_to_String(Cocoa::NSStringFromClass(ObjC.msgSend(ret,"class")))
42
+ return self if klass_name == '(NULL)'
43
+ instance = begin
44
+ ("Cocoa::"+klass_name).constantize.new(true)
45
+ rescue
46
+ klass_name = if klass_name =~ /^__NSCF/
47
+ "NS#{klass_name[6..-1]}"
48
+ elsif klass_name[0]=='_'
49
+ "FIX_#{klass_name}"
50
+ else
51
+ klass_name
52
+ end
53
+ klass = begin
54
+ Cocoa.const_get(klass_name)
55
+ rescue => e
56
+ superclass_name = NSString_to_String(Cocoa::NSStringFromClass(ObjC.msgSend(ret,'superclass')))
57
+ superclass = "Cocoa::#{superclass_name}".constantize
58
+ proxy = Class.new(superclass)
59
+ Cocoa.const_set(klass_name, proxy)
60
+ klass = ("Cocoa::"+klass_name).constantize
61
+ superclass.inherited(klass)
62
+ klass
63
+ end
64
+ klass.new(true)
65
+ end
66
+ instance.object = ret
67
+ instance
68
+ end
69
+
70
+ def self.translate_retval method,ret,type
71
+ case type
72
+ when '@'
73
+ return nil if ret.address == 0
74
+ return ret if method == :NSStringFromClass
75
+ object_to_instance ret
76
+ when '#'
77
+ ret
78
+ when /^{([^=]*)=.*}$/
79
+ ret
80
+ when /^\^{[^=]*=.*}$/
81
+ return nil if ret.address == 0
82
+ object_to_instance ret
83
+ else
84
+ raise type
85
+ end
86
+ end
87
+
88
+ def self.fixed_args args,params={},types=[],options={}
89
+ if options[:variadic]
90
+ _types = (types.dup*args.size)
91
+ args
92
+ else
93
+ _types = types.dup
94
+ ([args.first]+params.values)
95
+ end.map do |arg|
96
+ type = _types.shift
97
+ case arg
98
+ when TrueClass, FalseClass
99
+ [:bool,arg]
100
+ when Fixnum, Bignum
101
+ case type
102
+ when 'q'
103
+ [:long_long,arg]
104
+ when 'Q'
105
+ [:ulong_long,arg]
106
+ when 'd'
107
+ [:double,arg]
108
+ else
109
+ raise type.inspect
110
+ end
111
+ when Float
112
+ [:double,arg]
113
+ when String
114
+ [:pointer,ObjC.String_to_NSString(arg)]
115
+ when NilClass
116
+ [:pointer,nil]
117
+ when Symbol
118
+ [:pointer,ObjC.sel_registerName("#{arg}:")]
119
+ when Cocoa::NSObject
120
+ [:pointer,arg.object]
121
+ when FFI::Struct
122
+ [arg.class.by_value,arg]
123
+ when FFI::Pointer
124
+ [:pointer,arg]
125
+ else
126
+ raise ArgumentError.new("#{arg.class.name}: #{arg.inspect}")
127
+ end
128
+ end.flatten
129
+ end
130
+
131
+ def self.apple_type_to_ffi type
132
+ # TODO: These are just stubbed on guess - check'em'all
133
+ case type
134
+ when 'C'
135
+ :uchar
136
+ when '@'
137
+ :pointer
138
+ when '#'
139
+ :pointer
140
+ when 'Q'
141
+ :int
142
+ when ':'
143
+ :pointer
144
+ when 'I'
145
+ :int
146
+ when 'L'
147
+ :int
148
+ when 'd'
149
+ :double
150
+ when 'f'
151
+ :float
152
+ when 'i'
153
+ :int
154
+ when 's'
155
+ :int
156
+ when 'q'
157
+ :long_long
158
+ when 'S'
159
+ :int
160
+ when /^\^/
161
+ :pointer
162
+ when 'B'
163
+ :bool
164
+ when 'v'
165
+ :void
166
+ when '[5*]'
167
+ :void
168
+ when /^{[^=]*=.*}$/
169
+ begin
170
+ /^{_*([^=]*)=.*}$/.match(type)[1].constantize.by_value
171
+ rescue => e
172
+ begin
173
+ "Cocoa::#{/^{_*([^=]*)=.*}$/.match(type)[1]}".constantize.by_value
174
+ rescue => e
175
+ match = /^{_*([^=]*)=(.*)}$/.match(type)
176
+ klass = begin
177
+ Cocoa.const_get(match[1])
178
+ rescue
179
+ # puts "defining struct Cocoa::#{match[1]} as #{match[2]}"
180
+ # this stuff doesnt work with jruby
181
+ klass = Class.new(FFI::Struct)
182
+ Cocoa.const_set(match[1], klass)
183
+ name = 'a'
184
+ layout = []
185
+ match[2].each_char do |c|
186
+ case c
187
+ when 'd'
188
+ layout << name.to_sym
189
+ name = name.next
190
+ layout << :double
191
+ end
192
+ end
193
+ klass = "Cocoa::#{match[1]}".constantize
194
+ klass.layout *layout
195
+ klass
196
+ end
197
+ klass.by_ref
198
+ end
199
+ end
200
+ when nil
201
+ :void
202
+ when '*' # character string
203
+ :pointer
204
+ when '@?'
205
+ :pointer
206
+ else
207
+ raise type.inspect
208
+ end
209
+ end
210
+
211
+ def self.objc_type type,default='i'
212
+ case type
213
+ when nil
214
+ default
215
+ when '@'
216
+ type
217
+ when 'v'
218
+ type
219
+ when /^{([^=]*)=.*}$/
220
+ type
221
+ else
222
+ raise type.inspect
223
+ end
224
+ end
225
+
226
+ def self.call_arguments params,args
227
+ fixed_args = []
228
+ args.each_with_index do |arg,i|
229
+ case params[:types][i]
230
+ when '@'
231
+ fixed_args << arg
232
+ when 'd'
233
+ if arg.is_a?(Fixnum)
234
+ fixed_args << arg.to_f
235
+ else
236
+ raise ArgumentError.new("float expected, got #{arg.class.name}") unless arg.is_a?(Float)
237
+ fixed_args << arg
238
+ end
239
+ when 'I'
240
+ raise ArgumentError unless arg.is_a?(Fixnum)
241
+ fixed_args << arg
242
+ when 'Q'
243
+ raise ArgumentError.new(arg.inspect) unless arg.is_a?(Fixnum)
244
+ fixed_args << arg
245
+ when 'q'
246
+ raise ArgumentError unless arg.is_a?(Fixnum)
247
+ fixed_args << arg
248
+ when '#'
249
+ raise ArgumentError unless arg.is_a?(FFI::Pointer)
250
+ fixed_args << arg
251
+ when /^{[^=]*=.*}$/
252
+ raise ArgumentError.new(arg.inspect) unless arg.kind_of?(FFI::Struct)
253
+ fixed_args << arg
254
+ when /^\^{([^=]*)=.*}$/
255
+ case arg
256
+ when FFI::Pointer
257
+ fixed_args << arg
258
+ when Array
259
+ raise ArgumentError unless $1 == '__CFArray'
260
+ fixed_args << NSArray.arrayWithObjects(arg).object
261
+ else
262
+ match = $1
263
+ if arg.class.name =~ /^Cocoa::/ # "Cocoa::#{$1}".constantize
264
+ fixed_args << arg.object
265
+ elsif arg.is_a?(NilClass)
266
+ fixed_args << FFI::MemoryPointer::NULL
267
+ elsif arg.is_a?(String) && match == '__CFString'
268
+ fixed_args << Cocoa::String_to_NSString(arg)
269
+ else
270
+ raise ArgumentError.new("expected #{params[:types][i]} got #{arg.class.name} (#{match})")
271
+ end
272
+ end
273
+ when '^d'
274
+ raise ArgumentError unless arg.is_a?(Array)
275
+ arr = FFI::MemoryPointer.new(:double,arg.size)
276
+ arr.write_array_of_double(arg)
277
+ fixed_args << arr
278
+ when '^v'
279
+ raise ArgumentError unless arg.is_a?(NilClass)
280
+ fixed_args << FFI::MemoryPointer::NULL
281
+ else
282
+ raise params[:types][i]
283
+ end
284
+ end
285
+ fixed_args
286
+ end
25
287
  end
@@ -14,4 +14,10 @@ module Cocoa
14
14
  end
15
15
 
16
16
  NSPoint = CGPoint
17
+
18
+ def NSMakePoint x,y
19
+ CGPoint.new(x: x, y: y)
20
+ end
21
+
22
+ NSZeroPoint = CGPoint.new(x: 0, y: 0)
17
23
  end
@@ -0,0 +1,23 @@
1
+ module Cocoa
2
+ class CFRange < FFI::Struct
3
+ def initialize *args
4
+ options = args.first
5
+ if options.is_a? Hash
6
+ self[:location] = options[:location]
7
+ self[:length] = options[:length]
8
+ else
9
+ super *args
10
+ end
11
+ end
12
+ def to_s
13
+ "<CFRange: #{self[:location]} #{self[:length]}>"
14
+ end
15
+ layout :location, :long_long, :length, :long_long
16
+ end
17
+
18
+ NSRange = CFRange
19
+
20
+ def CFRangeMake loc,len
21
+ CFRange.new(location: loc, length: len)
22
+ end
23
+ end
@@ -16,4 +16,10 @@ module Cocoa
16
16
  end
17
17
 
18
18
  NSRect = Cocoa::CGRect
19
+
20
+ def CGRectMake x,y,width,height
21
+ CGRect.new(x: x, y: y, width: width, height: height)
22
+ end
23
+
24
+ NSZeroRect = CGRect.new(x: 0, y: 0, width: 0, height: 0)
19
25
  end
@@ -14,4 +14,8 @@ module Cocoa
14
14
  end
15
15
 
16
16
  NSSize = CGSize
17
+
18
+ def NSMakeSize width,height
19
+ CGSize.new(width: width, height: height)
20
+ end
17
21
  end