Mercurial > sdl-ios-xcode
annotate src/video/bwindow/SDL_sysevents.cc @ 52:3f344be3301b
MacOS X additions from Darrell
author | Sam Lantinga <slouken@lokigames.com> |
---|---|
date | Sun, 10 Jun 2001 05:02:38 +0000 |
parents | cf2af46e9e2a |
children | e8157fcb3114 |
rev | line source |
---|---|
0 | 1 /* |
2 SDL - Simple DirectMedia Layer | |
3 Copyright (C) 1997, 1998, 1999, 2000, 2001 Sam Lantinga | |
4 | |
5 This library is free software; you can redistribute it and/or | |
6 modify it under the terms of the GNU Library General Public | |
7 License as published by the Free Software Foundation; either | |
8 version 2 of the License, or (at your option) any later version. | |
9 | |
10 This library is distributed in the hope that it will be useful, | |
11 but WITHOUT ANY WARRANTY; without even the implied warranty of | |
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | |
13 Library General Public License for more details. | |
14 | |
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 | |
17 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | |
18 | |
19 Sam Lantinga | |
20 slouken@devolution.com | |
21 */ | |
22 | |
23 #ifdef SAVE_RCSID | |
24 static char rcsid = | |
25 "@(#) $Id$"; | |
26 #endif | |
27 | |
28 #include <support/UTF8.h> | |
29 #include <stdio.h> | |
30 #include <string.h> | |
31 #include "SDL_error.h" | |
32 #include "SDL_events.h" | |
33 #include "SDL_BWin.h" | |
34 #include "SDL_lowvideo.h" | |
35 | |
36 extern "C" { | |
37 | |
38 #include "SDL_events_c.h" | |
39 #include "SDL_sysevents.h" | |
40 #include "SDL_sysevents_c.h" | |
41 | |
42 /* A note on why the polling loops are necessary. | |
43 The BeOS Preview 2 implementation of BView->MouseMoved() only notifies | |
44 the view when the mouse enters or leaves the view. The documentation | |
45 says that you should loop and use GetMouse() to detect mouse motion. | |
46 The BeOS Preview 2 implementation of BView->KeyDown() and BView->KeyUp() | |
47 are only called for keys that generate ASCII characters. Since we want | |
48 to act like a low level raw keyboard, we need to poll the state of the | |
49 keys instead of catching the keys in callbacks. | |
50 These are documented portions of the BeBook for Preview Release 2 | |
51 */ | |
52 | |
53 /* Table to convert scancodes to SDL virtual keys */ | |
54 static SDLKey keymap[128]; | |
55 | |
56 /* Function to convert from a key scancode to a UNICODE character */ | |
57 static key_map *be_keymap; | |
58 static int32 *option_caps_map[2], *option_map[2], *caps_map[2], *normal_map[2]; | |
59 static char *unicode_map; | |
60 static Uint16 TranslateScancode(int scancode) | |
61 { | |
62 SDLMod modstate; | |
63 int shifted; | |
64 int32 index; /* Index into system unicode map */ | |
65 Uint16 unicode; | |
66 | |
67 /* Set the default character -- no character */ | |
68 unicode = 0; | |
69 | |
70 /* See whether or not the shift state is set */ | |
71 modstate = SDL_GetModState(); | |
72 if ( modstate & KMOD_SHIFT ) { | |
73 shifted = 1; | |
74 } else { | |
75 shifted = 0; | |
76 } | |
77 | |
78 if ( modstate & KMOD_NUM ) { | |
79 /* If numlock is on, numeric keypad keys have shift state inverted */ | |
80 switch (keymap[scancode]) { | |
81 case SDLK_KP0: | |
82 case SDLK_KP1: | |
83 case SDLK_KP2: | |
84 case SDLK_KP3: | |
85 case SDLK_KP4: | |
86 case SDLK_KP5: | |
87 case SDLK_KP6: | |
88 case SDLK_KP7: | |
89 case SDLK_KP8: | |
90 case SDLK_KP9: | |
91 case SDLK_KP_PERIOD: | |
92 case SDLK_KP_DIVIDE: | |
93 case SDLK_KP_MULTIPLY: | |
94 case SDLK_KP_MINUS: | |
95 case SDLK_KP_PLUS: | |
96 case SDLK_KP_ENTER: | |
97 case SDLK_KP_EQUALS: | |
98 shifted = !shifted; | |
99 break; | |
100 default: | |
101 break; | |
102 } | |
103 } | |
104 | |
105 /* Get the index based on modifier state */ | |
106 if ( modstate & KMOD_CTRL ) | |
107 index = be_keymap->control_map[scancode]; | |
108 else | |
109 if ( (modstate & KMOD_META) && (modstate & KMOD_CAPS) ) | |
110 index = option_caps_map[shifted][scancode]; | |
111 else | |
112 if ( modstate & KMOD_META ) | |
113 index = option_map[shifted][scancode]; | |
114 else | |
115 if ( modstate & KMOD_CAPS ) | |
116 index = caps_map[shifted][scancode]; | |
117 else | |
118 index = normal_map[shifted][scancode]; | |
119 | |
120 /* If there is a mapping, convert character from UTF-8 to UNICODE */ | |
121 if ( unicode_map[index] ) { | |
122 int32 state, srclen, dstlen; | |
123 unsigned char destbuf[2]; | |
124 | |
125 state = 0; | |
126 srclen = unicode_map[index++]; | |
127 dstlen = sizeof(destbuf); | |
128 convert_from_utf8(B_UNICODE_CONVERSION, | |
129 &unicode_map[index], &srclen, (char *)destbuf, &dstlen, | |
130 &state); | |
131 unicode = destbuf[0]; | |
132 unicode <<= 8; | |
133 unicode |= destbuf[1]; | |
134 | |
135 /* Keyboard input maps newline to carriage return */ | |
136 if ( unicode == '\n' ) { | |
137 unicode = '\r'; | |
138 } | |
139 | |
140 /* For some reason function keys map to control characters */ | |
141 # define CTRL(X) ((X)-'@') | |
142 switch (unicode) { | |
143 case CTRL('A'): | |
144 case CTRL('B'): | |
145 case CTRL('C'): | |
146 case CTRL('D'): | |
147 case CTRL('E'): | |
148 case CTRL('K'): | |
149 case CTRL('L'): | |
150 case CTRL('P'): | |
151 if ( ! (modstate & KMOD_CTRL) ) | |
152 unicode = 0; | |
153 break; | |
154 default: | |
155 break; | |
156 } | |
157 } | |
158 return(unicode); | |
159 } | |
160 | |
161 /* Function to translate a keyboard transition and queue the key event */ | |
162 static void QueueKey(int scancode, int pressed) | |
163 { | |
164 SDL_keysym keysym; | |
165 | |
166 /* Set the keysym information */ | |
167 keysym.scancode = scancode; | |
168 keysym.sym = keymap[scancode]; | |
169 keysym.mod = KMOD_NONE; | |
170 if ( SDL_TranslateUNICODE ) { | |
171 keysym.unicode = TranslateScancode(scancode); | |
172 } else { | |
173 keysym.unicode = 0; | |
174 } | |
175 | |
176 /* NUMLOCK and CAPSLOCK are implemented as double-presses in reality */ | |
177 if ( (keysym.sym == SDLK_NUMLOCK) || (keysym.sym == SDLK_CAPSLOCK) ) { | |
178 pressed = 1; | |
179 } | |
180 | |
181 /* Queue the key event */ | |
182 if ( pressed ) { | |
183 SDL_PrivateKeyboard(SDL_PRESSED, &keysym); | |
184 } else { | |
185 SDL_PrivateKeyboard(SDL_RELEASED, &keysym); | |
186 } | |
187 } | |
188 | |
189 /* This is special because we know it will be run in a loop in a separate | |
190 thread. Normally this function should loop as long as there are input | |
191 states changing, i.e. new events arriving. | |
192 */ | |
193 void BE_PumpEvents(_THIS) | |
194 { | |
195 BView *view; | |
196 BRect bounds; | |
197 BPoint point; | |
198 uint32 buttons; | |
199 const uint32 button_masks[3] = { | |
200 B_PRIMARY_MOUSE_BUTTON, | |
201 B_TERTIARY_MOUSE_BUTTON, | |
202 B_SECONDARY_MOUSE_BUTTON, | |
203 }; | |
204 unsigned int i, j; | |
205 | |
206 /* Check out the mouse buttons and position (slight race condition) */ | |
207 if ( SDL_Win->Lock() ) { | |
208 /* Don't do anything if we have no view */ | |
209 view = SDL_Win->View(); | |
210 if ( ! view ) { | |
211 SDL_Win->Unlock(); | |
212 return; | |
213 } | |
214 bounds = view->Bounds(); | |
215 /* Get new input state, if still active */ | |
216 if ( SDL_Win->IsActive() ) { | |
217 key_flip = !key_flip; | |
218 get_key_info(&keyinfo[key_flip]); | |
219 view->GetMouse(&point, &buttons, true); | |
220 } else { | |
221 key_flip = key_flip; | |
222 point = last_point; | |
223 buttons = last_buttons; | |
224 } | |
225 SDL_Win->Unlock(); | |
226 } else { | |
227 return; | |
228 } | |
229 | |
230 /* If our view is active, we'll find key changes here */ | |
231 if ( memcmp(keyinfo[0].key_states, keyinfo[1].key_states, 16) != 0 ) { | |
232 for ( i=0; i<16; ++i ) { | |
233 Uint8 new_state, transition; | |
234 | |
235 new_state = keyinfo[key_flip].key_states[i]; | |
236 transition = keyinfo[!key_flip].key_states[i] ^ | |
237 keyinfo[ key_flip].key_states[i]; | |
238 for ( j=0; j<8; ++j ) { | |
239 if ( transition&0x80 ) | |
240 QueueKey(i*8+j, new_state&0x80); | |
241 transition <<= 1; | |
242 new_state <<= 1; | |
243 } | |
244 } | |
245 } | |
246 | |
247 /* We check keyboard, but not mouse if mouse isn't in window */ | |
248 if ( ! bounds.Contains(point) ) { | |
249 /* Mouse moved outside our view? */ | |
250 if ( SDL_GetAppState() & SDL_APPMOUSEFOCUS ) { | |
251 SDL_PrivateAppActive(0, SDL_APPMOUSEFOCUS); | |
252 be_app->SetCursor(B_HAND_CURSOR); | |
253 } | |
254 return; | |
255 } | |
256 /* Has the mouse moved back into our view? */ | |
257 if ( ! (SDL_GetAppState() & SDL_APPMOUSEFOCUS) ) { | |
258 /* Reset the B_HAND_CURSOR to our own */ | |
259 SDL_PrivateAppActive(1, SDL_APPMOUSEFOCUS); | |
260 SDL_SetCursor(NULL); | |
261 } | |
262 | |
263 /* Check for mouse motion */ | |
264 if ( point != last_point ) { | |
1
cf2af46e9e2a
Changes since SDL 1.2.0 release
Sam Lantinga <slouken@lokigames.com>
parents:
0
diff
changeset
|
265 int x, y; |
cf2af46e9e2a
Changes since SDL 1.2.0 release
Sam Lantinga <slouken@lokigames.com>
parents:
0
diff
changeset
|
266 |
cf2af46e9e2a
Changes since SDL 1.2.0 release
Sam Lantinga <slouken@lokigames.com>
parents:
0
diff
changeset
|
267 SDL_Win->GetXYOffset(x, y); |
cf2af46e9e2a
Changes since SDL 1.2.0 release
Sam Lantinga <slouken@lokigames.com>
parents:
0
diff
changeset
|
268 x = (int)point.x - x; |
cf2af46e9e2a
Changes since SDL 1.2.0 release
Sam Lantinga <slouken@lokigames.com>
parents:
0
diff
changeset
|
269 y = (int)point.y - y; |
cf2af46e9e2a
Changes since SDL 1.2.0 release
Sam Lantinga <slouken@lokigames.com>
parents:
0
diff
changeset
|
270 SDL_PrivateMouseMotion(0, 0, x, y); |
0 | 271 } |
272 last_point = point; | |
273 | |
274 /* Add any mouse button events */ | |
275 for ( i=0; i<SDL_TABLESIZE(button_masks); ++i ) { | |
276 if ( (buttons ^ last_buttons) & button_masks[i] ) { | |
277 if ( buttons & button_masks[i] ) { | |
278 SDL_PrivateMouseButton(SDL_PRESSED, 1+i, 0, 0); | |
279 } else { | |
280 SDL_PrivateMouseButton(SDL_RELEASED, 1+i, 0, 0); | |
281 } | |
282 } | |
283 } | |
284 last_buttons = buttons; | |
285 } | |
286 | |
287 void BE_InitOSKeymap(_THIS) | |
288 { | |
289 unsigned int i; | |
290 | |
291 /* Initialize all the key states as "up" */ | |
292 key_flip = 0; | |
293 memset(keyinfo[key_flip].key_states, 0, 16); | |
294 | |
295 /* Initialize the BeOS key translation table */ | |
296 /* Source: <be/interface/InterfaceDefs.h> and BeOS keyboard info */ | |
297 for ( i=0; i<SDL_TABLESIZE(keymap); ++i ) | |
298 keymap[i] = SDLK_UNKNOWN; | |
299 | |
300 keymap[0x01] = SDLK_ESCAPE; | |
301 keymap[B_F1_KEY] = SDLK_F1; | |
302 keymap[B_F2_KEY] = SDLK_F2; | |
303 keymap[B_F3_KEY] = SDLK_F3; | |
304 keymap[B_F4_KEY] = SDLK_F4; | |
305 keymap[B_F5_KEY] = SDLK_F5; | |
306 keymap[B_F6_KEY] = SDLK_F6; | |
307 keymap[B_F7_KEY] = SDLK_F7; | |
308 keymap[B_F8_KEY] = SDLK_F8; | |
309 keymap[B_F9_KEY] = SDLK_F9; | |
310 keymap[B_F10_KEY] = SDLK_F10; | |
311 keymap[B_F11_KEY] = SDLK_F11; | |
312 keymap[B_F12_KEY] = SDLK_F12; | |
313 keymap[B_PRINT_KEY] = SDLK_PRINT; | |
314 //keymap[B_SCROLL_KEY] = SDLK_SCROLLOCK; | |
315 keymap[B_PAUSE_KEY] = SDLK_PAUSE; | |
316 keymap[0x11] = SDLK_BACKQUOTE; | |
317 keymap[0x12] = SDLK_1; | |
318 keymap[0x13] = SDLK_2; | |
319 keymap[0x14] = SDLK_3; | |
320 keymap[0x15] = SDLK_4; | |
321 keymap[0x16] = SDLK_5; | |
322 keymap[0x17] = SDLK_6; | |
323 keymap[0x18] = SDLK_7; | |
324 keymap[0x19] = SDLK_8; | |
325 keymap[0x1a] = SDLK_9; | |
326 keymap[0x1b] = SDLK_0; | |
327 keymap[0x1c] = SDLK_MINUS; | |
328 keymap[0x1d] = SDLK_EQUALS; | |
329 keymap[0x1e] = SDLK_BACKSPACE; | |
330 keymap[0x1f] = SDLK_INSERT; | |
331 keymap[0x20] = SDLK_HOME; | |
332 keymap[0x21] = SDLK_PAGEUP; | |
333 //keymap[0x22] = SDLK_NUMLOCK; | |
334 keymap[0x23] = SDLK_KP_DIVIDE; | |
335 keymap[0x24] = SDLK_KP_MULTIPLY; | |
336 keymap[0x25] = SDLK_KP_MINUS; | |
337 keymap[0x26] = SDLK_TAB; | |
338 keymap[0x27] = SDLK_q; | |
339 keymap[0x28] = SDLK_w; | |
340 keymap[0x29] = SDLK_e; | |
341 keymap[0x2a] = SDLK_r; | |
342 keymap[0x2b] = SDLK_t; | |
343 keymap[0x2c] = SDLK_y; | |
344 keymap[0x2d] = SDLK_u; | |
345 keymap[0x2e] = SDLK_i; | |
346 keymap[0x2f] = SDLK_o; | |
347 keymap[0x30] = SDLK_p; | |
348 keymap[0x31] = SDLK_LEFTBRACKET; | |
349 keymap[0x32] = SDLK_RIGHTBRACKET; | |
350 keymap[0x33] = SDLK_BACKSLASH; | |
351 keymap[0x34] = SDLK_DELETE; | |
352 keymap[0x35] = SDLK_END; | |
353 keymap[0x36] = SDLK_PAGEDOWN; | |
354 keymap[0x37] = SDLK_KP7; | |
355 keymap[0x38] = SDLK_KP8; | |
356 keymap[0x39] = SDLK_KP9; | |
357 keymap[0x3a] = SDLK_KP_PLUS; | |
358 //keymap[0x3b] = SDLK_CAPSLOCK; | |
359 keymap[0x3c] = SDLK_a; | |
360 keymap[0x3d] = SDLK_s; | |
361 keymap[0x3e] = SDLK_d; | |
362 keymap[0x3f] = SDLK_f; | |
363 keymap[0x40] = SDLK_g; | |
364 keymap[0x41] = SDLK_h; | |
365 keymap[0x42] = SDLK_j; | |
366 keymap[0x43] = SDLK_k; | |
367 keymap[0x44] = SDLK_l; | |
368 keymap[0x45] = SDLK_SEMICOLON; | |
369 keymap[0x46] = SDLK_QUOTE; | |
370 keymap[0x47] = SDLK_RETURN; | |
371 keymap[0x48] = SDLK_KP4; | |
372 keymap[0x49] = SDLK_KP5; | |
373 keymap[0x4a] = SDLK_KP6; | |
374 keymap[0x4b] = SDLK_LSHIFT; | |
375 keymap[0x4c] = SDLK_z; | |
376 keymap[0x4d] = SDLK_x; | |
377 keymap[0x4e] = SDLK_c; | |
378 keymap[0x4f] = SDLK_v; | |
379 keymap[0x50] = SDLK_b; | |
380 keymap[0x51] = SDLK_n; | |
381 keymap[0x52] = SDLK_m; | |
382 keymap[0x53] = SDLK_COMMA; | |
383 keymap[0x54] = SDLK_PERIOD; | |
384 keymap[0x55] = SDLK_SLASH; | |
385 keymap[0x56] = SDLK_RSHIFT; | |
386 keymap[0x57] = SDLK_UP; | |
387 keymap[0x58] = SDLK_KP1; | |
388 keymap[0x59] = SDLK_KP2; | |
389 keymap[0x5a] = SDLK_KP3; | |
390 keymap[0x5b] = SDLK_KP_ENTER; | |
391 //keymap[0x5c] = SDLK_LCTRL; | |
392 //keymap[0x5d] = SDLK_LALT; | |
393 keymap[0x5e] = SDLK_SPACE; | |
394 //keymap[0x5f] = SDLK_RALT; | |
395 //keymap[0x60] = SDLK_RCTRL; | |
396 keymap[0x61] = SDLK_LEFT; | |
397 keymap[0x62] = SDLK_DOWN; | |
398 keymap[0x63] = SDLK_RIGHT; | |
399 keymap[0x64] = SDLK_KP0; | |
400 keymap[0x65] = SDLK_KP_PERIOD; | |
401 //keymap[0x66] = SDLK_LMETA; | |
402 //keymap[0x67] = SDLK_RMETA; | |
403 //keymap[0x68] = SDLK_MENU; | |
404 keymap[0x69] = SDLK_EURO; | |
405 keymap[0x6a] = SDLK_KP_EQUALS; | |
406 keymap[0x6b] = SDLK_POWER; | |
407 | |
408 /* Get the system keymap and UNICODE table. | |
409 Note that this leaks memory since the maps are never freed. | |
410 */ | |
411 get_key_map(&be_keymap, &unicode_map); | |
412 | |
413 /* Set the modifier keys from the system keymap */ | |
414 keymap[be_keymap->caps_key] = SDLK_CAPSLOCK; | |
415 keymap[be_keymap->scroll_key] = SDLK_SCROLLOCK; | |
416 keymap[be_keymap->num_key] = SDLK_NUMLOCK; | |
417 keymap[be_keymap->left_shift_key] = SDLK_LSHIFT; | |
418 keymap[be_keymap->right_shift_key] = SDLK_RSHIFT; | |
419 keymap[be_keymap->left_command_key] = SDLK_LALT; | |
420 keymap[be_keymap->right_command_key] = SDLK_RALT; | |
421 keymap[be_keymap->left_control_key] = SDLK_LCTRL; | |
422 keymap[be_keymap->right_control_key] = SDLK_RCTRL; | |
423 keymap[be_keymap->left_option_key] = SDLK_LMETA; | |
424 keymap[be_keymap->right_option_key] = SDLK_RMETA; | |
425 keymap[be_keymap->menu_key] = SDLK_MENU; | |
426 | |
427 /* Set the modifier map pointers */ | |
428 option_caps_map[0] = be_keymap->option_caps_map; | |
429 option_caps_map[1] = be_keymap->option_caps_shift_map; | |
430 option_map[0] = be_keymap->option_map; | |
431 option_map[1] = be_keymap->option_shift_map; | |
432 caps_map[0] = be_keymap->caps_map; | |
433 caps_map[1] = be_keymap->caps_shift_map; | |
434 normal_map[0] = be_keymap->normal_map; | |
435 normal_map[1] = be_keymap->shift_map; | |
436 } | |
437 | |
438 }; /* Extern C */ |