Blender  V2.59
GHOST_DisplayManagerWin32.cpp
Go to the documentation of this file.
00001 /*
00002  * $Id: GHOST_DisplayManagerWin32.cpp 38908 2011-08-02 04:28:05Z merwin $
00003  * ***** BEGIN GPL LICENSE BLOCK *****
00004  *
00005  * This program is free software; you can redistribute it and/or
00006  * modify it under the terms of the GNU General Public License
00007  * as published by the Free Software Foundation; either version 2
00008  * of the License, or (at your option) any later version.
00009  *
00010  * This program is distributed in the hope that it will be useful,
00011  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00012  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00013  * GNU General Public License for more details.
00014  *
00015  * You should have received a copy of the GNU General Public License
00016  * along with this program; if not, write to the Free Software Foundation,
00017  * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
00018  *
00019  * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
00020  * All rights reserved.
00021  *
00022  * The Original Code is: all of this file.
00023  *
00024  * Contributor(s): none yet.
00025  *
00026  * ***** END GPL LICENSE BLOCK *****
00027  */
00028 
00035 #include "GHOST_DisplayManagerWin32.h"
00036 #include "GHOST_Debug.h"
00037 
00038 #define _WIN32_WINNT 0x501 // require Windows XP or newer
00039 #define WIN32_LEAN_AND_MEAN
00040 #include <windows.h>
00041 
00042 // We do not support multiple monitors at the moment
00043 #define COMPILE_MULTIMON_STUBS
00044 #ifndef FREE_WINDOWS
00045 #include <multimon.h>
00046 #endif
00047 
00048 
00049 GHOST_DisplayManagerWin32::GHOST_DisplayManagerWin32(void)
00050 {
00051 }
00052 
00053 
00054 GHOST_TSuccess GHOST_DisplayManagerWin32::getNumDisplays(GHOST_TUns8& numDisplays) const
00055 {
00056         // We do not support multiple monitors at the moment
00057         numDisplays = ::GetSystemMetrics(SM_CMONITORS);
00058         return numDisplays > 0 ? GHOST_kSuccess : GHOST_kFailure;
00059 }
00060 
00061 
00062 /*
00063  * When you call EnumDisplaySettings with iModeNum set to zero, the operating system 
00064  * initializes and caches information about the display device. When you call 
00065  * EnumDisplaySettings with iModeNum set to a non-zero value, the function returns 
00066  * the information that was cached the last time the function was called with iModeNum
00067  * set to zero. 
00068  */
00069 GHOST_TSuccess GHOST_DisplayManagerWin32::getNumDisplaySettings(GHOST_TUns8 display, GHOST_TInt32& numSettings) const
00070 {
00071         GHOST_ASSERT((display==kMainDisplay), "GHOST_DisplayManagerWin32::getNumDisplaySettings(): only main displlay is supported");
00072         numSettings = 0;
00073         DEVMODE dm;
00074         while (::EnumDisplaySettings(NULL, numSettings, &dm)) {
00075                 numSettings++;
00076         }
00077         return GHOST_kSuccess;
00078 }
00079 
00080 
00081 GHOST_TSuccess GHOST_DisplayManagerWin32::getDisplaySetting(GHOST_TUns8 display, GHOST_TInt32 index, GHOST_DisplaySetting& setting) const
00082 {
00083         GHOST_ASSERT((display==kMainDisplay), "GHOST_DisplayManagerWin32::getDisplaySetting(): only main display is supported");
00084         GHOST_TSuccess success;
00085         DEVMODE dm;
00086         if (::EnumDisplaySettings(NULL, index, &dm)) {
00087 #ifdef GHOST_DEBUG
00088                 printf("display mode: width=%d, height=%d, bpp=%d, frequency=%d\n", dm.dmPelsWidth, dm.dmPelsHeight, dm.dmBitsPerPel, dm.dmDisplayFrequency);
00089 #endif // GHOST_DEBUG
00090                 setting.xPixels         = dm.dmPelsWidth;
00091                 setting.yPixels         = dm.dmPelsHeight;
00092                 setting.bpp                     = dm.dmBitsPerPel;
00093                 /* When you call the EnumDisplaySettings function, the dmDisplayFrequency member
00094                  * may return with the value 0 or 1. These values represent the display hardware's
00095                  * default refresh rate. This default rate is typically set by switches on a display 
00096                  * card or computer motherboard, or by a configuration program that does not use 
00097                  * Win32 display functions such as ChangeDisplaySettings. 
00098                  */
00099                 /* First, we tried to explicitly set the frequency to 60 if EnumDisplaySettings
00100                  * returned 0 or 1 but this doesn't work since later on an exact match will
00101                  * be searched. And this will never happen if we change it to 60. Now we rely
00102                  * on the default h/w setting.
00103                  */
00104                 setting.frequency = dm.dmDisplayFrequency;
00105                 success = GHOST_kSuccess;
00106         }
00107         else {
00108                 success = GHOST_kFailure;
00109         }
00110         return success;
00111 }
00112 
00113 
00114 GHOST_TSuccess GHOST_DisplayManagerWin32::getCurrentDisplaySetting(GHOST_TUns8 display, GHOST_DisplaySetting& setting) const
00115 {
00116         GHOST_ASSERT((display==kMainDisplay), "GHOST_DisplayManagerWin32::getCurrentDisplaySetting(): only main display is supported");
00117         return getDisplaySetting(kMainDisplay, ENUM_CURRENT_SETTINGS, setting);
00118 }
00119 
00120 
00121 GHOST_TSuccess GHOST_DisplayManagerWin32::setCurrentDisplaySetting(GHOST_TUns8 display, const GHOST_DisplaySetting& setting)
00122 {
00123         GHOST_ASSERT((display==kMainDisplay), "GHOST_DisplayManagerWin32::setCurrentDisplaySetting(): only main display is supported");
00124 
00125         GHOST_DisplaySetting match;
00126         findMatch(display, setting, match);
00127         DEVMODE dm;
00128         int i = 0;
00129         while (::EnumDisplaySettings(NULL, i++, &dm)) {
00130                 if ((dm.dmBitsPerPel == match.bpp) &&
00131                         (dm.dmPelsWidth == match.xPixels) &&
00132                         (dm.dmPelsHeight == match.yPixels) &&
00133                         (dm.dmDisplayFrequency == match.frequency)) {
00134                         break;
00135                 }
00136         }
00137         /*
00138         dm.dmBitsPerPel = match.bpp;
00139         dm.dmPelsWidth = match.xPixels;
00140         dm.dmPelsHeight = match.yPixels;
00141         dm.dmDisplayFrequency = match.frequency;
00142         dm.dmFields = DM_BITSPERPEL | DM_PELSWIDTH | DM_PELSHEIGHT | DM_DISPLAYFREQUENCY;
00143         dm.dmSize = sizeof(DEVMODE);
00144         dm.dmDriverExtra = 0;
00145         */
00146 #ifdef GHOST_DEBUG
00147         printf("display change: Requested settings:\n");
00148         printf("  dmBitsPerPel=%d\n", dm.dmBitsPerPel);
00149         printf("  dmPelsWidth=%d\n", dm.dmPelsWidth);
00150         printf("  dmPelsHeight=%d\n", dm.dmPelsHeight);
00151         printf("  dmDisplayFrequency=%d\n", dm.dmDisplayFrequency);
00152 #endif // GHOST_DEBUG
00153 
00154         LONG status = ::ChangeDisplaySettings(&dm, CDS_FULLSCREEN);
00155 #ifdef GHOST_DEBUG
00156         switch (status)
00157         {
00158         case DISP_CHANGE_SUCCESSFUL:
00159                 printf("display change: The settings change was successful.\n");
00160                 break;
00161         case DISP_CHANGE_RESTART:
00162                 printf("display change: The computer must be restarted in order for the graphics mode to work.\n");
00163                 break;
00164         case DISP_CHANGE_BADFLAGS:
00165                 printf("display change: An invalid set of flags was passed in.\n");
00166                 break;
00167         case DISP_CHANGE_BADPARAM:
00168                 printf("display change: An invalid parameter was passed in. This can include an invalid flag or combination of flags.\n");
00169                 break;
00170         case DISP_CHANGE_FAILED:
00171                 printf("display change: The display driver failed the specified graphics mode.\n");
00172                 break;
00173         case DISP_CHANGE_BADMODE:
00174                 printf("display change: The graphics mode is not supported.\n");
00175                 break;
00176         case DISP_CHANGE_NOTUPDATED:
00177                 printf("display change: Windows NT: Unable to write settings to the registry.\n");
00178                 break;
00179         default:
00180                 printf("display change: Return value invalid\n");
00181                 break;
00182         }
00183 #endif // GHOST_DEBUG
00184         return status == DISP_CHANGE_SUCCESSFUL? GHOST_kSuccess : GHOST_kFailure;
00185 }