00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028 #include "internal.h"
00029
00030 #include <stdlib.h>
00031 #include <string.h>
00032 #include <limits.h>
00033 #include <malloc.h>
00034
00035
00036 #ifndef EDS_ROTATEDMODE
00037 #define EDS_ROTATEDMODE 0x00000004
00038 #endif
00039 #ifndef DISPLAY_DEVICE_ACTIVE
00040 #define DISPLAY_DEVICE_ACTIVE 0x00000001
00041 #endif
00042
00043
00047
00048
00049
00050 GLboolean _glfwSetVideoMode(_GLFWmonitor* monitor, const GLFWvidmode* desired)
00051 {
00052 GLFWvidmode current;
00053 const GLFWvidmode* best;
00054 DEVMODEW dm;
00055
00056 best = _glfwChooseVideoMode(monitor, desired);
00057 _glfwPlatformGetVideoMode(monitor, ¤t);
00058 if (_glfwCompareVideoModes(¤t, best) == 0)
00059 return GL_TRUE;
00060
00061 ZeroMemory(&dm, sizeof(dm));
00062 dm.dmSize = sizeof(DEVMODEW);
00063 dm.dmFields = DM_PELSWIDTH | DM_PELSHEIGHT | DM_BITSPERPEL |
00064 DM_DISPLAYFREQUENCY;
00065 dm.dmPelsWidth = best->width;
00066 dm.dmPelsHeight = best->height;
00067 dm.dmBitsPerPel = best->redBits + best->greenBits + best->blueBits;
00068 dm.dmDisplayFrequency = best->refreshRate;
00069
00070 if (dm.dmBitsPerPel < 15 || dm.dmBitsPerPel >= 24)
00071 dm.dmBitsPerPel = 32;
00072
00073 if (ChangeDisplaySettingsExW(monitor->win32.adapterName,
00074 &dm,
00075 NULL,
00076 CDS_FULLSCREEN,
00077 NULL) != DISP_CHANGE_SUCCESSFUL)
00078 {
00079 _glfwInputError(GLFW_PLATFORM_ERROR, "Win32: Failed to set video mode");
00080 return GL_FALSE;
00081 }
00082
00083 monitor->win32.modeChanged = GL_TRUE;
00084 return GL_TRUE;
00085 }
00086
00087
00088
00089 void _glfwRestoreVideoMode(_GLFWmonitor* monitor)
00090 {
00091 if (monitor->win32.modeChanged)
00092 {
00093 ChangeDisplaySettingsExW(monitor->win32.adapterName,
00094 NULL, NULL, CDS_FULLSCREEN, NULL);
00095 monitor->win32.modeChanged = GL_FALSE;
00096 }
00097 }
00098
00099
00103
00104 _GLFWmonitor** _glfwPlatformGetMonitors(int* count)
00105 {
00106 int found = 0;
00107 _GLFWmonitor** monitors = NULL;
00108 DWORD adapterIndex, displayIndex;
00109
00110 *count = 0;
00111
00112 for (adapterIndex = 0; ; adapterIndex++)
00113 {
00114 DISPLAY_DEVICEW adapter;
00115
00116 ZeroMemory(&adapter, sizeof(DISPLAY_DEVICEW));
00117 adapter.cb = sizeof(DISPLAY_DEVICEW);
00118
00119 if (!EnumDisplayDevicesW(NULL, adapterIndex, &adapter, 0))
00120 break;
00121
00122 if (!(adapter.StateFlags & DISPLAY_DEVICE_ACTIVE))
00123 continue;
00124
00125 for (displayIndex = 0; ; displayIndex++)
00126 {
00127 DISPLAY_DEVICEW display;
00128 _GLFWmonitor* monitor;
00129 char* name;
00130 HDC dc;
00131
00132 ZeroMemory(&display, sizeof(DISPLAY_DEVICEW));
00133 display.cb = sizeof(DISPLAY_DEVICEW);
00134
00135 if (!EnumDisplayDevicesW(adapter.DeviceName, displayIndex, &display, 0))
00136 break;
00137
00138 name = _glfwCreateUTF8FromWideString(display.DeviceString);
00139 if (!name)
00140 {
00141 _glfwInputError(GLFW_PLATFORM_ERROR,
00142 "Win32: Failed to convert string to UTF-8");
00143 continue;
00144 }
00145
00146 dc = CreateDCW(L"DISPLAY", adapter.DeviceName, NULL, NULL);
00147
00148 monitor = _glfwAllocMonitor(name,
00149 GetDeviceCaps(dc, HORZSIZE),
00150 GetDeviceCaps(dc, VERTSIZE));
00151
00152 DeleteDC(dc);
00153 free(name);
00154
00155 if (adapter.StateFlags & DISPLAY_DEVICE_MODESPRUNED)
00156 monitor->win32.modesPruned = GL_TRUE;
00157
00158 wcscpy(monitor->win32.adapterName, adapter.DeviceName);
00159 wcscpy(monitor->win32.displayName, display.DeviceName);
00160
00161 WideCharToMultiByte(CP_UTF8, 0,
00162 adapter.DeviceName, -1,
00163 monitor->win32.publicAdapterName,
00164 sizeof(monitor->win32.publicAdapterName),
00165 NULL, NULL);
00166
00167 WideCharToMultiByte(CP_UTF8, 0,
00168 display.DeviceName, -1,
00169 monitor->win32.publicDisplayName,
00170 sizeof(monitor->win32.publicDisplayName),
00171 NULL, NULL);
00172
00173 found++;
00174 monitors = realloc(monitors, sizeof(_GLFWmonitor*) * found);
00175 monitors[found - 1] = monitor;
00176
00177 if (adapter.StateFlags & DISPLAY_DEVICE_PRIMARY_DEVICE &&
00178 displayIndex == 0)
00179 {
00180 _GLFW_SWAP_POINTERS(monitors[0], monitors[found - 1]);
00181 }
00182 }
00183 }
00184
00185 *count = found;
00186 return monitors;
00187 }
00188
00189 GLboolean _glfwPlatformIsSameMonitor(_GLFWmonitor* first, _GLFWmonitor* second)
00190 {
00191 return wcscmp(first->win32.displayName, second->win32.displayName) == 0;
00192 }
00193
00194 void _glfwPlatformGetMonitorPos(_GLFWmonitor* monitor, int* xpos, int* ypos)
00195 {
00196 DEVMODEW settings;
00197 ZeroMemory(&settings, sizeof(DEVMODEW));
00198 settings.dmSize = sizeof(DEVMODEW);
00199
00200 EnumDisplaySettingsExW(monitor->win32.adapterName,
00201 ENUM_CURRENT_SETTINGS,
00202 &settings,
00203 EDS_ROTATEDMODE);
00204
00205 if (xpos)
00206 *xpos = settings.dmPosition.x;
00207 if (ypos)
00208 *ypos = settings.dmPosition.y;
00209 }
00210
00211 GLFWvidmode* _glfwPlatformGetVideoModes(_GLFWmonitor* monitor, int* count)
00212 {
00213 int modeIndex = 0, size = 0;
00214 GLFWvidmode* result = NULL;
00215
00216 *count = 0;
00217
00218 for (;;)
00219 {
00220 int i;
00221 GLFWvidmode mode;
00222 DEVMODEW dm;
00223
00224 ZeroMemory(&dm, sizeof(DEVMODEW));
00225 dm.dmSize = sizeof(DEVMODEW);
00226
00227 if (!EnumDisplaySettingsW(monitor->win32.adapterName, modeIndex, &dm))
00228 break;
00229
00230 modeIndex++;
00231
00232
00233 if (dm.dmBitsPerPel < 15)
00234 continue;
00235
00236 mode.width = dm.dmPelsWidth;
00237 mode.height = dm.dmPelsHeight;
00238 mode.refreshRate = dm.dmDisplayFrequency;
00239 _glfwSplitBPP(dm.dmBitsPerPel,
00240 &mode.redBits,
00241 &mode.greenBits,
00242 &mode.blueBits);
00243
00244 for (i = 0; i < *count; i++)
00245 {
00246 if (_glfwCompareVideoModes(result + i, &mode) == 0)
00247 break;
00248 }
00249
00250
00251 if (i < *count)
00252 continue;
00253
00254 if (monitor->win32.modesPruned)
00255 {
00256
00257 if (ChangeDisplaySettingsExW(monitor->win32.adapterName,
00258 &dm,
00259 NULL,
00260 CDS_TEST,
00261 NULL) != DISP_CHANGE_SUCCESSFUL)
00262 {
00263 continue;
00264 }
00265 }
00266
00267 if (*count == size)
00268 {
00269 if (*count)
00270 size *= 2;
00271 else
00272 size = 128;
00273
00274 result = (GLFWvidmode*) realloc(result, size * sizeof(GLFWvidmode));
00275 }
00276
00277 (*count)++;
00278 result[*count - 1] = mode;
00279 }
00280
00281 return result;
00282 }
00283
00284 void _glfwPlatformGetVideoMode(_GLFWmonitor* monitor, GLFWvidmode* mode)
00285 {
00286 DEVMODEW dm;
00287
00288 ZeroMemory(&dm, sizeof(DEVMODEW));
00289 dm.dmSize = sizeof(DEVMODEW);
00290
00291 EnumDisplaySettingsW(monitor->win32.adapterName, ENUM_CURRENT_SETTINGS, &dm);
00292
00293 mode->width = dm.dmPelsWidth;
00294 mode->height = dm.dmPelsHeight;
00295 mode->refreshRate = dm.dmDisplayFrequency;
00296 _glfwSplitBPP(dm.dmBitsPerPel,
00297 &mode->redBits,
00298 &mode->greenBits,
00299 &mode->blueBits);
00300 }
00301
00302 void _glfwPlatformGetGammaRamp(_GLFWmonitor* monitor, GLFWgammaramp* ramp)
00303 {
00304 HDC dc;
00305 WORD values[768];
00306
00307 dc = CreateDCW(L"DISPLAY", monitor->win32.adapterName, NULL, NULL);
00308 GetDeviceGammaRamp(dc, values);
00309 DeleteDC(dc);
00310
00311 _glfwAllocGammaArrays(ramp, 256);
00312
00313 memcpy(ramp->red, values + 0, 256 * sizeof(unsigned short));
00314 memcpy(ramp->green, values + 256, 256 * sizeof(unsigned short));
00315 memcpy(ramp->blue, values + 512, 256 * sizeof(unsigned short));
00316 }
00317
00318 void _glfwPlatformSetGammaRamp(_GLFWmonitor* monitor, const GLFWgammaramp* ramp)
00319 {
00320 HDC dc;
00321 WORD values[768];
00322
00323 if (ramp->size != 256)
00324 {
00325 _glfwInputError(GLFW_PLATFORM_ERROR,
00326 "Win32: Gamma ramp size must be 256");
00327 return;
00328 }
00329
00330 memcpy(values + 0, ramp->red, 256 * sizeof(unsigned short));
00331 memcpy(values + 256, ramp->green, 256 * sizeof(unsigned short));
00332 memcpy(values + 512, ramp->blue, 256 * sizeof(unsigned short));
00333
00334 dc = CreateDCW(L"DISPLAY", monitor->win32.adapterName, NULL, NULL);
00335 SetDeviceGammaRamp(dc, values);
00336 DeleteDC(dc);
00337 }
00338
00339
00343
00344 GLFWAPI const char* glfwGetWin32Adapter(GLFWmonitor* handle)
00345 {
00346 _GLFWmonitor* monitor = (_GLFWmonitor*) handle;
00347 _GLFW_REQUIRE_INIT_OR_RETURN(NULL);
00348 return monitor->win32.publicAdapterName;
00349 }
00350
00351 GLFWAPI const char* glfwGetWin32Monitor(GLFWmonitor* handle)
00352 {
00353 _GLFWmonitor* monitor = (_GLFWmonitor*) handle;
00354 _GLFW_REQUIRE_INIT_OR_RETURN(NULL);
00355 return monitor->win32.publicDisplayName;
00356 }
00357