Setting the line endings and keywords on a bunch of new text files
[freeglut] / src / Common / freeglut_window.c
1 /*
2  * freeglut_window.c
3  *
4  * Window management methods.
5  *
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
9  *
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:
16  *
17  * The above copyright notice and this permission notice shall be included
18  * in all copies or substantial portions of the Software.
19  *
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.
26  */
27
28 #define FREEGLUT_BUILDING_LIB
29 #include <GL/freeglut.h>
30 #include "freeglut_internal.h"
31
32 #if defined(_WIN32_WCE)
33 #   include <Aygshell.h>
34 #   ifdef FREEGLUT_LIB_PRAGMAS
35 #       pragma comment( lib, "Aygshell.lib" )
36 #   endif
37 #endif /* defined(_WIN32_WCE) */
38
39
40 /*
41  * TODO BEFORE THE STABLE RELEASE:
42  *
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  *  glutGetWindow()         -- OK
51  *  glutSetWindowTitle()    -- check the Win32 version
52  *  glutSetIconTitle()      -- check the Win32 version
53  *  glutShowWindow()        -- check the Win32 version
54  *  glutHideWindow()        -- check the Win32 version
55  *  glutIconifyWindow()     -- check the Win32 version
56  *  glutReshapeWindow()     -- check the Win32 version
57  *  glutPositionWindow()    -- check the Win32 version
58  *  glutPushWindow()        -- check the Win32 version
59  *  glutPopWindow()         -- check the Win32 version
60  */
61
62
63 extern void fgPlatformSetWindow ( SFG_Window *window );
64 extern void fgPlatformOpenWindow( SFG_Window* window, const char* title,
65                                   GLboolean positionUse, int x, int y,
66                                   GLboolean sizeUse, int w, int h,
67                                   GLboolean gameMode, GLboolean isSubWindow );
68 extern void fgPlatformCloseWindow( SFG_Window* window );
69 extern void fgPlatformGlutShowWindow( void );
70 extern void fgPlatformGlutHideWindow( void );
71 extern void fgPlatformGlutIconifyWindow( void );
72 extern void fgPlatformGlutSetWindowTitle( const char* title );
73 extern void fgPlatformGlutSetIconTitle( const char* title );
74 extern void fgPlatformGlutPositionWindow( int x, int y );
75 extern void fgPlatformGlutPushWindow( void );
76 extern void fgPlatformGlutPopWindow( void );
77 extern void fgPlatformGlutFullScreen( SFG_Window *win );
78 extern void fgPlatformGlutLeaveFullScreen( SFG_Window *win );
79 extern void fgPlatformGlutFullScreenToggle( SFG_Window *win );
80
81
82 /* -- PRIVATE FUNCTIONS ---------------------------------------------------- */
83
84 int fghIsLegacyContextVersionRequested( void )
85 {
86   return fgState.MajorVersion < 2 || (fgState.MajorVersion == 2 && fgState.MinorVersion <= 1);
87 }
88
89 int fghIsLegacyContextRequested( void )
90 {
91   return fghIsLegacyContextVersionRequested() &&
92          fgState.ContextFlags == 0 &&
93          fgState.ContextProfile == 0;
94 }
95
96 int fghNumberOfAuxBuffersRequested( void )
97 {
98   if ( fgState.DisplayMode & GLUT_AUX4 ) {
99     return 4;
100   }
101   if ( fgState.DisplayMode & GLUT_AUX3 ) {
102     return 3;
103   }
104   if ( fgState.DisplayMode & GLUT_AUX2 ) {
105     return 2;
106   }
107   if ( fgState.DisplayMode & GLUT_AUX1 ) { /* NOTE: Same as GLUT_AUX! */
108     return fgState.AuxiliaryBufferNumber;
109   }
110   return 0;
111 }
112
113 int fghMapBit( int mask, int from, int to )
114 {
115   return ( mask & from ) ? to : 0;
116
117 }
118
119 void fghContextCreationError( void )
120 {
121     fgError( "Unable to create OpenGL %d.%d context (flags %x, profile %x)",
122              fgState.MajorVersion, fgState.MinorVersion, fgState.ContextFlags,
123              fgState.ContextProfile );
124 }
125
126
127 /* -- SYSTEM-DEPENDENT PRIVATE FUNCTIONS ------------------------------------ */
128
129 /*
130  * Sets the OpenGL context and the fgStructure "Current Window" pointer to
131  * the window structure passed in.
132  */
133 void fgSetWindow ( SFG_Window *window )
134 {
135         fgPlatformSetWindow ( window );
136
137     fgStructure.CurrentWindow = window;
138 }
139
140 /*
141  * Opens a window. Requires a SFG_Window object created and attached
142  * to the freeglut structure. OpenGL context is created here.
143  */
144 void fgOpenWindow( SFG_Window* window, const char* title,
145                    GLboolean positionUse, int x, int y,
146                    GLboolean sizeUse, int w, int h,
147                    GLboolean gameMode, GLboolean isSubWindow )
148 {
149         fgPlatformOpenWindow( window, title,
150                    positionUse, x, y,
151                    sizeUse, w, h,
152                    gameMode, isSubWindow );
153
154     fgSetWindow( window );
155
156     window->Window.DoubleBuffered =
157         ( fgState.DisplayMode & GLUT_DOUBLE ) ? 1 : 0;
158
159     if ( ! window->Window.DoubleBuffered )
160     {
161         glDrawBuffer ( GL_FRONT );
162         glReadBuffer ( GL_FRONT );
163     }
164 }
165
166 /*
167  * Closes a window, destroying the frame and OpenGL context
168  */
169 void fgCloseWindow( SFG_Window* window )
170 {
171     /* if we're in gamemode and we're closing the gamemode window,
172      * call glutLeaveGameMode first to make sure the gamemode is
173      * properly closed before closing the window
174      */
175     if (fgStructure.GameModeWindow != NULL && fgStructure.GameModeWindow->ID==window->ID)
176         glutLeaveGameMode();
177
178         fgPlatformCloseWindow ( window );
179 }
180
181
182 /* -- INTERFACE FUNCTIONS -------------------------------------------------- */
183
184 /*
185  * Creates a new top-level freeglut window
186  */
187 int FGAPIENTRY glutCreateWindow( const char* title )
188 {
189     /* XXX GLUT does not exit; it simply calls "glutInit" quietly if the
190      * XXX application has not already done so.  The "freeglut" community
191      * XXX decided not to go this route (freeglut-developer e-mail from
192      * XXX Steve Baker, 12/16/04, 4:22 PM CST, "Re: [Freeglut-developer]
193      * XXX Desired 'freeglut' behaviour when there is no current window"
194      */
195     FREEGLUT_EXIT_IF_NOT_INITIALISED ( "glutCreateWindow" );
196
197     return fgCreateWindow( NULL, title, fgState.Position.Use,
198                            fgState.Position.X, fgState.Position.Y,
199                            fgState.Size.Use, fgState.Size.X, fgState.Size.Y,
200                            GL_FALSE, GL_FALSE )->ID;
201 }
202
203 /*
204  * This function creates a sub window.
205  */
206 int FGAPIENTRY glutCreateSubWindow( int parentID, int x, int y, int w, int h )
207 {
208     int ret = 0;
209     SFG_Window* window = NULL;
210     SFG_Window* parent = NULL;
211
212     FREEGLUT_EXIT_IF_NOT_INITIALISED ( "glutCreateSubWindow" );
213     parent = fgWindowByID( parentID );
214     freeglut_return_val_if_fail( parent != NULL, 0 );
215     if ( x < 0 )
216     {
217         x = parent->State.Width + x ;
218         if ( w >= 0 ) x -= w ;
219     }
220
221     if ( w < 0 ) w = parent->State.Width - x + w ;
222     if ( w < 0 )
223     {
224         x += w ;
225         w = -w ;
226     }
227
228     if ( y < 0 )
229     {
230         y = parent->State.Height + y ;
231         if ( h >= 0 ) y -= h ;
232     }
233
234     if ( h < 0 ) h = parent->State.Height - y + h ;
235     if ( h < 0 )
236     {
237         y += h ;
238         h = -h ;
239     }
240
241     window = fgCreateWindow( parent, "", GL_TRUE, x, y, GL_TRUE, w, h, GL_FALSE, GL_FALSE );
242     ret = window->ID;
243
244     return ret;
245 }
246
247 /*
248  * Destroys a window and all of its subwindows
249  */
250 void FGAPIENTRY glutDestroyWindow( int windowID )
251 {
252     SFG_Window* window;
253     FREEGLUT_EXIT_IF_NOT_INITIALISED ( "glutDestroyWindow" );
254     window = fgWindowByID( windowID );
255     freeglut_return_if_fail( window != NULL );
256     {
257         fgExecutionState ExecState = fgState.ExecState;
258         fgAddToWindowDestroyList( window );
259         fgState.ExecState = ExecState;
260     }
261 }
262
263 /*
264  * This function selects the current window
265  */
266 void FGAPIENTRY glutSetWindow( int ID )
267 {
268     SFG_Window* window = NULL;
269
270     FREEGLUT_EXIT_IF_NOT_INITIALISED ( "glutSetWindow" );
271     if( fgStructure.CurrentWindow != NULL )
272         if( fgStructure.CurrentWindow->ID == ID )
273             return;
274
275     window = fgWindowByID( ID );
276     if( window == NULL )
277     {
278         fgWarning( "glutSetWindow(): window ID %d not found!", ID );
279         return;
280     }
281
282     fgSetWindow( window );
283 }
284
285 /*
286  * This function returns the ID number of the current window, 0 if none exists
287  */
288 int FGAPIENTRY glutGetWindow( void )
289 {
290     SFG_Window *win = fgStructure.CurrentWindow;
291     /*
292      * Since GLUT did not throw an error if this function was called without a prior call to
293      * "glutInit", this function shouldn't do so here.  Instead let us return a zero.
294      * See Feature Request "[ 1307049 ] glutInit check".
295      */
296     if ( ! fgState.Initialised )
297         return 0;
298
299     while ( win && win->IsMenu )
300         win = win->Parent;
301     return win ? win->ID : 0;
302 }
303
304 /*
305  * This function makes the current window visible
306  */
307 void FGAPIENTRY glutShowWindow( void )
308 {
309     FREEGLUT_EXIT_IF_NOT_INITIALISED ( "glutShowWindow" );
310     FREEGLUT_EXIT_IF_NO_WINDOW ( "glutShowWindow" );
311
312         fgPlatformGlutShowWindow ();
313
314     fgStructure.CurrentWindow->State.Redisplay = GL_TRUE;
315 }
316
317 /*
318  * This function hides the current window
319  */
320 void FGAPIENTRY glutHideWindow( void )
321 {
322     FREEGLUT_EXIT_IF_NOT_INITIALISED ( "glutHideWindow" );
323     FREEGLUT_EXIT_IF_NO_WINDOW ( "glutHideWindow" );
324
325         fgPlatformGlutHideWindow ();
326
327     fgStructure.CurrentWindow->State.Redisplay = GL_FALSE;
328 }
329
330 /*
331  * Iconify the current window (top-level windows only)
332  */
333 void FGAPIENTRY glutIconifyWindow( void )
334 {
335     FREEGLUT_EXIT_IF_NOT_INITIALISED ( "glutIconifyWindow" );
336     FREEGLUT_EXIT_IF_NO_WINDOW ( "glutIconifyWindow" );
337
338     fgStructure.CurrentWindow->State.Visible   = GL_FALSE;
339
340         fgPlatformGlutIconifyWindow ();
341
342     fgStructure.CurrentWindow->State.Redisplay = GL_FALSE;
343 }
344
345 /*
346  * Set the current window's title
347  */
348 void FGAPIENTRY glutSetWindowTitle( const char* title )
349 {
350     FREEGLUT_EXIT_IF_NOT_INITIALISED ( "glutSetWindowTitle" );
351     FREEGLUT_EXIT_IF_NO_WINDOW ( "glutSetWindowTitle" );
352     if( ! fgStructure.CurrentWindow->Parent )
353     {
354                 fgPlatformGlutSetWindowTitle ( title );
355     }
356 }
357
358 /*
359  * Set the current window's iconified title
360  */
361 void FGAPIENTRY glutSetIconTitle( const char* title )
362 {
363     FREEGLUT_EXIT_IF_NOT_INITIALISED ( "glutSetIconTitle" );
364     FREEGLUT_EXIT_IF_NO_WINDOW ( "glutSetIconTitle" );
365
366     if( ! fgStructure.CurrentWindow->Parent )
367     {
368                 fgPlatformGlutSetIconTitle ( title );
369     }
370 }
371
372 /*
373  * Change the current window's size
374  */
375 void FGAPIENTRY glutReshapeWindow( int width, int height )
376 {
377     FREEGLUT_EXIT_IF_NOT_INITIALISED ( "glutReshapeWindow" );
378     FREEGLUT_EXIT_IF_NO_WINDOW ( "glutReshapeWindow" );
379
380     if (glutGet(GLUT_FULL_SCREEN))
381     {
382       /*  Leave full screen state before resizing. */
383       glutLeaveFullScreen();
384     }
385
386     fgStructure.CurrentWindow->State.NeedToResize = GL_TRUE;
387     fgStructure.CurrentWindow->State.Width  = width ;
388     fgStructure.CurrentWindow->State.Height = height;
389 }
390
391 /*
392  * Change the current window's position
393  */
394 void FGAPIENTRY glutPositionWindow( int x, int y )
395 {
396     FREEGLUT_EXIT_IF_NOT_INITIALISED ( "glutPositionWindow" );
397     FREEGLUT_EXIT_IF_NO_WINDOW ( "glutPositionWindow" );
398
399     if (glutGet(GLUT_FULL_SCREEN))
400     {
401       /*  Leave full screen state before moving. */
402       glutLeaveFullScreen();
403     }
404
405         fgPlatformGlutPositionWindow ( x, y );
406 }
407
408 /*
409  * Lowers the current window (by Z order change)
410  */
411 void FGAPIENTRY glutPushWindow( void )
412 {
413     FREEGLUT_EXIT_IF_NOT_INITIALISED ( "glutPushWindow" );
414     FREEGLUT_EXIT_IF_NO_WINDOW ( "glutPushWindow" );
415
416         fgPlatformGlutPushWindow ();
417 }
418
419 /*
420  * Raises the current window (by Z order change)
421  */
422 void FGAPIENTRY glutPopWindow( void )
423 {
424     FREEGLUT_EXIT_IF_NOT_INITIALISED ( "glutPopWindow" );
425     FREEGLUT_EXIT_IF_NO_WINDOW ( "glutPopWindow" );
426
427         fgPlatformGlutPopWindow ();
428 }
429
430 /*
431  * Resize the current window so that it fits the whole screen
432  */
433 void FGAPIENTRY glutFullScreen( void )
434 {
435     SFG_Window *win;
436
437     FREEGLUT_EXIT_IF_NOT_INITIALISED ( "glutFullScreen" );
438     FREEGLUT_EXIT_IF_NO_WINDOW ( "glutFullScreen" );
439
440     win = fgStructure.CurrentWindow;
441
442     if (win->Parent)
443     {
444         /* Child windows cannot be made fullscreen, consistent with GLUT's behavior
445          * Also, what would it mean for a child window to be fullscreen, given that it
446          * is confined to its parent?
447          */
448         fgWarning("glutFullScreen called on a child window, ignoring...");
449         return;
450     }
451     else if (fgStructure.GameModeWindow != NULL && fgStructure.GameModeWindow->ID==win->ID)
452     {
453         /* Ignore fullscreen call on GameMode window, those are always fullscreen already */
454         return;
455     }
456
457         fgPlatformGlutFullScreen ( win );
458 }
459
460 /*
461  * If we are fullscreen, resize the current window back to its original size
462  */
463 void FGAPIENTRY glutLeaveFullScreen( void )
464 {
465     SFG_Window *win;
466
467     FREEGLUT_EXIT_IF_NOT_INITIALISED ( "glutFullScreen" );
468     FREEGLUT_EXIT_IF_NO_WINDOW ( "glutFullScreen" );
469
470     win = fgStructure.CurrentWindow;
471
472         fgPlatformGlutLeaveFullScreen ( win );
473 }
474
475 /*
476  * Toggle the window's full screen state.
477  */
478 void FGAPIENTRY glutFullScreenToggle( void )
479 {
480     SFG_Window *win;
481
482     FREEGLUT_EXIT_IF_NOT_INITIALISED ( "glutFullScreenToggle" );
483     FREEGLUT_EXIT_IF_NO_WINDOW ( "glutFullScreenToggle" );
484
485     win = fgStructure.CurrentWindow;
486
487         fgPlatformGlutFullScreenToggle ( win );
488 }
489
490 /*
491  * A.Donev: Set and retrieve the window's user data
492  */
493 void* FGAPIENTRY glutGetWindowData( void )
494 {
495     FREEGLUT_EXIT_IF_NOT_INITIALISED ( "glutGetWindowData" );
496     FREEGLUT_EXIT_IF_NO_WINDOW ( "glutGetWindowData" );
497     return fgStructure.CurrentWindow->UserData;
498 }
499
500 void FGAPIENTRY glutSetWindowData(void* data)
501 {
502     FREEGLUT_EXIT_IF_NOT_INITIALISED ( "glutSetWindowData" );
503     FREEGLUT_EXIT_IF_NO_WINDOW ( "glutSetWindowData" );
504     fgStructure.CurrentWindow->UserData = data;
505 }
506
507 /*** END OF FILE ***/