47 changes: 45 additions & 2 deletions source/discovery/carla-discovery.cpp
Expand Up @@ -18,7 +18,6 @@
#include "CarlaBackendUtils.hpp"
#include "CarlaLibUtils.hpp"
#include "CarlaMathUtils.hpp"
#include "CarlaPipeUtils.cpp"
#include "CarlaScopeUtils.hpp"

#include "CarlaMIDI.h"
Expand All @@ -31,6 +30,10 @@
#include "CarlaVst3Utils.hpp"
#include "CarlaClapUtils.hpp"

#ifndef BUILDING_CARLA_FOR_WINE
# include "CarlaPipeUtils.cpp"
#endif

#ifdef CARLA_OS_MAC
# include "CarlaMacUtils.cpp"
# ifdef __aarch64__
Expand Down Expand Up @@ -80,6 +83,11 @@
# pragma GCC diagnostic pop
#endif

// must be last
#ifdef BUILDING_CARLA_FOR_WINE
# include "../jackbridge/JackBridge.hpp"
#endif

#define MAX_DISCOVERY_AUDIO_IO 64
#define MAX_DISCOVERY_CV_IO 32

Expand All @@ -102,6 +110,7 @@ static constexpr const float kSampleRatef = 44100.0f;
// --------------------------------------------------------------------------------------------------------------------
// Dynamic discovery

#ifndef BUILDING_CARLA_FOR_WINE
class DiscoveryPipe : public CarlaPipeClient
{
public:
Expand All @@ -124,7 +133,7 @@ class DiscoveryPipe : public CarlaPipeClient
if (! writeAndFixMessage(value))
return false;

flushMessages();
syncMessages();
return true;
}

Expand All @@ -135,6 +144,37 @@ class DiscoveryPipe : public CarlaPipeClient
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;

Expand Down Expand Up @@ -2667,6 +2707,7 @@ int main(int argc, const char* argv[])
if (handle == nullptr)
{
print_lib_error(filename);
gPipe = nullptr;
return 1;
}
}
Expand All @@ -2685,6 +2726,7 @@ int main(int argc, const char* argv[])
if (! lib_close(handle))
{
print_lib_error(filename);
gPipe = nullptr;
return 1;
}

Expand All @@ -2693,6 +2735,7 @@ int main(int argc, const char* argv[])
if (handle == nullptr)
{
print_lib_error(filename);
gPipe = nullptr;
return 1;
}
}
Expand Down
192 changes: 142 additions & 50 deletions source/frontend/pluginlist/pluginlistdialog.cpp
Expand Up @@ -356,16 +356,16 @@ struct PluginPaths {

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";
clap += ":" + winePrefix + "/drive_c/Program Files/Common Files/CLAP";

#ifdef CARLA_OS_64BIT
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";
clap += ":" + winePrefix + "/drive_c/Program Files (x86)/Common Files/CLAP";
}
Expand Down Expand Up @@ -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, {});

// read POD data first
const PluginFavoriteHeader* const data
const PluginFavoriteHeader* const data
= static_cast<const PluginFavoriteHeader*>(static_cast<const void*>(qdata.constData()));
PluginFavorite fav = { data->type, data->uniqueId, {}, {} };

