File add-MM731-rebased.patch of Package OpenRGB

From a8d4d7f287e5597708fd81ca6af73bc56e5bc3bd Mon Sep 17 00:00:00 2001
From: nomeat <nomeat@users.noreply.gitlab.com>
Date: Wed, 10 Dec 2025 23:52:48 +0000
Subject: [PATCH] Initial commit for Coolermaster MM731 & MM731 V2
 (7d2f0b6a71cfd71d28b0680d78631c8538840cf1)

+ Adding PIDs and detection block
+ Added RGBController_CMMM731Controller
+ Added CMMM731Controller
+ Adjusted CoolerMasterControllerDetect with Linux encoded LF

Fix branch for current OpenRGB
 + Update Usage and Interface values to fix detection
 + Move controller files to named folder
---
 .../CMMM731Controller/CMMM731Controller.cpp   | 209 +++++
 .../CMMM731Controller/CMMM731Controller.h     | 101 +++
 .../RGBController_CMMM731Controller.cpp       | 187 +++++
 .../RGBController_CMMM731Controller.h         |  40 +
 .../CoolerMasterControllerDetect.cpp          | 786 +++++++++---------
 5 files changed, 940 insertions(+), 383 deletions(-)
 create mode 100644 Controllers/CoolerMasterController/CMMM731Controller/CMMM731Controller.cpp
 create mode 100644 Controllers/CoolerMasterController/CMMM731Controller/CMMM731Controller.h
 create mode 100644 Controllers/CoolerMasterController/CMMM731Controller/RGBController_CMMM731Controller.cpp
 create mode 100644 Controllers/CoolerMasterController/CMMM731Controller/RGBController_CMMM731Controller.h

