mirror of
https://github.com/CalcProgrammer1/OpenRGB.git
synced 2025-12-26 08:47:50 -05:00
153 lines
4.8 KiB
C++
153 lines
4.8 KiB
C++
/*-----------------------------------------*\
|
|
| RGBController_HyperXMicrophone.cpp |
|
|
| |
|
|
| Implementation for the HyperX |
|
|
| Quadcast S RGB microphone |
|
|
| |
|
|
| Matt Silva (thesilvanator) 2022 |
|
|
\*-----------------------------------------*/
|
|
|
|
/**------------------------------------------------------------------*\
|
|
@name HyperX Quadcast S
|
|
@type USB
|
|
@save :white_check_mark:
|
|
@direct :white_check_mark:
|
|
@effects :x:
|
|
@detectors DetectHyperXMicrophoneControllers
|
|
@comment The HyperX Quadcast S has a manufacturer issue
|
|
with the interface it uses (0) for controlling its RGB.
|
|
HID requires that any HID interface have at least one
|
|
Interrupt IN endpoint; however, the HXQS does not,
|
|
even though its interface reports itelf as hid and
|
|
responds to hid requests. As such Linux doesn't bind
|
|
to the usbhid driver and it goes undetected by
|
|
hidapi-hidraw. Windows does detect it as hid and hidapi
|
|
finds and interacts with it just fine. To work around
|
|
the Linux issue, hidapi-libusb is loaded dynamically
|
|
using dlopen/dlsym as hidapi using a libusb backend is
|
|
able to find the device and interact with it. This
|
|
requires that you have support for dlopen/dlsym on your
|
|
Linux platform as well as hidapi-libusb (and libusb)
|
|
libraries installed in the standard dynamic library
|
|
path.
|
|
|
|
The controller for this device has a wrapper for hidapi
|
|
functions so that the controller can be the same across
|
|
all platforms, but call the correct underlying functions
|
|
that are defined in the detector under an #ifdef
|
|
for that platform.
|
|
|
|
Additionally, hidapi-libusb has an error that causes
|
|
hid_close() to hang on this device, see:
|
|
https://github.com/libusb/hidapi/issues/456
|
|
This will be fixed on newer versions of hidapi-libusb,
|
|
but until then, OpenRGB will hang/crash if you try to
|
|
rescan devices once a HXQS has been detected during
|
|
program session.
|
|
\*-------------------------------------------------------------------*/
|
|
|
|
#include "RGBController_HyperXMicrophone.h"
|
|
#include <LogManager.h>
|
|
|
|
using namespace std::chrono_literals;
|
|
|
|
RGBController_HyperXMicrophone::RGBController_HyperXMicrophone(HyperXMicrophoneController* controller_ptr)
|
|
{
|
|
controller = controller_ptr;
|
|
|
|
vendor = "HyperX";
|
|
type = DEVICE_TYPE_MICROPHONE;
|
|
description = "HyperX Microphone Device";
|
|
location = controller->GetDeviceLocation();
|
|
serial = controller->GetSerialString();
|
|
|
|
mode Direct;
|
|
Direct.name = "Direct";
|
|
Direct.flags = MODE_FLAG_HAS_PER_LED_COLOR | MODE_FLAG_MANUAL_SAVE;
|
|
Direct.color_mode = MODE_COLORS_PER_LED;
|
|
modes.push_back(Direct);
|
|
|
|
SetupZones();
|
|
|
|
keepalive_thread_run = 1;
|
|
keepalive_thread = new std::thread(&RGBController_HyperXMicrophone::KeepaliveThread, this);
|
|
};
|
|
|
|
RGBController_HyperXMicrophone::~RGBController_HyperXMicrophone()
|
|
{
|
|
keepalive_thread_run = 0;
|
|
keepalive_thread->join();
|
|
delete keepalive_thread;
|
|
|
|
delete controller;
|
|
}
|
|
|
|
void RGBController_HyperXMicrophone::SetupZones()
|
|
{
|
|
led Top;
|
|
Top.name = "Top";
|
|
Top.value = 0;
|
|
|
|
led Bot;
|
|
Bot.name = "Bottom";
|
|
Bot.value = 1;
|
|
|
|
leds.push_back(Top);
|
|
leds.push_back(Bot);
|
|
|
|
zone Mic;
|
|
Mic.name = "Microphone";
|
|
Mic.type = ZONE_TYPE_LINEAR;
|
|
Mic.leds_min = 2;
|
|
Mic.leds_max = 2;
|
|
Mic.leds_count = 2;
|
|
Mic.matrix_map = nullptr;
|
|
|
|
zones.push_back(Mic);
|
|
|
|
SetupColors();
|
|
}
|
|
|
|
void RGBController_HyperXMicrophone::ResizeZone(int /*zone*/, int /*new_size*/)
|
|
{
|
|
/*---------------------------------------------------------*\
|
|
| This device does not support resizing zones |
|
|
\*---------------------------------------------------------*/
|
|
}
|
|
|
|
void RGBController_HyperXMicrophone::DeviceUpdateLEDs()
|
|
{
|
|
last_update_time = std::chrono::steady_clock::now();
|
|
controller->SendDirect(colors);
|
|
}
|
|
void RGBController_HyperXMicrophone::UpdateZoneLEDs(int /*zone*/)
|
|
{
|
|
DeviceUpdateLEDs();
|
|
}
|
|
void RGBController_HyperXMicrophone::UpdateSingleLED(int /*led*/)
|
|
{
|
|
DeviceUpdateLEDs();
|
|
}
|
|
void RGBController_HyperXMicrophone::DeviceUpdateMode()
|
|
{
|
|
DeviceUpdateLEDs();
|
|
}
|
|
|
|
void RGBController_HyperXMicrophone::DeviceSaveMode()
|
|
{
|
|
LOG_DEBUG("[%s] Saving current direct colors to device", name.c_str());
|
|
controller->SaveColors(colors, 1);
|
|
}
|
|
|
|
void RGBController_HyperXMicrophone::KeepaliveThread()
|
|
{
|
|
while(keepalive_thread_run.load())
|
|
{
|
|
if((std::chrono::steady_clock::now() - last_update_time) > std::chrono::milliseconds(50))
|
|
{
|
|
UpdateLEDs();
|
|
}
|
|
std::this_thread::sleep_for(15ms);
|
|
}
|
|
}
|