comparison src/video/quartz/SDL_QuartzEvents.m @ 390:19e73568a75c

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