1 /// Translated from C to D
2 module glfw3.win32_platform;
3 
4 extern(C): @nogc: nothrow: __gshared:
5 //========================================================================
6 // GLFW 3.3 Win32 - www.glfw.org
7 //------------------------------------------------------------------------
8 // Copyright (c) 2002-2006 Marcus Geelnard
9 // Copyright (c) 2006-2019 Camilla Löwy <elmindreda@glfw.org>
10 //
11 // This software is provided 'as-is', without any express or implied
12 // warranty. In no event will the authors be held liable for any damages
13 // arising from the use of this software.
14 //
15 // Permission is granted to anyone to use this software for any purpose,
16 // including commercial applications, and to alter it and redistribute it
17 // freely, subject to the following restrictions:
18 //
19 // 1. The origin of this software must not be misrepresented; you must not
20 //    claim that you wrote the original software. If you use this software
21 //    in a product, an acknowledgment in the product documentation would
22 //    be appreciated but is not required.
23 //
24 // 2. Altered source versions must be plainly marked as such, and must not
25 //    be misrepresented as being the original software.
26 //
27 // 3. This notice may not be removed or altered from any source
28 //    distribution.
29 //
30 //========================================================================
31 
32 // GLFW uses DirectInput8 interfaces
33 enum DIRECTINPUT_VERSION = 0x0800;
34 
35 public import core.stdc.wctype;
36 public import core.sys.windows.windows;
37 public import core.sys.windows.winuser;
38 public import glfw3.directinput8;
39 public import glfw3.xinput;
40 public import core.sys.windows.objbase; // GUID
41 public import core.sys.windows.dbt;
42 
43 package:
44 
45 // TODO: make this @nogc nothrow upstream
46 @nogc nothrow extern (Windows) ULONGLONG VerSetConditionMask(ULONGLONG, DWORD, BYTE);
47 
48 // HACK: Define macros that some windows.h variants don't
49 enum WM_MOUSEHWHEEL = 0x020E;
50 enum WM_DWMCOMPOSITIONCHANGED = 0x031E;
51 enum WM_COPYGLOBALDATA = 0x0049;
52 //enum UNICODE_NOCHAR = 0xFFFF;
53 enum WM_DPICHANGED = 0x02E0;
54 int GET_XBUTTON_WPARAM(ulong w) {return HIWORD(w);}
55 enum EDS_ROTATEDMODE = 0x00000004;
56 enum DISPLAY_DEVICE_ACTIVE = 0x00000001;
57 enum _WIN32_WINNT_WINBLUE = 0x0602;
58 enum _WIN32_WINNT_WIN8 = 0x0602;
59 enum WM_GETDPISCALEDSIZE = 0x02e4;
60 enum USER_DEFAULT_SCREEN_DPI = 96;
61 enum OCR_HAND = 32649;
62 
63 // WINVER < 0x0601
64 version(all) {
65     struct _CHANGEFILTERSTRUCT {
66         DWORD cbSize;
67         DWORD ExtStatus;
68     }
69     alias _CHANGEFILTERSTRUCT CHANGEFILTERSTRUCT;
70 
71     enum MSGFLT_ALLOW = 1;
72 } /*Windows 7*/
73 
74 // WINVER < 0x0600
75 version(all) {
76     enum DWM_BB_ENABLE = 0x00000001;
77     enum DWM_BB_BLURREGION = 0x00000002;
78     struct _DWM_BLURBEHIND {
79         DWORD dwFlags;
80         BOOL fEnable;
81         HRGN hRgnBlur;
82         BOOL fTransitionOnMaximized;
83     }
84     alias _DWM_BLURBEHIND DWM_BLURBEHIND;
85 } else {
86     //public import dwmapi;
87 }
88 
89 version (all) {
90     enum PROCESS_DPI_AWARENESS {
91         PROCESS_DPI_UNAWARE = 0,
92         PROCESS_SYSTEM_DPI_AWARE = 1,
93         PROCESS_PER_MONITOR_DPI_AWARE = 2
94     }
95     enum MONITOR_DPI_TYPE {
96         MDT_EFFECTIVE_DPI = 0,
97         MDT_ANGULAR_DPI = 1,
98         MDT_RAW_DPI = 2,
99         MDT_DEFAULT = MDT_EFFECTIVE_DPI
100     }
101 
102     enum DISP_CHANGE_BADDUALVIEW = -6;
103 }
104 
105 enum DPI_AWARENESS_CONTEXT_PER_MONITOR_AWARE_V2 = cast(HANDLE) -4;
106 
107 // HACK: Define versionhelpers.h functions manually as MinGW lacks the header
108 package {
109     enum _WIN32_WINNT_WINXP = 0x0501;
110     enum _WIN32_WINNT_VISTA = 0x0600;
111     enum _WIN32_WINNT_WIN7 = 0x0601;
112 
113     // note: already in core.sys.windows.winver, but not @nogc
114     bool IsWindowsXPOrGreater() {
115         return cast(bool) _glfwIsWindowsVersionOrGreaterWin32(HIBYTE(_WIN32_WINNT_WINXP),
116                                             LOBYTE(_WIN32_WINNT_WINXP), 0);
117     }
118     bool IsWindowsVistaOrGreater() {
119         return cast(bool) _glfwIsWindowsVersionOrGreaterWin32(HIBYTE(_WIN32_WINNT_VISTA),
120                                             LOBYTE(_WIN32_WINNT_VISTA), 0);
121     }
122     bool IsWindows7OrGreater() {
123         return cast(bool) _glfwIsWindowsVersionOrGreaterWin32(HIBYTE(_WIN32_WINNT_WIN7),
124                                             LOBYTE(_WIN32_WINNT_WIN7), 0);
125     }
126     bool IsWindows8OrGreater() {
127         return cast(bool) _glfwIsWindowsVersionOrGreaterWin32(HIBYTE(_WIN32_WINNT_WIN8),
128                                             LOBYTE(_WIN32_WINNT_WIN8), 0);
129     }
130     bool IsWindows8Point1OrGreater() {
131         return cast(bool) _glfwIsWindowsVersionOrGreaterWin32(HIBYTE(_WIN32_WINNT_WINBLUE),
132                                             LOBYTE(_WIN32_WINNT_WINBLUE), 0);
133     }
134 
135     bool _glfwIsWindows10AnniversaryUpdateOrGreaterWin32() {
136         return cast(bool) _glfwIsWindows10BuildOrGreaterWin32(14393);
137     }
138     bool _glfwIsWindows10CreatorsUpdateOrGreaterWin32() {
139         return cast(bool) _glfwIsWindows10BuildOrGreaterWin32(15063);
140     }
141 
142     auto GET_X_LPARAM(T)(T lp) {
143         import core.sys.windows.windef : LOWORD;
144         return (cast(int)cast(short)LOWORD(lp));
145     }
146     auto GET_Y_LPARAM(T)(T lp) {
147         import core.sys.windows.windef : HIWORD;
148         return (cast(int)cast(short)HIWORD(lp));
149     }
150 }
151 
152 // HACK: Define macros that some xinput.h variants don't
153 enum XINPUT_CAPS_WIRELESS = 0x0002;
154 enum XINPUT_DEVSUBTYPE_WHEEL = 0x02;
155 enum XINPUT_DEVSUBTYPE_ARCADE_STICK = 0x03;
156 enum XINPUT_DEVSUBTYPE_FLIGHT_STICK = 0x04;
157 enum XINPUT_DEVSUBTYPE_DANCE_PAD = 0x05;
158 enum XINPUT_DEVSUBTYPE_GUITAR = 0x06;
159 enum XINPUT_DEVSUBTYPE_DRUM_KIT = 0x08;
160 enum XINPUT_DEVSUBTYPE_ARCADE_PAD = 0x13;
161 enum XUSER_MAX_COUNT = 4;
162 
163 // HACK: Define macros that some dinput.h variants don't
164 enum DIDFT_OPTIONAL = 0x80000000;
165 
166 extern(Windows) {
167     // winmm.dll function pointer typedefs
168     alias PFN_timeGetTime = DWORD function();
169     enum timeGetTime = "_glfw.win32.winmm.GetTime";
170 
171     // xinput.dll function pointer typedefs
172     alias PFN_XInputGetCapabilities = DWORD function(DWORD,DWORD,XINPUT_CAPABILITIES*);
173     alias PFN_XInputGetState = DWORD function(DWORD,XINPUT_STATE*);
174     alias PFN_XInputSetState = DWORD function(DWORD,XINPUT_VIBRATION*);
175     enum XInputGetCapabilities = "_glfw.win32.xinput.GetCapabilities";
176     enum XInputGetState = "_glfw.win32.xinput.GetState";
177     enum XInputSetState = "_glfw.win32.xinput.SetState";
178 
179     // dinput8.dll function pointer typedefs
180     alias PFN_DirectInput8Create = HRESULT function(HINSTANCE,DWORD,REFIID,LPVOID*,LPUNKNOWN);
181     enum DirectInput8Create = "_glfw.win32.dinput8.Create";
182 
183     // user32.dll function pointer typedefs
184     alias PFN_SetProcessDPIAware = BOOL function();
185     alias PFN_ChangeWindowMessageFilterEx = BOOL function(HWND,UINT,DWORD,CHANGEFILTERSTRUCT*);
186     alias PFN_EnableNonClientDpiScaling = BOOL function(HWND);
187     alias PFN_SetProcessDpiAwarenessContext = BOOL function(HANDLE);
188     alias PFN_GetDpiForWindow = UINT function(HWND);
189     alias PFN_AdjustWindowRectExForDpi = BOOL function(LPRECT,DWORD,BOOL,DWORD,UINT);
190     enum SetProcessDPIAware = "_glfw.win32.user32.SetProcessDPIAware_";
191     enum ChangeWindowMessageFilterEx = "_glfw.win32.user32.ChangeWindowMessageFilterEx_";
192     enum EnableNonClientDpiScaling = "_glfw.win32.user32.EnableNonClientDpiScaling_";
193     enum SetProcessDpiAwarenessContext = "_glfw.win32.user32.SetProcessDpiAwarenessContext_";
194     enum GetDpiForWindow = "_glfw.win32.user32.GetDpiForWindow_";
195     enum AdjustWindowRectExForDpi = "_glfw.win32.user32.AdjustWindowRectExForDpi_";
196 
197     // dwmapi.dll function pointer typedefs
198     alias PFN_DwmIsCompositionEnabled = HRESULT  function(BOOL*);
199     alias PFN_DwmFlush = HRESULT function();
200     alias PFN_DwmEnableBlurBehindWindow = HRESULT function(HWND, const(DWM_BLURBEHIND)*);
201     enum DwmIsCompositionEnabled = "_glfw.win32.dwmapi.IsCompositionEnabled";
202     enum DwmFlush = "_glfw.win32.dwmapi.Flush";
203     enum DwmEnableBlurBehindWindow = "_glfw.win32.dwmapi.EnableBlurBehindWindow";
204 
205     // shcore.dll function pointer typedefs
206     alias PFN_SetProcessDpiAwareness = HRESULT function(PROCESS_DPI_AWARENESS);
207     alias PFN_GetDpiForMonitor = HRESULT function(HMONITOR,MONITOR_DPI_TYPE,UINT*,UINT*);
208     enum SetProcessDpiAwareness = "_glfw.win32.shcore.SetProcessDpiAwareness_";
209     enum GetDpiForMonitor = "_glfw.win32.shcore.GetDpiForMonitor_";
210 
211     // ntdll.dll function pointer typedefs
212     alias PFN_RtlVerifyVersionInfo = LONG function(OSVERSIONINFOEXW*,ULONG,ULONGLONG);
213     alias RtlVerifyVersionInfo = _glfw.win32.ntdll.RtlVerifyVersionInfo_;
214 }
215 
216 alias VkFlags VkWin32SurfaceCreateFlagsKHR;
217 
218 struct VkWin32SurfaceCreateInfoKHR {
219     VkStructureType sType;
220     const(void)* pNext;
221     VkWin32SurfaceCreateFlagsKHR flags;
222     HINSTANCE hinstance;
223     HWND hwnd;
224 }
225 
226 alias PFN_vkCreateWin32SurfaceKHR = VkResult function(VkInstance, const(VkWin32SurfaceCreateInfoKHR)*, const(VkAllocationCallbacks)*, VkSurfaceKHR*);
227 alias PFN_vkGetPhysicalDeviceWin32PresentationSupportKHR = VkBool32 function(VkPhysicalDevice, uint32_t);
228 
229 import glfw3.internal;
230 public import glfw3.win32_joystick;
231 public import glfw3.wgl_context;
232 public import glfw3.egl_context;
233 public import glfw3.osmesa_context;
234 
235 enum _GLFW_WNDCLASSNAME = "GLFW30"w;
236 
237 auto _glfw_dlopen(const(char)* name) { return LoadLibraryA(name); }
238 auto _glfw_dlclose(void* handle) { return FreeLibrary(cast(HMODULE) handle); }
239 auto _glfw_dlsym(void* handle, const(char)* name) { return GetProcAddress(cast(HMODULE) handle, name);}
240 
241 enum _GLFW_EGL_NATIVE_WINDOW = "cast(EGLNativeWindowType) window.win32.handle";
242 enum _GLFW_EGL_NATIVE_DISPLAY = EGL_DEFAULT_DISPLAY;
243 
244 mixin template _GLFW_PLATFORM_WINDOW_STATE() {        _GLFWwindowWin32  win32;}
245 mixin template _GLFW_PLATFORM_LIBRARY_WINDOW_STATE() {_GLFWlibraryWin32 win32;}
246 mixin template _GLFW_PLATFORM_LIBRARY_TIMER_STATE() { _GLFWtimerWin32   win32;}
247 mixin template _GLFW_PLATFORM_MONITOR_STATE() {       _GLFWmonitorWin32 win32;}
248 mixin template _GLFW_PLATFORM_CURSOR_STATE() {        _GLFWcursorWin32  win32;}
249 mixin template _GLFW_PLATFORM_TLS_STATE() {           _GLFWtlsWin32     win32;}
250 mixin template _GLFW_PLATFORM_MUTEX_STATE() {         _GLFWmutexWin32   win32;}
251 
252 // Win32-specific per-window data
253 //
254 struct _GLFWwindowWin32 {
255     HWND handle;
256     HICON bigIcon;
257     HICON smallIcon;
258 
259     GLFWbool cursorTracked;
260     GLFWbool frameAction;
261     GLFWbool iconified;
262     GLFWbool maximized;
263     // Whether to enable framebuffer transparency on DWM
264     GLFWbool transparent;
265     GLFWbool scaleToMonitor;
266 
267     // The last received cursor position, regardless of source
268     int lastCursorPosX;int lastCursorPosY;
269 
270 }
271 
272 // Win32-specific global data
273 //
274 struct _GLFWlibraryWin32 {
275     import core.sys.windows.winuser: HDEVNOTIFY;
276     HWND helperWindowHandle;
277     HDEVNOTIFY deviceNotificationHandle;
278     DWORD foregroundLockTimeout;
279     int acquiredMonitorCount;
280     char* clipboardString;
281     int[512] keycodes;
282     int[GLFW_KEY_LAST + 1] scancodes;
283     char[5][GLFW_KEY_LAST + 1] keynames;
284     // Where to place the cursor when re-enabled
285     double restoreCursorPosX;double restoreCursorPosY;
286     // The window whose disabled cursor mode is active
287     _GLFWwindow* disabledCursorWindow;
288     RAWINPUT* rawInput;
289     int rawInputSize;
290     UINT mouseTrailSize;
291 
292     struct _Winmm {
293         HINSTANCE instance;
294         PFN_timeGetTime GetTime;
295     }_Winmm winmm;
296 
297     struct _Dinput8 {
298         HINSTANCE instance;
299         PFN_DirectInput8Create Create;
300         IDirectInput8 api;
301     }_Dinput8 dinput8;
302 
303     struct _Xinput {
304         HINSTANCE instance;
305         PFN_XInputGetCapabilities GetCapabilities;
306         PFN_XInputGetState GetState;
307         PFN_XInputSetState SetState;
308     }_Xinput xinput;
309 
310     struct _User32 {
311         HINSTANCE instance;
312         PFN_SetProcessDPIAware SetProcessDPIAware_;
313         PFN_ChangeWindowMessageFilterEx ChangeWindowMessageFilterEx_;
314         PFN_EnableNonClientDpiScaling EnableNonClientDpiScaling_;
315         PFN_SetProcessDpiAwarenessContext SetProcessDpiAwarenessContext_;
316         PFN_GetDpiForWindow GetDpiForWindow_;
317         PFN_AdjustWindowRectExForDpi AdjustWindowRectExForDpi_;
318     }_User32 user32;
319 
320     struct _Dwmapi {
321         HINSTANCE instance;
322         PFN_DwmIsCompositionEnabled IsCompositionEnabled;
323         PFN_DwmFlush Flush;
324         PFN_DwmEnableBlurBehindWindow EnableBlurBehindWindow;
325     }_Dwmapi dwmapi;
326 
327     struct _Shcore {
328         HINSTANCE instance;
329         PFN_SetProcessDpiAwareness SetProcessDpiAwareness_;
330         PFN_GetDpiForMonitor GetDpiForMonitor_;
331     }_Shcore shcore;
332 
333     struct _Ntdll {
334         HINSTANCE instance;
335         PFN_RtlVerifyVersionInfo RtlVerifyVersionInfo_;
336     }_Ntdll ntdll;
337 
338 }
339 
340 // Win32-specific per-monitor data
341 //
342 struct _GLFWmonitorWin32 {
343     HMONITOR handle;
344     // This size matches the static size of DISPLAY_DEVICE.DeviceName
345     WCHAR[32] adapterName;
346     WCHAR[32] displayName;
347     char[32] publicAdapterName;
348     char[32] publicDisplayName;
349     GLFWbool modesPruned;
350     GLFWbool modeChanged;
351 
352 }
353 
354 // Win32-specific per-cursor data
355 //
356 struct _GLFWcursorWin32 {
357     HCURSOR handle;
358 
359 }
360 
361 // Win32-specific global timer data
362 //
363 struct _GLFWtimerWin32 {
364     GLFWbool hasPC;
365     ulong frequency;
366 
367 }
368 
369 // Win32-specific thread local storage data
370 //
371 struct _GLFWtlsWin32 {
372     GLFWbool allocated;
373     DWORD index;
374 
375 }
376 
377 // Win32-specific mutex data
378 //
379 struct _GLFWmutexWin32 {
380     GLFWbool allocated;
381     CRITICAL_SECTION section;
382 
383 }
384 
385 
386 GLFWbool _glfwRegisterWindowClassWin32();
387 void _glfwUnregisterWindowClassWin32();
388 
389 wchar* _glfwCreateWideStringFromUTF8Win32(const(char)* source);
390 char* _glfwCreateUTF8FromWideStringWin32(const(wchar)* source);
391 BOOL _glfwIsWindowsVersionOrGreaterWin32(WORD major, WORD minor, WORD sp);
392 BOOL _glfwIsWindows10BuildOrGreaterWin32(WORD build);
393 void _glfwInputErrorWin32(int error, const(char)* description);
394 void _glfwUpdateKeyNamesWin32();
395 
396 void _glfwInitTimerWin32();
397 
398 void _glfwPollMonitorsWin32();
399 void _glfwSetVideoModeWin32(_GLFWmonitor* monitor, const(GLFWvidmode)* desired);
400 void _glfwRestoreVideoModeWin32(_GLFWmonitor* monitor);
401 void _glfwGetMonitorContentScaleWin32(HMONITOR handle, float* xscale, float* yscale);