Merge pull request #42 from rcmaniac25/feature/usr_callback_support
User data callback support
This commit is contained in:
commit
913c66e35e
@ -68,6 +68,7 @@ ENDIF()
|
|||||||
|
|
||||||
SET(FREEGLUT_HEADERS
|
SET(FREEGLUT_HEADERS
|
||||||
include/GL/freeglut.h
|
include/GL/freeglut.h
|
||||||
|
include/GL/freeglut_ucall.h
|
||||||
include/GL/freeglut_ext.h
|
include/GL/freeglut_ext.h
|
||||||
include/GL/freeglut_std.h
|
include/GL/freeglut_std.h
|
||||||
)
|
)
|
||||||
@ -90,6 +91,7 @@ SET(FREEGLUT_SRCS
|
|||||||
src/fg_init.c
|
src/fg_init.c
|
||||||
src/fg_init.h
|
src/fg_init.h
|
||||||
src/fg_internal.h
|
src/fg_internal.h
|
||||||
|
src/fg_callback_macros.h
|
||||||
src/fg_input_devices.c
|
src/fg_input_devices.c
|
||||||
src/fg_joystick.c
|
src/fg_joystick.c
|
||||||
src/fg_main.c
|
src/fg_main.c
|
||||||
@ -551,6 +553,7 @@ IF(UNIX)
|
|||||||
ENDIF()
|
ENDIF()
|
||||||
ADD_DEMO(subwin progs/demos/subwin/subwin.c)
|
ADD_DEMO(subwin progs/demos/subwin/subwin.c)
|
||||||
ADD_DEMO(timer progs/demos/timer/timer.c)
|
ADD_DEMO(timer progs/demos/timer/timer.c)
|
||||||
|
ADD_DEMO(timer_callback progs/demos/timer_callback/timer.c)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
@ -261,7 +261,7 @@ FGAPI void FGAPIENTRY glutSetVertexAttribNormal(GLint attrib);
|
|||||||
FGAPI void FGAPIENTRY glutSetVertexAttribTexCoord2( GLint attrib );
|
FGAPI void FGAPIENTRY glutSetVertexAttribTexCoord2( GLint attrib );
|
||||||
|
|
||||||
/* Mobile platforms lifecycle */
|
/* Mobile platforms lifecycle */
|
||||||
FGAPI void FGAPIENTRY glutInitContextFunc(void (* callback)());
|
FGAPI void FGAPIENTRY glutInitContextFunc( void (* callback)( void ) );
|
||||||
FGAPI void FGAPIENTRY glutAppStatusFunc( void (* callback)( int ) );
|
FGAPI void FGAPIENTRY glutAppStatusFunc( void (* callback)( int ) );
|
||||||
/* state flags that can be passed to callback set by glutAppStatusFunc */
|
/* state flags that can be passed to callback set by glutAppStatusFunc */
|
||||||
#define GLUT_APPSTATUS_PAUSE 0x0001
|
#define GLUT_APPSTATUS_PAUSE 0x0001
|
||||||
@ -274,6 +274,9 @@ FGAPI void FGAPIENTRY glutAppStatusFunc(void (* callback)(int));
|
|||||||
#define GLUT_BORDERLESS 0x0800
|
#define GLUT_BORDERLESS 0x0800
|
||||||
#define GLUT_SRGB 0x1000
|
#define GLUT_SRGB 0x1000
|
||||||
|
|
||||||
|
/* User-argument callbacks and implementation */
|
||||||
|
#include "freeglut_ucall.h"
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
113
freeglut/freeglut/include/GL/freeglut_ucall.h
Normal file
113
freeglut/freeglut/include/GL/freeglut_ucall.h
Normal file
@ -0,0 +1,113 @@
|
|||||||
|
#ifndef __FREEGLUT_UCALL_H__
|
||||||
|
#define __FREEGLUT_UCALL_H__
|
||||||
|
|
||||||
|
/*
|
||||||
|
* freeglut_ucall.h
|
||||||
|
*
|
||||||
|
* Callbacks with user data arguments.
|
||||||
|
*
|
||||||
|
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
|
||||||
|
* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
||||||
|
* PAWEL W. OLSZTA BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
|
||||||
|
* IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||||
|
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Menu stuff, see fg_menu.c
|
||||||
|
*/
|
||||||
|
FGAPI int FGAPIENTRY glutCreateMenuUcall( void (* callback)( int menu, void* user_data ), void* user_data );
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Global callback functions, see fg_callbacks.c
|
||||||
|
*/
|
||||||
|
FGAPI void FGAPIENTRY glutTimerFuncUcall( unsigned int time, void (* callback)( int, void* ), int value, void* user_data );
|
||||||
|
FGAPI void FGAPIENTRY glutIdleFuncUcall( void (* callback)( void* ), void* user_data );
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Window-specific callback functions, see fg_callbacks.c
|
||||||
|
*/
|
||||||
|
FGAPI void FGAPIENTRY glutKeyboardFuncUcall( void (* callback)( unsigned char, int, int, void* ), void* user_data );
|
||||||
|
FGAPI void FGAPIENTRY glutSpecialFuncUcall( void (* callback)( int, int, int, void* ), void* user_data );
|
||||||
|
FGAPI void FGAPIENTRY glutReshapeFuncUcall( void (* callback)( int, int, void* ), void* user_data );
|
||||||
|
FGAPI void FGAPIENTRY glutVisibilityFuncUcall( void (* callback)( int, void* ), void* user_data );
|
||||||
|
FGAPI void FGAPIENTRY glutDisplayFuncUcall( void (* callback)( void* ), void* user_data );
|
||||||
|
FGAPI void FGAPIENTRY glutMouseFuncUcall( void (* callback)( int, int, int, int, void* ), void* user_data );
|
||||||
|
FGAPI void FGAPIENTRY glutMotionFuncUcall( void (* callback)( int, int, void* ), void* user_data );
|
||||||
|
FGAPI void FGAPIENTRY glutPassiveMotionFuncUcall( void (* callback)( int, int, void* ), void* user_data );
|
||||||
|
FGAPI void FGAPIENTRY glutEntryFuncUcall( void (* callback)( int, void* ), void* user_data );
|
||||||
|
|
||||||
|
FGAPI void FGAPIENTRY glutKeyboardUpFuncUcall( void (* callback)( unsigned char, int, int, void* ), void* user_data );
|
||||||
|
FGAPI void FGAPIENTRY glutSpecialUpFuncUcall( void (* callback)( int, int, int, void* ), void* user_data );
|
||||||
|
FGAPI void FGAPIENTRY glutJoystickFuncUcall( void (* callback)( unsigned int, int, int, int, void* ), int pollInterval, void* user_data );
|
||||||
|
FGAPI void FGAPIENTRY glutMenuStatusFuncUcall( void (* callback)( int, int, int, void* ), void* user_data );
|
||||||
|
FGAPI void FGAPIENTRY glutOverlayDisplayFuncUcall( void (* callback)( void* ), void* user_data );
|
||||||
|
FGAPI void FGAPIENTRY glutWindowStatusFuncUcall( void (* callback)( int, void* ), void* user_data );
|
||||||
|
|
||||||
|
FGAPI void FGAPIENTRY glutSpaceballMotionFuncUcall( void (* callback)( int, int, int, void* ), void* user_data );
|
||||||
|
FGAPI void FGAPIENTRY glutSpaceballRotateFuncUcall( void (* callback)( int, int, int, void* ), void* user_data );
|
||||||
|
FGAPI void FGAPIENTRY glutSpaceballButtonFuncUcall( void (* callback)( int, int, void* ), void* user_data );
|
||||||
|
FGAPI void FGAPIENTRY glutButtonBoxFuncUcall( void (* callback)( int, int, void* ), void* user_data );
|
||||||
|
FGAPI void FGAPIENTRY glutDialsFuncUcall( void (* callback)( int, int, void* ), void* user_data );
|
||||||
|
FGAPI void FGAPIENTRY glutTabletMotionFuncUcall( void (* callback)( int, int, void* ), void* user_data );
|
||||||
|
FGAPI void FGAPIENTRY glutTabletButtonFuncUcall( void (* callback)( int, int, int, int, void* ), void* user_data );
|
||||||
|
|
||||||
|
FGAPI void FGAPIENTRY glutMouseWheelFuncUcall( void (* callback)( int, int, int, int, void* ), void* user_data );
|
||||||
|
FGAPI void FGAPIENTRY glutPositionFuncUcall( void (* callback)( int, int, void* ), void* user_data );
|
||||||
|
FGAPI void FGAPIENTRY glutCloseFuncUcall( void (* callback)( void* ), void* user_data );
|
||||||
|
FGAPI void FGAPIENTRY glutWMCloseFuncUcall( void (* callback)( void* ), void* user_data );
|
||||||
|
FGAPI void FGAPIENTRY glutMenuDestroyFuncUcall( void (* callback)( void* ), void* user_data );
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Multi-touch/multi-pointer extensions
|
||||||
|
*/
|
||||||
|
FGAPI void FGAPIENTRY glutMultiEntryFuncUcall( void (* callback)( int, int, void* ), void* user_data );
|
||||||
|
FGAPI void FGAPIENTRY glutMultiButtonFuncUcall( void (* callback)( int, int, int, int, int, void* ), void* user_data );
|
||||||
|
FGAPI void FGAPIENTRY glutMultiMotionFuncUcall( void (* callback)( int, int, int, void* ), void* user_data );
|
||||||
|
FGAPI void FGAPIENTRY glutMultiPassiveFuncUcall( void (* callback)( int, int, int, void* ), void* user_data );
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Initialization functions, see fg_init.c
|
||||||
|
*/
|
||||||
|
#include <stdarg.h>
|
||||||
|
FGAPI void FGAPIENTRY glutInitErrorFuncUcall( void (* callback)( const char *fmt, va_list ap, void* user_data ), void* user_data );
|
||||||
|
FGAPI void FGAPIENTRY glutInitWarningFuncUcall( void (* callback)( const char *fmt, va_list ap, void* user_data ), void* user_data );
|
||||||
|
|
||||||
|
/* Mobile platforms lifecycle */
|
||||||
|
FGAPI void FGAPIENTRY glutInitContextFuncUcall( void (* callback)( void* ), void* user_data );
|
||||||
|
FGAPI void FGAPIENTRY glutAppStatusFuncUcall( void (* callback)( int, void* ), void* user_data );
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Continued "hack" from GLUT applied to Ucall functions.
|
||||||
|
* For more info, see bottom of freeglut_std.h
|
||||||
|
*/
|
||||||
|
|
||||||
|
/* to get the prototype for exit() */
|
||||||
|
#include <stdlib.h>
|
||||||
|
|
||||||
|
#if defined(_WIN32) && !defined(GLUT_DISABLE_ATEXIT_HACK) && !defined(__WATCOMC__)
|
||||||
|
FGAPI int FGAPIENTRY __glutCreateMenuUcallWithExit(void(*func)(int, void*), void(__cdecl *exitfunc)(int), void* user_data);
|
||||||
|
#ifndef FREEGLUT_BUILDING_LIB
|
||||||
|
#if defined(__GNUC__)
|
||||||
|
#define FGUNUSED __attribute__((unused))
|
||||||
|
#else
|
||||||
|
#define FGUNUSED
|
||||||
|
#endif
|
||||||
|
static int FGAPIENTRY FGUNUSED glutCreateMenuUcall_ATEXIT_HACK(void(*func)(int, void*), void* user_data) { return __glutCreateMenuUcallWithExit(func, exit, user_data); }
|
||||||
|
#define glutCreateMenuUcall glutCreateMenuUcall_ATEXIT_HACK
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/*** END OF FILE ***/
|
||||||
|
|
||||||
|
#endif /* __FREEGLUT_UCALL_H__ */
|
||||||
|
|
174
freeglut/freeglut/progs/demos/timer_callback/timer.c
Normal file
174
freeglut/freeglut/progs/demos/timer_callback/timer.c
Normal file
@ -0,0 +1,174 @@
|
|||||||
|
/* Timer (callback) demo
|
||||||
|
*
|
||||||
|
* Written by John Tsiombikas <nuclear@member.fsf.org>
|
||||||
|
* Modified by Vincent Simonetti
|
||||||
|
*
|
||||||
|
* A modification of the timer sample, but with this
|
||||||
|
* offering a use of the user-data callback.
|
||||||
|
*/
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <GL/freeglut.h>
|
||||||
|
|
||||||
|
struct display_index_s
|
||||||
|
{
|
||||||
|
/* color index will be advanced every time the timer expires */
|
||||||
|
int surround_color_index;
|
||||||
|
int center_color_index;
|
||||||
|
};
|
||||||
|
typedef struct display_index_s display_index_t;
|
||||||
|
|
||||||
|
struct timer_state_s
|
||||||
|
{
|
||||||
|
int* color_index_ptr;
|
||||||
|
int* timer_time_ptr;
|
||||||
|
};
|
||||||
|
typedef struct timer_state_s timer_state_t;
|
||||||
|
|
||||||
|
struct menu_state_s
|
||||||
|
{
|
||||||
|
int* timer_time_ptr;
|
||||||
|
int menu_id;
|
||||||
|
};
|
||||||
|
typedef struct menu_state_s menu_state_t;
|
||||||
|
|
||||||
|
void disp(void* uptr);
|
||||||
|
void timer_func(int which, void* uptr);
|
||||||
|
|
||||||
|
const float color[][3] = {
|
||||||
|
{1, 0, 0},
|
||||||
|
{0, 1, 0},
|
||||||
|
{0, 0, 1},
|
||||||
|
{1, 1, 0},
|
||||||
|
{0, 1, 1},
|
||||||
|
{1, 0, 1}
|
||||||
|
};
|
||||||
|
const int timerInts[] = {
|
||||||
|
250,
|
||||||
|
500,
|
||||||
|
1000
|
||||||
|
};
|
||||||
|
|
||||||
|
void createMenuEntries(menu_state_t* menuState)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
for (i = 0; i < sizeof(timerInts) / sizeof(*timerInts); i++)
|
||||||
|
{
|
||||||
|
char temp[10] = {'\0'};
|
||||||
|
/* flag current value */
|
||||||
|
if ((*menuState->timer_time_ptr) == timerInts[i])
|
||||||
|
temp[0] = '+';
|
||||||
|
else
|
||||||
|
temp[0] = '-';
|
||||||
|
|
||||||
|
sprintf(temp + 1, " %4d ms", timerInts[i]);
|
||||||
|
|
||||||
|
glutAddMenuEntry(temp, timerInts[i]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void updateMenuEntries(menu_state_t* menuState)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
for (i = 0; i < sizeof(timerInts) / sizeof(*timerInts); i++)
|
||||||
|
{
|
||||||
|
char temp[10] = { '\0' };
|
||||||
|
/* flag current value */
|
||||||
|
if ((*menuState->timer_time_ptr) == timerInts[i])
|
||||||
|
temp[0] = '+';
|
||||||
|
else
|
||||||
|
temp[0] = '-';
|
||||||
|
|
||||||
|
sprintf(temp + 1, " %4d ms", timerInts[i]);
|
||||||
|
|
||||||
|
glutChangeToMenuEntry(i+1, temp, timerInts[i]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void MenuHandler(int timerInt, void* user_ptr)
|
||||||
|
{
|
||||||
|
menu_state_t* menuState;
|
||||||
|
|
||||||
|
if (!user_ptr)
|
||||||
|
{
|
||||||
|
/* In case main menu is selected somehow */
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
menuState = (menu_state_t*)user_ptr;
|
||||||
|
|
||||||
|
*menuState->timer_time_ptr = timerInt;
|
||||||
|
glutSetMenu(menuState->menu_id);
|
||||||
|
updateMenuEntries(menuState);
|
||||||
|
}
|
||||||
|
|
||||||
|
int main(int argc, char **argv)
|
||||||
|
{
|
||||||
|
int timerSurroundInt = 1000, timerCenterInt = 500;
|
||||||
|
display_index_t displayIndex = { 0, 2 };
|
||||||
|
timer_state_t surroundTimerState = { &displayIndex.surround_color_index, &timerSurroundInt };
|
||||||
|
timer_state_t centerTimerState = { &displayIndex.center_color_index, &timerCenterInt };
|
||||||
|
menu_state_t surroundMenuState = { &timerSurroundInt, 0 };
|
||||||
|
menu_state_t centerMenuState = { &timerCenterInt, 0 };
|
||||||
|
|
||||||
|
glutInit(&argc, argv);
|
||||||
|
glutInitWindowSize(128, 128);
|
||||||
|
glutInitDisplayMode(GLUT_RGB | GLUT_DOUBLE);
|
||||||
|
glutCreateWindow("timer test");
|
||||||
|
|
||||||
|
glutDisplayFuncUcall(disp, &displayIndex);
|
||||||
|
|
||||||
|
/* get timer started, its reset in the timer function itself */
|
||||||
|
glutTimerFuncUcall(timerSurroundInt, timer_func, 1, &surroundTimerState);
|
||||||
|
glutTimerFuncUcall(timerCenterInt, timer_func, 2, ¢erTimerState);
|
||||||
|
|
||||||
|
/* menus for setting timing */
|
||||||
|
surroundMenuState.menu_id = glutCreateMenuUcall(MenuHandler, &surroundMenuState);
|
||||||
|
createMenuEntries(&surroundMenuState);
|
||||||
|
|
||||||
|
centerMenuState.menu_id = glutCreateMenuUcall(MenuHandler, ¢erMenuState);
|
||||||
|
createMenuEntries(¢erMenuState);
|
||||||
|
|
||||||
|
glutCreateMenuUcall(MenuHandler, NULL); /* doesn't matter, no clickable entries in this menu */
|
||||||
|
glutAddSubMenu("Center", centerMenuState.menu_id);
|
||||||
|
glutAddSubMenu("Surround", surroundMenuState.menu_id);
|
||||||
|
glutAttachMenu(GLUT_RIGHT_BUTTON);
|
||||||
|
|
||||||
|
glutMainLoop();
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
void disp(void* user_ptr)
|
||||||
|
{
|
||||||
|
const display_index_t* displayIndex;
|
||||||
|
int cidx, pcidx;
|
||||||
|
|
||||||
|
displayIndex = (display_index_t*)user_ptr;
|
||||||
|
|
||||||
|
cidx = displayIndex->surround_color_index;
|
||||||
|
glClearColor(color[cidx][0], color[cidx][1], color[cidx][2], 1);
|
||||||
|
glClear(GL_COLOR_BUFFER_BIT);
|
||||||
|
|
||||||
|
pcidx = displayIndex->center_color_index;
|
||||||
|
glPointSize(10.f);
|
||||||
|
glColor3f(color[pcidx][0], color[pcidx][1], color[pcidx][2]);
|
||||||
|
glBegin(GL_POINTS);
|
||||||
|
glVertex2i(0,0);
|
||||||
|
glEnd();
|
||||||
|
|
||||||
|
glutSwapBuffers();
|
||||||
|
}
|
||||||
|
|
||||||
|
void timer_func(int which, void* user_ptr)
|
||||||
|
{
|
||||||
|
const timer_state_t* timerState;
|
||||||
|
|
||||||
|
timerState = (timer_state_t*)user_ptr;
|
||||||
|
|
||||||
|
/* advance the color index and trigger a redisplay */
|
||||||
|
*timerState->color_index_ptr = (*timerState->color_index_ptr + 1) % (sizeof color / sizeof *color);
|
||||||
|
|
||||||
|
glutPostRedisplay();
|
||||||
|
|
||||||
|
/* (re)set the timer callback and ask glut to call it in x ms */
|
||||||
|
glutTimerFuncUcall(*timerState->timer_time_ptr, timer_func, which, user_ptr);
|
||||||
|
}
|
333
freeglut/freeglut/src/fg_callback_macros.h
Normal file
333
freeglut/freeglut/src/fg_callback_macros.h
Normal file
@ -0,0 +1,333 @@
|
|||||||
|
/*
|
||||||
|
* fg_callback_macros.h
|
||||||
|
*
|
||||||
|
* The freeglut library callback macro file.
|
||||||
|
*
|
||||||
|
* Copyright (C) 2016 Vincent Simonetti
|
||||||
|
* Creation date: Sat Jan 16 2016
|
||||||
|
*
|
||||||
|
* Permission is hereby granted, free of charge, to any person obtaining a
|
||||||
|
* copy of this software and associated documentation files (the "Software"),
|
||||||
|
* to deal in the Software without restriction, including without limitation
|
||||||
|
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
||||||
|
* and/or sell copies of the Software, and to permit persons to whom the
|
||||||
|
* Software is furnished to do so, subject to the following conditions:
|
||||||
|
*
|
||||||
|
* The above copyright notice and this permission notice shall be included
|
||||||
|
* in all copies or substantial portions of the Software.
|
||||||
|
*
|
||||||
|
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
|
||||||
|
* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
||||||
|
* PAWEL W. OLSZTA BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
|
||||||
|
* IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||||
|
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef FREEGLUT_CALLBACK_MACROS_H
|
||||||
|
#define FREEGLUT_CALLBACK_MACROS_H
|
||||||
|
|
||||||
|
/*
|
||||||
|
* ----------------------------------------------------------------------------------------------------------------------
|
||||||
|
* There are two sets of macros here. One is for executing window callbacks, the others are for setting window callbacks.
|
||||||
|
* ----------------------------------------------------------------------------------------------------------------------
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Compiler define: FG_COMPILER_SUPPORTS_VA_ARGS: if the compiler supports variadic macros
|
||||||
|
*/
|
||||||
|
|
||||||
|
/* What supports variadic macros based off Wikipedia article on it (GCC-like must support C99 or higher to use variadic macros) */
|
||||||
|
#if (((defined(__GNUC__) && (__GNUC__ >= 3)) || \
|
||||||
|
(defined(__clang__))) && \
|
||||||
|
(defined(__STDC_VERSION__) && (__STDC_VERSION__ >= 199901L))) || \
|
||||||
|
(defined(_MSC_VER) && (_MSC_VER >= 1400)) || \
|
||||||
|
(defined(__BORLANDC__) && (__BORLANDC__ >= 0x570)) || \
|
||||||
|
(defined(__SUNPRO_C) && (__SUNPRO_C >= 0x530))
|
||||||
|
#define FG_COMPILER_SUPPORTS_VA_ARGS 1
|
||||||
|
#else
|
||||||
|
#define FG_COMPILER_SUPPORTS_VA_ARGS 0
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/*
|
||||||
|
* --------------------------
|
||||||
|
* Executing window callbacks
|
||||||
|
* --------------------------
|
||||||
|
*
|
||||||
|
* Info:
|
||||||
|
*
|
||||||
|
* This took a while to figure out, so be sure try to understand what is happening so that you can ensure that whatever you
|
||||||
|
* change won't break other areas.
|
||||||
|
*
|
||||||
|
* If you are just adding a new callback/changing it's argument count, just go to the bottom of the file.
|
||||||
|
*
|
||||||
|
* This whole file exists purely for the sake of preventing the need to implement additional parsing logic for each callback
|
||||||
|
* to pass user arguments. Of course, the necessity to support older compilers means that, as seen in the line above, there
|
||||||
|
* is still a requirement to add/modify code to handle callbacks. If freeglut ever requires newer compilers (at minimum, ones
|
||||||
|
* that support C99 or higher), code can very slowly be removed from this file. Even better would be if the C standard eventually
|
||||||
|
* supports something similar to what GCC has implemented or offers an alternative. Another option is if C++ would be "allowed" by
|
||||||
|
* project maintaners, as then templates can be used and function overloading. Ironically, the template would probably look worse
|
||||||
|
* then the GCC macro, so maybe it's good to stay as is.
|
||||||
|
*
|
||||||
|
* Onto the different "versions" of macros:
|
||||||
|
*
|
||||||
|
* The first is for any compiler that supports C99 by default. It requires each callback to have a specific argument count
|
||||||
|
* passthrough macro. The only reason there are specific count macros is so that (see paraghraph below) don't need have their own
|
||||||
|
* set of callback macros. Ideally, there would only be ZERO and ONE_OR_MORE. This works by having callback-specific macros call a
|
||||||
|
* specific handler macro to return user data (ZERO) or return one or more arguments along with userData (ONE_OR_MORE) where, with
|
||||||
|
* variadic macros, it just reuses the arguments.
|
||||||
|
*
|
||||||
|
* The last macro set is for the poor individual who has to use a compiler that doesn't support C99 by default, or may not support
|
||||||
|
* it at all. Stuff like MSVC6... It works by having a specific-count macro that "extracts" each argument to have them reused without
|
||||||
|
* the parathesis.
|
||||||
|
*
|
||||||
|
* There is a 3rd macro set that only worked on GCC/Clang, and thus was removed (last seen in revision e9676fc of the GIT mirror.
|
||||||
|
* Not sure at this time what the SVN number is.) as it's a non-standard functionality.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* EXPAND_WCB() is used as:
|
||||||
|
*
|
||||||
|
* EXPAND_WCB( cbname )(( arg_list, userData ))
|
||||||
|
*
|
||||||
|
* ... where {(arg_list)} is the parameter list and userData is user
|
||||||
|
* provided data.
|
||||||
|
*
|
||||||
|
* This will take the arg_list and extend it by one argument, adding
|
||||||
|
* the argument "userData" to the end of the list.
|
||||||
|
*
|
||||||
|
* In order for this to work, each callback must have a define that
|
||||||
|
* properly handles the arguments as needed by the callback.
|
||||||
|
* This callback is in the format of EXPAND_WCB_SUB_<cbname>.
|
||||||
|
* Helper functions exist for zero to five parameters: EXPAND_WCB_ZERO,
|
||||||
|
* EXPAND_WCB_ONE, EXPAND_WCB_TWO, EXPAND_WCB_THREE< EXPAND_WCB_FOUR,
|
||||||
|
* and EXPAND_WCB_FIVE. Each handle the callback argument counts.
|
||||||
|
*
|
||||||
|
* An example for the "Entry" callback, where "Entry" is the cbname:
|
||||||
|
* typedef void (* FGCBEntry )( int );
|
||||||
|
* typedef void (* FGCBEntryUC)( int, FGCBUserData );
|
||||||
|
* #define EXPAND_WCB_SUB_Entry(args) EXPAND_WCB_ONE args
|
||||||
|
*/
|
||||||
|
|
||||||
|
#if FG_COMPILER_SUPPORTS_VA_ARGS
|
||||||
|
|
||||||
|
#define EXPAND_WCB_UNPARAN(...) __VA_ARGS__
|
||||||
|
#define EXPAND_WCB_ONE_OR_MORE(args, userData) ( EXPAND_WCB_UNPARAN args, userData )
|
||||||
|
|
||||||
|
#define EXPAND_WCB_ONE(args, userData) EXPAND_WCB_ONE_OR_MORE( args, userData )
|
||||||
|
#define EXPAND_WCB_TWO(args, userData) EXPAND_WCB_ONE_OR_MORE( args, userData )
|
||||||
|
#define EXPAND_WCB_THREE(args, userData) EXPAND_WCB_ONE_OR_MORE( args, userData )
|
||||||
|
#define EXPAND_WCB_FOUR(args, userData) EXPAND_WCB_ONE_OR_MORE( args, userData )
|
||||||
|
#define EXPAND_WCB_FIVE(args, userData) EXPAND_WCB_ONE_OR_MORE( args, userData )
|
||||||
|
|
||||||
|
#else
|
||||||
|
|
||||||
|
#define EXPAND_WCB_EXTRACT_ONE_ARGS(arg1) arg1
|
||||||
|
#define EXPAND_WCB_EXTRACT_TWO_ARGS(arg1, arg2) arg1, arg2
|
||||||
|
#define EXPAND_WCB_EXTRACT_THREE_ARGS(arg1, arg2, arg3) arg1, arg2, arg3
|
||||||
|
#define EXPAND_WCB_EXTRACT_FOUR_ARGS(arg1, arg2, arg3, arg4) arg1, arg2, arg3, arg4
|
||||||
|
#define EXPAND_WCB_EXTRACT_FIVE_ARGS(arg1, arg2, arg3, arg4, arg5) arg1, arg2, arg3, arg4, arg5
|
||||||
|
|
||||||
|
#define EXPAND_WCB_ONE(args, userData) (EXPAND_WCB_EXTRACT_ONE_ARGS args, userData)
|
||||||
|
#define EXPAND_WCB_TWO(args, userData) (EXPAND_WCB_EXTRACT_TWO_ARGS args, userData)
|
||||||
|
#define EXPAND_WCB_THREE(args, userData) (EXPAND_WCB_EXTRACT_THREE_ARGS args, userData)
|
||||||
|
#define EXPAND_WCB_FOUR(args, userData) (EXPAND_WCB_EXTRACT_FOUR_ARGS args, userData)
|
||||||
|
#define EXPAND_WCB_FIVE(args, userData) (EXPAND_WCB_EXTRACT_FIVE_ARGS args, userData)
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#define EXPAND_WCB_ZERO(args, userData) ( userData )
|
||||||
|
|
||||||
|
#define EXPAND_WCB(cbname) EXPAND_WCB_SUB_ ## cbname
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Freeglut callbacks type definitions macros
|
||||||
|
*
|
||||||
|
* Every time a callback is updated in fg_internal.h is updated, this needs updated
|
||||||
|
* if argument counts change, new callbacks are added, or callbacks are removed.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#define EXPAND_WCB_SUB_Display(args) EXPAND_WCB_ZERO args
|
||||||
|
#define EXPAND_WCB_SUB_Reshape(args) EXPAND_WCB_TWO args
|
||||||
|
#define EXPAND_WCB_SUB_Position(args) EXPAND_WCB_TWO args
|
||||||
|
#define EXPAND_WCB_SUB_Visibility(args) EXPAND_WCB_ONE args
|
||||||
|
#define EXPAND_WCB_SUB_Keyboard(args) EXPAND_WCB_THREE args
|
||||||
|
#define EXPAND_WCB_SUB_KeyboardUp(args) EXPAND_WCB_THREE args
|
||||||
|
#define EXPAND_WCB_SUB_Special(args) EXPAND_WCB_THREE args
|
||||||
|
#define EXPAND_WCB_SUB_SpecialUp(args) EXPAND_WCB_THREE args
|
||||||
|
#define EXPAND_WCB_SUB_Mouse(args) EXPAND_WCB_FOUR args
|
||||||
|
#define EXPAND_WCB_SUB_MouseWheel(args) EXPAND_WCB_FOUR args
|
||||||
|
#define EXPAND_WCB_SUB_Motion(args) EXPAND_WCB_TWO args
|
||||||
|
#define EXPAND_WCB_SUB_Passive(args) EXPAND_WCB_TWO args
|
||||||
|
#define EXPAND_WCB_SUB_Entry(args) EXPAND_WCB_ONE args
|
||||||
|
#define EXPAND_WCB_SUB_WindowStatus(args) EXPAND_WCB_ONE args
|
||||||
|
#define EXPAND_WCB_SUB_Joystick(args) EXPAND_WCB_FOUR args
|
||||||
|
#define EXPAND_WCB_SUB_OverlayDisplay(args) EXPAND_WCB_ZERO args
|
||||||
|
#define EXPAND_WCB_SUB_SpaceMotion(args) EXPAND_WCB_THREE args
|
||||||
|
#define EXPAND_WCB_SUB_SpaceRotation(args) EXPAND_WCB_THREE args
|
||||||
|
#define EXPAND_WCB_SUB_SpaceButton(args) EXPAND_WCB_TWO args
|
||||||
|
#define EXPAND_WCB_SUB_Dials(args) EXPAND_WCB_TWO args
|
||||||
|
#define EXPAND_WCB_SUB_ButtonBox(args) EXPAND_WCB_TWO args
|
||||||
|
#define EXPAND_WCB_SUB_TabletMotion(args) EXPAND_WCB_TWO args
|
||||||
|
#define EXPAND_WCB_SUB_TabletButton(args) EXPAND_WCB_FOUR args
|
||||||
|
#define EXPAND_WCB_SUB_Destroy(args) EXPAND_WCB_ZERO args
|
||||||
|
#define EXPAND_WCB_SUB_MultiEntry(args) EXPAND_WCB_TWO args
|
||||||
|
#define EXPAND_WCB_SUB_MultiButton(args) EXPAND_WCB_FIVE args
|
||||||
|
#define EXPAND_WCB_SUB_MultiMotion(args) EXPAND_WCB_THREE args
|
||||||
|
#define EXPAND_WCB_SUB_MultiPassive(args) EXPAND_WCB_THREE args
|
||||||
|
#define EXPAND_WCB_SUB_InitContext(args) EXPAND_WCB_ZERO args
|
||||||
|
#define EXPAND_WCB_SUB_AppStatus(args) EXPAND_WCB_ONE args
|
||||||
|
|
||||||
|
/*
|
||||||
|
* ------------------------
|
||||||
|
* Setting window callbacks
|
||||||
|
* ------------------------
|
||||||
|
*
|
||||||
|
* These originally existed in fg_callbacks.c
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* All of the window-specific callbacks setting methods can be generalized to this:
|
||||||
|
*/
|
||||||
|
#define SET_CURRENT_WINDOW_CALLBACK(a) \
|
||||||
|
do \
|
||||||
|
{ \
|
||||||
|
if( fgStructure.CurrentWindow == NULL ) \
|
||||||
|
return; \
|
||||||
|
SET_WCB( ( *( fgStructure.CurrentWindow ) ), a, callback, userData ); \
|
||||||
|
} while( 0 )
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Types need to be defined for callbacks. It's not ideal, but it works for this.
|
||||||
|
*/
|
||||||
|
#define IMPLEMENT_CALLBACK_FUNC_CB_ARG0(a,b) \
|
||||||
|
static void fgh##a##FuncCallback( FGCBUserData userData ) \
|
||||||
|
{ \
|
||||||
|
FGCB##b callback = (FGCB##b)userData; \
|
||||||
|
callback(); \
|
||||||
|
}
|
||||||
|
#define IMPLEMENT_CALLBACK_FUNC_CB_ARG1(a,b) \
|
||||||
|
static void fgh##a##FuncCallback( int arg1val, FGCBUserData userData ) \
|
||||||
|
{ \
|
||||||
|
FGCB##b callback = (FGCB##b)userData; \
|
||||||
|
callback( arg1val ); \
|
||||||
|
}
|
||||||
|
#define IMPLEMENT_CALLBACK_FUNC_CB_ARG2(a,b) \
|
||||||
|
static void fgh##a##FuncCallback( int arg1val, int arg2val, FGCBUserData userData ) \
|
||||||
|
{ \
|
||||||
|
FGCB##b callback = (FGCB##b)userData; \
|
||||||
|
callback( arg1val, arg2val ); \
|
||||||
|
}
|
||||||
|
#define IMPLEMENT_CALLBACK_FUNC_CB_ARG3_USER(a,b,arg1,arg2,arg3) \
|
||||||
|
static void fgh##a##FuncCallback( arg1 arg1val, arg2 arg2val, arg3 arg3val, FGCBUserData userData ) \
|
||||||
|
{ \
|
||||||
|
FGCB##b callback = (FGCB##b)userData; \
|
||||||
|
callback( arg1val, arg2val, arg3val ); \
|
||||||
|
}
|
||||||
|
#define IMPLEMENT_CALLBACK_FUNC_CB_ARG3(a,b) IMPLEMENT_CALLBACK_FUNC_CB_ARG3_USER(a,b,int,int,int)
|
||||||
|
#define IMPLEMENT_CALLBACK_FUNC_CB_ARG4(a,b) \
|
||||||
|
static void fgh##a##FuncCallback( int arg1val, int arg2val, int arg3val, int arg4val, FGCBUserData userData ) \
|
||||||
|
{ \
|
||||||
|
FGCB##b callback = (FGCB##b)userData; \
|
||||||
|
callback( arg1val, arg2val, arg3val, arg4val ); \
|
||||||
|
}
|
||||||
|
#define IMPLEMENT_CALLBACK_FUNC_CB_ARG5(a,b) \
|
||||||
|
static void fgh##a##FuncCallback( int arg1val, int arg2val, int arg3val, int arg4val, int arg5val, FGCBUserData userData ) \
|
||||||
|
{ \
|
||||||
|
FGCB##b callback = (FGCB##b)userData; \
|
||||||
|
callback( arg1val, arg2val, arg3val, arg4val, arg5val ); \
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* And almost every time the callback setter function can be implemented with these:
|
||||||
|
*/
|
||||||
|
#define IMPLEMENT_CURRENT_WINDOW_CALLBACK_FUNC_2NAME_GLUT_UCALL(a,b) \
|
||||||
|
void FGAPIENTRY glut##a##FuncUcall( FGCB##b##UC callback, FGCBUserData userData ) \
|
||||||
|
{ \
|
||||||
|
FREEGLUT_EXIT_IF_NOT_INITIALISED ( "glut"#a"FuncUcall" ); \
|
||||||
|
SET_CURRENT_WINDOW_CALLBACK( b ); \
|
||||||
|
}
|
||||||
|
#define IMPLEMENT_CALLBACK_FUNC_2NAME_GLUT_BASE(a,b) \
|
||||||
|
void FGAPIENTRY glut##a##Func( FGCB##b callback ) \
|
||||||
|
{ \
|
||||||
|
FREEGLUT_EXIT_IF_NOT_INITIALISED ( "glut"#a"Func" ); \
|
||||||
|
if( callback ) \
|
||||||
|
glut##a##FuncUcall( fgh##a##FuncCallback, (FGCBUserData)callback ); \
|
||||||
|
else \
|
||||||
|
glut##a##FuncUcall( NULL, NULL ); \
|
||||||
|
}
|
||||||
|
|
||||||
|
#define IMPLEMENT_CURRENT_WINDOW_CALLBACK_FUNC_2NAME_GLUT(a,b) \
|
||||||
|
IMPLEMENT_CURRENT_WINDOW_CALLBACK_FUNC_2NAME_GLUT_UCALL(a,b) \
|
||||||
|
IMPLEMENT_CALLBACK_FUNC_2NAME_GLUT_BASE(a,b)
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Combine _glut and _cb macros:
|
||||||
|
*/
|
||||||
|
#define IMPLEMENT_CURRENT_WINDOW_CALLBACK_FUNC_ARG0(a) \
|
||||||
|
IMPLEMENT_CALLBACK_FUNC_CB_ARG0(a,a) \
|
||||||
|
IMPLEMENT_CURRENT_WINDOW_CALLBACK_FUNC_2NAME_GLUT(a,a)
|
||||||
|
|
||||||
|
#define IMPLEMENT_CURRENT_WINDOW_CALLBACK_FUNC_ARG0_2NAME(a,b) \
|
||||||
|
IMPLEMENT_CALLBACK_FUNC_CB_ARG0(a,b) \
|
||||||
|
IMPLEMENT_CURRENT_WINDOW_CALLBACK_FUNC_2NAME_GLUT(a,b)
|
||||||
|
|
||||||
|
#define IMPLEMENT_GLUT_CALLBACK_FUNC_ARG0(a) \
|
||||||
|
IMPLEMENT_CALLBACK_FUNC_CB_ARG0(a,a) \
|
||||||
|
IMPLEMENT_CALLBACK_FUNC_2NAME_GLUT_BASE(a,a)
|
||||||
|
|
||||||
|
#define IMPLEMENT_GLUT_CALLBACK_FUNC_ARG0_2NAME(a,b) \
|
||||||
|
IMPLEMENT_CALLBACK_FUNC_CB_ARG0(a,b) \
|
||||||
|
IMPLEMENT_CALLBACK_FUNC_2NAME_GLUT_BASE(a,b)
|
||||||
|
|
||||||
|
#define IMPLEMENT_CURRENT_WINDOW_CALLBACK_FUNC_ARG1(a) \
|
||||||
|
IMPLEMENT_CALLBACK_FUNC_CB_ARG1(a,a) \
|
||||||
|
IMPLEMENT_CURRENT_WINDOW_CALLBACK_FUNC_2NAME_GLUT(a,a)
|
||||||
|
|
||||||
|
#define IMPLEMENT_GLUT_CALLBACK_FUNC_ARG1(a) \
|
||||||
|
IMPLEMENT_CALLBACK_FUNC_CB_ARG1(a,a) \
|
||||||
|
IMPLEMENT_CALLBACK_FUNC_2NAME_GLUT_BASE(a,a)
|
||||||
|
|
||||||
|
#define IMPLEMENT_CURRENT_WINDOW_CALLBACK_FUNC_ARG2(a) \
|
||||||
|
IMPLEMENT_CALLBACK_FUNC_CB_ARG2(a,a) \
|
||||||
|
IMPLEMENT_CURRENT_WINDOW_CALLBACK_FUNC_2NAME_GLUT(a,a)
|
||||||
|
|
||||||
|
#define IMPLEMENT_CURRENT_WINDOW_CALLBACK_FUNC_ARG2_2NAME(a,b) \
|
||||||
|
IMPLEMENT_CALLBACK_FUNC_CB_ARG2(a,b) \
|
||||||
|
IMPLEMENT_CURRENT_WINDOW_CALLBACK_FUNC_2NAME_GLUT(a,b)
|
||||||
|
|
||||||
|
#define IMPLEMENT_GLUT_CALLBACK_FUNC_ARG2(a) \
|
||||||
|
IMPLEMENT_CALLBACK_FUNC_CB_ARG2(a,a) \
|
||||||
|
IMPLEMENT_CALLBACK_FUNC_2NAME_GLUT_BASE(a,a)
|
||||||
|
|
||||||
|
#define IMPLEMENT_GLUT_CALLBACK_FUNC_ARG2_2NAME(a,b) \
|
||||||
|
IMPLEMENT_CALLBACK_FUNC_CB_ARG2(a,b) \
|
||||||
|
IMPLEMENT_CALLBACK_FUNC_2NAME_GLUT_BASE(a,b)
|
||||||
|
|
||||||
|
#define IMPLEMENT_CURRENT_WINDOW_CALLBACK_FUNC_ARG3(a) \
|
||||||
|
IMPLEMENT_CALLBACK_FUNC_CB_ARG3(a,a) \
|
||||||
|
IMPLEMENT_CURRENT_WINDOW_CALLBACK_FUNC_2NAME_GLUT(a,a)
|
||||||
|
|
||||||
|
#define IMPLEMENT_CURRENT_WINDOW_CALLBACK_FUNC_ARG3_USER(a,arg1,arg2,arg3) \
|
||||||
|
IMPLEMENT_CALLBACK_FUNC_CB_ARG3_USER(a,a,arg1,arg2,arg3) \
|
||||||
|
IMPLEMENT_CURRENT_WINDOW_CALLBACK_FUNC_2NAME_GLUT(a,a)
|
||||||
|
|
||||||
|
#define IMPLEMENT_GLUT_CALLBACK_FUNC_ARG3(a) \
|
||||||
|
IMPLEMENT_CALLBACK_FUNC_CB_ARG3(a,a) \
|
||||||
|
IMPLEMENT_CALLBACK_FUNC_2NAME_GLUT_BASE(a,a)
|
||||||
|
|
||||||
|
#define IMPLEMENT_GLUT_CALLBACK_FUNC_ARG3_2NAME(a,b) \
|
||||||
|
IMPLEMENT_CALLBACK_FUNC_CB_ARG3(a,b) \
|
||||||
|
IMPLEMENT_CALLBACK_FUNC_2NAME_GLUT_BASE(a,b)
|
||||||
|
|
||||||
|
#define IMPLEMENT_CURRENT_WINDOW_CALLBACK_FUNC_ARG4(a) \
|
||||||
|
IMPLEMENT_CALLBACK_FUNC_CB_ARG4(a,a) \
|
||||||
|
IMPLEMENT_CURRENT_WINDOW_CALLBACK_FUNC_2NAME_GLUT(a,a)
|
||||||
|
|
||||||
|
#define IMPLEMENT_CURRENT_WINDOW_CALLBACK_FUNC_ARG5(a) \
|
||||||
|
IMPLEMENT_CALLBACK_FUNC_CB_ARG5(a,a) \
|
||||||
|
IMPLEMENT_CURRENT_WINDOW_CALLBACK_FUNC_2NAME_GLUT(a,a)
|
||||||
|
|
||||||
|
#endif /* FREEGLUT_CALLBACK_MACROS_H */
|
||||||
|
|
||||||
|
/*** END OF FILE ***/
|
@ -30,23 +30,26 @@
|
|||||||
|
|
||||||
/* -- INTERFACE FUNCTIONS -------------------------------------------------- */
|
/* -- INTERFACE FUNCTIONS -------------------------------------------------- */
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Global callbacks.
|
* Global callbacks.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/* Sets the global idle callback */
|
/* Sets the global idle callback */
|
||||||
void FGAPIENTRY glutIdleFunc( FGCBIdle callback )
|
void FGAPIENTRY glutIdleFuncUcall( FGCBIdleUC callback, FGCBUserData userData )
|
||||||
{
|
{
|
||||||
FREEGLUT_EXIT_IF_NOT_INITIALISED ( "glutIdleFunc" );
|
FREEGLUT_EXIT_IF_NOT_INITIALISED ( "glutIdleFuncUcall" );
|
||||||
fgState.IdleCallback = callback;
|
fgState.IdleCallback = callback;
|
||||||
|
fgState.IdleCallbackData = userData;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
IMPLEMENT_GLUT_CALLBACK_FUNC_ARG0(Idle)
|
||||||
|
|
||||||
/* Creates a timer and sets its callback */
|
/* Creates a timer and sets its callback */
|
||||||
void FGAPIENTRY glutTimerFunc( unsigned int timeOut, FGCBTimer callback, int timerID )
|
void FGAPIENTRY glutTimerFuncUcall( unsigned int timeOut, FGCBTimerUC callback, int timerID, FGCBUserData userData )
|
||||||
{
|
{
|
||||||
SFG_Timer *timer, *node;
|
SFG_Timer *timer, *node;
|
||||||
|
|
||||||
FREEGLUT_EXIT_IF_NOT_INITIALISED ( "glutTimerFunc" );
|
FREEGLUT_EXIT_IF_NOT_INITIALISED ( "glutTimerFuncUcall" );
|
||||||
|
|
||||||
if( (timer = fgState.FreeTimers.Last) )
|
if( (timer = fgState.FreeTimers.Last) )
|
||||||
{
|
{
|
||||||
@ -60,6 +63,7 @@ void FGAPIENTRY glutTimerFunc( unsigned int timeOut, FGCBTimer callback, int tim
|
|||||||
}
|
}
|
||||||
|
|
||||||
timer->Callback = callback;
|
timer->Callback = callback;
|
||||||
|
timer->CallbackData = userData;
|
||||||
timer->ID = timerID;
|
timer->ID = timerID;
|
||||||
timer->TriggerTime = fgElapsedTime() + timeOut;
|
timer->TriggerTime = fgElapsedTime() + timeOut;
|
||||||
|
|
||||||
@ -73,6 +77,17 @@ void FGAPIENTRY glutTimerFunc( unsigned int timeOut, FGCBTimer callback, int tim
|
|||||||
fgListInsert( &fgState.Timers, &node->Node, &timer->Node );
|
fgListInsert( &fgState.Timers, &node->Node, &timer->Node );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
IMPLEMENT_CALLBACK_FUNC_CB_ARG1(Timer, Timer)
|
||||||
|
|
||||||
|
void FGAPIENTRY glutTimerFunc( unsigned int timeOut, FGCBTimer callback, int timerID )
|
||||||
|
{
|
||||||
|
FREEGLUT_EXIT_IF_NOT_INITIALISED ( "glutTimerFunc" );
|
||||||
|
if( callback )
|
||||||
|
glutTimerFuncUcall( timeOut, fghTimerFuncCallback, timerID, (FGCBUserData)callback );
|
||||||
|
else
|
||||||
|
glutTimerFuncUcall( timeOut, NULL, timerID, NULL );
|
||||||
|
}
|
||||||
|
|
||||||
/* Deprecated version of glutMenuStatusFunc callback setting method */
|
/* Deprecated version of glutMenuStatusFunc callback setting method */
|
||||||
void FGAPIENTRY glutMenuStateFunc( FGCBMenuState callback )
|
void FGAPIENTRY glutMenuStateFunc( FGCBMenuState callback )
|
||||||
{
|
{
|
||||||
@ -81,102 +96,92 @@ void FGAPIENTRY glutMenuStateFunc( FGCBMenuState callback )
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* Sets the global menu status callback for the current window */
|
/* Sets the global menu status callback for the current window */
|
||||||
void FGAPIENTRY glutMenuStatusFunc( FGCBMenuStatus callback )
|
void FGAPIENTRY glutMenuStatusFuncUcall( FGCBMenuStatusUC callback, FGCBUserData userData )
|
||||||
{
|
{
|
||||||
FREEGLUT_EXIT_IF_NOT_INITIALISED ( "glutMenuStatusFunc" );
|
FREEGLUT_EXIT_IF_NOT_INITIALISED ( "glutMenuStatusFuncUcall" );
|
||||||
fgState.MenuStatusCallback = callback;
|
fgState.MenuStatusCallback = callback;
|
||||||
|
fgState.MenuStatusCallbackData = userData;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
IMPLEMENT_GLUT_CALLBACK_FUNC_ARG3(MenuStatus)
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Menu specific callbacks.
|
* Menu specific callbacks.
|
||||||
*/
|
*/
|
||||||
/* Callback upon menu destruction */
|
/* Callback upon menu destruction */
|
||||||
void FGAPIENTRY glutMenuDestroyFunc( FGCBDestroy callback )
|
void FGAPIENTRY glutMenuDestroyFuncUcall( FGCBDestroyUC callback, FGCBUserData userData )
|
||||||
{
|
{
|
||||||
FREEGLUT_EXIT_IF_NOT_INITIALISED ( "glutMenuDestroyFunc" );
|
FREEGLUT_EXIT_IF_NOT_INITIALISED ( "glutMenuDestroyFuncUcall" );
|
||||||
if( fgStructure.CurrentMenu )
|
if( fgStructure.CurrentMenu )
|
||||||
|
{
|
||||||
fgStructure.CurrentMenu->Destroy = callback;
|
fgStructure.CurrentMenu->Destroy = callback;
|
||||||
|
fgStructure.CurrentMenu->DestroyData = userData;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
IMPLEMENT_GLUT_CALLBACK_FUNC_ARG0_2NAME(MenuDestroy, Destroy)
|
||||||
/*
|
|
||||||
* All of the window-specific callbacks setting methods can be generalized to this:
|
|
||||||
*/
|
|
||||||
#define SET_CALLBACK(a) \
|
|
||||||
do \
|
|
||||||
{ \
|
|
||||||
if( fgStructure.CurrentWindow == NULL ) \
|
|
||||||
return; \
|
|
||||||
SET_WCB( ( *( fgStructure.CurrentWindow ) ), a, callback ); \
|
|
||||||
} while( 0 )
|
|
||||||
/*
|
|
||||||
* And almost every time the callback setter function can be implemented like this:
|
|
||||||
*/
|
|
||||||
#define IMPLEMENT_CALLBACK_FUNC_2NAME(a,b) \
|
|
||||||
void FGAPIENTRY glut##a##Func( FGCB##b callback ) \
|
|
||||||
{ \
|
|
||||||
FREEGLUT_EXIT_IF_NOT_INITIALISED ( "glut"#a"Func" ); \
|
|
||||||
SET_CALLBACK( b ); \
|
|
||||||
}
|
|
||||||
#define IMPLEMENT_CALLBACK_FUNC(a) IMPLEMENT_CALLBACK_FUNC_2NAME(a,a)
|
|
||||||
|
|
||||||
/* Implement all these callback setter functions... */
|
/* Implement all these callback setter functions... */
|
||||||
IMPLEMENT_CALLBACK_FUNC(Position)
|
IMPLEMENT_CURRENT_WINDOW_CALLBACK_FUNC_ARG2(Position)
|
||||||
IMPLEMENT_CALLBACK_FUNC(Keyboard)
|
IMPLEMENT_CURRENT_WINDOW_CALLBACK_FUNC_ARG3_USER(Keyboard,unsigned char,int,int)
|
||||||
IMPLEMENT_CALLBACK_FUNC(KeyboardUp)
|
IMPLEMENT_CURRENT_WINDOW_CALLBACK_FUNC_ARG3_USER(KeyboardUp,unsigned char,int,int)
|
||||||
IMPLEMENT_CALLBACK_FUNC(Special)
|
IMPLEMENT_CURRENT_WINDOW_CALLBACK_FUNC_ARG3(Special)
|
||||||
IMPLEMENT_CALLBACK_FUNC(SpecialUp)
|
IMPLEMENT_CURRENT_WINDOW_CALLBACK_FUNC_ARG3(SpecialUp)
|
||||||
IMPLEMENT_CALLBACK_FUNC(Mouse)
|
IMPLEMENT_CURRENT_WINDOW_CALLBACK_FUNC_ARG4(Mouse)
|
||||||
IMPLEMENT_CALLBACK_FUNC(MouseWheel)
|
IMPLEMENT_CURRENT_WINDOW_CALLBACK_FUNC_ARG4(MouseWheel)
|
||||||
IMPLEMENT_CALLBACK_FUNC(Motion)
|
IMPLEMENT_CURRENT_WINDOW_CALLBACK_FUNC_ARG2(Motion)
|
||||||
IMPLEMENT_CALLBACK_FUNC_2NAME(PassiveMotion,Passive)
|
IMPLEMENT_CURRENT_WINDOW_CALLBACK_FUNC_ARG2_2NAME(PassiveMotion,Passive)
|
||||||
IMPLEMENT_CALLBACK_FUNC(Entry)
|
IMPLEMENT_CURRENT_WINDOW_CALLBACK_FUNC_ARG1(Entry)
|
||||||
/* glutWMCloseFunc is an alias for glutCloseFunc; both set the window's Destroy callback */
|
/* glutWMCloseFunc is an alias for glutCloseFunc; both set the window's Destroy callback */
|
||||||
IMPLEMENT_CALLBACK_FUNC_2NAME(Close,Destroy)
|
IMPLEMENT_CURRENT_WINDOW_CALLBACK_FUNC_ARG0_2NAME(Close,Destroy)
|
||||||
IMPLEMENT_CALLBACK_FUNC_2NAME(WMClose,Destroy)
|
IMPLEMENT_CURRENT_WINDOW_CALLBACK_FUNC_ARG0_2NAME(WMClose,Destroy)
|
||||||
IMPLEMENT_CALLBACK_FUNC(OverlayDisplay)
|
IMPLEMENT_CURRENT_WINDOW_CALLBACK_FUNC_ARG0(OverlayDisplay)
|
||||||
IMPLEMENT_CALLBACK_FUNC(WindowStatus)
|
IMPLEMENT_CURRENT_WINDOW_CALLBACK_FUNC_ARG1(WindowStatus)
|
||||||
IMPLEMENT_CALLBACK_FUNC(ButtonBox)
|
IMPLEMENT_CURRENT_WINDOW_CALLBACK_FUNC_ARG2(ButtonBox)
|
||||||
IMPLEMENT_CALLBACK_FUNC(Dials)
|
IMPLEMENT_CURRENT_WINDOW_CALLBACK_FUNC_ARG2(Dials)
|
||||||
IMPLEMENT_CALLBACK_FUNC(TabletMotion)
|
IMPLEMENT_CURRENT_WINDOW_CALLBACK_FUNC_ARG2(TabletMotion)
|
||||||
IMPLEMENT_CALLBACK_FUNC(TabletButton)
|
IMPLEMENT_CURRENT_WINDOW_CALLBACK_FUNC_ARG4(TabletButton)
|
||||||
IMPLEMENT_CALLBACK_FUNC(MultiEntry)
|
IMPLEMENT_CURRENT_WINDOW_CALLBACK_FUNC_ARG2(MultiEntry)
|
||||||
IMPLEMENT_CALLBACK_FUNC(MultiButton)
|
IMPLEMENT_CURRENT_WINDOW_CALLBACK_FUNC_ARG5(MultiButton)
|
||||||
IMPLEMENT_CALLBACK_FUNC(MultiMotion)
|
IMPLEMENT_CURRENT_WINDOW_CALLBACK_FUNC_ARG3(MultiMotion)
|
||||||
IMPLEMENT_CALLBACK_FUNC(MultiPassive)
|
IMPLEMENT_CURRENT_WINDOW_CALLBACK_FUNC_ARG3(MultiPassive)
|
||||||
IMPLEMENT_CALLBACK_FUNC(InitContext)
|
IMPLEMENT_CURRENT_WINDOW_CALLBACK_FUNC_ARG0(InitContext)
|
||||||
IMPLEMENT_CALLBACK_FUNC(AppStatus)
|
IMPLEMENT_CURRENT_WINDOW_CALLBACK_FUNC_ARG1(AppStatus)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Sets the Display callback for the current window
|
* Sets the Display callback for the current window
|
||||||
*/
|
*/
|
||||||
void FGAPIENTRY glutDisplayFunc( FGCBDisplay callback )
|
void FGAPIENTRY glutDisplayFuncUcall( FGCBDisplayUC callback, FGCBUserData userData )
|
||||||
{
|
{
|
||||||
FREEGLUT_EXIT_IF_NOT_INITIALISED ( "glutDisplayFunc" );
|
FREEGLUT_EXIT_IF_NOT_INITIALISED ( "glutDisplayFuncUcall" );
|
||||||
if( !callback )
|
if( !callback )
|
||||||
fgError( "Fatal error in program. NULL display callback not "
|
fgError( "Fatal error in program. NULL display callback not "
|
||||||
"permitted in GLUT 3.0+ or freeglut 2.0.1+" );
|
"permitted in GLUT 3.0+ or freeglut 2.0.1+" );
|
||||||
SET_CALLBACK( Display );
|
SET_CURRENT_WINDOW_CALLBACK( Display );
|
||||||
}
|
}
|
||||||
|
|
||||||
void fghDefaultReshape(int width, int height)
|
IMPLEMENT_GLUT_CALLBACK_FUNC_ARG0(Display)
|
||||||
|
|
||||||
|
void fghDefaultReshape( int width, int height, FGCBUserData userData )
|
||||||
{
|
{
|
||||||
glViewport( 0, 0, width, height );
|
glViewport( 0, 0, width, height );
|
||||||
}
|
}
|
||||||
|
|
||||||
void FGAPIENTRY glutReshapeFunc( FGCBReshape callback )
|
void FGAPIENTRY glutReshapeFuncUcall( FGCBReshapeUC callback, FGCBUserData userData )
|
||||||
{
|
{
|
||||||
FREEGLUT_EXIT_IF_NOT_INITIALISED ( "glutReshapeFunc" );
|
FREEGLUT_EXIT_IF_NOT_INITIALISED ( "glutReshapeFuncUcall" );
|
||||||
|
|
||||||
if( !callback )
|
if( !callback )
|
||||||
|
{
|
||||||
callback = fghDefaultReshape;
|
callback = fghDefaultReshape;
|
||||||
|
userData = NULL;
|
||||||
SET_CALLBACK( Reshape );
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
SET_CURRENT_WINDOW_CALLBACK( Reshape );
|
||||||
|
}
|
||||||
|
|
||||||
|
IMPLEMENT_GLUT_CALLBACK_FUNC_ARG2(Reshape)
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Sets the Visibility callback for the current window.
|
* Sets the Visibility callback for the current window.
|
||||||
* NB: the Visibility func is deprecated in favor of the WindowStatus func,
|
* NB: the Visibility func is deprecated in favor of the WindowStatus func,
|
||||||
@ -192,7 +197,7 @@ void FGAPIENTRY glutReshapeFunc( FGCBReshape callback )
|
|||||||
* http://stackoverflow.com/questions/5445889/get-which-process-window-is-actually-visible-in-c-sharp
|
* http://stackoverflow.com/questions/5445889/get-which-process-window-is-actually-visible-in-c-sharp
|
||||||
* for an implementation outline (but it would be polling based, not push based).
|
* for an implementation outline (but it would be polling based, not push based).
|
||||||
*/
|
*/
|
||||||
static void fghVisibility( int status )
|
static void fghVisibility( int status, FGCBUserData userData )
|
||||||
{
|
{
|
||||||
int vis_status;
|
int vis_status;
|
||||||
|
|
||||||
@ -200,7 +205,7 @@ static void fghVisibility( int status )
|
|||||||
freeglut_return_if_fail( fgStructure.CurrentWindow );
|
freeglut_return_if_fail( fgStructure.CurrentWindow );
|
||||||
|
|
||||||
/* Translate window status func states to visibility states */
|
/* Translate window status func states to visibility states */
|
||||||
if( ( GLUT_HIDDEN == status ) || ( GLUT_FULLY_COVERED == status ) )
|
if( ( status == GLUT_HIDDEN) || ( status == GLUT_FULLY_COVERED) )
|
||||||
vis_status = GLUT_NOT_VISIBLE;
|
vis_status = GLUT_NOT_VISIBLE;
|
||||||
else /* GLUT_FULLY_RETAINED, GLUT_PARTIALLY_RETAINED */
|
else /* GLUT_FULLY_RETAINED, GLUT_PARTIALLY_RETAINED */
|
||||||
vis_status = GLUT_VISIBLE;
|
vis_status = GLUT_VISIBLE;
|
||||||
@ -208,23 +213,31 @@ static void fghVisibility( int status )
|
|||||||
INVOKE_WCB( *( fgStructure.CurrentWindow ), Visibility, ( vis_status ) );
|
INVOKE_WCB( *( fgStructure.CurrentWindow ), Visibility, ( vis_status ) );
|
||||||
}
|
}
|
||||||
|
|
||||||
void FGAPIENTRY glutVisibilityFunc( FGCBVisibility callback )
|
void FGAPIENTRY glutVisibilityFuncUcall( FGCBVisibilityUC callback, FGCBUserData userData )
|
||||||
{
|
{
|
||||||
FREEGLUT_EXIT_IF_NOT_INITIALISED ( "glutVisibilityFunc" );
|
FREEGLUT_EXIT_IF_NOT_INITIALISED ( "glutVisibilityFuncUcall" );
|
||||||
SET_CALLBACK( Visibility );
|
|
||||||
|
if ( !callback )
|
||||||
|
{
|
||||||
|
userData = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
SET_CURRENT_WINDOW_CALLBACK( Visibility );
|
||||||
|
|
||||||
if( callback )
|
if( callback )
|
||||||
glutWindowStatusFunc( fghVisibility );
|
glutWindowStatusFuncUcall( fghVisibility, NULL );
|
||||||
else
|
else
|
||||||
glutWindowStatusFunc( NULL );
|
glutWindowStatusFuncUcall( NULL, NULL );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
IMPLEMENT_GLUT_CALLBACK_FUNC_ARG1(Visibility)
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Sets the joystick callback and polling rate for the current window
|
* Sets the joystick callback and polling rate for the current window
|
||||||
*/
|
*/
|
||||||
void FGAPIENTRY glutJoystickFunc( FGCBJoystick callback, int pollInterval )
|
void FGAPIENTRY glutJoystickFuncUcall( FGCBJoystickUC callback, int pollInterval, FGCBUserData userData )
|
||||||
{
|
{
|
||||||
FREEGLUT_EXIT_IF_NOT_INITIALISED ( "glutJoystickFunc" );
|
FREEGLUT_EXIT_IF_NOT_INITIALISED ( "glutJoystickFuncUcall" );
|
||||||
fgInitialiseJoysticks ();
|
fgInitialiseJoysticks ();
|
||||||
|
|
||||||
if ( (
|
if ( (
|
||||||
@ -244,7 +257,7 @@ void FGAPIENTRY glutJoystickFunc( FGCBJoystick callback, int pollInterval )
|
|||||||
) )
|
) )
|
||||||
--fgState.NumActiveJoysticks;
|
--fgState.NumActiveJoysticks;
|
||||||
|
|
||||||
SET_CALLBACK( Joystick );
|
SET_CURRENT_WINDOW_CALLBACK( Joystick );
|
||||||
fgStructure.CurrentWindow->State.JoystickPollRate = pollInterval;
|
fgStructure.CurrentWindow->State.JoystickPollRate = pollInterval;
|
||||||
|
|
||||||
/* set last poll time such that joystick will be polled asap */
|
/* set last poll time such that joystick will be polled asap */
|
||||||
@ -255,39 +268,58 @@ void FGAPIENTRY glutJoystickFunc( FGCBJoystick callback, int pollInterval )
|
|||||||
fgStructure.CurrentWindow->State.JoystickLastPoll -= pollInterval;
|
fgStructure.CurrentWindow->State.JoystickLastPoll -= pollInterval;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void fghJoystickFuncCallback( unsigned int buttons, int axis0, int axis1, int axis2, FGCBUserData userData )
|
||||||
|
{
|
||||||
|
FGCBJoystick callback = (FGCBJoystick)userData;
|
||||||
|
callback( buttons, axis0, axis1, axis2 );
|
||||||
|
}
|
||||||
|
|
||||||
|
void FGAPIENTRY glutJoystickFunc( FGCBJoystick callback, int pollInterval )
|
||||||
|
{
|
||||||
|
FREEGLUT_EXIT_IF_NOT_INITIALISED ( "glutJoystickFunc" );
|
||||||
|
if( callback )
|
||||||
|
glutJoystickFuncUcall( fghJoystickFuncCallback, pollInterval, (FGCBUserData)callback );
|
||||||
|
else
|
||||||
|
glutJoystickFuncUcall( NULL, pollInterval, NULL );
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Sets the spaceball motion callback for the current window
|
* Sets the spaceball motion callback for the current window
|
||||||
*/
|
*/
|
||||||
void FGAPIENTRY glutSpaceballMotionFunc( FGCBSpaceMotion callback )
|
void FGAPIENTRY glutSpaceballMotionFuncUcall( FGCBSpaceMotionUC callback, FGCBUserData userData )
|
||||||
{
|
{
|
||||||
FREEGLUT_EXIT_IF_NOT_INITIALISED ( "glutSpaceballMotionFunc" );
|
FREEGLUT_EXIT_IF_NOT_INITIALISED ( "glutSpaceballMotionFuncUcall" );
|
||||||
fgInitialiseSpaceball();
|
fgInitialiseSpaceball();
|
||||||
|
|
||||||
SET_CALLBACK( SpaceMotion );
|
SET_CURRENT_WINDOW_CALLBACK( SpaceMotion );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
IMPLEMENT_GLUT_CALLBACK_FUNC_ARG3_2NAME(SpaceballMotion, SpaceMotion)
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Sets the spaceball rotate callback for the current window
|
* Sets the spaceball rotate callback for the current window
|
||||||
*/
|
*/
|
||||||
void FGAPIENTRY glutSpaceballRotateFunc( FGCBSpaceRotation callback )
|
void FGAPIENTRY glutSpaceballRotateFuncUcall( FGCBSpaceRotationUC callback, FGCBUserData userData )
|
||||||
{
|
{
|
||||||
FREEGLUT_EXIT_IF_NOT_INITIALISED ( "glutSpaceballRotateFunc" );
|
FREEGLUT_EXIT_IF_NOT_INITIALISED ( "glutSpaceballRotateFuncUcall" );
|
||||||
fgInitialiseSpaceball();
|
fgInitialiseSpaceball();
|
||||||
|
|
||||||
SET_CALLBACK( SpaceRotation );
|
SET_CURRENT_WINDOW_CALLBACK( SpaceRotation );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
IMPLEMENT_GLUT_CALLBACK_FUNC_ARG3_2NAME(SpaceballRotate, SpaceRotation)
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Sets the spaceball button callback for the current window
|
* Sets the spaceball button callback for the current window
|
||||||
*/
|
*/
|
||||||
void FGAPIENTRY glutSpaceballButtonFunc( FGCBSpaceButton callback )
|
void FGAPIENTRY glutSpaceballButtonFuncUcall( FGCBSpaceButtonUC callback, FGCBUserData userData )
|
||||||
{
|
{
|
||||||
FREEGLUT_EXIT_IF_NOT_INITIALISED ( "glutSpaceballButtonFunc" );
|
FREEGLUT_EXIT_IF_NOT_INITIALISED ( "glutSpaceballButtonFuncUcall" );
|
||||||
fgInitialiseSpaceball();
|
fgInitialiseSpaceball();
|
||||||
|
|
||||||
SET_CALLBACK( SpaceButton );
|
SET_CURRENT_WINDOW_CALLBACK( SpaceButton );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
IMPLEMENT_GLUT_CALLBACK_FUNC_ARG2_2NAME(SpaceballButton, SpaceButton)
|
||||||
|
|
||||||
/*** END OF FILE ***/
|
/*** END OF FILE ***/
|
||||||
|
@ -210,6 +210,46 @@ static GLUTproc fghGetGLUTProcAddress( const char* procName )
|
|||||||
CHECK_NAME(glutSetVertexAttribCoord3);
|
CHECK_NAME(glutSetVertexAttribCoord3);
|
||||||
CHECK_NAME(glutSetVertexAttribNormal);
|
CHECK_NAME(glutSetVertexAttribNormal);
|
||||||
CHECK_NAME(glutSetVertexAttribTexCoord2);
|
CHECK_NAME(glutSetVertexAttribTexCoord2);
|
||||||
|
|
||||||
|
/* freeglut user callback functions */
|
||||||
|
CHECK_NAME(glutCreateMenuUcall);
|
||||||
|
CHECK_NAME(glutTimerFuncUcall);
|
||||||
|
CHECK_NAME(glutIdleFuncUcall);
|
||||||
|
CHECK_NAME(glutKeyboardFuncUcall);
|
||||||
|
CHECK_NAME(glutSpecialFuncUcall);
|
||||||
|
CHECK_NAME(glutReshapeFuncUcall);
|
||||||
|
CHECK_NAME(glutVisibilityFuncUcall);
|
||||||
|
CHECK_NAME(glutDisplayFuncUcall);
|
||||||
|
CHECK_NAME(glutMouseFuncUcall);
|
||||||
|
CHECK_NAME(glutMotionFuncUcall);
|
||||||
|
CHECK_NAME(glutPassiveMotionFuncUcall);
|
||||||
|
CHECK_NAME(glutEntryFuncUcall);
|
||||||
|
CHECK_NAME(glutKeyboardUpFuncUcall);
|
||||||
|
CHECK_NAME(glutSpecialUpFuncUcall);
|
||||||
|
CHECK_NAME(glutJoystickFuncUcall);
|
||||||
|
CHECK_NAME(glutMenuStatusFuncUcall);
|
||||||
|
CHECK_NAME(glutOverlayDisplayFuncUcall);
|
||||||
|
CHECK_NAME(glutWindowStatusFuncUcall);
|
||||||
|
CHECK_NAME(glutSpaceballMotionFuncUcall);
|
||||||
|
CHECK_NAME(glutSpaceballRotateFuncUcall);
|
||||||
|
CHECK_NAME(glutSpaceballButtonFuncUcall);
|
||||||
|
CHECK_NAME(glutButtonBoxFuncUcall);
|
||||||
|
CHECK_NAME(glutDialsFuncUcall);
|
||||||
|
CHECK_NAME(glutTabletMotionFuncUcall);
|
||||||
|
CHECK_NAME(glutTabletButtonFuncUcall);
|
||||||
|
CHECK_NAME(glutMouseWheelFuncUcall);
|
||||||
|
CHECK_NAME(glutPositionFuncUcall);
|
||||||
|
CHECK_NAME(glutCloseFuncUcall);
|
||||||
|
CHECK_NAME(glutWMCloseFuncUcall);
|
||||||
|
CHECK_NAME(glutMenuDestroyFuncUcall);
|
||||||
|
CHECK_NAME(glutMultiEntryFuncUcall);
|
||||||
|
CHECK_NAME(glutMultiButtonFuncUcall);
|
||||||
|
CHECK_NAME(glutMultiMotionFuncUcall);
|
||||||
|
CHECK_NAME(glutMultiPassiveFuncUcall);
|
||||||
|
CHECK_NAME(glutInitErrorFuncUcall);
|
||||||
|
CHECK_NAME(glutInitWarningFuncUcall);
|
||||||
|
CHECK_NAME(glutInitContextFuncUcall);
|
||||||
|
CHECK_NAME(glutAppStatusFuncUcall);
|
||||||
#undef CHECK_NAME
|
#undef CHECK_NAME
|
||||||
|
|
||||||
return NULL;
|
return NULL;
|
||||||
|
@ -70,9 +70,11 @@ SFG_State fgState = { { -1, -1, GL_FALSE }, /* Position */
|
|||||||
{ NULL, NULL }, /* Timers */
|
{ NULL, NULL }, /* Timers */
|
||||||
{ NULL, NULL }, /* FreeTimers */
|
{ NULL, NULL }, /* FreeTimers */
|
||||||
NULL, /* IdleCallback */
|
NULL, /* IdleCallback */
|
||||||
|
NULL, /* IdleCallbackData */
|
||||||
0, /* ActiveMenus */
|
0, /* ActiveMenus */
|
||||||
NULL, /* MenuStateCallback */
|
NULL, /* MenuStateCallback */
|
||||||
NULL, /* MenuStatusCallback */
|
NULL, /* MenuStatusCallback */
|
||||||
|
NULL, /* MenuStatusCallbackData */
|
||||||
FREEGLUT_MENU_FONT,
|
FREEGLUT_MENU_FONT,
|
||||||
{ -1, -1, GL_TRUE }, /* GameModeSize */
|
{ -1, -1, GL_TRUE }, /* GameModeSize */
|
||||||
-1, /* GameModeDepth */
|
-1, /* GameModeDepth */
|
||||||
@ -95,7 +97,9 @@ SFG_State fgState = { { -1, -1, GL_FALSE }, /* Position */
|
|||||||
0, /* OpenGL ContextProfile */
|
0, /* OpenGL ContextProfile */
|
||||||
0, /* HasOpenGL20 */
|
0, /* HasOpenGL20 */
|
||||||
NULL, /* ErrorFunc */
|
NULL, /* ErrorFunc */
|
||||||
NULL /* WarningFunc */
|
NULL, /* ErrorFuncData */
|
||||||
|
NULL, /* WarningFunc */
|
||||||
|
NULL /* WarningFuncData */
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
@ -298,9 +302,11 @@ void fgDeinitialize( void )
|
|||||||
fgListInit( &fgState.Timers );
|
fgListInit( &fgState.Timers );
|
||||||
fgListInit( &fgState.FreeTimers );
|
fgListInit( &fgState.FreeTimers );
|
||||||
|
|
||||||
fgState.IdleCallback = NULL;
|
fgState.IdleCallback = ( FGCBIdleUC )NULL;
|
||||||
|
fgState.IdleCallbackData = NULL;
|
||||||
fgState.MenuStateCallback = ( FGCBMenuState )NULL;
|
fgState.MenuStateCallback = ( FGCBMenuState )NULL;
|
||||||
fgState.MenuStatusCallback = ( FGCBMenuStatus )NULL;
|
fgState.MenuStatusCallback = ( FGCBMenuStatusUC )NULL;
|
||||||
|
fgState.MenuStatusCallbackData = NULL;
|
||||||
|
|
||||||
fgState.SwapCount = 0;
|
fgState.SwapCount = 0;
|
||||||
fgState.SwapTime = 0;
|
fgState.SwapTime = 0;
|
||||||
@ -668,19 +674,57 @@ void FGAPIENTRY glutInitContextProfile( int profile )
|
|||||||
/*
|
/*
|
||||||
* Sets the user error handler (note the use of va_list for the args to the fmt)
|
* Sets the user error handler (note the use of va_list for the args to the fmt)
|
||||||
*/
|
*/
|
||||||
void FGAPIENTRY glutInitErrorFunc( FGError callback )
|
void FGAPIENTRY glutInitErrorFuncUcall( FGErrorUC callback, FGCBUserData userData )
|
||||||
{
|
{
|
||||||
/* This allows user programs to handle freeglut errors */
|
/* This allows user programs to handle freeglut errors */
|
||||||
fgState.ErrorFunc = callback;
|
fgState.ErrorFunc = callback;
|
||||||
|
fgState.ErrorFuncData = userData;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void fghInitErrorFuncCallback( const char *fmt, va_list ap, FGCBUserData userData )
|
||||||
|
{
|
||||||
|
FGError callback = (FGError)userData;
|
||||||
|
callback( fmt, ap );
|
||||||
|
}
|
||||||
|
|
||||||
|
void FGAPIENTRY glutInitErrorFunc( FGError callback )
|
||||||
|
{
|
||||||
|
if (callback)
|
||||||
|
{
|
||||||
|
glutInitErrorFuncUcall( fghInitErrorFuncCallback, (FGCBUserData)callback );
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
glutInitErrorFuncUcall( NULL, NULL );
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Sets the user warning handler (note the use of va_list for the args to the fmt)
|
* Sets the user warning handler (note the use of va_list for the args to the fmt)
|
||||||
*/
|
*/
|
||||||
void FGAPIENTRY glutInitWarningFunc( FGWarning callback )
|
void FGAPIENTRY glutInitWarningFuncUcall( FGWarningUC callback, FGCBUserData userData )
|
||||||
{
|
{
|
||||||
/* This allows user programs to handle freeglut warnings */
|
/* This allows user programs to handle freeglut warnings */
|
||||||
fgState.WarningFunc = callback;
|
fgState.WarningFunc = callback;
|
||||||
|
fgState.WarningFuncData = userData;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void fghInitWarningFuncCallback( const char *fmt, va_list ap, FGCBUserData userData )
|
||||||
|
{
|
||||||
|
FGWarning callback = (FGWarning)userData;
|
||||||
|
callback( fmt, ap );
|
||||||
|
}
|
||||||
|
|
||||||
|
void FGAPIENTRY glutInitWarningFunc( FGWarning callback )
|
||||||
|
{
|
||||||
|
if (callback)
|
||||||
|
{
|
||||||
|
glutInitWarningFuncUcall( fghInitWarningFuncCallback, (FGCBUserData)callback );
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
glutInitWarningFuncUcall( NULL, NULL );
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/*** END OF FILE ***/
|
/*** END OF FILE ***/
|
||||||
|
@ -33,12 +33,14 @@
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
#include "fg_version.h"
|
#include "fg_version.h"
|
||||||
|
#include "fg_callback_macros.h"
|
||||||
|
|
||||||
/* Freeglut is intended to function under all Unix/X11 and Win32 platforms. */
|
/* Freeglut is intended to function under all Unix/X11 and Win32 platforms. */
|
||||||
/* XXX: Don't all MS-Windows compilers (except Cygwin) have _WIN32 defined?
|
/* XXX: Don't all MS-Windows compilers (except Cygwin) have _WIN32 defined?
|
||||||
* XXX: If so, remove the first set of defined()'s below.
|
* XXX: If so, remove the first set of defined()'s below.
|
||||||
*/
|
*/
|
||||||
#if !defined(TARGET_HOST_POSIX_X11) && !defined(TARGET_HOST_MS_WINDOWS) && !defined(TARGET_HOST_MAC_OSX) && !defined(TARGET_HOST_SOLARIS)
|
#if !defined(TARGET_HOST_POSIX_X11) && !defined(TARGET_HOST_MS_WINDOWS) && !defined(TARGET_HOST_MAC_OSX) && !defined(TARGET_HOST_SOLARIS) && \
|
||||||
|
!defined(TARGET_HOST_ANDROID) && !defined(TARGET_HOST_BLACKBERRY) && !defined(TARGET_HOST_POSIX_WAYLAND)
|
||||||
#if defined(_MSC_VER) || defined(__WATCOMC__) || defined(__MINGW32__) \
|
#if defined(_MSC_VER) || defined(__WATCOMC__) || defined(__MINGW32__) \
|
||||||
|| defined(_WIN32) || defined(_WIN32_WCE) \
|
|| defined(_WIN32) || defined(_WIN32_WCE) \
|
||||||
|| ( defined(__CYGWIN__) && defined(X_DISPLAY_MISSING) )
|
|| ( defined(__CYGWIN__) && defined(X_DISPLAY_MISSING) )
|
||||||
@ -215,52 +217,97 @@
|
|||||||
|
|
||||||
/* -- GLOBAL TYPE DEFINITIONS ---------------------------------------------- */
|
/* -- GLOBAL TYPE DEFINITIONS ---------------------------------------------- */
|
||||||
|
|
||||||
/* Freeglut callbacks type definitions */
|
/*
|
||||||
|
* Freeglut callbacks type definitions
|
||||||
|
*
|
||||||
|
* If anything here is modified or added, update fg_callback_macros.h functions.
|
||||||
|
*
|
||||||
|
* This is not ideal, but freeglut needs to either define minimal compiler specs,
|
||||||
|
* or update header every time this is changed or updated.
|
||||||
|
*/
|
||||||
|
typedef void* FGCBUserData;
|
||||||
|
|
||||||
typedef void (* FGCBDisplay )( void );
|
typedef void (* FGCBDisplay )( void );
|
||||||
|
typedef void (* FGCBDisplayUC )( FGCBUserData );
|
||||||
typedef void (* FGCBReshape )( int, int );
|
typedef void (* FGCBReshape )( int, int );
|
||||||
|
typedef void (* FGCBReshapeUC )( int, int, FGCBUserData );
|
||||||
typedef void (* FGCBPosition )( int, int );
|
typedef void (* FGCBPosition )( int, int );
|
||||||
|
typedef void (* FGCBPositionUC )( int, int, FGCBUserData );
|
||||||
typedef void (* FGCBVisibility )( int );
|
typedef void (* FGCBVisibility )( int );
|
||||||
|
typedef void (* FGCBVisibilityUC )( int, FGCBUserData );
|
||||||
typedef void (* FGCBKeyboard )( unsigned char, int, int );
|
typedef void (* FGCBKeyboard )( unsigned char, int, int );
|
||||||
|
typedef void (* FGCBKeyboardUC )( unsigned char, int, int, FGCBUserData );
|
||||||
typedef void (* FGCBKeyboardUp )( unsigned char, int, int );
|
typedef void (* FGCBKeyboardUp )( unsigned char, int, int );
|
||||||
|
typedef void (* FGCBKeyboardUpUC )( unsigned char, int, int, FGCBUserData );
|
||||||
typedef void (* FGCBSpecial )( int, int, int );
|
typedef void (* FGCBSpecial )( int, int, int );
|
||||||
|
typedef void (* FGCBSpecialUC )( int, int, int, FGCBUserData );
|
||||||
typedef void (* FGCBSpecialUp )( int, int, int );
|
typedef void (* FGCBSpecialUp )( int, int, int );
|
||||||
|
typedef void (* FGCBSpecialUpUC )( int, int, int, FGCBUserData );
|
||||||
typedef void (* FGCBMouse )( int, int, int, int );
|
typedef void (* FGCBMouse )( int, int, int, int );
|
||||||
|
typedef void (* FGCBMouseUC )( int, int, int, int, FGCBUserData );
|
||||||
typedef void (* FGCBMouseWheel )( int, int, int, int );
|
typedef void (* FGCBMouseWheel )( int, int, int, int );
|
||||||
|
typedef void (* FGCBMouseWheelUC )( int, int, int, int, FGCBUserData );
|
||||||
typedef void (* FGCBMotion )( int, int );
|
typedef void (* FGCBMotion )( int, int );
|
||||||
|
typedef void (* FGCBMotionUC )( int, int, FGCBUserData );
|
||||||
typedef void (* FGCBPassive )( int, int );
|
typedef void (* FGCBPassive )( int, int );
|
||||||
|
typedef void (* FGCBPassiveUC )( int, int, FGCBUserData );
|
||||||
typedef void (* FGCBEntry )( int );
|
typedef void (* FGCBEntry )( int );
|
||||||
|
typedef void (* FGCBEntryUC )( int, FGCBUserData );
|
||||||
typedef void (* FGCBWindowStatus )( int );
|
typedef void (* FGCBWindowStatus )( int );
|
||||||
|
typedef void (* FGCBWindowStatusUC )( int, FGCBUserData );
|
||||||
typedef void (* FGCBJoystick )( unsigned int, int, int, int );
|
typedef void (* FGCBJoystick )( unsigned int, int, int, int );
|
||||||
|
typedef void (* FGCBJoystickUC )( unsigned int, int, int, int, FGCBUserData );
|
||||||
typedef void (* FGCBOverlayDisplay )( void );
|
typedef void (* FGCBOverlayDisplay )( void );
|
||||||
|
typedef void (* FGCBOverlayDisplayUC)( FGCBUserData );
|
||||||
typedef void (* FGCBSpaceMotion )( int, int, int );
|
typedef void (* FGCBSpaceMotion )( int, int, int );
|
||||||
|
typedef void (* FGCBSpaceMotionUC )( int, int, int, FGCBUserData );
|
||||||
typedef void (* FGCBSpaceRotation )( int, int, int );
|
typedef void (* FGCBSpaceRotation )( int, int, int );
|
||||||
|
typedef void (* FGCBSpaceRotationUC )( int, int, int, FGCBUserData );
|
||||||
typedef void (* FGCBSpaceButton )( int, int );
|
typedef void (* FGCBSpaceButton )( int, int );
|
||||||
|
typedef void (* FGCBSpaceButtonUC )( int, int, FGCBUserData );
|
||||||
typedef void (* FGCBDials )( int, int );
|
typedef void (* FGCBDials )( int, int );
|
||||||
|
typedef void (* FGCBDialsUC )( int, int, FGCBUserData );
|
||||||
typedef void (* FGCBButtonBox )( int, int );
|
typedef void (* FGCBButtonBox )( int, int );
|
||||||
|
typedef void (* FGCBButtonBoxUC )( int, int, FGCBUserData );
|
||||||
typedef void (* FGCBTabletMotion )( int, int );
|
typedef void (* FGCBTabletMotion )( int, int );
|
||||||
|
typedef void (* FGCBTabletMotionUC )( int, int, FGCBUserData );
|
||||||
typedef void (* FGCBTabletButton )( int, int, int, int );
|
typedef void (* FGCBTabletButton )( int, int, int, int );
|
||||||
|
typedef void (* FGCBTabletButtonUC )( int, int, int, int, FGCBUserData );
|
||||||
typedef void (* FGCBDestroy )( void ); /* Used for both window and menu destroy callbacks */
|
typedef void (* FGCBDestroy )( void ); /* Used for both window and menu destroy callbacks */
|
||||||
|
typedef void (* FGCBDestroyUC )( FGCBUserData );
|
||||||
|
|
||||||
typedef void (* FGCBMultiEntry )( int, int );
|
typedef void (* FGCBMultiEntry )( int, int );
|
||||||
|
typedef void (* FGCBMultiEntryUC )( int, int, FGCBUserData );
|
||||||
typedef void (* FGCBMultiButton )( int, int, int, int, int );
|
typedef void (* FGCBMultiButton )( int, int, int, int, int );
|
||||||
|
typedef void (* FGCBMultiButtonUC )( int, int, int, int, int, FGCBUserData );
|
||||||
typedef void (* FGCBMultiMotion )( int, int, int );
|
typedef void (* FGCBMultiMotion )( int, int, int );
|
||||||
|
typedef void (* FGCBMultiMotionUC )( int, int, int, FGCBUserData );
|
||||||
typedef void (* FGCBMultiPassive )( int, int, int );
|
typedef void (* FGCBMultiPassive )( int, int, int );
|
||||||
|
typedef void (* FGCBMultiPassiveUC )( int, int, int, FGCBUserData );
|
||||||
|
|
||||||
typedef void (* FGCBInitContext)();
|
typedef void (* FGCBInitContext )( void );
|
||||||
|
typedef void (* FGCBInitContextUC )( FGCBUserData );
|
||||||
typedef void (* FGCBAppStatus )( int );
|
typedef void (* FGCBAppStatus )( int );
|
||||||
|
typedef void (* FGCBAppStatusUC )( int, FGCBUserData );
|
||||||
|
|
||||||
/* The global callbacks type definitions */
|
/* The global callbacks type definitions */
|
||||||
typedef void (* FGCBIdle )( void );
|
typedef void (* FGCBIdle )( void );
|
||||||
|
typedef void (* FGCBIdleUC )( FGCBUserData );
|
||||||
typedef void (* FGCBTimer )( int );
|
typedef void (* FGCBTimer )( int );
|
||||||
|
typedef void (* FGCBTimerUC )( int, FGCBUserData );
|
||||||
typedef void (* FGCBMenuState )( int );
|
typedef void (* FGCBMenuState )( int );
|
||||||
typedef void (* FGCBMenuStatus )( int, int, int );
|
typedef void (* FGCBMenuStatus )( int, int, int );
|
||||||
|
typedef void (* FGCBMenuStatusUC )( int, int, int, FGCBUserData );
|
||||||
|
|
||||||
/* The callback used when creating/using menus */
|
/* The callback used when creating/using menus */
|
||||||
typedef void (* FGCBMenu )( int );
|
typedef void (* FGCBMenu )( int );
|
||||||
|
typedef void (* FGCBMenuUC )( int, FGCBUserData );
|
||||||
|
|
||||||
/* The FreeGLUT error/warning handler type definition */
|
/* The FreeGLUT error/warning handler type definition */
|
||||||
typedef void (* FGError )( const char *fmt, va_list ap );
|
typedef void (* FGError )( const char *fmt, va_list ap );
|
||||||
|
typedef void (* FGErrorUC )( const char *fmt, va_list ap, FGCBUserData userData );
|
||||||
typedef void (* FGWarning )( const char *fmt, va_list ap );
|
typedef void (* FGWarning )( const char *fmt, va_list ap );
|
||||||
|
typedef void (* FGWarningUC )( const char *fmt, va_list ap, FGCBUserData userData );
|
||||||
|
|
||||||
|
|
||||||
/* A list structure */
|
/* A list structure */
|
||||||
@ -327,11 +374,13 @@ struct tagSFG_State
|
|||||||
SFG_List Timers; /* The freeglut timer hooks */
|
SFG_List Timers; /* The freeglut timer hooks */
|
||||||
SFG_List FreeTimers; /* The unused timer hooks */
|
SFG_List FreeTimers; /* The unused timer hooks */
|
||||||
|
|
||||||
FGCBIdle IdleCallback; /* The global idle callback */
|
FGCBIdleUC IdleCallback; /* The global idle callback */
|
||||||
|
FGCBUserData IdleCallbackData; /* The global idle callback data */
|
||||||
|
|
||||||
int ActiveMenus; /* Num. of currently active menus */
|
int ActiveMenus; /* Num. of currently active menus */
|
||||||
FGCBMenuState MenuStateCallback; /* Menu callbacks are global */
|
FGCBMenuState MenuStateCallback; /* Menu callbacks are global */
|
||||||
FGCBMenuStatus MenuStatusCallback;
|
FGCBMenuStatusUC MenuStatusCallback;
|
||||||
|
FGCBUserData MenuStatusCallbackData;
|
||||||
void* MenuFont; /* Font to be used for newly created menus */
|
void* MenuFont; /* Font to be used for newly created menus */
|
||||||
|
|
||||||
SFG_XYUse GameModeSize; /* Game mode screen's dimensions */
|
SFG_XYUse GameModeSize; /* Game mode screen's dimensions */
|
||||||
@ -361,8 +410,10 @@ struct tagSFG_State
|
|||||||
int ContextFlags; /* OpenGL context flags */
|
int ContextFlags; /* OpenGL context flags */
|
||||||
int ContextProfile; /* OpenGL context profile */
|
int ContextProfile; /* OpenGL context profile */
|
||||||
int HasOpenGL20; /* fgInitGL2 could find all OpenGL 2.0 functions */
|
int HasOpenGL20; /* fgInitGL2 could find all OpenGL 2.0 functions */
|
||||||
FGError ErrorFunc; /* User defined error handler */
|
FGErrorUC ErrorFunc; /* User defined error handler */
|
||||||
FGWarning WarningFunc; /* User defined warning handler */
|
FGCBUserData ErrorFuncData; /* User defined error handler user data */
|
||||||
|
FGWarningUC WarningFunc; /* User defined warning handler */
|
||||||
|
FGCBUserData WarningFuncData; /* User defined warning handler user data */
|
||||||
};
|
};
|
||||||
|
|
||||||
/* The structure used by display initialization in fg_init.c */
|
/* The structure used by display initialization in fg_init.c */
|
||||||
@ -384,7 +435,8 @@ struct tagSFG_Timer
|
|||||||
{
|
{
|
||||||
SFG_Node Node;
|
SFG_Node Node;
|
||||||
int ID; /* The timer ID integer */
|
int ID; /* The timer ID integer */
|
||||||
FGCBTimer Callback; /* The timer callback */
|
FGCBTimerUC Callback; /* The timer callback */
|
||||||
|
FGCBUserData CallbackData; /* The timer callback user data */
|
||||||
fg_time_t TriggerTime; /* The timer trigger time */
|
fg_time_t TriggerTime; /* The timer trigger time */
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -511,11 +563,12 @@ typedef void (*SFG_Proc)();
|
|||||||
/*
|
/*
|
||||||
* SET_WCB() is used as:
|
* SET_WCB() is used as:
|
||||||
*
|
*
|
||||||
* SET_WCB( window, cbname, func );
|
* SET_WCB( window, cbname, func, udata );
|
||||||
*
|
*
|
||||||
* ...where {window} is the freeglut window to set the callback,
|
* ...where {window} is the freeglut window to set the callback,
|
||||||
* {cbname} is the window-specific callback to set,
|
* {cbname} is the window-specific callback to set,
|
||||||
* {func} is a function-pointer.
|
* {func} is a function-pointer,
|
||||||
|
* {udata} is a void* pointer for user data.
|
||||||
*
|
*
|
||||||
* Originally, {FETCH_WCB( ... ) = func} was rather sloppily used,
|
* Originally, {FETCH_WCB( ... ) = func} was rather sloppily used,
|
||||||
* but this can cause warnings because the FETCH_WCB() macro type-
|
* but this can cause warnings because the FETCH_WCB() macro type-
|
||||||
@ -524,12 +577,25 @@ typedef void (*SFG_Proc)();
|
|||||||
* The {if( FETCH_WCB( ... ) != func )} test is to do type-checking
|
* The {if( FETCH_WCB( ... ) != func )} test is to do type-checking
|
||||||
* and for no other reason. Since it's hidden in the macro, the
|
* and for no other reason. Since it's hidden in the macro, the
|
||||||
* ugliness is felt to be rather benign.
|
* ugliness is felt to be rather benign.
|
||||||
|
*
|
||||||
|
* If the function-pointer is the same, the data will be the only
|
||||||
|
* value updated. If the function-pointer changes, the data will
|
||||||
|
* be changed as well, preventing stail data from being passed in.
|
||||||
|
* Just updating the data does nothing unless a function-pointer
|
||||||
|
* exists, as the data is otherwise already allocated.
|
||||||
*/
|
*/
|
||||||
#define SET_WCB(window,cbname,func) \
|
#define SET_WCB(window,cbname,func,udata) \
|
||||||
do \
|
do \
|
||||||
{ \
|
{ \
|
||||||
if( FETCH_WCB( window, cbname ) != (SFG_Proc)(func) ) \
|
if( FETCH_WCB( window, cbname ) != (SFG_Proc)(func) ) \
|
||||||
|
{ \
|
||||||
(((window).CallBacks[WCB_ ## cbname]) = (SFG_Proc)(func)); \
|
(((window).CallBacks[WCB_ ## cbname]) = (SFG_Proc)(func)); \
|
||||||
|
(((window).CallbackDatas[WCB_ ## cbname]) = (udata)); \
|
||||||
|
} \
|
||||||
|
else if( FETCH_USER_DATA_WCB( window, cbname ) != udata ) \
|
||||||
|
{ \
|
||||||
|
(((window).CallbackDatas[WCB_ ## cbname]) = (udata)); \
|
||||||
|
} \
|
||||||
} while( 0 )
|
} while( 0 )
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -546,6 +612,39 @@ do \
|
|||||||
#define FETCH_WCB(window,cbname) \
|
#define FETCH_WCB(window,cbname) \
|
||||||
((window).CallBacks[WCB_ ## cbname])
|
((window).CallBacks[WCB_ ## cbname])
|
||||||
|
|
||||||
|
/*
|
||||||
|
* FETCH_USER_DATA_WCB() is used as:
|
||||||
|
*
|
||||||
|
* FETCH_USER_DATA_WCB( window, cbname );
|
||||||
|
*
|
||||||
|
* ...where {window} is the freeglut window,
|
||||||
|
* {cbname} is the window-specific callback to be invoked,
|
||||||
|
*
|
||||||
|
* This expects a variable named "window" of type tagSFG_Window to exist.
|
||||||
|
*
|
||||||
|
* The result is the callback data pointer.
|
||||||
|
*/
|
||||||
|
#define FETCH_USER_DATA_WCB(window,cbname) \
|
||||||
|
((window).CallbackDatas[WCB_ ## cbname])
|
||||||
|
|
||||||
|
/*
|
||||||
|
* EXPAND_WCB() is used as:
|
||||||
|
*
|
||||||
|
* EXPAND_WCB( cbname )(( arg_list, userData ))
|
||||||
|
*
|
||||||
|
* ... where {(arg_list)} is the parameter list and userData is user
|
||||||
|
* provided data.
|
||||||
|
*
|
||||||
|
* This will take the arg_list and extend it by one argument, adding
|
||||||
|
* the argument "userData" to the end of the list.
|
||||||
|
*
|
||||||
|
* All of this is defined in fg_callback_macros.h
|
||||||
|
*
|
||||||
|
* See that header for more info.
|
||||||
|
*
|
||||||
|
* ------------------------------------------------------------------
|
||||||
|
*/
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* INVOKE_WCB() is used as:
|
* INVOKE_WCB() is used as:
|
||||||
*
|
*
|
||||||
@ -557,36 +656,26 @@ do \
|
|||||||
*
|
*
|
||||||
* The callback is invoked as:
|
* The callback is invoked as:
|
||||||
*
|
*
|
||||||
* callback( arg_list );
|
* callback( arg_list, userData );
|
||||||
*
|
*
|
||||||
* ...so the parentheses are REQUIRED in the {arg_list}.
|
* ...where userData is added to the arg_list, but the parentheses
|
||||||
|
* are REQUIRED in the {arg_list}.
|
||||||
*
|
*
|
||||||
* NOTE that it does a sanity-check and also sets the
|
* NOTE that it does a sanity-check and also sets the
|
||||||
* current window.
|
* current window.
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
#if TARGET_HOST_MS_WINDOWS && !defined(_WIN32_WCE) /* FIXME: also WinCE? */
|
|
||||||
#define INVOKE_WCB(window,cbname,arg_list) \
|
#define INVOKE_WCB(window,cbname,arg_list) \
|
||||||
do \
|
do \
|
||||||
{ \
|
{ \
|
||||||
if( FETCH_WCB( window, cbname ) ) \
|
if( FETCH_WCB( window, cbname ) ) \
|
||||||
{ \
|
{ \
|
||||||
FGCB ## cbname func = (FGCB ## cbname)(FETCH_WCB( window, cbname )); \
|
FGCB ## cbname ## UC func = (FGCB ## cbname ## UC)(FETCH_WCB( window, cbname )); \
|
||||||
|
FGCBUserData userData = FETCH_USER_DATA_WCB( window, cbname ); \
|
||||||
fgSetWindow( &window ); \
|
fgSetWindow( &window ); \
|
||||||
func arg_list; \
|
func EXPAND_WCB( cbname )(( arg_list, userData )); \
|
||||||
} \
|
} \
|
||||||
} while( 0 )
|
} while( 0 )
|
||||||
#else
|
|
||||||
#define INVOKE_WCB(window,cbname,arg_list) \
|
|
||||||
do \
|
|
||||||
{ \
|
|
||||||
if( FETCH_WCB( window, cbname ) ) \
|
|
||||||
{ \
|
|
||||||
fgSetWindow( &window ); \
|
|
||||||
((FGCB ## cbname)FETCH_WCB( window, cbname )) arg_list; \
|
|
||||||
} \
|
|
||||||
} while( 0 )
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* The window callbacks the user can supply us with. Should be kept portable.
|
* The window callbacks the user can supply us with. Should be kept portable.
|
||||||
@ -662,8 +751,10 @@ struct tagSFG_Menu
|
|||||||
void *UserData; /* User data passed back at callback */
|
void *UserData; /* User data passed back at callback */
|
||||||
int ID; /* The global menu ID */
|
int ID; /* The global menu ID */
|
||||||
SFG_List Entries; /* The menu entries list */
|
SFG_List Entries; /* The menu entries list */
|
||||||
FGCBMenu Callback; /* The menu callback */
|
FGCBMenuUC Callback; /* The menu callback */
|
||||||
FGCBDestroy Destroy; /* Destruction callback */
|
FGCBUserData CallbackData; /* The menu callback user data */
|
||||||
|
FGCBDestroyUC Destroy; /* Destruction callback */
|
||||||
|
FGCBUserData DestroyData; /* Destruction callback user data */
|
||||||
GLboolean IsActive; /* Is the menu selected? */
|
GLboolean IsActive; /* Is the menu selected? */
|
||||||
void* Font; /* Font to be used for displaying this menu */
|
void* Font; /* Font to be used for displaying this menu */
|
||||||
int Width; /* Menu box width in pixels */
|
int Width; /* Menu box width in pixels */
|
||||||
@ -701,6 +792,7 @@ struct tagSFG_Window
|
|||||||
SFG_Context Window; /* Window and OpenGL context */
|
SFG_Context Window; /* Window and OpenGL context */
|
||||||
SFG_WindowState State; /* The window state */
|
SFG_WindowState State; /* The window state */
|
||||||
SFG_Proc CallBacks[ TOTAL_CALLBACKS ]; /* Array of window callbacks */
|
SFG_Proc CallBacks[ TOTAL_CALLBACKS ]; /* Array of window callbacks */
|
||||||
|
FGCBUserData CallbackDatas[ TOTAL_CALLBACKS ]; /* Array of window callback datas */
|
||||||
void *UserData ; /* For use by user */
|
void *UserData ; /* For use by user */
|
||||||
|
|
||||||
SFG_Menu* Menu[ FREEGLUT_MAX_MENUS ]; /* Menus appended to window */
|
SFG_Menu* Menu[ FREEGLUT_MAX_MENUS ]; /* Menus appended to window */
|
||||||
@ -970,7 +1062,7 @@ void fgCloseWindows ();
|
|||||||
void fgDestroyWindow( SFG_Window* window );
|
void fgDestroyWindow( SFG_Window* window );
|
||||||
|
|
||||||
/* Menu creation and destruction. Defined in fg_structure.c */
|
/* Menu creation and destruction. Defined in fg_structure.c */
|
||||||
SFG_Menu* fgCreateMenu( FGCBMenu menuCallback );
|
SFG_Menu* fgCreateMenu( FGCBMenuUC menuCallback, FGCBUserData userData );
|
||||||
void fgDestroyMenu( SFG_Menu* menu );
|
void fgDestroyMenu( SFG_Menu* menu );
|
||||||
|
|
||||||
/* Joystick device management functions, defined in fg_joystick.c */
|
/* Joystick device management functions, defined in fg_joystick.c */
|
||||||
|
@ -233,7 +233,7 @@ static void fghCheckTimers( void )
|
|||||||
fgListRemove( &fgState.Timers, &timer->Node );
|
fgListRemove( &fgState.Timers, &timer->Node );
|
||||||
fgListAppend( &fgState.FreeTimers, &timer->Node );
|
fgListAppend( &fgState.FreeTimers, &timer->Node );
|
||||||
|
|
||||||
timer->Callback( timer->ID );
|
timer->Callback( timer->ID, timer->CallbackData );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -269,7 +269,7 @@ void fgError( const char *fmt, ... )
|
|||||||
va_start( ap, fmt );
|
va_start( ap, fmt );
|
||||||
|
|
||||||
/* call user set error handler here */
|
/* call user set error handler here */
|
||||||
fgState.ErrorFunc(fmt, ap);
|
fgState.ErrorFunc(fmt, ap, fgState.ErrorFuncData);
|
||||||
|
|
||||||
va_end( ap );
|
va_end( ap );
|
||||||
|
|
||||||
@ -302,7 +302,7 @@ void fgWarning( const char *fmt, ... )
|
|||||||
va_start( ap, fmt );
|
va_start( ap, fmt );
|
||||||
|
|
||||||
/* call user set warning handler here */
|
/* call user set warning handler here */
|
||||||
fgState.WarningFunc(fmt, ap);
|
fgState.WarningFunc(fmt, ap, fgState.WarningFuncData);
|
||||||
|
|
||||||
va_end( ap );
|
va_end( ap );
|
||||||
|
|
||||||
@ -509,7 +509,7 @@ void FGAPIENTRY glutMainLoop( void )
|
|||||||
fgStructure.CurrentWindow->IsMenu )
|
fgStructure.CurrentWindow->IsMenu )
|
||||||
/* fail safe */
|
/* fail safe */
|
||||||
fgSetWindow( window );
|
fgSetWindow( window );
|
||||||
fgState.IdleCallback( );
|
fgState.IdleCallback( fgState.IdleCallbackData );
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
fghSleepForEvents( );
|
fghSleepForEvents( );
|
||||||
|
@ -531,7 +531,7 @@ static void fghActivateMenu( SFG_Window* window, int button )
|
|||||||
fgState.MenuStateCallback(GLUT_MENU_IN_USE);
|
fgState.MenuStateCallback(GLUT_MENU_IN_USE);
|
||||||
if (fgState.MenuStatusCallback)
|
if (fgState.MenuStatusCallback)
|
||||||
/* window->State.MouseX and window->State.MouseY are relative to client area origin, as needed */
|
/* window->State.MouseX and window->State.MouseY are relative to client area origin, as needed */
|
||||||
fgState.MenuStatusCallback(GLUT_MENU_IN_USE, window->State.MouseX, window->State.MouseY);
|
fgState.MenuStatusCallback(GLUT_MENU_IN_USE, window->State.MouseX, window->State.MouseY, fgState.MenuStatusCallbackData);
|
||||||
}
|
}
|
||||||
|
|
||||||
fgSetWindow( menu->Window );
|
fgSetWindow( menu->Window );
|
||||||
@ -609,7 +609,7 @@ GLboolean fgCheckActiveMenu ( SFG_Window *window, int button, GLboolean pressed,
|
|||||||
|
|
||||||
/* Deactivate menu and then call callback (we don't want menu to stay in view while callback is executing, and user should be able to change menus in callback) */
|
/* Deactivate menu and then call callback (we don't want menu to stay in view while callback is executing, and user should be able to change menus in callback) */
|
||||||
fgDeactivateMenu( parent_window );
|
fgDeactivateMenu( parent_window );
|
||||||
active_menu->Callback( active_entry->ID );
|
active_menu->Callback( active_entry->ID, active_menu->CallbackData );
|
||||||
|
|
||||||
/* Restore the current window and menu */
|
/* Restore the current window and menu */
|
||||||
fgSetWindow( save_window );
|
fgSetWindow( save_window );
|
||||||
@ -725,7 +725,7 @@ void fgDeactivateMenu( SFG_Window *window )
|
|||||||
SFG_XYUse mouse_pos;
|
SFG_XYUse mouse_pos;
|
||||||
fghPlatformGetCursorPos(parent_window, GL_TRUE, &mouse_pos);
|
fghPlatformGetCursorPos(parent_window, GL_TRUE, &mouse_pos);
|
||||||
|
|
||||||
fgState.MenuStatusCallback(GLUT_MENU_NOT_IN_USE, mouse_pos.X, mouse_pos.Y);
|
fgState.MenuStatusCallback(GLUT_MENU_NOT_IN_USE, mouse_pos.X, mouse_pos.Y, fgState.MenuStatusCallbackData);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -780,14 +780,33 @@ void fghCalculateMenuBoxSize( void )
|
|||||||
/*
|
/*
|
||||||
* Creates a new menu object, adding it to the freeglut structure
|
* Creates a new menu object, adding it to the freeglut structure
|
||||||
*/
|
*/
|
||||||
int FGAPIENTRY glutCreateMenu( FGCBMenu callback )
|
int FGAPIENTRY glutCreateMenuUcall( FGCBMenuUC callback, FGCBUserData userData )
|
||||||
{
|
{
|
||||||
/* The menu object creation code resides in fg_structure.c */
|
/* The menu object creation code resides in fg_structure.c */
|
||||||
FREEGLUT_EXIT_IF_NOT_INITIALISED ( "glutCreateMenu" );
|
FREEGLUT_EXIT_IF_NOT_INITIALISED ( "glutCreateMenuUcall" );
|
||||||
if (fgState.ActiveMenus)
|
if (fgState.ActiveMenus)
|
||||||
|
{
|
||||||
fgError( "Menu manipulation not allowed while menus in use." );
|
fgError( "Menu manipulation not allowed while menus in use." );
|
||||||
|
}
|
||||||
|
|
||||||
return fgCreateMenu( callback )->ID;
|
return fgCreateMenu( callback, userData )->ID;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Standard glutCreateMenu */
|
||||||
|
static void fghCreateMenuCallback( int menu, FGCBUserData userData )
|
||||||
|
{
|
||||||
|
FGCBMenu callback = (FGCBMenu)userData;
|
||||||
|
callback( menu );
|
||||||
|
}
|
||||||
|
|
||||||
|
int FGAPIENTRY glutCreateMenu( FGCBMenu callback )
|
||||||
|
{
|
||||||
|
FREEGLUT_EXIT_IF_NOT_INITIALISED ( "glutCreateMenu" );
|
||||||
|
if (!callback)
|
||||||
|
{
|
||||||
|
return glutCreateMenuUcall( NULL, NULL );
|
||||||
|
}
|
||||||
|
return glutCreateMenuUcall( fghCreateMenuCallback, (FGCBUserData)callback );
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -49,7 +49,7 @@ SFG_Structure fgStructure = { { NULL, NULL }, /* The list of windows */
|
|||||||
/* -- PRIVATE FUNCTIONS ---------------------------------------------------- */
|
/* -- PRIVATE FUNCTIONS ---------------------------------------------------- */
|
||||||
|
|
||||||
extern void fgPlatformCreateWindow ( SFG_Window *window );
|
extern void fgPlatformCreateWindow ( SFG_Window *window );
|
||||||
extern void fghDefaultReshape(int width, int height);
|
extern void fghDefaultReshape(int width, int height, FGCBUserData userData);
|
||||||
|
|
||||||
static void fghClearCallBacks( SFG_Window *window )
|
static void fghClearCallBacks( SFG_Window *window )
|
||||||
{
|
{
|
||||||
@ -57,7 +57,10 @@ static void fghClearCallBacks( SFG_Window *window )
|
|||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
for( i = 0; i < TOTAL_CALLBACKS; ++i )
|
for( i = 0; i < TOTAL_CALLBACKS; ++i )
|
||||||
|
{
|
||||||
window->CallBacks[ i ] = NULL;
|
window->CallBacks[ i ] = NULL;
|
||||||
|
window->CallbackDatas[ i ] = NULL;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -83,7 +86,7 @@ SFG_Window* fgCreateWindow( SFG_Window* parent, const char* title,
|
|||||||
fgPlatformCreateWindow ( window );
|
fgPlatformCreateWindow ( window );
|
||||||
|
|
||||||
fghClearCallBacks( window );
|
fghClearCallBacks( window );
|
||||||
SET_WCB( *window, Reshape, fghDefaultReshape);
|
SET_WCB( *window, Reshape, fghDefaultReshape, NULL);
|
||||||
|
|
||||||
/* Initialize the object properties */
|
/* Initialize the object properties */
|
||||||
window->ID = ++fgStructure.WindowID;
|
window->ID = ++fgStructure.WindowID;
|
||||||
@ -116,7 +119,7 @@ SFG_Window* fgCreateWindow( SFG_Window* parent, const char* title,
|
|||||||
/*
|
/*
|
||||||
* This private function creates a menu and adds it to the menus list
|
* This private function creates a menu and adds it to the menus list
|
||||||
*/
|
*/
|
||||||
SFG_Menu* fgCreateMenu( FGCBMenu menuCallback )
|
SFG_Menu* fgCreateMenu( FGCBMenuUC menuCallback, FGCBUserData userData )
|
||||||
{
|
{
|
||||||
SFG_Window *current_window = fgStructure.CurrentWindow;
|
SFG_Window *current_window = fgStructure.CurrentWindow;
|
||||||
|
|
||||||
@ -136,6 +139,7 @@ SFG_Menu* fgCreateMenu( FGCBMenu menuCallback )
|
|||||||
/* Initialize the object properties: */
|
/* Initialize the object properties: */
|
||||||
menu->ID = ++fgStructure.MenuID;
|
menu->ID = ++fgStructure.MenuID;
|
||||||
menu->Callback = menuCallback;
|
menu->Callback = menuCallback;
|
||||||
|
menu->CallbackData = userData;
|
||||||
menu->ActiveEntry = NULL;
|
menu->ActiveEntry = NULL;
|
||||||
menu->Font = fgState.MenuFont;
|
menu->Font = fgState.MenuFont;
|
||||||
|
|
||||||
@ -173,9 +177,10 @@ void fgAddToWindowDestroyList( SFG_Window* window )
|
|||||||
* to ensure that they are no longer called after this point.
|
* to ensure that they are no longer called after this point.
|
||||||
*/
|
*/
|
||||||
{
|
{
|
||||||
FGCBDestroy destroy = (FGCBDestroy)FETCH_WCB( *window, Destroy );
|
FGCBDestroyUC destroy = (FGCBDestroyUC)FETCH_WCB( *window, Destroy );
|
||||||
|
FGCBUserData destroyData = FETCH_USER_DATA_WCB( *window, Destroy );
|
||||||
fghClearCallBacks( window );
|
fghClearCallBacks( window );
|
||||||
SET_WCB( *window, Destroy, destroy );
|
SET_WCB( *window, Destroy, destroy, destroyData );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -302,7 +307,7 @@ void fgDestroyMenu( SFG_Menu* menu )
|
|||||||
{
|
{
|
||||||
SFG_Menu *activeMenu=fgStructure.CurrentMenu;
|
SFG_Menu *activeMenu=fgStructure.CurrentMenu;
|
||||||
fgStructure.CurrentMenu = menu;
|
fgStructure.CurrentMenu = menu;
|
||||||
menu->Destroy( );
|
menu->Destroy( menu->DestroyData );
|
||||||
fgStructure.CurrentMenu = activeMenu;
|
fgStructure.CurrentMenu = activeMenu;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -106,3 +106,8 @@ int FGAPIENTRY __glutCreateMenuWithExit( void(* callback)( int ), void (__cdecl
|
|||||||
return glutCreateMenu( callback );
|
return glutCreateMenu( callback );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int FGAPIENTRY __glutCreateMenuUcallWithExit(void(*callback)(int, void*), void(__cdecl *exit_function)(int), void* user_data)
|
||||||
|
{
|
||||||
|
__glutExitFunc = exit_function;
|
||||||
|
return glutCreateMenuUcall(callback, user_data);
|
||||||
|
}
|
||||||
|
@ -71,8 +71,10 @@ void fghKeyboardInterpretKeysym( SFG_Window* window,
|
|||||||
xkb_keysym_t sym,
|
xkb_keysym_t sym,
|
||||||
uint32_t state )
|
uint32_t state )
|
||||||
{
|
{
|
||||||
FGCBKeyboard keyboard_cb;
|
FGCBKeyboardUC keyboard_cb;
|
||||||
FGCBSpecial special_cb;
|
FGCBSpecialUC special_cb;
|
||||||
|
FGCBUserData keyboard_ud;
|
||||||
|
FGCBUserData special_ud;
|
||||||
char string[16];
|
char string[16];
|
||||||
int special = -1;
|
int special = -1;
|
||||||
|
|
||||||
@ -81,13 +83,17 @@ void fghKeyboardInterpretKeysym( SFG_Window* window,
|
|||||||
* others, which need to be translated to GLUT_KEY_Xs... */
|
* others, which need to be translated to GLUT_KEY_Xs... */
|
||||||
if( state )
|
if( state )
|
||||||
{
|
{
|
||||||
keyboard_cb = (FGCBKeyboard)( FETCH_WCB( *window, Keyboard ));
|
keyboard_cb = (FGCBKeyboardUC)( FETCH_WCB( *window, Keyboard ));
|
||||||
special_cb = (FGCBSpecial) ( FETCH_WCB( *window, Special ));
|
special_cb = (FGCBSpecialUC) ( FETCH_WCB( *window, Special ));
|
||||||
|
keyboard_ud = FETCH_USER_DATA_WCB( *window, Keyboard );
|
||||||
|
special_ud = FETCH_USER_DATA_WCB( *window, Special );
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
keyboard_cb = (FGCBKeyboard)( FETCH_WCB( *window, KeyboardUp ));
|
keyboard_cb = (FGCBKeyboardUC)( FETCH_WCB( *window, KeyboardUp ));
|
||||||
special_cb = (FGCBSpecial) ( FETCH_WCB( *window, SpecialUp ));
|
special_cb = (FGCBSpecialUC) ( FETCH_WCB( *window, SpecialUp ));
|
||||||
|
keyboard_ud = FETCH_USER_DATA_WCB( *window, KeyboardUp );
|
||||||
|
special_ud = FETCH_USER_DATA_WCB( *window, SpecialUp );
|
||||||
}
|
}
|
||||||
|
|
||||||
switch( sym )
|
switch( sym )
|
||||||
@ -127,13 +133,13 @@ void fghKeyboardInterpretKeysym( SFG_Window* window,
|
|||||||
if( special_cb && (special != -1) )
|
if( special_cb && (special != -1) )
|
||||||
{
|
{
|
||||||
fgSetWindow( window );
|
fgSetWindow( window );
|
||||||
special_cb( special, window->State.MouseX, window->State.MouseY );
|
special_cb( special, window->State.MouseX, window->State.MouseY, special_ud );
|
||||||
}
|
}
|
||||||
else if( keyboard_cb && (special == -1) )
|
else if( keyboard_cb && (special == -1) )
|
||||||
{
|
{
|
||||||
fgSetWindow( window );
|
fgSetWindow( window );
|
||||||
xkb_keysym_to_utf8( sym, string, sizeof( string ) );
|
xkb_keysym_to_utf8( sym, string, sizeof( string ) );
|
||||||
keyboard_cb( string[0], window->State.MouseX, window->State.MouseY );
|
keyboard_cb( string[0], window->State.MouseX, window->State.MouseY, keyboard_ud );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -890,8 +890,10 @@ void fgPlatformProcessSingleEvent ( void )
|
|||||||
case KeyRelease:
|
case KeyRelease:
|
||||||
case KeyPress:
|
case KeyPress:
|
||||||
{
|
{
|
||||||
FGCBKeyboard keyboard_cb;
|
FGCBKeyboardUC keyboard_cb;
|
||||||
FGCBSpecial special_cb;
|
FGCBSpecialUC special_cb;
|
||||||
|
FGCBUserData keyboard_ud;
|
||||||
|
FGCBUserData special_ud;
|
||||||
|
|
||||||
GETWINDOW( xkey );
|
GETWINDOW( xkey );
|
||||||
GETMOUSE( xkey );
|
GETMOUSE( xkey );
|
||||||
@ -932,13 +934,17 @@ void fgPlatformProcessSingleEvent ( void )
|
|||||||
|
|
||||||
if( event.type == KeyPress )
|
if( event.type == KeyPress )
|
||||||
{
|
{
|
||||||
keyboard_cb = (FGCBKeyboard)( FETCH_WCB( *window, Keyboard ));
|
keyboard_cb = (FGCBKeyboardUC)( FETCH_WCB( *window, Keyboard ));
|
||||||
special_cb = (FGCBSpecial) ( FETCH_WCB( *window, Special ));
|
special_cb = (FGCBSpecialUC) ( FETCH_WCB( *window, Special ));
|
||||||
|
keyboard_ud = FETCH_USER_DATA_WCB( *window, Keyboard );
|
||||||
|
special_ud = FETCH_USER_DATA_WCB( *window, Special );
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
keyboard_cb = (FGCBKeyboard)( FETCH_WCB( *window, KeyboardUp ));
|
keyboard_cb = (FGCBKeyboardUC)( FETCH_WCB( *window, KeyboardUp ));
|
||||||
special_cb = (FGCBSpecial) ( FETCH_WCB( *window, SpecialUp ));
|
special_cb = (FGCBSpecialUC) ( FETCH_WCB( *window, SpecialUp ));
|
||||||
|
keyboard_ud = FETCH_USER_DATA_WCB( *window, KeyboardUp );
|
||||||
|
special_ud = FETCH_USER_DATA_WCB( *window, SpecialUp );
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Is there a keyboard/special callback hooked for this window? */
|
/* Is there a keyboard/special callback hooked for this window? */
|
||||||
@ -963,7 +969,8 @@ void fgPlatformProcessSingleEvent ( void )
|
|||||||
fgSetWindow( window );
|
fgSetWindow( window );
|
||||||
fgState.Modifiers = fgPlatformGetModifiers( event.xkey.state );
|
fgState.Modifiers = fgPlatformGetModifiers( event.xkey.state );
|
||||||
keyboard_cb( asciiCode[ 0 ],
|
keyboard_cb( asciiCode[ 0 ],
|
||||||
event.xkey.x, event.xkey.y
|
event.xkey.x, event.xkey.y,
|
||||||
|
keyboard_ud
|
||||||
);
|
);
|
||||||
fgState.Modifiers = INVALID_MODIFIERS;
|
fgState.Modifiers = INVALID_MODIFIERS;
|
||||||
}
|
}
|
||||||
@ -1031,7 +1038,7 @@ void fgPlatformProcessSingleEvent ( void )
|
|||||||
{
|
{
|
||||||
fgSetWindow( window );
|
fgSetWindow( window );
|
||||||
fgState.Modifiers = fgPlatformGetModifiers( event.xkey.state );
|
fgState.Modifiers = fgPlatformGetModifiers( event.xkey.state );
|
||||||
special_cb( special, event.xkey.x, event.xkey.y );
|
special_cb( special, event.xkey.x, event.xkey.y, special_ud );
|
||||||
fgState.Modifiers = INVALID_MODIFIERS;
|
fgState.Modifiers = INVALID_MODIFIERS;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -327,6 +327,40 @@ area--which is <u>NOT</u> the (x,y) position of the window you specified
|
|||||||
when you created it.</ul>
|
when you created it.</ul>
|
||||||
</p>
|
</p>
|
||||||
|
|
||||||
|
<h3>3.2.2 User-data callbacks</h3>
|
||||||
|
|
||||||
|
<p>
|
||||||
|
GLUT was created as a tool to help teach OpenGL programming. To simplify
|
||||||
|
development, callbacks were used for handling display, input, and other
|
||||||
|
events. But at the time it was developed, the purpose, or for some other
|
||||||
|
unknown reason, the callbacks lacked any user-provided data argument.
|
||||||
|
This has caused considerable difficulties for any significantly advanced
|
||||||
|
usage of GLUT, and now <i>freeglut</i>. This has prevented any attempt to
|
||||||
|
wrap <i>freeglut</i> in a C++ wrapper, make per-window, per-callback data
|
||||||
|
structure, and potentially made it undesirable to modern C developers who
|
||||||
|
tend to be well versed in "don't use globals". To combat these
|
||||||
|
complaints and <i>issues</i>, many callbacks (with some deprecated
|
||||||
|
callbacks excluded) support user-data callbacks provided through additional
|
||||||
|
functions provided in <i>freeglut</i>. All callbacks that support user-data
|
||||||
|
callbacks are marked as such.
|
||||||
|
</p>
|
||||||
|
|
||||||
|
<p>
|
||||||
|
The general rule to follow is to take the <i>freeglut</i> callback function
|
||||||
|
and append "Ucall" to the end of the function, add an additional <tt>void*</tt>
|
||||||
|
argument to the end of the argument list of both the <i>freeglut</i> function
|
||||||
|
and the callback function. This will pass the user-data to the callback when it's
|
||||||
|
invoked.
|
||||||
|
</p>
|
||||||
|
|
||||||
|
<p><b>Examples</b></p>
|
||||||
|
|
||||||
|
<p><tt>void glutPositionFunc ( void (* func)( int x, int y ) );</tt><br>
|
||||||
|
<tt>void glutPositionFuncUcall ( void (* func)( int x, int y, void* user_data ), void* user_data );</tt></p>
|
||||||
|
|
||||||
|
<p><tt>void glutKeyboardUpFunc ( void (* func)( unsigned char key, int x, int y ) );</tt><br>
|
||||||
|
<tt>void glutKeyboardUpFuncUcall ( void (* func)( unsigned char key, int x, int y, void* user_data ), void* user_data );</tt></p>
|
||||||
|
|
||||||
<h2>3.3 Terminology</h2>
|
<h2>3.3 Terminology</h2>
|
||||||
|
|
||||||
<h2>3.4 Differences from GLUT 3.7</h2>
|
<h2>3.4 Differences from GLUT 3.7</h2>
|
||||||
@ -524,6 +558,8 @@ from the library can be handled by the user.
|
|||||||
<p><tt>void glutInitErrorFunc ( void (* callback)( const char *fmt, va_list ap) );</tt><br/>
|
<p><tt>void glutInitErrorFunc ( void (* callback)( const char *fmt, va_list ap) );</tt><br/>
|
||||||
<tt>void glutInitWarningFunc ( void (* callback)( const char *fmt, va_list ap) );</tt> </p>
|
<tt>void glutInitWarningFunc ( void (* callback)( const char *fmt, va_list ap) );</tt> </p>
|
||||||
|
|
||||||
|
<p>These functions have user-data callback functions.</p>
|
||||||
|
|
||||||
<p><b>Description</b></p>
|
<p><b>Description</b></p>
|
||||||
<p>
|
<p>
|
||||||
The users callback is passed a format string and a variable argument
|
The users callback is passed a format string and a variable argument
|
||||||
@ -943,6 +979,8 @@ The <tt>glutShowOverlay</tt> and <tt>glutHideOverlay</tt> functions are not impl
|
|||||||
|
|
||||||
<h2>10.1 glutCreateMenu</h2>
|
<h2>10.1 glutCreateMenu</h2>
|
||||||
|
|
||||||
|
<p>Has user-data callback function.</p>
|
||||||
|
|
||||||
<h2>10.2 glutDestroyMenu</h2>
|
<h2>10.2 glutDestroyMenu</h2>
|
||||||
|
|
||||||
<h2>10.3 glutGetMenu, glutSetMenu</h2>
|
<h2>10.3 glutGetMenu, glutSetMenu</h2>
|
||||||
@ -985,10 +1023,14 @@ stroke font, or an unknown font.
|
|||||||
|
|
||||||
<h2>10.11 glutMenuDestroyFunc</h2>
|
<h2>10.11 glutMenuDestroyFunc</h2>
|
||||||
|
|
||||||
|
<p>Has user-data callback function.</p>
|
||||||
|
|
||||||
<h1>11. <a name="GlobalCallback"></a>Global Callback Registration Functions</h1>
|
<h1>11. <a name="GlobalCallback"></a>Global Callback Registration Functions</h1>
|
||||||
|
|
||||||
<h2>11.1 glutTimerFunc</h2>
|
<h2>11.1 glutTimerFunc</h2>
|
||||||
|
|
||||||
|
<p>Has user-data callback function.</p>
|
||||||
|
|
||||||
<h2>11.2 glutIdleFunc</h2>
|
<h2>11.2 glutIdleFunc</h2>
|
||||||
|
|
||||||
<p>
|
<p>
|
||||||
@ -998,11 +1040,11 @@ freeglut</i> calls the idle callback when there are no inputs from the user.
|
|||||||
|
|
||||||
<p><b>Usage</b></p>
|
<p><b>Usage</b></p>
|
||||||
|
|
||||||
<p><tt>void glutIdleFunc ( void (*func)
|
<p><tt>void glutIdleFunc ( void (*func ) ( void ) );</tt> </p>
|
||||||
( void ) );</tt> </p>
|
|
||||||
|
|
||||||
<p><tt>func</tt>The new
|
<p><tt>func</tt> The new global idle callback function</p>
|
||||||
global idle callback function </p>
|
|
||||||
|
<p>Has user-data callback function.</p>
|
||||||
|
|
||||||
<p><b>Description</b></p>
|
<p><b>Description</b></p>
|
||||||
|
|
||||||
@ -1042,16 +1084,24 @@ the idle callback. </p>
|
|||||||
|
|
||||||
<h2>11.3 glutMenuStatusFunc</h2>
|
<h2>11.3 glutMenuStatusFunc</h2>
|
||||||
|
|
||||||
|
<p>Has user-data callback function.</p>
|
||||||
|
|
||||||
<h2>11.4 glutMenuStateFunc</h2>
|
<h2>11.4 glutMenuStateFunc</h2>
|
||||||
|
|
||||||
<h1>12. <a name="WindowCallback"></a>Window-Specific Callback Registration Functions</h1>
|
<h1>12. <a name="WindowCallback"></a>Window-Specific Callback Registration Functions</h1>
|
||||||
|
|
||||||
<h2>12.1 glutDisplayFunc</h2>
|
<h2>12.1 glutDisplayFunc</h2>
|
||||||
|
|
||||||
|
<p>Has user-data callback function.</p>
|
||||||
|
|
||||||
<h2>12.2 glutOverlayDisplayFunc</h2>
|
<h2>12.2 glutOverlayDisplayFunc</h2>
|
||||||
|
|
||||||
|
<p>Has user-data callback function.</p>
|
||||||
|
|
||||||
<h2>12.3 glutReshapeFunc</h2>
|
<h2>12.3 glutReshapeFunc</h2>
|
||||||
|
|
||||||
|
<p>Has user-data callback function.</p>
|
||||||
|
|
||||||
<h2>12.4 glutPositionFunc</h2>
|
<h2>12.4 glutPositionFunc</h2>
|
||||||
|
|
||||||
<p>
|
<p>
|
||||||
@ -1065,6 +1115,8 @@ repositioned/moved programatically or by the user.
|
|||||||
<p><tt>void glutPositionFunc ( void
|
<p><tt>void glutPositionFunc ( void
|
||||||
(* func)( int x, int y) );</tt></p>
|
(* func)( int x, int y) );</tt></p>
|
||||||
|
|
||||||
|
<p>Has user-data callback function.</p>
|
||||||
|
|
||||||
<p><b>Description</b></p>
|
<p><b>Description</b></p>
|
||||||
|
|
||||||
<p>When <i>freeglut</i> calls this callback, it provides the new
|
<p>When <i>freeglut</i> calls this callback, it provides the new
|
||||||
@ -1094,6 +1146,8 @@ about to be destroyed.
|
|||||||
<p><tt>func</tt> The window's new closure callback function <br/>
|
<p><tt>func</tt> The window's new closure callback function <br/>
|
||||||
</p>
|
</p>
|
||||||
|
|
||||||
|
<p>Has user-data callback function.</p>
|
||||||
|
|
||||||
<p><b>Description</b></p>
|
<p><b>Description</b></p>
|
||||||
|
|
||||||
<p>
|
<p>
|
||||||
@ -1121,6 +1175,8 @@ alias to <tt>glutCloseFunc</tt>.
|
|||||||
|
|
||||||
<h2>12.6 glutKeyboardFunc</h2>
|
<h2>12.6 glutKeyboardFunc</h2>
|
||||||
|
|
||||||
|
<p>Has user-data callback function.</p>
|
||||||
|
|
||||||
<h2>12.7 glutSpecialFunc</h2>
|
<h2>12.7 glutSpecialFunc</h2>
|
||||||
|
|
||||||
<p>
|
<p>
|
||||||
@ -1145,6 +1201,8 @@ to the window at the time the key is pressed <br/>
|
|||||||
</tt>The y-coordinate of the mouse relative
|
</tt>The y-coordinate of the mouse relative
|
||||||
to the window at the time the key is pressed </p>
|
to the window at the time the key is pressed </p>
|
||||||
|
|
||||||
|
<p>Has user-data callback function.</p>
|
||||||
|
|
||||||
<p><b>Description</b></p>
|
<p><b>Description</b></p>
|
||||||
|
|
||||||
<p>
|
<p>
|
||||||
@ -1200,6 +1258,8 @@ to the window at the time the key is released <br/>
|
|||||||
</tt>The y-coordinate of the mouse relative
|
</tt>The y-coordinate of the mouse relative
|
||||||
to the window at the time the key is released </p>
|
to the window at the time the key is released </p>
|
||||||
|
|
||||||
|
<p>Has user-data callback function.</p>
|
||||||
|
|
||||||
<p><b>Description</b></p>
|
<p><b>Description</b></p>
|
||||||
|
|
||||||
<p>
|
<p>
|
||||||
@ -1252,6 +1312,8 @@ to the window at the time the key is released <br/>
|
|||||||
</tt>The y-coordinate of the mouse relative
|
</tt>The y-coordinate of the mouse relative
|
||||||
to the window at the time the key is released </p>
|
to the window at the time the key is released </p>
|
||||||
|
|
||||||
|
<p>Has user-data callback function.</p>
|
||||||
|
|
||||||
<p><b>Description</b></p>
|
<p><b>Description</b></p>
|
||||||
|
|
||||||
<p>
|
<p>
|
||||||
@ -1289,8 +1351,12 @@ have them fixed.
|
|||||||
|
|
||||||
<h2>12.10 glutMotionFunc, glutPassiveMotionFunc</h2>
|
<h2>12.10 glutMotionFunc, glutPassiveMotionFunc</h2>
|
||||||
|
|
||||||
|
<p>Both functions have user-data callback functions.</p>
|
||||||
|
|
||||||
<h2>12.11 glutMouseFunc</h2>
|
<h2>12.11 glutMouseFunc</h2>
|
||||||
|
|
||||||
|
<p>Has user-data callback function.</p>
|
||||||
|
|
||||||
<h2>12.12 glutMouseWheelFunc</h2>
|
<h2>12.12 glutMouseWheelFunc</h2>
|
||||||
|
|
||||||
<p>
|
<p>
|
||||||
@ -1304,6 +1370,8 @@ spins the mouse wheel.
|
|||||||
<p><tt>void glutMouseWheelFunc ( void( *callback )( int wheel, int
|
<p><tt>void glutMouseWheelFunc ( void( *callback )( int wheel, int
|
||||||
direction, int x, int y ));</tt></p>
|
direction, int x, int y ));</tt></p>
|
||||||
|
|
||||||
|
<p>Has user-data callback function.</p>
|
||||||
|
|
||||||
<p><b>Description</b></p>
|
<p><b>Description</b></p>
|
||||||
|
|
||||||
<p>If the mouse wheel is spun over your (sub)window, <i>freeglut</i>
|
<p>If the mouse wheel is spun over your (sub)window, <i>freeglut</i>
|
||||||
@ -1320,8 +1388,12 @@ as mouse buttons.
|
|||||||
|
|
||||||
<h2>12.13 glutEntryFunc</h2>
|
<h2>12.13 glutEntryFunc</h2>
|
||||||
|
|
||||||
|
<p>Has user-data callback function.</p>
|
||||||
|
|
||||||
<h2>12.14 glutJoystickFunc</h2>
|
<h2>12.14 glutJoystickFunc</h2>
|
||||||
|
|
||||||
|
<p>Has user-data callback function.</p>
|
||||||
|
|
||||||
<h2>12.15 glutSpaceballMotionFunc</h2>
|
<h2>12.15 glutSpaceballMotionFunc</h2>
|
||||||
|
|
||||||
<p>
|
<p>
|
||||||
@ -1337,6 +1409,8 @@ provided so that GLUT-based programs can compile and link against
|
|||||||
|
|
||||||
<p><tt>void glutSpaceballMotionFunc ( void (* callback)( int x, int y, int z ) );</tt></p>
|
<p><tt>void glutSpaceballMotionFunc ( void (* callback)( int x, int y, int z ) );</tt></p>
|
||||||
|
|
||||||
|
<p>Has user-data callback function.</p>
|
||||||
|
|
||||||
<p><b>Description</b></p>
|
<p><b>Description</b></p>
|
||||||
|
|
||||||
<p>The <i>x</i>, <i>y</i>, and <i>z</i> arguments indicate the amount of translation in integer along x, y, and z axis respectively.</p>
|
<p>The <i>x</i>, <i>y</i>, and <i>z</i> arguments indicate the amount of translation in integer along x, y, and z axis respectively.</p>
|
||||||
@ -1357,6 +1431,8 @@ provided so that GLUT-based programs can compile and link against
|
|||||||
|
|
||||||
<p><tt>void glutSpaceballRotateFunc ( void (* callback)( int rx, int ry, int rz ) );</tt></p>
|
<p><tt>void glutSpaceballRotateFunc ( void (* callback)( int rx, int ry, int rz ) );</tt></p>
|
||||||
|
|
||||||
|
<p>Has user-data callback function.</p>
|
||||||
|
|
||||||
<p><b>Description</b></p>
|
<p><b>Description</b></p>
|
||||||
|
|
||||||
<p>The <i>rx</i>, <i>ry</i>, and <i>rz</i> arguments indicate the amount of rotation in integer with respect to x, y, and z axis respectively.</p>
|
<p>The <i>rx</i>, <i>ry</i>, and <i>rz</i> arguments indicate the amount of rotation in integer with respect to x, y, and z axis respectively.</p>
|
||||||
@ -1379,6 +1455,8 @@ The <tt>glutSpaceballButtonFunc</tt> function sets the window's Spaceball button
|
|||||||
<p><tt>void glutSpaceballButtonFunc ( void
|
<p><tt>void glutSpaceballButtonFunc ( void
|
||||||
(* callback)( int button, int updown )</tt><tt> );</tt></p>
|
(* callback)( int button, int updown )</tt><tt> );</tt></p>
|
||||||
|
|
||||||
|
<p>Has user-data callback function.</p>
|
||||||
|
|
||||||
<p><b>Description</b></p>
|
<p><b>Description</b></p>
|
||||||
|
|
||||||
<p>The <i>button</i> argument may take one of the following defined
|
<p>The <i>button</i> argument may take one of the following defined
|
||||||
@ -1418,6 +1496,8 @@ The <tt>glutDialsFunc</tt> function sets the global dials&buttons box callback.
|
|||||||
<tt>void glutButtonBoxFunc ( void (* callback)( int button, int updown ) );</tt>
|
<tt>void glutButtonBoxFunc ( void (* callback)( int button, int updown ) );</tt>
|
||||||
</p>
|
</p>
|
||||||
|
|
||||||
|
<p>Has user-data callback function.</p>
|
||||||
|
|
||||||
<p><b>Description</b></p>
|
<p><b>Description</b></p>
|
||||||
|
|
||||||
<p>
|
<p>
|
||||||
@ -1442,6 +1522,8 @@ The <tt>glutDialsFunc</tt> function sets the global dials&buttons box callback.
|
|||||||
<p><tt>void glutDialsFunc ( void (* callback)(
|
<p><tt>void glutDialsFunc ( void (* callback)(
|
||||||
int dial, int value )</tt><tt> );</tt></p>
|
int dial, int value )</tt><tt> );</tt></p>
|
||||||
|
|
||||||
|
<p>Has user-data callback function.</p>
|
||||||
|
|
||||||
<p><b>Description</b></p>
|
<p><b>Description</b></p>
|
||||||
|
|
||||||
<p>
|
<p>
|
||||||
@ -1469,6 +1551,8 @@ that a call to the function will not produce an error..
|
|||||||
<tt>void glutTabletMotionFunc ( void (* callback)( int x, int y ) );</tt>
|
<tt>void glutTabletMotionFunc ( void (* callback)( int x, int y ) );</tt>
|
||||||
</p>
|
</p>
|
||||||
|
|
||||||
|
<p>Has user-data callback function.</p>
|
||||||
|
|
||||||
<p><b>Description</b></p>
|
<p><b>Description</b></p>
|
||||||
|
|
||||||
<p>The <tt>glutTabletMotionFunc</tt> function
|
<p>The <tt>glutTabletMotionFunc</tt> function
|
||||||
@ -1491,6 +1575,8 @@ that a call to the function will not produce an error..
|
|||||||
<p><tt>void glutTabletButtonFunc ( void
|
<p><tt>void glutTabletButtonFunc ( void
|
||||||
(* callback)( int button, int updown, int x, int y )</tt><tt> );</tt></p>
|
(* callback)( int button, int updown, int x, int y )</tt><tt> );</tt></p>
|
||||||
|
|
||||||
|
<p>Has user-data callback function.</p>
|
||||||
|
|
||||||
<p><b>Description</b></p>
|
<p><b>Description</b></p>
|
||||||
|
|
||||||
<p>
|
<p>
|
||||||
@ -1517,6 +1603,8 @@ these callbacks when the visibility status of a window changes.
|
|||||||
<br><tt>void glutWindowStatusFunc ( void( *callback )( int state ));</tt>
|
<br><tt>void glutWindowStatusFunc ( void( *callback )( int state ));</tt>
|
||||||
</p>
|
</p>
|
||||||
|
|
||||||
|
<p>Both functions have user-data callback functions.</p>
|
||||||
|
|
||||||
<p><b>Description</b></p>
|
<p><b>Description</b></p>
|
||||||
|
|
||||||
<p>
|
<p>
|
||||||
@ -2701,6 +2789,8 @@ Currently, under windows, the first (oldest) touch point also controls
|
|||||||
the mouse cursor, which triggers the non-multi callbacks as
|
the mouse cursor, which triggers the non-multi callbacks as
|
||||||
usual.<br />
|
usual.<br />
|
||||||
|
|
||||||
|
All these functions have user-data callback functions.
|
||||||
|
|
||||||
<br />
|
<br />
|
||||||
|
|
||||||
Limitation: currently on the cursor id is provided. It may be
|
Limitation: currently on the cursor id is provided. It may be
|
||||||
@ -2729,9 +2819,11 @@ whether/how to implement it.</p>
|
|||||||
|
|
||||||
<ul>
|
<ul>
|
||||||
<li><code>glutInitContextFunc ← void</code> : called when the context
|
<li><code>glutInitContextFunc ← void</code> : called when the context
|
||||||
is initialized or re-initialized (e.g. after a pause)</li>
|
is initialized or re-initialized (e.g. after a pause). Has user-data callback
|
||||||
|
function.</li>
|
||||||
<li><code>glutAppStatusFunc ← event</code> : called when the
|
<li><code>glutAppStatusFunc ← event</code> : called when the
|
||||||
application's status changes, with event identifying the state entered.
|
application's status changes, with event identifying the state entered. Has
|
||||||
|
user-data callback function.
|
||||||
Possible states:
|
Possible states:
|
||||||
<ul>
|
<ul>
|
||||||
<li>application goes on a pause (or a stop) → GLUT_APPSTATUS_PAUSE</li>
|
<li>application goes on a pause (or a stop) → GLUT_APPSTATUS_PAUSE</li>
|
||||||
|
Reference in New Issue
Block a user