From 2c696aaae54eed1d79e2a4e47e98e0cbb6cb8c28 Mon Sep 17 00:00:00 2001 From: Adam Honse Date: Sat, 16 May 2026 16:54:49 -0500 Subject: [PATCH] Use RGBControllerInterface for plugin API --- .../DDPController/DDPControllerDetect.cpp | 2 +- JsonUtils.h | 2 +- OpenRGB.pro | 3 +- OpenRGBPluginAPI.cpp | 92 +-- OpenRGBPluginAPI.h | 47 +- OpenRGBPluginInterface.h | 69 +- PluginManager.cpp | 541 ++++++++------- PluginManager.h | 2 + PluginManagerInterface.h | 3 +- RGBController/RGBController.cpp | 193 ++---- RGBController/RGBController.h | 482 +------------ RGBController/RGBControllerInterface.h | 651 ++++++++++++++++++ RGBController/RGBController_Virtual.cpp | 156 +++++ RGBController/RGBController_Virtual.h | 62 ++ ResourceManager.cpp | 20 +- ResourceManager.h | 6 +- ResourceManagerCallback.h | 29 + ResourceManagerInterface.h | 72 -- cli.cpp | 2 +- .../BaseManualDeviceEntry.h | 2 +- .../DDPSettingsEntry/DDPSettingsEntry.cpp | 2 +- .../DebugSettingsEntry/DebugSettingsEntry.cpp | 2 +- .../ManualDevicesSettingsPage.h | 2 +- .../ManualDevicesTypeManager.h | 2 +- .../OpenRGBDeviceInfoPage.cpp | 2 +- .../OpenRGBDynamicSettingsWidget.h | 2 +- qt/OpenRGBSettingsPage/OpenRGBSettingsPage.h | 2 +- 27 files changed, 1366 insertions(+), 1084 deletions(-) create mode 100644 RGBController/RGBControllerInterface.h create mode 100644 RGBController/RGBController_Virtual.cpp create mode 100644 RGBController/RGBController_Virtual.h create mode 100644 ResourceManagerCallback.h delete mode 100644 ResourceManagerInterface.h diff --git a/Controllers/DDPController/DDPControllerDetect.cpp b/Controllers/DDPController/DDPControllerDetect.cpp index 58da8a01b..56b972ac4 100644 --- a/Controllers/DDPController/DDPControllerDetect.cpp +++ b/Controllers/DDPController/DDPControllerDetect.cpp @@ -9,7 +9,7 @@ #include #include -#include "nlohmann/json.hpp" +#include #include "DetectionManager.h" #include "LogManager.h" #include "ResourceManager.h" diff --git a/JsonUtils.h b/JsonUtils.h index 871253436..ab772ff00 100644 --- a/JsonUtils.h +++ b/JsonUtils.h @@ -10,7 +10,7 @@ #pragma once #include -#include "nlohmann/json.hpp" +#include class JsonUtils { diff --git a/OpenRGB.pro b/OpenRGB.pro index d3154bb9c..6cbb76904 100644 --- a/OpenRGB.pro +++ b/OpenRGB.pro @@ -175,7 +175,7 @@ HEADERS += PluginManager.h \ ProfileManager.h \ ResourceManager.h \ - ResourceManagerInterface.h \ + ResourceManagerCallback.h \ SettingsManager.h \ DetectionManager.h \ dmiinfo/dmiinfo.h \ @@ -268,6 +268,7 @@ SOURCES += RGBController/RGBController_Dummy.cpp \ RGBController/RGBControllerKeyNames.cpp \ RGBController/RGBController_Network.cpp \ + RGBController/RGBController_Virtual.cpp \ RESOURCES += \ qt/resources.qrc \ diff --git a/OpenRGBPluginAPI.cpp b/OpenRGBPluginAPI.cpp index 129538937..67383f433 100644 --- a/OpenRGBPluginAPI.cpp +++ b/OpenRGBPluginAPI.cpp @@ -10,6 +10,7 @@ \*---------------------------------------------------------*/ #include "OpenRGBPluginAPI.h" +#include "RGBController_Virtual.h" OpenRGBPluginAPI::OpenRGBPluginAPI() { @@ -36,81 +37,34 @@ void OpenRGBPluginAPI::LogEntry(const char* filename, int line, unsigned int lev /*---------------------------------------------------------*\ | PluginManager APIs | \*---------------------------------------------------------*/ -static void CallRegisterRGBController(OpenRGBPluginAPI * this_ptr, RGBController * rgb_controller) +RGBControllerInterface* OpenRGBPluginAPI::CreateVirtualRGBController(RGBController_Setup* setup, bool register_controller) { - this_ptr->RegisterRGBController(rgb_controller); -} + RGBController_Virtual* rgb_controller = new RGBController_Virtual(setup); -void OpenRGBPluginAPI::RegisterRGBControllerInThread(RGBController * rgb_controller) -{ - /*-----------------------------------------------------*\ - | To avoid deadlocks if this is called from a UI thread | - | run the register operation in a background thread. | - \*-----------------------------------------------------*/ - std::thread register_thread(CallRegisterRGBController, this, rgb_controller); - register_thread.detach(); -} - -void OpenRGBPluginAPI::RegisterRGBController(RGBController * rgb_controller) -{ - LOG_INFO("[PluginManager] Registering RGB controller %s", rgb_controller->GetName().c_str()); - - /*-----------------------------------------------------*\ - | Mark this controller as locally owned | - \*-----------------------------------------------------*/ - rgb_controller->flags &= ~CONTROLLER_FLAG_REMOTE; - rgb_controller->flags |= CONTROLLER_FLAG_LOCAL; - - /*-----------------------------------------------------*\ - | Add the new controller to the list | - \*-----------------------------------------------------*/ - rgb_controllers.push_back(rgb_controller); - - /*-----------------------------------------------------*\ - | Signal device list update in ResourceManager | - \*-----------------------------------------------------*/ - ResourceManager::get()->UpdateDeviceList(); -} - -static void CallUnregisterRGBController(OpenRGBPluginAPI * this_ptr, RGBController * rgb_controller) -{ - this_ptr->UnregisterRGBController(rgb_controller); -} - -void OpenRGBPluginAPI::UnregisterRGBController(RGBController * rgb_controller) -{ - LOG_INFO("[PluginManager] Unregistering RGB controller %s", rgb_controller->GetName().c_str()); - - /*-----------------------------------------------------*\ - | Clear callbacks from the controller before removal | - \*-----------------------------------------------------*/ - rgb_controller->ClearCallbacks(); - - /*-----------------------------------------------------*\ - | Find the controller to remove and remove it from the | - | master list | - \*-----------------------------------------------------*/ - std::vector::iterator rgb_it = std::find(rgb_controllers.begin(), rgb_controllers.end(), rgb_controller); - - if(rgb_it != rgb_controllers.end()) + if(register_controller) { - rgb_controllers.erase(rgb_it); + LOG_INFO("[PluginManager] Registering RGB controller %s", rgb_controller->GetName().c_str()); + + /*-------------------------------------------------*\ + | Add the new controller to the list | + \*-------------------------------------------------*/ + rgb_controllers.push_back(rgb_controller); } - /*-----------------------------------------------------*\ - | Signal device list update in ResourceManager | - \*-----------------------------------------------------*/ - ResourceManager::get()->UpdateDeviceList(); + return(rgb_controller); } -void OpenRGBPluginAPI::UnregisterRGBControllerInThread(RGBController * rgb_controller) +void OpenRGBPluginAPI::UpdateVirtualRGBControllerZone(RGBControllerInterface* rgb_controller, int zone_idx, zone updated_zone) { - /*-----------------------------------------------------*\ - | To avoid deadlocks if this is called from a UI thread | - | run the unregister operation in a background thread. | - \*-----------------------------------------------------*/ - std::thread unregister_thread(CallUnregisterRGBController, this, rgb_controller); - unregister_thread.detach(); + if(rgb_controller) + { + ((RGBController_Virtual*)rgb_controller)->UpdateVirtualZone(zone_idx, updated_zone); + } +} + +void OpenRGBPluginAPI::DeleteVirtualRGBController(RGBControllerInterface* rgb_controller) +{ + delete (RGBController*)rgb_controller; } /*---------------------------------------------------------*\ @@ -164,9 +118,9 @@ void OpenRGBPluginAPI::WaitForDetection() resource_manager->WaitForDetection(); } -std::vector & OpenRGBPluginAPI::GetRGBControllers() +std::vector OpenRGBPluginAPI::GetRGBControllers() { - return(resource_manager->GetRGBControllers()); + return(resource_manager->GetRGBControllerInterfaces()); } /*---------------------------------------------------------*\ diff --git a/OpenRGBPluginAPI.h b/OpenRGBPluginAPI.h index 4ee5f704f..f24e98ed9 100644 --- a/OpenRGBPluginAPI.h +++ b/OpenRGBPluginAPI.h @@ -26,50 +26,49 @@ public: /*-----------------------------------------------------*\ | LogManager APIs | \*-----------------------------------------------------*/ - void LogEntry(const char* filename, int line, unsigned int level, const char* fmt, ...); + void LogEntry(const char* filename, int line, unsigned int level, const char* fmt, ...); /*-----------------------------------------------------*\ | PluginManager APIs | \*-----------------------------------------------------*/ - void RegisterRGBController(RGBController * rgb_controller); - void RegisterRGBControllerInThread(RGBController * rgb_controller); - void UnregisterRGBController(RGBController * rgb_controller); - void UnregisterRGBControllerInThread(RGBController * rgb_controller); + RGBControllerInterface* CreateVirtualRGBController(RGBController_Setup* setup, bool register_controller = false); + void UpdateVirtualRGBControllerZone(RGBControllerInterface* rgb_controller, int zone_idx, zone updated_zone); + void DeleteVirtualRGBController(RGBControllerInterface* rgb_controller); /*-----------------------------------------------------*\ | ProfileManager APIs | \*-----------------------------------------------------*/ - void ClearActiveProfile(); - std::vector GetProfileList(); - bool LoadProfile(std::string profile_name); + void ClearActiveProfile(); + std::vector GetProfileList(); + bool LoadProfile(std::string profile_name); /*-----------------------------------------------------*\ | ResourceManager APIs | \*-----------------------------------------------------*/ - filesystem::path GetConfigurationDirectory(); - bool GetDetectionEnabled(); - unsigned int GetDetectionPercent(); - std::string GetDetectionString(); - void RescanDevices(); - void WaitForDetection(); - std::vector & GetRGBControllers(); + filesystem::path GetConfigurationDirectory(); + bool GetDetectionEnabled(); + unsigned int GetDetectionPercent(); + std::string GetDetectionString(); + void RescanDevices(); + void WaitForDetection(); + std::vector GetRGBControllers(); /*-----------------------------------------------------*\ | SettingsManager APIs | \*-----------------------------------------------------*/ - nlohmann::json GetSettings(std::string settings_key); - void SaveSettings(); - void SetSettings(std::string settings_key, nlohmann::json new_settings); + nlohmann::json GetSettings(std::string settings_key); + void SaveSettings(); + void SetSettings(std::string settings_key, nlohmann::json new_settings); /*-----------------------------------------------------*\ | RGBControllers registered by plugin | \*-----------------------------------------------------*/ - std::vector rgb_controllers; + std::vector rgb_controllers; private: - LogManager * log_manager; - PluginManagerInterface * plugin_manager; - ProfileManager * profile_manager; - ResourceManager * resource_manager; - SettingsManager * settings_manager; + LogManager * log_manager; + PluginManagerInterface * plugin_manager; + ProfileManager * profile_manager; + ResourceManager * resource_manager; + SettingsManager * settings_manager; }; diff --git a/OpenRGBPluginInterface.h b/OpenRGBPluginInterface.h index ca2460f26..5491fabbf 100644 --- a/OpenRGBPluginInterface.h +++ b/OpenRGBPluginInterface.h @@ -15,11 +15,11 @@ #include #include #include -#include "nlohmann/json.hpp" +#include #include "filesystem.h" -#include "RGBController.h" +#include "RGBControllerInterface.h" -#define OpenRGBPluginInterface_IID "com.OpenRGBPluginInterface" +#define OpenRGBPluginInterface_IID "org.openrgb.OpenRGBPluginInterface" /*-----------------------------------------------------------------------------------------------------*\ | OpenRGB Plugin API Versions | @@ -77,71 +77,70 @@ public: /*-----------------------------------------------------*\ | LogManager APIs | \*-----------------------------------------------------*/ - virtual void LogEntry(const char* filename, int line, unsigned int level, const char* fmt, ...) = 0; + virtual void LogEntry(const char* filename, int line, unsigned int level, const char* fmt, ...) = 0; /*-----------------------------------------------------*\ | PluginManager APIs | \*-----------------------------------------------------*/ - virtual void RegisterRGBController(RGBController * controller) = 0; - virtual void RegisterRGBControllerInThread(RGBController * controller) = 0; - virtual void UnregisterRGBController(RGBController * controller) = 0; - virtual void UnregisterRGBControllerInThread(RGBController * controller) = 0; + virtual RGBControllerInterface* CreateVirtualRGBController(RGBController_Setup* setup, bool register_controller = false) = 0; + virtual void UpdateVirtualRGBControllerZone(RGBControllerInterface* rgb_controller, int zone_idx, zone updated_zone) = 0; + virtual void DeleteVirtualRGBController(RGBControllerInterface* rgb_controller) = 0; /*-----------------------------------------------------*\ | ProfileManager APIs | \*-----------------------------------------------------*/ - virtual void ClearActiveProfile() = 0; - virtual std::vector GetProfileList() = 0; - virtual bool LoadProfile(std::string profile_name) = 0; + virtual void ClearActiveProfile() = 0; + virtual std::vector GetProfileList() = 0; + virtual bool LoadProfile(std::string profile_name) = 0; /*-----------------------------------------------------*\ | ResourceManager APIs | \*-----------------------------------------------------*/ - virtual filesystem::path GetConfigurationDirectory() = 0; - virtual bool GetDetectionEnabled() = 0; - virtual unsigned int GetDetectionPercent() = 0; - virtual std::string GetDetectionString() = 0; - virtual void RescanDevices() = 0; - virtual void WaitForDetection() = 0; - virtual std::vector & GetRGBControllers() = 0; + virtual filesystem::path GetConfigurationDirectory() = 0; + virtual bool GetDetectionEnabled() = 0; + virtual unsigned int GetDetectionPercent() = 0; + virtual std::string GetDetectionString() = 0; + virtual void RescanDevices() = 0; + virtual void WaitForDetection() = 0; + virtual std::vector GetRGBControllers() = 0; /*-----------------------------------------------------*\ | SettingsManager APIs | \*-----------------------------------------------------*/ - virtual nlohmann::json GetSettings(std::string settings_key) = 0; - virtual void SaveSettings() = 0; - virtual void SetSettings(std::string settings_key, nlohmann::json new_settings) = 0; + virtual nlohmann::json GetSettings(std::string settings_key) = 0; + virtual void SaveSettings() = 0; + virtual void SetSettings(std::string settings_key, nlohmann::json new_settings) = 0; }; class OpenRGBPluginInterface { public: - virtual ~OpenRGBPluginInterface() {} + virtual ~OpenRGBPluginInterface() {} /*-----------------------------------------------------*\ | Plugin Information | \*-----------------------------------------------------*/ - virtual OpenRGBPluginInfo GetPluginInfo() = 0; - virtual unsigned int GetPluginAPIVersion() = 0; + virtual OpenRGBPluginInfo GetPluginInfo() = 0; + virtual unsigned int GetPluginAPIVersion() = 0; /*-----------------------------------------------------*\ | Plugin Functionality | \*-----------------------------------------------------*/ - virtual void Load(OpenRGBPluginAPIInterface* plugin_api_ptr) = 0; - virtual QWidget* GetWidget() = 0; - virtual QMenu* GetTrayMenu() = 0; - virtual void Unload() = 0; - virtual void OnProfileAboutToLoad() = 0; - virtual void OnProfileLoad(nlohmann::json profile_data) = 0; - virtual nlohmann::json OnProfileSave() = 0; - virtual unsigned char* OnSDKCommand(unsigned int pkt_id, unsigned char * pkt_data, unsigned int *pkt_size) = 0; + virtual void Load(OpenRGBPluginAPIInterface* plugin_api_ptr) = 0; + virtual QWidget* GetWidget() = 0; + virtual QMenu* GetTrayMenu() = 0; + virtual void Unload() = 0; + virtual void OnProfileAboutToLoad() = 0; + virtual void OnProfileLoad(nlohmann::json profile_data) = 0; + virtual nlohmann::json OnProfileSave() = 0; + virtual unsigned char* OnSDKCommand(unsigned int pkt_id, unsigned char * pkt_data, unsigned int *pkt_size) = 0; /*-----------------------------------------------------*\ | Update Signals | \*-----------------------------------------------------*/ - virtual void ProfileManagerUpdated(unsigned int update_reason) = 0; - virtual void ResourceManagerUpdated(unsigned int update_reason) = 0; - virtual void SettingsManagerUpdated(unsigned int update_reason) = 0; + virtual void ProfileManagerUpdated(unsigned int update_reason) = 0; + virtual void ResourceManagerUpdated(unsigned int update_reason) = 0; + virtual void SettingsManagerUpdated(unsigned int update_reason) = 0; }; Q_DECLARE_INTERFACE(OpenRGBPluginInterface, OpenRGBPluginInterface_IID) diff --git a/PluginManager.cpp b/PluginManager.cpp index bde51893b..3f6f5423d 100644 --- a/PluginManager.cpp +++ b/PluginManager.cpp @@ -18,6 +18,11 @@ #include #endif +/*---------------------------------------------------------*\ +| PluginManager name for log entries | +\*---------------------------------------------------------*/ +const char* PLUGINMANAGER = "PluginManager"; + void PluginManagerProfileManagerCallback(void * this_ptr, unsigned int update_reason) { PluginManager * this_obj = (PluginManager *)this_ptr; @@ -88,35 +93,36 @@ void PluginManager::RegisterRemovePluginCallback(RemovePluginCallback new_callba void PluginManager::ScanAndLoadPlugins() { - /*---------------------------------------------------------*\ - | Get the user plugins directory | - | | - | The user plugins directory is a directory named "plugins" | - | in the configuration directory | - \*---------------------------------------------------------*/ + /*-----------------------------------------------------*\ + | Get the user plugins directory | + | | + | The user plugins directory is a directory named | + | "plugins" in the configuration directory | + \*-----------------------------------------------------*/ filesystem::path plugins_dir = ResourceManager::get()->GetConfigurationDirectory() / plugins_path; ScanAndLoadPluginsFrom(plugins_dir, false); #ifdef OPENRGB_SYSTEM_PLUGIN_DIRECTORY - /*---------------------------------------------------------*\ - | Get the system plugins directory | - | | - | The system plugin directory can be set during build time, | - | e.g. by the package maintainer to load plugins installed | - | via package manager | - \*---------------------------------------------------------*/ + /*-----------------------------------------------------*\ + | Get the system plugins directory | + | | + | The system plugin directory can be set during build | + | time, e.g. by the package maintainer to load plugins | + | installed via package manager | + \*-----------------------------------------------------*/ ScanAndLoadPluginsFrom(OPENRGB_SYSTEM_PLUGIN_DIRECTORY, true); #endif #ifdef _WIN32 - /*---------------------------------------------------------*\ - | Get the exe folder plugins directory (Windows) | - | | - | On Windows, system plugins are located in a folder called | - | "plugins" inside the folder where the OpenRGB.exe file is | - | installed. Typically, C:\Program Files\OpenRGB but other | - | install paths are allowed. | - \*---------------------------------------------------------*/ + /*-----------------------------------------------------*\ + | Get the exe folder plugins directory (Windows) | + | | + | On Windows, system plugins are located in a folder | + | called "plugins" inside the folder where the | + | OpenRGB.exe file is installed. Typically, | + | C:\Program Files\OpenRGB but other install paths are | + | allowed. | + \*-----------------------------------------------------*/ char path[MAX_PATH]; GetModuleFileName(NULL, path, MAX_PATH); @@ -131,11 +137,11 @@ void PluginManager::ScanAndLoadPluginsFrom(const filesystem::path & plugins_dir, { if(is_system) { - LOG_TRACE("[PluginManager] Scanning system plugin directory: %s", plugins_dir.generic_u8string().c_str()); + LOG_TRACE("[%s] Scanning system plugin directory: %s", PLUGINMANAGER, plugins_dir.generic_u8string().c_str()); } else { - LOG_TRACE("[PluginManager] Scanning user plugin directory: %s", plugins_dir.generic_u8string().c_str()); + LOG_TRACE("[%s] Scanning user plugin directory: %s", PLUGINMANAGER, plugins_dir.generic_u8string().c_str()); } if(!filesystem::is_directory(plugins_dir)) @@ -143,10 +149,9 @@ void PluginManager::ScanAndLoadPluginsFrom(const filesystem::path & plugins_dir, return; } - /*---------------------------------------------------------*\ - | Get a list of all files in the plugins directory | - \*---------------------------------------------------------*/ - + /*-----------------------------------------------------*\ + | Get a list of all files in the plugins directory | + \*-----------------------------------------------------*/ for(const filesystem::directory_entry& entry: filesystem::directory_iterator(plugins_dir)) { if(filesystem::is_directory(entry.path())) @@ -155,42 +160,40 @@ void PluginManager::ScanAndLoadPluginsFrom(const filesystem::path & plugins_dir, } filesystem::path plugin_path = entry.path(); - LOG_TRACE("[PluginManager] Found plugin file %s", plugin_path.filename().generic_u8string().c_str()); + LOG_TRACE("[%s] Found plugin file %s", PLUGINMANAGER, plugin_path.filename().generic_u8string().c_str()); AddPlugin(plugin_path, is_system); } } void PluginManager::AddPlugin(const filesystem::path& path, bool is_system) { - OpenRGBPluginInterface* plugin = nullptr; + /*-----------------------------------------------------*\ + | Prepare variables and open plugin settings | + \*-----------------------------------------------------*/ + OpenRGBPluginInterface* plugin = nullptr; + unsigned int plugin_idx; + json plugin_settings = ResourceManager::get()->GetSettingsManager()->GetSettings("Plugins"); - unsigned int plugin_idx; - - /*---------------------------------------------------------------------*\ - | Open plugin settings | - \*---------------------------------------------------------------------*/ - json plugin_settings = ResourceManager::get()->GetSettingsManager()->GetSettings("Plugins"); - - /*---------------------------------------------------------------------*\ - | Check if this plugin is on the remove list | - \*---------------------------------------------------------------------*/ + /*-----------------------------------------------------*\ + | Remove this plugin if it is on the remove list | + \*-----------------------------------------------------*/ if(plugin_settings.contains("plugins_remove")) { - for(unsigned int plugin_remove_idx = 0; plugin_remove_idx < plugin_settings["plugins_remove"].size(); plugin_remove_idx++) + for(std::size_t plugin_remove_idx = 0; plugin_remove_idx < plugin_settings["plugins_remove"].size(); plugin_remove_idx++) { - LOG_WARNING("[PluginManager] Checking remove %d, %s", plugin_remove_idx, to_string(plugin_settings["plugins_remove"][plugin_remove_idx]).c_str()); + LOG_WARNING("[%s] Checking remove %d, %s", PLUGINMANAGER, plugin_remove_idx, to_string(plugin_settings["plugins_remove"][plugin_remove_idx]).c_str()); if(plugin_settings["plugins_remove"][plugin_remove_idx] == path.generic_u8string()) { - /*---------------------------------------------------------*\ - | Delete the plugin file | - \*---------------------------------------------------------*/ + /*-----------------------------------------*\ + | Delete the plugin file | + \*-----------------------------------------*/ filesystem::remove(path); } - /*-----------------------------------------------------------------*\ - | Erase the plugin from the remove list | - \*-----------------------------------------------------------------*/ + /*---------------------------------------------*\ + | Erase the plugin from the remove list | + \*---------------------------------------------*/ plugin_settings["plugins_remove"].erase(plugin_remove_idx); ResourceManager::get()->GetSettingsManager()->SetSettings("Plugins", plugin_settings); @@ -198,183 +201,231 @@ void PluginManager::AddPlugin(const filesystem::path& path, bool is_system) } } - /*---------------------------------------------------------------------*\ - | Search active plugins to see if this path already exists | - \*---------------------------------------------------------------------*/ + /*-----------------------------------------------------*\ + | Search active plugins to see if this path already | + | exists | + \*-----------------------------------------------------*/ for(plugin_idx = 0; plugin_idx < ActivePlugins.size(); plugin_idx++) { if(path == ActivePlugins[plugin_idx].path) { - break; + LOG_WARNING("[%s] Plugin file %s already in list, skipping.", PLUGINMANAGER, path.c_str()); + return; } } - /*---------------------------------------------------------------------*\ - | If the path does not match an existing entry, create a new entry | - \*---------------------------------------------------------------------*/ - if(plugin_idx == ActivePlugins.size()) + /*-----------------------------------------------------*\ + | Create a QPluginLoader and extract the metadata | + \*-----------------------------------------------------*/ + std::string path_string = path.generic_u8string(); + QPluginLoader* loader = new QPluginLoader(QString::fromStdString(path_string)); + QJsonObject metadata = loader->metaData(); + unsigned int plugin_api_version = 0; + QString plugin_commit; + QString plugin_id = "incompatible"; + QString plugin_name = "Incompatible Plugin"; + QString plugin_url; + QString plugin_version; + + if(metadata.contains("MetaData")) { - /*-----------------------------------------------------------------*\ - | Create a QPluginLoader and load the plugin | - \*-----------------------------------------------------------------*/ - std::string path_string = path.generic_u8string(); - QPluginLoader* loader = new QPluginLoader(QString::fromStdString(path_string)); - QObject* instance = loader->instance(); + metadata = metadata.value("MetaData").toObject(); + } + else + { + LOG_WARNING("[%s] Plugin %s does not have a MetaData field, skipping.", PLUGINMANAGER, path.c_str()); + return; + } + + if(metadata.contains("OpenRGBPluginAPIVersion")) + { + plugin_api_version = metadata.value("OpenRGBPluginAPIVersion").toInt(); + } + else + { + LOG_WARNING("[%s] Plugin %s does not have an OpenRGBPluginAPIVersion field, skipping.", PLUGINMANAGER, path.c_str()); + return; + } + + if(metadata.contains("Id")) + { + plugin_id = metadata.value("Id").toString(); + } + else + { + LOG_WARNING("[%s] Plugin %s does not have an Id field, skipping.", PLUGINMANAGER, path.c_str()); + return; + } + + if(metadata.contains("Commit")) + { + plugin_commit = metadata.value("Commit").toString(); + } + + if(metadata.contains("Name")) + { + plugin_name = metadata.value("Name").toString(); + } + + if(metadata.contains("Url")) + { + plugin_url = metadata.value("Url").toString(); + } + + if(metadata.contains("VersionStr")) + { + plugin_version = metadata.value("VersionStr").toString(); + } + + /*-----------------------------------------------------*\ + | Create a new plugin entry to add to the list | + \*-----------------------------------------------------*/ + OpenRGBPluginEntry entry; + + entry.api = new OpenRGBPluginAPI(); + entry.api_version = plugin_api_version; + entry.enabled = false; + entry.info.Commit = plugin_commit.toStdString(); + entry.info.Description = "This plugin is not compatible with this version of OpenRGB."; + entry.info.Name = plugin_name.toStdString(); + entry.info.URL = plugin_url.toStdString(); + entry.info.Version = plugin_version.toStdString(); + entry.id = plugin_id; + entry.incompatible = (plugin_api_version == OPENRGB_PLUGIN_API_VERSION); + entry.is_system = is_system; + entry.loader = loader; + entry.path = path_string; + entry.plugin = plugin; + entry.widget = nullptr; + + /*-----------------------------------------------------*\ + | Check to see if this plugin's ID already exists | + \*-----------------------------------------------------*/ + for(plugin_idx = 0; plugin_idx < ActivePlugins.size(); plugin_idx++) + { + if(plugin_id == ActivePlugins[plugin_idx].id) + { + entry.info.Description = "This plugin has a duplicate ID as an already loaded plugin and cannot be loaded."; + LOG_WARNING("[%s] Plugin ID %s already in list.", PLUGINMANAGER, plugin_id.toStdString().c_str()); + goto add_plugin_entry; + } + } + + /*-----------------------------------------------------*\ + | If metadata indicates a matching API version, | + | continue loading | + \*-----------------------------------------------------*/ + if(plugin_api_version == OPENRGB_PLUGIN_API_VERSION) + { + QObject* instance = loader->instance(); if(!loader->isLoaded()) { - LOG_WARNING("[PluginManager] Plugin %s cannot be loaded: %s", path.c_str(), loader->errorString().toStdString().c_str()); + LOG_WARNING("[%s] Plugin %s cannot be loaded: %s", PLUGINMANAGER, path.c_str(), loader->errorString().toStdString().c_str()); + goto add_plugin_entry; } - /*-----------------------------------------------------------------*\ - | Check that the plugin is valid, then check the API version | - \*-----------------------------------------------------------------*/ - if(instance) + if(!instance) { - plugin = qobject_cast(instance); + LOG_WARNING("[%s] Plugin %s cannot be instantiated.", PLUGINMANAGER, path.c_str()); + goto add_plugin_entry; + } - if(plugin) + /*-------------------------------------------------*\ + | Initialize the plugin pointer | + \*-------------------------------------------------*/ + plugin = qobject_cast(instance); + + if(!plugin) + { + LOG_WARNING("[%s] Plugin %s cannot be casted to OpenRGBPluginInterface", PLUGINMANAGER, path.c_str()); + goto add_plugin_entry; + } + + if(plugin->GetPluginAPIVersion() != OPENRGB_PLUGIN_API_VERSION) + { + LOG_WARNING("[%s] Plugin %s has a compatible API version", PLUGINMANAGER, path.c_str()); + goto add_plugin_entry; + } + + /*-------------------------------------------------*\ + | Get the plugin information | + \*-------------------------------------------------*/ + OpenRGBPluginInfo info = plugin->GetPluginInfo(); + + /*-------------------------------------------------*\ + | Search the settings to see if it is enabled | + \*-------------------------------------------------*/ + std::string name = ""; + std::string description = ""; + bool enabled = true; + bool found = false; + unsigned int plugin_ct = 0; + + if(plugin_settings.contains("plugins")) + { + plugin_ct = (unsigned int)plugin_settings["plugins"].size(); + + for(unsigned int plugin_settings_idx = 0; plugin_settings_idx < plugin_settings["plugins"].size(); plugin_settings_idx++) { - if(plugin->GetPluginAPIVersion() == OPENRGB_PLUGIN_API_VERSION) + if(plugin_settings["plugins"][plugin_settings_idx].contains("name")) { - LOG_TRACE("[PluginManager] Plugin %s has a compatible API version", path.c_str()); - - /*-----------------------------------------------------*\ - | Get the plugin information | - \*-----------------------------------------------------*/ - OpenRGBPluginInfo info = plugin->GetPluginInfo(); - - /*-----------------------------------------------------*\ - | Search the settings to see if it is enabled | - \*-----------------------------------------------------*/ - std::string name = ""; - std::string description = ""; - bool enabled = true; - bool found = false; - unsigned int plugin_ct = 0; - - if(plugin_settings.contains("plugins")) - { - plugin_ct = (unsigned int)plugin_settings["plugins"].size(); - - for(unsigned int plugin_settings_idx = 0; plugin_settings_idx < plugin_settings["plugins"].size(); plugin_settings_idx++) - { - if(plugin_settings["plugins"][plugin_settings_idx].contains("name")) - { - name = plugin_settings["plugins"][plugin_settings_idx]["name"]; - } - - if(plugin_settings["plugins"][plugin_settings_idx].contains("description")) - { - description = plugin_settings["plugins"][plugin_settings_idx]["description"]; - } - - if(plugin_settings["plugins"][plugin_settings_idx].contains("enabled")) - { - enabled = plugin_settings["plugins"][plugin_settings_idx]["enabled"]; - } - - if((info.Name == name) - &&(info.Description == description)) - { - found = true; - break; - } - } - } - - /*-----------------------------------------------------*\ - | If the plugin was not in the list, add it to the list | - | and default it to enabled, then save the settings | - \*-----------------------------------------------------*/ - if(!found) - { - plugin_settings["plugins"][plugin_ct]["name"] = info.Name; - plugin_settings["plugins"][plugin_ct]["description"] = info.Description; - plugin_settings["plugins"][plugin_ct]["enabled"] = enabled; - - ResourceManager::get()->GetSettingsManager()->SetSettings("Plugins", plugin_settings); - ResourceManager::get()->GetSettingsManager()->SaveSettings(); - } - - LOG_VERBOSE("[PluginManager] Loaded plugin %s", info.Name.c_str()); - - /*-----------------------------------------------------*\ - | Add the plugin to the PluginManager active plugins | - \*-----------------------------------------------------*/ - OpenRGBPluginEntry entry; - - entry.info = info; - entry.plugin = plugin; - entry.api = new OpenRGBPluginAPI(); - entry.loader = loader; - entry.path = path_string; - entry.enabled = enabled; - entry.widget = nullptr; - entry.incompatible = false; - entry.api_version = plugin->GetPluginAPIVersion(); - entry.is_system = is_system; - - loader->unload(); - - ActivePlugins.push_back(entry); - - if(entry.enabled) - { - LoadPlugin(&ActivePlugins.back()); - } + name = plugin_settings["plugins"][plugin_settings_idx]["name"]; } - else + + if(plugin_settings["plugins"][plugin_settings_idx].contains("description")) { - /*-----------------------------------------------------*\ - | Fill in a plugin information object with text showing | - | the plugin is incompatible | - \*-----------------------------------------------------*/ - OpenRGBPluginInfo info; + description = plugin_settings["plugins"][plugin_settings_idx]["description"]; + } - info.Name = "Incompatible Plugin"; - info.Description = "This plugin is not compatible with this version of OpenRGB."; + if(plugin_settings["plugins"][plugin_settings_idx].contains("enabled")) + { + enabled = plugin_settings["plugins"][plugin_settings_idx]["enabled"]; + } - /*-----------------------------------------------------*\ - | Add the plugin to the PluginManager active plugins | - | but mark it as incompatible | - \*-----------------------------------------------------*/ - OpenRGBPluginEntry entry; - - entry.info = info; - entry.plugin = plugin; - entry.api = new OpenRGBPluginAPI(); - entry.loader = loader; - entry.path = path_string; - entry.enabled = false; - entry.widget = nullptr; - entry.incompatible = true; - entry.api_version = plugin->GetPluginAPIVersion(); - entry.is_system = is_system; - - loader->unload(); - - PluginManager::ActivePlugins.push_back(entry); - - bool unloaded = loader->unload(); - - LOG_WARNING("[PluginManager] Plugin %s has an incompatible API version", path.c_str()); - - if(!unloaded) - { - LOG_WARNING("[PluginManager] Plugin %s cannot be unloaded", path.c_str()); - } + if((info.Name == name) + &&(info.Description == description)) + { + found = true; + break; } } - else - { - LOG_WARNING("[PluginManager] Plugin %s cannot be casted to OpenRGBPluginInterface", path.c_str()); - } } - else + + /*-------------------------------------------------*\ + | If the plugin was not in the list, add it to the | + | list and default it to enabled, then save the | + | settings | + \*-------------------------------------------------*/ + if(!found) { - LOG_WARNING("[PluginManager] Plugin %s cannot be instantiated.", path.c_str()); + plugin_settings["plugins"][plugin_ct]["name"] = info.Name; + plugin_settings["plugins"][plugin_ct]["description"] = info.Description; + plugin_settings["plugins"][plugin_ct]["enabled"] = enabled; + + ResourceManager::get()->GetSettingsManager()->SetSettings("Plugins", plugin_settings); + ResourceManager::get()->GetSettingsManager()->SaveSettings(); } + + LOG_VERBOSE("[%s] Loaded plugin %s", PLUGINMANAGER, info.Name.c_str()); + + /*-----------------------------------------------------*\ + | Add the plugin to the PluginManager active plugins | + \*-----------------------------------------------------*/ + entry.enabled = enabled; + entry.info = info; + entry.incompatible = false; + entry.api_version = plugin->GetPluginAPIVersion(); + } + +add_plugin_entry: + loader->unload(); + + ActivePlugins.push_back(entry); + + if(entry.enabled) + { + LoadPlugin(&ActivePlugins.back()); } } @@ -382,11 +433,12 @@ void PluginManager::RemovePlugin(const filesystem::path& path) { unsigned int plugin_idx; - LOG_TRACE("[PluginManager] Attempting to remove plugin %s", path.c_str()); + LOG_TRACE("[%s] Attempting to remove plugin %s", PLUGINMANAGER, path.c_str()); - /*---------------------------------------------------------------------*\ - | Search active plugins to see if this path already exists | - \*---------------------------------------------------------------------*/ + /*-----------------------------------------------------*\ + | Search active plugins to see if this path already | + | exists | + \*-----------------------------------------------------*/ for(plugin_idx = 0; plugin_idx < ActivePlugins.size(); plugin_idx++) { if(path == ActivePlugins[plugin_idx].path) @@ -395,27 +447,29 @@ void PluginManager::RemovePlugin(const filesystem::path& path) } } - /*---------------------------------------------------------------------*\ - | If the plugin path does not exist in the active plugins list, return | - \*---------------------------------------------------------------------*/ + /*-----------------------------------------------------*\ + | If the plugin path does not exist in the active | + | plugins list, return | + \*-----------------------------------------------------*/ if(plugin_idx == ActivePlugins.size()) { - LOG_TRACE("[PluginManager] Plugin %s not active", path.c_str()); + LOG_TRACE("[%s] Plugin %s not active", PLUGINMANAGER, path.c_str()); return; } - /*---------------------------------------------------------------------*\ - | If the selected plugin is in the list and loaded, unload it | - \*---------------------------------------------------------------------*/ + /*-----------------------------------------------------*\ + | If the selected plugin is in the list and loaded, | + | unload it | + \*-----------------------------------------------------*/ if(ActivePlugins[plugin_idx].loader->isLoaded()) { - LOG_TRACE("[PluginManager] Plugin %s is active, unloading", path.c_str()); + LOG_TRACE("[%s] Plugin %s is active, unloading", PLUGINMANAGER, path.c_str()); UnloadPlugin(&ActivePlugins[plugin_idx]); } - /*---------------------------------------------------------------------*\ - | Remove the plugin from the active plugins list | - \*---------------------------------------------------------------------*/ + /*-----------------------------------------------------*\ + | Remove the plugin from the active plugins list | + \*-----------------------------------------------------*/ ActivePlugins.erase(ActivePlugins.begin() + plugin_idx); } @@ -423,9 +477,10 @@ void PluginManager::EnablePlugin(const filesystem::path& path) { unsigned int plugin_idx; - /*---------------------------------------------------------------------*\ - | Search active plugins to see if this path already exists | - \*---------------------------------------------------------------------*/ + /*-----------------------------------------------------*\ + | Search active plugins to see if this path already | + | exists | + \*-----------------------------------------------------*/ for(plugin_idx = 0; plugin_idx < ActivePlugins.size(); plugin_idx++) { if(path == ActivePlugins[plugin_idx].path) @@ -434,9 +489,10 @@ void PluginManager::EnablePlugin(const filesystem::path& path) } } - /*---------------------------------------------------------------------*\ - | If the plugin path does not exist in the active plugins list, return | - \*---------------------------------------------------------------------*/ + /*-----------------------------------------------------*\ + | If the plugin path does not exist in the active | + | plugins list, return | + \*-----------------------------------------------------*/ if(plugin_idx == ActivePlugins.size()) { return; @@ -448,17 +504,19 @@ void PluginManager::EnablePlugin(const filesystem::path& path) void PluginManager::LoadPlugin(OpenRGBPluginEntry* plugin_entry) { - /*---------------------------------------------------------------------*\ - | If the plugin is in the list but is incompatible, return | - \*---------------------------------------------------------------------*/ + /*-----------------------------------------------------*\ + | If the plugin is in the list but is incompatible, | + | return | + \*-----------------------------------------------------*/ if(plugin_entry->incompatible) { return; } - /*---------------------------------------------------------------------*\ - | If the selected plugin is in the list but not loaded, load it | - \*---------------------------------------------------------------------*/ + /*-----------------------------------------------------*\ + | If the selected plugin is in the list but not loaded, | + | load it | + \*-----------------------------------------------------*/ if(!plugin_entry->loader->isLoaded()) { plugin_entry->loader->load(); @@ -477,9 +535,9 @@ void PluginManager::LoadPlugin(OpenRGBPluginEntry* plugin_entry) plugin->Load(plugin_entry->api); - /*-------------------------------------------------*\ - | Call the Add Plugin callback | - \*-------------------------------------------------*/ + /*-------------------------------------*\ + | Call the Add Plugin callback | + \*-------------------------------------*/ if(AddPluginCallbackArg != nullptr) { AddPluginCallbackVal(AddPluginCallbackArg, plugin_entry); @@ -494,9 +552,10 @@ void PluginManager::DisablePlugin(const filesystem::path& path) { unsigned int plugin_idx; - /*---------------------------------------------------------------------*\ - | Search active plugins to see if this path already exists | - \*---------------------------------------------------------------------*/ + /*-----------------------------------------------------*\ + | Search active plugins to see if this path already | + | exists | + \*-----------------------------------------------------*/ for(plugin_idx = 0; plugin_idx < ActivePlugins.size(); plugin_idx++) { if(path == ActivePlugins[plugin_idx].path) @@ -505,9 +564,10 @@ void PluginManager::DisablePlugin(const filesystem::path& path) } } - /*---------------------------------------------------------------------*\ - | If the plugin path does not exist in the active plugins list, return | - \*---------------------------------------------------------------------*/ + /*-----------------------------------------------------*\ + | If the plugin path does not exist in the active | + | plugins list, return | + \*-----------------------------------------------------*/ if(plugin_idx == ActivePlugins.size()) { return; @@ -519,9 +579,10 @@ void PluginManager::DisablePlugin(const filesystem::path& path) void PluginManager::UnloadPlugin(OpenRGBPluginEntry* plugin_entry) { - /*---------------------------------------------------------------------*\ - | If the selected plugin is in the list and loaded, unload it | - \*---------------------------------------------------------------------*/ + /*-----------------------------------------------------*\ + | If the selected plugin is in the list and loaded, | + | unload it | + \*-----------------------------------------------------*/ if(plugin_entry->loader->isLoaded()) { /*-------------------------------------------------*\ @@ -541,16 +602,16 @@ void PluginManager::UnloadPlugin(OpenRGBPluginEntry* plugin_entry) if(!unloaded) { - LOG_WARNING("[PluginManager] Plugin %s cannot be unloaded", plugin_entry->path.c_str()); + LOG_WARNING("[%s] Plugin %s cannot be unloaded", PLUGINMANAGER, plugin_entry->path.c_str()); } else { - LOG_TRACE("[PluginManager] Plugin %s successfully unloaded", plugin_entry->path.c_str()); + LOG_TRACE("[%s] Plugin %s successfully unloaded", PLUGINMANAGER, plugin_entry->path.c_str()); } } else { - LOG_TRACE("[PluginManager] Plugin %s was already unloaded", plugin_entry->path.c_str()); + LOG_TRACE("[%s] Plugin %s was already unloaded", PLUGINMANAGER, plugin_entry->path.c_str()); } } diff --git a/PluginManager.h b/PluginManager.h index 2df15bc3f..c0f949110 100644 --- a/PluginManager.h +++ b/PluginManager.h @@ -17,12 +17,14 @@ #include #include "OpenRGBPluginInterface.h" #include "PluginManagerInterface.h" +#include "RGBController.h" struct OpenRGBPluginEntry { OpenRGBPluginInfo info; OpenRGBPluginInterface* plugin; OpenRGBPluginAPIInterface* api; + QString id; QPluginLoader* loader; QWidget* widget; QMenu* traymenu; diff --git a/PluginManagerInterface.h b/PluginManagerInterface.h index 2ee292c84..b571bae38 100644 --- a/PluginManagerInterface.h +++ b/PluginManagerInterface.h @@ -12,7 +12,8 @@ #pragma once #include -#include "nlohmann/json.hpp" +#include +#include "RGBController.h" class PluginManagerInterface { diff --git a/RGBController/RGBController.cpp b/RGBController/RGBController.cpp index 3a677c595..3974c94ec 100644 --- a/RGBController/RGBController.cpp +++ b/RGBController/RGBController.cpp @@ -10,8 +10,6 @@ | SPDX-License-Identifier: GPL-2.0-or-later | \*---------------------------------------------------------*/ -#include -#include "nlohmann/json.hpp" #include "LogManager.h" #include "RGBController.h" #include "StringUtils.h" @@ -70,104 +68,6 @@ using namespace std::chrono_literals; -matrix_map_type::matrix_map_type() -{ - Reset(); -} - -matrix_map_type::matrix_map_type(unsigned int height, unsigned int width, unsigned int * map) -{ - Set(height, width, map); -} - -matrix_map_type::~matrix_map_type() -{ -} - -void matrix_map_type::Reset() -{ - Set(0, 0, NULL); -} - -void matrix_map_type::Set(unsigned int height, unsigned int width, unsigned int * map) -{ - this->height = height; - this->width = width; - this->map.resize(height * width); - - if(map != NULL) - { - memcpy(this->map.data(), map, (height * width * sizeof(unsigned int))); - } - else - { - memset(this->map.data(), 0, (height * width * sizeof(unsigned int))); - } -} - -mode::mode() -{ - /*-----------------------------------------------------*\ - | Initialize mode variables | - \*-----------------------------------------------------*/ - name = ""; - value = 0; - flags = 0; - speed_min = 0; - speed_max = 0; - brightness_min = 0; - brightness_max = 0; - colors_min = 0; - colors_max = 0; - speed = 0; - brightness = 0; - direction = 0; - color_mode = 0; -} - -mode::~mode() -{ - colors.clear(); -} - -segment::segment() -{ - /*-----------------------------------------------------*\ - | Initialize zone variables | - \*-----------------------------------------------------*/ - name = ""; - type = 0; - start_idx = 0; - leds_count = 0; - flags = 0; -} - -segment::~segment() -{ -} - -zone::zone() -{ - /*-----------------------------------------------------*\ - | Initialize zone variables | - \*-----------------------------------------------------*/ - name = ""; - type = 0; - leds = NULL; - colors = NULL; - start_idx = 0; - leds_count = 0; - leds_min = 0; - leds_max = 0; - flags = 0; - active_mode = -1; -} - -zone::~zone() -{ - segments.clear(); -} - RGBController::RGBController() { /*-----------------------------------------------------*\ @@ -4384,56 +4284,53 @@ zone RGBController::SetZoneDescriptionJSON(nlohmann::json zone_json) return(new_zone); } -/*---------------------------------------------------------*\ -| Non-class functions | -\*---------------------------------------------------------*/ -std::string device_type_to_str(device_type type) +std::string RGBController::DeviceTypeToString(device_type type) { switch(type) { - case DEVICE_TYPE_MOTHERBOARD: - return "Motherboard"; - case DEVICE_TYPE_DRAM: - return "DRAM"; - case DEVICE_TYPE_GPU: - return "GPU"; - case DEVICE_TYPE_COOLER: - return "Cooler"; - case DEVICE_TYPE_LEDSTRIP: - return "LED Strip"; - case DEVICE_TYPE_KEYBOARD: - return "Keyboard"; - case DEVICE_TYPE_MOUSE: - return "Mouse"; - case DEVICE_TYPE_MOUSEMAT: - return "Mousemat"; - case DEVICE_TYPE_HEADSET: - return "Headset"; - case DEVICE_TYPE_HEADSET_STAND: - return "Headset Stand"; - case DEVICE_TYPE_GAMEPAD: - return "Gamepad"; - case DEVICE_TYPE_LIGHT: - return "Light"; - case DEVICE_TYPE_SPEAKER: - return "Speaker"; - case DEVICE_TYPE_VIRTUAL: - return "Virtual"; - case DEVICE_TYPE_STORAGE: - return "Storage"; - case DEVICE_TYPE_CASE: - return "Case"; - case DEVICE_TYPE_MICROPHONE: - return "Microphone"; - case DEVICE_TYPE_ACCESSORY: - return "Accessory"; - case DEVICE_TYPE_KEYPAD: - return "Keypad"; - case DEVICE_TYPE_LAPTOP: - return "Laptop"; - case DEVICE_TYPE_MONITOR: - return "Monitor"; - default: - return "Unknown"; + case DEVICE_TYPE_MOTHERBOARD: + return "Motherboard"; + case DEVICE_TYPE_DRAM: + return "DRAM"; + case DEVICE_TYPE_GPU: + return "GPU"; + case DEVICE_TYPE_COOLER: + return "Cooler"; + case DEVICE_TYPE_LEDSTRIP: + return "LED Strip"; + case DEVICE_TYPE_KEYBOARD: + return "Keyboard"; + case DEVICE_TYPE_MOUSE: + return "Mouse"; + case DEVICE_TYPE_MOUSEMAT: + return "Mousemat"; + case DEVICE_TYPE_HEADSET: + return "Headset"; + case DEVICE_TYPE_HEADSET_STAND: + return "Headset Stand"; + case DEVICE_TYPE_GAMEPAD: + return "Gamepad"; + case DEVICE_TYPE_LIGHT: + return "Light"; + case DEVICE_TYPE_SPEAKER: + return "Speaker"; + case DEVICE_TYPE_VIRTUAL: + return "Virtual"; + case DEVICE_TYPE_STORAGE: + return "Storage"; + case DEVICE_TYPE_CASE: + return "Case"; + case DEVICE_TYPE_MICROPHONE: + return "Microphone"; + case DEVICE_TYPE_ACCESSORY: + return "Accessory"; + case DEVICE_TYPE_KEYPAD: + return "Keypad"; + case DEVICE_TYPE_LAPTOP: + return "Laptop"; + case DEVICE_TYPE_MONITOR: + return "Monitor"; + default: + return "Unknown"; } } diff --git a/RGBController/RGBController.h b/RGBController/RGBController.h index 430002a13..1d969544c 100644 --- a/RGBController/RGBController.h +++ b/RGBController/RGBController.h @@ -13,489 +13,11 @@ #pragma once #include -#include -#include #include #include #include #include -#include "nlohmann/json.hpp" - -/*---------------------------------------------------------*\ -| 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))) - -#define RGBToBGRColor(rgb) ((rgb & 0xFF) << 16 | (rgb & 0xFF00) | (rgb & 0xFF0000) >> 16) - -/*---------------------------------------------------------*\ -| 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_FLAG_REQUIRES_ENTIRE_DEVICE = (1 << 10),/* Mode always applies to entire */ - /* device, overrides per-zone modes */ -}; - -/*---------------------------------------------------------*\ -| 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 -{ - /*-----------------------------------------------------*\ - | LED Information | - \*-----------------------------------------------------*/ - std::string name; /* LED name */ - unsigned int value; /* Device-specific LED value */ -} led; - -/*---------------------------------------------------------*\ -| Zone Flags | -\*---------------------------------------------------------*/ -typedef unsigned int zone_flags; - -#define ZONE_FLAGS_MANUALLY_CONFIGURABLE (ZONE_FLAG_MANUALLY_CONFIGURABLE_SIZE_EFFECTS_ONLY | \ - ZONE_FLAG_MANUALLY_CONFIGURABLE_SIZE | \ - ZONE_FLAG_MANUALLY_CONFIGURABLE_NAME | \ - ZONE_FLAG_MANUALLY_CONFIGURABLE_TYPE | \ - ZONE_FLAG_MANUALLY_CONFIGURABLE_MATRIX_MAP | \ - ZONE_FLAG_MANUALLY_CONFIGURABLE_SEGMENTS | \ - ZONE_FLAG_MANUALLY_CONFIGURABLE_DEVICE_SPECIFIC) - -#define ZONE_FLAGS_MANUALLY_CONFIGURED (ZONE_FLAG_MANUALLY_CONFIGURED_SIZE | \ - ZONE_FLAG_MANUALLY_CONFIGURED_NAME | \ - ZONE_FLAG_MANUALLY_CONFIGURED_TYPE | \ - ZONE_FLAG_MANUALLY_CONFIGURED_MATRIX_MAP | \ - ZONE_FLAG_MANUALLY_CONFIGURED_SEGMENTS | \ - ZONE_FLAG_MANUALLY_CONFIGURED_DEVICE_SPECIFIC) -enum -{ - ZONE_FLAG_MANUALLY_CONFIGURABLE_SIZE_EFFECTS_ONLY = (1 << 0), /* Zone size is manually configurable, but only */ - /* for hardware effects, treated as single LED */ - /* for per-LED modes */ - ZONE_FLAG_MANUALLY_CONFIGURABLE_SIZE = (1 << 1), /* Zone size is manually configurable */ - ZONE_FLAG_MANUALLY_CONFIGURABLE_NAME = (1 << 2), /* Zone name is manually configurable */ - ZONE_FLAG_MANUALLY_CONFIGURABLE_TYPE = (1 << 3), /* Zone type is manually configurable */ - ZONE_FLAG_MANUALLY_CONFIGURABLE_MATRIX_MAP = (1 << 4), /* Zone matrix map is manually configurable */ - ZONE_FLAG_MANUALLY_CONFIGURABLE_SEGMENTS = (1 << 5), /* Zone segments are manually configurable */ - ZONE_FLAG_MANUALLY_CONFIGURABLE_DEVICE_SPECIFIC = (1 << 6), /* Zone dev-specific cfg manually configurable */ - ZONE_FLAG_MANUALLY_CONFIGURED_SIZE = (1 << 12),/* Zone size has been manually configured */ - ZONE_FLAG_MANUALLY_CONFIGURED_NAME = (1 << 13),/* Zone name has been manually configured */ - ZONE_FLAG_MANUALLY_CONFIGURED_TYPE = (1 << 14),/* Zone type has been manually configured */ - ZONE_FLAG_MANUALLY_CONFIGURED_MATRIX_MAP = (1 << 15),/* Zone matrix map has been manually configured */ - ZONE_FLAG_MANUALLY_CONFIGURED_SEGMENTS = (1 << 16),/* Zone segments have been manually configured */ - ZONE_FLAG_MANUALLY_CONFIGURED_DEVICE_SPECIFIC = (1 << 17),/* Zone device-specific cfg manually configured */ - ZONE_FLAG_ZONE_GEOMETRY_MAY_CHANGE = (1 << 24),/* Zone geometry may change */ -}; - -/*---------------------------------------------------------*\ -| Zone Types | -\*---------------------------------------------------------*/ -typedef unsigned int zone_type; - -enum -{ - ZONE_TYPE_SINGLE, - ZONE_TYPE_LINEAR, - ZONE_TYPE_MATRIX, - ZONE_TYPE_LINEAR_LOOP, - ZONE_TYPE_MATRIX_LOOP_X, - ZONE_TYPE_MATRIX_LOOP_Y, - ZONE_TYPE_SEGMENTED -}; - -/*---------------------------------------------------------*\ -| Matrix Map Struct | -\*---------------------------------------------------------*/ -class matrix_map_type -{ -public: - unsigned int height; - unsigned int width; - std::vector map; - - matrix_map_type(); - matrix_map_type(unsigned int height, unsigned int width, unsigned int * map); - ~matrix_map_type(); - - void Reset(); - void Set(unsigned int height, unsigned int width, unsigned int * map); -}; - -/*---------------------------------------------------------*\ -| Segment Flags | -\*---------------------------------------------------------*/ -enum -{ - SEGMENT_FLAG_GROUP_START = (1 << 0), /* Start of segment group */ - SEGMENT_FLAG_GROUP_MEMBER = (1 << 1), /* Segment is in group */ -}; - -/*---------------------------------------------------------*\ -| Segment Class | -\*---------------------------------------------------------*/ -class segment -{ -public: - 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*/ - matrix_map_type matrix_map; /* Matrix map */ - unsigned int flags; /* Segment flags */ - - /*-----------------------------------------------------*\ - | Zone Constructor / Destructor | - \*-----------------------------------------------------*/ - segment(); - ~segment(); -}; - -/*---------------------------------------------------------*\ -| Zone Class | -\*---------------------------------------------------------*/ -class zone -{ -public: - 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 */ - std::vector segments; /* Segments in zone */ - zone_flags flags; /* Zone flags bitfield */ - std::vector modes; /* Zone-specific modes */ - int active_mode; /* Active zone-specific mode*/ - - /*-----------------------------------------------------*\ - | Zone Constructor / Destructor | - \*-----------------------------------------------------*/ - 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_LAPTOP, - DEVICE_TYPE_MONITOR, - DEVICE_TYPE_UNKNOWN, -}; - -/*---------------------------------------------------------*\ -| Controller Flags | -\*---------------------------------------------------------*/ -enum -{ - CONTROLLER_FLAG_LOCAL = (1 << 0), /* Device is local to this instance */ - CONTROLLER_FLAG_REMOTE = (1 << 1), /* Device is on a remote instance */ - CONTROLLER_FLAG_VIRTUAL = (1 << 2), /* Device is a virtual device */ - CONTROLLER_FLAG_HIDDEN = (1 << 3), /* Device is hidden */ - - CONTROLLER_FLAG_RESET_BEFORE_UPDATE = (1 << 8), /* Device resets update flag before */ - /* calling update function */ -}; - -/*---------------------------------------------------------*\ -| RGBController Callback Types | -\*---------------------------------------------------------*/ -typedef void (*RGBControllerCallback)(void *, unsigned int, void *); - -/*---------------------------------------------------------*\ -| Update Reason Codes | -\*---------------------------------------------------------*/ -enum -{ - RGBCONTROLLER_UPDATE_REASON_UPDATELEDS, /* UpdateLEDs() called */ - RGBCONTROLLER_UPDATE_REASON_UPDATEMODE, /* UpdateMode() called */ - RGBCONTROLLER_UPDATE_REASON_SAVEMODE, /* SaveMode() called */ - RGBCONTROLLER_UPDATE_REASON_CONFIGUREZONE, /* ConfigureZone() called */ - RGBCONTROLLER_UPDATE_REASON_CLEARSEGMENTS, /* ClearSegments() called */ - RGBCONTROLLER_UPDATE_REASON_ADDSEGMENT, /* AddSegment() called */ - RGBCONTROLLER_UPDATE_REASON_HIDDEN, /* Hidden flag set */ - RGBCONTROLLER_UPDATE_REASON_UNHIDDEN, /* Hidden flag cleared */ - RGBCONTROLLER_UPDATE_REASON_SETDEVICESPECIFICCONFIGURATION, - /* SetDeviceSpecificConfiguration() called */ - RGBCONTROLLER_UPDATE_REASON_SETDEVICESPECIFICZONECONFIGURATION, - /* SetDeviceSpecificZoneConfiguration() called */ -}; - -std::string device_type_to_str(device_type type); - -class RGBControllerInterface -{ -public: - /*-----------------------------------------------------*\ - | Controller Information | - \*-----------------------------------------------------*/ - virtual std::string GetName() = 0; - virtual std::string GetVendor() = 0; - virtual std::string GetDescription() = 0; - virtual std::string GetVersion() = 0; - virtual std::string GetSerial() = 0; - virtual std::string GetLocation() = 0; - - virtual device_type GetDeviceType() = 0; - virtual unsigned int GetFlags() = 0; - - /*-----------------------------------------------------*\ - | Hidden Flag Functions | - \*-----------------------------------------------------*/ - virtual bool GetHidden() = 0; - virtual void SetHidden(bool hidden) = 0; - - /*-----------------------------------------------------*\ - | Zone Functions | - \*-----------------------------------------------------*/ - virtual zone GetZone(unsigned int zone_idx) = 0; - virtual int GetZoneActiveMode(unsigned int zone) = 0; - virtual RGBColor GetZoneColor(unsigned int zone, unsigned int color_index) = 0; - virtual RGBColor* GetZoneColorsPointer(unsigned int zone) = 0; - virtual std::size_t GetZoneCount() = 0; - virtual unsigned int GetZoneFlags(unsigned int zone) = 0; - virtual unsigned int GetZoneLEDsCount(unsigned int zone) = 0; - virtual unsigned int GetZoneLEDsMax(unsigned int zone) = 0; - virtual unsigned int GetZoneLEDsMin(unsigned int zone) = 0; - virtual matrix_map_type GetZoneMatrixMap(unsigned int zone) = 0; - virtual const unsigned int* GetZoneMatrixMapData(unsigned int zone) = 0; - virtual unsigned int GetZoneMatrixMapHeight(unsigned int zone) = 0; - virtual unsigned int GetZoneMatrixMapWidth(unsigned int zone) = 0; - virtual std::size_t GetZoneModeCount(unsigned int zone) = 0; - virtual unsigned int GetZoneModeBrightness(unsigned int zone, unsigned int mode) = 0; - virtual unsigned int GetZoneModeBrightnessMax(unsigned int zone, unsigned int mode) = 0; - virtual unsigned int GetZoneModeBrightnessMin(unsigned int zone, unsigned int mode) = 0; - virtual RGBColor GetZoneModeColor(unsigned int zone, unsigned int mode, unsigned int color_index) = 0; - virtual unsigned int GetZoneModeColorMode(unsigned int zone, unsigned int mode) = 0; - virtual std::size_t GetZoneModeColorsCount(unsigned int zone, unsigned int mode) = 0; - virtual unsigned int GetZoneModeColorsMax(unsigned int zone, unsigned int mode) = 0; - virtual unsigned int GetZoneModeColorsMin(unsigned int zone, unsigned int mode) = 0; - virtual unsigned int GetZoneModeDirection(unsigned int zone, unsigned int mode) = 0; - virtual unsigned int GetZoneModeFlags(unsigned int zone, unsigned int mode) = 0; - virtual std::string GetZoneModeName(unsigned int zone, unsigned int mode) = 0; - virtual unsigned int GetZoneModeSpeed(unsigned int zone, unsigned int mode) = 0; - virtual unsigned int GetZoneModeSpeedMax(unsigned int zone, unsigned int mode) = 0; - virtual unsigned int GetZoneModeSpeedMin(unsigned int zone, unsigned int mode) = 0; - virtual int GetZoneModeValue(unsigned int zone, unsigned int mode) = 0; - virtual std::string GetZoneName(unsigned int zone) = 0; - virtual std::size_t GetZoneSegmentCount(unsigned int zone) = 0; - virtual unsigned int GetZoneSegmentFlags(unsigned int zone, unsigned int segment) = 0; - virtual unsigned int GetZoneSegmentLEDsCount(unsigned int zone, unsigned int segment) = 0; - virtual matrix_map_type GetZoneSegmentMatrixMap(unsigned int zone, unsigned int segment) = 0; - virtual const unsigned int * GetZoneSegmentMatrixMapData(unsigned int zone, unsigned int segment) = 0; - virtual unsigned int GetZoneSegmentMatrixMapHeight(unsigned int zone, unsigned int segment) = 0; - virtual unsigned int GetZoneSegmentMatrixMapWidth(unsigned int zone, unsigned int segment) = 0; - virtual std::string GetZoneSegmentName(unsigned int zone, unsigned int segment) = 0; - virtual unsigned int GetZoneSegmentStartIndex(unsigned int zone, unsigned int segment) = 0; - virtual unsigned int GetZoneSegmentType(unsigned int zone, unsigned int segment) = 0; - virtual unsigned int GetZoneStartIndex(unsigned int zone) = 0; - virtual zone_type GetZoneType(unsigned int zone) = 0; - - virtual unsigned int GetLEDsInZone(unsigned int zone) = 0; - - virtual void SetZoneActiveMode(unsigned int zone, int mode) = 0; - virtual void SetZoneColor(unsigned int zone, unsigned int color_index, RGBColor color) = 0; - virtual void SetZoneModeBrightness(unsigned int zone, unsigned int mode, unsigned int brightness) = 0; - virtual void SetZoneModeColor(unsigned int zone, unsigned int mode, unsigned int color_index, RGBColor color) = 0; - virtual void SetZoneModeColorMode(unsigned int zone, unsigned int mode, unsigned int color_mode) = 0; - virtual void SetZoneModeColorsCount(unsigned int zone, unsigned int mode, std::size_t count) = 0; - virtual void SetZoneModeDirection(unsigned int zone, unsigned int mode, unsigned int direction) = 0; - virtual void SetZoneModeSpeed(unsigned int zone, unsigned int mode, unsigned int speed) = 0; - - virtual bool SupportsPerZoneModes() = 0; - - /*-----------------------------------------------------*\ - | Mode Functions | - \*-----------------------------------------------------*/ - virtual std::size_t GetModeCount() = 0; - virtual unsigned int GetModeBrightness(unsigned int mode) = 0; - virtual unsigned int GetModeBrightnessMax(unsigned int mode) = 0; - virtual unsigned int GetModeBrightnessMin(unsigned int mode) = 0; - virtual RGBColor GetModeColor(unsigned int mode, unsigned int color_index) = 0; - virtual unsigned int GetModeColorMode(unsigned int mode) = 0; - virtual std::size_t GetModeColorsCount(unsigned int mode) = 0; - virtual unsigned int GetModeColorsMax(unsigned int mode) = 0; - virtual unsigned int GetModeColorsMin(unsigned int mode) = 0; - virtual unsigned int GetModeDirection(unsigned int mode) = 0; - virtual unsigned int GetModeFlags(unsigned int mode) = 0; - virtual std::string GetModeName(unsigned int mode) = 0; - virtual unsigned int GetModeSpeed(unsigned int mode) = 0; - virtual unsigned int GetModeSpeedMax(unsigned int mode) = 0; - virtual unsigned int GetModeSpeedMin(unsigned int mode) = 0; - virtual int GetModeValue(unsigned int mode) = 0; - - virtual void SetModeBrightness(unsigned int mode, unsigned int brightness) = 0; - virtual void SetModeColor(unsigned int mode, unsigned int color_index, RGBColor color) = 0; - virtual void SetModeColorMode(unsigned int mode, unsigned int color_mode) = 0; - virtual void SetModeColorsCount(unsigned int mode, std::size_t count) = 0; - virtual void SetModeDirection(unsigned int mode, unsigned int direction) = 0; - virtual void SetModeSpeed(unsigned int mode, unsigned int speed) = 0; - - virtual int GetActiveMode() = 0; - virtual void SetActiveMode(int mode) = 0; - virtual void SetCustomMode() = 0; - - /*-----------------------------------------------------*\ - | LED Functions | - \*-----------------------------------------------------*/ - virtual std::size_t GetLEDCount() = 0; - virtual std::string GetLEDName(unsigned int led) = 0; - virtual unsigned int GetLEDValue(unsigned int led) = 0; - - virtual std::string GetLEDDisplayName(unsigned int led) = 0; - - /*-----------------------------------------------------*\ - | Color Functions | - \*-----------------------------------------------------*/ - virtual RGBColor GetColor(unsigned int led) = 0; - virtual RGBColor* GetColorsPointer() = 0; - virtual void SetColor(unsigned int led, RGBColor color) = 0; - - virtual void SetAllColors(RGBColor color) = 0; - virtual void SetAllZoneColors(int zone, RGBColor color) = 0; - - /*-----------------------------------------------------*\ - | Device-Specific Configuration Functions | - \*-----------------------------------------------------*/ - virtual nlohmann::json GetDeviceSpecificConfigurationSchema() = 0; - virtual nlohmann::json GetDeviceSpecificConfiguration() = 0; - virtual void SetDeviceSpecificConfiguration(nlohmann::json configuration_json) = 0; - - virtual nlohmann::json GetDeviceSpecificZoneConfigurationSchema(int zone) = 0; - virtual nlohmann::json GetDeviceSpecificZoneConfiguration(int zone) = 0; - virtual void SetDeviceSpecificZoneConfiguration(int zone, nlohmann::json configuration_json) = 0; - - /*-----------------------------------------------------*\ - | Update Callback Functions | - \*-----------------------------------------------------*/ - 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(unsigned int update_reason) = 0; - - /*-----------------------------------------------------*\ - | Device Update Functions | - \*-----------------------------------------------------*/ - virtual void UpdateLEDs() = 0; - virtual void UpdateZoneLEDs(int zone) = 0; - virtual void UpdateSingleLED(int led) = 0; - - virtual void UpdateMode() = 0; - virtual void UpdateZoneMode(int zone) = 0; - virtual void SaveMode() = 0; - - virtual void ClearSegments(int zone) = 0; - virtual void AddSegment(int zone, segment new_segment) = 0; - - virtual void ConfigureZone(int zone_idx, zone new_zone) = 0; - virtual void ResizeZone(int zone, int new_size) = 0; -}; +#include "RGBControllerInterface.h" class RGBController : public RGBControllerInterface { @@ -732,6 +254,8 @@ public: static segment SetSegmentDescriptionJSON(nlohmann::json segment_json); static zone SetZoneDescriptionJSON(nlohmann::json zone_json); + static std::string DeviceTypeToString(device_type type); + protected: /*-----------------------------------------------------*\ | Controller information strings | diff --git a/RGBController/RGBControllerInterface.h b/RGBController/RGBControllerInterface.h new file mode 100644 index 000000000..d28505008 --- /dev/null +++ b/RGBController/RGBControllerInterface.h @@ -0,0 +1,651 @@ +/*---------------------------------------------------------*\ +| RGBControllerInterface.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-or-later | +\*---------------------------------------------------------*/ + +#pragma once + +#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))) + +#define RGBToBGRColor(rgb) ((rgb & 0xFF) << 16 | (rgb & 0xFF00) | (rgb & 0xFF0000) >> 16) + +/*---------------------------------------------------------*\ +| RGBController Callback Types | +\*---------------------------------------------------------*/ +typedef void (*RGBControllerCallback)(void *, unsigned int, void *); + +/*---------------------------------------------------------*\ +| Update Reason Codes | +\*---------------------------------------------------------*/ +enum +{ + RGBCONTROLLER_UPDATE_REASON_UPDATELEDS, /* UpdateLEDs() called */ + RGBCONTROLLER_UPDATE_REASON_UPDATEMODE, /* UpdateMode() called */ + RGBCONTROLLER_UPDATE_REASON_SAVEMODE, /* SaveMode() called */ + RGBCONTROLLER_UPDATE_REASON_CONFIGUREZONE, /* ConfigureZone() called */ + RGBCONTROLLER_UPDATE_REASON_CLEARSEGMENTS, /* ClearSegments() called */ + RGBCONTROLLER_UPDATE_REASON_ADDSEGMENT, /* AddSegment() called */ + RGBCONTROLLER_UPDATE_REASON_HIDDEN, /* Hidden flag set */ + RGBCONTROLLER_UPDATE_REASON_UNHIDDEN, /* Hidden flag cleared */ + RGBCONTROLLER_UPDATE_REASON_SETDEVICESPECIFICCONFIGURATION, + /* SetDeviceSpecificConfiguration() called */ + RGBCONTROLLER_UPDATE_REASON_SETDEVICESPECIFICZONECONFIGURATION, + /* SetDeviceSpecificZoneConfiguration() called */ +}; + +/*---------------------------------------------------------*\ +| 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_FLAG_REQUIRES_ENTIRE_DEVICE = (1 << 10),/* Mode always applies to entire */ + /* device, overrides per-zone modes */ +}; + +/*---------------------------------------------------------*\ +| 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 */ +}; + +/*---------------------------------------------------------*\ +| Zone Flags | +\*---------------------------------------------------------*/ +typedef unsigned int zone_flags; + +#define ZONE_FLAGS_MANUALLY_CONFIGURABLE (ZONE_FLAG_MANUALLY_CONFIGURABLE_SIZE_EFFECTS_ONLY | \ + ZONE_FLAG_MANUALLY_CONFIGURABLE_SIZE | \ + ZONE_FLAG_MANUALLY_CONFIGURABLE_NAME | \ + ZONE_FLAG_MANUALLY_CONFIGURABLE_TYPE | \ + ZONE_FLAG_MANUALLY_CONFIGURABLE_MATRIX_MAP | \ + ZONE_FLAG_MANUALLY_CONFIGURABLE_SEGMENTS | \ + ZONE_FLAG_MANUALLY_CONFIGURABLE_DEVICE_SPECIFIC) + +#define ZONE_FLAGS_MANUALLY_CONFIGURED (ZONE_FLAG_MANUALLY_CONFIGURED_SIZE | \ + ZONE_FLAG_MANUALLY_CONFIGURED_NAME | \ + ZONE_FLAG_MANUALLY_CONFIGURED_TYPE | \ + ZONE_FLAG_MANUALLY_CONFIGURED_MATRIX_MAP | \ + ZONE_FLAG_MANUALLY_CONFIGURED_SEGMENTS | \ + ZONE_FLAG_MANUALLY_CONFIGURED_DEVICE_SPECIFIC) +enum +{ + ZONE_FLAG_MANUALLY_CONFIGURABLE_SIZE_EFFECTS_ONLY = (1 << 0), /* Zone size is manually configurable, but only */ + /* for hardware effects, treated as single LED */ + /* for per-LED modes */ + ZONE_FLAG_MANUALLY_CONFIGURABLE_SIZE = (1 << 1), /* Zone size is manually configurable */ + ZONE_FLAG_MANUALLY_CONFIGURABLE_NAME = (1 << 2), /* Zone name is manually configurable */ + ZONE_FLAG_MANUALLY_CONFIGURABLE_TYPE = (1 << 3), /* Zone type is manually configurable */ + ZONE_FLAG_MANUALLY_CONFIGURABLE_MATRIX_MAP = (1 << 4), /* Zone matrix map is manually configurable */ + ZONE_FLAG_MANUALLY_CONFIGURABLE_SEGMENTS = (1 << 5), /* Zone segments are manually configurable */ + ZONE_FLAG_MANUALLY_CONFIGURABLE_DEVICE_SPECIFIC = (1 << 6), /* Zone dev-specific cfg manually configurable */ + ZONE_FLAG_MANUALLY_CONFIGURED_SIZE = (1 << 12),/* Zone size has been manually configured */ + ZONE_FLAG_MANUALLY_CONFIGURED_NAME = (1 << 13),/* Zone name has been manually configured */ + ZONE_FLAG_MANUALLY_CONFIGURED_TYPE = (1 << 14),/* Zone type has been manually configured */ + ZONE_FLAG_MANUALLY_CONFIGURED_MATRIX_MAP = (1 << 15),/* Zone matrix map has been manually configured */ + ZONE_FLAG_MANUALLY_CONFIGURED_SEGMENTS = (1 << 16),/* Zone segments have been manually configured */ + ZONE_FLAG_MANUALLY_CONFIGURED_DEVICE_SPECIFIC = (1 << 17),/* Zone device-specific cfg manually configured */ + ZONE_FLAG_ZONE_GEOMETRY_MAY_CHANGE = (1 << 24),/* Zone geometry may change */ +}; + +/*---------------------------------------------------------*\ +| Zone Types | +\*---------------------------------------------------------*/ +typedef unsigned int zone_type; + +enum +{ + ZONE_TYPE_SINGLE, + ZONE_TYPE_LINEAR, + ZONE_TYPE_MATRIX, + ZONE_TYPE_LINEAR_LOOP, + ZONE_TYPE_MATRIX_LOOP_X, + ZONE_TYPE_MATRIX_LOOP_Y, + ZONE_TYPE_SEGMENTED +}; + +/*---------------------------------------------------------*\ +| Segment Flags | +\*---------------------------------------------------------*/ +enum +{ + SEGMENT_FLAG_GROUP_START = (1 << 0), /* Start of segment group */ + SEGMENT_FLAG_GROUP_MEMBER = (1 << 1), /* Segment is in group */ +}; + +/*---------------------------------------------------------*\ +| 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_LAPTOP, + DEVICE_TYPE_MONITOR, + DEVICE_TYPE_UNKNOWN, +}; + +/*---------------------------------------------------------*\ +| Controller Flags | +\*---------------------------------------------------------*/ +enum +{ + CONTROLLER_FLAG_LOCAL = (1 << 0), /* Device is local to this instance */ + CONTROLLER_FLAG_REMOTE = (1 << 1), /* Device is on a remote instance */ + CONTROLLER_FLAG_VIRTUAL = (1 << 2), /* Device is a virtual device */ + CONTROLLER_FLAG_HIDDEN = (1 << 3), /* Device is hidden */ + + CONTROLLER_FLAG_RESET_BEFORE_UPDATE = (1 << 8), /* Device resets update flag before */ + /* calling update function */ +}; + +/*---------------------------------------------------------*\ +| Matrix Map | +\*---------------------------------------------------------*/ +class matrix_map_type +{ +public: + unsigned int height; + unsigned int width; + std::vector map; + + /*-----------------------------------------------------*\ + | Functionality defined inline so that it can be used | + | in consuming plugins | + \*-----------------------------------------------------*/ + matrix_map_type() + { + Reset(); + } + + matrix_map_type(unsigned int height, unsigned int width, unsigned int * map) + { + Set(height, width, map); + } + + ~matrix_map_type() + { + + } + + void Reset() + { + Set(0, 0, NULL); + } + + void Set(unsigned int height, unsigned int width, unsigned int * map) + { + this->height = height; + this->width = width; + this->map.resize(height * width); + + if(map != NULL) + { + memcpy(this->map.data(), map, (height * width * sizeof(unsigned int))); + } + else + { + memset(this->map.data(), 0, (height * width * sizeof(unsigned int))); + } + } +}; + +/*---------------------------------------------------------*\ +| 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 */ + + /*-----------------------------------------------------*\ + | Functionality defined inline so that it can be used | + | in consuming plugins | + \*-----------------------------------------------------*/ + mode() + { + /*-------------------------------------------------*\ + | Initialize mode variables | + \*-------------------------------------------------*/ + name = ""; + value = 0; + flags = 0; + speed_min = 0; + speed_max = 0; + brightness_min = 0; + brightness_max = 0; + colors_min = 0; + colors_max = 0; + speed = 0; + brightness = 0; + direction = 0; + color_mode = 0; + } + + ~mode() + { + colors.clear(); + } +}; + +/*---------------------------------------------------------*\ +| LED Class | +\*---------------------------------------------------------*/ +class led +{ +public: + /*-----------------------------------------------------*\ + | LED Information | + \*-----------------------------------------------------*/ + std::string name; /* LED name */ + unsigned int value; /* Device-specific LED value */ + + /*-----------------------------------------------------*\ + | Functionality defined inline so that it can be used | + | in consuming plugins | + \*-----------------------------------------------------*/ + led() + { + /*-------------------------------------------------*\ + | Initialize LED variables | + \*-------------------------------------------------*/ + name = ""; + value = 0; + } + + ~led() + { + + } +}; + +/*---------------------------------------------------------*\ +| Segment Class | +\*---------------------------------------------------------*/ +class segment +{ +public: + 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 */ + matrix_map_type matrix_map; /* Matrix map */ + unsigned int flags; /* Segment flags */ + + /*-----------------------------------------------------*\ + | Functionality defined inline so that it can be used | + | in consuming plugins | + \*-----------------------------------------------------*/ + segment() + { + /*-------------------------------------------------*\ + | Initialize segment variables | + \*-------------------------------------------------*/ + name = ""; + type = 0; + start_idx = 0; + leds_count = 0; + flags = 0; + } + + ~segment() + { + + } +}; + +/*---------------------------------------------------------*\ +| Zone Class | +\*---------------------------------------------------------*/ +class zone +{ +public: + 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 */ + std::vector segments; /* Segments in zone */ + zone_flags flags; /* Zone flags bitfield */ + std::vector modes; /* Zone-specific modes */ + int active_mode; /* Active zone-specific mode */ + + /*-----------------------------------------------------*\ + | Functionality defined inline so that it can be used | + | in consuming plugins | + \*-----------------------------------------------------*/ + zone() + { + /*-------------------------------------------------*\ + | Initialize zone variables | + \*-------------------------------------------------*/ + name = ""; + type = 0; + leds = NULL; + colors = NULL; + start_idx = 0; + leds_count = 0; + leds_min = 0; + leds_max = 0; + flags = 0; + active_mode = -1; + } + + ~zone() + { + + } +}; + +typedef struct +{ + /*-----------------------------------------------------*\ + | Controller information strings | + \*-----------------------------------------------------*/ + std::string description; /* controller description */ + std::string location; /* controller location */ + std::string name; /* controller name */ + std::string serial; /* controller serial number */ + std::string vendor; /* controller vendor */ + std::string version; /* controller version */ + std::string configuration; /* controller device- */ + /* specific config JSON */ + + /*-----------------------------------------------------*\ + | Controller variables | + \*-----------------------------------------------------*/ + int active_mode; /* active mode */ + device_type type; /* device type */ + + /*-----------------------------------------------------*\ + | Controller member vectors | + \*-----------------------------------------------------*/ + std::vector modes; /* Modes */ + std::vector zones; /* Zones */ + std::vector leds; /* LEDs */ + + /*-----------------------------------------------------*\ + | Pointer to user object | + \*-----------------------------------------------------*/ + void* object_ptr; + + /*-----------------------------------------------------*\ + | Function pointers | + \*-----------------------------------------------------*/ + void (*DeviceConfigureZone)(void*, int); + + void (*DeviceUpdateLEDs)(void*); + void (*DeviceUpdateZoneLEDs)(void*, int); + void (*DeviceUpdateSingleLED)(void*, int); + + void (*DeviceUpdateMode)(void*); + void (*DeviceSaveMode)(void*); + void (*DeviceUpdateZoneMode)(void*, int); + + void (*DeviceUpdateDeviceSpecificConfiguration)(void*); + void (*DeviceUpdateDeviceSpecificZoneConfiguration)(void*, int); +} RGBController_Setup; + +class RGBControllerInterface +{ +public: + /*-----------------------------------------------------*\ + | Controller Information | + \*-----------------------------------------------------*/ + virtual std::string GetName() = 0; + virtual std::string GetVendor() = 0; + virtual std::string GetDescription() = 0; + virtual std::string GetVersion() = 0; + virtual std::string GetSerial() = 0; + virtual std::string GetLocation() = 0; + + virtual device_type GetDeviceType() = 0; + virtual unsigned int GetFlags() = 0; + + /*-----------------------------------------------------*\ + | Hidden Flag Functions | + \*-----------------------------------------------------*/ + virtual bool GetHidden() = 0; + virtual void SetHidden(bool hidden) = 0; + + /*-----------------------------------------------------*\ + | Zone Functions | + \*-----------------------------------------------------*/ + virtual zone GetZone(unsigned int zone_idx) = 0; + virtual int GetZoneActiveMode(unsigned int zone) = 0; + virtual RGBColor GetZoneColor(unsigned int zone, unsigned int color_index) = 0; + virtual RGBColor* GetZoneColorsPointer(unsigned int zone) = 0; + virtual std::size_t GetZoneCount() = 0; + virtual unsigned int GetZoneFlags(unsigned int zone) = 0; + virtual unsigned int GetZoneLEDsCount(unsigned int zone) = 0; + virtual unsigned int GetZoneLEDsMax(unsigned int zone) = 0; + virtual unsigned int GetZoneLEDsMin(unsigned int zone) = 0; + virtual matrix_map_type GetZoneMatrixMap(unsigned int zone) = 0; + virtual const unsigned int* GetZoneMatrixMapData(unsigned int zone) = 0; + virtual unsigned int GetZoneMatrixMapHeight(unsigned int zone) = 0; + virtual unsigned int GetZoneMatrixMapWidth(unsigned int zone) = 0; + virtual std::size_t GetZoneModeCount(unsigned int zone) = 0; + virtual unsigned int GetZoneModeBrightness(unsigned int zone, unsigned int mode) = 0; + virtual unsigned int GetZoneModeBrightnessMax(unsigned int zone, unsigned int mode) = 0; + virtual unsigned int GetZoneModeBrightnessMin(unsigned int zone, unsigned int mode) = 0; + virtual RGBColor GetZoneModeColor(unsigned int zone, unsigned int mode, unsigned int color_index) = 0; + virtual unsigned int GetZoneModeColorMode(unsigned int zone, unsigned int mode) = 0; + virtual std::size_t GetZoneModeColorsCount(unsigned int zone, unsigned int mode) = 0; + virtual unsigned int GetZoneModeColorsMax(unsigned int zone, unsigned int mode) = 0; + virtual unsigned int GetZoneModeColorsMin(unsigned int zone, unsigned int mode) = 0; + virtual unsigned int GetZoneModeDirection(unsigned int zone, unsigned int mode) = 0; + virtual unsigned int GetZoneModeFlags(unsigned int zone, unsigned int mode) = 0; + virtual std::string GetZoneModeName(unsigned int zone, unsigned int mode) = 0; + virtual unsigned int GetZoneModeSpeed(unsigned int zone, unsigned int mode) = 0; + virtual unsigned int GetZoneModeSpeedMax(unsigned int zone, unsigned int mode) = 0; + virtual unsigned int GetZoneModeSpeedMin(unsigned int zone, unsigned int mode) = 0; + virtual int GetZoneModeValue(unsigned int zone, unsigned int mode) = 0; + virtual std::string GetZoneName(unsigned int zone) = 0; + virtual std::size_t GetZoneSegmentCount(unsigned int zone) = 0; + virtual unsigned int GetZoneSegmentFlags(unsigned int zone, unsigned int segment) = 0; + virtual unsigned int GetZoneSegmentLEDsCount(unsigned int zone, unsigned int segment) = 0; + virtual matrix_map_type GetZoneSegmentMatrixMap(unsigned int zone, unsigned int segment) = 0; + virtual const unsigned int * GetZoneSegmentMatrixMapData(unsigned int zone, unsigned int segment) = 0; + virtual unsigned int GetZoneSegmentMatrixMapHeight(unsigned int zone, unsigned int segment) = 0; + virtual unsigned int GetZoneSegmentMatrixMapWidth(unsigned int zone, unsigned int segment) = 0; + virtual std::string GetZoneSegmentName(unsigned int zone, unsigned int segment) = 0; + virtual unsigned int GetZoneSegmentStartIndex(unsigned int zone, unsigned int segment) = 0; + virtual unsigned int GetZoneSegmentType(unsigned int zone, unsigned int segment) = 0; + virtual unsigned int GetZoneStartIndex(unsigned int zone) = 0; + virtual zone_type GetZoneType(unsigned int zone) = 0; + + virtual unsigned int GetLEDsInZone(unsigned int zone) = 0; + + virtual void SetZoneActiveMode(unsigned int zone, int mode) = 0; + virtual void SetZoneColor(unsigned int zone, unsigned int color_index, RGBColor color) = 0; + virtual void SetZoneModeBrightness(unsigned int zone, unsigned int mode, unsigned int brightness) = 0; + virtual void SetZoneModeColor(unsigned int zone, unsigned int mode, unsigned int color_index, RGBColor color) = 0; + virtual void SetZoneModeColorMode(unsigned int zone, unsigned int mode, unsigned int color_mode) = 0; + virtual void SetZoneModeColorsCount(unsigned int zone, unsigned int mode, std::size_t count) = 0; + virtual void SetZoneModeDirection(unsigned int zone, unsigned int mode, unsigned int direction) = 0; + virtual void SetZoneModeSpeed(unsigned int zone, unsigned int mode, unsigned int speed) = 0; + + virtual bool SupportsPerZoneModes() = 0; + + /*-----------------------------------------------------*\ + | Mode Functions | + \*-----------------------------------------------------*/ + virtual std::size_t GetModeCount() = 0; + virtual unsigned int GetModeBrightness(unsigned int mode) = 0; + virtual unsigned int GetModeBrightnessMax(unsigned int mode) = 0; + virtual unsigned int GetModeBrightnessMin(unsigned int mode) = 0; + virtual RGBColor GetModeColor(unsigned int mode, unsigned int color_index) = 0; + virtual unsigned int GetModeColorMode(unsigned int mode) = 0; + virtual std::size_t GetModeColorsCount(unsigned int mode) = 0; + virtual unsigned int GetModeColorsMax(unsigned int mode) = 0; + virtual unsigned int GetModeColorsMin(unsigned int mode) = 0; + virtual unsigned int GetModeDirection(unsigned int mode) = 0; + virtual unsigned int GetModeFlags(unsigned int mode) = 0; + virtual std::string GetModeName(unsigned int mode) = 0; + virtual unsigned int GetModeSpeed(unsigned int mode) = 0; + virtual unsigned int GetModeSpeedMax(unsigned int mode) = 0; + virtual unsigned int GetModeSpeedMin(unsigned int mode) = 0; + virtual int GetModeValue(unsigned int mode) = 0; + + virtual void SetModeBrightness(unsigned int mode, unsigned int brightness) = 0; + virtual void SetModeColor(unsigned int mode, unsigned int color_index, RGBColor color) = 0; + virtual void SetModeColorMode(unsigned int mode, unsigned int color_mode) = 0; + virtual void SetModeColorsCount(unsigned int mode, std::size_t count) = 0; + virtual void SetModeDirection(unsigned int mode, unsigned int direction) = 0; + virtual void SetModeSpeed(unsigned int mode, unsigned int speed) = 0; + + virtual int GetActiveMode() = 0; + virtual void SetActiveMode(int mode) = 0; + virtual void SetCustomMode() = 0; + + /*-----------------------------------------------------*\ + | LED Functions | + \*-----------------------------------------------------*/ + virtual std::size_t GetLEDCount() = 0; + virtual std::string GetLEDName(unsigned int led) = 0; + virtual unsigned int GetLEDValue(unsigned int led) = 0; + + virtual std::string GetLEDDisplayName(unsigned int led) = 0; + + /*-----------------------------------------------------*\ + | Color Functions | + \*-----------------------------------------------------*/ + virtual RGBColor GetColor(unsigned int led) = 0; + virtual RGBColor* GetColorsPointer() = 0; + virtual void SetColor(unsigned int led, RGBColor color) = 0; + + virtual void SetAllColors(RGBColor color) = 0; + virtual void SetAllZoneColors(int zone, RGBColor color) = 0; + + /*-----------------------------------------------------*\ + | Device-Specific Configuration Functions | + \*-----------------------------------------------------*/ + virtual nlohmann::json GetDeviceSpecificConfigurationSchema() = 0; + virtual nlohmann::json GetDeviceSpecificConfiguration() = 0; + virtual void SetDeviceSpecificConfiguration(nlohmann::json configuration_json) = 0; + + virtual nlohmann::json GetDeviceSpecificZoneConfigurationSchema(int zone) = 0; + virtual nlohmann::json GetDeviceSpecificZoneConfiguration(int zone) = 0; + virtual void SetDeviceSpecificZoneConfiguration(int zone, nlohmann::json configuration_json) = 0; + + /*-----------------------------------------------------*\ + | Update Callback Functions | + \*-----------------------------------------------------*/ + 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(unsigned int update_reason) = 0; + + /*-----------------------------------------------------*\ + | Device Update Functions | + \*-----------------------------------------------------*/ + virtual void UpdateLEDs() = 0; + virtual void UpdateZoneLEDs(int zone) = 0; + virtual void UpdateSingleLED(int led) = 0; + + virtual void UpdateMode() = 0; + virtual void UpdateZoneMode(int zone) = 0; + virtual void SaveMode() = 0; + + virtual void ClearSegments(int zone) = 0; + virtual void AddSegment(int zone, segment new_segment) = 0; + + virtual void ConfigureZone(int zone_idx, zone new_zone) = 0; + virtual void ResizeZone(int zone, int new_size) = 0; +}; diff --git a/RGBController/RGBController_Virtual.cpp b/RGBController/RGBController_Virtual.cpp new file mode 100644 index 000000000..1c49c89a0 --- /dev/null +++ b/RGBController/RGBController_Virtual.cpp @@ -0,0 +1,156 @@ +/*---------------------------------------------------------*\ +| RGBController_Virtual.cpp | +| | +| Virtual RGBController that can be filled out by a | +| plugin, including function pointers for implementing | +| functionality plugin-side. | +| | +| Adam Honse (CalcProgrammer1) 18 May 2026 | +| | +| This file is part of the OpenRGB project | +| SPDX-License-Identifier: GPL-2.0-or-later | +\*---------------------------------------------------------*/ + +#include "RGBController_Virtual.h" +#include "RGBControllerInterface.h" + +RGBController_Virtual::RGBController_Virtual(RGBController_Setup* setup) +{ + description = setup->description; + location = setup->location; + name = setup->name; + serial = setup->serial; + vendor = setup->vendor; + version = setup->version; + configuration = setup->configuration; + + modes = setup->modes; + zones = setup->zones; + + active_mode = setup->active_mode; + type = setup->type; + flags = CONTROLLER_FLAG_VIRTUAL; + + DeviceConfigureZone_ptr = setup->DeviceConfigureZone; + DeviceUpdateLEDs_ptr = setup->DeviceUpdateLEDs; + DeviceUpdateZoneLEDs_ptr = setup->DeviceUpdateZoneLEDs; + DeviceUpdateSingleLED_ptr = setup->DeviceUpdateSingleLED; + DeviceUpdateMode_ptr = setup->DeviceUpdateMode; + DeviceUpdateZoneMode_ptr = setup->DeviceUpdateZoneMode; + DeviceSaveMode_ptr = setup->DeviceSaveMode; + DeviceUpdateDeviceSpecificConfiguration_ptr = setup->DeviceUpdateDeviceSpecificConfiguration; + DeviceUpdateDeviceSpecificZoneConfiguration_ptr = setup->DeviceUpdateDeviceSpecificZoneConfiguration; + + object_ptr = setup->object_ptr; + + SetupLEDs(); + SetupColors(); +} + +RGBController_Virtual::~RGBController_Virtual() +{ + +} + +void RGBController_Virtual::SetupLEDs() +{ + leds.clear(); + + for(std::size_t zone_idx = 0; zone_idx < zones.size(); zone_idx++) + { + for(std::size_t led_idx = 0; led_idx < zones[zone_idx].leds_count; led_idx++) + { + led new_led; + + new_led.name = "Zone " + std::to_string(zone_idx) + ", LED " + std::to_string(led_idx); + new_led.value = 0; + + leds.push_back(new_led); + } + } +} + +void RGBController_Virtual::UpdateVirtualZone(int zone_idx, zone updated_zone) +{ + AccessMutex.lock(); + if(zone_idx < zones.size()) + { + zones[zone_idx] = updated_zone; + } + + SetupLEDs(); + SetupColors(); + AccessMutex.unlock(); +} + +void RGBController_Virtual::DeviceConfigureZone(int zone_idx) +{ + if(DeviceConfigureZone_ptr) + { + DeviceConfigureZone_ptr(object_ptr, zone_idx); + } +} + +void RGBController_Virtual::DeviceUpdateLEDs() +{ + if(DeviceUpdateLEDs_ptr) + { + DeviceUpdateLEDs_ptr(object_ptr); + } +} + +void RGBController_Virtual::DeviceUpdateZoneLEDs(int zone) +{ + if(DeviceUpdateZoneLEDs_ptr) + { + DeviceUpdateZoneLEDs_ptr(object_ptr, zone); + } +} + +void RGBController_Virtual::DeviceUpdateSingleLED(int led) +{ + if(DeviceUpdateSingleLED_ptr) + { + DeviceUpdateSingleLED_ptr(object_ptr, led); + } +} + +void RGBController_Virtual::DeviceUpdateMode() +{ + if(DeviceUpdateMode_ptr) + { + DeviceUpdateMode_ptr(object_ptr); + } +} + +void RGBController_Virtual::DeviceUpdateZoneMode(int zone) +{ + if(DeviceUpdateZoneMode_ptr) + { + DeviceUpdateZoneMode_ptr(object_ptr, zone); + } +} + +void RGBController_Virtual::DeviceSaveMode() +{ + if(DeviceSaveMode_ptr) + { + DeviceSaveMode_ptr(object_ptr); + } +} + +void RGBController_Virtual::DeviceUpdateDeviceSpecificConfiguration() +{ + if(DeviceUpdateDeviceSpecificConfiguration_ptr) + { + DeviceUpdateDeviceSpecificConfiguration_ptr(object_ptr); + } +} + +void RGBController_Virtual::DeviceUpdateDeviceSpecificZoneConfiguration(int zone) +{ + if(DeviceUpdateDeviceSpecificZoneConfiguration_ptr) + { + DeviceUpdateDeviceSpecificZoneConfiguration_ptr(object_ptr, zone); + } +} diff --git a/RGBController/RGBController_Virtual.h b/RGBController/RGBController_Virtual.h new file mode 100644 index 000000000..6d36f207c --- /dev/null +++ b/RGBController/RGBController_Virtual.h @@ -0,0 +1,62 @@ +/*---------------------------------------------------------*\ +| RGBController_Virtual.h | +| | +| Virtual RGBController that can be filled out by a | +| plugin, including function pointers for implementing | +| functionality plugin-side. | +| | +| Adam Honse (CalcProgrammer1) 18 May 2026 | +| | +| This file is part of the OpenRGB project | +| SPDX-License-Identifier: GPL-2.0-or-later | +\*---------------------------------------------------------*/ + +#pragma once + +#include "RGBController.h" + +class RGBController_Virtual : public RGBController +{ +public: + RGBController_Virtual(RGBController_Setup* setup); + ~RGBController_Virtual(); + + void UpdateVirtualZone(int zone_idx, zone updated_zone); + + void DeviceConfigureZone(int zone_idx); + + void DeviceUpdateLEDs(); + void DeviceUpdateZoneLEDs(int zone); + void DeviceUpdateSingleLED(int led); + + void DeviceUpdateMode(); + void DeviceUpdateZoneMode(int zone); + void DeviceSaveMode(); + + void DeviceUpdateDeviceSpecificConfiguration(); + void DeviceUpdateDeviceSpecificZoneConfiguration(int zone); + +private: + /*-----------------------------------------------------*\ + | Pointer to user object | + \*-----------------------------------------------------*/ + void* object_ptr; + + /*-----------------------------------------------------*\ + | Function pointers | + \*-----------------------------------------------------*/ + void (*DeviceConfigureZone_ptr)(void*, int); + + void (*DeviceUpdateLEDs_ptr)(void*); + void (*DeviceUpdateZoneLEDs_ptr)(void*, int); + void (*DeviceUpdateSingleLED_ptr)(void*, int); + + void (*DeviceUpdateMode_ptr)(void*); + void (*DeviceSaveMode_ptr)(void*); + void (*DeviceUpdateZoneMode_ptr)(void*, int); + + void (*DeviceUpdateDeviceSpecificConfiguration_ptr)(void*); + void (*DeviceUpdateDeviceSpecificZoneConfiguration_ptr)(void*, int); + + void SetupLEDs(); +}; diff --git a/ResourceManager.cpp b/ResourceManager.cpp index a3847a0b2..ee85b5572 100644 --- a/ResourceManager.cpp +++ b/ResourceManager.cpp @@ -321,9 +321,14 @@ ProfileManager* ResourceManager::GetProfileManager() return(profile_manager); } -std::vector & ResourceManager::GetRGBControllers() +std::vector& ResourceManager::GetRGBControllers() { - return rgb_controllers; + return(rgb_controllers); +} + +std::vector& ResourceManager::GetRGBControllerInterfaces() +{ + return(rgb_controller_interfaces); } NetworkServer* ResourceManager::GetServer() @@ -546,6 +551,7 @@ void ResourceManager::UpdateDeviceList() | Clear the controller list | \*-----------------------------------------------------*/ rgb_controllers.clear(); + rgb_controller_interfaces.clear(); /*-----------------------------------------------------*\ | Insert hardware controllers into controller list | @@ -606,6 +612,16 @@ void ResourceManager::UpdateDeviceList() } } + /*-----------------------------------------------------*\ + | Synchronize interfaces with controllers | + \*-----------------------------------------------------*/ + rgb_controller_interfaces.reserve(rgb_controllers.size()); + + for(RGBController* rgb_controller : rgb_controllers) + { + rgb_controller_interfaces.push_back((RGBControllerInterface*)rgb_controller); + } + /*-----------------------------------------------------*\ | Signal list has changed | \*-----------------------------------------------------*/ diff --git a/ResourceManager.h b/ResourceManager.h index bc66dc12d..aeee453d0 100644 --- a/ResourceManager.h +++ b/ResourceManager.h @@ -23,7 +23,7 @@ #include "DetectionManager.h" #include "hidapi_wrapper.h" #include "i2c_smbus.h" -#include "ResourceManagerInterface.h" +#include "ResourceManagerCallback.h" #include "filesystem.h" using json = nlohmann::json; @@ -36,7 +36,7 @@ class ProfileManager; class RGBController; class SettingsManager; -class ResourceManager: public ResourceManagerInterface +class ResourceManager { public: ResourceManager(); @@ -60,6 +60,7 @@ public: PluginManagerInterface* GetPluginManager(); ProfileManager* GetProfileManager(); std::vector& GetRGBControllers(); + std::vector& GetRGBControllerInterfaces(); NetworkServer* GetServer(); SettingsManager* GetSettingsManager(); @@ -171,6 +172,7 @@ private: | RGBControllers | \*-----------------------------------------------------*/ std::vector rgb_controllers; + std::vector rgb_controller_interfaces; /*-----------------------------------------------------*\ | Network Server | diff --git a/ResourceManagerCallback.h b/ResourceManagerCallback.h new file mode 100644 index 000000000..555d8196c --- /dev/null +++ b/ResourceManagerCallback.h @@ -0,0 +1,29 @@ +/*---------------------------------------------------------*\ +| ResourceManagerCallback.h | +| | +| Callback type and update reason codes for | +| ResourceManager | +| | +| This file is part of the OpenRGB project | +| SPDX-License-Identifier: GPL-2.0-or-later | +\*---------------------------------------------------------*/ + +#pragma once + +/*---------------------------------------------------------*\ +| Callback Types | +\*---------------------------------------------------------*/ +typedef void (*ResourceManagerCallback)(void *, unsigned int); + +/*---------------------------------------------------------*\ +| ResourceManager Update Reason Codes | +\*---------------------------------------------------------*/ +enum +{ + RESOURCEMANAGER_UPDATE_REASON_DETECTION_STARTED, /* Detection started */ + RESOURCEMANAGER_UPDATE_REASON_DETECTION_PROGRESS_CHANGED, /* Detection progress changed */ + RESOURCEMANAGER_UPDATE_REASON_DETECTION_COMPLETE, /* Detection completed */ + RESOURCEMANAGER_UPDATE_REASON_CLIENT_INFO_UPDATED, /* NetworkClient info updated */ + RESOURCEMANAGER_UPDATE_REASON_I2C_BUS_LIST_UPDATED, /* I2C bus list updated */ + RESOURCEMANAGER_UPDATE_REASON_DEVICE_LIST_UPDATED, /* Device list updated */ +}; diff --git a/ResourceManagerInterface.h b/ResourceManagerInterface.h deleted file mode 100644 index bb7a445fc..000000000 --- a/ResourceManagerInterface.h +++ /dev/null @@ -1,72 +0,0 @@ -/*---------------------------------------------------------*\ -| ResourceManagerInterface.h | -| | -| Provides a virtual interface to ResourceManager for | -| exposing ResourceManager to plugins. Changes to this | -| class structure require a new plugin API version. | -| | -| This file is part of the OpenRGB project | -| SPDX-License-Identifier: GPL-2.0-or-later | -\*---------------------------------------------------------*/ - -#pragma once - -#include -#include "i2c_smbus.h" -#include "filesystem.h" - -class LogManager; -class PluginManagerInterface; -class ProfileManager; -class RGBController; -class SettingsManager; - -/*---------------------------------------------------------*\ -| Callback Types | -\*---------------------------------------------------------*/ -typedef void (*ResourceManagerCallback)(void *, unsigned int); - -/*---------------------------------------------------------*\ -| ResourceManager Update Reason Codes | -\*---------------------------------------------------------*/ -enum -{ - RESOURCEMANAGER_UPDATE_REASON_DETECTION_STARTED, /* Detection started */ - RESOURCEMANAGER_UPDATE_REASON_DETECTION_PROGRESS_CHANGED, /* Detection progress changed */ - RESOURCEMANAGER_UPDATE_REASON_DETECTION_COMPLETE, /* Detection completed */ - RESOURCEMANAGER_UPDATE_REASON_CLIENT_INFO_UPDATED, /* NetworkClient info updated */ - RESOURCEMANAGER_UPDATE_REASON_I2C_BUS_LIST_UPDATED, /* I2C bus list updated */ - RESOURCEMANAGER_UPDATE_REASON_DEVICE_LIST_UPDATED, /* Device list updated */ -}; - -class ResourceManagerInterface -{ -public: - /*-----------------------------------------------------*\ - | Resource Accessors | - \*-----------------------------------------------------*/ - virtual filesystem::path GetConfigurationDirectory() = 0; - virtual LogManager* GetLogManager() = 0; - virtual std::vector & GetI2CBuses() = 0; - virtual PluginManagerInterface* GetPluginManager() = 0; - virtual ProfileManager* GetProfileManager() = 0; - virtual std::vector & GetRGBControllers() = 0; - virtual SettingsManager* GetSettingsManager() = 0; - - /*-----------------------------------------------------*\ - | Callback Registration Functions | - \*-----------------------------------------------------*/ - virtual void RegisterResourceManagerCallback(ResourceManagerCallback new_callback, void * new_callback_arg) = 0; - virtual void UnregisterResourceManagerCallback(ResourceManagerCallback new_callback, void * new_callback_arg) = 0; - - /*-----------------------------------------------------*\ - | Functions to manage detection | - \*-----------------------------------------------------*/ - virtual bool GetDetectionEnabled() = 0; - virtual unsigned int GetDetectionPercent() = 0; - virtual std::string GetDetectionString() = 0; - virtual void WaitForDetection() = 0; - -protected: - virtual ~ResourceManagerInterface() {}; -}; diff --git a/cli.cpp b/cli.cpp index 80e369cb6..ef7830675 100644 --- a/cli.cpp +++ b/cli.cpp @@ -472,7 +472,7 @@ void OptionListDevices(std::vector& rgb_controllers) /*---------------------------------------------------------*\ | Print device type | \*---------------------------------------------------------*/ - std::cout << " Type: " << device_type_to_str(controller->GetDeviceType()) << std::endl; + std::cout << " Type: " << RGBController::DeviceTypeToString(controller->GetDeviceType()) << std::endl; /*---------------------------------------------------------*\ | Print device description | diff --git a/qt/ManualDevicesSettingsPage/BaseManualDeviceEntry.h b/qt/ManualDevicesSettingsPage/BaseManualDeviceEntry.h index d2acb9cbe..3d5e8ede2 100644 --- a/qt/ManualDevicesSettingsPage/BaseManualDeviceEntry.h +++ b/qt/ManualDevicesSettingsPage/BaseManualDeviceEntry.h @@ -10,7 +10,7 @@ #pragma once #include -#include "nlohmann/json.hpp" +#include using json = nlohmann::json; diff --git a/qt/ManualDevicesSettingsPage/DDPSettingsEntry/DDPSettingsEntry.cpp b/qt/ManualDevicesSettingsPage/DDPSettingsEntry/DDPSettingsEntry.cpp index 2934cf745..609c5764c 100644 --- a/qt/ManualDevicesSettingsPage/DDPSettingsEntry/DDPSettingsEntry.cpp +++ b/qt/ManualDevicesSettingsPage/DDPSettingsEntry/DDPSettingsEntry.cpp @@ -10,7 +10,7 @@ #include "DDPSettingsEntry.h" #include "ui_DDPSettingsEntry.h" #include "ManualDevicesTypeManager.h" -#include "nlohmann/json.hpp" +#include using json = nlohmann::json; diff --git a/qt/ManualDevicesSettingsPage/DebugSettingsEntry/DebugSettingsEntry.cpp b/qt/ManualDevicesSettingsPage/DebugSettingsEntry/DebugSettingsEntry.cpp index eda33e408..b71ec7d50 100644 --- a/qt/ManualDevicesSettingsPage/DebugSettingsEntry/DebugSettingsEntry.cpp +++ b/qt/ManualDevicesSettingsPage/DebugSettingsEntry/DebugSettingsEntry.cpp @@ -12,7 +12,7 @@ #include "DebugSettingsEntry.h" #include "ui_DebugSettingsEntry.h" #include "ManualDevicesTypeManager.h" -#include "nlohmann/json.hpp" +#include using json = nlohmann::json; diff --git a/qt/ManualDevicesSettingsPage/ManualDevicesSettingsPage.h b/qt/ManualDevicesSettingsPage/ManualDevicesSettingsPage.h index 37cba73a9..9c633bb20 100644 --- a/qt/ManualDevicesSettingsPage/ManualDevicesSettingsPage.h +++ b/qt/ManualDevicesSettingsPage/ManualDevicesSettingsPage.h @@ -11,7 +11,7 @@ #include "BaseManualDeviceEntry.h" #include "ManualDevicesTypeManager.h" -#include "nlohmann/json.hpp" +#include #include #include #include diff --git a/qt/ManualDevicesSettingsPage/ManualDevicesTypeManager.h b/qt/ManualDevicesSettingsPage/ManualDevicesTypeManager.h index 0ec8bed0a..bf8f43be4 100644 --- a/qt/ManualDevicesSettingsPage/ManualDevicesTypeManager.h +++ b/qt/ManualDevicesSettingsPage/ManualDevicesTypeManager.h @@ -15,7 +15,7 @@ #include #include -#include "nlohmann/json.hpp" +#include using json = nlohmann::json; diff --git a/qt/OpenRGBDeviceInfoPage/OpenRGBDeviceInfoPage.cpp b/qt/OpenRGBDeviceInfoPage/OpenRGBDeviceInfoPage.cpp index f74cd61d1..6745b6b03 100644 --- a/qt/OpenRGBDeviceInfoPage/OpenRGBDeviceInfoPage.cpp +++ b/qt/OpenRGBDeviceInfoPage/OpenRGBDeviceInfoPage.cpp @@ -18,7 +18,7 @@ OpenRGBDeviceInfoPage::OpenRGBDeviceInfoPage(RGBController *dev, QWidget *parent ui->setupUi(this); - ui->TypeValue->setText(device_type_to_str(dev->GetDeviceType()).c_str()); + ui->TypeValue->setText(RGBController::DeviceTypeToString(dev->GetDeviceType()).c_str()); ui->NameValue->setText(QString::fromStdString(dev->GetName())); ui->VendorValue->setText(QString::fromStdString(dev->GetVendor())); diff --git a/qt/OpenRGBDynamicSettingsWidget/OpenRGBDynamicSettingsWidget.h b/qt/OpenRGBDynamicSettingsWidget/OpenRGBDynamicSettingsWidget.h index f42d4abd4..8b82dfbd5 100644 --- a/qt/OpenRGBDynamicSettingsWidget/OpenRGBDynamicSettingsWidget.h +++ b/qt/OpenRGBDynamicSettingsWidget/OpenRGBDynamicSettingsWidget.h @@ -14,7 +14,7 @@ #include #include #include -#include "nlohmann/json.hpp" +#include /*---------------------------------------------------------*\ | Callback Type | diff --git a/qt/OpenRGBSettingsPage/OpenRGBSettingsPage.h b/qt/OpenRGBSettingsPage/OpenRGBSettingsPage.h index bdc4fdd20..55b0eae69 100644 --- a/qt/OpenRGBSettingsPage/OpenRGBSettingsPage.h +++ b/qt/OpenRGBSettingsPage/OpenRGBSettingsPage.h @@ -12,7 +12,7 @@ #pragma once #include -#include "nlohmann/json.hpp" +#include namespace Ui {