Skip to content

Commit

Permalink
Merge pull request LMMS#3991 from PhysSong/fix/qt5-vst
Browse files Browse the repository at this point in the history
Some fixes/enhancements for LMMS#3786
  • Loading branch information
lukas-w authored Nov 24, 2017
2 parents 09058c1 + 8c3c8ce commit 966ae27
Show file tree
Hide file tree
Showing 9 changed files with 110 additions and 45 deletions.
1 change: 1 addition & 0 deletions .travis.yml
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ matrix:
- env: TARGET_OS=win64
- os: osx
osx_image: xcode8.2
- env: QT5=
- env: QT5=True
- env: QT5=True TARGET_OS=win32
- env: QT5=True TARGET_OS=win64
Expand Down
1 change: 1 addition & 0 deletions include/ConfigManager.h
Original file line number Diff line number Diff line change
Expand Up @@ -210,6 +210,7 @@ class EXPORT ConfigManager : public QObject
return m_recentlyOpenedProjects;
}

static QStringList availabeVstEmbedMethods();
QString vstEmbedMethod() const;

// returns true if the working dir (e.g. ~/lmms) exists on disk
Expand Down
11 changes: 11 additions & 0 deletions plugins/VstEffect/VstEffect.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -128,10 +128,21 @@ void VstEffect::openPlugin( const QString & _plugin )
PLUGIN_NAME::getIconPixmap( "logo", 24, 24 ), 0 );

QMutexLocker ml( &m_pluginMutex ); Q_UNUSED( ml );
#if QT_VERSION > 0x050000
m_plugin.reset(new VstPlugin( _plugin ));
#else
{
QSharedPointer<VstPlugin> newPlugin(new VstPlugin( _plugin ));
std::swap(m_plugin, newPlugin);
}
#endif
if( m_plugin->failed() )
{
#if QT_VERSION > 0x050000
m_plugin.reset(nullptr);
#else
m_plugin.clear();
#endif
delete tf;
collectErrorForUI( VstPlugin::tr( "The VST plugin %1 could not be loaded." ).arg( _plugin ) );
return;
Expand Down
2 changes: 1 addition & 1 deletion plugins/vst_base/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ SET(REMOTE_VST_PLUGIN_FILEPATH "RemoteVstPlugin" CACHE STRING "Relative file pat
ADD_DEFINITIONS(-DREMOTE_VST_PLUGIN_FILEPATH="${REMOTE_VST_PLUGIN_FILEPATH}")
BUILD_PLUGIN(vstbase vst_base.cpp VstPlugin.cpp VstPlugin.h communication.h MOCFILES VstPlugin.h)

IF(LMMS_BUILD_LINUX)
IF(LMMS_BUILD_LINUX AND WANT_QT5)
TARGET_LINK_LIBRARIES(vstbase qx11embedcontainer)
ENDIF()

Expand Down
37 changes: 16 additions & 21 deletions plugins/vst_base/RemoteVstPlugin.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -109,6 +109,7 @@ static VstHostLanguages hlang = LanguageEnglish;

static bool EMBED = false;
static bool EMBED_X11 = false;
static bool EMBED_WIN32 = false;

class RemoteVstPlugin;

Expand Down Expand Up @@ -567,17 +568,6 @@ bool RemoteVstPlugin::processMessage( const message & _m )
init( _m.getString() );
break;

// TODO: Drop Windows hack for Qt 4
#ifdef LMMS_BUILD_WIN32
case IdVstPluginWindowInformation:
{
HWND top = FindWindowEx( NULL, NULL, NULL,
_m.getString().c_str() );
m_window = FindWindowEx( top, NULL, NULL, NULL );
break;
}
#endif

case IdVstSetTempo:
setBPM( _m.getInt() );
break;
Expand Down Expand Up @@ -1977,13 +1967,6 @@ DWORD WINAPI RemoteVstPlugin::guiEventLoop()
while( GetMessage( &msg, NULL, 0, 0 ) > 0 )
{
TranslateMessage( &msg );

if( msg.message == WM_SYSCOMMAND && msg.wParam == SC_CLOSE )
{
__plugin->destroyEditor();
continue;
}

DispatchMessage( &msg );
}

Expand Down Expand Up @@ -2030,6 +2013,12 @@ LRESULT CALLBACK RemoteVstPlugin::messageWndProc( HWND hwnd, UINT uMsg,
break;
}
}
else if( uMsg == WM_SYSCOMMAND && wParam == SC_CLOSE )
{
__plugin->destroyEditor();
return 0;
}

return DefWindowProc( hwnd, uMsg, wParam, lParam );
}

