You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
152 lines
4.0 KiB
152 lines
4.0 KiB
/* |
|
* Copyright 2019-2020 PixlOne |
|
* |
|
* This program is free software: you can redistribute it and/or modify |
|
* it under the terms of the GNU General Public License as published by |
|
* the Free Software Foundation, either version 3 of the License, or |
|
* (at your option) any later version. |
|
* |
|
* This program is distributed in the hope that it will be useful, |
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of |
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
|
* GNU General Public License for more details. |
|
* |
|
* You should have received a copy of the GNU General Public License |
|
* along with this program. If not, see <http://www.gnu.org/licenses/>. |
|
* |
|
*/ |
|
|
|
#include <thread> |
|
#include "util/log.h" |
|
#include "features/DPI.h" |
|
#include "Device.h" |
|
#include "Receiver.h" |
|
#include "features/SmartShift.h" |
|
#include "features/RemapButton.h" |
|
#include "backend/hidpp20/features/Reset.h" |
|
#include "features/HiresScroll.h" |
|
#include "features/DeviceStatus.h" |
|
#include "features/ThumbWheel.h" |
|
|
|
using namespace logid; |
|
using namespace logid::backend; |
|
|
|
Device::Device(std::string path, backend::hidpp::DeviceIndex index) : |
|
_hidpp20 (path, index), _path (std::move(path)), _index (index), |
|
_config (global_config, this), _receiver (nullptr) |
|
{ |
|
_init(); |
|
} |
|
|
|
Device::Device(const std::shared_ptr<backend::raw::RawDevice>& raw_device, |
|
hidpp::DeviceIndex index) : _hidpp20(raw_device, index), _path |
|
(raw_device->hidrawPath()), _index (index), |
|
_config (global_config, this), _receiver (nullptr) |
|
{ |
|
_init(); |
|
} |
|
|
|
Device::Device(Receiver* receiver, hidpp::DeviceIndex index) : _hidpp20 |
|
(receiver->rawReceiver(), index), _path (receiver->path()), _index (index), |
|
_config (global_config, this), _receiver (receiver) |
|
{ |
|
_init(); |
|
} |
|
|
|
void Device::_init() |
|
{ |
|
logPrintf(INFO, "Device found: %s on %s:%d", name().c_str(), |
|
hidpp20().devicePath().c_str(), _index); |
|
|
|
_addFeature<features::DPI>("dpi"); |
|
_addFeature<features::SmartShift>("smartshift"); |
|
_addFeature<features::HiresScroll>("hiresscroll"); |
|
_addFeature<features::RemapButton>("remapbutton"); |
|
_addFeature<features::DeviceStatus>("devicestatus"); |
|
_addFeature<features::ThumbWheel>("thumbwheel"); |
|
|
|
_makeResetMechanism(); |
|
reset(); |
|
|
|
for(auto& feature: _features) { |
|
feature.second->configure(); |
|
feature.second->listen(); |
|
} |
|
|
|
_hidpp20.listen(); |
|
} |
|
|
|
std::string Device::name() |
|
{ |
|
return _hidpp20.name(); |
|
} |
|
|
|
uint16_t Device::pid() |
|
{ |
|
return _hidpp20.pid(); |
|
} |
|
|
|
void Device::sleep() |
|
{ |
|
logPrintf(INFO, "%s:%d fell asleep.", _path.c_str(), _index); |
|
} |
|
|
|
void Device::wakeup() |
|
{ |
|
logPrintf(INFO, "%s:%d woke up.", _path.c_str(), _index); |
|
std::this_thread::sleep_for(std::chrono::milliseconds(100)); |
|
|
|
reset(); |
|
|
|
for(auto& feature: _features) |
|
feature.second->configure(); |
|
} |
|
|
|
void Device::reset() |
|
{ |
|
if(_reset_mechanism) |
|
(*_reset_mechanism)(); |
|
else |
|
logPrintf(DEBUG, "%s:%d tried to reset, but no reset mechanism was " |
|
"available.", _path.c_str(), _index); |
|
} |
|
|
|
DeviceConfig& Device::config() |
|
{ |
|
return _config; |
|
} |
|
|
|
hidpp20::Device& Device::hidpp20() |
|
{ |
|
return _hidpp20; |
|
} |
|
|
|
void Device::_makeResetMechanism() |
|
{ |
|
try { |
|
hidpp20::Reset reset(&_hidpp20); |
|
_reset_mechanism = std::make_unique<std::function<void()>>( |
|
[dev=&this->_hidpp20]{ |
|
hidpp20::Reset reset(dev); |
|
reset.reset(reset.getProfile()); |
|
}); |
|
} catch(hidpp20::UnsupportedFeature& e) { |
|
// Reset unsupported, ignore. |
|
} |
|
} |
|
|
|
DeviceConfig::DeviceConfig(const std::shared_ptr<Configuration>& config, Device* |
|
device) : _device (device), _config (config) |
|
{ |
|
try { |
|
_root_setting = config->getDevice(device->name()); |
|
} catch(Configuration::DeviceNotFound& e) { |
|
logPrintf(INFO, "Device %s not configured, using default config.", |
|
device->name().c_str()); |
|
} |
|
} |
|
|
|
libconfig::Setting& DeviceConfig::getSetting(const std::string& path) |
|
{ |
|
return _config->getSetting(_root_setting + '/' + path); |
|
}
|
|
|