src/video/quartz/SDL_QuartzEvents.m
author Sam Lantinga <slouken@libsdl.org>
Tue, 22 Jan 2002 18:46:28 +0000
changeset 272 d1447a846d80
parent 252 e8157fcb3114
child 297 f6ffac90895c
permissions -rw-r--r--
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.
slouken@47
     1
/*
slouken@172
     2
	SDL - Simple DirectMedia Layer
slouken@172
     3
	Copyright (C) 1997, 1998, 1999, 2000, 2001	Sam Lantinga
slouken@47
     4
slouken@172
     5
	This library is free software; you can redistribute it and/or
slouken@172
     6
	modify it under the terms of the GNU Library General Public
slouken@172
     7
	License as published by the Free Software Foundation; either
slouken@172
     8
	version 2 of the License, or (at your option) any later version.
slouken@47
     9
slouken@172
    10
	This library is distributed in the hope that it will be useful,
slouken@172
    11
	but WITHOUT ANY WARRANTY; without even the implied warranty of
slouken@172
    12
	MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
slouken@172
    13
	Library General Public License for more details.
slouken@47
    14
slouken@172
    15
	You should have received a copy of the GNU Library General Public
slouken@172
    16
	License along with this library; if not, write to the Free
slouken@172
    17
	Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
slouken@47
    18
slouken@172
    19
	Sam Lantinga
slouken@252
    20
	slouken@libsdl.org
slouken@47
    21
*/
slouken@272
    22
#include <sys/time.h>
slouken@47
    23
slouken@47
    24
#include "SDL_QuartzKeys.h"
slouken@47
    25
slouken@172
    26
static SDLKey keymap[256];
slouken@172
    27
static unsigned int currentMods = 0; /* Current keyboard modifiers, to track modifier state */
slouken@172
    28
static int last_virtual_button = 0; /* Last virtual mouse button pressed */
slouken@155
    29
slouken@172
    30
