Fix to glutInit() command-line argument compaction - Patch #1027724 from takeshi2
[freeglut] / src / freeglut_init.c
index c3de422..7b49169 100644 (file)
@@ -29,7 +29,7 @@
 #include "config.h"
 #endif
 
-#include "../include/GL/freeglut.h"
+#include <GL/freeglut.h>
 #include "freeglut_internal.h"
 
 /*
@@ -58,23 +58,24 @@ SFG_Display fgDisplay;
 SFG_State fgState = { { -1, -1, GL_FALSE },  /* Position */
                       { 300, 300, GL_TRUE }, /* Size */
                       GLUT_RGBA | GLUT_SINGLE | GLUT_DEPTH,  /* DisplayMode */
-                      GL_FALSE,              /* Initalized */
-                      GL_FALSE,              /* ForceDirectContext */
-                      GL_TRUE,               /* TryDirectContext */
+                      GL_FALSE,              /* Initialised */
+                      GLUT_TRY_DIRECT_CONTEXT,  /* DirectContext */
                       GL_FALSE,              /* ForceIconic */
                       GL_FALSE,              /* UseCurrentContext */
                       GL_FALSE,              /* GLDebugSwitch */
                       GL_FALSE,              /* XSyncSwitch */
-                      GL_TRUE,               /* IgnoreKeyRepeat */
+                      GL_TRUE,               /* KeyRepeat */
+                      0xffffffff,            /* Modifiers */
                       0,                     /* FPSInterval */
                       0,                     /* SwapCount */
                       0,                     /* SwapTime */
-#if TARGET_HOST_WIN32
+#if TARGET_HOST_WIN32 || TARGET_HOST_WINCE
                       { 0, GL_FALSE },       /* Time */
 #else
                       { { 0, 0 }, GL_FALSE },
 #endif
                       { NULL, NULL },         /* Timers */
+                      { NULL, NULL },         /* FreeTimers */
                       NULL,                   /* IdleCallback */
                       0,                      /* ActiveMenus */
                       NULL,                   /* MenuStateCallback */
@@ -83,7 +84,9 @@ SFG_State fgState = { { -1, -1, GL_FALSE },  /* Position */
                       16,                     /* GameModeDepth */
                       72,                     /* GameModeRefresh */
                       GLUT_ACTION_EXIT,       /* ActionOnWindowClose */
-                      GLUT_EXEC_STATE_INIT    /* ExecState */
+                      GLUT_EXEC_STATE_INIT,   /* ExecState */
+                      NULL,                   /* ProgramName */
+                      GL_FALSE                /* JoysticksInitialised */
 };
 
 
