[Input] Dynamically link to XInput.
This commit is contained in:
parent
86d2c9ae1e
commit
086d7e9da7
|
@ -119,11 +119,18 @@ std::vector<std::unique_ptr<hid::InputDriver>> CreateInputDrivers(
|
||||||
drivers.emplace_back(std::move(winkey_driver));
|
drivers.emplace_back(std::move(winkey_driver));
|
||||||
}
|
}
|
||||||
#endif // XE_PLATFORM_WIN32
|
#endif // XE_PLATFORM_WIN32
|
||||||
if (drivers.empty()) {
|
}
|
||||||
// Fallback to nop if none created.
|
for (auto it = drivers.begin(); it != drivers.end();) {
|
||||||
drivers.emplace_back(xe::hid::nop::Create(window));
|
if (XFAILED((*it)->Setup())) {
|
||||||
|
it = drivers.erase(it);
|
||||||
|
} else {
|
||||||
|
++it;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if (drivers.empty()) {
|
||||||
|
// Fallback to nop if none created.
|
||||||
|
drivers.emplace_back(xe::hid::nop::Create(window));
|
||||||
|
}
|
||||||
return drivers;
|
return drivers;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -21,26 +21,64 @@ namespace hid {
|
||||||
namespace xinput {
|
namespace xinput {
|
||||||
|
|
||||||
XInputInputDriver::XInputInputDriver(xe::ui::Window* window)
|
XInputInputDriver::XInputInputDriver(xe::ui::Window* window)
|
||||||
: InputDriver(window) {
|
: InputDriver(window),
|
||||||
#if (_WIN32_WINNT >= _WIN32_WINNT_WIN8 && _WIN32_WINNT < _WIN32_WINNT_WIN10)
|
module_(nullptr),
|
||||||
// TODO(gibbed): Is this necessary?
|
XInputGetCapabilities_(nullptr),
|
||||||
XInputEnable(TRUE);
|
XInputGetState_(nullptr),
|
||||||
#endif
|
XInputGetKeystroke_(nullptr),
|
||||||
}
|
XInputSetState_(nullptr),
|
||||||
|
XInputEnable_(nullptr) {}
|
||||||
|
|
||||||
XInputInputDriver::~XInputInputDriver() {
|
XInputInputDriver::~XInputInputDriver() {
|
||||||
#if (_WIN32_WINNT >= _WIN32_WINNT_WIN8 && _WIN32_WINNT < _WIN32_WINNT_WIN10)
|
if (module_) {
|
||||||
// TODO(gibbed): Is this necessary?
|
FreeLibrary((HMODULE)module_);
|
||||||
XInputEnable(FALSE);
|
module_ = nullptr;
|
||||||
#endif
|
XInputGetCapabilities_ = nullptr;
|
||||||
|
XInputGetState_ = nullptr;
|
||||||
|
XInputGetKeystroke_ = nullptr;
|
||||||
|
XInputSetState_ = nullptr;
|
||||||
|
XInputEnable_ = nullptr;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
X_STATUS XInputInputDriver::Setup() { return X_STATUS_SUCCESS; }
|
X_STATUS XInputInputDriver::Setup() {
|
||||||
|
HMODULE module = LoadLibraryW(L"xinput1_4.dll");
|
||||||
|
if (!module) {
|
||||||
|
module = LoadLibraryW(L"xinput1_3.dll");
|
||||||
|
}
|
||||||
|
if (!module) {
|
||||||
|
return X_STATUS_DLL_NOT_FOUND;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Required.
|
||||||
|
auto xigc = GetProcAddress(module, "XInputGetCapabilities");
|
||||||
|
auto xigs = GetProcAddress(module, "XInputGetState");
|
||||||
|
auto xigk = GetProcAddress(module, "XInputGetKeystroke");
|
||||||
|
auto xiss = GetProcAddress(module, "XInputSetState");
|
||||||
|
|
||||||
|
// Not required.
|
||||||
|
auto xie = GetProcAddress(module, "XInputEnable");
|
||||||
|
|
||||||
|
// Only fail when we don't have the bare essentials;
|
||||||
|
if (!xigc || !xigs || !xigk || !xiss) {
|
||||||
|
FreeLibrary(module);
|
||||||
|
return X_STATUS_PROCEDURE_NOT_FOUND;
|
||||||
|
}
|
||||||
|
|
||||||
|
module_ = module;
|
||||||
|
XInputGetCapabilities_ = xigc;
|
||||||
|
XInputGetState_ = xigs;
|
||||||
|
XInputGetKeystroke_ = xigk;
|
||||||
|
XInputSetState_ = xiss;
|
||||||
|
XInputEnable_ = xie;
|
||||||
|
return X_STATUS_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
X_RESULT XInputInputDriver::GetCapabilities(uint32_t user_index, uint32_t flags,
|
X_RESULT XInputInputDriver::GetCapabilities(uint32_t user_index, uint32_t flags,
|
||||||
X_INPUT_CAPABILITIES* out_caps) {
|
X_INPUT_CAPABILITIES* out_caps) {
|
||||||
XINPUT_CAPABILITIES native_caps;
|
XINPUT_CAPABILITIES native_caps;
|
||||||
DWORD result = XInputGetCapabilities(user_index, flags, &native_caps);
|
auto xigc = (decltype(&XInputGetCapabilities))XInputGetCapabilities_;
|
||||||
|
DWORD result = xigc(user_index, flags, &native_caps);
|
||||||
if (result) {
|
if (result) {
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
@ -65,7 +103,8 @@ X_RESULT XInputInputDriver::GetCapabilities(uint32_t user_index, uint32_t flags,
|
||||||
X_RESULT XInputInputDriver::GetState(uint32_t user_index,
|
X_RESULT XInputInputDriver::GetState(uint32_t user_index,
|
||||||
X_INPUT_STATE* out_state) {
|
X_INPUT_STATE* out_state) {
|
||||||
XINPUT_STATE native_state;
|
XINPUT_STATE native_state;
|
||||||
DWORD result = XInputGetState(user_index, &native_state);
|
auto xigs = (decltype(&XInputGetState))XInputGetState_;
|
||||||
|
DWORD result = xigs(user_index, &native_state);
|
||||||
if (result) {
|
if (result) {
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
@ -87,7 +126,8 @@ X_RESULT XInputInputDriver::SetState(uint32_t user_index,
|
||||||
XINPUT_VIBRATION native_vibration;
|
XINPUT_VIBRATION native_vibration;
|
||||||
native_vibration.wLeftMotorSpeed = vibration->left_motor_speed;
|
native_vibration.wLeftMotorSpeed = vibration->left_motor_speed;
|
||||||
native_vibration.wRightMotorSpeed = vibration->right_motor_speed;
|
native_vibration.wRightMotorSpeed = vibration->right_motor_speed;
|
||||||
DWORD result = XInputSetState(user_index, &native_vibration);
|
auto xiss = (decltype(&XInputSetState))XInputSetState_;
|
||||||
|
DWORD result = xiss(user_index, &native_vibration);
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -104,13 +144,15 @@ X_RESULT XInputInputDriver::GetKeystroke(uint32_t user_index, uint32_t flags,
|
||||||
// So we first check if the device is connected via XInputGetCapabilities, so
|
// So we first check if the device is connected via XInputGetCapabilities, so
|
||||||
// we are not passing back an uninitialized X_INPUT_KEYSTROKE structure:
|
// we are not passing back an uninitialized X_INPUT_KEYSTROKE structure:
|
||||||
XINPUT_CAPABILITIES caps;
|
XINPUT_CAPABILITIES caps;
|
||||||
result = XInputGetCapabilities(user_index, 0, &caps);
|
auto xigc = (decltype(&XInputGetCapabilities))XInputGetCapabilities_;
|
||||||
|
result = xigc(user_index, 0, &caps);
|
||||||
if (result) {
|
if (result) {
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
XINPUT_KEYSTROKE native_keystroke;
|
XINPUT_KEYSTROKE native_keystroke;
|
||||||
result = XInputGetKeystroke(user_index, 0, &native_keystroke);
|
auto xigk = (decltype(&XInputGetKeystroke))XInputGetKeystroke_;
|
||||||
|
result = xigk(user_index, 0, &native_keystroke);
|
||||||
if (result) {
|
if (result) {
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
|
@ -31,6 +31,12 @@ class XInputInputDriver : public InputDriver {
|
||||||
X_INPUT_KEYSTROKE* out_keystroke) override;
|
X_INPUT_KEYSTROKE* out_keystroke) override;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
void* module_;
|
||||||
|
void* XInputGetCapabilities_;
|
||||||
|
void* XInputGetState_;
|
||||||
|
void* XInputGetKeystroke_;
|
||||||
|
void* XInputSetState_;
|
||||||
|
void* XInputEnable_;
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace xinput
|
} // namespace xinput
|
||||||
|
|
|
@ -60,6 +60,7 @@ typedef uint32_t X_STATUS;
|
||||||
#define X_STATUS_OBJECT_NAME_COLLISION ((X_STATUS)0xC0000035L)
|
#define X_STATUS_OBJECT_NAME_COLLISION ((X_STATUS)0xC0000035L)
|
||||||
#define X_STATUS_INVALID_PAGE_PROTECTION ((X_STATUS)0xC0000045L)
|
#define X_STATUS_INVALID_PAGE_PROTECTION ((X_STATUS)0xC0000045L)
|
||||||
#define X_STATUS_MUTANT_NOT_OWNED ((X_STATUS)0xC0000046L)
|
#define X_STATUS_MUTANT_NOT_OWNED ((X_STATUS)0xC0000046L)
|
||||||
|
#define X_STATUS_PROCEDURE_NOT_FOUND ((X_STATUS)0xC000007AL)
|
||||||
#define X_STATUS_INSUFFICIENT_RESOURCES ((X_STATUS)0xC000009AL)
|
#define X_STATUS_INSUFFICIENT_RESOURCES ((X_STATUS)0xC000009AL)
|
||||||
#define X_STATUS_MEMORY_NOT_ALLOCATED ((X_STATUS)0xC00000A0L)
|
#define X_STATUS_MEMORY_NOT_ALLOCATED ((X_STATUS)0xC00000A0L)
|
||||||
#define X_STATUS_NOT_SUPPORTED ((X_STATUS)0xC00000BBL)
|
#define X_STATUS_NOT_SUPPORTED ((X_STATUS)0xC00000BBL)
|
||||||
|
@ -67,6 +68,7 @@ typedef uint32_t X_STATUS;
|
||||||
#define X_STATUS_INVALID_PARAMETER_2 ((X_STATUS)0xC00000F0L)
|
#define X_STATUS_INVALID_PARAMETER_2 ((X_STATUS)0xC00000F0L)
|
||||||
#define X_STATUS_INVALID_PARAMETER_3 ((X_STATUS)0xC00000F1L)
|
#define X_STATUS_INVALID_PARAMETER_3 ((X_STATUS)0xC00000F1L)
|
||||||
#define X_STATUS_DLL_NOT_FOUND ((X_STATUS)0xC0000135L)
|
#define X_STATUS_DLL_NOT_FOUND ((X_STATUS)0xC0000135L)
|
||||||
|
#define X_STATUS_ENTRYPOINT_NOT_FOUND ((X_STATUS)0xC0000139L)
|
||||||
#define X_STATUS_MAPPED_ALIGNMENT ((X_STATUS)0xC0000220L)
|
#define X_STATUS_MAPPED_ALIGNMENT ((X_STATUS)0xC0000220L)
|
||||||
#define X_STATUS_NOT_FOUND ((X_STATUS)0xC0000225L)
|
#define X_STATUS_NOT_FOUND ((X_STATUS)0xC0000225L)
|
||||||
#define X_STATUS_DRIVER_ORDINAL_NOT_FOUND ((X_STATUS)0xC0000262L)
|
#define X_STATUS_DRIVER_ORDINAL_NOT_FOUND ((X_STATUS)0xC0000262L)
|
||||||
|
|
Loading…
Reference in New Issue