Add support for Glorious Model I

This commit is contained in:
Kosta A
2025-11-29 00:07:36 +00:00
committed by Adam Honse
parent 05b4f00629
commit 8b9a4d141a
5 changed files with 462 additions and 0 deletions

View File

@@ -0,0 +1,102 @@
/*---------------------------------------------------------*\
| LaviewTechnologyController.cpp |
| |
| Driver for Laview Tech. mice, including Glorious |
| |
| Kosta A (kostaarvanitis) 27 Oct 2025 |
| |
| This file is part of the OpenRGB project |
| SPDX-License-Identifier: GPL-2.0-or-later |
\*---------------------------------------------------------*/
#include <cstring>
#include <cmath>
#include "LogManager.h"
#include "LaviewTechnologyController.h"
#include "StringUtils.h"
LaviewTechnologyController::LaviewTechnologyController(hid_device* dev_handle, hid_device_info* dev_info, std::string dev_name)
{
device = dev_handle;
location = dev_info->path;
name = dev_name;
version = dev_info->release_number;
vendor = StringUtils::wstring_to_string(dev_info->manufacturer_string);
serial = StringUtils::wstring_to_string(dev_info->serial_number);
}
LaviewTechnologyController::~LaviewTechnologyController()
{
hid_close(device);
}
std::string LaviewTechnologyController::GetLocation()
{
return("HID: " + location);
}
std::string LaviewTechnologyController::GetName()
{
return(name);
}
std::string LaviewTechnologyController::GetVendor()
{
return(vendor);
}
std::string LaviewTechnologyController::GetSerialNumber()
{
return(serial);
}
std::string LaviewTechnologyController::GetFirmwareVersion()
{
return std::to_string(version);
}
void LaviewTechnologyController::SetMode(unsigned int mode, unsigned int brightness, unsigned int speed, RGBColor* color)
{
uint8_t buf[LAVIEW_TECHNOLOGY_REPORT_SIZE];
memset(buf, 0x00, sizeof(buf));
buf[0] = 0xA1;
buf[1] = 0x0C;
buf[5] = 0x01; // Profile
buf[16] = mode;
buf[56] = std::clamp(0u, brightness, 64u);
buf[58] = std::clamp(0u, speed, 64u);
buf[60] = 0; // Set for some modes???
switch (mode)
{
case LAVIEW_TECHNOLOGY_MODE_STATIC:
case LAVIEW_TECHNOLOGY_MODE_BREATHING:
buf[17] = RGBGetRValue(color[0]);
buf[18] = RGBGetGValue(color[0]);
buf[19] = RGBGetBValue(color[0]);
break;
default:
/*----------------------------------------------------------------*\
| For these reports we inject the default color scheme into the |
| availble rgb values which in the official control application |
| are not present in some modes causing them to not function. |
| There is no mechanism in the control software for manipulating |
| these values, as such this functionality is also omitted here. |
\*----------------------------------------------------------------*/
const unsigned char bytes[] = {
0xFF, 0x00, 0x00, 0xFF, 0xA5, 0x00, 0xFF, 0xFF, 0x00,
0x00, 0xFF, 0x00, 0x00, 0x7F, 0xFF, 0x00, 0x00, 0xFF,
0x8B, 0x00, 0xFF
};
memcpy(&buf[17], bytes, sizeof(bytes));
break;
};
int ret = hid_send_feature_report(device, buf, sizeof(buf));
if(ret < 0)
{
LOG_ERROR("[%s] Failure to send report (%ls)!", name.c_str(), hid_error(device));
}
}

View File

