Publish LumaOps source

This commit is contained in:
LumaOps release export
2026-09-03 01:18:36 +02:00
commit 7f1c0e5f71
2363 changed files with 501543 additions and 0 deletions
@@ -0,0 +1,401 @@
/*---------------------------------------------------------*\
| RGBController_Razer.cpp |
| |
| RGBController for Razer devices |
| |
| Adam Honse (CalcProgrammer1) 22 Jan 2021 |
| |
| This file is part of the OpenRGB project |
| SPDX-License-Identifier: GPL-2.0-or-later |
\*---------------------------------------------------------*/
#include "RGBController_Razer.h"
#include "RazerDevices.h"
#include "LogManager.h"
/**------------------------------------------------------------------*\
@name Razer
@category Keyboard,Microphone,Mouse,Mousemat,HeadsetStand,Case,GPU,Accessory
@type USB
@save :robot:
@direct :white_check_mark:
@effects :white_check_mark:
@detectors DetectRazerControllers
@comment
\*-------------------------------------------------------------------*/
RGBController_Razer::RGBController_Razer(RazerController* controller_ptr)
{
controller = controller_ptr;
name = controller->GetName();
vendor = "Razer";
type = controller->GetDeviceType();
description = "Razer Device";
location = controller->GetDeviceLocation();
version = controller->GetFirmwareString();
serial = controller->GetSerialString();
uint8_t max_brightness = controller->GetMaxBrightness();
if(type == DEVICE_TYPE_KEYBOARD)
{
LOG_DEBUG("[%s] Checking Keyboard Layout", name.c_str());
std::string layout = controller->GetKeyboardLayoutString();
LOG_DEBUG("[%s] returned: %s", name.c_str(), layout.c_str());
description.append(", ");
description.append(layout);
}
LOG_DEBUG("[%s] Checking variant", name.c_str());
std::string variant = controller->GetVariantName();
LOG_DEBUG("[%s] returned: %s", name.c_str(), variant.c_str());
description.append(", ");
description.append(variant);
mode Direct;
Direct.name = "Direct";
Direct.value = RAZER_MODE_DIRECT;
Direct.flags = MODE_FLAG_HAS_PER_LED_COLOR | MODE_FLAG_HAS_BRIGHTNESS;
Direct.color_mode = MODE_COLORS_PER_LED;
Direct.brightness_min = 0;
Direct.brightness_max = max_brightness;
Direct.brightness = max_brightness;
modes.push_back(Direct);
mode Off;
Off.name = "Off";
Off.value = RAZER_MODE_OFF;
Off.flags = 0;
Off.color_mode = MODE_COLORS_NONE;
modes.push_back(Off);
mode Static;
Static.name = "Static";
Static.value = RAZER_MODE_STATIC;
Static.flags = MODE_FLAG_HAS_MODE_SPECIFIC_COLOR | MODE_FLAG_HAS_BRIGHTNESS;
Static.color_mode = MODE_COLORS_MODE_SPECIFIC;
Static.colors_min = 1;
Static.colors_max = 1;
Static.colors.resize(1);
Static.brightness_min = 0;
Static.brightness_max = max_brightness;
Static.brightness = max_brightness;
modes.push_back(Static);
if(controller->SupportsBreathing())
{
mode Breathing;
Breathing.name = "Breathing";
Breathing.value = RAZER_MODE_BREATHING;
Breathing.flags = MODE_FLAG_HAS_MODE_SPECIFIC_COLOR | MODE_FLAG_HAS_RANDOM_COLOR | MODE_FLAG_HAS_BRIGHTNESS;
Breathing.color_mode = MODE_COLORS_MODE_SPECIFIC;
Breathing.colors_min = 1;
Breathing.colors_max = 2;
Breathing.colors.resize(1);
Breathing.brightness_min = 0;
Breathing.brightness_max = max_brightness;
Breathing.brightness = max_brightness;
modes.push_back(Breathing);
}
mode SpectrumCycle;
SpectrumCycle.name = "Spectrum Cycle";
SpectrumCycle.value = RAZER_MODE_SPECTRUM_CYCLE;
SpectrumCycle.flags = MODE_FLAG_HAS_BRIGHTNESS;
SpectrumCycle.color_mode = MODE_COLORS_NONE;
SpectrumCycle.brightness_min = 0;
SpectrumCycle.brightness_max = max_brightness;
SpectrumCycle.brightness = max_brightness;
modes.push_back(SpectrumCycle);
if(controller->SupportsWave())
{
mode Wave;
Wave.name = "Wave";
Wave.value = RAZER_MODE_WAVE;
Wave.flags = MODE_FLAG_HAS_DIRECTION_LR | MODE_FLAG_HAS_BRIGHTNESS;
Wave.direction = MODE_DIRECTION_RIGHT;
Wave.color_mode = MODE_COLORS_NONE;
Wave.brightness_min = 0;
Wave.brightness_max = max_brightness;
Wave.brightness = max_brightness;
modes.push_back(Wave);
}
if(controller->SupportsReactive())
{
mode Reactive;
Reactive.name = "Reactive";
Reactive.value = RAZER_MODE_REACTIVE;
Reactive.flags = MODE_FLAG_HAS_MODE_SPECIFIC_COLOR | MODE_FLAG_HAS_BRIGHTNESS;
Reactive.color_mode = MODE_COLORS_MODE_SPECIFIC;
Reactive.colors_min = 1;
Reactive.colors_max = 1;
Reactive.colors.resize(1);
Reactive.brightness_min = 0;
Reactive.brightness_max = max_brightness;
Reactive.brightness = max_brightness;
modes.push_back(Reactive);
}
SetupZones();
}
RGBController_Razer::~RGBController_Razer()
{
delete controller;
}
void RGBController_Razer::SetupZones()
{
unsigned int device_index = controller->GetDeviceIndex();
unsigned char layout_type = controller->GetKeyboardLayoutType();
/*---------------------------------------------------------*\
| Fill in zone information based on device table |
\*---------------------------------------------------------*/
for(unsigned int zone_id = 0; zone_id < RAZER_MAX_ZONES; zone_id++)
{
if(device_list[device_index]->zones[zone_id] != NULL)
{
zone new_zone;
new_zone.name = device_list[device_index]->zones[zone_id]->name;
new_zone.type = device_list[device_index]->zones[zone_id]->type;
new_zone.leds_count = device_list[device_index]->zones[zone_id]->rows * device_list[device_index]->zones[zone_id]->cols;
new_zone.leds_min = new_zone.leds_count;
new_zone.leds_max = new_zone.leds_count;
/*---------------------------------------------------------*\
| If this is a keyboard zone, check if using Keyboard Layout|
| Manager |
\*---------------------------------------------------------*/
if(new_zone.type == ZONE_TYPE_MATRIX)
{
if(device_list[device_index]->layout != NULL &&
(new_zone.name == ZONE_EN_KEYBOARD || new_zone.name == "Keypad"))
{
/*---------------------------------------------------------*\
| Dynamically generate a keyboard layout |
\*---------------------------------------------------------*/
KEYBOARD_LAYOUT new_layout;
switch(layout_type)
{
case RAZER_LAYOUT_TYPE_AZERTY:
new_layout = KEYBOARD_LAYOUT::KEYBOARD_LAYOUT_ISO_AZERTY;
break;
case RAZER_LAYOUT_TYPE_ISO:
new_layout = KEYBOARD_LAYOUT::KEYBOARD_LAYOUT_ISO_QWERTY;
break;
case RAZER_LAYOUT_TYPE_JIS:
new_layout = KEYBOARD_LAYOUT::KEYBOARD_LAYOUT_ANSI_QWERTY;
break;
case RAZER_LAYOUT_TYPE_QWERTZ:
new_layout = KEYBOARD_LAYOUT::KEYBOARD_LAYOUT_ISO_QWERTZ;
break;
default:
new_layout = KEYBOARD_LAYOUT::KEYBOARD_LAYOUT_ANSI_QWERTY;
}
KeyboardLayoutManager new_kb(new_layout, device_list[device_index]->layout->base_size,
device_list[device_index]->layout->key_values);
matrix_map_type * new_map = new matrix_map_type;
new_zone.matrix_map = new_map;
new_map->height = device_list[device_index]->zones[zone_id]->rows;
new_map->width = device_list[device_index]->zones[zone_id]->cols;
new_map->map = new unsigned int[new_map->height * new_map->width];
if(device_list[device_index]->layout->base_size != KEYBOARD_SIZE::KEYBOARD_SIZE_EMPTY ||
!device_list[device_index]->layout->edit_keys.empty())
{
/*---------------------------------------------------------*\
| Minor adjustments to keyboard layout |
\*---------------------------------------------------------*/
keyboard_keymap_overlay_values* temp = device_list[device_index]->layout;
new_kb.ChangeKeys(*temp);
/*---------------------------------------------------------*\
| Matrix map still uses declared zone rows and columns |
| as the packet structure depends on the matrix map |
\*---------------------------------------------------------*/
new_kb.GetKeyMap(new_map->map, KEYBOARD_MAP_FILL_TYPE_INDEX, new_map->height, new_map->width);
}
zones.push_back(new_zone);
/*---------------------------------------------------------*\
| Check the dynamic layout |
\*---------------------------------------------------------*/
if(new_kb.GetKeyCount() > 0)
{
for(std::size_t row = 0; row < zones[zone_id].matrix_map->height; row++)
{
for(std::size_t col = 0; col < zones[zone_id].matrix_map->width; col++)
{
led new_led;
new_led.name = new_kb.GetKeyNameAt((unsigned int)row, (unsigned int)col);
leds.push_back(new_led);
}
}
}
continue;
}
else
{
/*---------------------------------------------------------*\
| Handle all other matrix type zones by filling in all |
| entries |
\*---------------------------------------------------------*/
matrix_map_type * new_map = new matrix_map_type;
new_zone.matrix_map = new_map;
new_map->height = device_list[device_index]->zones[zone_id]->rows;
new_map->width = device_list[device_index]->zones[zone_id]->cols;
new_map->map = new unsigned int[new_map->height * new_map->width];
for(unsigned int y = 0; y < new_map->height; y++)
{
for(unsigned int x = 0; x < new_map->width; x++)
{
new_map->map[(y * new_map->width) + x] = (y * new_map->width) + x;
}
}
}
}
else
{
new_zone.matrix_map = NULL;
}
zones.push_back(new_zone);
for (unsigned int row_id = 0; row_id < device_list[device_index]->zones[zone_id]->rows; row_id++)
{
for (unsigned int col_id = 0; col_id < device_list[device_index]->zones[zone_id]->cols; col_id++)
{
led* new_led = new led();
new_led->name = device_list[device_index]->zones[zone_id]->name;
if(zones[zone_id].leds_count > 1)
{
new_led->name.append(" LED ");
new_led->name.append(std::to_string(col_id + 1));
}
leds.push_back(*new_led);
}
}
}
}
SetupColors();
}
void RGBController_Razer::ResizeZone(int /*zone*/, int /*new_size*/)
{
/*---------------------------------------------------------*\
| This device does not support resizing zones |
\*---------------------------------------------------------*/
}
void RGBController_Razer::DeviceUpdateLEDs()
{
controller->SetLEDs(&colors[0]);
}
void RGBController_Razer::UpdateZoneLEDs(int /*zone*/)
{
DeviceUpdateLEDs();
}
void RGBController_Razer::UpdateSingleLED(int /*led*/)
{
DeviceUpdateLEDs();
}
void RGBController_Razer::DeviceUpdateMode()
{
switch(modes[active_mode].value)
{
case RAZER_MODE_OFF:
controller->SetModeOff();
break;
case RAZER_MODE_STATIC:
if(modes[active_mode].colors.size() == 1)
{
unsigned char red = RGBGetRValue(modes[active_mode].colors[0]);
unsigned char grn = RGBGetGValue(modes[active_mode].colors[0]);
unsigned char blu = RGBGetBValue(modes[active_mode].colors[0]);
controller->SetModeStatic(red, grn, blu);
}
break;
case RAZER_MODE_BREATHING:
if(modes[active_mode].color_mode == MODE_COLORS_RANDOM)
{
controller->SetModeBreathingRandom();
}
else if(modes[active_mode].color_mode == MODE_COLORS_MODE_SPECIFIC)
{
if(modes[active_mode].colors.size() == 1)
{
unsigned char red = RGBGetRValue(modes[active_mode].colors[0]);
unsigned char grn = RGBGetGValue(modes[active_mode].colors[0]);
unsigned char blu = RGBGetBValue(modes[active_mode].colors[0]);
controller->SetModeBreathingOneColor(red, grn, blu);
}
else if(modes[active_mode].colors.size() == 2)
{
unsigned char red1 = RGBGetRValue(modes[active_mode].colors[0]);
unsigned char grn1 = RGBGetGValue(modes[active_mode].colors[0]);
unsigned char blu1 = RGBGetBValue(modes[active_mode].colors[0]);
unsigned char red2 = RGBGetRValue(modes[active_mode].colors[1]);
unsigned char grn2 = RGBGetGValue(modes[active_mode].colors[1]);
unsigned char blu2 = RGBGetBValue(modes[active_mode].colors[1]);
controller->SetModeBreathingTwoColors(red1, grn1, blu1, red2, grn2, blu2);
}
}
break;
case RAZER_MODE_SPECTRUM_CYCLE:
controller->SetModeSpectrumCycle();
break;
case RAZER_MODE_WAVE:
switch(modes[active_mode].direction)
{
case MODE_DIRECTION_LEFT:
controller->SetModeWave(2);
break;
default:
controller->SetModeWave(1);
break;
}
break;
}
if(modes[active_mode].flags & MODE_FLAG_HAS_BRIGHTNESS)
{
controller->SetBrightness(modes[active_mode].brightness);
}
else
{
controller->SetBrightness(255);
}
}
@@ -0,0 +1,48 @@
/*---------------------------------------------------------*\
| RGBController_Razer.h |
| |
| RGBController for Razer devices |
| |
| Adam Honse (CalcProgrammer1) 22 Jan 2021 |
| |
| This file is part of the OpenRGB project |
| SPDX-License-Identifier: GPL-2.0-or-later |
\*---------------------------------------------------------*/
#pragma once
#include "RGBController.h"
#include "RazerController.h"
#define NA 0xFFFFFFFF
enum
{
RAZER_MODE_DIRECT,
RAZER_MODE_OFF,
RAZER_MODE_STATIC,
RAZER_MODE_BREATHING,
RAZER_MODE_SPECTRUM_CYCLE,
RAZER_MODE_WAVE,
RAZER_MODE_REACTIVE,
};
class RGBController_Razer : public RGBController
{
public:
RGBController_Razer(RazerController* controller_ptr);
~RGBController_Razer();
void SetupZones();
void ResizeZone(int zone, int new_size);
void DeviceUpdateLEDs();
void UpdateZoneLEDs(int zone);
void UpdateSingleLED(int led);
void DeviceUpdateMode();
private:
RazerController* controller;
};
@@ -0,0 +1,357 @@
/*---------------------------------------------------------*\
| RGBController_RazerAddressable.cpp |
| |
| RGBController for Razer ARGB Controller |
| |
| Adam Honse (CalcProgrammer1) 11 Apr 2021 |
| |
| This file is part of the OpenRGB project |
| SPDX-License-Identifier: GPL-2.0-or-later |
\*---------------------------------------------------------*/
#include <string.h>
#include "RGBController_RazerAddressable.h"
#include "RazerDevices.h"
/**------------------------------------------------------------------*\
@name Razer ARGB
@category LEDStrip
@type USB
@save :robot:
@direct :white_check_mark:
@effects :white_check_mark:
@detectors DetectRazerARGBControllers
@comment
\*-------------------------------------------------------------------*/
RGBController_RazerAddressable::RGBController_RazerAddressable(RazerController* controller_ptr)
{
controller = controller_ptr;
name = controller->GetName();
vendor = "Razer";
type = controller->GetDeviceType();
description = "Razer Addressable Device";
location = controller->GetDeviceLocation();
version = controller->GetFirmwareString();
serial = controller->GetSerialString();
mode Direct;
Direct.name = "Direct";
Direct.value = RAZER_ADDRESSABLE_MODE_DIRECT;
Direct.flags = MODE_FLAG_HAS_PER_LED_COLOR | MODE_FLAG_HAS_BRIGHTNESS;
Direct.color_mode = MODE_COLORS_PER_LED;
Direct.brightness_min = 0;
Direct.brightness_max = 255;
Direct.brightness = 255;
modes.push_back(Direct);
mode Off;
Off.name = "Off";
Off.value = RAZER_ADDRESSABLE_MODE_OFF;
Off.flags = 0;
Off.color_mode = MODE_COLORS_NONE;
modes.push_back(Off);
mode Static;
Static.name = "Static";
Static.value = RAZER_ADDRESSABLE_MODE_STATIC;
Static.flags = MODE_FLAG_HAS_MODE_SPECIFIC_COLOR | MODE_FLAG_HAS_BRIGHTNESS;
Static.color_mode = MODE_COLORS_MODE_SPECIFIC;
Static.colors_min = 1;
Static.colors_max = 1;
Static.colors.resize(1);
Static.brightness_min = 0;
Static.brightness_max = 255;
Static.brightness = 255;
modes.push_back(Static);
mode Breathing;
Breathing.name = "Breathing";
Breathing.value = RAZER_ADDRESSABLE_MODE_BREATHING;
Breathing.flags = MODE_FLAG_HAS_MODE_SPECIFIC_COLOR | MODE_FLAG_HAS_RANDOM_COLOR | MODE_FLAG_HAS_BRIGHTNESS;
Breathing.color_mode = MODE_COLORS_MODE_SPECIFIC;
Breathing.colors_min = 1;
Breathing.colors_max = 2;
Breathing.colors.resize(1);
Breathing.brightness_min = 0;
Breathing.brightness_max = 255;
Breathing.brightness = 255;
modes.push_back(Breathing);
mode SpectrumCycle;
SpectrumCycle.name = "Spectrum Cycle";
SpectrumCycle.value = RAZER_ADDRESSABLE_MODE_SPECTRUM_CYCLE;
SpectrumCycle.flags = MODE_FLAG_HAS_BRIGHTNESS;
SpectrumCycle.color_mode = MODE_COLORS_NONE;
SpectrumCycle.brightness_min = 0;
SpectrumCycle.brightness_max = 255;
SpectrumCycle.brightness = 255;
modes.push_back(SpectrumCycle);
if(controller->SupportsWave())
{
mode Wave;
Wave.name = "Wave";
Wave.value = RAZER_ADDRESSABLE_MODE_WAVE;
Wave.flags = MODE_FLAG_HAS_DIRECTION_LR | MODE_FLAG_HAS_BRIGHTNESS;
Wave.direction = MODE_DIRECTION_RIGHT;
Wave.color_mode = MODE_COLORS_NONE;
Wave.brightness_min = 0;
Wave.brightness_max = 255;
Wave.brightness = 255;
modes.push_back(Wave);
}
if(controller->SupportsReactive())
{
mode Reactive;
Reactive.name = "Reactive";
Reactive.value = RAZER_ADDRESSABLE_MODE_REACTIVE;
Reactive.flags = MODE_FLAG_HAS_MODE_SPECIFIC_COLOR | MODE_FLAG_HAS_BRIGHTNESS;
Reactive.color_mode = MODE_COLORS_MODE_SPECIFIC;
Reactive.colors_min = 1;
Reactive.colors_max = 1;
Reactive.colors.resize(1);
Reactive.brightness_min = 0;
Reactive.brightness_max = 255;
Reactive.brightness = 255;
modes.push_back(Reactive);
}
SetupZones();
}
RGBController_RazerAddressable::~RGBController_RazerAddressable()
{
delete controller;
}
void RGBController_RazerAddressable::SetupZones()
{
unsigned int device_index = controller->GetDeviceIndex();
unsigned int zone_count = 0;
/*-------------------------------------------------*\
| Only set LED count on the first run |
\*-------------------------------------------------*/
bool first_run = false;
if(zones.size() == 0)
{
first_run = true;
}
/*-------------------------------------------------*\
| Count the number of zones for this device |
\*-------------------------------------------------*/
for(unsigned int zone_id = 0; zone_id < RAZER_MAX_ZONES; zone_id++)
{
if(device_list[device_index]->zones[zone_id] != NULL)
{
zone_count++;
}
}
/*-------------------------------------------------*\
| Clear any existing color/LED configuration |
\*-------------------------------------------------*/
leds.clear();
colors.clear();
zones.resize(zone_count);
/*---------------------------------------------------------*\
| Fill in zone information based on device table |
\*---------------------------------------------------------*/
zone_count = 0;
for(unsigned int zone_id = 0; zone_id < RAZER_MAX_ZONES; zone_id++)
{
if(device_list[device_index]->zones[zone_id] != NULL)
{
zones[zone_count].name = device_list[device_index]->zones[zone_id]->name;
zones[zone_count].type = device_list[device_index]->zones[zone_id]->type;
zones[zone_count].leds_min = 0;
zones[zone_count].leds_max = device_list[device_index]->zones[zone_id]->rows * device_list[device_index]->zones[zone_id]->cols;
if(first_run)
{
zones[zone_count].leds_count = 0;
}
if(zones[zone_count].type == ZONE_TYPE_MATRIX)
{
matrix_map_type * new_map = new matrix_map_type;
zones[zone_count].matrix_map = new_map;
new_map->height = device_list[device_index]->zones[zone_id]->rows;
new_map->width = device_list[device_index]->zones[zone_id]->cols;
new_map->map = new unsigned int[new_map->height * new_map->width];
for(unsigned int y = 0; y < new_map->height; y++)
{
for(unsigned int x = 0; x < new_map->width; x++)
{
new_map->map[(y * new_map->width) + x] = (y * new_map->width) + x;
}
}
}
else
{
zones[zone_count].matrix_map = NULL;
}
zone_count++;
}
}
for(unsigned int zone_id = 0; zone_id < zones.size(); zone_id++)
{
for(unsigned int led_id = 0; led_id < zones[zone_id].leds_count; led_id++)
{
led new_led;
new_led.name = "Channel " + std::to_string(zone_id + 1) + ", LED " + std::to_string(led_id + 1);
leds.push_back(new_led);
}
}
SetupColors();
}
void RGBController_RazerAddressable::ResizeZone(int zone, int new_size)
{
/*---------------------------------------------------------*\
| Only the Razer Chroma Addressable RGB Controller supports |
| zone resizing |
\*---------------------------------------------------------*/
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;
controller->SetAddressableZoneSizes(zones[0].leds_count,
zones[1].leds_count,
zones[2].leds_count,
zones[3].leds_count,
zones[4].leds_count,
zones[5].leds_count);
SetupZones();
}
}
void RGBController_RazerAddressable::DeviceUpdateLEDs()
{
/*---------------------------------------------------------*\
| Only the Razer Chroma Addressable RGB Controller supports |
| zone resizing |
\*---------------------------------------------------------*/
RGBColor colors_buf[80 * 6];
for(unsigned int zone_id = 0; zone_id < zones.size(); zone_id++)
{
memcpy(&colors_buf[(80 * zone_id)], zones[zone_id].colors, sizeof(RGBColor) * zones[zone_id].leds_count);
}
controller->SetLEDs(&colors_buf[0]);
}
void RGBController_RazerAddressable::UpdateZoneLEDs(int /*zone*/)
{
DeviceUpdateLEDs();
}
void RGBController_RazerAddressable::UpdateSingleLED(int /*led*/)
{
DeviceUpdateLEDs();
}
void RGBController_RazerAddressable::DeviceUpdateMode()
{
switch(modes[active_mode].value)
{
case RAZER_ADDRESSABLE_MODE_DIRECT:
/*---------------------------------------------------------*\
| Controller does not preserve the LEDs for direct mode. |
| We have to restore them. |
\*---------------------------------------------------------*/
DeviceUpdateLEDs();
break;
case RAZER_ADDRESSABLE_MODE_OFF:
controller->SetModeOff();
break;
case RAZER_ADDRESSABLE_MODE_STATIC:
if(modes[active_mode].colors.size() == 1)
{
unsigned char red = RGBGetRValue(modes[active_mode].colors[0]);
unsigned char grn = RGBGetGValue(modes[active_mode].colors[0]);
unsigned char blu = RGBGetBValue(modes[active_mode].colors[0]);
controller->SetModeStatic(red, grn, blu);
}
break;
case RAZER_ADDRESSABLE_MODE_BREATHING:
if(modes[active_mode].color_mode == MODE_COLORS_RANDOM)
{
controller->SetModeBreathingRandom();
}
else if(modes[active_mode].color_mode == MODE_COLORS_MODE_SPECIFIC)
{
if(modes[active_mode].colors.size() == 1)
{
unsigned char red = RGBGetRValue(modes[active_mode].colors[0]);
unsigned char grn = RGBGetGValue(modes[active_mode].colors[0]);
unsigned char blu = RGBGetBValue(modes[active_mode].colors[0]);
controller->SetModeBreathingOneColor(red, grn, blu);
}
else if(modes[active_mode].colors.size() == 2)
{
unsigned char red1 = RGBGetRValue(modes[active_mode].colors[0]);
unsigned char grn1 = RGBGetGValue(modes[active_mode].colors[0]);
unsigned char blu1 = RGBGetBValue(modes[active_mode].colors[0]);
unsigned char red2 = RGBGetRValue(modes[active_mode].colors[1]);
unsigned char grn2 = RGBGetGValue(modes[active_mode].colors[1]);
unsigned char blu2 = RGBGetBValue(modes[active_mode].colors[1]);
controller->SetModeBreathingTwoColors(red1, grn1, blu1, red2, grn2, blu2);
}
}
break;
case RAZER_ADDRESSABLE_MODE_SPECTRUM_CYCLE:
controller->SetModeSpectrumCycle();
break;
case RAZER_ADDRESSABLE_MODE_WAVE:
switch(modes[active_mode].direction)
{
case MODE_DIRECTION_LEFT:
controller->SetModeWave(2);
break;
default:
controller->SetModeWave(1);
break;
}
break;
}
if(modes[active_mode].flags & MODE_FLAG_HAS_BRIGHTNESS)
{
controller->SetBrightness(modes[active_mode].brightness);
}
else
{
controller->SetBrightness(255);
}
}
@@ -0,0 +1,46 @@
/*---------------------------------------------------------*\
| RGBController_RazerAddressable.h |
| |
| RGBController for Razer ARGB Controller |
| |
| Adam Honse (CalcProgrammer1) 11 Apr 2021 |
| |
| This file is part of the OpenRGB project |
| SPDX-License-Identifier: GPL-2.0-or-later |
\*---------------------------------------------------------*/
#pragma once
#include "RGBController.h"
#include "RazerController.h"
enum
{
RAZER_ADDRESSABLE_MODE_DIRECT,
RAZER_ADDRESSABLE_MODE_OFF,
RAZER_ADDRESSABLE_MODE_STATIC,
RAZER_ADDRESSABLE_MODE_BREATHING,
RAZER_ADDRESSABLE_MODE_SPECTRUM_CYCLE,
RAZER_ADDRESSABLE_MODE_WAVE,
RAZER_ADDRESSABLE_MODE_REACTIVE,
};
class RGBController_RazerAddressable : public RGBController
{
public:
RGBController_RazerAddressable(RazerController* controller_ptr);
~RGBController_RazerAddressable();
void SetupZones();
void ResizeZone(int zone, int new_size);
void DeviceUpdateLEDs();
void UpdateZoneLEDs(int zone);
void UpdateSingleLED(int led);
void DeviceUpdateMode();
private:
RazerController* controller;
};
File diff suppressed because it is too large Load Diff
@@ -0,0 +1,358 @@
/*---------------------------------------------------------*\
| RazerController.h |
| |
| Driver for Razer devices |
| |
| Adam Honse (CalcProgrammer1) 22 Jan 2021 |
| |
| This file is part of the OpenRGB project |
| SPDX-License-Identifier: GPL-2.0-or-later |
\*---------------------------------------------------------*/
#pragma once
#include <atomic>
#include <chrono>
#include <string>
#include <thread>
#include <hidapi.h>
#include "RGBController.h"
#include "DeviceGuardManager.h"
/*---------------------------------------------------------*\
| Struct packing macro for GCC and MSVC |
\*---------------------------------------------------------*/
#ifdef __GNUC__
#define PACK( __Declaration__ ) __Declaration__ __attribute__((__packed__))
#endif
#ifdef _MSC_VER
#define PACK( __Declaration__ ) __pragma( pack(push, 1) ) __Declaration__ __pragma( pack(pop))
#endif
/*---------------------------------------------------------*\
| Razer Device Mode IDs |
\*---------------------------------------------------------*/
enum
{
RAZER_DEVICE_MODE_HARDWARE = 0x00,
RAZER_DEVICE_MODE_SOFTWARE = 0x03,
};
/*---------------------------------------------------------*\
| Razer Command IDs |
\*---------------------------------------------------------*/
enum
{
/*-----------------------------------------------------*\
| Set Commands |
\*-----------------------------------------------------*/
RAZER_COMMAND_ID_SET_LED_STATE = 0x00,
RAZER_COMMAND_ID_SET_DEVICE_MODE = 0x04,
/*-----------------------------------------------------*\
| Get Commands |
\*-----------------------------------------------------*/
RAZER_COMMAND_ID_GET_LED_STATE = 0x80,
RAZER_COMMAND_ID_GET_FIRMWARE_VERSION = 0x81,
RAZER_COMMAND_ID_GET_SERIAL_STRING = 0x82,
RAZER_COMMAND_ID_GET_DEVICE_MODE = 0x84,
RAZER_COMMAND_ID_GET_KEYBOARD_INFO = 0x86,
};
/*---------------------------------------------------------*\
| Razer Storage Flags |
\*---------------------------------------------------------*/
enum
{
RAZER_STORAGE_NO_SAVE = 0x00,
RAZER_STORAGE_SAVE = 0x01,
};
/*---------------------------------------------------------*\
| Razer LED IDs |
\*---------------------------------------------------------*/
enum
{
RAZER_LED_ID_ZERO = 0x00,
RAZER_LED_ID_SCROLL_WHEEL = 0x01,
RAZER_LED_ID_BATTERY = 0x03,
RAZER_LED_ID_LOGO = 0x04,
RAZER_LED_ID_BACKLIGHT = 0x05,
RAZER_LED_ID_MACRO = 0x07,
RAZER_LED_ID_GAME = 0x08,
RAZER_LED_ID_PROFILE_RED = 0x0C,
RAZER_LED_ID_PROFILE_GREEN = 0x0D,
RAZER_LED_ID_PROFILE_BLUE = 0x0E,
RAZER_LED_ID_RIGHT_SIDE = 0x10,
RAZER_LED_ID_LEFT_SIDE = 0x11,
RAZER_LED_ID_ARGB_CH_1 = 0x1A,
RAZER_LED_ID_ARGB_CH_2 = 0x1B,
RAZER_LED_ID_ARGB_CH_3 = 0x1C,
RAZER_LED_ID_ARGB_CH_4 = 0x1D,
RAZER_LED_ID_ARGB_CH_5 = 0x1E,
RAZER_LED_ID_ARGB_CH_6 = 0x1F,
};
/*---------------------------------------------------------*\
| Razer Matrix Type |
\*---------------------------------------------------------*/
enum
{
RAZER_MATRIX_TYPE_NONE = 0,
RAZER_MATRIX_TYPE_STANDARD = 1,
RAZER_MATRIX_TYPE_EXTENDED = 2,
RAZER_MATRIX_TYPE_LINEAR = 3,
RAZER_MATRIX_TYPE_EXTENDED_ARGB = 4,
RAZER_MATRIX_TYPE_CUSTOM = 5,
};
/*---------------------------------------------------------*\
| Razer Keyboard Layout |
\*---------------------------------------------------------*/
enum
{
RAZER_KEYBOARD_LAYOUT_NONE = 0,
RAZER_KEYBOARD_LAYOUT_US = 1,
RAZER_KEYBOARD_LAYOUT_GREEK = 2,
RAZER_KEYBOARD_LAYOUT_GERMAN = 3,
RAZER_KEYBOARD_LAYOUT_FRENCH = 4,
RAZER_KEYBOARD_LAYOUT_RUSSIAN = 5,
RAZER_KEYBOARD_LAYOUT_UK = 6,
RAZER_KEYBOARD_LAYOUT_NORDIC = 7,
RAZER_KEYBOARD_LAYOUT_CHT = 8,
RAZER_KEYBOARD_LAYOUT_KOREAN = 9,
RAZER_KEYBOARD_LAYOUT_TURKISH = 10,
RAZER_KEYBOARD_LAYOUT_THAILAND = 11,
RAZER_KEYBOARD_LAYOUT_JAPAN = 12,
RAZER_KEYBOARD_LAYOUT_PORTUGESE_BRAZIL = 13,
RAZER_KEYBOARD_LAYOUT_SPANISH_LATIN_AMERICAN = 14,
RAZER_KEYBOARD_LAYOUT_SWISS = 15,
RAZER_KEYBOARD_LAYOUT_SPANISH_EUR = 16,
RAZER_KEYBOARD_LAYOUT_ITALIAN = 17,
RAZER_KEYBOARD_LAYOUT_PORTUGESE_PORTUGA = 18,
RAZER_KEYBOARD_LAYOUT_HEBREW = 19,
RAZER_KEYBOARD_LAYOUT_ARABIC = 20,
};
/*---------------------------------------------------------*\
| Razer Layout Type |
\*---------------------------------------------------------*/
enum
{
RAZER_LAYOUT_TYPE_NONE = 0x00,
RAZER_LAYOUT_TYPE_ANSI = 0x01,
RAZER_LAYOUT_TYPE_ISO = 0x02,
RAZER_LAYOUT_TYPE_JIS = 0x04,
RAZER_LAYOUT_TYPE_QWERTZ = 0x08,
RAZER_LAYOUT_TYPE_AZERTY = 0x10,
RAZER_LAYOUT_TYPE_ALL = RAZER_LAYOUT_TYPE_ANSI | RAZER_LAYOUT_TYPE_ISO
| RAZER_LAYOUT_TYPE_JIS | RAZER_LAYOUT_TYPE_QWERTZ
};
/*---------------------------------------------------------*\
| Razer Keyboard Variant |
\*---------------------------------------------------------*/
enum
{
RAZER_KEYBOARD_VARIANT_BLACK = 0x00,
RAZER_KEYBOARD_VARIANT_QUARTZ = 0x80,
RAZER_KEYBOARD_VARIANT_MERCURY = 0x82,
};
/*---------------------------------------------------------*\
| Razer Report Type (taken from OpenRazer) |
\*---------------------------------------------------------*/
struct razer_rgb
{
unsigned char r,g,b;
};
union transaction_id_union
{
unsigned char id;
struct transaction_parts
{
unsigned char device : 3;
unsigned char id : 5;
} parts;
};
union command_id_union
{
unsigned char id;
struct command_id_parts
{
unsigned char direction : 1;
unsigned char id : 7;
} parts;
};
PACK(struct razer_report
{
unsigned char report_id;
unsigned char status;
union transaction_id_union transaction_id;
unsigned short remaining_packets;
unsigned char protocol_type;
unsigned char data_size;
unsigned char command_class;
union command_id_union command_id;
unsigned char arguments[80];
unsigned char crc;
unsigned char reserved;
});
/*---------------------------------------------------------*\
| Razer ARGB Report Type (taken from OpenRazer) |
\*---------------------------------------------------------*/
PACK(struct razer_argb_report
{
unsigned char hid_id;
unsigned char report_id;
unsigned char channel_1;
unsigned char channel_2;
unsigned char pad;
unsigned char last_idx;
unsigned char color_data[315];
});
class RazerController
{
public:
RazerController(hid_device* dev_handle, hid_device* dev_argb_handle, const char* path, unsigned short pid, std::string dev_name);
~RazerController();
unsigned int GetDeviceIndex();
device_type GetDeviceType();
std::string GetDeviceLocation();
std::string GetFirmwareString();
std::string GetName();
std::string GetSerialString();
unsigned char GetMaxBrightness();
unsigned char GetKeyboardLayoutType();
std::string GetKeyboardLayoutString();
std::string GetVariantName();
void SetBrightness(unsigned char brightness);
void SetLEDs(RGBColor* colors);
void SetAddressableZoneSizes(unsigned char zone_1_size, unsigned char zone_2_size, unsigned char zone_3_size, unsigned char zone_4_size, unsigned char zone_5_size, unsigned char zone_6_size);
void SetModeBreathingRandom();
void SetModeBreathingOneColor(unsigned char red, unsigned char grn, unsigned char blu);
void SetModeBreathingTwoColors(unsigned char r1, unsigned char g1, unsigned char b1, unsigned char r2, unsigned char g2, unsigned char b2);
void SetModeOff();
void SetModeSpectrumCycle();
void SetModeStatic(unsigned char red, unsigned char grn, unsigned char blu);
void SetModeWave(unsigned char direction);
bool SupportsBreathing();
bool SupportsReactive();
bool SupportsWave();
private:
hid_device* dev;
hid_device* dev_argb;
unsigned short dev_pid;
/*---------------------------------------------------------*\
| Device-specific protocol settings |
\*---------------------------------------------------------*/
unsigned char dev_transaction_id;
unsigned char dev_led_id;
/*---------------------------------------------------------*\
| Device information strings |
\*---------------------------------------------------------*/
std::string firmware_version;
std::string location;
std::string name;
/*---------------------------------------------------------*\
| Index of device in Razer device list |
\*---------------------------------------------------------*/
unsigned int device_index;
/*---------------------------------------------------------*\
| HID report index for request and response |
\*---------------------------------------------------------*/
unsigned char report_index;
unsigned char response_index;
/*---------------------------------------------------------*\
| Matrix type |
\*---------------------------------------------------------*/
unsigned char matrix_type;
/*---------------------------------------------------------*\
| Mutex lock to sync with other softwares |
\*---------------------------------------------------------*/
DeviceGuardManager* guard_manager_ptr;
/*---------------------------------------------------------*\
| Private functions based on OpenRazer |
\*---------------------------------------------------------*/
unsigned char razer_calculate_crc(razer_report* report);
razer_report razer_create_report(unsigned char command_class, unsigned char command_id, unsigned char data_size);
razer_report razer_create_response();
razer_report razer_create_addressable_size_report(unsigned char zone_1_size, unsigned char zone_2_size, unsigned char zone_3_size, unsigned char zone_4_size, unsigned char zone_5_size, unsigned char zone_6_size);
razer_report razer_create_addressable_startup_detect_report(bool enable);
razer_report razer_create_brightness_extended_matrix_report(unsigned char variable_storage, unsigned char led_id, unsigned char brightness);
razer_report razer_create_brightness_standard_report(unsigned char variable_storage, unsigned char led_id, unsigned char brightness);
razer_argb_report razer_create_custom_frame_argb_report(unsigned char row_index, unsigned char stop_col, unsigned char* rgb_data);
razer_report razer_create_custom_frame_linear_report(unsigned char start_col, unsigned char stop_col, unsigned char* rgb_data);
razer_report razer_create_custom_frame_extended_matrix_report(unsigned char row_index, unsigned char start_col, unsigned char stop_col, unsigned char* rgb_data);
razer_report razer_create_custom_frame_standard_matrix_report(unsigned char row_index, unsigned char start_col, unsigned char stop_col, unsigned char* rgb_data);
razer_report razer_create_device_mode_report(unsigned char mode, unsigned char param);
razer_report razer_create_mode_breathing_one_color_extended_matrix_report(unsigned char variable_storage, unsigned char led_id, unsigned char red, unsigned char grn, unsigned char blu);
razer_report razer_create_mode_breathing_one_color_standard_matrix_report(unsigned char variable_storage, unsigned char led_id, unsigned char red, unsigned char grn, unsigned char blu);
razer_report razer_create_mode_breathing_random_extended_matrix_report(unsigned char variable_storage, unsigned char led_id);
razer_report razer_create_mode_breathing_random_standard_matrix_report(unsigned char variable_storage, unsigned char led_id);
razer_report razer_create_mode_breathing_two_colors_extended_matrix_report(unsigned char variable_storage, unsigned char led_id, unsigned char r1, unsigned char g1, unsigned char b1, unsigned char r2, unsigned char g2, unsigned char b2);
razer_report razer_create_mode_breathing_two_colors_standard_matrix_report(unsigned char variable_storage, unsigned char led_id, unsigned char r1, unsigned char g1, unsigned char b1, unsigned char r2, unsigned char g2, unsigned char b2);
razer_report razer_create_mode_custom_extended_matrix_report();
razer_report razer_create_mode_custom_standard_matrix_report(unsigned char variable_storage);
razer_report razer_create_mode_none_extended_matrix_report(unsigned char variable_storage, unsigned char led_id);
razer_report razer_create_mode_none_standard_matrix_report(unsigned char variable_storage, unsigned char led_id);
razer_report razer_create_mode_spectrum_cycle_extended_matrix_report(unsigned char variable_storage, unsigned char led_id);
razer_report razer_create_mode_spectrum_cycle_standard_matrix_report(unsigned char variable_storage, unsigned char led_id);
razer_report razer_create_mode_static_extended_matrix_report(unsigned char variable_storage, unsigned char led_id, unsigned char red, unsigned char grn, unsigned char blu);
razer_report razer_create_mode_static_standard_matrix_report(unsigned char variable_storage, unsigned char led_id, unsigned char red, unsigned char grn, unsigned char blu);
razer_report razer_create_mode_wave_extended_matrix_report(unsigned char variable_storage, unsigned char led_id, unsigned char direction);
razer_report razer_create_mode_wave_standard_matrix_report(unsigned char variable_storage, unsigned char led_id, unsigned char direction);
razer_report razer_create_set_led_effect_report(unsigned char variable_storage, unsigned char led_id, unsigned char effect);
razer_report razer_create_set_led_rgb_report(unsigned char variable_storage, unsigned char led_id, unsigned char* rgb_data);
unsigned char razer_get_device_mode();
std::string razer_get_firmware();
std::string razer_get_serial();
void razer_get_keyboard_info(unsigned char* layout, unsigned char* variant);
void razer_set_brightness(unsigned char brightness);
void razer_set_custom_frame(unsigned char row_index, unsigned char start_col, unsigned char stop_col, unsigned char* rgb_data);
void razer_set_device_mode(unsigned char device_mode);
void razer_set_mode_breathing_random();
void razer_set_mode_breathing_one_color(unsigned char red, unsigned char grn, unsigned char blu);
void razer_set_mode_breathing_two_colors(unsigned char r1, unsigned char g1, unsigned char b1, unsigned char r2, unsigned char g2, unsigned char b2);
void razer_set_mode_custom();
void razer_set_mode_none();
void razer_set_mode_spectrum_cycle();
void razer_set_mode_static(unsigned char red, unsigned char grn, unsigned char blu);
void razer_set_mode_wave(unsigned char direction);
int razer_usb_receive(razer_report* report);
int razer_usb_send(razer_report* report);
int razer_usb_send_argb(razer_argb_report* report);
std::chrono::time_point<std::chrono::steady_clock> last_update_time;
std::atomic<bool> keepalive_thread_run;
std::thread * keepalive_thread;
void KeepaliveThreadFunction();
};
@@ -0,0 +1,464 @@
/*---------------------------------------------------------*\
| RazerControllerDetect.cpp |
| |
| Detector for Razer devices |
| |
| Adam Honse (CalcProgrammer1) 22 Jan 2021 |
| |
| This file is part of the OpenRGB project |
| SPDX-License-Identifier: GPL-2.0-or-later |
\*---------------------------------------------------------*/
#include <unordered_set>
#include <hidapi.h>
#include "Detector.h"
#include "RazerController.h"
#include "RazerKrakenController.h"
#include "RazerKrakenV3Controller.h"
#include "RazerKrakenV4Controller.h"
#include "RazerHanboController.h"
#include "RazerDevices.h"
#include "ResourceManager.h"
#include "RGBController_Razer.h"
#include "RGBController_RazerAddressable.h"
#include "RGBController_RazerKraken.h"
#include "RGBController_RazerKrakenV3.h"
#include "RGBController_RazerKrakenV4.h"
#include "RGBController_RazerHanbo.h"
/******************************************************************************************\
* *
* DetectRazerControllers *
* *
* Tests the USB address to see if a Razer controller exists there. *
* *
\******************************************************************************************/
void DetectRazerControllers(hid_device_info* info, const std::string& name)
{
hid_device* dev = hid_open_path(info->path);
if(dev)
{
RazerController* controller = new RazerController(dev, dev, info->path, info->product_id, name);
RGBController_Razer* rgb_controller = new RGBController_Razer(controller);
ResourceManager::get()->RegisterRGBController(rgb_controller);
}
} /* DetectRazerControllers() */
/******************************************************************************************\
* *
* DetectRazerARGBControllers *
* *
* Tests the USB address to see if a Razer ARGB controller exists there. *
* *
\******************************************************************************************/
/*---------------------------------------------------------------------*\
| Tracks the paths used in DetectRazerARGBControllers so multiple Razer |
| devices can be detected without all controlling the same device. |
\*---------------------------------------------------------------------*/
static std::unordered_set<std::string> used_paths;
/*--------------------------------------------------------------------------------*\
| Removes all entries in used_paths so device discovery does not skip any of them. |
\*--------------------------------------------------------------------------------*/
void ResetRazerARGBControllersPaths()
{
used_paths.clear();
}
void DetectRazerARGBControllers(hid_device_info* info, const std::string& name)
{
/*-------------------------------------------------------------------------------------------------*\
| Razer's ARGB controller uses two different interfaces, one for 90-byte Razer report packets and |
| one for 320-byte ARGB packets. Interface 0 for 90-byte and interface 1 for 320-byte. |
| |
| Create a local copy of the HID enumerations for the Razer ARGB controller VID/PID and iterate |
| through it. This prevents detection from failing if interface 1 comes before interface 0 in the |
| main info list. |
\*-------------------------------------------------------------------------------------------------*/
hid_device* dev_interface_0 = nullptr;
hid_device* dev_interface_1 = nullptr;
hid_device_info* info_full = hid_enumerate(RAZER_VID, RAZER_CHROMA_ADDRESSABLE_RGB_CONTROLLER_PID);
hid_device_info* info_temp = info_full;
/*--------------------------------------------------------------------------------------------*\
| Keep track of paths so they can be added to used_paths only if both interfaces can be found. |
\*--------------------------------------------------------------------------------------------*/
std::string dev_interface_0_path;
std::string dev_interface_1_path;
while(info_temp)
{
/*----------------------------------------------------------------------------*\
| Check for paths used on an already registered Razer ARGB controller to avoid |
| registering multiple controllers that refer to the same physical hardware. |
\*----------------------------------------------------------------------------*/
if(info_temp->vendor_id == info->vendor_id
&& info_temp->product_id == info->product_id
&& used_paths.find(info_temp->path) == used_paths.end() )
{
if(info_temp->interface_number == 0)
{
dev_interface_0 = hid_open_path(info_temp->path);
dev_interface_0_path = info_temp->path;
}
else if(info_temp->interface_number == 1)
{
dev_interface_1 = hid_open_path(info_temp->path);
dev_interface_1_path = info_temp->path;
}
}
if(dev_interface_0 && dev_interface_1)
{
break;
}
info_temp = info_temp->next;
}
hid_free_enumeration(info_full);
if(dev_interface_0 && dev_interface_1)
{
RazerController* controller = new RazerController(dev_interface_0, dev_interface_1, info->path, info->product_id, name);
RGBController_RazerAddressable* rgb_controller = new RGBController_RazerAddressable(controller);
ResourceManager::get()->RegisterRGBController(rgb_controller);
used_paths.insert(dev_interface_0_path);
used_paths.insert(dev_interface_1_path);
}
else
{
// Not all of them could be opened, do some cleanup
hid_close(dev_interface_0);
hid_close(dev_interface_1);
}
}
/******************************************************************************************\
* *
* DetectRazerKrakenController *
* *
* Tests the USB address to see if a Razer Kraken controller exists there. *
* *
\******************************************************************************************/
void DetectRazerKrakenControllers(hid_device_info* info, const std::string& name)
{
hid_device* dev = hid_open_path(info->path);
if(dev)
{
RazerKrakenController* controller = new RazerKrakenController(dev, info->path, info->product_id, name);
RGBController_RazerKraken* rgb_controller = new RGBController_RazerKraken(controller);
ResourceManager::get()->RegisterRGBController(rgb_controller);
}
} /* DetectRazerKrakenControllers() */
/******************************************************************************************\
* *
* DetectRazerKrakenV3Controllers *
* *
* Tests the USB address to see if a Razer Kraken V3 controller exists there. *
* *
\******************************************************************************************/
void DetectRazerKrakenV3Controllers(hid_device_info* info, const std::string& name)
{
hid_device* dev = hid_open_path(info->path);
if(dev)
{
RazerKrakenV3Controller* controller = new RazerKrakenV3Controller(dev, info->path, info->product_id, name);
RGBController_RazerKrakenV3* rgb_controller = new RGBController_RazerKrakenV3(controller);
ResourceManager::get()->RegisterRGBController(rgb_controller);
}
} /* DetectRazerKrakenV3Controllers() */
/******************************************************************************************\
* *
* DetectRazerKrakenV4Controllers *
* *
* Tests the USB address to see if a Razer Kraken V4 controller exists there. *
* *
\******************************************************************************************/
void DetectRazerKrakenV4Controllers(hid_device_info* info, const std::string& name)
{
hid_device* dev = hid_open_path(info->path);
if(dev)
{
RazerKrakenV4Controller* controller = new RazerKrakenV4Controller(dev, info->path, info->product_id, name);
RGBController_RazerKrakenV4* rgb_controller = new RGBController_RazerKrakenV4(controller);
ResourceManager::get()->RegisterRGBController(rgb_controller);
}
} /* DetectRazerKrakenV4Controllers() */
/******************************************************************************************\
* *
* DetectRazerHanboController *
* *
* Tests the USB address to see if a Razer Hanbo controller exists there. *
* *
\******************************************************************************************/
void DetectRazerHanboControllers(hid_device_info* info, const std::string& name)
{
hid_device* dev = hid_open_path(info->path);
if(dev)
{
RazerHanboController* controller = new RazerHanboController(dev, info->path, info->product_id, name);
RGBController_RazerHanbo* rgb_controller = new RGBController_RazerHanbo(controller);
ResourceManager::get()->RegisterRGBController(rgb_controller);
}
} /* DetectRazerHanboControllers() */
/*-----------------------------------------------------------------------------------------------------*\
| Keyboards |
\*-----------------------------------------------------------------------------------------------------*/
REGISTER_HID_DETECTOR_IPU("Razer Blackwidow 2019", DetectRazerControllers, RAZER_VID, RAZER_BLACKWIDOW_2019_PID, 0x02, 0x01, 0x02);
REGISTER_HID_DETECTOR_IPU("Razer Blackwidow Chroma", DetectRazerControllers, RAZER_VID, RAZER_BLACKWIDOW_CHROMA_PID, 0x02, 0x01, 0x02);
REGISTER_HID_DETECTOR_IPU("Razer Blackwidow Chroma Tournament Edition", DetectRazerControllers, RAZER_VID, RAZER_BLACKWIDOW_CHROMA_TE_PID, 0x02, 0x01, 0x02);
REGISTER_HID_DETECTOR_IPU("Razer Blackwidow Chroma V2", DetectRazerControllers, RAZER_VID, RAZER_BLACKWIDOW_CHROMA_V2_PID, 0x02, 0x01, 0x02);
REGISTER_HID_DETECTOR_IPU("Razer Blackwidow Elite", DetectRazerControllers, RAZER_VID, RAZER_BLACKWIDOW_ELITE_PID, 0x02, 0x01, 0x02);
REGISTER_HID_DETECTOR_IPU("Razer Blackwidow Overwatch", DetectRazerControllers, RAZER_VID, RAZER_BLACKWIDOW_OVERWATCH_PID, 0x02, 0x01, 0x02);
REGISTER_HID_DETECTOR_IPU("Razer Blackwidow V3", DetectRazerControllers, RAZER_VID, RAZER_BLACKWIDOW_V3_PID, 0x03, 0x0C, 0x01);
REGISTER_HID_DETECTOR_IPU("Razer Blackwidow V3 Pro (Wired)", DetectRazerControllers, RAZER_VID, RAZER_BLACKWIDOW_V3_PRO_WIRED_PID, 0x02, 0x01, 0x02);
// REGISTER_HID_DETECTOR_PU ("Razer Blackwidow V3 Pro (Bluetooth)", DetectRazerControllers, RAZER_VID, RAZER_BLACKWIDOW_V3_PRO_BLUETOOTH_PID, 0x01, 0x00);
REGISTER_HID_DETECTOR_IPU("Razer Blackwidow V3 Pro (Wireless)", DetectRazerControllers, RAZER_VID, RAZER_BLACKWIDOW_V3_PRO_WIRELESS_PID, 0x03, 0x0C, 0x01);
REGISTER_HID_DETECTOR_IPU("Razer Blackwidow V3 TKL", DetectRazerControllers, RAZER_VID, RAZER_BLACKWIDOW_V3_TKL_PID, 0x02, 0x01, 0x02);
REGISTER_HID_DETECTOR_IPU("Razer Blackwidow V3 Mini (Wired)", DetectRazerControllers, RAZER_VID, RAZER_BLACKWIDOW_V3_MINI_WIRED_PID, 0x03, 0x0C, 0x01);
REGISTER_HID_DETECTOR_IPU("Razer Blackwidow V3 Mini (Wireless)", DetectRazerControllers, RAZER_VID, RAZER_BLACKWIDOW_V3_MINI_WIRELESS_PID, 0x03, 0x0C, 0x01);
REGISTER_HID_DETECTOR_IPU("Razer Blackwidow V4", DetectRazerControllers, RAZER_VID, RAZER_BLACKWIDOW_V4_PID, 0x03, 0x01, 0x00);
REGISTER_HID_DETECTOR_IPU("Razer Blackwidow V4 Pro", /* firmware < 1.5 */ DetectRazerControllers, RAZER_VID, RAZER_BLACKWIDOW_V4_PRO_PID, 0x03, 0x01, 0x00);
REGISTER_HID_DETECTOR_IPU("Razer Blackwidow V4 Pro", /* firmware >= 1.5 */ DetectRazerControllers, RAZER_VID, RAZER_BLACKWIDOW_V4_PRO_PID, 0x03, 0x0C, 0x01);
REGISTER_HID_DETECTOR_IPU("Razer Blackwidow V4 Pro 75% (Wired)", DetectRazerControllers, RAZER_VID, RAZER_BLACKWIDOW_V4_PRO_75_WIRED_PID, 0x03, 0x0C, 0x01);
REGISTER_HID_DETECTOR_IPU("Razer Blackwidow V4 Pro 75% (Wireless)", DetectRazerControllers, RAZER_VID, RAZER_BLACKWIDOW_V4_PRO_75_WIRELESS_PID, 0x02, 0x01, 0x02);
REGISTER_HID_DETECTOR_IPU("Razer Blackwidow V4 75% (Wired)", DetectRazerControllers, RAZER_VID, RAZER_BLACKWIDOW_V4_75_WIRED_PID, 0x03, 0x01, 0x00);
REGISTER_HID_DETECTOR_IPU("Razer Blackwidow V4 X", DetectRazerControllers, RAZER_VID, RAZER_BLACKWIDOW_V4_X_PID, 0x02, 0x01, 0x02);
REGISTER_HID_DETECTOR_IPU("Razer Blackwidow V4 TKL (Wired)", DetectRazerControllers, RAZER_VID, RAZER_BLACKWIDOW_V4_TKL_WIRED_PID, 0x03, 0x0C, 0x01);
REGISTER_HID_DETECTOR_IPU("Razer Blackwidow V4 TKL (Wireless)", DetectRazerControllers, RAZER_VID, RAZER_BLACKWIDOW_V4_TKL_WIRELESS_PID, 0x02, 0x01, 0x02);
REGISTER_HID_DETECTOR_IPU("Razer Blackwidow V4 Low Profile TKL (Wired)", DetectRazerControllers, RAZER_VID, RAZER_BLACKWIDOW_V4_LOWPROFILE_TKL_WIRED_PID, 0x03, 0x0C, 0x01);
REGISTER_HID_DETECTOR_IPU("Razer Blackwidow V4 Low Profile TKL (Wireless)", DetectRazerControllers, RAZER_VID, RAZER_BLACKWIDOW_V4_LOWPROFILE_TKL_WIRELESS_PID, 0x02, 0x01, 0x02);
REGISTER_HID_DETECTOR_IPU("Razer Blackwidow X Chroma", DetectRazerControllers, RAZER_VID, RAZER_BLACKWIDOW_X_CHROMA_PID, 0x02, 0x01, 0x02);
REGISTER_HID_DETECTOR_IPU("Razer Blackwidow X Chroma Tournament Edition", DetectRazerControllers, RAZER_VID, RAZER_BLACKWIDOW_X_CHROMA_TE_PID, 0x02, 0x01, 0x02);
REGISTER_HID_DETECTOR_IPU("Razer Cynosa Chroma", DetectRazerControllers, RAZER_VID, RAZER_CYNOSA_CHROMA_PID, 0x02, 0x01, 0x02);
REGISTER_HID_DETECTOR_IPU("Razer Cynosa Chroma V2", DetectRazerControllers, RAZER_VID, RAZER_CYNOSA_V2_PID, 0x02, 0x01, 0x02);
REGISTER_HID_DETECTOR_IPU("Razer Cynosa Lite", DetectRazerControllers, RAZER_VID, RAZER_CYNOSA_LITE_PID, 0x02, 0x01, 0x02);
REGISTER_HID_DETECTOR_IPU("Razer Deathstalker Chroma", DetectRazerControllers, RAZER_VID, RAZER_DEATHSTALKER_CHROMA_PID, 0x02, 0x01, 0x02);
REGISTER_HID_DETECTOR_IPU("Razer Deathstalker V2", DetectRazerControllers, RAZER_VID, RAZER_DEATHSTALKER_V2_PID, 0x03, 0x0C, 0x01);
REGISTER_HID_DETECTOR_IPU("Razer Deathstalker V2 Pro TKL (Wired)", DetectRazerControllers, RAZER_VID, RAZER_DEATHSTALKER_V2_PRO_TKL_WIRED_PID, 0x03, 0x0C, 0x01);
REGISTER_HID_DETECTOR_IPU("Razer Deathstalker V2 Pro TKL (Wireless)", DetectRazerControllers, RAZER_VID, RAZER_DEATHSTALKER_V2_PRO_TKL_WIRELESS_PID, 0x02, 0x01, 0x02);
REGISTER_HID_DETECTOR_IPU("Razer Deathstalker V2 Pro (Wired)", DetectRazerControllers, RAZER_VID, RAZER_DEATHSTALKER_V2_PRO_WIRED_PID, 0x03, 0x0C, 0x01);
REGISTER_HID_DETECTOR_IPU("Razer Deathstalker V2 Pro (Wireless)", DetectRazerControllers, RAZER_VID, RAZER_DEATHSTALKER_V2_PRO_WIRELESS_PID, 0x02, 0x01, 0x02);
REGISTER_HID_DETECTOR_IPU("Razer Huntsman", DetectRazerControllers, RAZER_VID, RAZER_HUNTSMAN_PID, 0x02, 0x01, 0x02);
REGISTER_HID_DETECTOR_IPU("Razer Huntsman Elite", DetectRazerControllers, RAZER_VID, RAZER_HUNTSMAN_ELITE_PID, 0x02, 0x01, 0x02);
REGISTER_HID_DETECTOR_IPU("Razer Huntsman Mini", DetectRazerControllers, RAZER_VID, RAZER_HUNTSMAN_MINI_PID, 0x02, 0x01, 0x02);
REGISTER_HID_DETECTOR_IPU("Razer Huntsman Mini Analog", DetectRazerControllers, RAZER_VID, RAZER_HUNTSMAN_MINI_ANALOG_PID, 0x03, 0x0C, 0x01);
REGISTER_HID_DETECTOR_IPU("Razer Huntsman Tournament Edition", DetectRazerControllers, RAZER_VID, RAZER_HUNTSMAN_TE_PID, 0x02, 0x01, 0x02);
REGISTER_HID_DETECTOR_IPU("Razer Huntsman V2 Analog", DetectRazerControllers, RAZER_VID, RAZER_HUNTSMAN_V2_ANALOG_PID, 0x03, 0x0C, 0x01);
REGISTER_HID_DETECTOR_IPU("Razer Huntsman V2 TKL", DetectRazerControllers, RAZER_VID, RAZER_HUNTSMAN_V2_TKL_PID, 0x03, 0x0C, 0x01);
REGISTER_HID_DETECTOR_IPU("Razer Huntsman V2", DetectRazerControllers, RAZER_VID, RAZER_HUNTSMAN_V2_PID, 0x03, 0x0C, 0x01);
REGISTER_HID_DETECTOR_IPU("Razer Huntsman V3 Pro", DetectRazerControllers, RAZER_VID, RAZER_HUNTSMAN_V3_PRO_PID, 0x03, 0x0C, 0x01);
REGISTER_HID_DETECTOR_IPU("Razer Huntsman V3 Pro TKL White", DetectRazerControllers, RAZER_VID, RAZER_HUNTSMAN_V3_PRO_TKL_WHITE_PID, 0x03, 0x0C, 0x01);
REGISTER_HID_DETECTOR_IPU("Razer Ornata Chroma", DetectRazerControllers, RAZER_VID, RAZER_ORNATA_CHROMA_PID, 0x02, 0x01, 0x02);
REGISTER_HID_DETECTOR_IPU("Razer Ornata Chroma V2", DetectRazerControllers, RAZER_VID, RAZER_ORNATA_CHROMA_V2_PID, 0x02, 0x01, 0x02);
REGISTER_HID_DETECTOR_IPU("Razer Ornata V3", DetectRazerControllers, RAZER_VID, RAZER_ORNATA_V3_PID, 0x02, 0x01, 0x02);
REGISTER_HID_DETECTOR_IPU("Razer Ornata V3 Rev2", DetectRazerControllers, RAZER_VID, RAZER_ORNATA_V3_REV2_PID, 0x02, 0x01, 0x02);
REGISTER_HID_DETECTOR_IPU("Razer Ornata V3 TKL", DetectRazerControllers, RAZER_VID, RAZER_ORNATA_V3_TKL_PID, 0x02, 0x01, 0x02);
REGISTER_HID_DETECTOR_IPU("Razer Ornata V3 X", DetectRazerControllers, RAZER_VID, RAZER_ORNATA_V3_X_PID, 0x02, 0x01, 0x02);
REGISTER_HID_DETECTOR_IPU("Razer Ornata V3 X Rev2", DetectRazerControllers, RAZER_VID, RAZER_ORNATA_V3_X_REV2_PID, 0x02, 0x01, 0x02);
/*-----------------------------------------------------------------------------------------------------*\
| Laptops |
\*-----------------------------------------------------------------------------------------------------*/
REGISTER_HID_DETECTOR_IPU("Razer Blade (2016)", DetectRazerControllers, RAZER_VID, RAZER_BLADE_2016_PID, 0x02, 0x01, 0x02);
REGISTER_HID_DETECTOR_IPU("Razer Blade (Late 2016)", DetectRazerControllers, RAZER_VID, RAZER_BLADE_LATE_2016_PID, 0x02, 0x01, 0x02);
REGISTER_HID_DETECTOR_IPU("Razer Blade 14 (2021)", DetectRazerControllers, RAZER_VID, RAZER_BLADE_14_2021_PID, 0x02, 0x01, 0x02);
REGISTER_HID_DETECTOR_IPU("Razer Blade 14 (2022)", DetectRazerControllers, RAZER_VID, RAZER_BLADE_14_2022_PID, 0x02, 0x01, 0x02);
REGISTER_HID_DETECTOR_IPU("Razer Blade 14 (2023)", DetectRazerControllers, RAZER_VID, RAZER_BLADE_14_2023_PID, 0x02, 0x01, 0x02);
REGISTER_HID_DETECTOR_IPU("Razer Blade 15 (2022)", DetectRazerControllers, RAZER_VID, RAZER_BLADE_15_2022_PID, 0x02, 0x01, 0x02);
REGISTER_HID_DETECTOR_IPU("Razer Blade 15 (2018 Advanced)", DetectRazerControllers, RAZER_VID, RAZER_BLADE_2018_ADVANCED_PID, 0x02, 0x01, 0x02);
REGISTER_HID_DETECTOR_IPU("Razer Blade 15 (2018 Base)", DetectRazerControllers, RAZER_VID, RAZER_BLADE_2018_BASE_PID, 0x02, 0x01, 0x02);
REGISTER_HID_DETECTOR_IPU("Razer Blade 15 (2018 Mercury)", DetectRazerControllers, RAZER_VID, RAZER_BLADE_2018_MERCURY_PID, 0x02, 0x01, 0x02);
REGISTER_HID_DETECTOR_IPU("Razer Blade 15 (2019 Advanced)", DetectRazerControllers, RAZER_VID, RAZER_BLADE_2019_ADVANCED_PID, 0x02, 0x01, 0x02);
REGISTER_HID_DETECTOR_IPU("Razer Blade 15 (2019 Base)", DetectRazerControllers, RAZER_VID, RAZER_BLADE_2019_BASE_PID, 0x02, 0x01, 0x02);
REGISTER_HID_DETECTOR_IPU("Razer Blade 15 (2019 Mercury)", DetectRazerControllers, RAZER_VID, RAZER_BLADE_2019_MERCURY_PID, 0x02, 0x01, 0x02);
REGISTER_HID_DETECTOR_IPU("Razer Blade 15 (2019 Studio)", DetectRazerControllers, RAZER_VID, RAZER_BLADE_2019_STUDIO_PID, 0x02, 0x01, 0x02);
REGISTER_HID_DETECTOR_IPU("Razer Blade 15 (2020 Advanced)", DetectRazerControllers, RAZER_VID, RAZER_BLADE_2020_ADVANCED_PID, 0x02, 0x01, 0x02);
REGISTER_HID_DETECTOR_IPU("Razer Blade 15 (2020 Base)", DetectRazerControllers, RAZER_VID, RAZER_BLADE_2020_BASE_PID, 0x02, 0x01, 0x02);
REGISTER_HID_DETECTOR_IPU("Razer Blade 15 (Late 2020)", DetectRazerControllers, RAZER_VID, RAZER_BLADE_LATE_2020_PID, 0x02, 0x01, 0x02);
REGISTER_HID_DETECTOR_IPU("Razer Blade 15 (2021 Advanced)", DetectRazerControllers, RAZER_VID, RAZER_BLADE_2021_ADVANCED_PID, 0x02, 0x01, 0x02);
REGISTER_HID_DETECTOR_IPU("Razer Blade 15 (Late 2021 Advanced)", DetectRazerControllers, RAZER_VID, RAZER_BLADE_LATE_2021_ADVANCED_PID, 0x02, 0x01, 0x02);
REGISTER_HID_DETECTOR_IPU("Razer Blade 15 (2021 Base)", DetectRazerControllers, RAZER_VID, RAZER_BLADE_2021_BASE_PID, 0x02, 0x01, 0x02);
REGISTER_HID_DETECTOR_IPU("Razer Blade 15 (2021 Base)", DetectRazerControllers, RAZER_VID, RAZER_BLADE_2021_BASE_V2_PID, 0x02, 0x01, 0x02);
REGISTER_HID_DETECTOR_IPU("Razer Blade Pro (2016)", DetectRazerControllers, RAZER_VID, RAZER_BLADE_PRO_2016_PID, 0x02, 0x01, 0x02);
REGISTER_HID_DETECTOR_IPU("Razer Blade Pro (2017)", DetectRazerControllers, RAZER_VID, RAZER_BLADE_PRO_2017_PID, 0x02, 0x01, 0x02);
REGISTER_HID_DETECTOR_IPU("Razer Blade Pro (2017 FullHD)", DetectRazerControllers, RAZER_VID, RAZER_BLADE_PRO_2017_FULLHD_PID, 0x02, 0x01, 0x02);
REGISTER_HID_DETECTOR_IPU("Razer Blade Pro (2019)", DetectRazerControllers, RAZER_VID, RAZER_BLADE_PRO_2019_PID, 0x02, 0x01, 0x02);
REGISTER_HID_DETECTOR_IPU("Razer Blade Pro (Late 2019)", DetectRazerControllers, RAZER_VID, RAZER_BLADE_PRO_LATE_2019_PID, 0x02, 0x01, 0x02);
REGISTER_HID_DETECTOR_IPU("Razer Blade Pro 17 (2020)", DetectRazerControllers, RAZER_VID, RAZER_BLADE_PRO_17_2020_PID, 0x02, 0x01, 0x02);
REGISTER_HID_DETECTOR_IPU("Razer Blade Pro 17 (2021)", DetectRazerControllers, RAZER_VID, RAZER_BLADE_PRO_17_2021_PID, 0x02, 0x01, 0x02);
REGISTER_HID_DETECTOR_IPU("Razer Blade Stealth (2016)", DetectRazerControllers, RAZER_VID, RAZER_BLADE_STEALTH_2016_PID, 0x02, 0x01, 0x02);
REGISTER_HID_DETECTOR_IPU("Razer Blade Stealth (Late 2016)", DetectRazerControllers, RAZER_VID, RAZER_BLADE_STEALTH_LATE_2016_PID, 0x02, 0x01, 0x02);
REGISTER_HID_DETECTOR_IPU("Razer Blade Stealth (2017)", DetectRazerControllers, RAZER_VID, RAZER_BLADE_STEALTH_2017_PID, 0x02, 0x01, 0x02);
REGISTER_HID_DETECTOR_IPU("Razer Blade Stealth (Late 2017)", DetectRazerControllers, RAZER_VID, RAZER_BLADE_STEALTH_LATE_2017_PID, 0x02, 0x01, 0x02);
REGISTER_HID_DETECTOR_IPU("Razer Blade Stealth (2019)", DetectRazerControllers, RAZER_VID, RAZER_BLADE_STEALTH_2019_PID, 0x02, 0x01, 0x02);
REGISTER_HID_DETECTOR_IPU("Razer Blade Stealth (Late 2019)", DetectRazerControllers, RAZER_VID, RAZER_BLADE_STEALTH_LATE_2019_PID, 0x02, 0x01, 0x02);
REGISTER_HID_DETECTOR_IPU("Razer Blade Stealth (2020)", DetectRazerControllers, RAZER_VID, RAZER_BLADE_STEALTH_2020_PID, 0x02, 0x01, 0x02);
REGISTER_HID_DETECTOR_IPU("Razer Blade Stealth (Late 2020)", DetectRazerControllers, RAZER_VID, RAZER_BLADE_STEALTH_LATE_2020_PID, 0x02, 0x01, 0x02);
REGISTER_HID_DETECTOR_IPU("Razer Book 13 (2020)", DetectRazerControllers, RAZER_VID, RAZER_BOOK_13_2020_PID, 0x02, 0x01, 0x02);
/*-----------------------------------------------------------------------------------------------------*\
| Mice |
\*-----------------------------------------------------------------------------------------------------*/
REGISTER_HID_DETECTOR_IPU("Razer Abyssus Elite D.Va Edition", DetectRazerControllers, RAZER_VID, RAZER_ABYSSUS_ELITE_DVA_EDITION_PID, 0x00, 0x01, 0x02);
REGISTER_HID_DETECTOR_IPU("Razer Abyssus Essential", DetectRazerControllers, RAZER_VID, RAZER_ABYSSUS_ESSENTIAL_PID, 0x00, 0x01, 0x02);
REGISTER_HID_DETECTOR_IPU("Razer Basilisk", DetectRazerControllers, RAZER_VID, RAZER_BASILISK_PID, 0x00, 0x01, 0x02);
REGISTER_HID_DETECTOR_IPU("Razer Basilisk Essential", DetectRazerControllers, RAZER_VID, RAZER_BASILISK_ESSENTIAL_PID, 0x00, 0x01, 0x02);
REGISTER_HID_DETECTOR_IPU("Razer Basilisk Ultimate (Wired)", DetectRazerControllers, RAZER_VID, RAZER_BASILISK_ULTIMATE_WIRED_PID, 0x00, 0x01, 0x02);
REGISTER_HID_DETECTOR_IPU("Razer Basilisk Ultimate (Wireless)", DetectRazerControllers, RAZER_VID, RAZER_BASILISK_ULTIMATE_WIRELESS_PID, 0x00, 0x01, 0x02);
REGISTER_HID_DETECTOR_IPU("Razer Basilisk V2", DetectRazerControllers, RAZER_VID, RAZER_BASILISK_V2_PID, 0x00, 0x01, 0x02);
REGISTER_HID_DETECTOR_IPU("Razer Basilisk V3", DetectRazerControllers, RAZER_VID, RAZER_BASILISK_V3_PID, 0x03, 0x0C, 0x01);
REGISTER_HID_DETECTOR_IPU("Razer Basilisk V3 35K", DetectRazerControllers, RAZER_VID, RAZER_BASILISK_V3_35K_PID, 0x03, 0x0C, 0x01);
REGISTER_HID_DETECTOR_IPU("Razer Basilisk V3 Pro (Wired)", DetectRazerControllers, RAZER_VID, RAZER_BASILISK_V3_PRO_WIRED_PID, 0x00, 0x01, 0x02);
REGISTER_HID_DETECTOR_IPU("Razer Basilisk V3 Pro (Wireless)", DetectRazerControllers, RAZER_VID, RAZER_BASILISK_V3_PRO_WIRELESS_PID, 0x00, 0x01, 0x02);
REGISTER_HID_DETECTOR_IPU("Razer Basilisk V3 Pro 35K (Wired)", DetectRazerControllers, RAZER_VID, RAZER_BASILISK_V3_PRO_35K_WIRED_PID, 0x00, 0x01, 0x02);
REGISTER_HID_DETECTOR_IPU("Razer Basilisk V3 Pro 35K (Wireless)", DetectRazerControllers, RAZER_VID, RAZER_BASILISK_V3_PRO_35K_WIRELESS_PID, 0x00, 0x01, 0x02);
// REGISTER_HID_DETECTOR_PU ("Razer Basilisk V3 Pro (Bluetooth)", DetectRazerControllers, RAZER_VID, RAZER_BASILISK_V3_PRO_BLUETOOTH_PID, 0x01, 0x02);
REGISTER_HID_DETECTOR_IPU("Razer Basilisk V3 Pro 35K Phantom Green (Wired)", DetectRazerControllers, RAZER_VID, RAZER_BASILISK_V3_PRO_35K_PG_WIRED_PID, 0x00, 0x01, 0x02);
REGISTER_HID_DETECTOR_IPU("Razer Basilisk V3 Pro 35K Phantom Green (Wireless)", DetectRazerControllers, RAZER_VID, RAZER_BASILISK_V3_PRO_35K_PG_WIRELESS_PID, 0x00, 0x01, 0x02);
// REGISTER_HID_DETECTOR_PU("Razer Basilisk V3 Pro 35K Phantom Green (Bluetooth)",DetectRazerControllers, RAZER_BLUETOOTH_VID, RAZER_BASILISK_V3_PRO_35K_PG_BLUETOOTH_PID, 0x01, 0x02);
REGISTER_HID_DETECTOR_IPU("Razer Basilisk V3 X HyperSpeed", DetectRazerControllers, RAZER_VID, RAZER_BASILISK_V3_X_HYPERSPEED_PID, 0x00, 0x01, 0x02);
REGISTER_HID_DETECTOR_IPU("Razer Cobra", DetectRazerControllers, RAZER_VID, RAZER_COBRA_PID, 0x00, 0x01, 0x02);
REGISTER_HID_DETECTOR_IPU("Razer Cobra Pro (Wired)", DetectRazerControllers, RAZER_VID, RAZER_COBRA_PRO_WIRED_PID, 0x00, 0x01, 0x02);
REGISTER_HID_DETECTOR_IPU("Razer Cobra Pro (Wireless)", DetectRazerControllers, RAZER_VID, RAZER_COBRA_PRO_WIRELESS_PID, 0x00, 0x01, 0x02);
REGISTER_HID_DETECTOR_IPU("Razer Deathadder Chroma", DetectRazerControllers, RAZER_VID, RAZER_DEATHADDER_CHROMA_PID, 0x00, 0x01, 0x02);
REGISTER_HID_DETECTOR_IPU("Razer Deathadder Elite", DetectRazerControllers, RAZER_VID, RAZER_DEATHADDER_ELITE_PID, 0x00, 0x01, 0x02);
REGISTER_HID_DETECTOR_IPU("Razer Deathadder Essential", DetectRazerControllers, RAZER_VID, RAZER_DEATHADDER_ESSENTIAL_PID, 0x00, 0x01, 0x02);
REGISTER_HID_DETECTOR_IPU("Razer Deathadder Essential V2", DetectRazerControllers, RAZER_VID, RAZER_DEATHADDER_ESSENTIAL_V2_PID, 0x00, 0x01, 0x02);
REGISTER_HID_DETECTOR_IPU("Razer Deathadder Essential White Edition", DetectRazerControllers, RAZER_VID, RAZER_DEATHADDER_ESSENTIAL_WHITE_EDITION_PID, 0x00, 0x01, 0x02);
REGISTER_HID_DETECTOR_IPU("Razer Deathadder V2", DetectRazerControllers, RAZER_VID, RAZER_DEATHADDER_V2_PID, 0x00, 0x01, 0x02);
REGISTER_HID_DETECTOR_IPU("Razer Deathadder V2 Mini", DetectRazerControllers, RAZER_VID, RAZER_DEATHADDER_V2_MINI_PID, 0x00, 0x01, 0x02);
REGISTER_HID_DETECTOR_IPU("Razer Deathadder V2 Pro (Wired)", DetectRazerControllers, RAZER_VID, RAZER_DEATHADDER_V2_PRO_WIRED_PID, 0x00, 0x01, 0x02);
REGISTER_HID_DETECTOR_IPU("Razer Deathadder V2 Pro (Wireless)", DetectRazerControllers, RAZER_VID, RAZER_DEATHADDER_V2_PRO_WIRELESS_PID, 0x00, 0x01, 0x02);
REGISTER_HID_DETECTOR_IPU("Razer Diamondback", DetectRazerControllers, RAZER_VID, RAZER_DIAMONDBACK_CHROMA_PID, 0x00, 0x01, 0x02);
REGISTER_HID_DETECTOR_IPU("Razer Lancehead 2017 (Wired)", DetectRazerControllers, RAZER_VID, RAZER_LANCEHEAD_2017_WIRED_PID, 0x00, 0x01, 0x02);
REGISTER_HID_DETECTOR_IPU("Razer Lancehead 2017 (Wireless)", DetectRazerControllers, RAZER_VID, RAZER_LANCEHEAD_2017_WIRELESS_PID, 0x00, 0x01, 0x02);
REGISTER_HID_DETECTOR_IPU("Razer Lancehead 2019 (Wired)", DetectRazerControllers, RAZER_VID, RAZER_LANCEHEAD_2019_WIRED_PID, 0x00, 0x01, 0x02);
REGISTER_HID_DETECTOR_IPU("Razer Lancehead 2019 (Wireless)", DetectRazerControllers, RAZER_VID, RAZER_LANCEHEAD_2019_WIRELESS_PID, 0x00, 0x01, 0x02);
REGISTER_HID_DETECTOR_IPU("Razer Lancehead Tournament Edition", DetectRazerControllers, RAZER_VID, RAZER_LANCEHEAD_TE_WIRED_PID, 0x00, 0x01, 0x02);
REGISTER_HID_DETECTOR_IPU("Razer Mamba 2012 (Wired)", DetectRazerControllers, RAZER_VID, RAZER_MAMBA_2012_WIRED_PID, 0x00, 0x01, 0x02);
REGISTER_HID_DETECTOR_IPU("Razer Mamba 2012 (Wireless)", DetectRazerControllers, RAZER_VID, RAZER_MAMBA_2012_WIRELESS_PID, 0x00, 0x01, 0x02);
REGISTER_HID_DETECTOR_IPU("Razer Mamba 2015 (Wired)", DetectRazerControllers, RAZER_VID, RAZER_MAMBA_2015_WIRED_PID, 0x00, 0x01, 0x02);
REGISTER_HID_DETECTOR_IPU("Razer Mamba 2015 (Wireless)", DetectRazerControllers, RAZER_VID, RAZER_MAMBA_2015_WIRELESS_PID, 0x00, 0x01, 0x02);
REGISTER_HID_DETECTOR_IPU("Razer Mamba 2018 (Wired)", DetectRazerControllers, RAZER_VID, RAZER_MAMBA_2018_WIRED_PID, 0x00, 0x01, 0x02);
REGISTER_HID_DETECTOR_IPU("Razer Mamba 2018 (Wireless)", DetectRazerControllers, RAZER_VID, RAZER_MAMBA_2018_WIRELESS_PID, 0x00, 0x01, 0x02);
REGISTER_HID_DETECTOR_IPU("Razer Mamba Elite", DetectRazerControllers, RAZER_VID, RAZER_MAMBA_ELITE_PID, 0x00, 0x01, 0x02);
REGISTER_HID_DETECTOR_IPU("Razer Mamba Hyperflux (Wired)", DetectRazerControllers, RAZER_VID, RAZER_MAMBA_HYPERFLUX_PID, 0x00, 0x01, 0x02);
REGISTER_HID_DETECTOR_IPU("Razer Mamba Tournament Edition", DetectRazerControllers, RAZER_VID, RAZER_MAMBA_TE_PID, 0x00, 0x01, 0x02);
REGISTER_HID_DETECTOR_IPU("Razer Naga Chroma", DetectRazerControllers, RAZER_VID, RAZER_NAGA_CHROMA_PID, 0x00, 0x01, 0x02);
REGISTER_HID_DETECTOR_IPU("Razer Naga Classic", DetectRazerControllers, RAZER_VID, RAZER_NAGA_CLASSIC_PID, 0x00, 0x01, 0x02);
REGISTER_HID_DETECTOR_IPU("Razer Naga Epic Chroma", DetectRazerControllers, RAZER_VID, RAZER_NAGA_EPIC_CHROMA_PID, 0x00, 0x01, 0x02);
REGISTER_HID_DETECTOR_IPU("Razer Naga Left Handed", DetectRazerControllers, RAZER_VID, RAZER_NAGA_LEFT_HANDED_PID, 0x00, 0x01, 0x02);
REGISTER_HID_DETECTOR_IPU("Razer Naga Hex V2", DetectRazerControllers, RAZER_VID, RAZER_NAGA_HEX_V2_PID, 0x00, 0x01, 0x02);
REGISTER_HID_DETECTOR_IPU("Razer Naga Trinity", DetectRazerControllers, RAZER_VID, RAZER_NAGA_TRINITY_PID, 0x00, 0x01, 0x02);
REGISTER_HID_DETECTOR_IPU("Razer Naga Pro (Wired)", DetectRazerControllers, RAZER_VID, RAZER_NAGA_PRO_WIRED_PID, 0x00, 0x01, 0x02);
REGISTER_HID_DETECTOR_IPU("Razer Naga Pro (Wireless)", DetectRazerControllers, RAZER_VID, RAZER_NAGA_PRO_WIRELESS_PID, 0x00, 0x01, 0x02);
REGISTER_HID_DETECTOR_IPU("Razer Naga Pro V2 (Wired)", DetectRazerControllers, RAZER_VID, RAZER_NAGA_PRO_V2_WIRED_PID, 0x00, 0x01, 0x02);
REGISTER_HID_DETECTOR_IPU("Razer Naga Pro V2 (Wireless)", DetectRazerControllers, RAZER_VID, RAZER_NAGA_PRO_V2_WIRELESS_PID, 0x00, 0x01, 0x02);
REGISTER_HID_DETECTOR_IPU("Razer Viper", DetectRazerControllers, RAZER_VID, RAZER_VIPER_PID, 0x00, 0x01, 0x02);
REGISTER_HID_DETECTOR_IPU("Razer Viper 8kHz", DetectRazerControllers, RAZER_VID, RAZER_VIPER_8KHZ_PID, 0x00, 0x01, 0x02);
REGISTER_HID_DETECTOR_IPU("Razer Viper Mini", DetectRazerControllers, RAZER_VID, RAZER_VIPER_MINI_PID, 0x00, 0x01, 0x02);
REGISTER_HID_DETECTOR_IPU("Razer Viper Ultimate (Wired)", DetectRazerControllers, RAZER_VID, RAZER_VIPER_ULTIMATE_WIRED_PID, 0x00, 0x01, 0x02);
REGISTER_HID_DETECTOR_IPU("Razer Viper Ultimate (Wireless)", DetectRazerControllers, RAZER_VID, RAZER_VIPER_ULTIMATE_WIRELESS_PID, 0x00, 0x01, 0x02);
/*-----------------------------------------------------------------------------------------------------*\
| Keypads |
\*-----------------------------------------------------------------------------------------------------*/
REGISTER_HID_DETECTOR_IPU("Razer Orbweaver Chroma", DetectRazerControllers, RAZER_VID, RAZER_ORBWEAVER_CHROMA_PID, 0x02, 0x01, 0x02);
REGISTER_HID_DETECTOR_IPU("Razer Tartarus Chroma", DetectRazerControllers, RAZER_VID, RAZER_TARTARUS_CHROMA_PID, 0x02, 0x01, 0x02);
REGISTER_HID_DETECTOR_IPU("Razer Tartarus Pro", DetectRazerControllers, RAZER_VID, RAZER_TARTARUS_PRO_PID, 0x02, 0x01, 0x02);
REGISTER_HID_DETECTOR_IPU("Razer Tartarus V2", DetectRazerControllers, RAZER_VID, RAZER_TARTARUS_V2_PID, 0x02, 0x01, 0x02);
/*-----------------------------------------------------------------------------------------------------*\
| Headsets |
\*-----------------------------------------------------------------------------------------------------*/
REGISTER_HID_DETECTOR_IPU("Razer Kraken 7.1", DetectRazerKrakenControllers, RAZER_VID, RAZER_KRAKEN_CLASSIC_PID, 0x03, 0x0C, 0x01);
REGISTER_HID_DETECTOR_IPU("Razer Kraken 7.1", DetectRazerKrakenControllers, RAZER_VID, RAZER_KRAKEN_CLASSIC_ALT_PID, 0x03, 0x0C, 0x01);
REGISTER_HID_DETECTOR_IPU("Razer Kraken 7.1 Chroma", DetectRazerKrakenControllers, RAZER_VID, RAZER_KRAKEN_PID, 0x03, 0x0C, 0x01);
REGISTER_HID_DETECTOR_IPU("Razer Kraken 7.1 V2", DetectRazerKrakenControllers, RAZER_VID, RAZER_KRAKEN_V2_PID, 0x03, 0x0C, 0x01);
REGISTER_HID_DETECTOR_IPU("Razer Kraken Kitty Edition", DetectRazerControllers, RAZER_VID, RAZER_KRAKEN_KITTY_EDITION_PID, 0x01, 0x01, 0x03);
REGISTER_HID_DETECTOR_IPU("Razer Kraken Kitty Black Edition", DetectRazerControllers, RAZER_VID, RAZER_KRAKEN_KITTY_BLACK_EDITION_PID, 0x01, 0x01, 0x03);
REGISTER_HID_DETECTOR_IPU("Razer Kraken Kitty Black Edition V2", DetectRazerKrakenControllers, RAZER_VID, RAZER_KRAKEN_KITTY_BLACK_EDITION_V2_PID, 0x03, 0x0C, 0x01);
REGISTER_HID_DETECTOR_IPU("Razer Kraken Ultimate", DetectRazerKrakenControllers, RAZER_VID, RAZER_KRAKEN_ULTIMATE_PID, 0x03, 0x0C, 0x01);
REGISTER_HID_DETECTOR_IPU("Razer Kraken V3 HyperSense", DetectRazerKrakenV3Controllers,RAZER_VID, RAZER_KRAKEN_V3_HYPERSENSE_PID, 0x03, 0x0C, 0x01);
REGISTER_HID_DETECTOR_IPU("Razer Kraken V3 X", DetectRazerKrakenV3Controllers,RAZER_VID, RAZER_KRAKEN_V3_X_PID, 0x03, 0x0C, 0x01);
REGISTER_HID_DETECTOR_IPU("Razer Kraken V3", DetectRazerKrakenV3Controllers,RAZER_VID, RAZER_KRAKEN_V3_PID, 0x03, 0x0C, 0x01);
REGISTER_HID_DETECTOR_IPU("Razer Kraken Kitty V2 Pro", DetectRazerKrakenV3Controllers,RAZER_VID, RAZER_KRAKEN_KITTY_V2_PRO_PID, 0x03, 0x0C, 0x01);
REGISTER_HID_DETECTOR_IPU("Razer Kraken V4 (Wired)", DetectRazerKrakenV4Controllers,RAZER_VID, RAZER_KRAKEN_V4_WIRED_PID, 0x05, 0xFF14, 0x01);
REGISTER_HID_DETECTOR_IPU("Razer Kraken V4 (Wireless)", DetectRazerKrakenV4Controllers,RAZER_VID, RAZER_KRAKEN_V4_WIRELESS_PID, 0x05, 0xFF14, 0x01);
REGISTER_HID_DETECTOR_IPU("Razer Kraken Kitty V3 Pro (Wired)", DetectRazerKrakenV4Controllers,RAZER_VID, RAZER_KRAKEN_KITTY_V3_PRO_WIRED_PID, 0x05, 0xFF14, 0x01);
REGISTER_HID_DETECTOR_IPU("Razer Kraken Kitty V3 Pro (Wireless)", DetectRazerKrakenV4Controllers,RAZER_VID, RAZER_KRAKEN_KITTY_V3_PRO_WIRELESS_PID, 0x05, 0xFF14, 0x01);
REGISTER_HID_DETECTOR_I( "Razer Tiamat 7.1 V2", DetectRazerControllers, RAZER_VID, RAZER_TIAMAT_71_V2_PID, 0x00 );
/*-----------------------------------------------------------------------------------------------------*\
| Mousemats |
\*-----------------------------------------------------------------------------------------------------*/
REGISTER_HID_DETECTOR_IPU("Razer Firefly", DetectRazerControllers, RAZER_VID, RAZER_FIREFLY_PID, 0x00, 0x01, 0x02);
REGISTER_HID_DETECTOR_IPU("Razer Firefly V2", DetectRazerControllers, RAZER_VID, RAZER_FIREFLY_V2_PID, 0x00, 0x01, 0x02);
REGISTER_HID_DETECTOR_IPU("Razer Firefly V2 Pro", DetectRazerControllers, RAZER_VID, RAZER_FIREFLY_V2_PRO_PID, 0x00, 0x01, 0x02);
REGISTER_HID_DETECTOR_IPU("Razer Firefly Hyperflux", DetectRazerControllers, RAZER_VID, RAZER_FIREFLY_HYPERFLUX_PID, 0x00, 0x01, 0x02);
REGISTER_HID_DETECTOR_IPU("Razer Goliathus", DetectRazerControllers, RAZER_VID, RAZER_GOLIATHUS_CHROMA_PID, 0x00, 0x01, 0x02);
REGISTER_HID_DETECTOR_IPU("Razer Goliathus Chroma 3XL", DetectRazerControllers, RAZER_VID, RAZER_GOLIATHUS_CHROMA_3XL_PID, 0x00, 0x01, 0x02);
REGISTER_HID_DETECTOR_IPU("Razer Goliathus Extended", DetectRazerControllers, RAZER_VID, RAZER_GOLIATHUS_CHROMA_EXTENDED_PID, 0x00, 0x01, 0x02);
REGISTER_HID_DETECTOR_IPU("Razer Strider Chroma", DetectRazerControllers, RAZER_VID, RAZER_STRIDER_CHROMA_PID, 0x00, 0x01, 0x02);
/*-----------------------------------------------------------------------------------------------------*\
| Accessories |
\*-----------------------------------------------------------------------------------------------------*/
REGISTER_HID_DETECTOR_IPU("Razer Base Station Chroma", DetectRazerControllers, RAZER_VID, RAZER_BASE_STATION_CHROMA_PID, 0x00, 0x01, 0x02);
REGISTER_HID_DETECTOR_IPU("Razer Base Station V2 Chroma", DetectRazerControllers, RAZER_VID, RAZER_BASE_STATION_V2_CHROMA_PID, 0x00, 0x01, 0x02);
REGISTER_HID_DETECTOR_IPU("Razer Charging Pad Chroma", DetectRazerControllers, RAZER_VID, RAZER_CHARGING_PAD_CHROMA_PID, 0x00, 0x0C, 0x01);
REGISTER_HID_DETECTOR_I("Razer Chroma Addressable RGB Controller", DetectRazerARGBControllers, RAZER_VID, RAZER_CHROMA_ADDRESSABLE_RGB_CONTROLLER_PID, 0x00 );
REGISTER_HID_DETECTOR_IPU("Razer Chroma HDK", DetectRazerControllers, RAZER_VID, RAZER_CHROMA_HDK_PID, 0x02, 0x01, 0x02);
REGISTER_HID_DETECTOR_IPU("Razer Chroma Mug Holder", DetectRazerControllers, RAZER_VID, RAZER_CHROMA_MUG_PID, 0x00, 0x01, 0x02);
REGISTER_HID_DETECTOR_IPU("Razer Chroma PC Case Lighting Kit", DetectRazerControllers, RAZER_VID, RAZER_CHROMA_PC_CASE_LIGHTING_KIT_PID, 0x02, 0x01, 0x02);
REGISTER_HID_DETECTOR_IPU("Razer Core", DetectRazerControllers, RAZER_VID, RAZER_CORE_PID, 0x00, 0xFF00, 0x01);
REGISTER_HID_DETECTOR_IPU("Razer Core X", DetectRazerControllers, RAZER_VID, RAZER_CORE_X_PID, 0x02, 0x01, 0x02);
REGISTER_HID_DETECTOR_IPU("Razer Laptop Stand Chroma", DetectRazerControllers, RAZER_VID, RAZER_LAPTOP_STAND_CHROMA_PID, 0x00, 0x01, 0x02);
REGISTER_HID_DETECTOR_IPU("Razer Laptop Stand Chroma V2", DetectRazerControllers, RAZER_VID, RAZER_LAPTOP_STAND_CHROMA_V2_PID, 0x00, 0x01, 0x02);
REGISTER_HID_DETECTOR_IPU("Razer Leviathan V2", DetectRazerControllers, RAZER_VID, RAZER_LEVIATHAN_V2_PID, 0x02, 0x0C, 0x01);
REGISTER_HID_DETECTOR_IPU("Razer Leviathan V2 X", DetectRazerControllers, RAZER_VID, RAZER_LEVIATHAN_V2X_PID, 0x00, 0x0C, 0x01);
REGISTER_HID_DETECTOR_IPU("Razer Mouse Bungee V3 Chroma", DetectRazerControllers, RAZER_VID, RAZER_MOUSE_BUNGEE_V3_CHROMA_PID, 0x00, 0x01, 0x02);
REGISTER_HID_DETECTOR_IPU("Razer Mouse Dock Chroma", DetectRazerControllers, RAZER_VID, RAZER_MOUSE_DOCK_CHROMA_PID, 0x00, 0x01, 0x02);
REGISTER_HID_DETECTOR_IPU("Razer Mouse Dock Pro", DetectRazerControllers, RAZER_VID, RAZER_MOUSE_DOCK_PRO_PID, 0x00, 0x01, 0x02);
REGISTER_HID_DETECTOR_IPU("Lian Li O11 Dynamic - Razer Edition", DetectRazerControllers, RAZER_VID, RAZER_O11_DYNAMIC_PID, 0x02, 0x01, 0x02);
REGISTER_HID_DETECTOR_PU("Razer Seiren Emote", DetectRazerControllers, RAZER_VID, RAZER_SEIREN_EMOTE_PID, 0x0C, 0x01 );
REGISTER_HID_DETECTOR_PU("Razer Thunderbolt 4 Dock Chroma", DetectRazerControllers, RAZER_VID, RAZER_THUNDERBOLT_4_DOCK_CHROMA_PID, 0x0C, 0x01 );
REGISTER_HID_DETECTOR_PU("Razer Thunderbolt 5 Dock Chroma", DetectRazerControllers, RAZER_VID, RAZER_THUNDERBOLT_5_DOCK_CHROMA_PID, 0x0C, 0x01 );
REGISTER_HID_DETECTOR_IPU("Razer Hanbo Chroma", DetectRazerHanboControllers, RAZER_VID, RAZER_HANBO_CHROMA_PID, 0x00, 0xFF00, 0x01);
/*-----------------------------------------------------------------------------------------------------*\
| Nommo devices seem to have an issue where interface 1 doesn't show on Linux or MacOS. Due to the way |
| hidapi works on these operating systems, it is acceptable to use interface 0 instead. Interface 1 |
| must be used on Windows. |
\*-----------------------------------------------------------------------------------------------------*/
#ifdef _WIN32
REGISTER_HID_DETECTOR_IPU("Razer Nommo Chroma", DetectRazerControllers, RAZER_VID, RAZER_NOMMO_CHROMA_PID, 0x01, 0x01, 0x03);
REGISTER_HID_DETECTOR_IPU("Razer Nommo Pro", DetectRazerControllers, RAZER_VID, RAZER_NOMMO_PRO_PID, 0x01, 0x01, 0x03);
#else
REGISTER_HID_DETECTOR_IPU("Razer Nommo Chroma", DetectRazerControllers, RAZER_VID, RAZER_NOMMO_CHROMA_PID, 0x00, 0x01, 0x00);
REGISTER_HID_DETECTOR_IPU("Razer Nommo Pro", DetectRazerControllers, RAZER_VID, RAZER_NOMMO_PRO_PID, 0x00, 0x01, 0x00);
#endif
/*-----------------------------------------------------------------------------------------------------*\
| Need to clean up some stuff before we scan/rescan |
\*-----------------------------------------------------------------------------------------------------*/
REGISTER_PRE_DETECTION_HOOK(ResetRazerARGBControllersPaths);
@@ -0,0 +1,64 @@
/*---------------------------------------------------------*\
| RazerDeviceGuard.cpp |
| |
| DeviceGuard for Razer devices |
| |
| Aytac Kayadelen 18 May 2024 |
| |
| This file is part of the OpenRGB project |
| SPDX-License-Identifier: GPL-2.0-or-later |
\*---------------------------------------------------------*/
#include "RazerDeviceGuard.h"
RazerDeviceGuard::RazerDeviceGuard() : DeviceGuard()
{
#ifdef _WIN32
mutex_handle = CreateWindowsMutex();
#endif
}
void RazerDeviceGuard::Acquire()
{
#ifdef _WIN32
while(true)
{
DWORD result = WaitForSingleObject(mutex_handle, INFINITE);
if(result == WAIT_OBJECT_0)
{
break;
}
if(result == WAIT_ABANDONED)
{
ReleaseMutex(mutex_handle);
}
}
#endif
}
void RazerDeviceGuard::Release()
{
#ifdef _WIN32
ReleaseMutex(mutex_handle);
#endif
}
#ifdef _WIN32
HANDLE RazerDeviceGuard::CreateWindowsMutex()
{
SECURITY_DESCRIPTOR sd;
InitializeSecurityDescriptor(&sd, SECURITY_DESCRIPTOR_REVISION);
SetSecurityDescriptorDacl(&sd, TRUE, NULL, FALSE);
SECURITY_ATTRIBUTES sa;
sa.nLength = sizeof(SECURITY_ATTRIBUTES);
sa.lpSecurityDescriptor = &sd;
sa.bInheritHandle = FALSE;
return CreateMutex(&sa, FALSE, "Global\\RazerLinkReadWriteGuardMutex");
}
#endif
@@ -0,0 +1,34 @@
/*---------------------------------------------------------*\
| RazerDeviceGuard.h |
| |
| DeviceGuard for Razer devices |
| |
| Aytac Kayadelen 18 May 2024 |
| |
| This file is part of the OpenRGB project |
| SPDX-License-Identifier: GPL-2.0-or-later |
\*---------------------------------------------------------*/
#pragma once
#include "DeviceGuard.h"
#ifdef _WIN32
#include <Windows.h>
#endif
class RazerDeviceGuard : public DeviceGuard
{
public:
RazerDeviceGuard();
void Acquire() override;
void Release() override;
private:
#ifdef _WIN32
HANDLE mutex_handle;
HANDLE CreateWindowsMutex();
#endif
};
File diff suppressed because it is too large Load Diff
+308
View File
@@ -0,0 +1,308 @@
/*---------------------------------------------------------*\
| RazerDevices.h |
| |
| Device list for Razer devices |
| |
| Adam Honse (CalcProgrammer1) 04 Sep 2021 |
| |
| This file is part of the OpenRGB project |
| SPDX-License-Identifier: GPL-2.0-or-later |
\*---------------------------------------------------------*/
#pragma once
#include <string>
#include "RGBController.h"
#include "RGBControllerKeyNames.h"
#include "RazerController.h"
#include "KeyboardLayoutManager.h"
/*-----------------------------------------------------*\
| Razer vendor ID |
\*-----------------------------------------------------*/
#define RAZER_VID 0x1532
#define RAZER_BLUETOOTH_VID 0x068E
/*-----------------------------------------------------*\
| Razer maximum zones |
| If a new device has more than RAZER_MAX_ZONES, |
| increment RAZER_MAX_ZONES and update all device |
| tables accordingly. |
\*-----------------------------------------------------*/
#define RAZER_MAX_ZONES 6
/*-----------------------------------------------------*\
| Keyboard product IDs |
| List taken from OpenRazer |
| Non-RGB keyboards were omitted from this list |
\*-----------------------------------------------------*/
#define RAZER_BLACKWIDOW_2019_PID 0x0241
#define RAZER_BLACKWIDOW_CHROMA_PID 0x0203
#define RAZER_BLACKWIDOW_CHROMA_TE_PID 0x0209
#define RAZER_BLACKWIDOW_CHROMA_V2_PID 0x0221
#define RAZER_BLACKWIDOW_ELITE_PID 0x0228
#define RAZER_BLACKWIDOW_ESSENTIAL_PID 0x0237
#define RAZER_BLACKWIDOW_LITE_PID 0x0235
#define RAZER_BLACKWIDOW_OVERWATCH_PID 0x0211
#define RAZER_BLACKWIDOW_V3_PID 0x024E
#define RAZER_BLACKWIDOW_V3_MINI_WIRED_PID 0x0258
#define RAZER_BLACKWIDOW_V3_MINI_WIRELESS_PID 0x0271
#define RAZER_BLACKWIDOW_V3_PRO_WIRED_PID 0x025A
#define RAZER_BLACKWIDOW_V3_PRO_BLUETOOTH_PID 0x025B
#define RAZER_BLACKWIDOW_V3_PRO_WIRELESS_PID 0x025C
#define RAZER_BLACKWIDOW_V3_TKL_PID 0x0A24
#define RAZER_BLACKWIDOW_V4_PID 0x0287
#define RAZER_BLACKWIDOW_V4_PRO_PID 0x028D
#define RAZER_BLACKWIDOW_V4_X_PID 0x0293
#define RAZER_BLACKWIDOW_V4_PRO_75_WIRED_PID 0x02B3
#define RAZER_BLACKWIDOW_V4_PRO_75_WIRELESS_PID 0x02B4
#define RAZER_BLACKWIDOW_V4_75_WIRED_PID 0x02A5
#define RAZER_BLACKWIDOW_V4_TKL_WIRED_PID 0x02D7
#define RAZER_BLACKWIDOW_V4_TKL_WIRELESS_PID 0x02D5
#define RAZER_BLACKWIDOW_V4_LOWPROFILE_TKL_WIRED_PID 0x02D4
#define RAZER_BLACKWIDOW_V4_LOWPROFILE_TKL_WIRELESS_PID 0x02D2
#define RAZER_BLACKWIDOW_X_CHROMA_PID 0x0216
#define RAZER_BLACKWIDOW_X_CHROMA_TE_PID 0x021A
#define RAZER_BLADE_2016_PID 0x020F
#define RAZER_BLADE_LATE_2016_PID 0x0224
#define RAZER_BLADE_2018_ADVANCED_PID 0x0233
#define RAZER_BLADE_2018_BASE_PID 0x023B
#define RAZER_BLADE_2018_MERCURY_PID 0x0240
#define RAZER_BLADE_2019_ADVANCED_PID 0x023A
#define RAZER_BLADE_2019_BASE_PID 0x0246
#define RAZER_BLADE_2019_MERCURY_PID 0x0245
#define RAZER_BLADE_2019_STUDIO_PID 0x024D
#define RAZER_BLADE_2020_ADVANCED_PID 0x0253
#define RAZER_BLADE_2020_BASE_PID 0x0255
#define RAZER_BLADE_LATE_2020_PID 0x0268
#define RAZER_BLADE_2021_ADVANCED_PID 0x026D
#define RAZER_BLADE_2021_BASE_PID 0x026F
#define RAZER_BLADE_2021_BASE_V2_PID 0x027A
#define RAZER_BLADE_LATE_2021_ADVANCED_PID 0x0276
#define RAZER_BLADE_14_2021_PID 0x0270
#define RAZER_BLADE_14_2022_PID 0x028C
#define RAZER_BLADE_14_2023_PID 0x029D
#define RAZER_BLADE_15_2022_PID 0x028A
#define RAZER_BLADE_PRO_2016_PID 0x0210
#define RAZER_BLADE_PRO_2017_PID 0x0225
#define RAZER_BLADE_PRO_2017_FULLHD_PID 0x022F
#define RAZER_BLADE_PRO_2019_PID 0x0234
#define RAZER_BLADE_PRO_LATE_2019_PID 0x024C
#define RAZER_BLADE_PRO_17_2020_PID 0x0256
#define RAZER_BLADE_PRO_17_2021_PID 0x0279
#define RAZER_BLADE_STEALTH_2016_PID 0x0205
#define RAZER_BLADE_STEALTH_LATE_2016_PID 0x0220
#define RAZER_BLADE_STEALTH_2017_PID 0x022D
#define RAZER_BLADE_STEALTH_LATE_2017_PID 0x0232
#define RAZER_BLADE_STEALTH_2019_PID 0x0239
#define RAZER_BLADE_STEALTH_LATE_2019_PID 0x024A
#define RAZER_BLADE_STEALTH_2020_PID 0x0252
#define RAZER_BLADE_STEALTH_LATE_2020_PID 0x0259
#define RAZER_BOOK_13_2020_PID 0x026A
#define RAZER_CYNOSA_CHROMA_PID 0x022A
#define RAZER_CYNOSA_LITE_PID 0x023F
#define RAZER_CYNOSA_V2_PID 0x025E
#define RAZER_DEATHSTALKER_CHROMA_PID 0x0204
#define RAZER_DEATHSTALKER_V2_PID 0x0295
#define RAZER_DEATHSTALKER_V2_PRO_TKL_WIRELESS_PID 0x0296
#define RAZER_DEATHSTALKER_V2_PRO_TKL_WIRED_PID 0x0298
#define RAZER_DEATHSTALKER_V2_PRO_TKL_BT_PID 0x0297
#define RAZER_DEATHSTALKER_V2_PRO_WIRELESS_PID 0x0290
#define RAZER_DEATHSTALKER_V2_PRO_WIRED_PID 0x0292
#define RAZER_HUNTSMAN_ELITE_PID 0x0226
#define RAZER_HUNTSMAN_PID 0x0227
#define RAZER_HUNTSMAN_MINI_PID 0x0257
#define RAZER_HUNTSMAN_MINI_ANALOG_PID 0x0282
#define RAZER_HUNTSMAN_TE_PID 0x0243
#define RAZER_HUNTSMAN_V2_ANALOG_PID 0x0266
#define RAZER_HUNTSMAN_V2_TKL_PID 0x026B
#define RAZER_HUNTSMAN_V2_PID 0x026C
#define RAZER_HUNTSMAN_V3_PRO_PID 0x02A6
#define RAZER_HUNTSMAN_V3_PRO_TKL_WHITE_PID 0x02A7
#define RAZER_ORBWEAVER_CHROMA_PID 0x0207
#define RAZER_ORNATA_CHROMA_PID 0x021E
#define RAZER_ORNATA_CHROMA_V2_PID 0x025D
#define RAZER_ORNATA_V3_PID 0x028F
#define RAZER_ORNATA_V3_REV2_PID 0x02A1
#define RAZER_ORNATA_V3_TKL_PID 0x02A3
#define RAZER_ORNATA_V3_X_PID 0x0294
#define RAZER_ORNATA_V3_X_REV2_PID 0x02A2
#define RAZER_TARTARUS_CHROMA_PID 0x0208
#define RAZER_TARTARUS_PRO_PID 0x0244
#define RAZER_TARTARUS_V2_PID 0x022B
/*-----------------------------------------------------*\
| Mouse product IDs |
| List taken from OpenRazer |
\*-----------------------------------------------------*/
#define RAZER_ABYSSUS_1800_PID 0x0020
#define RAZER_ABYSSUS_2000_PID 0x005E
#define RAZER_ABYSSUS_ELITE_DVA_EDITION_PID 0x006A
#define RAZER_ABYSSUS_ESSENTIAL_PID 0x006B
#define RAZER_ABYSSUS_PID 0x0042
#define RAZER_ABYSSUS_V2_PID 0x005B
#define RAZER_ATHERIS_RECEIVER_PID 0x0062
#define RAZER_BASILISK_PID 0x0064
#define RAZER_BASILISK_ESSENTIAL_PID 0x0065
#define RAZER_BASILISK_ULTIMATE_WIRED_PID 0x0086
#define RAZER_BASILISK_ULTIMATE_WIRELESS_PID 0x0088
#define RAZER_BASILISK_X_HYPERSPEED_PID 0x0083
#define RAZER_BASILISK_V2_PID 0x0085
#define RAZER_BASILISK_V3_PID 0x0099
#define RAZER_BASILISK_V3_35K_PID 0x00CB
#define RAZER_BASILISK_V3_PRO_WIRED_PID 0x00AA
#define RAZER_BASILISK_V3_PRO_WIRELESS_PID 0x00AB
#define RAZER_BASILISK_V3_PRO_35K_WIRED_PID 0x00CC
#define RAZER_BASILISK_V3_PRO_35K_WIRELESS_PID 0x00CD
#define RAZER_BASILISK_V3_PRO_35K_PG_WIRED_PID 0x00D6
#define RAZER_BASILISK_V3_PRO_35K_PG_WIRELESS_PID 0x00D7
#define RAZER_BASILISK_V3_PRO_35K_PG_BLUETOOTH_PID 0x00D8
#define RAZER_BASILISK_V3_PRO_BLUETOOTH_PID 0x00AC
#define RAZER_BASILISK_V3_X_HYPERSPEED_PID 0x00B9
#define RAZER_COBRA_PID 0x00A3
#define RAZER_COBRA_PRO_WIRED_PID 0x00AF
#define RAZER_COBRA_PRO_WIRELESS_PID 0x00B0
#define RAZER_DEATHADDER_1800_PID 0x0038
#define RAZER_DEATHADDER_2000_PID 0x004F
#define RAZER_DEATHADDER_2013_PID 0x0037
#define RAZER_DEATHADDER_3_5G_PID 0x0016
#define RAZER_DEATHADDER_3500_PID 0x0054
#define RAZER_DEATHADDER_CHROMA_PID 0x0043
#define RAZER_DEATHADDER_ELITE_PID 0x005C
#define RAZER_DEATHADDER_ESSENTIAL_PID 0x006E
#define RAZER_DEATHADDER_ESSENTIAL_V2_PID 0x0098
#define RAZER_DEATHADDER_ESSENTIAL_WHITE_EDITION_PID 0x0071
#define RAZER_DEATHADDER_V2_MINI_PID 0x008C
#define RAZER_DEATHADDER_V2_PID 0x0084
#define RAZER_DEATHADDER_V2_PRO_WIRED_PID 0x007C
#define RAZER_DEATHADDER_V2_PRO_WIRELESS_PID 0x007D
#define RAZER_DIAMONDBACK_CHROMA_PID 0x004C
#define RAZER_IMPERATOR_PID 0x002F
#define RAZER_LANCEHEAD_TE_WIRED_PID 0x0060
#define RAZER_LANCEHEAD_2017_WIRED_PID 0x0059
#define RAZER_LANCEHEAD_2017_WIRELESS_PID 0x005A
#define RAZER_LANCEHEAD_2019_WIRED_PID 0x0070
#define RAZER_LANCEHEAD_2019_WIRELESS_PID 0x006F
#define RAZER_MAMBA_2012_WIRED_PID 0x0024
#define RAZER_MAMBA_2012_WIRELESS_PID 0x0025
#define RAZER_MAMBA_2015_WIRED_PID 0x0044
#define RAZER_MAMBA_2015_WIRELESS_PID 0x0045
#define RAZER_MAMBA_2018_WIRED_PID 0x0073
#define RAZER_MAMBA_2018_WIRELESS_PID 0x0072
#define RAZER_MAMBA_ELITE_PID 0x006C
#define RAZER_MAMBA_HYPERFLUX_PID 0x0069
#define RAZER_MAMBA_TE_PID 0x0046
#define RAZER_NAGA_2012_PID 0x002E
#define RAZER_NAGA_2014_PID 0x0040
#define RAZER_NAGA_CHROMA_PID 0x0053
#define RAZER_NAGA_CLASSIC_PID 0x0093
#define RAZER_NAGA_EPIC_CHROMA_DOCK_PID 0x003F
#define RAZER_NAGA_EPIC_CHROMA_PID 0x003E
#define RAZER_NAGA_HEX_PID 0x0041
#define RAZER_NAGA_HEX_RED_PID 0x0036
#define RAZER_NAGA_HEX_V2_PID 0x0050
#define RAZER_NAGA_LEFT_HANDED_PID 0x008D
#define RAZER_NAGA_TRINITY_PID 0x0067
#define RAZER_NAGA_PRO_WIRED_PID 0x008F
#define RAZER_NAGA_PRO_WIRELESS_PID 0x0090
#define RAZER_NAGA_PRO_V2_WIRED_PID 0x00A7
#define RAZER_NAGA_PRO_V2_WIRELESS_PID 0x00A8
#define RAZER_OROCHI_2011_PID 0x0013
#define RAZER_OROCHI_2013_PID 0x0039
#define RAZER_OROCHI_CHROMA_PID 0x0048
#define RAZER_OUROBOROS_PID 0x0032
#define RAZER_TAIPAN_PID 0x0034
#define RAZER_VIPER_8KHZ_PID 0x0091
#define RAZER_VIPER_MINI_PID 0x008A
#define RAZER_VIPER_PID 0x0078
#define RAZER_VIPER_ULTIMATE_WIRED_PID 0x007A
#define RAZER_VIPER_ULTIMATE_WIRELESS_PID 0x007B
/*-----------------------------------------------------*\
| Headset product IDs |
\*-----------------------------------------------------*/
#define RAZER_KRAKEN_CLASSIC_ALT_PID 0x0506
#define RAZER_KRAKEN_CLASSIC_PID 0x0501
#define RAZER_KRAKEN_KITTY_EDITION_PID 0x0F19
#define RAZER_KRAKEN_KITTY_BLACK_EDITION_PID 0x0F21
#define RAZER_KRAKEN_PID 0x0504
#define RAZER_KRAKEN_ULTIMATE_PID 0x0527
#define RAZER_KRAKEN_V2_PID 0x0510
#define RAZER_KRAKEN_KITTY_BLACK_EDITION_V2_PID 0x0560
#define RAZER_KRAKEN_V3_HYPERSENSE_PID 0x0533
#define RAZER_KRAKEN_V3_X_PID 0x0537
#define RAZER_KRAKEN_V3_PID 0x0549
#define RAZER_KRAKEN_KITTY_V2_PRO_PID 0x0554
#define RAZER_KRAKEN_V4_WIRED_PID 0x056B
#define RAZER_KRAKEN_V4_WIRELESS_PID 0x056C
#define RAZER_KRAKEN_KITTY_V3_PRO_WIRED_PID 0x0587
#define RAZER_KRAKEN_KITTY_V3_PRO_WIRELESS_PID 0x0588
#define RAZER_TIAMAT_71_V2_PID 0x0F03
/*-----------------------------------------------------*\
| Accessory product IDs |
| List taken from OpenRazer |
\*-----------------------------------------------------*/
#define RAZER_BASE_STATION_CHROMA_PID 0x0F08
#define RAZER_BASE_STATION_V2_CHROMA_PID 0x0F20
#define RAZER_CHARGING_PAD_CHROMA_PID 0x0F26
#define RAZER_CHROMA_ADDRESSABLE_RGB_CONTROLLER_PID 0x0F1F
#define RAZER_CHROMA_HDK_PID 0x0F09
#define RAZER_CHROMA_MUG_PID 0x0F07
#define RAZER_CHROMA_PC_CASE_LIGHTING_KIT_PID 0x0F0E
#define RAZER_CORE_PID 0x0215
#define RAZER_CORE_X_PID 0x0F1A
#define RAZER_FIREFLY_HYPERFLUX_PID 0x0068
#define RAZER_FIREFLY_PID 0x0C00
#define RAZER_FIREFLY_V2_PID 0x0C04
#define RAZER_FIREFLY_V2_PRO_PID 0x0C08
#define RAZER_GOLIATHUS_CHROMA_EXTENDED_PID 0x0C02
#define RAZER_GOLIATHUS_CHROMA_PID 0x0C01
#define RAZER_GOLIATHUS_CHROMA_3XL_PID 0x0C06
#define RAZER_LAPTOP_STAND_CHROMA_PID 0x0F0D
#define RAZER_LAPTOP_STAND_CHROMA_V2_PID 0x0F2B
#define RAZER_LEVIATHAN_V2_PID 0x0532
#define RAZER_LEVIATHAN_V2X_PID 0x054A
#define RAZER_MOUSE_BUNGEE_V3_CHROMA_PID 0x0F1D
#define RAZER_MOUSE_DOCK_CHROMA_PID 0x007E
#define RAZER_MOUSE_DOCK_PRO_PID 0x00A4
#define RAZER_NOMMO_CHROMA_PID 0x0517
#define RAZER_NOMMO_PRO_PID 0x0518
#define RAZER_O11_DYNAMIC_PID 0x0F13
#define RAZER_SEIREN_EMOTE_PID 0x0F1B
#define RAZER_STRIDER_CHROMA_PID 0x0C05
#define RAZER_THUNDERBOLT_4_DOCK_CHROMA_PID 0x0F21
#define RAZER_THUNDERBOLT_5_DOCK_CHROMA_PID 0x0F52
#define RAZER_HANBO_CHROMA_PID 0x0F35
typedef struct
{
std::string name;
unsigned int type;
unsigned int rows;
unsigned int cols;
} razer_zone;
typedef struct
{
std::string name;
unsigned short pid;
device_type type;
unsigned char matrix_type;
unsigned char transaction_id;
unsigned int rows;
unsigned int cols;
const razer_zone* zones[RAZER_MAX_ZONES];
keyboard_keymap_overlay_values* layout;
} razer_device;
/*-----------------------------------------------------*\
| These constant values are defined in RazerDevices.cpp |
\*-----------------------------------------------------*/
extern const unsigned int RAZER_NUM_DEVICES;
extern const razer_device** device_list;
@@ -0,0 +1,189 @@
/*---------------------------------------------------------*\
| RGBController_RazerHanbo.cpp |
| |
| RGBController for Razer Hanbo devices |
| |
| Joseph East (dripsnek) 12 Apr 2025 |
| |
| This file is part of the OpenRGB project |
| SPDX-License-Identifier: GPL-2.0-or-later |
\*---------------------------------------------------------*/
#include "RGBController_RazerHanbo.h"
#include "RazerDevices.h"
/**------------------------------------------------------------------*\
@name Razer Hanbo Chroma
@category Cooler
@type USB
@save :robot:
@direct :white_check_mark:
@effects :white_check_mark:
@detectors DetectRazerHanboControllers
@comment
\*-------------------------------------------------------------------*/
RGBController_RazerHanbo::RGBController_RazerHanbo(RazerHanboController* controller_ptr)
{
controller = controller_ptr;
name = controller->GetName();
vendor = "Razer";
type = controller->GetDeviceType();
description = "Razer Hanbo Device";
location = controller->GetDeviceLocation();
version = controller->GetFirmwareString();
serial = controller->GetSerialString();
mode Direct;
Direct.name = "Direct";
Direct.value = RAZER_HANBO_MODE_DIRECT;
Direct.flags = MODE_FLAG_HAS_PER_LED_COLOR;
Direct.color_mode = MODE_COLORS_PER_LED;
Direct.brightness_min = MIN_BRIGHTNESS;
Direct.brightness_max = MAX_BRIGHTNESS;
Direct.brightness = MAX_BRIGHTNESS/2;
modes.push_back(Direct);
mode Off;
Off.name = "Off";
Off.value = RAZER_HANBO_MODE_OFF;
Off.flags = 0;
Off.color_mode = MODE_COLORS_NONE;
modes.push_back(Off);
mode SpectrumCycle;
SpectrumCycle.name = "Spectrum Cycle";
SpectrumCycle.value = RAZER_HANBO_MODE_SPECTRUM_CYCLE;
SpectrumCycle.flags = 0;
SpectrumCycle.color_mode = MODE_COLORS_NONE;
modes.push_back(SpectrumCycle);
local_mode = RAZER_HANBO_MODE_DIRECT;
SetupZones();
}
RGBController_RazerHanbo::~RGBController_RazerHanbo()
{
delete controller;
}
void RGBController_RazerHanbo::SetupZones()
{
unsigned int device_index = controller->GetDeviceIndex();
/*---------------------------------------------------------*\
| Fill in zone information based on device table |
\*---------------------------------------------------------*/
for(unsigned int zone_id = 0; zone_id < RAZER_MAX_ZONES; zone_id++)
{
if(device_list[device_index]->zones[zone_id] != NULL)
{
zone new_zone;
new_zone.name = device_list[device_index]->zones[zone_id]->name;
new_zone.type = device_list[device_index]->zones[zone_id]->type;
new_zone.leds_count = device_list[device_index]->zones[zone_id]->rows * device_list[device_index]->zones[zone_id]->cols;
new_zone.leds_min = new_zone.leds_count;
new_zone.leds_max = new_zone.leds_count;
if(new_zone.type == ZONE_TYPE_MATRIX)
{
matrix_map_type * new_map = new matrix_map_type;
new_zone.matrix_map = new_map;
new_map->height = device_list[device_index]->zones[zone_id]->rows;
new_map->width = device_list[device_index]->zones[zone_id]->cols;
new_map->map = new unsigned int[new_map->height * new_map->width];
for(unsigned int y = 0; y < new_map->height; y++)
{
for(unsigned int x = 0; x < new_map->width; x++)
{
new_map->map[(y * new_map->width) + x] = (y * new_map->width) + x;
}
}
}
else
{
new_zone.matrix_map = NULL;
}
zones.push_back(new_zone);
}
}
for(unsigned int zone_id = 0; zone_id < zones.size(); zone_id++)
{
for(unsigned int row_id = 0; row_id < device_list[device_index]->zones[zone_id]->rows; row_id++)
{
for(unsigned int col_id = 0; col_id < device_list[device_index]->zones[zone_id]->cols; col_id++)
{
led* new_led = new led();
new_led->name = device_list[device_index]->zones[zone_id]->name;
if(zones[zone_id].leds_count > 1)
{
new_led->name.append(" LED ");
new_led->name.append(std::to_string(col_id + 1));
}
leds.push_back(*new_led);
}
}
}
SetupColors();
}
void RGBController_RazerHanbo::ResizeZone(int /*zone*/, int /*new_size*/)
{
/*---------------------------------------------------------*\
| This device does not support resizing zones |
\*---------------------------------------------------------*/
}
void RGBController_RazerHanbo::DeviceUpdateLEDs()
{
UpdateZoneLEDs(PUMP);
UpdateZoneLEDs(FAN1);
UpdateZoneLEDs(FAN2);
UpdateZoneLEDs(FAN3);
}
/*---------------------------------------------------------*\
| The Hanbo command set is arranged in terms of zones. |
| Transactions are straight forward when grouped this way. |
\*---------------------------------------------------------*/
void RGBController_RazerHanbo::UpdateZoneLEDs(int zoneid)
{
controller->SetZoneLeds(zoneid, this->zones[zoneid]);
}
void RGBController_RazerHanbo::UpdateSingleLED(int /*led*/)
{
DeviceUpdateLEDs();
}
void RGBController_RazerHanbo::DeviceUpdateMode()
{
switch(modes[active_mode].value)
{
case RAZER_HANBO_MODE_DIRECT:
if(local_mode != RAZER_HANBO_MODE_DIRECT)
controller->SetDirectMode();
break;
case RAZER_HANBO_MODE_OFF:
controller->SetModeOff();
break;
case RAZER_HANBO_MODE_SPECTRUM_CYCLE:
controller->SetModeSpectrumCycle();
break;
}
local_mode = modes[active_mode].value;
}
@@ -0,0 +1,43 @@
/*---------------------------------------------------------*\
| RGBController_Razer.h |
| |
| RGBController for Razer Hanbo devices |
| |
| Joseph East (dripsnek) 12 Apr 2025 |
| |
| This file is part of the OpenRGB project |
| SPDX-License-Identifier: GPL-2.0-or-later |
\*---------------------------------------------------------*/
#pragma once
#include "RGBController.h"
#include "RazerHanboController.h"
enum
{
RAZER_HANBO_MODE_DIRECT,
RAZER_HANBO_MODE_OFF,
RAZER_HANBO_MODE_SPECTRUM_CYCLE,
};
class RGBController_RazerHanbo : public RGBController
{
public:
RGBController_RazerHanbo(RazerHanboController* controller_ptr);
~RGBController_RazerHanbo();
void SetupZones();
void ResizeZone(int zone, int new_size);
void DeviceUpdateLEDs();
void UpdateZoneLEDs(int zone);
void UpdateSingleLED(int led);
void DeviceUpdateMode();
private:
RazerHanboController* controller;
int local_mode;
};
@@ -0,0 +1,262 @@
/*---------------------------------------------------------*\
| RazerHanboController.cpp |
| |
| Driver for Razer Hanbo devices |
| |
| Joseph East (dripsnek) 12 Apr 2025 |
| |
| This file is part of the OpenRGB project |
| SPDX-License-Identifier: GPL-2.0-or-later |
\*---------------------------------------------------------*/
#include <string.h>
#include "RazerHanboController.h"
#include "RazerDevices.h"
using namespace std::chrono_literals;
RazerHanboController::RazerHanboController(hid_device* dev_handle, const char* path, unsigned short pid, std::string dev_name)
{
dev = dev_handle;
dev_pid = pid;
location = path;
name = dev_name;
device_index = 0;
for(unsigned int i = 0; i < RAZER_NUM_DEVICES; i++)
{
if(device_list[i]->pid == dev_pid)
{
device_index = i;
}
}
GetFirmware();
SetDirectMode();
}
RazerHanboController::~RazerHanboController()
{
hid_close(dev);
}
unsigned int RazerHanboController::GetDeviceIndex()
{
return(device_index);
}
device_type RazerHanboController::GetDeviceType()
{
return(device_list[device_index]->type);
}
std::string RazerHanboController::GetDeviceLocation()
{
return("HID: " + location);
}
std::string RazerHanboController::GetFirmwareString()
{
return firmware_version;
}
std::string RazerHanboController::GetSerialString()
{
return serial_string;
}
std::string RazerHanboController::GetName()
{
return(name);
}
void RazerHanboController::SetDirectMode()
{
razer_hanbo_report request_report = razer_hanbo_create_report(0x82);
razer_hanbo_report response_report = razer_hanbo_create_report(0x00);
/*---------------------------------------*\
| Take the one request and transform as |
| appropriate for the sequence. |
\*---------------------------------------*/
request_report.arguments[0] = 0x01;
UsbSend(&request_report);
UsbReceive(&response_report);
request_report.header[1] = 0x80;
request_report.arguments[0] = 0x01;
request_report.arguments[1] = 0x00;
request_report.arguments[2] = 0x01;
UsbSend(&request_report);
UsbReceive(&response_report);
request_report.header[1] = 0x80;
request_report.arguments[0] = 0x01;
request_report.arguments[1] = 0x01;
request_report.arguments[2] = 0x01;
UsbSend(&request_report);
UsbReceive(&response_report);
memset(&request_report, 0, sizeof(razer_hanbo_report));
request_report.header[1] = 0x82;
request_report.arguments[0] = 0x01;
UsbSend(&request_report);
UsbReceive(&response_report);
}
void RazerHanboController::SetModeOff()
{
SetDirectMode();
}
void RazerHanboController::SetModeSpectrumCycle()
{
razer_hanbo_report request_report = razer_hanbo_create_report(0x82);
razer_hanbo_report response_report = razer_hanbo_create_report(0x00);
request_report.arguments[0] = 0x01;
UsbSend(&request_report);
UsbReceive(&response_report);
request_report.header[1] = 0x80;
request_report.arguments[0] = 0x01;
UsbSend(&request_report);
UsbReceive(&response_report);
request_report.header[1] = 0x80;
request_report.arguments[0] = 0x01;
request_report.arguments[1] = 0x01;
UsbSend(&request_report);
UsbReceive(&response_report);
}
void RazerHanboController::SetZoneLeds(int zone_idx, const zone& input_zone)
{
razer_hanbo_report request_report = razer_hanbo_create_report(0x32);
std::string payload;
unsigned int j = 0;
if(zone_idx > PUMP)
request_report.header[1] = 0x40;
payload = "0107000000000" + std::to_string(zone_idx);
for(unsigned int i = 0; i < payload.length(); i += 2)
{
std::string byteString = payload.substr(i, 2);
char byte = (char)strtol(byteString.c_str(), NULL, 16);
request_report.arguments[j] = byte;
j++;
}
/*--------------------------------------------*\
| The color command format is G/R/B |
\*--------------------------------------------*/
for(unsigned int i = 0; i < input_zone.leds_count; i++)
{
request_report.arguments[j] = RGBGetGValue(input_zone.colors[i]);
j++;
request_report.arguments[j] = RGBGetRValue(input_zone.colors[i]);
j++;
request_report.arguments[j] = RGBGetBValue(input_zone.colors[i]);
j++;
}
/*--------------------------------------------*\
| Writing RGB values does not generate ack |
| reports from the cooler. Add a gap between |
| transactions to not overwhelm it. |
\*--------------------------------------------*/
UsbSend(&request_report);
std::this_thread::sleep_for(2ms);
}
/*--------------------------------------------*\
| The Hanbo allows for individual brightness |
| of the pump cap and fans. OpenRGB only has |
| a single brightness slider. Whilst this |
| function can support individual settings, |
| most of the time they will be invoked with |
| identical values |
\*--------------------------------------------*/
void RazerHanboController::SetBrightness(int zone, unsigned int brightness)
{
razer_hanbo_report request_report = razer_hanbo_create_report(0x70);
razer_hanbo_report response_report = razer_hanbo_create_report(0x00);
request_report.arguments[0] = 0x01;
request_report.arguments[1] = 0x00;
if(zone > PUMP)
request_report.arguments[1] = 0x01;
request_report.arguments[2] = brightness & 0xFF;
UsbSend(&request_report);
UsbReceive(&response_report);
}
/*---------------------------------------------------------------------------------*\
| Basic report and response creation function |
\*---------------------------------------------------------------------------------*/
razer_hanbo_report RazerHanboController::razer_hanbo_create_report(unsigned char header)
{
/*---------------------------------------------------------*\
| One type supports both requests and responses. |
| Requests start at header[1] to provide a dummy byte. |
| Responses provide 0 to this function for consistency |
\*---------------------------------------------------------*/
razer_hanbo_report new_report;
memset(&new_report, 0, sizeof(razer_hanbo_report));
new_report.header[1] = header;
return new_report;
}
/*---------------------------------------------------------------------------------*\
| Get functions (request information from device) |
\*---------------------------------------------------------------------------------*/
void RazerHanboController::GetFirmware()
{
razer_hanbo_report request_report = razer_hanbo_create_report(0x01);
razer_hanbo_report response_report = razer_hanbo_create_report(0x00);
request_report.arguments[0] = 0x01;
UsbSend(&request_report);
/*---------------------------------------*\
| The Hanbo sends firmware reports twice |
\*---------------------------------------*/
UsbReceive(&response_report);
UsbReceive(&response_report);
if(response_report.header[0] == 0x02)
{
std::string ret_serial(response_report.arguments, response_report.arguments+15);
std::vector<unsigned char> firmware_ret(response_report.arguments+27, response_report.arguments+29);
char major = firmware_ret[0];
char minor = firmware_ret[1] >> 4 & 0x0F;
char patch = firmware_ret[1] & 0x0F;
char ver[12];
snprintf(ver, sizeof(ver), "%hhu.%hhu.%hhu", major, minor, patch);
serial_string = ret_serial;
firmware_version = std::string(ver);
}
}
/*---------------------------------------------------------------------------------*\
| USB transfer functions |
\*---------------------------------------------------------------------------------*/
int RazerHanboController::UsbReceive(razer_hanbo_report* report)
{
return hid_read_timeout(dev, (unsigned char*)report, sizeof(*report),2);
}
int RazerHanboController::UsbSend(razer_hanbo_report* report)
{
return hid_write(dev, (unsigned char*)report, sizeof(*report));
}
@@ -0,0 +1,103 @@
/*---------------------------------------------------------*\
| RazerHanboController.h |
| |
| Driver for Razer Hanbo devices |
| |
| Joseph East (dripsnek) 12 Apr 2025 |
| |
| This file is part of the OpenRGB project |
| SPDX-License-Identifier: GPL-2.0-or-later |
\*---------------------------------------------------------*/
#pragma once
#include <string>
#include <hidapi.h>
#include "RGBController.h"
/*---------------------------------------------------------*\
| Struct packing macro for GCC and MSVC |
\*---------------------------------------------------------*/
#ifdef __GNUC__
#define PACK( __Declaration__ ) __Declaration__ __attribute__((__packed__))
#endif
#ifdef _MSC_VER
#define PACK( __Declaration__ ) __pragma( pack(push, 1) ) __Declaration__ __pragma( pack(pop))
#endif
/*---------------------------------------------------------*\
| The Hanbo does not advertise HID report IDs. |
| In this case under Windows, payloads sent to hidapi must |
| be prefixed with a byte of value 0 even if this exceeds |
| the device report length. This dummy byte never ends up |
| on the wire. Hidapi via libusb under Linux is compatible |
| with this behavior. This is generally not compatible with |
| hidraw when using it directly. |
| |
| Request payloads start at header[1] to make this byte. |
| Responses are unaffected and start at header[0]. |
\*---------------------------------------------------------*/
PACK(struct razer_hanbo_report
{
unsigned char header[2];
unsigned char arguments[63];
});
enum
{
MIN_BRIGHTNESS = 0x00,
MAX_BRIGHTNESS = 0x64,
};
enum
{
PUMP,
FAN1,
FAN2,
FAN3
};
class RazerHanboController
{
public:
RazerHanboController(hid_device* dev_handle, const char* path, unsigned short pid, std::string dev_name);
~RazerHanboController();
unsigned int GetDeviceIndex();
device_type GetDeviceType();
std::string GetDeviceLocation();
std::string GetFirmwareString();
std::string GetSerialString();
std::string GetName();
void SetDirectMode();
void SetModeOff();
void SetModeSpectrumCycle();
void SetZoneLeds(int zone_idc, const zone& input_zone);
void SetBrightness(int zone, unsigned int brightness);
private:
hid_device* dev;
unsigned short dev_pid;
/*---------------------------------------------------------*\
| Device information strings |
\*---------------------------------------------------------*/
std::string firmware_version;
std::string serial_string;
std::string location;
std::string name;
/*---------------------------------------------------------*\
| Index of device in Razer device list |
\*---------------------------------------------------------*/
unsigned int device_index;
/*---------------------------------------------------------*\
| Private functions |
\*---------------------------------------------------------*/
razer_hanbo_report razer_hanbo_create_report(unsigned char header);
void GetFirmware();
int UsbReceive(razer_hanbo_report* report);
int UsbSend(razer_hanbo_report* report);
};
@@ -0,0 +1,259 @@
/*---------------------------------------------------------*\
| RGBController_RazerKraken.cpp |
| |
| RGBController for Razer Kraken |
| |
| Adam Honse (CalcProgrammer1) 28 Feb 2021 |
| |
| This file is part of the OpenRGB project |
| SPDX-License-Identifier: GPL-2.0-or-later |
\*---------------------------------------------------------*/
#include "RGBController_RazerKraken.h"
#include "RazerDevices.h"
/**------------------------------------------------------------------*\
@name Razer Kraken
@category Headset
@type USB
@save :robot:
@direct :white_check_mark:
@effects :white_check_mark:
@detectors DetectRazerKrakenControllers
@comment
\*-------------------------------------------------------------------*/
RGBController_RazerKraken::RGBController_RazerKraken(RazerKrakenController* controller_ptr)
{
controller = controller_ptr;
name = controller->GetName();
vendor = "Razer";
type = controller->GetDeviceType();
description = "Razer Kraken Device";
location = controller->GetDeviceLocation();
version = controller->GetFirmwareString();
serial = controller->GetSerialString();
mode Direct;
Direct.name = "Direct";
Direct.value = RAZER_KRAKEN_MODE_DIRECT;
Direct.flags = MODE_FLAG_HAS_PER_LED_COLOR;
Direct.color_mode = MODE_COLORS_PER_LED;
modes.push_back(Direct);
mode Off;
Off.name = "Off";
Off.value = RAZER_KRAKEN_MODE_OFF;
Off.flags = 0;
Off.color_mode = MODE_COLORS_NONE;
modes.push_back(Off);
mode Static;
Static.name = "Static";
Static.value = RAZER_KRAKEN_MODE_STATIC;
Static.flags = MODE_FLAG_HAS_MODE_SPECIFIC_COLOR;
Static.color_mode = MODE_COLORS_MODE_SPECIFIC;
Static.colors_min = 1;
Static.colors_max = 1;
Static.colors.resize(1);
modes.push_back(Static);
mode Breathing;
Breathing.name = "Breathing";
Breathing.value = RAZER_KRAKEN_MODE_BREATHING;
Breathing.flags = MODE_FLAG_HAS_MODE_SPECIFIC_COLOR;
Breathing.color_mode = MODE_COLORS_MODE_SPECIFIC;
Breathing.colors_min = 1;
/*---------------------------------------------------------*\
| Razer Kraken 7.1 Chroma only does single color breathing |
\*---------------------------------------------------------*/
if(device_list[controller->GetDeviceIndex()]->pid == RAZER_KRAKEN_PID)
{
Breathing.colors_max = 1;
}
else
{
Breathing.colors_max = 3;
}
Breathing.colors.resize(1);
modes.push_back(Breathing);
mode SpectrumCycle;
SpectrumCycle.name = "Spectrum Cycle";
SpectrumCycle.value = RAZER_KRAKEN_MODE_SPECTRUM_CYCLE;
SpectrumCycle.flags = 0;
SpectrumCycle.color_mode = MODE_COLORS_NONE;
modes.push_back(SpectrumCycle);
SetupZones();
}
RGBController_RazerKraken::~RGBController_RazerKraken()
{
delete controller;
}
void RGBController_RazerKraken::SetupZones()
{
unsigned int device_index = controller->GetDeviceIndex();
/*---------------------------------------------------------*\
| Fill in zone information based on device table |
\*---------------------------------------------------------*/
for(unsigned int zone_id = 0; zone_id < RAZER_MAX_ZONES; zone_id++)
{
if(device_list[device_index]->zones[zone_id] != NULL)
{
zone new_zone;
new_zone.name = device_list[device_index]->zones[zone_id]->name;
new_zone.type = device_list[device_index]->zones[zone_id]->type;
new_zone.leds_count = device_list[device_index]->zones[zone_id]->rows * device_list[device_index]->zones[zone_id]->cols;
new_zone.leds_min = new_zone.leds_count;
new_zone.leds_max = new_zone.leds_count;
if(new_zone.type == ZONE_TYPE_MATRIX)
{
matrix_map_type * new_map = new matrix_map_type;
new_zone.matrix_map = new_map;
new_map->height = device_list[device_index]->zones[zone_id]->rows;
new_map->width = device_list[device_index]->zones[zone_id]->cols;
new_map->map = new unsigned int[new_map->height * new_map->width];
for(unsigned int y = 0; y < new_map->height; y++)
{
for(unsigned int x = 0; x < new_map->width; x++)
{
new_map->map[(y * new_map->width) + x] = (y * new_map->width) + x;
}
}
}
else
{
new_zone.matrix_map = NULL;
}
zones.push_back(new_zone);
}
}
for(unsigned int zone_id = 0; zone_id < zones.size(); zone_id++)
{
for (unsigned int row_id = 0; row_id < device_list[device_index]->zones[zone_id]->rows; row_id++)
{
for (unsigned int col_id = 0; col_id < device_list[device_index]->zones[zone_id]->cols; col_id++)
{
led* new_led = new led();
new_led->name = device_list[device_index]->zones[zone_id]->name;
if(zones[zone_id].leds_count > 1)
{
new_led->name.append(" LED ");
new_led->name.append(std::to_string(col_id + 1));
}
leds.push_back(*new_led);
}
}
}
SetupColors();
}
void RGBController_RazerKraken::ResizeZone(int /*zone*/, int /*new_size*/)
{
/*---------------------------------------------------------*\
| This device does not support resizing zones |
\*---------------------------------------------------------*/
}
void RGBController_RazerKraken::DeviceUpdateLEDs()
{
unsigned char red = RGBGetRValue(colors[0]);
unsigned char grn = RGBGetGValue(colors[0]);
unsigned char blu = RGBGetBValue(colors[0]);
controller->SetModeCustom(red, grn, blu);
}
void RGBController_RazerKraken::UpdateZoneLEDs(int /*zone*/)
{
DeviceUpdateLEDs();
}
void RGBController_RazerKraken::UpdateSingleLED(int /*led*/)
{
DeviceUpdateLEDs();
}
void RGBController_RazerKraken::DeviceUpdateMode()
{
switch(modes[active_mode].value)
{
case RAZER_KRAKEN_MODE_OFF:
controller->SetModeOff();
break;
case RAZER_KRAKEN_MODE_STATIC:
if(modes[active_mode].color_mode == MODE_COLORS_MODE_SPECIFIC)
{
if(modes[active_mode].colors.size() == 1)
{
unsigned char red = RGBGetRValue(modes[active_mode].colors[0]);
unsigned char grn = RGBGetGValue(modes[active_mode].colors[0]);
unsigned char blu = RGBGetBValue(modes[active_mode].colors[0]);
controller->SetModeStatic(red, grn, blu);
}
}
break;
case RAZER_KRAKEN_MODE_BREATHING:
if(modes[active_mode].color_mode == MODE_COLORS_MODE_SPECIFIC)
{
if(modes[active_mode].colors.size() == 1)
{
unsigned char red = RGBGetRValue(modes[active_mode].colors[0]);
unsigned char grn = RGBGetGValue(modes[active_mode].colors[0]);
unsigned char blu = RGBGetBValue(modes[active_mode].colors[0]);
controller->SetModeBreathingOneColor(red, grn, blu);
}
else if(modes[active_mode].colors.size() == 2)
{
unsigned char red1 = RGBGetRValue(modes[active_mode].colors[0]);
unsigned char grn1 = RGBGetGValue(modes[active_mode].colors[0]);
unsigned char blu1 = RGBGetBValue(modes[active_mode].colors[0]);
unsigned char red2 = RGBGetRValue(modes[active_mode].colors[1]);
unsigned char grn2 = RGBGetGValue(modes[active_mode].colors[1]);
unsigned char blu2 = RGBGetBValue(modes[active_mode].colors[1]);
controller->SetModeBreathingTwoColors(red1, grn1, blu1, red2, grn2, blu2);
}
else if(modes[active_mode].colors.size() == 3)
{
unsigned char red1 = RGBGetRValue(modes[active_mode].colors[0]);
unsigned char grn1 = RGBGetGValue(modes[active_mode].colors[0]);
unsigned char blu1 = RGBGetBValue(modes[active_mode].colors[0]);
unsigned char red2 = RGBGetRValue(modes[active_mode].colors[1]);
unsigned char grn2 = RGBGetGValue(modes[active_mode].colors[1]);
unsigned char blu2 = RGBGetBValue(modes[active_mode].colors[1]);
unsigned char red3 = RGBGetRValue(modes[active_mode].colors[2]);
unsigned char grn3 = RGBGetGValue(modes[active_mode].colors[2]);
unsigned char blu3 = RGBGetBValue(modes[active_mode].colors[2]);
controller->SetModeBreathingThreeColors(red1, grn1, blu1, red2, grn2, blu2, red3, grn3, blu3);
}
}
break;
case RAZER_KRAKEN_MODE_SPECTRUM_CYCLE:
controller->SetModeSpectrumCycle();
break;
}
}
@@ -0,0 +1,44 @@
/*---------------------------------------------------------*\
| RGBController_RazerKraken.h |
| |
| RGBController for Razer Kraken |
| |
| Adam Honse (CalcProgrammer1) 28 Feb 2021 |
| |
| This file is part of the OpenRGB project |
| SPDX-License-Identifier: GPL-2.0-or-later |
\*---------------------------------------------------------*/
#pragma once
#include "RGBController.h"
#include "RazerKrakenController.h"
enum
{
RAZER_KRAKEN_MODE_DIRECT,
RAZER_KRAKEN_MODE_OFF,
RAZER_KRAKEN_MODE_STATIC,
RAZER_KRAKEN_MODE_BREATHING,
RAZER_KRAKEN_MODE_SPECTRUM_CYCLE,
};
class RGBController_RazerKraken : public RGBController
{
public:
RGBController_RazerKraken(RazerKrakenController* controller_ptr);
~RGBController_RazerKraken();
void SetupZones();
void ResizeZone(int zone, int new_size);
void DeviceUpdateLEDs();
void UpdateZoneLEDs(int zone);
void UpdateSingleLED(int led);
void DeviceUpdateMode();
private:
RazerKrakenController* controller;
};
@@ -0,0 +1,401 @@
/*---------------------------------------------------------*\
| RazerKrakenController.cpp |
| |
| Driver for Razer Kraken |
| |
| Adam Honse (CalcProgrammer1) 28 Feb 2021 |
| |
| This file is part of the OpenRGB project |
| SPDX-License-Identifier: GPL-2.0-or-later |
\*---------------------------------------------------------*/
#include <string.h>
#include "RazerKrakenController.h"
#include "RazerDevices.h"
using namespace std::chrono_literals;
RazerKrakenController::RazerKrakenController(hid_device* dev_handle, const char* path, unsigned short pid, std::string dev_name)
{
dev = dev_handle;
dev_pid = pid;
location = path;
name = dev_name;
device_index = 0;
/*-----------------------------------------------------------------*\
| Loop through all known devices to look for a name match |
\*-----------------------------------------------------------------*/
for (unsigned int i = 0; i < RAZER_NUM_DEVICES; i++)
{
if (device_list[i]->pid == dev_pid)
{
/*---------------------------------------------------------*\
| Set device ID |
\*---------------------------------------------------------*/
device_index = i;
}
}
/*-----------------------------------------------------------------*\
| Determine addresses for device |
\*-----------------------------------------------------------------*/
switch(dev_pid)
{
case RAZER_KRAKEN_V2_PID:
case RAZER_KRAKEN_KITTY_BLACK_EDITION_V2_PID:
case RAZER_KRAKEN_ULTIMATE_PID:
led_mode_address = 0x172D;
custom_address = 0x1189;
breathing_address[0] = 0x1741;
breathing_address[1] = 0x1745;
breathing_address[2] = 0x174D;
break;
case RAZER_KRAKEN_CLASSIC_PID:
case RAZER_KRAKEN_CLASSIC_ALT_PID:
case RAZER_KRAKEN_PID:
led_mode_address = 0x1008;
custom_address = 0x1189;
breathing_address[0] = 0x15DE;
breathing_address[1] = 0x15DE;
breathing_address[2] = 0x15DE;
break;
}
}
RazerKrakenController::~RazerKrakenController()
{
hid_close(dev);
}
std::string RazerKrakenController::GetName()
{
return(name);
}
unsigned int RazerKrakenController::GetDeviceIndex()
{
return(device_index);
}
device_type RazerKrakenController::GetDeviceType()
{
return(device_list[device_index]->type);
}
std::string RazerKrakenController::GetDeviceLocation()
{
return("HID: " + location);
}
std::string RazerKrakenController::GetFirmwareString()
{
return(razer_get_firmware());
}
std::string RazerKrakenController::GetSerialString()
{
return(razer_get_serial());
}
void RazerKrakenController::SetModeBreathingOneColor(unsigned char red, unsigned char grn, unsigned char blu)
{
razer_set_mode_breathing_one_color(red, grn, blu);
}
void RazerKrakenController::SetModeBreathingTwoColors(unsigned char r1, unsigned char g1, unsigned char b1, unsigned char r2, unsigned char g2, unsigned char b2)
{
razer_set_mode_breathing_two_colors(r1, g1, b1, r2, g2, b2);
}
void RazerKrakenController::SetModeBreathingThreeColors(unsigned char r1, unsigned char g1, unsigned char b1, unsigned char r2, unsigned char g2, unsigned char b2, unsigned char r3, unsigned char g3, unsigned char b3)
{
razer_set_mode_breathing_three_colors(r1, g1, b1, r2, g2, b2, r3, g3, b3);
}
void RazerKrakenController::SetModeCustom(unsigned char red, unsigned char grn, unsigned char blu)
{
razer_set_mode_custom(red, grn, blu);
}
void RazerKrakenController::SetModeOff()
{
razer_set_mode_none();
}
void RazerKrakenController::SetModeSpectrumCycle()
{
razer_set_mode_spectrum_cycle();
}
void RazerKrakenController::SetModeStatic(unsigned char red, unsigned char grn, unsigned char blu)
{
razer_set_mode_static(red, grn, blu);
}
/*---------------------------------------------------------------------------------*\
| Basic report and response creation functions |
\*---------------------------------------------------------------------------------*/
razer_kraken_request_report RazerKrakenController::razer_kraken_create_report(unsigned char report_id, unsigned char destination, unsigned char length, unsigned short address)
{
razer_kraken_request_report new_report;
/*---------------------------------------------------------*\
| Zero out the new report |
\*---------------------------------------------------------*/
memset(&new_report, 0, sizeof(razer_kraken_request_report));
/*---------------------------------------------------------*\
| Fill in the new report with the given parameters |
\*---------------------------------------------------------*/
new_report.report_id = report_id;
new_report.destination = destination;
new_report.length = length;
new_report.addr_h = (address >> 8);
new_report.addr_l = (address & 0xFF);
return new_report;
}
razer_kraken_effect_byte RazerKrakenController::razer_kraken_create_effect_byte()
{
razer_kraken_effect_byte effect_byte;
memset(&effect_byte, 0, sizeof(razer_kraken_effect_byte));
return effect_byte;
}
/*---------------------------------------------------------------------------------*\
| Get functions (request information from device) |
\*---------------------------------------------------------------------------------*/
std::string RazerKrakenController::razer_get_firmware()
{
std::string firmware_string = "";
struct razer_kraken_request_report report = razer_kraken_create_report(0x04, 0x20, 0x02, 0x0030);
struct razer_kraken_response_report response_report;
std::this_thread::sleep_for(1ms);
razer_usb_send(&report);
std::this_thread::sleep_for(1ms);
razer_usb_receive(&response_report);
if(response_report.report_id == 0x05)
{
firmware_string = "v" + std::to_string(response_report.arguments[1]) + "." + std::to_string(response_report.arguments[2]);
}
return firmware_string;
}
std::string RazerKrakenController::razer_get_serial()
{
char serial_string[64] = "";
struct razer_kraken_request_report report = razer_kraken_create_report(0x04, 0x20, 0x16, 0x7f00);
struct razer_kraken_response_report response_report;
std::this_thread::sleep_for(1ms);
razer_usb_send(&report);
std::this_thread::sleep_for(1ms);
razer_usb_receive(&response_report);
if(response_report.report_id == 0x05)
{
strncpy(&serial_string[0], (const char*)&response_report.arguments[0], 22);
serial_string[22] = '\0';
}
for(size_t i = 0; i < 22; i++)
{
if(serial_string[i] < 30 || serial_string[i] > 126)
{
serial_string[i] = ' ';
}
}
std::string ret_string = serial_string;
return ret_string;
}
/*---------------------------------------------------------------------------------*\
| Set functions (send information to device) |
\*---------------------------------------------------------------------------------*/
void RazerKrakenController::razer_set_mode_breathing_one_color(unsigned char red, unsigned char grn, unsigned char blu)
{
razer_kraken_request_report rgb_report = razer_kraken_create_report(0x04, 0x40, 0x03, breathing_address[0]);
razer_kraken_request_report effect_report = razer_kraken_create_report(0x04, 0x40, 0x01, led_mode_address);
razer_kraken_effect_byte effect_byte = razer_kraken_create_effect_byte();
rgb_report.arguments[0] = red;
rgb_report.arguments[1] = grn;
rgb_report.arguments[2] = blu;
effect_byte.bits.on_off_static = 1;
effect_byte.bits.single_colour_breathing = 1;
effect_byte.bits.sync = 1;
effect_report.arguments[0] = effect_byte.value;
razer_usb_send(&rgb_report);
razer_usb_send(&effect_report);
}
void RazerKrakenController::razer_set_mode_breathing_two_colors(unsigned char r1, unsigned char g1, unsigned char b1, unsigned char r2, unsigned char g2, unsigned char b2)
{
razer_kraken_request_report rgb_report_1 = razer_kraken_create_report(0x04, 0x40, 0x03, breathing_address[1]);
razer_kraken_request_report rgb_report_2 = razer_kraken_create_report(0x04, 0x40, 0x03, breathing_address[1] + 4);
razer_kraken_request_report effect_report = razer_kraken_create_report(0x04, 0x40, 0x01, led_mode_address);
razer_kraken_effect_byte effect_byte = razer_kraken_create_effect_byte();
rgb_report_1.arguments[0] = r1;
rgb_report_1.arguments[1] = g1;
rgb_report_1.arguments[2] = b1;
rgb_report_2.arguments[0] = r2;
rgb_report_2.arguments[1] = g2;
rgb_report_2.arguments[2] = b2;
effect_byte.bits.on_off_static = 1;
effect_byte.bits.two_colour_breathing = 1;
effect_byte.bits.sync = 1;
effect_report.arguments[0] = effect_byte.value;
razer_usb_send(&rgb_report_1);
razer_usb_send(&rgb_report_2);
razer_usb_send(&effect_report);
}
void RazerKrakenController::razer_set_mode_breathing_three_colors(unsigned char r1, unsigned char g1, unsigned char b1, unsigned char r2, unsigned char g2, unsigned char b2, unsigned char r3, unsigned char g3, unsigned char b3)
{
razer_kraken_request_report rgb_report_1 = razer_kraken_create_report(0x04, 0x40, 0x03, breathing_address[1]);
razer_kraken_request_report rgb_report_2 = razer_kraken_create_report(0x04, 0x40, 0x03, breathing_address[1] + 4);
razer_kraken_request_report rgb_report_3 = razer_kraken_create_report(0x04, 0x40, 0x03, breathing_address[1] + 8);
razer_kraken_request_report effect_report = razer_kraken_create_report(0x04, 0x40, 0x01, led_mode_address);
razer_kraken_effect_byte effect_byte = razer_kraken_create_effect_byte();
rgb_report_1.arguments[0] = r1;
rgb_report_1.arguments[1] = g1;
rgb_report_1.arguments[2] = b1;
rgb_report_2.arguments[0] = r2;
rgb_report_2.arguments[1] = g2;
rgb_report_2.arguments[2] = b2;
rgb_report_3.arguments[0] = r3;
rgb_report_3.arguments[1] = g3;
rgb_report_3.arguments[2] = b3;
effect_byte.bits.on_off_static = 1;
effect_byte.bits.three_colour_breathing = 1;
effect_byte.bits.sync = 1;
effect_report.arguments[0] = effect_byte.value;
razer_usb_send(&rgb_report_1);
razer_usb_send(&rgb_report_2);
razer_usb_send(&rgb_report_3);
razer_usb_send(&effect_report);
}
void RazerKrakenController::razer_set_mode_custom(unsigned char red, unsigned char grn, unsigned char blu)
{
razer_kraken_request_report rgb_report = razer_kraken_create_report(0x04, 0x40, 3, custom_address);
razer_kraken_request_report effect_report = razer_kraken_create_report(0x04, 0x40, 0x01, led_mode_address);
razer_kraken_effect_byte effect_byte = razer_kraken_create_effect_byte();
effect_byte.value = 0;
effect_byte.bits.on_off_static = 1;
effect_byte.bits.spectrum_cycling = 0;
rgb_report.arguments[0] = red;
rgb_report.arguments[1] = grn;
rgb_report.arguments[2] = blu;
effect_report.arguments[0] = effect_byte.value;
switch(dev_pid)
{
case RAZER_KRAKEN_PID:
case RAZER_KRAKEN_V2_PID:
case RAZER_KRAKEN_KITTY_BLACK_EDITION_V2_PID:
case RAZER_KRAKEN_ULTIMATE_PID:
razer_usb_send(&rgb_report);
break;
}
razer_usb_send(&effect_report);
}
void RazerKrakenController::razer_set_mode_none()
{
razer_kraken_request_report report = razer_kraken_create_report(0x04, 0x40, 0x01, led_mode_address);
razer_kraken_effect_byte effect_byte = razer_kraken_create_effect_byte();
effect_byte.value = 0;
effect_byte.bits.on_off_static = 0;
effect_byte.bits.spectrum_cycling = 0;
report.arguments[0] = effect_byte.value;
razer_usb_send(&report);
}
void RazerKrakenController::razer_set_mode_spectrum_cycle()
{
razer_kraken_request_report report = razer_kraken_create_report(0x04, 0x40, 0x01, led_mode_address);
razer_kraken_effect_byte effect_byte = razer_kraken_create_effect_byte();
effect_byte.value = 0;
effect_byte.bits.on_off_static = 1;
effect_byte.bits.spectrum_cycling = 1;
report.arguments[0] = effect_byte.value;
razer_usb_send(&report);
}
void RazerKrakenController::razer_set_mode_static(unsigned char red, unsigned char grn, unsigned char blu)
{
razer_kraken_request_report rgb_report = razer_kraken_create_report(0x04, 0x40, 3, breathing_address[0]);
razer_kraken_request_report effect_report = razer_kraken_create_report(0x04, 0x40, 0x01, led_mode_address);
razer_kraken_effect_byte effect_byte = razer_kraken_create_effect_byte();
effect_byte.value = 0;
effect_byte.bits.on_off_static = 1;
effect_byte.bits.spectrum_cycling = 0;
rgb_report.arguments[0] = red;
rgb_report.arguments[1] = grn;
rgb_report.arguments[2] = blu;
effect_report.arguments[0] = effect_byte.value;
switch(dev_pid)
{
case RAZER_KRAKEN_PID:
case RAZER_KRAKEN_V2_PID:
case RAZER_KRAKEN_KITTY_BLACK_EDITION_V2_PID:
case RAZER_KRAKEN_ULTIMATE_PID:
razer_usb_send(&rgb_report);
break;
}
razer_usb_send(&effect_report);
}
/*---------------------------------------------------------------------------------*\
| USB transfer functions |
\*---------------------------------------------------------------------------------*/
int RazerKrakenController::razer_usb_receive(razer_kraken_response_report* report)
{
return hid_read(dev, (unsigned char*)report, sizeof(*report));
}
int RazerKrakenController::razer_usb_send(razer_kraken_request_report* report)
{
return hid_write(dev, (unsigned char*)report, sizeof(*report));
}
@@ -0,0 +1,128 @@
/*---------------------------------------------------------*\
| RazerKrakenController.h |
| |
| Driver for Razer Kraken |
| |
| Adam Honse (CalcProgrammer1) 28 Feb 2021 |
| |
| This file is part of the OpenRGB project |
| SPDX-License-Identifier: GPL-2.0-or-later |
\*---------------------------------------------------------*/
#pragma once
#include <string>
#include <hidapi.h>
#include "RGBController.h"
/*---------------------------------------------------------*\
| Struct packing macro for GCC and MSVC |
\*---------------------------------------------------------*/
#ifdef __GNUC__
#define PACK( __Declaration__ ) __Declaration__ __attribute__((__packed__))
#endif
#ifdef _MSC_VER
#define PACK( __Declaration__ ) __pragma( pack(push, 1) ) __Declaration__ __pragma( pack(pop))
#endif
union razer_kraken_effect_byte
{
unsigned char value;
struct razer_kraken_effect_byte_bits
{
unsigned char on_off_static :1;
unsigned char single_colour_breathing :1;
unsigned char spectrum_cycling :1;
unsigned char sync :1;
unsigned char two_colour_breathing :1;
unsigned char three_colour_breathing :1;
} bits;
};
/*---------------------------------------------------------*\
| Razer Kraken Report Types (taken from OpenRazer) |
\*---------------------------------------------------------*/
PACK(struct razer_kraken_request_report
{
unsigned char report_id;
unsigned char destination;
unsigned char length;
unsigned char addr_h;
unsigned char addr_l;
unsigned char arguments[32];
});
PACK(struct razer_kraken_response_report
{
unsigned char report_id;
unsigned char arguments[36];
});
class RazerKrakenController
{
public:
RazerKrakenController(hid_device* dev_handle, const char* path, unsigned short pid, std::string dev_name);
~RazerKrakenController();
unsigned int GetDeviceIndex();
device_type GetDeviceType();
std::string GetDeviceLocation();
std::string GetFirmwareString();
std::string GetName();
std::string GetSerialString();
void SetModeBreathingOneColor(unsigned char red, unsigned char grn, unsigned char blu);
void SetModeBreathingTwoColors(unsigned char r1, unsigned char g1, unsigned char b1, unsigned char r2, unsigned char g2, unsigned char b2);
void SetModeBreathingThreeColors(unsigned char r1, unsigned char g1, unsigned char b1, unsigned char r2, unsigned char g2, unsigned char b2, unsigned char r3, unsigned char g3, unsigned char b3);
void SetModeCustom(unsigned char red, unsigned char grn, unsigned char blu);
void SetModeOff();
void SetModeSpectrumCycle();
void SetModeStatic(unsigned char red, unsigned char grn, unsigned char blu);
private:
hid_device* dev;
unsigned short dev_pid;
/*---------------------------------------------------------*\
| Device information strings |
\*---------------------------------------------------------*/
std::string firmware_version;
std::string location;
std::string name;
/*---------------------------------------------------------*\
| Kraken LED/Mode Addresses |
\*---------------------------------------------------------*/
unsigned short breathing_address[3];
unsigned short custom_address;
unsigned short led_mode_address;
/*---------------------------------------------------------*\
| Index of device in Razer device list |
\*---------------------------------------------------------*/
unsigned int device_index;
/*---------------------------------------------------------*\
| Private functions based on OpenRazer |
\*---------------------------------------------------------*/
razer_kraken_request_report razer_kraken_create_report(unsigned char report_id, unsigned char destination, unsigned char length, unsigned short address);
razer_kraken_effect_byte razer_kraken_create_effect_byte();
std::string razer_get_firmware();
std::string razer_get_serial();
void razer_set_mode_breathing_one_color(unsigned char red, unsigned char grn, unsigned char blu);
void razer_set_mode_breathing_two_colors(unsigned char r1, unsigned char g1, unsigned char b1, unsigned char r2, unsigned char g2, unsigned char b2);
void razer_set_mode_breathing_three_colors(unsigned char r1, unsigned char g1, unsigned char b1, unsigned char r2, unsigned char g2, unsigned char b2, unsigned char r3, unsigned char g3, unsigned char b3);
void razer_set_mode_custom(unsigned char red, unsigned char grn, unsigned char blu);
void razer_set_mode_none();
void razer_set_mode_spectrum_cycle();
void razer_set_mode_static(unsigned char red, unsigned char grn, unsigned char blu);
int razer_usb_receive(razer_kraken_response_report* report);
int razer_usb_send(razer_kraken_request_report* report);
};
@@ -0,0 +1,189 @@
/*---------------------------------------------------------*\
| RGBController_RazerKrakenV3.cpp |
| |
| RGBController for Razer devices with 13-byte reports |
| |
| Greg Sandstrom (superstrom) 1 Nov 2025 |
| |
| This file is part of the OpenRGB project |
| SPDX-License-Identifier: GPL-2.0-or-later |
\*---------------------------------------------------------*/
#include <vector>
#include "RazerDevices.h"
#include "RGBController_RazerKrakenV3.h"
RGBController_RazerKrakenV3::RGBController_RazerKrakenV3(RazerKrakenV3Controller* controller_ptr)
{
controller = controller_ptr;
name = controller->GetName();
vendor = "Razer";
type = controller->GetDeviceType();
description = "Razer Device";
location = controller->GetDeviceLocation();
version = controller->GetFirmwareString();
serial = controller->GetSerialString();
uint8_t max_brightness = controller->GetMaxBrightness();
// By default, the device starts as Wave/Spectrum Cycle.
// Set Wave as first mode, so switching to Direct calls DeviceUpdateMode()
mode Wave;
Wave.name = "Wave";
Wave.value = RAZER_KRAKEN_V3_MODE_WAVE;
Wave.flags = MODE_FLAG_HAS_BRIGHTNESS;
Wave.direction = MODE_DIRECTION_RIGHT;
Wave.color_mode = MODE_COLORS_NONE;
Wave.brightness_min = 0;
Wave.brightness_max = max_brightness;
Wave.brightness = max_brightness;
modes.push_back(Wave);
mode Direct;
Direct.name = "Direct";
Direct.value = RAZER_KRAKEN_V3_MODE_DIRECT;
Direct.flags = MODE_FLAG_HAS_PER_LED_COLOR | MODE_FLAG_HAS_BRIGHTNESS;
Direct.color_mode = MODE_COLORS_PER_LED;
Direct.brightness_min = 0;
Direct.brightness_max = max_brightness;
Direct.brightness = max_brightness;
modes.push_back(Direct);
// V3 X does not support this mode.
if(device_list[controller->GetDeviceIndex()]->pid == RAZER_KRAKEN_V3_HYPERSENSE_PID)
{
mode Breathing;
Breathing.name = "Breathing";
Breathing.value = RAZER_KRAKEN_V3_MODE_BREATHING;
Breathing.flags = MODE_FLAG_HAS_MODE_SPECIFIC_COLOR;
Breathing.color_mode = MODE_COLORS_MODE_SPECIFIC;
Breathing.colors_min = 1;
Breathing.colors_max = 2;
Breathing.colors.resize(1);
modes.push_back(Breathing);
}
SetupZones();
}
RGBController_RazerKrakenV3::~RGBController_RazerKrakenV3()
{
delete controller;
}
void RGBController_RazerKrakenV3::SetupZones()
{
unsigned int device_index = controller->GetDeviceIndex();
/*---------------------------------------------------------*\
| Fill in zone information based on device table |
\*---------------------------------------------------------*/
for(unsigned int zone_id = 0; zone_id < RAZER_MAX_ZONES; zone_id++)
{
if(device_list[device_index]->zones[zone_id] != NULL)
{
zone new_zone;
new_zone.name = device_list[device_index]->zones[zone_id]->name;
new_zone.type = device_list[device_index]->zones[zone_id]->type;
new_zone.leds_count = device_list[device_index]->zones[zone_id]->rows * device_list[device_index]->zones[zone_id]->cols;
new_zone.leds_min = new_zone.leds_count;
new_zone.leds_max = new_zone.leds_count;
if(new_zone.type == ZONE_TYPE_MATRIX)
{
matrix_map_type * new_map = new matrix_map_type;
new_zone.matrix_map = new_map;
new_map->height = device_list[device_index]->zones[zone_id]->rows;
new_map->width = device_list[device_index]->zones[zone_id]->cols;
new_map->map = new unsigned int[new_map->height * new_map->width];
for(unsigned int y = 0; y < new_map->height; y++)
{
for(unsigned int x = 0; x < new_map->width; x++)
{
new_map->map[(y * new_map->width) + x] = (y * new_map->width) + x;
}
}
}
else
{
new_zone.matrix_map = NULL;
}
zones.push_back(new_zone);
}
}
for(unsigned int zone_id = 0; zone_id < zones.size(); zone_id++)
{
for (unsigned int row_id = 0; row_id < device_list[device_index]->zones[zone_id]->rows; row_id++)
{
for (unsigned int col_id = 0; col_id < device_list[device_index]->zones[zone_id]->cols; col_id++)
{
led* new_led = new led();
new_led->name = device_list[device_index]->zones[zone_id]->name;
if(zones[zone_id].leds_count > 1)
{
new_led->name.append(" LED ");
new_led->name.append(std::to_string(col_id + 1));
}
leds.push_back(*new_led);
}
}
}
SetupColors();
}
void RGBController_RazerKrakenV3::ResizeZone(int /*zone*/, int /*new_size*/)
{
}
void RGBController_RazerKrakenV3::DeviceUpdateLEDs()
{
if(modes[active_mode].value == RAZER_KRAKEN_V3_MODE_DIRECT)
{
controller->SetDirect(&colors[0]);
}
}
void RGBController_RazerKrakenV3::UpdateZoneLEDs(int /*zone*/)
{
DeviceUpdateLEDs();
}
void RGBController_RazerKrakenV3::UpdateSingleLED(int /*led*/)
{
DeviceUpdateLEDs();
}
void RGBController_RazerKrakenV3::DeviceUpdateMode()
{
switch(modes[active_mode].value)
{
case RAZER_KRAKEN_V3_MODE_DIRECT:
controller->SetModeDirect();
controller->SetBrightness(modes[active_mode].brightness);
break;
case RAZER_KRAKEN_V3_MODE_WAVE:
controller->SetModeWave();
controller->SetBrightness(modes[active_mode].brightness);
break;
case RAZER_KRAKEN_V3_MODE_BREATHING:
controller->SetModeBreathing(modes[active_mode].colors);
controller->SetBrightness(modes[active_mode].brightness);
break;
}
}
@@ -0,0 +1,42 @@
/*---------------------------------------------------------*\
| RGBController_RazerKrakenV3.h |
| |
| RGBController for Razer devices with 13-byte reports |
| |
| Greg Sandstrom (superstrom) 1 Nov 2025 |
| |
| This file is part of the OpenRGB project |
| SPDX-License-Identifier: GPL-2.0-or-later |
\*---------------------------------------------------------*/
#pragma once
#include "RGBController.h"
#include "RazerKrakenV3Controller.h"
enum
{
RAZER_KRAKEN_V3_MODE_DIRECT,
RAZER_KRAKEN_V3_MODE_WAVE,
RAZER_KRAKEN_V3_MODE_BREATHING,
};
class RGBController_RazerKrakenV3 : public RGBController
{
public:
RGBController_RazerKrakenV3(RazerKrakenV3Controller* controller_ptr);
~RGBController_RazerKrakenV3();
void SetupZones();
void ResizeZone(int zone, int new_size);
void DeviceUpdateLEDs();
void UpdateZoneLEDs(int zone);
void UpdateSingleLED(int led);
void DeviceUpdateMode();
private:
RazerKrakenV3Controller* controller;
};
@@ -0,0 +1,280 @@
/*---------------------------------------------------------*\
| RazerKrakenV3Controller.cpp |
| |
| Driver for Razer devices with 13-byte reports |
| |
| Greg Sandstrom (superstrom) 1 Nov 2025 |
| |
| This file is part of the OpenRGB project |
| SPDX-License-Identifier: GPL-2.0-or-later |
\*---------------------------------------------------------*/
#include <cstring>
#include "RazerKrakenController.h"
#include "RazerKrakenV3Controller.h"
#include "RazerDevices.h"
using namespace std::chrono_literals;
RazerKrakenV3Controller::RazerKrakenV3Controller(hid_device* dev_handle, const char* path, unsigned short pid, std::string dev_name)
{
dev = dev_handle;
dev_pid = pid;
location = path;
name = dev_name;
/*-----------------------------------------------------------------*\
| Loop through all known devices to look for a name match |
\*-----------------------------------------------------------------*/
for(unsigned int i = 0; i < RAZER_NUM_DEVICES; i++)
{
if(device_list[i]->pid == dev_pid)
{
/*---------------------------------------------------------*\
| Set device ID |
\*---------------------------------------------------------*/
device_index = i;
}
}
/*-----------------------------------------------------------------*\
| Determine matrix type for device |
\*-----------------------------------------------------------------*/
matrix_type = device_list[device_index]->matrix_type;
}
RazerKrakenV3Controller::~RazerKrakenV3Controller()
{
hid_close(dev);
}
std::string RazerKrakenV3Controller::GetName()
{
return(name);
}
unsigned int RazerKrakenV3Controller::GetDeviceIndex()
{
return(device_index);
}
device_type RazerKrakenV3Controller::GetDeviceType()
{
return(device_list[device_index]->type);
}
std::string RazerKrakenV3Controller::GetDeviceLocation()
{
return("HID: " + location);
}
std::string RazerKrakenV3Controller::GetFirmwareString()
{
return(razer_get_firmware());
}
std::string RazerKrakenV3Controller::GetSerialString()
{
return(razer_get_serial());
}
unsigned char RazerKrakenV3Controller::GetMaxBrightness()
{
/*-----------------------------------------------------*\
| Max brightness for most devices is 0xFF (255) |
| Add PIDs only for devices that use 0x64 (100) |
| or any another arbitrary value |
\*-----------------------------------------------------*/
unsigned char max_brightness = 255;
return(max_brightness);
}
void RazerKrakenV3Controller::SetModeDirect()
{
razer_kraken_v3_request_report report = razer_kraken_create_v3_report();
// 0 1 2 3 4 5 6 7 8
// 4001000f0800000000
// 40010000080000000000000000
report.report_id = RAZER_KRAKEN_V3_REPORT_ID;
report.command_id = RAZER_KRAKEN_V3_CMD_LIGHTING_SET_MODE;
report.arguments[1] = 0x0F;
report.arguments[2] = RAZER_KRAKEN_V3_MODE_ID_DIRECT;
hid_write(dev, (unsigned char*)&report, sizeof(report));
}
void RazerKrakenV3Controller::SetDirect(RGBColor* colors)
{
razer_kraken_v3_request_report report = razer_kraken_create_v3_report();
// how to get the number of leds?
unsigned int led_count = device_list[device_index]->cols;
// 0 1 2 3 4 5 6 7 8
// 400300ffffff000000
// 400300ffffff00000000000000
report.report_id = RAZER_KRAKEN_V3_REPORT_ID;
report.command_id = RAZER_KRAKEN_V3_CMD_LIGHTING_SET_COLOR;
for(unsigned int led_idx = 0; led_idx < led_count; led_idx++)
{
report.arguments[1 + (led_idx * 3)] = RGBGetRValue(colors[led_idx]);
report.arguments[2 + (led_idx * 3)] = RGBGetGValue(colors[led_idx]);
report.arguments[3 + (led_idx * 3)] = RGBGetBValue(colors[led_idx]);
}
hid_write(dev, (unsigned char*)&report, sizeof(report));
}
void RazerKrakenV3Controller::SetBrightness(unsigned char brightness)
{
razer_kraken_v3_request_report report = razer_kraken_create_v3_report();
// 0 1 2 3 4 5 6 7 8
// 40020000ff00000000
report.report_id = RAZER_KRAKEN_V3_REPORT_ID;
report.command_id = RAZER_KRAKEN_V3_CMD_LIGHTING_SET_BRIGHTNESS;
report.arguments[2] = brightness;
hid_write(dev, (unsigned char*)&report, sizeof(report));
}
void RazerKrakenV3Controller::SetModeWave()
{
razer_kraken_v3_request_report report = razer_kraken_create_v3_report();
// 0 1 2 3 4 5 6 7 8
// 4001000f0300000000
// 40010100030000000000000000
report.report_id = RAZER_KRAKEN_V3_REPORT_ID;
report.command_id = RAZER_KRAKEN_V3_CMD_LIGHTING_SET_MODE;
report.arguments[1] = 0x0F;
report.arguments[2] = RAZER_KRAKEN_V3_MODE_ID_WAVE;
hid_write(dev, (unsigned char*)&report, sizeof(report));
}
void RazerKrakenV3Controller::SetModeBreathing(std::vector<RGBColor> colors)
{
razer_kraken_v3_request_report report = razer_kraken_create_v3_report();
unsigned char led_count = (unsigned char)colors.size();
// 0 1 2 3 4 5 6 7 8 9 0 1 2
// 400101000101ff000000000000
// 40010100010100ffff00000000
// 40010100020200ff00ff000000
report.report_id = RAZER_KRAKEN_V3_REPORT_ID;
report.command_id = RAZER_KRAKEN_V3_CMD_LIGHTING_SET_MODE;
report.arguments[0] = 0x01;
report.arguments[2] = led_count; // normally this is where the MODE_ID goes....
report.arguments[3] = led_count;
for(unsigned int led_idx = 0; led_idx < led_count; led_idx++)
{
report.arguments[4 + (led_idx * 3)] = RGBGetRValue(colors[led_idx]);
report.arguments[5 + (led_idx * 3)] = RGBGetGValue(colors[led_idx]);
report.arguments[6 + (led_idx * 3)] = RGBGetBValue(colors[led_idx]);
}
hid_write(dev, (unsigned char*)&report, sizeof(report));
}
razer_kraken_v3_request_report RazerKrakenV3Controller::razer_kraken_create_v3_report()
{
razer_kraken_v3_request_report new_report;
/*---------------------------------------------------------*\
| Zero out the new report |
\*---------------------------------------------------------*/
memset(&new_report, 0, sizeof(razer_kraken_v3_request_report));
new_report.report_id = RAZER_KRAKEN_V3_REPORT_ID;
return new_report;
}
razer_kraken_request_report RazerKrakenV3Controller::razer_kraken_create_report(unsigned char report_id, unsigned char destination, unsigned char length, unsigned short address)
{
razer_kraken_request_report new_report;
/*---------------------------------------------------------*\
| Zero out the new report |
\*---------------------------------------------------------*/
memset(&new_report, 0, sizeof(razer_kraken_request_report));
/*---------------------------------------------------------*\
| Fill in the new report with the given parameters |
\*---------------------------------------------------------*/
new_report.report_id = report_id;
new_report.destination = destination;
new_report.length = length;
new_report.addr_h = (address >> 8);
new_report.addr_l = (address & 0xFF);
return new_report;
}
std::string RazerKrakenV3Controller::razer_get_firmware()
{
std::string firmware_string = "";
struct razer_kraken_request_report report = razer_kraken_create_report(0x04, 0x20, 0x02, 0x0030);
struct razer_kraken_response_report response_report;
std::this_thread::sleep_for(1ms);
razer_usb_send(&report);
std::this_thread::sleep_for(1ms);
razer_usb_receive(&response_report);
if(response_report.report_id == 0x05)
{
firmware_string = "v" + std::to_string(response_report.arguments[1]) + "." + std::to_string(response_report.arguments[2]);
}
return firmware_string;
}
std::string RazerKrakenV3Controller::razer_get_serial()
{
char serial_string[64] = "";
struct razer_kraken_request_report report = razer_kraken_create_report(0x04, 0x20, 0x16, 0x7f00);
struct razer_kraken_response_report response_report;
std::this_thread::sleep_for(1ms);
razer_usb_send(&report);
std::this_thread::sleep_for(1ms);
razer_usb_receive(&response_report);
if(response_report.report_id == 0x05)
{
strncpy(&serial_string[0], (const char*)&response_report.arguments[0], 22);
serial_string[22] = '\0';
}
for(size_t i = 0; i < 22; i++)
{
if(serial_string[i] < 30 || serial_string[i] > 126)
{
serial_string[i] = ' ';
}
}
std::string ret_string = serial_string;
return ret_string;
}
/*---------------------------------------------------------------------------------*\
| USB transfer functions |
\*---------------------------------------------------------------------------------*/
int RazerKrakenV3Controller::razer_usb_receive(razer_kraken_response_report* report)
{
return hid_read(dev, (unsigned char*)report, sizeof(*report));
}
int RazerKrakenV3Controller::razer_usb_send(razer_kraken_request_report* report)
{
return hid_write(dev, (unsigned char*)report, sizeof(*report));
}
@@ -0,0 +1,106 @@
/*---------------------------------------------------------*\
| RazerKrakenV3Controller.h |
| |
| Driver for Razer devices with 13-byte reports |
| |
| Greg Sandstrom (superstrom) 1 Nov 2025 |
| |
| This file is part of the OpenRGB project |
| SPDX-License-Identifier: GPL-2.0-or-later |
\*---------------------------------------------------------*/
#pragma once
#include <hidapi.h>
#include "RGBController.h"
#include "DeviceGuardManager.h"
#include "RazerKrakenController.h"
#define RAZER_KRAKEN_V3_REPORT_ID 0x40
enum
{
RAZER_KRAKEN_V3_CMD_LIGHTING_SET_MODE = 0x01,
RAZER_KRAKEN_V3_CMD_LIGHTING_SET_BRIGHTNESS = 0x02,
RAZER_KRAKEN_V3_CMD_LIGHTING_SET_COLOR = 0x03,
};
enum
{
RAZER_KRAKEN_V3_MODE_ID_DIRECT = 0x08,
RAZER_KRAKEN_V3_MODE_ID_WAVE = 0x03,
};
PACK(struct razer_kraken_v3_request_report
{
unsigned char report_id; // usb_buf[0]
unsigned char command_id; // usb_buf[1]
unsigned char arguments[13]; // usb_buf[2...]
});
class RazerKrakenV3Controller
{
public:
RazerKrakenV3Controller(hid_device* dev_handle, const char* path, unsigned short pid, std::string dev_name);
~RazerKrakenV3Controller();
unsigned int GetDeviceIndex();
device_type GetDeviceType();
std::string GetDeviceLocation();
std::string GetFirmwareString();
std::string GetName();
std::string GetSerialString();
unsigned char GetMaxBrightness();
void SetDirect(RGBColor* colors);
void SetBrightness(unsigned char brightness);
void SetModeDirect();
void SetModeWave();
void SetModeBreathing(std::vector<RGBColor> colors);
private:
hid_device* dev;
unsigned short dev_pid;
/*---------------------------------------------------------*\
| Device-specific protocol settings |
\*---------------------------------------------------------*/
unsigned char dev_transaction_id;
unsigned char dev_led_id;
/*---------------------------------------------------------*\
| Device information strings |
\*---------------------------------------------------------*/
std::string firmware_version;
std::string location;
std::string name;
/*---------------------------------------------------------*\
| Index of device in Razer device list |
\*---------------------------------------------------------*/
unsigned int device_index;
/*---------------------------------------------------------*\
| HID report index for request and response |
\*---------------------------------------------------------*/
unsigned char report_index;
unsigned char response_index;
/*---------------------------------------------------------*\
| Matrix type |
\*---------------------------------------------------------*/
unsigned char matrix_type;
/*---------------------------------------------------------*\
| Private functions based on OpenRazer |
\*---------------------------------------------------------*/
std::string razer_get_firmware();
std::string razer_get_serial();
razer_kraken_v3_request_report razer_kraken_create_v3_report();
razer_kraken_request_report razer_kraken_create_report(unsigned char report_id, unsigned char destination, unsigned char length, unsigned short address);
int razer_usb_receive(razer_kraken_response_report* report);
int razer_usb_send(razer_kraken_request_report* report);
};
@@ -0,0 +1,130 @@
/*---------------------------------------------------------*\
| RGBController_RazerKrakenV4.cpp |
| |
| RGBController for Razer 64-byte devices |
| |
| Adam Honse (CalcProgrammer1) 21 Oct 2025 |
| |
| This file is part of the OpenRGB project |
| SPDX-License-Identifier: GPL-2.0-or-later |
\*---------------------------------------------------------*/
#include "RGBController_RazerKrakenV4.h"
#include "RazerDevices.h"
RGBController_RazerKrakenV4::RGBController_RazerKrakenV4(RazerKrakenV4Controller* controller_ptr)
{
controller = controller_ptr;
name = controller->GetName();
vendor = "Razer";
type = controller->GetDeviceType();
description = "Razer Device";
location = controller->GetDeviceLocation();
version = controller->GetFirmwareString();
serial = controller->GetSerialString();
uint8_t max_brightness = controller->GetMaxBrightness();
mode Direct;
Direct.name = "Direct";
Direct.value = RAZER_KRAKEN_V4_MODE_DIRECT;
Direct.flags = MODE_FLAG_HAS_PER_LED_COLOR;
Direct.color_mode = MODE_COLORS_PER_LED;
modes.push_back(Direct);
mode Wave;
Wave.name = "Wave";
Wave.value = RAZER_KRAKEN_V4_MODE_WAVE;
Wave.flags = MODE_FLAG_HAS_BRIGHTNESS;
Wave.direction = MODE_DIRECTION_RIGHT;
Wave.color_mode = MODE_COLORS_NONE;
Wave.brightness_min = 0;
Wave.brightness_max = max_brightness;
Wave.brightness = max_brightness;
modes.push_back(Wave);
SetupZones();
}
RGBController_RazerKrakenV4::~RGBController_RazerKrakenV4()
{
delete controller;
}
void RGBController_RazerKrakenV4::SetupZones()
{
unsigned int device_index = controller->GetDeviceIndex();
/*-----------------------------------------------------*\
| Fill in zone information based on device table |
| Kraken V4 devices are assumed to only have one row |
\*-----------------------------------------------------*/
for(unsigned int zone_id = 0; zone_id < RAZER_MAX_ZONES; zone_id++)
{
if(device_list[device_index]->zones[zone_id] != NULL)
{
zone new_zone;
new_zone.name = device_list[device_index]->zones[zone_id]->name;
new_zone.type = device_list[device_index]->zones[zone_id]->type;
new_zone.leds_count = device_list[device_index]->zones[zone_id]->cols;
new_zone.leds_min = new_zone.leds_count;
new_zone.leds_max = new_zone.leds_count;
new_zone.matrix_map = NULL;
zones.push_back(new_zone);
for(unsigned int col_id = 0; col_id < device_list[device_index]->zones[zone_id]->cols; col_id++)
{
led* new_led = new led();
new_led->name = device_list[device_index]->zones[zone_id]->name;
if(zones[zone_id].leds_count > 1)
{
new_led->name.append(" LED ");
new_led->name.append(std::to_string(col_id + 1));
}
leds.push_back(*new_led);
}
}
}
SetupColors();
}
void RGBController_RazerKrakenV4::ResizeZone(int /*zone*/, int /*new_size*/)
{
}
void RGBController_RazerKrakenV4::DeviceUpdateLEDs()
{
if(modes[active_mode].value == RAZER_KRAKEN_V4_MODE_DIRECT)
{
controller->SetDirect(&colors[0]);
}
}
void RGBController_RazerKrakenV4::UpdateZoneLEDs(int /*zone*/)
{
DeviceUpdateLEDs();
}
void RGBController_RazerKrakenV4::UpdateSingleLED(int /*led*/)
{
DeviceUpdateLEDs();
}
void RGBController_RazerKrakenV4::DeviceUpdateMode()
{
switch(modes[active_mode].value)
{
case RAZER_KRAKEN_V4_MODE_WAVE:
controller->SetModeWave();
controller->SetBrightness(modes[active_mode].brightness);
break;
}
}
@@ -0,0 +1,41 @@
/*---------------------------------------------------------*\
| RGBController_RazerKrakenV4.h |
| |
| RGBController for Razer 64-byte devices |
| |
| Adam Honse (CalcProgrammer1) 21 Oct 2025 |
| |
| This file is part of the OpenRGB project |
| SPDX-License-Identifier: GPL-2.0-or-later |
\*---------------------------------------------------------*/
#pragma once
#include "RGBController.h"
#include "RazerKrakenV4Controller.h"
enum
{
RAZER_KRAKEN_V4_MODE_DIRECT,
RAZER_KRAKEN_V4_MODE_WAVE,
};
class RGBController_RazerKrakenV4 : public RGBController
{
public:
RGBController_RazerKrakenV4(RazerKrakenV4Controller* controller_ptr);
~RGBController_RazerKrakenV4();
void SetupZones();
void ResizeZone(int zone, int new_size);
void DeviceUpdateLEDs();
void UpdateZoneLEDs(int zone);
void UpdateSingleLED(int led);
void DeviceUpdateMode();
private:
RazerKrakenV4Controller* controller;
};
@@ -0,0 +1,284 @@
/*---------------------------------------------------------*\
| RazerKrakenV4Controller.cpp |
| |
| Driver for Razer devices with 64-byte report |
| |
| Adam Honse (CalcProgrammer1) 21 Oct 2025 |
| |
| This file is part of the OpenRGB project |
| SPDX-License-Identifier: GPL-2.0-or-later |
\*---------------------------------------------------------*/
#include <cstring>
#include "RazerKrakenV4Controller.h"
#include "RazerDevices.h"
using namespace std::chrono_literals;
RazerKrakenV4Controller::RazerKrakenV4Controller(hid_device* dev_handle, const char* path, unsigned short pid, std::string dev_name)
{
dev = dev_handle;
dev_pid = pid;
location = path;
name = dev_name;
/*-----------------------------------------------------*\
| Loop through all known devices to look for a name |
| match |
\*-----------------------------------------------------*/
for(unsigned int i = 0; i < RAZER_NUM_DEVICES; i++)
{
if(device_list[i]->pid == dev_pid)
{
/*---------------------------------------------*\
| Set device ID |
\*---------------------------------------------*/
device_index = i;
}
}
/*-----------------------------------------------------*\
| Determine matrix type for device |
\*-----------------------------------------------------*/
matrix_type = device_list[device_index]->matrix_type;
/*-----------------------------------------------------*\
| All Kraken V4 devices use 0x02 for report and |
| response index |
\*-----------------------------------------------------*/
report_index = 0x02;
response_index = 0x02;
/*-----------------------------------------------------*\
| Determine transaction ID for device |
\*-----------------------------------------------------*/
dev_transaction_id = device_list[device_index]->transaction_id;
/*-----------------------------------------------------*\
| Determine wireless flag for device |
\*-----------------------------------------------------*/
switch(dev_pid)
{
case RAZER_KRAKEN_V4_WIRELESS_PID:
case RAZER_KRAKEN_KITTY_V3_PRO_WIRELESS_PID:
dev_wireless_flag = 0x80;
break;
default:
dev_wireless_flag = 0x00;
break;
}
}
RazerKrakenV4Controller::~RazerKrakenV4Controller()
{
hid_close(dev);
}
std::string RazerKrakenV4Controller::GetName()
{
return(name);
}
unsigned int RazerKrakenV4Controller::GetDeviceIndex()
{
return(device_index);
}
device_type RazerKrakenV4Controller::GetDeviceType()
{
return(device_list[device_index]->type);
}
std::string RazerKrakenV4Controller::GetDeviceLocation()
{
return("HID: " + location);
}
std::string RazerKrakenV4Controller::GetFirmwareString()
{
return(razer_get_firmware());
}
std::string RazerKrakenV4Controller::GetSerialString()
{
return(razer_get_serial());
}
unsigned char RazerKrakenV4Controller::GetMaxBrightness()
{
/*-----------------------------------------------------*\
| Max brightness for most devices is 0xFF (255) |
| Add PIDs only for devices that use 0x64 (100) |
| or any another arbitrary value |
\*-----------------------------------------------------*/
unsigned char max_brightness = 255;
return(max_brightness);
}
void RazerKrakenV4Controller::SetDirect(RGBColor* colors)
{
struct razer_kraken_v4_report report = razer_kraken_v4_create_report(0x0F, 0x03, (5 + (3 * device_list[device_index]->cols)));
report.arguments[2] = 0;
report.arguments[3] = 0;
report.arguments[4] = device_list[device_index]->cols - 1;
for(unsigned int led_idx = 0; led_idx < device_list[device_index]->cols; led_idx++)
{
report.arguments[5 + (led_idx * 3)] = RGBGetRValue(colors[led_idx]);
report.arguments[6 + (led_idx * 3)] = RGBGetGValue(colors[led_idx]);
report.arguments[7 + (led_idx * 3)] = RGBGetBValue(colors[led_idx]);
}
razer_usb_send(&report);
}
void RazerKrakenV4Controller::SetBrightness(unsigned char brightness)
{
struct razer_kraken_v4_report report = razer_kraken_v4_create_report(0x00, 0x00, 0x05);
report.arguments[0] = RAZER_KRAKEN_V4_CMD_LIGHTING_SET_BRIGHTNESS;
report.arguments[2] = 0x01;
report.arguments[3] = brightness;
razer_usb_send(&report);
}
void RazerKrakenV4Controller::SetModeWave()
{
struct razer_kraken_v4_report report = razer_kraken_v4_create_report(0x00, 0x00, 0x05);
report.arguments[0] = RAZER_KRAKEN_V4_CMD_LIGHTING_SET_MODE;
report.arguments[2] = 0x01;
report.arguments[3] = 0x04;
razer_usb_send(&report);
}
unsigned char RazerKrakenV4Controller::razer_kraken_v4_calculate_crc(razer_kraken_v4_report* report)
{
/*-----------------------------------------------------*\
| The second to last byte of report is a simple |
| checksum. Just xor all bytes up with overflow and |
| you are done |
\*-----------------------------------------------------*/
unsigned char crc = 0;
unsigned char* report_ptr = (unsigned char*)report;
for(unsigned int i = 0; i < 61; i++)
{
crc ^= report_ptr[i];
}
return crc;
}
razer_kraken_v4_report RazerKrakenV4Controller::razer_kraken_v4_create_report(unsigned char command_class, unsigned char command_id, unsigned char data_size)
{
razer_kraken_v4_report new_report;
/*-----------------------------------------------------*\
| Zero out the new report |
\*-----------------------------------------------------*/
memset(&new_report, 0, sizeof(razer_kraken_v4_report));
/*-----------------------------------------------------*\
| Fill in the new report with the given parameters |
\*-----------------------------------------------------*/
new_report.report_id = report_index;
new_report.status = 0x00;
new_report.transaction_id = dev_transaction_id;
new_report.remaining_packets = 0x00;
new_report.protocol_type = 0x00;
new_report.data_size = data_size;
new_report.command_class = command_class;
new_report.command_id = command_id;
new_report.wireless_flag = dev_wireless_flag;
return new_report;
}
razer_kraken_v4_report RazerKrakenV4Controller::razer_kraken_v4_create_response()
{
razer_kraken_v4_report new_report;
/*-----------------------------------------------------*\
| Zero out the new report |
\*-----------------------------------------------------*/
memset(&new_report, 0, sizeof(razer_kraken_v4_report));
/*-----------------------------------------------------*\
| Fill in the new report with the given parameters |
\*-----------------------------------------------------*/
new_report.report_id = response_index;
new_report.status = 0x00;
new_report.transaction_id = dev_transaction_id;
new_report.remaining_packets = 0x00;
new_report.protocol_type = 0x00;
new_report.command_class = 0x00;
new_report.command_id = 0x00;
new_report.data_size = 0x00;
new_report.wireless_flag = dev_wireless_flag;
return new_report;
}
std::string RazerKrakenV4Controller::razer_get_firmware()
{
std::string firmware_string = "";
struct razer_kraken_v4_report report = razer_kraken_v4_create_report(0x00, 0x00, 0x04);
struct razer_kraken_v4_report response_report = razer_kraken_v4_create_response();
report.arguments[0] = RAZER_KRAKEN_V4_CMD_GET_FIRMWARE_INFO;
std::this_thread::sleep_for(2ms);
razer_usb_send(&report);
std::this_thread::sleep_for(5ms);
razer_usb_receive(&response_report);
firmware_string = "v" + std::to_string(response_report.arguments[3]) + "." + std::to_string(response_report.arguments[4]) + "." + std::to_string(response_report.arguments[5]) + "." + std::to_string(response_report.arguments[6]);
return firmware_string;
}
std::string RazerKrakenV4Controller::razer_get_serial()
{
char serial_string[16];
struct razer_kraken_v4_report report = razer_kraken_v4_create_report(0x00, 0x00, 0x04);
struct razer_kraken_v4_report response_report = razer_kraken_v4_create_response();
report.arguments[0] = RAZER_KRAKEN_V4_CMD_GET_SERIAL;
std::this_thread::sleep_for(2ms);
razer_usb_send(&report);
std::this_thread::sleep_for(5ms);
razer_usb_receive(&response_report);
memcpy(&serial_string[0], &response_report.arguments[3], 16);
serial_string[15] = '\0';
for(size_t i = 0; i < 15; i++)
{
if(serial_string[i] < 30 || serial_string[i] > 126)
{
serial_string[i] = ' ';
}
}
std::string ret_string = serial_string;
return ret_string;
}
int RazerKrakenV4Controller::razer_usb_receive(razer_kraken_v4_report* report)
{
report->crc = razer_kraken_v4_calculate_crc(report);
return hid_read(dev, (unsigned char *)report, sizeof(*report));
}
int RazerKrakenV4Controller::razer_usb_send(razer_kraken_v4_report* report)
{
return hid_write(dev, (unsigned char *)report, sizeof(*report));
}
@@ -0,0 +1,118 @@
/*---------------------------------------------------------*\
| RazerKrakenV4Controller.h |
| |
| Driver for Razer devices with 64-byte report |
| |
| Adam Honse (CalcProgrammer1) 21 Oct 2025 |
| |
| This file is part of the OpenRGB project |
| SPDX-License-Identifier: GPL-2.0-or-later |
\*---------------------------------------------------------*/
#pragma once
#include <hidapi.h>
#include "RGBController.h"
#include "DeviceGuardManager.h"
/*---------------------------------------------------------*\
| Struct packing macro for GCC and MSVC |
\*---------------------------------------------------------*/
#ifdef __GNUC__
#define PACK( __Declaration__ ) __Declaration__ __attribute__((__packed__))
#endif
#ifdef _MSC_VER
#define PACK( __Declaration__ ) __pragma( pack(push, 1) ) __Declaration__ __pragma( pack(pop))
#endif
PACK(struct razer_kraken_v4_report
{
unsigned char report_id;
unsigned char status;
unsigned char transaction_id;
unsigned short remaining_packets;
unsigned char protocol_type;
unsigned char data_size;
unsigned char command_class;
unsigned char command_id;
unsigned char wireless_flag;
unsigned char arguments[52];
unsigned char crc;
unsigned char reserved;
});
enum
{
RAZER_KRAKEN_V4_CMD_GET_SERIAL = 0x00,
RAZER_KRAKEN_V4_CMD_GET_FIRMWARE_INFO = 0x02,
RAZER_KRAKEN_V4_CMD_LIGHTING_SET_MODE = 0xC0,
RAZER_KRAKEN_V4_CMD_LIGHTING_SET_BRIGHTNESS = 0xC1,
};
class RazerKrakenV4Controller
{
public:
RazerKrakenV4Controller(hid_device* dev_handle, const char* path, unsigned short pid, std::string dev_name);
~RazerKrakenV4Controller();
unsigned int GetDeviceIndex();
device_type GetDeviceType();
std::string GetDeviceLocation();
std::string GetFirmwareString();
std::string GetName();
std::string GetSerialString();
unsigned char GetMaxBrightness();
void SetDirect(RGBColor* colors);
void SetBrightness(unsigned char brightness);
void SetModeWave();
private:
hid_device* dev;
unsigned short dev_pid;
/*---------------------------------------------------------*\
| Device-specific protocol settings |
\*---------------------------------------------------------*/
unsigned char dev_transaction_id;
unsigned char dev_led_id;
unsigned char dev_wireless_flag;
/*---------------------------------------------------------*\
| Device information strings |
\*---------------------------------------------------------*/
std::string firmware_version;
std::string location;
std::string name;
/*---------------------------------------------------------*\
| Index of device in Razer device list |
\*---------------------------------------------------------*/
unsigned int device_index;
/*---------------------------------------------------------*\
| HID report index for request and response |
\*---------------------------------------------------------*/
unsigned char report_index;
unsigned char response_index;
/*---------------------------------------------------------*\
| Matrix type |
\*---------------------------------------------------------*/
unsigned char matrix_type;
/*---------------------------------------------------------*\
| Private functions based on OpenRazer |
\*---------------------------------------------------------*/
unsigned char razer_kraken_v4_calculate_crc(razer_kraken_v4_report* report);
razer_kraken_v4_report razer_kraken_v4_create_report(unsigned char command_class, unsigned char command_id, unsigned char data_size);
razer_kraken_v4_report razer_kraken_v4_create_response();
std::string razer_get_firmware();
std::string razer_get_serial();
int razer_usb_receive(razer_kraken_v4_report* report);
int razer_usb_send(razer_kraken_v4_report* report);
};