parent
c382ba1c0b
commit
3129cda581
3 changed files with 292 additions and 0 deletions
@ -0,0 +1,133 @@ |
||||
/*
|
||||
* 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 <cassert> |
||||
#include "ReprogControls.h" |
||||
|
||||
using namespace logid::backend::hidpp20; |
||||
|
||||
#define DEFINE_REPROG(x, base) \ |
||||
x::x(Device* dev) : base(dev, ID) \
|
||||
{ \
|
||||
} \
|
||||
x::x(Device* dev, uint16_t _id) : base(dev, _id) \
|
||||
{ \
|
||||
} |
||||
|
||||
#define MAKE_REPROG(x, dev) \ |
||||
try { \
|
||||
return x(dev); \
|
||||
} catch(UnsupportedFeature &e) {\
|
||||
} |
||||
|
||||
// Define all of the ReprogControls versions
|
||||
DEFINE_REPROG(ReprogControls, Feature); |
||||
DEFINE_REPROG(ReprogControlsV2, ReprogControls); |
||||
DEFINE_REPROG(ReprogControlsV2_2, ReprogControlsV2); |
||||
DEFINE_REPROG(ReprogControlsV3, ReprogControlsV2_2); |
||||
DEFINE_REPROG(ReprogControlsV4, ReprogControlsV3); |
||||
|
||||
ReprogControls ReprogControls::autoVersion(Device *dev) |
||||
{ |
||||
MAKE_REPROG(ReprogControlsV4, dev); |
||||
MAKE_REPROG(ReprogControlsV3, dev); |
||||
MAKE_REPROG(ReprogControlsV2_2, dev); |
||||
MAKE_REPROG(ReprogControlsV2, dev); |
||||
|
||||
// If base version cannot be made, throw error
|
||||
return ReprogControls(dev); |
||||
} |
||||
|
||||
uint8_t ReprogControls::getControlCount() |
||||
{ |
||||
std::vector<uint8_t> params(0); |
||||
auto response = callFunction(GetControlCount, params); |
||||
return response[0]; |
||||
} |
||||
|
||||
ReprogControls::ControlInfo ReprogControls::getControlInfo(uint8_t index) |
||||
{ |
||||
std::vector<uint8_t> params(1); |
||||
ControlInfo info{}; |
||||
params[0] = index; |
||||
auto response = callFunction(GetControlInfo, params); |
||||
|
||||
info.controlID = response[1]; |
||||
info.controlID |= response[0] << 8; |
||||
info.taskID = response[3]; |
||||
info.taskID |= response[2] << 8; |
||||
info.flags = response[4]; |
||||
info.position = response[5]; |
||||
info.group = response[6]; |
||||
info.groupMask = response[7]; |
||||
info.additionalFlags = response[8]; |
||||
return info; |
||||
} |
||||
|
||||
ReprogControls::ControlInfo ReprogControls::getControlReporting(uint16_t cid) |
||||
{ |
||||
std::vector<uint8_t> params(2); |
||||
ControlInfo info{}; |
||||
params[0] = (cid >> 8) & 0xff; |
||||
params[1] = cid & 0xff; |
||||
auto response = callFunction(GetControlReporting, params); |
||||
|
||||
info.controlID = response[1]; |
||||
info.controlID |= response[0] << 8; |
||||
info.flags = response[2]; |
||||
return info; |
||||
} |
||||
|
||||
void ReprogControls::setControlReporting(uint8_t cid, ControlInfo info) |
||||
{ |
||||
std::vector<uint8_t> params(5); |
||||
params[0] = (cid >> 8) & 0xff; |
||||
params[1] = cid & 0xff; |
||||
params[2] = info.flags; |
||||
params[3] = (info.controlID >> 8) & 0xff; |
||||
params[4] = info.controlID & 0xff; |
||||
callFunction(SetControlReporting, params); |
||||
} |
||||
|
||||
std::set<uint16_t> ReprogControls::divertedButtonEvent( |
||||
const hidpp::Report& report) |
||||
{ |
||||
assert(report.function() == DivertedButtonEvent); |
||||
std::set<uint16_t> buttons; |
||||
uint8_t cids = std::distance(report.paramBegin(), report.paramEnd())/2; |
||||
for(uint8_t i = 0; i < cids; i++) { |
||||
uint16_t cid = report.paramBegin()[2*i + 1]; |
||||
cid |= report.paramBegin()[2*i] << 8; |
||||
if(cid) |
||||
buttons.insert(cid); |
||||
else |
||||
break; |
||||
} |
||||
return buttons; |
||||
} |
||||
|
||||
ReprogControls::Move ReprogControls::divertedRawXYEvent(const hidpp::Report |
||||
&report) |
||||
{ |
||||
assert(report.function() == DivertedRawXYEvent); |
||||
Move move{}; |
||||
move.x = report.paramBegin()[1]; |
||||
move.x |= report.paramBegin()[0] << 8; |
||||
move.y = report.paramBegin()[3]; |
||||
move.y |= report.paramBegin()[2] << 8; |
||||
return move; |
||||
} |
@ -0,0 +1,158 @@ |
||||
/*
|
||||
* 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/>.
|
||||
* |
||||
*/ |
||||
#ifndef LOGID_BACKEND_HIDPP20_FEATURE_REPROGCONTROLS_H |
||||
#define LOGID_BACKEND_HIDPP20_FEATURE_REPROGCONTROLS_H |
||||
|
||||
#include "../feature_defs.h" |
||||
#include "../Feature.h" |
||||
|
||||
namespace logid { |
||||
namespace backend { |
||||
namespace hidpp20 |
||||
{ |
||||
class ReprogControls : public Feature |
||||
{ |
||||
public: |
||||
static const uint16_t ID = FeatureID::REPROG_CONTROLS; |
||||
virtual uint16_t getID() { return ID; } |
||||
|
||||
virtual bool supportsRawXY() { return false; } |
||||
|
||||
enum Function { |
||||
GetControlCount = 0, |
||||
GetControlInfo = 1, |
||||
GetControlReporting = 2, |
||||
SetControlReporting = 3 |
||||
}; |
||||
|
||||
enum Event { |
||||
DivertedButtonEvent = 0, |
||||
DivertedRawXYEvent = 1 |
||||
}; |
||||
|
||||
explicit ReprogControls(Device* dev); |
||||
|
||||
virtual uint8_t getControlCount(); |
||||
|
||||
struct ControlInfo |
||||
{ |
||||
uint16_t controlID; |
||||
uint16_t taskID; |
||||
uint8_t flags; |
||||
uint8_t position; // F key position, 0 if not an Fx key
|
||||
uint8_t group; |
||||
uint8_t groupMask; |
||||
uint8_t additionalFlags; |
||||
}; |
||||
|
||||
enum ControlInfoFlags: uint8_t |
||||
{ |
||||
MouseButton = 1, //Mouse button
|
||||
FKey = 1<<1, //Fx key
|
||||
Hotkey = 1<<2, |
||||
FnToggle = 1<<3, |
||||
ReprogHint = 1<<4, |
||||
TemporaryDivertable = 1<<5, |
||||
PerisentlyDiverable = 1<<6, |
||||
Virtual = 1<<7 |
||||
}; |
||||
enum ControlInfoAdditionalFlags: uint8_t { |
||||
RawXY = 1<<0 |
||||
}; |
||||
|
||||
virtual ControlInfo getControlInfo(uint8_t index); |
||||
|
||||
enum ControlReportingFlags: uint8_t { |
||||
TemporaryDiverted = 1<<0, |
||||
ChangeTemporaryDivert = 1<<1, |
||||
PersistentDiverted = 1<<2, |
||||
ChangePersistentDivert = 1<<3, |
||||
RawXYDiverted = 1<<4, |
||||
ChangeRawXYDivert = 1<<5 |
||||
}; |
||||
|
||||
// Onlu controlId and flags will be set
|
||||
virtual ControlInfo getControlReporting(uint16_t cid); |
||||
|
||||
// Only controlId (for remap) and flags will be read
|
||||
virtual void setControlReporting(uint8_t cid, ControlInfo info); |
||||
|
||||
static std::set<uint16_t> divertedButtonEvent(const hidpp::Report& |
||||
report); |
||||
|
||||
struct Move |
||||
{ |
||||
int16_t x; |
||||
int16_t y; |
||||
}; |
||||
|
||||
static Move divertedRawXYEvent(const hidpp::Report& report); |
||||
|
||||
static ReprogControls autoVersion(Device *dev); |
||||
protected: |
||||
ReprogControls(Device* dev, uint16_t _id); |
||||
}; |
||||
|
||||
class ReprogControlsV2 : public ReprogControls |
||||
{ |
||||
public: |
||||
static const uint16_t ID = FeatureID::REPROG_CONTROLS_V2; |
||||
uint16_t getID() override { return ID; } |
||||
|
||||
explicit ReprogControlsV2(Device* dev); |
||||
protected: |
||||
ReprogControlsV2(Device* dev, uint16_t _id); |
||||
}; |
||||
|
||||
class ReprogControlsV2_2 : public ReprogControlsV2 |
||||
{ |
||||
public: |
||||
static const uint16_t ID = FeatureID::REPROG_CONTROLS_V2_2; |
||||
uint16_t getID() override { return ID; } |
||||
|
||||
explicit ReprogControlsV2_2(Device* dev); |
||||
protected: |
||||
ReprogControlsV2_2(Device* dev, uint16_t _id); |
||||
}; |
||||
|
||||
class ReprogControlsV3 : public ReprogControlsV2_2 |
||||
{ |
||||
public: |
||||
static const uint16_t ID = FeatureID::REPROG_CONTROLS_V3; |
||||
uint16_t getID() override { return ID; } |
||||
|
||||
explicit ReprogControlsV3(Device* dev); |
||||
protected: |
||||
ReprogControlsV3(Device* dev, uint16_t _id); |
||||
}; |
||||
|
||||
class ReprogControlsV4 : public ReprogControlsV3 |
||||
{ |
||||
public: |
||||
static const uint16_t ID = FeatureID::REPROG_CONTROLS_V4; |
||||
uint16_t getID() override { return ID; } |
||||
|
||||
bool supportsRawXY() override { return true; } |
||||
|
||||
explicit ReprogControlsV4(Device* dev); |
||||
protected: |
||||
ReprogControlsV4(Device* dev, uint16_t _id); |
||||
}; |
||||
}}} |
||||
|
||||
#endif //LOGID_BACKEND_HIDPP20_FEATURE_REPROGCONTROLS_H
|
Loading…
Reference in new issue