boo/lib/inputdev/DeviceFinder.cpp

138 lines
3.6 KiB
C++
Raw Normal View History

2016-08-17 20:04:19 +00:00
#include "boo/inputdev/DeviceFinder.hpp"
#include <cstdio>
#include <cstdlib>
2016-08-17 20:04:19 +00:00
#if _WIN32
#include <Dbt.h>
#include <hidclass.h>
#include <usbiodef.h>
2016-08-17 20:04:19 +00:00
#endif
2018-12-08 05:17:51 +00:00
namespace boo {
2016-08-17 20:04:19 +00:00
2017-09-15 22:26:39 +00:00
DeviceFinder* DeviceFinder::skDevFinder = nullptr;
DeviceFinder::DeviceFinder(std::unordered_set<uint64_t> types) {
if (skDevFinder) {
fmt::print(stderr, fmt("only one instance of CDeviceFinder may be constructed"));
std::abort();
}
skDevFinder = this;
for (const uint64_t& typeHash : types) {
const DeviceSignature* sigIter = BOO_DEVICE_SIGS;
while (sigIter->m_name) {
if (sigIter->m_typeHash == typeHash)
m_types.push_back(sigIter);
++sigIter;
}
}
}
DeviceFinder::~DeviceFinder() {
if (m_listener)
m_listener->stopScanning();
skDevFinder = nullptr;
}
bool DeviceFinder::_insertToken(std::unique_ptr<DeviceToken>&& token) {
if (DeviceSignature::DeviceMatchToken(*token, m_types)) {
m_tokensLock.lock();
TInsertedDeviceToken insertedTok = m_tokens.insert(std::make_pair(token->getDevicePath(), std::move(token)));
m_tokensLock.unlock();
deviceConnected(*insertedTok.first->second);
return true;
}
return false;
}
void DeviceFinder::_removeToken(const std::string& path) {
auto preCheck = m_tokens.find(path);
if (preCheck != m_tokens.end()) {
DeviceToken& tok = *preCheck->second;
std::shared_ptr<DeviceBase> dev = tok.m_connectedDev;
tok._deviceClose();
deviceDisconnected(tok, dev.get());
m_tokensLock.lock();
m_tokens.erase(preCheck);
m_tokensLock.unlock();
}
}
bool DeviceFinder::startScanning() {
if (!m_listener)
m_listener = IHIDListenerNew(*this);
if (m_listener)
return m_listener->startScanning();
return false;
}
bool DeviceFinder::stopScanning() {
if (!m_listener)
m_listener = IHIDListenerNew(*this);
if (m_listener)
return m_listener->stopScanning();
return false;
}
bool DeviceFinder::scanNow() {
if (!m_listener)
m_listener = IHIDListenerNew(*this);
if (m_listener)
return m_listener->scanNow();
return false;
}
2017-12-06 03:20:59 +00:00
#if _WIN32 && !WINDOWS_STORE
2016-08-17 20:04:19 +00:00
/* Windows-specific WM_DEVICECHANGED handler */
2018-12-08 05:17:51 +00:00
LRESULT DeviceFinder::winDevChangedHandler(WPARAM wParam, LPARAM lParam) {
PDEV_BROADCAST_HDR dbh = (PDEV_BROADCAST_HDR)lParam;
PDEV_BROADCAST_DEVICEINTERFACE dbhi = (PDEV_BROADCAST_DEVICEINTERFACE)lParam;
DeviceFinder* finder = instance();
if (!finder)
return 0;
2016-08-17 20:04:19 +00:00
2018-12-08 05:17:51 +00:00
if (wParam == DBT_DEVICEARRIVAL) {
if (dbh->dbch_devicetype == DBT_DEVTYP_DEVICEINTERFACE) {
DeviceType type = DeviceType::None;
if (dbhi->dbcc_classguid == GUID_DEVINTERFACE_USB_DEVICE)
type = DeviceType::USB;
else if (dbhi->dbcc_classguid == GUID_DEVINTERFACE_HID)
type = DeviceType::HID;
2018-12-08 05:17:51 +00:00
if (type != DeviceType::None) {
2016-08-17 20:04:19 +00:00
#ifdef UNICODE
2018-12-08 05:17:51 +00:00
char devPath[1024];
wcstombs(devPath, dbhi->dbcc_name, 1024);
finder->m_listener->_extDevConnect(devPath);
2016-08-17 20:04:19 +00:00
#else
2018-12-08 05:17:51 +00:00
finder->m_listener->_extDevConnect(dbhi->dbcc_name);
2016-08-17 20:04:19 +00:00
#endif
2018-12-08 05:17:51 +00:00
}
2016-08-17 20:04:19 +00:00
}
2018-12-08 05:17:51 +00:00
} else if (wParam == DBT_DEVICEREMOVECOMPLETE) {
if (dbh->dbch_devicetype == DBT_DEVTYP_DEVICEINTERFACE) {
DeviceType type = DeviceType::None;
if (dbhi->dbcc_classguid == GUID_DEVINTERFACE_USB_DEVICE)
type = DeviceType::USB;
else if (dbhi->dbcc_classguid == GUID_DEVINTERFACE_HID)
type = DeviceType::HID;
2018-12-08 05:17:51 +00:00
if (type != DeviceType::None) {
2016-08-17 20:04:19 +00:00
#ifdef UNICODE
2018-12-08 05:17:51 +00:00
char devPath[1024];
wcstombs(devPath, dbhi->dbcc_name, 1024);
finder->m_listener->_extDevDisconnect(devPath);
2016-08-17 20:04:19 +00:00
#else
2018-12-08 05:17:51 +00:00
finder->m_listener->_extDevDisconnect(dbhi->dbcc_name);
2016-08-17 20:04:19 +00:00
#endif
2018-12-08 05:17:51 +00:00
}
2016-08-17 20:04:19 +00:00
}
2018-12-08 05:17:51 +00:00
}
2016-08-17 20:04:19 +00:00
2018-12-08 05:17:51 +00:00
return 0;
2016-08-17 20:04:19 +00:00
}
#endif
2018-12-08 05:17:51 +00:00
} // namespace boo