//-------------------------------------------------------------------------- bool WindowsVideoDevice::_SetDisplayMode(VeVideoDisplay* pkDisplay, VeDisplayMode* pkMode) noexcept { VeDisplayData* pkDisplayData = (VeDisplayData*)pkDisplay->m_spDriverData; VeDisplayModeData* pkData = (VeDisplayModeData*)pkMode->m_spDriverData; LONG status; status = ChangeDisplaySettingsExA(pkDisplayData->DeviceName, &pkData->DeviceMode, nullptr, CDS_FULLSCREEN, nullptr); if (status != DISP_CHANGE_SUCCESSFUL) { const VeChar8* pcReason = "Unknown reason"; switch (status) { case DISP_CHANGE_BADFLAGS: pcReason = "DISP_CHANGE_BADFLAGS"; break; case DISP_CHANGE_BADMODE: pcReason = "DISP_CHANGE_BADMODE"; break; case DISP_CHANGE_BADPARAM: pcReason = "DISP_CHANGE_BADPARAM"; break; case DISP_CHANGE_FAILED: pcReason = "DISP_CHANGE_FAILED"; break; } VeDebugOutputCore("ChangeDisplaySettingsEx() failed: %s", pcReason); return false; } EnumDisplaySettingsA(pkDisplayData->DeviceName, ENUM_CURRENT_SETTINGS, &pkData->DeviceMode); return true; }
int kinc_display_count_available_modes(int display_index) { DEVMODEA dev_mode = {0}; dev_mode.dmSize = sizeof(DEVMODEA); int i = 0; for (; EnumDisplaySettingsA(displays[display_index].name, i, &dev_mode) != FALSE; ++i) ; return i; }
/*********************************************************************** * EnumDisplaySettingsExA (USER32.@) */ BOOL WINAPI EnumDisplaySettingsExA(LPCSTR lpszDeviceName, DWORD iModeNum, LPDEVMODEA lpDevMode, DWORD dwFlags) { FIXME_(system)("(%s,%lu,%p,%08lx): stub\n", debugstr_a(lpszDeviceName), iModeNum, lpDevMode, dwFlags); return EnumDisplaySettingsA(lpszDeviceName, iModeNum, lpDevMode); }
/*********************************************************************** * EnumDisplaySettings (USER.621) */ BOOL16 WINAPI EnumDisplaySettings16( LPCSTR name, /* [in] huh? */ DWORD n, /* [in] nth entry in display settings list*/ LPDEVMODEA devmode /* [out] devmode for that setting */ ) { TRACE_(system)("(%s, %ld, %p)\n", name, n, devmode); return (BOOL16)EnumDisplaySettingsA(name, n, devmode); }
static BOOL CALLBACK EnumerationCallback(HMONITOR monitor, HDC hdc_unused, LPRECT rect_unused, LPARAM lparam) { MONITORINFOEXA info; memset(&info, 0, sizeof(MONITORINFOEXA)); info.cbSize = sizeof(MONITORINFOEXA); if (GetMonitorInfoA(monitor, (MONITORINFO*)&info) == FALSE) { return FALSE; } int free_slot = 0; for (; free_slot < MAXIMUM_DISPLAYS; ++free_slot) { if (displays[free_slot].monitor == monitor) { return FALSE; } if (displays[free_slot].monitor == NULL) { break; } } DisplayData *display = &displays[free_slot]; strcpy_s(display->name, 32, info.szDevice); display->index = free_slot; display->monitor = monitor; display->primary = (info.dwFlags & MONITORINFOF_PRIMARY) != 0; display->available = true; display->x = info.rcMonitor.left; display->y = info.rcMonitor.top; display->width = info.rcMonitor.right - info.rcMonitor.left; display->height = info.rcMonitor.bottom - info.rcMonitor.top; HDC hdc = CreateDCA(NULL, display->name, NULL, NULL); display->ppi = GetDeviceCaps(hdc, LOGPIXELSX); int scale = GetDeviceCaps(hdc, SCALINGFACTORX); DeleteDC(hdc); if (MyGetDpiForMonitor != NULL) { unsigned dpiX, dpiY; MyGetDpiForMonitor(monitor, MDT_EFFECTIVE_DPI, &dpiX, &dpiY); display->ppi = (int)dpiX; } memset(&original_modes[free_slot], 0, sizeof(DEVMODEA)); original_modes[free_slot].dmSize = sizeof(DEVMODEA); EnumDisplaySettingsA(display->name, ENUM_CURRENT_SETTINGS, &original_modes[free_slot]); display->frequency = original_modes[free_slot].dmDisplayFrequency; display->bpp = original_modes[free_slot].dmBitsPerPel; ++screen_counter; return TRUE; }
kinc_display_mode_t kinc_display_available_mode(int display_index, int mode_index) { DEVMODEA dev_mode = {0}; dev_mode.dmSize = sizeof(DEVMODEA); EnumDisplaySettingsA(displays[display_index].name, mode_index, &dev_mode); kinc_display_mode_t mode; mode.x = displays[display_index].x; mode.y = displays[display_index].y; mode.width = dev_mode.dmPelsWidth; mode.height = dev_mode.dmPelsHeight; mode.frequency = dev_mode.dmDisplayFrequency; mode.bits_per_pixel = dev_mode.dmBitsPerPel; mode.pixels_per_inch = displays[display_index].ppi * mode.width / original_modes[display_index].dmPelsWidth; return mode; }
//Imago - 7/28/09 this function will return the adapter's Windows desktop refresh rate setting // used to set the maximum refresh rate and avoid any PnP issues (thanks Sgt_Baker) int GetMaxRate(int index = 0) { DISPLAY_DEVICEA dd; dd.cb = sizeof(DISPLAY_DEVICEA); if (!EnumDisplayDevicesA(NULL, index, &dd, 0)) { debugf("1: EnumDisplayDevices failed:%d\n", GetLastError()); return 60; } DISPLAY_DEVICEA monitor; monitor.cb = sizeof(DISPLAY_DEVICEA); if (!EnumDisplayDevicesA(dd.DeviceName, 0, &monitor, 0)) { debugf("2: EnumDisplayDevices failed:%d\n", GetLastError()); if (!EnumDisplayDevicesA(NULL, 0, &monitor, 0)) { debugf("22: EnumDisplayDevices failed:%d\n", GetLastError()); return 60; } } DEVMODEA dm; dm.dmSize = sizeof(DEVMODEA); if (!EnumDisplaySettingsA(dd.DeviceName, ENUM_CURRENT_SETTINGS, &dm)) { debugf("3: EnumDisplaySettings failed:%d\n", GetLastError()); return 60; } debugf("Device string: %s\n", dd.DeviceString); debugf("Monitor ID: %s\n", monitor.DeviceID); debugf("Monitor name: %s\n", monitor.DeviceName); debugf("Monitor string: %s\n", monitor.DeviceString); debugf("Refresh rate, in hertz: %d\n", dm.dmDisplayFrequency); debugf("Color depth: %d\n", dm.dmBitsPerPel); debugf("Screen resolution, in pixels: %d x %d\n", dm.dmPelsWidth, dm.dmPelsHeight); return dm.dmDisplayFrequency; }
void Nena::InteractiveTV::Web::View::Initialize( Nena::Application::Window *window, Session *session ) { ::BOOL status; ::DEVMODEA screen; ::Nena::Platform::ZeroValue(&screen); ZeroMemory(&screen, sizeof DEVMODEA); status = EnumDisplaySettingsA(nullptr, ENUM_CURRENT_SETTINGS, &screen); dims.u32[0] = (uint32) screen.dmPelsWidth; dims.u32[1] = (uint32) screen.dmPelsHeight; impl->Initialize( core->impl, // web core dims.u32[0], // screen width dims.u32[1], // screen height session->impl // session config ); }
/*********************************************************************** * EnumDisplaySettingsW (USER32.@) */ BOOL WINAPI EnumDisplaySettingsW(LPCWSTR name,DWORD n,LPDEVMODEW devmode) { DEVMODEA devmodeA; BOOL ret; LPSTR nameA = NULL; if (name){ DWORD len = WideCharToMultiByte( CP_ACP, 0, name, -1, NULL, 0, NULL, NULL ); nameA = HeapAlloc( GetProcessHeap(), 0, len ); if (nameA == NULL){ ERR_(system)("not enough memory to allocate a string conversion buffer for '%s'\n", debugstr_w(name)); return FALSE; } WideCharToMultiByte( CP_ACP, 0, name, -1, nameA, len, NULL, NULL ); } ret = EnumDisplaySettingsA(nameA,n,&devmodeA); if (ret) { devmode->dmBitsPerPel = devmodeA.dmBitsPerPel; devmode->dmPelsHeight = devmodeA.dmPelsHeight; devmode->dmPelsWidth = devmodeA.dmPelsWidth; devmode->dmDisplayFlags = devmodeA.dmDisplayFlags; devmode->dmDisplayFrequency = devmodeA.dmDisplayFrequency; devmode->dmFields = devmodeA.dmFields; /* FIXME: convert rest too, if they are ever returned */ } if (nameA) HeapFree(GetProcessHeap(),0,nameA); return ret; }
static int Win32_GetVideoModeOnScreen(SST_DisplayTarget target, size_t screenIndex, SST_VideoMode* vmodeReturn) { SST_DisplayTarget_Win32* displayTarget = (SST_DisplayTarget_Win32*)target; const DISPLAY_DEVICEA* dev = &displayTarget->devs[screenIndex]; DEVMODEA devMode; int ok = 0; devMode.dmSize = sizeof(devMode); if(EnumDisplaySettingsA(dev->DeviceName, ENUM_CURRENT_SETTINGS, &devMode)) { vmodeReturn->bpp = devMode.dmBitsPerPel; vmodeReturn->width = devMode.dmPelsWidth; vmodeReturn->height = devMode.dmPelsHeight; vmodeReturn->refreshRate = devMode.dmDisplayFrequency; if(vmodeReturn->refreshRate == 1) vmodeReturn->refreshRate = SST_DEFAULT_REFRESHRATE; ok = 1; } return ok; }
bool NativeApp::PreInit() { COut(C_Info) << "Detecting video system..." << std::endl; //#define HACK_DISABLE_GL #if defined(RAD_OPT_GL) && !defined(HACK_DISABLE_GL) { WNDCLASSEXA clex; memset(&clex, 0, sizeof(WNDCLASSEXA)); clex.cbSize = sizeof(WNDCLASSEXA); clex.style = CS_OWNDC; clex.lpfnWndProc = DefWindowProc; clex.hInstance = s_hInstance; clex.lpszClassName = "rad_openGL_ini"; RegisterClassExA(&clex); } HWND wglWnd = CreateWindowA( "rad_openGL_ini", "", WS_CLIPCHILDREN|WS_CLIPSIBLINGS, 0, 0, 100, 100, 0, 0, s_hInstance, 0 ); if (!wglWnd) { COut(C_Error) << "ERROR: Unable to create device window!" << std::endl; return false; } HDC wglDC = GetDC(wglWnd); { PIXELFORMATDESCRIPTOR pfd; memset(&pfd, 0, sizeof(PIXELFORMATDESCRIPTOR)); pfd.nSize = sizeof(PIXELFORMATDESCRIPTOR); pfd.nVersion = 1; pfd.dwFlags = PFD_DRAW_TO_WINDOW|PFD_SUPPORT_OPENGL|PFD_DOUBLEBUFFER; pfd.iPixelType = PFD_TYPE_RGBA; pfd.cColorBits = 24; pfd.cAlphaBits = 8; pfd.cDepthBits = 24; pfd.cStencilBits = 8; pfd.iLayerType = PFD_MAIN_PLANE; int pf = ChoosePixelFormat(wglDC, &pfd); if (pf < 1) { ReleaseDC(wglWnd, wglDC); DestroyWindow(wglWnd); COut(C_Error) << "ERROR: Unable to bind device window pixel format!" << std::endl; return false; } DescribePixelFormat(wglDC, pf, sizeof(PIXELFORMATDESCRIPTOR), &pfd); if (!SetPixelFormat(wglDC, pf, &pfd)) { COut(C_Error) << "ERROR: Unable to bind device window pixel format!" << std::endl; return false; } } HGLRC wglRC = myWglCreateContex(wglDC); if (!wglRC) { COut(C_Error) << "ERROR: Unable to create device window context!" << std::endl; return false; } wglMakeCurrent(wglDC, wglRC); PFNWGLGETEXTENSIONSSTRINGARBPROC wglGetExtensionsStringARB = (PFNWGLGETEXTENSIONSSTRINGARBPROC)wglGetProcAddress("wglGetExtensionsStringARB"); if (!wglGetExtensionsStringARB) { wglGetExtensionsStringARB = (PFNWGLGETEXTENSIONSSTRINGARBPROC)wglGetProcAddress("wglGetExtensionsStringEXT"); if (!wglGetExtensionsStringARB) { wglMakeCurrent(0, 0); wglDeleteContext(wglRC); ReleaseDC(wglWnd, wglDC); DestroyWindow(wglWnd); COut(C_Error) << "Unable to find wglGetExtensionsStringARB" << std::endl; return false; } } const char *wglStrings = wglGetExtensionsStringARB(wglDC); if (wglStrings) COut(C_Info) << "wglGetExtensionsStringARB: " << wglStrings << std::endl; if (!wglStrings || !string::strstr(wglStrings, "WGL_ARB_pixel_format")) { wglMakeCurrent(0, 0); wglDeleteContext(wglRC); ReleaseDC(wglWnd, wglDC); DestroyWindow(wglWnd); COut(C_Error) << "WGL_ARB_pixel_format is required but not found." << std::endl; return false; } bool multiSample = false; if (string::strstr(wglStrings, "WGL_ARB_multisample")) multiSample = true; PFNWGLCHOOSEPIXELFORMATARBPROC wglChoosePixelFormatARB = (PFNWGLCHOOSEPIXELFORMATARBPROC)wglGetProcAddress("wglChoosePixelFormatARB"); PFNWGLGETPIXELFORMATATTRIBIVARBPROC wglGetPixelFormatAttribivARB = (PFNWGLGETPIXELFORMATATTRIBIVARBPROC)wglGetProcAddress("wglGetPixelFormatAttribivARB"); #endif DISPLAY_DEVICEA wdd; for (int i = 0; ; ++i) { wdd.cb = sizeof(DISPLAY_DEVICEA); if (!EnumDisplayDevicesA(0, (DWORD)i, &wdd, 0)) break; if (!(wdd.StateFlags&DISPLAY_DEVICE_ACTIVE)) continue; ::DisplayDevice::Ref _dd(new (ZEngine) ::DisplayDevice()); DisplayDevice *dd = &_dd->m_imp; dd->m_vars.reset(new (ZEngine) DDVars()); DDVars *ddv = DDVars::Get(dd->m_vars); memcpy(&ddv->dd, &wdd, sizeof(DISPLAY_DEVICEA)); if (wdd.StateFlags&DISPLAY_DEVICE_PRIMARY_DEVICE) { dd->m_primary = true; } else { dd->m_primary = false; } DEVMODEA dm; dm.dmSize = sizeof(DEVMODEA); BOOL r = EnumDisplaySettingsA(ddv->dd.DeviceName, ENUM_CURRENT_SETTINGS, &dm); if (!r || ((dm.dmFields&kRequiredDMFields) != kRequiredDMFields)) { if (dd->m_primary) { // this is kinda bad COut(C_Error) << "ERROR: failed to enumerate primary display, initialization failed." << std::endl; return false; } continue; } if (!(dm.dmFields & DM_POSITION)) { // dmPosition is not valid, meaning we cannot identify this as secondary monitor... if (dd->m_primary) { dm.dmPosition.x = 0; dm.dmPosition.y = 0; dm.dmFields |= DM_POSITION; } else { continue; // this monitor cannot be identified. } } string::ncpy((char*)dm.dmDeviceName, wdd.DeviceName, 32); memcpy(&ddv->dm, &dm, sizeof(DEVMODEA)); dd->m_defMode = VidModeFromDevMode(dm); dd->m_curMode = dd->m_defMode; dd->m_maxMSAA = 0; dd->m_maxAnisotropy = 0; // enumerate valid display modes. COut(C_Info) << "Display " << i << ": '" << ddv->dd.DeviceName << " - " << ddv->dd.DeviceString << "':" << std::endl; for (int k = 0; ; ++k) { dm.dmSize = sizeof(DEVMODEA); if (!EnumDisplaySettingsA(ddv->dd.DeviceName, k, &dm)) break; if ((dm.dmFields&kRequiredDMFields) != kRequiredDMFields) continue; if (dm.dmBitsPerPel < 32) continue; r::VidMode m = VidModeFromDevMode(dm); r::VidModeVec::iterator it; for (it = dd->m_vidModes.begin(); it != dd->m_vidModes.end(); ++it) { r::VidMode &x = *it; if (x.w == m.w && x.h == m.h) { // matches. // prefer we use the same hz as our desktop... if (m.hz == dd->m_defMode.hz) x.hz = m.hz; break; } } if (it == dd->m_vidModes.end()) dd->m_vidModes.push_back(m); } for (r::VidModeVec::const_iterator it = dd->m_vidModes.begin(); it != dd->m_vidModes.end(); ++it) { const r::VidMode &m = *it; COut(C_Info) << "\t" << (it-dd->m_vidModes.begin()) << ": " << m.w << "x" << m.h << "x" << m.bpp << " @ " << m.hz << "hz" << std::endl; } if (dd->m_vidModes.empty()) { if (dd->m_primary) { COut(C_Error) << "ERROR: primary display '" << ddv->dd.DeviceName << "' is invalid, initialization failed." << std::endl; return false; } continue; } #if defined(RAD_OPT_GL) && !defined(HACK_DISABLE_GL) if (multiSample) { int maxSamples = 0; int reqAttribs[9] = { WGL_SUPPORT_OPENGL_ARB, WGL_DRAW_TO_WINDOW_ARB, WGL_ACCELERATION_ARB, WGL_PIXEL_TYPE_ARB, WGL_COLOR_BITS_ARB, WGL_ALPHA_BITS_ARB, WGL_DEPTH_BITS_ARB, WGL_STENCIL_BITS_ARB, WGL_SAMPLES_ARB }; int attribs[9]; // Enumerate all pixel formats, find highest multi-sample count for (int k = 1; ; ++k) { // PF's are 1 based if (!wglGetPixelFormatAttribivARB(wglDC, k, PFD_MAIN_PLANE, 9, reqAttribs, attribs)) break; if (attribs[0] != TRUE) continue; if (attribs[1] != TRUE) continue; if (attribs[2] != WGL_FULL_ACCELERATION_ARB) continue; if (attribs[3] != WGL_TYPE_RGBA_ARB) continue; if (attribs[4] < 24) continue; if (attribs[5] < 8) continue; if (attribs[6] < 24) continue; if (attribs[7] < 8) continue; if (maxSamples < attribs[8]) maxSamples = attribs[8]; if (maxSamples >= kMaxMultiSample) break; } dd->m_maxMSAA = maxSamples; } const char *glExt = (const char *)glGetString(GL_EXTENSIONS); if (glExt && string::strstr(glExt, "GL_EXT_texture_filter_anisotropic")) { GLint maxAnisotropy; glGetIntegerv(GL_MAX_TEXTURE_MAX_ANISOTROPY_EXT, &maxAnisotropy); dd->m_maxAnisotropy = maxAnisotropy; } #endif m_displayDevices.push_back(_dd); if (dd->m_primary) m_primaryDisplay = _dd; } if (!m_primaryDisplay) { COut(C_Error) << "ERROR: no primary display detected, initialization failed!" << std::endl; return false; } return true; }
//-------------------------------------------------------------------------- static bool GetDisplayMode(LPCSTR deviceName, DWORD index, VeDisplayMode* mode) noexcept { VeDisplayModeData* data; DEVMODEA devmode; HDC hdc; devmode.dmSize = sizeof(devmode); devmode.dmDriverExtra = 0; if (!EnumDisplaySettingsA(deviceName, index, &devmode)) { return false; } data = VE_NEW VeDisplayModeData; VE_ASSERT(data); data->DeviceMode = devmode; data->DeviceMode.dmFields = (DM_BITSPERPEL | DM_PELSWIDTH | DM_PELSHEIGHT | DM_DISPLAYFREQUENCY | DM_DISPLAYFLAGS); data->ScaleX = 1.0f; data->ScaleY = 1.0f; mode->m_u32Format = VE_PIXELFORMAT_UNKNOWN; mode->m_i32Width = devmode.dmPelsWidth; mode->m_i32Height = devmode.dmPelsHeight; mode->m_i32RefreshRate = devmode.dmDisplayFrequency; mode->m_spDriverData = data; if (index == ENUM_CURRENT_SETTINGS && (hdc = CreateDCA(deviceName, nullptr, nullptr, nullptr)) != nullptr) { char bmi_data[sizeof(BITMAPINFOHEADER) + 256 * sizeof(RGBQUAD)]; LPBITMAPINFO bmi; HBITMAP hbm; int logical_width = GetDeviceCaps(hdc, HORZRES); int logical_height = GetDeviceCaps(hdc, VERTRES); data->ScaleX = (float)logical_width / devmode.dmPelsWidth; data->ScaleY = (float)logical_height / devmode.dmPelsHeight; mode->m_i32Width = logical_width; mode->m_i32Height = logical_height; VeZeroMemory(bmi_data, sizeof(bmi_data)); bmi = (LPBITMAPINFO)bmi_data; bmi->bmiHeader.biSize = sizeof(BITMAPINFOHEADER); hbm = CreateCompatibleBitmap(hdc, 1, 1); GetDIBits(hdc, hbm, 0, 1, nullptr, bmi, DIB_RGB_COLORS); GetDIBits(hdc, hbm, 0, 1, nullptr, bmi, DIB_RGB_COLORS); DeleteObject(hbm); DeleteDC(hdc); if (bmi->bmiHeader.biCompression == BI_BITFIELDS) { switch (*(VeUInt32 *)bmi->bmiColors) { case 0x00FF0000: mode->m_u32Format = VE_PIXELFORMAT_RGB888; break; case 0x000000FF: mode->m_u32Format = VE_PIXELFORMAT_BGR888; break; case 0xF800: mode->m_u32Format = VE_PIXELFORMAT_RGB565; break; case 0x7C00: mode->m_u32Format = VE_PIXELFORMAT_RGB555; break; } } else if (bmi->bmiHeader.biBitCount == 8) { mode->m_u32Format = VE_PIXELFORMAT_INDEX8; } else if (bmi->bmiHeader.biBitCount == 4) { mode->m_u32Format = VE_PIXELFORMAT_INDEX4LSB; } } else { if ((devmode.dmFields & DM_BITSPERPEL) == DM_BITSPERPEL) { switch (devmode.dmBitsPerPel) { case 32: mode->m_u32Format = VE_PIXELFORMAT_RGB888; break; case 24: mode->m_u32Format = VE_PIXELFORMAT_RGB24; break; case 16: mode->m_u32Format = VE_PIXELFORMAT_RGB565; break; case 15: mode->m_u32Format = VE_PIXELFORMAT_RGB555; break; case 8: mode->m_u32Format = VE_PIXELFORMAT_INDEX8; break; case 4: mode->m_u32Format = VE_PIXELFORMAT_INDEX4LSB; break; } } } return true; }
int DxVsyncSource::vsyncThread(void* context) { DxVsyncSource* me = reinterpret_cast<DxVsyncSource*>(context); SDL_SetThreadPriority(SDL_THREAD_PRIORITY_HIGH); D3DKMT_OPENADAPTERFROMHDC openAdapterParams = {}; HMONITOR lastMonitor = nullptr; DEVMODEA monitorMode; monitorMode.dmSize = sizeof(monitorMode); while (SDL_AtomicGet(&me->m_Stopping) == 0) { D3DKMT_WAITFORVERTICALBLANKEVENT waitForVblankEventParams; NTSTATUS status; // If the monitor has changed from last time, open the new adapter HMONITOR currentMonitor = MonitorFromWindow(me->m_Window, MONITOR_DEFAULTTONEAREST); if (currentMonitor != lastMonitor) { MONITORINFOEXA monitorInfo = {}; monitorInfo.cbSize = sizeof(monitorInfo); if (!GetMonitorInfoA(currentMonitor, &monitorInfo)) { SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "GetMonitorInfo() failed: %d", GetLastError()); SDL_Delay(10); continue; } if (!EnumDisplaySettingsA(monitorInfo.szDevice, ENUM_CURRENT_SETTINGS, &monitorMode)) { SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "EnumDisplaySettings() failed: %d", GetLastError()); SDL_Delay(10); continue; } SDL_LogInfo(SDL_LOG_CATEGORY_APPLICATION, "Monitor changed: %s %d Hz", monitorInfo.szDevice, monitorMode.dmDisplayFrequency); if (openAdapterParams.hAdapter != 0) { D3DKMT_CLOSEADAPTER closeAdapterParams = {}; closeAdapterParams.hAdapter = openAdapterParams.hAdapter; me->m_D3DKMTCloseAdapter(&closeAdapterParams); } openAdapterParams.hDc = CreateDCA(nullptr, monitorInfo.szDevice, nullptr, nullptr); if (!openAdapterParams.hDc) { SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "CreateDC() failed: %d", GetLastError()); SDL_Delay(10); continue; } status = me->m_D3DKMTOpenAdapterFromHdc(&openAdapterParams); DeleteDC(openAdapterParams.hDc); if (status != STATUS_SUCCESS) { SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "D3DKMTOpenAdapterFromHdc() failed: %x", status); SDL_Delay(10); continue; } lastMonitor = currentMonitor; } waitForVblankEventParams.hAdapter = openAdapterParams.hAdapter; waitForVblankEventParams.hDevice = 0; waitForVblankEventParams.VidPnSourceId = openAdapterParams.VidPnSourceId; status = me->m_D3DKMTWaitForVerticalBlankEvent(&waitForVblankEventParams); if (status != STATUS_SUCCESS) { SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "D3DKMTWaitForVerticalBlankEvent() failed: %x", status); SDL_Delay(10); continue; } me->m_Pacer->vsyncCallback(1000 / me->m_DisplayFps); } if (openAdapterParams.hAdapter != 0) { D3DKMT_CLOSEADAPTER closeAdapterParams = {}; closeAdapterParams.hAdapter = openAdapterParams.hAdapter; me->m_D3DKMTCloseAdapter(&closeAdapterParams); } return 0; }