Expand Down Expand Up @@ -2084,21 +2073,27 @@ int main( int _argc, char * * _argv )
if ( embedMethod == "none" )
{
cerr << "Starting detached." << endl;
EMBED = EMBED_X11 = false;
EMBED = EMBED_X11 = EMBED_WIN32 = false;
}
else if ( embedMethod == "win32" )
{
cerr << "Starting using Win32-native embedding." << endl;
EMBED = EMBED_WIN32 = true; EMBED_X11= false;
}
else if ( embedMethod == "qt" )
{
cerr << "Starting using Qt-native embedding." << endl;
EMBED = true; EMBED_X11 = false;
EMBED = true; EMBED_X11 = EMBED_WIN32 = false;
}
else if ( embedMethod == "xembed" )
{
cerr << "Starting using X11Embed protocol." << endl;
EMBED = true; EMBED_X11 = true;
EMBED = EMBED_X11 = true; EMBED_WIN32 = false;
}
else
{
cerr << "Unknown embed method " << embedMethod << ". Starting detached instead." << endl;
EMBED = EMBED_X11 = EMBED_WIN32 = false;
}
}

Expand Down
42 changes: 38 additions & 4 deletions plugins/vst_base/VstPlugin.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,7 @@

#ifdef LMMS_BUILD_WIN32
# include <windows.h>
# include <QLayout>
#endif

#include "ConfigManager.h"
Expand Down Expand Up @@ -659,6 +660,7 @@ void VstPlugin::createUI( QWidget * parent, bool isEffect )
m_pluginSubWindow = new vstSubWin( gui->mainWindow()->workspace() );
auto sw = m_pluginSubWindow.data();

#if QT_VERSION >= 0x050100
if (m_embedMethod == "qt" )
{
QWindow* vw = QWindow::fromWinId(m_pluginWindowID);
Expand All @@ -667,17 +669,49 @@ void VstPlugin::createUI( QWidget * parent, bool isEffect )
// TODO: Synchronize show
// Tell remote that it is embedded
// Wait for remote reply
}
} else
#endif

#ifdef LMMS_BUILD_WIN32
if (m_embedMethod == "win32" )
{
QWidget * helper = new QWidget;
QHBoxLayout * l = new QHBoxLayout( helper );
QWidget * target = new QWidget( helper );
l->setSpacing( 0 );
l->setMargin( 0 );
l->addWidget( target );

// we've to call that for making sure, Qt created the windows
helper->winId();
HWND targetHandle = (HWND)target->winId();
HWND pluginHandle = (HWND)(intptr_t)m_pluginWindowID;

DWORD style = GetWindowLong(pluginHandle, GWL_STYLE);
style = style & ~(WS_POPUP);
style = style | WS_CHILD;
SetWindowLong(pluginHandle, GWL_STYLE, style);
SetParent(pluginHandle, targetHandle);

DWORD threadId = GetWindowThreadProcessId(pluginHandle, NULL);
DWORD currentThreadId = GetCurrentThreadId();
AttachThreadInput(currentThreadId, threadId, true);

container = helper;
RemotePlugin::showUI();

} else
#endif

