| /* |
| * Copyright (C) 2006 Claudio Ciccani <klan@users.sf.net> |
| * |
| * 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 <stdio.h> |
| #include <stdlib.h> |
| #include <unistd.h> |
| |
| #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 ); |
| } |
| } |
| } |
| } |
| |