misha-ruby-sdl-ffi 0.5

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.
@@ -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
+