4 * Various freeglut initialization functions.
6 * Copyright (c) 1999-2000 Pawel W. Olszta. All Rights Reserved.
7 * Written by Pawel W. Olszta, <olszta@sourceforge.net>
8 * Creation date: Thu Dec 2 1999
10 * Permission is hereby granted, free of charge, to any person obtaining a
11 * copy of this software and associated documentation files (the "Software"),
12 * to deal in the Software without restriction, including without limitation
13 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
14 * and/or sell copies of the Software, and to permit persons to whom the
15 * Software is furnished to do so, subject to the following conditions:
17 * The above copyright notice and this permission notice shall be included
18 * in all copies or substantial portions of the Software.
20 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
21 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
22 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
23 * PAWEL W. OLSZTA BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
24 * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
25 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
28 #define FREEGLUT_BUILDING_LIB
29 #include <GL/freeglut.h>
30 #include "freeglut_internal.h"
32 #if TARGET_HOST_POSIX_X11
33 #include <limits.h> /* LONG_MAX */
37 * TODO BEFORE THE STABLE RELEASE:
39 * fgDeinitialize() -- Win32's OK, X11 needs the OS-specific
40 * deinitialization done
41 * glutInitDisplayString() -- display mode string parsing
43 * Wouldn't it be cool to use gettext() for error messages? I just love
44 * bash saying "nie znaleziono pliku" instead of "file not found" :)
45 * Is gettext easily portable?
48 /* -- GLOBAL VARIABLES ----------------------------------------------------- */
51 * A structure pointed by g_pDisplay holds all information
52 * regarding the display, screen, root window etc.
54 SFG_Display fgDisplay;
57 * The settings for the current freeglut session
59 SFG_State fgState = { { -1, -1, GL_FALSE }, /* Position */
60 { 300, 300, GL_TRUE }, /* Size */
61 GLUT_RGBA | GLUT_SINGLE | GLUT_DEPTH, /* DisplayMode */
62 GL_FALSE, /* Initialised */
63 GLUT_TRY_DIRECT_CONTEXT, /* DirectContext */
64 GL_FALSE, /* ForceIconic */
65 GL_FALSE, /* UseCurrentContext */
66 GL_FALSE, /* GLDebugSwitch */
67 GL_FALSE, /* XSyncSwitch */
68 GLUT_KEY_REPEAT_ON, /* KeyRepeat */
69 INVALID_MODIFIERS, /* Modifiers */
74 { NULL, NULL }, /* Timers */
75 { NULL, NULL }, /* FreeTimers */
76 NULL, /* IdleCallback */
78 NULL, /* MenuStateCallback */
79 NULL, /* MenuStatusCallback */
80 { 640, 480, GL_TRUE }, /* GameModeSize */
81 16, /* GameModeDepth */
82 72, /* GameModeRefresh */
83 GLUT_ACTION_EXIT, /* ActionOnWindowClose */
84 GLUT_EXEC_STATE_INIT, /* ExecState */
85 NULL, /* ProgramName */
86 GL_FALSE, /* JoysticksInitialised */
87 GL_FALSE, /* InputDevsInitialised */
88 1, /* AuxiliaryBufferNumber */
96 /* -- PRIVATE FUNCTIONS ---------------------------------------------------- */
98 #if TARGET_HOST_POSIX_X11
100 /* Return the atom associated with "name". */
101 static Atom fghGetAtom(const char * name)
103 return XInternAtom(fgDisplay.Display, name, False);
107 * Check if "property" is set on "window". The property's values are returned
108 * through "data". If the property is set and is of type "type", return the
109 * number of elements in "data". Return zero otherwise. In both cases, use
110 * "Xfree()" to free "data".
112 static int fghGetWindowProperty(Window window,
115 unsigned char ** data)
118 * Caller always has to use "Xfree()" to free "data", since
119 * "XGetWindowProperty() always allocates one extra byte in prop_return
120 * [i.e. "data"] (even if the property is zero length) [..]".
123 int status; /* Returned by "XGetWindowProperty". */
126 int temp_format; /* Not used. */
127 unsigned long number_of_elements;
128 unsigned long temp_bytes_after; /* Not used. */
131 status = XGetWindowProperty(fgDisplay.Display,
144 FREEGLUT_INTERNAL_ERROR_EXIT(status == Success,
145 "XGetWindowProperty failled",
146 "fghGetWindowProperty");
148 if (type_returned != type)
150 number_of_elements = 0;
153 return number_of_elements;
156 /* Check if the window manager is NET WM compliant. */
157 static int fghNetWMSupported(void)
160 Window ** window_ptr_1;
162 int number_of_windows;
163 int net_wm_supported;
166 net_wm_supported = 0;
168 wm_check = fghGetAtom("_NET_SUPPORTING_WM_CHECK");
169 window_ptr_1 = malloc(sizeof(Window *));
172 * Check that the window manager has set this property on the root window.
173 * The property must be the ID of a child window.
175 number_of_windows = fghGetWindowProperty(fgDisplay.RootWindow,
178 (unsigned char **) window_ptr_1);
179 if (number_of_windows == 1)
181 Window ** window_ptr_2;
183 window_ptr_2 = malloc(sizeof(Window *));
185 /* Check that the window has the same property set to the same value. */
186 number_of_windows = fghGetWindowProperty(**window_ptr_1,
189 (unsigned char **) window_ptr_2);
190 if ((number_of_windows == 1) && (**window_ptr_1 == **window_ptr_2))
192 /* NET WM compliant */
193 net_wm_supported = 1;
196 XFree(*window_ptr_2);
200 XFree(*window_ptr_1);
203 return net_wm_supported;
206 /* Check if "hint" is present in "property" for "window". */
207 int fgHintPresent(Window window, Atom property, Atom hint)
216 atoms_ptr = malloc(sizeof(Atom *));
217 number_of_atoms = fghGetWindowProperty(window,
220 (unsigned char **) atoms_ptr);
221 for (i = 0; i < number_of_atoms; i++)
223 if ((*atoms_ptr)[i] == hint)
233 #endif /* TARGET_HOST_POSIX_X11 */
237 * A call to this function should initialize all the display stuff...
239 static void fghInitialize( const char* displayName )
241 #if TARGET_HOST_POSIX_X11
242 fgDisplay.Display = XOpenDisplay( displayName );
244 if( fgDisplay.Display == NULL )
245 fgError( "failed to open display '%s'", XDisplayName( displayName ) );
247 if( !glXQueryExtension( fgDisplay.Display, NULL, NULL ) )
248 fgError( "OpenGL GLX extension not supported by display '%s'",
249 XDisplayName( displayName ) );
251 fgDisplay.Screen = DefaultScreen( fgDisplay.Display );
252 fgDisplay.RootWindow = RootWindow(
257 fgDisplay.ScreenWidth = DisplayWidth(
261 fgDisplay.ScreenHeight = DisplayHeight(
266 fgDisplay.ScreenWidthMM = DisplayWidthMM(
270 fgDisplay.ScreenHeightMM = DisplayHeightMM(
275 fgDisplay.Connection = ConnectionNumber( fgDisplay.Display );
277 /* Create the window deletion atom */
278 fgDisplay.DeleteWindow = fghGetAtom("WM_DELETE_WINDOW");
280 /* Create the state and full screen atoms */
281 fgDisplay.State = None;
282 fgDisplay.StateFullScreen = None;
284 if (fghNetWMSupported())
286 const Atom supported = fghGetAtom("_NET_SUPPORTED");
287 const Atom state = fghGetAtom("_NET_WM_STATE");
289 /* Check if the state hint is supported. */
290 if (fgHintPresent(fgDisplay.RootWindow, supported, state))
292 const Atom full_screen = fghGetAtom("_NET_WM_STATE_FULLSCREEN");
294 fgDisplay.State = state;
296 /* Check if the window manager supports full screen. */
297 /** Check "_NET_WM_ALLOWED_ACTIONS" on our window instead? **/
298 if (fgHintPresent(fgDisplay.RootWindow, supported, full_screen))
300 fgDisplay.StateFullScreen = full_screen;
305 #elif TARGET_HOST_MS_WINDOWS
310 /* What we need to do is to initialize the fgDisplay global structure here. */
311 fgDisplay.Instance = GetModuleHandle( NULL );
313 atom = GetClassInfo( fgDisplay.Instance, _T("FREEGLUT"), &wc );
317 ZeroMemory( &wc, sizeof(WNDCLASS) );
320 * Each of the windows should have its own device context, and we
321 * want redraw events during Vertical and Horizontal Resizes by
324 * XXX Old code had "| CS_DBCLCKS" commented out. Plans for the
325 * XXX future? Dead-end idea?
327 wc.lpfnWndProc = fgWindowProc;
330 wc.hInstance = fgDisplay.Instance;
331 wc.hIcon = LoadIcon( fgDisplay.Instance, _T("GLUT_ICON") );
333 #if defined(_WIN32_WCE)
334 wc.style = CS_HREDRAW | CS_VREDRAW;
336 wc.style = CS_OWNDC | CS_HREDRAW | CS_VREDRAW;
338 wc.hIcon = LoadIcon( NULL, IDI_WINLOGO );
341 wc.hCursor = LoadCursor( NULL, IDC_ARROW );
342 wc.hbrBackground = NULL;
343 wc.lpszMenuName = NULL;
344 wc.lpszClassName = _T("FREEGLUT");
346 /* Register the window class */
347 atom = RegisterClass( &wc );
348 FREEGLUT_INTERNAL_ERROR_EXIT ( atom, "Window Class Not Registered", "fghInitialize" );
351 /* The screen dimensions can be obtained via GetSystemMetrics() calls */
352 fgDisplay.ScreenWidth = GetSystemMetrics( SM_CXSCREEN );
353 fgDisplay.ScreenHeight = GetSystemMetrics( SM_CYSCREEN );
356 HWND desktop = GetDesktopWindow( );
357 HDC context = GetDC( desktop );
359 fgDisplay.ScreenWidthMM = GetDeviceCaps( context, HORZSIZE );
360 fgDisplay.ScreenHeightMM = GetDeviceCaps( context, VERTSIZE );
362 ReleaseDC( desktop, context );
365 /* Set the timer granularity to 1 ms */
366 timeBeginPeriod ( 1 );
370 fgState.Initialised = GL_TRUE;
372 /* InputDevice uses GlutTimerFunc(), so fgState.Initialised must be TRUE */
373 fgInitialiseInputDevices();
377 * Perform the freeglut deinitialization...
379 void fgDeinitialize( void )
383 if( !fgState.Initialised )
385 fgWarning( "fgDeinitialize(): "
386 "no valid initialization has been performed" );
390 /* If there was a menu created, destroy the rendering context */
391 if( fgStructure.MenuContext )
393 #if TARGET_HOST_POSIX_X11
394 /* Note that the MVisualInfo is not owned by the MenuContext! */
395 glXDestroyContext( fgDisplay.Display, fgStructure.MenuContext->MContext );
397 free( fgStructure.MenuContext );
398 fgStructure.MenuContext = NULL;
401 fgDestroyStructure( );
403 while( ( timer = fgState.Timers.First) )
405 fgListRemove( &fgState.Timers, &timer->Node );
409 while( ( timer = fgState.FreeTimers.First) )
411 fgListRemove( &fgState.FreeTimers, &timer->Node );
415 #if !defined(_WIN32_WCE)
416 if ( fgState.JoysticksInitialised )
419 if ( fgState.InputDevsInitialised )
420 fgInputDeviceClose( );
421 #endif /* !defined(_WIN32_WCE) */
422 fgState.JoysticksInitialised = GL_FALSE;
423 fgState.InputDevsInitialised = GL_FALSE;
425 fgState.MajorVersion = 1;
426 fgState.MinorVersion = 0;
427 fgState.ContextFlags = 0;
429 fgState.Initialised = GL_FALSE;
431 fgState.Position.X = -1;
432 fgState.Position.Y = -1;
433 fgState.Position.Use = GL_FALSE;
435 fgState.Size.X = 300;
436 fgState.Size.Y = 300;
437 fgState.Size.Use = GL_TRUE;
439 fgState.DisplayMode = GLUT_RGBA | GLUT_SINGLE | GLUT_DEPTH;
441 fgState.DirectContext = GLUT_TRY_DIRECT_CONTEXT;
442 fgState.ForceIconic = GL_FALSE;
443 fgState.UseCurrentContext = GL_FALSE;
444 fgState.GLDebugSwitch = GL_FALSE;
445 fgState.XSyncSwitch = GL_FALSE;
446 fgState.ActionOnWindowClose = GLUT_ACTION_EXIT;
447 fgState.ExecState = GLUT_EXEC_STATE_INIT;
449 fgState.KeyRepeat = GLUT_KEY_REPEAT_ON;
450 fgState.Modifiers = INVALID_MODIFIERS;
452 fgState.GameModeSize.X = 640;
453 fgState.GameModeSize.Y = 480;
454 fgState.GameModeDepth = 16;
455 fgState.GameModeRefresh = 72;
457 fgListInit( &fgState.Timers );
458 fgListInit( &fgState.FreeTimers );
460 fgState.IdleCallback = NULL;
461 fgState.MenuStateCallback = ( FGCBMenuState )NULL;
462 fgState.MenuStatusCallback = ( FGCBMenuStatus )NULL;
464 fgState.SwapCount = 0;
465 fgState.SwapTime = 0;
466 fgState.FPSInterval = 0;
468 if( fgState.ProgramName )
470 free( fgState.ProgramName );
471 fgState.ProgramName = NULL;
474 #if TARGET_HOST_POSIX_X11
477 * Make sure all X-client data we have created will be destroyed on
480 XSetCloseDownMode( fgDisplay.Display, DestroyAll );
483 * Close the display connection, destroying all windows we have
486 XCloseDisplay( fgDisplay.Display );
488 #elif TARGET_HOST_MS_WINDOWS
490 /* Reset the timer granularity */
495 fgState.Initialised = GL_FALSE;
499 * Everything inside the following #ifndef is copied from the X sources.
502 #if TARGET_HOST_MS_WINDOWS
506 Copyright 1985, 1986, 1987,1998 The Open Group
508 Permission to use, copy, modify, distribute, and sell this software and its
509 documentation for any purpose is hereby granted without fee, provided that
510 the above copyright notice appear in all copies and that both that
511 copyright notice and this permission notice appear in supporting
514 The above copyright notice and this permission notice shall be included
515 in all copies or substantial portions of the Software.
517 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
518 OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
519 MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
520 IN NO EVENT SHALL THE OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR
521 OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
522 ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
523 OTHER DEALINGS IN THE SOFTWARE.
525 Except as contained in this notice, the name of The Open Group shall
526 not be used in advertising or otherwise to promote the sale, use or
527 other dealings in this Software without prior written authorization
532 #define NoValue 0x0000
533 #define XValue 0x0001
534 #define YValue 0x0002
535 #define WidthValue 0x0004
536 #define HeightValue 0x0008
537 #define AllValues 0x000F
538 #define XNegative 0x0010
539 #define YNegative 0x0020
542 * XParseGeometry parses strings of the form
543 * "=<width>x<height>{+-}<xoffset>{+-}<yoffset>", where
544 * width, height, xoffset, and yoffset are unsigned integers.
545 * Example: "=80x24+300-49"
546 * The equal sign is optional.
547 * It returns a bitmask that indicates which of the four values
548 * were actually found in the string. For each value found,
549 * the corresponding argument is updated; for each value
550 * not found, the corresponding argument is left unchanged.
554 ReadInteger(char *string, char **NextString)
556 register int Result = 0;
561 else if (*string == '-')
566 for (; (*string >= '0') && (*string <= '9'); string++)
568 Result = (Result * 10) + (*string - '0');
570 *NextString = string;
577 static int XParseGeometry (
581 unsigned int *width, /* RETURN */
582 unsigned int *height) /* RETURN */
585 register char *strind;
586 unsigned int tempWidth = 0, tempHeight = 0;
587 int tempX = 0, tempY = 0;
590 if ( (string == NULL) || (*string == '\0'))
593 string++; /* ignore possible '=' at beg of geometry spec */
595 strind = (char *)string;
596 if (*strind != '+' && *strind != '-' && *strind != 'x') {
597 tempWidth = ReadInteger(strind, &nextCharacter);
598 if (strind == nextCharacter)
600 strind = nextCharacter;
604 if (*strind == 'x' || *strind == 'X') {
606 tempHeight = ReadInteger(strind, &nextCharacter);
607 if (strind == nextCharacter)
609 strind = nextCharacter;
613 if ((*strind == '+') || (*strind == '-')) {
614 if (*strind == '-') {
616 tempX = -ReadInteger(strind, &nextCharacter);
617 if (strind == nextCharacter)
619 strind = nextCharacter;
625 tempX = ReadInteger(strind, &nextCharacter);
626 if (strind == nextCharacter)
628 strind = nextCharacter;
631 if ((*strind == '+') || (*strind == '-')) {
632 if (*strind == '-') {
634 tempY = -ReadInteger(strind, &nextCharacter);
635 if (strind == nextCharacter)
637 strind = nextCharacter;
643 tempY = ReadInteger(strind, &nextCharacter);
644 if (strind == nextCharacter)
646 strind = nextCharacter;
652 /* If strind isn't at the end of the string the it's an invalid
653 geometry specification. */
655 if (*strind != '\0') return 0;
661 if (mask & WidthValue)
663 if (mask & HeightValue)
664 *height = tempHeight;
669 /* -- INTERFACE FUNCTIONS -------------------------------------------------- */
672 * Perform initialization. This usually happens on the program startup
673 * and restarting after glutMainLoop termination...
675 void FGAPIENTRY glutInit( int* pargc, char** argv )
677 char* displayName = NULL;
678 char* geometry = NULL;
679 int i, j, argc = *pargc;
681 /* will return true for VC8 (VC2005) and higher */
682 #if TARGET_HOST_MS_WINDOWS && ( _MSC_VER >= 1400 )
687 if( fgState.Initialised )
688 fgError( "illegal glutInit() reinitialization attempt" );
690 if (pargc && *pargc && argv && *argv && **argv)
692 fgState.ProgramName = strdup (*argv);
694 if( !fgState.ProgramName )
695 fgError ("Could not allocate space for the program's name.");
698 fgCreateStructure( );
701 fgState.Time = fgSystemTime();
703 /* check if GLUT_FPS env var is set */
706 /* will return true for VC8 (VC2005) and higher */
707 #if TARGET_HOST_MS_WINDOWS && ( _MSC_VER >= 1400 )
709 err = _dupenv_s( &fps, &sLen, "GLUT_FPS" );
711 fgError("Error getting GLUT_FPS environment variable");
713 const char *fps = getenv( "GLUT_FPS" );
718 sscanf( fps, "%d", &interval );
721 fgState.FPSInterval = 5000; /* 5000 millisecond default */
723 fgState.FPSInterval = interval;
725 /* will return true for VC8 (VC2005) and higher */
726 #if TARGET_HOST_MS_WINDOWS && ( _MSC_VER >= 1400 )
727 free ( fps ); fps = NULL; /* dupenv_s allocates a string that we must free */
731 /* will return true for VC8 (VC2005) and higher */
732 #if TARGET_HOST_MS_WINDOWS && ( _MSC_VER >= 1400 )
733 err = _dupenv_s( &displayName, &sLen, "DISPLAY" );
735 fgError("Error getting DISPLAY environment variable");
737 displayName = getenv( "DISPLAY" );
740 for( i = 1; i < argc; i++ )
742 if( strcmp( argv[ i ], "-display" ) == 0 )
745 fgError( "-display parameter must be followed by display name" );
747 displayName = argv[ i ];
749 argv[ i - 1 ] = NULL;
753 else if( strcmp( argv[ i ], "-geometry" ) == 0 )
756 fgError( "-geometry parameter must be followed by window "
757 "geometry settings" );
759 geometry = argv[ i ];
761 argv[ i - 1 ] = NULL;
765 else if( strcmp( argv[ i ], "-direct" ) == 0)
767 if( fgState.DirectContext == GLUT_FORCE_INDIRECT_CONTEXT )
768 fgError( "parameters ambiguity, -direct and -indirect "
769 "cannot be both specified" );
771 fgState.DirectContext = GLUT_FORCE_DIRECT_CONTEXT;
775 else if( strcmp( argv[ i ], "-indirect" ) == 0 )
777 if( fgState.DirectContext == GLUT_FORCE_DIRECT_CONTEXT )
778 fgError( "parameters ambiguity, -direct and -indirect "
779 "cannot be both specified" );
781 fgState.DirectContext = GLUT_FORCE_INDIRECT_CONTEXT;
785 else if( strcmp( argv[ i ], "-iconic" ) == 0 )
787 fgState.ForceIconic = GL_TRUE;
791 else if( strcmp( argv[ i ], "-gldebug" ) == 0 )
793 fgState.GLDebugSwitch = GL_TRUE;
797 else if( strcmp( argv[ i ], "-sync" ) == 0 )
799 fgState.XSyncSwitch = GL_TRUE;
805 /* Compact {argv}. */
806 for( i = j = 1; i < *pargc; i++, j++ )
808 /* Guaranteed to end because there are "*pargc" arguments left */
809 while ( argv[ j ] == NULL )
812 argv[ i ] = argv[ j ];
815 #endif /* _WIN32_WCE */
818 * Have the display created now. If there wasn't a "-display"
819 * in the program arguments, we will use the DISPLAY environment
820 * variable for opening the X display (see code above):
822 fghInitialize( displayName );
823 /* will return true for VC8 (VC2005) and higher */
824 #if TARGET_HOST_MS_WINDOWS && ( _MSC_VER >= 1400 )
825 free ( displayName ); displayName = NULL; /* dupenv_s allocates a string that we must free */
829 * Geometry parsing deffered until here because we may need the screen
835 unsigned int parsedWidth, parsedHeight;
836 int mask = XParseGeometry( geometry,
837 &fgState.Position.X, &fgState.Position.Y,
838 &parsedWidth, &parsedHeight );
839 /* TODO: Check for overflow? */
840 fgState.Size.X = parsedWidth;
841 fgState.Size.Y = parsedHeight;
843 if( (mask & (WidthValue|HeightValue)) == (WidthValue|HeightValue) )
844 fgState.Size.Use = GL_TRUE;
846 if( mask & XNegative )
847 fgState.Position.X += fgDisplay.ScreenWidth - fgState.Size.X;
849 if( mask & YNegative )
850 fgState.Position.Y += fgDisplay.ScreenHeight - fgState.Size.Y;
852 if( (mask & (XValue|YValue)) == (XValue|YValue) )
853 fgState.Position.Use = GL_TRUE;
857 #if TARGET_HOST_MS_WINDOWS
858 void (__cdecl *__glutExitFunc)( int return_value ) = NULL;
860 void FGAPIENTRY __glutInitWithExit( int *pargc, char **argv, void (__cdecl *exit_function)(int) )
862 __glutExitFunc = exit_function;
863 glutInit(pargc, argv);
868 * Undoes all the "glutInit" stuff
870 void FGAPIENTRY glutExit ( void )
876 * Sets the default initial window position for new windows
878 void FGAPIENTRY glutInitWindowPosition( int x, int y )
880 fgState.Position.X = x;
881 fgState.Position.Y = y;
883 if( ( x >= 0 ) && ( y >= 0 ) )
884 fgState.Position.Use = GL_TRUE;
886 fgState.Position.Use = GL_FALSE;
890 * Sets the default initial window size for new windows
892 void FGAPIENTRY glutInitWindowSize( int width, int height )
894 fgState.Size.X = width;
895 fgState.Size.Y = height;
897 if( ( width > 0 ) && ( height > 0 ) )
898 fgState.Size.Use = GL_TRUE;
900 fgState.Size.Use = GL_FALSE;
904 * Sets the default display mode for all new windows
906 void FGAPIENTRY glutInitDisplayMode( unsigned int displayMode )
908 /* We will make use of this value when creating a new OpenGL context... */
909 fgState.DisplayMode = displayMode;
913 /* -- INIT DISPLAY STRING PARSING ------------------------------------------ */
915 static char* Tokens[] =
917 "alpha", "acca", "acc", "blue", "buffer", "conformant", "depth", "double",
918 "green", "index", "num", "red", "rgba", "rgb", "luminance", "stencil",
919 "single", "stereo", "samples", "slow", "win32pdf", "win32pfd", "xvisual",
920 "xstaticgray", "xgrayscale", "xstaticcolor", "xpseudocolor",
921 "xtruecolor", "xdirectcolor",
922 "xstaticgrey", "xgreyscale", "xstaticcolour", "xpseudocolour",
923 "xtruecolour", "xdirectcolour", "borderless", "aux"
925 #define NUM_TOKENS (sizeof(Tokens) / sizeof(*Tokens))
927 void FGAPIENTRY glutInitDisplayString( const char* displayMode )
929 int glut_state_flag = 0 ;
931 * Unpack a lot of options from a character string. The options are
932 * delimited by blanks or tabs.
935 /* will return true for VC8 (VC2005) and higher */
936 #if TARGET_HOST_MS_WINDOWS && ( _MSC_VER >= 1400 )
937 char *next_token = NULL;
939 size_t len = strlen ( displayMode );
940 char *buffer = (char *)malloc ( (len+1) * sizeof(char) );
941 memcpy ( buffer, displayMode, len );
944 /* will return true for VC8 (VC2005) and higher */
945 #if TARGET_HOST_MS_WINDOWS && ( _MSC_VER >= 1400 )
946 token = strtok_s ( buffer, " \t", &next_token );
948 token = strtok ( buffer, " \t" );
952 /* Process this token */
955 /* Temporary fix: Ignore any length specifications and at least
956 * process the basic token
957 * TODO: Fix this permanently
959 size_t cleanlength = strcspn ( token, "=<>~!" );
961 for ( i = 0; i < NUM_TOKENS; i++ )
963 if ( strncmp ( token, Tokens[i], cleanlength ) == 0 ) break ;
968 case 0 : /* "alpha": Alpha color buffer precision in bits */
969 glut_state_flag |= GLUT_ALPHA ; /* Somebody fix this for me! */
972 case 1 : /* "acca": Red, green, blue, and alpha accumulation buffer
976 case 2 : /* "acc": Red, green, and blue accumulation buffer precision
977 in bits with zero bits alpha */
978 glut_state_flag |= GLUT_ACCUM ; /* Somebody fix this for me! */
981 case 3 : /* "blue": Blue color buffer precision in bits */
984 case 4 : /* "buffer": Number of bits in the color index color buffer
988 case 5 : /* "conformant": Boolean indicating if the frame buffer
989 configuration is conformant or not */
992 case 6 : /* "depth": Number of bits of precsion in the depth buffer */
993 glut_state_flag |= GLUT_DEPTH ; /* Somebody fix this for me! */
996 case 7 : /* "double": Boolean indicating if the color buffer is
998 glut_state_flag |= GLUT_DOUBLE ;
1001 case 8 : /* "green": Green color buffer precision in bits */
1004 case 9 : /* "index": Boolean if the color model is color index or not
1006 glut_state_flag |= GLUT_INDEX ;
1009 case 10 : /* "num": A special capability name indicating where the
1010 value represents the Nth frame buffer configuration
1011 matching the description string */
1014 case 11 : /* "red": Red color buffer precision in bits */
1017 case 12 : /* "rgba": Number of bits of red, green, blue, and alpha in
1018 the RGBA color buffer */
1019 glut_state_flag |= GLUT_RGBA ; /* Somebody fix this for me! */
1022 case 13 : /* "rgb": Number of bits of red, green, and blue in the
1023 RGBA color buffer with zero bits alpha */
1024 glut_state_flag |= GLUT_RGB ; /* Somebody fix this for me! */
1027 case 14 : /* "luminance": Number of bits of red in the RGBA and zero
1028 bits of green, blue (alpha not specified) of color buffer
1030 glut_state_flag |= GLUT_LUMINANCE ; /* Somebody fix this for me! */
1033 case 15 : /* "stencil": Number of bits in the stencil buffer */
1034 glut_state_flag |= GLUT_STENCIL; /* Somebody fix this for me! */
1037 case 16 : /* "single": Boolean indicate the color buffer is single
1039 glut_state_flag |= GLUT_SINGLE ;
1042 case 17 : /* "stereo": Boolean indicating the color buffer supports
1043 OpenGL-style stereo */
1044 glut_state_flag |= GLUT_STEREO ;
1047 case 18 : /* "samples": Indicates the number of multisamples to use
1048 based on GLX's SGIS_multisample extension (for
1050 glut_state_flag |= GLUT_MULTISAMPLE ; /*Somebody fix this for me!*/
1053 case 19 : /* "slow": Boolean indicating if the frame buffer
1054 configuration is slow or not */
1057 case 20 : /* "win32pdf": (incorrect spelling but was there before */
1058 case 21 : /* "win32pfd": matches the Win32 Pixel Format Descriptor by
1060 #if TARGET_HOST_MS_WINDOWS
1064 case 22 : /* "xvisual": matches the X visual ID by number */
1065 #if TARGET_HOST_POSIX_X11
1069 case 23 : /* "xstaticgray": */
1070 case 29 : /* "xstaticgrey": boolean indicating if the frame buffer
1071 configuration's X visual is of type StaticGray */
1072 #if TARGET_HOST_POSIX_X11
1076 case 24 : /* "xgrayscale": */
1077 case 30 : /* "xgreyscale": boolean indicating if the frame buffer
1078 configuration's X visual is of type GrayScale */
1079 #if TARGET_HOST_POSIX_X11
1083 case 25 : /* "xstaticcolor": */
1084 case 31 : /* "xstaticcolour": boolean indicating if the frame buffer
1085 configuration's X visual is of type StaticColor */
1086 #if TARGET_HOST_POSIX_X11
1090 case 26 : /* "xpseudocolor": */
1091 case 32 : /* "xpseudocolour": boolean indicating if the frame buffer
1092 configuration's X visual is of type PseudoColor */
1093 #if TARGET_HOST_POSIX_X11
1097 case 27 : /* "xtruecolor": */
1098 case 33 : /* "xtruecolour": boolean indicating if the frame buffer
1099 configuration's X visual is of type TrueColor */
1100 #if TARGET_HOST_POSIX_X11
1104 case 28 : /* "xdirectcolor": */
1105 case 34 : /* "xdirectcolour": boolean indicating if the frame buffer
1106 configuration's X visual is of type DirectColor */
1107 #if TARGET_HOST_POSIX_X11
1111 case 35 : /* "borderless": windows should not have borders */
1112 #if TARGET_HOST_POSIX_X11
1116 case 36 : /* "aux": some number of aux buffers */
1117 glut_state_flag |= GLUT_AUX;
1120 case 37 : /* Unrecognized */
1121 fgWarning ( "WARNING - Display string token not recognized: %s",
1126 /* will return true for VC8 (VC2005) and higher */
1127 #if TARGET_HOST_MS_WINDOWS && ( _MSC_VER >= 1400 )
1128 token = strtok_s ( NULL, " \t", &next_token );
1130 token = strtok ( NULL, " \t" );
1136 /* We will make use of this value when creating a new OpenGL context... */
1137 fgState.DisplayMode = glut_state_flag;
1140 /* -- SETTING OPENGL 3.0 CONTEXT CREATION PARAMETERS ---------------------- */
1142 void FGAPIENTRY glutInitContextVersion( int majorVersion, int minorVersion )
1144 /* We will make use of these valuse when creating a new OpenGL context... */
1145 fgState.MajorVersion = majorVersion;
1146 fgState.MinorVersion = minorVersion;
1150 void FGAPIENTRY glutInitContextFlags( int flags )
1152 /* We will make use of this value when creating a new OpenGL context... */
1153 fgState.ContextFlags = flags;
1156 /*** END OF FILE ***/