hybridgroup-ruby-sdl-ffi 0.4.1
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.
- checksums.yaml +7 -0
- data/ChangeLog.txt +2460 -0
- data/NEWS.rdoc +77 -0
- data/README.rdoc +84 -0
- data/lib/ruby-sdl-ffi/gfx/blitfunc.rb +56 -0
- data/lib/ruby-sdl-ffi/gfx/framerate.rb +51 -0
- data/lib/ruby-sdl-ffi/gfx/imagefilter.rb +176 -0
- data/lib/ruby-sdl-ffi/gfx/primitives.rb +251 -0
- data/lib/ruby-sdl-ffi/gfx/rotozoom.rb +108 -0
- data/lib/ruby-sdl-ffi/gfx.rb +56 -0
- data/lib/ruby-sdl-ffi/image.rb +90 -0
- data/lib/ruby-sdl-ffi/mixer.rb +215 -0
- data/lib/ruby-sdl-ffi/sdl/audio.rb +139 -0
- data/lib/ruby-sdl-ffi/sdl/cdrom.rb +87 -0
- data/lib/ruby-sdl-ffi/sdl/core.rb +129 -0
- data/lib/ruby-sdl-ffi/sdl/event.rb +375 -0
- data/lib/ruby-sdl-ffi/sdl/joystick.rb +73 -0
- data/lib/ruby-sdl-ffi/sdl/keyboard.rb +76 -0
- data/lib/ruby-sdl-ffi/sdl/keysyms.rb +282 -0
- data/lib/ruby-sdl-ffi/sdl/mac.rb +443 -0
- data/lib/ruby-sdl-ffi/sdl/mouse.rb +106 -0
- data/lib/ruby-sdl-ffi/sdl/mutex.rb +57 -0
- data/lib/ruby-sdl-ffi/sdl/rwops.rb +137 -0
- data/lib/ruby-sdl-ffi/sdl/timer.rb +47 -0
- data/lib/ruby-sdl-ffi/sdl/video.rb +513 -0
- data/lib/ruby-sdl-ffi/sdl.rb +81 -0
- data/lib/ruby-sdl-ffi/ttf.rb +257 -0
- data/lib/ruby-sdl-ffi.rb +56 -0
- metadata +95 -0
@@ -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
|