Mercurial > sdl-ios-xcode
comparison src/video/quartz/SDL_QuartzEvents.m @ 501:74262d2647ca
Lots of cleanups by Darrell, added the ability to resize Cocoa windows.
author | Sam Lantinga <slouken@libsdl.org> |
---|---|
date | Sat, 05 Oct 2002 05:07:57 +0000 |
parents | c4338ecf45f9 |
children | 80a3d09bab29 |
comparison
equal
deleted
inserted
replaced
500:c335456c421d | 501:74262d2647ca |
---|---|
17 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | 17 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA |
18 | 18 |
19 Sam Lantinga | 19 Sam Lantinga |
20 slouken@libsdl.org | 20 slouken@libsdl.org |
21 */ | 21 */ |
22 #include <sys/time.h> | |
23 | |
24 #include "SDL_QuartzKeys.h" | 22 #include "SDL_QuartzKeys.h" |
25 | |
26 | |
27 | |
28 static SDLKey keymap[256]; | |
29 static unsigned int currentMods = 0; /* Current keyboard modifiers, to track modifier state */ | |
30 static int last_virtual_button = 0; /* Last virtual mouse button pressed */ | |
31 | 23 |
32 static void QZ_InitOSKeymap (_THIS) { | 24 static void QZ_InitOSKeymap (_THIS) { |
33 const void *KCHRPtr; | 25 const void *KCHRPtr; |
34 UInt32 state; | 26 UInt32 state; |
35 UInt32 value; | 27 UInt32 value; |
145 keymap[QZ_IBOOK_RIGHT] = SDLK_RIGHT; | 137 keymap[QZ_IBOOK_RIGHT] = SDLK_RIGHT; |
146 keymap[QZ_IBOOK_DOWN] = SDLK_DOWN; | 138 keymap[QZ_IBOOK_DOWN] = SDLK_DOWN; |
147 keymap[QZ_IBOOK_UP] = SDLK_UP; | 139 keymap[QZ_IBOOK_UP] = SDLK_UP; |
148 keymap[QZ_IBOOK_LEFT] = SDLK_LEFT; | 140 keymap[QZ_IBOOK_LEFT] = SDLK_LEFT; |
149 | 141 |
150 /* Up there we setup a static scancode->keysym map. However, it will not | 142 /* |
151 * work very well on international keyboard. Hence we now query MacOS | 143 Up there we setup a static scancode->keysym map. However, it will not |
152 * for its own keymap to adjust our own mapping table. However, this is | 144 work very well on international keyboard. Hence we now query MacOS |
153 * bascially only useful for ascii char keys. This is also the reason | 145 for its own keymap to adjust our own mapping table. However, this is |
154 * why we keep the static table, too. | 146 basically only useful for ascii char keys. This is also the reason |
147 why we keep the static table, too. | |
155 */ | 148 */ |
156 | 149 |
157 /* Get a pointer to the systems cached KCHR */ | 150 /* Get a pointer to the systems cached KCHR */ |
158 KCHRPtr = (void *)GetScriptManagerVariable(smKCHRCache); | 151 KCHRPtr = (void *)GetScriptManagerVariable(smKCHRCache); |
159 if (KCHRPtr) | 152 if (KCHRPtr) |
178 else if (value >= 32) /* non-control ASCII char */ | 171 else if (value >= 32) /* non-control ASCII char */ |
179 keymap[i] = value; | 172 keymap[i] = value; |
180 } | 173 } |
181 } | 174 } |
182 | 175 |
183 /* The keypad codes are re-setup here, because the loop above cannot | 176 /* |
184 * distinguish between a key on the keypad and a regular key. We maybe | 177 The keypad codes are re-setup here, because the loop above cannot |
185 * could get around this problem in another fashion: NSEvent's flags | 178 distinguish between a key on the keypad and a regular key. We maybe |
186 * include a "NSNumericPadKeyMask" bit; we could check that and modify | 179 could get around this problem in another fashion: NSEvent's flags |
187 * the symbol we return on the fly. However, this flag seems to exhibit | 180 include a "NSNumericPadKeyMask" bit; we could check that and modify |
188 * some weird behaviour related to the num lock key | 181 the symbol we return on the fly. However, this flag seems to exhibit |
189 */ | 182 some weird behaviour related to the num lock key |
183 */ | |
190 keymap[QZ_KP0] = SDLK_KP0; | 184 keymap[QZ_KP0] = SDLK_KP0; |
191 keymap[QZ_KP1] = SDLK_KP1; | 185 keymap[QZ_KP1] = SDLK_KP1; |
192 keymap[QZ_KP2] = SDLK_KP2; | 186 keymap[QZ_KP2] = SDLK_KP2; |
193 keymap[QZ_KP3] = SDLK_KP3; | 187 keymap[QZ_KP3] = SDLK_KP3; |
194 keymap[QZ_KP4] = SDLK_KP4; | 188 keymap[QZ_KP4] = SDLK_KP4; |
204 keymap[QZ_KP_DIVIDE] = SDLK_KP_DIVIDE; | 198 keymap[QZ_KP_DIVIDE] = SDLK_KP_DIVIDE; |
205 keymap[QZ_KP_MULTIPLY] = SDLK_KP_MULTIPLY; | 199 keymap[QZ_KP_MULTIPLY] = SDLK_KP_MULTIPLY; |
206 keymap[QZ_KP_ENTER] = SDLK_KP_ENTER; | 200 keymap[QZ_KP_ENTER] = SDLK_KP_ENTER; |
207 } | 201 } |
208 | 202 |
209 static void QZ_DoKey (int state, NSEvent *event) { | 203 static void QZ_DoKey (_THIS, int state, NSEvent *event) { |
210 | 204 |
211 NSString *chars; | 205 NSString *chars; |
212 int i; | 206 int i; |
213 SDL_keysym key; | 207 SDL_keysym key; |
214 | 208 |
215 /* An event can contain multiple characters */ | 209 /* |
216 /* I'll ignore this fact for now, since there is only one virtual key code per event */ | 210 An event can contain multiple characters |
211 I'll ignore this fact for now, since there | |
212 is only one virtual key code per event, so | |
213 no good way to handle this. | |
214 */ | |
217 chars = [ event characters ]; | 215 chars = [ event characters ]; |
218 for (i =0; i < 1 /*[ chars length ] */; i++) { | 216 for (i =0; i < 1 /*[ chars length ] */; i++) { |
219 | 217 |
220 key.scancode = [ event keyCode ]; | 218 key.scancode = [ event keyCode ]; |
221 key.sym = keymap [ key.scancode ]; | 219 key.sym = keymap [ key.scancode ]; |
224 | 222 |
225 SDL_PrivateKeyboard (state, &key); | 223 SDL_PrivateKeyboard (state, &key); |
226 } | 224 } |
227 } | 225 } |
228 | 226 |
229 static void QZ_DoModifiers (unsigned int newMods) { | 227 static void QZ_DoModifiers (_THIS, unsigned int newMods) { |
230 | 228 |
231 const int mapping[] = { SDLK_CAPSLOCK, SDLK_LSHIFT, SDLK_LCTRL, SDLK_LALT, SDLK_LMETA } ; | 229 const int mapping[] = { SDLK_CAPSLOCK, SDLK_LSHIFT, SDLK_LCTRL, SDLK_LALT, SDLK_LMETA } ; |
232 | 230 |
233 int i; | 231 int i; |
234 int bit; | 232 int bit; |
242 /* Iterate through the bits, testing each against the current modifiers */ | 240 /* Iterate through the bits, testing each against the current modifiers */ |
243 for (i = 0, bit = NSAlphaShiftKeyMask; bit <= NSCommandKeyMask; bit <<= 1, ++i) { | 241 for (i = 0, bit = NSAlphaShiftKeyMask; bit <= NSCommandKeyMask; bit <<= 1, ++i) { |
244 | 242 |
245 unsigned int currentMask, newMask; | 243 unsigned int currentMask, newMask; |
246 | 244 |
247 currentMask = currentMods & bit; | 245 currentMask = current_mods & bit; |
248 newMask = newMods & bit; | 246 newMask = newMods & bit; |
249 | 247 |
250 if ( currentMask && | 248 if ( currentMask && |
251 currentMask != newMask ) { /* modifier up event */ | 249 currentMask != newMask ) { /* modifier up event */ |
252 | 250 |
253 key.sym = mapping[i]; | 251 key.sym = mapping[i]; |
265 if (bit == NSAlphaShiftKeyMask) | 263 if (bit == NSAlphaShiftKeyMask) |
266 SDL_PrivateKeyboard (SDL_RELEASED, &key); | 264 SDL_PrivateKeyboard (SDL_RELEASED, &key); |
267 } | 265 } |
268 } | 266 } |
269 | 267 |
270 currentMods = newMods; | 268 current_mods = newMods; |
271 } | 269 } |
272 | 270 |
273 static void QZ_DoActivate (_THIS) | 271 static void QZ_DoActivate (_THIS) |
274 { | 272 { |
275 inForeground = YES; | 273 in_foreground = YES; |
276 | 274 |
277 /* Regrab the mouse */ | 275 /* Regrab the mouse, only if it was previously grabbed */ |
278 if (currentGrabMode == SDL_GRAB_ON) { | 276 if ( current_grab_mode == SDL_GRAB_ON ) { |
279 QZ_WarpWMCursor (this, SDL_VideoSurface->w / 2, SDL_VideoSurface->h / 2); | 277 QZ_WarpWMCursor (this, SDL_VideoSurface->w / 2, SDL_VideoSurface->h / 2); |
280 CGAssociateMouseAndMouseCursorPosition (0); | 278 CGAssociateMouseAndMouseCursorPosition (0); |
281 } | 279 } |
282 | 280 |
283 /* Hide the mouse cursor if inside the app window */ | 281 /* Hide the mouse cursor if inside the app window */ |
288 SDL_PrivateAppActive (1, SDL_APPINPUTFOCUS); | 286 SDL_PrivateAppActive (1, SDL_APPINPUTFOCUS); |
289 } | 287 } |
290 | 288 |
291 static void QZ_DoDeactivate (_THIS) { | 289 static void QZ_DoDeactivate (_THIS) { |
292 | 290 |
293 inForeground = NO; | 291 in_foreground = NO; |
294 | 292 |
295 /* Ungrab mouse if it is grabbed */ | 293 /* Ungrab mouse if it is grabbed */ |
296 if (currentGrabMode == SDL_GRAB_ON) { | 294 if ( current_grab_mode == SDL_GRAB_ON ) { |
297 CGAssociateMouseAndMouseCursorPosition (1); | 295 CGAssociateMouseAndMouseCursorPosition (1); |
298 } | 296 } |
299 | 297 |
300 /* Show the mouse cursor */ | 298 /* Show the mouse cursor */ |
301 if (!QZ_cursor_visible) { | 299 if (!QZ_cursor_visible) { |
341 | 339 |
342 unsigned int type; | 340 unsigned int type; |
343 BOOL isForGameWin; | 341 BOOL isForGameWin; |
344 | 342 |
345 #define DO_MOUSE_DOWN(button, sendToWindow) do { \ | 343 #define DO_MOUSE_DOWN(button, sendToWindow) do { \ |
346 if ( inForeground ) { \ | 344 if ( in_foreground ) { \ |
347 if ( (SDL_VideoSurface->flags & SDL_FULLSCREEN) || \ | 345 if ( (SDL_VideoSurface->flags & SDL_FULLSCREEN) || \ |
348 NSPointInRect([event locationInWindow], winRect) ) \ | 346 NSPointInRect([event locationInWindow], winRect) ) \ |
349 SDL_PrivateMouseButton (SDL_PRESSED, button, 0, 0); \ | 347 SDL_PrivateMouseButton (SDL_PRESSED, button, 0, 0); \ |
350 } \ | 348 } \ |
351 else { \ | 349 else { \ |
364 type = [ event type ]; | 362 type = [ event type ]; |
365 isForGameWin = (qz_window == [ event window ]); | 363 isForGameWin = (qz_window == [ event window ]); |
366 switch (type) { | 364 switch (type) { |
367 | 365 |
368 case NSLeftMouseDown: | 366 case NSLeftMouseDown: |
369 if ( NSCommandKeyMask & currentMods ) { | 367 if ( NSCommandKeyMask & current_mods ) { |
370 last_virtual_button = 3; | 368 last_virtual_button = 3; |
371 DO_MOUSE_DOWN (3, 0); | 369 DO_MOUSE_DOWN (3, 0); |
372 } | 370 } |
373 else if ( NSAlternateKeyMask & currentMods ) { | 371 else if ( NSAlternateKeyMask & current_mods ) { |
374 last_virtual_button = 2; | 372 last_virtual_button = 2; |
375 DO_MOUSE_DOWN (2, 0); | 373 DO_MOUSE_DOWN (2, 0); |
376 } | 374 } |
377 else { | 375 else { |
378 DO_MOUSE_DOWN (1, 1); | 376 DO_MOUSE_DOWN (1, 1); |
390 } | 388 } |
391 break; | 389 break; |
392 case NSOtherMouseUp: DO_MOUSE_UP (2, 0); break; | 390 case NSOtherMouseUp: DO_MOUSE_UP (2, 0); break; |
393 case NSRightMouseUp: DO_MOUSE_UP (3, 0); break; | 391 case NSRightMouseUp: DO_MOUSE_UP (3, 0); break; |
394 case NSSystemDefined: | 392 case NSSystemDefined: |
395 //if ([event subtype] == 7) { | 393 /* |
396 // unsigned int buttons; // up to 32 mouse button states! | 394 Future: up to 32 "mouse" buttons can be handled. |
397 // buttons = [ event data2 ]; | 395 if ([event subtype] == 7) { |
398 //} | 396 unsigned int buttons; |
397 buttons = [ event data2 ]; | |
398 */ | |
399 break; | 399 break; |
400 case NSLeftMouseDragged: | 400 case NSLeftMouseDragged: |
401 case NSRightMouseDragged: | 401 case NSRightMouseDragged: |
402 case NSOtherMouseDragged: /* usually middle mouse dragged */ | 402 case NSOtherMouseDragged: /* usually middle mouse dragged */ |
403 case NSMouseMoved: | 403 case NSMouseMoved: |
404 if (currentGrabMode == SDL_GRAB_ON) { | 404 if (current_grab_mode == SDL_GRAB_ON) { |
405 | 405 |
406 /** | 406 /* |
407 * If input is grabbed, the cursor doesn't move, | 407 If input is grabbed, the cursor doesn't move, |
408 * so we have to call the lowlevel window server | 408 so we have to call the lowlevel window server |
409 * function. This is less accurate but works OK. | 409 function. This is less accurate but works OK. |
410 **/ | 410 */ |
411 CGMouseDelta dx1, dy1; | 411 CGMouseDelta dx1, dy1; |
412 CGGetLastMouseDelta (&dx1, &dy1); | 412 CGGetLastMouseDelta (&dx1, &dy1); |
413 dx += dx1; | 413 dx += dx1; |
414 dy += dy1; | 414 dy += dy1; |
415 } | 415 } |
416 else if (warp_flag) { | 416 else if (warp_flag) { |
417 | 417 |
418 /** | 418 /* |
419 * If we just warped the mouse, the cursor is frozen for a while. | 419 If we just warped the mouse, the cursor is frozen for a while. |
420 * So we have to use the lowlevel function until it | 420 So we have to use the lowlevel function until it |
421 * unfreezes. This really helps apps that continuously | 421 unfreezes. This really helps apps that continuously |
422 * warp the mouse to keep it in the game window. | 422 warp the mouse to keep it in the game window. Developers should |
423 **/ | 423 really use GrabInput, but our GrabInput freezes the HW cursor, |
424 which doesn't cut it for some apps. | |
425 */ | |
424 Uint32 ticks; | 426 Uint32 ticks; |
425 | 427 |
426 ticks = SDL_GetTicks(); | 428 ticks = SDL_GetTicks(); |
427 if (ticks - warp_ticks < 150) { | 429 if (ticks - warp_ticks < 150) { |
428 | 430 |
436 warp_flag = 0; | 438 warp_flag = 0; |
437 } | 439 } |
438 } | 440 } |
439 else if (firstMouseEvent) { | 441 else if (firstMouseEvent) { |
440 | 442 |
441 /** | 443 /* |
442 * Get the first mouse event in a possible | 444 Get the first mouse event in a possible |
443 * sequence of mouse moved events. Since we | 445 sequence of mouse moved events. Since we |
444 * use absolute coordinates, this serves to | 446 use absolute coordinates, this serves to |
445 * compensate any inaccuracy in deltas, and | 447 compensate any inaccuracy in deltas, and |
446 * provides the first known mouse position, | 448 provides the first known mouse position, |
447 * since everything after this uses deltas | 449 since everything after this uses deltas |
448 **/ | 450 */ |
449 NSPoint p = [ event locationInWindow ]; | 451 NSPoint p = [ event locationInWindow ]; |
450 QZ_PrivateCocoaToSDL(this, &p); | 452 QZ_PrivateCocoaToSDL(this, &p); |
451 | 453 |
452 SDL_PrivateMouseMotion (0, 0, p.x, p.y); | 454 SDL_PrivateMouseMotion (0, 0, p.x, p.y); |
453 | 455 |
454 firstMouseEvent = 0; | 456 firstMouseEvent = 0; |
455 } | 457 } |
456 else { | 458 else { |
457 | 459 |
458 /** | 460 /* |
459 * Get the amount moved since the last drag or move event, | 461 Get the amount moved since the last drag or move event, |
460 * add it on for one big move event at the end. | 462 add it on for one big move event at the end. |
461 **/ | 463 */ |
462 dx += [ event deltaX ]; | 464 dx += [ event deltaX ]; |
463 dy += [ event deltaY ]; | 465 dy += [ event deltaY ]; |
464 } | 466 } |
465 break; | 467 break; |
466 case NSScrollWheel: | 468 case NSScrollWheel: |
467 if (NSPointInRect([ event locationInWindow ], winRect)) { | 469 if (NSPointInRect([ event locationInWindow ], winRect)) { |
468 float dy; | 470 float dy; |
472 else /* Scroll down */ | 474 else /* Scroll down */ |
473 SDL_PrivateMouseButton (SDL_PRESSED, 5, 0, 0); | 475 SDL_PrivateMouseButton (SDL_PRESSED, 5, 0, 0); |
474 } | 476 } |
475 break; | 477 break; |
476 case NSKeyUp: | 478 case NSKeyUp: |
477 QZ_DoKey (SDL_RELEASED, event); | 479 QZ_DoKey (this, SDL_RELEASED, event); |
478 break; | 480 break; |
479 case NSKeyDown: | 481 case NSKeyDown: |
480 QZ_DoKey (SDL_PRESSED, event); | 482 QZ_DoKey (this, SDL_PRESSED, event); |
481 break; | 483 break; |
482 case NSFlagsChanged: | 484 case NSFlagsChanged: |
483 QZ_DoModifiers( [ event modifierFlags ] ); | 485 QZ_DoModifiers(this, [ event modifierFlags ] ); |
484 break; | 486 break; |
485 case NSAppKitDefined: | 487 case NSAppKitDefined: |
486 switch ( [ event subtype ] ) { | 488 switch ( [ event subtype ] ) { |
487 case NSApplicationActivatedEventType: | 489 case NSApplicationActivatedEventType: |
488 QZ_DoActivate (this); | 490 QZ_DoActivate (this); |
506 if (dx != 0 || dy != 0) | 508 if (dx != 0 || dy != 0) |
507 SDL_PrivateMouseMotion (0, 1, dx, dy); | 509 SDL_PrivateMouseMotion (0, 1, dx, dy); |
508 | 510 |
509 [ pool release ]; | 511 [ pool release ]; |
510 } | 512 } |
511 |