comparison src/video/bwindow/SDL_sysevents.cc @ 907:3bd4d7a1ee04

Date: Mon, 21 Jun 2004 16:52:47 +0200 From: Marcin Konicki Subject: SDL 1.2.7 patch for BeOS (new input handling code) I rewrote input handling code for BeOS. It should be faster now (i got report that mouse is faster, keyboard should be too, but it's harder to observe). I'll try to add mouse wheel support too, soon. Stefano Ceccherini (a.k.a Jack Burton) helped me beautify code (working version was less clean), and it was he who asked me to write this thing ;).
author Sam Lantinga <slouken@libsdl.org>
date Sun, 18 Jul 2004 19:36:06 +0000
parents b8d311d90021
children c9b51268668f
comparison
equal deleted inserted replaced
906:a48acf6ee48f 907:3bd4d7a1ee04
37 37
38 #include "SDL_events_c.h" 38 #include "SDL_events_c.h"
39 #include "SDL_sysevents.h" 39 #include "SDL_sysevents.h"
40 #include "SDL_sysevents_c.h" 40 #include "SDL_sysevents_c.h"
41 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) 42 void BE_PumpEvents(_THIS)
194 { 43 {
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 int x, y;
266
267 SDL_Win->GetXYOffset(x, y);
268 x = (int)point.x - x;
269 y = (int)point.y - y;
270 SDL_PrivateMouseMotion(0, 0, x, y);
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 } 44 }
286 45
287 void BE_InitOSKeymap(_THIS) 46 void BE_InitOSKeymap(_THIS)
288 { 47 {
289 unsigned int i;
290
291 /* Initialize the keyboard state */
292 key_flip = 0;
293 get_key_info(&keyinfo[key_flip]);
294 memcpy(keyinfo[!key_flip].key_states,
295 keyinfo[key_flip].key_states,
296 SDL_TABLESIZE(keyinfo[key_flip].key_states));
297
298 /* Initialize the BeOS key translation table */
299 /* Source: <be/interface/InterfaceDefs.h> and BeOS keyboard info */
300 for ( i=0; i<SDL_TABLESIZE(keymap); ++i )
301 keymap[i] = SDLK_UNKNOWN;
302
303 keymap[0x01] = SDLK_ESCAPE;
304 keymap[B_F1_KEY] = SDLK_F1;
305 keymap[B_F2_KEY] = SDLK_F2;
306 keymap[B_F3_KEY] = SDLK_F3;
307 keymap[B_F4_KEY] = SDLK_F4;
308 keymap[B_F5_KEY] = SDLK_F5;
309 keymap[B_F6_KEY] = SDLK_F6;
310 keymap[B_F7_KEY] = SDLK_F7;
311 keymap[B_F8_KEY] = SDLK_F8;
312 keymap[B_F9_KEY] = SDLK_F9;
313 keymap[B_F10_KEY] = SDLK_F10;
314 keymap[B_F11_KEY] = SDLK_F11;
315 keymap[B_F12_KEY] = SDLK_F12;
316 keymap[B_PRINT_KEY] = SDLK_PRINT;
317 //keymap[B_SCROLL_KEY] = SDLK_SCROLLOCK;
318 keymap[B_PAUSE_KEY] = SDLK_PAUSE;
319 keymap[0x11] = SDLK_BACKQUOTE;
320 keymap[0x12] = SDLK_1;
321 keymap[0x13] = SDLK_2;
322 keymap[0x14] = SDLK_3;
323 keymap[0x15] = SDLK_4;
324 keymap[0x16] = SDLK_5;
325 keymap[0x17] = SDLK_6;
326 keymap[0x18] = SDLK_7;
327 keymap[0x19] = SDLK_8;
328 keymap[0x1a] = SDLK_9;
329 keymap[0x1b] = SDLK_0;
330 keymap[0x1c] = SDLK_MINUS;
331 keymap[0x1d] = SDLK_EQUALS;
332 keymap[0x1e] = SDLK_BACKSPACE;
333 keymap[0x1f] = SDLK_INSERT;
334 keymap[0x20] = SDLK_HOME;
335 keymap[0x21] = SDLK_PAGEUP;
336 //keymap[0x22] = SDLK_NUMLOCK;
337 keymap[0x23] = SDLK_KP_DIVIDE;
338 keymap[0x24] = SDLK_KP_MULTIPLY;
339 keymap[0x25] = SDLK_KP_MINUS;
340 keymap[0x26] = SDLK_TAB;
341 keymap[0x27] = SDLK_q;
342 keymap[0x28] = SDLK_w;
343 keymap[0x29] = SDLK_e;
344 keymap[0x2a] = SDLK_r;
345 keymap[0x2b] = SDLK_t;
346 keymap[0x2c] = SDLK_y;
347 keymap[0x2d] = SDLK_u;
348 keymap[0x2e] = SDLK_i;
349 keymap[0x2f] = SDLK_o;
350 keymap[0x30] = SDLK_p;
351 keymap[0x31] = SDLK_LEFTBRACKET;
352 keymap[0x32] = SDLK_RIGHTBRACKET;
353 keymap[0x33] = SDLK_BACKSLASH;
354 keymap[0x34] = SDLK_DELETE;
355 keymap[0x35] = SDLK_END;
356 keymap[0x36] = SDLK_PAGEDOWN;
357 keymap[0x37] = SDLK_KP7;
358 keymap[0x38] = SDLK_KP8;
359 keymap[0x39] = SDLK_KP9;
360 keymap[0x3a] = SDLK_KP_PLUS;
361 //keymap[0x3b] = SDLK_CAPSLOCK;
362 keymap[0x3c] = SDLK_a;
363 keymap[0x3d] = SDLK_s;
364 keymap[0x3e] = SDLK_d;
365 keymap[0x3f] = SDLK_f;
366 keymap[0x40] = SDLK_g;
367 keymap[0x41] = SDLK_h;
368 keymap[0x42] = SDLK_j;
369 keymap[0x43] = SDLK_k;
370 keymap[0x44] = SDLK_l;
371 keymap[0x45] = SDLK_SEMICOLON;
372 keymap[0x46] = SDLK_QUOTE;
373 keymap[0x47] = SDLK_RETURN;
374 keymap[0x48] = SDLK_KP4;
375 keymap[0x49] = SDLK_KP5;
376 keymap[0x4a] = SDLK_KP6;
377 keymap[0x4b] = SDLK_LSHIFT;
378 keymap[0x4c] = SDLK_z;
379 keymap[0x4d] = SDLK_x;
380 keymap[0x4e] = SDLK_c;
381 keymap[0x4f] = SDLK_v;
382 keymap[0x50] = SDLK_b;
383 keymap[0x51] = SDLK_n;
384 keymap[0x52] = SDLK_m;
385 keymap[0x53] = SDLK_COMMA;
386 keymap[0x54] = SDLK_PERIOD;
387 keymap[0x55] = SDLK_SLASH;
388 keymap[0x56] = SDLK_RSHIFT;
389 keymap[0x57] = SDLK_UP;
390 keymap[0x58] = SDLK_KP1;
391 keymap[0x59] = SDLK_KP2;
392 keymap[0x5a] = SDLK_KP3;
393 keymap[0x5b] = SDLK_KP_ENTER;
394 //keymap[0x5c] = SDLK_LCTRL;
395 //keymap[0x5d] = SDLK_LALT;
396 keymap[0x5e] = SDLK_SPACE;
397 //keymap[0x5f] = SDLK_RALT;
398 //keymap[0x60] = SDLK_RCTRL;
399 keymap[0x61] = SDLK_LEFT;
400 keymap[0x62] = SDLK_DOWN;
401 keymap[0x63] = SDLK_RIGHT;
402 keymap[0x64] = SDLK_KP0;
403 keymap[0x65] = SDLK_KP_PERIOD;
404 //keymap[0x66] = SDLK_LMETA;
405 //keymap[0x67] = SDLK_RMETA;
406 //keymap[0x68] = SDLK_MENU;
407 keymap[0x69] = SDLK_EURO;
408 keymap[0x6a] = SDLK_KP_EQUALS;
409 keymap[0x6b] = SDLK_POWER;
410
411 /* Get the system keymap and UNICODE table.
412 Note that this leaks memory since the maps are never freed.
413 */
414 get_key_map(&be_keymap, &unicode_map);
415
416 /* Set the modifier keys from the system keymap */
417 keymap[be_keymap->caps_key] = SDLK_CAPSLOCK;
418 keymap[be_keymap->scroll_key] = SDLK_SCROLLOCK;
419 keymap[be_keymap->num_key] = SDLK_NUMLOCK;
420 keymap[be_keymap->left_shift_key] = SDLK_LSHIFT;
421 keymap[be_keymap->right_shift_key] = SDLK_RSHIFT;
422 keymap[be_keymap->left_command_key] = SDLK_LALT;
423 keymap[be_keymap->right_command_key] = SDLK_RALT;
424 keymap[be_keymap->left_control_key] = SDLK_LCTRL;
425 keymap[be_keymap->right_control_key] = SDLK_RCTRL;
426 keymap[be_keymap->left_option_key] = SDLK_LMETA;
427 keymap[be_keymap->right_option_key] = SDLK_RMETA;
428 keymap[be_keymap->menu_key] = SDLK_MENU;
429
430 /* Set the modifier map pointers */
431 option_caps_map[0] = be_keymap->option_caps_map;
432 option_caps_map[1] = be_keymap->option_caps_shift_map;
433 option_map[0] = be_keymap->option_map;
434 option_map[1] = be_keymap->option_shift_map;
435 caps_map[0] = be_keymap->caps_map;
436 caps_map[1] = be_keymap->caps_shift_map;
437 normal_map[0] = be_keymap->normal_map;
438 normal_map[1] = be_keymap->shift_map;
439 } 48 }
440 49
441 }; /* Extern C */ 50 }; /* Extern C */