static void	 QZ_InitOSKeymap (_THIS) {
slouken@172
    31
	const void *KCHRPtr;
slouken@172
    32
	UInt32 state;
slouken@172
    33
	UInt32 value;
slouken@47
    34
	int i;
slouken@172
    35
	int world = SDLK_WORLD_0;
slouken@172
    36
	
slouken@47
    37
	for ( i=0; i<SDL_TABLESIZE(keymap); ++i )
slouken@47
    38
		keymap[i] = SDLK_UNKNOWN;
slouken@47
    39
slouken@172
    40
	/* This keymap is almost exactly the same as the OS 9 one */
slouken@172
    41
	keymap[QZ_ESCAPE] = SDLK_ESCAPE;
slouken@47
    42
	keymap[QZ_F1] = SDLK_F1;
slouken@47
    43
	keymap[QZ_F2] = SDLK_F2;
slouken@47
    44
	keymap[QZ_F3] = SDLK_F3;
slouken@47
    45
	keymap[QZ_F4] = SDLK_F4;
slouken@47
    46
	keymap[QZ_F5] = SDLK_F5;
slouken@47
    47
	keymap[QZ_F6] = SDLK_F6;
slouken@47
    48
	keymap[QZ_F7] = SDLK_F7;
slouken@47
    49
	keymap[QZ_F8] = SDLK_F8;
slouken@47
    50
	keymap[QZ_F9] = SDLK_F9;
slouken@47
    51
	keymap[QZ_F10] = SDLK_F10;
slouken@47
    52
	keymap[QZ_F11] = SDLK_F11;
slouken@47
    53
	keymap[QZ_F12] = SDLK_F12;
slouken@47
    54
	keymap[QZ_PRINT] = SDLK_PRINT;
slouken@47
    55
	keymap[QZ_SCROLLOCK] = SDLK_SCROLLOCK;
slouken@47
    56
	keymap[QZ_PAUSE] = SDLK_PAUSE;
slouken@47
    57
	keymap[QZ_POWER] = SDLK_POWER;
slouken@47
    58
	keymap[QZ_BACKQUOTE] = SDLK_BACKQUOTE;
slouken@47
    59
	keymap[QZ_1] = SDLK_1;
slouken@47
    60
	keymap[QZ_2] = SDLK_2;
slouken@47
    61
	keymap[QZ_3] = SDLK_3;
slouken@47
    62
	keymap[QZ_4] = SDLK_4;
slouken@47
    63
	keymap[QZ_5] = SDLK_5;
slouken@47
    64
	keymap[QZ_6] = SDLK_6;
slouken@47
    65
	keymap[QZ_7] = SDLK_7;
slouken@47
    66
	keymap[QZ_8] = SDLK_8;
slouken@47
    67
	keymap[QZ_9] = SDLK_9;
slouken@47
    68
	keymap[QZ_0] = SDLK_0;
slouken@47
    69
	keymap[QZ_MINUS] = SDLK_MINUS;
slouken@47
    70
	keymap[QZ_EQUALS] = SDLK_EQUALS;
slouken@47
    71
	keymap[QZ_BACKSPACE] = SDLK_BACKSPACE;
slouken@47
    72
	keymap[QZ_INSERT] = SDLK_INSERT;
slouken@47
    73
	keymap[QZ_HOME] = SDLK_HOME;
slouken@47
    74
	keymap[QZ_PAGEUP] = SDLK_PAGEUP;
slouken@47
    75
	keymap[QZ_NUMLOCK] = SDLK_NUMLOCK;
slouken@47
    76
	keymap[QZ_KP_EQUALS] = SDLK_KP_EQUALS;
slouken@47
    77
	keymap[QZ_KP_DIVIDE] = SDLK_KP_DIVIDE;
slouken@47
    78
	keymap[QZ_KP_MULTIPLY] = SDLK_KP_MULTIPLY;
slouken@47
    79
	keymap[QZ_TAB] = SDLK_TAB;
slouken@47
    80
	keymap[QZ_q] = SDLK_q;
slouken@47
    81
	keymap[QZ_w] = SDLK_w;
slouken@47
    82
	keymap[QZ_e] = SDLK_e;
slouken@47
    83
	keymap[QZ_r] = SDLK_r;
slouken@47
    84
	keymap[QZ_t] = SDLK_t;
slouken@47
    85
	keymap[QZ_y] = SDLK_y;
slouken@47
    86
	keymap[QZ_u] = SDLK_u;
slouken@47
    87
	keymap[QZ_i] = SDLK_i;
slouken@47
    88
	keymap[QZ_o] = SDLK_o;
slouken@47
    89
	keymap[QZ_p] = SDLK_p;
slouken@47
    90
	keymap[QZ_LEFTBRACKET] = SDLK_LEFTBRACKET;
slouken@47
    91
	keymap[QZ_RIGHTBRACKET] = SDLK_RIGHTBRACKET;
slouken@47
    92
	keymap[QZ_BACKSLASH] = SDLK_BACKSLASH;
slouken@47
    93
	keymap[QZ_DELETE] = SDLK_DELETE;
slouken@47
    94
	keymap[QZ_END] = SDLK_END;
slouken@47
    95
	keymap[QZ_PAGEDOWN] = SDLK_PAGEDOWN;
slouken@47
    96
	keymap[QZ_KP7] = SDLK_KP7;
slouken@47
    97
	keymap[QZ_KP8] = SDLK_KP8;
slouken@47
    98
	keymap[QZ_KP9] = SDLK_KP9;
slouken@47
    99
	keymap[QZ_KP_MINUS] = SDLK_KP_MINUS;
slouken@47
   100
	keymap[QZ_CAPSLOCK] = SDLK_CAPSLOCK;
slouken@47
   101
	keymap[QZ_a] = SDLK_a;
slouken@47
   102
	keymap[QZ_s] = SDLK_s;
slouken@47
   103
	keymap[QZ_d] = SDLK_d;
slouken@47
   104
	keymap[QZ_f] = SDLK_f;
slouken@47
   105
	keymap[QZ_g] = SDLK_g;
slouken@47
   106
	keymap[QZ_h] = SDLK_h;
slouken@47
   107
	keymap[QZ_j] = SDLK_j;
slouken@47
   108
	keymap[QZ_k] = SDLK_k;
slouken@47
   109
	keymap[QZ_l] = SDLK_l;
slouken@47
   110
	keymap[QZ_SEMICOLON] = SDLK_SEMICOLON;
slouken@47
   111
	keymap[QZ_QUOTE] = SDLK_QUOTE;
slouken@47
   112
	keymap[QZ_RETURN] = SDLK_RETURN;
slouken@47
   113
	keymap[QZ_KP4] = SDLK_KP4;
slouken@47
   114
	keymap[QZ_KP5] = SDLK_KP5;
slouken@47
   115
	keymap[QZ_KP6] = SDLK_KP6;
slouken@47
   116
	keymap[QZ_KP_PLUS] = SDLK_KP_PLUS;
slouken@47
   117
	keymap[QZ_LSHIFT] = SDLK_LSHIFT;
slouken@47
   118
	keymap[QZ_z] = SDLK_z;
slouken@47
   119
	keymap[QZ_x] = SDLK_x;
slouken@47
   120
	keymap[QZ_c] = SDLK_c;
slouken@47
   121
	keymap[QZ_v] = SDLK_v;
slouken@47
   122
	keymap[QZ_b] = SDLK_b;
slouken@47
   123
	keymap[QZ_n] = SDLK_n;
slouken@47
   124
	keymap[QZ_m] = SDLK_m;
slouken@47
   125
	keymap[QZ_COMMA] = SDLK_COMMA;
slouken@47
   126
	keymap[QZ_PERIOD] = SDLK_PERIOD;
slouken@47
   127
	keymap[QZ_SLASH] = SDLK_SLASH;
slouken@47
   128
	keymap[QZ_UP] = SDLK_UP;
slouken@47
   129
	keymap[QZ_KP1] = SDLK_KP1;
slouken@47
   130
	keymap[QZ_KP2] = SDLK_KP2;
slouken@47
   131
	keymap[QZ_KP3] = SDLK_KP3;
slouken@47
   132
	keymap[QZ_KP_ENTER] = SDLK_KP_ENTER;
slouken@47
   133
	keymap[QZ_LCTRL] = SDLK_LCTRL;
slouken@47
   134
	keymap[QZ_LALT] = SDLK_LALT;
slouken@47
   135
	keymap[QZ_LMETA] = SDLK_LMETA;
slouken@47
   136
	keymap[QZ_SPACE] = SDLK_SPACE;
slouken@47
   137
	keymap[QZ_LEFT] = SDLK_LEFT;
slouken@47
   138
	keymap[QZ_DOWN] = SDLK_DOWN;
slouken@47
   139
	keymap[QZ_RIGHT] = SDLK_RIGHT;
slouken@47
   140
	keymap[QZ_KP0] = SDLK_KP0;
slouken@47
   141
	keymap[QZ_KP_PERIOD] = SDLK_KP_PERIOD;
slouken@47
   142
	keymap[QZ_IBOOK_ENTER] = SDLK_KP_ENTER;
slouken@47
   143
	keymap[QZ_IBOOK_RIGHT] = SDLK_RIGHT;
slouken@47
   144
	keymap[QZ_IBOOK_DOWN] = SDLK_DOWN;
slouken@172
   145
	keymap[QZ_IBOOK_UP]	  = SDLK_UP;
slouken@47
   146
	keymap[QZ_IBOOK_LEFT] = SDLK_LEFT;
slouken@172
   147
	
slouken@172
   148
	/* Up there we setup a static scancode->keysym map. However, it will not
slouken@172
   149
	 * work very well on international keyboard. Hence we now query MacOS
slouken@172
   150
	 * for its own keymap to adjust our own mapping table. However, this is
slouken@172
   151
	 * bascially only useful for ascii char keys. This is also the reason
slouken@172
   152
	 * why we keep the static table, too.
slouken@172
   153
	 */
slouken@172
   154
	
slouken@172
   155
	/* Get a pointer to the systems cached KCHR */
slouken@172
   156
	KCHRPtr = (void *)GetScriptManagerVariable(smKCHRCache);
slouken@172
   157
	if (KCHRPtr)
slouken@172
   158
	{
slouken@172
   159
		/* Loop over all 127 possible scan codes */
slouken@172
   160
		for (i = 0; i < 0x7F; i++)
slouken@172
   161
		{
slouken@172
   162
			/* We pretend a clean start to begin with (i.e. no dead keys active */
slouken@172
   163
			state = 0;
slouken@172
   164
			
slouken@172
   165
			/* Now translate the key code to a key value */
slouken@172
   166
			value = KeyTranslate(KCHRPtr, i, &state) & 0xff;
slouken@172
   167
			
slouken@172
   168
			/* If the state become 0, it was a dead key. We need to translate again,
slouken@172
   169
			passing in the new state, to get the actual key value */
slouken@172
   170
			if (state != 0)
slouken@172
   171
				value = KeyTranslate(KCHRPtr, i, &state) & 0xff;
slouken@172
   172
			
slouken@172
   173
			/* Now we should have an ascii value, or 0. Try to figure out to which SDL symbol it maps */
slouken@172
   174
			if (value >= 128)	 /* Some non-ASCII char, map it to SDLK_WORLD_* */
slouken@172
   175
				keymap[i] = world++;
slouken@172
   176
			else if (value >= 32)	 /* non-control ASCII char */
slouken@172
   177
				keymap[i] = value;
slouken@172
   178
		}
slouken@172
   179
	}
slouken@172
   180
	
slouken@172
   181
	/* The keypad codes are re-setup here, because the loop above cannot
slouken@172
   182
	 * distinguish between a key on the keypad and a regular key. We maybe
slouken@172
   183
	 * could get around this problem in another fashion: NSEvent's flags
slouken@172
   184
	 * include a "NSNumericPadKeyMask" bit; we could check that and modify
slouken@172
   185
	 * the symbol we return on the fly. However, this flag seems to exhibit
slouken@172
   186
	 * some weird behaviour related to the num lock key
slouken@172
   187
	 */
slouken@172
   188
	keymap[QZ_KP0] = SDLK_KP0;
slouken@172
   189
	keymap[QZ_KP1] = SDLK_KP1;
slouken@172
   190
	keymap[QZ_KP2] = SDLK_KP2;
slouken@172
   191
	keymap[QZ_KP3] = SDLK_KP3;
slouken@172
   192
	keymap[QZ_KP4] = SDLK_KP4;
slouken@172
   193
	keymap[QZ_KP5] = SDLK_KP5;
slouken@172
   194
	keymap[QZ_KP6] = SDLK_KP6;
slouken@172
   195
	keymap[QZ_KP7] = SDLK_KP7;
slouken@172
   196
	keymap[QZ_KP8] = SDLK_KP8;
slouken@172
   197
	keymap[QZ_KP9] = SDLK_KP9;
slouken@172
   198
	keymap[QZ_KP_MINUS] = SDLK_KP_MINUS;
slouken@172
   199
	keymap[QZ_KP_PLUS] = SDLK_KP_PLUS;
slouken@172
   200
	keymap[QZ_KP_PERIOD] = SDLK_KP_PERIOD;
slouken@172
   201
	keymap[QZ_KP_EQUALS] = SDLK_KP_EQUALS;
slouken@172
   202
	keymap[QZ_KP_DIVIDE] = SDLK_KP_DIVIDE;
slouken@172
   203
	keymap[QZ_KP_MULTIPLY] = SDLK_KP_MULTIPLY;
slouken@172
   204
	keymap[QZ_KP_ENTER] = SDLK_KP_ENTER;
slouken@47
   205
}
slouken@47
   206
