| /* |
| * 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; |
| } |
| |