@@ -92,7 +95,7 @@ SFG_State fgState = { { -1, -1, GL_FALSE },  /* Position */
 /*
  * A call to this function should initialize all the display stuff...
  */
-void fgInitialize( const char* displayName )
+static void fghInitialize( const char* displayName )
 {
 #if TARGET_HOST_UNIX_X11
     fgDisplay.Display = XOpenDisplay( displayName );
@@ -130,57 +133,60 @@ void fgInitialize( const char* displayName )
 
     fgDisplay.Connection = ConnectionNumber( fgDisplay.Display );
 
-    /*
-     * Create the window deletion atom
-     */
+    /* Create the window deletion atom */
     fgDisplay.DeleteWindow = XInternAtom(
         fgDisplay.Display,
         "WM_DELETE_WINDOW",
         FALSE
     );
 
-#elif TARGET_HOST_WIN32
+#elif TARGET_HOST_WIN32 || TARGET_HOST_WINCE
 
     WNDCLASS wc;
     ATOM atom;
 
-    /*
-     * What we need to do is to initialize the fgDisplay global structure here...
-     */
+    /* What we need to do is to initialize the fgDisplay global structure here. */
     fgDisplay.Instance = GetModuleHandle( NULL );
 
-    atom = GetClassInfo( fgDisplay.Instance, "FREEGLUT", &wc );
+    atom = GetClassInfo( fgDisplay.Instance, _T("FREEGLUT"), &wc );
+
     if( atom == 0 )
     {
         ZeroMemory( &wc, sizeof(WNDCLASS) );
 
         /*
-         * Each of the windows should have its own device context...
+         * 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.style          = CS_OWNDC;
         wc.lpfnWndProc    = fgWindowProc;
         wc.cbClsExtra     = 0;
         wc.cbWndExtra     = 0;
         wc.hInstance      = fgDisplay.Instance;
-        wc.hIcon          = LoadIcon( fgDisplay.Instance, "GLUT_ICON" );
+        wc.hIcon          = LoadIcon( fgDisplay.Instance, _T("GLUT_ICON") );
+
+#if TARGET_HOST_WIN32
+        wc.style          = CS_OWNDC | CS_HREDRAW | CS_VREDRAW;
         if (!wc.hIcon)
           wc.hIcon        = LoadIcon( NULL, IDI_WINLOGO );
+#else /* TARGET_HOST_WINCE */
+        wc.style          = CS_HREDRAW | CS_VREDRAW;
+#endif
 
         wc.hCursor        = LoadCursor( NULL, IDC_ARROW );
         wc.hbrBackground  = NULL;
         wc.lpszMenuName   = NULL;
-        wc.lpszClassName  = "FREEGLUT";
+        wc.lpszClassName  = _T("FREEGLUT");
 
-        /*
-         * Register the window class
-         */
+        /* Register the window class */
         atom = RegisterClass( &wc );
         assert( atom );
     }
 
-    /*
-     * The screen dimensions can be obtained via GetSystemMetrics() calls
-     */
+    /* The screen dimensions can be obtained via GetSystemMetrics() calls */
     fgDisplay.ScreenWidth  = GetSystemMetrics( SM_CXSCREEN );
     fgDisplay.ScreenHeight = GetSystemMetrics( SM_CYSCREEN );
 
@@ -196,9 +202,7 @@ void fgInitialize( const char* displayName )
 
 #endif
 
-    fgJoystickInit( 0 );
-
-    fgState.Initalized = GL_TRUE;
+    fgState.Initialised = GL_TRUE;
 }
 
 /*
@@ -208,18 +212,16 @@ void fgDeinitialize( void )
 {
     SFG_Timer *timer;
 
-    if( !fgState.Initalized )
+    if( !fgState.Initialised )
     {
         fgWarning( "fgDeinitialize(): "
                    "no valid initialization has been performed" );
         return;
     }
 
-    /* fgState.Initalized = GL_FALSE; */
+    /* fgState.Initialised = GL_FALSE; */
 
-    /*
-     * If there was a menu created, destroy the rendering context
-     */
+    /* If there was a menu created, destroy the rendering context */
     if( fgStructure.MenuContext )
     {
         free( fgStructure.MenuContext );
@@ -228,15 +230,25 @@ void fgDeinitialize( void )
 
     fgDestroyStructure( );
 
-    while( timer = ( SFG_Timer * )fgState.Timers.First )
+    while( (timer = fgState.Timers.First) )
+    {
+        fgListRemove( &fgState.Timers, &timer->Node );
+        free( timer );
+    }
+
+    while( (timer = fgState.FreeTimers.First) )
     {
-        fgListRemove ( &fgState.Timers, &timer->Node );
+        fgListRemove( &fgState.FreeTimers, &timer->Node );
         free( timer );
     }
 
-    fgJoystickClose( );
+#if !TARGET_HOST_WINCE
+    if ( fgState.JoysticksInitialised )
+        fgJoystickClose( );
+#endif /* !TARGET_HOST_WINCE */
+    fgState.JoysticksInitialised = GL_FALSE;
 
-    fgState.Initalized = GL_FALSE;
+    fgState.Initialised = GL_FALSE;
 
     fgState.Position.X = -1;
     fgState.Position.Y = -1;
@@ -248,8 +260,7 @@ void fgDeinitialize( void )
 
     fgState.DisplayMode = GLUT_RGBA | GLUT_SINGLE | GLUT_DEPTH;
 
-    fgState.ForceDirectContext  = GL_FALSE;
-    fgState.TryDirectContext    = GL_TRUE;
+    fgState.DirectContext  = GLUT_TRY_DIRECT_CONTEXT;
     fgState.ForceIconic         = GL_FALSE;
     fgState.UseCurrentContext   = GL_FALSE;
     fgState.GLDebugSwitch       = GL_FALSE;
@@ -257,7 +268,8 @@ void fgDeinitialize( void )
     fgState.ActionOnWindowClose = GLUT_ACTION_EXIT;
     fgState.ExecState           = GLUT_EXEC_STATE_INIT;
 
-    fgState.IgnoreKeyRepeat = GL_TRUE;
+    fgState.KeyRepeat       = GL_FALSE;
+    fgState.Modifiers       = 0xffffffff;
 
     fgState.GameModeSize.X  = 640;
     fgState.GameModeSize.Y  = 480;
@@ -266,7 +278,9 @@ void fgDeinitialize( void )
 
     fgState.Time.Set = GL_FALSE;
 
-    fgState.Timers.First = fgState.Timers.Last = NULL;
+    fgListInit( &fgState.Timers );
+    fgListInit( &fgState.FreeTimers );
+
     fgState.IdleCallback = NULL;
     fgState.MenuStateCallback = ( FGCBMenuState )NULL;
     fgState.MenuStatusCallback = ( FGCBMenuStatus )NULL;
@@ -280,7 +294,7 @@ void fgDeinitialize( void )
         free( fgState.ProgramName );
         fgState.ProgramName = NULL;
     }
-    
+
 
 #if TARGET_HOST_UNIX_X11
 
@@ -303,7 +317,35 @@ void fgDeinitialize( void )
  * Everything inside the following #ifndef is copied from the X sources.
  */
 
-#ifndef TARGET_HOST_UNIX_X11
+#if TARGET_HOST_WIN32 || TARGET_HOST_WINCE
+
+/*
+
+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
@@ -323,7 +365,7 @@ void fgDeinitialize( void )
  *   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. 
+ *   not found, the corresponding argument is left unchanged.
  */
 
 static int
@@ -331,7 +373,7 @@ ReadInteger(char *string, char **NextString)
 {
     register int Result = 0;
     int Sign = 1;
-    
+
     if (*string == '+')
         string++;
     else if (*string == '-')
@@ -345,13 +387,13 @@ ReadInteger(char *string, char **NextString)
     }
     *NextString = string;
     if (Sign >= 0)
-        return (Result);
+        return Result;
     else
-        return (-Result);
+        return -Result;
 }
 
 static int XParseGeometry (
-    _Xconst char *string,
+    const char *string,
     int *x,
     int *y,
     unsigned int *width,    /* RETURN */
@@ -363,15 +405,16 @@ static int XParseGeometry (
     int tempX = 0, tempY = 0;
     char *nextCharacter;
 
-    if ( (string == NULL) || (*string == '\0')) return(mask);
+    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);
+        if (strind == nextCharacter)
+            return 0;
         strind = nextCharacter;
         mask |= WidthValue;
     }