@@ -0,0 +1,68 @@
/*---------------------------------------------------------*\
| LaviewTechnologyController.h |
| |
| Driver for Laview Tech. mice, including Glorious |
| |
| Kosta A (kostaarvanitis) 27 Oct 2025 |
| |
| This file is part of the OpenRGB project |
| SPDX-License-Identifier: GPL-2.0-or-later |
\*---------------------------------------------------------*/
#pragma once
#include <vector>
#include <hidapi.h>
#include "RGBController.h"
#define LAVIEW_TECHNOLOGY_REPORT_SIZE 64
enum
{
LAVIEW_TECHNOLOGY_MODE_OFF = 0x00, // Off
LAVIEW_TECHNOLOGY_MODE_STATIC = 0x01, // Normally on
LAVIEW_TECHNOLOGY_MODE_FLASHING = 0x02, // Wave
LAVIEW_TECHNOLOGY_MODE_BREATHING = 0x04, // Breathing single color
LAVIEW_TECHNOLOGY_MODE_SPECTRUM_CYCLE = 0x06, // Breating does not work with factory Core software
LAVIEW_TECHNOLOGY_MODE_RAINBOW_WAVE = 0x10, // Glorious Mode
LAVIEW_TECHNOLOGY_MODE_CHASE = 0x11, // Tail
LAVIEW_TECHNOLOGY_MODE_WAVE = 0x14, // Rave (Same issue as breathing)
LAVIEW_TECHNOLOGY_MODE_SPECTRUM_BREATHING = 0x15, // Seamless Breathing
};
enum
{
LAVIEW_TECHNOLOGY_SPEED_SLOW = 1,
LAVIEW_TECHNOLOGY_SPEED_NORMAL = 50,
LAVIEW_TECHNOLOGY_SPEED_FAST = 100,
};
enum
{
LAVIEW_TECHNOLOGY_BRIGHTNESS_SLOW = 0,
LAVIEW_TECHNOLOGY_BRIGHTNESS_NORMAL = 50,
LAVIEW_TECHNOLOGY_BRIGHTNESS_FAST = 100,
};
class LaviewTechnologyController
{
public:
LaviewTechnologyController(hid_device* dev_handle, hid_device_info* dev_info, std::string name);
~LaviewTechnologyController();
std::string GetLocation();
std::string GetName();
std::string GetVendor();
std::string GetSerialNumber();
std::string GetFirmwareVersion();
void SetMode(unsigned int mode, unsigned int brightness, unsigned int speed, RGBColor* color);
private:
hid_device* device;
std::string location;
std::string name;
std::string vendor;
std::string serial;
unsigned int version;
};

View File

