SDL-1.2.14
[sdl_omap.git] / src / video / bwindow / SDL_sysevents.cc
1 /*
2     SDL - Simple DirectMedia Layer
3     Copyright (C) 1997-2009 Sam Lantinga
4
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.
9
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.
14
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
18
19     Sam Lantinga
20     slouken@libsdl.org
21 */
22 #include "SDL_config.h"
23
24 #include <support/UTF8.h>
25 #include <stdio.h>
26 #include <string.h>
27 #include "SDL_error.h"
28 #include "SDL_events.h"
29 #include "SDL_BWin.h"
30 #include "SDL_lowvideo.h"
31
32 static SDLKey keymap[128];
33 int mouse_relative = 0;
34 extern "C" {
35
36 #include "../../events/SDL_sysevents.h"
37 #include "../../events/SDL_events_c.h"
38 #include "SDL_sysevents_c.h"
39
40 void BE_PumpEvents(_THIS)
41 {
42 }
43
44 void BE_InitOSKeymap(_THIS)
45 {
46                 for ( uint i=0; i<SDL_TABLESIZE(keymap); ++i )
47                         keymap[i] = SDLK_UNKNOWN;
48
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;
156 }
157
158 }; /* Extern C */
159
160 void SDL_BWin::DispatchMessage(BMessage *msg, BHandler *target)
161 {
162         switch (msg->what) {
163                 case B_MOUSE_MOVED:
164                 {
165                         SDL_VideoDevice *view = current_video;
166                         BPoint where;
167                         int32 transit;
168                         if (msg->FindPoint("where", &where) == B_OK && msg->FindInt32("be:transit", &transit) == B_OK) {
169                                 int x, y;
170
171                                 GetXYOffset(x, y);
172                                 x = (int)where.x - x;
173                                 y = (int)where.y - y;
174
175                                 //BeSman: I need another method for cursor catching !!!
176                                 if (view->input_grab != SDL_GRAB_OFF)
177                                 {
178                                         bool clipped = false;
179                                         if ( x < 0 ) {
180                                                 x = 0;
181                                                 clipped = true;
182                                         } else if ( x >= SDL_VideoSurface->w ) {
183                                                 x = (SDL_VideoSurface->w-1);
184                                                 clipped = true;
185                                         }
186                                         if ( y < 0 ) {
187                                                 y = 0;
188                                                 clipped = true;
189                                         } else if ( y >= SDL_VideoSurface->h ) {
190                                                 y = (SDL_VideoSurface->h-1);
191                                                 clipped = true;
192                                         }
193                                         if ( clipped ) {
194                                                 BPoint edge;
195                                                 GetXYOffset(edge.x, edge.y);
196                                                 edge.x += x;
197                                                 edge.y += y;
198                                                 ConvertToScreen(&edge);
199                                                 set_mouse_position((int)edge.x, (int)edge.y);
200                                         }
201                                         transit = B_INSIDE_VIEW;
202                                 }
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);
207                                         }
208                                 } else {
209                                         if ( !(SDL_GetAppState() & SDL_APPMOUSEFOCUS) ) {
210                                                 SDL_PrivateAppActive(1, SDL_APPMOUSEFOCUS);
211                                                 SDL_SetCursor(NULL);
212                                         }
213
214                                         if ( mouse_relative ) {
215                                                 int half_w = (SDL_VideoSurface->w/2);
216                                                 int half_h = (SDL_VideoSurface->h/2);
217                                                 x -= half_w;
218                                                 y -= half_h;
219                                                 if ( x || y ) {
220                                                         BPoint center;
221                                                         GetXYOffset(center.x, center.y);
222                                                         center.x += half_w;
223                                                         center.y += half_h;
224                                                         ConvertToScreen(&center);
225                                                         set_mouse_position((int)center.x, (int)center.y);
226                                                         SDL_PrivateMouseMotion(0, 1, x, y);
227                                                 }
228                                         } else {
229                                                 SDL_PrivateMouseMotion(0, 0, x, y);
230                                         }
231                                 }
232                         }
233                         break;
234                 }
235
236                 case B_MOUSE_DOWN:
237                 {
238                         /*      it looks like mouse down is send only for first clicked
239                                 button, each next is not send while last one is holded */
240                         int32 buttons;
241                         int sdl_buttons = 0;
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;
246                                 }
247                                 if (buttons & B_SECONDARY_MOUSE_BUTTON) {
248                                         sdl_buttons |= SDL_BUTTON_RIGHT;
249                                 }
250                                 if (buttons & B_TERTIARY_MOUSE_BUTTON) {
251                                         sdl_buttons |= SDL_BUTTON_MIDDLE;
252                                 }
253                                 SDL_PrivateMouseButton(SDL_PRESSED, sdl_buttons, 0, 0);
254
255                                 last_buttons = buttons;
256                         }
257                         break;
258                 }
259
260                 case B_MOUSE_UP:
261                 {
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
266                                 in mouse up :(
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. */
271                         int32 buttons;
272                         int sdl_buttons = 0;
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;
277                                 }
278                                 if ((buttons ^ B_SECONDARY_MOUSE_BUTTON) & last_buttons) {
279                                         sdl_buttons |= SDL_BUTTON_RIGHT;
280                                 }
281                                 if ((buttons ^ B_TERTIARY_MOUSE_BUTTON) & last_buttons) {
282                                         sdl_buttons |= SDL_BUTTON_MIDDLE;
283                                 }
284                                 SDL_PrivateMouseButton(SDL_RELEASED, sdl_buttons, 0, 0);
285
286                                 last_buttons = buttons;
287                         }
288                         break;
289                 }
290
291                 case B_MOUSE_WHEEL_CHANGED:
292                 {
293                         float x, y;
294                         x = y = 0;
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);
302                                 }
303                         }
304                         break;
305                 }
306
307                 case B_KEY_DOWN:
308                 case B_UNMAPPED_KEY_DOWN: /* modifier keys are unmapped */
309                 {
310                         int32 key;
311                         int32 modifiers;
312                         int32 key_repeat;
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)
315                                 break;
316
317                         if (msg->FindInt32("key", &key) == B_OK && msg->FindInt32("modifiers", &modifiers) == B_OK) {
318                                 SDL_keysym keysym;
319                                 keysym.scancode = key;
320                                 if (key < 128) {
321                                         keysym.sym = keymap[key];
322                                 } else {
323                                         keysym.sym = SDLK_UNKNOWN;
324                                 }
325                                 /*      FIX THIS?
326                                         it seems SDL_PrivateKeyboard() changes mod value
327                                         anyway, and doesn't care about what we setup here */
328                                 keysym.mod = KMOD_NONE;
329                                 keysym.unicode = 0;
330                                 if (SDL_TranslateUNICODE) {
331                                         const char *bytes;
332                                         if (msg->FindString("bytes", &bytes) == B_OK) {
333                                                 /*      FIX THIS?
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);
338                                         }
339                                 }
340                                 SDL_PrivateKeyboard(SDL_PRESSED, &keysym);
341                         }
342                         break;
343                 }
344
345                 case B_KEY_UP:
346                 case B_UNMAPPED_KEY_UP: /* modifier keys are unmapped */
347                 {
348                         int32 key;
349                         int32 modifiers;
350                         if (msg->FindInt32("key", &key) == B_OK && msg->FindInt32("modifiers", &modifiers) == B_OK) {
351                                 SDL_keysym keysym;
352                                 keysym.scancode = key;
353                                 if (key < 128) {
354                                         keysym.sym = keymap[key];
355                                 } else {
356                                         keysym.sym = SDLK_UNKNOWN;
357                                 }
358                                 keysym.mod = KMOD_NONE; /* FIX THIS? */
359                                 keysym.unicode = 0;
360                                 if (SDL_TranslateUNICODE) {
361                                         const char *bytes;
362                                         if (msg->FindString("bytes", &bytes) == B_OK) {
363                                                 keysym.unicode = Translate2Unicode(bytes);
364                                         }
365                                 }
366                                 SDL_PrivateKeyboard(SDL_RELEASED, &keysym);
367                         }
368                         break;
369                 }
370
371                 default:
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
376                                 - etc.. */
377                         //BDirectWindow::DispatchMessage(msg, target);
378                         break;
379         }
380         BDirectWindow::DispatchMessage(msg, target);
381 }
382
383 void SDL_BWin::DirectConnected(direct_buffer_info *info) {
384         switch (info->buffer_state & B_DIRECT_MODE_MASK) {
385                 case B_DIRECT_START:
386                 case B_DIRECT_MODIFY:
387                         {
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);
393                                 break;
394                         }
395                 default:
396                         break;
397         }
398 }