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, /* UseCurrentContext */
65 FALSE, /* GLDebugSwitch */
66 FALSE, /* XSyncSwitch */
67 TRUE, /* IgnoreKeyRepeat */
72 { 0, FALSE }, /* Time */
76 { NULL, NULL }, /* Timers */
77 NULL, /* IdleCallback */
78 FALSE, /* BuildingAMenu */
80 NULL, /* MenuStateCallback */
81 NULL, /* MenuStatusCallback */
82 { 640, 480, TRUE }, /* GameModeSize */
83 16, /* GameModeDepth */
84 72, /* GameModeRefresh */
85 GLUT_ACTION_EXIT, /* ActionOnWindowClose */
86 GLUT_EXEC_STATE_INIT /* ExecState */
90 /* -- PRIVATE FUNCTIONS ---------------------------------------------------- */
93 * A call to this function should initialize all the display stuff...
95 void fgInitialize( const char* displayName )
97 #if TARGET_HOST_UNIX_X11
98 fgDisplay.Display = XOpenDisplay( displayName );
100 if( fgDisplay.Display == NULL )
101 fgError( "failed to open display '%s'", XDisplayName( displayName ) );
103 if( !glXQueryExtension( fgDisplay.Display, NULL, NULL ) )
104 fgError( "OpenGL GLX extension not supported by display '%s'",
105 XDisplayName( displayName ) );
107 fgDisplay.Screen = DefaultScreen( fgDisplay.Display );
108 fgDisplay.RootWindow = RootWindow(
113 fgDisplay.ScreenWidth = DisplayWidth(
117 fgDisplay.ScreenHeight = DisplayHeight(
122 fgDisplay.ScreenWidthMM = DisplayWidthMM(
126 fgDisplay.ScreenHeightMM = DisplayHeightMM(
131 fgDisplay.Connection = ConnectionNumber( fgDisplay.Display );
134 * Create the window deletion atom
136 fgDisplay.DeleteWindow = XInternAtom(
142 #elif TARGET_HOST_WIN32
148 * What we need to do is to initialize the fgDisplay global structure here...
150 fgDisplay.Instance = GetModuleHandle( NULL );
152 atom = GetClassInfo( fgDisplay.Instance, "FREEGLUT", &wc );
155 ZeroMemory( &wc, sizeof(WNDCLASS) );
158 * Each of the windows should have its own device context...
161 wc.lpfnWndProc = fgWindowProc;
164 wc.hInstance = fgDisplay.Instance;
165 wc.hIcon = LoadIcon( fgDisplay.Instance, "GLUT_ICON" );
167 wc.hIcon = LoadIcon( NULL, IDI_WINLOGO );
169 wc.hCursor = LoadCursor( NULL, IDC_ARROW );
170 wc.hbrBackground = NULL;
171 wc.lpszMenuName = NULL;
172 wc.lpszClassName = "FREEGLUT";
175 * Register the window class
177 atom = RegisterClass( &wc );
182 * The screen dimensions can be obtained via GetSystemMetrics() calls
184 fgDisplay.ScreenWidth = GetSystemMetrics( SM_CXSCREEN );
185 fgDisplay.ScreenHeight = GetSystemMetrics( SM_CYSCREEN );
188 HWND desktop = GetDesktopWindow();
189 HDC context = GetDC( desktop );
191 fgDisplay.ScreenWidthMM = GetDeviceCaps( context, HORZSIZE );
192 fgDisplay.ScreenHeightMM = GetDeviceCaps( context, VERTSIZE );
194 ReleaseDC( desktop, context );
203 * Perform the freeglut deinitialization...
205 void fgDeinitialize( void )
209 if( !fgState.Time.Set )
211 fgWarning( "fgDeinitialize(): fgState.Timer is null => "
212 "no valid initialization has been performed" );
217 * If there was a menu created, destroy the rendering context
219 if ( fgStructure.MenuContext )
221 free ( fgStructure.MenuContext ) ;
222 fgStructure.MenuContext = NULL ;
225 fgDestroyStructure();
227 while ( (timer = (SFG_Timer *)fgState.Timers.First) != NULL )
229 fgListRemove ( &fgState.Timers, &timer->Node ) ;
235 fgState.Position.X = -1 ;
236 fgState.Position.Y = -1 ;
237 fgState.Position.Use = FALSE ;
239 fgState.Size.X = 300 ;
240 fgState.Size.Y = 300 ;
241 fgState.Size.Use = TRUE ;
243 fgState.DisplayMode = GLUT_RGBA | GLUT_SINGLE | GLUT_DEPTH;
245 fgState.ForceDirectContext = FALSE;
246 fgState.TryDirectContext = TRUE;
247 fgState.ForceIconic = FALSE;
248 fgState.UseCurrentContext = FALSE;
249 fgState.GLDebugSwitch = FALSE;
250 fgState.XSyncSwitch = FALSE;
251 fgState.ActionOnWindowClose = GLUT_ACTION_EXIT ;
252 fgState.ExecState = GLUT_EXEC_STATE_INIT ;
254 fgState.IgnoreKeyRepeat = TRUE;
256 fgState.GameModeSize.X = 640;
257 fgState.GameModeSize.Y = 480;
258 fgState.GameModeDepth = 16;
259 fgState.GameModeRefresh = 72;
261 fgState.Time.Set = FALSE ;
263 fgState.Timers.First = fgState.Timers.Last = NULL ;
264 fgState.IdleCallback = NULL ;
265 fgState.MenuStateCallback = (FGCBmenuState)NULL ;
266 fgState.MenuStatusCallback = (FGCBmenuStatus)NULL ;
268 fgState.SwapCount = 0;
269 fgState.SwapTime = 0;
270 fgState.FPSInterval = 0;
272 #if TARGET_HOST_UNIX_X11
275 * Make sure all X-client data we have created will be destroyed on display closing
277 XSetCloseDownMode( fgDisplay.Display, DestroyAll );
280 * Close the display connection, destroying all windows we have created so far
282 XCloseDisplay( fgDisplay.Display );
288 /* -- INTERFACE FUNCTIONS -------------------------------------------------- */
291 * Perform initialization. This usually happens on the program startup
292 * and restarting after glutMainLoop termination...
294 void FGAPIENTRY glutInit( int* pargc, char** argv )
296 char* displayName = NULL;
297 int i, j, argc = *pargc;
299 if (pargc && *pargc && argv && *argv && **argv)
300 fgState.ProgramName = strdup (*argv);
302 fgState.ProgramName = strdup ("");
303 if (!fgState.ProgramName)
304 fgError ("Could not allocate space for the program's name.");
306 if( fgState.Time.Set )
307 fgError( "illegal glutInit() reinitialization attemp" );
311 #if TARGET_HOST_UNIX_X11
312 gettimeofday(&fgState.Time.Value, NULL);
313 #elif TARGET_HOST_WIN32
314 fgState.Time.Value = timeGetTime();
316 fgState.Time.Set = TRUE;
318 /* check if GLUT_FPS env var is set */
320 const char *fps = getenv ( "GLUT_FPS" );
323 sscanf ( fps, "%d", &fgState.FPSInterval ) ;
324 if ( fgState.FPSInterval <= 0 )
325 fgState.FPSInterval = 5000 ; /* 5000 milliseconds */
329 #if TARGET_HOST_WIN32
330 if ( !getenv ( "DISPLAY" ) )
331 displayName = strdup ( "" ) ;
334 displayName = strdup( getenv( "DISPLAY" ) );
336 fgError ("Could not allocate space for display name.");
338 for( i=1; i<argc; i++ )
340 if( strcmp( argv[ i ], "-display" ) == 0 )
343 fgError( "-display parameter must be followed by display name" );
347 displayName = strdup( argv[ i ] );
349 fgError( "Could not allocate space for display name (%s)",
352 argv[ i - 1 ] = NULL;
356 else if( strcmp( argv[ i ], "-geometry" ) == 0 )
362 fgError( "-geometry parameter must be followed by window "
363 "geometry settings" );
364 result = sscanf ( argv[i], "%dx%d+%d+%d", &x, &y, &w, &h );
375 fgDisplay.ScreenHeight + y - fgState.Size.Y;
377 fgState.Position.Y = y;
384 fgDisplay.ScreenWidth + x - fgState.Size.X;
386 fgState.Position.X = x;
389 argv[ i - 1 ] = NULL;
393 else if( strcmp( argv[ i ], "-direct" ) == 0)
395 if( fgState.TryDirectContext == FALSE )
396 fgError( "parameters ambiguity, -direct and -indirect "
397 "cannot be both specified" );
399 fgState.ForceDirectContext = TRUE;
403 else if( strcmp( argv[ i ], "-indirect" ) == 0 )
405 if( fgState.ForceDirectContext == TRUE )
406 fgError( "parameters ambiguity, -direct and -indirect "
407 "cannot be both specified" );
409 fgState.TryDirectContext = FALSE;
413 else if( strcmp( argv[ i ], "-iconic" ) == 0 )
415 fgState.ForceIconic = TRUE;
419 else if( strcmp( argv[ i ], "-gldebug" ) == 0 )
421 fgState.GLDebugSwitch = TRUE;
425 else if( strcmp( argv[ i ], "-sync" ) == 0 )
427 fgState.XSyncSwitch = TRUE;
437 for( i = 1; i < *pargc; i++, j++ )
439 if( argv[ i ] == NULL )
441 /* Guaranteed to end because there are "*pargc" arguments left */
442 while ( argv[j] == NULL )
449 * Have the display created now. As I am too lazy to implement
450 * the program arguments parsing, we will have the DISPLAY
451 * environment variable used for opening the X display:
453 * XXX The above comment is rather unclear. We have just
454 * XXX completed parsing of the program arguments for GLUT
455 * XXX parameters. We obviously canNOT parse the application-
456 * XXX specific parameters. Can someone re-write the above
459 fgInitialize( displayName );
462 * Check for the minus one settings for both position and size...
464 if( fgState.Position.X < 0 || fgState.Position.Y < 0 )
465 fgState.Position.Use = FALSE;
467 if( fgState.Size.X < 0 || fgState.Size.Y < 0 )
468 fgState.Size.Use = FALSE;
475 * Sets the default initial window position for new windows
477 void FGAPIENTRY glutInitWindowPosition( int x, int y )
479 if( (x >= 0) && (y >= 0) )
482 fgState.Position.X = x;
483 fgState.Position.Y = y;
484 fgState.Position.Use = TRUE;
488 fgState.Position.X = -1;
489 fgState.Position.Y = -1;
490 fgState.Position.Use = FALSE;
495 * Sets the default initial window size for new windows
497 void FGAPIENTRY glutInitWindowSize( int width, int height )
499 if( (width > 0) && (height > 0) )
501 fgState.Size.X = width;
502 fgState.Size.Y = height;
503 fgState.Size.Use = TRUE;
509 fgState.Size.Use = FALSE;
514 * Sets the default display mode for all new windows
516 void FGAPIENTRY glutInitDisplayMode( unsigned int displayMode )
519 * We will make use of this value when creating a new OpenGL context...
521 fgState.DisplayMode = displayMode;
525 /* -- INIT DISPLAY STRING PARSING ------------------------------------------ */
527 #if 0 /* FIXME: CJP */
529 * There is a discrete number of comparison operators we can encounter:
531 * comparison ::= "=" | "!=" | "<" | ">" | "<=" | ">=" | "~"
533 #define FG_NONE 0x0000
534 #define FG_EQUAL 0x0001
535 #define FG_NOT_EQUAL 0x0002
536 #define FG_LESS 0x0003
537 #define FG_MORE 0x0004
538 #define FG_LESS_OR_EQUAL 0x0005
539 #define FG_MORE_OR_EQUAL 0x0006
540 #define FG_CLOSEST 0x0007
543 * The caller can feed us with a number of capability tokens:
545 * capability ::= "alpha" | "acca" | "acc" | "blue" | "buffer" | "conformant" | "depth" | "double" |
546 * "green" | "index" | "num" | "red" | "rgba" | "rgb" | "luminance" | "stencil" |
547 * "single" | "stereo" | "samples" | "slow" | "win32pdf" | "xvisual" | "xstaticgray" |
548 * "xgrayscale" | "xstaticcolor" | "xpseudocolor" | "xtruecolor" | "xdirectcolor"
550 static gchar* g_Tokens[] =
552 "none", "alpha", "acca", "acc", "blue", "buffer", "conformant", "depth", "double", "green",
553 "index", "num", "red", "rgba", "rgb", "luminance", "stencil", "single", "stereo", "samples",
554 "slow", "win32pdf", "xvisual", "xstaticgray", "xgrayscale", "xstaticcolor", "xpseudocolor",
555 "xtruecolor", "xdirectcolor", NULL
559 * The structure to hold the parsed display string tokens
561 typedef struct tagSFG_Capability SFG_Capability;
562 struct tagSFG_Capability
564 gint capability; /* the capability token enumerator */
565 gint comparison; /* the comparison operator used */
566 gint value; /* the value we're comparing to */
570 * The scanner configuration for the init display string
572 static GScannerConfig fgInitDisplayStringScannerConfig =
574 ( " \t\r\n" ) /* cset_skip_characters */,
579 ) /* cset_identifier_first */,
587 ) /* cset_identifier_nth */,
588 ( "#\n" ) /* cpair_comment_single */,
589 FALSE /* case_sensitive */,
590 TRUE /* skip_comment_multi */,
591 TRUE /* skip_comment_single */,
592 TRUE /* scan_comment_multi */,
593 TRUE /* scan_identifier */,
594 FALSE /* scan_identifier_1char */,
595 FALSE /* scan_identifier_NULL */,
596 TRUE /* scan_symbols */,
597 FALSE /* scan_binary */,
598 TRUE /* scan_octal */,
599 TRUE /* scan_float */,
601 FALSE /* scan_hex_dollar */,
602 TRUE /* scan_string_sq */,
603 TRUE /* scan_string_dq */,
604 TRUE /* numbers_2_int */,
605 FALSE /* int_2_float */,
606 FALSE /* identifier_2_string */,
607 TRUE /* char_2_token */,
608 FALSE /* symbol_2_token */,
609 FALSE /* scope_0_fallback */,
613 * Sets the default display mode for all new windows using a string
615 void FGAPIENTRY glutInitDisplayString( char* displayMode )
618 * display_string ::= (switch)
619 * switch ::= capability [comparison value]
620 * comparison ::= "=" | "!=" | "<" | ">" | "<=" | ">=" | "~"
621 * capability ::= "alpha" | "acca" | "acc" | "blue" | "buffer" | "conformant" |
622 * "depth" | "double" | "green" | "index" | "num" | "red" | "rgba" |
623 * "rgb" | "luminance" | "stencil" | "single" | "stereo" |
624 * "samples" | "slow" | "win32pdf" | "xvisual" | "xstaticgray" |
625 * "xgrayscale" | "xstaticcolor" | "xpseudocolor" |
626 * "xtruecolor" | "xdirectcolor"
627 * value ::= 0..9 [value]
629 * The display string grammar. This should be EBNF, but I couldn't find the definitions so, to
630 * clarify: (expr) means 0 or more times the expression, [expr] means 0 or 1 times expr.
632 * Create a new GLib lexical analyzer to process the display mode string
634 GScanner* scanner = g_scanner_new( &fgInitDisplayStringScannerConfig );
639 * Fail if the display mode string is empty or the scanner failed to initialize
641 freeglut_return_if_fail( (scanner != NULL) && (strlen( displayMode ) > 0) );
644 * Set the scanner's input name (for debugging)
646 scanner->input_name = "glutInitDisplayString";
649 * Start the lexical analysis of the extensions string
651 g_scanner_input_text( scanner, displayMode, strlen( displayMode ) );
654 * While there are any more tokens to be checked...
656 while( !g_scanner_eof( scanner ) )
659 * Actually we're expecting only string tokens
661 GTokenType tokenType = g_scanner_get_next_token( scanner );
664 * We are looking for identifiers
666 if( tokenType == G_TOKEN_IDENTIFIER )
668 gchar* capability = NULL; /* the capability identifier string (always present) */
669 gint capID = 0; /* the capability identifier value (from g_Tokens) */
670 gint comparison = 0; /* the comparison operator value, see definitions */
671 gchar* valueString = NULL; /* if the previous one is present, this is needed */
672 gint value = 0; /* the integer value converted using a strtol call */
673 SFG_Capability* capStruct; /* the capability description structure */
676 * OK. The general rule of thumb that we always should be getting a capability identifier
677 * string (see the grammar description). If it is followed by a comparison identifier, then
678 * there must follow an integer value we're comparing the capability to...
680 * Have the current token analyzed with that in mind...
682 for( i=0; i<(gint) strlen( scanner->value.v_identifier ); i++ )
684 gchar c = scanner->value.v_identifier[ i ];
686 if( (c == '=') || (c == '!') || (c == '<') || (c == '>') || (c == '~') )
691 * Here we go with the length of the capability identifier string.
692 * In the worst of cases, it is as long as the token identifier.
694 capability = g_strndup( scanner->value.v_identifier, i );
697 * OK. Is there a chance for comparison and value identifiers to follow?
698 * Note: checking against i+1 as this handles two cases: single character
699 * comparison operator and first of value's digits, which must always be
700 * there, or the two-character comparison operators.
702 if( (i + 1) < (gint) strlen( scanner->value.v_identifier ) )
705 * Yeah, indeed, it is the i-th character to start the identifier, then.
707 gchar c1 = scanner->value.v_identifier[ i + 0 ];
708 gchar c2 = scanner->value.v_identifier[ i + 1 ];
710 if( (c1 == '=') ) { i += 1; comparison = FG_EQUAL; } else
711 if( (c1 == '!') && (c2 == '=') ) { i += 2; comparison = FG_NOT_EQUAL; } else
712 if( (c1 == '<') && (c2 == '=') ) { i += 2; comparison = FG_LESS_OR_EQUAL; } else
713 if( (c1 == '>') && (c2 == '=') ) { i += 2; comparison = FG_MORE_OR_EQUAL; } else
714 if( (c1 == '<') ) { i += 1; comparison = FG_LESS; } else
715 if( (c1 == '>') ) { i += 1; comparison = FG_MORE; } else
716 if( (c1 == '~') ) { i += 1; comparison = FG_CLOSEST; } else
717 g_warning( "invalid comparison operator in token `%s'", scanner->value.v_identifier );
721 * Grab the value string that must follow the comparison operator...
723 if( comparison != FG_NONE && i < (gint) strlen( scanner->value.v_identifier ) )
725 valueString = strdup( scanner->value.v_identifier + i );
727 fgError ("Could not allocate an internal string.");
731 * If there was a value string, convert it to integer...
733 if( comparison != FG_NONE && strlen( valueString ) > 0 )
734 value = strtol( valueString, NULL, 0 );
737 * Now we need to match the capability string and its ID
739 for( i=0; g_Tokens[ i ]!=NULL; i++ )
741 if( strcmp( capability, g_Tokens[ i ] ) == 0 )
744 * Looks like we've found the one we were looking for
752 * Create a new capability description structure
754 capStruct = g_new0( SFG_Capability, 1 );
757 * Fill in the cap's values, as we have parsed it:
759 capStruct->capability = capID;
760 capStruct->comparison = comparison;
761 capStruct->value = value;
764 * Add the new capabaility to the caps list
766 caps = g_list_append( caps, capStruct );
769 * Clean up the local mess and keep rolling on
771 g_free( valueString );
772 g_free( capability );
777 * Now that we have converted the string into somewhat more machine-friendly
778 * form, proceed with matching the frame buffer configuration...
780 * The caps list could be passed to a function that would try finding the closest
781 * matching pixel format, visual, frame buffer configuration or whatever. It would
782 * be good to convert the glutInitDisplayMode() to use the same method.
785 g_message( "found %i capability preferences", g_list_length( caps ) );
787 g_message( "token `%s': cap: %i, com: %i, val: %i",
788 scanner->value.v_identifier,
789 capStruct->capability,
790 capStruct->comparison,
796 * Free the capabilities we have parsed
798 for( i=0; i<(gint) g_list_length( caps ); i++ )
799 g_free( g_list_nth( caps, i )->data );
802 * Destroy the capabilities list itself
807 * Free the lexical scanner now...
809 g_scanner_destroy( scanner );
813 #define NUM_TOKENS 28
814 static char* Tokens[] =
816 "alpha", "acca", "acc", "blue", "buffer", "conformant", "depth", "double", "green",
817 "index", "num", "red", "rgba", "rgb", "luminance", "stencil", "single", "stereo", "samples",
818 "slow", "win32pdf", "xvisual", "xstaticgray", "xgrayscale", "xstaticcolor", "xpseudocolor",
819 "xtruecolor", "xdirectcolor"
822 static int TokenLengths[] =
824 5, 4, 3, 4, 6, 10, 5, 6, 5,
825 5, 3, 3, 4, 3, 9, 7, 6, 6, 7,
826 4, 8, 7, 11, 10, 12, 12,
830 void FGAPIENTRY glutInitDisplayString( const char* displayMode )
832 int glut_state_flag = 0 ;
834 * Unpack a lot of options from a character string. The options are delimited by blanks or tabs.
837 int len = strlen ( displayMode ) ;
838 char *buffer = (char *)malloc ( (len+1) * sizeof(char) ) ;
839 memcpy ( buffer, displayMode, len ) ;
842 token = strtok ( buffer, " \t" ) ;
849 for ( i = 0; i < NUM_TOKENS; i++ )
851 if ( strncmp ( token, Tokens[i], TokenLengths[i] ) == 0 ) break ;
856 case 0 : /* "alpha": Alpha color buffer precision in bits */
857 glut_state_flag |= GLUT_ALPHA ; /* Somebody fix this for me! */
860 case 1 : /* "acca": Red, green, blue, and alpha accumulation buffer precision in bits */
863 case 2 : /* "acc": Red, green, and blue accumulation buffer precision in bits with zero bits alpha */
864 glut_state_flag |= GLUT_ACCUM ; /* Somebody fix this for me! */
867 case 3 : /* "blue": Blue color buffer precision in bits */
870 case 4 : /* "buffer": Number of bits in the color index color buffer */
873 case 5 : /* "conformant": Boolean indicating if the frame buffer configuration is conformant or not */
876 case 6 : /* "depth": Number of bits of precsion in the depth buffer */
877 glut_state_flag |= GLUT_DEPTH ; /* Somebody fix this for me! */
880 case 7 : /* "double": Boolean indicating if the color buffer is double buffered */
881 glut_state_flag |= GLUT_DOUBLE ;
884 case 8 : /* "green": Green color buffer precision in bits */
887 case 9 : /* "index": Boolean if the color model is color index or not */
888 glut_state_flag |= GLUT_INDEX ;
891 case 10 : /* "num": A special capability name indicating where the value represents the Nth frame buffer configuration matching the description string */
894 case 11 : /* "red": Red color buffer precision in bits */
897 case 12 : /* "rgba": Number of bits of red, green, blue, and alpha in the RGBA color buffer */
898 glut_state_flag |= GLUT_RGBA ; /* Somebody fix this for me! */
901 case 13 : /* "rgb": Number of bits of red, green, and blue in the RGBA color buffer with zero bits alpha */
902 glut_state_flag |= GLUT_RGB ; /* Somebody fix this for me! */
905 case 14 : /* "luminance": Number of bits of red in the RGBA and zero bits of green, blue (alpha not specified) of color buffer precision */
906 glut_state_flag |= GLUT_LUMINANCE ; /* Somebody fix this for me! */
909 case 15 : /* "stencil": Number of bits in the stencil buffer */
910 glut_state_flag |= GLUT_STENCIL ; /* Somebody fix this for me! */
913 case 16 : /* "single": Boolean indicate the color buffer is single buffered */
914 glut_state_flag |= GLUT_SINGLE ;
917 case 17 : /* "stereo": Boolean indicating the color buffer supports OpenGL-style stereo */
918 glut_state_flag |= GLUT_STEREO ;
921 case 18 : /* "samples": Indicates the number of multisamples to use based on GLX's SGIS_multisample extension (for antialiasing) */
922 glut_state_flag |= GLUT_MULTISAMPLE ; /* Somebody fix this for me! */
925 case 19 : /* "slow": Boolean indicating if the frame buffer configuration is slow or not */
928 case 20 : /* "win32pdf": matches the Win32 Pixel Format Descriptor by number */
929 #if TARGET_HOST_WIN32
933 case 21 : /* "xvisual": matches the X visual ID by number */
934 #if TARGET_HOST_UNIX_X11
938 case 22 : /* "xstaticgray": boolean indicating if the frame buffer configuration's X visual is of type StaticGray */
939 #if TARGET_HOST_UNIX_X11
943 case 23 : /* "xgrayscale": boolean indicating if the frame buffer configuration's X visual is of type GrayScale */
944 #if TARGET_HOST_UNIX_X11
948 case 24 : /* "xstaticcolor": boolean indicating if the frame buffer configuration's X visual is of type StaticColor */
949 #if TARGET_HOST_UNIX_X11
953 case 25 : /* "xpseudocolor": boolean indicating if the frame buffer configuration's X visual is of type PseudoColor */
954 #if TARGET_HOST_UNIX_X11
958 case 26 : /* "xtruecolor": boolean indicating if the frame buffer configuration's X visual is of type TrueColor */
959 #if TARGET_HOST_UNIX_X11
963 case 27 : /* "xdirectcolor": boolean indicating if the frame buffer configuration's X visual is of type DirectColor */
964 #if TARGET_HOST_UNIX_X11
968 case 28 : /* Unrecognized */
969 printf ( "WARNING - Display string token not recognized: %s\n", token ) ;
973 token = strtok ( NULL, " \t" ) ;
979 * We will make use of this value when creating a new OpenGL context...
981 fgState.DisplayMode = glut_state_flag;
984 /*** END OF FILE ***/