@@ -0,0 +1,213 @@
/*---------------------------------------------------------*\
| RGBController_LaviewTechnology.cpp |
| |
| RGBController for Laview Tech. mice, including Glorious |
| |
| Kosta A (kostaarvanitis) 27 Oct 2025 |
| |
| This file is part of the OpenRGB project |
| SPDX-License-Identifier: GPL-2.0-or-later |
\*---------------------------------------------------------*/
#include "RGBController_LaviewTechnology.h"
/**------------------------------------------------------------------*\
@name Laview Technology Mice
@category Mouse
@type USB
@save :robot:
@direct :x:
@effects :white_check_mark:
@detectors DetectLaviewTechnologyMouse
@comment
\*-------------------------------------------------------------------*/
RGBController_LaviewTechnology::RGBController_LaviewTechnology(LaviewTechnologyController* controller_ptr)
{
controller = controller_ptr;
name = controller->GetName();
type = DEVICE_TYPE_MOUSE;
description = "Glorious Device";
vendor = controller->GetVendor();
location = controller->GetLocation();
serial = controller->GetSerialNumber();
version = controller->GetFirmwareVersion();
mode Custom;
Custom.name = "Custom";
Custom.flags = MODE_FLAG_HAS_PER_LED_COLOR | MODE_FLAG_HAS_BRIGHTNESS;
Custom.brightness_min = LAVIEW_TECHNOLOGY_BRIGHTNESS_SLOW;
Custom.brightness = LAVIEW_TECHNOLOGY_BRIGHTNESS_NORMAL;
Custom.brightness_max = LAVIEW_TECHNOLOGY_BRIGHTNESS_FAST;
Custom.color_mode = MODE_COLORS_PER_LED;
Custom.value = LAVIEW_TECHNOLOGY_MODE_STATIC;
modes.push_back(Custom);
mode Flashing;
Flashing.name = "Flashing";
Flashing.flags = MODE_FLAG_HAS_BRIGHTNESS | MODE_FLAG_HAS_SPEED;
Flashing.brightness_min = LAVIEW_TECHNOLOGY_BRIGHTNESS_SLOW;
Flashing.brightness = LAVIEW_TECHNOLOGY_BRIGHTNESS_NORMAL;
Flashing.brightness_max = LAVIEW_TECHNOLOGY_BRIGHTNESS_FAST;
Flashing.speed_min = LAVIEW_TECHNOLOGY_SPEED_SLOW;
Flashing.speed = LAVIEW_TECHNOLOGY_SPEED_NORMAL;
Flashing.speed_max = LAVIEW_TECHNOLOGY_SPEED_FAST;
Flashing.color_mode = MODE_COLORS_NONE;
Flashing.value = LAVIEW_TECHNOLOGY_MODE_FLASHING;
modes.push_back(Flashing);
mode Chase;
Chase.name = "Chase";
Chase.flags = MODE_FLAG_HAS_BRIGHTNESS | MODE_FLAG_HAS_SPEED;
Chase.brightness_min = LAVIEW_TECHNOLOGY_BRIGHTNESS_SLOW;
Chase.brightness = LAVIEW_TECHNOLOGY_BRIGHTNESS_NORMAL;
Chase.brightness_max = LAVIEW_TECHNOLOGY_BRIGHTNESS_FAST;
Chase.speed_min = LAVIEW_TECHNOLOGY_SPEED_SLOW;
Chase.speed = LAVIEW_TECHNOLOGY_SPEED_NORMAL;
Chase.speed_max = LAVIEW_TECHNOLOGY_SPEED_FAST;
Chase.color_mode = MODE_COLORS_NONE;
Chase.value = LAVIEW_TECHNOLOGY_MODE_CHASE;
modes.push_back(Chase);
mode Wave;
Wave.name = "Wave";
Wave.flags = MODE_FLAG_HAS_BRIGHTNESS | MODE_FLAG_HAS_SPEED;
Wave.brightness_min = LAVIEW_TECHNOLOGY_BRIGHTNESS_SLOW;
Wave.brightness = LAVIEW_TECHNOLOGY_BRIGHTNESS_NORMAL;
Wave.brightness_max = LAVIEW_TECHNOLOGY_BRIGHTNESS_FAST;
Wave.speed_min = LAVIEW_TECHNOLOGY_SPEED_SLOW;
Wave.speed = LAVIEW_TECHNOLOGY_SPEED_NORMAL;
Wave.speed_max = LAVIEW_TECHNOLOGY_SPEED_FAST;
Wave.color_mode = MODE_COLORS_NONE;
Wave.value = LAVIEW_TECHNOLOGY_MODE_WAVE;
modes.push_back(Wave);
mode SpectrumCycle;
SpectrumCycle.name = "Spectrum Cycle";
SpectrumCycle.flags = MODE_FLAG_HAS_BRIGHTNESS | MODE_FLAG_HAS_SPEED;
SpectrumCycle.brightness_min = LAVIEW_TECHNOLOGY_BRIGHTNESS_SLOW;
SpectrumCycle.brightness = LAVIEW_TECHNOLOGY_BRIGHTNESS_NORMAL;
SpectrumCycle.brightness_max = LAVIEW_TECHNOLOGY_BRIGHTNESS_FAST;
SpectrumCycle.speed_min = LAVIEW_TECHNOLOGY_SPEED_SLOW;
SpectrumCycle.speed = LAVIEW_TECHNOLOGY_SPEED_NORMAL;
SpectrumCycle.speed_max = LAVIEW_TECHNOLOGY_SPEED_FAST;
SpectrumCycle.color_mode = MODE_COLORS_NONE;
SpectrumCycle.value = LAVIEW_TECHNOLOGY_MODE_SPECTRUM_CYCLE;
modes.push_back(SpectrumCycle);
mode Breathing;
Breathing.name = "Breathing";
Breathing.flags = MODE_FLAG_HAS_MODE_SPECIFIC_COLOR | MODE_FLAG_HAS_BRIGHTNESS | MODE_FLAG_HAS_SPEED;
Breathing.brightness_min = LAVIEW_TECHNOLOGY_BRIGHTNESS_SLOW;
Breathing.brightness = LAVIEW_TECHNOLOGY_BRIGHTNESS_NORMAL;
Breathing.brightness_max = LAVIEW_TECHNOLOGY_BRIGHTNESS_FAST;
Breathing.speed_min = LAVIEW_TECHNOLOGY_SPEED_SLOW;
Breathing.speed = LAVIEW_TECHNOLOGY_SPEED_NORMAL;
Breathing.speed_max = LAVIEW_TECHNOLOGY_SPEED_FAST;
Breathing.color_mode = MODE_COLORS_MODE_SPECIFIC;
Breathing.colors_min = 1;
Breathing.colors_max = 1;
Breathing.colors.resize(1, ToRGBColor(255, 0, 0));
Breathing.value = LAVIEW_TECHNOLOGY_MODE_BREATHING;
modes.push_back(Breathing);
mode SpectrumBreathing;
SpectrumBreathing.name = "Spectrum Breathing";
SpectrumBreathing.flags = MODE_FLAG_HAS_BRIGHTNESS | MODE_FLAG_HAS_SPEED;
SpectrumBreathing.brightness_min = LAVIEW_TECHNOLOGY_BRIGHTNESS_SLOW;
SpectrumBreathing.brightness = LAVIEW_TECHNOLOGY_BRIGHTNESS_NORMAL;
SpectrumBreathing.brightness_max = LAVIEW_TECHNOLOGY_BRIGHTNESS_FAST;
SpectrumBreathing.speed_min = LAVIEW_TECHNOLOGY_SPEED_SLOW;
SpectrumBreathing.speed = LAVIEW_TECHNOLOGY_SPEED_NORMAL;
SpectrumBreathing.speed_max = LAVIEW_TECHNOLOGY_SPEED_FAST;
SpectrumBreathing.color_mode = MODE_COLORS_NONE;
SpectrumBreathing.value = LAVIEW_TECHNOLOGY_MODE_SPECTRUM_BREATHING;
modes.push_back(SpectrumBreathing);
mode RainbowWave;
RainbowWave.name = "Rainbow Wave";
RainbowWave.flags = MODE_FLAG_HAS_BRIGHTNESS | MODE_FLAG_HAS_SPEED;
RainbowWave.brightness_min = LAVIEW_TECHNOLOGY_BRIGHTNESS_SLOW;
RainbowWave.brightness = LAVIEW_TECHNOLOGY_BRIGHTNESS_NORMAL;
RainbowWave.brightness_max = LAVIEW_TECHNOLOGY_BRIGHTNESS_FAST;
RainbowWave.speed_min = LAVIEW_TECHNOLOGY_SPEED_SLOW;
RainbowWave.speed = LAVIEW_TECHNOLOGY_SPEED_NORMAL;
RainbowWave.speed_max = LAVIEW_TECHNOLOGY_SPEED_FAST;
RainbowWave.color_mode = MODE_COLORS_NONE;
RainbowWave.value = LAVIEW_TECHNOLOGY_MODE_RAINBOW_WAVE;
modes.push_back(RainbowWave);
mode Off;
Off.name = "Off";
Off.flags = MODE_FLAG_AUTOMATIC_SAVE;
Off.color_mode = MODE_COLORS_NONE;
Off.value = LAVIEW_TECHNOLOGY_MODE_OFF;
modes.push_back(Off);
SetupZones();
}
void RGBController_LaviewTechnology::SetupZones()
{
/*---------------------------------------------------------*\
| Create a single zone |
\*---------------------------------------------------------*/
zone new_zone;
new_zone.name = "Mouse";
new_zone.type = ZONE_TYPE_SINGLE;
new_zone.leds_min = 1;
new_zone.leds_max = 1;
new_zone.leds_count = 1;
new_zone.matrix_map = NULL;
zones.push_back(new_zone);
/*---------------------------------------------------------*\
| Set up LEDs |
\*---------------------------------------------------------*/
led new_led;
new_led.name = "LED";
leds.push_back(new_led);
SetupColors();
}
RGBController_LaviewTechnology::~RGBController_LaviewTechnology()
{
delete controller;
}
void RGBController_LaviewTechnology::ResizeZone(int /*zone*/, int /*new_size*/)
{
}
void RGBController_LaviewTechnology::DeviceUpdateLEDs()
{
DeviceUpdateMode();
}
void RGBController_LaviewTechnology::UpdateZoneLEDs(int /*zone*/)
{
DeviceUpdateMode();
}
void RGBController_LaviewTechnology::UpdateSingleLED(int /*led*/)
{
DeviceUpdateMode();
}
void RGBController_LaviewTechnology::DeviceUpdateMode()
{
if(modes[active_mode].color_mode == MODE_COLORS_PER_LED)
{
controller->SetMode(modes[active_mode].value, modes[active_mode].brightness, modes[active_mode].speed, &colors[0]);
}
else if(modes[active_mode].color_mode == MODE_COLORS_MODE_SPECIFIC)
{
controller->SetMode(modes[active_mode].value, modes[active_mode].brightness, modes[active_mode].speed, &modes[active_mode].colors[0]);
}
else // MODE_COLORS_NONE
{
controller->SetMode(modes[active_mode].value, modes[active_mode].brightness, modes[active_mode].speed, 0);
}
}

