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