hybridgroup-ruby-sdl-ffi 0.4.1

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,282 @@
1
+ #--
2
+ #
3
+ # This file is one part of:
4
+ #
5
+ # Ruby-SDL-FFI - Ruby-FFI bindings to SDL
6
+ #
7
+ # Copyright (c) 2009 John Croisant
8
+ #
9
+ # Permission is hereby granted, free of charge, to any person obtaining
10
+ # a copy of this software and associated documentation files (the
11
+ # "Software"), to deal in the Software without restriction, including
12
+ # without limitation the rights to use, copy, modify, merge, publish,
13
+ # distribute, sublicense, and/or sell copies of the Software, and to
14
+ # permit persons to whom the Software is furnished to do so, subject to
15
+ # the following conditions:
16
+ #
17
+ # The above copyright notice and this permission notice shall be
18
+ # included in all copies or substantial portions of the Software.
19
+ #
20
+ # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
21
+ # EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
22
+ # MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
23
+ # IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
24
+ # CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
25
+ # TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
26
+ # SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
27
+ #
28
+ #++
29
+
30
+
31
+ module SDL
32
+
33
+ K_FIRST = 0
34
+ K_UNKNOWN = 0
35
+ K_BACKSPACE = 8
36
+ K_TAB = 9
37
+ K_CLEAR = 12
38
+ K_RETURN = 13
39
+ K_PAUSE = 19
40
+ K_ESCAPE = 27
41
+ K_SPACE = 32
42
+ K_EXCLAIM = 33
43
+ K_QUOTEDBL = 34
44
+ K_HASH = 35
45
+ K_DOLLAR = 36
46
+ K_AMPERSAND = 38
47
+ K_QUOTE = 39
48
+ K_LEFTPAREN = 40
49
+ K_RIGHTPAREN = 41
50
+ K_ASTERISK = 42
51
+ K_PLUS = 43
52
+ K_COMMA = 44
53
+ K_MINUS = 45
54
+ K_PERIOD = 46
55
+ K_SLASH = 47
56
+ K_0 = 48
57
+ K_1 = 49
58
+ K_2 = 50
59
+ K_3 = 51
60
+ K_4 = 52
61
+ K_5 = 53
62
+ K_6 = 54
63
+ K_7 = 55
64
+ K_8 = 56
65
+ K_9 = 57
66
+ K_COLON = 58
67
+ K_SEMICOLON = 59
68
+ K_LESS = 60
69
+ K_EQUALS = 61
70
+ K_GREATER = 62
71
+ K_QUESTION = 63
72
+ K_AT = 64
73
+ K_LEFTBRACKET = 91
74
+ K_BACKSLASH = 92
75
+ K_RIGHTBRACKET = 93
76
+ K_CARET = 94
77
+ K_UNDERSCORE = 95
78
+ K_BACKQUOTE = 96
79
+ K_a = 97
80
+ K_b = 98
81
+ K_c = 99
82
+ K_d = 100
83
+ K_e = 101
84
+ K_f = 102
85
+ K_g = 103
86
+ K_h = 104
87
+ K_i = 105
88
+ K_j = 106
89
+ K_k = 107
90
+ K_l = 108
91
+ K_m = 109
92
+ K_n = 110
93
+ K_o = 111
94
+ K_p = 112
95
+ K_q = 113
96
+ K_r = 114
97
+ K_s = 115
98
+ K_t = 116
99
+ K_u = 117
100
+ K_v = 118
101
+ K_w = 119
102
+ K_x = 120
103
+ K_y = 121
104
+ K_z = 122
105
+ K_DELETE = 127
106
+ K_WORLD_0 = 160
107
+ K_WORLD_1 = 161
108
+ K_WORLD_2 = 162
109
+ K_WORLD_3 = 163
110
+ K_WORLD_4 = 164
111
+ K_WORLD_5 = 165
112
+ K_WORLD_6 = 166
113
+ K_WORLD_7 = 167
114
+ K_WORLD_8 = 168
115
+ K_WORLD_9 = 169
116
+ K_WORLD_10 = 170
117
+ K_WORLD_11 = 171
118
+ K_WORLD_12 = 172
119
+ K_WORLD_13 = 173
120
+ K_WORLD_14 = 174
121
+ K_WORLD_15 = 175
122
+ K_WORLD_16 = 176
123
+ K_WORLD_17 = 177
124
+ K_WORLD_18 = 178
125
+ K_WORLD_19 = 179
126
+ K_WORLD_20 = 180
127
+ K_WORLD_21 = 181
128
+ K_WORLD_22 = 182
129
+ K_WORLD_23 = 183
130
+ K_WORLD_24 = 184
131
+ K_WORLD_25 = 185
132
+ K_WORLD_26 = 186
133
+ K_WORLD_27 = 187
134
+ K_WORLD_28 = 188
135
+ K_WORLD_29 = 189
136
+ K_WORLD_30 = 190
137
+ K_WORLD_31 = 191
138
+ K_WORLD_32 = 192
139
+ K_WORLD_33 = 193
140
+ K_WORLD_34 = 194
141
+ K_WORLD_35 = 195
142
+ K_WORLD_36 = 196
143
+ K_WORLD_37 = 197
144
+ K_WORLD_38 = 198
145
+ K_WORLD_39 = 199
146
+ K_WORLD_40 = 200
147
+ K_WORLD_41 = 201
148
+ K_WORLD_42 = 202
149
+ K_WORLD_43 = 203
150
+ K_WORLD_44 = 204
151
+ K_WORLD_45 = 205
152
+ K_WORLD_46 = 206
153
+ K_WORLD_47 = 207
154
+ K_WORLD_48 = 208
155
+ K_WORLD_49 = 209
156
+ K_WORLD_50 = 210
157
+ K_WORLD_51 = 211
158
+ K_WORLD_52 = 212
159
+ K_WORLD_53 = 213
160
+ K_WORLD_54 = 214
161
+ K_WORLD_55 = 215
162
+ K_WORLD_56 = 216
163
+ K_WORLD_57 = 217
164
+ K_WORLD_58 = 218
165
+ K_WORLD_59 = 219
166
+ K_WORLD_60 = 220
167
+ K_WORLD_61 = 221
168
+ K_WORLD_62 = 222
169
+ K_WORLD_63 = 223
170
+ K_WORLD_64 = 224
171
+ K_WORLD_65 = 225
172
+ K_WORLD_66 = 226
173
+ K_WORLD_67 = 227
174
+ K_WORLD_68 = 228
175
+ K_WORLD_69 = 229
176
+ K_WORLD_70 = 230
177
+ K_WORLD_71 = 231
178
+ K_WORLD_72 = 232
179
+ K_WORLD_73 = 233
180
+ K_WORLD_74 = 234
181
+ K_WORLD_75 = 235
182
+ K_WORLD_76 = 236
183
+ K_WORLD_77 = 237
184
+ K_WORLD_78 = 238
185
+ K_WORLD_79 = 239
186
+ K_WORLD_80 = 240
187
+ K_WORLD_81 = 241
188
+ K_WORLD_82 = 242
189
+ K_WORLD_83 = 243
190
+ K_WORLD_84 = 244
191
+ K_WORLD_85 = 245
192
+ K_WORLD_86 = 246
193
+ K_WORLD_87 = 247
194
+ K_WORLD_88 = 248
195
+ K_WORLD_89 = 249
196
+ K_WORLD_90 = 250
197
+ K_WORLD_91 = 251
198
+ K_WORLD_92 = 252
199
+ K_WORLD_93 = 253
200
+ K_WORLD_94 = 254
201
+ K_WORLD_95 = 255
202
+ K_KP0 = 256
203
+ K_KP1 = 257
204
+ K_KP2 = 258
205
+ K_KP3 = 259
206
+ K_KP4 = 260
207
+ K_KP5 = 261
208
+ K_KP6 = 262
209
+ K_KP7 = 263
210
+ K_KP8 = 264
211
+ K_KP9 = 265
212
+ K_KP_PERIOD = 266
213
+ K_KP_DIVIDE = 267
214
+ K_KP_MULTIPLY = 268
215
+ K_KP_MINUS = 269
216
+ K_KP_PLUS = 270
217
+ K_KP_ENTER = 271
218
+ K_KP_EQUALS = 272
219
+ K_UP = 273
220
+ K_DOWN = 274
221
+ K_RIGHT = 275
222
+ K_LEFT = 276
223
+ K_INSERT = 277
224
+ K_HOME = 278
225
+ K_END = 279
226
+ K_PAGEUP = 280
227
+ K_PAGEDOWN = 281
228
+ K_F1 = 282
229
+ K_F2 = 283
230
+ K_F3 = 284
231
+ K_F4 = 285
232
+ K_F5 = 286
233
+ K_F6 = 287
234
+ K_F7 = 288
235
+ K_F8 = 289
236
+ K_F9 = 290
237
+ K_F10 = 291
238
+ K_F11 = 292
239
+ K_F12 = 293
240
+ K_F13 = 294
241
+ K_F14 = 295
242
+ K_F15 = 296
243
+ K_NUMLOCK = 300
244
+ K_CAPSLOCK = 301
245
+ K_SCROLLOCK = 302
246
+ K_RSHIFT = 303
247
+ K_LSHIFT = 304
248
+ K_RCTRL = 305
249
+ K_LCTRL = 306
250
+ K_RALT = 307
251
+ K_LALT = 308
252
+ K_RMETA = 309
253
+ K_LMETA = 310
254
+ K_LSUPER = 311
255
+ K_RSUPER = 312
256
+ K_MODE = 313
257
+ K_COMPOSE = 314
258
+ K_HELP = 315
259
+ K_PRINT = 316
260
+ K_SYSREQ = 317
261
+ K_BREAK = 318
262
+ K_MENU = 319
263
+ K_POWER = 320
264
+ K_EURO = 321
265
+ K_UNDO = 322
266
+ K_LAST = 323
267
+
268
+ KMOD_NONE = 0x0000
269
+ KMOD_LSHIFT = 0x0001
270
+ KMOD_RSHIFT = 0x0002
271
+ KMOD_LCTRL = 0x0040
272
+ KMOD_RCTRL = 0x0080
273
+ KMOD_LALT = 0x0100
274
+ KMOD_RALT = 0x0200
275
+ KMOD_LMETA = 0x0400
276
+ KMOD_RMETA = 0x0800
277
+ KMOD_NUM = 0x1000
278
+ KMOD_CAPS = 0x2000
279
+ KMOD_MODE = 0x4000
280
+ KMOD_RESERVED = 0x8000
281
+
282
+ end
@@ -0,0 +1,443 @@
1
+ #--
2
+ #
3
+ # This file is one part of:
4
+ #
5
+ # Ruby-SDL-FFI - Ruby-FFI bindings to SDL
6
+ #
7
+ # Copyright (c) 2010 John Croisant
8
+ #
9
+ # Permission is hereby granted, free of charge, to any person obtaining
10
+ # a copy of this software and associated documentation files (the
11
+ # "Software"), to deal in the Software without restriction, including
12
+ # without limitation the rights to use, copy, modify, merge, publish,
13
+ # distribute, sublicense, and/or sell copies of the Software, and to
14
+ # permit persons to whom the Software is furnished to do so, subject to
15
+ # the following conditions:
16
+ #
17
+ # The above copyright notice and this permission notice shall be
18
+ # included in all copies or substantial portions of the Software.
19
+ #
20
+ # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
21
+ # EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
22
+ # MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
23
+ # IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
24
+ # CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
25
+ # TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
26
+ # SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
27
+ #
28
+ #
29
+ # Contributions:
30
+ #
31
+ # - Bart Leusink, 2011-01-22:
32
+ # Fixed the display window not gaining focus on Mac OS X 10.6.
33
+ #
34
+ #++
35
+
36
+ #--
37
+ # Some bindings to Mac OS X system framework to allow Ruby-SDL-FFI
38
+ # to create a window on Mac without a special Ruby interpreter (rsdl).
39
+ # These are for internal use only. They are NOT part of the API.
40
+ #
41
+ # Eternal thanks to erisdiscord and jlnr for pointing the way!
42
+
43
+
44
+ # Only define this stuff if running on a Mac and not using rsdl and
45
+ # the RUBYSDLFFI_NOCOCOA environment variable is not true-ish.
46
+ if FFI::Platform.mac? and ($0 != "rsdl") and \
47
+ not (/^(1|t|true|y|yes)$/i =~ ENV["RUBYSDLFFI_NOCOCOA"])
48
+
49
+ module SDL::Mac
50
+
51
+ class << self
52
+
53
+ def make_menus( app_name )
54
+ ptr = FFI.find_type(:pointer)
55
+
56
+ nsapp = Cocoa.NSApp
57
+ menubar = Cocoa::NSMenu.new.initWithTitle("AMainMenu")
58
+ nsapp.msg( "setMainMenu:", ptr, menubar )
59
+
60
+ remove_bold_menu( nsapp, menubar )
61
+ make_app_menu( menubar, app_name )
62
+ make_window_menu( nsapp, menubar )
63
+
64
+ nil
65
+ end
66
+
67
+
68
+ def set_app_name( app_name )
69
+ ptr = FFI.find_type(:pointer)
70
+
71
+ if @appmenuitem
72
+ @appmenuitem.title = app_name
73
+ @hideitem.title = "Hide #{app_name}" if @hideitem
74
+ @quititem.title = "Quit #{app_name}" if @quititem
75
+ else
76
+ make_menus( app_name )
77
+ end
78
+
79
+ nil
80
+ end
81
+
82
+
83
+ private
84
+
85
+ # Hack to remove the bold "ruby" menu (aka the "Apple" menu).
86
+ # It's a ghost menu, it haunts us but can't be modified.
87
+ def remove_bold_menu( nsapp, menubar )
88
+ item = Cocoa::NSMenuItem.new.initWithTitle("AppleMenu")
89
+ menu = Cocoa::NSMenu.new.initWithTitle("AppleMenu")
90
+ item.submenu = menu
91
+
92
+ nsapp.msg("setAppleMenu:", FFI.find_type(:pointer), menu)
93
+ menubar.addItem(item)
94
+ menubar.removeItem(item)
95
+
96
+ item.release
97
+ menu.release
98
+ end
99
+
100
+
101
+ # Create the main menu with the app's name (Hide, Quit, etc.)
102
+ def make_app_menu( menubar, app_name )
103
+ item = Cocoa::NSMenuItem.new.initWithTitle( app_name )
104
+ menu = Cocoa::NSMenu.new.initWithTitle( app_name )
105
+ item.submenu = menu
106
+ menubar.addItem(item)
107
+
108
+ @hideitem = menu.addItemWithTitle("Hide #{app_name}", "hide:")
109
+ menu.addItemWithTitle("Hide Others", "hideOtherApplications:")
110
+ menu.addItemWithTitle("Show All", "unhideAllApplications:")
111
+
112
+ # Can't get the Quit menu item to work right yet.
113
+ # menu.addItem( Cocoa::NSMenuItem.separatorItem )
114
+ # @quititem = menu.addItemWithTitle("Quit #{app_name}", "terminate:")
115
+
116
+ @appmenuitem = item
117
+ menu.release
118
+ end
119
+
120
+
121
+ # Create the "Window" menu (Minimize, etc.)
122
+ def make_window_menu( nsapp, menubar )
123
+ ptr = FFI.find_type(:pointer)
124
+
125
+ item = Cocoa::NSMenuItem.new.initWithTitle("Window")
126
+ menu = Cocoa::NSMenu.new.initWithTitle("Window")
127
+ item.submenu = menu
128
+ menubar.addItem(item)
129
+ nsapp.msg("setWindowsMenu:", ptr, menu)
130
+
131
+ menu.addItemWithTitle("Minimize", "performMiniaturize:")
132
+
133
+ item.release
134
+ menu.release
135
+ end
136
+
137
+
138
+ def inspect_menu( menu, indent="" )
139
+ puts "%s-%s (%s \"%s\", %d items)"%[indent, menu, menu.classname,
140
+ menu.title, menu.length]
141
+ menu.each do |ob|
142
+ if ob.hasSubmenu?
143
+ inspect_menu( ob.submenu, indent+" " )
144
+ else
145
+ puts "%s -%s (%s \"%s\")"%[indent, ob, ob.classname, ob.title]
146
+ end
147
+ end
148
+ end
149
+
150
+ end
151
+
152
+
153
+ module ObjC
154
+ extend NiceFFI::Library
155
+ load_library 'objc'
156
+
157
+ typedef :pointer, :id
158
+ typedef :pointer, :sel
159
+ typedef :pointer, :ivar
160
+ typedef :pointer, :nsclass
161
+ callback :imp, [:id, :sel, :varargs], :id
162
+
163
+
164
+ class NSObject < NiceFFI::OpaqueStruct
165
+ def self.nsclassname; name.split("::")[-1]; end
166
+
167
+ # define msg, msg_ptr, msg_str, msg_int, msg_bool (and class methods)
168
+ ["", "_ptr", "_str", "_int", "_bool"].each do |suffix|
169
+ module_eval("
170
+ def msg#{suffix}( message, *args )
171
+ ObjC.msgSend#{suffix}( @pointer, message, *args )
172
+ end
173
+
174
+ def self.msg#{suffix}( message, *args )
175
+ ObjC.msgSend#{suffix}( ObjC.NSClass(self.nsclassname),
176
+ message, *args )
177
+ end")
178
+ end
179
+
180
+ def inspect; msg_str("description").to_s; end
181
+ def nsclassname; ObjC.object_getClassName(@pointer); end
182
+ def release; msg("release"); end
183
+ end
184
+
185
+ def self.NSObject( *args )
186
+ NSObject.new( *args )
187
+ end
188
+
189
+
190
+ class NSClass < NSObject
191
+ def initialize( str_or_ptr )
192
+ if str_or_ptr.is_a? String
193
+ super( ObjC.getClass(str_or_ptr) )
194
+ else
195
+ super
196
+ end
197
+ end
198
+ end
199
+
200
+ def self.NSClass( *args )
201
+ NSClass.new( *args )
202
+ end
203
+
204
+
205
+ class NSString < NSObject
206
+ def initialize( str_or_ptr )
207
+ if str_or_ptr.is_a? String
208
+ super( ObjC::NSClass("NSString").\
209
+ msg_ptr("stringWithUTF8String:",
210
+ FFI.find_type(:string), str_or_ptr) )
211
+ else
212
+ super
213
+ end
214
+ end
215
+
216
+ def to_s
217
+ str = msg_ptr( "UTF8String" )
218
+ (str.null?) ? "(NULL)" : str.read_string()
219
+ end
220
+ end
221
+
222
+ def self.NSString( *args )
223
+ NSString.new( *args )
224
+ end
225
+
226
+
227
+ func :__msgSend, :objc_msgSend, [:id, :sel, :varargs], :id
228
+ func :__msgSend_int, :objc_msgSend, [:id, :sel, :varargs], :long
229
+
230
+ def self.msgSend( id, selector, *args )
231
+ selector = self.sel(selector) if selector.is_a? String
232
+ NSObject.new( __msgSend( id, selector, *args ) )
233
+ end
234
+ def self.msgSend_ptr( id, selector, *args )
235
+ selector = self.sel(selector) if selector.is_a? String
236
+ __msgSend( id, selector, *args )
237
+ end
238
+ def self.msgSend_str( id, selector, *args )
239
+ selector = self.sel(selector) if selector.is_a? String
240
+ NSString.new( __msgSend( id, selector, *args ) )
241
+ end
242
+ def self.msgSend_int( id, selector, *args )
243
+ selector = self.sel(selector) if selector.is_a? String
244
+ __msgSend_int( id, selector, *args )
245
+ end
246
+ def self.msgSend_bool( id, selector, *args )
247
+ selector = self.sel(selector) if selector.is_a? String
248
+ ( __msgSend_int( id, selector, *args ) == 0 ) ? false : true
249
+ end
250
+
251
+ func :getClass, :objc_getClass, [:string], :id
252
+ func :class_replaceMethod, [:nsclass, :sel, :imp, :string], :imp
253
+
254
+ func :object_getClassName, [:id], :string
255
+ func :object_getInstanceVariable, [:id, :string, :pointer], :ivar
256
+ func :object_setInstanceVariable, [:id, :string, :pointer], :ivar
257
+
258
+ func :sel_registerName, [:string], :sel
259
+ func :sel_getName, [:sel], :string
260
+
261
+ def self.sel( name )
262
+ sel_registerName( name.to_s )
263
+ end
264
+
265
+ end
266
+
267
+
268
+ module Cocoa
269
+ extend NiceFFI::Library
270
+ load_library '/System/Library/Frameworks/Cocoa.framework/Cocoa'
271
+
272
+ func :NSApplicationLoad, [], :bool
273
+
274
+ func :NSPushAutoreleasePool, [], :void
275
+ func :NSPopAutoreleasePool, [], :void
276
+
277
+ NSApplicationLoad()
278
+ NSPushAutoreleasePool()
279
+
280
+ def self.NSApp
281
+ @nsapp ||= ObjC::NSClass("NSApplication").msg("sharedApplication")
282
+ end
283
+
284
+ class NSMenu < ObjC::NSObject
285
+ include Enumerable
286
+
287
+ def initialize( *args )
288
+ if args.empty?
289
+ super( ObjC::NSClass("NSMenu").msg_ptr("alloc") )
290
+ else
291
+ super( args[0] )
292
+ end
293
+ end
294
+
295
+ def initWithTitle( title )
296
+ msg( "initWithTitle:", FFI.find_type(:pointer), ObjC::NSString(title) )
297
+ self
298
+ end
299
+
300
+ def title
301
+ msg_str("title")
302
+ end
303
+
304
+ def title=( t )
305
+ msg("setTitle:", FFI.find_type(:pointer), ObjC::NSString(t))
306
+ end
307
+
308
+ def addItem( item )
309
+ msg("addItem:", FFI.find_type(:pointer), item)
310
+ self
311
+ end
312
+
313
+ def addItemWithTitle( title, action=nil, keyEquivalent="" )
314
+ ptr = FFI.find_type(:pointer)
315
+ action = ObjC.sel(action) if action.is_a? String
316
+ item = msg_ptr( "addItemWithTitle:action:keyEquivalent:",
317
+ ptr, ObjC::NSString(title),
318
+ ptr, action,
319
+ ptr, ObjC::NSString(keyEquivalent))
320
+ NSMenuItem.new(item)
321
+ end
322
+
323
+ def removeItem( item )
324
+ msg("removeItem:", FFI.find_type(:pointer), item)
325
+ self
326
+ end
327
+
328
+ def removeItemAtIndex( index )
329
+ msg("removeItemAtIndex:", FFI.find_type(:long), index)
330
+ self
331
+ end
332
+
333
+ def length
334
+ msg_int( "numberOfItems" )
335
+ end
336
+
337
+ def [](index)
338
+ Cocoa::NSMenuItem( msg_ptr("itemAtIndex:", FFI.find_type(:long), index) )
339
+ end
340
+
341
+ def each
342
+ length.times{ |i| yield self[i] }
343
+ end
344
+ end
345
+
346
+ def self.NSMenu( *args )
347
+ NSMenu.new( *args )
348
+ end
349
+
350
+
351
+ class NSMenuItem < ObjC::NSObject
352
+ def self.separatorItem
353
+ new( msg_ptr("separatorItem") )
354
+ end
355
+
356
+ def initialize( *args )
357
+ if args.empty?
358
+ super( ObjC::NSClass("NSMenuItem").msg_ptr("alloc") )
359
+ else
360
+ super( args[0] )
361
+ end
362
+ end
363
+
364
+ def initWithTitle( title, action=nil, keyEquivalent="" )
365
+ ptr = FFI.find_type(:pointer)
366
+ action = ObjC.sel(action) if action.is_a? String
367
+ msg( "initWithTitle:action:keyEquivalent:",
368
+ ptr, ObjC::NSString(title),
369
+ ptr, action,
370
+ ptr, ObjC::NSString(keyEquivalent))
371
+ self
372
+ end
373
+
374
+ def title
375
+ msg_str("title")
376
+ end
377
+
378
+ def title=( t )
379
+ msg("setTitle:", FFI.find_type(:pointer), ObjC::NSString(t))
380
+ end
381
+
382
+ def hasSubmenu?
383
+ msg_bool("hasSubmenu")
384
+ end
385
+
386
+ def submenu
387
+ Cocoa::NSMenu( msg_ptr("submenu") ) if hasSubmenu?
388
+ end
389
+
390
+ def submenu=( menu )
391
+ msg("setSubmenu:", FFI.find_type(:pointer), menu)
392
+ end
393
+ end
394
+
395
+ def self.NSMenuItem( *args )
396
+ NSMenuItem.new( *args )
397
+ end
398
+
399
+
400
+ attach_variable "vNSNibOwner", "NSNibOwner", :pointer
401
+ NSNibOwner =
402
+ ObjC::NSString( ObjC::NSString(self.vNSNibOwner).to_s )
403
+
404
+ attach_variable "vNSNibTopLevelObjects", "NSNibTopLevelObjects", :pointer
405
+ NSNibTopLevelObjects =
406
+ ObjC::NSString( ObjC::NSString(self.vNSNibTopLevelObjects).to_s )
407
+
408
+ NSAlphaShiftKeyMask = 1 << 16
409
+ NSShiftKeyMask = 1 << 17
410
+ NSControlKeyMask = 1 << 18
411
+ NSAlternateKeyMask = 1 << 19
412
+ NSCommandKeyMask = 1 << 20
413
+ NSNumericPadKeyMask = 1 << 21
414
+ NSHelpKeyMask = 1 << 22
415
+ NSFunctionKeyMask = 1 << 23
416
+ end
417
+
418
+
419
+ module HIServices
420
+ extend NiceFFI::Library
421
+ load_library '/System/Library/Frameworks/ApplicationServices.framework/Frameworks/HIServices.framework/HIServices'
422
+
423
+ class ProcessSerialNumber < NiceFFI::Struct
424
+ layout :highLongOfPSN, :ulong, :lowLongOfPSN, :ulong
425
+ end
426
+
427
+ KProcessTransformToForegroundApplication = 1
428
+
429
+ func :GetCurrentProcess, [:pointer], :long
430
+ func :TransformProcessType, [:pointer, :long], :long
431
+ func :SetFrontProcess, [:pointer], :long
432
+
433
+ # Does the magic to make the current process a front process.
434
+ def self.make_current_front
435
+ current = ProcessSerialNumber.new( [0, 0] )
436
+ GetCurrentProcess( current )
437
+ TransformProcessType(current,KProcessTransformToForegroundApplication)
438
+ SetFrontProcess( current )
439
+ end
440
+ end
441
+
442
+ end
443
+ end