Blender V2.61 - r43446

GHOST_DisplayManagerWin32.cpp

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