[HID] Fixed issue with controller input introduced in previous commit.
Added option to switch keyboard working mode.
This commit is contained in:
parent
f6ae651cc2
commit
ef8619b0a8
|
@ -137,6 +137,10 @@ X_RESULT InputSystem::GetKeystroke(uint32_t user_index, uint32_t flags,
|
||||||
bool any_connected = false;
|
bool any_connected = false;
|
||||||
for (auto& driver : drivers_) {
|
for (auto& driver : drivers_) {
|
||||||
X_RESULT result = driver->GetKeystroke(user_index, flags, out_keystroke);
|
X_RESULT result = driver->GetKeystroke(user_index, flags, out_keystroke);
|
||||||
|
if (result == X_ERROR_INVALID_PARAMETER) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
if (result != X_ERROR_DEVICE_NOT_CONNECTED) {
|
if (result != X_ERROR_DEVICE_NOT_CONNECTED) {
|
||||||
any_connected = true;
|
any_connected = true;
|
||||||
}
|
}
|
||||||
|
|
|
@ -25,26 +25,32 @@
|
||||||
#include "winkey_binding_table.inc"
|
#include "winkey_binding_table.inc"
|
||||||
#undef XE_HID_WINKEY_BINDING
|
#undef XE_HID_WINKEY_BINDING
|
||||||
|
|
||||||
DEFINE_int32(keyboard_user_index, 0, "Controller port that keyboard emulates",
|
DEFINE_int32(keyboard_mode, 1,
|
||||||
"HID.WinKey");
|
"Allows user do specify keyboard working mode. Possible values: 0 "
|
||||||
|
"- Disabled, 1 - Enabled, 2 - Passthrough",
|
||||||
|
"HID");
|
||||||
|
|
||||||
DEFINE_int32(keyboard_passthru_user_index, -1,
|
DEFINE_int32(keyboard_user_index, 0,
|
||||||
"Allows keyboard to be assigned as virtual keyboard to user with "
|
"Controller port that keyboard emulates. -1 - Keyboard usage "
|
||||||
"specific index. This also forces keyboard to be assigned to that "
|
"disabled, [0, 3] - Keyboard is assigned to selected slot.",
|
||||||
"slot to be interpreted as controller. Possible values: -1 - "
|
|
||||||
"Disabled (Keyboard is in "
|
|
||||||
"gamepad mode), [0, 3] - Keyboard is assigned as VK for that user",
|
|
||||||
"HID");
|
"HID");
|
||||||
|
|
||||||
namespace xe {
|
namespace xe {
|
||||||
namespace hid {
|
namespace hid {
|
||||||
namespace winkey {
|
namespace winkey {
|
||||||
|
|
||||||
bool static IsPassThruForUserEnabled(uint32_t user_index) {
|
bool static IsPassthroughEnabled(uint32_t user_index) {
|
||||||
if (cvars::keyboard_passthru_user_index == -1) {
|
return static_cast<KeyboardMode>(cvars::keyboard_mode) ==
|
||||||
|
KeyboardMode::Passthrough;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool static IsKeyboardForUserEnabled(uint32_t user_index) {
|
||||||
|
if (static_cast<KeyboardMode>(cvars::keyboard_mode) !=
|
||||||
|
KeyboardMode::Enabled) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
return user_index == cvars::keyboard_passthru_user_index;
|
|
||||||
|
return cvars::keyboard_user_index == user_index;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool __inline IsKeyToggled(uint8_t key) {
|
bool __inline IsKeyToggled(uint8_t key) {
|
||||||
|
@ -120,7 +126,7 @@ X_STATUS WinKeyInputDriver::Setup() { return X_STATUS_SUCCESS; }
|
||||||
|
|
||||||
X_RESULT WinKeyInputDriver::GetCapabilities(uint32_t user_index, uint32_t flags,
|
X_RESULT WinKeyInputDriver::GetCapabilities(uint32_t user_index, uint32_t flags,
|
||||||
X_INPUT_CAPABILITIES* out_caps) {
|
X_INPUT_CAPABILITIES* out_caps) {
|
||||||
if (user_index != cvars::keyboard_user_index) {
|
if (!IsKeyboardForUserEnabled(user_index)) {
|
||||||
return X_ERROR_DEVICE_NOT_CONNECTED;
|
return X_ERROR_DEVICE_NOT_CONNECTED;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -142,8 +148,7 @@ X_RESULT WinKeyInputDriver::GetCapabilities(uint32_t user_index, uint32_t flags,
|
||||||
|
|
||||||
X_RESULT WinKeyInputDriver::GetState(uint32_t user_index,
|
X_RESULT WinKeyInputDriver::GetState(uint32_t user_index,
|
||||||
X_INPUT_STATE* out_state) {
|
X_INPUT_STATE* out_state) {
|
||||||
if (!IsPassThruForUserEnabled(user_index) &&
|
if (!IsKeyboardForUserEnabled(user_index)) {
|
||||||
user_index != cvars::keyboard_user_index) {
|
|
||||||
return X_ERROR_DEVICE_NOT_CONNECTED;
|
return X_ERROR_DEVICE_NOT_CONNECTED;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -258,8 +263,7 @@ X_RESULT WinKeyInputDriver::GetState(uint32_t user_index,
|
||||||
|
|
||||||
X_RESULT WinKeyInputDriver::SetState(uint32_t user_index,
|
X_RESULT WinKeyInputDriver::SetState(uint32_t user_index,
|
||||||
X_INPUT_VIBRATION* vibration) {
|
X_INPUT_VIBRATION* vibration) {
|
||||||
if (!IsPassThruForUserEnabled(user_index) &&
|
if (!IsKeyboardForUserEnabled(user_index)) {
|
||||||
user_index != cvars::keyboard_user_index) {
|
|
||||||
return X_ERROR_DEVICE_NOT_CONNECTED;
|
return X_ERROR_DEVICE_NOT_CONNECTED;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -268,8 +272,20 @@ X_RESULT WinKeyInputDriver::SetState(uint32_t user_index,
|
||||||
|
|
||||||
X_RESULT WinKeyInputDriver::GetKeystroke(uint32_t user_index, uint32_t flags,
|
X_RESULT WinKeyInputDriver::GetKeystroke(uint32_t user_index, uint32_t flags,
|
||||||
X_INPUT_KEYSTROKE* out_keystroke) {
|
X_INPUT_KEYSTROKE* out_keystroke) {
|
||||||
if (!IsPassThruForUserEnabled(user_index) &&
|
// Pop from the queue.
|
||||||
user_index != cvars::keyboard_user_index) {
|
KeyEvent evt;
|
||||||
|
{
|
||||||
|
auto global_lock = global_critical_region_.Acquire();
|
||||||
|
if (key_events_.empty()) {
|
||||||
|
// No keys!
|
||||||
|
return X_ERROR_EMPTY;
|
||||||
|
}
|
||||||
|
evt = key_events_.front();
|
||||||
|
key_events_.pop();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!IsKeyboardForUserEnabled(user_index) &&
|
||||||
|
!IsPassthroughEnabled(user_index)) {
|
||||||
return X_ERROR_DEVICE_NOT_CONNECTED;
|
return X_ERROR_DEVICE_NOT_CONNECTED;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -284,26 +300,16 @@ X_RESULT WinKeyInputDriver::GetKeystroke(uint32_t user_index, uint32_t flags,
|
||||||
uint16_t keystroke_flags = 0;
|
uint16_t keystroke_flags = 0;
|
||||||
uint8_t hid_code = 0;
|
uint8_t hid_code = 0;
|
||||||
|
|
||||||
// Pop from the queue.
|
|
||||||
KeyEvent evt;
|
|
||||||
{
|
|
||||||
auto global_lock = global_critical_region_.Acquire();
|
|
||||||
if (key_events_.empty()) {
|
|
||||||
// No keys!
|
|
||||||
return X_ERROR_EMPTY;
|
|
||||||
}
|
|
||||||
evt = key_events_.front();
|
|
||||||
key_events_.pop();
|
|
||||||
}
|
|
||||||
|
|
||||||
bool capital = IsKeyToggled(VK_CAPITAL) || IsKeyDown(VK_SHIFT);
|
bool capital = IsKeyToggled(VK_CAPITAL) || IsKeyDown(VK_SHIFT);
|
||||||
|
|
||||||
if (!IsPassThruForUserEnabled(user_index)) {
|
if (!IsPassthroughEnabled(user_index)) {
|
||||||
for (const KeyBinding& b : key_bindings_) {
|
if (IsKeyboardForUserEnabled(user_index)) {
|
||||||
if (b.input_key == evt.virtual_key &&
|
for (const KeyBinding& b : key_bindings_) {
|
||||||
((b.lowercase == b.uppercase) || (b.lowercase && !capital) ||
|
if (b.input_key == evt.virtual_key &&
|
||||||
(b.uppercase && capital))) {
|
((b.lowercase == b.uppercase) || (b.lowercase && !capital) ||
|
||||||
xinput_virtual_key = b.output_key;
|
(b.uppercase && capital))) {
|
||||||
|
xinput_virtual_key = b.output_key;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
@ -332,7 +338,7 @@ X_RESULT WinKeyInputDriver::GetKeystroke(uint32_t user_index, uint32_t flags,
|
||||||
keystroke_flags |= 0x0002; // XINPUT_KEYSTROKE_KEYUP
|
keystroke_flags |= 0x0002; // XINPUT_KEYSTROKE_KEYUP
|
||||||
}
|
}
|
||||||
|
|
||||||
if (IsPassThruForUserEnabled(user_index)) {
|
if (IsPassthroughEnabled(user_index)) {
|
||||||
if (GetKeyboardState(key_map_)) {
|
if (GetKeyboardState(key_map_)) {
|
||||||
WCHAR buf;
|
WCHAR buf;
|
||||||
if (ToUnicode(uint8_t(xinput_virtual_key), 0, key_map_, &buf, 1, 0) ==
|
if (ToUnicode(uint8_t(xinput_virtual_key), 0, key_map_, &buf, 1, 0) ==
|
||||||
|
|
|
@ -20,6 +20,8 @@ namespace xe {
|
||||||
namespace hid {
|
namespace hid {
|
||||||
namespace winkey {
|
namespace winkey {
|
||||||
|
|
||||||
|
enum class KeyboardMode { Disabled, Enabled, Passthrough };
|
||||||
|
|
||||||
class WinKeyInputDriver final : public InputDriver {
|
class WinKeyInputDriver final : public InputDriver {
|
||||||
public:
|
public:
|
||||||
explicit WinKeyInputDriver(xe::ui::Window* window, size_t window_z_order);
|
explicit WinKeyInputDriver(xe::ui::Window* window, size_t window_z_order);
|
||||||
|
|
|
@ -200,9 +200,6 @@ X_RESULT XInputInputDriver::GetKeystroke(uint32_t user_index, uint32_t flags,
|
||||||
// flags is reserved on desktop.
|
// flags is reserved on desktop.
|
||||||
DWORD result;
|
DWORD result;
|
||||||
|
|
||||||
if ((flags & XINPUT_FLAG_KEYBOARD) != 0) {
|
|
||||||
return X_ERROR_INVALID_PARAMETER;
|
|
||||||
}
|
|
||||||
// XInputGetKeystroke on Windows has a bug where it will return
|
// XInputGetKeystroke on Windows has a bug where it will return
|
||||||
// ERROR_SUCCESS (0) even if the device is not connected:
|
// ERROR_SUCCESS (0) even if the device is not connected:
|
||||||
// https://stackoverflow.com/questions/23669238/xinputgetkeystroke-returning-error-success-while-controller-is-unplugged
|
// https://stackoverflow.com/questions/23669238/xinputgetkeystroke-returning-error-success-while-controller-is-unplugged
|
||||||
|
|
Loading…
Reference in New Issue