when entering game mode, now avoiding call to ChangeDisplaySettingsEx
[freeglut] / src / mswin / fg_gamemode_mswin.c
1 /*
2  * freeglut_gamemode_mswin.c
3  *
4  * The Windows-specific mouse cursor related stuff.
5  *
6  * Copyright (c) 2012 Stephen J. Baker. All Rights Reserved.
7  * Written by John F. Fay, <fayjf@sourceforge.net>
8  * Creation date: Thu Jan 19, 2012
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 #include <GL/freeglut.h>
29 #include "../fg_internal.h"
30
31 /*
32  *
33  *
34  */
35 GLboolean fghPlatformChangeDisplayMode(GLboolean haveToTest, DEVMODE *devModeRequested)
36 {
37     GLboolean success = GL_FALSE;
38     DEVMODE  devModeCurrent;
39     char *fggmstr = NULL;
40     char displayMode[300];
41
42     /* Get current display mode */
43     EnumDisplaySettings( fgDisplay.pDisplay.DisplayName, ENUM_CURRENT_SETTINGS, &devModeCurrent );
44     /* Now see if requested matches current mode, then we're done
45      * There's only four fields we touch:
46      * - dmPelsWidth
47      * - dmPelsHeight
48      * - dmBitsPerPel
49      * - dmDisplayFrequency
50      */
51     if (devModeCurrent.dmPelsWidth       ==devModeRequested->dmPelsWidth &&
52         devModeCurrent.dmPelsHeight      ==devModeRequested->dmPelsHeight && 
53         devModeCurrent.dmBitsPerPel      ==devModeRequested->dmBitsPerPel && 
54         devModeCurrent.dmDisplayFrequency==devModeRequested->dmDisplayFrequency)
55     {
56         if (!haveToTest)
57         {
58             /* update vars in case if actual switch was requested */
59             EnumDisplaySettings( fgDisplay.pDisplay.DisplayName, ENUM_CURRENT_SETTINGS, &devModeCurrent );
60             fgState.GameModeSize.X  = devModeCurrent.dmPelsWidth;        
61             fgState.GameModeSize.Y  = devModeCurrent.dmPelsHeight;
62             fgState.GameModeDepth   = devModeCurrent.dmBitsPerPel;
63             fgState.GameModeRefresh = devModeCurrent.dmDisplayFrequency;
64         }
65
66         /* We're done */
67         return GL_TRUE;
68     }
69
70
71     /* Ok, we do have a mode switch to perform/test */
72     switch ( ChangeDisplaySettingsEx(fgDisplay.pDisplay.DisplayName, devModeRequested, NULL, haveToTest ? CDS_TEST : CDS_FULLSCREEN , NULL) )
73     {
74     case DISP_CHANGE_SUCCESSFUL:
75         success = GL_TRUE;
76
77         if (!haveToTest)
78         {
79             /* update vars in case if windows switched to proper mode */
80             EnumDisplaySettings( fgDisplay.pDisplay.DisplayName, ENUM_CURRENT_SETTINGS, &devModeCurrent );
81             fgState.GameModeSize.X  = devModeCurrent.dmPelsWidth;        
82             fgState.GameModeSize.Y  = devModeCurrent.dmPelsHeight;
83             fgState.GameModeDepth   = devModeCurrent.dmBitsPerPel;
84             fgState.GameModeRefresh = devModeCurrent.dmDisplayFrequency;
85         }
86         break;
87     case DISP_CHANGE_RESTART:
88         fggmstr = "The computer must be restarted for the graphics mode to work.";
89         break;
90     case DISP_CHANGE_BADFLAGS:
91         fggmstr = "An invalid set of flags was passed in.";
92         break;
93     case DISP_CHANGE_BADPARAM:
94         fggmstr = "An invalid parameter was passed in. This can include an invalid flag or combination of flags.";
95         break;
96     case DISP_CHANGE_FAILED:
97         fggmstr = "The display driver failed the specified graphics mode.";
98         break;
99     case DISP_CHANGE_BADMODE:
100         fggmstr = "The graphics mode is not supported.";
101         break;
102     default:
103         fggmstr = "Unknown error in graphics mode???"; /* dunno if it is possible, MSDN does not mention any other error */
104         break;
105     }
106
107     if ( !success )
108     {
109         /* I'd rather get info whats going on in my program than wonder about */
110         /* what magic happens behind my back, its lib for devels after all ;) */
111
112         /* append display mode to error to make things more informative */
113         sprintf(displayMode,"%s Problem with requested mode: %lux%lu:%lu@%lu", fggmstr, devModeRequested->dmPelsWidth, devModeRequested->dmPelsHeight, devModeRequested->dmBitsPerPel, devModeRequested->dmDisplayFrequency);
114         fgWarning(displayMode);
115     }
116     
117     return success;
118 }
119
120 /*
121  * Remembers the current visual settings, so that
122  * we can change them and restore later...
123  */
124 void fgPlatformRememberState( void )
125 {
126     /* Grab the current desktop settings... */
127     EnumDisplaySettings( fgDisplay.pDisplay.DisplayName, ENUM_CURRENT_SETTINGS,
128                          &fgDisplay.pDisplay.DisplayMode );
129
130     /* Make sure we will be restoring all settings needed */
131     fgDisplay.pDisplay.DisplayMode.dmFields |=
132         DM_PELSWIDTH | DM_PELSHEIGHT | DM_BITSPERPEL | DM_DISPLAYFREQUENCY;
133
134 }
135
136 /*
137  * Restores the previously remembered visual settings
138  */
139 void fgPlatformRestoreState( void )
140 {
141     /* Restore the previously remembered desktop display settings */
142     fghPlatformChangeDisplayMode(GL_FALSE,&fgDisplay.pDisplay.DisplayMode);
143 }
144
145
146
147
148 /*
149  * Changes the current display mode to match user's settings
150  */
151 GLboolean fgPlatformChangeDisplayMode( GLboolean haveToTest )
152 {
153     DEVMODE  devMode;
154
155     /* Get current display mode */
156     EnumDisplaySettings( fgDisplay.pDisplay.DisplayName, ENUM_CURRENT_SETTINGS, &devMode ); 
157     devMode.dmFields = 0;
158
159     if (fgState.GameModeSize.X!=-1)
160     {
161         devMode.dmPelsWidth  = fgState.GameModeSize.X;
162         devMode.dmFields |= DM_PELSWIDTH;
163     }
164     if (fgState.GameModeSize.Y!=-1)
165     {
166         devMode.dmPelsHeight  = fgState.GameModeSize.Y;
167         devMode.dmFields |= DM_PELSHEIGHT;
168     }
169     if (fgState.GameModeDepth!=-1)
170     {
171         devMode.dmBitsPerPel  = fgState.GameModeDepth;
172         devMode.dmFields |= DM_BITSPERPEL;
173     }
174     if (fgState.GameModeRefresh!=-1)
175     {
176         devMode.dmDisplayFrequency  = fgState.GameModeRefresh;
177         devMode.dmFields |= DM_DISPLAYFREQUENCY;
178     }
179
180     return fghPlatformChangeDisplayMode(haveToTest, &devMode);
181 }
182
183 void fgPlatformEnterGameMode( void ) 
184 {
185 }
186
187 void fgPlatformLeaveGameMode( void ) 
188 {
189 }