twitchapon-anim

Basic Twitchapon Receiver/Visuals
git clone git://bsandro.tech/twitchapon-anim
Log | Files | Refs | README | LICENSE

win32_init.c (23104B)


      1 //========================================================================
      2 // GLFW 3.3 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 <stdlib.h>
     33 #include <malloc.h>
     34 
     35 static const GUID _glfw_GUID_DEVINTERFACE_HID =
     36     {0x4d1e55b2,0xf16f,0x11cf,{0x88,0xcb,0x00,0x11,0x11,0x00,0x00,0x30}};
     37 
     38 #define GUID_DEVINTERFACE_HID _glfw_GUID_DEVINTERFACE_HID
     39 
     40 #if defined(_GLFW_USE_HYBRID_HPG) || defined(_GLFW_USE_OPTIMUS_HPG)
     41 
     42 // Executables (but not DLLs) exporting this symbol with this value will be
     43 // automatically directed to the high-performance GPU on Nvidia Optimus systems
     44 // with up-to-date drivers
     45 //
     46 __declspec(dllexport) DWORD NvOptimusEnablement = 1;
     47 
     48 // Executables (but not DLLs) exporting this symbol with this value will be
     49 // automatically directed to the high-performance GPU on AMD PowerXpress systems
     50 // with up-to-date drivers
     51 //
     52 __declspec(dllexport) int AmdPowerXpressRequestHighPerformance = 1;
     53 
     54 #endif // _GLFW_USE_HYBRID_HPG
     55 
     56 #if defined(_GLFW_BUILD_DLL)
     57 
     58 // GLFW DLL entry point
     59 //
     60 BOOL WINAPI DllMain(HINSTANCE instance, DWORD reason, LPVOID reserved)
     61 {
     62     return TRUE;
     63 }
     64 
     65 #endif // _GLFW_BUILD_DLL
     66 
     67 // Load necessary libraries (DLLs)
     68 //
     69 static GLFWbool loadLibraries(void)
     70 {
     71     _glfw.win32.winmm.instance = LoadLibraryA("winmm.dll");
     72     if (!_glfw.win32.winmm.instance)
     73     {
     74         _glfwInputErrorWin32(GLFW_PLATFORM_ERROR,
     75                              "Win32: Failed to load winmm.dll");
     76         return GLFW_FALSE;
     77     }
     78 
     79     _glfw.win32.winmm.GetTime = (PFN_timeGetTime)
     80         GetProcAddress(_glfw.win32.winmm.instance, "timeGetTime");
     81 
     82     _glfw.win32.user32.instance = LoadLibraryA("user32.dll");
     83     if (!_glfw.win32.user32.instance)
     84     {
     85         _glfwInputErrorWin32(GLFW_PLATFORM_ERROR,
     86                              "Win32: Failed to load user32.dll");
     87         return GLFW_FALSE;
     88     }
     89 
     90     _glfw.win32.user32.SetProcessDPIAware_ = (PFN_SetProcessDPIAware)
     91         GetProcAddress(_glfw.win32.user32.instance, "SetProcessDPIAware");
     92     _glfw.win32.user32.ChangeWindowMessageFilterEx_ = (PFN_ChangeWindowMessageFilterEx)
     93         GetProcAddress(_glfw.win32.user32.instance, "ChangeWindowMessageFilterEx");
     94     _glfw.win32.user32.EnableNonClientDpiScaling_ = (PFN_EnableNonClientDpiScaling)
     95         GetProcAddress(_glfw.win32.user32.instance, "EnableNonClientDpiScaling");
     96     _glfw.win32.user32.SetProcessDpiAwarenessContext_ = (PFN_SetProcessDpiAwarenessContext)
     97         GetProcAddress(_glfw.win32.user32.instance, "SetProcessDpiAwarenessContext");
     98     _glfw.win32.user32.GetDpiForWindow_ = (PFN_GetDpiForWindow)
     99         GetProcAddress(_glfw.win32.user32.instance, "GetDpiForWindow");
    100     _glfw.win32.user32.AdjustWindowRectExForDpi_ = (PFN_AdjustWindowRectExForDpi)
    101         GetProcAddress(_glfw.win32.user32.instance, "AdjustWindowRectExForDpi");
    102 
    103     _glfw.win32.dinput8.instance = LoadLibraryA("dinput8.dll");
    104     if (_glfw.win32.dinput8.instance)
    105     {
    106         _glfw.win32.dinput8.Create = (PFN_DirectInput8Create)
    107             GetProcAddress(_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 = LoadLibraryA(names[i]);
    125             if (_glfw.win32.xinput.instance)
    126             {
    127                 _glfw.win32.xinput.GetCapabilities = (PFN_XInputGetCapabilities)
    128                     GetProcAddress(_glfw.win32.xinput.instance, "XInputGetCapabilities");
    129                 _glfw.win32.xinput.GetState = (PFN_XInputGetState)
    130                     GetProcAddress(_glfw.win32.xinput.instance, "XInputGetState");
    131 
    132                 break;
    133             }
    134         }
    135     }
    136 
    137     _glfw.win32.dwmapi.instance = LoadLibraryA("dwmapi.dll");
    138     if (_glfw.win32.dwmapi.instance)
    139     {
    140         _glfw.win32.dwmapi.IsCompositionEnabled = (PFN_DwmIsCompositionEnabled)
    141             GetProcAddress(_glfw.win32.dwmapi.instance, "DwmIsCompositionEnabled");
    142         _glfw.win32.dwmapi.Flush = (PFN_DwmFlush)
    143             GetProcAddress(_glfw.win32.dwmapi.instance, "DwmFlush");
    144         _glfw.win32.dwmapi.EnableBlurBehindWindow = (PFN_DwmEnableBlurBehindWindow)
    145             GetProcAddress(_glfw.win32.dwmapi.instance, "DwmEnableBlurBehindWindow");
    146     }
    147 
    148     _glfw.win32.shcore.instance = LoadLibraryA("shcore.dll");
    149     if (_glfw.win32.shcore.instance)
    150     {
    151         _glfw.win32.shcore.SetProcessDpiAwareness_ = (PFN_SetProcessDpiAwareness)
    152             GetProcAddress(_glfw.win32.shcore.instance, "SetProcessDpiAwareness");
    153         _glfw.win32.shcore.GetDpiForMonitor_ = (PFN_GetDpiForMonitor)
    154             GetProcAddress(_glfw.win32.shcore.instance, "GetDpiForMonitor");
    155     }
    156 
    157     _glfw.win32.ntdll.instance = LoadLibraryA("ntdll.dll");
    158     if (_glfw.win32.ntdll.instance)
    159     {
    160         _glfw.win32.ntdll.RtlVerifyVersionInfo_ = (PFN_RtlVerifyVersionInfo)
    161             GetProcAddress(_glfw.win32.ntdll.instance, "RtlVerifyVersionInfo");
    162     }
    163 
    164     return GLFW_TRUE;
    165 }
    166 
    167 // Unload used libraries (DLLs)
    168 //
    169 static void freeLibraries(void)
    170 {
    171     if (_glfw.win32.xinput.instance)
    172         FreeLibrary(_glfw.win32.xinput.instance);
    173 
    174     if (_glfw.win32.dinput8.instance)
    175         FreeLibrary(_glfw.win32.dinput8.instance);
    176 
    177     if (_glfw.win32.winmm.instance)
    178         FreeLibrary(_glfw.win32.winmm.instance);
    179 
    180     if (_glfw.win32.user32.instance)
    181         FreeLibrary(_glfw.win32.user32.instance);
    182 
    183     if (_glfw.win32.dwmapi.instance)
    184         FreeLibrary(_glfw.win32.dwmapi.instance);
    185 
    186     if (_glfw.win32.shcore.instance)
    187         FreeLibrary(_glfw.win32.shcore.instance);
    188 
    189     if (_glfw.win32.ntdll.instance)
    190         FreeLibrary(_glfw.win32.ntdll.instance);
    191 }
    192 
    193 // Create key code translation tables
    194 //
    195 static void createKeyTables(void)
    196 {
    197     int scancode;
    198 
    199     memset(_glfw.win32.keycodes, -1, sizeof(_glfw.win32.keycodes));
    200     memset(_glfw.win32.scancodes, -1, sizeof(_glfw.win32.scancodes));
    201 
    202     _glfw.win32.keycodes[0x00B] = GLFW_KEY_0;
    203     _glfw.win32.keycodes[0x002] = GLFW_KEY_1;
    204     _glfw.win32.keycodes[0x003] = GLFW_KEY_2;
    205     _glfw.win32.keycodes[0x004] = GLFW_KEY_3;
    206     _glfw.win32.keycodes[0x005] = GLFW_KEY_4;
    207     _glfw.win32.keycodes[0x006] = GLFW_KEY_5;
    208     _glfw.win32.keycodes[0x007] = GLFW_KEY_6;
    209     _glfw.win32.keycodes[0x008] = GLFW_KEY_7;
    210     _glfw.win32.keycodes[0x009] = GLFW_KEY_8;
    211     _glfw.win32.keycodes[0x00A] = GLFW_KEY_9;
    212     _glfw.win32.keycodes[0x01E] = GLFW_KEY_A;
    213     _glfw.win32.keycodes[0x030] = GLFW_KEY_B;
    214     _glfw.win32.keycodes[0x02E] = GLFW_KEY_C;
    215     _glfw.win32.keycodes[0x020] = GLFW_KEY_D;
    216     _glfw.win32.keycodes[0x012] = GLFW_KEY_E;
    217     _glfw.win32.keycodes[0x021] = GLFW_KEY_F;
    218     _glfw.win32.keycodes[0x022] = GLFW_KEY_G;
    219     _glfw.win32.keycodes[0x023] = GLFW_KEY_H;
    220     _glfw.win32.keycodes[0x017] = GLFW_KEY_I;
    221     _glfw.win32.keycodes[0x024] = GLFW_KEY_J;
    222     _glfw.win32.keycodes[0x025] = GLFW_KEY_K;
    223     _glfw.win32.keycodes[0x026] = GLFW_KEY_L;
    224     _glfw.win32.keycodes[0x032] = GLFW_KEY_M;
    225     _glfw.win32.keycodes[0x031] = GLFW_KEY_N;
    226     _glfw.win32.keycodes[0x018] = GLFW_KEY_O;
    227     _glfw.win32.keycodes[0x019] = GLFW_KEY_P;
    228     _glfw.win32.keycodes[0x010] = GLFW_KEY_Q;
    229     _glfw.win32.keycodes[0x013] = GLFW_KEY_R;
    230     _glfw.win32.keycodes[0x01F] = GLFW_KEY_S;
    231     _glfw.win32.keycodes[0x014] = GLFW_KEY_T;
    232     _glfw.win32.keycodes[0x016] = GLFW_KEY_U;
    233     _glfw.win32.keycodes[0x02F] = GLFW_KEY_V;
    234     _glfw.win32.keycodes[0x011] = GLFW_KEY_W;
    235     _glfw.win32.keycodes[0x02D] = GLFW_KEY_X;
    236     _glfw.win32.keycodes[0x015] = GLFW_KEY_Y;
    237     _glfw.win32.keycodes[0x02C] = GLFW_KEY_Z;
    238 
    239     _glfw.win32.keycodes[0x028] = GLFW_KEY_APOSTROPHE;
    240     _glfw.win32.keycodes[0x02B] = GLFW_KEY_BACKSLASH;
    241     _glfw.win32.keycodes[0x033] = GLFW_KEY_COMMA;
    242     _glfw.win32.keycodes[0x00D] = GLFW_KEY_EQUAL;
    243     _glfw.win32.keycodes[0x029] = GLFW_KEY_GRAVE_ACCENT;
    244     _glfw.win32.keycodes[0x01A] = GLFW_KEY_LEFT_BRACKET;
    245     _glfw.win32.keycodes[0x00C] = GLFW_KEY_MINUS;
    246     _glfw.win32.keycodes[0x034] = GLFW_KEY_PERIOD;
    247     _glfw.win32.keycodes[0x01B] = GLFW_KEY_RIGHT_BRACKET;
    248     _glfw.win32.keycodes[0x027] = GLFW_KEY_SEMICOLON;
    249     _glfw.win32.keycodes[0x035] = GLFW_KEY_SLASH;
    250     _glfw.win32.keycodes[0x056] = GLFW_KEY_WORLD_2;
    251 
    252     _glfw.win32.keycodes[0x00E] = GLFW_KEY_BACKSPACE;
    253     _glfw.win32.keycodes[0x153] = GLFW_KEY_DELETE;
    254     _glfw.win32.keycodes[0x14F] = GLFW_KEY_END;
    255     _glfw.win32.keycodes[0x01C] = GLFW_KEY_ENTER;
    256     _glfw.win32.keycodes[0x001] = GLFW_KEY_ESCAPE;
    257     _glfw.win32.keycodes[0x147] = GLFW_KEY_HOME;
    258     _glfw.win32.keycodes[0x152] = GLFW_KEY_INSERT;
    259     _glfw.win32.keycodes[0x15D] = GLFW_KEY_MENU;
    260     _glfw.win32.keycodes[0x151] = GLFW_KEY_PAGE_DOWN;
    261     _glfw.win32.keycodes[0x149] = GLFW_KEY_PAGE_UP;
    262     _glfw.win32.keycodes[0x045] = GLFW_KEY_PAUSE;
    263     _glfw.win32.keycodes[0x146] = GLFW_KEY_PAUSE;
    264     _glfw.win32.keycodes[0x039] = GLFW_KEY_SPACE;
    265     _glfw.win32.keycodes[0x00F] = GLFW_KEY_TAB;
    266     _glfw.win32.keycodes[0x03A] = GLFW_KEY_CAPS_LOCK;
    267     _glfw.win32.keycodes[0x145] = GLFW_KEY_NUM_LOCK;
    268     _glfw.win32.keycodes[0x046] = GLFW_KEY_SCROLL_LOCK;
    269     _glfw.win32.keycodes[0x03B] = GLFW_KEY_F1;
    270     _glfw.win32.keycodes[0x03C] = GLFW_KEY_F2;
    271     _glfw.win32.keycodes[0x03D] = GLFW_KEY_F3;
    272     _glfw.win32.keycodes[0x03E] = GLFW_KEY_F4;
    273     _glfw.win32.keycodes[0x03F] = GLFW_KEY_F5;
    274     _glfw.win32.keycodes[0x040] = GLFW_KEY_F6;
    275     _glfw.win32.keycodes[0x041] = GLFW_KEY_F7;
    276     _glfw.win32.keycodes[0x042] = GLFW_KEY_F8;
    277     _glfw.win32.keycodes[0x043] = GLFW_KEY_F9;
    278     _glfw.win32.keycodes[0x044] = GLFW_KEY_F10;
    279     _glfw.win32.keycodes[0x057] = GLFW_KEY_F11;
    280     _glfw.win32.keycodes[0x058] = GLFW_KEY_F12;
    281     _glfw.win32.keycodes[0x064] = GLFW_KEY_F13;
    282     _glfw.win32.keycodes[0x065] = GLFW_KEY_F14;
    283     _glfw.win32.keycodes[0x066] = GLFW_KEY_F15;
    284     _glfw.win32.keycodes[0x067] = GLFW_KEY_F16;
    285     _glfw.win32.keycodes[0x068] = GLFW_KEY_F17;
    286     _glfw.win32.keycodes[0x069] = GLFW_KEY_F18;
    287     _glfw.win32.keycodes[0x06A] = GLFW_KEY_F19;
    288     _glfw.win32.keycodes[0x06B] = GLFW_KEY_F20;
    289     _glfw.win32.keycodes[0x06C] = GLFW_KEY_F21;
    290     _glfw.win32.keycodes[0x06D] = GLFW_KEY_F22;
    291     _glfw.win32.keycodes[0x06E] = GLFW_KEY_F23;
    292     _glfw.win32.keycodes[0x076] = GLFW_KEY_F24;
    293     _glfw.win32.keycodes[0x038] = GLFW_KEY_LEFT_ALT;
    294     _glfw.win32.keycodes[0x01D] = GLFW_KEY_LEFT_CONTROL;
    295     _glfw.win32.keycodes[0x02A] = GLFW_KEY_LEFT_SHIFT;
    296     _glfw.win32.keycodes[0x15B] = GLFW_KEY_LEFT_SUPER;
    297     _glfw.win32.keycodes[0x137] = GLFW_KEY_PRINT_SCREEN;
    298     _glfw.win32.keycodes[0x138] = GLFW_KEY_RIGHT_ALT;
    299     _glfw.win32.keycodes[0x11D] = GLFW_KEY_RIGHT_CONTROL;
    300     _glfw.win32.keycodes[0x036] = GLFW_KEY_RIGHT_SHIFT;
    301     _glfw.win32.keycodes[0x15C] = GLFW_KEY_RIGHT_SUPER;
    302     _glfw.win32.keycodes[0x150] = GLFW_KEY_DOWN;
    303     _glfw.win32.keycodes[0x14B] = GLFW_KEY_LEFT;
    304     _glfw.win32.keycodes[0x14D] = GLFW_KEY_RIGHT;
    305     _glfw.win32.keycodes[0x148] = GLFW_KEY_UP;
    306 
    307     _glfw.win32.keycodes[0x052] = GLFW_KEY_KP_0;
    308     _glfw.win32.keycodes[0x04F] = GLFW_KEY_KP_1;
    309     _glfw.win32.keycodes[0x050] = GLFW_KEY_KP_2;
    310     _glfw.win32.keycodes[0x051] = GLFW_KEY_KP_3;
    311     _glfw.win32.keycodes[0x04B] = GLFW_KEY_KP_4;
    312     _glfw.win32.keycodes[0x04C] = GLFW_KEY_KP_5;
    313     _glfw.win32.keycodes[0x04D] = GLFW_KEY_KP_6;
    314     _glfw.win32.keycodes[0x047] = GLFW_KEY_KP_7;
    315     _glfw.win32.keycodes[0x048] = GLFW_KEY_KP_8;
    316     _glfw.win32.keycodes[0x049] = GLFW_KEY_KP_9;
    317     _glfw.win32.keycodes[0x04E] = GLFW_KEY_KP_ADD;
    318     _glfw.win32.keycodes[0x053] = GLFW_KEY_KP_DECIMAL;
    319     _glfw.win32.keycodes[0x135] = GLFW_KEY_KP_DIVIDE;
    320     _glfw.win32.keycodes[0x11C] = GLFW_KEY_KP_ENTER;
    321     _glfw.win32.keycodes[0x059] = GLFW_KEY_KP_EQUAL;
    322     _glfw.win32.keycodes[0x037] = GLFW_KEY_KP_MULTIPLY;
    323     _glfw.win32.keycodes[0x04A] = GLFW_KEY_KP_SUBTRACT;
    324 
    325     for (scancode = 0;  scancode < 512;  scancode++)
    326     {
    327         if (_glfw.win32.keycodes[scancode] > 0)
    328             _glfw.win32.scancodes[_glfw.win32.keycodes[scancode]] = scancode;
    329     }
    330 }
    331 
    332 // Creates a dummy window for behind-the-scenes work
    333 //
    334 static GLFWbool createHelperWindow(void)
    335 {
    336     MSG msg;
    337 
    338     _glfw.win32.helperWindowHandle =
    339         CreateWindowExW(WS_EX_OVERLAPPEDWINDOW,
    340                         _GLFW_WNDCLASSNAME,
    341                         L"GLFW message window",
    342                         WS_CLIPSIBLINGS | WS_CLIPCHILDREN,
    343                         0, 0, 1, 1,
    344                         NULL, NULL,
    345                         GetModuleHandleW(NULL),
    346                         NULL);
    347 
    348     if (!_glfw.win32.helperWindowHandle)
    349     {
    350         _glfwInputErrorWin32(GLFW_PLATFORM_ERROR,
    351                              "Win32: Failed to create helper window");
    352         return GLFW_FALSE;
    353     }
    354 
    355     // HACK: The command to the first ShowWindow call is ignored if the parent
    356     //       process passed along a STARTUPINFO, so clear that with a no-op call
    357     ShowWindow(_glfw.win32.helperWindowHandle, SW_HIDE);
    358 
    359     // Register for HID device notifications
    360     {
    361         DEV_BROADCAST_DEVICEINTERFACE_W dbi;
    362         ZeroMemory(&dbi, sizeof(dbi));
    363         dbi.dbcc_size = sizeof(dbi);
    364         dbi.dbcc_devicetype = DBT_DEVTYP_DEVICEINTERFACE;
    365         dbi.dbcc_classguid = GUID_DEVINTERFACE_HID;
    366 
    367         _glfw.win32.deviceNotificationHandle =
    368             RegisterDeviceNotificationW(_glfw.win32.helperWindowHandle,
    369                                         (DEV_BROADCAST_HDR*) &dbi,
    370                                         DEVICE_NOTIFY_WINDOW_HANDLE);
    371     }
    372 
    373     while (PeekMessageW(&msg, _glfw.win32.helperWindowHandle, 0, 0, PM_REMOVE))
    374     {
    375         TranslateMessage(&msg);
    376         DispatchMessageW(&msg);
    377     }
    378 
    379    return GLFW_TRUE;
    380 }
    381 
    382 
    383 //////////////////////////////////////////////////////////////////////////
    384 //////                       GLFW internal API                      //////
    385 //////////////////////////////////////////////////////////////////////////
    386 
    387 // Returns a wide string version of the specified UTF-8 string
    388 //
    389 WCHAR* _glfwCreateWideStringFromUTF8Win32(const char* source)
    390 {
    391     WCHAR* target;
    392     int count;
    393 
    394     count = MultiByteToWideChar(CP_UTF8, 0, source, -1, NULL, 0);
    395     if (!count)
    396     {
    397         _glfwInputErrorWin32(GLFW_PLATFORM_ERROR,
    398                              "Win32: Failed to convert string from UTF-8");
    399         return NULL;
    400     }
    401 
    402     target = calloc(count, sizeof(WCHAR));
    403 
    404     if (!MultiByteToWideChar(CP_UTF8, 0, source, -1, target, count))
    405     {
    406         _glfwInputErrorWin32(GLFW_PLATFORM_ERROR,
    407                              "Win32: Failed to convert string from UTF-8");
    408         free(target);
    409         return NULL;
    410     }
    411 
    412     return target;
    413 }
    414 
    415 // Returns a UTF-8 string version of the specified wide string
    416 //
    417 char* _glfwCreateUTF8FromWideStringWin32(const WCHAR* source)
    418 {
    419     char* target;
    420     int size;
    421 
    422     size = WideCharToMultiByte(CP_UTF8, 0, source, -1, NULL, 0, NULL, NULL);
    423     if (!size)
    424     {
    425         _glfwInputErrorWin32(GLFW_PLATFORM_ERROR,
    426                              "Win32: Failed to convert string to UTF-8");
    427         return NULL;
    428     }
    429 
    430     target = calloc(size, 1);
    431 
    432     if (!WideCharToMultiByte(CP_UTF8, 0, source, -1, target, size, NULL, NULL))
    433     {
    434         _glfwInputErrorWin32(GLFW_PLATFORM_ERROR,
    435                              "Win32: Failed to convert string to UTF-8");
    436         free(target);
    437         return NULL;
    438     }
    439 
    440     return target;
    441 }
    442 
    443 // Reports the specified error, appending information about the last Win32 error
    444 //
    445 void _glfwInputErrorWin32(int error, const char* description)
    446 {
    447     WCHAR buffer[_GLFW_MESSAGE_SIZE] = L"";
    448     char message[_GLFW_MESSAGE_SIZE] = "";
    449 
    450     FormatMessageW(FORMAT_MESSAGE_FROM_SYSTEM |
    451                        FORMAT_MESSAGE_IGNORE_INSERTS |
    452                        FORMAT_MESSAGE_MAX_WIDTH_MASK,
    453                    NULL,
    454                    GetLastError() & 0xffff,
    455                    MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
    456                    buffer,
    457                    sizeof(buffer) / sizeof(WCHAR),
    458                    NULL);
    459     WideCharToMultiByte(CP_UTF8, 0, buffer, -1, message, sizeof(message), NULL, NULL);
    460 
    461     _glfwInputError(error, "%s: %s", description, message);
    462 }
    463 
    464 // Updates key names according to the current keyboard layout
    465 //
    466 void _glfwUpdateKeyNamesWin32(void)
    467 {
    468     int key;
    469     BYTE state[256] = {0};
    470 
    471     memset(_glfw.win32.keynames, 0, sizeof(_glfw.win32.keynames));
    472 
    473     for (key = GLFW_KEY_SPACE;  key <= GLFW_KEY_LAST;  key++)
    474     {
    475         UINT vk;
    476         int scancode, length;
    477         WCHAR chars[16];
    478 
    479         scancode = _glfw.win32.scancodes[key];
    480         if (scancode == -1)
    481             continue;
    482 
    483         if (key >= GLFW_KEY_KP_0 && key <= GLFW_KEY_KP_ADD)
    484         {
    485             const UINT vks[] = {
    486                 VK_NUMPAD0,  VK_NUMPAD1,  VK_NUMPAD2, VK_NUMPAD3,
    487                 VK_NUMPAD4,  VK_NUMPAD5,  VK_NUMPAD6, VK_NUMPAD7,
    488                 VK_NUMPAD8,  VK_NUMPAD9,  VK_DECIMAL, VK_DIVIDE,
    489                 VK_MULTIPLY, VK_SUBTRACT, VK_ADD
    490             };
    491 
    492             vk = vks[key - GLFW_KEY_KP_0];
    493         }
    494         else
    495             vk = MapVirtualKey(scancode, MAPVK_VSC_TO_VK);
    496 
    497         length = ToUnicode(vk, scancode, state,
    498                            chars, sizeof(chars) / sizeof(WCHAR),
    499                            0);
    500 
    501         if (length == -1)
    502         {
    503             length = ToUnicode(vk, scancode, state,
    504                                chars, sizeof(chars) / sizeof(WCHAR),
    505                                0);
    506         }
    507 
    508         if (length < 1)
    509             continue;
    510 
    511         WideCharToMultiByte(CP_UTF8, 0, chars, 1,
    512                             _glfw.win32.keynames[key],
    513                             sizeof(_glfw.win32.keynames[key]),
    514                             NULL, NULL);
    515     }
    516 }
    517 
    518 // Replacement for IsWindowsVersionOrGreater as MinGW lacks versionhelpers.h
    519 //
    520 BOOL _glfwIsWindowsVersionOrGreaterWin32(WORD major, WORD minor, WORD sp)
    521 {
    522     OSVERSIONINFOEXW osvi = { sizeof(osvi), major, minor, 0, 0, {0}, sp };
    523     DWORD mask = VER_MAJORVERSION | VER_MINORVERSION | VER_SERVICEPACKMAJOR;
    524     ULONGLONG cond = VerSetConditionMask(0, VER_MAJORVERSION, VER_GREATER_EQUAL);
    525     cond = VerSetConditionMask(cond, VER_MINORVERSION, VER_GREATER_EQUAL);
    526     cond = VerSetConditionMask(cond, VER_SERVICEPACKMAJOR, VER_GREATER_EQUAL);
    527     // HACK: Use RtlVerifyVersionInfo instead of VerifyVersionInfoW as the
    528     //       latter lies unless the user knew to embed a non-default manifest
    529     //       announcing support for Windows 10 via supportedOS GUID
    530     return RtlVerifyVersionInfo(&osvi, mask, cond) == 0;
    531 }
    532 
    533 // Checks whether we are on at least the specified build of Windows 10
    534 //
    535 BOOL _glfwIsWindows10BuildOrGreaterWin32(WORD build)
    536 {
    537     OSVERSIONINFOEXW osvi = { sizeof(osvi), 10, 0, build };
    538     DWORD mask = VER_MAJORVERSION | VER_MINORVERSION | VER_BUILDNUMBER;
    539     ULONGLONG cond = VerSetConditionMask(0, VER_MAJORVERSION, VER_GREATER_EQUAL);
    540     cond = VerSetConditionMask(cond, VER_MINORVERSION, VER_GREATER_EQUAL);
    541     cond = VerSetConditionMask(cond, VER_BUILDNUMBER, VER_GREATER_EQUAL);
    542     // HACK: Use RtlVerifyVersionInfo instead of VerifyVersionInfoW as the
    543     //       latter lies unless the user knew to embed a non-default manifest
    544     //       announcing support for Windows 10 via supportedOS GUID
    545     return RtlVerifyVersionInfo(&osvi, mask, cond) == 0;
    546 }
    547 
    548 
    549 //////////////////////////////////////////////////////////////////////////
    550 //////                       GLFW platform API                      //////
    551 //////////////////////////////////////////////////////////////////////////
    552 
    553 int _glfwPlatformInit(void)
    554 {
    555     // To make SetForegroundWindow work as we want, we need to fiddle
    556     // with the FOREGROUNDLOCKTIMEOUT system setting (we do this as early
    557     // as possible in the hope of still being the foreground process)
    558     SystemParametersInfoW(SPI_GETFOREGROUNDLOCKTIMEOUT, 0,
    559                           &_glfw.win32.foregroundLockTimeout, 0);
    560     SystemParametersInfoW(SPI_SETFOREGROUNDLOCKTIMEOUT, 0, UIntToPtr(0),
    561                           SPIF_SENDCHANGE);
    562 
    563     if (!loadLibraries())
    564         return GLFW_FALSE;
    565 
    566     createKeyTables();
    567     _glfwUpdateKeyNamesWin32();
    568 
    569     if (_glfwIsWindows10CreatorsUpdateOrGreaterWin32())
    570         SetProcessDpiAwarenessContext(DPI_AWARENESS_CONTEXT_PER_MONITOR_AWARE_V2);
    571     else if (IsWindows8Point1OrGreater())
    572         SetProcessDpiAwareness(PROCESS_PER_MONITOR_DPI_AWARE);
    573     else if (IsWindowsVistaOrGreater())
    574         SetProcessDPIAware();
    575 
    576     if (!_glfwRegisterWindowClassWin32())
    577         return GLFW_FALSE;
    578 
    579     if (!createHelperWindow())
    580         return GLFW_FALSE;
    581 
    582     _glfwInitTimerWin32();
    583     _glfwInitJoysticksWin32();
    584 
    585     _glfwPollMonitorsWin32();
    586     return GLFW_TRUE;
    587 }
    588 
    589 void _glfwPlatformTerminate(void)
    590 {
    591     if (_glfw.win32.deviceNotificationHandle)
    592         UnregisterDeviceNotification(_glfw.win32.deviceNotificationHandle);
    593 
    594     if (_glfw.win32.helperWindowHandle)
    595         DestroyWindow(_glfw.win32.helperWindowHandle);
    596 
    597     _glfwUnregisterWindowClassWin32();
    598 
    599     // Restore previous foreground lock timeout system setting
    600     SystemParametersInfoW(SPI_SETFOREGROUNDLOCKTIMEOUT, 0,
    601                           UIntToPtr(_glfw.win32.foregroundLockTimeout),
    602                           SPIF_SENDCHANGE);
    603 
    604     free(_glfw.win32.clipboardString);
    605     free(_glfw.win32.rawInput);
    606 
    607     _glfwTerminateWGL();
    608     _glfwTerminateEGL();
    609 
    610     _glfwTerminateJoysticksWin32();
    611 
    612     freeLibraries();
    613 }
    614 
    615 const char* _glfwPlatformGetVersionString(void)
    616 {
    617     return _GLFW_VERSION_NUMBER " Win32 WGL EGL OSMesa"
    618 #if defined(__MINGW32__)
    619         " MinGW"
    620 #elif defined(_MSC_VER)
    621         " VisualC"
    622 #endif
    623 #if defined(_GLFW_USE_HYBRID_HPG) || defined(_GLFW_USE_OPTIMUS_HPG)
    624         " hybrid-GPU"
    625 #endif
    626 #if defined(_GLFW_BUILD_DLL)
    627         " DLL"
    628 #endif
    629         ;
    630 }
    631