- There's really no need anymore to dynamically load RawInput, considering it has been in Windows since XP.

This commit is contained in:
Christoph Oelckers 2019-07-14 17:41:25 +02:00
parent 79ad3e6203
commit 293aa2e6da
6 changed files with 45 additions and 270 deletions

View file

@ -50,7 +50,6 @@
#include "cmdlib.h"
#include "v_text.h"
#include "m_argv.h"
#include "rawinput.h"
#define SAFE_RELEASE(x) { if (x != NULL) { x->Release(); x = NULL; } }
@ -254,8 +253,6 @@ protected:
static BOOL CALLBACK EnumCallback(LPCDIDEVICEINSTANCE lpddi, LPVOID pvRef);
static int NameSort(const void *a, const void *b);
static bool IsXInputDevice(const GUID *guid);
static bool IsXInputDeviceFast(const GUID *guid);
static bool IsXInputDeviceSlow(const GUID *guid);
};
// EXTERNAL FUNCTION PROTOTYPES --------------------------------------------
@ -1133,140 +1130,6 @@ BOOL CALLBACK FDInputJoystickManager::EnumCallback(LPCDIDEVICEINSTANCE lpddi, LP
return DIENUM_CONTINUE;
}
//===========================================================================
//
// FDInputJoystickManager :: IsXInputDevice STATIC
//
// Does the DirectInput product GUID correspond to an XInput controller?
// If the product's device ID contains contains "IG_"
// (ex. "VID_045E&PID_028E&IG_00"), then it is an XInput device.
// Unfortunately this information can not be found by just using DirectInput.
//
//===========================================================================
bool FDInputJoystickManager::IsXInputDevice(const GUID *guid)
{
if (MyGetRawInputDeviceList == NULL || MyGetRawInputDeviceInfoA == NULL)
{
return IsXInputDeviceSlow(guid);
}
else
{
return IsXInputDeviceFast(guid);
}
}
//===========================================================================
//
// FDInputJoystickManager :: IsXInputDeviceSlow STATIC
//
// Pretty much copied straight from the article "XInput and DirectInput".
//
// Enum each PNP device using WMI and check each device ID. This is
// Microsoft's reference implementation, but it is damn slow. After
// a hardware change, connecting to the WMI server can take nearly three
// seconds, and creating the instance enumerator consistantly takes longer
// than 0.25 seconds.
//
// The XInput DLL can apparently be hacked fairly simply to work with
// Windows 2000, and since Raw Input wasn't introduced until XP, I think
// that's reason enough to keep this version around, despite it being
// so horrendously slow.
//
//===========================================================================
bool FDInputJoystickManager::IsXInputDeviceSlow(const GUID *guid)
{
IWbemLocator *wbemlocator = NULL;
IEnumWbemClassObject *enumdevices = NULL;
IWbemClassObject *devices[20] = { 0 };
IWbemServices *wbemservices = NULL;
BSTR namespce = NULL;
BSTR deviceid = NULL;
BSTR classname = NULL;
DWORD returned = 0;
bool isxinput = false;
UINT device = 0;
VARIANT var;
HRESULT hr;
// Create WMI
hr = CoCreateInstance(CLSID_WbemLocator, NULL, CLSCTX_INPROC_SERVER, IID_IWbemLocator, (LPVOID*)&wbemlocator);
if (FAILED(hr) || wbemlocator == NULL)
goto cleanup;
if (NULL == (namespce = SysAllocString(OLESTR("\\\\.\\root\\cimv2")))) goto cleanup;
if (NULL == (classname = SysAllocString(OLESTR("Win32_PNPEntity")))) goto cleanup;
if (NULL == (deviceid = SysAllocString(OLESTR("DeviceID")))) goto cleanup;
// Connect to WMI
hr = wbemlocator->ConnectServer(namespce, NULL, NULL, 0, 0, NULL, NULL, &wbemservices);
if (FAILED(hr) || wbemservices == NULL)
goto cleanup;
// Switch security level to IMPERSONATE.
CoSetProxyBlanket(wbemservices, RPC_C_AUTHN_WINNT, RPC_C_AUTHZ_NONE, NULL,
RPC_C_AUTHN_LEVEL_CALL, RPC_C_IMP_LEVEL_IMPERSONATE, NULL, EOAC_NONE);
hr = wbemservices->CreateInstanceEnum(classname, 0, NULL, &enumdevices);
if (FAILED(hr) || enumdevices == NULL)
goto cleanup;
// Loop over all devices
for (;;)
{
// Get 20 at a time.
hr = enumdevices->Next(10000, countof(devices), devices, &returned);
if (FAILED(hr))
goto cleanup;
if (returned == 0)
break;
for (device = 0; device < returned; device++)
{
// For each device, get its device ID.
hr = devices[device]->Get(deviceid, 0L, &var, NULL, NULL);
if (SUCCEEDED(hr) && var.vt == VT_BSTR && var.bstrVal != NULL)
{
// Check if the device ID contains "IG_". If it does, then it's an XInput device.
// This information cannot be found from DirectInput.
if (wcsstr(var.bstrVal, L"IG_"))
{
// If it does, then get the VID/PID from var.bstrVal.
DWORD pid = 0, vid = 0;
WCHAR *strvid = wcsstr(var.bstrVal, L"VID_");
if (strvid && swscanf(strvid, L"VID_%4X", &vid) != 1)
vid = 0;
WCHAR *strpid = wcsstr(var.bstrVal, L"PID_");
if (strpid && swscanf(strpid, L"PID_%4X", &pid) != 1)
pid = 0;
// Compare the VID/PID to the DInput device.
DWORD vidpid = MAKELONG(vid, pid);
if (vidpid == guid->Data1)
{
isxinput = true;
goto cleanup;
}
}
}
SAFE_RELEASE(devices[device]);
}
}
cleanup:
if (namespce) SysFreeString(namespce);
if (deviceid) SysFreeString(deviceid);
if (classname) SysFreeString(classname);
for (device = 0; device < countof(devices); ++device)
SAFE_RELEASE(devices[device]);
SAFE_RELEASE(enumdevices);
SAFE_RELEASE(wbemlocator);
SAFE_RELEASE(wbemservices);
return isxinput;
}
//===========================================================================
//
// FDInputJoystickManager :: IsXInputDeviceFast STATIC
@ -1279,14 +1142,14 @@ cleanup:
//
//===========================================================================
bool FDInputJoystickManager::IsXInputDeviceFast(const GUID *guid)
bool FDInputJoystickManager::IsXInputDevice(const GUID *guid)
{
UINT nDevices, numDevices;
RAWINPUTDEVICELIST *devices;
UINT i;
bool isxinput = false;
if (MyGetRawInputDeviceList(NULL, &nDevices, sizeof(RAWINPUTDEVICELIST)) != 0)
if (GetRawInputDeviceList(NULL, &nDevices, sizeof(RAWINPUTDEVICELIST)) != 0)
{
return false;
}
@ -1294,7 +1157,7 @@ bool FDInputJoystickManager::IsXInputDeviceFast(const GUID *guid)
{
return false;
}
if ((numDevices = MyGetRawInputDeviceList(devices, &nDevices, sizeof(RAWINPUTDEVICELIST))) == (UINT)-1)
if ((numDevices = GetRawInputDeviceList(devices, &nDevices, sizeof(RAWINPUTDEVICELIST))) == (UINT)-1)
{
free(devices);
return false;
@ -1310,7 +1173,7 @@ bool FDInputJoystickManager::IsXInputDeviceFast(const GUID *guid)
UINT cbSize;
cbSize = rdi.cbSize = sizeof(rdi);
if ((INT)MyGetRawInputDeviceInfoA(devices[i].hDevice, RIDI_DEVICEINFO, &rdi, &cbSize) >= 0)
if ((INT)GetRawInputDeviceInfoA(devices[i].hDevice, RIDI_DEVICEINFO, &rdi, &cbSize) >= 0)
{
if(MAKELONG(rdi.hid.dwVendorId, rdi.hid.dwProductId) == (LONG)guid->Data1)
{
@ -1318,7 +1181,7 @@ bool FDInputJoystickManager::IsXInputDeviceFast(const GUID *guid)
UINT namelen = countof(name);
UINT reslen;
reslen = MyGetRawInputDeviceInfoA(devices[i].hDevice, RIDI_DEVICENAME, name, &namelen);
reslen = GetRawInputDeviceInfoA(devices[i].hDevice, RIDI_DEVICENAME, name, &namelen);
if (reslen != (UINT)-1)
{
isxinput = (strstr(name, "IG_") != NULL);

View file

@ -40,6 +40,7 @@
#ifndef __GNUC__
#define INITGUID
#endif
#define DIRECTINPUT_VERSION 0x800
#include <windows.h>
#include <dbt.h>
#include <dinput.h>
@ -89,13 +90,6 @@
#include "g_levellocals.h"
#include "atterm.h"
// Prototypes and declarations.
#include "rawinput.h"
// Definitions
#define RIF(name, ret, args) \
name##Proto My##name;
#include "rawinput.h"
// Compensate for w32api's lack
#ifndef GET_XBUTTON_WPARAM
@ -110,7 +104,6 @@
#define INGAME_PRIORITY_CLASS NORMAL_PRIORITY_CLASS
#endif
static void FindRawInputFunctions();
FJoystickCollection *JoyDevices[NUM_JOYDEVICES];
@ -153,11 +146,6 @@ static bool EventHandlerResultForNativeMouse;
CVAR (Bool, i_soundinbackground, false, CVAR_ARCHIVE|CVAR_GLOBALCONFIG)
CVAR (Bool, k_allowfullscreentoggle, true, CVAR_ARCHIVE|CVAR_GLOBALCONFIG)
CUSTOM_CVAR(Bool, norawinput, false, CVAR_ARCHIVE|CVAR_GLOBALCONFIG|CVAR_NOINITCALL)
{
Printf("This won't take effect until " GAMENAME " is restarted.\n");
}
extern int chatmodeon;
static void I_CheckGUICapture ()
@ -378,25 +366,22 @@ LRESULT CALLBACK WndProc (HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
if (message == WM_INPUT)
{
if (MyGetRawInputData != NULL)
{
UINT size;
UINT size;
if (!MyGetRawInputData((HRAWINPUT)lParam, RID_INPUT, NULL, &size, sizeof(RAWINPUTHEADER)) &&
size != 0)
if (!GetRawInputData((HRAWINPUT)lParam, RID_INPUT, NULL, &size, sizeof(RAWINPUTHEADER)) &&
size != 0)
{
uint8_t *buffer = (uint8_t *)alloca(size);
if (GetRawInputData((HRAWINPUT)lParam, RID_INPUT, buffer, &size, sizeof(RAWINPUTHEADER)) == size)
{
uint8_t *buffer = (uint8_t *)alloca(size);
if (MyGetRawInputData((HRAWINPUT)lParam, RID_INPUT, buffer, &size, sizeof(RAWINPUTHEADER)) == size)
int code = GET_RAWINPUT_CODE_WPARAM(wParam);
if (Keyboard == NULL || !Keyboard->ProcessRawInput((RAWINPUT *)buffer, code))
{
int code = GET_RAWINPUT_CODE_WPARAM(wParam);
if (Keyboard == NULL || !Keyboard->ProcessRawInput((RAWINPUT *)buffer, code))
if (Mouse == NULL || !Mouse->ProcessRawInput((RAWINPUT *)buffer, code))
{
if (Mouse == NULL || !Mouse->ProcessRawInput((RAWINPUT *)buffer, code))
if (JoyDevices[INPUT_RawPS2] != NULL)
{
if (JoyDevices[INPUT_RawPS2] != NULL)
{
JoyDevices[INPUT_RawPS2]->ProcessRawInput((RAWINPUT *)buffer, code);
}
JoyDevices[INPUT_RawPS2]->ProcessRawInput((RAWINPUT *)buffer, code);
}
}
}
@ -635,8 +620,6 @@ bool I_InitInput (void *hwnd)
g_pdi = NULL;
g_pdi3 = NULL;
FindRawInputFunctions();
// Try for DirectInput 8 first, then DirectInput 3 for NT 4's benefit.
DInputDLL = LoadLibraryA("dinput8.dll");
if (DInputDLL != NULL)
@ -951,26 +934,3 @@ bool FInputDevice::WndProcHook(HWND hWnd, UINT message, WPARAM wParam, LPARAM lP
return false;
}
//==========================================================================
//
// FindRawInputFunctions
//
// Finds functions for raw input, if available.
//
//==========================================================================
static void FindRawInputFunctions()
{
if (!norawinput)
{
HMODULE user32 = GetModuleHandleA("user32.dll");
if (user32 == NULL)
{
return; // WTF kind of broken system are we running on?
}
#define RIF(name,ret,args) \
My##name = (name##Proto)GetProcAddress(user32, #name);
#include "rawinput.h"
}
}

View file

@ -40,7 +40,7 @@
#include "i_input.h"
#include "d_event.h"
#include "rawinput.h"
// MACROS ------------------------------------------------------------------
@ -423,15 +423,12 @@ FRawKeyboard::FRawKeyboard()
FRawKeyboard::~FRawKeyboard()
{
if (MyRegisterRawInputDevices != NULL)
{
RAWINPUTDEVICE rid;
rid.usUsagePage = HID_GENERIC_DESKTOP_PAGE;
rid.usUsage = HID_GDP_KEYBOARD;
rid.dwFlags = RIDEV_REMOVE;
rid.hwndTarget = NULL;
MyRegisterRawInputDevices(&rid, 1, sizeof(rid));
}
RAWINPUTDEVICE rid;
rid.usUsagePage = HID_GENERIC_DESKTOP_PAGE;
rid.usUsage = HID_GDP_KEYBOARD;
rid.dwFlags = RIDEV_REMOVE;
rid.hwndTarget = NULL;
RegisterRawInputDevices(&rid, 1, sizeof(rid));
}
//==========================================================================
@ -446,15 +443,11 @@ bool FRawKeyboard::GetDevice()
{
RAWINPUTDEVICE rid;
if (MyRegisterRawInputDevices == NULL)
{
return false;
}
rid.usUsagePage = HID_GENERIC_DESKTOP_PAGE;
rid.usUsage = HID_GDP_KEYBOARD;
rid.dwFlags = RIDEV_INPUTSINK;
rid.hwndTarget = Window;
if (!MyRegisterRawInputDevices(&rid, 1, sizeof(rid)))
if (!RegisterRawInputDevices(&rid, 1, sizeof(rid)))
{
return false;
}

View file

@ -43,7 +43,6 @@
#include "d_gui.h"
#include "g_game.h"
#include "hardware.h"
#include "rawinput.h"
#include "menu/menu.h"
#include "events.h"
@ -546,21 +545,17 @@ bool FRawMouse::GetDevice()
{
RAWINPUTDEVICE rid;
if (MyRegisterRawInputDevices == NULL)
{
return false;
}
rid.usUsagePage = HID_GENERIC_DESKTOP_PAGE;
rid.usUsage = HID_GDP_MOUSE;
rid.dwFlags = 0;
rid.hwndTarget = Window;
if (!MyRegisterRawInputDevices(&rid, 1, sizeof(rid)))
if (!RegisterRawInputDevices(&rid, 1, sizeof(rid)))
{
return false;
}
rid.dwFlags = RIDEV_REMOVE;
rid.hwndTarget = NULL; // Must be NULL for RIDEV_REMOVE.
MyRegisterRawInputDevices(&rid, 1, sizeof(rid));
RegisterRawInputDevices(&rid, 1, sizeof(rid));
return true;
}
@ -580,7 +575,7 @@ void FRawMouse::Grab()
rid.usUsage = HID_GDP_MOUSE;
rid.dwFlags = RIDEV_CAPTUREMOUSE | RIDEV_NOLEGACY;
rid.hwndTarget = Window;
if (MyRegisterRawInputDevices(&rid, 1, sizeof(rid)))
if (RegisterRawInputDevices(&rid, 1, sizeof(rid)))
{
GetCursorPos(&UngrabbedPointerPos);
Grabbed = true;
@ -609,7 +604,7 @@ void FRawMouse::Ungrab()
rid.usUsage = HID_GDP_MOUSE;
rid.dwFlags = RIDEV_REMOVE;
rid.hwndTarget = NULL;
if (MyRegisterRawInputDevices(&rid, 1, sizeof(rid)))
if (RegisterRawInputDevices(&rid, 1, sizeof(rid)))
{
Grabbed = false;
ClearButtonState();
@ -1185,18 +1180,6 @@ void I_StartupMouse ()
switch(in_mouse)
{
case 0:
default:
if (MyRegisterRawInputDevices != NULL)
{
new_mousemode = MM_RawInput;
}
else
{
new_mousemode = MM_DInput;
}
break;
case 1:
new_mousemode = MM_Win32;
break;
@ -1205,6 +1188,7 @@ void I_StartupMouse ()
new_mousemode = MM_DInput;
break;
default:
case 3:
new_mousemode = MM_RawInput;
break;

View file

@ -41,7 +41,6 @@
#include "templates.h"
#include "gameconfigfile.h"
#include "m_argv.h"
#include "rawinput.h"
// MACROS ------------------------------------------------------------------
@ -901,23 +900,17 @@ bool FRawPS2Manager::GetDevice()
{
RAWINPUTDEVICE rid;
if (MyRegisterRawInputDevices == NULL ||
MyGetRawInputDeviceList == NULL ||
MyGetRawInputDeviceInfoA == NULL)
{
return false;
}
rid.usUsagePage = HID_GENERIC_DESKTOP_PAGE;
rid.usUsage = HID_GDP_JOYSTICK;
rid.dwFlags = RIDEV_INPUTSINK;
rid.hwndTarget = Window;
if (!MyRegisterRawInputDevices(&rid, 1, sizeof(rid)))
if (!RegisterRawInputDevices(&rid, 1, sizeof(rid)))
{
return false;
}
rid.dwFlags = RIDEV_REMOVE;
rid.hwndTarget = NULL; // Must be NULL for RIDEV_REMOVE.
MyRegisterRawInputDevices(&rid, 1, sizeof(rid));
RegisterRawInputDevices(&rid, 1, sizeof(rid));
EnumDevices();
return true;
}
@ -1013,7 +1006,7 @@ FRawPS2Controller *FRawPS2Manager::EnumDevices()
RAWINPUTDEVICELIST *devices;
UINT i, j;
if (MyGetRawInputDeviceList(NULL, &nDevices, sizeof(RAWINPUTDEVICELIST)) != 0)
if (GetRawInputDeviceList(NULL, &nDevices, sizeof(RAWINPUTDEVICELIST)) != 0)
{
return NULL;
}
@ -1021,7 +1014,7 @@ FRawPS2Controller *FRawPS2Manager::EnumDevices()
{
return NULL;
}
if ((numDevices = MyGetRawInputDeviceList(devices, &nDevices, sizeof(RAWINPUTDEVICELIST))) == (UINT)-1)
if ((numDevices = GetRawInputDeviceList(devices, &nDevices, sizeof(RAWINPUTDEVICELIST))) == (UINT)-1)
{
free(devices);
return NULL;
@ -1037,7 +1030,7 @@ FRawPS2Controller *FRawPS2Manager::EnumDevices()
UINT cbSize;
cbSize = rdi.cbSize = sizeof(rdi);
if ((INT)MyGetRawInputDeviceInfoA(devices[i].hDevice, RIDI_DEVICEINFO, &rdi, &cbSize) >= 0)
if ((INT)GetRawInputDeviceInfoA(devices[i].hDevice, RIDI_DEVICEINFO, &rdi, &cbSize) >= 0)
{
// All the PS2 adapters report themselves as joysticks.
// (By comparison, the 360 controller reports itself as a gamepad.)
@ -1080,41 +1073,41 @@ FRawPS2Controller *FRawPS2Manager::EnumDevices()
// <Enumerator>#<Device ID>#<Device Interface Class GUID>
// The Device ID has multiple #-seperated parts and uniquely identifies
// this device and which USB port it is connected to.
char name[256];
wchar_t name[256];
UINT namelen = countof(name);
char *devid, *devidend;
wchar_t *devid, *devidend;
if (MyGetRawInputDeviceInfoA(devices[i].hDevice, RIDI_DEVICENAME, name, &namelen) == (UINT)-1)
if (GetRawInputDeviceInfoW(devices[i].hDevice, RIDI_DEVICENAME, name, &namelen) == (UINT)-1)
{ // Can't get name. Skip it, since there's stuff in there we need for config.
continue;
}
devid = strchr(name, '#');
devid = wcschr(name, '#');
if (devid == NULL)
{ // Should not happen
continue;
}
devidend = strrchr(++devid, '#');
devidend = wcsrchr(++devid, '#');
if (devidend != NULL)
{
*devidend = '\0';
}
FAdapterHandle handle = { devices[i].hDevice, type, 0, devid };
FAdapterHandle handle = { devices[i].hDevice, type, 0, FString(devid) };
// Adapters that support more than one controller have a seperate device
// entry for each controller. We can examine the name to determine which
// controller this device is for.
if (Descriptors[type].ControllerNumber >= 0)
{
char *col = strstr(devid, "&Col");
wchar_t *col = wcsstr(devid, L"&Col");
if (col != NULL)
{
// I have no idea if this number is base 16 or base 10. Every
// other number in the name is base 16, so I assume this one is
// too, but since I don't have anything that goes higher than 02,
// I can't be sure.
handle.ControllerNumber = strtoul(col + 4, NULL, 16);
handle.ControllerNumber = wcstoul(col + 4, NULL, 16);
}
}
adapters.Push(handle);
@ -1267,7 +1260,7 @@ void FRawPS2Manager::DoRegister()
{
rid.dwFlags = RIDEV_REMOVE;
rid.hwndTarget = NULL;
if (MyRegisterRawInputDevices(&rid, 1, sizeof(rid)))
if (RegisterRawInputDevices(&rid, 1, sizeof(rid)))
{
Registered = false;
}
@ -1279,7 +1272,7 @@ void FRawPS2Manager::DoRegister()
{
rid.dwFlags = RIDEV_INPUTSINK;
rid.hwndTarget = Window;
if (MyRegisterRawInputDevices(&rid, 1, sizeof(rid)))
if (RegisterRawInputDevices(&rid, 1, sizeof(rid)))
{
Registered = true;
}

View file

@ -1,18 +0,0 @@
// Pointers to raw-input related functions. They were introduced with XP,
// so we can't use static linking with them.
#ifndef RIF
#define RIF(name,ret,args) \
typedef ret (WINAPI *name##Proto)args; \
extern name##Proto My##name;
#endif
RIF(DefRawInputProc, LRESULT, (PRAWINPUT *paRawInput, INT nInput, UINT cbSizeHeader))
RIF(GetRawInputBuffer, UINT, (PRAWINPUT pData, PUINT pcbSize, UINT cbSizeHeader))
RIF(GetRawInputData, UINT, (HRAWINPUT hRawInput, UINT uiCommand, LPVOID pData, PUINT pcbSize, UINT cbSizeHeader))
RIF(GetRawInputDeviceInfoA, UINT, (HANDLE hDevice, UINT uiCommand, LPVOID pData, PUINT pcbSize))
RIF(GetRawInputDeviceInfoW, UINT, (HANDLE hDevice, UINT uiCommand, LPVOID pData, PUINT pcbSize))
RIF(GetRawInputDeviceList, UINT, (PRAWINPUTDEVICELIST pRawInputDeviceList, PUINT puiNumDevices, UINT cbSize))
RIF(GetRegisteredRawInputDevices, UINT, (PRAWINPUTDEVICE pRawInputDevices, PUINT puiNumDevices, UINT cbSize))
RIF(RegisterRawInputDevices, BOOL, (PCRAWINPUTDEVICE pRawInputDevices, UINT uiNumDevices, UINT cbSize))
#undef RIF