ScrapExplorer - win32_init.c
Home / ext / glfw / src Lines: 1 | Size: 28091 bytes [Download] [Show on GitHub] [Search similar files] [Raw] [Raw (proxy)][FILE BEGIN]1//======================================================================== 2// GLFW 3.5 Win32 - www.glfw.org 3//------------------------------------------------------------------------ 4// Copyright (c) 2002-2006 Marcus Geelnard 5// Copyright (c) 2006-2019 Camilla Löwy <[email protected]> 6// 7// This software is provided 'as-is', without any express or implied 8// warranty. In no event will the authors be held liable for any damages 9// arising from the use of this software. 10// 11// Permission is granted to anyone to use this software for any purpose, 12// including commercial applications, and to alter it and redistribute it 13// freely, subject to the following restrictions: 14// 15// 1. The origin of this software must not be misrepresented; you must not 16// claim that you wrote the original software. If you use this software 17// in a product, an acknowledgment in the product documentation would 18// be appreciated but is not required. 19// 20// 2. Altered source versions must be plainly marked as such, and must not 21// be misrepresented as being the original software. 22// 23// 3. This notice may not be removed or altered from any source 24// distribution. 25// 26//======================================================================== 27 28#include "internal.h" 29 30#if defined(_GLFW_WIN32) 31 32#include <stdlib.h> 33 34static const GUID _glfw_GUID_DEVINTERFACE_HID = 35 {0x4d1e55b2,0xf16f,0x11cf,{0x88,0xcb,0x00,0x11,0x11,0x00,0x00,0x30}}; 36 37#define GUID_DEVINTERFACE_HID _glfw_GUID_DEVINTERFACE_HID 38 39#if defined(_GLFW_USE_HYBRID_HPG) || defined(_GLFW_USE_OPTIMUS_HPG) 40 41#if defined(_GLFW_BUILD_DLL) 42 #pragma message("These symbols must be exported by the executable and have no effect in a DLL") 43#endif 44 45// Executables (but not DLLs) exporting this symbol with this value will be 46// automatically directed to the high-performance GPU on Nvidia Optimus systems 47// with up-to-date drivers 48// 49__declspec(dllexport) DWORD NvOptimusEnablement = 1; 50 51// Executables (but not DLLs) exporting this symbol with this value will be 52// automatically directed to the high-performance GPU on AMD PowerXpress systems 53// with up-to-date drivers 54// 55__declspec(dllexport) int AmdPowerXpressRequestHighPerformance = 1; 56 57#endif // _GLFW_USE_HYBRID_HPG 58 59#if defined(_GLFW_BUILD_DLL) 60 61// GLFW DLL entry point 62// 63BOOL WINAPI DllMain(HINSTANCE instance, DWORD reason, LPVOID reserved) 64{ 65 return TRUE; 66} 67 68#endif // _GLFW_BUILD_DLL 69 70// Load necessary libraries (DLLs) 71// 72static GLFWbool loadLibraries(void) 73{ 74 if (!GetModuleHandleExW(GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS | 75 GET_MODULE_HANDLE_EX_FLAG_UNCHANGED_REFCOUNT, 76 (const WCHAR*) &_glfw, 77 (HMODULE*) &_glfw.win32.instance)) 78 { 79 _glfwInputErrorWin32(GLFW_PLATFORM_ERROR, 80 "Win32: Failed to retrieve own module handle"); 81 return GLFW_FALSE; 82 } 83 84 _glfw.win32.user32.instance = _glfwPlatformLoadModule("user32.dll"); 85 if (!_glfw.win32.user32.instance) 86 { 87 _glfwInputErrorWin32(GLFW_PLATFORM_ERROR, 88 "Win32: Failed to load user32.dll"); 89 return GLFW_FALSE; 90 } 91 92 _glfw.win32.user32.EnableNonClientDpiScaling_ = (PFN_EnableNonClientDpiScaling) 93 _glfwPlatformGetModuleSymbol(_glfw.win32.user32.instance, "EnableNonClientDpiScaling"); 94 _glfw.win32.user32.SetProcessDpiAwarenessContext_ = (PFN_SetProcessDpiAwarenessContext) 95 _glfwPlatformGetModuleSymbol(_glfw.win32.user32.instance, "SetProcessDpiAwarenessContext"); 96 _glfw.win32.user32.GetDpiForWindow_ = (PFN_GetDpiForWindow) 97 _glfwPlatformGetModuleSymbol(_glfw.win32.user32.instance, "GetDpiForWindow"); 98 _glfw.win32.user32.AdjustWindowRectExForDpi_ = (PFN_AdjustWindowRectExForDpi) 99 _glfwPlatformGetModuleSymbol(_glfw.win32.user32.instance, "AdjustWindowRectExForDpi"); 100 _glfw.win32.user32.GetSystemMetricsForDpi_ = (PFN_GetSystemMetricsForDpi) 101 _glfwPlatformGetModuleSymbol(_glfw.win32.user32.instance, "GetSystemMetricsForDpi"); 102 103 _glfw.win32.dinput8.instance = _glfwPlatformLoadModule("dinput8.dll"); 104 if (_glfw.win32.dinput8.instance) 105 { 106 _glfw.win32.dinput8.Create = (PFN_DirectInput8Create) 107 _glfwPlatformGetModuleSymbol(_glfw.win32.dinput8.instance, "DirectInput8Create"); 108 } 109 110 { 111 int i; 112 const char* names[] = 113 { 114 "xinput1_4.dll", 115 "xinput1_3.dll", 116 "xinput9_1_0.dll", 117 "xinput1_2.dll", 118 "xinput1_1.dll", 119 NULL 120 }; 121 122 for (i = 0; names[i]; i++) 123 { 124 _glfw.win32.xinput.instance = _glfwPlatformLoadModule(names[i]); 125 if (_glfw.win32.xinput.instance) 126 { 127 _glfw.win32.xinput.GetCapabilities = (PFN_XInputGetCapabilities) 128 _glfwPlatformGetModuleSymbol(_glfw.win32.xinput.instance, "XInputGetCapabilities"); 129 _glfw.win32.xinput.GetState = (PFN_XInputGetState) 130 _glfwPlatformGetModuleSymbol(_glfw.win32.xinput.instance, "XInputGetState"); 131 132 break; 133 } 134 } 135 } 136 137 _glfw.win32.dwmapi.instance = _glfwPlatformLoadModule("dwmapi.dll"); 138 if (_glfw.win32.dwmapi.instance) 139 { 140 _glfw.win32.dwmapi.IsCompositionEnabled = (PFN_DwmIsCompositionEnabled) 141 _glfwPlatformGetModuleSymbol(_glfw.win32.dwmapi.instance, "DwmIsCompositionEnabled"); 142 _glfw.win32.dwmapi.Flush = (PFN_DwmFlush) 143 _glfwPlatformGetModuleSymbol(_glfw.win32.dwmapi.instance, "DwmFlush"); 144 _glfw.win32.dwmapi.EnableBlurBehindWindow = (PFN_DwmEnableBlurBehindWindow) 145 _glfwPlatformGetModuleSymbol(_glfw.win32.dwmapi.instance, "DwmEnableBlurBehindWindow"); 146 _glfw.win32.dwmapi.GetColorizationColor = (PFN_DwmGetColorizationColor) 147 _glfwPlatformGetModuleSymbol(_glfw.win32.dwmapi.instance, "DwmGetColorizationColor"); 148 } 149 150 _glfw.win32.shcore.instance = _glfwPlatformLoadModule("shcore.dll"); 151 if (_glfw.win32.shcore.instance) 152 { 153 _glfw.win32.shcore.SetProcessDpiAwareness_ = (PFN_SetProcessDpiAwareness) 154 _glfwPlatformGetModuleSymbol(_glfw.win32.shcore.instance, "SetProcessDpiAwareness"); 155 _glfw.win32.shcore.GetDpiForMonitor_ = (PFN_GetDpiForMonitor) 156 _glfwPlatformGetModuleSymbol(_glfw.win32.shcore.instance, "GetDpiForMonitor"); 157 } 158 159 _glfw.win32.ntdll.instance = _glfwPlatformLoadModule("ntdll.dll"); 160 if (_glfw.win32.ntdll.instance) 161 { 162 _glfw.win32.ntdll.RtlVerifyVersionInfo_ = (PFN_RtlVerifyVersionInfo) 163 _glfwPlatformGetModuleSymbol(_glfw.win32.ntdll.instance, "RtlVerifyVersionInfo"); 164 } 165 166 return GLFW_TRUE; 167} 168 169// Unload used libraries (DLLs) 170// 171static void freeLibraries(void) 172{ 173 if (_glfw.win32.xinput.instance) 174 _glfwPlatformFreeModule(_glfw.win32.xinput.instance); 175 176 if (_glfw.win32.dinput8.instance) 177 _glfwPlatformFreeModule(_glfw.win32.dinput8.instance); 178 179 if (_glfw.win32.user32.instance) 180 _glfwPlatformFreeModule(_glfw.win32.user32.instance); 181 182 if (_glfw.win32.dwmapi.instance) 183 _glfwPlatformFreeModule(_glfw.win32.dwmapi.instance); 184 185 if (_glfw.win32.shcore.instance) 186 _glfwPlatformFreeModule(_glfw.win32.shcore.instance); 187 188 if (_glfw.win32.ntdll.instance) 189 _glfwPlatformFreeModule(_glfw.win32.ntdll.instance); 190} 191 192// Create key code translation tables 193// 194static void createKeyTables(void) 195{ 196 int scancode; 197 198 memset(_glfw.win32.keycodes, -1, sizeof(_glfw.win32.keycodes)); 199 memset(_glfw.win32.scancodes, -1, sizeof(_glfw.win32.scancodes)); 200 201 _glfw.win32.keycodes[0x00B] = GLFW_KEY_0; 202 _glfw.win32.keycodes[0x002] = GLFW_KEY_1; 203 _glfw.win32.keycodes[0x003] = GLFW_KEY_2; 204 _glfw.win32.keycodes[0x004] = GLFW_KEY_3; 205 _glfw.win32.keycodes[0x005] = GLFW_KEY_4; 206 _glfw.win32.keycodes[0x006] = GLFW_KEY_5; 207 _glfw.win32.keycodes[0x007] = GLFW_KEY_6; 208 _glfw.win32.keycodes[0x008] = GLFW_KEY_7; 209 _glfw.win32.keycodes[0x009] = GLFW_KEY_8; 210 _glfw.win32.keycodes[0x00A] = GLFW_KEY_9; 211 _glfw.win32.keycodes[0x01E] = GLFW_KEY_A; 212 _glfw.win32.keycodes[0x030] = GLFW_KEY_B; 213 _glfw.win32.keycodes[0x02E] = GLFW_KEY_C; 214 _glfw.win32.keycodes[0x020] = GLFW_KEY_D; 215 _glfw.win32.keycodes[0x012] = GLFW_KEY_E; 216 _glfw.win32.keycodes[0x021] = GLFW_KEY_F; 217 _glfw.win32.keycodes[0x022] = GLFW_KEY_G; 218 _glfw.win32.keycodes[0x023] = GLFW_KEY_H; 219 _glfw.win32.keycodes[0x017] = GLFW_KEY_I; 220 _glfw.win32.keycodes[0x024] = GLFW_KEY_J; 221 _glfw.win32.keycodes[0x025] = GLFW_KEY_K; 222 _glfw.win32.keycodes[0x026] = GLFW_KEY_L; 223 _glfw.win32.keycodes[0x032] = GLFW_KEY_M; 224 _glfw.win32.keycodes[0x031] = GLFW_KEY_N; 225 _glfw.win32.keycodes[0x018] = GLFW_KEY_O; 226 _glfw.win32.keycodes[0x019] = GLFW_KEY_P; 227 _glfw.win32.keycodes[0x010] = GLFW_KEY_Q; 228 _glfw.win32.keycodes[0x013] = GLFW_KEY_R; 229 _glfw.win32.keycodes[0x01F] = GLFW_KEY_S; 230 _glfw.win32.keycodes[0x014] = GLFW_KEY_T; 231 _glfw.win32.keycodes[0x016] = GLFW_KEY_U; 232 _glfw.win32.keycodes[0x02F] = GLFW_KEY_V; 233 _glfw.win32.keycodes[0x011] = GLFW_KEY_W; 234 _glfw.win32.keycodes[0x02D] = GLFW_KEY_X; 235 _glfw.win32.keycodes[0x015] = GLFW_KEY_Y; 236 _glfw.win32.keycodes[0x02C] = GLFW_KEY_Z; 237 238 _glfw.win32.keycodes[0x028] = GLFW_KEY_APOSTROPHE; 239 _glfw.win32.keycodes[0x02B] = GLFW_KEY_BACKSLASH; 240 _glfw.win32.keycodes[0x033] = GLFW_KEY_COMMA; 241 _glfw.win32.keycodes[0x00D] = GLFW_KEY_EQUAL; 242 _glfw.win32.keycodes[0x029] = GLFW_KEY_GRAVE_ACCENT; 243 _glfw.win32.keycodes[0x01A] = GLFW_KEY_LEFT_BRACKET; 244 _glfw.win32.keycodes[0x00C] = GLFW_KEY_MINUS; 245 _glfw.win32.keycodes[0x034] = GLFW_KEY_PERIOD; 246 _glfw.win32.keycodes[0x01B] = GLFW_KEY_RIGHT_BRACKET; 247 _glfw.win32.keycodes[0x027] = GLFW_KEY_SEMICOLON; 248 _glfw.win32.keycodes[0x035] = GLFW_KEY_SLASH; 249 _glfw.win32.keycodes[0x056] = GLFW_KEY_WORLD_2; 250 251 _glfw.win32.keycodes[0x00E] = GLFW_KEY_BACKSPACE; 252 _glfw.win32.keycodes[0x153] = GLFW_KEY_DELETE; 253 _glfw.win32.keycodes[0x14F] = GLFW_KEY_END; 254 _glfw.win32.keycodes[0x01C] = GLFW_KEY_ENTER; 255 _glfw.win32.keycodes[0x001] = GLFW_KEY_ESCAPE; 256 _glfw.win32.keycodes[0x147] = GLFW_KEY_HOME; 257 _glfw.win32.keycodes[0x152] = GLFW_KEY_INSERT; 258 _glfw.win32.keycodes[0x15D] = GLFW_KEY_MENU; 259 _glfw.win32.keycodes[0x151] = GLFW_KEY_PAGE_DOWN; 260 _glfw.win32.keycodes[0x149] = GLFW_KEY_PAGE_UP; 261 _glfw.win32.keycodes[0x045] = GLFW_KEY_PAUSE; 262 _glfw.win32.keycodes[0x039] = GLFW_KEY_SPACE; 263 _glfw.win32.keycodes[0x00F] = GLFW_KEY_TAB; 264 _glfw.win32.keycodes[0x03A] = GLFW_KEY_CAPS_LOCK; 265 _glfw.win32.keycodes[0x145] = GLFW_KEY_NUM_LOCK; 266 _glfw.win32.keycodes[0x046] = GLFW_KEY_SCROLL_LOCK; 267 _glfw.win32.keycodes[0x03B] = GLFW_KEY_F1; 268 _glfw.win32.keycodes[0x03C] = GLFW_KEY_F2; 269 _glfw.win32.keycodes[0x03D] = GLFW_KEY_F3; 270 _glfw.win32.keycodes[0x03E] = GLFW_KEY_F4; 271 _glfw.win32.keycodes[0x03F] = GLFW_KEY_F5; 272 _glfw.win32.keycodes[0x040] = GLFW_KEY_F6; 273 _glfw.win32.keycodes[0x041] = GLFW_KEY_F7; 274 _glfw.win32.keycodes[0x042] = GLFW_KEY_F8; 275 _glfw.win32.keycodes[0x043] = GLFW_KEY_F9; 276 _glfw.win32.keycodes[0x044] = GLFW_KEY_F10; 277 _glfw.win32.keycodes[0x057] = GLFW_KEY_F11; 278 _glfw.win32.keycodes[0x058] = GLFW_KEY_F12; 279 _glfw.win32.keycodes[0x064] = GLFW_KEY_F13; 280 _glfw.win32.keycodes[0x065] = GLFW_KEY_F14; 281 _glfw.win32.keycodes[0x066] = GLFW_KEY_F15; 282 _glfw.win32.keycodes[0x067] = GLFW_KEY_F16; 283 _glfw.win32.keycodes[0x068] = GLFW_KEY_F17; 284 _glfw.win32.keycodes[0x069] = GLFW_KEY_F18; 285 _glfw.win32.keycodes[0x06A] = GLFW_KEY_F19; 286 _glfw.win32.keycodes[0x06B] = GLFW_KEY_F20; 287 _glfw.win32.keycodes[0x06C] = GLFW_KEY_F21; 288 _glfw.win32.keycodes[0x06D] = GLFW_KEY_F22; 289 _glfw.win32.keycodes[0x06E] = GLFW_KEY_F23; 290 _glfw.win32.keycodes[0x076] = GLFW_KEY_F24; 291 _glfw.win32.keycodes[0x038] = GLFW_KEY_LEFT_ALT; 292 _glfw.win32.keycodes[0x01D] = GLFW_KEY_LEFT_CONTROL; 293 _glfw.win32.keycodes[0x02A] = GLFW_KEY_LEFT_SHIFT; 294 _glfw.win32.keycodes[0x15B] = GLFW_KEY_LEFT_SUPER; 295 _glfw.win32.keycodes[0x137] = GLFW_KEY_PRINT_SCREEN; 296 _glfw.win32.keycodes[0x138] = GLFW_KEY_RIGHT_ALT; 297 _glfw.win32.keycodes[0x11D] = GLFW_KEY_RIGHT_CONTROL; 298 _glfw.win32.keycodes[0x036] = GLFW_KEY_RIGHT_SHIFT; 299 _glfw.win32.keycodes[0x15C] = GLFW_KEY_RIGHT_SUPER; 300 _glfw.win32.keycodes[0x150] = GLFW_KEY_DOWN; 301 _glfw.win32.keycodes[0x14B] = GLFW_KEY_LEFT; 302 _glfw.win32.keycodes[0x14D] = GLFW_KEY_RIGHT; 303 _glfw.win32.keycodes[0x148] = GLFW_KEY_UP; 304 305 _glfw.win32.keycodes[0x052] = GLFW_KEY_KP_0; 306 _glfw.win32.keycodes[0x04F] = GLFW_KEY_KP_1; 307 _glfw.win32.keycodes[0x050] = GLFW_KEY_KP_2; 308 _glfw.win32.keycodes[0x051] = GLFW_KEY_KP_3; 309 _glfw.win32.keycodes[0x04B] = GLFW_KEY_KP_4; 310 _glfw.win32.keycodes[0x04C] = GLFW_KEY_KP_5; 311 _glfw.win32.keycodes[0x04D] = GLFW_KEY_KP_6; 312 _glfw.win32.keycodes[0x047] = GLFW_KEY_KP_7; 313 _glfw.win32.keycodes[0x048] = GLFW_KEY_KP_8; 314 _glfw.win32.keycodes[0x049] = GLFW_KEY_KP_9; 315 _glfw.win32.keycodes[0x04E] = GLFW_KEY_KP_ADD; 316 _glfw.win32.keycodes[0x053] = GLFW_KEY_KP_DECIMAL; 317 _glfw.win32.keycodes[0x135] = GLFW_KEY_KP_DIVIDE; 318 _glfw.win32.keycodes[0x11C] = GLFW_KEY_KP_ENTER; 319 _glfw.win32.keycodes[0x059] = GLFW_KEY_KP_EQUAL; 320 _glfw.win32.keycodes[0x037] = GLFW_KEY_KP_MULTIPLY; 321 _glfw.win32.keycodes[0x04A] = GLFW_KEY_KP_SUBTRACT; 322 323 for (scancode = 0; scancode < 512; scancode++) 324 { 325 if (_glfw.win32.keycodes[scancode] > 0) 326 _glfw.win32.scancodes[_glfw.win32.keycodes[scancode]] = scancode; 327 } 328} 329 330// Window procedure for the hidden helper window 331// 332static LRESULT CALLBACK helperWindowProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam) 333{ 334 switch (uMsg) 335 { 336 case WM_DISPLAYCHANGE: 337 _glfwPollMonitorsWin32(); 338 break; 339 340 case WM_DEVICECHANGE: 341 { 342 if (!_glfw.joysticksInitialized) 343 break; 344 345 if (wParam == DBT_DEVICEARRIVAL) 346 { 347 DEV_BROADCAST_HDR* dbh = (DEV_BROADCAST_HDR*) lParam; 348 if (dbh && dbh->dbch_devicetype == DBT_DEVTYP_DEVICEINTERFACE) 349 _glfwDetectJoystickConnectionWin32(); 350 } 351 else if (wParam == DBT_DEVICEREMOVECOMPLETE) 352 { 353 DEV_BROADCAST_HDR* dbh = (DEV_BROADCAST_HDR*) lParam; 354 if (dbh && dbh->dbch_devicetype == DBT_DEVTYP_DEVICEINTERFACE) 355 _glfwDetectJoystickDisconnectionWin32(); 356 } 357 358 break; 359 } 360 } 361 362 return DefWindowProcW(hWnd, uMsg, wParam, lParam); 363} 364 365// Creates a dummy window for behind-the-scenes work 366// 367static GLFWbool createHelperWindow(void) 368{ 369 MSG msg; 370 WNDCLASSEXW wc = { sizeof(wc) }; 371 372 wc.style = CS_OWNDC; 373 wc.lpfnWndProc = (WNDPROC) helperWindowProc; 374 wc.hInstance = _glfw.win32.instance; 375 wc.lpszClassName = L"GLFW3 Helper"; 376 377 _glfw.win32.helperWindowClass = RegisterClassExW(&wc); 378 if (!_glfw.win32.helperWindowClass) 379 { 380 _glfwInputErrorWin32(GLFW_PLATFORM_ERROR, 381 "Win32: Failed to register helper window class"); 382 return GLFW_FALSE; 383 } 384 385 _glfw.win32.helperWindowHandle = 386 CreateWindowExW(WS_EX_OVERLAPPEDWINDOW, 387 MAKEINTATOM(_glfw.win32.helperWindowClass), 388 L"GLFW message window", 389 WS_CLIPSIBLINGS | WS_CLIPCHILDREN, 390 0, 0, 1, 1, 391 NULL, NULL, 392 _glfw.win32.instance, 393 NULL); 394 395 if (!_glfw.win32.helperWindowHandle) 396 { 397 _glfwInputErrorWin32(GLFW_PLATFORM_ERROR, 398 "Win32: Failed to create helper window"); 399 return GLFW_FALSE; 400 } 401 402 // HACK: The command to the first ShowWindow call is ignored if the parent 403 // process passed along a STARTUPINFO, so clear that with a no-op call 404 ShowWindow(_glfw.win32.helperWindowHandle, SW_HIDE); 405 406 // Register for HID device notifications 407 { 408 DEV_BROADCAST_DEVICEINTERFACE_W dbi; 409 ZeroMemory(&dbi, sizeof(dbi)); 410 dbi.dbcc_size = sizeof(dbi); 411 dbi.dbcc_devicetype = DBT_DEVTYP_DEVICEINTERFACE; 412 dbi.dbcc_classguid = GUID_DEVINTERFACE_HID; 413 414 _glfw.win32.deviceNotificationHandle = 415 RegisterDeviceNotificationW(_glfw.win32.helperWindowHandle, 416 (DEV_BROADCAST_HDR*) &dbi, 417 DEVICE_NOTIFY_WINDOW_HANDLE); 418 } 419 420 while (PeekMessageW(&msg, _glfw.win32.helperWindowHandle, 0, 0, PM_REMOVE)) 421 { 422 TranslateMessage(&msg); 423 DispatchMessageW(&msg); 424 } 425 426 return GLFW_TRUE; 427} 428 429////////////////////////////////////////////////////////////////////////// 430////// GLFW internal API ////// 431////////////////////////////////////////////////////////////////////////// 432 433// Returns a wide string version of the specified UTF-8 string 434// 435WCHAR* _glfwCreateWideStringFromUTF8Win32(const char* source) 436{ 437 WCHAR* target; 438 int count; 439 440 count = MultiByteToWideChar(CP_UTF8, 0, source, -1, NULL, 0); 441 if (!count) 442 { 443 _glfwInputErrorWin32(GLFW_PLATFORM_ERROR, 444 "Win32: Failed to convert string from UTF-8"); 445 return NULL; 446 } 447 448 target = _glfw_calloc(count, sizeof(WCHAR)); 449 450 if (!MultiByteToWideChar(CP_UTF8, 0, source, -1, target, count)) 451 { 452 _glfwInputErrorWin32(GLFW_PLATFORM_ERROR, 453 "Win32: Failed to convert string from UTF-8"); 454 _glfw_free(target); 455 return NULL; 456 } 457 458 return target; 459} 460 461// Returns a UTF-8 string version of the specified wide string 462// 463char* _glfwCreateUTF8FromWideStringWin32(const WCHAR* source) 464{ 465 char* target; 466 int size; 467 468 size = WideCharToMultiByte(CP_UTF8, 0, source, -1, NULL, 0, NULL, NULL); 469 if (!size) 470 { 471 _glfwInputErrorWin32(GLFW_PLATFORM_ERROR, 472 "Win32: Failed to convert string to UTF-8"); 473 return NULL; 474 } 475 476 target = _glfw_calloc(size, 1); 477 478 if (!WideCharToMultiByte(CP_UTF8, 0, source, -1, target, size, NULL, NULL)) 479 { 480 _glfwInputErrorWin32(GLFW_PLATFORM_ERROR, 481 "Win32: Failed to convert string to UTF-8"); 482 _glfw_free(target); 483 return NULL; 484 } 485 486 return target; 487} 488 489// Reports the specified error, appending information about the last Win32 error 490// 491void _glfwInputErrorWin32(int error, const char* description) 492{ 493 WCHAR buffer[_GLFW_MESSAGE_SIZE] = L""; 494 char message[_GLFW_MESSAGE_SIZE] = ""; 495 496 FormatMessageW(FORMAT_MESSAGE_FROM_SYSTEM | 497 FORMAT_MESSAGE_IGNORE_INSERTS | 498 FORMAT_MESSAGE_MAX_WIDTH_MASK, 499 NULL, 500 GetLastError() & 0xffff, 501 MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), 502 buffer, 503 sizeof(buffer) / sizeof(WCHAR), 504 NULL); 505 WideCharToMultiByte(CP_UTF8, 0, buffer, -1, message, sizeof(message), NULL, NULL); 506 507 _glfwInputError(error, "%s: %s", description, message); 508} 509 510// Updates key names according to the current keyboard layout 511// 512void _glfwUpdateKeyNamesWin32(void) 513{ 514 int key; 515 BYTE state[256] = {0}; 516 517 memset(_glfw.win32.keynames, 0, sizeof(_glfw.win32.keynames)); 518 519 for (key = GLFW_KEY_SPACE; key <= GLFW_KEY_LAST; key++) 520 { 521 UINT vk; 522 int scancode, length; 523 WCHAR chars[16]; 524 525 scancode = _glfw.win32.scancodes[key]; 526 if (scancode == -1) 527 continue; 528 529 if (key >= GLFW_KEY_KP_0 && key <= GLFW_KEY_KP_ADD) 530 { 531 const UINT vks[] = { 532 VK_NUMPAD0, VK_NUMPAD1, VK_NUMPAD2, VK_NUMPAD3, 533 VK_NUMPAD4, VK_NUMPAD5, VK_NUMPAD6, VK_NUMPAD7, 534 VK_NUMPAD8, VK_NUMPAD9, VK_DECIMAL, VK_DIVIDE, 535 VK_MULTIPLY, VK_SUBTRACT, VK_ADD 536 }; 537 538 vk = vks[key - GLFW_KEY_KP_0]; 539 } 540 else 541 vk = MapVirtualKeyW(scancode, MAPVK_VSC_TO_VK); 542 543 length = ToUnicode(vk, scancode, state, 544 chars, sizeof(chars) / sizeof(WCHAR), 545 0); 546 547 if (length == -1) 548 { 549 // This is a dead key, so we need a second simulated key press 550 // to make it output its own character (usually a diacritic) 551 length = ToUnicode(vk, scancode, state, 552 chars, sizeof(chars) / sizeof(WCHAR), 553 0); 554 } 555 556 if (length < 1) 557 continue; 558 559 WideCharToMultiByte(CP_UTF8, 0, chars, 1, 560 _glfw.win32.keynames[key], 561 sizeof(_glfw.win32.keynames[key]), 562 NULL, NULL); 563 } 564} 565 566// Replacement for IsWindowsVersionOrGreater, as we cannot rely on the 567// application having a correct embedded manifest 568// 569BOOL _glfwIsWindowsVersionOrGreaterWin32(WORD major, WORD minor, WORD sp) 570{ 571 OSVERSIONINFOEXW osvi = { sizeof(osvi), major, minor, 0, 0, {0}, sp }; 572 DWORD mask = VER_MAJORVERSION | VER_MINORVERSION | VER_SERVICEPACKMAJOR; 573 ULONGLONG cond = VerSetConditionMask(0, VER_MAJORVERSION, VER_GREATER_EQUAL); 574 cond = VerSetConditionMask(cond, VER_MINORVERSION, VER_GREATER_EQUAL); 575 cond = VerSetConditionMask(cond, VER_SERVICEPACKMAJOR, VER_GREATER_EQUAL); 576 // HACK: Use RtlVerifyVersionInfo instead of VerifyVersionInfoW as the 577 // latter lies unless the user knew to embed a non-default manifest 578 // announcing support for Windows 10 via supportedOS GUID 579 return RtlVerifyVersionInfo(&osvi, mask, cond) == 0; 580} 581 582// Checks whether we are on at least the specified build of Windows 10 583// 584BOOL _glfwIsWindows10BuildOrGreaterWin32(WORD build) 585{ 586 OSVERSIONINFOEXW osvi = { sizeof(osvi), 10, 0, build }; 587 DWORD mask = VER_MAJORVERSION | VER_MINORVERSION | VER_BUILDNUMBER; 588 ULONGLONG cond = VerSetConditionMask(0, VER_MAJORVERSION, VER_GREATER_EQUAL); 589 cond = VerSetConditionMask(cond, VER_MINORVERSION, VER_GREATER_EQUAL); 590 cond = VerSetConditionMask(cond, VER_BUILDNUMBER, VER_GREATER_EQUAL); 591 // HACK: Use RtlVerifyVersionInfo instead of VerifyVersionInfoW as the 592 // latter lies unless the user knew to embed a non-default manifest 593 // announcing support for Windows 10 via supportedOS GUID 594 return RtlVerifyVersionInfo(&osvi, mask, cond) == 0; 595} 596 597GLFWbool _glfwConnectWin32(int platformID, _GLFWplatform* platform) 598{ 599 const _GLFWplatform win32 = 600 { 601 .platformID = GLFW_PLATFORM_WIN32, 602 .init = _glfwInitWin32, 603 .terminate = _glfwTerminateWin32, 604 .getCursorPos = _glfwGetCursorPosWin32, 605 .setCursorPos = _glfwSetCursorPosWin32, 606 .setCursorMode = _glfwSetCursorModeWin32, 607 .setRawMouseMotion = _glfwSetRawMouseMotionWin32, 608 .rawMouseMotionSupported = _glfwRawMouseMotionSupportedWin32, 609 .createCursor = _glfwCreateCursorWin32, 610 .createStandardCursor = _glfwCreateStandardCursorWin32, 611 .destroyCursor = _glfwDestroyCursorWin32, 612 .setCursor = _glfwSetCursorWin32, 613 .getScancodeName = _glfwGetScancodeNameWin32, 614 .getKeyScancode = _glfwGetKeyScancodeWin32, 615 .setClipboardString = _glfwSetClipboardStringWin32, 616 .getClipboardString = _glfwGetClipboardStringWin32, 617 .initJoysticks = _glfwInitJoysticksWin32, 618 .terminateJoysticks = _glfwTerminateJoysticksWin32, 619 .pollJoystick = _glfwPollJoystickWin32, 620 .getMappingName = _glfwGetMappingNameWin32, 621 .updateGamepadGUID = _glfwUpdateGamepadGUIDWin32, 622 .freeMonitor = _glfwFreeMonitorWin32, 623 .getMonitorPos = _glfwGetMonitorPosWin32, 624 .getMonitorContentScale = _glfwGetMonitorContentScaleWin32, 625 .getMonitorWorkarea = _glfwGetMonitorWorkareaWin32, 626 .getVideoModes = _glfwGetVideoModesWin32, 627 .getVideoMode = _glfwGetVideoModeWin32, 628 .getGammaRamp = _glfwGetGammaRampWin32, 629 .setGammaRamp = _glfwSetGammaRampWin32, 630 .createWindow = _glfwCreateWindowWin32, 631 .destroyWindow = _glfwDestroyWindowWin32, 632 .setWindowTitle = _glfwSetWindowTitleWin32, 633 .setWindowIcon = _glfwSetWindowIconWin32, 634 .getWindowPos = _glfwGetWindowPosWin32, 635 .setWindowPos = _glfwSetWindowPosWin32, 636 .getWindowSize = _glfwGetWindowSizeWin32, 637 .setWindowSize = _glfwSetWindowSizeWin32, 638 .setWindowSizeLimits = _glfwSetWindowSizeLimitsWin32, 639 .setWindowAspectRatio = _glfwSetWindowAspectRatioWin32, 640 .getFramebufferSize = _glfwGetFramebufferSizeWin32, 641 .getWindowFrameSize = _glfwGetWindowFrameSizeWin32, 642 .getWindowContentScale = _glfwGetWindowContentScaleWin32, 643 .iconifyWindow = _glfwIconifyWindowWin32, 644 .restoreWindow = _glfwRestoreWindowWin32, 645 .maximizeWindow = _glfwMaximizeWindowWin32, 646 .showWindow = _glfwShowWindowWin32, 647 .hideWindow = _glfwHideWindowWin32, 648 .requestWindowAttention = _glfwRequestWindowAttentionWin32, 649 .focusWindow = _glfwFocusWindowWin32, 650 .setWindowMonitor = _glfwSetWindowMonitorWin32, 651 .windowFocused = _glfwWindowFocusedWin32, 652 .windowIconified = _glfwWindowIconifiedWin32, 653 .windowVisible = _glfwWindowVisibleWin32, 654 .windowMaximized = _glfwWindowMaximizedWin32, 655 .windowHovered = _glfwWindowHoveredWin32, 656 .framebufferTransparent = _glfwFramebufferTransparentWin32, 657 .getWindowOpacity = _glfwGetWindowOpacityWin32, 658 .setWindowResizable = _glfwSetWindowResizableWin32, 659 .setWindowDecorated = _glfwSetWindowDecoratedWin32, 660 .setWindowFloating = _glfwSetWindowFloatingWin32, 661 .setWindowOpacity = _glfwSetWindowOpacityWin32, 662 .setWindowMousePassthrough = _glfwSetWindowMousePassthroughWin32, 663 .pollEvents = _glfwPollEventsWin32, 664 .waitEvents = _glfwWaitEventsWin32, 665 .waitEventsTimeout = _glfwWaitEventsTimeoutWin32, 666 .postEmptyEvent = _glfwPostEmptyEventWin32, 667 .getEGLPlatform = _glfwGetEGLPlatformWin32, 668 .getEGLNativeDisplay = _glfwGetEGLNativeDisplayWin32, 669 .getEGLNativeWindow = _glfwGetEGLNativeWindowWin32, 670 .getRequiredInstanceExtensions = _glfwGetRequiredInstanceExtensionsWin32, 671 .getPhysicalDevicePresentationSupport = _glfwGetPhysicalDevicePresentationSupportWin32, 672 .createWindowSurface = _glfwCreateWindowSurfaceWin32 673 }; 674 675 *platform = win32; 676 return GLFW_TRUE; 677} 678 679int _glfwInitWin32(void) 680{ 681 if (!loadLibraries()) 682 return GLFW_FALSE; 683 684 createKeyTables(); 685 _glfwUpdateKeyNamesWin32(); 686 687 if (_glfwIsWindows10Version1703OrGreaterWin32()) 688 SetProcessDpiAwarenessContext(DPI_AWARENESS_CONTEXT_PER_MONITOR_AWARE_V2); 689 else if (IsWindows8Point1OrGreater()) 690 SetProcessDpiAwareness(PROCESS_PER_MONITOR_DPI_AWARE); 691 else 692 SetProcessDPIAware(); 693 694 if (!createHelperWindow()) 695 return GLFW_FALSE; 696 697 _glfwPollMonitorsWin32(); 698 return GLFW_TRUE; 699} 700 701void _glfwTerminateWin32(void) 702{ 703 if (_glfw.win32.blankCursor) 704 DestroyIcon((HICON) _glfw.win32.blankCursor); 705 706 if (_glfw.win32.deviceNotificationHandle) 707 UnregisterDeviceNotification(_glfw.win32.deviceNotificationHandle); 708 709 if (_glfw.win32.helperWindowHandle) 710 DestroyWindow(_glfw.win32.helperWindowHandle); 711 if (_glfw.win32.helperWindowClass) 712 UnregisterClassW(MAKEINTATOM(_glfw.win32.helperWindowClass), _glfw.win32.instance); 713 if (_glfw.win32.mainWindowClass) 714 UnregisterClassW(MAKEINTATOM(_glfw.win32.mainWindowClass), _glfw.win32.instance); 715 716 _glfw_free(_glfw.win32.clipboardString); 717 _glfw_free(_glfw.win32.rawInput); 718 719 _glfwTerminateWGL(); 720 _glfwTerminateEGL(); 721 _glfwTerminateOSMesa(); 722 723 freeLibraries(); 724} 725 726#endif // _GLFW_WIN32 727 728[FILE END](C) 2025 0x4248 (C) 2025 4248 Media and 4248 Systems, All part of 0x4248 See LICENCE files for more information. Not all files are by 0x4248 always check Licencing.