Mercurial > sdl-ios-xcode
comparison src/video/quartz/SDL_QuartzEvents.m @ 1662:782fd950bd46 SDL-1.3
Revamp of the video system in progress - adding support for multiple displays, multiple windows, and a full video mode selection API.
WARNING: None of the video drivers have been updated for the new API yet! The API is still under design and very fluid.
The code is now run through a consistent indent format:
indent -i4 -nut -nsc -br -ce
The headers are being converted to automatically generate doxygen documentation.
author | Sam Lantinga <slouken@libsdl.org> |
---|---|
date | Sun, 28 May 2006 13:04:16 +0000 |
parents | ef4a796e7f24 |
children |
comparison
equal
deleted
inserted
replaced
1661:281d3f4870e5 | 1662:782fd950bd46 |
---|---|
21 */ | 21 */ |
22 #include "SDL_config.h" | 22 #include "SDL_config.h" |
23 | 23 |
24 #include "SDL_QuartzVideo.h" | 24 #include "SDL_QuartzVideo.h" |
25 | 25 |
26 #include <IOKit/IOMessage.h> /* For wake from sleep detection */ | 26 #include <IOKit/IOMessage.h> /* For wake from sleep detection */ |
27 #include <IOKit/pwr_mgt/IOPMLib.h> /* For wake from sleep detection */ | 27 #include <IOKit/pwr_mgt/IOPMLib.h> /* For wake from sleep detection */ |
28 #include "SDL_QuartzKeys.h" | 28 #include "SDL_QuartzKeys.h" |
29 | 29 |
30 /* | 30 /* |
31 * In Panther, this header defines device dependent masks for | 31 * In Panther, this header defines device dependent masks for |
32 * right side keys. These definitions only exist in Panther, but | 32 * right side keys. These definitions only exist in Panther, but |
37 /* | 37 /* |
38 * These are not defined before Panther. To keep the code compiling | 38 * These are not defined before Panther. To keep the code compiling |
39 * on systems without these, I will define if they don't exist. | 39 * on systems without these, I will define if they don't exist. |
40 */ | 40 */ |
41 #ifndef NX_DEVICERCTLKEYMASK | 41 #ifndef NX_DEVICERCTLKEYMASK |
42 #define NX_DEVICELCTLKEYMASK 0x00000001 | 42 #define NX_DEVICELCTLKEYMASK 0x00000001 |
43 #endif | 43 #endif |
44 #ifndef NX_DEVICELSHIFTKEYMASK | 44 #ifndef NX_DEVICELSHIFTKEYMASK |
45 #define NX_DEVICELSHIFTKEYMASK 0x00000002 | 45 #define NX_DEVICELSHIFTKEYMASK 0x00000002 |
46 #endif | 46 #endif |
47 #ifndef NX_DEVICERSHIFTKEYMASK | 47 #ifndef NX_DEVICERSHIFTKEYMASK |
48 #define NX_DEVICERSHIFTKEYMASK 0x00000004 | 48 #define NX_DEVICERSHIFTKEYMASK 0x00000004 |
49 #endif | 49 #endif |
50 #ifndef NX_DEVICELCMDKEYMASK | 50 #ifndef NX_DEVICELCMDKEYMASK |
51 #define NX_DEVICELCMDKEYMASK 0x00000008 | 51 #define NX_DEVICELCMDKEYMASK 0x00000008 |
52 #endif | 52 #endif |
53 #ifndef NX_DEVICERCMDKEYMASK | 53 #ifndef NX_DEVICERCMDKEYMASK |
54 #define NX_DEVICERCMDKEYMASK 0x00000010 | 54 #define NX_DEVICERCMDKEYMASK 0x00000010 |
55 #endif | 55 #endif |
56 #ifndef NX_DEVICELALTKEYMASK | 56 #ifndef NX_DEVICELALTKEYMASK |
57 #define NX_DEVICELALTKEYMASK 0x00000020 | 57 #define NX_DEVICELALTKEYMASK 0x00000020 |
58 #endif | 58 #endif |
59 #ifndef NX_DEVICERALTKEYMASK | 59 #ifndef NX_DEVICERALTKEYMASK |
60 #define NX_DEVICERALTKEYMASK 0x00000040 | 60 #define NX_DEVICERALTKEYMASK 0x00000040 |
61 #endif | 61 #endif |
62 #ifndef NX_DEVICERCTLKEYMASK | 62 #ifndef NX_DEVICERCTLKEYMASK |
63 #define NX_DEVICERCTLKEYMASK 0x00002000 | 63 #define NX_DEVICERCTLKEYMASK 0x00002000 |
64 #endif | 64 #endif |
65 | 65 |
66 void QZ_InitOSKeymap (_THIS) { | 66 void |
67 QZ_InitOSKeymap (_THIS) | |
68 { | |
67 const void *KCHRPtr; | 69 const void *KCHRPtr; |
68 UInt32 state; | 70 UInt32 state; |
69 UInt32 value; | 71 UInt32 value; |
70 int i; | 72 int i; |
71 int world = SDLK_WORLD_0; | 73 int world = SDLK_WORLD_0; |
72 | 74 |
73 for ( i=0; i<SDL_TABLESIZE(keymap); ++i ) | 75 for (i = 0; i < SDL_TABLESIZE (keymap); ++i) |
74 keymap[i] = SDLK_UNKNOWN; | 76 keymap[i] = SDLK_UNKNOWN; |
75 | 77 |
76 /* This keymap is almost exactly the same as the OS 9 one */ | 78 /* This keymap is almost exactly the same as the OS 9 one */ |
77 keymap[QZ_ESCAPE] = SDLK_ESCAPE; | 79 keymap[QZ_ESCAPE] = SDLK_ESCAPE; |
78 keymap[QZ_F1] = SDLK_F1; | 80 keymap[QZ_F1] = SDLK_F1; |
180 keymap[QZ_KP0] = SDLK_KP0; | 182 keymap[QZ_KP0] = SDLK_KP0; |
181 keymap[QZ_KP_PERIOD] = SDLK_KP_PERIOD; | 183 keymap[QZ_KP_PERIOD] = SDLK_KP_PERIOD; |
182 keymap[QZ_IBOOK_ENTER] = SDLK_KP_ENTER; | 184 keymap[QZ_IBOOK_ENTER] = SDLK_KP_ENTER; |
183 keymap[QZ_IBOOK_RIGHT] = SDLK_RIGHT; | 185 keymap[QZ_IBOOK_RIGHT] = SDLK_RIGHT; |
184 keymap[QZ_IBOOK_DOWN] = SDLK_DOWN; | 186 keymap[QZ_IBOOK_DOWN] = SDLK_DOWN; |
185 keymap[QZ_IBOOK_UP] = SDLK_UP; | 187 keymap[QZ_IBOOK_UP] = SDLK_UP; |
186 keymap[QZ_IBOOK_LEFT] = SDLK_LEFT; | 188 keymap[QZ_IBOOK_LEFT] = SDLK_LEFT; |
187 | 189 |
188 /* | 190 /* |
189 Up there we setup a static scancode->keysym map. However, it will not | 191 Up there we setup a static scancode->keysym map. However, it will not |
190 work very well on international keyboard. Hence we now query MacOS | 192 work very well on international keyboard. Hence we now query MacOS |
191 for its own keymap to adjust our own mapping table. However, this is | 193 for its own keymap to adjust our own mapping table. However, this is |
192 basically only useful for ascii char keys. This is also the reason | 194 basically only useful for ascii char keys. This is also the reason |
193 why we keep the static table, too. | 195 why we keep the static table, too. |
194 */ | 196 */ |
195 | 197 |
196 /* Get a pointer to the systems cached KCHR */ | 198 /* Get a pointer to the systems cached KCHR */ |
197 KCHRPtr = (void *)GetScriptManagerVariable(smKCHRCache); | 199 KCHRPtr = (void *) GetScriptManagerVariable (smKCHRCache); |
198 if (KCHRPtr) | 200 if (KCHRPtr) { |
199 { | |
200 /* Loop over all 127 possible scan codes */ | 201 /* Loop over all 127 possible scan codes */ |
201 for (i = 0; i < 0x7F; i++) | 202 for (i = 0; i < 0x7F; i++) { |
202 { | |
203 /* We pretend a clean start to begin with (i.e. no dead keys active */ | 203 /* We pretend a clean start to begin with (i.e. no dead keys active */ |
204 state = 0; | 204 state = 0; |
205 | 205 |
206 /* Now translate the key code to a key value */ | 206 /* Now translate the key code to a key value */ |
207 value = KeyTranslate(KCHRPtr, i, &state) & 0xff; | 207 value = KeyTranslate (KCHRPtr, i, &state) & 0xff; |
208 | 208 |
209 /* If the state become 0, it was a dead key. We need to translate again, | 209 /* If the state become 0, it was a dead key. We need to translate again, |
210 passing in the new state, to get the actual key value */ | 210 passing in the new state, to get the actual key value */ |
211 if (state != 0) | 211 if (state != 0) |
212 value = KeyTranslate(KCHRPtr, i, &state) & 0xff; | 212 value = KeyTranslate (KCHRPtr, i, &state) & 0xff; |
213 | 213 |
214 /* Now we should have an ascii value, or 0. Try to figure out to which SDL symbol it maps */ | 214 /* Now we should have an ascii value, or 0. Try to figure out to which SDL symbol it maps */ |
215 if (value >= 128) /* Some non-ASCII char, map it to SDLK_WORLD_* */ | 215 if (value >= 128) /* Some non-ASCII char, map it to SDLK_WORLD_* */ |
216 keymap[i] = world++; | 216 keymap[i] = world++; |
217 else if (value >= 32) /* non-control ASCII char */ | 217 else if (value >= 32) /* non-control ASCII char */ |
218 keymap[i] = value; | 218 keymap[i] = value; |
219 } | 219 } |
220 } | 220 } |
221 | 221 |
222 /* | 222 /* |
223 The keypad codes are re-setup here, because the loop above cannot | 223 The keypad codes are re-setup here, because the loop above cannot |
224 distinguish between a key on the keypad and a regular key. We maybe | 224 distinguish between a key on the keypad and a regular key. We maybe |
225 could get around this problem in another fashion: NSEvent's flags | 225 could get around this problem in another fashion: NSEvent's flags |
226 include a "NSNumericPadKeyMask" bit; we could check that and modify | 226 include a "NSNumericPadKeyMask" bit; we could check that and modify |
227 the symbol we return on the fly. However, this flag seems to exhibit | 227 the symbol we return on the fly. However, this flag seems to exhibit |
228 some weird behaviour related to the num lock key | 228 some weird behaviour related to the num lock key |
229 */ | 229 */ |
230 keymap[QZ_KP0] = SDLK_KP0; | 230 keymap[QZ_KP0] = SDLK_KP0; |
231 keymap[QZ_KP1] = SDLK_KP1; | 231 keymap[QZ_KP1] = SDLK_KP1; |
232 keymap[QZ_KP2] = SDLK_KP2; | 232 keymap[QZ_KP2] = SDLK_KP2; |
233 keymap[QZ_KP3] = SDLK_KP3; | 233 keymap[QZ_KP3] = SDLK_KP3; |
234 keymap[QZ_KP4] = SDLK_KP4; | 234 keymap[QZ_KP4] = SDLK_KP4; |
244 keymap[QZ_KP_DIVIDE] = SDLK_KP_DIVIDE; | 244 keymap[QZ_KP_DIVIDE] = SDLK_KP_DIVIDE; |
245 keymap[QZ_KP_MULTIPLY] = SDLK_KP_MULTIPLY; | 245 keymap[QZ_KP_MULTIPLY] = SDLK_KP_MULTIPLY; |
246 keymap[QZ_KP_ENTER] = SDLK_KP_ENTER; | 246 keymap[QZ_KP_ENTER] = SDLK_KP_ENTER; |
247 } | 247 } |
248 | 248 |
249 static void QZ_DoKey (_THIS, int state, NSEvent *event) { | 249 static void |
250 QZ_DoKey (_THIS, int state, NSEvent * event) | |
251 { | |
250 | 252 |
251 NSString *chars; | 253 NSString *chars; |
252 unsigned int numChars; | 254 unsigned int numChars; |
253 SDL_keysym key; | 255 SDL_keysym key; |
254 | 256 |
255 /* | 257 /* |
256 A key event can contain multiple characters, | 258 A key event can contain multiple characters, |
257 or no characters at all. In most cases, it | 259 or no characters at all. In most cases, it |
258 will contain a single character. If it contains | 260 will contain a single character. If it contains |
259 0 characters, we'll use 0 as the unicode. If it | 261 0 characters, we'll use 0 as the unicode. If it |
260 contains multiple characters, we'll use 0 as | 262 contains multiple characters, we'll use 0 as |
261 the scancode/keysym. | 263 the scancode/keysym. |
262 */ | 264 */ |
263 chars = [ event characters ]; | 265 chars =[event characters]; |
264 numChars = [ chars length ]; | 266 numChars =[chars length]; |
265 | 267 |
266 if (numChars == 1) { | 268 if (numChars == 1) { |
267 | 269 |
268 key.scancode = [ event keyCode ]; | 270 key.scancode =[event keyCode]; |
269 key.sym = keymap [ key.scancode ]; | 271 key.sym = keymap[key.scancode]; |
270 key.unicode = [ chars characterAtIndex:0 ]; | 272 key.unicode =[chars characterAtIndex:0]; |
271 key.mod = KMOD_NONE; | 273 key.mod = KMOD_NONE; |
272 | 274 |
273 SDL_PrivateKeyboard (state, &key); | 275 SDL_PrivateKeyboard (state, &key); |
274 } | 276 } else if (numChars == 0) { |
275 else if (numChars == 0) { | 277 |
276 | 278 key.scancode =[event keyCode]; |
277 key.scancode = [ event keyCode ]; | 279 key.sym = keymap[key.scancode]; |
278 key.sym = keymap [ key.scancode ]; | 280 key.unicode = 0; |
279 key.unicode = 0; | 281 key.mod = KMOD_NONE; |
280 key.mod = KMOD_NONE; | |
281 | 282 |
282 SDL_PrivateKeyboard (state, &key); | 283 SDL_PrivateKeyboard (state, &key); |
283 } | 284 } else { /* (numChars > 1) */ |
284 else /* (numChars > 1) */ { | 285 |
285 | 286 |
286 int i; | 287 int i; |
287 for (i = 0; i < numChars; i++) { | 288 for (i = 0; i < numChars; i++) { |
288 | 289 |
289 key.scancode = 0; | 290 key.scancode = 0; |
290 key.sym = 0; | 291 key.sym = 0; |
291 key.unicode = [ chars characterAtIndex:i]; | 292 key.unicode =[chars characterAtIndex:i]; |
292 key.mod = KMOD_NONE; | 293 key.mod = KMOD_NONE; |
293 | 294 |
294 SDL_PrivateKeyboard (state, &key); | 295 SDL_PrivateKeyboard (state, &key); |
295 } | 296 } |
296 } | 297 } |
297 | 298 |
298 if (SDL_getenv ("SDL_ENABLEAPPEVENTS")) | 299 if (SDL_getenv ("SDL_ENABLEAPPEVENTS")) |
299 [ NSApp sendEvent:event ]; | 300 [NSApp sendEvent:event]; |
300 } | 301 } |
301 | 302 |
302 /* This is the original behavior, before support was added for | 303 /* This is the original behavior, before support was added for |
303 * differentiating between left and right versions of the keys. | 304 * differentiating between left and right versions of the keys. |
304 */ | 305 */ |
305 static void QZ_DoUnsidedModifiers (_THIS, unsigned int newMods) { | 306 static void |
306 | 307 QZ_DoUnsidedModifiers (_THIS, unsigned int newMods) |
307 const int mapping[] = { SDLK_CAPSLOCK, SDLK_LSHIFT, SDLK_LCTRL, SDLK_LALT, SDLK_LMETA }; | 308 { |
309 | |
310 const int mapping[] = | |
311 { SDLK_CAPSLOCK, SDLK_LSHIFT, SDLK_LCTRL, SDLK_LALT, SDLK_LMETA }; | |
308 | 312 |
309 int i; | 313 int i; |
310 int bit; | 314 int bit; |
311 SDL_keysym key; | 315 SDL_keysym key; |
312 | 316 |
313 key.scancode = 0; | 317 key.scancode = 0; |
314 key.sym = SDLK_UNKNOWN; | 318 key.sym = SDLK_UNKNOWN; |
315 key.unicode = 0; | 319 key.unicode = 0; |
316 key.mod = KMOD_NONE; | 320 key.mod = KMOD_NONE; |
317 | 321 |
318 /* Iterate through the bits, testing each against the current modifiers */ | 322 /* Iterate through the bits, testing each against the current modifiers */ |
319 for (i = 0, bit = NSAlphaShiftKeyMask; bit <= NSCommandKeyMask; bit <<= 1, ++i) { | 323 for (i = 0, bit = NSAlphaShiftKeyMask; bit <= NSCommandKeyMask; |
324 bit <<= 1, ++i) { | |
320 | 325 |
321 unsigned int currentMask, newMask; | 326 unsigned int currentMask, newMask; |
322 | 327 |
323 currentMask = current_mods & bit; | 328 currentMask = current_mods & bit; |
324 newMask = newMods & bit; | 329 newMask = newMods & bit; |
325 | 330 |
326 if ( currentMask && | 331 if (currentMask && currentMask != newMask) { /* modifier up event */ |
327 currentMask != newMask ) { /* modifier up event */ | 332 |
328 | 333 key.sym = mapping[i]; |
329 key.sym = mapping[i]; | 334 /* If this was Caps Lock, we need some additional voodoo to make SDL happy */ |
330 /* If this was Caps Lock, we need some additional voodoo to make SDL happy */ | 335 if (bit == NSAlphaShiftKeyMask) |
331 if (bit == NSAlphaShiftKeyMask) | 336 SDL_PrivateKeyboard (SDL_PRESSED, &key); |
332 SDL_PrivateKeyboard (SDL_PRESSED, &key); | 337 SDL_PrivateKeyboard (SDL_RELEASED, &key); |
333 SDL_PrivateKeyboard (SDL_RELEASED, &key); | 338 } else if (newMask && currentMask != newMask) { /* modifier down event */ |
334 } | 339 |
335 else if ( newMask && | 340 key.sym = mapping[i]; |
336 currentMask != newMask ) { /* modifier down event */ | 341 SDL_PrivateKeyboard (SDL_PRESSED, &key); |
337 | 342 /* If this was Caps Lock, we need some additional voodoo to make SDL happy */ |
338 key.sym = mapping[i]; | 343 if (bit == NSAlphaShiftKeyMask) |
339 SDL_PrivateKeyboard (SDL_PRESSED, &key); | 344 SDL_PrivateKeyboard (SDL_RELEASED, &key); |
340 /* If this was Caps Lock, we need some additional voodoo to make SDL happy */ | |
341 if (bit == NSAlphaShiftKeyMask) | |
342 SDL_PrivateKeyboard (SDL_RELEASED, &key); | |
343 } | 345 } |
344 } | 346 } |
345 } | 347 } |
346 | 348 |
347 /* This is a helper function for QZ_HandleModifierSide. This | 349 /* This is a helper function for QZ_HandleModifierSide. This |
348 * function reverts back to behavior before the distinction between | 350 * function reverts back to behavior before the distinction between |
349 * sides was made. | 351 * sides was made. |
350 */ | 352 */ |
351 static void QZ_HandleNonDeviceModifier ( _THIS, unsigned int device_independent_mask, unsigned int newMods, unsigned int key_sym) { | 353 static void |
354 QZ_HandleNonDeviceModifier (_THIS, unsigned int device_independent_mask, | |
355 unsigned int newMods, unsigned int key_sym) | |
356 { | |
352 unsigned int currentMask, newMask; | 357 unsigned int currentMask, newMask; |
353 SDL_keysym key; | 358 SDL_keysym key; |
354 | 359 |
355 key.scancode = 0; | 360 key.scancode = 0; |
356 key.sym = key_sym; | 361 key.sym = key_sym; |
357 key.unicode = 0; | 362 key.unicode = 0; |
358 key.mod = KMOD_NONE; | 363 key.mod = KMOD_NONE; |
359 | 364 |
360 /* Isolate just the bits we care about in the depedent bits so we can | 365 /* Isolate just the bits we care about in the depedent bits so we can |
361 * figure out what changed | 366 * figure out what changed |
362 */ | 367 */ |
363 currentMask = current_mods & device_independent_mask; | 368 currentMask = current_mods & device_independent_mask; |
364 newMask = newMods & device_independent_mask; | 369 newMask = newMods & device_independent_mask; |
365 | 370 |
366 if ( currentMask && | 371 if (currentMask && currentMask != newMask) { /* modifier up event */ |
367 currentMask != newMask ) { /* modifier up event */ | 372 SDL_PrivateKeyboard (SDL_RELEASED, &key); |
368 SDL_PrivateKeyboard (SDL_RELEASED, &key); | 373 } else if (newMask && currentMask != newMask) { /* modifier down event */ |
369 } | 374 SDL_PrivateKeyboard (SDL_PRESSED, &key); |
370 else if ( newMask && | |
371 currentMask != newMask ) { /* modifier down event */ | |
372 SDL_PrivateKeyboard (SDL_PRESSED, &key); | |
373 } | 375 } |
374 } | 376 } |
375 | 377 |
376 /* This is a helper function for QZ_HandleModifierSide. | 378 /* This is a helper function for QZ_HandleModifierSide. |
377 * This function sets the actual SDL_PrivateKeyboard event. | 379 * This function sets the actual SDL_PrivateKeyboard event. |
378 */ | 380 */ |
379 static void QZ_HandleModifierOneSide ( _THIS, unsigned int newMods, | 381 static void |
380 unsigned int key_sym, | 382 QZ_HandleModifierOneSide (_THIS, unsigned int newMods, |
381 unsigned int sided_device_dependent_mask ) { | 383 unsigned int key_sym, |
382 | 384 unsigned int sided_device_dependent_mask) |
385 { | |
386 | |
383 SDL_keysym key; | 387 SDL_keysym key; |
384 unsigned int current_dep_mask, new_dep_mask; | 388 unsigned int current_dep_mask, new_dep_mask; |
385 | 389 |
386 key.scancode = 0; | 390 key.scancode = 0; |
387 key.sym = key_sym; | 391 key.sym = key_sym; |
388 key.unicode = 0; | 392 key.unicode = 0; |
389 key.mod = KMOD_NONE; | 393 key.mod = KMOD_NONE; |
390 | 394 |
391 /* Isolate just the bits we care about in the depedent bits so we can | 395 /* Isolate just the bits we care about in the depedent bits so we can |
392 * figure out what changed | 396 * figure out what changed |
393 */ | 397 */ |
394 current_dep_mask = current_mods & sided_device_dependent_mask; | 398 current_dep_mask = current_mods & sided_device_dependent_mask; |
395 new_dep_mask = newMods & sided_device_dependent_mask; | 399 new_dep_mask = newMods & sided_device_dependent_mask; |
396 | 400 |
397 /* We now know that this side bit flipped. But we don't know if | 401 /* We now know that this side bit flipped. But we don't know if |
398 * it went pressed to released or released to pressed, so we must | 402 * it went pressed to released or released to pressed, so we must |
399 * find out which it is. | 403 * find out which it is. |
400 */ | 404 */ |
401 if( new_dep_mask && | 405 if (new_dep_mask && current_dep_mask != new_dep_mask) { |
402 current_dep_mask != new_dep_mask ) { | |
403 /* Modifier down event */ | 406 /* Modifier down event */ |
404 SDL_PrivateKeyboard (SDL_PRESSED, &key); | 407 SDL_PrivateKeyboard (SDL_PRESSED, &key); |
405 } | 408 } else { /* Modifier up event */ |
406 else /* Modifier up event */ { | 409 |
407 SDL_PrivateKeyboard (SDL_RELEASED, &key); | 410 SDL_PrivateKeyboard (SDL_RELEASED, &key); |
408 } | 411 } |
409 } | 412 } |
410 | 413 |
411 /* This is a helper function for QZ_DoSidedModifiers. | 414 /* This is a helper function for QZ_DoSidedModifiers. |
412 * This function will figure out if the modifier key is the left or right side, | 415 * This function will figure out if the modifier key is the left or right side, |
413 * e.g. left-shift vs right-shift. | 416 * e.g. left-shift vs right-shift. |
414 */ | 417 */ |
415 static void QZ_HandleModifierSide ( _THIS, int device_independent_mask, | 418 static void |
416 unsigned int newMods, | 419 QZ_HandleModifierSide (_THIS, int device_independent_mask, |
417 unsigned int left_key_sym, | 420 unsigned int newMods, |
418 unsigned int right_key_sym, | 421 unsigned int left_key_sym, |
419 unsigned int left_device_dependent_mask, | 422 unsigned int right_key_sym, |
420 unsigned int right_device_dependent_mask ) { | 423 unsigned int left_device_dependent_mask, |
424 unsigned int right_device_dependent_mask) | |
425 { | |
421 unsigned int device_dependent_mask = 0; | 426 unsigned int device_dependent_mask = 0; |
422 unsigned int diff_mod = 0; | 427 unsigned int diff_mod = 0; |
423 | 428 |
424 device_dependent_mask = left_device_dependent_mask | right_device_dependent_mask; | 429 device_dependent_mask = |
430 left_device_dependent_mask | right_device_dependent_mask; | |
425 /* On the basis that the device independent mask is set, but there are | 431 /* On the basis that the device independent mask is set, but there are |
426 * no device dependent flags set, we'll assume that we can't detect this | 432 * no device dependent flags set, we'll assume that we can't detect this |
427 * keyboard and revert to the unsided behavior. | 433 * keyboard and revert to the unsided behavior. |
428 */ | 434 */ |
429 if ( (device_dependent_mask & newMods) == 0 ) { | 435 if ((device_dependent_mask & newMods) == 0) { |
430 /* Revert to the old behavior */ | 436 /* Revert to the old behavior */ |
431 QZ_HandleNonDeviceModifier ( this, device_independent_mask, newMods, left_key_sym ); | 437 QZ_HandleNonDeviceModifier (this, device_independent_mask, newMods, |
438 left_key_sym); | |
432 return; | 439 return; |
433 } | 440 } |
434 | 441 |
435 /* XOR the previous state against the new state to see if there's a change */ | 442 /* XOR the previous state against the new state to see if there's a change */ |
436 diff_mod = (device_dependent_mask & current_mods) | 443 diff_mod = (device_dependent_mask & current_mods) |
437 ^ (device_dependent_mask & newMods); | 444 ^ (device_dependent_mask & newMods); |
438 | 445 |
439 if ( diff_mod ) { | 446 if (diff_mod) { |
440 /* A change in state was found. Isolate the left and right bits | 447 /* A change in state was found. Isolate the left and right bits |
441 * to handle them separately just in case the values can simulataneously | 448 * to handle them separately just in case the values can simulataneously |
442 * change or if the bits don't both exist. | 449 * change or if the bits don't both exist. |
443 */ | 450 */ |
444 if ( left_device_dependent_mask & diff_mod ) { | 451 if (left_device_dependent_mask & diff_mod) { |
445 QZ_HandleModifierOneSide ( this, newMods, left_key_sym, left_device_dependent_mask ); | 452 QZ_HandleModifierOneSide (this, newMods, left_key_sym, |
453 left_device_dependent_mask); | |
446 } | 454 } |
447 if ( right_device_dependent_mask & diff_mod ) { | 455 if (right_device_dependent_mask & diff_mod) { |
448 QZ_HandleModifierOneSide ( this, newMods, right_key_sym, right_device_dependent_mask ); | 456 QZ_HandleModifierOneSide (this, newMods, right_key_sym, |
457 right_device_dependent_mask); | |
449 } | 458 } |
450 } | 459 } |
451 } | 460 } |
452 | 461 |
453 /* This is a helper function for QZ_DoSidedModifiers. | 462 /* This is a helper function for QZ_DoSidedModifiers. |
454 * This function will release a key press in the case that | 463 * This function will release a key press in the case that |
455 * it is clear that the modifier has been released (i.e. one side | 464 * it is clear that the modifier has been released (i.e. one side |
456 * can't still be down). | 465 * can't still be down). |
457 */ | 466 */ |
458 static void QZ_ReleaseModifierSide ( _THIS, | 467 static void |
459 unsigned int device_independent_mask, | 468 QZ_ReleaseModifierSide (_THIS, |
460 unsigned int newMods, | 469 unsigned int device_independent_mask, |
461 unsigned int left_key_sym, | 470 unsigned int newMods, |
462 unsigned int right_key_sym, | 471 unsigned int left_key_sym, |
463 unsigned int left_device_dependent_mask, | 472 unsigned int right_key_sym, |
464 unsigned int right_device_dependent_mask ) { | 473 unsigned int left_device_dependent_mask, |
474 unsigned int right_device_dependent_mask) | |
475 { | |
465 unsigned int device_dependent_mask = 0; | 476 unsigned int device_dependent_mask = 0; |
466 SDL_keysym key; | 477 SDL_keysym key; |
467 | 478 |
468 key.scancode = 0; | 479 key.scancode = 0; |
469 key.sym = SDLK_UNKNOWN; | 480 key.sym = SDLK_UNKNOWN; |
470 key.unicode = 0; | 481 key.unicode = 0; |
471 key.mod = KMOD_NONE; | 482 key.mod = KMOD_NONE; |
472 | 483 |
473 device_dependent_mask = left_device_dependent_mask | right_device_dependent_mask; | 484 device_dependent_mask = |
485 left_device_dependent_mask | right_device_dependent_mask; | |
474 /* On the basis that the device independent mask is set, but there are | 486 /* On the basis that the device independent mask is set, but there are |
475 * no device dependent flags set, we'll assume that we can't detect this | 487 * no device dependent flags set, we'll assume that we can't detect this |
476 * keyboard and revert to the unsided behavior. | 488 * keyboard and revert to the unsided behavior. |
477 */ | 489 */ |
478 if ( (device_dependent_mask & current_mods) == 0 ) { | 490 if ((device_dependent_mask & current_mods) == 0) { |
479 /* In this case, we can't detect the keyboard, so use the left side | 491 /* In this case, we can't detect the keyboard, so use the left side |
480 * to represent both, and release it. | 492 * to represent both, and release it. |
481 */ | 493 */ |
482 key.sym = left_key_sym; | 494 key.sym = left_key_sym; |
483 SDL_PrivateKeyboard (SDL_RELEASED, &key); | 495 SDL_PrivateKeyboard (SDL_RELEASED, &key); |
484 | 496 |
485 return; | 497 return; |
486 } | 498 } |
487 | 499 |
488 | 500 |
489 /* | 501 /* |
490 * This could have been done in an if-else case because at this point, | 502 * This could have been done in an if-else case because at this point, |
491 * we know that all keys have been released when calling this function. | 503 * we know that all keys have been released when calling this function. |
492 * But I'm being paranoid so I want to handle each separately, | 504 * But I'm being paranoid so I want to handle each separately, |
493 * so I hope this doesn't cause other problems. | 505 * so I hope this doesn't cause other problems. |
494 */ | 506 */ |
495 if ( left_device_dependent_mask & current_mods ) { | 507 if (left_device_dependent_mask & current_mods) { |
496 key.sym = left_key_sym; | 508 key.sym = left_key_sym; |
497 SDL_PrivateKeyboard (SDL_RELEASED, &key); | 509 SDL_PrivateKeyboard (SDL_RELEASED, &key); |
498 } | 510 } |
499 if ( right_device_dependent_mask & current_mods ) { | 511 if (right_device_dependent_mask & current_mods) { |
500 key.sym = right_key_sym; | 512 key.sym = right_key_sym; |
501 SDL_PrivateKeyboard (SDL_RELEASED, &key); | 513 SDL_PrivateKeyboard (SDL_RELEASED, &key); |
502 } | 514 } |
503 } | 515 } |
504 | 516 |
505 /* This is a helper function for QZ_DoSidedModifiers. | 517 /* This is a helper function for QZ_DoSidedModifiers. |
506 * This function handles the CapsLock case. | 518 * This function handles the CapsLock case. |
507 */ | 519 */ |
508 static void QZ_HandleCapsLock (_THIS, unsigned int newMods) { | 520 static void |
521 QZ_HandleCapsLock (_THIS, unsigned int newMods) | |
522 { | |
509 unsigned int currentMask, newMask; | 523 unsigned int currentMask, newMask; |
510 SDL_keysym key; | 524 SDL_keysym key; |
511 | 525 |
512 key.scancode = 0; | 526 key.scancode = 0; |
513 key.sym = SDLK_CAPSLOCK; | 527 key.sym = SDLK_CAPSLOCK; |
514 key.unicode = 0; | 528 key.unicode = 0; |
515 key.mod = KMOD_NONE; | 529 key.mod = KMOD_NONE; |
516 | 530 |
517 currentMask = current_mods & NSAlphaShiftKeyMask; | 531 currentMask = current_mods & NSAlphaShiftKeyMask; |
518 newMask = newMods & NSAlphaShiftKeyMask; | 532 newMask = newMods & NSAlphaShiftKeyMask; |
519 | 533 |
520 if ( currentMask && | 534 if (currentMask && currentMask != newMask) { /* modifier up event */ |
521 currentMask != newMask ) { /* modifier up event */ | |
522 /* If this was Caps Lock, we need some additional voodoo to make SDL happy */ | |
523 SDL_PrivateKeyboard (SDL_PRESSED, &key); | |
524 SDL_PrivateKeyboard (SDL_RELEASED, &key); | |
525 } | |
526 else if ( newMask && | |
527 currentMask != newMask ) { /* modifier down event */ | |
528 /* If this was Caps Lock, we need some additional voodoo to make SDL happy */ | 535 /* If this was Caps Lock, we need some additional voodoo to make SDL happy */ |
529 SDL_PrivateKeyboard (SDL_PRESSED, &key); | 536 SDL_PrivateKeyboard (SDL_PRESSED, &key); |
530 SDL_PrivateKeyboard (SDL_RELEASED, &key); | 537 SDL_PrivateKeyboard (SDL_RELEASED, &key); |
538 } else if (newMask && currentMask != newMask) { /* modifier down event */ | |
539 /* If this was Caps Lock, we need some additional voodoo to make SDL happy */ | |
540 SDL_PrivateKeyboard (SDL_PRESSED, &key); | |
541 SDL_PrivateKeyboard (SDL_RELEASED, &key); | |
531 } | 542 } |
532 } | 543 } |
533 | 544 |
534 /* This function will handle the modifier keys and also determine the | 545 /* This function will handle the modifier keys and also determine the |
535 * correct side of the key. | 546 * correct side of the key. |
536 */ | 547 */ |
537 static void QZ_DoSidedModifiers (_THIS, unsigned int newMods) { | 548 static void |
538 /* Set up arrays for the key syms for the left and right side. */ | 549 QZ_DoSidedModifiers (_THIS, unsigned int newMods) |
539 const unsigned int left_mapping[] = { SDLK_LSHIFT, SDLK_LCTRL, SDLK_LALT, SDLK_LMETA }; | 550 { |
540 const unsigned int right_mapping[] = { SDLK_RSHIFT, SDLK_RCTRL, SDLK_RALT, SDLK_RMETA }; | 551 /* Set up arrays for the key syms for the left and right side. */ |
541 /* Set up arrays for the device dependent masks with indices that | 552 const unsigned int left_mapping[] = |
553 { SDLK_LSHIFT, SDLK_LCTRL, SDLK_LALT, SDLK_LMETA }; | |
554 const unsigned int right_mapping[] = | |
555 { SDLK_RSHIFT, SDLK_RCTRL, SDLK_RALT, SDLK_RMETA }; | |
556 /* Set up arrays for the device dependent masks with indices that | |
542 * correspond to the _mapping arrays | 557 * correspond to the _mapping arrays |
543 */ | 558 */ |
544 const unsigned int left_device_mapping[] = { NX_DEVICELSHIFTKEYMASK, NX_DEVICELCTLKEYMASK, NX_DEVICELALTKEYMASK, NX_DEVICELCMDKEYMASK }; | 559 const unsigned int left_device_mapping[] = |
545 const unsigned int right_device_mapping[] = { NX_DEVICERSHIFTKEYMASK, NX_DEVICERCTLKEYMASK, NX_DEVICERALTKEYMASK, NX_DEVICERCMDKEYMASK }; | 560 { NX_DEVICELSHIFTKEYMASK, NX_DEVICELCTLKEYMASK, NX_DEVICELALTKEYMASK, |
561 NX_DEVICELCMDKEYMASK | |
562 }; | |
563 const unsigned int right_device_mapping[] = | |
564 { NX_DEVICERSHIFTKEYMASK, NX_DEVICERCTLKEYMASK, NX_DEVICERALTKEYMASK, | |
565 NX_DEVICERCMDKEYMASK | |
566 }; | |
546 | 567 |
547 unsigned int i; | 568 unsigned int i; |
548 unsigned int bit; | 569 unsigned int bit; |
549 | 570 |
550 /* Handle CAPSLOCK separately because it doesn't have a left/right side */ | 571 /* Handle CAPSLOCK separately because it doesn't have a left/right side */ |
551 QZ_HandleCapsLock ( this, newMods ); | 572 QZ_HandleCapsLock (this, newMods); |
552 | 573 |
553 /* Iterate through the bits, testing each against the current modifiers */ | 574 /* Iterate through the bits, testing each against the current modifiers */ |
554 for (i = 0, bit = NSShiftKeyMask; bit <= NSCommandKeyMask; bit <<= 1, ++i) { | 575 for (i = 0, bit = NSShiftKeyMask; bit <= NSCommandKeyMask; bit <<= 1, ++i) { |
555 | 576 |
556 unsigned int currentMask, newMask; | 577 unsigned int currentMask, newMask; |
557 | 578 |
558 currentMask = current_mods & bit; | 579 currentMask = current_mods & bit; |
559 newMask = newMods & bit; | 580 newMask = newMods & bit; |
560 | 581 |
561 /* If the bit is set, we must always examine it because the left | 582 /* If the bit is set, we must always examine it because the left |
562 * and right side keys may alternate or both may be pressed. | 583 * and right side keys may alternate or both may be pressed. |
563 */ | 584 */ |
564 if ( newMask ) { | 585 if (newMask) { |
565 QZ_HandleModifierSide ( this, bit, newMods, | 586 QZ_HandleModifierSide (this, bit, newMods, |
566 left_mapping[i], | 587 left_mapping[i], |
567 right_mapping[i], | 588 right_mapping[i], |
568 left_device_mapping[i], | 589 left_device_mapping[i], |
569 right_device_mapping[i] ); | 590 right_device_mapping[i]); |
570 } | 591 } |
571 /* If the state changed from pressed to unpressed, we must examine | 592 /* If the state changed from pressed to unpressed, we must examine |
572 * the device dependent bits to release the correct keys. | 593 * the device dependent bits to release the correct keys. |
573 */ | 594 */ |
574 else if ( currentMask && | 595 else if (currentMask && currentMask != newMask) { /* modifier up event */ |
575 currentMask != newMask ) { /* modifier up event */ | 596 QZ_ReleaseModifierSide (this, bit, newMods, |
576 QZ_ReleaseModifierSide ( this, bit, newMods, | 597 left_mapping[i], |
577 left_mapping[i], | 598 right_mapping[i], |
578 right_mapping[i], | 599 left_device_mapping[i], |
579 left_device_mapping[i], | 600 right_device_mapping[i]); |
580 right_device_mapping[i] ); | |
581 } | 601 } |
582 } | 602 } |
583 } | 603 } |
584 | 604 |
585 /* This function is called to handle the modifiers. | 605 /* This function is called to handle the modifiers. |
586 * It will try to distinguish between the left side and right side | 606 * It will try to distinguish between the left side and right side |
587 * of the keyboard for those modifiers that qualify if the | 607 * of the keyboard for those modifiers that qualify if the |
588 * operating system version supports it. Otherwise, the code | 608 * operating system version supports it. Otherwise, the code |
589 * will not try to make the distinction. | 609 * will not try to make the distinction. |
590 */ | 610 */ |
591 static void QZ_DoModifiers (_THIS, unsigned int newMods) { | 611 static void |
592 | 612 QZ_DoModifiers (_THIS, unsigned int newMods) |
613 { | |
614 | |
593 if (current_mods == newMods) | 615 if (current_mods == newMods) |
594 return; | 616 return; |
595 | 617 |
596 /* | 618 /* |
597 * Starting with Panther (10.3.0), the ability to distinguish between | 619 * Starting with Panther (10.3.0), the ability to distinguish between |
598 * left side and right side modifiers is available. | 620 * left side and right side modifiers is available. |
599 */ | 621 */ |
600 if( system_version >= 0x1030 ) { | 622 if (system_version >= 0x1030) { |
601 QZ_DoSidedModifiers (this, newMods); | 623 QZ_DoSidedModifiers (this, newMods); |
602 } | 624 } else { |
603 else { | |
604 QZ_DoUnsidedModifiers (this, newMods); | 625 QZ_DoUnsidedModifiers (this, newMods); |
605 } | 626 } |
606 | 627 |
607 current_mods = newMods; | 628 current_mods = newMods; |
608 } | 629 } |
609 | 630 |
610 static void QZ_GetMouseLocation (_THIS, NSPoint *p) { | 631 static void |
611 *p = [ NSEvent mouseLocation ]; /* global coordinates */ | 632 QZ_GetMouseLocation (_THIS, NSPoint * p) |
633 { | |
634 *p =[NSEvent mouseLocation]; /* global coordinates */ | |
612 if (qz_window) | 635 if (qz_window) |
613 QZ_PrivateGlobalToLocal (this, p); | 636 QZ_PrivateGlobalToLocal (this, p); |
614 QZ_PrivateCocoaToSDL (this, p); | 637 QZ_PrivateCocoaToSDL (this, p); |
615 } | 638 } |
616 | 639 |
617 void QZ_DoActivate (_THIS) { | 640 void |
618 | 641 QZ_DoActivate (_THIS) |
619 SDL_PrivateAppActive (1, SDL_APPINPUTFOCUS | (QZ_IsMouseInWindow (this) ? SDL_APPMOUSEFOCUS : 0)); | 642 { |
620 | 643 |
644 SDL_PrivateAppActive (1, | |
645 SDL_APPINPUTFOCUS | (QZ_IsMouseInWindow (this) ? | |
646 SDL_APPMOUSEFOCUS : 0)); | |
647 | |
621 /* Hide the cursor if it was hidden by SDL_ShowCursor() */ | 648 /* Hide the cursor if it was hidden by SDL_ShowCursor() */ |
622 if (!cursor_should_be_visible) | 649 if (!cursor_should_be_visible) |
623 QZ_HideMouse (this); | 650 QZ_HideMouse (this); |
624 | 651 |
625 /* Regrab input, only if it was previously grabbed */ | 652 /* Regrab input, only if it was previously grabbed */ |
626 if ( current_grab_mode == SDL_GRAB_ON ) { | 653 if (current_grab_mode == SDL_GRAB_ON) { |
627 | 654 |
628 /* Restore cursor location if input was grabbed */ | 655 /* Restore cursor location if input was grabbed */ |
629 QZ_PrivateWarpCursor (this, cursor_loc.x, cursor_loc.y); | 656 QZ_PrivateWarpCursor (this, cursor_loc.x, cursor_loc.y); |
630 QZ_ChangeGrabState (this, QZ_ENABLE_GRAB); | 657 QZ_ChangeGrabState (this, QZ_ENABLE_GRAB); |
631 } | 658 } else { |
632 else { | |
633 /* Update SDL's mouse location */ | 659 /* Update SDL's mouse location */ |
634 NSPoint p; | 660 NSPoint p; |
635 QZ_GetMouseLocation (this, &p); | 661 QZ_GetMouseLocation (this, &p); |
636 SDL_PrivateMouseMotion (0, 0, p.x, p.y); | 662 SDL_PrivateMouseMotion (0, 0, p.x, p.y); |
637 } | 663 } |
638 } | 664 } |
639 | 665 |
640 void QZ_DoDeactivate (_THIS) { | 666 void |
641 | 667 QZ_DoDeactivate (_THIS) |
668 { | |
669 | |
642 SDL_PrivateAppActive (0, SDL_APPINPUTFOCUS | SDL_APPMOUSEFOCUS); | 670 SDL_PrivateAppActive (0, SDL_APPINPUTFOCUS | SDL_APPMOUSEFOCUS); |
643 | 671 |
644 /* Get the current cursor location, for restore on activate */ | 672 /* Get the current cursor location, for restore on activate */ |
645 QZ_GetMouseLocation (this, &cursor_loc); | 673 QZ_GetMouseLocation (this, &cursor_loc); |
646 | 674 |
647 /* Reassociate mouse and cursor */ | 675 /* Reassociate mouse and cursor */ |
648 CGAssociateMouseAndMouseCursorPosition (1); | 676 CGAssociateMouseAndMouseCursorPosition (1); |
649 | 677 |
650 /* Show the cursor if it was hidden by SDL_ShowCursor() */ | 678 /* Show the cursor if it was hidden by SDL_ShowCursor() */ |
651 if (!cursor_should_be_visible) | 679 if (!cursor_should_be_visible) |
652 QZ_ShowMouse (this); | 680 QZ_ShowMouse (this); |
653 } | 681 } |
654 | 682 |
655 void QZ_SleepNotificationHandler (void * refcon, | 683 void |
656 io_service_t service, | 684 QZ_SleepNotificationHandler (void *refcon, |
657 natural_t messageType, | 685 io_service_t service, |
658 void * messageArgument ) | 686 natural_t messageType, void *messageArgument) |
659 { | 687 { |
660 SDL_VideoDevice *this = (SDL_VideoDevice*)refcon; | 688 SDL_VideoDevice *this = (SDL_VideoDevice *) refcon; |
661 | 689 |
662 switch(messageType) | 690 switch (messageType) { |
663 { | 691 case kIOMessageSystemWillSleep: |
664 case kIOMessageSystemWillSleep: | 692 IOAllowPowerChange (power_connection, (long) messageArgument); |
665 IOAllowPowerChange(power_connection, (long) messageArgument); | 693 break; |
666 break; | 694 case kIOMessageCanSystemSleep: |
667 case kIOMessageCanSystemSleep: | 695 IOAllowPowerChange (power_connection, (long) messageArgument); |
668 IOAllowPowerChange(power_connection, (long) messageArgument); | 696 break; |
669 break; | 697 case kIOMessageSystemHasPoweredOn: |
670 case kIOMessageSystemHasPoweredOn: | 698 /* awake */ |
671 /* awake */ | 699 SDL_PrivateExpose (); |
672 SDL_PrivateExpose(); | 700 break; |
673 break; | 701 } |
674 } | 702 } |
675 } | 703 |
676 | 704 void |
677 void QZ_RegisterForSleepNotifications (_THIS) | 705 QZ_RegisterForSleepNotifications (_THIS) |
678 { | 706 { |
679 CFRunLoopSourceRef rls; | 707 CFRunLoopSourceRef rls; |
680 IONotificationPortRef thePortRef; | 708 IONotificationPortRef thePortRef; |
681 io_object_t notifier; | 709 io_object_t notifier; |
682 | 710 |
683 power_connection = IORegisterForSystemPower (this, &thePortRef, QZ_SleepNotificationHandler, ¬ifier); | 711 power_connection = |
684 | 712 IORegisterForSystemPower (this, &thePortRef, |
685 if (power_connection == 0) | 713 QZ_SleepNotificationHandler, ¬ifier); |
686 NSLog(@"SDL: QZ_SleepNotificationHandler() IORegisterForSystemPower failed."); | 714 |
687 | 715 if (power_connection == 0) |
688 rls = IONotificationPortGetRunLoopSource (thePortRef); | 716 NSLog |
689 CFRunLoopAddSource (CFRunLoopGetCurrent(), rls, kCFRunLoopDefaultMode); | 717 (@"SDL: QZ_SleepNotificationHandler() IORegisterForSystemPower failed."); |
690 CFRelease (rls); | 718 |
719 rls = IONotificationPortGetRunLoopSource (thePortRef); | |
720 CFRunLoopAddSource (CFRunLoopGetCurrent (), rls, kCFRunLoopDefaultMode); | |
721 CFRelease (rls); | |
691 } | 722 } |
692 | 723 |
693 | 724 |
694 /* Try to map Quartz mouse buttons to SDL's lingo... */ | 725 /* Try to map Quartz mouse buttons to SDL's lingo... */ |
695 static int QZ_OtherMouseButtonToSDL(int button) | 726 static int |
696 { | 727 QZ_OtherMouseButtonToSDL (int button) |
697 switch (button) | 728 { |
698 { | 729 switch (button) { |
699 case 0: | 730 case 0: |
700 return(SDL_BUTTON_LEFT); /* 1 */ | 731 return (SDL_BUTTON_LEFT); /* 1 */ |
701 case 1: | 732 case 1: |
702 return(SDL_BUTTON_RIGHT); /* 3 */ | 733 return (SDL_BUTTON_RIGHT); /* 3 */ |
703 case 2: | 734 case 2: |
704 return(SDL_BUTTON_MIDDLE); /* 2 */ | 735 return (SDL_BUTTON_MIDDLE); /* 2 */ |
705 } | 736 } |
706 | 737 |
707 /* >= 3: skip 4 & 5, since those are the SDL mousewheel buttons. */ | 738 /* >= 3: skip 4 & 5, since those are the SDL mousewheel buttons. */ |
708 return(button + 3); | 739 return (button + 3); |
709 } | 740 } |
710 | 741 |
711 | 742 |
712 void QZ_PumpEvents (_THIS) | 743 void |
744 QZ_PumpEvents (_THIS) | |
713 { | 745 { |
714 static Uint32 screensaverTicks = 0; | 746 static Uint32 screensaverTicks = 0; |
715 Uint32 nowTicks; | 747 Uint32 nowTicks; |
716 int firstMouseEvent; | 748 int firstMouseEvent; |
717 CGMouseDelta dx, dy; | 749 CGMouseDelta dx, dy; |
720 NSEvent *event; | 752 NSEvent *event; |
721 NSRect winRect; | 753 NSRect winRect; |
722 NSAutoreleasePool *pool; | 754 NSAutoreleasePool *pool; |
723 | 755 |
724 if (!SDL_VideoSurface) | 756 if (!SDL_VideoSurface) |
725 return; /* don't do anything if there's no screen surface. */ | 757 return; /* don't do anything if there's no screen surface. */ |
726 | 758 |
727 /* Update activity every five seconds to prevent screensaver. --ryan. */ | 759 /* Update activity every five seconds to prevent screensaver. --ryan. */ |
728 nowTicks = SDL_GetTicks(); | 760 nowTicks = SDL_GetTicks (); |
729 if ((nowTicks - screensaverTicks) > 5000) | 761 if ((nowTicks - screensaverTicks) > 5000) { |
730 { | 762 UpdateSystemActivity (UsrActivity); |
731 UpdateSystemActivity(UsrActivity); | |
732 screensaverTicks = nowTicks; | 763 screensaverTicks = nowTicks; |
733 } | 764 } |
734 | 765 |
735 pool = [ [ NSAutoreleasePool alloc ] init ]; | 766 pool =[[NSAutoreleasePool alloc] init]; |
736 distantPast = [ NSDate distantPast ]; | 767 distantPast =[NSDate distantPast]; |
737 | 768 |
738 winRect = NSMakeRect (0, 0, SDL_VideoSurface->w, SDL_VideoSurface->h); | 769 winRect = NSMakeRect (0, 0, SDL_VideoSurface->w, SDL_VideoSurface->h); |
739 | 770 |
740 /* send the first mouse event in absolute coordinates */ | 771 /* send the first mouse event in absolute coordinates */ |
741 firstMouseEvent = 1; | 772 firstMouseEvent = 1; |
742 | 773 |
743 /* accumulate any additional mouse moved events into one SDL mouse event */ | 774 /* accumulate any additional mouse moved events into one SDL mouse event */ |
744 dx = 0; | 775 dx = 0; |
745 dy = 0; | 776 dy = 0; |
746 | 777 |
747 do { | 778 do { |
748 | 779 |
749 /* Poll for an event. This will not block */ | 780 /* Poll for an event. This will not block */ |
750 event = [ NSApp nextEventMatchingMask:NSAnyEventMask | 781 event =[NSApp nextEventMatchingMask: NSAnyEventMask untilDate: distantPast inMode: NSDefaultRunLoopMode dequeue:YES]; |
751 untilDate:distantPast | |
752 inMode: NSDefaultRunLoopMode dequeue:YES ]; | |
753 if (event != nil) { | 782 if (event != nil) { |
754 | 783 |
755 int button; | 784 int button; |
756 unsigned int type; | 785 unsigned int type; |
757 BOOL isInGameWin; | 786 BOOL isInGameWin; |
758 | 787 |
759 #define DO_MOUSE_DOWN(button) do { \ | 788 #define DO_MOUSE_DOWN(button) do { \ |
760 if ( SDL_GetAppState() & SDL_APPMOUSEFOCUS ) { \ | 789 if ( SDL_GetAppState() & SDL_APPMOUSEFOCUS ) { \ |
761 SDL_PrivateMouseButton (SDL_PRESSED, button, 0, 0); \ | 790 SDL_PrivateMouseButton (SDL_PRESSED, button, 0, 0); \ |
762 expect_mouse_up |= 1<<button; \ | 791 expect_mouse_up |= 1<<button; \ |
763 } \ | 792 } \ |
764 [ NSApp sendEvent:event ]; \ | 793 [ NSApp sendEvent:event ]; \ |
765 } while(0) | 794 } while(0) |
766 | 795 |
767 #define DO_MOUSE_UP(button) do { \ | 796 #define DO_MOUSE_UP(button) do { \ |
768 if ( expect_mouse_up & (1<<button) ) { \ | 797 if ( expect_mouse_up & (1<<button) ) { \ |
769 SDL_PrivateMouseButton (SDL_RELEASED, button, 0, 0); \ | 798 SDL_PrivateMouseButton (SDL_RELEASED, button, 0, 0); \ |
770 expect_mouse_up &= ~(1<<button); \ | 799 expect_mouse_up &= ~(1<<button); \ |
771 } \ | 800 } \ |
772 [ NSApp sendEvent:event ]; \ | 801 [ NSApp sendEvent:event ]; \ |
773 } while(0) | 802 } while(0) |
774 | 803 |
775 type = [ event type ]; | 804 type =[event type]; |
776 isInGameWin = QZ_IsMouseInWindow (this); | 805 isInGameWin = QZ_IsMouseInWindow (this); |
777 | 806 |
778 QZ_DoModifiers(this, [ event modifierFlags ] ); | 807 QZ_DoModifiers (this,[event modifierFlags]); |
779 | 808 |
780 switch (type) { | 809 switch (type) { |
781 case NSLeftMouseDown: | 810 case NSLeftMouseDown: |
782 if ( SDL_getenv("SDL_HAS3BUTTONMOUSE") ) { | 811 if (SDL_getenv ("SDL_HAS3BUTTONMOUSE")) { |
812 DO_MOUSE_DOWN (SDL_BUTTON_LEFT); | |
813 } else { | |
814 if (NSCommandKeyMask & current_mods) { | |
815 last_virtual_button = SDL_BUTTON_RIGHT; | |
816 DO_MOUSE_DOWN (SDL_BUTTON_RIGHT); | |
817 } else if (NSAlternateKeyMask & current_mods) { | |
818 last_virtual_button = SDL_BUTTON_MIDDLE; | |
819 DO_MOUSE_DOWN (SDL_BUTTON_MIDDLE); | |
820 } else { | |
783 DO_MOUSE_DOWN (SDL_BUTTON_LEFT); | 821 DO_MOUSE_DOWN (SDL_BUTTON_LEFT); |
784 } else { | |
785 if ( NSCommandKeyMask & current_mods ) { | |
786 last_virtual_button = SDL_BUTTON_RIGHT; | |
787 DO_MOUSE_DOWN (SDL_BUTTON_RIGHT); | |
788 } | |
789 else if ( NSAlternateKeyMask & current_mods ) { | |
790 last_virtual_button = SDL_BUTTON_MIDDLE; | |
791 DO_MOUSE_DOWN (SDL_BUTTON_MIDDLE); | |
792 } | |
793 else { | |
794 DO_MOUSE_DOWN (SDL_BUTTON_LEFT); | |
795 } | |
796 } | 822 } |
797 break; | 823 } |
798 | 824 break; |
799 case NSLeftMouseUp: | 825 |
800 if ( last_virtual_button != 0 ) { | 826 case NSLeftMouseUp: |
801 DO_MOUSE_UP (last_virtual_button); | 827 if (last_virtual_button != 0) { |
802 last_virtual_button = 0; | 828 DO_MOUSE_UP (last_virtual_button); |
829 last_virtual_button = 0; | |
830 } else { | |
831 DO_MOUSE_UP (SDL_BUTTON_LEFT); | |
832 } | |
833 break; | |
834 | |
835 case NSOtherMouseDown: | |
836 case NSRightMouseDown: | |
837 button = QZ_OtherMouseButtonToSDL ([event buttonNumber]); | |
838 DO_MOUSE_DOWN (button); | |
839 break; | |
840 | |
841 case NSOtherMouseUp: | |
842 case NSRightMouseUp: | |
843 button = QZ_OtherMouseButtonToSDL ([event buttonNumber]); | |
844 DO_MOUSE_UP (button); | |
845 break; | |
846 | |
847 case NSSystemDefined: | |
848 /* | |
849 Future: up to 32 "mouse" buttons can be handled. | |
850 if ([event subtype] == 7) { | |
851 unsigned int buttons; | |
852 buttons = [ event data2 ]; | |
853 */ | |
854 break; | |
855 case NSLeftMouseDragged: | |
856 case NSRightMouseDragged: | |
857 case NSOtherMouseDragged: /* usually middle mouse dragged */ | |
858 case NSMouseMoved: | |
859 if (grab_state == QZ_INVISIBLE_GRAB) { | |
860 | |
861 /* | |
862 If input is grabbed+hidden, the cursor doesn't move, | |
863 so we have to call the lowlevel window server | |
864 function. This is less accurate but works OK. | |
865 */ | |
866 CGMouseDelta dx1, dy1; | |
867 CGGetLastMouseDelta (&dx1, &dy1); | |
868 dx += dx1; | |
869 dy += dy1; | |
870 } else if (firstMouseEvent) { | |
871 | |
872 /* | |
873 Get the first mouse event in a possible | |
874 sequence of mouse moved events. Since we | |
875 use absolute coordinates, this serves to | |
876 compensate any inaccuracy in deltas, and | |
877 provides the first known mouse position, | |
878 since everything after this uses deltas | |
879 */ | |
880 NSPoint p; | |
881 QZ_GetMouseLocation (this, &p); | |
882 SDL_PrivateMouseMotion (0, 0, p.x, p.y); | |
883 firstMouseEvent = 0; | |
884 } else { | |
885 | |
886 /* | |
887 Get the amount moved since the last drag or move event, | |
888 add it on for one big move event at the end. | |
889 */ | |
890 dx +=[event deltaX]; | |
891 dy +=[event deltaY]; | |
892 } | |
893 | |
894 /* | |
895 Handle grab input+cursor visible by warping the cursor back | |
896 into the game window. This still generates a mouse moved event, | |
897 but not as a result of the warp (so it's in the right direction). | |
898 */ | |
899 if (grab_state == QZ_VISIBLE_GRAB && !isInGameWin) { | |
900 | |
901 NSPoint p; | |
902 QZ_GetMouseLocation (this, &p); | |
903 | |
904 if (p.x < 0.0) | |
905 p.x = 0.0; | |
906 | |
907 if (p.y < 0.0) | |
908 p.y = 0.0; | |
909 | |
910 if (p.x >= winRect.size.width) | |
911 p.x = winRect.size.width - 1; | |
912 | |
913 if (p.y >= winRect.size.height) | |
914 p.y = winRect.size.height - 1; | |
915 | |
916 QZ_PrivateWarpCursor (this, p.x, p.y); | |
917 } else if (!isInGameWin | |
918 && (SDL_GetAppState () & SDL_APPMOUSEFOCUS)) { | |
919 | |
920 SDL_PrivateAppActive (0, SDL_APPMOUSEFOCUS); | |
921 if (grab_state == QZ_INVISIBLE_GRAB) | |
922 /*The cursor has left the window even though it is | |
923 disassociated from the mouse (and therefore | |
924 shouldn't move): this can happen with Wacom | |
925 tablets, and it effectively breaks the grab, since | |
926 mouse down events now go to background | |
927 applications. The only possibility to avoid this | |
928 seems to be talking to the tablet driver | |
929 (AppleEvents) to constrain its mapped area to the | |
930 window, which may not be worth the effort. For | |
931 now, handle the condition more gracefully than | |
932 before by reassociating cursor and mouse until the | |
933 cursor enters the window again, making it obvious | |
934 to the user that the grab is broken. */ | |
935 CGAssociateMouseAndMouseCursorPosition (1); | |
936 if (!cursor_should_be_visible) | |
937 QZ_ShowMouse (this); | |
938 } else if (isInGameWin | |
939 && (SDL_GetAppState () & | |
940 (SDL_APPMOUSEFOCUS | SDL_APPINPUTFOCUS)) == | |
941 SDL_APPINPUTFOCUS) { | |
942 | |
943 SDL_PrivateAppActive (1, SDL_APPMOUSEFOCUS); | |
944 if (!cursor_should_be_visible) | |
945 QZ_HideMouse (this); | |
946 if (grab_state == QZ_INVISIBLE_GRAB) { /*see comment above */ | |
947 QZ_PrivateWarpCursor (this, | |
948 SDL_VideoSurface->w / | |
949 2, SDL_VideoSurface->h / 2); | |
950 CGAssociateMouseAndMouseCursorPosition (0); | |
803 } | 951 } |
804 else { | 952 } |
805 DO_MOUSE_UP (SDL_BUTTON_LEFT); | 953 break; |
806 } | 954 case NSScrollWheel: |
807 break; | 955 if (isInGameWin) { |
808 | 956 float dy, dx; |
809 case NSOtherMouseDown: | 957 Uint8 button; |
810 case NSRightMouseDown: | 958 dy =[event deltaY]; |
811 button = QZ_OtherMouseButtonToSDL([ event buttonNumber ]); | 959 dx =[event deltaX]; |
812 DO_MOUSE_DOWN (button); | 960 if (dy > 0.0 || dx > 0.0) /* Scroll up */ |
813 break; | 961 button = SDL_BUTTON_WHEELUP; |
814 | 962 else /* Scroll down */ |
815 case NSOtherMouseUp: | 963 button = SDL_BUTTON_WHEELDOWN; |
816 case NSRightMouseUp: | 964 /* For now, wheel is sent as a quick down+up */ |
817 button = QZ_OtherMouseButtonToSDL([ event buttonNumber ]); | 965 SDL_PrivateMouseButton (SDL_PRESSED, button, 0, 0); |
818 DO_MOUSE_UP (button); | 966 SDL_PrivateMouseButton (SDL_RELEASED, button, 0, 0); |
819 break; | 967 } |
820 | 968 break; |
821 case NSSystemDefined: | 969 case NSKeyUp: |
822 /* | 970 QZ_DoKey (this, SDL_RELEASED, event); |
823 Future: up to 32 "mouse" buttons can be handled. | 971 break; |
824 if ([event subtype] == 7) { | 972 case NSKeyDown: |
825 unsigned int buttons; | 973 QZ_DoKey (this, SDL_PRESSED, event); |
826 buttons = [ event data2 ]; | 974 break; |
827 */ | 975 case NSFlagsChanged: |
828 break; | 976 break; |
829 case NSLeftMouseDragged: | 977 /* case NSAppKitDefined: break; */ |
830 case NSRightMouseDragged: | 978 /* case NSApplicationDefined: break; */ |
831 case NSOtherMouseDragged: /* usually middle mouse dragged */ | 979 /* case NSPeriodic: break; */ |
832 case NSMouseMoved: | 980 /* case NSCursorUpdate: break; */ |
833 if ( grab_state == QZ_INVISIBLE_GRAB ) { | 981 default: |
834 | 982 [NSApp sendEvent:event]; |
835 /* | |
836 If input is grabbed+hidden, the cursor doesn't move, | |
837 so we have to call the lowlevel window server | |
838 function. This is less accurate but works OK. | |
839 */ | |
840 CGMouseDelta dx1, dy1; | |
841 CGGetLastMouseDelta (&dx1, &dy1); | |
842 dx += dx1; | |
843 dy += dy1; | |
844 } | |
845 else if (firstMouseEvent) { | |
846 | |
847 /* | |
848 Get the first mouse event in a possible | |
849 sequence of mouse moved events. Since we | |
850 use absolute coordinates, this serves to | |
851 compensate any inaccuracy in deltas, and | |
852 provides the first known mouse position, | |
853 since everything after this uses deltas | |
854 */ | |
855 NSPoint p; | |
856 QZ_GetMouseLocation (this, &p); | |
857 SDL_PrivateMouseMotion (0, 0, p.x, p.y); | |
858 firstMouseEvent = 0; | |
859 } | |
860 else { | |
861 | |
862 /* | |
863 Get the amount moved since the last drag or move event, | |
864 add it on for one big move event at the end. | |
865 */ | |
866 dx += [ event deltaX ]; | |
867 dy += [ event deltaY ]; | |
868 } | |
869 | |
870 /* | |
871 Handle grab input+cursor visible by warping the cursor back | |
872 into the game window. This still generates a mouse moved event, | |
873 but not as a result of the warp (so it's in the right direction). | |
874 */ | |
875 if ( grab_state == QZ_VISIBLE_GRAB && | |
876 !isInGameWin ) { | |
877 | |
878 NSPoint p; | |
879 QZ_GetMouseLocation (this, &p); | |
880 | |
881 if ( p.x < 0.0 ) | |
882 p.x = 0.0; | |
883 | |
884 if ( p.y < 0.0 ) | |
885 p.y = 0.0; | |
886 | |
887 if ( p.x >= winRect.size.width ) | |
888 p.x = winRect.size.width-1; | |
889 | |
890 if ( p.y >= winRect.size.height ) | |
891 p.y = winRect.size.height-1; | |
892 | |
893 QZ_PrivateWarpCursor (this, p.x, p.y); | |
894 } | |
895 else | |
896 if ( !isInGameWin && (SDL_GetAppState() & SDL_APPMOUSEFOCUS) ) { | |
897 | |
898 SDL_PrivateAppActive (0, SDL_APPMOUSEFOCUS); | |
899 if (grab_state == QZ_INVISIBLE_GRAB) | |
900 /*The cursor has left the window even though it is | |
901 disassociated from the mouse (and therefore | |
902 shouldn't move): this can happen with Wacom | |
903 tablets, and it effectively breaks the grab, since | |
904 mouse down events now go to background | |
905 applications. The only possibility to avoid this | |
906 seems to be talking to the tablet driver | |
907 (AppleEvents) to constrain its mapped area to the | |
908 window, which may not be worth the effort. For | |
909 now, handle the condition more gracefully than | |
910 before by reassociating cursor and mouse until the | |
911 cursor enters the window again, making it obvious | |
912 to the user that the grab is broken.*/ | |
913 CGAssociateMouseAndMouseCursorPosition (1); | |
914 if (!cursor_should_be_visible) | |
915 QZ_ShowMouse (this); | |
916 } | |
917 else | |
918 if ( isInGameWin && (SDL_GetAppState() & (SDL_APPMOUSEFOCUS | SDL_APPINPUTFOCUS)) == SDL_APPINPUTFOCUS ) { | |
919 | |
920 SDL_PrivateAppActive (1, SDL_APPMOUSEFOCUS); | |
921 if (!cursor_should_be_visible) | |
922 QZ_HideMouse (this); | |
923 if (grab_state == QZ_INVISIBLE_GRAB) { /*see comment above*/ | |
924 QZ_PrivateWarpCursor (this, SDL_VideoSurface->w / 2, SDL_VideoSurface->h / 2); | |
925 CGAssociateMouseAndMouseCursorPosition (0); | |
926 } | |
927 } | |
928 break; | |
929 case NSScrollWheel: | |
930 if ( isInGameWin ) { | |
931 float dy, dx; | |
932 Uint8 button; | |
933 dy = [ event deltaY ]; | |
934 dx = [ event deltaX ]; | |
935 if ( dy > 0.0 || dx > 0.0 ) /* Scroll up */ | |
936 button = SDL_BUTTON_WHEELUP; | |
937 else /* Scroll down */ | |
938 button = SDL_BUTTON_WHEELDOWN; | |
939 /* For now, wheel is sent as a quick down+up */ | |
940 SDL_PrivateMouseButton (SDL_PRESSED, button, 0, 0); | |
941 SDL_PrivateMouseButton (SDL_RELEASED, button, 0, 0); | |
942 } | |
943 break; | |
944 case NSKeyUp: | |
945 QZ_DoKey (this, SDL_RELEASED, event); | |
946 break; | |
947 case NSKeyDown: | |
948 QZ_DoKey (this, SDL_PRESSED, event); | |
949 break; | |
950 case NSFlagsChanged: | |
951 break; | |
952 /* case NSAppKitDefined: break; */ | |
953 /* case NSApplicationDefined: break; */ | |
954 /* case NSPeriodic: break; */ | |
955 /* case NSCursorUpdate: break; */ | |
956 default: | |
957 [ NSApp sendEvent:event ]; | |
958 } | 983 } |
959 } | 984 } |
960 } while (event != nil); | 985 } |
961 | 986 while (event != nil); |
987 | |
962 /* handle accumulated mouse moved events */ | 988 /* handle accumulated mouse moved events */ |
963 if (dx != 0 || dy != 0) | 989 if (dx != 0 || dy != 0) |
964 SDL_PrivateMouseMotion (0, 1, dx, dy); | 990 SDL_PrivateMouseMotion (0, 1, dx, dy); |
965 | 991 |
966 [ pool release ]; | 992 [pool release]; |
967 } | 993 } |
968 | 994 |
969 void QZ_UpdateMouse (_THIS) | 995 void |
996 QZ_UpdateMouse (_THIS) | |
970 { | 997 { |
971 NSPoint p; | 998 NSPoint p; |
972 QZ_GetMouseLocation (this, &p); | 999 QZ_GetMouseLocation (this, &p); |
973 SDL_PrivateAppActive (QZ_IsMouseInWindow (this), SDL_APPMOUSEFOCUS); | 1000 SDL_PrivateAppActive (QZ_IsMouseInWindow (this), SDL_APPMOUSEFOCUS); |
974 SDL_PrivateMouseMotion (0, 0, p.x, p.y); | 1001 SDL_PrivateMouseMotion (0, 0, p.x, p.y); |