Add hidpp20 ReprogControls support
This commit is contained in:
parent
c382ba1c0b
commit
3129cda581
|
@ -37,6 +37,7 @@ add_executable(logid
|
|||
backend/hidpp20/features/Reset.cpp
|
||||
backend/hidpp20/features/AdjustableDPI.cpp
|
||||
backend/hidpp20/features/SmartShift.cpp
|
||||
backend/hidpp20/features/ReprogControls.cpp
|
||||
backend/dj/Report.cpp
|
||||
util/mutex_queue.h
|
||||
util/thread.cpp
|
||||
|
|
133
src/logid/backend/hidpp20/features/ReprogControls.cpp
Normal file
133
src/logid/backend/hidpp20/features/ReprogControls.cpp
Normal file
|
@ -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;
|
||||
}
|
158
src/logid/backend/hidpp20/features/ReprogControls.h
Normal file
158
src/logid/backend/hidpp20/features/ReprogControls.h
Normal file
|
@ -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
Block a user