diff --git a/Controllers/CoolerMasterController/CMMM731Controller/CMMM731Controller.cpp b/Controllers/CoolerMasterController/CMMM731Controller/CMMM731Controller.cpp
new file mode 100644
index 0000000000..844a55bdca
--- /dev/null
+++ b/Controllers/CoolerMasterController/CMMM731Controller/CMMM731Controller.cpp
@@ -0,0 +1,209 @@
+/*-------------------------------------------------------------------*\
+| CMMM731Controller.cpp                                               |
+|                                                                     |
+|   Driver for the Cooler Master MM731 Mouse                          |
+|                                                                     |
+|   Chris M (Dr_No)                              1 Jan 2022           |
+|                                                                     |
+|   This file is part of the OpenRGB project                          |
+|   SPDX-License-Identifier: GPL-2.0-only                             |
+\*-------------------------------------------------------------------*/
+
+#include <cstring>
+#include "CMMM731Controller.h"
+#include "StringUtils.h"
+
+CMMM731Controller::CMMM731Controller(hid_device* dev_handle, char *_path)
+{
+    dev                 = dev_handle;
+    location            = _path;
+    current_speed       = CM_MM731_SPEED_NORMAL;
+
+    /*---------------------------------------------------------*\
+    | Get device name from HID manufacturer and product strings |
+    \*---------------------------------------------------------*/
+    wchar_t name_string[HID_MAX_STR];
+
+    hid_get_manufacturer_string(dev, name_string, HID_MAX_STR);
+    device_name = StringUtils::wstring_to_string(name_string);
+
+    hid_get_product_string(dev, name_string, HID_MAX_STR);
+    device_name.append(" ").append(StringUtils::wstring_to_string(name_string));
+
+    hid_get_indexed_string(dev, 2, name_string, HID_MAX_STR);
+    serial = StringUtils::wstring_to_string(name_string);
+
+    SendInitPacket();
+}
+
+CMMM731Controller::~CMMM731Controller()
+{
+    hid_close(dev);
+}
+
+/*void CMMM731Controller::GetColourStatus()
+{
+    uint8_t buffer[CM_MM731_PACKET_SIZE]    = { 0x00, 0x52, 0x2B };
+
+    hid_write(dev, buffer, CM_MM731_PACKET_SIZE);
+    hid_read_timeout(dev, buffer, CM_MM731_PACKET_SIZE, CM_MM731_INTERRUPT_TIMEOUT);
+
+    current_brightness      = buffer[CM_MM731_BRIGHTNESS_BYTE - 1];
+    current_red             = buffer[CM_MM731_RED_BYTE - 1];
+    current_green           = buffer[CM_MM731_GREEN_BYTE - 1];
+    current_blue            = buffer[CM_MM731_BLUE_BYTE - 1];
+}*/
+
+/*void CMMM731Controller::GetCustomStatus()
+{
+    uint8_t buffer[CM_MM731_PACKET_SIZE]    = { 0x00, 0x52, 0xA8 };
+    int read_size                           = CM_MM731_PACKET_SIZE - 1;
+    int result                              = 0;
+
+    hid_write(dev, buffer, CM_MM711_PACKET_SIZE);
+    do
+    {
+        result = hid_read_timeout(dev, buffer, read_size, CM_MM731_INTERRUPT_TIMEOUT);
+    }while(buffer[1] != 0xA8 && result == read_size);
+
+    if(result == read_size)
+    {
+        wheel_colour            = ToRGBColor(buffer[4], buffer[5], buffer[6]);
+        logo_colour             = ToRGBColor(buffer[7], buffer[8], buffer[9]);
+    }
+}*/
+
+std::string CMMM731Controller::GetDeviceName()
+{
+    return device_name;
+}
+
+std::string CMMM731Controller::GetSerial()
+{
+    return(serial);
+}
+
+std::string CMMM731Controller::GetLocation()
+{
+    return("HID: " + location);
+}
+
+uint8_t CMMM731Controller::GetMode()
+{
+    return(current_mode);
+}
+
+uint8_t CMMM731Controller::GetLedRed()
+{
+    return(current_red);
+}
+
+uint8_t CMMM731Controller::GetLedGreen()
+{
+    return(current_green);
+}
+
+uint8_t CMMM731Controller::GetLedBlue()
+{
+    return(current_blue);
+}
+
+uint8_t CMMM731Controller::GetLedSpeed()
+{
+    return(current_speed);
+}
+
+uint8_t CMMM731Controller::GetBrightness()
+{
+    return(current_brightness);
+}
+
+bool CMMM731Controller::GetRandomColours()
+{
+    return(bool_random);
+}
+
+void CMMM731Controller::SetMode(uint8_t mode, uint8_t speed, uint8_t brightness, RGBColor colour, bool random_colours)
+{
+    bool needs_update       = !( (current_mode == mode) && (current_speed == speed) && (current_brightness == brightness) && (ToRGBColor(current_red, current_green, current_blue) == colour));
+
+    if (needs_update)
+    {
+        current_mode        = mode;
+        current_speed       = speed;
+        current_brightness  = brightness;
+        current_red         = RGBGetRValue(colour);
+        current_green       = RGBGetGValue(colour);
+        current_blue        = RGBGetBValue(colour);
+        bool_random         = random_colours;
+        SendUpdate();
+    }
+}
+
+void  CMMM731Controller::SetLedsDirect(RGBColor logo_colour)
+{
+    uint8_t buffer[CM_MM731_PACKET_SIZE]    = { 0x00, 0x4C, 0x81, 0x04, CM_MM731_MODE_STATIC, CM_MM731_BRIGHTNESS_MAX, CM_MM731_BRIGHTNESS_MAX, CM_MM731_SPEED_NORMAL };
+
+    buffer[CM_MM731_RED_BYTE]               = RGBGetRValue(logo_colour);
+    buffer[CM_MM731_GREEN_BYTE]             = RGBGetGValue(logo_colour);
+    buffer[CM_MM731_BLUE_BYTE]              = RGBGetBValue(logo_colour);
+    buffer[CM_MM731_NFI_2]                  = CM_MM731_BRIGHTNESS_MAX;
+
+    hid_write(dev, buffer, CM_MM731_PACKET_SIZE);
+    hid_read_timeout(dev, buffer, CM_MM731_PACKET_SIZE, CM_MM731_INTERRUPT_TIMEOUT);
+}
+
+void CMMM731Controller::GetStatus()
+{
+    uint8_t buffer[CM_MM731_PACKET_SIZE]    = { 0x00, 0x52, 0x28 };
+
+    hid_write(dev, buffer, CM_MM731_PACKET_SIZE);
+    hid_read_timeout(dev, buffer, CM_MM731_PACKET_SIZE, CM_MM731_INTERRUPT_TIMEOUT);
+
+    current_mode                            = buffer[CM_MM731_MODE_BYTE - 1];
+}
+
+void CMMM731Controller::SendUpdate()
+{
+    uint8_t buffer[CM_MM731_PACKET_SIZE]    = { 0x00, 0x4C, 0x81, 0x04 };
+
+    buffer[CM_MM731_MODE_BYTE]              = current_mode;
+    buffer[CM_MM731_NFI_1]                  = CM_MM731_BRIGHTNESS_MAX;
+    buffer[CM_MM731_BRIGHTNESS_BYTE]        = current_brightness;
+    buffer[CM_MM731_SPEED_BYTE]             = current_speed;
+    buffer[CM_MM731_RED_BYTE]               = current_red;
+    buffer[CM_MM731_GREEN_BYTE]             = current_green;
+    buffer[CM_MM731_BLUE_BYTE]              = current_blue;
+    buffer[CM_MM731_NFI_2]                  = CM_MM731_BRIGHTNESS_MAX;
+
+    hid_write(dev, buffer, CM_MM731_PACKET_SIZE);
+    hid_read_timeout(dev, buffer, CM_MM731_PACKET_SIZE, CM_MM731_INTERRUPT_TIMEOUT);
+
+    SendApplyPacket();
+}
+
+void CMMM731Controller::SendApplyPacket()
+{
+    uint8_t buffer[CM_MM731_PACKET_SIZE]    = { 0x00, 0x4C, 0x81, 0x08, current_mode };
+
+    hid_write(dev, buffer, CM_MM731_PACKET_SIZE);
+    hid_read_timeout(dev, buffer, CM_MM731_PACKET_SIZE, CM_MM731_INTERRUPT_TIMEOUT);
+}
+
+void CMMM731Controller::SendInitPacket()
+{
+    uint8_t buffer[CM_MM731_PACKET_SIZE]    = { 0x00, 0x44, 0x81, 0x02 };
+
+    hid_write(dev, buffer, CM_MM731_PACKET_SIZE);
+    hid_read_timeout(dev, buffer, CM_MM731_PACKET_SIZE, CM_MM731_INTERRUPT_TIMEOUT);
+
+}
+
+void CMMM731Controller::SendSavePacket()
+{
+    uint8_t buffer[CM_MM731_PACKET_SIZE]    = { 0x00, 0x54, 0x81, 0x01 };
+
+    hid_write(dev, buffer, CM_MM731_PACKET_SIZE);
+    hid_read_timeout(dev, buffer, CM_MM731_PACKET_SIZE, CM_MM731_INTERRUPT_TIMEOUT);
+}
+
diff --git a/Controllers/CoolerMasterController/CMMM731Controller/CMMM731Controller.h b/Controllers/CoolerMasterController/CMMM731Controller/CMMM731Controller.h
new file mode 100644
index 0000000000..7a43b46839
--- /dev/null
+++ b/Controllers/CoolerMasterController/CMMM731Controller/CMMM731Controller.h
@@ -0,0 +1,101 @@
+/*-------------------------------------------------------------------*\
+| CMMM731Controller.h                                                 |
+|                                                                     |
+|   Driver for the Cooler Master MM731 Mouse                          |
+|                                                                     |
+|   Chris M (Dr_No)                              1 Jan 2022           |
+|                                                                     |
+|   This file is part of the OpenRGB project                          |
+|   SPDX-License-Identifier: GPL-2.0-only                             |
+\*-------------------------------------------------------------------*/
+
+#include <string>
+#include <hidapi.h>
+#include "RGBController.h"
+
+#pragma once
+
+#define CM_MM731_INTERRUPT_TIMEOUT  250
+#define CM_MM731_PACKET_SIZE        65
+#define CM_MM731_BRIGHTNESS_MIN     0
+#define CM_MM731_BRIGHTNESS_MAX     255
+#define HID_MAX_STR 255
+
+enum
+{
+    CM_MM731_MODE_STATIC            = 0x00, //Static Mode - Set entire zone to a single color.
+    CM_MM731_MODE_BREATHING         = 0x01, //Breathing Mode - Fades between fully off and fully on.
+    CM_MM731_MODE_SPECTRUM          = 0x02, //Spectrum Cycle Mode - Cycles through the color spectrum on all lights on the device
+    CM_MM731_MODE_OFF               = 0x03, //Turn off - All leds off
+};
+
+enum
+{
+    CM_MM731_REPORT_BYTE            = 1,
+    CM_MM731_COMMAND_BYTE           = 2,
+    CM_MM731_FUNCTION_BYTE          = 3,
+    CM_MM731_MODE_BYTE              = 4,
+    CM_MM731_NFI_1                  = 5,
+    CM_MM731_BRIGHTNESS_BYTE        = 6,
+    CM_MM731_SPEED_BYTE             = 7,
+    CM_MM731_RED_BYTE               = 8,
+    CM_MM731_GREEN_BYTE             = 9,
+    CM_MM731_BLUE_BYTE              = 10,
+    CM_MM731_NFI_2                  = 11,
+};
+
+enum
+{
+    CM_MM731_SPEED_SLOWEST          = 0x00, // Slowest speed
+    CM_MM731_SPEED_SLOW             = 0x01, // Slower speed
+    CM_MM731_SPEED_NORMAL           = 0x02, // Normal speed
+    CM_MM731_SPEED_FAST             = 0x03, // Fast speed
+    CM_MM731_SPEED_FASTEST          = 0x04, // Fastest speed
+};
+
+class CMMM731Controller
+{
+public:
+    CMMM731Controller(hid_device* dev_handle, char *_path);
+    ~CMMM731Controller();
+
+    std::string     GetDeviceName();
+    std::string     GetSerial();
+    std::string     GetLocation();
+
+    uint8_t         GetMode();
+    uint8_t         GetLedSpeed();
+
+    uint8_t         GetLedRed();
+    uint8_t         GetLedGreen();
+    uint8_t         GetLedBlue();
+    uint8_t         GetBrightness();
+    bool            GetRandomColours();
+
+    void            SetMode(uint8_t mode, uint8_t speed, uint8_t brightness, RGBColor colour, bool random_colours);
+    void            SetLedsDirect(RGBColor logo_colour);
+    void            SendSavePacket();
+private:
+    std::string     device_name;
+    std::string     serial;
+    std::string     location;
+    hid_device*     dev;
+
+    uint8_t         zone_index;
+    uint8_t         current_mode;
+    uint8_t         current_speed;
+
+    uint8_t         current_red;
+    uint8_t         current_green;
+    uint8_t         current_blue;
+    uint8_t         current_brightness;
+    bool            bool_random;
+
+    void            GetStatus();
+    void            SendUpdate();
+
+    //void        GetColourStatus();
+    //void        GetCustomStatus();
+    void            SendInitPacket();
+    void            SendApplyPacket();
+};
diff --git a/Controllers/CoolerMasterController/CMMM731Controller/RGBController_CMMM731Controller.cpp b/Controllers/CoolerMasterController/CMMM731Controller/RGBController_CMMM731Controller.cpp
new file mode 100644
index 0000000000..146e7cc4b5
--- /dev/null
+++ b/Controllers/CoolerMasterController/CMMM731Controller/RGBController_CMMM731Controller.cpp
@@ -0,0 +1,187 @@
+/*-------------------------------------------------------------------*\
+| RGBController_CMMM731Controller.cpp                                 |
+|                                                                     |
+|   Driver for the Cooler Master MM731 Mouse                          |
+|                                                                     |
+|   Chris M (Dr_No)                              1 Jan 2022           |
+|                                                                     |
+|   This file is part of the OpenRGB project                          |
+|   SPDX-License-Identifier: GPL-2.0-only                             |
+\*-------------------------------------------------------------------*/
+
+#include "RGBController_CMMM731Controller.h"
+
+/**------------------------------------------------------------------*\
+    @name Coolermaster Master Mouse 731
+    @category Mouse
+    @type USB
+    @save :white_check_mark:
+    @direct :white_check_mark:
+    @effects :white_check_mark:
+    @detectors DetectCoolerMasterMouse
+    @comment
+\*-------------------------------------------------------------------*/
+
+RGBController_CMMM731Controller::RGBController_CMMM731Controller(CMMM731Controller *controller_ptr)
+{
+    controller                  = controller_ptr;
+    uint8_t speed               = controller->GetLedSpeed();
+
+    name                        = controller->GetDeviceName();
+    vendor                      = "Cooler Master";
+    type                        = DEVICE_TYPE_MOUSE;
+    description                 = controller->GetDeviceName();
+    version                     = "1.0";
+    serial                      = controller->GetSerial();
+    location                    = controller->GetLocation();
+
+    mode Direct;
+    Direct.name                 = "Direct";
+    Direct.value                = CM_MM731_MODE_STATIC; //Direct is Static that does not send a save packet
+    Direct.flags                = MODE_FLAG_HAS_PER_LED_COLOR;
+    Direct.color_mode           = MODE_COLORS_PER_LED;
+    modes.push_back(Direct);
+
+    mode Static;
+    Static.name                 = "Static";
+    Static.value                = CM_MM731_MODE_STATIC;
+    Static.flags                = MODE_FLAG_HAS_MODE_SPECIFIC_COLOR | MODE_FLAG_HAS_BRIGHTNESS | MODE_FLAG_MANUAL_SAVE;
+    Static.colors_min           = 1;
+    Static.colors_max           = 1;
+    Static.colors.resize(Static.colors_max);
+    Static.brightness_min       = CM_MM731_BRIGHTNESS_MIN;
+    Static.brightness_max       = CM_MM731_BRIGHTNESS_MAX;
+    Static.brightness           = CM_MM731_BRIGHTNESS_MAX;
+    Static.speed_min            = CM_MM731_SPEED_SLOWEST;
+    Static.speed_max            = CM_MM731_SPEED_FASTEST;
+    Static.color_mode           = MODE_COLORS_MODE_SPECIFIC;
+    Static.speed                = speed;
+    modes.push_back(Static);
+
+    mode Breathing;
+    Breathing.name              = "Breathing";
+    Breathing.value             = CM_MM731_MODE_BREATHING;
+    Breathing.flags             = MODE_FLAG_HAS_SPEED | MODE_FLAG_HAS_MODE_SPECIFIC_COLOR | MODE_FLAG_HAS_RANDOM_COLOR | MODE_FLAG_HAS_BRIGHTNESS | MODE_FLAG_MANUAL_SAVE;
+    Breathing.colors_min        = 1;
+    Breathing.colors_max        = 1;
+    Breathing.colors.resize(Breathing.colors_max);
+    Breathing.brightness_min    = CM_MM731_BRIGHTNESS_MIN;
+    Breathing.brightness_max    = CM_MM731_BRIGHTNESS_MAX;
+    Breathing.brightness        = CM_MM731_BRIGHTNESS_MAX;
+    Breathing.speed_min         = CM_MM731_SPEED_SLOWEST;
+    Breathing.speed_max         = CM_MM731_SPEED_FASTEST;
+    Breathing.color_mode        = MODE_COLORS_MODE_SPECIFIC;
+    Breathing.speed             = speed;
+    modes.push_back(Breathing);
+
+
+    mode Spectrum;
+    Spectrum.name               = "Spectrum";
+    Spectrum.value              = CM_MM731_MODE_SPECTRUM;
+    Spectrum.flags              = MODE_FLAG_HAS_SPEED | MODE_FLAG_HAS_BRIGHTNESS | MODE_FLAG_MANUAL_SAVE;
+    Spectrum.brightness_min     = CM_MM731_BRIGHTNESS_MIN;
+    Spectrum.brightness_max     = CM_MM731_BRIGHTNESS_MAX;
+    Spectrum.brightness         = CM_MM731_BRIGHTNESS_MAX;
+    Spectrum.speed_min          = CM_MM731_SPEED_SLOWEST;
+    Spectrum.speed_max          = CM_MM731_SPEED_FASTEST;
+    Spectrum.color_mode         = MODE_COLORS_NONE;
+    Spectrum.speed              = speed;
+    modes.push_back(Spectrum);
+
+    mode Off;
+    Off.name                    = "Turn Off";
+    Off.value                   = CM_MM731_MODE_OFF;
+    Off.flags                   = MODE_FLAG_MANUAL_SAVE;
+    Off.color_mode              = MODE_COLORS_NONE;
+    modes.push_back(Off);
+
+    Init_Controller();
+    SetupZones();
+
+    /*int temp_mode               = controller->GetMode();
+    for(std::size_t mode_idx = 0; mode_idx < modes.size() ; mode_idx++)
+    {
+        if (temp_mode == modes[mode_idx].value)
+        {
+            active_mode = mode_idx;
+            break;
+        }
+    }
+    if (modes[active_mode].flags & MODE_FLAG_HAS_MODE_SPECIFIC_COLOR)
+    {
+        modes[active_mode].colors[0] = ToRGBColor(cmargb->GetLedRed(), cmargb->GetLedGreen(), cmargb->GetLedBlue());
+        modes[active_mode].color_mode = (cmargb->GetRandomColours()) ? MODE_COLORS_RANDOM : MODE_COLORS_MODE_SPECIFIC;
+    }
+    if (modes[active_mode].flags & MODE_FLAG_HAS_SPEED)
+    {
+        modes[active_mode].speed = cmargb->GetLedSpeed();
+    }*/
+}
+
+RGBController_CMMM731Controller::~RGBController_CMMM731Controller()
+{
+    delete controller;
+}
+
+void RGBController_CMMM731Controller::Init_Controller()
+{
+    zone mouse_zone;
+    mouse_zone.name         = name;
+    mouse_zone.type         = ZONE_TYPE_SINGLE;
+    mouse_zone.leds_min     = 1;
+    mouse_zone.leds_max     = 1;
+    mouse_zone.leds_count   = 1;
+    mouse_zone.matrix_map   = NULL;
+    zones.push_back(mouse_zone);
+
+    led logo_led;
+    logo_led.name           = "Logo LED";
+    logo_led.value          = 1;
+    leds.push_back(logo_led);
+}
+
+void RGBController_CMMM731Controller::SetupZones()
+{
+    SetupColors();
+}
+
+void RGBController_CMMM731Controller::ResizeZone(int /*zone*/, int /*new_size*/)
+{
+    /*---------------------------------------------------------*\
+    | This device does not support resizing zones               |
+    \*---------------------------------------------------------*/
+}
+
+void RGBController_CMMM731Controller::DeviceUpdateLEDs()
+{
+    controller->SetLedsDirect( colors[0] );
+}
+
+void RGBController_CMMM731Controller::UpdateZoneLEDs(int /*zone*/)
+{
+    controller->SetLedsDirect( colors[0] );
+}
+
+void RGBController_CMMM731Controller::UpdateSingleLED(int /*led*/)
+{
+    controller->SetLedsDirect( colors[0] );
+}
+
+void RGBController_CMMM731Controller::SetCustomMode()
+{
+    active_mode             = 0;
+}
+
+void RGBController_CMMM731Controller::DeviceUpdateMode()
+{
+    bool random_colours     = (modes[active_mode].color_mode == MODE_COLORS_RANDOM);
+    RGBColor colour         = (modes[active_mode].color_mode == MODE_COLORS_MODE_SPECIFIC) ? modes[active_mode].colors[0] : 0;
+
+    controller->SetMode( modes[active_mode].value, modes[active_mode].speed, modes[active_mode].brightness, colour, random_colours );
+}
+
+void RGBController_CMMM731Controller::DeviceSaveMode()
+{
+    DeviceUpdateMode();
+    controller->SendSavePacket();
+}
diff --git a/Controllers/CoolerMasterController/CMMM731Controller/RGBController_CMMM731Controller.h b/Controllers/CoolerMasterController/CMMM731Controller/RGBController_CMMM731Controller.h
new file mode 100644
index 0000000000..dc2981b199
--- /dev/null
+++ b/Controllers/CoolerMasterController/CMMM731Controller/RGBController_CMMM731Controller.h
@@ -0,0 +1,40 @@
+/*-------------------------------------------------------------------*\
+| RGBController_CMMM731Controller.h                                   |
+|                                                                     |
+|   Driver for the Cooler Master MM731 Mouse                          |
+|                                                                     |
+|   Chris M (Dr_No)                              1 Jan 2022           |
+|                                                                     |
+|   This file is part of the OpenRGB project                          |
+|   SPDX-License-Identifier: GPL-2.0-only                             |
+\*-------------------------------------------------------------------*/
+
+#pragma once
+#include "RGBController.h"
+#include "CMMM731Controller.h"
+#include <vector>
+
+class RGBController_CMMM731Controller : public RGBController
+{
+public:
+    RGBController_CMMM731Controller(CMMM731Controller *controller_ptr);
+    ~RGBController_CMMM731Controller();
+
+    void        SetupZones();
+    void        ResizeZone(int zone, int new_size);
+
+    void        DeviceUpdateLEDs();
+    void        UpdateZoneLEDs(int zone);
+    void        UpdateSingleLED(int led);
+
+    void        SetCustomMode();
+    void        DeviceUpdateMode();
+    void        DeviceSaveMode();
+
+private:
+    void        Init_Controller();
+    int         GetDeviceMode();
+    int         GetLED_Zone(int led_idx);
+
+    CMMM731Controller* controller;
+};
diff --git a/Controllers/CoolerMasterController/CoolerMasterControllerDetect.cpp b/Controllers/CoolerMasterController/CoolerMasterControllerDetect.cpp
index c4e14c937a..0c0f3e0602 100644
--- a/Controllers/CoolerMasterController/CoolerMasterControllerDetect.cpp
+++ b/Controllers/CoolerMasterController/CoolerMasterControllerDetect.cpp
@@ -1,383 +1,403 @@
-/*---------------------------------------------------------*\
-| CoolerMasterControllerDetect.cpp                          |
-|                                                           |
-|   Detector for Cooler Master devices                      |
-|                                                           |
-|   This file is part of the OpenRGB project                |
-|   SPDX-License-Identifier: GPL-2.0-or-later               |
-\*---------------------------------------------------------*/
-
-/*-----------------------------------------------------*\
-| OpenRGB includes                                      |
-\*-----------------------------------------------------*/
-#include <hidapi.h>
-#include "Detector.h"
-#include "LogManager.h"
-
-/*-----------------------------------------------------*\
-| Coolermaster specific includes                        |
-\*-----------------------------------------------------*/
-#include "RGBController_CMMMController.h"
-#include "RGBController_CMMM711Controller.h"
-#include "RGBController_CMMM712Controller.h"
-#include "RGBController_CMMP750Controller.h"
-#include "RGBController_CMARGBController.h"
-#include "RGBController_CMSmallARGBController.h"
-#include "RGBController_CMARGBGen2A1Controller.h"
-#include "RGBController_CMRGBController.h"
-#include "RGBController_CMR6000Controller.h"
-#include "RGBController_CMMonitorController.h"
-#include "RGBController_CMGD160Controller.h"
-#include "RGBController_CMKeyboardController.h"
-
-/*-----------------------------------------------------*\
-| Coolermaster USB vendor ID                            |
-\*-----------------------------------------------------*/
-#define COOLERMASTER_VID                            0x2516
-
-/*-----------------------------------------------------*\
-| Coolermaster Keyboards                                |
-|   PIDs defined in `CMMKControllerV2.h`                |
-\*-----------------------------------------------------*/
-
-/*-----------------------------------------------------*\
-| Coolermaster GPUs                                     |
-|   PIDs defined in `CMR6000Controller.h`               |
-\*-----------------------------------------------------*/
-
-/*-----------------------------------------------------*\
-| Coolermaster LEDstrip controllers                     |
-\*-----------------------------------------------------*/
-#define COOLERMASTER_ARGB_PID                       0x1011
-#define COOLERMASTER_ARGB_GEN2_A1_PID               0x0173
-#define COOLERMASTER_ARGB_GEN2_A1_V2_PID            0x01C9
-#define COOLERMASTER_ARGB_GEN2_A1_MINI_PID          0x01CB
-#define COOLERMASTER_SMALL_ARGB_PID                 0x1000
-#define COOLERMASTER_RGB_PID                        0x004F
-
-/*-----------------------------------------------------*\
-| Coolermaster Mice                                     |
-\*-----------------------------------------------------*/
-#define COOLERMASTER_MM530_PID                      0x0065
-#define COOLERMASTER_MM531_PID                      0x0097
-#define COOLERMASTER_MM711_PID                      0x0101
-#define COOLERMASTER_MM712_PID                      0x0169
-#define COOLERMASTER_MM720_PID                      0x0141
-#define COOLERMASTER_MM730_PID                      0x0165
-
-/*-----------------------------------------------------*\
-| Coolermaster Mousemats                                |
-\*-----------------------------------------------------*/
-#define COOLERMASTER_MP750_XL_PID                   0x0109
-#define COOLERMASTER_MP750_L_PID                    0x0107
-#define COOLERMASTER_MP750_MEDIUM_PID               0x0105
-
-/*-----------------------------------------------------*\
-| Coolermaster Monitors                                 |
-\*-----------------------------------------------------*/
-#define COOLERMASTER_GM27_FQS_PID                   0x01BB
-
-/*-----------------------------------------------------*\
-| Coolermaster Desks                                    |
-\*-----------------------------------------------------*/
-#define COOLERMASTER_GD160_PID                      0x01A9
-
-/******************************************************************************************\
-*                                                                                          *
-*   DetectCoolerMasterControllers                                                          *
-*                                                                                          *
-*       Tests the USB address to see if any CoolerMaster controllers exists there.         *
-*                                                                                          *
-\******************************************************************************************/
-
-void DetectCoolerMasterARGB(hid_device_info* info, const std::string&)
-{
-    hid_device* dev = hid_open_path(info->path);
-
-    if(dev)
-    {
-        /*-------------------------------------------------*\
-        | Create mutex to prevent the controllers sharing a |
-        |   receiver from interfering with each other       |
-        \*-------------------------------------------------*/
-        std::shared_ptr<std::mutex>       cm_mutex = std::make_shared<std::mutex>();
-
-        for(unsigned char i = 0; i < CM_ARGB_HEADER_DATA_SIZE; i++)
-        {
-            CMARGBController*               controller     = new CMARGBController(dev, info->path, i, cm_mutex);
-            RGBController_CMARGBController* rgb_controller = new RGBController_CMARGBController(controller);
-
-            ResourceManager::get()->RegisterRGBController(rgb_controller);
-        }
-    }
-}
-
-void DetectCoolerMasterARGBGen2A1(hid_device_info* info, const std::string& name)
-{
-    hid_device* dev = hid_open_path(info->path);
-
-    if(dev)
-    {
-        CMARGBGen2A1controller*               controller     = new CMARGBGen2A1controller(dev, *info, name);
-        RGBController_CMARGBGen2A1Controller* rgb_controller = new RGBController_CMARGBGen2A1Controller(controller);
-
-        ResourceManager::get()->RegisterRGBController(rgb_controller);
-    }
-}
-
-void DetectCoolerMasterGPU(hid_device_info* info, const std::string&)
-{
-    hid_device* dev = hid_open_path(info->path);
-
-    if(dev)
-    {
-        CMR6000Controller*               controller     = new CMR6000Controller(dev, info->path, info->product_id);
-        RGBController_CMR6000Controller* rgb_controller = new RGBController_CMR6000Controller(controller);
-
-        ResourceManager::get()->RegisterRGBController(rgb_controller);
-    }
-}
-
-void DetectCoolerMasterV1Keyboards(hid_device_info* info, const std::string& name)
-{
-    hid_device* dev = hid_open_path(info->path);
-
-    if(dev)
-    {
-        switch(info->product_id)
-        {
-            case COOLERMASTER_KEYBOARD_PRO_L_PID:
-            case COOLERMASTER_KEYBOARD_PRO_L_WHITE_PID:
-            case COOLERMASTER_KEYBOARD_PRO_S_PID:
-            {
-                CMKeyboardV1Controller*             controller     = new CMKeyboardV1Controller(dev, info, name);
-                RGBController_CMKeyboardController* rgb_controller = new RGBController_CMKeyboardController(controller);
-
-                ResourceManager::get()->RegisterRGBController(rgb_controller);
-            }
-            break;
-
-            default:
-                LOG_DEBUG("[%s] Controller not created as the product ID %04X is missing from detector switch", name.c_str(), info->product_id);
-            break;
-        }
-    }
-}
-
-void DetectCoolerMasterV2Keyboards(hid_device_info* info, const std::string& name)
-{
-    hid_device* dev = hid_open_path(info->path);
-
-    if(dev)
-    {
-        switch(info->product_id)
-        {
-            case COOLERMASTER_KEYBOARD_PRO_L_PID:
-            case COOLERMASTER_KEYBOARD_PRO_L_WHITE_PID:
-            case COOLERMASTER_KEYBOARD_PRO_S_PID:
-            {
-                CMKeyboardV1Controller*             controller     = new CMKeyboardV1Controller(dev, info, name);
-                RGBController_CMKeyboardController* rgb_controller = new RGBController_CMKeyboardController(controller);
-
-                ResourceManager::get()->RegisterRGBController(rgb_controller);
-            }
-            break;
-
-            case COOLERMASTER_KEYBOARD_SK622B_PID:
-            case COOLERMASTER_KEYBOARD_SK622W_PID:
-            case COOLERMASTER_KEYBOARD_SK630_PID:
-            case COOLERMASTER_KEYBOARD_SK650_PID:
-            case COOLERMASTER_KEYBOARD_SK652_PID:
-            case COOLERMASTER_KEYBOARD_SK653_PID:
-            case COOLERMASTER_KEYBOARD_CK530_PID:
-            case COOLERMASTER_KEYBOARD_CK530_V2_PID:
-            case COOLERMASTER_KEYBOARD_CK550_V2_PID:
-            case COOLERMASTER_KEYBOARD_CK552_V2_PID:
-            case COOLERMASTER_KEYBOARD_MK730_PID:
-            case COOLERMASTER_KEYBOARD_MK750_PID:
-            {
-                CMKeyboardV2Controller*             controller     = new CMKeyboardV2Controller(dev, info, name);
-                RGBController_CMKeyboardController* rgb_controller = new RGBController_CMKeyboardController(controller);
-
-                ResourceManager::get()->RegisterRGBController(rgb_controller);
-            }
-            break;
-
-            default:
-                LOG_DEBUG("[%s] Controller not created as the product ID %04X is missing from detector switch", name.c_str(), info->product_id);
-            break;
-        }
-    }
-}
-
-void DetectCoolerMasterMouse(hid_device_info* info, const std::string& name)
-{
-    hid_device* dev = hid_open_path(info->path);
-
-    if(dev)
-    {
-        CMMMController*               controller        = new CMMMController(dev, info->path, info->product_id, name);
-        RGBController_CMMMController* rgb_controller    = new RGBController_CMMMController(controller);
-
-        ResourceManager::get()->RegisterRGBController(rgb_controller);
-    }
-}
-
-void DetectCoolerMasterMouse711(hid_device_info* info, const std::string& /*name*/)
-{
-    hid_device* dev = hid_open_path(info->path);
-
-    if(dev)
-    {
-        CMMM711Controller*               controller     = new CMMM711Controller(dev, info->path);
-        RGBController_CMMM711Controller* rgb_controller = new RGBController_CMMM711Controller(controller);
-
-        ResourceManager::get()->RegisterRGBController(rgb_controller);
-    }
-}
-
-void DetectCoolerMasterMouse712(hid_device_info* info, const std::string& /*name*/)
-{
-    hid_device* dev = hid_open_path(info->path);
-
-    if(dev)
-    {
-        CMMM712Controller*               controller     = new CMMM712Controller(dev, info->path);
-        RGBController_CMMM712Controller* rgb_controller = new RGBController_CMMM712Controller(controller);
-
-        ResourceManager::get()->RegisterRGBController(rgb_controller);
-    }
-}
-
-void DetectCoolerMasterMousemats(hid_device_info* info, const std::string& /*name*/)
-{
-    hid_device* dev = hid_open_path(info->path);
-
-    if(dev)
-    {
-        CMMP750Controller*               controller     = new CMMP750Controller(dev, info->path);
-        RGBController_CMMP750Controller* rgb_controller = new RGBController_CMMP750Controller(controller);
-
-        ResourceManager::get()->RegisterRGBController(rgb_controller);
-    }
-}
-
-void DetectCoolerMasterRGB(hid_device_info* info, const std::string& /*name*/)
-{
-    hid_device* dev = hid_open_path(info->path);
-
-    if(dev)
-    {
-        CMRGBController*               controller     = new CMRGBController(dev, info->path);
-        RGBController_CMRGBController* rgb_controller = new RGBController_CMRGBController(controller);
-
-        ResourceManager::get()->RegisterRGBController(rgb_controller);
-    }
-}
-
-void DetectCoolerMasterSmallARGB(hid_device_info* info, const std::string& /*name*/)
-{
-    hid_device* dev = hid_open_path(info->path);
-
-    if(dev)
-    {
-        CMSmallARGBController*               controller     = new CMSmallARGBController(dev, info->path, 0);
-        RGBController_CMSmallARGBController* rgb_controller = new RGBController_CMSmallARGBController(controller);
-
-        ResourceManager::get()->RegisterRGBController(rgb_controller);
-    }
-}
-
-void DetectCoolerMasterMonitor(hid_device_info* info, const std::string& name)
-{
-    hid_device* dev = hid_open_path(info->path);
-
-    if(dev)
-    {
-        CMMonitorController*               controller     = new CMMonitorController(dev, *info, name);
-        RGBController_CMMonitorController* rgb_controller = new RGBController_CMMonitorController(controller);
-
-        ResourceManager::get()->RegisterRGBController(rgb_controller);
-    }
-}
-
-void DetectCoolerMasterGD160(hid_device_info* info, const std::string& name)
-{
-    hid_device* dev = hid_open_path(info->path);
-
-    if(dev)
-    {
-        CMGD160Controller*               controller     = new CMGD160Controller(dev, *info, name);
-        RGBController_CMGD160Controller* rgb_controller = new RGBController_CMGD160Controller(controller);
-
-        ResourceManager::get()->RegisterRGBController(rgb_controller);
-    }
-}
-
-
-/*-----------------------------------------------------*\
-| Coolermaster Keyboards                                |
-|   PIDs defined in `CMKeyboardDevices.h`               |
-\*-----------------------------------------------------*/
-REGISTER_HID_DETECTOR_IPU("Cooler Master MasterKeys Pro S",         DetectCoolerMasterV1Keyboards,  COOLERMASTER_VID,   COOLERMASTER_KEYBOARD_PRO_S_PID,          1,      0xFF00, 1);
-REGISTER_HID_DETECTOR_IPU("Cooler Master MasterKeys Pro L",         DetectCoolerMasterV1Keyboards,  COOLERMASTER_VID,   COOLERMASTER_KEYBOARD_PRO_L_PID,          1,      0xFF00, 1);
-REGISTER_HID_DETECTOR_IPU("Cooler Master MasterKeys Pro L White",   DetectCoolerMasterV1Keyboards,  COOLERMASTER_VID,   COOLERMASTER_KEYBOARD_PRO_L_WHITE_PID,    1,      0xFF00, 1);
-REGISTER_HID_DETECTOR_IPU("Cooler Master MK850",                    DetectCoolerMasterV2Keyboards,  COOLERMASTER_VID,   COOLERMASTER_KEYBOARD_MK850_PID,          1,      0xFF00, 1);
-REGISTER_HID_DETECTOR_IPU("Cooler Master SK620 White",              DetectCoolerMasterV2Keyboards,  COOLERMASTER_VID,   COOLERMASTER_KEYBOARD_SK620W_PID,         1,      0xFF00, 1);
-REGISTER_HID_DETECTOR_IPU("Cooler Master SK620 Black",              DetectCoolerMasterV2Keyboards,  COOLERMASTER_VID,   COOLERMASTER_KEYBOARD_SK620B_PID,         1,      0xFF00, 1);
-REGISTER_HID_DETECTOR_IPU("Cooler Master SK622 White",              DetectCoolerMasterV2Keyboards,  COOLERMASTER_VID,   COOLERMASTER_KEYBOARD_SK622W_PID,         1,      0xFF00, 1);
-REGISTER_HID_DETECTOR_IPU("Cooler Master SK622 Black",              DetectCoolerMasterV2Keyboards,  COOLERMASTER_VID,   COOLERMASTER_KEYBOARD_SK622B_PID,         1,      0xFF00, 1);
-REGISTER_HID_DETECTOR_IPU("Cooler Master SK630",                    DetectCoolerMasterV2Keyboards,  COOLERMASTER_VID,   COOLERMASTER_KEYBOARD_SK630_PID,          1,      0xFF00, 1);
-REGISTER_HID_DETECTOR_IPU("Cooler Master SK650",                    DetectCoolerMasterV2Keyboards,  COOLERMASTER_VID,   COOLERMASTER_KEYBOARD_SK650_PID,          1,      0xFF00, 1);
-REGISTER_HID_DETECTOR_IPU("Cooler Master SK652",                    DetectCoolerMasterV2Keyboards,  COOLERMASTER_VID,   COOLERMASTER_KEYBOARD_SK652_PID,          1,      0xFF00, 1);
-REGISTER_HID_DETECTOR_IPU("Cooler Master SK653",                    DetectCoolerMasterV2Keyboards,  COOLERMASTER_VID,   COOLERMASTER_KEYBOARD_SK653_PID,          1,      0xFF00, 1);
-REGISTER_HID_DETECTOR_IPU("Cooler Master MK730",                    DetectCoolerMasterV2Keyboards,  COOLERMASTER_VID,   COOLERMASTER_KEYBOARD_MK730_PID,          1,      0xFF00, 1);
-REGISTER_HID_DETECTOR_IPU("Cooler Master MK750",                    DetectCoolerMasterV2Keyboards,  COOLERMASTER_VID,   COOLERMASTER_KEYBOARD_MK750_PID,          1,      0xFF00, 1);
-REGISTER_HID_DETECTOR_IPU("Cooler Master CK530",                    DetectCoolerMasterV2Keyboards,  COOLERMASTER_VID,   COOLERMASTER_KEYBOARD_CK530_PID,          1,      0xFF00, 1);
-REGISTER_HID_DETECTOR_IPU("Cooler Master CK530 V2",                 DetectCoolerMasterV2Keyboards,  COOLERMASTER_VID,   COOLERMASTER_KEYBOARD_CK530_V2_PID,       1,      0xFF00, 1);
-REGISTER_HID_DETECTOR_IPU("Cooler Master CK550 V2",                 DetectCoolerMasterV2Keyboards,  COOLERMASTER_VID,   COOLERMASTER_KEYBOARD_CK550_V2_PID,       1,      0xFF00, 1);
-REGISTER_HID_DETECTOR_IPU("Cooler Master CK550 V1 / CK552",         DetectCoolerMasterV2Keyboards,  COOLERMASTER_VID,   COOLERMASTER_KEYBOARD_CK552_V2_PID,       1,      0xFF00, 1);
-
-/*-----------------------------------------------------*\
-| Coolermaster LEDstrip controllers                     |
-\*-----------------------------------------------------*/
-REGISTER_HID_DETECTOR_IPU("Cooler Master ARGB",                     DetectCoolerMasterARGB,         COOLERMASTER_VID,   COOLERMASTER_ARGB_PID,                      0,      0xFF00, 1);
-REGISTER_HID_DETECTOR_IPU("Cooler Master ARGB Gen 2 A1",            DetectCoolerMasterARGBGen2A1,   COOLERMASTER_VID,   COOLERMASTER_ARGB_GEN2_A1_PID,              1,      0xFF01, 1);
-REGISTER_HID_DETECTOR_IPU("Cooler Master ARGB Gen 2 A1 V2",         DetectCoolerMasterARGBGen2A1,   COOLERMASTER_VID,   COOLERMASTER_ARGB_GEN2_A1_V2_PID,           1,      0xFF01, 1);
-REGISTER_HID_DETECTOR_IPU("Cooler Master ARGB Gen 2 A1 Mini",       DetectCoolerMasterARGBGen2A1,   COOLERMASTER_VID,   COOLERMASTER_ARGB_GEN2_A1_MINI_PID,         1,      0xFF01, 1);
-REGISTER_HID_DETECTOR_IPU("Cooler Master RGB",                      DetectCoolerMasterRGB,          COOLERMASTER_VID,   COOLERMASTER_RGB_PID,                       1,      0xFF00, 1);
-REGISTER_HID_DETECTOR_IPU("Cooler Master Small ARGB",               DetectCoolerMasterSmallARGB,    COOLERMASTER_VID,   COOLERMASTER_SMALL_ARGB_PID,                0,      0xFF00, 1);
-
-/*-----------------------------------------------------*\
-| Coolermaster Mice                                     |
-\*-----------------------------------------------------*/
-REGISTER_HID_DETECTOR_IPU("Cooler Master MM530",                    DetectCoolerMasterMouse,        COOLERMASTER_VID,   COOLERMASTER_MM530_PID,                     1,      0xFF00, 1);
-//REGISTER_HID_DETECTOR_IPU("Cooler Master MM531",                  DetectCoolerMasterMouse,        COOLERMASTER_VID,   COOLERMASTER_MM531_PID,                     1,      0xFF00, 1);
-REGISTER_HID_DETECTOR_IPU("Cooler Master MM711",                    DetectCoolerMasterMouse711,     COOLERMASTER_VID,   COOLERMASTER_MM711_PID,                     1,      0xFF00, 1);
-REGISTER_HID_DETECTOR_IPU("Cooler Master MM712",                    DetectCoolerMasterMouse712,     COOLERMASTER_VID,   COOLERMASTER_MM712_PID,                     3,      0xFF0A, 2);
-REGISTER_HID_DETECTOR_IPU("Cooler Master MM720",                    DetectCoolerMasterMouse,        COOLERMASTER_VID,   COOLERMASTER_MM720_PID,                     1,      0xFF00, 1);
-REGISTER_HID_DETECTOR_IPU("Cooler Master MM730",                    DetectCoolerMasterMouse,        COOLERMASTER_VID,   COOLERMASTER_MM730_PID,                     1,      0xFF00, 1);
-
-/*-----------------------------------------------------*\
-| Coolermaster Mousemats                                |
-\*-----------------------------------------------------*/
-REGISTER_HID_DETECTOR_PU ("Cooler Master MP750 XL",                 DetectCoolerMasterMousemats,    COOLERMASTER_VID,   COOLERMASTER_MP750_XL_PID,                          0xFF00, 1);
-REGISTER_HID_DETECTOR_PU ("Cooler Master MP750 Large",              DetectCoolerMasterMousemats,    COOLERMASTER_VID,   COOLERMASTER_MP750_L_PID,                           0xFF00, 1);
-REGISTER_HID_DETECTOR_PU ("Cooler Master MP750 Medium",             DetectCoolerMasterMousemats,    COOLERMASTER_VID,   COOLERMASTER_MP750_MEDIUM_PID,                      0xFF00, 1);
-
-/*-----------------------------------------------------*\
-| Coolermaster GPUs                                     |
-|   PIDs defined in `CMR6000Controller.h`               |
-\*-----------------------------------------------------*/
-REGISTER_HID_DETECTOR_I  ("Cooler Master Radeon RX 6000 GPU",        DetectCoolerMasterGPU,          COOLERMASTER_VID,   COOLERMASTER_RADEON_6000_PID,               1                );
-REGISTER_HID_DETECTOR_I  ("Cooler Master Radeon RX 6900 GPU",        DetectCoolerMasterGPU,          COOLERMASTER_VID,   COOLERMASTER_RADEON_6900_PID,               1                );
-
-/*-----------------------------------------------------*\
-| Coolermaster Monitors                                 |
-\*-----------------------------------------------------*/
-REGISTER_HID_DETECTOR_IPU("Cooler Master GM27-FQS ARGB Monitor",    DetectCoolerMasterMonitor,      COOLERMASTER_VID,   COOLERMASTER_GM27_FQS_PID,                   0,      0xFF00, 1);
-
-/*-----------------------------------------------------*\
-| Coolermaster Desks                                    |
-\*-----------------------------------------------------*/
-REGISTER_HID_DETECTOR_IPU("Cooler Master GD160 ARGB Gaming Desk",   DetectCoolerMasterGD160,        COOLERMASTER_VID,   COOLERMASTER_GD160_PID,                   0,      0xFF00, 1);
+/*---------------------------------------------------------*\
+| CoolerMasterControllerDetect.cpp                          |
+|                                                           |
+|   Detector for Cooler Master devices                      |
+|                                                           |
+|   This file is part of the OpenRGB project                |
+|   SPDX-License-Identifier: GPL-2.0-or-later               |
+\*---------------------------------------------------------*/
+
+/*-----------------------------------------------------*\
+| OpenRGB includes                                      |
+\*-----------------------------------------------------*/
+#include <hidapi.h>
+#include "Detector.h"
+#include "LogManager.h"
+
+/*-----------------------------------------------------*\
+| Coolermaster specific includes                        |
+\*-----------------------------------------------------*/
+#include "RGBController_CMMMController.h"
+#include "RGBController_CMMM711Controller.h"
+#include "RGBController_CMMM712Controller.h"
+#include "RGBController_CMMM731Controller.h"
+#include "RGBController_CMMP750Controller.h"
+#include "RGBController_CMARGBController.h"
+#include "RGBController_CMSmallARGBController.h"
+#include "RGBController_CMARGBGen2A1Controller.h"
+#include "RGBController_CMRGBController.h"
+#include "RGBController_CMR6000Controller.h"
+#include "RGBController_CMMonitorController.h"
+#include "RGBController_CMGD160Controller.h"
+#include "RGBController_CMKeyboardController.h"
+
+/*-----------------------------------------------------*\
+| Coolermaster USB vendor ID                            |
+\*-----------------------------------------------------*/
+#define COOLERMASTER_VID                            0x2516
+
+/*-----------------------------------------------------*\
+| Coolermaster Keyboards                                |
+|   PIDs defined in `CMMKControllerV2.h`                |
+\*-----------------------------------------------------*/
+
+/*-----------------------------------------------------*\
+| Coolermaster GPUs                                     |
+|   PIDs defined in `CMR6000Controller.h`               |
+\*-----------------------------------------------------*/
+
+/*-----------------------------------------------------*\
+| Coolermaster LEDstrip controllers                     |
+\*-----------------------------------------------------*/
+#define COOLERMASTER_ARGB_PID                       0x1011
+#define COOLERMASTER_ARGB_GEN2_A1_PID               0x0173
+#define COOLERMASTER_ARGB_GEN2_A1_V2_PID            0x01C9
+#define COOLERMASTER_ARGB_GEN2_A1_MINI_PID          0x01CB
+#define COOLERMASTER_SMALL_ARGB_PID                 0x1000
+#define COOLERMASTER_RGB_PID                        0x004F
+
+/*-----------------------------------------------------*\
+| Coolermaster Mice                                     |
+\*-----------------------------------------------------*/
+#define COOLERMASTER_MM530_PID                      0x0065
+#define COOLERMASTER_MM531_PID                      0x0097
+#define COOLERMASTER_MM711_PID                      0x0101
+#define COOLERMASTER_MM712_PID                      0x0169
+#define COOLERMASTER_MM720_PID                      0x0141
+#define COOLERMASTER_MM730_PID                      0x0165
+#define COOLERMASTER_MM731_WIRED_PID                0x0167
+#define COOLERMASTER_MM731_WIRELESS_PID             0x0171
+#define COOLERMASTER_MM731_WIRELESS_R2_PID          0x01B7
+
+/*-----------------------------------------------------*\
+| Coolermaster Mousemats                                |
+\*-----------------------------------------------------*/
+#define COOLERMASTER_MP750_XL_PID                   0x0109
+#define COOLERMASTER_MP750_L_PID                    0x0107
+#define COOLERMASTER_MP750_MEDIUM_PID               0x0105
+
+/*-----------------------------------------------------*\
+| Coolermaster Monitors                                 |
+\*-----------------------------------------------------*/
+#define COOLERMASTER_GM27_FQS_PID                   0x01BB
+
+/*-----------------------------------------------------*\
+| Coolermaster Desks                                    |
+\*-----------------------------------------------------*/
+#define COOLERMASTER_GD160_PID                      0x01A9
+
+/******************************************************************************************\
+*                                                                                          *
+*   DetectCoolerMasterControllers                                                          *
+*                                                                                          *
+*       Tests the USB address to see if any CoolerMaster controllers exists there.         *
+*                                                                                          *
+\******************************************************************************************/
+
+void DetectCoolerMasterARGB(hid_device_info* info, const std::string&)
+{
+    hid_device* dev = hid_open_path(info->path);
+
+    if(dev)
+    {
+        /*-------------------------------------------------*\
+        | Create mutex to prevent the controllers sharing a |
+        |   receiver from interfering with each other       |
+        \*-------------------------------------------------*/
+        std::shared_ptr<std::mutex>       cm_mutex = std::make_shared<std::mutex>();
+
+        for(unsigned char i = 0; i < CM_ARGB_HEADER_DATA_SIZE; i++)
+        {
+            CMARGBController*               controller     = new CMARGBController(dev, info->path, i, cm_mutex);
+            RGBController_CMARGBController* rgb_controller = new RGBController_CMARGBController(controller);
+
+            ResourceManager::get()->RegisterRGBController(rgb_controller);
+        }
+    }
+}
+
+void DetectCoolerMasterARGBGen2A1(hid_device_info* info, const std::string& name)
+{
+    hid_device* dev = hid_open_path(info->path);
+
+    if(dev)
+    {
+        CMARGBGen2A1controller*               controller     = new CMARGBGen2A1controller(dev, *info, name);
+        RGBController_CMARGBGen2A1Controller* rgb_controller = new RGBController_CMARGBGen2A1Controller(controller);
+
+        ResourceManager::get()->RegisterRGBController(rgb_controller);
+    }
+}
+
+void DetectCoolerMasterGPU(hid_device_info* info, const std::string&)
+{
+    hid_device* dev = hid_open_path(info->path);
+
+    if(dev)
+    {
+        CMR6000Controller*               controller     = new CMR6000Controller(dev, info->path, info->product_id);
+        RGBController_CMR6000Controller* rgb_controller = new RGBController_CMR6000Controller(controller);
+
+        ResourceManager::get()->RegisterRGBController(rgb_controller);
+    }
+}
+
+void DetectCoolerMasterV1Keyboards(hid_device_info* info, const std::string& name)
+{
+    hid_device* dev = hid_open_path(info->path);
+
+    if(dev)
+    {
+        switch(info->product_id)
+        {
+            case COOLERMASTER_KEYBOARD_PRO_L_PID:
+            case COOLERMASTER_KEYBOARD_PRO_L_WHITE_PID:
+            case COOLERMASTER_KEYBOARD_PRO_S_PID:
+            {
+                CMKeyboardV1Controller*             controller     = new CMKeyboardV1Controller(dev, info, name);
+                RGBController_CMKeyboardController* rgb_controller = new RGBController_CMKeyboardController(controller);
+
+                ResourceManager::get()->RegisterRGBController(rgb_controller);
+            }
+            break;
+
+            default:
+                LOG_DEBUG("[%s] Controller not created as the product ID %04X is missing from detector switch", name.c_str(), info->product_id);
+            break;
+        }
+    }
+}
+
+void DetectCoolerMasterV2Keyboards(hid_device_info* info, const std::string& name)
+{
+    hid_device* dev = hid_open_path(info->path);
+
+    if(dev)
+    {
+        switch(info->product_id)
+        {
+            case COOLERMASTER_KEYBOARD_PRO_L_PID:
+            case COOLERMASTER_KEYBOARD_PRO_L_WHITE_PID:
+            case COOLERMASTER_KEYBOARD_PRO_S_PID:
+            {
+                CMKeyboardV1Controller*             controller     = new CMKeyboardV1Controller(dev, info, name);
+                RGBController_CMKeyboardController* rgb_controller = new RGBController_CMKeyboardController(controller);
+
+                ResourceManager::get()->RegisterRGBController(rgb_controller);
+            }
+            break;
+
+            case COOLERMASTER_KEYBOARD_SK622B_PID:
+            case COOLERMASTER_KEYBOARD_SK622W_PID:
+            case COOLERMASTER_KEYBOARD_SK630_PID:
+            case COOLERMASTER_KEYBOARD_SK650_PID:
+            case COOLERMASTER_KEYBOARD_SK652_PID:
+            case COOLERMASTER_KEYBOARD_SK653_PID:
+            case COOLERMASTER_KEYBOARD_CK530_PID:
+            case COOLERMASTER_KEYBOARD_CK530_V2_PID:
+            case COOLERMASTER_KEYBOARD_CK550_V2_PID:
+            case COOLERMASTER_KEYBOARD_CK552_V2_PID:
+            case COOLERMASTER_KEYBOARD_MK730_PID:
+            case COOLERMASTER_KEYBOARD_MK750_PID:
+            {
+                CMKeyboardV2Controller*             controller     = new CMKeyboardV2Controller(dev, info, name);
+                RGBController_CMKeyboardController* rgb_controller = new RGBController_CMKeyboardController(controller);
+
+                ResourceManager::get()->RegisterRGBController(rgb_controller);
+            }
+            break;
+
+            default:
+                LOG_DEBUG("[%s] Controller not created as the product ID %04X is missing from detector switch", name.c_str(), info->product_id);
+            break;
+        }
+    }
+}
+
+void DetectCoolerMasterMouse(hid_device_info* info, const std::string& name)
+{
+    hid_device* dev = hid_open_path(info->path);
+
+    if(dev)
+    {
+        CMMMController*               controller        = new CMMMController(dev, info->path, info->product_id, name);
+        RGBController_CMMMController* rgb_controller    = new RGBController_CMMMController(controller);
+
+        ResourceManager::get()->RegisterRGBController(rgb_controller);
+    }
+}
+
+void DetectCoolerMasterMouse711(hid_device_info* info, const std::string& /*name*/)
+{
+    hid_device* dev = hid_open_path(info->path);
+
+    if(dev)
+    {
+        CMMM711Controller*               controller     = new CMMM711Controller(dev, info->path);
+        RGBController_CMMM711Controller* rgb_controller = new RGBController_CMMM711Controller(controller);
+
+        ResourceManager::get()->RegisterRGBController(rgb_controller);
+    }
+}
+
+void DetectCoolerMasterMouse712(hid_device_info* info, const std::string& /*name*/)
+{
+    hid_device* dev = hid_open_path(info->path);
+
+    if(dev)
+    {
+        CMMM712Controller*               controller     = new CMMM712Controller(dev, info->path);
+        RGBController_CMMM712Controller* rgb_controller = new RGBController_CMMM712Controller(controller);
+
+        ResourceManager::get()->RegisterRGBController(rgb_controller);
+    }
+}
+
+void DetectCoolerMasterMouse731(hid_device_info* info, const std::string& /*name*/)
+{
+    hid_device* dev = hid_open_path(info->path);
+
+    if(dev)
+    {
+        CMMM731Controller*               controller     = new CMMM731Controller(dev, info->path);
+        RGBController_CMMM731Controller* rgb_controller = new RGBController_CMMM731Controller(controller);
+
+        ResourceManager::get()->RegisterRGBController(rgb_controller);
+    }
+}
+
+void DetectCoolerMasterMousemats(hid_device_info* info, const std::string& /*name*/)
+{
+    hid_device* dev = hid_open_path(info->path);
+
+    if(dev)
+    {
+        CMMP750Controller*               controller     = new CMMP750Controller(dev, info->path);
+        RGBController_CMMP750Controller* rgb_controller = new RGBController_CMMP750Controller(controller);
+
+        ResourceManager::get()->RegisterRGBController(rgb_controller);
+    }
+}
+
+void DetectCoolerMasterRGB(hid_device_info* info, const std::string& /*name*/)
+{
+    hid_device* dev = hid_open_path(info->path);
+
+    if(dev)
+    {
+        CMRGBController*               controller     = new CMRGBController(dev, info->path);
+        RGBController_CMRGBController* rgb_controller = new RGBController_CMRGBController(controller);
+
+        ResourceManager::get()->RegisterRGBController(rgb_controller);
+    }
+}
+
+void DetectCoolerMasterSmallARGB(hid_device_info* info, const std::string& /*name*/)
+{
+    hid_device* dev = hid_open_path(info->path);
+
+    if(dev)
+    {
+        CMSmallARGBController*               controller     = new CMSmallARGBController(dev, info->path, 0);
+        RGBController_CMSmallARGBController* rgb_controller = new RGBController_CMSmallARGBController(controller);
+
+        ResourceManager::get()->RegisterRGBController(rgb_controller);
+    }
+}
+
+void DetectCoolerMasterMonitor(hid_device_info* info, const std::string& name)
+{
+    hid_device* dev = hid_open_path(info->path);
+
+    if(dev)
+    {
+        CMMonitorController*               controller     = new CMMonitorController(dev, *info, name);
+        RGBController_CMMonitorController* rgb_controller = new RGBController_CMMonitorController(controller);
+
+        ResourceManager::get()->RegisterRGBController(rgb_controller);
+    }
+}
+
+void DetectCoolerMasterGD160(hid_device_info* info, const std::string& name)
+{
+    hid_device* dev = hid_open_path(info->path);
+
+    if(dev)
+    {
+        CMGD160Controller*               controller     = new CMGD160Controller(dev, *info, name);
+        RGBController_CMGD160Controller* rgb_controller = new RGBController_CMGD160Controller(controller);
+
+        ResourceManager::get()->RegisterRGBController(rgb_controller);
+    }
+}
+
+
+/*-----------------------------------------------------*\
+| Coolermaster Keyboards                                |
+|   PIDs defined in `CMKeyboardDevices.h`               |
+\*-----------------------------------------------------*/
+REGISTER_HID_DETECTOR_IPU("Cooler Master MasterKeys Pro S",         DetectCoolerMasterV1Keyboards,  COOLERMASTER_VID,   COOLERMASTER_KEYBOARD_PRO_S_PID,          1,      0xFF00, 1);
+REGISTER_HID_DETECTOR_IPU("Cooler Master MasterKeys Pro L",         DetectCoolerMasterV1Keyboards,  COOLERMASTER_VID,   COOLERMASTER_KEYBOARD_PRO_L_PID,          1,      0xFF00, 1);
+REGISTER_HID_DETECTOR_IPU("Cooler Master MasterKeys Pro L White",   DetectCoolerMasterV1Keyboards,  COOLERMASTER_VID,   COOLERMASTER_KEYBOARD_PRO_L_WHITE_PID,    1,      0xFF00, 1);
+REGISTER_HID_DETECTOR_IPU("Cooler Master MK850",                    DetectCoolerMasterV2Keyboards,  COOLERMASTER_VID,   COOLERMASTER_KEYBOARD_MK850_PID,          1,      0xFF00, 1);
+REGISTER_HID_DETECTOR_IPU("Cooler Master SK620 White",              DetectCoolerMasterV2Keyboards,  COOLERMASTER_VID,   COOLERMASTER_KEYBOARD_SK620W_PID,         1,      0xFF00, 1);
+REGISTER_HID_DETECTOR_IPU("Cooler Master SK620 Black",              DetectCoolerMasterV2Keyboards,  COOLERMASTER_VID,   COOLERMASTER_KEYBOARD_SK620B_PID,         1,      0xFF00, 1);
+REGISTER_HID_DETECTOR_IPU("Cooler Master SK622 White",              DetectCoolerMasterV2Keyboards,  COOLERMASTER_VID,   COOLERMASTER_KEYBOARD_SK622W_PID,         1,      0xFF00, 1);
+REGISTER_HID_DETECTOR_IPU("Cooler Master SK622 Black",              DetectCoolerMasterV2Keyboards,  COOLERMASTER_VID,   COOLERMASTER_KEYBOARD_SK622B_PID,         1,      0xFF00, 1);
+REGISTER_HID_DETECTOR_IPU("Cooler Master SK630",                    DetectCoolerMasterV2Keyboards,  COOLERMASTER_VID,   COOLERMASTER_KEYBOARD_SK630_PID,          1,      0xFF00, 1);
+REGISTER_HID_DETECTOR_IPU("Cooler Master SK650",                    DetectCoolerMasterV2Keyboards,  COOLERMASTER_VID,   COOLERMASTER_KEYBOARD_SK650_PID,          1,      0xFF00, 1);
+REGISTER_HID_DETECTOR_IPU("Cooler Master SK652",                    DetectCoolerMasterV2Keyboards,  COOLERMASTER_VID,   COOLERMASTER_KEYBOARD_SK652_PID,          1,      0xFF00, 1);
+REGISTER_HID_DETECTOR_IPU("Cooler Master SK653",                    DetectCoolerMasterV2Keyboards,  COOLERMASTER_VID,   COOLERMASTER_KEYBOARD_SK653_PID,          1,      0xFF00, 1);
+REGISTER_HID_DETECTOR_IPU("Cooler Master MK730",                    DetectCoolerMasterV2Keyboards,  COOLERMASTER_VID,   COOLERMASTER_KEYBOARD_MK730_PID,          1,      0xFF00, 1);
+REGISTER_HID_DETECTOR_IPU("Cooler Master MK750",                    DetectCoolerMasterV2Keyboards,  COOLERMASTER_VID,   COOLERMASTER_KEYBOARD_MK750_PID,          1,      0xFF00, 1);
+REGISTER_HID_DETECTOR_IPU("Cooler Master CK530",                    DetectCoolerMasterV2Keyboards,  COOLERMASTER_VID,   COOLERMASTER_KEYBOARD_CK530_PID,          1,      0xFF00, 1);
+REGISTER_HID_DETECTOR_IPU("Cooler Master CK530 V2",                 DetectCoolerMasterV2Keyboards,  COOLERMASTER_VID,   COOLERMASTER_KEYBOARD_CK530_V2_PID,       1,      0xFF00, 1);
+REGISTER_HID_DETECTOR_IPU("Cooler Master CK550 V2",                 DetectCoolerMasterV2Keyboards,  COOLERMASTER_VID,   COOLERMASTER_KEYBOARD_CK550_V2_PID,       1,      0xFF00, 1);
+REGISTER_HID_DETECTOR_IPU("Cooler Master CK550 V1 / CK552",         DetectCoolerMasterV2Keyboards,  COOLERMASTER_VID,   COOLERMASTER_KEYBOARD_CK552_V2_PID,       1,      0xFF00, 1);
+
+/*-----------------------------------------------------*\
+| Coolermaster LEDstrip controllers                     |
+\*-----------------------------------------------------*/
+REGISTER_HID_DETECTOR_IPU("Cooler Master ARGB",                     DetectCoolerMasterARGB,         COOLERMASTER_VID,   COOLERMASTER_ARGB_PID,                      0,      0xFF00, 1);
+REGISTER_HID_DETECTOR_IPU("Cooler Master ARGB Gen 2 A1",            DetectCoolerMasterARGBGen2A1,   COOLERMASTER_VID,   COOLERMASTER_ARGB_GEN2_A1_PID,              1,      0xFF01, 1);
+REGISTER_HID_DETECTOR_IPU("Cooler Master ARGB Gen 2 A1 V2",         DetectCoolerMasterARGBGen2A1,   COOLERMASTER_VID,   COOLERMASTER_ARGB_GEN2_A1_V2_PID,           1,      0xFF01, 1);
+REGISTER_HID_DETECTOR_IPU("Cooler Master ARGB Gen 2 A1 Mini",       DetectCoolerMasterARGBGen2A1,   COOLERMASTER_VID,   COOLERMASTER_ARGB_GEN2_A1_MINI_PID,         1,      0xFF01, 1);
+REGISTER_HID_DETECTOR_IPU("Cooler Master RGB",                      DetectCoolerMasterRGB,          COOLERMASTER_VID,   COOLERMASTER_RGB_PID,                       1,      0xFF00, 1);
+REGISTER_HID_DETECTOR_IPU("Cooler Master Small ARGB",               DetectCoolerMasterSmallARGB,    COOLERMASTER_VID,   COOLERMASTER_SMALL_ARGB_PID,                0,      0xFF00, 1);
+
+/*-----------------------------------------------------*\
+| Coolermaster Mice                                     |
+\*-----------------------------------------------------*/
+REGISTER_HID_DETECTOR_IPU("Cooler Master MM530",                    DetectCoolerMasterMouse,        COOLERMASTER_VID,   COOLERMASTER_MM530_PID,                     1,      0xFF00, 1);
+//REGISTER_HID_DETECTOR_IPU("Cooler Master MM531",                  DetectCoolerMasterMouse,        COOLERMASTER_VID,   COOLERMASTER_MM531_PID,                     1,      0xFF00, 1);
+REGISTER_HID_DETECTOR_IPU("Cooler Master MM711",                    DetectCoolerMasterMouse711,     COOLERMASTER_VID,   COOLERMASTER_MM711_PID,                     1,      0xFF00, 1);
+REGISTER_HID_DETECTOR_IPU("Cooler Master MM712",                    DetectCoolerMasterMouse712,     COOLERMASTER_VID,   COOLERMASTER_MM712_PID,                     3,      0xFF0A, 2);
+REGISTER_HID_DETECTOR_IPU("Cooler Master MM720",                    DetectCoolerMasterMouse,        COOLERMASTER_VID,   COOLERMASTER_MM720_PID,                     1,      0xFF00, 1);
+REGISTER_HID_DETECTOR_IPU("Cooler Master MM730",                    DetectCoolerMasterMouse,        COOLERMASTER_VID,   COOLERMASTER_MM730_PID,                     1,      0xFF00, 1);
+REGISTER_HID_DETECTOR_IPU("Cooler Master MM731 (Wired)",            DetectCoolerMasterMouse731,     COOLERMASTER_VID,   COOLERMASTER_MM731_WIRED_PID,               4,      0xFF0A, 2);
+REGISTER_HID_DETECTOR_IPU("Cooler Master MM731 (Wireless)",         DetectCoolerMasterMouse731,     COOLERMASTER_VID,   COOLERMASTER_MM731_WIRELESS_PID,            4,      0xFF0A, 1);
+REGISTER_HID_DETECTOR_IPU("Cooler Master MM731 (Wireless)",         DetectCoolerMasterMouse731,     COOLERMASTER_VID,   COOLERMASTER_MM731_WIRELESS_R2_PID,         4,      0xFF0A, 1);
+
+/*-----------------------------------------------------*\
+| Coolermaster Mousemats                                |
+\*-----------------------------------------------------*/
+REGISTER_HID_DETECTOR_PU ("Cooler Master MP750 XL",                 DetectCoolerMasterMousemats,    COOLERMASTER_VID,   COOLERMASTER_MP750_XL_PID,                          0xFF00, 1);
+REGISTER_HID_DETECTOR_PU ("Cooler Master MP750 Large",              DetectCoolerMasterMousemats,    COOLERMASTER_VID,   COOLERMASTER_MP750_L_PID,                           0xFF00, 1);
+REGISTER_HID_DETECTOR_PU ("Cooler Master MP750 Medium",             DetectCoolerMasterMousemats,    COOLERMASTER_VID,   COOLERMASTER_MP750_MEDIUM_PID,                      0xFF00, 1);
+
+/*-----------------------------------------------------*\
+| Coolermaster GPUs                                     |
+|   PIDs defined in `CMR6000Controller.h`               |
+\*-----------------------------------------------------*/
+REGISTER_HID_DETECTOR_I  ("Cooler Master Radeon RX 6000 GPU",        DetectCoolerMasterGPU,          COOLERMASTER_VID,   COOLERMASTER_RADEON_6000_PID,               1                );
+REGISTER_HID_DETECTOR_I  ("Cooler Master Radeon RX 6900 GPU",        DetectCoolerMasterGPU,          COOLERMASTER_VID,   COOLERMASTER_RADEON_6900_PID,               1                );
+
+/*-----------------------------------------------------*\
+| Coolermaster Monitors                                 |
+\*-----------------------------------------------------*/
+REGISTER_HID_DETECTOR_IPU("Cooler Master GM27-FQS ARGB Monitor",    DetectCoolerMasterMonitor,      COOLERMASTER_VID,   COOLERMASTER_GM27_FQS_PID,                   0,      0xFF00, 1);
+
+/*-----------------------------------------------------*\
+| Coolermaster Desks                                    |
+\*-----------------------------------------------------*/
+REGISTER_HID_DETECTOR_IPU("Cooler Master GD160 ARGB Gaming Desk",   DetectCoolerMasterGD160,        COOLERMASTER_VID,   COOLERMASTER_GD160_PID,                   0,      0xFF00, 1);
-- 
GitLab

openSUSE Build Service is sponsored by