#ifdef LMMS_BUILD_LINUX
else if (m_embedMethod == "xembed" )
if (m_embedMethod == "xembed" )
{
QX11EmbedContainer * embedContainer = new QX11EmbedContainer( sw );
connect(embedContainer, SIGNAL(clientIsEmbedded()), this, SLOT(handleClientEmbed()));
embedContainer->embedClient( m_pluginWindowID );
container = embedContainer;
}
} else
#endif
else
{
qCritical() << "Unknown embed method" << m_embedMethod;
delete m_pluginSubWindow;
Expand Down
2 changes: 0 additions & 2 deletions plugins/vst_base/communication.h
Original file line number Diff line number Diff line change
Expand Up @@ -57,8 +57,6 @@ enum VstRemoteMessageIDs
{
// vstPlugin -> remoteVstPlugin
IdVstLoadPlugin = IdUserBase,
// TODO: Drop IdVstPluginWindowInformation, Windows hack for Qt 4
IdVstPluginWindowInformation,
IdVstClosePlugin,
IdVstSetTempo,
IdVstSetLanguage,
Expand Down
35 changes: 26 additions & 9 deletions src/core/ConfigManager.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -35,10 +35,6 @@

#include "lmmsversion.h"

#ifdef LMMS_BUILD_LINUX
#include <QtX11Extras/QX11Info>
#endif

static inline QString ensureTrailingSlash( const QString & s )
{
if( ! s.isEmpty() && !s.endsWith('/') && !s.endsWith('\\') )
Expand Down Expand Up @@ -190,16 +186,37 @@ QString ConfigManager::defaultVersion() const
return LMMS_VERSION;
}

QString ConfigManager::vstEmbedMethod() const
QStringList ConfigManager::availabeVstEmbedMethods()
{
QString defaultMethod = "qt";
QStringList methods;
methods.append("none");
#if QT_VERSION >= 0x050100
methods.append("qt");
#endif
#ifdef LMMS_BUILD_WIN32
methods.append("win32");
#endif
#ifdef LMMS_BUILD_LINUX
if (QX11Info::isPlatformX11()) {
defaultMethod = "xembed";
#if QT_VERSION >= 0x050000
if (static_cast<QGuiApplication*>(QApplication::instance())->
platformName() == "xcb")
#else
if (qgetenv("QT_QPA_PLATFORM").isNull()
|| qgetenv("QT_QPA_PLATFORM") == "xcb")
#endif
{
methods.append("xembed");
}
#endif
return methods;
}

return value( "ui", "vstembedmethod", defaultMethod );
QString ConfigManager::vstEmbedMethod() const
{
QStringList methods = availabeVstEmbedMethods();
QString defaultMethod = *(methods.end() - 1);
QString currentMethod = value( "ui", "vstembedmethod", defaultMethod );
return methods.contains(currentMethod) ? currentMethod : defaultMethod;
}

bool ConfigManager::hasWorkingDir() const
Expand Down
24 changes: 16 additions & 8 deletions src/gui/SetupDialog.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -67,10 +67,6 @@
#include "MidiApple.h"
#include "MidiDummy.h"

#ifdef LMMS_BUILD_LINUX
#include <QtX11Extras/QX11Info>
#endif

inline void labelWidget( QWidget * _w, const QString & _txt )
{
QLabel * title = new QLabel( _txt, _w );
Expand Down Expand Up @@ -342,13 +338,21 @@ SetupDialog::SetupDialog( ConfigTabs _tab_to_open ) :
embed_tw->setFixedHeight( 48 );
m_vstEmbedComboBox = new QComboBox( embed_tw );
m_vstEmbedComboBox->move( XDelta, YDelta );

QStringList embedMethods = ConfigManager::availabeVstEmbedMethods();
m_vstEmbedComboBox->addItem( tr( "No embedding" ), "none" );
m_vstEmbedComboBox->addItem( tr( "Embed using Qt API" ), "qt" );
#ifdef LMMS_BUILD_LINUX
if ( QX11Info::isPlatformX11() ) {
if( embedMethods.contains("qt") )
{
m_vstEmbedComboBox->addItem( tr( "Embed using Qt API" ), "qt" );
}
if( embedMethods.contains("win32") )
{
m_vstEmbedComboBox->addItem( tr( "Embed using native Win32 API" ), "win32" );
}
if( embedMethods.contains("xembed") )
{
m_vstEmbedComboBox->addItem( tr( "Embed using XEmbed protocol" ), "xembed" );
}
#endif
m_vstEmbedComboBox->setCurrentIndex( m_vstEmbedComboBox->findData( m_vstEmbedMethod ) );

TabWidget * lang_tw = new TabWidget( tr( "LANGUAGE" ), general );
Expand Down Expand Up @@ -1077,7 +1081,11 @@ void SetupDialog::accept()
QString::number( m_disableAutoQuit ) );
ConfigManager::inst()->setValue( "app", "language", m_lang );
ConfigManager::inst()->setValue( "ui", "vstembedmethod",
#if QT_VERSION >= 0x050000
m_vstEmbedComboBox->currentData().toString() );
#else
m_vstEmbedComboBox->itemData(m_vstEmbedComboBox->currentIndex()).toString() );
#endif


ConfigManager::inst()->setWorkingDir(QDir::fromNativeSeparators(m_workingDir));
Expand Down

0 comments on commit 966ae27

Please sign in to comment.