@@ -380,7 +423,7 @@ static int XParseGeometry (
         strind++;
         tempHeight = ReadInteger(strind, &nextCharacter);
         if (strind == nextCharacter)
-            return (0);
+            return 0;
         strind = nextCharacter;
         mask |= HeightValue;
     }
@@ -390,7 +433,7 @@ static int XParseGeometry (
             strind++;
             tempX = -ReadInteger(strind, &nextCharacter);
             if (strind == nextCharacter)
-                return (0);
+                return 0;
             strind = nextCharacter;
             mask |= XNegative;
         }
@@ -399,7 +442,7 @@ static int XParseGeometry (
             strind++;
             tempX = ReadInteger(strind, &nextCharacter);
             if (strind == nextCharacter)
-                return(0);
+                return 0;
             strind = nextCharacter;
         }
         mask |= XValue;
@@ -408,7 +451,7 @@ static int XParseGeometry (
                 strind++;
                 tempY = -ReadInteger(strind, &nextCharacter);
                 if (strind == nextCharacter)
-                    return(0);
+                    return 0;
                 strind = nextCharacter;
                 mask |= YNegative;
             }
@@ -417,7 +460,7 @@ static int XParseGeometry (
                 strind++;
                 tempY = ReadInteger(strind, &nextCharacter);
                 if (strind == nextCharacter)
-                    return(0);
+                    return 0;
                 strind = nextCharacter;
             }
             mask |= YValue;
@@ -427,7 +470,7 @@ static int XParseGeometry (
     /* If strind isn't at the end of the string the it's an invalid
        geometry specification. */
 
-    if (*strind != '\0') return (0);
+    if (*strind != '\0') return 0;
 
     if (mask & XValue)
         *x = tempX;
@@ -437,7 +480,7 @@ static int XParseGeometry (
         *width = tempWidth;
     if (mask & HeightValue)
         *height = tempHeight;
-    return (mask);
+    return mask;
 }
 #endif
 
@@ -453,28 +496,34 @@ void FGAPIENTRY glutInit( int* pargc, char** argv )
     char* geometry = NULL;
     int i, j, argc = *pargc;
 
+    if( fgState.Initialised )
+        fgError( "illegal glutInit() reinitialization attempt" );
+
     if (pargc && *pargc && argv && *argv && **argv)
+    {
         fgState.ProgramName = strdup (*argv);
-    else
-        fgState.ProgramName = strdup ("");
-    if( !fgState.ProgramName )
-        fgError ("Could not allocate space for the program's name.");
 
-    if( fgState.Initalized )
-        fgError( "illegal glutInit() reinitialization attemp" );
+        if( !fgState.ProgramName )
+            fgError ("Could not allocate space for the program's name.");
+    }
 
     fgCreateStructure( );
 
     fgElapsedTime( );
 
     /* check if GLUT_FPS env var is set */
+#if !TARGET_HOST_WINCE
     {
         const char *fps = getenv( "GLUT_FPS" );
         if( fps )
         {
-            sscanf( fps, "%d", &fgState.FPSInterval );
-            if( fgState.FPSInterval <= 0 )
-                fgState.FPSInterval = 5000;  /* 5000 milliseconds */
+            int interval;
+            sscanf( fps, "%d", &interval );
+
+            if( interval <= 0 )
+                fgState.FPSInterval = 5000;  /* 5000 millisecond default */
+            else
+                fgState.FPSInterval = interval;
         }
     }
 
@@ -507,21 +556,21 @@ void FGAPIENTRY glutInit( int* pargc, char** argv )
         }
         else if( strcmp( argv[ i ], "-direct" ) == 0)
         {
-            if( ! fgState.TryDirectContext )
+            if( fgState.DirectContext == GLUT_FORCE_INDIRECT_CONTEXT )
                 fgError( "parameters ambiguity, -direct and -indirect "
                     "cannot be both specified" );
 
-            fgState.ForceDirectContext = GL_TRUE;
+            fgState.DirectContext = GLUT_FORCE_DIRECT_CONTEXT;
             argv[ i ] = NULL;
             ( *pargc )--;
         }
         else if( strcmp( argv[ i ], "-indirect" ) == 0 )
         {
-            if( fgState.ForceDirectContext )
+            if( fgState.DirectContext == GLUT_FORCE_DIRECT_CONTEXT )
                 fgError( "parameters ambiguity, -direct and -indirect "
                     "cannot be both specified" );
 
-            fgState.TryDirectContext = GL_FALSE;
+            fgState.DirectContext = GLUT_FORCE_INDIRECT_CONTEXT;
             argv[ i ] = NULL;
             (*pargc)--;
         }
