Mercurial > sdl-ios-xcode
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 |