timers internally now use 64bit unsigned int, if available
[freeglut] / src / Common / freeglut_init.c
index 0a96b14..bb0c097 100644 (file)
-/*\r
- * freeglut_init.c\r
- *\r
- * Various freeglut initialization functions.\r
- *\r
- * Copyright (c) 1999-2000 Pawel W. Olszta. All Rights Reserved.\r
- * Written by Pawel W. Olszta, <olszta@sourceforge.net>\r
- * Creation date: Thu Dec 2 1999\r
- *\r
- * Permission is hereby granted, free of charge, to any person obtaining a\r
- * copy of this software and associated documentation files (the "Software"),\r
- * to deal in the Software without restriction, including without limitation\r
- * the rights to use, copy, modify, merge, publish, distribute, sublicense,\r
- * and/or sell copies of the Software, and to permit persons to whom the\r
- * Software is furnished to do so, subject to the following conditions:\r
- *\r
- * The above copyright notice and this permission notice shall be included\r
- * in all copies or substantial portions of the Software.\r
- *\r
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS\r
- * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\r
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL\r
- * PAWEL W. OLSZTA BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER\r
- * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN\r
- * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.\r
- */\r
-\r
-#define FREEGLUT_BUILDING_LIB\r
-#include <GL/freeglut.h>\r
-#include "freeglut_internal.h"\r
-\r
-#if TARGET_HOST_POSIX_X11\r
-#include <limits.h>  /* LONG_MAX */\r
-#endif\r
-\r
-/*\r
- * TODO BEFORE THE STABLE RELEASE:\r
- *\r
- *  fgDeinitialize()        -- Win32's OK, X11 needs the OS-specific\r
- *                             deinitialization done\r
- *  glutInitDisplayString() -- display mode string parsing\r
- *\r
- * Wouldn't it be cool to use gettext() for error messages? I just love\r
- * bash saying  "nie znaleziono pliku" instead of "file not found" :)\r
- * Is gettext easily portable?\r
- */\r
-\r
-/* -- GLOBAL VARIABLES ----------------------------------------------------- */\r
-\r
-/*\r
- * A structure pointed by g_pDisplay holds all information\r
- * regarding the display, screen, root window etc.\r
- */\r
-SFG_Display fgDisplay;\r
-\r
-/*\r
- * The settings for the current freeglut session\r
- */\r
-SFG_State fgState = { { -1, -1, GL_FALSE },  /* Position */\r
-                      { 300, 300, GL_TRUE }, /* Size */\r
-                      GLUT_RGBA | GLUT_SINGLE | GLUT_DEPTH,  /* DisplayMode */\r
-                      GL_FALSE,              /* Initialised */\r
-                      GLUT_TRY_DIRECT_CONTEXT,  /* DirectContext */\r
-                      GL_FALSE,              /* ForceIconic */\r
-                      GL_FALSE,              /* UseCurrentContext */\r
-                      GL_FALSE,              /* GLDebugSwitch */\r
-                      GL_FALSE,              /* XSyncSwitch */\r
-                      GLUT_KEY_REPEAT_ON,    /* KeyRepeat */\r
-                      INVALID_MODIFIERS,     /* Modifiers */\r
-                      0,                     /* FPSInterval */\r
-                      0,                     /* SwapCount */\r
-                      0,                     /* SwapTime */\r
-                      0,                     /* Time */\r
-                      { NULL, NULL },         /* Timers */\r
-                      { NULL, NULL },         /* FreeTimers */\r
-                      NULL,                   /* IdleCallback */\r
-                      0,                      /* ActiveMenus */\r
-                      NULL,                   /* MenuStateCallback */\r
-                      NULL,                   /* MenuStatusCallback */\r
-                      { 640, 480, GL_TRUE },  /* GameModeSize */\r
-                      16,                     /* GameModeDepth */\r
-                      72,                     /* GameModeRefresh */\r
-                      GLUT_ACTION_EXIT,       /* ActionOnWindowClose */\r
-                      GLUT_EXEC_STATE_INIT,   /* ExecState */\r
-                      NULL,                   /* ProgramName */\r
-                      GL_FALSE,               /* JoysticksInitialised */\r
-                      0,                      /* NumActiveJoysticks */\r
-                      GL_FALSE,               /* InputDevsInitialised */\r
-                      0,                      /* MouseWheelTicks */\r
-                      1,                      /* AuxiliaryBufferNumber */\r
-                      4,                      /* SampleNumber */\r
-                      1,                      /* MajorVersion */\r
-                      0,                      /* MinorVersion */\r
-                      0,                      /* ContextFlags */\r
-                      0,                      /* ContextProfile */\r
-                      NULL,                   /* ErrorFunc */\r
-                      NULL                    /* WarningFunc */\r
-};\r
-\r
-\r
-/* -- PRIVATE FUNCTIONS ---------------------------------------------------- */\r
-\r
-extern void fghInitialize( const char* displayName );\r
-extern void fghDeinitialiseInputDevices ( void );\r
-extern void fghCloseDisplay ( void );\r
-\r
-#if TARGET_HOST_POSIX_X11\r
-\r
-/* Return the atom associated with "name". */\r
-static Atom fghGetAtom(const char * name)\r
-{\r
-  return XInternAtom(fgDisplay.Display, name, False);\r
-}\r
-\r
-/*\r
- * Check if "property" is set on "window".  The property's values are returned\r
- * through "data".  If the property is set and is of type "type", return the\r
- * number of elements in "data".  Return zero otherwise.  In both cases, use\r
- * "Xfree()" to free "data".\r
- */\r
-static int fghGetWindowProperty(Window window,\r
-                               Atom property,\r
-                               Atom type,\r
-                               unsigned char ** data)\r
-{\r
-  /*\r
-   * Caller always has to use "Xfree()" to free "data", since\r
-   * "XGetWindowProperty() always allocates one extra byte in prop_return\r
-   * [i.e. "data"] (even if the property is zero length) [..]".\r
-   */\r
-\r
-  int status;  /*  Returned by "XGetWindowProperty". */\r
-\r
-  Atom          type_returned;\r
-  int           temp_format;             /*  Not used. */\r
-  unsigned long number_of_elements;\r
-  unsigned long temp_bytes_after;        /*  Not used. */\r
-\r
-\r
-  status = XGetWindowProperty(fgDisplay.Display,\r
-                             window,\r
-                             property,\r
-                             0,\r
-                             LONG_MAX,\r
-                             False,\r
-                             type,\r
-                             &type_returned,\r
-                             &temp_format,\r
-                             &number_of_elements,\r
-                             &temp_bytes_after,\r
-                             data);\r
-\r
-  FREEGLUT_INTERNAL_ERROR_EXIT(status == Success,\r
-                              "XGetWindowProperty failled",\r
-                              "fghGetWindowProperty");\r
-\r
-  if (type_returned != type)\r
-    {\r
-      number_of_elements = 0;\r
-    }\r
-\r
-  return number_of_elements;\r
-}\r
-\r
-/*  Check if the window manager is NET WM compliant. */\r
-static int fghNetWMSupported(void)\r
-{\r
-  Atom wm_check;\r
-  Window ** window_ptr_1;\r
-\r
-  int number_of_windows;\r
-  int net_wm_supported;\r
-\r
-\r
-  net_wm_supported = 0;\r
-\r
-  wm_check = fghGetAtom("_NET_SUPPORTING_WM_CHECK");\r
-  window_ptr_1 = malloc(sizeof(Window *));\r
-\r
-  /*\r
-   * Check that the window manager has set this property on the root window.\r
-   * The property must be the ID of a child window.\r
-   */\r
-  number_of_windows = fghGetWindowProperty(fgDisplay.RootWindow,\r
-                                           wm_check,\r
-                                           XA_WINDOW,\r
-                                           (unsigned char **) window_ptr_1);\r
-  if (number_of_windows == 1)\r
-    {\r
-      Window ** window_ptr_2;\r
-\r
-      window_ptr_2 = malloc(sizeof(Window *));\r
-\r
-      /* Check that the window has the same property set to the same value. */\r
-      number_of_windows = fghGetWindowProperty(**window_ptr_1,\r
-                                               wm_check,\r
-                                               XA_WINDOW,\r
-                                               (unsigned char **) window_ptr_2);\r
-      if ((number_of_windows == 1) && (**window_ptr_1 == **window_ptr_2))\r
-      {\r
-        /* NET WM compliant */\r
-        net_wm_supported = 1;\r
-      }\r
-\r
-      XFree(*window_ptr_2);\r
-      free(window_ptr_2);\r
-    }\r
-\r
-        XFree(*window_ptr_1);\r
-        free(window_ptr_1);\r
-\r
-        return net_wm_supported;\r
-}\r
-\r
-/*  Check if "hint" is present in "property" for "window". */\r
-int fgHintPresent(Window window, Atom property, Atom hint)\r
-{\r
-  Atom *atoms;\r
-  int number_of_atoms;\r
-  int supported;\r
-  int i;\r
-\r
-  supported = 0;\r
-\r
-  number_of_atoms = fghGetWindowProperty(window,\r
-                                        property,\r
-                                        XA_ATOM,\r
-                                        (unsigned char **) &atoms);\r
-  for (i = 0; i < number_of_atoms; i++)\r
-  {\r
-      if (atoms[i] == hint)\r
-      {\r
-          supported = 1;\r
-          break;\r
-      }\r
-  }\r
-\r
-  XFree(atoms);\r
-  return supported;\r
-}\r
-\r
-#endif /*  TARGET_HOST_POSIX_X11  */\r
-\r
-\r
-#if TARGET_HOST_POSIX_X11\r
-/*\r
- * A call to this function should initialize all the display stuff...\r
- */\r
-static void fghInitialize( const char* displayName )\r
-{\r
-    fgDisplay.Display = XOpenDisplay( displayName );\r
-\r
-    if( fgDisplay.Display == NULL )\r
-        fgError( "failed to open display '%s'", XDisplayName( displayName ) );\r
-\r
-    if( !glXQueryExtension( fgDisplay.Display, NULL, NULL ) )\r
-        fgError( "OpenGL GLX extension not supported by display '%s'",\r
-            XDisplayName( displayName ) );\r
-\r
-    fgDisplay.Screen = DefaultScreen( fgDisplay.Display );\r
-    fgDisplay.RootWindow = RootWindow(\r
-        fgDisplay.Display,\r
-        fgDisplay.Screen\r
-    );\r
-\r
-    fgDisplay.ScreenWidth  = DisplayWidth(\r
-        fgDisplay.Display,\r
-        fgDisplay.Screen\r
-    );\r
-    fgDisplay.ScreenHeight = DisplayHeight(\r
-        fgDisplay.Display,\r
-        fgDisplay.Screen\r
-    );\r
-\r
-    fgDisplay.ScreenWidthMM = DisplayWidthMM(\r
-        fgDisplay.Display,\r
-        fgDisplay.Screen\r
-    );\r
-    fgDisplay.ScreenHeightMM = DisplayHeightMM(\r
-        fgDisplay.Display,\r
-        fgDisplay.Screen\r
-    );\r
-\r
-    fgDisplay.Connection = ConnectionNumber( fgDisplay.Display );\r
-\r
-    /* Create the window deletion atom */\r
-    fgDisplay.DeleteWindow = fghGetAtom("WM_DELETE_WINDOW");\r
-\r
-    /* Create the state and full screen atoms */\r
-    fgDisplay.State           = None;\r
-    fgDisplay.StateFullScreen = None;\r
-\r
-    if (fghNetWMSupported())\r
-    {\r
-      const Atom supported = fghGetAtom("_NET_SUPPORTED");\r
-      const Atom state     = fghGetAtom("_NET_WM_STATE");\r
-      \r
-      /* Check if the state hint is supported. */\r
-      if (fgHintPresent(fgDisplay.RootWindow, supported, state))\r
-      {\r
-        const Atom full_screen = fghGetAtom("_NET_WM_STATE_FULLSCREEN");\r
-        \r
-        fgDisplay.State = state;\r
-        \r
-        /* Check if the window manager supports full screen. */\r
-        /**  Check "_NET_WM_ALLOWED_ACTIONS" on our window instead? **/\r
-        if (fgHintPresent(fgDisplay.RootWindow, supported, full_screen))\r
-        {\r
-          fgDisplay.StateFullScreen = full_screen;\r
-        }\r
-      }\r
-    }\r
-\r
-\r
-    fgState.Initialised = GL_TRUE;\r
-\r
-    atexit(fgDeinitialize);\r
-\r
-    /* InputDevice uses GlutTimerFunc(), so fgState.Initialised must be TRUE */\r
-    fgInitialiseInputDevices();\r
-}\r
-\r
-#endif\r
-\r
-void fghCloseInputDevices ( void )\r
-{\r
-    if ( fgState.JoysticksInitialised )\r
-        fgJoystickClose( );\r
-\r
-    if ( fgState.InputDevsInitialised )\r
-        fgInputDeviceClose( );\r
-}\r
-\r
-\r
-#if TARGET_HOST_POSIX_X11\r
-static void fghDeinitialiseInputDevices ( void )\r
-{\r
-       fghCloseInputDevices ();\r
-\r
-    fgState.JoysticksInitialised = GL_FALSE;\r
-    fgState.InputDevsInitialised = GL_FALSE;\r
-}\r
-\r
-\r
-static void fghCloseDisplay ( void )\r
-{\r
-    /*\r
-     * Make sure all X-client data we have created will be destroyed on\r
-     * display closing\r
-     */\r
-    XSetCloseDownMode( fgDisplay.Display, DestroyAll );\r
-\r
-    /*\r
-     * Close the display connection, destroying all windows we have\r
-     * created so far\r
-     */\r
-    XCloseDisplay( fgDisplay.Display );\r
-}\r
-\r
-#endif\r
-\r
-\r
-/*\r
- * Perform the freeglut deinitialization...\r
- */\r
-void fgDeinitialize( void )\r
-{\r
-    SFG_Timer *timer;\r
-\r
-    if( !fgState.Initialised )\r
-    {\r
-        return;\r
-    }\r
-\r
-       /* If we're in game mode, we want to leave game mode */\r
-    if( fgStructure.GameModeWindow ) {\r
-        glutLeaveGameMode();\r
-    }\r
-\r
-    /* If there was a menu created, destroy the rendering context */\r
-    if( fgStructure.MenuContext )\r
-    {\r
-#if TARGET_HOST_POSIX_X11\r
-        /* Note that the MVisualInfo is not owned by the MenuContext! */\r
-        glXDestroyContext( fgDisplay.Display, fgStructure.MenuContext->MContext );\r
-#endif\r
-        free( fgStructure.MenuContext );\r
-        fgStructure.MenuContext = NULL;\r
-    }\r
-\r
-    fgDestroyStructure( );\r
-\r
-    while( ( timer = fgState.Timers.First) )\r
-    {\r
-        fgListRemove( &fgState.Timers, &timer->Node );\r
-        free( timer );\r
-    }\r
-\r
-    while( ( timer = fgState.FreeTimers.First) )\r
-    {\r
-        fgListRemove( &fgState.FreeTimers, &timer->Node );\r
-        free( timer );\r
-    }\r
-\r
-       fghDeinitialiseInputDevices ();\r
-\r
-       fgState.MouseWheelTicks = 0;\r
-\r
-    fgState.MajorVersion = 1;\r
-    fgState.MinorVersion = 0;\r
-    fgState.ContextFlags = 0;\r
-    fgState.ContextProfile = 0;\r
-\r
-    fgState.Initialised = GL_FALSE;\r
-\r
-    fgState.Position.X = -1;\r
-    fgState.Position.Y = -1;\r
-    fgState.Position.Use = GL_FALSE;\r
-\r
-    fgState.Size.X = 300;\r
-    fgState.Size.Y = 300;\r
-    fgState.Size.Use = GL_TRUE;\r
-\r
-    fgState.DisplayMode = GLUT_RGBA | GLUT_SINGLE | GLUT_DEPTH;\r
-\r
-    fgState.DirectContext  = GLUT_TRY_DIRECT_CONTEXT;\r
-    fgState.ForceIconic         = GL_FALSE;\r
-    fgState.UseCurrentContext   = GL_FALSE;\r
-    fgState.GLDebugSwitch       = GL_FALSE;\r
-    fgState.XSyncSwitch         = GL_FALSE;\r
-    fgState.ActionOnWindowClose = GLUT_ACTION_EXIT;\r
-    fgState.ExecState           = GLUT_EXEC_STATE_INIT;\r
-\r
-    fgState.KeyRepeat       = GLUT_KEY_REPEAT_ON;\r
-    fgState.Modifiers       = INVALID_MODIFIERS;\r
-\r
-    fgState.GameModeSize.X  = 640;\r
-    fgState.GameModeSize.Y  = 480;\r
-    fgState.GameModeDepth   =  16;\r
-    fgState.GameModeRefresh =  72;\r
-\r
-    fgListInit( &fgState.Timers );\r
-    fgListInit( &fgState.FreeTimers );\r
-\r
-    fgState.IdleCallback = NULL;\r
-    fgState.MenuStateCallback = ( FGCBMenuState )NULL;\r
-    fgState.MenuStatusCallback = ( FGCBMenuStatus )NULL;\r
-\r
-    fgState.SwapCount   = 0;\r
-    fgState.SwapTime    = 0;\r
-    fgState.FPSInterval = 0;\r
-\r
-    if( fgState.ProgramName )\r
-    {\r
-        free( fgState.ProgramName );\r
-        fgState.ProgramName = NULL;\r
-    }\r
-\r
-       fghCloseDisplay ();\r
-\r
-    fgState.Initialised = GL_FALSE;\r
-}\r
-\r
-/*\r
- * Everything inside the following #ifndef is copied from the X sources.\r
- */\r
-\r
-#if TARGET_HOST_MS_WINDOWS\r
-\r
-/*\r
-\r
-Copyright 1985, 1986, 1987,1998  The Open Group\r
-\r
-Permission to use, copy, modify, distribute, and sell this software and its\r
-documentation for any purpose is hereby granted without fee, provided that\r
-the above copyright notice appear in all copies and that both that\r
-copyright notice and this permission notice appear in supporting\r
-documentation.\r
-\r
-The above copyright notice and this permission notice shall be included\r
-in all copies or substantial portions of the Software.\r
-\r
-THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS\r
-OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF\r
-MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.\r
-IN NO EVENT SHALL THE OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR\r
-OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,\r
-ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR\r
-OTHER DEALINGS IN THE SOFTWARE.\r
-\r
-Except as contained in this notice, the name of The Open Group shall\r
-not be used in advertising or otherwise to promote the sale, use or\r
-other dealings in this Software without prior written authorization\r
-from The Open Group.\r
-\r
-*/\r
-\r
-#define NoValue         0x0000\r
-#define XValue          0x0001\r
-#define YValue          0x0002\r
-#define WidthValue      0x0004\r
-#define HeightValue     0x0008\r
-#define AllValues       0x000F\r
-#define XNegative       0x0010\r
-#define YNegative       0x0020\r
-\r
-/*\r
- *    XParseGeometry parses strings of the form\r
- *   "=<width>x<height>{+-}<xoffset>{+-}<yoffset>", where\r
- *   width, height, xoffset, and yoffset are unsigned integers.\r
- *   Example:  "=80x24+300-49"\r
- *   The equal sign is optional.\r
- *   It returns a bitmask that indicates which of the four values\r
- *   were actually found in the string.  For each value found,\r
- *   the corresponding argument is updated;  for each value\r
- *   not found, the corresponding argument is left unchanged.\r
- */\r
-\r
-static int\r
-ReadInteger(char *string, char **NextString)\r
-{\r
-    register int Result = 0;\r
-    int Sign = 1;\r
-\r
-    if (*string == '+')\r
-        string++;\r
-    else if (*string == '-')\r
-    {\r
-        string++;\r
-        Sign = -1;\r
-    }\r
-    for (; (*string >= '0') && (*string <= '9'); string++)\r
-    {\r
-        Result = (Result * 10) + (*string - '0');\r
-    }\r
-    *NextString = string;\r
-    if (Sign >= 0)\r
-        return Result;\r
-    else\r
-        return -Result;\r
-}\r
-\r
-static int XParseGeometry (\r
-    const char *string,\r
-    int *x,\r
-    int *y,\r
-    unsigned int *width,    /* RETURN */\r
-    unsigned int *height)    /* RETURN */\r
-{\r
-    int mask = NoValue;\r
-    register char *strind;\r
-    unsigned int tempWidth = 0, tempHeight = 0;\r
-    int tempX = 0, tempY = 0;\r
-    char *nextCharacter;\r
-\r
-    if ( (string == NULL) || (*string == '\0'))\r
-      return mask;\r
-    if (*string == '=')\r
-        string++;  /* ignore possible '=' at beg of geometry spec */\r
-\r
-    strind = (char *)string;\r
-    if (*strind != '+' && *strind != '-' && *strind != 'x') {\r
-        tempWidth = ReadInteger(strind, &nextCharacter);\r
-        if (strind == nextCharacter)\r
-            return 0;\r
-        strind = nextCharacter;\r
-        mask |= WidthValue;\r
-    }\r
-\r
-    if (*strind == 'x' || *strind == 'X') {\r
-        strind++;\r
-        tempHeight = ReadInteger(strind, &nextCharacter);\r
-        if (strind == nextCharacter)\r
-            return 0;\r
-        strind = nextCharacter;\r
-        mask |= HeightValue;\r
-    }\r
-\r
-    if ((*strind == '+') || (*strind == '-')) {\r
-        if (*strind == '-') {\r
-            strind++;\r
-            tempX = -ReadInteger(strind, &nextCharacter);\r
-            if (strind == nextCharacter)\r
-                return 0;\r
-            strind = nextCharacter;\r
-            mask |= XNegative;\r
-        }\r
-        else\r
-        {\r
-            strind++;\r
-            tempX = ReadInteger(strind, &nextCharacter);\r
-            if (strind == nextCharacter)\r
-                return 0;\r
-            strind = nextCharacter;\r
-        }\r
-        mask |= XValue;\r
-        if ((*strind == '+') || (*strind == '-')) {\r
-            if (*strind == '-') {\r
-                strind++;\r
-                tempY = -ReadInteger(strind, &nextCharacter);\r
-                if (strind == nextCharacter)\r
-                    return 0;\r
-                strind = nextCharacter;\r
-                mask |= YNegative;\r
-            }\r
-            else\r
-            {\r
-                strind++;\r
-                tempY = ReadInteger(strind, &nextCharacter);\r
-                if (strind == nextCharacter)\r
-                    return 0;\r
-                strind = nextCharacter;\r
-            }\r
-            mask |= YValue;\r
-        }\r
-    }\r
-\r
-    /* If strind isn't at the end of the string the it's an invalid\r
-       geometry specification. */\r
-\r
-    if (*strind != '\0') return 0;\r
-\r
-    if (mask & XValue)\r
-        *x = tempX;\r
-    if (mask & YValue)\r
-        *y = tempY;\r
-    if (mask & WidthValue)\r
-        *width = tempWidth;\r
-    if (mask & HeightValue)\r
-        *height = tempHeight;\r
-    return mask;\r
-}\r
-#endif\r
-\r
-/* -- INTERFACE FUNCTIONS -------------------------------------------------- */\r
-\r
-/*\r
- * Perform initialization. This usually happens on the program startup\r
- * and restarting after glutMainLoop termination...\r
- */\r
-void FGAPIENTRY glutInit( int* pargc, char** argv )\r
-{\r
-    char* displayName = NULL;\r
-    char* geometry = NULL;\r
-    int i, j, argc = *pargc;\r
-\r
-    if( fgState.Initialised )\r
-        fgError( "illegal glutInit() reinitialization attempt" );\r
-\r
-    if (pargc && *pargc && argv && *argv && **argv)\r
-    {\r
-        fgState.ProgramName = strdup (*argv);\r
-\r
-        if( !fgState.ProgramName )\r
-            fgError ("Could not allocate space for the program's name.");\r
-    }\r
-\r
-    fgCreateStructure( );\r
-\r
-    /* Get start time */\r
-    fgState.Time = fgSystemTime();\r
-\r
-    /* check if GLUT_FPS env var is set */\r
-#ifndef _WIN32_WCE\r
-    {\r
-        const char *fps = getenv( "GLUT_FPS" );\r
-\r
-        if( fps )\r
-        {\r
-            int interval;\r
-            sscanf( fps, "%d", &interval );\r
-\r
-            if( interval <= 0 )\r
-                fgState.FPSInterval = 5000;  /* 5000 millisecond default */\r
-            else\r
-                fgState.FPSInterval = interval;\r
-        }\r
-    }\r
-\r
-    displayName = getenv( "DISPLAY" );\r
-\r
-    for( i = 1; i < argc; i++ )\r
-    {\r
-        if( strcmp( argv[ i ], "-display" ) == 0 )\r
-        {\r
-            if( ++i >= argc )\r
-                fgError( "-display parameter must be followed by display name" );\r
-\r
-            displayName = argv[ i ];\r
-\r
-            argv[ i - 1 ] = NULL;\r
-            argv[ i     ] = NULL;\r
-            ( *pargc ) -= 2;\r
-        }\r
-        else if( strcmp( argv[ i ], "-geometry" ) == 0 )\r
-        {\r
-            if( ++i >= argc )\r
-                fgError( "-geometry parameter must be followed by window "\r
-                         "geometry settings" );\r
-\r
-            geometry = argv[ i ];\r
-\r
-            argv[ i - 1 ] = NULL;\r
-            argv[ i     ] = NULL;\r
-            ( *pargc ) -= 2;\r
-        }\r
-        else if( strcmp( argv[ i ], "-direct" ) == 0)\r
-        {\r
-            if( fgState.DirectContext == GLUT_FORCE_INDIRECT_CONTEXT )\r
-                fgError( "parameters ambiguity, -direct and -indirect "\r
-                    "cannot be both specified" );\r
-\r
-            fgState.DirectContext = GLUT_FORCE_DIRECT_CONTEXT;\r
-            argv[ i ] = NULL;\r
-            ( *pargc )--;\r
-        }\r
-        else if( strcmp( argv[ i ], "-indirect" ) == 0 )\r
-        {\r
-            if( fgState.DirectContext == GLUT_FORCE_DIRECT_CONTEXT )\r
-                fgError( "parameters ambiguity, -direct and -indirect "\r
-                    "cannot be both specified" );\r
-\r
-            fgState.DirectContext = GLUT_FORCE_INDIRECT_CONTEXT;\r
-            argv[ i ] = NULL;\r
-            (*pargc)--;\r
-        }\r
-        else if( strcmp( argv[ i ], "-iconic" ) == 0 )\r
-        {\r
-            fgState.ForceIconic = GL_TRUE;\r
-            argv[ i ] = NULL;\r
-            ( *pargc )--;\r
-        }\r
-        else if( strcmp( argv[ i ], "-gldebug" ) == 0 )\r
-        {\r
-            fgState.GLDebugSwitch = GL_TRUE;\r
-            argv[ i ] = NULL;\r
-            ( *pargc )--;\r
-        }\r
-        else if( strcmp( argv[ i ], "-sync" ) == 0 )\r
-        {\r
-            fgState.XSyncSwitch = GL_TRUE;\r
-            argv[ i ] = NULL;\r
-            ( *pargc )--;\r
-        }\r
-    }\r
-\r
-    /* Compact {argv}. */\r
-    for( i = j = 1; i < *pargc; i++, j++ )\r
-    {\r
-        /* Guaranteed to end because there are "*pargc" arguments left */\r
-        while ( argv[ j ] == NULL )\r
-            j++;\r
-        if ( i != j )\r
-            argv[ i ] = argv[ j ];\r
-    }\r
-\r
-#endif /* _WIN32_WCE */\r
-\r
-    /*\r
-     * Have the display created now. If there wasn't a "-display"\r
-     * in the program arguments, we will use the DISPLAY environment\r
-     * variable for opening the X display (see code above):\r
-     */\r
-    fghInitialize( displayName );\r
-\r
-    /*\r
-     * Geometry parsing deffered until here because we may need the screen\r
-     * size.\r
-     */\r
-\r
-    if (geometry )\r
-    {\r
-        unsigned int parsedWidth, parsedHeight;\r
-        int mask = XParseGeometry( geometry,\r
-                                   &fgState.Position.X, &fgState.Position.Y,\r
-                                   &parsedWidth, &parsedHeight );\r
-        /* TODO: Check for overflow? */\r
-        fgState.Size.X = parsedWidth;\r
-        fgState.Size.Y = parsedHeight;\r
-\r
-        if( (mask & (WidthValue|HeightValue)) == (WidthValue|HeightValue) )\r
-            fgState.Size.Use = GL_TRUE;\r
-\r
-        if( mask & XNegative )\r
-            fgState.Position.X += fgDisplay.ScreenWidth - fgState.Size.X;\r
-\r
-        if( mask & YNegative )\r
-            fgState.Position.Y += fgDisplay.ScreenHeight - fgState.Size.Y;\r
-\r
-        if( (mask & (XValue|YValue)) == (XValue|YValue) )\r
-            fgState.Position.Use = GL_TRUE;\r
-    }\r
-}\r
-\r
-#if TARGET_HOST_MS_WINDOWS\r
-void (__cdecl *__glutExitFunc)( int return_value ) = NULL;\r
-\r
-void FGAPIENTRY __glutInitWithExit( int *pargc, char **argv, void (__cdecl *exit_function)(int) )\r
-{\r
-  __glutExitFunc = exit_function;\r
-  glutInit(pargc, argv);\r
-}\r
-#endif\r
-\r
-/*\r
- * Undoes all the "glutInit" stuff\r
- */\r
-void FGAPIENTRY glutExit ( void )\r
-{\r
-  fgDeinitialize ();\r
-}\r
-\r
-/*\r
- * Sets the default initial window position for new windows\r
- */\r
-void FGAPIENTRY glutInitWindowPosition( int x, int y )\r
-{\r
-    fgState.Position.X = x;\r
-    fgState.Position.Y = y;\r
-\r
-    if( ( x >= 0 ) && ( y >= 0 ) )\r
-        fgState.Position.Use = GL_TRUE;\r
-    else\r
-        fgState.Position.Use = GL_FALSE;\r
-}\r
-\r
-/*\r
- * Sets the default initial window size for new windows\r
- */\r
-void FGAPIENTRY glutInitWindowSize( int width, int height )\r
-{\r
-    fgState.Size.X = width;\r
-    fgState.Size.Y = height;\r
-\r
-    if( ( width > 0 ) && ( height > 0 ) )\r
-        fgState.Size.Use = GL_TRUE;\r
-    else\r
-        fgState.Size.Use = GL_FALSE;\r
-}\r
-\r
-/*\r
- * Sets the default display mode for all new windows\r
- */\r
-void FGAPIENTRY glutInitDisplayMode( unsigned int displayMode )\r
-{\r
-    /* We will make use of this value when creating a new OpenGL context... */\r
-    fgState.DisplayMode = displayMode;\r
-}\r
-\r
-\r
-/* -- INIT DISPLAY STRING PARSING ------------------------------------------ */\r
-\r
-static char* Tokens[] =\r
-{\r
-    "alpha", "acca", "acc", "blue", "buffer", "conformant", "depth", "double",\r
-    "green", "index", "num", "red", "rgba", "rgb", "luminance", "stencil",\r
-    "single", "stereo", "samples", "slow", "win32pdf", "win32pfd", "xvisual",\r
-    "xstaticgray", "xgrayscale", "xstaticcolor", "xpseudocolor",\r
-    "xtruecolor", "xdirectcolor",\r
-    "xstaticgrey", "xgreyscale", "xstaticcolour", "xpseudocolour",\r
-    "xtruecolour", "xdirectcolour", "borderless", "aux"\r
-};\r
-#define NUM_TOKENS             (sizeof(Tokens) / sizeof(*Tokens))\r
-\r
-void FGAPIENTRY glutInitDisplayString( const char* displayMode )\r
-{\r
-    int glut_state_flag = 0 ;\r
-    /*\r
-     * Unpack a lot of options from a character string.  The options are\r
-     * delimited by blanks or tabs.\r
-     */\r
-    char *token ;\r
-    size_t len = strlen ( displayMode );\r
-    char *buffer = (char *)malloc ( (len+1) * sizeof(char) );\r
-    memcpy ( buffer, displayMode, len );\r
-    buffer[len] = '\0';\r
-\r
-    token = strtok ( buffer, " \t" );\r
-\r
-    while ( token )\r
-    {\r
-        /* Process this token */\r
-        int i ;\r
-\r
-        /* Temporary fix:  Ignore any length specifications and at least\r
-         * process the basic token\r
-         * TODO:  Fix this permanently\r
-         */\r
-        size_t cleanlength = strcspn ( token, "=<>~!" );\r
-\r
-        for ( i = 0; i < NUM_TOKENS; i++ )\r
-        {\r
-            if ( strncmp ( token, Tokens[i], cleanlength ) == 0 ) break ;\r
-        }\r
-\r
-        switch ( i )\r
-        {\r
-        case 0 :  /* "alpha":  Alpha color buffer precision in bits */\r
-            glut_state_flag |= GLUT_ALPHA ;  /* Somebody fix this for me! */\r
-            break ;\r
-\r
-        case 1 :  /* "acca":  Red, green, blue, and alpha accumulation buffer\r
-                     precision in bits */\r
-            break ;\r
-\r
-        case 2 :  /* "acc":  Red, green, and blue accumulation buffer precision\r
-                     in bits with zero bits alpha */\r
-            glut_state_flag |= GLUT_ACCUM ;  /* Somebody fix this for me! */\r
-            break ;\r
-\r
-        case 3 :  /* "blue":  Blue color buffer precision in bits */\r
-            break ;\r
-\r
-        case 4 :  /* "buffer":  Number of bits in the color index color buffer\r
-                   */\r
-            break ;\r
-\r
-        case 5 :  /* "conformant":  Boolean indicating if the frame buffer\r
-                     configuration is conformant or not */\r
-            break ;\r
-\r
-        case 6 : /* "depth":  Number of bits of precsion in the depth buffer */\r
-            glut_state_flag |= GLUT_DEPTH ;  /* Somebody fix this for me! */\r
-            break ;\r
-\r
-        case 7 :  /* "double":  Boolean indicating if the color buffer is\r
-                     double buffered */\r
-            glut_state_flag |= GLUT_DOUBLE ;\r
-            break ;\r
-\r
-        case 8 :  /* "green":  Green color buffer precision in bits */\r
-            break ;\r
-\r
-        case 9 :  /* "index":  Boolean if the color model is color index or not\r
-                   */\r
-            glut_state_flag |= GLUT_INDEX ;\r
-            break ;\r
-\r
-        case 10 :  /* "num":  A special capability  name indicating where the\r
-                      value represents the Nth frame buffer configuration\r
-                      matching the description string */\r
-            break ;\r
-\r
-        case 11 :  /* "red":  Red color buffer precision in bits */\r
-            break ;\r
-\r
-        case 12 :  /* "rgba":  Number of bits of red, green, blue, and alpha in\r
-                      the RGBA color buffer */\r
-            glut_state_flag |= GLUT_RGBA ;  /* Somebody fix this for me! */\r
-            break ;\r
-\r
-        case 13 :  /* "rgb":  Number of bits of red, green, and blue in the\r
-                      RGBA color buffer with zero bits alpha */\r
-            glut_state_flag |= GLUT_RGB ;  /* Somebody fix this for me! */\r
-            break ;\r
-\r
-        case 14 :  /* "luminance":  Number of bits of red in the RGBA and zero\r
-                      bits of green, blue (alpha not specified) of color buffer\r
-                      precision */\r
-            glut_state_flag |= GLUT_LUMINANCE ; /* Somebody fix this for me! */\r
-            break ;\r
-\r
-        case 15 :  /* "stencil":  Number of bits in the stencil buffer */\r
-            glut_state_flag |= GLUT_STENCIL;  /* Somebody fix this for me! */\r
-            break ;\r
-\r
-        case 16 :  /* "single":  Boolean indicate the color buffer is single\r
-                      buffered */\r
-            glut_state_flag |= GLUT_SINGLE ;\r
-            break ;\r
-\r
-        case 17 :  /* "stereo":  Boolean indicating the color buffer supports\r
-                      OpenGL-style stereo */\r
-            glut_state_flag |= GLUT_STEREO ;\r
-            break ;\r
-\r
-        case 18 :  /* "samples":  Indicates the number of multisamples to use\r
-                      based on GLX's SGIS_multisample extension (for\r
-                      antialiasing) */\r
-            glut_state_flag |= GLUT_MULTISAMPLE ; /*Somebody fix this for me!*/\r
-            break ;\r
-\r
-        case 19 :  /* "slow":  Boolean indicating if the frame buffer\r
-                      configuration is slow or not */\r
-            break ;\r
-\r
-        case 20 :  /* "win32pdf": (incorrect spelling but was there before */\r
-        case 21 :  /* "win32pfd":  matches the Win32 Pixel Format Descriptor by\r
-                      number */\r
-#if TARGET_HOST_MS_WINDOWS\r
-#endif\r
-            break ;\r
-\r
-        case 22 :  /* "xvisual":  matches the X visual ID by number */\r
-#if TARGET_HOST_POSIX_X11\r
-#endif\r
-            break ;\r
-\r
-        case 23 :  /* "xstaticgray": */\r
-        case 29 :  /* "xstaticgrey":  boolean indicating if the frame buffer\r
-                      configuration's X visual is of type StaticGray */\r
-#if TARGET_HOST_POSIX_X11\r
-#endif\r
-            break ;\r
-\r
-        case 24 :  /* "xgrayscale": */\r
-        case 30 :  /* "xgreyscale":  boolean indicating if the frame buffer\r
-                      configuration's X visual is of type GrayScale */\r
-#if TARGET_HOST_POSIX_X11\r
-#endif\r
-            break ;\r
-\r
-        case 25 :  /* "xstaticcolor": */\r
-        case 31 :  /* "xstaticcolour":  boolean indicating if the frame buffer\r
-                      configuration's X visual is of type StaticColor */\r
-#if TARGET_HOST_POSIX_X11\r
-#endif\r
-            break ;\r
-\r
-        case 26 :  /* "xpseudocolor": */\r
-        case 32 :  /* "xpseudocolour":  boolean indicating if the frame buffer\r
-                      configuration's X visual is of type PseudoColor */\r
-#if TARGET_HOST_POSIX_X11\r
-#endif\r
-            break ;\r
-\r
-        case 27 :  /* "xtruecolor": */\r
-        case 33 :  /* "xtruecolour":  boolean indicating if the frame buffer\r
-                      configuration's X visual is of type TrueColor */\r
-#if TARGET_HOST_POSIX_X11\r
-#endif\r
-            break ;\r
-\r
-        case 28 :  /* "xdirectcolor": */\r
-        case 34 :  /* "xdirectcolour":  boolean indicating if the frame buffer\r
-                      configuration's X visual is of type DirectColor */\r
-#if TARGET_HOST_POSIX_X11\r
-#endif\r
-            break ;\r
-\r
-        case 35 :  /* "borderless":  windows should not have borders */\r
-#if TARGET_HOST_POSIX_X11\r
-#endif\r
-            break ;\r
-\r
-        case 36 :  /* "aux":  some number of aux buffers */\r
-            glut_state_flag |= GLUT_AUX;\r
-            break ;\r
-\r
-        case 37 :  /* Unrecognized */\r
-            fgWarning ( "WARNING - Display string token not recognized:  %s",\r
-                        token );\r
-            break ;\r
-        }\r
-\r
-        token = strtok ( NULL, " \t" );\r
-    }\r
-\r
-    free ( buffer );\r
-\r
-    /* We will make use of this value when creating a new OpenGL context... */\r
-    fgState.DisplayMode = glut_state_flag;\r
-}\r
-\r
-/* -- SETTING OPENGL 3.0 CONTEXT CREATION PARAMETERS ---------------------- */\r
-\r
-void FGAPIENTRY glutInitContextVersion( int majorVersion, int minorVersion )\r
-{\r
-    /* We will make use of these valuse when creating a new OpenGL context... */\r
-    fgState.MajorVersion = majorVersion;\r
-    fgState.MinorVersion = minorVersion;\r
-}\r
-\r
-\r
-void FGAPIENTRY glutInitContextFlags( int flags )\r
-{\r
-    /* We will make use of this value when creating a new OpenGL context... */\r
-    fgState.ContextFlags = flags;\r
-}\r
-\r
-void FGAPIENTRY glutInitContextProfile( int profile )\r
-{\r
-    /* We will make use of this value when creating a new OpenGL context... */\r
-    fgState.ContextProfile = profile;\r
-}\r
-\r
-/* -------------- User Defined Error/Warning Handler Support -------------- */\r
-\r
-/*\r
- * Sets the user error handler (note the use of va_list for the args to the fmt)\r
- */\r
-void FGAPIENTRY glutInitErrorFunc( void (* vfgError) ( const char *fmt, va_list ap ) )\r
-{\r
-    /* This allows user programs to handle freeglut errors */\r
-    fgState.ErrorFunc = vfgError;\r
-}\r
-\r
-/*\r
- * Sets the user warning handler (note the use of va_list for the args to the fmt)\r
- */\r
-void FGAPIENTRY glutInitWarningFunc( void (* vfgWarning) ( const char *fmt, va_list ap ) )\r
-{\r
-    /* This allows user programs to handle freeglut warnings */\r
-    fgState.WarningFunc = vfgWarning;\r
-}\r
-\r
-/*** END OF FILE ***/\r
+/*
+ * freeglut_init.c
+ *
+ * Various freeglut initialization functions.
+ *
+ * Copyright (c) 1999-2000 Pawel W. Olszta. All Rights Reserved.
+ * Written by Pawel W. Olszta, <olszta@sourceforge.net>
+ * Creation date: Thu Dec 2 1999
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * 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
+ * PAWEL W. OLSZTA 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.
+ */
+
+#define FREEGLUT_BUILDING_LIB
+#include <GL/freeglut.h>
+#include "freeglut_internal.h"
+
+/*
+ * TODO BEFORE THE STABLE RELEASE:
+ *
+ *  fgDeinitialize()        -- Win32's OK, X11 needs the OS-specific
+ *                             deinitialization done
+ *  glutInitDisplayString() -- display mode string parsing
+ *
+ * Wouldn't it be cool to use gettext() for error messages? I just love
+ * bash saying  "nie znaleziono pliku" instead of "file not found" :)
+ * Is gettext easily portable?
+ */
+
+/* -- GLOBAL VARIABLES ----------------------------------------------------- */
+
+/*
+ * A structure pointed by fgDisplay holds all information
+ * regarding the display, screen, root window etc.
+ */
+SFG_Display fgDisplay;
+
+/*
+ * The settings for the current freeglut session
+ */
+SFG_State fgState = { { -1, -1, GL_FALSE },  /* Position */
+                      { 300, 300, GL_TRUE }, /* Size */
+                      GLUT_RGBA | GLUT_SINGLE | GLUT_DEPTH,  /* DisplayMode */
+                      GL_FALSE,              /* Initialised */
+                      GLUT_TRY_DIRECT_CONTEXT,  /* DirectContext */
+                      GL_FALSE,              /* ForceIconic */
+                      GL_FALSE,              /* UseCurrentContext */
+                      GL_FALSE,              /* GLDebugSwitch */
+                      GL_FALSE,              /* XSyncSwitch */
+                      GLUT_KEY_REPEAT_ON,    /* KeyRepeat */
+                      INVALID_MODIFIERS,     /* Modifiers */
+                      0,                     /* FPSInterval */
+                      0,                     /* SwapCount */
+                      0,                     /* SwapTime */
+                      0,                     /* Time */
+                      { NULL, NULL },         /* Timers */
+                      { NULL, NULL },         /* FreeTimers */
+                      NULL,                   /* IdleCallback */
+                      0,                      /* ActiveMenus */
+                      NULL,                   /* MenuStateCallback */
+                      NULL,                   /* MenuStatusCallback */
+                      { -1, -1, GL_TRUE },    /* GameModeSize */
+                      -1,                     /* GameModeDepth */
+                      -1,                     /* GameModeRefresh */
+                      GLUT_ACTION_EXIT,       /* ActionOnWindowClose */
+                      GLUT_EXEC_STATE_INIT,   /* ExecState */
+                      NULL,                   /* ProgramName */
+                      GL_FALSE,               /* JoysticksInitialised */
+                      0,                      /* NumActiveJoysticks */
+                      GL_FALSE,               /* InputDevsInitialised */
+                      0,                      /* MouseWheelTicks */
+                      1,                      /* AuxiliaryBufferNumber */
+                      4,                      /* SampleNumber */
+                      1,                      /* MajorVersion */
+                      0,                      /* MinorVersion */
+                      0,                      /* ContextFlags */
+                      0,                      /* ContextProfile */
+                      NULL,                   /* ErrorFunc */
+                      NULL                    /* WarningFunc */
+};
+
+
+/* -- PRIVATE FUNCTIONS ---------------------------------------------------- */
+
+extern void fgPlatformInitialize( const char* displayName );
+extern void fgPlatformDeinitialiseInputDevices ( void );
+extern void fgPlatformCloseDisplay ( void );
+extern void fgPlatformDestroyContext ( SFG_PlatformDisplay pDisplay, SFG_WindowContextType MContext );
+
+
+void fghParseCommandLineArguments ( int* pargc, char** argv, char **pDisplayName, char **pGeometry )
+{
+#ifndef _WIN32_WCE
+    int i, j, argc = *pargc;
+
+    {
+           /* check if GLUT_FPS env var is set */
+        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;
+        }
+    }
+
+    *pDisplayName = 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" );
+
+            *pDisplayName = 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" );
+
+            *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 )--;
+        }
+    }
+
+    /* 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( );
+}
+
+
+/*
+ * Perform the freeglut deinitialization...
+ */
+void fgDeinitialize( void )
+{
+    SFG_Timer *timer;
+
+    if( !fgState.Initialised )
+    {
+        return;
+    }
+
+       /* If we're in game mode, we want to leave game mode */
+    if( fgStructure.GameModeWindow ) {
+        glutLeaveGameMode();
+    }
+
+    /* If there was a menu created, destroy the rendering context */
+    if( fgStructure.MenuContext )
+    {
+               fgPlatformDestroyContext (fgDisplay.pDisplay, fgStructure.MenuContext->MContext );
+        free( fgStructure.MenuContext );
+        fgStructure.MenuContext = NULL;
+    }
+
+    fgDestroyStructure( );
+
+    while( ( timer = fgState.Timers.First) )
+    {
+        fgListRemove( &fgState.Timers, &timer->Node );
+        free( timer );
+    }
+
+    while( ( timer = fgState.FreeTimers.First) )
+    {
+        fgListRemove( &fgState.FreeTimers, &timer->Node );
+        free( timer );
+    }
+
+       fgPlatformDeinitialiseInputDevices ();
+
+       fgState.MouseWheelTicks = 0;
+
+    fgState.MajorVersion = 1;
+    fgState.MinorVersion = 0;
+    fgState.ContextFlags = 0;
+    fgState.ContextProfile = 0;
+
+    fgState.Initialised = GL_FALSE;
+
+    fgState.Position.X = -1;
+    fgState.Position.Y = -1;
+    fgState.Position.Use = GL_FALSE;
+
+    fgState.Size.X = 300;
+    fgState.Size.Y = 300;
+    fgState.Size.Use = GL_TRUE;
+
+    fgState.DisplayMode = GLUT_RGBA | GLUT_SINGLE | GLUT_DEPTH;
+
+    fgState.DirectContext  = GLUT_TRY_DIRECT_CONTEXT;
+    fgState.ForceIconic         = GL_FALSE;
+    fgState.UseCurrentContext   = GL_FALSE;
+    fgState.GLDebugSwitch       = GL_FALSE;
+    fgState.XSyncSwitch         = GL_FALSE;
+    fgState.ActionOnWindowClose = GLUT_ACTION_EXIT;
+    fgState.ExecState           = GLUT_EXEC_STATE_INIT;
+
+    fgState.KeyRepeat       = GLUT_KEY_REPEAT_ON;
+    fgState.Modifiers       = INVALID_MODIFIERS;
+
+    fgState.GameModeSize.X  = -1;
+    fgState.GameModeSize.Y  = -1;
+    fgState.GameModeDepth   = -1;
+    fgState.GameModeRefresh = -1;
+
+    fgListInit( &fgState.Timers );
+    fgListInit( &fgState.FreeTimers );
+
+    fgState.IdleCallback = NULL;
+    fgState.MenuStateCallback = ( FGCBMenuState )NULL;
+    fgState.MenuStatusCallback = ( FGCBMenuStatus )NULL;
+
+    fgState.SwapCount   = 0;
+    fgState.SwapTime    = 0;
+    fgState.FPSInterval = 0;
+
+    if( fgState.ProgramName )
+    {
+        free( fgState.ProgramName );
+        fgState.ProgramName = NULL;
+    }
+
+       fgPlatformCloseDisplay ();
+
+    fgState.Initialised = GL_FALSE;
+}
+
+
+/* -- INTERFACE FUNCTIONS -------------------------------------------------- */
+#if !TARGET_HOST_POSIX_X11
+#   include "../Common/xparsegeometry_repl.h"
+#endif
+
+/*
+ * Perform initialization. This usually happens on the program startup
+ * and restarting after glutMainLoop termination...
+ */
+void FGAPIENTRY glutInit( int* pargc, char** argv )
+{
+    char* displayName = NULL;
+    char* geometry = NULL;
+    if( fgState.Initialised )
+        fgError( "illegal glutInit() reinitialization attempt" );
+
+    if (pargc && *pargc && argv && *argv && **argv)
+    {
+        fgState.ProgramName = strdup (*argv);
+
+        if( !fgState.ProgramName )
+            fgError ("Could not allocate space for the program's name.");
+    }
+
+    fgCreateStructure( );
+
+    /* Get start time */
+    fgState.Time = fgSystemTime();
+
+       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):
+     */
+    fgPlatformInitialize( displayName );
+
+    /*
+     * Geometry parsing deferred until here because we may need the screen
+     * size.
+     */
+
+    if (geometry )
+    {
+        unsigned int parsedWidth, parsedHeight;
+        int mask = XParseGeometry( geometry,
+                                   &fgState.Position.X, &fgState.Position.Y,
+                                   &parsedWidth, &parsedHeight );
+        /* TODO: Check for overflow? */
+        fgState.Size.X = parsedWidth;
+        fgState.Size.Y = parsedHeight;
+
+        if( (mask & (WidthValue|HeightValue)) == (WidthValue|HeightValue) )
+            fgState.Size.Use = GL_TRUE;
+
+        if( mask & XNegative )
+            fgState.Position.X += fgDisplay.ScreenWidth - fgState.Size.X;
+
+        if( mask & YNegative )
+            fgState.Position.Y += fgDisplay.ScreenHeight - fgState.Size.Y;
+
+        if( (mask & (XValue|YValue)) == (XValue|YValue) )
+            fgState.Position.Use = GL_TRUE;
+    }
+}
+
+/*
+ * Undoes all the "glutInit" stuff
+ */
+void FGAPIENTRY glutExit ( void )
+{
+  fgDeinitialize ();
+}
+
+/*
+ * Sets the default initial window position for new windows
+ */
+void FGAPIENTRY glutInitWindowPosition( int x, int y )
+{
+    fgState.Position.X = x;
+    fgState.Position.Y = y;
+
+    if( ( x >= 0 ) && ( y >= 0 ) )
+        fgState.Position.Use = GL_TRUE;
+    else
+        fgState.Position.Use = GL_FALSE;
+}
+
+/*
+ * Sets the default initial window size for new windows
+ */
+void FGAPIENTRY glutInitWindowSize( int width, int height )
+{
+    fgState.Size.X = width;
+    fgState.Size.Y = height;
+
+    if( ( width > 0 ) && ( height > 0 ) )
+        fgState.Size.Use = GL_TRUE;
+    else
+        fgState.Size.Use = GL_FALSE;
+}
+
+/*
+ * Sets the default display mode for all new windows
+ */
+void FGAPIENTRY glutInitDisplayMode( unsigned int displayMode )
+{
+    /* We will make use of this value when creating a new OpenGL context... */
+    fgState.DisplayMode = displayMode;
+}
+
+
+/* -- INIT DISPLAY STRING PARSING ------------------------------------------ */
+
+static char* Tokens[] =
+{
+    "alpha", "acca", "acc", "blue", "buffer", "conformant", "depth", "double",
+    "green", "index", "num", "red", "rgba", "rgb", "luminance", "stencil",
+    "single", "stereo", "samples", "slow", "win32pdf", "win32pfd", "xvisual",
+    "xstaticgray", "xgrayscale", "xstaticcolor", "xpseudocolor",
+    "xtruecolor", "xdirectcolor",
+    "xstaticgrey", "xgreyscale", "xstaticcolour", "xpseudocolour",
+    "xtruecolour", "xdirectcolour", "borderless", "aux"
+};
+#define NUM_TOKENS             (sizeof(Tokens) / sizeof(*Tokens))
+
+void FGAPIENTRY glutInitDisplayString( const char* displayMode )
+{
+    int glut_state_flag = 0 ;
+    /*
+     * Unpack a lot of options from a character string.  The options are
+     * delimited by blanks or tabs.
+     */
+    char *token ;
+    size_t len = strlen ( displayMode );
+    char *buffer = (char *)malloc ( (len+1) * sizeof(char) );
+    memcpy ( buffer, displayMode, len );
+    buffer[len] = '\0';
+
+    token = strtok ( buffer, " \t" );
+
+    while ( token )
+    {
+        /* Process this token */
+        int i ;
+
+        /* Temporary fix:  Ignore any length specifications and at least
+         * process the basic token
+         * TODO:  Fix this permanently
+         */
+        size_t cleanlength = strcspn ( token, "=<>~!" );
+
+        for ( i = 0; i < NUM_TOKENS; i++ )
+        {
+            if ( strncmp ( token, Tokens[i], cleanlength ) == 0 ) break ;
+        }
+
+        switch ( i )
+        {
+        case 0 :  /* "alpha":  Alpha color buffer precision in bits */
+            glut_state_flag |= GLUT_ALPHA ;  /* Somebody fix this for me! */
+            break ;
+
+        case 1 :  /* "acca":  Red, green, blue, and alpha accumulation buffer
+                     precision in bits */
+            break ;
+
+        case 2 :  /* "acc":  Red, green, and blue accumulation buffer precision
+                     in bits with zero bits alpha */
+            glut_state_flag |= GLUT_ACCUM ;  /* Somebody fix this for me! */
+            break ;
+
+        case 3 :  /* "blue":  Blue color buffer precision in bits */
+            break ;
+
+        case 4 :  /* "buffer":  Number of bits in the color index color buffer
+                   */
+            break ;
+
+        case 5 :  /* "conformant":  Boolean indicating if the frame buffer
+                     configuration is conformant or not */
+            break ;
+
+        case 6 : /* "depth":  Number of bits of precision in the depth buffer */
+            glut_state_flag |= GLUT_DEPTH ;  /* Somebody fix this for me! */
+            break ;
+
+        case 7 :  /* "double":  Boolean indicating if the color buffer is
+                     double buffered */
+            glut_state_flag |= GLUT_DOUBLE ;
+            break ;
+
+        case 8 :  /* "green":  Green color buffer precision in bits */
+            break ;
+
+        case 9 :  /* "index":  Boolean if the color model is color index or not
+                   */
+            glut_state_flag |= GLUT_INDEX ;
+            break ;
+
+        case 10 :  /* "num":  A special capability  name indicating where the
+                      value represents the Nth frame buffer configuration
+                      matching the description string */
+            break ;
+
+        case 11 :  /* "red":  Red color buffer precision in bits */
+            break ;
+
+        case 12 :  /* "rgba":  Number of bits of red, green, blue, and alpha in
+                      the RGBA color buffer */
+            glut_state_flag |= GLUT_RGBA ;  /* Somebody fix this for me! */
+            break ;
+
+        case 13 :  /* "rgb":  Number of bits of red, green, and blue in the
+                      RGBA color buffer with zero bits alpha */
+            glut_state_flag |= GLUT_RGB ;  /* Somebody fix this for me! */
+            break ;
+
+        case 14 :  /* "luminance":  Number of bits of red in the RGBA and zero
+                      bits of green, blue (alpha not specified) of color buffer
+                      precision */
+            glut_state_flag |= GLUT_LUMINANCE ; /* Somebody fix this for me! */
+            break ;
+
+        case 15 :  /* "stencil":  Number of bits in the stencil buffer */
+            glut_state_flag |= GLUT_STENCIL;  /* Somebody fix this for me! */
+            break ;
+
+        case 16 :  /* "single":  Boolean indicate the color buffer is single
+                      buffered */
+            glut_state_flag |= GLUT_SINGLE ;
+            break ;
+
+        case 17 :  /* "stereo":  Boolean indicating the color buffer supports
+                      OpenGL-style stereo */
+            glut_state_flag |= GLUT_STEREO ;
+            break ;
+
+        case 18 :  /* "samples":  Indicates the number of multisamples to use
+                      based on GLX's SGIS_multisample extension (for
+                      antialiasing) */
+            glut_state_flag |= GLUT_MULTISAMPLE ; /*Somebody fix this for me!*/
+            break ;
+
+        case 19 :  /* "slow":  Boolean indicating if the frame buffer
+                      configuration is slow or not */
+            break ;
+
+        case 20 :  /* "win32pdf": (incorrect spelling but was there before */
+        case 21 :  /* "win32pfd":  matches the Win32 Pixel Format Descriptor by
+                      number */
+#if TARGET_HOST_MS_WINDOWS
+#endif
+            break ;
+
+        case 22 :  /* "xvisual":  matches the X visual ID by number */
+#if TARGET_HOST_POSIX_X11
+#endif
+            break ;
+
+        case 23 :  /* "xstaticgray": */
+        case 29 :  /* "xstaticgrey":  boolean indicating if the frame buffer
+                      configuration's X visual is of type StaticGray */
+#if TARGET_HOST_POSIX_X11
+#endif
+            break ;
+
+        case 24 :  /* "xgrayscale": */
+        case 30 :  /* "xgreyscale":  boolean indicating if the frame buffer
+                      configuration's X visual is of type GrayScale */
+#if TARGET_HOST_POSIX_X11
+#endif
+            break ;
+
+        case 25 :  /* "xstaticcolor": */
+        case 31 :  /* "xstaticcolour":  boolean indicating if the frame buffer
+                      configuration's X visual is of type StaticColor */
+#if TARGET_HOST_POSIX_X11
+#endif
+            break ;
+
+        case 26 :  /* "xpseudocolor": */
+        case 32 :  /* "xpseudocolour":  boolean indicating if the frame buffer
+                      configuration's X visual is of type PseudoColor */
+#if TARGET_HOST_POSIX_X11
+#endif
+            break ;
+
+        case 27 :  /* "xtruecolor": */
+        case 33 :  /* "xtruecolour":  boolean indicating if the frame buffer
+                      configuration's X visual is of type TrueColor */
+#if TARGET_HOST_POSIX_X11
+#endif
+            break ;
+
+        case 28 :  /* "xdirectcolor": */
+        case 34 :  /* "xdirectcolour":  boolean indicating if the frame buffer
+                      configuration's X visual is of type DirectColor */
+#if TARGET_HOST_POSIX_X11
+#endif
+            break ;
+
+        case 35 :  /* "borderless":  windows should not have borders */
+            glut_state_flag |= GLUT_BORDERLESS;
+            break ;
+
+        case 36 :  /* "aux":  some number of aux buffers */
+            glut_state_flag |= GLUT_AUX;
+            break ;
+
+        case 37 :  /* Unrecognized */
+            fgWarning ( "WARNING - Display string token not recognized:  %s",
+                        token );
+            break ;
+        }
+
+        token = strtok ( NULL, " \t" );
+    }
+
+    free ( buffer );
+
+    /* We will make use of this value when creating a new OpenGL context... */
+    fgState.DisplayMode = glut_state_flag;
+}
+
+/* -- SETTING OPENGL 3.0 CONTEXT CREATION PARAMETERS ---------------------- */
+
+void FGAPIENTRY glutInitContextVersion( int majorVersion, int minorVersion )
+{
+    /* We will make use of these value when creating a new OpenGL context... */
+    fgState.MajorVersion = majorVersion;
+    fgState.MinorVersion = minorVersion;
+}
+
+
+void FGAPIENTRY glutInitContextFlags( int flags )
+{
+    /* We will make use of this value when creating a new OpenGL context... */
+    fgState.ContextFlags = flags;
+}
+
+void FGAPIENTRY glutInitContextProfile( int profile )
+{
+    /* We will make use of this value when creating a new OpenGL context... */
+    fgState.ContextProfile = profile;
+}
+
+/* -------------- User Defined Error/Warning Handler Support -------------- */
+
+/*
+ * Sets the user error handler (note the use of va_list for the args to the fmt)
+ */
+void FGAPIENTRY glutInitErrorFunc( void (* vfgError) ( const char *fmt, va_list ap ) )
+{
+    /* This allows user programs to handle freeglut errors */
+    fgState.ErrorFunc = vfgError;
+}
+
+/*
+ * Sets the user warning handler (note the use of va_list for the args to the fmt)
+ */
+void FGAPIENTRY glutInitWarningFunc( void (* vfgWarning) ( const char *fmt, va_list ap ) )
+{
+    /* This allows user programs to handle freeglut warnings */
+    fgState.WarningFunc = vfgWarning;
+}
+
+/*** END OF FILE ***/
\ No newline at end of file