comparison src/video/bwindow/SDL_sysevents.cc @ 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 376665398b25
children 1146681dbb74
comparison
equal deleted inserted replaced
3877:81f66f258d77 3878:678576473849
27 #include "SDL_error.h" 27 #include "SDL_error.h"
28 #include "SDL_events.h" 28 #include "SDL_events.h"
29 #include "SDL_BWin.h" 29 #include "SDL_BWin.h"
30 #include "SDL_lowvideo.h" 30 #include "SDL_lowvideo.h"
31 31
32 static SDLKey keymap[128];
33 int mouse_relative = 0;
32 extern "C" { 34 extern "C" {
33 35
34 #include "../../events/SDL_sysevents.h" 36 #include "../../events/SDL_sysevents.h"
35 #include "../../events/SDL_events_c.h" 37 #include "../../events/SDL_events_c.h"
36 #include "SDL_sysevents_c.h" 38 #include "SDL_sysevents_c.h"
39 { 41 {
40 } 42 }
41 43
42 void BE_InitOSKeymap(_THIS) 44 void BE_InitOSKeymap(_THIS)
43 { 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;
44 } 156 }
45 157
46 }; /* Extern C */ 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
170 //BeSman: I need another method for cursor catching !!!
171 if(view->input_grab != SDL_GRAB_OFF)
172 {
173 BPoint center;
174 center.x = (SDL_VideoSurface->w/2);
175 center.y = (SDL_VideoSurface->h/2);
176 BPoint delta = where - center;
177 if(delta.x > center.x)
178 SDL_WarpMouse((int)center.x*2,(int)where.y);
179
180 if(delta.x < -center.x)
181 SDL_WarpMouse(0,(int)where.y);
182
183 if(delta.y > center.y)
184 SDL_WarpMouse((int)where.x,(int)center.y*2);
185
186 if(delta.y < -center.y)
187 SDL_WarpMouse((int)where.x,0);
188
189
190 if((delta.x-1 < -center.x)&&(delta.y-1 < -center.y))
191 SDL_WarpMouse(1,1);
192
193 if((delta.x-1 < -center.x)&&(delta.y+1 > center.y))
194 SDL_WarpMouse(1,(int)center.y*2-1);
195
196 if((delta.x+1 > center.x)&&(delta.y-1 < -center.y))
197 SDL_WarpMouse((int)center.x*2-1,1);
198
199 if((delta.x+1 > center.x)&&(delta.y+1 > center.y))
200 SDL_WarpMouse((int)center.x*2-1,(int)center.y*2-1);
201
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
210 int x, y;
211 if ( ! (SDL_GetAppState() & SDL_APPMOUSEFOCUS) ) {
212 SDL_PrivateAppActive(1, SDL_APPMOUSEFOCUS);
213 SDL_SetCursor(NULL);
214 }
215 x = (int)where.x;
216 y = (int)where.y;
217
218 if ( mouse_relative ) {
219 BPoint center;
220 center.x = (SDL_VideoSurface->w/2);
221 center.y = (SDL_VideoSurface->h/2);
222 x -= (int)center.x;
223 y -= (int)center.y;
224 if ( x || y ) {
225 ConvertToScreen(&center);
226 set_mouse_position((int)center.x, (int)center.y);
227 SDL_PrivateMouseMotion(0, 1, x, y);
228 }
229 } else {
230 SDL_PrivateMouseMotion(0, 0, x, y);
231 }
232 }
233 }
234 break;
235 }
236
237 case B_MOUSE_DOWN:
238 {
239 /* it looks like mouse down is send only for first clicked
240 button, each next is not send while last one is holded */
241 int32 buttons;
242 int sdl_buttons = 0;
243 if (msg->FindInt32("buttons", &buttons) == B_OK) {
244 /* Add any mouse button events */
245 if (buttons & B_PRIMARY_MOUSE_BUTTON) {
246 sdl_buttons |= SDL_BUTTON_LEFT;
247 }
248 if (buttons & B_SECONDARY_MOUSE_BUTTON) {
249 sdl_buttons |= SDL_BUTTON_RIGHT;
250 }
251 if (buttons & B_TERTIARY_MOUSE_BUTTON) {
252 sdl_buttons |= SDL_BUTTON_MIDDLE;
253 }
254 SDL_PrivateMouseButton(SDL_PRESSED, sdl_buttons, 0, 0);
255
256 last_buttons = buttons;
257 }
258 break;
259 }
260
261 case B_MOUSE_UP:
262 {
263 /* mouse up doesn't give which button was released,
264 only state of buttons (after release, so it's always = 0),
265 which is not what we need ;]
266 So we need to store button in mouse down, and restore
267 in mouse up :(
268 mouse up is (similarly to mouse down) send only for
269 first button down (ie. it's no send if we click another button
270 without releasing previous one first) - but that's probably
271 because of how drivers are written?, not BeOS itself. */
272 int32 buttons;
273 int sdl_buttons = 0;
274 if (msg->FindInt32("buttons", &buttons) == B_OK) {
275 /* Add any mouse button events */
276 if ((buttons ^ B_PRIMARY_MOUSE_BUTTON) & last_buttons) {
277 sdl_buttons |= SDL_BUTTON_LEFT;
278 }
279 if ((buttons ^ B_SECONDARY_MOUSE_BUTTON) & last_buttons) {
280 sdl_buttons |= SDL_BUTTON_RIGHT;
281 }
282 if ((buttons ^ B_TERTIARY_MOUSE_BUTTON) & last_buttons) {
283 sdl_buttons |= SDL_BUTTON_MIDDLE;
284 }
285 SDL_PrivateMouseButton(SDL_RELEASED, sdl_buttons, 0, 0);
286
287 last_buttons = buttons;
288 }
289 break;
290 }
291
292 case B_MOUSE_WHEEL_CHANGED:
293 {
294 float x, y;
295 x = y = 0;
296 if (msg->FindFloat("be:wheel_delta_x", &x) == B_OK && msg->FindFloat("be:wheel_delta_y", &y) == B_OK) {
297 if (x < 0 || y < 0) {
298 SDL_PrivateMouseButton(SDL_PRESSED, SDL_BUTTON_WHEELDOWN, 0, 0);
299 SDL_PrivateMouseButton(SDL_RELEASED, SDL_BUTTON_WHEELDOWN, 0, 0);
300 } else if (x > 0 || y > 0) {
301 SDL_PrivateMouseButton(SDL_PRESSED, SDL_BUTTON_WHEELUP, 0, 0);
302 SDL_PrivateMouseButton(SDL_RELEASED, SDL_BUTTON_WHEELUP, 0, 0);
303 }
304 }
305 break;
306 }
307
308 case B_KEY_DOWN:
309 case B_UNMAPPED_KEY_DOWN: /* modifier keys are unmapped */
310 {
311 int32 key;
312 int32 modifiers;
313 int32 key_repeat;
314 /* Workaround for SDL message queue being filled too fast because of BeOS own key-repeat mechanism */
315 if (msg->FindInt32("be:key_repeat", &key_repeat) == B_OK && key_repeat > 0)
316 break;
317
318 if (msg->FindInt32("key", &key) == B_OK && msg->FindInt32("modifiers", &modifiers) == B_OK) {
319 SDL_keysym keysym;
320 keysym.scancode = key;
321 if (key < 128) {
322 keysym.sym = keymap[key];
323 } else {
324 keysym.sym = SDLK_UNKNOWN;
325 }
326 /* FIX THIS?
327 it seems SDL_PrivateKeyboard() changes mod value
328 anyway, and doesn't care about what we setup here */
329 keysym.mod = KMOD_NONE;
330 keysym.unicode = 0;
331 if (SDL_TranslateUNICODE) {
332 const char *bytes;
333 if (msg->FindString("bytes", &bytes) == B_OK) {
334 /* FIX THIS?
335 this cares only about first "letter",
336 so if someone maps some key to print
337 "BeOS rulez!" only "B" will be used. */
338 keysym.unicode = Translate2Unicode(bytes);
339 }
340 }
341 SDL_PrivateKeyboard(SDL_PRESSED, &keysym);
342 }
343 break;
344 }
345
346 case B_KEY_UP:
347 case B_UNMAPPED_KEY_UP: /* modifier keys are unmapped */
348 {
349 int32 key;
350 int32 modifiers;
351 if (msg->FindInt32("key", &key) == B_OK && msg->FindInt32("modifiers", &modifiers) == B_OK) {
352 SDL_keysym keysym;
353 keysym.scancode = key;
354 if (key < 128) {
355 keysym.sym = keymap[key];
356 } else {
357 keysym.sym = SDLK_UNKNOWN;
358 }
359 keysym.mod = KMOD_NONE; /* FIX THIS? */
360 keysym.unicode = 0;
361 if (SDL_TranslateUNICODE) {
362 const char *bytes;
363 if (msg->FindString("bytes", &bytes) == B_OK) {
364 keysym.unicode = Translate2Unicode(bytes);
365 }
366 }
367 SDL_PrivateKeyboard(SDL_RELEASED, &keysym);
368 }
369 break;
370 }
371
372 default:
373 /* move it after switch{} so it's always handled
374 that way we keep BeOS feautures like:
375 - CTRL+Q to close window (and other shortcuts)
376 - PrintScreen to make screenshot into /boot/home
377 - etc.. */
378 //BDirectWindow::DispatchMessage(msg, target);
379 break;
380 }
381 BDirectWindow::DispatchMessage(msg, target);
382 }