blob: 7c9768aac0adcab7fced6e00f7765f8480b5a55f [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 <string.h>
#include <sys/time.h>
#include "internal.h"
typedef void (GLUTCALLBACK *__GlutTimerCallback) ( int value );
typedef struct __GlutTimer_s {
struct timeval interval;
struct timeval expire;
__GlutTimerCallback func;
int value;
struct __GlutTimer_s *next;
} __GlutTimer;
/*****************************************************************************/
static __GlutTimer *g_timers = NULL;
/*****************************************************************************/
void GLUTAPIENTRY
glutDisplayFunc( void (GLUTCALLBACK *func) (void) )
{
display_func = func;
}
void GLUTAPIENTRY
glutReshapeFunc( void (GLUTCALLBACK *func) (int width, int height) )
{
reshape_func = func;
}
void GLUTAPIENTRY
glutKeyboardFunc( void (GLUTCALLBACK *func) (unsigned char key, int x, int y) )
{
keyboard_func = func;
}
void GLUTAPIENTRY
glutMouseFunc( void (GLUTCALLBACK *func) (int button, int state, int x, int y) )
{
mouse_func = func;
}
void GLUTAPIENTRY
glutMotionFunc( void (GLUTCALLBACK *func) (int x, int y) )
{
motion_func = func;
}
void GLUTAPIENTRY
glutPassiveMotionFunc( void (GLUTCALLBACK *func) (int x, int y) )
{
passive_motion_func = func;
}
void GLUTAPIENTRY
glutEntryFunc( void (GLUTCALLBACK *func) (int state) )
{
entry_func = func;
}
void GLUTAPIENTRY
glutVisibilityFunc( void (GLUTCALLBACK *func) (int state) )
{
visibility_func = func;
}
void GLUTAPIENTRY
glutMenuStateFunc( void (GLUTCALLBACK *func) (int state) )
{
menu_state_func = func;
}
void GLUTAPIENTRY
glutSpecialFunc( void (GLUTCALLBACK *func) (int key, int x, int y) )
{
special_func = func;
}
void GLUTAPIENTRY
glutSpaceballMotionFunc( void (GLUTCALLBACK *func) (int x, int y, int z) )
{
}
void GLUTAPIENTRY
glutSpaceballRotateFunc( void (GLUTCALLBACK *func) (int x, int y, int z) )
{
}
void GLUTAPIENTRY
glutSpaceballButtonFunc( void (GLUTCALLBACK *func) (int button, int state) )
{
}
void GLUTAPIENTRY
glutButtonBoxFunc( void (GLUTCALLBACK *func) (int button, int state) )
{
}
void GLUTAPIENTRY
glutDialsFunc( void (GLUTCALLBACK *func) (int dial, int value) )
{
}
void GLUTAPIENTRY
glutTabletMotionFunc( void (GLUTCALLBACK *func) (int x, int y) )
{
}
void GLUTAPIENTRY
glutTabletButtonFunc( void (GLUTCALLBACK *func) (int button, int state, int x, int y) )
{
}
void GLUTAPIENTRY
glutMenuStatusFunc( void (GLUTCALLBACK *func) (int status, int x, int y) )
{
}
void GLUTAPIENTRY
glutOverlayDisplayFunc( void (GLUTCALLBACK *func) (void) )
{
}
void GLUTAPIENTRY
glutWindowStatusFunc( void (GLUTCALLBACK *func) (int state) )
{
}
void GLUTAPIENTRY
glutKeyboardUpFunc( void (GLUTCALLBACK *func) (unsigned char key, int x, int y) )
{
keyboard_up_func = func;
}
void GLUTAPIENTRY
glutSpecialUpFunc( void (GLUTCALLBACK *func) (int key, int x, int y) )
{
special_up_func = func;
}
void GLUTAPIENTRY
glutJoystickFunc( void (GLUTCALLBACK *func)(unsigned int buttons, int x, int y, int z), int pollInterval )
{
joystick_func = func;
/* FIXME: take care of pollInterval */
}
void GLUTAPIENTRY
glutIdleFunc( void (GLUTCALLBACK *func) (void) )
{
idle_func = func;
}
void GLUTAPIENTRY
glutTimerFunc( unsigned int msec, void (GLUTCALLBACK *func) (int value), int value )
{
__GlutTimer *timer;
if (!func)
return;
timer = calloc( 1, sizeof(__GlutTimer) );
if (!timer)
__glutFatalError( "out of memory" );
timer->interval.tv_sec = msec / 1000;
timer->interval.tv_usec = (msec % 1000) * 1000;
gettimeofday( &timer->expire, NULL );
timer->expire.tv_usec += timer->interval.tv_usec;
timer->expire.tv_sec += timer->interval.tv_sec + timer->expire.tv_usec/1000000;
timer->expire.tv_usec %= 1000000;
timer->func = func;
timer->value = value;
timer->next = g_timers;
g_timers = timer;
}
void
__glutHandleTimers( void )
{
__GlutTimer *cur;
struct timeval now;
for (cur = g_timers; cur; cur = cur->next ) {
gettimeofday( &now, NULL );
if (cur->expire.tv_sec > now.tv_sec ||
(cur->expire.tv_sec == now.tv_sec &&
cur->expire.tv_usec >= now.tv_usec))
{
g_idle = GL_FALSE;
cur->func( cur->value );
cur->expire.tv_usec += cur->interval.tv_usec;
cur->expire.tv_sec += cur->interval.tv_sec + cur->expire.tv_usec/1000000;
cur->expire.tv_usec %= 1000000;
}
}
}
GLboolean
__glutGetTimeout( int *ret_msec )
{
__GlutTimer *cur;
struct timeval *time = NULL;
struct timeval now;
for (cur = g_timers; cur; cur = cur->next) {
if (time == NULL ||
time->tv_sec > cur->expire.tv_sec ||
(time->tv_sec == cur->expire.tv_sec &&
time->tv_usec > cur->expire.tv_usec)) {
time = &cur->expire;
}
}
if (time == NULL)
return GL_FALSE;
gettimeofday( &now, NULL );
*ret_msec = (time->tv_sec - now.tv_sec) * 1000 +
(time->tv_usec - now.tv_usec + 999) / 1000;
return GL_TRUE;
}
void
__glutFreeTimers( void )
{
__GlutTimer *cur = g_timers;
while (cur) {
__GlutTimer *next = cur->next;
free( cur );
cur = next;
}
g_timers = NULL;
}