/*---------------------------------------------------------*\ | RGBController.h | | | | OpenRGB's RGB controller hardware abstration layer, | | provides a generic representation of an RGB device | | | | Adam Honse (CalcProgrammer1) 02 Jun 2019 | | | | This file is part of the OpenRGB project | | SPDX-License-Identifier: GPL-2.0-only | \*---------------------------------------------------------*/ #pragma once #include #include #include #include #include #include /*------------------------------------------------------------------*\ | RGB Color Type and Conversion Macros | \*------------------------------------------------------------------*/ typedef unsigned int RGBColor; #define RGBGetRValue(rgb) (rgb & 0x000000FF) #define RGBGetGValue(rgb) ((rgb >> 8) & 0x000000FF) #define RGBGetBValue(rgb) ((rgb >> 16) & 0x000000FF) #define ToRGBColor(r, g, b) ((RGBColor)((b << 16) | (g << 8) | (r))) /*------------------------------------------------------------------*\ | Mode Flags | \*------------------------------------------------------------------*/ enum { MODE_FLAG_HAS_SPEED = (1 << 0), /* Mode has speed parameter */ MODE_FLAG_HAS_DIRECTION_LR = (1 << 1), /* Mode has left/right parameter */ MODE_FLAG_HAS_DIRECTION_UD = (1 << 2), /* Mode has up/down parameter */ MODE_FLAG_HAS_DIRECTION_HV = (1 << 3), /* Mode has horiz/vert parameter */ MODE_FLAG_HAS_BRIGHTNESS = (1 << 4), /* Mode has brightness parameter */ MODE_FLAG_HAS_PER_LED_COLOR = (1 << 5), /* Mode has per-LED colors */ MODE_FLAG_HAS_MODE_SPECIFIC_COLOR = (1 << 6), /* Mode has mode specific colors */ MODE_FLAG_HAS_RANDOM_COLOR = (1 << 7), /* Mode has random color option */ MODE_FLAG_MANUAL_SAVE = (1 << 8), /* Mode can manually be saved */ MODE_FLAG_AUTOMATIC_SAVE = (1 << 9), /* Mode automatically saves */ }; /*------------------------------------------------------------------*\ | Mode Directions | \*------------------------------------------------------------------*/ enum { MODE_DIRECTION_LEFT = 0, /* Mode direction left */ MODE_DIRECTION_RIGHT = 1, /* Mode direction right */ MODE_DIRECTION_UP = 2, /* Mode direction up */ MODE_DIRECTION_DOWN = 3, /* Mode direction down */ MODE_DIRECTION_HORIZONTAL = 4, /* Mode direction horizontal */ MODE_DIRECTION_VERTICAL = 5, /* Mode direction vertical */ }; /*------------------------------------------------------------------*\ | Mode Color Types | \*------------------------------------------------------------------*/ enum { MODE_COLORS_NONE = 0, /* Mode has no colors */ MODE_COLORS_PER_LED = 1, /* Mode has per LED colors selected */ MODE_COLORS_MODE_SPECIFIC = 2, /* Mode specific colors selected */ MODE_COLORS_RANDOM = 3, /* Mode has random colors selected */ }; /*------------------------------------------------------------------*\ | Mode Class | \*------------------------------------------------------------------*/ class mode { public: /*--------------------------------------------------------------*\ | Mode Information | \*--------------------------------------------------------------*/ std::string name; /* Mode name */ int value; /* Device-specific mode value */ unsigned int flags; /* Mode flags bitfield */ unsigned int speed_min; /* speed minimum value */ unsigned int speed_max; /* speed maximum value */ unsigned int brightness_min; /*brightness min value */ unsigned int brightness_max; /*brightness max value */ unsigned int colors_min; /* minimum number of mode colors*/ unsigned int colors_max; /* maximum numver of mode colors*/ /*--------------------------------------------------------------*\ | Mode Settings | \*--------------------------------------------------------------*/ unsigned int speed; /* Mode speed parameter value */ unsigned int brightness; /* Mode brightness value */ unsigned int direction; /* Mode direction value */ unsigned int color_mode; /* Mode color selection */ std::vector colors; /* mode-specific colors */ /*--------------------------------------------------------------*\ | Mode Constructor / Destructor | \*--------------------------------------------------------------*/ mode(); ~mode(); }; /*------------------------------------------------------------------*\ | LED Struct | \*------------------------------------------------------------------*/ typedef struct { std::string name; /* LED name */ unsigned int value; /* Device-specific LED value */ } led; /*------------------------------------------------------------------*\ | Zone Types | \*------------------------------------------------------------------*/ typedef int zone_type; enum { ZONE_TYPE_SINGLE, ZONE_TYPE_LINEAR, ZONE_TYPE_MATRIX }; /*------------------------------------------------------------------*\ | Matrix Map Struct | \*------------------------------------------------------------------*/ typedef struct { unsigned int height; unsigned int width; unsigned int * map; } matrix_map_type; /*------------------------------------------------------------------*\ | Segment Struct | \*------------------------------------------------------------------*/ typedef struct { std::string name; /* Segment name */ zone_type type; /* Segment type */ unsigned int start_idx; /* Start index within zone */ unsigned int leds_count; /* Number of LEDs in segment*/ } segment; /*------------------------------------------------------------------*\ | Zone Struct | \*------------------------------------------------------------------*/ typedef struct { std::string name; /* Zone name */ zone_type type; /* Zone type */ led * leds; /* List of LEDs in zone */ RGBColor * colors; /* Colors of LEDs in zone */ unsigned int start_idx; /* Start index of led/color */ unsigned int leds_count; /* Number of LEDs in zone */ unsigned int leds_min; /* Minimum number of LEDs */ unsigned int leds_max; /* Maximum number of LEDs */ matrix_map_type * matrix_map; /* Matrix map pointer */ std::vector segments; /* Segments in zone */ } zone; /*------------------------------------------------------------------*\ | Device Types | | The enum order should be maintained as is for the API however | | DEVICE_TYPE_UNKNOWN needs to remain last. Any new device types | | need to be inserted at the end of the list but before unknown. | \*------------------------------------------------------------------*/ typedef int device_type; enum { DEVICE_TYPE_MOTHERBOARD, DEVICE_TYPE_DRAM, DEVICE_TYPE_GPU, DEVICE_TYPE_COOLER, DEVICE_TYPE_LEDSTRIP, DEVICE_TYPE_KEYBOARD, DEVICE_TYPE_MOUSE, DEVICE_TYPE_MOUSEMAT, DEVICE_TYPE_HEADSET, DEVICE_TYPE_HEADSET_STAND, DEVICE_TYPE_GAMEPAD, DEVICE_TYPE_LIGHT, DEVICE_TYPE_SPEAKER, DEVICE_TYPE_VIRTUAL, DEVICE_TYPE_STORAGE, DEVICE_TYPE_CASE, DEVICE_TYPE_MICROPHONE, DEVICE_TYPE_ACCESSORY, DEVICE_TYPE_KEYPAD, DEVICE_TYPE_UNKNOWN, }; /*------------------------------------------------------------------*\ | RGBController Callback Types | \*------------------------------------------------------------------*/ typedef void (*RGBControllerCallback)(void *); std::string device_type_to_str(device_type type); class RGBControllerInterface { public: virtual void SetupColors() = 0; virtual RGBColor GetLED(unsigned int led) = 0; virtual void SetLED(unsigned int led, RGBColor color) = 0; virtual void SetAllLEDs(RGBColor color) = 0; virtual void SetAllZoneLEDs(int zone, RGBColor color) = 0; virtual int GetMode() = 0; virtual void SetMode(int mode) = 0; virtual unsigned char * GetDeviceDescription(unsigned int protocol_version) = 0; virtual void ReadDeviceDescription(unsigned char* data_buf, unsigned int protocol_version) = 0; virtual unsigned char * GetModeDescription(int mode, unsigned int protocol_version) = 0; virtual void SetModeDescription(unsigned char* data_buf, unsigned int protocol_version) = 0; virtual unsigned char * GetColorDescription() = 0; virtual void SetColorDescription(unsigned char* data_buf) = 0; virtual unsigned char * GetZoneColorDescription(int zone) = 0; virtual void SetZoneColorDescription(unsigned char* data_buf) = 0; virtual unsigned char * GetSingleLEDColorDescription(int led) = 0; virtual void SetSingleLEDColorDescription(unsigned char* data_buf) = 0; virtual void RegisterUpdateCallback(RGBControllerCallback new_callback, void * new_callback_arg) = 0; virtual void UnregisterUpdateCallback(void * callback_arg) = 0; virtual void ClearCallbacks() = 0; virtual void SignalUpdate() = 0; virtual void UpdateLEDs() = 0; //virtual void UpdateZoneLEDs(int zone) = 0; //virtual void UpdateSingleLED(int led) = 0; virtual void UpdateMode() = 0; virtual void SaveMode() = 0; virtual void DeviceCallThreadFunction() = 0; /*---------------------------------------------------------*\ | Functions to be implemented in device implementation | \*---------------------------------------------------------*/ virtual void SetupZones() = 0; virtual void ResizeZone(int zone, int new_size) = 0; virtual void DeviceUpdateLEDs() = 0; virtual void UpdateZoneLEDs(int zone) = 0; virtual void UpdateSingleLED(int led) = 0; virtual void DeviceUpdateMode() = 0; virtual void DeviceSaveMode() = 0; virtual void SetCustomMode() = 0; }; class RGBController : public RGBControllerInterface { public: std::string name; /* controller name */ std::string vendor; /* controller vendor */ std::string description; /* controller description */ std::string version; /* controller version */ std::string serial; /* controller serial number */ std::string location; /* controller location */ std::vector leds; /* LEDs */ std::vector zones; /* Zones */ std::vector modes; /* Modes */ std::vector colors; /* Color buffer */ device_type type; /* device type */ int active_mode = 0;/* active mode */ /*---------------------------------------------------------*\ | RGBController base class constructor | \*---------------------------------------------------------*/ RGBController(); virtual ~RGBController(); /*---------------------------------------------------------*\ | Generic functions implemented in RGBController.cpp | \*---------------------------------------------------------*/ void SetupColors(); RGBColor GetLED(unsigned int led); void SetLED(unsigned int led, RGBColor color); void SetAllLEDs(RGBColor color); void SetAllZoneLEDs(int zone, RGBColor color); int GetMode(); void SetMode(int mode); unsigned char * GetDeviceDescription(unsigned int protocol_version); void ReadDeviceDescription(unsigned char* data_buf, unsigned int protocol_version); unsigned char * GetModeDescription(int mode, unsigned int protocol_version); void SetModeDescription(unsigned char* data_buf, unsigned int protocol_version); unsigned char * GetColorDescription(); void SetColorDescription(unsigned char* data_buf); unsigned char * GetZoneColorDescription(int zone); void SetZoneColorDescription(unsigned char* data_buf); unsigned char * GetSingleLEDColorDescription(int led); void SetSingleLEDColorDescription(unsigned char* data_buf); void RegisterUpdateCallback(RGBControllerCallback new_callback, void * new_callback_arg); void UnregisterUpdateCallback(void * callback_arg); void ClearCallbacks(); void SignalUpdate(); void UpdateLEDs(); //void UpdateZoneLEDs(int zone); //void UpdateSingleLED(int led); void UpdateMode(); void SaveMode(); void DeviceCallThreadFunction(); /*---------------------------------------------------------*\ | Functions to be implemented in device implementation | \*---------------------------------------------------------*/ virtual void SetupZones() = 0; virtual void ResizeZone(int zone, int new_size) = 0; virtual void DeviceUpdateLEDs() = 0; virtual void UpdateZoneLEDs(int zone) = 0; virtual void UpdateSingleLED(int led) = 0; virtual void DeviceUpdateMode() = 0; void DeviceSaveMode(); void SetCustomMode(); private: std::thread* DeviceCallThread; std::atomic CallFlag_UpdateLEDs; std::atomic CallFlag_UpdateMode; std::atomic DeviceThreadRunning; //bool CallFlag_UpdateZoneLEDs = false; //bool CallFlag_UpdateSingleLED = false; //bool CallFlag_UpdateMode = false; std::mutex UpdateMutex; std::vector UpdateCallbacks; std::vector UpdateCallbackArgs; };