mirror of
https://github.com/love2d/megasource.git
synced 2026-08-21 05:02:11 +02:00
update SDL3 to latest commit
This commit is contained in:
@@ -25,25 +25,27 @@
|
||||
#include "SDL_windowsvideo.h"
|
||||
#include "../../events/SDL_displayevents_c.h"
|
||||
|
||||
#ifdef HAVE_DXGI1_6_H
|
||||
#define COBJMACROS
|
||||
#include <dxgi1_6.h>
|
||||
#endif
|
||||
|
||||
/* Windows CE compatibility */
|
||||
// Windows CE compatibility
|
||||
#ifndef CDS_FULLSCREEN
|
||||
#define CDS_FULLSCREEN 0
|
||||
#endif
|
||||
|
||||
/* #define DEBUG_MODES */
|
||||
/* #define HIGHDPI_DEBUG_VERBOSE */
|
||||
// #define DEBUG_MODES
|
||||
// #define HIGHDPI_DEBUG_VERBOSE
|
||||
|
||||
static void WIN_UpdateDisplayMode(SDL_VideoDevice *_this, LPCWSTR deviceName, DWORD index, SDL_DisplayMode *mode)
|
||||
{
|
||||
SDL_DisplayModeData *data = (SDL_DisplayModeData *)mode->driverdata;
|
||||
SDL_DisplayModeData *data = (SDL_DisplayModeData *)mode->internal;
|
||||
HDC hdc;
|
||||
|
||||
data->DeviceMode.dmFields = (DM_BITSPERPEL | DM_PELSWIDTH | DM_PELSHEIGHT | DM_DISPLAYFREQUENCY | DM_DISPLAYFLAGS);
|
||||
|
||||
/* NOLINTNEXTLINE(bugprone-assignment-in-if-condition): No simple way to extract the assignment */
|
||||
// NOLINTNEXTLINE(bugprone-assignment-in-if-condition): No simple way to extract the assignment
|
||||
if (index == ENUM_CURRENT_SETTINGS && (hdc = CreateDC(deviceName, NULL, NULL, NULL)) != NULL) {
|
||||
char bmi_data[sizeof(BITMAPINFOHEADER) + 256 * sizeof(RGBQUAD)];
|
||||
LPBITMAPINFO bmi;
|
||||
@@ -70,7 +72,7 @@ static void WIN_UpdateDisplayMode(SDL_VideoDevice *_this, LPCWSTR deviceName, DW
|
||||
mode->format = SDL_PIXELFORMAT_RGB565;
|
||||
break;
|
||||
case 0x7C00:
|
||||
mode->format = SDL_PIXELFORMAT_RGB555;
|
||||
mode->format = SDL_PIXELFORMAT_XRGB1555;
|
||||
break;
|
||||
}
|
||||
} else if (bmi->bmiHeader.biCompression == BI_RGB) {
|
||||
@@ -83,7 +85,7 @@ static void WIN_UpdateDisplayMode(SDL_VideoDevice *_this, LPCWSTR deviceName, DW
|
||||
}
|
||||
}
|
||||
} else if (mode->format == SDL_PIXELFORMAT_UNKNOWN) {
|
||||
/* FIXME: Can we tell what this will be? */
|
||||
// FIXME: Can we tell what this will be?
|
||||
if ((data->DeviceMode.dmFields & DM_BITSPERPEL) == DM_BITSPERPEL) {
|
||||
switch (data->DeviceMode.dmBitsPerPel) {
|
||||
case 32:
|
||||
@@ -96,7 +98,7 @@ static void WIN_UpdateDisplayMode(SDL_VideoDevice *_this, LPCWSTR deviceName, DW
|
||||
mode->format = SDL_PIXELFORMAT_RGB565;
|
||||
break;
|
||||
case 15:
|
||||
mode->format = SDL_PIXELFORMAT_RGB555;
|
||||
mode->format = SDL_PIXELFORMAT_XRGB1555;
|
||||
break;
|
||||
case 8:
|
||||
mode->format = SDL_PIXELFORMAT_INDEX8;
|
||||
@@ -109,12 +111,59 @@ static void WIN_UpdateDisplayMode(SDL_VideoDevice *_this, LPCWSTR deviceName, DW
|
||||
}
|
||||
}
|
||||
|
||||
static void *WIN_GetDXGIOutput(SDL_VideoDevice *_this, const WCHAR *DeviceName)
|
||||
{
|
||||
void *result = NULL;
|
||||
|
||||
#ifdef HAVE_DXGI_H
|
||||
const SDL_VideoData *videodata = (const SDL_VideoData *)_this->internal;
|
||||
int nAdapter, nOutput;
|
||||
IDXGIAdapter *pDXGIAdapter;
|
||||
IDXGIOutput *pDXGIOutput;
|
||||
|
||||
if (!videodata->pDXGIFactory) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
nAdapter = 0;
|
||||
while (!result && SUCCEEDED(IDXGIFactory_EnumAdapters(videodata->pDXGIFactory, nAdapter, &pDXGIAdapter))) {
|
||||
nOutput = 0;
|
||||
while (!result && SUCCEEDED(IDXGIAdapter_EnumOutputs(pDXGIAdapter, nOutput, &pDXGIOutput))) {
|
||||
DXGI_OUTPUT_DESC outputDesc;
|
||||
if (SUCCEEDED(IDXGIOutput_GetDesc(pDXGIOutput, &outputDesc))) {
|
||||
if (SDL_wcscmp(outputDesc.DeviceName, DeviceName) == 0) {
|
||||
result = pDXGIOutput;
|
||||
}
|
||||
}
|
||||
if (pDXGIOutput != result) {
|
||||
IDXGIOutput_Release(pDXGIOutput);
|
||||
}
|
||||
nOutput++;
|
||||
}
|
||||
IDXGIAdapter_Release(pDXGIAdapter);
|
||||
nAdapter++;
|
||||
}
|
||||
#endif
|
||||
return result;
|
||||
}
|
||||
|
||||
static void WIN_ReleaseDXGIOutput(void *dxgi_output)
|
||||
{
|
||||
#ifdef HAVE_DXGI_H
|
||||
IDXGIOutput *pDXGIOutput = (IDXGIOutput *)dxgi_output;
|
||||
|
||||
if (pDXGIOutput) {
|
||||
IDXGIOutput_Release(pDXGIOutput);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
static SDL_DisplayOrientation WIN_GetNaturalOrientation(DEVMODE *mode)
|
||||
{
|
||||
int width = mode->dmPelsWidth;
|
||||
int height = mode->dmPelsHeight;
|
||||
|
||||
/* Use unrotated width/height to guess orientation */
|
||||
// Use unrotated width/height to guess orientation
|
||||
if (mode->dmDisplayOrientation == DMDO_90 || mode->dmDisplayOrientation == DMDO_270) {
|
||||
int temp = width;
|
||||
width = height;
|
||||
@@ -159,22 +208,46 @@ static SDL_DisplayOrientation WIN_GetDisplayOrientation(DEVMODE *mode)
|
||||
}
|
||||
}
|
||||
|
||||
static float WIN_GetRefreshRate(DEVMODE *mode)
|
||||
static void WIN_GetRefreshRate(void *dxgi_output, DEVMODE *mode, int *numerator, int *denominator)
|
||||
{
|
||||
/* We're not currently using DXGI to query display modes, so fake NTSC timings */
|
||||
// We're not currently using DXGI to query display modes, so fake NTSC timings
|
||||
switch (mode->dmDisplayFrequency) {
|
||||
case 119:
|
||||
case 59:
|
||||
case 29:
|
||||
return ((100 * (mode->dmDisplayFrequency + 1) * 1000) / 1001) / 100.0f;
|
||||
*numerator = (mode->dmDisplayFrequency + 1) * 1000;
|
||||
*denominator = 1001;
|
||||
break;
|
||||
default:
|
||||
return (float)mode->dmDisplayFrequency;
|
||||
*numerator = mode->dmDisplayFrequency;
|
||||
*denominator = 1;
|
||||
break;
|
||||
}
|
||||
|
||||
#ifdef HAVE_DXGI_H
|
||||
if (dxgi_output) {
|
||||
IDXGIOutput *pDXGIOutput = (IDXGIOutput *)dxgi_output;
|
||||
DXGI_MODE_DESC modeToMatch;
|
||||
DXGI_MODE_DESC closestMatch;
|
||||
|
||||
SDL_zero(modeToMatch);
|
||||
modeToMatch.Width = mode->dmPelsWidth;
|
||||
modeToMatch.Height = mode->dmPelsHeight;
|
||||
modeToMatch.RefreshRate.Numerator = *numerator;
|
||||
modeToMatch.RefreshRate.Denominator = *denominator;
|
||||
modeToMatch.Format = DXGI_FORMAT_R8G8B8A8_UNORM;
|
||||
|
||||
if (SUCCEEDED(IDXGIOutput_FindClosestMatchingMode(pDXGIOutput, &modeToMatch, &closestMatch, NULL))) {
|
||||
*numerator = closestMatch.RefreshRate.Numerator;
|
||||
*denominator = closestMatch.RefreshRate.Denominator;
|
||||
}
|
||||
}
|
||||
#endif // HAVE_DXGI_H
|
||||
}
|
||||
|
||||
static float WIN_GetContentScale(SDL_VideoDevice *_this, HMONITOR hMonitor)
|
||||
{
|
||||
const SDL_VideoData *videodata = (const SDL_VideoData *)_this->driverdata;
|
||||
const SDL_VideoData *videodata = (const SDL_VideoData *)_this->internal;
|
||||
int dpi = 0;
|
||||
|
||||
if (videodata->GetDpiForMonitor) {
|
||||
@@ -184,7 +257,7 @@ static float WIN_GetContentScale(SDL_VideoDevice *_this, HMONITOR hMonitor)
|
||||
}
|
||||
}
|
||||
if (dpi == 0) {
|
||||
/* Window 8.0 and below: same DPI for all monitors */
|
||||
// Window 8.0 and below: same DPI for all monitors
|
||||
HDC hdc = GetDC(NULL);
|
||||
if (hdc) {
|
||||
dpi = GetDeviceCaps(hdc, LOGPIXELSX);
|
||||
@@ -192,13 +265,13 @@ static float WIN_GetContentScale(SDL_VideoDevice *_this, HMONITOR hMonitor)
|
||||
}
|
||||
}
|
||||
if (dpi == 0) {
|
||||
/* Safe default */
|
||||
// Safe default
|
||||
dpi = USER_DEFAULT_SCREEN_DPI;
|
||||
}
|
||||
return dpi / (float)USER_DEFAULT_SCREEN_DPI;
|
||||
}
|
||||
|
||||
static SDL_bool WIN_GetDisplayMode(SDL_VideoDevice *_this, HMONITOR hMonitor, LPCWSTR deviceName, DWORD index, SDL_DisplayMode *mode, SDL_DisplayOrientation *natural_orientation, SDL_DisplayOrientation *current_orientation)
|
||||
static bool WIN_GetDisplayMode(SDL_VideoDevice *_this, void *dxgi_output, HMONITOR hMonitor, LPCWSTR deviceName, DWORD index, SDL_DisplayMode *mode, SDL_DisplayOrientation *natural_orientation, SDL_DisplayOrientation *current_orientation)
|
||||
{
|
||||
SDL_DisplayModeData *data;
|
||||
DEVMODE devmode;
|
||||
@@ -206,24 +279,24 @@ static SDL_bool WIN_GetDisplayMode(SDL_VideoDevice *_this, HMONITOR hMonitor, LP
|
||||
devmode.dmSize = sizeof(devmode);
|
||||
devmode.dmDriverExtra = 0;
|
||||
if (!EnumDisplaySettingsW(deviceName, index, &devmode)) {
|
||||
return SDL_FALSE;
|
||||
return false;
|
||||
}
|
||||
|
||||
data = (SDL_DisplayModeData *)SDL_malloc(sizeof(*data));
|
||||
if (!data) {
|
||||
return SDL_FALSE;
|
||||
return false;
|
||||
}
|
||||
|
||||
SDL_zerop(mode);
|
||||
mode->driverdata = data;
|
||||
mode->internal = data;
|
||||
data->DeviceMode = devmode;
|
||||
|
||||
mode->format = SDL_PIXELFORMAT_UNKNOWN;
|
||||
mode->w = data->DeviceMode.dmPelsWidth;
|
||||
mode->h = data->DeviceMode.dmPelsHeight;
|
||||
mode->refresh_rate = WIN_GetRefreshRate(&data->DeviceMode);
|
||||
WIN_GetRefreshRate(dxgi_output, &data->DeviceMode, &mode->refresh_rate_numerator, &mode->refresh_rate_denominator);
|
||||
|
||||
/* Fill in the mode information */
|
||||
// Fill in the mode information
|
||||
WIN_UpdateDisplayMode(_this, deviceName, index, mode);
|
||||
|
||||
if (natural_orientation) {
|
||||
@@ -233,45 +306,25 @@ static SDL_bool WIN_GetDisplayMode(SDL_VideoDevice *_this, HMONITOR hMonitor, LP
|
||||
*current_orientation = WIN_GetDisplayOrientation(&devmode);
|
||||
}
|
||||
|
||||
return SDL_TRUE;
|
||||
return 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;
|
||||
char *result = NULL;
|
||||
UINT32 pathCount = 0;
|
||||
UINT32 modeCount = 0;
|
||||
UINT32 i;
|
||||
LONG rc;
|
||||
|
||||
dll = SDL_LoadObject("USER32.DLL");
|
||||
if (!dll) {
|
||||
if (!videodata->GetDisplayConfigBufferSizes || !videodata->QueryDisplayConfig || !videodata->DisplayConfigGetDeviceInfo) {
|
||||
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;
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
@@ -285,7 +338,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) {
|
||||
@@ -298,7 +351,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) {
|
||||
@@ -310,14 +363,14 @@ 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);
|
||||
result = WIN_StringToUTF8W(targetName.monitorFriendlyDeviceName);
|
||||
/* if we got an empty string, treat it as failure so we'll fallback
|
||||
to getting the generic name. */
|
||||
if (retval && (*retval == '\0')) {
|
||||
SDL_free(retval);
|
||||
retval = NULL;
|
||||
if (result && (*result == '\0')) {
|
||||
SDL_free(result);
|
||||
result = NULL;
|
||||
}
|
||||
}
|
||||
break;
|
||||
@@ -326,34 +379,29 @@ static char *WIN_GetDisplayNameVista(const WCHAR *deviceName)
|
||||
|
||||
SDL_free(paths);
|
||||
SDL_free(modes);
|
||||
SDL_UnloadObject(dll);
|
||||
return retval;
|
||||
return result;
|
||||
|
||||
WIN_GetDisplayNameVista_failed:
|
||||
SDL_free(retval);
|
||||
SDL_free(result);
|
||||
SDL_free(paths);
|
||||
SDL_free(modes);
|
||||
SDL_UnloadObject(dll);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static SDL_bool WIN_GetMonitorDESC1(HMONITOR hMonitor, DXGI_OUTPUT_DESC1 *desc)
|
||||
#ifdef HAVE_DXGI1_6_H
|
||||
static bool WIN_GetMonitorDESC1(HMONITOR hMonitor, DXGI_OUTPUT_DESC1 *desc)
|
||||
{
|
||||
typedef HRESULT (WINAPI * PFN_CREATE_DXGI_FACTORY)(REFIID riid, void **ppFactory);
|
||||
PFN_CREATE_DXGI_FACTORY CreateDXGIFactoryFunc = NULL;
|
||||
void *hDXGIMod = NULL;
|
||||
SDL_bool found = SDL_FALSE;
|
||||
SDL_SharedObject *hDXGIMod = NULL;
|
||||
bool found = false;
|
||||
|
||||
#ifdef SDL_PLATFORM_WINRT
|
||||
CreateDXGIFactoryFunc = CreateDXGIFactory1;
|
||||
#else
|
||||
hDXGIMod = SDL_LoadObject("dxgi.dll");
|
||||
if (hDXGIMod) {
|
||||
CreateDXGIFactoryFunc = (PFN_CREATE_DXGI_FACTORY)SDL_LoadFunction(hDXGIMod, "CreateDXGIFactory1");
|
||||
}
|
||||
#endif
|
||||
if (CreateDXGIFactoryFunc) {
|
||||
static const GUID SDL_IID_IDXGIFactory1 = { 0x770aae78, 0xf26f, 0x4dba, { 0xa8, 0x29, 0x25, 0x3c, 0x83, 0xd1, 0xb3, 0x87 } };
|
||||
static const GUID SDL_IID_IDXGIFactory1 = { 0x770aae78, 0xf26f, 0x4dba, { 0xa8, 0x29, 0x25, 0x3c, 0x83, 0xd1, 0xb3, 0x87 } };
|
||||
static const GUID SDL_IID_IDXGIOutput6 = { 0x068346e8, 0xaaec, 0x4b84, { 0xad, 0xd7, 0x13, 0x7f, 0x51, 0x3f, 0x77, 0xa1 } };
|
||||
IDXGIFactory1 *dxgiFactory;
|
||||
|
||||
@@ -368,7 +416,7 @@ static SDL_bool WIN_GetMonitorDESC1(HMONITOR hMonitor, DXGI_OUTPUT_DESC1 *desc)
|
||||
if (SUCCEEDED(IDXGIOutput_QueryInterface(dxgiOutput, &SDL_IID_IDXGIOutput6, (void **)&dxgiOutput6))) {
|
||||
if (SUCCEEDED(IDXGIOutput6_GetDesc1(dxgiOutput6, desc))) {
|
||||
if (desc->Monitor == hMonitor) {
|
||||
found = SDL_TRUE;
|
||||
found = true;
|
||||
}
|
||||
}
|
||||
IDXGIOutput6_Release(dxgiOutput6);
|
||||
@@ -388,7 +436,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 bool WIN_GetMonitorPathInfo(SDL_VideoData *videodata, HMONITOR hMonitor, DISPLAYCONFIG_PATH_INFO *path_info)
|
||||
{
|
||||
LONG result;
|
||||
MONITORINFOEXW view_info;
|
||||
@@ -397,7 +445,11 @@ static SDL_bool WIN_GetMonitorPathInfo(HMONITOR hMonitor, DISPLAYCONFIG_PATH_INF
|
||||
UINT32 num_mode_info_array_elements = 0;
|
||||
DISPLAYCONFIG_PATH_INFO *path_infos = NULL, *new_path_infos;
|
||||
DISPLAYCONFIG_MODE_INFO *mode_infos = NULL, *new_mode_infos;
|
||||
SDL_bool found = SDL_FALSE;
|
||||
bool found = false;
|
||||
|
||||
if (!videodata->GetDisplayConfigBufferSizes || !videodata->QueryDisplayConfig || !videodata->DisplayConfigGetDeviceInfo) {
|
||||
return false;
|
||||
}
|
||||
|
||||
SDL_zero(view_info);
|
||||
view_info.cbSize = sizeof(view_info);
|
||||
@@ -406,8 +458,10 @@ 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) {
|
||||
return SDL_FALSE;
|
||||
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 false;
|
||||
}
|
||||
|
||||
new_path_infos = (DISPLAYCONFIG_PATH_INFO *)SDL_realloc(path_infos, num_path_array_elements * sizeof(*path_infos));
|
||||
@@ -422,7 +476,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);
|
||||
|
||||
@@ -435,10 +489,10 @@ 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;
|
||||
found = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
@@ -452,12 +506,13 @@ done:
|
||||
return found;
|
||||
}
|
||||
|
||||
static float WIN_GetSDRWhitePoint(HMONITOR hMonitor)
|
||||
static float WIN_GetSDRWhitePoint(SDL_VideoDevice *_this, HMONITOR hMonitor)
|
||||
{
|
||||
DISPLAYCONFIG_PATH_INFO path_info;
|
||||
float SDR_white_point = 1.0f;
|
||||
SDL_VideoData *videodata = _this->internal;
|
||||
float SDR_white_level = 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);
|
||||
@@ -465,15 +520,16 @@ 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);
|
||||
SDR_white_level = (white_level.SDRWhiteLevel / 1000.0f);
|
||||
}
|
||||
}
|
||||
return SDR_white_point;
|
||||
return SDR_white_level;
|
||||
}
|
||||
|
||||
static void WIN_GetHDRProperties(SDL_VideoDevice *_this, HMONITOR hMonitor, SDL_HDRDisplayProperties *HDR)
|
||||
static void WIN_GetHDRProperties(SDL_VideoDevice *_this, HMONITOR hMonitor, SDL_HDROutputProperties *HDR)
|
||||
{
|
||||
DXGI_OUTPUT_DESC1 desc;
|
||||
|
||||
@@ -481,17 +537,19 @@ 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->HDR_headroom = (desc.MaxLuminance / 80.0f) / HDR->SDR_white_point;
|
||||
HDR->SDR_white_level = WIN_GetSDRWhitePoint(_this, hMonitor);
|
||||
HDR->HDR_headroom = (desc.MaxLuminance / 80.0f) / HDR->SDR_white_level;
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif // HAVE_DXGI1_6_H
|
||||
|
||||
static void WIN_AddDisplay(SDL_VideoDevice *_this, HMONITOR hMonitor, const MONITORINFOEXW *info, int *display_index)
|
||||
{
|
||||
int i, index = *display_index;
|
||||
SDL_VideoDisplay display;
|
||||
SDL_DisplayData *displaydata;
|
||||
void *dxgi_output = NULL;
|
||||
SDL_DisplayMode mode;
|
||||
SDL_DisplayOrientation natural_orientation;
|
||||
SDL_DisplayOrientation current_orientation;
|
||||
@@ -501,7 +559,10 @@ static void WIN_AddDisplay(SDL_VideoDevice *_this, HMONITOR hMonitor, const MONI
|
||||
SDL_Log("Display: %s\n", WIN_StringToUTF8W(info->szDevice));
|
||||
#endif
|
||||
|
||||
if (!WIN_GetDisplayMode(_this, hMonitor, info->szDevice, ENUM_CURRENT_SETTINGS, &mode, &natural_orientation, ¤t_orientation)) {
|
||||
dxgi_output = WIN_GetDXGIOutput(_this, info->szDevice);
|
||||
bool found = WIN_GetDisplayMode(_this, dxgi_output, hMonitor, info->szDevice, ENUM_CURRENT_SETTINGS, &mode, &natural_orientation, ¤t_orientation);
|
||||
WIN_ReleaseDXGIOutput(dxgi_output);
|
||||
if (!found) {
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -509,18 +570,18 @@ static void WIN_AddDisplay(SDL_VideoDevice *_this, HMONITOR hMonitor, const MONI
|
||||
// ready to be added to allow any displays that we can't fully query to be
|
||||
// removed
|
||||
for (i = 0; i < _this->num_displays; ++i) {
|
||||
SDL_DisplayData *driverdata = _this->displays[i]->driverdata;
|
||||
if (SDL_wcscmp(driverdata->DeviceName, info->szDevice) == 0) {
|
||||
SDL_bool moved = (index != i);
|
||||
SDL_bool changed_bounds = SDL_FALSE;
|
||||
SDL_DisplayData *internal = _this->displays[i]->internal;
|
||||
if (SDL_wcscmp(internal->DeviceName, info->szDevice) == 0) {
|
||||
bool moved = (index != i);
|
||||
bool changed_bounds = false;
|
||||
|
||||
if (driverdata->state != DisplayRemoved) {
|
||||
/* We've already enumerated this display, don't move it */
|
||||
if (internal->state != DisplayRemoved) {
|
||||
// We've already enumerated this display, don't move it
|
||||
return;
|
||||
}
|
||||
|
||||
if (index >= _this->num_displays) {
|
||||
/* This should never happen due to the check above, but just in case... */
|
||||
// This should never happen due to the check above, but just in case...
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -533,28 +594,30 @@ static void WIN_AddDisplay(SDL_VideoDevice *_this, HMONITOR hMonitor, const MONI
|
||||
i = index;
|
||||
}
|
||||
|
||||
driverdata->MonitorHandle = hMonitor;
|
||||
driverdata->state = DisplayUnchanged;
|
||||
internal->MonitorHandle = hMonitor;
|
||||
internal->state = DisplayUnchanged;
|
||||
|
||||
if (!_this->setting_display_mode) {
|
||||
SDL_VideoDisplay *existing_display = _this->displays[i];
|
||||
SDL_Rect bounds;
|
||||
SDL_HDRDisplayProperties HDR;
|
||||
|
||||
SDL_ResetFullscreenDisplayModes(existing_display);
|
||||
SDL_SetDesktopDisplayMode(existing_display, &mode);
|
||||
if (WIN_GetDisplayBounds(_this, existing_display, &bounds) == 0 &&
|
||||
SDL_memcmp(&driverdata->bounds, &bounds, sizeof(bounds)) != 0) {
|
||||
changed_bounds = SDL_TRUE;
|
||||
SDL_copyp(&driverdata->bounds, &bounds);
|
||||
if (WIN_GetDisplayBounds(_this, existing_display, &bounds) &&
|
||||
SDL_memcmp(&internal->bounds, &bounds, sizeof(bounds)) != 0) {
|
||||
changed_bounds = true;
|
||||
SDL_copyp(&internal->bounds, &bounds);
|
||||
}
|
||||
if (moved || changed_bounds) {
|
||||
SDL_SendDisplayEvent(existing_display, SDL_EVENT_DISPLAY_MOVED, 0);
|
||||
SDL_SendDisplayEvent(existing_display, SDL_EVENT_DISPLAY_MOVED, 0, 0);
|
||||
}
|
||||
SDL_SendDisplayEvent(existing_display, SDL_EVENT_DISPLAY_ORIENTATION, current_orientation);
|
||||
SDL_SendDisplayEvent(existing_display, SDL_EVENT_DISPLAY_ORIENTATION, current_orientation, 0);
|
||||
SDL_SetDisplayContentScale(existing_display, content_scale);
|
||||
#ifdef HAVE_DXGI1_6_H
|
||||
SDL_HDROutputProperties HDR;
|
||||
WIN_GetHDRProperties(_this, hMonitor, &HDR);
|
||||
SDL_SetDisplayHDRProperties(existing_display, &HDR);
|
||||
#endif
|
||||
}
|
||||
goto done;
|
||||
}
|
||||
@@ -569,7 +632,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->internal, info->szDevice);
|
||||
if (!display.name) {
|
||||
DISPLAY_DEVICEW device;
|
||||
SDL_zero(device);
|
||||
@@ -584,10 +647,12 @@ static void WIN_AddDisplay(SDL_VideoDevice *_this, HMONITOR hMonitor, const MONI
|
||||
display.current_orientation = current_orientation;
|
||||
display.content_scale = content_scale;
|
||||
display.device = _this;
|
||||
display.driverdata = displaydata;
|
||||
display.internal = displaydata;
|
||||
WIN_GetDisplayBounds(_this, &display, &displaydata->bounds);
|
||||
#ifdef HAVE_DXGI1_6_H
|
||||
WIN_GetHDRProperties(_this, hMonitor, &display.HDR);
|
||||
SDL_AddVideoDisplay(&display, SDL_FALSE);
|
||||
#endif
|
||||
SDL_AddVideoDisplay(&display, false);
|
||||
SDL_free(display.name);
|
||||
|
||||
done:
|
||||
@@ -598,7 +663,7 @@ typedef struct _WIN_AddDisplaysData
|
||||
{
|
||||
SDL_VideoDevice *video_device;
|
||||
int display_index;
|
||||
SDL_bool want_primary;
|
||||
bool want_primary;
|
||||
} WIN_AddDisplaysData;
|
||||
|
||||
static BOOL CALLBACK WIN_AddDisplaysCallback(HMONITOR hMonitor,
|
||||
@@ -613,7 +678,7 @@ static BOOL CALLBACK WIN_AddDisplaysCallback(HMONITOR hMonitor,
|
||||
info.cbSize = sizeof(info);
|
||||
|
||||
if (GetMonitorInfoW(hMonitor, (LPMONITORINFO)&info) != 0) {
|
||||
const SDL_bool is_primary = ((info.dwFlags & MONITORINFOF_PRIMARY) == MONITORINFOF_PRIMARY);
|
||||
const bool is_primary = ((info.dwFlags & MONITORINFOF_PRIMARY) == MONITORINFOF_PRIMARY);
|
||||
|
||||
if (is_primary == data->want_primary) {
|
||||
WIN_AddDisplay(data->video_device, hMonitor, &info, &data->display_index);
|
||||
@@ -630,26 +695,26 @@ static void WIN_AddDisplays(SDL_VideoDevice *_this)
|
||||
callback_data.video_device = _this;
|
||||
callback_data.display_index = 0;
|
||||
|
||||
callback_data.want_primary = SDL_TRUE;
|
||||
callback_data.want_primary = true;
|
||||
EnumDisplayMonitors(NULL, NULL, WIN_AddDisplaysCallback, (LPARAM)&callback_data);
|
||||
|
||||
callback_data.want_primary = SDL_FALSE;
|
||||
callback_data.want_primary = false;
|
||||
EnumDisplayMonitors(NULL, NULL, WIN_AddDisplaysCallback, (LPARAM)&callback_data);
|
||||
}
|
||||
|
||||
int WIN_InitModes(SDL_VideoDevice *_this)
|
||||
bool WIN_InitModes(SDL_VideoDevice *_this)
|
||||
{
|
||||
WIN_AddDisplays(_this);
|
||||
|
||||
if (_this->num_displays == 0) {
|
||||
return SDL_SetError("No displays available");
|
||||
}
|
||||
return 0;
|
||||
return true;
|
||||
}
|
||||
|
||||
int WIN_GetDisplayBounds(SDL_VideoDevice *_this, SDL_VideoDisplay *display, SDL_Rect *rect)
|
||||
bool WIN_GetDisplayBounds(SDL_VideoDevice *_this, SDL_VideoDisplay *display, SDL_Rect *rect)
|
||||
{
|
||||
const SDL_DisplayData *data = display->driverdata;
|
||||
const SDL_DisplayData *data = display->internal;
|
||||
MONITORINFO minfo;
|
||||
BOOL rc;
|
||||
|
||||
@@ -666,12 +731,12 @@ int WIN_GetDisplayBounds(SDL_VideoDevice *_this, SDL_VideoDisplay *display, SDL_
|
||||
rect->w = minfo.rcMonitor.right - minfo.rcMonitor.left;
|
||||
rect->h = minfo.rcMonitor.bottom - minfo.rcMonitor.top;
|
||||
|
||||
return 0;
|
||||
return true;
|
||||
}
|
||||
|
||||
int WIN_GetDisplayUsableBounds(SDL_VideoDevice *_this, SDL_VideoDisplay *display, SDL_Rect *rect)
|
||||
bool WIN_GetDisplayUsableBounds(SDL_VideoDevice *_this, SDL_VideoDisplay *display, SDL_Rect *rect)
|
||||
{
|
||||
const SDL_DisplayData *data = display->driverdata;
|
||||
const SDL_DisplayData *data = display->internal;
|
||||
MONITORINFO minfo;
|
||||
BOOL rc;
|
||||
|
||||
@@ -688,39 +753,45 @@ int WIN_GetDisplayUsableBounds(SDL_VideoDevice *_this, SDL_VideoDisplay *display
|
||||
rect->w = minfo.rcWork.right - minfo.rcWork.left;
|
||||
rect->h = minfo.rcWork.bottom - minfo.rcWork.top;
|
||||
|
||||
return 0;
|
||||
return true;
|
||||
}
|
||||
|
||||
int WIN_GetDisplayModes(SDL_VideoDevice *_this, SDL_VideoDisplay *display)
|
||||
bool WIN_GetDisplayModes(SDL_VideoDevice *_this, SDL_VideoDisplay *display)
|
||||
{
|
||||
SDL_DisplayData *data = display->driverdata;
|
||||
SDL_DisplayData *data = display->internal;
|
||||
void *dxgi_output;
|
||||
DWORD i;
|
||||
SDL_DisplayMode mode;
|
||||
|
||||
dxgi_output = WIN_GetDXGIOutput(_this, data->DeviceName);
|
||||
|
||||
for (i = 0;; ++i) {
|
||||
if (!WIN_GetDisplayMode(_this, data->MonitorHandle, data->DeviceName, i, &mode, NULL, NULL)) {
|
||||
if (!WIN_GetDisplayMode(_this, dxgi_output, data->MonitorHandle, data->DeviceName, i, &mode, NULL, NULL)) {
|
||||
break;
|
||||
}
|
||||
if (SDL_ISPIXELFORMAT_INDEXED(mode.format)) {
|
||||
/* We don't support palettized modes now */
|
||||
SDL_free(mode.driverdata);
|
||||
// We don't support palettized modes now
|
||||
SDL_free(mode.internal);
|
||||
continue;
|
||||
}
|
||||
if (mode.format != SDL_PIXELFORMAT_UNKNOWN) {
|
||||
if (!SDL_AddFullscreenDisplayMode(display, &mode)) {
|
||||
SDL_free(mode.driverdata);
|
||||
SDL_free(mode.internal);
|
||||
}
|
||||
} else {
|
||||
SDL_free(mode.driverdata);
|
||||
SDL_free(mode.internal);
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
|
||||
WIN_ReleaseDXGIOutput(dxgi_output);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
#ifdef DEBUG_MODES
|
||||
static void WIN_LogMonitor(SDL_VideoDevice *_this, HMONITOR mon)
|
||||
{
|
||||
const SDL_VideoData *vid_data = (const SDL_VideoData *)_this->driverdata;
|
||||
const SDL_VideoData *vid_data = (const SDL_VideoData *)_this->internal;
|
||||
MONITORINFOEX minfo;
|
||||
UINT xdpi = 0, ydpi = 0;
|
||||
char *name_utf8;
|
||||
@@ -747,10 +818,10 @@ static void WIN_LogMonitor(SDL_VideoDevice *_this, HMONITOR mon)
|
||||
}
|
||||
#endif
|
||||
|
||||
int WIN_SetDisplayMode(SDL_VideoDevice *_this, SDL_VideoDisplay *display, SDL_DisplayMode *mode)
|
||||
bool WIN_SetDisplayMode(SDL_VideoDevice *_this, SDL_VideoDisplay *display, SDL_DisplayMode *mode)
|
||||
{
|
||||
SDL_DisplayData *displaydata = display->driverdata;
|
||||
SDL_DisplayModeData *data = (SDL_DisplayModeData *)mode->driverdata;
|
||||
SDL_DisplayData *displaydata = display->internal;
|
||||
SDL_DisplayModeData *data = (SDL_DisplayModeData *)mode->internal;
|
||||
LONG status;
|
||||
|
||||
#ifdef DEBUG_MODES
|
||||
@@ -768,7 +839,7 @@ int WIN_SetDisplayMode(SDL_VideoDevice *_this, SDL_VideoDisplay *display, SDL_Di
|
||||
reset the monitor DPI to 192. (200% scaling)
|
||||
|
||||
NOTE: these are temporary changes in DPI, not modifications to the Control Panel setting. */
|
||||
if (mode->driverdata == display->desktop_mode.driverdata) {
|
||||
if (mode->internal == display->desktop_mode.internal) {
|
||||
#ifdef DEBUG_MODES
|
||||
SDL_Log("WIN_SetDisplayMode: resetting to original resolution");
|
||||
#endif
|
||||
@@ -805,7 +876,7 @@ int WIN_SetDisplayMode(SDL_VideoDevice *_this, SDL_VideoDisplay *display, SDL_Di
|
||||
|
||||
EnumDisplaySettingsW(displaydata->DeviceName, ENUM_CURRENT_SETTINGS, &data->DeviceMode);
|
||||
WIN_UpdateDisplayMode(_this, displaydata->DeviceName, ENUM_CURRENT_SETTINGS, mode);
|
||||
return 0;
|
||||
return true;
|
||||
}
|
||||
|
||||
void WIN_RefreshDisplays(SDL_VideoDevice *_this)
|
||||
@@ -815,8 +886,8 @@ void WIN_RefreshDisplays(SDL_VideoDevice *_this)
|
||||
// Mark all displays as potentially invalid to detect
|
||||
// entries that have actually been removed
|
||||
for (i = 0; i < _this->num_displays; ++i) {
|
||||
SDL_DisplayData *driverdata = _this->displays[i]->driverdata;
|
||||
driverdata->state = DisplayRemoved;
|
||||
SDL_DisplayData *internal = _this->displays[i]->internal;
|
||||
internal->state = DisplayRemoved;
|
||||
}
|
||||
|
||||
// Enumerate displays to add any new ones and mark still
|
||||
@@ -827,25 +898,25 @@ void WIN_RefreshDisplays(SDL_VideoDevice *_this)
|
||||
// in reverse as each delete takes effect immediately
|
||||
for (i = _this->num_displays - 1; i >= 0; --i) {
|
||||
SDL_VideoDisplay *display = _this->displays[i];
|
||||
SDL_DisplayData *driverdata = display->driverdata;
|
||||
if (driverdata->state == DisplayRemoved) {
|
||||
SDL_DelVideoDisplay(display->id, SDL_TRUE);
|
||||
SDL_DisplayData *internal = display->internal;
|
||||
if (internal->state == DisplayRemoved) {
|
||||
SDL_DelVideoDisplay(display->id, true);
|
||||
}
|
||||
}
|
||||
|
||||
// Send events for any newly added displays
|
||||
for (i = 0; i < _this->num_displays; ++i) {
|
||||
SDL_VideoDisplay *display = _this->displays[i];
|
||||
SDL_DisplayData *driverdata = display->driverdata;
|
||||
if (driverdata->state == DisplayAdded) {
|
||||
SDL_SendDisplayEvent(display, SDL_EVENT_DISPLAY_ADDED, 0);
|
||||
SDL_DisplayData *internal = display->internal;
|
||||
if (internal->state == DisplayAdded) {
|
||||
SDL_SendDisplayEvent(display, SDL_EVENT_DISPLAY_ADDED, 0, 0);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void WIN_QuitModes(SDL_VideoDevice *_this)
|
||||
{
|
||||
/* All fullscreen windows should have restored modes by now */
|
||||
// All fullscreen windows should have restored modes by now
|
||||
}
|
||||
|
||||
#endif /* SDL_VIDEO_DRIVER_WINDOWS */
|
||||
#endif // SDL_VIDEO_DRIVER_WINDOWS
|
||||
|
||||
Reference in New Issue
Block a user