Signed-off-by: falkTX <falktx@falktx.com>tags/v2.1-rc1
@@ -294,11 +294,11 @@ protected: | |||
const ScopedEngineEnvironmentLocker _seel(kEngine); | |||
const ScopedEnvVar sev2("LD_LIBRARY_PATH", libjackdir.buffer()); | |||
const ScopedEnvVar sev1("LD_PRELOAD", ldpreload.isNotEmpty() ? ldpreload.buffer() : nullptr); | |||
#ifdef HAVE_LIBLO | |||
const ScopedEnvVar sev3("NSM_URL", lo_server_get_url(fOscServer)); | |||
#endif | |||
const ScopedEnvVar sev2("LD_LIBRARY_PATH", libjackdir.buffer()); | |||
const ScopedEnvVar sev1("LD_PRELOAD", ldpreload.isNotEmpty() ? ldpreload.buffer() : nullptr); | |||
if (kPlugin->getHints() & PLUGIN_HAS_CUSTOM_UI) | |||
carla_setenv("CARLA_FRONTEND_WIN_ID", winIdStr); | |||
@@ -49,6 +49,13 @@ enum InterposerAction { | |||
LIBJACK_INTERPOSER_ACTION_CLOSE_EVERYTHING, | |||
}; | |||
enum InterposerCallbacks { | |||
LIBJACK_INTERPOSER_CALLBACK_NONE = 0, | |||
LIBJACK_INTERPOSER_CALLBACK_UI_HIDE, | |||
}; | |||
typedef int (*CarlaInterposedCallback)(int, void*); | |||
int jack_carla_interposed_action(uint action, uint value, void* ptr); | |||
#ifdef __cplusplus | |||
@@ -64,7 +64,6 @@ struct ScopedLibOpen { | |||
typedef int (*XWindowFunc)(Display*, Window); | |||
typedef int (*XNextEventFunc)(Display*, XEvent*); | |||
typedef int (*CarlaInterposedCallback)(int, void*); | |||
// -------------------------------------------------------------------------------------------------------------------- | |||
// Current state | |||
@@ -312,7 +311,7 @@ int XUnmapWindow(Display* display, Window window) | |||
gCurrentWindowVisible = false; | |||
if (gInterposedCallback != nullptr) | |||
gInterposedCallback(1, nullptr); | |||
gInterposedCallback(LIBJACK_INTERPOSER_CALLBACK_UI_HIDE, nullptr); | |||
} | |||
return real_XUnmapWindow(display, window); | |||
@@ -344,7 +343,7 @@ int XNextEvent(Display* display, XEvent* event) | |||
gCurrentWindowMapped = false; | |||
if (gInterposedCallback != nullptr) | |||
gInterposedCallback(1, nullptr); | |||
gInterposedCallback(LIBJACK_INTERPOSER_CALLBACK_UI_HIDE, nullptr); | |||
event->type = 0; | |||
carla_stdout("XNextEvent close event catched, hiding UI instead"); | |||
@@ -19,7 +19,7 @@ | |||
#define CARLA_LIBJACK_API_H_INCLUDED | |||
#include "CarlaLibJackHints.h" | |||
#include "jackbridge/JackBridge.hpp" | |||
#include "../jackbridge/JackBridge.hpp" | |||
#include <pthread.h> | |||
@@ -213,7 +213,7 @@ void jack_set_transport_info(jack_client_t*, void*); | |||
#define JACK_UUID_SIZE 36 | |||
#define JACK_UUID_STRING_SIZE (JACK_UUID_SIZE+1) /* includes trailing null */ | |||
// #define JACK_UUID_EMPTY_INITIALIZER 0 | |||
#define JACK_UUID_EMPTY_INITIALIZER 0 | |||
jack_uuid_t jack_client_uuid_generate(); | |||
jack_uuid_t jack_port_uuid_generate(uint32_t port_id); | |||
@@ -25,12 +25,22 @@ | |||
// --------------------------------------------------------------------------------------------------------------------- | |||
typedef int (*CarlaInterposedCallback)(int, void*); | |||
CARLA_EXPORT | |||
int jack_carla_interposed_action(uint, uint, void*) | |||
{ | |||
carla_stderr2("Non-export jack_carla_interposed_action called, this should not happen!!"); | |||
static bool printWarning = true; | |||
if (printWarning) | |||
{ | |||
printWarning = false; | |||
carla_stderr2("Non-exported jack_carla_interposed_action called, this should not happen!!"); | |||
carla_stderr("Printing some info:"); | |||
carla_stderr("\tLD_LIBRARY_PATH: '%s'", std::getenv("LD_LIBRARY_PATH")); | |||
carla_stderr("\tLD_PRELOAD: '%s'", std::getenv("LD_PRELOAD")); | |||
std::fflush(stderr); | |||
} | |||
// ::kill(::getpid(), SIGKILL); | |||
return 1337; | |||
} | |||
@@ -111,10 +121,12 @@ class CarlaJackAppClient : public CarlaJackRealtimeThread::Callback, | |||
public: | |||
JackServerState fServer; | |||
LinkedList<JackClientState*> fClients; | |||
LinkedList<JackClientState*> fNewClients; | |||
CarlaJackAppClient() | |||
: fServer(this), | |||
fClients(), | |||
fNewClients(), | |||
fShmAudioPool(), | |||
fShmRtClientControl(), | |||
fShmNonRtClientControl(), | |||
@@ -133,6 +145,9 @@ public: | |||
fRealtimeThread(this), | |||
fNonRealtimeThread(this), | |||
fRealtimeThreadMutex() | |||
#ifdef DEBUG | |||
,leakDetector_CarlaJackAppClient() | |||
#endif | |||
{ | |||
carla_debug("CarlaJackAppClient::CarlaJackAppClient()"); | |||
@@ -172,8 +187,13 @@ public: | |||
fSessionManager = static_cast<uint>(libjackSetup[4] - '0'); | |||
fSetupHints = static_cast<uint>(libjackSetup[5] - '0'); | |||
jack_carla_interposed_action(LIBJACK_INTERPOSER_ACTION_SET_HINTS_AND_CALLBACK, fSetupHints, (void*)carla_interposed_callback); | |||
jack_carla_interposed_action(LIBJACK_INTERPOSER_ACTION_SET_SESSION_MANAGER, fSessionManager, nullptr); | |||
jack_carla_interposed_action(LIBJACK_INTERPOSER_ACTION_SET_HINTS_AND_CALLBACK, | |||
fSetupHints, | |||
(void*)carla_interposed_callback); | |||
jack_carla_interposed_action(LIBJACK_INTERPOSER_ACTION_SET_SESSION_MANAGER, | |||
fSessionManager, | |||
nullptr); | |||
fNonRealtimeThread.startThread(false); | |||
} | |||
@@ -223,6 +243,11 @@ public: | |||
if (! fClients.append(jclient)) | |||
return false; | |||
if (! fNewClients.append(jclient)) | |||
{ | |||
fClients.removeOne(jclient); | |||
return false; | |||
} | |||
jclient->activated = true; | |||
jclient->deactivated = false; | |||
@@ -252,7 +277,7 @@ public: | |||
switch (cb_action) | |||
{ | |||
case 1: { | |||
case LIBJACK_INTERPOSER_CALLBACK_UI_HIDE: { | |||
const CarlaMutexLocker cml(fShmNonRtServerControl.mutex); | |||
fShmNonRtServerControl.writeOpcode(kPluginBridgeNonRtServerUiClosed); | |||
fShmNonRtServerControl.commitWrite(); | |||
@@ -457,6 +482,20 @@ void CarlaJackAppClient::clearSharedMemory() noexcept | |||
bool CarlaJackAppClient::handleRtData() | |||
{ | |||
if (fNewClients.count() != 0) | |||
{ | |||
for (LinkedList<JackClientState*>::Itenerator it = fNewClients.begin2(); it.valid(); it.next()) | |||
{ | |||
JackClientState* const jclient(it.getValue(nullptr)); | |||
CARLA_SAFE_ASSERT_CONTINUE(jclient != nullptr); | |||
if (jclient->threadInitCb != nullptr) | |||
jclient->threadInitCb(jclient->threadInitCbPtr); | |||
} | |||
fNewClients.clear(); | |||
} | |||
const BridgeRtClientControl::WaitHelper helper(fShmRtClientControl); | |||
if (! helper.ok) | |||
@@ -192,6 +192,9 @@ struct JackClientState { | |||
JackSyncCallback syncCb; | |||
void* syncCbPtr; | |||
JackThreadInitCallback threadInitCb; | |||
void* threadInitCbPtr; | |||
JackClientState(const JackServerState& s, const char* const n) | |||
: server(s), | |||
mutex(), | |||
@@ -216,7 +219,9 @@ struct JackClientState { | |||
sampleRateCb(nullptr), | |||
sampleRateCbPtr(nullptr), | |||
syncCb(nullptr), | |||
syncCbPtr(nullptr) {} | |||
syncCbPtr(nullptr), | |||
threadInitCb(nullptr), | |||
threadInitCbPtr(nullptr) {} | |||
~JackClientState() | |||
{ | |||
@@ -24,8 +24,15 @@ CARLA_BACKEND_USE_NAMESPACE | |||
CARLA_EXPORT | |||
int jack_set_thread_init_callback(jack_client_t* client, JackThreadInitCallback callback, void* arg) | |||
{ | |||
carla_stderr2("%s(%p, %p, %p)", __FUNCTION__, client, callback, arg); | |||
carla_debug("%s(%p, %p, %p)", __FUNCTION__, client, callback, arg); | |||
JackClientState* const jclient = (JackClientState*)client; | |||
CARLA_SAFE_ASSERT_RETURN(jclient != nullptr, 1); | |||
const CarlaMutexLocker cms(jclient->mutex); | |||
jclient->threadInitCb = callback; | |||
jclient->threadInitCbPtr = arg; | |||
return 0; | |||
} | |||
@@ -47,16 +47,62 @@ const char* JACK_METADATA_ICON_LARGE = "http://jackaudio.org/metadata/icon-large | |||
// -------------------------------------------------------------------------------------------------------------------- | |||
typedef struct { | |||
jack_uuid_t uuid; | |||
std::string key; | |||
} MetadataKey; | |||
typedef struct { | |||
std::string type; | |||
std::string value; | |||
} MetadataValue; | |||
typedef std::map<MetadataKey, MetadataValue> Metadata; | |||
static Metadata sMetadata; | |||
// -------------------------------------------------------------------------------------------------------------------- | |||
CARLA_EXPORT | |||
int jack_set_property(jack_client_t*, jack_uuid_t, const char*, const char*, const char*) | |||
int jack_set_property(jack_client_t*, jack_uuid_t uuid, const char* key, const char* value, const char* type) | |||
{ | |||
return -1; | |||
CARLA_SAFE_ASSERT_RETURN(uuid != JACK_UUID_EMPTY_INITIALIZER, -1); | |||
CARLA_SAFE_ASSERT_RETURN(key != nullptr && key[0] != '\0', -1); | |||
CARLA_SAFE_ASSERT_RETURN(value != nullptr && value[0] != '\0', -1); | |||
const MetadataKey mkey = { uuid, key }; | |||
const MetadataValue mvalue = { value, type }; | |||
// sMetadata[mkey] = mvalue; | |||
return 0; | |||
} | |||
CARLA_EXPORT | |||
int jack_get_property(jack_uuid_t, const char*, char**, char**) | |||
int jack_get_property(jack_uuid_t uuid, const char* key, char** value, char** type) | |||
{ | |||
CARLA_SAFE_ASSERT_RETURN(uuid != JACK_UUID_EMPTY_INITIALIZER, -1); | |||
CARLA_SAFE_ASSERT_RETURN(key != nullptr && key[0] != '\0', -1); | |||
// const MetadataKey mkey = { uuid, key }; | |||
// const auto mvalueit = sMetadata.find(mkey); | |||
// | |||
// if (mvalueit == sMetadata.end()) | |||
// return -1; | |||
// | |||
// const MetadataValue& mvalue = mvalueit->second; | |||
// *value = strdup(mvalue.value.c_str()); | |||
// | |||
// if (mvalue.type.size() != 0) | |||
// *type = strdup(mvalue.type.c_str()); | |||
// else | |||
// *type = nullptr; | |||
return -1; | |||
(void)value; | |||
(void)type; | |||
} | |||
CARLA_EXPORT | |||
@@ -77,21 +123,43 @@ int jack_get_all_properties(jack_description_t**) | |||
} | |||
CARLA_EXPORT | |||
int jack_remove_property(jack_client_t*, jack_uuid_t, const char*) | |||
int jack_remove_property(jack_client_t*, jack_uuid_t uuid, const char* key) | |||
{ | |||
// const MetadataKey mkey = { uuid, key }; | |||
// sMetadata.erase(mkey); | |||
return -1; | |||
(void)uuid; | |||
(void)key; | |||
} | |||
CARLA_EXPORT | |||
int jack_remove_properties(jack_client_t*, jack_uuid_t) | |||
int jack_remove_properties(jack_client_t*, jack_uuid_t uuid) | |||
{ | |||
return -1; | |||
int count = 0; | |||
// for (Metadata::const_iterator cit = sMetadata.begin(), cend = sMetadata.end(); cit != cend; ++cit) | |||
{ | |||
// const MetadataKey& mkey = cit->first; | |||
// if (mkey.uuid != uuid) | |||
// continue; | |||
// ++count; | |||
// sMetadata.erase(mkey); | |||
} | |||
return count; | |||
(void)uuid; | |||
} | |||
CARLA_EXPORT | |||
int jack_remove_all_properties(jack_client_t*) | |||
{ | |||
return -1; | |||
// sMetadata = {}; | |||
return 0; | |||
} | |||
CARLA_EXPORT | |||
@@ -105,56 +173,76 @@ int jack_set_property_change_callback(jack_client_t*, JackPropertyChangeCallback | |||
CARLA_EXPORT | |||
jack_uuid_t jack_client_uuid_generate() | |||
{ | |||
return 0; | |||
static uint32_t uuid_cnt = 0; | |||
jack_uuid_t uuid = 0x2; /* JackUUIDClient */; | |||
uuid = (uuid << 32) | ++uuid_cnt; | |||
return uuid; | |||
} | |||
CARLA_EXPORT | |||
jack_uuid_t jack_port_uuid_generate(uint32_t) | |||
jack_uuid_t jack_port_uuid_generate(uint32_t port_id) | |||
{ | |||
return 0; | |||
jack_uuid_t uuid = 0x1; /* JackUUIDPort */ | |||
uuid = (uuid << 32) | (port_id + 1); | |||
return uuid; | |||
} | |||
CARLA_EXPORT | |||
uint32_t jack_uuid_to_index(jack_uuid_t) | |||
uint32_t jack_uuid_to_index(jack_uuid_t u) | |||
{ | |||
return 0; | |||
return static_cast<uint32_t>(u & 0xffff) - 1; | |||
} | |||
CARLA_EXPORT | |||
int jack_uuid_compare(jack_uuid_t, jack_uuid_t) | |||
int jack_uuid_compare(jack_uuid_t a, jack_uuid_t b) | |||
{ | |||
return 0; | |||
if (a == b) { | |||
return 0; | |||
} | |||
if (a < b) { | |||
return -1; | |||
} | |||
return 1; | |||
} | |||
CARLA_EXPORT | |||
void jack_uuid_copy(jack_uuid_t*, jack_uuid_t) | |||
void jack_uuid_copy(jack_uuid_t* dst, jack_uuid_t src) | |||
{ | |||
*dst = src; | |||
} | |||
CARLA_EXPORT | |||
void jack_uuid_clear(jack_uuid_t*) | |||
void jack_uuid_clear(jack_uuid_t* uuid) | |||
{ | |||
*uuid = JACK_UUID_EMPTY_INITIALIZER; | |||
} | |||
CARLA_EXPORT | |||
int jack_uuid_parse(const char*, jack_uuid_t*) | |||
int jack_uuid_parse(const char* b, jack_uuid_t* u) | |||
{ | |||
if (std::sscanf(b, P_UINT64, u) != 1) | |||
return -1; | |||
if (*u < (0x1LL << 32)) { | |||
/* has not type bits set - not legal */ | |||
return -1; | |||
} | |||
return 0; | |||
} | |||
CARLA_EXPORT | |||
void jack_uuid_unparse(jack_uuid_t, char buf[JACK_UUID_STRING_SIZE]) | |||
void jack_uuid_unparse(jack_uuid_t u, char buf[JACK_UUID_STRING_SIZE]) | |||
{ | |||
return; | |||
// unused | |||
(void)buf; | |||
std::snprintf(buf, JACK_UUID_STRING_SIZE, P_UINT64, u); | |||
} | |||
CARLA_EXPORT | |||
int jack_uuid_empty(jack_uuid_t) | |||
int jack_uuid_empty(jack_uuid_t u) | |||
{ | |||
return 0; | |||
return u == JACK_UUID_EMPTY_INITIALIZER; | |||
} | |||
// -------------------------------------------------------------------------------------------------------------------- |