Browse Source

Implement auto-discovery for wine bridges

Signed-off-by: falkTX <falktx@falktx.com>
pull/1807/head
falkTX 2 years ago
parent
commit
cec462a44d
Signed by: falkTX <falktx@falktx.com> GPG Key ID: CDBAA37ABC74FBA0
17 changed files with 452 additions and 126 deletions
  1. +1
    -1
      Makefile
  2. +1
    -0
      source/backend/CarlaUtils.h
  3. +1
    -0
      source/backend/utils/Makefile
  4. +1
    -1
      source/backend/utils/PipeClient.cpp
  5. +89
    -27
      source/backend/utils/PluginDiscovery.cpp
  6. +10
    -5
      source/discovery/Makefile
  7. +45
    -2
      source/discovery/carla-discovery.cpp
  8. +142
    -50
      source/frontend/pluginlist/pluginlistdialog.cpp
  9. +4
    -0
      source/jackbridge/JackBridge.hpp
  10. +70
    -5
      source/jackbridge/JackBridge2.cpp
  11. +7
    -4
      source/jackbridge/JackBridge3.cpp
  12. +32
    -10
      source/jackbridge/JackBridgeExport.cpp
  13. +9
    -1
      source/jackbridge/JackBridgeExport.hpp
  14. +7
    -1
      source/jackbridge/Makefile
  15. +1
    -1
      source/utils/CarlaBinaryUtils.hpp
  16. +23
    -16
      source/utils/CarlaPipeUtils.cpp
  17. +9
    -2
      source/utils/CarlaPipeUtils.hpp

+ 1
- 1
Makefile View File

@@ -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


+ 1
- 0
source/backend/CarlaUtils.h View File

@@ -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,


+ 1
- 0
source/backend/utils/Makefile View File

@@ -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
- 1
source/backend/utils/PipeClient.cpp View File

@@ -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


+ 89
- 27
source/backend/utils/PluginDiscovery.cpp View File

@@ -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)


+ 10
- 5
source/discovery/Makefile View File

@@ -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


+ 45
- 2
source/discovery/carla-discovery.cpp View File

@@ -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;
} }
} }


+ 142
- 50
source/frontend/pluginlist/pluginlistdialog.cpp View File

@@ -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);


+ 4
- 0
source/jackbridge/JackBridge.hpp View File

@@ -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

+ 70
- 5
source/jackbridge/JackBridge2.cpp View File

@@ -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
} }


// -----------------------------------------------------------------------------
// --------------------------------------------------------------------------------------------------------------------

+ 7
- 4
source/jackbridge/JackBridge3.cpp View File

@@ -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;
} }


// -----------------------------------------------------------------------------
// --------------------------------------------------------------------------------------------------------------------

+ 32
- 10
source/jackbridge/JackBridgeExport.cpp View File

@@ -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);
} }


// -----------------------------------------------------------------------------
// --------------------------------------------------------------------------------------------------------------------

+ 9
- 1
source/jackbridge/JackBridgeExport.hpp View File

@@ -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;
}; };


+ 7
- 1
source/jackbridge/Makefile View File

@@ -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))


+ 1
- 1
source/utils/CarlaBinaryUtils.hpp View File

@@ -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')
{ {


+ 23
- 16
source/utils/CarlaPipeUtils.cpp View File

@@ -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);


+ 9
- 2
source/utils/CarlaPipeUtils.hpp View File

@@ -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.


Loading…
Cancel
Save