Add RC28 LED Control to the features and disable controls that don't make sense

qcpfix
Phil Taylor 2023-04-13 14:36:16 +01:00
rodzic 59bc2077e4
commit 58f38c1735
4 zmienionych plików z 126 dodań i 89 usunięć

Wyświetl plik

@ -496,6 +496,7 @@ void controllerSetup::newDevice(USBDEVICE* dev)
connect(&c->sens, &QSlider::valueChanged,
[dev,this](int val) { this->sensitivityMoved(dev,val); });
c->sensLayout.addStretch(0);
c->pageLabel.setText("Page:");
c->sensLayout.addWidget(&c->pageLabel);
c->page.setObjectName("Page SpinBox");
@ -508,46 +509,46 @@ void controllerSetup::newDevice(USBDEVICE* dev)
dev->pageSpin = &c->page;
switch (dev->type.model) {
case shuttleXpress:
c->image.load(":/resources/shuttlexpress.png");
break;
case shuttlePro2:
c->image.load(":/resources/shuttlepro.png");
break;
case RC28:
c->image.load(":/resources/rc28.png");
break;
case xBoxGamepad:
c->image.load(":/resources/xbox.png");
break;
case eCoderPlus:
c->image.load(":/resources/ecoder.png");
break;
case QuickKeys:
c->image.load(":/resources/quickkeys.png");
break;
case StreamDeckOriginal:
case StreamDeckOriginalV2:
case StreamDeckOriginalMK2:
c->image.load(":/resources/streamdeck.png");
break;
case StreamDeckMini:
case StreamDeckMiniV2:
c->image.load(":/resources/streamdeckmini.png");
break;
case StreamDeckXL:
case StreamDeckXLV2:
c->image.load(":/resources/streamdeckxl.png");
break;
case StreamDeckPlus:
c->image.load(":/resources/streamdeckplus.png");
break;
case StreamDeckPedal:
c->image.load(":/resources/streamdeckpedal.png");
break;
default:
this->adjustSize();
break;
case shuttleXpress:
c->image.load(":/resources/shuttlexpress.png");
break;
case shuttlePro2:
c->image.load(":/resources/shuttlepro.png");
break;
case RC28:
c->image.load(":/resources/rc28.png");
break;
case xBoxGamepad:
c->image.load(":/resources/xbox.png");
break;
case eCoderPlus:
c->image.load(":/resources/ecoder.png");
break;
case QuickKeys:
c->image.load(":/resources/quickkeys.png");
break;
case StreamDeckOriginal:
case StreamDeckOriginalV2:
case StreamDeckOriginalMK2:
c->image.load(":/resources/streamdeck.png");
break;
case StreamDeckMini:
case StreamDeckMiniV2:
c->image.load(":/resources/streamdeckmini.png");
break;
case StreamDeckXL:
case StreamDeckXLV2:
c->image.load(":/resources/streamdeckxl.png");
break;
case StreamDeckPlus:
c->image.load(":/resources/streamdeckplus.png");
break;
case StreamDeckPedal:
c->image.load(":/resources/streamdeckpedal.png");
break;
default:
this->adjustSize();
break;
}
c->bgImage = new QGraphicsPixmapItem(QPixmap::fromImage(c->image));
@ -656,6 +657,60 @@ void controllerSetup::newDevice(USBDEVICE* dev)
connect(&c->page, qOverload<int>(&QSpinBox::valueChanged),
[dev, this](int index) { this->pageChanged(dev, index); });
// Hide all controls that are not relevant to this controller
// We rely on being able to fallthrough case
#if defined __GNUC__
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wimplicit-fallthrough"
#endif
switch (dev->type.model) {
case QuickKeys:
break;
case StreamDeckPedal:
c->sensLabel.setVisible(false);
c->sens.setVisible(false);
case shuttleXpress:
case shuttlePro2:
case RC28:
case xBoxGamepad:
case eCoderPlus:
c->brightLabel.setVisible(false);
c->speedLabel.setVisible(false);
c->timeoutLabel.setVisible(false);
c->orientLabel.setVisible(false);
c->brightness.setVisible(false);
c->speed.setVisible(false);
c->timeout.setVisible(false);
c->orientation.setVisible(false);
c->color.setVisible(false);
break;
case StreamDeckOriginal:
case StreamDeckOriginalV2:
case StreamDeckOriginalMK2:
case StreamDeckMini:
case StreamDeckMiniV2:
case StreamDeckXL:
case StreamDeckXLV2:
c->sensLabel.setVisible(false);
c->sens.setVisible(false); // No knobs!
case StreamDeckPlus:
c->speedLabel.setVisible(false);
c->timeoutLabel.setVisible(false);
c->orientLabel.setVisible(false);
c->speed.setVisible(false);
c->timeout.setVisible(false);
c->orientation.setVisible(false);
break;
default:
break;
}
// Don't allow fallthrough elsewhere in the file.
#if defined __GNUC__
#pragma GCC diagnostic pop
#endif
// pageChanged will update the buttons/knobs for the tab (using qTimer ensures mutex is unlocked first)
QTimer::singleShot(0, this, [=]() { pageChanged(dev,1); });

