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