[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));
|
||||
}
|
||||
#endif // XE_PLATFORM_WIN32
|
||||
if (drivers.empty()) {
|
||||
// Fallback to nop if none created.
|
||||
drivers.emplace_back(xe::hid::nop::Create(window));
|
||||
}
|
||||
for (auto it = drivers.begin(); it != drivers.end();) {
|
||||
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;
|
||||
}
|
||||
|
||||
|
|
|
@ -21,26 +21,64 @@ namespace hid {
|
|||
namespace xinput {
|
||||
|
||||
XInputInputDriver::XInputInputDriver(xe::ui::Window* window)
|
||||
: InputDriver(window) {
|
||||
#if (_WIN32_WINNT >= _WIN32_WINNT_WIN8 && _WIN32_WINNT < _WIN32_WINNT_WIN10)
|
||||
// TODO(gibbed): Is this necessary?
|
||||
XInputEnable(TRUE);
|
||||
#endif
|
||||
}
|
||||
: InputDriver(window),
|
||||
module_(nullptr),
|
||||
XInputGetCapabilities_(nullptr),
|
||||
XInputGetState_(nullptr),
|
||||
XInputGetKeystroke_(nullptr),
|
||||
XInputSetState_(nullptr),
|
||||
XInputEnable_(nullptr) {}
|
||||
|
||||
XInputInputDriver::~XInputInputDriver() {
|
||||
#if (_WIN32_WINNT >= _WIN32_WINNT_WIN8 && _WIN32_WINNT < _WIN32_WINNT_WIN10)
|
||||
// TODO(gibbed): Is this necessary?
|
||||
XInputEnable(FALSE);
|
||||
#endif
|
||||
if (module_) {
|
||||
FreeLibrary((HMODULE)module_);
|
||||
module_ = nullptr;
|
||||
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_INPUT_CAPABILITIES* out_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) {
|
||||
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_INPUT_STATE* out_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) {
|
||||
return result;
|
||||
}
|
||||
|
@ -87,7 +126,8 @@ X_RESULT XInputInputDriver::SetState(uint32_t user_index,
|
|||
XINPUT_VIBRATION native_vibration;
|
||||
native_vibration.wLeftMotorSpeed = vibration->left_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;
|
||||
}
|
||||
|
||||
|
@ -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
|
||||
// we are not passing back an uninitialized X_INPUT_KEYSTROKE structure:
|
||||
XINPUT_CAPABILITIES caps;
|
||||
result = XInputGetCapabilities(user_index, 0, &caps);
|
||||
auto xigc = (decltype(&XInputGetCapabilities))XInputGetCapabilities_;
|
||||
result = xigc(user_index, 0, &caps);
|
||||
if (result) {
|
||||
return result;
|
||||
}
|
||||
|
||||
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) {
|
||||
return result;
|
||||
}
|
||||
|
|
|
@ -31,6 +31,12 @@ class XInputInputDriver : public InputDriver {
|
|||
X_INPUT_KEYSTROKE* out_keystroke) override;
|
||||
|
||||
protected:
|
||||
void* module_;
|
||||
void* XInputGetCapabilities_;
|
||||
void* XInputGetState_;
|
||||
void* XInputGetKeystroke_;
|
||||
void* XInputSetState_;
|
||||
void* XInputEnable_;
|
||||
};
|
||||
|
||||
} // namespace xinput
|
||||
|
|
|
@ -60,6 +60,7 @@ typedef uint32_t X_STATUS;
|
|||
#define X_STATUS_OBJECT_NAME_COLLISION ((X_STATUS)0xC0000035L)
|
||||
#define X_STATUS_INVALID_PAGE_PROTECTION ((X_STATUS)0xC0000045L)
|
||||
#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_MEMORY_NOT_ALLOCATED ((X_STATUS)0xC00000A0L)
|
||||
#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_3 ((X_STATUS)0xC00000F1L)
|
||||
#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_NOT_FOUND ((X_STATUS)0xC0000225L)
|
||||
#define X_STATUS_DRIVER_ORDINAL_NOT_FOUND ((X_STATUS)0xC0000262L)
|
||||
|
|
Loading…
Reference in New Issue