4 * Various freeglut initialization functions.
\r
6 * Copyright (c) 1999-2000 Pawel W. Olszta. All Rights Reserved.
\r
7 * Written by Pawel W. Olszta, <olszta@sourceforge.net>
\r
8 * Creation date: Thu Dec 2 1999
\r
10 * Permission is hereby granted, free of charge, to any person obtaining a
\r
11 * copy of this software and associated documentation files (the "Software"),
\r
12 * to deal in the Software without restriction, including without limitation
\r
13 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
\r
14 * and/or sell copies of the Software, and to permit persons to whom the
\r
15 * Software is furnished to do so, subject to the following conditions:
\r
17 * The above copyright notice and this permission notice shall be included
\r
18 * in all copies or substantial portions of the Software.
\r
20 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
\r
21 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
\r
22 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
\r
23 * PAWEL W. OLSZTA BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
\r
24 * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
\r
25 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
\r
28 #define FREEGLUT_BUILDING_LIB
\r
29 #include <GL/freeglut.h>
\r
30 #include "freeglut_internal.h"
\r
32 #if TARGET_HOST_POSIX_X11
\r
33 #include <limits.h> /* LONG_MAX */
\r
37 * TODO BEFORE THE STABLE RELEASE:
\r
39 * fgDeinitialize() -- Win32's OK, X11 needs the OS-specific
\r
40 * deinitialization done
\r
41 * glutInitDisplayString() -- display mode string parsing
\r
43 * Wouldn't it be cool to use gettext() for error messages? I just love
\r
44 * bash saying "nie znaleziono pliku" instead of "file not found" :)
\r
45 * Is gettext easily portable?
\r
48 /* -- GLOBAL VARIABLES ----------------------------------------------------- */
\r
51 * A structure pointed by g_pDisplay holds all information
\r
52 * regarding the display, screen, root window etc.
\r
54 SFG_Display fgDisplay;
\r
57 * The settings for the current freeglut session
\r
59 SFG_State fgState = { { -1, -1, GL_FALSE }, /* Position */
\r
60 { 300, 300, GL_TRUE }, /* Size */
\r
61 GLUT_RGBA | GLUT_SINGLE | GLUT_DEPTH, /* DisplayMode */
\r
62 GL_FALSE, /* Initialised */
\r
63 GLUT_TRY_DIRECT_CONTEXT, /* DirectContext */
\r
64 GL_FALSE, /* ForceIconic */
\r
65 GL_FALSE, /* UseCurrentContext */
\r
66 GL_FALSE, /* GLDebugSwitch */
\r
67 GL_FALSE, /* XSyncSwitch */
\r
68 GLUT_KEY_REPEAT_ON, /* KeyRepeat */
\r
69 INVALID_MODIFIERS, /* Modifiers */
\r
70 0, /* FPSInterval */
\r
74 { NULL, NULL }, /* Timers */
\r
75 { NULL, NULL }, /* FreeTimers */
\r
76 NULL, /* IdleCallback */
\r
77 0, /* ActiveMenus */
\r
78 NULL, /* MenuStateCallback */
\r
79 NULL, /* MenuStatusCallback */
\r
80 { 640, 480, GL_TRUE }, /* GameModeSize */
\r
81 16, /* GameModeDepth */
\r
82 72, /* GameModeRefresh */
\r
83 GLUT_ACTION_EXIT, /* ActionOnWindowClose */
\r
84 GLUT_EXEC_STATE_INIT, /* ExecState */
\r
85 NULL, /* ProgramName */
\r
86 GL_FALSE, /* JoysticksInitialised */
\r
87 0, /* NumActiveJoysticks */
\r
88 GL_FALSE, /* InputDevsInitialised */
\r
89 0, /* MouseWheelTicks */
\r
90 1, /* AuxiliaryBufferNumber */
\r
91 4, /* SampleNumber */
\r
92 1, /* MajorVersion */
\r
93 0, /* MinorVersion */
\r
94 0, /* ContextFlags */
\r
95 0, /* ContextProfile */
\r
96 NULL, /* ErrorFunc */
\r
97 NULL /* WarningFunc */
\r
101 /* -- PRIVATE FUNCTIONS ---------------------------------------------------- */
\r
103 extern void fghInitialize( const char* displayName );
\r
104 extern void fghDeinitialiseInputDevices ( void );
\r
105 extern void fghCloseDisplay ( void );
\r
107 #if TARGET_HOST_POSIX_X11
\r
109 /* Return the atom associated with "name". */
\r
110 static Atom fghGetAtom(const char * name)
\r
112 return XInternAtom(fgDisplay.Display, name, False);
\r
116 * Check if "property" is set on "window". The property's values are returned
\r
117 * through "data". If the property is set and is of type "type", return the
\r
118 * number of elements in "data". Return zero otherwise. In both cases, use
\r
119 * "Xfree()" to free "data".
\r
121 static int fghGetWindowProperty(Window window,
\r
124 unsigned char ** data)
\r
127 * Caller always has to use "Xfree()" to free "data", since
\r
128 * "XGetWindowProperty() always allocates one extra byte in prop_return
\r
129 * [i.e. "data"] (even if the property is zero length) [..]".
\r
132 int status; /* Returned by "XGetWindowProperty". */
\r
134 Atom type_returned;
\r
135 int temp_format; /* Not used. */
\r
136 unsigned long number_of_elements;
\r
137 unsigned long temp_bytes_after; /* Not used. */
\r
140 status = XGetWindowProperty(fgDisplay.Display,
\r
149 &number_of_elements,
\r
153 FREEGLUT_INTERNAL_ERROR_EXIT(status == Success,
\r
154 "XGetWindowProperty failled",
\r
155 "fghGetWindowProperty");
\r
157 if (type_returned != type)
\r
159 number_of_elements = 0;
\r
162 return number_of_elements;
\r
165 /* Check if the window manager is NET WM compliant. */
\r
166 static int fghNetWMSupported(void)
\r
169 Window ** window_ptr_1;
\r
171 int number_of_windows;
\r
172 int net_wm_supported;
\r
175 net_wm_supported = 0;
\r
177 wm_check = fghGetAtom("_NET_SUPPORTING_WM_CHECK");
\r
178 window_ptr_1 = malloc(sizeof(Window *));
\r
181 * Check that the window manager has set this property on the root window.
\r
182 * The property must be the ID of a child window.
\r
184 number_of_windows = fghGetWindowProperty(fgDisplay.RootWindow,
\r
187 (unsigned char **) window_ptr_1);
\r
188 if (number_of_windows == 1)
\r
190 Window ** window_ptr_2;
\r
192 window_ptr_2 = malloc(sizeof(Window *));
\r
194 /* Check that the window has the same property set to the same value. */
\r
195 number_of_windows = fghGetWindowProperty(**window_ptr_1,
\r
198 (unsigned char **) window_ptr_2);
\r
199 if ((number_of_windows == 1) && (**window_ptr_1 == **window_ptr_2))
\r
201 /* NET WM compliant */
\r
202 net_wm_supported = 1;
\r
205 XFree(*window_ptr_2);
\r
206 free(window_ptr_2);
\r
209 XFree(*window_ptr_1);
\r
210 free(window_ptr_1);
\r
212 return net_wm_supported;
\r
215 /* Check if "hint" is present in "property" for "window". */
\r
216 int fgHintPresent(Window window, Atom property, Atom hint)
\r
219 int number_of_atoms;
\r
225 number_of_atoms = fghGetWindowProperty(window,
\r
228 (unsigned char **) &atoms);
\r
229 for (i = 0; i < number_of_atoms; i++)
\r
231 if (atoms[i] == hint)
\r
242 #endif /* TARGET_HOST_POSIX_X11 */
\r
245 #if TARGET_HOST_POSIX_X11
\r
247 * A call to this function should initialize all the display stuff...
\r
249 static void fghInitialize( const char* displayName )
\r
251 fgDisplay.Display = XOpenDisplay( displayName );
\r
253 if( fgDisplay.Display == NULL )
\r
254 fgError( "failed to open display '%s'", XDisplayName( displayName ) );
\r
256 if( !glXQueryExtension( fgDisplay.Display, NULL, NULL ) )
\r
257 fgError( "OpenGL GLX extension not supported by display '%s'",
\r
258 XDisplayName( displayName ) );
\r
260 fgDisplay.Screen = DefaultScreen( fgDisplay.Display );
\r
261 fgDisplay.RootWindow = RootWindow(
\r
266 fgDisplay.ScreenWidth = DisplayWidth(
\r
270 fgDisplay.ScreenHeight = DisplayHeight(
\r
275 fgDisplay.ScreenWidthMM = DisplayWidthMM(
\r
279 fgDisplay.ScreenHeightMM = DisplayHeightMM(
\r
284 fgDisplay.Connection = ConnectionNumber( fgDisplay.Display );
\r
286 /* Create the window deletion atom */
\r
287 fgDisplay.DeleteWindow = fghGetAtom("WM_DELETE_WINDOW");
\r
289 /* Create the state and full screen atoms */
\r
290 fgDisplay.State = None;
\r
291 fgDisplay.StateFullScreen = None;
\r
293 if (fghNetWMSupported())
\r
295 const Atom supported = fghGetAtom("_NET_SUPPORTED");
\r
296 const Atom state = fghGetAtom("_NET_WM_STATE");
\r
298 /* Check if the state hint is supported. */
\r
299 if (fgHintPresent(fgDisplay.RootWindow, supported, state))
\r
301 const Atom full_screen = fghGetAtom("_NET_WM_STATE_FULLSCREEN");
\r
303 fgDisplay.State = state;
\r
305 /* Check if the window manager supports full screen. */
\r
306 /** Check "_NET_WM_ALLOWED_ACTIONS" on our window instead? **/
\r
307 if (fgHintPresent(fgDisplay.RootWindow, supported, full_screen))
\r
309 fgDisplay.StateFullScreen = full_screen;
\r
315 fgState.Initialised = GL_TRUE;
\r
317 atexit(fgDeinitialize);
\r
319 /* InputDevice uses GlutTimerFunc(), so fgState.Initialised must be TRUE */
\r
320 fgInitialiseInputDevices();
\r
326 void fghParseCommandLineArguments ( int* pargc, char** argv, char **pDisplayName, char **pGeometry )
\r
329 int i, j, argc = *pargc;
\r
332 /* check if GLUT_FPS env var is set */
\r
333 const char *fps = getenv( "GLUT_FPS" );
\r
338 sscanf( fps, "%d", &interval );
\r
340 if( interval <= 0 )
\r
341 fgState.FPSInterval = 5000; /* 5000 millisecond default */
\r
343 fgState.FPSInterval = interval;
\r
347 *pDisplayName = getenv( "DISPLAY" );
\r
349 for( i = 1; i < argc; i++ )
\r
351 if( strcmp( argv[ i ], "-display" ) == 0 )
\r
354 fgError( "-display parameter must be followed by display name" );
\r
356 *pDisplayName = argv[ i ];
\r
358 argv[ i - 1 ] = NULL;
\r
362 else if( strcmp( argv[ i ], "-geometry" ) == 0 )
\r
365 fgError( "-geometry parameter must be followed by window "
\r
366 "geometry settings" );
\r
368 *pGeometry = argv[ i ];
\r
370 argv[ i - 1 ] = NULL;
\r
374 else if( strcmp( argv[ i ], "-direct" ) == 0)
\r
376 if( fgState.DirectContext == GLUT_FORCE_INDIRECT_CONTEXT )
\r
377 fgError( "parameters ambiguity, -direct and -indirect "
\r
378 "cannot be both specified" );
\r
380 fgState.DirectContext = GLUT_FORCE_DIRECT_CONTEXT;
\r
384 else if( strcmp( argv[ i ], "-indirect" ) == 0 )
\r
386 if( fgState.DirectContext == GLUT_FORCE_DIRECT_CONTEXT )
\r
387 fgError( "parameters ambiguity, -direct and -indirect "
\r
388 "cannot be both specified" );
\r
390 fgState.DirectContext = GLUT_FORCE_INDIRECT_CONTEXT;
\r
394 else if( strcmp( argv[ i ], "-iconic" ) == 0 )
\r
396 fgState.ForceIconic = GL_TRUE;
\r
400 else if( strcmp( argv[ i ], "-gldebug" ) == 0 )
\r
402 fgState.GLDebugSwitch = GL_TRUE;
\r
406 else if( strcmp( argv[ i ], "-sync" ) == 0 )
\r
408 fgState.XSyncSwitch = GL_TRUE;
\r
414 /* Compact {argv}. */
\r
415 for( i = j = 1; i < *pargc; i++, j++ )
\r
417 /* Guaranteed to end because there are "*pargc" arguments left */
\r
418 while ( argv[ j ] == NULL )
\r
421 argv[ i ] = argv[ j ];
\r
424 #endif /* _WIN32_WCE */
\r
429 void fghCloseInputDevices ( void )
\r
431 if ( fgState.JoysticksInitialised )
\r
432 fgJoystickClose( );
\r
434 if ( fgState.InputDevsInitialised )
\r
435 fgInputDeviceClose( );
\r
439 #if TARGET_HOST_POSIX_X11
\r
440 static void fghDeinitialiseInputDevices ( void )
\r
442 fghCloseInputDevices ();
\r
444 fgState.JoysticksInitialised = GL_FALSE;
\r
445 fgState.InputDevsInitialised = GL_FALSE;
\r
449 static void fghCloseDisplay ( void )
\r
452 * Make sure all X-client data we have created will be destroyed on
\r
455 XSetCloseDownMode( fgDisplay.Display, DestroyAll );
\r
458 * Close the display connection, destroying all windows we have
\r
461 XCloseDisplay( fgDisplay.Display );
\r
468 * Perform the freeglut deinitialization...
\r
470 void fgDeinitialize( void )
\r
474 if( !fgState.Initialised )
\r
479 /* If we're in game mode, we want to leave game mode */
\r
480 if( fgStructure.GameModeWindow ) {
\r
481 glutLeaveGameMode();
\r
484 /* If there was a menu created, destroy the rendering context */
\r
485 if( fgStructure.MenuContext )
\r
487 #if TARGET_HOST_POSIX_X11
\r
488 /* Note that the MVisualInfo is not owned by the MenuContext! */
\r
489 glXDestroyContext( fgDisplay.Display, fgStructure.MenuContext->MContext );
\r
491 free( fgStructure.MenuContext );
\r
492 fgStructure.MenuContext = NULL;
\r
495 fgDestroyStructure( );
\r
497 while( ( timer = fgState.Timers.First) )
\r
499 fgListRemove( &fgState.Timers, &timer->Node );
\r
503 while( ( timer = fgState.FreeTimers.First) )
\r
505 fgListRemove( &fgState.FreeTimers, &timer->Node );
\r
509 fghDeinitialiseInputDevices ();
\r
511 fgState.MouseWheelTicks = 0;
\r
513 fgState.MajorVersion = 1;
\r
514 fgState.MinorVersion = 0;
\r
515 fgState.ContextFlags = 0;
\r
516 fgState.ContextProfile = 0;
\r
518 fgState.Initialised = GL_FALSE;
\r
520 fgState.Position.X = -1;
\r
521 fgState.Position.Y = -1;
\r
522 fgState.Position.Use = GL_FALSE;
\r
524 fgState.Size.X = 300;
\r
525 fgState.Size.Y = 300;
\r
526 fgState.Size.Use = GL_TRUE;
\r
528 fgState.DisplayMode = GLUT_RGBA | GLUT_SINGLE | GLUT_DEPTH;
\r
530 fgState.DirectContext = GLUT_TRY_DIRECT_CONTEXT;
\r
531 fgState.ForceIconic = GL_FALSE;
\r
532 fgState.UseCurrentContext = GL_FALSE;
\r
533 fgState.GLDebugSwitch = GL_FALSE;
\r
534 fgState.XSyncSwitch = GL_FALSE;
\r
535 fgState.ActionOnWindowClose = GLUT_ACTION_EXIT;
\r
536 fgState.ExecState = GLUT_EXEC_STATE_INIT;
\r
538 fgState.KeyRepeat = GLUT_KEY_REPEAT_ON;
\r
539 fgState.Modifiers = INVALID_MODIFIERS;
\r
541 fgState.GameModeSize.X = 640;
\r
542 fgState.GameModeSize.Y = 480;
\r
543 fgState.GameModeDepth = 16;
\r
544 fgState.GameModeRefresh = 72;
\r
546 fgListInit( &fgState.Timers );
\r
547 fgListInit( &fgState.FreeTimers );
\r
549 fgState.IdleCallback = NULL;
\r
550 fgState.MenuStateCallback = ( FGCBMenuState )NULL;
\r
551 fgState.MenuStatusCallback = ( FGCBMenuStatus )NULL;
\r
553 fgState.SwapCount = 0;
\r
554 fgState.SwapTime = 0;
\r
555 fgState.FPSInterval = 0;
\r
557 if( fgState.ProgramName )
\r
559 free( fgState.ProgramName );
\r
560 fgState.ProgramName = NULL;
\r
563 fghCloseDisplay ();
\r
565 fgState.Initialised = GL_FALSE;
\r
569 #if defined TARGET_HOST_MS_WINDOWS
\r
570 #define NoValue 0x0000
\r
571 #define XValue 0x0001
\r
572 #define YValue 0x0002
\r
573 #define WidthValue 0x0004
\r
574 #define HeightValue 0x0008
\r
575 #define AllValues 0x000F
\r
576 #define XNegative 0x0010
\r
577 #define YNegative 0x0020
\r
579 extern int XParseGeometry (
\r
580 const char *string,
\r
583 unsigned int *width, /* RETURN */
\r
584 unsigned int *height); /* RETURN */
\r
587 /* -- INTERFACE FUNCTIONS -------------------------------------------------- */
\r
590 * Perform initialization. This usually happens on the program startup
\r
591 * and restarting after glutMainLoop termination...
\r
593 void FGAPIENTRY glutInit( int* pargc, char** argv )
\r
595 char* displayName = NULL;
\r
596 char* geometry = NULL;
\r
597 if( fgState.Initialised )
\r
598 fgError( "illegal glutInit() reinitialization attempt" );
\r
600 if (pargc && *pargc && argv && *argv && **argv)
\r
602 fgState.ProgramName = strdup (*argv);
\r
604 if( !fgState.ProgramName )
\r
605 fgError ("Could not allocate space for the program's name.");
\r
608 fgCreateStructure( );
\r
610 /* Get start time */
\r
611 fgState.Time = fgSystemTime();
\r
613 fghParseCommandLineArguments ( pargc, argv, &displayName, &geometry );
\r
616 * Have the display created now. If there wasn't a "-display"
\r
617 * in the program arguments, we will use the DISPLAY environment
\r
618 * variable for opening the X display (see code above):
\r
620 fghInitialize( displayName );
\r
623 * Geometry parsing deffered until here because we may need the screen
\r
629 unsigned int parsedWidth, parsedHeight;
\r
630 int mask = XParseGeometry( geometry,
\r
631 &fgState.Position.X, &fgState.Position.Y,
\r
632 &parsedWidth, &parsedHeight );
\r
633 /* TODO: Check for overflow? */
\r
634 fgState.Size.X = parsedWidth;
\r
635 fgState.Size.Y = parsedHeight;
\r
637 if( (mask & (WidthValue|HeightValue)) == (WidthValue|HeightValue) )
\r
638 fgState.Size.Use = GL_TRUE;
\r
640 if( mask & XNegative )
\r
641 fgState.Position.X += fgDisplay.ScreenWidth - fgState.Size.X;
\r
643 if( mask & YNegative )
\r
644 fgState.Position.Y += fgDisplay.ScreenHeight - fgState.Size.Y;
\r
646 if( (mask & (XValue|YValue)) == (XValue|YValue) )
\r
647 fgState.Position.Use = GL_TRUE;
\r
651 #if TARGET_HOST_MS_WINDOWS
\r
652 void (__cdecl *__glutExitFunc)( int return_value ) = NULL;
\r
654 void FGAPIENTRY __glutInitWithExit( int *pargc, char **argv, void (__cdecl *exit_function)(int) )
\r
656 __glutExitFunc = exit_function;
\r
657 glutInit(pargc, argv);
\r
662 * Undoes all the "glutInit" stuff
\r
664 void FGAPIENTRY glutExit ( void )
\r
670 * Sets the default initial window position for new windows
\r
672 void FGAPIENTRY glutInitWindowPosition( int x, int y )
\r
674 fgState.Position.X = x;
\r
675 fgState.Position.Y = y;
\r
677 if( ( x >= 0 ) && ( y >= 0 ) )
\r
678 fgState.Position.Use = GL_TRUE;
\r
680 fgState.Position.Use = GL_FALSE;
\r
684 * Sets the default initial window size for new windows
\r
686 void FGAPIENTRY glutInitWindowSize( int width, int height )
\r
688 fgState.Size.X = width;
\r
689 fgState.Size.Y = height;
\r
691 if( ( width > 0 ) && ( height > 0 ) )
\r
692 fgState.Size.Use = GL_TRUE;
\r
694 fgState.Size.Use = GL_FALSE;
\r
698 * Sets the default display mode for all new windows
\r
700 void FGAPIENTRY glutInitDisplayMode( unsigned int displayMode )
\r
702 /* We will make use of this value when creating a new OpenGL context... */
\r
703 fgState.DisplayMode = displayMode;
\r
707 /* -- INIT DISPLAY STRING PARSING ------------------------------------------ */
\r
709 static char* Tokens[] =
\r
711 "alpha", "acca", "acc", "blue", "buffer", "conformant", "depth", "double",
\r
712 "green", "index", "num", "red", "rgba", "rgb", "luminance", "stencil",
\r
713 "single", "stereo", "samples", "slow", "win32pdf", "win32pfd", "xvisual",
\r
714 "xstaticgray", "xgrayscale", "xstaticcolor", "xpseudocolor",
\r
715 "xtruecolor", "xdirectcolor",
\r
716 "xstaticgrey", "xgreyscale", "xstaticcolour", "xpseudocolour",
\r
717 "xtruecolour", "xdirectcolour", "borderless", "aux"
\r
719 #define NUM_TOKENS (sizeof(Tokens) / sizeof(*Tokens))
\r
721 void FGAPIENTRY glutInitDisplayString( const char* displayMode )
\r
723 int glut_state_flag = 0 ;
\r
725 * Unpack a lot of options from a character string. The options are
\r
726 * delimited by blanks or tabs.
\r
729 size_t len = strlen ( displayMode );
\r
730 char *buffer = (char *)malloc ( (len+1) * sizeof(char) );
\r
731 memcpy ( buffer, displayMode, len );
\r
732 buffer[len] = '\0';
\r
734 token = strtok ( buffer, " \t" );
\r
738 /* Process this token */
\r
741 /* Temporary fix: Ignore any length specifications and at least
\r
742 * process the basic token
\r
743 * TODO: Fix this permanently
\r
745 size_t cleanlength = strcspn ( token, "=<>~!" );
\r
747 for ( i = 0; i < NUM_TOKENS; i++ )
\r
749 if ( strncmp ( token, Tokens[i], cleanlength ) == 0 ) break ;
\r
754 case 0 : /* "alpha": Alpha color buffer precision in bits */
\r
755 glut_state_flag |= GLUT_ALPHA ; /* Somebody fix this for me! */
\r
758 case 1 : /* "acca": Red, green, blue, and alpha accumulation buffer
\r
759 precision in bits */
\r
762 case 2 : /* "acc": Red, green, and blue accumulation buffer precision
\r
763 in bits with zero bits alpha */
\r
764 glut_state_flag |= GLUT_ACCUM ; /* Somebody fix this for me! */
\r
767 case 3 : /* "blue": Blue color buffer precision in bits */
\r
770 case 4 : /* "buffer": Number of bits in the color index color buffer
\r
774 case 5 : /* "conformant": Boolean indicating if the frame buffer
\r
775 configuration is conformant or not */
\r
778 case 6 : /* "depth": Number of bits of precsion in the depth buffer */
\r
779 glut_state_flag |= GLUT_DEPTH ; /* Somebody fix this for me! */
\r
782 case 7 : /* "double": Boolean indicating if the color buffer is
\r
784 glut_state_flag |= GLUT_DOUBLE ;
\r
787 case 8 : /* "green": Green color buffer precision in bits */
\r
790 case 9 : /* "index": Boolean if the color model is color index or not
\r
792 glut_state_flag |= GLUT_INDEX ;
\r
795 case 10 : /* "num": A special capability name indicating where the
\r
796 value represents the Nth frame buffer configuration
\r
797 matching the description string */
\r
800 case 11 : /* "red": Red color buffer precision in bits */
\r
803 case 12 : /* "rgba": Number of bits of red, green, blue, and alpha in
\r
804 the RGBA color buffer */
\r
805 glut_state_flag |= GLUT_RGBA ; /* Somebody fix this for me! */
\r
808 case 13 : /* "rgb": Number of bits of red, green, and blue in the
\r
809 RGBA color buffer with zero bits alpha */
\r
810 glut_state_flag |= GLUT_RGB ; /* Somebody fix this for me! */
\r
813 case 14 : /* "luminance": Number of bits of red in the RGBA and zero
\r
814 bits of green, blue (alpha not specified) of color buffer
\r
816 glut_state_flag |= GLUT_LUMINANCE ; /* Somebody fix this for me! */
\r
819 case 15 : /* "stencil": Number of bits in the stencil buffer */
\r
820 glut_state_flag |= GLUT_STENCIL; /* Somebody fix this for me! */
\r
823 case 16 : /* "single": Boolean indicate the color buffer is single
\r
825 glut_state_flag |= GLUT_SINGLE ;
\r
828 case 17 : /* "stereo": Boolean indicating the color buffer supports
\r
829 OpenGL-style stereo */
\r
830 glut_state_flag |= GLUT_STEREO ;
\r
833 case 18 : /* "samples": Indicates the number of multisamples to use
\r
834 based on GLX's SGIS_multisample extension (for
\r
836 glut_state_flag |= GLUT_MULTISAMPLE ; /*Somebody fix this for me!*/
\r
839 case 19 : /* "slow": Boolean indicating if the frame buffer
\r
840 configuration is slow or not */
\r
843 case 20 : /* "win32pdf": (incorrect spelling but was there before */
\r
844 case 21 : /* "win32pfd": matches the Win32 Pixel Format Descriptor by
\r
846 #if TARGET_HOST_MS_WINDOWS
\r
850 case 22 : /* "xvisual": matches the X visual ID by number */
\r
851 #if TARGET_HOST_POSIX_X11
\r
855 case 23 : /* "xstaticgray": */
\r
856 case 29 : /* "xstaticgrey": boolean indicating if the frame buffer
\r
857 configuration's X visual is of type StaticGray */
\r
858 #if TARGET_HOST_POSIX_X11
\r
862 case 24 : /* "xgrayscale": */
\r
863 case 30 : /* "xgreyscale": boolean indicating if the frame buffer
\r
864 configuration's X visual is of type GrayScale */
\r
865 #if TARGET_HOST_POSIX_X11
\r
869 case 25 : /* "xstaticcolor": */
\r
870 case 31 : /* "xstaticcolour": boolean indicating if the frame buffer
\r
871 configuration's X visual is of type StaticColor */
\r
872 #if TARGET_HOST_POSIX_X11
\r
876 case 26 : /* "xpseudocolor": */
\r
877 case 32 : /* "xpseudocolour": boolean indicating if the frame buffer
\r
878 configuration's X visual is of type PseudoColor */
\r
879 #if TARGET_HOST_POSIX_X11
\r
883 case 27 : /* "xtruecolor": */
\r
884 case 33 : /* "xtruecolour": boolean indicating if the frame buffer
\r
885 configuration's X visual is of type TrueColor */
\r
886 #if TARGET_HOST_POSIX_X11
\r
890 case 28 : /* "xdirectcolor": */
\r
891 case 34 : /* "xdirectcolour": boolean indicating if the frame buffer
\r
892 configuration's X visual is of type DirectColor */
\r
893 #if TARGET_HOST_POSIX_X11
\r
897 case 35 : /* "borderless": windows should not have borders */
\r
898 #if TARGET_HOST_POSIX_X11
\r
902 case 36 : /* "aux": some number of aux buffers */
\r
903 glut_state_flag |= GLUT_AUX;
\r
906 case 37 : /* Unrecognized */
\r
907 fgWarning ( "WARNING - Display string token not recognized: %s",
\r
912 token = strtok ( NULL, " \t" );
\r
917 /* We will make use of this value when creating a new OpenGL context... */
\r
918 fgState.DisplayMode = glut_state_flag;
\r
921 /* -- SETTING OPENGL 3.0 CONTEXT CREATION PARAMETERS ---------------------- */
\r
923 void FGAPIENTRY glutInitContextVersion( int majorVersion, int minorVersion )
\r
925 /* We will make use of these valuse when creating a new OpenGL context... */
\r
926 fgState.MajorVersion = majorVersion;
\r
927 fgState.MinorVersion = minorVersion;
\r
931 void FGAPIENTRY glutInitContextFlags( int flags )
\r
933 /* We will make use of this value when creating a new OpenGL context... */
\r
934 fgState.ContextFlags = flags;
\r
937 void FGAPIENTRY glutInitContextProfile( int profile )
\r
939 /* We will make use of this value when creating a new OpenGL context... */
\r
940 fgState.ContextProfile = profile;
\r
943 /* -------------- User Defined Error/Warning Handler Support -------------- */
\r
946 * Sets the user error handler (note the use of va_list for the args to the fmt)
\r
948 void FGAPIENTRY glutInitErrorFunc( void (* vfgError) ( const char *fmt, va_list ap ) )
\r
950 /* This allows user programs to handle freeglut errors */
\r
951 fgState.ErrorFunc = vfgError;
\r
955 * Sets the user warning handler (note the use of va_list for the args to the fmt)
\r
957 void FGAPIENTRY glutInitWarningFunc( void (* vfgWarning) ( const char *fmt, va_list ap ) )
\r
959 /* This allows user programs to handle freeglut warnings */
\r
960 fgState.WarningFunc = vfgWarning;
\r
963 /*** END OF FILE ***/
\r