From 8fb7b342a32cb2336b5c3752c68714b47ac7c63e Mon Sep 17 00:00:00 2001 From: Sven Panne Date: Fri, 22 May 2009 15:20:03 +0000 Subject: [PATCH] Added the ugly ATEXIT_HACK from GLUT 3.7, making freeglut binary compatible with the GLUT DLLs out in the wild. git-svn-id: svn+ssh://svn.code.sf.net/p/freeglut/code/trunk/freeglut/freeglut@818 7f0cb862-5218-0410-a997-914c9d46530a --- ChangeLog | 4 ++++ include/GL/freeglut_std.h | 39 +++++++++++++++++++++++++++++++++++++++ src/freeglut_init.c | 11 +++++++++++ src/freeglut_internal.h | 4 ++++ src/freeglut_menu.c | 7 +++++++ src/freeglut_window.c | 9 +++++++++ src/freeglutdll.def | 3 +++ 7 files changed, 77 insertions(+) diff --git a/ChangeLog b/ChangeLog index 3dbb4d9..e6a6c3e 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,4 +1,8 @@ 2009-05-22 Sven Panne + * 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. diff --git a/include/GL/freeglut_std.h b/include/GL/freeglut_std.h index f799233..3248929 100644 --- a/include/GL/freeglut_std.h +++ b/include/GL/freeglut_std.h @@ -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 + +#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 diff --git a/src/freeglut_init.c b/src/freeglut_init.c index 01dabc7..9b4eb09 100644 --- a/src/freeglut_init.c +++ b/src/freeglut_init.c @@ -25,6 +25,7 @@ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ +#define FREEGLUT_BUILDING_LIB #include #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 */ diff --git a/src/freeglut_internal.h b/src/freeglut_internal.h index e7540b0..05cdddf 100644 --- a/src/freeglut_internal.h +++ b/src/freeglut_internal.h @@ -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 ***/ diff --git a/src/freeglut_menu.c b/src/freeglut_menu.c index a96f5d6..8a04d0b 100644 --- a/src/freeglut_menu.c +++ b/src/freeglut_menu.c @@ -25,6 +25,7 @@ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ +#define FREEGLUT_BUILDING_LIB #include #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 */ diff --git a/src/freeglut_window.c b/src/freeglut_window.c index 005074b..03a3b25 100644 --- a/src/freeglut_window.c +++ b/src/freeglut_window.c @@ -25,6 +25,7 @@ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ +#define FREEGLUT_BUILDING_LIB #include #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. */ diff --git a/src/freeglutdll.def b/src/freeglutdll.def index 7618307..5bf3ca0 100644 --- a/src/freeglutdll.def +++ b/src/freeglutdll.def @@ -154,3 +154,6 @@ EXPORTS glutGetModeValues glutInitContextFlags glutInitContextVersion + __glutInitWithExit + __glutCreateWindowWithExit + __glutCreateMenuWithExit -- 1.7.10.4