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:
spanne 2009-05-22 15:20:03 +00:00
parent 2fe5703d54
commit f3de81ff34
7 changed files with 77 additions and 0 deletions

View File

@ -1,4 +1,8 @@
2009-05-22 Sven Panne <sven.panne@aedion.de> 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. * src/freeglutdll.def: Removed obsolete lines. Fixed version number.

View File

@ -574,6 +574,45 @@ FGAPI void FGAPIENTRY glutForceJoystickFunc( void );
FGAPI int FGAPIENTRY glutExtensionSupported( const char* extension ); FGAPI int FGAPIENTRY glutExtensionSupported( const char* extension );
FGAPI void FGAPIENTRY glutReportErrors( void ); 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 #ifdef __cplusplus
} }
#endif #endif

View File

@ -25,6 +25,7 @@
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/ */
#define FREEGLUT_BUILDING_LIB
#include <GL/freeglut.h> #include <GL/freeglut.h>
#include "freeglut_internal.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 * Undoes all the "glutInit" stuff
*/ */

View File

@ -933,6 +933,10 @@ int fgHintPresent(Window window, Atom property, Atom hint);
SFG_Proc fghGetProcAddress( const char *procName ); SFG_Proc fghGetProcAddress( const char *procName );
#ifdef _WIN32
extern void (__cdecl *__glutExitFunc)( int retval );
#endif
#endif /* FREEGLUT_INTERNAL_H */ #endif /* FREEGLUT_INTERNAL_H */
/*** END OF FILE ***/ /*** END OF FILE ***/

View File

@ -25,6 +25,7 @@
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/ */
#define FREEGLUT_BUILDING_LIB
#include <GL/freeglut.h> #include <GL/freeglut.h>
#include "freeglut_internal.h" #include "freeglut_internal.h"
@ -778,6 +779,12 @@ int FGAPIENTRY glutCreateMenu( void(* callback)( int ) )
return fgCreateMenu( callback )->ID; 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 * Destroys a menu object, removing all references to it
*/ */

View File

@ -25,6 +25,7 @@
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/ */
#define FREEGLUT_BUILDING_LIB
#include <GL/freeglut.h> #include <GL/freeglut.h>
#include "freeglut_internal.h" #include "freeglut_internal.h"
@ -1092,6 +1093,14 @@ int FGAPIENTRY glutCreateWindow( const char* title )
GL_FALSE, GL_FALSE )->ID; 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. * This function creates a sub window.
*/ */

View File

@ -154,3 +154,6 @@ EXPORTS
glutGetModeValues glutGetModeValues
glutInitContextFlags glutInitContextFlags
glutInitContextVersion glutInitContextVersion
__glutInitWithExit
__glutCreateWindowWithExit
__glutCreateMenuWithExit