summaryrefslogtreecommitdiffhomepage
path: root/opentrack-logic
diff options
context:
space:
mode:
authorStanislaw Halik <sthalik@misaki.pl>2016-07-07 14:15:18 +0200
committerStanislaw Halik <sthalik@misaki.pl>2016-07-07 14:15:18 +0200
commit5f5ca66c58ad30d0c218b2da904aa3f722e18ebe (patch)
tree8e8d5bae3ca7edf6c96c7f0e0da87f347486b045 /opentrack-logic
parentc418644838e99416fb168066bacc28a4cbc36a04 (diff)
logic/dinput: only ever use a single handle to DIRECTINPUT8 COM object
Diffstat (limited to 'opentrack-logic')
-rw-r--r--opentrack-logic/dinput.cpp48
-rw-r--r--opentrack-logic/dinput.hpp27
-rw-r--r--opentrack-logic/keybinding-worker.cpp28
-rw-r--r--opentrack-logic/keybinding-worker.hpp12
-rw-r--r--opentrack-logic/win32-joystick.cpp40
-rw-r--r--opentrack-logic/win32-joystick.hpp17
-rw-r--r--opentrack-logic/win32-shortcuts.cpp2
7 files changed, 98 insertions, 76 deletions
diff --git a/opentrack-logic/dinput.cpp b/opentrack-logic/dinput.cpp
new file mode 100644
index 00000000..4958e862
--- /dev/null
+++ b/opentrack-logic/dinput.cpp
@@ -0,0 +1,48 @@
+#ifdef _WIN32
+
+#include "dinput.hpp"
+#include <QDebug>
+
+dinput_handle dinput_handle::self;
+
+dinput_handle::dinput_handle() : handle(init_di())
+{
+}
+
+dinput_handle::~dinput_handle()
+{
+ if (handle)
+ {
+ handle->Release();
+ handle = nullptr;
+ }
+}
+
+dinput_handle::di_t dinput_handle::init_di()
+{
+ HRESULT hr = CoInitializeEx(NULL, COINIT_APARTMENTTHREADED);
+ if (FAILED(hr))
+ qDebug() << "dinput: failed CoInitializeEx" << hr << GetLastError();
+
+ static LPDIRECTINPUT8 di_ = nullptr;
+ if (di_ == nullptr)
+ {
+ if (SUCCEEDED(DirectInput8Create(GetModuleHandle(NULL), DIRECTINPUT_VERSION, IID_IDirectInput8, (void**)&di_, NULL)))
+ {
+ qDebug() << "made dinput8 handle";
+ return di_;
+ }
+ else
+ {
+ return di_ = nullptr;
+ }
+ }
+ return di_;
+}
+
+dinput_handle::di_t dinput_handle::make_di()
+{
+ return self.handle;
+}
+
+#endif
diff --git a/opentrack-logic/dinput.hpp b/opentrack-logic/dinput.hpp
new file mode 100644
index 00000000..9300f39f
--- /dev/null
+++ b/opentrack-logic/dinput.hpp
@@ -0,0 +1,27 @@
+#pragma once
+
+#ifdef _WIN32
+
+#ifndef DIRECTINPUT_VERSION
+# define DIRECTINPUT_VERSION 0x800
+#endif
+#include <dinput.h>
+#include <windows.h>
+
+struct dinput_handle final
+{
+ using di_t = LPDIRECTINPUT8;
+private:
+ static dinput_handle self;
+ dinput_handle();
+ ~dinput_handle();
+ static di_t init_di();
+ di_t handle;
+public:
+ static di_t make_di();
+
+ dinput_handle(const dinput_handle&) = delete;
+ dinput_handle(dinput_handle&&) = delete;
+};
+
+#endif
diff --git a/opentrack-logic/keybinding-worker.cpp b/opentrack-logic/keybinding-worker.cpp
index eba026a5..a009d399 100644
--- a/opentrack-logic/keybinding-worker.cpp
+++ b/opentrack-logic/keybinding-worker.cpp
@@ -23,56 +23,47 @@ bool Key::should_process()
return ret;
}
-KeybindingWorker::~KeybindingWorker() {
+KeybindingWorker::~KeybindingWorker()
+{
should_quit = true;
wait();
if (dinkeyboard) {
dinkeyboard->Unacquire();
dinkeyboard->Release();
}
- if (din)
- din->Release();
}
-KeybindingWorker::KeybindingWorker() :
- should_quit(true)
+KeybindingWorker::KeybindingWorker() : should_quit(true)
{
- if (DirectInput8Create(GetModuleHandle(NULL), DIRECTINPUT_VERSION, IID_IDirectInput8, (void**)&din, NULL) != DI_OK) {
- qDebug() << "setup DirectInput8 Creation failed!" << GetLastError();
- return;
- }
+ LPDIRECTINPUT8 din = dinput_handle::make_di();
+
if (din->CreateDevice(GUID_SysKeyboard, &dinkeyboard, NULL) != DI_OK) {
- din->Release();
- din = 0;
qDebug() << "setup CreateDevice function failed!" << GetLastError();
return;
}
+
if (dinkeyboard->SetDataFormat(&c_dfDIKeyboard) != DI_OK) {
qDebug() << "setup SetDataFormat function failed!" << GetLastError();
dinkeyboard->Release();
dinkeyboard = 0;
- din->Release();
- din = 0;
return;
}
if (dinkeyboard->SetCooperativeLevel((HWND) fake_main_window.winId(), DISCL_NONEXCLUSIVE | DISCL_BACKGROUND) != DI_OK) {
dinkeyboard->Release();
- din->Release();
- din = 0;
dinkeyboard = 0;
qDebug() << "setup SetCooperativeLevel function failed!" << GetLastError();
return;
}
+
if (dinkeyboard->Acquire() != DI_OK)
{
dinkeyboard->Release();
- din->Release();
- din = 0;
dinkeyboard = 0;
qDebug() << "setup dinkeyboard Acquire failed!" << GetLastError();
return;
}
+
should_quit = false;
start();
}
@@ -83,7 +74,8 @@ KeybindingWorker& KeybindingWorker::make()
return k;
}
-void KeybindingWorker::run() {
+void KeybindingWorker::run()
+{
BYTE keystate[256] = {0};
BYTE old_keystate[256] = {0};
diff --git a/opentrack-logic/keybinding-worker.hpp b/opentrack-logic/keybinding-worker.hpp
index 12237ab0..e38e5046 100644
--- a/opentrack-logic/keybinding-worker.hpp
+++ b/opentrack-logic/keybinding-worker.hpp
@@ -12,6 +12,7 @@
#include "opentrack-compat/timer.hpp"
#include "win32-joystick.hpp"
+#include "dinput.hpp"
#include <QThread>
#include <QMutex>
#include <QWidget>
@@ -40,25 +41,26 @@ public:
struct OPENTRACK_LOGIC_EXPORT KeybindingWorker : private QThread
{
+ using fun = std::function<void(const Key&)>;
+
private:
- LPDIRECTINPUT8 din;
LPDIRECTINPUTDEVICE8 dinkeyboard;
win32_joy_ctx joy_ctx;
- volatile bool should_quit;
- using fun = std::function<void(const Key&)>;
std::vector<std::unique_ptr<fun>> receivers;
QMutex mtx;
QMainWindow fake_main_window;
+ volatile bool should_quit;
void run() override;
KeybindingWorker();
- KeybindingWorker(const KeybindingWorker&) = delete;
- KeybindingWorker& operator=(KeybindingWorker&) = delete;
static KeybindingWorker& make();
fun* _add_receiver(fun &receiver);
void remove_receiver(fun* pos);
~KeybindingWorker();
+
+ KeybindingWorker(const KeybindingWorker&) = delete;
+ KeybindingWorker& operator=(KeybindingWorker&) = delete;
public:
class Token
{
diff --git a/opentrack-logic/win32-joystick.cpp b/opentrack-logic/win32-joystick.cpp
index a24224b0..fa1a8060 100644
--- a/opentrack-logic/win32-joystick.cpp
+++ b/opentrack-logic/win32-joystick.cpp
@@ -109,24 +109,6 @@ std::vector<win32_joy_ctx::joy_info> win32_joy_ctx::get_joy_info()
return ret;
}
-win32_joy_ctx::di_t& win32_joy_ctx::make_di()
-{
- static LPDIRECTINPUT8 di_ = nullptr;
- if (di_ == nullptr)
- {
- if (SUCCEEDED(DirectInput8Create(GetModuleHandle(NULL), DIRECTINPUT_VERSION, IID_IDirectInput8, (void**)&di_, NULL)))
- {
- qDebug() << "made di handle";
- return di_;
- }
- else
- {
- return di_ = nullptr;
- }
- }
- return di_;
-}
-
win32_joy_ctx::win32_joy_ctx()
{
refresh();
@@ -244,23 +226,14 @@ win32_joy_ctx::enum_state::~enum_state()
{
QMutexLocker l(&mtx);
- di_t& di = make_di();
- if (!di)
- {
- qDebug() << "can't create dinput";
- return;
- }
-
joys = std::unordered_map<QString, std::shared_ptr<joy>>();
- di->Release();
- di = nullptr;
}
void win32_joy_ctx::enum_state::refresh()
{
all.clear();
- di_t di = make_di();
+ di_t di = dinput_handle::make_di();
if (!di)
{
qDebug() << "can't create dinput";
@@ -293,7 +266,7 @@ void win32_joy_ctx::enum_state::refresh()
BOOL CALLBACK win32_joy_ctx::enum_state::EnumJoysticksCallback(const DIDEVICEINSTANCE *pdidInstance, void *pContext)
{
- di_t di = make_di();
+ di_t di = dinput_handle::make_di();
if (!di)
{
qDebug() << "can't create dinput";
@@ -386,13 +359,4 @@ win32_joy_ctx::joy::~joy()
release();
}
-win32_joy_ctx::di_initializer::di_initializer()
-{
- HRESULT hr = CoInitializeEx(NULL, COINIT_APARTMENTTHREADED);
- if (FAILED(hr))
- qDebug() << "dinput: failed CoInitializeEx" << hr << GetLastError();
- win32_joy_ctx::make_di();
- qDebug() << "made directinput8 handle";
-}
-
#endif
diff --git a/opentrack-logic/win32-joystick.hpp b/opentrack-logic/win32-joystick.hpp
index ab6ebc7c..f8c2e7e4 100644
--- a/opentrack-logic/win32-joystick.hpp
+++ b/opentrack-logic/win32-joystick.hpp
@@ -2,20 +2,15 @@
#ifdef _WIN32
+#include "dinput.hpp"
+#include "opentrack-compat/timer.hpp"
#include "export.hpp"
-
#include <cstring>
#include <memory>
#include <vector>
#include <functional>
#include <algorithm>
#include <unordered_map>
-#ifndef DIRECTINPUT_VERSION
-# define DIRECTINPUT_VERSION 0x800
-#endif
-#include <dinput.h>
-#include <windows.h>
-#include "opentrack-compat/timer.hpp"
#include <QString>
#include <QDebug>
#include <QMutex>
@@ -35,7 +30,6 @@ struct hash<QString>
struct OPENTRACK_LOGIC_EXPORT win32_joy_ctx
{
- using di_t = LPDIRECTINPUT8;
using fn = std::function<void(const QString& guid, int btn, bool held)>;
struct joy
@@ -70,13 +64,8 @@ struct OPENTRACK_LOGIC_EXPORT win32_joy_ctx
win32_joy_ctx();
void refresh();
- static di_t& make_di();
- class di_initializer final
- {
- static di_initializer self;
- di_initializer();
- };
+ using di_t = dinput_handle::di_t;
private:
static QString guid_to_string(const GUID guid);
diff --git a/opentrack-logic/win32-shortcuts.cpp b/opentrack-logic/win32-shortcuts.cpp
index a93803a3..5c19cad7 100644
--- a/opentrack-logic/win32-shortcuts.cpp
+++ b/opentrack-logic/win32-shortcuts.cpp
@@ -13,10 +13,10 @@
# include <windows.h>
# include <dinput.h>
+#include "win32-shortcuts.h"
#include <QList>
#include <QVariant>
#include <QDebug>
-#include "win32-shortcuts.h"
QList<win_key> windows_key_mods =
QList<win_key>({