Added the ugly ATEXIT_HACK from GLUT 3.7, making freeglut binary compatible with the GLUT DLLs out in the wild.
git-svn-id: https://svn.code.sf.net/p/freeglut/code/trunk@818 7f0cb862-5218-0410-a997-914c9d46530a
This commit is contained in:
parent
2fe5703d54
commit
f3de81ff34
@ -1,4 +1,8 @@
|
||||
2009-05-22 Sven Panne <sven.panne@aedion.de>
|
||||
* include/GL/freeglut_std.h,src/freeglut_init.c,src/freeglut_internal.h,
|
||||
src/freeglut_menu.c,src/freeglut_window.c,src/freeglutdll.def: Added the
|
||||
ugly ATEXIT_HACK from GLUT 3.7, making freeglut binary compatible with the
|
||||
GLUT DLLs out in the wild.
|
||||
|
||||
* src/freeglutdll.def: Removed obsolete lines. Fixed version number.
|
||||
|
||||
|
@ -574,6 +574,45 @@ FGAPI void FGAPIENTRY glutForceJoystickFunc( void );
|
||||
FGAPI int FGAPIENTRY glutExtensionSupported( const char* extension );
|
||||
FGAPI void FGAPIENTRY glutReportErrors( void );
|
||||
|
||||
/* Comment from glut.h of classic GLUT:
|
||||
|
||||
Win32 has an annoying issue where there are multiple C run-time
|
||||
libraries (CRTs). If the executable is linked with a different CRT
|
||||
from the GLUT DLL, the GLUT DLL will not share the same CRT static
|
||||
data seen by the executable. In particular, atexit callbacks registered
|
||||
in the executable will not be called if GLUT calls its (different)
|
||||
exit routine). GLUT is typically built with the
|
||||
"/MD" option (the CRT with multithreading DLL support), but the Visual
|
||||
C++ linker default is "/ML" (the single threaded CRT).
|
||||
|
||||
One workaround to this issue is requiring users to always link with
|
||||
the same CRT as GLUT is compiled with. That requires users supply a
|
||||
non-standard option. GLUT 3.7 has its own built-in workaround where
|
||||
the executable's "exit" function pointer is covertly passed to GLUT.
|
||||
GLUT then calls the executable's exit function pointer to ensure that
|
||||
any "atexit" calls registered by the application are called if GLUT
|
||||
needs to exit.
|
||||
|
||||
Note that the __glut*WithExit routines should NEVER be called directly.
|
||||
To avoid the atexit workaround, #define GLUT_DISABLE_ATEXIT_HACK. */
|
||||
|
||||
/* to get the prototype for exit() */
|
||||
#include <stdlib.h>
|
||||
|
||||
#if defined(_WIN32) && !defined(GLUT_DISABLE_ATEXIT_HACK)
|
||||
FGAPI void FGAPIENTRY __glutInitWithExit(int *argcp, char **argv, void (__cdecl *exitfunc)(int));
|
||||
FGAPI int FGAPIENTRY __glutCreateWindowWithExit(const char *title, void (__cdecl *exitfunc)(int));
|
||||
FGAPI int FGAPIENTRY __glutCreateMenuWithExit(void (* func)(int), void (__cdecl *exitfunc)(int));
|
||||
#ifndef FREEGLUT_BUILDING_LIB
|
||||
static void FGAPIENTRY glutInit_ATEXIT_HACK(int *argcp, char **argv) { __glutInitWithExit(argcp, argv, exit); }
|
||||
#define glutInit glutInit_ATEXIT_HACK
|
||||
static int FGAPIENTRY glutCreateWindow_ATEXIT_HACK(const char *title) { return __glutCreateWindowWithExit(title, exit); }
|
||||
#define glutCreateWindow glutCreateWindow_ATEXIT_HACK
|
||||
static int FGAPIENTRY glutCreateMenu_ATEXIT_HACK(void (* func)(int)) { return __glutCreateMenuWithExit(func, exit); }
|
||||
#define glutCreateMenu glutCreateMenu_ATEXIT_HACK
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
@ -25,6 +25,7 @@
|
||||
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#define FREEGLUT_BUILDING_LIB
|
||||
#include <GL/freeglut.h>
|
||||
#include "freeglut_internal.h"
|
||||
|
||||
@ -853,6 +854,16 @@ void FGAPIENTRY glutInit( int* pargc, char** argv )
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef _WIN32
|
||||
void (__cdecl *__glutExitFunc)( int retval ) = NULL;
|
||||
|
||||
void FGAPIENTRY __glutInitWithExit( int *argcp, char **argv, void (__cdecl *exitfunc)(int) )
|
||||
{
|
||||
__glutExitFunc = exitfunc;
|
||||
glutInit(argcp, argv);
|
||||
}
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Undoes all the "glutInit" stuff
|
||||
*/
|
||||
|
@ -933,6 +933,10 @@ int fgHintPresent(Window window, Atom property, Atom hint);
|
||||
|
||||
SFG_Proc fghGetProcAddress( const char *procName );
|
||||
|
||||
#ifdef _WIN32
|
||||
extern void (__cdecl *__glutExitFunc)( int retval );
|
||||
#endif
|
||||
|
||||
#endif /* FREEGLUT_INTERNAL_H */
|
||||
|
||||
/*** END OF FILE ***/
|
||||
|
@ -25,6 +25,7 @@
|
||||
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#define FREEGLUT_BUILDING_LIB
|
||||
#include <GL/freeglut.h>
|
||||
#include "freeglut_internal.h"
|
||||
|
||||
@ -778,6 +779,12 @@ int FGAPIENTRY glutCreateMenu( void(* callback)( int ) )
|
||||
return fgCreateMenu( callback )->ID;
|
||||
}
|
||||
|
||||
int FGAPIENTRY __glutCreateMenuWithExit( void(* callback)( int ), void (__cdecl *exitfunc)(int) )
|
||||
{
|
||||
__glutExitFunc = exitfunc;
|
||||
return glutCreateMenu( callback );
|
||||
}
|
||||
|
||||
/*
|
||||
* Destroys a menu object, removing all references to it
|
||||
*/
|
||||
|
@ -25,6 +25,7 @@
|
||||
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#define FREEGLUT_BUILDING_LIB
|
||||
#include <GL/freeglut.h>
|
||||
#include "freeglut_internal.h"
|
||||
|
||||
@ -1092,6 +1093,14 @@ int FGAPIENTRY glutCreateWindow( const char* title )
|
||||
GL_FALSE, GL_FALSE )->ID;
|
||||
}
|
||||
|
||||
#ifdef _WIN32
|
||||
int FGAPIENTRY __glutCreateWindowWithExit( const char *title, void (__cdecl *exitfunc)(int) )
|
||||
{
|
||||
__glutExitFunc = exitfunc;
|
||||
return glutCreateWindow( title );
|
||||
}
|
||||
#endif
|
||||
|
||||
/*
|
||||
* This function creates a sub window.
|
||||
*/
|
||||
|
@ -154,3 +154,6 @@ EXPORTS
|
||||
glutGetModeValues
|
||||
glutInitContextFlags
|
||||
glutInitContextVersion
|
||||
__glutInitWithExit
|
||||
__glutCreateWindowWithExit
|
||||
__glutCreateMenuWithExit
|
||||
|
Reference in New Issue
Block a user