X-Git-Url: http://git.mutantstargoat.com/user/nuclear/?a=blobdiff_plain;f=src%2FCommon%2Ffreeglut_init.c;h=eab4ac68cf62c9ce5c637ab0ed51df3dbd8c4a56;hb=474daf255eabd124b1023c199c3c7b98f242325c;hp=e295a6abc9379a186fd968e795e25b90343bee65;hpb=d2f7ea29ea6d946f455f4363c3f058ff2bdfba35;p=freeglut diff --git a/src/Common/freeglut_init.c b/src/Common/freeglut_init.c index e295a6a..eab4ac6 100644 --- a/src/Common/freeglut_init.c +++ b/src/Common/freeglut_init.c @@ -100,6 +100,10 @@ SFG_State fgState = { { -1, -1, GL_FALSE }, /* Position */ /* -- PRIVATE FUNCTIONS ---------------------------------------------------- */ +extern void fgPlatformInitialize( const char* displayName ); +extern void fgPlatformDeinitialiseInputDevices ( void ); +extern void fgPlatformCloseDisplay ( void ); + #if TARGET_HOST_POSIX_X11 /* Return the atom associated with "name". */ @@ -238,12 +242,12 @@ int fgHintPresent(Window window, Atom property, Atom hint) #endif /* TARGET_HOST_POSIX_X11 */ +#if TARGET_HOST_POSIX_X11 /* * A call to this function should initialize all the display stuff... */ -static void fghInitialize( const char* displayName ) +void fgPlatformInitialize( const char* displayName ) { -#if TARGET_HOST_POSIX_X11 fgDisplay.Display = XOpenDisplay( displayName ); if( fgDisplay.Display == NULL ) @@ -307,103 +311,159 @@ static void fghInitialize( const char* displayName ) } } -#elif TARGET_HOST_MS_WINDOWS - WNDCLASS wc; - ATOM atom; + fgState.Initialised = GL_TRUE; - /* What we need to do is to initialize the fgDisplay global structure here. */ - fgDisplay.Instance = GetModuleHandle( NULL ); - fgDisplay.DisplayName= displayName ? strdup(displayName) : 0 ; - atom = GetClassInfo( fgDisplay.Instance, _T("FREEGLUT"), &wc ); + atexit(fgDeinitialize); - if( atom == 0 ) - { - ZeroMemory( &wc, sizeof(WNDCLASS) ); - - /* - * Each of the windows should have its own device context, and we - * want redraw events during Vertical and Horizontal Resizes by - * the user. - * - * XXX Old code had "| CS_DBCLCKS" commented out. Plans for the - * XXX future? Dead-end idea? - */ - wc.lpfnWndProc = fgWindowProc; - wc.cbClsExtra = 0; - wc.cbWndExtra = 0; - wc.hInstance = fgDisplay.Instance; - wc.hIcon = LoadIcon( fgDisplay.Instance, _T("GLUT_ICON") ); - -#if defined(_WIN32_WCE) - wc.style = CS_HREDRAW | CS_VREDRAW; -#else - wc.style = CS_OWNDC | CS_HREDRAW | CS_VREDRAW; - if (!wc.hIcon) - wc.hIcon = LoadIcon( NULL, IDI_WINLOGO ); -#endif + /* InputDevice uses GlutTimerFunc(), so fgState.Initialised must be TRUE */ + fgInitialiseInputDevices(); +} - wc.hCursor = LoadCursor( NULL, IDC_ARROW ); - wc.hbrBackground = NULL; - wc.lpszMenuName = NULL; - wc.lpszClassName = _T("FREEGLUT"); +#endif - /* Register the window class */ - atom = RegisterClass( &wc ); - FREEGLUT_INTERNAL_ERROR_EXIT ( atom, "Window Class Not Registered", "fghInitialize" ); - } - /* The screen dimensions can be obtained via GetSystemMetrics() calls */ - fgDisplay.ScreenWidth = GetSystemMetrics( SM_CXSCREEN ); - fgDisplay.ScreenHeight = GetSystemMetrics( SM_CYSCREEN ); +void fghParseCommandLineArguments ( int* pargc, char** argv, char **pDisplayName, char **pGeometry ) +{ +#ifndef _WIN32_WCE + int i, j, argc = *pargc; { - HWND desktop = GetDesktopWindow( ); - HDC context = GetDC( desktop ); + /* check if GLUT_FPS env var is set */ + const char *fps = getenv( "GLUT_FPS" ); - fgDisplay.ScreenWidthMM = GetDeviceCaps( context, HORZSIZE ); - fgDisplay.ScreenHeightMM = GetDeviceCaps( context, VERTSIZE ); + if( fps ) + { + int interval; + sscanf( fps, "%d", &interval ); - ReleaseDC( desktop, context ); + if( interval <= 0 ) + fgState.FPSInterval = 5000; /* 5000 millisecond default */ + else + fgState.FPSInterval = interval; + } } - /* If we have a DisplayName try to use it for metrics */ - if( fgDisplay.DisplayName ) + + *pDisplayName = getenv( "DISPLAY" ); + + for( i = 1; i < argc; i++ ) { - HDC context = CreateDC(fgDisplay.DisplayName,0,0,0); - if( context ) + if( strcmp( argv[ i ], "-display" ) == 0 ) + { + if( ++i >= argc ) + fgError( "-display parameter must be followed by display name" ); + + *pDisplayName = argv[ i ]; + + argv[ i - 1 ] = NULL; + argv[ i ] = NULL; + ( *pargc ) -= 2; + } + else if( strcmp( argv[ i ], "-geometry" ) == 0 ) { - fgDisplay.ScreenWidth = GetDeviceCaps( context, HORZRES ); - fgDisplay.ScreenHeight = GetDeviceCaps( context, VERTRES ); - fgDisplay.ScreenWidthMM = GetDeviceCaps( context, HORZSIZE ); - fgDisplay.ScreenHeightMM = GetDeviceCaps( context, VERTSIZE ); - DeleteDC(context); + if( ++i >= argc ) + fgError( "-geometry parameter must be followed by window " + "geometry settings" ); + + *pGeometry = argv[ i ]; + + argv[ i - 1 ] = NULL; + argv[ i ] = NULL; + ( *pargc ) -= 2; + } + else if( strcmp( argv[ i ], "-direct" ) == 0) + { + if( fgState.DirectContext == GLUT_FORCE_INDIRECT_CONTEXT ) + fgError( "parameters ambiguity, -direct and -indirect " + "cannot be both specified" ); + + fgState.DirectContext = GLUT_FORCE_DIRECT_CONTEXT; + argv[ i ] = NULL; + ( *pargc )--; + } + else if( strcmp( argv[ i ], "-indirect" ) == 0 ) + { + if( fgState.DirectContext == GLUT_FORCE_DIRECT_CONTEXT ) + fgError( "parameters ambiguity, -direct and -indirect " + "cannot be both specified" ); + + fgState.DirectContext = GLUT_FORCE_INDIRECT_CONTEXT; + argv[ i ] = NULL; + (*pargc)--; + } + else if( strcmp( argv[ i ], "-iconic" ) == 0 ) + { + fgState.ForceIconic = GL_TRUE; + argv[ i ] = NULL; + ( *pargc )--; + } + else if( strcmp( argv[ i ], "-gldebug" ) == 0 ) + { + fgState.GLDebugSwitch = GL_TRUE; + argv[ i ] = NULL; + ( *pargc )--; + } + else if( strcmp( argv[ i ], "-sync" ) == 0 ) + { + fgState.XSyncSwitch = GL_TRUE; + argv[ i ] = NULL; + ( *pargc )--; } - else - fgWarning("fghInitialize: " - "CreateDC failed, Screen size info may be incorrect\n" - "This is quite likely caused by a bad '-display' parameter"); - } - /* Set the timer granularity to 1 ms */ - timeBeginPeriod ( 1 ); -#endif + /* Compact {argv}. */ + for( i = j = 1; i < *pargc; i++, j++ ) + { + /* Guaranteed to end because there are "*pargc" arguments left */ + while ( argv[ j ] == NULL ) + j++; + if ( i != j ) + argv[ i ] = argv[ j ]; + } + +#endif /* _WIN32_WCE */ + +} + + +void fghCloseInputDevices ( void ) +{ + if ( fgState.JoysticksInitialised ) + fgJoystickClose( ); + + if ( fgState.InputDevsInitialised ) + fgInputDeviceClose( ); +} - fgState.Initialised = GL_TRUE; - /* Avoid registering atexit callback on Win32 as it results in an access - * violation due to calling into a module which has been unloaded. - * Any cleanup isn't needed on Windows anyway, the OS takes care of it.c - * see: http://blogs.msdn.com/b/oldnewthing/archive/2012/01/05/10253268.aspx +#if TARGET_HOST_POSIX_X11 +void fgPlatformDeinitialiseInputDevices ( void ) +{ + fghCloseInputDevices (); + + fgState.JoysticksInitialised = GL_FALSE; + fgState.InputDevsInitialised = GL_FALSE; +} + + +void fgPlatformCloseDisplay ( void ) +{ + /* + * Make sure all X-client data we have created will be destroyed on + * display closing */ -#if ( TARGET_HOST_MS_WINDOWS == 0 ) - atexit(fgDeinitialize); -#endif + XSetCloseDownMode( fgDisplay.Display, DestroyAll ); - /* InputDevice uses GlutTimerFunc(), so fgState.Initialised must be TRUE */ - fgInitialiseInputDevices(); + /* + * Close the display connection, destroying all windows we have + * created so far + */ + XCloseDisplay( fgDisplay.Display ); } +#endif + + /* * Perform the freeglut deinitialization... */ @@ -446,15 +506,7 @@ void fgDeinitialize( void ) free( timer ); } -#if !defined(_WIN32_WCE) - if ( fgState.JoysticksInitialised ) - fgJoystickClose( ); - - if ( fgState.InputDevsInitialised ) - fgInputDeviceClose( ); -#endif /* !defined(_WIN32_WCE) */ - fgState.JoysticksInitialised = GL_FALSE; - fgState.InputDevsInitialised = GL_FALSE; + fgPlatformDeinitialiseInputDevices (); fgState.MouseWheelTicks = 0; @@ -508,69 +560,13 @@ void fgDeinitialize( void ) fgState.ProgramName = NULL; } -#if TARGET_HOST_POSIX_X11 - - /* - * Make sure all X-client data we have created will be destroyed on - * display closing - */ - XSetCloseDownMode( fgDisplay.Display, DestroyAll ); - - /* - * Close the display connection, destroying all windows we have - * created so far - */ - XCloseDisplay( fgDisplay.Display ); - -#elif TARGET_HOST_MS_WINDOWS - if( fgDisplay.DisplayName ) - { - free( fgDisplay.DisplayName ); - fgDisplay.DisplayName = NULL; - } - - /* Reset the timer granularity */ - timeEndPeriod ( 1 ); - -#endif + fgPlatformCloseDisplay (); fgState.Initialised = GL_FALSE; } -/* - * Everything inside the following #ifndef is copied from the X sources. - */ #if TARGET_HOST_MS_WINDOWS - -/* - -Copyright 1985, 1986, 1987,1998 The Open Group - -Permission to use, copy, modify, distribute, and sell this software and its -documentation for any purpose is hereby granted without fee, provided that -the above copyright notice appear in all copies and that both that -copyright notice and this permission notice appear in supporting -documentation. - -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 THE OPEN GROUP 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. - -Except as contained in this notice, the name of The Open Group shall -not be used in advertising or otherwise to promote the sale, use or -other dealings in this Software without prior written authorization -from The Open Group. - -*/ - #define NoValue 0x0000 #define XValue 0x0001 #define YValue 0x0002 @@ -580,132 +576,12 @@ from The Open Group. #define XNegative 0x0010 #define YNegative 0x0020 -/* - * XParseGeometry parses strings of the form - * "=x{+-}{+-}", where - * width, height, xoffset, and yoffset are unsigned integers. - * Example: "=80x24+300-49" - * The equal sign is optional. - * It returns a bitmask that indicates which of the four values - * were actually found in the string. For each value found, - * the corresponding argument is updated; for each value - * not found, the corresponding argument is left unchanged. - */ - -static int -ReadInteger(char *string, char **NextString) -{ - register int Result = 0; - int Sign = 1; - - if (*string == '+') - string++; - else if (*string == '-') - { - string++; - Sign = -1; - } - for (; (*string >= '0') && (*string <= '9'); string++) - { - Result = (Result * 10) + (*string - '0'); - } - *NextString = string; - if (Sign >= 0) - return Result; - else - return -Result; -} - -static int XParseGeometry ( +extern int XParseGeometry ( const char *string, int *x, int *y, unsigned int *width, /* RETURN */ - unsigned int *height) /* RETURN */ -{ - int mask = NoValue; - register char *strind; - unsigned int tempWidth = 0, tempHeight = 0; - int tempX = 0, tempY = 0; - char *nextCharacter; - - if ( (string == NULL) || (*string == '\0')) - return mask; - if (*string == '=') - string++; /* ignore possible '=' at beg of geometry spec */ - - strind = (char *)string; - if (*strind != '+' && *strind != '-' && *strind != 'x') { - tempWidth = ReadInteger(strind, &nextCharacter); - if (strind == nextCharacter) - return 0; - strind = nextCharacter; - mask |= WidthValue; - } - - if (*strind == 'x' || *strind == 'X') { - strind++; - tempHeight = ReadInteger(strind, &nextCharacter); - if (strind == nextCharacter) - return 0; - strind = nextCharacter; - mask |= HeightValue; - } - - if ((*strind == '+') || (*strind == '-')) { - if (*strind == '-') { - strind++; - tempX = -ReadInteger(strind, &nextCharacter); - if (strind == nextCharacter) - return 0; - strind = nextCharacter; - mask |= XNegative; - } - else - { - strind++; - tempX = ReadInteger(strind, &nextCharacter); - if (strind == nextCharacter) - return 0; - strind = nextCharacter; - } - mask |= XValue; - if ((*strind == '+') || (*strind == '-')) { - if (*strind == '-') { - strind++; - tempY = -ReadInteger(strind, &nextCharacter); - if (strind == nextCharacter) - return 0; - strind = nextCharacter; - mask |= YNegative; - } - else - { - strind++; - tempY = ReadInteger(strind, &nextCharacter); - if (strind == nextCharacter) - return 0; - strind = nextCharacter; - } - mask |= YValue; - } - } - - /* If strind isn't at the end of the string the it's an invalid - geometry specification. */ - - if (*strind != '\0') return 0; - - if (mask & XValue) - *x = tempX; - if (mask & YValue) - *y = tempY; - if (mask & WidthValue) - *width = tempWidth; - if (mask & HeightValue) - *height = tempHeight; - return mask; -} + unsigned int *height); /* RETURN */ #endif /* -- INTERFACE FUNCTIONS -------------------------------------------------- */ @@ -718,8 +594,6 @@ void FGAPIENTRY glutInit( int* pargc, char** argv ) { char* displayName = NULL; char* geometry = NULL; - int i, j, argc = *pargc; - if( fgState.Initialised ) fgError( "illegal glutInit() reinitialization attempt" ); @@ -736,108 +610,14 @@ void FGAPIENTRY glutInit( int* pargc, char** argv ) /* Get start time */ fgState.Time = fgSystemTime(); - /* check if GLUT_FPS env var is set */ -#ifndef _WIN32_WCE - { - const char *fps = getenv( "GLUT_FPS" ); - - if( fps ) - { - int interval; - sscanf( fps, "%d", &interval ); - - if( interval <= 0 ) - fgState.FPSInterval = 5000; /* 5000 millisecond default */ - else - fgState.FPSInterval = interval; - } - } - - displayName = getenv( "DISPLAY" ); - - for( i = 1; i < argc; i++ ) - { - if( strcmp( argv[ i ], "-display" ) == 0 ) - { - if( ++i >= argc ) - fgError( "-display parameter must be followed by display name" ); - - displayName = argv[ i ]; - - argv[ i - 1 ] = NULL; - argv[ i ] = NULL; - ( *pargc ) -= 2; - } - else if( strcmp( argv[ i ], "-geometry" ) == 0 ) - { - if( ++i >= argc ) - fgError( "-geometry parameter must be followed by window " - "geometry settings" ); - - geometry = argv[ i ]; - - argv[ i - 1 ] = NULL; - argv[ i ] = NULL; - ( *pargc ) -= 2; - } - else if( strcmp( argv[ i ], "-direct" ) == 0) - { - if( fgState.DirectContext == GLUT_FORCE_INDIRECT_CONTEXT ) - fgError( "parameters ambiguity, -direct and -indirect " - "cannot be both specified" ); - - fgState.DirectContext = GLUT_FORCE_DIRECT_CONTEXT; - argv[ i ] = NULL; - ( *pargc )--; - } - else if( strcmp( argv[ i ], "-indirect" ) == 0 ) - { - if( fgState.DirectContext == GLUT_FORCE_DIRECT_CONTEXT ) - fgError( "parameters ambiguity, -direct and -indirect " - "cannot be both specified" ); - - fgState.DirectContext = GLUT_FORCE_INDIRECT_CONTEXT; - argv[ i ] = NULL; - (*pargc)--; - } - else if( strcmp( argv[ i ], "-iconic" ) == 0 ) - { - fgState.ForceIconic = GL_TRUE; - argv[ i ] = NULL; - ( *pargc )--; - } - else if( strcmp( argv[ i ], "-gldebug" ) == 0 ) - { - fgState.GLDebugSwitch = GL_TRUE; - argv[ i ] = NULL; - ( *pargc )--; - } - else if( strcmp( argv[ i ], "-sync" ) == 0 ) - { - fgState.XSyncSwitch = GL_TRUE; - argv[ i ] = NULL; - ( *pargc )--; - } - } - - /* Compact {argv}. */ - for( i = j = 1; i < *pargc; i++, j++ ) - { - /* Guaranteed to end because there are "*pargc" arguments left */ - while ( argv[ j ] == NULL ) - j++; - if ( i != j ) - argv[ i ] = argv[ j ]; - } - -#endif /* _WIN32_WCE */ + fghParseCommandLineArguments ( pargc, argv, &displayName, &geometry ); /* * Have the display created now. If there wasn't a "-display" * in the program arguments, we will use the DISPLAY environment * variable for opening the X display (see code above): */ - fghInitialize( displayName ); + fgPlatformInitialize( displayName ); /* * Geometry parsing deffered until here because we may need the screen