Files
OpenRGB/Controllers/SinowealthController/SinowealthKeyboard10cController/RGBController_SinowealthKeyboard10c.cpp
Adam Honse a3b023d86c RGBController API Overhaul
* Reorganize and clean up RGBController API functions
    * Add functions to get protected RGBController member values
    * Make NetworkClient, ProfileManager, and ResourceManager friend classes so they can access protected members
    * Protected previously-public RGBController members
        * Information strings (name, vendor, description, version, serial location)
        * Device type
        * Active mode
        * Flags
        * LEDs vector
        * LED alternate names vector
        * Modes vector
        * Colors vector
        * Zones vector
    * Add CONTROLLER_FLAG_HIDDEN to allow plugins to hide controllers from control GUI
    * Add update reason codes to RGBController update callback and signal updates on more RGBController events
    * Add loop zone types and segmented zone type
    * Add matrix map field to segments
    * Rework matrix_map_type from using pointers to vector to prevent memory leaks
    * Rework KeyboardLayoutManager to return new matrix_map_type
    * Add access mutex to RGBController API
    * Add per-zone modes ot RGBController API
    * Add JSON description functions to RGBController API
2026-01-11 13:10:40 -06:00

166 lines
5.4 KiB
C++
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
/*---------------------------------------------------------*\
| RGBController_SinowealthKeyboard10c.cpp |
| |
| RGBController for Sinowealth Keyboards with PID 010C |
| |
| Rodrigo Tavares 27 Nov 2025 |
| |
| This file is part of the OpenRGB project |
| SPDX-License-Identifier: GPL-2.0-or-later |
\*---------------------------------------------------------*/
#include "KeyboardLayoutManager.h"
#include "RGBControllerKeyNames.h"
#include "SinowealthKeyboard10cController.h"
#include "SinowealthKeyboard10cDevices.h"
#include "RGBController_SinowealthKeyboard10c.h"
using namespace kbd10c;
using namespace std::chrono_literals;
/**------------------------------------------------------------------*\
@name Sinowealth Keyboard
@category Keyboard
@type USB
@save :x:
@direct :white_check_mark:
@effects :x:
@detectors DetectSinowealthKeyboard10c
@comment
\*-------------------------------------------------------------------*/
RGBController_SinowealthKeyboard10c::RGBController_SinowealthKeyboard10c(
SinowealthKeyboard10cController* controller_ptr, unsigned char model_id)
: model_id(model_id)
{
controller = controller_ptr;
name = controller->GetName();
type = DEVICE_TYPE_KEYBOARD;
vendor = "Sinowealth";
description = "Sinowealth Keyboard Device";
location = controller->GetLocation();
serial = controller->GetSerialString();
mode Off;
Off.name = "Off";
Off.flags = 0;
Off.color_mode = MODE_COLORS_NONE;
Off.value = MODE_OFF;
modes.push_back(Off);
mode Direct;
Direct.name = "Direct";
Direct.flags = MODE_FLAG_HAS_PER_LED_COLOR;
Direct.color_mode = MODE_COLORS_PER_LED;
Direct.value = MODE_DIRECT;
modes.push_back(Direct);
active_mode = MODE_DIRECT;
SetupZones();
/*---------------------------------------------------------*\
| The Sinowealth 010C Keyboard requires a steady stream |
| of packets in order to not revert out of direct mode. |
| Start a thread to continuously refresh the device |
\*---------------------------------------------------------*/
keepalive_thread_run = true;
keepalive_thread = new std::thread(&RGBController_SinowealthKeyboard10c::KeepaliveThreadFunction, this);
}
RGBController_SinowealthKeyboard10c::~RGBController_SinowealthKeyboard10c()
{
keepalive_thread_run = false;
keepalive_thread->join();
delete keepalive_thread;
delete controller;
}
void RGBController_SinowealthKeyboard10c::SetupZones()
{
/*---------------------------------------------------------*\
| Create the keyboard zone usiung Keyboard Layout Manager |
\*---------------------------------------------------------*/
zone new_zone;
new_zone.name = ZONE_EN_KEYBOARD;
new_zone.type = ZONE_TYPE_MATRIX;
sinowealth_device device = sinowealth_10c_keyboards.at(model_id);
KeyboardLayoutManager new_kb(KEYBOARD_LAYOUT_ANSI_QWERTY, device.keyboard_layout.base_size,
device.keyboard_layout.key_values);
new_kb.ChangeKeys(device.keyboard_layout.edit_keys);
new_zone.leds_count = new_kb.GetRowCount() * new_kb.GetColumnCount();
new_zone.leds_min = new_zone.leds_count;
new_zone.leds_max = new_zone.leds_count;
/*---------------------------------------------------------*\
| These keyboards use sparse LED indexes — for example, a |
| 99-key board might use LED indexes 0112, leaving some |
| numbers unused. Empty positions are marked 0xFFFFFFFF. |
| |
| We map each key to its actual LED index, filling the |
| `leds` vector by those indexes and leaving gaps where no |
| LED exists. |
\*---------------------------------------------------------*/
new_zone.matrix_map = new_kb.GetKeyMap(KEYBOARD_MAP_FILL_TYPE_VALUE);
leds.resize(new_zone.leds_count);
for(unsigned int i = 0, j = 0; i < new_zone.leds_count; i++)
{
if(new_zone.matrix_map.map[i] == 0xFFFFFFFF)
{
continue;
}
led new_led;
new_led.name = new_kb.GetKeyNameAt(j);
new_led.value = new_kb.GetKeyValueAt(j);
leds[new_zone.matrix_map.map[i]] = new_led;
j++;
}
zones.push_back(new_zone);
SetupColors();
}
void RGBController_SinowealthKeyboard10c::DeviceUpdateLEDs()
{
last_update_time = std::chrono::steady_clock::now();
controller->SetLEDsDirect(colors);
}
void RGBController_SinowealthKeyboard10c::DeviceUpdateZoneLEDs(int /*zone*/)
{
DeviceUpdateLEDs();
}
void RGBController_SinowealthKeyboard10c::DeviceUpdateSingleLED(int /*led*/)
{
DeviceUpdateLEDs();
}
void RGBController_SinowealthKeyboard10c::DeviceUpdateMode()
{
}
void RGBController_SinowealthKeyboard10c::KeepaliveThreadFunction()
{
while(keepalive_thread_run.load())
{
if(active_mode == MODE_DIRECT && (std::chrono::steady_clock::now() - last_update_time) > 1s)
{
UpdateLEDsInternal();
}
std::this_thread::sleep_for(500ms);
}
}