/* * 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 #include "internal.h" typedef void (GLUTCALLBACK *__GlutTimerCallback) ( int value ); typedef struct __GlutTimer_s { unsigned int interval; struct timeval expire; __GlutTimerCallback func; int value; struct __GlutTimer_s *next; struct __GlutTimer_s *prev; } __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; struct timeval now; if (!func) return; timer = calloc( 1, sizeof(__GlutTimer) ); if (!timer) __glutFatalError( "out of memory" ); gettimeofday( &now, NULL ); timer->interval = msec; timer->expire.tv_sec = now.tv_sec + (now.tv_usec/1000 + msec) / 1000; timer->expire.tv_usec = (now.tv_usec + msec*1000) % 1000000; timer->func = func; timer->value = value; if (g_timers) { timer->prev = g_timers->prev; g_timers->prev->next = timer; g_timers->prev = timer; } else { g_timers = timer; g_timers->prev = 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_sec += (cur->expire.tv_usec/1000 + cur->interval) / 1000; cur->expire.tv_usec = (cur->expire.tv_usec + cur->interval*1000) % 1000000; } } } void __glutFreeTimers( void ) { __GlutTimer *cur = g_timers; while (cur) { __GlutTimer *next = cur->next; free( cur ); cur = next; } g_timers = NULL; }