2 SDL - Simple DirectMedia Layer
3 Copyright (C) 1997-2009 Sam Lantinga
5 This library is free software; you can redistribute it and/or
6 modify it under the terms of the GNU Lesser General Public
7 License as published by the Free Software Foundation; either
8 version 2.1 of the License, or (at your option) any later version.
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 Lesser General Public License for more details.
15 You should have received a copy of the GNU Lesser General Public
16 License along with this library; if not, write to the Free Software
17 Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
22 #include "SDL_config.h"
24 #include <support/UTF8.h>
27 #include "SDL_error.h"
28 #include "SDL_events.h"
30 #include "SDL_lowvideo.h"
32 static SDLKey keymap[128];
33 int mouse_relative = 0;
36 #include "../../events/SDL_sysevents.h"
37 #include "../../events/SDL_events_c.h"
38 #include "SDL_sysevents_c.h"
40 void BE_PumpEvents(_THIS)
44 void BE_InitOSKeymap(_THIS)
46 for ( uint i=0; i<SDL_TABLESIZE(keymap); ++i )
47 keymap[i] = SDLK_UNKNOWN;
49 keymap[0x01] = SDLK_ESCAPE;
50 keymap[B_F1_KEY] = SDLK_F1;
51 keymap[B_F2_KEY] = SDLK_F2;
52 keymap[B_F3_KEY] = SDLK_F3;
53 keymap[B_F4_KEY] = SDLK_F4;
54 keymap[B_F5_KEY] = SDLK_F5;
55 keymap[B_F6_KEY] = SDLK_F6;
56 keymap[B_F7_KEY] = SDLK_F7;
57 keymap[B_F8_KEY] = SDLK_F8;
58 keymap[B_F9_KEY] = SDLK_F9;
59 keymap[B_F10_KEY] = SDLK_F10;
60 keymap[B_F11_KEY] = SDLK_F11;
61 keymap[B_F12_KEY] = SDLK_F12;
62 keymap[B_PRINT_KEY] = SDLK_PRINT;
63 keymap[B_SCROLL_KEY] = SDLK_SCROLLOCK;
64 keymap[B_PAUSE_KEY] = SDLK_PAUSE;
65 keymap[0x11] = SDLK_BACKQUOTE;
66 keymap[0x12] = SDLK_1;
67 keymap[0x13] = SDLK_2;
68 keymap[0x14] = SDLK_3;
69 keymap[0x15] = SDLK_4;
70 keymap[0x16] = SDLK_5;
71 keymap[0x17] = SDLK_6;
72 keymap[0x18] = SDLK_7;
73 keymap[0x19] = SDLK_8;
74 keymap[0x1a] = SDLK_9;
75 keymap[0x1b] = SDLK_0;
76 keymap[0x1c] = SDLK_MINUS;
77 keymap[0x1d] = SDLK_EQUALS;
78 keymap[0x1e] = SDLK_BACKSPACE;
79 keymap[0x1f] = SDLK_INSERT;
80 keymap[0x20] = SDLK_HOME;
81 keymap[0x21] = SDLK_PAGEUP;
82 keymap[0x22] = SDLK_NUMLOCK;
83 keymap[0x23] = SDLK_KP_DIVIDE;
84 keymap[0x24] = SDLK_KP_MULTIPLY;
85 keymap[0x25] = SDLK_KP_MINUS;
86 keymap[0x26] = SDLK_TAB;
87 keymap[0x27] = SDLK_q;
88 keymap[0x28] = SDLK_w;
89 keymap[0x29] = SDLK_e;
90 keymap[0x2a] = SDLK_r;
91 keymap[0x2b] = SDLK_t;
92 keymap[0x2c] = SDLK_y;
93 keymap[0x2d] = SDLK_u;
94 keymap[0x2e] = SDLK_i;
95 keymap[0x2f] = SDLK_o;
96 keymap[0x30] = SDLK_p;
97 keymap[0x31] = SDLK_LEFTBRACKET;
98 keymap[0x32] = SDLK_RIGHTBRACKET;
99 keymap[0x33] = SDLK_BACKSLASH;
100 keymap[0x34] = SDLK_DELETE;
101 keymap[0x35] = SDLK_END;
102 keymap[0x36] = SDLK_PAGEDOWN;
103 keymap[0x37] = SDLK_KP7;
104 keymap[0x38] = SDLK_KP8;
105 keymap[0x39] = SDLK_KP9;
106 keymap[0x3a] = SDLK_KP_PLUS;
107 keymap[0x3b] = SDLK_CAPSLOCK;
108 keymap[0x3c] = SDLK_a;
109 keymap[0x3d] = SDLK_s;
110 keymap[0x3e] = SDLK_d;
111 keymap[0x3f] = SDLK_f;
112 keymap[0x40] = SDLK_g;
113 keymap[0x41] = SDLK_h;
114 keymap[0x42] = SDLK_j;
115 keymap[0x43] = SDLK_k;
116 keymap[0x44] = SDLK_l;
117 keymap[0x45] = SDLK_SEMICOLON;
118 keymap[0x46] = SDLK_QUOTE;
119 keymap[0x47] = SDLK_RETURN;
120 keymap[0x48] = SDLK_KP4;
121 keymap[0x49] = SDLK_KP5;
122 keymap[0x4a] = SDLK_KP6;
123 keymap[0x4b] = SDLK_LSHIFT;
124 keymap[0x4c] = SDLK_z;
125 keymap[0x4d] = SDLK_x;
126 keymap[0x4e] = SDLK_c;
127 keymap[0x4f] = SDLK_v;
128 keymap[0x50] = SDLK_b;
129 keymap[0x51] = SDLK_n;
130 keymap[0x52] = SDLK_m;
131 keymap[0x53] = SDLK_COMMA;
132 keymap[0x54] = SDLK_PERIOD;
133 keymap[0x55] = SDLK_SLASH;
134 keymap[0x56] = SDLK_RSHIFT;
135 keymap[0x57] = SDLK_UP;
136 keymap[0x58] = SDLK_KP1;
137 keymap[0x59] = SDLK_KP2;
138 keymap[0x5a] = SDLK_KP3;
139 keymap[0x5b] = SDLK_KP_ENTER;
140 keymap[0x5c] = SDLK_LCTRL;
141 keymap[0x5d] = SDLK_LALT;
142 keymap[0x5e] = SDLK_SPACE;
143 keymap[0x5f] = SDLK_RALT;
144 keymap[0x60] = SDLK_RCTRL;
145 keymap[0x61] = SDLK_LEFT;
146 keymap[0x62] = SDLK_DOWN;
147 keymap[0x63] = SDLK_RIGHT;
148 keymap[0x64] = SDLK_KP0;
149 keymap[0x65] = SDLK_KP_PERIOD;
150 keymap[0x66] = SDLK_LMETA;
151 keymap[0x67] = SDLK_RMETA;
152 keymap[0x68] = SDLK_MENU;
153 keymap[0x69] = SDLK_EURO;
154 keymap[0x6a] = SDLK_KP_EQUALS;
155 keymap[0x6b] = SDLK_POWER;
160 void SDL_BWin::DispatchMessage(BMessage *msg, BHandler *target)
165 SDL_VideoDevice *view = current_video;
168 if (msg->FindPoint("where", &where) == B_OK && msg->FindInt32("be:transit", &transit) == B_OK) {
172 x = (int)where.x - x;
173 y = (int)where.y - y;
175 //BeSman: I need another method for cursor catching !!!
176 if (view->input_grab != SDL_GRAB_OFF)
178 bool clipped = false;
182 } else if ( x >= SDL_VideoSurface->w ) {
183 x = (SDL_VideoSurface->w-1);
189 } else if ( y >= SDL_VideoSurface->h ) {
190 y = (SDL_VideoSurface->h-1);
195 GetXYOffset(edge.x, edge.y);
198 ConvertToScreen(&edge);
199 set_mouse_position((int)edge.x, (int)edge.y);
201 transit = B_INSIDE_VIEW;
203 if (transit == B_EXITED_VIEW) {
204 if ( SDL_GetAppState() & SDL_APPMOUSEFOCUS ) {
205 SDL_PrivateAppActive(0, SDL_APPMOUSEFOCUS);
206 be_app->SetCursor(B_HAND_CURSOR);
209 if ( !(SDL_GetAppState() & SDL_APPMOUSEFOCUS) ) {
210 SDL_PrivateAppActive(1, SDL_APPMOUSEFOCUS);
214 if ( mouse_relative ) {
215 int half_w = (SDL_VideoSurface->w/2);
216 int half_h = (SDL_VideoSurface->h/2);
221 GetXYOffset(center.x, center.y);
224 ConvertToScreen(¢er);
225 set_mouse_position((int)center.x, (int)center.y);
226 SDL_PrivateMouseMotion(0, 1, x, y);
229 SDL_PrivateMouseMotion(0, 0, x, y);
238 /* it looks like mouse down is send only for first clicked
239 button, each next is not send while last one is holded */
242 if (msg->FindInt32("buttons", &buttons) == B_OK) {
243 /* Add any mouse button events */
244 if (buttons & B_PRIMARY_MOUSE_BUTTON) {
245 sdl_buttons |= SDL_BUTTON_LEFT;
247 if (buttons & B_SECONDARY_MOUSE_BUTTON) {
248 sdl_buttons |= SDL_BUTTON_RIGHT;
250 if (buttons & B_TERTIARY_MOUSE_BUTTON) {
251 sdl_buttons |= SDL_BUTTON_MIDDLE;
253 SDL_PrivateMouseButton(SDL_PRESSED, sdl_buttons, 0, 0);
255 last_buttons = buttons;
262 /* mouse up doesn't give which button was released,
263 only state of buttons (after release, so it's always = 0),
264 which is not what we need ;]
265 So we need to store button in mouse down, and restore
267 mouse up is (similarly to mouse down) send only for
268 first button down (ie. it's no send if we click another button
269 without releasing previous one first) - but that's probably
270 because of how drivers are written?, not BeOS itself. */
273 if (msg->FindInt32("buttons", &buttons) == B_OK) {
274 /* Add any mouse button events */
275 if ((buttons ^ B_PRIMARY_MOUSE_BUTTON) & last_buttons) {
276 sdl_buttons |= SDL_BUTTON_LEFT;
278 if ((buttons ^ B_SECONDARY_MOUSE_BUTTON) & last_buttons) {
279 sdl_buttons |= SDL_BUTTON_RIGHT;
281 if ((buttons ^ B_TERTIARY_MOUSE_BUTTON) & last_buttons) {
282 sdl_buttons |= SDL_BUTTON_MIDDLE;
284 SDL_PrivateMouseButton(SDL_RELEASED, sdl_buttons, 0, 0);
286 last_buttons = buttons;
291 case B_MOUSE_WHEEL_CHANGED:
295 if (msg->FindFloat("be:wheel_delta_x", &x) == B_OK && msg->FindFloat("be:wheel_delta_y", &y) == B_OK) {
296 if (x < 0 || y < 0) {
297 SDL_PrivateMouseButton(SDL_PRESSED, SDL_BUTTON_WHEELDOWN, 0, 0);
298 SDL_PrivateMouseButton(SDL_RELEASED, SDL_BUTTON_WHEELDOWN, 0, 0);
299 } else if (x > 0 || y > 0) {
300 SDL_PrivateMouseButton(SDL_PRESSED, SDL_BUTTON_WHEELUP, 0, 0);
301 SDL_PrivateMouseButton(SDL_RELEASED, SDL_BUTTON_WHEELUP, 0, 0);
308 case B_UNMAPPED_KEY_DOWN: /* modifier keys are unmapped */
313 /* Workaround for SDL message queue being filled too fast because of BeOS own key-repeat mechanism */
314 if (msg->FindInt32("be:key_repeat", &key_repeat) == B_OK && key_repeat > 0)
317 if (msg->FindInt32("key", &key) == B_OK && msg->FindInt32("modifiers", &modifiers) == B_OK) {
319 keysym.scancode = key;
321 keysym.sym = keymap[key];
323 keysym.sym = SDLK_UNKNOWN;
326 it seems SDL_PrivateKeyboard() changes mod value
327 anyway, and doesn't care about what we setup here */
328 keysym.mod = KMOD_NONE;
330 if (SDL_TranslateUNICODE) {
332 if (msg->FindString("bytes", &bytes) == B_OK) {
334 this cares only about first "letter",
335 so if someone maps some key to print
336 "BeOS rulez!" only "B" will be used. */
337 keysym.unicode = Translate2Unicode(bytes);
340 SDL_PrivateKeyboard(SDL_PRESSED, &keysym);
346 case B_UNMAPPED_KEY_UP: /* modifier keys are unmapped */
350 if (msg->FindInt32("key", &key) == B_OK && msg->FindInt32("modifiers", &modifiers) == B_OK) {
352 keysym.scancode = key;
354 keysym.sym = keymap[key];
356 keysym.sym = SDLK_UNKNOWN;
358 keysym.mod = KMOD_NONE; /* FIX THIS? */
360 if (SDL_TranslateUNICODE) {
362 if (msg->FindString("bytes", &bytes) == B_OK) {
363 keysym.unicode = Translate2Unicode(bytes);
366 SDL_PrivateKeyboard(SDL_RELEASED, &keysym);
372 /* move it after switch{} so it's always handled
373 that way we keep BeOS feautures like:
374 - CTRL+Q to close window (and other shortcuts)
375 - PrintScreen to make screenshot into /boot/home
377 //BDirectWindow::DispatchMessage(msg, target);
380 BDirectWindow::DispatchMessage(msg, target);
383 void SDL_BWin::DirectConnected(direct_buffer_info *info) {
384 switch (info->buffer_state & B_DIRECT_MODE_MASK) {
386 case B_DIRECT_MODIFY:
388 int32 width = info->window_bounds.right -
389 info->window_bounds.left + 1;
390 int32 height = info->window_bounds.bottom -
391 info->window_bounds.top + 1;
392 SDL_PrivateResize(width, height);