mirror of
https://github.com/kovidgoyal/kitty
synced 2026-07-25 17:52:02 +02:00
Remove windows glfw backend as it is unused
This commit is contained in:
627
glfw/win32_init.c
vendored
627
glfw/win32_init.c
vendored
@@ -1,627 +0,0 @@
|
|||||||
//========================================================================
|
|
||||||
// GLFW 3.3 Win32 - www.glfw.org
|
|
||||||
//------------------------------------------------------------------------
|
|
||||||
// Copyright (c) 2002-2006 Marcus Geelnard
|
|
||||||
// Copyright (c) 2006-2016 Camilla Löwy <elmindreda@glfw.org>
|
|
||||||
//
|
|
||||||
// This software is provided 'as-is', without any express or implied
|
|
||||||
// warranty. In no event will the authors be held liable for any damages
|
|
||||||
// arising from the use of this software.
|
|
||||||
//
|
|
||||||
// Permission is granted to anyone to use this software for any purpose,
|
|
||||||
// including commercial applications, and to alter it and redistribute it
|
|
||||||
// freely, subject to the following restrictions:
|
|
||||||
//
|
|
||||||
// 1. The origin of this software must not be misrepresented; you must not
|
|
||||||
// claim that you wrote the original software. If you use this software
|
|
||||||
// in a product, an acknowledgment in the product documentation would
|
|
||||||
// be appreciated but is not required.
|
|
||||||
//
|
|
||||||
// 2. Altered source versions must be plainly marked as such, and must not
|
|
||||||
// be misrepresented as being the original software.
|
|
||||||
//
|
|
||||||
// 3. This notice may not be removed or altered from any source
|
|
||||||
// distribution.
|
|
||||||
//
|
|
||||||
//========================================================================
|
|
||||||
|
|
||||||
#include "internal.h"
|
|
||||||
|
|
||||||
#include <stdlib.h>
|
|
||||||
#include <malloc.h>
|
|
||||||
|
|
||||||
static const GUID _glfw_GUID_DEVINTERFACE_HID =
|
|
||||||
{0x4d1e55b2,0xf16f,0x11cf,{0x88,0xcb,0x00,0x11,0x11,0x00,0x00,0x30}};
|
|
||||||
|
|
||||||
#define GUID_DEVINTERFACE_HID _glfw_GUID_DEVINTERFACE_HID
|
|
||||||
|
|
||||||
#if defined(_GLFW_USE_HYBRID_HPG) || defined(_GLFW_USE_OPTIMUS_HPG)
|
|
||||||
|
|
||||||
// Executables (but not DLLs) exporting this symbol with this value will be
|
|
||||||
// automatically directed to the high-performance GPU on Nvidia Optimus systems
|
|
||||||
// with up-to-date drivers
|
|
||||||
//
|
|
||||||
__declspec(dllexport) DWORD NvOptimusEnablement = 1;
|
|
||||||
|
|
||||||
// Executables (but not DLLs) exporting this symbol with this value will be
|
|
||||||
// automatically directed to the high-performance GPU on AMD PowerXpress systems
|
|
||||||
// with up-to-date drivers
|
|
||||||
//
|
|
||||||
__declspec(dllexport) int AmdPowerXpressRequestHighPerformance = 1;
|
|
||||||
|
|
||||||
#endif // _GLFW_USE_HYBRID_HPG
|
|
||||||
|
|
||||||
#if defined(_GLFW_BUILD_DLL)
|
|
||||||
|
|
||||||
// GLFW DLL entry point
|
|
||||||
//
|
|
||||||
BOOL WINAPI DllMain(HINSTANCE instance, DWORD reason, LPVOID reserved)
|
|
||||||
{
|
|
||||||
return TRUE;
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif // _GLFW_BUILD_DLL
|
|
||||||
|
|
||||||
// Load necessary libraries (DLLs)
|
|
||||||
//
|
|
||||||
static GLFWbool loadLibraries(void)
|
|
||||||
{
|
|
||||||
_glfw.win32.winmm.instance = LoadLibraryA("winmm.dll");
|
|
||||||
if (!_glfw.win32.winmm.instance)
|
|
||||||
{
|
|
||||||
_glfwInputErrorWin32(GLFW_PLATFORM_ERROR,
|
|
||||||
"Win32: Failed to load winmm.dll");
|
|
||||||
return GLFW_FALSE;
|
|
||||||
}
|
|
||||||
|
|
||||||
_glfw.win32.winmm.GetTime = (PFN_timeGetTime)
|
|
||||||
GetProcAddress(_glfw.win32.winmm.instance, "timeGetTime");
|
|
||||||
|
|
||||||
_glfw.win32.user32.instance = LoadLibraryA("user32.dll");
|
|
||||||
if (!_glfw.win32.user32.instance)
|
|
||||||
{
|
|
||||||
_glfwInputErrorWin32(GLFW_PLATFORM_ERROR,
|
|
||||||
"Win32: Failed to load user32.dll");
|
|
||||||
return GLFW_FALSE;
|
|
||||||
}
|
|
||||||
|
|
||||||
_glfw.win32.user32.SetProcessDPIAware_ = (PFN_SetProcessDPIAware)
|
|
||||||
GetProcAddress(_glfw.win32.user32.instance, "SetProcessDPIAware");
|
|
||||||
_glfw.win32.user32.ChangeWindowMessageFilterEx_ = (PFN_ChangeWindowMessageFilterEx)
|
|
||||||
GetProcAddress(_glfw.win32.user32.instance, "ChangeWindowMessageFilterEx");
|
|
||||||
_glfw.win32.user32.EnableNonClientDpiScaling_ = (PFN_EnableNonClientDpiScaling)
|
|
||||||
GetProcAddress(_glfw.win32.user32.instance, "EnableNonClientDpiScaling");
|
|
||||||
_glfw.win32.user32.SetProcessDpiAwarenessContext_ = (PFN_SetProcessDpiAwarenessContext)
|
|
||||||
GetProcAddress(_glfw.win32.user32.instance, "SetProcessDpiAwarenessContext");
|
|
||||||
_glfw.win32.user32.GetDpiForWindow_ = (PFN_GetDpiForWindow)
|
|
||||||
GetProcAddress(_glfw.win32.user32.instance, "GetDpiForWindow");
|
|
||||||
_glfw.win32.user32.AdjustWindowRectExForDpi_ = (PFN_AdjustWindowRectExForDpi)
|
|
||||||
GetProcAddress(_glfw.win32.user32.instance, "AdjustWindowRectExForDpi");
|
|
||||||
|
|
||||||
_glfw.win32.dinput8.instance = LoadLibraryA("dinput8.dll");
|
|
||||||
if (_glfw.win32.dinput8.instance)
|
|
||||||
{
|
|
||||||
_glfw.win32.dinput8.Create = (PFN_DirectInput8Create)
|
|
||||||
GetProcAddress(_glfw.win32.dinput8.instance, "DirectInput8Create");
|
|
||||||
}
|
|
||||||
|
|
||||||
{
|
|
||||||
int i;
|
|
||||||
const char* names[] =
|
|
||||||
{
|
|
||||||
"xinput1_4.dll",
|
|
||||||
"xinput1_3.dll",
|
|
||||||
"xinput9_1_0.dll",
|
|
||||||
"xinput1_2.dll",
|
|
||||||
"xinput1_1.dll",
|
|
||||||
NULL
|
|
||||||
};
|
|
||||||
|
|
||||||
for (i = 0; names[i]; i++)
|
|
||||||
{
|
|
||||||
_glfw.win32.xinput.instance = LoadLibraryA(names[i]);
|
|
||||||
if (_glfw.win32.xinput.instance)
|
|
||||||
{
|
|
||||||
_glfw.win32.xinput.GetCapabilities = (PFN_XInputGetCapabilities)
|
|
||||||
GetProcAddress(_glfw.win32.xinput.instance, "XInputGetCapabilities");
|
|
||||||
_glfw.win32.xinput.GetState = (PFN_XInputGetState)
|
|
||||||
GetProcAddress(_glfw.win32.xinput.instance, "XInputGetState");
|
|
||||||
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
_glfw.win32.dwmapi.instance = LoadLibraryA("dwmapi.dll");
|
|
||||||
if (_glfw.win32.dwmapi.instance)
|
|
||||||
{
|
|
||||||
_glfw.win32.dwmapi.IsCompositionEnabled = (PFN_DwmIsCompositionEnabled)
|
|
||||||
GetProcAddress(_glfw.win32.dwmapi.instance, "DwmIsCompositionEnabled");
|
|
||||||
_glfw.win32.dwmapi.Flush = (PFN_DwmFlush)
|
|
||||||
GetProcAddress(_glfw.win32.dwmapi.instance, "DwmFlush");
|
|
||||||
_glfw.win32.dwmapi.EnableBlurBehindWindow = (PFN_DwmEnableBlurBehindWindow)
|
|
||||||
GetProcAddress(_glfw.win32.dwmapi.instance, "DwmEnableBlurBehindWindow");
|
|
||||||
}
|
|
||||||
|
|
||||||
_glfw.win32.shcore.instance = LoadLibraryA("shcore.dll");
|
|
||||||
if (_glfw.win32.shcore.instance)
|
|
||||||
{
|
|
||||||
_glfw.win32.shcore.SetProcessDpiAwareness_ = (PFN_SetProcessDpiAwareness)
|
|
||||||
GetProcAddress(_glfw.win32.shcore.instance, "SetProcessDpiAwareness");
|
|
||||||
_glfw.win32.shcore.GetDpiForMonitor_ = (PFN_GetDpiForMonitor)
|
|
||||||
GetProcAddress(_glfw.win32.shcore.instance, "GetDpiForMonitor");
|
|
||||||
}
|
|
||||||
|
|
||||||
_glfw.win32.ntdll.instance = LoadLibraryA("ntdll.dll");
|
|
||||||
if (_glfw.win32.ntdll.instance)
|
|
||||||
{
|
|
||||||
_glfw.win32.ntdll.RtlVerifyVersionInfo_ = (PFN_RtlVerifyVersionInfo)
|
|
||||||
GetProcAddress(_glfw.win32.ntdll.instance, "RtlVerifyVersionInfo");
|
|
||||||
}
|
|
||||||
|
|
||||||
return GLFW_TRUE;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Unload used libraries (DLLs)
|
|
||||||
//
|
|
||||||
static void freeLibraries(void)
|
|
||||||
{
|
|
||||||
if (_glfw.win32.xinput.instance)
|
|
||||||
FreeLibrary(_glfw.win32.xinput.instance);
|
|
||||||
|
|
||||||
if (_glfw.win32.dinput8.instance)
|
|
||||||
FreeLibrary(_glfw.win32.dinput8.instance);
|
|
||||||
|
|
||||||
if (_glfw.win32.winmm.instance)
|
|
||||||
FreeLibrary(_glfw.win32.winmm.instance);
|
|
||||||
|
|
||||||
if (_glfw.win32.user32.instance)
|
|
||||||
FreeLibrary(_glfw.win32.user32.instance);
|
|
||||||
|
|
||||||
if (_glfw.win32.dwmapi.instance)
|
|
||||||
FreeLibrary(_glfw.win32.dwmapi.instance);
|
|
||||||
|
|
||||||
if (_glfw.win32.shcore.instance)
|
|
||||||
FreeLibrary(_glfw.win32.shcore.instance);
|
|
||||||
|
|
||||||
if (_glfw.win32.ntdll.instance)
|
|
||||||
FreeLibrary(_glfw.win32.ntdll.instance);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Create key code translation tables
|
|
||||||
//
|
|
||||||
static void createKeyTables(void)
|
|
||||||
{
|
|
||||||
int scancode;
|
|
||||||
|
|
||||||
memset(_glfw.win32.keycodes, -1, sizeof(_glfw.win32.keycodes));
|
|
||||||
memset(_glfw.win32.scancodes, -1, sizeof(_glfw.win32.scancodes));
|
|
||||||
|
|
||||||
_glfw.win32.keycodes[0x00B] = GLFW_KEY_0;
|
|
||||||
_glfw.win32.keycodes[0x002] = GLFW_KEY_1;
|
|
||||||
_glfw.win32.keycodes[0x003] = GLFW_KEY_2;
|
|
||||||
_glfw.win32.keycodes[0x004] = GLFW_KEY_3;
|
|
||||||
_glfw.win32.keycodes[0x005] = GLFW_KEY_4;
|
|
||||||
_glfw.win32.keycodes[0x006] = GLFW_KEY_5;
|
|
||||||
_glfw.win32.keycodes[0x007] = GLFW_KEY_6;
|
|
||||||
_glfw.win32.keycodes[0x008] = GLFW_KEY_7;
|
|
||||||
_glfw.win32.keycodes[0x009] = GLFW_KEY_8;
|
|
||||||
_glfw.win32.keycodes[0x00A] = GLFW_KEY_9;
|
|
||||||
_glfw.win32.keycodes[0x01E] = GLFW_KEY_A;
|
|
||||||
_glfw.win32.keycodes[0x030] = GLFW_KEY_B;
|
|
||||||
_glfw.win32.keycodes[0x02E] = GLFW_KEY_C;
|
|
||||||
_glfw.win32.keycodes[0x020] = GLFW_KEY_D;
|
|
||||||
_glfw.win32.keycodes[0x012] = GLFW_KEY_E;
|
|
||||||
_glfw.win32.keycodes[0x021] = GLFW_KEY_F;
|
|
||||||
_glfw.win32.keycodes[0x022] = GLFW_KEY_G;
|
|
||||||
_glfw.win32.keycodes[0x023] = GLFW_KEY_H;
|
|
||||||
_glfw.win32.keycodes[0x017] = GLFW_KEY_I;
|
|
||||||
_glfw.win32.keycodes[0x024] = GLFW_KEY_J;
|
|
||||||
_glfw.win32.keycodes[0x025] = GLFW_KEY_K;
|
|
||||||
_glfw.win32.keycodes[0x026] = GLFW_KEY_L;
|
|
||||||
_glfw.win32.keycodes[0x032] = GLFW_KEY_M;
|
|
||||||
_glfw.win32.keycodes[0x031] = GLFW_KEY_N;
|
|
||||||
_glfw.win32.keycodes[0x018] = GLFW_KEY_O;
|
|
||||||
_glfw.win32.keycodes[0x019] = GLFW_KEY_P;
|
|
||||||
_glfw.win32.keycodes[0x010] = GLFW_KEY_Q;
|
|
||||||
_glfw.win32.keycodes[0x013] = GLFW_KEY_R;
|
|
||||||
_glfw.win32.keycodes[0x01F] = GLFW_KEY_S;
|
|
||||||
_glfw.win32.keycodes[0x014] = GLFW_KEY_T;
|
|
||||||
_glfw.win32.keycodes[0x016] = GLFW_KEY_U;
|
|
||||||
_glfw.win32.keycodes[0x02F] = GLFW_KEY_V;
|
|
||||||
_glfw.win32.keycodes[0x011] = GLFW_KEY_W;
|
|
||||||
_glfw.win32.keycodes[0x02D] = GLFW_KEY_X;
|
|
||||||
_glfw.win32.keycodes[0x015] = GLFW_KEY_Y;
|
|
||||||
_glfw.win32.keycodes[0x02C] = GLFW_KEY_Z;
|
|
||||||
|
|
||||||
_glfw.win32.keycodes[0x028] = GLFW_KEY_APOSTROPHE;
|
|
||||||
_glfw.win32.keycodes[0x02B] = GLFW_KEY_BACKSLASH;
|
|
||||||
_glfw.win32.keycodes[0x033] = GLFW_KEY_COMMA;
|
|
||||||
_glfw.win32.keycodes[0x00D] = GLFW_KEY_EQUAL;
|
|
||||||
_glfw.win32.keycodes[0x029] = GLFW_KEY_GRAVE_ACCENT;
|
|
||||||
_glfw.win32.keycodes[0x01A] = GLFW_KEY_LEFT_BRACKET;
|
|
||||||
_glfw.win32.keycodes[0x00C] = GLFW_KEY_MINUS;
|
|
||||||
_glfw.win32.keycodes[0x034] = GLFW_KEY_PERIOD;
|
|
||||||
_glfw.win32.keycodes[0x01B] = GLFW_KEY_RIGHT_BRACKET;
|
|
||||||
_glfw.win32.keycodes[0x027] = GLFW_KEY_SEMICOLON;
|
|
||||||
_glfw.win32.keycodes[0x035] = GLFW_KEY_SLASH;
|
|
||||||
_glfw.win32.keycodes[0x056] = GLFW_KEY_WORLD_2;
|
|
||||||
|
|
||||||
_glfw.win32.keycodes[0x00E] = GLFW_KEY_BACKSPACE;
|
|
||||||
_glfw.win32.keycodes[0x153] = GLFW_KEY_DELETE;
|
|
||||||
_glfw.win32.keycodes[0x14F] = GLFW_KEY_END;
|
|
||||||
_glfw.win32.keycodes[0x01C] = GLFW_KEY_ENTER;
|
|
||||||
_glfw.win32.keycodes[0x001] = GLFW_KEY_ESCAPE;
|
|
||||||
_glfw.win32.keycodes[0x147] = GLFW_KEY_HOME;
|
|
||||||
_glfw.win32.keycodes[0x152] = GLFW_KEY_INSERT;
|
|
||||||
_glfw.win32.keycodes[0x15D] = GLFW_KEY_MENU;
|
|
||||||
_glfw.win32.keycodes[0x151] = GLFW_KEY_PAGE_DOWN;
|
|
||||||
_glfw.win32.keycodes[0x149] = GLFW_KEY_PAGE_UP;
|
|
||||||
_glfw.win32.keycodes[0x045] = GLFW_KEY_PAUSE;
|
|
||||||
_glfw.win32.keycodes[0x146] = GLFW_KEY_PAUSE;
|
|
||||||
_glfw.win32.keycodes[0x039] = GLFW_KEY_SPACE;
|
|
||||||
_glfw.win32.keycodes[0x00F] = GLFW_KEY_TAB;
|
|
||||||
_glfw.win32.keycodes[0x03A] = GLFW_KEY_CAPS_LOCK;
|
|
||||||
_glfw.win32.keycodes[0x145] = GLFW_KEY_NUM_LOCK;
|
|
||||||
_glfw.win32.keycodes[0x046] = GLFW_KEY_SCROLL_LOCK;
|
|
||||||
_glfw.win32.keycodes[0x03B] = GLFW_KEY_F1;
|
|
||||||
_glfw.win32.keycodes[0x03C] = GLFW_KEY_F2;
|
|
||||||
_glfw.win32.keycodes[0x03D] = GLFW_KEY_F3;
|
|
||||||
_glfw.win32.keycodes[0x03E] = GLFW_KEY_F4;
|
|
||||||
_glfw.win32.keycodes[0x03F] = GLFW_KEY_F5;
|
|
||||||
_glfw.win32.keycodes[0x040] = GLFW_KEY_F6;
|
|
||||||
_glfw.win32.keycodes[0x041] = GLFW_KEY_F7;
|
|
||||||
_glfw.win32.keycodes[0x042] = GLFW_KEY_F8;
|
|
||||||
_glfw.win32.keycodes[0x043] = GLFW_KEY_F9;
|
|
||||||
_glfw.win32.keycodes[0x044] = GLFW_KEY_F10;
|
|
||||||
_glfw.win32.keycodes[0x057] = GLFW_KEY_F11;
|
|
||||||
_glfw.win32.keycodes[0x058] = GLFW_KEY_F12;
|
|
||||||
_glfw.win32.keycodes[0x064] = GLFW_KEY_F13;
|
|
||||||
_glfw.win32.keycodes[0x065] = GLFW_KEY_F14;
|
|
||||||
_glfw.win32.keycodes[0x066] = GLFW_KEY_F15;
|
|
||||||
_glfw.win32.keycodes[0x067] = GLFW_KEY_F16;
|
|
||||||
_glfw.win32.keycodes[0x068] = GLFW_KEY_F17;
|
|
||||||
_glfw.win32.keycodes[0x069] = GLFW_KEY_F18;
|
|
||||||
_glfw.win32.keycodes[0x06A] = GLFW_KEY_F19;
|
|
||||||
_glfw.win32.keycodes[0x06B] = GLFW_KEY_F20;
|
|
||||||
_glfw.win32.keycodes[0x06C] = GLFW_KEY_F21;
|
|
||||||
_glfw.win32.keycodes[0x06D] = GLFW_KEY_F22;
|
|
||||||
_glfw.win32.keycodes[0x06E] = GLFW_KEY_F23;
|
|
||||||
_glfw.win32.keycodes[0x076] = GLFW_KEY_F24;
|
|
||||||
_glfw.win32.keycodes[0x038] = GLFW_KEY_LEFT_ALT;
|
|
||||||
_glfw.win32.keycodes[0x01D] = GLFW_KEY_LEFT_CONTROL;
|
|
||||||
_glfw.win32.keycodes[0x02A] = GLFW_KEY_LEFT_SHIFT;
|
|
||||||
_glfw.win32.keycodes[0x15B] = GLFW_KEY_LEFT_SUPER;
|
|
||||||
_glfw.win32.keycodes[0x137] = GLFW_KEY_PRINT_SCREEN;
|
|
||||||
_glfw.win32.keycodes[0x138] = GLFW_KEY_RIGHT_ALT;
|
|
||||||
_glfw.win32.keycodes[0x11D] = GLFW_KEY_RIGHT_CONTROL;
|
|
||||||
_glfw.win32.keycodes[0x036] = GLFW_KEY_RIGHT_SHIFT;
|
|
||||||
_glfw.win32.keycodes[0x15C] = GLFW_KEY_RIGHT_SUPER;
|
|
||||||
_glfw.win32.keycodes[0x150] = GLFW_KEY_DOWN;
|
|
||||||
_glfw.win32.keycodes[0x14B] = GLFW_KEY_LEFT;
|
|
||||||
_glfw.win32.keycodes[0x14D] = GLFW_KEY_RIGHT;
|
|
||||||
_glfw.win32.keycodes[0x148] = GLFW_KEY_UP;
|
|
||||||
|
|
||||||
_glfw.win32.keycodes[0x052] = GLFW_KEY_KP_0;
|
|
||||||
_glfw.win32.keycodes[0x04F] = GLFW_KEY_KP_1;
|
|
||||||
_glfw.win32.keycodes[0x050] = GLFW_KEY_KP_2;
|
|
||||||
_glfw.win32.keycodes[0x051] = GLFW_KEY_KP_3;
|
|
||||||
_glfw.win32.keycodes[0x04B] = GLFW_KEY_KP_4;
|
|
||||||
_glfw.win32.keycodes[0x04C] = GLFW_KEY_KP_5;
|
|
||||||
_glfw.win32.keycodes[0x04D] = GLFW_KEY_KP_6;
|
|
||||||
_glfw.win32.keycodes[0x047] = GLFW_KEY_KP_7;
|
|
||||||
_glfw.win32.keycodes[0x048] = GLFW_KEY_KP_8;
|
|
||||||
_glfw.win32.keycodes[0x049] = GLFW_KEY_KP_9;
|
|
||||||
_glfw.win32.keycodes[0x04E] = GLFW_KEY_KP_ADD;
|
|
||||||
_glfw.win32.keycodes[0x053] = GLFW_KEY_KP_DECIMAL;
|
|
||||||
_glfw.win32.keycodes[0x135] = GLFW_KEY_KP_DIVIDE;
|
|
||||||
_glfw.win32.keycodes[0x11C] = GLFW_KEY_KP_ENTER;
|
|
||||||
_glfw.win32.keycodes[0x059] = GLFW_KEY_KP_EQUAL;
|
|
||||||
_glfw.win32.keycodes[0x037] = GLFW_KEY_KP_MULTIPLY;
|
|
||||||
_glfw.win32.keycodes[0x04A] = GLFW_KEY_KP_SUBTRACT;
|
|
||||||
|
|
||||||
for (scancode = 0; scancode < 512; scancode++)
|
|
||||||
{
|
|
||||||
if (_glfw.win32.keycodes[scancode] > 0)
|
|
||||||
_glfw.win32.scancodes[_glfw.win32.keycodes[scancode]] = scancode;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Creates a dummy window for behind-the-scenes work
|
|
||||||
//
|
|
||||||
static HWND createHelperWindow(void)
|
|
||||||
{
|
|
||||||
MSG msg;
|
|
||||||
HWND window = CreateWindowExW(WS_EX_OVERLAPPEDWINDOW,
|
|
||||||
_GLFW_WNDCLASSNAME,
|
|
||||||
L"GLFW message window",
|
|
||||||
WS_CLIPSIBLINGS | WS_CLIPCHILDREN,
|
|
||||||
0, 0, 1, 1,
|
|
||||||
NULL, NULL,
|
|
||||||
GetModuleHandleW(NULL),
|
|
||||||
NULL);
|
|
||||||
if (!window)
|
|
||||||
{
|
|
||||||
_glfwInputErrorWin32(GLFW_PLATFORM_ERROR,
|
|
||||||
"Win32: Failed to create helper window");
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
// HACK: The command to the first ShowWindow call is ignored if the parent
|
|
||||||
// process passed along a STARTUPINFO, so clear that with a no-op call
|
|
||||||
ShowWindow(window, SW_HIDE);
|
|
||||||
|
|
||||||
// Register for HID device notifications
|
|
||||||
{
|
|
||||||
DEV_BROADCAST_DEVICEINTERFACE_W dbi;
|
|
||||||
ZeroMemory(&dbi, sizeof(dbi));
|
|
||||||
dbi.dbcc_size = sizeof(dbi);
|
|
||||||
dbi.dbcc_devicetype = DBT_DEVTYP_DEVICEINTERFACE;
|
|
||||||
dbi.dbcc_classguid = GUID_DEVINTERFACE_HID;
|
|
||||||
|
|
||||||
_glfw.win32.deviceNotificationHandle =
|
|
||||||
RegisterDeviceNotificationW(window,
|
|
||||||
(DEV_BROADCAST_HDR*) &dbi,
|
|
||||||
DEVICE_NOTIFY_WINDOW_HANDLE);
|
|
||||||
}
|
|
||||||
|
|
||||||
while (PeekMessageW(&msg, _glfw.win32.helperWindowHandle, 0, 0, PM_REMOVE))
|
|
||||||
{
|
|
||||||
TranslateMessage(&msg);
|
|
||||||
DispatchMessageW(&msg);
|
|
||||||
}
|
|
||||||
|
|
||||||
return window;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
//////////////////////////////////////////////////////////////////////////
|
|
||||||
////// GLFW internal API //////
|
|
||||||
//////////////////////////////////////////////////////////////////////////
|
|
||||||
|
|
||||||
// Returns a wide string version of the specified UTF-8 string
|
|
||||||
//
|
|
||||||
WCHAR* _glfwCreateWideStringFromUTF8Win32(const char* source)
|
|
||||||
{
|
|
||||||
WCHAR* target;
|
|
||||||
int count;
|
|
||||||
|
|
||||||
count = MultiByteToWideChar(CP_UTF8, 0, source, -1, NULL, 0);
|
|
||||||
if (!count)
|
|
||||||
{
|
|
||||||
_glfwInputErrorWin32(GLFW_PLATFORM_ERROR,
|
|
||||||
"Win32: Failed to convert string from UTF-8");
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
target = calloc(count, sizeof(WCHAR));
|
|
||||||
|
|
||||||
if (!MultiByteToWideChar(CP_UTF8, 0, source, -1, target, count))
|
|
||||||
{
|
|
||||||
_glfwInputErrorWin32(GLFW_PLATFORM_ERROR,
|
|
||||||
"Win32: Failed to convert string from UTF-8");
|
|
||||||
free(target);
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
return target;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Returns a UTF-8 string version of the specified wide string
|
|
||||||
//
|
|
||||||
char* _glfwCreateUTF8FromWideStringWin32(const WCHAR* source)
|
|
||||||
{
|
|
||||||
char* target;
|
|
||||||
int size;
|
|
||||||
|
|
||||||
size = WideCharToMultiByte(CP_UTF8, 0, source, -1, NULL, 0, NULL, NULL);
|
|
||||||
if (!size)
|
|
||||||
{
|
|
||||||
_glfwInputErrorWin32(GLFW_PLATFORM_ERROR,
|
|
||||||
"Win32: Failed to convert string to UTF-8");
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
target = calloc(size, 1);
|
|
||||||
|
|
||||||
if (!WideCharToMultiByte(CP_UTF8, 0, source, -1, target, size, NULL, NULL))
|
|
||||||
{
|
|
||||||
_glfwInputErrorWin32(GLFW_PLATFORM_ERROR,
|
|
||||||
"Win32: Failed to convert string to UTF-8");
|
|
||||||
free(target);
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
return target;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Reports the specified error, appending information about the last Win32 error
|
|
||||||
//
|
|
||||||
void _glfwInputErrorWin32(int error, const char* description)
|
|
||||||
{
|
|
||||||
WCHAR buffer[_GLFW_MESSAGE_SIZE] = L"";
|
|
||||||
char message[_GLFW_MESSAGE_SIZE] = "";
|
|
||||||
|
|
||||||
FormatMessageW(FORMAT_MESSAGE_FROM_SYSTEM |
|
|
||||||
FORMAT_MESSAGE_IGNORE_INSERTS |
|
|
||||||
FORMAT_MESSAGE_MAX_WIDTH_MASK,
|
|
||||||
NULL,
|
|
||||||
GetLastError() & 0xffff,
|
|
||||||
MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
|
|
||||||
buffer,
|
|
||||||
sizeof(buffer),
|
|
||||||
NULL);
|
|
||||||
WideCharToMultiByte(CP_UTF8, 0, buffer, -1, message, sizeof(message), NULL, NULL);
|
|
||||||
|
|
||||||
_glfwInputError(error, "%s: %s", description, message);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Updates key names according to the current keyboard layout
|
|
||||||
//
|
|
||||||
void _glfwUpdateKeyNamesWin32(void)
|
|
||||||
{
|
|
||||||
int key;
|
|
||||||
BYTE state[256] = {0};
|
|
||||||
|
|
||||||
memset(_glfw.win32.keynames, 0, sizeof(_glfw.win32.keynames));
|
|
||||||
|
|
||||||
for (key = GLFW_KEY_SPACE; key <= GLFW_KEY_LAST; key++)
|
|
||||||
{
|
|
||||||
UINT vk;
|
|
||||||
int scancode, length;
|
|
||||||
WCHAR chars[16];
|
|
||||||
|
|
||||||
scancode = _glfw.win32.scancodes[key];
|
|
||||||
if (scancode == -1)
|
|
||||||
continue;
|
|
||||||
|
|
||||||
if (key >= GLFW_KEY_KP_0 && key <= GLFW_KEY_KP_ADD)
|
|
||||||
{
|
|
||||||
const UINT vks[] = {
|
|
||||||
VK_NUMPAD0, VK_NUMPAD1, VK_NUMPAD2, VK_NUMPAD3,
|
|
||||||
VK_NUMPAD4, VK_NUMPAD5, VK_NUMPAD6, VK_NUMPAD7,
|
|
||||||
VK_NUMPAD8, VK_NUMPAD9, VK_DECIMAL, VK_DIVIDE,
|
|
||||||
VK_MULTIPLY, VK_SUBTRACT, VK_ADD
|
|
||||||
};
|
|
||||||
|
|
||||||
vk = vks[key - GLFW_KEY_KP_0];
|
|
||||||
}
|
|
||||||
else
|
|
||||||
vk = MapVirtualKey(scancode, MAPVK_VSC_TO_VK);
|
|
||||||
|
|
||||||
length = ToUnicode(vk, scancode, state,
|
|
||||||
chars, sizeof(chars) / sizeof(WCHAR),
|
|
||||||
0);
|
|
||||||
|
|
||||||
if (length == -1)
|
|
||||||
{
|
|
||||||
length = ToUnicode(vk, scancode, state,
|
|
||||||
chars, sizeof(chars) / sizeof(WCHAR),
|
|
||||||
0);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (length < 1)
|
|
||||||
continue;
|
|
||||||
|
|
||||||
WideCharToMultiByte(CP_UTF8, 0, chars, 1,
|
|
||||||
_glfw.win32.keynames[key],
|
|
||||||
sizeof(_glfw.win32.keynames[key]),
|
|
||||||
NULL, NULL);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Replacement for IsWindowsVersionOrGreater as MinGW lacks versionhelpers.h
|
|
||||||
//
|
|
||||||
BOOL _glfwIsWindowsVersionOrGreaterWin32(WORD major, WORD minor, WORD sp)
|
|
||||||
{
|
|
||||||
OSVERSIONINFOEXW osvi = { sizeof(osvi), major, minor, 0, 0, {0}, sp };
|
|
||||||
DWORD mask = VER_MAJORVERSION | VER_MINORVERSION | VER_SERVICEPACKMAJOR;
|
|
||||||
ULONGLONG cond = VerSetConditionMask(0, VER_MAJORVERSION, VER_GREATER_EQUAL);
|
|
||||||
cond = VerSetConditionMask(cond, VER_MINORVERSION, VER_GREATER_EQUAL);
|
|
||||||
cond = VerSetConditionMask(cond, VER_SERVICEPACKMAJOR, VER_GREATER_EQUAL);
|
|
||||||
// HACK: Use RtlVerifyVersionInfo instead of VerifyVersionInfoW as the
|
|
||||||
// latter lies unless the user knew to embedd a non-default manifest
|
|
||||||
// announcing support for Windows 10 via supportedOS GUID
|
|
||||||
return RtlVerifyVersionInfo(&osvi, mask, cond) == 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Checks whether we are on at least the specified build of Windows 10
|
|
||||||
//
|
|
||||||
BOOL _glfwIsWindows10BuildOrGreaterWin32(WORD build)
|
|
||||||
{
|
|
||||||
OSVERSIONINFOEXW osvi = { sizeof(osvi), 10, 0, build };
|
|
||||||
DWORD mask = VER_MAJORVERSION | VER_MINORVERSION | VER_BUILDNUMBER;
|
|
||||||
ULONGLONG cond = VerSetConditionMask(0, VER_MAJORVERSION, VER_GREATER_EQUAL);
|
|
||||||
cond = VerSetConditionMask(cond, VER_MINORVERSION, VER_GREATER_EQUAL);
|
|
||||||
cond = VerSetConditionMask(cond, VER_BUILDNUMBER, VER_GREATER_EQUAL);
|
|
||||||
// HACK: Use RtlVerifyVersionInfo instead of VerifyVersionInfoW as the
|
|
||||||
// latter lies unless the user knew to embedd a non-default manifest
|
|
||||||
// announcing support for Windows 10 via supportedOS GUID
|
|
||||||
return RtlVerifyVersionInfo(&osvi, mask, cond) == 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
//////////////////////////////////////////////////////////////////////////
|
|
||||||
////// GLFW platform API //////
|
|
||||||
//////////////////////////////////////////////////////////////////////////
|
|
||||||
|
|
||||||
int _glfwPlatformInit(void)
|
|
||||||
{
|
|
||||||
// To make SetForegroundWindow work as we want, we need to fiddle
|
|
||||||
// with the FOREGROUNDLOCKTIMEOUT system setting (we do this as early
|
|
||||||
// as possible in the hope of still being the foreground process)
|
|
||||||
SystemParametersInfoW(SPI_GETFOREGROUNDLOCKTIMEOUT, 0,
|
|
||||||
&_glfw.win32.foregroundLockTimeout, 0);
|
|
||||||
SystemParametersInfoW(SPI_SETFOREGROUNDLOCKTIMEOUT, 0, UIntToPtr(0),
|
|
||||||
SPIF_SENDCHANGE);
|
|
||||||
|
|
||||||
if (!loadLibraries())
|
|
||||||
return GLFW_FALSE;
|
|
||||||
|
|
||||||
createKeyTables();
|
|
||||||
_glfwUpdateKeyNamesWin32();
|
|
||||||
|
|
||||||
if (_glfwIsWindows10CreatorsUpdateOrGreaterWin32())
|
|
||||||
SetProcessDpiAwarenessContext(DPI_AWARENESS_CONTEXT_PER_MONITOR_AWARE_V2);
|
|
||||||
else if (IsWindows8Point1OrGreater())
|
|
||||||
SetProcessDpiAwareness(PROCESS_PER_MONITOR_DPI_AWARE);
|
|
||||||
else if (IsWindowsVistaOrGreater())
|
|
||||||
SetProcessDPIAware();
|
|
||||||
|
|
||||||
if (!_glfwRegisterWindowClassWin32())
|
|
||||||
return GLFW_FALSE;
|
|
||||||
|
|
||||||
_glfw.win32.helperWindowHandle = createHelperWindow();
|
|
||||||
if (!_glfw.win32.helperWindowHandle)
|
|
||||||
return GLFW_FALSE;
|
|
||||||
|
|
||||||
_glfwInitTimerWin32();
|
|
||||||
_glfwInitJoysticksWin32();
|
|
||||||
|
|
||||||
_glfwPollMonitorsWin32();
|
|
||||||
return GLFW_TRUE;
|
|
||||||
}
|
|
||||||
|
|
||||||
void _glfwPlatformTerminate(void)
|
|
||||||
{
|
|
||||||
if (_glfw.win32.deviceNotificationHandle)
|
|
||||||
UnregisterDeviceNotification(_glfw.win32.deviceNotificationHandle);
|
|
||||||
|
|
||||||
if (_glfw.win32.helperWindowHandle)
|
|
||||||
DestroyWindow(_glfw.win32.helperWindowHandle);
|
|
||||||
|
|
||||||
_glfwUnregisterWindowClassWin32();
|
|
||||||
|
|
||||||
// Restore previous foreground lock timeout system setting
|
|
||||||
SystemParametersInfoW(SPI_SETFOREGROUNDLOCKTIMEOUT, 0,
|
|
||||||
UIntToPtr(_glfw.win32.foregroundLockTimeout),
|
|
||||||
SPIF_SENDCHANGE);
|
|
||||||
|
|
||||||
free(_glfw.win32.clipboardString);
|
|
||||||
free(_glfw.win32.rawInput);
|
|
||||||
|
|
||||||
_glfwTerminateWGL();
|
|
||||||
_glfwTerminateEGL();
|
|
||||||
|
|
||||||
_glfwTerminateJoysticksWin32();
|
|
||||||
|
|
||||||
freeLibraries();
|
|
||||||
}
|
|
||||||
|
|
||||||
const char* _glfwPlatformGetVersionString(void)
|
|
||||||
{
|
|
||||||
return _GLFW_VERSION_NUMBER " Win32 WGL EGL"
|
|
||||||
#if defined(__MINGW32__)
|
|
||||||
" MinGW"
|
|
||||||
#elif defined(_MSC_VER)
|
|
||||||
" VisualC"
|
|
||||||
#endif
|
|
||||||
#if defined(_GLFW_USE_HYBRID_HPG) || defined(_GLFW_USE_OPTIMUS_HPG)
|
|
||||||
" hybrid-GPU"
|
|
||||||
#endif
|
|
||||||
#if defined(_GLFW_BUILD_DLL)
|
|
||||||
" DLL"
|
|
||||||
#endif
|
|
||||||
;
|
|
||||||
}
|
|
||||||
|
|
||||||
750
glfw/win32_joystick.c
vendored
750
glfw/win32_joystick.c
vendored
@@ -1,750 +0,0 @@
|
|||||||
//========================================================================
|
|
||||||
// GLFW 3.3 Win32 - www.glfw.org
|
|
||||||
//------------------------------------------------------------------------
|
|
||||||
// Copyright (c) 2002-2006 Marcus Geelnard
|
|
||||||
// Copyright (c) 2006-2016 Camilla Löwy <elmindreda@glfw.org>
|
|
||||||
//
|
|
||||||
// This software is provided 'as-is', without any express or implied
|
|
||||||
// warranty. In no event will the authors be held liable for any damages
|
|
||||||
// arising from the use of this software.
|
|
||||||
//
|
|
||||||
// Permission is granted to anyone to use this software for any purpose,
|
|
||||||
// including commercial applications, and to alter it and redistribute it
|
|
||||||
// freely, subject to the following restrictions:
|
|
||||||
//
|
|
||||||
// 1. The origin of this software must not be misrepresented; you must not
|
|
||||||
// claim that you wrote the original software. If you use this software
|
|
||||||
// in a product, an acknowledgment in the product documentation would
|
|
||||||
// be appreciated but is not required.
|
|
||||||
//
|
|
||||||
// 2. Altered source versions must be plainly marked as such, and must not
|
|
||||||
// be misrepresented as being the original software.
|
|
||||||
//
|
|
||||||
// 3. This notice may not be removed or altered from any source
|
|
||||||
// distribution.
|
|
||||||
//
|
|
||||||
//========================================================================
|
|
||||||
|
|
||||||
#include "internal.h"
|
|
||||||
|
|
||||||
#include <stdio.h>
|
|
||||||
#include <math.h>
|
|
||||||
|
|
||||||
#define _GLFW_TYPE_AXIS 0
|
|
||||||
#define _GLFW_TYPE_SLIDER 1
|
|
||||||
#define _GLFW_TYPE_BUTTON 2
|
|
||||||
#define _GLFW_TYPE_POV 3
|
|
||||||
|
|
||||||
// Data produced with DirectInput device object enumeration
|
|
||||||
//
|
|
||||||
typedef struct _GLFWobjenumWin32
|
|
||||||
{
|
|
||||||
IDirectInputDevice8W* device;
|
|
||||||
_GLFWjoyobjectWin32* objects;
|
|
||||||
int objectCount;
|
|
||||||
int axisCount;
|
|
||||||
int sliderCount;
|
|
||||||
int buttonCount;
|
|
||||||
int povCount;
|
|
||||||
} _GLFWobjenumWin32;
|
|
||||||
|
|
||||||
// Define local copies of the necessary GUIDs
|
|
||||||
//
|
|
||||||
static const GUID _glfw_IID_IDirectInput8W =
|
|
||||||
{0xbf798031,0x483a,0x4da2,{0xaa,0x99,0x5d,0x64,0xed,0x36,0x97,0x00}};
|
|
||||||
static const GUID _glfw_GUID_XAxis =
|
|
||||||
{0xa36d02e0,0xc9f3,0x11cf,{0xbf,0xc7,0x44,0x45,0x53,0x54,0x00,0x00}};
|
|
||||||
static const GUID _glfw_GUID_YAxis =
|
|
||||||
{0xa36d02e1,0xc9f3,0x11cf,{0xbf,0xc7,0x44,0x45,0x53,0x54,0x00,0x00}};
|
|
||||||
static const GUID _glfw_GUID_ZAxis =
|
|
||||||
{0xa36d02e2,0xc9f3,0x11cf,{0xbf,0xc7,0x44,0x45,0x53,0x54,0x00,0x00}};
|
|
||||||
static const GUID _glfw_GUID_RxAxis =
|
|
||||||
{0xa36d02f4,0xc9f3,0x11cf,{0xbf,0xc7,0x44,0x45,0x53,0x54,0x00,0x00}};
|
|
||||||
static const GUID _glfw_GUID_RyAxis =
|
|
||||||
{0xa36d02f5,0xc9f3,0x11cf,{0xbf,0xc7,0x44,0x45,0x53,0x54,0x00,0x00}};
|
|
||||||
static const GUID _glfw_GUID_RzAxis =
|
|
||||||
{0xa36d02e3,0xc9f3,0x11cf,{0xbf,0xc7,0x44,0x45,0x53,0x54,0x00,0x00}};
|
|
||||||
static const GUID _glfw_GUID_Slider =
|
|
||||||
{0xa36d02e4,0xc9f3,0x11cf,{0xbf,0xc7,0x44,0x45,0x53,0x54,0x00,0x00}};
|
|
||||||
static const GUID _glfw_GUID_POV =
|
|
||||||
{0xa36d02f2,0xc9f3,0x11cf,{0xbf,0xc7,0x44,0x45,0x53,0x54,0x00,0x00}};
|
|
||||||
|
|
||||||
#define IID_IDirectInput8W _glfw_IID_IDirectInput8W
|
|
||||||
#define GUID_XAxis _glfw_GUID_XAxis
|
|
||||||
#define GUID_YAxis _glfw_GUID_YAxis
|
|
||||||
#define GUID_ZAxis _glfw_GUID_ZAxis
|
|
||||||
#define GUID_RxAxis _glfw_GUID_RxAxis
|
|
||||||
#define GUID_RyAxis _glfw_GUID_RyAxis
|
|
||||||
#define GUID_RzAxis _glfw_GUID_RzAxis
|
|
||||||
#define GUID_Slider _glfw_GUID_Slider
|
|
||||||
#define GUID_POV _glfw_GUID_POV
|
|
||||||
|
|
||||||
// Object data array for our clone of c_dfDIJoystick
|
|
||||||
// Generated with https://github.com/elmindreda/c_dfDIJoystick2
|
|
||||||
//
|
|
||||||
static DIOBJECTDATAFORMAT _glfwObjectDataFormats[] =
|
|
||||||
{
|
|
||||||
{ &GUID_XAxis,DIJOFS_X,DIDFT_AXIS|DIDFT_OPTIONAL|DIDFT_ANYINSTANCE,DIDOI_ASPECTPOSITION },
|
|
||||||
{ &GUID_YAxis,DIJOFS_Y,DIDFT_AXIS|DIDFT_OPTIONAL|DIDFT_ANYINSTANCE,DIDOI_ASPECTPOSITION },
|
|
||||||
{ &GUID_ZAxis,DIJOFS_Z,DIDFT_AXIS|DIDFT_OPTIONAL|DIDFT_ANYINSTANCE,DIDOI_ASPECTPOSITION },
|
|
||||||
{ &GUID_RxAxis,DIJOFS_RX,DIDFT_AXIS|DIDFT_OPTIONAL|DIDFT_ANYINSTANCE,DIDOI_ASPECTPOSITION },
|
|
||||||
{ &GUID_RyAxis,DIJOFS_RY,DIDFT_AXIS|DIDFT_OPTIONAL|DIDFT_ANYINSTANCE,DIDOI_ASPECTPOSITION },
|
|
||||||
{ &GUID_RzAxis,DIJOFS_RZ,DIDFT_AXIS|DIDFT_OPTIONAL|DIDFT_ANYINSTANCE,DIDOI_ASPECTPOSITION },
|
|
||||||
{ &GUID_Slider,DIJOFS_SLIDER(0),DIDFT_AXIS|DIDFT_OPTIONAL|DIDFT_ANYINSTANCE,DIDOI_ASPECTPOSITION },
|
|
||||||
{ &GUID_Slider,DIJOFS_SLIDER(1),DIDFT_AXIS|DIDFT_OPTIONAL|DIDFT_ANYINSTANCE,DIDOI_ASPECTPOSITION },
|
|
||||||
{ &GUID_POV,DIJOFS_POV(0),DIDFT_POV|DIDFT_OPTIONAL|DIDFT_ANYINSTANCE,0 },
|
|
||||||
{ &GUID_POV,DIJOFS_POV(1),DIDFT_POV|DIDFT_OPTIONAL|DIDFT_ANYINSTANCE,0 },
|
|
||||||
{ &GUID_POV,DIJOFS_POV(2),DIDFT_POV|DIDFT_OPTIONAL|DIDFT_ANYINSTANCE,0 },
|
|
||||||
{ &GUID_POV,DIJOFS_POV(3),DIDFT_POV|DIDFT_OPTIONAL|DIDFT_ANYINSTANCE,0 },
|
|
||||||
{ NULL,DIJOFS_BUTTON(0),DIDFT_BUTTON|DIDFT_OPTIONAL|DIDFT_ANYINSTANCE,0 },
|
|
||||||
{ NULL,DIJOFS_BUTTON(1),DIDFT_BUTTON|DIDFT_OPTIONAL|DIDFT_ANYINSTANCE,0 },
|
|
||||||
{ NULL,DIJOFS_BUTTON(2),DIDFT_BUTTON|DIDFT_OPTIONAL|DIDFT_ANYINSTANCE,0 },
|
|
||||||
{ NULL,DIJOFS_BUTTON(3),DIDFT_BUTTON|DIDFT_OPTIONAL|DIDFT_ANYINSTANCE,0 },
|
|
||||||
{ NULL,DIJOFS_BUTTON(4),DIDFT_BUTTON|DIDFT_OPTIONAL|DIDFT_ANYINSTANCE,0 },
|
|
||||||
{ NULL,DIJOFS_BUTTON(5),DIDFT_BUTTON|DIDFT_OPTIONAL|DIDFT_ANYINSTANCE,0 },
|
|
||||||
{ NULL,DIJOFS_BUTTON(6),DIDFT_BUTTON|DIDFT_OPTIONAL|DIDFT_ANYINSTANCE,0 },
|
|
||||||
{ NULL,DIJOFS_BUTTON(7),DIDFT_BUTTON|DIDFT_OPTIONAL|DIDFT_ANYINSTANCE,0 },
|
|
||||||
{ NULL,DIJOFS_BUTTON(8),DIDFT_BUTTON|DIDFT_OPTIONAL|DIDFT_ANYINSTANCE,0 },
|
|
||||||
{ NULL,DIJOFS_BUTTON(9),DIDFT_BUTTON|DIDFT_OPTIONAL|DIDFT_ANYINSTANCE,0 },
|
|
||||||
{ NULL,DIJOFS_BUTTON(10),DIDFT_BUTTON|DIDFT_OPTIONAL|DIDFT_ANYINSTANCE,0 },
|
|
||||||
{ NULL,DIJOFS_BUTTON(11),DIDFT_BUTTON|DIDFT_OPTIONAL|DIDFT_ANYINSTANCE,0 },
|
|
||||||
{ NULL,DIJOFS_BUTTON(12),DIDFT_BUTTON|DIDFT_OPTIONAL|DIDFT_ANYINSTANCE,0 },
|
|
||||||
{ NULL,DIJOFS_BUTTON(13),DIDFT_BUTTON|DIDFT_OPTIONAL|DIDFT_ANYINSTANCE,0 },
|
|
||||||
{ NULL,DIJOFS_BUTTON(14),DIDFT_BUTTON|DIDFT_OPTIONAL|DIDFT_ANYINSTANCE,0 },
|
|
||||||
{ NULL,DIJOFS_BUTTON(15),DIDFT_BUTTON|DIDFT_OPTIONAL|DIDFT_ANYINSTANCE,0 },
|
|
||||||
{ NULL,DIJOFS_BUTTON(16),DIDFT_BUTTON|DIDFT_OPTIONAL|DIDFT_ANYINSTANCE,0 },
|
|
||||||
{ NULL,DIJOFS_BUTTON(17),DIDFT_BUTTON|DIDFT_OPTIONAL|DIDFT_ANYINSTANCE,0 },
|
|
||||||
{ NULL,DIJOFS_BUTTON(18),DIDFT_BUTTON|DIDFT_OPTIONAL|DIDFT_ANYINSTANCE,0 },
|
|
||||||
{ NULL,DIJOFS_BUTTON(19),DIDFT_BUTTON|DIDFT_OPTIONAL|DIDFT_ANYINSTANCE,0 },
|
|
||||||
{ NULL,DIJOFS_BUTTON(20),DIDFT_BUTTON|DIDFT_OPTIONAL|DIDFT_ANYINSTANCE,0 },
|
|
||||||
{ NULL,DIJOFS_BUTTON(21),DIDFT_BUTTON|DIDFT_OPTIONAL|DIDFT_ANYINSTANCE,0 },
|
|
||||||
{ NULL,DIJOFS_BUTTON(22),DIDFT_BUTTON|DIDFT_OPTIONAL|DIDFT_ANYINSTANCE,0 },
|
|
||||||
{ NULL,DIJOFS_BUTTON(23),DIDFT_BUTTON|DIDFT_OPTIONAL|DIDFT_ANYINSTANCE,0 },
|
|
||||||
{ NULL,DIJOFS_BUTTON(24),DIDFT_BUTTON|DIDFT_OPTIONAL|DIDFT_ANYINSTANCE,0 },
|
|
||||||
{ NULL,DIJOFS_BUTTON(25),DIDFT_BUTTON|DIDFT_OPTIONAL|DIDFT_ANYINSTANCE,0 },
|
|
||||||
{ NULL,DIJOFS_BUTTON(26),DIDFT_BUTTON|DIDFT_OPTIONAL|DIDFT_ANYINSTANCE,0 },
|
|
||||||
{ NULL,DIJOFS_BUTTON(27),DIDFT_BUTTON|DIDFT_OPTIONAL|DIDFT_ANYINSTANCE,0 },
|
|
||||||
{ NULL,DIJOFS_BUTTON(28),DIDFT_BUTTON|DIDFT_OPTIONAL|DIDFT_ANYINSTANCE,0 },
|
|
||||||
{ NULL,DIJOFS_BUTTON(29),DIDFT_BUTTON|DIDFT_OPTIONAL|DIDFT_ANYINSTANCE,0 },
|
|
||||||
{ NULL,DIJOFS_BUTTON(30),DIDFT_BUTTON|DIDFT_OPTIONAL|DIDFT_ANYINSTANCE,0 },
|
|
||||||
{ NULL,DIJOFS_BUTTON(31),DIDFT_BUTTON|DIDFT_OPTIONAL|DIDFT_ANYINSTANCE,0 },
|
|
||||||
};
|
|
||||||
|
|
||||||
// Our clone of c_dfDIJoystick
|
|
||||||
//
|
|
||||||
static const DIDATAFORMAT _glfwDataFormat =
|
|
||||||
{
|
|
||||||
sizeof(DIDATAFORMAT),
|
|
||||||
sizeof(DIOBJECTDATAFORMAT),
|
|
||||||
DIDFT_ABSAXIS,
|
|
||||||
sizeof(DIJOYSTATE),
|
|
||||||
sizeof(_glfwObjectDataFormats) / sizeof(DIOBJECTDATAFORMAT),
|
|
||||||
_glfwObjectDataFormats
|
|
||||||
};
|
|
||||||
|
|
||||||
// Returns a description fitting the specified XInput capabilities
|
|
||||||
//
|
|
||||||
static const char* getDeviceDescription(const XINPUT_CAPABILITIES* xic)
|
|
||||||
{
|
|
||||||
switch (xic->SubType)
|
|
||||||
{
|
|
||||||
case XINPUT_DEVSUBTYPE_WHEEL:
|
|
||||||
return "XInput Wheel";
|
|
||||||
case XINPUT_DEVSUBTYPE_ARCADE_STICK:
|
|
||||||
return "XInput Arcade Stick";
|
|
||||||
case XINPUT_DEVSUBTYPE_FLIGHT_STICK:
|
|
||||||
return "XInput Flight Stick";
|
|
||||||
case XINPUT_DEVSUBTYPE_DANCE_PAD:
|
|
||||||
return "XInput Dance Pad";
|
|
||||||
case XINPUT_DEVSUBTYPE_GUITAR:
|
|
||||||
return "XInput Guitar";
|
|
||||||
case XINPUT_DEVSUBTYPE_DRUM_KIT:
|
|
||||||
return "XInput Drum Kit";
|
|
||||||
case XINPUT_DEVSUBTYPE_GAMEPAD:
|
|
||||||
{
|
|
||||||
if (xic->Flags & XINPUT_CAPS_WIRELESS)
|
|
||||||
return "Wireless Xbox Controller";
|
|
||||||
else
|
|
||||||
return "Xbox Controller";
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return "Unknown XInput Device";
|
|
||||||
}
|
|
||||||
|
|
||||||
// Lexically compare device objects
|
|
||||||
//
|
|
||||||
static int compareJoystickObjects(const void* first, const void* second)
|
|
||||||
{
|
|
||||||
const _GLFWjoyobjectWin32* fo = first;
|
|
||||||
const _GLFWjoyobjectWin32* so = second;
|
|
||||||
|
|
||||||
if (fo->type != so->type)
|
|
||||||
return fo->type - so->type;
|
|
||||||
|
|
||||||
return fo->offset - so->offset;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Checks whether the specified device supports XInput
|
|
||||||
// Technique from FDInputJoystickManager::IsXInputDeviceFast in ZDoom
|
|
||||||
//
|
|
||||||
static GLFWbool supportsXInput(const GUID* guid)
|
|
||||||
{
|
|
||||||
UINT i, count = 0;
|
|
||||||
RAWINPUTDEVICELIST* ridl;
|
|
||||||
GLFWbool result = GLFW_FALSE;
|
|
||||||
|
|
||||||
if (GetRawInputDeviceList(NULL, &count, sizeof(RAWINPUTDEVICELIST)) != 0)
|
|
||||||
return GLFW_FALSE;
|
|
||||||
|
|
||||||
ridl = calloc(count, sizeof(RAWINPUTDEVICELIST));
|
|
||||||
|
|
||||||
if (GetRawInputDeviceList(ridl, &count, sizeof(RAWINPUTDEVICELIST)) == (UINT) -1)
|
|
||||||
{
|
|
||||||
free(ridl);
|
|
||||||
return GLFW_FALSE;
|
|
||||||
}
|
|
||||||
|
|
||||||
for (i = 0; i < count; i++)
|
|
||||||
{
|
|
||||||
RID_DEVICE_INFO rdi;
|
|
||||||
char name[256];
|
|
||||||
UINT size;
|
|
||||||
|
|
||||||
if (ridl[i].dwType != RIM_TYPEHID)
|
|
||||||
continue;
|
|
||||||
|
|
||||||
ZeroMemory(&rdi, sizeof(rdi));
|
|
||||||
rdi.cbSize = sizeof(rdi);
|
|
||||||
size = sizeof(rdi);
|
|
||||||
|
|
||||||
if ((INT) GetRawInputDeviceInfoA(ridl[i].hDevice,
|
|
||||||
RIDI_DEVICEINFO,
|
|
||||||
&rdi, &size) == -1)
|
|
||||||
{
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (MAKELONG(rdi.hid.dwVendorId, rdi.hid.dwProductId) != (LONG) guid->Data1)
|
|
||||||
continue;
|
|
||||||
|
|
||||||
memset(name, 0, sizeof(name));
|
|
||||||
size = sizeof(name);
|
|
||||||
|
|
||||||
if ((INT) GetRawInputDeviceInfoA(ridl[i].hDevice,
|
|
||||||
RIDI_DEVICENAME,
|
|
||||||
name, &size) == -1)
|
|
||||||
{
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
name[sizeof(name) - 1] = '\0';
|
|
||||||
if (strstr(name, "IG_"))
|
|
||||||
{
|
|
||||||
result = GLFW_TRUE;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
free(ridl);
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Frees all resources associated with the specified joystick
|
|
||||||
//
|
|
||||||
static void closeJoystick(_GLFWjoystick* js)
|
|
||||||
{
|
|
||||||
if (js->win32.device)
|
|
||||||
{
|
|
||||||
IDirectInputDevice8_Unacquire(js->win32.device);
|
|
||||||
IDirectInputDevice8_Release(js->win32.device);
|
|
||||||
}
|
|
||||||
|
|
||||||
_glfwFreeJoystick(js);
|
|
||||||
_glfwInputJoystick(js, GLFW_DISCONNECTED);
|
|
||||||
}
|
|
||||||
|
|
||||||
// DirectInput device object enumeration callback
|
|
||||||
// Insights gleaned from SDL
|
|
||||||
//
|
|
||||||
static BOOL CALLBACK deviceObjectCallback(const DIDEVICEOBJECTINSTANCEW* doi,
|
|
||||||
void* user)
|
|
||||||
{
|
|
||||||
_GLFWobjenumWin32* data = user;
|
|
||||||
_GLFWjoyobjectWin32* object = data->objects + data->objectCount;
|
|
||||||
|
|
||||||
if (DIDFT_GETTYPE(doi->dwType) & DIDFT_AXIS)
|
|
||||||
{
|
|
||||||
DIPROPRANGE dipr;
|
|
||||||
|
|
||||||
if (memcmp(&doi->guidType, &GUID_Slider, sizeof(GUID)) == 0)
|
|
||||||
object->offset = DIJOFS_SLIDER(data->sliderCount);
|
|
||||||
else if (memcmp(&doi->guidType, &GUID_XAxis, sizeof(GUID)) == 0)
|
|
||||||
object->offset = DIJOFS_X;
|
|
||||||
else if (memcmp(&doi->guidType, &GUID_YAxis, sizeof(GUID)) == 0)
|
|
||||||
object->offset = DIJOFS_Y;
|
|
||||||
else if (memcmp(&doi->guidType, &GUID_ZAxis, sizeof(GUID)) == 0)
|
|
||||||
object->offset = DIJOFS_Z;
|
|
||||||
else if (memcmp(&doi->guidType, &GUID_RxAxis, sizeof(GUID)) == 0)
|
|
||||||
object->offset = DIJOFS_RX;
|
|
||||||
else if (memcmp(&doi->guidType, &GUID_RyAxis, sizeof(GUID)) == 0)
|
|
||||||
object->offset = DIJOFS_RY;
|
|
||||||
else if (memcmp(&doi->guidType, &GUID_RzAxis, sizeof(GUID)) == 0)
|
|
||||||
object->offset = DIJOFS_RZ;
|
|
||||||
else
|
|
||||||
return DIENUM_CONTINUE;
|
|
||||||
|
|
||||||
ZeroMemory(&dipr, sizeof(dipr));
|
|
||||||
dipr.diph.dwSize = sizeof(dipr);
|
|
||||||
dipr.diph.dwHeaderSize = sizeof(dipr.diph);
|
|
||||||
dipr.diph.dwObj = doi->dwType;
|
|
||||||
dipr.diph.dwHow = DIPH_BYID;
|
|
||||||
dipr.lMin = -32768;
|
|
||||||
dipr.lMax = 32767;
|
|
||||||
|
|
||||||
if (FAILED(IDirectInputDevice8_SetProperty(data->device,
|
|
||||||
DIPROP_RANGE,
|
|
||||||
&dipr.diph)))
|
|
||||||
{
|
|
||||||
return DIENUM_CONTINUE;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (memcmp(&doi->guidType, &GUID_Slider, sizeof(GUID)) == 0)
|
|
||||||
{
|
|
||||||
object->type = _GLFW_TYPE_SLIDER;
|
|
||||||
data->sliderCount++;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
object->type = _GLFW_TYPE_AXIS;
|
|
||||||
data->axisCount++;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else if (DIDFT_GETTYPE(doi->dwType) & DIDFT_BUTTON)
|
|
||||||
{
|
|
||||||
object->offset = DIJOFS_BUTTON(data->buttonCount);
|
|
||||||
object->type = _GLFW_TYPE_BUTTON;
|
|
||||||
data->buttonCount++;
|
|
||||||
}
|
|
||||||
else if (DIDFT_GETTYPE(doi->dwType) & DIDFT_POV)
|
|
||||||
{
|
|
||||||
object->offset = DIJOFS_POV(data->povCount);
|
|
||||||
object->type = _GLFW_TYPE_POV;
|
|
||||||
data->povCount++;
|
|
||||||
}
|
|
||||||
|
|
||||||
data->objectCount++;
|
|
||||||
return DIENUM_CONTINUE;
|
|
||||||
}
|
|
||||||
|
|
||||||
// DirectInput device enumeration callback
|
|
||||||
//
|
|
||||||
static BOOL CALLBACK deviceCallback(const DIDEVICEINSTANCE* di, void* user)
|
|
||||||
{
|
|
||||||
int jid = 0;
|
|
||||||
DIDEVCAPS dc;
|
|
||||||
DIPROPDWORD dipd;
|
|
||||||
IDirectInputDevice8* device;
|
|
||||||
_GLFWobjenumWin32 data;
|
|
||||||
_GLFWjoystick* js;
|
|
||||||
char guid[33];
|
|
||||||
char name[256];
|
|
||||||
|
|
||||||
for (jid = 0; jid <= GLFW_JOYSTICK_LAST; jid++)
|
|
||||||
{
|
|
||||||
_GLFWjoystick* js = _glfw.joysticks + jid;
|
|
||||||
if (js->present)
|
|
||||||
{
|
|
||||||
if (memcmp(&js->win32.guid, &di->guidInstance, sizeof(GUID)) == 0)
|
|
||||||
return DIENUM_CONTINUE;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (supportsXInput(&di->guidProduct))
|
|
||||||
return DIENUM_CONTINUE;
|
|
||||||
|
|
||||||
if (FAILED(IDirectInput8_CreateDevice(_glfw.win32.dinput8.api,
|
|
||||||
&di->guidInstance,
|
|
||||||
&device,
|
|
||||||
NULL)))
|
|
||||||
{
|
|
||||||
_glfwInputError(GLFW_PLATFORM_ERROR, "Win32: Failed to create device");
|
|
||||||
return DIENUM_CONTINUE;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (FAILED(IDirectInputDevice8_SetDataFormat(device, &_glfwDataFormat)))
|
|
||||||
{
|
|
||||||
_glfwInputError(GLFW_PLATFORM_ERROR,
|
|
||||||
"Win32: Failed to set device data format");
|
|
||||||
|
|
||||||
IDirectInputDevice8_Release(device);
|
|
||||||
return DIENUM_CONTINUE;
|
|
||||||
}
|
|
||||||
|
|
||||||
ZeroMemory(&dc, sizeof(dc));
|
|
||||||
dc.dwSize = sizeof(dc);
|
|
||||||
|
|
||||||
if (FAILED(IDirectInputDevice8_GetCapabilities(device, &dc)))
|
|
||||||
{
|
|
||||||
_glfwInputError(GLFW_PLATFORM_ERROR,
|
|
||||||
"Win32: Failed to query device capabilities");
|
|
||||||
|
|
||||||
IDirectInputDevice8_Release(device);
|
|
||||||
return DIENUM_CONTINUE;
|
|
||||||
}
|
|
||||||
|
|
||||||
ZeroMemory(&dipd, sizeof(dipd));
|
|
||||||
dipd.diph.dwSize = sizeof(dipd);
|
|
||||||
dipd.diph.dwHeaderSize = sizeof(dipd.diph);
|
|
||||||
dipd.diph.dwHow = DIPH_DEVICE;
|
|
||||||
dipd.dwData = DIPROPAXISMODE_ABS;
|
|
||||||
|
|
||||||
if (FAILED(IDirectInputDevice8_SetProperty(device,
|
|
||||||
DIPROP_AXISMODE,
|
|
||||||
&dipd.diph)))
|
|
||||||
{
|
|
||||||
_glfwInputError(GLFW_PLATFORM_ERROR,
|
|
||||||
"Win32: Failed to set device axis mode");
|
|
||||||
|
|
||||||
IDirectInputDevice8_Release(device);
|
|
||||||
return DIENUM_CONTINUE;
|
|
||||||
}
|
|
||||||
|
|
||||||
memset(&data, 0, sizeof(data));
|
|
||||||
data.device = device;
|
|
||||||
data.objects = calloc(dc.dwAxes + dc.dwButtons + dc.dwPOVs,
|
|
||||||
sizeof(_GLFWjoyobjectWin32));
|
|
||||||
|
|
||||||
if (FAILED(IDirectInputDevice8_EnumObjects(device,
|
|
||||||
deviceObjectCallback,
|
|
||||||
&data,
|
|
||||||
DIDFT_AXIS | DIDFT_BUTTON | DIDFT_POV)))
|
|
||||||
{
|
|
||||||
_glfwInputError(GLFW_PLATFORM_ERROR,
|
|
||||||
"Win32: Failed to enumerate device objects");
|
|
||||||
|
|
||||||
IDirectInputDevice8_Release(device);
|
|
||||||
free(data.objects);
|
|
||||||
return DIENUM_CONTINUE;
|
|
||||||
}
|
|
||||||
|
|
||||||
qsort(data.objects, data.objectCount,
|
|
||||||
sizeof(_GLFWjoyobjectWin32),
|
|
||||||
compareJoystickObjects);
|
|
||||||
|
|
||||||
if (!WideCharToMultiByte(CP_UTF8, 0,
|
|
||||||
di->tszInstanceName, -1,
|
|
||||||
name, sizeof(name),
|
|
||||||
NULL, NULL))
|
|
||||||
{
|
|
||||||
_glfwInputError(GLFW_PLATFORM_ERROR,
|
|
||||||
"Win32: Failed to convert joystick name to UTF-8");
|
|
||||||
|
|
||||||
IDirectInputDevice8_Release(device);
|
|
||||||
free(data.objects);
|
|
||||||
return DIENUM_STOP;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Generate a joystick GUID that matches the SDL 2.0.5+ one
|
|
||||||
if (memcmp(&di->guidProduct.Data4[2], "PIDVID", 6) == 0)
|
|
||||||
{
|
|
||||||
sprintf(guid, "03000000%02x%02x0000%02x%02x000000000000",
|
|
||||||
(uint8_t) di->guidProduct.Data1,
|
|
||||||
(uint8_t) (di->guidProduct.Data1 >> 8),
|
|
||||||
(uint8_t) (di->guidProduct.Data1 >> 16),
|
|
||||||
(uint8_t) (di->guidProduct.Data1 >> 24));
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
sprintf(guid, "05000000%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x00",
|
|
||||||
name[0], name[1], name[2], name[3],
|
|
||||||
name[4], name[5], name[6], name[7],
|
|
||||||
name[8], name[9], name[10]);
|
|
||||||
}
|
|
||||||
|
|
||||||
js = _glfwAllocJoystick(name, guid,
|
|
||||||
data.axisCount + data.sliderCount,
|
|
||||||
data.buttonCount,
|
|
||||||
data.povCount);
|
|
||||||
if (!js)
|
|
||||||
{
|
|
||||||
IDirectInputDevice8_Release(device);
|
|
||||||
free(data.objects);
|
|
||||||
return DIENUM_STOP;
|
|
||||||
}
|
|
||||||
|
|
||||||
js->win32.device = device;
|
|
||||||
js->win32.guid = di->guidInstance;
|
|
||||||
js->win32.objects = data.objects;
|
|
||||||
js->win32.objectCount = data.objectCount;
|
|
||||||
|
|
||||||
_glfwInputJoystick(js, GLFW_CONNECTED);
|
|
||||||
return DIENUM_CONTINUE;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
//////////////////////////////////////////////////////////////////////////
|
|
||||||
////// GLFW internal API //////
|
|
||||||
//////////////////////////////////////////////////////////////////////////
|
|
||||||
|
|
||||||
// Initialize joystick interface
|
|
||||||
//
|
|
||||||
void _glfwInitJoysticksWin32(void)
|
|
||||||
{
|
|
||||||
if (_glfw.win32.dinput8.instance)
|
|
||||||
{
|
|
||||||
if (FAILED(DirectInput8Create(GetModuleHandle(NULL),
|
|
||||||
DIRECTINPUT_VERSION,
|
|
||||||
&IID_IDirectInput8W,
|
|
||||||
(void**) &_glfw.win32.dinput8.api,
|
|
||||||
NULL)))
|
|
||||||
{
|
|
||||||
_glfwInputError(GLFW_PLATFORM_ERROR,
|
|
||||||
"Win32: Failed to create interface");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
_glfwDetectJoystickConnectionWin32();
|
|
||||||
}
|
|
||||||
|
|
||||||
// Close all opened joystick handles
|
|
||||||
//
|
|
||||||
void _glfwTerminateJoysticksWin32(void)
|
|
||||||
{
|
|
||||||
int jid;
|
|
||||||
|
|
||||||
for (jid = GLFW_JOYSTICK_1; jid <= GLFW_JOYSTICK_LAST; jid++)
|
|
||||||
closeJoystick(_glfw.joysticks + jid);
|
|
||||||
|
|
||||||
if (_glfw.win32.dinput8.api)
|
|
||||||
IDirectInput8_Release(_glfw.win32.dinput8.api);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Checks for new joysticks after DBT_DEVICEARRIVAL
|
|
||||||
//
|
|
||||||
void _glfwDetectJoystickConnectionWin32(void)
|
|
||||||
{
|
|
||||||
if (_glfw.win32.xinput.instance)
|
|
||||||
{
|
|
||||||
DWORD index;
|
|
||||||
|
|
||||||
for (index = 0; index < XUSER_MAX_COUNT; index++)
|
|
||||||
{
|
|
||||||
int jid;
|
|
||||||
char guid[33];
|
|
||||||
XINPUT_CAPABILITIES xic;
|
|
||||||
_GLFWjoystick* js;
|
|
||||||
|
|
||||||
for (jid = 0; jid <= GLFW_JOYSTICK_LAST; jid++)
|
|
||||||
{
|
|
||||||
if (_glfw.joysticks[jid].present &&
|
|
||||||
_glfw.joysticks[jid].win32.device == NULL &&
|
|
||||||
_glfw.joysticks[jid].win32.index == index)
|
|
||||||
{
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (jid <= GLFW_JOYSTICK_LAST)
|
|
||||||
continue;
|
|
||||||
|
|
||||||
if (XInputGetCapabilities(index, 0, &xic) != ERROR_SUCCESS)
|
|
||||||
continue;
|
|
||||||
|
|
||||||
// Generate a joystick GUID that matches the SDL 2.0.5+ one
|
|
||||||
sprintf(guid, "78696e707574%02x000000000000000000",
|
|
||||||
xic.SubType & 0xff);
|
|
||||||
|
|
||||||
js = _glfwAllocJoystick(getDeviceDescription(&xic), guid, 6, 10, 1);
|
|
||||||
if (!js)
|
|
||||||
continue;
|
|
||||||
|
|
||||||
js->win32.index = index;
|
|
||||||
|
|
||||||
_glfwInputJoystick(js, GLFW_CONNECTED);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (_glfw.win32.dinput8.api)
|
|
||||||
{
|
|
||||||
if (FAILED(IDirectInput8_EnumDevices(_glfw.win32.dinput8.api,
|
|
||||||
DI8DEVCLASS_GAMECTRL,
|
|
||||||
deviceCallback,
|
|
||||||
NULL,
|
|
||||||
DIEDFL_ALLDEVICES)))
|
|
||||||
{
|
|
||||||
_glfwInputError(GLFW_PLATFORM_ERROR,
|
|
||||||
"Failed to enumerate DirectInput8 devices");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Checks for joystick disconnection after DBT_DEVICEREMOVECOMPLETE
|
|
||||||
//
|
|
||||||
void _glfwDetectJoystickDisconnectionWin32(void)
|
|
||||||
{
|
|
||||||
int jid;
|
|
||||||
|
|
||||||
for (jid = 0; jid <= GLFW_JOYSTICK_LAST; jid++)
|
|
||||||
{
|
|
||||||
_GLFWjoystick* js = _glfw.joysticks + jid;
|
|
||||||
if (js->present)
|
|
||||||
_glfwPlatformPollJoystick(js, _GLFW_POLL_PRESENCE);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
//////////////////////////////////////////////////////////////////////////
|
|
||||||
////// GLFW platform API //////
|
|
||||||
//////////////////////////////////////////////////////////////////////////
|
|
||||||
|
|
||||||
int _glfwPlatformPollJoystick(_GLFWjoystick* js, int mode)
|
|
||||||
{
|
|
||||||
if (js->win32.device)
|
|
||||||
{
|
|
||||||
int i, ai = 0, bi = 0, pi = 0;
|
|
||||||
HRESULT result;
|
|
||||||
DIJOYSTATE state;
|
|
||||||
|
|
||||||
IDirectInputDevice8_Poll(js->win32.device);
|
|
||||||
result = IDirectInputDevice8_GetDeviceState(js->win32.device,
|
|
||||||
sizeof(state),
|
|
||||||
&state);
|
|
||||||
if (result == DIERR_NOTACQUIRED || result == DIERR_INPUTLOST)
|
|
||||||
{
|
|
||||||
IDirectInputDevice8_Acquire(js->win32.device);
|
|
||||||
IDirectInputDevice8_Poll(js->win32.device);
|
|
||||||
result = IDirectInputDevice8_GetDeviceState(js->win32.device,
|
|
||||||
sizeof(state),
|
|
||||||
&state);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (FAILED(result))
|
|
||||||
{
|
|
||||||
closeJoystick(js);
|
|
||||||
return GLFW_FALSE;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (mode == _GLFW_POLL_PRESENCE)
|
|
||||||
return GLFW_TRUE;
|
|
||||||
|
|
||||||
for (i = 0; i < js->win32.objectCount; i++)
|
|
||||||
{
|
|
||||||
const void* data = (char*) &state + js->win32.objects[i].offset;
|
|
||||||
|
|
||||||
switch (js->win32.objects[i].type)
|
|
||||||
{
|
|
||||||
case _GLFW_TYPE_AXIS:
|
|
||||||
case _GLFW_TYPE_SLIDER:
|
|
||||||
{
|
|
||||||
const float value = (*((LONG*) data) + 0.5f) / 32767.5f;
|
|
||||||
_glfwInputJoystickAxis(js, ai, value);
|
|
||||||
ai++;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
case _GLFW_TYPE_BUTTON:
|
|
||||||
{
|
|
||||||
const char value = (*((BYTE*) data) & 0x80) != 0;
|
|
||||||
_glfwInputJoystickButton(js, bi, value);
|
|
||||||
bi++;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
case _GLFW_TYPE_POV:
|
|
||||||
{
|
|
||||||
const int states[9] =
|
|
||||||
{
|
|
||||||
GLFW_HAT_UP,
|
|
||||||
GLFW_HAT_RIGHT_UP,
|
|
||||||
GLFW_HAT_RIGHT,
|
|
||||||
GLFW_HAT_RIGHT_DOWN,
|
|
||||||
GLFW_HAT_DOWN,
|
|
||||||
GLFW_HAT_LEFT_DOWN,
|
|
||||||
GLFW_HAT_LEFT,
|
|
||||||
GLFW_HAT_LEFT_UP,
|
|
||||||
GLFW_HAT_CENTERED
|
|
||||||
};
|
|
||||||
|
|
||||||
// Screams of horror are appropriate at this point
|
|
||||||
int state = LOWORD(*(DWORD*) data) / (45 * DI_DEGREES);
|
|
||||||
if (state < 0 || state > 8)
|
|
||||||
state = 8;
|
|
||||||
|
|
||||||
_glfwInputJoystickHat(js, pi, states[state]);
|
|
||||||
pi++;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
int i, dpad = 0;
|
|
||||||
DWORD result;
|
|
||||||
XINPUT_STATE xis;
|
|
||||||
const WORD buttons[10] =
|
|
||||||
{
|
|
||||||
XINPUT_GAMEPAD_A,
|
|
||||||
XINPUT_GAMEPAD_B,
|
|
||||||
XINPUT_GAMEPAD_X,
|
|
||||||
XINPUT_GAMEPAD_Y,
|
|
||||||
XINPUT_GAMEPAD_LEFT_SHOULDER,
|
|
||||||
XINPUT_GAMEPAD_RIGHT_SHOULDER,
|
|
||||||
XINPUT_GAMEPAD_BACK,
|
|
||||||
XINPUT_GAMEPAD_START,
|
|
||||||
XINPUT_GAMEPAD_LEFT_THUMB,
|
|
||||||
XINPUT_GAMEPAD_RIGHT_THUMB
|
|
||||||
};
|
|
||||||
|
|
||||||
result = XInputGetState(js->win32.index, &xis);
|
|
||||||
if (result != ERROR_SUCCESS)
|
|
||||||
{
|
|
||||||
if (result == ERROR_DEVICE_NOT_CONNECTED)
|
|
||||||
closeJoystick(js);
|
|
||||||
|
|
||||||
return GLFW_FALSE;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (mode == _GLFW_POLL_PRESENCE)
|
|
||||||
return GLFW_TRUE;
|
|
||||||
|
|
||||||
_glfwInputJoystickAxis(js, 0, (xis.Gamepad.sThumbLX + 0.5f) / 32767.5f);
|
|
||||||
_glfwInputJoystickAxis(js, 1, -(xis.Gamepad.sThumbLY + 0.5f) / 32767.5f);
|
|
||||||
_glfwInputJoystickAxis(js, 2, (xis.Gamepad.sThumbRX + 0.5f) / 32767.5f);
|
|
||||||
_glfwInputJoystickAxis(js, 3, -(xis.Gamepad.sThumbRY + 0.5f) / 32767.5f);
|
|
||||||
_glfwInputJoystickAxis(js, 4, xis.Gamepad.bLeftTrigger / 127.5f - 1.f);
|
|
||||||
_glfwInputJoystickAxis(js, 5, xis.Gamepad.bRightTrigger / 127.5f - 1.f);
|
|
||||||
|
|
||||||
for (i = 0; i < 10; i++)
|
|
||||||
{
|
|
||||||
const char value = (xis.Gamepad.wButtons & buttons[i]) ? 1 : 0;
|
|
||||||
_glfwInputJoystickButton(js, i, value);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (xis.Gamepad.wButtons & XINPUT_GAMEPAD_DPAD_UP)
|
|
||||||
dpad |= GLFW_HAT_UP;
|
|
||||||
if (xis.Gamepad.wButtons & XINPUT_GAMEPAD_DPAD_RIGHT)
|
|
||||||
dpad |= GLFW_HAT_RIGHT;
|
|
||||||
if (xis.Gamepad.wButtons & XINPUT_GAMEPAD_DPAD_DOWN)
|
|
||||||
dpad |= GLFW_HAT_DOWN;
|
|
||||||
if (xis.Gamepad.wButtons & XINPUT_GAMEPAD_DPAD_LEFT)
|
|
||||||
dpad |= GLFW_HAT_LEFT;
|
|
||||||
|
|
||||||
_glfwInputJoystickHat(js, 0, dpad);
|
|
||||||
}
|
|
||||||
|
|
||||||
return GLFW_TRUE;
|
|
||||||
}
|
|
||||||
|
|
||||||
void _glfwPlatformUpdateGamepadGUID(char* guid)
|
|
||||||
{
|
|
||||||
if (strcmp(guid + 20, "504944564944") == 0)
|
|
||||||
{
|
|
||||||
char original[33];
|
|
||||||
strncpy(original, guid, sizeof(original) - 1);
|
|
||||||
sprintf(guid, "03000000%.4s0000%.4s000000000000",
|
|
||||||
original, original + 4);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
56
glfw/win32_joystick.h
vendored
56
glfw/win32_joystick.h
vendored
@@ -1,56 +0,0 @@
|
|||||||
//========================================================================
|
|
||||||
// GLFW 3.3 Win32 - www.glfw.org
|
|
||||||
//------------------------------------------------------------------------
|
|
||||||
// Copyright (c) 2006-2016 Camilla Löwy <elmindreda@glfw.org>
|
|
||||||
//
|
|
||||||
// This software is provided 'as-is', without any express or implied
|
|
||||||
// warranty. In no event will the authors be held liable for any damages
|
|
||||||
// arising from the use of this software.
|
|
||||||
//
|
|
||||||
// Permission is granted to anyone to use this software for any purpose,
|
|
||||||
// including commercial applications, and to alter it and redistribute it
|
|
||||||
// freely, subject to the following restrictions:
|
|
||||||
//
|
|
||||||
// 1. The origin of this software must not be misrepresented; you must not
|
|
||||||
// claim that you wrote the original software. If you use this software
|
|
||||||
// in a product, an acknowledgment in the product documentation would
|
|
||||||
// be appreciated but is not required.
|
|
||||||
//
|
|
||||||
// 2. Altered source versions must be plainly marked as such, and must not
|
|
||||||
// be misrepresented as being the original software.
|
|
||||||
//
|
|
||||||
// 3. This notice may not be removed or altered from any source
|
|
||||||
// distribution.
|
|
||||||
//
|
|
||||||
//========================================================================
|
|
||||||
|
|
||||||
#define _GLFW_PLATFORM_JOYSTICK_STATE _GLFWjoystickWin32 win32
|
|
||||||
#define _GLFW_PLATFORM_LIBRARY_JOYSTICK_STATE int dummy
|
|
||||||
|
|
||||||
#define _GLFW_PLATFORM_MAPPING_NAME "Windows"
|
|
||||||
|
|
||||||
// Joystick element (axis, button or slider)
|
|
||||||
//
|
|
||||||
typedef struct _GLFWjoyobjectWin32
|
|
||||||
{
|
|
||||||
int offset;
|
|
||||||
int type;
|
|
||||||
} _GLFWjoyobjectWin32;
|
|
||||||
|
|
||||||
// Win32-specific per-joystick data
|
|
||||||
//
|
|
||||||
typedef struct _GLFWjoystickWin32
|
|
||||||
{
|
|
||||||
_GLFWjoyobjectWin32* objects;
|
|
||||||
int objectCount;
|
|
||||||
IDirectInputDevice8W* device;
|
|
||||||
DWORD index;
|
|
||||||
GUID guid;
|
|
||||||
} _GLFWjoystickWin32;
|
|
||||||
|
|
||||||
|
|
||||||
void _glfwInitJoysticksWin32(void);
|
|
||||||
void _glfwTerminateJoysticksWin32(void);
|
|
||||||
void _glfwDetectJoystickConnectionWin32(void);
|
|
||||||
void _glfwDetectJoystickDisconnectionWin32(void);
|
|
||||||
|
|
||||||
514
glfw/win32_monitor.c
vendored
514
glfw/win32_monitor.c
vendored
@@ -1,514 +0,0 @@
|
|||||||
//========================================================================
|
|
||||||
// GLFW 3.3 Win32 - www.glfw.org
|
|
||||||
//------------------------------------------------------------------------
|
|
||||||
// Copyright (c) 2002-2006 Marcus Geelnard
|
|
||||||
// Copyright (c) 2006-2016 Camilla Löwy <elmindreda@glfw.org>
|
|
||||||
//
|
|
||||||
// This software is provided 'as-is', without any express or implied
|
|
||||||
// warranty. In no event will the authors be held liable for any damages
|
|
||||||
// arising from the use of this software.
|
|
||||||
//
|
|
||||||
// Permission is granted to anyone to use this software for any purpose,
|
|
||||||
// including commercial applications, and to alter it and redistribute it
|
|
||||||
// freely, subject to the following restrictions:
|
|
||||||
//
|
|
||||||
// 1. The origin of this software must not be misrepresented; you must not
|
|
||||||
// claim that you wrote the original software. If you use this software
|
|
||||||
// in a product, an acknowledgment in the product documentation would
|
|
||||||
// be appreciated but is not required.
|
|
||||||
//
|
|
||||||
// 2. Altered source versions must be plainly marked as such, and must not
|
|
||||||
// be misrepresented as being the original software.
|
|
||||||
//
|
|
||||||
// 3. This notice may not be removed or altered from any source
|
|
||||||
// distribution.
|
|
||||||
//
|
|
||||||
//========================================================================
|
|
||||||
|
|
||||||
#include "internal.h"
|
|
||||||
|
|
||||||
#include <stdlib.h>
|
|
||||||
#include <string.h>
|
|
||||||
#include <limits.h>
|
|
||||||
#include <malloc.h>
|
|
||||||
|
|
||||||
|
|
||||||
// Callback for EnumDisplayMonitors in createMonitor
|
|
||||||
//
|
|
||||||
static BOOL CALLBACK monitorCallback(HMONITOR handle,
|
|
||||||
HDC dc,
|
|
||||||
RECT* rect,
|
|
||||||
LPARAM data)
|
|
||||||
{
|
|
||||||
MONITORINFOEXW mi;
|
|
||||||
ZeroMemory(&mi, sizeof(mi));
|
|
||||||
mi.cbSize = sizeof(mi);
|
|
||||||
|
|
||||||
if (GetMonitorInfoW(handle, (MONITORINFO*) &mi))
|
|
||||||
{
|
|
||||||
_GLFWmonitor* monitor = (_GLFWmonitor*) data;
|
|
||||||
if (wcscmp(mi.szDevice, monitor->win32.adapterName) == 0)
|
|
||||||
monitor->win32.handle = handle;
|
|
||||||
}
|
|
||||||
|
|
||||||
return TRUE;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Create monitor from an adapter and (optionally) a display
|
|
||||||
//
|
|
||||||
static _GLFWmonitor* createMonitor(DISPLAY_DEVICEW* adapter,
|
|
||||||
DISPLAY_DEVICEW* display)
|
|
||||||
{
|
|
||||||
_GLFWmonitor* monitor;
|
|
||||||
int widthMM, heightMM;
|
|
||||||
char* name;
|
|
||||||
HDC dc;
|
|
||||||
DEVMODEW dm;
|
|
||||||
RECT rect;
|
|
||||||
|
|
||||||
if (display)
|
|
||||||
name = _glfwCreateUTF8FromWideStringWin32(display->DeviceString);
|
|
||||||
else
|
|
||||||
name = _glfwCreateUTF8FromWideStringWin32(adapter->DeviceString);
|
|
||||||
if (!name)
|
|
||||||
return NULL;
|
|
||||||
|
|
||||||
ZeroMemory(&dm, sizeof(dm));
|
|
||||||
dm.dmSize = sizeof(dm);
|
|
||||||
EnumDisplaySettingsW(adapter->DeviceName, ENUM_CURRENT_SETTINGS, &dm);
|
|
||||||
|
|
||||||
dc = CreateDCW(L"DISPLAY", adapter->DeviceName, NULL, NULL);
|
|
||||||
|
|
||||||
if (IsWindows8Point1OrGreater())
|
|
||||||
{
|
|
||||||
widthMM = GetDeviceCaps(dc, HORZSIZE);
|
|
||||||
heightMM = GetDeviceCaps(dc, VERTSIZE);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
widthMM = (int) (dm.dmPelsWidth * 25.4f / GetDeviceCaps(dc, LOGPIXELSX));
|
|
||||||
heightMM = (int) (dm.dmPelsHeight * 25.4f / GetDeviceCaps(dc, LOGPIXELSY));
|
|
||||||
}
|
|
||||||
|
|
||||||
DeleteDC(dc);
|
|
||||||
|
|
||||||
monitor = _glfwAllocMonitor(name, widthMM, heightMM);
|
|
||||||
free(name);
|
|
||||||
|
|
||||||
if (adapter->StateFlags & DISPLAY_DEVICE_MODESPRUNED)
|
|
||||||
monitor->win32.modesPruned = GLFW_TRUE;
|
|
||||||
|
|
||||||
wcscpy(monitor->win32.adapterName, adapter->DeviceName);
|
|
||||||
WideCharToMultiByte(CP_UTF8, 0,
|
|
||||||
adapter->DeviceName, -1,
|
|
||||||
monitor->win32.publicAdapterName,
|
|
||||||
sizeof(monitor->win32.publicAdapterName),
|
|
||||||
NULL, NULL);
|
|
||||||
|
|
||||||
if (display)
|
|
||||||
{
|
|
||||||
wcscpy(monitor->win32.displayName, display->DeviceName);
|
|
||||||
WideCharToMultiByte(CP_UTF8, 0,
|
|
||||||
display->DeviceName, -1,
|
|
||||||
monitor->win32.publicDisplayName,
|
|
||||||
sizeof(monitor->win32.publicDisplayName),
|
|
||||||
NULL, NULL);
|
|
||||||
}
|
|
||||||
|
|
||||||
rect.left = dm.dmPosition.x;
|
|
||||||
rect.top = dm.dmPosition.y;
|
|
||||||
rect.right = dm.dmPosition.x + dm.dmPelsWidth;
|
|
||||||
rect.bottom = dm.dmPosition.y + dm.dmPelsHeight;
|
|
||||||
|
|
||||||
EnumDisplayMonitors(NULL, &rect, monitorCallback, (LPARAM) monitor);
|
|
||||||
return monitor;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
//////////////////////////////////////////////////////////////////////////
|
|
||||||
////// GLFW internal API //////
|
|
||||||
//////////////////////////////////////////////////////////////////////////
|
|
||||||
|
|
||||||
// Poll for changes in the set of connected monitors
|
|
||||||
//
|
|
||||||
void _glfwPollMonitorsWin32(void)
|
|
||||||
{
|
|
||||||
int i, disconnectedCount;
|
|
||||||
_GLFWmonitor** disconnected = NULL;
|
|
||||||
DWORD adapterIndex, displayIndex;
|
|
||||||
DISPLAY_DEVICEW adapter, display;
|
|
||||||
_GLFWmonitor* monitor;
|
|
||||||
|
|
||||||
disconnectedCount = _glfw.monitorCount;
|
|
||||||
if (disconnectedCount)
|
|
||||||
{
|
|
||||||
disconnected = calloc(_glfw.monitorCount, sizeof(_GLFWmonitor*));
|
|
||||||
memcpy(disconnected,
|
|
||||||
_glfw.monitors,
|
|
||||||
_glfw.monitorCount * sizeof(_GLFWmonitor*));
|
|
||||||
}
|
|
||||||
|
|
||||||
for (adapterIndex = 0; ; adapterIndex++)
|
|
||||||
{
|
|
||||||
int type = _GLFW_INSERT_LAST;
|
|
||||||
|
|
||||||
ZeroMemory(&adapter, sizeof(adapter));
|
|
||||||
adapter.cb = sizeof(adapter);
|
|
||||||
|
|
||||||
if (!EnumDisplayDevicesW(NULL, adapterIndex, &adapter, 0))
|
|
||||||
break;
|
|
||||||
|
|
||||||
if (!(adapter.StateFlags & DISPLAY_DEVICE_ACTIVE))
|
|
||||||
continue;
|
|
||||||
|
|
||||||
if (adapter.StateFlags & DISPLAY_DEVICE_PRIMARY_DEVICE)
|
|
||||||
type = _GLFW_INSERT_FIRST;
|
|
||||||
|
|
||||||
for (displayIndex = 0; ; displayIndex++)
|
|
||||||
{
|
|
||||||
ZeroMemory(&display, sizeof(display));
|
|
||||||
display.cb = sizeof(display);
|
|
||||||
|
|
||||||
if (!EnumDisplayDevicesW(adapter.DeviceName, displayIndex, &display, 0))
|
|
||||||
break;
|
|
||||||
|
|
||||||
if (!(display.StateFlags & DISPLAY_DEVICE_ACTIVE))
|
|
||||||
continue;
|
|
||||||
|
|
||||||
for (i = 0; i < disconnectedCount; i++)
|
|
||||||
{
|
|
||||||
if (disconnected[i] &&
|
|
||||||
wcscmp(disconnected[i]->win32.displayName,
|
|
||||||
display.DeviceName) == 0)
|
|
||||||
{
|
|
||||||
disconnected[i] = NULL;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (i < disconnectedCount)
|
|
||||||
continue;
|
|
||||||
|
|
||||||
monitor = createMonitor(&adapter, &display);
|
|
||||||
if (!monitor)
|
|
||||||
{
|
|
||||||
free(disconnected);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
_glfwInputMonitor(monitor, GLFW_CONNECTED, type);
|
|
||||||
|
|
||||||
type = _GLFW_INSERT_LAST;
|
|
||||||
}
|
|
||||||
|
|
||||||
// HACK: If an active adapter does not have any display devices
|
|
||||||
// (as sometimes happens), add it directly as a monitor
|
|
||||||
if (displayIndex == 0)
|
|
||||||
{
|
|
||||||
for (i = 0; i < disconnectedCount; i++)
|
|
||||||
{
|
|
||||||
if (disconnected[i] &&
|
|
||||||
wcscmp(disconnected[i]->win32.adapterName,
|
|
||||||
adapter.DeviceName) == 0)
|
|
||||||
{
|
|
||||||
disconnected[i] = NULL;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (i < disconnectedCount)
|
|
||||||
continue;
|
|
||||||
|
|
||||||
monitor = createMonitor(&adapter, NULL);
|
|
||||||
if (!monitor)
|
|
||||||
{
|
|
||||||
free(disconnected);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
_glfwInputMonitor(monitor, GLFW_CONNECTED, type);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
for (i = 0; i < disconnectedCount; i++)
|
|
||||||
{
|
|
||||||
if (disconnected[i])
|
|
||||||
_glfwInputMonitor(disconnected[i], GLFW_DISCONNECTED, 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
free(disconnected);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Change the current video mode
|
|
||||||
//
|
|
||||||
void _glfwSetVideoModeWin32(_GLFWmonitor* monitor, const GLFWvidmode* desired)
|
|
||||||
{
|
|
||||||
GLFWvidmode current;
|
|
||||||
const GLFWvidmode* best;
|
|
||||||
DEVMODEW dm;
|
|
||||||
LONG result;
|
|
||||||
|
|
||||||
best = _glfwChooseVideoMode(monitor, desired);
|
|
||||||
_glfwPlatformGetVideoMode(monitor, ¤t);
|
|
||||||
if (_glfwCompareVideoModes(¤t, best) == 0)
|
|
||||||
return;
|
|
||||||
|
|
||||||
ZeroMemory(&dm, sizeof(dm));
|
|
||||||
dm.dmSize = sizeof(dm);
|
|
||||||
dm.dmFields = DM_PELSWIDTH | DM_PELSHEIGHT | DM_BITSPERPEL |
|
|
||||||
DM_DISPLAYFREQUENCY;
|
|
||||||
dm.dmPelsWidth = best->width;
|
|
||||||
dm.dmPelsHeight = best->height;
|
|
||||||
dm.dmBitsPerPel = best->redBits + best->greenBits + best->blueBits;
|
|
||||||
dm.dmDisplayFrequency = best->refreshRate;
|
|
||||||
|
|
||||||
if (dm.dmBitsPerPel < 15 || dm.dmBitsPerPel >= 24)
|
|
||||||
dm.dmBitsPerPel = 32;
|
|
||||||
|
|
||||||
result = ChangeDisplaySettingsExW(monitor->win32.adapterName,
|
|
||||||
&dm,
|
|
||||||
NULL,
|
|
||||||
CDS_FULLSCREEN,
|
|
||||||
NULL);
|
|
||||||
if (result == DISP_CHANGE_SUCCESSFUL)
|
|
||||||
monitor->win32.modeChanged = GLFW_TRUE;
|
|
||||||
else
|
|
||||||
{
|
|
||||||
const char* description = "Unknown error";
|
|
||||||
|
|
||||||
if (result == DISP_CHANGE_BADDUALVIEW)
|
|
||||||
description = "The system uses DualView";
|
|
||||||
else if (result == DISP_CHANGE_BADFLAGS)
|
|
||||||
description = "Invalid flags";
|
|
||||||
else if (result == DISP_CHANGE_BADMODE)
|
|
||||||
description = "Graphics mode not supported";
|
|
||||||
else if (result == DISP_CHANGE_BADPARAM)
|
|
||||||
description = "Invalid parameter";
|
|
||||||
else if (result == DISP_CHANGE_FAILED)
|
|
||||||
description = "Graphics mode failed";
|
|
||||||
else if (result == DISP_CHANGE_NOTUPDATED)
|
|
||||||
description = "Failed to write to registry";
|
|
||||||
else if (result == DISP_CHANGE_RESTART)
|
|
||||||
description = "Computer restart required";
|
|
||||||
|
|
||||||
_glfwInputError(GLFW_PLATFORM_ERROR,
|
|
||||||
"Win32: Failed to set video mode: %s",
|
|
||||||
description);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Restore the previously saved (original) video mode
|
|
||||||
//
|
|
||||||
void _glfwRestoreVideoModeWin32(_GLFWmonitor* monitor)
|
|
||||||
{
|
|
||||||
if (monitor->win32.modeChanged)
|
|
||||||
{
|
|
||||||
ChangeDisplaySettingsExW(monitor->win32.adapterName,
|
|
||||||
NULL, NULL, CDS_FULLSCREEN, NULL);
|
|
||||||
monitor->win32.modeChanged = GLFW_FALSE;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void _glfwGetMonitorContentScaleWin32(HMONITOR handle, float* xscale, float* yscale)
|
|
||||||
{
|
|
||||||
UINT xdpi, ydpi;
|
|
||||||
|
|
||||||
if (IsWindows8Point1OrGreater())
|
|
||||||
GetDpiForMonitor(handle, MDT_EFFECTIVE_DPI, &xdpi, &ydpi);
|
|
||||||
else
|
|
||||||
{
|
|
||||||
const HDC dc = GetDC(NULL);
|
|
||||||
xdpi = GetDeviceCaps(dc, LOGPIXELSX);
|
|
||||||
ydpi = GetDeviceCaps(dc, LOGPIXELSY);
|
|
||||||
ReleaseDC(NULL, dc);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (xscale)
|
|
||||||
*xscale = xdpi / (float) USER_DEFAULT_SCREEN_DPI;
|
|
||||||
if (yscale)
|
|
||||||
*yscale = ydpi / (float) USER_DEFAULT_SCREEN_DPI;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
//////////////////////////////////////////////////////////////////////////
|
|
||||||
////// GLFW platform API //////
|
|
||||||
//////////////////////////////////////////////////////////////////////////
|
|
||||||
|
|
||||||
void _glfwPlatformFreeMonitor(_GLFWmonitor* monitor)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
void _glfwPlatformGetMonitorPos(_GLFWmonitor* monitor, int* xpos, int* ypos)
|
|
||||||
{
|
|
||||||
DEVMODEW dm;
|
|
||||||
ZeroMemory(&dm, sizeof(dm));
|
|
||||||
dm.dmSize = sizeof(dm);
|
|
||||||
|
|
||||||
EnumDisplaySettingsExW(monitor->win32.adapterName,
|
|
||||||
ENUM_CURRENT_SETTINGS,
|
|
||||||
&dm,
|
|
||||||
EDS_ROTATEDMODE);
|
|
||||||
|
|
||||||
if (xpos)
|
|
||||||
*xpos = dm.dmPosition.x;
|
|
||||||
if (ypos)
|
|
||||||
*ypos = dm.dmPosition.y;
|
|
||||||
}
|
|
||||||
|
|
||||||
void _glfwPlatformGetMonitorContentScale(_GLFWmonitor* monitor,
|
|
||||||
float* xscale, float* yscale)
|
|
||||||
{
|
|
||||||
_glfwGetMonitorContentScaleWin32(monitor->win32.handle, xscale, yscale);
|
|
||||||
}
|
|
||||||
|
|
||||||
GLFWvidmode* _glfwPlatformGetVideoModes(_GLFWmonitor* monitor, int* count)
|
|
||||||
{
|
|
||||||
int modeIndex = 0, size = 0;
|
|
||||||
GLFWvidmode* result = NULL;
|
|
||||||
|
|
||||||
*count = 0;
|
|
||||||
|
|
||||||
for (;;)
|
|
||||||
{
|
|
||||||
int i;
|
|
||||||
GLFWvidmode mode;
|
|
||||||
DEVMODEW dm;
|
|
||||||
|
|
||||||
ZeroMemory(&dm, sizeof(dm));
|
|
||||||
dm.dmSize = sizeof(dm);
|
|
||||||
|
|
||||||
if (!EnumDisplaySettingsW(monitor->win32.adapterName, modeIndex, &dm))
|
|
||||||
break;
|
|
||||||
|
|
||||||
modeIndex++;
|
|
||||||
|
|
||||||
// Skip modes with less than 15 BPP
|
|
||||||
if (dm.dmBitsPerPel < 15)
|
|
||||||
continue;
|
|
||||||
|
|
||||||
mode.width = dm.dmPelsWidth;
|
|
||||||
mode.height = dm.dmPelsHeight;
|
|
||||||
mode.refreshRate = dm.dmDisplayFrequency;
|
|
||||||
_glfwSplitBPP(dm.dmBitsPerPel,
|
|
||||||
&mode.redBits,
|
|
||||||
&mode.greenBits,
|
|
||||||
&mode.blueBits);
|
|
||||||
|
|
||||||
for (i = 0; i < *count; i++)
|
|
||||||
{
|
|
||||||
if (_glfwCompareVideoModes(result + i, &mode) == 0)
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Skip duplicate modes
|
|
||||||
if (i < *count)
|
|
||||||
continue;
|
|
||||||
|
|
||||||
if (monitor->win32.modesPruned)
|
|
||||||
{
|
|
||||||
// Skip modes not supported by the connected displays
|
|
||||||
if (ChangeDisplaySettingsExW(monitor->win32.adapterName,
|
|
||||||
&dm,
|
|
||||||
NULL,
|
|
||||||
CDS_TEST,
|
|
||||||
NULL) != DISP_CHANGE_SUCCESSFUL)
|
|
||||||
{
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (*count == size)
|
|
||||||
{
|
|
||||||
size += 128;
|
|
||||||
result = (GLFWvidmode*) realloc(result, size * sizeof(GLFWvidmode));
|
|
||||||
}
|
|
||||||
|
|
||||||
(*count)++;
|
|
||||||
result[*count - 1] = mode;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!*count)
|
|
||||||
{
|
|
||||||
// HACK: Report the current mode if no valid modes were found
|
|
||||||
result = calloc(1, sizeof(GLFWvidmode));
|
|
||||||
_glfwPlatformGetVideoMode(monitor, result);
|
|
||||||
*count = 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
void _glfwPlatformGetVideoMode(_GLFWmonitor* monitor, GLFWvidmode* mode)
|
|
||||||
{
|
|
||||||
DEVMODEW dm;
|
|
||||||
ZeroMemory(&dm, sizeof(dm));
|
|
||||||
dm.dmSize = sizeof(dm);
|
|
||||||
|
|
||||||
EnumDisplaySettingsW(monitor->win32.adapterName, ENUM_CURRENT_SETTINGS, &dm);
|
|
||||||
|
|
||||||
mode->width = dm.dmPelsWidth;
|
|
||||||
mode->height = dm.dmPelsHeight;
|
|
||||||
mode->refreshRate = dm.dmDisplayFrequency;
|
|
||||||
_glfwSplitBPP(dm.dmBitsPerPel,
|
|
||||||
&mode->redBits,
|
|
||||||
&mode->greenBits,
|
|
||||||
&mode->blueBits);
|
|
||||||
}
|
|
||||||
|
|
||||||
GLFWbool _glfwPlatformGetGammaRamp(_GLFWmonitor* monitor, GLFWgammaramp* ramp)
|
|
||||||
{
|
|
||||||
HDC dc;
|
|
||||||
WORD values[768];
|
|
||||||
|
|
||||||
dc = CreateDCW(L"DISPLAY", monitor->win32.adapterName, NULL, NULL);
|
|
||||||
GetDeviceGammaRamp(dc, values);
|
|
||||||
DeleteDC(dc);
|
|
||||||
|
|
||||||
_glfwAllocGammaArrays(ramp, 256);
|
|
||||||
|
|
||||||
memcpy(ramp->red, values + 0, 256 * sizeof(unsigned short));
|
|
||||||
memcpy(ramp->green, values + 256, 256 * sizeof(unsigned short));
|
|
||||||
memcpy(ramp->blue, values + 512, 256 * sizeof(unsigned short));
|
|
||||||
|
|
||||||
return GLFW_TRUE;
|
|
||||||
}
|
|
||||||
|
|
||||||
void _glfwPlatformSetGammaRamp(_GLFWmonitor* monitor, const GLFWgammaramp* ramp)
|
|
||||||
{
|
|
||||||
HDC dc;
|
|
||||||
WORD values[768];
|
|
||||||
|
|
||||||
if (ramp->size != 256)
|
|
||||||
{
|
|
||||||
_glfwInputError(GLFW_PLATFORM_ERROR,
|
|
||||||
"Win32: Gamma ramp size must be 256");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
memcpy(values + 0, ramp->red, 256 * sizeof(unsigned short));
|
|
||||||
memcpy(values + 256, ramp->green, 256 * sizeof(unsigned short));
|
|
||||||
memcpy(values + 512, ramp->blue, 256 * sizeof(unsigned short));
|
|
||||||
|
|
||||||
dc = CreateDCW(L"DISPLAY", monitor->win32.adapterName, NULL, NULL);
|
|
||||||
SetDeviceGammaRamp(dc, values);
|
|
||||||
DeleteDC(dc);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
//////////////////////////////////////////////////////////////////////////
|
|
||||||
////// GLFW native API //////
|
|
||||||
//////////////////////////////////////////////////////////////////////////
|
|
||||||
|
|
||||||
GLFWAPI const char* glfwGetWin32Adapter(GLFWmonitor* handle)
|
|
||||||
{
|
|
||||||
_GLFWmonitor* monitor = (_GLFWmonitor*) handle;
|
|
||||||
_GLFW_REQUIRE_INIT_OR_RETURN(NULL);
|
|
||||||
return monitor->win32.publicAdapterName;
|
|
||||||
}
|
|
||||||
|
|
||||||
GLFWAPI const char* glfwGetWin32Monitor(GLFWmonitor* handle)
|
|
||||||
{
|
|
||||||
_GLFWmonitor* monitor = (_GLFWmonitor*) handle;
|
|
||||||
_GLFW_REQUIRE_INIT_OR_RETURN(NULL);
|
|
||||||
return monitor->win32.publicDisplayName;
|
|
||||||
}
|
|
||||||
449
glfw/win32_platform.h
vendored
449
glfw/win32_platform.h
vendored
@@ -1,449 +0,0 @@
|
|||||||
//========================================================================
|
|
||||||
// GLFW 3.3 Win32 - www.glfw.org
|
|
||||||
//------------------------------------------------------------------------
|
|
||||||
// Copyright (c) 2002-2006 Marcus Geelnard
|
|
||||||
// Copyright (c) 2006-2016 Camilla Löwy <elmindreda@glfw.org>
|
|
||||||
//
|
|
||||||
// This software is provided 'as-is', without any express or implied
|
|
||||||
// warranty. In no event will the authors be held liable for any damages
|
|
||||||
// arising from the use of this software.
|
|
||||||
//
|
|
||||||
// Permission is granted to anyone to use this software for any purpose,
|
|
||||||
// including commercial applications, and to alter it and redistribute it
|
|
||||||
// freely, subject to the following restrictions:
|
|
||||||
//
|
|
||||||
// 1. The origin of this software must not be misrepresented; you must not
|
|
||||||
// claim that you wrote the original software. If you use this software
|
|
||||||
// in a product, an acknowledgment in the product documentation would
|
|
||||||
// be appreciated but is not required.
|
|
||||||
//
|
|
||||||
// 2. Altered source versions must be plainly marked as such, and must not
|
|
||||||
// be misrepresented as being the original software.
|
|
||||||
//
|
|
||||||
// 3. This notice may not be removed or altered from any source
|
|
||||||
// distribution.
|
|
||||||
//
|
|
||||||
//========================================================================
|
|
||||||
|
|
||||||
// We don't need all the fancy stuff
|
|
||||||
#ifndef NOMINMAX
|
|
||||||
#define NOMINMAX
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifndef VC_EXTRALEAN
|
|
||||||
#define VC_EXTRALEAN
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifndef WIN32_LEAN_AND_MEAN
|
|
||||||
#define WIN32_LEAN_AND_MEAN
|
|
||||||
#endif
|
|
||||||
|
|
||||||
// This is a workaround for the fact that glfw3.h needs to export APIENTRY (for
|
|
||||||
// example to allow applications to correctly declare a GL_ARB_debug_output
|
|
||||||
// callback) but windows.h assumes no one will define APIENTRY before it does
|
|
||||||
#undef APIENTRY
|
|
||||||
|
|
||||||
// GLFW on Windows is Unicode only and does not work in MBCS mode
|
|
||||||
#ifndef UNICODE
|
|
||||||
#define UNICODE
|
|
||||||
#endif
|
|
||||||
|
|
||||||
// GLFW requires Windows XP or later
|
|
||||||
#if WINVER < 0x0501
|
|
||||||
#undef WINVER
|
|
||||||
#define WINVER 0x0501
|
|
||||||
#endif
|
|
||||||
#if _WIN32_WINNT < 0x0501
|
|
||||||
#undef _WIN32_WINNT
|
|
||||||
#define _WIN32_WINNT 0x0501
|
|
||||||
#endif
|
|
||||||
|
|
||||||
// GLFW uses DirectInput8 interfaces
|
|
||||||
#define DIRECTINPUT_VERSION 0x0800
|
|
||||||
|
|
||||||
#include <wctype.h>
|
|
||||||
#include <windows.h>
|
|
||||||
#include <dinput.h>
|
|
||||||
#include <xinput.h>
|
|
||||||
#include <dbt.h>
|
|
||||||
|
|
||||||
// HACK: Define macros that some windows.h variants don't
|
|
||||||
#ifndef WM_MOUSEHWHEEL
|
|
||||||
#define WM_MOUSEHWHEEL 0x020E
|
|
||||||
#endif
|
|
||||||
#ifndef WM_DWMCOMPOSITIONCHANGED
|
|
||||||
#define WM_DWMCOMPOSITIONCHANGED 0x031E
|
|
||||||
#endif
|
|
||||||
#ifndef WM_COPYGLOBALDATA
|
|
||||||
#define WM_COPYGLOBALDATA 0x0049
|
|
||||||
#endif
|
|
||||||
#ifndef WM_UNICHAR
|
|
||||||
#define WM_UNICHAR 0x0109
|
|
||||||
#endif
|
|
||||||
#ifndef UNICODE_NOCHAR
|
|
||||||
#define UNICODE_NOCHAR 0xFFFF
|
|
||||||
#endif
|
|
||||||
#ifndef WM_DPICHANGED
|
|
||||||
#define WM_DPICHANGED 0x02E0
|
|
||||||
#endif
|
|
||||||
#ifndef GET_XBUTTON_WPARAM
|
|
||||||
#define GET_XBUTTON_WPARAM(w) (HIWORD(w))
|
|
||||||
#endif
|
|
||||||
#ifndef EDS_ROTATEDMODE
|
|
||||||
#define EDS_ROTATEDMODE 0x00000004
|
|
||||||
#endif
|
|
||||||
#ifndef DISPLAY_DEVICE_ACTIVE
|
|
||||||
#define DISPLAY_DEVICE_ACTIVE 0x00000001
|
|
||||||
#endif
|
|
||||||
#ifndef _WIN32_WINNT_WINBLUE
|
|
||||||
#define _WIN32_WINNT_WINBLUE 0x0602
|
|
||||||
#endif
|
|
||||||
#ifndef WM_GETDPISCALEDSIZE
|
|
||||||
#define WM_GETDPISCALEDSIZE 0x02e4
|
|
||||||
#endif
|
|
||||||
#ifndef USER_DEFAULT_SCREEN_DPI
|
|
||||||
#define USER_DEFAULT_SCREEN_DPI 96
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#if WINVER < 0x0601
|
|
||||||
typedef struct
|
|
||||||
{
|
|
||||||
DWORD cbSize;
|
|
||||||
DWORD ExtStatus;
|
|
||||||
} CHANGEFILTERSTRUCT;
|
|
||||||
#ifndef MSGFLT_ALLOW
|
|
||||||
#define MSGFLT_ALLOW 1
|
|
||||||
#endif
|
|
||||||
#endif /*Windows 7*/
|
|
||||||
|
|
||||||
#if WINVER < 0x0600
|
|
||||||
#define DWM_BB_ENABLE 0x00000001
|
|
||||||
#define DWM_BB_BLURREGION 0x00000002
|
|
||||||
typedef struct
|
|
||||||
{
|
|
||||||
DWORD dwFlags;
|
|
||||||
BOOL fEnable;
|
|
||||||
HRGN hRgnBlur;
|
|
||||||
BOOL fTransitionOnMaximized;
|
|
||||||
} DWM_BLURBEHIND;
|
|
||||||
#else
|
|
||||||
#include <dwmapi.h>
|
|
||||||
#endif /*Windows Vista*/
|
|
||||||
|
|
||||||
#ifndef DPI_ENUMS_DECLARED
|
|
||||||
typedef enum
|
|
||||||
{
|
|
||||||
PROCESS_DPI_UNAWARE = 0,
|
|
||||||
PROCESS_SYSTEM_DPI_AWARE = 1,
|
|
||||||
PROCESS_PER_MONITOR_DPI_AWARE = 2
|
|
||||||
} PROCESS_DPI_AWARENESS;
|
|
||||||
typedef enum
|
|
||||||
{
|
|
||||||
MDT_EFFECTIVE_DPI = 0,
|
|
||||||
MDT_ANGULAR_DPI = 1,
|
|
||||||
MDT_RAW_DPI = 2,
|
|
||||||
MDT_DEFAULT = MDT_EFFECTIVE_DPI
|
|
||||||
} MONITOR_DPI_TYPE;
|
|
||||||
#endif /*DPI_ENUMS_DECLARED*/
|
|
||||||
|
|
||||||
#ifndef DPI_AWARENESS_CONTEXT_PER_MONITOR_AWARE_V2
|
|
||||||
DECLARE_HANDLE(DPI_AWARENESS_CONTEXT);
|
|
||||||
#define DPI_AWARENESS_CONTEXT_PER_MONITOR_AWARE_V2 ((DPI_AWARENESS_CONTEXT) -4)
|
|
||||||
#endif /*DPI_AWARENESS_CONTEXT_PER_MONITOR_AWARE_V2*/
|
|
||||||
|
|
||||||
// HACK: Define versionhelpers.h functions manually as MinGW lacks the header
|
|
||||||
#define IsWindowsXPOrGreater() \
|
|
||||||
_glfwIsWindowsVersionOrGreaterWin32(HIBYTE(_WIN32_WINNT_WINXP), \
|
|
||||||
LOBYTE(_WIN32_WINNT_WINXP), 0)
|
|
||||||
#define IsWindowsVistaOrGreater() \
|
|
||||||
_glfwIsWindowsVersionOrGreaterWin32(HIBYTE(_WIN32_WINNT_VISTA), \
|
|
||||||
LOBYTE(_WIN32_WINNT_VISTA), 0)
|
|
||||||
#define IsWindows7OrGreater() \
|
|
||||||
_glfwIsWindowsVersionOrGreaterWin32(HIBYTE(_WIN32_WINNT_WIN7), \
|
|
||||||
LOBYTE(_WIN32_WINNT_WIN7), 0)
|
|
||||||
#define IsWindows8OrGreater() \
|
|
||||||
_glfwIsWindowsVersionOrGreaterWin32(HIBYTE(_WIN32_WINNT_WIN8), \
|
|
||||||
LOBYTE(_WIN32_WINNT_WIN8), 0)
|
|
||||||
#define IsWindows8Point1OrGreater() \
|
|
||||||
_glfwIsWindowsVersionOrGreaterWin32(HIBYTE(_WIN32_WINNT_WINBLUE), \
|
|
||||||
LOBYTE(_WIN32_WINNT_WINBLUE), 0)
|
|
||||||
|
|
||||||
#define _glfwIsWindows10AnniversaryUpdateOrGreaterWin32() \
|
|
||||||
_glfwIsWindows10BuildOrGreaterWin32(14393)
|
|
||||||
#define _glfwIsWindows10CreatorsUpdateOrGreaterWin32() \
|
|
||||||
_glfwIsWindows10BuildOrGreaterWin32(15063)
|
|
||||||
|
|
||||||
// HACK: Define macros that some xinput.h variants don't
|
|
||||||
#ifndef XINPUT_CAPS_WIRELESS
|
|
||||||
#define XINPUT_CAPS_WIRELESS 0x0002
|
|
||||||
#endif
|
|
||||||
#ifndef XINPUT_DEVSUBTYPE_WHEEL
|
|
||||||
#define XINPUT_DEVSUBTYPE_WHEEL 0x02
|
|
||||||
#endif
|
|
||||||
#ifndef XINPUT_DEVSUBTYPE_ARCADE_STICK
|
|
||||||
#define XINPUT_DEVSUBTYPE_ARCADE_STICK 0x03
|
|
||||||
#endif
|
|
||||||
#ifndef XINPUT_DEVSUBTYPE_FLIGHT_STICK
|
|
||||||
#define XINPUT_DEVSUBTYPE_FLIGHT_STICK 0x04
|
|
||||||
#endif
|
|
||||||
#ifndef XINPUT_DEVSUBTYPE_DANCE_PAD
|
|
||||||
#define XINPUT_DEVSUBTYPE_DANCE_PAD 0x05
|
|
||||||
#endif
|
|
||||||
#ifndef XINPUT_DEVSUBTYPE_GUITAR
|
|
||||||
#define XINPUT_DEVSUBTYPE_GUITAR 0x06
|
|
||||||
#endif
|
|
||||||
#ifndef XINPUT_DEVSUBTYPE_DRUM_KIT
|
|
||||||
#define XINPUT_DEVSUBTYPE_DRUM_KIT 0x08
|
|
||||||
#endif
|
|
||||||
#ifndef XINPUT_DEVSUBTYPE_ARCADE_PAD
|
|
||||||
#define XINPUT_DEVSUBTYPE_ARCADE_PAD 0x13
|
|
||||||
#endif
|
|
||||||
#ifndef XUSER_MAX_COUNT
|
|
||||||
#define XUSER_MAX_COUNT 4
|
|
||||||
#endif
|
|
||||||
|
|
||||||
// HACK: Define macros that some dinput.h variants don't
|
|
||||||
#ifndef DIDFT_OPTIONAL
|
|
||||||
#define DIDFT_OPTIONAL 0x80000000
|
|
||||||
#endif
|
|
||||||
|
|
||||||
// winmm.dll function pointer typedefs
|
|
||||||
typedef DWORD (WINAPI * PFN_timeGetTime)(void);
|
|
||||||
#define timeGetTime _glfw.win32.winmm.GetTime
|
|
||||||
|
|
||||||
// xinput.dll function pointer typedefs
|
|
||||||
typedef DWORD (WINAPI * PFN_XInputGetCapabilities)(DWORD,DWORD,XINPUT_CAPABILITIES*);
|
|
||||||
typedef DWORD (WINAPI * PFN_XInputGetState)(DWORD,XINPUT_STATE*);
|
|
||||||
#define XInputGetCapabilities _glfw.win32.xinput.GetCapabilities
|
|
||||||
#define XInputGetState _glfw.win32.xinput.GetState
|
|
||||||
|
|
||||||
// dinput8.dll function pointer typedefs
|
|
||||||
typedef HRESULT (WINAPI * PFN_DirectInput8Create)(HINSTANCE,DWORD,REFIID,LPVOID*,LPUNKNOWN);
|
|
||||||
#define DirectInput8Create _glfw.win32.dinput8.Create
|
|
||||||
|
|
||||||
// user32.dll function pointer typedefs
|
|
||||||
typedef BOOL (WINAPI * PFN_SetProcessDPIAware)(void);
|
|
||||||
typedef BOOL (WINAPI * PFN_ChangeWindowMessageFilterEx)(HWND,UINT,DWORD,CHANGEFILTERSTRUCT*);
|
|
||||||
typedef BOOL (WINAPI * PFN_EnableNonClientDpiScaling)(HWND);
|
|
||||||
typedef BOOL (WINAPI * PFN_SetProcessDpiAwarenessContext)(DPI_AWARENESS_CONTEXT);
|
|
||||||
typedef UINT (WINAPI * PFN_GetDpiForWindow)(HWND);
|
|
||||||
typedef BOOL (WINAPI * PFN_AdjustWindowRectExForDpi)(LPRECT,DWORD,BOOL,DWORD,UINT);
|
|
||||||
#define SetProcessDPIAware _glfw.win32.user32.SetProcessDPIAware_
|
|
||||||
#define ChangeWindowMessageFilterEx _glfw.win32.user32.ChangeWindowMessageFilterEx_
|
|
||||||
#define EnableNonClientDpiScaling _glfw.win32.user32.EnableNonClientDpiScaling_
|
|
||||||
#define SetProcessDpiAwarenessContext _glfw.win32.user32.SetProcessDpiAwarenessContext_
|
|
||||||
#define GetDpiForWindow _glfw.win32.user32.GetDpiForWindow_
|
|
||||||
#define AdjustWindowRectExForDpi _glfw.win32.user32.AdjustWindowRectExForDpi_
|
|
||||||
|
|
||||||
// dwmapi.dll function pointer typedefs
|
|
||||||
typedef HRESULT (WINAPI * PFN_DwmIsCompositionEnabled)(BOOL*);
|
|
||||||
typedef HRESULT (WINAPI * PFN_DwmFlush)(VOID);
|
|
||||||
typedef HRESULT(WINAPI * PFN_DwmEnableBlurBehindWindow)(HWND,const DWM_BLURBEHIND*);
|
|
||||||
#define DwmIsCompositionEnabled _glfw.win32.dwmapi.IsCompositionEnabled
|
|
||||||
#define DwmFlush _glfw.win32.dwmapi.Flush
|
|
||||||
#define DwmEnableBlurBehindWindow _glfw.win32.dwmapi.EnableBlurBehindWindow
|
|
||||||
|
|
||||||
// shcore.dll function pointer typedefs
|
|
||||||
typedef HRESULT (WINAPI * PFN_SetProcessDpiAwareness)(PROCESS_DPI_AWARENESS);
|
|
||||||
typedef HRESULT (WINAPI * PFN_GetDpiForMonitor)(HMONITOR,MONITOR_DPI_TYPE,UINT*,UINT*);
|
|
||||||
#define SetProcessDpiAwareness _glfw.win32.shcore.SetProcessDpiAwareness_
|
|
||||||
#define GetDpiForMonitor _glfw.win32.shcore.GetDpiForMonitor_
|
|
||||||
|
|
||||||
// ntdll.dll function pointer typedefs
|
|
||||||
typedef LONG (WINAPI * PFN_RtlVerifyVersionInfo)(OSVERSIONINFOEXW*,ULONG,ULONGLONG);
|
|
||||||
#define RtlVerifyVersionInfo _glfw.win32.ntdll.RtlVerifyVersionInfo_
|
|
||||||
|
|
||||||
typedef VkFlags VkWin32SurfaceCreateFlagsKHR;
|
|
||||||
|
|
||||||
typedef struct VkWin32SurfaceCreateInfoKHR
|
|
||||||
{
|
|
||||||
VkStructureType sType;
|
|
||||||
const void* pNext;
|
|
||||||
VkWin32SurfaceCreateFlagsKHR flags;
|
|
||||||
HINSTANCE hinstance;
|
|
||||||
HWND hwnd;
|
|
||||||
} VkWin32SurfaceCreateInfoKHR;
|
|
||||||
|
|
||||||
typedef VkResult (APIENTRY *PFN_vkCreateWin32SurfaceKHR)(VkInstance,const VkWin32SurfaceCreateInfoKHR*,const VkAllocationCallbacks*,VkSurfaceKHR*);
|
|
||||||
typedef VkBool32 (APIENTRY *PFN_vkGetPhysicalDeviceWin32PresentationSupportKHR)(VkPhysicalDevice,uint32_t);
|
|
||||||
|
|
||||||
#include "win32_joystick.h"
|
|
||||||
#include "wgl_context.h"
|
|
||||||
#include "egl_context.h"
|
|
||||||
#include "osmesa_context.h"
|
|
||||||
|
|
||||||
#if !defined(_GLFW_WNDCLASSNAME)
|
|
||||||
#define _GLFW_WNDCLASSNAME L"GLFW30"
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#define _glfw_dlopen(name) LoadLibraryA(name)
|
|
||||||
#define _glfw_dlclose(handle) FreeLibrary((HMODULE) handle)
|
|
||||||
#define _glfw_dlsym(handle, name) GetProcAddress((HMODULE) handle, name)
|
|
||||||
|
|
||||||
#define _GLFW_EGL_NATIVE_WINDOW ((EGLNativeWindowType) window->win32.handle)
|
|
||||||
#define _GLFW_EGL_NATIVE_DISPLAY EGL_DEFAULT_DISPLAY
|
|
||||||
|
|
||||||
#define _GLFW_PLATFORM_WINDOW_STATE _GLFWwindowWin32 win32
|
|
||||||
#define _GLFW_PLATFORM_LIBRARY_WINDOW_STATE _GLFWlibraryWin32 win32
|
|
||||||
#define _GLFW_PLATFORM_LIBRARY_TIMER_STATE _GLFWtimerWin32 win32
|
|
||||||
#define _GLFW_PLATFORM_MONITOR_STATE _GLFWmonitorWin32 win32
|
|
||||||
#define _GLFW_PLATFORM_CURSOR_STATE _GLFWcursorWin32 win32
|
|
||||||
#define _GLFW_PLATFORM_TLS_STATE _GLFWtlsWin32 win32
|
|
||||||
#define _GLFW_PLATFORM_MUTEX_STATE _GLFWmutexWin32 win32
|
|
||||||
|
|
||||||
|
|
||||||
// Win32-specific per-window data
|
|
||||||
//
|
|
||||||
typedef struct _GLFWwindowWin32
|
|
||||||
{
|
|
||||||
HWND handle;
|
|
||||||
HICON bigIcon;
|
|
||||||
HICON smallIcon;
|
|
||||||
|
|
||||||
GLFWbool cursorTracked;
|
|
||||||
GLFWbool frameAction;
|
|
||||||
GLFWbool iconified;
|
|
||||||
GLFWbool maximized;
|
|
||||||
// Whether to enable framebuffer transparency on DWM
|
|
||||||
GLFWbool transparent;
|
|
||||||
GLFWbool scaleToMonitor;
|
|
||||||
|
|
||||||
// The last received cursor position, regardless of source
|
|
||||||
int lastCursorPosX, lastCursorPosY;
|
|
||||||
|
|
||||||
} _GLFWwindowWin32;
|
|
||||||
|
|
||||||
// Win32-specific global data
|
|
||||||
//
|
|
||||||
typedef struct _GLFWlibraryWin32
|
|
||||||
{
|
|
||||||
HWND helperWindowHandle;
|
|
||||||
HDEVNOTIFY deviceNotificationHandle;
|
|
||||||
DWORD foregroundLockTimeout;
|
|
||||||
int acquiredMonitorCount;
|
|
||||||
char* clipboardString;
|
|
||||||
short int keycodes[512];
|
|
||||||
short int scancodes[GLFW_KEY_LAST + 1];
|
|
||||||
char keynames[GLFW_KEY_LAST + 1][5];
|
|
||||||
// Where to place the cursor when re-enabled
|
|
||||||
double restoreCursorPosX, restoreCursorPosY;
|
|
||||||
// The window whose disabled cursor mode is active
|
|
||||||
_GLFWwindow* disabledCursorWindow;
|
|
||||||
RAWINPUT* rawInput;
|
|
||||||
int rawInputSize;
|
|
||||||
UINT mouseTrailSize;
|
|
||||||
|
|
||||||
struct {
|
|
||||||
HINSTANCE instance;
|
|
||||||
PFN_timeGetTime GetTime;
|
|
||||||
} winmm;
|
|
||||||
|
|
||||||
struct {
|
|
||||||
HINSTANCE instance;
|
|
||||||
PFN_DirectInput8Create Create;
|
|
||||||
IDirectInput8W* api;
|
|
||||||
} dinput8;
|
|
||||||
|
|
||||||
struct {
|
|
||||||
HINSTANCE instance;
|
|
||||||
PFN_XInputGetCapabilities GetCapabilities;
|
|
||||||
PFN_XInputGetState GetState;
|
|
||||||
} xinput;
|
|
||||||
|
|
||||||
struct {
|
|
||||||
HINSTANCE instance;
|
|
||||||
PFN_SetProcessDPIAware SetProcessDPIAware_;
|
|
||||||
PFN_ChangeWindowMessageFilterEx ChangeWindowMessageFilterEx_;
|
|
||||||
PFN_EnableNonClientDpiScaling EnableNonClientDpiScaling_;
|
|
||||||
PFN_SetProcessDpiAwarenessContext SetProcessDpiAwarenessContext_;
|
|
||||||
PFN_GetDpiForWindow GetDpiForWindow_;
|
|
||||||
PFN_AdjustWindowRectExForDpi AdjustWindowRectExForDpi_;
|
|
||||||
} user32;
|
|
||||||
|
|
||||||
struct {
|
|
||||||
HINSTANCE instance;
|
|
||||||
PFN_DwmIsCompositionEnabled IsCompositionEnabled;
|
|
||||||
PFN_DwmFlush Flush;
|
|
||||||
PFN_DwmEnableBlurBehindWindow EnableBlurBehindWindow;
|
|
||||||
} dwmapi;
|
|
||||||
|
|
||||||
struct {
|
|
||||||
HINSTANCE instance;
|
|
||||||
PFN_SetProcessDpiAwareness SetProcessDpiAwareness_;
|
|
||||||
PFN_GetDpiForMonitor GetDpiForMonitor_;
|
|
||||||
} shcore;
|
|
||||||
|
|
||||||
struct {
|
|
||||||
HINSTANCE instance;
|
|
||||||
PFN_RtlVerifyVersionInfo RtlVerifyVersionInfo_;
|
|
||||||
} ntdll;
|
|
||||||
|
|
||||||
} _GLFWlibraryWin32;
|
|
||||||
|
|
||||||
// Win32-specific per-monitor data
|
|
||||||
//
|
|
||||||
typedef struct _GLFWmonitorWin32
|
|
||||||
{
|
|
||||||
HMONITOR handle;
|
|
||||||
// This size matches the static size of DISPLAY_DEVICE.DeviceName
|
|
||||||
WCHAR adapterName[32];
|
|
||||||
WCHAR displayName[32];
|
|
||||||
char publicAdapterName[32];
|
|
||||||
char publicDisplayName[32];
|
|
||||||
GLFWbool modesPruned;
|
|
||||||
GLFWbool modeChanged;
|
|
||||||
|
|
||||||
} _GLFWmonitorWin32;
|
|
||||||
|
|
||||||
// Win32-specific per-cursor data
|
|
||||||
//
|
|
||||||
typedef struct _GLFWcursorWin32
|
|
||||||
{
|
|
||||||
HCURSOR handle;
|
|
||||||
|
|
||||||
} _GLFWcursorWin32;
|
|
||||||
|
|
||||||
// Win32-specific global timer data
|
|
||||||
//
|
|
||||||
typedef struct _GLFWtimerWin32
|
|
||||||
{
|
|
||||||
GLFWbool hasPC;
|
|
||||||
uint64_t frequency;
|
|
||||||
|
|
||||||
} _GLFWtimerWin32;
|
|
||||||
|
|
||||||
// Win32-specific thread local storage data
|
|
||||||
//
|
|
||||||
typedef struct _GLFWtlsWin32
|
|
||||||
{
|
|
||||||
GLFWbool allocated;
|
|
||||||
DWORD index;
|
|
||||||
|
|
||||||
} _GLFWtlsWin32;
|
|
||||||
|
|
||||||
// Win32-specific mutex data
|
|
||||||
//
|
|
||||||
typedef struct _GLFWmutexWin32
|
|
||||||
{
|
|
||||||
GLFWbool allocated;
|
|
||||||
CRITICAL_SECTION section;
|
|
||||||
|
|
||||||
} _GLFWmutexWin32;
|
|
||||||
|
|
||||||
|
|
||||||
GLFWbool _glfwRegisterWindowClassWin32(void);
|
|
||||||
void _glfwUnregisterWindowClassWin32(void);
|
|
||||||
|
|
||||||
WCHAR* _glfwCreateWideStringFromUTF8Win32(const char* source);
|
|
||||||
char* _glfwCreateUTF8FromWideStringWin32(const WCHAR* source);
|
|
||||||
BOOL _glfwIsWindowsVersionOrGreaterWin32(WORD major, WORD minor, WORD sp);
|
|
||||||
BOOL _glfwIsWindows10BuildOrGreaterWin32(WORD build);
|
|
||||||
void _glfwInputErrorWin32(int error, const char* description);
|
|
||||||
void _glfwUpdateKeyNamesWin32(void);
|
|
||||||
|
|
||||||
void _glfwInitTimerWin32(void);
|
|
||||||
|
|
||||||
void _glfwPollMonitorsWin32(void);
|
|
||||||
void _glfwSetVideoModeWin32(_GLFWmonitor* monitor, const GLFWvidmode* desired);
|
|
||||||
void _glfwRestoreVideoModeWin32(_GLFWmonitor* monitor);
|
|
||||||
void _glfwGetMonitorContentScaleWin32(HMONITOR handle, float* xscale, float* yscale);
|
|
||||||
97
glfw/win32_thread.c
vendored
97
glfw/win32_thread.c
vendored
@@ -1,97 +0,0 @@
|
|||||||
//========================================================================
|
|
||||||
// GLFW 3.3 Win32 - www.glfw.org
|
|
||||||
//------------------------------------------------------------------------
|
|
||||||
// Copyright (c) 2002-2006 Marcus Geelnard
|
|
||||||
// Copyright (c) 2006-2016 Camilla Löwy <elmindreda@glfw.org>
|
|
||||||
//
|
|
||||||
// This software is provided 'as-is', without any express or implied
|
|
||||||
// warranty. In no event will the authors be held liable for any damages
|
|
||||||
// arising from the use of this software.
|
|
||||||
//
|
|
||||||
// Permission is granted to anyone to use this software for any purpose,
|
|
||||||
// including commercial applications, and to alter it and redistribute it
|
|
||||||
// freely, subject to the following restrictions:
|
|
||||||
//
|
|
||||||
// 1. The origin of this software must not be misrepresented; you must not
|
|
||||||
// claim that you wrote the original software. If you use this software
|
|
||||||
// in a product, an acknowledgment in the product documentation would
|
|
||||||
// be appreciated but is not required.
|
|
||||||
//
|
|
||||||
// 2. Altered source versions must be plainly marked as such, and must not
|
|
||||||
// be misrepresented as being the original software.
|
|
||||||
//
|
|
||||||
// 3. This notice may not be removed or altered from any source
|
|
||||||
// distribution.
|
|
||||||
//
|
|
||||||
//========================================================================
|
|
||||||
|
|
||||||
#include "internal.h"
|
|
||||||
|
|
||||||
#include <assert.h>
|
|
||||||
|
|
||||||
|
|
||||||
//////////////////////////////////////////////////////////////////////////
|
|
||||||
////// GLFW platform API //////
|
|
||||||
//////////////////////////////////////////////////////////////////////////
|
|
||||||
|
|
||||||
GLFWbool _glfwPlatformCreateTls(_GLFWtls* tls)
|
|
||||||
{
|
|
||||||
assert(tls->win32.allocated == GLFW_FALSE);
|
|
||||||
|
|
||||||
tls->win32.index = TlsAlloc();
|
|
||||||
if (tls->win32.index == TLS_OUT_OF_INDEXES)
|
|
||||||
{
|
|
||||||
_glfwInputErrorWin32(GLFW_PLATFORM_ERROR,
|
|
||||||
"Win32: Failed to allocate TLS index");
|
|
||||||
return GLFW_FALSE;
|
|
||||||
}
|
|
||||||
|
|
||||||
tls->win32.allocated = GLFW_TRUE;
|
|
||||||
return GLFW_TRUE;
|
|
||||||
}
|
|
||||||
|
|
||||||
void _glfwPlatformDestroyTls(_GLFWtls* tls)
|
|
||||||
{
|
|
||||||
if (tls->win32.allocated)
|
|
||||||
TlsFree(tls->win32.index);
|
|
||||||
memset(tls, 0, sizeof(_GLFWtls));
|
|
||||||
}
|
|
||||||
|
|
||||||
void* _glfwPlatformGetTls(_GLFWtls* tls)
|
|
||||||
{
|
|
||||||
assert(tls->win32.allocated == GLFW_TRUE);
|
|
||||||
return TlsGetValue(tls->win32.index);
|
|
||||||
}
|
|
||||||
|
|
||||||
void _glfwPlatformSetTls(_GLFWtls* tls, void* value)
|
|
||||||
{
|
|
||||||
assert(tls->win32.allocated == GLFW_TRUE);
|
|
||||||
TlsSetValue(tls->win32.index, value);
|
|
||||||
}
|
|
||||||
|
|
||||||
GLFWbool _glfwPlatformCreateMutex(_GLFWmutex* mutex)
|
|
||||||
{
|
|
||||||
assert(mutex->win32.allocated == GLFW_FALSE);
|
|
||||||
InitializeCriticalSection(&mutex->win32.section);
|
|
||||||
return mutex->win32.allocated = GLFW_TRUE;
|
|
||||||
}
|
|
||||||
|
|
||||||
void _glfwPlatformDestroyMutex(_GLFWmutex* mutex)
|
|
||||||
{
|
|
||||||
if (mutex->win32.allocated)
|
|
||||||
DeleteCriticalSection(&mutex->win32.section);
|
|
||||||
memset(mutex, 0, sizeof(_GLFWmutex));
|
|
||||||
}
|
|
||||||
|
|
||||||
void _glfwPlatformLockMutex(_GLFWmutex* mutex)
|
|
||||||
{
|
|
||||||
assert(mutex->win32.allocated == GLFW_TRUE);
|
|
||||||
EnterCriticalSection(&mutex->win32.section);
|
|
||||||
}
|
|
||||||
|
|
||||||
void _glfwPlatformUnlockMutex(_GLFWmutex* mutex)
|
|
||||||
{
|
|
||||||
assert(mutex->win32.allocated == GLFW_TRUE);
|
|
||||||
LeaveCriticalSection(&mutex->win32.section);
|
|
||||||
}
|
|
||||||
|
|
||||||
74
glfw/win32_time.c
vendored
74
glfw/win32_time.c
vendored
@@ -1,74 +0,0 @@
|
|||||||
//========================================================================
|
|
||||||
// GLFW 3.3 Win32 - www.glfw.org
|
|
||||||
//------------------------------------------------------------------------
|
|
||||||
// Copyright (c) 2002-2006 Marcus Geelnard
|
|
||||||
// Copyright (c) 2006-2016 Camilla Löwy <elmindreda@glfw.org>
|
|
||||||
//
|
|
||||||
// This software is provided 'as-is', without any express or implied
|
|
||||||
// warranty. In no event will the authors be held liable for any damages
|
|
||||||
// arising from the use of this software.
|
|
||||||
//
|
|
||||||
// Permission is granted to anyone to use this software for any purpose,
|
|
||||||
// including commercial applications, and to alter it and redistribute it
|
|
||||||
// freely, subject to the following restrictions:
|
|
||||||
//
|
|
||||||
// 1. The origin of this software must not be misrepresented; you must not
|
|
||||||
// claim that you wrote the original software. If you use this software
|
|
||||||
// in a product, an acknowledgment in the product documentation would
|
|
||||||
// be appreciated but is not required.
|
|
||||||
//
|
|
||||||
// 2. Altered source versions must be plainly marked as such, and must not
|
|
||||||
// be misrepresented as being the original software.
|
|
||||||
//
|
|
||||||
// 3. This notice may not be removed or altered from any source
|
|
||||||
// distribution.
|
|
||||||
//
|
|
||||||
//========================================================================
|
|
||||||
|
|
||||||
#include "internal.h"
|
|
||||||
|
|
||||||
|
|
||||||
//////////////////////////////////////////////////////////////////////////
|
|
||||||
////// GLFW internal API //////
|
|
||||||
//////////////////////////////////////////////////////////////////////////
|
|
||||||
|
|
||||||
// Initialise timer
|
|
||||||
//
|
|
||||||
void _glfwInitTimerWin32(void)
|
|
||||||
{
|
|
||||||
uint64_t frequency;
|
|
||||||
|
|
||||||
if (QueryPerformanceFrequency((LARGE_INTEGER*) &frequency))
|
|
||||||
{
|
|
||||||
_glfw.timer.win32.hasPC = GLFW_TRUE;
|
|
||||||
_glfw.timer.win32.frequency = frequency;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
_glfw.timer.win32.hasPC = GLFW_FALSE;
|
|
||||||
_glfw.timer.win32.frequency = 1000;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
//////////////////////////////////////////////////////////////////////////
|
|
||||||
////// GLFW platform API //////
|
|
||||||
//////////////////////////////////////////////////////////////////////////
|
|
||||||
|
|
||||||
uint64_t _glfwPlatformGetTimerValue(void)
|
|
||||||
{
|
|
||||||
if (_glfw.timer.win32.hasPC)
|
|
||||||
{
|
|
||||||
uint64_t value;
|
|
||||||
QueryPerformanceCounter((LARGE_INTEGER*) &value);
|
|
||||||
return value;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
return (uint64_t) timeGetTime();
|
|
||||||
}
|
|
||||||
|
|
||||||
uint64_t _glfwPlatformGetTimerFrequency(void)
|
|
||||||
{
|
|
||||||
return _glfw.timer.win32.frequency;
|
|
||||||
}
|
|
||||||
|
|
||||||
2197
glfw/win32_window.c
vendored
2197
glfw/win32_window.c
vendored
File diff suppressed because it is too large
Load Diff
Reference in New Issue
Block a user