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