win32_window.c
Go to the documentation of this file.
1 //========================================================================
2 // GLFW 3.3 Win32 - www.glfw.org
3 //------------------------------------------------------------------------
4 // Copyright (c) 2002-2006 Marcus Geelnard
5 // Copyright (c) 2006-2016 Camilla Löwy <elmindreda@glfw.org>
6 //
7 // This software is provided 'as-is', without any express or implied
8 // warranty. In no event will the authors be held liable for any damages
9 // arising from the use of this software.
10 //
11 // Permission is granted to anyone to use this software for any purpose,
12 // including commercial applications, and to alter it and redistribute it
13 // freely, subject to the following restrictions:
14 //
15 // 1. The origin of this software must not be misrepresented; you must not
16 // claim that you wrote the original software. If you use this software
17 // in a product, an acknowledgment in the product documentation would
18 // be appreciated but is not required.
19 //
20 // 2. Altered source versions must be plainly marked as such, and must not
21 // be misrepresented as being the original software.
22 //
23 // 3. This notice may not be removed or altered from any source
24 // distribution.
25 //
26 //========================================================================
27 
28 #include "internal.h"
29 
30 #include <limits.h>
31 #include <stdlib.h>
32 #include <malloc.h>
33 #include <string.h>
34 #include <windowsx.h>
35 #include <shellapi.h>
36 
37 #define _GLFW_KEY_INVALID -2
38 
39 // Returns the window style for the specified window
40 //
41 static DWORD getWindowStyle(const _GLFWwindow* window)
42 {
43  DWORD style = WS_CLIPSIBLINGS | WS_CLIPCHILDREN;
44 
45  if (window->monitor)
46  style |= WS_POPUP;
47  else
48  {
49  style |= WS_SYSMENU | WS_MINIMIZEBOX;
50 
51  if (window->decorated)
52  {
53  style |= WS_CAPTION;
54 
55  if (window->resizable)
56  style |= WS_MAXIMIZEBOX | WS_THICKFRAME;
57  }
58  else
59  style |= WS_POPUP;
60  }
61 
62  return style;
63 }
64 
65 // Returns the extended window style for the specified window
66 //
67 static DWORD getWindowExStyle(const _GLFWwindow* window)
68 {
69  DWORD style = WS_EX_APPWINDOW;
70 
71  if (window->monitor || window->floating)
72  style |= WS_EX_TOPMOST;
73 
74  return style;
75 }
76 
77 // Returns the image whose area most closely matches the desired one
78 //
79 static const GLFWimage* chooseImage(int count, const GLFWimage* images,
80  int width, int height)
81 {
82  int i, leastDiff = INT_MAX;
83  const GLFWimage* closest = NULL;
84 
85  for (i = 0; i < count; i++)
86  {
87  const int currDiff = abs(images[i].width * images[i].height -
88  width * height);
89  if (currDiff < leastDiff)
90  {
91  closest = images + i;
92  leastDiff = currDiff;
93  }
94  }
95 
96  return closest;
97 }
98 
99 // Creates an RGBA icon or cursor
100 //
101 static HICON createIcon(const GLFWimage* image,
102  int xhot, int yhot, GLFWbool icon)
103 {
104  int i;
105  HDC dc;
106  HICON handle;
107  HBITMAP color, mask;
108  BITMAPV5HEADER bi;
109  ICONINFO ii;
110  unsigned char* target = NULL;
111  unsigned char* source = image->pixels;
112 
113  ZeroMemory(&bi, sizeof(bi));
114  bi.bV5Size = sizeof(bi);
115  bi.bV5Width = image->width;
116  bi.bV5Height = -image->height;
117  bi.bV5Planes = 1;
118  bi.bV5BitCount = 32;
119  bi.bV5Compression = BI_BITFIELDS;
120  bi.bV5RedMask = 0x00ff0000;
121  bi.bV5GreenMask = 0x0000ff00;
122  bi.bV5BlueMask = 0x000000ff;
123  bi.bV5AlphaMask = 0xff000000;
124 
125  dc = GetDC(NULL);
126  color = CreateDIBSection(dc,
127  (BITMAPINFO*) &bi,
128  DIB_RGB_COLORS,
129  (void**) &target,
130  NULL,
131  (DWORD) 0);
132  ReleaseDC(NULL, dc);
133 
134  if (!color)
135  {
137  "Win32: Failed to create RGBA bitmap");
138  return NULL;
139  }
140 
141  mask = CreateBitmap(image->width, image->height, 1, 1, NULL);
142  if (!mask)
143  {
145  "Win32: Failed to create mask bitmap");
146  DeleteObject(color);
147  return NULL;
148  }
149 
150  for (i = 0; i < image->width * image->height; i++)
151  {
152  target[0] = source[2];
153  target[1] = source[1];
154  target[2] = source[0];
155  target[3] = source[3];
156  target += 4;
157  source += 4;
158  }
159 
160  ZeroMemory(&ii, sizeof(ii));
161  ii.fIcon = icon;
162  ii.xHotspot = xhot;
163  ii.yHotspot = yhot;
164  ii.hbmMask = mask;
165  ii.hbmColor = color;
166 
167  handle = CreateIconIndirect(&ii);
168 
169  DeleteObject(color);
170  DeleteObject(mask);
171 
172  if (!handle)
173  {
174  if (icon)
175  {
177  "Win32: Failed to create icon");
178  }
179  else
180  {
182  "Win32: Failed to create cursor");
183  }
184  }
185 
186  return handle;
187 }
188 
189 // Translate client window size to full window size according to styles and DPI
190 //
191 static void getFullWindowSize(DWORD style, DWORD exStyle,
192  int clientWidth, int clientHeight,
193  int* fullWidth, int* fullHeight,
194  UINT dpi)
195 {
196  RECT rect = { 0, 0, clientWidth, clientHeight };
197 
199  AdjustWindowRectExForDpi(&rect, style, FALSE, exStyle, dpi);
200  else
201  AdjustWindowRectEx(&rect, style, FALSE, exStyle);
202 
203  *fullWidth = rect.right - rect.left;
204  *fullHeight = rect.bottom - rect.top;
205 }
206 
207 // Enforce the client rect aspect ratio based on which edge is being dragged
208 //
209 static void applyAspectRatio(_GLFWwindow* window, int edge, RECT* area)
210 {
211  int xoff, yoff;
212  UINT dpi = USER_DEFAULT_SCREEN_DPI;
213  const float ratio = (float) window->numer / (float) window->denom;
214 
216  dpi = GetDpiForWindow(window->win32.handle);
217 
219  0, 0, &xoff, &yoff, dpi);
220 
221  if (edge == WMSZ_LEFT || edge == WMSZ_BOTTOMLEFT ||
222  edge == WMSZ_RIGHT || edge == WMSZ_BOTTOMRIGHT)
223  {
224  area->bottom = area->top + yoff +
225  (int) ((area->right - area->left - xoff) / ratio);
226  }
227  else if (edge == WMSZ_TOPLEFT || edge == WMSZ_TOPRIGHT)
228  {
229  area->top = area->bottom - yoff -
230  (int) ((area->right - area->left - xoff) / ratio);
231  }
232  else if (edge == WMSZ_TOP || edge == WMSZ_BOTTOM)
233  {
234  area->right = area->left + xoff +
235  (int) ((area->bottom - area->top - yoff) * ratio);
236  }
237 }
238 
239 // Centers the cursor over the window client area
240 //
242 {
243  int width, height;
244  _glfwPlatformGetWindowSize(window, &width, &height);
245  _glfwPlatformSetCursorPos(window, width / 2.0, height / 2.0);
246 }
247 
248 // Updates the cursor image according to its cursor mode
249 //
251 {
252  if (window->cursorMode == GLFW_CURSOR_NORMAL)
253  {
254  if (window->cursor)
255  SetCursor(window->cursor->win32.handle);
256  else
257  SetCursor(LoadCursorW(NULL, IDC_ARROW));
258  }
259  else
260  SetCursor(NULL);
261 }
262 
263 // Updates the cursor clip rect
264 //
266 {
267  if (window)
268  {
269  RECT clipRect;
270  GetClientRect(window->win32.handle, &clipRect);
271  ClientToScreen(window->win32.handle, (POINT*) &clipRect.left);
272  ClientToScreen(window->win32.handle, (POINT*) &clipRect.right);
273  ClipCursor(&clipRect);
274  }
275  else
276  ClipCursor(NULL);
277 }
278 
279 // Apply disabled cursor mode to a focused window
280 //
282 {
283  const RAWINPUTDEVICE rid = { 0x01, 0x02, 0, window->win32.handle };
284 
285  _glfw.win32.disabledCursorWindow = window;
287  &_glfw.win32.restoreCursorPosX,
288  &_glfw.win32.restoreCursorPosY);
289  updateCursorImage(window);
290  centerCursor(window);
291  updateClipRect(window);
292 
293  if (!RegisterRawInputDevices(&rid, 1, sizeof(rid)))
294  {
296  "Win32: Failed to register raw input device");
297  }
298 }
299 
300 // Exit disabled cursor mode for the specified window
301 //
303 {
304  const RAWINPUTDEVICE rid = { 0x01, 0x02, RIDEV_REMOVE, NULL };
305 
306  _glfw.win32.disabledCursorWindow = NULL;
307  updateClipRect(NULL);
309  _glfw.win32.restoreCursorPosX,
310  _glfw.win32.restoreCursorPosY);
311  updateCursorImage(window);
312 
313  if (!RegisterRawInputDevices(&rid, 1, sizeof(rid)))
314  {
316  "Win32: Failed to remove raw input device");
317  }
318 }
319 
320 // Returns whether the cursor is in the client area of the specified window
321 //
323 {
324  RECT area;
325  POINT pos;
326 
327  if (!GetCursorPos(&pos))
328  return GLFW_FALSE;
329 
330  if (WindowFromPoint(pos) != window->win32.handle)
331  return GLFW_FALSE;
332 
333  GetClientRect(window->win32.handle, &area);
334  ClientToScreen(window->win32.handle, (POINT*) &area.left);
335  ClientToScreen(window->win32.handle, (POINT*) &area.right);
336 
337  return PtInRect(&area, pos);
338 }
339 
340 // Update native window styles to match attributes
341 //
343 {
344  RECT rect;
345  DWORD style = GetWindowLongW(window->win32.handle, GWL_STYLE);
346  style &= ~(WS_OVERLAPPEDWINDOW | WS_POPUP);
347  style |= getWindowStyle(window);
348 
349  GetClientRect(window->win32.handle, &rect);
350 
352  {
353  AdjustWindowRectExForDpi(&rect, style, FALSE,
354  getWindowExStyle(window),
355  GetDpiForWindow(window->win32.handle));
356  }
357  else
358  AdjustWindowRectEx(&rect, style, FALSE, getWindowExStyle(window));
359 
360  ClientToScreen(window->win32.handle, (POINT*) &rect.left);
361  ClientToScreen(window->win32.handle, (POINT*) &rect.right);
362  SetWindowLongW(window->win32.handle, GWL_STYLE, style);
363  SetWindowPos(window->win32.handle, HWND_TOP,
364  rect.left, rect.top,
365  rect.right - rect.left, rect.bottom - rect.top,
366  SWP_FRAMECHANGED | SWP_NOACTIVATE | SWP_NOZORDER);
367 }
368 
369 // Update window framebuffer transparency
370 //
372 {
373  BOOL enabled;
374 
376  return;
377 
378  if (SUCCEEDED(DwmIsCompositionEnabled(&enabled)) && enabled)
379  {
380  HRGN region = CreateRectRgn(0, 0, -1, -1);
381  DWM_BLURBEHIND bb = {0};
383  bb.hRgnBlur = region;
384  bb.fEnable = TRUE;
385 
386  if (SUCCEEDED(DwmEnableBlurBehindWindow(window->win32.handle, &bb)))
387  {
388  // Decorated windows don't repaint the transparent background
389  // leaving a trail behind animations
390  // HACK: Making the window layered with a transparency color key
391  // seems to fix this. Normally, when specifying
392  // a transparency color key to be used when composing the
393  // layered window, all pixels painted by the window in this
394  // color will be transparent. That doesn't seem to be the
395  // case anymore, at least when used with blur behind window
396  // plus negative region.
397  LONG exStyle = GetWindowLongW(window->win32.handle, GWL_EXSTYLE);
398  exStyle |= WS_EX_LAYERED;
399  SetWindowLongW(window->win32.handle, GWL_EXSTYLE, exStyle);
400 
401  // Using a color key not equal to black to fix the trailing
402  // issue. When set to black, something is making the hit test
403  // not resize with the window frame.
404  SetLayeredWindowAttributes(window->win32.handle,
405  RGB(0, 193, 48), 255, LWA_COLORKEY);
406  }
407 
408  DeleteObject(region);
409  }
410  else
411  {
412  LONG exStyle = GetWindowLongW(window->win32.handle, GWL_EXSTYLE);
413  exStyle &= ~WS_EX_LAYERED;
414  SetWindowLongW(window->win32.handle, GWL_EXSTYLE, exStyle);
415  RedrawWindow(window->win32.handle, NULL, NULL,
416  RDW_ERASE | RDW_INVALIDATE | RDW_FRAME);
417  }
418 }
419 
420 // Retrieves and translates modifier keys
421 //
422 static int getKeyMods(void)
423 {
424  int mods = 0;
425 
426  if (GetKeyState(VK_SHIFT) & 0x8000)
427  mods |= GLFW_MOD_SHIFT;
428  if (GetKeyState(VK_CONTROL) & 0x8000)
429  mods |= GLFW_MOD_CONTROL;
430  if (GetKeyState(VK_MENU) & 0x8000)
431  mods |= GLFW_MOD_ALT;
432  if ((GetKeyState(VK_LWIN) | GetKeyState(VK_RWIN)) & 0x8000)
433  mods |= GLFW_MOD_SUPER;
434  if (GetKeyState(VK_CAPITAL) & 1)
435  mods |= GLFW_MOD_CAPS_LOCK;
436  if (GetKeyState(VK_NUMLOCK) & 1)
437  mods |= GLFW_MOD_NUM_LOCK;
438 
439  return mods;
440 }
441 
442 // Retrieves and translates modifier keys
443 //
444 static int getAsyncKeyMods(void)
445 {
446  int mods = 0;
447 
448  if (GetAsyncKeyState(VK_SHIFT) & 0x8000)
449  mods |= GLFW_MOD_SHIFT;
450  if (GetAsyncKeyState(VK_CONTROL) & 0x8000)
451  mods |= GLFW_MOD_CONTROL;
452  if (GetAsyncKeyState(VK_MENU) & 0x8000)
453  mods |= GLFW_MOD_ALT;
454  if ((GetAsyncKeyState(VK_LWIN) | GetAsyncKeyState(VK_RWIN)) & 0x8000)
455  mods |= GLFW_MOD_SUPER;
456  if (GetAsyncKeyState(VK_CAPITAL) & 1)
457  mods |= GLFW_MOD_CAPS_LOCK;
458  if (GetAsyncKeyState(VK_NUMLOCK) & 1)
459  mods |= GLFW_MOD_NUM_LOCK;
460 
461  return mods;
462 }
463 
464 // Translates a Windows key to the corresponding GLFW key
465 //
466 static int translateKey(WPARAM wParam, LPARAM lParam)
467 {
468  // The Ctrl keys require special handling
469  if (wParam == VK_CONTROL)
470  {
471  MSG next;
472  DWORD time;
473 
474  // Right side keys have the extended key bit set
475  if (lParam & 0x01000000)
476  return GLFW_KEY_RIGHT_CONTROL;
477 
478  // HACK: Alt Gr sends Left Ctrl and then Right Alt in close sequence
479  // We only want the Right Alt message, so if the next message is
480  // Right Alt we ignore this (synthetic) Left Ctrl message
481  time = GetMessageTime();
482 
483  if (PeekMessageW(&next, NULL, 0, 0, PM_NOREMOVE))
484  {
485  if (next.message == WM_KEYDOWN ||
486  next.message == WM_SYSKEYDOWN ||
487  next.message == WM_KEYUP ||
488  next.message == WM_SYSKEYUP)
489  {
490  if (next.wParam == VK_MENU &&
491  (next.lParam & 0x01000000) &&
492  next.time == time)
493  {
494  // Next message is Right Alt down so discard this
495  return _GLFW_KEY_INVALID;
496  }
497  }
498  }
499 
500  return GLFW_KEY_LEFT_CONTROL;
501  }
502 
503  if (wParam == VK_PROCESSKEY)
504  {
505  // IME notifies that keys have been filtered by setting the virtual
506  // key-code to VK_PROCESSKEY
507  return _GLFW_KEY_INVALID;
508  }
509 
510  return _glfw.win32.keycodes[HIWORD(lParam) & 0x1FF];
511 }
512 
514 {
515  MONITORINFO mi = { sizeof(mi) };
516  GetMonitorInfo(window->monitor->win32.handle, &mi);
517  SetWindowPos(window->win32.handle, HWND_TOPMOST,
518  mi.rcMonitor.left,
519  mi.rcMonitor.top,
520  mi.rcMonitor.right - mi.rcMonitor.left,
521  mi.rcMonitor.bottom - mi.rcMonitor.top,
522  SWP_NOZORDER | SWP_NOACTIVATE | SWP_NOCOPYBITS);
523 }
524 
525 // Make the specified window and its video mode active on its monitor
526 //
528 {
529  if (!_glfw.win32.acquiredMonitorCount)
530  {
531  SetThreadExecutionState(ES_CONTINUOUS | ES_DISPLAY_REQUIRED);
532 
533  // HACK: When mouse trails are enabled the cursor becomes invisible when
534  // the OpenGL ICD switches to page flipping
535  if (IsWindowsXPOrGreater())
536  {
537  SystemParametersInfo(SPI_GETMOUSETRAILS, 0, &_glfw.win32.mouseTrailSize, 0);
538  SystemParametersInfo(SPI_SETMOUSETRAILS, 0, 0, 0);
539  }
540  }
541 
542  if (!window->monitor->window)
543  _glfw.win32.acquiredMonitorCount++;
544 
545  _glfwSetVideoModeWin32(window->monitor, &window->videoMode);
546  _glfwInputMonitorWindow(window->monitor, window);
547 }
548 
549 // Remove the window and restore the original video mode
550 //
552 {
553  if (window->monitor->window != window)
554  return;
555 
556  _glfw.win32.acquiredMonitorCount--;
557  if (!_glfw.win32.acquiredMonitorCount)
558  {
559  SetThreadExecutionState(ES_CONTINUOUS);
560 
561  // HACK: Restore mouse trail length saved in acquireMonitor
562  if (IsWindowsXPOrGreater())
563  SystemParametersInfo(SPI_SETMOUSETRAILS, _glfw.win32.mouseTrailSize, 0, 0);
564  }
565 
568 }
569 
570 // Window callback function (handles window messages)
571 //
572 static LRESULT CALLBACK windowProc(HWND hWnd, UINT uMsg,
573  WPARAM wParam, LPARAM lParam)
574 {
575  _GLFWwindow* window = GetPropW(hWnd, L"GLFW");
576  if (!window)
577  {
578  // This is the message handling for the hidden helper window
579  // and for a regular window during its initial creation
580 
581  switch (uMsg)
582  {
583  case WM_NCCREATE:
584  {
587 
588  break;
589  }
590 
591  case WM_DISPLAYCHANGE:
593  break;
594 
595  case WM_DEVICECHANGE:
596  {
597  if (wParam == DBT_DEVICEARRIVAL)
598  {
599  DEV_BROADCAST_HDR* dbh = (DEV_BROADCAST_HDR*) lParam;
600  if (dbh && dbh->dbch_devicetype == DBT_DEVTYP_DEVICEINTERFACE)
602  }
603  else if (wParam == DBT_DEVICEREMOVECOMPLETE)
604  {
605  DEV_BROADCAST_HDR* dbh = (DEV_BROADCAST_HDR*) lParam;
606  if (dbh && dbh->dbch_devicetype == DBT_DEVTYP_DEVICEINTERFACE)
608  }
609 
610  break;
611  }
612  }
613 
614  return DefWindowProcW(hWnd, uMsg, wParam, lParam);
615  }
616 
617  switch (uMsg)
618  {
619  case WM_MOUSEACTIVATE:
620  {
621  // HACK: Postpone cursor disabling when the window was activated by
622  // clicking a caption button
623  if (HIWORD(lParam) == WM_LBUTTONDOWN)
624  {
625  if (LOWORD(lParam) == HTCLOSE ||
626  LOWORD(lParam) == HTMINBUTTON ||
627  LOWORD(lParam) == HTMAXBUTTON)
628  {
629  window->win32.frameAction = GLFW_TRUE;
630  }
631  }
632 
633  break;
634  }
635 
636  case WM_CAPTURECHANGED:
637  {
638  // HACK: Disable the cursor once the caption button action has been
639  // completed or cancelled
640  if (lParam == 0 && window->win32.frameAction)
641  {
642  if (window->cursorMode == GLFW_CURSOR_DISABLED)
643  disableCursor(window);
644 
645  window->win32.frameAction = GLFW_FALSE;
646  }
647 
648  break;
649  }
650 
651  case WM_SETFOCUS:
652  {
654 
655  // HACK: Do not disable cursor while the user is interacting with
656  // a caption button
657  if (window->win32.frameAction)
658  break;
659 
660  if (window->cursorMode == GLFW_CURSOR_DISABLED)
661  disableCursor(window);
662 
663  return 0;
664  }
665 
666  case WM_KILLFOCUS:
667  {
668  if (window->cursorMode == GLFW_CURSOR_DISABLED)
669  enableCursor(window);
670 
671  if (window->monitor && window->autoIconify)
673 
675  return 0;
676  }
677 
678  case WM_SYSCOMMAND:
679  {
680  switch (wParam & 0xfff0)
681  {
682  case SC_SCREENSAVE:
683  case SC_MONITORPOWER:
684  {
685  if (window->monitor)
686  {
687  // We are running in full screen mode, so disallow
688  // screen saver and screen blanking
689  return 0;
690  }
691  else
692  break;
693  }
694 
695  // User trying to access application menu using ALT?
696  case SC_KEYMENU:
697  return 0;
698  }
699  break;
700  }
701 
702  case WM_CLOSE:
703  {
705  return 0;
706  }
707 
708  case WM_INPUTLANGCHANGE:
709  {
711  break;
712  }
713 
714  case WM_CHAR:
715  case WM_SYSCHAR:
716  case WM_UNICHAR:
717  {
718  const GLFWbool plain = (uMsg != WM_SYSCHAR);
719 
720  if (uMsg == WM_UNICHAR && wParam == UNICODE_NOCHAR)
721  {
722  // WM_UNICHAR is not sent by Windows, but is sent by some
723  // third-party input method engine
724  // Returning TRUE here announces support for this message
725  return TRUE;
726  }
727 
728  _glfwInputChar(window, (unsigned int) wParam, getKeyMods(), plain);
729  return 0;
730  }
731 
732  case WM_KEYDOWN:
733  case WM_SYSKEYDOWN:
734  case WM_KEYUP:
735  case WM_SYSKEYUP:
736  {
737  const int key = translateKey(wParam, lParam);
738  const int scancode = (lParam >> 16) & 0x1ff;
739  const int action = ((lParam >> 31) & 1) ? GLFW_RELEASE : GLFW_PRESS;
740  const int mods = getKeyMods();
741 
742  if (key == _GLFW_KEY_INVALID)
743  break;
744 
745  if (action == GLFW_RELEASE && wParam == VK_SHIFT)
746  {
747  // HACK: Release both Shift keys on Shift up event, as when both
748  // are pressed the first release does not emit any event
749  // NOTE: The other half of this is in _glfwPlatformPollEvents
750  _glfwInputKey(window, GLFW_KEY_LEFT_SHIFT, scancode, action, mods);
751  _glfwInputKey(window, GLFW_KEY_RIGHT_SHIFT, scancode, action, mods);
752  }
753  else if (wParam == VK_SNAPSHOT)
754  {
755  // HACK: Key down is not reported for the Print Screen key
756  _glfwInputKey(window, key, scancode, GLFW_PRESS, mods);
757  _glfwInputKey(window, key, scancode, GLFW_RELEASE, mods);
758  }
759  else
760  _glfwInputKey(window, key, scancode, action, mods);
761 
762  break;
763  }
764 
765  case WM_LBUTTONDOWN:
766  case WM_RBUTTONDOWN:
767  case WM_MBUTTONDOWN:
768  case WM_XBUTTONDOWN:
769  case WM_LBUTTONUP:
770  case WM_RBUTTONUP:
771  case WM_MBUTTONUP:
772  case WM_XBUTTONUP:
773  {
774  int i, button, action;
775 
776  if (uMsg == WM_LBUTTONDOWN || uMsg == WM_LBUTTONUP)
777  button = GLFW_MOUSE_BUTTON_LEFT;
778  else if (uMsg == WM_RBUTTONDOWN || uMsg == WM_RBUTTONUP)
779  button = GLFW_MOUSE_BUTTON_RIGHT;
780  else if (uMsg == WM_MBUTTONDOWN || uMsg == WM_MBUTTONUP)
781  button = GLFW_MOUSE_BUTTON_MIDDLE;
782  else if (GET_XBUTTON_WPARAM(wParam) == XBUTTON1)
783  button = GLFW_MOUSE_BUTTON_4;
784  else
785  button = GLFW_MOUSE_BUTTON_5;
786 
787  if (uMsg == WM_LBUTTONDOWN || uMsg == WM_RBUTTONDOWN ||
788  uMsg == WM_MBUTTONDOWN || uMsg == WM_XBUTTONDOWN)
789  {
790  action = GLFW_PRESS;
791  }
792  else
793  action = GLFW_RELEASE;
794 
795  for (i = 0; i <= GLFW_MOUSE_BUTTON_LAST; i++)
796  {
797  if (window->mouseButtons[i] == GLFW_PRESS)
798  break;
799  }
800 
801  if (i > GLFW_MOUSE_BUTTON_LAST)
802  SetCapture(hWnd);
803 
804  _glfwInputMouseClick(window, button, action, getKeyMods());
805 
806  for (i = 0; i <= GLFW_MOUSE_BUTTON_LAST; i++)
807  {
808  if (window->mouseButtons[i] == GLFW_PRESS)
809  break;
810  }
811 
812  if (i > GLFW_MOUSE_BUTTON_LAST)
813  ReleaseCapture();
814 
815  if (uMsg == WM_XBUTTONDOWN || uMsg == WM_XBUTTONUP)
816  return TRUE;
817 
818  return 0;
819  }
820 
821  case WM_MOUSEMOVE:
822  {
823  const int x = GET_X_LPARAM(lParam);
824  const int y = GET_Y_LPARAM(lParam);
825 
826  // Disabled cursor motion input is provided by WM_INPUT
827  if (window->cursorMode == GLFW_CURSOR_DISABLED)
828  break;
829 
830  _glfwInputCursorPos(window, x, y);
831 
832  window->win32.lastCursorPosX = x;
833  window->win32.lastCursorPosY = y;
834 
835  if (!window->win32.cursorTracked)
836  {
837  TRACKMOUSEEVENT tme;
838  ZeroMemory(&tme, sizeof(tme));
839  tme.cbSize = sizeof(tme);
840  tme.dwFlags = TME_LEAVE;
841  tme.hwndTrack = window->win32.handle;
842  TrackMouseEvent(&tme);
843 
844  window->win32.cursorTracked = GLFW_TRUE;
846  }
847 
848  return 0;
849  }
850 
851  case WM_INPUT:
852  {
853  UINT size;
854  HRAWINPUT ri = (HRAWINPUT) lParam;
855  RAWINPUT* data;
856  int dx, dy;
857 
858  // Only process input when disabled cursor mode is applied
859  if (_glfw.win32.disabledCursorWindow != window)
860  break;
861 
862  GetRawInputData(ri, RID_INPUT, NULL, &size, sizeof(RAWINPUTHEADER));
863  if (size > (UINT) _glfw.win32.rawInputSize)
864  {
865  free(_glfw.win32.rawInput);
866  _glfw.win32.rawInput = calloc(size, 1);
867  _glfw.win32.rawInputSize = size;
868  }
869 
870  size = _glfw.win32.rawInputSize;
871  if (GetRawInputData(ri, RID_INPUT,
872  _glfw.win32.rawInput, &size,
873  sizeof(RAWINPUTHEADER)) == (UINT) -1)
874  {
876  "Win32: Failed to retrieve raw input data");
877  break;
878  }
879 
880  data = _glfw.win32.rawInput;
881  if (data->data.mouse.usFlags & MOUSE_MOVE_ABSOLUTE)
882  {
883  dx = data->data.mouse.lLastX - window->win32.lastCursorPosX;
884  dy = data->data.mouse.lLastY - window->win32.lastCursorPosY;
885  }
886  else
887  {
888  dx = data->data.mouse.lLastX;
889  dy = data->data.mouse.lLastY;
890  }
891 
892  _glfwInputCursorPos(window,
893  window->virtualCursorPosX + dx,
894  window->virtualCursorPosY + dy);
895 
896  window->win32.lastCursorPosX += dx;
897  window->win32.lastCursorPosY += dy;
898  break;
899  }
900 
901  case WM_MOUSELEAVE:
902  {
903  window->win32.cursorTracked = GLFW_FALSE;
905  return 0;
906  }
907 
908  case WM_MOUSEWHEEL:
909  {
910  _glfwInputScroll(window, 0.0, (SHORT) HIWORD(wParam) / (double) WHEEL_DELTA);
911  return 0;
912  }
913 
914  case WM_MOUSEHWHEEL:
915  {
916  // This message is only sent on Windows Vista and later
917  // NOTE: The X-axis is inverted for consistency with macOS and X11
918  _glfwInputScroll(window, -((SHORT) HIWORD(wParam) / (double) WHEEL_DELTA), 0.0);
919  return 0;
920  }
921 
922  case WM_ENTERSIZEMOVE:
923  case WM_ENTERMENULOOP:
924  {
925  // HACK: Enable the cursor while the user is moving or
926  // resizing the window or using the window menu
927  if (window->cursorMode == GLFW_CURSOR_DISABLED)
928  enableCursor(window);
929 
930  break;
931  }
932 
933  case WM_EXITSIZEMOVE:
934  case WM_EXITMENULOOP:
935  {
936  // HACK: Disable the cursor once the user is done moving or
937  // resizing the window or using the menu
938  if (window->cursorMode == GLFW_CURSOR_DISABLED)
939  disableCursor(window);
940 
941  break;
942  }
943 
944  case WM_SIZE:
945  {
946  const GLFWbool iconified = wParam == SIZE_MINIMIZED;
947  const GLFWbool maximized = wParam == SIZE_MAXIMIZED ||
948  (window->win32.maximized &&
949  wParam != SIZE_RESTORED);
950 
951  if (_glfw.win32.disabledCursorWindow == window)
952  updateClipRect(window);
953 
954  if (window->win32.iconified != iconified)
955  _glfwInputWindowIconify(window, iconified);
956 
957  if (window->win32.maximized != maximized)
958  _glfwInputWindowMaximize(window, maximized);
959 
960  _glfwInputFramebufferSize(window, LOWORD(lParam), HIWORD(lParam));
961  _glfwInputWindowSize(window, LOWORD(lParam), HIWORD(lParam));
962 
963  if (window->monitor && window->win32.iconified != iconified)
964  {
965  if (iconified)
966  releaseMonitor(window);
967  else
968  {
969  acquireMonitor(window);
970  fitToMonitor(window);
971  }
972  }
973 
974  window->win32.iconified = iconified;
975  window->win32.maximized = maximized;
976  return 0;
977  }
978 
979  case WM_MOVE:
980  {
981  if (_glfw.win32.disabledCursorWindow == window)
982  updateClipRect(window);
983 
984  // NOTE: This cannot use LOWORD/HIWORD recommended by MSDN, as
985  // those macros do not handle negative window positions correctly
986  _glfwInputWindowPos(window,
987  GET_X_LPARAM(lParam),
988  GET_Y_LPARAM(lParam));
989  return 0;
990  }
991 
992  case WM_SIZING:
993  {
994  if (window->numer == GLFW_DONT_CARE ||
995  window->denom == GLFW_DONT_CARE)
996  {
997  break;
998  }
999 
1000  applyAspectRatio(window, (int) wParam, (RECT*) lParam);
1001  return TRUE;
1002  }
1003 
1004  case WM_GETMINMAXINFO:
1005  {
1006  int xoff, yoff;
1007  UINT dpi = USER_DEFAULT_SCREEN_DPI;
1008  MINMAXINFO* mmi = (MINMAXINFO*) lParam;
1009 
1010  if (window->monitor)
1011  break;
1012 
1014  dpi = GetDpiForWindow(window->win32.handle);
1015 
1017  0, 0, &xoff, &yoff, dpi);
1018 
1019  if (window->minwidth != GLFW_DONT_CARE &&
1020  window->minheight != GLFW_DONT_CARE)
1021  {
1022  mmi->ptMinTrackSize.x = window->minwidth + xoff;
1023  mmi->ptMinTrackSize.y = window->minheight + yoff;
1024  }
1025 
1026  if (window->maxwidth != GLFW_DONT_CARE &&
1027  window->maxheight != GLFW_DONT_CARE)
1028  {
1029  mmi->ptMaxTrackSize.x = window->maxwidth + xoff;
1030  mmi->ptMaxTrackSize.y = window->maxheight + yoff;
1031  }
1032 
1033  if (!window->decorated)
1034  {
1035  MONITORINFO mi;
1036  const HMONITOR mh = MonitorFromWindow(window->win32.handle,
1037  MONITOR_DEFAULTTONEAREST);
1038 
1039  ZeroMemory(&mi, sizeof(mi));
1040  mi.cbSize = sizeof(mi);
1041  GetMonitorInfo(mh, &mi);
1042 
1043  mmi->ptMaxPosition.x = mi.rcWork.left - mi.rcMonitor.left;
1044  mmi->ptMaxPosition.y = mi.rcWork.top - mi.rcMonitor.top;
1045  mmi->ptMaxSize.x = mi.rcWork.right - mi.rcWork.left;
1046  mmi->ptMaxSize.y = mi.rcWork.bottom - mi.rcWork.top;
1047  }
1048 
1049  return 0;
1050  }
1051 
1052  case WM_PAINT:
1053  {
1054  _glfwInputWindowDamage(window);
1055  break;
1056  }
1057 
1058  case WM_ERASEBKGND:
1059  {
1060  return TRUE;
1061  }
1062 
1064  {
1065  if (window->win32.transparent)
1067  return 0;
1068  }
1069 
1070  case WM_GETDPISCALEDSIZE:
1071  {
1072  if (window->win32.scaleToMonitor)
1073  break;
1074 
1075  // Adjust the window size to keep the client area size constant
1077  {
1078  RECT source = {0}, target = {0};
1079  SIZE* size = (SIZE*) lParam;
1080 
1081  AdjustWindowRectExForDpi(&source, getWindowStyle(window),
1082  FALSE, getWindowExStyle(window),
1083  GetDpiForWindow(window->win32.handle));
1085  FALSE, getWindowExStyle(window),
1086  LOWORD(wParam));
1087 
1088  size->cx += (target.right - target.left) -
1089  (source.right - source.left);
1090  size->cy += (target.bottom - target.top) -
1091  (source.bottom - source.top);
1092  return TRUE;
1093  }
1094 
1095  break;
1096  }
1097 
1098  case WM_DPICHANGED:
1099  {
1100  const float xscale = HIWORD(wParam) / (float) USER_DEFAULT_SCREEN_DPI;
1101  const float yscale = LOWORD(wParam) / (float) USER_DEFAULT_SCREEN_DPI;
1102 
1103  // Only apply the suggested size if the OS is new enough to have
1104  // sent a WM_GETDPISCALEDSIZE before this
1106  {
1107  RECT* suggested = (RECT*) lParam;
1108  SetWindowPos(window->win32.handle, HWND_TOP,
1109  suggested->left,
1110  suggested->top,
1111  suggested->right - suggested->left,
1112  suggested->bottom - suggested->top,
1113  SWP_NOACTIVATE | SWP_NOZORDER);
1114  }
1115 
1116  _glfwInputWindowContentScale(window, xscale, yscale);
1117  break;
1118  }
1119 
1120  case WM_SETCURSOR:
1121  {
1122  if (LOWORD(lParam) == HTCLIENT)
1123  {
1124  updateCursorImage(window);
1125  return TRUE;
1126  }
1127 
1128  break;
1129  }
1130 
1131  case WM_DROPFILES:
1132  {
1133  HDROP drop = (HDROP) wParam;
1134  POINT pt;
1135  int i;
1136 
1137  const int count = DragQueryFileW(drop, 0xffffffff, NULL, 0);
1138  char** paths = calloc(count, sizeof(char*));
1139 
1140  // Move the mouse to the position of the drop
1141  DragQueryPoint(drop, &pt);
1142  _glfwInputCursorPos(window, pt.x, pt.y);
1143 
1144  for (i = 0; i < count; i++)
1145  {
1146  const UINT length = DragQueryFileW(drop, i, NULL, 0);
1147  WCHAR* buffer = calloc(length + 1, sizeof(WCHAR));
1148 
1149  DragQueryFileW(drop, i, buffer, length + 1);
1150  paths[i] = _glfwCreateUTF8FromWideStringWin32(buffer);
1151 
1152  free(buffer);
1153  }
1154 
1155  _glfwInputDrop(window, count, (const char**) paths);
1156 
1157  for (i = 0; i < count; i++)
1158  free(paths[i]);
1159  free(paths);
1160 
1161  DragFinish(drop);
1162  return 0;
1163  }
1164  }
1165 
1166  return DefWindowProcW(hWnd, uMsg, wParam, lParam);
1167 }
1168 
1169 // Creates the GLFW window
1170 //
1172  const _GLFWwndconfig* wndconfig,
1173  const _GLFWfbconfig* fbconfig)
1174 {
1175  int xpos, ypos, fullWidth, fullHeight;
1176  WCHAR* wideTitle;
1177  DWORD style = getWindowStyle(window);
1178  DWORD exStyle = getWindowExStyle(window);
1179 
1180  if (window->monitor)
1181  {
1182  GLFWvidmode mode;
1183 
1184  // NOTE: This window placement is temporary and approximate, as the
1185  // correct position and size cannot be known until the monitor
1186  // video mode has been picked in _glfwSetVideoModeWin32
1187  _glfwPlatformGetMonitorPos(window->monitor, &xpos, &ypos);
1188  _glfwPlatformGetVideoMode(window->monitor, &mode);
1189  fullWidth = mode.width;
1190  fullHeight = mode.height;
1191  }
1192  else
1193  {
1194  xpos = CW_USEDEFAULT;
1195  ypos = CW_USEDEFAULT;
1196 
1197  if (wndconfig->maximized)
1198  style |= WS_MAXIMIZE;
1199 
1200  getFullWindowSize(style, exStyle,
1201  wndconfig->width, wndconfig->height,
1202  &fullWidth, &fullHeight,
1204  }
1205 
1206  wideTitle = _glfwCreateWideStringFromUTF8Win32(wndconfig->title);
1207  if (!wideTitle)
1208  return GLFW_FALSE;
1209 
1210  window->win32.handle = CreateWindowExW(exStyle,
1212  wideTitle,
1213  style,
1214  xpos, ypos,
1215  fullWidth, fullHeight,
1216  NULL, // No parent window
1217  NULL, // No window menu
1218  GetModuleHandleW(NULL),
1219  NULL);
1220 
1221  free(wideTitle);
1222 
1223  if (!window->win32.handle)
1224  {
1226  "Win32: Failed to create window");
1227  return GLFW_FALSE;
1228  }
1229 
1230  SetPropW(window->win32.handle, L"GLFW", window);
1231 
1232  if (IsWindows7OrGreater())
1233  {
1234  ChangeWindowMessageFilterEx(window->win32.handle,
1235  WM_DROPFILES, MSGFLT_ALLOW, NULL);
1236  ChangeWindowMessageFilterEx(window->win32.handle,
1237  WM_COPYDATA, MSGFLT_ALLOW, NULL);
1238  ChangeWindowMessageFilterEx(window->win32.handle,
1240  }
1241 
1242  window->win32.scaleToMonitor = wndconfig->scaleToMonitor;
1243 
1244  // Adjust window size to account for DPI scaling of the window frame and
1245  // optionally DPI scaling of the client area
1246  // This cannot be done until we know what monitor it was placed on
1247  if (!window->monitor)
1248  {
1249  RECT rect = { 0, 0, wndconfig->width, wndconfig->height };
1250 
1251  if (wndconfig->scaleToMonitor)
1252  {
1253  float xscale, yscale;
1254  _glfwPlatformGetWindowContentScale(window, &xscale, &yscale);
1255  rect.right = (int) (rect.right * xscale);
1256  rect.bottom = (int) (rect.bottom * yscale);
1257  }
1258 
1259  ClientToScreen(window->win32.handle, (POINT*) &rect.left);
1260  ClientToScreen(window->win32.handle, (POINT*) &rect.right);
1261 
1263  {
1264  AdjustWindowRectExForDpi(&rect, style, FALSE, exStyle,
1265  GetDpiForWindow(window->win32.handle));
1266  }
1267  else
1268  AdjustWindowRectEx(&rect, style, FALSE, exStyle);
1269 
1270  SetWindowPos(window->win32.handle, NULL,
1271  rect.left, rect.top,
1272  rect.right - rect.left, rect.bottom - rect.top,
1273  SWP_NOACTIVATE | SWP_NOZORDER);
1274  }
1275 
1276  DragAcceptFiles(window->win32.handle, TRUE);
1277 
1278  if (fbconfig->transparent)
1279  {
1281  window->win32.transparent = GLFW_TRUE;
1282  }
1283 
1284  return GLFW_TRUE;
1285 }
1286 
1287 
1291 
1292 // Registers the GLFW window class
1293 //
1295 {
1296  WNDCLASSEXW wc;
1297 
1298  ZeroMemory(&wc, sizeof(wc));
1299  wc.cbSize = sizeof(wc);
1300  wc.style = CS_HREDRAW | CS_VREDRAW | CS_OWNDC;
1301  wc.lpfnWndProc = (WNDPROC) windowProc;
1302  wc.hInstance = GetModuleHandleW(NULL);
1303  wc.hCursor = LoadCursorW(NULL, IDC_ARROW);
1304  wc.lpszClassName = _GLFW_WNDCLASSNAME;
1305 
1306  // Load user-provided icon if available
1307  wc.hIcon = LoadImageW(GetModuleHandleW(NULL),
1308  L"GLFW_ICON", IMAGE_ICON,
1309  0, 0, LR_DEFAULTSIZE | LR_SHARED);
1310  if (!wc.hIcon)
1311  {
1312  // No user-provided icon found, load default icon
1313  wc.hIcon = LoadImageW(NULL,
1314  IDI_APPLICATION, IMAGE_ICON,
1315  0, 0, LR_DEFAULTSIZE | LR_SHARED);
1316  }
1317 
1318  if (!RegisterClassExW(&wc))
1319  {
1321  "Win32: Failed to register window class");
1322  return GLFW_FALSE;
1323  }
1324 
1325  return GLFW_TRUE;
1326 }
1327 
1328 // Unregisters the GLFW window class
1329 //
1331 {
1332  UnregisterClassW(_GLFW_WNDCLASSNAME, GetModuleHandleW(NULL));
1333 }
1334 
1335 
1339 
1341  const _GLFWwndconfig* wndconfig,
1342  const _GLFWctxconfig* ctxconfig,
1343  const _GLFWfbconfig* fbconfig)
1344 {
1345  if (!createNativeWindow(window, wndconfig, fbconfig))
1346  return GLFW_FALSE;
1347 
1348  if (ctxconfig->client != GLFW_NO_API)
1349  {
1350  if (ctxconfig->source == GLFW_NATIVE_CONTEXT_API)
1351  {
1352  if (!_glfwInitWGL())
1353  return GLFW_FALSE;
1354  if (!_glfwCreateContextWGL(window, ctxconfig, fbconfig))
1355  return GLFW_FALSE;
1356  }
1357  else if (ctxconfig->source == GLFW_EGL_CONTEXT_API)
1358  {
1359  if (!_glfwInitEGL())
1360  return GLFW_FALSE;
1361  if (!_glfwCreateContextEGL(window, ctxconfig, fbconfig))
1362  return GLFW_FALSE;
1363  }
1364  else if (ctxconfig->source == GLFW_OSMESA_CONTEXT_API)
1365  {
1366  if (!_glfwInitOSMesa())
1367  return GLFW_FALSE;
1368  if (!_glfwCreateContextOSMesa(window, ctxconfig, fbconfig))
1369  return GLFW_FALSE;
1370  }
1371  }
1372 
1373  if (window->monitor)
1374  {
1375  _glfwPlatformShowWindow(window);
1376  _glfwPlatformFocusWindow(window);
1377  acquireMonitor(window);
1378  fitToMonitor(window);
1379  }
1380 
1381  return GLFW_TRUE;
1382 }
1383 
1385 {
1386  if (window->monitor)
1387  releaseMonitor(window);
1388 
1389  if (window->context.destroy)
1390  window->context.destroy(window);
1391 
1392  if (_glfw.win32.disabledCursorWindow == window)
1393  _glfw.win32.disabledCursorWindow = NULL;
1394 
1395  if (window->win32.handle)
1396  {
1397  RemovePropW(window->win32.handle, L"GLFW");
1398  DestroyWindow(window->win32.handle);
1399  window->win32.handle = NULL;
1400  }
1401 
1402  if (window->win32.bigIcon)
1403  DestroyIcon(window->win32.bigIcon);
1404 
1405  if (window->win32.smallIcon)
1406  DestroyIcon(window->win32.smallIcon);
1407 }
1408 
1410 {
1411  WCHAR* wideTitle = _glfwCreateWideStringFromUTF8Win32(title);
1412  if (!wideTitle)
1413  return;
1414 
1415  SetWindowTextW(window->win32.handle, wideTitle);
1416  free(wideTitle);
1417 }
1418 
1420  int count, const GLFWimage* images)
1421 {
1422  HICON bigIcon = NULL, smallIcon = NULL;
1423 
1424  if (count)
1425  {
1426  const GLFWimage* bigImage = chooseImage(count, images,
1427  GetSystemMetrics(SM_CXICON),
1428  GetSystemMetrics(SM_CYICON));
1429  const GLFWimage* smallImage = chooseImage(count, images,
1430  GetSystemMetrics(SM_CXSMICON),
1431  GetSystemMetrics(SM_CYSMICON));
1432 
1433  bigIcon = createIcon(bigImage, 0, 0, GLFW_TRUE);
1434  smallIcon = createIcon(smallImage, 0, 0, GLFW_TRUE);
1435  }
1436  else
1437  {
1438  bigIcon = (HICON) GetClassLongPtrW(window->win32.handle, GCLP_HICON);
1439  smallIcon = (HICON) GetClassLongPtrW(window->win32.handle, GCLP_HICONSM);
1440  }
1441 
1442  SendMessage(window->win32.handle, WM_SETICON, ICON_BIG, (LPARAM) bigIcon);
1443  SendMessage(window->win32.handle, WM_SETICON, ICON_SMALL, (LPARAM) smallIcon);
1444 
1445  if (window->win32.bigIcon)
1446  DestroyIcon(window->win32.bigIcon);
1447 
1448  if (window->win32.smallIcon)
1449  DestroyIcon(window->win32.smallIcon);
1450 
1451  if (count)
1452  {
1453  window->win32.bigIcon = bigIcon;
1454  window->win32.smallIcon = smallIcon;
1455  }
1456 }
1457 
1459 {
1460  POINT pos = { 0, 0 };
1461  ClientToScreen(window->win32.handle, &pos);
1462 
1463  if (xpos)
1464  *xpos = pos.x;
1465  if (ypos)
1466  *ypos = pos.y;
1467 }
1468 
1470 {
1471  RECT rect = { xpos, ypos, xpos, ypos };
1472 
1474  {
1476  FALSE, getWindowExStyle(window),
1477  GetDpiForWindow(window->win32.handle));
1478  }
1479  else
1480  {
1481  AdjustWindowRectEx(&rect, getWindowStyle(window),
1482  FALSE, getWindowExStyle(window));
1483  }
1484 
1485  SetWindowPos(window->win32.handle, NULL, rect.left, rect.top, 0, 0,
1486  SWP_NOACTIVATE | SWP_NOZORDER | SWP_NOSIZE);
1487 }
1488 
1490 {
1491  RECT area;
1492  GetClientRect(window->win32.handle, &area);
1493 
1494  if (width)
1495  *width = area.right;
1496  if (height)
1497  *height = area.bottom;
1498 }
1499 
1501 {
1502  if (window->monitor)
1503  {
1504  if (window->monitor->window == window)
1505  {
1506  acquireMonitor(window);
1507  fitToMonitor(window);
1508  }
1509  }
1510  else
1511  {
1512  RECT rect = { 0, 0, width, height };
1513 
1515  {
1517  FALSE, getWindowExStyle(window),
1518  GetDpiForWindow(window->win32.handle));
1519  }
1520  else
1521  {
1522  AdjustWindowRectEx(&rect, getWindowStyle(window),
1523  FALSE, getWindowExStyle(window));
1524  }
1525 
1526  SetWindowPos(window->win32.handle, HWND_TOP,
1527  0, 0, rect.right - rect.left, rect.bottom - rect.top,
1528  SWP_NOACTIVATE | SWP_NOOWNERZORDER | SWP_NOMOVE | SWP_NOZORDER);
1529  }
1530 }
1531 
1533  int minwidth, int minheight,
1534  int maxwidth, int maxheight)
1535 {
1536  RECT area;
1537 
1538  if ((minwidth == GLFW_DONT_CARE || minheight == GLFW_DONT_CARE) &&
1539  (maxwidth == GLFW_DONT_CARE || maxheight == GLFW_DONT_CARE))
1540  {
1541  return;
1542  }
1543 
1544  GetWindowRect(window->win32.handle, &area);
1545  MoveWindow(window->win32.handle,
1546  area.left, area.top,
1547  area.right - area.left,
1548  area.bottom - area.top, TRUE);
1549 }
1550 
1552 {
1553  RECT area;
1554 
1555  if (numer == GLFW_DONT_CARE || denom == GLFW_DONT_CARE)
1556  return;
1557 
1558  GetWindowRect(window->win32.handle, &area);
1559  applyAspectRatio(window, WMSZ_BOTTOMRIGHT, &area);
1560  MoveWindow(window->win32.handle,
1561  area.left, area.top,
1562  area.right - area.left,
1563  area.bottom - area.top, TRUE);
1564 }
1565 
1567 {
1568  _glfwPlatformGetWindowSize(window, width, height);
1569 }
1570 
1572  int* left, int* top,
1573  int* right, int* bottom)
1574 {
1575  RECT rect;
1576  int width, height;
1577 
1578  _glfwPlatformGetWindowSize(window, &width, &height);
1579  SetRect(&rect, 0, 0, width, height);
1580 
1582  {
1584  FALSE, getWindowExStyle(window),
1585  GetDpiForWindow(window->win32.handle));
1586  }
1587  else
1588  {
1589  AdjustWindowRectEx(&rect, getWindowStyle(window),
1590  FALSE, getWindowExStyle(window));
1591  }
1592 
1593  if (left)
1594  *left = -rect.left;
1595  if (top)
1596  *top = -rect.top;
1597  if (right)
1598  *right = rect.right - width;
1599  if (bottom)
1600  *bottom = rect.bottom - height;
1601 }
1602 
1604  float* xscale, float* yscale)
1605 {
1606  const HANDLE handle = MonitorFromWindow(window->win32.handle,
1607  MONITOR_DEFAULTTONEAREST);
1608  _glfwGetMonitorContentScaleWin32(handle, xscale, yscale);
1609 }
1610 
1612 {
1613  ShowWindow(window->win32.handle, SW_MINIMIZE);
1614 }
1615 
1617 {
1618  ShowWindow(window->win32.handle, SW_RESTORE);
1619 }
1620 
1622 {
1623  ShowWindow(window->win32.handle, SW_MAXIMIZE);
1624 }
1625 
1627 {
1628  ShowWindow(window->win32.handle, SW_SHOWNA);
1629 }
1630 
1632 {
1633  ShowWindow(window->win32.handle, SW_HIDE);
1634 }
1635 
1637 {
1638  FlashWindow(window->win32.handle, TRUE);
1639 }
1640 
1642 {
1643  BringWindowToTop(window->win32.handle);
1644  SetForegroundWindow(window->win32.handle);
1645  SetFocus(window->win32.handle);
1646 }
1647 
1649  _GLFWmonitor* monitor,
1650  int xpos, int ypos,
1651  int width, int height,
1652  int refreshRate)
1653 {
1654  if (window->monitor == monitor)
1655  {
1656  if (monitor)
1657  {
1658  if (monitor->window == window)
1659  {
1660  acquireMonitor(window);
1661  fitToMonitor(window);
1662  }
1663  }
1664  else
1665  {
1666  RECT rect = { xpos, ypos, xpos + width, ypos + height };
1667 
1669  {
1671  FALSE, getWindowExStyle(window),
1672  GetDpiForWindow(window->win32.handle));
1673  }
1674  else
1675  {
1676  AdjustWindowRectEx(&rect, getWindowStyle(window),
1677  FALSE, getWindowExStyle(window));
1678  }
1679 
1680  SetWindowPos(window->win32.handle, HWND_TOP,
1681  rect.left, rect.top,
1682  rect.right - rect.left, rect.bottom - rect.top,
1683  SWP_NOCOPYBITS | SWP_NOACTIVATE | SWP_NOZORDER);
1684  }
1685 
1686  return;
1687  }
1688 
1689  if (window->monitor)
1690  releaseMonitor(window);
1691 
1692  _glfwInputWindowMonitor(window, monitor);
1693 
1694  if (monitor)
1695  {
1696  MONITORINFO mi = { sizeof(mi) };
1697  UINT flags = SWP_SHOWWINDOW | SWP_NOACTIVATE | SWP_NOCOPYBITS;
1698 
1699  if (window->decorated)
1700  {
1701  DWORD style = GetWindowLongW(window->win32.handle, GWL_STYLE);
1702  style &= ~WS_OVERLAPPEDWINDOW;
1703  style |= getWindowStyle(window);
1704  SetWindowLongW(window->win32.handle, GWL_STYLE, style);
1705  flags |= SWP_FRAMECHANGED;
1706  }
1707 
1708  acquireMonitor(window);
1709 
1710  GetMonitorInfo(window->monitor->win32.handle, &mi);
1711  SetWindowPos(window->win32.handle, HWND_TOPMOST,
1712  mi.rcMonitor.left,
1713  mi.rcMonitor.top,
1714  mi.rcMonitor.right - mi.rcMonitor.left,
1715  mi.rcMonitor.bottom - mi.rcMonitor.top,
1716  flags);
1717  }
1718  else
1719  {
1720  HWND after;
1721  RECT rect = { xpos, ypos, xpos + width, ypos + height };
1722  DWORD style = GetWindowLongW(window->win32.handle, GWL_STYLE);
1723  UINT flags = SWP_NOACTIVATE | SWP_NOCOPYBITS;
1724 
1725  if (window->decorated)
1726  {
1727  style &= ~WS_POPUP;
1728  style |= getWindowStyle(window);
1729  SetWindowLongW(window->win32.handle, GWL_STYLE, style);
1730 
1731  flags |= SWP_FRAMECHANGED;
1732  }
1733 
1734  if (window->floating)
1735  after = HWND_TOPMOST;
1736  else
1737  after = HWND_NOTOPMOST;
1738 
1740  {
1742  FALSE, getWindowExStyle(window),
1743  GetDpiForWindow(window->win32.handle));
1744  }
1745  else
1746  {
1747  AdjustWindowRectEx(&rect, getWindowStyle(window),
1748  FALSE, getWindowExStyle(window));
1749  }
1750 
1751  SetWindowPos(window->win32.handle, after,
1752  rect.left, rect.top,
1753  rect.right - rect.left, rect.bottom - rect.top,
1754  flags);
1755  }
1756 }
1757 
1759 {
1760  return window->win32.handle == GetActiveWindow();
1761 }
1762 
1764 {
1765  return IsIconic(window->win32.handle);
1766 }
1767 
1769 {
1770  return IsWindowVisible(window->win32.handle);
1771 }
1772 
1774 {
1775  return IsZoomed(window->win32.handle);
1776 }
1777 
1779 {
1780  return cursorInClientArea(window);
1781 }
1782 
1784 {
1785  BOOL enabled;
1786 
1787  if (!window->win32.transparent)
1788  return GLFW_FALSE;
1789 
1790  if (!IsWindowsVistaOrGreater())
1791  return GLFW_FALSE;
1792 
1793  return SUCCEEDED(DwmIsCompositionEnabled(&enabled)) && enabled;
1794 }
1795 
1797 {
1798  updateWindowStyles(window);
1799 }
1800 
1802 {
1803  updateWindowStyles(window);
1804 }
1805 
1807 {
1808  const HWND after = enabled ? HWND_TOPMOST : HWND_NOTOPMOST;
1809  SetWindowPos(window->win32.handle, after, 0, 0, 0, 0,
1810  SWP_NOACTIVATE | SWP_NOMOVE | SWP_NOSIZE);
1811 }
1812 
1814 {
1815  BYTE alpha;
1816  DWORD flags;
1817 
1818  if ((GetWindowLongW(window->win32.handle, GWL_EXSTYLE) & WS_EX_LAYERED) &&
1819  GetLayeredWindowAttributes(window->win32.handle, NULL, &alpha, &flags))
1820  {
1821  if (flags & LWA_ALPHA)
1822  return alpha / 255.f;
1823  }
1824 
1825  return 1.f;
1826 }
1827 
1829 {
1830  if (opacity < 1.f)
1831  {
1832  const BYTE alpha = (BYTE) (255 * opacity);
1833  DWORD style = GetWindowLongW(window->win32.handle, GWL_EXSTYLE);
1834  style |= WS_EX_LAYERED;
1835  SetWindowLongW(window->win32.handle, GWL_EXSTYLE, style);
1836  SetLayeredWindowAttributes(window->win32.handle, 0, alpha, LWA_ALPHA);
1837  }
1838  else
1839  {
1840  DWORD style = GetWindowLongW(window->win32.handle, GWL_EXSTYLE);
1841  style &= ~WS_EX_LAYERED;
1842  SetWindowLongW(window->win32.handle, GWL_EXSTYLE, style);
1843  }
1844 }
1845 
1847 {
1848  MSG msg;
1849  HWND handle;
1851 
1852  while (PeekMessageW(&msg, NULL, 0, 0, PM_REMOVE))
1853  {
1854  if (msg.message == WM_QUIT)
1855  {
1856  // NOTE: While GLFW does not itself post WM_QUIT, other processes
1857  // may post it to this one, for example Task Manager
1858  // HACK: Treat WM_QUIT as a close on all windows
1859 
1860  window = _glfw.windowListHead;
1861  while (window)
1862  {
1864  window = window->next;
1865  }
1866  }
1867  else
1868  {
1869  TranslateMessage(&msg);
1870  DispatchMessageW(&msg);
1871  }
1872  }
1873 
1874  handle = GetActiveWindow();
1875  if (handle)
1876  {
1877  // NOTE: Shift keys on Windows tend to "stick" when both are pressed as
1878  // no key up message is generated by the first key release
1879  // The other half of this is in the handling of WM_KEYUP
1880  // HACK: Query actual key state and synthesize release events as needed
1881  window = GetPropW(handle, L"GLFW");
1882  if (window)
1883  {
1884  const GLFWbool lshift = (GetAsyncKeyState(VK_LSHIFT) >> 15) & 1;
1885  const GLFWbool rshift = (GetAsyncKeyState(VK_RSHIFT) >> 15) & 1;
1886 
1887  if (!lshift && window->keys[GLFW_KEY_LEFT_SHIFT] == GLFW_PRESS)
1888  {
1889  const int mods = getAsyncKeyMods();
1890  const int scancode = _glfw.win32.scancodes[GLFW_KEY_LEFT_SHIFT];
1891  _glfwInputKey(window, GLFW_KEY_LEFT_SHIFT, scancode, GLFW_RELEASE, mods);
1892  }
1893  else if (!rshift && window->keys[GLFW_KEY_RIGHT_SHIFT] == GLFW_PRESS)
1894  {
1895  const int mods = getAsyncKeyMods();
1896  const int scancode = _glfw.win32.scancodes[GLFW_KEY_RIGHT_SHIFT];
1897  _glfwInputKey(window, GLFW_KEY_RIGHT_SHIFT, scancode, GLFW_RELEASE, mods);
1898  }
1899  }
1900  }
1901 
1902  window = _glfw.win32.disabledCursorWindow;
1903  if (window)
1904  {
1905  int width, height;
1906  _glfwPlatformGetWindowSize(window, &width, &height);
1907 
1908  // NOTE: Re-center the cursor only if it has moved since the last call,
1909  // to avoid breaking glfwWaitEvents with WM_MOUSEMOVE
1910  if (window->win32.lastCursorPosX != width / 2 ||
1911  window->win32.lastCursorPosY != height / 2)
1912  {
1913  _glfwPlatformSetCursorPos(window, width / 2, height / 2);
1914  }
1915  }
1916 }
1917 
1919 {
1920  WaitMessage();
1921 
1923 }
1924 
1926 {
1927  MsgWaitForMultipleObjects(0, NULL, FALSE, (DWORD) (timeout * 1e3), QS_ALLEVENTS);
1928 
1930 }
1931 
1933 {
1934  PostMessage(_glfw.win32.helperWindowHandle, WM_NULL, 0, 0);
1935 }
1936 
1938 {
1939  POINT pos;
1940 
1941  if (GetCursorPos(&pos))
1942  {
1943  ScreenToClient(window->win32.handle, &pos);
1944 
1945  if (xpos)
1946  *xpos = pos.x;
1947  if (ypos)
1948  *ypos = pos.y;
1949  }
1950 }
1951 
1953 {
1954  POINT pos = { (int) xpos, (int) ypos };
1955 
1956  // Store the new position so it can be recognized later
1957  window->win32.lastCursorPosX = pos.x;
1958  window->win32.lastCursorPosY = pos.y;
1959 
1960  ClientToScreen(window->win32.handle, &pos);
1961  SetCursorPos(pos.x, pos.y);
1962 }
1963 
1965 {
1966  if (mode == GLFW_CURSOR_DISABLED)
1967  {
1968  if (_glfwPlatformWindowFocused(window))
1969  disableCursor(window);
1970  }
1971  else if (_glfw.win32.disabledCursorWindow == window)
1972  enableCursor(window);
1973  else if (cursorInClientArea(window))
1974  updateCursorImage(window);
1975 }
1976 
1977 const char* _glfwPlatformGetScancodeName(int scancode)
1978 {
1979  return _glfw.win32.keynames[_glfw.win32.keycodes[scancode]];
1980 }
1981 
1983 {
1984  return _glfw.win32.scancodes[key];
1985 }
1986 
1988  const GLFWimage* image,
1989  int xhot, int yhot)
1990 {
1991  cursor->win32.handle = (HCURSOR) createIcon(image, xhot, yhot, GLFW_FALSE);
1992  if (!cursor->win32.handle)
1993  return GLFW_FALSE;
1994 
1995  return GLFW_TRUE;
1996 }
1997 
1999 {
2000  LPCWSTR name = NULL;
2001 
2002  if (shape == GLFW_ARROW_CURSOR)
2003  name = IDC_ARROW;
2004  else if (shape == GLFW_IBEAM_CURSOR)
2005  name = IDC_IBEAM;
2006  else if (shape == GLFW_CROSSHAIR_CURSOR)
2007  name = IDC_CROSS;
2008  else if (shape == GLFW_HAND_CURSOR)
2009  name = IDC_HAND;
2010  else if (shape == GLFW_HRESIZE_CURSOR)
2011  name = IDC_SIZEWE;
2012  else if (shape == GLFW_VRESIZE_CURSOR)
2013  name = IDC_SIZENS;
2014  else
2015  return GLFW_FALSE;
2016 
2017  cursor->win32.handle = CopyCursor(LoadCursorW(NULL, name));
2018  if (!cursor->win32.handle)
2019  {
2021  "Win32: Failed to create standard cursor");
2022  return GLFW_FALSE;
2023  }
2024 
2025  return GLFW_TRUE;
2026 }
2027 
2029 {
2030  if (cursor->win32.handle)
2031  DestroyIcon((HICON) cursor->win32.handle);
2032 }
2033 
2035 {
2036  if (cursorInClientArea(window))
2037  updateCursorImage(window);
2038 }
2039 
2040 void _glfwPlatformSetClipboardString(const char* string)
2041 {
2042  int characterCount;
2043  HANDLE object;
2044  WCHAR* buffer;
2045 
2046  characterCount = MultiByteToWideChar(CP_UTF8, 0, string, -1, NULL, 0);
2047  if (!characterCount)
2048  return;
2049 
2050  object = GlobalAlloc(GMEM_MOVEABLE, characterCount * sizeof(WCHAR));
2051  if (!object)
2052  {
2054  "Win32: Failed to allocate global handle for clipboard");
2055  return;
2056  }
2057 
2058  buffer = GlobalLock(object);
2059  if (!buffer)
2060  {
2062  "Win32: Failed to lock global handle");
2063  GlobalFree(object);
2064  return;
2065  }
2066 
2067  MultiByteToWideChar(CP_UTF8, 0, string, -1, buffer, characterCount);
2068  GlobalUnlock(object);
2069 
2070  if (!OpenClipboard(_glfw.win32.helperWindowHandle))
2071  {
2073  "Win32: Failed to open clipboard");
2074  GlobalFree(object);
2075  return;
2076  }
2077 
2078  EmptyClipboard();
2079  SetClipboardData(CF_UNICODETEXT, object);
2080  CloseClipboard();
2081 }
2082 
2084 {
2085  HANDLE object;
2086  WCHAR* buffer;
2087 
2088  if (!OpenClipboard(_glfw.win32.helperWindowHandle))
2089  {
2091  "Win32: Failed to open clipboard");
2092  return NULL;
2093  }
2094 
2095  object = GetClipboardData(CF_UNICODETEXT);
2096  if (!object)
2097  {
2099  "Win32: Failed to convert clipboard to string");
2100  CloseClipboard();
2101  return NULL;
2102  }
2103 
2104  buffer = GlobalLock(object);
2105  if (!buffer)
2106  {
2108  "Win32: Failed to lock global handle");
2109  CloseClipboard();
2110  return NULL;
2111  }
2112 
2113  free(_glfw.win32.clipboardString);
2114  _glfw.win32.clipboardString = _glfwCreateUTF8FromWideStringWin32(buffer);
2115 
2116  GlobalUnlock(object);
2117  CloseClipboard();
2118 
2119  return _glfw.win32.clipboardString;
2120 }
2121 
2123 {
2124  if (!_glfw.vk.KHR_surface || !_glfw.vk.KHR_win32_surface)
2125  return;
2126 
2127  extensions[0] = "VK_KHR_surface";
2128  extensions[1] = "VK_KHR_win32_surface";
2129 }
2130 
2133  uint32_t queuefamily)
2134 {
2136  vkGetPhysicalDeviceWin32PresentationSupportKHR =
2138  vkGetInstanceProcAddr(instance, "vkGetPhysicalDeviceWin32PresentationSupportKHR");
2139  if (!vkGetPhysicalDeviceWin32PresentationSupportKHR)
2140  {
2142  "Win32: Vulkan instance missing VK_KHR_win32_surface extension");
2143  return GLFW_FALSE;
2144  }
2145 
2146  return vkGetPhysicalDeviceWin32PresentationSupportKHR(device, queuefamily);
2147 }
2148 
2151  const VkAllocationCallbacks* allocator,
2152  VkSurfaceKHR* surface)
2153 {
2154  VkResult err;
2156  PFN_vkCreateWin32SurfaceKHR vkCreateWin32SurfaceKHR;
2157 
2158  vkCreateWin32SurfaceKHR = (PFN_vkCreateWin32SurfaceKHR)
2159  vkGetInstanceProcAddr(instance, "vkCreateWin32SurfaceKHR");
2160  if (!vkCreateWin32SurfaceKHR)
2161  {
2163  "Win32: Vulkan instance missing VK_KHR_win32_surface extension");
2165  }
2166 
2167  memset(&sci, 0, sizeof(sci));
2169  sci.hinstance = GetModuleHandle(NULL);
2170  sci.hwnd = window->win32.handle;
2171 
2172  err = vkCreateWin32SurfaceKHR(instance, &sci, allocator, surface);
2173  if (err)
2174  {
2176  "Win32: Failed to create Vulkan surface: %s",
2178  }
2179 
2180  return err;
2181 }
2182 
2183 
2187 
2189 {
2190  _GLFWwindow* window = (_GLFWwindow*) handle;
2192  return window->win32.handle;
2193 }
2194 
static DWORD getWindowStyle(const _GLFWwindow *window)
Definition: win32_window.c:41
void _glfwGetMonitorContentScaleWin32(HMONITOR handle, float *xscale, float *yscale)
void _glfwPlatformIconifyWindow(_GLFWwindow *window)
float _glfwPlatformGetWindowOpacity(_GLFWwindow *window)
#define GLFW_KEY_RIGHT_CONTROL
Definition: glfw3.h:478
int height
Definition: glfw3.h:1532
void _glfwRestoreVideoModeWin32(_GLFWmonitor *monitor)
WCHAR * _glfwCreateWideStringFromUTF8Win32(const char *source)
Definition: win32_init.c:384
GLint y
IMGUI_API ImVec2 GetCursorPos()
Definition: imgui.cpp:5076
VkResult(APIENTRY * PFN_vkCreateWin32SurfaceKHR)(VkInstance, const VkWin32SurfaceCreateInfoKHR *, const VkAllocationCallbacks *, VkSurfaceKHR *)
#define UNICODE_NOCHAR
#define GLFW_MOD_CONTROL
If this bit is set one or more Control keys were held down.
Definition: glfw3.h:504
VkBool32(APIENTRY * PFN_vkGetPhysicalDeviceWin32PresentationSupportKHR)(VkPhysicalDevice, uint32_t)
GLuint const GLchar * name
static HICON createIcon(const GLFWimage *image, int xhot, int yhot, GLFWbool icon)
Definition: win32_window.c:101
VkResult
Definition: vulkan_core.h:122
void _glfwInputWindowCloseRequest(_GLFWwindow *window)
Definition: window.c:131
GLFWbool scaleToMonitor
Definition: internal.h:268
void _glfwPlatformSetWindowSizeLimits(_GLFWwindow *window, int minwidth, int minheight, int maxwidth, int maxheight)
unsigned char * pixels
Definition: glfw3.h:1598
static int translateKey(WPARAM wParam, LPARAM lParam)
Definition: win32_window.c:466
#define GLFWAPI
Definition: glfw3.h:240
GLdouble GLdouble GLdouble top
static void enableCursor(_GLFWwindow *window)
Definition: win32_window.c:302
void _glfwDetectJoystickConnectionWin32(void)
void _glfwUnregisterWindowClassWin32(void)
IMGUI_API void SetCursorPos(const ImVec2 &local_pos)
Definition: imgui.cpp:5094
void _glfwInputChar(_GLFWwindow *window, unsigned int codepoint, int mods, GLFWbool plain)
Definition: input.c:290
static void updateClipRect(_GLFWwindow *window)
Definition: win32_window.c:265
#define WM_DPICHANGED
static void updateCursorImage(_GLFWwindow *window)
Definition: win32_window.c:250
static const GLFWimage * chooseImage(int count, const GLFWimage *images, int width, int height)
Definition: win32_window.c:79
void _glfwPlatformGetCursorPos(_GLFWwindow *window, double *xpos, double *ypos)
static GLFWwindow * window
Definition: joysticks.c:55
GLFWbool _glfwInitOSMesa(void)
static void updateWindowStyles(const _GLFWwindow *window)
Definition: win32_window.c:342
int width
Definition: glfw3.h:1529
void _glfwInputWindowIconify(_GLFWwindow *window, GLFWbool iconified)
Definition: window.c:89
const char * _glfwPlatformGetClipboardString(void)
int _glfwPlatformFramebufferTransparent(_GLFWwindow *window)
GLuint64 GLenum void * handle
Definition: glext.h:7785
#define GLFW_MOUSE_BUTTON_RIGHT
Definition: glfw3.h:547
_GLFWdestroycontextfun destroy
Definition: internal.h:353
GLint GLuint mask
void _glfwInputFramebufferSize(_GLFWwindow *window, int width, int height)
Definition: window.c:106
void _glfwPlatformDestroyCursor(_GLFWcursor *cursor)
GLsizei const GLuint * paths
Definition: glext.h:10532
int height
Definition: glfw3.h:1595
char * _glfwCreateUTF8FromWideStringWin32(const WCHAR *source)
Definition: win32_init.c:412
void _glfwInputWindowMaximize(_GLFWwindow *window, GLFWbool maximized)
Definition: window.c:97
int _glfwPlatformCreateStandardCursor(_GLFWcursor *cursor, int shape)
#define GLFW_KEY_LEFT_SHIFT
Definition: glfw3.h:473
#define GLFW_FALSE
Zero.
Definition: glfw3.h:287
const char * _glfwGetVulkanResultString(VkResult result)
Definition: src/vulkan.c:159
struct _GLFWlibrary::@29 vk
void _glfwPlatformGetVideoMode(_GLFWmonitor *monitor, GLFWvidmode *mode)
Definition: null_monitor.c:57
#define GLFW_MOUSE_BUTTON_LEFT
Definition: glfw3.h:546
#define GLFW_CROSSHAIR_CURSOR
The crosshair shape.
Definition: glfw3.h:1040
static void centerCursor(_GLFWwindow *window)
Definition: win32_window.c:241
#define GLFW_API_UNAVAILABLE
GLFW could not find support for the requested API on the system.
Definition: glfw3.h:698
#define GLFW_EGL_CONTEXT_API
Definition: glfw3.h:1015
GLFWbool _glfwCreateContextWGL(_GLFWwindow *window, const _GLFWctxconfig *ctxconfig, const _GLFWfbconfig *fbconfig)
Definition: wgl_context.c:478
#define EnableNonClientDpiScaling
std::array< point3d, 4 > object
#define GLFW_FORMAT_UNAVAILABLE
The requested format is not supported or available.
Definition: glfw3.h:745
#define DWM_BB_ENABLE
void _glfwPlatformGetWindowContentScale(_GLFWwindow *window, float *xscale, float *yscale)
#define GLFW_ARROW_CURSOR
The regular arrow cursor shape.
Definition: glfw3.h:1030
static int getAsyncKeyMods(void)
Definition: win32_window.c:444
void _glfwPlatformSetWindowResizable(_GLFWwindow *window, GLFWbool enabled)
_GLFWcontext context
Definition: internal.h:394
_GLFWwindow * windowListHead
Definition: internal.h:526
int GLFWbool
Definition: internal.h:61
GLenum GLfloat * buffer
void _glfwPlatformSetWindowIcon(_GLFWwindow *window, int count, const GLFWimage *images)
int _glfwPlatformWindowFocused(_GLFWwindow *window)
#define GLFW_MOUSE_BUTTON_5
Definition: glfw3.h:541
const char * title
Definition: internal.h:258
void _glfwInputWindowDamage(_GLFWwindow *window)
Definition: window.c:123
GLenum GLenum GLsizei void * image
#define MSGFLT_ALLOW
#define GLFW_DONT_CARE
Definition: glfw3.h:1080
void _glfwInputCursorEnter(_GLFWwindow *window, GLFWbool entered)
Definition: input.c:352
void _glfwInputWindowPos(_GLFWwindow *window, int xpos, int ypos)
Definition: window.c:72
void _glfwPlatformDestroyWindow(_GLFWwindow *window)
void _glfwPlatformSetWindowAspectRatio(_GLFWwindow *window, int numer, int denom)
GLFWvidmode videoMode
Definition: internal.h:377
GLFWbool KHR_surface
Definition: internal.h:553
void _glfwPlatformSetCursorPos(_GLFWwindow *window, double xpos, double ypos)
void _glfwPlatformSetWindowSize(_GLFWwindow *window, int width, int height)
void _glfwInputScroll(_GLFWwindow *window, double xoffset, double yoffset)
Definition: input.c:310
#define GLFW_RELEASE
The key or mouse button was released.
Definition: glfw3.h:297
GLuint64 key
Definition: glext.h:8966
#define GLFW_CURSOR_DISABLED
Definition: glfw3.h:1008
void _glfwPlatformWaitEventsTimeout(double timeout)
void _glfwPlatformShowWindow(_GLFWwindow *window)
GLFWbool resizable
Definition: internal.h:370
GLFWbool transparent
Definition: internal.h:328
#define IsWindowsXPOrGreater()
void _glfwPlatformGetRequiredInstanceExtensions(char **extensions)
GLdouble f
int maxwidth
Definition: internal.h:382
#define GLFW_VRESIZE_CURSOR
The vertical resize arrow shape.
Definition: glfw3.h:1055
#define _GLFW_REQUIRE_INIT_OR_RETURN(x)
Definition: internal.h:210
GLenum mode
unsigned char BYTE
Definition: lz4.c:145
char keys[GLFW_KEY_LAST+1]
Definition: internal.h:390
#define WM_COPYGLOBALDATA
#define GLFW_MOUSE_BUTTON_MIDDLE
Definition: glfw3.h:548
GLfloat GLfloat GLfloat alpha
static int createNativeWindow(_GLFWwindow *window, const _GLFWwndconfig *wndconfig, const _GLFWfbconfig *fbconfig)
GLsizeiptr size
GLFWbool _glfwCreateContextEGL(_GLFWwindow *window, const _GLFWctxconfig *ctxconfig, const _GLFWfbconfig *fbconfig)
Definition: egl_context.c:456
static void fitToMonitor(_GLFWwindow *window)
Definition: win32_window.c:513
void _glfwPlatformHideWindow(_GLFWwindow *window)
int maxheight
Definition: internal.h:382
#define GLFW_CURSOR_NORMAL
Definition: glfw3.h:1006
GLFWbool maximized
Definition: internal.h:265
#define GLFW_PLATFORM_ERROR
A platform-specific error occurred that does not match any of the more specific categories.
Definition: glfw3.h:726
int _glfwPlatformWindowVisible(_GLFWwindow *window)
#define GLFW_NATIVE_CONTEXT_API
Definition: glfw3.h:1014
_GLFWlibrary _glfw
Definition: init.c:44
#define WM_GETDPISCALEDSIZE
void _glfwInputWindowFocus(_GLFWwindow *window, GLFWbool focused)
Definition: window.c:43
#define DWM_BB_BLURREGION
#define GLFW_MOD_SUPER
If this bit is set one or more Super keys were held down.
Definition: glfw3.h:514
GLdouble x
void * VkInstance
Definition: internal.h:118
#define GLFW_HAND_CURSOR
The hand shape.
Definition: glfw3.h:1045
unsigned int uint32_t
Definition: stdint.h:80
void _glfwInputWindowContentScale(_GLFWwindow *window, float xscale, float yscale)
Definition: window.c:115
#define GLFW_MOD_SHIFT
If this bit is set one or more Shift keys were held down.
Definition: glfw3.h:499
int cursorMode
Definition: internal.h:388
void * VkPhysicalDevice
Definition: internal.h:119
void _glfwPlatformSetCursorMode(_GLFWwindow *window, int mode)
void _glfwInputErrorWin32(int error, const char *description)
Definition: win32_init.c:440
GLint GLsizei GLsizei height
int _glfwPlatformCreateWindow(_GLFWwindow *window, const _GLFWwndconfig *wndconfig, const _GLFWctxconfig *ctxconfig, const _GLFWfbconfig *fbconfig)
struct _GLFWwindow * next
Definition: internal.h:367
GLenum target
Definition: glext.h:1565
GLFWbool _glfwRegisterWindowClassWin32(void)
GLbitfield flags
#define DwmEnableBlurBehindWindow
void _glfwPlatformGetMonitorPos(_GLFWmonitor *monitor, int *xpos, int *ypos)
Definition: null_monitor.c:39
GLenum GLenum GLsizei const GLuint GLboolean enabled
void _glfwPlatformSetWindowMonitor(_GLFWwindow *window, _GLFWmonitor *monitor, int xpos, int ypos, int width, int height, int refreshRate)
void _glfwInputKey(_GLFWwindow *window, int key, int scancode, int action, int mods)
Definition: input.c:259
VKAPI_ATTR PFN_vkVoidFunction VKAPI_CALL vkGetInstanceProcAddr(VkInstance instance, const char *pName)
int _glfwPlatformGetPhysicalDevicePresentationSupport(VkInstance instance, VkPhysicalDevice device, uint32_t queuefamily)
void _glfwPlatformGetWindowPos(_GLFWwindow *window, int *xpos, int *ypos)
void _glfwPlatformGetWindowSize(_GLFWwindow *window, int *width, int *height)
GLint left
Definition: glext.h:1963
double virtualCursorPosY
Definition: internal.h:392
uint64_t VkSurfaceKHR
Definition: internal.h:120
#define GLFW_OSMESA_CONTEXT_API
Definition: glfw3.h:1016
int minwidth
Definition: internal.h:381
#define WM_UNICHAR
void _glfwInputError(int code, const char *format,...)
Definition: init.c:129
void _glfwPollMonitorsWin32(void)
#define GLFW_MOD_ALT
If this bit is set one or more Alt keys were held down.
Definition: glfw3.h:509
action
Definition: enums.py:62
void _glfwSetVideoModeWin32(_GLFWmonitor *monitor, const GLFWvidmode *desired)
#define IsWindows7OrGreater()
#define AdjustWindowRectExForDpi
void _glfwInputWindowSize(_GLFWwindow *window, int width, int height)
Definition: window.c:81
void _glfwPlatformSetWindowPos(_GLFWwindow *window, int xpos, int ypos)
#define GLFW_MOD_CAPS_LOCK
If this bit is set the Caps Lock key is enabled.
Definition: glfw3.h:520
#define IsWindowsVistaOrGreater()
#define GET_XBUTTON_WPARAM(w)
static LRESULT CALLBACK windowProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
Definition: win32_window.c:572
int _glfwPlatformWindowHovered(_GLFWwindow *window)
GLFWbool floating
Definition: internal.h:373
void _glfwPlatformRequestWindowAttention(_GLFWwindow *window)
VkResult _glfwPlatformCreateWindowSurface(VkInstance instance, _GLFWwindow *window, const VkAllocationCallbacks *allocator, VkSurfaceKHR *surface)
void _glfwPlatformSetWindowTitle(_GLFWwindow *window, const char *title)
static DWORD getWindowExStyle(const _GLFWwindow *window)
Definition: win32_window.c:67
void _glfwInputWindowMonitor(_GLFWwindow *window, _GLFWmonitor *monitor)
Definition: window.c:141
int width
Definition: glfw3.h:1592
#define GLFW_TRUE
One.
Definition: glfw3.h:279
void next(auto_any_t cur, type2type< T, C > *)
Definition: foreach.hpp:757
void _glfwInputCursorPos(_GLFWwindow *window, double xpos, double ypos)
Definition: input.c:338
GLFWbool autoIconify
Definition: internal.h:372
Definition: example.hpp:70
#define _glfwIsWindows10CreatorsUpdateOrGreaterWin32()
#define WM_MOUSEHWHEEL
void _glfwPlatformSetWindowFloating(_GLFWwindow *window, GLFWbool enabled)
int _glfwPlatformWindowIconified(_GLFWwindow *window)
void _glfwPlatformFocusWindow(_GLFWwindow *window)
Video mode type.
Definition: glfw3.h:1525
static void releaseMonitor(_GLFWwindow *window)
Definition: win32_window.c:551
int _glfwPlatformGetKeyScancode(int key)
GLdouble right
GLbitfield GLuint64 timeout
#define GLFW_HRESIZE_CURSOR
The horizontal resize arrow shape.
Definition: glfw3.h:1050
static double xpos
Definition: splitview.c:33
#define GLFW_IBEAM_CURSOR
The text input I-beam cursor shape.
Definition: glfw3.h:1035
GLFWbool _glfwCreateContextOSMesa(_GLFWwindow *window, const _GLFWctxconfig *ctxconfig, const _GLFWfbconfig *fbconfig)
static const char * maximized
Definition: model-views.h:183
GLint GLsizei count
void _glfwInputMonitorWindow(_GLFWmonitor *monitor, _GLFWwindow *window)
Definition: monitor.c:149
void _glfwDetectJoystickDisconnectionWin32(void)
#define GLFW_KEY_LEFT_CONTROL
Definition: glfw3.h:474
GLFWbool _glfwInitWGL(void)
Definition: wgl_context.c:343
void _glfwPlatformWaitEvents(void)
static void updateFramebufferTransparency(const _GLFWwindow *window)
Definition: win32_window.c:371
void _glfwPlatformPostEmptyEvent(void)
_GLFWcursor * cursor
Definition: internal.h:379
#define GLFW_MOUSE_BUTTON_LAST
Definition: glfw3.h:545
int minheight
Definition: internal.h:381
GLsizei GLsizei GLchar * source
#define WM_DWMCOMPOSITIONCHANGED
float rs2_vector::* pos
void _glfwPlatformSetWindowOpacity(_GLFWwindow *window, float opacity)
static void applyAspectRatio(_GLFWwindow *window, int edge, RECT *area)
Definition: win32_window.c:209
#define DwmIsCompositionEnabled
char mouseButtons[GLFW_MOUSE_BUTTON_LAST+1]
Definition: internal.h:389
int _glfwPlatformCreateCursor(_GLFWcursor *cursor, const GLFWimage *image, int xhot, int yhot)
#define NULL
Definition: tinycthread.c:47
#define TRUE
Definition: tinycthread.c:50
int i
GLenum GLuint GLenum GLsizei length
void _glfwPlatformRestoreWindow(_GLFWwindow *window)
static void getFullWindowSize(DWORD style, DWORD exStyle, int clientWidth, int clientHeight, int *fullWidth, int *fullHeight, UINT dpi)
Definition: win32_window.c:191
std::array< float, 3 > color
Definition: model-views.h:449
Image data.
Definition: glfw3.h:1588
#define _GLFW_KEY_INVALID
Definition: win32_window.c:37
#define USER_DEFAULT_SCREEN_DPI
#define ChangeWindowMessageFilterEx
void _glfwPlatformMaximizeWindow(_GLFWwindow *window)
void _glfwInputMouseClick(_GLFWwindow *window, int button, int action, int mods)
Definition: input.c:318
void _glfwPlatformSetWindowDecorated(_GLFWwindow *window, GLFWbool enabled)
GLFWbool _glfwInitEGL(void)
Definition: egl_context.c:300
static GLFWbool cursorInClientArea(_GLFWwindow *window)
Definition: win32_window.c:322
void _glfwPlatformPollEvents(void)
#define GLFW_KEY_RIGHT_SHIFT
Definition: glfw3.h:477
#define FALSE
Definition: tinycthread.c:53
void _glfwPlatformSetCursor(_GLFWwindow *window, _GLFWcursor *cursor)
void _glfwPlatformGetWindowFrameSize(_GLFWwindow *window, int *left, int *top, int *right, int *bottom)
GLboolean * data
double virtualCursorPosX
Definition: internal.h:392
_GLFWwindow * window
Definition: internal.h:431
#define GLFW_PRESS
The key or mouse button was pressed.
Definition: glfw3.h:304
#define _glfwIsWindows10AnniversaryUpdateOrGreaterWin32()
_GLFWmonitor * monitor
Definition: internal.h:378
void _glfwPlatformGetFramebufferSize(_GLFWwindow *window, int *width, int *height)
void _glfwUpdateKeyNamesWin32(void)
Definition: win32_init.c:461
void _glfwInputDrop(_GLFWwindow *window, int count, const char **paths)
Definition: input.c:360
GLFWbool decorated
Definition: internal.h:371
static void SetWindowPos(ImGuiWindow *window, const ImVec2 &pos, ImGuiSetCond cond)
Definition: imgui.cpp:4799
static int getKeyMods(void)
Definition: win32_window.c:422
auto device
Definition: pyrs_net.cpp:17
static void acquireMonitor(_GLFWwindow *window)
Definition: win32_window.c:527
struct GLFWwindow GLFWwindow
GLint GLsizei width
int _glfwPlatformWindowMaximized(_GLFWwindow *window)
#define GetDpiForWindow
const char * _glfwPlatformGetScancodeName(int scancode)
#define GLFW_MOD_NUM_LOCK
If this bit is set the Num Lock key is enabled.
Definition: glfw3.h:526
#define GLFW_MOUSE_BUTTON_4
Definition: glfw3.h:540
void _glfwPlatformSetClipboardString(const char *string)
static double ypos
Definition: splitview.c:33
#define GLFW_NO_API
Definition: glfw3.h:989
GLFWAPI HWND glfwGetWin32Window(GLFWwindow *handle)
static void disableCursor(_GLFWwindow *window)
Definition: win32_window.c:281
#define _GLFW_WNDCLASSNAME
GLdouble GLdouble bottom


librealsense2
Author(s): Sergey Dorodnicov , Doron Hirshberg , Mark Horn , Reagan Lopez , Itay Carpis
autogenerated on Mon May 3 2021 02:50:23