Browse Source

More VST work, custom UIs now working

tags/1.9.4
falkTX 11 years ago
parent
commit
03fc8247c2
5 changed files with 134 additions and 254 deletions
  1. +16
    -104
      source/backend/plugin/CarlaPlugin.cpp
  2. +32
    -101
      source/backend/plugin/CarlaPluginInternal.hpp
  3. +81
    -48
      source/backend/plugin/VstPlugin.cpp
  4. +1
    -1
      source/carla.py
  5. +4
    -0
      source/utils/CarlaVstUtils.hpp

+ 16
- 104
source/backend/plugin/CarlaPlugin.cpp View File

@@ -21,8 +21,7 @@


#include <QtCore/QFile> #include <QtCore/QFile>
#include <QtCore/QTextStream> #include <QtCore/QTextStream>

//#include <QtGui/QtEvents>
#include <QtGui/QCloseEvent>


CARLA_BACKEND_START_NAMESPACE CARLA_BACKEND_START_NAMESPACE


@@ -1972,24 +1971,16 @@ CarlaPlugin::ScopedProcessLocker::~ScopedProcessLocker()
// ------------------------------------------------------------------- // -------------------------------------------------------------------
// CarlaPluginGUI // CarlaPluginGUI


#if 0
CarlaPluginGUI::CarlaPluginGUI(QWidget* const parent, Callback* const callback) CarlaPluginGUI::CarlaPluginGUI(QWidget* const parent, Callback* const callback)
: QMainWindow(parent), : QMainWindow(parent),
kCallback(callback)
kCallback(callback),
fContainer(this)
{ {
carla_debug("CarlaPluginGUI::CarlaPluginGUI(%p)", parent);
//CARLA_ASSERT(callback);

//m_container = new GuiContainer(this);
//setCentralWidget(m_container);
//adjustSize();

//m_container->setParent(this);
//m_container->show();

//m_resizable = true;
carla_debug("CarlaPluginGUI::CarlaPluginGUI(%p, %p)", parent, callback);
CARLA_ASSERT(callback != nullptr);


//setNewSize(50, 50);
setCentralWidget(&fContainer);
adjustSize();


QMainWindow::setVisible(false); QMainWindow::setVisible(false);
} }
@@ -1997,109 +1988,30 @@ CarlaPluginGUI::CarlaPluginGUI(QWidget* const parent, Callback* const callback)
CarlaPluginGUI::~CarlaPluginGUI() CarlaPluginGUI::~CarlaPluginGUI()
{ {
carla_debug("CarlaPluginGUI::~CarlaPluginGUI()"); carla_debug("CarlaPluginGUI::~CarlaPluginGUI()");
//CARLA_ASSERT(m_container);

// FIXME, automatically deleted by parent ?
//delete m_container;
}
#endif

#if 0

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

GuiContainer* CarlaPluginGUI::getContainer() const
{
return m_container;
} }