@@ -548,30 +597,24 @@ void FGAPIENTRY glutInit( int* pargc, char** argv )
     /*
      * Compact {argv}.
      */
-    j = 2;
+    j = 1;
     for( i = 1; i < *pargc; i++, j++ )
     {
-        if( argv[ i ] == NULL )
-        {
-            /* Guaranteed to end because there are "*pargc" arguments left */
-            while ( argv[ j ] == NULL )
-                j++;
+        /* Guaranteed to end because there are "*pargc" arguments left */
+        while ( argv[ j ] == NULL )
+            j++;
+        if (i != j)
             argv[ i ] = argv[ j ];
-        }
     }
 
+#endif /* TARGET_HOST_WINCE */
+
     /*
-     * Have the display created now. As I am too lazy to implement
-     * the program arguments parsing, we will have the DISPLAY
-     * environment variable used for opening the X display:
-     *
-     * XXX The above comment is rather unclear.  We have just
-     * XXX completed parsing of the program arguments for GLUT
-     * XXX parameters.  We obviously canNOT parse the application-
-     * XXX specific parameters.  Can someone re-write the above
-     * XXX more clearly?
+     * 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):
      */
-    fgInitialize( displayName );
+    fghInitialize( displayName );
 
     /*
      * Geometry parsing deffered until here because we may need the screen
@@ -631,9 +674,7 @@ void FGAPIENTRY glutInitWindowSize( int width, int height )
  */
 void FGAPIENTRY glutInitDisplayMode( unsigned int displayMode )
 {
-    /*
-     * We will make use of this value when creating a new OpenGL context...
-     */
+    /* We will make use of this value when creating a new OpenGL context... */
     fgState.DisplayMode = displayMode;
 }
 
@@ -667,17 +708,15 @@ void FGAPIENTRY glutInitDisplayString( const char* displayMode )
      * delimited by blanks or tabs.
      */
     char *token ;
-    int len = strlen ( displayMode ) ;
-    char *buffer = (char *)malloc ( (len+1) * sizeof(char) ) ;
-    memcpy ( buffer, displayMode, len ) ;
-    buffer[len] = '\0' ;
+    int len = strlen ( displayMode );
+    char *buffer = (char *)malloc ( (len+1) * sizeof(char) );
+    memcpy ( buffer, displayMode, len );
+    buffer[len] = '\0';
 
-    token = strtok ( buffer, " \t" ) ;
+    token = strtok ( buffer, " \t" );
     while ( token )
     {
-        /*
-         * Process this token
-         */
+        /* Process this token */
         int i ;
         for ( i = 0; i < NUM_TOKENS; i++ )
         {
@@ -823,19 +862,17 @@ void FGAPIENTRY glutInitDisplayString( const char* displayMode )
             break ;
 
         case 28 :  /* Unrecognized */
-            printf ( "WARNING - Display string token not recognized:  %s\n",
-                     token ) ;
+            fgWarning ( "WARNING - Display string token not recognized:  %s",
+                        token );
             break ;
         }
 
-        token = strtok ( NULL, " \t" ) ;
+        token = strtok ( NULL, " \t" );
     }
 
-    free ( buffer ) ;
+    free ( buffer );
 
-    /*
-     * We will make use of this value when creating a new OpenGL context...
-     */
+    /* We will make use of this value when creating a new OpenGL context... */
     fgState.DisplayMode = glut_state_flag;
 }