slouken@47
   207
static void QZ_DoKey (int state, NSEvent *event) {
slouken@47
   208
slouken@172
   209
	NSString *chars;
slouken@172
   210
	int i;
slouken@172
   211
	SDL_keysym key;
slouken@172
   212
	
slouken@172
   213
	/* An event can contain multiple characters */
slouken@172
   214
	/* I'll ignore this fact for now, since there is only one virtual key code per event */
slouken@172
   215
	chars = [ event characters ];
slouken@172
   216
	for (i =0; i < 1 /*[ chars length ] */; i++) {
slouken@172
   217
				
slouken@172
   218
		key.scancode = [ event keyCode ];
slouken@172
   219
		key.sym		 = keymap [ key.scancode ];
slouken@172
   220
		key.unicode	 = [ chars characterAtIndex:i];
slouken@172
   221
		key.mod		 = KMOD_NONE;
slouken@172
   222
					
slouken@172
   223
		SDL_PrivateKeyboard (state, &key);
slouken@172
   224
	}
slouken@47
   225
}
slouken@47
   226
slouken@47
   227
static void QZ_DoModifiers (unsigned int newMods) {
slouken@47
   228
slouken@172
   229
	const int mapping[] = { SDLK_CAPSLOCK, SDLK_LSHIFT, SDLK_LCTRL, SDLK_LALT, SDLK_LMETA } ;
slouken@47
   230
slouken@172
   231
	int i;
slouken@172
   232
	int bit;
slouken@172
   233
	SDL_keysym key;
slouken@47
   234
slouken@172
   235
	key.scancode = 0;
slouken@172
   236
	key.sym		 = SDLK_UNKNOWN;
slouken@172
   237
	key.unicode	 = 0;
slouken@172
   238
	key.mod		 = KMOD_NONE;
slouken@172
   239
	
slouken@172
   240
	/* Iterate through the bits, testing each against the current modifiers */
slouken@172
   241
	for (i = 0, bit = NSAlphaShiftKeyMask; bit <= NSCommandKeyMask; bit <<= 1, ++i) {
slouken@172
   242
	
slouken@172
   243
		unsigned int currentMask, newMask;
slouken@172
   244
		
slouken@172
   245
		currentMask = currentMods & bit;
slouken@172
   246
		newMask		= newMods & bit;
slouken@172
   247
		
slouken@172
   248
		if ( currentMask &&
slouken@172
   249
			 currentMask != newMask ) {	 /* modifier up event */
slouken@172
   250
slouken@172
   251
			key.sym = mapping[i];
slouken@172
   252
			/* If this was Caps Lock, we need some additional voodoo to make SDL happy */
slouken@172
   253
			if (bit == NSAlphaShiftKeyMask)
slouken@172
   254
				SDL_PrivateKeyboard (SDL_PRESSED, &key);
slouken@172
   255
			SDL_PrivateKeyboard (SDL_RELEASED, &key);
slouken@172
   256
		}
slouken@172
   257
		else
slouken@172
   258
		if ( newMask &&
slouken@172
   259
			 currentMask != newMask ) {	 /* modifier down event */
slouken@172
   260
		
slouken@172
   261
			key.sym = mapping[i];
slouken@172
   262
			SDL_PrivateKeyboard (SDL_PRESSED, &key);
slouken@172
   263
			/* If this was Caps Lock, we need some additional voodoo to make SDL happy */
slouken@172
   264
			if (bit == NSAlphaShiftKeyMask)
slouken@172
   265
				SDL_PrivateKeyboard (SDL_RELEASED, &key);
slouken@172
   266
		}
slouken@172
   267
	}
slouken@172
   268
	
slouken@172
   269
	currentMods = newMods;
slouken@47
   270
}
slouken@47
   271
