21 #include "../../SDL_internal.h"
23 #if SDL_VIDEO_DRIVER_WINDOWS
25 #include "../../core/windows/SDL_windows.h"
27 #include "../SDL_sysvideo.h"
28 #include "../SDL_pixels_c.h"
29 #include "../../events/SDL_keyboard_c.h"
30 #include "../../events/SDL_mouse_c.h"
44 #ifndef SWP_NOCOPYBITS
45 #define SWP_NOCOPYBITS 0
49 HWND SDL_HelperWindow =
NULL;
50 static WCHAR *SDL_HelperWindowClassName = TEXT(
"SDLHelperWindowInputCatcher");
51 static WCHAR *SDL_HelperWindowName = TEXT(
"SDLHelperWindowInputMsgWindow");
52 static ATOM SDL_HelperWindowClass = 0;
61 #define STYLE_BASIC (WS_CLIPSIBLINGS | WS_CLIPCHILDREN)
62 #define STYLE_FULLSCREEN (WS_POPUP)
63 #define STYLE_BORDERLESS (WS_POPUP)
64 #define STYLE_BORDERLESS_WINDOWED (WS_POPUP | WS_CAPTION | WS_SYSMENU | WS_MINIMIZEBOX)
65 #define STYLE_NORMAL (WS_OVERLAPPED | WS_CAPTION | WS_SYSMENU | WS_MINIMIZEBOX)
66 #define STYLE_RESIZABLE (WS_THICKFRAME | WS_MAXIMIZEBOX)
67 #define STYLE_MASK (STYLE_FULLSCREEN | STYLE_BORDERLESS | STYLE_NORMAL | STYLE_RESIZABLE)
75 style |= STYLE_FULLSCREEN;
88 style |= STYLE_BORDERLESS_WINDOWED;
90 style |= STYLE_BORDERLESS;
93 style |= STYLE_NORMAL;
102 style |= STYLE_RESIZABLE;
108 style |= WS_MINIMIZE;
128 AdjustWindowRectEx(&
rect, style, menu, 0);
144 style = GetWindowLong(hwnd, GWL_STYLE);
145 menu = (style & WS_CHILDWINDOW) ?
FALSE : (GetMenu(hwnd) !=
NULL);
162 top = HWND_NOTOPMOST;
185 data->parent = parent;
186 data->hdc = GetDC(hwnd);
187 data->hinstance = (
HINSTANCE) GetWindowLongPtr(hwnd, GWLP_HINSTANCE);
188 data->created = created;
189 data->mouse_button_flags = 0;
190 data->last_pointer_update = (LPARAM)-1;
191 data->videodata = videodata;
197 if (!SetProp(hwnd, TEXT(
"SDL_WindowData"),
data)) {
198 ReleaseDC(hwnd,
data->hdc);
205 data->wndproc = (WNDPROC) GetWindowLongPtr(hwnd, GWLP_WNDPROC);
212 data->wndproc = (WNDPROC) GetWindowLong(hwnd, GWL_WNDPROC);
223 if (GetClientRect(hwnd, &
rect)) {
231 SetWindowPos(hwnd, HWND_NOTOPMOST,
x,
y,
w,
h, SWP_NOCOPYBITS | SWP_NOZORDER | SWP_NOACTIVATE);
242 if (ClientToScreen(hwnd, &point)) {
248 DWORD style = GetWindowLong(hwnd, GWL_STYLE);
249 if (style & WS_VISIBLE) {
254 if (style & WS_POPUP) {
259 if (style & WS_THICKFRAME) {
265 if (style & WS_MAXIMIZE) {
273 if (style & WS_MINIMIZE) {
281 if (GetFocus() == hwnd) {
287 GetClientRect(hwnd, &
rect);
288 ClientToScreen(hwnd, (LPPOINT) &
rect);
289 ClientToScreen(hwnd, (LPPOINT) &
rect + 1);
295 if (videodata->RegisterTouchWindow) {
310 HWND hwnd, parent =
NULL;
311 DWORD style = STYLE_BASIC;
316 parent = CreateWindow(
SDL_Appname, TEXT(
""), STYLE_BASIC, 0, 0, 32, 32,
NULL,
NULL,
SDL_Instance,
NULL);
319 style |= GetWindowStyle(
window);
336 DestroyWindow(parent);
342 SetWindowPos(hwnd,
NULL, 0, 0, 0, 0, SWP_FRAMECHANGED | SWP_NOSIZE | SWP_NOZORDER | SWP_NOMOVE | SWP_NOACTIVATE);
345 ShowWindow(hwnd, SW_SHOWMINNOACTIVE);
353 #if SDL_VIDEO_OPENGL_ES2
359 #if SDL_VIDEO_OPENGL_EGL
366 return SDL_SetError(
"Could not create GLES window surface (EGL support not configured)");
371 #if SDL_VIDEO_OPENGL_WGL
377 return SDL_SetError(
"Could not create GL window (WGL support not configured)");
386 HWND hwnd = (HWND)
data;
392 titleLen = GetWindowTextLength(hwnd);
395 titleLen = GetWindowText(hwnd, title, titleLen + 1);
410 #if SDL_VIDEO_OPENGL_WGL
425 if (!WIN_GL_SetPixelFormatFrom(
_this, otherWindow,
window)) {
441 SetWindowText(hwnd, title);
451 int icon_len, mask_len,
y;
456 mask_len = (icon->
h * (icon->
w + 7)/8);
457 icon_len = 40 + icon->
h * icon->
w *
sizeof(
Uint32) + mask_len;
487 SDL_memset(icon_bmp + icon_len - mask_len, 0xFF, mask_len);
489 hicon = CreateIconFromResource(icon_bmp, icon_len,
TRUE, 0x00030000);
495 SendMessage(hwnd, WM_SETICON, ICON_SMALL, (LPARAM) hicon);
498 SendMessage(hwnd, WM_SETICON, ICON_BIG, (LPARAM) hicon);
504 WIN_SetWindowPositionInternal(
_this,
window, SWP_NOCOPYBITS | SWP_NOSIZE | SWP_NOACTIVATE);
510 WIN_SetWindowPositionInternal(
_this,
window, SWP_NOCOPYBITS | SWP_NOMOVE | SWP_NOACTIVATE);
517 RECT rcClient, rcWindow;
522 GetClientRect(hwnd, &rcClient);
523 GetWindowRect(hwnd, &rcWindow);
527 ptDiff.y = rcWindow.top;
528 ptDiff.x = rcWindow.left;
530 ScreenToClient(hwnd, &ptDiff);
532 rcWindow.top = ptDiff.y;
533 rcWindow.left = ptDiff.x;
537 ptDiff.y = rcWindow.bottom;
538 ptDiff.x = rcWindow.right;
540 ScreenToClient(hwnd, &ptDiff);
542 rcWindow.bottom = ptDiff.y;
543 rcWindow.right = ptDiff.x;
548 *
top = rcClient.top - rcWindow.top;
549 *
left = rcClient.left - rcWindow.left;
550 *
bottom = rcWindow.bottom - rcClient.bottom;
551 *
right = rcWindow.right - rcClient.right;
565 style = GetWindowLong(hwnd, GWL_EXSTYLE);
566 if (style & WS_EX_NOACTIVATE) {
567 nCmdShow = SW_SHOWNOACTIVATE;
569 ShowWindow(hwnd, nCmdShow);
576 ShowWindow(hwnd, SW_HIDE);
583 SetForegroundWindow(hwnd);
592 ShowWindow(hwnd, SW_MAXIMIZE);
600 ShowWindow(hwnd, SW_MINIMIZE);
610 style = GetWindowLong(hwnd, GWL_STYLE);
611 style &= ~STYLE_MASK;
612 style |= GetWindowStyle(
window);
615 SetWindowLong(hwnd, GWL_STYLE, style);
616 WIN_SetWindowPositionInternal(
_this,
window, SWP_NOCOPYBITS | SWP_FRAMECHANGED | SWP_NOZORDER | SWP_NOACTIVATE);
627 style = GetWindowLong(hwnd, GWL_STYLE);
628 style &= ~STYLE_MASK;
629 style |= GetWindowStyle(
window);
631 SetWindowLong(hwnd, GWL_STYLE, style);
640 ShowWindow(hwnd, SW_RESTORE);
658 top = HWND_NOTOPMOST;
661 style = GetWindowLong(hwnd, GWL_STYLE);
662 style &= ~STYLE_MASK;
663 style |= GetWindowStyle(
window);
676 if (style & WS_MAXIMIZE) {
678 style &= ~WS_MAXIMIZE;
689 if (
data->windowed_mode_was_maximized && !
data->in_window_deactivation) {
690 style |= WS_MAXIMIZE;
694 menu = (style & WS_CHILDWINDOW) ?
FALSE : (GetMenu(hwnd) !=
NULL);
697 SetWindowLong(hwnd, GWL_STYLE, style);
699 SetWindowPos(hwnd,
top,
x,
y,
w,
h, SWP_NOCOPYBITS | SWP_NOACTIVATE);
709 BOOL succeeded =
FALSE;
713 succeeded = SetDeviceGammaRamp(hdc, (LPVOID)ramp);
719 return succeeded ? 0 : -1;
728 BOOL succeeded =
FALSE;
732 succeeded = GetDeviceGammaRamp(hdc, (LPVOID)ramp);
738 return succeeded ? 0 : -1;
747 UINT
flags = SWP_NOCOPYBITS | SWP_NOMOVE | SWP_NOSIZE;
750 flags |= SWP_NOACTIVATE;
763 RemoveProp(
data->hwnd, TEXT(
"SDL_WindowData"));
765 DestroyWindow(
data->hwnd);
767 DestroyWindow(
data->parent);
773 SetWindowLongPtr(
data->hwnd, GWLP_WNDPROC,
774 (LONG_PTR)
data->wndproc);
776 SetWindowLong(
data->hwnd, GWL_WNDPROC,
777 (LONG_PTR)
data->wndproc);
801 info->
info.win.hinstance =
data->hinstance;
816 SDL_HelperWindowCreate(
void)
822 if (SDL_HelperWindow !=
NULL) {
828 wce.lpfnWndProc = DefWindowProc;
829 wce.lpszClassName = (LPCWSTR) SDL_HelperWindowClassName;
830 wce.hInstance = hInstance;
833 SDL_HelperWindowClass = RegisterClass(&wce);
834 if (SDL_HelperWindowClass == 0 && GetLastError() != ERROR_CLASS_ALREADY_EXISTS) {
835 return WIN_SetError(
"Unable to create Helper Window Class");
839 SDL_HelperWindow = CreateWindowEx(0, SDL_HelperWindowClassName,
840 SDL_HelperWindowName,
841 WS_OVERLAPPED, CW_USEDEFAULT,
842 CW_USEDEFAULT, CW_USEDEFAULT,
843 CW_USEDEFAULT, HWND_MESSAGE,
NULL,
845 if (SDL_HelperWindow ==
NULL) {
846 UnregisterClass(SDL_HelperWindowClassName, hInstance);
858 SDL_HelperWindowDestroy(
void)
863 if (SDL_HelperWindow !=
NULL) {
864 if (DestroyWindow(SDL_HelperWindow) == 0) {
868 SDL_HelperWindow =
NULL;
872 if (SDL_HelperWindowClass != 0) {
873 if ((UnregisterClass(SDL_HelperWindowClassName, hInstance)) == 0) {
877 SDL_HelperWindowClass = 0;
891 WIN_SetWindowPositionInternal(
_this,
window, SWP_NOCOPYBITS | SWP_NOSIZE | SWP_NOACTIVATE);
896 TRACKMOUSEEVENT trackMouseEvent;
898 trackMouseEvent.cbSize =
sizeof(TRACKMOUSEEVENT);
899 trackMouseEvent.dwFlags = TME_LEAVE;
900 trackMouseEvent.hwndTrack =
data->hwnd;
902 TrackMouseEvent(&trackMouseEvent);
912 RECT
rect, clipped_rect;
914 if (
data->in_title_click ||
data->focus_click_pending) {
917 if (
data->skip_update_clipcursor) {
920 if (!GetClipCursor(&clipped_rect)) {
926 if (mouse->relative_mode && !mouse->relative_mode_warp) {
927 if (GetWindowRect(
data->hwnd, &
rect)) {
937 rect.bottom = cy + 1;
940 if (ClipCursor(&
rect)) {
946 if (GetClientRect(
data->hwnd, &
rect) && !IsRectEmpty(&
rect)) {
947 ClientToScreen(
data->hwnd, (LPPOINT) &
rect);
948 ClientToScreen(
data->hwnd, (LPPOINT) &
rect + 1);
950 if (ClipCursor(&
rect)) {
959 first.x = clipped_rect.left;
960 first.y = clipped_rect.top;
961 second.x = clipped_rect.right - 1;
962 second.y = clipped_rect.bottom - 1;
963 if (PtInRect(&
data->cursor_clipped_rect,
first) &&
964 PtInRect(&
data->cursor_clipped_rect, second)) {
983 const LONG style = GetWindowLong(hwnd, GWL_EXSTYLE);
987 if (opacity == 1.0f) {
989 if (style & WS_EX_LAYERED) {
990 if (SetWindowLong(hwnd, GWL_EXSTYLE, style & ~WS_EX_LAYERED) == 0) {
995 const BYTE
alpha = (BYTE) ((
int) (opacity * 255.0f));
997 if ((style & WS_EX_LAYERED) == 0) {
998 if (SetWindowLong(hwnd, GWL_EXSTYLE, style | WS_EX_LAYERED) == 0) {
1003 if (SetLayeredWindowAttributes(hwnd, 0,
alpha, LWA_ALPHA) == 0) {
#define SDL_assert(condition)
#define SDL_VIDEO_OPENGL_WGL
#define SDL_GetHintBoolean
#define SDL_OutOfMemory()
#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").
#define SDL_small_alloc(type, count, pisstack)
#define SDL_small_free(ptr, isstack)
void SDL_SetKeyboardFocus(SDL_Window *window)
SDL_Mouse * SDL_GetMouse(void)
GLint GLint GLint GLint GLint GLint y
GLint GLenum GLsizei GLsizei GLsizei GLint GLsizei const GLvoid * data
GLint GLint GLsizei width
GLint GLint GLint GLint GLint x
GLint GLint GLsizei GLsizei height
GLenum GLenum GLsizei const GLuint GLboolean enabled
GLdouble GLdouble GLdouble GLdouble top
GLfloat GLfloat GLfloat alpha
GLfloat GLfloat GLfloat GLfloat h
GLubyte GLubyte GLubyte GLubyte w
@ SDL_PIXELFORMAT_ARGB8888
SDL_bool SDL_ShouldAllowTopmost(void)
SDL_VideoDisplay * SDL_GetDisplayForWindow(SDL_Window *window)
Uint32 SDL_GetTicks(void)
Get the number of milliseconds since the SDL library initialization.
#define SDL_MINOR_VERSION
#define SDL_MAJOR_VERSION
#define SDL_VERSIONNUM(X, Y, Z)
static SDL_VideoDevice * _this
@ SDL_WINDOW_ALWAYS_ON_TOP
@ SDL_WINDOW_SKIP_TASKBAR
@ SDL_WINDOW_INPUT_GRABBED
@ SDL_GL_CONTEXT_PROFILE_ES
#define WIN_UTF8ToString(S)
#define WIN_StringToUTF8(S)
int WIN_SetError(const char *prefix)
LRESULT CALLBACK WIN_WindowProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
void WIN_PumpEvents(_THIS)
int WIN_GetDisplayBounds(_THIS, SDL_VideoDisplay *display, SDL_Rect *rect)
int WIN_GetWindowBordersSize(_THIS, SDL_Window *window, int *top, int *left, int *bottom, int *right)
void WIN_ShowWindow(_THIS, SDL_Window *window)
void WIN_SetWindowIcon(_THIS, SDL_Window *window, SDL_Surface *icon)
int WIN_SetWindowOpacity(_THIS, SDL_Window *window, float opacity)
void WIN_RaiseWindow(_THIS, SDL_Window *window)
int WIN_CreateWindowFrom(_THIS, SDL_Window *window, const void *data)
void WIN_SetWindowPosition(_THIS, SDL_Window *window)
void WIN_HideWindow(_THIS, SDL_Window *window)
void WIN_SetWindowBordered(_THIS, SDL_Window *window, SDL_bool bordered)
void WIN_DestroyWindow(_THIS, SDL_Window *window)
int WIN_GetWindowGammaRamp(_THIS, SDL_Window *window, Uint16 *ramp)
void WIN_MinimizeWindow(_THIS, SDL_Window *window)
void WIN_SetWindowGrab(_THIS, SDL_Window *window, SDL_bool grabbed)
void WIN_SetWindowTitle(_THIS, SDL_Window *window)
void WIN_MaximizeWindow(_THIS, SDL_Window *window)
void WIN_AcceptDragAndDrop(SDL_Window *window, SDL_bool accept)
void WIN_RestoreWindow(_THIS, SDL_Window *window)
void WIN_SetWindowResizable(_THIS, SDL_Window *window, SDL_bool resizable)
void WIN_SetWindowFullscreen(_THIS, SDL_Window *window, SDL_VideoDisplay *display, SDL_bool fullscreen)
int WIN_SetWindowHitTest(SDL_Window *window, SDL_bool enabled)
void WIN_OnWindowEnter(_THIS, SDL_Window *window)
int WIN_CreateWindow(_THIS, SDL_Window *window)
SDL_bool WIN_GetWindowWMInfo(_THIS, SDL_Window *window, struct SDL_SysWMinfo *info)
void WIN_UpdateClipCursor(SDL_Window *window)
int WIN_SetWindowGammaRamp(_THIS, SDL_Window *window, const Uint16 *ramp)
void WIN_SetWindowSize(_THIS, SDL_Window *window)
EGLSurface EGLNativeWindowType * window
set set set set set set set macro pixldst1 abits if abits op else op endif endm macro pixldst2 abits if abits op else op endif endm macro pixldst4 abits if abits op else op endif endm macro pixldst0 abits op endm macro pixldst3 mem_operand op endm macro pixldst30 mem_operand op endm macro pixldst abits if abits elseif abits elseif abits elseif abits elseif abits pixldst0 abits else pixldst0 abits pixldst0 abits pixldst0 abits pixldst0 abits endif elseif abits else pixldst0 abits pixldst0 abits endif elseif abits else error unsupported bpp *numpix else pixst endif endm macro pixld1_s mem_operand if asr adds SRC_WIDTH_FIXED bpl add asl mov asr adds SRC_WIDTH_FIXED bpl add asl mov asr adds SRC_WIDTH_FIXED bpl add asl mov asr adds SRC_WIDTH_FIXED bpl add asl elseif asr adds SRC_WIDTH_FIXED bpl add asl mov asr adds SRC_WIDTH_FIXED bpl add asl else error unsupported endif endm macro pixld2_s mem_operand if mov asr add asl add asl mov asr sub UNIT_X add asl mov asr add asl add asl mov asr add UNIT_X add asl else pixld1_s mem_operand pixld1_s mem_operand endif endm macro pixld0_s mem_operand if asr adds SRC_WIDTH_FIXED bpl add asl elseif asr adds SRC_WIDTH_FIXED bpl add asl endif endm macro pixld_s_internal mem_operand if mem_operand pixld2_s mem_operand pixdeinterleave basereg elseif mem_operand elseif mem_operand elseif mem_operand elseif mem_operand pixld0_s mem_operand else pixld0_s mem_operand pixld0_s mem_operand pixld0_s mem_operand pixld0_s mem_operand endif elseif mem_operand else pixld0_s mem_operand pixld0_s mem_operand endif elseif mem_operand else error unsupported mem_operand if bpp mem_operand endif endm macro vuzp8 reg2 vuzp d d ®2 endm macro vzip8 reg2 vzip d d ®2 endm macro pixdeinterleave basereg basereg basereg basereg basereg endif endm macro pixinterleave basereg basereg basereg basereg basereg endif endm macro PF boost_increment endif if endif PF tst PF addne PF subne PF cmp ORIG_W if endif if endif if endif PF subge ORIG_W PF subges if endif if endif if endif endif endm macro cache_preload_simple endif if dst_r_bpp pld[DST_R, #(PREFETCH_DISTANCE_SIMPLE *dst_r_bpp/8)] endif if mask_bpp pld endif[MASK, #(PREFETCH_DISTANCE_SIMPLE *mask_bpp/8)] endif endif endm macro fetch_mask_pixblock pixld mask_basereg pixblock_size MASK endm macro ensure_destination_ptr_alignment process_pixblock_tail_head if beq irp skip1 beq endif SRC MASK if dst_r_bpp DST_R else add endif PF add sub src_basereg pixdeinterleave mask_basereg pixdeinterleave dst_r_basereg process_pixblock_head pixblock_size cache_preload_simple process_pixblock_tail pixinterleave dst_w_basereg irp beq endif process_pixblock_tail_head tst beq irp if pixblock_size chunk_size tst beq pixld_src SRC pixld MASK if DST_R else pixld DST_R endif if
set set set set set set set macro pixldst1 abits if abits op else op endif endm macro pixldst2 abits if abits op else op endif endm macro pixldst4 abits if abits op else op endif endm macro pixldst0 abits op endm macro pixldst3 mem_operand op endm macro pixldst30 mem_operand op endm macro pixldst abits if abits elseif abits elseif abits elseif abits elseif abits pixldst0 abits else pixldst0 abits pixldst0 abits pixldst0 abits pixldst0 abits endif elseif abits else pixldst0 abits pixldst0 abits endif elseif abits else error unsupported bpp *numpix else pixst endif endm macro pixld1_s mem_operand if asr adds SRC_WIDTH_FIXED bpl add asl mov asr adds SRC_WIDTH_FIXED bpl add asl mov asr adds SRC_WIDTH_FIXED bpl add asl mov asr adds SRC_WIDTH_FIXED bpl add asl elseif asr adds SRC_WIDTH_FIXED bpl add asl mov asr adds SRC_WIDTH_FIXED bpl add asl else error unsupported endif endm macro pixld2_s mem_operand if mov asr add asl add asl mov asr sub UNIT_X add asl mov asr add asl add asl mov asr add UNIT_X add asl else pixld1_s mem_operand pixld1_s mem_operand endif endm macro pixld0_s mem_operand if asr adds SRC_WIDTH_FIXED bpl add asl elseif asr adds SRC_WIDTH_FIXED bpl add asl endif endm macro pixld_s_internal mem_operand if mem_operand pixld2_s mem_operand pixdeinterleave basereg elseif mem_operand elseif mem_operand elseif mem_operand elseif mem_operand pixld0_s mem_operand else pixld0_s mem_operand pixld0_s mem_operand pixld0_s mem_operand pixld0_s mem_operand endif elseif mem_operand else pixld0_s mem_operand pixld0_s mem_operand endif elseif mem_operand else error unsupported mem_operand if bpp mem_operand endif endm macro vuzp8 reg2 vuzp d d ®2 endm macro vzip8 reg2 vzip d d ®2 endm macro pixdeinterleave basereg basereg basereg basereg basereg endif endm macro pixinterleave basereg basereg basereg basereg basereg endif endm macro PF boost_increment endif if endif PF tst PF addne PF subne PF cmp ORIG_W if endif if endif if endif PF subge ORIG_W PF subges if endif if endif if endif endif endm macro cache_preload_simple endif if dst_r_bpp pld[DST_R, #(PREFETCH_DISTANCE_SIMPLE *dst_r_bpp/8)] endif if mask_bpp pld if[MASK, #(PREFETCH_DISTANCE_SIMPLE *mask_bpp/8)] endif endif endm macro fetch_mask_pixblock pixld mask_basereg pixblock_size MASK endm macro ensure_destination_ptr_alignment process_pixblock_tail_head if beq irp skip1(dst_w_bpp<=(lowbit *8)) &&((lowbit *8)<(pixblock_size *dst_w_bpp)) .if lowbit< 16 tst DST_R
A rectangle, with the origin at the upper left (integer).
A collection of pixels used in software blitting.
union SDL_SysWMinfo::@10 info
struct SDL_VideoDevice::@440 gl_config
struct SDL_GLDriverData * gl_data
The type used to identify a window.
struct HINSTANCE__ * HINSTANCE