misha-ruby-sdl-ffi 0.5

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,73 @@
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
+ class Joystick < NiceFFI::OpaqueStruct
34
+ #--
35
+ # SDL_Joystick struct (in C) has a hidden layout.
36
+ #++
37
+ end
38
+
39
+
40
+ sdl_func :NumJoysticks, [ ], :int
41
+ sdl_func :JoystickName, [ :int ], :string
42
+ sdl_func :JoystickOpen, [ :int ], Joystick.typed_pointer
43
+ sdl_func :JoystickOpened, [ :int ], :int
44
+ sdl_func :JoystickIndex, [ :pointer ], :int
45
+
46
+ sdl_func :JoystickNumAxes, [ :pointer ], :int
47
+ sdl_func :JoystickNumBalls, [ :pointer ], :int
48
+ sdl_func :JoystickNumHats, [ :pointer ], :int
49
+ sdl_func :JoystickNumButtons, [ :pointer ], :int
50
+
51
+ sdl_func :JoystickUpdate, [ ], :void
52
+ sdl_func :JoystickEventState, [ :int ], :int
53
+ sdl_func :JoystickGetAxis, [ :pointer, :int ], :int16
54
+
55
+
56
+ HAT_CENTERED = 0x00
57
+ HAT_UP = 0x01
58
+ HAT_RIGHT = 0x02
59
+ HAT_DOWN = 0x04
60
+ HAT_LEFT = 0x08
61
+ HAT_RIGHTUP = (HAT_RIGHT|HAT_UP)
62
+ HAT_RIGHTDOWN = (HAT_RIGHT|HAT_DOWN)
63
+ HAT_LEFTUP = (HAT_LEFT |HAT_UP)
64
+ HAT_LEFTDOWN = (HAT_LEFT |HAT_DOWN)
65
+
66
+
67
+ sdl_func :JoystickGetHat, [ :pointer, :int ], :uint8
68
+ sdl_func :JoystickGetBall, [ :pointer, :int, :pointer, :pointer ], :int
69
+ sdl_func :JoystickGetButton, [ :pointer, :int ], :uint8
70
+
71
+ sdl_func :JoystickClose, [ :pointer ], :void
72
+
73
+ end
@@ -0,0 +1,76 @@
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
+ class Keysym < NiceFFI::Struct
34
+ layout( :scancode, :uint8,
35
+ :sym, SDL::ENUM,
36
+ :mod, SDL::ENUM,
37
+ :unicode, :uint16 )
38
+ end
39
+
40
+ ALL_HOTKEYS = 0xFFFFFFFF
41
+
42
+
43
+ sdl_func :EnableUNICODE, [ :int ], :int
44
+
45
+
46
+ DEFAULT_REPEAT_DELAY = 500
47
+ DEFAULT_REPEAT_INTERVAL = 30
48
+
49
+ sdl_func :EnableKeyRepeat, [ :int, :int ], :int
50
+
51
+
52
+ func :__SDL_GetKeyRepeat, "SDL_GetKeyRepeat",
53
+ [ :buffer_out, :buffer_out ], :void
54
+
55
+ def self.GetKeyRepeat()
56
+ delay = FFI::Buffer.new( :int )
57
+ interval = FFI::Buffer.new( :int )
58
+ __SDL_GetKeyRepeat( delay, interval )
59
+ return [delay.get_int(0), interval.get_int(0)]
60
+ end
61
+
62
+
63
+ func :__SDL_GetKeyState, "SDL_GetKeyState", [ :buffer_out ], :pointer
64
+
65
+ def self.GetKeyState()
66
+ numkeys = FFI::Buffer.new( :int )
67
+ keys = __SDL_GetKeyState( numkeys )
68
+ return keys.get_array_of_uint8( 0, numkeys.get_int(0) )
69
+ end
70
+
71
+
72
+ sdl_func :GetModState, [ ], SDL::ENUM
73
+ sdl_func :SetModState, [ SDL::ENUM ], :void
74
+ sdl_func :GetKeyName, [ SDL::ENUM ], :string
75
+
76
+ end
@@ -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,446 @@
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
+ puts "wnet a here...."
162
+ callback :imp, [:id, :sel, :ivar], :id
163
+
164
+
165
+ class NSObject < NiceFFI::OpaqueStruct
166
+ def self.nsclassname; name.split("::")[-1]; end
167
+
168
+ # define msg, msg_ptr, msg_str, msg_int, msg_bool (and class methods)
169
+ ["", "_ptr", "_str", "_int", "_bool"].each do |suffix|
170
+ module_eval("
171
+ def msg#{suffix}( message, *args )
172
+ ObjC.msgSend#{suffix}( @pointer, message, *args )
173
+ end
174
+
175
+ def self.msg#{suffix}( message, *args )
176
+ ObjC.msgSend#{suffix}( ObjC.NSClass(self.nsclassname),
177
+ message, *args )
178
+ end")
179
+ end
180
+
181
+ def inspect; msg_str("description").to_s; end
182
+ def nsclassname; ObjC.object_getClassName(@pointer); end
183
+ def release; msg("release"); end
184
+ end
185
+
186
+ def self.NSObject( *args )
187
+ NSObject.new( *args )
188
+ end
189
+
190
+
191
+ class NSClass < NSObject
192
+ def initialize( str_or_ptr )
193
+ if str_or_ptr.is_a? String
194
+ super( ObjC.getClass(str_or_ptr) )
195
+ else
196
+ super
197
+ end
198
+ end
199
+ end
200
+
201
+ def self.NSClass( *args )
202
+ NSClass.new( *args )
203
+ end
204
+
205
+
206
+ class NSString < NSObject
207
+ def initialize( str_or_ptr )
208
+ if str_or_ptr.is_a? String
209
+ super( ObjC::NSClass("NSString").\
210
+ msg_ptr("stringWithUTF8String:",
211
+ FFI.find_type(:string), str_or_ptr) )
212
+ else
213
+ super
214
+ end
215
+ end
216
+
217
+ def to_s
218
+ str = msg_ptr( "UTF8String" )
219
+ (str.null?) ? "(NULL)" : str.read_string()
220
+ end
221
+ end
222
+
223
+ def self.NSString( *args )
224
+ NSString.new( *args )
225
+ end
226
+
227
+
228
+ func :__msgSend, :objc_msgSend, [:id, :sel, :varargs], :id
229
+ func :__msgSend_int, :objc_msgSend, [:id, :sel, :varargs], :long
230
+
231
+ def self.msgSend( id, selector, *args )
232
+ selector = self.sel(selector) if selector.is_a? String
233
+ NSObject.new( __msgSend( id, selector, *args ) )
234
+ end
235
+ def self.msgSend_ptr( id, selector, *args )
236
+ selector = self.sel(selector) if selector.is_a? String
237
+ __msgSend( id, selector, *args )
238
+ end
239
+ def self.msgSend_str( id, selector, *args )
240
+ selector = self.sel(selector) if selector.is_a? String
241
+ NSString.new( __msgSend( id, selector, *args ) )
242
+ end
243
+ def self.msgSend_int( id, selector, *args )
244
+ selector = self.sel(selector) if selector.is_a? String
245
+ __msgSend_int( id, selector, *args )
246
+ end
247
+ def self.msgSend_bool( id, selector, *args )
248
+ selector = self.sel(selector) if selector.is_a? String
249
+ ( __msgSend_int( id, selector, *args ) == 0 ) ? false : true
250
+ end
251
+
252
+ func :getClass, :objc_getClass, [:string], :id
253
+ func :class_replaceMethod, [:nsclass, :sel, :imp, :string], :imp
254
+
255
+ func :object_getClassName, [:id], :string
256
+ func :object_getInstanceVariable, [:id, :string, :pointer], :ivar
257
+ func :object_setInstanceVariable, [:id, :string, :pointer], :ivar
258
+
259
+ func :sel_registerName, [:string], :sel
260
+ func :sel_getName, [:sel], :string
261
+
262
+ def self.sel( name )
263
+ sel_registerName( name.to_s )
264
+ end
265
+
266
+ end
267
+
268
+
269
+ module Cocoa
270
+ extend NiceFFI::Library
271
+ load_library '/System/Library/Frameworks/Cocoa.framework/Cocoa'
272
+
273
+ func :NSApplicationLoad, [], :bool
274
+
275
+ func :NSPushAutoreleasePool, [], :void
276
+ func :NSPopAutoreleasePool, [], :void
277
+
278
+ NSApplicationLoad()
279
+ NSPushAutoreleasePool()
280
+
281
+ def self.NSApp
282
+ @nsapp ||= ObjC::NSClass("NSApplication").msg("sharedApplication")
283
+ end
284
+
285
+ class NSMenu < ObjC::NSObject
286
+ include Enumerable
287
+
288
+ def initialize( *args )
289
+ if args.empty?
290
+ super( ObjC::NSClass("NSMenu").msg_ptr("alloc") )
291
+ else
292
+ super( args[0] )
293
+ end
294
+ end
295
+
296
+ def initWithTitle( title )
297
+ msg( "initWithTitle:", FFI.find_type(:pointer), ObjC::NSString(title) )
298
+ self
299
+ end
300
+
301
+ def title
302
+ msg_str("title")
303
+ end
304
+
305
+ def title=( t )
306
+ msg("setTitle:", FFI.find_type(:pointer), ObjC::NSString(t))
307
+ end
308
+
309
+ def addItem( item )
310
+ msg("addItem:", FFI.find_type(:pointer), item)
311
+ self
312
+ end
313
+
314
+ def addItemWithTitle( title, action=nil, keyEquivalent="" )
315
+ ptr = FFI.find_type(:pointer)
316
+ action = ObjC.sel(action) if action.is_a? String
317
+ item = msg_ptr( "addItemWithTitle:action:keyEquivalent:",
318
+ ptr, ObjC::NSString(title),
319
+ ptr, action,
320
+ ptr, ObjC::NSString(keyEquivalent))
321
+ NSMenuItem.new(item)
322
+ end
323
+
324
+ def removeItem( item )
325
+ msg("removeItem:", FFI.find_type(:pointer), item)
326
+ self
327
+ end
328
+
329
+ def removeItemAtIndex( index )
330
+ msg("removeItemAtIndex:", FFI.find_type(:long), index)
331
+ self
332
+ end
333
+
334
+ def length
335
+ msg_int( "numberOfItems" )
336
+ end
337
+
338
+ def [](index)
339
+ Cocoa::NSMenuItem( msg_ptr("itemAtIndex:", FFI.find_type(:long), index) )
340
+ end
341
+
342
+ def each
343
+ length.times{ |i| yield self[i] }
344
+ end
345
+ end
346
+
347
+ def self.NSMenu( *args )
348
+ NSMenu.new( *args )
349
+ end
350
+
351
+
352
+ class NSMenuItem < ObjC::NSObject
353
+ def self.separatorItem
354
+ new( msg_ptr("separatorItem") )
355
+ end
356
+
357
+ def initialize( *args )
358
+ if args.empty?
359
+ super( ObjC::NSClass("NSMenuItem").msg_ptr("alloc") )
360
+ else
361
+ super( args[0] )
362
+ end
363
+ end
364
+
365
+ def initWithTitle( title, action=nil, keyEquivalent="" )
366
+ ptr = FFI.find_type(:pointer)
367
+ action = ObjC.sel(action) if action.is_a? String
368
+ msg( "initWithTitle:action:keyEquivalent:",
369
+ ptr, ObjC::NSString(title),
370
+ ptr, action,
371
+ ptr, ObjC::NSString(keyEquivalent))
372
+ self
373
+ end
374
+
375
+ def title
376
+ msg_str("title")
377
+ end
378
+
379
+ def title=( t )
380
+ msg("setTitle:", FFI.find_type(:pointer), ObjC::NSString(t))
381
+ end
382
+
383
+ def hasSubmenu?
384
+ msg_bool("hasSubmenu")
385
+ end
386
+
387
+ def submenu
388
+ Cocoa::NSMenu( msg_ptr("submenu") ) if hasSubmenu?
389
+ end
390
+
391
+ def submenu=( menu )
392
+ msg("setSubmenu:", FFI.find_type(:pointer), menu)
393
+ end
394
+ end
395
+
396
+ def self.NSMenuItem( *args )
397
+ NSMenuItem.new( *args )
398
+ end
399
+
400
+
401
+ attach_variable "vNSNibOwner", "NSNibOwner", :pointer
402
+ NSNibOwner =
403
+ ObjC::NSString( ObjC::NSString(self.vNSNibOwner).to_s )
404
+
405
+ attach_variable "vNSNibTopLevelObjects", "NSNibTopLevelObjects", :pointer
406
+ NSNibTopLevelObjects =
407
+ ObjC::NSString( ObjC::NSString(self.vNSNibTopLevelObjects).to_s )
408
+
409
+ NSAlphaShiftKeyMask = 1 << 16
410
+ NSShiftKeyMask = 1 << 17
411
+ NSControlKeyMask = 1 << 18
412
+ NSAlternateKeyMask = 1 << 19
413
+ NSCommandKeyMask = 1 << 20
414
+ NSNumericPadKeyMask = 1 << 21
415
+ NSHelpKeyMask = 1 << 22
416
+ NSFunctionKeyMask = 1 << 23
417
+ end
418
+
419
+
420
+ module HIServices
421
+ extend NiceFFI::Library
422
+ load_library '/System/Library/Frameworks/ApplicationServices.framework/Frameworks/HIServices.framework/HIServices'
423
+
424
+ class ProcessSerialNumber < NiceFFI::Struct
425
+ layout :highLongOfPSN, :ulong, :lowLongOfPSN, :ulong
426
+ end
427
+
428
+ KProcessTransformToForegroundApplication = 1
429
+
430
+ func :GetCurrentProcess, [:pointer], :long
431
+ func :TransformProcessType, [:pointer, :long], :long
432
+ func :SetFrontProcess, [:pointer], :long
433
+
434
+ # Does the magic to make the current process a front process.
435
+ def self.make_current_front
436
+ current = ProcessSerialNumber.new( [0, 0] )
437
+ GetCurrentProcess( current )
438
+ TransformProcessType(current,KProcessTransformToForegroundApplication)
439
+ SetFrontProcess( current )
440
+ end
441
+ end
442
+
443
+ end
444
+ end
445
+
446
+