SDL_CreateWindowWithPosition() and SDL_CreateWindowFrom() have been replaced with SDL_CreateWindowWithProperties()

This is a more general interface that can be extended in the future as needed.
This commit is contained in:
Sam Lantinga
2023-11-13 11:29:30 -08:00
parent 2c1fbe1967
commit 229b7b9d50
47 changed files with 470 additions and 573 deletions

View File

@@ -276,7 +276,7 @@ static void SDLCALL WIN_MouseRelativeModeCenterChanged(void *userdata, const cha
data->mouse_relative_mode_center = SDL_GetStringBoolean(hint, SDL_TRUE);
}
static int SetupWindowData(SDL_VideoDevice *_this, SDL_Window *window, HWND hwnd, HWND parent, SDL_bool created)
static int SetupWindowData(SDL_VideoDevice *_this, SDL_Window *window, HWND hwnd, HWND parent)
{
SDL_VideoData *videodata = _this->driverdata;
SDL_WindowData *data;
@@ -295,8 +295,6 @@ static int SetupWindowData(SDL_VideoDevice *_this, SDL_Window *window, HWND hwnd
data->hdc = GetDC(hwnd);
#endif
data->hinstance = (HINSTANCE)GetWindowLongPtr(hwnd, GWLP_HINSTANCE);
data->created = created;
data->high_surrogate = 0;
data->mouse_button_flags = (WPARAM)-1;
data->last_pointer_update = (LPARAM)-1;
data->videodata = videodata;
@@ -349,7 +347,10 @@ static int SetupWindowData(SDL_VideoDevice *_this, SDL_Window *window, HWND hwnd
int w = rect.right;
int h = rect.bottom;
if ((window->windowed.w && window->windowed.w != w) || (window->windowed.h && window->windowed.h != h)) {
if (window->flags & SDL_WINDOW_FOREIGN) {
window->windowed.w = window->w = w;
window->windowed.h = window->h = h;
} else 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;
/* Figure out what the window area will be */
@@ -369,6 +370,10 @@ static int SetupWindowData(SDL_VideoDevice *_this, SDL_Window *window, HWND hwnd
point.x = 0;
point.y = 0;
if (ClientToScreen(hwnd, &point)) {
if (window->flags & SDL_WINDOW_FOREIGN) {
window->windowed.x = point.x;
window->windowed.y = point.y;
}
window->x = point.x;
window->y = point.y;
}
@@ -438,6 +443,27 @@ static int SetupWindowData(SDL_VideoDevice *_this, SDL_Window *window, HWND hwnd
data->initializing = SDL_FALSE;
if (window->flags & SDL_WINDOW_FOREIGN) {
/* Query the title from the existing window */
LPTSTR title;
int titleLen;
SDL_bool isstack;
titleLen = GetWindowTextLength(hwnd);
title = SDL_small_alloc(TCHAR, titleLen + 1, &isstack);
if (title) {
titleLen = GetWindowText(hwnd, title, titleLen + 1);
} else {
titleLen = 0;
}
if (titleLen > 0) {
window->title = WIN_StringToUTF8(title);
}
if (title) {
SDL_small_free(title, isstack);
}
}
SDL_PropertiesID props = SDL_GetWindowProperties(window);
SDL_SetProperty(props, "SDL.window.win32.hwnd", data->hwnd);
SDL_SetProperty(props, "SDL.window.win32.hdc", data->hdc);
@@ -464,7 +490,7 @@ static void CleanupWindowData(SDL_VideoDevice *_this, SDL_Window *window)
ReleaseDC(data->hwnd, data->hdc);
RemoveProp(data->hwnd, TEXT("SDL_WindowData"));
#endif
if (data->created) {
if (!(window->flags & SDL_WINDOW_FOREIGN)) {
DestroyWindow(data->hwnd);
if (data->destroy_parent_with_window && data->parent) {
DestroyWindow(data->parent);
@@ -538,55 +564,64 @@ static void WIN_SetKeyboardFocus(SDL_Window *window)
SDL_SetKeyboardFocus(window);
}
int WIN_CreateWindow(SDL_VideoDevice *_this, SDL_Window *window)
int WIN_CreateWindow(SDL_VideoDevice *_this, SDL_Window *window, SDL_PropertiesID create_props)
{
HWND hwnd, parent = NULL;
DWORD style = STYLE_BASIC;
DWORD styleEx = 0;
int x, y;
int w, h;
HWND hwnd = (HWND)SDL_GetProperty(create_props, "native.win32.hwnd", SDL_GetProperty(create_props, "native.data", NULL));
HWND parent = NULL;
if (hwnd) {
window->flags |= SDL_WINDOW_FOREIGN;
if (SDL_WINDOW_IS_POPUP(window)) {
parent = window->parent->driverdata->hwnd;
} else if (window->flags & SDL_WINDOW_UTILITY) {
parent = CreateWindow(SDL_Appname, TEXT(""), STYLE_BASIC, 0, 0, 32, 32, NULL, NULL, SDL_Instance, NULL);
}
style |= GetWindowStyle(window);
styleEx |= GetWindowStyleEx(window);
/* Figure out what the window area will be */
WIN_ConstrainPopup(window);
WIN_AdjustWindowRectWithStyle(window, style, FALSE, &x, &y, &w, &h, SDL_FALSE);
hwnd = CreateWindowEx(styleEx, SDL_Appname, TEXT(""), style,
x, y, w, h, parent, NULL, SDL_Instance, NULL);
if (!hwnd) {
return WIN_SetError("Couldn't create window");
}
WIN_UpdateDarkModeForHWND(hwnd);
WIN_PumpEvents(_this);
if (SetupWindowData(_this, window, hwnd, parent, SDL_TRUE) < 0) {
DestroyWindow(hwnd);
if (parent) {
DestroyWindow(parent);
if (SetupWindowData(_this, window, hwnd, parent) < 0) {
return -1;
}
return -1;
}
} else {
DWORD style = STYLE_BASIC;
DWORD styleEx = 0;
int x, y;
int w, h;
/* 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_NOMOVE | SWP_NOZORDER | SWP_NOOWNERZORDER | SWP_NOACTIVATE);
if (SDL_WINDOW_IS_POPUP(window)) {
parent = window->parent->driverdata->hwnd;
} else if (window->flags & SDL_WINDOW_UTILITY) {
parent = CreateWindow(SDL_Appname, TEXT(""), STYLE_BASIC, 0, 0, 32, 32, NULL, NULL, SDL_Instance, NULL);
}
if (window->flags & SDL_WINDOW_MINIMIZED) {
/* TODO: We have to clear SDL_WINDOW_HIDDEN here to ensure the window flags match the window state. The
window is already shown after this and windows with WS_MINIMIZE do not generate a WM_SHOWWINDOW. This
means you can't currently create a window that is initially hidden and is minimized when shown.
*/
window->flags &= ~SDL_WINDOW_HIDDEN;
ShowWindow(hwnd, SW_SHOWMINNOACTIVE);
style |= GetWindowStyle(window);
styleEx |= GetWindowStyleEx(window);
/* Figure out what the window area will be */
WIN_ConstrainPopup(window);
WIN_AdjustWindowRectWithStyle(window, style, FALSE, &x, &y, &w, &h, SDL_FALSE);
hwnd = CreateWindowEx(styleEx, SDL_Appname, TEXT(""), style,
x, y, w, h, parent, NULL, SDL_Instance, NULL);
if (!hwnd) {
return WIN_SetError("Couldn't create window");
}
WIN_UpdateDarkModeForHWND(hwnd);
WIN_PumpEvents(_this);
if (SetupWindowData(_this, window, hwnd, parent) < 0) {
DestroyWindow(hwnd);
if (parent) {
DestroyWindow(parent);
}
return -1;
}
/* 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_NOMOVE | SWP_NOZORDER | SWP_NOOWNERZORDER | SWP_NOACTIVATE);
if (window->flags & SDL_WINDOW_MINIMIZED) {
/* TODO: We have to clear SDL_WINDOW_HIDDEN here to ensure the window flags match the window state. The
window is already shown after this and windows with WS_MINIMIZE do not generate a WM_SHOWWINDOW. This
means you can't currently create a window that is initially hidden and is minimized when shown.
*/
window->flags &= ~SDL_WINDOW_HIDDEN;
ShowWindow(hwnd, SW_SHOWMINNOACTIVE);
}
}
/* FIXME: does not work on all hardware configurations with different renders (i.e. hybrid GPUs) */
@@ -608,98 +643,56 @@ int WIN_CreateWindow(SDL_VideoDevice *_this, SDL_Window *window)
}
}
if (!(window->flags & SDL_WINDOW_OPENGL)) {
return 0;
}
HWND share_hwnd = (HWND)SDL_GetProperty(create_props, "native.win32.pixel_format_hwnd", NULL);
if (share_hwnd) {
HDC hdc = GetDC(share_hwnd);
int pixel_format = GetPixelFormat(hdc);
PIXELFORMATDESCRIPTOR pfd;
/* The rest of this macro mess is for OpenGL or OpenGL ES windows */
#ifdef SDL_VIDEO_OPENGL_ES2
if ((_this->gl_config.profile_mask == SDL_GL_CONTEXT_PROFILE_ES ||
SDL_GetHintBoolean(SDL_HINT_VIDEO_FORCE_EGL, SDL_FALSE)) &&
#ifdef SDL_VIDEO_OPENGL_WGL
(!_this->gl_data || WIN_GL_UseEGL(_this))
#endif /* SDL_VIDEO_OPENGL_WGL */
) {
#ifdef SDL_VIDEO_OPENGL_EGL
if (WIN_GLES_SetupWindow(_this, window) < 0) {
SDL_zero(pfd);
DescribePixelFormat(hdc, pixel_format, sizeof(pfd), &pfd);
ReleaseDC(share_hwnd, hdc);
if (!SetPixelFormat(window->driverdata->hdc, pixel_format, &pfd)) {
WIN_DestroyWindow(_this, window);
return -1;
return WIN_SetError("SetPixelFormat()");
}
return 0;
} else {
if (!(window->flags & SDL_WINDOW_OPENGL)) {
return 0;
}
/* The rest of this macro mess is for OpenGL or OpenGL ES windows */
#ifdef SDL_VIDEO_OPENGL_ES2
if ((_this->gl_config.profile_mask == SDL_GL_CONTEXT_PROFILE_ES ||
SDL_GetHintBoolean(SDL_HINT_VIDEO_FORCE_EGL, SDL_FALSE)) &&
#ifdef SDL_VIDEO_OPENGL_WGL
(!_this->gl_data || WIN_GL_UseEGL(_this))
#endif /* SDL_VIDEO_OPENGL_WGL */
) {
#ifdef SDL_VIDEO_OPENGL_EGL
if (WIN_GLES_SetupWindow(_this, window) < 0) {
WIN_DestroyWindow(_this, window);
return -1;
}
return 0;
#else
return SDL_SetError("Could not create GLES window surface (EGL support not configured)");
return SDL_SetError("Could not create GLES window surface (EGL support not configured)");
#endif /* SDL_VIDEO_OPENGL_EGL */
}
}
#endif /* SDL_VIDEO_OPENGL_ES2 */
#ifdef SDL_VIDEO_OPENGL_WGL
if (WIN_GL_SetupWindow(_this, window) < 0) {
WIN_DestroyWindow(_this, window);
return -1;
}
#else
return SDL_SetError("Could not create GL window (WGL support not configured)");
#endif
return 0;
}
int WIN_CreateWindowFrom(SDL_VideoDevice *_this, SDL_Window *window, SDL_PropertiesID props)
{
#if defined(__XBOXONE__) || defined(__XBOXSERIES__)
return -1;
#else
HWND hwnd = (HWND)SDL_GetProperty(props, "win32.hwnd", SDL_GetProperty(props, "data", NULL));
LPTSTR title;
int titleLen;
SDL_bool isstack;
if (!hwnd) {
return SDL_SetError("Couldn't find property win32.hwnd");
}
/* Query the title from the existing window */
titleLen = GetWindowTextLength(hwnd);
title = SDL_small_alloc(TCHAR, titleLen + 1, &isstack);
if (title) {
titleLen = GetWindowText(hwnd, title, titleLen + 1);
} else {
titleLen = 0;
}
if (titleLen > 0) {
window->title = WIN_StringToUTF8(title);
}
if (title) {
SDL_small_free(title, isstack);
}
if (SetupWindowData(_this, window, hwnd, GetParent(hwnd), SDL_FALSE) < 0) {
return -1;
}
#ifdef SDL_VIDEO_OPENGL_WGL
{
HWND share_hwnd = (HWND)SDL_GetProperty(props, "win32.pixel_format_hwnd", NULL);
if (share_hwnd) {
HDC hdc = GetDC(share_hwnd);
int pixel_format = GetPixelFormat(hdc);
PIXELFORMATDESCRIPTOR pfd;
SDL_zero(pfd);
DescribePixelFormat(hdc, pixel_format, sizeof(pfd), &pfd);
ReleaseDC(share_hwnd, hdc);
if (!SetPixelFormat(window->driverdata->hdc, pixel_format, &pfd)) {
return WIN_SetError("SetPixelFormat()");
}
} else if (window->flags & SDL_WINDOW_OPENGL) {
/* Try to set up the pixel format, if it hasn't been set by the application */
WIN_GL_SetupWindow(_this, window);
if (WIN_GL_SetupWindow(_this, window) < 0) {
WIN_DestroyWindow(_this, window);
return -1;
}
}
#else
return SDL_SetError("Could not create GL window (WGL support not configured)");
#endif
}
return 0;
#endif /*!defined(__XBOXONE__) && !defined(__XBOXSERIES__)*/
}
void WIN_SetWindowTitle(SDL_VideoDevice *_this, SDL_Window *window)