summaryrefslogtreecommitdiffhomepage
path: root/opentrack
diff options
context:
space:
mode:
authorStanislaw Halik <sthalik@misaki.pl>2015-12-06 05:16:39 +0100
committerStanislaw Halik <sthalik@misaki.pl>2015-12-06 05:16:39 +0100
commitacef508f0b6f16a7be987eeebbb3402455f9aef8 (patch)
tree0b80a6fd07db11677bad6f4cabfa3f5ed11bd00a /opentrack
parent1aa7bceaed59770adeb389d6c4c8f5561d0e7402 (diff)
joystick: no longer singleton, use fake window handle
We can create arbitrary amount of dinput handles, given they're passed unique window handles.
Diffstat (limited to 'opentrack')
-rw-r--r--opentrack/win32-joystick.cpp60
-rw-r--r--opentrack/win32-joystick.hpp23
2 files changed, 33 insertions, 50 deletions
diff --git a/opentrack/win32-joystick.cpp b/opentrack/win32-joystick.cpp
index e3147929..89092403 100644
--- a/opentrack/win32-joystick.cpp
+++ b/opentrack/win32-joystick.cpp
@@ -1,23 +1,9 @@
+#undef NDEBUG
+#include <cassert>
#include "win32-joystick.hpp"
#ifdef _WIN32
-LPDIRECTINPUT8& win32_joy_ctx::dinput_handle()
-{
- (void) CoInitialize(nullptr);
-
- static LPDIRECTINPUT8 dinput_handle_ = nullptr;
-
- if (dinput_handle_ == nullptr)
- (void) DirectInput8Create(GetModuleHandle(nullptr),
- DIRECTINPUT_VERSION,
- IID_IDirectInput8,
- (void**) &dinput_handle_,
- nullptr);
-
- return dinput_handle_;
-}
-
std::unordered_map<QString, std::shared_ptr<win32_joy_ctx::joy>>& win32_joy_ctx::joys()
{
static std::unordered_map<QString, std::shared_ptr<joy>> js;
@@ -25,12 +11,6 @@ std::unordered_map<QString, std::shared_ptr<win32_joy_ctx::joy>>& win32_joy_ctx:
return js;
}
-win32_joy_ctx& win32_joy_ctx::make()
-{
- static win32_joy_ctx ret;
- return ret;
-}
-
void win32_joy_ctx::poll(fn f)
{
refresh(false);
@@ -117,17 +97,18 @@ std::vector<win32_joy_ctx::joy_info> win32_joy_ctx::get_joy_info()
win32_joy_ctx::win32_joy_ctx()
{
+ if (DirectInput8Create(GetModuleHandle(NULL), DIRECTINPUT_VERSION, IID_IDirectInput8, (void**)&di, NULL) != DI_OK) {
+ qDebug() << "setup DirectInput8 Creation failed!" << GetLastError();
+ assert(!"direct input handle can't be created");
+ }
refresh(true);
}
void win32_joy_ctx::release()
{
joys() = std::unordered_map<QString, std::shared_ptr<joy>>();
- {
- auto& di = dinput_handle();
- di->Release();
- di = nullptr;
- }
+ di->Release();
+ di = nullptr;
}
void win32_joy_ctx::refresh(bool first)
@@ -141,7 +122,7 @@ void win32_joy_ctx::refresh(bool first)
timer_joylist.start();
}
- enum_state st(joys(), first, mtx);
+ enum_state st(joys(), mtx, fake_main_window, di);
}
QString win32_joy_ctx::guid_to_string(const GUID guid)
@@ -193,12 +174,10 @@ bool win32_joy_ctx::joy::poll(fn f)
return false;
}
- first |= first_timer.elapsed_ms() > first_event_delay_ms;
-
for (int i = 0; i < 128; i++)
{
const bool state = !!(js.rgbButtons[i] & 0x80);
- if (state != pressed[i] && first)
+ if (state != pressed[i])
{
f(guid, i, state);
qDebug() << "btn" << guid << i << state;
@@ -209,15 +188,19 @@ bool win32_joy_ctx::joy::poll(fn f)
return true;
}
-win32_joy_ctx::enum_state::enum_state(std::unordered_map<QString, std::shared_ptr<joy> > &joys, bool first, QMutex& mtx) : first(first)
+win32_joy_ctx::enum_state::enum_state(std::unordered_map<QString, std::shared_ptr<joy>> &joys,
+ QMutex& mtx,
+ QMainWindow &fake_main_window,
+ LPDIRECTINPUT8 di) :
+ fake_main_window(fake_main_window),
+ di(di)
{
- HRESULT hr;
- LPDIRECTINPUT8 di = dinput_handle();
-
{
QMutexLocker l(&mtx);
this->joys = joys;
}
+
+ HRESULT hr;
if(FAILED(hr = di->EnumDevices(DI8DEVCLASS_GAMECTRL,
EnumJoysticksCallback,
@@ -257,8 +240,7 @@ win32_joy_ctx::enum_state::EnumJoysticksCallback(const DIDEVICEINSTANCE *pdidIns
{
HRESULT hr;
LPDIRECTINPUTDEVICE8 h;
- LPDIRECTINPUT8 di = dinput_handle();
- if (FAILED(hr = di->CreateDevice(pdidInstance->guidInstance, &h, nullptr)))
+ if (FAILED(hr = state.di->CreateDevice(pdidInstance->guidInstance, &h, nullptr)))
{
qDebug() << "createdevice" << guid << hr;
goto end;
@@ -270,7 +252,7 @@ win32_joy_ctx::enum_state::EnumJoysticksCallback(const DIDEVICEINSTANCE *pdidIns
goto end;
}
- if (FAILED(h->SetCooperativeLevel((HWND) GetDesktopWindow(), DISCL_NONEXCLUSIVE | DISCL_BACKGROUND)))
+ if (FAILED(h->SetCooperativeLevel((HWND) state.fake_main_window.winId(), DISCL_NONEXCLUSIVE | DISCL_BACKGROUND)))
{
qDebug() << "coop";
h->Release();
@@ -284,7 +266,7 @@ win32_joy_ctx::enum_state::EnumJoysticksCallback(const DIDEVICEINSTANCE *pdidIns
}
qDebug() << "add joy" << guid;
- state.joys[guid] = std::make_shared<joy>(h, guid, name, state.first);
+ state.joys[guid] = std::make_shared<joy>(h, guid, name);
}
end:
return DIENUM_CONTINUE;
diff --git a/opentrack/win32-joystick.hpp b/opentrack/win32-joystick.hpp
index 421774a9..f7629c3d 100644
--- a/opentrack/win32-joystick.hpp
+++ b/opentrack/win32-joystick.hpp
@@ -18,6 +18,7 @@
#include <QDebug>
#include <QMutex>
#include <QMutexLocker>
+#include <QMainWindow>
namespace std {
template<>
@@ -49,21 +50,23 @@ struct OPENTRACK_EXPORT win32_joy_ctx
void poll(fn f);
bool poll_axis(const QString& guid, int axes[8]);
- ~win32_joy_ctx();
std::vector<joy_info> get_joy_info();
- static win32_joy_ctx& make();
+
win32_joy_ctx(const win32_joy_ctx&) = delete;
win32_joy_ctx& operator=(const win32_joy_ctx&) = delete;
+ win32_joy_ctx();
+ ~win32_joy_ctx();
+
private:
enum { joylist_refresh_ms = 100 };
QMutex mtx;
Timer timer_joylist;
+ QMainWindow fake_main_window;
+ LPDIRECTINPUT8 di;
static QString guid_to_string(const GUID guid);
- static LPDIRECTINPUT8& dinput_handle();
- win32_joy_ctx();
void release();
void refresh(bool first);
@@ -72,16 +75,13 @@ private:
struct joy
{
- enum { first_event_delay_ms = 3000 };
-
LPDIRECTINPUTDEVICE8 joy_handle;
QString guid, name;
bool pressed[128];
Timer first_timer;
- bool first;
- joy(LPDIRECTINPUTDEVICE8 handle, const QString& guid, const QString& name, bool first)
- : joy_handle(handle), guid(guid), name(name), first(first)
+ joy(LPDIRECTINPUTDEVICE8 handle, const QString& guid, const QString& name)
+ : joy_handle(handle), guid(guid), name(name)
{
qDebug() << "got joy" << guid;
for (int i = 0; i < 128; i++)
@@ -101,13 +101,14 @@ private:
class enum_state
{
std::unordered_map<QString, std::shared_ptr<joy>> joys;
- bool first;
+ QMainWindow& fake_main_window;
+ LPDIRECTINPUT8 di;
std::vector<QString> all;
static BOOL CALLBACK EnumJoysticksCallback(const DIDEVICEINSTANCE* pdidInstance, VOID* pContext);
static BOOL CALLBACK EnumObjectsCallback(const DIDEVICEOBJECTINSTANCE* pdidoi, VOID* ctx);
public:
- enum_state(std::unordered_map<QString, std::shared_ptr<joy>>& joys, bool first, QMutex &mtx);
+ enum_state(std::unordered_map<QString, std::shared_ptr<joy>>& joys, QMutex &mtx, QMainWindow& fake_main_window, LPDIRECTINPUT8 di);
};
};