diff --git a/src/video/windows/SDL_windowsmodes.c b/src/video/windows/SDL_windowsmodes.c index 2cca6a36b8..04af82f706 100644 --- a/src/video/windows/SDL_windowsmodes.c +++ b/src/video/windows/SDL_windowsmodes.c @@ -238,19 +238,8 @@ static SDL_bool WIN_GetDisplayMode(SDL_VideoDevice *_this, HMONITOR hMonitor, LP return SDL_TRUE; } -/* The win32 API calls in this function require Windows Vista or later. */ -/* *INDENT-OFF* */ /* clang-format off */ -typedef LONG (WINAPI *SDL_WIN32PROC_GetDisplayConfigBufferSizes)(UINT32 flags, UINT32* numPathArrayElements, UINT32* numModeInfoArrayElements); -typedef LONG (WINAPI *SDL_WIN32PROC_QueryDisplayConfig)(UINT32 flags, UINT32* numPathArrayElements, DISPLAYCONFIG_PATH_INFO* pathArray, UINT32* numModeInfoArrayElements, DISPLAYCONFIG_MODE_INFO* modeInfoArray, DISPLAYCONFIG_TOPOLOGY_ID* currentTopologyId); -typedef LONG (WINAPI *SDL_WIN32PROC_DisplayConfigGetDeviceInfo)(DISPLAYCONFIG_DEVICE_INFO_HEADER* requestPacket); -/* *INDENT-ON* */ /* clang-format on */ - -static char *WIN_GetDisplayNameVista(const WCHAR *deviceName) +static char *WIN_GetDisplayNameVista(SDL_VideoData *videodata, const WCHAR *deviceName) { - void *dll; - SDL_WIN32PROC_GetDisplayConfigBufferSizes pGetDisplayConfigBufferSizes; - SDL_WIN32PROC_QueryDisplayConfig pQueryDisplayConfig; - SDL_WIN32PROC_DisplayConfigGetDeviceInfo pDisplayConfigGetDeviceInfo; DISPLAYCONFIG_PATH_INFO *paths = NULL; DISPLAYCONFIG_MODE_INFO *modes = NULL; char *retval = NULL; @@ -259,21 +248,12 @@ static char *WIN_GetDisplayNameVista(const WCHAR *deviceName) UINT32 i; LONG rc; - dll = SDL_LoadObject("USER32.DLL"); - if (!dll) { - return NULL; - } - - pGetDisplayConfigBufferSizes = (SDL_WIN32PROC_GetDisplayConfigBufferSizes)SDL_LoadFunction(dll, "GetDisplayConfigBufferSizes"); - pQueryDisplayConfig = (SDL_WIN32PROC_QueryDisplayConfig)SDL_LoadFunction(dll, "QueryDisplayConfig"); - pDisplayConfigGetDeviceInfo = (SDL_WIN32PROC_DisplayConfigGetDeviceInfo)SDL_LoadFunction(dll, "DisplayConfigGetDeviceInfo"); - - if (!pGetDisplayConfigBufferSizes || !pQueryDisplayConfig || !pDisplayConfigGetDeviceInfo) { - goto WIN_GetDisplayNameVista_failed; + if (!videodata->GetDisplayConfigBufferSizes || !videodata->QueryDisplayConfig || !videodata->DisplayConfigGetDeviceInfo) { + return SDL_FALSE; } do { - rc = pGetDisplayConfigBufferSizes(QDC_ONLY_ACTIVE_PATHS, &pathCount, &modeCount); + rc = videodata->GetDisplayConfigBufferSizes(QDC_ONLY_ACTIVE_PATHS, &pathCount, &modeCount); if (rc != ERROR_SUCCESS) { goto WIN_GetDisplayNameVista_failed; } @@ -287,7 +267,7 @@ static char *WIN_GetDisplayNameVista(const WCHAR *deviceName) goto WIN_GetDisplayNameVista_failed; } - rc = pQueryDisplayConfig(QDC_ONLY_ACTIVE_PATHS, &pathCount, paths, &modeCount, modes, 0); + rc = videodata->QueryDisplayConfig(QDC_ONLY_ACTIVE_PATHS, &pathCount, paths, &modeCount, modes, 0); } while (rc == ERROR_INSUFFICIENT_BUFFER); if (rc == ERROR_SUCCESS) { @@ -300,7 +280,7 @@ static char *WIN_GetDisplayNameVista(const WCHAR *deviceName) sourceName.header.type = DISPLAYCONFIG_DEVICE_INFO_GET_SOURCE_NAME; sourceName.header.size = sizeof(sourceName); sourceName.header.id = paths[i].sourceInfo.id; - rc = pDisplayConfigGetDeviceInfo(&sourceName.header); + rc = videodata->DisplayConfigGetDeviceInfo(&sourceName.header); if (rc != ERROR_SUCCESS) { break; } else if (SDL_wcscmp(deviceName, sourceName.viewGdiDeviceName) != 0) { @@ -312,7 +292,7 @@ static char *WIN_GetDisplayNameVista(const WCHAR *deviceName) targetName.header.id = paths[i].targetInfo.id; targetName.header.type = DISPLAYCONFIG_DEVICE_INFO_GET_TARGET_NAME; targetName.header.size = sizeof(targetName); - rc = pDisplayConfigGetDeviceInfo(&targetName.header); + rc = videodata->DisplayConfigGetDeviceInfo(&targetName.header); if (rc == ERROR_SUCCESS) { retval = WIN_StringToUTF8W(targetName.monitorFriendlyDeviceName); /* if we got an empty string, treat it as failure so we'll fallback @@ -328,14 +308,12 @@ static char *WIN_GetDisplayNameVista(const WCHAR *deviceName) SDL_free(paths); SDL_free(modes); - SDL_UnloadObject(dll); return retval; WIN_GetDisplayNameVista_failed: SDL_free(retval); SDL_free(paths); SDL_free(modes); - SDL_UnloadObject(dll); return NULL; } @@ -391,7 +369,7 @@ static SDL_bool WIN_GetMonitorDESC1(HMONITOR hMonitor, DXGI_OUTPUT_DESC1 *desc) return found; } -static SDL_bool WIN_GetMonitorPathInfo(HMONITOR hMonitor, DISPLAYCONFIG_PATH_INFO *path_info) +static SDL_bool WIN_GetMonitorPathInfo(SDL_VideoData *videodata, HMONITOR hMonitor, DISPLAYCONFIG_PATH_INFO *path_info) { LONG result; MONITORINFOEXW view_info; @@ -402,6 +380,10 @@ static SDL_bool WIN_GetMonitorPathInfo(HMONITOR hMonitor, DISPLAYCONFIG_PATH_INF DISPLAYCONFIG_MODE_INFO *mode_infos = NULL, *new_mode_infos; SDL_bool found = SDL_FALSE; + if (!videodata->GetDisplayConfigBufferSizes || !videodata->QueryDisplayConfig || !videodata->DisplayConfigGetDeviceInfo) { + return SDL_FALSE; + } + SDL_zero(view_info); view_info.cbSize = sizeof(view_info); if (!GetMonitorInfoW(hMonitor, (MONITORINFO *)&view_info)) { @@ -409,7 +391,7 @@ static SDL_bool WIN_GetMonitorPathInfo(HMONITOR hMonitor, DISPLAYCONFIG_PATH_INF } do { - if (GetDisplayConfigBufferSizes(QDC_ONLY_ACTIVE_PATHS, &num_path_array_elements, &num_mode_info_array_elements) != ERROR_SUCCESS) { + if (videodata->GetDisplayConfigBufferSizes(QDC_ONLY_ACTIVE_PATHS, &num_path_array_elements, &num_mode_info_array_elements) != ERROR_SUCCESS) { SDL_free(path_infos); SDL_free(mode_infos); return SDL_FALSE; @@ -427,7 +409,7 @@ static SDL_bool WIN_GetMonitorPathInfo(HMONITOR hMonitor, DISPLAYCONFIG_PATH_INF } mode_infos = new_mode_infos; - result = QueryDisplayConfig(QDC_ONLY_ACTIVE_PATHS, &num_path_array_elements, path_infos, &num_mode_info_array_elements, mode_infos, NULL); + result = videodata->QueryDisplayConfig(QDC_ONLY_ACTIVE_PATHS, &num_path_array_elements, path_infos, &num_mode_info_array_elements, mode_infos, NULL); } while (result == ERROR_INSUFFICIENT_BUFFER); @@ -440,7 +422,7 @@ static SDL_bool WIN_GetMonitorPathInfo(HMONITOR hMonitor, DISPLAYCONFIG_PATH_INF device_name.header.size = sizeof(device_name); device_name.header.adapterId = path_infos[i].sourceInfo.adapterId; device_name.header.id = path_infos[i].sourceInfo.id; - if (DisplayConfigGetDeviceInfo(&device_name.header) == ERROR_SUCCESS) { + if (videodata->DisplayConfigGetDeviceInfo(&device_name.header) == ERROR_SUCCESS) { if (SDL_wcscmp(view_info.szDevice, device_name.viewGdiDeviceName) == 0) { SDL_copyp(path_info, &path_infos[i]); found = SDL_TRUE; @@ -457,12 +439,13 @@ done: return found; } -static float WIN_GetSDRWhitePoint(HMONITOR hMonitor) +static float WIN_GetSDRWhitePoint(SDL_VideoDevice *_this, HMONITOR hMonitor) { DISPLAYCONFIG_PATH_INFO path_info; + SDL_VideoData *videodata = _this->driverdata; float SDR_white_point = 1.0f; - if (WIN_GetMonitorPathInfo(hMonitor, &path_info)) { + if (WIN_GetMonitorPathInfo(videodata, hMonitor, &path_info)) { DISPLAYCONFIG_SDR_WHITE_LEVEL white_level; SDL_zero(white_level); @@ -470,7 +453,8 @@ static float WIN_GetSDRWhitePoint(HMONITOR hMonitor) white_level.header.size = sizeof(white_level); white_level.header.adapterId = path_info.targetInfo.adapterId; white_level.header.id = path_info.targetInfo.id; - if (DisplayConfigGetDeviceInfo(&white_level.header) == ERROR_SUCCESS && + /* WIN_GetMonitorPathInfo() succeeded: DisplayConfigGetDeviceInfo is not NULL */ + if (videodata->DisplayConfigGetDeviceInfo(&white_level.header) == ERROR_SUCCESS && white_level.SDRWhiteLevel > 0) { SDR_white_point = (white_level.SDRWhiteLevel / 1000.0f); } @@ -486,7 +470,7 @@ static void WIN_GetHDRProperties(SDL_VideoDevice *_this, HMONITOR hMonitor, SDL_ if (WIN_GetMonitorDESC1(hMonitor, &desc)) { if (desc.ColorSpace == DXGI_COLOR_SPACE_RGB_FULL_G2084_NONE_P2020) { - HDR->SDR_white_point = WIN_GetSDRWhitePoint(hMonitor); + HDR->SDR_white_point = WIN_GetSDRWhitePoint(_this, hMonitor); HDR->HDR_headroom = (desc.MaxLuminance / 80.0f) / HDR->SDR_white_point; } } @@ -577,7 +561,7 @@ static void WIN_AddDisplay(SDL_VideoDevice *_this, HMONITOR hMonitor, const MONI displaydata->state = DisplayAdded; SDL_zero(display); - display.name = WIN_GetDisplayNameVista(info->szDevice); + display.name = WIN_GetDisplayNameVista(_this->driverdata, info->szDevice); if (!display.name) { DISPLAY_DEVICEW device; SDL_zero(device); diff --git a/src/video/windows/SDL_windowsvideo.c b/src/video/windows/SDL_windowsvideo.c index 44cd3a55d0..660b59d730 100644 --- a/src/video/windows/SDL_windowsvideo.c +++ b/src/video/windows/SDL_windowsvideo.c @@ -151,6 +151,9 @@ static SDL_VideoDevice *WIN_CreateDevice(void) data->GetDpiForWindow = (UINT (WINAPI *)(HWND))SDL_LoadFunction(data->userDLL, "GetDpiForWindow"); data->AreDpiAwarenessContextsEqual = (BOOL (WINAPI *)(DPI_AWARENESS_CONTEXT, DPI_AWARENESS_CONTEXT))SDL_LoadFunction(data->userDLL, "AreDpiAwarenessContextsEqual"); data->IsValidDpiAwarenessContext = (BOOL (WINAPI *)(DPI_AWARENESS_CONTEXT))SDL_LoadFunction(data->userDLL, "IsValidDpiAwarenessContext"); + data->GetDisplayConfigBufferSizes = (LONG (WINAPI *)(UINT32,UINT32*,UINT32* ))SDL_LoadFunction(data->userDLL, "GetDisplayConfigBufferSizes"); + data->QueryDisplayConfig = (LONG (WINAPI *)(UINT32,UINT32*,DISPLAYCONFIG_PATH_INFO*,UINT32*,DISPLAYCONFIG_MODE_INFO*,DISPLAYCONFIG_TOPOLOGY_ID*))SDL_LoadFunction(data->userDLL, "QueryDisplayConfig"); + data->DisplayConfigGetDeviceInfo = (LONG (WINAPI *)(DISPLAYCONFIG_DEVICE_INFO_HEADER*))SDL_LoadFunction(data->userDLL, "DisplayConfigGetDeviceInfo"); /* *INDENT-ON* */ /* clang-format on */ } else { SDL_ClearError(); diff --git a/src/video/windows/SDL_windowsvideo.h b/src/video/windows/SDL_windowsvideo.h index 390e2a68fb..32f310f53a 100644 --- a/src/video/windows/SDL_windowsvideo.h +++ b/src/video/windows/SDL_windowsvideo.h @@ -392,6 +392,10 @@ struct SDL_VideoData UINT (WINAPI *GetDpiForWindow)( HWND ); BOOL (WINAPI *AreDpiAwarenessContextsEqual)(DPI_AWARENESS_CONTEXT, DPI_AWARENESS_CONTEXT); BOOL (WINAPI *IsValidDpiAwarenessContext)(DPI_AWARENESS_CONTEXT); + /* DisplayConfig functions */ + LONG (WINAPI *GetDisplayConfigBufferSizes)( UINT32, UINT32*, UINT32* ); + LONG (WINAPI *QueryDisplayConfig)( UINT32, UINT32*, DISPLAYCONFIG_PATH_INFO*, UINT32*, DISPLAYCONFIG_MODE_INFO*, DISPLAYCONFIG_TOPOLOGY_ID*); + LONG (WINAPI *DisplayConfigGetDeviceInfo)( DISPLAYCONFIG_DEVICE_INFO_HEADER*); /* *INDENT-ON* */ /* clang-format on */ void *shcoreDLL;