WId CarlaPluginGUI::getWinId() const WId CarlaPluginGUI::getWinId() const
{ {
return m_container->winId();
}

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

void CarlaPluginGUI::setNewSize(int width, int height)
{
carla_debug("CarlaPluginGUI::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);
m_container->setFixedSize(width, height);
}
}

void CarlaPluginGUI::setResizable(bool resizable)
{
m_resizable = resizable;
setNewSize(width(), height());

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

void CarlaPluginGUI::setTitle(const char* const title)
{
CARLA_ASSERT(title);
setWindowTitle(QString("%1 (GUI)").arg(title));
}

void CarlaPluginGUI::setVisible(const bool yesNo)
{
carla_debug("CarlaPluginGUI::setVisible(%s)", bool2str(yesNo));

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

QMainWindow::setVisible(yesNo);
}

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

void CarlaPluginGUI::hideEvent(QHideEvent* const event)
{
carla_debug("CarlaPluginGUI::hideEvent(%p)", event);
CARLA_ASSERT(event);

event->accept();
close();
carla_debug("CarlaPluginGUI::getWinId()");
return fContainer.winId();
} }


void CarlaPluginGUI::closeEvent(QCloseEvent* const event) void CarlaPluginGUI::closeEvent(QCloseEvent* const event)
{ {
carla_debug("CarlaPluginGUI::closeEvent(%p)", event); carla_debug("CarlaPluginGUI::closeEvent(%p)", event);
CARLA_ASSERT(event);
CARLA_ASSERT(event != nullptr);


if (event->spontaneous())
if (! event->spontaneous())
{ {
if (m_callback)
m_callback->guiClosedCallback();

QMainWindow::closeEvent(event);
event->ignore();
return; return;
} }


event->ignore();
if (kCallback != nullptr)
kCallback->guiClosedCallback();

QMainWindow::closeEvent(event);
} }
#endif


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




+ 32
- 101
source/backend/plugin/CarlaPluginInternal.hpp View File

@@ -31,6 +31,14 @@


#include <QtGui/QMainWindow> #include <QtGui/QMainWindow>


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

#define CARLA_DECLARE_NON_COPY_STRUCT(structName) \ #define CARLA_DECLARE_NON_COPY_STRUCT(structName) \
structName(structName&) = delete; \ structName(structName&) = delete; \
structName(const structName&) = delete; structName(const structName&) = delete;
@@ -400,8 +408,14 @@ public:
CarlaPluginGUI(QWidget* const parent, Callback* const callback); CarlaPluginGUI(QWidget* const parent, Callback* const callback);
~CarlaPluginGUI(); ~CarlaPluginGUI();


WId getWinId() const;

protected:
void closeEvent(QCloseEvent* const event);

private: private:
Callback* const kCallback; Callback* const kCallback;
GuiContainer fContainer;


CARLA_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR(CarlaPluginGUI) CARLA_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR(CarlaPluginGUI)
}; };
@@ -559,6 +573,24 @@ struct CarlaPluginProtectedData {
CarlaPluginProtectedData(CarlaPluginProtectedData&) = delete; CarlaPluginProtectedData(CarlaPluginProtectedData&) = delete;
CarlaPluginProtectedData(const CarlaPluginProtectedData&) = delete; CarlaPluginProtectedData(const CarlaPluginProtectedData&) = delete;


void createUiIfNeeded(CarlaPluginGUI::Callback* const callback)
{
if (gui != nullptr)
return;

gui = new CarlaPluginGUI(nullptr, callback);
}

void destroyUiIfNeeded()
{
if (gui == nullptr)
return;

gui->close();
delete gui;
gui = nullptr;
}

static CarlaEngine* getEngine(CarlaPlugin* const plugin) static CarlaEngine* getEngine(CarlaPlugin* const plugin)
{ {
return plugin->kData->engine; return plugin->kData->engine;
@@ -587,104 +619,3 @@ struct CarlaPluginProtectedData {
CARLA_BACKEND_END_NAMESPACE CARLA_BACKEND_END_NAMESPACE


#endif // __CARLA_PLUGIN_INTERNAL_HPP__ #endif // __CARLA_PLUGIN_INTERNAL_HPP__

// common includes
//#include <cmath>
//#include <vector>
//#include <QtCore/QMutex>
//#include <QtGui/QMainWindow>

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

#if 0

/*!
* \class CarlaPluginGUI
*
* \brief Carla Backend gui plugin class
*
* \see CarlaPlugin
*/
class CarlaPluginGUI : public QMainWindow
{
public:
/*!
* \class Callback
*
* \brief Carla plugin GUI callback
*/
class Callback
{
public:
virtual ~Callback() {}
virtual void guiClosedCallback() = 0;
};

// -------------------------------------------------------------------
// Constructor and destructor

/*!
* TODO
*/
CarlaPluginGUI(QWidget* const parent, Callback* const callback);

/*!
* TODO
*/
~CarlaPluginGUI();

// -------------------------------------------------------------------
// Get data

/*!
* TODO
*/
GuiContainer* getContainer() const;

/*!
* TODO
*/
WId getWinId() const;

// -------------------------------------------------------------------
// Set data

/*!
* TODO
*/
void setNewSize(const int width, const int height);

/*!
* TODO
*/
void setResizable(const bool resizable);

/*!
* TODO
*/
void setTitle(const char* const title);

/*!
* TODO
*/
void setVisible(const bool yesNo);

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

private:
Callback* const m_callback;
GuiContainer* m_container;

QByteArray m_geometry;
bool m_resizable;

void hideEvent(QHideEvent* const event);
void closeEvent(QCloseEvent* const event);
};
#endif

+ 81
- 48
source/backend/plugin/VstPlugin.cpp View File

@@ -37,7 +37,8 @@ const unsigned int PLUGIN_USES_OLD_VSTSDK = 0x4000; //!< VST Plugin uses a
const unsigned int PLUGIN_WANTS_MIDI_INPUT = 0x8000; //!< VST Plugin wants MIDI input const unsigned int PLUGIN_WANTS_MIDI_INPUT = 0x8000; //!< VST Plugin wants MIDI input
/**@}*/ /**@}*/


class VstPlugin : public CarlaPlugin
class VstPlugin : public CarlaPlugin,
public CarlaPluginGUI::Callback
{ {
public: public:
VstPlugin(CarlaEngine* const engine, const unsigned short id) VstPlugin(CarlaEngine* const engine, const unsigned short id)
@@ -332,39 +333,9 @@ public:


void setGuiContainer(GuiContainer* const container) void setGuiContainer(GuiContainer* const container)
{ {
carla_debug("VstPlugin::setGuiContainer(%p)", container);
CARLA_ASSERT(container);

if (gui.type == GUI_EXTERNAL_OSC)
return;

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

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

// get UI size before opening UI, plugin may refuse this
effect->dispatcher(effect, effEditGetRect, 0, 0, &vstRect, 0.0f);

if (vstRect)
{
int width = vstRect->right - vstRect->left;
int height = vstRect->bottom - vstRect->top;

if (width > 0 || height > 0)
{
container->setFixedSize(width, height);
#ifdef BUILD_BRIDGE
x_engine->callback(CALLBACK_RESIZE_GUI, m_id, width, height, 1.0, nullptr);
#endif
}
}


// open UI // open UI
if (effect->dispatcher(effect, effEditOpen, 0, value, ptr, 0.0f) == 1)

{ {
// get UI size again, can't fail now // get UI size again, can't fail now
vstRect = nullptr; vstRect = nullptr;
@@ -398,7 +369,7 @@ public:
m_hints &= ~PLUGIN_HAS_GUI; m_hints &= ~PLUGIN_HAS_GUI;
x_engine->callback(CALLBACK_SHOW_GUI, m_id, -1, 0, 0.0, nullptr); x_engine->callback(CALLBACK_SHOW_GUI, m_id, -1, 0, 0.0, nullptr);


effect->dispatcher(effect, effEditClose, 0, 0, nullptr, 0.0f);
} }
} }
#endif #endif
@@ -426,8 +397,49 @@ public:
} }
else else
{ {
if (yesNo && fGui.width > 0 && fGui.height > 0 && kData->gui != nullptr)
kData->gui->setFixedSize(fGui.width, fGui.height);
if (yesNo)
{
kData->createUiIfNeeded(this);

int32_t value = 0;
#ifdef Q_WS_X11
//value = (intptr_t)QX11Info::display();
#endif
void* const ptr = (void*)kData->gui->getWinId();

if (dispatcher(effEditOpen, 0, value, ptr, 0.0f) == 1)
{
ERect* vstRect = nullptr;

dispatcher(effEditGetRect, 0, 0, &vstRect, 0.0f);

if (vstRect != nullptr)
{
const int16_t width = vstRect->right - vstRect->left;
const int16_t height = vstRect->bottom - vstRect->top;

if (width > 0 && height > 0)
{
kData->gui->setFixedSize(width, height);
}
}

kData->gui->setWindowTitle(QString("%1 (GUI)").arg((const char*)fName));
kData->gui->show();
}
else
{
kData->destroyUiIfNeeded();
kData->engine->callback(CALLBACK_ERROR, fId, 0, 0, 0.0f, "Plugin refused to open its own UI");
kData->engine->callback(CALLBACK_SHOW_GUI, fId, 0, 0, 0.0f, nullptr);
return;
}
}
else if (fGui.isVisible)
{
dispatcher(effEditClose, 0, 0, nullptr, 0.0f);
kData->destroyUiIfNeeded();
}
} }


fGui.isVisible = yesNo; fGui.isVisible = yesNo;
@@ -1601,9 +1613,18 @@ public:
// ------------------------------------------------------------------- // -------------------------------------------------------------------


protected: protected:
void guiClosedCallback()
{
showGui(false);
kData->engine->callback(CALLBACK_SHOW_GUI, fId, 0, 0, 0.0f, nullptr);
}

intptr_t dispatcher(int32_t opcode, int32_t index, intptr_t value, void* ptr, float opt) intptr_t dispatcher(int32_t opcode, int32_t index, intptr_t value, void* ptr, float opt)
{ {
carla_debug("VstPlugin::dispatcher(%02i:%s, %i, " P_INTPTR ", %p, %f)", opcode, vstEffectOpcode2str(opcode), index, value, ptr, opt);
#if defined(DEBUG) && ! defined(CARLA_OS_WIN)
if (opcode != effEditIdle && opcode != effProcessEvents)
carla_debug("VstPlugin::dispatcher(%02i:%s, %i, " P_INTPTR ", %p, %f)", opcode, vstEffectOpcode2str(opcode), index, value, ptr, opt);
#endif
CARLA_ASSERT(fEffect != nullptr); CARLA_ASSERT(fEffect != nullptr);


return (fEffect != nullptr) ? fEffect->dispatcher(fEffect, opcode, index, value, ptr, opt) : 0; return (fEffect != nullptr) ? fEffect->dispatcher(fEffect, opcode, index, value, ptr, opt) : 0;
@@ -1649,21 +1670,38 @@ protected:
switch (opcode) switch (opcode)
{ {
case audioMasterAutomate: case audioMasterAutomate:
CARLA_ASSERT(fEnabled);
CARLA_ASSERT_INT(index < static_cast<int32_t>(kData->param.count), index); CARLA_ASSERT_INT(index < static_cast<int32_t>(kData->param.count), index);
CARLA_SAFE_ASSERT(fEnabled); // plugins should never do this!


if (index < 0 || index >= static_cast<int32_t>(kData->param.count) || ! fEnabled) if (index < 0 || index >= static_cast<int32_t>(kData->param.count) || ! fEnabled)
break; break;


if (fIsProcessing && ! kData->engine->isOffline())
if (fIsProcessing)
{ {
// Called from engine
if (kData->engine->isOffline())
{
setParameterValue(index, opt, true, true, true);
}
else
{
setParameterValue(index, opt, false, false, false);
postponeRtEvent(kPluginPostRtEventParameterChange, index, 0, opt);
}
}
else if (! kData->active)
{
// On init?
setParameterValue(index, opt, false, false, false); setParameterValue(index, opt, false, false, false);
postponeRtEvent(kPluginPostRtEventParameterChange, index, 0, opt);
}
else if (fGui.isVisible)
{
// Called from GUI
setParameterValue(index, opt, false, true, true);
} }
else else
{ {
CARLA_ASSERT(fGui.isVisible); // FIXME - remove when offline is implemented
setParameterValue(index, opt, fIsProcessing, true, true);
carla_stdout("audioMasterAutomate called from unknown source");
} }
break; break;


@@ -1802,8 +1840,7 @@ protected:
break; break;


case audioMasterSizeWindow: case audioMasterSizeWindow:
fGui.width = index;
fGui.height = value;
CARLA_ASSERT(kData->gui != nullptr);


// FIXME - ensure thread safe // FIXME - ensure thread safe
if (kData->gui != nullptr) if (kData->gui != nullptr)
@@ -2125,14 +2162,10 @@ private:
struct GuiInfo { struct GuiInfo {
bool isOsc; bool isOsc;
bool isVisible; bool isVisible;
int width;
int height;


GuiInfo() GuiInfo()
: isOsc(false), : isOsc(false),
isVisible(false),
width(0),
height(0) {}
isVisible(false) {}
} fGui; } fGui;


bool fIsProcessing; bool fIsProcessing;


+ 1
- 1
source/carla.py View File

@@ -1541,7 +1541,7 @@ def engineCallback(ptr, action, pluginId, value1, value2, value3, valueStr):
#elif action == CALLBACK_NSM_SAVE: #elif action == CALLBACK_NSM_SAVE:
#Carla.gui.emit(SIGNAL("NSM_SaveCallback()")) #Carla.gui.emit(SIGNAL("NSM_SaveCallback()"))
elif action == CALLBACK_ERROR: elif action == CALLBACK_ERROR:
Carla.gui.emit(SIGNAL("ErrorCallback(QString)"), valueStr)
Carla.gui.emit(SIGNAL("ErrorCallback(QString)"), cString(valueStr))
elif action == CALLBACK_QUIT: elif action == CALLBACK_QUIT:
Carla.gui.emit(SIGNAL("QuitCallback()")) Carla.gui.emit(SIGNAL("QuitCallback()"))




+ 4
- 0
source/utils/CarlaVstUtils.hpp View File

@@ -182,6 +182,10 @@ const char* vstEffectOpcode2str(const int32_t opcode)
return "effEditMouse"; return "effEditMouse";
case effEditKey: case effEditKey:
return "effEditKey"; return "effEditKey";
#endif
case effEditIdle:
return "effEditIdle";
#if ! VST_FORCE_DEPRECATED
case effEditTop: case effEditTop:
return "effEditTop"; return "effEditTop";
case effEditSleep: case effEditSleep:


Loading…
Cancel
Save