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/Reset.cpp
|
||||||
backend/hidpp20/features/AdjustableDPI.cpp
|
backend/hidpp20/features/AdjustableDPI.cpp
|
||||||
backend/hidpp20/features/SmartShift.cpp
|
backend/hidpp20/features/SmartShift.cpp
|
||||||
|
backend/hidpp20/features/ReprogControls.cpp
|
||||||
backend/dj/Report.cpp
|
backend/dj/Report.cpp
|
||||||
util/mutex_queue.h
|
util/mutex_queue.h
|
||||||
util/thread.cpp
|
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