update SDL3 to latest commit

This commit is contained in:
Sasha Szpakowski
2024-10-06 20:30:44 -03:00
parent 1b0fdc338b
commit 9e5eb1b018
1426 changed files with 242456 additions and 103496 deletions
+3 -3
View File
@@ -28,7 +28,7 @@
#define TF_IPSINK_FLAG_ACTIVE 0x0001
#define TF_TMAE_UIELEMENTENABLEDONLY 0x00000004
/* *INDENT-OFF* */ /* clang-format off */
/* *INDENT-OFF* */ // clang-format off
typedef struct ITfThreadMgr ITfThreadMgr;
typedef struct ITfDocumentMgr ITfDocumentMgr;
@@ -241,6 +241,6 @@ struct ITfSource
const struct ITfSourceVtbl *lpVtbl;
};
/* *INDENT-ON* */ /* clang-format on */
/* *INDENT-ON* */ // clang-format on
#endif /* SDL_msctf_h_ */
#endif // SDL_msctf_h_
@@ -25,6 +25,7 @@
#include "SDL_windowsvideo.h"
#include "SDL_windowswindow.h"
#include "../SDL_clipboard_c.h"
#include "../../events/SDL_events_c.h"
#include "../../events/SDL_clipboardevents_c.h"
#ifdef UNICODE
@@ -35,20 +36,20 @@
#define IMAGE_FORMAT CF_DIB
#define IMAGE_MIME_TYPE "image/bmp"
#define BFT_BITMAP 0x4d42 /* 'BM' */
#define BFT_BITMAP 0x4d42 // 'BM'
/* Assume we can directly read and write BMP fields without byte swapping */
// Assume we can directly read and write BMP fields without byte swapping
SDL_COMPILE_TIME_ASSERT(verify_byte_order, SDL_BYTEORDER == SDL_LIL_ENDIAN);
static BOOL WIN_OpenClipboard(SDL_VideoDevice *_this)
{
/* Retry to open the clipboard in case another application has it open */
// Retry to open the clipboard in case another application has it open
const int MAX_ATTEMPTS = 3;
int attempt;
HWND hwnd = NULL;
if (_this->windows) {
hwnd = _this->windows->driverdata->hwnd;
hwnd = _this->windows->internal->hwnd;
}
for (attempt = 0; attempt < MAX_ATTEMPTS; ++attempt) {
if (OpenClipboard(hwnd)) {
@@ -139,33 +140,33 @@ static void *WIN_ConvertDIBtoBMP(HANDLE hMem, size_t *size)
return bmp;
}
static int WIN_SetClipboardImage(SDL_VideoDevice *_this)
static bool WIN_SetClipboardImage(SDL_VideoDevice *_this)
{
HANDLE hMem;
size_t clipboard_data_size;
const void *clipboard_data;
int result = 0;
bool result = true;
clipboard_data = _this->clipboard_callback(_this->clipboard_userdata, IMAGE_MIME_TYPE, &clipboard_data_size);
hMem = WIN_ConvertBMPtoDIB(clipboard_data, clipboard_data_size);
if (hMem) {
/* Save the image to the clipboard */
// Save the image to the clipboard
if (!SetClipboardData(IMAGE_FORMAT, hMem)) {
result = WIN_SetError("Couldn't set clipboard data");
}
} else {
/* WIN_ConvertBMPtoDIB() set the error */
result = -1;
// WIN_ConvertBMPtoDIB() set the error
result = false;
}
return result;
}
static int WIN_SetClipboardText(SDL_VideoDevice *_this, const char *mime_type)
static bool WIN_SetClipboardText(SDL_VideoDevice *_this, const char *mime_type)
{
HANDLE hMem;
size_t clipboard_data_size;
const void *clipboard_data;
int result = 0;
bool result = true;
clipboard_data = _this->clipboard_callback(_this->clipboard_userdata, mime_type, &clipboard_data_size);
if (clipboard_data && clipboard_data_size > 0) {
@@ -175,21 +176,21 @@ static int WIN_SetClipboardText(SDL_VideoDevice *_this, const char *mime_type)
return SDL_SetError("Couldn't convert text from UTF-8");
}
/* Find out the size of the data */
// Find out the size of the data
for (size = 0, i = 0; tstr[i]; ++i, ++size) {
if (tstr[i] == '\n' && (i == 0 || tstr[i - 1] != '\r')) {
/* We're going to insert a carriage return */
// We're going to insert a carriage return
++size;
}
}
size = (size + 1) * sizeof(*tstr);
/* Save the data to the clipboard */
// Save the data to the clipboard
hMem = GlobalAlloc(GMEM_MOVEABLE, size);
if (hMem) {
LPTSTR dst = (LPTSTR)GlobalLock(hMem);
if (dst) {
/* Copy the text over, adding carriage returns as necessary */
// Copy the text over, adding carriage returns as necessary
for (i = 0; tstr[i]; ++i) {
if (tstr[i] == '\n' && (i == 0 || tstr[i - 1] != '\r')) {
*dst++ = '\r';
@@ -211,11 +212,11 @@ static int WIN_SetClipboardText(SDL_VideoDevice *_this, const char *mime_type)
return result;
}
int WIN_SetClipboardData(SDL_VideoDevice *_this)
bool WIN_SetClipboardData(SDL_VideoDevice *_this)
{
SDL_VideoData *data = _this->driverdata;
SDL_VideoData *data = _this->internal;
size_t i;
int result = 0;
bool result = true;
/* I investigated delayed clipboard rendering, and at least with text and image
* formats you have to use an output window, not SDL_HelperWindow, and the system
@@ -225,26 +226,26 @@ int WIN_SetClipboardData(SDL_VideoDevice *_this)
if (WIN_OpenClipboard(_this)) {
EmptyClipboard();
/* Set the clipboard text */
// Set the clipboard text
for (i = 0; i < _this->num_clipboard_mime_types; ++i) {
const char *mime_type = _this->clipboard_mime_types[i];
if (SDL_IsTextMimeType(mime_type)) {
if (WIN_SetClipboardText(_this, mime_type) < 0) {
result = -1;
if (!WIN_SetClipboardText(_this, mime_type)) {
result = false;
}
/* Only set the first clipboard text */
// Only set the first clipboard text
break;
}
}
/* Set the clipboard image */
// Set the clipboard image
for (i = 0; i < _this->num_clipboard_mime_types; ++i) {
const char *mime_type = _this->clipboard_mime_types[i];
if (SDL_strcmp(mime_type, IMAGE_MIME_TYPE) == 0) {
if (WIN_SetClipboardImage(_this) < 0) {
result = -1;
if (!WIN_SetClipboardImage(_this)) {
result = false;
}
break;
}
@@ -311,33 +312,92 @@ void *WIN_GetClipboardData(SDL_VideoDevice *_this, const char *mime_type, size_t
return data;
}
SDL_bool WIN_HasClipboardData(SDL_VideoDevice *_this, const char *mime_type)
bool WIN_HasClipboardData(SDL_VideoDevice *_this, const char *mime_type)
{
if (SDL_IsTextMimeType(mime_type)) {
if (IsClipboardFormatAvailable(TEXT_FORMAT)) {
return SDL_TRUE;
return true;
}
} else if (SDL_strcmp(mime_type, IMAGE_MIME_TYPE) == 0) {
if (IsClipboardFormatAvailable(IMAGE_FORMAT)) {
return SDL_TRUE;
return true;
}
} else {
if (SDL_HasInternalClipboardData(_this, mime_type)) {
return SDL_TRUE;
return true;
}
}
return SDL_FALSE;
return false;
}
static char **GetMimeTypes(int *pnformats)
{
*pnformats = 0;
int nformats = CountClipboardFormats();
size_t allocSize = (nformats + 1) * sizeof(char*);
UINT format = 0;
int formatsSz = 0;
int i;
for (i = 0; i < nformats; i++) {
format = EnumClipboardFormats(format);
if (!format) {
nformats = i;
break;
}
char mimeType[200];
int nchars = GetClipboardFormatNameA(format, mimeType, sizeof(mimeType));
formatsSz += nchars + 1;
}
char **new_mime_types = SDL_AllocateTemporaryMemory(allocSize + formatsSz);
if (!new_mime_types)
return NULL;
format = 0;
char *strPtr = (char *)(new_mime_types + nformats + 1);
int formatRemains = formatsSz;
for (i = 0; i < nformats; i++) {
format = EnumClipboardFormats(format);
if (!format) {
nformats = i;
break;
}
new_mime_types[i] = strPtr;
int nchars = GetClipboardFormatNameA(format, strPtr, formatRemains-1);
strPtr += nchars;
*strPtr = '\0';
strPtr++;
formatRemains -= (nchars + 1);
}
new_mime_types[nformats] = NULL;
*pnformats = nformats;
return new_mime_types;
}
void WIN_CheckClipboardUpdate(struct SDL_VideoData *data)
{
const DWORD count = GetClipboardSequenceNumber();
if (count != data->clipboard_count) {
const DWORD seq = GetClipboardSequenceNumber();
if (seq != data->clipboard_count) {
if (data->clipboard_count) {
SDL_SendClipboardUpdate();
int nformats = 0;
char **new_mime_types = GetMimeTypes(&nformats);
if (new_mime_types) {
SDL_SendClipboardUpdate(false, new_mime_types, nformats);
} else {
WIN_SetError("Couldn't get clipboard mime types");
}
}
data->clipboard_count = count;
data->clipboard_count = seq;
}
}
#endif /* SDL_VIDEO_DRIVER_WINDOWS */
#endif // SDL_VIDEO_DRIVER_WINDOWS
@@ -23,12 +23,12 @@
#ifndef SDL_windowsclipboard_h_
#define SDL_windowsclipboard_h_
/* Forward declaration */
// Forward declaration
struct SDL_VideoData;
extern int WIN_SetClipboardData(SDL_VideoDevice *_this);
extern bool WIN_SetClipboardData(SDL_VideoDevice *_this);
extern void *WIN_GetClipboardData(SDL_VideoDevice *_this, const char *mime_type, size_t *size);
extern SDL_bool WIN_HasClipboardData(SDL_VideoDevice *_this, const char *mime_type);
extern bool WIN_HasClipboardData(SDL_VideoDevice *_this, const char *mime_type);
extern void WIN_CheckClipboardUpdate(struct SDL_VideoData *data);
#endif /* SDL_windowsclipboard_h_ */
#endif // SDL_windowsclipboard_h_
File diff suppressed because it is too large Load Diff
@@ -31,9 +31,9 @@ extern LRESULT CALLBACK WIN_KeyboardHookProc(int nCode, WPARAM wParam, LPARAM lP
extern LRESULT CALLBACK WIN_WindowProc(HWND hwnd, UINT msg, WPARAM wParam,
LPARAM lParam);
extern void WIN_PollRawInput(SDL_VideoDevice *_this);
extern void WIN_CheckKeyboardAndMouseHotplug(SDL_VideoDevice *_this, SDL_bool initial_check);
extern void WIN_CheckKeyboardAndMouseHotplug(SDL_VideoDevice *_this, bool initial_check);
extern void WIN_PumpEvents(SDL_VideoDevice *_this);
extern void WIN_SendWakeupEvent(SDL_VideoDevice *_this, SDL_Window *window);
extern int WIN_WaitEventTimeout(SDL_VideoDevice *_this, Sint64 timeoutNS);
#endif /* SDL_windowsevents_h_ */
#endif // SDL_windowsevents_h_
@@ -24,10 +24,10 @@
#include "SDL_windowsvideo.h"
int WIN_CreateWindowFramebuffer(SDL_VideoDevice *_this, SDL_Window *window, SDL_PixelFormatEnum *format, void **pixels, int *pitch)
bool WIN_CreateWindowFramebuffer(SDL_VideoDevice *_this, SDL_Window *window, SDL_PixelFormat *format, void **pixels, int *pitch)
{
SDL_WindowData *data = window->driverdata;
SDL_bool isstack;
SDL_WindowData *data = window->internal;
bool isstack;
size_t size;
LPBITMAPINFO info;
HBITMAP hbm;
@@ -35,7 +35,7 @@ int WIN_CreateWindowFramebuffer(SDL_VideoDevice *_this, SDL_Window *window, SDL_
SDL_GetWindowSizeInPixels(window, &w, &h);
/* Free the old framebuffer surface */
// Free the old framebuffer surface
if (data->mdc) {
DeleteDC(data->mdc);
}
@@ -43,17 +43,17 @@ int WIN_CreateWindowFramebuffer(SDL_VideoDevice *_this, SDL_Window *window, SDL_
DeleteObject(data->hbm);
}
/* Find out the format of the screen */
// Find out the format of the screen
size = sizeof(BITMAPINFOHEADER) + 256 * sizeof(RGBQUAD);
info = (LPBITMAPINFO)SDL_small_alloc(Uint8, size, &isstack);
if (!info) {
return -1;
return false;
}
SDL_memset(info, 0, size);
info->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
/* The second call to GetDIBits() fills in the bitfields */
// The second call to GetDIBits() fills in the bitfields
hbm = CreateCompatibleBitmap(data->hdc, 1, 1);
GetDIBits(data->hdc, hbm, 0, 0, NULL, info, DIB_RGB_COLORS);
GetDIBits(data->hdc, hbm, 0, 0, NULL, info, DIB_RGB_COLORS);
@@ -66,13 +66,13 @@ int WIN_CreateWindowFramebuffer(SDL_VideoDevice *_this, SDL_Window *window, SDL_
bpp = info->bmiHeader.biPlanes * info->bmiHeader.biBitCount;
masks = (Uint32 *)((Uint8 *)info + info->bmiHeader.biSize);
*format = SDL_GetPixelFormatEnumForMasks(bpp, masks[0], masks[1], masks[2], 0);
*format = SDL_GetPixelFormatForMasks(bpp, masks[0], masks[1], masks[2], 0);
}
if (*format == SDL_PIXELFORMAT_UNKNOWN) {
/* We'll use RGB format for now */
// We'll use RGB format for now
*format = SDL_PIXELFORMAT_XRGB8888;
/* Create a new one */
// Create a new one
SDL_memset(info, 0, size);
info->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
info->bmiHeader.biPlanes = 1;
@@ -80,10 +80,10 @@ int WIN_CreateWindowFramebuffer(SDL_VideoDevice *_this, SDL_Window *window, SDL_
info->bmiHeader.biCompression = BI_RGB;
}
/* Fill in the size information */
// Fill in the size information
*pitch = (((w * SDL_BYTESPERPIXEL(*format)) + 3) & ~3);
info->bmiHeader.biWidth = w;
info->bmiHeader.biHeight = -h; /* negative for topdown bitmap */
info->bmiHeader.biHeight = -h; // negative for topdown bitmap
info->bmiHeader.biSizeImage = (DWORD)h * (*pitch);
data->mdc = CreateCompatibleDC(data->hdc);
@@ -95,27 +95,27 @@ int WIN_CreateWindowFramebuffer(SDL_VideoDevice *_this, SDL_Window *window, SDL_
}
SelectObject(data->mdc, data->hbm);
return 0;
return true;
}
int WIN_UpdateWindowFramebuffer(SDL_VideoDevice *_this, SDL_Window *window, const SDL_Rect *rects, int numrects)
bool WIN_UpdateWindowFramebuffer(SDL_VideoDevice *_this, SDL_Window *window, const SDL_Rect *rects, int numrects)
{
SDL_WindowData *data = window->driverdata;
SDL_WindowData *data = window->internal;
int i;
for (i = 0; i < numrects; ++i) {
BitBlt(data->hdc, rects[i].x, rects[i].y, rects[i].w, rects[i].h,
data->mdc, rects[i].x, rects[i].y, SRCCOPY);
}
return 0;
return true;
}
void WIN_DestroyWindowFramebuffer(SDL_VideoDevice *_this, SDL_Window *window)
{
SDL_WindowData *data = window->driverdata;
SDL_WindowData *data = window->internal;
if (!data) {
/* The window wasn't fully initialized */
// The window wasn't fully initialized
return;
}
@@ -129,4 +129,4 @@ void WIN_DestroyWindowFramebuffer(SDL_VideoDevice *_this, SDL_Window *window)
}
}
#endif /* SDL_VIDEO_DRIVER_WINDOWS */
#endif // SDL_VIDEO_DRIVER_WINDOWS
@@ -20,6 +20,6 @@
*/
#include "SDL_internal.h"
extern int WIN_CreateWindowFramebuffer(SDL_VideoDevice *_this, SDL_Window *window, SDL_PixelFormatEnum *format, void **pixels, int *pitch);
extern int WIN_UpdateWindowFramebuffer(SDL_VideoDevice *_this, SDL_Window *window, const SDL_Rect *rects, int numrects);
extern bool WIN_CreateWindowFramebuffer(SDL_VideoDevice *_this, SDL_Window *window, SDL_PixelFormat *format, void **pixels, int *pitch);
extern bool WIN_UpdateWindowFramebuffer(SDL_VideoDevice *_this, SDL_Window *window, const SDL_Rect *rects, int numrects);
extern void WIN_DestroyWindowFramebuffer(SDL_VideoDevice *_this, SDL_Window *window);
@@ -0,0 +1,626 @@
/*
Simple DirectMedia Layer
Copyright (C) 1997-2024 Sam Lantinga <slouken@libsdl.org>
This software is provided 'as-is', without any express or implied
warranty. In no event will the authors be held liable for any damages
arising from the use of this software.
Permission is granted to anyone to use this software for any purpose,
including commercial applications, and to alter it and redistribute it
freely, subject to the following restrictions:
1. The origin of this software must not be misrepresented; you must not
claim that you wrote the original software. If you use this software
in a product, an acknowledgment in the product documentation would be
appreciated but is not required.
2. Altered source versions must be plainly marked as such, and must not be
misrepresented as being the original software.
3. This notice may not be removed or altered from any source distribution.
*/
#include "SDL_internal.h"
#include "SDL_windowsvideo.h"
// GameInput currently has a bug with keys stuck on focus change, and crashes on initialization on some systems, so we'll disable it until these issues are fixed.
#undef HAVE_GAMEINPUT_H
#ifdef HAVE_GAMEINPUT_H
#define COBJMACROS
#include <gameinput.h>
#include "../../events/SDL_mouse_c.h"
#include "../../events/SDL_keyboard_c.h"
#include "../../events/scancodes_windows.h"
#define MAX_GAMEINPUT_BUTTONS 7 // GameInputMouseWheelTiltRight is the highest button
static const Uint8 GAMEINPUT_button_map[MAX_GAMEINPUT_BUTTONS] = {
SDL_BUTTON_LEFT,
SDL_BUTTON_RIGHT,
SDL_BUTTON_MIDDLE,
SDL_BUTTON_X1,
SDL_BUTTON_X2,
6,
7
};
typedef struct GAMEINPUT_Device
{
IGameInputDevice *pDevice;
const GameInputDeviceInfo *info;
char *name;
Uint32 instance_id; // generated by SDL
bool registered;
bool delete_requested;
IGameInputReading *last_mouse_reading;
IGameInputReading *last_keyboard_reading;
} GAMEINPUT_Device;
struct WIN_GameInputData
{
void *hGameInputDLL;
IGameInput *pGameInput;
GameInputCallbackToken gameinput_callback_token;
int num_devices;
GAMEINPUT_Device **devices;
GameInputKind enabled_input;
SDL_Mutex *lock;
uint64_t timestamp_offset;
};
static bool GAMEINPUT_InternalAddOrFind(WIN_GameInputData *data, IGameInputDevice *pDevice)
{
GAMEINPUT_Device **devicelist = NULL;
GAMEINPUT_Device *device = NULL;
const GameInputDeviceInfo *info;
bool result = false;
info = IGameInputDevice_GetDeviceInfo(pDevice);
SDL_LockMutex(data->lock);
{
for (int i = 0; i < data->num_devices; ++i) {
device = data->devices[i];
if (device && device->pDevice == pDevice) {
// we're already added
device->delete_requested = false;
result = true;
goto done;
}
}
device = (GAMEINPUT_Device *)SDL_calloc(1, sizeof(*device));
if (!device) {
goto done;
}
devicelist = (GAMEINPUT_Device **)SDL_realloc(data->devices, (data->num_devices + 1) * sizeof(*devicelist));
if (!devicelist) {
SDL_free(device);
goto done;
}
if (info->deviceStrings) {
// In theory we could get the manufacturer and product strings here, but they're NULL for all the devices I've tested
}
if (info->displayName) {
// This could give us a product string, but it's NULL for all the devices I've tested
}
IGameInputDevice_AddRef(pDevice);
device->pDevice = pDevice;
device->instance_id = SDL_GetNextObjectID();
device->info = info;
data->devices = devicelist;
data->devices[data->num_devices++] = device;
result = true;
}
done:
SDL_UnlockMutex(data->lock);
return result;
}
static bool GAMEINPUT_InternalRemoveByIndex(WIN_GameInputData *data, int idx)
{
GAMEINPUT_Device **devicelist = NULL;
GAMEINPUT_Device *device;
bool result = false;
SDL_LockMutex(data->lock);
{
if (idx < 0 || idx >= data->num_devices) {
result = SDL_SetError("GAMEINPUT_InternalRemoveByIndex argument idx %d is out of range", idx);
goto done;
}
device = data->devices[idx];
if (device) {
if (device->registered) {
if (device->info->supportedInput & GameInputKindMouse) {
SDL_RemoveMouse(device->instance_id, true);
}
if (device->info->supportedInput & GameInputKindKeyboard) {
SDL_RemoveKeyboard(device->instance_id, true);
}
if (device->last_mouse_reading) {
IGameInputReading_Release(device->last_mouse_reading);
device->last_mouse_reading = NULL;
}
if (device->last_keyboard_reading) {
IGameInputReading_Release(device->last_keyboard_reading);
device->last_keyboard_reading = NULL;
}
}
IGameInputDevice_Release(device->pDevice);
SDL_free(device->name);
SDL_free(device);
}
data->devices[idx] = NULL;
if (data->num_devices == 1) {
// last element in the list, free the entire list then
SDL_free(data->devices);
data->devices = NULL;
} else {
if (idx != data->num_devices - 1) {
size_t bytes = sizeof(*devicelist) * (data->num_devices - idx - 1);
SDL_memmove(&data->devices[idx], &data->devices[idx + 1], bytes);
}
}
// decrement the count and return
--data->num_devices;
result = true;
}
done:
SDL_UnlockMutex(data->lock);
return result;
}
static void CALLBACK GAMEINPUT_InternalDeviceCallback(
_In_ GameInputCallbackToken callbackToken,
_In_ void* context,
_In_ IGameInputDevice *pDevice,
_In_ uint64_t timestamp,
_In_ GameInputDeviceStatus currentStatus,
_In_ GameInputDeviceStatus previousStatus)
{
WIN_GameInputData *data = (WIN_GameInputData *)context;
int idx = 0;
GAMEINPUT_Device *device = NULL;
if (!pDevice) {
// This should never happen, but ignore it if it does
return;
}
if (currentStatus & GameInputDeviceConnected) {
GAMEINPUT_InternalAddOrFind(data, pDevice);
} else {
for (idx = 0; idx < data->num_devices; ++idx) {
device = data->devices[idx];
if (device && device->pDevice == pDevice) {
// will be deleted on the next Detect call
device->delete_requested = true;
break;
}
}
}
}
bool WIN_InitGameInput(SDL_VideoDevice *_this)
{
WIN_GameInputData *data;
HRESULT hr;
bool result = false;
if (_this->internal->gameinput_context) {
return true;
}
data = (WIN_GameInputData *)SDL_calloc(1, sizeof(*data));
if (!data) {
goto done;
}
_this->internal->gameinput_context = data;
data->lock = SDL_CreateMutex();
if (!data->lock) {
goto done;
}
data->hGameInputDLL = SDL_LoadObject("gameinput.dll");
if (!data->hGameInputDLL) {
goto done;
}
typedef HRESULT (WINAPI *GameInputCreate_t)(IGameInput * *gameInput);
GameInputCreate_t GameInputCreateFunc = (GameInputCreate_t)SDL_LoadFunction(data->hGameInputDLL, "GameInputCreate");
if (!GameInputCreateFunc) {
goto done;
}
hr = GameInputCreateFunc(&data->pGameInput);
if (FAILED(hr)) {
SDL_SetError("GameInputCreate failure with HRESULT of %08X", hr);
goto done;
}
hr = IGameInput_RegisterDeviceCallback(data->pGameInput,
NULL,
(GameInputKindMouse | GameInputKindKeyboard),
GameInputDeviceConnected,
GameInputBlockingEnumeration,
data,
GAMEINPUT_InternalDeviceCallback,
&data->gameinput_callback_token);
if (FAILED(hr)) {
SDL_SetError("IGameInput::RegisterDeviceCallback failure with HRESULT of %08X", hr);
goto done;
}
// Calculate the relative offset between SDL timestamps and GameInput timestamps
Uint64 now = SDL_GetTicksNS();
uint64_t timestampUS = IGameInput_GetCurrentTimestamp(data->pGameInput);
data->timestamp_offset = (SDL_NS_TO_US(now) - timestampUS);
result = true;
done:
if (!result) {
WIN_QuitGameInput(_this);
}
return result;
}
static void GAMEINPUT_InitialMouseReading(WIN_GameInputData *data, SDL_Window *window, GAMEINPUT_Device *device, IGameInputReading *reading)
{
GameInputMouseState state;
if (SUCCEEDED(IGameInputReading_GetMouseState(reading, &state))) {
Uint64 timestamp = SDL_US_TO_NS(IGameInputReading_GetTimestamp(reading) + data->timestamp_offset);
SDL_MouseID mouseID = device->instance_id;
for (int i = 0; i < MAX_GAMEINPUT_BUTTONS; ++i) {
const GameInputMouseButtons mask = (1 << i);
bool down = ((state.buttons & mask) != 0);
SDL_SendMouseButton(timestamp, window, mouseID, GAMEINPUT_button_map[i], down);
}
}
}
static void GAMEINPUT_HandleMouseDelta(WIN_GameInputData *data, SDL_Window *window, GAMEINPUT_Device *device, IGameInputReading *last_reading, IGameInputReading *reading)
{
GameInputMouseState last;
GameInputMouseState state;
if (SUCCEEDED(IGameInputReading_GetMouseState(last_reading, &last)) &&
SUCCEEDED(IGameInputReading_GetMouseState(reading, &state))) {
Uint64 timestamp = SDL_US_TO_NS(IGameInputReading_GetTimestamp(reading) + data->timestamp_offset);
SDL_MouseID mouseID = device->instance_id;
GameInputMouseState delta;
delta.buttons = (state.buttons ^ last.buttons);
delta.positionX = (state.positionX - last.positionX);
delta.positionY = (state.positionY - last.positionY);
delta.wheelX = (state.wheelX - last.wheelX);
delta.wheelY = (state.wheelY - last.wheelY);
if (delta.positionX || delta.positionY) {
SDL_SendMouseMotion(timestamp, window, mouseID, true, (float)delta.positionX, (float)delta.positionY);
}
if (delta.buttons) {
for (int i = 0; i < MAX_GAMEINPUT_BUTTONS; ++i) {
const GameInputMouseButtons mask = (1 << i);
if (delta.buttons & mask) {
bool down = ((state.buttons & mask) != 0);
SDL_SendMouseButton(timestamp, window, mouseID, GAMEINPUT_button_map[i], down);
}
}
}
if (delta.wheelX || delta.wheelY) {
float fAmountX = (float)delta.wheelX / WHEEL_DELTA;
float fAmountY = (float)delta.wheelY / WHEEL_DELTA;
SDL_SendMouseWheel(timestamp, SDL_GetMouseFocus(), device->instance_id, fAmountX, fAmountY, SDL_MOUSEWHEEL_NORMAL);
}
}
}
static SDL_Scancode GetScancodeFromKeyState(const GameInputKeyState *state)
{
Uint8 index = (Uint8)(state->scanCode & 0xFF);
if ((state->scanCode & 0xFF00) == 0xE000) {
index |= 0x80;
}
return windows_scancode_table[index];
}
static bool KeysHaveScancode(const GameInputKeyState *keys, uint32_t count, SDL_Scancode scancode)
{
for (uint32_t i = 0; i < count; ++i) {
if (GetScancodeFromKeyState(&keys[i]) == scancode) {
return true;
}
}
return false;
}
static void GAMEINPUT_InitialKeyboardReading(WIN_GameInputData *data, SDL_Window *window, GAMEINPUT_Device *device, IGameInputReading *reading)
{
Uint64 timestamp = SDL_US_TO_NS(IGameInputReading_GetTimestamp(reading) + data->timestamp_offset);
SDL_KeyboardID keyboardID = device->instance_id;
uint32_t max_keys = device->info->keyboardInfo->maxSimultaneousKeys;
GameInputKeyState *keys = SDL_stack_alloc(GameInputKeyState, max_keys);
if (!keys) {
return;
}
uint32_t num_keys = IGameInputReading_GetKeyState(reading, max_keys, keys);
if (!num_keys) {
// FIXME: We probably need to track key state by keyboardID
SDL_ResetKeyboard();
return;
}
// Go through and send key up events for any key that's not held down
int num_scancodes;
const bool *keyboard_state = SDL_GetKeyboardState(&num_scancodes);
for (int i = 0; i < num_scancodes; ++i) {
if (keyboard_state[i] && !KeysHaveScancode(keys, num_keys, (SDL_Scancode)i)) {
SDL_SendKeyboardKey(timestamp, keyboardID, keys[i].scanCode, (SDL_Scancode)i, false);
}
}
// Go through and send key down events for any key that's held down
for (uint32_t i = 0; i < num_keys; ++i) {
SDL_SendKeyboardKey(timestamp, keyboardID, keys[i].scanCode, GetScancodeFromKeyState(&keys[i]), true);
}
}
#ifdef DEBUG_KEYS
static void DumpKeys(const char *prefix, GameInputKeyState *keys, uint32_t count)
{
SDL_Log("%s", prefix);
for (uint32_t i = 0; i < count; ++i) {
char str[5];
*SDL_UCS4ToUTF8(keys[i].codePoint, str) = '\0';
SDL_Log(" Key 0x%.2x (%s)\n", keys[i].scanCode, str);
}
}
#endif // DEBUG_KEYS
static void GAMEINPUT_HandleKeyboardDelta(WIN_GameInputData *data, SDL_Window *window, GAMEINPUT_Device *device, IGameInputReading *last_reading, IGameInputReading *reading)
{
Uint64 timestamp = SDL_US_TO_NS(IGameInputReading_GetTimestamp(reading) + data->timestamp_offset);
SDL_KeyboardID keyboardID = device->instance_id;
uint32_t max_keys = device->info->keyboardInfo->maxSimultaneousKeys;
GameInputKeyState *last = SDL_stack_alloc(GameInputKeyState, max_keys);
GameInputKeyState *keys = SDL_stack_alloc(GameInputKeyState, max_keys);
if (!last || !keys) {
return;
}
uint32_t index_last = 0;
uint32_t index_keys = 0;
uint32_t num_last = IGameInputReading_GetKeyState(last_reading, max_keys, last);
uint32_t num_keys = IGameInputReading_GetKeyState(reading, max_keys, keys);
#ifdef DEBUG_KEYS
SDL_Log("Timestamp: %llu\n", timestamp);
DumpKeys("Last keys:", last, num_last);
DumpKeys("New keys:", keys, num_keys);
#endif
while (index_last < num_last || index_keys < num_keys) {
if (index_last < num_last && index_keys < num_keys) {
if (last[index_last].scanCode == keys[index_keys].scanCode) {
// No change
++index_last;
++index_keys;
} else {
// This key was released
SDL_SendKeyboardKey(timestamp, keyboardID, last[index_last].scanCode, GetScancodeFromKeyState(&last[index_last]), false);
++index_last;
}
} else if (index_last < num_last) {
// This key was released
SDL_SendKeyboardKey(timestamp, keyboardID, last[index_last].scanCode, GetScancodeFromKeyState(&last[index_last]), false);
++index_last;
} else {
// This key was pressed
SDL_SendKeyboardKey(timestamp, keyboardID, keys[index_keys].scanCode, GetScancodeFromKeyState(&keys[index_keys]), true);
++index_keys;
}
}
}
void WIN_UpdateGameInput(SDL_VideoDevice *_this)
{
WIN_GameInputData *data = _this->internal->gameinput_context;
SDL_LockMutex(data->lock);
{
// Key events and relative mouse motion both go to the window with keyboard focus
SDL_Window *window = SDL_GetKeyboardFocus();
for (int i = 0; i < data->num_devices; ++i) {
GAMEINPUT_Device *device = data->devices[i];
IGameInputReading *reading;
if (!device->registered) {
if (device->info->supportedInput & GameInputKindMouse) {
SDL_AddMouse(device->instance_id, device->name, true);
}
if (device->info->supportedInput & GameInputKindKeyboard) {
SDL_AddKeyboard(device->instance_id, device->name, true);
}
device->registered = true;
}
if (device->delete_requested) {
GAMEINPUT_InternalRemoveByIndex(data, i--);
continue;
}
if (!(device->info->supportedInput & data->enabled_input)) {
continue;
}
if (!window) {
continue;
}
if (data->enabled_input & GameInputKindMouse) {
if (device->last_mouse_reading) {
HRESULT hr;
while (SUCCEEDED(hr = IGameInput_GetNextReading(data->pGameInput, device->last_mouse_reading, GameInputKindMouse, device->pDevice, &reading))) {
GAMEINPUT_HandleMouseDelta(data, window, device, device->last_mouse_reading, reading);
IGameInputReading_Release(device->last_mouse_reading);
device->last_mouse_reading = reading;
}
if (hr != GAMEINPUT_E_READING_NOT_FOUND) {
// The last reading is too old, resynchronize
IGameInputReading_Release(device->last_mouse_reading);
device->last_mouse_reading = NULL;
}
}
if (!device->last_mouse_reading) {
if (SUCCEEDED(IGameInput_GetCurrentReading(data->pGameInput, GameInputKindMouse, device->pDevice, &reading))) {
GAMEINPUT_InitialMouseReading(data, window, device, reading);
device->last_mouse_reading = reading;
}
}
}
if (data->enabled_input & GameInputKindKeyboard) {
if (window->text_input_active) {
// Reset raw input while text input is active
if (device->last_keyboard_reading) {
IGameInputReading_Release(device->last_keyboard_reading);
device->last_keyboard_reading = NULL;
}
} else {
if (device->last_keyboard_reading) {
HRESULT hr;
while (SUCCEEDED(hr = IGameInput_GetNextReading(data->pGameInput, device->last_keyboard_reading, GameInputKindKeyboard, device->pDevice, &reading))) {
GAMEINPUT_HandleKeyboardDelta(data, window, device, device->last_keyboard_reading, reading);
IGameInputReading_Release(device->last_keyboard_reading);
device->last_keyboard_reading = reading;
}
if (hr != GAMEINPUT_E_READING_NOT_FOUND) {
// The last reading is too old, resynchronize
IGameInputReading_Release(device->last_keyboard_reading);
device->last_keyboard_reading = NULL;
}
}
if (!device->last_keyboard_reading) {
if (SUCCEEDED(IGameInput_GetCurrentReading(data->pGameInput, GameInputKindKeyboard, device->pDevice, &reading))) {
GAMEINPUT_InitialKeyboardReading(data, window, device, reading);
device->last_keyboard_reading = reading;
}
}
}
}
}
}
SDL_UnlockMutex(data->lock);
}
bool WIN_UpdateGameInputEnabled(SDL_VideoDevice *_this)
{
WIN_GameInputData *data = _this->internal->gameinput_context;
bool raw_mouse_enabled = _this->internal->raw_mouse_enabled;
bool raw_keyboard_enabled = _this->internal->raw_keyboard_enabled;
SDL_LockMutex(data->lock);
{
data->enabled_input = (raw_mouse_enabled ? GameInputKindMouse : GameInputKindUnknown) |
(raw_keyboard_enabled ? GameInputKindKeyboard : GameInputKindUnknown);
// Reset input if not enabled
for (int i = 0; i < data->num_devices; ++i) {
GAMEINPUT_Device *device = data->devices[i];
if (device->last_mouse_reading && !raw_mouse_enabled) {
IGameInputReading_Release(device->last_mouse_reading);
device->last_mouse_reading = NULL;
}
if (device->last_keyboard_reading && !raw_keyboard_enabled) {
IGameInputReading_Release(device->last_keyboard_reading);
device->last_keyboard_reading = NULL;
}
}
}
SDL_UnlockMutex(data->lock);
return true;
}
void WIN_QuitGameInput(SDL_VideoDevice *_this)
{
WIN_GameInputData *data = _this->internal->gameinput_context;
if (!data) {
return;
}
if (data->pGameInput) {
// free the callback
if (data->gameinput_callback_token != GAMEINPUT_INVALID_CALLBACK_TOKEN_VALUE) {
IGameInput_UnregisterCallback(data->pGameInput, data->gameinput_callback_token, /*timeoutInUs:*/ 10000);
data->gameinput_callback_token = GAMEINPUT_INVALID_CALLBACK_TOKEN_VALUE;
}
// free the list
while (data->num_devices > 0) {
GAMEINPUT_InternalRemoveByIndex(data, 0);
}
IGameInput_Release(data->pGameInput);
data->pGameInput = NULL;
}
if (data->hGameInputDLL) {
SDL_UnloadObject(data->hGameInputDLL);
data->hGameInputDLL = NULL;
}
if (data->lock) {
SDL_DestroyMutex(data->lock);
data->lock = NULL;
}
SDL_free(data);
_this->internal->gameinput_context = NULL;
}
#else // !HAVE_GAMEINPUT_H
bool WIN_InitGameInput(SDL_VideoDevice* _this)
{
return SDL_Unsupported();
}
bool WIN_UpdateGameInputEnabled(SDL_VideoDevice *_this)
{
return SDL_Unsupported();
}
void WIN_UpdateGameInput(SDL_VideoDevice* _this)
{
return;
}
void WIN_QuitGameInput(SDL_VideoDevice* _this)
{
return;
}
#endif // HAVE_GAMEINPUT_H
@@ -0,0 +1,29 @@
/*
Simple DirectMedia Layer
Copyright (C) 1997-2024 Sam Lantinga <slouken@libsdl.org>
This software is provided 'as-is', without any express or implied
warranty. In no event will the authors be held liable for any damages
arising from the use of this software.
Permission is granted to anyone to use this software for any purpose,
including commercial applications, and to alter it and redistribute it
freely, subject to the following restrictions:
1. The origin of this software must not be misrepresented; you must not
claim that you wrote the original software. If you use this software
in a product, an acknowledgment in the product documentation would be
appreciated but is not required.
2. Altered source versions must be plainly marked as such, and must not be
misrepresented as being the original software.
3. This notice may not be removed or altered from any source distribution.
*/
#include "SDL_internal.h"
typedef struct WIN_GameInputData WIN_GameInputData;
extern bool WIN_InitGameInput(SDL_VideoDevice *_this);
extern bool WIN_UpdateGameInputEnabled(SDL_VideoDevice *_this);
extern void WIN_UpdateGameInput(SDL_VideoDevice *_this);
extern void WIN_QuitGameInput(SDL_VideoDevice *_this);
File diff suppressed because it is too large Load Diff
@@ -24,16 +24,17 @@
#define SDL_windowskeyboard_h_
extern void WIN_InitKeyboard(SDL_VideoDevice *_this);
extern void WIN_UpdateKeymap(SDL_bool send_event);
extern void WIN_UpdateKeymap(bool send_event);
extern void WIN_QuitKeyboard(SDL_VideoDevice *_this);
extern void WIN_ResetDeadKeys(void);
extern void WIN_StartTextInput(SDL_VideoDevice *_this);
extern void WIN_StopTextInput(SDL_VideoDevice *_this);
extern int WIN_SetTextInputRect(SDL_VideoDevice *_this, const SDL_Rect *rect);
extern void WIN_ClearComposition(SDL_VideoDevice *_this);
extern bool WIN_StartTextInput(SDL_VideoDevice *_this, SDL_Window *window, SDL_PropertiesID props);
extern bool WIN_StopTextInput(SDL_VideoDevice *_this, SDL_Window *window);
extern bool WIN_UpdateTextInputArea(SDL_VideoDevice *_this, SDL_Window *window);
extern bool WIN_ClearComposition(SDL_VideoDevice *_this, SDL_Window *window);
extern SDL_bool IME_HandleMessage(HWND hwnd, UINT msg, WPARAM wParam, LPARAM *lParam, struct SDL_VideoData *videodata);
extern bool WIN_HandleIMEMessage(HWND hwnd, UINT msg, WPARAM wParam, LPARAM *lParam, struct SDL_VideoData *videodata);
extern void WIN_UpdateIMECandidates(SDL_VideoDevice *_this);
#endif /* SDL_windowskeyboard_h_ */
#endif // SDL_windowskeyboard_h_
@@ -45,13 +45,13 @@
#define IDCANCEL 2
#endif
/* Custom dialog return codes */
// Custom dialog return codes
#define IDCLOSED 20
#define IDINVALPTRINIT 50
#define IDINVALPTRCOMMAND 51
#define IDINVALPTRSETFOCUS 52
#define IDINVALPTRDLGITEM 53
/* First button ID */
// First button ID
#define IDBUTTONINDEX0 100
#define DLGITEMTYPEBUTTON 0x0080
@@ -64,7 +64,7 @@
*/
#define MAX_BUTTONS (0xffff - 100)
/* Display a Windows message box */
// Display a Windows message box
typedef HRESULT(CALLBACK *PFTASKDIALOGCALLBACK)(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam, LONG_PTR lpRefData);
@@ -238,14 +238,14 @@ typedef struct
WORD numbuttons;
} WIN_DialogData;
static SDL_bool GetButtonIndex(const SDL_MessageBoxData *messageboxdata, Uint32 flags, size_t *i)
static bool GetButtonIndex(const SDL_MessageBoxData *messageboxdata, SDL_MessageBoxButtonFlags flags, size_t *i)
{
for (*i = 0; *i < (size_t)messageboxdata->numbuttons; ++*i) {
if (messageboxdata->buttons[*i].flags & flags) {
return SDL_TRUE;
return true;
}
}
return SDL_FALSE;
return false;
}
static INT_PTR CALLBACK MessageBoxDialogProc(HWND hDlg, UINT iMessage, WPARAM wParam, LPARAM lParam)
@@ -263,14 +263,14 @@ static INT_PTR CALLBACK MessageBoxDialogProc(HWND hDlg, UINT iMessage, WPARAM wP
SetWindowLongPtr(hDlg, GWLP_USERDATA, lParam);
if (GetButtonIndex(messageboxdata, SDL_MESSAGEBOX_BUTTON_RETURNKEY_DEFAULT, &buttonindex)) {
/* Focus on the first default return-key button */
// Focus on the first default return-key button
HWND buttonctl = GetDlgItem(hDlg, (int)(IDBUTTONINDEX0 + buttonindex));
if (!buttonctl) {
EndDialog(hDlg, IDINVALPTRDLGITEM);
}
PostMessage(hDlg, WM_NEXTDLGCTL, (WPARAM)buttonctl, TRUE);
} else {
/* Give the focus to the dialog window instead */
// Give the focus to the dialog window instead
SetFocus(hDlg);
}
return FALSE;
@@ -281,7 +281,7 @@ static INT_PTR CALLBACK MessageBoxDialogProc(HWND hDlg, UINT iMessage, WPARAM wP
return TRUE;
}
/* Let the default button be focused if there is one. Otherwise, prevent any initial focus. */
// Let the default button be focused if there is one. Otherwise, prevent any initial focus.
if (GetButtonIndex(messageboxdata, SDL_MESSAGEBOX_BUTTON_RETURNKEY_DEFAULT, &buttonindex)) {
return FALSE;
}
@@ -293,7 +293,7 @@ static INT_PTR CALLBACK MessageBoxDialogProc(HWND hDlg, UINT iMessage, WPARAM wP
return TRUE;
}
/* Return the ID of the button that was pushed */
// Return the ID of the button that was pushed
if (wParam == IDOK) {
if (GetButtonIndex(messageboxdata, SDL_MESSAGEBOX_BUTTON_RETURNKEY_DEFAULT, &buttonindex)) {
EndDialog(hDlg, IDBUTTONINDEX0 + buttonindex);
@@ -302,7 +302,7 @@ static INT_PTR CALLBACK MessageBoxDialogProc(HWND hDlg, UINT iMessage, WPARAM wP
if (GetButtonIndex(messageboxdata, SDL_MESSAGEBOX_BUTTON_ESCAPEKEY_DEFAULT, &buttonindex)) {
EndDialog(hDlg, IDBUTTONINDEX0 + buttonindex);
} else {
/* Closing of window was requested by user or system. It would be rude not to comply. */
// Closing of window was requested by user or system. It would be rude not to comply.
EndDialog(hDlg, IDCLOSED);
}
} else if (wParam >= IDBUTTONINDEX0 && (int)wParam - IDBUTTONINDEX0 < messageboxdata->numbuttons) {
@@ -316,14 +316,14 @@ static INT_PTR CALLBACK MessageBoxDialogProc(HWND hDlg, UINT iMessage, WPARAM wP
return FALSE;
}
static SDL_bool ExpandDialogSpace(WIN_DialogData *dialog, size_t space)
static bool ExpandDialogSpace(WIN_DialogData *dialog, size_t space)
{
/* Growing memory in 64 KiB steps. */
// Growing memory in 64 KiB steps.
const size_t sizestep = 0x10000;
size_t size = dialog->size;
if (size == 0) {
/* Start with 4 KiB or a multiple of 64 KiB to fit the data. */
// Start with 4 KiB or a multiple of 64 KiB to fit the data.
size = 0x1000;
if (SIZE_MAX - sizestep < space) {
size = space;
@@ -332,12 +332,12 @@ static SDL_bool ExpandDialogSpace(WIN_DialogData *dialog, size_t space)
}
} else if (SIZE_MAX - dialog->used < space) {
SDL_OutOfMemory();
return SDL_FALSE;
return false;
} else if (SIZE_MAX - (dialog->used + space) < sizestep) {
/* Close to the maximum. */
// Close to the maximum.
size = dialog->used + space;
} else if (size < dialog->used + space) {
/* Round up to the next 64 KiB block. */
// Round up to the next 64 KiB block.
size = dialog->used + space;
size += sizestep - size % sizestep;
}
@@ -345,46 +345,46 @@ static SDL_bool ExpandDialogSpace(WIN_DialogData *dialog, size_t space)
if (size > dialog->size) {
void *data = SDL_realloc(dialog->data, size);
if (!data) {
return SDL_FALSE;
return false;
}
dialog->data = data;
dialog->size = size;
dialog->lpDialog = (DLGTEMPLATEEX *)dialog->data;
}
return SDL_TRUE;
return true;
}
static SDL_bool AlignDialogData(WIN_DialogData *dialog, size_t size)
static bool AlignDialogData(WIN_DialogData *dialog, size_t size)
{
size_t padding = (dialog->used % size);
if (!ExpandDialogSpace(dialog, padding)) {
return SDL_FALSE;
return false;
}
dialog->used += padding;
return SDL_TRUE;
return true;
}
static SDL_bool AddDialogData(WIN_DialogData *dialog, const void *data, size_t size)
static bool AddDialogData(WIN_DialogData *dialog, const void *data, size_t size)
{
if (!ExpandDialogSpace(dialog, size)) {
return SDL_FALSE;
return false;
}
SDL_memcpy((Uint8 *)dialog->data + dialog->used, data, size);
dialog->used += size;
return SDL_TRUE;
return true;
}
static SDL_bool AddDialogString(WIN_DialogData *dialog, const char *string)
static bool AddDialogString(WIN_DialogData *dialog, const char *string)
{
WCHAR *wstring;
WCHAR *p;
size_t count;
SDL_bool status;
bool status;
if (!string) {
string = "";
@@ -392,10 +392,10 @@ static SDL_bool AddDialogString(WIN_DialogData *dialog, const char *string)
wstring = WIN_UTF8ToStringW(string);
if (!wstring) {
return SDL_FALSE;
return false;
}
/* Find out how many characters we have, including null terminator */
// Find out how many characters we have, including null terminator
count = 0;
for (p = wstring; *p; ++p) {
++count;
@@ -411,13 +411,13 @@ static int s_BaseUnitsX;
static int s_BaseUnitsY;
static void Vec2ToDLU(short *x, short *y)
{
SDL_assert(s_BaseUnitsX != 0); /* we init in WIN_ShowMessageBox(), which is the only public function... */
SDL_assert(s_BaseUnitsX != 0); // we init in WIN_ShowMessageBox(), which is the only public function...
*x = (short)MulDiv(*x, 4, s_BaseUnitsX);
*y = (short)MulDiv(*y, 8, s_BaseUnitsY);
}
static SDL_bool AddDialogControl(WIN_DialogData *dialog, WORD type, DWORD style, DWORD exStyle, int x, int y, int w, int h, int id, const char *caption, WORD ordinal)
static bool AddDialogControl(WIN_DialogData *dialog, WORD type, DWORD style, DWORD exStyle, int x, int y, int w, int h, int id, const char *caption, WORD ordinal)
{
DLGITEMTEMPLATEEX item;
WORD marker = 0xFFFF;
@@ -436,53 +436,53 @@ static SDL_bool AddDialogControl(WIN_DialogData *dialog, WORD type, DWORD style,
Vec2ToDLU(&item.cx, &item.cy);
if (!AlignDialogData(dialog, sizeof(DWORD))) {
return SDL_FALSE;
return false;
}
if (!AddDialogData(dialog, &item, sizeof(item))) {
return SDL_FALSE;
return false;
}
if (!AddDialogData(dialog, &marker, sizeof(marker))) {
return SDL_FALSE;
return false;
}
if (!AddDialogData(dialog, &type, sizeof(type))) {
return SDL_FALSE;
return false;
}
if (type == DLGITEMTYPEBUTTON || (type == DLGITEMTYPESTATIC && caption)) {
if (!AddDialogString(dialog, caption)) {
return SDL_FALSE;
return false;
}
} else {
if (!AddDialogData(dialog, &marker, sizeof(marker))) {
return SDL_FALSE;
return false;
}
if (!AddDialogData(dialog, &ordinal, sizeof(ordinal))) {
return SDL_FALSE;
return false;
}
}
if (!AddDialogData(dialog, &extraData, sizeof(extraData))) {
return SDL_FALSE;
return false;
}
if (type == DLGITEMTYPEBUTTON) {
dialog->numbuttons++;
}
++dialog->lpDialog->cDlgItems;
return SDL_TRUE;
return true;
}
static SDL_bool AddDialogStaticText(WIN_DialogData *dialog, int x, int y, int w, int h, const char *text)
static bool AddDialogStaticText(WIN_DialogData *dialog, int x, int y, int w, int h, const char *text)
{
DWORD style = WS_VISIBLE | WS_CHILD | SS_LEFT | SS_NOPREFIX | SS_EDITCONTROL | WS_GROUP;
return AddDialogControl(dialog, DLGITEMTYPESTATIC, style, 0, x, y, w, h, -1, text, 0);
}
static SDL_bool AddDialogStaticIcon(WIN_DialogData *dialog, int x, int y, int w, int h, Uint16 ordinal)
static bool AddDialogStaticIcon(WIN_DialogData *dialog, int x, int y, int w, int h, Uint16 ordinal)
{
DWORD style = WS_VISIBLE | WS_CHILD | SS_ICON | WS_GROUP;
return AddDialogControl(dialog, DLGITEMTYPESTATIC, style, 0, x, y, w, h, -2, NULL, ordinal);
}
static SDL_bool AddDialogButton(WIN_DialogData *dialog, int x, int y, int w, int h, const char *text, int id, SDL_bool isDefault)
static bool AddDialogButton(WIN_DialogData *dialog, int x, int y, int w, int h, const char *text, int id, bool isDefault)
{
DWORD style = WS_VISIBLE | WS_CHILD | WS_TABSTOP;
if (isDefault) {
@@ -490,7 +490,7 @@ static SDL_bool AddDialogButton(WIN_DialogData *dialog, int x, int y, int w, int
} else {
style |= BS_PUSHBUTTON;
}
/* The first button marks the start of the group. */
// The first button marks the start of the group.
if (dialog->numbuttons == 0) {
style |= WS_GROUP;
}
@@ -529,26 +529,26 @@ static WIN_DialogData *CreateDialogData(int w, int h, const char *caption)
return NULL;
}
/* No menu */
// No menu
WordToPass = 0;
if (!AddDialogData(dialog, &WordToPass, 2)) {
FreeDialogData(dialog);
return NULL;
}
/* No custom class */
// No custom class
if (!AddDialogData(dialog, &WordToPass, 2)) {
FreeDialogData(dialog);
return NULL;
}
/* title */
// title
if (!AddDialogString(dialog, caption)) {
FreeDialogData(dialog);
return NULL;
}
/* Font stuff */
// Font stuff
{
/*
* We want to use the system messagebox font.
@@ -559,12 +559,12 @@ static WIN_DialogData *CreateDialogData(int w, int h, const char *caption)
NCM.cbSize = sizeof(NCM);
SystemParametersInfoA(SPI_GETNONCLIENTMETRICS, 0, &NCM, 0);
/* Font size - convert to logical font size for dialog parameter. */
// Font size - convert to logical font size for dialog parameter.
{
HDC ScreenDC = GetDC(NULL);
int LogicalPixelsY = GetDeviceCaps(ScreenDC, LOGPIXELSY);
if (!LogicalPixelsY) {
LogicalPixelsY = 72; /* This can happen if the application runs out of GDI handles */
LogicalPixelsY = 72; // This can happen if the application runs out of GDI handles
}
WordToPass = (WORD)(-72 * NCM.lfMessageFont.lfHeight / LogicalPixelsY);
@@ -576,28 +576,28 @@ static WIN_DialogData *CreateDialogData(int w, int h, const char *caption)
return NULL;
}
/* Font weight */
// Font weight
WordToPass = (WORD)NCM.lfMessageFont.lfWeight;
if (!AddDialogData(dialog, &WordToPass, 2)) {
FreeDialogData(dialog);
return NULL;
}
/* italic? */
// italic?
ToPass = NCM.lfMessageFont.lfItalic;
if (!AddDialogData(dialog, &ToPass, 1)) {
FreeDialogData(dialog);
return NULL;
}
/* charset? */
// charset?
ToPass = NCM.lfMessageFont.lfCharSet;
if (!AddDialogData(dialog, &ToPass, 1)) {
FreeDialogData(dialog);
return NULL;
}
/* font typeface. */
// font typeface.
if (!AddDialogString(dialog, NCM.lfMessageFont.lfFaceName)) {
FreeDialogData(dialog);
return NULL;
@@ -635,14 +635,14 @@ static const char *EscapeAmpersands(char **dst, size_t *dstlen, const char *src)
srclen++;
if (ampcount == 0) {
/* Nothing to do. */
// Nothing to do.
return src;
}
if (SIZE_MAX - srclen < ampcount) {
return NULL;
}
if (!*dst || *dstlen < srclen + ampcount) {
/* Allocating extra space in case the next strings are a bit longer. */
// Allocating extra space in case the next strings are a bit longer.
size_t extraspace = SIZE_MAX - (srclen + ampcount);
if (extraspace > 512) {
extraspace = 512;
@@ -659,7 +659,7 @@ static const char *EscapeAmpersands(char **dst, size_t *dstlen, const char *src)
newdst = *dst;
}
/* The escape character is the ampersand itself. */
// The escape character is the ampersand itself.
while (srclen--) {
if (*src == '&') {
*newdst++ = '&';
@@ -670,22 +670,23 @@ static const char *EscapeAmpersands(char **dst, size_t *dstlen, const char *src)
return *dst;
}
/* This function is called if a Task Dialog is unsupported. */
static int WIN_ShowOldMessageBox(const SDL_MessageBoxData *messageboxdata, int *buttonID)
// This function is called if a Task Dialog is unsupported.
static bool WIN_ShowOldMessageBox(const SDL_MessageBoxData *messageboxdata, int *buttonID)
{
WIN_DialogData *dialog;
int i, x, y, retval;
int i, x, y;
HFONT DialogFont;
SIZE Size;
RECT TextSize;
wchar_t *wmessage;
TEXTMETRIC TM;
HDC FontDC;
INT_PTR result;
INT_PTR rc;
char *ampescape = NULL;
size_t ampescapesize = 0;
Uint16 defbuttoncount = 0;
Uint16 icon = 0;
bool result;
HWND ParentWindow = NULL;
@@ -701,7 +702,7 @@ static int WIN_ShowOldMessageBox(const SDL_MessageBoxData *messageboxdata, int *
return SDL_SetError("Number of buttons exceeds limit of %d", MAX_BUTTONS);
}
switch (messageboxdata->flags) {
switch (messageboxdata->flags & (SDL_MESSAGEBOX_ERROR | SDL_MESSAGEBOX_WARNING | SDL_MESSAGEBOX_INFORMATION)) {
case SDL_MESSAGEBOX_ERROR:
icon = (Uint16)(size_t)IDI_ERROR;
break;
@@ -745,7 +746,7 @@ static int WIN_ShowOldMessageBox(const SDL_MessageBoxData *messageboxdata, int *
FontDC = CreateCompatibleDC(0);
{
/* Create a duplicate of the font used in system message boxes. */
// Create a duplicate of the font used in system message boxes.
LOGFONT lf;
NONCLIENTMETRICS NCM;
NCM.cbSize = sizeof(NCM);
@@ -754,11 +755,11 @@ static int WIN_ShowOldMessageBox(const SDL_MessageBoxData *messageboxdata, int *
DialogFont = CreateFontIndirect(&lf);
}
/* Select the font in to our DC */
// Select the font in to our DC
SelectObject(FontDC, DialogFont);
{
/* Get the metrics to try and figure our DLU conversion. */
// Get the metrics to try and figure our DLU conversion.
GetTextMetrics(FontDC, &TM);
/* Calculation from the following documentation:
@@ -770,7 +771,7 @@ static int WIN_ShowOldMessageBox(const SDL_MessageBoxData *messageboxdata, int *
GetTextExtentPoint32A(FontDC, "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz", 52, &extent);
s_BaseUnitsX = (extent.cx / 26 + 1) / 2;
}
/*s_BaseUnitsX = TM.tmAveCharWidth + 1;*/
// s_BaseUnitsX = TM.tmAveCharWidth + 1;
s_BaseUnitsY = TM.tmHeight;
}
@@ -779,62 +780,62 @@ static int WIN_ShowOldMessageBox(const SDL_MessageBoxData *messageboxdata, int *
SDL_zero(TextSize);
DrawTextW(FontDC, wmessage, -1, &TextSize, DT_CALCRECT | DT_LEFT | DT_NOPREFIX | DT_EDITCONTROL);
/* Add margins and some padding for hangs, etc. */
// Add margins and some padding for hangs, etc.
TextSize.left += TextMargin;
TextSize.right += TextMargin + 2;
TextSize.top += TextMargin;
TextSize.bottom += TextMargin + 2;
/* Done with the DC, and the string */
// Done with the DC, and the string
DeleteDC(FontDC);
SDL_free(wmessage);
/* Increase the size of the dialog by some border spacing around the text. */
// Increase the size of the dialog by some border spacing around the text.
Size.cx = TextSize.right - TextSize.left;
Size.cy = TextSize.bottom - TextSize.top;
Size.cx += TextMargin * 2;
Size.cy += TextMargin * 2;
/* Make dialog wider and shift text over for the icon. */
// Make dialog wider and shift text over for the icon.
if (icon) {
Size.cx += IconMargin + IconWidth;
TextSize.left += IconMargin + IconWidth;
TextSize.right += IconMargin + IconWidth;
}
/* Ensure the size is wide enough for all of the buttons. */
// Ensure the size is wide enough for all of the buttons.
if (Size.cx < (LONG)messageboxdata->numbuttons * (ButtonWidth + ButtonMargin) + ButtonMargin) {
Size.cx = (LONG)messageboxdata->numbuttons * (ButtonWidth + ButtonMargin) + ButtonMargin;
}
/* Reset the height to the icon size if it is actually bigger than the text. */
// Reset the height to the icon size if it is actually bigger than the text.
if (icon && Size.cy < (LONG)IconMargin * 2 + IconHeight) {
Size.cy = (LONG)IconMargin * 2 + IconHeight;
}
/* Add vertical space for the buttons and border. */
// Add vertical space for the buttons and border.
Size.cy += ButtonHeight + TextMargin;
dialog = CreateDialogData(Size.cx, Size.cy, messageboxdata->title);
if (!dialog) {
return -1;
return false;
}
if (icon && !AddDialogStaticIcon(dialog, IconMargin, IconMargin, IconWidth, IconHeight, icon)) {
FreeDialogData(dialog);
return -1;
return false;
}
if (!AddDialogStaticText(dialog, TextSize.left, TextSize.top, TextSize.right - TextSize.left, TextSize.bottom - TextSize.top, messageboxdata->message)) {
FreeDialogData(dialog);
return -1;
return false;
}
/* Align the buttons to the right/bottom. */
// Align the buttons to the right/bottom.
x = Size.cx - (ButtonWidth + ButtonMargin) * messageboxdata->numbuttons;
y = Size.cy - ButtonHeight - ButtonMargin;
for (i = 0; i < messageboxdata->numbuttons; i++) {
SDL_bool isdefault = SDL_FALSE;
bool isdefault = false;
const char *buttontext;
const SDL_MessageBoxButtonData *sdlButton;
@@ -850,7 +851,7 @@ static int WIN_ShowOldMessageBox(const SDL_MessageBoxData *messageboxdata, int *
if (sdlButton->flags & SDL_MESSAGEBOX_BUTTON_RETURNKEY_DEFAULT) {
defbuttoncount++;
if (defbuttoncount == 1) {
isdefault = SDL_TRUE;
isdefault = true;
}
}
@@ -860,7 +861,7 @@ static int WIN_ShowOldMessageBox(const SDL_MessageBoxData *messageboxdata, int *
if (!buttontext || !AddDialogButton(dialog, x, y, ButtonWidth, ButtonHeight, buttontext, IDBUTTONINDEX0 + (int)(sdlButton - messageboxdata->buttons), isdefault)) {
FreeDialogData(dialog);
SDL_free(ampescape);
return -1;
return false;
}
x += ButtonWidth + ButtonMargin;
@@ -870,45 +871,45 @@ static int WIN_ShowOldMessageBox(const SDL_MessageBoxData *messageboxdata, int *
/* If we have a parent window, get the Instance and HWND for them
* so that our little dialog gets exclusive focus at all times. */
if (messageboxdata->window) {
ParentWindow = messageboxdata->window->driverdata->hwnd;
ParentWindow = messageboxdata->window->internal->hwnd;
}
result = DialogBoxIndirectParam(NULL, (DLGTEMPLATE *)dialog->lpDialog, ParentWindow, MessageBoxDialogProc, (LPARAM)messageboxdata);
if (result >= IDBUTTONINDEX0 && result - IDBUTTONINDEX0 < messageboxdata->numbuttons) {
*buttonID = messageboxdata->buttons[result - IDBUTTONINDEX0].buttonID;
retval = 0;
} else if (result == IDCLOSED) {
/* Dialog window closed by user or system. */
/* This could use a special return code. */
retval = 0;
rc = DialogBoxIndirectParam(NULL, (DLGTEMPLATE *)dialog->lpDialog, ParentWindow, MessageBoxDialogProc, (LPARAM)messageboxdata);
if (rc >= IDBUTTONINDEX0 && rc - IDBUTTONINDEX0 < messageboxdata->numbuttons) {
*buttonID = messageboxdata->buttons[rc - IDBUTTONINDEX0].buttonID;
result = true;
} else if (rc == IDCLOSED) {
// Dialog window closed by user or system.
// This could use a special return code.
result = true;
*buttonID = -1;
} else {
if (result == 0) {
if (rc == 0) {
SDL_SetError("Invalid parent window handle");
} else if (result == -1) {
} else if (rc == -1) {
SDL_SetError("The message box encountered an error.");
} else if (result == IDINVALPTRINIT || result == IDINVALPTRSETFOCUS || result == IDINVALPTRCOMMAND) {
} else if (rc == IDINVALPTRINIT || rc == IDINVALPTRSETFOCUS || rc == IDINVALPTRCOMMAND) {
SDL_SetError("Invalid message box pointer in dialog procedure");
} else if (result == IDINVALPTRDLGITEM) {
} else if (rc == IDINVALPTRDLGITEM) {
SDL_SetError("Couldn't find dialog control of the default enter-key button");
} else {
SDL_SetError("An unknown error occurred");
}
retval = -1;
result = false;
}
FreeDialogData(dialog);
return retval;
return result;
}
/* TaskDialogIndirect procedure
* This is because SDL targets Windows XP (0x501), so this is not defined in the platform SDK.
*/
/* *INDENT-OFF* */ /* clang-format off */
/* *INDENT-OFF* */ // clang-format off
typedef HRESULT (FAR WINAPI *TASKDIALOGINDIRECTPROC)(const TASKDIALOGCONFIG *pTaskConfig, int *pnButton, int *pnRadioButton, BOOL *pfVerificationFlagChecked);
/* *INDENT-ON* */ /* clang-format on */
/* *INDENT-ON* */ // clang-format on
int WIN_ShowMessageBox(const SDL_MessageBoxData *messageboxdata, int *buttonID)
bool WIN_ShowMessageBox(const SDL_MessageBoxData *messageboxdata, int *buttonID)
{
HWND ParentWindow = NULL;
wchar_t *wmessage;
@@ -929,7 +930,7 @@ int WIN_ShowMessageBox(const SDL_MessageBoxData *messageboxdata, int *buttonID)
return SDL_OutOfMemory();
}
/* If we cannot load comctl32.dll use the old messagebox! */
// If we cannot load comctl32.dll use the old messagebox!
hComctl32 = LoadLibrary(TEXT("comctl32.dll"));
if (!hComctl32) {
return WIN_ShowOldMessageBox(messageboxdata, buttonID);
@@ -951,7 +952,7 @@ int WIN_ShowMessageBox(const SDL_MessageBoxData *messageboxdata, int *buttonID)
/* If we have a parent window, get the Instance and HWND for them
so that our little dialog gets exclusive focus at all times. */
if (messageboxdata->window) {
ParentWindow = messageboxdata->window->driverdata->hwnd;
ParentWindow = messageboxdata->window->internal->hwnd;
}
wmessage = WIN_UTF8ToStringW(messageboxdata->message);
@@ -1001,7 +1002,7 @@ int WIN_ShowMessageBox(const SDL_MessageBoxData *messageboxdata, int *buttonID)
SDL_free((wchar_t *)pButtons[j].pszButtonText);
}
SDL_free(pButtons);
return -1;
return false;
}
pButton->pszButtonText = WIN_UTF8ToStringW(buttontext);
if (messageboxdata->buttons[i].flags & SDL_MESSAGEBOX_BUTTON_RETURNKEY_DEFAULT) {
@@ -1010,10 +1011,10 @@ int WIN_ShowMessageBox(const SDL_MessageBoxData *messageboxdata, int *buttonID)
}
TaskConfig.pButtons = pButtons;
/* Show the Task Dialog */
// Show the Task Dialog
hr = pfnTaskDialogIndirect(&TaskConfig, &nButton, NULL, NULL);
/* Free everything */
// Free everything
FreeLibrary(hComctl32);
SDL_free(ampescape);
SDL_free(wmessage);
@@ -1023,7 +1024,7 @@ int WIN_ShowMessageBox(const SDL_MessageBoxData *messageboxdata, int *buttonID)
}
SDL_free(pButtons);
/* Check the Task Dialog was successful and give the result */
// Check the Task Dialog was successful and give the result
if (SUCCEEDED(hr)) {
if (nButton == IDCANCEL) {
*buttonID = nCancelButton;
@@ -1032,11 +1033,11 @@ int WIN_ShowMessageBox(const SDL_MessageBoxData *messageboxdata, int *buttonID)
} else {
*buttonID = -1;
}
return 0;
return true;
}
/* We failed showing the Task Dialog, use the old message box! */
// We failed showing the Task Dialog, use the old message box!
return WIN_ShowOldMessageBox(messageboxdata, buttonID);
}
#endif /* SDL_VIDEO_DRIVER_WINDOWS */
#endif // SDL_VIDEO_DRIVER_WINDOWS
@@ -22,6 +22,6 @@
#ifdef SDL_VIDEO_DRIVER_WINDOWS
extern int WIN_ShowMessageBox(const SDL_MessageBoxData *messageboxdata, int *buttonID);
extern bool WIN_ShowMessageBox(const SDL_MessageBoxData *messageboxdata, int *buttonID);
#endif /* SDL_VIDEO_DRIVER_WINDOWS */
#endif // SDL_VIDEO_DRIVER_WINDOWS
+210 -139
View File
@@ -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, &current_orientation)) {
dxgi_output = WIN_GetDXGIOutput(_this, info->szDevice);
bool found = WIN_GetDisplayMode(_this, dxgi_output, hMonitor, info->szDevice, ENUM_CURRENT_SETTINGS, &mode, &natural_orientation, &current_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
@@ -44,12 +44,12 @@ struct SDL_DisplayModeData
DEVMODE DeviceMode;
};
extern int WIN_InitModes(SDL_VideoDevice *_this);
extern int WIN_GetDisplayBounds(SDL_VideoDevice *_this, SDL_VideoDisplay *display, SDL_Rect *rect);
extern int WIN_GetDisplayUsableBounds(SDL_VideoDevice *_this, SDL_VideoDisplay *display, SDL_Rect *rect);
extern int WIN_GetDisplayModes(SDL_VideoDevice *_this, SDL_VideoDisplay *display);
extern int WIN_SetDisplayMode(SDL_VideoDevice *_this, SDL_VideoDisplay *display, SDL_DisplayMode *mode);
extern bool WIN_InitModes(SDL_VideoDevice *_this);
extern bool WIN_GetDisplayBounds(SDL_VideoDevice *_this, SDL_VideoDisplay *display, SDL_Rect *rect);
extern bool WIN_GetDisplayUsableBounds(SDL_VideoDevice *_this, SDL_VideoDisplay *display, SDL_Rect *rect);
extern bool WIN_GetDisplayModes(SDL_VideoDevice *_this, SDL_VideoDisplay *display);
extern bool WIN_SetDisplayMode(SDL_VideoDevice *_this, SDL_VideoDisplay *display, SDL_DisplayMode *mode);
extern void WIN_RefreshDisplays(SDL_VideoDevice *_this);
extern void WIN_QuitModes(SDL_VideoDevice *_this);
#endif /* SDL_windowsmodes_h_ */
#endif // SDL_windowsmodes_h_
+206 -94
View File
@@ -30,44 +30,75 @@
#include "../../events/SDL_mouse_c.h"
#include "../../joystick/usb_ids.h"
typedef struct CachedCursor
{
float scale;
HCURSOR cursor;
struct CachedCursor *next;
} CachedCursor;
struct SDL_CursorData
{
SDL_Surface *surface;
int hot_x;
int hot_y;
CachedCursor *cache;
HCURSOR cursor;
};
DWORD SDL_last_warp_time = 0;
HCURSOR SDL_cursor = NULL;
static SDL_Cursor *SDL_blank_cursor = NULL;
static SDL_Cursor *WIN_CreateDefaultCursor()
static SDL_Cursor *WIN_CreateCursorAndData(HCURSOR hcursor)
{
SDL_Cursor *cursor = (SDL_Cursor *)SDL_calloc(1, sizeof(*cursor));
if (cursor) {
cursor->driverdata = LoadCursor(NULL, IDC_ARROW);
if (!hcursor) {
return NULL;
}
SDL_Cursor *cursor = (SDL_Cursor *)SDL_calloc(1, sizeof(*cursor));
if (cursor) {
SDL_CursorData *data = (SDL_CursorData *)SDL_calloc(1, sizeof(*data));
if (!data) {
SDL_free(cursor);
return NULL;
}
data->cursor = hcursor;
cursor->internal = data;
}
return cursor;
}
static SDL_bool IsMonochromeSurface(SDL_Surface *surface)
static SDL_Cursor *WIN_CreateDefaultCursor(void)
{
return WIN_CreateCursorAndData(LoadCursor(NULL, IDC_ARROW));
}
static bool IsMonochromeSurface(SDL_Surface *surface)
{
int x, y;
Uint8 r, g, b, a;
SDL_assert(surface->format->format == SDL_PIXELFORMAT_ARGB8888);
SDL_assert(surface->format == SDL_PIXELFORMAT_ARGB8888);
for (y = 0; y < surface->h; y++) {
for (x = 0; x < surface->w; x++) {
SDL_ReadSurfacePixel(surface, x, y, &r, &g, &b, &a);
/* Black or white pixel. */
// Black or white pixel.
if (!((r == 0x00 && g == 0x00 && b == 0x00) || (r == 0xff && g == 0xff && b == 0xff))) {
return SDL_FALSE;
return false;
}
/* Transparent or opaque pixel. */
// Transparent or opaque pixel.
if (!(a == 0x00 || a == 0xff)) {
return SDL_FALSE;
return false;
}
}
}
return SDL_TRUE;
return true;
}
static HBITMAP CreateColorBitmap(SDL_Surface *surface)
@@ -76,12 +107,12 @@ static HBITMAP CreateColorBitmap(SDL_Surface *surface)
BITMAPINFO bi;
void *pixels;
SDL_assert(surface->format->format == SDL_PIXELFORMAT_ARGB8888);
SDL_assert(surface->format == SDL_PIXELFORMAT_ARGB8888);
SDL_zero(bi);
bi.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
bi.bmiHeader.biWidth = surface->w;
bi.bmiHeader.biHeight = -surface->h; /* Invert height to make the top-down DIB. */
bi.bmiHeader.biHeight = -surface->h; // Invert height to make the top-down DIB.
bi.bmiHeader.biPlanes = 1;
bi.bmiHeader.biBitCount = 32;
bi.bmiHeader.biCompression = BI_RGB;
@@ -102,10 +133,10 @@ static HBITMAP CreateColorBitmap(SDL_Surface *surface)
* For info on the expected mask format see:
* https://devblogs.microsoft.com/oldnewthing/20101018-00/?p=12513
*/
static HBITMAP CreateMaskBitmap(SDL_Surface *surface, SDL_bool is_monochrome)
static HBITMAP CreateMaskBitmap(SDL_Surface *surface, bool is_monochrome)
{
HBITMAP bitmap;
SDL_bool isstack;
bool isstack;
void *pixels;
int x, y;
Uint8 r, g, b, a;
@@ -114,7 +145,7 @@ static HBITMAP CreateMaskBitmap(SDL_Surface *surface, SDL_bool is_monochrome)
const int size = pitch * surface->h;
static const unsigned char masks[] = { 0x80, 0x40, 0x20, 0x10, 0x8, 0x4, 0x2, 0x1 };
SDL_assert(surface->format->format == SDL_PIXELFORMAT_ARGB8888);
SDL_assert(surface->format == SDL_PIXELFORMAT_ARGB8888);
pixels = SDL_small_alloc(Uint8, size * (is_monochrome ? 2 : 1), &isstack);
if (!pixels) {
@@ -123,7 +154,7 @@ static HBITMAP CreateMaskBitmap(SDL_Surface *surface, SDL_bool is_monochrome)
dst = (Uint8 *)pixels;
/* Make the mask completely transparent. */
// Make the mask completely transparent.
SDL_memset(dst, 0xff, size);
if (is_monochrome) {
SDL_memset(dst + size, 0x00, size);
@@ -134,12 +165,12 @@ static HBITMAP CreateMaskBitmap(SDL_Surface *surface, SDL_bool is_monochrome)
SDL_ReadSurfacePixel(surface, x, y, &r, &g, &b, &a);
if (a != 0) {
/* Reset bit of an opaque pixel. */
// Reset bit of an opaque pixel.
dst[x >> 3] &= ~masks[x & 7];
}
if (is_monochrome && !(r == 0x00 && g == 0x00 && b == 0x00)) {
/* Set bit of white or inverted pixel. */
// Set bit of white or inverted pixel.
dst[size + (x >> 3)] |= masks[x & 7];
}
}
@@ -155,12 +186,11 @@ static HBITMAP CreateMaskBitmap(SDL_Surface *surface, SDL_bool is_monochrome)
return bitmap;
}
static SDL_Cursor *WIN_CreateCursor(SDL_Surface *surface, int hot_x, int hot_y)
static HCURSOR WIN_CreateHCursor(SDL_Surface *surface, int hot_x, int hot_y)
{
HCURSOR hcursor;
SDL_Cursor *cursor;
ICONINFO ii;
SDL_bool is_monochrome = IsMonochromeSurface(surface);
bool is_monochrome = IsMonochromeSurface(surface);
SDL_zero(ii);
ii.fIcon = FALSE;
@@ -170,6 +200,7 @@ static SDL_Cursor *WIN_CreateCursor(SDL_Surface *surface, int hot_x, int hot_y)
ii.hbmColor = is_monochrome ? NULL : CreateColorBitmap(surface);
if (!ii.hbmMask || (!is_monochrome && !ii.hbmColor)) {
SDL_SetError("Couldn't create cursor bitmaps");
return NULL;
}
@@ -184,18 +215,37 @@ static SDL_Cursor *WIN_CreateCursor(SDL_Surface *surface, int hot_x, int hot_y)
WIN_SetError("CreateIconIndirect()");
return NULL;
}
return hcursor;
}
cursor = (SDL_Cursor *)SDL_calloc(1, sizeof(*cursor));
if (cursor) {
cursor->driverdata = hcursor;
} else {
DestroyCursor(hcursor);
static SDL_Cursor *WIN_CreateCursor(SDL_Surface *surface, int hot_x, int hot_y)
{
if (!SDL_SurfaceHasAlternateImages(surface)) {
HCURSOR hcursor = WIN_CreateHCursor(surface, hot_x, hot_y);
if (!hcursor) {
return NULL;
}
return WIN_CreateCursorAndData(hcursor);
}
// Dynamically generate cursors at the appropriate DPI
SDL_Cursor *cursor = (SDL_Cursor *)SDL_calloc(1, sizeof(*cursor));
if (cursor) {
SDL_CursorData *data = (SDL_CursorData *)SDL_calloc(1, sizeof(*data));
if (!data) {
SDL_free(cursor);
return NULL;
}
data->hot_x = hot_x;
data->hot_y = hot_y;
data->surface = surface;
++surface->refcount;
cursor->internal = data;
}
return cursor;
}
static SDL_Cursor *WIN_CreateBlankCursor()
static SDL_Cursor *WIN_CreateBlankCursor(void)
{
SDL_Cursor *cursor = NULL;
SDL_Surface *surface = SDL_CreateSurface(32, 32, SDL_PIXELFORMAT_ARGB8888);
@@ -208,17 +258,16 @@ static SDL_Cursor *WIN_CreateBlankCursor()
static SDL_Cursor *WIN_CreateSystemCursor(SDL_SystemCursor id)
{
SDL_Cursor *cursor;
LPCTSTR name;
switch (id) {
default:
SDL_assert(0);
SDL_assert(!"Unknown system cursor ID");
return NULL;
case SDL_SYSTEM_CURSOR_ARROW:
case SDL_SYSTEM_CURSOR_DEFAULT:
name = IDC_ARROW;
break;
case SDL_SYSTEM_CURSOR_IBEAM:
case SDL_SYSTEM_CURSOR_TEXT:
name = IDC_IBEAM;
break;
case SDL_SYSTEM_CURSOR_WAIT:
@@ -227,101 +276,164 @@ static SDL_Cursor *WIN_CreateSystemCursor(SDL_SystemCursor id)
case SDL_SYSTEM_CURSOR_CROSSHAIR:
name = IDC_CROSS;
break;
case SDL_SYSTEM_CURSOR_WAITARROW:
case SDL_SYSTEM_CURSOR_PROGRESS:
name = IDC_WAIT;
break;
case SDL_SYSTEM_CURSOR_SIZENWSE:
case SDL_SYSTEM_CURSOR_NWSE_RESIZE:
name = IDC_SIZENWSE;
break;
case SDL_SYSTEM_CURSOR_SIZENESW:
case SDL_SYSTEM_CURSOR_NESW_RESIZE:
name = IDC_SIZENESW;
break;
case SDL_SYSTEM_CURSOR_SIZEWE:
case SDL_SYSTEM_CURSOR_EW_RESIZE:
name = IDC_SIZEWE;
break;
case SDL_SYSTEM_CURSOR_SIZENS:
case SDL_SYSTEM_CURSOR_NS_RESIZE:
name = IDC_SIZENS;
break;
case SDL_SYSTEM_CURSOR_SIZEALL:
case SDL_SYSTEM_CURSOR_MOVE:
name = IDC_SIZEALL;
break;
case SDL_SYSTEM_CURSOR_NO:
case SDL_SYSTEM_CURSOR_NOT_ALLOWED:
name = IDC_NO;
break;
case SDL_SYSTEM_CURSOR_HAND:
case SDL_SYSTEM_CURSOR_POINTER:
name = IDC_HAND;
break;
case SDL_SYSTEM_CURSOR_WINDOW_TOPLEFT:
case SDL_SYSTEM_CURSOR_NW_RESIZE:
name = IDC_SIZENWSE;
break;
case SDL_SYSTEM_CURSOR_WINDOW_TOP:
case SDL_SYSTEM_CURSOR_N_RESIZE:
name = IDC_SIZENS;
break;
case SDL_SYSTEM_CURSOR_WINDOW_TOPRIGHT:
case SDL_SYSTEM_CURSOR_NE_RESIZE:
name = IDC_SIZENESW;
break;
case SDL_SYSTEM_CURSOR_WINDOW_RIGHT:
case SDL_SYSTEM_CURSOR_E_RESIZE:
name = IDC_SIZEWE;
break;
case SDL_SYSTEM_CURSOR_WINDOW_BOTTOMRIGHT:
case SDL_SYSTEM_CURSOR_SE_RESIZE:
name = IDC_SIZENWSE;
break;
case SDL_SYSTEM_CURSOR_WINDOW_BOTTOM:
case SDL_SYSTEM_CURSOR_S_RESIZE:
name = IDC_SIZENS;
break;
case SDL_SYSTEM_CURSOR_WINDOW_BOTTOMLEFT:
case SDL_SYSTEM_CURSOR_SW_RESIZE:
name = IDC_SIZENESW;
break;
case SDL_SYSTEM_CURSOR_WINDOW_LEFT:
case SDL_SYSTEM_CURSOR_W_RESIZE:
name = IDC_SIZEWE;
break;
}
cursor = (SDL_Cursor *)SDL_calloc(1, sizeof(*cursor));
if (cursor) {
HCURSOR hcursor;
hcursor = LoadCursor(NULL, name);
cursor->driverdata = hcursor;
}
return cursor;
return WIN_CreateCursorAndData(LoadCursor(NULL, name));
}
static void WIN_FreeCursor(SDL_Cursor *cursor)
{
HCURSOR hcursor = (HCURSOR)cursor->driverdata;
SDL_CursorData *data = cursor->internal;
DestroyCursor(hcursor);
if (data->surface) {
SDL_DestroySurface(data->surface);
}
while (data->cache) {
CachedCursor *entry = data->cache;
data->cache = entry->next;
DestroyCursor(entry->cursor);
SDL_free(entry);
}
if (data->cursor) {
DestroyCursor(data->cursor);
}
SDL_free(data);
SDL_free(cursor);
}
static int WIN_ShowCursor(SDL_Cursor *cursor)
static HCURSOR GetCachedCursor(SDL_Cursor *cursor)
{
SDL_CursorData *data = cursor->internal;
SDL_Window *focus = SDL_GetMouseFocus();
if (!focus) {
return NULL;
}
float scale = SDL_GetDisplayContentScale(SDL_GetDisplayForWindow(focus));
for (CachedCursor *entry = data->cache; entry; entry = entry->next) {
if (scale == entry->scale) {
return entry->cursor;
}
}
// Need to create a cursor for this content scale
SDL_Surface *surface = NULL;
HCURSOR hcursor = NULL;
CachedCursor *entry = NULL;
surface = SDL_GetSurfaceImage(data->surface, scale);
if (!surface) {
goto error;
}
int hot_x = (int)SDL_round(data->hot_x * scale);
int hot_y = (int)SDL_round(data->hot_x * scale);
hcursor = WIN_CreateHCursor(surface, hot_x, hot_y);
if (!hcursor) {
goto error;
}
entry = (CachedCursor *)SDL_malloc(sizeof(*entry));
if (!entry) {
goto error;
}
entry->cursor = hcursor;
entry->scale = scale;
entry->next = data->cache;
data->cache = entry;
SDL_DestroySurface(surface);
return hcursor;
error:
if (surface) {
SDL_DestroySurface(surface);
}
if (hcursor) {
DestroyCursor(hcursor);
}
SDL_free(entry);
return NULL;
}
static bool WIN_ShowCursor(SDL_Cursor *cursor)
{
if (!cursor) {
cursor = SDL_blank_cursor;
}
if (cursor) {
SDL_cursor = (HCURSOR)cursor->driverdata;
if (cursor->internal->surface) {
SDL_cursor = GetCachedCursor(cursor);
} else {
SDL_cursor = cursor->internal->cursor;
}
} else {
SDL_cursor = NULL;
}
if (SDL_GetMouseFocus() != NULL) {
SetCursor(SDL_cursor);
}
return 0;
return true;
}
void WIN_SetCursorPos(int x, int y)
{
/* We need to jitter the value because otherwise Windows will occasionally inexplicably ignore the SetCursorPos() or SendInput() */
// We need to jitter the value because otherwise Windows will occasionally inexplicably ignore the SetCursorPos() or SendInput()
SetCursorPos(x, y);
SetCursorPos(x + 1, y);
SetCursorPos(x, y);
/* Flush any mouse motion prior to or associated with this warp */
#ifdef _MSC_VER /* We explicitly want to use GetTickCount(), not GetTickCount64() */
// Flush any mouse motion prior to or associated with this warp
#ifdef _MSC_VER // We explicitly want to use GetTickCount(), not GetTickCount64()
#pragma warning(push)
#pragma warning(disable : 28159)
#endif
@@ -334,15 +446,15 @@ void WIN_SetCursorPos(int x, int y)
#endif
}
static int WIN_WarpMouse(SDL_Window *window, float x, float y)
static bool WIN_WarpMouse(SDL_Window *window, float x, float y)
{
SDL_WindowData *data = window->driverdata;
SDL_WindowData *data = window->internal;
HWND hwnd = data->hwnd;
POINT pt;
/* Don't warp the mouse while we're doing a modal interaction */
// Don't warp the mouse while we're doing a modal interaction
if (data->in_title_click || data->focus_click_pending) {
return 0;
return true;
}
pt.x = (int)SDL_roundf(x);
@@ -350,36 +462,36 @@ static int WIN_WarpMouse(SDL_Window *window, float x, float y)
ClientToScreen(hwnd, &pt);
WIN_SetCursorPos(pt.x, pt.y);
/* Send the exact mouse motion associated with this warp */
SDL_SendMouseMotion(0, window, SDL_GLOBAL_MOUSE_ID, SDL_FALSE, x, y);
return 0;
// Send the exact mouse motion associated with this warp
SDL_SendMouseMotion(0, window, SDL_GLOBAL_MOUSE_ID, false, x, y);
return true;
}
static int WIN_WarpMouseGlobal(float x, float y)
static bool WIN_WarpMouseGlobal(float x, float y)
{
POINT pt;
pt.x = (int)SDL_roundf(x);
pt.y = (int)SDL_roundf(y);
SetCursorPos(pt.x, pt.y);
return 0;
return true;
}
static int WIN_SetRelativeMouseMode(SDL_bool enabled)
static bool WIN_SetRelativeMouseMode(bool enabled)
{
return WIN_SetRawMouseEnabled(SDL_GetVideoDevice(), enabled);
}
static int WIN_CaptureMouse(SDL_Window *window)
static bool WIN_CaptureMouse(SDL_Window *window)
{
if (window) {
SDL_WindowData *data = window->driverdata;
SDL_WindowData *data = window->internal;
SetCapture(data->hwnd);
} else {
SDL_Window *focus_window = SDL_GetMouseFocus();
if (focus_window) {
SDL_WindowData *data = focus_window->driverdata;
SDL_WindowData *data = focus_window->internal;
if (!data->mouse_tracked) {
SDL_SetMouseFocus(NULL);
}
@@ -387,26 +499,26 @@ static int WIN_CaptureMouse(SDL_Window *window)
ReleaseCapture();
}
return 0;
return true;
}
static Uint32 WIN_GetGlobalMouseState(float *x, float *y)
static SDL_MouseButtonFlags WIN_GetGlobalMouseState(float *x, float *y)
{
Uint32 retval = 0;
SDL_MouseButtonFlags result = 0;
POINT pt = { 0, 0 };
SDL_bool swapButtons = GetSystemMetrics(SM_SWAPBUTTON) != 0;
bool swapButtons = GetSystemMetrics(SM_SWAPBUTTON) != 0;
GetCursorPos(&pt);
*x = (float)pt.x;
*y = (float)pt.y;
retval |= GetAsyncKeyState(!swapButtons ? VK_LBUTTON : VK_RBUTTON) & 0x8000 ? SDL_BUTTON_LMASK : 0;
retval |= GetAsyncKeyState(!swapButtons ? VK_RBUTTON : VK_LBUTTON) & 0x8000 ? SDL_BUTTON_RMASK : 0;
retval |= GetAsyncKeyState(VK_MBUTTON) & 0x8000 ? SDL_BUTTON_MMASK : 0;
retval |= GetAsyncKeyState(VK_XBUTTON1) & 0x8000 ? SDL_BUTTON_X1MASK : 0;
retval |= GetAsyncKeyState(VK_XBUTTON2) & 0x8000 ? SDL_BUTTON_X2MASK : 0;
result |= GetAsyncKeyState(!swapButtons ? VK_LBUTTON : VK_RBUTTON) & 0x8000 ? SDL_BUTTON_LMASK : 0;
result |= GetAsyncKeyState(!swapButtons ? VK_RBUTTON : VK_LBUTTON) & 0x8000 ? SDL_BUTTON_RMASK : 0;
result |= GetAsyncKeyState(VK_MBUTTON) & 0x8000 ? SDL_BUTTON_MMASK : 0;
result |= GetAsyncKeyState(VK_XBUTTON1) & 0x8000 ? SDL_BUTTON_X1MASK : 0;
result |= GetAsyncKeyState(VK_XBUTTON2) & 0x8000 ? SDL_BUTTON_X2MASK : 0;
return retval;
return result;
}
void WIN_InitMouse(SDL_VideoDevice *_this)
@@ -442,7 +554,7 @@ void WIN_QuitMouse(SDL_VideoDevice *_this)
* https://superuser.com/questions/278362/windows-mouse-acceleration-curve-smoothmousexcurve-and-smoothmouseycurve
* http://www.esreality.com/?a=post&id=1846538/
*/
static SDL_bool LoadFiveFixedPointFloats(const BYTE *bytes, float *values)
static bool LoadFiveFixedPointFloats(const BYTE *bytes, float *values)
{
int i;
@@ -452,7 +564,7 @@ static SDL_bool LoadFiveFixedPointFloats(const BYTE *bytes, float *values)
*values++ = value;
bytes += 8;
}
return SDL_TRUE;
return true;
}
static void WIN_SetEnhancedMouseScale(int mouse_speed)
@@ -522,7 +634,7 @@ static void WIN_SetLinearMouseScale(int mouse_speed)
}
}
void WIN_UpdateMouseSystemScale()
void WIN_UpdateMouseSystemScale(void)
{
int mouse_speed;
int params[3] = { 0, 0, 0 };
@@ -537,4 +649,4 @@ void WIN_UpdateMouseSystemScale()
}
}
#endif /* SDL_VIDEO_DRIVER_WINDOWS */
#endif // SDL_VIDEO_DRIVER_WINDOWS
@@ -29,6 +29,6 @@ extern HCURSOR SDL_cursor;
extern void WIN_InitMouse(SDL_VideoDevice *_this);
extern void WIN_QuitMouse(SDL_VideoDevice *_this);
extern void WIN_SetCursorPos(int x, int y);
extern void WIN_UpdateMouseSystemScale();
extern void WIN_UpdateMouseSystemScale(void);
#endif /* SDL_windowsmouse_h_ */
#endif // SDL_windowsmouse_h_
+93 -92
View File
@@ -25,7 +25,7 @@
#include "SDL_windowsvideo.h"
#include "SDL_windowsopengles.h"
/* WGL implementation of SDL OpenGL support */
// WGL implementation of SDL OpenGL support
#ifdef SDL_VIDEO_OPENGL_WGL
#include <SDL3/SDL_opengl.h>
@@ -105,32 +105,32 @@ typedef HGLRC(APIENTRYP PFNWGLCREATECONTEXTATTRIBSARBPROC)(HDC hDC,
#define SetPixelFormat _this->gl_data->wglSetPixelFormat
#endif
int WIN_GL_LoadLibrary(SDL_VideoDevice *_this, const char *path)
bool WIN_GL_LoadLibrary(SDL_VideoDevice *_this, const char *path)
{
void *handle;
if (path == NULL) {
path = SDL_getenv("SDL_OPENGL_LIBRARY");
path = SDL_GetHint(SDL_HINT_OPENGL_LIBRARY);
}
if (path == NULL) {
path = DEFAULT_OPENGL;
}
_this->gl_config.dll_handle = SDL_LoadObject(path);
if (!_this->gl_config.dll_handle) {
return -1;
return false;
}
SDL_strlcpy(_this->gl_config.driver_path, path,
SDL_arraysize(_this->gl_config.driver_path));
/* Allocate OpenGL memory */
// Allocate OpenGL memory
_this->gl_data = (struct SDL_GLDriverData *)SDL_calloc(1, sizeof(struct SDL_GLDriverData));
if (!_this->gl_data) {
return -1;
return false;
}
/* Load function pointers */
// Load function pointers
handle = _this->gl_config.dll_handle;
/* *INDENT-OFF* */ /* clang-format off */
/* *INDENT-OFF* */ // clang-format off
_this->gl_data->wglGetProcAddress = (PROC (WINAPI *)(const char *))
SDL_LoadFunction(handle, "wglGetProcAddress");
_this->gl_data->wglCreateContext = (HGLRC (WINAPI *)(HDC))
@@ -141,7 +141,7 @@ int WIN_GL_LoadLibrary(SDL_VideoDevice *_this, const char *path)
SDL_LoadFunction(handle, "wglMakeCurrent");
_this->gl_data->wglShareLists = (BOOL (WINAPI *)(HGLRC, HGLRC))
SDL_LoadFunction(handle, "wglShareLists");
/* *INDENT-ON* */ /* clang-format on */
/* *INDENT-ON* */ // clang-format on
#if defined(SDL_PLATFORM_XBOXONE) || defined(SDL_PLATFORM_XBOXSERIES)
_this->gl_data->wglSwapBuffers = (BOOL(WINAPI *)(HDC))
@@ -209,17 +209,17 @@ int WIN_GL_LoadLibrary(SDL_VideoDevice *_this, const char *path)
WIN_GL_InitExtensions(_this);
--_this->gl_config.driver_loaded;
return 0;
return true;
}
SDL_FunctionPointer WIN_GL_GetProcAddress(SDL_VideoDevice *_this, const char *proc)
{
SDL_FunctionPointer func;
/* This is to pick up extensions */
// This is to pick up extensions
func = (SDL_FunctionPointer)_this->gl_data->wglGetProcAddress(proc);
if (!func) {
/* This is probably a normal GL function */
// This is probably a normal GL function
func = (SDL_FunctionPointer)GetProcAddress((HMODULE)_this->gl_config.dll_handle, proc);
}
return func;
@@ -230,7 +230,7 @@ void WIN_GL_UnloadLibrary(SDL_VideoDevice *_this)
SDL_UnloadObject(_this->gl_config.dll_handle);
_this->gl_config.dll_handle = NULL;
/* Free OpenGL memory */
// Free OpenGL memory
SDL_free(_this->gl_data);
_this->gl_data = NULL;
}
@@ -272,7 +272,7 @@ static void WIN_GL_SetupPixelFormat(SDL_VideoDevice *_this, PIXELFORMATDESCRIPTO
/* Choose the closest pixel format that meets or exceeds the target.
FIXME: Should we weight any particular attribute over any other?
*/
static int WIN_GL_ChoosePixelFormat(SDL_VideoDevice *_this, HDC hdc, PIXELFORMATDESCRIPTOR *target)
static bool WIN_GL_ChoosePixelFormat(SDL_VideoDevice *_this, HDC hdc, PIXELFORMATDESCRIPTOR *target)
{
PIXELFORMATDESCRIPTOR pfd;
int count, index, best = 0;
@@ -369,19 +369,19 @@ static int WIN_GL_ChoosePixelFormat(SDL_VideoDevice *_this, HDC hdc, PIXELFORMAT
return best;
}
static SDL_bool HasExtension(const char *extension, const char *extensions)
static bool HasExtension(const char *extension, const char *extensions)
{
const char *start;
const char *where, *terminator;
/* Extension names should not have spaces. */
// Extension names should not have spaces.
where = SDL_strchr(extension, ' ');
if (where || *extension == '\0') {
return SDL_FALSE;
return false;
}
if (!extensions) {
return SDL_FALSE;
return false;
}
/* It takes a bit of care to be fool-proof about parsing the
@@ -399,20 +399,20 @@ static SDL_bool HasExtension(const char *extension, const char *extensions)
terminator = where + SDL_strlen(extension);
if (where == start || *(where - 1) == ' ') {
if (*terminator == ' ' || *terminator == '\0') {
return SDL_TRUE;
return true;
}
}
start = terminator;
}
return SDL_FALSE;
return false;
}
void WIN_GL_InitExtensions(SDL_VideoDevice *_this)
{
/* *INDENT-OFF* */ /* clang-format off */
/* *INDENT-OFF* */ // clang-format off
const char *(WINAPI * wglGetExtensionsStringARB)(HDC) = 0;
/* *INDENT-ON* */ /* clang-format on */
/* *INDENT-ON* */ // clang-format on
const char *extensions;
HWND hwnd;
HDC hdc;
@@ -443,36 +443,36 @@ void WIN_GL_InitExtensions(SDL_VideoDevice *_this)
}
_this->gl_data->wglMakeCurrent(hdc, hglrc);
/* *INDENT-OFF* */ /* clang-format off */
/* *INDENT-OFF* */ // clang-format off
wglGetExtensionsStringARB = (const char *(WINAPI *)(HDC))
_this->gl_data->wglGetProcAddress("wglGetExtensionsStringARB");
/* *INDENT-ON* */ /* clang-format on */
/* *INDENT-ON* */ // clang-format on
if (wglGetExtensionsStringARB) {
extensions = wglGetExtensionsStringARB(hdc);
} else {
extensions = NULL;
}
/* Check for WGL_ARB_pixel_format */
_this->gl_data->HAS_WGL_ARB_pixel_format = SDL_FALSE;
// Check for WGL_ARB_pixel_format
_this->gl_data->HAS_WGL_ARB_pixel_format = false;
if (HasExtension("WGL_ARB_pixel_format", extensions)) {
/* *INDENT-OFF* */ /* clang-format off */
/* *INDENT-OFF* */ // clang-format off
_this->gl_data->wglChoosePixelFormatARB =
(BOOL (WINAPI *)(HDC, const int *, const FLOAT *, UINT, int *, UINT *))
WIN_GL_GetProcAddress(_this, "wglChoosePixelFormatARB");
_this->gl_data->wglGetPixelFormatAttribivARB =
(BOOL (WINAPI *)(HDC, int, int, UINT, const int *, int *))
WIN_GL_GetProcAddress(_this, "wglGetPixelFormatAttribivARB");
/* *INDENT-ON* */ /* clang-format on */
/* *INDENT-ON* */ // clang-format on
if ((_this->gl_data->wglChoosePixelFormatARB != NULL) &&
(_this->gl_data->wglGetPixelFormatAttribivARB != NULL)) {
_this->gl_data->HAS_WGL_ARB_pixel_format = SDL_TRUE;
_this->gl_data->HAS_WGL_ARB_pixel_format = true;
}
}
/* Check for WGL_EXT_swap_control */
_this->gl_data->HAS_WGL_EXT_swap_control_tear = SDL_FALSE;
// Check for WGL_EXT_swap_control
_this->gl_data->HAS_WGL_EXT_swap_control_tear = false;
if (HasExtension("WGL_EXT_swap_control", extensions)) {
_this->gl_data->wglSwapIntervalEXT =
(BOOL (WINAPI *)(int))
@@ -481,33 +481,33 @@ void WIN_GL_InitExtensions(SDL_VideoDevice *_this)
(int (WINAPI *)(void))
WIN_GL_GetProcAddress(_this, "wglGetSwapIntervalEXT");
if (HasExtension("WGL_EXT_swap_control_tear", extensions)) {
_this->gl_data->HAS_WGL_EXT_swap_control_tear = SDL_TRUE;
_this->gl_data->HAS_WGL_EXT_swap_control_tear = true;
}
} else {
_this->gl_data->wglSwapIntervalEXT = NULL;
_this->gl_data->wglGetSwapIntervalEXT = NULL;
}
/* Check for WGL_EXT_create_context_es2_profile */
// Check for WGL_EXT_create_context_es2_profile
if (HasExtension("WGL_EXT_create_context_es2_profile", extensions)) {
SDL_GL_DeduceMaxSupportedESProfile(
&_this->gl_data->es_profile_max_supported_version.major,
&_this->gl_data->es_profile_max_supported_version.minor);
}
/* Check for WGL_ARB_context_flush_control */
// Check for WGL_ARB_context_flush_control
if (HasExtension("WGL_ARB_context_flush_control", extensions)) {
_this->gl_data->HAS_WGL_ARB_context_flush_control = SDL_TRUE;
_this->gl_data->HAS_WGL_ARB_context_flush_control = true;
}
/* Check for WGL_ARB_create_context_robustness */
// Check for WGL_ARB_create_context_robustness
if (HasExtension("WGL_ARB_create_context_robustness", extensions)) {
_this->gl_data->HAS_WGL_ARB_create_context_robustness = SDL_TRUE;
_this->gl_data->HAS_WGL_ARB_create_context_robustness = true;
}
/* Check for WGL_ARB_create_context_no_error */
// Check for WGL_ARB_create_context_no_error
if (HasExtension("WGL_ARB_create_context_no_error", extensions)) {
_this->gl_data->HAS_WGL_ARB_create_context_no_error = SDL_TRUE;
_this->gl_data->HAS_WGL_ARB_create_context_no_error = true;
}
_this->gl_data->wglMakeCurrent(hdc, NULL);
@@ -549,7 +549,7 @@ static int WIN_GL_ChoosePixelFormatARB(SDL_VideoDevice *_this, int *iAttribs, fl
1, &pixel_format,
&matching);
/* Check whether we actually got an SRGB capable buffer */
// Check whether we actually got an SRGB capable buffer
_this->gl_data->wglGetPixelFormatAttribivARB(hdc, pixel_format, 0, 1, &qAttrib, &srgb);
_this->gl_config.framebuffer_srgb_capable = srgb;
}
@@ -564,10 +564,10 @@ static int WIN_GL_ChoosePixelFormatARB(SDL_VideoDevice *_this, int *iAttribs, fl
return pixel_format;
}
/* actual work of WIN_GL_SetupWindow() happens here. */
static int WIN_GL_SetupWindowInternal(SDL_VideoDevice *_this, SDL_Window *window)
// actual work of WIN_GL_SetupWindow() happens here.
static bool WIN_GL_SetupWindowInternal(SDL_VideoDevice *_this, SDL_Window *window)
{
HDC hdc = window->driverdata->hdc;
HDC hdc = window->internal->hdc;
PIXELFORMATDESCRIPTOR pfd;
int pixel_format = 0;
int iAttribs[64];
@@ -577,7 +577,7 @@ static int WIN_GL_SetupWindowInternal(SDL_VideoDevice *_this, SDL_Window *window
WIN_GL_SetupPixelFormat(_this, &pfd);
/* setup WGL_ARB_pixel_format attribs */
// setup WGL_ARB_pixel_format attribs
iAttr = &iAttribs[0];
*iAttr++ = WGL_DRAW_TO_WINDOW_ARB;
@@ -641,6 +641,7 @@ static int WIN_GL_SetupWindowInternal(SDL_VideoDevice *_this, SDL_Window *window
}
if (_this->gl_config.floatbuffers) {
*iAttr++ = WGL_PIXEL_TYPE_ARB;
*iAttr++ = WGL_TYPE_RGBA_FLOAT_ARB;
}
@@ -663,14 +664,14 @@ static int WIN_GL_SetupWindowInternal(SDL_VideoDevice *_this, SDL_Window *window
*iAttr = 0;
/* Choose and set the closest available pixel format */
// Choose and set the closest available pixel format
pixel_format = WIN_GL_ChoosePixelFormatARB(_this, iAttribs, fAttribs);
/* App said "don't care about accel" and FULL accel failed. Try NO. */
// App said "don't care about accel" and FULL accel failed. Try NO.
if ((!pixel_format) && (_this->gl_config.accelerated < 0)) {
*iAccelAttr = WGL_NO_ACCELERATION_ARB;
pixel_format = WIN_GL_ChoosePixelFormatARB(_this, iAttribs, fAttribs);
*iAccelAttr = WGL_FULL_ACCELERATION_ARB; /* if we try again. */
*iAccelAttr = WGL_FULL_ACCELERATION_ARB; // if we try again.
}
if (!pixel_format) {
pixel_format = WIN_GL_ChoosePixelFormat(_this, hdc, &pfd);
@@ -681,35 +682,35 @@ static int WIN_GL_SetupWindowInternal(SDL_VideoDevice *_this, SDL_Window *window
if (!SetPixelFormat(hdc, pixel_format, &pfd)) {
return WIN_SetError("SetPixelFormat()");
}
return 0;
return true;
}
int WIN_GL_SetupWindow(SDL_VideoDevice *_this, SDL_Window *window)
bool WIN_GL_SetupWindow(SDL_VideoDevice *_this, SDL_Window *window)
{
/* The current context is lost in here; save it and reset it. */
// The current context is lost in here; save it and reset it.
SDL_Window *current_win = SDL_GL_GetCurrentWindow();
SDL_GLContext current_ctx = SDL_GL_GetCurrentContext();
const int retval = WIN_GL_SetupWindowInternal(_this, window);
const int result = WIN_GL_SetupWindowInternal(_this, window);
WIN_GL_MakeCurrent(_this, current_win, current_ctx);
return retval;
return result;
}
SDL_bool WIN_GL_UseEGL(SDL_VideoDevice *_this)
bool WIN_GL_UseEGL(SDL_VideoDevice *_this)
{
SDL_assert(_this->gl_data != NULL);
SDL_assert(_this->gl_config.profile_mask == SDL_GL_CONTEXT_PROFILE_ES);
return SDL_GetHintBoolean(SDL_HINT_OPENGL_ES_DRIVER, SDL_FALSE) || _this->gl_config.major_version == 1 || _this->gl_config.major_version > _this->gl_data->es_profile_max_supported_version.major || (_this->gl_config.major_version == _this->gl_data->es_profile_max_supported_version.major && _this->gl_config.minor_version > _this->gl_data->es_profile_max_supported_version.minor); /* No WGL extension for OpenGL ES 1.x profiles. */
return SDL_GetHintBoolean(SDL_HINT_OPENGL_ES_DRIVER, false) || _this->gl_config.major_version == 1 || _this->gl_config.major_version > _this->gl_data->es_profile_max_supported_version.major || (_this->gl_config.major_version == _this->gl_data->es_profile_max_supported_version.major && _this->gl_config.minor_version > _this->gl_data->es_profile_max_supported_version.minor); // No WGL extension for OpenGL ES 1.x profiles.
}
SDL_GLContext WIN_GL_CreateContext(SDL_VideoDevice *_this, SDL_Window *window)
{
HDC hdc = window->driverdata->hdc;
HDC hdc = window->internal->hdc;
HGLRC context, share_context;
if (_this->gl_config.profile_mask == SDL_GL_CONTEXT_PROFILE_ES && WIN_GL_UseEGL(_this)) {
#ifdef SDL_VIDEO_OPENGL_EGL
/* Switch to EGL based functions */
// Switch to EGL based functions
WIN_GL_UnloadLibrary(_this);
_this->GL_LoadLibrary = WIN_GLES_LoadLibrary;
_this->GL_GetProcAddress = WIN_GLES_GetProcAddress;
@@ -719,10 +720,10 @@ SDL_GLContext WIN_GL_CreateContext(SDL_VideoDevice *_this, SDL_Window *window)
_this->GL_SetSwapInterval = WIN_GLES_SetSwapInterval;
_this->GL_GetSwapInterval = WIN_GLES_GetSwapInterval;
_this->GL_SwapWindow = WIN_GLES_SwapWindow;
_this->GL_DeleteContext = WIN_GLES_DeleteContext;
_this->GL_DestroyContext = WIN_GLES_DestroyContext;
_this->GL_GetEGLSurface = WIN_GLES_GetEGLSurface;
if (WIN_GLES_LoadLibrary(_this, NULL) != 0) {
if (!WIN_GLES_LoadLibrary(_this, NULL)) {
return NULL;
}
@@ -742,7 +743,7 @@ SDL_GLContext WIN_GL_CreateContext(SDL_VideoDevice *_this, SDL_Window *window)
if (_this->gl_config.major_version < 3 &&
_this->gl_config.profile_mask == 0 &&
_this->gl_config.flags == 0) {
/* Create legacy context */
// Create legacy context
context = _this->gl_data->wglCreateContext(hdc);
if (share_context != 0) {
_this->gl_data->wglShareLists(share_context, context);
@@ -755,9 +756,9 @@ SDL_GLContext WIN_GL_CreateContext(SDL_VideoDevice *_this, SDL_Window *window)
return NULL;
}
/* Make the context current */
if (WIN_GL_MakeCurrent(_this, window, temp_context) < 0) {
WIN_GL_DeleteContext(_this, temp_context);
// Make the context current
if (!WIN_GL_MakeCurrent(_this, window, (SDL_GLContext)temp_context)) {
WIN_GL_DestroyContext(_this, (SDL_GLContext)temp_context);
return NULL;
}
@@ -767,7 +768,7 @@ SDL_GLContext WIN_GL_CreateContext(SDL_VideoDevice *_this, SDL_Window *window)
SDL_SetError("GL 3.x is not supported");
context = temp_context;
} else {
int attribs[15]; /* max 14 attributes plus terminator */
int attribs[15]; // max 14 attributes plus terminator
int iattr = 0;
attribs[iattr++] = WGL_CONTEXT_MAJOR_VERSION_ARB;
@@ -775,31 +776,31 @@ SDL_GLContext WIN_GL_CreateContext(SDL_VideoDevice *_this, SDL_Window *window)
attribs[iattr++] = WGL_CONTEXT_MINOR_VERSION_ARB;
attribs[iattr++] = _this->gl_config.minor_version;
/* SDL profile bits match WGL profile bits */
// SDL profile bits match WGL profile bits
if (_this->gl_config.profile_mask != 0) {
attribs[iattr++] = WGL_CONTEXT_PROFILE_MASK_ARB;
attribs[iattr++] = _this->gl_config.profile_mask;
}
/* SDL flags match WGL flags */
// SDL flags match WGL flags
if (_this->gl_config.flags != 0) {
attribs[iattr++] = WGL_CONTEXT_FLAGS_ARB;
attribs[iattr++] = _this->gl_config.flags;
}
/* only set if wgl extension is available and not the default setting */
// only set if wgl extension is available and not the default setting
if ((_this->gl_data->HAS_WGL_ARB_context_flush_control) && (_this->gl_config.release_behavior == 0)) {
attribs[iattr++] = WGL_CONTEXT_RELEASE_BEHAVIOR_ARB;
attribs[iattr++] = _this->gl_config.release_behavior ? WGL_CONTEXT_RELEASE_BEHAVIOR_FLUSH_ARB : WGL_CONTEXT_RELEASE_BEHAVIOR_NONE_ARB;
}
/* only set if wgl extension is available and not the default setting */
// only set if wgl extension is available and not the default setting
if ((_this->gl_data->HAS_WGL_ARB_create_context_robustness) && (_this->gl_config.reset_notification != 0)) {
attribs[iattr++] = WGL_CONTEXT_RESET_NOTIFICATION_STRATEGY_ARB;
attribs[iattr++] = _this->gl_config.reset_notification ? WGL_LOSE_CONTEXT_ON_RESET_ARB : WGL_NO_RESET_NOTIFICATION_ARB;
}
/* only set if wgl extension is available and not the default setting */
// only set if wgl extension is available and not the default setting
if ((_this->gl_data->HAS_WGL_ARB_create_context_no_error) && (_this->gl_config.no_error != 0)) {
attribs[iattr++] = WGL_CONTEXT_OPENGL_NO_ERROR_ARB;
attribs[iattr++] = _this->gl_config.no_error;
@@ -807,9 +808,9 @@ SDL_GLContext WIN_GL_CreateContext(SDL_VideoDevice *_this, SDL_Window *window)
attribs[iattr++] = 0;
/* Create the GL 3.x context */
// Create the GL 3.x context
context = wglCreateContextAttribsARB(hdc, share_context, attribs);
/* Delete the GL 2.x context */
// Delete the GL 2.x context
_this->gl_data->wglDeleteContext(temp_context);
}
}
@@ -819,15 +820,15 @@ SDL_GLContext WIN_GL_CreateContext(SDL_VideoDevice *_this, SDL_Window *window)
return NULL;
}
if (WIN_GL_MakeCurrent(_this, window, context) < 0) {
WIN_GL_DeleteContext(_this, context);
if (!WIN_GL_MakeCurrent(_this, window, (SDL_GLContext)context)) {
WIN_GL_DestroyContext(_this, (SDL_GLContext)context);
return NULL;
}
return context;
return (SDL_GLContext)context;
}
int WIN_GL_MakeCurrent(SDL_VideoDevice *_this, SDL_Window *window, SDL_GLContext context)
bool WIN_GL_MakeCurrent(SDL_VideoDevice *_this, SDL_Window *window, SDL_GLContext context)
{
HDC hdc;
@@ -835,7 +836,7 @@ int WIN_GL_MakeCurrent(SDL_VideoDevice *_this, SDL_Window *window, SDL_GLContext
return SDL_SetError("OpenGL not initialized");
}
/* sanity check that higher level handled this. */
// sanity check that higher level handled this.
SDL_assert(window || (window == NULL && !context));
/* Some Windows drivers freak out if hdc is NULL, even when context is
@@ -846,60 +847,60 @@ int WIN_GL_MakeCurrent(SDL_VideoDevice *_this, SDL_Window *window, SDL_GLContext
window = SDL_GL_GetCurrentWindow();
if (!window) {
SDL_assert(SDL_GL_GetCurrentContext() == NULL);
return 0; /* already done. */
return true; // already done.
}
}
hdc = window->driverdata->hdc;
hdc = window->internal->hdc;
if (!_this->gl_data->wglMakeCurrent(hdc, (HGLRC)context)) {
return WIN_SetError("wglMakeCurrent()");
}
return 0;
return true;
}
int WIN_GL_SetSwapInterval(SDL_VideoDevice *_this, int interval)
bool WIN_GL_SetSwapInterval(SDL_VideoDevice *_this, int interval)
{
if ((interval < 0) && (!_this->gl_data->HAS_WGL_EXT_swap_control_tear)) {
return SDL_SetError("Negative swap interval unsupported in this GL");
} else if (_this->gl_data->wglSwapIntervalEXT) {
if (_this->gl_data->wglSwapIntervalEXT(interval) != TRUE) {
if (!_this->gl_data->wglSwapIntervalEXT(interval)) {
return WIN_SetError("wglSwapIntervalEXT()");
}
} else {
return SDL_Unsupported();
}
return 0;
return true;
}
int WIN_GL_GetSwapInterval(SDL_VideoDevice *_this, int *interval)
bool WIN_GL_GetSwapInterval(SDL_VideoDevice *_this, int *interval)
{
if (_this->gl_data->wglGetSwapIntervalEXT) {
*interval = _this->gl_data->wglGetSwapIntervalEXT();
return 0;
return true;
} else {
return -1;
return false;
}
}
int WIN_GL_SwapWindow(SDL_VideoDevice *_this, SDL_Window *window)
bool WIN_GL_SwapWindow(SDL_VideoDevice *_this, SDL_Window *window)
{
HDC hdc = window->driverdata->hdc;
HDC hdc = window->internal->hdc;
if (!SwapBuffers(hdc)) {
return WIN_SetError("SwapBuffers()");
}
return 0;
return true;
}
int WIN_GL_DeleteContext(SDL_VideoDevice *_this, SDL_GLContext context)
bool WIN_GL_DestroyContext(SDL_VideoDevice *_this, SDL_GLContext context)
{
if (!_this->gl_data) {
return 0;
return true;
}
_this->gl_data->wglDeleteContext((HGLRC)context);
return 0;
return true;
}
#endif /* SDL_VIDEO_OPENGL_WGL */
#endif // SDL_VIDEO_OPENGL_WGL
#endif /* SDL_VIDEO_DRIVER_WINDOWS */
#endif // SDL_VIDEO_DRIVER_WINDOWS
+18 -18
View File
@@ -59,11 +59,11 @@ typedef struct tagPIXELFORMATDESCRIPTOR
struct SDL_GLDriverData
{
SDL_bool HAS_WGL_ARB_pixel_format;
SDL_bool HAS_WGL_EXT_swap_control_tear;
SDL_bool HAS_WGL_ARB_context_flush_control;
SDL_bool HAS_WGL_ARB_create_context_robustness;
SDL_bool HAS_WGL_ARB_create_context_no_error;
bool HAS_WGL_ARB_pixel_format;
bool HAS_WGL_EXT_swap_control_tear;
bool HAS_WGL_ARB_context_flush_control;
bool HAS_WGL_ARB_create_context_robustness;
bool HAS_WGL_ARB_create_context_no_error;
/* Max version of OpenGL ES context that can be created if the
implementation supports WGL_EXT_create_context_es2_profile.
@@ -75,7 +75,7 @@ struct SDL_GLDriverData
int minor;
} es_profile_max_supported_version;
/* *INDENT-OFF* */ /* clang-format off */
/* *INDENT-OFF* */ // clang-format off
PROC (WINAPI *wglGetProcAddress)(const char *proc);
HGLRC (WINAPI *wglCreateContext)(HDC hdc);
BOOL (WINAPI *wglDeleteContext)(HGLRC hglrc);
@@ -98,22 +98,22 @@ struct SDL_GLDriverData
const PIXELFORMATDESCRIPTOR *ppfd);
int (WINAPI *wglGetPixelFormat)(HDC hdc);
#endif
/* *INDENT-ON* */ /* clang-format on */
/* *INDENT-ON* */ // clang-format on
};
/* OpenGL functions */
extern int WIN_GL_LoadLibrary(SDL_VideoDevice *_this, const char *path);
// OpenGL functions
extern bool WIN_GL_LoadLibrary(SDL_VideoDevice *_this, const char *path);
extern SDL_FunctionPointer WIN_GL_GetProcAddress(SDL_VideoDevice *_this, const char *proc);
extern void WIN_GL_UnloadLibrary(SDL_VideoDevice *_this);
extern SDL_bool WIN_GL_UseEGL(SDL_VideoDevice *_this);
extern int WIN_GL_SetupWindow(SDL_VideoDevice *_this, SDL_Window *window);
extern bool WIN_GL_UseEGL(SDL_VideoDevice *_this);
extern bool WIN_GL_SetupWindow(SDL_VideoDevice *_this, SDL_Window *window);
extern SDL_GLContext WIN_GL_CreateContext(SDL_VideoDevice *_this, SDL_Window *window);
extern int WIN_GL_MakeCurrent(SDL_VideoDevice *_this, SDL_Window *window,
extern bool WIN_GL_MakeCurrent(SDL_VideoDevice *_this, SDL_Window *window,
SDL_GLContext context);
extern int WIN_GL_SetSwapInterval(SDL_VideoDevice *_this, int interval);
extern int WIN_GL_GetSwapInterval(SDL_VideoDevice *_this, int *interval);
extern int WIN_GL_SwapWindow(SDL_VideoDevice *_this, SDL_Window *window);
extern int WIN_GL_DeleteContext(SDL_VideoDevice *_this, SDL_GLContext context);
extern bool WIN_GL_SetSwapInterval(SDL_VideoDevice *_this, int interval);
extern bool WIN_GL_GetSwapInterval(SDL_VideoDevice *_this, int *interval);
extern bool WIN_GL_SwapWindow(SDL_VideoDevice *_this, SDL_Window *window);
extern bool WIN_GL_DestroyContext(SDL_VideoDevice *_this, SDL_GLContext context);
extern void WIN_GL_InitExtensions(SDL_VideoDevice *_this);
#ifndef WGL_ARB_pixel_format
@@ -173,6 +173,6 @@ extern void WIN_GL_InitExtensions(SDL_VideoDevice *_this);
#define WGL_SAMPLES_ARB 0x2042
#endif
#endif /* SDL_VIDEO_OPENGL_WGL */
#endif // SDL_VIDEO_OPENGL_WGL
#endif /* SDL_windowsopengl_h_ */
#endif // SDL_windowsopengl_h_
@@ -27,14 +27,14 @@
#include "SDL_windowsopengl.h"
#include "SDL_windowswindow.h"
/* EGL implementation of SDL OpenGL support */
// EGL implementation of SDL OpenGL support
int WIN_GLES_LoadLibrary(SDL_VideoDevice *_this, const char *path)
bool WIN_GLES_LoadLibrary(SDL_VideoDevice *_this, const char *path)
{
/* If the profile requested is not GL ES, switch over to WIN_GL functions */
// If the profile requested is not GL ES, switch over to WIN_GL functions
if (_this->gl_config.profile_mask != SDL_GL_CONTEXT_PROFILE_ES &&
!SDL_GetHintBoolean(SDL_HINT_VIDEO_FORCE_EGL, SDL_FALSE)) {
!SDL_GetHintBoolean(SDL_HINT_VIDEO_FORCE_EGL, false)) {
#ifdef SDL_VIDEO_OPENGL_WGL
WIN_GLES_UnloadLibrary(_this);
_this->GL_LoadLibrary = WIN_GL_LoadLibrary;
@@ -45,7 +45,7 @@ int WIN_GLES_LoadLibrary(SDL_VideoDevice *_this, const char *path)
_this->GL_SetSwapInterval = WIN_GL_SetSwapInterval;
_this->GL_GetSwapInterval = WIN_GL_GetSwapInterval;
_this->GL_SwapWindow = WIN_GL_SwapWindow;
_this->GL_DeleteContext = WIN_GL_DeleteContext;
_this->GL_DestroyContext = WIN_GL_DestroyContext;
_this->GL_GetEGLSurface = NULL;
return WIN_GL_LoadLibrary(_this, path);
#else
@@ -57,18 +57,18 @@ int WIN_GLES_LoadLibrary(SDL_VideoDevice *_this, const char *path)
return SDL_EGL_LoadLibrary(_this, NULL, EGL_DEFAULT_DISPLAY, _this->gl_config.egl_platform);
}
return 0;
return true;
}
SDL_GLContext WIN_GLES_CreateContext(SDL_VideoDevice *_this, SDL_Window *window)
{
SDL_GLContext context;
SDL_WindowData *data = window->driverdata;
SDL_WindowData *data = window->internal;
#ifdef SDL_VIDEO_OPENGL_WGL
if (_this->gl_config.profile_mask != SDL_GL_CONTEXT_PROFILE_ES &&
!SDL_GetHintBoolean(SDL_HINT_VIDEO_FORCE_EGL, SDL_FALSE)) {
/* Switch to WGL based functions */
!SDL_GetHintBoolean(SDL_HINT_VIDEO_FORCE_EGL, false)) {
// Switch to WGL based functions
WIN_GLES_UnloadLibrary(_this);
_this->GL_LoadLibrary = WIN_GL_LoadLibrary;
_this->GL_GetProcAddress = WIN_GL_GetProcAddress;
@@ -78,10 +78,10 @@ SDL_GLContext WIN_GLES_CreateContext(SDL_VideoDevice *_this, SDL_Window *window)
_this->GL_SetSwapInterval = WIN_GL_SetSwapInterval;
_this->GL_GetSwapInterval = WIN_GL_GetSwapInterval;
_this->GL_SwapWindow = WIN_GL_SwapWindow;
_this->GL_DeleteContext = WIN_GL_DeleteContext;
_this->GL_DestroyContext = WIN_GL_DestroyContext;
_this->GL_GetEGLSurface = NULL;
if (WIN_GL_LoadLibrary(_this, NULL) != 0) {
if (!WIN_GL_LoadLibrary(_this, NULL)) {
return NULL;
}
@@ -93,37 +93,36 @@ SDL_GLContext WIN_GLES_CreateContext(SDL_VideoDevice *_this, SDL_Window *window)
return context;
}
int WIN_GLES_DeleteContext(SDL_VideoDevice *_this, SDL_GLContext context)
bool WIN_GLES_DestroyContext(SDL_VideoDevice *_this, SDL_GLContext context)
{
SDL_EGL_DeleteContext(_this, context);
return 0;
return SDL_EGL_DestroyContext(_this, context);
}
/* *INDENT-OFF* */ /* clang-format off */
/* *INDENT-OFF* */ // clang-format off
SDL_EGL_SwapWindow_impl(WIN)
SDL_EGL_MakeCurrent_impl(WIN)
/* *INDENT-ON* */ /* clang-format on */
/* *INDENT-ON* */ // clang-format on
int WIN_GLES_SetupWindow(SDL_VideoDevice *_this, SDL_Window *window)
bool WIN_GLES_SetupWindow(SDL_VideoDevice *_this, SDL_Window *window)
{
/* The current context is lost in here; save it and reset it. */
SDL_WindowData *windowdata = window->driverdata;
// The current context is lost in here; save it and reset it.
SDL_WindowData *windowdata = window->internal;
SDL_Window *current_win = SDL_GL_GetCurrentWindow();
SDL_GLContext current_ctx = SDL_GL_GetCurrentContext();
if (!_this->egl_data) {
/* !!! FIXME: commenting out this assertion is (I think) incorrect; figure out why driver_loaded is wrong for ANGLE instead. --ryan. */
#if 0 /* When hint SDL_HINT_OPENGL_ES_DRIVER is set to "1" (e.g. for ANGLE support), _this->gl_config.driver_loaded can be 1, while the below lines function. */
// !!! FIXME: commenting out this assertion is (I think) incorrect; figure out why driver_loaded is wrong for ANGLE instead. --ryan.
#if 0 // When hint SDL_HINT_OPENGL_ES_DRIVER is set to "1" (e.g. for ANGLE support), _this->gl_config.driver_loaded can be 1, while the below lines function.
SDL_assert(!_this->gl_config.driver_loaded);
#endif
if (SDL_EGL_LoadLibrary(_this, NULL, EGL_DEFAULT_DISPLAY, _this->gl_config.egl_platform) < 0) {
if (!SDL_EGL_LoadLibrary(_this, NULL, EGL_DEFAULT_DISPLAY, _this->gl_config.egl_platform)) {
SDL_EGL_UnloadLibrary(_this);
return -1;
return false;
}
_this->gl_config.driver_loaded = 1;
}
/* Create the GLES window surface */
// Create the GLES window surface
windowdata->egl_surface = SDL_EGL_CreateSurface(_this, window, (NativeWindowType)windowdata->hwnd);
if (windowdata->egl_surface == EGL_NO_SURFACE) {
@@ -133,12 +132,11 @@ int WIN_GLES_SetupWindow(SDL_VideoDevice *_this, SDL_Window *window)
return WIN_GLES_MakeCurrent(_this, current_win, current_ctx);
}
EGLSurface
WIN_GLES_GetEGLSurface(SDL_VideoDevice *_this, SDL_Window *window)
EGLSurface WIN_GLES_GetEGLSurface(SDL_VideoDevice *_this, SDL_Window *window)
{
SDL_WindowData *windowdata = window->driverdata;
SDL_WindowData *windowdata = window->internal;
return windowdata->egl_surface;
}
#endif /* SDL_VIDEO_DRIVER_WINDOWS && SDL_VIDEO_OPENGL_EGL */
#endif // SDL_VIDEO_DRIVER_WINDOWS && SDL_VIDEO_OPENGL_EGL
@@ -28,21 +28,21 @@
#include "../SDL_sysvideo.h"
#include "../SDL_egl_c.h"
/* OpenGLES functions */
// OpenGLES functions
#define WIN_GLES_GetAttribute SDL_EGL_GetAttribute
#define WIN_GLES_GetProcAddress SDL_EGL_GetProcAddressInternal
#define WIN_GLES_UnloadLibrary SDL_EGL_UnloadLibrary
#define WIN_GLES_GetSwapInterval SDL_EGL_GetSwapInterval
#define WIN_GLES_SetSwapInterval SDL_EGL_SetSwapInterval
extern int WIN_GLES_LoadLibrary(SDL_VideoDevice *_this, const char *path);
extern bool WIN_GLES_LoadLibrary(SDL_VideoDevice *_this, const char *path);
extern SDL_GLContext WIN_GLES_CreateContext(SDL_VideoDevice *_this, SDL_Window *window);
extern int WIN_GLES_SwapWindow(SDL_VideoDevice *_this, SDL_Window *window);
extern int WIN_GLES_MakeCurrent(SDL_VideoDevice *_this, SDL_Window *window, SDL_GLContext context);
extern int WIN_GLES_DeleteContext(SDL_VideoDevice *_this, SDL_GLContext context);
extern int WIN_GLES_SetupWindow(SDL_VideoDevice *_this, SDL_Window *window);
extern bool WIN_GLES_SwapWindow(SDL_VideoDevice *_this, SDL_Window *window);
extern bool WIN_GLES_MakeCurrent(SDL_VideoDevice *_this, SDL_Window *window, SDL_GLContext context);
extern bool WIN_GLES_DestroyContext(SDL_VideoDevice *_this, SDL_GLContext context);
extern bool WIN_GLES_SetupWindow(SDL_VideoDevice *_this, SDL_Window *window);
extern SDL_EGLSurface WIN_GLES_GetEGLSurface(SDL_VideoDevice *_this, SDL_Window *window);
#endif /* SDL_VIDEO_OPENGL_EGL */
#endif // SDL_VIDEO_OPENGL_EGL
#endif /* SDL_winopengles_h_ */
#endif // SDL_winopengles_h_
@@ -30,16 +30,21 @@
#include "../../joystick/usb_ids.h"
#define ENABLE_RAW_MOUSE_INPUT 0x01
#define ENABLE_RAW_KEYBOARD_INPUT 0x02
typedef struct
{
SDL_bool done;
bool done;
Uint32 flags;
HANDLE ready_event;
HANDLE done_event;
HANDLE thread;
} RawInputThreadData;
static RawInputThreadData thread_data = {
SDL_FALSE,
false,
0,
INVALID_HANDLE_VALUE,
INVALID_HANDLE_VALUE,
INVALID_HANDLE_VALUE
@@ -51,31 +56,40 @@ static DWORD WINAPI WIN_RawInputThread(LPVOID param)
RawInputThreadData *data = (RawInputThreadData *)param;
RAWINPUTDEVICE devices[2];
HWND window;
UINT count = 0;
window = CreateWindowEx(0, TEXT("Message"), NULL, 0, 0, 0, 0, 0, HWND_MESSAGE, NULL, NULL, NULL);
if (!window) {
return 0;
}
devices[0].usUsagePage = USB_USAGEPAGE_GENERIC_DESKTOP;
devices[0].usUsage = USB_USAGE_GENERIC_MOUSE;
devices[0].dwFlags = 0;
devices[0].hwndTarget = window;
SDL_zeroa(devices);
devices[1].usUsagePage = USB_USAGEPAGE_GENERIC_DESKTOP;
devices[1].usUsage = USB_USAGE_GENERIC_KEYBOARD;
devices[1].dwFlags = 0;
devices[1].hwndTarget = window;
if (data->flags & ENABLE_RAW_MOUSE_INPUT) {
devices[count].usUsagePage = USB_USAGEPAGE_GENERIC_DESKTOP;
devices[count].usUsage = USB_USAGE_GENERIC_MOUSE;
devices[count].dwFlags = 0;
devices[count].hwndTarget = window;
++count;
}
if (!RegisterRawInputDevices(devices, SDL_arraysize(devices), sizeof(devices[0]))) {
if (data->flags & ENABLE_RAW_KEYBOARD_INPUT) {
devices[count].usUsagePage = USB_USAGEPAGE_GENERIC_DESKTOP;
devices[count].usUsage = USB_USAGE_GENERIC_KEYBOARD;
devices[count].dwFlags = 0;
devices[count].hwndTarget = window;
++count;
}
if (!RegisterRawInputDevices(devices, count, sizeof(devices[0]))) {
DestroyWindow(window);
return 0;
}
/* Make sure we get events as soon as possible */
// Make sure we get events as soon as possible
SetThreadPriority(GetCurrentThread(), THREAD_PRIORITY_TIME_CRITICAL);
/* Tell the parent we're ready to go! */
// Tell the parent we're ready to go!
SetEvent(data->ready_event);
while (!data->done) {
@@ -83,7 +97,7 @@ static DWORD WINAPI WIN_RawInputThread(LPVOID param)
break;
}
/* Clear the queue status so MsgWaitForMultipleObjects() will wait again */
// Clear the queue status so MsgWaitForMultipleObjects() will wait again
(void)GetQueueStatus(QS_RAWINPUT);
WIN_PollRawInput(_this);
@@ -91,7 +105,7 @@ static DWORD WINAPI WIN_RawInputThread(LPVOID param)
devices[0].dwFlags |= RIDEV_REMOVE;
devices[1].dwFlags |= RIDEV_REMOVE;
RegisterRawInputDevices(devices, SDL_arraysize(devices), sizeof(devices[0]));
RegisterRawInputDevices(devices, count, sizeof(devices[0]));
DestroyWindow(window);
@@ -101,7 +115,7 @@ static DWORD WINAPI WIN_RawInputThread(LPVOID param)
static void CleanupRawInputThreadData(RawInputThreadData *data)
{
if (data->thread != INVALID_HANDLE_VALUE) {
data->done = SDL_TRUE;
data->done = true;
SetEvent(data->done_event);
WaitForSingleObject(data->thread, 3000);
CloseHandle(data->thread);
@@ -119,20 +133,23 @@ static void CleanupRawInputThreadData(RawInputThreadData *data)
}
}
static int WIN_SetRawInputEnabled(SDL_VideoDevice *_this, SDL_bool enabled)
static bool WIN_SetRawInputEnabled(SDL_VideoDevice *_this, Uint32 flags)
{
int result = -1;
bool result = false;
if (enabled) {
CleanupRawInputThreadData(&thread_data);
if (flags) {
HANDLE handles[2];
thread_data.flags = flags;
thread_data.ready_event = CreateEvent(NULL, FALSE, FALSE, NULL);
if (thread_data.ready_event == INVALID_HANDLE_VALUE) {
WIN_SetError("CreateEvent");
goto done;
}
thread_data.done = SDL_FALSE;
thread_data.done = false;
thread_data.done_event = CreateEvent(NULL, FALSE, FALSE, NULL);
if (thread_data.done_event == INVALID_HANDLE_VALUE) {
WIN_SetError("CreateEvent");
@@ -145,66 +162,93 @@ static int WIN_SetRawInputEnabled(SDL_VideoDevice *_this, SDL_bool enabled)
goto done;
}
/* Wait for the thread to signal ready or exit */
// Wait for the thread to signal ready or exit
handles[0] = thread_data.ready_event;
handles[1] = thread_data.thread;
if (WaitForMultipleObjects(2, handles, FALSE, INFINITE) != WAIT_OBJECT_0) {
SDL_SetError("Couldn't set up raw input handling");
goto done;
}
result = 0;
result = true;
} else {
CleanupRawInputThreadData(&thread_data);
result = 0;
result = true;
}
done:
if (enabled && result < 0) {
if (!result) {
CleanupRawInputThreadData(&thread_data);
}
return result;
}
static int WIN_UpdateRawInputEnabled(SDL_VideoDevice *_this)
static bool WIN_UpdateRawInputEnabled(SDL_VideoDevice *_this)
{
SDL_VideoData *data = _this->driverdata;
SDL_bool enabled = (data->raw_mouse_enabled || data->raw_keyboard_enabled);
if (enabled != data->raw_input_enabled) {
if (WIN_SetRawInputEnabled(_this, enabled) == 0) {
data->raw_input_enabled = enabled;
SDL_VideoData *data = _this->internal;
Uint32 flags = 0;
if (data->raw_mouse_enabled) {
flags |= ENABLE_RAW_MOUSE_INPUT;
}
if (data->raw_keyboard_enabled) {
flags |= ENABLE_RAW_KEYBOARD_INPUT;
}
if (flags != data->raw_input_enabled) {
if (WIN_SetRawInputEnabled(_this, flags)) {
data->raw_input_enabled = flags;
} else {
return -1;
return false;
}
}
return 0;
return true;
}
int WIN_SetRawMouseEnabled(SDL_VideoDevice *_this, SDL_bool enabled)
bool WIN_SetRawMouseEnabled(SDL_VideoDevice *_this, bool enabled)
{
SDL_VideoData *data = _this->driverdata;
SDL_VideoData *data = _this->internal;
data->raw_mouse_enabled = enabled;
return WIN_UpdateRawInputEnabled(_this);
if (data->gameinput_context) {
if (!WIN_UpdateGameInputEnabled(_this)) {
data->raw_mouse_enabled = !enabled;
return false;
}
} else {
if (!WIN_UpdateRawInputEnabled(_this)) {
data->raw_mouse_enabled = !enabled;
return false;
}
}
return true;
}
int WIN_SetRawKeyboardEnabled(SDL_VideoDevice *_this, SDL_bool enabled)
bool WIN_SetRawKeyboardEnabled(SDL_VideoDevice *_this, bool enabled)
{
SDL_VideoData *data = _this->driverdata;
SDL_VideoData *data = _this->internal;
data->raw_keyboard_enabled = enabled;
return WIN_UpdateRawInputEnabled(_this);
if (data->gameinput_context) {
if (!WIN_UpdateGameInputEnabled(_this)) {
data->raw_keyboard_enabled = !enabled;
return false;
}
} else {
if (!WIN_UpdateRawInputEnabled(_this)) {
data->raw_keyboard_enabled = !enabled;
return false;
}
}
return true;
}
#else
int WIN_SetRawMouseEnabled(SDL_VideoDevice *_this, SDL_bool enabled)
bool WIN_SetRawMouseEnabled(SDL_VideoDevice *_this, bool enabled)
{
return SDL_Unsupported();
}
int WIN_SetRawKeyboardEnabled(SDL_VideoDevice *_this, SDL_bool enabled)
bool WIN_SetRawKeyboardEnabled(SDL_VideoDevice *_this, bool enabled)
{
return SDL_Unsupported();
}
#endif /* !SDL_PLATFORM_XBOXONE && !SDL_PLATFORM_XBOXSERIES */
#endif // !SDL_PLATFORM_XBOXONE && !SDL_PLATFORM_XBOXSERIES
#endif /* SDL_VIDEO_DRIVER_WINDOWS */
#endif // SDL_VIDEO_DRIVER_WINDOWS
@@ -23,7 +23,7 @@
#ifndef SDL_windowsrawinput_h_
#define SDL_windowsrawinput_h_
extern int WIN_SetRawMouseEnabled(SDL_VideoDevice *_this, SDL_bool enabled);
extern int WIN_SetRawKeyboardEnabled(SDL_VideoDevice *_this, SDL_bool enabled);
extern bool WIN_SetRawMouseEnabled(SDL_VideoDevice *_this, bool enabled);
extern bool WIN_SetRawKeyboardEnabled(SDL_VideoDevice *_this, bool enabled);
#endif /* SDL_windowsrawinput_h_ */
#endif // SDL_windowsrawinput_h_
+14 -14
View File
@@ -59,7 +59,7 @@ static HRGN GenerateSpanListRegion(SDL_Surface *shape, int offset_x, int offset_
a += 4;
}
if (span_start != -1) {
/* Add the final span */
// Add the final span
AddRegion(&mask, offset_x + span_start, offset_y + y, offset_x + x, offset_y + y + 1);
span_start = -1;
}
@@ -67,12 +67,12 @@ static HRGN GenerateSpanListRegion(SDL_Surface *shape, int offset_x, int offset_
return mask;
}
int WIN_UpdateWindowShape(SDL_VideoDevice *_this, SDL_Window *window, SDL_Surface *shape)
bool WIN_UpdateWindowShape(SDL_VideoDevice *_this, SDL_Window *window, SDL_Surface *shape)
{
SDL_WindowData *data = window->driverdata;
SDL_WindowData *data = window->internal;
HRGN mask = NULL;
/* Generate a set of spans for the region */
// Generate a set of spans for the region
if (shape) {
SDL_Surface *stretched = NULL;
RECT rect;
@@ -80,11 +80,11 @@ int WIN_UpdateWindowShape(SDL_VideoDevice *_this, SDL_Window *window, SDL_Surfac
if (shape->w != window->w || shape->h != window->h) {
stretched = SDL_CreateSurface(window->w, window->h, SDL_PIXELFORMAT_ARGB32);
if (!stretched) {
return -1;
return false;
}
if (SDL_SoftStretch(shape, NULL, stretched, NULL, SDL_SCALEMODE_LINEAR) < 0) {
if (!SDL_SoftStretch(shape, NULL, stretched, NULL, SDL_SCALEMODE_LINEAR)) {
SDL_DestroySurface(stretched);
return -1;
return false;
}
shape = stretched;
}
@@ -100,14 +100,14 @@ int WIN_UpdateWindowShape(SDL_VideoDevice *_this, SDL_Window *window, SDL_Surfac
mask = GenerateSpanListRegion(shape, -rect.left, -rect.top);
if (!(SDL_GetWindowFlags(data->window) & SDL_WINDOW_BORDERLESS)) {
/* Add the window borders */
/* top */
// Add the window borders
// top
AddRegion(&mask, 0, 0, -rect.left + shape->w + rect.right + 1, -rect.top + 1);
/* left */
// left
AddRegion(&mask, 0, -rect.top, -rect.left + 1, -rect.top + shape->h + 1);
/* right */
// right
AddRegion(&mask, -rect.left + shape->w, -rect.top, -rect.left + shape->w + rect.right + 1, -rect.top + shape->h + 1);
/* bottom */
// bottom
AddRegion(&mask, 0, -rect.top + shape->h, -rect.left + shape->w + rect.right + 1, -rect.top + shape->h + rect.bottom + 1);
}
@@ -118,7 +118,7 @@ int WIN_UpdateWindowShape(SDL_VideoDevice *_this, SDL_Window *window, SDL_Surfac
if (!SetWindowRgn(data->hwnd, mask, TRUE)) {
return WIN_SetError("SetWindowRgn failed");
}
return 0;
return true;
}
#endif /* defined(SDL_VIDEO_DRIVER_WINDOWS) && !defined(SDL_PLATFORM_XBOXONE) && !defined(SDL_PLATFORM_XBOXSERIES) */
#endif // defined(SDL_VIDEO_DRIVER_WINDOWS) && !defined(SDL_PLATFORM_XBOXONE) && !defined(SDL_PLATFORM_XBOXSERIES)
@@ -23,6 +23,6 @@
#ifndef SDL_windowsshape_h_
#define SDL_windowsshape_h_
extern int WIN_UpdateWindowShape(SDL_VideoDevice *_this, SDL_Window *window, SDL_Surface *shape);
extern bool WIN_UpdateWindowShape(SDL_VideoDevice *_this, SDL_Window *window, SDL_Surface *shape);
#endif /* SDL_windowsshape_h_ */
#endif // SDL_windowsshape_h_
+160 -143
View File
@@ -40,48 +40,48 @@
#include "../gdk/SDL_gdktextinput.h"
#endif
/* #define HIGHDPI_DEBUG */
// #define HIGHDPI_DEBUG
/* Initialization/Query functions */
static int WIN_VideoInit(SDL_VideoDevice *_this);
// Initialization/Query functions
static bool WIN_VideoInit(SDL_VideoDevice *_this);
static void WIN_VideoQuit(SDL_VideoDevice *_this);
/* Hints */
SDL_bool g_WindowsEnableMessageLoop = SDL_TRUE;
SDL_bool g_WindowsEnableMenuMnemonics = SDL_FALSE;
SDL_bool g_WindowFrameUsableWhileCursorHidden = SDL_TRUE;
// Hints
bool g_WindowsEnableMessageLoop = true;
bool g_WindowsEnableMenuMnemonics = false;
bool g_WindowFrameUsableWhileCursorHidden = true;
static void SDLCALL UpdateWindowsRawKeyboard(void *userdata, const char *name, const char *oldValue, const char *newValue)
{
SDL_VideoDevice *_this = (SDL_VideoDevice *)userdata;
SDL_bool enabled = SDL_GetStringBoolean(newValue, SDL_TRUE);
bool enabled = SDL_GetStringBoolean(newValue, false);
WIN_SetRawKeyboardEnabled(_this, enabled);
}
static void SDLCALL UpdateWindowsEnableMessageLoop(void *userdata, const char *name, const char *oldValue, const char *newValue)
{
g_WindowsEnableMessageLoop = SDL_GetStringBoolean(newValue, SDL_TRUE);
g_WindowsEnableMessageLoop = SDL_GetStringBoolean(newValue, true);
}
static void SDLCALL UpdateWindowsEnableMenuMnemonics(void *userdata, const char *name, const char *oldValue, const char *newValue)
{
g_WindowsEnableMenuMnemonics = SDL_GetStringBoolean(newValue, SDL_FALSE);
g_WindowsEnableMenuMnemonics = SDL_GetStringBoolean(newValue, false);
}
static void SDLCALL UpdateWindowFrameUsableWhileCursorHidden(void *userdata, const char *name, const char *oldValue, const char *newValue)
{
g_WindowFrameUsableWhileCursorHidden = SDL_GetStringBoolean(newValue, SDL_TRUE);
g_WindowFrameUsableWhileCursorHidden = SDL_GetStringBoolean(newValue, true);
}
#if !defined(SDL_PLATFORM_XBOXONE) && !defined(SDL_PLATFORM_XBOXSERIES)
static int WIN_SuspendScreenSaver(SDL_VideoDevice *_this)
static bool WIN_SuspendScreenSaver(SDL_VideoDevice *_this)
{
if (_this->suspend_screensaver) {
SetThreadExecutionState(ES_CONTINUOUS | ES_DISPLAY_REQUIRED);
} else {
SetThreadExecutionState(ES_CONTINUOUS);
}
return 0;
return true;
}
#endif
@@ -89,11 +89,11 @@ static int WIN_SuspendScreenSaver(SDL_VideoDevice *_this)
extern void D3D12_XBOX_GetResolution(Uint32 *width, Uint32 *height);
#endif
/* Windows driver bootstrap functions */
// Windows driver bootstrap functions
static void WIN_DeleteDevice(SDL_VideoDevice *device)
{
SDL_VideoData *data = device->driverdata;
SDL_VideoData *data = device->internal;
SDL_UnregisterApp();
#if !defined(SDL_PLATFORM_XBOXONE) && !defined(SDL_PLATFORM_XBOXSERIES)
@@ -103,12 +103,20 @@ static void WIN_DeleteDevice(SDL_VideoDevice *device)
if (data->shcoreDLL) {
SDL_UnloadObject(data->shcoreDLL);
}
#endif
#ifdef HAVE_DXGI_H
if (data->pDXGIFactory) {
IDXGIFactory_Release(data->pDXGIFactory);
}
if (data->dxgiDLL) {
SDL_UnloadObject(data->dxgiDLL);
}
#endif
if (device->wakeup_lock) {
SDL_DestroyMutex(device->wakeup_lock);
}
SDL_free(device->driverdata->rawinput);
SDL_free(device->driverdata);
SDL_free(device->internal->rawinput);
SDL_free(device->internal);
SDL_free(device);
}
@@ -119,7 +127,7 @@ static SDL_VideoDevice *WIN_CreateDevice(void)
SDL_RegisterApp(NULL, 0, NULL);
/* Initialize all variables that we clean on shutdown */
// Initialize all variables that we clean on shutdown
device = (SDL_VideoDevice *)SDL_calloc(1, sizeof(SDL_VideoDevice));
if (device) {
data = (SDL_VideoData *)SDL_calloc(1, sizeof(SDL_VideoData));
@@ -130,14 +138,14 @@ static SDL_VideoDevice *WIN_CreateDevice(void)
SDL_free(device);
return NULL;
}
device->driverdata = data;
device->internal = data;
device->wakeup_lock = SDL_CreateMutex();
device->system_theme = WIN_GetSystemTheme();
#if !defined(SDL_PLATFORM_XBOXONE) && !defined(SDL_PLATFORM_XBOXSERIES)
data->userDLL = SDL_LoadObject("USER32.DLL");
if (data->userDLL) {
/* *INDENT-OFF* */ /* clang-format off */
/* *INDENT-OFF* */ // clang-format off
data->CloseTouchInputHandle = (BOOL (WINAPI *)(HTOUCHINPUT))SDL_LoadFunction(data->userDLL, "CloseTouchInputHandle");
data->GetTouchInputInfo = (BOOL (WINAPI *)(HTOUCHINPUT, UINT, PTOUCHINPUT, int)) SDL_LoadFunction(data->userDLL, "GetTouchInputInfo");
data->RegisterTouchWindow = (BOOL (WINAPI *)(HWND, ULONG))SDL_LoadFunction(data->userDLL, "RegisterTouchWindow");
@@ -151,23 +159,42 @@ 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");
/* *INDENT-ON* */ /* clang-format on */
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();
}
data->shcoreDLL = SDL_LoadObject("SHCORE.DLL");
if (data->shcoreDLL) {
/* *INDENT-OFF* */ /* clang-format off */
/* *INDENT-OFF* */ // clang-format off
data->GetDpiForMonitor = (HRESULT (WINAPI *)(HMONITOR, MONITOR_DPI_TYPE, UINT *, UINT *))SDL_LoadFunction(data->shcoreDLL, "GetDpiForMonitor");
data->SetProcessDpiAwareness = (HRESULT (WINAPI *)(PROCESS_DPI_AWARENESS))SDL_LoadFunction(data->shcoreDLL, "SetProcessDpiAwareness");
/* *INDENT-ON* */ /* clang-format on */
/* *INDENT-ON* */ // clang-format on
} else {
SDL_ClearError();
}
#endif /* #if !defined(SDL_PLATFORM_XBOXONE) && !defined(SDL_PLATFORM_XBOXSERIES) */
#endif // #if !defined(SDL_PLATFORM_XBOXONE) && !defined(SDL_PLATFORM_XBOXSERIES)
/* Set the function pointers */
#ifdef HAVE_DXGI_H
data->dxgiDLL = SDL_LoadObject("DXGI.DLL");
if (data->dxgiDLL) {
/* *INDENT-OFF* */ // clang-format off
typedef HRESULT (WINAPI *CreateDXGI_t)(REFIID riid, void **ppFactory);
/* *INDENT-ON* */ // clang-format on
CreateDXGI_t CreateDXGI;
CreateDXGI = (CreateDXGI_t)SDL_LoadFunction(data->dxgiDLL, "CreateDXGIFactory");
if (CreateDXGI) {
GUID dxgiGUID = { 0x7b7166ec, 0x21c7, 0x44ae, { 0xb2, 0x1a, 0xc9, 0xae, 0x32, 0x1a, 0xe3, 0x69 } };
CreateDXGI(&dxgiGUID, (void **)&data->pDXGIFactory);
}
}
#endif
// Set the function pointers
device->VideoInit = WIN_VideoInit;
device->VideoQuit = WIN_VideoQuit;
#if !defined(SDL_PLATFORM_XBOXONE) && !defined(SDL_PLATFORM_XBOXSERIES)
@@ -202,6 +229,8 @@ static SDL_VideoDevice *WIN_CreateDevice(void)
device->SetWindowResizable = WIN_SetWindowResizable;
device->SetWindowAlwaysOnTop = WIN_SetWindowAlwaysOnTop;
device->SetWindowFullscreen = WIN_SetWindowFullscreen;
device->SetWindowParent = WIN_SetWindowParent;
device->SetWindowModal = WIN_SetWindowModal;
#if !defined(SDL_PLATFORM_XBOXONE) && !defined(SDL_PLATFORM_XBOXSERIES)
device->GetWindowICCProfile = WIN_GetWindowICCProfile;
device->SetWindowMouseRect = WIN_SetWindowMouseRect;
@@ -231,14 +260,14 @@ static SDL_VideoDevice *WIN_CreateDevice(void)
device->GL_SetSwapInterval = WIN_GL_SetSwapInterval;
device->GL_GetSwapInterval = WIN_GL_GetSwapInterval;
device->GL_SwapWindow = WIN_GL_SwapWindow;
device->GL_DeleteContext = WIN_GL_DeleteContext;
device->GL_DestroyContext = WIN_GL_DestroyContext;
device->GL_GetEGLSurface = NULL;
#endif
#ifdef SDL_VIDEO_OPENGL_EGL
#ifdef SDL_VIDEO_OPENGL_WGL
if (SDL_GetHintBoolean(SDL_HINT_VIDEO_FORCE_EGL, SDL_FALSE)) {
if (SDL_GetHintBoolean(SDL_HINT_VIDEO_FORCE_EGL, false)) {
#endif
/* Use EGL based functions */
// Use EGL based functions
device->GL_LoadLibrary = WIN_GLES_LoadLibrary;
device->GL_GetProcAddress = WIN_GLES_GetProcAddress;
device->GL_UnloadLibrary = WIN_GLES_UnloadLibrary;
@@ -247,7 +276,7 @@ static SDL_VideoDevice *WIN_CreateDevice(void)
device->GL_SetSwapInterval = WIN_GLES_SetSwapInterval;
device->GL_GetSwapInterval = WIN_GLES_GetSwapInterval;
device->GL_SwapWindow = WIN_GLES_SwapWindow;
device->GL_DeleteContext = WIN_GLES_DeleteContext;
device->GL_DestroyContext = WIN_GLES_DestroyContext;
device->GL_GetEGLSurface = WIN_GLES_GetEGLSurface;
#ifdef SDL_VIDEO_OPENGL_WGL
}
@@ -258,12 +287,14 @@ static SDL_VideoDevice *WIN_CreateDevice(void)
device->Vulkan_UnloadLibrary = WIN_Vulkan_UnloadLibrary;
device->Vulkan_GetInstanceExtensions = WIN_Vulkan_GetInstanceExtensions;
device->Vulkan_CreateSurface = WIN_Vulkan_CreateSurface;
device->Vulkan_DestroySurface = WIN_Vulkan_DestroySurface;
device->Vulkan_GetPresentationSupport = WIN_Vulkan_GetPresentationSupport;
#endif
#if !defined(SDL_PLATFORM_XBOXONE) && !defined(SDL_PLATFORM_XBOXSERIES)
device->StartTextInput = WIN_StartTextInput;
device->StopTextInput = WIN_StopTextInput;
device->SetTextInputRect = WIN_SetTextInputRect;
device->UpdateTextInputArea = WIN_UpdateTextInputArea;
device->ClearComposition = WIN_ClearComposition;
device->SetClipboardData = WIN_SetClipboardData;
@@ -276,7 +307,7 @@ static SDL_VideoDevice *WIN_CreateDevice(void)
device->StartTextInput = GDK_StartTextInput;
device->StopTextInput = GDK_StopTextInput;
device->SetTextInputRect = GDK_SetTextInputRect;
device->UpdateTextInputArea = GDK_UpdateTextInputArea;
device->ClearComposition = GDK_ClearComposition;
device->HasScreenKeyboardSupport = GDK_HasScreenKeyboardSupport;
@@ -305,12 +336,12 @@ VideoBootStrap WINDOWS_bootstrap = {
static BOOL WIN_DeclareDPIAwareUnaware(SDL_VideoDevice *_this)
{
#if !defined(SDL_PLATFORM_XBOXONE) && !defined(SDL_PLATFORM_XBOXSERIES)
SDL_VideoData *data = _this->driverdata;
SDL_VideoData *data = _this->internal;
if (data->SetProcessDpiAwarenessContext) {
return data->SetProcessDpiAwarenessContext(DPI_AWARENESS_CONTEXT_UNAWARE);
} else if (data->SetProcessDpiAwareness) {
/* Windows 8.1 */
// Windows 8.1
return SUCCEEDED(data->SetProcessDpiAwareness(PROCESS_DPI_UNAWARE));
}
#endif
@@ -320,16 +351,16 @@ static BOOL WIN_DeclareDPIAwareUnaware(SDL_VideoDevice *_this)
static BOOL WIN_DeclareDPIAwareSystem(SDL_VideoDevice *_this)
{
#if !defined(SDL_PLATFORM_XBOXONE) && !defined(SDL_PLATFORM_XBOXSERIES)
SDL_VideoData *data = _this->driverdata;
SDL_VideoData *data = _this->internal;
if (data->SetProcessDpiAwarenessContext) {
/* Windows 10, version 1607 */
// Windows 10, version 1607
return data->SetProcessDpiAwarenessContext(DPI_AWARENESS_CONTEXT_SYSTEM_AWARE);
} else if (data->SetProcessDpiAwareness) {
/* Windows 8.1 */
// Windows 8.1
return SUCCEEDED(data->SetProcessDpiAwareness(PROCESS_SYSTEM_DPI_AWARE));
} else if (data->SetProcessDPIAware) {
/* Windows Vista */
// Windows Vista
return data->SetProcessDPIAware();
}
#endif
@@ -339,16 +370,16 @@ static BOOL WIN_DeclareDPIAwareSystem(SDL_VideoDevice *_this)
static BOOL WIN_DeclareDPIAwarePerMonitor(SDL_VideoDevice *_this)
{
#if !defined(SDL_PLATFORM_XBOXONE) && !defined(SDL_PLATFORM_XBOXSERIES)
SDL_VideoData *data = _this->driverdata;
SDL_VideoData *data = _this->internal;
if (data->SetProcessDpiAwarenessContext) {
/* Windows 10, version 1607 */
// Windows 10, version 1607
return data->SetProcessDpiAwarenessContext(DPI_AWARENESS_CONTEXT_PER_MONITOR_AWARE);
} else if (data->SetProcessDpiAwareness) {
/* Windows 8.1 */
// Windows 8.1
return SUCCEEDED(data->SetProcessDpiAwareness(PROCESS_PER_MONITOR_DPI_AWARE));
} else {
/* Older OS: fall back to system DPI aware */
// Older OS: fall back to system DPI aware
return WIN_DeclareDPIAwareSystem(_this);
}
#else
@@ -361,11 +392,11 @@ static BOOL WIN_DeclareDPIAwarePerMonitorV2(SDL_VideoDevice *_this)
#if defined(SDL_PLATFORM_XBOXONE) || defined(SDL_PLATFORM_XBOXSERIES)
return FALSE;
#else
SDL_VideoData *data = _this->driverdata;
SDL_VideoData *data = _this->internal;
/* Declare DPI aware (may have been done in external code or a manifest, as well) */
// Declare DPI aware (may have been done in external code or a manifest, as well)
if (data->SetProcessDpiAwarenessContext) {
/* Windows 10, version 1607 */
// Windows 10, version 1607
/* NOTE: SetThreadDpiAwarenessContext doesn't work here with OpenGL - the OpenGL contents
end up still getting OS scaled. (tested on Windows 10 21H1 19043.1348, NVIDIA 496.49)
@@ -388,7 +419,7 @@ static BOOL WIN_DeclareDPIAwarePerMonitorV2(SDL_VideoDevice *_this)
return WIN_DeclareDPIAwarePerMonitor(_this);
}
} else {
/* Older OS: fall back to per-monitor (or system) */
// Older OS: fall back to per-monitor (or system)
return WIN_DeclareDPIAwarePerMonitor(_this);
}
#endif
@@ -397,7 +428,7 @@ static BOOL WIN_DeclareDPIAwarePerMonitorV2(SDL_VideoDevice *_this)
#ifdef HIGHDPI_DEBUG
static const char *WIN_GetDPIAwareness(SDL_VideoDevice *_this)
{
SDL_VideoData *data = _this->driverdata;
SDL_VideoData *data = _this->internal;
if (data->GetThreadDpiAwarenessContext && data->AreDpiAwarenessContextsEqual) {
DPI_AWARENESS_CONTEXT context = data->GetThreadDpiAwarenessContext();
@@ -434,9 +465,26 @@ static void WIN_InitDPIAwareness(SDL_VideoDevice *_this)
}
}
int WIN_VideoInit(SDL_VideoDevice *_this)
static bool WIN_VideoInit(SDL_VideoDevice *_this)
{
SDL_VideoData *data = _this->driverdata;
SDL_VideoData *data = _this->internal;
HRESULT hr;
hr = WIN_CoInitialize();
if (SUCCEEDED(hr)) {
data->coinitialized = true;
#if !(defined(SDL_PLATFORM_XBOXONE) || defined(SDL_PLATFORM_XBOXSERIES))
hr = OleInitialize(NULL);
if (SUCCEEDED(hr)) {
data->oleinitialized = true;
} else {
SDL_LogInfo(SDL_LOG_CATEGORY_VIDEO, "OleInitialize() failed: 0x%.8x, using fallback drag-n-drop functionality\n", (unsigned int)hr);
}
#endif // !(defined(SDL_PLATFORM_XBOXONE) || defined(SDL_PLATFORM_XBOXSERIES))
} else {
SDL_LogInfo(SDL_LOG_CATEGORY_VIDEO, "CoInitialize() failed: 0x%.8x, using fallback drag-n-drop functionality\n", (unsigned int)hr);
}
WIN_InitDPIAwareness(_this);
@@ -444,8 +492,12 @@ int WIN_VideoInit(SDL_VideoDevice *_this)
SDL_Log("DPI awareness: %s", WIN_GetDPIAwareness(_this));
#endif
if (SDL_GetHintBoolean(SDL_HINT_WINDOWS_GAMEINPUT, true)) {
WIN_InitGameInput(_this);
}
#if defined(SDL_PLATFORM_XBOXONE) || defined(SDL_PLATFORM_XBOXSERIES)
/* For Xbox, we just need to create the single display */
// For Xbox, we just need to create the single display
{
SDL_DisplayMode mode;
@@ -456,15 +508,17 @@ int WIN_VideoInit(SDL_VideoDevice *_this)
SDL_AddBasicVideoDisplay(&mode);
}
#else /*!defined(SDL_PLATFORM_XBOXONE) && !defined(SDL_PLATFORM_XBOXSERIES)*/
if (WIN_InitModes(_this) < 0) {
return -1;
#else // !defined(SDL_PLATFORM_XBOXONE) && !defined(SDL_PLATFORM_XBOXSERIES)
if (!WIN_InitModes(_this)) {
return false;
}
WIN_InitKeyboard(_this);
WIN_InitMouse(_this);
WIN_InitDeviceNotification();
WIN_CheckKeyboardAndMouseHotplug(_this, SDL_TRUE);
if (!_this->internal->gameinput_context) {
WIN_CheckKeyboardAndMouseHotplug(_this, true);
}
#endif
SDL_AddHintCallback(SDL_HINT_WINDOWS_RAW_KEYBOARD, UpdateWindowsRawKeyboard, _this);
@@ -476,25 +530,38 @@ int WIN_VideoInit(SDL_VideoDevice *_this)
data->_SDL_WAKEUP = RegisterWindowMessageA("_SDL_WAKEUP");
#endif
return 0;
return true;
}
void WIN_VideoQuit(SDL_VideoDevice *_this)
{
SDL_VideoData *data = _this->internal;
SDL_RemoveHintCallback(SDL_HINT_WINDOWS_RAW_KEYBOARD, UpdateWindowsRawKeyboard, _this);
SDL_RemoveHintCallback(SDL_HINT_WINDOWS_ENABLE_MESSAGELOOP, UpdateWindowsEnableMessageLoop, NULL);
SDL_RemoveHintCallback(SDL_HINT_WINDOWS_ENABLE_MENU_MNEMONICS, UpdateWindowsEnableMenuMnemonics, NULL);
SDL_RemoveHintCallback(SDL_HINT_WINDOW_FRAME_USABLE_WHILE_CURSOR_HIDDEN, UpdateWindowFrameUsableWhileCursorHidden, NULL);
WIN_SetRawMouseEnabled(_this, false);
WIN_SetRawKeyboardEnabled(_this, false);
WIN_QuitGameInput(_this);
#if !defined(SDL_PLATFORM_XBOXONE) && !defined(SDL_PLATFORM_XBOXSERIES)
WIN_QuitModes(_this);
WIN_QuitDeviceNotification();
WIN_QuitKeyboard(_this);
WIN_QuitMouse(_this);
#endif
SDL_DelHintCallback(SDL_HINT_WINDOWS_RAW_KEYBOARD, UpdateWindowsRawKeyboard, _this);
SDL_DelHintCallback(SDL_HINT_WINDOWS_ENABLE_MESSAGELOOP, UpdateWindowsEnableMessageLoop, NULL);
SDL_DelHintCallback(SDL_HINT_WINDOWS_ENABLE_MENU_MNEMONICS, UpdateWindowsEnableMenuMnemonics, NULL);
SDL_DelHintCallback(SDL_HINT_WINDOW_FRAME_USABLE_WHILE_CURSOR_HIDDEN, UpdateWindowFrameUsableWhileCursorHidden, NULL);
if (data->oleinitialized) {
OleUninitialize();
data->oleinitialized = false;
}
#endif // !(defined(SDL_PLATFORM_XBOXONE) || defined(SDL_PLATFORM_XBOXSERIES))
WIN_SetRawMouseEnabled(_this, SDL_FALSE);
WIN_SetRawKeyboardEnabled(_this, SDL_FALSE);
if (data->coinitialized) {
WIN_CoUninitialize();
data->coinitialized = false;
}
}
#if !defined(SDL_PLATFORM_XBOXONE) && !defined(SDL_PLATFORM_XBOXSERIES)
@@ -508,7 +575,7 @@ void WIN_VideoQuit(SDL_VideoDevice *_this)
#ifndef D3D9b_SDK_VERSION
#define D3D9b_SDK_VERSION (31 | 0x80000000)
#endif
#else /**/
#else //
#ifndef D3D_SDK_VERSION
#define D3D_SDK_VERSION 32
#endif
@@ -517,17 +584,17 @@ void WIN_VideoQuit(SDL_VideoDevice *_this)
#endif
#endif
SDL_bool D3D_LoadDLL(void **pD3DDLL, IDirect3D9 **pDirect3D9Interface)
bool D3D_LoadDLL(void **pD3DDLL, IDirect3D9 **pDirect3D9Interface)
{
*pD3DDLL = SDL_LoadObject("D3D9.DLL");
if (*pD3DDLL) {
/* *INDENT-OFF* */ /* clang-format off */
/* *INDENT-OFF* */ // clang-format off
typedef IDirect3D9 *(WINAPI *Direct3DCreate9_t)(UINT SDKVersion);
typedef HRESULT (WINAPI* Direct3DCreate9Ex_t)(UINT SDKVersion, IDirect3D9Ex** ppD3D);
/* *INDENT-ON* */ /* clang-format on */
/* *INDENT-ON* */ // clang-format on
Direct3DCreate9_t Direct3DCreate9Func;
if (SDL_GetHintBoolean(SDL_HINT_WINDOWS_USE_D3D9EX, SDL_FALSE)) {
if (SDL_GetHintBoolean(SDL_HINT_WINDOWS_USE_D3D9EX, false)) {
Direct3DCreate9Ex_t Direct3DCreate9ExFunc;
Direct3DCreate9ExFunc = (Direct3DCreate9Ex_t)SDL_LoadFunction(*pD3DDLL, "Direct3DCreate9Ex");
@@ -539,7 +606,7 @@ SDL_bool D3D_LoadDLL(void **pD3DDLL, IDirect3D9 **pDirect3D9Interface)
hr = IDirect3D9Ex_QueryInterface(pDirect3D9ExInterface, &IDirect3D9_GUID, (void **)pDirect3D9Interface);
IDirect3D9Ex_Release(pDirect3D9ExInterface);
if (SUCCEEDED(hr)) {
return SDL_TRUE;
return true;
}
}
}
@@ -549,7 +616,7 @@ SDL_bool D3D_LoadDLL(void **pD3DDLL, IDirect3D9 **pDirect3D9Interface)
if (Direct3DCreate9Func) {
*pDirect3D9Interface = Direct3DCreate9Func(D3D_SDK_VERSION);
if (*pDirect3D9Interface) {
return SDL_TRUE;
return true;
}
}
@@ -557,23 +624,23 @@ SDL_bool D3D_LoadDLL(void **pD3DDLL, IDirect3D9 **pDirect3D9Interface)
*pD3DDLL = NULL;
}
*pDirect3D9Interface = NULL;
return SDL_FALSE;
return false;
}
int SDL_Direct3D9GetAdapterIndex(SDL_DisplayID displayID)
int SDL_GetDirect3D9AdapterIndex(SDL_DisplayID displayID)
{
void *pD3DDLL;
IDirect3D9 *pD3D;
if (!D3D_LoadDLL(&pD3DDLL, &pD3D)) {
SDL_SetError("Unable to create Direct3D interface");
return D3DADAPTER_DEFAULT;
return -1;
} else {
SDL_DisplayData *pData = SDL_GetDisplayDriverData(displayID);
int adapterIndex = D3DADAPTER_DEFAULT;
if (!pData) {
SDL_SetError("Invalid display index");
adapterIndex = -1; /* make sure we return something invalid */
adapterIndex = -1; // make sure we return something invalid
} else {
char *displayName = WIN_StringToUTF8W(pData->DeviceName);
unsigned int count = IDirect3D9_GetAdapterCount(pD3D);
@@ -590,51 +657,16 @@ int SDL_Direct3D9GetAdapterIndex(SDL_DisplayID displayID)
SDL_free(displayName);
}
/* free up the D3D stuff we inited */
// free up the D3D stuff we inited
IDirect3D9_Release(pD3D);
SDL_UnloadObject(pD3DDLL);
return adapterIndex;
}
}
#endif /* !defined(SDL_PLATFORM_XBOXONE) && !defined(SDL_PLATFORM_XBOXSERIES) */
#endif // !defined(SDL_PLATFORM_XBOXONE) && !defined(SDL_PLATFORM_XBOXSERIES)
#ifdef HAVE_DXGI_H
#define CINTERFACE
#define COBJMACROS
#include <dxgi.h>
static SDL_bool DXGI_LoadDLL(void **pDXGIDLL, IDXGIFactory **pDXGIFactory)
{
*pDXGIDLL = SDL_LoadObject("DXGI.DLL");
if (*pDXGIDLL) {
/* *INDENT-OFF* */ /* clang-format off */
typedef HRESULT (WINAPI *CreateDXGI_t)(REFIID riid, void **ppFactory);
/* *INDENT-ON* */ /* clang-format on */
CreateDXGI_t CreateDXGI;
CreateDXGI = (CreateDXGI_t)SDL_LoadFunction(*pDXGIDLL, "CreateDXGIFactory");
if (CreateDXGI) {
GUID dxgiGUID = { 0x7b7166ec, 0x21c7, 0x44ae, { 0xb2, 0x1a, 0xc9, 0xae, 0x32, 0x1a, 0xe3, 0x69 } };
if (!SUCCEEDED(CreateDXGI(&dxgiGUID, (void **)pDXGIFactory))) {
*pDXGIFactory = NULL;
}
}
if (!*pDXGIFactory) {
SDL_UnloadObject(*pDXGIDLL);
*pDXGIDLL = NULL;
return SDL_FALSE;
}
return SDL_TRUE;
} else {
*pDXGIFactory = NULL;
return SDL_FALSE;
}
}
#endif
SDL_bool SDL_DXGIGetOutputInfo(SDL_DisplayID displayID, int *adapterIndex, int *outputIndex)
bool SDL_GetDXGIOutputInfo(SDL_DisplayID displayID, int *adapterIndex, int *outputIndex)
{
#ifndef HAVE_DXGI_H
if (adapterIndex) {
@@ -643,53 +675,44 @@ SDL_bool SDL_DXGIGetOutputInfo(SDL_DisplayID displayID, int *adapterIndex, int *
if (outputIndex) {
*outputIndex = -1;
}
SDL_SetError("SDL was compiled without DXGI support due to missing dxgi.h header");
return SDL_FALSE;
return SDL_SetError("SDL was compiled without DXGI support due to missing dxgi.h header");
#else
const SDL_VideoDevice *videodevice = SDL_GetVideoDevice();
const SDL_VideoData *videodata = videodevice ? videodevice->internal : NULL;
SDL_DisplayData *pData = SDL_GetDisplayDriverData(displayID);
void *pDXGIDLL;
char *displayName;
int nAdapter, nOutput;
IDXGIFactory *pDXGIFactory = NULL;
IDXGIAdapter *pDXGIAdapter;
IDXGIOutput *pDXGIOutput;
if (!adapterIndex) {
SDL_InvalidParamError("adapterIndex");
return SDL_FALSE;
return SDL_InvalidParamError("adapterIndex");
}
if (!outputIndex) {
SDL_InvalidParamError("outputIndex");
return SDL_FALSE;
return SDL_InvalidParamError("outputIndex");
}
*adapterIndex = -1;
*outputIndex = -1;
if (!pData) {
SDL_SetError("Invalid display index");
return SDL_FALSE;
return SDL_SetError("Invalid display index");
}
if (!DXGI_LoadDLL(&pDXGIDLL, &pDXGIFactory)) {
SDL_SetError("Unable to create DXGI interface");
return SDL_FALSE;
if (!videodata || !videodata->pDXGIFactory) {
return SDL_SetError("Unable to create DXGI interface");
}
displayName = WIN_StringToUTF8W(pData->DeviceName);
nAdapter = 0;
while (*adapterIndex == -1 && SUCCEEDED(IDXGIFactory_EnumAdapters(pDXGIFactory, nAdapter, &pDXGIAdapter))) {
while (*adapterIndex == -1 && SUCCEEDED(IDXGIFactory_EnumAdapters(videodata->pDXGIFactory, nAdapter, &pDXGIAdapter))) {
nOutput = 0;
while (*adapterIndex == -1 && SUCCEEDED(IDXGIAdapter_EnumOutputs(pDXGIAdapter, nOutput, &pDXGIOutput))) {
DXGI_OUTPUT_DESC outputDesc;
if (SUCCEEDED(IDXGIOutput_GetDesc(pDXGIOutput, &outputDesc))) {
char *outputName = WIN_StringToUTF8W(outputDesc.DeviceName);
if (SDL_strcmp(outputName, displayName) == 0) {
if (SDL_wcscmp(outputDesc.DeviceName, pData->DeviceName) == 0) {
*adapterIndex = nAdapter;
*outputIndex = nOutput;
}
SDL_free(outputName);
}
IDXGIOutput_Release(pDXGIOutput);
nOutput++;
@@ -697,17 +720,11 @@ SDL_bool SDL_DXGIGetOutputInfo(SDL_DisplayID displayID, int *adapterIndex, int *
IDXGIAdapter_Release(pDXGIAdapter);
nAdapter++;
}
SDL_free(displayName);
/* free up the DXGI factory */
IDXGIFactory_Release(pDXGIFactory);
SDL_UnloadObject(pDXGIDLL);
if (*adapterIndex == -1) {
return SDL_FALSE;
} else {
return SDL_TRUE;
return SDL_SetError("Couldn't find matching adapter");
}
return true;
#endif
}
@@ -719,7 +736,7 @@ SDL_SystemTheme WIN_GetSystemTheme(void)
DWORD value = ~0U;
DWORD length = sizeof(value);
/* Technically this isn't the system theme, but it's the preference for applications */
// Technically this isn't the system theme, but it's the preference for applications
if (RegOpenKeyExW(HKEY_CURRENT_USER, L"Software\\Microsoft\\Windows\\CurrentVersion\\Themes\\Personalize", 0, KEY_READ, &hKey) == ERROR_SUCCESS) {
if (RegQueryValueExW(hKey, L"AppsUseLightTheme", 0, &dwType, (LPBYTE)&value, &length) == ERROR_SUCCESS) {
if (value == 0) {
@@ -731,17 +748,17 @@ SDL_SystemTheme WIN_GetSystemTheme(void)
return theme;
}
SDL_bool WIN_IsPerMonitorV2DPIAware(SDL_VideoDevice *_this)
bool WIN_IsPerMonitorV2DPIAware(SDL_VideoDevice *_this)
{
#if !defined(SDL_PLATFORM_XBOXONE) && !defined(SDL_PLATFORM_XBOXSERIES)
SDL_VideoData *data = _this->driverdata;
SDL_VideoData *data = _this->internal;
if (data->AreDpiAwarenessContextsEqual && data->GetThreadDpiAwarenessContext) {
/* Windows 10, version 1607 */
// Windows 10, version 1607
return data->AreDpiAwarenessContextsEqual(DPI_AWARENESS_CONTEXT_PER_MONITOR_AWARE_V2, data->GetThreadDpiAwarenessContext());
}
#endif
return SDL_FALSE;
return false;
}
#endif /* SDL_VIDEO_DRIVER_WINDOWS */
#endif // SDL_VIDEO_DRIVER_WINDOWS
+78 -61
View File
@@ -27,6 +27,12 @@
#include "../SDL_sysvideo.h"
#ifdef HAVE_DXGI_H
#define CINTERFACE
#define COBJMACROS
#include <dxgi.h>
#endif
#if defined(_MSC_VER) && (_MSC_VER >= 1500) && !defined(SDL_PLATFORM_XBOXONE) && !defined(SDL_PLATFORM_XBOXSERIES)
#include <msctf.h>
#else
@@ -41,6 +47,7 @@
#include "SDL_windowsclipboard.h"
#include "SDL_windowsevents.h"
#include "SDL_windowsgameinput.h"
#include "SDL_windowsopengl.h"
#if !defined(SDL_PLATFORM_XBOXONE) && !defined(SDL_PLATFORM_XBOXSERIES)
@@ -58,7 +65,7 @@
#endif
#if WINVER < 0x0601
/* Touch input definitions */
// Touch input definitions
#define TWF_FINETOUCH 1
#define TWF_WANTPALM 2
@@ -82,8 +89,8 @@ typedef struct _TOUCHINPUT
DWORD cyContact;
} TOUCHINPUT, *PTOUCHINPUT;
/* More-robust display information in Vista... */
/* This is a huge amount of data to be stuffing into three API calls. :( */
// More-robust display information in Vista...
// This is a huge amount of data to be stuffing into three API calls. :(
typedef struct DISPLAYCONFIG_PATH_SOURCE_INFO
{
LUID adapterId;
@@ -278,7 +285,7 @@ typedef struct DISPLAYCONFIG_TARGET_DEVICE_NAME
#define QDC_ONLY_ACTIVE_PATHS 0x00000002
#endif /* WINVER < 0x0601 */
#endif // WINVER < 0x0601
#ifndef HAVE_SHELLSCALINGAPI_H
@@ -317,17 +324,17 @@ DECLARE_HANDLE(DPI_AWARENESS_CONTEXT);
#define DPI_AWARENESS_CONTEXT_SYSTEM_AWARE ((DPI_AWARENESS_CONTEXT)-2)
#define DPI_AWARENESS_CONTEXT_PER_MONITOR_AWARE ((DPI_AWARENESS_CONTEXT)-3)
#endif /* _DPI_AWARENESS_CONTEXTS_ */
#endif // _DPI_AWARENESS_CONTEXTS_
/* Windows 10 Creators Update */
// Windows 10 Creators Update
#if NTDDI_VERSION < 0x0A000003
#define DPI_AWARENESS_CONTEXT_PER_MONITOR_AWARE_V2 ((DPI_AWARENESS_CONTEXT)-4)
#endif /* NTDDI_VERSION < 0x0A000003 */
#endif // NTDDI_VERSION < 0x0A000003
/* Windows 10 version 1809 */
// Windows 10 version 1809
#if NTDDI_VERSION < 0x0A000006
#define DPI_AWARENESS_CONTEXT_UNAWARE_GDISCALED ((DPI_AWARENESS_CONTEXT)-5)
#endif /* NTDDI_VERSION < 0x0A000006 */
#endif // NTDDI_VERSION < 0x0A000006
typedef BOOL (*PFNSHFullScreen)(HWND, DWORD);
typedef void (*PFCoordTransform)(SDL_Window *, POINT *);
@@ -340,7 +347,7 @@ typedef struct
} TSFSink;
#ifndef SDL_DISABLE_WINDOWS_IME
/* Definition from Win98DDK version of IMM.H */
// Definition from Win98DDK version of IMM.H
typedef struct tagINPUTCONTEXT2
{
HWND hWnd;
@@ -365,20 +372,25 @@ typedef struct tagINPUTCONTEXT2
DWORD fdwInit;
DWORD dwReserve[3];
} INPUTCONTEXT2, *PINPUTCONTEXT2, NEAR *NPINPUTCONTEXT2, FAR *LPINPUTCONTEXT2;
#endif /* !SDL_DISABLE_WINDOWS_IME */
#endif
/* Private display data */
// Private display data
struct SDL_VideoData
{
int render;
bool coinitialized;
#if !(defined(SDL_PLATFORM_XBOXONE) || defined(SDL_PLATFORM_XBOXSERIES))
bool oleinitialized;
#endif // !(defined(SDL_PLATFORM_XBOXONE) || defined(SDL_PLATFORM_XBOXSERIES))
DWORD clipboard_count;
#if !defined(SDL_PLATFORM_XBOXONE) && !defined(SDL_PLATFORM_XBOXSERIES) /* Xbox doesn't support user32/shcore*/
/* Touch input functions */
void *userDLL;
/* *INDENT-OFF* */ /* clang-format off */
#if !defined(SDL_PLATFORM_XBOXONE) && !defined(SDL_PLATFORM_XBOXSERIES) // Xbox doesn't support user32/shcore
// Touch input functions
SDL_SharedObject *userDLL;
/* *INDENT-OFF* */ // clang-format off
BOOL (WINAPI *CloseTouchInputHandle)( HTOUCHINPUT );
BOOL (WINAPI *GetTouchInputInfo)( HTOUCHINPUT, UINT, PTOUCHINPUT, int );
BOOL (WINAPI *RegisterTouchWindow)( HWND, ULONG );
@@ -392,19 +404,28 @@ struct SDL_VideoData
UINT (WINAPI *GetDpiForWindow)( HWND );
BOOL (WINAPI *AreDpiAwarenessContextsEqual)(DPI_AWARENESS_CONTEXT, DPI_AWARENESS_CONTEXT);
BOOL (WINAPI *IsValidDpiAwarenessContext)(DPI_AWARENESS_CONTEXT);
/* *INDENT-ON* */ /* clang-format on */
// 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;
/* *INDENT-OFF* */ /* clang-format off */
SDL_SharedObject *shcoreDLL;
/* *INDENT-OFF* */ // clang-format off
HRESULT (WINAPI *GetDpiForMonitor)( HMONITOR hmonitor,
MONITOR_DPI_TYPE dpiType,
UINT *dpiX,
UINT *dpiY );
HRESULT (WINAPI *SetProcessDpiAwareness)(PROCESS_DPI_AWARENESS dpiAwareness);
/* *INDENT-ON* */ /* clang-format on */
#endif /*!defined(SDL_PLATFORM_XBOXONE) && !defined(SDL_PLATFORM_XBOXSERIES)*/
/* *INDENT-ON* */ // clang-format on
#endif // !defined(SDL_PLATFORM_XBOXONE) && !defined(SDL_PLATFORM_XBOXSERIES)
SDL_bool cleared;
#ifdef HAVE_DXGI_H
SDL_SharedObject *dxgiDLL;
IDXGIFactory *pDXGIFactory;
#endif
bool cleared;
BYTE *rawinput;
UINT rawinput_offset;
@@ -412,76 +433,72 @@ struct SDL_VideoData
UINT rawinput_count;
Uint64 last_rawinput_poll;
SDL_Point last_raw_mouse_position;
SDL_bool raw_mouse_enabled;
SDL_bool raw_keyboard_enabled;
SDL_bool pending_E1_key_sequence;
SDL_bool raw_input_enabled;
bool raw_mouse_enabled;
bool raw_keyboard_enabled;
bool pending_E1_key_sequence;
Uint32 raw_input_enabled;
WIN_GameInputData *gameinput_context;
#ifndef SDL_DISABLE_WINDOWS_IME
SDL_bool ime_com_initialized;
struct ITfThreadMgr *ime_threadmgr;
SDL_bool ime_initialized;
SDL_bool ime_enabled;
SDL_bool ime_available;
bool ime_initialized;
bool ime_enabled;
bool ime_available;
bool ime_internal_composition;
bool ime_internal_candidates;
HWND ime_hwnd_main;
HWND ime_hwnd_current;
SDL_bool ime_suppress_endcomposition_event;
bool ime_needs_clear_composition;
HIMC ime_himc;
WCHAR *ime_composition;
int ime_composition_length;
WCHAR ime_readingstring[16];
int ime_cursor;
int ime_selected_start;
int ime_selected_length;
SDL_bool ime_candlist;
WCHAR *ime_candidates;
DWORD ime_candcount;
bool ime_candidates_open;
bool ime_update_candidates;
char *ime_candidates[MAX_CANDLIST];
int ime_candcount;
DWORD ime_candref;
DWORD ime_candsel;
UINT ime_candpgsize;
int ime_candlistindexbase;
SDL_bool ime_candvertical;
bool ime_horizontal_candidates;
#endif
SDL_bool ime_dirty;
SDL_Rect ime_rect;
SDL_Rect ime_candlistrect;
int ime_winwidth;
int ime_winheight;
#if !defined(SDL_PLATFORM_XBOXONE) && !defined(SDL_PLATFORM_XBOXSERIES)
COMPOSITIONFORM ime_composition_area;
CANDIDATEFORM ime_candidate_area;
#endif // !defined(SDL_PLATFORM_XBOXONE) && !defined(SDL_PLATFORM_XBOXSERIES)
#ifndef SDL_DISABLE_WINDOWS_IME
HKL ime_hkl;
void *ime_himm32;
/* *INDENT-OFF* */ /* clang-format off */
SDL_SharedObject *ime_himm32;
/* *INDENT-OFF* */ // clang-format off
UINT (WINAPI *GetReadingString)(HIMC himc, UINT uReadingBufLen, LPWSTR lpwReadingBuf, PINT pnErrorIndex, BOOL *pfIsVertical, PUINT puMaxReadingLen);
BOOL (WINAPI *ShowReadingWindow)(HIMC himc, BOOL bShow);
LPINPUTCONTEXT2 (WINAPI *ImmLockIMC)(HIMC himc);
BOOL (WINAPI *ImmUnlockIMC)(HIMC himc);
LPVOID (WINAPI *ImmLockIMCC)(HIMCC himcc);
BOOL (WINAPI *ImmUnlockIMCC)(HIMCC himcc);
/* *INDENT-ON* */ /* clang-format on */
/* *INDENT-ON* */ // clang-format on
SDL_bool ime_uiless;
struct ITfThreadMgrEx *ime_threadmgrex;
DWORD ime_uielemsinkcookie;
DWORD ime_alpnsinkcookie;
DWORD ime_openmodesinkcookie;
DWORD ime_convmodesinkcookie;
TSFSink *ime_uielemsink;
TSFSink *ime_ippasink;
LONG ime_uicontext;
#endif /* !SDL_DISABLE_WINDOWS_IME */
#endif // !SDL_DISABLE_WINDOWS_IME
BYTE pre_hook_key_state[256];
UINT _SDL_WAKEUP;
};
extern SDL_bool g_WindowsEnableMessageLoop;
extern SDL_bool g_WindowsEnableMenuMnemonics;
extern SDL_bool g_WindowFrameUsableWhileCursorHidden;
extern bool g_WindowsEnableMessageLoop;
extern bool g_WindowsEnableMenuMnemonics;
extern bool g_WindowFrameUsableWhileCursorHidden;
typedef struct IDirect3D9 IDirect3D9;
extern SDL_bool D3D_LoadDLL(void **pD3DDLL, IDirect3D9 **pDirect3D9Interface);
extern bool D3D_LoadDLL(void **pD3DDLL, IDirect3D9 **pDirect3D9Interface);
extern SDL_SystemTheme WIN_GetSystemTheme(void);
extern SDL_bool WIN_IsPerMonitorV2DPIAware(SDL_VideoDevice *_this);
extern bool WIN_IsPerMonitorV2DPIAware(SDL_VideoDevice *_this);
#endif /* SDL_windowsvideo_h_ */
#endif // SDL_windowsvideo_h_
+58 -26
View File
@@ -35,28 +35,28 @@
#include "SDL_windowsvulkan.h"
int WIN_Vulkan_LoadLibrary(SDL_VideoDevice *_this, const char *path)
bool WIN_Vulkan_LoadLibrary(SDL_VideoDevice *_this, const char *path)
{
VkExtensionProperties *extensions = NULL;
Uint32 extensionCount = 0;
Uint32 i;
SDL_bool hasSurfaceExtension = SDL_FALSE;
SDL_bool hasWin32SurfaceExtension = SDL_FALSE;
bool hasSurfaceExtension = false;
bool hasWin32SurfaceExtension = false;
PFN_vkGetInstanceProcAddr vkGetInstanceProcAddr = NULL;
if (_this->vulkan_config.loader_handle) {
return SDL_SetError("Vulkan already loaded");
}
/* Load the Vulkan loader library */
// Load the Vulkan loader library
if (!path) {
path = SDL_getenv("SDL_VULKAN_LIBRARY");
path = SDL_GetHint(SDL_HINT_VULKAN_LIBRARY);
}
if (!path) {
path = "vulkan-1.dll";
}
_this->vulkan_config.loader_handle = SDL_LoadObject(path);
if (!_this->vulkan_config.loader_handle) {
return -1;
return false;
}
SDL_strlcpy(_this->vulkan_config.loader_path, path,
SDL_arraysize(_this->vulkan_config.loader_path));
@@ -81,9 +81,9 @@ int WIN_Vulkan_LoadLibrary(SDL_VideoDevice *_this, const char *path)
}
for (i = 0; i < extensionCount; i++) {
if (SDL_strcmp(VK_KHR_SURFACE_EXTENSION_NAME, extensions[i].extensionName) == 0) {
hasSurfaceExtension = SDL_TRUE;
hasSurfaceExtension = true;
} else if (SDL_strcmp(VK_KHR_WIN32_SURFACE_EXTENSION_NAME, extensions[i].extensionName) == 0) {
hasWin32SurfaceExtension = SDL_TRUE;
hasWin32SurfaceExtension = true;
}
}
SDL_free(extensions);
@@ -94,12 +94,12 @@ int WIN_Vulkan_LoadLibrary(SDL_VideoDevice *_this, const char *path)
SDL_SetError("Installed Vulkan doesn't implement the " VK_KHR_WIN32_SURFACE_EXTENSION_NAME "extension");
goto fail;
}
return 0;
return true;
fail:
SDL_UnloadObject(_this->vulkan_config.loader_handle);
_this->vulkan_config.loader_handle = NULL;
return -1;
return false;
}
void WIN_Vulkan_UnloadLibrary(SDL_VideoDevice *_this)
@@ -116,17 +116,19 @@ char const* const* WIN_Vulkan_GetInstanceExtensions(SDL_VideoDevice *_this,
static const char *const extensionsForWin32[] = {
VK_KHR_SURFACE_EXTENSION_NAME, VK_KHR_WIN32_SURFACE_EXTENSION_NAME
};
if(count) { *count = SDL_arraysize(extensionsForWin32); }
if (count) {
*count = SDL_arraysize(extensionsForWin32);
}
return extensionsForWin32;
}
SDL_bool WIN_Vulkan_CreateSurface(SDL_VideoDevice *_this,
SDL_Window *window,
VkInstance instance,
const struct VkAllocationCallbacks *allocator,
VkSurfaceKHR *surface)
bool WIN_Vulkan_CreateSurface(SDL_VideoDevice *_this,
SDL_Window *window,
VkInstance instance,
const struct VkAllocationCallbacks *allocator,
VkSurfaceKHR *surface)
{
SDL_WindowData *windowData = window->driverdata;
SDL_WindowData *windowData = window->internal;
PFN_vkGetInstanceProcAddr vkGetInstanceProcAddr =
(PFN_vkGetInstanceProcAddr)_this->vulkan_config.vkGetInstanceProcAddr;
PFN_vkCreateWin32SurfaceKHR vkCreateWin32SurfaceKHR =
@@ -137,14 +139,12 @@ SDL_bool WIN_Vulkan_CreateSurface(SDL_VideoDevice *_this,
VkResult result;
if (!_this->vulkan_config.loader_handle) {
SDL_SetError("Vulkan is not loaded");
return SDL_FALSE;
return SDL_SetError("Vulkan is not loaded");
}
if (!vkCreateWin32SurfaceKHR) {
SDL_SetError(VK_KHR_WIN32_SURFACE_EXTENSION_NAME
" extension is not enabled in the Vulkan instance.");
return SDL_FALSE;
return SDL_SetError(VK_KHR_WIN32_SURFACE_EXTENSION_NAME
" extension is not enabled in the Vulkan instance.");
}
createInfo.sType = VK_STRUCTURE_TYPE_WIN32_SURFACE_CREATE_INFO_KHR;
createInfo.pNext = NULL;
@@ -153,11 +153,43 @@ SDL_bool WIN_Vulkan_CreateSurface(SDL_VideoDevice *_this,
createInfo.hwnd = windowData->hwnd;
result = vkCreateWin32SurfaceKHR(instance, &createInfo, allocator, surface);
if (result != VK_SUCCESS) {
SDL_SetError("vkCreateWin32SurfaceKHR failed: %s",
SDL_Vulkan_GetResultString(result));
return SDL_FALSE;
return SDL_SetError("vkCreateWin32SurfaceKHR failed: %s", SDL_Vulkan_GetResultString(result));
}
return SDL_TRUE;
return true;
}
void WIN_Vulkan_DestroySurface(SDL_VideoDevice *_this,
VkInstance instance,
VkSurfaceKHR surface,
const struct VkAllocationCallbacks *allocator)
{
if (_this->vulkan_config.loader_handle) {
SDL_Vulkan_DestroySurface_Internal(_this->vulkan_config.vkGetInstanceProcAddr, instance, surface, allocator);
}
}
bool WIN_Vulkan_GetPresentationSupport(SDL_VideoDevice *_this,
VkInstance instance,
VkPhysicalDevice physicalDevice,
Uint32 queueFamilyIndex)
{
PFN_vkGetInstanceProcAddr vkGetInstanceProcAddr =
(PFN_vkGetInstanceProcAddr)_this->vulkan_config.vkGetInstanceProcAddr;
PFN_vkGetPhysicalDeviceWin32PresentationSupportKHR vkGetPhysicalDeviceWin32PresentationSupportKHR =
(PFN_vkGetPhysicalDeviceWin32PresentationSupportKHR)vkGetInstanceProcAddr(
instance,
"vkGetPhysicalDeviceWin32PresentationSupportKHR");
if (!_this->vulkan_config.loader_handle) {
return SDL_SetError("Vulkan is not loaded");
}
if (!vkGetPhysicalDeviceWin32PresentationSupportKHR) {
return SDL_SetError(VK_KHR_WIN32_SURFACE_EXTENSION_NAME " extension is not enabled in the Vulkan instance.");
}
return vkGetPhysicalDeviceWin32PresentationSupportKHR(physicalDevice,
queueFamilyIndex);
}
#endif
+19 -13
View File
@@ -29,21 +29,27 @@
#ifndef SDL_windowsvulkan_h_
#define SDL_windowsvulkan_h_
#include <SDL3/SDL_vulkan.h>
#if defined(SDL_VIDEO_VULKAN) && defined(SDL_VIDEO_DRIVER_WINDOWS)
#include "../SDL_vulkan_internal.h"
#include "../SDL_sysvideo.h"
int WIN_Vulkan_LoadLibrary(SDL_VideoDevice *_this, const char *path);
void WIN_Vulkan_UnloadLibrary(SDL_VideoDevice *_this);
char const* const* WIN_Vulkan_GetInstanceExtensions(SDL_VideoDevice *_this,
Uint32 *count);
SDL_bool WIN_Vulkan_CreateSurface(SDL_VideoDevice *_this,
SDL_Window *window,
VkInstance instance,
const struct VkAllocationCallbacks *allocator,
VkSurfaceKHR *surface);
extern bool WIN_Vulkan_LoadLibrary(SDL_VideoDevice *_this, const char *path);
extern void WIN_Vulkan_UnloadLibrary(SDL_VideoDevice *_this);
extern char const* const* WIN_Vulkan_GetInstanceExtensions(SDL_VideoDevice *_this, Uint32 *count);
extern bool WIN_Vulkan_CreateSurface(SDL_VideoDevice *_this,
SDL_Window *window,
VkInstance instance,
const struct VkAllocationCallbacks *allocator,
VkSurfaceKHR *surface);
extern void WIN_Vulkan_DestroySurface(SDL_VideoDevice *_this,
VkInstance instance,
VkSurfaceKHR surface,
const struct VkAllocationCallbacks *allocator);
bool WIN_Vulkan_GetPresentationSupport(SDL_VideoDevice *_this,
VkInstance instance,
VkPhysicalDevice physicalDevice,
Uint32 queueFamilyIndex);
#endif
#endif /* SDL_windowsvulkan_h_ */
#endif // SDL_windowsvulkan_h_
File diff suppressed because it is too large Load Diff
+56 -35
View File
@@ -29,7 +29,7 @@
#include "../SDL_sysvideo.h"
#endif
/* Set up for C function definitions, even when using C++ */
// Set up for C function definitions, even when using C++
#ifdef __cplusplus
extern "C" {
#endif
@@ -41,6 +41,23 @@ typedef enum SDL_WindowRect
SDL_WINDOWRECT_FLOATING
} SDL_WindowRect;
typedef enum SDL_WindowEraseBackgroundMode
{
SDL_ERASEBACKGROUNDMODE_NEVER,
SDL_ERASEBACKGROUNDMODE_INITIAL,
SDL_ERASEBACKGROUNDMODE_ALWAYS,
} SDL_WindowEraseBackgroundMode;
typedef struct
{
void **lpVtbl;
int refcount;
SDL_Window *window;
HWND hwnd;
UINT format_text;
UINT format_file;
} SDLDropTarget;
struct SDL_WindowData
{
SDL_Window *window;
@@ -55,73 +72,77 @@ struct SDL_WindowData
WPARAM mouse_button_flags;
LPARAM last_pointer_update;
WCHAR high_surrogate;
SDL_bool initializing;
SDL_bool expected_resize;
SDL_bool in_border_change;
SDL_bool in_title_click;
SDL_bool floating_rect_pending;
bool initializing;
bool expected_resize;
bool in_border_change;
bool in_title_click;
bool floating_rect_pending;
Uint8 focus_click_pending;
SDL_bool skip_update_clipcursor;
bool skip_update_clipcursor;
Uint64 last_updated_clipcursor;
SDL_bool mouse_relative_mode_center;
SDL_bool windowed_mode_was_maximized;
SDL_bool in_window_deactivation;
bool mouse_relative_mode_center;
bool windowed_mode_was_maximized;
bool in_window_deactivation;
RECT cursor_clipped_rect;
UINT windowed_mode_corner_rounding;
COLORREF dwma_border_color;
SDL_bool mouse_tracked;
SDL_bool destroy_parent_with_window;
bool mouse_tracked;
bool destroy_parent_with_window;
SDL_DisplayID last_displayID;
WCHAR *ICMFileName;
SDL_Window *keyboard_focus;
SDL_WindowEraseBackgroundMode hint_erase_background_mode;
struct SDL_VideoData *videodata;
#ifdef SDL_VIDEO_OPENGL_EGL
EGLSurface egl_surface;
#endif
/* Whether we retain the content of the window when changing state */
// Whether we retain the content of the window when changing state
UINT copybits_flag;
SDLDropTarget *drop_target;
};
extern int WIN_CreateWindow(SDL_VideoDevice *_this, SDL_Window *window, SDL_PropertiesID create_props);
extern bool WIN_CreateWindow(SDL_VideoDevice *_this, SDL_Window *window, SDL_PropertiesID create_props);
extern void WIN_SetWindowTitle(SDL_VideoDevice *_this, SDL_Window *window);
extern int WIN_SetWindowIcon(SDL_VideoDevice *_this, SDL_Window *window, SDL_Surface *icon);
extern int WIN_SetWindowPosition(SDL_VideoDevice *_this, SDL_Window *window);
extern bool WIN_SetWindowIcon(SDL_VideoDevice *_this, SDL_Window *window, SDL_Surface *icon);
extern bool WIN_SetWindowPosition(SDL_VideoDevice *_this, SDL_Window *window);
extern void WIN_SetWindowSize(SDL_VideoDevice *_this, SDL_Window *window);
extern int WIN_GetWindowBordersSize(SDL_VideoDevice *_this, SDL_Window *window, int *top, int *left, int *bottom, int *right);
extern bool WIN_GetWindowBordersSize(SDL_VideoDevice *_this, SDL_Window *window, int *top, int *left, int *bottom, int *right);
extern void WIN_GetWindowSizeInPixels(SDL_VideoDevice *_this, SDL_Window *window, int *width, int *height);
extern int WIN_SetWindowOpacity(SDL_VideoDevice *_this, SDL_Window *window, float opacity);
extern bool WIN_SetWindowOpacity(SDL_VideoDevice *_this, SDL_Window *window, float opacity);
extern void WIN_ShowWindow(SDL_VideoDevice *_this, SDL_Window *window);
extern void WIN_HideWindow(SDL_VideoDevice *_this, SDL_Window *window);
extern void WIN_RaiseWindow(SDL_VideoDevice *_this, SDL_Window *window);
extern void WIN_MaximizeWindow(SDL_VideoDevice *_this, SDL_Window *window);
extern void WIN_MinimizeWindow(SDL_VideoDevice *_this, SDL_Window *window);
extern void WIN_RestoreWindow(SDL_VideoDevice *_this, SDL_Window *window);
extern void WIN_SetWindowBordered(SDL_VideoDevice *_this, SDL_Window *window, SDL_bool bordered);
extern void WIN_SetWindowResizable(SDL_VideoDevice *_this, SDL_Window *window, SDL_bool resizable);
extern void WIN_SetWindowAlwaysOnTop(SDL_VideoDevice *_this, SDL_Window *window, SDL_bool on_top);
extern int WIN_SetWindowFullscreen(SDL_VideoDevice *_this, SDL_Window *window, SDL_VideoDisplay *display, SDL_bool fullscreen);
extern void WIN_UpdateWindowICCProfile(SDL_Window *window, SDL_bool send_event);
extern void WIN_SetWindowBordered(SDL_VideoDevice *_this, SDL_Window *window, bool bordered);
extern void WIN_SetWindowResizable(SDL_VideoDevice *_this, SDL_Window *window, bool resizable);
extern void WIN_SetWindowAlwaysOnTop(SDL_VideoDevice *_this, SDL_Window *window, bool on_top);
extern SDL_FullscreenResult WIN_SetWindowFullscreen(SDL_VideoDevice *_this, SDL_Window *window, SDL_VideoDisplay *display, SDL_FullscreenOp fullscreen);
extern void WIN_UpdateWindowICCProfile(SDL_Window *window, bool send_event);
extern void *WIN_GetWindowICCProfile(SDL_VideoDevice *_this, SDL_Window *window, size_t *size);
extern int WIN_SetWindowMouseRect(SDL_VideoDevice *_this, SDL_Window *window);
extern int WIN_SetWindowMouseGrab(SDL_VideoDevice *_this, SDL_Window *window, SDL_bool grabbed);
extern int WIN_SetWindowKeyboardGrab(SDL_VideoDevice *_this, SDL_Window *window, SDL_bool grabbed);
extern bool WIN_SetWindowMouseRect(SDL_VideoDevice *_this, SDL_Window *window);
extern bool WIN_SetWindowMouseGrab(SDL_VideoDevice *_this, SDL_Window *window, bool grabbed);
extern bool WIN_SetWindowKeyboardGrab(SDL_VideoDevice *_this, SDL_Window *window, bool grabbed);
extern void WIN_DestroyWindow(SDL_VideoDevice *_this, SDL_Window *window);
extern void WIN_OnWindowEnter(SDL_VideoDevice *_this, SDL_Window *window);
extern void WIN_UpdateClipCursor(SDL_Window *window);
extern int WIN_SetWindowHitTest(SDL_Window *window, SDL_bool enabled);
extern void WIN_AcceptDragAndDrop(SDL_Window *window, SDL_bool accept);
extern int WIN_FlashWindow(SDL_VideoDevice *_this, SDL_Window *window, SDL_FlashOperation operation);
extern bool WIN_SetWindowHitTest(SDL_Window *window, bool enabled);
extern void WIN_AcceptDragAndDrop(SDL_Window *window, bool accept);
extern bool WIN_FlashWindow(SDL_VideoDevice *_this, SDL_Window *window, SDL_FlashOperation operation);
extern void WIN_UpdateDarkModeForHWND(HWND hwnd);
extern int WIN_SetWindowPositionInternal(SDL_Window *window, UINT flags, SDL_WindowRect rect_type);
extern bool WIN_SetWindowPositionInternal(SDL_Window *window, UINT flags, SDL_WindowRect rect_type);
extern void WIN_ShowWindowSystemMenu(SDL_Window *window, int x, int y);
extern int WIN_SetWindowFocusable(SDL_VideoDevice *_this, SDL_Window *window, SDL_bool focusable);
extern int WIN_AdjustWindowRect(SDL_Window *window, int *x, int *y, int *width, int *height, SDL_WindowRect rect_type);
extern int WIN_AdjustWindowRectForHWND(HWND hwnd, LPRECT lpRect, UINT frame_dpi);
extern bool WIN_SetWindowFocusable(SDL_VideoDevice *_this, SDL_Window *window, bool focusable);
extern bool WIN_AdjustWindowRect(SDL_Window *window, int *x, int *y, int *width, int *height, SDL_WindowRect rect_type);
extern bool WIN_AdjustWindowRectForHWND(HWND hwnd, LPRECT lpRect, UINT frame_dpi);
extern bool WIN_SetWindowParent(SDL_VideoDevice *_this, SDL_Window *window, SDL_Window *parent);
extern bool WIN_SetWindowModal(SDL_VideoDevice *_this, SDL_Window *window, bool modal);
/* Ends C function definitions when using C++ */
// Ends C function definitions when using C++
#ifdef __cplusplus
}
#endif
#endif /* SDL_windowswindow_h_ */
#endif // SDL_windowswindow_h_