diff options
Diffstat (limited to 'apps/plugins/sdl/src/video/bwindow/SDL_sysevents.cc')
-rw-r--r-- | apps/plugins/sdl/src/video/bwindow/SDL_sysevents.cc | 415 |
1 files changed, 415 insertions, 0 deletions
diff --git a/apps/plugins/sdl/src/video/bwindow/SDL_sysevents.cc b/apps/plugins/sdl/src/video/bwindow/SDL_sysevents.cc new file mode 100644 index 0000000000..9e127506de --- /dev/null +++ b/apps/plugins/sdl/src/video/bwindow/SDL_sysevents.cc | |||
@@ -0,0 +1,415 @@ | |||
1 | /* | ||
2 | SDL - Simple DirectMedia Layer | ||
3 | Copyright (C) 1997-2012 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 | #include "../SDL_cursor_c.h" | ||
40 | |||
41 | void BE_PumpEvents(_THIS) | ||
42 | { | ||
43 | } | ||
44 | |||
45 | void BE_InitOSKeymap(_THIS) | ||
46 | { | ||
47 | for ( uint i=0; i<SDL_TABLESIZE(keymap); ++i ) | ||
48 | keymap[i] = SDLK_UNKNOWN; | ||
49 | |||
50 | keymap[0x01] = SDLK_ESCAPE; | ||
51 | keymap[B_F1_KEY] = SDLK_F1; | ||
52 | keymap[B_F2_KEY] = SDLK_F2; | ||
53 | keymap[B_F3_KEY] = SDLK_F3; | ||
54 | keymap[B_F4_KEY] = SDLK_F4; | ||
55 | keymap[B_F5_KEY] = SDLK_F5; | ||
56 | keymap[B_F6_KEY] = SDLK_F6; | ||
57 | keymap[B_F7_KEY] = SDLK_F7; | ||
58 | keymap[B_F8_KEY] = SDLK_F8; | ||
59 | keymap[B_F9_KEY] = SDLK_F9; | ||
60 | keymap[B_F10_KEY] = SDLK_F10; | ||
61 | keymap[B_F11_KEY] = SDLK_F11; | ||
62 | keymap[B_F12_KEY] = SDLK_F12; | ||
63 | keymap[B_PRINT_KEY] = SDLK_PRINT; | ||
64 | keymap[B_SCROLL_KEY] = SDLK_SCROLLOCK; | ||
65 | keymap[B_PAUSE_KEY] = SDLK_PAUSE; | ||
66 | keymap[0x11] = SDLK_BACKQUOTE; | ||
67 | keymap[0x12] = SDLK_1; | ||
68 | keymap[0x13] = SDLK_2; | ||
69 | keymap[0x14] = SDLK_3; | ||
70 | keymap[0x15] = SDLK_4; | ||
71 | keymap[0x16] = SDLK_5; | ||
72 | keymap[0x17] = SDLK_6; | ||
73 | keymap[0x18] = SDLK_7; | ||
74 | keymap[0x19] = SDLK_8; | ||
75 | keymap[0x1a] = SDLK_9; | ||
76 | keymap[0x1b] = SDLK_0; | ||
77 | keymap[0x1c] = SDLK_MINUS; | ||
78 | keymap[0x1d] = SDLK_EQUALS; | ||
79 | keymap[0x1e] = SDLK_BACKSPACE; | ||
80 | keymap[0x1f] = SDLK_INSERT; | ||
81 | keymap[0x20] = SDLK_HOME; | ||
82 | keymap[0x21] = SDLK_PAGEUP; | ||
83 | keymap[0x22] = SDLK_NUMLOCK; | ||
84 | keymap[0x23] = SDLK_KP_DIVIDE; | ||
85 | keymap[0x24] = SDLK_KP_MULTIPLY; | ||
86 | keymap[0x25] = SDLK_KP_MINUS; | ||
87 | keymap[0x26] = SDLK_TAB; | ||
88 | keymap[0x27] = SDLK_q; | ||
89 | keymap[0x28] = SDLK_w; | ||
90 | keymap[0x29] = SDLK_e; | ||
91 | keymap[0x2a] = SDLK_r; | ||
92 | keymap[0x2b] = SDLK_t; | ||
93 | keymap[0x2c] = SDLK_y; | ||
94 | keymap[0x2d] = SDLK_u; | ||
95 | keymap[0x2e] = SDLK_i; | ||
96 | keymap[0x2f] = SDLK_o; | ||
97 | keymap[0x30] = SDLK_p; | ||
98 | keymap[0x31] = SDLK_LEFTBRACKET; | ||
99 | keymap[0x32] = SDLK_RIGHTBRACKET; | ||
100 | keymap[0x33] = SDLK_BACKSLASH; | ||
101 | keymap[0x34] = SDLK_DELETE; | ||
102 | keymap[0x35] = SDLK_END; | ||
103 | keymap[0x36] = SDLK_PAGEDOWN; | ||
104 | keymap[0x37] = SDLK_KP7; | ||
105 | keymap[0x38] = SDLK_KP8; | ||
106 | keymap[0x39] = SDLK_KP9; | ||
107 | keymap[0x3a] = SDLK_KP_PLUS; | ||
108 | keymap[0x3b] = SDLK_CAPSLOCK; | ||
109 | keymap[0x3c] = SDLK_a; | ||
110 | keymap[0x3d] = SDLK_s; | ||
111 | keymap[0x3e] = SDLK_d; | ||
112 | keymap[0x3f] = SDLK_f; | ||
113 | keymap[0x40] = SDLK_g; | ||
114 | keymap[0x41] = SDLK_h; | ||
115 | keymap[0x42] = SDLK_j; | ||
116 | keymap[0x43] = SDLK_k; | ||
117 | keymap[0x44] = SDLK_l; | ||
118 | keymap[0x45] = SDLK_SEMICOLON; | ||
119 | keymap[0x46] = SDLK_QUOTE; | ||
120 | keymap[0x47] = SDLK_RETURN; | ||
121 | keymap[0x48] = SDLK_KP4; | ||
122 | keymap[0x49] = SDLK_KP5; | ||
123 | keymap[0x4a] = SDLK_KP6; | ||
124 | keymap[0x4b] = SDLK_LSHIFT; | ||
125 | keymap[0x4c] = SDLK_z; | ||
126 | keymap[0x4d] = SDLK_x; | ||
127 | keymap[0x4e] = SDLK_c; | ||
128 | keymap[0x4f] = SDLK_v; | ||
129 | keymap[0x50] = SDLK_b; | ||
130 | keymap[0x51] = SDLK_n; | ||
131 | keymap[0x52] = SDLK_m; | ||
132 | keymap[0x53] = SDLK_COMMA; | ||
133 | keymap[0x54] = SDLK_PERIOD; | ||
134 | keymap[0x55] = SDLK_SLASH; | ||
135 | keymap[0x56] = SDLK_RSHIFT; | ||
136 | keymap[0x57] = SDLK_UP; | ||
137 | keymap[0x58] = SDLK_KP1; | ||
138 | keymap[0x59] = SDLK_KP2; | ||
139 | keymap[0x5a] = SDLK_KP3; | ||
140 | keymap[0x5b] = SDLK_KP_ENTER; | ||
141 | keymap[0x5c] = SDLK_LCTRL; | ||
142 | keymap[0x5d] = SDLK_LALT; | ||
143 | keymap[0x5e] = SDLK_SPACE; | ||
144 | keymap[0x5f] = SDLK_RALT; | ||
145 | keymap[0x60] = SDLK_RCTRL; | ||
146 | keymap[0x61] = SDLK_LEFT; | ||
147 | keymap[0x62] = SDLK_DOWN; | ||
148 | keymap[0x63] = SDLK_RIGHT; | ||
149 | keymap[0x64] = SDLK_KP0; | ||
150 | keymap[0x65] = SDLK_KP_PERIOD; | ||
151 | keymap[0x66] = SDLK_LMETA; | ||
152 | keymap[0x67] = SDLK_RMETA; | ||
153 | keymap[0x68] = SDLK_MENU; | ||
154 | keymap[0x69] = SDLK_EURO; | ||
155 | keymap[0x6a] = SDLK_KP_EQUALS; | ||
156 | keymap[0x6b] = SDLK_POWER; | ||
157 | } | ||
158 | |||
159 | }; /* Extern C */ | ||
160 | |||
161 | void SDL_BWin::DispatchMessage(BMessage *msg, BHandler *target) | ||
162 | { | ||
163 | switch (msg->what) { | ||
164 | case B_MOUSE_MOVED: | ||
165 | { | ||
166 | SDL_VideoDevice *view = current_video; | ||
167 | BPoint where; | ||
168 | int32 transit; | ||
169 | if (msg->FindPoint("where", &where) == B_OK && msg->FindInt32("be:transit", &transit) == B_OK) { | ||
170 | int x, y; | ||
171 | |||
172 | GetXYOffset(x, y); | ||
173 | x = (int)where.x - x; | ||
174 | y = (int)where.y - y; | ||
175 | |||
176 | //BeSman: I need another method for cursor catching !!! | ||
177 | if (view->input_grab != SDL_GRAB_OFF) | ||
178 | { | ||
179 | bool clipped = false; | ||
180 | if ( x < 0 ) { | ||
181 | x = 0; | ||
182 | clipped = true; | ||
183 | } else if ( x >= SDL_VideoSurface->w ) { | ||
184 | x = (SDL_VideoSurface->w-1); | ||
185 | clipped = true; | ||
186 | } | ||
187 | if ( y < 0 ) { | ||
188 | y = 0; | ||
189 | clipped = true; | ||
190 | } else if ( y >= SDL_VideoSurface->h ) { | ||
191 | y = (SDL_VideoSurface->h-1); | ||
192 | clipped = true; | ||
193 | } | ||
194 | if ( clipped ) { | ||
195 | BPoint edge; | ||
196 | GetXYOffset(edge.x, edge.y); | ||
197 | edge.x += x; | ||
198 | edge.y += y; | ||
199 | ConvertToScreen(&edge); | ||
200 | set_mouse_position((int)edge.x, (int)edge.y); | ||
201 | } | ||
202 | transit = B_INSIDE_VIEW; | ||
203 | } | ||
204 | if (transit == B_EXITED_VIEW) { | ||
205 | if ( SDL_GetAppState() & SDL_APPMOUSEFOCUS ) { | ||
206 | SDL_PrivateAppActive(0, SDL_APPMOUSEFOCUS); | ||
207 | #if SDL_VIDEO_OPENGL | ||
208 | // for some reason, SDL_EraseCursor fails for OpenGL | ||
209 | if (this->the_view != this->SDL_GLView) | ||
210 | #endif | ||
211 | SDL_EraseCursor(SDL_VideoSurface); | ||
212 | be_app->SetCursor(B_HAND_CURSOR); | ||
213 | } | ||
214 | } else { | ||
215 | if ( !(SDL_GetAppState() & SDL_APPMOUSEFOCUS) ) { | ||
216 | SDL_PrivateAppActive(1, SDL_APPMOUSEFOCUS); | ||
217 | #if SDL_VIDEO_OPENGL | ||
218 | // for some reason, SDL_EraseCursor fails for OpenGL | ||
219 | if (this->the_view != this->SDL_GLView) | ||
220 | #endif | ||
221 | SDL_EraseCursor(SDL_VideoSurface); | ||
222 | SDL_SetCursor(NULL); | ||
223 | } | ||
224 | |||
225 | if ( mouse_relative ) { | ||
226 | int half_w = (SDL_VideoSurface->w/2); | ||
227 | int half_h = (SDL_VideoSurface->h/2); | ||
228 | x -= half_w; | ||
229 | y -= half_h; | ||
230 | if ( x || y ) { | ||
231 | BPoint center; | ||
232 | GetXYOffset(center.x, center.y); | ||
233 | center.x += half_w; | ||
234 | center.y += half_h; | ||
235 | ConvertToScreen(¢er); | ||
236 | set_mouse_position((int)center.x, (int)center.y); | ||
237 | SDL_PrivateMouseMotion(0, 1, x, y); | ||
238 | } | ||
239 | } else { | ||
240 | SDL_PrivateMouseMotion(0, 0, x, y); | ||
241 | } | ||
242 | } | ||
243 | } | ||
244 | break; | ||
245 | } | ||
246 | |||
247 | case B_MOUSE_DOWN: | ||
248 | { | ||
249 | /* it looks like mouse down is send only for first clicked | ||
250 | button, each next is not send while last one is holded */ | ||
251 | int32 buttons; | ||
252 | int sdl_buttons = 0; | ||
253 | if (msg->FindInt32("buttons", &buttons) == B_OK) { | ||
254 | /* Add any mouse button events */ | ||
255 | if (buttons & B_PRIMARY_MOUSE_BUTTON) { | ||
256 | sdl_buttons |= SDL_BUTTON_LEFT; | ||
257 | } | ||
258 | if (buttons & B_SECONDARY_MOUSE_BUTTON) { | ||
259 | sdl_buttons |= SDL_BUTTON_RIGHT; | ||
260 | } | ||
261 | if (buttons & B_TERTIARY_MOUSE_BUTTON) { | ||
262 | sdl_buttons |= SDL_BUTTON_MIDDLE; | ||
263 | } | ||
264 | SDL_PrivateMouseButton(SDL_PRESSED, sdl_buttons, 0, 0); | ||
265 | |||
266 | last_buttons = buttons; | ||
267 | } | ||
268 | break; | ||
269 | } | ||
270 | |||
271 | case B_MOUSE_UP: | ||
272 | { | ||
273 | /* mouse up doesn't give which button was released, | ||
274 | only state of buttons (after release, so it's always = 0), | ||
275 | which is not what we need ;] | ||
276 | So we need to store button in mouse down, and restore | ||
277 | in mouse up :( | ||
278 | mouse up is (similarly to mouse down) send only for | ||
279 | first button down (ie. it's no send if we click another button | ||
280 | without releasing previous one first) - but that's probably | ||
281 | because of how drivers are written?, not BeOS itself. */ | ||
282 | int32 buttons; | ||
283 | int sdl_buttons = 0; | ||
284 | if (msg->FindInt32("buttons", &buttons) == B_OK) { | ||
285 | /* Add any mouse button events */ | ||
286 | if ((buttons ^ B_PRIMARY_MOUSE_BUTTON) & last_buttons) { | ||
287 | sdl_buttons |= SDL_BUTTON_LEFT; | ||
288 | } | ||
289 | if ((buttons ^ B_SECONDARY_MOUSE_BUTTON) & last_buttons) { | ||
290 | sdl_buttons |= SDL_BUTTON_RIGHT; | ||
291 | } | ||
292 | if ((buttons ^ B_TERTIARY_MOUSE_BUTTON) & last_buttons) { | ||
293 | sdl_buttons |= SDL_BUTTON_MIDDLE; | ||
294 | } | ||
295 | SDL_PrivateMouseButton(SDL_RELEASED, sdl_buttons, 0, 0); | ||
296 | |||
297 | last_buttons = buttons; | ||
298 | } | ||
299 | break; | ||
300 | } | ||
301 | |||
302 | case B_MOUSE_WHEEL_CHANGED: | ||
303 | { | ||
304 | float x, y; | ||
305 | x = y = 0; | ||
306 | if (msg->FindFloat("be:wheel_delta_x", &x) == B_OK && msg->FindFloat("be:wheel_delta_y", &y) == B_OK) { | ||
307 | if (x < 0 || y < 0) { | ||
308 | SDL_PrivateMouseButton(SDL_PRESSED, SDL_BUTTON_WHEELDOWN, 0, 0); | ||
309 | SDL_PrivateMouseButton(SDL_RELEASED, SDL_BUTTON_WHEELDOWN, 0, 0); | ||
310 | } else if (x > 0 || y > 0) { | ||
311 | SDL_PrivateMouseButton(SDL_PRESSED, SDL_BUTTON_WHEELUP, 0, 0); | ||
312 | SDL_PrivateMouseButton(SDL_RELEASED, SDL_BUTTON_WHEELUP, 0, 0); | ||
313 | } | ||
314 | } | ||
315 | break; | ||
316 | } | ||
317 | |||
318 | case B_KEY_DOWN: | ||
319 | case B_UNMAPPED_KEY_DOWN: /* modifier keys are unmapped */ | ||
320 | { | ||
321 | int32 key; | ||
322 | int32 modifiers; | ||
323 | int32 key_repeat; | ||
324 | /* Workaround for SDL message queue being filled too fast because of BeOS own key-repeat mechanism */ | ||
325 | if (msg->FindInt32("be:key_repeat", &key_repeat) == B_OK && key_repeat > 0) | ||
326 | break; | ||
327 | |||
328 | if (msg->FindInt32("key", &key) == B_OK && msg->FindInt32("modifiers", &modifiers) == B_OK) { | ||
329 | SDL_keysym keysym; | ||
330 | keysym.scancode = key; | ||
331 | if (key < 128) { | ||
332 | keysym.sym = keymap[key]; | ||
333 | } else { | ||
334 | keysym.sym = SDLK_UNKNOWN; | ||
335 | } | ||
336 | /* FIX THIS? | ||
337 | it seems SDL_PrivateKeyboard() changes mod value | ||
338 | anyway, and doesn't care about what we setup here */ | ||
339 | keysym.mod = KMOD_NONE; | ||
340 | keysym.unicode = 0; | ||
341 | if (SDL_TranslateUNICODE) { | ||
342 | const char *bytes; | ||
343 | if (msg->FindString("bytes", &bytes) == B_OK) { | ||
344 | /* FIX THIS? | ||
345 | this cares only about first "letter", | ||
346 | so if someone maps some key to print | ||
347 | "BeOS rulez!" only "B" will be used. */ | ||
348 | keysym.unicode = Translate2Unicode(bytes); | ||
349 | } | ||
350 | } | ||
351 | SDL_PrivateKeyboard(SDL_PRESSED, &keysym); | ||
352 | } | ||
353 | break; | ||
354 | } | ||
355 | |||
356 | case B_KEY_UP: | ||
357 | case B_UNMAPPED_KEY_UP: /* modifier keys are unmapped */ | ||
358 | { | ||
359 | int32 key; | ||
360 | int32 modifiers; | ||
361 | if (msg->FindInt32("key", &key) == B_OK && msg->FindInt32("modifiers", &modifiers) == B_OK) { | ||
362 | SDL_keysym keysym; | ||
363 | keysym.scancode = key; | ||
364 | if (key < 128) { | ||
365 | keysym.sym = keymap[key]; | ||
366 | } else { | ||
367 | keysym.sym = SDLK_UNKNOWN; | ||
368 | } | ||
369 | keysym.mod = KMOD_NONE; /* FIX THIS? */ | ||
370 | keysym.unicode = 0; | ||
371 | if (SDL_TranslateUNICODE) { | ||
372 | const char *bytes; | ||
373 | if (msg->FindString("bytes", &bytes) == B_OK) { | ||
374 | keysym.unicode = Translate2Unicode(bytes); | ||
375 | } | ||
376 | } | ||
377 | SDL_PrivateKeyboard(SDL_RELEASED, &keysym); | ||
378 | } | ||
379 | break; | ||
380 | } | ||
381 | |||
382 | default: | ||
383 | /* move it after switch{} so it's always handled | ||
384 | that way we keep BeOS feautures like: | ||
385 | - CTRL+Q to close window (and other shortcuts) | ||
386 | - PrintScreen to make screenshot into /boot/home | ||
387 | - etc.. */ | ||
388 | //BDirectWindow::DispatchMessage(msg, target); | ||
389 | break; | ||
390 | } | ||
391 | BDirectWindow::DispatchMessage(msg, target); | ||
392 | } | ||
393 | |||
394 | void SDL_BWin::DirectConnected(direct_buffer_info *info) { | ||
395 | switch (info->buffer_state & B_DIRECT_MODE_MASK) { | ||
396 | case B_DIRECT_START: | ||
397 | case B_DIRECT_MODIFY: | ||
398 | { | ||
399 | int32 width = info->window_bounds.right - | ||
400 | info->window_bounds.left; | ||
401 | int32 height = info->window_bounds.bottom - | ||
402 | info->window_bounds.top; | ||
403 | SDL_PrivateResize(width, height); | ||
404 | break; | ||
405 | } | ||
406 | default: | ||
407 | break; | ||
408 | } | ||
409 | #if SDL_VIDEO_OPENGL | ||
410 | // If it is a BGLView, it is apparently required to | ||
411 | // call DirectConnected() on it as well | ||
412 | if (this->the_view == this->SDL_GLView) | ||
413 | this->SDL_GLView->DirectConnected(info); | ||
414 | #endif | ||
415 | } | ||