Mercurial > sdl-ios-xcode
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, ¬ifier); | 711 power_connection = |
688 | 712 IORegisterForSystemPower (this, &thePortRef, |
689 if (power_connection == 0) | 713 QZ_SleepNotificationHandler, ¬ifier); |
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); |