hybridgroup-ruby-sdl-ffi 0.4.1
Sign up to get free protection for your applications and to get access to all the features.
- 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
|