From 2a7f9b4e769f00a8f1303c03c06d34e12ae47c78 Mon Sep 17 00:00:00 2001 From: falkTX Date: Sat, 22 Jun 2013 03:46:12 +0100 Subject: [PATCH] Fix for canvas icons; listen for external changes --- source/backend/CarlaBackend.hpp | 26 +++-- source/backend/engine/CarlaEngineJack.cpp | 134 +++++++++++++++++----- source/carla.py | 22 +++- source/carla_backend.py | 19 +-- source/utils/CarlaBackendUtils.hpp | 2 + 5 files changed, 154 insertions(+), 49 deletions(-) diff --git a/source/backend/CarlaBackend.hpp b/source/backend/CarlaBackend.hpp index 212793c49..173fe0423 100644 --- a/source/backend/CarlaBackend.hpp +++ b/source/backend/CarlaBackend.hpp @@ -604,15 +604,23 @@ enum CallbackType { */ CALLBACK_PATCHBAY_CONNECTION_REMOVED = 25, + /*! + * Canvas client icon changed + * + * \param value1 Client Id + * \param value2 Client Icon + */ + CALLBACK_PATCHBAY_ICON_CHANGED = 26, + /*! * Engine buffer-size changed. */ - CALLBACK_BUFFER_SIZE_CHANGED = 26, + CALLBACK_BUFFER_SIZE_CHANGED = 27, /*! * Engine sample-rate changed. */ - CALLBACK_SAMPLE_RATE_CHANGED = 27, + CALLBACK_SAMPLE_RATE_CHANGED = 28, /*! * Engine process mode changed. @@ -620,37 +628,37 @@ enum CallbackType { * \param value1 New process mode * \see ProcessMode */ - CALLBACK_PROCESS_MODE_CHANGED = 28, + CALLBACK_PROCESS_MODE_CHANGED = 29, /*! * Non-Session-Manager Announce message. */ - CALLBACK_NSM_ANNOUNCE = 29, + CALLBACK_NSM_ANNOUNCE = 30, /*! * Non-Session-Manager Open message. */ - CALLBACK_NSM_OPEN = 30, + CALLBACK_NSM_OPEN = 31, /*! * Non-Session-Manager Save message. */ - CALLBACK_NSM_SAVE = 31, + CALLBACK_NSM_SAVE = 32, /*! * An error occurred, show \a valueStr as an error to user. */ - CALLBACK_ERROR = 32, + CALLBACK_ERROR = 33, /*! * Show \a valueStr as info to user. */ - CALLBACK_INFO = 33, + CALLBACK_INFO = 34, /*! * The engine has crashed or malfunctioned and will no longer work. */ - CALLBACK_QUIT = 34 + CALLBACK_QUIT = 35 }; /*! diff --git a/source/backend/engine/CarlaEngineJack.cpp b/source/backend/engine/CarlaEngineJack.cpp index 782002ba3..482a8230e 100644 --- a/source/backend/engine/CarlaEngineJack.cpp +++ b/source/backend/engine/CarlaEngineJack.cpp @@ -631,6 +631,7 @@ public: fUsedGroupNames.clear(); fUsedPortNames.clear(); fUsedConnections.clear(); + fGroupIconsChanged.clear(); #endif } @@ -673,6 +674,7 @@ public: fUsedGroupNames.clear(); fUsedPortNames.clear(); fUsedConnections.clear(); + fGroupIconsChanged.clear(); fClient = jackbridge_client_open(clientName, JackNullOption, nullptr); @@ -682,6 +684,7 @@ public: fSampleRate = jackbridge_get_sample_rate(fClient); jackbridge_custom_publish_data(fClient, URI_CANVAS_ICON, "carla", 6); + jackbridge_custom_set_data_appearance_callback(fClient, carla_jack_custom_appearance_callback, this); jackbridge_set_buffer_size_callback(fClient, carla_jack_bufsize_callback, this); jackbridge_set_sample_rate_callback(fClient, carla_jack_srate_callback, this); @@ -782,10 +785,68 @@ public: fUsedGroupNames.clear(); fUsedPortNames.clear(); fUsedConnections.clear(); + fGroupIconsChanged.clear(); #endif return false; } + void idle() override + { + CarlaEngine::idle(); + + if (fGroupIconsChanged.count() == 0) + return; + + static bool checkIcons = false; + + if (! checkIcons) + { + checkIcons = true; // check them next time + return; + } + + checkIcons = false; + + void* data; + size_t dataSize; + + QList groupIconsCopy(fGroupIconsChanged); + fGroupIconsChanged.clear(); + + foreach (const int& groupId, groupIconsCopy) + { + const char* const groupName(getGroupName(groupId)); + + data = nullptr; + dataSize = 0; + + if (jackbridge_custom_get_data(fClient, groupName, URI_CANVAS_ICON, &data, &dataSize) && data != nullptr && dataSize != 0) + { + const char* const icon((const char*)data); + CARLA_ASSERT(std::strlen(icon)+1 == dataSize); + + PatchbayIconType groupIcon; + + if (std::strcmp(icon, "app") == 0 || std::strcmp(icon, "application") == 0) + groupIcon = PATCHBAY_ICON_APPLICATION; + else if (std::strcmp(icon, "hardware") == 0) + groupIcon = PATCHBAY_ICON_HARDWARE; + else if (std::strcmp(icon, "carla") == 0) + groupIcon = PATCHBAY_ICON_CARLA; + else if (std::strcmp(icon, "distrho") == 0) + groupIcon = PATCHBAY_ICON_DISTRHO; + else if (std::strcmp(icon, "file") == 0) + groupIcon = PATCHBAY_ICON_FILE; + else if (std::strcmp(icon, "plugin") == 0) + groupIcon = PATCHBAY_ICON_PLUGIN; + else + groupIcon = PATCHBAY_ICON_APPLICATION; + + callback(CALLBACK_PATCHBAY_ICON_CHANGED, 0, groupId, groupIcon, 0.0f, nullptr); + } + } + } + bool isRunning() const override { #ifdef BUILD_BRIDGE @@ -817,6 +878,7 @@ public: fSampleRate = jackbridge_get_sample_rate(client); jackbridge_custom_publish_data(client, URI_CANVAS_ICON, iconName, std::strlen(iconName)+1); + jackbridge_custom_set_data_appearance_callback(fClient, carla_jack_custom_appearance_callback, this); jackbridge_set_buffer_size_callback(client, carla_jack_bufsize_callback, this); jackbridge_set_sample_rate_callback(client, carla_jack_srate_callback, this); @@ -1016,6 +1078,7 @@ public: fUsedGroupNames.clear(); fUsedPortNames.clear(); fUsedConnections.clear(); + fGroupIconsChanged.clear(); initJackPatchbay(jackbridge_get_client_name(fClient)); } @@ -1051,6 +1114,19 @@ public: // ------------------------------------- protected: + void handleCustomAppearanceCallback(const char* client_name, const char* key, jack_custom_change_t change) + { + if ((change == JackCustomAdded || change == JackCustomReplaced) && std::strcmp(key, URI_CANVAS_ICON) == 0) + { + const int groupId (getGroupId(client_name)); + + if (groupId == -1) + return; + + fGroupIconsChanged.append(groupId); + } + } + void handleJackBufferSizeCallback(const uint32_t newBufferSize) { if (fBufferSize == newBufferSize) @@ -1426,33 +1502,9 @@ protected: GroupNameToId groupNameToId(groupId, groupName); fUsedGroupNames.append(groupNameToId); - PatchbayIconType groupIcon = PATCHBAY_ICON_APPLICATION; + callback(CALLBACK_PATCHBAY_CLIENT_ADDED, 0, groupId, PATCHBAY_ICON_APPLICATION, 0.0f, groupName); - void* data = nullptr; - size_t dataSize = 0; - - if (jackbridge_custom_get_data(fClient, groupName, URI_CANVAS_ICON, &data, &dataSize) && data != nullptr && dataSize != 0) - { - const char* const icon((const char*)data); - CARLA_ASSERT(std::strlen(icon)+1 == dataSize); - - if (std::strcmp(icon, "app") == 0 || std::strcmp(icon, "application") == 0) - groupIcon = PATCHBAY_ICON_APPLICATION; - else if (std::strcmp(icon, "hardware") == 0) - groupIcon = PATCHBAY_ICON_HARDWARE; - else if (std::strcmp(icon, "carla") == 0) - groupIcon = PATCHBAY_ICON_CARLA; - else if (std::strcmp(icon, "distrho") == 0) - groupIcon = PATCHBAY_ICON_DISTRHO; - else if (std::strcmp(icon, "file") == 0) - groupIcon = PATCHBAY_ICON_FILE; - else if (std::strcmp(icon, "plugin") == 0) - groupIcon = PATCHBAY_ICON_PLUGIN; - } - else if (jackPortFlags & JackPortIsPhysical) - groupIcon = PATCHBAY_ICON_HARDWARE; - - callback(CALLBACK_PATCHBAY_CLIENT_ADDED, 0, groupId, groupIcon, 0.0f, groupName); + fGroupIconsChanged.append(groupId); } bool portIsInput = (jackPortFlags & JackPortIsInput); @@ -1729,6 +1781,7 @@ private: QList fUsedGroupNames; QList fUsedPortNames; QList fUsedConnections; + QList fGroupIconsChanged; int getGroupId(const char* const name) { @@ -1746,6 +1799,24 @@ private: return -1; } + const char* getGroupName(const int groupId) + { + CARLA_ASSERT(groupId >= 0); + + static const char fallback[1] = { '\0' }; + + if (groupId < 0) + return fallback; + + foreach (const GroupNameToId& groupNameId, fUsedGroupNames) + { + if (groupNameId.id == groupId) + return groupNameId.name; + } + + return fallback; + } + int getPortId(const char* const fullName) { CARLA_ASSERT(fullName != nullptr); @@ -2023,10 +2094,9 @@ private: #define handlePtr ((CarlaEngineJack*)arg) - static int carla_jack_srate_callback(jack_nframes_t newSampleRate, void* arg) + static void carla_jack_custom_appearance_callback(const char* client_name, const char* key, jack_custom_change_t change, void* arg) { - handlePtr->handleJackSampleRateCallback(newSampleRate); - return 0; + handlePtr->handleCustomAppearanceCallback(client_name, key, change); } static int carla_jack_bufsize_callback(jack_nframes_t newBufferSize, void* arg) @@ -2035,6 +2105,12 @@ private: return 0; } + static int carla_jack_srate_callback(jack_nframes_t newSampleRate, void* arg) + { + handlePtr->handleJackSampleRateCallback(newSampleRate); + return 0; + } + static void carla_jack_freewheel_callback(int starting, void* arg) { handlePtr->handleJackFreewheelCallback(bool(starting)); diff --git a/source/carla.py b/source/carla.py index 6f25024d3..d7a0b7a57 100755 --- a/source/carla.py +++ b/source/carla.py @@ -883,6 +883,7 @@ class CarlaMainW(QMainWindow): self.connect(self, SIGNAL("PatchbayPortRenamedCallback(int, QString)"), SLOT("slot_handlePatchbayPortRenamedCallback(int, QString)")) self.connect(self, SIGNAL("PatchbayConnectionAddedCallback(int, int, int)"), SLOT("slot_handlePatchbayConnectionAddedCallback(int, int, int)")) self.connect(self, SIGNAL("PatchbayConnectionRemovedCallback(int)"), SLOT("slot_handlePatchbayConnectionRemovedCallback(int)")) + self.connect(self, SIGNAL("PatchbayIconChangedCallback(int, int)"), SLOT("slot_handlePatchbayIconChangedCallback(int, int)")) self.connect(self, SIGNAL("BufferSizeChangedCallback(int)"), SLOT("slot_handleBufferSizeChangedCallback(int)")) self.connect(self, SIGNAL("SampleRateChangedCallback(double)"), SLOT("slot_handleSampleRateChangedCallback(double)")) self.connect(self, SIGNAL("NSM_AnnounceCallback(QString)"), SLOT("slot_handleNSM_AnnounceCallback(QString)")) @@ -1909,12 +1910,12 @@ class CarlaMainW(QMainWindow): if clientIcon == PATCHBAY_ICON_HARDWARE: pcSplit = patchcanvas.SPLIT_YES pcIcon = patchcanvas.ICON_HARDWARE - elif clientIcon == PATCHBAY_ICON_PLUGIN: - pcIcon = patchcanvas.ICON_PLUGIN elif clientIcon == PATCHBAY_ICON_DISTRHO: pcIcon = patchcanvas.ICON_DISTRHO elif clientIcon == PATCHBAY_ICON_FILE: pcIcon = patchcanvas.ICON_FILE + elif clientIcon == PATCHBAY_ICON_PLUGIN: + pcIcon = patchcanvas.ICON_PLUGIN patchcanvas.addGroup(clientId, clientName, pcSplit, pcIcon) QTimer.singleShot(0, self.ui.miniCanvasPreview, SLOT("update()")) @@ -1971,6 +1972,21 @@ class CarlaMainW(QMainWindow): patchcanvas.disconnectPorts(connectionId) QTimer.singleShot(0, self.ui.miniCanvasPreview, SLOT("update()")) + @pyqtSlot(int, int) + def slot_handlePatchbayIconChangedCallback(self, clientId, clientIcon): + pcIcon = patchcanvas.ICON_APPLICATION + + if clientIcon == PATCHBAY_ICON_HARDWARE: + pcIcon = patchcanvas.ICON_HARDWARE + elif clientIcon == PATCHBAY_ICON_DISTRHO: + pcIcon = patchcanvas.ICON_DISTRHO + elif clientIcon == PATCHBAY_ICON_FILE: + pcIcon = patchcanvas.ICON_FILE + elif clientIcon == PATCHBAY_ICON_PLUGIN: + pcIcon = patchcanvas.ICON_PLUGIN + + patchcanvas.setGroupIcon(clientId, pcIcon) + @pyqtSlot(int) def slot_handleBufferSizeChangedCallback(self, newBufferSize): self.fBufferSize = newBufferSize @@ -2286,6 +2302,8 @@ def engineCallback(ptr, action, pluginId, value1, value2, value3, valueStr): Carla.gui.emit(SIGNAL("PatchbayConnectionAddedCallback(int, int, int)"), value1, value2, value3) elif action == CALLBACK_PATCHBAY_CONNECTION_REMOVED: Carla.gui.emit(SIGNAL("PatchbayConnectionRemovedCallback(int)"), value1) + elif action == CALLBACK_PATCHBAY_ICON_CHANGED: + Carla.gui.emit(SIGNAL("PatchbayIconChangedCallback(int, int)"), value1, value2) elif action == CALLBACK_BUFFER_SIZE_CHANGED: Carla.gui.emit(SIGNAL("BufferSizeChangedCallback(int)"), value1) elif action == CALLBACK_SAMPLE_RATE_CHANGED: diff --git a/source/carla_backend.py b/source/carla_backend.py index cd94e7907..b33eca3a0 100644 --- a/source/carla_backend.py +++ b/source/carla_backend.py @@ -255,15 +255,16 @@ CALLBACK_PATCHBAY_PORT_REMOVED = 22 CALLBACK_PATCHBAY_PORT_RENAMED = 23 CALLBACK_PATCHBAY_CONNECTION_ADDED = 24 CALLBACK_PATCHBAY_CONNECTION_REMOVED = 25 -CALLBACK_BUFFER_SIZE_CHANGED = 26 -CALLBACK_SAMPLE_RATE_CHANGED = 27 -CALLBACK_PROCESS_MODE_CHANGED = 28 -CALLBACK_NSM_ANNOUNCE = 29 -CALLBACK_NSM_OPEN = 30 -CALLBACK_NSM_SAVE = 31 -CALLBACK_ERROR = 32 -CALLBACK_INFO = 33 -CALLBACK_QUIT = 34 +CALLBACK_PATCHBAY_ICON_CHANGED = 26 +CALLBACK_BUFFER_SIZE_CHANGED = 27 +CALLBACK_SAMPLE_RATE_CHANGED = 28 +CALLBACK_PROCESS_MODE_CHANGED = 29 +CALLBACK_NSM_ANNOUNCE = 30 +CALLBACK_NSM_OPEN = 31 +CALLBACK_NSM_SAVE = 32 +CALLBACK_ERROR = 33 +CALLBACK_INFO = 34 +CALLBACK_QUIT = 35 # Process Mode PROCESS_MODE_SINGLE_CLIENT = 0 diff --git a/source/utils/CarlaBackendUtils.hpp b/source/utils/CarlaBackendUtils.hpp index 00edc69ab..fec60edd1 100644 --- a/source/utils/CarlaBackendUtils.hpp +++ b/source/utils/CarlaBackendUtils.hpp @@ -325,6 +325,8 @@ const char* CallbackType2Str(const CallbackType& type) return "CALLBACK_PATCHBAY_CONNECTION_ADDED"; case CALLBACK_PATCHBAY_CONNECTION_REMOVED: return "CALLBACK_PATCHBAY_CONNECTION_REMOVED"; + case CALLBACK_PATCHBAY_ICON_CHANGED: + return "CALLBACK_PATCHBAY_ICON_CHANGED"; case CALLBACK_RELOAD_INFO: return "CALLBACK_RELOAD_INFO"; case CALLBACK_RELOAD_PARAMETERS: