comparison src/video/bwindow/SDL_BWin.h @ 3878:678576473849 SDL-1.2

Fixed bug #286 Date: Thu, 9 Feb 2006 17:06:51 +0300 From: "Oleg K [BeSman]" Subject: BeOS SDL patches Hello all. My name is Oleg K. [BeSman], Im a BeOS user from Russia.This mail contain a BeOs-specific patches to SDL (implementation of InputGrabbing and mouse_relative mode). See the source in attached file for details.
author Sam Lantinga <slouken@libsdl.org>
date Sun, 24 Sep 2006 15:31:42 +0000
parents 6162b8d921ce
children 4e29535b821b
comparison
equal deleted inserted replaced
3877:81f66f258d77 3878:678576473849
38 #include "SDL_events.h" 38 #include "SDL_events.h"
39 #include "SDL_BView.h" 39 #include "SDL_BView.h"
40 40
41 extern "C" { 41 extern "C" {
42 #include "../../events/SDL_events_c.h" 42 #include "../../events/SDL_events_c.h"
43
44 extern int mouse_relative;
43 }; 45 };
44 46
45 class SDL_BWin : public BDirectWindow 47 class SDL_BWin : public BDirectWindow
46 { 48 {
47 public: 49 public:
48 SDL_BWin(BRect bounds) : 50 SDL_BWin(BRect bounds) :
49 BDirectWindow(bounds, "Untitled", B_TITLED_WINDOW, 0) { 51 BDirectWindow(bounds, "Untitled", B_TITLED_WINDOW, 0) {
50 InitKeyboard();
51 last_buttons = 0; 52 last_buttons = 0;
52
53 the_view = NULL; 53 the_view = NULL;
54 #if SDL_VIDEO_OPENGL 54 #if SDL_VIDEO_OPENGL
55 SDL_GLView = NULL; 55 SDL_GLView = NULL;
56 #endif 56 #endif
57 SDL_View = NULL; 57 SDL_View = NULL;
80 if ( SDL_View ) { 80 if ( SDL_View ) {
81 delete SDL_View; 81 delete SDL_View;
82 } 82 }
83 } 83 }
84 84
85 virtual void InitKeyboard(void) {
86 for ( uint i=0; i<SDL_TABLESIZE(keymap); ++i )
87 keymap[i] = SDLK_UNKNOWN;
88
89 keymap[0x01] = SDLK_ESCAPE;
90 keymap[B_F1_KEY] = SDLK_F1;
91 keymap[B_F2_KEY] = SDLK_F2;
92 keymap[B_F3_KEY] = SDLK_F3;
93 keymap[B_F4_KEY] = SDLK_F4;
94 keymap[B_F5_KEY] = SDLK_F5;
95 keymap[B_F6_KEY] = SDLK_F6;
96 keymap[B_F7_KEY] = SDLK_F7;
97 keymap[B_F8_KEY] = SDLK_F8;
98 keymap[B_F9_KEY] = SDLK_F9;
99 keymap[B_F10_KEY] = SDLK_F10;
100 keymap[B_F11_KEY] = SDLK_F11;
101 keymap[B_F12_KEY] = SDLK_F12;
102 keymap[B_PRINT_KEY] = SDLK_PRINT;
103 keymap[B_SCROLL_KEY] = SDLK_SCROLLOCK;
104 keymap[B_PAUSE_KEY] = SDLK_PAUSE;
105 keymap[0x11] = SDLK_BACKQUOTE;
106 keymap[0x12] = SDLK_1;
107 keymap[0x13] = SDLK_2;
108 keymap[0x14] = SDLK_3;
109 keymap[0x15] = SDLK_4;
110 keymap[0x16] = SDLK_5;
111 keymap[0x17] = SDLK_6;
112 keymap[0x18] = SDLK_7;
113 keymap[0x19] = SDLK_8;
114 keymap[0x1a] = SDLK_9;
115 keymap[0x1b] = SDLK_0;
116 keymap[0x1c] = SDLK_MINUS;
117 keymap[0x1d] = SDLK_EQUALS;
118 keymap[0x1e] = SDLK_BACKSPACE;
119 keymap[0x1f] = SDLK_INSERT;
120 keymap[0x20] = SDLK_HOME;
121 keymap[0x21] = SDLK_PAGEUP;
122 keymap[0x22] = SDLK_NUMLOCK;
123 keymap[0x23] = SDLK_KP_DIVIDE;
124 keymap[0x24] = SDLK_KP_MULTIPLY;
125 keymap[0x25] = SDLK_KP_MINUS;
126 keymap[0x26] = SDLK_TAB;
127 keymap[0x27] = SDLK_q;
128 keymap[0x28] = SDLK_w;
129 keymap[0x29] = SDLK_e;
130 keymap[0x2a] = SDLK_r;
131 keymap[0x2b] = SDLK_t;
132 keymap[0x2c] = SDLK_y;
133 keymap[0x2d] = SDLK_u;
134 keymap[0x2e] = SDLK_i;
135 keymap[0x2f] = SDLK_o;
136 keymap[0x30] = SDLK_p;
137 keymap[0x31] = SDLK_LEFTBRACKET;
138 keymap[0x32] = SDLK_RIGHTBRACKET;
139 keymap[0x33] = SDLK_BACKSLASH;
140 keymap[0x34] = SDLK_DELETE;
141 keymap[0x35] = SDLK_END;
142 keymap[0x36] = SDLK_PAGEDOWN;
143 keymap[0x37] = SDLK_KP7;
144 keymap[0x38] = SDLK_KP8;
145 keymap[0x39] = SDLK_KP9;
146 keymap[0x3a] = SDLK_KP_PLUS;
147 keymap[0x3b] = SDLK_CAPSLOCK;
148 keymap[0x3c] = SDLK_a;
149 keymap[0x3d] = SDLK_s;
150 keymap[0x3e] = SDLK_d;
151 keymap[0x3f] = SDLK_f;
152 keymap[0x40] = SDLK_g;
153 keymap[0x41] = SDLK_h;
154 keymap[0x42] = SDLK_j;
155 keymap[0x43] = SDLK_k;
156 keymap[0x44] = SDLK_l;
157 keymap[0x45] = SDLK_SEMICOLON;
158 keymap[0x46] = SDLK_QUOTE;
159 keymap[0x47] = SDLK_RETURN;
160 keymap[0x48] = SDLK_KP4;
161 keymap[0x49] = SDLK_KP5;
162 keymap[0x4a] = SDLK_KP6;
163 keymap[0x4b] = SDLK_LSHIFT;
164 keymap[0x4c] = SDLK_z;
165 keymap[0x4d] = SDLK_x;
166 keymap[0x4e] = SDLK_c;
167 keymap[0x4f] = SDLK_v;
168 keymap[0x50] = SDLK_b;
169 keymap[0x51] = SDLK_n;
170 keymap[0x52] = SDLK_m;
171 keymap[0x53] = SDLK_COMMA;
172 keymap[0x54] = SDLK_PERIOD;
173 keymap[0x55] = SDLK_SLASH;
174 keymap[0x56] = SDLK_RSHIFT;
175 keymap[0x57] = SDLK_UP;
176 keymap[0x58] = SDLK_KP1;
177 keymap[0x59] = SDLK_KP2;
178 keymap[0x5a] = SDLK_KP3;
179 keymap[0x5b] = SDLK_KP_ENTER;
180 keymap[0x5c] = SDLK_LCTRL;
181 keymap[0x5d] = SDLK_LALT;
182 keymap[0x5e] = SDLK_SPACE;
183 keymap[0x5f] = SDLK_RALT;
184 keymap[0x60] = SDLK_RCTRL;
185 keymap[0x61] = SDLK_LEFT;
186 keymap[0x62] = SDLK_DOWN;
187 keymap[0x63] = SDLK_RIGHT;
188 keymap[0x64] = SDLK_KP0;
189 keymap[0x65] = SDLK_KP_PERIOD;
190 keymap[0x66] = SDLK_LMETA;
191 keymap[0x67] = SDLK_RMETA;
192 keymap[0x68] = SDLK_MENU;
193 keymap[0x69] = SDLK_EURO;
194 keymap[0x6a] = SDLK_KP_EQUALS;
195 keymap[0x6b] = SDLK_POWER;
196 }
197 85
198 /* Override the Show() method so we can tell when we've been shown */ 86 /* Override the Show() method so we can tell when we've been shown */
199 virtual void Show(void) { 87 virtual void Show(void) {
200 BWindow::Show(); 88 BWindow::Show();
201 shown = true; 89 shown = true;
258 Unlock(); 146 Unlock();
259 return(retval); 147 return(retval);
260 } 148 }
261 virtual void SetBitmap(BBitmap *bitmap) { 149 virtual void SetBitmap(BBitmap *bitmap) {
262 SDL_View->SetBitmap(bitmap); 150 SDL_View->SetBitmap(bitmap);
263 }
264 virtual void SetXYOffset(int x, int y) {
265 #if SDL_VIDEO_OPENGL
266 if ( the_view == SDL_GLView ) {
267 return;
268 }
269 #endif
270 SDL_View->SetXYOffset(x, y);
271 }
272 virtual void GetXYOffset(int &x, int &y) {
273 #if SDL_VIDEO_OPENGL
274 if ( the_view == SDL_GLView ) {
275 x = 0;
276 y = 0;
277 return;
278 }
279 #endif
280 SDL_View->GetXYOffset(x, y);
281 } 151 }
282 virtual bool BeginDraw(void) { 152 virtual bool BeginDraw(void) {
283 return(Lock()); 153 return(Lock());
284 } 154 }
285 virtual void DrawAsync(BRect updateRect) { 155 virtual void DrawAsync(BRect updateRect) {
365 } 235 }
366 236
367 return unicode; 237 return unicode;
368 } 238 }
369 239
370 virtual void DispatchMessage(BMessage *msg, BHandler *target) { 240 virtual void DispatchMessage(BMessage *msg, BHandler *target);
371 switch (msg->what) {
372 case B_MOUSE_MOVED:
373 {
374 BPoint where;
375 int32 transit;
376 if (msg->FindPoint("where", &where) == B_OK && msg->FindInt32("be:transit", &transit) == B_OK) {
377 if (transit == B_EXITED_VIEW) {
378 if ( SDL_GetAppState() & SDL_APPMOUSEFOCUS ) {
379 SDL_PrivateAppActive(0, SDL_APPMOUSEFOCUS);
380 be_app->SetCursor(B_HAND_CURSOR);
381 }
382 } else {
383 int x, y;
384 if ( ! (SDL_GetAppState() & SDL_APPMOUSEFOCUS) ) {
385 SDL_PrivateAppActive(1, SDL_APPMOUSEFOCUS);
386 SDL_SetCursor(NULL);
387 }
388 GetXYOffset(x, y);
389 x = (int)where.x - x;
390 y = (int)where.y - y;
391 SDL_PrivateMouseMotion(0, 0, x, y);
392 }
393 }
394 break;
395 }
396
397 case B_MOUSE_DOWN:
398 {
399 /* it looks like mouse down is send only for first clicked
400 button, each next is not send while last one is holded */
401 int32 buttons;
402 int sdl_buttons = 0;
403 if (msg->FindInt32("buttons", &buttons) == B_OK) {
404 /* Add any mouse button events */
405 if (buttons & B_PRIMARY_MOUSE_BUTTON) {
406 sdl_buttons |= SDL_BUTTON_LEFT;
407 }
408 if (buttons & B_SECONDARY_MOUSE_BUTTON) {
409 sdl_buttons |= SDL_BUTTON_RIGHT;
410 }
411 if (buttons & B_TERTIARY_MOUSE_BUTTON) {
412 sdl_buttons |= SDL_BUTTON_MIDDLE;
413 }
414 SDL_PrivateMouseButton(SDL_PRESSED, sdl_buttons, 0, 0);
415
416 last_buttons = buttons;
417 }
418 break;
419 }
420
421 case B_MOUSE_UP:
422 {
423 /* mouse up doesn't give which button was released,
424 only state of buttons (after release, so it's always = 0),
425 which is not what we need ;]
426 So we need to store button in mouse down, and restore
427 in mouse up :(
428 mouse up is (similarly to mouse down) send only for
429 first button down (ie. it's no send if we click another button
430 without releasing previous one first) - but that's probably
431 because of how drivers are written?, not BeOS itself. */
432 int32 buttons;
433 int sdl_buttons = 0;
434 if (msg->FindInt32("buttons", &buttons) == B_OK) {
435 /* Add any mouse button events */
436 if ((buttons ^ B_PRIMARY_MOUSE_BUTTON) & last_buttons) {
437 sdl_buttons |= SDL_BUTTON_LEFT;
438 }
439 if ((buttons ^ B_SECONDARY_MOUSE_BUTTON) & last_buttons) {
440 sdl_buttons |= SDL_BUTTON_RIGHT;
441 }
442 if ((buttons ^ B_TERTIARY_MOUSE_BUTTON) & last_buttons) {
443 sdl_buttons |= SDL_BUTTON_MIDDLE;
444 }
445 SDL_PrivateMouseButton(SDL_RELEASED, sdl_buttons, 0, 0);
446
447 last_buttons = buttons;
448 }
449 break;
450 }
451
452 case B_MOUSE_WHEEL_CHANGED:
453 {
454 float x, y;
455 x = y = 0;
456 if (msg->FindFloat("be:wheel_delta_x", &x) == B_OK && msg->FindFloat("be:wheel_delta_y", &y) == B_OK) {
457 if (x < 0 || y < 0) {
458 SDL_PrivateMouseButton(SDL_PRESSED, SDL_BUTTON_WHEELDOWN, 0, 0);
459 SDL_PrivateMouseButton(SDL_RELEASED, SDL_BUTTON_WHEELDOWN, 0, 0);
460 } else if (x > 0 || y > 0) {
461 SDL_PrivateMouseButton(SDL_PRESSED, SDL_BUTTON_WHEELUP, 0, 0);
462 SDL_PrivateMouseButton(SDL_RELEASED, SDL_BUTTON_WHEELUP, 0, 0);
463 }
464 }
465 break;
466 }
467
468 case B_KEY_DOWN:
469 case B_UNMAPPED_KEY_DOWN: /* modifier keys are unmapped */
470 {
471 int32 key;
472 int32 modifiers;
473 int32 key_repeat;
474 /* Workaround for SDL message queue being filled too fast because of BeOS own key-repeat mechanism */
475 if (msg->FindInt32("be:key_repeat", &key_repeat) == B_OK && key_repeat > 0)
476 break;
477
478 if (msg->FindInt32("key", &key) == B_OK && msg->FindInt32("modifiers", &modifiers) == B_OK) {
479 SDL_keysym keysym;
480 keysym.scancode = key;
481 if ((key > 0) && (key < 128)) {
482 keysym.sym = keymap[key];
483 } else {
484 keysym.sym = SDLK_UNKNOWN;
485 }
486 /* FIX THIS?
487 it seems SDL_PrivateKeyboard() changes mod value
488 anyway, and doesn't care about what we setup here */
489 keysym.mod = KMOD_NONE;
490 keysym.unicode = 0;
491 if (SDL_TranslateUNICODE) {
492 const char *bytes;
493 if (msg->FindString("bytes", &bytes) == B_OK) {
494 /* FIX THIS?
495 this cares only about first "letter",
496 so if someone maps some key to print
497 "BeOS rulez!" only "B" will be used. */
498 keysym.unicode = Translate2Unicode(bytes);
499 }
500 }
501 SDL_PrivateKeyboard(SDL_PRESSED, &keysym);
502 }
503 break;
504 }
505
506 case B_KEY_UP:
507 case B_UNMAPPED_KEY_UP: /* modifier keys are unmapped */
508 {
509 int32 key;
510 int32 modifiers;
511 if (msg->FindInt32("key", &key) == B_OK && msg->FindInt32("modifiers", &modifiers) == B_OK) {
512 SDL_keysym keysym;
513 keysym.scancode = key;
514 if ((key > 0) && (key < 128)) {
515 keysym.sym = keymap[key];
516 } else {
517 keysym.sym = SDLK_UNKNOWN;
518 }
519 keysym.mod = KMOD_NONE; /* FIX THIS? */
520 keysym.unicode = 0;
521 if (SDL_TranslateUNICODE) {
522 const char *bytes;
523 if (msg->FindString("bytes", &bytes) == B_OK) {
524 keysym.unicode = Translate2Unicode(bytes);
525 }
526 }
527 SDL_PrivateKeyboard(SDL_RELEASED, &keysym);
528 }
529 break;
530 }
531
532 default:
533 /* move it after switch{} so it's always handled
534 that way we keep BeOS feautures like:
535 - CTRL+Q to close window (and other shortcuts)
536 - PrintScreen to make screenshot into /boot/home
537 - etc.. */
538 //BDirectWindow::DispatchMessage(msg, target);
539 break;
540 }
541 BDirectWindow::DispatchMessage(msg, target);
542 }
543 241
544 private: 242 private:
545 #if SDL_VIDEO_OPENGL 243 #if SDL_VIDEO_OPENGL
546 BGLView *SDL_GLView; 244 BGLView *SDL_GLView;
547 #endif 245 #endif
548 SDL_BView *SDL_View; 246 SDL_BView *SDL_View;
549 BView *the_view; 247 BView *the_view;
550
551 bool shown; 248 bool shown;
552 bool inhibit_resize; 249 bool inhibit_resize;
553
554 int32 last_buttons; 250 int32 last_buttons;
555 SDLKey keymap[128];
556 }; 251 };
557 252
558 #endif /* _SDL_BWin_h */ 253 #endif /* _SDL_BWin_h */