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 ) {
|
|
265 SDL_PrivateMouseMotion(0, 0, (int)point.x, (int)point.y);
|
|
266 }
|
|
267 last_point = point;
|
|
268
|
|
269 /* Add any mouse button events */
|
|
270 for ( i=0; i<SDL_TABLESIZE(button_masks); ++i ) {
|
|
271 if ( (buttons ^ last_buttons) & button_masks[i] ) {
|
|
272 if ( buttons & button_masks[i] ) {
|
|
273 SDL_PrivateMouseButton(SDL_PRESSED, 1+i, 0, 0);
|
|
274 } else {
|
|
275 SDL_PrivateMouseButton(SDL_RELEASED, 1+i, 0, 0);
|
|
276 }
|
|
277 }
|
|
278 }
|
|
279 last_buttons = buttons;
|
|
280 }
|
|
281
|
|
282 void BE_InitOSKeymap(_THIS)
|
|
283 {
|
|
284 unsigned int i;
|
|
285
|
|
286 /* Initialize all the key states as "up" */
|
|
287 key_flip = 0;
|
|
288 memset(keyinfo[key_flip].key_states, 0, 16);
|
|
289
|
|
290 /* Initialize the BeOS key translation table */
|
|
291 /* Source: <be/interface/InterfaceDefs.h> and BeOS keyboard info */
|
|
292 for ( i=0; i<SDL_TABLESIZE(keymap); ++i )
|
|
293 keymap[i] = SDLK_UNKNOWN;
|
|
294
|
|
295 keymap[0x01] = SDLK_ESCAPE;
|
|
296 keymap[B_F1_KEY] = SDLK_F1;
|
|
297 keymap[B_F2_KEY] = SDLK_F2;
|
|
298 keymap[B_F3_KEY] = SDLK_F3;
|
|
299 keymap[B_F4_KEY] = SDLK_F4;
|
|
300 keymap[B_F5_KEY] = SDLK_F5;
|
|
301 keymap[B_F6_KEY] = SDLK_F6;
|
|
302 keymap[B_F7_KEY] = SDLK_F7;
|
|
303 keymap[B_F8_KEY] = SDLK_F8;
|
|
304 keymap[B_F9_KEY] = SDLK_F9;
|
|
305 keymap[B_F10_KEY] = SDLK_F10;
|
|
306 keymap[B_F11_KEY] = SDLK_F11;
|
|
307 keymap[B_F12_KEY] = SDLK_F12;
|
|
308 keymap[B_PRINT_KEY] = SDLK_PRINT;
|
|
309 //keymap[B_SCROLL_KEY] = SDLK_SCROLLOCK;
|
|
310 keymap[B_PAUSE_KEY] = SDLK_PAUSE;
|
|
311 keymap[0x11] = SDLK_BACKQUOTE;
|
|
312 keymap[0x12] = SDLK_1;
|
|
313 keymap[0x13] = SDLK_2;
|
|
314 keymap[0x14] = SDLK_3;
|
|
315 keymap[0x15] = SDLK_4;
|
|
316 keymap[0x16] = SDLK_5;
|
|
317 keymap[0x17] = SDLK_6;
|
|
318 keymap[0x18] = SDLK_7;
|
|
319 keymap[0x19] = SDLK_8;
|
|
320 keymap[0x1a] = SDLK_9;
|
|
321 keymap[0x1b] = SDLK_0;
|
|
322 keymap[0x1c] = SDLK_MINUS;
|
|
323 keymap[0x1d] = SDLK_EQUALS;
|
|
324 keymap[0x1e] = SDLK_BACKSPACE;
|
|
325 keymap[0x1f] = SDLK_INSERT;
|
|
326 keymap[0x20] = SDLK_HOME;
|
|
327 keymap[0x21] = SDLK_PAGEUP;
|
|
328 //keymap[0x22] = SDLK_NUMLOCK;
|
|
329 keymap[0x23] = SDLK_KP_DIVIDE;
|
|
330 keymap[0x24] = SDLK_KP_MULTIPLY;
|
|
331 keymap[0x25] = SDLK_KP_MINUS;
|
|
332 keymap[0x26] = SDLK_TAB;
|
|
333 keymap[0x27] = SDLK_q;
|
|
334 keymap[0x28] = SDLK_w;
|
|
335 keymap[0x29] = SDLK_e;
|
|
336 keymap[0x2a] = SDLK_r;
|
|
337 keymap[0x2b] = SDLK_t;
|
|
338 keymap[0x2c] = SDLK_y;
|
|
339 keymap[0x2d] = SDLK_u;
|
|
340 keymap[0x2e] = SDLK_i;
|
|
341 keymap[0x2f] = SDLK_o;
|
|
342 keymap[0x30] = SDLK_p;
|
|
343 keymap[0x31] = SDLK_LEFTBRACKET;
|
|
344 keymap[0x32] = SDLK_RIGHTBRACKET;
|
|
345 keymap[0x33] = SDLK_BACKSLASH;
|
|
346 keymap[0x34] = SDLK_DELETE;
|
|
347 keymap[0x35] = SDLK_END;
|
|
348 keymap[0x36] = SDLK_PAGEDOWN;
|
|
349 keymap[0x37] = SDLK_KP7;
|
|
350 keymap[0x38] = SDLK_KP8;
|
|
351 keymap[0x39] = SDLK_KP9;
|
|
352 keymap[0x3a] = SDLK_KP_PLUS;
|
|
353 //keymap[0x3b] = SDLK_CAPSLOCK;
|
|
354 keymap[0x3c] = SDLK_a;
|
|
355 keymap[0x3d] = SDLK_s;
|
|
356 keymap[0x3e] = SDLK_d;
|
|
357 keymap[0x3f] = SDLK_f;
|
|
358 keymap[0x40] = SDLK_g;
|
|
359 keymap[0x41] = SDLK_h;
|
|
360 keymap[0x42] = SDLK_j;
|
|
361 keymap[0x43] = SDLK_k;
|
|
362 keymap[0x44] = SDLK_l;
|
|
363 keymap[0x45] = SDLK_SEMICOLON;
|
|
364 keymap[0x46] = SDLK_QUOTE;
|
|
365 keymap[0x47] = SDLK_RETURN;
|
|
366 keymap[0x48] = SDLK_KP4;
|
|
367 keymap[0x49] = SDLK_KP5;
|
|
368 keymap[0x4a] = SDLK_KP6;
|
|
369 keymap[0x4b] = SDLK_LSHIFT;
|
|
370 keymap[0x4c] = SDLK_z;
|
|
371 keymap[0x4d] = SDLK_x;
|
|
372 keymap[0x4e] = SDLK_c;
|
|
373 keymap[0x4f] = SDLK_v;
|
|
374 keymap[0x50] = SDLK_b;
|
|
375 keymap[0x51] = SDLK_n;
|
|
376 keymap[0x52] = SDLK_m;
|
|
377 keymap[0x53] = SDLK_COMMA;
|
|
378 keymap[0x54] = SDLK_PERIOD;
|
|
379 keymap[0x55] = SDLK_SLASH;
|
|
380 keymap[0x56] = SDLK_RSHIFT;
|
|
381 keymap[0x57] = SDLK_UP;
|
|
382 keymap[0x58] = SDLK_KP1;
|
|
383 keymap[0x59] = SDLK_KP2;
|
|
384 keymap[0x5a] = SDLK_KP3;
|
|
385 keymap[0x5b] = SDLK_KP_ENTER;
|
|
386 //keymap[0x5c] = SDLK_LCTRL;
|
|
387 //keymap[0x5d] = SDLK_LALT;
|
|
388 keymap[0x5e] = SDLK_SPACE;
|
|
389 //keymap[0x5f] = SDLK_RALT;
|
|
390 //keymap[0x60] = SDLK_RCTRL;
|
|
391 keymap[0x61] = SDLK_LEFT;
|
|
392 keymap[0x62] = SDLK_DOWN;
|
|
393 keymap[0x63] = SDLK_RIGHT;
|
|
394 keymap[0x64] = SDLK_KP0;
|
|
395 keymap[0x65] = SDLK_KP_PERIOD;
|
|
396 //keymap[0x66] = SDLK_LMETA;
|
|
397 //keymap[0x67] = SDLK_RMETA;
|
|
398 //keymap[0x68] = SDLK_MENU;
|
|
399 keymap[0x69] = SDLK_EURO;
|
|
400 keymap[0x6a] = SDLK_KP_EQUALS;
|
|
401 keymap[0x6b] = SDLK_POWER;
|
|
402
|
|
403 /* Get the system keymap and UNICODE table.
|
|
404 Note that this leaks memory since the maps are never freed.
|
|
405 */
|
|
406 get_key_map(&be_keymap, &unicode_map);
|
|
407
|
|
408 /* Set the modifier keys from the system keymap */
|
|
409 keymap[be_keymap->caps_key] = SDLK_CAPSLOCK;
|
|
410 keymap[be_keymap->scroll_key] = SDLK_SCROLLOCK;
|
|
411 keymap[be_keymap->num_key] = SDLK_NUMLOCK;
|
|
412 keymap[be_keymap->left_shift_key] = SDLK_LSHIFT;
|
|
413 keymap[be_keymap->right_shift_key] = SDLK_RSHIFT;
|
|
414 keymap[be_keymap->left_command_key] = SDLK_LALT;
|
|
415 keymap[be_keymap->right_command_key] = SDLK_RALT;
|
|
416 keymap[be_keymap->left_control_key] = SDLK_LCTRL;
|
|
417 keymap[be_keymap->right_control_key] = SDLK_RCTRL;
|
|
418 keymap[be_keymap->left_option_key] = SDLK_LMETA;
|
|
419 keymap[be_keymap->right_option_key] = SDLK_RMETA;
|
|
420 keymap[be_keymap->menu_key] = SDLK_MENU;
|
|
421
|
|
422 /* Set the modifier map pointers */
|
|
423 option_caps_map[0] = be_keymap->option_caps_map;
|
|
424 option_caps_map[1] = be_keymap->option_caps_shift_map;
|
|
425 option_map[0] = be_keymap->option_map;
|
|
426 option_map[1] = be_keymap->option_shift_map;
|
|
427 caps_map[0] = be_keymap->caps_map;
|
|
428 caps_map[1] = be_keymap->caps_shift_map;
|
|
429 normal_map[0] = be_keymap->normal_map;
|
|
430 normal_map[1] = be_keymap->shift_map;
|
|
431 }
|
|
432
|
|
433 }; /* Extern C */
|