comparison src/video/bwindow/SDL_sysevents.cc @ 0:74212992fb08

Initial revision
author Sam Lantinga <slouken@lokigames.com>
date Thu, 26 Apr 2001 16:45:43 +0000
parents
children cf2af46e9e2a
comparison
equal deleted inserted replaced
-1:000000000000 0:74212992fb08
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 */