File Clevo8910.patch of Package OpenRGB

Index: OpenRGB-1.0~rc2+git32.gda9a96e3/Controllers/Clevo8910/Clevo8910Controller.cpp
===================================================================
--- /dev/null
+++ OpenRGB-1.0~rc2+git32.gda9a96e3/Controllers/Clevo8910/Clevo8910Controller.cpp
@@ -0,0 +1,167 @@
+/*
+ * Clevo8910Controller.cpp
+ *
+ *   Driver for Clevo Color per key keyboard
+ *
+ *   EZY      9 Jan 2026
+ *
+ *   This file is part of the OpenRGB project
+ *   SPDX-License-Identifier: GPL-2.0-or-later
+ */
+
+#include <string.h>
+#include "Clevo8910Controller.h"
+#ifdef DEBUG
+#include "LogManager.h"
+#endif
+
+Clevo8910Controller::Clevo8910Controller(hidapi_wrapper hid_wrapper, hid_device* dev_handle, const hid_device_info& info, const unsigned short pid, std::string dev_name)
+{
+#   ifdef DEBUG
+    LOG_DEBUG("[Clevo Controller] detected: %s", "Starting Controller");
+#   endif
+    wrapper		= hid_wrapper;
+    dev                 = dev_handle;
+    location            = info.path;
+    usb_pid             = pid;
+    name                = dev_name;
+}
+
+Clevo8910Controller::~Clevo8910Controller()
+{
+    wrapper.hid_close(dev);
+}
+
+std::string Clevo8910Controller::GetDeviceLocation()
+{
+    return("HID: " + location);
+}
+
+std::string Clevo8910Controller::GetDeviceName()
+{
+    return(name);
+}
+
+uint16_t Clevo8910Controller::GetUSBPID()
+{
+    return(usb_pid);
+}
+
+void Clevo8910Controller::TurnOff()
+{
+    uint8_t usb_buf[CLEVO8910_REPORT_SIZE];
+    memset(usb_buf, 0x00, CLEVO8910_REPORT_SIZE);
+    usb_buf[0] = CLEVO8910_CLASS_BYTE;
+    usb_buf[2] = CLEVO8910_OFF_CMD;
+    wrapper.hid_send_feature_report(dev, usb_buf, CLEVO8910_REPORT_SIZE);
+}
+
+void Clevo8910Controller::SaveBios(bool save)
+{
+    uint8_t usb_buf[CLEVO8910_REPORT_SIZE];
+    memset(usb_buf+3, 0x00, CLEVO8910_REPORT_SIZE-3);
+    usb_buf[0] = CLEVO8910_CLASS_BYTE;
+    usb_buf[1] = CLEVO8910_BIOS_CMD;
+    usb_buf[2] = (save ? (uint8_t)1 : (uint8_t) 0);
+    wrapper.hid_send_feature_report(dev, usb_buf, CLEVO8910_REPORT_SIZE);
+}
+
+void Clevo8910Controller::setparams(uint8_t brightness, uint8_t speed)
+{
+    uint8_t usb_buf[CLEVO8910_REPORT_SIZE];
+
+    memset(usb_buf, 0x00, CLEVO8910_REPORT_SIZE);
+    usb_buf[0] = CLEVO8910_CLASS_BYTE;
+    usb_buf[1] = CLEVO8910_BRT_SPD_CMD;
+    usb_buf[2] = brightness;
+    usb_buf[3] = speed;
+    wrapper.hid_send_feature_report(dev, usb_buf, CLEVO8910_REPORT_SIZE);
+}
+
+
+
+void Clevo8910Controller::SetSimpleMode(uint8_t effect, uint8_t bright, uint8_t speed)
+{
+    uint8_t usb_buf[CLEVO8910_REPORT_SIZE];
+    setparams(bright, speed);
+
+    memset(usb_buf, 0x00, CLEVO8910_REPORT_SIZE);
+    usb_buf[0] = CLEVO8910_CLASS_BYTE;
+
+    usb_buf[2] = effect;
+    wrapper.hid_send_feature_report(dev, usb_buf, CLEVO8910_REPORT_SIZE);
+}
+
+void Clevo8910Controller::SetMode(uint8_t effect, uint8_t brightness,
+			uint8_t speed, uint8_t key,
+			RGBColor color )
+{
+    uint8_t usb_buf[CLEVO8910_REPORT_SIZE];
+    setparams(brightness, speed);
+
+    memset(usb_buf, 0x00, CLEVO8910_REPORT_SIZE);
+    usb_buf[0] = CLEVO8910_CLASS_BYTE;
+
+    usb_buf[1] = effect;
+    usb_buf[2] = key;
+    usb_buf[3] = RGBGetRValue(color);
+    usb_buf[4] = RGBGetGValue(color);
+    usb_buf[5] = RGBGetBValue(color);
+
+    wrapper.hid_send_feature_report(dev, usb_buf, CLEVO8910_REPORT_SIZE);
+}
+
+void Clevo8910Controller::SetColors(uint8_t mode,
+				    std::vector<led> array_leds,
+				    bool rnd_flag,
+				    std::vector<RGBColor> array_colors)
+{
+    uint8_t usb_buf[CLEVO8910_REPORT_SIZE];
+    usb_buf[0] = CLEVO8910_CLASS_BYTE;
+    usb_buf[1] = mode;
+    usb_buf[6] = 0;
+    if (!rnd_flag) 
+    {
+	for(size_t i = 0; i < array_leds.size(); i++)
+	{
+	    usb_buf[2] = (uint8_t)(array_leds[i].value);
+	    usb_buf[3] = RGBGetRValue(array_colors[i]);
+	    usb_buf[4] = RGBGetGValue(array_colors[i]);
+	    usb_buf[5] = RGBGetBValue(array_colors[i]);
+	    wrapper.hid_send_feature_report(dev, usb_buf, CLEVO8910_REPORT_SIZE);
+	}
+    } else {
+	usb_buf[2] = 0xFF;
+	usb_buf[4] = 0;
+	usb_buf[5] = 0;
+	for(size_t i = 0; i < array_leds.size(); i++)
+	{
+	    usb_buf[3] = (uint8_t)(array_leds[i].value);
+	    wrapper.hid_send_feature_report(dev, usb_buf, CLEVO8910_REPORT_SIZE);
+	}
+
+    }
+}
+
+void Clevo8910Controller::SetSingleLED(uint8_t effect, uint8_t key, RGBColor color)
+{
+    const RGBColor rndcolor = ToRGBColor(0, 0, 0);
+
+    uint8_t usb_buf[CLEVO8910_REPORT_SIZE];
+    usb_buf[0] = CLEVO8910_CLASS_BYTE;
+    usb_buf[1] = effect;
+
+    if (color == rndcolor && effect != (uint8_t )(CLEVO8910_MODE_DIRECT & 0xFF))
+    {
+	usb_buf[2] = 0xFF; //This is used for random color mode with the key in the next byte
+	usb_buf[3] = key;
+	usb_buf[4] = 0;
+	usb_buf[5] = 0;
+    } else {
+	usb_buf[2] = key;
+	usb_buf[3] = RGBGetRValue(color);
+	usb_buf[4] = RGBGetGValue(color);
+	usb_buf[5] = RGBGetBValue(color);
+    }
+    wrapper.hid_send_feature_report(dev, usb_buf, CLEVO8910_REPORT_SIZE);
+}
Index: OpenRGB-1.0~rc2+git32.gda9a96e3/Controllers/Clevo8910/Clevo8910ControllerDetect.cpp
===================================================================
--- /dev/null
+++ OpenRGB-1.0~rc2+git32.gda9a96e3/Controllers/Clevo8910/Clevo8910ControllerDetect.cpp
@@ -0,0 +1,39 @@
+
+/********************************************************
+ *
+ *   clevo8910Controller.cpp
+ *   
+ *   Detector for Clevo ITE controller 048d:8910 colour per key
+ *   
+ *   Ezy  9 Jan  2026
+ *   
+ *   This file is part of the OpenRGB project
+ *   SPDX-License-Identifier: GPL-2.0-or-later
+ *******************************************************/
+
+#include "Detector.h"
+#include "RGBController.h"
+#include "hidapi_wrapper.h"
+#include "Clevo8910Controller.h"
+#include "RGBController_Clevo8910.h"
+
+#define CLEVO8910_VID        0x048D
+#define CLEVO8910_PID        0x8910
+
+
+void DetectClevo8910Controller(hidapi_wrapper wrapper, hid_device_info* info, const std::string& name)
+{
+
+    
+    hid_device* dev = wrapper.hid_open_path(info->path);
+
+    if(dev)
+    {
+        Clevo8910Controller*     controller         = new Clevo8910Controller(wrapper, dev, *info, info->product_id, name);
+        RGBController_Clevo8910* rgb_controller     = new RGBController_Clevo8910(controller);
+
+        ResourceManager::get()->RegisterRGBController(rgb_controller);
+    }
+}
+
+REGISTER_HID_WRAPPED_DETECTOR_PU("Clevo 8910 Keyboard", DetectClevo8910Controller, CLEVO8910_VID, CLEVO8910_PID, 0x00, 0x00);
Index: OpenRGB-1.0~rc2+git32.gda9a96e3/Controllers/Clevo8910/Clevo8910Controller.h
===================================================================
--- /dev/null
+++ OpenRGB-1.0~rc2+git32.gda9a96e3/Controllers/Clevo8910/Clevo8910Controller.h
@@ -0,0 +1,96 @@
+
+/*
+ * Clevo8910Controller.h
+ *   
+ *   Driver for Clevo colour per key keyboard
+ *   
+ *   Ezy 9 Dec 2026
+ *   
+ *   This file is part of the OpenRGB project
+ *   SPDX-License-Identifier: GPL-2.0-or-later
+ */
+
+#pragma once
+
+#include <string>
+#include <hidapi_wrapper.h>
+#include "RGBController.h"
+#include "Clevo8910Keys.h"
+
+#define CLEVO8910_CLASS_BYTE                 0xCC
+#define CLEVO8910_DIRECT_CMD                 0x01
+#define CLEVO8910_DIRECT_BRIGHTNESS_MIN      0
+#define CLEVO8910_DIRECT_BRIGHTNESS_MAX      10
+#define CLEVO8910_DIRECT_BRIGHTNESS_DEFAULT  5
+#define CLEVO8910_DIRECT_SPEED_MIN           0
+#define CLEVO8910_DIRECT_SPEED_MAX           2
+#define CLEVO8910_DIRECT_SPEED_DEFAULT       1
+#define CLEVO8910_BRT_SPD_CMD                0x09
+#define CLEVO8910_OFF_CMD                    0x0C
+#define CLEVO8910_BIOS_CMD                  0x20
+
+enum
+{
+    CLEVO8910_COMPLEX_MODE         = (1<<8),
+    CLEVO8910_MODE_DIRECT          = CLEVO8910_COMPLEX_MODE+1,
+    CLEVO8910_MODE_RIPPLE          = CLEVO8910_COMPLEX_MODE+7,
+    CLEVO8910_MODE_FADE            = CLEVO8910_COMPLEX_MODE+8,
+    CLEVO8910_MODE_BREATHE         = CLEVO8910_COMPLEX_MODE+10,
+    CLEVO8910_MODE_BLINK           = CLEVO8910_COMPLEX_MODE+11,
+};
+
+enum
+{
+    CLEVO8910_TYPE_COLOURS         = 1,
+    CLEVO8910_TYPE_CYCLE           = 2,
+    CLEVO8910_TYPE_STOP            = 3,
+    CLEVO8910_TYPE_WAVE            = 4,
+    CLEVO8910_TYPE_NOOP            = 5,
+    CLEVO8910_TYPE_RANDOM          = 9,
+    CLEVO8910_TYPE_SCAN            = 10,
+    CLEVO8910_TYPE_SNAKE           = 11,
+    CLEVO8910_TYPE_OFF             = 12
+};
+
+
+class Clevo8910Controller
+{
+    public:
+        Clevo8910Controller(hidapi_wrapper hid_wrapper, hid_device* dev_handle, const hid_device_info& info, const unsigned short pid, std::string dev_name);
+        ~Clevo8910Controller();
+
+        std::string GetDeviceLocation();
+        std::string GetDeviceName();
+        uint16_t    GetUSBPID();
+        void        TurnOff();
+	void	    SaveBios(bool save);
+	void	    setparams(uint8_t brightness, uint8_t speed);
+
+        void	    SetSimpleMode(uint8_t effect, uint8_t bright, uint8_t speed);
+	void	    SetMode(uint8_t effect, uint8_t brightness,
+		    uint8_t speed, uint8_t key,
+		    RGBColor color );
+	void	    SetColors(uint8_t mode, std::vector<led> array_leds, bool rnd_flag,  std::vector<RGBColor> array_colors);
+	void	    SetSingleLED(uint8_t mode, uint8_t key, RGBColor color);
+
+    private:
+	hidapi_wrapper wrapper;
+        hid_device* dev;
+        std::string location;
+        std::string name;
+        //std::string serial_number;
+        uint16_t    usb_pid;
+
+};
+
+typedef	struct
+	{
+	    uint8_t header;
+	    uint8_t mode;
+	    uint8_t param;
+	    uint8_t red;
+	    uint8_t greem;
+	    uint8_t blue;
+	    uint8_t end;
+	} report_buf_t;
+#define CLEVO8910_REPORT_SIZE	(7)
Index: OpenRGB-1.0~rc2+git32.gda9a96e3/Controllers/Clevo8910/Clevo8910Keys.h
===================================================================
--- /dev/null
+++ OpenRGB-1.0~rc2+git32.gda9a96e3/Controllers/Clevo8910/Clevo8910Keys.h
@@ -0,0 +1,162 @@
+
+/**********************************************************
+ * Clevo8910Keys.h
+ * 
+ *   Keymap for Clevo per key coiour keyboards
+ *
+ *   Ezy			9 Jan 2026
+ * 
+ *   This file is part of the OpenRGB project
+ *   SPDX-License-Identifier: GPL-2.0-or-later
+ ***********************************************************/
+
+#pragma once
+
+#include <string>
+#include "RGBControllerKeyNames.h"
+#include "RGBController.h"
+
+#define NA 0xFFFFFFFF
+
+
+static const unsigned int clevo8910_leds_map[] =
+    {    0,   1,   2,   3,   4,   5,   6,   7,   8,   9,  10,  11,  12,  13,  14,  15,  16,  17,  18,  19,
+        20,  21,  22,  23,  24,  25,  26,  27,  28,  29,  30,  31,  32,  33,  34,  NA,  35,  36,  37,  38,
+        39,  40,  41,  42,  43,  44,  45,  46,  47,  48,  49,  50,  51,  52,  53,  NA,  54,  55,  56,  57,
+        58,  59,  60,  61,  62,  63,  64,  65,  66,  67,  68,  69,  70,  71,  72,  NA,  73,  74,  75,  76,
+        77,  78,  79,  80,  81,  82,  83,  84,  85,  86,  87,  88,  89,  90,  91,  NA,  92,  93,  94,  95,
+        96,  97,  98,  99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111,  NA, 112, 113, 114 };
+#define CLEVO8910_NUM_LEDS (sizeof (clevo8910_leds_map) / sizeof (unsigned int))
+#define CLEVO8910_KEYROWS 6
+#define CLEVO8910_KEYSINROW 20
+
+const led clevo8910_leds[]
+{
+    //row 1
+    {KEY_EN_ESCAPE, 0x00},//0
+    {KEY_EN_F1, 0x01},//1
+    {KEY_EN_F2, 0x02},//2
+    {KEY_EN_F3, 0x03},//3
+    {KEY_EN_F4, 0x04},//4
+    {KEY_EN_F5, 0x05},//5
+    {KEY_EN_F6, 0x06},//6
+    {KEY_EN_F7, 0x07},//7
+    {KEY_EN_F8, 0x08},//8
+    {KEY_EN_F9, 0x09},//9
+    {KEY_EN_F10, 0x0A},//10
+    {KEY_EN_F11, 0x0B},//11
+    {KEY_EN_F12, 0x0C},//12
+    {KEY_EN_PRINT_SCREEN, 0x0D},//15
+    {KEY_EN_INSERT, 0x0E},//14
+    {KEY_EN_DELETE, 0x0F},//15
+    {KEY_EN_HOME, 0x10},//16
+    {KEY_EN_END, 0x11},//17
+    {KEY_EN_PAGE_UP, 0x12},//18
+    {KEY_EN_PAGE_DOWN, 0x13},//19
+
+    //row 2
+    {KEY_EN_BACK_TICK, 0x20},//20
+    {KEY_EN_1, 0x21},//21
+    {KEY_EN_2, 0x22},//22
+    {KEY_EN_3, 0x23},//23
+    {KEY_EN_4, 0x24},//24
+    {KEY_EN_5, 0x25},//25
+    {KEY_EN_6, 0x26},//26
+    {KEY_EN_7, 0x27},//27
+    {KEY_EN_8, 0x28},//28
+    {KEY_EN_9, 0x29},//29
+    {KEY_EN_0, 0x2A},//30
+    {KEY_EN_MINUS, 0x2B},//31
+    {KEY_EN_EQUALS, 0x2D},//32
+    {KEY_EN_BACKSPACE, 0x2E},//33
+    {KEY_EN_BACKSPACE, 0x2F},//34
+    {KEY_EN_NUMPAD_LOCK, 0x30},//35
+    {KEY_EN_NUMPAD_DIVIDE, 0x31},//36
+    {KEY_EN_NUMPAD_TIMES, 0x32},//37
+    {KEY_EN_NUMPAD_MINUS, 0x33},//38
+
+    //row 3
+    {KEY_EN_TAB, 0x40},//39
+    {KEY_EN_TAB, 0x41},//40
+    {KEY_EN_Q, 0x42},//41
+    {KEY_EN_W, 0x43},//42
+    {KEY_EN_E, 0x44},//43
+    {KEY_EN_R, 0x45},//44
+    {KEY_EN_T, 0x46},//45
+    {KEY_EN_Y, 0x47},//46
+    {KEY_EN_U, 0x48},//47
+    {KEY_EN_I, 0x49},//48
+    {KEY_EN_O, 0x4A},//49
+    {KEY_EN_P, 0x4B},//50
+    {KEY_EN_LEFT_BRACKET, 0x4C},//51
+    {KEY_EN_RIGHT_BRACKET, 0x4D},//52
+    {KEY_EN_ANSI_BACK_SLASH, 0x4E},//53
+    {KEY_EN_NUMPAD_7, 0x50},//54
+    {KEY_EN_NUMPAD_8, 0x51},//55
+    {KEY_EN_NUMPAD_9, 0x52},//56
+    {KEY_EN_NUMPAD_PLUS, 0x53},//57
+
+    //row 4
+    {KEY_EN_CAPS_LOCK, 0x60},//58
+    {KEY_EN_CAPS_LOCK, 0x61},//59
+    {KEY_EN_A, 0x62},//60
+    {KEY_EN_S, 0x63},//61
+    {KEY_EN_D, 0x64},//62
+    {KEY_EN_F, 0x65},//63
+    {KEY_EN_G, 0x66},//64
+    {KEY_EN_H, 0x67},//65
+    {KEY_EN_J, 0x68},//66
+    {KEY_EN_K, 0x69},//67
+    {KEY_EN_L, 0x6A},//68
+    {KEY_EN_SEMICOLON, 0x6B},//69
+    {KEY_EN_QUOTE, 0x6C},//70
+    {KEY_EN_ANSI_ENTER, 0x6E},//71
+    {KEY_EN_ANSI_ENTER, 0x6F},//72
+    {KEY_EN_NUMPAD_4, 0x70},//73
+    {KEY_EN_NUMPAD_5, 0x71},//74
+    {KEY_EN_NUMPAD_6, 0x72},//75
+    {KEY_EN_NUMPAD_PLUS, 0x73},//76
+
+    //row 5
+    {KEY_EN_LEFT_SHIFT, 0x80},//77
+    {KEY_EN_LEFT_SHIFT, 0x82},//78
+    {KEY_EN_Z, 0x83},//79
+    {KEY_EN_X, 0x84},//80
+    {KEY_EN_C, 0x85},//81
+    {KEY_EN_V, 0x86},//82
+    {KEY_EN_B, 0x87},//83
+    {KEY_EN_N, 0x88},//84
+    {KEY_EN_M, 0x89},//85
+    {KEY_EN_COMMA, 0x8A},//86
+    {KEY_EN_PERIOD, 0x8B},//87
+    {KEY_EN_FORWARD_SLASH, 0x8C},//88
+    {KEY_EN_RIGHT_SHIFT, 0x8D},//89
+    {KEY_EN_RIGHT_SHIFT, 0x8E},//90
+    {KEY_EN_UP_ARROW, 0x8F},//91
+    {KEY_EN_NUMPAD_1, 0x90},//92
+    {KEY_EN_NUMPAD_2, 0x91},//93
+    {KEY_EN_NUMPAD_3, 0x92},//94
+    {KEY_EN_NUMPAD_ENTER, 0x93},//95
+
+    //row 6
+    {KEY_EN_LEFT_CONTROL, 0xA0},//96
+    {KEY_EN_LEFT_CONTROL, 0xA1},//97
+    {KEY_EN_LEFT_FUNCTION, 0xA2},//98
+    {KEY_EN_LEFT_WINDOWS, 0xA3},//99
+    {KEY_EN_LEFT_ALT, 0xA4},//100
+    {KEY_EN_SPACE, 0xA5},//101
+    {KEY_EN_SPACE, 0xA6},//102
+    {KEY_EN_SPACE, 0xA8},//103
+    {KEY_EN_SPACE, 0xA9},//104
+    {KEY_EN_RIGHT_ALT, 0xAA},//105
+    {KEY_EN_MENU, 0xAB},//106
+    {KEY_EN_RIGHT_CONTROL, 0xAC},//107
+    {KEY_EN_RIGHT_CONTROL, 0xAD},//108
+    {KEY_EN_LEFT_ARROW, 0xAE},//109
+    {KEY_EN_DOWN_ARROW, 0xAF},//110
+    {KEY_EN_RIGHT_ARROW, 0xB0},//111
+    {KEY_EN_NUMPAD_0, 0xB1},//112
+    {KEY_EN_NUMPAD_PERIOD, 0xB2},//113
+    {KEY_EN_NUMPAD_ENTER, 0xB3},//114
+};
+#define CLEVO8910_KEYBOARD_LED_COUNT  (sizeof (clevo8910_leds) / sizeof (led))
Index: OpenRGB-1.0~rc2+git32.gda9a96e3/Controllers/Clevo8910/RGBController_Clevo8910.cpp
===================================================================
--- /dev/null
+++ OpenRGB-1.0~rc2+git32.gda9a96e3/Controllers/Clevo8910/RGBController_Clevo8910.cpp
@@ -0,0 +1,390 @@
+
+/*
+ * RGBController_Clevo8910.cpp
+ *   
+ *   RGBController for Clevo RGB Colour per key
+ *   
+ *   Ezy		29 Dec 2025
+ *   
+ *   This file is part of the OpenRGB project
+ *   SPDX-License-Identifier: GPL-2.0-or-later
+ */
+
+#include "RGBController_Clevo8910.h"
+#include "LogManager.h"
+
+/**------------------------------------------------------------------*\
+    @name Clevo 8910
+    @category Keyboard
+    @type USB
+    @save :X:
+    @direct :white_check_mark:
+    @effects :white_check_mark:
+    @detectors DetectClevo8910Controller
+    @comment
+\*-------------------------------------------------------------------*/
+
+
+RGBController_Clevo8910::RGBController_Clevo8910(Clevo8910Controller* controller_ptr)
+{
+    controller                          = controller_ptr;
+
+    name                                = controller->GetDeviceName();
+    vendor                              = "OEM - Clevo";
+    description                         = name;
+    location                            = controller->GetDeviceLocation();
+    flags                               = CONTROLLER_FLAG_LOCAL;
+    type				= DEVICE_TYPE_KEYBOARD;
+
+    mode Direct;
+    Direct.name                         = "Direct";
+    Direct.value                        = CLEVO8910_MODE_DIRECT;
+    Direct.flags                        = MODE_FLAG_MANUAL_SAVE |
+					    MODE_FLAG_HAS_PER_LED_COLOR |
+					    MODE_FLAG_HAS_BRIGHTNESS;
+    Direct.color_mode                   = MODE_COLORS_PER_LED;
+    Direct.brightness_min               = CLEVO8910_DIRECT_BRIGHTNESS_MIN;
+    Direct.brightness_max               = CLEVO8910_DIRECT_BRIGHTNESS_MAX;
+    Direct.speed			= CLEVO8910_DIRECT_SPEED_DEFAULT;
+    Direct.brightness                   = CLEVO8910_DIRECT_BRIGHTNESS_DEFAULT;
+    modes.push_back(Direct);
+
+
+    mode Ripple;
+    Ripple.name                      = "Ripple";
+    Ripple.value                     = CLEVO8910_MODE_RIPPLE;
+    Ripple.flags                     = MODE_FLAG_MANUAL_SAVE |
+					MODE_FLAG_HAS_SPEED | 
+    					MODE_FLAG_HAS_BRIGHTNESS | 
+					MODE_FLAG_HAS_PER_LED_COLOR | 
+					MODE_FLAG_HAS_RANDOM_COLOR;
+    Ripple.speed_min                 = CLEVO8910_DIRECT_SPEED_MIN;
+    Ripple.speed_max                 = CLEVO8910_DIRECT_SPEED_MAX;
+    Ripple.brightness_min            = CLEVO8910_DIRECT_BRIGHTNESS_MIN;
+    Ripple.brightness_max            = CLEVO8910_DIRECT_BRIGHTNESS_MAX;
+    Ripple.speed                     = CLEVO8910_DIRECT_SPEED_DEFAULT;
+    Ripple.brightness                = CLEVO8910_DIRECT_BRIGHTNESS_DEFAULT;
+    Ripple.color_mode                = MODE_COLORS_RANDOM;
+    Ripple.colors.resize(1);
+    modes.push_back(Ripple);
+
+    mode Fade;
+    Fade.name                      = "Fade";
+    Fade.value                     = CLEVO8910_MODE_FADE;
+    Fade.flags                     = MODE_FLAG_MANUAL_SAVE |
+					MODE_FLAG_HAS_SPEED | 
+    					MODE_FLAG_HAS_BRIGHTNESS | 
+					MODE_FLAG_HAS_PER_LED_COLOR | 
+					MODE_FLAG_HAS_RANDOM_COLOR;
+    Fade.speed_min                 = CLEVO8910_DIRECT_SPEED_MIN;
+    Fade.speed_max                 = CLEVO8910_DIRECT_SPEED_MAX;
+    Fade.brightness_min            = CLEVO8910_DIRECT_BRIGHTNESS_MIN;
+    Fade.brightness_max            = CLEVO8910_DIRECT_BRIGHTNESS_MAX;
+    Fade.speed                     = CLEVO8910_DIRECT_SPEED_DEFAULT;
+    Fade.brightness                = CLEVO8910_DIRECT_BRIGHTNESS_DEFAULT;
+    Fade.color_mode                = MODE_COLORS_RANDOM;
+    Fade.colors.resize(1);
+    modes.push_back(Fade);
+
+    mode Breathe;
+    Breathe.name                      = "Breathe";
+    Breathe.value                     = CLEVO8910_MODE_BREATHE;
+    Breathe.flags                     = MODE_FLAG_MANUAL_SAVE |
+					MODE_FLAG_HAS_SPEED | 
+    					MODE_FLAG_HAS_BRIGHTNESS | 
+					MODE_FLAG_HAS_MODE_SPECIFIC_COLOR | 
+					MODE_FLAG_HAS_RANDOM_COLOR;
+    Breathe.speed_min                 = CLEVO8910_DIRECT_SPEED_MIN;
+    Breathe.speed_max                 = CLEVO8910_DIRECT_SPEED_MAX;
+    Breathe.brightness_min            = CLEVO8910_DIRECT_BRIGHTNESS_MIN;
+    Breathe.brightness_max            = CLEVO8910_DIRECT_BRIGHTNESS_MAX;
+    Breathe.speed                     = CLEVO8910_DIRECT_SPEED_DEFAULT;
+    Breathe.brightness                = CLEVO8910_DIRECT_BRIGHTNESS_DEFAULT;
+    Breathe.color_mode                = MODE_COLORS_RANDOM;
+    Breathe.colors.resize(1);
+    modes.push_back(Breathe);
+
+    mode Blink;
+    Blink.name                      = "Blink";
+    Blink.value                     = CLEVO8910_MODE_BLINK;
+    Blink.flags                     = MODE_FLAG_MANUAL_SAVE |
+					MODE_FLAG_HAS_SPEED | 
+    					MODE_FLAG_HAS_BRIGHTNESS | 
+					MODE_FLAG_HAS_MODE_SPECIFIC_COLOR | 
+					MODE_FLAG_HAS_RANDOM_COLOR;
+    Blink.speed_min                 = CLEVO8910_DIRECT_SPEED_MIN;
+    Blink.speed_max                 = CLEVO8910_DIRECT_SPEED_MAX;
+    Blink.brightness_min            = CLEVO8910_DIRECT_BRIGHTNESS_MIN;
+    Blink.brightness_max            = CLEVO8910_DIRECT_BRIGHTNESS_MAX;
+    Blink.speed                     = CLEVO8910_DIRECT_SPEED_DEFAULT;
+    Blink.brightness                = CLEVO8910_DIRECT_BRIGHTNESS_DEFAULT;
+    Blink.color_mode                = MODE_COLORS_RANDOM;
+    Blink.colors.resize(1);
+    modes.push_back(Blink);
+
+    mode Colours;
+    Colours.name                      = "Colors";
+    Colours.value                     = CLEVO8910_TYPE_COLOURS;
+    Colours.flags                     = MODE_FLAG_MANUAL_SAVE |
+					MODE_FLAG_HAS_SPEED | 
+    					MODE_FLAG_HAS_BRIGHTNESS | 
+					MODE_FLAG_HAS_RANDOM_COLOR;
+    Colours.speed_min                 = CLEVO8910_DIRECT_SPEED_MIN;
+    Colours.speed_max                 = CLEVO8910_DIRECT_SPEED_MAX;
+    Colours.brightness_min            = CLEVO8910_DIRECT_BRIGHTNESS_MIN;
+    Colours.brightness_max            = CLEVO8910_DIRECT_BRIGHTNESS_MAX;
+    Colours.speed                     = CLEVO8910_DIRECT_SPEED_DEFAULT;
+    Colours.brightness                = CLEVO8910_DIRECT_BRIGHTNESS_DEFAULT;
+    Colours.color_mode                = MODE_COLORS_RANDOM;
+    modes.push_back(Colours);
+
+    mode Cycle;
+    Cycle.name                      = "Cycle";
+    Cycle.value                     = CLEVO8910_TYPE_CYCLE;
+    Cycle.flags                     = MODE_FLAG_MANUAL_SAVE |
+					MODE_FLAG_HAS_SPEED | 
+    					MODE_FLAG_HAS_BRIGHTNESS | 
+					MODE_FLAG_HAS_RANDOM_COLOR;
+    Cycle.speed_min                 = CLEVO8910_DIRECT_SPEED_MIN;
+    Cycle.speed_max                 = CLEVO8910_DIRECT_SPEED_MAX;
+    Cycle.brightness_min            = CLEVO8910_DIRECT_BRIGHTNESS_MIN;
+    Cycle.brightness_max            = CLEVO8910_DIRECT_BRIGHTNESS_MAX;
+    Cycle.speed                     = CLEVO8910_DIRECT_SPEED_DEFAULT;
+    Cycle.brightness                = CLEVO8910_DIRECT_BRIGHTNESS_DEFAULT;
+    Cycle.color_mode                = MODE_COLORS_RANDOM;
+    modes.push_back(Cycle);
+
+    mode Stop;
+    Stop.name                      = "Stop";
+    Stop.value                     = CLEVO8910_TYPE_STOP;
+    Stop.flags                     = MODE_FLAG_HAS_SPEED | 
+    					MODE_FLAG_HAS_BRIGHTNESS | 
+					MODE_FLAG_HAS_RANDOM_COLOR;
+    Stop.speed_min                 = CLEVO8910_DIRECT_SPEED_MIN;
+    Stop.speed_max                 = CLEVO8910_DIRECT_SPEED_MAX;
+    Stop.brightness_min            = CLEVO8910_DIRECT_BRIGHTNESS_MIN;
+    Stop.brightness_max            = CLEVO8910_DIRECT_BRIGHTNESS_MAX;
+    Stop.speed                     = CLEVO8910_DIRECT_SPEED_DEFAULT;
+    Stop.brightness                = CLEVO8910_DIRECT_BRIGHTNESS_DEFAULT;
+    Stop.color_mode                = MODE_COLORS_RANDOM;
+    modes.push_back(Stop);
+
+    mode Noop;
+    Noop.name                      = "Noop";
+    Noop.value                     = CLEVO8910_TYPE_NOOP;
+    Noop.flags                     = MODE_FLAG_HAS_SPEED | 
+    					MODE_FLAG_HAS_BRIGHTNESS | 
+					MODE_FLAG_HAS_RANDOM_COLOR;
+    Noop.speed_min                 = CLEVO8910_DIRECT_SPEED_MIN;
+    Noop.speed_max                 = CLEVO8910_DIRECT_SPEED_MAX;
+    Noop.brightness_min            = CLEVO8910_DIRECT_BRIGHTNESS_MIN;
+    Noop.brightness_max            = CLEVO8910_DIRECT_BRIGHTNESS_MAX;
+    Noop.speed                     = CLEVO8910_DIRECT_SPEED_DEFAULT;
+    Noop.brightness                = CLEVO8910_DIRECT_BRIGHTNESS_DEFAULT;
+    Noop.color_mode                = MODE_COLORS_RANDOM;
+    modes.push_back(Noop);
+
+    mode Wave;
+    Wave.name                      = "Wave";
+    Wave.value                     = CLEVO8910_TYPE_WAVE;
+    Wave.flags                     = MODE_FLAG_MANUAL_SAVE |
+					MODE_FLAG_HAS_SPEED | 
+    					MODE_FLAG_HAS_BRIGHTNESS | 
+					MODE_FLAG_HAS_RANDOM_COLOR;
+    Wave.speed_min                 = CLEVO8910_DIRECT_SPEED_MIN;
+    Wave.speed_max                 = CLEVO8910_DIRECT_SPEED_MAX;
+    Wave.brightness_min            = CLEVO8910_DIRECT_BRIGHTNESS_MIN;
+    Wave.brightness_max            = CLEVO8910_DIRECT_BRIGHTNESS_MAX;
+    Wave.speed                     = CLEVO8910_DIRECT_SPEED_DEFAULT;
+    Wave.brightness                = CLEVO8910_DIRECT_BRIGHTNESS_DEFAULT;
+    Wave.color_mode                = MODE_COLORS_RANDOM;
+    modes.push_back(Wave);
+
+    mode Random;
+    Random.name                      = "Random";
+    Random.value                     = CLEVO8910_TYPE_RANDOM;
+    Random.flags                     = MODE_FLAG_MANUAL_SAVE |
+					MODE_FLAG_HAS_SPEED | 
+    					MODE_FLAG_HAS_BRIGHTNESS | 
+					MODE_FLAG_HAS_RANDOM_COLOR;
+    Random.speed_min                 = CLEVO8910_DIRECT_SPEED_MIN;
+    Random.speed_max                 = CLEVO8910_DIRECT_SPEED_MAX;
+    Random.brightness_min            = CLEVO8910_DIRECT_BRIGHTNESS_MIN;
+    Random.brightness_max            = CLEVO8910_DIRECT_BRIGHTNESS_MAX;
+    Random.speed                     = CLEVO8910_DIRECT_SPEED_DEFAULT;
+    Random.brightness                = CLEVO8910_DIRECT_BRIGHTNESS_DEFAULT;
+    Random.color_mode                = MODE_COLORS_RANDOM;
+    modes.push_back(Random);
+
+    mode Scan;
+    Scan.name                      = "Scan";
+    Scan.value                     = CLEVO8910_TYPE_SCAN;
+    Scan.flags                     = MODE_FLAG_MANUAL_SAVE |
+					MODE_FLAG_HAS_SPEED | 
+    					MODE_FLAG_HAS_BRIGHTNESS | 
+					MODE_FLAG_HAS_RANDOM_COLOR;
+    Scan.speed_min                 = CLEVO8910_DIRECT_SPEED_MIN;
+    Scan.speed_max                 = CLEVO8910_DIRECT_SPEED_MAX;
+    Scan.brightness_min            = CLEVO8910_DIRECT_BRIGHTNESS_MIN;
+    Scan.brightness_max            = CLEVO8910_DIRECT_BRIGHTNESS_MAX;
+    Scan.speed                     = CLEVO8910_DIRECT_SPEED_DEFAULT;
+    Scan.brightness                = CLEVO8910_DIRECT_BRIGHTNESS_DEFAULT;
+    Scan.color_mode                = MODE_COLORS_RANDOM;
+    modes.push_back(Scan);
+
+    mode Snake;
+    Snake.name                      = "Snake";
+    Snake.value                     = CLEVO8910_TYPE_SNAKE;
+    Snake.flags                     = MODE_FLAG_MANUAL_SAVE |
+					MODE_FLAG_HAS_SPEED | 
+    					MODE_FLAG_HAS_BRIGHTNESS | 
+					MODE_FLAG_HAS_RANDOM_COLOR;
+    Snake.speed_min                 = CLEVO8910_DIRECT_SPEED_MIN;
+    Snake.speed_max                 = CLEVO8910_DIRECT_SPEED_MAX;
+    Snake.brightness_min            = CLEVO8910_DIRECT_BRIGHTNESS_MIN;
+    Snake.brightness_max            = CLEVO8910_DIRECT_BRIGHTNESS_MAX;
+    Snake.speed                     = CLEVO8910_DIRECT_SPEED_DEFAULT;
+    Snake.brightness                = CLEVO8910_DIRECT_BRIGHTNESS_DEFAULT;
+    Snake.color_mode                = MODE_COLORS_RANDOM;
+    modes.push_back(Snake);
+
+    mode Off;
+    Off.name                      = "Off";
+    Off.value                     = CLEVO8910_TYPE_OFF;
+    Off.flags                     = 0;
+    modes.push_back(Off);
+
+    SetupZones();
+}
+
+RGBController_Clevo8910::~RGBController_Clevo8910()
+{
+    delete controller;
+}
+
+void RGBController_Clevo8910::SetupZones()
+{
+    
+    //colors.clear();
+
+    leds.clear();
+    leds.resize(CLEVO8910_KEYBOARD_LED_COUNT);
+    for(size_t i = 0; i < leds.size(); ++i)
+    {
+	leds[i].name = clevo8910_leds[i].name;
+	leds[i].value = clevo8910_leds[i].value;
+    }
+
+    matrix_map_type* new_zone_map 	     = new matrix_map_type;
+
+    zone zone_keyboard;
+    zone_keyboard.name       = "Clevo Keyboard";
+    zone_keyboard.type       = ZONE_TYPE_MATRIX;
+    zone_keyboard.name       = "Keyboard";
+    zone_keyboard.leds_min   = (unsigned int)leds.size();
+    zone_keyboard.leds_max   = (unsigned int)leds.size();
+    zone_keyboard.leds_count = (unsigned int)leds.size();
+    zone_keyboard.matrix_map = new_zone_map;
+    zone_keyboard.matrix_map->height	= CLEVO8910_KEYROWS;
+    zone_keyboard.matrix_map->width 	= CLEVO8910_KEYSINROW;
+    zone_keyboard.matrix_map->map 	= (unsigned int *)clevo8910_leds_map;
+    zones.emplace_back(zone_keyboard);
+
+    LOG_DEBUG("[Clevo Controller] detected: %s", description.c_str());
+
+
+    SetupColors();
+}
+
+void RGBController_Clevo8910::ResizeZone(int /*zone*/, int /*new_size*/)
+{
+    // This device does not support resizing zones               |
+}
+
+void RGBController_Clevo8910::DeviceUpdateLEDs()
+{
+    uint8_t effect = (uint8_t)(modes[active_mode].value & 0xFF);
+    controller->SetColors(effect, leds, false, colors);
+}
+
+void RGBController_Clevo8910::UpdateZoneLEDs(int /*zone*/)
+{
+    DeviceUpdateLEDs();  //Only one zone and same as device
+}
+
+void RGBController_Clevo8910::DeviceSaveMode()
+{
+	bool saveflg = (  modes[active_mode].value != CLEVO8910_MODE_FADE &&
+			modes[active_mode].value != CLEVO8910_MODE_RIPPLE );
+	
+    	controller->SaveBios(saveflg);
+}
+
+void RGBController_Clevo8910::UpdateSingleLED(int led)
+{
+    const RGBColor rndcolor = ToRGBColor(0, 0, 0);
+
+    if(led != (int)NA)
+    {
+	uint8_t effect = (uint8_t)(modes[active_mode].value & 0xFF);
+	/*
+	 * A hack is required for oneshot modes supported by the device
+	 * In these modes, the colour can be random but the OpenRGB does not
+	 * suport this. Instead, we can simulate the effect by using black which
+	 * otherwise would be a no-op.
+	 */
+	if (modes[active_mode].color_mode == MODE_COLORS_RANDOM)
+	{
+	    controller->SetSingleLED(effect, leds[led].value, rndcolor);
+	} else {
+	    controller->SetSingleLED(effect, leds[led].value, colors[led]);
+	}
+    }
+
+}
+
+void RGBController_Clevo8910::DeviceUpdateMode()
+{
+    uint8_t effect = (uint8_t)(modes[active_mode].value & 0xFF);
+    uint8_t key=0xAA;
+    switch (modes[active_mode].value)
+    {
+    case CLEVO8910_TYPE_OFF:
+        controller->TurnOff();
+        break;
+    case CLEVO8910_MODE_RIPPLE:
+    case CLEVO8910_MODE_FADE:
+    case CLEVO8910_MODE_DIRECT:
+	controller->setparams((uint8_t)modes[active_mode].brightness,
+			    (uint8_t)modes[active_mode].speed);
+	if  (modes[active_mode].color_mode == MODE_COLORS_RANDOM)
+	    controller->SetColors(effect, leds, true, colors);
+        break;
+
+    case CLEVO8910_TYPE_COLOURS:
+    case CLEVO8910_TYPE_CYCLE:
+    case CLEVO8910_TYPE_STOP:
+    case CLEVO8910_TYPE_NOOP:
+    case CLEVO8910_TYPE_WAVE:
+    case CLEVO8910_TYPE_RANDOM:
+    case CLEVO8910_TYPE_SCAN:
+    case CLEVO8910_TYPE_SNAKE:
+    	controller->SetSimpleMode(effect, (uint8_t)modes[active_mode].brightness, (uint8_t)modes[active_mode].speed);
+	break;
+
+    case CLEVO8910_MODE_BREATHE:
+    case CLEVO8910_MODE_BLINK:
+	key = (modes[active_mode].color_mode == MODE_COLORS_RANDOM) ? 0 : 0xAA;
+        controller->SetMode( effect, (uint8_t)modes[active_mode].brightness,
+	(uint8_t)modes[active_mode].speed, 
+	key,
+	modes[active_mode].colors[0] );
+	break;
+
+    default:
+	controller->setparams((uint8_t)modes[active_mode].brightness,
+			    (uint8_t)modes[active_mode].speed);
+//	controller->SetColors(effect, leds, false, colors);
+        break;
+    }
+}
Index: OpenRGB-1.0~rc2+git32.gda9a96e3/Controllers/Clevo8910/RGBController_Clevo8910.h
===================================================================
--- /dev/null
+++ OpenRGB-1.0~rc2+git32.gda9a96e3/Controllers/Clevo8910/RGBController_Clevo8910.h
@@ -0,0 +1,38 @@
+
+/*
+ *  RGBController_Clevo8910.h
+ *
+ *    RGBController for Clevo RGB colour per key keyboard
+ *    
+ *    Ezy  9 Jan 202r65
+ *                                                            |
+ *    This file is part of the OpenRGB project
+ *    SPDX-License-Identifier: GPL-2.0-or-later
+ */
+
+#pragma once
+
+#include "RGBController.h"
+#include "Clevo8910Controller.h"
+
+
+class RGBController_Clevo8910 : public RGBController
+{
+public:
+    RGBController_Clevo8910(Clevo8910Controller* controller_ptr);
+    ~RGBController_Clevo8910();
+
+    void SetupZones();
+    void ResizeZone(int zone, int new_size);
+
+    void DeviceUpdateLEDs();
+    void UpdateZoneLEDs(int zone);
+    void UpdateSingleLED(int led);
+
+    void DeviceUpdateMode();
+    void DeviceSaveMode();
+
+
+private:
+    Clevo8910Controller* controller;
+};
openSUSE Build Service is sponsored by