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
325 void fghCloseInputDevices ( void )
\r
327 if ( fgState.JoysticksInitialised )
\r
328 fgJoystickClose( );
\r
330 if ( fgState.InputDevsInitialised )
\r
331 fgInputDeviceClose( );
\r
333 fgState.JoysticksInitialised = GL_FALSE;
\r
334 fgState.InputDevsInitialised = GL_FALSE;
\r
338 #if TARGET_HOST_POSIX_X11
\r
339 static void fghDeinitialiseInputDevices ( void )
\r
341 fghCloseInputDevices ();
\r
343 fgState.JoysticksInitialised = GL_FALSE;
\r
344 fgState.InputDevsInitialised = GL_FALSE;
\r
348 static void fghCloseDisplay ( void )
\r
351 * Make sure all X-client data we have created will be destroyed on
\r
354 XSetCloseDownMode( fgDisplay.Display, DestroyAll );
\r
357 * Close the display connection, destroying all windows we have
\r
360 XCloseDisplay( fgDisplay.Display );
\r
367 * Perform the freeglut deinitialization...
\r
369 void fgDeinitialize( void )
\r
373 if( !fgState.Initialised )
\r
378 /* If we're in game mode, we want to leave game mode */
\r
379 if( fgStructure.GameModeWindow ) {
\r
380 glutLeaveGameMode();
\r
383 /* If there was a menu created, destroy the rendering context */
\r
384 if( fgStructure.MenuContext )
\r
386 #if TARGET_HOST_POSIX_X11
\r
387 /* Note that the MVisualInfo is not owned by the MenuContext! */
\r
388 glXDestroyContext( fgDisplay.Display, fgStructure.MenuContext->MContext );
\r
390 free( fgStructure.MenuContext );
\r
391 fgStructure.MenuContext = NULL;
\r
394 fgDestroyStructure( );
\r
396 while( ( timer = fgState.Timers.First) )
\r
398 fgListRemove( &fgState.Timers, &timer->Node );
\r
402 while( ( timer = fgState.FreeTimers.First) )
\r
404 fgListRemove( &fgState.FreeTimers, &timer->Node );
\r
408 fghDeinitialiseInputDevices ();
\r
410 fgState.MouseWheelTicks = 0;
\r
412 fgState.MajorVersion = 1;
\r
413 fgState.MinorVersion = 0;
\r
414 fgState.ContextFlags = 0;
\r
415 fgState.ContextProfile = 0;
\r
417 fgState.Initialised = GL_FALSE;
\r
419 fgState.Position.X = -1;
\r
420 fgState.Position.Y = -1;
\r
421 fgState.Position.Use = GL_FALSE;
\r
423 fgState.Size.X = 300;
\r
424 fgState.Size.Y = 300;
\r
425 fgState.Size.Use = GL_TRUE;
\r
427 fgState.DisplayMode = GLUT_RGBA | GLUT_SINGLE | GLUT_DEPTH;
\r
429 fgState.DirectContext = GLUT_TRY_DIRECT_CONTEXT;
\r
430 fgState.ForceIconic = GL_FALSE;
\r
431 fgState.UseCurrentContext = GL_FALSE;
\r
432 fgState.GLDebugSwitch = GL_FALSE;
\r
433 fgState.XSyncSwitch = GL_FALSE;
\r
434 fgState.ActionOnWindowClose = GLUT_ACTION_EXIT;
\r
435 fgState.ExecState = GLUT_EXEC_STATE_INIT;
\r
437 fgState.KeyRepeat = GLUT_KEY_REPEAT_ON;
\r
438 fgState.Modifiers = INVALID_MODIFIERS;
\r
440 fgState.GameModeSize.X = 640;
\r
441 fgState.GameModeSize.Y = 480;
\r
442 fgState.GameModeDepth = 16;
\r
443 fgState.GameModeRefresh = 72;
\r
445 fgListInit( &fgState.Timers );
\r
446 fgListInit( &fgState.FreeTimers );
\r
448 fgState.IdleCallback = NULL;
\r
449 fgState.MenuStateCallback = ( FGCBMenuState )NULL;
\r
450 fgState.MenuStatusCallback = ( FGCBMenuStatus )NULL;
\r
452 fgState.SwapCount = 0;
\r
453 fgState.SwapTime = 0;
\r
454 fgState.FPSInterval = 0;
\r
456 if( fgState.ProgramName )
\r
458 free( fgState.ProgramName );
\r
459 fgState.ProgramName = NULL;
\r
462 fghCloseDisplay ();
\r
464 fgState.Initialised = GL_FALSE;
\r
468 * Everything inside the following #ifndef is copied from the X sources.
\r
471 #if TARGET_HOST_MS_WINDOWS
\r
475 Copyright 1985, 1986, 1987,1998 The Open Group
\r
477 Permission to use, copy, modify, distribute, and sell this software and its
\r
478 documentation for any purpose is hereby granted without fee, provided that
\r
479 the above copyright notice appear in all copies and that both that
\r
480 copyright notice and this permission notice appear in supporting
\r
483 The above copyright notice and this permission notice shall be included
\r
484 in all copies or substantial portions of the Software.
\r
486 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
\r
487 OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
\r
488 MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
\r
489 IN NO EVENT SHALL THE OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR
\r
490 OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
\r
491 ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
\r
492 OTHER DEALINGS IN THE SOFTWARE.
\r
494 Except as contained in this notice, the name of The Open Group shall
\r
495 not be used in advertising or otherwise to promote the sale, use or
\r
496 other dealings in this Software without prior written authorization
\r
497 from The Open Group.
\r
501 #define NoValue 0x0000
\r
502 #define XValue 0x0001
\r
503 #define YValue 0x0002
\r
504 #define WidthValue 0x0004
\r
505 #define HeightValue 0x0008
\r
506 #define AllValues 0x000F
\r
507 #define XNegative 0x0010
\r
508 #define YNegative 0x0020
\r
511 * XParseGeometry parses strings of the form
\r
512 * "=<width>x<height>{+-}<xoffset>{+-}<yoffset>", where
\r
513 * width, height, xoffset, and yoffset are unsigned integers.
\r
514 * Example: "=80x24+300-49"
\r
515 * The equal sign is optional.
\r
516 * It returns a bitmask that indicates which of the four values
\r
517 * were actually found in the string. For each value found,
\r
518 * the corresponding argument is updated; for each value
\r
519 * not found, the corresponding argument is left unchanged.
\r
523 ReadInteger(char *string, char **NextString)
\r
525 register int Result = 0;
\r
528 if (*string == '+')
\r
530 else if (*string == '-')
\r
535 for (; (*string >= '0') && (*string <= '9'); string++)
\r
537 Result = (Result * 10) + (*string - '0');
\r
539 *NextString = string;
\r
546 static int XParseGeometry (
\r
547 const char *string,
\r
550 unsigned int *width, /* RETURN */
\r
551 unsigned int *height) /* RETURN */
\r
553 int mask = NoValue;
\r
554 register char *strind;
\r
555 unsigned int tempWidth = 0, tempHeight = 0;
\r
556 int tempX = 0, tempY = 0;
\r
557 char *nextCharacter;
\r
559 if ( (string == NULL) || (*string == '\0'))
\r
561 if (*string == '=')
\r
562 string++; /* ignore possible '=' at beg of geometry spec */
\r
564 strind = (char *)string;
\r
565 if (*strind != '+' && *strind != '-' && *strind != 'x') {
\r
566 tempWidth = ReadInteger(strind, &nextCharacter);
\r
567 if (strind == nextCharacter)
\r
569 strind = nextCharacter;
\r
570 mask |= WidthValue;
\r
573 if (*strind == 'x' || *strind == 'X') {
\r
575 tempHeight = ReadInteger(strind, &nextCharacter);
\r
576 if (strind == nextCharacter)
\r
578 strind = nextCharacter;
\r
579 mask |= HeightValue;
\r
582 if ((*strind == '+') || (*strind == '-')) {
\r
583 if (*strind == '-') {
\r
585 tempX = -ReadInteger(strind, &nextCharacter);
\r
586 if (strind == nextCharacter)
\r
588 strind = nextCharacter;
\r
594 tempX = ReadInteger(strind, &nextCharacter);
\r
595 if (strind == nextCharacter)
\r
597 strind = nextCharacter;
\r
600 if ((*strind == '+') || (*strind == '-')) {
\r
601 if (*strind == '-') {
\r
603 tempY = -ReadInteger(strind, &nextCharacter);
\r
604 if (strind == nextCharacter)
\r
606 strind = nextCharacter;
\r
612 tempY = ReadInteger(strind, &nextCharacter);
\r
613 if (strind == nextCharacter)
\r
615 strind = nextCharacter;
\r
621 /* If strind isn't at the end of the string the it's an invalid
\r
622 geometry specification. */
\r
624 if (*strind != '\0') return 0;
\r
630 if (mask & WidthValue)
\r
631 *width = tempWidth;
\r
632 if (mask & HeightValue)
\r
633 *height = tempHeight;
\r
638 /* -- INTERFACE FUNCTIONS -------------------------------------------------- */
\r
641 * Perform initialization. This usually happens on the program startup
\r
642 * and restarting after glutMainLoop termination...
\r
644 void FGAPIENTRY glutInit( int* pargc, char** argv )
\r
646 char* displayName = NULL;
\r
647 char* geometry = NULL;
\r
648 int i, j, argc = *pargc;
\r
650 if( fgState.Initialised )
\r
651 fgError( "illegal glutInit() reinitialization attempt" );
\r
653 if (pargc && *pargc && argv && *argv && **argv)
\r
655 fgState.ProgramName = strdup (*argv);
\r
657 if( !fgState.ProgramName )
\r
658 fgError ("Could not allocate space for the program's name.");
\r
661 fgCreateStructure( );
\r
663 /* Get start time */
\r
664 fgState.Time = fgSystemTime();
\r
666 /* check if GLUT_FPS env var is set */
\r
669 const char *fps = getenv( "GLUT_FPS" );
\r
674 sscanf( fps, "%d", &interval );
\r
676 if( interval <= 0 )
\r
677 fgState.FPSInterval = 5000; /* 5000 millisecond default */
\r
679 fgState.FPSInterval = interval;
\r
683 displayName = getenv( "DISPLAY" );
\r
685 for( i = 1; i < argc; i++ )
\r
687 if( strcmp( argv[ i ], "-display" ) == 0 )
\r
690 fgError( "-display parameter must be followed by display name" );
\r
692 displayName = argv[ i ];
\r
694 argv[ i - 1 ] = NULL;
\r
698 else if( strcmp( argv[ i ], "-geometry" ) == 0 )
\r
701 fgError( "-geometry parameter must be followed by window "
\r
702 "geometry settings" );
\r
704 geometry = argv[ i ];
\r
706 argv[ i - 1 ] = NULL;
\r
710 else if( strcmp( argv[ i ], "-direct" ) == 0)
\r
712 if( fgState.DirectContext == GLUT_FORCE_INDIRECT_CONTEXT )
\r
713 fgError( "parameters ambiguity, -direct and -indirect "
\r
714 "cannot be both specified" );
\r
716 fgState.DirectContext = GLUT_FORCE_DIRECT_CONTEXT;
\r
720 else if( strcmp( argv[ i ], "-indirect" ) == 0 )
\r
722 if( fgState.DirectContext == GLUT_FORCE_DIRECT_CONTEXT )
\r
723 fgError( "parameters ambiguity, -direct and -indirect "
\r
724 "cannot be both specified" );
\r
726 fgState.DirectContext = GLUT_FORCE_INDIRECT_CONTEXT;
\r
730 else if( strcmp( argv[ i ], "-iconic" ) == 0 )
\r
732 fgState.ForceIconic = GL_TRUE;
\r
736 else if( strcmp( argv[ i ], "-gldebug" ) == 0 )
\r
738 fgState.GLDebugSwitch = GL_TRUE;
\r
742 else if( strcmp( argv[ i ], "-sync" ) == 0 )
\r
744 fgState.XSyncSwitch = GL_TRUE;
\r
750 /* Compact {argv}. */
\r
751 for( i = j = 1; i < *pargc; i++, j++ )
\r
753 /* Guaranteed to end because there are "*pargc" arguments left */
\r
754 while ( argv[ j ] == NULL )
\r
757 argv[ i ] = argv[ j ];
\r
760 #endif /* _WIN32_WCE */
\r
763 * Have the display created now. If there wasn't a "-display"
\r
764 * in the program arguments, we will use the DISPLAY environment
\r
765 * variable for opening the X display (see code above):
\r
767 fghInitialize( displayName );
\r
770 * Geometry parsing deffered until here because we may need the screen
\r
776 unsigned int parsedWidth, parsedHeight;
\r
777 int mask = XParseGeometry( geometry,
\r
778 &fgState.Position.X, &fgState.Position.Y,
\r
779 &parsedWidth, &parsedHeight );
\r
780 /* TODO: Check for overflow? */
\r
781 fgState.Size.X = parsedWidth;
\r
782 fgState.Size.Y = parsedHeight;
\r
784 if( (mask & (WidthValue|HeightValue)) == (WidthValue|HeightValue) )
\r
785 fgState.Size.Use = GL_TRUE;
\r
787 if( mask & XNegative )
\r
788 fgState.Position.X += fgDisplay.ScreenWidth - fgState.Size.X;
\r
790 if( mask & YNegative )
\r
791 fgState.Position.Y += fgDisplay.ScreenHeight - fgState.Size.Y;
\r
793 if( (mask & (XValue|YValue)) == (XValue|YValue) )
\r
794 fgState.Position.Use = GL_TRUE;
\r
798 #if TARGET_HOST_MS_WINDOWS
\r
799 void (__cdecl *__glutExitFunc)( int return_value ) = NULL;
\r
801 void FGAPIENTRY __glutInitWithExit( int *pargc, char **argv, void (__cdecl *exit_function)(int) )
\r
803 __glutExitFunc = exit_function;
\r
804 glutInit(pargc, argv);
\r
809 * Undoes all the "glutInit" stuff
\r
811 void FGAPIENTRY glutExit ( void )
\r
817 * Sets the default initial window position for new windows
\r
819 void FGAPIENTRY glutInitWindowPosition( int x, int y )
\r
821 fgState.Position.X = x;
\r
822 fgState.Position.Y = y;
\r
824 if( ( x >= 0 ) && ( y >= 0 ) )
\r
825 fgState.Position.Use = GL_TRUE;
\r
827 fgState.Position.Use = GL_FALSE;
\r
831 * Sets the default initial window size for new windows
\r
833 void FGAPIENTRY glutInitWindowSize( int width, int height )
\r
835 fgState.Size.X = width;
\r
836 fgState.Size.Y = height;
\r
838 if( ( width > 0 ) && ( height > 0 ) )
\r
839 fgState.Size.Use = GL_TRUE;
\r
841 fgState.Size.Use = GL_FALSE;
\r
845 * Sets the default display mode for all new windows
\r
847 void FGAPIENTRY glutInitDisplayMode( unsigned int displayMode )
\r
849 /* We will make use of this value when creating a new OpenGL context... */
\r
850 fgState.DisplayMode = displayMode;
\r
854 /* -- INIT DISPLAY STRING PARSING ------------------------------------------ */
\r
856 static char* Tokens[] =
\r
858 "alpha", "acca", "acc", "blue", "buffer", "conformant", "depth", "double",
\r
859 "green", "index", "num", "red", "rgba", "rgb", "luminance", "stencil",
\r
860 "single", "stereo", "samples", "slow", "win32pdf", "win32pfd", "xvisual",
\r
861 "xstaticgray", "xgrayscale", "xstaticcolor", "xpseudocolor",
\r
862 "xtruecolor", "xdirectcolor",
\r
863 "xstaticgrey", "xgreyscale", "xstaticcolour", "xpseudocolour",
\r
864 "xtruecolour", "xdirectcolour", "borderless", "aux"
\r
866 #define NUM_TOKENS (sizeof(Tokens) / sizeof(*Tokens))
\r
868 void FGAPIENTRY glutInitDisplayString( const char* displayMode )
\r
870 int glut_state_flag = 0 ;
\r
872 * Unpack a lot of options from a character string. The options are
\r
873 * delimited by blanks or tabs.
\r
876 size_t len = strlen ( displayMode );
\r
877 char *buffer = (char *)malloc ( (len+1) * sizeof(char) );
\r
878 memcpy ( buffer, displayMode, len );
\r
879 buffer[len] = '\0';
\r
881 token = strtok ( buffer, " \t" );
\r
885 /* Process this token */
\r
888 /* Temporary fix: Ignore any length specifications and at least
\r
889 * process the basic token
\r
890 * TODO: Fix this permanently
\r
892 size_t cleanlength = strcspn ( token, "=<>~!" );
\r
894 for ( i = 0; i < NUM_TOKENS; i++ )
\r
896 if ( strncmp ( token, Tokens[i], cleanlength ) == 0 ) break ;
\r
901 case 0 : /* "alpha": Alpha color buffer precision in bits */
\r
902 glut_state_flag |= GLUT_ALPHA ; /* Somebody fix this for me! */
\r
905 case 1 : /* "acca": Red, green, blue, and alpha accumulation buffer
\r
906 precision in bits */
\r
909 case 2 : /* "acc": Red, green, and blue accumulation buffer precision
\r
910 in bits with zero bits alpha */
\r
911 glut_state_flag |= GLUT_ACCUM ; /* Somebody fix this for me! */
\r
914 case 3 : /* "blue": Blue color buffer precision in bits */
\r
917 case 4 : /* "buffer": Number of bits in the color index color buffer
\r
921 case 5 : /* "conformant": Boolean indicating if the frame buffer
\r
922 configuration is conformant or not */
\r
925 case 6 : /* "depth": Number of bits of precsion in the depth buffer */
\r
926 glut_state_flag |= GLUT_DEPTH ; /* Somebody fix this for me! */
\r
929 case 7 : /* "double": Boolean indicating if the color buffer is
\r
931 glut_state_flag |= GLUT_DOUBLE ;
\r
934 case 8 : /* "green": Green color buffer precision in bits */
\r
937 case 9 : /* "index": Boolean if the color model is color index or not
\r
939 glut_state_flag |= GLUT_INDEX ;
\r
942 case 10 : /* "num": A special capability name indicating where the
\r
943 value represents the Nth frame buffer configuration
\r
944 matching the description string */
\r
947 case 11 : /* "red": Red color buffer precision in bits */
\r
950 case 12 : /* "rgba": Number of bits of red, green, blue, and alpha in
\r
951 the RGBA color buffer */
\r
952 glut_state_flag |= GLUT_RGBA ; /* Somebody fix this for me! */
\r
955 case 13 : /* "rgb": Number of bits of red, green, and blue in the
\r
956 RGBA color buffer with zero bits alpha */
\r
957 glut_state_flag |= GLUT_RGB ; /* Somebody fix this for me! */
\r
960 case 14 : /* "luminance": Number of bits of red in the RGBA and zero
\r
961 bits of green, blue (alpha not specified) of color buffer
\r
963 glut_state_flag |= GLUT_LUMINANCE ; /* Somebody fix this for me! */
\r
966 case 15 : /* "stencil": Number of bits in the stencil buffer */
\r
967 glut_state_flag |= GLUT_STENCIL; /* Somebody fix this for me! */
\r
970 case 16 : /* "single": Boolean indicate the color buffer is single
\r
972 glut_state_flag |= GLUT_SINGLE ;
\r
975 case 17 : /* "stereo": Boolean indicating the color buffer supports
\r
976 OpenGL-style stereo */
\r
977 glut_state_flag |= GLUT_STEREO ;
\r
980 case 18 : /* "samples": Indicates the number of multisamples to use
\r
981 based on GLX's SGIS_multisample extension (for
\r
983 glut_state_flag |= GLUT_MULTISAMPLE ; /*Somebody fix this for me!*/
\r
986 case 19 : /* "slow": Boolean indicating if the frame buffer
\r
987 configuration is slow or not */
\r
990 case 20 : /* "win32pdf": (incorrect spelling but was there before */
\r
991 case 21 : /* "win32pfd": matches the Win32 Pixel Format Descriptor by
\r
993 #if TARGET_HOST_MS_WINDOWS
\r
997 case 22 : /* "xvisual": matches the X visual ID by number */
\r
998 #if TARGET_HOST_POSIX_X11
\r
1002 case 23 : /* "xstaticgray": */
\r
1003 case 29 : /* "xstaticgrey": boolean indicating if the frame buffer
\r
1004 configuration's X visual is of type StaticGray */
\r
1005 #if TARGET_HOST_POSIX_X11
\r
1009 case 24 : /* "xgrayscale": */
\r
1010 case 30 : /* "xgreyscale": boolean indicating if the frame buffer
\r
1011 configuration's X visual is of type GrayScale */
\r
1012 #if TARGET_HOST_POSIX_X11
\r
1016 case 25 : /* "xstaticcolor": */
\r
1017 case 31 : /* "xstaticcolour": boolean indicating if the frame buffer
\r
1018 configuration's X visual is of type StaticColor */
\r
1019 #if TARGET_HOST_POSIX_X11
\r
1023 case 26 : /* "xpseudocolor": */
\r
1024 case 32 : /* "xpseudocolour": boolean indicating if the frame buffer
\r
1025 configuration's X visual is of type PseudoColor */
\r
1026 #if TARGET_HOST_POSIX_X11
\r
1030 case 27 : /* "xtruecolor": */
\r
1031 case 33 : /* "xtruecolour": boolean indicating if the frame buffer
\r
1032 configuration's X visual is of type TrueColor */
\r
1033 #if TARGET_HOST_POSIX_X11
\r
1037 case 28 : /* "xdirectcolor": */
\r
1038 case 34 : /* "xdirectcolour": boolean indicating if the frame buffer
\r
1039 configuration's X visual is of type DirectColor */
\r
1040 #if TARGET_HOST_POSIX_X11
\r
1044 case 35 : /* "borderless": windows should not have borders */
\r
1045 #if TARGET_HOST_POSIX_X11
\r
1049 case 36 : /* "aux": some number of aux buffers */
\r
1050 glut_state_flag |= GLUT_AUX;
\r
1053 case 37 : /* Unrecognized */
\r
1054 fgWarning ( "WARNING - Display string token not recognized: %s",
\r
1059 token = strtok ( NULL, " \t" );
\r
1064 /* We will make use of this value when creating a new OpenGL context... */
\r
1065 fgState.DisplayMode = glut_state_flag;
\r
1068 /* -- SETTING OPENGL 3.0 CONTEXT CREATION PARAMETERS ---------------------- */
\r
1070 void FGAPIENTRY glutInitContextVersion( int majorVersion, int minorVersion )
\r
1072 /* We will make use of these valuse when creating a new OpenGL context... */
\r
1073 fgState.MajorVersion = majorVersion;
\r
1074 fgState.MinorVersion = minorVersion;
\r
1078 void FGAPIENTRY glutInitContextFlags( int flags )
\r
1080 /* We will make use of this value when creating a new OpenGL context... */
\r
1081 fgState.ContextFlags = flags;
\r
1084 void FGAPIENTRY glutInitContextProfile( int profile )
\r
1086 /* We will make use of this value when creating a new OpenGL context... */
\r
1087 fgState.ContextProfile = profile;
\r
1090 /* -------------- User Defined Error/Warning Handler Support -------------- */
\r
1093 * Sets the user error handler (note the use of va_list for the args to the fmt)
\r
1095 void FGAPIENTRY glutInitErrorFunc( void (* vfgError) ( const char *fmt, va_list ap ) )
\r
1097 /* This allows user programs to handle freeglut errors */
\r
1098 fgState.ErrorFunc = vfgError;
\r
1102 * Sets the user warning handler (note the use of va_list for the args to the fmt)
\r
1104 void FGAPIENTRY glutInitWarningFunc( void (* vfgWarning) ( const char *fmt, va_list ap ) )
\r
1106 /* This allows user programs to handle freeglut warnings */
\r
1107 fgState.WarningFunc = vfgWarning;
\r
1110 /*** END OF FILE ***/
\r