Mercurial > sdl-ios-xcode
view src/video/quartz/SDL_QuartzEvents.m @ 117:aac75d5f7869
Fixed fullscreen mouse events on MacOS X
Fixed crash when quitting fullscreen mode on MacOS X
author | Sam Lantinga <slouken@libsdl.org> |
---|---|
date | Sun, 22 Jul 2001 20:57:24 +0000 |
parents | 45b1c4303f87 |
children | 2d162219f433 |
line wrap: on
line source
/* SDL - Simple DirectMedia Layer Copyright (C) 1997, 1998, 1999, 2000, 2001 Sam Lantinga This library is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public License for more details. You should have received a copy of the GNU Library General Public License along with this library; if not, write to the Free Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA Sam Lantinga slouken@devolution.com */ #include "SDL_QuartzKeys.h" static void QZ_InitOSKeymap (_THIS) { int i; for ( i=0; i<SDL_TABLESIZE(keymap); ++i ) keymap[i] = SDLK_UNKNOWN; // This keymap is almost exactly the same as the OS 9 one keymap[QZ_ESCAPE] = SDLK_ESCAPE; keymap[QZ_F1] = SDLK_F1; keymap[QZ_F2] = SDLK_F2; keymap[QZ_F3] = SDLK_F3; keymap[QZ_F4] = SDLK_F4; keymap[QZ_F5] = SDLK_F5; keymap[QZ_F6] = SDLK_F6; keymap[QZ_F7] = SDLK_F7; keymap[QZ_F8] = SDLK_F8; keymap[QZ_F9] = SDLK_F9; keymap[QZ_F10] = SDLK_F10; keymap[QZ_F11] = SDLK_F11; keymap[QZ_F12] = SDLK_F12; keymap[QZ_PRINT] = SDLK_PRINT; keymap[QZ_SCROLLOCK] = SDLK_SCROLLOCK; keymap[QZ_PAUSE] = SDLK_PAUSE; keymap[QZ_POWER] = SDLK_POWER; keymap[QZ_BACKQUOTE] = SDLK_BACKQUOTE; keymap[QZ_1] = SDLK_1; keymap[QZ_2] = SDLK_2; keymap[QZ_3] = SDLK_3; keymap[QZ_4] = SDLK_4; keymap[QZ_5] = SDLK_5; keymap[QZ_6] = SDLK_6; keymap[QZ_7] = SDLK_7; keymap[QZ_8] = SDLK_8; keymap[QZ_9] = SDLK_9; keymap[QZ_0] = SDLK_0; keymap[QZ_MINUS] = SDLK_MINUS; keymap[QZ_EQUALS] = SDLK_EQUALS; keymap[QZ_BACKSPACE] = SDLK_BACKSPACE; keymap[QZ_INSERT] = SDLK_INSERT; keymap[QZ_HOME] = SDLK_HOME; keymap[QZ_PAGEUP] = SDLK_PAGEUP; keymap[QZ_NUMLOCK] = SDLK_NUMLOCK; keymap[QZ_KP_EQUALS] = SDLK_KP_EQUALS; keymap[QZ_KP_DIVIDE] = SDLK_KP_DIVIDE; keymap[QZ_KP_MULTIPLY] = SDLK_KP_MULTIPLY; keymap[QZ_TAB] = SDLK_TAB; keymap[QZ_q] = SDLK_q; keymap[QZ_w] = SDLK_w; keymap[QZ_e] = SDLK_e; keymap[QZ_r] = SDLK_r; keymap[QZ_t] = SDLK_t; keymap[QZ_y] = SDLK_y; keymap[QZ_u] = SDLK_u; keymap[QZ_i] = SDLK_i; keymap[QZ_o] = SDLK_o; keymap[QZ_p] = SDLK_p; keymap[QZ_LEFTBRACKET] = SDLK_LEFTBRACKET; keymap[QZ_RIGHTBRACKET] = SDLK_RIGHTBRACKET; keymap[QZ_BACKSLASH] = SDLK_BACKSLASH; keymap[QZ_DELETE] = SDLK_DELETE; keymap[QZ_END] = SDLK_END; keymap[QZ_PAGEDOWN] = SDLK_PAGEDOWN; keymap[QZ_KP7] = SDLK_KP7; keymap[QZ_KP8] = SDLK_KP8; keymap[QZ_KP9] = SDLK_KP9; keymap[QZ_KP_MINUS] = SDLK_KP_MINUS; keymap[QZ_CAPSLOCK] = SDLK_CAPSLOCK; keymap[QZ_a] = SDLK_a; keymap[QZ_s] = SDLK_s; keymap[QZ_d] = SDLK_d; keymap[QZ_f] = SDLK_f; keymap[QZ_g] = SDLK_g; keymap[QZ_h] = SDLK_h; keymap[QZ_j] = SDLK_j; keymap[QZ_k] = SDLK_k; keymap[QZ_l] = SDLK_l; keymap[QZ_SEMICOLON] = SDLK_SEMICOLON; keymap[QZ_QUOTE] = SDLK_QUOTE; keymap[QZ_RETURN] = SDLK_RETURN; keymap[QZ_KP4] = SDLK_KP4; keymap[QZ_KP5] = SDLK_KP5; keymap[QZ_KP6] = SDLK_KP6; keymap[QZ_KP_PLUS] = SDLK_KP_PLUS; keymap[QZ_LSHIFT] = SDLK_LSHIFT; keymap[QZ_z] = SDLK_z; keymap[QZ_x] = SDLK_x; keymap[QZ_c] = SDLK_c; keymap[QZ_v] = SDLK_v; keymap[QZ_b] = SDLK_b; keymap[QZ_n] = SDLK_n; keymap[QZ_m] = SDLK_m; keymap[QZ_COMMA] = SDLK_COMMA; keymap[QZ_PERIOD] = SDLK_PERIOD; keymap[QZ_SLASH] = SDLK_SLASH; keymap[QZ_UP] = SDLK_UP; keymap[QZ_KP1] = SDLK_KP1; keymap[QZ_KP2] = SDLK_KP2; keymap[QZ_KP3] = SDLK_KP3; keymap[QZ_KP_ENTER] = SDLK_KP_ENTER; keymap[QZ_LCTRL] = SDLK_LCTRL; keymap[QZ_LALT] = SDLK_LALT; keymap[QZ_LMETA] = SDLK_LMETA; keymap[QZ_SPACE] = SDLK_SPACE; keymap[QZ_LEFT] = SDLK_LEFT; keymap[QZ_DOWN] = SDLK_DOWN; keymap[QZ_RIGHT] = SDLK_RIGHT; keymap[QZ_KP0] = SDLK_KP0; keymap[QZ_KP_PERIOD] = SDLK_KP_PERIOD; keymap[QZ_IBOOK_ENTER] = SDLK_KP_ENTER; keymap[QZ_IBOOK_RIGHT] = SDLK_RIGHT; keymap[QZ_IBOOK_DOWN] = SDLK_DOWN; keymap[QZ_IBOOK_UP] = SDLK_UP; keymap[QZ_IBOOK_LEFT] = SDLK_LEFT; } static void QZ_DoKey (int state, NSEvent *event) { NSString *chars; int i; SDL_keysym key; /* An event can contain multiple characters */ /* I'll ignore this fact for now, since there is only one virtual key code per event */ chars = [ event characters ]; for (i =0; i < 1 /*[ chars length ] */; i++) { key.scancode = [ event keyCode ]; key.sym = keymap [ key.scancode ]; key.unicode = [ chars characterAtIndex:i]; key.mod = KMOD_NONE; SDL_PrivateKeyboard (state, &key); } } static void QZ_DoModifiers (unsigned int newMods) { const int offset = 18; const int mapping[] = { SDLK_LSHIFT, SDLK_LCTRL, SDLK_LALT, 0, SDLK_LMETA } ; int bit; SDL_keysym key; key.scancode = 0; key.sym = SDLK_UNKNOWN; key.unicode = 0; key.mod = KMOD_NONE; /* Iterate through the bits, testing each against the current modifiers */ for (bit = NSShiftKeyMask; bit <= NSCommandKeyMask; bit <<= 1) { unsigned int currentMask, newMask; currentMask = currentMods & bit; newMask = newMods & bit; if ( currentMask && currentMask != newMask ) { /* modifier up event */ key.sym = mapping[ currentMask >> offset ]; SDL_PrivateKeyboard (SDL_RELEASED, &key); } else if ( newMask && currentMask != newMask ) { /* modifier down event */ key.sym = mapping [ newMask >> offset ]; SDL_PrivateKeyboard (SDL_PRESSED, &key); } } currentMods = newMods; } static void QZ_DoActivate (_THIS) { inForeground = YES; /* Regrab the mouse */ if (currentGrabMode == SDL_GRAB_ON) { QZ_WarpWMCursor (this, SDL_VideoSurface->w / 2, SDL_VideoSurface->h / 2); CGAssociateMouseAndMouseCursorPosition (0); } SDL_PrivateAppActive (1, SDL_APPINPUTFOCUS); } static void QZ_DoDeactivate (_THIS) { inForeground = NO; /* Ungrab mouse if it is grabbed */ if (currentGrabMode == SDL_GRAB_ON) { CGAssociateMouseAndMouseCursorPosition (1); } SDL_PrivateAppActive (0, SDL_APPINPUTFOCUS); } static void QZ_PumpEvents (_THIS) { NSDate *distantPast = [ NSDate distantPast ]; NSEvent *event; NSRect winRect; NSRect titleBarRect; winRect = NSMakeRect (0, 0, SDL_VideoSurface->w + 1, SDL_VideoSurface->h + 1); titleBarRect = NSMakeRect ( 0, SDL_VideoSurface->h, SDL_VideoSurface->w, SDL_VideoSurface->h + 22 ); do { /* Poll for an event. This will not block */ event = [ NSApp nextEventMatchingMask:NSAnyEventMask untilDate:distantPast inMode: NSDefaultRunLoopMode dequeue:YES ]; if (event != nil) { unsigned int type; #define DO_MOUSE_DOWN(button, sendToWindow) \ if ( inForeground ) { \ if ( (SDL_VideoSurface->flags & SDL_FULLSCREEN) || \ NSPointInRect([event locationInWindow], winRect) ) \ SDL_PrivateMouseButton (SDL_PRESSED, button, 0, 0); \ else if (sendToWindow) \ [ window sendEvent:event ]; \ } \ else { \ QZ_DoActivate (this); \ } #define DO_MOUSE_UP(button, sendToWindow) \ if ( (SDL_VideoSurface->flags & SDL_FULLSCREEN) || \ !NSPointInRect([event locationInWindow], titleBarRect) )\ SDL_PrivateMouseButton (SDL_RELEASED, button, 0, 0); \ if (sendToWindow) \ [ window sendEvent:event ] type = [ event type ]; switch (type) { case NSLeftMouseDown: if ( NSCommandKeyMask & currentMods ) { DO_MOUSE_DOWN (3, 0); } else if ( NSAlternateKeyMask & currentMods ) { DO_MOUSE_DOWN (2, 0); } else { DO_MOUSE_DOWN (1, 1); } break; case 25: DO_MOUSE_DOWN (2, 0); break; case NSRightMouseDown: DO_MOUSE_DOWN (3, 0); break; case NSLeftMouseUp: if ( NSCommandKeyMask & currentMods ) { DO_MOUSE_UP (3, 0); } else if ( NSAlternateKeyMask & currentMods ) { DO_MOUSE_UP (2, 0); } else DO_MOUSE_UP (1, 1); break; case 26: DO_MOUSE_UP (2, 0); break; case NSRightMouseUp: DO_MOUSE_UP (3, 0); break; case NSSystemDefined: //if ([event subtype] == 7) { // unsigned int buttons; // up to 32 mouse button states! // buttons = [ event data2 ]; //} break; case NSLeftMouseDragged: case NSRightMouseDragged: case 27: case NSMouseMoved: { static int moves = 0; NSPoint p; if ( SDL_VideoSurface->flags & SDL_FULLSCREEN ) { p = [ NSEvent mouseLocation ]; p.y = [[NSScreen mainScreen] frame].size.height - p.y; } else { p = [ event locationInWindow ]; p.y = SDL_VideoSurface->h - p.y; } if ( (moves % 10) == 0 ) { SDL_PrivateMouseMotion (0, 0, p.x, p.y); } else { CGMouseDelta dx, dy; CGGetLastMouseDelta (&dx, &dy); SDL_PrivateMouseMotion (0, 1, dx, dy); } moves++; } break; case NSScrollWheel: { if (NSPointInRect([ event locationInWindow ], winRect)) { float dy; dy = [ event deltaY ]; if ( dy > 0.0 ) /* Scroll up */ SDL_PrivateMouseButton (SDL_PRESSED, 4, 0, 0); else /* Scroll down */ SDL_PrivateMouseButton (SDL_PRESSED, 5, 0, 0); } } break; case NSKeyUp: QZ_DoKey (SDL_RELEASED, event); break; case NSKeyDown: QZ_DoKey (SDL_PRESSED, event); break; case NSFlagsChanged: QZ_DoModifiers( [ event modifierFlags ] ); break; case NSMouseEntered: break; case NSMouseExited: break; case NSAppKitDefined: switch ( [ event subtype ] ) { case NSApplicationActivatedEventType: QZ_DoActivate (this); break; case NSApplicationDeactivatedEventType: QZ_DoDeactivate (this); break; case NSWindowMovedEventType: [ window sendEvent:event ]; break; } break; case NSApplicationDefined: break; case NSPeriodic: break; case NSCursorUpdate: break; } } } while (event != nil); }