Wyświetl plik

@ -1,10 +1,6 @@
#if defined(USB_CONTROLLER)
#include "usbcontroller.h"
// We rely on being able to fallthrough case
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wimplicit-fallthrough"
#ifdef Q_OS_WIN
#pragma comment (lib, "Setupapi.lib")
#endif
@ -50,7 +46,7 @@ usbController::~usbController()
sendRequest(dev,usbFeatureType::featureOverlay,60,"Goodbye from wfview");
if (dev->type.model == RC28) {
ledControl(false, 3);
sendRequest(dev,usbFeatureType::featureLEDControl,3,"off");
}
emit removeDevice(dev);
hid_close(dev->handle);
@ -261,7 +257,7 @@ void usbController::run()
devs = hid_enumerate(0x0, 0x0);
// Step through all currenly connected devices and add any newly discovered ones to usbDevices.
while (devs) {
auto i = std::find_if(knownDevices.begin(), knownDevices.end(), [this,devs](const USBTYPE& d)
auto i = std::find_if(knownDevices.begin(), knownDevices.end(), [devs](const USBTYPE& d)
{ return ((devs->vendor_id == d.manufacturerId) && (devs->product_id == d.productId)
&& (d.usage == 0x00 || devs->usage == d.usage)
&& (d.usagePage == 0x00 || devs->usage_page == d.usagePage));});
@ -327,10 +323,10 @@ void usbController::run()
if (dev->type.model == RC28)
{
ledControl(false, 0);
ledControl(false, 1);
ledControl(false, 2);
ledControl(true, 3);
QTimer::singleShot(0, this, [=]() { sendRequest(dev,usbFeatureType::featureLEDControl,0,"off"); });
QTimer::singleShot(0, this, [=]() { sendRequest(dev,usbFeatureType::featureLEDControl,1,"off"); });
QTimer::singleShot(0, this, [=]() { sendRequest(dev,usbFeatureType::featureLEDControl,2,"off"); });
QTimer::singleShot(0, this, [=]() { sendRequest(dev,usbFeatureType::featureLEDControl,3,"on"); });
}
else if (dev->type.model == QuickKeys)
{
@ -830,40 +826,12 @@ void usbController::sendToLCD(QImage* img)
}
}
/*
* All functions below here are for specific controllers
*/
void usbController::ledControl(bool on, unsigned char num)
{
// Currently this will act on ALL connected RC28 devices
// Not sure if this needs to change?
QMutexLocker locker(mutex);
for (auto devIt = devices->begin(); devIt != devices->end(); devIt++)
{
auto dev = &devIt.value();
if (dev->connected && dev->type.model == RC28) {
QByteArray data(3, 0x0);
data[1] = 0x01;
static unsigned char ledNum = 0x07;
if (on)
ledNum &= ~(1UL << num);
else
ledNum |= 1UL << num;
data[2] = ledNum;
int res = hid_write(dev->handle, (const unsigned char*)data.constData(), data.size());
if (res < 0) {
qDebug(logUsbControl()) << "Unable to write(), Error:" << hid_error(dev->handle);
return;
}
}
}
}
// We rely on being able to fallthrough case
#if defined __GNUC__
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wimplicit-fallthrough"
#endif
/* This function will handle various commands for multiple models of controller
*
@ -871,7 +839,6 @@ void usbController::ledControl(bool on, unsigned char num)
* featureInit, featureFirmware, featureSerial, featureButton, featureSensitivity, featureBrightness,
* featureOrientation, featureSpeed, featureColor, featureOverlay, featureTimeout, featurePages, featureDisable
*/
void usbController::sendRequest(USBDEVICE *dev, usbFeatureType feature, int val, QString text, QImage* img, QColor* color)
{
if (dev == Q_NULLPTR || !dev->connected || dev->disabled || !dev->handle)
@ -1281,15 +1248,27 @@ void usbController::sendRequest(USBDEVICE *dev, usbFeatureType feature, int val,
}
break;
case RC28:
data.resize(3);
memset(data.data(),0x0,data.size());
switch (feature)
{
case usbFeatureType::featureFirmware:
data[0] = 63;
data[1] = 0x02;
hid_write(dev->handle, (const unsigned char*)data.constData(), data.size());
break;
case usbFeatureType::featureLEDControl:
data[1] = 0x01;
data[2] = 0x07;
if (text == "on")
data[2] &= ~(1UL << val);
else
data[2] |= 1UL << val;
break;
default:
return; // No command
break;
}
res = hid_write(dev->handle, (const unsigned char*)data.constData(), data.size());
break;
default:
break;
@ -1299,6 +1278,11 @@ void usbController::sendRequest(USBDEVICE *dev, usbFeatureType feature, int val,
qInfo(logUsbControl()) << "Command" << feature << "returned" << res;
}
// Don't allow fallthrough elsewhere in the file.
#if defined __GNUC__
#pragma GCC diagnostic pop
#endif
void usbController::programDisable(USBDEVICE* dev, bool disabled)
{
dev->disabled = disabled;
@ -1311,7 +1295,7 @@ void usbController::programDisable(USBDEVICE* dev, bool disabled)
sendRequest(dev,usbFeatureType::featureOverlay,60,"Goodbye from wfview");
if (dev->type.model == RC28) {
ledControl(false, 3);
sendRequest(dev,usbFeatureType::featureLEDControl,3,"off");
}
QMutexLocker locker(mutex);
@ -2080,5 +2064,4 @@ void usbController::restoreController(USBDEVICE* dev, QString file)
QTimer::singleShot(250, this, SLOT(run())); // Call run to cleanup connectons after 250ms
}
#pragma GCC diagnostic pop
#endif

Wyświetl plik

@ -229,7 +229,6 @@ public slots:
void init(QMutex* mut,usbDevMap* prefs ,QVector<BUTTON>* buts,QVector<KNOB>* knobs);
void run();
void runTimer();
void ledControl(bool on, unsigned char num);
void receivePTTStatus(bool on);
void receiveLevel(cmds cmd, unsigned char level);
void programPages(USBDEVICE* dev, int pages);

Wyświetl plik

@ -207,6 +207,6 @@ enum usbDeviceType { usbNone = 0, shuttleXpress, shuttlePro2,
enum usbCommandType{ commandButton, commandKnob, commandAny };
enum usbFeatureType { featureReset,featureResetKeys, featureEventsA, featureEventsB, featureFirmware, featureSerial, featureButton, featureSensitivity, featureBrightness,
featureOrientation, featureSpeed, featureColor, featureOverlay, featureTimeout, featureLCD, featureGraph };
featureOrientation, featureSpeed, featureColor, featureOverlay, featureTimeout, featureLCD, featureGraph, featureLEDControl };
#endif // WFVIEWTYPES_H