Browse Source

Carla: Rework plugin-bridge, misc fixing

tags/v0.9.0
falkTX 13 years ago
parent
commit
3967d36145
14 changed files with 377 additions and 374 deletions
  1. +4
    -11
      c++/carla-backend/carla_backend_standalone.cpp
  2. +1
    -1
      c++/carla-backend/carla_backend_standalone.h
  3. +2
    -2
      c++/carla-backend/carla_bridge.cpp
  4. +6
    -2
      c++/carla-backend/carla_engine.cpp
  5. +2
    -1
      c++/carla-backend/carla_engine.h
  6. +11
    -5
      c++/carla-backend/carla_plugin.h
  7. +0
    -5
      c++/carla-backend/carla_threads.cpp
  8. +10
    -7
      c++/carla-backend/lv2.cpp
  9. +16
    -10
      c++/carla-backend/vst.cpp
  10. +0
    -2
      c++/carla-bridge/carla_bridge_client.h
  11. +298
    -316
      c++/carla-bridge/carla_bridge_plugin.cpp
  12. +2
    -0
      c++/carla-bridge/carla_bridge_toolkit.h
  13. +4
    -4
      src/carla_backend.py
  14. +21
    -8
      src/shared_carla.py

+ 4
- 11
c++/carla-backend/carla_backend_standalone.cpp View File

@@ -1066,23 +1066,16 @@ void set_chunk_data(unsigned short plugin_id, const char* chunk_data)
qCritical("CarlaBackendStandalone::set_chunk_data(%i, \"%s\") - could not find plugin", plugin_id, chunk_data); qCritical("CarlaBackendStandalone::set_chunk_data(%i, \"%s\") - could not find plugin", plugin_id, chunk_data);
} }


void set_gui_data(unsigned short plugin_id, uintptr_t gui_addr)
void set_gui_container(unsigned short plugin_id, uintptr_t gui_addr)
{ {
qDebug("CarlaBackendStandalone::set_gui_data(%i, " P_UINTPTR ")", plugin_id, gui_addr);
qDebug("CarlaBackendStandalone::set_gui_container(%i, " P_UINTPTR ")", plugin_id, gui_addr);


CarlaBackend::CarlaPlugin* const plugin = carlaEngine->getPlugin(plugin_id); CarlaBackend::CarlaPlugin* const plugin = carlaEngine->getPlugin(plugin_id);


if (plugin) if (plugin)
{
#ifdef __WINE__
plugin->setGuiData((HWND)gui_addr);
#else
plugin->setGuiData((QDialog*)CarlaBackend::getPointer(gui_addr));
#endif
return;
}
return plugin->setGuiContainer((GuiContainer*)CarlaBackend::getPointer(gui_addr));


qCritical("CarlaBackendStandalone::set_gui_data(%i, " P_UINTPTR ") - could not find plugin", plugin_id, gui_addr);
qCritical("CarlaBackendStandalone::set_gui_container(%i, " P_UINTPTR ") - could not find plugin", plugin_id, gui_addr);
} }


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


+ 1
- 1
c++/carla-backend/carla_backend_standalone.h View File

