comparison src/video/quartz/SDL_QuartzEvents.m @ 435:140798e1e7a6

Darrell's fix for Quartz mouse motion
author Sam Lantinga <slouken@libsdl.org>
date Mon, 12 Aug 2002 22:43:58 +0000
parents 19e73568a75c
children c4338ecf45f9
comparison
equal deleted inserted replaced
434:ed58b98c0d9d 435:140798e1e7a6
20 slouken@libsdl.org 20 slouken@libsdl.org
21 */ 21 */
22 #include <sys/time.h> 22 #include <sys/time.h>
23 23
24 #include "SDL_QuartzKeys.h" 24 #include "SDL_QuartzKeys.h"
25
26
25 27
26 static SDLKey keymap[256]; 28 static SDLKey keymap[256];
27 static unsigned int currentMods = 0; /* Current keyboard modifiers, to track modifier state */ 29 static unsigned int currentMods = 0; /* Current keyboard modifiers, to track modifier state */
28 static int last_virtual_button = 0; /* Last virtual mouse button pressed */ 30 static int last_virtual_button = 0; /* Last virtual mouse button pressed */
29 31
303 SDL_PrivateAppActive (0, SDL_APPINPUTFOCUS); 305 SDL_PrivateAppActive (0, SDL_APPINPUTFOCUS);
304 } 306 }
305 307
306 static void QZ_PumpEvents (_THIS) 308 static void QZ_PumpEvents (_THIS)
307 { 309 {
308 static NSPoint lastMouse; 310 int firstMouseEvent;
309 NSPoint mouse, saveMouse;
310 Point qdMouse;
311 CGMouseDelta dx, dy; 311 CGMouseDelta dx, dy;
312 312
313 NSDate *distantPast; 313 NSDate *distantPast;
314 NSEvent *event; 314 NSEvent *event;
315 NSRect winRect; 315 NSRect winRect;
318 318
319 pool = [ [ NSAutoreleasePool alloc ] init ]; 319 pool = [ [ NSAutoreleasePool alloc ] init ];
320 distantPast = [ NSDate distantPast ]; 320 distantPast = [ NSDate distantPast ];
321 321
322 winRect = NSMakeRect (0, 0, SDL_VideoSurface->w, SDL_VideoSurface->h); 322 winRect = NSMakeRect (0, 0, SDL_VideoSurface->w, SDL_VideoSurface->h);
323 titleBarRect = NSMakeRect ( 0, SDL_VideoSurface->h, SDL_VideoSurface->w, 323 titleBarRect = NSMakeRect (0, SDL_VideoSurface->h, SDL_VideoSurface->w,
324 SDL_VideoSurface->h + 22 ); 324 SDL_VideoSurface->h + 22);
325 325
326 if (currentGrabMode != SDL_GRAB_ON) { /* if grabbed, the cursor can't move! (see fallback below) */ 326 /* send the first mouse event in absolute coordinates */
327 327 firstMouseEvent = 1;
328 /* 1/2 second after a warp, the mouse cannot move (don't ask me why) */ 328
329 /* So, approximate motion with CGGetLastMouseDelta, which still works, somehow */ 329 /* accumulate any additional mouse moved events into one SDL mouse event */
330 if (! warp_flag) {
331
332 GetGlobalMouse (&qdMouse); /* use Carbon since [ NSEvent mouseLocation ] is broken */
333 mouse = NSMakePoint (qdMouse.h, qdMouse.v);
334 saveMouse = mouse;
335
336 if (mouse.x != lastMouse.x || mouse.y != lastMouse.y) {
337
338 QZ_PrivateCGToSDL (this, &mouse);
339 /* -note- we now generate mouse motion events if the mouse isn't over the window */
340 if (inForeground /* && NSPointInRect (mouse, winRect)*/) {
341 //printf ("Mouse Loc: (%f, %f)\n", mouse.x, mouse.y);
342 SDL_PrivateMouseMotion (0, 0, mouse.x, mouse.y);
343 }
344 }
345 lastMouse = saveMouse;
346 }
347 }
348
349 /* accumulate any mouse events into one SDL mouse event */
350 dx = 0; 330 dx = 0;
351 dy = 0; 331 dy = 0;
352 332
353 do { 333 do {
354 334
417 // buttons = [ event data2 ]; 397 // buttons = [ event data2 ];
418 //} 398 //}
419 break; 399 break;
420 case NSLeftMouseDragged: 400 case NSLeftMouseDragged:
421 case NSRightMouseDragged: 401 case NSRightMouseDragged:
422 case 27: 402 case NSOtherMouseDragged: /* usually middle mouse dragged */
423 case NSMouseMoved: 403 case NSMouseMoved:
424 if (currentGrabMode == SDL_GRAB_ON) { 404 if (currentGrabMode == SDL_GRAB_ON) {
425 405
426 /** 406 /**
427 * If input is grabbed, we'll wing it and try to send some mouse 407 * If input is grabbed, the cursor doesn't move,
428 * moved events with CGGetLastMouseDelta(). Not optimal, but better 408 * so we have to call the lowlevel window server
429 * than nothing. 409 * function. This is less accurate but works OK.
430 **/ 410 **/
431 CGMouseDelta dx1, dy1; 411 CGMouseDelta dx1, dy1;
432 CGGetLastMouseDelta (&dx1, &dy1); 412 CGGetLastMouseDelta (&dx1, &dy1);
433 dx += dx1; 413 dx += dx1;
434 dy += dy1; 414 dy += dy1;
435 } 415 }
436 else if (warp_flag) { 416 else if (warp_flag) {
437 417
418 /**
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
421 * unfreezes. This really helps apps that continuously
422 * warp the mouse to keep it in the game window.
423 **/
438 Uint32 ticks; 424 Uint32 ticks;
439 425
440 ticks = SDL_GetTicks(); 426 ticks = SDL_GetTicks();
441 if (ticks - warp_ticks < 150) { 427 if (ticks - warp_ticks < 150) {
442 428
448 else { 434 else {
449 435
450 warp_flag = 0; 436 warp_flag = 0;
451 } 437 }
452 } 438 }
439 else if (firstMouseEvent) {
440
441 /**
442 * Get the first mouse event in a possible
443 * sequence of mouse moved events. Since we
444 * use absolute coordinates, this serves to
445 * compensate any inaccuracy in deltas, and
446 * provides the first known mouse position,
447 * since everything after this uses deltas
448 **/
449 NSPoint p = [ event locationInWindow ];
450 QZ_PrivateCocoaToSDL(this, &p);
451
452 firstMouseEvent = 0;
453 }
454 else {
455
456 /**
457 * Get the amount moved since the last drag or move event,
458 * add it on for one big move event at the end.
459 **/
460 dx += [ event deltaX ];
461 dy += [ event deltaY ];
462 }
453 break; 463 break;
454 case NSScrollWheel: 464 case NSScrollWheel:
455 if (NSPointInRect([ event locationInWindow ], winRect)) { 465 if (NSPointInRect([ event locationInWindow ], winRect)) {
456 float dy; 466 float dy;
457 dy = [ event deltaY ]; 467 dy = [ event deltaY ];
488 [ NSApp sendEvent:event ]; 498 [ NSApp sendEvent:event ];
489 } 499 }
490 } 500 }
491 } while (event != nil); 501 } while (event != nil);
492 502
493 /* check for accumulated mouse events */ 503 /* handle accumulated mouse moved events */
494 if (dx != 0 || dy != 0) 504 if (dx != 0 || dy != 0)
495 SDL_PrivateMouseMotion (0, 1, dx, dy); 505 SDL_PrivateMouseMotion (0, 1, dx, dy);
496 506
497 [ pool release ]; 507 [ pool release ];
498 } 508 }
499 509