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.
32 #define G_LOG_DOMAIN "freeglut-init"
34 #include "../include/GL/freeglut.h"
35 #include "freeglut_internal.h"
38 * TODO BEFORE THE STABLE RELEASE:
40 * fgDeinitialize() -- Win32's OK, X11 needs the OS-specific deinitialization done
41 * glutInitDisplayString() -- display mode string parsing
43 * Wouldn't it be cool to use gettext() for error messages? I just love bash saying
44 * "nie znaleziono pliku" instead of "file not found" :) Is gettext easily portable?
47 /* -- GLOBAL VARIABLES ----------------------------------------------------- */
50 * A structure pointed by g_pDisplay holds all information
51 * regarding the display, screen, root window etc.
53 SFG_Display fgDisplay;
56 * The settings for the current freeglut session
58 SFG_State fgState = { { -1, -1, FALSE }, /* Position */
59 { 300, 300, TRUE }, /* Size */
60 GLUT_RGBA | GLUT_SINGLE | GLUT_DEPTH, /* DisplayMode */
61 FALSE, /* ForceDirectContext */
62 TRUE, /* TryDirectContext */
63 FALSE, /* ForceIconic */
64 FALSE, /* GLDebugSwitch */
65 FALSE, /* XSyncSwitch */
66 TRUE, /* IgnoreKeyRepeat */
70 #ifdef TARGET_HOST_WIN32
71 { 0, FALSE }, /* Time */
75 { NULL, NULL }, /* Timers */
76 NULL, /* IdleCallback */
77 NULL, /* MenuStateCallback */
78 NULL, /* MenuStatusCallback */
79 { 640, 480, TRUE }, /* GameModeSize */
80 16, /* GameModeDepth */
81 72, /* GameModeRefresh */
82 GLUT_ACTION_EXIT, /* ActionOnWindowClose */
83 GLUT_EXEC_STATE_INIT /* ExecState */
87 /* -- PRIVATE FUNCTIONS ---------------------------------------------------- */
90 * A call to this function should initialize all the display stuff...
92 void fgInitialize( const char* displayName )
94 #if TARGET_HOST_UNIX_X11
96 * Have the display created
98 fgDisplay.Display = XOpenDisplay( displayName );
100 if( fgDisplay.Display == NULL )
103 * Failed to open a display. That's no good.
105 fgError( "failed to open display '%s'", XDisplayName( displayName ) );
109 * Check for the OpenGL GLX extension availability:
111 if( !glXQueryExtension( fgDisplay.Display, NULL, NULL ) )
114 * GLX extensions have not been found...
116 fgError( "OpenGL GLX extension not supported by display '%s'", XDisplayName( displayName ) );
120 * Grab the default screen for the display we have just opened
122 fgDisplay.Screen = DefaultScreen( fgDisplay.Display );
125 * The same applying to the root window
127 fgDisplay.RootWindow = RootWindow(
133 * Grab the logical screen's geometry
135 fgDisplay.ScreenWidth = DisplayWidth(
140 fgDisplay.ScreenHeight = DisplayHeight(
146 * Grab the physical screen's geometry
148 fgDisplay.ScreenWidthMM = DisplayWidthMM(
153 fgDisplay.ScreenHeightMM = DisplayHeightMM(
159 * The display's connection number
161 fgDisplay.Connection = ConnectionNumber( fgDisplay.Display );
164 * Create the window deletion atom
166 fgDisplay.DeleteWindow = XInternAtom(
172 #elif TARGET_HOST_WIN32
178 * What we need to do is to initialize the fgDisplay global structure here...
180 fgDisplay.Instance = GetModuleHandle( NULL );
183 * Check if the freeglut window class has been registered before...
185 atom = GetClassInfo( fgDisplay.Instance, "FREEGLUT", &wc );
188 * ...nope, it has not, and we have to do it right now:
193 * Make sure the unitialized fields are reset to zero
195 ZeroMemory( &wc, sizeof(WNDCLASS) );
198 * Each of the windows should have its own device context...
201 wc.lpfnWndProc = fgWindowProc;
204 wc.hInstance = fgDisplay.Instance;
205 wc.hIcon = LoadIcon( fgDisplay.Instance, "GLUT_ICON" );
207 wc.hIcon = LoadIcon( NULL, IDI_WINLOGO );
209 wc.hCursor = LoadCursor( NULL, IDC_ARROW );
210 wc.hbrBackground = NULL;
211 wc.lpszMenuName = NULL;
212 wc.lpszClassName = "FREEGLUT";
215 * Register the window class
217 atom = RegisterClass( &wc );
222 * The screen dimensions can be obtained via GetSystemMetrics() calls
224 fgDisplay.ScreenWidth = GetSystemMetrics( SM_CXSCREEN );
225 fgDisplay.ScreenHeight = GetSystemMetrics( SM_CYSCREEN );
229 * Checking the display's size in millimeters isn't too hard, too:
231 HWND desktop = GetDesktopWindow();
232 HDC context = GetDC( desktop );
235 * Grab the appropriate values now (HORZSIZE and VERTSIZE respectably):
237 fgDisplay.ScreenWidthMM = GetDeviceCaps( context, HORZSIZE );
238 fgDisplay.ScreenHeightMM = GetDeviceCaps( context, VERTSIZE );
241 * Whoops, forgot to release the device context :)
243 ReleaseDC( desktop, context );
249 * Have the joystick device initialized now
255 * Perform the freeglut deinitialization...
257 void fgDeinitialize( void )
262 * Check if initialization has been performed before
264 if( !fgState.Time.Set )
266 fgWarning( "fgDeinitialize(): fgState.Timer is null => no valid initialization has been performed" );
271 * Perform the freeglut structure deinitialization
273 fgDestroyStructure();
276 * Delete all the timers and their storage list
278 while ( (timer = fgState.Timers.First) != NULL )
280 fgListRemove ( &fgState.Timers, &timer->Node ) ;
285 * Deinitialize the joystick device
290 * Reset the state structure
293 fgState.Position.X = -1 ;
294 fgState.Position.Y = -1 ;
295 fgState.Position.Use = FALSE ;
297 fgState.Size.X = 300 ;
298 fgState.Size.Y = 300 ;
299 fgState.Size.Use = TRUE ;
302 * The default display mode to be used
304 fgState.DisplayMode = GLUT_RGBA | GLUT_SINGLE | GLUT_DEPTH;
306 fgState.ForceDirectContext = FALSE;
307 fgState.TryDirectContext = TRUE;
308 fgState.ForceIconic = FALSE;
309 fgState.GLDebugSwitch = FALSE;
310 fgState.XSyncSwitch = FALSE;
311 fgState.ActionOnWindowClose = GLUT_ACTION_EXIT ;
312 fgState.ExecState = GLUT_EXEC_STATE_INIT ;
315 * Assume we want to ignore the automatic key repeat
317 fgState.IgnoreKeyRepeat = TRUE;
320 * Set the default game mode settings
322 fgState.GameModeSize.X = 640;
323 fgState.GameModeSize.Y = 480;
324 fgState.GameModeDepth = 16;
325 fgState.GameModeRefresh = 72;
327 fgState.Time.Set = FALSE ;
329 fgState.Timers.First = fgState.Timers.Last = NULL ;
330 fgState.IdleCallback = NULL ;
331 fgState.MenuStateCallback = (FGCBmenuState)NULL ;
332 fgState.MenuStatusCallback = (FGCBmenuStatus)NULL ;
337 fgState.SwapCount = 0;
338 fgState.SwapTime = 0;
339 fgState.FPSInterval = 0;
342 #if TARGET_HOST_UNIX_X11
345 * Make sure all X-client data we have created will be destroyed on display closing
347 XSetCloseDownMode( fgDisplay.Display, DestroyAll );
350 * Close the display connection, destroying all windows we have created so far
352 XCloseDisplay( fgDisplay.Display );
358 /* -- INTERFACE FUNCTIONS -------------------------------------------------- */
361 * Perform initialization. This usually happens on the program startup
362 * and restarting after glutMainLoop termination...
364 void FGAPIENTRY glutInit( int* pargc, char** argv )
366 char* displayName = NULL;
367 int i, j, argc = *pargc;
370 * Do not allow multiple initialization of the library
372 if( fgState.Time.Set )
375 * We can't have multiple initialization performed
377 fgError( "illegal glutInit() reinitialization attemp" );
381 * Have the internal freeglut structure initialized now
386 * Remember the function's call time
388 #if TARGET_HOST_UNIX_X11
389 gettimeofday(&fgState.Time.Value, NULL);
390 #elif TARGET_HOST_WIN32
391 fgState.Time.Value = timeGetTime();
393 fgState.Time.Set = TRUE;
395 /* check if GLUT_FPS env var is set */
397 const char *fps = getenv("GLUT_FPS");
399 sscanf(fps, "%d", &fgState.FPSInterval);
400 if (fgState.FPSInterval <= 0)
401 fgState.FPSInterval = 5000; /* 5000 milliseconds */
406 * Grab the environment variable indicating the X display to use.
407 * This is harmless under Win32, so let's let it stay here...
409 #if TARGET_HOST_WIN32
410 if ( !getenv ( "DISPLAY" ) )
411 displayName = strdup ( "" ) ;
414 displayName = strdup( getenv( "DISPLAY" ) );
417 * Have the program arguments parsed.
419 for( i=1; i<argc; i++ )
422 * The X display name settings
424 if( strcmp( argv[ i ], "-display" ) == 0 )
427 * Check for possible lack of the next argument
430 fgError( "-display parameter must be followed by display name" );
433 * Release the previous display name (the one from app's environment)
438 * Make a working copy of the name for us to use
440 displayName = strdup( argv[ i ] );
443 * Have both arguments removed
445 argv[ i - 1 ] = NULL;
451 * The geometry settings
453 else if( strcmp( argv[ i ], "-geometry" ) == 0 )
459 * Again, check if there is at least one more argument
462 fgError( "-geometry parameter must be followed by window geometry settings" );
465 * Otherwise scan the geometry settings...
467 result = sscanf ( argv[i], "%dx%d+%d+%d", &x, &y, &w, &h );
470 * Check what we have been supplied with...
481 fgState.Position.Y = fgDisplay.ScreenHeight + y - fgState.Size.Y;
483 fgState.Position.Y = y;
489 fgState.Position.X = fgDisplay.ScreenWidth + x - fgState.Size.X;
491 fgState.Position.X = x;
495 * Have both arguments removed
497 argv[ i - 1 ] = NULL;
503 * The direct/indirect OpenGL contexts settings
505 else if( strcmp( argv[ i ], "-direct" ) == 0)
508 * We try to force direct rendering...
510 if( fgState.TryDirectContext == FALSE )
511 fgError( "parameters ambiguity, -direct and -indirect cannot be both specified" );
513 fgState.ForceDirectContext = TRUE;
517 else if( strcmp( argv[ i ], "-indirect" ) == 0 )
520 * We try to force indirect rendering...
522 if( fgState.ForceDirectContext == TRUE )
523 fgError( "parameters ambiguity, -direct and -indirect cannot be both specified" );
525 fgState.TryDirectContext = FALSE;
531 * The '-iconic' parameter makes all new top-level
532 * windows created in iconified state...
534 else if( strcmp( argv[ i ], "-iconic" ) == 0 )
536 fgState.ForceIconic = TRUE;
542 * The '-gldebug' option activates some OpenGL state debugging features
544 else if( strcmp( argv[ i ], "-gldebug" ) == 0 )
546 fgState.GLDebugSwitch = TRUE;
552 * The '-sync' option activates X protocol synchronization (for debugging purposes)
554 else if( strcmp( argv[ i ], "-sync" ) == 0 )
556 fgState.XSyncSwitch = TRUE;
563 * Have the arguments list compacted now
566 for( i = 1; i < *pargc; i++, j++ )
568 if( argv[ i ] == NULL )
570 while ( argv[j] == NULL ) j++ ; /* Guaranteed to end because there are "*pargc" arguments left */
576 * Have the display created now. As I am too lazy to implement
577 * the program arguments parsing, we will have the DISPLAY
578 * environment variable used for opening the X display:
580 fgInitialize( displayName );
583 * Check for the minus one settings for both position and size...
585 if( fgState.Position.X < 0 || fgState.Position.Y < 0 )
586 fgState.Position.Use = FALSE;
588 if( fgState.Size.X < 0 || fgState.Size.Y < 0 )
589 fgState.Size.Use = FALSE;
592 * Do not forget about releasing the display name string
598 * Sets the default initial window position for new windows
600 void FGAPIENTRY glutInitWindowPosition( int x, int y )
603 * The settings can be disables when both coordinates are negative
605 if( (x >= 0) && (y >= 0) )
608 * We want to specify the initial position of each of the windows
610 fgState.Position.X = x;
611 fgState.Position.Y = y;
612 fgState.Position.Use = TRUE;
617 * The initial position of each of the windows is specified by the wm
619 fgState.Position.X = -1;
620 fgState.Position.Y = -1;
621 fgState.Position.Use = FALSE;
626 * Sets the default initial window size for new windows
628 void FGAPIENTRY glutInitWindowSize( int width, int height )
631 * The settings can be disables when both values are negative
633 if( (width > 0) && (height > 0) )
636 * We want to specify the initial size of each of the windows
638 fgState.Size.X = width;
639 fgState.Size.Y = height;
640 fgState.Size.Use = TRUE;
645 * The initial size of each of the windows is specified by the wm (officially this is an error condition)
649 fgState.Size.Use = FALSE;
654 * Sets the default display mode for all new windows
656 void FGAPIENTRY glutInitDisplayMode( unsigned int displayMode )
659 * We will make use of this value when creating a new OpenGL context...
661 fgState.DisplayMode = displayMode;
665 /* -- INIT DISPLAY STRING PARSING ------------------------------------------ */
667 #if 0 /* FIXME: CJP */
669 * There is a discrete number of comparison operators we can encounter:
671 * comparison ::= "=" | "!=" | "<" | ">" | "<=" | ">=" | "~"
673 #define FG_NONE 0x0000
674 #define FG_EQUAL 0x0001
675 #define FG_NOT_EQUAL 0x0002
676 #define FG_LESS 0x0003
677 #define FG_MORE 0x0004
678 #define FG_LESS_OR_EQUAL 0x0005
679 #define FG_MORE_OR_EQUAL 0x0006
680 #define FG_CLOSEST 0x0007
683 * The caller can feed us with a number of capability tokens:
685 * capability ::= "alpha" | "acca" | "acc" | "blue" | "buffer" | "conformant" | "depth" | "double" |
686 * "green" | "index" | "num" | "red" | "rgba" | "rgb" | "luminance" | "stencil" |
687 * "single" | "stereo" | "samples" | "slow" | "win32pdf" | "xvisual" | "xstaticgray" |
688 * "xgrayscale" | "xstaticcolor" | "xpseudocolor" | "xtruecolor" | "xdirectcolor"
690 static gchar* g_Tokens[] =
692 "none", "alpha", "acca", "acc", "blue", "buffer", "conformant", "depth", "double", "green",
693 "index", "num", "red", "rgba", "rgb", "luminance", "stencil", "single", "stereo", "samples",
694 "slow", "win32pdf", "xvisual", "xstaticgray", "xgrayscale", "xstaticcolor", "xpseudocolor",
695 "xtruecolor", "xdirectcolor", NULL
699 * The structure to hold the parsed display string tokens
701 typedef struct tagSFG_Capability SFG_Capability;
702 struct tagSFG_Capability
704 gint capability; /* the capability token enumerator */
705 gint comparison; /* the comparison operator used */
706 gint value; /* the value we're comparing to */
710 * The scanner configuration for the init display string
712 static GScannerConfig fgInitDisplayStringScannerConfig =
714 ( " \t\r\n" ) /* cset_skip_characters */,
719 ) /* cset_identifier_first */,
727 ) /* cset_identifier_nth */,
728 ( "#\n" ) /* cpair_comment_single */,
729 FALSE /* case_sensitive */,
730 TRUE /* skip_comment_multi */,
731 TRUE /* skip_comment_single */,
732 TRUE /* scan_comment_multi */,
733 TRUE /* scan_identifier */,
734 FALSE /* scan_identifier_1char */,
735 FALSE /* scan_identifier_NULL */,
736 TRUE /* scan_symbols */,
737 FALSE /* scan_binary */,
738 TRUE /* scan_octal */,
739 TRUE /* scan_float */,
741 FALSE /* scan_hex_dollar */,
742 TRUE /* scan_string_sq */,
743 TRUE /* scan_string_dq */,
744 TRUE /* numbers_2_int */,
745 FALSE /* int_2_float */,
746 FALSE /* identifier_2_string */,
747 TRUE /* char_2_token */,
748 FALSE /* symbol_2_token */,
749 FALSE /* scope_0_fallback */,
753 * Sets the default display mode for all new windows using a string
755 void FGAPIENTRY glutInitDisplayString( char* displayMode )
758 * display_string ::= (switch)
759 * switch ::= capability [comparison value]
760 * comparison ::= "=" | "!=" | "<" | ">" | "<=" | ">=" | "~"
761 * capability ::= "alpha" | "acca" | "acc" | "blue" | "buffer" | "conformant" |
762 * "depth" | "double" | "green" | "index" | "num" | "red" | "rgba" |
763 * "rgb" | "luminance" | "stencil" | "single" | "stereo" |
764 * "samples" | "slow" | "win32pdf" | "xvisual" | "xstaticgray" |
765 * "xgrayscale" | "xstaticcolor" | "xpseudocolor" |
766 * "xtruecolor" | "xdirectcolor"
767 * value ::= 0..9 [value]
769 * The display string grammar. This should be EBNF, but I couldn't find the definitions so, to
770 * clarify: (expr) means 0 or more times the expression, [expr] means 0 or 1 times expr.
772 * Create a new GLib lexical analyzer to process the display mode string
774 GScanner* scanner = g_scanner_new( &fgInitDisplayStringScannerConfig );
779 * Fail if the display mode string is empty or the scanner failed to initialize
781 freeglut_return_if_fail( (scanner != NULL) && (strlen( displayMode ) > 0) );
784 * Set the scanner's input name (for debugging)
786 scanner->input_name = "glutInitDisplayString";
789 * Start the lexical analysis of the extensions string
791 g_scanner_input_text( scanner, displayMode, strlen( displayMode ) );
794 * While there are any more tokens to be checked...
796 while( !g_scanner_eof( scanner ) )
799 * Actually we're expecting only string tokens
801 GTokenType tokenType = g_scanner_get_next_token( scanner );
804 * We are looking for identifiers
806 if( tokenType == G_TOKEN_IDENTIFIER )
808 gchar* capability = NULL; /* the capability identifier string (always present) */
809 gint capID = 0; /* the capability identifier value (from g_Tokens) */
810 gint comparison = 0; /* the comparison operator value, see definitions */
811 gchar* valueString = NULL; /* if the previous one is present, this is needed */
812 gint value = 0; /* the integer value converted using a strtol call */
813 SFG_Capability* capStruct; /* the capability description structure */
816 * OK. The general rule of thumb that we always should be getting a capability identifier
817 * string (see the grammar description). If it is followed by a comparison identifier, then
818 * there must follow an integer value we're comparing the capability to...
820 * Have the current token analyzed with that in mind...
822 for( i=0; i<(gint) strlen( scanner->value.v_identifier ); i++ )
824 gchar c = scanner->value.v_identifier[ i ];
826 if( (c == '=') || (c == '!') || (c == '<') || (c == '>') || (c == '~') )
831 * Here we go with the length of the capability identifier string.
832 * In the worst of cases, it is as long as the token identifier.
834 capability = g_strndup( scanner->value.v_identifier, i );
837 * OK. Is there a chance for comparison and value identifiers to follow?
838 * Note: checking against i+1 as this handles two cases: single character
839 * comparison operator and first of value's digits, which must always be
840 * there, or the two-character comparison operators.
842 if( (i + 1) < (gint) strlen( scanner->value.v_identifier ) )
845 * Yeah, indeed, it is the i-th character to start the identifier, then.
847 gchar c1 = scanner->value.v_identifier[ i + 0 ];
848 gchar c2 = scanner->value.v_identifier[ i + 1 ];
850 if( (c1 == '=') ) { i += 1; comparison = FG_EQUAL; } else
851 if( (c1 == '!') && (c2 == '=') ) { i += 2; comparison = FG_NOT_EQUAL; } else
852 if( (c1 == '<') && (c2 == '=') ) { i += 2; comparison = FG_LESS_OR_EQUAL; } else
853 if( (c1 == '>') && (c2 == '=') ) { i += 2; comparison = FG_MORE_OR_EQUAL; } else
854 if( (c1 == '<') ) { i += 1; comparison = FG_LESS; } else
855 if( (c1 == '>') ) { i += 1; comparison = FG_MORE; } else
856 if( (c1 == '~') ) { i += 1; comparison = FG_CLOSEST; } else
857 g_warning( "invalid comparison operator in token `%s'", scanner->value.v_identifier );
861 * Grab the value string that must follow the comparison operator...
863 if( comparison != FG_NONE && i < (gint) strlen( scanner->value.v_identifier ) )
864 valueString = strdup( scanner->value.v_identifier + i );
867 * If there was a value string, convert it to integer...
869 if( comparison != FG_NONE && strlen( valueString ) > 0 )
870 value = strtol( valueString, NULL, 0 );
873 * Now we need to match the capability string and its ID
875 for( i=0; g_Tokens[ i ]!=NULL; i++ )
877 if( strcmp( capability, g_Tokens[ i ] ) == 0 )
880 * Looks like we've found the one we were looking for
888 * Create a new capability description structure
890 capStruct = g_new0( SFG_Capability, 1 );
893 * Fill in the cap's values, as we have parsed it:
895 capStruct->capability = capID;
896 capStruct->comparison = comparison;
897 capStruct->value = value;
900 * Add the new capabaility to the caps list
902 caps = g_list_append( caps, capStruct );
905 * Clean up the local mess and keep rolling on
907 g_free( valueString );
908 g_free( capability );
913 * Now that we have converted the string into somewhat more machine-friendly
914 * form, proceed with matching the frame buffer configuration...
916 * The caps list could be passed to a function that would try finding the closest
917 * matching pixel format, visual, frame buffer configuration or whatever. It would
918 * be good to convert the glutInitDisplayMode() to use the same method.
921 g_message( "found %i capability preferences", g_list_length( caps ) );
923 g_message( "token `%s': cap: %i, com: %i, val: %i",
924 scanner->value.v_identifier,
925 capStruct->capability,
926 capStruct->comparison,
932 * Free the capabilities we have parsed
934 for( i=0; i<(gint) g_list_length( caps ); i++ )
935 g_free( g_list_nth( caps, i )->data );
938 * Destroy the capabilities list itself
943 * Free the lexical scanner now...
945 g_scanner_destroy( scanner );
949 #define NUM_TOKENS 28
950 static char* Tokens[] =
952 "alpha", "acca", "acc", "blue", "buffer", "conformant", "depth", "double", "green",
953 "index", "num", "red", "rgba", "rgb", "luminance", "stencil", "single", "stereo", "samples",
954 "slow", "win32pdf", "xvisual", "xstaticgray", "xgrayscale", "xstaticcolor", "xpseudocolor",
955 "xtruecolor", "xdirectcolor"
958 static int TokenLengths[] =
960 5, 4, 3, 4, 6, 10, 5, 6, 5,
961 5, 3, 3, 4, 3, 9, 7, 6, 6, 7,
962 4, 8, 7, 11, 10, 12, 12,
966 void FGAPIENTRY glutInitDisplayString( const char* displayMode )
968 int glut_state_flag = 0 ;
970 * Unpack a lot of options from a character string. The options are delimited by blanks or tabs.
973 int len = strlen ( displayMode ) ;
974 char *buffer = malloc ( (len+1) * sizeof(char) ) ;
975 memcpy ( buffer, displayMode, len ) ;
978 token = strtok ( buffer, " \t" ) ;
985 for ( i = 0; i < NUM_TOKENS; i++ )
987 if ( strncmp ( token, Tokens[i], TokenLengths[i] ) == 0 ) break ;
992 case 0 : /* "alpha": Alpha color buffer precision in bits */
993 glut_state_flag |= GLUT_ALPHA ; /* Somebody fix this for me! */
996 case 1 : /* "acca": Red, green, blue, and alpha accumulation buffer precision in bits */
999 case 2 : /* "acc": Red, green, and blue accumulation buffer precision in bits with zero bits alpha */
1000 glut_state_flag |= GLUT_ACCUM ; /* Somebody fix this for me! */
1003 case 3 : /* "blue": Blue color buffer precision in bits */
1006 case 4 : /* "buffer": Number of bits in the color index color buffer */
1009 case 5 : /* "conformant": Boolean indicating if the frame buffer configuration is conformant or not */
1012 case 6 : /* "depth": Number of bits of precsion in the depth buffer */
1013 glut_state_flag |= GLUT_DEPTH ; /* Somebody fix this for me! */
1016 case 7 : /* "double": Boolean indicating if the color buffer is double buffered */
1017 glut_state_flag |= GLUT_DOUBLE ;
1020 case 8 : /* "green": Green color buffer precision in bits */
1023 case 9 : /* "index": Boolean if the color model is color index or not */
1024 glut_state_flag |= GLUT_INDEX ;
1027 case 10 : /* "num": A special capability name indicating where the value represents the Nth frame buffer configuration matching the description string */
1030 case 11 : /* "red": Red color buffer precision in bits */
1033 case 12 : /* "rgba": Number of bits of red, green, blue, and alpha in the RGBA color buffer */
1034 glut_state_flag |= GLUT_RGBA ; /* Somebody fix this for me! */
1037 case 13 : /* "rgb": Number of bits of red, green, and blue in the RGBA color buffer with zero bits alpha */
1038 glut_state_flag |= GLUT_RGB ; /* Somebody fix this for me! */
1041 case 14 : /* "luminance": Number of bits of red in the RGBA and zero bits of green, blue (alpha not specified) of color buffer precision */
1042 glut_state_flag |= GLUT_LUMINANCE ; /* Somebody fix this for me! */
1045 case 15 : /* "stencil": Number of bits in the stencil buffer */
1046 glut_state_flag |= GLUT_STENCIL ; /* Somebody fix this for me! */
1049 case 16 : /* "single": Boolean indicate the color buffer is single buffered */
1050 glut_state_flag |= GLUT_SINGLE ;
1053 case 17 : /* "stereo": Boolean indicating the color buffer supports OpenGL-style stereo */
1054 glut_state_flag |= GLUT_STEREO ;
1057 case 18 : /* "samples": Indicates the number of multisamples to use based on GLX's SGIS_multisample extension (for antialiasing) */
1058 glut_state_flag |= GLUT_MULTISAMPLE ; /* Somebody fix this for me! */
1061 case 19 : /* "slow": Boolean indicating if the frame buffer configuration is slow or not */
1064 case 20 : /* "win32pdf": matches the Win32 Pixel Format Descriptor by number */
1065 #ifdef TARGET_HOST_WIN32
1069 case 21 : /* "xvisual": matches the X visual ID by number */
1070 #ifdef TARGET_HOST_UNIX_X11
1074 case 22 : /* "xstaticgray": boolean indicating if the frame buffer configuration's X visual is of type StaticGray */
1075 #ifdef TARGET_HOST_UNIX_X11
1079 case 23 : /* "xgrayscale": boolean indicating if the frame buffer configuration's X visual is of type GrayScale */
1080 #ifdef TARGET_HOST_UNIX_X11
1084 case 24 : /* "xstaticcolor": boolean indicating if the frame buffer configuration's X visual is of type StaticColor */
1085 #ifdef TARGET_HOST_UNIX_X11
1089 case 25 : /* "xpseudocolor": boolean indicating if the frame buffer configuration's X visual is of type PseudoColor */
1090 #ifdef TARGET_HOST_UNIX_X11
1094 case 26 : /* "xtruecolor": boolean indicating if the frame buffer configuration's X visual is of type TrueColor */
1095 #ifdef TARGET_HOST_UNIX_X11
1099 case 27 : /* "xdirectcolor": boolean indicating if the frame buffer configuration's X visual is of type DirectColor */
1100 #ifdef TARGET_HOST_UNIX_X11
1104 case 28 : /* Unrecognized */
1105 printf ( "WARNING - Display string token not recognized: %s\n", token ) ;
1109 token = strtok ( NULL, " \t" ) ;
1115 * We will make use of this value when creating a new OpenGL context...
1117 fgState.DisplayMode = glut_state_flag;
1120 /*** END OF FILE ***/