From 14a976e4729d38f86d336fa6054279b33905b63c Mon Sep 17 00:00:00 2001 From: Stanislaw Halik Date: Sat, 9 Feb 2019 12:11:49 +0100 Subject: dinput: fix api usage Issue: #871 - don't sleep with a lock held - fix Acquire() return value check - remove needless Unacquire() calls - always use Poll(), even for keyboard - fix HRESULT debug output --- dinput/dinput.cpp | 31 +++++++++++++++++++++++++++ dinput/dinput.hpp | 6 ++++++ dinput/keybinding-worker.cpp | 17 ++++++--------- dinput/win32-joystick.cpp | 51 ++++++++++++++++---------------------------- 4 files changed, 61 insertions(+), 44 deletions(-) diff --git a/dinput/dinput.cpp b/dinput/dinput.cpp index e896f5f1..575922d9 100644 --- a/dinput/dinput.cpp +++ b/dinput/dinput.cpp @@ -1,4 +1,6 @@ #include "dinput.hpp" +#include "compat/macros.hpp" + #include int di_t::refcnt{0}; @@ -58,3 +60,32 @@ di_t::~di_t() unref_di(); } +bool di_t::poll_device(LPDIRECTINPUTDEVICE8 dev) +{ + HRESULT hr; + + switch (dev->Poll()) + { + case DI_OK: + case DI_NOEFFECT: + return true; + default: + break; + } + + switch (hr = dev->Acquire()) + { + case DI_OK: + case S_FALSE: + switch (hr = dev->Poll()) + { + case DI_OK: + case DI_NOEFFECT: + return true; + default: + eval_once(qDebug() << "dinput: device poll failed:" << (void*)hr); + } + } + + return false; +} diff --git a/dinput/dinput.hpp b/dinput/dinput.hpp index 9dbc576c..394084e2 100644 --- a/dinput/dinput.hpp +++ b/dinput/dinput.hpp @@ -17,6 +17,10 @@ #include +// XXX TODO -sh 20190209 +// keybinding_worker and joystick context are badly named +// add namespaces and rename, including inner joystick device struct + using diptr = IDirectInput8A*; class OTR_DINPUT_EXPORT di_t final @@ -38,4 +42,6 @@ public: diptr operator->() const { return handle; } operator bool() const { return handle != nullptr; } operator diptr() const { return handle; } + + static bool poll_device(LPDIRECTINPUTDEVICE8 dev); }; diff --git a/dinput/keybinding-worker.cpp b/dinput/keybinding-worker.cpp index e4cc6659..3d792778 100644 --- a/dinput/keybinding-worker.cpp +++ b/dinput/keybinding-worker.cpp @@ -82,14 +82,6 @@ bool KeybindingWorker::init() } } - if (dinkeyboard->Acquire() != DI_OK) - { - dinkeyboard->Release(); - dinkeyboard = nullptr; - qDebug() << "dinput: acquire keyboard failed" << GetLastError(); - return false; - } - return true; } @@ -142,12 +134,15 @@ bool KeybindingWorker::run_keyboard_nolock() * Key-up events work on my end. */ + if (!di_t::poll_device(dinkeyboard)) + eval_once(qDebug() << "dinput: keyboard poll failed"); + DWORD sz = num_keyboard_states; - const HRESULT hr = dinkeyboard->GetDeviceData(sizeof(*keyboard_states), keyboard_states, &sz, 0); + HRESULT hr = dinkeyboard->GetDeviceData(sizeof(*keyboard_states), keyboard_states, &sz, 0); - if (hr != DI_OK) + if (FAILED(hr)) { - eval_once(qDebug() << "dinput: keyboard GetDeviceData" << hr); + eval_once(qDebug() << "dinput: keyboard GetDeviceData failed" << (void*)hr); return false; } diff --git a/dinput/win32-joystick.cpp b/dinput/win32-joystick.cpp index d1546df3..0f2687fe 100644 --- a/dinput/win32-joystick.cpp +++ b/dinput/win32-joystick.cpp @@ -6,6 +6,7 @@ #include #include #include +#include #include #include @@ -46,29 +47,15 @@ bool win32_joy_ctx::poll_axis(const QString &guid, int* axes) return false; auto& j = iter->second; - auto& joy_handle = j->joy_handle; - bool ok = false; - HRESULT hr = S_OK; (void)hr; - - if (SUCCEEDED(hr = joy_handle->Poll())) - ok = true; - else if (SUCCEEDED(hr = joy_handle->Acquire()) && SUCCEEDED(hr = joy_handle->Poll())) - ok = true; + DIJOYSTATE2 js = {}; - if (!ok) - { - (void)joy_handle->Unacquire(); - Sleep(0); + if (!di_t::poll_device(joy_handle)) continue; - } - DIJOYSTATE2 js = {}; - - if (FAILED(hr = joy_handle->GetDeviceState(sizeof(js), &js))) + if (FAILED(joy_handle->GetDeviceState(sizeof(js), &js))) { - //qDebug() << "joy get state failed" << guid << hr; - Sleep(0); + //qDebug() << "joy get state failed" << guid; continue; } @@ -84,7 +71,7 @@ bool win32_joy_ctx::poll_axis(const QString &guid, int* axes) js.rglSlider[1] }; - for (unsigned i = 0; i < 8; i++) + for (unsigned i = 0; i < std::size(values); i++) axes[i] = values[i]; return true; @@ -147,19 +134,18 @@ bool win32_joy_ctx::joy::poll(fn const& f) { HRESULT hr; - (void) joy_handle->Acquire(); - - if (FAILED(hr = joy_handle->Poll())) + if (!di_t::poll_device(joy_handle)) { - //qDebug() << "joy acquire failed" << guid << hr; - (void) joy_handle->Unacquire(); + eval_once(qDebug() << "joy poll failed" << guid << (void*)hr); + //(void)joy_handle->Unacquire(); + //Sleep(0); return false; } DWORD sz = num_buffers; if (FAILED(hr = joy_handle->GetDeviceData(sizeof(DIDEVICEOBJECTDATA), keystate_buffers, &sz, 0))) { - eval_once(qDebug() << "joy get state failed" << guid << hr); + eval_once(qDebug() << "joy GetDeviceData failed" << guid << (void*)hr); return false; } @@ -254,7 +240,7 @@ void win32_joy_ctx::enum_state::refresh() this, DIEDFL_ATTACHEDONLY))) { - eval_once(qDebug() << "dinput: failed enum joysticks" << hr); + eval_once(qDebug() << "dinput: failed enum joysticks" << (void*)hr); return; } @@ -287,12 +273,12 @@ BOOL CALLBACK win32_joy_ctx::enum_state::EnumJoysticksCallback(const DIDEVICEINS LPDIRECTINPUTDEVICE8 h; if (FAILED(hr = state.di->CreateDevice(pdidInstance->guidInstance, &h, nullptr))) { - qDebug() << "dinput: joystick CreateDevice" << guid << hr; + qDebug() << "dinput: failed joystick CreateDevice" << guid << (void*)hr; goto end; } - if (FAILED(h->SetDataFormat(&c_dfDIJoystick2))) + if (FAILED(hr = h->SetDataFormat(&c_dfDIJoystick2))) { - qDebug() << "dinput: joystick SetDataFormat"; + qDebug() << "dinput: failed joystick SetDataFormat" << (void*)hr; h->Release(); goto end; } @@ -341,8 +327,8 @@ BOOL CALLBACK win32_joy_ctx::enum_state::EnumObjectsCallback(const DIDEVICEOBJEC if (pdidoi->dwType & DIDFT_AXIS) { DIPROPRANGE diprg = {}; - diprg.diph.dwSize = sizeof( DIPROPRANGE ); - diprg.diph.dwHeaderSize = sizeof( DIPROPHEADER ); + diprg.diph.dwSize = sizeof(DIPROPRANGE); + diprg.diph.dwHeaderSize = sizeof(DIPROPHEADER); diprg.diph.dwHow = DIPH_BYID; diprg.diph.dwObj = pdidoi->dwType; diprg.lMax = joy_axis_size; @@ -352,7 +338,7 @@ BOOL CALLBACK win32_joy_ctx::enum_state::EnumObjectsCallback(const DIDEVICEOBJEC if (FAILED(hr = reinterpret_cast(ctx)->SetProperty(DIPROP_RANGE, &diprg.diph))) { - qDebug() << "dinput: joystick DIPROP_RANGE" << hr; + qDebug() << "dinput: failed joystick DIPROP_RANGE" << (void*)hr; return DIENUM_STOP; } } @@ -373,5 +359,4 @@ win32_joy_ctx::joy::~joy() } } // ns win32_joy_impl - #endif -- cgit v1.2.3