Expand Down Expand Up @@ -673,6 +673,7 @@ struct PluginListDialog::PrivateData {
bool hasLoadedLv2Plugins = false;

struct Discovery {
BinaryType btype = BINARY_NATIVE;
PluginType ptype = PLUGIN_NONE;
bool firstInit = true;
bool ignoreCache = false;
Expand All @@ -682,18 +683,94 @@ struct PluginListDialog::PrivateData {
CarlaScopedPointer<PluginRefreshDialog> dialog;
Discovery()
{
tool = carla_get_library_folder();
tool += CARLA_OS_SEP_STR "carla-discovery-native";
#ifdef CARLA_OS_WIN
tool += ".exe";
#endif
restart();
}

~Discovery()
{
if (handle != nullptr)
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;

PluginPaths paths;
Expand Down Expand Up @@ -788,10 +865,11 @@ PluginListDialog::PluginListDialog(QWidget* const parent, const HostSettings& ho
// custom action that listens for Ctrl+F shortcut
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)"));
#else
ui.ch_bridged->setChecked(false);
ui.ch_bridged->setEnabled(false);
#endif

#if !(defined(CARLA_OS_LINUX) || defined(CARLA_OS_MAC))
Expand Down Expand Up @@ -1081,9 +1159,13 @@ void PluginListDialog::timerEvent(QTimerEvent* const event)
{
case PLUGIN_NONE:
#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:
ui.label->setText(tr("Discovering LADSPA plugins..."));
path = p->paths.ladspa;
Expand Down Expand Up @@ -1118,12 +1200,16 @@ void PluginListDialog::timerEvent(QTimerEvent* const event)
case PLUGIN_CLAP:
#ifndef CARLA_FRONTEND_ONLY_EMBEDDABLE_PLUGINS
#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:
#endif
if (p->paths.jsfx.isNotEmpty())
if (p->discovery.btype == BINARY_NATIVE && p->paths.jsfx.isNotEmpty())
{
ui.label->setText(tr("Discovering JSFX plugins..."));
path = p->paths.jsfx;
Expand All @@ -1132,20 +1218,29 @@ void PluginListDialog::timerEvent(QTimerEvent* const event)
}
[[fallthrough]];
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:
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:
#endif
default:
// discovery complete
refreshPluginsStop();
if (! p->discovery.nextTool())
refreshPluginsStop();
}

if (p->timerId == 0)
Expand All @@ -1155,6 +1250,7 @@ void PluginListDialog::timerEvent(QTimerEvent* const event)
p->discovery.dialog->progressBar->setFormat(ui.label->text());

p->discovery.handle = carla_plugin_discovery_start(p->discovery.tool.toUtf8().constData(),
p->discovery.btype,
p->discovery.ptype,
path.toUtf8().constData(),
discoveryCallback, checkCacheCallback, this);
Expand Down Expand Up @@ -1462,17 +1558,19 @@ void PluginListDialog::checkFilters()
const bool hideNonIDisp = ui.ch_inline_display->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)
{
Expand All @@ -1499,14 +1597,8 @@ void PluginListDialog::checkFilters()
const bool hasCV = cvIns + cvOuts > 0;
const bool hasGui = phints & PLUGIN_HAS_CUSTOM_UI;
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 QStringList textSplit = text.strip().split(' ');
Expand Down Expand Up @@ -1798,15 +1890,15 @@ void PluginListDialog::refreshPluginsStart()
p->plugins.cache.clear();

// start discovery again
p->discovery.ptype = PLUGIN_NONE;
p->discovery.restart();

if (p->timerId == 0)
p->timerId = startTimer(0);
}

void PluginListDialog::refreshPluginsStop()
{
// stop previous discovery if still running
// stop previous discovery if still running
if (p->discovery.handle != nullptr)
{
carla_plugin_discovery_stop(p->discovery.handle);
Expand Down
4 changes: 4 additions & 0 deletions source/jackbridge/JackBridge.hpp
Expand Up @@ -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_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;

#endif // JACKBRIDGE_HPP_INCLUDED
75 changes: 70 additions & 5 deletions source/jackbridge/JackBridge2.cpp
@@ -1,6 +1,6 @@
/*
* 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
* or without fee is hereby granted, provided that the above copyright notice and this
Expand All @@ -22,9 +22,13 @@
# include "CarlaProcessUtils.hpp"
# include "CarlaSemUtils.hpp"
# include "CarlaShmUtils.hpp"
# include "CarlaTimeUtils.hpp"
# ifdef __WINE__
# include "utils/PipeClient.cpp"
# endif
#endif // ! JACKBRIDGE_DUMMY

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

bool jackbridge_sem_init(void* sem) noexcept
{
Expand Down Expand Up @@ -77,7 +81,7 @@ bool jackbridge_sem_timedwait(void* sem, uint msecs, bool server) noexcept
}
#endif

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

bool jackbridge_shm_is_valid(const void* shm) noexcept
{
Expand Down Expand Up @@ -137,7 +141,68 @@ void jackbridge_shm_unmap(void* shm, void* ptr) noexcept
#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
{
Expand All @@ -146,4 +211,4 @@ void jackbridge_parent_deathsig(bool kill) noexcept
#endif
}

// -----------------------------------------------------------------------------
// --------------------------------------------------------------------------------------------------------------------
11 changes: 7 additions & 4 deletions source/jackbridge/JackBridge3.cpp
@@ -1,6 +1,6 @@
/*
* 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
* or without fee is hereby granted, provided that the above copyright notice and this
Expand All @@ -18,15 +18,15 @@

#include "CarlaUtils.hpp"

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

#if defined(CARLA_OS_WIN) && ! defined(__WINE__)
# define JACKBRIDGE_EXPORT extern "C" __declspec (dllexport)
#else
# define JACKBRIDGE_EXPORT extern "C" __attribute__ ((visibility("default")))
#endif

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

JACKBRIDGE_EXPORT
const JackBridgeExportedFunctions* JACKBRIDGE_API jackbridge_get_exported_functions();
Expand Down Expand Up @@ -140,11 +140,14 @@ const JackBridgeExportedFunctions* JACKBRIDGE_API jackbridge_get_exported_functi
funcs.shm_close_ptr = jackbridge_shm_close;
funcs.shm_map_ptr = jackbridge_shm_map;
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.unique1 = funcs.unique2 = funcs.unique3 = 0xdeadf00d;

return &funcs;
}

// -----------------------------------------------------------------------------
// --------------------------------------------------------------------------------------------------------------------
42 changes: 32 additions & 10 deletions source/jackbridge/JackBridgeExport.cpp
@@ -1,6 +1,6 @@
/*
* 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
* or without fee is hereby granted, provided that the above copyright notice and this
Expand All @@ -17,8 +17,11 @@
#include "JackBridgeExport.hpp"

#include "CarlaLibUtils.hpp"
#include "CarlaUtils.h"

// -----------------------------------------------------------------------------
// #include <cstdio>

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

class JackBridgeExported
{
Expand All @@ -27,11 +30,11 @@ class JackBridgeExported
: lib(nullptr),
func(nullptr)
{
#ifdef CARLA_OS_WIN64
#ifdef CARLA_OS_WIN64
lib = lib_open("jackbridge-wine64.dll");
#else
#else
lib = lib_open("jackbridge-wine32.dll");
#endif
#endif
CARLA_SAFE_ASSERT_RETURN(lib != nullptr,);

func = lib_symbol<jackbridge_exported_function_type>(lib, "jackbridge_get_exported_functions");
Expand Down Expand Up @@ -59,12 +62,12 @@ class JackBridgeExported
static const JackBridgeExported bridge;
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->unique1 != 0, fallback);
CARLA_SAFE_ASSERT_RETURN(funcs->unique1 == funcs->unique2, 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;
}
Expand All @@ -77,15 +80,15 @@ class JackBridgeExported
CARLA_DECLARE_NON_COPYABLE(JackBridgeExported);
};

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

static const JackBridgeExportedFunctions& getBridgeInstance() noexcept
{
static const JackBridgeExportedFunctions& funcs(JackBridgeExported::getFunctions());
return funcs;
}

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

bool jackbridge_is_ok() noexcept
{
Expand Down Expand Up @@ -598,9 +601,28 @@ void jackbridge_shm_unmap(void* shm, void* ptr) noexcept
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
{
return getBridgeInstance().parent_deathsig_ptr(kill);
}

// -----------------------------------------------------------------------------
// --------------------------------------------------------------------------------------------------------------------
10 changes: 9 additions & 1 deletion source/jackbridge/JackBridgeExport.hpp
@@ -1,6 +1,6 @@
/*
* 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
* or without fee is hereby granted, provided that the above copyright notice and this
Expand All @@ -14,6 +14,8 @@
* CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/

#pragma once

#include "JackBridge.hpp"

extern "C" {
Expand Down Expand Up @@ -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_map)(void*, uint64_t);
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);

// -----------------------------------------------------------------------------
Expand Down Expand Up @@ -233,6 +238,9 @@ struct _JackBridgeExportedFunctions {
jackbridgesym_shm_close shm_close_ptr;
jackbridgesym_shm_map shm_map_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;
ulong unique3;
};
Expand Down
8 changes: 7 additions & 1 deletion source/jackbridge/Makefile
Expand Up @@ -10,14 +10,20 @@ include ../modules/Makefile.mk

# ---------------------------------------------------------------------------------------------------------------------

BUILD_CXX_FLAGS += $(JACKBRIDGE_FLAGS)
BUILD_CXX_FLAGS += $(JACKBRIDGE_FLAGS) -I../backend
LINK_FLAGS += $(JACKBRIDGE_LIBS)

ifeq ($(JACKBRIDGE_DIRECT),true)
BUILD_CXX_FLAGS += $(JACK_FLAGS) -DJACKBRIDGE_DIRECT
LINK_FLAGS += $(JACK_LIBS)
endif

ifneq ($(BUILDING_FOR_WINE),true)
ifeq ($(WINDOWS),true)
BUILD_CXX_FLAGS += -I../modules
endif
endif

WINE_32BIT_FLAGS = $(32BIT_FLAGS) -fpermissive
WINE_64BIT_FLAGS = $(64BIT_FLAGS) -fpermissive
WINE_BUILD_FLAGS = $(filter-out -flto,$(BUILD_CXX_FLAGS))
Expand Down
2 changes: 1 addition & 1 deletion source/utils/CarlaBinaryUtils.hpp
Expand Up @@ -88,7 +88,7 @@ BinaryType getBinaryTypeFromFile(const char* const filename)
#if defined(HAVE_LIBMAGIC) && ! defined(BUILD_BRIDGE_ALTERNATIVE_ARCH)
static const CarlaMagic magic;

const char* const output(magic.getFileDescription(filename));
const char* const output = magic.getFileDescription(filename);

if (output != nullptr && output[0] != '\0')
{
Expand Down
39 changes: 23 additions & 16 deletions source/utils/CarlaPipeUtils.cpp
Expand Up @@ -35,9 +35,8 @@

#include <fcntl.h>

#include "water/text/String.h"

#ifdef CARLA_OS_WIN
# include "water/text/String.h"
# include <ctime>
#else
# include <cerrno>
Expand Down Expand Up @@ -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 arg2,
const int size) noexcept
Expand Down Expand Up @@ -1642,31 +1642,30 @@ bool CarlaPipeServer::startPipeServer(const char* const filename,
//-----------------------------------------------------------------------------------------------------------------
// 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[i++] = filename;

//-----------------------------------------------------------------------------------------------------------------
// argv[1-2] => args

argv[1] = arg1;
argv[2] = arg2;
argv[i++] = arg1;
argv[i++] = arg2;

//-----------------------------------------------------------------------------------------------------------------
// 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
Expand Down Expand Up @@ -1766,6 +1765,14 @@ bool CarlaPipeServer::startPipeServer(const char* const filename,
(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
{
carla_debug("CarlaPipeServer::stopPipeServer(%i)", timeOutMilliseconds);
Expand Down
11 changes: 9 additions & 2 deletions source/utils/CarlaPipeUtils.hpp
Expand Up @@ -285,13 +285,20 @@ class CarlaPipeServer : public CarlaPipeCommon
* Start the pipe server using @a filename with 2 arguments.
* @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.
* 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.
Expand Down