SDL_windowswindow.c
Go to the documentation of this file.
/*
Simple DirectMedia Layer
Copyright (C) 1997-2016 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"
#if SDL_VIDEO_DRIVER_WINDOWS
#include "../../core/windows/SDL_windows.h"
#include "SDL_assert.h"
#include "../SDL_sysvideo.h"
#include "../SDL_pixels_c.h"
#include "../../events/SDL_keyboard_c.h"
#include "../../events/SDL_mouse_c.h"
#include "SDL_windowsvideo.h"
#include "SDL_windowswindow.h"
#include "SDL_hints.h"
/* Dropfile support */
#include <shellapi.h>
/* This is included after SDL_windowsvideo.h, which includes windows.h */
#include "SDL_syswm.h"
/* Windows CE compatibility */
#ifndef SWP_NOCOPYBITS
#define SWP_NOCOPYBITS 0
#endif
/* Fake window to help with DirectInput events. */
HWND SDL_HelperWindow = NULL;
static WCHAR *SDL_HelperWindowClassName = TEXT("SDLHelperWindowInputCatcher");
static WCHAR *SDL_HelperWindowName = TEXT("SDLHelperWindowInputMsgWindow");
static ATOM SDL_HelperWindowClass = 0;
#define STYLE_BASIC (WS_CLIPSIBLINGS | WS_CLIPCHILDREN)
#define STYLE_FULLSCREEN (WS_POPUP)
#define STYLE_BORDERLESS (WS_POPUP)
#define STYLE_NORMAL (WS_OVERLAPPED | WS_CAPTION | WS_SYSMENU | WS_MINIMIZEBOX)
#define STYLE_RESIZABLE (WS_THICKFRAME | WS_MAXIMIZEBOX)
#define STYLE_MASK (STYLE_FULLSCREEN | STYLE_BORDERLESS | STYLE_NORMAL | STYLE_RESIZABLE)
static DWORD
GetWindowStyle(SDL_Window * window)
{
DWORD style = 0;
if (window->flags & SDL_WINDOW_FULLSCREEN) {
style |= STYLE_FULLSCREEN;
} else {
if (window->flags & SDL_WINDOW_BORDERLESS) {
style |= STYLE_BORDERLESS;
} else {
style |= STYLE_NORMAL;
}
if (window->flags & SDL_WINDOW_RESIZABLE) {
style |= STYLE_RESIZABLE;
}
}
return style;
}
static void
WIN_SetWindowPositionInternal(_THIS, SDL_Window * window, UINT flags)
{
SDL_WindowData *data = (SDL_WindowData *)window->driverdata;
HWND hwnd = data->hwnd;
RECT rect;
DWORD style;
HWND top;
BOOL menu;
int x, y;
int w, h;
/* Figure out what the window area will be */
if (SDL_ShouldAllowTopmost() && (window->flags & (SDL_WINDOW_FULLSCREEN|SDL_WINDOW_INPUT_FOCUS)) == (SDL_WINDOW_FULLSCREEN|SDL_WINDOW_INPUT_FOCUS)) {
top = HWND_TOPMOST;
} else {
top = HWND_NOTOPMOST;
}
style = GetWindowLong(hwnd, GWL_STYLE);
rect.left = 0;
rect.top = 0;
rect.right = window->w;
rect.bottom = window->h;
menu = (style & WS_CHILDWINDOW) ? FALSE : (GetMenu(hwnd) != NULL);
AdjustWindowRectEx(&rect, style, menu, 0);
w = (rect.right - rect.left);
h = (rect.bottom - rect.top);
x = window->x + rect.left;
y = window->y + rect.top;
data->expected_resize = SDL_TRUE;
SetWindowPos(hwnd, top, x, y, w, h, flags);
data->expected_resize = SDL_FALSE;
}
static int
SetupWindowData(_THIS, SDL_Window * window, HWND hwnd, SDL_bool created)
{
SDL_VideoData *videodata = (SDL_VideoData *) _this->driverdata;
SDL_WindowData *data;
/* Allocate the window data */
data = (SDL_WindowData *) SDL_calloc(1, sizeof(*data));
if (!data) {
return SDL_OutOfMemory();
}
data->window = window;
data->hwnd = hwnd;
data->hdc = GetDC(hwnd);
data->created = created;
data->mouse_button_flags = 0;
data->videodata = videodata;
data->initializing = SDL_TRUE;
window->driverdata = data;
/* Associate the data with the window */
if (!SetProp(hwnd, TEXT("SDL_WindowData"), data)) {
ReleaseDC(hwnd, data->hdc);
SDL_free(data);
return WIN_SetError("SetProp() failed");
}
/* Set up the window proc function */
#ifdef GWLP_WNDPROC
data->wndproc = (WNDPROC) GetWindowLongPtr(hwnd, GWLP_WNDPROC);
if (data->wndproc == WIN_WindowProc) {
data->wndproc = NULL;
} else {
SetWindowLongPtr(hwnd, GWLP_WNDPROC, (LONG_PTR) WIN_WindowProc);
}
#else
data->wndproc = (WNDPROC) GetWindowLong(hwnd, GWL_WNDPROC);
if (data->wndproc == WIN_WindowProc) {
data->wndproc = NULL;
} else {
SetWindowLong(hwnd, GWL_WNDPROC, (LONG_PTR) WIN_WindowProc);
}
#endif
/* Fill in the SDL window with the window data */
{
RECT rect;
if (GetClientRect(hwnd, &rect)) {
int w = rect.right;
int h = rect.bottom;
if ((window->w && window->w != w) || (window->h && window->h != h)) {
/* We tried to create a window larger than the desktop and Windows didn't allow it. Override! */
RECT rect;
DWORD style;
BOOL menu;
int x, y;
int w, h;
/* Figure out what the window area will be */
style = GetWindowLong(hwnd, GWL_STYLE);
rect.left = 0;
rect.top = 0;
rect.right = window->w;
rect.bottom = window->h;
menu = (style & WS_CHILDWINDOW) ? FALSE : (GetMenu(hwnd) != NULL);
AdjustWindowRectEx(&rect, style, menu, 0);
w = (rect.right - rect.left);
h = (rect.bottom - rect.top);
x = window->x + rect.left;
y = window->y + rect.top;
SetWindowPos(hwnd, HWND_NOTOPMOST, x, y, w, h, SWP_NOCOPYBITS | SWP_NOZORDER | SWP_NOACTIVATE);
} else {
window->w = w;
window->h = h;
}
}
}
{
POINT point;
point.x = 0;
point.y = 0;
if (ClientToScreen(hwnd, &point)) {
window->x = point.x;
window->y = point.y;
}
}
{
DWORD style = GetWindowLong(hwnd, GWL_STYLE);
if (style & WS_VISIBLE) {
window->flags |= SDL_WINDOW_SHOWN;
} else {
window->flags &= ~SDL_WINDOW_SHOWN;
}
if (style & (WS_BORDER | WS_THICKFRAME)) {
window->flags &= ~SDL_WINDOW_BORDERLESS;
} else {
window->flags |= SDL_WINDOW_BORDERLESS;
}
if (style & WS_THICKFRAME) {
window->flags |= SDL_WINDOW_RESIZABLE;
} else {
window->flags &= ~SDL_WINDOW_RESIZABLE;
}
#ifdef WS_MAXIMIZE
if (style & WS_MAXIMIZE) {
window->flags |= SDL_WINDOW_MAXIMIZED;
} else
#endif
{
window->flags &= ~SDL_WINDOW_MAXIMIZED;
}
#ifdef WS_MINIMIZE
if (style & WS_MINIMIZE) {
window->flags |= SDL_WINDOW_MINIMIZED;
} else
#endif
{
window->flags &= ~SDL_WINDOW_MINIMIZED;
}
}
if (GetFocus() == hwnd) {
window->flags |= SDL_WINDOW_INPUT_FOCUS;
SDL_SetKeyboardFocus(data->window);
if (window->flags & SDL_WINDOW_INPUT_GRABBED) {
RECT rect;
GetClientRect(hwnd, &rect);
ClientToScreen(hwnd, (LPPOINT) & rect);
ClientToScreen(hwnd, (LPPOINT) & rect + 1);
ClipCursor(&rect);
}
}
/* Enable multi-touch */
if (videodata->RegisterTouchWindow) {
videodata->RegisterTouchWindow(hwnd, (TWF_FINETOUCH|TWF_WANTPALM));
}
/* Enable dropping files */
DragAcceptFiles(hwnd, TRUE);
data->initializing = SDL_FALSE;
/* All done! */
return 0;
}
int
WIN_CreateWindow(_THIS, SDL_Window * window)
{
HWND hwnd;
RECT rect;
DWORD style = STYLE_BASIC;
int x, y;
int w, h;
style |= GetWindowStyle(window);
/* Figure out what the window area will be */
rect.left = window->x;
rect.top = window->y;
rect.right = window->x + window->w;
rect.bottom = window->y + window->h;
AdjustWindowRectEx(&rect, style, FALSE, 0);
x = rect.left;
y = rect.top;
w = (rect.right - rect.left);
h = (rect.bottom - rect.top);
hwnd =
CreateWindow(SDL_Appname, TEXT(""), style, x, y, w, h, NULL, NULL,
SDL_Instance, NULL);
if (!hwnd) {
return WIN_SetError("Couldn't create window");
}
WIN_PumpEvents(_this);
if (SetupWindowData(_this, window, hwnd, SDL_TRUE) < 0) {
DestroyWindow(hwnd);
return -1;
}
#if SDL_VIDEO_OPENGL_WGL
/* We need to initialize the extensions before deciding how to create ES profiles */
if (window->flags & SDL_WINDOW_OPENGL) {
WIN_GL_InitExtensions(_this);
}
#endif
#if SDL_VIDEO_OPENGL_ES2
if ((window->flags & SDL_WINDOW_OPENGL) &&
_this->gl_config.profile_mask == SDL_GL_CONTEXT_PROFILE_ES
#if SDL_VIDEO_OPENGL_WGL
&& (!_this->gl_data || !_this->gl_data->HAS_WGL_EXT_create_context_es2_profile)
#endif
) {
#if SDL_VIDEO_OPENGL_EGL
if (WIN_GLES_SetupWindow(_this, window) < 0) {
WIN_DestroyWindow(_this, window);
return -1;
}
#else
return SDL_SetError("Could not create GLES window surface (no EGL support available)");
#endif /* SDL_VIDEO_OPENGL_EGL */
} else
#endif /* SDL_VIDEO_OPENGL_ES2 */
#if SDL_VIDEO_OPENGL_WGL
if (window->flags & SDL_WINDOW_OPENGL) {
if (WIN_GL_SetupWindow(_this, window) < 0) {
WIN_DestroyWindow(_this, window);
return -1;
}
}
#endif
return 0;
}
int
WIN_CreateWindowFrom(_THIS, SDL_Window * window, const void *data)
{
HWND hwnd = (HWND) data;
LPTSTR title;
int titleLen;
/* Query the title from the existing window */
titleLen = GetWindowTextLength(hwnd);
title = SDL_stack_alloc(TCHAR, titleLen + 1);
if (title) {
titleLen = GetWindowText(hwnd, title, titleLen);
} else {
titleLen = 0;
}
if (titleLen > 0) {
window->title = WIN_StringToUTF8(title);
}
if (title) {
SDL_stack_free(title);
}
if (SetupWindowData(_this, window, hwnd, SDL_FALSE) < 0) {
return -1;
}
#if SDL_VIDEO_OPENGL_WGL
{
const char *hint = SDL_GetHint(SDL_HINT_VIDEO_WINDOW_SHARE_PIXEL_FORMAT);
if (hint) {
/* This hint is a pointer (in string form) of the address of
the window to share a pixel format with
*/
SDL_Window *otherWindow = NULL;
SDL_sscanf(hint, "%p", (void**)&otherWindow);
/* Do some error checking on the pointer */
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)
{
window->flags |= SDL_WINDOW_OPENGL;
if(!WIN_GL_SetPixelFormatFrom(_this, otherWindow, window)) {
return -1;
}
}
}
}
}
#endif
return 0;
}
void
WIN_SetWindowTitle(_THIS, SDL_Window * window)
{
HWND hwnd = ((SDL_WindowData *) window->driverdata)->hwnd;
LPTSTR title = WIN_UTF8ToString(window->title);
SetWindowText(hwnd, title);
SDL_free(title);
}
void
WIN_SetWindowIcon(_THIS, SDL_Window * window, SDL_Surface * icon)
{
HWND hwnd = ((SDL_WindowData *) window->driverdata)->hwnd;
HICON hicon = NULL;
BYTE *icon_bmp;
int icon_len, y;
SDL_RWops *dst;
/* Create temporary bitmap buffer */
icon_len = 40 + icon->h * icon->w * 4;
icon_bmp = SDL_stack_alloc(BYTE, icon_len);
dst = SDL_RWFromMem(icon_bmp, icon_len);
if (!dst) {
SDL_stack_free(icon_bmp);
return;
}
/* Write the BITMAPINFO header */
SDL_WriteLE32(dst, 40);
SDL_WriteLE32(dst, icon->w);
SDL_WriteLE32(dst, icon->h * 2);
SDL_WriteLE16(dst, 1);
SDL_WriteLE16(dst, 32);
SDL_WriteLE32(dst, BI_RGB);
SDL_WriteLE32(dst, icon->h * icon->w * 4);
SDL_WriteLE32(dst, 0);
SDL_WriteLE32(dst, 0);
SDL_WriteLE32(dst, 0);
SDL_WriteLE32(dst, 0);
/* Write the pixels upside down into the bitmap buffer */
SDL_assert(icon->format->format == SDL_PIXELFORMAT_ARGB8888);
y = icon->h;
while (y--) {
Uint8 *src = (Uint8 *) icon->pixels + y * icon->pitch;
SDL_RWwrite(dst, src, icon->pitch, 1);
}
hicon = CreateIconFromResource(icon_bmp, icon_len, TRUE, 0x00030000);
SDL_RWclose(dst);
SDL_stack_free(icon_bmp);
/* Set the icon for the window */
SendMessage(hwnd, WM_SETICON, ICON_SMALL, (LPARAM) hicon);
/* Set the icon in the task manager (should we do this?) */
SendMessage(hwnd, WM_SETICON, ICON_BIG, (LPARAM) hicon);
}
void
WIN_SetWindowPosition(_THIS, SDL_Window * window)
{
WIN_SetWindowPositionInternal(_this, window, SWP_NOCOPYBITS | SWP_NOSIZE | SWP_NOACTIVATE);
}
void
WIN_SetWindowSize(_THIS, SDL_Window * window)
{
WIN_SetWindowPositionInternal(_this, window, SWP_NOCOPYBITS | SWP_NOMOVE | SWP_NOACTIVATE);
}
void
WIN_ShowWindow(_THIS, SDL_Window * window)
{
HWND hwnd = ((SDL_WindowData *) window->driverdata)->hwnd;
ShowWindow(hwnd, SW_SHOW);
}
void
WIN_HideWindow(_THIS, SDL_Window * window)
{
HWND hwnd = ((SDL_WindowData *) window->driverdata)->hwnd;
ShowWindow(hwnd, SW_HIDE);
}
void
WIN_RaiseWindow(_THIS, SDL_Window * window)
{
WIN_SetWindowPositionInternal(_this, window, SWP_NOCOPYBITS | SWP_NOMOVE | SWP_NOSIZE);
}
void
WIN_MaximizeWindow(_THIS, SDL_Window * window)
{
SDL_WindowData *data = (SDL_WindowData *)window->driverdata;
HWND hwnd = data->hwnd;
data->expected_resize = SDL_TRUE;
ShowWindow(hwnd, SW_MAXIMIZE);
data->expected_resize = SDL_FALSE;
}
void
WIN_MinimizeWindow(_THIS, SDL_Window * window)
{
HWND hwnd = ((SDL_WindowData *) window->driverdata)->hwnd;
ShowWindow(hwnd, SW_MINIMIZE);
}
void
WIN_SetWindowBordered(_THIS, SDL_Window * window, SDL_bool bordered)
{
SDL_WindowData *data = (SDL_WindowData *)window->driverdata;
HWND hwnd = data->hwnd;
DWORD style = GetWindowLong(hwnd, GWL_STYLE);
if (bordered) {
style &= ~STYLE_BORDERLESS;
style |= STYLE_NORMAL;
} else {
style &= ~STYLE_NORMAL;
style |= STYLE_BORDERLESS;
}
data->in_border_change = SDL_TRUE;
SetWindowLong(hwnd, GWL_STYLE, style);
WIN_SetWindowPositionInternal(_this, window, SWP_NOCOPYBITS | SWP_FRAMECHANGED | SWP_NOZORDER | SWP_NOACTIVATE);
data->in_border_change = SDL_FALSE;
}
void
WIN_RestoreWindow(_THIS, SDL_Window * window)
{
SDL_WindowData *data = (SDL_WindowData *)window->driverdata;
HWND hwnd = data->hwnd;
data->expected_resize = SDL_TRUE;
ShowWindow(hwnd, SW_RESTORE);
data->expected_resize = SDL_FALSE;
}
void
WIN_SetWindowFullscreen(_THIS, SDL_Window * window, SDL_VideoDisplay * display, SDL_bool fullscreen)
{
SDL_WindowData *data = (SDL_WindowData *) window->driverdata;
HWND hwnd = data->hwnd;
RECT rect;
SDL_Rect bounds;
DWORD style;
HWND top;
BOOL menu;
int x, y;
int w, h;
if (SDL_ShouldAllowTopmost() && (window->flags & (SDL_WINDOW_FULLSCREEN|SDL_WINDOW_INPUT_FOCUS)) == (SDL_WINDOW_FULLSCREEN|SDL_WINDOW_INPUT_FOCUS)) {
top = HWND_TOPMOST;
} else {
top = HWND_NOTOPMOST;
}
style = GetWindowLong(hwnd, GWL_STYLE);
style &= ~STYLE_MASK;
style |= GetWindowStyle(window);
WIN_GetDisplayBounds(_this, display, &bounds);
if (fullscreen) {
x = bounds.x;
y = bounds.y;
w = bounds.w;
h = bounds.h;
/* Unset the maximized flag. This fixes
https://bugzilla.libsdl.org/show_bug.cgi?id=3215
*/
if (style & WS_MAXIMIZE) {
data->windowed_mode_was_maximized = SDL_TRUE;
style &= ~WS_MAXIMIZE;
}
} else {
/* Restore window-maximization state, as applicable.
Special care is taken to *not* do this if and when we're
alt-tab'ing away (to some other window; as indicated by
in_window_deactivation), otherwise
https://bugzilla.libsdl.org/show_bug.cgi?id=3215 can reproduce!
*/
if (data->windowed_mode_was_maximized && !data->in_window_deactivation) {
style |= WS_MAXIMIZE;
data->windowed_mode_was_maximized = SDL_FALSE;
}
rect.left = 0;
rect.top = 0;
rect.right = window->windowed.w;
rect.bottom = window->windowed.h;
menu = (style & WS_CHILDWINDOW) ? FALSE : (GetMenu(hwnd) != NULL);
AdjustWindowRectEx(&rect, style, menu, 0);
w = (rect.right - rect.left);
h = (rect.bottom - rect.top);
x = window->windowed.x + rect.left;
y = window->windowed.y + rect.top;
}
SetWindowLong(hwnd, GWL_STYLE, style);
data->expected_resize = SDL_TRUE;
SetWindowPos(hwnd, top, x, y, w, h, SWP_NOCOPYBITS | SWP_NOACTIVATE);
data->expected_resize = SDL_FALSE;
}
int
WIN_SetWindowGammaRamp(_THIS, SDL_Window * window, const Uint16 * ramp)
{
SDL_VideoDisplay *display = SDL_GetDisplayForWindow(window);
SDL_DisplayData *data = (SDL_DisplayData *) display->driverdata;
HDC hdc;
BOOL succeeded = FALSE;
hdc = CreateDC(data->DeviceName, NULL, NULL, NULL);
if (hdc) {
succeeded = SetDeviceGammaRamp(hdc, (LPVOID)ramp);
if (!succeeded) {
WIN_SetError("SetDeviceGammaRamp()");
}
DeleteDC(hdc);
}
return succeeded ? 0 : -1;
}
int
WIN_GetWindowGammaRamp(_THIS, SDL_Window * window, Uint16 * ramp)
{
SDL_VideoDisplay *display = SDL_GetDisplayForWindow(window);
SDL_DisplayData *data = (SDL_DisplayData *) display->driverdata;
HDC hdc;
BOOL succeeded = FALSE;
hdc = CreateDC(data->DeviceName, NULL, NULL, NULL);
if (hdc) {
succeeded = GetDeviceGammaRamp(hdc, (LPVOID)ramp);
if (!succeeded) {
WIN_SetError("GetDeviceGammaRamp()");
}
DeleteDC(hdc);
}
return succeeded ? 0 : -1;
}
void
WIN_SetWindowGrab(_THIS, SDL_Window * window, SDL_bool grabbed)
{
WIN_UpdateClipCursor(window);
if (window->flags & SDL_WINDOW_FULLSCREEN) {
UINT flags = SWP_NOCOPYBITS | SWP_NOMOVE | SWP_NOSIZE;
if (!(window->flags & SDL_WINDOW_SHOWN)) {
flags |= SWP_NOACTIVATE;
}
WIN_SetWindowPositionInternal(_this, window, flags);
}
}
void
WIN_DestroyWindow(_THIS, SDL_Window * window)
{
SDL_WindowData *data = (SDL_WindowData *) window->driverdata;
if (data) {
ReleaseDC(data->hwnd, data->hdc);
RemoveProp(data->hwnd, TEXT("SDL_WindowData"));
if (data->created) {
DestroyWindow(data->hwnd);
} else {
/* Restore any original event handler... */
if (data->wndproc != NULL) {
#ifdef GWLP_WNDPROC
SetWindowLongPtr(data->hwnd, GWLP_WNDPROC,
(LONG_PTR) data->wndproc);
#else
SetWindowLong(data->hwnd, GWL_WNDPROC,
(LONG_PTR) data->wndproc);
#endif
}
}
SDL_free(data);
}
window->driverdata = NULL;
}
SDL_bool
WIN_GetWindowWMInfo(_THIS, SDL_Window * window, SDL_SysWMinfo * info)
{
const SDL_WindowData *data = (const SDL_WindowData *) window->driverdata;
if (info->version.major <= SDL_MAJOR_VERSION) {
info->subsystem = SDL_SYSWM_WINDOWS;
info->info.win.window = data->hwnd;
info->info.win.hdc = data->hdc;
return SDL_TRUE;
} else {
SDL_SetError("Application not compiled with SDL %d.%d\n",
SDL_MAJOR_VERSION, SDL_MINOR_VERSION);
return SDL_FALSE;
}
}
/*
* Creates a HelperWindow used for DirectInput events.
*/
int
SDL_HelperWindowCreate(void)
{
HINSTANCE hInstance = GetModuleHandle(NULL);
WNDCLASS wce;
/* Make sure window isn't created twice. */
if (SDL_HelperWindow != NULL) {
return 0;
}
/* Create the class. */
SDL_zero(wce);
wce.lpfnWndProc = DefWindowProc;
wce.lpszClassName = (LPCWSTR) SDL_HelperWindowClassName;
wce.hInstance = hInstance;
/* Register the class. */
SDL_HelperWindowClass = RegisterClass(&wce);
if (SDL_HelperWindowClass == 0 && GetLastError() != ERROR_CLASS_ALREADY_EXISTS) {
return WIN_SetError("Unable to create Helper Window Class");
}
/* Create the window. */
SDL_HelperWindow = CreateWindowEx(0, SDL_HelperWindowClassName,
SDL_HelperWindowName,
WS_OVERLAPPED, CW_USEDEFAULT,
CW_USEDEFAULT, CW_USEDEFAULT,
CW_USEDEFAULT, HWND_MESSAGE, NULL,
hInstance, NULL);
if (SDL_HelperWindow == NULL) {
UnregisterClass(SDL_HelperWindowClassName, hInstance);
return WIN_SetError("Unable to create Helper Window");
}
return 0;
}
/*
* Destroys the HelperWindow previously created with SDL_HelperWindowCreate.
*/
void
SDL_HelperWindowDestroy(void)
{
HINSTANCE hInstance = GetModuleHandle(NULL);
/* Destroy the window. */
if (SDL_HelperWindow != NULL) {
if (DestroyWindow(SDL_HelperWindow) == 0) {
WIN_SetError("Unable to destroy Helper Window");
return;
}
SDL_HelperWindow = NULL;
}
/* Unregister the class. */
if (SDL_HelperWindowClass != 0) {
if ((UnregisterClass(SDL_HelperWindowClassName, hInstance)) == 0) {
WIN_SetError("Unable to destroy Helper Window Class");
return;
}
SDL_HelperWindowClass = 0;
}
}
void WIN_OnWindowEnter(_THIS, SDL_Window * window)
{
#ifdef WM_MOUSELEAVE
SDL_WindowData *data = (SDL_WindowData *) window->driverdata;
TRACKMOUSEEVENT trackMouseEvent;
if (!data || !data->hwnd) {
/* The window wasn't fully initialized */
return;
}
trackMouseEvent.cbSize = sizeof(TRACKMOUSEEVENT);
trackMouseEvent.dwFlags = TME_LEAVE;
trackMouseEvent.hwndTrack = data->hwnd;
TrackMouseEvent(&trackMouseEvent);
#endif /* WM_MOUSELEAVE */
}
void
WIN_UpdateClipCursor(SDL_Window *window)
{
SDL_WindowData *data = (SDL_WindowData *) window->driverdata;
SDL_Mouse *mouse = SDL_GetMouse();
if (data->focus_click_pending) {
return;
}
if ((mouse->relative_mode || (window->flags & SDL_WINDOW_INPUT_GRABBED)) &&
(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;
cy = (rect.top + rect.bottom) / 2;
/* Make an absurdly small clip rect */
rect.left = cx - 1;
rect.right = cx + 1;
rect.top = cy - 1;
rect.bottom = cy + 1;
ClipCursor(&rect);
} else {
RECT rect;
if (GetClientRect(data->hwnd, &rect) && !IsRectEmpty(&rect)) {
ClientToScreen(data->hwnd, (LPPOINT) & rect);
ClientToScreen(data->hwnd, (LPPOINT) & rect + 1);
ClipCursor(&rect);
}
}
} else {
ClipCursor(NULL);
}
}
int
WIN_SetWindowHitTest(SDL_Window *window, SDL_bool enabled)
{
return 0; /* just succeed, the real work is done elsewhere. */
}
#endif /* SDL_VIDEO_DRIVER_WINDOWS */
/* vi: set ts=4 sw=4 expandtab: */
BI_RGB
#define BI_RGB
Definition: SDL_bmp.c:44
SDL_PIXELFORMAT_ARGB8888
Definition: SDL_pixels.h:247
dst
GLenum GLenum dst
Definition: SDL_opengl_glext.h:1737
SDL_MINOR_VERSION
#define SDL_MINOR_VERSION
Definition: SDL_version.h:61
SDL_Instance
HINSTANCE SDL_Instance
SDL_WindowData::hwnd
HWND hwnd
Definition: SDL_windowswindow.h:33
WIN_UTF8ToString
#define WIN_UTF8ToString(S)
Definition: SDL_windows.h:46
SDL_GetMouse
SDL_Mouse * SDL_GetMouse(void)
Definition: SDL_mouse.c:66
WIN_SetWindowSize
void WIN_SetWindowSize(_THIS, SDL_Window *window)
SDL_SetKeyboardFocus
void SDL_SetKeyboardFocus(SDL_Window *window)
Definition: SDL_keyboard.c:612
SDL_Window::w
int w
Definition: SDL_sysvideo.h:78
SDL_Surface::h
int h
Definition: SDL_surface.h:73
SDL_RWwrite
#define SDL_RWwrite(ctx, ptr, size, n)
Definition: SDL_rwops.h:188
x
GLint GLint GLint GLint GLint x
Definition: SDL_opengl.h:1567
SDL_MAJOR_VERSION
#define SDL_MAJOR_VERSION
Definition: SDL_version.h:60
SDL_RWops
Definition: SDL_rwops.h:52
SDL_Window::x
int x
Definition: SDL_sysvideo.h:77
WIN_RaiseWindow
void WIN_RaiseWindow(_THIS, SDL_Window *window)
SDL_Window::magic
const void * magic
Definition: SDL_sysvideo.h:73
rect
SDL_Rect rect
Definition: testrelative.c:27
window
SDL_Window * window
Definition: testautomation_render.c:26
WIN_GetWindowGammaRamp
int WIN_GetWindowGammaRamp(_THIS, SDL_Window *window, Uint16 *ramp)
WIN_WindowProc
LRESULT CALLBACK WIN_WindowProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
WIN_DestroyWindow
void WIN_DestroyWindow(_THIS, SDL_Window *window)
WIN_GetWindowWMInfo
SDL_bool WIN_GetWindowWMInfo(_THIS, SDL_Window *window, struct SDL_SysWMinfo *info)
SDL_Surface
A collection of pixels used in software blitting.
Definition: SDL_surface.h:69
SDL_VideoDevice::driverdata
void * driverdata
Definition: SDL_sysvideo.h:332
data
GLint GLenum GLsizei GLsizei GLsizei GLint GLsizei const GLvoid * data
Definition: SDL_opengl.h:1967
WIN_MaximizeWindow
void WIN_MaximizeWindow(_THIS, SDL_Window *window)
SDL_GetHint
#define SDL_GetHint
Definition: SDL_dynapi_overrides.h:197
SDL_SysWMinfo::version
SDL_version version
Definition: SDL_syswm.h:183
SDL_WindowData::expected_resize
SDL_bool expected_resize
Definition: SDL_windowswindow.h:41
SDL_version::major
Uint8 major
Definition: SDL_version.h:53
SDL_WriteLE16
#define SDL_WriteLE16
Definition: SDL_dynapi_overrides.h:370
SDL_Appname
LPTSTR SDL_Appname
SDL_VideoDevice::profile_mask
int profile_mask
Definition: SDL_sysvideo.h:310
SDL_SysWMinfo::subsystem
SDL_SYSWM_TYPE subsystem
Definition: SDL_syswm.h:184
SDL_WindowData::window
SDL_Window * window
Definition: SDL_cocoawindow.h:110
SDL_WindowData::hdc
HDC hdc
Definition: SDL_windowswindow.h:34
SDL_Surface::w
int w
Definition: SDL_surface.h:73
top
GLdouble GLdouble GLdouble GLdouble top
Definition: SDL_opengl_glext.h:6103
SDL_Window::windowed
SDL_Rect windowed
Definition: SDL_sysvideo.h:85
WIN_OnWindowEnter
void WIN_OnWindowEnter(_THIS, SDL_Window *window)
SDL_DisplayData
Definition: SDL_cocoamodes.h:26
SDL_WINDOW_SHOWN
Definition: SDL_video.h:100
SDL_WindowData::initializing
SDL_bool initializing
Definition: SDL_windowswindow.h:40
SDL_VideoDevice::gl_data
struct SDL_GLDriverData * gl_data
Definition: SDL_sysvideo.h:333
WIN_SetWindowPosition
void WIN_SetWindowPosition(_THIS, SDL_Window *window)
SDL_WindowData
Definition: SDL_androidwindow.h:34
WIN_SetWindowHitTest
int WIN_SetWindowHitTest(SDL_Window *window, SDL_bool enabled)
WIN_CreateWindow
int WIN_CreateWindow(_THIS, SDL_Window *window)
_this
static SDL_VideoDevice * _this
Definition: SDL_video.c:114
SDL_bool
SDL_bool
Definition: SDL_stdinc.h:126
SDL_VideoDevice::gl_config
struct SDL_VideoDevice::@29 gl_config
SDL_SYSWM_WINDOWS
Definition: SDL_syswm.h:115
SDL_WindowData::windowed_mode_was_maximized
SDL_bool windowed_mode_was_maximized
Definition: SDL_windowswindow.h:45
SDL_DisplayData::DeviceName
TCHAR DeviceName[32]
Definition: SDL_windowsmodes.h:28
SDL_WindowData::in_border_change
SDL_bool in_border_change
Definition: SDL_windowswindow.h:42
SDL_calloc
void * SDL_calloc(size_t nmemb, size_t size)
WIN_GetDisplayBounds
int WIN_GetDisplayBounds(_THIS, SDL_VideoDisplay *display, SDL_Rect *rect)
SDL_SysWMinfo
Definition: SDL_syswm.h:181
y
GLint GLint GLint GLint GLint GLint y
Definition: SDL_opengl.h:1567
SDL_WindowData::wndproc
WNDPROC wndproc
Definition: SDL_windowswindow.h:37
SDL_Surface::pixels
void * pixels
Definition: SDL_surface.h:75
WIN_MinimizeWindow
void WIN_MinimizeWindow(_THIS, SDL_Window *window)
_THIS
#define _THIS
Definition: SDL_alsa_audio.h:31
SDL_WindowData::videodata
struct SDL_VideoData * videodata
Definition: SDL_cocoawindow.h:116
Uint8
uint8_t Uint8
An unsigned 8-bit integer type.
Definition: SDL_stdinc.h:139
SDL_stack_alloc
#define SDL_stack_alloc(type, count)
Definition: SDL_stdinc.h:324
SDL_free
void SDL_free(void *mem)
TRUE
#define TRUE
Definition: edid-parse.c:31
WIN_SetWindowIcon
void WIN_SetWindowIcon(_THIS, SDL_Window *window, SDL_Surface *icon)
WIN_ShowWindow
void WIN_ShowWindow(_THIS, SDL_Window *window)
SDL_hints.h
SDL_RWFromMem
#define SDL_RWFromMem
Definition: SDL_dynapi_overrides.h:358
WIN_UpdateClipCursor
void WIN_UpdateClipCursor(SDL_Window *window)
WIN_StringToUTF8
#define WIN_StringToUTF8(S)
Definition: SDL_windows.h:45
SDL_zero
#define SDL_zero(x)
Definition: SDL_stdinc.h:355
SDL_HINT_VIDEO_WINDOW_SHARE_PIXEL_FORMAT
#define SDL_HINT_VIDEO_WINDOW_SHARE_PIXEL_FORMAT
A variable that is the address of another SDL_Window* (as a hex string formatted with "%p")...
Definition: SDL_hints.h:422
SDL_WINDOW_MINIMIZED
Definition: SDL_video.h:104
SDL_sscanf
#define SDL_sscanf
Definition: SDL_dynapi_overrides.h:45
SDL_Window::title
char * title
Definition: SDL_sysvideo.h:75
SDL_Window::y
int y
Definition: SDL_sysvideo.h:77
SDL_Rect::x
int x
Definition: SDL_rect.h:66
SDL_TRUE
Definition: SDL_stdinc.h:129
SDL_VIDEO_OPENGL_WGL
#define SDL_VIDEO_OPENGL_WGL
Definition: SDL_config_windows.h:194
TWF_FINETOUCH
#define TWF_FINETOUCH
Definition: SDL_windowsvideo.h:55
TWF_WANTPALM
#define TWF_WANTPALM
Definition: SDL_windowsvideo.h:56
SDL_Rect::w
int w
Definition: SDL_rect.h:67
WIN_RestoreWindow
void WIN_RestoreWindow(_THIS, SDL_Window *window)
SDL_VideoDevice::window_magic
Uint8 window_magic
Definition: SDL_sysvideo.h:283
enabled
GLenum GLenum GLsizei const GLuint GLboolean enabled
Definition: SDL_opengl_glext.h:2479
SDL_VideoDisplay
Definition: SDL_sysvideo.h:120
SDL_Window::h
int h
Definition: SDL_sysvideo.h:78
SDL_assert
#define SDL_assert(condition)
Definition: SDL_assert.h:167
WIN_SetWindowGammaRamp
int WIN_SetWindowGammaRamp(_THIS, SDL_Window *window, const Uint16 *ramp)
SDL_SysWMinfo::window
Window window
Definition: SDL_syswm.h:204
SDL_ShouldAllowTopmost
SDL_bool SDL_ShouldAllowTopmost(void)
Definition: SDL_video.c:3619
NULL
#define NULL
Definition: begin_code.h:143
SDL_OutOfMemory
#define SDL_OutOfMemory()
Definition: SDL_error.h:52
SDL_WINDOW_INPUT_FOCUS
Definition: SDL_video.h:107
SDL_WINDOW_RESIZABLE
Definition: SDL_video.h:103
SDL_Surface::format
SDL_PixelFormat * format
Definition: SDL_surface.h:72
SDL_RWclose
#define SDL_RWclose(ctx)
Definition: SDL_rwops.h:189
WIN_SetError
int WIN_SetError(const char *prefix)
SDL_WINDOW_BORDERLESS
Definition: SDL_video.h:102
SDL_SetError
#define SDL_SetError
Definition: SDL_dynapi_overrides.h:36
WIN_SetWindowTitle
void WIN_SetWindowTitle(_THIS, SDL_Window *window)
WIN_PumpEvents
void WIN_PumpEvents(_THIS)
SDL_GetDisplayForWindow
SDL_VideoDisplay * SDL_GetDisplayForWindow(SDL_Window *window)
Definition: SDL_video.c:1039
WIN_SetWindowGrab
void WIN_SetWindowGrab(_THIS, SDL_Window *window, SDL_bool grabbed)
SDL_Rect::h
int h
Definition: SDL_rect.h:67
SDL_Window
The type used to identify a window.
Definition: SDL_sysvideo.h:71
SDL_WINDOW_MAXIMIZED
Definition: SDL_video.h:105
SDL_WindowData::focus_click_pending
SDL_bool focus_click_pending
Definition: SDL_windowswindow.h:44
SDL_FALSE
Definition: SDL_stdinc.h:128
SDL_WINDOW_FULLSCREEN
Definition: SDL_video.h:98
SDL_Surface::pitch
int pitch
Definition: SDL_surface.h:74
WIN_SetWindowFullscreen
void WIN_SetWindowFullscreen(_THIS, SDL_Window *window, SDL_VideoDisplay *display, SDL_bool fullscreen)
SDL_WriteLE32
#define SDL_WriteLE32
Definition: SDL_dynapi_overrides.h:372
SDL_VideoData
Definition: SDL_androidvideo.h:35
Uint16
uint16_t Uint16
An unsigned 16-bit integer type.
Definition: SDL_stdinc.h:147
SDL_WindowData::in_window_deactivation
SDL_bool in_window_deactivation
Definition: SDL_windowswindow.h:46
SDL_SysWMinfo::info
union SDL_SysWMinfo::@18 info
SDL_WindowData::created
SDL_bool created
Definition: SDL_cocoawindow.h:113
flags
GLbitfield flags
Definition: SDL_opengl_glext.h:1480
SDL_WINDOW_OPENGL
Definition: SDL_video.h:99
WIN_SetWindowBordered
void WIN_SetWindowBordered(_THIS, SDL_Window *window, SDL_bool bordered)
SDL_Mouse
Definition: SDL_mouse_c.h:43
w
GLubyte GLubyte GLubyte GLubyte w
Definition: SDL_opengl_glext.h:731
SDL_Window::driverdata
void * driverdata
Definition: SDL_sysvideo.h:106
WIN_CreateWindowFrom
int WIN_CreateWindowFrom(_THIS, SDL_Window *window, const void *data)
SDL_PixelFormat::format
Uint32 format
Definition: SDL_pixels.h:301
SDL_stack_free
#define SDL_stack_free(data)
Definition: SDL_stdinc.h:325
WIN_HideWindow
void WIN_HideWindow(_THIS, SDL_Window *window)
FALSE
#define FALSE
Definition: edid-parse.c:32
SDL_windowswindow.h
SDL_WindowData::mouse_button_flags
WPARAM mouse_button_flags
Definition: SDL_windowswindow.h:39
SDL_Window::flags
Uint32 flags
Definition: SDL_sysvideo.h:81
SDL_GL_CONTEXT_PROFILE_ES
Definition: SDL_video.h:202
SDL_windowsvideo.h
src
GLenum src
Definition: SDL_opengl_glext.h:1737
SDL_syswm.h
SDL_Rect::y
int y
Definition: SDL_rect.h:66
SDL_WINDOW_INPUT_GRABBED
Definition: SDL_video.h:106
h
GLfloat GLfloat GLfloat GLfloat h
Definition: SDL_opengl_glext.h:1946
SDL_Rect
A rectangle, with the origin at the upper left.
Definition: SDL_rect.h:64
SDL_VideoDisplay::driverdata
void * driverdata
Definition: SDL_sysvideo.h:133
SDL_assert.h