Signed-off-by: falkTX <falktx@falktx.com>pull/1807/head
| @@ -124,7 +124,7 @@ $(MODULEDIR)/carla_plugin.a: .FORCE | |||||
| $(MODULEDIR)/jackbridge.a: .FORCE | $(MODULEDIR)/jackbridge.a: .FORCE | ||||
| @$(MAKE) -C source/jackbridge | @$(MAKE) -C source/jackbridge | ||||
| $(MODULEDIR)/jackbridge.%.a: $(MODULEDIR)/jackbridge.a | |||||
| $(MODULEDIR)/jackbridge.%.a: .FORCE | |||||
| @$(MAKE) -C source/jackbridge $* | @$(MAKE) -C source/jackbridge $* | ||||
| $(MODULEDIR)/native-plugins.a: .FORCE | $(MODULEDIR)/native-plugins.a: .FORCE | ||||
| @@ -304,6 +304,7 @@ typedef bool (*CarlaPluginCheckCacheCallback)(void* ptr, const char* filename, c | |||||
| * @a carla_plugin_discovery_idle must be called at regular intervals afterwards. | * @a carla_plugin_discovery_idle must be called at regular intervals afterwards. | ||||
| */ | */ | ||||
| CARLA_PLUGIN_EXPORT CarlaPluginDiscoveryHandle carla_plugin_discovery_start(const char* discoveryTool, | CARLA_PLUGIN_EXPORT CarlaPluginDiscoveryHandle carla_plugin_discovery_start(const char* discoveryTool, | ||||
| BinaryType btype, | |||||
| PluginType ptype, | PluginType ptype, | ||||
| const char* pluginPath, | const char* pluginPath, | ||||
| CarlaPluginDiscoveryCallback discoveryCb, | CarlaPluginDiscoveryCallback discoveryCb, | ||||
| @@ -10,6 +10,7 @@ include ../Makefile.mk | |||||
| # --------------------------------------------------------------------------------------------------------------------- | # --------------------------------------------------------------------------------------------------------------------- | ||||
| BUILD_CXX_FLAGS += $(FLUIDSYNTH_FLAGS) | BUILD_CXX_FLAGS += $(FLUIDSYNTH_FLAGS) | ||||
| BUILD_CXX_FLAGS += $(MAGIC_LIBS) | |||||
| BUILD_CXX_FLAGS += $(YSFX_FLAGS) | BUILD_CXX_FLAGS += $(YSFX_FLAGS) | ||||
| # --------------------------------------------------------------------------------------------------------------------- | # --------------------------------------------------------------------------------------------------------------------- | ||||
| @@ -1,6 +1,6 @@ | |||||
| /* | /* | ||||
| * Carla Plugin Host | * Carla Plugin Host | ||||
| * Copyright (C) 2011-2022 Filipe Coelho <falktx@falktx.com> | |||||
| * Copyright (C) 2011-2023 Filipe Coelho <falktx@falktx.com> | |||||
| * | * | ||||
| * This program is free software; you can redistribute it and/or | * This program is free software; you can redistribute it and/or | ||||
| * modify it under the terms of the GNU General Public License as | * modify it under the terms of the GNU General Public License as | ||||
| @@ -18,6 +18,7 @@ | |||||
| #include "CarlaUtils.h" | #include "CarlaUtils.h" | ||||
| #include "CarlaBackendUtils.hpp" | #include "CarlaBackendUtils.hpp" | ||||
| #include "CarlaBinaryUtils.hpp" | |||||
| #include "CarlaJuceUtils.hpp" | #include "CarlaJuceUtils.hpp" | ||||
| #include "CarlaPipeUtils.hpp" | #include "CarlaPipeUtils.hpp" | ||||
| #include "CarlaSha1Utils.hpp" | #include "CarlaSha1Utils.hpp" | ||||
| @@ -64,12 +65,14 @@ class CarlaPluginDiscovery : private CarlaPipeServer | |||||
| { | { | ||||
| public: | public: | ||||
| CarlaPluginDiscovery(const char* const discoveryTool, | CarlaPluginDiscovery(const char* const discoveryTool, | ||||
| const BinaryType btype, | |||||
| const PluginType ptype, | const PluginType ptype, | ||||
| const std::vector<water::File>&& binaries, | const std::vector<water::File>&& binaries, | ||||
| const CarlaPluginDiscoveryCallback discoveryCb, | const CarlaPluginDiscoveryCallback discoveryCb, | ||||
| const CarlaPluginCheckCacheCallback checkCacheCb, | const CarlaPluginCheckCacheCallback checkCacheCb, | ||||
| void* const callbackPtr) | void* const callbackPtr) | ||||
| : fPluginType(ptype), | |||||
| : fBinaryType(btype), | |||||
| fPluginType(ptype), | |||||
| fDiscoveryCallback(discoveryCb), | fDiscoveryCallback(discoveryCb), | ||||
| fCheckCacheCallback(checkCacheCb), | fCheckCacheCallback(checkCacheCb), | ||||
| fCallbackPtr(callbackPtr), | fCallbackPtr(callbackPtr), | ||||
| @@ -87,11 +90,13 @@ public: | |||||
| } | } | ||||
| CarlaPluginDiscovery(const char* const discoveryTool, | CarlaPluginDiscovery(const char* const discoveryTool, | ||||
| const BinaryType btype, | |||||
| const PluginType ptype, | const PluginType ptype, | ||||
| const CarlaPluginDiscoveryCallback discoveryCb, | const CarlaPluginDiscoveryCallback discoveryCb, | ||||
| const CarlaPluginCheckCacheCallback checkCacheCb, | const CarlaPluginCheckCacheCallback checkCacheCb, | ||||
| void* const callbackPtr) | void* const callbackPtr) | ||||
| : fPluginType(ptype), | |||||
| : fBinaryType(btype), | |||||
| fPluginType(ptype), | |||||
| fDiscoveryCallback(discoveryCb), | fDiscoveryCallback(discoveryCb), | ||||
| fCheckCacheCallback(checkCacheCb), | fCheckCacheCallback(checkCacheCb), | ||||
| fCallbackPtr(callbackPtr), | fCallbackPtr(callbackPtr), | ||||
| @@ -340,6 +345,7 @@ protected: | |||||
| } | } | ||||
| private: | private: | ||||
| const BinaryType fBinaryType; | |||||
| const PluginType fPluginType; | const PluginType fPluginType; | ||||
| const CarlaPluginDiscoveryCallback fDiscoveryCallback; | const CarlaPluginDiscoveryCallback fDiscoveryCallback; | ||||
| const CarlaPluginCheckCacheCallback fCheckCacheCallback; | const CarlaPluginCheckCacheCallback fCheckCacheCallback; | ||||
| @@ -365,9 +371,25 @@ private: | |||||
| fPluginsFoundInBinary = false; | fPluginsFoundInBinary = false; | ||||
| fNextSha1Sum.clear(); | fNextSha1Sum.clear(); | ||||
| const char* helperTool; | |||||
| switch (fBinaryType) | |||||
| { | |||||
| #ifndef CARLA_OS_WIN | |||||
| case CB::BINARY_WIN32: | |||||
| helperTool = "wine"; | |||||
| break; | |||||
| case CB::BINARY_WIN64: | |||||
| helperTool = "wine64"; | |||||
| break; | |||||
| #endif | |||||
| default: | |||||
| helperTool = nullptr; | |||||
| break; | |||||
| } | |||||
| if (fBinaries.empty()) | if (fBinaries.empty()) | ||||
| { | { | ||||
| startPipeServer(fDiscoveryTool, | |||||
| startPipeServer(helperTool, fDiscoveryTool, | |||||
| getPluginTypeAsString(fPluginType), | getPluginTypeAsString(fPluginType), | ||||
| ":all"); | ":all"); | ||||
| } | } | ||||
| @@ -389,7 +411,7 @@ private: | |||||
| } | } | ||||
| carla_stdout("Scanning \"%s\"...", filename.toRawUTF8()); | carla_stdout("Scanning \"%s\"...", filename.toRawUTF8()); | ||||
| startPipeServer(fDiscoveryTool, getPluginTypeAsString(fPluginType), filename.toRawUTF8()); | |||||
| startPipeServer(helperTool, fDiscoveryTool, getPluginTypeAsString(fPluginType), filename.toRawUTF8()); | |||||
| } | } | ||||
| } | } | ||||
| @@ -455,7 +477,8 @@ static bool findDirectories(std::vector<water::File>& files, const char* const p | |||||
| return files.empty(); | return files.empty(); | ||||
| } | } | ||||
| static bool findFiles(std::vector<water::File>& files, const char* const pluginPath, const char* const wildcard) | |||||
| static bool findFiles(std::vector<water::File>& files, | |||||
| const BinaryType btype, const char* const pluginPath, const char* const wildcard) | |||||
| { | { | ||||
| CARLA_SAFE_ASSERT_RETURN(pluginPath != nullptr, true); | CARLA_SAFE_ASSERT_RETURN(pluginPath != nullptr, true); | ||||
| @@ -479,14 +502,22 @@ static bool findFiles(std::vector<water::File>& files, const char* const pluginP | |||||
| if (dir.findChildFiles(results, File::findFiles|File::ignoreHiddenFiles, true, wildcard) > 0) | if (dir.findChildFiles(results, File::findFiles|File::ignoreHiddenFiles, true, wildcard) > 0) | ||||
| { | { | ||||
| files.reserve(files.size() + results.size()); | files.reserve(files.size() + results.size()); | ||||
| files.insert(files.end(), results.begin(), results.end()); | |||||
| for (std::vector<File>::const_iterator cit = results.begin(); cit != results.end(); ++cit) | |||||
| { | |||||
| const File file(*cit); | |||||
| if (CB::getBinaryTypeFromFile(file.getFullPathName().toRawUTF8()) == btype) | |||||
| files.push_back(file); | |||||
| } | |||||
| } | } | ||||
| } | } | ||||
| return files.empty(); | return files.empty(); | ||||
| } | } | ||||
| static bool findVST3s(std::vector<water::File>& files, const char* const pluginPath) | |||||
| static bool findVST3s(std::vector<water::File>& files, | |||||
| const BinaryType btype, const char* const pluginPath) | |||||
| { | { | ||||
| CARLA_SAFE_ASSERT_RETURN(pluginPath != nullptr, true); | CARLA_SAFE_ASSERT_RETURN(pluginPath != nullptr, true); | ||||
| @@ -502,11 +533,9 @@ static bool findVST3s(std::vector<water::File>& files, const char* const pluginP | |||||
| if (splitPaths.size() == 0) | if (splitPaths.size() == 0) | ||||
| return true; | return true; | ||||
| #if defined(CARLA_OS_WIN) | |||||
| static constexpr const uint flags = File::findDirectories|File::findFiles; | |||||
| #else | |||||
| static constexpr const uint flags = File::findDirectories; | |||||
| #endif | |||||
| const uint flags = btype == CB::BINARY_WIN32 || btype == CB::BINARY_WIN64 | |||||
| ? File::findDirectories|File::findFiles | |||||
| : File::findDirectories; | |||||
| for (String *it = splitPaths.begin(), *end = splitPaths.end(); it != end; ++it) | for (String *it = splitPaths.begin(), *end = splitPaths.end(); it != end; ++it) | ||||
| { | { | ||||
| @@ -516,7 +545,14 @@ static bool findVST3s(std::vector<water::File>& files, const char* const pluginP | |||||
| if (dir.findChildFiles(results, flags|File::ignoreHiddenFiles, true, "*.vst3") > 0) | if (dir.findChildFiles(results, flags|File::ignoreHiddenFiles, true, "*.vst3") > 0) | ||||
| { | { | ||||
| files.reserve(files.size() + results.size()); | files.reserve(files.size() + results.size()); | ||||
| files.insert(files.end(), results.begin(), results.end()); | |||||
| for (std::vector<File>::const_iterator cit = results.begin(); cit != results.end(); ++cit) | |||||
| { | |||||
| const File file(*cit); | |||||
| if (CB::getBinaryTypeFromFile(file.getFullPathName().toRawUTF8()) == btype) | |||||
| files.push_back(file); | |||||
| } | |||||
| } | } | ||||
| } | } | ||||
| @@ -524,12 +560,15 @@ static bool findVST3s(std::vector<water::File>& files, const char* const pluginP | |||||
| } | } | ||||
| CarlaPluginDiscoveryHandle carla_plugin_discovery_start(const char* const discoveryTool, | CarlaPluginDiscoveryHandle carla_plugin_discovery_start(const char* const discoveryTool, | ||||
| const BinaryType btype, | |||||
| const PluginType ptype, | const PluginType ptype, | ||||
| const char* const pluginPath, | const char* const pluginPath, | ||||
| const CarlaPluginDiscoveryCallback discoveryCb, | const CarlaPluginDiscoveryCallback discoveryCb, | ||||
| const CarlaPluginCheckCacheCallback checkCacheCb, | const CarlaPluginCheckCacheCallback checkCacheCb, | ||||
| void* const callbackPtr) | void* const callbackPtr) | ||||
| { | { | ||||
| CARLA_SAFE_ASSERT_RETURN(btype != CB::BINARY_NONE, nullptr); | |||||
| CARLA_SAFE_ASSERT_RETURN(ptype != CB::PLUGIN_NONE, nullptr); | |||||
| CARLA_SAFE_ASSERT_RETURN(discoveryTool != nullptr && discoveryTool[0] != '\0', nullptr); | CARLA_SAFE_ASSERT_RETURN(discoveryTool != nullptr && discoveryTool[0] != '\0', nullptr); | ||||
| CARLA_SAFE_ASSERT_RETURN(discoveryCb != nullptr, nullptr); | CARLA_SAFE_ASSERT_RETURN(discoveryCb != nullptr, nullptr); | ||||
| @@ -547,44 +586,66 @@ CarlaPluginDiscoveryHandle carla_plugin_discovery_start(const char* const discov | |||||
| case CB::PLUGIN_JSFX: | case CB::PLUGIN_JSFX: | ||||
| { | { | ||||
| const CarlaScopedEnvVar csev("CARLA_DISCOVERY_PATH", pluginPath); | const CarlaScopedEnvVar csev("CARLA_DISCOVERY_PATH", pluginPath); | ||||
| return new CarlaPluginDiscovery(discoveryTool, ptype, discoveryCb, checkCacheCb, callbackPtr); | |||||
| return new CarlaPluginDiscovery(discoveryTool, btype, ptype, discoveryCb, checkCacheCb, callbackPtr); | |||||
| } | } | ||||
| case CB::PLUGIN_INTERNAL: | case CB::PLUGIN_INTERNAL: | ||||
| case CB::PLUGIN_LV2: | case CB::PLUGIN_LV2: | ||||
| case CB::PLUGIN_AU: | case CB::PLUGIN_AU: | ||||
| return new CarlaPluginDiscovery(discoveryTool, ptype, discoveryCb, checkCacheCb, callbackPtr); | |||||
| return new CarlaPluginDiscovery(discoveryTool, btype, ptype, discoveryCb, checkCacheCb, callbackPtr); | |||||
| case CB::PLUGIN_LADSPA: | case CB::PLUGIN_LADSPA: | ||||
| case CB::PLUGIN_DSSI: | case CB::PLUGIN_DSSI: | ||||
| #if defined(CARLA_OS_MAC) | |||||
| wildcard = "*.dylib"; | |||||
| #elif defined(CARLA_OS_WIN) | |||||
| #ifdef CARLA_OS_WIN | |||||
| wildcard = "*.dll"; | wildcard = "*.dll"; | ||||
| #else | #else | ||||
| wildcard = "*.so"; | |||||
| if (btype == CB::BINARY_WIN32 || btype == CB::BINARY_WIN64) | |||||
| { | |||||
| wildcard = "*.dll"; | |||||
| } | |||||
| else | |||||
| { | |||||
| #ifdef CARLA_OS_MAC | |||||
| wildcard = "*.dylib"; | |||||
| #else | |||||
| wildcard = "*.so"; | |||||
| #endif | |||||
| } | |||||
| #endif | #endif | ||||
| break; | break; | ||||
| case CB::PLUGIN_VST2: | case CB::PLUGIN_VST2: | ||||
| #if defined(CARLA_OS_MAC) | |||||
| directories = true; | |||||
| wildcard = "*.vst"; | |||||
| #elif defined(CARLA_OS_WIN) | |||||
| #ifdef CARLA_OS_WIN | |||||
| wildcard = "*.dll"; | wildcard = "*.dll"; | ||||
| #else | #else | ||||
| wildcard = "*.so"; | |||||
| if (btype == CB::BINARY_WIN32 || btype == CB::BINARY_WIN64) | |||||
| { | |||||
| wildcard = "*.dll"; | |||||
| } | |||||
| else | |||||
| { | |||||
| #ifdef CARLA_OS_MAC | |||||
| directories = true; | |||||
| wildcard = "*.vst"; | |||||
| #else | |||||
| wildcard = "*.so"; | |||||
| #endif | |||||
| } | |||||
| #endif | #endif | ||||
| break; | break; | ||||
| case CB::PLUGIN_VST3: | case CB::PLUGIN_VST3: | ||||
| directories = true; | directories = true; | ||||
| wildcard = "*.vst3"; | wildcard = "*.vst3"; | ||||
| break; | break; | ||||
| case CB::PLUGIN_CLAP: | case CB::PLUGIN_CLAP: | ||||
| wildcard = "*.clap"; | wildcard = "*.clap"; | ||||
| #ifdef CARLA_OS_MAC | #ifdef CARLA_OS_MAC | ||||
| directories = true; | directories = true; | ||||
| #endif | #endif | ||||
| break; | break; | ||||
| case CB::PLUGIN_DLS: | case CB::PLUGIN_DLS: | ||||
| wildcard = "*.dls"; | wildcard = "*.dls"; | ||||
| break; | break; | ||||
| @@ -602,7 +663,7 @@ CarlaPluginDiscoveryHandle carla_plugin_discovery_start(const char* const discov | |||||
| if (ptype == CB::PLUGIN_VST3) | if (ptype == CB::PLUGIN_VST3) | ||||
| { | { | ||||
| if (findVST3s(files, pluginPath)) | |||||
| if (findVST3s(files, btype, pluginPath)) | |||||
| return nullptr; | return nullptr; | ||||
| } | } | ||||
| else if (directories) | else if (directories) | ||||
| @@ -612,11 +673,12 @@ CarlaPluginDiscoveryHandle carla_plugin_discovery_start(const char* const discov | |||||
| } | } | ||||
| else | else | ||||
| { | { | ||||
| if (findFiles(files, pluginPath, wildcard)) | |||||
| if (findFiles(files, btype, pluginPath, wildcard)) | |||||
| return nullptr; | return nullptr; | ||||
| } | } | ||||
| return new CarlaPluginDiscovery(discoveryTool, ptype, std::move(files), discoveryCb, checkCacheCb, callbackPtr); | |||||
| return new CarlaPluginDiscovery(discoveryTool, btype, ptype, std::move(files), | |||||
| discoveryCb, checkCacheCb, callbackPtr); | |||||
| } | } | ||||
| bool carla_plugin_discovery_idle(const CarlaPluginDiscoveryHandle handle) | bool carla_plugin_discovery_idle(const CarlaPluginDiscoveryHandle handle) | ||||
| @@ -79,11 +79,11 @@ LIBS_win64 = $(MODULEDIR)/lilv.win64.a | |||||
| LINK_FLAGS += $(LILV_LIBS) | LINK_FLAGS += $(LILV_LIBS) | ||||
| LIBS_native += $(MODULEDIR)/water.files.a | LIBS_native += $(MODULEDIR)/water.files.a | ||||
| LIBS_arm32 = $(MODULEDIR)/water.files.arm32.a | |||||
| LIBS_posix32 = $(MODULEDIR)/water.posix32.a | |||||
| LIBS_posix64 = $(MODULEDIR)/water.posix64.a | |||||
| LIBS_win32 = $(MODULEDIR)/water.win32.a | |||||
| LIBS_win64 = $(MODULEDIR)/water.win64.a | |||||
| LIBS_arm32 += $(MODULEDIR)/water.files.arm32.a | |||||
| LIBS_posix32 += $(MODULEDIR)/water.posix32.a | |||||
| LIBS_posix64 += $(MODULEDIR)/water.posix64.a | |||||
| LIBS_win32 += $(MODULEDIR)/water.win32.a | |||||
| LIBS_win64 += $(MODULEDIR)/water.win64.a | |||||
| LINK_FLAGS += $(WATER_LIBS) | LINK_FLAGS += $(WATER_LIBS) | ||||
| LINK_FLAGS += $(LIBDL_LIBS) | LINK_FLAGS += $(LIBDL_LIBS) | ||||
| @@ -92,6 +92,11 @@ LIBS_native += $(MODULEDIR)/ysfx.a | |||||
| LINK_FLAGS += $(YSFX_GRAPHICS_LIBS) | LINK_FLAGS += $(YSFX_GRAPHICS_LIBS) | ||||
| endif | endif | ||||
| ifeq ($(BUILDING_FOR_WINE),true) | |||||
| LIBS_win32 += $(MODULEDIR)/jackbridge.win32e.a | |||||
| LIBS_win64 += $(MODULEDIR)/jackbridge.win64e.a | |||||
| endif | |||||
| ifeq ($(USING_JUCE),true) | ifeq ($(USING_JUCE),true) | ||||
| LIBS_native += $(MODULEDIR)/carla_juce.a | LIBS_native += $(MODULEDIR)/carla_juce.a | ||||
| LIBS_native += $(MODULEDIR)/juce_audio_basics.a | LIBS_native += $(MODULEDIR)/juce_audio_basics.a | ||||
| @@ -18,7 +18,6 @@ | |||||
| #include "CarlaBackendUtils.hpp" | #include "CarlaBackendUtils.hpp" | ||||
| #include "CarlaLibUtils.hpp" | #include "CarlaLibUtils.hpp" | ||||
| #include "CarlaMathUtils.hpp" | #include "CarlaMathUtils.hpp" | ||||
| #include "CarlaPipeUtils.cpp" | |||||
| #include "CarlaScopeUtils.hpp" | #include "CarlaScopeUtils.hpp" | ||||
| #include "CarlaMIDI.h" | #include "CarlaMIDI.h" | ||||
| @@ -31,6 +30,10 @@ | |||||
| #include "CarlaVst3Utils.hpp" | #include "CarlaVst3Utils.hpp" | ||||
| #include "CarlaClapUtils.hpp" | #include "CarlaClapUtils.hpp" | ||||
| #ifndef BUILDING_CARLA_FOR_WINE | |||||
| # include "CarlaPipeUtils.cpp" | |||||
| #endif | |||||
| #ifdef CARLA_OS_MAC | #ifdef CARLA_OS_MAC | ||||
| # include "CarlaMacUtils.cpp" | # include "CarlaMacUtils.cpp" | ||||
| # ifdef __aarch64__ | # ifdef __aarch64__ | ||||
| @@ -80,6 +83,11 @@ | |||||
| # pragma GCC diagnostic pop | # pragma GCC diagnostic pop | ||||
| #endif | #endif | ||||
| // must be last | |||||
| #ifdef BUILDING_CARLA_FOR_WINE | |||||
| # include "../jackbridge/JackBridge.hpp" | |||||
| #endif | |||||
| #define MAX_DISCOVERY_AUDIO_IO 64 | #define MAX_DISCOVERY_AUDIO_IO 64 | ||||
| #define MAX_DISCOVERY_CV_IO 32 | #define MAX_DISCOVERY_CV_IO 32 | ||||
| @@ -102,6 +110,7 @@ static constexpr const float kSampleRatef = 44100.0f; | |||||
| // -------------------------------------------------------------------------------------------------------------------- | // -------------------------------------------------------------------------------------------------------------------- | ||||
| // Dynamic discovery | // Dynamic discovery | ||||
| #ifndef BUILDING_CARLA_FOR_WINE | |||||
| class DiscoveryPipe : public CarlaPipeClient | class DiscoveryPipe : public CarlaPipeClient | ||||
| { | { | ||||
| public: | public: | ||||
| @@ -124,7 +133,7 @@ public: | |||||
| if (! writeAndFixMessage(value)) | if (! writeAndFixMessage(value)) | ||||
| return false; | return false; | ||||
| flushMessages(); | |||||
| syncMessages(); | |||||
| return true; | return true; | ||||
| } | } | ||||
| @@ -135,6 +144,37 @@ protected: | |||||
| return true; | return true; | ||||
| } | } | ||||
| }; | }; | ||||
| #else | |||||
| class DiscoveryPipe | |||||
| { | |||||
| void* pipe; | |||||
| public: | |||||
| DiscoveryPipe() noexcept : pipe(nullptr) {} | |||||
| ~DiscoveryPipe() | |||||
| { | |||||
| jackbridge_discovery_pipe_destroy(pipe); | |||||
| } | |||||
| bool initPipeClient(const char* argv[]) | |||||
| { | |||||
| if (jackbridge_is_ok()) | |||||
| pipe = jackbridge_discovery_pipe_create(argv); | |||||
| return pipe != nullptr; | |||||
| } | |||||
| bool writeDiscoveryMessage(const char* const key, const char* const value) const noexcept | |||||
| { | |||||
| CARLA_SAFE_ASSERT_RETURN(key != nullptr && key[0] != '\0', false); | |||||
| CARLA_SAFE_ASSERT_RETURN(value != nullptr, false); | |||||
| jackbridge_discovery_pipe_message(pipe, key, value); | |||||
| return true; | |||||
| } | |||||
| }; | |||||
| #endif | |||||
| CarlaScopedPointer<DiscoveryPipe> gPipe; | CarlaScopedPointer<DiscoveryPipe> gPipe; | ||||
| @@ -2667,6 +2707,7 @@ int main(int argc, const char* argv[]) | |||||
| if (handle == nullptr) | if (handle == nullptr) | ||||
| { | { | ||||
| print_lib_error(filename); | print_lib_error(filename); | ||||
| gPipe = nullptr; | |||||
| return 1; | return 1; | ||||
| } | } | ||||
| } | } | ||||
| @@ -2685,6 +2726,7 @@ int main(int argc, const char* argv[]) | |||||
| if (! lib_close(handle)) | if (! lib_close(handle)) | ||||
| { | { | ||||
| print_lib_error(filename); | print_lib_error(filename); | ||||
| gPipe = nullptr; | |||||
| return 1; | return 1; | ||||
| } | } | ||||
| @@ -2693,6 +2735,7 @@ int main(int argc, const char* argv[]) | |||||
| if (handle == nullptr) | if (handle == nullptr) | ||||
| { | { | ||||
| print_lib_error(filename); | print_lib_error(filename); | ||||
| gPipe = nullptr; | |||||
| return 1; | return 1; | ||||
| } | } | ||||
| } | } | ||||
| @@ -356,16 +356,16 @@ struct PluginPaths { | |||||
| if (QDir(winePrefix).exists()) | if (QDir(winePrefix).exists()) | ||||
| { | { | ||||
| vst2 += ":" + winePrefix + "/drive_c/Program Files/VSTPlugins"; | |||||
| vst2 += ":" + winePrefix + "/drive_c/Program Files/Steinberg/VSTPlugins"; | |||||
| vst2 += ":" + winePrefix + "/drive_c/Program Files/VstPlugins"; | |||||
| vst2 += ":" + winePrefix + "/drive_c/Program Files/Steinberg/VstPlugins"; | |||||
| vst3 += ":" + winePrefix + "/drive_c/Program Files/Common Files/VST3"; | vst3 += ":" + winePrefix + "/drive_c/Program Files/Common Files/VST3"; | ||||
| clap += ":" + winePrefix + "/drive_c/Program Files/Common Files/CLAP"; | clap += ":" + winePrefix + "/drive_c/Program Files/Common Files/CLAP"; | ||||
| #ifdef CARLA_OS_64BIT | #ifdef CARLA_OS_64BIT | ||||
| if (QDir(winePrefix + "/drive_c/Program Files (x86)").exists()) | if (QDir(winePrefix + "/drive_c/Program Files (x86)").exists()) | ||||
| { | { | ||||
| vst2 += ":" + winePrefix + "/drive_c/Program Files (x86)/VSTPlugins"; | |||||
| vst2 += ":" + winePrefix + "/drive_c/Program Files (x86)/Steinberg/VSTPlugins"; | |||||
| vst2 += ":" + winePrefix + "/drive_c/Program Files (x86)/VstPlugins"; | |||||
| vst2 += ":" + winePrefix + "/drive_c/Program Files (x86)/Steinberg/VstPlugins"; | |||||
| vst3 += ":" + winePrefix + "/drive_c/Program Files (x86)/Common Files/VST3"; | vst3 += ":" + winePrefix + "/drive_c/Program Files (x86)/Common Files/VST3"; | ||||
| clap += ":" + winePrefix + "/drive_c/Program Files (x86)/Common Files/CLAP"; | clap += ":" + winePrefix + "/drive_c/Program Files (x86)/Common Files/CLAP"; | ||||
| } | } | ||||
| @@ -606,7 +606,7 @@ static PluginFavorite asPluginFavorite(const QByteArray& qdata) | |||||
| CARLA_SAFE_ASSERT_RETURN(static_cast<size_t>(qdata.size()) >= sizeof(PluginFavoriteHeader) + sizeof(char) * 3, {}); | CARLA_SAFE_ASSERT_RETURN(static_cast<size_t>(qdata.size()) >= sizeof(PluginFavoriteHeader) + sizeof(char) * 3, {}); | ||||
| // read POD data first | // read POD data first | ||||
| const PluginFavoriteHeader* const data | |||||
| const PluginFavoriteHeader* const data | |||||
| = static_cast<const PluginFavoriteHeader*>(static_cast<const void*>(qdata.constData())); | = static_cast<const PluginFavoriteHeader*>(static_cast<const void*>(qdata.constData())); | ||||
| PluginFavorite fav = { data->type, data->uniqueId, {}, {} }; | PluginFavorite fav = { data->type, data->uniqueId, {}, {} }; | ||||
| @@ -673,6 +673,7 @@ struct PluginListDialog::PrivateData { | |||||
| bool hasLoadedLv2Plugins = false; | bool hasLoadedLv2Plugins = false; | ||||
| struct Discovery { | struct Discovery { | ||||
| BinaryType btype = BINARY_NATIVE; | |||||
| PluginType ptype = PLUGIN_NONE; | PluginType ptype = PLUGIN_NONE; | ||||
| bool firstInit = true; | bool firstInit = true; | ||||
| bool ignoreCache = false; | bool ignoreCache = false; | ||||
| @@ -682,11 +683,7 @@ struct PluginListDialog::PrivateData { | |||||
| CarlaScopedPointer<PluginRefreshDialog> dialog; | CarlaScopedPointer<PluginRefreshDialog> dialog; | ||||
| Discovery() | Discovery() | ||||
| { | { | ||||
| tool = carla_get_library_folder(); | |||||
| tool += CARLA_OS_SEP_STR "carla-discovery-native"; | |||||
| #ifdef CARLA_OS_WIN | |||||
| tool += ".exe"; | |||||
| #endif | |||||
| restart(); | |||||
| } | } | ||||
| ~Discovery() | ~Discovery() | ||||
| @@ -694,6 +691,86 @@ struct PluginListDialog::PrivateData { | |||||
| if (handle != nullptr) | if (handle != nullptr) | ||||
| carla_plugin_discovery_stop(handle); | carla_plugin_discovery_stop(handle); | ||||
| } | } | ||||
| bool nextTool() | |||||
| { | |||||
| if (handle != nullptr) | |||||
| { | |||||
| carla_plugin_discovery_stop(handle); | |||||
| handle = nullptr; | |||||
| } | |||||
| #ifdef CARLA_OS_WIN | |||||
| #ifdef CARLA_OS_WIN64 | |||||
| // look for win32 plugins on win64 | |||||
| if (btype == BINARY_NATIVE) | |||||
| { | |||||
| btype = BINARY_WIN32; | |||||
| ptype = PLUGIN_INTERNAL; | |||||
| tool = carla_get_library_folder(); | |||||
| tool += CARLA_OS_SEP_STR "carla-discovery-win32.exe"; | |||||
| if (QFile(tool).exists()) | |||||
| return true; | |||||
| } | |||||
| #endif | |||||
| // no other types to try | |||||
| return false; | |||||
| #else // CARLA_OS_WIN | |||||
| #ifndef CARLA_OS_MAC | |||||
| // try 32bit plugins on 64bit systems, skipping macOS where 32bit is no longer supported | |||||
| if (btype == BINARY_NATIVE) | |||||
| { | |||||
| btype = BINARY_POSIX32; | |||||
| ptype = PLUGIN_INTERNAL; | |||||
| tool = carla_get_library_folder(); | |||||
| tool += CARLA_OS_SEP_STR "carla-discovery-posix32"; | |||||
| if (QFile(tool).exists()) | |||||
| return true; | |||||
| } | |||||
| #endif | |||||
| // try wine bridges | |||||
| #ifdef CARLA_OS_64BIT | |||||
| if (btype == BINARY_NATIVE || btype == BINARY_POSIX32) | |||||
| { | |||||
| btype = BINARY_WIN64; | |||||
| ptype = PLUGIN_INTERNAL; | |||||
| tool = carla_get_library_folder(); | |||||
| tool += CARLA_OS_SEP_STR "carla-discovery-win64.exe"; | |||||
| if (QFile(tool).exists()) | |||||
| return true; | |||||
| } | |||||
| #endif | |||||
| { | |||||
| btype = BINARY_WIN32; | |||||
| ptype = PLUGIN_INTERNAL; | |||||
| tool = carla_get_library_folder(); | |||||
| tool += CARLA_OS_SEP_STR "carla-discovery-win32.exe"; | |||||
| if (QFile(tool).exists()) | |||||
| return true; | |||||
| } | |||||
| return false; | |||||
| #endif // CARLA_OS_WIN | |||||
| } | |||||
| void restart() | |||||
| { | |||||
| btype = BINARY_NATIVE; | |||||
| ptype = PLUGIN_NONE; | |||||
| tool = carla_get_library_folder(); | |||||
| tool += CARLA_OS_SEP_STR "carla-discovery-native"; | |||||
| #ifdef CARLA_OS_WIN | |||||
| tool += ".exe"; | |||||
| #endif | |||||
| } | |||||
| } discovery; | } discovery; | ||||
| PluginPaths paths; | PluginPaths paths; | ||||
| @@ -788,10 +865,11 @@ PluginListDialog::PluginListDialog(QWidget* const parent, const HostSettings& ho | |||||
| // custom action that listens for Ctrl+F shortcut | // custom action that listens for Ctrl+F shortcut | ||||
| addAction(ui.act_focus_search); | addAction(ui.act_focus_search); | ||||
| #if BINARY_NATIVE == BINARY_POSIX32 || BINARY_NATIVE == BINARY_WIN32 | |||||
| ui.ch_bridged->setText(tr("Bridged (64bit)")); | |||||
| #else | |||||
| #ifdef CARLA_OS_64BIT | |||||
| ui.ch_bridged->setText(tr("Bridged (32bit)")); | ui.ch_bridged->setText(tr("Bridged (32bit)")); | ||||
| #else | |||||
| ui.ch_bridged->setChecked(false); | |||||
| ui.ch_bridged->setEnabled(false); | |||||
| #endif | #endif | ||||
| #if !(defined(CARLA_OS_LINUX) || defined(CARLA_OS_MAC)) | #if !(defined(CARLA_OS_LINUX) || defined(CARLA_OS_MAC)) | ||||
| @@ -1081,9 +1159,13 @@ void PluginListDialog::timerEvent(QTimerEvent* const event) | |||||
| { | { | ||||
| case PLUGIN_NONE: | case PLUGIN_NONE: | ||||
| #ifndef CARLA_FRONTEND_ONLY_EMBEDDABLE_PLUGINS | #ifndef CARLA_FRONTEND_ONLY_EMBEDDABLE_PLUGINS | ||||
| ui.label->setText(tr("Discovering internal plugins...")); | |||||
| p->discovery.ptype = PLUGIN_INTERNAL; | |||||
| break; | |||||
| if (p->discovery.btype == BINARY_NATIVE) | |||||
| { | |||||
| ui.label->setText(tr("Discovering internal plugins...")); | |||||
| p->discovery.ptype = PLUGIN_INTERNAL; | |||||
| break; | |||||
| } | |||||
| [[fallthrough]]; | |||||
| case PLUGIN_INTERNAL: | case PLUGIN_INTERNAL: | ||||
| ui.label->setText(tr("Discovering LADSPA plugins...")); | ui.label->setText(tr("Discovering LADSPA plugins...")); | ||||
| path = p->paths.ladspa; | path = p->paths.ladspa; | ||||
| @@ -1118,12 +1200,16 @@ void PluginListDialog::timerEvent(QTimerEvent* const event) | |||||
| case PLUGIN_CLAP: | case PLUGIN_CLAP: | ||||
| #ifndef CARLA_FRONTEND_ONLY_EMBEDDABLE_PLUGINS | #ifndef CARLA_FRONTEND_ONLY_EMBEDDABLE_PLUGINS | ||||
| #ifdef CARLA_OS_MAC | #ifdef CARLA_OS_MAC | ||||
| ui.label->setText(tr("Discovering AU plugins...")); | |||||
| p->discovery.ptype = PLUGIN_AU; | |||||
| break; | |||||
| if (p->discovery.btype == BINARY_POSIX32 || p->discovery.btype == BINARY_POSIX64) | |||||
| { | |||||
| ui.label->setText(tr("Discovering AU plugins...")); | |||||
| p->discovery.ptype = PLUGIN_AU; | |||||
| break; | |||||
| } | |||||
| [[fallthrough]]; | |||||
| case PLUGIN_AU: | case PLUGIN_AU: | ||||
| #endif | #endif | ||||
| if (p->paths.jsfx.isNotEmpty()) | |||||
| if (p->discovery.btype == BINARY_NATIVE && p->paths.jsfx.isNotEmpty()) | |||||
| { | { | ||||
| ui.label->setText(tr("Discovering JSFX plugins...")); | ui.label->setText(tr("Discovering JSFX plugins...")); | ||||
| path = p->paths.jsfx; | path = p->paths.jsfx; | ||||
| @@ -1132,20 +1218,29 @@ void PluginListDialog::timerEvent(QTimerEvent* const event) | |||||
| } | } | ||||
| [[fallthrough]]; | [[fallthrough]]; | ||||
| case PLUGIN_JSFX: | case PLUGIN_JSFX: | ||||
| ui.label->setText(tr("Discovering SF2 kits...")); | |||||
| path = p->paths.sf2; | |||||
| p->discovery.ptype = PLUGIN_SF2; | |||||
| break; | |||||
| if (p->discovery.btype == BINARY_NATIVE && p->paths.sf2.isNotEmpty()) | |||||
| { | |||||
| ui.label->setText(tr("Discovering SF2 kits...")); | |||||
| path = p->paths.sf2; | |||||
| p->discovery.ptype = PLUGIN_SF2; | |||||
| break; | |||||
| } | |||||
| [[fallthrough]]; | |||||
| case PLUGIN_SF2: | case PLUGIN_SF2: | ||||
| ui.label->setText(tr("Discovering SFZ kits...")); | |||||
| path = p->paths.sfz; | |||||
| p->discovery.ptype = PLUGIN_SFZ; | |||||
| break; | |||||
| if (p->discovery.btype == BINARY_NATIVE && p->paths.sfz.isNotEmpty()) | |||||
| { | |||||
| ui.label->setText(tr("Discovering SFZ kits...")); | |||||
| path = p->paths.sfz; | |||||
| p->discovery.ptype = PLUGIN_SFZ; | |||||
| break; | |||||
| } | |||||
| [[fallthrough]]; | |||||
| case PLUGIN_SFZ: | case PLUGIN_SFZ: | ||||
| #endif | #endif | ||||
| default: | default: | ||||
| // discovery complete | // discovery complete | ||||
| refreshPluginsStop(); | |||||
| if (! p->discovery.nextTool()) | |||||
| refreshPluginsStop(); | |||||
| } | } | ||||
| if (p->timerId == 0) | if (p->timerId == 0) | ||||
| @@ -1155,6 +1250,7 @@ void PluginListDialog::timerEvent(QTimerEvent* const event) | |||||
| p->discovery.dialog->progressBar->setFormat(ui.label->text()); | p->discovery.dialog->progressBar->setFormat(ui.label->text()); | ||||
| p->discovery.handle = carla_plugin_discovery_start(p->discovery.tool.toUtf8().constData(), | p->discovery.handle = carla_plugin_discovery_start(p->discovery.tool.toUtf8().constData(), | ||||
| p->discovery.btype, | |||||
| p->discovery.ptype, | p->discovery.ptype, | ||||
| path.toUtf8().constData(), | path.toUtf8().constData(), | ||||
| discoveryCallback, checkCacheCallback, this); | discoveryCallback, checkCacheCallback, this); | ||||
| @@ -1462,17 +1558,19 @@ void PluginListDialog::checkFilters() | |||||
| const bool hideNonIDisp = ui.ch_inline_display->isChecked(); | const bool hideNonIDisp = ui.ch_inline_display->isChecked(); | ||||
| const bool hideNonStereo = ui.ch_stereo->isChecked(); | const bool hideNonStereo = ui.ch_stereo->isChecked(); | ||||
| #if 0 | |||||
| if HAIKU or LINUX or MACOS: | |||||
| nativeBins = [BINARY_POSIX32, BINARY_POSIX64] | |||||
| wineBins = [BINARY_WIN32, BINARY_WIN64] | |||||
| elif WINDOWS: | |||||
| nativeBins = [BINARY_WIN32, BINARY_WIN64] | |||||
| wineBins = [] | |||||
| else: | |||||
| nativeBins = [] | |||||
| wineBins = [] | |||||
| #endif | |||||
| #if defined(CARLA_OS_WIN64) | |||||
| static constexpr const BinaryType nativeBins[2] = { BINARY_WIN32, BINARY_WIN64 }; | |||||
| static constexpr const BinaryType wineBins[2] = { BINARY_NONE, BINARY_NONE }; | |||||
| #elif defined(CARLA_OS_WIN32) | |||||
| static constexpr const BinaryType nativeBins[2] = { BINARY_WIN32, BINARY_NONE }; | |||||
| static constexpr const BinaryType wineBins[2] = { BINARY_NONE, BINARY_NONE }; | |||||
| #elif defined(CARLA_OS_MAC) | |||||
| static constexpr const BinaryType nativeBins[2] = { BINARY_POSIX64, BINARY_NONE }; | |||||
| static constexpr const BinaryType wineBins[2] = { BINARY_WIN32, BINARY_WIN64 }; | |||||
| #else | |||||
| static constexpr const BinaryType nativeBins[2] = { BINARY_POSIX32, BINARY_POSIX64 }; | |||||
| static constexpr const BinaryType wineBins[2] = { BINARY_WIN32, BINARY_WIN64 }; | |||||
| #endif | |||||
| for (int i=0, c=ui.tableWidget->rowCount(); i<c; ++i) | for (int i=0, c=ui.tableWidget->rowCount(); i<c; ++i) | ||||
| { | { | ||||
| @@ -1499,14 +1597,8 @@ void PluginListDialog::checkFilters() | |||||
| const bool hasCV = cvIns + cvOuts > 0; | const bool hasCV = cvIns + cvOuts > 0; | ||||
| const bool hasGui = phints & PLUGIN_HAS_CUSTOM_UI; | const bool hasGui = phints & PLUGIN_HAS_CUSTOM_UI; | ||||
| const bool hasIDisp = phints & PLUGIN_HAS_INLINE_DISPLAY; | const bool hasIDisp = phints & PLUGIN_HAS_INLINE_DISPLAY; | ||||
| #if 0 | |||||
| const bool isBridged = bool(not isNative and info.build in nativeBins); | |||||
| const bool isBridgedWine = bool(not isNative and info.build in wineBins); | |||||
| #else | |||||
| const bool isBridged = false; | |||||
| const bool isBridgedWine = false; | |||||
| #endif | |||||
| const bool isBridged = !isNative && (nativeBins[0] == info.build || nativeBins[1] == info.build); | |||||
| const bool isBridgedWine = !isNative && (wineBins[0] == info.build || wineBins[1] == info.build); | |||||
| const auto hasText = [text, ptext]() { | const auto hasText = [text, ptext]() { | ||||
| const QStringList textSplit = text.strip().split(' '); | const QStringList textSplit = text.strip().split(' '); | ||||
| @@ -1798,7 +1890,7 @@ void PluginListDialog::refreshPluginsStart() | |||||
| p->plugins.cache.clear(); | p->plugins.cache.clear(); | ||||
| // start discovery again | // start discovery again | ||||
| p->discovery.ptype = PLUGIN_NONE; | |||||
| p->discovery.restart(); | |||||
| if (p->timerId == 0) | if (p->timerId == 0) | ||||
| p->timerId = startTimer(0); | p->timerId = startTimer(0); | ||||
| @@ -1806,7 +1898,7 @@ void PluginListDialog::refreshPluginsStart() | |||||
| void PluginListDialog::refreshPluginsStop() | void PluginListDialog::refreshPluginsStop() | ||||
| { | { | ||||
| // stop previous discovery if still running | |||||
| // stop previous discovery if still running | |||||
| if (p->discovery.handle != nullptr) | if (p->discovery.handle != nullptr) | ||||
| { | { | ||||
| carla_plugin_discovery_stop(p->discovery.handle); | carla_plugin_discovery_stop(p->discovery.handle); | ||||
| @@ -428,6 +428,10 @@ JACKBRIDGE_API void jackbridge_shm_close(void* shm) noexcept; | |||||
| JACKBRIDGE_API void* jackbridge_shm_map(void* shm, uint64_t size) noexcept; | JACKBRIDGE_API void* jackbridge_shm_map(void* shm, uint64_t size) noexcept; | ||||
| JACKBRIDGE_API void jackbridge_shm_unmap(void* shm, void* ptr) noexcept; | JACKBRIDGE_API void jackbridge_shm_unmap(void* shm, void* ptr) noexcept; | ||||
| JACKBRIDGE_API void* jackbridge_discovery_pipe_create(const char* argv[]); | |||||
| JACKBRIDGE_API void jackbridge_discovery_pipe_message(void* pipe, const char* key, const char* value); | |||||
| JACKBRIDGE_API void jackbridge_discovery_pipe_destroy(void* pipe); | |||||
| JACKBRIDGE_API void jackbridge_parent_deathsig(bool kill) noexcept; | JACKBRIDGE_API void jackbridge_parent_deathsig(bool kill) noexcept; | ||||
| #endif // JACKBRIDGE_HPP_INCLUDED | #endif // JACKBRIDGE_HPP_INCLUDED | ||||
| @@ -1,6 +1,6 @@ | |||||
| /* | /* | ||||
| * JackBridge (Part 2, Semaphore + Shared memory and other misc functions) | * JackBridge (Part 2, Semaphore + Shared memory and other misc functions) | ||||
| * Copyright (C) 2013-2019 Filipe Coelho <falktx@falktx.com> | |||||
| * Copyright (C) 2013-2023 Filipe Coelho <falktx@falktx.com> | |||||
| * | * | ||||
| * Permission to use, copy, modify, and/or distribute this software for any purpose with | * Permission to use, copy, modify, and/or distribute this software for any purpose with | ||||
| * or without fee is hereby granted, provided that the above copyright notice and this | * or without fee is hereby granted, provided that the above copyright notice and this | ||||
| @@ -22,9 +22,13 @@ | |||||
| # include "CarlaProcessUtils.hpp" | # include "CarlaProcessUtils.hpp" | ||||
| # include "CarlaSemUtils.hpp" | # include "CarlaSemUtils.hpp" | ||||
| # include "CarlaShmUtils.hpp" | # include "CarlaShmUtils.hpp" | ||||
| # include "CarlaTimeUtils.hpp" | |||||
| # ifdef __WINE__ | |||||
| # include "utils/PipeClient.cpp" | |||||
| # endif | |||||
| #endif // ! JACKBRIDGE_DUMMY | #endif // ! JACKBRIDGE_DUMMY | ||||
| // ----------------------------------------------------------------------------- | |||||
| // -------------------------------------------------------------------------------------------------------------------- | |||||
| bool jackbridge_sem_init(void* sem) noexcept | bool jackbridge_sem_init(void* sem) noexcept | ||||
| { | { | ||||
| @@ -77,7 +81,7 @@ bool jackbridge_sem_timedwait(void* sem, uint msecs, bool server) noexcept | |||||
| } | } | ||||
| #endif | #endif | ||||
| // ----------------------------------------------------------------------------- | |||||
| // -------------------------------------------------------------------------------------------------------------------- | |||||
| bool jackbridge_shm_is_valid(const void* shm) noexcept | bool jackbridge_shm_is_valid(const void* shm) noexcept | ||||
| { | { | ||||
| @@ -137,7 +141,68 @@ void jackbridge_shm_unmap(void* shm, void* ptr) noexcept | |||||
| #endif | #endif | ||||
| } | } | ||||
| // ----------------------------------------------------------------------------- | |||||
| // -------------------------------------------------------------------------------------------------------------------- | |||||
| #if !defined(JACKBRIDGE_DUMMY) && defined(__WINE__) | |||||
| static void discovery_pipe_callback(void*, const char* const msg) noexcept | |||||
| { | |||||
| carla_stdout("discovery msgReceived %s", msg); | |||||
| } | |||||
| #endif | |||||
| void* jackbridge_discovery_pipe_create(const char* argv[]) | |||||
| { | |||||
| #if defined(JACKBRIDGE_DUMMY) || !defined(__WINE__) | |||||
| return nullptr; | |||||
| // unused | |||||
| (void)argv; | |||||
| #else | |||||
| return carla_pipe_client_new(argv, discovery_pipe_callback, nullptr); | |||||
| #endif | |||||
| } | |||||
| void jackbridge_discovery_pipe_message(void* pipe, const char* key, const char* value) | |||||
| { | |||||
| #if defined(JACKBRIDGE_DUMMY) || !defined(__WINE__) | |||||
| // unused | |||||
| (void)pipe; | |||||
| (void)key; | |||||
| (void)value; | |||||
| #else | |||||
| carla_pipe_client_lock(pipe); | |||||
| carla_pipe_client_write_and_fix_msg(pipe, key); | |||||
| carla_pipe_client_write_and_fix_msg(pipe, value); | |||||
| carla_pipe_client_flush_and_unlock(pipe); | |||||
| #endif | |||||
| } | |||||
| void jackbridge_discovery_pipe_destroy(void* pipe) | |||||
| { | |||||
| #if defined(JACKBRIDGE_DUMMY) || !defined(__WINE__) | |||||
| // unused | |||||
| (void)pipe; | |||||
| #else | |||||
| carla_pipe_client_lock(pipe); | |||||
| carla_pipe_client_write_msg(pipe, "exiting\n"); | |||||
| carla_pipe_client_flush_and_unlock(pipe); | |||||
| // NOTE: no more messages are handled after this point | |||||
| // pData->clientClosingDown = true; | |||||
| for (int i=0; i < 100 && carla_pipe_client_is_running(pipe); ++i) | |||||
| { | |||||
| carla_msleep(50); | |||||
| carla_pipe_client_idle(pipe); | |||||
| } | |||||
| if (carla_pipe_client_is_running(pipe)) | |||||
| carla_stderr2("jackbridge_discovery_pipe_destroy: pipe is still running!"); | |||||
| carla_pipe_client_destroy(pipe); | |||||
| #endif | |||||
| } | |||||
| // -------------------------------------------------------------------------------------------------------------------- | |||||
| void jackbridge_parent_deathsig(bool kill) noexcept | void jackbridge_parent_deathsig(bool kill) noexcept | ||||
| { | { | ||||
| @@ -146,4 +211,4 @@ void jackbridge_parent_deathsig(bool kill) noexcept | |||||
| #endif | #endif | ||||
| } | } | ||||
| // ----------------------------------------------------------------------------- | |||||
| // -------------------------------------------------------------------------------------------------------------------- | |||||
| @@ -1,6 +1,6 @@ | |||||
| /* | /* | ||||
| * JackBridge (Part 3, Export) | * JackBridge (Part 3, Export) | ||||
| * Copyright (C) 2013-2015 Filipe Coelho <falktx@falktx.com> | |||||
| * Copyright (C) 2013-2023 Filipe Coelho <falktx@falktx.com> | |||||
| * | * | ||||
| * Permission to use, copy, modify, and/or distribute this software for any purpose with | * Permission to use, copy, modify, and/or distribute this software for any purpose with | ||||
| * or without fee is hereby granted, provided that the above copyright notice and this | * or without fee is hereby granted, provided that the above copyright notice and this | ||||
| @@ -18,7 +18,7 @@ | |||||
| #include "CarlaUtils.hpp" | #include "CarlaUtils.hpp" | ||||
| // ----------------------------------------------------------------------------- | |||||
| // -------------------------------------------------------------------------------------------------------------------- | |||||
| #if defined(CARLA_OS_WIN) && ! defined(__WINE__) | #if defined(CARLA_OS_WIN) && ! defined(__WINE__) | ||||
| # define JACKBRIDGE_EXPORT extern "C" __declspec (dllexport) | # define JACKBRIDGE_EXPORT extern "C" __declspec (dllexport) | ||||
| @@ -26,7 +26,7 @@ | |||||
| # define JACKBRIDGE_EXPORT extern "C" __attribute__ ((visibility("default"))) | # define JACKBRIDGE_EXPORT extern "C" __attribute__ ((visibility("default"))) | ||||
| #endif | #endif | ||||
| // ----------------------------------------------------------------------------- | |||||
| // -------------------------------------------------------------------------------------------------------------------- | |||||
| JACKBRIDGE_EXPORT | JACKBRIDGE_EXPORT | ||||
| const JackBridgeExportedFunctions* JACKBRIDGE_API jackbridge_get_exported_functions(); | const JackBridgeExportedFunctions* JACKBRIDGE_API jackbridge_get_exported_functions(); | ||||
| @@ -140,6 +140,9 @@ const JackBridgeExportedFunctions* JACKBRIDGE_API jackbridge_get_exported_functi | |||||
| funcs.shm_close_ptr = jackbridge_shm_close; | funcs.shm_close_ptr = jackbridge_shm_close; | ||||
| funcs.shm_map_ptr = jackbridge_shm_map; | funcs.shm_map_ptr = jackbridge_shm_map; | ||||
| funcs.shm_unmap_ptr = jackbridge_shm_unmap; | funcs.shm_unmap_ptr = jackbridge_shm_unmap; | ||||
| funcs.discovery_pipe_create_ptr = jackbridge_discovery_pipe_create; | |||||
| funcs.discovery_pipe_message_ptr = jackbridge_discovery_pipe_message; | |||||
| funcs.discovery_pipe_destroy_ptr = jackbridge_discovery_pipe_destroy; | |||||
| funcs.parent_deathsig_ptr = jackbridge_parent_deathsig; | funcs.parent_deathsig_ptr = jackbridge_parent_deathsig; | ||||
| funcs.unique1 = funcs.unique2 = funcs.unique3 = 0xdeadf00d; | funcs.unique1 = funcs.unique2 = funcs.unique3 = 0xdeadf00d; | ||||
| @@ -147,4 +150,4 @@ const JackBridgeExportedFunctions* JACKBRIDGE_API jackbridge_get_exported_functi | |||||
| return &funcs; | return &funcs; | ||||
| } | } | ||||
| // ----------------------------------------------------------------------------- | |||||
| // -------------------------------------------------------------------------------------------------------------------- | |||||
| @@ -1,6 +1,6 @@ | |||||
| /* | /* | ||||
| * JackBridge (Part 3, Export) | * JackBridge (Part 3, Export) | ||||
| * Copyright (C) 2013-2015 Filipe Coelho <falktx@falktx.com> | |||||
| * Copyright (C) 2013-2023 Filipe Coelho <falktx@falktx.com> | |||||
| * | * | ||||
| * Permission to use, copy, modify, and/or distribute this software for any purpose with | * Permission to use, copy, modify, and/or distribute this software for any purpose with | ||||
| * or without fee is hereby granted, provided that the above copyright notice and this | * or without fee is hereby granted, provided that the above copyright notice and this | ||||
| @@ -17,8 +17,11 @@ | |||||
| #include "JackBridgeExport.hpp" | #include "JackBridgeExport.hpp" | ||||
| #include "CarlaLibUtils.hpp" | #include "CarlaLibUtils.hpp" | ||||
| #include "CarlaUtils.h" | |||||
| // ----------------------------------------------------------------------------- | |||||
| // #include <cstdio> | |||||
| // -------------------------------------------------------------------------------------------------------------------- | |||||
| class JackBridgeExported | class JackBridgeExported | ||||
| { | { | ||||
| @@ -27,11 +30,11 @@ public: | |||||
| : lib(nullptr), | : lib(nullptr), | ||||
| func(nullptr) | func(nullptr) | ||||
| { | { | ||||
| #ifdef CARLA_OS_WIN64 | |||||
| #ifdef CARLA_OS_WIN64 | |||||
| lib = lib_open("jackbridge-wine64.dll"); | lib = lib_open("jackbridge-wine64.dll"); | ||||
| #else | |||||
| #else | |||||
| lib = lib_open("jackbridge-wine32.dll"); | lib = lib_open("jackbridge-wine32.dll"); | ||||
| #endif | |||||
| #endif | |||||
| CARLA_SAFE_ASSERT_RETURN(lib != nullptr,); | CARLA_SAFE_ASSERT_RETURN(lib != nullptr,); | ||||
| func = lib_symbol<jackbridge_exported_function_type>(lib, "jackbridge_get_exported_functions"); | func = lib_symbol<jackbridge_exported_function_type>(lib, "jackbridge_get_exported_functions"); | ||||
| @@ -59,12 +62,12 @@ public: | |||||
| static const JackBridgeExported bridge; | static const JackBridgeExported bridge; | ||||
| CARLA_SAFE_ASSERT_RETURN(bridge.func != nullptr, fallback); | CARLA_SAFE_ASSERT_RETURN(bridge.func != nullptr, fallback); | ||||
| const JackBridgeExportedFunctions* const funcs(bridge.func()); | |||||
| const JackBridgeExportedFunctions* const funcs = bridge.func(); | |||||
| CARLA_SAFE_ASSERT_RETURN(funcs != nullptr, fallback); | CARLA_SAFE_ASSERT_RETURN(funcs != nullptr, fallback); | ||||
| CARLA_SAFE_ASSERT_RETURN(funcs->unique1 != 0, fallback); | CARLA_SAFE_ASSERT_RETURN(funcs->unique1 != 0, fallback); | ||||
| CARLA_SAFE_ASSERT_RETURN(funcs->unique1 == funcs->unique2, fallback); | CARLA_SAFE_ASSERT_RETURN(funcs->unique1 == funcs->unique2, fallback); | ||||
| CARLA_SAFE_ASSERT_RETURN(funcs->unique2 == funcs->unique3, fallback); | CARLA_SAFE_ASSERT_RETURN(funcs->unique2 == funcs->unique3, fallback); | ||||
| CARLA_SAFE_ASSERT_RETURN(funcs->shm_map_ptr != nullptr, fallback); | |||||
| CARLA_SAFE_ASSERT_RETURN(funcs->discovery_pipe_destroy_ptr != nullptr, fallback); | |||||
| return *funcs; | return *funcs; | ||||
| } | } | ||||
| @@ -77,7 +80,7 @@ private: | |||||
| CARLA_DECLARE_NON_COPYABLE(JackBridgeExported); | CARLA_DECLARE_NON_COPYABLE(JackBridgeExported); | ||||
| }; | }; | ||||
| // ----------------------------------------------------------------------------- | |||||
| // -------------------------------------------------------------------------------------------------------------------- | |||||
| static const JackBridgeExportedFunctions& getBridgeInstance() noexcept | static const JackBridgeExportedFunctions& getBridgeInstance() noexcept | ||||
| { | { | ||||
| @@ -85,7 +88,7 @@ static const JackBridgeExportedFunctions& getBridgeInstance() noexcept | |||||
| return funcs; | return funcs; | ||||
| } | } | ||||
| // ----------------------------------------------------------------------------- | |||||
| // -------------------------------------------------------------------------------------------------------------------- | |||||
| bool jackbridge_is_ok() noexcept | bool jackbridge_is_ok() noexcept | ||||
| { | { | ||||
| @@ -598,9 +601,28 @@ void jackbridge_shm_unmap(void* shm, void* ptr) noexcept | |||||
| return getBridgeInstance().shm_unmap_ptr(shm, ptr); | return getBridgeInstance().shm_unmap_ptr(shm, ptr); | ||||
| } | } | ||||
| // -------------------------------------------------------------------------------------------------------------------- | |||||
| void* jackbridge_discovery_pipe_create(const char* argv[]) | |||||
| { | |||||
| return getBridgeInstance().discovery_pipe_create_ptr(argv); | |||||
| } | |||||
| void jackbridge_discovery_pipe_message(void* pipe, const char* key, const char* value) | |||||
| { | |||||
| return getBridgeInstance().discovery_pipe_message_ptr(pipe, key, value); | |||||
| } | |||||
| void jackbridge_discovery_pipe_destroy(void* pipe) | |||||
| { | |||||
| return getBridgeInstance().discovery_pipe_destroy_ptr(pipe); | |||||
| } | |||||
| // -------------------------------------------------------------------------------------------------------------------- | |||||
| void jackbridge_parent_deathsig(bool kill) noexcept | void jackbridge_parent_deathsig(bool kill) noexcept | ||||
| { | { | ||||
| return getBridgeInstance().parent_deathsig_ptr(kill); | return getBridgeInstance().parent_deathsig_ptr(kill); | ||||
| } | } | ||||
| // ----------------------------------------------------------------------------- | |||||
| // -------------------------------------------------------------------------------------------------------------------- | |||||
| @@ -1,6 +1,6 @@ | |||||
| /* | /* | ||||
| * JackBridge (Part 3, Export) | * JackBridge (Part 3, Export) | ||||
| * Copyright (C) 2013-2015 Filipe Coelho <falktx@falktx.com> | |||||
| * Copyright (C) 2013-2023 Filipe Coelho <falktx@falktx.com> | |||||
| * | * | ||||
| * Permission to use, copy, modify, and/or distribute this software for any purpose with | * Permission to use, copy, modify, and/or distribute this software for any purpose with | ||||
| * or without fee is hereby granted, provided that the above copyright notice and this | * or without fee is hereby granted, provided that the above copyright notice and this | ||||
| @@ -14,6 +14,8 @@ | |||||
| * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. | * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. | ||||
| */ | */ | ||||
| #pragma once | |||||
| #include "JackBridge.hpp" | #include "JackBridge.hpp" | ||||
| extern "C" { | extern "C" { | ||||
| @@ -123,6 +125,9 @@ typedef void (JACKBRIDGE_API *jackbridgesym_shm_attach)(void*, const char*); | |||||
| typedef void (JACKBRIDGE_API *jackbridgesym_shm_close)(void*); | typedef void (JACKBRIDGE_API *jackbridgesym_shm_close)(void*); | ||||
| typedef void* (JACKBRIDGE_API *jackbridgesym_shm_map)(void*, uint64_t); | typedef void* (JACKBRIDGE_API *jackbridgesym_shm_map)(void*, uint64_t); | ||||
| typedef void (JACKBRIDGE_API *jackbridgesym_shm_unmap)(void*, void*); | typedef void (JACKBRIDGE_API *jackbridgesym_shm_unmap)(void*, void*); | ||||
| typedef void* (JACKBRIDGE_API *jackbridgesym_discovery_pipe_create)(const char**); | |||||
| typedef void (JACKBRIDGE_API *jackbridgesym_discovery_pipe_message)(void*, const char*, const char*); | |||||
| typedef void (JACKBRIDGE_API *jackbridgesym_discovery_pipe_destroy)(void*); | |||||
| typedef void (JACKBRIDGE_API *jackbridgesym_parent_deathsig)(bool); | typedef void (JACKBRIDGE_API *jackbridgesym_parent_deathsig)(bool); | ||||
| // ----------------------------------------------------------------------------- | // ----------------------------------------------------------------------------- | ||||
| @@ -233,6 +238,9 @@ struct _JackBridgeExportedFunctions { | |||||
| jackbridgesym_shm_close shm_close_ptr; | jackbridgesym_shm_close shm_close_ptr; | ||||
| jackbridgesym_shm_map shm_map_ptr; | jackbridgesym_shm_map shm_map_ptr; | ||||
| jackbridgesym_shm_unmap shm_unmap_ptr; | jackbridgesym_shm_unmap shm_unmap_ptr; | ||||
| jackbridgesym_discovery_pipe_create discovery_pipe_create_ptr; | |||||
| jackbridgesym_discovery_pipe_message discovery_pipe_message_ptr; | |||||
| jackbridgesym_discovery_pipe_destroy discovery_pipe_destroy_ptr; | |||||
| jackbridgesym_parent_deathsig parent_deathsig_ptr; | jackbridgesym_parent_deathsig parent_deathsig_ptr; | ||||
| ulong unique3; | ulong unique3; | ||||
| }; | }; | ||||
| @@ -10,7 +10,7 @@ include ../modules/Makefile.mk | |||||
| # --------------------------------------------------------------------------------------------------------------------- | # --------------------------------------------------------------------------------------------------------------------- | ||||
| BUILD_CXX_FLAGS += $(JACKBRIDGE_FLAGS) | |||||
| BUILD_CXX_FLAGS += $(JACKBRIDGE_FLAGS) -I../backend | |||||
| LINK_FLAGS += $(JACKBRIDGE_LIBS) | LINK_FLAGS += $(JACKBRIDGE_LIBS) | ||||
| ifeq ($(JACKBRIDGE_DIRECT),true) | ifeq ($(JACKBRIDGE_DIRECT),true) | ||||
| @@ -18,6 +18,12 @@ BUILD_CXX_FLAGS += $(JACK_FLAGS) -DJACKBRIDGE_DIRECT | |||||
| LINK_FLAGS += $(JACK_LIBS) | LINK_FLAGS += $(JACK_LIBS) | ||||
| endif | endif | ||||
| ifneq ($(BUILDING_FOR_WINE),true) | |||||
| ifeq ($(WINDOWS),true) | |||||
| BUILD_CXX_FLAGS += -I../modules | |||||
| endif | |||||
| endif | |||||
| WINE_32BIT_FLAGS = $(32BIT_FLAGS) -fpermissive | WINE_32BIT_FLAGS = $(32BIT_FLAGS) -fpermissive | ||||
| WINE_64BIT_FLAGS = $(64BIT_FLAGS) -fpermissive | WINE_64BIT_FLAGS = $(64BIT_FLAGS) -fpermissive | ||||
| WINE_BUILD_FLAGS = $(filter-out -flto,$(BUILD_CXX_FLAGS)) | WINE_BUILD_FLAGS = $(filter-out -flto,$(BUILD_CXX_FLAGS)) | ||||
| @@ -88,7 +88,7 @@ BinaryType getBinaryTypeFromFile(const char* const filename) | |||||
| #if defined(HAVE_LIBMAGIC) && ! defined(BUILD_BRIDGE_ALTERNATIVE_ARCH) | #if defined(HAVE_LIBMAGIC) && ! defined(BUILD_BRIDGE_ALTERNATIVE_ARCH) | ||||
| static const CarlaMagic magic; | static const CarlaMagic magic; | ||||
| const char* const output(magic.getFileDescription(filename)); | |||||
| const char* const output = magic.getFileDescription(filename); | |||||
| if (output != nullptr && output[0] != '\0') | if (output != nullptr && output[0] != '\0') | ||||
| { | { | ||||
| @@ -35,9 +35,8 @@ | |||||
| #include <fcntl.h> | #include <fcntl.h> | ||||
| #include "water/text/String.h" | |||||
| #ifdef CARLA_OS_WIN | #ifdef CARLA_OS_WIN | ||||
| # include "water/text/String.h" | |||||
| # include <ctime> | # include <ctime> | ||||
| #else | #else | ||||
| # include <cerrno> | # include <cerrno> | ||||
| @@ -1494,7 +1493,8 @@ uintptr_t CarlaPipeServer::getPID() const noexcept | |||||
| // -------------------------------------------------------------------------------------------------------------------- | // -------------------------------------------------------------------------------------------------------------------- | ||||
| bool CarlaPipeServer::startPipeServer(const char* const filename, | |||||
| bool CarlaPipeServer::startPipeServer(const char* const helperTool, | |||||
| const char* const filename, | |||||
| const char* const arg1, | const char* const arg1, | ||||
| const char* const arg2, | const char* const arg2, | ||||
| const int size) noexcept | const int size) noexcept | ||||
| @@ -1642,31 +1642,30 @@ bool CarlaPipeServer::startPipeServer(const char* const filename, | |||||
| //----------------------------------------------------------------------------------------------------------------- | //----------------------------------------------------------------------------------------------------------------- | ||||
| // set arguments | // set arguments | ||||
| const char* argv[8]; | |||||
| const char* argv[9] = {}; | |||||
| int i = 0; | |||||
| if (helperTool != nullptr) | |||||
| argv[i++] = helperTool; | |||||
| //----------------------------------------------------------------------------------------------------------------- | //----------------------------------------------------------------------------------------------------------------- | ||||
| // argv[0] => filename | // argv[0] => filename | ||||
| argv[0] = filename; | |||||
| argv[i++] = filename; | |||||
| //----------------------------------------------------------------------------------------------------------------- | //----------------------------------------------------------------------------------------------------------------- | ||||
| // argv[1-2] => args | // argv[1-2] => args | ||||
| argv[1] = arg1; | |||||
| argv[2] = arg2; | |||||
| argv[i++] = arg1; | |||||
| argv[i++] = arg2; | |||||
| //----------------------------------------------------------------------------------------------------------------- | //----------------------------------------------------------------------------------------------------------------- | ||||
| // argv[3-6] => pipes | // argv[3-6] => pipes | ||||
| argv[3] = pipeRecvServerStr; | |||||
| argv[4] = pipeSendServerStr; | |||||
| argv[5] = pipeRecvClientStr; | |||||
| argv[6] = pipeSendClientStr; | |||||
| //----------------------------------------------------------------------------------------------------------------- | |||||
| // argv[7] => null | |||||
| argv[7] = nullptr; | |||||
| argv[i++] = pipeRecvServerStr; | |||||
| argv[i++] = pipeSendServerStr; | |||||
| argv[i++] = pipeRecvClientStr; | |||||
| argv[i++] = pipeSendClientStr; | |||||
| //----------------------------------------------------------------------------------------------------------------- | //----------------------------------------------------------------------------------------------------------------- | ||||
| // start process | // start process | ||||
| @@ -1766,6 +1765,14 @@ bool CarlaPipeServer::startPipeServer(const char* const filename, | |||||
| (void)size; (void)ovRecv; (void)process; | (void)size; (void)ovRecv; (void)process; | ||||
| } | } | ||||
| bool CarlaPipeServer::startPipeServer(const char* const filename, | |||||
| const char* const arg1, | |||||
| const char* const arg2, | |||||
| const int size) noexcept | |||||
| { | |||||
| return startPipeServer(nullptr, filename, arg1, arg2, size); | |||||
| } | |||||
| void CarlaPipeServer::stopPipeServer(const uint32_t timeOutMilliseconds) noexcept | void CarlaPipeServer::stopPipeServer(const uint32_t timeOutMilliseconds) noexcept | ||||
| { | { | ||||
| carla_debug("CarlaPipeServer::stopPipeServer(%i)", timeOutMilliseconds); | carla_debug("CarlaPipeServer::stopPipeServer(%i)", timeOutMilliseconds); | ||||
| @@ -285,13 +285,20 @@ public: | |||||
| * Start the pipe server using @a filename with 2 arguments. | * Start the pipe server using @a filename with 2 arguments. | ||||
| * @see fail() | * @see fail() | ||||
| */ | */ | ||||
| bool startPipeServer(const char* const filename, const char* const arg1, const char* const arg2, const int size = -1) noexcept; | |||||
| bool startPipeServer(const char* helperTool, | |||||
| const char* filename, const char* arg1, const char* arg2, int size = -1) noexcept; | |||||
| /*! | |||||
| * Start the pipe server using @a filename with 2 arguments. | |||||
| * @see fail() | |||||
| */ | |||||
| bool startPipeServer(const char* filename, const char* arg1, const char* arg2, int size = -1) noexcept; | |||||
| /*! | /*! | ||||
| * Stop the pipe server. | * Stop the pipe server. | ||||
| * This will send a quit message to the client, wait for it to close for @a timeOutMilliseconds, and close the pipes. | * This will send a quit message to the client, wait for it to close for @a timeOutMilliseconds, and close the pipes. | ||||
| */ | */ | ||||
| void stopPipeServer(const uint32_t timeOutMilliseconds) noexcept; | |||||
| void stopPipeServer(uint32_t timeOutMilliseconds) noexcept; | |||||
| /*! | /*! | ||||
| * Close the pipes without waiting for the child process to terminate. | * Close the pipes without waiting for the child process to terminate. | ||||