comparison src/video/quartz/SDL_QuartzEvents.m @ 1895:c121d94672cb

SDL 1.2 is moving to a branch, and SDL 1.3 is becoming the head.
author Sam Lantinga <slouken@libsdl.org>
date Mon, 10 Jul 2006 21:04:37 +0000
parents 406b8325ee34
children
comparison
equal deleted inserted replaced
1894:c69cee13dd76 1895:c121d94672cb
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 if (SDL_TranslateUNICODE) { 265 chars =[event characters];
264 chars = [ event characters ]; 266 numChars =[chars length];
265 numChars = [ chars length ]; 267
266 } else { 268 if (numChars == 1) {
267 numChars = 0; 269
268 } 270 key.scancode =[event keyCode];
269 271 key.sym = keymap[key.scancode];
270 if (numChars == 0) { 272 key.unicode =[chars characterAtIndex:0];
271 273 key.mod = KMOD_NONE;
272 key.scancode = [ event keyCode ];
273 key.sym = keymap [ key.scancode ];
274 key.unicode = 0;
275 key.mod = KMOD_NONE;
276 274
277 SDL_PrivateKeyboard (state, &key); 275 SDL_PrivateKeyboard (state, &key);
278 } 276 } else if (numChars == 0) {
279 else if (numChars == 1) { 277
280 278 key.scancode =[event keyCode];
281 key.scancode = [ event keyCode ]; 279 key.sym = keymap[key.scancode];
282 key.sym = keymap [ key.scancode ]; 280 key.unicode = 0;
283 key.unicode = [ chars characterAtIndex:0 ]; 281 key.mod = KMOD_NONE;
284 key.mod = KMOD_NONE;
285 282
286 SDL_PrivateKeyboard (state, &key); 283 SDL_PrivateKeyboard (state, &key);
287 } 284 } else { /* (numChars > 1) */
288 else /* (numChars > 1) */ { 285
289 286
290 int i; 287 int i;
291 for (i = 0; i < numChars; i++) { 288 for (i = 0; i < numChars; i++) {
292 289
293 key.scancode = 0; 290 key.scancode = 0;
294 key.sym = 0; 291 key.sym = 0;
295 key.unicode = [ chars characterAtIndex:i]; 292 key.unicode =[chars characterAtIndex:i];
296 key.mod = KMOD_NONE; 293 key.mod = KMOD_NONE;
297 294
298 SDL_PrivateKeyboard (state, &key); 295 SDL_PrivateKeyboard (state, &key);
299 } 296 }
300 } 297 }
301 298
302 if (SDL_getenv ("SDL_ENABLEAPPEVENTS")) 299 if (SDL_getenv ("SDL_ENABLEAPPEVENTS"))
303 [ NSApp sendEvent:event ]; 300 [NSApp sendEvent:event];
304 } 301 }
305 302
306 /* This is the original behavior, before support was added for 303 /* This is the original behavior, before support was added for
307 * differentiating between left and right versions of the keys. 304 * differentiating between left and right versions of the keys.
308 */ 305 */
309 static void QZ_DoUnsidedModifiers (_THIS, unsigned int newMods) { 306 static void
310 307 QZ_DoUnsidedModifiers (_THIS, unsigned int newMods)
311 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 };
312 312
313 int i; 313 int i;
314 int bit; 314 int bit;
315 SDL_keysym key; 315 SDL_keysym key;
316 316
317 key.scancode = 0; 317 key.scancode = 0;
318 key.sym = SDLK_UNKNOWN; 318 key.sym = SDLK_UNKNOWN;
319 key.unicode = 0; 319 key.unicode = 0;
320 key.mod = KMOD_NONE; 320 key.mod = KMOD_NONE;
321 321
322 /* Iterate through the bits, testing each against the current modifiers */ 322 /* Iterate through the bits, testing each against the current modifiers */
323 for (i = 0, bit = NSAlphaShiftKeyMask; bit <= NSCommandKeyMask; bit <<= 1, ++i) { 323 for (i = 0, bit = NSAlphaShiftKeyMask; bit <= NSCommandKeyMask;
324 bit <<= 1, ++i) {
324 325
325 unsigned int currentMask, newMask; 326 unsigned int currentMask, newMask;
326 327
327 currentMask = current_mods & bit; 328 currentMask = current_mods & bit;
328 newMask = newMods & bit; 329 newMask = newMods & bit;
329 330
330 if ( currentMask && 331 if (currentMask && currentMask != newMask) { /* modifier up event */
331 currentMask != newMask ) { /* modifier up event */ 332
332 333 key.sym = mapping[i];
333 key.sym = mapping[i]; 334 /* If this was Caps Lock, we need some additional voodoo to make SDL happy */
334 /* If this was Caps Lock, we need some additional voodoo to make SDL happy */ 335 if (bit == NSAlphaShiftKeyMask)
335 if (bit == NSAlphaShiftKeyMask) 336 SDL_PrivateKeyboard (SDL_PRESSED, &key);
336 SDL_PrivateKeyboard (SDL_PRESSED, &key); 337 SDL_PrivateKeyboard (SDL_RELEASED, &key);
337 SDL_PrivateKeyboard (SDL_RELEASED, &key); 338 } else if (newMask && currentMask != newMask) { /* modifier down event */
338 } 339
339 else if ( newMask && 340 key.sym = mapping[i];
340 currentMask != newMask ) { /* modifier down event */ 341 SDL_PrivateKeyboard (SDL_PRESSED, &key);
341 342 /* If this was Caps Lock, we need some additional voodoo to make SDL happy */
342 key.sym = mapping[i]; 343 if (bit == NSAlphaShiftKeyMask)
343 SDL_PrivateKeyboard (SDL_PRESSED, &key); 344 SDL_PrivateKeyboard (SDL_RELEASED, &key);
344 /* If this was Caps Lock, we need some additional voodoo to make SDL happy */
345 if (bit == NSAlphaShiftKeyMask)
346 SDL_PrivateKeyboard (SDL_RELEASED, &key);
347 } 345 }
348 } 346 }
349 } 347 }
350 348
351 /* This is a helper function for QZ_HandleModifierSide. This 349 /* This is a helper function for QZ_HandleModifierSide. This
352 * function reverts back to behavior before the distinction between 350 * function reverts back to behavior before the distinction between
353 * sides was made. 351 * sides was made.
354 */ 352 */
355 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 {
356 unsigned int currentMask, newMask; 357 unsigned int currentMask, newMask;
357 SDL_keysym key; 358 SDL_keysym key;
358 359
359 key.scancode = 0; 360 key.scancode = 0;
360 key.sym = key_sym; 361 key.sym = key_sym;
361 key.unicode = 0; 362 key.unicode = 0;
362 key.mod = KMOD_NONE; 363 key.mod = KMOD_NONE;
363 364
364 /* 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
365 * figure out what changed 366 * figure out what changed
366 */ 367 */
367 currentMask = current_mods & device_independent_mask; 368 currentMask = current_mods & device_independent_mask;
368 newMask = newMods & device_independent_mask; 369 newMask = newMods & device_independent_mask;
369 370
370 if ( currentMask && 371 if (currentMask && currentMask != newMask) { /* modifier up event */
371 currentMask != newMask ) { /* modifier up event */ 372 SDL_PrivateKeyboard (SDL_RELEASED, &key);
372 SDL_PrivateKeyboard (SDL_RELEASED, &key); 373 } else if (newMask && currentMask != newMask) { /* modifier down event */
373 } 374 SDL_PrivateKeyboard (SDL_PRESSED, &key);
374 else if ( newMask &&
375 currentMask != newMask ) { /* modifier down event */
376 SDL_PrivateKeyboard (SDL_PRESSED, &key);
377 } 375 }
378 } 376 }
379 377
380 /* This is a helper function for QZ_HandleModifierSide. 378 /* This is a helper function for QZ_HandleModifierSide.
381 * This function sets the actual SDL_PrivateKeyboard event. 379 * This function sets the actual SDL_PrivateKeyboard event.
382 */ 380 */
383 static void QZ_HandleModifierOneSide ( _THIS, unsigned int newMods, 381 static void
384 unsigned int key_sym, 382 QZ_HandleModifierOneSide (_THIS, unsigned int newMods,
385 unsigned int sided_device_dependent_mask ) { 383 unsigned int key_sym,
386 384 unsigned int sided_device_dependent_mask)
385 {
386
387 SDL_keysym key; 387 SDL_keysym key;
388 unsigned int current_dep_mask, new_dep_mask; 388 unsigned int current_dep_mask, new_dep_mask;
389 389
390 key.scancode = 0; 390 key.scancode = 0;
391 key.sym = key_sym; 391 key.sym = key_sym;
392 key.unicode = 0; 392 key.unicode = 0;
393 key.mod = KMOD_NONE; 393 key.mod = KMOD_NONE;
394 394
395 /* 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
396 * figure out what changed 396 * figure out what changed
397 */ 397 */
398 current_dep_mask = current_mods & sided_device_dependent_mask; 398 current_dep_mask = current_mods & sided_device_dependent_mask;
399 new_dep_mask = newMods & sided_device_dependent_mask; 399 new_dep_mask = newMods & sided_device_dependent_mask;
400 400
401 /* 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
402 * 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
403 * find out which it is. 403 * find out which it is.
404 */ 404 */
405 if( new_dep_mask && 405 if (new_dep_mask && current_dep_mask != new_dep_mask) {
406 current_dep_mask != new_dep_mask ) {
407 /* Modifier down event */ 406 /* Modifier down event */
408 SDL_PrivateKeyboard (SDL_PRESSED, &key); 407 SDL_PrivateKeyboard (SDL_PRESSED, &key);
409 } 408 } else { /* Modifier up event */
410 else /* Modifier up event */ { 409
411 SDL_PrivateKeyboard (SDL_RELEASED, &key); 410 SDL_PrivateKeyboard (SDL_RELEASED, &key);
412 } 411 }
413 } 412 }
414 413
415 /* This is a helper function for QZ_DoSidedModifiers. 414 /* This is a helper function for QZ_DoSidedModifiers.
416 * 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,
417 * e.g. left-shift vs right-shift. 416 * e.g. left-shift vs right-shift.
418 */ 417 */
419 static void QZ_HandleModifierSide ( _THIS, int device_independent_mask, 418 static void
420 unsigned int newMods, 419 QZ_HandleModifierSide (_THIS, int device_independent_mask,
421 unsigned int left_key_sym, 420 unsigned int newMods,
422 unsigned int right_key_sym, 421 unsigned int left_key_sym,
423 unsigned int left_device_dependent_mask, 422 unsigned int right_key_sym,
424 unsigned int right_device_dependent_mask ) { 423 unsigned int left_device_dependent_mask,
424 unsigned int right_device_dependent_mask)
425 {
425 unsigned int device_dependent_mask = 0; 426 unsigned int device_dependent_mask = 0;
426 unsigned int diff_mod = 0; 427 unsigned int diff_mod = 0;
427 428
428 device_dependent_mask = left_device_dependent_mask | right_device_dependent_mask; 429 device_dependent_mask =
430 left_device_dependent_mask | right_device_dependent_mask;
429 /* 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
430 * 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
431 * keyboard and revert to the unsided behavior. 433 * keyboard and revert to the unsided behavior.
432 */ 434 */
433 if ( (device_dependent_mask & newMods) == 0 ) { 435 if ((device_dependent_mask & newMods) == 0) {
434 /* Revert to the old behavior */ 436 /* Revert to the old behavior */
435 QZ_HandleNonDeviceModifier ( this, device_independent_mask, newMods, left_key_sym ); 437 QZ_HandleNonDeviceModifier (this, device_independent_mask, newMods,
438 left_key_sym);
436 return; 439 return;
437 } 440 }
438 441
439 /* 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 */
440 diff_mod = (device_dependent_mask & current_mods) 443 diff_mod = (device_dependent_mask & current_mods)
441 ^ (device_dependent_mask & newMods); 444 ^ (device_dependent_mask & newMods);
442 445
443 if ( diff_mod ) { 446 if (diff_mod) {
444 /* 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
445 * to handle them separately just in case the values can simulataneously 448 * to handle them separately just in case the values can simulataneously
446 * change or if the bits don't both exist. 449 * change or if the bits don't both exist.
447 */ 450 */
448 if ( left_device_dependent_mask & diff_mod ) { 451 if (left_device_dependent_mask & diff_mod) {
449 QZ_HandleModifierOneSide ( this, newMods, left_key_sym, left_device_dependent_mask ); 452 QZ_HandleModifierOneSide (this, newMods, left_key_sym,
453 left_device_dependent_mask);
450 } 454 }
451 if ( right_device_dependent_mask & diff_mod ) { 455 if (right_device_dependent_mask & diff_mod) {
452 QZ_HandleModifierOneSide ( this, newMods, right_key_sym, right_device_dependent_mask ); 456 QZ_HandleModifierOneSide (this, newMods, right_key_sym,
457 right_device_dependent_mask);
453 } 458 }
454 } 459 }
455 } 460 }
456 461
457 /* This is a helper function for QZ_DoSidedModifiers. 462 /* This is a helper function for QZ_DoSidedModifiers.
458 * This function will release a key press in the case that 463 * This function will release a key press in the case that
459 * 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
460 * can't still be down). 465 * can't still be down).
461 */ 466 */
462 static void QZ_ReleaseModifierSide ( _THIS, 467 static void
463 unsigned int device_independent_mask, 468 QZ_ReleaseModifierSide (_THIS,
464 unsigned int newMods, 469 unsigned int device_independent_mask,
465 unsigned int left_key_sym, 470 unsigned int newMods,
466 unsigned int right_key_sym, 471 unsigned int left_key_sym,
467 unsigned int left_device_dependent_mask, 472 unsigned int right_key_sym,
468 unsigned int right_device_dependent_mask ) { 473 unsigned int left_device_dependent_mask,
474 unsigned int right_device_dependent_mask)
475 {
469 unsigned int device_dependent_mask = 0; 476 unsigned int device_dependent_mask = 0;
470 SDL_keysym key; 477 SDL_keysym key;
471 478
472 key.scancode = 0; 479 key.scancode = 0;
473 key.sym = SDLK_UNKNOWN; 480 key.sym = SDLK_UNKNOWN;
474 key.unicode = 0; 481 key.unicode = 0;
475 key.mod = KMOD_NONE; 482 key.mod = KMOD_NONE;
476 483
477 device_dependent_mask = left_device_dependent_mask | right_device_dependent_mask; 484 device_dependent_mask =
485 left_device_dependent_mask | right_device_dependent_mask;
478 /* 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
479 * 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
480 * keyboard and revert to the unsided behavior. 488 * keyboard and revert to the unsided behavior.
481 */ 489 */
482 if ( (device_dependent_mask & current_mods) == 0 ) { 490 if ((device_dependent_mask & current_mods) == 0) {
483 /* 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
484 * to represent both, and release it. 492 * to represent both, and release it.
485 */ 493 */
486 key.sym = left_key_sym; 494 key.sym = left_key_sym;
487 SDL_PrivateKeyboard (SDL_RELEASED, &key); 495 SDL_PrivateKeyboard (SDL_RELEASED, &key);
488 496
489 return; 497 return;
490 } 498 }
491 499
492 500
493 /* 501 /*
494 * 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,
495 * 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.
496 * 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,
497 * so I hope this doesn't cause other problems. 505 * so I hope this doesn't cause other problems.
498 */ 506 */
499 if ( left_device_dependent_mask & current_mods ) { 507 if (left_device_dependent_mask & current_mods) {
500 key.sym = left_key_sym; 508 key.sym = left_key_sym;
501 SDL_PrivateKeyboard (SDL_RELEASED, &key); 509 SDL_PrivateKeyboard (SDL_RELEASED, &key);
502 } 510 }
503 if ( right_device_dependent_mask & current_mods ) { 511 if (right_device_dependent_mask & current_mods) {
504 key.sym = right_key_sym; 512 key.sym = right_key_sym;
505 SDL_PrivateKeyboard (SDL_RELEASED, &key); 513 SDL_PrivateKeyboard (SDL_RELEASED, &key);
506 } 514 }
507 } 515 }
508 516
509 /* This is a helper function for QZ_DoSidedModifiers. 517 /* This is a helper function for QZ_DoSidedModifiers.
510 * This function handles the CapsLock case. 518 * This function handles the CapsLock case.
511 */ 519 */
512 static void QZ_HandleCapsLock (_THIS, unsigned int newMods) { 520 static void
521 QZ_HandleCapsLock (_THIS, unsigned int newMods)
522 {
513 unsigned int currentMask, newMask; 523 unsigned int currentMask, newMask;
514 SDL_keysym key; 524 SDL_keysym key;
515 525
516 key.scancode = 0; 526 key.scancode = 0;
517 key.sym = SDLK_CAPSLOCK; 527 key.sym = SDLK_CAPSLOCK;
518 key.unicode = 0; 528 key.unicode = 0;
519 key.mod = KMOD_NONE; 529 key.mod = KMOD_NONE;
520 530
521 currentMask = current_mods & NSAlphaShiftKeyMask; 531 currentMask = current_mods & NSAlphaShiftKeyMask;
522 newMask = newMods & NSAlphaShiftKeyMask; 532 newMask = newMods & NSAlphaShiftKeyMask;
523 533
524 if ( currentMask && 534 if (currentMask && currentMask != newMask) { /* modifier up event */
525 currentMask != newMask ) { /* modifier up event */
526 /* If this was Caps Lock, we need some additional voodoo to make SDL happy */
527 SDL_PrivateKeyboard (SDL_PRESSED, &key);
528 SDL_PrivateKeyboard (SDL_RELEASED, &key);
529 }
530 else if ( newMask &&
531 currentMask != newMask ) { /* modifier down event */
532 /* 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 */
533 SDL_PrivateKeyboard (SDL_PRESSED, &key); 536 SDL_PrivateKeyboard (SDL_PRESSED, &key);
534 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);
535 } 542 }
536 } 543 }
537 544
538 /* This function will handle the modifier keys and also determine the 545 /* This function will handle the modifier keys and also determine the
539 * correct side of the key. 546 * correct side of the key.
540 */ 547 */
541 static void QZ_DoSidedModifiers (_THIS, unsigned int newMods) { 548 static void
542 /* Set up arrays for the key syms for the left and right side. */ 549 QZ_DoSidedModifiers (_THIS, unsigned int newMods)
543 const unsigned int left_mapping[] = { SDLK_LSHIFT, SDLK_LCTRL, SDLK_LALT, SDLK_LMETA }; 550 {
544 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. */
545 /* 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
546 * correspond to the _mapping arrays 557 * correspond to the _mapping arrays
547 */ 558 */
548 const unsigned int left_device_mapping[] = { NX_DEVICELSHIFTKEYMASK, NX_DEVICELCTLKEYMASK, NX_DEVICELALTKEYMASK, NX_DEVICELCMDKEYMASK }; 559 const unsigned int left_device_mapping[] =
549 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 };
550 567
551 unsigned int i; 568 unsigned int i;
552 unsigned int bit; 569 unsigned int bit;
553 570
554 /* 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 */
555 QZ_HandleCapsLock ( this, newMods ); 572 QZ_HandleCapsLock (this, newMods);
556 573
557 /* Iterate through the bits, testing each against the current modifiers */ 574 /* Iterate through the bits, testing each against the current modifiers */
558 for (i = 0, bit = NSShiftKeyMask; bit <= NSCommandKeyMask; bit <<= 1, ++i) { 575 for (i = 0, bit = NSShiftKeyMask; bit <= NSCommandKeyMask; bit <<= 1, ++i) {
559 576
560 unsigned int currentMask, newMask; 577 unsigned int currentMask, newMask;
561 578
562 currentMask = current_mods & bit; 579 currentMask = current_mods & bit;
563 newMask = newMods & bit; 580 newMask = newMods & bit;
564 581
565 /* 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
566 * and right side keys may alternate or both may be pressed. 583 * and right side keys may alternate or both may be pressed.
567 */ 584 */
568 if ( newMask ) { 585 if (newMask) {
569 QZ_HandleModifierSide ( this, bit, newMods, 586 QZ_HandleModifierSide (this, bit, newMods,
570 left_mapping[i], 587 left_mapping[i],
571 right_mapping[i], 588 right_mapping[i],
572 left_device_mapping[i], 589 left_device_mapping[i],
573 right_device_mapping[i] ); 590 right_device_mapping[i]);
574 } 591 }
575 /* If the state changed from pressed to unpressed, we must examine 592 /* If the state changed from pressed to unpressed, we must examine
576 * the device dependent bits to release the correct keys. 593 * the device dependent bits to release the correct keys.
577 */ 594 */
578 else if ( currentMask && 595 else if (currentMask && currentMask != newMask) { /* modifier up event */
579 currentMask != newMask ) { /* modifier up event */ 596 QZ_ReleaseModifierSide (this, bit, newMods,
580 QZ_ReleaseModifierSide ( this, bit, newMods, 597 left_mapping[i],
581 left_mapping[i], 598 right_mapping[i],
582 right_mapping[i], 599 left_device_mapping[i],
583 left_device_mapping[i], 600 right_device_mapping[i]);
584 right_device_mapping[i] );
585 } 601 }
586 } 602 }
587 } 603 }
588 604
589 /* This function is called to handle the modifiers. 605 /* This function is called to handle the modifiers.
590 * 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
591 * of the keyboard for those modifiers that qualify if the 607 * of the keyboard for those modifiers that qualify if the
592 * operating system version supports it. Otherwise, the code 608 * operating system version supports it. Otherwise, the code
593 * will not try to make the distinction. 609 * will not try to make the distinction.
594 */ 610 */
595 static void QZ_DoModifiers (_THIS, unsigned int newMods) { 611 static void
596 612 QZ_DoModifiers (_THIS, unsigned int newMods)
613 {
614
597 if (current_mods == newMods) 615 if (current_mods == newMods)
598 return; 616 return;
599 617
600 /* 618 /*
601 * Starting with Panther (10.3.0), the ability to distinguish between 619 * Starting with Panther (10.3.0), the ability to distinguish between
602 * left side and right side modifiers is available. 620 * left side and right side modifiers is available.
603 */ 621 */
604 if( system_version >= 0x1030 ) { 622 if (system_version >= 0x1030) {
605 QZ_DoSidedModifiers (this, newMods); 623 QZ_DoSidedModifiers (this, newMods);
606 } 624 } else {
607 else {
608 QZ_DoUnsidedModifiers (this, newMods); 625 QZ_DoUnsidedModifiers (this, newMods);
609 } 626 }
610 627
611 current_mods = newMods; 628 current_mods = newMods;
612 } 629 }
613 630
614 static void QZ_GetMouseLocation (_THIS, NSPoint *p) { 631 static void
615 *p = [ NSEvent mouseLocation ]; /* global coordinates */ 632 QZ_GetMouseLocation (_THIS, NSPoint * p)
633 {
634 *p =[NSEvent mouseLocation]; /* global coordinates */
616 if (qz_window) 635 if (qz_window)
617 QZ_PrivateGlobalToLocal (this, p); 636 QZ_PrivateGlobalToLocal (this, p);
618 QZ_PrivateCocoaToSDL (this, p); 637 QZ_PrivateCocoaToSDL (this, p);
619 } 638 }
620 639
621 void QZ_DoActivate (_THIS) { 640 void
622 641 QZ_DoActivate (_THIS)
623 SDL_PrivateAppActive (1, SDL_APPINPUTFOCUS | (QZ_IsMouseInWindow (this) ? SDL_APPMOUSEFOCUS : 0)); 642 {
624 643
644 SDL_PrivateAppActive (1,
645 SDL_APPINPUTFOCUS | (QZ_IsMouseInWindow (this) ?
646 SDL_APPMOUSEFOCUS : 0));
647
625 /* Hide the cursor if it was hidden by SDL_ShowCursor() */ 648 /* Hide the cursor if it was hidden by SDL_ShowCursor() */
626 if (!cursor_should_be_visible) 649 if (!cursor_should_be_visible)
627 QZ_HideMouse (this); 650 QZ_HideMouse (this);
628 651
629 /* Regrab input, only if it was previously grabbed */ 652 /* Regrab input, only if it was previously grabbed */
630 if ( current_grab_mode == SDL_GRAB_ON ) { 653 if (current_grab_mode == SDL_GRAB_ON) {
631 654
632 /* Restore cursor location if input was grabbed */ 655 /* Restore cursor location if input was grabbed */
633 QZ_PrivateWarpCursor (this, cursor_loc.x, cursor_loc.y); 656 QZ_PrivateWarpCursor (this, cursor_loc.x, cursor_loc.y);
634 QZ_ChangeGrabState (this, QZ_ENABLE_GRAB); 657 QZ_ChangeGrabState (this, QZ_ENABLE_GRAB);
635 } 658 } else {
636 else {
637 /* Update SDL's mouse location */ 659 /* Update SDL's mouse location */
638 NSPoint p; 660 NSPoint p;
639 QZ_GetMouseLocation (this, &p); 661 QZ_GetMouseLocation (this, &p);
640 SDL_PrivateMouseMotion (0, 0, p.x, p.y); 662 SDL_PrivateMouseMotion (0, 0, p.x, p.y);
641 } 663 }
642 } 664 }
643 665
644 void QZ_DoDeactivate (_THIS) { 666 void
645 667 QZ_DoDeactivate (_THIS)
668 {
669
646 SDL_PrivateAppActive (0, SDL_APPINPUTFOCUS | SDL_APPMOUSEFOCUS); 670 SDL_PrivateAppActive (0, SDL_APPINPUTFOCUS | SDL_APPMOUSEFOCUS);
647 671
648 /* Get the current cursor location, for restore on activate */ 672 /* Get the current cursor location, for restore on activate */
649 QZ_GetMouseLocation (this, &cursor_loc); 673 QZ_GetMouseLocation (this, &cursor_loc);
650 674
651 /* Reassociate mouse and cursor */ 675 /* Reassociate mouse and cursor */
652 CGAssociateMouseAndMouseCursorPosition (1); 676 CGAssociateMouseAndMouseCursorPosition (1);
653 677
654 /* Show the cursor if it was hidden by SDL_ShowCursor() */ 678 /* Show the cursor if it was hidden by SDL_ShowCursor() */
655 if (!cursor_should_be_visible) 679 if (!cursor_should_be_visible)
656 QZ_ShowMouse (this); 680 QZ_ShowMouse (this);
657 } 681 }
658 682
659 void QZ_SleepNotificationHandler (void * refcon, 683 void
660 io_service_t service, 684 QZ_SleepNotificationHandler (void *refcon,
661 natural_t messageType, 685 io_service_t service,
662 void * messageArgument ) 686 natural_t messageType, void *messageArgument)
663 { 687 {
664 SDL_VideoDevice *this = (SDL_VideoDevice*)refcon; 688 SDL_VideoDevice *this = (SDL_VideoDevice *) refcon;
665 689
666 switch(messageType) 690 switch (messageType) {
667 { 691 case kIOMessageSystemWillSleep:
668 case kIOMessageSystemWillSleep: 692 IOAllowPowerChange (power_connection, (long) messageArgument);
669 IOAllowPowerChange(power_connection, (long) messageArgument); 693 break;
670 break; 694 case kIOMessageCanSystemSleep:
671 case kIOMessageCanSystemSleep: 695 IOAllowPowerChange (power_connection, (long) messageArgument);
672 IOAllowPowerChange(power_connection, (long) messageArgument); 696 break;
673 break; 697 case kIOMessageSystemHasPoweredOn:
674 case kIOMessageSystemHasPoweredOn: 698 /* awake */
675 /* awake */ 699 SDL_PrivateExpose ();
676 SDL_PrivateExpose(); 700 break;
677 break; 701 }
678 } 702 }
679 } 703
680 704 void
681 void QZ_RegisterForSleepNotifications (_THIS) 705 QZ_RegisterForSleepNotifications (_THIS)
682 { 706 {
683 CFRunLoopSourceRef rls; 707 CFRunLoopSourceRef rls;
684 IONotificationPortRef thePortRef; 708 IONotificationPortRef thePortRef;
685 io_object_t notifier; 709 io_object_t notifier;
686 710
687 power_connection = IORegisterForSystemPower (this, &thePortRef, QZ_SleepNotificationHandler, &notifier); 711 power_connection =
688 712 IORegisterForSystemPower (this, &thePortRef,
689 if (power_connection == 0) 713 QZ_SleepNotificationHandler, &notifier);
690 NSLog(@"SDL: QZ_SleepNotificationHandler() IORegisterForSystemPower failed."); 714
691 715 if (power_connection == 0)
692 rls = IONotificationPortGetRunLoopSource (thePortRef); 716 NSLog
693 CFRunLoopAddSource (CFRunLoopGetCurrent(), rls, kCFRunLoopDefaultMode); 717 (@"SDL: QZ_SleepNotificationHandler() IORegisterForSystemPower failed.");
694 CFRelease (rls); 718
719 rls = IONotificationPortGetRunLoopSource (thePortRef);
720 CFRunLoopAddSource (CFRunLoopGetCurrent (), rls, kCFRunLoopDefaultMode);
721 CFRelease (rls);
695 } 722 }
696 723
697 724
698 /* Try to map Quartz mouse buttons to SDL's lingo... */ 725 /* Try to map Quartz mouse buttons to SDL's lingo... */
699 static int QZ_OtherMouseButtonToSDL(int button) 726 static int
700 { 727 QZ_OtherMouseButtonToSDL (int button)
701 switch (button) 728 {
702 { 729 switch (button) {
703 case 0: 730 case 0:
704 return(SDL_BUTTON_LEFT); /* 1 */ 731 return (SDL_BUTTON_LEFT); /* 1 */
705 case 1: 732 case 1:
706 return(SDL_BUTTON_RIGHT); /* 3 */ 733 return (SDL_BUTTON_RIGHT); /* 3 */
707 case 2: 734 case 2:
708 return(SDL_BUTTON_MIDDLE); /* 2 */ 735 return (SDL_BUTTON_MIDDLE); /* 2 */
709 } 736 }
710 737
711 /* >= 3: skip 4 & 5, since those are the SDL mousewheel buttons. */ 738 /* >= 3: skip 4 & 5, since those are the SDL mousewheel buttons. */
712 return(button + 3); 739 return (button + 3);
713 } 740 }
714 741
715 742
716 void QZ_PumpEvents (_THIS) 743 void
744 QZ_PumpEvents (_THIS)
717 { 745 {
718 static Uint32 screensaverTicks = 0; 746 static Uint32 screensaverTicks = 0;
719 Uint32 nowTicks; 747 Uint32 nowTicks;
720 int firstMouseEvent; 748 int firstMouseEvent;
721 CGMouseDelta dx, dy; 749 CGMouseDelta dx, dy;
724 NSEvent *event; 752 NSEvent *event;
725 NSRect winRect; 753 NSRect winRect;
726 NSAutoreleasePool *pool; 754 NSAutoreleasePool *pool;
727 755
728 if (!SDL_VideoSurface) 756 if (!SDL_VideoSurface)
729 return; /* don't do anything if there's no screen surface. */ 757 return; /* don't do anything if there's no screen surface. */
730 758
731 /* Update activity every five seconds to prevent screensaver. --ryan. */ 759 /* Update activity every five seconds to prevent screensaver. --ryan. */
732 nowTicks = SDL_GetTicks(); 760 nowTicks = SDL_GetTicks ();
733 if ((nowTicks - screensaverTicks) > 5000) 761 if ((nowTicks - screensaverTicks) > 5000) {
734 { 762 UpdateSystemActivity (UsrActivity);
735 UpdateSystemActivity(UsrActivity);
736 screensaverTicks = nowTicks; 763 screensaverTicks = nowTicks;
737 } 764 }
738 765
739 pool = [ [ NSAutoreleasePool alloc ] init ]; 766 pool =[[NSAutoreleasePool alloc] init];
740 distantPast = [ NSDate distantPast ]; 767 distantPast =[NSDate distantPast];
741 768
742 winRect = NSMakeRect (0, 0, SDL_VideoSurface->w, SDL_VideoSurface->h); 769 winRect = NSMakeRect (0, 0, SDL_VideoSurface->w, SDL_VideoSurface->h);
743 770
744 /* send the first mouse event in absolute coordinates */ 771 /* send the first mouse event in absolute coordinates */
745 firstMouseEvent = 1; 772 firstMouseEvent = 1;
746 773
747 /* accumulate any additional mouse moved events into one SDL mouse event */ 774 /* accumulate any additional mouse moved events into one SDL mouse event */
748 dx = 0; 775 dx = 0;
749 dy = 0; 776 dy = 0;
750 777
751 do { 778 do {
752 779
753 /* Poll for an event. This will not block */ 780 /* Poll for an event. This will not block */
754 event = [ NSApp nextEventMatchingMask:NSAnyEventMask 781 event =[NSApp nextEventMatchingMask: NSAnyEventMask untilDate: distantPast inMode: NSDefaultRunLoopMode dequeue:YES];
755 untilDate:distantPast
756 inMode: NSDefaultRunLoopMode dequeue:YES ];
757 if (event != nil) { 782 if (event != nil) {
758 783
759 int button; 784 int button;
760 unsigned int type; 785 unsigned int type;
761 BOOL isInGameWin; 786 BOOL isInGameWin;
762 787
763 #define DO_MOUSE_DOWN(button) do { \ 788 #define DO_MOUSE_DOWN(button) do { \
764 if ( SDL_GetAppState() & SDL_APPMOUSEFOCUS ) { \ 789 if ( SDL_GetAppState() & SDL_APPMOUSEFOCUS ) { \
765 SDL_PrivateMouseButton (SDL_PRESSED, button, 0, 0); \ 790 SDL_PrivateMouseButton (SDL_PRESSED, button, 0, 0); \
766 expect_mouse_up |= 1<<button; \ 791 expect_mouse_up |= 1<<button; \
767 } \ 792 } \
768 [ NSApp sendEvent:event ]; \ 793 [ NSApp sendEvent:event ]; \
769 } while(0) 794 } while(0)
770 795
771 #define DO_MOUSE_UP(button) do { \ 796 #define DO_MOUSE_UP(button) do { \
772 if ( expect_mouse_up & (1<<button) ) { \ 797 if ( expect_mouse_up & (1<<button) ) { \
773 SDL_PrivateMouseButton (SDL_RELEASED, button, 0, 0); \ 798 SDL_PrivateMouseButton (SDL_RELEASED, button, 0, 0); \
774 expect_mouse_up &= ~(1<<button); \ 799 expect_mouse_up &= ~(1<<button); \
775 } \ 800 } \
776 [ NSApp sendEvent:event ]; \ 801 [ NSApp sendEvent:event ]; \
777 } while(0) 802 } while(0)
778 803
779 type = [ event type ]; 804 type =[event type];
780 isInGameWin = QZ_IsMouseInWindow (this); 805 isInGameWin = QZ_IsMouseInWindow (this);
781 806
782 QZ_DoModifiers(this, [ event modifierFlags ] ); 807 QZ_DoModifiers (this,[event modifierFlags]);
783 808
784 switch (type) { 809 switch (type) {
785 case NSLeftMouseDown: 810 case NSLeftMouseDown:
786 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 {
787 DO_MOUSE_DOWN (SDL_BUTTON_LEFT); 821 DO_MOUSE_DOWN (SDL_BUTTON_LEFT);
788 } else {
789 if ( NSCommandKeyMask & current_mods ) {
790 last_virtual_button = SDL_BUTTON_RIGHT;
791 DO_MOUSE_DOWN (SDL_BUTTON_RIGHT);
792 }
793 else if ( NSAlternateKeyMask & current_mods ) {
794 last_virtual_button = SDL_BUTTON_MIDDLE;
795 DO_MOUSE_DOWN (SDL_BUTTON_MIDDLE);
796 }
797 else {
798 DO_MOUSE_DOWN (SDL_BUTTON_LEFT);
799 }
800 } 822 }
801 break; 823 }
802 824 break;
803 case NSLeftMouseUp: 825
804 if ( last_virtual_button != 0 ) { 826 case NSLeftMouseUp:
805 DO_MOUSE_UP (last_virtual_button); 827 if (last_virtual_button != 0) {
806 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);
807 } 951 }
808 else { 952 }
809 DO_MOUSE_UP (SDL_BUTTON_LEFT); 953 break;
810 } 954 case NSScrollWheel:
811 break; 955 if (isInGameWin) {
812 956 float dy, dx;
813 case NSOtherMouseDown: 957 Uint8 button;
814 case NSRightMouseDown: 958 dy =[event deltaY];
815 button = QZ_OtherMouseButtonToSDL([ event buttonNumber ]); 959 dx =[event deltaX];
816 DO_MOUSE_DOWN (button); 960 if (dy > 0.0 || dx > 0.0) /* Scroll up */
817 break; 961 button = SDL_BUTTON_WHEELUP;
818 962 else /* Scroll down */
819 case NSOtherMouseUp: 963 button = SDL_BUTTON_WHEELDOWN;
820 case NSRightMouseUp: 964 /* For now, wheel is sent as a quick down+up */
821 button = QZ_OtherMouseButtonToSDL([ event buttonNumber ]); 965 SDL_PrivateMouseButton (SDL_PRESSED, button, 0, 0);
822 DO_MOUSE_UP (button); 966 SDL_PrivateMouseButton (SDL_RELEASED, button, 0, 0);
823 break; 967 }
824 968 break;
825 case NSSystemDefined: 969 case NSKeyUp:
826 /* 970 QZ_DoKey (this, SDL_RELEASED, event);
827 Future: up to 32 "mouse" buttons can be handled. 971 break;
828 if ([event subtype] == 7) { 972 case NSKeyDown:
829 unsigned int buttons; 973 QZ_DoKey (this, SDL_PRESSED, event);
830 buttons = [ event data2 ]; 974 break;
831 */ 975 case NSFlagsChanged:
832 break; 976 break;
833 case NSLeftMouseDragged: 977 /* case NSAppKitDefined: break; */
834 case NSRightMouseDragged: 978 /* case NSApplicationDefined: break; */
835 case NSOtherMouseDragged: /* usually middle mouse dragged */ 979 /* case NSPeriodic: break; */
836 case NSMouseMoved: 980 /* case NSCursorUpdate: break; */
837 if ( grab_state == QZ_INVISIBLE_GRAB ) { 981 default:
838 982 [NSApp sendEvent:event];
839 /*
840 If input is grabbed+hidden, the cursor doesn't move,
841 so we have to call the lowlevel window server
842 function. This is less accurate but works OK.
843 */
844 CGMouseDelta dx1, dy1;
845 CGGetLastMouseDelta (&dx1, &dy1);
846 dx += dx1;
847 dy += dy1;
848 }
849 else if (firstMouseEvent) {
850
851 /*
852 Get the first mouse event in a possible
853 sequence of mouse moved events. Since we
854 use absolute coordinates, this serves to
855 compensate any inaccuracy in deltas, and
856 provides the first known mouse position,
857 since everything after this uses deltas
858 */
859 NSPoint p;
860 QZ_GetMouseLocation (this, &p);
861 SDL_PrivateMouseMotion (0, 0, p.x, p.y);
862 firstMouseEvent = 0;
863 }
864 else {
865
866 /*
867 Get the amount moved since the last drag or move event,
868 add it on for one big move event at the end.
869 */
870 dx += [ event deltaX ];
871 dy += [ event deltaY ];
872 }
873
874 /*
875 Handle grab input+cursor visible by warping the cursor back
876 into the game window. This still generates a mouse moved event,
877 but not as a result of the warp (so it's in the right direction).
878 */
879 if ( grab_state == QZ_VISIBLE_GRAB &&
880 !isInGameWin ) {
881
882 NSPoint p;
883 QZ_GetMouseLocation (this, &p);
884
885 if ( p.x < 0.0 )
886 p.x = 0.0;
887
888 if ( p.y < 0.0 )
889 p.y = 0.0;
890
891 if ( p.x >= winRect.size.width )
892 p.x = winRect.size.width-1;
893
894 if ( p.y >= winRect.size.height )
895 p.y = winRect.size.height-1;
896
897 QZ_PrivateWarpCursor (this, p.x, p.y);
898 }
899 else
900 if ( !isInGameWin && (SDL_GetAppState() & SDL_APPMOUSEFOCUS) ) {
901
902 SDL_PrivateAppActive (0, SDL_APPMOUSEFOCUS);
903 if (grab_state == QZ_INVISIBLE_GRAB)
904 /*The cursor has left the window even though it is
905 disassociated from the mouse (and therefore
906 shouldn't move): this can happen with Wacom
907 tablets, and it effectively breaks the grab, since
908 mouse down events now go to background
909 applications. The only possibility to avoid this
910 seems to be talking to the tablet driver
911 (AppleEvents) to constrain its mapped area to the
912 window, which may not be worth the effort. For
913 now, handle the condition more gracefully than
914 before by reassociating cursor and mouse until the
915 cursor enters the window again, making it obvious
916 to the user that the grab is broken.*/
917 CGAssociateMouseAndMouseCursorPosition (1);
918 if (!cursor_should_be_visible)
919 QZ_ShowMouse (this);
920 }
921 else
922 if ( isInGameWin && (SDL_GetAppState() & (SDL_APPMOUSEFOCUS | SDL_APPINPUTFOCUS)) == SDL_APPINPUTFOCUS ) {
923
924 SDL_PrivateAppActive (1, SDL_APPMOUSEFOCUS);
925 if (!cursor_should_be_visible)
926 QZ_HideMouse (this);
927 if (grab_state == QZ_INVISIBLE_GRAB) { /*see comment above*/
928 QZ_PrivateWarpCursor (this, SDL_VideoSurface->w / 2, SDL_VideoSurface->h / 2);
929 CGAssociateMouseAndMouseCursorPosition (0);
930 }
931 }
932 break;
933 case NSScrollWheel:
934 if ( isInGameWin ) {
935 float dy, dx;
936 Uint8 button;
937 dy = [ event deltaY ];
938 dx = [ event deltaX ];
939 if ( dy > 0.0 || dx > 0.0 ) /* Scroll up */
940 button = SDL_BUTTON_WHEELUP;
941 else /* Scroll down */
942 button = SDL_BUTTON_WHEELDOWN;
943 /* For now, wheel is sent as a quick down+up */
944 SDL_PrivateMouseButton (SDL_PRESSED, button, 0, 0);
945 SDL_PrivateMouseButton (SDL_RELEASED, button, 0, 0);
946 }
947 break;
948 case NSKeyUp:
949 QZ_DoKey (this, SDL_RELEASED, event);
950 break;
951 case NSKeyDown:
952 QZ_DoKey (this, SDL_PRESSED, event);
953 break;
954 case NSFlagsChanged:
955 break;
956 /* case NSAppKitDefined: break; */
957 /* case NSApplicationDefined: break; */
958 /* case NSPeriodic: break; */
959 /* case NSCursorUpdate: break; */
960 default:
961 [ NSApp sendEvent:event ];
962 } 983 }
963 } 984 }
964 } while (event != nil); 985 }
965 986 while (event != nil);
987
966 /* handle accumulated mouse moved events */ 988 /* handle accumulated mouse moved events */
967 if (dx != 0 || dy != 0) 989 if (dx != 0 || dy != 0)
968 SDL_PrivateMouseMotion (0, 1, dx, dy); 990 SDL_PrivateMouseMotion (0, 1, dx, dy);
969 991
970 [ pool release ]; 992 [pool release];
971 } 993 }
972 994
973 void QZ_UpdateMouse (_THIS) 995 void
996 QZ_UpdateMouse (_THIS)
974 { 997 {
975 NSPoint p; 998 NSPoint p;
976 QZ_GetMouseLocation (this, &p); 999 QZ_GetMouseLocation (this, &p);
977 SDL_PrivateAppActive (QZ_IsMouseInWindow (this), SDL_APPMOUSEFOCUS); 1000 SDL_PrivateAppActive (QZ_IsMouseInWindow (this), SDL_APPMOUSEFOCUS);
978 SDL_PrivateMouseMotion (0, 0, p.x, p.y); 1001 SDL_PrivateMouseMotion (0, 0, p.x, p.y);