Wise&mystical  1.0
Project about Europe
Loading...
Searching...
No Matches
win32_window.c
Go to the documentation of this file.
1//========================================================================
2// GLFW 3.4 Win32 - www.glfw.org
3//------------------------------------------------------------------------
4// Copyright (c) 2002-2006 Marcus Geelnard
5// Copyright (c) 2006-2019 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// Please use C89 style variable declarations in this file because VS 2010
28//========================================================================
29
30#include "internal.h"
31
32#include <limits.h>
33#include <stdlib.h>
34#include <malloc.h>
35#include <string.h>
36#include <windowsx.h>
37#include <shellapi.h>
38
39// Returns the window style for the specified window
40//
41static 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//
67static 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//
79static 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//
101static 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 content area size to full window size according to styles and DPI
190//
191static void getFullWindowSize(DWORD style, DWORD exStyle,
192 int contentWidth, int contentHeight,
193 int* fullWidth, int* fullHeight,
194 UINT dpi)
195{
196 RECT rect = { 0, 0, contentWidth, contentHeight };
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 content area aspect ratio based on which edge is being dragged
208//
209static 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
218 getFullWindowSize(getWindowStyle(window), getWindowExStyle(window),
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// Updates the cursor image according to its cursor mode
240//
241static void updateCursorImage(_GLFWwindow* window)
242{
243 if (window->cursorMode == GLFW_CURSOR_NORMAL)
244 {
245 if (window->cursor)
246 SetCursor(window->cursor->win32.handle);
247 else
248 SetCursor(LoadCursorW(NULL, IDC_ARROW));
249 }
250 else
251 SetCursor(NULL);
252}
253
254// Updates the cursor clip rect
255//
256static void updateClipRect(_GLFWwindow* window)
257{
258 if (window)
259 {
260 RECT clipRect;
261 GetClientRect(window->win32.handle, &clipRect);
262 ClientToScreen(window->win32.handle, (POINT*) &clipRect.left);
263 ClientToScreen(window->win32.handle, (POINT*) &clipRect.right);
264 ClipCursor(&clipRect);
265 }
266 else
267 ClipCursor(NULL);
268}
269
270// Enables WM_INPUT messages for the mouse for the specified window
271//
272static void enableRawMouseMotion(_GLFWwindow* window)
273{
274 const RAWINPUTDEVICE rid = { 0x01, 0x02, 0, window->win32.handle };
275
276 if (!RegisterRawInputDevices(&rid, 1, sizeof(rid)))
277 {
279 "Win32: Failed to register raw input device");
280 }
281}
282
283// Disables WM_INPUT messages for the mouse
284//
285static void disableRawMouseMotion(_GLFWwindow* window)
286{
287 const RAWINPUTDEVICE rid = { 0x01, 0x02, RIDEV_REMOVE, NULL };
288
289 if (!RegisterRawInputDevices(&rid, 1, sizeof(rid)))
290 {
292 "Win32: Failed to remove raw input device");
293 }
294}
295
296// Apply disabled cursor mode to a focused window
297//
298static void disableCursor(_GLFWwindow* window)
299{
300 _glfw.win32.disabledCursorWindow = window;
302 &_glfw.win32.restoreCursorPosX,
303 &_glfw.win32.restoreCursorPosY);
304 updateCursorImage(window);
306 updateClipRect(window);
307
308 if (window->rawMouseMotion)
309 enableRawMouseMotion(window);
310}
311
312// Exit disabled cursor mode for the specified window
313//
314static void enableCursor(_GLFWwindow* window)
315{
316 if (window->rawMouseMotion)
317 disableRawMouseMotion(window);
318
319 _glfw.win32.disabledCursorWindow = NULL;
320 updateClipRect(NULL);
322 _glfw.win32.restoreCursorPosX,
323 _glfw.win32.restoreCursorPosY);
324 updateCursorImage(window);
325}
326
327// Returns whether the cursor is in the content area of the specified window
328//
329static GLFWbool cursorInContentArea(_GLFWwindow* window)
330{
331 RECT area;
332 POINT pos;
333
334 if (!GetCursorPos(&pos))
335 return GLFW_FALSE;
336
337 if (WindowFromPoint(pos) != window->win32.handle)
338 return GLFW_FALSE;
339
340 GetClientRect(window->win32.handle, &area);
341 ClientToScreen(window->win32.handle, (POINT*) &area.left);
342 ClientToScreen(window->win32.handle, (POINT*) &area.right);
343
344 return PtInRect(&area, pos);
345}
346
347// Update native window styles to match attributes
348//
349static void updateWindowStyles(const _GLFWwindow* window)
350{
351 RECT rect;
352 DWORD style = GetWindowLongW(window->win32.handle, GWL_STYLE);
353 style &= ~(WS_OVERLAPPEDWINDOW | WS_POPUP);
354 style |= getWindowStyle(window);
355
356 GetClientRect(window->win32.handle, &rect);
357
359 {
360 AdjustWindowRectExForDpi(&rect, style, FALSE,
361 getWindowExStyle(window),
362 GetDpiForWindow(window->win32.handle));
363 }
364 else
365 AdjustWindowRectEx(&rect, style, FALSE, getWindowExStyle(window));
366
367 ClientToScreen(window->win32.handle, (POINT*) &rect.left);
368 ClientToScreen(window->win32.handle, (POINT*) &rect.right);
369 SetWindowLongW(window->win32.handle, GWL_STYLE, style);
370 SetWindowPos(window->win32.handle, HWND_TOP,
371 rect.left, rect.top,
372 rect.right - rect.left, rect.bottom - rect.top,
373 SWP_FRAMECHANGED | SWP_NOACTIVATE | SWP_NOZORDER);
374}
375
376// Update window framebuffer transparency
377//
378static void updateFramebufferTransparency(const _GLFWwindow* window)
379{
380 BOOL composition, opaque;
381 DWORD color;
382
384 return;
385
386 if (FAILED(DwmIsCompositionEnabled(&composition)) || !composition)
387 return;
388
389 if (IsWindows8OrGreater() ||
390 (SUCCEEDED(DwmGetColorizationColor(&color, &opaque)) && !opaque))
391 {
392 HRGN region = CreateRectRgn(0, 0, -1, -1);
393 DWM_BLURBEHIND bb = {0};
395 bb.hRgnBlur = region;
396 bb.fEnable = TRUE;
397
398 DwmEnableBlurBehindWindow(window->win32.handle, &bb);
399 DeleteObject(region);
400 }
401 else
402 {
403 // HACK: Disable framebuffer transparency on Windows 7 when the
404 // colorization color is opaque, because otherwise the window
405 // contents is blended additively with the previous frame instead
406 // of replacing it
407 DWM_BLURBEHIND bb = {0};
409 DwmEnableBlurBehindWindow(window->win32.handle, &bb);
410 }
411}
412
413// Retrieves and translates modifier keys
414//
415static int getKeyMods(void)
416{
417 int mods = 0;
418
419 if (GetKeyState(VK_SHIFT) & 0x8000)
420 mods |= GLFW_MOD_SHIFT;
421 if (GetKeyState(VK_CONTROL) & 0x8000)
422 mods |= GLFW_MOD_CONTROL;
423 if (GetKeyState(VK_MENU) & 0x8000)
424 mods |= GLFW_MOD_ALT;
425 if ((GetKeyState(VK_LWIN) | GetKeyState(VK_RWIN)) & 0x8000)
426 mods |= GLFW_MOD_SUPER;
427 if (GetKeyState(VK_CAPITAL) & 1)
428 mods |= GLFW_MOD_CAPS_LOCK;
429 if (GetKeyState(VK_NUMLOCK) & 1)
430 mods |= GLFW_MOD_NUM_LOCK;
431
432 return mods;
433}
434
435static void fitToMonitor(_GLFWwindow* window)
436{
437 MONITORINFO mi = { sizeof(mi) };
438 GetMonitorInfo(window->monitor->win32.handle, &mi);
439 SetWindowPos(window->win32.handle, HWND_TOPMOST,
440 mi.rcMonitor.left,
441 mi.rcMonitor.top,
442 mi.rcMonitor.right - mi.rcMonitor.left,
443 mi.rcMonitor.bottom - mi.rcMonitor.top,
444 SWP_NOZORDER | SWP_NOACTIVATE | SWP_NOCOPYBITS);
445}
446
447// Make the specified window and its video mode active on its monitor
448//
449static void acquireMonitor(_GLFWwindow* window)
450{
451 if (!_glfw.win32.acquiredMonitorCount)
452 {
453 SetThreadExecutionState(ES_CONTINUOUS | ES_DISPLAY_REQUIRED);
454
455 // HACK: When mouse trails are enabled the cursor becomes invisible when
456 // the OpenGL ICD switches to page flipping
457 SystemParametersInfo(SPI_GETMOUSETRAILS, 0, &_glfw.win32.mouseTrailSize, 0);
458 SystemParametersInfo(SPI_SETMOUSETRAILS, 0, 0, 0);
459 }
460
461 if (!window->monitor->window)
462 _glfw.win32.acquiredMonitorCount++;
463
464 _glfwSetVideoModeWin32(window->monitor, &window->videoMode);
465 _glfwInputMonitorWindow(window->monitor, window);
466}
467
468// Remove the window and restore the original video mode
469//
470static void releaseMonitor(_GLFWwindow* window)
471{
472 if (window->monitor->window != window)
473 return;
474
475 _glfw.win32.acquiredMonitorCount--;
476 if (!_glfw.win32.acquiredMonitorCount)
477 {
478 SetThreadExecutionState(ES_CONTINUOUS);
479
480 // HACK: Restore mouse trail length saved in acquireMonitor
481 SystemParametersInfo(SPI_SETMOUSETRAILS, _glfw.win32.mouseTrailSize, 0, 0);
482 }
483
486}
487
488// Window callback function (handles window messages)
489//
490static LRESULT CALLBACK windowProc(HWND hWnd, UINT uMsg,
491 WPARAM wParam, LPARAM lParam)
492{
493 _GLFWwindow* window = GetPropW(hWnd, L"GLFW");
494 if (!window)
495 {
496 // This is the message handling for the hidden helper window
497 // and for a regular window during its initial creation
498
499 switch (uMsg)
500 {
501 case WM_NCCREATE:
502 {
504 {
505 const CREATESTRUCTW* cs = (const CREATESTRUCTW*) lParam;
506 const _GLFWwndconfig* wndconfig = cs->lpCreateParams;
507
508 // On per-monitor DPI aware V1 systems, only enable
509 // non-client scaling for windows that scale the client area
510 // We need WM_GETDPISCALEDSIZE from V2 to keep the client
511 // area static when the non-client area is scaled
512 if (wndconfig && wndconfig->scaleToMonitor)
514 }
515
516 break;
517 }
518
519 case WM_DISPLAYCHANGE:
521 break;
522
523 case WM_DEVICECHANGE:
524 {
526 break;
527
528 if (wParam == DBT_DEVICEARRIVAL)
529 {
530 DEV_BROADCAST_HDR* dbh = (DEV_BROADCAST_HDR*) lParam;
531 if (dbh && dbh->dbch_devicetype == DBT_DEVTYP_DEVICEINTERFACE)
533 }
534 else if (wParam == DBT_DEVICEREMOVECOMPLETE)
535 {
536 DEV_BROADCAST_HDR* dbh = (DEV_BROADCAST_HDR*) lParam;
537 if (dbh && dbh->dbch_devicetype == DBT_DEVTYP_DEVICEINTERFACE)
539 }
540
541 break;
542 }
543 }
544
545 return DefWindowProcW(hWnd, uMsg, wParam, lParam);
546 }
547
548 switch (uMsg)
549 {
550 case WM_MOUSEACTIVATE:
551 {
552 // HACK: Postpone cursor disabling when the window was activated by
553 // clicking a caption button
554 if (HIWORD(lParam) == WM_LBUTTONDOWN)
555 {
556 if (LOWORD(lParam) != HTCLIENT)
557 window->win32.frameAction = GLFW_TRUE;
558 }
559
560 break;
561 }
562
563 case WM_CAPTURECHANGED:
564 {
565 // HACK: Disable the cursor once the caption button action has been
566 // completed or cancelled
567 if (lParam == 0 && window->win32.frameAction)
568 {
569 if (window->cursorMode == GLFW_CURSOR_DISABLED)
570 disableCursor(window);
571
572 window->win32.frameAction = GLFW_FALSE;
573 }
574
575 break;
576 }
577
578 case WM_SETFOCUS:
579 {
581
582 // HACK: Do not disable cursor while the user is interacting with
583 // a caption button
584 if (window->win32.frameAction)
585 break;
586
587 if (window->cursorMode == GLFW_CURSOR_DISABLED)
588 disableCursor(window);
589
590 return 0;
591 }
592
593 case WM_KILLFOCUS:
594 {
595 if (window->cursorMode == GLFW_CURSOR_DISABLED)
596 enableCursor(window);
597
598 if (window->monitor && window->autoIconify)
600
602 return 0;
603 }
604
605 case WM_SYSCOMMAND:
606 {
607 switch (wParam & 0xfff0)
608 {
609 case SC_SCREENSAVE:
610 case SC_MONITORPOWER:
611 {
612 if (window->monitor)
613 {
614 // We are running in full screen mode, so disallow
615 // screen saver and screen blanking
616 return 0;
617 }
618 else
619 break;
620 }
621
622 // User trying to access application menu using ALT?
623 case SC_KEYMENU:
624 {
625 if (!window->win32.keymenu)
626 return 0;
627
628 break;
629 }
630 }
631 break;
632 }
633
634 case WM_CLOSE:
635 {
637 return 0;
638 }
639
640 case WM_INPUTLANGCHANGE:
641 {
643 break;
644 }
645
646 case WM_CHAR:
647 case WM_SYSCHAR:
648 {
649 if (wParam >= 0xd800 && wParam <= 0xdbff)
650 window->win32.highSurrogate = (WCHAR) wParam;
651 else
652 {
653 unsigned int codepoint = 0;
654
655 if (wParam >= 0xdc00 && wParam <= 0xdfff)
656 {
657 if (window->win32.highSurrogate)
658 {
659 codepoint += (window->win32.highSurrogate - 0xd800) << 10;
660 codepoint += (WCHAR) wParam - 0xdc00;
661 codepoint += 0x10000;
662 }
663 }
664 else
665 codepoint = (WCHAR) wParam;
666
667 window->win32.highSurrogate = 0;
668 _glfwInputChar(window, codepoint, getKeyMods(), uMsg != WM_SYSCHAR);
669 }
670
671 if (uMsg == WM_SYSCHAR && window->win32.keymenu)
672 break;
673
674 return 0;
675 }
676
677 case WM_UNICHAR:
678 {
679 if (wParam == UNICODE_NOCHAR)
680 {
681 // WM_UNICHAR is not sent by Windows, but is sent by some
682 // third-party input method engine
683 // Returning TRUE here announces support for this message
684 return TRUE;
685 }
686
687 _glfwInputChar(window, (unsigned int) wParam, getKeyMods(), GLFW_TRUE);
688 return 0;
689 }
690
691 case WM_KEYDOWN:
692 case WM_SYSKEYDOWN:
693 case WM_KEYUP:
694 case WM_SYSKEYUP:
695 {
696 int key, scancode;
697 const int action = (HIWORD(lParam) & KF_UP) ? GLFW_RELEASE : GLFW_PRESS;
698 const int mods = getKeyMods();
699
700 scancode = (HIWORD(lParam) & (KF_EXTENDED | 0xff));
701 if (!scancode)
702 {
703 // NOTE: Some synthetic key messages have a scancode of zero
704 // HACK: Map the virtual key back to a usable scancode
705 scancode = MapVirtualKeyW((UINT) wParam, MAPVK_VK_TO_VSC);
706 }
707
708 key = _glfw.win32.keycodes[scancode];
709
710 // The Ctrl keys require special handling
711 if (wParam == VK_CONTROL)
712 {
713 if (HIWORD(lParam) & KF_EXTENDED)
714 {
715 // Right side keys have the extended key bit set
717 }
718 else
719 {
720 // NOTE: Alt Gr sends Left Ctrl followed by Right Alt
721 // HACK: We only want one event for Alt Gr, so if we detect
722 // this sequence we discard this Left Ctrl message now
723 // and later report Right Alt normally
724 MSG next;
725 const DWORD time = GetMessageTime();
726
727 if (PeekMessageW(&next, NULL, 0, 0, PM_NOREMOVE))
728 {
729 if (next.message == WM_KEYDOWN ||
730 next.message == WM_SYSKEYDOWN ||
731 next.message == WM_KEYUP ||
732 next.message == WM_SYSKEYUP)
733 {
734 if (next.wParam == VK_MENU &&
735 (HIWORD(next.lParam) & KF_EXTENDED) &&
736 next.time == time)
737 {
738 // Next message is Right Alt down so discard this
739 break;
740 }
741 }
742 }
743
744 // This is a regular Left Ctrl message
746 }
747 }
748 else if (wParam == VK_PROCESSKEY)
749 {
750 // IME notifies that keys have been filtered by setting the
751 // virtual key-code to VK_PROCESSKEY
752 break;
753 }
754
755 if (action == GLFW_RELEASE && wParam == VK_SHIFT)
756 {
757 // HACK: Release both Shift keys on Shift up event, as when both
758 // are pressed the first release does not emit any event
759 // NOTE: The other half of this is in _glfwPlatformPollEvents
760 _glfwInputKey(window, GLFW_KEY_LEFT_SHIFT, scancode, action, mods);
761 _glfwInputKey(window, GLFW_KEY_RIGHT_SHIFT, scancode, action, mods);
762 }
763 else if (wParam == VK_SNAPSHOT)
764 {
765 // HACK: Key down is not reported for the Print Screen key
766 _glfwInputKey(window, key, scancode, GLFW_PRESS, mods);
767 _glfwInputKey(window, key, scancode, GLFW_RELEASE, mods);
768 }
769 else
770 _glfwInputKey(window, key, scancode, action, mods);
771
772 break;
773 }
774
775 case WM_LBUTTONDOWN:
776 case WM_RBUTTONDOWN:
777 case WM_MBUTTONDOWN:
778 case WM_XBUTTONDOWN:
779 case WM_LBUTTONUP:
780 case WM_RBUTTONUP:
781 case WM_MBUTTONUP:
782 case WM_XBUTTONUP:
783 {
784 int i, button, action;
785
786 if (uMsg == WM_LBUTTONDOWN || uMsg == WM_LBUTTONUP)
787 button = GLFW_MOUSE_BUTTON_LEFT;
788 else if (uMsg == WM_RBUTTONDOWN || uMsg == WM_RBUTTONUP)
790 else if (uMsg == WM_MBUTTONDOWN || uMsg == WM_MBUTTONUP)
792 else if (GET_XBUTTON_WPARAM(wParam) == XBUTTON1)
793 button = GLFW_MOUSE_BUTTON_4;
794 else
795 button = GLFW_MOUSE_BUTTON_5;
796
797 if (uMsg == WM_LBUTTONDOWN || uMsg == WM_RBUTTONDOWN ||
798 uMsg == WM_MBUTTONDOWN || uMsg == WM_XBUTTONDOWN)
799 {
800 action = GLFW_PRESS;
801 }
802 else
803 action = GLFW_RELEASE;
804
805 for (i = 0; i <= GLFW_MOUSE_BUTTON_LAST; i++)
806 {
807 if (window->mouseButtons[i] == GLFW_PRESS)
808 break;
809 }
810
812 SetCapture(hWnd);
813
814 _glfwInputMouseClick(window, button, action, getKeyMods());
815
816 for (i = 0; i <= GLFW_MOUSE_BUTTON_LAST; i++)
817 {
818 if (window->mouseButtons[i] == GLFW_PRESS)
819 break;
820 }
821
823 ReleaseCapture();
824
825 if (uMsg == WM_XBUTTONDOWN || uMsg == WM_XBUTTONUP)
826 return TRUE;
827
828 return 0;
829 }
830
831 case WM_MOUSEMOVE:
832 {
833 const int x = GET_X_LPARAM(lParam);
834 const int y = GET_Y_LPARAM(lParam);
835
836 if (!window->win32.cursorTracked)
837 {
838 TRACKMOUSEEVENT tme;
839 ZeroMemory(&tme, sizeof(tme));
840 tme.cbSize = sizeof(tme);
841 tme.dwFlags = TME_LEAVE;
842 tme.hwndTrack = window->win32.handle;
843 TrackMouseEvent(&tme);
844
845 window->win32.cursorTracked = GLFW_TRUE;
847 }
848
849 if (window->cursorMode == GLFW_CURSOR_DISABLED)
850 {
851 const int dx = x - window->win32.lastCursorPosX;
852 const int dy = y - window->win32.lastCursorPosY;
853
854 if (_glfw.win32.disabledCursorWindow != window)
855 break;
856 if (window->rawMouseMotion)
857 break;
858
859 _glfwInputCursorPos(window,
860 window->virtualCursorPosX + dx,
861 window->virtualCursorPosY + dy);
862 }
863 else
864 _glfwInputCursorPos(window, x, y);
865
866 window->win32.lastCursorPosX = x;
867 window->win32.lastCursorPosY = y;
868
869 return 0;
870 }
871
872 case WM_INPUT:
873 {
874 UINT size = 0;
875 HRAWINPUT ri = (HRAWINPUT) lParam;
876 RAWINPUT* data = NULL;
877 int dx, dy;
878
879 if (_glfw.win32.disabledCursorWindow != window)
880 break;
881 if (!window->rawMouseMotion)
882 break;
883
884 GetRawInputData(ri, RID_INPUT, NULL, &size, sizeof(RAWINPUTHEADER));
885 if (size > (UINT) _glfw.win32.rawInputSize)
886 {
887 free(_glfw.win32.rawInput);
888 _glfw.win32.rawInput = calloc(size, 1);
889 _glfw.win32.rawInputSize = size;
890 }
891
892 size = _glfw.win32.rawInputSize;
893 if (GetRawInputData(ri, RID_INPUT,
894 _glfw.win32.rawInput, &size,
895 sizeof(RAWINPUTHEADER)) == (UINT) -1)
896 {
898 "Win32: Failed to retrieve raw input data");
899 break;
900 }
901
902 data = _glfw.win32.rawInput;
903 if (data->data.mouse.usFlags & MOUSE_MOVE_ABSOLUTE)
904 {
905 dx = data->data.mouse.lLastX - window->win32.lastCursorPosX;
906 dy = data->data.mouse.lLastY - window->win32.lastCursorPosY;
907 }
908 else
909 {
910 dx = data->data.mouse.lLastX;
911 dy = data->data.mouse.lLastY;
912 }
913
914 _glfwInputCursorPos(window,
915 window->virtualCursorPosX + dx,
916 window->virtualCursorPosY + dy);
917
918 window->win32.lastCursorPosX += dx;
919 window->win32.lastCursorPosY += dy;
920 break;
921 }
922
923 case WM_MOUSELEAVE:
924 {
925 window->win32.cursorTracked = GLFW_FALSE;
927 return 0;
928 }
929
930 case WM_MOUSEWHEEL:
931 {
932 _glfwInputScroll(window, 0.0, (SHORT) HIWORD(wParam) / (double) WHEEL_DELTA);
933 return 0;
934 }
935
936 case WM_MOUSEHWHEEL:
937 {
938 // This message is only sent on Windows Vista and later
939 // NOTE: The X-axis is inverted for consistency with macOS and X11
940 _glfwInputScroll(window, -((SHORT) HIWORD(wParam) / (double) WHEEL_DELTA), 0.0);
941 return 0;
942 }
943
944 case WM_ENTERSIZEMOVE:
945 case WM_ENTERMENULOOP:
946 {
947 if (window->win32.frameAction)
948 break;
949
950 // HACK: Enable the cursor while the user is moving or
951 // resizing the window or using the window menu
952 if (window->cursorMode == GLFW_CURSOR_DISABLED)
953 enableCursor(window);
954
955 break;
956 }
957
958 case WM_EXITSIZEMOVE:
959 case WM_EXITMENULOOP:
960 {
961 if (window->win32.frameAction)
962 break;
963
964 // HACK: Disable the cursor once the user is done moving or
965 // resizing the window or using the menu
966 if (window->cursorMode == GLFW_CURSOR_DISABLED)
967 disableCursor(window);
968
969 break;
970 }
971
972 case WM_SIZE:
973 {
974 const int width = LOWORD(lParam);
975 const int height = HIWORD(lParam);
976 const GLFWbool iconified = wParam == SIZE_MINIMIZED;
977 const GLFWbool maximized = wParam == SIZE_MAXIMIZED ||
978 (window->win32.maximized &&
979 wParam != SIZE_RESTORED);
980
981 if (_glfw.win32.disabledCursorWindow == window)
982 updateClipRect(window);
983
984 if (window->win32.iconified != iconified)
985 _glfwInputWindowIconify(window, iconified);
986
987 if (window->win32.maximized != maximized)
988 _glfwInputWindowMaximize(window, maximized);
989
990 if (width != window->win32.width || height != window->win32.height)
991 {
992 window->win32.width = width;
993 window->win32.height = height;
994
995 _glfwInputFramebufferSize(window, width, height);
996 _glfwInputWindowSize(window, width, height);
997 }
998
999 if (window->monitor && window->win32.iconified != iconified)
1000 {
1001 if (iconified)
1002 releaseMonitor(window);
1003 else
1004 {
1005 acquireMonitor(window);
1006 fitToMonitor(window);
1007 }
1008 }
1009
1010 window->win32.iconified = iconified;
1011 window->win32.maximized = maximized;
1012 return 0;
1013 }
1014
1015 case WM_MOVE:
1016 {
1017 if (_glfw.win32.disabledCursorWindow == window)
1018 updateClipRect(window);
1019
1020 // NOTE: This cannot use LOWORD/HIWORD recommended by MSDN, as
1021 // those macros do not handle negative window positions correctly
1022 _glfwInputWindowPos(window,
1023 GET_X_LPARAM(lParam),
1024 GET_Y_LPARAM(lParam));
1025 return 0;
1026 }
1027
1028 case WM_SIZING:
1029 {
1030 if (window->numer == GLFW_DONT_CARE ||
1031 window->denom == GLFW_DONT_CARE)
1032 {
1033 break;
1034 }
1035
1036 applyAspectRatio(window, (int) wParam, (RECT*) lParam);
1037 return TRUE;
1038 }
1039
1040 case WM_GETMINMAXINFO:
1041 {
1042 int xoff, yoff;
1043 UINT dpi = USER_DEFAULT_SCREEN_DPI;
1044 MINMAXINFO* mmi = (MINMAXINFO*) lParam;
1045
1046 if (window->monitor)
1047 break;
1048
1050 dpi = GetDpiForWindow(window->win32.handle);
1051
1052 getFullWindowSize(getWindowStyle(window), getWindowExStyle(window),
1053 0, 0, &xoff, &yoff, dpi);
1054
1055 if (window->minwidth != GLFW_DONT_CARE &&
1056 window->minheight != GLFW_DONT_CARE)
1057 {
1058 mmi->ptMinTrackSize.x = window->minwidth + xoff;
1059 mmi->ptMinTrackSize.y = window->minheight + yoff;
1060 }
1061
1062 if (window->maxwidth != GLFW_DONT_CARE &&
1063 window->maxheight != GLFW_DONT_CARE)
1064 {
1065 mmi->ptMaxTrackSize.x = window->maxwidth + xoff;
1066 mmi->ptMaxTrackSize.y = window->maxheight + yoff;
1067 }
1068
1069 if (!window->decorated)
1070 {
1071 MONITORINFO mi;
1072 const HMONITOR mh = MonitorFromWindow(window->win32.handle,
1073 MONITOR_DEFAULTTONEAREST);
1074
1075 ZeroMemory(&mi, sizeof(mi));
1076 mi.cbSize = sizeof(mi);
1077 GetMonitorInfo(mh, &mi);
1078
1079 mmi->ptMaxPosition.x = mi.rcWork.left - mi.rcMonitor.left;
1080 mmi->ptMaxPosition.y = mi.rcWork.top - mi.rcMonitor.top;
1081 mmi->ptMaxSize.x = mi.rcWork.right - mi.rcWork.left;
1082 mmi->ptMaxSize.y = mi.rcWork.bottom - mi.rcWork.top;
1083 }
1084
1085 return 0;
1086 }
1087
1088 case WM_PAINT:
1089 {
1090 _glfwInputWindowDamage(window);
1091 break;
1092 }
1093
1094 case WM_ERASEBKGND:
1095 {
1096 return TRUE;
1097 }
1098
1099 case WM_NCACTIVATE:
1100 case WM_NCPAINT:
1101 {
1102 // Prevent title bar from being drawn after restoring a minimized
1103 // undecorated window
1104 if (!window->decorated)
1105 return TRUE;
1106
1107 break;
1108 }
1109
1112 {
1113 if (window->win32.transparent)
1114 updateFramebufferTransparency(window);
1115 return 0;
1116 }
1117
1119 {
1120 if (window->win32.scaleToMonitor)
1121 break;
1122
1123 // Adjust the window size to keep the content area size constant
1125 {
1126 RECT source = {0}, target = {0};
1127 SIZE* size = (SIZE*) lParam;
1128
1129 AdjustWindowRectExForDpi(&source, getWindowStyle(window),
1130 FALSE, getWindowExStyle(window),
1131 GetDpiForWindow(window->win32.handle));
1132 AdjustWindowRectExForDpi(&target, getWindowStyle(window),
1133 FALSE, getWindowExStyle(window),
1134 LOWORD(wParam));
1135
1136 size->cx += (target.right - target.left) -
1137 (source.right - source.left);
1138 size->cy += (target.bottom - target.top) -
1139 (source.bottom - source.top);
1140 return TRUE;
1141 }
1142
1143 break;
1144 }
1145
1146 case WM_DPICHANGED:
1147 {
1148 const float xscale = HIWORD(wParam) / (float) USER_DEFAULT_SCREEN_DPI;
1149 const float yscale = LOWORD(wParam) / (float) USER_DEFAULT_SCREEN_DPI;
1150
1151 // Resize windowed mode windows that either permit rescaling or that
1152 // need it to compensate for non-client area scaling
1153 if (!window->monitor &&
1154 (window->win32.scaleToMonitor ||
1156 {
1157 RECT* suggested = (RECT*) lParam;
1158 SetWindowPos(window->win32.handle, HWND_TOP,
1159 suggested->left,
1160 suggested->top,
1161 suggested->right - suggested->left,
1162 suggested->bottom - suggested->top,
1163 SWP_NOACTIVATE | SWP_NOZORDER);
1164 }
1165
1166 _glfwInputWindowContentScale(window, xscale, yscale);
1167 break;
1168 }
1169
1170 case WM_SETCURSOR:
1171 {
1172 if (LOWORD(lParam) == HTCLIENT)
1173 {
1174 updateCursorImage(window);
1175 return TRUE;
1176 }
1177
1178 break;
1179 }
1180
1181 case WM_DROPFILES:
1182 {
1183 HDROP drop = (HDROP) wParam;
1184 POINT pt;
1185 int i;
1186
1187 const int count = DragQueryFileW(drop, 0xffffffff, NULL, 0);
1188 char** paths = calloc(count, sizeof(char*));
1189
1190 // Move the mouse to the position of the drop
1191 DragQueryPoint(drop, &pt);
1192 _glfwInputCursorPos(window, pt.x, pt.y);
1193
1194 for (i = 0; i < count; i++)
1195 {
1196 const UINT length = DragQueryFileW(drop, i, NULL, 0);
1197 WCHAR* buffer = calloc((size_t) length + 1, sizeof(WCHAR));
1198
1199 DragQueryFileW(drop, i, buffer, length + 1);
1200 paths[i] = _glfwCreateUTF8FromWideStringWin32(buffer);
1201
1202 free(buffer);
1203 }
1204
1205 _glfwInputDrop(window, count, (const char**) paths);
1206
1207 for (i = 0; i < count; i++)
1208 free(paths[i]);
1209 free(paths);
1210
1211 DragFinish(drop);
1212 return 0;
1213 }
1214 }
1215
1216 return DefWindowProcW(hWnd, uMsg, wParam, lParam);
1217}
1218
1219// Creates the GLFW window
1220//
1221static int createNativeWindow(_GLFWwindow* window,
1222 const _GLFWwndconfig* wndconfig,
1223 const _GLFWfbconfig* fbconfig)
1224{
1225 int xpos, ypos, fullWidth, fullHeight;
1226 WCHAR* wideTitle;
1227 DWORD style = getWindowStyle(window);
1228 DWORD exStyle = getWindowExStyle(window);
1229
1230 if (window->monitor)
1231 {
1232 GLFWvidmode mode;
1233
1234 // NOTE: This window placement is temporary and approximate, as the
1235 // correct position and size cannot be known until the monitor
1236 // video mode has been picked in _glfwSetVideoModeWin32
1237 _glfwPlatformGetMonitorPos(window->monitor, &xpos, &ypos);
1238 _glfwPlatformGetVideoMode(window->monitor, &mode);
1239 fullWidth = mode.width;
1240 fullHeight = mode.height;
1241 }
1242 else
1243 {
1244 xpos = CW_USEDEFAULT;
1245 ypos = CW_USEDEFAULT;
1246
1247 window->win32.maximized = wndconfig->maximized;
1248 if (wndconfig->maximized)
1249 style |= WS_MAXIMIZE;
1250
1251 getFullWindowSize(style, exStyle,
1252 wndconfig->width, wndconfig->height,
1253 &fullWidth, &fullHeight,
1255 }
1256
1257 wideTitle = _glfwCreateWideStringFromUTF8Win32(wndconfig->title);
1258 if (!wideTitle)
1259 return GLFW_FALSE;
1260
1261 window->win32.handle = CreateWindowExW(exStyle,
1263 wideTitle,
1264 style,
1265 xpos, ypos,
1266 fullWidth, fullHeight,
1267 NULL, // No parent window
1268 NULL, // No window menu
1269 GetModuleHandleW(NULL),
1270 (LPVOID) wndconfig);
1271
1272 free(wideTitle);
1273
1274 if (!window->win32.handle)
1275 {
1277 "Win32: Failed to create window");
1278 return GLFW_FALSE;
1279 }
1280
1281 SetPropW(window->win32.handle, L"GLFW", window);
1282
1283 if (IsWindows7OrGreater())
1284 {
1285 ChangeWindowMessageFilterEx(window->win32.handle,
1286 WM_DROPFILES, MSGFLT_ALLOW, NULL);
1287 ChangeWindowMessageFilterEx(window->win32.handle,
1288 WM_COPYDATA, MSGFLT_ALLOW, NULL);
1289 ChangeWindowMessageFilterEx(window->win32.handle,
1291 }
1292
1293 window->win32.scaleToMonitor = wndconfig->scaleToMonitor;
1294 window->win32.keymenu = wndconfig->win32.keymenu;
1295
1296 // Adjust window rect to account for DPI scaling of the window frame and
1297 // (if enabled) DPI scaling of the content area
1298 // This cannot be done until we know what monitor the window was placed on
1299 if (!window->monitor)
1300 {
1301 RECT rect = { 0, 0, wndconfig->width, wndconfig->height };
1302 WINDOWPLACEMENT wp = { sizeof(wp) };
1303
1304 if (wndconfig->scaleToMonitor)
1305 {
1306 float xscale, yscale;
1307 _glfwPlatformGetWindowContentScale(window, &xscale, &yscale);
1308 rect.right = (int) (rect.right * xscale);
1309 rect.bottom = (int) (rect.bottom * yscale);
1310 }
1311
1312 ClientToScreen(window->win32.handle, (POINT*) &rect.left);
1313 ClientToScreen(window->win32.handle, (POINT*) &rect.right);
1314
1316 {
1317 AdjustWindowRectExForDpi(&rect, style, FALSE, exStyle,
1318 GetDpiForWindow(window->win32.handle));
1319 }
1320 else
1321 AdjustWindowRectEx(&rect, style, FALSE, exStyle);
1322
1323 // Only update the restored window rect as the window may be maximized
1324 GetWindowPlacement(window->win32.handle, &wp);
1325 wp.rcNormalPosition = rect;
1326 wp.showCmd = SW_HIDE;
1327 SetWindowPlacement(window->win32.handle, &wp);
1328 }
1329
1330 DragAcceptFiles(window->win32.handle, TRUE);
1331
1332 if (fbconfig->transparent)
1333 {
1334 updateFramebufferTransparency(window);
1335 window->win32.transparent = GLFW_TRUE;
1336 }
1337
1338 _glfwPlatformGetWindowSize(window, &window->win32.width, &window->win32.height);
1339
1340 return GLFW_TRUE;
1341}
1342
1343
1347
1348// Registers the GLFW window class
1349//
1351{
1352 WNDCLASSEXW wc;
1353
1354 ZeroMemory(&wc, sizeof(wc));
1355 wc.cbSize = sizeof(wc);
1356 wc.style = CS_HREDRAW | CS_VREDRAW | CS_OWNDC;
1357 wc.lpfnWndProc = (WNDPROC) windowProc;
1358 wc.hInstance = GetModuleHandleW(NULL);
1359 wc.hCursor = LoadCursorW(NULL, IDC_ARROW);
1360 wc.lpszClassName = _GLFW_WNDCLASSNAME;
1361
1362 // Load user-provided icon if available
1363 wc.hIcon = LoadImageW(GetModuleHandleW(NULL),
1364 L"GLFW_ICON", IMAGE_ICON,
1365 0, 0, LR_DEFAULTSIZE | LR_SHARED);
1366 if (!wc.hIcon)
1367 {
1368 // No user-provided icon found, load default icon
1369 wc.hIcon = LoadImageW(NULL,
1370 IDI_APPLICATION, IMAGE_ICON,
1371 0, 0, LR_DEFAULTSIZE | LR_SHARED);
1372 }
1373
1374 if (!RegisterClassExW(&wc))
1375 {
1377 "Win32: Failed to register window class");
1378 return GLFW_FALSE;
1379 }
1380
1381 return GLFW_TRUE;
1382}
1383
1384// Unregisters the GLFW window class
1385//
1387{
1388 UnregisterClassW(_GLFW_WNDCLASSNAME, GetModuleHandleW(NULL));
1389}
1390
1391
1395
1397 const _GLFWwndconfig* wndconfig,
1398 const _GLFWctxconfig* ctxconfig,
1399 const _GLFWfbconfig* fbconfig)
1400{
1401 if (!createNativeWindow(window, wndconfig, fbconfig))
1402 return GLFW_FALSE;
1403
1404 if (ctxconfig->client != GLFW_NO_API)
1405 {
1406 if (ctxconfig->source == GLFW_NATIVE_CONTEXT_API)
1407 {
1408 if (!_glfwInitWGL())
1409 return GLFW_FALSE;
1410 if (!_glfwCreateContextWGL(window, ctxconfig, fbconfig))
1411 return GLFW_FALSE;
1412 }
1413 else if (ctxconfig->source == GLFW_EGL_CONTEXT_API)
1414 {
1415 if (!_glfwInitEGL())
1416 return GLFW_FALSE;
1417 if (!_glfwCreateContextEGL(window, ctxconfig, fbconfig))
1418 return GLFW_FALSE;
1419 }
1420 else if (ctxconfig->source == GLFW_OSMESA_CONTEXT_API)
1421 {
1422 if (!_glfwInitOSMesa())
1423 return GLFW_FALSE;
1424 if (!_glfwCreateContextOSMesa(window, ctxconfig, fbconfig))
1425 return GLFW_FALSE;
1426 }
1427 }
1428
1429 if (window->monitor)
1430 {
1433 acquireMonitor(window);
1434 fitToMonitor(window);
1435 }
1436
1437 return GLFW_TRUE;
1438}
1439
1441{
1442 if (window->monitor)
1443 releaseMonitor(window);
1444
1445 if (window->context.destroy)
1446 window->context.destroy(window);
1447
1448 if (_glfw.win32.disabledCursorWindow == window)
1449 _glfw.win32.disabledCursorWindow = NULL;
1450
1451 if (window->win32.handle)
1452 {
1453 RemovePropW(window->win32.handle, L"GLFW");
1454 DestroyWindow(window->win32.handle);
1455 window->win32.handle = NULL;
1456 }
1457
1458 if (window->win32.bigIcon)
1459 DestroyIcon(window->win32.bigIcon);
1460
1461 if (window->win32.smallIcon)
1462 DestroyIcon(window->win32.smallIcon);
1463}
1464
1465void _glfwPlatformSetWindowTitle(_GLFWwindow* window, const char* title)
1466{
1467 WCHAR* wideTitle = _glfwCreateWideStringFromUTF8Win32(title);
1468 if (!wideTitle)
1469 return;
1470
1471 SetWindowTextW(window->win32.handle, wideTitle);
1472 free(wideTitle);
1473}
1474
1476 int count, const GLFWimage* images)
1477{
1478 HICON bigIcon = NULL, smallIcon = NULL;
1479
1480 if (count)
1481 {
1482 const GLFWimage* bigImage = chooseImage(count, images,
1483 GetSystemMetrics(SM_CXICON),
1484 GetSystemMetrics(SM_CYICON));
1485 const GLFWimage* smallImage = chooseImage(count, images,
1486 GetSystemMetrics(SM_CXSMICON),
1487 GetSystemMetrics(SM_CYSMICON));
1488
1489 bigIcon = createIcon(bigImage, 0, 0, GLFW_TRUE);
1490 smallIcon = createIcon(smallImage, 0, 0, GLFW_TRUE);
1491 }
1492 else
1493 {
1494 bigIcon = (HICON) GetClassLongPtrW(window->win32.handle, GCLP_HICON);
1495 smallIcon = (HICON) GetClassLongPtrW(window->win32.handle, GCLP_HICONSM);
1496 }
1497
1498 SendMessage(window->win32.handle, WM_SETICON, ICON_BIG, (LPARAM) bigIcon);
1499 SendMessage(window->win32.handle, WM_SETICON, ICON_SMALL, (LPARAM) smallIcon);
1500
1501 if (window->win32.bigIcon)
1502 DestroyIcon(window->win32.bigIcon);
1503
1504 if (window->win32.smallIcon)
1505 DestroyIcon(window->win32.smallIcon);
1506
1507 if (count)
1508 {
1509 window->win32.bigIcon = bigIcon;
1510 window->win32.smallIcon = smallIcon;
1511 }
1512}
1513
1514void _glfwPlatformGetWindowPos(_GLFWwindow* window, int* xpos, int* ypos)
1515{
1516 POINT pos = { 0, 0 };
1517 ClientToScreen(window->win32.handle, &pos);
1518
1519 if (xpos)
1520 *xpos = pos.x;
1521 if (ypos)
1522 *ypos = pos.y;
1523}
1524
1525void _glfwPlatformSetWindowPos(_GLFWwindow* window, int xpos, int ypos)
1526{
1527 RECT rect = { xpos, ypos, xpos, ypos };
1528
1530 {
1531 AdjustWindowRectExForDpi(&rect, getWindowStyle(window),
1532 FALSE, getWindowExStyle(window),
1533 GetDpiForWindow(window->win32.handle));
1534 }
1535 else
1536 {
1537 AdjustWindowRectEx(&rect, getWindowStyle(window),
1538 FALSE, getWindowExStyle(window));
1539 }
1540
1541 SetWindowPos(window->win32.handle, NULL, rect.left, rect.top, 0, 0,
1542 SWP_NOACTIVATE | SWP_NOZORDER | SWP_NOSIZE);
1543}
1544
1545void _glfwPlatformGetWindowSize(_GLFWwindow* window, int* width, int* height)
1546{
1547 RECT area;
1548 GetClientRect(window->win32.handle, &area);
1549
1550 if (width)
1551 *width = area.right;
1552 if (height)
1553 *height = area.bottom;
1554}
1555
1556void _glfwPlatformSetWindowSize(_GLFWwindow* window, int width, int height)
1557{
1558 if (window->monitor)
1559 {
1560 if (window->monitor->window == window)
1561 {
1562 acquireMonitor(window);
1563 fitToMonitor(window);
1564 }
1565 }
1566 else
1567 {
1568 RECT rect = { 0, 0, width, height };
1569
1571 {
1572 AdjustWindowRectExForDpi(&rect, getWindowStyle(window),
1573 FALSE, getWindowExStyle(window),
1574 GetDpiForWindow(window->win32.handle));
1575 }
1576 else
1577 {
1578 AdjustWindowRectEx(&rect, getWindowStyle(window),
1579 FALSE, getWindowExStyle(window));
1580 }
1581
1582 SetWindowPos(window->win32.handle, HWND_TOP,
1583 0, 0, rect.right - rect.left, rect.bottom - rect.top,
1584 SWP_NOACTIVATE | SWP_NOOWNERZORDER | SWP_NOMOVE | SWP_NOZORDER);
1585 }
1586}
1587
1589 int minwidth, int minheight,
1590 int maxwidth, int maxheight)
1591{
1592 RECT area;
1593
1594 if ((minwidth == GLFW_DONT_CARE || minheight == GLFW_DONT_CARE) &&
1595 (maxwidth == GLFW_DONT_CARE || maxheight == GLFW_DONT_CARE))
1596 {
1597 return;
1598 }
1599
1600 GetWindowRect(window->win32.handle, &area);
1601 MoveWindow(window->win32.handle,
1602 area.left, area.top,
1603 area.right - area.left,
1604 area.bottom - area.top, TRUE);
1605}
1606
1607void _glfwPlatformSetWindowAspectRatio(_GLFWwindow* window, int numer, int denom)
1608{
1609 RECT area;
1610
1611 if (numer == GLFW_DONT_CARE || denom == GLFW_DONT_CARE)
1612 return;
1613
1614 GetWindowRect(window->win32.handle, &area);
1615 applyAspectRatio(window, WMSZ_BOTTOMRIGHT, &area);
1616 MoveWindow(window->win32.handle,
1617 area.left, area.top,
1618 area.right - area.left,
1619 area.bottom - area.top, TRUE);
1620}
1621
1622void _glfwPlatformGetFramebufferSize(_GLFWwindow* window, int* width, int* height)
1623{
1624 _glfwPlatformGetWindowSize(window, width, height);
1625}
1626
1628 int* left, int* top,
1629 int* right, int* bottom)
1630{
1631 RECT rect;
1632 int width, height;
1633
1634 _glfwPlatformGetWindowSize(window, &width, &height);
1635 SetRect(&rect, 0, 0, width, height);
1636
1638 {
1639 AdjustWindowRectExForDpi(&rect, getWindowStyle(window),
1640 FALSE, getWindowExStyle(window),
1641 GetDpiForWindow(window->win32.handle));
1642 }
1643 else
1644 {
1645 AdjustWindowRectEx(&rect, getWindowStyle(window),
1646 FALSE, getWindowExStyle(window));
1647 }
1648
1649 if (left)
1650 *left = -rect.left;
1651 if (top)
1652 *top = -rect.top;
1653 if (right)
1654 *right = rect.right - width;
1655 if (bottom)
1656 *bottom = rect.bottom - height;
1657}
1658
1660 float* xscale, float* yscale)
1661{
1662 const HANDLE handle = MonitorFromWindow(window->win32.handle,
1663 MONITOR_DEFAULTTONEAREST);
1664 _glfwGetMonitorContentScaleWin32(handle, xscale, yscale);
1665}
1666
1668{
1669 ShowWindow(window->win32.handle, SW_MINIMIZE);
1670}
1671
1673{
1674 ShowWindow(window->win32.handle, SW_RESTORE);
1675}
1676
1678{
1679 ShowWindow(window->win32.handle, SW_MAXIMIZE);
1680}
1681
1683{
1684 ShowWindow(window->win32.handle, SW_SHOWNA);
1685}
1686
1688{
1689 ShowWindow(window->win32.handle, SW_HIDE);
1690}
1691
1693{
1694 FlashWindow(window->win32.handle, TRUE);
1695}
1696
1698{
1699 BringWindowToTop(window->win32.handle);
1700 SetForegroundWindow(window->win32.handle);
1701 SetFocus(window->win32.handle);
1702}
1703
1705 _GLFWmonitor* monitor,
1706 int xpos, int ypos,
1707 int width, int height,
1708 int refreshRate)
1709{
1710 if (window->monitor == monitor)
1711 {
1712 if (monitor)
1713 {
1714 if (monitor->window == window)
1715 {
1716 acquireMonitor(window);
1717 fitToMonitor(window);
1718 }
1719 }
1720 else
1721 {
1722 RECT rect = { xpos, ypos, xpos + width, ypos + height };
1723
1725 {
1726 AdjustWindowRectExForDpi(&rect, getWindowStyle(window),
1727 FALSE, getWindowExStyle(window),
1728 GetDpiForWindow(window->win32.handle));
1729 }
1730 else
1731 {
1732 AdjustWindowRectEx(&rect, getWindowStyle(window),
1733 FALSE, getWindowExStyle(window));
1734 }
1735
1736 SetWindowPos(window->win32.handle, HWND_TOP,
1737 rect.left, rect.top,
1738 rect.right - rect.left, rect.bottom - rect.top,
1739 SWP_NOCOPYBITS | SWP_NOACTIVATE | SWP_NOZORDER);
1740 }
1741
1742 return;
1743 }
1744
1745 if (window->monitor)
1746 releaseMonitor(window);
1747
1748 _glfwInputWindowMonitor(window, monitor);
1749
1750 if (window->monitor)
1751 {
1752 MONITORINFO mi = { sizeof(mi) };
1753 UINT flags = SWP_SHOWWINDOW | SWP_NOACTIVATE | SWP_NOCOPYBITS;
1754
1755 if (window->decorated)
1756 {
1757 DWORD style = GetWindowLongW(window->win32.handle, GWL_STYLE);
1758 style &= ~WS_OVERLAPPEDWINDOW;
1759 style |= getWindowStyle(window);
1760 SetWindowLongW(window->win32.handle, GWL_STYLE, style);
1761 flags |= SWP_FRAMECHANGED;
1762 }
1763
1764 acquireMonitor(window);
1765
1766 GetMonitorInfo(window->monitor->win32.handle, &mi);
1767 SetWindowPos(window->win32.handle, HWND_TOPMOST,
1768 mi.rcMonitor.left,
1769 mi.rcMonitor.top,
1770 mi.rcMonitor.right - mi.rcMonitor.left,
1771 mi.rcMonitor.bottom - mi.rcMonitor.top,
1772 flags);
1773 }
1774 else
1775 {
1776 HWND after;
1777 RECT rect = { xpos, ypos, xpos + width, ypos + height };
1778 DWORD style = GetWindowLongW(window->win32.handle, GWL_STYLE);
1779 UINT flags = SWP_NOACTIVATE | SWP_NOCOPYBITS;
1780
1781 if (window->decorated)
1782 {
1783 style &= ~WS_POPUP;
1784 style |= getWindowStyle(window);
1785 SetWindowLongW(window->win32.handle, GWL_STYLE, style);
1786
1787 flags |= SWP_FRAMECHANGED;
1788 }
1789
1790 if (window->floating)
1791 after = HWND_TOPMOST;
1792 else
1793 after = HWND_NOTOPMOST;
1794
1796 {
1797 AdjustWindowRectExForDpi(&rect, getWindowStyle(window),
1798 FALSE, getWindowExStyle(window),
1799 GetDpiForWindow(window->win32.handle));
1800 }
1801 else
1802 {
1803 AdjustWindowRectEx(&rect, getWindowStyle(window),
1804 FALSE, getWindowExStyle(window));
1805 }
1806
1807 SetWindowPos(window->win32.handle, after,
1808 rect.left, rect.top,
1809 rect.right - rect.left, rect.bottom - rect.top,
1810 flags);
1811 }
1812}
1813
1815{
1816 return window->win32.handle == GetActiveWindow();
1817}
1818
1820{
1821 return IsIconic(window->win32.handle);
1822}
1823
1825{
1826 return IsWindowVisible(window->win32.handle);
1827}
1828
1830{
1831 return IsZoomed(window->win32.handle);
1832}
1833
1835{
1836 return cursorInContentArea(window);
1837}
1838
1840{
1841 BOOL composition, opaque;
1842 DWORD color;
1843
1844 if (!window->win32.transparent)
1845 return GLFW_FALSE;
1846
1848 return GLFW_FALSE;
1849
1850 if (FAILED(DwmIsCompositionEnabled(&composition)) || !composition)
1851 return GLFW_FALSE;
1852
1853 if (!IsWindows8OrGreater())
1854 {
1855 // HACK: Disable framebuffer transparency on Windows 7 when the
1856 // colorization color is opaque, because otherwise the window
1857 // contents is blended additively with the previous frame instead
1858 // of replacing it
1859 if (FAILED(DwmGetColorizationColor(&color, &opaque)) || opaque)
1860 return GLFW_FALSE;
1861 }
1862
1863 return GLFW_TRUE;
1864}
1865
1867{
1868 updateWindowStyles(window);
1869}
1870
1872{
1873 updateWindowStyles(window);
1874}
1875
1877{
1878 const HWND after = enabled ? HWND_TOPMOST : HWND_NOTOPMOST;
1879 SetWindowPos(window->win32.handle, after, 0, 0, 0, 0,
1880 SWP_NOACTIVATE | SWP_NOMOVE | SWP_NOSIZE);
1881}
1882
1884{
1885 COLORREF key = 0;
1886 BYTE alpha = 0;
1887 DWORD flags = 0;
1888 DWORD exStyle = GetWindowLongW(window->win32.handle, GWL_EXSTYLE);
1889
1890 if (exStyle & WS_EX_LAYERED)
1891 GetLayeredWindowAttributes(window->win32.handle, &key, &alpha, &flags);
1892
1893 if (enabled)
1894 exStyle |= (WS_EX_TRANSPARENT | WS_EX_LAYERED);
1895 else
1896 {
1897 exStyle &= ~WS_EX_TRANSPARENT;
1898 // NOTE: Window opacity also needs the layered window style so do not
1899 // remove it if the window is alpha blended
1900 if (exStyle & WS_EX_LAYERED)
1901 {
1902 if (!(flags & LWA_ALPHA))
1903 exStyle &= ~WS_EX_LAYERED;
1904 }
1905 }
1906
1907 SetWindowLongW(window->win32.handle, GWL_EXSTYLE, exStyle);
1908
1909 if (enabled)
1910 SetLayeredWindowAttributes(window->win32.handle, key, alpha, flags);
1911}
1912
1914{
1915 BYTE alpha;
1916 DWORD flags;
1917
1918 if ((GetWindowLongW(window->win32.handle, GWL_EXSTYLE) & WS_EX_LAYERED) &&
1919 GetLayeredWindowAttributes(window->win32.handle, NULL, &alpha, &flags))
1920 {
1921 if (flags & LWA_ALPHA)
1922 return alpha / 255.f;
1923 }
1924
1925 return 1.f;
1926}
1927
1928void _glfwPlatformSetWindowOpacity(_GLFWwindow* window, float opacity)
1929{
1930 LONG exStyle = GetWindowLongW(window->win32.handle, GWL_EXSTYLE);
1931 if (opacity < 1.f || (exStyle & WS_EX_TRANSPARENT))
1932 {
1933 const BYTE alpha = (BYTE) (255 * opacity);
1934 exStyle |= WS_EX_LAYERED;
1935 SetWindowLongW(window->win32.handle, GWL_EXSTYLE, exStyle);
1936 SetLayeredWindowAttributes(window->win32.handle, 0, alpha, LWA_ALPHA);
1937 }
1938 else if (exStyle & WS_EX_TRANSPARENT)
1939 {
1940 SetLayeredWindowAttributes(window->win32.handle, 0, 0, 0);
1941 }
1942 else
1943 {
1944 exStyle &= ~WS_EX_LAYERED;
1945 SetWindowLongW(window->win32.handle, GWL_EXSTYLE, exStyle);
1946 }
1947}
1948
1950{
1951 if (_glfw.win32.disabledCursorWindow != window)
1952 return;
1953
1954 if (enabled)
1955 enableRawMouseMotion(window);
1956 else
1957 disableRawMouseMotion(window);
1958}
1959
1961{
1962 return GLFW_TRUE;
1963}
1964
1966{
1967 MSG msg;
1968 HWND handle;
1969 _GLFWwindow* window;
1970
1971 while (PeekMessageW(&msg, NULL, 0, 0, PM_REMOVE))
1972 {
1973 if (msg.message == WM_QUIT)
1974 {
1975 // NOTE: While GLFW does not itself post WM_QUIT, other processes
1976 // may post it to this one, for example Task Manager
1977 // HACK: Treat WM_QUIT as a close on all windows
1978
1979 window = _glfw.windowListHead;
1980 while (window)
1981 {
1983 window = window->next;
1984 }
1985 }
1986 else
1987 {
1988 TranslateMessage(&msg);
1989 DispatchMessageW(&msg);
1990 }
1991 }
1992
1993 // HACK: Release modifier keys that the system did not emit KEYUP for
1994 // NOTE: Shift keys on Windows tend to "stick" when both are pressed as
1995 // no key up message is generated by the first key release
1996 // NOTE: Windows key is not reported as released by the Win+V hotkey
1997 // Other Win hotkeys are handled implicitly by _glfwInputWindowFocus
1998 // because they change the input focus
1999 // NOTE: The other half of this is in the WM_*KEY* handler in windowProc
2000 handle = GetActiveWindow();
2001 if (handle)
2002 {
2003 window = GetPropW(handle, L"GLFW");
2004 if (window)
2005 {
2006 int i;
2007 const int keys[4][2] =
2008 {
2009 { VK_LSHIFT, GLFW_KEY_LEFT_SHIFT },
2010 { VK_RSHIFT, GLFW_KEY_RIGHT_SHIFT },
2011 { VK_LWIN, GLFW_KEY_LEFT_SUPER },
2012 { VK_RWIN, GLFW_KEY_RIGHT_SUPER }
2013 };
2014
2015 for (i = 0; i < 4; i++)
2016 {
2017 const int vk = keys[i][0];
2018 const int key = keys[i][1];
2019 const int scancode = _glfw.win32.scancodes[key];
2020
2021 if ((GetKeyState(vk) & 0x8000))
2022 continue;
2023 if (window->keys[key] != GLFW_PRESS)
2024 continue;
2025
2026 _glfwInputKey(window, key, scancode, GLFW_RELEASE, getKeyMods());
2027 }
2028 }
2029 }
2030
2031 window = _glfw.win32.disabledCursorWindow;
2032 if (window)
2033 {
2034 int width, height;
2035 _glfwPlatformGetWindowSize(window, &width, &height);
2036
2037 // NOTE: Re-center the cursor only if it has moved since the last call,
2038 // to avoid breaking glfwWaitEvents with WM_MOUSEMOVE
2039 if (window->win32.lastCursorPosX != width / 2 ||
2040 window->win32.lastCursorPosY != height / 2)
2041 {
2042 _glfwPlatformSetCursorPos(window, width / 2, height / 2);
2043 }
2044 }
2045}
2046
2048{
2049 WaitMessage();
2050
2052}
2053
2055{
2056 MsgWaitForMultipleObjects(0, NULL, FALSE, (DWORD) (timeout * 1e3), QS_ALLEVENTS);
2057
2059}
2060
2062{
2063 PostMessage(_glfw.win32.helperWindowHandle, WM_NULL, 0, 0);
2064}
2065
2066void _glfwPlatformGetCursorPos(_GLFWwindow* window, double* xpos, double* ypos)
2067{
2068 POINT pos;
2069
2070 if (GetCursorPos(&pos))
2071 {
2072 ScreenToClient(window->win32.handle, &pos);
2073
2074 if (xpos)
2075 *xpos = pos.x;
2076 if (ypos)
2077 *ypos = pos.y;
2078 }
2079}
2080
2081void _glfwPlatformSetCursorPos(_GLFWwindow* window, double xpos, double ypos)
2082{
2083 POINT pos = { (int) xpos, (int) ypos };
2084
2085 // Store the new position so it can be recognized later
2086 window->win32.lastCursorPosX = pos.x;
2087 window->win32.lastCursorPosY = pos.y;
2088
2089 ClientToScreen(window->win32.handle, &pos);
2090 SetCursorPos(pos.x, pos.y);
2091}
2092
2094{
2095 if (mode == GLFW_CURSOR_DISABLED)
2096 {
2097 if (_glfwPlatformWindowFocused(window))
2098 disableCursor(window);
2099 }
2100 else if (_glfw.win32.disabledCursorWindow == window)
2101 enableCursor(window);
2102 else if (cursorInContentArea(window))
2103 updateCursorImage(window);
2104}
2105
2106const char* _glfwPlatformGetScancodeName(int scancode)
2107{
2108 if (scancode < 0 || scancode > (KF_EXTENDED | 0xff) ||
2109 _glfw.win32.keycodes[scancode] == GLFW_KEY_UNKNOWN)
2110 {
2111 _glfwInputError(GLFW_INVALID_VALUE, "Invalid scancode");
2112 return NULL;
2113 }
2114
2115 return _glfw.win32.keynames[_glfw.win32.keycodes[scancode]];
2116}
2117
2119{
2120 return _glfw.win32.scancodes[key];
2121}
2122
2124 const GLFWimage* image,
2125 int xhot, int yhot)
2126{
2127 cursor->win32.handle = (HCURSOR) createIcon(image, xhot, yhot, GLFW_FALSE);
2128 if (!cursor->win32.handle)
2129 return GLFW_FALSE;
2130
2131 return GLFW_TRUE;
2132}
2133
2135{
2136 int id = 0;
2137
2138 switch (shape)
2139 {
2140 case GLFW_ARROW_CURSOR:
2141 id = OCR_NORMAL;
2142 break;
2143 case GLFW_IBEAM_CURSOR:
2144 id = OCR_IBEAM;
2145 break;
2147 id = OCR_CROSS;
2148 break;
2150 id = OCR_HAND;
2151 break;
2153 id = OCR_SIZEWE;
2154 break;
2156 id = OCR_SIZENS;
2157 break;
2159 id = OCR_SIZENWSE;
2160 break;
2162 id = OCR_SIZENESW;
2163 break;
2165 id = OCR_SIZEALL;
2166 break;
2168 id = OCR_NO;
2169 break;
2170 default:
2171 _glfwInputError(GLFW_PLATFORM_ERROR, "Win32: Unknown standard cursor");
2172 return GLFW_FALSE;
2173 }
2174
2175 cursor->win32.handle = LoadImageW(NULL,
2176 MAKEINTRESOURCEW(id), IMAGE_CURSOR, 0, 0,
2177 LR_DEFAULTSIZE | LR_SHARED);
2178 if (!cursor->win32.handle)
2179 {
2181 "Win32: Failed to create standard cursor");
2182 return GLFW_FALSE;
2183 }
2184
2185 return GLFW_TRUE;
2186}
2187
2189{
2190 if (cursor->win32.handle)
2191 DestroyIcon((HICON) cursor->win32.handle);
2192}
2193
2195{
2196 if (cursorInContentArea(window))
2197 updateCursorImage(window);
2198}
2199
2200void _glfwPlatformSetClipboardString(const char* string)
2201{
2202 int characterCount;
2203 HANDLE object;
2204 WCHAR* buffer;
2205
2206 characterCount = MultiByteToWideChar(CP_UTF8, 0, string, -1, NULL, 0);
2207 if (!characterCount)
2208 return;
2209
2210 object = GlobalAlloc(GMEM_MOVEABLE, characterCount * sizeof(WCHAR));
2211 if (!object)
2212 {
2214 "Win32: Failed to allocate global handle for clipboard");
2215 return;
2216 }
2217
2218 buffer = GlobalLock(object);
2219 if (!buffer)
2220 {
2222 "Win32: Failed to lock global handle");
2223 GlobalFree(object);
2224 return;
2225 }
2226
2227 MultiByteToWideChar(CP_UTF8, 0, string, -1, buffer, characterCount);
2228 GlobalUnlock(object);
2229
2230 if (!OpenClipboard(_glfw.win32.helperWindowHandle))
2231 {
2233 "Win32: Failed to open clipboard");
2234 GlobalFree(object);
2235 return;
2236 }
2237
2238 EmptyClipboard();
2239 SetClipboardData(CF_UNICODETEXT, object);
2240 CloseClipboard();
2241}
2242
2244{
2245 HANDLE object;
2246 WCHAR* buffer;
2247
2248 if (!OpenClipboard(_glfw.win32.helperWindowHandle))
2249 {
2251 "Win32: Failed to open clipboard");
2252 return NULL;
2253 }
2254
2255 object = GetClipboardData(CF_UNICODETEXT);
2256 if (!object)
2257 {
2259 "Win32: Failed to convert clipboard to string");
2260 CloseClipboard();
2261 return NULL;
2262 }
2263
2264 buffer = GlobalLock(object);
2265 if (!buffer)
2266 {
2268 "Win32: Failed to lock global handle");
2269 CloseClipboard();
2270 return NULL;
2271 }
2272
2273 free(_glfw.win32.clipboardString);
2274 _glfw.win32.clipboardString = _glfwCreateUTF8FromWideStringWin32(buffer);
2275
2276 GlobalUnlock(object);
2277 CloseClipboard();
2278
2279 return _glfw.win32.clipboardString;
2280}
2281
2283{
2285 {
2286 int type = 0;
2287
2289 {
2294 }
2295
2297 {
2302 }
2303
2305 {
2308 }
2309
2310 if (type)
2311 {
2312 *attribs = calloc(3, sizeof(EGLint));
2313 (*attribs)[0] = EGL_PLATFORM_ANGLE_TYPE_ANGLE;
2314 (*attribs)[1] = type;
2315 (*attribs)[2] = EGL_NONE;
2317 }
2318 }
2319
2320 return 0;
2321}
2322
2324{
2325 return GetDC(_glfw.win32.helperWindowHandle);
2326}
2327
2329{
2330 return window->win32.handle;
2331}
2332
2334{
2335 if (!_glfw.vk.KHR_surface || !_glfw.vk.KHR_win32_surface)
2336 return;
2337
2338 extensions[0] = "VK_KHR_surface";
2339 extensions[1] = "VK_KHR_win32_surface";
2340}
2341
2343 VkPhysicalDevice device,
2344 uint32_t queuefamily)
2345{
2347 vkGetPhysicalDeviceWin32PresentationSupportKHR =
2349 vkGetInstanceProcAddr(instance, "vkGetPhysicalDeviceWin32PresentationSupportKHR");
2350 if (!vkGetPhysicalDeviceWin32PresentationSupportKHR)
2351 {
2353 "Win32: Vulkan instance missing VK_KHR_win32_surface extension");
2354 return GLFW_FALSE;
2355 }
2356
2357 return vkGetPhysicalDeviceWin32PresentationSupportKHR(device, queuefamily);
2358}
2359
2361 _GLFWwindow* window,
2362 const VkAllocationCallbacks* allocator,
2363 VkSurfaceKHR* surface)
2364{
2365 VkResult err;
2367 PFN_vkCreateWin32SurfaceKHR vkCreateWin32SurfaceKHR;
2368
2369 vkCreateWin32SurfaceKHR = (PFN_vkCreateWin32SurfaceKHR)
2370 vkGetInstanceProcAddr(instance, "vkCreateWin32SurfaceKHR");
2371 if (!vkCreateWin32SurfaceKHR)
2372 {
2374 "Win32: Vulkan instance missing VK_KHR_win32_surface extension");
2376 }
2377
2378 memset(&sci, 0, sizeof(sci));
2380 sci.hinstance = GetModuleHandle(NULL);
2381 sci.hwnd = window->win32.handle;
2382
2383 err = vkCreateWin32SurfaceKHR(instance, &sci, allocator, surface);
2384 if (err)
2385 {
2387 "Win32: Failed to create Vulkan surface: %s",
2389 }
2390
2391 return err;
2392}
2393
2394
2398
2400{
2401 _GLFWwindow* window = (_GLFWwindow*) handle;
2403 return window->win32.handle;
2404}
2405
void _glfwPlatformGetVideoMode(_GLFWmonitor *monitor, GLFWvidmode *mode)
void _glfwPlatformGetMonitorPos(_GLFWmonitor *monitor, int *xpos, int *ypos)
GLFWbool _glfwInitEGL(void)
Definition: egl_context.c:303
GLFWbool _glfwCreateContextEGL(_GLFWwindow *window, const _GLFWctxconfig *ctxconfig, const _GLFWfbconfig *fbconfig)
Definition: egl_context.c:505
#define EGL_PLATFORM_ANGLE_TYPE_D3D9_ANGLE
Definition: egl_context.h:101
#define EGL_PLATFORM_ANGLE_TYPE_ANGLE
Definition: egl_context.h:98
unsigned int EGLenum
Definition: egl_context.h:109
#define EGL_PLATFORM_ANGLE_TYPE_OPENGL_ANGLE
Definition: egl_context.h:99
#define EGL_PLATFORM_ANGLE_TYPE_OPENGLES_ANGLE
Definition: egl_context.h:100
void * EGLNativeDisplayType
Definition: egl_context.h:115
#define EGL_NONE
Definition: egl_context.h:66
void * EGLNativeWindowType
Definition: egl_context.h:116
#define EGL_PLATFORM_ANGLE_TYPE_VULKAN_ANGLE
Definition: egl_context.h:103
int EGLint
Definition: egl_context.h:107
#define EGL_PLATFORM_ANGLE_TYPE_D3D11_ANGLE
Definition: egl_context.h:102
#define EGL_PLATFORM_ANGLE_ANGLE
Definition: egl_context.h:97
#define GLFW_ANGLE_PLATFORM_TYPE_OPENGLES
Definition: glfw3.h:1118
#define GLFW_EGL_CONTEXT_API
Definition: glfw3.h:1113
#define GLFW_NATIVE_CONTEXT_API
Definition: glfw3.h:1112
#define GLFW_CURSOR_DISABLED
Definition: glfw3.h:1106
#define GLFWAPI
Definition: glfw3.h:269
#define GLFW_ANGLE_PLATFORM_TYPE_VULKAN
Definition: glfw3.h:1121
#define GLFW_ANGLE_PLATFORM_TYPE_D3D9
Definition: glfw3.h:1119
#define GLFW_DONT_CARE
Definition: glfw3.h:1262
#define GLFW_NO_API
Definition: glfw3.h:1086
#define GLFW_ANGLE_PLATFORM_TYPE_D3D11
Definition: glfw3.h:1120
#define GLFW_ANGLE_PLATFORM_TYPE_OPENGL
Definition: glfw3.h:1117
#define GLFW_CURSOR_NORMAL
Definition: glfw3.h:1104
#define GLFW_OSMESA_CONTEXT_API
Definition: glfw3.h:1114
#define GLFW_MOUSE_BUTTON_MIDDLE
Definition: glfw3.h:580
#define GLFW_MOUSE_BUTTON_RIGHT
Definition: glfw3.h:579
#define GLFW_MOUSE_BUTTON_4
Definition: glfw3.h:572
#define GLFW_MOUSE_BUTTON_LAST
Definition: glfw3.h:577
#define GLFW_MOUSE_BUTTON_5
Definition: glfw3.h:573
#define GLFW_MOUSE_BUTTON_LEFT
Definition: glfw3.h:578
#define GLFW_FORMAT_UNAVAILABLE
The requested format is not supported or available.
Definition: glfw3.h:777
#define GLFW_API_UNAVAILABLE
GLFW could not find support for the requested API on the system.
Definition: glfw3.h:730
#define GLFW_INVALID_VALUE
One of the arguments to the function was an invalid value.
Definition: glfw3.h:706
#define GLFW_PLATFORM_ERROR
A platform-specific error occurred that does not match any of the more specific categories.
Definition: glfw3.h:758
#define GLFW_TRUE
One.
Definition: glfw3.h:310
#define GLFW_FALSE
Zero.
Definition: glfw3.h:319
#define GLFW_PRESS
The key or mouse button was pressed.
Definition: glfw3.h:336
#define GLFW_RELEASE
The key or mouse button was released.
Definition: glfw3.h:329
#define GLFW_KEY_LEFT_SHIFT
Definition: glfw3.h:505
#define GLFW_KEY_UNKNOWN
Definition: glfw3.h:389
#define GLFW_KEY_LEFT_CONTROL
Definition: glfw3.h:506
#define GLFW_KEY_RIGHT_CONTROL
Definition: glfw3.h:510
#define GLFW_KEY_RIGHT_SUPER
Definition: glfw3.h:512
#define GLFW_KEY_LEFT_SUPER
Definition: glfw3.h:508
#define GLFW_KEY_RIGHT_SHIFT
Definition: glfw3.h:509
#define GLFW_MOD_SHIFT
If this bit is set one or more Shift keys were held down.
Definition: glfw3.h:531
#define GLFW_MOD_NUM_LOCK
If this bit is set the Num Lock key is enabled.
Definition: glfw3.h:558
#define GLFW_MOD_SUPER
If this bit is set one or more Super keys were held down.
Definition: glfw3.h:546
#define GLFW_MOD_CONTROL
If this bit is set one or more Control keys were held down.
Definition: glfw3.h:536
#define GLFW_MOD_ALT
If this bit is set one or more Alt keys were held down.
Definition: glfw3.h:541
#define GLFW_MOD_CAPS_LOCK
If this bit is set the Caps Lock key is enabled.
Definition: glfw3.h:552
#define GLFW_RESIZE_EW_CURSOR
The horizontal resize/move arrow shape.
Definition: glfw3.h:1158
#define GLFW_NOT_ALLOWED_CURSOR
The operation-not-allowed shape.
Definition: glfw3.h:1212
#define GLFW_IBEAM_CURSOR
The text input I-beam cursor shape.
Definition: glfw3.h:1142
#define GLFW_RESIZE_ALL_CURSOR
The omni-directional resize/move cursor shape.
Definition: glfw3.h:1200
#define GLFW_ARROW_CURSOR
The regular arrow cursor shape.
Definition: glfw3.h:1137
#define GLFW_CROSSHAIR_CURSOR
The crosshair cursor shape.
Definition: glfw3.h:1147
#define GLFW_RESIZE_NS_CURSOR
The vertical resize/move arrow shape.
Definition: glfw3.h:1164
#define GLFW_POINTING_HAND_CURSOR
The pointing hand cursor shape.
Definition: glfw3.h:1152
#define GLFW_RESIZE_NESW_CURSOR
The top-right to bottom-left diagonal resize/move arrow shape.
Definition: glfw3.h:1194
#define GLFW_RESIZE_NWSE_CURSOR
The top-left to bottom-right diagonal resize/move arrow shape.
Definition: glfw3.h:1179
struct GLFWwindow GLFWwindow
Opaque window object.
Definition: glfw3.h:1319
_GLFWlibrary _glfw
Definition: init.c:46
void _glfwInputError(int code, const char *format,...)
Definition: init.c:160
void _glfwInputDrop(_GLFWwindow *window, int count, const char **paths)
Definition: input.c:378
void _glfwInputCursorEnter(_GLFWwindow *window, GLFWbool entered)
Definition: input.c:370
void _glfwInputScroll(_GLFWwindow *window, double xoffset, double yoffset)
Definition: input.c:328
void _glfwInputChar(_GLFWwindow *window, unsigned int codepoint, int mods, GLFWbool plain)
Definition: input.c:308
void _glfwInputCursorPos(_GLFWwindow *window, double xpos, double ypos)
Definition: input.c:356
void _glfwInputKey(_GLFWwindow *window, int key, int scancode, int action, int mods)
Definition: input.c:277
void _glfwCenterCursorInContentArea(_GLFWwindow *window)
Definition: input.c:475
void _glfwInputMouseClick(_GLFWwindow *window, int button, int action, int mods)
Definition: input.c:336
void _glfwInputMonitorWindow(_GLFWmonitor *monitor, _GLFWwindow *window)
Definition: monitor.c:155
uint64_t VkSurfaceKHR
Definition: internal.h:120
void _glfwInputFramebufferSize(_GLFWwindow *window, int width, int height)
Definition: window.c:108
void * VkInstance
Definition: internal.h:118
void _glfwInputWindowIconify(_GLFWwindow *window, GLFWbool iconified)
Definition: window.c:91
void _glfwInputWindowMaximize(_GLFWwindow *window, GLFWbool maximized)
Definition: window.c:99
void _glfwInputWindowSize(_GLFWwindow *window, int width, int height)
Definition: window.c:83
void _glfwInputWindowMonitor(_GLFWwindow *window, _GLFWmonitor *monitor)
Definition: window.c:143
#define _GLFW_REQUIRE_INIT_OR_RETURN(x)
Definition: internal.h:214
void _glfwInputWindowPos(_GLFWwindow *window, int xpos, int ypos)
Definition: window.c:74
void * VkPhysicalDevice
Definition: internal.h:119
const char * _glfwGetVulkanResultString(VkResult result)
Definition: vulkan.c:165
void _glfwInputWindowContentScale(_GLFWwindow *window, float xscale, float yscale)
Definition: window.c:117
int GLFWbool
Definition: internal.h:61
void _glfwInputWindowDamage(_GLFWwindow *window)
Definition: window.c:125
void _glfwInputWindowCloseRequest(_GLFWwindow *window)
Definition: window.c:133
void _glfwInputWindowFocus(_GLFWwindow *window, GLFWbool focused)
Definition: window.c:45
@ VK_STRUCTURE_TYPE_WIN32_SURFACE_CREATE_INFO_KHR
Definition: internal.h:129
#define NULL
Definition: miniaudio.h:3718
GLFWbool _glfwCreateContextOSMesa(_GLFWwindow *window, const _GLFWctxconfig *ctxconfig, const _GLFWfbconfig *fbconfig)
GLFWbool _glfwInitOSMesa(void)
unsigned int uint32_t
Definition: stdint.h:80
_GLFWdestroycontextfun destroy
Definition: internal.h:365
GLFWbool transparent
Definition: internal.h:340
GLFWbool ANGLE_platform_angle_d3d
Definition: egl_context.h:189
GLFWbool ANGLE_platform_angle
Definition: egl_context.h:187
GLFWbool ANGLE_platform_angle_vulkan
Definition: egl_context.h:190
GLFWbool ANGLE_platform_angle_opengl
Definition: egl_context.h:188
_GLFWlibraryEGL egl
Definition: internal.h:595
struct _GLFWlibrary::@25 vk
GLFWbool KHR_surface
Definition: internal.h:569
_GLFWwindow * windowListHead
Definition: internal.h:541
_GLFWinitconfig init
Definition: internal.h:532
GLFWbool joysticksInitialized
Definition: internal.h:546
struct _GLFWlibrary::@23 hints
_GLFWwindow * window
Definition: internal.h:446
int minwidth
Definition: internal.h:395
int minheight
Definition: internal.h:395
GLFWvidmode videoMode
Definition: internal.h:391
int cursorMode
Definition: internal.h:402
char mouseButtons[GLFW_MOUSE_BUTTON_LAST+1]
Definition: internal.h:403
double virtualCursorPosY
Definition: internal.h:406
_GLFWmonitor * monitor
Definition: internal.h:392
GLFWbool resizable
Definition: internal.h:382
double virtualCursorPosX
Definition: internal.h:406
struct _GLFWwindow * next
Definition: internal.h:379
int maxheight
Definition: internal.h:396
GLFWbool decorated
Definition: internal.h:383
int maxwidth
Definition: internal.h:396
GLFWbool rawMouseMotion
Definition: internal.h:407
GLFWbool autoIconify
Definition: internal.h:384
GLFWbool floating
Definition: internal.h:385
char keys[GLFW_KEY_LAST+1]
Definition: internal.h:404
_GLFWcursor * cursor
Definition: internal.h:393
_GLFWcontext context
Definition: internal.h:409
GLFWbool scaleToMonitor
Definition: internal.h:277
GLFWbool keymenu
Definition: internal.h:287
const char * title
Definition: internal.h:266
struct _GLFWwndconfig::@20 win32
GLFWbool maximized
Definition: internal.h:273
Image data.
Definition: glfw3.h:1855
int height
Definition: glfw3.h:1861
unsigned char * pixels
Definition: glfw3.h:1864
int width
Definition: glfw3.h:1858
Video mode type.
Definition: glfw3.h:1792
int width
Definition: glfw3.h:1795
int height
Definition: glfw3.h:1798
VkResult
Definition: vulkan.h:842
@ VK_ERROR_EXTENSION_NOT_PRESENT
Definition: vulkan.h:855
#define vkGetInstanceProcAddr
Definition: vulkan.h:3378
GLFWbool _glfwCreateContextWGL(_GLFWwindow *window, const _GLFWctxconfig *ctxconfig, const _GLFWfbconfig *fbconfig)
Definition: wgl_context.c:545
GLFWbool _glfwInitWGL(void)
Definition: wgl_context.c:410
void _glfwInputErrorWin32(int error, const char *description)
Definition: win32_init.c:451
WCHAR * _glfwCreateWideStringFromUTF8Win32(const char *source)
Definition: win32_init.c:395
char * _glfwCreateUTF8FromWideStringWin32(const WCHAR *source)
Definition: win32_init.c:423
void _glfwUpdateKeyNamesWin32(void)
Definition: win32_init.c:472
void _glfwDetectJoystickDisconnectionWin32(void)
void _glfwDetectJoystickConnectionWin32(void)
void _glfwPollMonitorsWin32(void)
void _glfwSetVideoModeWin32(_GLFWmonitor *monitor, const GLFWvidmode *desired)
void _glfwGetMonitorContentScaleWin32(HMONITOR handle, float *xscale, float *yscale)
void _glfwRestoreVideoModeWin32(_GLFWmonitor *monitor)
#define WM_COPYGLOBALDATA
#define AdjustWindowRectExForDpi
#define IsWindows8OrGreater()
#define DWM_BB_BLURREGION
#define _glfwIsWindows10AnniversaryUpdateOrGreaterWin32()
#define WM_GETDPISCALEDSIZE
#define WM_UNICHAR
#define IsWindowsVistaOrGreater()
#define WM_DPICHANGED
#define UNICODE_NOCHAR
#define MSGFLT_ALLOW
#define DwmGetColorizationColor
#define EnableNonClientDpiScaling
#define DwmEnableBlurBehindWindow
#define WM_DWMCOMPOSITIONCHANGED
#define WM_MOUSEHWHEEL
#define _glfwIsWindows10CreatorsUpdateOrGreaterWin32()
#define ChangeWindowMessageFilterEx
#define IsWindows7OrGreater()
VkBool32(APIENTRY * PFN_vkGetPhysicalDeviceWin32PresentationSupportKHR)(VkPhysicalDevice, uint32_t)
#define OCR_HAND
#define GET_XBUTTON_WPARAM(w)
VkResult(APIENTRY * PFN_vkCreateWin32SurfaceKHR)(VkInstance, const VkWin32SurfaceCreateInfoKHR *, const VkAllocationCallbacks *, VkSurfaceKHR *)
#define USER_DEFAULT_SCREEN_DPI
#define GetDpiForWindow
#define DwmIsCompositionEnabled
#define WM_DWMCOLORIZATIONCOLORCHANGED
#define _GLFW_WNDCLASSNAME
#define DWM_BB_ENABLE
void _glfwPlatformSetWindowMonitor(_GLFWwindow *window, _GLFWmonitor *monitor, int xpos, int ypos, int width, int height, int refreshRate)
void _glfwPlatformSetWindowPos(_GLFWwindow *window, int xpos, int ypos)
void _glfwPlatformGetWindowContentScale(_GLFWwindow *window, float *xscale, float *yscale)
void _glfwPlatformSetWindowResizable(_GLFWwindow *window, GLFWbool enabled)
int _glfwPlatformWindowIconified(_GLFWwindow *window)
void _glfwPlatformMaximizeWindow(_GLFWwindow *window)
EGLenum _glfwPlatformGetEGLPlatform(EGLint **attribs)
void _glfwPlatformIconifyWindow(_GLFWwindow *window)
void _glfwPlatformSetWindowSize(_GLFWwindow *window, int width, int height)
void _glfwPlatformWaitEvents(void)
void _glfwPlatformSetWindowSizeLimits(_GLFWwindow *window, int minwidth, int minheight, int maxwidth, int maxheight)
void _glfwPlatformGetRequiredInstanceExtensions(char **extensions)
VkResult _glfwPlatformCreateWindowSurface(VkInstance instance, _GLFWwindow *window, const VkAllocationCallbacks *allocator, VkSurfaceKHR *surface)
int _glfwPlatformFramebufferTransparent(_GLFWwindow *window)
int _glfwPlatformCreateCursor(_GLFWcursor *cursor, const GLFWimage *image, int xhot, int yhot)
void _glfwPlatformPollEvents(void)
void _glfwPlatformGetFramebufferSize(_GLFWwindow *window, int *width, int *height)
int _glfwPlatformWindowVisible(_GLFWwindow *window)
GLFWbool _glfwRegisterWindowClassWin32(void)
void _glfwPlatformSetCursor(_GLFWwindow *window, _GLFWcursor *cursor)
void _glfwPlatformGetWindowSize(_GLFWwindow *window, int *width, int *height)
void _glfwPlatformGetWindowFrameSize(_GLFWwindow *window, int *left, int *top, int *right, int *bottom)
void _glfwPlatformSetWindowIcon(_GLFWwindow *window, int count, const GLFWimage *images)
EGLNativeWindowType _glfwPlatformGetEGLNativeWindow(_GLFWwindow *window)
const char * _glfwPlatformGetScancodeName(int scancode)
void _glfwPlatformSetWindowDecorated(_GLFWwindow *window, GLFWbool enabled)
void _glfwPlatformGetWindowPos(_GLFWwindow *window, int *xpos, int *ypos)
void _glfwPlatformSetWindowOpacity(_GLFWwindow *window, float opacity)
void _glfwPlatformSetCursorPos(_GLFWwindow *window, double xpos, double ypos)
float _glfwPlatformGetWindowOpacity(_GLFWwindow *window)
void _glfwPlatformDestroyCursor(_GLFWcursor *cursor)
GLFWAPI HWND glfwGetWin32Window(GLFWwindow *handle)
void _glfwPlatformRestoreWindow(_GLFWwindow *window)
void _glfwUnregisterWindowClassWin32(void)
GLFWbool _glfwPlatformRawMouseMotionSupported(void)
void _glfwPlatformSetCursorMode(_GLFWwindow *window, int mode)
int _glfwPlatformWindowHovered(_GLFWwindow *window)
void _glfwPlatformDestroyWindow(_GLFWwindow *window)
void _glfwPlatformWaitEventsTimeout(double timeout)
void _glfwPlatformHideWindow(_GLFWwindow *window)
int _glfwPlatformGetPhysicalDevicePresentationSupport(VkInstance instance, VkPhysicalDevice device, uint32_t queuefamily)
int _glfwPlatformWindowMaximized(_GLFWwindow *window)
void _glfwPlatformSetClipboardString(const char *string)
void _glfwPlatformShowWindow(_GLFWwindow *window)
void _glfwPlatformSetRawMouseMotion(_GLFWwindow *window, GLFWbool enabled)
int _glfwPlatformWindowFocused(_GLFWwindow *window)
void _glfwPlatformPostEmptyEvent(void)
int _glfwPlatformGetKeyScancode(int key)
int _glfwPlatformCreateStandardCursor(_GLFWcursor *cursor, int shape)
int _glfwPlatformCreateWindow(_GLFWwindow *window, const _GLFWwndconfig *wndconfig, const _GLFWctxconfig *ctxconfig, const _GLFWfbconfig *fbconfig)
void _glfwPlatformSetWindowAspectRatio(_GLFWwindow *window, int numer, int denom)
const char * _glfwPlatformGetClipboardString(void)
void _glfwPlatformGetCursorPos(_GLFWwindow *window, double *xpos, double *ypos)
void _glfwPlatformRequestWindowAttention(_GLFWwindow *window)
EGLNativeDisplayType _glfwPlatformGetEGLNativeDisplay(void)
void _glfwPlatformSetWindowTitle(_GLFWwindow *window, const char *title)
void _glfwPlatformFocusWindow(_GLFWwindow *window)
void _glfwPlatformSetWindowMousePassthrough(_GLFWwindow *window, GLFWbool enabled)
void _glfwPlatformSetWindowFloating(_GLFWwindow *window, GLFWbool enabled)