slouken@117
   272
static void QZ_DoActivate (_THIS)
slouken@117
   273
{
slouken@172
   274
	inForeground = YES;
slouken@47
   275
slouken@172
   276
	/* Regrab the mouse */
slouken@172
   277
	if (currentGrabMode == SDL_GRAB_ON) {
slouken@172
   278
		QZ_WarpWMCursor (this, SDL_VideoSurface->w / 2, SDL_VideoSurface->h / 2);
slouken@172
   279
		CGAssociateMouseAndMouseCursorPosition (0);
slouken@172
   280
	}
slouken@168
   281
slouken@172
   282
	/* Hide the mouse cursor if inside the app window */
slouken@172
   283
	if (!QZ_cursor_visible) {
slouken@172
   284
		HideCursor ();
slouken@172
   285
	}
slouken@172
   286
	
slouken@172
   287
	SDL_PrivateAppActive (1, SDL_APPINPUTFOCUS);
slouken@47
   288
}
slouken@47
   289
slouken@47
   290
static void QZ_DoDeactivate (_THIS) {
slouken@172
   291
	
slouken@172
   292
	inForeground = NO;
slouken@47
   293
slouken@172
   294
	/* Ungrab mouse if it is grabbed */
slouken@172
   295
	if (currentGrabMode == SDL_GRAB_ON) {
slouken@172
   296
		CGAssociateMouseAndMouseCursorPosition (1);
slouken@172
   297
	}
slouken@168
   298
slouken@172
   299
	/* Show the mouse cursor */
slouken@172
   300
	if (!QZ_cursor_visible) {
slouken@172
   301
		ShowCursor ();
slouken@172
   302
	}
slouken@172
   303
	
slouken@172
   304
	SDL_PrivateAppActive (0, SDL_APPINPUTFOCUS);
slouken@47
   305
}
slouken@47
   306
