summaryrefslogtreecommitdiffhomepage
path: root/dinput/dinput.cpp
diff options
context:
space:
mode:
authorStanislaw Halik <sthalik@misaki.pl>2016-08-12 18:00:49 +0200
committerStanislaw Halik <sthalik@misaki.pl>2016-08-12 18:00:49 +0200
commit9040b187a1c4fa380f8a12207b9dd6d04b3a10ac (patch)
tree115e1351571d690c1261a9d512e6d44e717f3051 /dinput/dinput.cpp
parent13a18b149764509a3f460be86590250cdcf690fb (diff)
all: rename modules s#^opentrack-##. and opentrack -> api
Adjust usages.
Diffstat (limited to 'dinput/dinput.cpp')
-rw-r--r--dinput/dinput.cpp98
1 files changed, 98 insertions, 0 deletions
diff --git a/dinput/dinput.cpp b/dinput/dinput.cpp
new file mode 100644
index 00000000..d408ff2f
--- /dev/null
+++ b/dinput/dinput.cpp
@@ -0,0 +1,98 @@
+#ifdef _WIN32
+
+#include "dinput.hpp"
+#include "compat/win32-com.hpp"
+#include <QDebug>
+
+std::atomic<int> dinput_handle::refcnt;
+std::atomic_flag dinput_handle::init_lock = ATOMIC_FLAG_INIT;
+dinput_handle::di_t dinput_handle::handle(dinput_handle::make_di());
+
+LPDIRECTINPUT8& dinput_handle::init_di()
+{
+ init_com_threading(com_multithreaded);
+
+ static LPDIRECTINPUT8 di_ = nullptr;
+ if (di_ == nullptr)
+ {
+ if (!SUCCEEDED(DirectInput8Create(GetModuleHandle(NULL), DIRECTINPUT_VERSION, IID_IDirectInput8, (void**)&di_, NULL)))
+ {
+ di_ = nullptr;
+ }
+ }
+ return di_;
+}
+
+dinput_handle::di_t dinput_handle::make_di()
+{
+ while (init_lock.test_and_set()) { /* busy loop */ }
+
+ LPDIRECTINPUT8& ret = init_di();
+
+ init_lock.clear();
+
+ return di_t(ret);
+}
+
+void dinput_handle::di_t::free_di()
+{
+ if (handle && *handle)
+ (*handle)->Release();
+ *handle = nullptr;
+ handle = nullptr;
+}
+
+void dinput_handle::di_t::ref_di()
+{
+ while (init_lock.test_and_set()) { /* busy loop */ }
+
+ const int refcnt_ = refcnt.fetch_add(1) + 1;
+ qDebug() << "start: dinput refcount now" << (refcnt_);
+
+ init_lock.clear();
+}
+
+dinput_handle::di_t& dinput_handle::di_t::operator=(const di_t& new_di)
+{
+ if (handle)
+ unref_di();
+
+ handle = new_di.handle;
+
+ if (handle)
+ ref_di();
+
+ return *this;
+}
+
+void dinput_handle::di_t::unref_di()
+{
+ while (init_lock.test_and_set()) { /* busy loop */ }
+
+ const int refcnt_ = refcnt.fetch_sub(1) - 1;
+
+ qDebug() << "exit: dinput refcount now" << refcnt_;
+
+ if (refcnt_ == 0)
+ {
+ qDebug() << "exit: deleting di handle";
+ free_di();
+ }
+
+ init_lock.clear();
+}
+
+dinput_handle::di_t::di_t(LPDIRECTINPUT8& handle) : handle(&handle)
+{
+ ref_di();
+}
+
+dinput_handle::di_t::di_t() : handle(nullptr) {}
+
+dinput_handle::di_t::~di_t()
+{
+ if (handle)
+ unref_di();
+}
+
+#endif