diff --git a/NetworkServer.cpp b/NetworkServer.cpp index 8d9f0eb73..ce982e554 100644 --- a/NetworkServer.cpp +++ b/NetworkServer.cpp @@ -70,10 +70,11 @@ NetworkServer::NetworkServer(std::vector& control) : controller for(int i = 0; i < MAXSOCK; i++) { - ConnectionThread[i] = nullptr; + ConnectionThread[i] = nullptr; } - profile_manager = nullptr; + plugin_manager = nullptr; + profile_manager = nullptr; } NetworkServer::~NetworkServer() @@ -936,21 +937,17 @@ void NetworkServer::ListenThreadFunction(NetworkClientInfo * client_info) break; case NET_PACKET_ID_PLUGIN_SPECIFIC: + if(plugin_manager) { - unsigned int plugin_pkt_type = *((unsigned int*)(data)); - unsigned int plugin_pkt_size = header.pkt_size - (sizeof(unsigned int)); - unsigned char* plugin_data = (unsigned char*)(data + sizeof(unsigned int)); + unsigned int plugin_pkt_id = *((unsigned int*)(data)); + unsigned int plugin_pkt_size = header.pkt_size - (sizeof(unsigned int)); + unsigned char* plugin_data = (unsigned char*)(data + sizeof(unsigned int)); + unsigned char* output = plugin_manager->OnSDKCommand(header.pkt_dev_idx, plugin_pkt_id, plugin_data, &plugin_pkt_size); - if(header.pkt_dev_idx < plugins.size()) + if(output != nullptr) { - NetworkPlugin plugin = plugins[header.pkt_dev_idx]; - unsigned char* output = plugin.callback(plugin.callback_arg, plugin_pkt_type, plugin_data, &plugin_pkt_size); - if(output != nullptr) - { - SendReply_PluginSpecific(client_sock, plugin_pkt_type, output, plugin_pkt_size); - } + SendReply_PluginSpecific(client_sock, plugin_pkt_id, output, plugin_pkt_size); } - break; } break; @@ -1162,7 +1159,7 @@ void NetworkServer::SendReply_PluginList(SOCKET client_sock) /*---------------------------------------------------------*\ | Calculate data size | \*---------------------------------------------------------*/ - unsigned short num_plugins = (unsigned short)plugins.size(); + unsigned short num_plugins = (unsigned short)plugin_manager->GetPluginCount(); data_size += sizeof(data_size); data_size += sizeof(num_plugins); @@ -1170,9 +1167,9 @@ void NetworkServer::SendReply_PluginList(SOCKET client_sock) for(unsigned int i = 0; i < num_plugins; i++) { data_size += sizeof(unsigned short) * 3; - data_size += (unsigned int)strlen(plugins[i].name.c_str()) + 1; - data_size += (unsigned int)strlen(plugins[i].description.c_str()) + 1; - data_size += (unsigned int)strlen(plugins[i].version.c_str()) + 1; + data_size += (unsigned int)strlen(plugin_manager->GetPluginName(i).c_str()) + 1; + data_size += (unsigned int)strlen(plugin_manager->GetPluginDescription(i).c_str()) + 1; + data_size += (unsigned int)strlen(plugin_manager->GetPluginVersion(i).c_str()) + 1; data_size += sizeof(unsigned int) * 2; } @@ -1198,34 +1195,34 @@ void NetworkServer::SendReply_PluginList(SOCKET client_sock) /*---------------------------------------------------------*\ | Copy in plugin name (size+data) | \*---------------------------------------------------------*/ - unsigned short str_len = (unsigned short)strlen(plugins[i].name.c_str()) + 1; + unsigned short str_len = (unsigned short)strlen(plugin_manager->GetPluginName(i).c_str()) + 1; memcpy(&data_buf[data_ptr], &str_len, sizeof(unsigned short)); data_ptr += sizeof(unsigned short); - strcpy((char *)&data_buf[data_ptr], plugins[i].name.c_str()); + strcpy((char *)&data_buf[data_ptr], plugin_manager->GetPluginName(i).c_str()); data_ptr += str_len; /*---------------------------------------------------------*\ | Copy in plugin description (size+data) | \*---------------------------------------------------------*/ - str_len = (unsigned short)strlen(plugins[i].description.c_str()) + 1; + str_len = (unsigned short)strlen(plugin_manager->GetPluginDescription(i).c_str()) + 1; memcpy(&data_buf[data_ptr], &str_len, sizeof(unsigned short)); data_ptr += sizeof(unsigned short); - strcpy((char *)&data_buf[data_ptr], plugins[i].description.c_str()); + strcpy((char *)&data_buf[data_ptr], plugin_manager->GetPluginDescription(i).c_str()); data_ptr += str_len; /*---------------------------------------------------------*\ | Copy in plugin version (size+data) | \*---------------------------------------------------------*/ - str_len = (unsigned short)strlen(plugins[i].version.c_str()) + 1; + str_len = (unsigned short)strlen(plugin_manager->GetPluginVersion(i).c_str()) + 1; memcpy(&data_buf[data_ptr], &str_len, sizeof(unsigned short)); data_ptr += sizeof(unsigned short); - strcpy((char *)&data_buf[data_ptr], plugins[i].version.c_str()); + strcpy((char *)&data_buf[data_ptr], plugin_manager->GetPluginVersion(i).c_str()); data_ptr += str_len; /*---------------------------------------------------------*\ @@ -1237,7 +1234,8 @@ void NetworkServer::SendReply_PluginList(SOCKET client_sock) /*---------------------------------------------------------*\ | Copy in plugin sdk version (data) | \*---------------------------------------------------------*/ - memcpy(&data_buf[data_ptr], &plugins[i].protocol_version, sizeof(unsigned int)); + unsigned int protocol_version = plugin_manager->GetPluginProtocolVersion(i); + memcpy(&data_buf[data_ptr], &protocol_version, sizeof(unsigned int)); data_ptr += sizeof(unsigned int); } @@ -1256,39 +1254,27 @@ void NetworkServer::SendReply_PluginList(SOCKET client_sock) delete [] data_buf; } -void NetworkServer::SendReply_PluginSpecific(SOCKET client_sock, unsigned int pkt_type, unsigned char* data, unsigned int data_size) +void NetworkServer::SendReply_PluginSpecific(SOCKET client_sock, unsigned int pkt_id, unsigned char* data, unsigned int data_size) { NetPacketHeader reply_hdr; - InitNetPacketHeader(&reply_hdr, 0, NET_PACKET_ID_PLUGIN_SPECIFIC, data_size + sizeof(pkt_type)); + InitNetPacketHeader(&reply_hdr, 0, NET_PACKET_ID_PLUGIN_SPECIFIC, data_size + sizeof(pkt_id)); send_in_progress.lock(); send(client_sock, (const char *)&reply_hdr, sizeof(NetPacketHeader), 0); - send(client_sock, (const char *)&pkt_type, sizeof(pkt_type), 0); + send(client_sock, (const char *)&pkt_id, sizeof(pkt_id), 0); send(client_sock, (const char *)data, data_size, 0); send_in_progress.unlock(); delete [] data; } +void NetworkServer::SetPluginManager(PluginManagerInterface* plugin_manager_pointer) +{ + plugin_manager = plugin_manager_pointer; +} + void NetworkServer::SetProfileManager(ProfileManagerInterface* profile_manager_pointer) { profile_manager = profile_manager_pointer; } - -void NetworkServer::RegisterPlugin(NetworkPlugin plugin) -{ - plugins.push_back(plugin); -} - -void NetworkServer::UnregisterPlugin(std::string plugin_name) -{ - for(std::vector::iterator it = plugins.begin(); it != plugins.end(); it++) - { - if(it->name == plugin_name) - { - plugins.erase(it); - break; - } - } -} diff --git a/NetworkServer.h b/NetworkServer.h index 8962205c0..96eff12d2 100644 --- a/NetworkServer.h +++ b/NetworkServer.h @@ -17,6 +17,7 @@ #include "RGBController.h" #include "NetworkProtocol.h" #include "net_port.h" +#include "PluginManagerInterface.h" #include "ProfileManager.h" #include "ResourceManager.h" @@ -24,17 +25,6 @@ #define TCP_TIMEOUT_SECONDS 5 typedef void (*NetServerCallback)(void *); -typedef unsigned char* (*NetPluginCallback)(void *, unsigned int, unsigned char*, unsigned int*); - -struct NetworkPlugin -{ - std::string name; - std::string description; - std::string version; - NetPluginCallback callback; - void* callback_arg; - unsigned int protocol_version; -}; class NetworkClientInfo { @@ -94,11 +84,9 @@ public: void SendReply_PluginList(SOCKET client_sock); void SendReply_PluginSpecific(SOCKET client_sock, unsigned int pkt_type, unsigned char* data, unsigned int data_size); + void SetPluginManager(PluginManagerInterface* plugin_manager_pointer); void SetProfileManager(ProfileManagerInterface* profile_manager_pointer); - void RegisterPlugin(NetworkPlugin plugin); - void UnregisterPlugin(std::string plugin_name); - protected: std::string host; unsigned short port_num; @@ -119,10 +107,9 @@ protected: std::vector ServerListeningChangeCallbacks; std::vector ServerListeningChangeCallbackArgs; + PluginManagerInterface* plugin_manager; ProfileManagerInterface* profile_manager; - std::vector plugins; - std::mutex send_in_progress; private: diff --git a/OpenRGBPluginInterface.h b/OpenRGBPluginInterface.h index 45ad382ae..44b9d4c3f 100644 --- a/OpenRGBPluginInterface.h +++ b/OpenRGBPluginInterface.h @@ -1,7 +1,7 @@ /*---------------------------------------------------------*\ | OpenRGBPluginInterface.h | | | -| OpenRGB SDK network protocol | +| OpenRGB Plugin API | | | | herosilas12 (CoffeeIsLife) 11 Dec 2020 | | Adam Honse (CalcProgrammer1) 05 Jan 2021 | @@ -62,6 +62,11 @@ struct OpenRGBPluginInfo std::string Label; /* Plugin tab label string */ std::string TabIconString; /* Plugin tab icon string, leave empty to use custom */ QImage TabIcon; /* Custom tab icon image (displayed 16x16) */ + + /*-----------------------------------------------------*\ + | Plugin SDK Details | + \*-----------------------------------------------------*/ + unsigned int ProtocolVersion;/* Plugin SDK protocol version */ }; class OpenRGBPluginInterface @@ -82,6 +87,7 @@ public: virtual QWidget* GetWidget() = 0; virtual QMenu* GetTrayMenu() = 0; virtual void Unload() = 0; + virtual unsigned char* OnSDKCommand(unsigned int pkt_id, unsigned char * pkt_data, unsigned int *pkt_size) = 0; }; Q_DECLARE_INTERFACE(OpenRGBPluginInterface, OpenRGBPluginInterface_IID) diff --git a/PluginManager.cpp b/PluginManager.cpp index 4e52eb50e..a758740cc 100644 --- a/PluginManager.cpp +++ b/PluginManager.cpp @@ -532,3 +532,75 @@ void PluginManager::UnloadPlugins() UnloadPlugin(&plugin_entry); } } + +unsigned char * PluginManager::OnSDKCommand(unsigned int plugin_idx, unsigned int pkt_id, unsigned char * pkt_data, unsigned int * pkt_size) +{ + unsigned char * out_data = NULL; + + if(plugin_idx < ActivePlugins.size()) + { + if(ActivePlugins[plugin_idx].enabled && ActivePlugins[plugin_idx].loader->isLoaded()) + { + out_data = ActivePlugins[plugin_idx].plugin->OnSDKCommand(pkt_id, pkt_data, pkt_size); + } + } + + return(out_data); +} + +unsigned int PluginManager::GetPluginCount() +{ + return(ActivePlugins.size()); +} + +std::string PluginManager::GetPluginDescription(unsigned int plugin_idx) +{ + if(plugin_idx < ActivePlugins.size()) + { + if(ActivePlugins[plugin_idx].enabled && ActivePlugins[plugin_idx].loader->isLoaded()) + { + return(ActivePlugins[plugin_idx].plugin->GetPluginInfo().Description); + } + } + + return(""); +} + +std::string PluginManager::GetPluginName(unsigned int plugin_idx) +{ + if(plugin_idx < ActivePlugins.size()) + { + if(ActivePlugins[plugin_idx].enabled && ActivePlugins[plugin_idx].loader->isLoaded()) + { + return(ActivePlugins[plugin_idx].plugin->GetPluginInfo().Name); + } + } + + return(""); +} + +unsigned int PluginManager::GetPluginProtocolVersion(unsigned int plugin_idx) +{ + if(plugin_idx < ActivePlugins.size()) + { + if(ActivePlugins[plugin_idx].enabled && ActivePlugins[plugin_idx].loader->isLoaded()) + { + return(ActivePlugins[plugin_idx].plugin->GetPluginInfo().ProtocolVersion); + } + } + + return(0); +} + +std::string PluginManager::GetPluginVersion(unsigned int plugin_idx) +{ + if(plugin_idx < ActivePlugins.size()) + { + if(ActivePlugins[plugin_idx].enabled && ActivePlugins[plugin_idx].loader->isLoaded()) + { + return(ActivePlugins[plugin_idx].plugin->GetPluginInfo().Version); + } + } + + return(""); +} diff --git a/PluginManager.h b/PluginManager.h index 3b8e599eb..6fdd177ad 100644 --- a/PluginManager.h +++ b/PluginManager.h @@ -16,6 +16,7 @@ #include #include #include "OpenRGBPluginInterface.h" +#include "PluginManagerInterface.h" struct OpenRGBPluginEntry { @@ -34,11 +35,17 @@ struct OpenRGBPluginEntry typedef void (*AddPluginCallback)(void *, OpenRGBPluginEntry* plugin); typedef void (*RemovePluginCallback)(void *, OpenRGBPluginEntry* plugin); -class PluginManager +class PluginManager : public PluginManagerInterface { public: PluginManager(); + unsigned int GetPluginCount(); + std::string GetPluginDescription(unsigned int plugin_idx); + std::string GetPluginName(unsigned int plugin_idx); + unsigned int GetPluginProtocolVersion(unsigned int plugin_idx); + std::string GetPluginVersion(unsigned int plugin_idx); + void RegisterAddPluginCallback(AddPluginCallback new_callback, void * new_callback_arg); void RegisterRemovePluginCallback(RemovePluginCallback new_callback, void * new_callback_arg); @@ -53,6 +60,8 @@ public: void LoadPlugins(); void UnloadPlugins(); + unsigned char * OnSDKCommand(unsigned int plugin_idx, unsigned int pkt_id, unsigned char * pkt_data, unsigned int * pkt_size); + std::vector ActivePlugins; private: diff --git a/PluginManagerInterface.h b/PluginManagerInterface.h new file mode 100644 index 000000000..1ec748877 --- /dev/null +++ b/PluginManagerInterface.h @@ -0,0 +1,29 @@ +/*---------------------------------------------------------*\ +| PluginManagerInterface.h | +| | +| OpenRGB plugin manager interface | +| | +| Adam Honse Nov 18 2025 | +| | +| This file is part of the OpenRGB project | +| SPDX-License-Identifier: GPL-2.0-or-later | +\*---------------------------------------------------------*/ + +#pragma once + +#include + +class PluginManagerInterface +{ +public: + virtual unsigned int GetPluginCount() = 0; + virtual std::string GetPluginDescription(unsigned int plugin_idx) = 0; + virtual std::string GetPluginName(unsigned int plugin_idx) = 0; + virtual unsigned int GetPluginProtocolVersion(unsigned int plugin_idx) = 0; + virtual std::string GetPluginVersion(unsigned int plugin_idx) = 0; + + virtual void LoadPlugins() = 0; + virtual void UnloadPlugins() = 0; + + virtual unsigned char * OnSDKCommand(unsigned int plugin_idx, unsigned int pkt_id, unsigned char * pkt_data, unsigned int * pkt_size) = 0; +}; diff --git a/ResourceManager.cpp b/ResourceManager.cpp index 5e97dff08..d354569e8 100644 --- a/ResourceManager.cpp +++ b/ResourceManager.cpp @@ -820,6 +820,11 @@ std::vector& ResourceManager::GetClients() return(clients); } +PluginManagerInterface* ResourceManager::GetPluginManager() +{ + return(plugin_manager); +} + ProfileManager* ResourceManager::GetProfileManager() { return(profile_manager); @@ -1717,6 +1722,12 @@ void ResourceManager::DetectDevicesCoroutine() } } +void ResourceManager::SetPluginManager(PluginManagerInterface* plugin_manager_ptr) +{ + plugin_manager = plugin_manager_ptr; + server->SetPluginManager(plugin_manager); +} + void ResourceManager::StopDeviceDetection() { LOG_INFO("[ResourceManager] Detection abort requested"); diff --git a/ResourceManager.h b/ResourceManager.h index b4abbed25..208e1b5d4 100644 --- a/ResourceManager.h +++ b/ResourceManager.h @@ -19,12 +19,12 @@ #include #include #include +#include #include "SPDWrapper.h" #include "hidapi_wrapper.h" #include "i2c_smbus.h" #include "ResourceManagerInterface.h" #include "filesystem.h" -#include using json = nlohmann::json; @@ -35,6 +35,7 @@ using json = nlohmann::json; struct hid_device_info; class NetworkClient; class NetworkServer; +class PluginManagerInterface; class ProfileManager; class RGBController; class SettingsManager; @@ -167,6 +168,7 @@ public: std::vector& GetClients(); NetworkServer* GetServer(); + PluginManagerInterface* GetPluginManager(); ProfileManager* GetProfileManager(); SettingsManager* GetSettingsManager(); @@ -190,6 +192,8 @@ public: void RescanDevices(); + void SetPluginManager(PluginManagerInterface* plugin_manager_ptr); + void StopDeviceDetection(); void WaitForInitialization(); @@ -259,6 +263,11 @@ private: \*-----------------------------------------------------*/ bool initial_detection; + /*-----------------------------------------------------*\ + | Plugin Manager | + \*-----------------------------------------------------*/ + PluginManagerInterface* plugin_manager; + /*-----------------------------------------------------*\ | Profile Manager | \*-----------------------------------------------------*/ diff --git a/ResourceManagerInterface.h b/ResourceManagerInterface.h index a06b87ff7..e7f6d359b 100644 --- a/ResourceManagerInterface.h +++ b/ResourceManagerInterface.h @@ -15,8 +15,7 @@ #include "i2c_smbus.h" #include "filesystem.h" -class NetworkClient; -class NetworkServer; +class PluginManagerInterface; class ProfileManager; class RGBController; class SettingsManager; @@ -54,9 +53,7 @@ public: virtual filesystem::path GetConfigurationDirectory() = 0; - virtual std::vector& GetClients() = 0; - virtual NetworkServer* GetServer() = 0; - + virtual PluginManagerInterface* GetPluginManager() = 0; virtual ProfileManager* GetProfileManager() = 0; virtual SettingsManager* GetSettingsManager() = 0; diff --git a/qt/OpenRGBDialog/OpenRGBDialog.cpp b/qt/OpenRGBDialog/OpenRGBDialog.cpp index 9ea23df55..635956f8a 100644 --- a/qt/OpenRGBDialog/OpenRGBDialog.cpp +++ b/qt/OpenRGBDialog/OpenRGBDialog.cpp @@ -494,6 +494,7 @@ OpenRGBDialog::OpenRGBDialog(QWidget *parent) : QMainWindow(parent), ui(new Ui:: | Initialize the plugin manager | \*-----------------------------------------------------*/ plugin_manager = new PluginManager(); + ResourceManager::get()->SetPluginManager(plugin_manager); plugin_manager->RegisterAddPluginCallback(&CreatePluginCallback, this); plugin_manager->RegisterRemovePluginCallback(&DeletePluginCallback, this);