slouken@117
   307
static void QZ_PumpEvents (_THIS)
slouken@158
   308
{
slouken@272
   309
	
slouken@272
   310
        static NSPoint lastMouse;
slouken@272
   311
        NSPoint mouse, saveMouse;
slouken@272
   312
        Point qdMouse;
slouken@272
   313
        CGMouseDelta dx, dy;
slouken@272
   314
        
slouken@272
   315
        NSDate *distantPast;
slouken@172
   316
	NSEvent *event;
slouken@172
   317
	NSRect winRect;
slouken@172
   318
	NSRect titleBarRect;
slouken@172
   319
	NSAutoreleasePool *pool;
slouken@172
   320
	
slouken@172
   321
	pool = [ [ NSAutoreleasePool alloc ] init ];
slouken@172
   322
	distantPast = [ NSDate distantPast ];
slouken@172
   323
	
slouken@272
   324
	winRect = NSMakeRect (0, 0, SDL_VideoSurface->w, SDL_VideoSurface->h);
slouken@172
   325
	titleBarRect = NSMakeRect ( 0, SDL_VideoSurface->h, SDL_VideoSurface->w,
slouken@172
   326
		SDL_VideoSurface->h + 22 );
slouken@272
   327
	
slouken@272
   328
        if (currentGrabMode != SDL_GRAB_ON) { /* if grabbed, the cursor can't move! (see fallback below) */
slouken@272
   329
        
slouken@272
   330
            /* 1/2 second after a warp, the mouse cannot move (don't ask me why) */
slouken@272
   331
            /* So, approximate motion with CGGetLastMouseDelta, which still works, somehow */
slouken@272
   332
            if (! warp_flag) {
slouken@272
   333
            
slouken@272
   334
                GetGlobalMouse (&qdMouse);  /* use Carbon since [ NSEvent mouseLocation ] is broken */
slouken@272
   335
                mouse = NSMakePoint (qdMouse.h, qdMouse.v);
slouken@272
   336
                saveMouse = mouse;
slouken@272
   337
                
slouken@272
   338
                if (mouse.x != lastMouse.x || mouse.y != lastMouse.y) {
slouken@272
   339
                
slouken@272
   340
                    QZ_PrivateCGToSDL (this, &mouse);
slouken@272
   341
                    if (inForeground && NSPointInRect (mouse, winRect)) {
slouken@272
   342
                        //printf ("Mouse Loc: (%f, %f)\n", mouse.x, mouse.y);
slouken@272
   343
                        SDL_PrivateMouseMotion (0, 0, mouse.x, mouse.y);
slouken@272
   344
                    }
slouken@272
   345
                }
slouken@272
   346
                lastMouse = saveMouse;
slouken@272
   347
            }
slouken@272
   348
        }
slouken@272
   349
        
slouken@272
   350
        /* accumulate any mouse events into one SDL mouse event */
slouken@272
   351
        dx = 0;
slouken@272
   352
        dy = 0;
slouken@272
   353
        
slouken@172
   354
	do {
slouken@172
   355
	
slouken@172
   356
		/* Poll for an event. This will not block */
slouken@172
   357
		event = [ NSApp nextEventMatchingMask:NSAnyEventMask
slouken@172
   358
					untilDate:distantPast
slouken@172
   359
					inMode: NSDefaultRunLoopMode dequeue:YES ];
slouken@172
   360
	
slouken@172
   361
		if (event != nil) {
slouken@172
   362
			unsigned int type;
slouken@172
   363
			BOOL isForGameWin;
slouken@117
   364
slouken@172
   365
			#define DO_MOUSE_DOWN(button, sendToWindow) do {				 \
slouken@272
   366
				if ( inForeground ) {			                                 \
slouken@172
   367
					if ( (SDL_VideoSurface->flags & SDL_FULLSCREEN) ||		 \
slouken@172
   368
						 NSPointInRect([event locationInWindow], winRect) )	 \
slouken@172
   369
						SDL_PrivateMouseButton (SDL_PRESSED, button, 0, 0);	 \
slouken@272
   370
				}                                                                        \
slouken@272
   371
				else {									 \
slouken@272
   372
					QZ_DoActivate (this);                                            \
slouken@272
   373
				}									 \
slouken@272
   374
				[ NSApp sendEvent:event ];			                         \
slouken@172
   375
				} while(0)
slouken@172
   376
				
slouken@172
   377
			#define DO_MOUSE_UP(button, sendToWindow) do {					 \
slouken@172
   378
				if ( (SDL_VideoSurface->flags & SDL_FULLSCREEN) ||			 \
slouken@272
   379
					 !NSPointInRect([event locationInWindow], titleBarRect) )        \
slouken@272
   380
					SDL_PrivateMouseButton (SDL_RELEASED, button, 0, 0);	         \
slouken@272
   381
				[ NSApp sendEvent:event ];						 \
slouken@172
   382
				} while(0)
slouken@158
   383
slouken@172
   384
			type = [ event type ];
slouken@172
   385
			isForGameWin = (qz_window == [ event window ]);
slouken@172
   386
			switch (type) {
slouken@172
   387
			
slouken@172
   388
			case NSLeftMouseDown:
slouken@172
   389
				if ( NSCommandKeyMask & currentMods ) {
slouken@172
   390
					last_virtual_button = 3;
slouken@172
   391
					DO_MOUSE_DOWN (3, 0);
slouken@172
   392
				}
slouken@172
   393
				else if ( NSAlternateKeyMask & currentMods ) {
slouken@172
   394
					last_virtual_button = 2;
slouken@172
   395
					DO_MOUSE_DOWN (2, 0);
slouken@172
   396
				}
slouken@172
   397
				else {
slouken@172
   398
					DO_MOUSE_DOWN (1, 1);
slouken@172
   399
				}
slouken@172
   400
				break;
slouken@272
   401
			case NSOtherMouseDown: DO_MOUSE_DOWN (2, 0); break;
slouken@172
   402
			case NSRightMouseDown: DO_MOUSE_DOWN (3, 0); break;	
slouken@172
   403
			case NSLeftMouseUp:
slouken@172
   404
			
slouken@172
   405
				if ( last_virtual_button != 0 ) {
slouken@172
   406
					DO_MOUSE_UP (last_virtual_button, 0);
slouken@172
   407
					last_virtual_button = 0;
slouken@172
   408
				}
slouken@172
   409
				else {
slouken@172
   410
					DO_MOUSE_UP (1, 1);
slouken@172
   411
				}
slouken@172
   412
				break;
slouken@272
   413
			case NSOtherMouseUp:   DO_MOUSE_UP (2, 0);	 break;
slouken@172
   414
			case NSRightMouseUp:   DO_MOUSE_UP (3, 0);	 break;
slouken@172
   415
			case NSSystemDefined:
slouken@172
   416
				//if ([event subtype] == 7) {
slouken@172
   417
				//	  unsigned int buttons;	  // up to 32 mouse button states!
slouken@172
   418
				//	  buttons = [ event data2 ];
slouken@172
   419
				//}
slouken@172
   420
				break;
slouken@172
   421
			case NSLeftMouseDragged:
slouken@172
   422
			case NSRightMouseDragged:
slouken@172
   423
			case 27:
slouken@172
   424
			case NSMouseMoved:
slouken@272
   425
                            
slouken@272
   426
                                if (currentGrabMode == SDL_GRAB_ON) { 
slouken@272
   427
                                    
slouken@272
   428
                                    /** 
slouken@272
   429
                                     *  If input is grabbed, we'll wing it and try to send some mouse
slouken@272
   430
                                     *  moved events with CGGetLastMouseDelta(). Not optimal, but better
slouken@272
   431
                                     *  than nothing.
slouken@272
   432
                                     **/ 
slouken@272
   433
                                     CGMouseDelta dx1, dy1;
slouken@272
   434
                                     CGGetLastMouseDelta (&dx1, &dy1);
slouken@272
   435
                                     dx += dx1;
slouken@272
   436
                                     dy += dy1;
slouken@272
   437
                                }
slouken@272
   438
                                else if (warp_flag) {
slouken@272
   439
                                
slouken@272
   440
                                    Uint32 ticks;
slouken@272
   441
                
slouken@272
   442
                                    ticks = SDL_GetTicks();
slouken@272
   443
                                    if (ticks - warp_ticks < 150) {
slouken@272
   444
                                    
slouken@272
   445
                                        CGMouseDelta dx1, dy1;
slouken@272
   446
                                        CGGetLastMouseDelta (&dx1, &dy1);
slouken@272
   447
                                        dx += dx1;
slouken@272
   448
                                        dy += dy1;
slouken@272
   449
                                    }
slouken@272
   450
                                    else {
slouken@272
   451
                                        
slouken@272
   452
                                        warp_flag = 0;
slouken@272
   453
                                    }
slouken@272
   454
                                }
slouken@272
   455
                                
slouken@172
   456
				break;
slouken@172
   457
			case NSScrollWheel:
slouken@172
   458
				{
slouken@172
   459
					if (NSPointInRect([ event locationInWindow ], winRect)) {
slouken@172
   460
						float dy;
slouken@172
   461
						dy = [ event deltaY ];
slouken@172
   462
						if ( dy > 0.0 ) /* Scroll up */
slouken@172
   463
							SDL_PrivateMouseButton (SDL_PRESSED, 4, 0, 0);
slouken@172
   464
						else /* Scroll down */
slouken@172
   465
							SDL_PrivateMouseButton (SDL_PRESSED, 5, 0, 0);
slouken@172
   466
					}
slouken@172
   467
				}
slouken@172
   468
				break;
slouken@172
   469
			case NSKeyUp:
slouken@172
   470
				QZ_DoKey (SDL_RELEASED, event);
slouken@172
   471
				break;
slouken@172
   472
			case NSKeyDown:
slouken@172
   473
				QZ_DoKey (SDL_PRESSED, event);
slouken@172
   474
				break;
slouken@172
   475
			case NSFlagsChanged:
slouken@172
   476
				QZ_DoModifiers( [ event modifierFlags ] );
slouken@172
   477
				break;
slouken@172
   478
			case NSAppKitDefined:
slouken@172
   479
				switch ( [ event subtype ] ) {
slouken@172
   480
				case NSApplicationActivatedEventType:
slouken@172
   481
					QZ_DoActivate (this);
slouken@172
   482
					break;
slouken@172
   483
				case NSApplicationDeactivatedEventType:
slouken@172
   484
					QZ_DoDeactivate (this);
slouken@172
   485
					break;
slouken@172
   486
				}
slouken@172
   487
				[ NSApp sendEvent:event ];
slouken@172
   488
				break;
slouken@172
   489
			/* case NSApplicationDefined: break; */
slouken@172
   490
			/* case NSPeriodic: break; */
slouken@172
   491
			/* case NSCursorUpdate: break; */
slouken@272
   492
                        
slouken@272
   493
                        default:
slouken@172
   494
				[ NSApp sendEvent:event ];
slouken@172
   495
			}
slouken@172
   496
		}
slouken@172
   497
	  } while (event != nil);
slouken@172
   498
	
slouken@272
   499
          /* check for accumulated mouse events */
slouken@272
   500
          if (dx != 0 || dy != 0)
slouken@272
   501
            SDL_PrivateMouseMotion (0, 1, dx, dy);
slouken@272
   502
        
slouken@172
   503
	  [ pool release ];
slouken@47
   504
}
slouken@47
   505