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 // We don't need all the fancy stuff
29 #ifndef NOMINMAX
30  #define NOMINMAX
31 #endif
32 
33 #ifndef VC_EXTRALEAN
34  #define VC_EXTRALEAN
35 #endif
36 
37 #ifndef WIN32_LEAN_AND_MEAN
38  #define WIN32_LEAN_AND_MEAN
39 #endif
40 
41 // This is a workaround for the fact that glfw3.h needs to export APIENTRY (for
42 // example to allow applications to correctly declare a GL_ARB_debug_output
43 // callback) but windows.h assumes no one will define APIENTRY before it does
44 #undef APIENTRY
45 
46 // GLFW on Windows is Unicode only and does not work in MBCS mode
47 #ifndef UNICODE
48  #define UNICODE
49 #endif
50 
51 // GLFW requires Windows XP or later
52 #if WINVER < 0x0501
53  #undef WINVER
54  #define WINVER 0x0501
55 #endif
56 #if _WIN32_WINNT < 0x0501
57  #undef _WIN32_WINNT
58  #define _WIN32_WINNT 0x0501
59 #endif
60 
61 // GLFW uses DirectInput8 interfaces
62 #define DIRECTINPUT_VERSION 0x0800
63 
64 #include <wctype.h>
65 #include <windows.h>
66 #include <dinput.h>
67 #include <xinput.h>
68 #include <dbt.h>
69 
70 // HACK: Define macros that some windows.h variants don't
71 #ifndef WM_MOUSEHWHEEL
72  #define WM_MOUSEHWHEEL 0x020E
73 #endif
74 #ifndef WM_DWMCOMPOSITIONCHANGED
75  #define WM_DWMCOMPOSITIONCHANGED 0x031E
76 #endif
77 #ifndef WM_COPYGLOBALDATA
78  #define WM_COPYGLOBALDATA 0x0049
79 #endif
80 #ifndef WM_UNICHAR
81  #define WM_UNICHAR 0x0109
82 #endif
83 #ifndef UNICODE_NOCHAR
84  #define UNICODE_NOCHAR 0xFFFF
85 #endif
86 #ifndef WM_DPICHANGED
87  #define WM_DPICHANGED 0x02E0
88 #endif
89 #ifndef GET_XBUTTON_WPARAM
90  #define GET_XBUTTON_WPARAM(w) (HIWORD(w))
91 #endif
92 #ifndef EDS_ROTATEDMODE
93  #define EDS_ROTATEDMODE 0x00000004
94 #endif
95 #ifndef DISPLAY_DEVICE_ACTIVE
96  #define DISPLAY_DEVICE_ACTIVE 0x00000001
97 #endif
98 #ifndef _WIN32_WINNT_WINBLUE
99  #define _WIN32_WINNT_WINBLUE 0x0602
100 #endif
101 #ifndef WM_GETDPISCALEDSIZE
102  #define WM_GETDPISCALEDSIZE 0x02e4
103 #endif
104 #ifndef USER_DEFAULT_SCREEN_DPI
105  #define USER_DEFAULT_SCREEN_DPI 96
106 #endif
107 
108 #if WINVER < 0x0601
109 typedef struct
110 {
111     DWORD cbSize;
112     DWORD ExtStatus;
113 } CHANGEFILTERSTRUCT;
114 #ifndef MSGFLT_ALLOW
115  #define MSGFLT_ALLOW 1
116 #endif
117 #endif /*Windows 7*/
118 
119 #if WINVER < 0x0600
120 #define DWM_BB_ENABLE 0x00000001
121 #define DWM_BB_BLURREGION 0x00000002
122 typedef struct
123 {
124     DWORD dwFlags;
125     BOOL fEnable;
126     HRGN hRgnBlur;
127     BOOL fTransitionOnMaximized;
128 } DWM_BLURBEHIND;
129 #else
130  #include <dwmapi.h>
131 #endif /*Windows Vista*/
132 
133 #ifndef DPI_ENUMS_DECLARED
134 typedef enum
135 {
136     PROCESS_DPI_UNAWARE = 0,
137     PROCESS_SYSTEM_DPI_AWARE = 1,
138     PROCESS_PER_MONITOR_DPI_AWARE = 2
139 } PROCESS_DPI_AWARENESS;
140 typedef enum
141 {
142     MDT_EFFECTIVE_DPI = 0,
143     MDT_ANGULAR_DPI = 1,
144     MDT_RAW_DPI = 2,
145     MDT_DEFAULT = MDT_EFFECTIVE_DPI
146 } MONITOR_DPI_TYPE;
147 #endif /*DPI_ENUMS_DECLARED*/
148 
149 #ifndef DPI_AWARENESS_CONTEXT_PER_MONITOR_AWARE_V2
150 #define DPI_AWARENESS_CONTEXT_PER_MONITOR_AWARE_V2 ((HANDLE) -4)
151 #endif /*DPI_AWARENESS_CONTEXT_PER_MONITOR_AWARE_V2*/
152 
153 // HACK: Define versionhelpers.h functions manually as MinGW lacks the header
154 #define IsWindowsXPOrGreater()                                 \
155     _glfwIsWindowsVersionOrGreaterWin32(HIBYTE(_WIN32_WINNT_WINXP),   \
156                                         LOBYTE(_WIN32_WINNT_WINXP), 0)
157 #define IsWindowsVistaOrGreater()                                     \
158     _glfwIsWindowsVersionOrGreaterWin32(HIBYTE(_WIN32_WINNT_VISTA),   \
159                                         LOBYTE(_WIN32_WINNT_VISTA), 0)
160 #define IsWindows7OrGreater()                                         \
161     _glfwIsWindowsVersionOrGreaterWin32(HIBYTE(_WIN32_WINNT_WIN7),    \
162                                         LOBYTE(_WIN32_WINNT_WIN7), 0)
163 #define IsWindows8OrGreater()                                         \
164     _glfwIsWindowsVersionOrGreaterWin32(HIBYTE(_WIN32_WINNT_WIN8),    \
165                                         LOBYTE(_WIN32_WINNT_WIN8), 0)
166 #define IsWindows8Point1OrGreater()                                   \
167     _glfwIsWindowsVersionOrGreaterWin32(HIBYTE(_WIN32_WINNT_WINBLUE), \
168                                         LOBYTE(_WIN32_WINNT_WINBLUE), 0)
169 
170 #define _glfwIsWindows10AnniversaryUpdateOrGreaterWin32() \
171     _glfwIsWindows10BuildOrGreaterWin32(14393)
172 #define _glfwIsWindows10CreatorsUpdateOrGreaterWin32() \
173     _glfwIsWindows10BuildOrGreaterWin32(15063)
174 
175 // HACK: Define macros that some xinput.h variants don't
176 #ifndef XINPUT_CAPS_WIRELESS
177  #define XINPUT_CAPS_WIRELESS 0x0002
178 #endif
179 #ifndef XINPUT_DEVSUBTYPE_WHEEL
180  #define XINPUT_DEVSUBTYPE_WHEEL 0x02
181 #endif
182 #ifndef XINPUT_DEVSUBTYPE_ARCADE_STICK
183  #define XINPUT_DEVSUBTYPE_ARCADE_STICK 0x03
184 #endif
185 #ifndef XINPUT_DEVSUBTYPE_FLIGHT_STICK
186  #define XINPUT_DEVSUBTYPE_FLIGHT_STICK 0x04
187 #endif
188 #ifndef XINPUT_DEVSUBTYPE_DANCE_PAD
189  #define XINPUT_DEVSUBTYPE_DANCE_PAD 0x05
190 #endif
191 #ifndef XINPUT_DEVSUBTYPE_GUITAR
192  #define XINPUT_DEVSUBTYPE_GUITAR 0x06
193 #endif
194 #ifndef XINPUT_DEVSUBTYPE_DRUM_KIT
195  #define XINPUT_DEVSUBTYPE_DRUM_KIT 0x08
196 #endif
197 #ifndef XINPUT_DEVSUBTYPE_ARCADE_PAD
198  #define XINPUT_DEVSUBTYPE_ARCADE_PAD 0x13
199 #endif
200 #ifndef XUSER_MAX_COUNT
201  #define XUSER_MAX_COUNT 4
202 #endif
203 
204 // HACK: Define macros that some dinput.h variants don't
205 #ifndef DIDFT_OPTIONAL
206  #define DIDFT_OPTIONAL	0x80000000
207 #endif
208 
209 // winmm.dll function pointer typedefs
210 typedef DWORD (WINAPI * PFN_timeGetTime)(void);
211 #define timeGetTime _glfw.win32.winmm.GetTime
212 
213 // xinput.dll function pointer typedefs
214 typedef DWORD (WINAPI * PFN_XInputGetCapabilities)(DWORD,DWORD,XINPUT_CAPABILITIES*);
215 typedef DWORD (WINAPI * PFN_XInputGetState)(DWORD,XINPUT_STATE*);
216 #define XInputGetCapabilities _glfw.win32.xinput.GetCapabilities
217 #define XInputGetState _glfw.win32.xinput.GetState
218 
219 // dinput8.dll function pointer typedefs
220 typedef HRESULT (WINAPI * PFN_DirectInput8Create)(HINSTANCE,DWORD,REFIID,LPVOID*,LPUNKNOWN);
221 #define DirectInput8Create _glfw.win32.dinput8.Create
222 
223 // user32.dll function pointer typedefs
224 typedef BOOL (WINAPI * PFN_SetProcessDPIAware)(void);
225 typedef BOOL (WINAPI * PFN_ChangeWindowMessageFilterEx)(HWND,UINT,DWORD,CHANGEFILTERSTRUCT*);
226 typedef BOOL (WINAPI * PFN_EnableNonClientDpiScaling)(HWND);
227 typedef BOOL (WINAPI * PFN_SetProcessDpiAwarenessContext)(HANDLE);
228 typedef UINT (WINAPI * PFN_GetDpiForWindow)(HWND);
229 typedef BOOL (WINAPI * PFN_AdjustWindowRectExForDpi)(LPRECT,DWORD,BOOL,DWORD,UINT);
230 #define SetProcessDPIAware _glfw.win32.user32.SetProcessDPIAware_
231 #define ChangeWindowMessageFilterEx _glfw.win32.user32.ChangeWindowMessageFilterEx_
232 #define EnableNonClientDpiScaling _glfw.win32.user32.EnableNonClientDpiScaling_
233 #define SetProcessDpiAwarenessContext _glfw.win32.user32.SetProcessDpiAwarenessContext_
234 #define GetDpiForWindow _glfw.win32.user32.GetDpiForWindow_
235 #define AdjustWindowRectExForDpi _glfw.win32.user32.AdjustWindowRectExForDpi_
236 
237 // dwmapi.dll function pointer typedefs
238 typedef HRESULT (WINAPI * PFN_DwmIsCompositionEnabled)(BOOL*);
239 typedef HRESULT (WINAPI * PFN_DwmFlush)(VOID);
240 typedef HRESULT(WINAPI * PFN_DwmEnableBlurBehindWindow)(HWND,const DWM_BLURBEHIND*);
241 #define DwmIsCompositionEnabled _glfw.win32.dwmapi.IsCompositionEnabled
242 #define DwmFlush _glfw.win32.dwmapi.Flush
243 #define DwmEnableBlurBehindWindow _glfw.win32.dwmapi.EnableBlurBehindWindow
244 
245 // shcore.dll function pointer typedefs
246 typedef HRESULT (WINAPI * PFN_SetProcessDpiAwareness)(PROCESS_DPI_AWARENESS);
247 typedef HRESULT (WINAPI * PFN_GetDpiForMonitor)(HMONITOR,MONITOR_DPI_TYPE,UINT*,UINT*);
248 #define SetProcessDpiAwareness _glfw.win32.shcore.SetProcessDpiAwareness_
249 #define GetDpiForMonitor _glfw.win32.shcore.GetDpiForMonitor_
250 
251 // ntdll.dll function pointer typedefs
252 typedef LONG (WINAPI * PFN_RtlVerifyVersionInfo)(OSVERSIONINFOEXW*,ULONG,ULONGLONG);
253 #define RtlVerifyVersionInfo _glfw.win32.ntdll.RtlVerifyVersionInfo_
254 
255 typedef VkFlags VkWin32SurfaceCreateFlagsKHR;
256 
257 typedef struct VkWin32SurfaceCreateInfoKHR
258 {
259     VkStructureType                 sType;
260     const void*                     pNext;
261     VkWin32SurfaceCreateFlagsKHR    flags;
262     HINSTANCE                       hinstance;
263     HWND                            hwnd;
264 } VkWin32SurfaceCreateInfoKHR;
265 
266 typedef VkResult (APIENTRY *PFN_vkCreateWin32SurfaceKHR)(VkInstance,const VkWin32SurfaceCreateInfoKHR*,const VkAllocationCallbacks*,VkSurfaceKHR*);
267 typedef VkBool32 (APIENTRY *PFN_vkGetPhysicalDeviceWin32PresentationSupportKHR)(VkPhysicalDevice,uint32_t);
268 
269 #include "win32_joystick.h"
270 #include "wgl_context.h"
271 #include "egl_context.h"
272 #include "osmesa_context.h"
273 
274 #if !defined(_GLFW_WNDCLASSNAME)
275  #define _GLFW_WNDCLASSNAME L"GLFW30"
276 #endif
277 
278 #define _glfw_dlopen(name) LoadLibraryA(name)
279 #define _glfw_dlclose(handle) FreeLibrary((HMODULE) handle)
280 #define _glfw_dlsym(handle, name) GetProcAddress((HMODULE) handle, name)
281 
282 #define _GLFW_EGL_NATIVE_WINDOW  ((EGLNativeWindowType) window->win32.handle)
283 #define _GLFW_EGL_NATIVE_DISPLAY EGL_DEFAULT_DISPLAY
284 
285 #define _GLFW_PLATFORM_WINDOW_STATE         _GLFWwindowWin32  win32
286 #define _GLFW_PLATFORM_LIBRARY_WINDOW_STATE _GLFWlibraryWin32 win32
287 #define _GLFW_PLATFORM_LIBRARY_TIMER_STATE  _GLFWtimerWin32   win32
288 #define _GLFW_PLATFORM_MONITOR_STATE        _GLFWmonitorWin32 win32
289 #define _GLFW_PLATFORM_CURSOR_STATE         _GLFWcursorWin32  win32
290 #define _GLFW_PLATFORM_TLS_STATE            _GLFWtlsWin32     win32
291 #define _GLFW_PLATFORM_MUTEX_STATE          _GLFWmutexWin32   win32
292 
293 
294 // Win32-specific per-window data
295 //
296 typedef struct _GLFWwindowWin32
297 {
298     HWND                handle;
299     HICON               bigIcon;
300     HICON               smallIcon;
301 
302     GLFWbool            cursorTracked;
303     GLFWbool            frameAction;
304     GLFWbool            iconified;
305     GLFWbool            maximized;
306     // Whether to enable framebuffer transparency on DWM
307     GLFWbool            transparent;
308     GLFWbool            scaleToMonitor;
309 
310     // The last received cursor position, regardless of source
311     int                 lastCursorPosX, lastCursorPosY;
312 
313 } _GLFWwindowWin32;
314 
315 // Win32-specific global data
316 //
317 typedef struct _GLFWlibraryWin32
318 {
319     HWND                helperWindowHandle;
320     HDEVNOTIFY          deviceNotificationHandle;
321     DWORD               foregroundLockTimeout;
322     int                 acquiredMonitorCount;
323     char*               clipboardString;
324     short int           keycodes[512];
325     short int           scancodes[GLFW_KEY_LAST + 1];
326     char                keynames[GLFW_KEY_LAST + 1][5];
327     // Where to place the cursor when re-enabled
328     double              restoreCursorPosX, restoreCursorPosY;
329     // The window whose disabled cursor mode is active
330     _GLFWwindow*        disabledCursorWindow;
331     RAWINPUT*           rawInput;
332     int                 rawInputSize;
333     UINT                mouseTrailSize;
334 
335     struct {
336         HINSTANCE                       instance;
337         PFN_timeGetTime                 GetTime;
338     } winmm;
339 
340     struct {
341         HINSTANCE                       instance;
342         PFN_DirectInput8Create          Create;
343         IDirectInput8W*                 api;
344     } dinput8;
345 
346     struct {
347         HINSTANCE                       instance;
348         PFN_XInputGetCapabilities       GetCapabilities;
349         PFN_XInputGetState              GetState;
350     } xinput;
351 
352     struct {
353         HINSTANCE                       instance;
354         PFN_SetProcessDPIAware          SetProcessDPIAware_;
355         PFN_ChangeWindowMessageFilterEx ChangeWindowMessageFilterEx_;
356         PFN_EnableNonClientDpiScaling   EnableNonClientDpiScaling_;
357         PFN_SetProcessDpiAwarenessContext SetProcessDpiAwarenessContext_;
358         PFN_GetDpiForWindow             GetDpiForWindow_;
359         PFN_AdjustWindowRectExForDpi    AdjustWindowRectExForDpi_;
360     } user32;
361 
362     struct {
363         HINSTANCE                       instance;
364         PFN_DwmIsCompositionEnabled     IsCompositionEnabled;
365         PFN_DwmFlush                    Flush;
366         PFN_DwmEnableBlurBehindWindow   EnableBlurBehindWindow;
367     } dwmapi;
368 
369     struct {
370         HINSTANCE                       instance;
371         PFN_SetProcessDpiAwareness      SetProcessDpiAwareness_;
372         PFN_GetDpiForMonitor            GetDpiForMonitor_;
373     } shcore;
374 
375     struct {
376         HINSTANCE                       instance;
377         PFN_RtlVerifyVersionInfo        RtlVerifyVersionInfo_;
378     } ntdll;
379 
380 } _GLFWlibraryWin32;
381 
382 // Win32-specific per-monitor data
383 //
384 typedef struct _GLFWmonitorWin32
385 {
386     HMONITOR            handle;
387     // This size matches the static size of DISPLAY_DEVICE.DeviceName
388     WCHAR               adapterName[32];
389     WCHAR               displayName[32];
390     char                publicAdapterName[32];
391     char                publicDisplayName[32];
392     GLFWbool            modesPruned;
393     GLFWbool            modeChanged;
394 
395 } _GLFWmonitorWin32;
396 
397 // Win32-specific per-cursor data
398 //
399 typedef struct _GLFWcursorWin32
400 {
401     HCURSOR             handle;
402 
403 } _GLFWcursorWin32;
404 
405 // Win32-specific global timer data
406 //
407 typedef struct _GLFWtimerWin32
408 {
409     GLFWbool            hasPC;
410     uint64_t            frequency;
411 
412 } _GLFWtimerWin32;
413 
414 // Win32-specific thread local storage data
415 //
416 typedef struct _GLFWtlsWin32
417 {
418     GLFWbool            allocated;
419     DWORD               index;
420 
421 } _GLFWtlsWin32;
422 
423 // Win32-specific mutex data
424 //
425 typedef struct _GLFWmutexWin32
426 {
427     GLFWbool            allocated;
428     CRITICAL_SECTION    section;
429 
430 } _GLFWmutexWin32;
431 
432 
433 GLFWbool _glfwRegisterWindowClassWin32(void);
434 void _glfwUnregisterWindowClassWin32(void);
435 
436 WCHAR* _glfwCreateWideStringFromUTF8Win32(const char* source);
437 char* _glfwCreateUTF8FromWideStringWin32(const WCHAR* source);
438 BOOL _glfwIsWindowsVersionOrGreaterWin32(WORD major, WORD minor, WORD sp);
439 BOOL _glfwIsWindows10BuildOrGreaterWin32(WORD build);
440 void _glfwInputErrorWin32(int error, const char* description);
441 void _glfwUpdateKeyNamesWin32(void);
442 
443 void _glfwInitTimerWin32(void);
444 
445 void _glfwPollMonitorsWin32(void);
446 void _glfwSetVideoModeWin32(_GLFWmonitor* monitor, const GLFWvidmode* desired);
447 void _glfwRestoreVideoModeWin32(_GLFWmonitor* monitor);
448 void _glfwGetMonitorContentScaleWin32(HMONITOR handle, float* xscale, float* yscale);
449 
450