comparison src/video/bwindow/SDL_BWin.h @ 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 a48acf6ee48f
children a649064a3215
comparison
equal deleted inserted replaced
906:a48acf6ee48f 907:3bd4d7a1ee04
33 #include <InterfaceKit.h> 33 #include <InterfaceKit.h>
34 #include <be/game/DirectWindow.h> 34 #include <be/game/DirectWindow.h>
35 #ifdef HAVE_OPENGL 35 #ifdef HAVE_OPENGL
36 #include <be/opengl/GLView.h> 36 #include <be/opengl/GLView.h>
37 #endif 37 #endif
38 #include <support/UTF8.h>
38 39
39 #include "SDL_BeApp.h" 40 #include "SDL_BeApp.h"
40 #include "SDL_events.h" 41 #include "SDL_events.h"
41 #include "SDL_BView.h" 42 #include "SDL_BView.h"
42 43
47 class SDL_BWin : public BDirectWindow 48 class SDL_BWin : public BDirectWindow
48 { 49 {
49 public: 50 public:
50 SDL_BWin(BRect bounds) : 51 SDL_BWin(BRect bounds) :
51 BDirectWindow(bounds, "Untitled", B_TITLED_WINDOW, 0) { 52 BDirectWindow(bounds, "Untitled", B_TITLED_WINDOW, 0) {
53 InitKeyboard();
54 last_buttons = 0;
55
52 the_view = NULL; 56 the_view = NULL;
53 #ifdef HAVE_OPENGL 57 #ifdef HAVE_OPENGL
54 SDL_GLView = NULL; 58 SDL_GLView = NULL;
55 #endif 59 #endif
56 SDL_View = NULL; 60 SDL_View = NULL;
57 Unlock(); 61 Unlock();
58 shown = false; 62 shown = false;
59 inhibit_resize = false; 63 inhibit_resize = false;
60 } 64 }
65
61 virtual ~SDL_BWin() { 66 virtual ~SDL_BWin() {
62 Lock(); 67 Lock();
63 if ( the_view ) { 68 if ( the_view ) {
64 #ifdef HAVE_OPENGL 69 #ifdef HAVE_OPENGL
65 if ( the_view == SDL_GLView ) { 70 if ( the_view == SDL_GLView ) {
76 } 81 }
77 #endif 82 #endif
78 if ( SDL_View ) { 83 if ( SDL_View ) {
79 delete SDL_View; 84 delete SDL_View;
80 } 85 }
86 }
87
88 virtual void InitKeyboard(void) {
89 for ( uint i=0; i<SDL_TABLESIZE(keymap); ++i )
90 keymap[i] = SDLK_UNKNOWN;
91
92 keymap[0x01] = SDLK_ESCAPE;
93 keymap[B_F1_KEY] = SDLK_F1;
94 keymap[B_F2_KEY] = SDLK_F2;
95 keymap[B_F3_KEY] = SDLK_F3;
96 keymap[B_F4_KEY] = SDLK_F4;
97 keymap[B_F5_KEY] = SDLK_F5;
98 keymap[B_F6_KEY] = SDLK_F6;
99 keymap[B_F7_KEY] = SDLK_F7;
100 keymap[B_F8_KEY] = SDLK_F8;
101 keymap[B_F9_KEY] = SDLK_F9;
102 keymap[B_F10_KEY] = SDLK_F10;
103 keymap[B_F11_KEY] = SDLK_F11;
104 keymap[B_F12_KEY] = SDLK_F12;
105 keymap[B_PRINT_KEY] = SDLK_PRINT;
106 keymap[B_SCROLL_KEY] = SDLK_SCROLLOCK;
107 keymap[B_PAUSE_KEY] = SDLK_PAUSE;
108 keymap[0x11] = SDLK_BACKQUOTE;
109 keymap[0x12] = SDLK_1;
110 keymap[0x13] = SDLK_2;
111 keymap[0x14] = SDLK_3;
112 keymap[0x15] = SDLK_4;
113 keymap[0x16] = SDLK_5;
114 keymap[0x17] = SDLK_6;
115 keymap[0x18] = SDLK_7;
116 keymap[0x19] = SDLK_8;
117 keymap[0x1a] = SDLK_9;
118 keymap[0x1b] = SDLK_0;
119 keymap[0x1c] = SDLK_MINUS;
120 keymap[0x1d] = SDLK_EQUALS;
121 keymap[0x1e] = SDLK_BACKSPACE;
122 keymap[0x1f] = SDLK_INSERT;
123 keymap[0x20] = SDLK_HOME;
124 keymap[0x21] = SDLK_PAGEUP;
125 keymap[0x22] = SDLK_NUMLOCK;
126 keymap[0x23] = SDLK_KP_DIVIDE;
127 keymap[0x24] = SDLK_KP_MULTIPLY;
128 keymap[0x25] = SDLK_KP_MINUS;
129 keymap[0x26] = SDLK_TAB;
130 keymap[0x27] = SDLK_q;
131 keymap[0x28] = SDLK_w;
132 keymap[0x29] = SDLK_e;
133 keymap[0x2a] = SDLK_r;
134 keymap[0x2b] = SDLK_t;
135 keymap[0x2c] = SDLK_y;
136 keymap[0x2d] = SDLK_u;
137 keymap[0x2e] = SDLK_i;
138 keymap[0x2f] = SDLK_o;
139 keymap[0x30] = SDLK_p;
140 keymap[0x31] = SDLK_LEFTBRACKET;
141 keymap[0x32] = SDLK_RIGHTBRACKET;
142 keymap[0x33] = SDLK_BACKSLASH;
143 keymap[0x34] = SDLK_DELETE;
144 keymap[0x35] = SDLK_END;
145 keymap[0x36] = SDLK_PAGEDOWN;
146 keymap[0x37] = SDLK_KP7;
147 keymap[0x38] = SDLK_KP8;
148 keymap[0x39] = SDLK_KP9;
149 keymap[0x3a] = SDLK_KP_PLUS;
150 keymap[0x3b] = SDLK_CAPSLOCK;
151 keymap[0x3c] = SDLK_a;
152 keymap[0x3d] = SDLK_s;
153 keymap[0x3e] = SDLK_d;
154 keymap[0x3f] = SDLK_f;
155 keymap[0x40] = SDLK_g;
156 keymap[0x41] = SDLK_h;
157 keymap[0x42] = SDLK_j;
158 keymap[0x43] = SDLK_k;
159 keymap[0x44] = SDLK_l;
160 keymap[0x45] = SDLK_SEMICOLON;
161 keymap[0x46] = SDLK_QUOTE;
162 keymap[0x47] = SDLK_RETURN;
163 keymap[0x48] = SDLK_KP4;
164 keymap[0x49] = SDLK_KP5;
165 keymap[0x4a] = SDLK_KP6;
166 keymap[0x4b] = SDLK_LSHIFT;
167 keymap[0x4c] = SDLK_z;
168 keymap[0x4d] = SDLK_x;
169 keymap[0x4e] = SDLK_c;
170 keymap[0x4f] = SDLK_v;
171 keymap[0x50] = SDLK_b;
172 keymap[0x51] = SDLK_n;
173 keymap[0x52] = SDLK_m;
174 keymap[0x53] = SDLK_COMMA;
175 keymap[0x54] = SDLK_PERIOD;
176 keymap[0x55] = SDLK_SLASH;
177 keymap[0x56] = SDLK_RSHIFT;
178 keymap[0x57] = SDLK_UP;
179 keymap[0x58] = SDLK_KP1;
180 keymap[0x59] = SDLK_KP2;
181 keymap[0x5a] = SDLK_KP3;
182 keymap[0x5b] = SDLK_KP_ENTER;
183 keymap[0x5c] = SDLK_LCTRL;
184 keymap[0x5d] = SDLK_LALT;
185 keymap[0x5e] = SDLK_SPACE;
186 keymap[0x5f] = SDLK_RALT;
187 keymap[0x60] = SDLK_RCTRL;
188 keymap[0x61] = SDLK_LEFT;
189 keymap[0x62] = SDLK_DOWN;
190 keymap[0x63] = SDLK_RIGHT;
191 keymap[0x64] = SDLK_KP0;
192 keymap[0x65] = SDLK_KP_PERIOD;
193 keymap[0x66] = SDLK_LMETA;
194 keymap[0x67] = SDLK_RMETA;
195 keymap[0x68] = SDLK_MENU;
196 keymap[0x69] = SDLK_EURO;
197 keymap[0x6a] = SDLK_KP_EQUALS;
198 keymap[0x6b] = SDLK_POWER;
81 } 199 }
82 200
83 /* Override the Show() method so we can tell when we've been shown */ 201 /* Override the Show() method so we can tell when we've been shown */
84 virtual void Show(void) { 202 virtual void Show(void) {
85 BWindow::Show(); 203 BWindow::Show();
209 if (!IsLocked()) 327 if (!IsLocked())
210 Lock(); 328 Lock();
211 BDirectWindow::Quit(); 329 BDirectWindow::Quit();
212 } 330 }
213 331
332 virtual int16 Translate2Unicode(const char *buf) {
333 int32 state, srclen, dstlen;
334 unsigned char destbuf[2];
335 Uint16 unicode = 0;
336
337 if ((uchar)buf[0] > 127) {
338 state = 0;
339 srclen = strlen(buf);
340 dstlen = sizeof(destbuf);
341 convert_from_utf8(B_UNICODE_CONVERSION, buf, &srclen, (char *)destbuf, &dstlen, &state);
342 unicode = destbuf[0];
343 unicode <<= 8;
344 unicode |= destbuf[1];
345 } else
346 unicode = buf[0];
347
348 /* For some reason function keys map to control characters */
349 # define CTRL(X) ((X)-'@')
350 switch (unicode) {
351 case CTRL('A'):
352 case CTRL('B'):
353 case CTRL('C'):
354 case CTRL('D'):
355 case CTRL('E'):
356 case CTRL('K'):
357 case CTRL('L'):
358 case CTRL('P'):
359 if ( ! (SDL_GetModState() & KMOD_CTRL) )
360 unicode = 0;
361 break;
362 /* Keyboard input maps newline to carriage return */
363 case '\n':
364 unicode = '\r';
365 break;
366 default:
367 break;
368 }
369
370 return unicode;
371 }
372
373 virtual void DispatchMessage(BMessage *msg, BHandler *target) {
374 switch (msg->what) {
375 case B_MOUSE_MOVED:
376 {
377 BPoint where;
378 int32 transit;
379 if (msg->FindPoint("where", &where) == B_OK && msg->FindInt32("be:transit", &transit) == B_OK) {
380 if (transit == B_EXITED_VIEW) {
381 if ( SDL_GetAppState() & SDL_APPMOUSEFOCUS ) {
382 SDL_PrivateAppActive(0, SDL_APPMOUSEFOCUS);
383 be_app->SetCursor(B_HAND_CURSOR);
384 }
385 } else {
386 int x, y;
387 if ( ! (SDL_GetAppState() & SDL_APPMOUSEFOCUS) ) {
388 SDL_PrivateAppActive(1, SDL_APPMOUSEFOCUS);
389 SDL_SetCursor(NULL);
390 }
391 GetXYOffset(x, y);
392 x = (int)where.x - x;
393 y = (int)where.y - y;
394 SDL_PrivateMouseMotion(0, 0, x, y);
395 }
396 }
397 break;
398 }
399
400 case B_MOUSE_DOWN:
401 {
402 /* it looks like mouse down is send only for first clicked
403 button, each next is not send while last one is holded */
404 int32 buttons;
405 int sdl_buttons = 0;
406 if (msg->FindInt32("buttons", &buttons) == B_OK) {
407 /* Add any mouse button events */
408 if (buttons & B_PRIMARY_MOUSE_BUTTON) {
409 sdl_buttons |= SDL_BUTTON_LEFT;
410 }
411 if (buttons & B_SECONDARY_MOUSE_BUTTON) {
412 sdl_buttons |= SDL_BUTTON_RIGHT;
413 }
414 if (buttons & B_TERTIARY_MOUSE_BUTTON) {
415 sdl_buttons |= SDL_BUTTON_MIDDLE;
416 }
417 SDL_PrivateMouseButton(SDL_PRESSED, sdl_buttons, 0, 0);
418
419 last_buttons = buttons;
420 }
421 break;
422 }
423
424 case B_MOUSE_UP:
425 {
426 /* mouse up doesn't give which button was released,
427 only state of buttons (after release, so it's always = 0),
428 which is is not what we need ;]
429 So we need to store button in mouse down, and restore
430 in mouse up :(
431 mouse up is (similarly to mouse down) send only when
432 no more buttons are down */
433 int32 buttons;
434 int sdl_buttons = 0;
435 if (msg->FindInt32("buttons", &buttons) == B_OK) {
436 /* Add any mouse button events */
437 if ((buttons ^ B_PRIMARY_MOUSE_BUTTON) & last_buttons) {
438 sdl_buttons |= SDL_BUTTON_LEFT;
439 }
440 if ((buttons ^ B_SECONDARY_MOUSE_BUTTON) & last_buttons) {
441 sdl_buttons |= SDL_BUTTON_RIGHT;
442 }
443 if ((buttons ^ B_TERTIARY_MOUSE_BUTTON) & last_buttons) {
444 sdl_buttons |= SDL_BUTTON_MIDDLE;
445 }
446 SDL_PrivateMouseButton(SDL_RELEASED, sdl_buttons, 0, 0);
447
448 last_buttons = buttons;
449 }
450 break;
451 }
452
453 case B_MOUSE_WHEEL_CHANGED:
454 {
455 float x, y;
456 x = y = 0;
457 if (msg->FindFloat("be:wheel_delta_x", &x) == B_OK && msg->FindFloat("be:wheel_delta_y", &y) == B_OK) {
458 if (x < 0 || y < 0) {
459 SDL_PrivateMouseButton(SDL_PRESSED, SDL_BUTTON_WHEELDOWN, 0, 0);
460 SDL_PrivateMouseButton(SDL_RELEASED, SDL_BUTTON_WHEELDOWN, 0, 0);
461 } else if (x > 0 || y > 0) {
462 SDL_PrivateMouseButton(SDL_PRESSED, SDL_BUTTON_WHEELUP, 0, 0);
463 SDL_PrivateMouseButton(SDL_RELEASED, SDL_BUTTON_WHEELUP, 0, 0);
464 }
465 }
466 break;
467 }
468
469 case B_KEY_DOWN:
470 case B_UNMAPPED_KEY_DOWN: /* modifier keys are unmapped */
471 {
472 int32 key;
473 int32 modifiers;
474 if (msg->FindInt32("key", &key) == B_OK && msg->FindInt32("modifiers", &modifiers) == B_OK) {
475 SDL_keysym keysym;
476 keysym.scancode = key;
477 if (key < 128) {
478 keysym.sym = keymap[key];
479 } else {
480 keysym.sym = SDLK_UNKNOWN;
481 }
482 /* FIX THIS?
483 it seems SDL_PrivateKeyboard() changes mod value
484 anyway, and doesn't care about what we setup here */
485 keysym.mod = KMOD_NONE;
486 keysym.unicode = 0;
487 if (SDL_TranslateUNICODE) {
488 const char *bytes;
489 if (msg->FindString("bytes", &bytes) == B_OK) {
490 /* FIX THIS?
491 this cares only about first "letter",
492 so if someone maps some key to print
493 "BeOS rulez!" only "B" will be used. */
494 keysym.unicode = Translate2Unicode(bytes);
495 }
496 }
497 SDL_PrivateKeyboard(SDL_PRESSED, &keysym);
498 }
499 break;
500 }
501
502 case B_KEY_UP:
503 case B_UNMAPPED_KEY_UP: /* modifier keys are unmapped */
504 {
505 int32 key;
506 int32 modifiers;
507 if (msg->FindInt32("key", &key) == B_OK && msg->FindInt32("modifiers", &modifiers) == B_OK) {
508 SDL_keysym keysym;
509 keysym.scancode = key;
510 if (key < 128) {
511 keysym.sym = keymap[key];
512 } else {
513 keysym.sym = SDLK_UNKNOWN;
514 }
515 keysym.mod = KMOD_NONE; /* FIX THIS? */
516 keysym.unicode = 0;
517 if (SDL_TranslateUNICODE) {
518 const char *bytes;
519 if (msg->FindString("bytes", &bytes) == B_OK) {
520 keysym.unicode = Translate2Unicode(bytes);
521 }
522 }
523 SDL_PrivateKeyboard(SDL_RELEASED, &keysym);
524 }
525 break;
526 }
527
528 default:
529 /* move it after switch{} so it's always handled
530 that way we keep BeOS feautures like:
531 - CTRL+Q to close window (and other shortcuts)
532 - PrintScreen to make screenshot into /boot/home
533 - etc.. */
534 //BDirectWindow::DispatchMessage(msg, target);
535 break;
536 }
537 BDirectWindow::DispatchMessage(msg, target);
538 }
539
214 private: 540 private:
215 #ifdef HAVE_OPENGL 541 #ifdef HAVE_OPENGL
216 BGLView *SDL_GLView; 542 BGLView *SDL_GLView;
217 #endif 543 #endif
218 SDL_BView *SDL_View; 544 SDL_BView *SDL_View;
219 BView *the_view; 545 BView *the_view;
220 546
221 bool shown; 547 bool shown;
222 bool inhibit_resize; 548 bool inhibit_resize;
549
550 int32 last_buttons;
551 SDLKey keymap[128];
223 }; 552 };
224 553
225 #endif /* _SDL_BWin_h */ 554 #endif /* _SDL_BWin_h */