add back ghost/guardedalloc from trunk
[blender-staging.git] / intern / ghost / intern / GHOST_DisplayManagerWin32.cpp
1 /*
2  * $Id$
3  * ***** BEGIN GPL LICENSE BLOCK *****
4  *
5  * This program is free software; you can redistribute it and/or
6  * modify it under the terms of the GNU General Public License
7  * as published by the Free Software Foundation; either version 2
8  * of the License, or (at your option) any later version.
9  *
10  * This program is distributed in the hope that it will be useful,
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13  * GNU General Public License for more details.
14  *
15  * You should have received a copy of the GNU General Public License
16  * along with this program; if not, write to the Free Software Foundation,
17  * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
18  *
19  * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
20  * All rights reserved.
21  *
22  * The Original Code is: all of this file.
23  *
24  * Contributor(s): none yet.
25  *
26  * ***** END GPL LICENSE BLOCK *****
27  */
28
29 /** \file ghost/intern/GHOST_DisplayManagerWin32.cpp
30  *  \ingroup GHOST
31  *  \author     Maarten Gribnau
32  *  \date       September 21, 2001
33  */
34
35 #include "GHOST_DisplayManagerWin32.h"
36 #include "GHOST_Debug.h"
37
38 // We do not support multiple monitors at the moment
39 #include <windows.h>
40 #define COMPILE_MULTIMON_STUBS
41 #ifndef FREE_WINDOWS
42 #include <multimon.h>
43 #endif
44
45
46 GHOST_DisplayManagerWin32::GHOST_DisplayManagerWin32(void)
47 {
48 }
49
50
51 GHOST_TSuccess GHOST_DisplayManagerWin32::getNumDisplays(GHOST_TUns8& numDisplays) const
52 {
53         // We do not support multiple monitors at the moment
54         numDisplays = ::GetSystemMetrics(SM_CMONITORS);
55         return numDisplays > 0 ? GHOST_kSuccess : GHOST_kFailure;
56 }
57
58
59 /*
60  * When you call EnumDisplaySettings with iModeNum set to zero, the operating system 
61  * initializes and caches information about the display device. When you call 
62  * EnumDisplaySettings with iModeNum set to a non-zero value, the function returns 
63  * the information that was cached the last time the function was called with iModeNum
64  * set to zero. 
65  */
66 GHOST_TSuccess GHOST_DisplayManagerWin32::getNumDisplaySettings(GHOST_TUns8 display, GHOST_TInt32& numSettings) const
67 {
68         GHOST_ASSERT((display==kMainDisplay), "GHOST_DisplayManagerWin32::getNumDisplaySettings(): only main displlay is supported");
69         numSettings = 0;
70         DEVMODE dm;
71         while (::EnumDisplaySettings(NULL, numSettings, &dm)) {
72                 numSettings++;
73         }
74         return GHOST_kSuccess;
75 }
76
77
78 GHOST_TSuccess GHOST_DisplayManagerWin32::getDisplaySetting(GHOST_TUns8 display, GHOST_TInt32 index, GHOST_DisplaySetting& setting) const
79 {
80         GHOST_ASSERT((display==kMainDisplay), "GHOST_DisplayManagerWin32::getDisplaySetting(): only main display is supported");
81         GHOST_TSuccess success;
82         DEVMODE dm;
83         if (::EnumDisplaySettings(NULL, index, &dm)) {
84 #ifdef GHOST_DEBUG
85                 printf("display mode: width=%d, height=%d, bpp=%d, frequency=%d\n", dm.dmPelsWidth, dm.dmPelsHeight, dm.dmBitsPerPel, dm.dmDisplayFrequency);
86 #endif // GHOST_DEBUG
87                 setting.xPixels         = dm.dmPelsWidth;
88                 setting.yPixels         = dm.dmPelsHeight;
89                 setting.bpp                     = dm.dmBitsPerPel;
90                 /* When you call the EnumDisplaySettings function, the dmDisplayFrequency member
91                  * may return with the value 0 or 1. These values represent the display hardware's
92                  * default refresh rate. This default rate is typically set by switches on a display 
93                  * card or computer motherboard, or by a configuration program that does not use 
94                  * Win32 display functions such as ChangeDisplaySettings. 
95                  */
96                 /* First, we tried to explicitly set the frequency to 60 if EnumDisplaySettings
97                  * returned 0 or 1 but this doesn't work since later on an exact match will
98                  * be searched. And this will never happen if we change it to 60. Now we rely
99                  * on the default h/w setting.
100                  */
101                 setting.frequency = dm.dmDisplayFrequency;
102                 success = GHOST_kSuccess;
103         }
104         else {
105                 success = GHOST_kFailure;
106         }
107         return success;
108 }
109
110
111 GHOST_TSuccess GHOST_DisplayManagerWin32::getCurrentDisplaySetting(GHOST_TUns8 display, GHOST_DisplaySetting& setting) const
112 {
113         GHOST_ASSERT((display==kMainDisplay), "GHOST_DisplayManagerWin32::getCurrentDisplaySetting(): only main display is supported");
114         return getDisplaySetting(kMainDisplay, ENUM_CURRENT_SETTINGS, setting);
115 }
116
117
118 GHOST_TSuccess GHOST_DisplayManagerWin32::setCurrentDisplaySetting(GHOST_TUns8 display, const GHOST_DisplaySetting& setting)
119 {
120         GHOST_ASSERT((display==kMainDisplay), "GHOST_DisplayManagerWin32::setCurrentDisplaySetting(): only main display is supported");
121
122         GHOST_DisplaySetting match;
123         findMatch(display, setting, match);
124         DEVMODE dm;
125         int i = 0;
126         while (::EnumDisplaySettings(NULL, i++, &dm)) {
127                 if ((dm.dmBitsPerPel == match.bpp) &&
128                         (dm.dmPelsWidth == match.xPixels) &&
129                         (dm.dmPelsHeight == match.yPixels) &&
130                         (dm.dmDisplayFrequency == match.frequency)) {
131                         break;
132                 }
133         }
134         /*
135         dm.dmBitsPerPel = match.bpp;
136         dm.dmPelsWidth = match.xPixels;
137         dm.dmPelsHeight = match.yPixels;
138         dm.dmDisplayFrequency = match.frequency;
139         dm.dmFields = DM_BITSPERPEL | DM_PELSWIDTH | DM_PELSHEIGHT | DM_DISPLAYFREQUENCY;
140         dm.dmSize = sizeof(DEVMODE);
141         dm.dmDriverExtra = 0;
142         */
143 #ifdef GHOST_DEBUG
144         printf("display change: Requested settings:\n");
145         printf("  dmBitsPerPel=%d\n", dm.dmBitsPerPel);
146         printf("  dmPelsWidth=%d\n", dm.dmPelsWidth);
147         printf("  dmPelsHeight=%d\n", dm.dmPelsHeight);
148         printf("  dmDisplayFrequency=%d\n", dm.dmDisplayFrequency);
149 #endif // GHOST_DEBUG
150
151         LONG status = ::ChangeDisplaySettings(&dm, CDS_FULLSCREEN);
152 #ifdef GHOST_DEBUG
153         switch (status)
154         {
155         case DISP_CHANGE_SUCCESSFUL:
156                 printf("display change: The settings change was successful.\n");
157                 break;
158         case DISP_CHANGE_RESTART:
159                 printf("display change: The computer must be restarted in order for the graphics mode to work.\n");
160                 break;
161         case DISP_CHANGE_BADFLAGS:
162                 printf("display change: An invalid set of flags was passed in.\n");
163                 break;
164         case DISP_CHANGE_BADPARAM:
165                 printf("display change: An invalid parameter was passed in. This can include an invalid flag or combination of flags.\n");
166                 break;
167         case DISP_CHANGE_FAILED:
168                 printf("display change: The display driver failed the specified graphics mode.\n");
169                 break;
170         case DISP_CHANGE_BADMODE:
171                 printf("display change: The graphics mode is not supported.\n");
172                 break;
173         case DISP_CHANGE_NOTUPDATED:
174                 printf("display change: Windows NT: Unable to write settings to the registry.\n");
175                 break;
176         default:
177                 printf("display change: Return value invalid\n");
178                 break;
179         }
180 #endif // GHOST_DEBUG
181         return status == DISP_CHANGE_SUCCESSFUL? GHOST_kSuccess : GHOST_kFailure;
182 }