4 * Window management methods.
6 * Copyright (c) 1999-2000 Pawel W. Olszta. All Rights Reserved.
7 * Written by Pawel W. Olszta, <olszta@sourceforge.net>
8 * Creation date: Fri Dec 3 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.
28 #define FREEGLUT_BUILDING_LIB
29 #include <GL/freeglut.h>
30 #include "freeglut_internal.h"
32 #if defined(_WIN32_WCE)
33 # include <Aygshell.h>
34 # ifdef FREEGLUT_LIB_PRAGMAS
35 # pragma comment( lib, "Aygshell.lib" )
37 #endif /* defined(_WIN32_WCE) */
41 * TODO BEFORE THE STABLE RELEASE:
43 * fgSetupPixelFormat -- ignores the display mode settings
44 * fgOpenWindow() -- check the Win32 version, -iconic handling!
45 * fgCloseWindow() -- check the Win32 version
46 * glutCreateWindow() -- Check when default position and size is {-1,-1}
47 * glutCreateSubWindow() -- Check when default position and size is {-1,-1}
48 * glutDestroyWindow() -- check the Win32 version
49 * glutSetWindow() -- check the Win32 version
50 * glutSetWindowTitle() -- check the Win32 version
51 * glutSetIconTitle() -- check the Win32 version
52 * glutShowWindow() -- check the Win32 version
53 * glutHideWindow() -- check the Win32 version
54 * glutIconifyWindow() -- check the Win32 version
55 * glutPushWindow() -- check the Win32 version
56 * glutPopWindow() -- check the Win32 version
60 extern void fgPlatformSetWindow ( SFG_Window *window );
61 extern void fgPlatformOpenWindow( SFG_Window* window, const char* title,
62 GLboolean positionUse, int x, int y,
63 GLboolean sizeUse, int w, int h,
64 GLboolean gameMode, GLboolean isSubWindow );
65 extern void fgPlatformCloseWindow( SFG_Window* window );
66 extern void fgPlatformGlutShowWindow( void );
67 extern void fgPlatformGlutHideWindow( void );
68 extern void fgPlatformGlutIconifyWindow( void );
69 extern void fgPlatformGlutSetWindowTitle( const char* title );
70 extern void fgPlatformGlutSetIconTitle( const char* title );
71 extern void fgPlatformGlutPositionWindow( int x, int y );
72 extern void fgPlatformGlutPushWindow( void );
73 extern void fgPlatformGlutPopWindow( void );
74 extern void fgPlatformGlutFullScreen( SFG_Window *win );
75 extern void fgPlatformGlutLeaveFullScreen( SFG_Window *win );
76 extern void fgPlatformGlutFullScreenToggle( SFG_Window *win );
79 /* -- PRIVATE FUNCTIONS ---------------------------------------------------- */
81 int fghIsLegacyContextVersionRequested( void )
83 return fgState.MajorVersion < 2 || (fgState.MajorVersion == 2 && fgState.MinorVersion <= 1);
86 int fghIsLegacyContextRequested( void )
88 return fghIsLegacyContextVersionRequested() &&
89 fgState.ContextFlags == 0 &&
90 fgState.ContextProfile == 0;
93 int fghNumberOfAuxBuffersRequested( void )
95 if ( fgState.DisplayMode & GLUT_AUX4 ) {
98 if ( fgState.DisplayMode & GLUT_AUX3 ) {
101 if ( fgState.DisplayMode & GLUT_AUX2 ) {
104 if ( fgState.DisplayMode & GLUT_AUX1 ) { /* NOTE: Same as GLUT_AUX! */
105 return fgState.AuxiliaryBufferNumber;
110 int fghMapBit( int mask, int from, int to )
112 return ( mask & from ) ? to : 0;
116 void fghContextCreationError( void )
118 fgError( "Unable to create OpenGL %d.%d context (flags %x, profile %x)",
119 fgState.MajorVersion, fgState.MinorVersion, fgState.ContextFlags,
120 fgState.ContextProfile );
124 /* -- SYSTEM-DEPENDENT PRIVATE FUNCTIONS ------------------------------------ */
127 * Sets the OpenGL context and the fgStructure "Current Window" pointer to
128 * the window structure passed in.
130 void fgSetWindow ( SFG_Window *window )
132 fgPlatformSetWindow ( window );
134 fgStructure.CurrentWindow = window;
138 * Opens a window. Requires a SFG_Window object created and attached
139 * to the freeglut structure. OpenGL context is created here.
141 void fgOpenWindow( SFG_Window* window, const char* title,
142 GLboolean positionUse, int x, int y,
143 GLboolean sizeUse, int w, int h,
144 GLboolean gameMode, GLboolean isSubWindow )
146 fgPlatformOpenWindow( window, title,
149 gameMode, isSubWindow );
151 fgSetWindow( window );
153 window->Window.DoubleBuffered =
154 ( fgState.DisplayMode & GLUT_DOUBLE ) ? 1 : 0;
156 if ( ! window->Window.DoubleBuffered )
158 glDrawBuffer ( GL_FRONT );
159 glReadBuffer ( GL_FRONT );
164 * Closes a window, destroying the frame and OpenGL context
166 void fgCloseWindow( SFG_Window* window )
168 /* if we're in gamemode and we're closing the gamemode window,
169 * call glutLeaveGameMode first to make sure the gamemode is
170 * properly closed before closing the window
172 if (fgStructure.GameModeWindow != NULL && fgStructure.GameModeWindow->ID==window->ID)
175 fgPlatformCloseWindow ( window );
179 /* -- INTERFACE FUNCTIONS -------------------------------------------------- */
182 * Creates a new top-level freeglut window
184 int FGAPIENTRY glutCreateWindow( const char* title )
186 /* XXX GLUT does not exit; it simply calls "glutInit" quietly if the
187 * XXX application has not already done so. The "freeglut" community
188 * XXX decided not to go this route (freeglut-developer e-mail from
189 * XXX Steve Baker, 12/16/04, 4:22 PM CST, "Re: [Freeglut-developer]
190 * XXX Desired 'freeglut' behaviour when there is no current window"
192 FREEGLUT_EXIT_IF_NOT_INITIALISED ( "glutCreateWindow" );
194 return fgCreateWindow( NULL, title, fgState.Position.Use,
195 fgState.Position.X, fgState.Position.Y,
196 fgState.Size.Use, fgState.Size.X, fgState.Size.Y,
197 GL_FALSE, GL_FALSE )->ID;
201 * This function creates a sub window.
203 int FGAPIENTRY glutCreateSubWindow( int parentID, int x, int y, int w, int h )
206 SFG_Window* window = NULL;
207 SFG_Window* parent = NULL;
209 FREEGLUT_EXIT_IF_NOT_INITIALISED ( "glutCreateSubWindow" );
210 parent = fgWindowByID( parentID );
211 freeglut_return_val_if_fail( parent != NULL, 0 );
214 x = parent->State.Width + x ;
215 if ( w >= 0 ) x -= w ;
218 if ( w < 0 ) w = parent->State.Width - x + w ;
227 y = parent->State.Height + y ;
228 if ( h >= 0 ) y -= h ;
231 if ( h < 0 ) h = parent->State.Height - y + h ;
238 window = fgCreateWindow( parent, "", GL_TRUE, x, y, GL_TRUE, w, h, GL_FALSE, GL_FALSE );
245 * Destroys a window and all of its subwindows
247 void FGAPIENTRY glutDestroyWindow( int windowID )
250 FREEGLUT_EXIT_IF_NOT_INITIALISED ( "glutDestroyWindow" );
251 window = fgWindowByID( windowID );
252 freeglut_return_if_fail( window != NULL );
254 fgExecutionState ExecState = fgState.ExecState;
255 fgAddToWindowDestroyList( window );
256 fgState.ExecState = ExecState;
261 * This function selects the specified window as the current window
263 void FGAPIENTRY glutSetWindow( int ID )
265 SFG_Window* window = NULL;
267 FREEGLUT_EXIT_IF_NOT_INITIALISED ( "glutSetWindow" );
268 if( fgStructure.CurrentWindow != NULL )
269 if( fgStructure.CurrentWindow->ID == ID )
272 window = fgWindowByID( ID );
275 fgWarning( "glutSetWindow(): window ID %d not found!", ID );
279 fgSetWindow( window );
283 * This function returns the ID number of the current window, 0 if none exists
285 int FGAPIENTRY glutGetWindow( void )
287 SFG_Window *win = fgStructure.CurrentWindow;
289 * Since GLUT did not throw an error if this function was called without a prior call to
290 * "glutInit", this function shouldn't do so here. Instead let us return a zero.
291 * See Feature Request "[ 1307049 ] glutInit check".
293 if ( ! fgState.Initialised )
296 while ( win && win->IsMenu )
298 return win ? win->ID : 0;
302 * This function makes the current window visible
304 void FGAPIENTRY glutShowWindow( void )
306 FREEGLUT_EXIT_IF_NOT_INITIALISED ( "glutShowWindow" );
307 FREEGLUT_EXIT_IF_NO_WINDOW ( "glutShowWindow" );
309 fgPlatformGlutShowWindow ();
311 fgStructure.CurrentWindow->State.Redisplay = GL_TRUE;
315 * This function hides the current window
317 void FGAPIENTRY glutHideWindow( void )
319 FREEGLUT_EXIT_IF_NOT_INITIALISED ( "glutHideWindow" );
320 FREEGLUT_EXIT_IF_NO_WINDOW ( "glutHideWindow" );
322 fgPlatformGlutHideWindow ();
324 fgStructure.CurrentWindow->State.Redisplay = GL_FALSE;
328 * Iconify the current window (top-level windows only)
330 void FGAPIENTRY glutIconifyWindow( void )
332 FREEGLUT_EXIT_IF_NOT_INITIALISED ( "glutIconifyWindow" );
333 FREEGLUT_EXIT_IF_NO_WINDOW ( "glutIconifyWindow" );
335 fgStructure.CurrentWindow->State.Visible = GL_FALSE;
337 fgPlatformGlutIconifyWindow ();
339 fgStructure.CurrentWindow->State.Redisplay = GL_FALSE;
343 * Set the current window's title
345 void FGAPIENTRY glutSetWindowTitle( const char* title )
347 FREEGLUT_EXIT_IF_NOT_INITIALISED ( "glutSetWindowTitle" );
348 FREEGLUT_EXIT_IF_NO_WINDOW ( "glutSetWindowTitle" );
349 if( ! fgStructure.CurrentWindow->Parent )
351 fgPlatformGlutSetWindowTitle ( title );
356 * Set the current window's iconified title
358 void FGAPIENTRY glutSetIconTitle( const char* title )
360 FREEGLUT_EXIT_IF_NOT_INITIALISED ( "glutSetIconTitle" );
361 FREEGLUT_EXIT_IF_NO_WINDOW ( "glutSetIconTitle" );
363 if( ! fgStructure.CurrentWindow->Parent )
365 fgPlatformGlutSetIconTitle ( title );
370 * Change the current window's size
372 void FGAPIENTRY glutReshapeWindow( int width, int height )
374 FREEGLUT_EXIT_IF_NOT_INITIALISED ( "glutReshapeWindow" );
375 FREEGLUT_EXIT_IF_NO_WINDOW ( "glutReshapeWindow" );
377 if (glutGet(GLUT_FULL_SCREEN))
379 /* Leave full screen state before resizing. */
380 glutLeaveFullScreen();
383 fgStructure.CurrentWindow->State.NeedToResize = GL_TRUE;
384 fgStructure.CurrentWindow->State.Width = width ;
385 fgStructure.CurrentWindow->State.Height = height;
389 * Change the current window's position
391 void FGAPIENTRY glutPositionWindow( int x, int y )
393 FREEGLUT_EXIT_IF_NOT_INITIALISED ( "glutPositionWindow" );
394 FREEGLUT_EXIT_IF_NO_WINDOW ( "glutPositionWindow" );
396 if (glutGet(GLUT_FULL_SCREEN))
398 /* Leave full screen state before moving. */
399 glutLeaveFullScreen();
402 fgPlatformGlutPositionWindow ( x, y );
406 * Lowers the current window (by Z order change)
408 void FGAPIENTRY glutPushWindow( void )
410 FREEGLUT_EXIT_IF_NOT_INITIALISED ( "glutPushWindow" );
411 FREEGLUT_EXIT_IF_NO_WINDOW ( "glutPushWindow" );
413 fgPlatformGlutPushWindow ();
417 * Raises the current window (by Z order change)
419 void FGAPIENTRY glutPopWindow( void )
421 FREEGLUT_EXIT_IF_NOT_INITIALISED ( "glutPopWindow" );
422 FREEGLUT_EXIT_IF_NO_WINDOW ( "glutPopWindow" );
424 fgPlatformGlutPopWindow ();
428 * Resize the current window so that it fits the whole screen
430 void FGAPIENTRY glutFullScreen( void )
434 FREEGLUT_EXIT_IF_NOT_INITIALISED ( "glutFullScreen" );
435 FREEGLUT_EXIT_IF_NO_WINDOW ( "glutFullScreen" );
437 win = fgStructure.CurrentWindow;
441 /* Child windows cannot be made fullscreen, consistent with GLUT's behavior
442 * Also, what would it mean for a child window to be fullscreen, given that it
443 * is confined to its parent?
445 fgWarning("glutFullScreen called on a child window, ignoring...");
448 else if (fgStructure.GameModeWindow != NULL && fgStructure.GameModeWindow->ID==win->ID)
450 /* Ignore fullscreen call on GameMode window, those are always fullscreen already */
454 fgPlatformGlutFullScreen ( win );
458 * If we are fullscreen, resize the current window back to its original size
460 void FGAPIENTRY glutLeaveFullScreen( void )
464 FREEGLUT_EXIT_IF_NOT_INITIALISED ( "glutFullScreen" );
465 FREEGLUT_EXIT_IF_NO_WINDOW ( "glutFullScreen" );
467 win = fgStructure.CurrentWindow;
469 fgPlatformGlutLeaveFullScreen ( win );
473 * Toggle the window's full screen state.
475 void FGAPIENTRY glutFullScreenToggle( void )
479 FREEGLUT_EXIT_IF_NOT_INITIALISED ( "glutFullScreenToggle" );
480 FREEGLUT_EXIT_IF_NO_WINDOW ( "glutFullScreenToggle" );
482 win = fgStructure.CurrentWindow;
484 fgPlatformGlutFullScreenToggle ( win );
488 * A.Donev: Set and retrieve the window's user data
490 void* FGAPIENTRY glutGetWindowData( void )
492 FREEGLUT_EXIT_IF_NOT_INITIALISED ( "glutGetWindowData" );
493 FREEGLUT_EXIT_IF_NO_WINDOW ( "glutGetWindowData" );
494 return fgStructure.CurrentWindow->UserData;
497 void FGAPIENTRY glutSetWindowData(void* data)
499 FREEGLUT_EXIT_IF_NOT_INITIALISED ( "glutSetWindowData" );
500 FREEGLUT_EXIT_IF_NO_WINDOW ( "glutSetWindowData" );
501 fgStructure.CurrentWindow->UserData = data;
504 /*** END OF FILE ***/