Merge branch 'mesa_7_5_branch'
[mesa.git] / src / glut / directfb / events.c
1 /*
2 * Copyright (C) 2006 Claudio Ciccani <klan@users.sf.net>
3 *
4 * This library is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU Lesser General Public
6 * License as published by the Free Software Foundation; either
7 * version 2 of the License, or (at your option) any later version.
8 *
9 * This library is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 * Lesser General Public License for more details.
13 *
14 * You should have received a copy of the GNU Lesser General Public
15 * License along with this library; if not, write to the Free Software
16 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
17 *
18 */
19
20 #include <stdio.h>
21 #include <stdlib.h>
22 #include <unistd.h>
23
24 #include "internal.h"
25
26
27 /*****************************************************************************/
28
29 static int g_ignore_key_repeat = 0;
30
31 /*****************************************************************************/
32
33
34 int GLUTAPIENTRY
35 glutDeviceGet( GLenum type )
36 {
37 switch (type) {
38 case GLUT_HAS_KEYBOARD:
39 return (keyboard != NULL);
40 case GLUT_HAS_MOUSE:
41 return (mouse != NULL);
42 case GLUT_NUM_MOUSE_BUTTONS:
43 if (mouse) {
44 DFBInputDeviceDescription dsc;
45 mouse->GetDescription( mouse, &dsc );
46 return dsc.max_button+1;
47 }
48 break;
49 case GLUT_DEVICE_IGNORE_KEY_REPEAT:
50 return g_ignore_key_repeat;
51 case GLUT_DEVICE_KEY_REPEAT:
52 return (g_ignore_key_repeat) ? GLUT_KEY_REPEAT_OFF
53 : GLUT_KEY_REPEAT_ON;
54 case GLUT_HAS_JOYSTICK:
55 case GLUT_OWNS_JOYSTICK:
56 return (g_game && joystick); /* only available in game mode */
57 case GLUT_JOYSTICK_BUTTONS:
58 if (joystick) {
59 DFBInputDeviceDescription dsc;
60 joystick->GetDescription( joystick, &dsc );
61 return dsc.max_button+1;
62 }
63 break;
64 case GLUT_JOYSTICK_AXES:
65 if (joystick) {
66 DFBInputDeviceDescription dsc;
67 joystick->GetDescription( joystick, &dsc );
68 return dsc.max_axis+1;
69 }
70 break;
71 case GLUT_JOYSTICK_POLL_RATE:
72 if (joystick)
73 return 1; /* hack */
74 break;
75 default:
76 break;
77 }
78
79 return 0;
80 }
81
82
83 int GLUTAPIENTRY
84 glutGetModifiers( void )
85 {
86 if (g_current)
87 return g_current->modifiers;
88 return 0;
89 }
90
91
92 void GLUTAPIENTRY
93 glutIgnoreKeyRepeat( int ignore )
94 {
95 g_ignore_key_repeat = ignore;
96 }
97
98
99 void GLUTAPIENTRY
100 glutSetKeyRepeat( int mode )
101 {
102 g_ignore_key_repeat = (mode == GLUT_KEY_REPEAT_OFF);
103 }
104
105
106 void GLUTAPIENTRY
107 glutForceJoystickFunc( void )
108 {
109 if (g_game && joystick && joystick_func) {
110 joystick_func( g_game->buttons,
111 g_game->jx, g_game->jy, g_game->jz );
112 }
113 }
114
115
116 static int
117 __glutSpecialKey( DFBInputDeviceKeySymbol key )
118 {
119 switch (key) {
120 case DIKS_F1:
121 return GLUT_KEY_F1;
122 case DIKS_F2:
123 return GLUT_KEY_F2;
124 case DIKS_F3:
125 return GLUT_KEY_F3;
126 case DIKS_F4:
127 return GLUT_KEY_F4;
128 case DIKS_F5:
129 return GLUT_KEY_F5;
130 case DIKS_F6:
131 return GLUT_KEY_F6;
132 case DIKS_F7:
133 return GLUT_KEY_F7;
134 case DIKS_F8:
135 return GLUT_KEY_F8;
136 case DIKS_F9:
137 return GLUT_KEY_F9;
138 case DIKS_F10:
139 return GLUT_KEY_F10;
140 case DIKS_F11:
141 return GLUT_KEY_F11;
142 case DIKS_F12:
143 return GLUT_KEY_F12;
144 case DIKS_CURSOR_LEFT:
145 return GLUT_KEY_LEFT;
146 case DIKS_CURSOR_UP:
147 return GLUT_KEY_UP;
148 case DIKS_CURSOR_RIGHT:
149 return GLUT_KEY_RIGHT;
150 case DIKS_CURSOR_DOWN:
151 return GLUT_KEY_DOWN;
152 case DIKS_PAGE_UP:
153 return GLUT_KEY_PAGE_UP;
154 case DIKS_PAGE_DOWN:
155 return GLUT_KEY_PAGE_DOWN;
156 case DIKS_HOME:
157 return GLUT_KEY_HOME;
158 case DIKS_END:
159 return GLUT_KEY_END;
160 case DIKS_INSERT:
161 return GLUT_KEY_INSERT;
162 default:
163 break;
164 }
165
166 return 0;
167 }
168
169
170 static int
171 __glutButton( DFBInputDeviceButtonIdentifier button )
172 {
173 switch (button) {
174 case DIBI_LEFT:
175 return GLUT_LEFT_BUTTON;
176 case DIBI_MIDDLE:
177 return GLUT_MIDDLE_BUTTON;
178 case DIBI_RIGHT:
179 return GLUT_RIGHT_BUTTON;
180 default:
181 break;
182 }
183
184 return 0;
185 }
186
187
188 static int
189 __glutModifiers( DFBInputDeviceModifierMask mask )
190 {
191 return ((mask & DIMM_SHIFT) ? GLUT_ACTIVE_SHIFT : 0) |
192 ((mask & DIMM_CONTROL) ? GLUT_ACTIVE_CTRL : 0) |
193 ((mask & DIMM_ALT) ? GLUT_ACTIVE_ALT : 0);
194 }
195
196
197 static void
198 __glutWindowEvent( DFBWindowEvent *e, DFBWindowEvent *p )
199 {
200 __GlutWindow *window;
201
202 window = __glutFindWindow( e->window_id );
203 if (!window) /* window was destroyed */
204 return;
205
206 switch (e->type) {
207 case DWET_KEYDOWN:
208 window->modifiers = __glutModifiers( e->modifiers );
209 if (g_ignore_key_repeat && p) {
210 if (p->type == DWET_KEYDOWN &&
211 p->window_id == e->window_id &&
212 p->key_symbol == e->key_symbol)
213 break;
214 }
215 if (DFB_KEY_IS_ASCII( e->key_symbol )) {
216 if (keyboard_func) {
217 __glutSetWindow( window );
218 keyboard_func( e->key_symbol, e->x, e->y );
219 }
220 }
221 else {
222 int key = __glutSpecialKey( e->key_symbol );
223 if (key && special_func) {
224 __glutSetWindow( window );
225 special_func( key, e->x, e->y );
226 }
227 }
228 break;
229 case DWET_KEYUP:
230 window->modifiers = __glutModifiers( e->modifiers );
231 if (DFB_KEY_IS_ASCII( e->key_symbol )) {
232 if (keyboard_up_func) {
233 __glutSetWindow( window );
234 keyboard_up_func( e->key_symbol, e->x, e->y );
235 }
236 }
237 else {
238 int key = __glutSpecialKey( e->key_symbol );
239 if (key && special_up_func) {
240 __glutSetWindow( window );
241 special_up_func( key, e->x, e->y );
242 }
243 }
244 break;
245 case DWET_BUTTONDOWN:
246 if (mouse_func) {
247 __glutSetWindow( window );
248 mouse_func( __glutButton( e->button ), GLUT_DOWN, e->x, e->y );
249 }
250 break;
251 case DWET_BUTTONUP:
252 if (mouse_func) {
253 __glutSetWindow( window );
254 mouse_func( __glutButton( e->button ), GLUT_UP, e->x, e->y );
255 }
256 break;
257 case DWET_MOTION:
258 if (e->buttons) {
259 if (motion_func) {
260 __glutSetWindow( window );
261 motion_func( e->cx, e->cy );
262 }
263 }
264 else {
265 if (passive_motion_func) {
266 __glutSetWindow( window );
267 passive_motion_func( e->cx, e->cy );
268 }
269 }
270 break;
271 case DWET_ENTER:
272 if (entry_func) {
273 __glutSetWindow( window );
274 entry_func( GLUT_ENTERED );
275 }
276 break;
277 case DWET_LEAVE:
278 if (entry_func) {
279 __glutSetWindow( window );
280 entry_func( GLUT_LEFT );
281 }
282 break;
283 case DWET_SIZE:
284 window->reshape = GL_TRUE;
285 window->redisplay = GL_TRUE;
286 break;
287 default:
288 break;
289 }
290 }
291
292
293 static void
294 __glutInputEvent( DFBInputEvent *e, DFBInputEvent *p )
295 {
296 __glutAssert( g_game != NULL );
297
298 switch (e->type) {
299 case DIET_KEYPRESS:
300 g_game->modifiers = __glutModifiers( e->modifiers );
301 if (g_ignore_key_repeat && p) {
302 if (p->type == DIET_KEYPRESS &&
303 p->key_symbol == e->key_symbol)
304 break;
305 }
306 if (DFB_KEY_IS_ASCII( e->key_symbol )) {
307 if (keyboard_func) {
308 __glutSetWindow( g_game );
309 keyboard_func( e->key_symbol, g_game->cx, g_game->cy );
310 }
311 }
312 else {
313 int key = __glutSpecialKey( e->key_symbol );
314 if (key && special_func) {
315 __glutSetWindow( g_game );
316 special_func( key, g_game->cx, g_game->cy );
317 }
318 }
319 break;
320 case DIET_KEYRELEASE:
321 g_game->modifiers = __glutModifiers( e->modifiers );
322 if (DFB_KEY_IS_ASCII( e->key_symbol )) {
323 if (keyboard_up_func) {
324 __glutSetWindow( g_game );
325 keyboard_up_func( e->key_symbol, g_game->cx, g_game->cy );
326 }
327 }
328 else {
329 int key = __glutSpecialKey( e->key_symbol );
330 if (key && special_up_func) {
331 __glutSetWindow( g_game );
332 special_up_func( key, g_game->cx, g_game->cy );
333 }
334 }
335 break;
336 case DIET_BUTTONPRESS:
337 if (e->device_id == DIDID_JOYSTICK) {
338 g_game->buttons = e->buttons;
339 if (joystick_func) {
340 __glutSetWindow( g_game );
341 joystick_func( g_game->buttons,
342 g_game->jx, g_game->jy, g_game->jz );
343 }
344 }
345 else {
346 if (mouse_func) {
347 __glutSetWindow( g_game );
348 mouse_func( __glutButton( e->button ),
349 GLUT_DOWN, g_game->cx, g_game->cy );
350 }
351 }
352 break;
353 case DIET_BUTTONRELEASE:
354 if (e->device_id == DIDID_JOYSTICK) {
355 g_game->buttons = e->buttons;
356 if (joystick_func) {
357 __glutSetWindow( g_game );
358 joystick_func( g_game->buttons,
359 g_game->jx, g_game->jy, g_game->jz );
360 }
361 }
362 else {
363 if (mouse_func) {
364 __glutSetWindow( g_game );
365 mouse_func( __glutButton( e->button ),
366 GLUT_UP, g_game->cx, g_game->cy );
367 }
368 }
369 break;
370 case DIET_AXISMOTION:
371 if (e->device_id == DIDID_JOYSTICK) {
372 switch (e->axis) {
373 case DIAI_X:
374 if (e->flags & DIEF_AXISABS)
375 g_game->jx = e->axisabs;
376 else if (e->flags & DIEF_AXISREL)
377 g_game->jx += e->axisrel;
378 break;
379 case DIAI_Y:
380 if (e->flags & DIEF_AXISABS)
381 g_game->jy = e->axisabs;
382 else if (e->flags & DIEF_AXISREL)
383 g_game->jy += e->axisrel;
384 break;
385 case DIAI_Z:
386 if (e->flags & DIEF_AXISABS)
387 g_game->jz = e->axisabs;
388 else if (e->flags & DIEF_AXISREL)
389 g_game->jz += e->axisrel;
390 break;
391 default:
392 break;
393 }
394 if (joystick_func) {
395 __glutSetWindow( g_game );
396 joystick_func( g_game->buttons,
397 g_game->jx, g_game->jy, g_game->jz );
398 }
399 }
400 else {
401 switch (e->axis) {
402 case DIAI_X:
403 if (e->flags & DIEF_AXISABS)
404 g_game->cx = e->axisabs;
405 else if (e->flags & DIEF_AXISREL)
406 g_game->cx += e->axisrel;
407 break;
408 case DIAI_Y:
409 if (e->flags & DIEF_AXISABS)
410 g_game->cy = e->axisabs;
411 else if (e->flags & DIEF_AXISREL)
412 g_game->cy += e->axisrel;
413 break;
414 default:
415 return;
416 }
417 if (e->buttons && motion_func) {
418 __glutSetWindow( g_game );
419 motion_func( g_game->cx, g_game->cy );
420 }
421 else if (!e->buttons && passive_motion_func) {
422 __glutSetWindow( g_game );
423 passive_motion_func( g_game->cx, g_game->cy );
424 }
425 }
426 break;
427 default:
428 break;
429 }
430 }
431
432
433 void GLUTAPIENTRY
434 glutMainLoop( void )
435 {
436 __glutAssert( events != NULL );
437
438 __glutHandleWindows();
439
440 while (GL_TRUE) {
441 DFBEvent evt, prev;
442
443 g_idle = GL_TRUE;
444
445 __glutHandleTimers();
446
447 prev.clazz = DFEC_NONE;
448
449 while (events->GetEvent( events, &evt ) == DFB_OK) {
450 g_idle = GL_FALSE;
451
452 switch (evt.clazz) {
453 case DFEC_WINDOW:
454 if (prev.clazz == DFEC_WINDOW)
455 __glutWindowEvent( &evt.window, &prev.window );
456 else
457 __glutWindowEvent( &evt.window, NULL );
458 break;
459 case DFEC_INPUT:
460 if (prev.clazz == DFEC_INPUT)
461 __glutInputEvent( &evt.input, &prev.input );
462 else
463 __glutInputEvent( &evt.input, NULL );
464 break;
465 default:
466 __glutWarning( "unexpected event class %d!\n", evt.clazz );
467 break;
468 }
469
470 prev = evt;
471
472 __glutHandleTimers();
473 }
474
475 __glutHandleWindows();
476
477 if (g_idle) {
478 if (idle_func) {
479 idle_func();
480 }
481 else {
482 int msec;
483 __glutSetWindow( NULL );
484 if (__glutGetTimeout( &msec ))
485 events->WaitForEventWithTimeout( events, msec/1000, msec%1000 );
486 else
487 events->WaitForEvent( events );
488 }
489 }
490 }
491 }
492