/* * Copyright (C) 2006 Claudio Ciccani * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * */ #include #include #include #include "internal.h" /*****************************************************************************/ static int g_ignore_key_repeat = 0; /*****************************************************************************/ int GLUTAPIENTRY glutDeviceGet( GLenum type ) { switch (type) { case GLUT_HAS_KEYBOARD: return (keyboard != NULL); case GLUT_HAS_MOUSE: return (mouse != NULL); case GLUT_NUM_MOUSE_BUTTONS: if (mouse) { DFBInputDeviceDescription dsc; mouse->GetDescription( mouse, &dsc ); return dsc.max_button+1; } break; case GLUT_DEVICE_IGNORE_KEY_REPEAT: return g_ignore_key_repeat; case GLUT_DEVICE_KEY_REPEAT: return (g_ignore_key_repeat) ? GLUT_KEY_REPEAT_OFF : GLUT_KEY_REPEAT_ON; case GLUT_HAS_JOYSTICK: case GLUT_OWNS_JOYSTICK: return (g_game && joystick); /* only available in game mode */ case GLUT_JOYSTICK_BUTTONS: if (joystick) { DFBInputDeviceDescription dsc; joystick->GetDescription( joystick, &dsc ); return dsc.max_button+1; } break; case GLUT_JOYSTICK_AXES: if (joystick) { DFBInputDeviceDescription dsc; joystick->GetDescription( joystick, &dsc ); return dsc.max_axis+1; } break; case GLUT_JOYSTICK_POLL_RATE: if (joystick) return 1; /* hack */ break; default: break; } return 0; } int GLUTAPIENTRY glutGetModifiers( void ) { if (g_current) return g_current->modifiers; return 0; } void GLUTAPIENTRY glutIgnoreKeyRepeat( int ignore ) { g_ignore_key_repeat = ignore; } void GLUTAPIENTRY glutSetKeyRepeat( int mode ) { g_ignore_key_repeat = (mode == GLUT_KEY_REPEAT_OFF); } void GLUTAPIENTRY glutForceJoystickFunc( void ) { if (g_game && joystick && joystick_func) { joystick_func( g_game->buttons, g_game->jx, g_game->jy, g_game->jz ); } } static int __glutSpecialKey( DFBInputDeviceKeySymbol key ) { switch (key) { case DIKS_F1: return GLUT_KEY_F1; case DIKS_F2: return GLUT_KEY_F2; case DIKS_F3: return GLUT_KEY_F3; case DIKS_F4: return GLUT_KEY_F4; case DIKS_F5: return GLUT_KEY_F5; case DIKS_F6: return GLUT_KEY_F6; case DIKS_F7: return GLUT_KEY_F7; case DIKS_F8: return GLUT_KEY_F8; case DIKS_F9: return GLUT_KEY_F9; case DIKS_F10: return GLUT_KEY_F10; case DIKS_F11: return GLUT_KEY_F11; case DIKS_F12: return GLUT_KEY_F12; case DIKS_CURSOR_LEFT: return GLUT_KEY_LEFT; case DIKS_CURSOR_UP: return GLUT_KEY_UP; case DIKS_CURSOR_RIGHT: return GLUT_KEY_RIGHT; case DIKS_CURSOR_DOWN: return GLUT_KEY_DOWN; case DIKS_PAGE_UP: return GLUT_KEY_PAGE_UP; case DIKS_PAGE_DOWN: return GLUT_KEY_PAGE_DOWN; case DIKS_HOME: return GLUT_KEY_HOME; case DIKS_END: return GLUT_KEY_END; case DIKS_INSERT: return GLUT_KEY_INSERT; default: break; } return 0; } static int __glutButton( DFBInputDeviceButtonIdentifier button ) { switch (button) { case DIBI_LEFT: return GLUT_LEFT_BUTTON; case DIBI_MIDDLE: return GLUT_MIDDLE_BUTTON; case DIBI_RIGHT: return GLUT_RIGHT_BUTTON; default: break; } return 0; } static int __glutModifiers( DFBInputDeviceModifierMask mask ) { return ((mask & DIMM_SHIFT) ? GLUT_ACTIVE_SHIFT : 0) | ((mask & DIMM_CONTROL) ? GLUT_ACTIVE_CTRL : 0) | ((mask & DIMM_ALT) ? GLUT_ACTIVE_ALT : 0); } static void __glutWindowEvent( DFBWindowEvent *e, DFBWindowEvent *p ) { __GlutWindow *window; window = __glutFindWindow( e->window_id ); if (!window) /* window was destroyed */ return; switch (e->type) { case DWET_KEYDOWN: window->modifiers = __glutModifiers( e->modifiers ); if (g_ignore_key_repeat && p) { if (p->type == DWET_KEYDOWN && p->window_id == e->window_id && p->key_symbol == e->key_symbol) break; } if (DFB_KEY_IS_ASCII( e->key_symbol )) { if (keyboard_func) { __glutSetWindow( window ); keyboard_func( e->key_symbol, e->x, e->y ); } } else { int key = __glutSpecialKey( e->key_symbol ); if (key && special_func) { __glutSetWindow( window ); special_func( key, e->x, e->y ); } } break; case DWET_KEYUP: window->modifiers = __glutModifiers( e->modifiers ); if (DFB_KEY_IS_ASCII( e->key_symbol )) { if (keyboard_up_func) { __glutSetWindow( window ); keyboard_up_func( e->key_symbol, e->x, e->y ); } } else { int key = __glutSpecialKey( e->key_symbol ); if (key && special_up_func) { __glutSetWindow( window ); special_up_func( key, e->x, e->y ); } } break; case DWET_BUTTONDOWN: if (mouse_func) { __glutSetWindow( window ); mouse_func( __glutButton( e->button ), GLUT_DOWN, e->x, e->y ); } break; case DWET_BUTTONUP: if (mouse_func) { __glutSetWindow( window ); mouse_func( __glutButton( e->button ), GLUT_UP, e->x, e->y ); } break; case DWET_MOTION: if (e->buttons) { if (motion_func) { __glutSetWindow( window ); motion_func( e->cx, e->cy ); } } else { if (passive_motion_func) { __glutSetWindow( window ); passive_motion_func( e->cx, e->cy ); } } break; case DWET_ENTER: if (entry_func) { __glutSetWindow( window ); entry_func( GLUT_ENTERED ); } break; case DWET_LEAVE: if (entry_func) { __glutSetWindow( window ); entry_func( GLUT_LEFT ); } break; case DWET_SIZE: window->reshape = GL_TRUE; window->redisplay = GL_TRUE; break; default: break; } } static void __glutInputEvent( DFBInputEvent *e, DFBInputEvent *p ) { __glutAssert( g_game != NULL ); switch (e->type) { case DIET_KEYPRESS: g_game->modifiers = __glutModifiers( e->modifiers ); if (g_ignore_key_repeat && p) { if (p->type == DIET_KEYPRESS && p->key_symbol == e->key_symbol) break; } if (DFB_KEY_IS_ASCII( e->key_symbol )) { if (keyboard_func) { __glutSetWindow( g_game ); keyboard_func( e->key_symbol, g_game->cx, g_game->cy ); } } else { int key = __glutSpecialKey( e->key_symbol ); if (key && special_func) { __glutSetWindow( g_game ); special_func( key, g_game->cx, g_game->cy ); } } break; case DIET_KEYRELEASE: g_game->modifiers = __glutModifiers( e->modifiers ); if (DFB_KEY_IS_ASCII( e->key_symbol )) { if (keyboard_up_func) { __glutSetWindow( g_game ); keyboard_up_func( e->key_symbol, g_game->cx, g_game->cy ); } } else { int key = __glutSpecialKey( e->key_symbol ); if (key && special_up_func) { __glutSetWindow( g_game ); special_up_func( key, g_game->cx, g_game->cy ); } } break; case DIET_BUTTONPRESS: if (e->device_id == DIDID_JOYSTICK) { g_game->buttons = e->buttons; if (joystick_func) { __glutSetWindow( g_game ); joystick_func( g_game->buttons, g_game->jx, g_game->jy, g_game->jz ); } } else { if (mouse_func) { __glutSetWindow( g_game ); mouse_func( __glutButton( e->button ), GLUT_DOWN, g_game->cx, g_game->cy ); } } break; case DIET_BUTTONRELEASE: if (e->device_id == DIDID_JOYSTICK) { g_game->buttons = e->buttons; if (joystick_func) { __glutSetWindow( g_game ); joystick_func( g_game->buttons, g_game->jx, g_game->jy, g_game->jz ); } } else { if (mouse_func) { __glutSetWindow( g_game ); mouse_func( __glutButton( e->button ), GLUT_UP, g_game->cx, g_game->cy ); } } break; case DIET_AXISMOTION: if (e->device_id == DIDID_JOYSTICK) { switch (e->axis) { case DIAI_X: if (e->flags & DIEF_AXISABS) g_game->jx = e->axisabs; else if (e->flags & DIEF_AXISREL) g_game->jx += e->axisrel; break; case DIAI_Y: if (e->flags & DIEF_AXISABS) g_game->jy = e->axisabs; else if (e->flags & DIEF_AXISREL) g_game->jy += e->axisrel; break; case DIAI_Z: if (e->flags & DIEF_AXISABS) g_game->jz = e->axisabs; else if (e->flags & DIEF_AXISREL) g_game->jz += e->axisrel; break; default: break; } if (joystick_func) { __glutSetWindow( g_game ); joystick_func( g_game->buttons, g_game->jx, g_game->jy, g_game->jz ); } } else { switch (e->axis) { case DIAI_X: if (e->flags & DIEF_AXISABS) g_game->cx = e->axisabs; else if (e->flags & DIEF_AXISREL) g_game->cx += e->axisrel; break; case DIAI_Y: if (e->flags & DIEF_AXISABS) g_game->cy = e->axisabs; else if (e->flags & DIEF_AXISREL) g_game->cy += e->axisrel; break; default: return; } if (e->buttons && motion_func) { __glutSetWindow( g_game ); motion_func( g_game->cx, g_game->cy ); } else if (!e->buttons && passive_motion_func) { __glutSetWindow( g_game ); passive_motion_func( g_game->cx, g_game->cy ); } } break; default: break; } } void GLUTAPIENTRY glutMainLoop( void ) { __glutAssert( events != NULL ); __glutHandleWindows(); while (GL_TRUE) { DFBEvent evt, prev; g_idle = GL_TRUE; __glutHandleTimers(); prev.clazz = DFEC_NONE; while (events->GetEvent( events, &evt ) == DFB_OK) { g_idle = GL_FALSE; switch (evt.clazz) { case DFEC_WINDOW: if (prev.clazz == DFEC_WINDOW) __glutWindowEvent( &evt.window, &prev.window ); else __glutWindowEvent( &evt.window, NULL ); break; case DFEC_INPUT: if (prev.clazz == DFEC_INPUT) __glutInputEvent( &evt.input, &prev.input ); else __glutInputEvent( &evt.input, NULL ); break; default: __glutWarning( "unexpected event class %d!\n", evt.clazz ); break; } prev = evt; __glutHandleTimers(); } __glutHandleWindows(); if (g_idle) { if (idle_func) { idle_func(); } else { int msec; __glutSetWindow( NULL ); if (__glutGetTimeout( &msec )) events->WaitForEventWithTimeout( events, msec/1000, msec%1000 ); else events->WaitForEvent( events ); } } } }