Mercurial > sdl-ios-xcode
comparison src/video/quartz/SDL_QuartzEvents.m @ 272:d1447a846d80
Date: Sat, 19 Jan 2002 17:24:32 -0500 (EST)
From: Darrell Walisser <dwaliss1@purdue.edu>
Subject: SDL Quartz video update
-better mouse motion events
-fixed minification bugs (except OpenGL)
-fixed QZ_SetGamma for correct semantics
-fade/unfade display before/after rez switch
-experimental obscured-check/blind-copy code
The obscured code, while it speeds up window drawing substantially, isn't
ready yet. The reason is that there doesn't (yet) seem to be a way to know
when the window is dragged or when the window suddenly comes to the
foreground. Since Carbon windows seem to allow detection of such things, I
suspect it is possible through some window server API. Cocoa(NSWindow) has no
functions for such things, AFAIK.
author | Sam Lantinga <slouken@libsdl.org> |
---|---|
date | Tue, 22 Jan 2002 18:46:28 +0000 |
parents | e8157fcb3114 |
children | f6ffac90895c |
comparison
equal
deleted
inserted
replaced
271:9631db4d9ee1 | 272:d1447a846d80 |
---|---|
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> | |
22 | 23 |
23 #include "SDL_QuartzKeys.h" | 24 #include "SDL_QuartzKeys.h" |
24 | 25 |
25 static SDLKey keymap[256]; | 26 static SDLKey keymap[256]; |
26 static unsigned int currentMods = 0; /* Current keyboard modifiers, to track modifier state */ | 27 static unsigned int currentMods = 0; /* Current keyboard modifiers, to track modifier state */ |
303 SDL_PrivateAppActive (0, SDL_APPINPUTFOCUS); | 304 SDL_PrivateAppActive (0, SDL_APPINPUTFOCUS); |
304 } | 305 } |
305 | 306 |
306 static void QZ_PumpEvents (_THIS) | 307 static void QZ_PumpEvents (_THIS) |
307 { | 308 { |
308 NSDate *distantPast; | 309 |
310 static NSPoint lastMouse; | |
311 NSPoint mouse, saveMouse; | |
312 Point qdMouse; | |
313 CGMouseDelta dx, dy; | |
314 | |
315 NSDate *distantPast; | |
309 NSEvent *event; | 316 NSEvent *event; |
310 NSRect winRect; | 317 NSRect winRect; |
311 NSRect titleBarRect; | 318 NSRect titleBarRect; |
312 NSAutoreleasePool *pool; | 319 NSAutoreleasePool *pool; |
313 | 320 |
314 pool = [ [ NSAutoreleasePool alloc ] init ]; | 321 pool = [ [ NSAutoreleasePool alloc ] init ]; |
315 distantPast = [ NSDate distantPast ]; | 322 distantPast = [ NSDate distantPast ]; |
316 | 323 |
317 winRect = NSMakeRect (0, 0, SDL_VideoSurface->w + 1, SDL_VideoSurface->h + 1); | 324 winRect = NSMakeRect (0, 0, SDL_VideoSurface->w, SDL_VideoSurface->h); |
318 titleBarRect = NSMakeRect ( 0, SDL_VideoSurface->h, SDL_VideoSurface->w, | 325 titleBarRect = NSMakeRect ( 0, SDL_VideoSurface->h, SDL_VideoSurface->w, |
319 SDL_VideoSurface->h + 22 ); | 326 SDL_VideoSurface->h + 22 ); |
320 | 327 |
328 if (currentGrabMode != SDL_GRAB_ON) { /* if grabbed, the cursor can't move! (see fallback below) */ | |
329 | |
330 /* 1/2 second after a warp, the mouse cannot move (don't ask me why) */ | |
331 /* So, approximate motion with CGGetLastMouseDelta, which still works, somehow */ | |
332 if (! warp_flag) { | |
333 | |
334 GetGlobalMouse (&qdMouse); /* use Carbon since [ NSEvent mouseLocation ] is broken */ | |
335 mouse = NSMakePoint (qdMouse.h, qdMouse.v); | |
336 saveMouse = mouse; | |
337 | |
338 if (mouse.x != lastMouse.x || mouse.y != lastMouse.y) { | |
339 | |
340 QZ_PrivateCGToSDL (this, &mouse); | |
341 if (inForeground && NSPointInRect (mouse, winRect)) { | |
342 //printf ("Mouse Loc: (%f, %f)\n", mouse.x, mouse.y); | |
343 SDL_PrivateMouseMotion (0, 0, mouse.x, mouse.y); | |
344 } | |
345 } | |
346 lastMouse = saveMouse; | |
347 } | |
348 } | |
349 | |
350 /* accumulate any mouse events into one SDL mouse event */ | |
351 dx = 0; | |
352 dy = 0; | |
353 | |
321 do { | 354 do { |
322 | 355 |
323 /* Poll for an event. This will not block */ | 356 /* Poll for an event. This will not block */ |
324 event = [ NSApp nextEventMatchingMask:NSAnyEventMask | 357 event = [ NSApp nextEventMatchingMask:NSAnyEventMask |
325 untilDate:distantPast | 358 untilDate:distantPast |
328 if (event != nil) { | 361 if (event != nil) { |
329 unsigned int type; | 362 unsigned int type; |
330 BOOL isForGameWin; | 363 BOOL isForGameWin; |
331 | 364 |
332 #define DO_MOUSE_DOWN(button, sendToWindow) do { \ | 365 #define DO_MOUSE_DOWN(button, sendToWindow) do { \ |
333 if ( inForeground ) { \ | 366 if ( inForeground ) { \ |
334 if ( (SDL_VideoSurface->flags & SDL_FULLSCREEN) || \ | 367 if ( (SDL_VideoSurface->flags & SDL_FULLSCREEN) || \ |
335 NSPointInRect([event locationInWindow], winRect) ) \ | 368 NSPointInRect([event locationInWindow], winRect) ) \ |
336 SDL_PrivateMouseButton (SDL_PRESSED, button, 0, 0); \ | 369 SDL_PrivateMouseButton (SDL_PRESSED, button, 0, 0); \ |
337 } \ | 370 } \ |
338 else { \ | 371 else { \ |
339 QZ_DoActivate (this); \ | 372 QZ_DoActivate (this); \ |
340 } \ | 373 } \ |
341 [ NSApp sendEvent:event ]; \ | 374 [ NSApp sendEvent:event ]; \ |
342 } while(0) | 375 } while(0) |
343 | 376 |
344 #define DO_MOUSE_UP(button, sendToWindow) do { \ | 377 #define DO_MOUSE_UP(button, sendToWindow) do { \ |
345 if ( (SDL_VideoSurface->flags & SDL_FULLSCREEN) || \ | 378 if ( (SDL_VideoSurface->flags & SDL_FULLSCREEN) || \ |
346 !NSPointInRect([event locationInWindow], titleBarRect) )\ | 379 !NSPointInRect([event locationInWindow], titleBarRect) ) \ |
347 SDL_PrivateMouseButton (SDL_RELEASED, button, 0, 0); \ | 380 SDL_PrivateMouseButton (SDL_RELEASED, button, 0, 0); \ |
348 [ NSApp sendEvent:event ]; \ | 381 [ NSApp sendEvent:event ]; \ |
349 } while(0) | 382 } while(0) |
350 | 383 |
351 type = [ event type ]; | 384 type = [ event type ]; |
352 isForGameWin = (qz_window == [ event window ]); | 385 isForGameWin = (qz_window == [ event window ]); |
353 switch (type) { | 386 switch (type) { |
363 } | 396 } |
364 else { | 397 else { |
365 DO_MOUSE_DOWN (1, 1); | 398 DO_MOUSE_DOWN (1, 1); |
366 } | 399 } |
367 break; | 400 break; |
368 case 25: DO_MOUSE_DOWN (2, 0); break; | 401 case NSOtherMouseDown: DO_MOUSE_DOWN (2, 0); break; |
369 case NSRightMouseDown: DO_MOUSE_DOWN (3, 0); break; | 402 case NSRightMouseDown: DO_MOUSE_DOWN (3, 0); break; |
370 case NSLeftMouseUp: | 403 case NSLeftMouseUp: |
371 | 404 |
372 if ( last_virtual_button != 0 ) { | 405 if ( last_virtual_button != 0 ) { |
373 DO_MOUSE_UP (last_virtual_button, 0); | 406 DO_MOUSE_UP (last_virtual_button, 0); |
375 } | 408 } |
376 else { | 409 else { |
377 DO_MOUSE_UP (1, 1); | 410 DO_MOUSE_UP (1, 1); |
378 } | 411 } |
379 break; | 412 break; |
380 case 26: DO_MOUSE_UP (2, 0); break; | 413 case NSOtherMouseUp: DO_MOUSE_UP (2, 0); break; |
381 case NSRightMouseUp: DO_MOUSE_UP (3, 0); break; | 414 case NSRightMouseUp: DO_MOUSE_UP (3, 0); break; |
382 case NSSystemDefined: | 415 case NSSystemDefined: |
383 //if ([event subtype] == 7) { | 416 //if ([event subtype] == 7) { |
384 // unsigned int buttons; // up to 32 mouse button states! | 417 // unsigned int buttons; // up to 32 mouse button states! |
385 // buttons = [ event data2 ]; | 418 // buttons = [ event data2 ]; |
387 break; | 420 break; |
388 case NSLeftMouseDragged: | 421 case NSLeftMouseDragged: |
389 case NSRightMouseDragged: | 422 case NSRightMouseDragged: |
390 case 27: | 423 case 27: |
391 case NSMouseMoved: | 424 case NSMouseMoved: |
392 if ( (SDL_VideoSurface->flags & SDL_FULLSCREEN) | 425 |
393 || NSPointInRect([event locationInWindow], winRect) ) | 426 if (currentGrabMode == SDL_GRAB_ON) { |
394 { | 427 |
395 static int moves = 0; | 428 /** |
396 NSPoint p; | 429 * If input is grabbed, we'll wing it and try to send some mouse |
397 | 430 * moved events with CGGetLastMouseDelta(). Not optimal, but better |
398 if ( SDL_VideoSurface->flags & SDL_FULLSCREEN ) { | 431 * than nothing. |
399 p = [ NSEvent mouseLocation ]; | 432 **/ |
400 p.y = [[NSScreen mainScreen] frame].size.height - p.y; | 433 CGMouseDelta dx1, dy1; |
401 } else { | 434 CGGetLastMouseDelta (&dx1, &dy1); |
402 p = [ event locationInWindow ]; | 435 dx += dx1; |
403 p.y = SDL_VideoSurface->h - p.y; | 436 dy += dy1; |
404 } | 437 } |
405 | 438 else if (warp_flag) { |
406 if ( (moves % 10) == 0 ) { | 439 |
407 SDL_PrivateMouseMotion (0, 0, p.x, p.y); | 440 Uint32 ticks; |
408 } | 441 |
409 else { | 442 ticks = SDL_GetTicks(); |
410 CGMouseDelta dx, dy; | 443 if (ticks - warp_ticks < 150) { |
411 CGGetLastMouseDelta (&dx, &dy); | 444 |
412 SDL_PrivateMouseMotion (0, 1, dx, dy); | 445 CGMouseDelta dx1, dy1; |
413 } | 446 CGGetLastMouseDelta (&dx1, &dy1); |
414 moves++; | 447 dx += dx1; |
415 } | 448 dy += dy1; |
449 } | |
450 else { | |
451 | |
452 warp_flag = 0; | |
453 } | |
454 } | |
455 | |
416 break; | 456 break; |
417 case NSScrollWheel: | 457 case NSScrollWheel: |
418 { | 458 { |
419 if (NSPointInRect([ event locationInWindow ], winRect)) { | 459 if (NSPointInRect([ event locationInWindow ], winRect)) { |
420 float dy; | 460 float dy; |
433 QZ_DoKey (SDL_PRESSED, event); | 473 QZ_DoKey (SDL_PRESSED, event); |
434 break; | 474 break; |
435 case NSFlagsChanged: | 475 case NSFlagsChanged: |
436 QZ_DoModifiers( [ event modifierFlags ] ); | 476 QZ_DoModifiers( [ event modifierFlags ] ); |
437 break; | 477 break; |
438 /* case NSMouseEntered: break; */ | |
439 /* case NSMouseExited: break; */ | |
440 case NSAppKitDefined: | 478 case NSAppKitDefined: |
441 switch ( [ event subtype ] ) { | 479 switch ( [ event subtype ] ) { |
442 case NSApplicationActivatedEventType: | 480 case NSApplicationActivatedEventType: |
443 QZ_DoActivate (this); | 481 QZ_DoActivate (this); |
444 break; | 482 break; |
449 [ NSApp sendEvent:event ]; | 487 [ NSApp sendEvent:event ]; |
450 break; | 488 break; |
451 /* case NSApplicationDefined: break; */ | 489 /* case NSApplicationDefined: break; */ |
452 /* case NSPeriodic: break; */ | 490 /* case NSPeriodic: break; */ |
453 /* case NSCursorUpdate: break; */ | 491 /* case NSCursorUpdate: break; */ |
454 default: | 492 |
493 default: | |
455 [ NSApp sendEvent:event ]; | 494 [ NSApp sendEvent:event ]; |
456 } | 495 } |
457 } | 496 } |
458 } while (event != nil); | 497 } while (event != nil); |
459 | 498 |
499 /* check for accumulated mouse events */ | |
500 if (dx != 0 || dy != 0) | |
501 SDL_PrivateMouseMotion (0, 1, dx, dy); | |
502 | |
460 [ pool release ]; | 503 [ pool release ]; |
461 } | 504 } |
462 | 505 |