View File

@@ -0,0 +1,34 @@
/*---------------------------------------------------------*\
| RGBController_LaviewTechnology.h |
| |
| RGBController for Laview Tech. mice, including Glorious |
| |
| Kosta A (kostaarvanitis) 27 Oct 2025 |
| |
| This file is part of the OpenRGB project |
| SPDX-License-Identifier: GPL-2.0-or-later |
\*---------------------------------------------------------*/
#pragma once
#include "RGBController.h"
#include "LaviewTechnologyController.h"
class RGBController_LaviewTechnology : public RGBController
{
public:
RGBController_LaviewTechnology(LaviewTechnologyController* controller_ptr);
~RGBController_LaviewTechnology();
void SetupZones();
void ResizeZone(int zone, int new_size);
void DeviceUpdateLEDs();
void UpdateZoneLEDs(int zone);
void UpdateSingleLED(int led);
void DeviceUpdateMode();
private:
LaviewTechnologyController* controller;
};

View File

@@ -0,0 +1,45 @@
/*---------------------------------------------------------*\
| LaviewTechnologyDetect.cpp |
| |
| Detector for Laview Technology brand Mice (Glorious) |
| |
| This file is part of the OpenRGB project |
| SPDX-License-Identifier: GPL-2.0-or-later |
\*---------------------------------------------------------*/
#include <hidapi.h>
#include <sstream>
#include <iomanip>
#include <string>
#include "Detector.h"
#include "LaviewTechnologyController.h"
#include "RGBController.h"
#include "RGBController_LaviewTechnology.h"
#include "LogManager.h"
#define LAVIEW_TECHNOLOGY_VID 0x22D4
#define GLORIOUS_MODEL_I_PID 0x1503 // Wired
/******************************************************************************************\
* *
* DetectLaviewTechnologyMouse *
* *
* Tests the USB address to see if a Laview Technology controller exists there. *
* *
\******************************************************************************************/
static void DetectLaviewTechnologyMouse(hid_device_info* info, const std::string& name)
{
hid_device* dev = hid_open_path(info->path);
if(dev)
{
LaviewTechnologyController* controller = new LaviewTechnologyController(dev, info, name);
RGBController_LaviewTechnology* rgb_controller = new RGBController_LaviewTechnology(controller);
ResourceManager::get()->RegisterRGBController(rgb_controller);
}
}
REGISTER_HID_DETECTOR_IPU("Glorious Model I", DetectLaviewTechnologyMouse, LAVIEW_TECHNOLOGY_VID, GLORIOUS_MODEL_I_PID, 1, 0xFF01, 0x02);