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
335 #if TARGET_HOST_POSIX_X11
\r
336 static void fghDeinitialiseInputDevices ( void )
\r
338 fghCloseInputDevices ();
\r
340 fgState.JoysticksInitialised = GL_FALSE;
\r
341 fgState.InputDevsInitialised = GL_FALSE;
\r
345 static void fghCloseDisplay ( void )
\r
348 * Make sure all X-client data we have created will be destroyed on
\r
351 XSetCloseDownMode( fgDisplay.Display, DestroyAll );
\r
354 * Close the display connection, destroying all windows we have
\r
357 XCloseDisplay( fgDisplay.Display );
\r
364 * Perform the freeglut deinitialization...
\r
366 void fgDeinitialize( void )
\r
370 if( !fgState.Initialised )
\r
375 /* If we're in game mode, we want to leave game mode */
\r
376 if( fgStructure.GameModeWindow ) {
\r
377 glutLeaveGameMode();
\r
380 /* If there was a menu created, destroy the rendering context */
\r
381 if( fgStructure.MenuContext )
\r
383 #if TARGET_HOST_POSIX_X11
\r
384 /* Note that the MVisualInfo is not owned by the MenuContext! */
\r
385 glXDestroyContext( fgDisplay.Display, fgStructure.MenuContext->MContext );
\r
387 free( fgStructure.MenuContext );
\r
388 fgStructure.MenuContext = NULL;
\r
391 fgDestroyStructure( );
\r
393 while( ( timer = fgState.Timers.First) )
\r
395 fgListRemove( &fgState.Timers, &timer->Node );
\r
399 while( ( timer = fgState.FreeTimers.First) )
\r
401 fgListRemove( &fgState.FreeTimers, &timer->Node );
\r
405 fghDeinitialiseInputDevices ();
\r
407 fgState.MouseWheelTicks = 0;
\r
409 fgState.MajorVersion = 1;
\r
410 fgState.MinorVersion = 0;
\r
411 fgState.ContextFlags = 0;
\r
412 fgState.ContextProfile = 0;
\r
414 fgState.Initialised = GL_FALSE;
\r
416 fgState.Position.X = -1;
\r
417 fgState.Position.Y = -1;
\r
418 fgState.Position.Use = GL_FALSE;
\r
420 fgState.Size.X = 300;
\r
421 fgState.Size.Y = 300;
\r
422 fgState.Size.Use = GL_TRUE;
\r
424 fgState.DisplayMode = GLUT_RGBA | GLUT_SINGLE | GLUT_DEPTH;
\r
426 fgState.DirectContext = GLUT_TRY_DIRECT_CONTEXT;
\r
427 fgState.ForceIconic = GL_FALSE;
\r
428 fgState.UseCurrentContext = GL_FALSE;
\r
429 fgState.GLDebugSwitch = GL_FALSE;
\r
430 fgState.XSyncSwitch = GL_FALSE;
\r
431 fgState.ActionOnWindowClose = GLUT_ACTION_EXIT;
\r
432 fgState.ExecState = GLUT_EXEC_STATE_INIT;
\r
434 fgState.KeyRepeat = GLUT_KEY_REPEAT_ON;
\r
435 fgState.Modifiers = INVALID_MODIFIERS;
\r
437 fgState.GameModeSize.X = 640;
\r
438 fgState.GameModeSize.Y = 480;
\r
439 fgState.GameModeDepth = 16;
\r
440 fgState.GameModeRefresh = 72;
\r
442 fgListInit( &fgState.Timers );
\r
443 fgListInit( &fgState.FreeTimers );
\r
445 fgState.IdleCallback = NULL;
\r
446 fgState.MenuStateCallback = ( FGCBMenuState )NULL;
\r
447 fgState.MenuStatusCallback = ( FGCBMenuStatus )NULL;
\r
449 fgState.SwapCount = 0;
\r
450 fgState.SwapTime = 0;
\r
451 fgState.FPSInterval = 0;
\r
453 if( fgState.ProgramName )
\r
455 free( fgState.ProgramName );
\r
456 fgState.ProgramName = NULL;
\r
459 fghCloseDisplay ();
\r
461 fgState.Initialised = GL_FALSE;
\r
465 * Everything inside the following #ifndef is copied from the X sources.
\r
468 #if TARGET_HOST_MS_WINDOWS
\r
472 Copyright 1985, 1986, 1987,1998 The Open Group
\r
474 Permission to use, copy, modify, distribute, and sell this software and its
\r
475 documentation for any purpose is hereby granted without fee, provided that
\r
476 the above copyright notice appear in all copies and that both that
\r
477 copyright notice and this permission notice appear in supporting
\r
480 The above copyright notice and this permission notice shall be included
\r
481 in all copies or substantial portions of the Software.
\r
483 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
\r
484 OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
\r
485 MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
\r
486 IN NO EVENT SHALL THE OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR
\r
487 OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
\r
488 ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
\r
489 OTHER DEALINGS IN THE SOFTWARE.
\r
491 Except as contained in this notice, the name of The Open Group shall
\r
492 not be used in advertising or otherwise to promote the sale, use or
\r
493 other dealings in this Software without prior written authorization
\r
494 from The Open Group.
\r
498 #define NoValue 0x0000
\r
499 #define XValue 0x0001
\r
500 #define YValue 0x0002
\r
501 #define WidthValue 0x0004
\r
502 #define HeightValue 0x0008
\r
503 #define AllValues 0x000F
\r
504 #define XNegative 0x0010
\r
505 #define YNegative 0x0020
\r
508 * XParseGeometry parses strings of the form
\r
509 * "=<width>x<height>{+-}<xoffset>{+-}<yoffset>", where
\r
510 * width, height, xoffset, and yoffset are unsigned integers.
\r
511 * Example: "=80x24+300-49"
\r
512 * The equal sign is optional.
\r
513 * It returns a bitmask that indicates which of the four values
\r
514 * were actually found in the string. For each value found,
\r
515 * the corresponding argument is updated; for each value
\r
516 * not found, the corresponding argument is left unchanged.
\r
520 ReadInteger(char *string, char **NextString)
\r
522 register int Result = 0;
\r
525 if (*string == '+')
\r
527 else if (*string == '-')
\r
532 for (; (*string >= '0') && (*string <= '9'); string++)
\r
534 Result = (Result * 10) + (*string - '0');
\r
536 *NextString = string;
\r
543 static int XParseGeometry (
\r
544 const char *string,
\r
547 unsigned int *width, /* RETURN */
\r
548 unsigned int *height) /* RETURN */
\r
550 int mask = NoValue;
\r
551 register char *strind;
\r
552 unsigned int tempWidth = 0, tempHeight = 0;
\r
553 int tempX = 0, tempY = 0;
\r
554 char *nextCharacter;
\r
556 if ( (string == NULL) || (*string == '\0'))
\r
558 if (*string == '=')
\r
559 string++; /* ignore possible '=' at beg of geometry spec */
\r
561 strind = (char *)string;
\r
562 if (*strind != '+' && *strind != '-' && *strind != 'x') {
\r
563 tempWidth = ReadInteger(strind, &nextCharacter);
\r
564 if (strind == nextCharacter)
\r
566 strind = nextCharacter;
\r
567 mask |= WidthValue;
\r
570 if (*strind == 'x' || *strind == 'X') {
\r
572 tempHeight = ReadInteger(strind, &nextCharacter);
\r
573 if (strind == nextCharacter)
\r
575 strind = nextCharacter;
\r
576 mask |= HeightValue;
\r
579 if ((*strind == '+') || (*strind == '-')) {
\r
580 if (*strind == '-') {
\r
582 tempX = -ReadInteger(strind, &nextCharacter);
\r
583 if (strind == nextCharacter)
\r
585 strind = nextCharacter;
\r
591 tempX = ReadInteger(strind, &nextCharacter);
\r
592 if (strind == nextCharacter)
\r
594 strind = nextCharacter;
\r
597 if ((*strind == '+') || (*strind == '-')) {
\r
598 if (*strind == '-') {
\r
600 tempY = -ReadInteger(strind, &nextCharacter);
\r
601 if (strind == nextCharacter)
\r
603 strind = nextCharacter;
\r
609 tempY = ReadInteger(strind, &nextCharacter);
\r
610 if (strind == nextCharacter)
\r
612 strind = nextCharacter;
\r
618 /* If strind isn't at the end of the string the it's an invalid
\r
619 geometry specification. */
\r
621 if (*strind != '\0') return 0;
\r
627 if (mask & WidthValue)
\r
628 *width = tempWidth;
\r
629 if (mask & HeightValue)
\r
630 *height = tempHeight;
\r
635 /* -- INTERFACE FUNCTIONS -------------------------------------------------- */
\r
638 * Perform initialization. This usually happens on the program startup
\r
639 * and restarting after glutMainLoop termination...
\r
641 void FGAPIENTRY glutInit( int* pargc, char** argv )
\r
643 char* displayName = NULL;
\r
644 char* geometry = NULL;
\r
645 int i, j, argc = *pargc;
\r
647 if( fgState.Initialised )
\r
648 fgError( "illegal glutInit() reinitialization attempt" );
\r
650 if (pargc && *pargc && argv && *argv && **argv)
\r
652 fgState.ProgramName = strdup (*argv);
\r
654 if( !fgState.ProgramName )
\r
655 fgError ("Could not allocate space for the program's name.");
\r
658 fgCreateStructure( );
\r
660 /* Get start time */
\r
661 fgState.Time = fgSystemTime();
\r
663 /* check if GLUT_FPS env var is set */
\r
666 const char *fps = getenv( "GLUT_FPS" );
\r
671 sscanf( fps, "%d", &interval );
\r
673 if( interval <= 0 )
\r
674 fgState.FPSInterval = 5000; /* 5000 millisecond default */
\r
676 fgState.FPSInterval = interval;
\r
680 displayName = getenv( "DISPLAY" );
\r
682 for( i = 1; i < argc; i++ )
\r
684 if( strcmp( argv[ i ], "-display" ) == 0 )
\r
687 fgError( "-display parameter must be followed by display name" );
\r
689 displayName = argv[ i ];
\r
691 argv[ i - 1 ] = NULL;
\r
695 else if( strcmp( argv[ i ], "-geometry" ) == 0 )
\r
698 fgError( "-geometry parameter must be followed by window "
\r
699 "geometry settings" );
\r
701 geometry = argv[ i ];
\r
703 argv[ i - 1 ] = NULL;
\r
707 else if( strcmp( argv[ i ], "-direct" ) == 0)
\r
709 if( fgState.DirectContext == GLUT_FORCE_INDIRECT_CONTEXT )
\r
710 fgError( "parameters ambiguity, -direct and -indirect "
\r
711 "cannot be both specified" );
\r
713 fgState.DirectContext = GLUT_FORCE_DIRECT_CONTEXT;
\r
717 else if( strcmp( argv[ i ], "-indirect" ) == 0 )
\r
719 if( fgState.DirectContext == GLUT_FORCE_DIRECT_CONTEXT )
\r
720 fgError( "parameters ambiguity, -direct and -indirect "
\r
721 "cannot be both specified" );
\r
723 fgState.DirectContext = GLUT_FORCE_INDIRECT_CONTEXT;
\r
727 else if( strcmp( argv[ i ], "-iconic" ) == 0 )
\r
729 fgState.ForceIconic = GL_TRUE;
\r
733 else if( strcmp( argv[ i ], "-gldebug" ) == 0 )
\r
735 fgState.GLDebugSwitch = GL_TRUE;
\r
739 else if( strcmp( argv[ i ], "-sync" ) == 0 )
\r
741 fgState.XSyncSwitch = GL_TRUE;
\r
747 /* Compact {argv}. */
\r
748 for( i = j = 1; i < *pargc; i++, j++ )
\r
750 /* Guaranteed to end because there are "*pargc" arguments left */
\r
751 while ( argv[ j ] == NULL )
\r
754 argv[ i ] = argv[ j ];
\r
757 #endif /* _WIN32_WCE */
\r
760 * Have the display created now. If there wasn't a "-display"
\r
761 * in the program arguments, we will use the DISPLAY environment
\r
762 * variable for opening the X display (see code above):
\r
764 fghInitialize( displayName );
\r
767 * Geometry parsing deffered until here because we may need the screen
\r
773 unsigned int parsedWidth, parsedHeight;
\r
774 int mask = XParseGeometry( geometry,
\r
775 &fgState.Position.X, &fgState.Position.Y,
\r
776 &parsedWidth, &parsedHeight );
\r
777 /* TODO: Check for overflow? */
\r
778 fgState.Size.X = parsedWidth;
\r
779 fgState.Size.Y = parsedHeight;
\r
781 if( (mask & (WidthValue|HeightValue)) == (WidthValue|HeightValue) )
\r
782 fgState.Size.Use = GL_TRUE;
\r
784 if( mask & XNegative )
\r
785 fgState.Position.X += fgDisplay.ScreenWidth - fgState.Size.X;
\r
787 if( mask & YNegative )
\r
788 fgState.Position.Y += fgDisplay.ScreenHeight - fgState.Size.Y;
\r
790 if( (mask & (XValue|YValue)) == (XValue|YValue) )
\r
791 fgState.Position.Use = GL_TRUE;
\r
795 #if TARGET_HOST_MS_WINDOWS
\r
796 void (__cdecl *__glutExitFunc)( int return_value ) = NULL;
\r
798 void FGAPIENTRY __glutInitWithExit( int *pargc, char **argv, void (__cdecl *exit_function)(int) )
\r
800 __glutExitFunc = exit_function;
\r
801 glutInit(pargc, argv);
\r
806 * Undoes all the "glutInit" stuff
\r
808 void FGAPIENTRY glutExit ( void )
\r
814 * Sets the default initial window position for new windows
\r
816 void FGAPIENTRY glutInitWindowPosition( int x, int y )
\r
818 fgState.Position.X = x;
\r
819 fgState.Position.Y = y;
\r
821 if( ( x >= 0 ) && ( y >= 0 ) )
\r
822 fgState.Position.Use = GL_TRUE;
\r
824 fgState.Position.Use = GL_FALSE;
\r
828 * Sets the default initial window size for new windows
\r
830 void FGAPIENTRY glutInitWindowSize( int width, int height )
\r
832 fgState.Size.X = width;
\r
833 fgState.Size.Y = height;
\r
835 if( ( width > 0 ) && ( height > 0 ) )
\r
836 fgState.Size.Use = GL_TRUE;
\r
838 fgState.Size.Use = GL_FALSE;
\r
842 * Sets the default display mode for all new windows
\r
844 void FGAPIENTRY glutInitDisplayMode( unsigned int displayMode )
\r
846 /* We will make use of this value when creating a new OpenGL context... */
\r
847 fgState.DisplayMode = displayMode;
\r
851 /* -- INIT DISPLAY STRING PARSING ------------------------------------------ */
\r
853 static char* Tokens[] =
\r
855 "alpha", "acca", "acc", "blue", "buffer", "conformant", "depth", "double",
\r
856 "green", "index", "num", "red", "rgba", "rgb", "luminance", "stencil",
\r
857 "single", "stereo", "samples", "slow", "win32pdf", "win32pfd", "xvisual",
\r
858 "xstaticgray", "xgrayscale", "xstaticcolor", "xpseudocolor",
\r
859 "xtruecolor", "xdirectcolor",
\r
860 "xstaticgrey", "xgreyscale", "xstaticcolour", "xpseudocolour",
\r
861 "xtruecolour", "xdirectcolour", "borderless", "aux"
\r
863 #define NUM_TOKENS (sizeof(Tokens) / sizeof(*Tokens))
\r
865 void FGAPIENTRY glutInitDisplayString( const char* displayMode )
\r
867 int glut_state_flag = 0 ;
\r
869 * Unpack a lot of options from a character string. The options are
\r
870 * delimited by blanks or tabs.
\r
873 size_t len = strlen ( displayMode );
\r
874 char *buffer = (char *)malloc ( (len+1) * sizeof(char) );
\r
875 memcpy ( buffer, displayMode, len );
\r
876 buffer[len] = '\0';
\r
878 token = strtok ( buffer, " \t" );
\r
882 /* Process this token */
\r
885 /* Temporary fix: Ignore any length specifications and at least
\r
886 * process the basic token
\r
887 * TODO: Fix this permanently
\r
889 size_t cleanlength = strcspn ( token, "=<>~!" );
\r
891 for ( i = 0; i < NUM_TOKENS; i++ )
\r
893 if ( strncmp ( token, Tokens[i], cleanlength ) == 0 ) break ;
\r
898 case 0 : /* "alpha": Alpha color buffer precision in bits */
\r
899 glut_state_flag |= GLUT_ALPHA ; /* Somebody fix this for me! */
\r
902 case 1 : /* "acca": Red, green, blue, and alpha accumulation buffer
\r
903 precision in bits */
\r
906 case 2 : /* "acc": Red, green, and blue accumulation buffer precision
\r
907 in bits with zero bits alpha */
\r
908 glut_state_flag |= GLUT_ACCUM ; /* Somebody fix this for me! */
\r
911 case 3 : /* "blue": Blue color buffer precision in bits */
\r
914 case 4 : /* "buffer": Number of bits in the color index color buffer
\r
918 case 5 : /* "conformant": Boolean indicating if the frame buffer
\r
919 configuration is conformant or not */
\r
922 case 6 : /* "depth": Number of bits of precsion in the depth buffer */
\r
923 glut_state_flag |= GLUT_DEPTH ; /* Somebody fix this for me! */
\r
926 case 7 : /* "double": Boolean indicating if the color buffer is
\r
928 glut_state_flag |= GLUT_DOUBLE ;
\r
931 case 8 : /* "green": Green color buffer precision in bits */
\r
934 case 9 : /* "index": Boolean if the color model is color index or not
\r
936 glut_state_flag |= GLUT_INDEX ;
\r
939 case 10 : /* "num": A special capability name indicating where the
\r
940 value represents the Nth frame buffer configuration
\r
941 matching the description string */
\r
944 case 11 : /* "red": Red color buffer precision in bits */
\r
947 case 12 : /* "rgba": Number of bits of red, green, blue, and alpha in
\r
948 the RGBA color buffer */
\r
949 glut_state_flag |= GLUT_RGBA ; /* Somebody fix this for me! */
\r
952 case 13 : /* "rgb": Number of bits of red, green, and blue in the
\r
953 RGBA color buffer with zero bits alpha */
\r
954 glut_state_flag |= GLUT_RGB ; /* Somebody fix this for me! */
\r
957 case 14 : /* "luminance": Number of bits of red in the RGBA and zero
\r
958 bits of green, blue (alpha not specified) of color buffer
\r
960 glut_state_flag |= GLUT_LUMINANCE ; /* Somebody fix this for me! */
\r
963 case 15 : /* "stencil": Number of bits in the stencil buffer */
\r
964 glut_state_flag |= GLUT_STENCIL; /* Somebody fix this for me! */
\r
967 case 16 : /* "single": Boolean indicate the color buffer is single
\r
969 glut_state_flag |= GLUT_SINGLE ;
\r
972 case 17 : /* "stereo": Boolean indicating the color buffer supports
\r
973 OpenGL-style stereo */
\r
974 glut_state_flag |= GLUT_STEREO ;
\r
977 case 18 : /* "samples": Indicates the number of multisamples to use
\r
978 based on GLX's SGIS_multisample extension (for
\r
980 glut_state_flag |= GLUT_MULTISAMPLE ; /*Somebody fix this for me!*/
\r
983 case 19 : /* "slow": Boolean indicating if the frame buffer
\r
984 configuration is slow or not */
\r
987 case 20 : /* "win32pdf": (incorrect spelling but was there before */
\r
988 case 21 : /* "win32pfd": matches the Win32 Pixel Format Descriptor by
\r
990 #if TARGET_HOST_MS_WINDOWS
\r
994 case 22 : /* "xvisual": matches the X visual ID by number */
\r
995 #if TARGET_HOST_POSIX_X11
\r
999 case 23 : /* "xstaticgray": */
\r
1000 case 29 : /* "xstaticgrey": boolean indicating if the frame buffer
\r
1001 configuration's X visual is of type StaticGray */
\r
1002 #if TARGET_HOST_POSIX_X11
\r
1006 case 24 : /* "xgrayscale": */
\r
1007 case 30 : /* "xgreyscale": boolean indicating if the frame buffer
\r
1008 configuration's X visual is of type GrayScale */
\r
1009 #if TARGET_HOST_POSIX_X11
\r
1013 case 25 : /* "xstaticcolor": */
\r
1014 case 31 : /* "xstaticcolour": boolean indicating if the frame buffer
\r
1015 configuration's X visual is of type StaticColor */
\r
1016 #if TARGET_HOST_POSIX_X11
\r
1020 case 26 : /* "xpseudocolor": */
\r
1021 case 32 : /* "xpseudocolour": boolean indicating if the frame buffer
\r
1022 configuration's X visual is of type PseudoColor */
\r
1023 #if TARGET_HOST_POSIX_X11
\r
1027 case 27 : /* "xtruecolor": */
\r
1028 case 33 : /* "xtruecolour": boolean indicating if the frame buffer
\r
1029 configuration's X visual is of type TrueColor */
\r
1030 #if TARGET_HOST_POSIX_X11
\r
1034 case 28 : /* "xdirectcolor": */
\r
1035 case 34 : /* "xdirectcolour": boolean indicating if the frame buffer
\r
1036 configuration's X visual is of type DirectColor */
\r
1037 #if TARGET_HOST_POSIX_X11
\r
1041 case 35 : /* "borderless": windows should not have borders */
\r
1042 #if TARGET_HOST_POSIX_X11
\r
1046 case 36 : /* "aux": some number of aux buffers */
\r
1047 glut_state_flag |= GLUT_AUX;
\r
1050 case 37 : /* Unrecognized */
\r
1051 fgWarning ( "WARNING - Display string token not recognized: %s",
\r
1056 token = strtok ( NULL, " \t" );
\r
1061 /* We will make use of this value when creating a new OpenGL context... */
\r
1062 fgState.DisplayMode = glut_state_flag;
\r
1065 /* -- SETTING OPENGL 3.0 CONTEXT CREATION PARAMETERS ---------------------- */
\r
1067 void FGAPIENTRY glutInitContextVersion( int majorVersion, int minorVersion )
\r
1069 /* We will make use of these valuse when creating a new OpenGL context... */
\r
1070 fgState.MajorVersion = majorVersion;
\r
1071 fgState.MinorVersion = minorVersion;
\r
1075 void FGAPIENTRY glutInitContextFlags( int flags )
\r
1077 /* We will make use of this value when creating a new OpenGL context... */
\r
1078 fgState.ContextFlags = flags;
\r
1081 void FGAPIENTRY glutInitContextProfile( int profile )
\r
1083 /* We will make use of this value when creating a new OpenGL context... */
\r
1084 fgState.ContextProfile = profile;
\r
1087 /* -------------- User Defined Error/Warning Handler Support -------------- */
\r
1090 * Sets the user error handler (note the use of va_list for the args to the fmt)
\r
1092 void FGAPIENTRY glutInitErrorFunc( void (* vfgError) ( const char *fmt, va_list ap ) )
\r
1094 /* This allows user programs to handle freeglut errors */
\r
1095 fgState.ErrorFunc = vfgError;
\r
1099 * Sets the user warning handler (note the use of va_list for the args to the fmt)
\r
1101 void FGAPIENTRY glutInitWarningFunc( void (* vfgWarning) ( const char *fmt, va_list ap ) )
\r
1103 /* This allows user programs to handle freeglut warnings */
\r
1104 fgState.WarningFunc = vfgWarning;
\r
1107 /*** END OF FILE ***/
\r