summaryrefslogtreecommitdiff
path: root/Source/3rdParty/SDL2/src/video/windows
diff options
context:
space:
mode:
Diffstat (limited to 'Source/3rdParty/SDL2/src/video/windows')
-rw-r--r--Source/3rdParty/SDL2/src/video/windows/SDL_windowsevents.c52
-rw-r--r--Source/3rdParty/SDL2/src/video/windows/SDL_windowsmessagebox.c469
-rw-r--r--Source/3rdParty/SDL2/src/video/windows/SDL_windowsmouse.c2
-rw-r--r--Source/3rdParty/SDL2/src/video/windows/SDL_windowsopengl.h48
-rw-r--r--Source/3rdParty/SDL2/src/video/windows/SDL_windowstaskdialog.h156
-rw-r--r--Source/3rdParty/SDL2/src/video/windows/SDL_windowsvideo.c11
-rw-r--r--Source/3rdParty/SDL2/src/video/windows/SDL_windowsvulkan.c2
-rw-r--r--Source/3rdParty/SDL2/src/video/windows/SDL_windowswindow.c62
-rw-r--r--Source/3rdParty/SDL2/src/video/windows/SDL_windowswindow.h3
9 files changed, 720 insertions, 85 deletions
diff --git a/Source/3rdParty/SDL2/src/video/windows/SDL_windowsevents.c b/Source/3rdParty/SDL2/src/video/windows/SDL_windowsevents.c
index a5fd006..e961cf5 100644
--- a/Source/3rdParty/SDL2/src/video/windows/SDL_windowsevents.c
+++ b/Source/3rdParty/SDL2/src/video/windows/SDL_windowsevents.c
@@ -228,9 +228,7 @@ WIN_CheckWParamMouseButton(SDL_bool bwParamMousePressed, SDL_bool bSDLMousePress
/* Ignore the button click for activation */
if (!bwParamMousePressed) {
data->focus_click_pending &= ~SDL_BUTTON(button);
- if (!data->focus_click_pending) {
- WIN_UpdateClipCursor(data->window);
- }
+ WIN_UpdateClipCursor(data->window);
}
if (WIN_ShouldIgnoreFocusClick()) {
return;
@@ -416,11 +414,23 @@ WIN_WindowProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
}
break;
+ case WM_NCACTIVATE:
+ {
+ /* Don't immediately clip the cursor in case we're clicking minimize/maximize buttons */
+ data->skip_update_clipcursor = SDL_TRUE;
+ }
+ break;
+
case WM_ACTIVATE:
{
POINT cursorPos;
BOOL minimized;
+ /* Don't mark the window as shown if it's activated before being shown */
+ if (!IsWindowVisible(hwnd)) {
+ break;
+ }
+
minimized = HIWORD(wParam);
if (!minimized && (LOWORD(wParam) != WA_INACTIVE)) {
if (LOWORD(wParam) == WA_CLICKACTIVE) {
@@ -460,6 +470,8 @@ WIN_WindowProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
SDL_ToggleModState(KMOD_CAPS, (GetKeyState(VK_CAPITAL) & 0x0001) != 0);
SDL_ToggleModState(KMOD_NUM, (GetKeyState(VK_NUMLOCK) & 0x0001) != 0);
} else {
+ RECT rect;
+
data->in_window_deactivation = SDL_TRUE;
if (SDL_GetKeyboardFocus() == data->window) {
@@ -467,7 +479,10 @@ WIN_WindowProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
WIN_ResetDeadKeys();
}
- ClipCursor(NULL);
+ if (GetClipCursor(&rect) && SDL_memcmp(&rect, &data->cursor_clipped_rect, sizeof(rect) == 0)) {
+ ClipCursor(NULL);
+ SDL_zero(data->cursor_clipped_rect);
+ }
data->in_window_deactivation = SDL_FALSE;
}
@@ -648,7 +663,7 @@ WIN_WindowProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
break;
case WM_UNICHAR:
- if ( wParam == UNICODE_NOCHAR ) {
+ if (wParam == UNICODE_NOCHAR) {
returnCode = 1;
break;
}
@@ -656,8 +671,8 @@ WIN_WindowProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
case WM_CHAR:
{
char text[5];
- if ( WIN_ConvertUTF32toUTF8( (UINT32)wParam, text ) ) {
- SDL_SendKeyboardText( text );
+ if (WIN_ConvertUTF32toUTF8((UINT32)wParam, text)) {
+ SDL_SendKeyboardText(text);
}
}
returnCode = 0;
@@ -1022,6 +1037,20 @@ WIN_WindowProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
}
}
+static void WIN_UpdateClipCursorForWindows()
+{
+ SDL_VideoDevice *_this = SDL_GetVideoDevice();
+ SDL_Window *window;
+
+ if (_this) {
+ for (window = _this->windows; window; window = window->next) {
+ if (window->driverdata) {
+ WIN_UpdateClipCursor(window);
+ }
+ }
+ }
+}
+
/* A message hook called before TranslateMessage() */
static SDL_WindowsMessageHook g_WindowsMessageHook = NULL;
static void *g_WindowsMessageHookData = NULL;
@@ -1067,6 +1096,9 @@ WIN_PumpEvents(_THIS)
if ((keystate[SDL_SCANCODE_RSHIFT] == SDL_PRESSED) && !(GetKeyState(VK_RSHIFT) & 0x8000)) {
SDL_SendKeyboardKey(SDL_RELEASED, SDL_SCANCODE_RSHIFT);
}
+
+ /* Update the clipping rect in case someone else has stolen it */
+ WIN_UpdateClipCursorForWindows();
}
/* to work around #3931, a bug introduced in Win10 Fall Creators Update (build nr. 16299)
@@ -1094,9 +1126,9 @@ IsWin10FCUorNewer(void)
SDL_zero(info);
info.dwOSVersionInfoSize = sizeof(info);
if (getVersionPtr(&info) == 0) { /* STATUS_SUCCESS == 0 */
- if ( (info.dwMajorVersion == 10 && info.dwMinorVersion == 0 && info.dwBuildNumber >= 16299)
- || (info.dwMajorVersion == 10 && info.dwMinorVersion > 0)
- || (info.dwMajorVersion > 10) )
+ if ((info.dwMajorVersion == 10 && info.dwMinorVersion == 0 && info.dwBuildNumber >= 16299) ||
+ (info.dwMajorVersion == 10 && info.dwMinorVersion > 0) ||
+ (info.dwMajorVersion > 10))
{
return SDL_TRUE;
}
diff --git a/Source/3rdParty/SDL2/src/video/windows/SDL_windowsmessagebox.c b/Source/3rdParty/SDL2/src/video/windows/SDL_windowsmessagebox.c
index 924b412..9ddb9e2 100644
--- a/Source/3rdParty/SDL2/src/video/windows/SDL_windowsmessagebox.c
+++ b/Source/3rdParty/SDL2/src/video/windows/SDL_windowsmessagebox.c
@@ -22,16 +22,52 @@
#if SDL_VIDEO_DRIVER_WINDOWS
+#ifdef HAVE_LIMITS_H
+#include <limits.h>
+#else
+#ifndef SIZE_MAX
+#define SIZE_MAX ((size_t)-1)
+#endif
+#endif
+
#include "../../core/windows/SDL_windows.h"
#include "SDL_assert.h"
#include "SDL_windowsvideo.h"
-
+#include "SDL_windowstaskdialog.h"
#ifndef SS_EDITCONTROL
#define SS_EDITCONTROL 0x2000
#endif
+#ifndef IDOK
+#define IDOK 1
+#endif
+
+#ifndef IDCANCEL
+#define IDCANCEL 2
+#endif
+
+/* Custom dialog return codes */
+#define IDCLOSED 20
+#define IDINVALPTRINIT 50
+#define IDINVALPTRCOMMAND 51
+#define IDINVALPTRSETFOCUS 52
+#define IDINVALPTRDLGITEM 53
+/* First button ID */
+#define IDBUTTONINDEX0 100
+
+#define DLGITEMTYPEBUTTON 0x0080
+#define DLGITEMTYPESTATIC 0x0082
+
+/* Windows only sends the lower 16 bits of the control ID when a button
+ * gets clicked. There are also some predefined and custom IDs that lower
+ * the available number further. 2^16 - 101 buttons should be enough for
+ * everyone, no need to make the code more complex.
+ */
+#define MAX_BUTTONS (0xffff - 100)
+
+
/* Display a Windows message box */
#pragma pack(push, 1)
@@ -70,15 +106,79 @@ typedef struct
Uint8 *data;
size_t size;
size_t used;
+ WORD numbuttons;
} WIN_DialogData;
+static SDL_bool GetButtonIndex(const SDL_MessageBoxData *messageboxdata, Uint32 flags, size_t *i)
+{
+ for (*i = 0; *i < (size_t)messageboxdata->numbuttons; ++*i) {
+ if (messageboxdata->buttons[*i].flags & flags) {
+ return SDL_TRUE;
+ }
+ }
+ return SDL_FALSE;
+}
static INT_PTR MessageBoxDialogProc(HWND hDlg, UINT iMessage, WPARAM wParam, LPARAM lParam)
{
+ const SDL_MessageBoxData *messageboxdata;
+ size_t buttonindex;
+
switch ( iMessage ) {
+ case WM_INITDIALOG:
+ if (lParam == 0) {
+ EndDialog(hDlg, IDINVALPTRINIT);
+ return TRUE;
+ }
+ messageboxdata = (const SDL_MessageBoxData *)lParam;
+ SetWindowLongPtr(hDlg, GWLP_USERDATA, lParam);
+
+ if (GetButtonIndex(messageboxdata, SDL_MESSAGEBOX_BUTTON_RETURNKEY_DEFAULT, &buttonindex)) {
+ /* Focus on the first default return-key button */
+ HWND buttonctl = GetDlgItem(hDlg, (int)(IDBUTTONINDEX0 + buttonindex));
+ if (buttonctl == NULL) {
+ EndDialog(hDlg, IDINVALPTRDLGITEM);
+ }
+ PostMessage(hDlg, WM_NEXTDLGCTL, (WPARAM)buttonctl, TRUE);
+ } else {
+ /* Give the focus to the dialog window instead */
+ SetFocus(hDlg);
+ }
+ return FALSE;
+ case WM_SETFOCUS:
+ messageboxdata = (const SDL_MessageBoxData *)GetWindowLongPtr(hDlg, GWLP_USERDATA);
+ if (messageboxdata == NULL) {
+ EndDialog(hDlg, IDINVALPTRSETFOCUS);
+ return TRUE;
+ }
+
+ /* 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;
+ }
+ return TRUE;
case WM_COMMAND:
+ messageboxdata = (const SDL_MessageBoxData *)GetWindowLongPtr(hDlg, GWLP_USERDATA);
+ if (messageboxdata == NULL) {
+ EndDialog(hDlg, IDINVALPTRCOMMAND);
+ return TRUE;
+ }
+
/* Return the ID of the button that was pushed */
- EndDialog(hDlg, LOWORD(wParam));
+ if (wParam == IDOK) {
+ if (GetButtonIndex(messageboxdata, SDL_MESSAGEBOX_BUTTON_RETURNKEY_DEFAULT, &buttonindex)) {
+ EndDialog(hDlg, IDBUTTONINDEX0 + buttonindex);
+ }
+ } else if (wParam == IDCANCEL) {
+ 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. */
+ EndDialog(hDlg, IDCLOSED);
+ }
+ } else if (wParam >= IDBUTTONINDEX0 && (int)wParam - IDBUTTONINDEX0 < messageboxdata->numbuttons) {
+ EndDialog(hDlg, wParam);
+ }
return TRUE;
default:
@@ -89,15 +189,30 @@ static INT_PTR MessageBoxDialogProc(HWND hDlg, UINT iMessage, WPARAM wParam, LPA
static SDL_bool ExpandDialogSpace(WIN_DialogData *dialog, size_t space)
{
+ /* Growing memory in 64 KiB steps. */
+ const size_t sizestep = 0x10000;
size_t size = dialog->size;
if (size == 0) {
- size = space;
- } else {
- while ((dialog->used + space) > size) {
- size *= 2;
+ /* Start with 4 KiB or a multiple of 64 KiB to fit the data. */
+ size = 0x1000;
+ if (SIZE_MAX - sizestep < space) {
+ size = space;
+ } else if (space > size) {
+ size = (space + sizestep) & ~(sizestep - 1);
}
+ } else if (SIZE_MAX - dialog->used < space) {
+ SDL_OutOfMemory();
+ return SDL_FALSE;
+ } else if (SIZE_MAX - (dialog->used + space) < sizestep) {
+ /* Close to the maximum. */
+ size = dialog->used + space;
+ } else if (size < dialog->used + space) {
+ /* Round up to the next 64 KiB block. */
+ size = dialog->used + space;
+ size += sizestep - size % sizestep;
}
+
if (size > dialog->size) {
void *data = SDL_realloc(dialog->data, size);
if (!data) {
@@ -175,7 +290,7 @@ static void Vec2ToDLU(short *x, short *y)
}
-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)
+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)
{
DLGITEMTEMPLATEEX item;
WORD marker = 0xFFFF;
@@ -205,32 +320,54 @@ static SDL_bool AddDialogControl(WIN_DialogData *dialog, WORD type, DWORD style,
if (!AddDialogData(dialog, &type, sizeof(type))) {
return SDL_FALSE;
}
- if (!AddDialogString(dialog, caption)) {
- return SDL_FALSE;
+ if (type == DLGITEMTYPEBUTTON || (type == DLGITEMTYPESTATIC && caption != NULL)) {
+ if (!AddDialogString(dialog, caption)) {
+ return SDL_FALSE;
+ }
+ } else {
+ if (!AddDialogData(dialog, &marker, sizeof(marker))) {
+ return SDL_FALSE;
+ }
+ if (!AddDialogData(dialog, &ordinal, sizeof(ordinal))) {
+ return SDL_FALSE;
+ }
}
if (!AddDialogData(dialog, &extraData, sizeof(extraData))) {
return SDL_FALSE;
}
+ if (type == DLGITEMTYPEBUTTON) {
+ dialog->numbuttons++;
+ }
++dialog->lpDialog->cDlgItems;
return SDL_TRUE;
}
-static SDL_bool AddDialogStatic(WIN_DialogData *dialog, int x, int y, int w, int h, const char *text)
+static SDL_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;
- return AddDialogControl(dialog, 0x0082, style, 0, x, y, w, h, -1, 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)
+{
+ 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)
{
- DWORD style = WS_VISIBLE | WS_CHILD;
+ DWORD style = WS_VISIBLE | WS_CHILD | WS_TABSTOP;
if (isDefault) {
style |= BS_DEFPUSHBUTTON;
} else {
style |= BS_PUSHBUTTON;
}
- return AddDialogControl(dialog, 0x0080, style, 0, x, y, w, h, id, text);
+ /* The first button marks the start of the group. */
+ if (dialog->numbuttons == 0) {
+ style |= WS_GROUP;
+ }
+ return AddDialogControl(dialog, DLGITEMTYPEBUTTON, style, 0, x, y, w, h, IDBUTTONINDEX0 + dialog->numbuttons, text, 0);
}
static void FreeDialogData(WIN_DialogData *dialog)
@@ -341,17 +478,87 @@ static WIN_DialogData *CreateDialogData(int w, int h, const char *caption)
return dialog;
}
-int
-WIN_ShowMessageBox(const SDL_MessageBoxData *messageboxdata, int *buttonid)
+/* Escaping ampersands is necessary to disable mnemonics in dialog controls.
+ * The caller provides a char** for dst and a size_t* for dstlen where the
+ * address of the work buffer and its size will be stored. Their values must be
+ * NULL and 0 on the first call. src is the string to be escaped. On error, the
+ * function returns NULL and, on success, returns a pointer to the escaped
+ * sequence as a read-only string that is valid until the next call or until the
+ * work buffer is freed. Once all strings have been processed, it's the caller's
+ * responsibilty to free the work buffer with SDL_free, even on errors.
+ */
+static const char *EscapeAmpersands(char **dst, size_t *dstlen, const char *src)
+{
+ char *newdst;
+ size_t ampcount = 0;
+ size_t srclen = 0;
+
+ if (src == NULL) {
+ return NULL;
+ }
+
+ while (src[srclen]) {
+ if (src[srclen] == '&') {
+ ampcount++;
+ }
+ srclen++;
+ }
+ srclen++;
+
+ if (ampcount == 0) {
+ /* Nothing to do. */
+ return src;
+ }
+ if (SIZE_MAX - srclen < ampcount) {
+ return NULL;
+ }
+ if (*dst == NULL || *dstlen < srclen + ampcount) {
+ /* Allocating extra space in case the next strings are a bit longer. */
+ size_t extraspace = SIZE_MAX - (srclen + ampcount);
+ if (extraspace > 512) {
+ extraspace = 512;
+ }
+ *dstlen = srclen + ampcount + extraspace;
+ SDL_free(*dst);
+ *dst = NULL;
+ newdst = SDL_malloc(*dstlen);
+ if (newdst == NULL) {
+ return NULL;
+ }
+ *dst = newdst;
+ } else {
+ newdst = *dst;
+ }
+
+ /* The escape character is the ampersand itself. */
+ while (srclen--) {
+ if (*src == '&') {
+ *newdst++ = '&';
+ }
+ *newdst++ = *src++;
+ }
+
+ return *dst;
+}
+
+/* This function is called if a Task Dialog is unsupported. */
+static int
+WIN_ShowOldMessageBox(const SDL_MessageBoxData *messageboxdata, int *buttonid)
{
WIN_DialogData *dialog;
- int i, x, y;
+ int i, x, y, retval;
const SDL_MessageBoxButtonData *buttons = messageboxdata->buttons;
HFONT DialogFont;
SIZE Size;
RECT TextSize;
wchar_t* wmessage;
TEXTMETRIC TM;
+ HDC FontDC;
+ INT_PTR result;
+ char *ampescape = NULL;
+ size_t ampescapesize = 0;
+ Uint16 defbuttoncount = 0;
+ Uint16 icon = 0;
HWND ParentWindow = NULL;
@@ -359,7 +566,25 @@ WIN_ShowMessageBox(const SDL_MessageBoxData *messageboxdata, int *buttonid)
const int ButtonHeight = 26;
const int TextMargin = 16;
const int ButtonMargin = 12;
+ const int IconWidth = GetSystemMetrics(SM_CXICON);
+ const int IconHeight = GetSystemMetrics(SM_CYICON);
+ const int IconMargin = 20;
+
+ if (messageboxdata->numbuttons > MAX_BUTTONS) {
+ return SDL_SetError("Number of butons exceeds limit of %d", MAX_BUTTONS);
+ }
+ switch (messageboxdata->flags) {
+ case SDL_MESSAGEBOX_ERROR:
+ icon = (Uint16)(size_t)IDI_ERROR;
+ break;
+ case SDL_MESSAGEBOX_WARNING:
+ icon = (Uint16)(size_t)IDI_WARNING;
+ break;
+ case SDL_MESSAGEBOX_INFORMATION:
+ icon = (Uint16)(size_t)IDI_INFORMATION;
+ break;
+ }
/* Jan 25th, 2013 - dant@fleetsa.com
*
@@ -393,7 +618,7 @@ WIN_ShowMessageBox(const SDL_MessageBoxData *messageboxdata, int *buttonid)
* In order to get text dimensions we need to have a DC with the desired font.
* I'm assuming a dialog box in SDL is rare enough we can to the create.
*/
- HDC FontDC = CreateCompatibleDC(0);
+ FontDC = CreateCompatibleDC(0);
{
/* Create a duplicate of the font used in system message boxes. */
@@ -428,11 +653,13 @@ WIN_ShowMessageBox(const SDL_MessageBoxData *messageboxdata, int *buttonid)
/* Measure the *pixel* size of the string. */
wmessage = WIN_UTF8ToString(messageboxdata->message);
SDL_zero(TextSize);
- DrawText(FontDC, wmessage, -1, &TextSize, DT_CALCRECT);
+ DrawText(FontDC, wmessage, -1, &TextSize, DT_CALCRECT | DT_LEFT | DT_NOPREFIX | DT_EDITCONTROL);
- /* Add some padding for hangs, etc. */
- TextSize.right += 2;
- TextSize.bottom += 2;
+ /* 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 */
DeleteDC(FontDC);
@@ -444,10 +671,22 @@ WIN_ShowMessageBox(const SDL_MessageBoxData *messageboxdata, int *buttonid)
Size.cx += TextMargin * 2;
Size.cy += TextMargin * 2;
+ /* 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. */
if (Size.cx < messageboxdata->numbuttons * (ButtonWidth + ButtonMargin) + ButtonMargin)
Size.cx = messageboxdata->numbuttons * (ButtonWidth + ButtonMargin) + ButtonMargin;
+ /* Reset the height to the icon size if it is actually bigger than the text. */
+ if (icon && Size.cy < IconMargin * 2 + IconHeight) {
+ Size.cy = IconMargin * 2 + IconHeight;
+ }
+
/* Add vertical space for the buttons and border. */
Size.cy += ButtonHeight + TextMargin;
@@ -456,7 +695,12 @@ WIN_ShowMessageBox(const SDL_MessageBoxData *messageboxdata, int *buttonid)
return -1;
}
- if (!AddDialogStatic(dialog, TextMargin, TextMargin, TextSize.right - TextSize.left, TextSize.bottom - TextSize.top, messageboxdata->message)) {
+ if (icon && ! AddDialogStaticIcon(dialog, IconMargin, IconMargin, IconWidth, IconHeight, icon)) {
+ FreeDialogData(dialog);
+ return -1;
+ }
+
+ if (!AddDialogStaticText(dialog, TextSize.left, TextSize.top, TextSize.right - TextSize.left, TextSize.bottom - TextSize.top, messageboxdata->message)) {
FreeDialogData(dialog);
return -1;
}
@@ -465,19 +709,25 @@ WIN_ShowMessageBox(const SDL_MessageBoxData *messageboxdata, int *buttonid)
x = Size.cx - (ButtonWidth + ButtonMargin) * messageboxdata->numbuttons;
y = Size.cy - ButtonHeight - ButtonMargin;
for (i = messageboxdata->numbuttons - 1; i >= 0; --i) {
- SDL_bool isDefault;
+ SDL_bool isdefault = SDL_FALSE;
+ const char *buttontext;
if (buttons[i].flags & SDL_MESSAGEBOX_BUTTON_RETURNKEY_DEFAULT) {
- isDefault = SDL_TRUE;
- } else {
- isDefault = SDL_FALSE;
+ defbuttoncount++;
+ if (defbuttoncount == 1) {
+ isdefault = SDL_TRUE;
+ }
}
- if (!AddDialogButton(dialog, x, y, ButtonWidth, ButtonHeight, buttons[i].text, buttons[i].buttonid, isDefault)) {
+
+ buttontext = EscapeAmpersands(&ampescape, &ampescapesize, buttons[i].text);
+ if (buttontext == NULL || !AddDialogButton(dialog, x, y, ButtonWidth, ButtonHeight, buttontext, buttons[i].buttonid, isdefault)) {
FreeDialogData(dialog);
+ SDL_free(ampescape);
return -1;
}
x += ButtonWidth + ButtonMargin;
}
+ SDL_free(ampescape);
/* If we have a parent window, get the Instance and HWND for them
* so that our little dialog gets exclusive focus at all times. */
@@ -485,10 +735,169 @@ WIN_ShowMessageBox(const SDL_MessageBoxData *messageboxdata, int *buttonid)
ParentWindow = ((SDL_WindowData*)messageboxdata->window->driverdata)->hwnd;
}
- *buttonid = (int)DialogBoxIndirect(NULL, (DLGTEMPLATE*)dialog->lpDialog, ParentWindow, (DLGPROC)MessageBoxDialogProc);
+ result = DialogBoxIndirectParam(NULL, (DLGTEMPLATE*)dialog->lpDialog, ParentWindow, (DLGPROC)MessageBoxDialogProc, (LPARAM)messageboxdata);
+ if (result >= IDBUTTONINDEX0 && result - IDBUTTONINDEX0 < messageboxdata->numbuttons) {
+ *buttonid = messageboxdata->buttons[(messageboxdata->numbuttons - 1) - (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;
+ *buttonid = -1;
+ } else {
+ if (result == 0) {
+ SDL_SetError("Invalid parent window handle");
+ } else if (result == -1) {
+ SDL_SetError("The message box encountered an error.");
+ } else if (result == IDINVALPTRINIT || result == IDINVALPTRSETFOCUS || result == IDINVALPTRCOMMAND) {
+ SDL_SetError("Invalid message box pointer in dialog procedure");
+ } else if (result == IDINVALPTRDLGITEM) {
+ SDL_SetError("Couldn't find dialog control of the default enter-key button");
+ } else {
+ SDL_SetError("An unknown error occured");
+ }
+ retval = -1;
+ }
FreeDialogData(dialog);
- return 0;
+ return retval;
+}
+
+/* TaskDialogIndirect procedure
+ * This is because SDL targets Windows XP (0x501), so this is not defined in the platform SDK.
+ */
+typedef HRESULT(FAR WINAPI *TASKDIALOGINDIRECTPROC)(const TASKDIALOGCONFIG *pTaskConfig, int *pnButton, int *pnRadioButton, BOOL *pfVerificationFlagChecked);
+
+int
+WIN_ShowMessageBox(const SDL_MessageBoxData *messageboxdata, int *buttonid)
+{
+ HWND ParentWindow = NULL;
+ wchar_t *wmessage;
+ wchar_t *wtitle;
+ TASKDIALOGCONFIG TaskConfig;
+ TASKDIALOG_BUTTON *pButtons;
+ TASKDIALOG_BUTTON *pButton;
+ HMODULE hComctl32;
+ TASKDIALOGINDIRECTPROC pfnTaskDialogIndirect;
+ HRESULT hr;
+ char *ampescape = NULL;
+ size_t ampescapesize = 0;
+ int nButton;
+ int nCancelButton;
+ int i;
+
+ if (SIZE_MAX / sizeof(TASKDIALOG_BUTTON) < messageboxdata->numbuttons) {
+ return SDL_OutOfMemory();
+ }
+
+ /* If we cannot load comctl32.dll use the old messagebox! */
+ hComctl32 = LoadLibrary(TEXT("Comctl32.dll"));
+ if (hComctl32 == NULL) {
+ return WIN_ShowOldMessageBox(messageboxdata, buttonid);
+ }
+
+ /* If TaskDialogIndirect doesn't exist use the old messagebox!
+ This will fail prior to Windows Vista.
+ The manifest file in the application may require targeting version 6 of comctl32.dll, even
+ when we use LoadLibrary here!
+ If you don't want to bother with manifests, put this #pragma in your app's source code somewhere:
+ pragma comment(linker,"\"/manifestdependency:type='win32' name='Microsoft.Windows.Common-Controls' version='6.0.0.0' processorArchitecture='*' publicKeyToken='6595b64144ccf1df' language='*'\"")
+ */
+ pfnTaskDialogIndirect = (TASKDIALOGINDIRECTPROC) GetProcAddress(hComctl32, "TaskDialogIndirect");
+ if (pfnTaskDialogIndirect == NULL) {
+ FreeLibrary(hComctl32);
+ return WIN_ShowOldMessageBox(messageboxdata, 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 = ((SDL_WindowData *) messageboxdata->window->driverdata)->hwnd;
+ }
+
+ wmessage = WIN_UTF8ToString(messageboxdata->message);
+ wtitle = WIN_UTF8ToString(messageboxdata->title);
+
+ SDL_zero(TaskConfig);
+ TaskConfig.cbSize = sizeof (TASKDIALOGCONFIG);
+ TaskConfig.hwndParent = ParentWindow;
+ TaskConfig.dwFlags = TDF_SIZE_TO_CONTENT;
+ TaskConfig.pszWindowTitle = wtitle;
+ if (messageboxdata->flags & SDL_MESSAGEBOX_ERROR) {
+ TaskConfig.pszMainIcon = TD_ERROR_ICON;
+ } else if (messageboxdata->flags & SDL_MESSAGEBOX_WARNING) {
+ TaskConfig.pszMainIcon = TD_WARNING_ICON;
+ } else if (messageboxdata->flags & SDL_MESSAGEBOX_INFORMATION) {
+ TaskConfig.pszMainIcon = TD_INFORMATION_ICON;
+ } else {
+ TaskConfig.pszMainIcon = NULL;
+ }
+
+ TaskConfig.pszContent = wmessage;
+ TaskConfig.cButtons = messageboxdata->numbuttons;
+ pButtons = SDL_malloc(sizeof (TASKDIALOG_BUTTON) * messageboxdata->numbuttons);
+ TaskConfig.nDefaultButton = 0;
+ nCancelButton = 0;
+ for (i = 0; i < messageboxdata->numbuttons; i++)
+ {
+ const char *buttontext;
+ pButton = &pButtons[messageboxdata->numbuttons-1-i];
+ if (messageboxdata->buttons[i].flags & SDL_MESSAGEBOX_BUTTON_ESCAPEKEY_DEFAULT) {
+ nCancelButton = messageboxdata->buttons[i].buttonid;
+ pButton->nButtonID = 2;
+ } else {
+ pButton->nButtonID = messageboxdata->buttons[i].buttonid + 1;
+ if (pButton->nButtonID >= 2) {
+ pButton->nButtonID++;
+ }
+ }
+ buttontext = EscapeAmpersands(&ampescape, &ampescapesize, messageboxdata->buttons[i].text);
+ if (buttontext == NULL) {
+ int j;
+ FreeLibrary(hComctl32);
+ SDL_free(ampescape);
+ SDL_free(wmessage);
+ SDL_free(wtitle);
+ for (j = 0; j < i; j++) {
+ SDL_free((wchar_t *) pButtons[j].pszButtonText);
+ }
+ SDL_free(pButtons);
+ return -1;
+ }
+ pButton->pszButtonText = WIN_UTF8ToString(buttontext);
+ if (messageboxdata->buttons[i].flags & SDL_MESSAGEBOX_BUTTON_RETURNKEY_DEFAULT) {
+ TaskConfig.nDefaultButton = pButton->nButtonID;
+ }
+ }
+ TaskConfig.pButtons = pButtons;
+
+ /* Show the Task Dialog */
+ hr = pfnTaskDialogIndirect(&TaskConfig, &nButton, NULL, NULL);
+
+ /* Free everything */
+ FreeLibrary(hComctl32);
+ SDL_free(ampescape);
+ SDL_free(wmessage);
+ SDL_free(wtitle);
+ for (i = 0; i < messageboxdata->numbuttons; i++) {
+ SDL_free((wchar_t *) pButtons[i].pszButtonText);
+ }
+ SDL_free(pButtons);
+
+ /* Check the Task Dialog was successful and give the result */
+ if (SUCCEEDED(hr)) {
+ if (nButton == 2) {
+ *buttonid = nCancelButton;
+ } else if (nButton > 2) {
+ *buttonid = nButton-1-1;
+ } else {
+ *buttonid = nButton-1;
+ }
+ return 0;
+ }
+
+ /* We failed showing the Task Dialog, use the old message box! */
+ return WIN_ShowOldMessageBox(messageboxdata, buttonid);
}
#endif /* SDL_VIDEO_DRIVER_WINDOWS */
diff --git a/Source/3rdParty/SDL2/src/video/windows/SDL_windowsmouse.c b/Source/3rdParty/SDL2/src/video/windows/SDL_windowsmouse.c
index 1ddeae2..eff3160 100644
--- a/Source/3rdParty/SDL2/src/video/windows/SDL_windowsmouse.c
+++ b/Source/3rdParty/SDL2/src/video/windows/SDL_windowsmouse.c
@@ -304,8 +304,6 @@ WIN_InitMouse(_THIS)
mouse->GetGlobalMouseState = WIN_GetGlobalMouseState;
SDL_SetDefaultCursor(WIN_CreateDefaultCursor());
-
- SDL_SetDoubleClickTime(GetDoubleClickTime());
}
void
diff --git a/Source/3rdParty/SDL2/src/video/windows/SDL_windowsopengl.h b/Source/3rdParty/SDL2/src/video/windows/SDL_windowsopengl.h
index 75b4898..8704411 100644
--- a/Source/3rdParty/SDL2/src/video/windows/SDL_windowsopengl.h
+++ b/Source/3rdParty/SDL2/src/video/windows/SDL_windowsopengl.h
@@ -33,31 +33,31 @@ struct SDL_GLDriverData
SDL_bool HAS_WGL_ARB_create_context_robustness;
SDL_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.
- major = minor = 0 when unsupported.
- */
- struct {
- int major;
- int minor;
- } es_profile_max_supported_version;
+ /* Max version of OpenGL ES context that can be created if the
+ implementation supports WGL_EXT_create_context_es2_profile.
+ major = minor = 0 when unsupported.
+ */
+ struct {
+ int major;
+ int minor;
+ } es_profile_max_supported_version;
- void *(WINAPI * wglGetProcAddress) (const char *proc);
- HGLRC(WINAPI * wglCreateContext) (HDC hdc);
- BOOL(WINAPI * wglDeleteContext) (HGLRC hglrc);
- BOOL(WINAPI * wglMakeCurrent) (HDC hdc, HGLRC hglrc);
- BOOL(WINAPI * wglShareLists) (HGLRC hglrc1, HGLRC hglrc2);
- BOOL(WINAPI * wglChoosePixelFormatARB) (HDC hdc,
- const int *piAttribIList,
- const FLOAT * pfAttribFList,
- UINT nMaxFormats,
- int *piFormats,
- UINT * nNumFormats);
- BOOL(WINAPI * wglGetPixelFormatAttribivARB) (HDC hdc, int iPixelFormat,
- int iLayerPlane,
- UINT nAttributes,
- const int *piAttributes,
- int *piValues);
+ void *(WINAPI * wglGetProcAddress) (const char *proc);
+ HGLRC(WINAPI * wglCreateContext) (HDC hdc);
+ BOOL(WINAPI * wglDeleteContext) (HGLRC hglrc);
+ BOOL(WINAPI * wglMakeCurrent) (HDC hdc, HGLRC hglrc);
+ BOOL(WINAPI * wglShareLists) (HGLRC hglrc1, HGLRC hglrc2);
+ BOOL(WINAPI * wglChoosePixelFormatARB) (HDC hdc,
+ const int *piAttribIList,
+ const FLOAT * pfAttribFList,
+ UINT nMaxFormats,
+ int *piFormats,
+ UINT * nNumFormats);
+ BOOL(WINAPI * wglGetPixelFormatAttribivARB) (HDC hdc, int iPixelFormat,
+ int iLayerPlane,
+ UINT nAttributes,
+ const int *piAttributes,
+ int *piValues);
BOOL (WINAPI * wglSwapIntervalEXT) (int interval);
int (WINAPI * wglGetSwapIntervalEXT) (void);
};
diff --git a/Source/3rdParty/SDL2/src/video/windows/SDL_windowstaskdialog.h b/Source/3rdParty/SDL2/src/video/windows/SDL_windowstaskdialog.h
new file mode 100644
index 0000000..a2a9e8a
--- /dev/null
+++ b/Source/3rdParty/SDL2/src/video/windows/SDL_windowstaskdialog.h
@@ -0,0 +1,156 @@
+/*
+ Simple DirectMedia Layer
+ Copyright (C) 1997-2018 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 <pshpack1.h>
+
+typedef HRESULT(CALLBACK *PFTASKDIALOGCALLBACK)(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam, LONG_PTR lpRefData);
+
+enum _TASKDIALOG_FLAGS
+{
+ TDF_ENABLE_HYPERLINKS = 0x0001,
+ TDF_USE_HICON_MAIN = 0x0002,
+ TDF_USE_HICON_FOOTER = 0x0004,
+ TDF_ALLOW_DIALOG_CANCELLATION = 0x0008,
+ TDF_USE_COMMAND_LINKS = 0x0010,
+ TDF_USE_COMMAND_LINKS_NO_ICON = 0x0020,
+ TDF_EXPAND_FOOTER_AREA = 0x0040,
+ TDF_EXPANDED_BY_DEFAULT = 0x0080,
+ TDF_VERIFICATION_FLAG_CHECKED = 0x0100,
+ TDF_SHOW_PROGRESS_BAR = 0x0200,
+ TDF_SHOW_MARQUEE_PROGRESS_BAR = 0x0400,
+ TDF_CALLBACK_TIMER = 0x0800,
+ TDF_POSITION_RELATIVE_TO_WINDOW = 0x1000,
+ TDF_RTL_LAYOUT = 0x2000,
+ TDF_NO_DEFAULT_RADIO_BUTTON = 0x4000,
+ TDF_CAN_BE_MINIMIZED = 0x8000,
+ //#if (NTDDI_VERSION >= NTDDI_WIN8)
+ TDF_NO_SET_FOREGROUND = 0x00010000, // Don't call SetForegroundWindow() when activating the dialog
+ //#endif // (NTDDI_VERSION >= NTDDI_WIN8)
+ TDF_SIZE_TO_CONTENT = 0x01000000 // used by ShellMessageBox to emulate MessageBox sizing behavior
+};
+typedef int TASKDIALOG_FLAGS; // Note: _TASKDIALOG_FLAGS is an int
+
+typedef enum _TASKDIALOG_MESSAGES
+{
+ TDM_NAVIGATE_PAGE = WM_USER + 101,
+ TDM_CLICK_BUTTON = WM_USER + 102, // wParam = Button ID
+ TDM_SET_MARQUEE_PROGRESS_BAR = WM_USER + 103, // wParam = 0 (nonMarque) wParam != 0 (Marquee)
+ TDM_SET_PROGRESS_BAR_STATE = WM_USER + 104, // wParam = new progress state
+ TDM_SET_PROGRESS_BAR_RANGE = WM_USER + 105, // lParam = MAKELPARAM(nMinRange, nMaxRange)
+ TDM_SET_PROGRESS_BAR_POS = WM_USER + 106, // wParam = new position
+ TDM_SET_PROGRESS_BAR_MARQUEE = WM_USER + 107, // wParam = 0 (stop marquee), wParam != 0 (start marquee), lparam = speed (milliseconds between repaints)
+ TDM_SET_ELEMENT_TEXT = WM_USER + 108, // wParam = element (TASKDIALOG_ELEMENTS), lParam = new element text (LPCWSTR)
+ TDM_CLICK_RADIO_BUTTON = WM_USER + 110, // wParam = Radio Button ID
+ TDM_ENABLE_BUTTON = WM_USER + 111, // lParam = 0 (disable), lParam != 0 (enable), wParam = Button ID
+ TDM_ENABLE_RADIO_BUTTON = WM_USER + 112, // lParam = 0 (disable), lParam != 0 (enable), wParam = Radio Button ID
+ TDM_CLICK_VERIFICATION = WM_USER + 113, // wParam = 0 (unchecked), 1 (checked), lParam = 1 (set key focus)
+ TDM_UPDATE_ELEMENT_TEXT = WM_USER + 114, // wParam = element (TASKDIALOG_ELEMENTS), lParam = new element text (LPCWSTR)
+ TDM_SET_BUTTON_ELEVATION_REQUIRED_STATE = WM_USER + 115, // wParam = Button ID, lParam = 0 (elevation not required), lParam != 0 (elevation required)
+ TDM_UPDATE_ICON = WM_USER + 116 // wParam = icon element (TASKDIALOG_ICON_ELEMENTS), lParam = new icon (hIcon if TDF_USE_HICON_* was set, PCWSTR otherwise)
+} TASKDIALOG_MESSAGES;
+
+typedef enum _TASKDIALOG_NOTIFICATIONS
+{
+ TDN_CREATED = 0,
+ TDN_NAVIGATED = 1,
+ TDN_BUTTON_CLICKED = 2, // wParam = Button ID
+ TDN_HYPERLINK_CLICKED = 3, // lParam = (LPCWSTR)pszHREF
+ TDN_TIMER = 4, // wParam = Milliseconds since dialog created or timer reset
+ TDN_DESTROYED = 5,
+ TDN_RADIO_BUTTON_CLICKED = 6, // wParam = Radio Button ID
+ TDN_DIALOG_CONSTRUCTED = 7,
+ TDN_VERIFICATION_CLICKED = 8, // wParam = 1 if checkbox checked, 0 if not, lParam is unused and always 0
+ TDN_HELP = 9,
+ TDN_EXPANDO_BUTTON_CLICKED = 10 // wParam = 0 (dialog is now collapsed), wParam != 0 (dialog is now expanded)
+} TASKDIALOG_NOTIFICATIONS;
+
+typedef struct _TASKDIALOG_BUTTON
+{
+ int nButtonID;
+ PCWSTR pszButtonText;
+} TASKDIALOG_BUTTON;
+
+typedef enum _TASKDIALOG_ELEMENTS
+{
+ TDE_CONTENT,
+ TDE_EXPANDED_INFORMATION,
+ TDE_FOOTER,
+ TDE_MAIN_INSTRUCTION
+} TASKDIALOG_ELEMENTS;
+
+typedef enum _TASKDIALOG_ICON_ELEMENTS
+{
+ TDIE_ICON_MAIN,
+ TDIE_ICON_FOOTER
+} TASKDIALOG_ICON_ELEMENTS;
+
+#define TD_WARNING_ICON MAKEINTRESOURCEW(-1)
+#define TD_ERROR_ICON MAKEINTRESOURCEW(-2)
+#define TD_INFORMATION_ICON MAKEINTRESOURCEW(-3)
+#define TD_SHIELD_ICON MAKEINTRESOURCEW(-4)
+
+enum _TASKDIALOG_COMMON_BUTTON_FLAGS
+{
+ TDCBF_OK_BUTTON = 0x0001, // selected control return value IDOK
+ TDCBF_YES_BUTTON = 0x0002, // selected control return value IDYES
+ TDCBF_NO_BUTTON = 0x0004, // selected control return value IDNO
+ TDCBF_CANCEL_BUTTON = 0x0008, // selected control return value IDCANCEL
+ TDCBF_RETRY_BUTTON = 0x0010, // selected control return value IDRETRY
+ TDCBF_CLOSE_BUTTON = 0x0020 // selected control return value IDCLOSE
+};
+typedef int TASKDIALOG_COMMON_BUTTON_FLAGS; // Note: _TASKDIALOG_COMMON_BUTTON_FLAGS is an int
+
+typedef struct _TASKDIALOGCONFIG
+{
+ UINT cbSize;
+ HWND hwndParent; // incorrectly named, this is the owner window, not a parent.
+ HINSTANCE hInstance; // used for MAKEINTRESOURCE() strings
+ TASKDIALOG_FLAGS dwFlags; // TASKDIALOG_FLAGS (TDF_XXX) flags
+ TASKDIALOG_COMMON_BUTTON_FLAGS dwCommonButtons; // TASKDIALOG_COMMON_BUTTON (TDCBF_XXX) flags
+ PCWSTR pszWindowTitle; // string or MAKEINTRESOURCE()
+ union
+ {
+ HICON hMainIcon;
+ PCWSTR pszMainIcon;
+ } /*DUMMYUNIONNAME*/;
+ PCWSTR pszMainInstruction;
+ PCWSTR pszContent;
+ UINT cButtons;
+ const TASKDIALOG_BUTTON *pButtons;
+ int nDefaultButton;
+ UINT cRadioButtons;
+ const TASKDIALOG_BUTTON *pRadioButtons;
+ int nDefaultRadioButton;
+ PCWSTR pszVerificationText;
+ PCWSTR pszExpandedInformation;
+ PCWSTR pszExpandedControlText;
+ PCWSTR pszCollapsedControlText;
+ union
+ {
+ HICON hFooterIcon;
+ PCWSTR pszFooterIcon;
+ } /*DUMMYUNIONNAME2*/;
+ PCWSTR pszFooter;
+ PFTASKDIALOGCALLBACK pfCallback;
+ LONG_PTR lpCallbackData;
+ UINT cxWidth; // width of the Task Dialog's client area in DLU's. If 0, Task Dialog will calculate the ideal width.
+} TASKDIALOGCONFIG;
+
+#include <poppack.h>
diff --git a/Source/3rdParty/SDL2/src/video/windows/SDL_windowsvideo.c b/Source/3rdParty/SDL2/src/video/windows/SDL_windowsvideo.c
index 8d45b72..358ab23 100644
--- a/Source/3rdParty/SDL2/src/video/windows/SDL_windowsvideo.c
+++ b/Source/3rdParty/SDL2/src/video/windows/SDL_windowsvideo.c
@@ -63,6 +63,15 @@ UpdateWindowFrameUsableWhileCursorHidden(void *userdata, const char *name, const
}
}
+static void WIN_SuspendScreenSaver(_THIS)
+{
+ if (_this->suspend_screensaver) {
+ SetThreadExecutionState(ES_CONTINUOUS | ES_DISPLAY_REQUIRED);
+ } else {
+ SetThreadExecutionState(ES_CONTINUOUS);
+ }
+}
+
/* Windows driver bootstrap functions */
@@ -136,6 +145,7 @@ WIN_CreateDevice(int devindex)
device->GetDisplayModes = WIN_GetDisplayModes;
device->SetDisplayMode = WIN_SetDisplayMode;
device->PumpEvents = WIN_PumpEvents;
+ device->SuspendScreenSaver = WIN_SuspendScreenSaver;
device->CreateSDLWindow = WIN_CreateWindow;
device->CreateSDLWindowFrom = WIN_CreateWindowFrom;
@@ -164,6 +174,7 @@ WIN_CreateDevice(int devindex)
device->DestroyWindowFramebuffer = WIN_DestroyWindowFramebuffer;
device->OnWindowEnter = WIN_OnWindowEnter;
device->SetWindowHitTest = WIN_SetWindowHitTest;
+ device->AcceptDragAndDrop = WIN_AcceptDragAndDrop;
device->shape_driver.CreateShaper = Win32_CreateShaper;
device->shape_driver.SetWindowShape = Win32_SetWindowShape;
diff --git a/Source/3rdParty/SDL2/src/video/windows/SDL_windowsvulkan.c b/Source/3rdParty/SDL2/src/video/windows/SDL_windowsvulkan.c
index c4b34f0..6bb8f2a 100644
--- a/Source/3rdParty/SDL2/src/video/windows/SDL_windowsvulkan.c
+++ b/Source/3rdParty/SDL2/src/video/windows/SDL_windowsvulkan.c
@@ -40,7 +40,7 @@ int WIN_Vulkan_LoadLibrary(_THIS, const char *path)
{
VkExtensionProperties *extensions = NULL;
Uint32 extensionCount = 0;
- Uint32 i;
+ Uint32 i;
SDL_bool hasSurfaceExtension = SDL_FALSE;
SDL_bool hasWin32SurfaceExtension = SDL_FALSE;
PFN_vkGetInstanceProcAddr vkGetInstanceProcAddr = NULL;
diff --git a/Source/3rdParty/SDL2/src/video/windows/SDL_windowswindow.c b/Source/3rdParty/SDL2/src/video/windows/SDL_windowswindow.c
index b082443..45463c4 100644
--- a/Source/3rdParty/SDL2/src/video/windows/SDL_windowswindow.c
+++ b/Source/3rdParty/SDL2/src/video/windows/SDL_windowswindow.c
@@ -97,6 +97,11 @@ GetWindowStyle(SDL_Window * window)
if (window->flags & SDL_WINDOW_RESIZABLE) {
style |= STYLE_RESIZABLE;
}
+
+ /* Need to set initialize minimize style, or when we call ShowWindow with WS_MINIMIZE it will activate a random window */
+ if (window->flags & SDL_WINDOW_MINIMIZED) {
+ style |= WS_MINIMIZE;
+ }
}
return style;
}
@@ -215,8 +220,6 @@ SetupWindowData(_THIS, SDL_Window * window, HWND hwnd, HWND parent, SDL_bool cre
if ((window->windowed.w && window->windowed.w != w) || (window->windowed.h && window->windowed.h != h)) {
/* We tried to create a window larger than the desktop and Windows didn't allow it. Override! */
int x, y;
- int w, h;
-
/* Figure out what the window area will be */
WIN_AdjustWindowRect(window, &x, &y, &w, &h, SDL_FALSE);
SetWindowPos(hwnd, HWND_NOTOPMOST, x, y, w, h, SWP_NOCOPYBITS | SWP_NOZORDER | SWP_NOACTIVATE);
@@ -287,9 +290,6 @@ SetupWindowData(_THIS, SDL_Window * window, HWND hwnd, HWND parent, SDL_bool cre
videodata->RegisterTouchWindow(hwnd, (TWF_FINETOUCH|TWF_WANTPALM));
}
- /* Enable dropping files */
- DragAcceptFiles(hwnd, TRUE);
-
data->initializing = SDL_FALSE;
/* All done! */
@@ -335,6 +335,10 @@ WIN_CreateWindow(_THIS, SDL_Window * window)
/* Inform Windows of the frame change so we can respond to WM_NCCALCSIZE */
SetWindowPos(hwnd, NULL, 0, 0, 0, 0, SWP_FRAMECHANGED | SWP_NOSIZE | SWP_NOZORDER | SWP_NOMOVE | SWP_NOACTIVATE);
+ if (window->flags & SDL_WINDOW_MINIMIZED) {
+ ShowWindow(hwnd, SW_SHOWMINNOACTIVE);
+ }
+
if (!(window->flags & SDL_WINDOW_OPENGL)) {
return 0;
}
@@ -407,13 +411,11 @@ WIN_CreateWindowFrom(_THIS, SDL_Window * window, const void *data)
SDL_sscanf(hint, "%p", (void**)&otherWindow);
/* Do some error checking on the pointer */
- if (otherWindow != NULL && otherWindow->magic == &_this->window_magic)
- {
+ if (otherWindow != NULL && otherWindow->magic == &_this->window_magic) {
/* If the otherWindow has SDL_WINDOW_OPENGL set, set it for the new window as well */
- if (otherWindow->flags & SDL_WINDOW_OPENGL)
- {
+ if (otherWindow->flags & SDL_WINDOW_OPENGL) {
window->flags |= SDL_WINDOW_OPENGL;
- if(!WIN_GL_SetPixelFormatFrom(_this, otherWindow, window)) {
+ if (!WIN_GL_SetPixelFormatFrom(_this, otherWindow, window)) {
return -1;
}
}
@@ -546,8 +548,17 @@ WIN_GetWindowBordersSize(_THIS, SDL_Window * window, int *top, int *left, int *b
void
WIN_ShowWindow(_THIS, SDL_Window * window)
{
- HWND hwnd = ((SDL_WindowData *) window->driverdata)->hwnd;
- ShowWindow(hwnd, SW_SHOW);
+ DWORD style;
+ HWND hwnd;
+ int nCmdShow;
+
+ hwnd = ((SDL_WindowData *)window->driverdata)->hwnd;
+ nCmdShow = SW_SHOW;
+ style = GetWindowLong(hwnd, GWL_EXSTYLE);
+ if (style & WS_EX_NOACTIVATE) {
+ nCmdShow = SW_SHOWNOACTIVATE;
+ }
+ ShowWindow(hwnd, nCmdShow);
}
void
@@ -891,8 +902,13 @@ WIN_UpdateClipCursor(SDL_Window *window)
{
SDL_WindowData *data = (SDL_WindowData *) window->driverdata;
SDL_Mouse *mouse = SDL_GetMouse();
+ RECT rect;
- if (data->focus_click_pending) {
+ if (data->in_title_click || data->focus_click_pending) {
+ return;
+ }
+ if (data->skip_update_clipcursor) {
+ data->skip_update_clipcursor = SDL_FALSE;
return;
}
@@ -900,7 +916,6 @@ WIN_UpdateClipCursor(SDL_Window *window)
(window->flags & SDL_WINDOW_INPUT_FOCUS)) {
if (mouse->relative_mode && !mouse->relative_mode_warp) {
LONG cx, cy;
- RECT rect;
GetWindowRect(data->hwnd, &rect);
cx = (rect.left + rect.right) / 2;
@@ -912,17 +927,21 @@ WIN_UpdateClipCursor(SDL_Window *window)
rect.top = cy - 1;
rect.bottom = cy + 1;
- ClipCursor(&rect);
+ if (ClipCursor(&rect)) {
+ data->cursor_clipped_rect = rect;
+ }
} else {
- RECT rect;
if (GetClientRect(data->hwnd, &rect) && !IsRectEmpty(&rect)) {
ClientToScreen(data->hwnd, (LPPOINT) & rect);
ClientToScreen(data->hwnd, (LPPOINT) & rect + 1);
- ClipCursor(&rect);
+ if (ClipCursor(&rect)) {
+ data->cursor_clipped_rect = rect;
+ }
}
}
- } else {
+ } else if (GetClipCursor(&rect) && SDL_memcmp(&rect, &data->cursor_clipped_rect, sizeof(rect)) == 0) {
ClipCursor(NULL);
+ SDL_zero(data->cursor_clipped_rect);
}
}
@@ -965,6 +984,13 @@ WIN_SetWindowOpacity(_THIS, SDL_Window * window, float opacity)
return 0;
}
+void
+WIN_AcceptDragAndDrop(SDL_Window * window, SDL_bool accept)
+{
+ const SDL_WindowData *data = (SDL_WindowData *) window->driverdata;
+ DragAcceptFiles(data->hwnd, accept ? TRUE : FALSE);
+}
+
#endif /* SDL_VIDEO_DRIVER_WINDOWS */
/* vi: set ts=4 sw=4 expandtab: */
diff --git a/Source/3rdParty/SDL2/src/video/windows/SDL_windowswindow.h b/Source/3rdParty/SDL2/src/video/windows/SDL_windowswindow.h
index 0325abb..b738c34 100644
--- a/Source/3rdParty/SDL2/src/video/windows/SDL_windowswindow.h
+++ b/Source/3rdParty/SDL2/src/video/windows/SDL_windowswindow.h
@@ -44,8 +44,10 @@ typedef struct
SDL_bool in_border_change;
SDL_bool in_title_click;
Uint8 focus_click_pending;
+ SDL_bool skip_update_clipcursor;
SDL_bool windowed_mode_was_maximized;
SDL_bool in_window_deactivation;
+ RECT cursor_clipped_rect;
struct SDL_VideoData *videodata;
#if SDL_VIDEO_OPENGL_EGL
EGLSurface egl_surface;
@@ -78,6 +80,7 @@ extern SDL_bool WIN_GetWindowWMInfo(_THIS, SDL_Window * window,
extern void WIN_OnWindowEnter(_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);
#endif /* SDL_windowswindow_h_ */