SDL  2.0
SDL_windowsevents.c
Go to the documentation of this file.
1 /*
2  Simple DirectMedia Layer
3  Copyright (C) 1997-2020 Sam Lantinga <slouken@libsdl.org>
4 
5  This software is provided 'as-is', without any express or implied
6  warranty. In no event will the authors be held liable for any damages
7  arising from the use of this software.
8 
9  Permission is granted to anyone to use this software for any purpose,
10  including commercial applications, and to alter it and redistribute it
11  freely, subject to the following restrictions:
12 
13  1. The origin of this software must not be misrepresented; you must not
14  claim that you wrote the original software. If you use this software
15  in a product, an acknowledgment in the product documentation would be
16  appreciated but is not required.
17  2. Altered source versions must be plainly marked as such, and must not be
18  misrepresented as being the original software.
19  3. This notice may not be removed or altered from any source distribution.
20 */
21 #include "../../SDL_internal.h"
22 
23 #if SDL_VIDEO_DRIVER_WINDOWS
24 
25 #include "SDL_windowsvideo.h"
26 #include "SDL_windowsshape.h"
27 #include "SDL_system.h"
28 #include "SDL_syswm.h"
29 #include "SDL_timer.h"
30 #include "SDL_vkeys.h"
31 #include "SDL_hints.h"
32 #include "../../events/SDL_events_c.h"
33 #include "../../events/SDL_touch_c.h"
34 #include "../../events/scancodes_windows.h"
35 #include "SDL_assert.h"
36 #include "SDL_hints.h"
37 
38 /* Dropfile support */
39 #include <shellapi.h>
40 
41 /* For GET_X_LPARAM, GET_Y_LPARAM. */
42 #include <windowsx.h>
43 
44 /* #define WMMSG_DEBUG */
45 #ifdef WMMSG_DEBUG
46 #include <stdio.h>
47 #include "wmmsg.h"
48 #endif
49 
50 /* Masks for processing the windows KEYDOWN and KEYUP messages */
51 #define REPEATED_KEYMASK (1<<30)
52 #define EXTENDED_KEYMASK (1<<24)
53 
54 #define VK_ENTER 10 /* Keypad Enter ... no VKEY defined? */
55 #ifndef VK_OEM_NEC_EQUAL
56 #define VK_OEM_NEC_EQUAL 0x92
57 #endif
58 
59 /* Make sure XBUTTON stuff is defined that isn't in older Platform SDKs... */
60 #ifndef WM_XBUTTONDOWN
61 #define WM_XBUTTONDOWN 0x020B
62 #endif
63 #ifndef WM_XBUTTONUP
64 #define WM_XBUTTONUP 0x020C
65 #endif
66 #ifndef GET_XBUTTON_WPARAM
67 #define GET_XBUTTON_WPARAM(w) (HIWORD(w))
68 #endif
69 #ifndef WM_INPUT
70 #define WM_INPUT 0x00ff
71 #endif
72 #ifndef WM_TOUCH
73 #define WM_TOUCH 0x0240
74 #endif
75 #ifndef WM_MOUSEHWHEEL
76 #define WM_MOUSEHWHEEL 0x020E
77 #endif
78 #ifndef WM_UNICHAR
79 #define WM_UNICHAR 0x0109
80 #endif
81 
82 static SDL_Scancode
83 VKeytoScancode(WPARAM vkey)
84 {
85  switch (vkey) {
86 /* Windows generates this virtual keycode for Keypad 5 when NumLock is off.
87  case VK_CLEAR: return SDL_SCANCODE_CLEAR;
88 */
89  case VK_LEFT: return SDL_SCANCODE_LEFT;
90  case VK_UP: return SDL_SCANCODE_UP;
91  case VK_RIGHT: return SDL_SCANCODE_RIGHT;
92  case VK_DOWN: return SDL_SCANCODE_DOWN;
93 
94  case VK_MODECHANGE: return SDL_SCANCODE_MODE;
95  case VK_SELECT: return SDL_SCANCODE_SELECT;
96  case VK_EXECUTE: return SDL_SCANCODE_EXECUTE;
97  case VK_HELP: return SDL_SCANCODE_HELP;
98  case VK_PAUSE: return SDL_SCANCODE_PAUSE;
99  case VK_NUMLOCK: return SDL_SCANCODE_NUMLOCKCLEAR;
100 
101  case VK_F13: return SDL_SCANCODE_F13;
102  case VK_F14: return SDL_SCANCODE_F14;
103  case VK_F15: return SDL_SCANCODE_F15;
104  case VK_F16: return SDL_SCANCODE_F16;
105  case VK_F17: return SDL_SCANCODE_F17;
106  case VK_F18: return SDL_SCANCODE_F18;
107  case VK_F19: return SDL_SCANCODE_F19;
108  case VK_F20: return SDL_SCANCODE_F20;
109  case VK_F21: return SDL_SCANCODE_F21;
110  case VK_F22: return SDL_SCANCODE_F22;
111  case VK_F23: return SDL_SCANCODE_F23;
112  case VK_F24: return SDL_SCANCODE_F24;
113 
114  case VK_OEM_NEC_EQUAL: return SDL_SCANCODE_KP_EQUALS;
115  case VK_BROWSER_BACK: return SDL_SCANCODE_AC_BACK;
116  case VK_BROWSER_FORWARD: return SDL_SCANCODE_AC_FORWARD;
117  case VK_BROWSER_REFRESH: return SDL_SCANCODE_AC_REFRESH;
118  case VK_BROWSER_STOP: return SDL_SCANCODE_AC_STOP;
119  case VK_BROWSER_SEARCH: return SDL_SCANCODE_AC_SEARCH;
120  case VK_BROWSER_FAVORITES: return SDL_SCANCODE_AC_BOOKMARKS;
121  case VK_BROWSER_HOME: return SDL_SCANCODE_AC_HOME;
122  case VK_VOLUME_MUTE: return SDL_SCANCODE_AUDIOMUTE;
123  case VK_VOLUME_DOWN: return SDL_SCANCODE_VOLUMEDOWN;
124  case VK_VOLUME_UP: return SDL_SCANCODE_VOLUMEUP;
125 
126  case VK_MEDIA_NEXT_TRACK: return SDL_SCANCODE_AUDIONEXT;
127  case VK_MEDIA_PREV_TRACK: return SDL_SCANCODE_AUDIOPREV;
128  case VK_MEDIA_STOP: return SDL_SCANCODE_AUDIOSTOP;
129  case VK_MEDIA_PLAY_PAUSE: return SDL_SCANCODE_AUDIOPLAY;
130  case VK_LAUNCH_MAIL: return SDL_SCANCODE_MAIL;
131  case VK_LAUNCH_MEDIA_SELECT: return SDL_SCANCODE_MEDIASELECT;
132 
134 
135  case VK_ATTN: return SDL_SCANCODE_SYSREQ;
136  case VK_CRSEL: return SDL_SCANCODE_CRSEL;
137  case VK_EXSEL: return SDL_SCANCODE_EXSEL;
138  case VK_OEM_CLEAR: return SDL_SCANCODE_CLEAR;
139 
140  case VK_LAUNCH_APP1: return SDL_SCANCODE_APP1;
141  case VK_LAUNCH_APP2: return SDL_SCANCODE_APP2;
142 
143  default: return SDL_SCANCODE_UNKNOWN;
144  }
145 }
146 
147 static SDL_Scancode
148 WindowsScanCodeToSDLScanCode(LPARAM lParam, WPARAM wParam)
149 {
150  SDL_Scancode code;
151  int nScanCode = (lParam >> 16) & 0xFF;
152  SDL_bool bIsExtended = (lParam & (1 << 24)) != 0;
153 
154  code = VKeytoScancode(wParam);
155 
156  if (code == SDL_SCANCODE_UNKNOWN && nScanCode <= 127) {
157  code = windows_scancode_table[nScanCode];
158 
159  if (bIsExtended) {
160  switch (code) {
161  case SDL_SCANCODE_RETURN:
162  code = SDL_SCANCODE_KP_ENTER;
163  break;
164  case SDL_SCANCODE_LALT:
165  code = SDL_SCANCODE_RALT;
166  break;
167  case SDL_SCANCODE_LCTRL:
168  code = SDL_SCANCODE_RCTRL;
169  break;
170  case SDL_SCANCODE_SLASH:
171  code = SDL_SCANCODE_KP_DIVIDE;
172  break;
174  code = SDL_SCANCODE_KP_PLUS;
175  break;
176  default:
177  break;
178  }
179  } else {
180  switch (code) {
181  case SDL_SCANCODE_HOME:
182  code = SDL_SCANCODE_KP_7;
183  break;
184  case SDL_SCANCODE_UP:
185  code = SDL_SCANCODE_KP_8;
186  break;
187  case SDL_SCANCODE_PAGEUP:
188  code = SDL_SCANCODE_KP_9;
189  break;
190  case SDL_SCANCODE_LEFT:
191  code = SDL_SCANCODE_KP_4;
192  break;
193  case SDL_SCANCODE_RIGHT:
194  code = SDL_SCANCODE_KP_6;
195  break;
196  case SDL_SCANCODE_END:
197  code = SDL_SCANCODE_KP_1;
198  break;
199  case SDL_SCANCODE_DOWN:
200  code = SDL_SCANCODE_KP_2;
201  break;
203  code = SDL_SCANCODE_KP_3;
204  break;
205  case SDL_SCANCODE_INSERT:
206  code = SDL_SCANCODE_KP_0;
207  break;
208  case SDL_SCANCODE_DELETE:
209  code = SDL_SCANCODE_KP_PERIOD;
210  break;
213  break;
214  default:
215  break;
216  }
217  }
218  }
219  return code;
220 }
221 
222 static SDL_bool
223 WIN_ShouldIgnoreFocusClick()
224 {
226 }
227 
228 static void
229 WIN_CheckWParamMouseButton(SDL_bool bwParamMousePressed, SDL_bool bSDLMousePressed, SDL_WindowData *data, Uint8 button, SDL_MouseID mouseID)
230 {
231  if (data->focus_click_pending & SDL_BUTTON(button)) {
232  /* Ignore the button click for activation */
233  if (!bwParamMousePressed) {
234  data->focus_click_pending &= ~SDL_BUTTON(button);
235  WIN_UpdateClipCursor(data->window);
236  }
237  if (WIN_ShouldIgnoreFocusClick()) {
238  return;
239  }
240  }
241 
242  if (bwParamMousePressed && !bSDLMousePressed) {
243  SDL_SendMouseButton(data->window, mouseID, SDL_PRESSED, button);
244  } else if (!bwParamMousePressed && bSDLMousePressed) {
245  SDL_SendMouseButton(data->window, mouseID, SDL_RELEASED, button);
246  }
247 }
248 
249 /*
250 * Some windows systems fail to send a WM_LBUTTONDOWN sometimes, but each mouse move contains the current button state also
251 * so this function reconciles our view of the world with the current buttons reported by windows
252 */
253 static void
254 WIN_CheckWParamMouseButtons(WPARAM wParam, SDL_WindowData *data, SDL_MouseID mouseID)
255 {
256  if (wParam != data->mouse_button_flags) {
257  Uint32 mouseFlags = SDL_GetMouseState(NULL, NULL);
258  WIN_CheckWParamMouseButton((wParam & MK_LBUTTON), (mouseFlags & SDL_BUTTON_LMASK), data, SDL_BUTTON_LEFT, mouseID);
259  WIN_CheckWParamMouseButton((wParam & MK_MBUTTON), (mouseFlags & SDL_BUTTON_MMASK), data, SDL_BUTTON_MIDDLE, mouseID);
260  WIN_CheckWParamMouseButton((wParam & MK_RBUTTON), (mouseFlags & SDL_BUTTON_RMASK), data, SDL_BUTTON_RIGHT, mouseID);
261  WIN_CheckWParamMouseButton((wParam & MK_XBUTTON1), (mouseFlags & SDL_BUTTON_X1MASK), data, SDL_BUTTON_X1, mouseID);
262  WIN_CheckWParamMouseButton((wParam & MK_XBUTTON2), (mouseFlags & SDL_BUTTON_X2MASK), data, SDL_BUTTON_X2, mouseID);
263  data->mouse_button_flags = wParam;
264  }
265 }
266 
267 static void
268 WIN_CheckRawMouseButtons(ULONG rawButtons, SDL_WindowData *data)
269 {
270  if (rawButtons != data->mouse_button_flags) {
271  Uint32 mouseFlags = SDL_GetMouseState(NULL, NULL);
272  if ((rawButtons & RI_MOUSE_BUTTON_1_DOWN))
273  WIN_CheckWParamMouseButton((rawButtons & RI_MOUSE_BUTTON_1_DOWN), (mouseFlags & SDL_BUTTON_LMASK), data, SDL_BUTTON_LEFT, 0);
274  if ((rawButtons & RI_MOUSE_BUTTON_1_UP))
275  WIN_CheckWParamMouseButton(!(rawButtons & RI_MOUSE_BUTTON_1_UP), (mouseFlags & SDL_BUTTON_LMASK), data, SDL_BUTTON_LEFT, 0);
276  if ((rawButtons & RI_MOUSE_BUTTON_2_DOWN))
277  WIN_CheckWParamMouseButton((rawButtons & RI_MOUSE_BUTTON_2_DOWN), (mouseFlags & SDL_BUTTON_RMASK), data, SDL_BUTTON_RIGHT, 0);
278  if ((rawButtons & RI_MOUSE_BUTTON_2_UP))
279  WIN_CheckWParamMouseButton(!(rawButtons & RI_MOUSE_BUTTON_2_UP), (mouseFlags & SDL_BUTTON_RMASK), data, SDL_BUTTON_RIGHT, 0);
280  if ((rawButtons & RI_MOUSE_BUTTON_3_DOWN))
281  WIN_CheckWParamMouseButton((rawButtons & RI_MOUSE_BUTTON_3_DOWN), (mouseFlags & SDL_BUTTON_MMASK), data, SDL_BUTTON_MIDDLE, 0);
282  if ((rawButtons & RI_MOUSE_BUTTON_3_UP))
283  WIN_CheckWParamMouseButton(!(rawButtons & RI_MOUSE_BUTTON_3_UP), (mouseFlags & SDL_BUTTON_MMASK), data, SDL_BUTTON_MIDDLE, 0);
284  if ((rawButtons & RI_MOUSE_BUTTON_4_DOWN))
285  WIN_CheckWParamMouseButton((rawButtons & RI_MOUSE_BUTTON_4_DOWN), (mouseFlags & SDL_BUTTON_X1MASK), data, SDL_BUTTON_X1, 0);
286  if ((rawButtons & RI_MOUSE_BUTTON_4_UP))
287  WIN_CheckWParamMouseButton(!(rawButtons & RI_MOUSE_BUTTON_4_UP), (mouseFlags & SDL_BUTTON_X1MASK), data, SDL_BUTTON_X1, 0);
288  if ((rawButtons & RI_MOUSE_BUTTON_5_DOWN))
289  WIN_CheckWParamMouseButton((rawButtons & RI_MOUSE_BUTTON_5_DOWN), (mouseFlags & SDL_BUTTON_X2MASK), data, SDL_BUTTON_X2, 0);
290  if ((rawButtons & RI_MOUSE_BUTTON_5_UP))
291  WIN_CheckWParamMouseButton(!(rawButtons & RI_MOUSE_BUTTON_5_UP), (mouseFlags & SDL_BUTTON_X2MASK), data, SDL_BUTTON_X2, 0);
292  data->mouse_button_flags = rawButtons;
293  }
294 }
295 
296 static void
297 WIN_CheckAsyncMouseRelease(SDL_WindowData *data)
298 {
299  Uint32 mouseFlags;
300  SHORT keyState;
301 
302  /* mouse buttons may have changed state here, we need to resync them,
303  but we will get a WM_MOUSEMOVE right away which will fix things up if in non raw mode also
304  */
305  mouseFlags = SDL_GetMouseState(NULL, NULL);
306 
307  keyState = GetAsyncKeyState(VK_LBUTTON);
308  if (!(keyState & 0x8000)) {
309  WIN_CheckWParamMouseButton(SDL_FALSE, (mouseFlags & SDL_BUTTON_LMASK), data, SDL_BUTTON_LEFT, 0);
310  }
311  keyState = GetAsyncKeyState(VK_RBUTTON);
312  if (!(keyState & 0x8000)) {
313  WIN_CheckWParamMouseButton(SDL_FALSE, (mouseFlags & SDL_BUTTON_RMASK), data, SDL_BUTTON_RIGHT, 0);
314  }
315  keyState = GetAsyncKeyState(VK_MBUTTON);
316  if (!(keyState & 0x8000)) {
317  WIN_CheckWParamMouseButton(SDL_FALSE, (mouseFlags & SDL_BUTTON_MMASK), data, SDL_BUTTON_MIDDLE, 0);
318  }
319  keyState = GetAsyncKeyState(VK_XBUTTON1);
320  if (!(keyState & 0x8000)) {
321  WIN_CheckWParamMouseButton(SDL_FALSE, (mouseFlags & SDL_BUTTON_X1MASK), data, SDL_BUTTON_X1, 0);
322  }
323  keyState = GetAsyncKeyState(VK_XBUTTON2);
324  if (!(keyState & 0x8000)) {
325  WIN_CheckWParamMouseButton(SDL_FALSE, (mouseFlags & SDL_BUTTON_X2MASK), data, SDL_BUTTON_X2, 0);
326  }
327  data->mouse_button_flags = 0;
328 }
329 
330 static BOOL
331 WIN_ConvertUTF32toUTF8(UINT32 codepoint, char * text)
332 {
333  if (codepoint <= 0x7F) {
334  text[0] = (char) codepoint;
335  text[1] = '\0';
336  } else if (codepoint <= 0x7FF) {
337  text[0] = 0xC0 | (char) ((codepoint >> 6) & 0x1F);
338  text[1] = 0x80 | (char) (codepoint & 0x3F);
339  text[2] = '\0';
340  } else if (codepoint <= 0xFFFF) {
341  text[0] = 0xE0 | (char) ((codepoint >> 12) & 0x0F);
342  text[1] = 0x80 | (char) ((codepoint >> 6) & 0x3F);
343  text[2] = 0x80 | (char) (codepoint & 0x3F);
344  text[3] = '\0';
345  } else if (codepoint <= 0x10FFFF) {
346  text[0] = 0xF0 | (char) ((codepoint >> 18) & 0x0F);
347  text[1] = 0x80 | (char) ((codepoint >> 12) & 0x3F);
348  text[2] = 0x80 | (char) ((codepoint >> 6) & 0x3F);
349  text[3] = 0x80 | (char) (codepoint & 0x3F);
350  text[4] = '\0';
351  } else {
352  return SDL_FALSE;
353  }
354  return SDL_TRUE;
355 }
356 
357 static SDL_bool
358 ShouldGenerateWindowCloseOnAltF4(void)
359 {
361 }
362 
363 /* Win10 "Fall Creators Update" introduced the bug that SetCursorPos() (as used by SDL_WarpMouseInWindow())
364  doesn't reliably generate WM_MOUSEMOVE events anymore (see #3931) which breaks relative mouse mode via warping.
365  This is used to implement a workaround.. */
366 static SDL_bool isWin10FCUorNewer = SDL_FALSE;
367 
368 /* We want to generate mouse events from mouse and pen, and touch events from touchscreens */
369 #define MI_WP_SIGNATURE 0xFF515700
370 #define MI_WP_SIGNATURE_MASK 0xFFFFFF00
371 #define IsTouchEvent(dw) ((dw) & MI_WP_SIGNATURE_MASK) == MI_WP_SIGNATURE
372 
373 typedef enum
374 {
375  SDL_MOUSE_EVENT_SOURCE_UNKNOWN,
376  SDL_MOUSE_EVENT_SOURCE_MOUSE,
377  SDL_MOUSE_EVENT_SOURCE_TOUCH,
378  SDL_MOUSE_EVENT_SOURCE_PEN,
379 } SDL_MOUSE_EVENT_SOURCE;
380 
381 static SDL_MOUSE_EVENT_SOURCE GetMouseMessageSource()
382 {
383  LPARAM extrainfo = GetMessageExtraInfo();
384  /* Mouse data (ignoring synthetic mouse events generated for touchscreens) */
385  /* Versions below Vista will set the low 7 bits to the Mouse ID and don't use bit 7:
386  Check bits 8-32 for the signature (which will indicate a Tablet PC Pen or Touch Device).
387  Only check bit 7 when Vista and up(Cleared=Pen, Set=Touch(which we need to filter out)),
388  when the signature is set. The Mouse ID will be zero for an actual mouse. */
389  if (IsTouchEvent(extrainfo)) {
390  if (extrainfo & 0x80) {
391  return SDL_MOUSE_EVENT_SOURCE_TOUCH;
392  } else {
393  return SDL_MOUSE_EVENT_SOURCE_PEN;
394  }
395  }
396  return SDL_MOUSE_EVENT_SOURCE_MOUSE;
397 }
398 
399 LRESULT CALLBACK
400 WIN_WindowProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
401 {
403  LRESULT returnCode = -1;
404 
405  /* Send a SDL_SYSWMEVENT if the application wants them */
407  SDL_SysWMmsg wmmsg;
408 
409  SDL_VERSION(&wmmsg.version);
411  wmmsg.msg.win.hwnd = hwnd;
412  wmmsg.msg.win.msg = msg;
413  wmmsg.msg.win.wParam = wParam;
414  wmmsg.msg.win.lParam = lParam;
415  SDL_SendSysWMEvent(&wmmsg);
416  }
417 
418  /* Get the window data for the window */
419  data = (SDL_WindowData *) GetProp(hwnd, TEXT("SDL_WindowData"));
420  if (!data) {
421  return CallWindowProc(DefWindowProc, hwnd, msg, wParam, lParam);
422  }
423 
424 #ifdef WMMSG_DEBUG
425  {
426  char message[1024];
427  if (msg > MAX_WMMSG) {
428  SDL_snprintf(message, sizeof(message), "Received windows message: %p UNKNOWN (%d) -- 0x%X, 0x%X\n", hwnd, msg, wParam, lParam);
429  } else {
430  SDL_snprintf(message, sizeof(message), "Received windows message: %p %s -- 0x%X, 0x%X\n", hwnd, wmtab[msg], wParam, lParam);
431  }
432  OutputDebugStringA(message);
433  }
434 #endif /* WMMSG_DEBUG */
435 
436  if (IME_HandleMessage(hwnd, msg, wParam, &lParam, data->videodata))
437  return 0;
438 
439  switch (msg) {
440 
441  case WM_SHOWWINDOW:
442  {
443  if (wParam) {
445  } else {
447  }
448  }
449  break;
450 
451  case WM_NCACTIVATE:
452  {
453  /* Don't immediately clip the cursor in case we're clicking minimize/maximize buttons */
454  data->skip_update_clipcursor = SDL_TRUE;
455  }
456  break;
457 
458  case WM_ACTIVATE:
459  {
460  POINT cursorPos;
461  BOOL minimized;
462 
463  minimized = HIWORD(wParam);
464  if (!minimized && (LOWORD(wParam) != WA_INACTIVE)) {
465  /* Don't mark the window as shown if it's activated before being shown */
466  if (!IsWindowVisible(hwnd)) {
467  break;
468  }
469  if (LOWORD(wParam) == WA_CLICKACTIVE) {
470  if (GetAsyncKeyState(VK_LBUTTON)) {
471  data->focus_click_pending |= SDL_BUTTON_LMASK;
472  }
473  if (GetAsyncKeyState(VK_RBUTTON)) {
474  data->focus_click_pending |= SDL_BUTTON_RMASK;
475  }
476  if (GetAsyncKeyState(VK_MBUTTON)) {
477  data->focus_click_pending |= SDL_BUTTON_MMASK;
478  }
479  if (GetAsyncKeyState(VK_XBUTTON1)) {
480  data->focus_click_pending |= SDL_BUTTON_X1MASK;
481  }
482  if (GetAsyncKeyState(VK_XBUTTON2)) {
483  data->focus_click_pending |= SDL_BUTTON_X2MASK;
484  }
485  }
486 
488  if (SDL_GetKeyboardFocus() != data->window) {
489  SDL_SetKeyboardFocus(data->window);
490  }
491 
492  GetCursorPos(&cursorPos);
493  ScreenToClient(hwnd, &cursorPos);
494  SDL_SendMouseMotion(data->window, 0, 0, cursorPos.x, cursorPos.y);
495 
496  WIN_CheckAsyncMouseRelease(data);
497 
498  /*
499  * FIXME: Update keyboard state
500  */
501  WIN_CheckClipboardUpdate(data->videodata);
502 
503  SDL_ToggleModState(KMOD_CAPS, (GetKeyState(VK_CAPITAL) & 0x0001) != 0);
504  SDL_ToggleModState(KMOD_NUM, (GetKeyState(VK_NUMLOCK) & 0x0001) != 0);
505  } else {
506  RECT rect;
507 
508  data->in_window_deactivation = SDL_TRUE;
509 
510  if (SDL_GetKeyboardFocus() == data->window) {
513  }
514 
515  if (GetClipCursor(&rect) && SDL_memcmp(&rect, &data->cursor_clipped_rect, sizeof(rect)) == 0) {
516  ClipCursor(NULL);
517  SDL_zero(data->cursor_clipped_rect);
518  }
519 
520  data->in_window_deactivation = SDL_FALSE;
521  }
522  }
523  returnCode = 0;
524  break;
525 
526  case WM_MOUSEMOVE:
527  {
528  SDL_Mouse *mouse = SDL_GetMouse();
529  if (!mouse->relative_mode || mouse->relative_mode_warp) {
530  /* Only generate mouse events for real mouse */
531  if (GetMouseMessageSource() != SDL_MOUSE_EVENT_SOURCE_TOUCH) {
532  SDL_SendMouseMotion(data->window, 0, 0, GET_X_LPARAM(lParam), GET_Y_LPARAM(lParam));
533  if (isWin10FCUorNewer && mouse->relative_mode_warp) {
534  /* To work around #3931, Win10 bug introduced in Fall Creators Update, where
535  SetCursorPos() (SDL_WarpMouseInWindow()) doesn't reliably generate mouse events anymore,
536  after each windows mouse event generate a fake event for the middle of the window
537  if relative_mode_warp is used */
538  int center_x = 0, center_y = 0;
539  SDL_GetWindowSize(data->window, &center_x, &center_y);
540  center_x /= 2;
541  center_y /= 2;
542  SDL_SendMouseMotion(data->window, 0, 0, center_x, center_y);
543  }
544  }
545  } else {
546  /* We still need to update focus */
547  SDL_SetMouseFocus(data->window);
548  }
549  }
550  /* don't break here, fall through to check the wParam like the button presses */
551  case WM_LBUTTONUP:
552  case WM_RBUTTONUP:
553  case WM_MBUTTONUP:
554  case WM_XBUTTONUP:
555  case WM_LBUTTONDOWN:
556  case WM_LBUTTONDBLCLK:
557  case WM_RBUTTONDOWN:
558  case WM_RBUTTONDBLCLK:
559  case WM_MBUTTONDOWN:
560  case WM_MBUTTONDBLCLK:
561  case WM_XBUTTONDOWN:
562  case WM_XBUTTONDBLCLK:
563  {
564  SDL_Mouse *mouse = SDL_GetMouse();
565  if (!mouse->relative_mode || mouse->relative_mode_warp) {
566  if (GetMouseMessageSource() != SDL_MOUSE_EVENT_SOURCE_TOUCH) {
567  WIN_CheckWParamMouseButtons(wParam, data, 0);
568  }
569  }
570  }
571  break;
572 
573  case WM_INPUT:
574  {
575  SDL_Mouse *mouse = SDL_GetMouse();
576  HRAWINPUT hRawInput = (HRAWINPUT)lParam;
577  RAWINPUT inp;
578  UINT size = sizeof(inp);
579  const SDL_bool isRelative = mouse->relative_mode || mouse->relative_mode_warp;
580  const SDL_bool isCapture = ((data->window->flags & SDL_WINDOW_MOUSE_CAPTURE) != 0);
581 
582  if (!isRelative || mouse->focus != data->window) {
583  if (!isCapture) {
584  break;
585  }
586  }
587 
588  GetRawInputData(hRawInput, RID_INPUT, &inp, &size, sizeof(RAWINPUTHEADER));
589 
590  /* Mouse data (ignoring synthetic mouse events generated for touchscreens) */
591  if (inp.header.dwType == RIM_TYPEMOUSE) {
592  if (GetMouseMessageSource() == SDL_MOUSE_EVENT_SOURCE_TOUCH) {
593  break;
594  }
595  if (isRelative) {
596  RAWMOUSE* rawmouse = &inp.data.mouse;
597 
598  if ((rawmouse->usFlags & 0x01) == MOUSE_MOVE_RELATIVE) {
599  SDL_SendMouseMotion(data->window, 0, 1, (int)rawmouse->lLastX, (int)rawmouse->lLastY);
600  } else {
601  /* synthesize relative moves from the abs position */
602  static SDL_Point lastMousePoint;
603  SDL_bool virtual_desktop = (rawmouse->usFlags & MOUSE_VIRTUAL_DESKTOP) ? SDL_TRUE : SDL_FALSE;
604  int w = GetSystemMetrics(virtual_desktop ? SM_CXVIRTUALSCREEN : SM_CXSCREEN);
605  int h = GetSystemMetrics(virtual_desktop ? SM_CYVIRTUALSCREEN : SM_CYSCREEN);
606  int x = (int)(((float)rawmouse->lLastX / 65535.0f) * w);
607  int y = (int)(((float)rawmouse->lLastY / 65535.0f) * h);
608 
609  if (lastMousePoint.x == 0 && lastMousePoint.y == 0) {
610  lastMousePoint.x = x;
611  lastMousePoint.y = y;
612  }
613 
614  SDL_SendMouseMotion(data->window, 0, 1, (int)(x-lastMousePoint.x), (int)(y-lastMousePoint.y));
615 
616  lastMousePoint.x = x;
617  lastMousePoint.y = y;
618  }
619  WIN_CheckRawMouseButtons(rawmouse->usButtonFlags, data);
620  } else if (isCapture) {
621  /* we check for where Windows thinks the system cursor lives in this case, so we don't really lose mouse accel, etc. */
622  POINT pt;
623  RECT hwndRect;
624  HWND currentHnd;
625 
626  GetCursorPos(&pt);
627  currentHnd = WindowFromPoint(pt);
628  ScreenToClient(hwnd, &pt);
629  GetClientRect(hwnd, &hwndRect);
630 
631  /* if in the window, WM_MOUSEMOVE, etc, will cover it. */
632  if(currentHnd != hwnd || pt.x < 0 || pt.y < 0 || pt.x > hwndRect.right || pt.y > hwndRect.right) {
633  SDL_SendMouseMotion(data->window, 0, 0, (int)pt.x, (int)pt.y);
634  SDL_SendMouseButton(data->window, 0, GetAsyncKeyState(VK_LBUTTON) & 0x8000 ? SDL_PRESSED : SDL_RELEASED, SDL_BUTTON_LEFT);
635  SDL_SendMouseButton(data->window, 0, GetAsyncKeyState(VK_RBUTTON) & 0x8000 ? SDL_PRESSED : SDL_RELEASED, SDL_BUTTON_RIGHT);
636  SDL_SendMouseButton(data->window, 0, GetAsyncKeyState(VK_MBUTTON) & 0x8000 ? SDL_PRESSED : SDL_RELEASED, SDL_BUTTON_MIDDLE);
637  SDL_SendMouseButton(data->window, 0, GetAsyncKeyState(VK_XBUTTON1) & 0x8000 ? SDL_PRESSED : SDL_RELEASED, SDL_BUTTON_X1);
638  SDL_SendMouseButton(data->window, 0, GetAsyncKeyState(VK_XBUTTON2) & 0x8000 ? SDL_PRESSED : SDL_RELEASED, SDL_BUTTON_X2);
639  }
640  } else {
641  SDL_assert(0 && "Shouldn't happen");
642  }
643  }
644  }
645  break;
646 
647  case WM_MOUSEWHEEL:
648  case WM_MOUSEHWHEEL:
649  {
650  short amount = GET_WHEEL_DELTA_WPARAM(wParam);
651  float fAmount = (float) amount / WHEEL_DELTA;
652  if (msg == WM_MOUSEWHEEL)
653  SDL_SendMouseWheel(data->window, 0, 0.0f, fAmount, SDL_MOUSEWHEEL_NORMAL);
654  else
655  SDL_SendMouseWheel(data->window, 0, fAmount, 0.0f, SDL_MOUSEWHEEL_NORMAL);
656  }
657  break;
658 
659 #ifdef WM_MOUSELEAVE
660  case WM_MOUSELEAVE:
661  if (SDL_GetMouseFocus() == data->window && !SDL_GetMouse()->relative_mode && !(data->window->flags & SDL_WINDOW_MOUSE_CAPTURE)) {
662  if (!IsIconic(hwnd)) {
663  SDL_Mouse *mouse;
664  POINT cursorPos;
665  GetCursorPos(&cursorPos);
666  ScreenToClient(hwnd, &cursorPos);
667  mouse = SDL_GetMouse();
668  if (!mouse->was_touch_mouse_events) { /* we're not a touch handler causing a mouse leave? */
669  SDL_SendMouseMotion(data->window, 0, 0, cursorPos.x, cursorPos.y);
670  } else { /* touch handling? */
671  mouse->was_touch_mouse_events = SDL_FALSE; /* not anymore */
672  if (mouse->touch_mouse_events) { /* convert touch to mouse events */
673  SDL_SendMouseMotion(data->window, SDL_TOUCH_MOUSEID, 0, cursorPos.x, cursorPos.y);
674  } else { /* normal handling */
675  SDL_SendMouseMotion(data->window, 0, 0, cursorPos.x, cursorPos.y);
676  }
677  }
678  }
680  }
681  returnCode = 0;
682  break;
683 #endif /* WM_MOUSELEAVE */
684 
685  case WM_KEYDOWN:
686  case WM_SYSKEYDOWN:
687  {
688  SDL_Scancode code = WindowsScanCodeToSDLScanCode(lParam, wParam);
689  const Uint8 *keyboardState = SDL_GetKeyboardState(NULL);
690 
691  /* Detect relevant keyboard shortcuts */
692  if (keyboardState[SDL_SCANCODE_LALT] == SDL_PRESSED || keyboardState[SDL_SCANCODE_RALT] == SDL_PRESSED) {
693  /* ALT+F4: Close window */
694  if (code == SDL_SCANCODE_F4 && ShouldGenerateWindowCloseOnAltF4()) {
696  }
697  }
698 
699  if (code != SDL_SCANCODE_UNKNOWN) {
701  }
702  }
703 
704  returnCode = 0;
705  break;
706 
707  case WM_SYSKEYUP:
708  case WM_KEYUP:
709  {
710  SDL_Scancode code = WindowsScanCodeToSDLScanCode(lParam, wParam);
711  const Uint8 *keyboardState = SDL_GetKeyboardState(NULL);
712 
713  if (code != SDL_SCANCODE_UNKNOWN) {
714  if (code == SDL_SCANCODE_PRINTSCREEN &&
715  keyboardState[code] == SDL_RELEASED) {
717  }
719  }
720  }
721  returnCode = 0;
722  break;
723 
724  case WM_UNICHAR:
725  if (wParam == UNICODE_NOCHAR) {
726  returnCode = 1;
727  break;
728  }
729  /* otherwise fall through to below */
730  case WM_CHAR:
731  {
732  char text[5];
733  if (WIN_ConvertUTF32toUTF8((UINT32)wParam, text)) {
735  }
736  }
737  returnCode = 0;
738  break;
739 
740 #ifdef WM_INPUTLANGCHANGE
741  case WM_INPUTLANGCHANGE:
742  {
745  }
746  returnCode = 1;
747  break;
748 #endif /* WM_INPUTLANGCHANGE */
749 
750  case WM_NCLBUTTONDOWN:
751  {
752  data->in_title_click = SDL_TRUE;
753  }
754  break;
755 
756  case WM_CAPTURECHANGED:
757  {
758  data->in_title_click = SDL_FALSE;
759 
760  /* The mouse may have been released during a modal loop */
761  WIN_CheckAsyncMouseRelease(data);
762  }
763  break;
764 
765 #ifdef WM_GETMINMAXINFO
766  case WM_GETMINMAXINFO:
767  {
768  MINMAXINFO *info;
769  RECT size;
770  int x, y;
771  int w, h;
772  int min_w, min_h;
773  int max_w, max_h;
774  BOOL constrain_max_size;
775 
776  if (SDL_IsShapedWindow(data->window)) {
777  Win32_ResizeWindowShape(data->window);
778  }
779 
780  /* If this is an expected size change, allow it */
781  if (data->expected_resize) {
782  break;
783  }
784 
785  /* Get the current position of our window */
786  GetWindowRect(hwnd, &size);
787  x = size.left;
788  y = size.top;
789 
790  /* Calculate current size of our window */
791  SDL_GetWindowSize(data->window, &w, &h);
792  SDL_GetWindowMinimumSize(data->window, &min_w, &min_h);
793  SDL_GetWindowMaximumSize(data->window, &max_w, &max_h);
794 
795  /* Store in min_w and min_h difference between current size and minimal
796  size so we don't need to call AdjustWindowRectEx twice */
797  min_w -= w;
798  min_h -= h;
799  if (max_w && max_h) {
800  max_w -= w;
801  max_h -= h;
802  constrain_max_size = TRUE;
803  } else {
804  constrain_max_size = FALSE;
805  }
806 
807  if (!(SDL_GetWindowFlags(data->window) & SDL_WINDOW_BORDERLESS)) {
808  LONG style = GetWindowLong(hwnd, GWL_STYLE);
809  /* DJM - according to the docs for GetMenu(), the
810  return value is undefined if hwnd is a child window.
811  Apparently it's too difficult for MS to check
812  inside their function, so I have to do it here.
813  */
814  BOOL menu = (style & WS_CHILDWINDOW) ? FALSE : (GetMenu(hwnd) != NULL);
815  size.top = 0;
816  size.left = 0;
817  size.bottom = h;
818  size.right = w;
819 
820  AdjustWindowRectEx(&size, style, menu, 0);
821  w = size.right - size.left;
822  h = size.bottom - size.top;
823  }
824 
825  /* Fix our size to the current size */
826  info = (MINMAXINFO *) lParam;
828  info->ptMinTrackSize.x = w + min_w;
829  info->ptMinTrackSize.y = h + min_h;
830  if (constrain_max_size) {
831  info->ptMaxTrackSize.x = w + max_w;
832  info->ptMaxTrackSize.y = h + max_h;
833  }
834  } else {
835  info->ptMaxSize.x = w;
836  info->ptMaxSize.y = h;
837  info->ptMaxPosition.x = x;
838  info->ptMaxPosition.y = y;
839  info->ptMinTrackSize.x = w;
840  info->ptMinTrackSize.y = h;
841  info->ptMaxTrackSize.x = w;
842  info->ptMaxTrackSize.y = h;
843  }
844  }
845  returnCode = 0;
846  break;
847 #endif /* WM_GETMINMAXINFO */
848 
849  case WM_WINDOWPOSCHANGING:
850 
851  if (data->expected_resize) {
852  returnCode = 0;
853  }
854  break;
855 
856  case WM_WINDOWPOSCHANGED:
857  {
858  RECT rect;
859  int x, y;
860  int w, h;
861 
862  if (data->initializing || data->in_border_change) {
863  break;
864  }
865 
866  if (!GetClientRect(hwnd, &rect) || IsRectEmpty(&rect)) {
867  break;
868  }
869  ClientToScreen(hwnd, (LPPOINT) & rect);
870  ClientToScreen(hwnd, (LPPOINT) & rect + 1);
871 
872  WIN_UpdateClipCursor(data->window);
873 
874  x = rect.left;
875  y = rect.top;
877 
878  w = rect.right - rect.left;
879  h = rect.bottom - rect.top;
881 
882  /* Forces a WM_PAINT event */
883  InvalidateRect(hwnd, NULL, FALSE);
884  }
885  break;
886 
887  case WM_SIZE:
888  {
889  switch (wParam) {
890  case SIZE_MAXIMIZED:
891  SDL_SendWindowEvent(data->window,
893  SDL_SendWindowEvent(data->window,
895  break;
896  case SIZE_MINIMIZED:
897  SDL_SendWindowEvent(data->window,
899  break;
900  default:
901  SDL_SendWindowEvent(data->window,
903  break;
904  }
905  }
906  break;
907 
908  case WM_SETCURSOR:
909  {
910  Uint16 hittest;
911 
912  hittest = LOWORD(lParam);
913  if (hittest == HTCLIENT) {
914  SetCursor(SDL_cursor);
915  returnCode = TRUE;
917  SetCursor(NULL);
918  returnCode = TRUE;
919  }
920  }
921  break;
922 
923  /* We were occluded, refresh our display */
924  case WM_PAINT:
925  {
926  RECT rect;
927  if (GetUpdateRect(hwnd, &rect, FALSE)) {
928  ValidateRect(hwnd, NULL);
930  }
931  }
932  returnCode = 0;
933  break;
934 
935  /* We'll do our own drawing, prevent flicker */
936  case WM_ERASEBKGND:
937  {
938  }
939  return (1);
940 
941  case WM_SYSCOMMAND:
942  {
943  if ((wParam & 0xFFF0) == SC_KEYMENU) {
944  return (0);
945  }
946 
947 #if defined(SC_SCREENSAVE) || defined(SC_MONITORPOWER)
948  /* Don't start the screensaver or blank the monitor in fullscreen apps */
949  if ((wParam & 0xFFF0) == SC_SCREENSAVE ||
950  (wParam & 0xFFF0) == SC_MONITORPOWER) {
951  if (SDL_GetVideoDevice()->suspend_screensaver) {
952  return (0);
953  }
954  }
955 #endif /* System has screensaver support */
956  }
957  break;
958 
959  case WM_CLOSE:
960  {
962  }
963  returnCode = 0;
964  break;
965 
966  case WM_TOUCH:
967  if (data->videodata->GetTouchInputInfo && data->videodata->CloseTouchInputHandle) {
968  UINT i, num_inputs = LOWORD(wParam);
969  SDL_bool isstack;
970  PTOUCHINPUT inputs = SDL_small_alloc(TOUCHINPUT, num_inputs, &isstack);
971  if (data->videodata->GetTouchInputInfo((HTOUCHINPUT)lParam, num_inputs, inputs, sizeof(TOUCHINPUT))) {
972  RECT rect;
973  float x, y;
974 
975  if (!GetClientRect(hwnd, &rect) ||
976  (rect.right == rect.left && rect.bottom == rect.top)) {
977  if (inputs) {
978  SDL_small_free(inputs, isstack);
979  }
980  break;
981  }
982  ClientToScreen(hwnd, (LPPOINT) & rect);
983  ClientToScreen(hwnd, (LPPOINT) & rect + 1);
984  rect.top *= 100;
985  rect.left *= 100;
986  rect.bottom *= 100;
987  rect.right *= 100;
988 
989  for (i = 0; i < num_inputs; ++i) {
990  PTOUCHINPUT input = &inputs[i];
991 
992  const SDL_TouchID touchId = (SDL_TouchID)((size_t)input->hSource);
993 
994  /* TODO: Can we use GetRawInputDeviceInfo and HID info to
995  determine if this is a direct or indirect touch device?
996  */
997  if (SDL_AddTouch(touchId, SDL_TOUCH_DEVICE_DIRECT, "") < 0) {
998  continue;
999  }
1000 
1001  /* Get the normalized coordinates for the window */
1002  x = (float)(input->x - rect.left)/(rect.right - rect.left);
1003  y = (float)(input->y - rect.top)/(rect.bottom - rect.top);
1004 
1005  if (input->dwFlags & TOUCHEVENTF_DOWN) {
1006  SDL_SendTouch(touchId, input->dwID, data->window, SDL_TRUE, x, y, 1.0f);
1007  }
1008  if (input->dwFlags & TOUCHEVENTF_MOVE) {
1009  SDL_SendTouchMotion(touchId, input->dwID, data->window, x, y, 1.0f);
1010  }
1011  if (input->dwFlags & TOUCHEVENTF_UP) {
1012  SDL_SendTouch(touchId, input->dwID, data->window, SDL_FALSE, x, y, 1.0f);
1013  }
1014  }
1015  }
1016  SDL_small_free(inputs, isstack);
1017 
1018  data->videodata->CloseTouchInputHandle((HTOUCHINPUT)lParam);
1019  return 0;
1020  }
1021  break;
1022 
1023  case WM_DROPFILES:
1024  {
1025  UINT i;
1026  HDROP drop = (HDROP) wParam;
1027  UINT count = DragQueryFile(drop, 0xFFFFFFFF, NULL, 0);
1028  for (i = 0; i < count; ++i) {
1029  SDL_bool isstack;
1030  UINT size = DragQueryFile(drop, i, NULL, 0) + 1;
1031  LPTSTR buffer = SDL_small_alloc(TCHAR, size, &isstack);
1032  if (buffer) {
1033  if (DragQueryFile(drop, i, buffer, size)) {
1034  char *file = WIN_StringToUTF8(buffer);
1035  SDL_SendDropFile(data->window, file);
1036  SDL_free(file);
1037  }
1038  SDL_small_free(buffer, isstack);
1039  }
1040  }
1041  SDL_SendDropComplete(data->window);
1042  DragFinish(drop);
1043  return 0;
1044  }
1045  break;
1046 
1047  case WM_NCCALCSIZE:
1048  {
1049  Uint32 window_flags = SDL_GetWindowFlags(data->window);
1050  if (wParam == TRUE && (window_flags & SDL_WINDOW_BORDERLESS) && !(window_flags & SDL_WINDOW_FULLSCREEN)) {
1051  /* When borderless, need to tell windows that the size of the non-client area is 0 */
1052  if (!(window_flags & SDL_WINDOW_RESIZABLE)) {
1053  int w, h;
1054  NCCALCSIZE_PARAMS *params = (NCCALCSIZE_PARAMS *)lParam;
1055  w = data->window->windowed.w;
1056  h = data->window->windowed.h;
1057  params->rgrc[0].right = params->rgrc[0].left + w;
1058  params->rgrc[0].bottom = params->rgrc[0].top + h;
1059  }
1060  return 0;
1061  }
1062  }
1063  break;
1064 
1065  case WM_NCHITTEST:
1066  {
1067  SDL_Window *window = data->window;
1068  if (window->hit_test) {
1069  POINT winpoint = { GET_X_LPARAM(lParam), GET_Y_LPARAM(lParam) };
1070  if (ScreenToClient(hwnd, &winpoint)) {
1071  const SDL_Point point = { (int) winpoint.x, (int) winpoint.y };
1072  const SDL_HitTestResult rc = window->hit_test(window, &point, window->hit_test_data);
1073  switch (rc) {
1074  #define POST_HIT_TEST(ret) { SDL_SendWindowEvent(data->window, SDL_WINDOWEVENT_HIT_TEST, 0, 0); return ret; }
1075  case SDL_HITTEST_DRAGGABLE: POST_HIT_TEST(HTCAPTION);
1076  case SDL_HITTEST_RESIZE_TOPLEFT: POST_HIT_TEST(HTTOPLEFT);
1077  case SDL_HITTEST_RESIZE_TOP: POST_HIT_TEST(HTTOP);
1078  case SDL_HITTEST_RESIZE_TOPRIGHT: POST_HIT_TEST(HTTOPRIGHT);
1079  case SDL_HITTEST_RESIZE_RIGHT: POST_HIT_TEST(HTRIGHT);
1080  case SDL_HITTEST_RESIZE_BOTTOMRIGHT: POST_HIT_TEST(HTBOTTOMRIGHT);
1081  case SDL_HITTEST_RESIZE_BOTTOM: POST_HIT_TEST(HTBOTTOM);
1082  case SDL_HITTEST_RESIZE_BOTTOMLEFT: POST_HIT_TEST(HTBOTTOMLEFT);
1083  case SDL_HITTEST_RESIZE_LEFT: POST_HIT_TEST(HTLEFT);
1084  #undef POST_HIT_TEST
1085  case SDL_HITTEST_NORMAL: return HTCLIENT;
1086  }
1087  }
1088  /* If we didn't return, this will call DefWindowProc below. */
1089  }
1090  }
1091  break;
1092  }
1093 
1094  /* If there's a window proc, assume it's going to handle messages */
1095  if (data->wndproc) {
1096  return CallWindowProc(data->wndproc, hwnd, msg, wParam, lParam);
1097  } else if (returnCode >= 0) {
1098  return returnCode;
1099  } else {
1100  return CallWindowProc(DefWindowProc, hwnd, msg, wParam, lParam);
1101  }
1102 }
1103 
1104 static void WIN_UpdateClipCursorForWindows()
1105 {
1107  SDL_Window *window;
1108 
1109  if (_this) {
1110  for (window = _this->windows; window; window = window->next) {
1111  if (window->driverdata) {
1113  }
1114  }
1115  }
1116 }
1117 
1118 /* A message hook called before TranslateMessage() */
1119 static SDL_WindowsMessageHook g_WindowsMessageHook = NULL;
1120 static void *g_WindowsMessageHookData = NULL;
1121 
1123 {
1124  g_WindowsMessageHook = callback;
1125  g_WindowsMessageHookData = userdata;
1126 }
1127 
1128 void
1130 {
1131  const Uint8 *keystate;
1132  MSG msg;
1133  DWORD start_ticks = GetTickCount();
1134  int new_messages = 0;
1135 
1137  while (PeekMessage(&msg, NULL, 0, 0, PM_REMOVE)) {
1138  if (g_WindowsMessageHook) {
1139  g_WindowsMessageHook(g_WindowsMessageHookData, msg.hwnd, msg.message, msg.wParam, msg.lParam);
1140  }
1141 
1142  /* Always translate the message in case it's a non-SDL window (e.g. with Qt integration) */
1143  TranslateMessage(&msg);
1144  DispatchMessage(&msg);
1145 
1146  /* Make sure we don't busy loop here forever if there are lots of events coming in */
1147  if (SDL_TICKS_PASSED(msg.time, start_ticks)) {
1148  /* We might get a few new messages generated by the Steam overlay or other application hooks
1149  In this case those messages will be processed before any pending input, so we want to continue after those messages.
1150  (thanks to Peter Deayton for his investigation here)
1151  */
1152  const int MAX_NEW_MESSAGES = 3;
1153  ++new_messages;
1154  if (new_messages > MAX_NEW_MESSAGES) {
1155  break;
1156  }
1157  }
1158  }
1159  }
1160 
1161  /* Windows loses a shift KEYUP event when you have both pressed at once and let go of one.
1162  You won't get a KEYUP until both are released, and that keyup will only be for the second
1163  key you released. Take heroic measures and check the keystate as of the last handled event,
1164  and if we think a key is pressed when Windows doesn't, unstick it in SDL's state. */
1165  keystate = SDL_GetKeyboardState(NULL);
1166  if ((keystate[SDL_SCANCODE_LSHIFT] == SDL_PRESSED) && !(GetKeyState(VK_LSHIFT) & 0x8000)) {
1168  }
1169  if ((keystate[SDL_SCANCODE_RSHIFT] == SDL_PRESSED) && !(GetKeyState(VK_RSHIFT) & 0x8000)) {
1171  }
1172 
1173  /* Update the clipping rect in case someone else has stolen it */
1174  WIN_UpdateClipCursorForWindows();
1175 }
1176 
1177 /* to work around #3931, a bug introduced in Win10 Fall Creators Update (build nr. 16299)
1178  we need to detect the windows version. this struct and the function below does that.
1179  usually this struct and the corresponding function (RtlGetVersion) are in <Ntddk.h>
1180  but here we just load it dynamically */
1181 struct SDL_WIN_OSVERSIONINFOW {
1182  ULONG dwOSVersionInfoSize;
1183  ULONG dwMajorVersion;
1184  ULONG dwMinorVersion;
1185  ULONG dwBuildNumber;
1186  ULONG dwPlatformId;
1187  WCHAR szCSDVersion[128];
1188 };
1189 
1190 static SDL_bool
1191 IsWin10FCUorNewer(void)
1192 {
1193  HMODULE handle = GetModuleHandleW(L"ntdll.dll");
1194  if (handle) {
1195  typedef LONG(WINAPI* RtlGetVersionPtr)(struct SDL_WIN_OSVERSIONINFOW*);
1196  RtlGetVersionPtr getVersionPtr = (RtlGetVersionPtr)GetProcAddress(handle, "RtlGetVersion");
1197  if (getVersionPtr != NULL) {
1198  struct SDL_WIN_OSVERSIONINFOW info;
1199  SDL_zero(info);
1200  info.dwOSVersionInfoSize = sizeof(info);
1201  if (getVersionPtr(&info) == 0) { /* STATUS_SUCCESS == 0 */
1202  if ((info.dwMajorVersion == 10 && info.dwMinorVersion == 0 && info.dwBuildNumber >= 16299) ||
1203  (info.dwMajorVersion == 10 && info.dwMinorVersion > 0) ||
1204  (info.dwMajorVersion > 10))
1205  {
1206  return SDL_TRUE;
1207  }
1208  }
1209  }
1210  }
1211  return SDL_FALSE;
1212 }
1213 
1214 static int app_registered = 0;
1215 LPTSTR SDL_Appname = NULL;
1216 Uint32 SDL_Appstyle = 0;
1217 HINSTANCE SDL_Instance = NULL;
1218 
1219 /* Register the class for this application */
1220 int
1221 SDL_RegisterApp(char *name, Uint32 style, void *hInst)
1222 {
1223  const char *hint;
1224  WNDCLASSEX wcex;
1225  TCHAR path[MAX_PATH];
1226 
1227  /* Only do this once... */
1228  if (app_registered) {
1229  ++app_registered;
1230  return (0);
1231  }
1232  if (!name && !SDL_Appname) {
1233  name = "SDL_app";
1234 #if defined(CS_BYTEALIGNCLIENT) || defined(CS_OWNDC)
1235  SDL_Appstyle = (CS_BYTEALIGNCLIENT | CS_OWNDC);
1236 #endif
1237  SDL_Instance = hInst ? hInst : GetModuleHandle(NULL);
1238  }
1239 
1240  if (name) {
1242  SDL_Appstyle = style;
1243  SDL_Instance = hInst ? hInst : GetModuleHandle(NULL);
1244  }
1245 
1246  /* Register the application class */
1247  wcex.cbSize = sizeof(WNDCLASSEX);
1248  wcex.hCursor = NULL;
1249  wcex.hIcon = NULL;
1250  wcex.hIconSm = NULL;
1251  wcex.lpszMenuName = NULL;
1252  wcex.lpszClassName = SDL_Appname;
1253  wcex.style = SDL_Appstyle;
1254  wcex.hbrBackground = NULL;
1255  wcex.lpfnWndProc = WIN_WindowProc;
1256  wcex.hInstance = SDL_Instance;
1257  wcex.cbClsExtra = 0;
1258  wcex.cbWndExtra = 0;
1259 
1261  if (hint && *hint) {
1262  wcex.hIcon = LoadIcon(SDL_Instance, MAKEINTRESOURCE(SDL_atoi(hint)));
1263 
1265  if (hint && *hint) {
1266  wcex.hIconSm = LoadIcon(SDL_Instance, MAKEINTRESOURCE(SDL_atoi(hint)));
1267  }
1268  } else {
1269  /* Use the first icon as a default icon, like in the Explorer */
1270  GetModuleFileName(SDL_Instance, path, MAX_PATH);
1271  ExtractIconEx(path, 0, &wcex.hIcon, &wcex.hIconSm, 1);
1272  }
1273 
1274  if (!RegisterClassEx(&wcex)) {
1275  return SDL_SetError("Couldn't register application class");
1276  }
1277 
1278  isWin10FCUorNewer = IsWin10FCUorNewer();
1279 
1280  app_registered = 1;
1281  return 0;
1282 }
1283 
1284 /* Unregisters the windowclass registered in SDL_RegisterApp above. */
1285 void
1287 {
1288  WNDCLASSEX wcex;
1289 
1290  /* SDL_RegisterApp might not have been called before */
1291  if (!app_registered) {
1292  return;
1293  }
1294  --app_registered;
1295  if (app_registered == 0) {
1296  /* Check for any registered window classes. */
1297  if (GetClassInfoEx(SDL_Instance, SDL_Appname, &wcex)) {
1298  UnregisterClass(SDL_Appname, SDL_Instance);
1299  if (wcex.hIcon) DestroyIcon(wcex.hIcon);
1300  if (wcex.hIconSm) DestroyIcon(wcex.hIconSm);
1301  }
1303  SDL_Appname = NULL;
1304  }
1305 }
1306 
1307 #endif /* SDL_VIDEO_DRIVER_WINDOWS */
1308 
1309 /* vi: set ts=4 sw=4 expandtab: */
SDL_HITTEST_DRAGGABLE
@ SDL_HITTEST_DRAGGABLE
Definition: SDL_video.h:1022
SDL_SCANCODE_KP_2
@ SDL_SCANCODE_KP_2
Definition: SDL_scancode.h:189
SDL_GetMouse
SDL_Mouse * SDL_GetMouse(void)
Definition: SDL_mouse.c:170
SDL_zero
#define SDL_zero(x)
Definition: SDL_stdinc.h:418
SDL_WINDOW_MOUSE_CAPTURE
@ SDL_WINDOW_MOUSE_CAPTURE
Definition: SDL_video.h:115
SDL_SysWMmsg
Definition: SDL_syswm.h:142
SDL_SCANCODE_AC_FORWARD
@ SDL_SCANCODE_AC_FORWARD
Definition: SDL_scancode.h:364
SDL_TOUCH_DEVICE_DIRECT
@ SDL_TOUCH_DEVICE_DIRECT
Definition: SDL_touch.h:47
SDL_SCANCODE_RCTRL
@ SDL_SCANCODE_RCTRL
Definition: SDL_scancode.h:332
SDL_GetMouseState
#define SDL_GetMouseState
Definition: SDL_dynapi_overrides.h:246
SDL_Point::x
int x
Definition: SDL_rect.h:50
SDL_SCANCODE_PRINTSCREEN
@ SDL_SCANCODE_PRINTSCREEN
Definition: SDL_scancode.h:166
SDL_HINT_WINDOWS_NO_CLOSE_ON_ALT_F4
#define SDL_HINT_WINDOWS_NO_CLOSE_ON_ALT_F4
Tell SDL not to generate window-close events for Alt+F4 on Windows.
Definition: SDL_hints.h:1016
SDL_SCANCODE_HELP
@ SDL_SCANCODE_HELP
Definition: SDL_scancode.h:228
Uint32
uint32_t Uint32
Definition: SDL_stdinc.h:203
SDL_SendSysWMEvent
int SDL_SendSysWMEvent(SDL_SysWMmsg *message)
Definition: SDL_events.c:986
SDL_SysWMmsg::subsystem
SDL_SYSWM_TYPE subsystem
Definition: SDL_syswm.h:145
SDL_small_free
#define SDL_small_free(ptr, isstack)
Definition: SDL_internal.h:40
g_WindowsEnableMessageLoop
SDL_bool g_WindowsEnableMessageLoop
WIN_UTF8ToString
#define WIN_UTF8ToString(S)
Definition: SDL_windows.h:47
SDL_SCANCODE_LEFT
@ SDL_SCANCODE_LEFT
Definition: SDL_scancode.h:177
SDL_SCANCODE_F17
@ SDL_SCANCODE_F17
Definition: SDL_scancode.h:219
SDL_SCANCODE_F13
@ SDL_SCANCODE_F13
Definition: SDL_scancode.h:215
SDL_SCANCODE_SELECT
@ SDL_SCANCODE_SELECT
Definition: SDL_scancode.h:230
SDL_SCANCODE_APP2
@ SDL_SCANCODE_APP2
Definition: SDL_scancode.h:389
WIN_UpdateClipCursor
void WIN_UpdateClipCursor(SDL_Window *window)
SDL_IsShapedWindow
#define SDL_IsShapedWindow
Definition: SDL_dynapi_overrides.h:371
NULL
#define NULL
Definition: begin_code.h:167
SDL_SCANCODE_KP_PERIOD
@ SDL_SCANCODE_KP_PERIOD
Definition: SDL_scancode.h:198
handle
EGLImageKHR EGLint EGLint * handle
Definition: eglext.h:937
SDL_timer.h
message
GLuint GLsizei const GLchar * message
Definition: SDL_opengl_glext.h:2486
SDL_HINT_WINDOWS_INTRESOURCE_ICON
#define SDL_HINT_WINDOWS_INTRESOURCE_ICON
A variable to specify custom icon resource id from RC file on Windows platform.
Definition: SDL_hints.h:272
SDL_SCANCODE_SLASH
@ SDL_SCANCODE_SLASH
Definition: SDL_scancode.h:149
TRUE
#define TRUE
Definition: edid-parse.c:33
SDL_WINDOWEVENT_CLOSE
@ SDL_WINDOWEVENT_CLOSE
Definition: SDL_video.h:166
SDL_VERSION
#define SDL_VERSION(x)
Macro to determine SDL version program was compiled against.
Definition: SDL_version.h:79
SDL_SCANCODE_RIGHT
@ SDL_SCANCODE_RIGHT
Definition: SDL_scancode.h:176
SDL_BUTTON_RIGHT
#define SDL_BUTTON_RIGHT
Definition: SDL_mouse.h:284
SDL_WindowsMessageHook
void(* SDL_WindowsMessageHook)(void *userdata, void *hWnd, unsigned int message, Uint64 wParam, Sint64 lParam)
Set a function that is called for every windows message, before TranslateMessage()
Definition: SDL_system.h:49
SDL_BUTTON_RMASK
#define SDL_BUTTON_RMASK
Definition: SDL_mouse.h:289
SDL_SysWMmsg::version
SDL_version version
Definition: SDL_syswm.h:144
SDL_Mouse::touch_mouse_events
SDL_bool touch_mouse_events
Definition: SDL_mouse_c.h:95
SDL_SysWMmsg::msg
union SDL_SysWMmsg::@8 msg
SDL_WindowData
Definition: SDL_androidwindow.h:38
count
GLuint GLuint GLsizei count
Definition: SDL_opengl.h:1571
SDL_SCANCODE_VOLUMEDOWN
@ SDL_SCANCODE_VOLUMEDOWN
Definition: SDL_scancode.h:240
KMOD_NUM
@ KMOD_NUM
Definition: SDL_keycode.h:336
SDL_GetWindowFlags
#define SDL_GetWindowFlags
Definition: SDL_dynapi_overrides.h:518
SDL_SCANCODE_F15
@ SDL_SCANCODE_F15
Definition: SDL_scancode.h:217
SDL_WINDOW_FULLSCREEN
@ SDL_WINDOW_FULLSCREEN
Definition: SDL_video.h:99
SDL_SendTouch
int SDL_SendTouch(SDL_TouchID id, SDL_FingerID fingerid, SDL_Window *window, SDL_bool down, float x, float y, float pressure)
Definition: SDL_touch.c:242
SDL_TouchID
Sint64 SDL_TouchID
Definition: SDL_touch.h:41
SDL_WINDOWEVENT_RESIZED
@ SDL_WINDOWEVENT_RESIZED
Definition: SDL_video.h:154
SDL_Scancode
SDL_Scancode
The SDL keyboard scancode representation.
Definition: SDL_scancode.h:43
SDL_SCANCODE_KP_8
@ SDL_SCANCODE_KP_8
Definition: SDL_scancode.h:195
SDL_BUTTON_X2MASK
#define SDL_BUTTON_X2MASK
Definition: SDL_mouse.h:291
TOUCHEVENTF_MOVE
#define TOUCHEVENTF_MOVE
Definition: SDL_windowsvideo.h:58
params
const GLfloat * params
Definition: SDL_opengl_glext.h:374
SDL_UnregisterApp
void SDL_UnregisterApp(void)
SDL_VideoData::BOOL
BOOL(WINAPI *CloseTouchInputHandle)(HTOUCHINPUT)
SDL_SCANCODE_UP
@ SDL_SCANCODE_UP
Definition: SDL_scancode.h:179
SDL_SetKeyboardFocus
void SDL_SetKeyboardFocus(SDL_Window *window)
Definition: SDL_keyboard.c:630
callback
static Uint32 callback(Uint32 interval, void *param)
Definition: testtimer.c:34
SDL_ENABLE
#define SDL_ENABLE
Definition: SDL_events.h:760
SDL_HITTEST_RESIZE_TOPLEFT
@ SDL_HITTEST_RESIZE_TOPLEFT
Definition: SDL_video.h:1023
input
GLenum GLenum GLenum input
Definition: SDL_opengl_glext.h:9377
path
GLsizei const GLchar *const * path
Definition: SDL_opengl_glext.h:3733
SDL_SCANCODE_VOLUMEUP
@ SDL_SCANCODE_VOLUMEUP
Definition: SDL_scancode.h:239
SDL_SCANCODE_EXECUTE
@ SDL_SCANCODE_EXECUTE
Definition: SDL_scancode.h:227
SDL_SCANCODE_PAGEDOWN
@ SDL_SCANCODE_PAGEDOWN
Definition: SDL_scancode.h:175
SDL_VideoData::ULONG
ULONG
Definition: SDL_windowsvideo.h:136
SDL_WINDOWEVENT_MOVED
@ SDL_WINDOWEVENT_MOVED
Definition: SDL_video.h:152
SDL_GetHint
#define SDL_GetHint
Definition: SDL_dynapi_overrides.h:191
SDL_RELEASED
#define SDL_RELEASED
Definition: SDL_events.h:49
SDL_RegisterApp
int SDL_RegisterApp(char *name, Uint32 style, void *hInst)
h
GLfloat GLfloat GLfloat GLfloat h
Definition: SDL_opengl_glext.h:1949
SDL_small_alloc
#define SDL_small_alloc(type, count, pisstack)
Definition: SDL_internal.h:39
SDL_SCANCODE_F18
@ SDL_SCANCODE_F18
Definition: SDL_scancode.h:220
SDL_SetMouseFocus
void SDL_SetMouseFocus(SDL_Window *window)
Definition: SDL_mouse.c:203
SDL_SCANCODE_KP_6
@ SDL_SCANCODE_KP_6
Definition: SDL_scancode.h:193
SDL_MouseID
Uint32 SDL_MouseID
Definition: SDL_mouse_c.h:28
SDL_SCANCODE_LALT
@ SDL_SCANCODE_LALT
Definition: SDL_scancode.h:330
SDL_SendKeyboardKey
int SDL_SendKeyboardKey(Uint8 state, SDL_Scancode scancode)
Definition: SDL_keyboard.c:679
SDL_WINDOW_RESIZABLE
@ SDL_WINDOW_RESIZABLE
Definition: SDL_video.h:104
SDL_SCANCODE_KP_EQUALS
@ SDL_SCANCODE_KP_EQUALS
Definition: SDL_scancode.h:214
data
GLint GLenum GLsizei GLsizei GLsizei GLint GLsizei const GLvoid * data
Definition: SDL_opengl.h:1974
SDL_BUTTON_X1
#define SDL_BUTTON_X1
Definition: SDL_mouse.h:285
WIN_CheckClipboardUpdate
void WIN_CheckClipboardUpdate(struct SDL_VideoData *data)
SDL_Window
The type used to identify a window.
Definition: SDL_sysvideo.h:74
SDL_GetKeyboardFocus
#define SDL_GetKeyboardFocus
Definition: SDL_dynapi_overrides.h:216
SDL_SCANCODE_KP_1
@ SDL_SCANCODE_KP_1
Definition: SDL_scancode.h:188
SDL_TOUCH_MOUSEID
#define SDL_TOUCH_MOUSEID
Definition: SDL_touch.h:61
SDL_WINDOWEVENT_SHOWN
@ SDL_WINDOWEVENT_SHOWN
Definition: SDL_video.h:148
SDL_SCANCODE_CAPSLOCK
@ SDL_SCANCODE_CAPSLOCK
Definition: SDL_scancode.h:151
SDL_GetWindowSize
#define SDL_GetWindowSize
Definition: SDL_dynapi_overrides.h:527
SDL_SendKeyboardText
int SDL_SendKeyboardText(const char *text)
Definition: SDL_keyboard.c:789
SDL_cursor
HCURSOR SDL_cursor
SDL_Mouse::was_touch_mouse_events
SDL_bool was_touch_mouse_events
Definition: SDL_mouse_c.h:97
SDL_PRESSED
#define SDL_PRESSED
Definition: SDL_events.h:50
SDL_HITTEST_RESIZE_BOTTOMRIGHT
@ SDL_HITTEST_RESIZE_BOTTOMRIGHT
Definition: SDL_video.h:1027
SDL_GetHintBoolean
#define SDL_GetHintBoolean
Definition: SDL_dynapi_overrides.h:608
SDL_FALSE
@ SDL_FALSE
Definition: SDL_stdinc.h:163
SDL_ToggleModState
void SDL_ToggleModState(const SDL_Keymod modstate, const SDL_bool toggle)
Definition: SDL_keyboard.c:865
buffer
GLuint buffer
Definition: SDL_opengl_glext.h:536
SDL_AddTouch
int SDL_AddTouch(SDL_TouchID touchID, SDL_TouchDeviceType type, const char *name)
Definition: SDL_touch.c:155
SDL_Mouse::relative_mode
SDL_bool relative_mode
Definition: SDL_mouse_c.h:87
SDL_SCANCODE_F16
@ SDL_SCANCODE_F16
Definition: SDL_scancode.h:218
SDL_HITTEST_RESIZE_TOPRIGHT
@ SDL_HITTEST_RESIZE_TOPRIGHT
Definition: SDL_video.h:1025
SDL_SCANCODE_KP_MULTIPLY
@ SDL_SCANCODE_KP_MULTIPLY
Definition: SDL_scancode.h:184
windows_scancode_table
static const SDL_Scancode windows_scancode_table[]
Definition: scancodes_windows.h:27
_this
static SDL_VideoDevice * _this
Definition: SDL_video.c:121
SDL_BUTTON_LEFT
#define SDL_BUTTON_LEFT
Definition: SDL_mouse.h:282
SDL_HitTestResult
SDL_HitTestResult
Possible return values from the SDL_HitTest callback.
Definition: SDL_video.h:1019
SDL_windowsshape.h
SDL_windowsvideo.h
x
GLint GLint GLint GLint GLint x
Definition: SDL_opengl.h:1574
SDL_GetEventState
#define SDL_GetEventState(type)
Definition: SDL_events.h:773
SDL_SCANCODE_PAUSE
@ SDL_SCANCODE_PAUSE
Definition: SDL_scancode.h:168
window
EGLSurface EGLNativeWindowType * window
Definition: eglext.h:1025
SDL_SCANCODE_KP_7
@ SDL_SCANCODE_KP_7
Definition: SDL_scancode.h:194
SDL_memcmp
#define SDL_memcmp
Definition: SDL_dynapi_overrides.h:389
SDL_free
#define SDL_free
Definition: SDL_dynapi_overrides.h:377
SDL_SCANCODE_F24
@ SDL_SCANCODE_F24
Definition: SDL_scancode.h:226
SDL_SCANCODE_SYSREQ
@ SDL_SCANCODE_SYSREQ
Definition: SDL_scancode.h:269
SDL_HITTEST_RESIZE_BOTTOM
@ SDL_HITTEST_RESIZE_BOTTOM
Definition: SDL_video.h:1028
SDL_SCANCODE_F21
@ SDL_SCANCODE_F21
Definition: SDL_scancode.h:223
SDL_GetKeyboardState
#define SDL_GetKeyboardState
Definition: SDL_dynapi_overrides.h:217
name
GLuint const GLchar * name
Definition: SDL_opengl_glext.h:663
SDL_SCANCODE_KP_4
@ SDL_SCANCODE_KP_4
Definition: SDL_scancode.h:191
SDL_SCANCODE_KP_0
@ SDL_SCANCODE_KP_0
Definition: SDL_scancode.h:197
WIN_PumpEvents
void WIN_PumpEvents(_THIS)
SDL_SendDropFile
int SDL_SendDropFile(SDL_Window *window, const char *file)
Definition: SDL_dropevents.c:80
SDL_HITTEST_RESIZE_LEFT
@ SDL_HITTEST_RESIZE_LEFT
Definition: SDL_video.h:1030
rect
SDL_Rect rect
Definition: testrelative.c:27
SDL_SendMouseMotion
int SDL_SendMouseMotion(SDL_Window *window, SDL_MouseID mouseID, int relative, int x, int y)
Definition: SDL_mouse.c:293
SDL_WINDOWEVENT_EXPOSED
@ SDL_WINDOWEVENT_EXPOSED
Definition: SDL_video.h:150
SDL_SCANCODE_MAIL
@ SDL_SCANCODE_MAIL
Definition: SDL_scancode.h:358
SDL_BUTTON_MIDDLE
#define SDL_BUTTON_MIDDLE
Definition: SDL_mouse.h:283
SDL_SCANCODE_F14
@ SDL_SCANCODE_F14
Definition: SDL_scancode.h:216
TOUCHEVENTF_DOWN
#define TOUCHEVENTF_DOWN
Definition: SDL_windowsvideo.h:59
Uint16
uint16_t Uint16
Definition: SDL_stdinc.h:191
SDL_SCANCODE_KP_9
@ SDL_SCANCODE_KP_9
Definition: SDL_scancode.h:196
SDL_assert.h
SDL_SCANCODE_F20
@ SDL_SCANCODE_F20
Definition: SDL_scancode.h:222
SDL_VideoData::int
int
Definition: SDL_windowsvideo.h:135
SDL_BUTTON_LMASK
#define SDL_BUTTON_LMASK
Definition: SDL_mouse.h:287
_THIS
#define _THIS
Definition: SDL_alsa_audio.h:31
text
static char text[MAX_TEXT_LENGTH]
Definition: testime.c:47
SDL_SCANCODE_KP_DIVIDE
@ SDL_SCANCODE_KP_DIVIDE
Definition: SDL_scancode.h:183
SDL_GetWindowMinimumSize
#define SDL_GetWindowMinimumSize
Definition: SDL_dynapi_overrides.h:529
SDL_SCANCODE_AC_BACK
@ SDL_SCANCODE_AC_BACK
Definition: SDL_scancode.h:363
SDL_Mouse
Definition: SDL_mouse_c.h:43
SDL_SendDropComplete
int SDL_SendDropComplete(SDL_Window *window)
Definition: SDL_dropevents.c:92
SDL_Instance
HINSTANCE SDL_Instance
SDL_Mouse::relative_mode_warp
SDL_bool relative_mode_warp
Definition: SDL_mouse_c.h:88
WIN_WindowProc
LRESULT CALLBACK WIN_WindowProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
SDL_SCANCODE_AC_STOP
@ SDL_SCANCODE_AC_STOP
Definition: SDL_scancode.h:365
SDL_assert
#define SDL_assert(condition)
Definition: SDL_assert.h:169
SDL_BUTTON_X1MASK
#define SDL_BUTTON_X1MASK
Definition: SDL_mouse.h:290
SDL_Mouse::focus
SDL_Window * focus
Definition: SDL_mouse_c.h:77
SDL_WINDOWEVENT_MINIMIZED
@ SDL_WINDOWEVENT_MINIMIZED
Definition: SDL_video.h:158
Win32_ResizeWindowShape
int Win32_ResizeWindowShape(SDL_Window *window)
SDL_SCANCODE_KP_PLUS
@ SDL_SCANCODE_KP_PLUS
Definition: SDL_scancode.h:186
SDL_SCANCODE_APP1
@ SDL_SCANCODE_APP1
Definition: SDL_scancode.h:388
SDL_SCANCODE_LCTRL
@ SDL_SCANCODE_LCTRL
Definition: SDL_scancode.h:328
SDL_VideoDevice
Definition: SDL_sysvideo.h:149
SDL_SCANCODE_AUDIOMUTE
@ SDL_SCANCODE_AUDIOMUTE
Definition: SDL_scancode.h:355
WIN_ResetDeadKeys
void WIN_ResetDeadKeys(void)
size
GLsizeiptr size
Definition: SDL_opengl_glext.h:540
y
GLint GLint GLint GLint GLint GLint y
Definition: SDL_opengl.h:1574
SDL_HITTEST_NORMAL
@ SDL_HITTEST_NORMAL
Definition: SDL_video.h:1021
WIN_UpdateKeymap
void WIN_UpdateKeymap(void)
SDL_SCANCODE_UNKNOWN
@ SDL_SCANCODE_UNKNOWN
Definition: SDL_scancode.h:45
SDL_SendMouseWheel
int SDL_SendMouseWheel(SDL_Window *window, SDL_MouseID mouseID, float x, float y, SDL_MouseWheelDirection direction)
Definition: SDL_mouse.c:600
SDL_SCANCODE_LSHIFT
@ SDL_SCANCODE_LSHIFT
Definition: SDL_scancode.h:329
SDL_SCANCODE_MEDIASELECT
@ SDL_SCANCODE_MEDIASELECT
Definition: SDL_scancode.h:356
SDL_HITTEST_RESIZE_RIGHT
@ SDL_HITTEST_RESIZE_RIGHT
Definition: SDL_video.h:1026
SDL_SCANCODE_CLEAR
@ SDL_SCANCODE_CLEAR
Definition: SDL_scancode.h:271
SDL_atoi
#define SDL_atoi
Definition: SDL_dynapi_overrides.h:410
SDL_SCANCODE_DELETE
@ SDL_SCANCODE_DELETE
Definition: SDL_scancode.h:173
wmtab
char * wmtab[]
Definition: wmmsg.h:24
SDL_TRUE
@ SDL_TRUE
Definition: SDL_stdinc.h:164
SDL_SCANCODE_AC_REFRESH
@ SDL_SCANCODE_AC_REFRESH
Definition: SDL_scancode.h:366
SDL_SCANCODE_NONUSBACKSLASH
@ SDL_SCANCODE_NONUSBACKSLASH
Definition: SDL_scancode.h:200
SDL_SCANCODE_AUDIOSTOP
@ SDL_SCANCODE_AUDIOSTOP
Definition: SDL_scancode.h:353
SDL_Point
The structure that defines a point (integer)
Definition: SDL_rect.h:48
SDL_Window::next
SDL_Window * next
Definition: SDL_sysvideo.h:115
SDL_SetError
#define SDL_SetError
Definition: SDL_dynapi_overrides.h:30
SDL_vkeys.h
SDL_snprintf
#define SDL_snprintf
Definition: SDL_dynapi_overrides.h:40
SDL_HINT_WINDOWS_INTRESOURCE_ICON_SMALL
#define SDL_HINT_WINDOWS_INTRESOURCE_ICON_SMALL
Definition: SDL_hints.h:273
SDL_GetMouseFocus
#define SDL_GetMouseFocus
Definition: SDL_dynapi_overrides.h:245
SDL_SetWindowsMessageHook
void SDL_SetWindowsMessageHook(SDL_WindowsMessageHook callback, void *userdata)
SDL_system.h
MAX_WMMSG
#define MAX_WMMSG
Definition: wmmsg.h:22
SDL_GetWindowMaximumSize
#define SDL_GetWindowMaximumSize
Definition: SDL_dynapi_overrides.h:531
SDL_hints.h
SDL_SendTouchMotion
int SDL_SendTouchMotion(SDL_TouchID id, SDL_FingerID fingerid, SDL_Window *window, float x, float y, float pressure)
Definition: SDL_touch.c:356
SDL_SCANCODE_AC_HOME
@ SDL_SCANCODE_AC_HOME
Definition: SDL_scancode.h:362
SDL_SCANCODE_PAGEUP
@ SDL_SCANCODE_PAGEUP
Definition: SDL_scancode.h:172
SDL_SCANCODE_NUMLOCKCLEAR
@ SDL_SCANCODE_NUMLOCKCLEAR
Definition: SDL_scancode.h:181
WIN_StringToUTF8
#define WIN_StringToUTF8(S)
Definition: SDL_windows.h:46
SDL_SCANCODE_MODE
@ SDL_SCANCODE_MODE
Definition: SDL_scancode.h:337
SDL_SendKeymapChangedEvent
int SDL_SendKeymapChangedEvent(void)
Definition: SDL_events.c:1003
SDL_SendWindowEvent
int SDL_SendWindowEvent(SDL_Window *window, Uint8 windowevent, int data1, int data2)
Definition: SDL_windowevents.c:74
SDL_SCANCODE_F23
@ SDL_SCANCODE_F23
Definition: SDL_scancode.h:225
SDL_Appstyle
Uint32 SDL_Appstyle
TOUCHEVENTF_UP
#define TOUCHEVENTF_UP
Definition: SDL_windowsvideo.h:60
PTOUCHINPUT
struct TOUCHINPUT * PTOUCHINPUT
SDL_SYSWMEVENT
@ SDL_SYSWMEVENT
Definition: SDL_events.h:93
SDL_TICKS_PASSED
#define SDL_TICKS_PASSED(A, B)
Compare SDL ticks values, and return true if A has passed B.
Definition: SDL_timer.h:56
SDL_Appname
LPTSTR SDL_Appname
SDL_SCANCODE_KP_3
@ SDL_SCANCODE_KP_3
Definition: SDL_scancode.h:190
SDL_MOUSEWHEEL_NORMAL
@ SDL_MOUSEWHEEL_NORMAL
Definition: SDL_mouse.h:68
SDL_WINDOWEVENT_HIDDEN
@ SDL_WINDOWEVENT_HIDDEN
Definition: SDL_video.h:149
SDL_GetVideoDevice
SDL_VideoDevice * SDL_GetVideoDevice(void)
Definition: SDL_video.c:586
SDL_BUTTON_X2
#define SDL_BUTTON_X2
Definition: SDL_mouse.h:286
SDL_WINDOWEVENT_RESTORED
@ SDL_WINDOWEVENT_RESTORED
Definition: SDL_video.h:160
SDL_SCANCODE_CRSEL
@ SDL_SCANCODE_CRSEL
Definition: SDL_scancode.h:278
SDL_HINT_MOUSE_FOCUS_CLICKTHROUGH
#define SDL_HINT_MOUSE_FOCUS_CLICKTHROUGH
Allow mouse click events when clicking to focus an SDL window.
Definition: SDL_hints.h:337
SDL_SCANCODE_F19
@ SDL_SCANCODE_F19
Definition: SDL_scancode.h:221
SDL_SCANCODE_INSERT
@ SDL_SCANCODE_INSERT
Definition: SDL_scancode.h:169
SDL_SCANCODE_F22
@ SDL_SCANCODE_F22
Definition: SDL_scancode.h:224
SDL_SCANCODE_AC_SEARCH
@ SDL_SCANCODE_AC_SEARCH
Definition: SDL_scancode.h:361
SDL_SCANCODE_AUDIOPLAY
@ SDL_SCANCODE_AUDIOPLAY
Definition: SDL_scancode.h:354
SDL_SCANCODE_DOWN
@ SDL_SCANCODE_DOWN
Definition: SDL_scancode.h:178
SDL_BUTTON
#define SDL_BUTTON(X)
Definition: SDL_mouse.h:281
SDL_SCANCODE_RALT
@ SDL_SCANCODE_RALT
Definition: SDL_scancode.h:334
VK_OEM_102
#define VK_OEM_102
Definition: SDL_vkeys.h:74
SDL_SCANCODE_END
@ SDL_SCANCODE_END
Definition: SDL_scancode.h:174
SDL_SCANCODE_EXSEL
@ SDL_SCANCODE_EXSEL
Definition: SDL_scancode.h:279
IME_HandleMessage
SDL_bool IME_HandleMessage(HWND hwnd, UINT msg, WPARAM wParam, LPARAM *lParam, struct SDL_VideoData *videodata)
SDL_SCANCODE_RSHIFT
@ SDL_SCANCODE_RSHIFT
Definition: SDL_scancode.h:333
wmmsg.h
SDL_SCANCODE_AUDIOPREV
@ SDL_SCANCODE_AUDIOPREV
Definition: SDL_scancode.h:352
SDL_VideoData::UINT
UINT
Definition: SDL_windowsvideo.h:135
SDL_HITTEST_RESIZE_TOP
@ SDL_HITTEST_RESIZE_TOP
Definition: SDL_video.h:1024
KMOD_CAPS
@ KMOD_CAPS
Definition: SDL_keycode.h:337
SDL_BUTTON_MMASK
#define SDL_BUTTON_MMASK
Definition: SDL_mouse.h:288
button
SDL_Texture * button
Definition: testgamecontroller.c:67
g_WindowFrameUsableWhileCursorHidden
SDL_bool g_WindowFrameUsableWhileCursorHidden
SDL_SCANCODE_HOME
@ SDL_SCANCODE_HOME
Definition: SDL_scancode.h:171
i
return Display return Display Bool Bool int int int return Display XEvent Bool(*) XPointer return Display return Display Drawable _Xconst char unsigned int unsigned int return Display Pixmap Pixmap XColor XColor unsigned int unsigned int return Display _Xconst char char int char return Display Visual unsigned int int int char unsigned int unsigned int in i)
Definition: SDL_x11sym.h:50
SDL_SCANCODE_RETURN
@ SDL_SCANCODE_RETURN
Definition: SDL_scancode.h:92
SDL_HITTEST_RESIZE_BOTTOMLEFT
@ SDL_HITTEST_RESIZE_BOTTOMLEFT
Definition: SDL_video.h:1029
SDL_Point::y
int y
Definition: SDL_rect.h:51
SDL_SendMouseButton
int SDL_SendMouseButton(SDL_Window *window, SDL_MouseID mouseID, Uint8 state, Uint8 button)
Definition: SDL_mouse.c:594
SDL_WINDOWEVENT_MAXIMIZED
@ SDL_WINDOWEVENT_MAXIMIZED
Definition: SDL_video.h:159
FALSE
#define FALSE
Definition: edid-parse.c:34
SDL_SCANCODE_AUDIONEXT
@ SDL_SCANCODE_AUDIONEXT
Definition: SDL_scancode.h:351
SDL_bool
SDL_bool
Definition: SDL_stdinc.h:161
SDL_SYSWM_WINDOWS
@ SDL_SYSWM_WINDOWS
Definition: SDL_syswm.h:125
SDL_syswm.h
SDL_SCANCODE_KP_ENTER
@ SDL_SCANCODE_KP_ENTER
Definition: SDL_scancode.h:187
SDL_WINDOW_BORDERLESS
@ SDL_WINDOW_BORDERLESS
Definition: SDL_video.h:103
SDL_VideoDevice::windows
SDL_Window * windows
Definition: SDL_sysvideo.h:325
w
GLubyte GLubyte GLubyte GLubyte w
Definition: SDL_opengl_glext.h:734
SDL_SCANCODE_F4
@ SDL_SCANCODE_F4
Definition: SDL_scancode.h:156
Uint8
uint8_t Uint8
Definition: SDL_stdinc.h:179
SDL_SCANCODE_AC_BOOKMARKS
@ SDL_SCANCODE_AC_BOOKMARKS
Definition: SDL_scancode.h:367