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, &notifier); 711 power_connection =
684 712 IORegisterForSystemPower (this, &thePortRef,
685 if (power_connection == 0) 713 QZ_SleepNotificationHandler, &notifier);
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);