SDL  2.0
SDL_windowsevents.c
Go to the documentation of this file.
1 /*
2  Simple DirectMedia Layer
3  Copyright (C) 1997-2016 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 "../../events/SDL_events_c.h"
32 #include "../../events/SDL_touch_c.h"
33 #include "../../events/scancodes_windows.h"
34 #include "SDL_assert.h"
35 #include "SDL_hints.h"
36 
37 /* Dropfile support */
38 #include <shellapi.h>
39 
40 /* For GET_X_LPARAM, GET_Y_LPARAM. */
41 #include <windowsx.h>
42 
43 /* #define WMMSG_DEBUG */
44 #ifdef WMMSG_DEBUG
45 #include <stdio.h>
46 #include "wmmsg.h"
47 #endif
48 
49 /* For processing mouse WM_*BUTTON* and WM_MOUSEMOVE message-data from GetMessageExtraInfo() */
50 #define MOUSEEVENTF_FROMTOUCH 0xFF515700
51 
52 /* Masks for processing the windows KEYDOWN and KEYUP messages */
53 #define REPEATED_KEYMASK (1<<30)
54 #define EXTENDED_KEYMASK (1<<24)
55 
56 #define VK_ENTER 10 /* Keypad Enter ... no VKEY defined? */
57 #ifndef VK_OEM_NEC_EQUAL
58 #define VK_OEM_NEC_EQUAL 0x92
59 #endif
60 
61 /* Make sure XBUTTON stuff is defined that isn't in older Platform SDKs... */
62 #ifndef WM_XBUTTONDOWN
63 #define WM_XBUTTONDOWN 0x020B
64 #endif
65 #ifndef WM_XBUTTONUP
66 #define WM_XBUTTONUP 0x020C
67 #endif
68 #ifndef GET_XBUTTON_WPARAM
69 #define GET_XBUTTON_WPARAM(w) (HIWORD(w))
70 #endif
71 #ifndef WM_INPUT
72 #define WM_INPUT 0x00ff
73 #endif
74 #ifndef WM_TOUCH
75 #define WM_TOUCH 0x0240
76 #endif
77 #ifndef WM_MOUSEHWHEEL
78 #define WM_MOUSEHWHEEL 0x020E
79 #endif
80 #ifndef WM_UNICHAR
81 #define WM_UNICHAR 0x0109
82 #endif
83 
84 static SDL_Scancode
85 WindowsScanCodeToSDLScanCode(LPARAM lParam, WPARAM wParam)
86 {
87  SDL_Scancode code;
88  char bIsExtended;
89  int nScanCode = (lParam >> 16) & 0xFF;
90 
91  /* 0x45 here to work around both pause and numlock sharing the same scancode, so use the VK key to tell them apart */
92  if (nScanCode == 0 || nScanCode == 0x45) {
93  switch(wParam) {
94  case VK_CLEAR: return SDL_SCANCODE_CLEAR;
95  case VK_MODECHANGE: return SDL_SCANCODE_MODE;
96  case VK_SELECT: return SDL_SCANCODE_SELECT;
97  case VK_EXECUTE: return SDL_SCANCODE_EXECUTE;
98  case VK_HELP: return SDL_SCANCODE_HELP;
99  case VK_PAUSE: return SDL_SCANCODE_PAUSE;
100  case VK_NUMLOCK: return SDL_SCANCODE_NUMLOCKCLEAR;
101 
102  case VK_F13: return SDL_SCANCODE_F13;
103  case VK_F14: return SDL_SCANCODE_F14;
104  case VK_F15: return SDL_SCANCODE_F15;
105  case VK_F16: return SDL_SCANCODE_F16;
106  case VK_F17: return SDL_SCANCODE_F17;
107  case VK_F18: return SDL_SCANCODE_F18;
108  case VK_F19: return SDL_SCANCODE_F19;
109  case VK_F20: return SDL_SCANCODE_F20;
110  case VK_F21: return SDL_SCANCODE_F21;
111  case VK_F22: return SDL_SCANCODE_F22;
112  case VK_F23: return SDL_SCANCODE_F23;
113  case VK_F24: return SDL_SCANCODE_F24;
114 
115  case VK_OEM_NEC_EQUAL: return SDL_SCANCODE_KP_EQUALS;
116  case VK_BROWSER_BACK: return SDL_SCANCODE_AC_BACK;
117  case VK_BROWSER_FORWARD: return SDL_SCANCODE_AC_FORWARD;
118  case VK_BROWSER_REFRESH: return SDL_SCANCODE_AC_REFRESH;
119  case VK_BROWSER_STOP: return SDL_SCANCODE_AC_STOP;
120  case VK_BROWSER_SEARCH: return SDL_SCANCODE_AC_SEARCH;
121  case VK_BROWSER_FAVORITES: return SDL_SCANCODE_AC_BOOKMARKS;
122  case VK_BROWSER_HOME: return SDL_SCANCODE_AC_HOME;
123  case VK_VOLUME_MUTE: return SDL_SCANCODE_AUDIOMUTE;
124  case VK_VOLUME_DOWN: return SDL_SCANCODE_VOLUMEDOWN;
125  case VK_VOLUME_UP: return SDL_SCANCODE_VOLUMEUP;
126 
127  case VK_MEDIA_NEXT_TRACK: return SDL_SCANCODE_AUDIONEXT;
128  case VK_MEDIA_PREV_TRACK: return SDL_SCANCODE_AUDIOPREV;
129  case VK_MEDIA_STOP: return SDL_SCANCODE_AUDIOSTOP;
130  case VK_MEDIA_PLAY_PAUSE: return SDL_SCANCODE_AUDIOPLAY;
131  case VK_LAUNCH_MAIL: return SDL_SCANCODE_MAIL;
132  case VK_LAUNCH_MEDIA_SELECT: return SDL_SCANCODE_MEDIASELECT;
133 
135 
136  case VK_ATTN: return SDL_SCANCODE_SYSREQ;
137  case VK_CRSEL: return SDL_SCANCODE_CRSEL;
138  case VK_EXSEL: return SDL_SCANCODE_EXSEL;
139  case VK_OEM_CLEAR: return SDL_SCANCODE_CLEAR;
140 
141  case VK_LAUNCH_APP1: return SDL_SCANCODE_APP1;
142  case VK_LAUNCH_APP2: return SDL_SCANCODE_APP2;
143 
144  default: return SDL_SCANCODE_UNKNOWN;
145  }
146  }
147 
148  if (nScanCode > 127)
149  return SDL_SCANCODE_UNKNOWN;
150 
151  code = windows_scancode_table[nScanCode];
152 
153  bIsExtended = (lParam & (1 << 24)) != 0;
154  if (!bIsExtended) {
155  switch (code) {
156  case SDL_SCANCODE_HOME:
157  return SDL_SCANCODE_KP_7;
158  case SDL_SCANCODE_UP:
159  return SDL_SCANCODE_KP_8;
160  case SDL_SCANCODE_PAGEUP:
161  return SDL_SCANCODE_KP_9;
162  case SDL_SCANCODE_LEFT:
163  return SDL_SCANCODE_KP_4;
164  case SDL_SCANCODE_RIGHT:
165  return SDL_SCANCODE_KP_6;
166  case SDL_SCANCODE_END:
167  return SDL_SCANCODE_KP_1;
168  case SDL_SCANCODE_DOWN:
169  return SDL_SCANCODE_KP_2;
171  return SDL_SCANCODE_KP_3;
172  case SDL_SCANCODE_INSERT:
173  return SDL_SCANCODE_KP_0;
174  case SDL_SCANCODE_DELETE:
175  return SDL_SCANCODE_KP_PERIOD;
178  default:
179  break;
180  }
181  } else {
182  switch (code) {
183  case SDL_SCANCODE_RETURN:
184  return SDL_SCANCODE_KP_ENTER;
185  case SDL_SCANCODE_LALT:
186  return SDL_SCANCODE_RALT;
187  case SDL_SCANCODE_LCTRL:
188  return SDL_SCANCODE_RCTRL;
189  case SDL_SCANCODE_SLASH:
190  return SDL_SCANCODE_KP_DIVIDE;
192  return SDL_SCANCODE_KP_PLUS;
193  default:
194  break;
195  }
196  }
197 
198  return code;
199 }
200 
201 
202 void
203 WIN_CheckWParamMouseButton(SDL_bool bwParamMousePressed, SDL_bool bSDLMousePressed, SDL_WindowData *data, Uint8 button, SDL_MouseID mouseID)
204 {
205  if (data->focus_click_pending && button == SDL_BUTTON_LEFT && !bwParamMousePressed) {
208  }
209 
210  if (bwParamMousePressed && !bSDLMousePressed) {
211  SDL_SendMouseButton(data->window, mouseID, SDL_PRESSED, button);
212  } else if (!bwParamMousePressed && bSDLMousePressed) {
213  SDL_SendMouseButton(data->window, mouseID, SDL_RELEASED, button);
214  }
215 }
216 
217 /*
218 * Some windows systems fail to send a WM_LBUTTONDOWN sometimes, but each mouse move contains the current button state also
219 * so this funciton reconciles our view of the world with the current buttons reported by windows
220 */
221 void
222 WIN_CheckWParamMouseButtons(WPARAM wParam, SDL_WindowData *data, SDL_MouseID mouseID)
223 {
224  if (wParam != data->mouse_button_flags) {
225  Uint32 mouseFlags = SDL_GetMouseState(NULL, NULL);
226  WIN_CheckWParamMouseButton((wParam & MK_LBUTTON), (mouseFlags & SDL_BUTTON_LMASK), data, SDL_BUTTON_LEFT, mouseID);
227  WIN_CheckWParamMouseButton((wParam & MK_MBUTTON), (mouseFlags & SDL_BUTTON_MMASK), data, SDL_BUTTON_MIDDLE, mouseID);
228  WIN_CheckWParamMouseButton((wParam & MK_RBUTTON), (mouseFlags & SDL_BUTTON_RMASK), data, SDL_BUTTON_RIGHT, mouseID);
229  WIN_CheckWParamMouseButton((wParam & MK_XBUTTON1), (mouseFlags & SDL_BUTTON_X1MASK), data, SDL_BUTTON_X1, mouseID);
230  WIN_CheckWParamMouseButton((wParam & MK_XBUTTON2), (mouseFlags & SDL_BUTTON_X2MASK), data, SDL_BUTTON_X2, mouseID);
231  data->mouse_button_flags = wParam;
232  }
233 }
234 
235 
236 void
237 WIN_CheckRawMouseButtons(ULONG rawButtons, SDL_WindowData *data)
238 {
239  if (rawButtons != data->mouse_button_flags) {
240  Uint32 mouseFlags = SDL_GetMouseState(NULL, NULL);
241  if ((rawButtons & RI_MOUSE_BUTTON_1_DOWN))
242  WIN_CheckWParamMouseButton((rawButtons & RI_MOUSE_BUTTON_1_DOWN), (mouseFlags & SDL_BUTTON_LMASK), data, SDL_BUTTON_LEFT, 0);
243  if ((rawButtons & RI_MOUSE_BUTTON_1_UP))
244  WIN_CheckWParamMouseButton(!(rawButtons & RI_MOUSE_BUTTON_1_UP), (mouseFlags & SDL_BUTTON_LMASK), data, SDL_BUTTON_LEFT, 0);
245  if ((rawButtons & RI_MOUSE_BUTTON_2_DOWN))
246  WIN_CheckWParamMouseButton((rawButtons & RI_MOUSE_BUTTON_2_DOWN), (mouseFlags & SDL_BUTTON_RMASK), data, SDL_BUTTON_RIGHT, 0);
247  if ((rawButtons & RI_MOUSE_BUTTON_2_UP))
248  WIN_CheckWParamMouseButton(!(rawButtons & RI_MOUSE_BUTTON_2_UP), (mouseFlags & SDL_BUTTON_RMASK), data, SDL_BUTTON_RIGHT, 0);
249  if ((rawButtons & RI_MOUSE_BUTTON_3_DOWN))
250  WIN_CheckWParamMouseButton((rawButtons & RI_MOUSE_BUTTON_3_DOWN), (mouseFlags & SDL_BUTTON_MMASK), data, SDL_BUTTON_MIDDLE, 0);
251  if ((rawButtons & RI_MOUSE_BUTTON_3_UP))
252  WIN_CheckWParamMouseButton(!(rawButtons & RI_MOUSE_BUTTON_3_UP), (mouseFlags & SDL_BUTTON_MMASK), data, SDL_BUTTON_MIDDLE, 0);
253  if ((rawButtons & RI_MOUSE_BUTTON_4_DOWN))
254  WIN_CheckWParamMouseButton((rawButtons & RI_MOUSE_BUTTON_4_DOWN), (mouseFlags & SDL_BUTTON_X1MASK), data, SDL_BUTTON_X1, 0);
255  if ((rawButtons & RI_MOUSE_BUTTON_4_UP))
256  WIN_CheckWParamMouseButton(!(rawButtons & RI_MOUSE_BUTTON_4_UP), (mouseFlags & SDL_BUTTON_X1MASK), data, SDL_BUTTON_X1, 0);
257  if ((rawButtons & RI_MOUSE_BUTTON_5_DOWN))
258  WIN_CheckWParamMouseButton((rawButtons & RI_MOUSE_BUTTON_5_DOWN), (mouseFlags & SDL_BUTTON_X2MASK), data, SDL_BUTTON_X2, 0);
259  if ((rawButtons & RI_MOUSE_BUTTON_5_UP))
260  WIN_CheckWParamMouseButton(!(rawButtons & RI_MOUSE_BUTTON_5_UP), (mouseFlags & SDL_BUTTON_X2MASK), data, SDL_BUTTON_X2, 0);
261  data->mouse_button_flags = rawButtons;
262  }
263 }
264 
265 void
266 WIN_CheckAsyncMouseRelease(SDL_WindowData *data)
267 {
268  Uint32 mouseFlags;
269  SHORT keyState;
270 
271  /* mouse buttons may have changed state here, we need to resync them,
272  but we will get a WM_MOUSEMOVE right away which will fix things up if in non raw mode also
273  */
274  mouseFlags = SDL_GetMouseState(NULL, NULL);
275 
276  keyState = GetAsyncKeyState(VK_LBUTTON);
277  if (!(keyState & 0x8000)) {
278  WIN_CheckWParamMouseButton(SDL_FALSE, (mouseFlags & SDL_BUTTON_LMASK), data, SDL_BUTTON_LEFT, 0);
279  }
280  keyState = GetAsyncKeyState(VK_RBUTTON);
281  if (!(keyState & 0x8000)) {
282  WIN_CheckWParamMouseButton(SDL_FALSE, (mouseFlags & SDL_BUTTON_RMASK), data, SDL_BUTTON_RIGHT, 0);
283  }
284  keyState = GetAsyncKeyState(VK_MBUTTON);
285  if (!(keyState & 0x8000)) {
286  WIN_CheckWParamMouseButton(SDL_FALSE, (mouseFlags & SDL_BUTTON_MMASK), data, SDL_BUTTON_MIDDLE, 0);
287  }
288  keyState = GetAsyncKeyState(VK_XBUTTON1);
289  if (!(keyState & 0x8000)) {
290  WIN_CheckWParamMouseButton(SDL_FALSE, (mouseFlags & SDL_BUTTON_X1MASK), data, SDL_BUTTON_X1, 0);
291  }
292  keyState = GetAsyncKeyState(VK_XBUTTON2);
293  if (!(keyState & 0x8000)) {
294  WIN_CheckWParamMouseButton(SDL_FALSE, (mouseFlags & SDL_BUTTON_X2MASK), data, SDL_BUTTON_X2, 0);
295  }
296  data->mouse_button_flags = 0;
297 }
298 
299 BOOL
300 WIN_ConvertUTF32toUTF8(UINT32 codepoint, char * text)
301 {
302  if (codepoint <= 0x7F) {
303  text[0] = (char) codepoint;
304  text[1] = '\0';
305  } else if (codepoint <= 0x7FF) {
306  text[0] = 0xC0 | (char) ((codepoint >> 6) & 0x1F);
307  text[1] = 0x80 | (char) (codepoint & 0x3F);
308  text[2] = '\0';
309  } else if (codepoint <= 0xFFFF) {
310  text[0] = 0xE0 | (char) ((codepoint >> 12) & 0x0F);
311  text[1] = 0x80 | (char) ((codepoint >> 6) & 0x3F);
312  text[2] = 0x80 | (char) (codepoint & 0x3F);
313  text[3] = '\0';
314  } else if (codepoint <= 0x10FFFF) {
315  text[0] = 0xF0 | (char) ((codepoint >> 18) & 0x0F);
316  text[1] = 0x80 | (char) ((codepoint >> 12) & 0x3F);
317  text[2] = 0x80 | (char) ((codepoint >> 6) & 0x3F);
318  text[3] = 0x80 | (char) (codepoint & 0x3F);
319  text[4] = '\0';
320  } else {
321  return SDL_FALSE;
322  }
323  return SDL_TRUE;
324 }
325 
326 static SDL_bool
327 ShouldGenerateWindowCloseOnAltF4(void)
328 {
329  const char *hint;
330 
332  if (hint) {
333  if (*hint == '0') {
334  return SDL_TRUE;
335  } else {
336  return SDL_FALSE;
337  }
338  }
339  return SDL_TRUE;
340 }
341 
342 LRESULT CALLBACK
343 WIN_WindowProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
344 {
346  LRESULT returnCode = -1;
347 
348  /* Send a SDL_SYSWMEVENT if the application wants them */
350  SDL_SysWMmsg wmmsg;
351 
352  SDL_VERSION(&wmmsg.version);
354  wmmsg.msg.win.hwnd = hwnd;
355  wmmsg.msg.win.msg = msg;
356  wmmsg.msg.win.wParam = wParam;
357  wmmsg.msg.win.lParam = lParam;
358  SDL_SendSysWMEvent(&wmmsg);
359  }
360 
361  /* Get the window data for the window */
362  data = (SDL_WindowData *) GetProp(hwnd, TEXT("SDL_WindowData"));
363  if (!data) {
364  return CallWindowProc(DefWindowProc, hwnd, msg, wParam, lParam);
365  }
366 
367 #ifdef WMMSG_DEBUG
368  {
369  char message[1024];
370  if (msg > MAX_WMMSG) {
371  SDL_snprintf(message, sizeof(message), "Received windows message: %p UNKNOWN (%d) -- 0x%X, 0x%X\n", hwnd, msg, wParam, lParam);
372  } else {
373  SDL_snprintf(message, sizeof(message), "Received windows message: %p %s -- 0x%X, 0x%X\n", hwnd, wmtab[msg], wParam, lParam);
374  }
375  OutputDebugStringA(message);
376  }
377 #endif /* WMMSG_DEBUG */
378 
379  if (IME_HandleMessage(hwnd, msg, wParam, &lParam, data->videodata))
380  return 0;
381 
382  switch (msg) {
383 
384  case WM_SHOWWINDOW:
385  {
386  if (wParam) {
388  } else {
390  }
391  }
392  break;
393 
394  case WM_ACTIVATE:
395  {
396  POINT cursorPos;
397  BOOL minimized;
398 
399  minimized = HIWORD(wParam);
400  if (!minimized && (LOWORD(wParam) != WA_INACTIVE)) {
401  data->focus_click_pending = (GetAsyncKeyState(VK_LBUTTON) != 0);
402 
404  if (SDL_GetKeyboardFocus() != data->window) {
406  }
407 
408  GetCursorPos(&cursorPos);
409  ScreenToClient(hwnd, &cursorPos);
410  SDL_SendMouseMotion(data->window, 0, 0, cursorPos.x, cursorPos.y);
411 
412  WIN_CheckAsyncMouseRelease(data);
413 
414  /*
415  * FIXME: Update keyboard state
416  */
418 
419  SDL_ToggleModState(KMOD_CAPS, (GetKeyState(VK_CAPITAL) & 0x0001) != 0);
420  SDL_ToggleModState(KMOD_NUM, (GetKeyState(VK_NUMLOCK) & 0x0001) != 0);
421  } else {
423 
424  if (SDL_GetKeyboardFocus() == data->window) {
426  }
427 
428  ClipCursor(NULL);
429 
431  }
432  }
433  returnCode = 0;
434  break;
435 
436  case WM_MOUSEMOVE:
437  {
438  SDL_Mouse *mouse = SDL_GetMouse();
439  if (!mouse->relative_mode || mouse->relative_mode_warp) {
440  SDL_MouseID mouseID = (((GetMessageExtraInfo() & MOUSEEVENTF_FROMTOUCH) == MOUSEEVENTF_FROMTOUCH) ? SDL_TOUCH_MOUSEID : 0);
441  SDL_SendMouseMotion(data->window, mouseID, 0, GET_X_LPARAM(lParam), GET_Y_LPARAM(lParam));
442  }
443  }
444  /* don't break here, fall through to check the wParam like the button presses */
445  case WM_LBUTTONUP:
446  case WM_RBUTTONUP:
447  case WM_MBUTTONUP:
448  case WM_XBUTTONUP:
449  case WM_LBUTTONDOWN:
450  case WM_LBUTTONDBLCLK:
451  case WM_RBUTTONDOWN:
452  case WM_RBUTTONDBLCLK:
453  case WM_MBUTTONDOWN:
454  case WM_MBUTTONDBLCLK:
455  case WM_XBUTTONDOWN:
456  case WM_XBUTTONDBLCLK:
457  {
458  SDL_Mouse *mouse = SDL_GetMouse();
459  if (!mouse->relative_mode || mouse->relative_mode_warp) {
460  SDL_MouseID mouseID = (((GetMessageExtraInfo() & MOUSEEVENTF_FROMTOUCH) == MOUSEEVENTF_FROMTOUCH) ? SDL_TOUCH_MOUSEID : 0);
461  WIN_CheckWParamMouseButtons(wParam, data, mouseID);
462  }
463  }
464  break;
465 
466  case WM_INPUT:
467  {
468  SDL_Mouse *mouse = SDL_GetMouse();
469  HRAWINPUT hRawInput = (HRAWINPUT)lParam;
470  RAWINPUT inp;
471  UINT size = sizeof(inp);
472  const SDL_bool isRelative = mouse->relative_mode || mouse->relative_mode_warp;
473  const SDL_bool isCapture = ((data->window->flags & SDL_WINDOW_MOUSE_CAPTURE) != 0);
474 
475  if (!isRelative || mouse->focus != data->window) {
476  if (!isCapture) {
477  break;
478  }
479  }
480 
481  GetRawInputData(hRawInput, RID_INPUT, &inp, &size, sizeof(RAWINPUTHEADER));
482 
483  /* Mouse data */
484  if (inp.header.dwType == RIM_TYPEMOUSE) {
485  if (isRelative) {
486  RAWMOUSE* rawmouse = &inp.data.mouse;
487 
488  if ((rawmouse->usFlags & 0x01) == MOUSE_MOVE_RELATIVE) {
489  SDL_SendMouseMotion(data->window, 0, 1, (int)rawmouse->lLastX, (int)rawmouse->lLastY);
490  } else {
491  /* synthesize relative moves from the abs position */
492  static SDL_Point initialMousePoint;
493  if (initialMousePoint.x == 0 && initialMousePoint.y == 0) {
494  initialMousePoint.x = rawmouse->lLastX;
495  initialMousePoint.y = rawmouse->lLastY;
496  }
497 
498  SDL_SendMouseMotion(data->window, 0, 1, (int)(rawmouse->lLastX-initialMousePoint.x), (int)(rawmouse->lLastY-initialMousePoint.y) );
499 
500  initialMousePoint.x = rawmouse->lLastX;
501  initialMousePoint.y = rawmouse->lLastY;
502  }
503  WIN_CheckRawMouseButtons(rawmouse->usButtonFlags, data);
504  } else if (isCapture) {
505  /* we check for where Windows thinks the system cursor lives in this case, so we don't really lose mouse accel, etc. */
506  POINT pt;
507  GetCursorPos(&pt);
508  if (WindowFromPoint(pt) != hwnd) { /* if in the window, WM_MOUSEMOVE, etc, will cover it. */
509  ScreenToClient(hwnd, &pt);
510  SDL_SendMouseMotion(data->window, 0, 0, (int) pt.x, (int) pt.y);
511  SDL_SendMouseButton(data->window, 0, GetAsyncKeyState(VK_LBUTTON) & 0x8000 ? SDL_PRESSED : SDL_RELEASED, SDL_BUTTON_LEFT);
512  SDL_SendMouseButton(data->window, 0, GetAsyncKeyState(VK_RBUTTON) & 0x8000 ? SDL_PRESSED : SDL_RELEASED, SDL_BUTTON_RIGHT);
513  SDL_SendMouseButton(data->window, 0, GetAsyncKeyState(VK_MBUTTON) & 0x8000 ? SDL_PRESSED : SDL_RELEASED, SDL_BUTTON_MIDDLE);
514  SDL_SendMouseButton(data->window, 0, GetAsyncKeyState(VK_XBUTTON1) & 0x8000 ? SDL_PRESSED : SDL_RELEASED, SDL_BUTTON_X1);
515  SDL_SendMouseButton(data->window, 0, GetAsyncKeyState(VK_XBUTTON2) & 0x8000 ? SDL_PRESSED : SDL_RELEASED, SDL_BUTTON_X2);
516  }
517  } else {
518  SDL_assert(0 && "Shouldn't happen");
519  }
520  }
521  }
522  break;
523 
524  case WM_MOUSEWHEEL:
525  {
526  static short s_AccumulatedMotion;
527 
528  s_AccumulatedMotion += GET_WHEEL_DELTA_WPARAM(wParam);
529  if (s_AccumulatedMotion > 0) {
530  while (s_AccumulatedMotion >= WHEEL_DELTA) {
532  s_AccumulatedMotion -= WHEEL_DELTA;
533  }
534  } else {
535  while (s_AccumulatedMotion <= -WHEEL_DELTA) {
537  s_AccumulatedMotion += WHEEL_DELTA;
538  }
539  }
540  }
541  break;
542 
543  case WM_MOUSEHWHEEL:
544  {
545  static short s_AccumulatedMotion;
546 
547  s_AccumulatedMotion += GET_WHEEL_DELTA_WPARAM(wParam);
548  if (s_AccumulatedMotion > 0) {
549  while (s_AccumulatedMotion >= WHEEL_DELTA) {
551  s_AccumulatedMotion -= WHEEL_DELTA;
552  }
553  } else {
554  while (s_AccumulatedMotion <= -WHEEL_DELTA) {
556  s_AccumulatedMotion += WHEEL_DELTA;
557  }
558  }
559  }
560  break;
561 
562 #ifdef WM_MOUSELEAVE
563  case WM_MOUSELEAVE:
564  if (SDL_GetMouseFocus() == data->window && !SDL_GetMouse()->relative_mode && !(data->window->flags & SDL_WINDOW_MOUSE_CAPTURE)) {
565  if (!IsIconic(hwnd)) {
566  POINT cursorPos;
567  GetCursorPos(&cursorPos);
568  ScreenToClient(hwnd, &cursorPos);
569  SDL_SendMouseMotion(data->window, 0, 0, cursorPos.x, cursorPos.y);
570  }
572  }
573  returnCode = 0;
574  break;
575 #endif /* WM_MOUSELEAVE */
576 
577  case WM_KEYDOWN:
578  case WM_SYSKEYDOWN:
579  {
580  SDL_Scancode code = WindowsScanCodeToSDLScanCode(lParam, wParam);
581  const Uint8 *keyboardState = SDL_GetKeyboardState(NULL);
582 
583  /* Detect relevant keyboard shortcuts */
584  if (keyboardState[SDL_SCANCODE_LALT] == SDL_PRESSED || keyboardState[SDL_SCANCODE_RALT] == SDL_PRESSED) {
585  /* ALT+F4: Close window */
586  if (code == SDL_SCANCODE_F4 && ShouldGenerateWindowCloseOnAltF4()) {
588  }
589  }
590 
591  if (code != SDL_SCANCODE_UNKNOWN) {
593  }
594  }
595 
596  returnCode = 0;
597  break;
598 
599  case WM_SYSKEYUP:
600  case WM_KEYUP:
601  {
602  SDL_Scancode code = WindowsScanCodeToSDLScanCode(lParam, wParam);
603  const Uint8 *keyboardState = SDL_GetKeyboardState(NULL);
604 
605  if (code != SDL_SCANCODE_UNKNOWN) {
606  if (code == SDL_SCANCODE_PRINTSCREEN &&
607  keyboardState[code] == SDL_RELEASED) {
609  }
611  }
612  }
613  returnCode = 0;
614  break;
615 
616  case WM_UNICHAR:
617  if ( wParam == UNICODE_NOCHAR ) {
618  returnCode = 1;
619  break;
620  }
621  /* otherwise fall through to below */
622  case WM_CHAR:
623  {
624  char text[5];
625  if ( WIN_ConvertUTF32toUTF8( (UINT32)wParam, text ) ) {
626  SDL_SendKeyboardText( text );
627  }
628  }
629  returnCode = 0;
630  break;
631 
632 #ifdef WM_INPUTLANGCHANGE
633  case WM_INPUTLANGCHANGE:
634  {
637  }
638  returnCode = 1;
639  break;
640 #endif /* WM_INPUTLANGCHANGE */
641 
642  case WM_NCLBUTTONDOWN:
643  {
644  data->in_title_click = SDL_TRUE;
645  }
646  break;
647 
648  case WM_CAPTURECHANGED:
649  {
650  data->in_title_click = SDL_FALSE;
651 
652  /* The mouse may have been released during a modal loop */
653  WIN_CheckAsyncMouseRelease(data);
654  }
655  break;
656 
657 #ifdef WM_GETMINMAXINFO
658  case WM_GETMINMAXINFO:
659  {
660  MINMAXINFO *info;
661  RECT size;
662  int x, y;
663  int w, h;
664  int min_w, min_h;
665  int max_w, max_h;
666  int style;
667  BOOL menu;
668  BOOL constrain_max_size;
669 
670  if (SDL_IsShapedWindow(data->window))
672 
673  /* If this is an expected size change, allow it */
674  if (data->expected_resize) {
675  break;
676  }
677 
678  /* Get the current position of our window */
679  GetWindowRect(hwnd, &size);
680  x = size.left;
681  y = size.top;
682 
683  /* Calculate current size of our window */
684  SDL_GetWindowSize(data->window, &w, &h);
685  SDL_GetWindowMinimumSize(data->window, &min_w, &min_h);
686  SDL_GetWindowMaximumSize(data->window, &max_w, &max_h);
687 
688  /* Store in min_w and min_h difference between current size and minimal
689  size so we don't need to call AdjustWindowRectEx twice */
690  min_w -= w;
691  min_h -= h;
692  if (max_w && max_h) {
693  max_w -= w;
694  max_h -= h;
695  constrain_max_size = TRUE;
696  } else {
697  constrain_max_size = FALSE;
698  }
699 
700  size.top = 0;
701  size.left = 0;
702  size.bottom = h;
703  size.right = w;
704 
705  style = GetWindowLong(hwnd, GWL_STYLE);
706  /* DJM - according to the docs for GetMenu(), the
707  return value is undefined if hwnd is a child window.
708  Apparently it's too difficult for MS to check
709  inside their function, so I have to do it here.
710  */
711  menu = (style & WS_CHILDWINDOW) ? FALSE : (GetMenu(hwnd) != NULL);
712  AdjustWindowRectEx(&size, style, menu, 0);
713  w = size.right - size.left;
714  h = size.bottom - size.top;
715 
716  /* Fix our size to the current size */
717  info = (MINMAXINFO *) lParam;
719  info->ptMinTrackSize.x = w + min_w;
720  info->ptMinTrackSize.y = h + min_h;
721  if (constrain_max_size) {
722  info->ptMaxTrackSize.x = w + max_w;
723  info->ptMaxTrackSize.y = h + max_h;
724  }
725  } else {
726  info->ptMaxSize.x = w;
727  info->ptMaxSize.y = h;
728  info->ptMaxPosition.x = x;
729  info->ptMaxPosition.y = y;
730  info->ptMinTrackSize.x = w;
731  info->ptMinTrackSize.y = h;
732  info->ptMaxTrackSize.x = w;
733  info->ptMaxTrackSize.y = h;
734  }
735  }
736  returnCode = 0;
737  break;
738 #endif /* WM_GETMINMAXINFO */
739 
740  case WM_WINDOWPOSCHANGED:
741  {
742  RECT rect;
743  int x, y;
744  int w, h;
745 
746  if (data->initializing || data->in_border_change) {
747  break;
748  }
749 
750  if (!GetClientRect(hwnd, &rect) || IsRectEmpty(&rect)) {
751  break;
752  }
753  ClientToScreen(hwnd, (LPPOINT) & rect);
754  ClientToScreen(hwnd, (LPPOINT) & rect + 1);
755 
757 
758  x = rect.left;
759  y = rect.top;
761 
762  w = rect.right - rect.left;
763  h = rect.bottom - rect.top;
765  h);
766  }
767  break;
768 
769  case WM_SIZE:
770  {
771  switch (wParam) {
772  case SIZE_MAXIMIZED:
775  break;
776  case SIZE_MINIMIZED:
779  break;
780  default:
783  break;
784  }
785  }
786  break;
787 
788  case WM_SETCURSOR:
789  {
790  Uint16 hittest;
791 
792  hittest = LOWORD(lParam);
793  if (hittest == HTCLIENT) {
794  SetCursor(SDL_cursor);
795  returnCode = TRUE;
797  SetCursor(NULL);
798  returnCode = TRUE;
799  }
800  }
801  break;
802 
803  /* We were occluded, refresh our display */
804  case WM_PAINT:
805  {
806  RECT rect;
807  if (GetUpdateRect(hwnd, &rect, FALSE)) {
808  ValidateRect(hwnd, NULL);
810  0, 0);
811  }
812  }
813  returnCode = 0;
814  break;
815 
816  /* We'll do our own drawing, prevent flicker */
817  case WM_ERASEBKGND:
818  {
819  }
820  return (1);
821 
822  case WM_SYSCOMMAND:
823  {
824  if ((wParam & 0xFFF0) == SC_KEYMENU) {
825  return (0);
826  }
827 
828 #if defined(SC_SCREENSAVE) || defined(SC_MONITORPOWER)
829  /* Don't start the screensaver or blank the monitor in fullscreen apps */
830  if ((wParam & 0xFFF0) == SC_SCREENSAVE ||
831  (wParam & 0xFFF0) == SC_MONITORPOWER) {
832  if (SDL_GetVideoDevice()->suspend_screensaver) {
833  return (0);
834  }
835  }
836 #endif /* System has screensaver support */
837  }
838  break;
839 
840  case WM_CLOSE:
841  {
843  }
844  returnCode = 0;
845  break;
846 
847  case WM_TOUCH:
848  {
849  UINT i, num_inputs = LOWORD(wParam);
850  PTOUCHINPUT inputs = SDL_stack_alloc(TOUCHINPUT, num_inputs);
851  if (data->videodata->GetTouchInputInfo((HTOUCHINPUT)lParam, num_inputs, inputs, sizeof(TOUCHINPUT))) {
852  RECT rect;
853  float x, y;
854 
855  if (!GetClientRect(hwnd, &rect) ||
856  (rect.right == rect.left && rect.bottom == rect.top)) {
857  if (inputs) {
858  SDL_stack_free(inputs);
859  }
860  break;
861  }
862  ClientToScreen(hwnd, (LPPOINT) & rect);
863  ClientToScreen(hwnd, (LPPOINT) & rect + 1);
864  rect.top *= 100;
865  rect.left *= 100;
866  rect.bottom *= 100;
867  rect.right *= 100;
868 
869  for (i = 0; i < num_inputs; ++i) {
870  PTOUCHINPUT input = &inputs[i];
871 
872  const SDL_TouchID touchId = (SDL_TouchID)((size_t)input->hSource);
873  if (SDL_AddTouch(touchId, "") < 0) {
874  continue;
875  }
876 
877  /* Get the normalized coordinates for the window */
878  x = (float)(input->x - rect.left)/(rect.right - rect.left);
879  y = (float)(input->y - rect.top)/(rect.bottom - rect.top);
880 
881  if (input->dwFlags & TOUCHEVENTF_DOWN) {
882  SDL_SendTouch(touchId, input->dwID, SDL_TRUE, x, y, 1.0f);
883  }
884  if (input->dwFlags & TOUCHEVENTF_MOVE) {
885  SDL_SendTouchMotion(touchId, input->dwID, x, y, 1.0f);
886  }
887  if (input->dwFlags & TOUCHEVENTF_UP) {
888  SDL_SendTouch(touchId, input->dwID, SDL_FALSE, x, y, 1.0f);
889  }
890  }
891  }
892  SDL_stack_free(inputs);
893 
894  data->videodata->CloseTouchInputHandle((HTOUCHINPUT)lParam);
895  return 0;
896  }
897  break;
898 
899  case WM_DROPFILES:
900  {
901  UINT i;
902  HDROP drop = (HDROP) wParam;
903  UINT count = DragQueryFile(drop, 0xFFFFFFFF, NULL, 0);
904  for (i = 0; i < count; ++i) {
905  UINT size = DragQueryFile(drop, i, NULL, 0) + 1;
906  LPTSTR buffer = SDL_stack_alloc(TCHAR, size);
907  if (buffer) {
908  if (DragQueryFile(drop, i, buffer, size)) {
909  char *file = WIN_StringToUTF8(buffer);
910  SDL_SendDropFile(file);
911  SDL_free(file);
912  }
913  SDL_stack_free(buffer);
914  }
915  }
916  DragFinish(drop);
917  return 0;
918  }
919  break;
920 
921  case WM_NCHITTEST:
922  {
923  SDL_Window *window = data->window;
924  if (window->hit_test) {
925  POINT winpoint = { (int) LOWORD(lParam), (int) HIWORD(lParam) };
926  if (ScreenToClient(hwnd, &winpoint)) {
927  const SDL_Point point = { (int) winpoint.x, (int) winpoint.y };
928  const SDL_HitTestResult rc = window->hit_test(window, &point, window->hit_test_data);
929  switch (rc) {
930  case SDL_HITTEST_DRAGGABLE: return HTCAPTION;
931  case SDL_HITTEST_RESIZE_TOPLEFT: return HTTOPLEFT;
932  case SDL_HITTEST_RESIZE_TOP: return HTTOP;
933  case SDL_HITTEST_RESIZE_TOPRIGHT: return HTTOPRIGHT;
934  case SDL_HITTEST_RESIZE_RIGHT: return HTRIGHT;
935  case SDL_HITTEST_RESIZE_BOTTOMRIGHT: return HTBOTTOMRIGHT;
936  case SDL_HITTEST_RESIZE_BOTTOM: return HTBOTTOM;
937  case SDL_HITTEST_RESIZE_BOTTOMLEFT: return HTBOTTOMLEFT;
938  case SDL_HITTEST_RESIZE_LEFT: return HTLEFT;
939  case SDL_HITTEST_NORMAL: return HTCLIENT;
940  }
941  }
942  /* If we didn't return, this will call DefWindowProc below. */
943  }
944  }
945  break;
946 
947  }
948 
949  /* If there's a window proc, assume it's going to handle messages */
950  if (data->wndproc) {
951  return CallWindowProc(data->wndproc, hwnd, msg, wParam, lParam);
952  } else if (returnCode >= 0) {
953  return returnCode;
954  } else {
955  return CallWindowProc(DefWindowProc, hwnd, msg, wParam, lParam);
956  }
957 }
958 
959 /* A message hook called before TranslateMessage() */
960 static SDL_WindowsMessageHook g_WindowsMessageHook = NULL;
961 static void *g_WindowsMessageHookData = NULL;
962 
964 {
965  g_WindowsMessageHook = callback;
966  g_WindowsMessageHookData = userdata;
967 }
968 
969 void
971 {
972  const Uint8 *keystate;
973  MSG msg;
974  DWORD start_ticks = GetTickCount();
975 
977  while (PeekMessage(&msg, NULL, 0, 0, PM_REMOVE)) {
978  if (g_WindowsMessageHook) {
979  g_WindowsMessageHook(g_WindowsMessageHookData, msg.hwnd, msg.message, msg.wParam, msg.lParam);
980  }
981 
982  /* Always translate the message in case it's a non-SDL window (e.g. with Qt integration) */
983  TranslateMessage(&msg);
984  DispatchMessage(&msg);
985 
986  /* Make sure we don't busy loop here forever if there are lots of events coming in */
987  if (SDL_TICKS_PASSED(msg.time, start_ticks)) {
988  break;
989  }
990  }
991  }
992 
993  /* Windows loses a shift KEYUP event when you have both pressed at once and let go of one.
994  You won't get a KEYUP until both are released, and that keyup will only be for the second
995  key you released. Take heroic measures and check the keystate as of the last handled event,
996  and if we think a key is pressed when Windows doesn't, unstick it in SDL's state. */
997  keystate = SDL_GetKeyboardState(NULL);
998  if ((keystate[SDL_SCANCODE_LSHIFT] == SDL_PRESSED) && !(GetKeyState(VK_LSHIFT) & 0x8000)) {
1000  }
1001  if ((keystate[SDL_SCANCODE_RSHIFT] == SDL_PRESSED) && !(GetKeyState(VK_RSHIFT) & 0x8000)) {
1003  }
1004 }
1005 
1006 static int app_registered = 0;
1007 LPTSTR SDL_Appname = NULL;
1008 Uint32 SDL_Appstyle = 0;
1009 HINSTANCE SDL_Instance = NULL;
1010 
1011 /* Register the class for this application */
1012 int
1013 SDL_RegisterApp(char *name, Uint32 style, void *hInst)
1014 {
1015  WNDCLASS class;
1016 
1017  /* Only do this once... */
1018  if (app_registered) {
1019  ++app_registered;
1020  return (0);
1021  }
1022  if (!name && !SDL_Appname) {
1023  name = "SDL_app";
1024 #if defined(CS_BYTEALIGNCLIENT) || defined(CS_OWNDC)
1025  SDL_Appstyle = (CS_BYTEALIGNCLIENT | CS_OWNDC);
1026 #endif
1027  SDL_Instance = hInst ? hInst : GetModuleHandle(NULL);
1028  }
1029 
1030  if (name) {
1031  SDL_Appname = WIN_UTF8ToString(name);
1032  SDL_Appstyle = style;
1033  SDL_Instance = hInst ? hInst : GetModuleHandle(NULL);
1034  }
1035 
1036  /* Register the application class */
1037  class.hCursor = NULL;
1038  class.hIcon =
1039  LoadImage(SDL_Instance, SDL_Appname, IMAGE_ICON, 0, 0,
1040  LR_DEFAULTCOLOR);
1041  class.lpszMenuName = NULL;
1042  class.lpszClassName = SDL_Appname;
1043  class.hbrBackground = NULL;
1044  class.hInstance = SDL_Instance;
1045  class.style = SDL_Appstyle;
1046  class.lpfnWndProc = WIN_WindowProc;
1047  class.cbWndExtra = 0;
1048  class.cbClsExtra = 0;
1049  if (!RegisterClass(&class)) {
1050  return SDL_SetError("Couldn't register application class");
1051  }
1052 
1053  app_registered = 1;
1054  return 0;
1055 }
1056 
1057 /* Unregisters the windowclass registered in SDL_RegisterApp above. */
1058 void
1060 {
1061  WNDCLASS class;
1062 
1063  /* SDL_RegisterApp might not have been called before */
1064  if (!app_registered) {
1065  return;
1066  }
1067  --app_registered;
1068  if (app_registered == 0) {
1069  /* Check for any registered window classes. */
1070  if (GetClassInfo(SDL_Instance, SDL_Appname, &class)) {
1071  UnregisterClass(SDL_Appname, SDL_Instance);
1072  }
1073  SDL_free(SDL_Appname);
1074  SDL_Appname = NULL;
1075  }
1076 }
1077 
1078 #endif /* SDL_VIDEO_DRIVER_WINDOWS */
1079 
1080 /* vi: set ts=4 sw=4 expandtab: */
SDL_version version
Definition: SDL_syswm.h:131
HINSTANCE SDL_Instance
#define WIN_UTF8ToString(S)
Definition: SDL_windows.h:46
SDL_Mouse * SDL_GetMouse(void)
Definition: SDL_mouse.c:66
SDL_bool g_WindowFrameUsableWhileCursorHidden
#define SDL_IsShapedWindow
SDL_Texture * button
void SDL_SetKeyboardFocus(SDL_Window *window)
Definition: SDL_keyboard.c:612
int Win32_ResizeWindowShape(SDL_Window *window)
uint32_t Uint32
An unsigned 32-bit integer type.
Definition: SDL_stdinc.h:155
#define SDL_BUTTON_RMASK
Definition: SDL_mouse.h:287
void * hit_test_data
Definition: SDL_sysvideo.h:102
GLuint GLsizei const GLchar * message
GLint GLint GLint GLint GLint x
Definition: SDL_opengl.h:1567
SDL_bool relative_mode_warp
Definition: SDL_mouse_c.h:85
SDL_Window * focus
Definition: SDL_mouse_c.h:77
GLuint GLuint GLsizei count
Definition: SDL_opengl.h:1564
SDL_Rect rect
Definition: testrelative.c:27
#define SDL_BUTTON_X2MASK
Definition: SDL_mouse.h:289
SDL_Window * window
LRESULT CALLBACK WIN_WindowProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
#define SDL_BUTTON_RIGHT
Definition: SDL_mouse.h:282
The structure that defines a point.
Definition: SDL_rect.h:48
GLint GLenum GLsizei GLsizei GLsizei GLint GLsizei const GLvoid * data
Definition: SDL_opengl.h:1967
#define SDL_GetHint
#define SDL_GetWindowFlags
int SDL_SendTouch(SDL_TouchID id, SDL_FingerID fingerid, SDL_bool down, float x, float y, float pressure)
Definition: SDL_touch.c:216
SDL_bool expected_resize
#define SDL_ENABLE
Definition: SDL_events.h:718
LPTSTR SDL_Appname
GLuint const GLchar * name
int SDL_SendWindowEvent(SDL_Window *window, Uint8 windowevent, int data1, int data2)
SDL_Window * window
#define SDL_BUTTON_X1
Definition: SDL_mouse.h:283
void SDL_SetMouseFocus(SDL_Window *window)
Definition: SDL_mouse.c:103
#define SDL_GetKeyboardFocus
#define SDL_TOUCH_MOUSEID
Definition: SDL_touch.h:53
union SDL_SysWMmsg::@16 msg
GLsizeiptr size
#define TOUCHEVENTF_MOVE
SDL_bool g_WindowsEnableMessageLoop
int SDL_SendSysWMEvent(SDL_SysWMmsg *message)
Definition: SDL_events.c:636
Uint32 SDL_MouseID
Definition: SDL_mouse_c.h:28
int SDL_SendKeyboardKey(Uint8 state, SDL_Scancode scancode)
Definition: SDL_keyboard.c:661
int SDL_SendTouchMotion(SDL_TouchID id, SDL_FingerID fingerid, float x, float y, float pressure)
Definition: SDL_touch.c:278
#define SDL_VERSION(x)
Macro to determine SDL version program was compiled against.
Definition: SDL_version.h:79
SDL_HitTestResult
Possible return values from the SDL_HitTest callback.
Definition: SDL_video.h:852
SDL_bool
Definition: SDL_stdinc.h:126
int x
Definition: SDL_rect.h:50
void SDL_UnregisterApp(void)
#define SDL_GetWindowSize
SDL_bool in_border_change
GLenum GLenum GLenum input
#define SDL_GetEventState(type)
Definition: SDL_events.h:731
#define SDL_GetKeyboardState
GLint GLint GLint GLint GLint GLint y
Definition: SDL_opengl.h:1567
int SDL_SendMouseMotion(SDL_Window *window, SDL_MouseID mouseID, int relative, int x, int y)
Definition: SDL_mouse.c:188
#define SDL_BUTTON_LEFT
Definition: SDL_mouse.h:280
int y
Definition: SDL_rect.h:51
#define _THIS
struct SDL_VideoData * videodata
uint8_t Uint8
An unsigned 8-bit integer type.
Definition: SDL_stdinc.h:139
int SDL_SendKeyboardText(const char *text)
Definition: SDL_keyboard.c:774
#define SDL_stack_alloc(type, count)
Definition: SDL_stdinc.h:324
void SDL_free(void *mem)
#define TRUE
Definition: edid-parse.c:31
SDL_bool relative_mode
Definition: SDL_mouse_c.h:84
#define SDL_BUTTON_X1MASK
Definition: SDL_mouse.h:288
void WIN_UpdateClipCursor(SDL_Window *window)
#define WIN_StringToUTF8(S)
Definition: SDL_windows.h:45
Sint64 SDL_TouchID
Definition: SDL_touch.h:41
static Uint32 callback(Uint32 interval, void *param)
Definition: testtimer.c:34
#define SDL_BUTTON_LMASK
Definition: SDL_mouse.h:285
#define SDL_BUTTON_MIDDLE
Definition: SDL_mouse.h:281
#define SDL_GetWindowMinimumSize
int SDL_AddTouch(SDL_TouchID touchID, const char *name)
Definition: SDL_touch.c:130
BOOL(WINAPI *CloseTouchInputHandle)(HTOUCHINPUT)
#define TOUCHEVENTF_DOWN
void SDL_ToggleModState(const SDL_Keymod modstate, const SDL_bool toggle)
Definition: SDL_keyboard.c:850
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:42
#define SDL_assert(condition)
Definition: SDL_assert.h:167
SDL_SYSWM_TYPE subsystem
Definition: SDL_syswm.h:132
#define NULL
Definition: begin_code.h:143
#define SDL_GetMouseFocus
SDL_HitTest hit_test
Definition: SDL_sysvideo.h:101
void WIN_UpdateKeymap(void)
#define SDL_SetError
static char text[MAX_TEXT_LENGTH]
Definition: testime.c:34
void WIN_PumpEvents(_THIS)
int SDL_SendKeymapChangedEvent(void)
Definition: SDL_events.c:653
static const SDL_Scancode windows_scancode_table[]
int SDL_SendDropFile(const char *file)
The type used to identify a window.
Definition: SDL_sysvideo.h:71
SDL_bool focus_click_pending
GLuint buffer
uint16_t Uint16
An unsigned 16-bit integer type.
Definition: SDL_stdinc.h:147
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_VideoDevice * SDL_GetVideoDevice(void)
Definition: SDL_video.c:573
#define SDL_GetWindowMaximumSize
#define SDL_snprintf
SDL_bool in_window_deactivation
int SDL_SendMouseWheel(SDL_Window *window, SDL_MouseID mouseID, int x, int y, SDL_MouseWheelDirection direction)
Definition: SDL_mouse.c:406
#define VK_OEM_102
Definition: SDL_vkeys.h:74
GLubyte GLubyte GLubyte GLubyte w
char * wmtab[]
Definition: wmmsg.h:24
void SDL_SetWindowsMessageHook(SDL_WindowsMessageHook callback, void *userdata)
#define SDL_PRESSED
Definition: SDL_events.h:50
#define SDL_stack_free(data)
Definition: SDL_stdinc.h:325
void WIN_CheckClipboardUpdate(struct SDL_VideoData *data)
#define SDL_BUTTON_X2
Definition: SDL_mouse.h:284
#define FALSE
Definition: edid-parse.c:32
Uint32 flags
Definition: SDL_sysvideo.h:81
#define SDL_TICKS_PASSED(A, B)
Compare SDL ticks values, and return true if A has passed B.
Definition: SDL_timer.h:56
HCURSOR SDL_cursor
#define SDL_RELEASED
Definition: SDL_events.h:49
#define SDL_BUTTON_MMASK
Definition: SDL_mouse.h:286
#define MAX_WMMSG
Definition: wmmsg.h:22
#define TOUCHEVENTF_UP
int SDL_SendMouseButton(SDL_Window *window, SDL_MouseID mouseID, Uint8 state, Uint8 button)
Definition: SDL_mouse.c:326
SDL_Scancode
The SDL keyboard scancode representation.
Definition: SDL_scancode.h:43
#define SDL_GetMouseState
int SDL_RegisterApp(char *name, Uint32 style, void *hInst)
GLfloat GLfloat GLfloat GLfloat h
SDL_bool in_title_click
#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:631
SDL_bool IME_HandleMessage(HWND hwnd, UINT msg, WPARAM wParam, LPARAM *lParam, struct SDL_VideoData *videodata)
Uint32 SDL_Appstyle