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