blob: 6ebdd166ac8ef65700a95f701410861edd7ff535 [file] [log] [blame]
/*
* 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 );
}
}
}
}