4 * Window management methods.
\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: Fri Dec 3 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 defined(_WIN32_WCE)
\r
33 # include <Aygshell.h>
\r
34 # ifdef FREEGLUT_LIB_PRAGMAS
\r
35 # pragma comment( lib, "Aygshell.lib" )
\r
37 #endif /* defined(_WIN32_WCE) */
\r
41 * TODO BEFORE THE STABLE RELEASE:
\r
43 * fgChooseFBConfig() -- OK, but what about glutInitDisplayString()?
\r
44 * fgSetupPixelFormat -- ignores the display mode settings
\r
45 * fgOpenWindow() -- check the Win32 version, -iconic handling!
\r
46 * fgCloseWindow() -- check the Win32 version
\r
47 * glutCreateWindow() -- Check when default position and size is {-1,-1}
\r
48 * glutCreateSubWindow() -- Check when default position and size is {-1,-1}
\r
49 * glutDestroyWindow() -- check the Win32 version
\r
50 * glutSetWindow() -- check the Win32 version
\r
51 * glutGetWindow() -- OK
\r
52 * glutSetWindowTitle() -- check the Win32 version
\r
53 * glutSetIconTitle() -- check the Win32 version
\r
54 * glutShowWindow() -- check the Win32 version
\r
55 * glutHideWindow() -- check the Win32 version
\r
56 * glutIconifyWindow() -- check the Win32 version
\r
57 * glutReshapeWindow() -- check the Win32 version
\r
58 * glutPositionWindow() -- check the Win32 version
\r
59 * glutPushWindow() -- check the Win32 version
\r
60 * glutPopWindow() -- check the Win32 version
\r
64 extern void fgPlatformSetWindow ( SFG_Window *window );
\r
65 extern void fgPlatformOpenWindow( SFG_Window* window, const char* title,
\r
66 GLboolean positionUse, int x, int y,
\r
67 GLboolean sizeUse, int w, int h,
\r
68 GLboolean gameMode, GLboolean isSubWindow );
\r
69 extern void fgPlatformCloseWindow( SFG_Window* window );
\r
70 extern void fgPlatformGlutShowWindow( void );
\r
71 extern void fgPlatformGlutHideWindow( void );
\r
72 extern void fgPlatformGlutIconifyWindow( void );
\r
73 extern void fgPlatformGlutSetWindowTitle( const char* title );
\r
74 extern void fgPlatformGlutSetIconTitle( const char* title );
\r
75 extern void fgPlatformGlutPositionWindow( int x, int y );
\r
76 extern void fgPlatformGlutPushWindow( void );
\r
77 extern void fgPlatformGlutPopWindow( void );
\r
78 extern void fgPlatformGlutFullScreen( SFG_Window *win );
\r
79 extern void fgPlatformGlutLeaveFullScreen( SFG_Window *win );
\r
80 extern void fgPlatformGlutFullScreenToggle( SFG_Window *win );
\r
83 /* -- PRIVATE FUNCTIONS ---------------------------------------------------- */
\r
85 int fghIsLegacyContextVersionRequested( void )
\r
87 return fgState.MajorVersion < 2 || (fgState.MajorVersion == 2 && fgState.MinorVersion <= 1);
\r
90 int fghIsLegacyContextRequested( void )
\r
92 return fghIsLegacyContextVersionRequested() &&
\r
93 fgState.ContextFlags == 0 &&
\r
94 fgState.ContextProfile == 0;
\r
97 int fghNumberOfAuxBuffersRequested( void )
\r
99 if ( fgState.DisplayMode & GLUT_AUX4 ) {
\r
102 if ( fgState.DisplayMode & GLUT_AUX3 ) {
\r
105 if ( fgState.DisplayMode & GLUT_AUX2 ) {
\r
108 if ( fgState.DisplayMode & GLUT_AUX1 ) { /* NOTE: Same as GLUT_AUX! */
\r
109 return fgState.AuxiliaryBufferNumber;
\r
114 int fghMapBit( int mask, int from, int to )
\r
116 return ( mask & from ) ? to : 0;
\r
120 void fghContextCreationError( void )
\r
122 fgError( "Unable to create OpenGL %d.%d context (flags %x, profile %x)",
\r
123 fgState.MajorVersion, fgState.MinorVersion, fgState.ContextFlags,
\r
124 fgState.ContextProfile );
\r
128 /* -- SYSTEM-DEPENDENT PRIVATE FUNCTIONS ------------------------------------ */
\r
131 * Sets the OpenGL context and the fgStructure "Current Window" pointer to
\r
132 * the window structure passed in.
\r
134 void fgSetWindow ( SFG_Window *window )
\r
136 fgPlatformSetWindow ( window );
\r
138 fgStructure.CurrentWindow = window;
\r
142 * Opens a window. Requires a SFG_Window object created and attached
\r
143 * to the freeglut structure. OpenGL context is created here.
\r
145 void fgOpenWindow( SFG_Window* window, const char* title,
\r
146 GLboolean positionUse, int x, int y,
\r
147 GLboolean sizeUse, int w, int h,
\r
148 GLboolean gameMode, GLboolean isSubWindow )
\r
150 fgPlatformOpenWindow( window, title,
\r
153 gameMode, isSubWindow );
\r
155 fgSetWindow( window );
\r
157 window->Window.DoubleBuffered =
\r
158 ( fgState.DisplayMode & GLUT_DOUBLE ) ? 1 : 0;
\r
160 if ( ! window->Window.DoubleBuffered )
\r
162 glDrawBuffer ( GL_FRONT );
\r
163 glReadBuffer ( GL_FRONT );
\r
168 * Closes a window, destroying the frame and OpenGL context
\r
170 void fgCloseWindow( SFG_Window* window )
\r
172 /* if we're in gamemode and we're closing the gamemode window,
\r
173 * call glutLeaveGameMode first to make sure the gamemode is
\r
174 * properly closed before closing the window
\r
176 if (fgStructure.GameModeWindow != NULL && fgStructure.GameModeWindow->ID==window->ID)
\r
177 glutLeaveGameMode();
\r
179 fgPlatformCloseWindow ( window );
\r
183 /* -- INTERFACE FUNCTIONS -------------------------------------------------- */
\r
186 * Creates a new top-level freeglut window
\r
188 int FGAPIENTRY glutCreateWindow( const char* title )
\r
190 /* XXX GLUT does not exit; it simply calls "glutInit" quietly if the
\r
191 * XXX application has not already done so. The "freeglut" community
\r
192 * XXX decided not to go this route (freeglut-developer e-mail from
\r
193 * XXX Steve Baker, 12/16/04, 4:22 PM CST, "Re: [Freeglut-developer]
\r
194 * XXX Desired 'freeglut' behaviour when there is no current window"
\r
196 FREEGLUT_EXIT_IF_NOT_INITIALISED ( "glutCreateWindow" );
\r
198 return fgCreateWindow( NULL, title, fgState.Position.Use,
\r
199 fgState.Position.X, fgState.Position.Y,
\r
200 fgState.Size.Use, fgState.Size.X, fgState.Size.Y,
\r
201 GL_FALSE, GL_FALSE )->ID;
\r
205 * This function creates a sub window.
\r
207 int FGAPIENTRY glutCreateSubWindow( int parentID, int x, int y, int w, int h )
\r
210 SFG_Window* window = NULL;
\r
211 SFG_Window* parent = NULL;
\r
213 FREEGLUT_EXIT_IF_NOT_INITIALISED ( "glutCreateSubWindow" );
\r
214 parent = fgWindowByID( parentID );
\r
215 freeglut_return_val_if_fail( parent != NULL, 0 );
\r
218 x = parent->State.Width + x ;
\r
219 if ( w >= 0 ) x -= w ;
\r
222 if ( w < 0 ) w = parent->State.Width - x + w ;
\r
231 y = parent->State.Height + y ;
\r
232 if ( h >= 0 ) y -= h ;
\r
235 if ( h < 0 ) h = parent->State.Height - y + h ;
\r
242 window = fgCreateWindow( parent, "", GL_TRUE, x, y, GL_TRUE, w, h, GL_FALSE, GL_FALSE );
\r
249 * Destroys a window and all of its subwindows
\r
251 void FGAPIENTRY glutDestroyWindow( int windowID )
\r
253 SFG_Window* window;
\r
254 FREEGLUT_EXIT_IF_NOT_INITIALISED ( "glutDestroyWindow" );
\r
255 window = fgWindowByID( windowID );
\r
256 freeglut_return_if_fail( window != NULL );
\r
258 fgExecutionState ExecState = fgState.ExecState;
\r
259 fgAddToWindowDestroyList( window );
\r
260 fgState.ExecState = ExecState;
\r
265 * This function selects the current window
\r
267 void FGAPIENTRY glutSetWindow( int ID )
\r
269 SFG_Window* window = NULL;
\r
271 FREEGLUT_EXIT_IF_NOT_INITIALISED ( "glutSetWindow" );
\r
272 if( fgStructure.CurrentWindow != NULL )
\r
273 if( fgStructure.CurrentWindow->ID == ID )
\r
276 window = fgWindowByID( ID );
\r
277 if( window == NULL )
\r
279 fgWarning( "glutSetWindow(): window ID %d not found!", ID );
\r
283 fgSetWindow( window );
\r
287 * This function returns the ID number of the current window, 0 if none exists
\r
289 int FGAPIENTRY glutGetWindow( void )
\r
291 SFG_Window *win = fgStructure.CurrentWindow;
\r
293 * Since GLUT did not throw an error if this function was called without a prior call to
\r
294 * "glutInit", this function shouldn't do so here. Instead let us return a zero.
\r
295 * See Feature Request "[ 1307049 ] glutInit check".
\r
297 if ( ! fgState.Initialised )
\r
300 while ( win && win->IsMenu )
\r
302 return win ? win->ID : 0;
\r
306 * This function makes the current window visible
\r
308 void FGAPIENTRY glutShowWindow( void )
\r
310 FREEGLUT_EXIT_IF_NOT_INITIALISED ( "glutShowWindow" );
\r
311 FREEGLUT_EXIT_IF_NO_WINDOW ( "glutShowWindow" );
\r
313 fgPlatformGlutShowWindow ();
\r
315 fgStructure.CurrentWindow->State.Redisplay = GL_TRUE;
\r
319 * This function hides the current window
\r
321 void FGAPIENTRY glutHideWindow( void )
\r
323 FREEGLUT_EXIT_IF_NOT_INITIALISED ( "glutHideWindow" );
\r
324 FREEGLUT_EXIT_IF_NO_WINDOW ( "glutHideWindow" );
\r
326 fgPlatformGlutHideWindow ();
\r
328 fgStructure.CurrentWindow->State.Redisplay = GL_FALSE;
\r
332 * Iconify the current window (top-level windows only)
\r
334 void FGAPIENTRY glutIconifyWindow( void )
\r
336 FREEGLUT_EXIT_IF_NOT_INITIALISED ( "glutIconifyWindow" );
\r
337 FREEGLUT_EXIT_IF_NO_WINDOW ( "glutIconifyWindow" );
\r
339 fgStructure.CurrentWindow->State.Visible = GL_FALSE;
\r
341 fgPlatformGlutIconifyWindow ();
\r
343 fgStructure.CurrentWindow->State.Redisplay = GL_FALSE;
\r
347 * Set the current window's title
\r
349 void FGAPIENTRY glutSetWindowTitle( const char* title )
\r
351 FREEGLUT_EXIT_IF_NOT_INITIALISED ( "glutSetWindowTitle" );
\r
352 FREEGLUT_EXIT_IF_NO_WINDOW ( "glutSetWindowTitle" );
\r
353 if( ! fgStructure.CurrentWindow->Parent )
\r
355 fgPlatformGlutSetWindowTitle ( title );
\r
360 * Set the current window's iconified title
\r
362 void FGAPIENTRY glutSetIconTitle( const char* title )
\r
364 FREEGLUT_EXIT_IF_NOT_INITIALISED ( "glutSetIconTitle" );
\r
365 FREEGLUT_EXIT_IF_NO_WINDOW ( "glutSetIconTitle" );
\r
367 if( ! fgStructure.CurrentWindow->Parent )
\r
369 fgPlatformGlutSetIconTitle ( title );
\r
374 * Change the current window's size
\r
376 void FGAPIENTRY glutReshapeWindow( int width, int height )
\r
378 FREEGLUT_EXIT_IF_NOT_INITIALISED ( "glutReshapeWindow" );
\r
379 FREEGLUT_EXIT_IF_NO_WINDOW ( "glutReshapeWindow" );
\r
381 if (glutGet(GLUT_FULL_SCREEN))
\r
383 /* Leave full screen state before resizing. */
\r
384 glutLeaveFullScreen();
\r
387 fgStructure.CurrentWindow->State.NeedToResize = GL_TRUE;
\r
388 fgStructure.CurrentWindow->State.Width = width ;
\r
389 fgStructure.CurrentWindow->State.Height = height;
\r
393 * Change the current window's position
\r
395 void FGAPIENTRY glutPositionWindow( int x, int y )
\r
397 FREEGLUT_EXIT_IF_NOT_INITIALISED ( "glutPositionWindow" );
\r
398 FREEGLUT_EXIT_IF_NO_WINDOW ( "glutPositionWindow" );
\r
400 if (glutGet(GLUT_FULL_SCREEN))
\r
402 /* Leave full screen state before moving. */
\r
403 glutLeaveFullScreen();
\r
406 fgPlatformGlutPositionWindow ( x, y );
\r
410 * Lowers the current window (by Z order change)
\r
412 void FGAPIENTRY glutPushWindow( void )
\r
414 FREEGLUT_EXIT_IF_NOT_INITIALISED ( "glutPushWindow" );
\r
415 FREEGLUT_EXIT_IF_NO_WINDOW ( "glutPushWindow" );
\r
417 fgPlatformGlutPushWindow ();
\r
421 * Raises the current window (by Z order change)
\r
423 void FGAPIENTRY glutPopWindow( void )
\r
425 FREEGLUT_EXIT_IF_NOT_INITIALISED ( "glutPopWindow" );
\r
426 FREEGLUT_EXIT_IF_NO_WINDOW ( "glutPopWindow" );
\r
428 fgPlatformGlutPopWindow ();
\r
432 * Resize the current window so that it fits the whole screen
\r
434 void FGAPIENTRY glutFullScreen( void )
\r
438 FREEGLUT_EXIT_IF_NOT_INITIALISED ( "glutFullScreen" );
\r
439 FREEGLUT_EXIT_IF_NO_WINDOW ( "glutFullScreen" );
\r
441 win = fgStructure.CurrentWindow;
\r
445 /* Child windows cannot be made fullscreen, consistent with GLUT's behavior
\r
446 * Also, what would it mean for a child window to be fullscreen, given that it
\r
447 * is confined to its parent?
\r
449 fgWarning("glutFullScreen called on a child window, ignoring...");
\r
452 else if (fgStructure.GameModeWindow != NULL && fgStructure.GameModeWindow->ID==win->ID)
\r
454 /* Ignore fullscreen call on GameMode window, those are always fullscreen already */
\r
458 fgPlatformGlutFullScreen ( win );
\r
462 * If we are fullscreen, resize the current window back to its original size
\r
464 void FGAPIENTRY glutLeaveFullScreen( void )
\r
468 FREEGLUT_EXIT_IF_NOT_INITIALISED ( "glutFullScreen" );
\r
469 FREEGLUT_EXIT_IF_NO_WINDOW ( "glutFullScreen" );
\r
471 win = fgStructure.CurrentWindow;
\r
473 fgPlatformGlutLeaveFullScreen ( win );
\r
477 * Toggle the window's full screen state.
\r
479 void FGAPIENTRY glutFullScreenToggle( void )
\r
483 FREEGLUT_EXIT_IF_NOT_INITIALISED ( "glutFullScreenToggle" );
\r
484 FREEGLUT_EXIT_IF_NO_WINDOW ( "glutFullScreenToggle" );
\r
486 win = fgStructure.CurrentWindow;
\r
488 fgPlatformGlutFullScreenToggle ( win );
\r
492 * A.Donev: Set and retrieve the window's user data
\r
494 void* FGAPIENTRY glutGetWindowData( void )
\r
496 FREEGLUT_EXIT_IF_NOT_INITIALISED ( "glutGetWindowData" );
\r
497 FREEGLUT_EXIT_IF_NO_WINDOW ( "glutGetWindowData" );
\r
498 return fgStructure.CurrentWindow->UserData;
\r
501 void FGAPIENTRY glutSetWindowData(void* data)
\r
503 FREEGLUT_EXIT_IF_NOT_INITIALISED ( "glutSetWindowData" );
\r
504 FREEGLUT_EXIT_IF_NO_WINDOW ( "glutSetWindowData" );
\r
505 fgStructure.CurrentWindow->UserData = data;
\r
508 /*** END OF FILE ***/
\r