Compare commits

...
Author SHA1 Message Date
Chris dbdf5eab0b Changed "Set All Devices"
* Changed `Apply Colors` to contextual
* Changed `Set All Devices` to `Apply To All Devices`
* Added a tooltip to `Apply to All`
* Added Black and White quick colour swatches and left them "not flat" to
ensure visibility in Light and Dark mode.

Commit amended to fix display issues on Windows and to group buttons in layout by Adam Honse <[email protected]>
2021-04-23 08:16:44 -05:00
Adam Honse be1fbc27ca Add device type string for virtual device 2021-04-22 16:24:48 -05:00
TheRogueZeta 95f40039eb Correct errant hyphen with underscore and update CI names 2021-04-22 19:44:17 +00:00
TheRogueZeta cd8e455b79 Update CI config to rename artifacts.zip with build info 2021-04-22 00:08:17 -05:00
morg 57db50f642 Fix VisualMap plugin URL in README 2021-04-22 00:11:22 +00:00
TheRogueZeta 9789ac0fde Remove 7z compression on Windows builds 2021-04-21 16:05:48 -07:00
morg c45f864977 Add virtual device type 2021-04-21 21:37:50 +02:00
Gareth Hancock 28af2da1c2 Added support for EVGA 2080Ti FTW3 Ultra 2021-04-21 15:44:44 +00:00
Cheerpipe b32ef76121 Creative Sound BlasterX G6 support
Commits squashed and amended for code style by Adam Honse <[email protected]>
2021-04-21 00:03:46 -05:00
edbgon a300e80f47 AMD Reference 6800 cards custom mode set to static 2021-04-21 04:15:32 +00:00
Boothin e098bb5c41 Added Rival 310 and compatible special editions to detector 2021-04-20 22:25:17 -04:00
Adam Honse f06b0ee952 Use NULL (shared) libusb context 2021-04-20 20:30:58 -05:00
Luca Lovisa 0da484bffc Add support for the Lian Li Uni Hub
Commits squashed and amended for code style by Adam Honse <[email protected]>
2021-04-20 20:30:57 -05:00
Adam Honse bea2ae2fdc Add OpenRGB Visual Map plugin link to README 2021-04-20 12:07:19 -05:00
morg 2a6b457324 Add UnregisterRGBController method to ResourceManager
Commit amended by Adam Honse <[email protected]>
2021-04-20 09:21:24 -05:00
TheRogueZeta 50adf9ab51 Correct SetCustomMode() to use virtual mode. 2021-04-18 21:42:54 +00:00
31 changed files with 2155 additions and 284 deletions
+23 -23
View File
@@ -29,7 +29,7 @@ before_script:
#-----------------------------------------------------------------------#
# Linux (AppImage) 32-bit Build Target #
#-----------------------------------------------------------------------#
build_linux_32:
"Linux 32 AppImage":
<<: *ccache_init
image: i386/ubuntu:bionic
stage: build
@@ -38,6 +38,7 @@ build_linux_32:
- ./scripts/build-appimage.sh
artifacts:
name: "${CI_PROJECT_NAME}_Linux_32_${CI_COMMIT_SHORT_SHA}"
paths:
- OpenRGB-i386.AppImage
- 60-openrgb.rules
@@ -47,7 +48,7 @@ build_linux_32:
#-----------------------------------------------------------------------#
# Linux (AppImage) 64-bit Build Target #
#-----------------------------------------------------------------------#
build_linux_64:
"Linux 64 AppImage":
<<: *ccache_init
image: ubuntu:bionic
stage: build
@@ -56,6 +57,7 @@ build_linux_64:
- ./scripts/build-appimage.sh
artifacts:
name: "${CI_PROJECT_NAME}_Linux_64_${CI_COMMIT_SHORT_SHA}"
paths:
- OpenRGB-x86_64.AppImage
- 60-openrgb.rules
@@ -65,7 +67,7 @@ build_linux_64:
#-----------------------------------------------------------------------#
# Linux (.deb) 32-bit Build Target #
#-----------------------------------------------------------------------#
build_linux_deb32:
"Linux 32 deb":
<<: *ccache_init
image: i386/ubuntu:bionic
stage: build
@@ -77,6 +79,7 @@ build_linux_deb32:
- mv -v ../openrgb*.deb ./
artifacts:
name: "${CI_PROJECT_NAME}_Linux_32_deb_${CI_COMMIT_SHORT_SHA}"
paths:
- openrgb*.deb
exclude:
@@ -86,7 +89,7 @@ build_linux_deb32:
#-----------------------------------------------------------------------#
# Linux (.deb) 64-bit Build Target #
#-----------------------------------------------------------------------#
build_linux_deb64:
"Linux 64 deb":
<<: *ccache_init
image: ubuntu:bionic
stage: build
@@ -98,6 +101,7 @@ build_linux_deb64:
- mv -v ../openrgb*.deb ./
artifacts:
name: "${CI_PROJECT_NAME}_Linux_64_deb_${CI_COMMIT_SHORT_SHA}"
paths:
- openrgb*.deb
exclude:
@@ -107,7 +111,7 @@ build_linux_deb64:
#-----------------------------------------------------------------------#
# Windows (32-bit) Build Target #
#-----------------------------------------------------------------------#
build_windows_32:
"Windows 32":
extends:
- .shared_windows_runners
stage: build
@@ -160,26 +164,23 @@ build_windows_32:
- ..\_qt\5.15.0\msvc2019\bin\windeployqt --no-angle --no-translations --no-opengl-sw --no-system-d3d-compiler --no-compiler-runtime --no-webkit2 .\release\
- _fold_final_
- _fold_start_ 'compressing the release folder so that we can upload it as artifact'
- mv release 'OpenRGB Windows 32-bit'
- ${datetime} = Get-Date ([datetime]::UtcNow) -Format "yyyy-MM-ddTHH-mm-ss"
- ${revision} = ((git rev-parse --short HEAD) | Out-String).Trim()
- ${rversion} = (((Get-Content '..\OpenRGB.pro' | Select-String -Pattern "VERSION =") | Out-String).Trim().Split("="))[1].Trim()
- 7z a -mx9 -r -y "OpenRGB_${rversion}_32_${revision}_nightly_${datetime}.7z" 'OpenRGB Windows 32-bit'
- _fold_start_ 'Moving results for upload'
- mv release ../'OpenRGB Windows 32-bit'
- _fold_final_
# cache:
# key: same-key
# paths:
# - C:\vcpkg\installed\
artifacts:
name: "${CI_PROJECT_NAME}_Windows_32_${CI_COMMIT_SHORT_SHA}"
paths:
- _build/*.7z
- 'OpenRGB Windows 32-bit'
expire_in: 30 days
#-----------------------------------------------------------------------#
# Windows (64-bit) Build Target #
#-----------------------------------------------------------------------#
build_windows_64:
"Windows 64":
extends:
- .shared_windows_runners
stage: build
@@ -232,26 +233,23 @@ build_windows_64:
- ..\_qt\5.15.0\msvc2019_64\bin\windeployqt --no-angle --no-translations --no-opengl-sw --no-system-d3d-compiler --no-compiler-runtime --no-webkit2 .\release\
- _fold_final_
- _fold_start_ 'compressing the release folder so that we can upload it as artifact'
- mv release 'OpenRGB Windows 64-bit'
- ${datetime} = Get-Date ([datetime]::UtcNow) -Format "yyyy-MM-ddTHH-mm-ss"
- ${revision} = ((git rev-parse --short HEAD) | Out-String).Trim()
- ${rversion} = (((Get-Content '..\OpenRGB.pro' | Select-String -Pattern "VERSION =") | Out-String).Trim().Split("="))[1].Trim()
- 7z a -mx9 -r -y "OpenRGB_${rversion}_64_${revision}_nightly_${datetime}.7z" 'OpenRGB Windows 64-bit'
- _fold_start_ 'Moving results for upload'
- mv release ../'OpenRGB Windows 64-bit'
- _fold_final_
# cache:
# key: same-key
# paths:
# - C:\vcpkg\installed\
artifacts:
name: "${CI_PROJECT_NAME}_Windows_64_${CI_COMMIT_SHORT_SHA}"
paths:
- _build/*.7z
- 'OpenRGB Windows 64-bit'
expire_in: 30 days
#-----------------------------------------------------------------------#
# MacOS Build Target #
#-----------------------------------------------------------------------#
build_macos_arm64:
"MacOS ARM64":
tags:
- macos
stage: build
@@ -262,6 +260,7 @@ build_macos_arm64:
- macdeployqt OpenRGB.app -codesign=OpenRGB
artifacts:
name: "${CI_PROJECT_NAME}_MacOS_ARM64_${CI_COMMIT_SHORT_SHA}"
paths:
- OpenRGB.app
expire_in: 30 days
@@ -272,7 +271,7 @@ build_macos_arm64:
- if: '$BUILD_MACOS =~ /.+/'
when: on_success
build_macos_intel:
"MacOS Intel":
tags:
- macos
stage: build
@@ -283,6 +282,7 @@ build_macos_intel:
- arch -x86_64 macdeployqt OpenRGB.app -codesign=OpenRGB
artifacts:
name: "${CI_PROJECT_NAME}_MacOS_Intel_${CI_COMMIT_SHORT_SHA}"
paths:
- OpenRGB.app
expire_in: 30 days
@@ -291,4 +291,4 @@ build_macos_intel:
- if: '$CI_PROJECT_PATH == "CalcProgrammer1/OpenRGB"'
when: on_success
- if: '$BUILD_MACOS =~ /.+/'
when: on_success
when: on_success
+5
View File
@@ -172,6 +172,11 @@ SUBSYSTEMS=="usb", ATTR{idVendor}=="0951", ATTR{idProduct}=="16be", TAG+="uacces
SUBSYSTEMS=="usb", ATTR{idVendor}=="0951", ATTR{idProduct}=="16d3", TAG+="uaccess"
SUBSYSTEMS=="usb", ATTR{idVendor}=="0951", ATTR{idProduct}=="1705", TAG+="uaccess"
#---------------------------------------------------------------#
# Lian Li Uni Hub #
#---------------------------------------------------------------#
SUBSYSTEMS=="usb", ATTR{idVendor}=="0cf2", ATTR{idProduct}=="7750", TAG+="uaccess"
#---------------------------------------------------------------#
# Logitech Peripheral Devices #
# #
@@ -140,7 +140,7 @@ void RGBController_CMR6000Controller::UpdateSingleLED(int /*led*/)
void RGBController_CMR6000Controller::SetCustomMode()
{
active_mode = 1;
}
void RGBController_CMR6000Controller::DeviceUpdateMode()
@@ -47,16 +47,15 @@ static const corsair_hydro_device device_list[] =
void DetectCorsairHydroControllers(std::vector<RGBController*>& rgb_controllers)
{
libusb_context * ctx;
libusb_init(&ctx);
libusb_init(NULL);
#ifdef _WIN32
libusb_set_option(ctx, LIBUSB_OPTION_USE_USBDK);
libusb_set_option(NULL, LIBUSB_OPTION_USE_USBDK);
#endif
for(std::size_t device_idx = 0; device_idx < CORSAIR_NUM_DEVICES; device_idx++)
{
libusb_device_handle * dev = libusb_open_device_with_vid_pid(ctx, device_list[device_idx].usb_vid, device_list[device_idx].usb_pid);
libusb_device_handle * dev = libusb_open_device_with_vid_pid(NULL, device_list[device_idx].usb_vid, device_list[device_idx].usb_pid);
//Look for Corsair RGB Peripheral
if(dev)
@@ -0,0 +1,30 @@
#include "CreativeSoundBlasterXG6Controller.h"
#include "RGBController_CreativeSoundBlasterXG6.h"
#include "Detector.h"
#include <hidapi/hidapi.h>
/*-----------------------------------------------------*\
| Creative vendor ID |
\*-----------------------------------------------------*/
#define CREATIVE_VID 0x041E
/*-----------------------------------------------------*\
| SoundCards |
\*-----------------------------------------------------*/
#define CREATIVE_SOUNDBLASTERX_G6_PID 0x3256
void DetectCreativeDevice(hid_device_info* info, const std::string& name)
{
hid_device* dev = hid_open_path(info->path);
if(dev)
{
CreativeSoundBlasterXG6Controller* controller = new CreativeSoundBlasterXG6Controller(dev, info->path);
RGBController_CreativeSoundBlasterXG6* rgb_controller = new RGBController_CreativeSoundBlasterXG6(controller);
rgb_controller->name = name;
ResourceManager::get()->RegisterRGBController(rgb_controller);
}
}
/*-------------------------------------------------------------------------------------------------------------------------------------------------*\
| Sound Cards |
\*-------------------------------------------------------------------------------------------------------------------------------------------------*/
REGISTER_HID_DETECTOR_I("Creative SoundBlasterX G6", DetectCreativeDevice, CREATIVE_VID, CREATIVE_SOUNDBLASTERX_G6_PID, 4);
@@ -0,0 +1,82 @@
#include "CreativeSoundBlasterXG6Controller.h"
CreativeSoundBlasterXG6Controller::CreativeSoundBlasterXG6Controller(hid_device* dev_handle, const char* path)
{
dev = dev_handle;
location = path;
}
CreativeSoundBlasterXG6Controller::~CreativeSoundBlasterXG6Controller()
{
hid_close(dev);
}
std::string CreativeSoundBlasterXG6Controller::GetDeviceLocation()
{
return("HID " + location);
}
void CreativeSoundBlasterXG6Controller::SetLedColor (unsigned char red, unsigned char green, unsigned char blue)
{
unsigned char usb_buf[64];
/*-----------------------------------------------------*\
| Zero out buffer |
\*-----------------------------------------------------*/
memset(usb_buf, 0x00, sizeof(usb_buf));
//5A 3A 02 06 01 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
usb_buf[0x01] = 0x5A;
usb_buf[0x02] = 0x3A;
usb_buf[0x03] = 0x02;
usb_buf[0x04] = 0x06;
usb_buf[0x05] = 0x01;
/*-----------------------------------------------------*\
| Send packet |
\*-----------------------------------------------------*/
hid_write(dev, (unsigned char *)usb_buf, 64);
/*-----------------------------------------------------*\
| Zero out buffer |
\*-----------------------------------------------------*/
memset(usb_buf, 0x00, sizeof(usb_buf));
//5A 3A 06 04 00 03 01 00 01 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
usb_buf[0x01] = 0x5A;
usb_buf[0x02] = 0x3A;
usb_buf[0x03] = 0x06;
usb_buf[0x04] = 0x04;
usb_buf[0x06] = 0x03;
usb_buf[0x07] = 0x01;
usb_buf[0x09] = 0x01;
/*-----------------------------------------------------*\
| Send packet |
\*-----------------------------------------------------*/
hid_write(dev, (unsigned char *)usb_buf, 64);
/*-----------------------------------------------------*\
| Zero out buffer |
\*-----------------------------------------------------*/
memset(usb_buf, 0x00, sizeof(usb_buf));
//5A 3A 09 0A 00 03 01 01 FF BB GG RR
usb_buf[0x01] = 0x5A;
usb_buf[0x02] = 0x3A;
usb_buf[0x03] = 0x09;
usb_buf[0x04] = 0x0A;
usb_buf[0x06] = 0x03;
usb_buf[0x07] = 0x01;
usb_buf[0x08] = 0x01;
usb_buf[0x09] = 0x0FF;
usb_buf[0x0A] = blue;
usb_buf[0x0B] = green;
usb_buf[0x0C] = red;
/*-----------------------------------------------------*\
| Send packet |
\*-----------------------------------------------------*/
hid_write(dev, (unsigned char *)usb_buf, 64);
}
@@ -0,0 +1,20 @@
#include "RGBController.h"
#include <cstring>
#include <hidapi/hidapi.h>
#pragma once
class CreativeSoundBlasterXG6Controller
{
public:
CreativeSoundBlasterXG6Controller(hid_device* dev_handle, const char* path);
~CreativeSoundBlasterXG6Controller();
void SetLedColor (unsigned char red, unsigned char green, unsigned char blue);
std::string GetDeviceLocation();
std::string GetSerialString();
private:
hid_device* dev;
std::string location;
};
@@ -0,0 +1,81 @@
#include "RGBController_CreativeSoundBlasterXG6.h"
RGBController_CreativeSoundBlasterXG6::RGBController_CreativeSoundBlasterXG6(CreativeSoundBlasterXG6Controller* creative_device)
{
creative = creative_device;
name = "Creative SoundBlasterX G6 Device";
vendor = "Creative";
type = DEVICE_TYPE_HEADSET;
description = "Creative SoundBlasterX G6 Device";
location = creative_device->GetDeviceLocation();
serial = "";
mode Static;
Static.name = "Direct";
Static.value = 0;
Static.flags = MODE_COLORS_PER_LED;
Static.color_mode = MODE_COLORS_PER_LED;
modes.push_back(Static);
SetupZones();
}
RGBController_CreativeSoundBlasterXG6::~RGBController_CreativeSoundBlasterXG6()
{
delete creative;
}
void RGBController_CreativeSoundBlasterXG6::SetupZones()
{
zone logo_zone;
logo_zone.name = "Logo";
logo_zone.type = ZONE_TYPE_SINGLE;
logo_zone.leds_min = 1;
logo_zone.leds_max = 1;
logo_zone.leds_count = 1;
logo_zone.matrix_map = NULL;
zones.push_back(logo_zone);
led logo_led;
logo_led.name = "Logo";
leds.push_back(logo_led);
SetupColors();
}
void RGBController_CreativeSoundBlasterXG6::ResizeZone(int /*zone*/, int /*new_size*/)
{
/*---------------------------------------------------------*\
| This device does not support resizing zones |
\*---------------------------------------------------------*/
}
void RGBController_CreativeSoundBlasterXG6::DeviceUpdateLEDs()
{
unsigned char red = RGBGetRValue(colors[0]);
unsigned char grn = RGBGetGValue(colors[0]);
unsigned char blu = RGBGetBValue(colors[0]);
creative->SetLedColor(red, grn, blu);
}
void RGBController_CreativeSoundBlasterXG6::UpdateZoneLEDs(int /*zone*/)
{
DeviceUpdateLEDs();
}
void RGBController_CreativeSoundBlasterXG6::UpdateSingleLED(int /*led*/)
{
DeviceUpdateLEDs();
}
void RGBController_CreativeSoundBlasterXG6::SetCustomMode()
{
active_mode = 0;
}
void RGBController_CreativeSoundBlasterXG6::DeviceUpdateMode()
{
DeviceUpdateLEDs();
}
@@ -0,0 +1,24 @@
#pragma once
#include "RGBController.h"
#include "CreativeSoundBlasterXG6Controller.h"
class RGBController_CreativeSoundBlasterXG6: public RGBController
{
public:
RGBController_CreativeSoundBlasterXG6(CreativeSoundBlasterXG6Controller* creative_device);
~RGBController_CreativeSoundBlasterXG6();
void SetupZones();
void ResizeZone(int zone, int new_size);
void DeviceUpdateLEDs();
void UpdateZoneLEDs(int zone);
void UpdateSingleLED(int led);
void SetCustomMode();
void DeviceUpdateMode();
private:
CreativeSoundBlasterXG6Controller* creative;
};
@@ -41,6 +41,7 @@ static const gpu_pci_device device_list[] =
{ NVIDIA_VEN, NVIDIA_RTX2080_A_DEV, EVGA_SUB_VEN, EVGA_RTX2080_XC_GAMING_SUB_DEV, EVGA_RGB_V2, "EVGA GeForce RTX 2080 XC Gaming" },
{ NVIDIA_VEN, NVIDIA_RTX2080_A_DEV, EVGA_SUB_VEN, EVGA_RTX2080_XC_ULTRA_GAMING_SUB_DEV, EVGA_RGB_V2, "EVGA GeForce RTX 2080 XC Ultra Gaming" },
{ NVIDIA_VEN, NVIDIA_RTX2080TI_DEV, EVGA_SUB_VEN, EVGA_RTX2080TI_XC_ULTRA_GAMING_SUB_DEV, EVGA_RGB_V2, "EVGA GeForce RTX 2080Ti XC Ultra" },
{ NVIDIA_VEN, NVIDIA_RTX2080TI_DEV, EVGA_SUB_VEN, EVGA_RTX2080TI_FTW3_ULTRA_SUB_DEV , EVGA_RGB_V2, "EVGA GeForce RTX 2080Ti FTW3 Ultra" },
};
@@ -182,7 +182,7 @@ void RGBController_EVGAGPUv2::UpdateSingleLED(int /*led*/)
void RGBController_EVGAGPUv2::SetCustomMode()
{
active_mode = getModeIndex(EVGA_GPU_V2_MODE_DIRECT);
active_mode = getModeIndex(EVGA_GPU_V2_RGB_MODE_DIRECT);
}
void RGBController_EVGAGPUv2::DeviceUpdateMode()
@@ -0,0 +1,75 @@
/*-----------------------------------------*\
| LianLiControllerDetect.cpp |
| |
| Detector for Lian Li Uni Hub USB |
| lighting controller |
| |
| Luca Lovisa 2/20/2021 |
\*-----------------------------------------*/
#include <string>
#include <vector>
#include "Detector.h"
#include "LianLiUniHubController.h"
#include "RGBController_LianLiUniHub.h"
#include "ResourceManager.h"
#include <libusb-1.0/libusb.h>
#define UNI_HUB_VID 0x0CF2
#define UNI_HUB_PID 0x7750
/*----------------------------------------------------------------------------*\
| The Uni Hub is controlled by sending control transfers to various wIndex |
| addresses, allthough it announces some kind of hid interface. Hence it |
| requires libusb as hidapi provides no wIndex customization. |
\*----------------------------------------------------------------------------*/
void DetectLianLiUniHub(std::vector<RGBController*>&)
{
libusb_device** devices = nullptr;
int ret;
ret = libusb_init(NULL);
if(ret < 0)
{
return;
}
ret = libusb_get_device_list(NULL, &devices);
if(ret < 0)
{
return;
}
int deviceCount = ret;
for(int i = 0; i < deviceCount; i++)
{
libusb_device* device = devices[i];
libusb_device_descriptor descriptor;
ret = libusb_get_device_descriptor(device, &descriptor);
if (ret < 0)
{
continue;
}
if( descriptor.idVendor == UNI_HUB_VID
&& descriptor.idProduct == UNI_HUB_PID)
{
LianLiUniHubController* controller = new LianLiUniHubController(device, &descriptor);
RGBController_LianLiUniHub* rgb_controller = new RGBController_LianLiUniHub(controller);
ResourceManager::get()->RegisterRGBController(rgb_controller);
}
}
if(devices != nullptr)
{
libusb_free_device_list(devices, 1);
}
}
REGISTER_DETECTOR("Lian Li Uni Hub", DetectLianLiUniHub);
@@ -0,0 +1,700 @@
/*-----------------------------------------*\
| LianLiUniHubController.cpp |
| |
| Driver for Lian Li Uni Hub USB |
| lighting controller |
| |
| Luca Lovisa 2/20/2021 |
\*-----------------------------------------*/
#include "LianLiUniHubController.h"
#include <cstring>
using namespace std::chrono_literals;
/*----------------------------------------------------------------------------*\
| The Uni Hub is controlled by sending control transfers to various wIndex |
| addresses, allthough it announces some kind of hid interface. Hence it |
| requires libusb as hidapi provides no wIndex customization. |
\*----------------------------------------------------------------------------*/
LianLiUniHubController::LianLiUniHubController
(
libusb_device* device,
libusb_device_descriptor* descriptor
)
{
int ret;
/*--------------------------------------------------------------------*\
| Open the libusb device. |
\*--------------------------------------------------------------------*/
ret = libusb_open(device, &handle);
if(ret < 0)
{
return;
}
/*--------------------------------------------------------------------*\
| Fill in the location string from USB port numbers. |
\*--------------------------------------------------------------------*/
uint8_t ports[7];
ret = libusb_get_port_numbers(device, ports, sizeof(ports));
if(ret > 0)
{
location = "USB: ";
for (int i = 0; i < ret; i ++)
{
location += std::to_string(ports[i]);
location.push_back(':');
}
location.pop_back();
}
/*--------------------------------------------------------------------*\
| Fill in the serial string from the string descriptor |
\*--------------------------------------------------------------------*/
char serialStr[64];
ret = libusb_get_string_descriptor_ascii(handle, descriptor->iSerialNumber, reinterpret_cast<unsigned char*>(serialStr), sizeof(serialStr));
if(ret > 0)
{
serial = std::string(serialStr, ret);
}
/*--------------------------------------------------------------------*\
| Fill in the version string by reading version from device. |
\*--------------------------------------------------------------------*/
version = ReadVersion();
/*--------------------------------------------------------------------*\
| Create channels with their static configuration and "sane" defaults. |
\*--------------------------------------------------------------------*/
Channel channel1;
channel1.index = 0;
channel1.anyFanCountOffset = UNIHUB_ANY_C1_FAN_COUNT_OFFSET;
channel1.anyFanCount = UNIHUB_ANY_FAN_COUNT_001;
channel1.ledActionAddress = UNIHUB_LED_C1_ACTION_ADDRESS;
channel1.ledCommitAddress = UNIHUB_LED_C1_COMMIT_ADDRESS;
channel1.ledModeAddress = UNIHUB_LED_C1_MODE_ADDRESS;
channel1.ledSpeedAddress = UNIHUB_LED_C1_SPEED_ADDRESS;
channel1.ledDirectionAddress = UNIHUB_LED_C1_DIRECTION_ADDRESS;
channel1.ledBrightnessAddress = UNIHUB_LED_C1_BRIGHTNESS_ADDRESS;
channel1.ledMode = UNIHUB_LED_MODE_RAINBOW;
channel1.ledSpeed = UNIHUB_LED_SPEED_100;
channel1.ledDirection = UNIHUB_LED_DIRECTION_LTR;
channel1.ledBrightness = UNIHUB_LED_BRIGHTNESS_100;
channel1.fanHubActionAddress = UNIHUB_FAN_C1_HUB_ACTION_ADDRESS;
channel1.fanHubCommitAddress = UNIHUB_FAN_C1_HUB_COMMIT_ADDRESS;
channel1.fanPwmActionAddress = UNIHUB_FAN_C1_PWM_ACTION_ADDRESS;
channel1.fanPwmCommitAddress = UNIHUB_FAN_C1_PWM_COMMIT_ADDRESS;
channel1.fanRpmActionAddress = UNIHUB_FAN_C1_RPM_ACTION_ADDRESS;
channel1.fanSpeed = UNIHUB_FAN_SPEED_QUIET;
channels[0] = channel1;
Channel channel2;
channel2.index = 1;
channel2.anyFanCountOffset = UNIHUB_ANY_C2_FAN_COUNT_OFFSET;
channel2.anyFanCount = UNIHUB_ANY_FAN_COUNT_001;
channel2.ledActionAddress = UNIHUB_LED_C2_ACTION_ADDRESS;
channel2.ledCommitAddress = UNIHUB_LED_C2_COMMIT_ADDRESS;
channel2.ledModeAddress = UNIHUB_LED_C2_MODE_ADDRESS;
channel2.ledSpeedAddress = UNIHUB_LED_C2_SPEED_ADDRESS;
channel2.ledDirectionAddress = UNIHUB_LED_C2_DIRECTION_ADDRESS;
channel2.ledBrightnessAddress = UNIHUB_LED_C2_BRIGHTNESS_ADDRESS;
channel2.ledMode = UNIHUB_LED_MODE_RAINBOW;
channel2.ledSpeed = UNIHUB_LED_SPEED_100;
channel2.ledDirection = UNIHUB_LED_DIRECTION_LTR;
channel2.ledBrightness = UNIHUB_LED_BRIGHTNESS_100;
channel2.fanHubActionAddress = UNIHUB_FAN_C2_HUB_ACTION_ADDRESS;
channel2.fanHubCommitAddress = UNIHUB_FAN_C2_HUB_COMMIT_ADDRESS;
channel2.fanPwmActionAddress = UNIHUB_FAN_C2_PWM_ACTION_ADDRESS;
channel2.fanPwmCommitAddress = UNIHUB_FAN_C2_PWM_COMMIT_ADDRESS;
channel2.fanRpmActionAddress = UNIHUB_FAN_C2_RPM_ACTION_ADDRESS;
channel2.fanSpeed = UNIHUB_FAN_SPEED_QUIET;
channels[1] = channel2;
Channel channel3;
channel3.index = 2;
channel3.anyFanCountOffset = UNIHUB_ANY_C3_FAN_COUNT_OFFSET;
channel3.anyFanCount = UNIHUB_ANY_FAN_COUNT_001;
channel3.ledActionAddress = UNIHUB_LED_C3_ACTION_ADDRESS;
channel3.ledCommitAddress = UNIHUB_LED_C3_COMMIT_ADDRESS;
channel3.ledModeAddress = UNIHUB_LED_C3_MODE_ADDRESS;
channel3.ledSpeedAddress = UNIHUB_LED_C3_SPEED_ADDRESS;
channel3.ledDirectionAddress = UNIHUB_LED_C3_DIRECTION_ADDRESS;
channel3.ledBrightnessAddress = UNIHUB_LED_C3_BRIGHTNESS_ADDRESS;
channel3.ledMode = UNIHUB_LED_MODE_RAINBOW;
channel3.ledSpeed = UNIHUB_LED_SPEED_100;
channel3.ledDirection = UNIHUB_LED_DIRECTION_LTR;
channel3.ledBrightness = UNIHUB_LED_BRIGHTNESS_100;
channel3.fanHubActionAddress = UNIHUB_FAN_C3_HUB_ACTION_ADDRESS;
channel3.fanHubCommitAddress = UNIHUB_FAN_C3_HUB_COMMIT_ADDRESS;
channel3.fanPwmActionAddress = UNIHUB_FAN_C3_PWM_ACTION_ADDRESS;
channel3.fanPwmCommitAddress = UNIHUB_FAN_C3_PWM_COMMIT_ADDRESS;
channel3.fanRpmActionAddress = UNIHUB_FAN_C3_RPM_ACTION_ADDRESS;
channel3.fanSpeed = UNIHUB_FAN_SPEED_QUIET;
channels[2] = channel3;
Channel channel4;
channel4.index = 3;
channel4.anyFanCountOffset = UNIHUB_ANY_C4_FAN_COUNT_OFFSET;
channel4.anyFanCount = UNIHUB_ANY_FAN_COUNT_001;
channel4.ledActionAddress = UNIHUB_LED_C4_ACTION_ADDRESS;
channel4.ledCommitAddress = UNIHUB_LED_C4_COMMIT_ADDRESS;
channel4.ledModeAddress = UNIHUB_LED_C4_MODE_ADDRESS;
channel4.ledSpeedAddress = UNIHUB_LED_C4_SPEED_ADDRESS;
channel4.ledDirectionAddress = UNIHUB_LED_C4_DIRECTION_ADDRESS;
channel4.ledBrightnessAddress = UNIHUB_LED_C4_BRIGHTNESS_ADDRESS;
channel4.ledMode = UNIHUB_LED_MODE_RAINBOW;
channel4.ledSpeed = UNIHUB_LED_SPEED_100;
channel4.ledDirection = UNIHUB_LED_DIRECTION_LTR;
channel4.ledBrightness = UNIHUB_LED_BRIGHTNESS_100;
channel4.fanHubActionAddress = UNIHUB_FAN_C4_HUB_ACTION_ADDRESS;
channel4.fanHubCommitAddress = UNIHUB_FAN_C4_HUB_COMMIT_ADDRESS;
channel4.fanPwmActionAddress = UNIHUB_FAN_C4_PWM_ACTION_ADDRESS;
channel4.fanPwmCommitAddress = UNIHUB_FAN_C4_PWM_COMMIT_ADDRESS;
channel4.fanRpmActionAddress = UNIHUB_FAN_C4_RPM_ACTION_ADDRESS;
channel4.fanSpeed = UNIHUB_FAN_SPEED_QUIET;
channels[3] = channel4;
}
LianLiUniHubController::~LianLiUniHubController()
{
CloseLibusb();
}
std::string LianLiUniHubController::GetVersion()
{
return version;
}
std::string LianLiUniHubController::GetLocation()
{
return location;
}
std::string LianLiUniHubController::GetSerial()
{
return serial;
}
void LianLiUniHubController::SetAnyFanCount(size_t channel, uint8_t count)
{
/*-------------------------------------*\
| Check for invalid channel |
\*-------------------------------------*/
if(channel >= UNIHUB_CHANNEL_COUNT)
{
return;
}
channels[channel].anyFanCount = count;
}
void LianLiUniHubController::SetLedColors(size_t channel, RGBColor* colors, size_t count)
{
/*-------------------------------------*\
| Check for invalid channel |
\*-------------------------------------*/
if(channel >= UNIHUB_CHANNEL_COUNT)
{
return;
}
/*-------------------------------------*\
| Check for invalid count |
\*-------------------------------------*/
if(count > UNIHUB_CHANLED_COUNT)
{
count = UNIHUB_CHANLED_COUNT;
}
size_t i = 0;
for(; i < count; i++)
{
channels[channel].colors[i].r = RGBGetRValue(colors[i]);
channels[channel].colors[i].b = RGBGetBValue(colors[i]);
channels[channel].colors[i].g = RGBGetGValue(colors[i]);
}
/* Set all remaining leds to black */
for(; i < UNIHUB_CHANLED_COUNT; i++)
{
channels[channel].colors[i].r = 0x00;
channels[channel].colors[i].b = 0x00;
channels[channel].colors[i].g = 0x00;
}
}
void LianLiUniHubController::SetLedMode(size_t channel, uint8_t mode)
{
/*-------------------------------------*\
| Check for invalid channel |
\*-------------------------------------*/
if(channel >= UNIHUB_CHANNEL_COUNT)
{
return;
}
channels[channel].ledMode = mode;
}
void LianLiUniHubController::SetLedSpeed(size_t channel, uint8_t speed)
{
/*-------------------------------------*\
| Check for invalid channel |
\*-------------------------------------*/
if(channel >= UNIHUB_CHANNEL_COUNT)
{
return;
}
channels[channel].ledSpeed = speed;
}
void LianLiUniHubController::SetLedDirection(size_t channel, uint8_t direction)
{
/*-------------------------------------*\
| Check for invalid channel |
\*-------------------------------------*/
if(channel >= UNIHUB_CHANNEL_COUNT)
{
return;
}
channels[channel].ledDirection = direction;
}
void LianLiUniHubController::SetLedBrightness(size_t channel, uint8_t brightness)
{
/*-------------------------------------*\
| Check for invalid channel |
\*-------------------------------------*/
if(channel >= UNIHUB_CHANNEL_COUNT)
{
return;
}
channels[channel].ledBrightness = brightness;
}
uint16_t LianLiUniHubController::GetFanSpeed(size_t channel)
{
/*-------------------------------------*\
| Check for invalid channel |
\*-------------------------------------*/
if(channel >= UNIHUB_CHANNEL_COUNT)
{
return 0;
}
return channels[channel].fanSpeed;
}
void LianLiUniHubController::SetFanSpeed(size_t channel, uint16_t speed)
{
/*-------------------------------------*\
| Check for invalid channel |
\*-------------------------------------*/
if(channel >= UNIHUB_CHANNEL_COUNT)
{
return;
}
channels[channel].fanSpeed = speed;
}
void LianLiUniHubController::EnableRgbhMode()
{
rgbhModeEnabled = true;
}
void LianLiUniHubController::DisableRgbhMode()
{
rgbhModeEnabled = false;
}
void LianLiUniHubController::EnableSyncMode()
{
syncModeEnabled = true;
}
void LianLiUniHubController::DisableSyncMode()
{
syncModeEnabled = false;
}
/*----------------------------------------------------------------------------*\
| The Uni Hub is a PWM and LED controller designed specifically for the Lian |
| Li Uni Fans. It can control them by itself using the built-in effect engine |
| can also be connected to the mainboard via 4-pin PWM and 3-pin RGB cables |
| and forward these signals. The protocol implementation below was build as |
| close a possible to the Lian Li L-Connect software. |
| |
| The commands to control the fan speeds and to switch between controller and |
| mainboard control is already included, but currently deactivated as OpenRGB |
| had no fan control module or controller specific configuration at the time |
| of writing. |
\*----------------------------------------------------------------------------*/
void LianLiUniHubController::Synchronize()
{
/*---------------------------------------------------------------------*\
| Configure common settings. |
\*---------------------------------------------------------------------*/
/*---------------------------------------------------------------------*\
| Still unsure about this. Probably some sort of configuration |
| initialization |
\*---------------------------------------------------------------------*/
uint8_t config_initialization[1] = { 0x34 };
SendConfig(UNIHUB_ACTION_ADDRESS, config_initialization, sizeof(config_initialization));
SendCommit(UNIHUB_COMMIT_ADDRESS);
for(const Channel& channel : channels)
{
/*-------------------------------------*\
| The Uni Hub doesn't know zero fans |
\*-------------------------------------*/
uint8_t anyFanCount = channel.anyFanCount;
if(anyFanCount == UNIHUB_ANY_FAN_COUNT_000)
{
anyFanCount = UNIHUB_ANY_FAN_COUNT_001;
}
/*-------------------------------------*\
| Configure the physical fan count |
\*-------------------------------------*/
uint8_t config_fan_count[2] = { 0x32, (uint8_t)(channel.anyFanCountOffset | anyFanCount) };
SendConfig(UNIHUB_ACTION_ADDRESS, config_fan_count, sizeof(config_fan_count));
SendCommit(UNIHUB_COMMIT_ADDRESS);
}
/*--------------------------------------------------------------------*\
| Configure channels for sync effects |
\*--------------------------------------------------------------------*/
if(syncModeEnabled)
{
uint8_t config_sync[6];
uint8_t config_sync_index = 0;
config_sync[config_sync_index++] = 0x33;
for(const Channel& channel : channels)
{
if(channel.anyFanCount != UNIHUB_ANY_FAN_COUNT_000)
{
config_sync[config_sync_index++] = channel.index;
}
}
config_sync[config_sync_index++] = 0x08;
SendConfig(UNIHUB_ACTION_ADDRESS, config_sync, config_sync_index);
SendCommit(UNIHUB_COMMIT_ADDRESS);
}
/*--------------------------------------------------------------------*\
| Configure led settings. |
\*--------------------------------------------------------------------*/
for(const Channel& channel : channels)
{
if(channel.anyFanCount != UNIHUB_ANY_FAN_COUNT_000)
{
/*-----------------------------*\
| Configure led colors |
\*-----------------------------*/
uint8_t config_colors[192];
memcpy(config_colors, channel.colors, sizeof(config_colors));
/*-----------------------------*\
| No idea what this does ... |
\*-----------------------------*/
if (syncModeEnabled)
{
config_colors[0x06] = 0x66;
config_colors[0x07] = 0x33;
config_colors[0x08] = 0xCC;
memset(config_colors + 0x09, 0x00, sizeof(config_colors) - 0x09);
}
SendConfig(channel.ledActionAddress, config_colors, sizeof(config_colors));
/*-----------------------------*\
| Configure led mode |
\*-----------------------------*/
uint8_t config_mode[1] = { channel.ledMode };
SendConfig(channel.ledModeAddress, config_mode, sizeof(config_mode));
}
/*-----------------------------------------------------------------*\
| The Uni Hub doesn't know zero fans so we set them to black |
\*-----------------------------------------------------------------*/
else
{
/*-----------------------------*\
| Configure led colors |
\*-----------------------------*/
uint8_t config_colors[192];
memset(config_colors, 0x00, sizeof(config_colors));
SendConfig(channel.ledActionAddress, config_colors, sizeof(config_colors));
/*-----------------------------*\
| Configure led mode |
\*-----------------------------*/
uint8_t config_mode[1] = { UNIHUB_LED_MODE_STATIC_COLOR };
SendConfig(channel.ledModeAddress, config_mode, sizeof(config_mode));
}
/*---------------------------------*\
| Configure led speed |
\*---------------------------------*/
uint8_t config_speed[1] = { channel.ledSpeed };
SendConfig(channel.ledSpeedAddress, config_speed, sizeof(config_speed));
/*---------------------------------*\
| Configure led direction |
\*---------------------------------*/
uint8_t config_direction[1] = { channel.ledDirection };
SendConfig(channel.ledDirectionAddress, config_direction, sizeof(config_direction));
/*---------------------------------*\
| Configure led brightness |
\*---------------------------------*/
uint8_t config_brightness[1] = { channel.ledBrightness };
SendConfig(channel.ledBrightnessAddress, config_brightness, sizeof(config_brightness));
/*---------------------------------*\
| Commit only once for all led |
| settings |
\*---------------------------------*/
SendCommit(channel.ledCommitAddress);
}
/*--------------------------------------------------------------------*\
| Configure fan settings. Comment out until enabling fan control |
\*--------------------------------------------------------------------*/
// uint8_t control = 0;
// /*-------------------------------------*\
// | Configure fan settings |
// \*-------------------------------------*/
// for(const Channel& channel : channels)
// {
// if(channel.fanSpeed == UNIHUB_FAN_SPEED_PWM)
// {
// /*-----------------------------*\
// | Configure the fan to pwm |
// | control |
// \*-----------------------------*/
// uint8_t config_pwm[1] = { 0x00 };
// control |= (0x01 << channel.index);
// SendConfig(channel.fanPwmActionAddress, config_pwm, sizeof(config_pwm));
// SendCommit(channel.fanPwmCommitAddress);
// }
// else
// {
// /*-----------------------------*\
// | Configure the fan to hub |
// | control and set speed |
// \*-----------------------------*/
// uint8_t config_hub[2] = { (uint8_t)(channel.fanSpeed >> 0x08), (uint8_t)(channel.fanSpeed & 0xFF) };
// SendConfig(channel.fanHubActionAddress, config_hub, sizeof(config_hub));
// SendCommit(channel.fanHubCommitAddress);
// }
// }
// /*-------------------------------------*\
// | Configure fan control modes |
// \*-------------------------------------*/
// uint8_t config_fan_mode[2] = { 0x31, (uint8_t)(0xF0 | control) };
// SendConfig(UNIHUB_ACTION_ADDRESS, config_fan_mode, sizeof(config_fan_mode));
// SendCommit(UNIHUB_COMMIT_ADDRESS);
/*--------------------------------------------------------------------*\
| Configure led settings. |
\*--------------------------------------------------------------------*/
if(rgbhModeEnabled)
{
/*-------------------------------------*\
| Configure the leds to hdr control. |
\*-------------------------------------*/
uint8_t config_hdr[2] = { 0x30, 0x01 };
SendConfig(UNIHUB_ACTION_ADDRESS, config_hdr, sizeof(config_hdr));
SendCommit(UNIHUB_COMMIT_ADDRESS);
}
else
{
/*-------------------------------------*\
| Configure the leds to hub control |
\*-------------------------------------*/
uint8_t config_hub[2] = { 0x30, 0x00 };
SendConfig(UNIHUB_ACTION_ADDRESS, config_hub, sizeof(config_hub));
SendCommit(UNIHUB_COMMIT_ADDRESS);
}
}
uint16_t LianLiUniHubController::ReadFanSpeed(size_t channel)
{
/*-------------------------------------*\
| Check for invalid handle |
\*-------------------------------------*/
if(handle == nullptr)
{
return(0);
}
/*-------------------------------------*\
| Check for invalid channel |
\*-------------------------------------*/
if(channel > UNIHUB_CHANNEL_COUNT)
{
return(0);
}
uint8_t buffer[2];
uint8_t length = sizeof(buffer);
uint16_t wIndex = channels[channel].fanRpmActionAddress;
/*-------------------------------------*\
| Send packet |
\*-------------------------------------*/
size_t ret = libusb_control_transfer(handle, /* dev_handle */
0xC0, /* bmRequestType */
0x81, /* bRequest */
0x00, /* wValue */
wIndex, /* wIndex */
buffer, /* data */
length, /* wLength */
1000); /* timeout */
/*-------------------------------------*\
| Check for communication error |
\*-------------------------------------*/
if(ret != length)
{
return(0);
}
return(*(uint16_t*)buffer);
}
void LianLiUniHubController::CloseLibusb()
{
if (handle != nullptr)
{
libusb_close(handle);
handle = nullptr;
}
}
std::string LianLiUniHubController::ReadVersion()
{
/*-------------------------------------*\
| Check for invalid handle |
\*-------------------------------------*/
if(handle == nullptr)
{
return("");
}
uint8_t buffer[5];
uint8_t length = sizeof(buffer);
/*-------------------------------------*\
| Send packet |
\*-------------------------------------*/
size_t ret = libusb_control_transfer(handle, /* dev_handle */
0xC0, /* bmRequestType */
0x81, /* bRequest */
0x00, /* wValue */
0xB500, /* wIndex */
buffer, /* data */
length, /* wLength */
1000); /* timeout */
/*-------------------------------------*\
| Check for communication error |
\*-------------------------------------*/
if(ret != length)
{
return("");
}
/*-------------------------------------*\
| Format version string |
\*-------------------------------------*/
char version[14];
int vlength = std::snprintf(version, sizeof(version), "%x.%x.%x.%x.%x", buffer[0], buffer[1], buffer[2], buffer[3], buffer[4]);
return(std::string(version, vlength));
}
void LianLiUniHubController::SendConfig(uint16_t wIndex, uint8_t *config, size_t length)
{
/*-------------------------------------*\
| Check for invalid handle |
\*-------------------------------------*/
if(handle == nullptr)
{
return;
}
/*-------------------------------------*\
| Send packet |
\*-------------------------------------*/
size_t ret = libusb_control_transfer(handle, /* dev_handle */
0x40, /* bmRequestType */
0x80, /* bRequest */
0x00, /* wValue */
wIndex, /* wIndex */
config, /* data */
length, /* wLength */
1000); /* timeout */
/*-------------------------------------*\
| Check for communication error |
\*-------------------------------------*/
if(ret != length)
{
return;
}
}
void LianLiUniHubController::SendCommit(uint16_t wIndex)
{
/*-------------------------------------*\
| Set up config packet |
\*-------------------------------------*/
uint8_t config[1] = { 0x01 };
/*-------------------------------------*\
| Send packet |
\*-------------------------------------*/
SendConfig(wIndex, config, sizeof(config));
std::this_thread::sleep_for(5ms);
}
@@ -0,0 +1,263 @@
/*-----------------------------------------*\
| LianLiUniHubController.h |
| |
| Definitions and types for Lian Li Uni |
| Hub USB RGB lighting controller |
| |
| Luca Lovisa 2/20/2021 |
\*-----------------------------------------*/
#pragma once
#include <cstdint>
#include <mutex>
#include <string>
#include "RGBController.h"
#include <libusb-1.0/libusb.h>
/*----------------------------------------------------------------------------*\
| Global definitions. |
\*----------------------------------------------------------------------------*/
enum
{
UNIHUB_CHANNEL_COUNT = 0x04, /* Channel count */
UNIHUB_CHANLED_COUNT = 0x40, /* Max-LED per channel count */
};
enum
{
UNIHUB_ACTION_ADDRESS = 0xe021, /* Global action address */
UNIHUB_COMMIT_ADDRESS = 0xe02f, /* Global commit address */
};
enum
{
UNIHUB_ANY_C1_FAN_COUNT_OFFSET = 0x00, /* Channel 1 fan count offset */
UNIHUB_ANY_C2_FAN_COUNT_OFFSET = 0x10, /* Channel 2 fan count offset */
UNIHUB_ANY_C3_FAN_COUNT_OFFSET = 0x20, /* Channel 3 fan count offset */
UNIHUB_ANY_C4_FAN_COUNT_OFFSET = 0x30, /* Channel 4 fan count offset */
};
enum
{
UNIHUB_ANY_FAN_COUNT_000 = 0xFF, /* Fan count for 0 fans (dummy value) */
UNIHUB_ANY_FAN_COUNT_001 = 0x00, /* Fan count for 1 fan */
UNIHUB_ANY_FAN_COUNT_002 = 0x01, /* Fan count for 2 fans */
UNIHUB_ANY_FAN_COUNT_003 = 0x02, /* Fan count for 3 fans */
UNIHUB_ANY_FAN_COUNT_004 = 0x03, /* Fan count for 4 fans */
};
/*----------------------------------------------------------------------------*\
| Definitions related to led configuration. |
\*----------------------------------------------------------------------------*/
enum
{
UNIHUB_LED_C1_ACTION_ADDRESS = 0xe300, /* Channel 1 led action address */
UNIHUB_LED_C1_COMMIT_ADDRESS = 0xe02f, /* Channel 1 led commit address */
UNIHUB_LED_C1_MODE_ADDRESS = 0xe021, /* Channel 1 led mode address */
UNIHUB_LED_C1_SPEED_ADDRESS = 0xe022, /* Channel 1 led speed address */
UNIHUB_LED_C1_DIRECTION_ADDRESS = 0xe023, /* Channel 1 led direction address */
UNIHUB_LED_C1_BRIGHTNESS_ADDRESS = 0xe029, /* Channel 1 led brightness address */
UNIHUB_LED_C2_ACTION_ADDRESS = 0xe3c0, /* Channel 2 led action address */
UNIHUB_LED_C2_COMMIT_ADDRESS = 0xe03f, /* Channel 2 led commit address */
UNIHUB_LED_C2_MODE_ADDRESS = 0xe031, /* Channel 2 led mode address */
UNIHUB_LED_C2_SPEED_ADDRESS = 0xe032, /* Channel 2 led speed address */
UNIHUB_LED_C2_DIRECTION_ADDRESS = 0xe033, /* Channel 2 led direction address */
UNIHUB_LED_C2_BRIGHTNESS_ADDRESS = 0xe039, /* Channel 2 led brightness address */
UNIHUB_LED_C3_ACTION_ADDRESS = 0xe480, /* Channel 3 led action address */
UNIHUB_LED_C3_COMMIT_ADDRESS = 0xe04f, /* Channel 3 led commit address */
UNIHUB_LED_C3_MODE_ADDRESS = 0xe041, /* Channel 3 led mode address */
UNIHUB_LED_C3_SPEED_ADDRESS = 0xe042, /* Channel 3 led speed address */
UNIHUB_LED_C3_DIRECTION_ADDRESS = 0xe043, /* Channel 3 led direction address */
UNIHUB_LED_C3_BRIGHTNESS_ADDRESS = 0xe049, /* Channel 3 led brightness address */
UNIHUB_LED_C4_ACTION_ADDRESS = 0xe540, /* Channel 4 led action address */
UNIHUB_LED_C4_COMMIT_ADDRESS = 0xe05f, /* Channel 4 led commit address */
UNIHUB_LED_C4_MODE_ADDRESS = 0xe051, /* Channel 4 led mode address */
UNIHUB_LED_C4_SPEED_ADDRESS = 0xe052, /* Channel 4 led speed address */
UNIHUB_LED_C4_DIRECTION_ADDRESS = 0xe053, /* Channel 4 led direction address */
UNIHUB_LED_C4_BRIGHTNESS_ADDRESS = 0xe059, /* Channel 4 led brightness address */
};
enum
{
UNIHUB_LED_MODE_RAINBOW = 0x05, /* Rainbow mode */
UNIHUB_LED_MODE_STATIC_COLOR = 0x01, /* Static Color mode */
UNIHUB_LED_MODE_BREATHING = 0x02, /* Breathing mode */
UNIHUB_LED_MODE_COLOR_CYCLE = 0x04, /* Color Cycle mode */
UNIHUB_LED_MODE_RUNWAY = 0x1c, /* Runway mode */
UNIHUB_LED_MODE_RUNWAY_SYNC = 0x1c, /* Runway Sync mode */
UNIHUB_LED_MODE_STAGGGERED = 0x18, /* Stagggered mode */
UNIHUB_LED_MODE_MIXING = 0x1a, /* Mixing mode */
UNIHUB_LED_MODE_METEOR = 0x07, /* Meteor mode */
UNIHUB_LED_MODE_METEOR_SYNC = 0x07, /* Meteor Sync mode */
UNIHUB_LED_MODE_FIREWORK = 0x1f, /* Firework mode */
UNIHUB_LED_MODE_STACK = 0x21, /* Stack mode */
UNIHUB_LED_MODE_STACK_MULTI_COLOR = 0x22, /* Stack Multi Color mode */
UNIHUB_LED_MODE_NEON = 0x23, /* Neon mode */
};
enum
{
UNIHUB_LED_SPEED_000 = 0x04, /* Very slow speed */
UNIHUB_LED_SPEED_025 = 0x03, /* Rather slow speed */
UNIHUB_LED_SPEED_050 = 0x02, /* Medium speed */
UNIHUB_LED_SPEED_075 = 0x01, /* Rather fast speed */
UNIHUB_LED_SPEED_100 = 0x00, /* Very fast speed */
};
enum
{
UNIHUB_LED_DIRECTION_LTR = 0x00, /* Left-to-Right direction */
UNIHUB_LED_DIRECTION_RTL = 0x01, /* Right-to-Left direction */
};
enum
{
UNIHUB_LED_BRIGHTNESS_000 = 0x08, /* Very dark (off) */
UNIHUB_LED_BRIGHTNESS_025 = 0x03, /* Rather dark */
UNIHUB_LED_BRIGHTNESS_050 = 0x02, /* Medium bright */
UNIHUB_LED_BRIGHTNESS_075 = 0x01, /* Rather bright */
UNIHUB_LED_BRIGHTNESS_100 = 0x00, /* Very bright */
};
/*----------------------------------------------------------------------------*\
| Definitions related to fan configuration. |
\*----------------------------------------------------------------------------*/
enum
{
UNIHUB_FAN_C1_HUB_ACTION_ADDRESS = 0xe8a0, /* Channel 1 fan action address for hub control */
UNIHUB_FAN_C1_HUB_COMMIT_ADDRESS = 0xe890, /* Channel 1 fan commit address for hub control */
UNIHUB_FAN_C1_PWM_ACTION_ADDRESS = 0xe890, /* Channel 1 fan action address for pwm control */
UNIHUB_FAN_C1_PWM_COMMIT_ADDRESS = 0xe818, /* Channel 1 fan commit address for pwm control */
UNIHUB_FAN_C1_RPM_ACTION_ADDRESS = 0xe800, /* Channel 1 fan pwm read address */
UNIHUB_FAN_C2_HUB_ACTION_ADDRESS = 0xe8a2, /* Channel 2 fan action address for hub control */
UNIHUB_FAN_C2_HUB_COMMIT_ADDRESS = 0xe891, /* Channel 2 fan commit address for hub control */
UNIHUB_FAN_C2_PWM_ACTION_ADDRESS = 0xe891, /* Channel 2 fan action address for pwm control */
UNIHUB_FAN_C2_PWM_COMMIT_ADDRESS = 0xe81a, /* Channel 2 fan commit address for pwm control */
UNIHUB_FAN_C2_RPM_ACTION_ADDRESS = 0xe802, /* Channel 1 fan pwm read address */
UNIHUB_FAN_C3_HUB_ACTION_ADDRESS = 0xe8a4, /* Channel 3 fan action address for hub control */
UNIHUB_FAN_C3_HUB_COMMIT_ADDRESS = 0xe892, /* Channel 3 fan commit address for hub control */
UNIHUB_FAN_C3_PWM_ACTION_ADDRESS = 0xe892, /* Channel 3 fan action address for pwm control */
UNIHUB_FAN_C3_PWM_COMMIT_ADDRESS = 0xe81c, /* Channel 3 fan commit address for pwm control */
UNIHUB_FAN_C3_RPM_ACTION_ADDRESS = 0xe804, /* Channel 1 fan pwm read address */
UNIHUB_FAN_C4_HUB_ACTION_ADDRESS = 0xe8a6, /* Channel 4 fan action address for hub control */
UNIHUB_FAN_C4_HUB_COMMIT_ADDRESS = 0xe893, /* Channel 4 fan commit address for hub control */
UNIHUB_FAN_C4_PWM_ACTION_ADDRESS = 0xe893, /* Channel 4 fan action address for pwm control */
UNIHUB_FAN_C4_PWM_COMMIT_ADDRESS = 0xe81e, /* Channel 4 fan commit address for pwm control */
UNIHUB_FAN_C4_RPM_ACTION_ADDRESS = 0xe806, /* Channel 1 fan pwm read address */
};
enum
{
UNIHUB_FAN_SPEED_QUIET = 0x2003, /* Rather slow */
UNIHUB_FAN_SPEED_HIGH_SPEED = 0x2206, /* Rather fast */
UNIHUB_FAN_SPEED_FULL_SPEED = 0x6c07, /* BRRRRRRRRRR */
UNIHUB_FAN_SPEED_PWM = 0xffff, /* PWM Control */
};
/*----------------------------------------------------------------------------*\
| Uni Hub controller. |
\*----------------------------------------------------------------------------*/
class LianLiUniHubController
{
private:
/* The Uni Hub requires colors in RBG order */
struct Color
{
uint8_t r;
uint8_t b;
uint8_t g;
};
/* The values correspond to the definitions above */
struct Channel
{
uint8_t index;
uint8_t anyFanCountOffset;
uint8_t anyFanCount;
uint16_t ledActionAddress;
uint16_t ledCommitAddress;
uint16_t ledModeAddress;
uint16_t ledSpeedAddress;
uint16_t ledDirectionAddress;
uint16_t ledBrightnessAddress;
Color colors[UNIHUB_CHANLED_COUNT];
uint8_t ledMode;
uint8_t ledSpeed;
uint8_t ledDirection;
uint8_t ledBrightness;
uint16_t fanHubActionAddress;
uint16_t fanHubCommitAddress;
uint16_t fanPwmActionAddress;
uint16_t fanPwmCommitAddress;
uint16_t fanRpmActionAddress;
uint16_t fanSpeed;
};
public:
LianLiUniHubController
(
libusb_device* device,
libusb_device_descriptor* descriptor
);
~LianLiUniHubController();
std::string GetVersion();
std::string GetLocation();
std::string GetSerial();
void SetAnyFanCount(size_t channel, uint8_t count);
void SetLedColors(size_t channel, RGBColor* colors, size_t count);
void SetLedMode(size_t channel, uint8_t mode);
void SetLedSpeed(size_t channel, uint8_t speed);
void SetLedDirection(size_t channel, uint8_t direction);
void SetLedBrightness(size_t channel, uint8_t brightness);
uint16_t GetFanSpeed(size_t channel);
void SetFanSpeed(size_t channel, uint16_t speed);
void EnableRgbhMode();
void DisableRgbhMode();
void EnableSyncMode();
void DisableSyncMode();
uint16_t ReadFanSpeed(size_t channel);
/*-----------------------------------------------------*\
| Synchronize the current configuration to the Uni Hub. |
\*-----------------------------------------------------*/
void Synchronize();
private:
libusb_device_handle* handle = nullptr;
std::string version;
std::string location;
std::string serial;
bool rgbhModeEnabled = false;
bool syncModeEnabled = false;
Channel channels[UNIHUB_CHANNEL_COUNT];
void CloseLibusb();
std::string ReadVersion();
void SendConfig(uint16_t wIndex, uint8_t *config, size_t length);
void SendCommit(uint16_t wIndex);
};
@@ -0,0 +1,475 @@
/*-----------------------------------------*\
| RGBController_LianLiUniHub.cpp |
| |
| Generic RGB Interface for Lian Li Uni |
| Hub USB controller driver |
| |
| Luca Lovisa 2/20/2021 |
\*-----------------------------------------*/
#include "RGBController_LianLiUniHub.h"
#include <string>
mode makeMode()
{
mode Mode;
Mode.value = 0;
Mode.flags = 0;
Mode.speed_min = 0;
Mode.speed_max = 0;
Mode.colors_min = 0;
Mode.colors_max = 0;
Mode.speed = 0;
Mode.direction = 0;
Mode.color_mode = 0;
return Mode;
}
RGBController_LianLiUniHub::RGBController_LianLiUniHub(LianLiUniHubController* uniHub_ptr)
{
uniHub = uniHub_ptr;
name = "Lian Li Uni Hub";
vendor = "Lian Li";
version = uniHub->GetVersion();
type = DEVICE_TYPE_COOLER;
description = "Lian Li Uni Hub";
location = uniHub->GetLocation();
serial = uniHub->GetSerial();
initializedMode = false;
mode StaticColor = makeMode();
StaticColor.name = "Custom";
StaticColor.value = UNIHUB_LED_MODE_STATIC_COLOR;
StaticColor.flags = MODE_FLAG_HAS_BRIGHTNESS | MODE_FLAG_HAS_PER_LED_COLOR;
StaticColor.color_mode = MODE_COLORS_PER_LED;
modes.push_back(StaticColor);
mode Rainbow = makeMode();
Rainbow.name = "Rainbow Wave";
Rainbow.value = UNIHUB_LED_MODE_RAINBOW;
Rainbow.flags = MODE_FLAG_HAS_SPEED | MODE_FLAG_HAS_BRIGHTNESS | MODE_FLAG_HAS_DIRECTION_LR;
Rainbow.speed_min = 1;
Rainbow.speed_max = 5;
Rainbow.color_mode = MODE_COLORS_NONE;
modes.push_back(Rainbow);
mode Breathing = makeMode();
Breathing.name = "Breathing";
Breathing.value = UNIHUB_LED_MODE_BREATHING;
Breathing.flags = MODE_FLAG_HAS_SPEED | MODE_FLAG_HAS_BRIGHTNESS | MODE_FLAG_HAS_PER_LED_COLOR;
Breathing.speed_min = 1;
Breathing.speed_max = 5;
Breathing.color_mode = MODE_COLORS_PER_LED;
modes.push_back(Breathing);
mode ColorCycle = makeMode();
ColorCycle.name = "Color Cycle";
ColorCycle.value = UNIHUB_LED_MODE_COLOR_CYCLE;
ColorCycle.flags = MODE_FLAG_HAS_SPEED | MODE_FLAG_HAS_BRIGHTNESS | MODE_FLAG_HAS_DIRECTION_LR | MODE_FLAG_HAS_MODE_SPECIFIC_COLOR;
ColorCycle.speed_min = 1;
ColorCycle.speed_max = 5;
ColorCycle.colors_min = 3;
ColorCycle.colors_max = 3;
ColorCycle.color_mode = MODE_COLORS_MODE_SPECIFIC;
ColorCycle.colors.resize(3);
modes.push_back(ColorCycle);
mode Runway = makeMode();
Runway.name = "Runway";
Runway.value = UNIHUB_LED_MODE_RUNWAY;
Runway.flags = MODE_FLAG_HAS_SPEED | MODE_FLAG_HAS_BRIGHTNESS | MODE_FLAG_HAS_MODE_SPECIFIC_COLOR;
Runway.speed_min = 1;
Runway.speed_max = 5;
Runway.colors_min = 2;
Runway.colors_max = 2;
Runway.color_mode = MODE_COLORS_MODE_SPECIFIC;
Runway.colors.resize(2);
modes.push_back(Runway);
mode RunwaySync = makeMode();
RunwaySync.name = "Runway Sync";
RunwaySync.value = UNIHUB_LED_MODE_RUNWAY_SYNC | 0x0100;
RunwaySync.flags = MODE_FLAG_HAS_SPEED | MODE_FLAG_HAS_BRIGHTNESS | MODE_FLAG_HAS_MODE_SPECIFIC_COLOR;
RunwaySync.speed_min = 1;
RunwaySync.speed_max = 5;
RunwaySync.colors_min = 2;
RunwaySync.colors_max = 2;
RunwaySync.color_mode = MODE_COLORS_MODE_SPECIFIC;
RunwaySync.colors.resize(2);
modes.push_back(RunwaySync);
mode Staggered = makeMode();
Staggered.name = "Staggered";
Staggered.value = UNIHUB_LED_MODE_STAGGGERED;
Staggered.flags = MODE_FLAG_HAS_SPEED | MODE_FLAG_HAS_BRIGHTNESS | MODE_FLAG_HAS_MODE_SPECIFIC_COLOR;
Staggered.speed_min = 1;
Staggered.speed_max = 5;
Staggered.colors_min = 2;
Staggered.colors_max = 2;
Staggered.color_mode = MODE_COLORS_MODE_SPECIFIC;
Staggered.colors.resize(2);
modes.push_back(Staggered);
mode Mixing = makeMode();
Mixing.name = "Mixing";
Mixing.value = UNIHUB_LED_MODE_MIXING;
Mixing.flags = MODE_FLAG_HAS_SPEED | MODE_FLAG_HAS_BRIGHTNESS | MODE_FLAG_HAS_MODE_SPECIFIC_COLOR;
Mixing.speed_min = 1;
Mixing.speed_max = 5;
Mixing.colors_min = 2;
Mixing.colors_max = 2;
Mixing.color_mode = MODE_COLORS_MODE_SPECIFIC;
Mixing.colors.resize(2);
modes.push_back(Mixing);
mode Meteor = makeMode();
Meteor.name = "Meteor";
Meteor.value = UNIHUB_LED_MODE_METEOR;
Meteor.flags = MODE_FLAG_HAS_SPEED | MODE_FLAG_HAS_BRIGHTNESS | MODE_FLAG_HAS_MODE_SPECIFIC_COLOR;
Meteor.speed_min = 1;
Meteor.speed_max = 5;
Meteor.colors_min = 2;
Meteor.colors_max = 2;
Meteor.color_mode = MODE_COLORS_MODE_SPECIFIC;
Meteor.colors.resize(2);
modes.push_back(Meteor);
mode MeteorSync = makeMode();
MeteorSync.name = "Meteor Sync";
MeteorSync.value = UNIHUB_LED_MODE_METEOR_SYNC | 0x0100;
MeteorSync.flags = MODE_FLAG_HAS_SPEED | MODE_FLAG_HAS_BRIGHTNESS | MODE_FLAG_HAS_MODE_SPECIFIC_COLOR;
MeteorSync.speed_min = 1;
MeteorSync.speed_max = 5;
MeteorSync.colors_min = 2;
MeteorSync.colors_max = 2;
MeteorSync.color_mode = MODE_COLORS_MODE_SPECIFIC;
MeteorSync.colors.resize(2);
modes.push_back(MeteorSync);
mode Firework = makeMode();
Firework.name = "Firework";
Firework.value = UNIHUB_LED_MODE_FIREWORK;
Firework.flags = MODE_FLAG_HAS_SPEED | MODE_FLAG_HAS_BRIGHTNESS | MODE_FLAG_HAS_MODE_SPECIFIC_COLOR;
Firework.speed_min = 1;
Firework.speed_max = 5;
Firework.colors_min = 2;
Firework.colors_max = 2;
Firework.color_mode = MODE_COLORS_MODE_SPECIFIC;
Firework.colors.resize(2);
modes.push_back(Firework);
mode Stack = makeMode();
Stack.name = "Stack";
Stack.value = UNIHUB_LED_MODE_STACK;
Stack.flags = MODE_FLAG_HAS_SPEED | MODE_FLAG_HAS_BRIGHTNESS | MODE_FLAG_HAS_DIRECTION_LR | MODE_FLAG_HAS_MODE_SPECIFIC_COLOR;
Stack.speed_min = 1;
Stack.speed_max = 5;
Stack.colors_min = 1;
Stack.colors_max = 1;
Stack.color_mode = MODE_COLORS_MODE_SPECIFIC;
Stack.colors.resize(1);
modes.push_back(Stack);
mode StackMultiColor = makeMode();
StackMultiColor.name = "Stack Multi Color";
StackMultiColor.value = UNIHUB_LED_MODE_STACK_MULTI_COLOR;
StackMultiColor.flags = MODE_FLAG_HAS_SPEED | MODE_FLAG_HAS_BRIGHTNESS | MODE_FLAG_HAS_DIRECTION_LR;
StackMultiColor.speed_min = 1;
StackMultiColor.speed_max = 5;
StackMultiColor.color_mode = MODE_COLORS_NONE;
modes.push_back(StackMultiColor);
mode Neon = makeMode();
Neon.name = "Neon";
Neon.value = UNIHUB_LED_MODE_NEON;
Neon.flags = MODE_FLAG_HAS_SPEED | MODE_FLAG_HAS_BRIGHTNESS;
Neon.speed_min = 1;
Neon.speed_max = 5;
Neon.color_mode = MODE_COLORS_NONE;
modes.push_back(Neon);
mode Rgbh = makeMode();
Rgbh.name = "RGB Header";
Rgbh.value = UNIHUB_LED_MODE_STATIC_COLOR | 0x0200;
Rgbh.flags = 0;
Rgbh.color_mode = MODE_COLORS_NONE;
modes.push_back(Rgbh);
RGBController_LianLiUniHub::SetupZones();
}
void RGBController_LianLiUniHub::SetupZones()
{
/*-------------------------------------------------*\
| Only set LED count on the first run |
\*-------------------------------------------------*/
bool first_run = false;
if(zones.size() == 0)
{
first_run = true;
}
/*-------------------------------------------------*\
| Clear any existing color/LED configuration |
\*-------------------------------------------------*/
leds.clear();
colors.clear();
zones.resize(UNIHUB_CHANNEL_COUNT);
/*-------------------------------------------------*\
| Set zones and leds |
\*-------------------------------------------------*/
int addressableCounter = 1;
for(unsigned int channel_idx = 0; channel_idx < zones.size(); channel_idx++)
{
zones[channel_idx].name = "Channel ";
zones[channel_idx].name.append(std::to_string(addressableCounter));
addressableCounter++;
zones[channel_idx].type = ZONE_TYPE_LINEAR;
zones[channel_idx].leds_min = 0;
zones[channel_idx].leds_max = UNIHUB_CHANLED_COUNT;
if(first_run)
{
zones[channel_idx].leds_count = zones[channel_idx].leds_min;
}
for(unsigned int led_ch_idx = 0; led_ch_idx < zones[channel_idx].leds_count; led_ch_idx++)
{
led new_led;
new_led.name = zones[channel_idx].name;
new_led.name.append(", LED ");
new_led.name.append(std::to_string(led_ch_idx + 1));
new_led.value = channel_idx;
leds.push_back(new_led);
}
zones[channel_idx].matrix_map = NULL;
}
SetupColors();
}
void RGBController_LianLiUniHub::ResizeZone(int zone, int new_size)
{
if((size_t) zone >= zones.size())
{
return;
}
if(((unsigned int)new_size >= zones[zone].leds_min) && ((unsigned int)new_size <= zones[zone].leds_max))
{
zones[zone].leds_count = new_size;
SetupZones();
}
}
void RGBController_LianLiUniHub::DeviceUpdateLEDs()
{
if(!initializedMode)
{
DeviceUpdateMode();
}
for(size_t channel = 0; channel < zones.size(); channel++)
{
uint8_t fanCount = convertLedCountToFanCount(zones[channel].leds_count);
uniHub->SetAnyFanCount(channel, convertAnyFanCount(fanCount));
uniHub->SetLedColors(channel, zones[channel].colors, zones[channel].leds_count);
}
uniHub->Synchronize();
}
void RGBController_LianLiUniHub::UpdateZoneLEDs(int zone)
{
if(!initializedMode)
{
DeviceUpdateMode();
}
unsigned int channel = zone;
uint8_t fanCount = convertLedCountToFanCount(zones[channel].leds_count);
uniHub->SetAnyFanCount(channel, convertAnyFanCount(fanCount));
uniHub->SetLedColors(channel, zones[channel].colors, zones[channel].leds_count);
uniHub->Synchronize();
}
void RGBController_LianLiUniHub::UpdateSingleLED(int led)
{
if(!initializedMode)
{
DeviceUpdateMode();
}
unsigned int channel = leds[led].value;
uint8_t fanCount = convertLedCountToFanCount(zones[channel].leds_count);
uniHub->SetAnyFanCount(channel, convertAnyFanCount(fanCount));
uniHub->SetLedColors(channel, zones[channel].colors, zones[channel].leds_count);
uniHub->Synchronize();
}
void RGBController_LianLiUniHub::DeviceUpdateMode()
{
initializedMode = true;
for (size_t channel = 0; channel < zones.size(); channel++)
{
uint8_t fanCount = convertLedCountToFanCount(zones[channel].leds_count);
uniHub->SetAnyFanCount(channel, convertAnyFanCount(fanCount));
switch (modes[active_mode].color_mode)
{
case MODE_COLORS_PER_LED:
uniHub->SetLedColors(channel, zones[channel].colors, zones[channel].leds_count);
break;
case MODE_COLORS_MODE_SPECIFIC:
uniHub->SetLedColors(channel, modes[active_mode].colors.data(), modes[active_mode].colors.size());
break;
default:
uniHub->SetLedColors(channel, nullptr, 0);
break;
}
uniHub->SetLedMode(channel, modes[active_mode].value);
if(modes[active_mode].flags & MODE_FLAG_HAS_SPEED)
{
uniHub->SetLedSpeed(channel, convertLedSpeed(modes[active_mode].speed));
}
else
{
uniHub->SetLedSpeed(channel, UNIHUB_LED_SPEED_000);
}
if(modes[active_mode].flags & MODE_FLAG_HAS_DIRECTION_LR)
{
uniHub->SetLedDirection(channel, convertLedDirection(modes[active_mode].direction));
}
else
{
uniHub->SetLedDirection(channel, UNIHUB_LED_DIRECTION_LTR);
}
}
if(modes[active_mode].value & 0x0200)
{
uniHub->EnableRgbhMode();
uniHub->DisableSyncMode();
}
else if (modes[active_mode].value & 0x0100)
{
uniHub->DisableRgbhMode();
uniHub->EnableSyncMode();
}
else
{
uniHub->DisableRgbhMode();
uniHub->DisableSyncMode();
}
uniHub->Synchronize();
}
void RGBController_LianLiUniHub::SetCustomMode()
{
/*-------------------------------------------------*\
| Set mode to Static Color |
\*-------------------------------------------------*/
active_mode = 0;
}
uint8_t RGBController_LianLiUniHub::convertAnyFanCount(uint8_t count)
{
switch (count)
{
case 0:
return UNIHUB_ANY_FAN_COUNT_000;
case 1:
return UNIHUB_ANY_FAN_COUNT_001;
case 2:
return UNIHUB_ANY_FAN_COUNT_002;
case 3:
return UNIHUB_ANY_FAN_COUNT_003;
case 4:
return UNIHUB_ANY_FAN_COUNT_004;
default:
return UNIHUB_ANY_FAN_COUNT_001;
}
}
uint8_t RGBController_LianLiUniHub::convertLedSpeed(uint8_t speed)
{
switch (speed)
{
case 1:
return UNIHUB_LED_SPEED_000;
case 2:
return UNIHUB_LED_SPEED_025;
case 3:
return UNIHUB_LED_SPEED_050;
case 4:
return UNIHUB_LED_SPEED_075;
case 5:
return UNIHUB_LED_SPEED_100;
default:
return UNIHUB_LED_SPEED_050;
}
}
uint8_t RGBController_LianLiUniHub::convertLedDirection(uint8_t direction)
{
switch (direction)
{
case 0:
return UNIHUB_LED_DIRECTION_LTR;
case 1:
return UNIHUB_LED_DIRECTION_RTL;
default:
return UNIHUB_LED_DIRECTION_LTR;
}
}
uint8_t RGBController_LianLiUniHub::convertLedCountToFanCount(uint8_t count)
{
/*-------------------------------------------------*\
| Converts 0 to 0, 1-16 to 1, 17-32 to 2, 33-48 to |
| 3 and 49-64+ to 4 |
\*-------------------------------------------------*/
if (count == 0x00)
{
return 0x00;
}
if (count >= 0x40)
{
count = 0x40;
}
return((count -1) / 16 + 1);
}
@@ -0,0 +1,45 @@
/*-----------------------------------------*\
| RGBController_LianLiUniHub.h |
| |
| Generic RGB Interface for Lian Li Uni |
| Hub USB controller driver |
| |
| Luca Lovisa 2/20/2021 |
\*-----------------------------------------*/
#pragma once
#include <cstdint>
#include <vector>
#include "LianLiUniHubController.h"
#include "RGBController.h"
class RGBController_LianLiUniHub : public RGBController
{
public:
RGBController_LianLiUniHub(LianLiUniHubController* uniHub_ptr);
void SetupZones();
void ResizeZone(int zone, int new_size);
void DeviceUpdateLEDs();
void UpdateZoneLEDs(int zone);
void UpdateSingleLED(int led);
void DeviceUpdateMode();
void SetCustomMode();
private:
uint8_t convertAnyFanCount(uint8_t count);
uint8_t convertLedSpeed(uint8_t speed);
uint8_t convertLedDirection(uint8_t direction);
uint8_t convertLedCountToFanCount(uint8_t count);
private:
LianLiUniHubController* uniHub;
bool initializedMode;
};
@@ -33,7 +33,11 @@
#define STEELSERIES_RIVAL_300_DOTA_PID 0x1392
#define STEELSERIES_RIVAL_300_HP_PID 0x1718
#define STEELSERIES_RIVAL_300_BLACKOPS_PID 0x1710
#define STEELSERIES_RIVAL_310_PID 0x1720
#define STEELSERIES_RIVAL_310_CSGO_HOWL_PID 0x171e
#define STEELSERIES_RIVAL_310_PUBG_PID 0x1736
#define STEELSERIES_SENSEI_TEN_PID 0x1832
#define STEELSERIES_SENSEI_TEN_CSGO_NEON_RIDER_PID 0x1834
#define STEELSERIES_SENSEI_310_PID 0x1722
/*-----------------------------------------------------*\
| Headset product IDs |
@@ -161,7 +165,11 @@ REGISTER_HID_DETECTOR_I("SteelSeries Rival 300 CS:GO Hyperbeast Edition", Dete
REGISTER_HID_DETECTOR_I("SteelSeries Rival 300 Dota 2 Edition", DetectSteelSeriesRival300, STEELSERIES_VID, STEELSERIES_RIVAL_300_DOTA_PID, 0 );
REGISTER_HID_DETECTOR_I("SteelSeries Rival 300 HP Omen Edition", DetectSteelSeriesRival300, STEELSERIES_VID, STEELSERIES_RIVAL_300_HP_PID, 0 );
REGISTER_HID_DETECTOR_I("SteelSeries Rival 300 Black Ops Edition", DetectSteelSeriesRival300, STEELSERIES_VID, STEELSERIES_RIVAL_300_BLACKOPS_PID, 0 );
REGISTER_HID_DETECTOR_I("SteelSeries Rival 310", DetectSteelSeriesSensei, STEELSERIES_VID, STEELSERIES_RIVAL_310_PID, 0 );
REGISTER_HID_DETECTOR_I("SteelSeries Rival 310 CS:GO Howl Edition", DetectSteelSeriesSensei, STEELSERIES_VID, STEELSERIES_RIVAL_310_CSGO_HOWL_PID, 0 );
REGISTER_HID_DETECTOR_I("SteelSeries Rival 310 PUBG Edition", DetectSteelSeriesSensei, STEELSERIES_VID, STEELSERIES_RIVAL_310_PUBG_PID, 0 );
REGISTER_HID_DETECTOR_I("SteelSeries Sensei TEN", DetectSteelSeriesSensei, STEELSERIES_VID, STEELSERIES_SENSEI_TEN_PID, 0 );
REGISTER_HID_DETECTOR_I("SteelSeries Sensei TEN CS:GO Neon Rider Edition", DetectSteelSeriesSensei, STEELSERIES_VID, STEELSERIES_SENSEI_TEN_CSGO_NEON_RIDER_PID,0 );
REGISTER_HID_DETECTOR_I("SteelSeries Sensei 310", DetectSteelSeriesSensei, STEELSERIES_VID, STEELSERIES_SENSEI_310_PID, 0 );
/*---------------------------------------------------------------------------------------------------------------------------------------------------------------------*\
| Headsets |
+12
View File
@@ -67,6 +67,7 @@ INCLUDEPATH +=
Controllers/CorsairLightingNodeController/ \
Controllers/CorsairVengeanceController/ \
Controllers/CorsairVengeanceProController/ \
Controllers/CreativeController/ \
Controllers/CrucialController/ \
Controllers/DasKeyboardController/ \
Controllers/DebugController/ \
@@ -91,6 +92,7 @@ INCLUDEPATH +=
Controllers/HyperXMouseController/ \
Controllers/HyperXMousematController/ \
Controllers/LEDStripController/ \
Controllers/LianLiController/ \
Controllers/LogitechController/ \
Controllers/MSI3ZoneController/ \
Controllers/MSIGPUController/ \
@@ -194,6 +196,8 @@ HEADERS +=
Controllers/CorsairVengeanceController/RGBController_CorsairVengeance.h \
Controllers/CorsairVengeanceProController/CorsairVengeanceProController.h \
Controllers/CorsairVengeanceProController/RGBController_CorsairVengeancePro.h \
Controllers/CreativeController/CreativeSoundBlasterXG6Controller.h \
Controllers/CreativeController/RGBController_CreativeSoundBlasterXG6.h \
Controllers/CrucialController/CrucialController.h \
Controllers/CrucialController/RGBController_Crucial.h \
Controllers/DasKeyboardController/DasKeyboardController.h \
@@ -255,6 +259,8 @@ HEADERS +=
Controllers/HyperXMousematController/RGBController_HyperXMousemat.h \
Controllers/LEDStripController/LEDStripController.h \
Controllers/LEDStripController/RGBController_LEDStrip.h \
Controllers/LianLiController/LianLiUniHubController.h \
Controllers/LianLiController/RGBController_LianLiUniHub.h \
Controllers/LogitechController/LogitechG203Controller.h \
Controllers/LogitechController/LogitechG203LController.h \
Controllers/LogitechController/LogitechG213Controller.h \
@@ -438,6 +444,9 @@ SOURCES +=
Controllers/CorsairVengeanceProController/CorsairVengeanceProController.cpp \
Controllers/CorsairVengeanceProController/CorsairVengeanceProControllerDetect.cpp \
Controllers/CorsairVengeanceProController/RGBController_CorsairVengeancePro.cpp \
Controllers/CreativeController/CreativeSoundBlasterXG6Controller.cpp \
Controllers/CreativeController/CreativeControllerDetect.cpp \
Controllers/CreativeController/RGBController_CreativeSoundBlasterXG6.cpp \
Controllers/CrucialController/CrucialController.cpp \
Controllers/CrucialController/CrucialControllerDetect.cpp \
Controllers/CrucialController/RGBController_Crucial.cpp \
@@ -523,6 +532,9 @@ SOURCES +=
Controllers/LEDStripController/LEDStripController.cpp \
Controllers/LEDStripController/LEDStripControllerDetect.cpp \
Controllers/LEDStripController/RGBController_LEDStrip.cpp \
Controllers/LianLiController/LianLiControllerDetect.cpp \
Controllers/LianLiController/LianLiUniHubController.cpp \
Controllers/LianLiController/RGBController_LianLiUniHub.cpp \
Controllers/LogitechController/LogitechControllerDetect.cpp \
Controllers/LogitechController/LogitechG203Controller.cpp \
Controllers/LogitechController/LogitechG203LController.cpp \
+1
View File
@@ -178,6 +178,7 @@ There have been two instances of hardware damage in OpenRGB's development and we
* OpenRGB E1.31 Receiver Plugin (by me): https://gitlab.com/CalcProgrammer1/OpenRGBE131ReceiverPlugin
* Auto Updates Plugin (by herosilas12): https://gitlab.com/herosilas12/OpenRGB-Plugins/-/tree/Updates
* Effects Engine Plugin (by herosilas12): https://gitlab.com/OpenRGBDevelopers/OpenRGBEffectPlugin
* OpenRGB Visual Map Plugin (by morg): https://gitlab.com/OpenRGBDevelopers/OpenRGBVisualMapPlugin
## Projects Used
+8
View File
@@ -1369,6 +1369,12 @@ void RGBController::UnregisterUpdateCallback(void * callback_arg)
}
}
void RGBController::ClearCallbacks()
{
UpdateCallbacks.clear();
UpdateCallbackArgs.clear();
}
void RGBController::SignalUpdate()
{
UpdateMutex.lock();
@@ -1459,6 +1465,8 @@ std::string device_type_to_str(device_type type)
return "Light";
case DEVICE_TYPE_SPEAKER:
return "Speaker";
case DEVICE_TYPE_VIRTUAL:
return "Virtual";
default:
return "Unknown";
}
+3
View File
@@ -118,6 +118,7 @@ enum
DEVICE_TYPE_GAMEPAD,
DEVICE_TYPE_LIGHT,
DEVICE_TYPE_SPEAKER,
DEVICE_TYPE_VIRTUAL,
DEVICE_TYPE_UNKNOWN
};
@@ -175,6 +176,7 @@ public:
virtual void RegisterUpdateCallback(RGBControllerCallback new_callback, void * new_callback_arg) = 0;
virtual void UnregisterUpdateCallback(void * callback_arg) = 0;
virtual void ClearCallbacks() = 0;
virtual void SignalUpdate() = 0;
virtual void UpdateLEDs() = 0;
@@ -253,6 +255,7 @@ public:
void RegisterUpdateCallback(RGBControllerCallback new_callback, void * new_callback_arg);
void UnregisterUpdateCallback(void * callback_arg);
void ClearCallbacks();
void SignalUpdate();
void UpdateLEDs();
+32
View File
@@ -91,6 +91,38 @@ void ResourceManager::RegisterRGBController(RGBController *rgb_controller)
DeviceListChanged();
}
void ResourceManager::UnregisterRGBController(RGBController *rgb_controller)
{
LOG_NOTICE("Unregistering RGB controller: %s", rgb_controller->name.c_str());
/*-------------------------------------------------------------------------*\
| Clear callbacks from the controller before removal |
\*-------------------------------------------------------------------------*/
rgb_controller->ClearCallbacks();
/*-------------------------------------------------------------------------*\
| Find the controller to remove and remove it from the hardware list |
\*-------------------------------------------------------------------------*/
std::vector<RGBController*>::iterator hw_it = std::find(rgb_controllers_hw.begin(), rgb_controllers_hw.end(), rgb_controller);
if (hw_it != rgb_controllers_hw.end())
{
rgb_controllers_hw.erase(hw_it);
}
/*-------------------------------------------------------------------------*\
| Find the controller to remove and remove it from the master list |
\*-------------------------------------------------------------------------*/
std::vector<RGBController*>::iterator rgb_it = std::find(rgb_controllers.begin(), rgb_controllers.end(), rgb_controller);
if (rgb_it != rgb_controllers.end())
{
rgb_controllers.erase(rgb_it);
}
DeviceListChanged();
}
std::vector<RGBController*> & ResourceManager::GetRGBControllers()
{
return rgb_controllers;
+2
View File
@@ -56,6 +56,7 @@ public:
virtual std::vector<i2c_smbus_interface*> & GetI2CBusses() = 0;
virtual void RegisterRGBController(RGBController *rgb_controller) = 0;
virtual void UnregisterRGBController(RGBController *rgb_controller) = 0;
virtual void RegisterDeviceListChangeCallback(DeviceListChangeCallback new_callback, void * new_callback_arg) = 0;
virtual void RegisterDetectionProgressCallback(DetectionProgressCallback new_callback, void * new_callback_arg) = 0;
@@ -92,6 +93,7 @@ public:
std::vector<i2c_smbus_interface*> & GetI2CBusses();
void RegisterRGBController(RGBController *rgb_controller);
void UnregisterRGBController(RGBController *rgb_controller);
std::vector<RGBController*> & GetRGBControllers();
+1
View File
@@ -98,6 +98,7 @@
#define EVGA_RTX2080_XC_GAMING_SUB_DEV 0x2182
#define EVGA_RTX2080_XC_ULTRA_GAMING_SUB_DEV 0x2183
#define EVGA_RTX2080TI_XC_ULTRA_GAMING_SUB_DEV 0x2383
#define EVGA_RTX2080TI_FTW3_ULTRA_SUB_DEV 0x2487
/*-----------------------------------------------------*\
| Gainward Sub-Device IDs |
+65 -78
View File
@@ -72,80 +72,45 @@ OpenRGBDevicePage::OpenRGBDevicePage(RGBController *dev, QWidget *parent) :
/*-----------------------------------------------------*\
| Set up the color palette buttons |
\*-----------------------------------------------------*/
#ifdef _WIN32
if(((OpenRGBDialog2 *)parent)->IsDarkTheme())
{
ui->ButtonRed->setStyleSheet("QPushButton {background-color: rgb(255,0,0); color: rgb(255,0,0);}");
ui->ButtonRed->setFlat(true);
ui->ButtonRed->update();
ui->ButtonBlack->setStyleSheet("QPushButton {background-color: rgb(0,0,0); color: rgb(0,0,0); border: 1px solid rgb(128, 128, 128); padding-top: 1px; padding-bottom: 1px;}");
ui->ButtonBlack->setFlat(true);
ui->ButtonBlack->setMinimumWidth(20);
ui->ButtonBlack->update();
ui->ButtonYellow->setStyleSheet("QPushButton {background-color: rgb(255,255,0); color: rgb(255,255,0);}");
ui->ButtonYellow->setFlat(true);
ui->ButtonYellow->update();
ui->ButtonRed->setStyleSheet("QPushButton {background-color: rgb(255,0,0); color: rgb(255,0,0); border: 1px solid rgb(128, 128, 128); padding-top: 1px; padding-bottom: 1px;}");
ui->ButtonRed->setFlat(true);
ui->ButtonRed->setMinimumWidth(20);
ui->ButtonRed->update();
ui->ButtonGreen->setStyleSheet("QPushButton {background-color: rgb(0,255,0); color: rgb(0,255,0);}");
ui->ButtonGreen->setFlat(true);
ui->ButtonGreen->update();
ui->ButtonYellow->setStyleSheet("QPushButton {background-color: rgb(255,255,0); color: rgb(255,255,0); border: 1px solid rgb(128, 128, 128); padding-top: 1px; padding-bottom: 1px;}");
ui->ButtonYellow->setFlat(true);
ui->ButtonYellow->setMinimumWidth(20);
ui->ButtonYellow->update();
ui->ButtonCyan->setStyleSheet("QPushButton {background-color: rgb(0,255,255); color: rgb(0,255,255);}");
ui->ButtonCyan->setFlat(true);
ui->ButtonCyan->update();
ui->ButtonGreen->setStyleSheet("QPushButton {background-color: rgb(0,255,0); color: rgb(0,255,0); border: 1px solid rgb(128, 128, 128); padding-top: 1px; padding-bottom: 1px;}");
ui->ButtonGreen->setFlat(true);
ui->ButtonGreen->setMinimumWidth(20);
ui->ButtonGreen->update();
ui->ButtonBlue->setStyleSheet("QPushButton {background-color: rgb(0,0,255); color: rgb(0,0,255);}");
ui->ButtonBlue->setFlat(true);
ui->ButtonBlue->update();
ui->ButtonCyan->setStyleSheet("QPushButton {background-color: rgb(0,255,255); color: rgb(0,255,255); border: 1px solid rgb(128, 128, 128); padding-top: 1px; padding-bottom: 1px;}");
ui->ButtonCyan->setFlat(true);
ui->ButtonCyan->setMinimumWidth(20);
ui->ButtonCyan->update();
ui->ButtonMagenta->setStyleSheet("QPushButton {background-color: rgb(255,0,255); color: rgb(255,0,255);}");
ui->ButtonMagenta->setFlat(true);
ui->ButtonMagenta->update();
}
else
#endif
{
QPalette pal;
ui->ButtonBlue->setStyleSheet("QPushButton {background-color: rgb(0,0,255); color: rgb(0,0,255); border: 1px solid rgb(128, 128, 128); padding-top: 1px; padding-bottom: 1px;}");
ui->ButtonBlue->setFlat(true);
ui->ButtonBlue->setMinimumWidth(20);
ui->ButtonBlue->update();
pal = ui->ButtonRed->palette();
pal.setColor(QPalette::Button, QColor(255, 0, 0));
ui->ButtonRed->setAutoFillBackground(true);
ui->ButtonRed->setPalette(pal);
ui->ButtonRed->setFlat(true);
ui->ButtonRed->update();
ui->ButtonMagenta->setStyleSheet("QPushButton {background-color: rgb(255,0,255); color: rgb(255,0,255); border: 1px solid rgb(128, 128, 128); padding-top: 1px; padding-bottom: 1px;}");
ui->ButtonMagenta->setFlat(true);
ui->ButtonMagenta->setMinimumWidth(20);
ui->ButtonMagenta->update();
pal = ui->ButtonYellow->palette();
pal.setColor(QPalette::Button, QColor(255, 255, 0));
ui->ButtonYellow->setAutoFillBackground(true);
ui->ButtonYellow->setPalette(pal);
ui->ButtonYellow->setFlat(true);
ui->ButtonYellow->update();
pal = ui->ButtonGreen->palette();
pal.setColor(QPalette::Button, QColor(0, 255, 0));
ui->ButtonGreen->setAutoFillBackground(true);
ui->ButtonGreen->setPalette(pal);
ui->ButtonGreen->setFlat(true);
ui->ButtonGreen->update();
pal = ui->ButtonCyan->palette();
pal.setColor(QPalette::Button, QColor(0, 255, 255));
ui->ButtonCyan->setAutoFillBackground(true);
ui->ButtonCyan->setPalette(pal);
ui->ButtonCyan->setFlat(true);
ui->ButtonCyan->update();
pal = ui->ButtonBlue->palette();
pal.setColor(QPalette::Button, QColor(0, 0, 255));
ui->ButtonBlue->setAutoFillBackground(true);
ui->ButtonBlue->setPalette(pal);
ui->ButtonBlue->setFlat(true);
ui->ButtonBlue->update();
pal = ui->ButtonMagenta->palette();
pal.setColor(QPalette::Button, QColor(255, 0, 255));
ui->ButtonMagenta->setAutoFillBackground(true);
ui->ButtonMagenta->setPalette(pal);
ui->ButtonMagenta->setFlat(true);
ui->ButtonMagenta->update();
}
ui->ButtonWhite->setStyleSheet("QPushButton {background-color: rgb(255,255,255); color: rgb(255,255,255); border: 1px solid rgb(128, 128, 128); padding-top: 1px; padding-bottom: 1px;}");
ui->ButtonWhite->setFlat(true);
ui->ButtonWhite->setMinimumWidth(20);
ui->ButtonWhite->update();
/*-----------------------------------------------------*\
| Fill in the mode selection box |
@@ -245,6 +210,12 @@ void Ui::OpenRGBDevicePage::on_ZoneBox_currentIndexChanged(int /*index*/)
ui->DeviceViewBox->clearSelection();
ui->DeviceViewBox->blockSignals(false);
}
ui->ApplyColorsButton->setText("Apply Colors To This Device");
}
else
{
//If the index has been changed and there is more than one zone change the "Apply" text
ui->ApplyColorsButton->setText("Apply Colors To The Selection");
}
selected_zone = selected_zone - 1;
}
@@ -325,6 +296,12 @@ void Ui::OpenRGBDevicePage::on_LEDBox_currentIndexChanged(int index)
ui->DeviceViewBox->clearSelection();
ui->DeviceViewBox->blockSignals(false);
}
ui->ApplyColorsButton->setText("Apply Colors To This Device");
}
else
{
//If the index has been changed and there is more than one zone change the "Apply" text
ui->ApplyColorsButton->setText("Apply Colors To The Selection");
}
index = index - 1;
}
@@ -397,17 +374,17 @@ void Ui::OpenRGBDevicePage::on_LEDBox_currentIndexChanged(int index)
case MODE_COLORS_MODE_SPECIFIC:
{
/*-----------------------------------------------------*\
| Update color picker with color of selected mode |
\*-----------------------------------------------------*/
RGBColor color = device->modes[selected_mode].colors[index];
UpdatingColor = true;
ui->RedSpinBox->setValue(RGBGetRValue(color));
ui->GreenSpinBox->setValue(RGBGetGValue(color));
ui->BlueSpinBox->setValue(RGBGetBValue(color));
UpdatingColor = false;
updateHSV();
updateWheel();
/*-----------------------------------------------------*\
| Update color picker with color of selected mode |
\*-----------------------------------------------------*/
RGBColor color = device->modes[selected_mode].colors[index];
UpdatingColor = true;
ui->RedSpinBox->setValue(RGBGetRValue(color));
ui->GreenSpinBox->setValue(RGBGetGValue(color));
ui->BlueSpinBox->setValue(RGBGetBValue(color));
UpdatingColor = false;
updateHSV();
updateWheel();
}
break;
}
@@ -952,6 +929,11 @@ void Ui::OpenRGBDevicePage::SetCustomMode(unsigned char red, unsigned char green
UpdateMode();
}
void Ui::OpenRGBDevicePage::on_ButtonBlack_clicked()
{
SetDevice(0, 0, 0);
}
void Ui::OpenRGBDevicePage::on_ButtonRed_clicked()
{
SetDevice(255, 0, 0);
@@ -982,6 +964,11 @@ void Ui::OpenRGBDevicePage::on_ButtonMagenta_clicked()
SetDevice(255, 0, 255);
}
void Ui::OpenRGBDevicePage::on_ButtonWhite_clicked()
{
SetDevice(255, 255, 255);
}
void Ui::OpenRGBDevicePage::on_ColorWheelBox_colorChanged(const QColor color)
{
if(UpdatingColor)
+3
View File
@@ -45,12 +45,15 @@ private slots:
void on_ValSpinBox_valueChanged(int arg1);
void on_DeviceViewBox_selectionChanged(QVector<int>);
void on_ButtonBlack_clicked();
void on_ButtonRed_clicked();
void on_ButtonYellow_clicked();
void on_ButtonGreen_clicked();
void on_ButtonCyan_clicked();
void on_ButtonBlue_clicked();
void on_ButtonMagenta_clicked();
void on_ButtonWhite_clicked();
void on_SetAllButton_clicked();
void on_RandomCheck_clicked();
void on_PerLEDCheck_clicked();
+186 -177
View File
@@ -6,7 +6,7 @@
<rect>
<x>0</x>
<y>0</y>
<width>875</width>
<width>800</width>
<height>374</height>
</rect>
</property>
@@ -14,58 +14,10 @@
<string>Frame</string>
</property>
<layout class="QGridLayout" name="gridLayout">
<item row="12" column="8">
<widget class="QPushButton" name="ButtonCyan">
<item row="2" column="4">
<widget class="QPushButton" name="SelectAllLEDsButton">
<property name="text">
<string/>
</property>
</widget>
</item>
<item row="7" column="1" colspan="4">
<widget class="QComboBox" name="ModeBox"/>
</item>
<item row="7" column="5">
<widget class="QLabel" name="RedLabel">
<property name="text">
<string>R:</string>
</property>
</widget>
</item>
<item row="8" column="0">
<widget class="QLabel" name="ColorLabel">
<property name="text">
<string>Colors:</string>
</property>
</widget>
</item>
<item row="12" column="1" colspan="4">
<widget class="QComboBox" name="DirectionBox"/>
</item>
<item row="12" column="9">
<widget class="QPushButton" name="ButtonBlue">
<property name="text">
<string/>
</property>
</widget>
</item>
<item row="7" column="6" colspan="2">
<widget class="QSpinBox" name="RedSpinBox">
<property name="maximum">
<number>255</number>
</property>
</widget>
</item>
<item row="4" column="1" colspan="4">
<widget class="QPushButton" name="ApplyColorsButton">
<property name="text">
<string>Apply Colors</string>
</property>
</widget>
</item>
<item row="12" column="6">
<widget class="QPushButton" name="ButtonYellow">
<property name="text">
<string/>
<string>Select All</string>
</property>
</widget>
</item>
@@ -85,49 +37,141 @@
</property>
</widget>
</item>
<item row="7" column="0">
<widget class="QLabel" name="ModeLabel">
<item row="1" column="4">
<widget class="QPushButton" name="ResizeButton">
<property name="text">
<string>Mode:</string>
<string>Resize</string>
</property>
</widget>
</item>
<item row="9" column="1" colspan="4">
<widget class="QSlider" name="SpeedSlider">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
</widget>
</item>
<item row="8" column="8">
<widget class="QLabel" name="SatLabel">
<item row="6" column="0">
<widget class="QLabel" name="SpeedLabel">
<property name="text">
<string>S:</string>
<string>Speed:</string>
</property>
</widget>
</item>
<item row="5" column="1" colspan="4">
<widget class="QPushButton" name="SetAllButton">
<item row="5" column="1">
<widget class="QRadioButton" name="PerLEDCheck">
<property name="text">
<string>Set All Devices</string>
<string>Per-LED</string>
</property>
</widget>
</item>
<item row="3" column="0">
<item row="5" column="0">
<widget class="QLabel" name="ColorLabel">
<property name="text">
<string>Colors:</string>
</property>
</widget>
</item>
<item row="2" column="0">
<widget class="QLabel" name="LEDLabel">
<property name="text">
<string>LED:</string>
</property>
</widget>
</item>
<item row="12" column="5">
<widget class="QPushButton" name="ButtonRed">
<item row="4" column="0">
<widget class="QLabel" name="ModeLabel">
<property name="text">
<string/>
<string>Mode:</string>
</property>
</widget>
</item>
<item row="8" column="6" colspan="2">
<item row="2" column="1" colspan="3">
<widget class="QComboBox" name="LEDBox"/>
</item>
<item row="3" column="1" colspan="3">
<widget class="QPushButton" name="ApplyColorsButton">
<property name="text">
<string>Apply Colors To Selection</string>
</property>
</widget>
</item>
<item row="5" column="4">
<widget class="QRadioButton" name="RandomCheck">
<property name="text">
<string>Random</string>
</property>
</widget>
</item>
<item row="6" column="1" colspan="4">
<widget class="QSlider" name="SpeedSlider">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
</widget>
</item>
<item row="3" column="4">
<widget class="QPushButton" name="SetAllButton">
<property name="toolTip">
<string>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p align=&quot;justify&quot;&gt;Sets all devices to&lt;br/&gt;&lt;b&gt;Static&lt;/b&gt; mode and&lt;br/&gt;applies the selected color.&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
</property>
<property name="text">
<string>Apply All Devices</string>
</property>
</widget>
</item>
<item row="1" column="0">
<widget class="QLabel" name="ZoneLabel">
<property name="text">
<string>Zone:</string>
</property>
</widget>
</item>
<item row="1" column="1" colspan="3">
<widget class="QComboBox" name="ZoneBox"/>
</item>
<item row="4" column="1" colspan="4">
<widget class="QComboBox" name="ModeBox"/>
</item>
<item row="9" column="1" colspan="4">
<widget class="QComboBox" name="DirectionBox"/>
</item>
<item row="9" column="0">
<widget class="QLabel" name="DirectionLabel">
<property name="text">
<string>Dir:</string>
</property>
</widget>
</item>
<item row="5" column="2" colspan="2">
<widget class="QRadioButton" name="ModeSpecificCheck">
<property name="text">
<string>Mode-Specific</string>
</property>
</widget>
</item>
<item row="9" column="5">
<widget class="QLabel" name="BlueLabel">
<property name="text">
<string>B:</string>
</property>
</widget>
</item>
<item row="6" column="5">
<widget class="QLabel" name="GreenLabel">
<property name="text">
<string>G:</string>
</property>
</widget>
</item>
<item row="5" column="5">
<widget class="QLabel" name="RedLabel">
<property name="text">
<string>R:</string>
</property>
</widget>
</item>
<item row="5" column="6" colspan="2">
<widget class="QSpinBox" name="RedSpinBox">
<property name="maximum">
<number>255</number>
</property>
</widget>
</item>
<item row="6" column="6" colspan="2">
<widget class="QSpinBox" name="GreenSpinBox">
<property name="maximum">
<number>255</number>
@@ -148,80 +192,31 @@
</property>
</widget>
</item>
<item row="12" column="0">
<widget class="QLabel" name="DirectionLabel">
<item row="6" column="8">
<widget class="QLabel" name="SatLabel">
<property name="text">
<string>Dir:</string>
<string>S:</string>
</property>
</widget>
</item>
<item row="8" column="2" colspan="2">
<widget class="QRadioButton" name="ModeSpecificCheck">
<property name="text">
<string>Mode-Specific</string>
</property>
</widget>
</item>
<item row="12" column="10">
<widget class="QPushButton" name="ButtonMagenta">
<property name="text">
<string/>
</property>
</widget>
</item>
<item row="8" column="9" colspan="2">
<widget class="QSpinBox" name="SatSpinBox">
<property name="maximum">
<number>255</number>
</property>
</widget>
</item>
<item row="7" column="8">
<item row="5" column="8">
<widget class="QLabel" name="HueLabel">
<property name="text">
<string>H:</string>
</property>
</widget>
</item>
<item row="8" column="5">
<widget class="QLabel" name="GreenLabel">
<property name="text">
<string>G:</string>
</property>
</widget>
</item>
<item row="7" column="9" colspan="2">
<item row="5" column="9" colspan="2">
<widget class="QSpinBox" name="HueSpinBox">
<property name="maximum">
<number>359</number>
</property>
</widget>
</item>
<item row="8" column="4">
<widget class="QRadioButton" name="RandomCheck">
<property name="text">
<string>Random</string>
</property>
</widget>
</item>
<item row="9" column="0">
<widget class="QLabel" name="SpeedLabel">
<property name="text">
<string>Speed:</string>
</property>
</widget>
</item>
<item row="8" column="1">
<widget class="QRadioButton" name="PerLEDCheck">
<property name="text">
<string>Per-LED</string>
</property>
</widget>
</item>
<item row="12" column="7">
<widget class="QPushButton" name="ButtonGreen">
<property name="text">
<string/>
<item row="6" column="9" colspan="2">
<widget class="QSpinBox" name="SatSpinBox">
<property name="maximum">
<number>255</number>
</property>
</widget>
</item>
@@ -232,41 +227,67 @@
</property>
</widget>
</item>
<item row="9" column="5">
<widget class="QLabel" name="BlueLabel">
<property name="text">
<string>B:</string>
</property>
</widget>
<item row="4" column="5" colspan="6">
<layout class="QHBoxLayout" name="horizontalLayout">
<item>
<widget class="QPushButton" name="ButtonBlack">
<property name="text">
<string/>
</property>
</widget>
</item>
<item>
<widget class="QPushButton" name="ButtonRed">
<property name="text">
<string/>
</property>
</widget>
</item>
<item>
<widget class="QPushButton" name="ButtonYellow">
<property name="text">
<string/>
</property>
</widget>
</item>
<item>
<widget class="QPushButton" name="ButtonGreen">
<property name="text">
<string/>
</property>
</widget>
</item>
<item>
<widget class="QPushButton" name="ButtonCyan">
<property name="text">
<string/>
</property>
</widget>
</item>
<item>
<widget class="QPushButton" name="ButtonBlue">
<property name="text">
<string/>
</property>
</widget>
</item>
<item>
<widget class="QPushButton" name="ButtonMagenta">
<property name="text">
<string/>
</property>
</widget>
</item>
<item>
<widget class="QPushButton" name="ButtonWhite">
<property name="text">
<string/>
</property>
</widget>
</item>
</layout>
</item>
<item row="3" column="1" colspan="3">
<widget class="QComboBox" name="LEDBox"/>
</item>
<item row="3" column="4">
<widget class="QPushButton" name="SelectAllLEDsButton">
<property name="text">
<string>Select All</string>
</property>
</widget>
</item>
<item row="2" column="4">
<widget class="QPushButton" name="ResizeButton">
<property name="text">
<string>Resize</string>
</property>
</widget>
</item>
<item row="2" column="0">
<widget class="QLabel" name="ZoneLabel">
<property name="text">
<string>Zone:</string>
</property>
</widget>
</item>
<item row="2" column="1" colspan="3">
<widget class="QComboBox" name="ZoneBox"/>
</item>
<item row="2" column="5" rowspan="4" colspan="6">
<item row="1" column="5" rowspan="3" colspan="6">
<widget class="ColorWheel" name="ColorWheelBox" native="true">
<property name="sizePolicy">
<sizepolicy hsizetype="Preferred" vsizetype="Preferred">
@@ -304,18 +325,6 @@
<tabstop>RandomCheck</tabstop>
<tabstop>SpeedSlider</tabstop>
<tabstop>DirectionBox</tabstop>
<tabstop>RedSpinBox</tabstop>
<tabstop>GreenSpinBox</tabstop>
<tabstop>BlueSpinBox</tabstop>
<tabstop>HueSpinBox</tabstop>
<tabstop>SatSpinBox</tabstop>
<tabstop>ValSpinBox</tabstop>
<tabstop>ButtonRed</tabstop>
<tabstop>ButtonYellow</tabstop>
<tabstop>ButtonGreen</tabstop>
<tabstop>ButtonCyan</tabstop>
<tabstop>ButtonBlue</tabstop>
<tabstop>ButtonMagenta</tabstop>
</tabstops>
<resources/>
<connections/>
+3
View File
@@ -65,6 +65,9 @@ static QString GetIconString(device_type type, bool dark)
case DEVICE_TYPE_SPEAKER:
filename = "speaker";
break;
case DEVICE_TYPE_VIRTUAL:
filename = "virtual";
break;
default:
filename = "unknown";
break;
+2
View File
@@ -36,5 +36,7 @@
<file>plugin_dark.png</file>
<file>speaker.png</file>
<file>speaker_dark.png</file>
<file>virtual.png</file>
<file>virtual_dark.png</file>
</qresource>
</RCC>
BIN
View File
Binary file not shown.

After

Width:  |  Height:  |  Size: 5.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.3 KiB