@@ -152,7 +152,7 @@ CARLA_EXPORT void set_midi_program(unsigned short plugin_id, uint32_t midi_progr


CARLA_EXPORT void set_custom_data(unsigned short plugin_id, CarlaBackend::CustomDataType dtype, const char* key, const char* value); CARLA_EXPORT void set_custom_data(unsigned short plugin_id, CarlaBackend::CustomDataType dtype, const char* key, const char* value);
CARLA_EXPORT void set_chunk_data(unsigned short plugin_id, const char* chunk_data); CARLA_EXPORT void set_chunk_data(unsigned short plugin_id, const char* chunk_data);
CARLA_EXPORT void set_gui_data(unsigned short plugin_id, uintptr_t gui_addr);
CARLA_EXPORT void set_gui_container(unsigned short plugin_id, uintptr_t gui_addr);


CARLA_EXPORT void show_gui(unsigned short plugin_id, bool yesno); CARLA_EXPORT void show_gui(unsigned short plugin_id, bool yesno);
CARLA_EXPORT void idle_guis(); CARLA_EXPORT void idle_guis();


+ 2
- 2
c++/carla-backend/carla_bridge.cpp View File

@@ -497,8 +497,8 @@ public:


Q_ASSERT(index >= 0 && index < (int32_t)param.count); Q_ASSERT(index >= 0 && index < (int32_t)param.count);
Q_ASSERT(min < max); Q_ASSERT(min < max);
Q_ASSERT(def > min);
Q_ASSERT(def < max);
Q_ASSERT(def >= min);
Q_ASSERT(def <= max);


if (index >= 0 && index < (int32_t)param.count) if (index >= 0 && index < (int32_t)param.count)
{ {


+ 6
- 2
c++/carla-backend/carla_engine.cpp View File

@@ -28,8 +28,8 @@ CarlaEngine::CarlaEngine()
: m_checkThread(this), : m_checkThread(this),
#ifndef BUILD_BRIDGE #ifndef BUILD_BRIDGE
m_osc(this), m_osc(this),
m_oscData(nullptr),
#endif #endif
m_oscData(nullptr),
m_callback(nullptr), m_callback(nullptr),
#ifdef Q_COMPILER_INITIALIZER_LISTS #ifdef Q_COMPILER_INITIALIZER_LISTS
m_callbackPtr(nullptr), m_callbackPtr(nullptr),
@@ -529,12 +529,16 @@ void CarlaEngine::midiUnlock()
// ----------------------------------------------------------------------- // -----------------------------------------------------------------------
// OSC Stuff // OSC Stuff


#ifndef BUILD_BRIDGE
bool CarlaEngine::isOscControllerRegisted() const bool CarlaEngine::isOscControllerRegisted() const
{ {
#ifndef BUILD_BRIDGE
return m_osc.isControllerRegistered(); return m_osc.isControllerRegistered();
#else
return bool(m_oscData);
#endif
} }


#ifndef BUILD_BRIDGE
const char* CarlaEngine::getOscServerPath() const const char* CarlaEngine::getOscServerPath() const
{ {
return m_osc.getServerPath(); return m_osc.getServerPath();


+ 2
- 1
c++/carla-backend/carla_engine.h View File

@@ -260,8 +260,9 @@ public:
// ------------------------------------------------------------------- // -------------------------------------------------------------------
// OSC Stuff // OSC Stuff


#ifndef BUILD_BRIDGE
bool isOscControllerRegisted() const; bool isOscControllerRegisted() const;

#ifndef BUILD_BRIDGE
const char* getOscServerPath() const; const char* getOscServerPath() const;
#else #else
void setOscBridgeData(const CarlaOscData* const oscData); void setOscBridgeData(const CarlaOscData* const oscData);


+ 11
- 5
c++/carla-backend/carla_plugin.h View File

@@ -35,6 +35,13 @@
#include <vector> #include <vector>
#include <QtGui/QDialog> #include <QtGui/QDialog>


#ifdef Q_WS_X11
#include <QtGui/QX11EmbedContainer>
typedef QX11EmbedContainer GuiContainer;
#else
typedef QWidget GuiContainer;
#endif

CARLA_BACKEND_START_NAMESPACE CARLA_BACKEND_START_NAMESPACE


/*! /*!
@@ -1255,14 +1262,13 @@ public:
// Set gui stuff // Set gui stuff


/*! /*!
* Set the plugin's custom GUI data.\n
* Parameters change between plugin types.
* Set the plugin's custom GUI container.\n
* *
* \note This function must be always called from the main thread. * \note This function must be always called from the main thread.
*/ */
virtual void setGuiData(QDialog* const dialog)
virtual void setGuiContainer(GuiContainer* const container)
{ {
Q_UNUSED(dialog);
Q_UNUSED(container);
} }


/*! /*!
@@ -1393,10 +1399,10 @@ public:
*/ */
void registerToOsc() void registerToOsc()
{ {
#ifndef BUILD_BRIDGE
if (! x_engine->isOscControllerRegisted()) if (! x_engine->isOscControllerRegisted())
return; return;


#ifndef BUILD_BRIDGE
x_engine->osc_send_control_add_plugin(m_id, m_name); x_engine->osc_send_control_add_plugin(m_id, m_name);
#endif #endif




+ 0
- 5
c++/carla-backend/carla_threads.cpp View File

@@ -73,12 +73,7 @@ void CarlaCheckThread::run()
while (engine->isRunning() && ! m_stopNow) while (engine->isRunning() && ! m_stopNow)
{ {
const ScopedLocker m(this); const ScopedLocker m(this);

#ifdef BUILD_BRIDGE
oscControllerRegisted = true;
#else
oscControllerRegisted = engine->isOscControllerRegisted(); oscControllerRegisted = engine->isOscControllerRegisted();
#endif


for (unsigned short i=0; i < maxPluginNumber; i++) for (unsigned short i=0; i < maxPluginNumber; i++)
{ {


+ 10
- 7
c++/carla-backend/lv2.cpp View File

@@ -887,8 +887,11 @@ public:
// ------------------------------------------------------------------- // -------------------------------------------------------------------
// Set gui stuff // Set gui stuff


void setGuiData(QDialog* const dialog)
void setGuiContainer(GuiContainer* const container)
{ {
qDebug("Lv2Plugin::setGuiContainer(%p)", container);
Q_ASSERT(container);

switch(gui.type) switch(gui.type)
{ {
case GUI_NONE: case GUI_NONE:
@@ -898,9 +901,11 @@ public:
if (ui.widget) if (ui.widget)
{ {
QWidget* const widget = (QWidget*)ui.widget; QWidget* const widget = (QWidget*)ui.widget;
dialog->layout()->addWidget(widget);
Q_ASSERT(container->layout());
Q_ASSERT(widget);
container->layout()->addWidget(widget);
widget->adjustSize(); widget->adjustSize();
widget->setParent(dialog);
widget->setParent(container);
widget->show(); widget->show();
} }
break; break;
@@ -910,10 +915,8 @@ public:
case GUI_INTERNAL_X11: case GUI_INTERNAL_X11:
if (ui.descriptor) if (ui.descriptor)
{ {
features[lv2_feature_id_ui_parent]->data = (void*)dialog->winId();
ui.handle = ui.descriptor->instantiate(ui.descriptor,
descriptor->URI, ui.rdf_descriptor->Bundle,
carla_lv2_ui_write_function, this, &ui.widget,features);
features[lv2_feature_id_ui_parent]->data = (void*)container->winId();
ui.handle = ui.descriptor->instantiate(ui.descriptor, descriptor->URI, ui.rdf_descriptor->Bundle, carla_lv2_ui_write_function, this, &ui.widget, features);
updateUi(); updateUi();
} }
break; break;


+ 16
- 10
c++/carla-backend/vst.cpp View File

@@ -328,19 +328,22 @@ public:
// ------------------------------------------------------------------- // -------------------------------------------------------------------
// Set gui stuff // Set gui stuff


void setGuiData(QDialog* const dialog)
void setGuiContainer(GuiContainer* const container)
{ {
Q_ASSERT(dialog);
qDebug("VstPlugin::setGuiContainer(%p)", container);
Q_ASSERT(container);


if (gui.type == GUI_EXTERNAL_OSC) if (gui.type == GUI_EXTERNAL_OSC)
return; return;


int32_t value = 0;
int32_t value = 0;
void* const ptr = (void*)container->winId();

#ifdef Q_WS_X11 #ifdef Q_WS_X11
value = (int64_t)QX11Info::display();
value = (intptr_t)QX11Info::display();
#endif #endif


if (effect->dispatcher(effect, effEditOpen, 0, value, (void*)dialog->winId(), 0.0f) == 1)
if (effect->dispatcher(effect, effEditOpen, 0, value, ptr, 0.0f) == 1)
{ {
ERect* vstRect = nullptr; ERect* vstRect = nullptr;
effect->dispatcher(effect, effEditGetRect, 0, 0, &vstRect, 0.0f); effect->dispatcher(effect, effEditGetRect, 0, 0, &vstRect, 0.0f);
@@ -352,19 +355,24 @@ public:


if (width <= 0 || height <= 0) if (width <= 0 || height <= 0)
{ {
qCritical("VstPlugin::setGuiData(%p) - failed to get proper window size", dialog);
qCritical("VstPlugin::setGuiContainer(%p) - failed to get proper window size", container);
return; return;
} }


gui.width = width; gui.width = width;
gui.height = height; gui.height = height;

container->setFixedSize(width, height);
qDebug("VstPlugin::setGuiContainer(%p) -> setFixedSize(%i, %i)", container, width, height);
} }
else else
qCritical("VstPlugin::setGuiData(%p) - failed to get plugin window size", dialog);
qCritical("VstPlugin::setGuiContainer(%p) - failed to get plugin window size", container);
} }
else else
{ {
// failed to open UI // failed to open UI
qWarning("VstPlugin::setGuiContainer(%p) - failed to open UI", container);

m_hints &= ~PLUGIN_HAS_GUI; m_hints &= ~PLUGIN_HAS_GUI;
x_engine->callback(CALLBACK_SHOW_GUI, m_id, -1, 0, 0.0); x_engine->callback(CALLBACK_SHOW_GUI, m_id, -1, 0, 0.0);


@@ -2008,11 +2016,9 @@ public:
break; break;


case audioMasterUpdateDisplay: case audioMasterUpdateDisplay:
Q_ASSERT(self && effect);
Q_ASSERT(effect);
if (self) if (self)
self->handleAudioMasterUpdateDisplay(); self->handleAudioMasterUpdateDisplay();
else
qWarning("VstPlugin::hostCallback::audioMasterUpdateDisplay called without valid object");
if (effect) if (effect)
effect->dispatcher(effect, effEditIdle, 0, 0, nullptr, 0.0f); effect->dispatcher(effect, effEditIdle, 0, 0, nullptr, 0.0f);
break; break;


+ 0
- 2
c++/carla-bridge/carla_bridge_client.h View File

@@ -328,8 +328,6 @@ private:
#ifdef BUILD_BRIDGE_UI #ifdef BUILD_BRIDGE_UI
char* m_filename; char* m_filename;
void* m_lib; void* m_lib;
#else
friend class CarlaPluginClient;
#endif #endif
}; };




+ 298
- 316
c++/carla-bridge/carla_bridge_plugin.cpp View File

@@ -32,22 +32,21 @@
#include <signal.h> #include <signal.h>
#endif #endif


static int qargc = 0;
static char** qargv = nullptr;

bool qcloseNow = false;
static int qargc = 0;
static char** qargv = nullptr;
static bool qCloseNow = false;


#if defined(Q_OS_UNIX) #if defined(Q_OS_UNIX)
void closeSignalHandler(int) void closeSignalHandler(int)
{ {
qcloseNow = true;
qCloseNow = true;
} }
#elif defined(Q_OS_WIN) #elif defined(Q_OS_WIN)
BOOL WINAPI closeSignalHandler(DWORD dwCtrlType) BOOL WINAPI closeSignalHandler(DWORD dwCtrlType)
{ {
if (dwCtrlType == CTRL_C_EVENT) if (dwCtrlType == CTRL_C_EVENT)
{ {
qcloseNow = true;
qCloseNow = true;
return TRUE; return TRUE;
} }


@@ -77,29 +76,273 @@ void initSignalHandler()
CARLA_BRIDGE_START_NAMESPACE CARLA_BRIDGE_START_NAMESPACE


// ------------------------------------------------------------------------- // -------------------------------------------------------------------------
// client


class CarlaPluginClient : public CarlaClient
class BridgePluginGUI : public QDialog
{
public:
class Callback
{
public:
virtual ~Callback() {}
virtual void guiClosedCallback() = 0;
};

BridgePluginGUI(QWidget* const parent, Callback* const callback_, const char* const pluginName, const bool resizable)
: QDialog(parent),
callback(callback_)
{
qDebug("BridgePluginGUI::BridgePluginGUI(%p, %p, \"%s\", %s", parent, callback, pluginName, bool2str(resizable));
Q_ASSERT(callback);
Q_ASSERT(pluginName);

m_firstShow = true;
m_resizable = resizable;

vbLayout = new QVBoxLayout(this);
vbLayout->setContentsMargins(0, 0, 0, 0);
setLayout(vbLayout);

container = new GuiContainer(this);
vbLayout->addWidget(container);

setNewSize(50, 50);
setWindowTitle(QString("%1 (GUI)").arg(pluginName));

#ifdef Q_OS_WIN
//if (! resizable)
//setWindowFlags(windowFlags() | Qt::MSWindowsFixedSizeDialogHint);
#endif
}

~BridgePluginGUI()
{
qDebug("BridgePluginGUI::~BridgePluginGUI()");
Q_ASSERT(container);
Q_ASSERT(vbLayout);

delete container;
delete vbLayout;
}

GuiContainer* getContainer()
{
return container;
}

void setNewSize(int width, int height)
{
qDebug("BridgePluginGUI::setNewSize(%i, %i)", width, height);

if (width < 30)
width = 30;
if (height < 30)
height = 30;

if (m_resizable)
{
resize(width, height);
}
else
{
setFixedSize(width, height);
container->setFixedSize(width, height);
}
}

void setVisible(const bool yesNo)
{
qDebug("BridgePluginGUI::setVisible(%s)", bool2str(yesNo));

if (yesNo)
{
if (m_firstShow)
{
m_firstShow = false;
restoreGeometry(QByteArray());
}
else if (! m_geometry.isNull())
restoreGeometry(m_geometry);
}
else
m_geometry = saveGeometry();

QDialog::setVisible(yesNo);
}

protected:
void hideEvent(QHideEvent* const event)
{
qDebug("BridgePluginGUI::hideEvent(%p)", event);

event->accept();
close();
}

void closeEvent(QCloseEvent* const event)
{
qDebug("BridgePluginGUI::closeEvent(%p)", event);

if (event->spontaneous())
callback->guiClosedCallback();

QDialog::closeEvent(event);
}

void done(int r)
{
QDialog::done(r);
close();
}

private:
Callback* const callback;

QVBoxLayout* vbLayout;
GuiContainer* container;

bool m_firstShow;
bool m_resizable;
QByteArray m_geometry;
};

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

class BridgePluginClient : public CarlaToolkit,
public CarlaClient,
public BridgePluginGUI::Callback,
public QApplication
{ {
public: public:
CarlaPluginClient(CarlaToolkit* const toolkit)
: CarlaClient(toolkit)
BridgePluginClient()
: CarlaToolkit("carla-bridge-plugin"),
CarlaClient(this),
QApplication(qargc, qargv)
{ {
engine = nullptr;
plugin = nullptr;
qDebug("BridgePluginClient::BridgePluginClient()");

msgTimer = 0;
nextWidth = 0;
nextHeight = 0;

engine = nullptr;
plugin = nullptr;
pluginGui = nullptr;

m_client = this;
} }


~CarlaPluginClient()
~BridgePluginClient()
{ {
qDebug("BridgePluginClient::~BridgePluginClient()");
Q_ASSERT(msgTimer == 0);
Q_ASSERT(! pluginGui);
} }


void setStuff(CarlaBackend::CarlaEngine* const engine_, CarlaBackend::CarlaPlugin* const plugin_)
void setStuff(CarlaBackend::CarlaEngine* const engine, CarlaBackend::CarlaPlugin* const plugin)
{ {
Q_ASSERT(engine_);
Q_ASSERT(plugin_);
qDebug("BridgePluginClient::setStuff(%p, %p)", engine, plugin);
Q_ASSERT(engine);
Q_ASSERT(plugin);


engine = engine_;
plugin = plugin_;
this->engine = engine;
this->plugin = plugin;
}

// ---------------------------------------------------------------------
// toolkit

void init()
{
qDebug("BridgePluginClient::init()");
}

void exec(CarlaClient* const, const bool showGui)
{
qDebug("BridgePluginClient::exec()");

if (showGui)
{
show();
}
else
{
CarlaClient::sendOscUpdate();
CarlaClient::sendOscBridgeUpdate();
QApplication::setQuitOnLastWindowClosed(false);
}

msgTimer = startTimer(50);

QApplication::exec();
}

void quit()
{
qDebug("BridgePluginClient::quit()");

if (msgTimer != 0)
{
QApplication::killTimer(msgTimer);
msgTimer = 0;
}

if (pluginGui)
{
if (pluginGui->isVisible())
hide();

pluginGui->close();

delete pluginGui;
pluginGui = nullptr;
}

if (! QApplication::closingDown())
QApplication::quit();
}

void show()
{
qDebug("BridgePluginClient::show()");
Q_ASSERT(pluginGui);

if (plugin)
plugin->showGui(true);

if (pluginGui)
pluginGui->show();
}

void hide()
{
qDebug("BridgePluginClient::hide()");
Q_ASSERT(pluginGui);

if (pluginGui)
pluginGui->hide();

if (plugin)
plugin->showGui(false);
}

void resize(int width, int height)
{
qDebug("BridgePluginClient::resize(%i, %i)", width, height);
Q_ASSERT(pluginGui);

if (pluginGui)
pluginGui->setNewSize(width, height);
}

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

void createWindow(const bool resizable)
{
qDebug("BridgePluginClient::createWindow(%s)", bool2str(resizable));
Q_ASSERT(plugin);

pluginGui = new BridgePluginGUI(nullptr, this, plugin->name(), resizable);
plugin->setGuiContainer(pluginGui->getContainer());
} }


// --------------------------------------------------------------------- // ---------------------------------------------------------------------
@@ -262,30 +505,6 @@ public:
#endif #endif
} }


// ---------------------------------------------------------------------
// idle

void idle()
{
Q_ASSERT(plugin);

if (! plugin)
return;

plugin->idleGui();
}

void showGui(const bool yesNo)
{
qDebug("CarlaPluginClient::showGui(%s)", bool2str(yesNo));
Q_ASSERT(plugin);

if (! plugin)
return;

plugin->showGui(yesNo);
}

// --------------------------------------------------------------------- // ---------------------------------------------------------------------
// callback // callback


@@ -330,8 +549,9 @@ public:
break; break;


case CarlaBackend::CALLBACK_RESIZE_GUI: case CarlaBackend::CALLBACK_RESIZE_GUI:
if (m_toolkit)
m_toolkit->resize(value1, value2);
Q_ASSERT(value1 > 0 && value2 > 0);
nextWidth = value1;
nextHeight = value2;
break; break;


case CarlaBackend::CALLBACK_RELOAD_PARAMETERS: case CarlaBackend::CALLBACK_RELOAD_PARAMETERS:
@@ -345,7 +565,7 @@ public:
break; break;


case CarlaBackend::CALLBACK_QUIT: case CarlaBackend::CALLBACK_QUIT:
//quequeMessage(MESSAGE_QUIT, 0, 0, 0.0);
//QApplication::quit();
break; break;


default: default:
@@ -363,289 +583,55 @@ public:
if (! ptr) if (! ptr)
return; return;


CarlaPluginClient* const client = (CarlaPluginClient*)ptr;
client->handleCallback(action, value1, value2, value3);
}

private:
CarlaBackend::CarlaEngine* engine;
CarlaBackend::CarlaPlugin* plugin;
};

// -------------------------------------------------------------------------
// toolkit

class BridgeApplication : public QApplication
{
public:
BridgeApplication()
: QApplication(qargc, qargv)
{
msgTimer = 0;
m_client = nullptr;
}

void exec(CarlaPluginClient* const client)
{
m_client = client;
msgTimer = startTimer(50);

QApplication::exec();
}

void killMsgTimer()
{
Q_ASSERT(msgTimer != 0);

killTimer(msgTimer);
msgTimer = 0;
BridgePluginClient* const _this_ = (BridgePluginClient*)ptr;
_this_->handleCallback(action, value1, value2, value3);
} }


void hideHostGUI()
protected:
void guiClosedCallback()
{ {
if (m_client)
m_client->handleCallback(CarlaBackend::CALLBACK_SHOW_GUI, 0, 0, 0.0);
} }


protected:
void timerEvent(QTimerEvent* const event) void timerEvent(QTimerEvent* const event)
{ {
if (qcloseNow)
if (qCloseNow)
return quit(); return quit();


if (event->timerId() == msgTimer) if (event->timerId() == msgTimer)
{ {
if (m_client)
if (nextWidth > 0 && nextHeight > 0 && pluginGui)
{ {
m_client->idle();

if (! m_client->runMessages())
{
msgTimer = 0;
return;
}
pluginGui->setNewSize(nextWidth, nextHeight);
nextWidth = 0;
nextHeight = 0;
} }
}

QApplication::timerEvent(event);
}


private:
int msgTimer;
CarlaPluginClient* m_client;
};

class BridgePluginGUI : public QDialog
{
public:
BridgePluginGUI(QWidget* const parent, BridgeApplication* const app, const char* const pluginName, const bool resizable)
: QDialog(parent),
m_app(app),
vbLayout(this)
{
m_firstShow = true;
m_resizable = resizable;
if (plugin)
plugin->idleGui();


vbLayout.setContentsMargins(0, 0, 0, 0);
setLayout(&vbLayout);
setNewSize(50, 50);
setWindowTitle(QString("%1 (GUI)").arg(pluginName));

#ifdef Q_OS_WIN
if (! resizable)
setWindowFlags(windowFlags() | Qt::MSWindowsFixedSizeDialogHint);
#endif
}

void setNewSize(int width, int height)
{
if (width < 30)
width = 30;
if (height < 30)
height = 30;

if (m_resizable)
resize(width, height);
else
setFixedSize(width, height);
}

void setVisible(const bool yesNo)
{
if (yesNo)
{
if (m_firstShow)
if (! CarlaClient::runMessages())
{ {
m_firstShow = false;
restoreGeometry(QByteArray());
Q_ASSERT(msgTimer == 0);
msgTimer = 0;
return;
} }
else if (! m_geometry.isNull())
restoreGeometry(m_geometry);
}
else
m_geometry = saveGeometry();

QDialog::setVisible(yesNo);
}

protected:
void hideEvent(QHideEvent* const event)
{
// FIXME
event->accept();
close();

m_app->hideHostGUI();
}

void done(int r)
{
QDialog::done(r);
close();
}

private:
BridgeApplication* const m_app;

bool m_firstShow;
bool m_resizable;

QByteArray m_geometry;
QVBoxLayout vbLayout;
};

class CarlaToolkitPlugin : public CarlaToolkit
{
public:
CarlaToolkitPlugin()
: CarlaToolkit("carla-bridge-plugin")
{
qDebug("CarlaToolkitPlugin::CarlaToolkitPlugin()");
app = nullptr;
gui = nullptr;
}

~CarlaToolkitPlugin()
{
qDebug("CarlaToolkitPlugin::~CarlaToolkitPlugin()");
Q_ASSERT(! app);
}

void init()
{
qDebug("CarlaToolkitPlugin::init()");
Q_ASSERT(! app);

app = new BridgeApplication;
}

void exec(CarlaClient* const client, const bool showGui)
{
qDebug("CarlaToolkitPlugin::exec(%p)", client);
Q_ASSERT(app);
Q_ASSERT(client);

m_client = client;

if (showGui)
{
show();
}
else
{
m_client->sendOscUpdate();
m_client->sendOscBridgeUpdate();
app->setQuitOnLastWindowClosed(false);
} }


app->exec((CarlaPluginClient*)client);
}

void quit()
{
qDebug("CarlaToolkitPlugin::quit()");
Q_ASSERT(app);

if (gui)
{
gui->close();

delete gui;
gui = nullptr;
}

if (app)
{
app->killMsgTimer();

if (! app->closingDown())
app->quit();

delete app;
app = nullptr;
}
}

void show()
{
qDebug("CarlaToolkitPlugin::show()");

if (m_client)
((CarlaPluginClient*)m_client)->showGui(true);

if (gui)
gui->show();
}

void hide()
{
qDebug("CarlaToolkitPlugin::hide()");

if (gui)
gui->hide();

if (m_client)
((CarlaPluginClient*)m_client)->showGui(false);
}

void resize(int width, int height)
{
qDebug("CarlaToolkitPlugin::resize(%i, %i)", width, height);
Q_ASSERT(gui);

if (! gui)
return;

gui->setNewSize(width, height);
QApplication::timerEvent(event);
} }


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


void createWindow(const char* const pluginName, const bool resizable)
{
qDebug("CarlaToolkitPlugin::createWindow(%s, %s)", pluginName, bool2str(resizable));
Q_ASSERT(pluginName);

gui = new BridgePluginGUI(nullptr, app, pluginName, resizable);
}

QDialog* getWindowHandle() const
{
return gui;
}
private:
int msgTimer;
int nextWidth, nextHeight;


// ---------------------------------------------------------------------
CarlaBackend::CarlaEngine* engine;
CarlaBackend::CarlaPlugin* plugin;


private:
BridgeApplication* app;
BridgePluginGUI* gui;
BridgePluginGUI* pluginGui;
}; };


CarlaToolkit* CarlaToolkit::createNew(const char* const)
{
return new CarlaToolkitPlugin;
}

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


CARLA_BRIDGE_END_NAMESPACE CARLA_BRIDGE_END_NAMESPACE
@@ -689,18 +675,15 @@ int main(int argc, char* argv[])
return 1; return 1;
} }


// Init toolkit
CarlaBridge::CarlaToolkitPlugin toolkit;
toolkit.init();

// Init client
CarlaBridge::CarlaPluginClient client(&toolkit);
// Init bridge client
CarlaBridge::BridgePluginClient client;
client.init();


// Init OSC // Init OSC
if (useOsc && ! client.oscInit(oscUrl)) if (useOsc && ! client.oscInit(oscUrl))
{ {
toolkit.quit();
return -1;
client.quit();
return -1;
} }


// Init backend engine // Init backend engine
@@ -718,7 +701,7 @@ int main(int argc, char* argv[])
{ {
qWarning("Bridge engine failed to start, error was:\n%s", CarlaBackend::getLastError()); qWarning("Bridge engine failed to start, error was:\n%s", CarlaBackend::getLastError());
engine.close(); engine.close();
toolkit.quit();
client.quit();
return 2; return 2;
} }


@@ -738,8 +721,7 @@ int main(int argc, char* argv[])


if (guiType == CarlaBackend::GUI_INTERNAL_QT4 || guiType == CarlaBackend::GUI_INTERNAL_COCOA || guiType == CarlaBackend::GUI_INTERNAL_HWND || guiType == CarlaBackend::GUI_INTERNAL_X11) if (guiType == CarlaBackend::GUI_INTERNAL_QT4 || guiType == CarlaBackend::GUI_INTERNAL_COCOA || guiType == CarlaBackend::GUI_INTERNAL_HWND || guiType == CarlaBackend::GUI_INTERNAL_X11)
{ {
toolkit.createWindow(plugin->name(), guiResizable);
plugin->setGuiData(toolkit.getWindowHandle());
client.createWindow(guiResizable);
} }


if (! useOsc) if (! useOsc)
@@ -756,7 +738,7 @@ int main(int argc, char* argv[])
if (ret == 0) if (ret == 0)
{ {
initSignalHandler(); initSignalHandler();
toolkit.exec(&client, !useOsc);
client.exec(nullptr, !useOsc);
} }


engine.removeAllPlugins(); engine.removeAllPlugins();
@@ -767,12 +749,12 @@ int main(int argc, char* argv[])
// Close OSC // Close OSC
client.sendOscExiting(); client.sendOscExiting();
client.oscClose(); client.oscClose();
// toolkit can't be closed manually, only by host
// bridge client can't be closed manually, only by host
} }
else else
{ {
// Close toolkit
toolkit.quit();
// Close bridge client
client.quit();
} }


return ret; return ret;


+ 2
- 0
c++/carla-bridge/carla_bridge_toolkit.h View File

@@ -57,7 +57,9 @@ public:
virtual void hide() = 0; virtual void hide() = 0;
virtual void resize(int width, int height) = 0; virtual void resize(int width, int height) = 0;


#if BUILD_BRIDGE_UI
static CarlaToolkit* createNew(const char* const title); static CarlaToolkit* createNew(const char* const title);
#endif


protected: protected:
char* m_title; char* m_title;


+ 4
- 4
src/carla_backend.py View File

@@ -878,8 +878,8 @@ class Host(object):
self.lib.set_chunk_data.argtypes = [c_ushort, c_char_p] self.lib.set_chunk_data.argtypes = [c_ushort, c_char_p]
self.lib.set_chunk_data.restype = None self.lib.set_chunk_data.restype = None


self.lib.set_gui_data.argtypes = [c_ushort, c_uintptr]
self.lib.set_gui_data.restype = None
self.lib.set_gui_container.argtypes = [c_ushort, c_uintptr]
self.lib.set_gui_container.restype = None


self.lib.show_gui.argtypes = [c_ushort, c_bool] self.lib.show_gui.argtypes = [c_ushort, c_bool]
self.lib.show_gui.restype = None self.lib.show_gui.restype = None
@@ -1055,8 +1055,8 @@ class Host(object):
def set_chunk_data(self, plugin_id, chunk_data): def set_chunk_data(self, plugin_id, chunk_data):
self.lib.set_chunk_data(plugin_id, chunk_data.encode("utf-8")) self.lib.set_chunk_data(plugin_id, chunk_data.encode("utf-8"))


def set_gui_data(self, plugin_id, gui_addr):
self.lib.set_gui_data(plugin_id, gui_addr)
def set_gui_container(self, plugin_id, gui_addr):
self.lib.set_gui_container(plugin_id, gui_addr)


def show_gui(self, plugin_id, yesno): def show_gui(self, plugin_id, yesno):
self.lib.show_gui(plugin_id, yesno) self.lib.show_gui(plugin_id, yesno)


+ 21
- 8
src/shared_carla.py View File

@@ -24,6 +24,12 @@ from PyQt4.QtCore import pyqtSlot, Qt, QSettings, QTimer
from PyQt4.QtGui import QColor, QCursor, QDialog, QFontMetrics, QFrame, QInputDialog, QMenu, QPainter, QVBoxLayout, QWidget from PyQt4.QtGui import QColor, QCursor, QDialog, QFontMetrics, QFrame, QInputDialog, QMenu, QPainter, QVBoxLayout, QWidget
from PyQt4.QtXml import QDomDocument from PyQt4.QtXml import QDomDocument


try:
from PyQt4.QtGui import QX11EmbedContainer
GuiContainer = QX11EmbedContainer
except:
GuiContainer = QWidget

# Imports (Custom) # Imports (Custom)
import ui_carla_edit, ui_carla_parameter, ui_carla_plugin import ui_carla_edit, ui_carla_parameter, ui_carla_plugin
from shared import * from shared import *
@@ -1278,7 +1284,7 @@ class PluginWidget(QFrame, ui_carla_plugin.Ui_PluginWidget):
self.gui_dialog = PluginGUI(self, self.m_pluginInfo['name'], guiInfo['resizable']) self.gui_dialog = PluginGUI(self, self.m_pluginInfo['name'], guiInfo['resizable'])
self.gui_dialog.hide() self.gui_dialog.hide()


Carla.Host.set_gui_data(self.m_pluginId, unwrapinstance(self.gui_dialog))
Carla.Host.set_gui_container(self.m_pluginId, unwrapinstance(self.gui_dialog.getContainer()))


elif guiType in (GUI_EXTERNAL_LV2, GUI_EXTERNAL_SUIL, GUI_EXTERNAL_OSC): elif guiType in (GUI_EXTERNAL_LV2, GUI_EXTERNAL_SUIL, GUI_EXTERNAL_OSC):
pass pass
@@ -1988,19 +1994,24 @@ class PluginGUI(QDialog):
QDialog.__init__(self, parent) QDialog.__init__(self, parent)


self.m_firstShow = True self.m_firstShow = True
self.m_geometry = None
self.m_resizable = resizable self.m_resizable = resizable
self.m_geometry = None


self.vbLayout = QVBoxLayout(self) self.vbLayout = QVBoxLayout(self)
self.vbLayout.setContentsMargins(0, 0, 0, 0) self.vbLayout.setContentsMargins(0, 0, 0, 0)
self.setLayout(self.vbLayout) self.setLayout(self.vbLayout)

self.container = GuiContainer(self)
self.vbLayout.addWidget(self.container)

self.setNewSize(50, 50) self.setNewSize(50, 50)
self.setWindowTitle("%s (GUI)" % pluginName) self.setWindowTitle("%s (GUI)" % pluginName)


if WINDOWS and not resizable: if WINDOWS and not resizable:
self.setWindowFlags(self.windowFlags() | Qt.MSWindowsFixedSizeDialogHint) self.setWindowFlags(self.windowFlags() | Qt.MSWindowsFixedSizeDialogHint)


self.connect(self, SIGNAL("finished(int)"), SLOT("slot_finished()"))
def getContainer(self):
return self.container


def setNewSize(self, width, height): def setNewSize(self, width, height):
if width < 30: if width < 30:
@@ -2012,6 +2023,7 @@ class PluginGUI(QDialog):
self.resize(width, height) self.resize(width, height)
else: else:
self.setFixedSize(width, height) self.setFixedSize(width, height)
self.container.setFixedSize(width, height)


def setVisible(self, yesNo): def setVisible(self, yesNo):
if yesNo: if yesNo:
@@ -2025,15 +2037,16 @@ class PluginGUI(QDialog):


QDialog.setVisible(self, yesNo) QDialog.setVisible(self, yesNo)


@pyqtSlot()
def slot_finished(self):
self.parent().b_gui.setChecked(False)

def hideEvent(self, event): def hideEvent(self, event):
# FIXME
event.accept() event.accept()
self.close() self.close()


def closeEvent(self, event):
if event.spontaneous():
self.parent().b_gui.setChecked(False)

QDialog.closeEvent(self, event)

def done(self, r): def done(self, r):
QDialog.done(self, r) QDialog.done(self, r)
self.close() self.close()

Loading…
Cancel
Save