src/video/quartz/SDL_QuartzEvents.m
author Sam Lantinga <slouken@libsdl.org>
Tue, 11 Sep 2001 19:00:18 +0000
changeset 172 37e3ca9254c7
parent 168 e92aa316c517
child 252 e8157fcb3114
permissions -rw-r--r--
Date: Sat, 8 Sep 2001 04:42:23 +0200
From: Max Horn <max@quendi.de>
Subject: SDL/OSX: Joystick; Better key handling

I just finished implementing improved keyhandling for OS X (in fact
the code should be easily ported to the "normal" MacOS part of SDL, I
just had no chance yet). Works like this:
First init the mapping table statically like before. Them, it queries
the OS for the "official" key table, then iterates over all 127
scancode and gets the associates ascii code. It ignores everythng
below 32 (has to, as it would lead to many problems if we did not...
e.g. both ESC and NUM LOCk produce an ascii code 27 on my keyboard),
and all stuff above 127 is mapped to SDLK_WORLD_* simply in the order
it is encountered.
In addition, caps lock is now working, too.
The code work flawless for me, but since I only have one keyboard, I
may have not encountered some serious problem... but I am pretty
confident that it is better than the old code in most cases.


The joystick driver works fine for me, too. I think it can be added
to CVS already. It would simply be helpful if more people would test
it. Hm, I wonder if Maelstrom or GLTron has Joystick support? That
would be a wonderful test application :)


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