diff options
| -rw-r--r-- | opentrack/win32-joystick-shortcuts.hpp | 86 | 
1 files changed, 45 insertions, 41 deletions
diff --git a/opentrack/win32-joystick-shortcuts.hpp b/opentrack/win32-joystick-shortcuts.hpp index 530545dc..3e384da5 100644 --- a/opentrack/win32-joystick-shortcuts.hpp +++ b/opentrack/win32-joystick-shortcuts.hpp @@ -1,5 +1,7 @@  #pragma once +#ifdef _WIN32 +  #include <cstring>  #include <memory>  #include <vector> @@ -17,7 +19,7 @@  struct win32_joy_ctx  {      using fn = std::function<void(const QString& guid, int btn, bool held)>; -     +      void poll(fn f)      {          refresh(false); @@ -27,13 +29,13 @@ struct win32_joy_ctx                  joys.erase(joys.begin() + i);          }      } -     +      struct joy      {          LPDIRECTINPUTDEVICE8 joy_handle;          QString guid;          bool pressed[128]; -         +          joy(LPDIRECTINPUTDEVICE8 handle, const QString& guid) : joy_handle(handle), guid(guid)          {              qDebug() << "got joy" << guid; @@ -41,13 +43,13 @@ struct win32_joy_ctx                  pressed[i] = false;              poll([&](const QString&, int idx, bool held) -> void { pressed[idx] = held; });          } -         +          ~joy()          {              qDebug() << "nix joy" << guid;              release();          } -         +          void release()          {              if (joy_handle) @@ -57,12 +59,12 @@ struct win32_joy_ctx                  joy_handle = nullptr;              }          } -         +          bool poll(fn f)          {              HRESULT hr;              bool ok = false; -             +              for (int i = 0; i < 5; i++)              {                  if (!FAILED(joy_handle->Poll())) @@ -76,22 +78,22 @@ struct win32_joy_ctx                      ok = true;                  break;              } -             +              if (!ok)              {                  qDebug() << "joy acquire failed" << guid << hr;                  return false;              } -             +              DIJOYSTATE2 js;              memset(&js, 0, sizeof(js)); -             +              if (FAILED(hr = joy_handle->GetDeviceState(sizeof(js), &js)))              {                  qDebug() << "joy get state failed" << guid << hr;                  return false;              } -             +              for (int i = 0; i < 128; i++)              {                  const bool state = !!(js.rgbButtons[i] & 0x80); @@ -102,49 +104,49 @@ struct win32_joy_ctx                  }                  pressed[i] = state;              } -             +              return true;          }      }; -     +      static QString guid_to_string(const GUID guid)      {          char buf[40] = {0};          wchar_t szGuidW[40] = {0}; -         +          StringFromGUID2(guid, szGuidW, 40);          WideCharToMultiByte(0, 0, szGuidW, -1, buf, 40, NULL, NULL); -         +          return QString(buf);      } -     +      win32_joy_ctx() : dinput_handle(nullptr)      {          (void) CoInitialize(nullptr); -         +          HRESULT hr; -         +          if (FAILED(hr = DirectInput8Create(GetModuleHandle(nullptr),                                             DIRECTINPUT_VERSION,                                             IID_IDirectInput8,                                             (void**) &dinput_handle,                                             nullptr)))              goto fail; -         +          refresh(true); -         +          return;  fail:          qDebug() << "dinput8 failed for shortcuts" << hr; -         +          release();      } -     +      ~win32_joy_ctx()      {          release();      } -     +      void release()      {          joys = std::vector<std::shared_ptr<joy>>(); @@ -154,32 +156,32 @@ fail:              dinput_handle = nullptr;          }      } -     +      void refresh(bool first)      {          if (!dinput_handle)              return; -         +          if (!first)          {              if (timer_joylist.elapsed_ms() < joylist_refresh_ms)                  return;              timer_joylist.start();          } -         +          enum_state st(dinput_handle, joys);      } -     +      struct enum_state      {          std::vector<std::shared_ptr<joy>>& joys;          std::vector<QString> all;          LPDIRECTINPUT8 dinput_handle; -         +          enum_state(LPDIRECTINPUT8 di, std::vector<std::shared_ptr<joy>>& joys) : joys(joys), dinput_handle(di)          {              HRESULT hr; -             +              if(FAILED(hr = dinput_handle->EnumDevices(DI8DEVCLASS_GAMECTRL,                                                        EnumJoysticksCallback,                                                        this, @@ -188,7 +190,7 @@ fail:                  qDebug() << "failed enum joysticks" << hr;                  return;              } -             +              for (int i = joys.size() - 1; i >= 0; i--)              {                  const auto& guid = joys[i]->guid; @@ -196,7 +198,7 @@ fail:                      joys.erase(joys.begin() + i);              }          } -         +          static BOOL CALLBACK EnumJoysticksCallback(const DIDEVICEINSTANCE* pdidInstance, VOID* pContext)          {              enum_state& state = *reinterpret_cast<enum_state*>(pContext); @@ -207,13 +209,13 @@ fail:              const int cnt_names = std::count_if(state.joys.begin(), state.joys.end(), [&](const joy& j) -> bool { return j.name == name; });              // this is potentially bad since replugged sticks can change guids (?)  #endif -             +              const bool exists = std::find_if(state.joys.cbegin(),                                               state.joys.cend(),                                               [&](const std::shared_ptr<joy>& j) -> bool { return j->guid == guid; }) != state.joys.cend(); -             +              state.all.push_back(guid); -             +              if (!exists)              {                  HRESULT hr; @@ -229,7 +231,7 @@ fail:                      h->Release();                      goto end;                  } -                 +                  if (FAILED(h->SetCooperativeLevel((HWND) GetDesktopWindow(), DISCL_NONEXCLUSIVE | DISCL_BACKGROUND)))                  {                      qDebug() << "coop"; @@ -246,10 +248,10 @@ fail:  #endif                  state.joys.push_back(std::make_shared<joy>(h, guid));              } -             +  end:        return DIENUM_CONTINUE;          } -         +  #if 0          static BOOL CALLBACK EnumObjectsCallback(const DIDEVICEOBJECTINSTANCE* pdidoi, VOID* ctx)          { @@ -263,18 +265,20 @@ end:        return DIENUM_CONTINUE;                  diprg.diph.dwObj = pdidoi->dwType;                  diprg.lMax = 32;                  diprg.lMin = -32; -                 +                  if (FAILED(reinterpret_cast<LPDIRECTINPUTDEVICE8>(ctx)->SetProperty(DIPROP_RANGE, &diprg.diph)))                      return DIENUM_STOP;              } -             +              return DIENUM_CONTINUE;          }  #endif      }; -     +      LPDIRECTINPUT8 dinput_handle;      std::vector<std::shared_ptr<joy>> joys;      Timer timer_joylist;      enum { joylist_refresh_ms = 250 }; -};
\ No newline at end of file +}; + +#endif  | 
