Use window instead of embedder application
This commit is contained in:
committed by
Lukas W
parent
12f6ea5566
commit
f87f3638e1
@@ -1217,7 +1217,7 @@ RemotePluginClient::RemotePluginClient( const char * socketPath ) :
|
||||
if( waitForMessage( IdBufferSizeInformation ).id
|
||||
!= IdBufferSizeInformation )
|
||||
{
|
||||
fprintf( stderr, "Could not get buffer size information.\n" );
|
||||
fprintf( stderr, "Could not get buffer size information\n" );
|
||||
}
|
||||
sendMessage( IdHostInfoGotten );
|
||||
}
|
||||
|
||||
@@ -219,7 +219,9 @@ VstEffectControlDialog::VstEffectControlDialog( VstEffectControls * _ctl ) :
|
||||
l->addItem( new QSpacerItem( newSize - 20, 30, QSizePolicy::Fixed,
|
||||
QSizePolicy::Fixed ), 1, 0 );
|
||||
l->addWidget( resize, 2, 0, 1, 1, Qt::AlignCenter );
|
||||
#if QT_VERSION < 0x050000
|
||||
l->addWidget( m_pluginWidget, 3, 0, 1, 1, Qt::AlignCenter );
|
||||
#endif
|
||||
l->setRowStretch( 5, 1 );
|
||||
l->setColumnStretch( 1, 1 );
|
||||
|
||||
@@ -273,11 +275,11 @@ void VstEffectControlDialog::togglePluginUI( bool checked )
|
||||
{
|
||||
if( checked )
|
||||
{
|
||||
m_plugin->showUI();
|
||||
m_plugin->showEditor( NULL, true );
|
||||
}
|
||||
else
|
||||
{
|
||||
m_plugin->hideUI();
|
||||
m_plugin->hideEditor();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -261,7 +261,7 @@ void vestigeInstrument::loadFile( const QString & _file )
|
||||
return;
|
||||
}
|
||||
|
||||
m_plugin->showUI();
|
||||
m_plugin->showEditor( NULL, false );
|
||||
|
||||
if( set_ch_name )
|
||||
{
|
||||
@@ -735,7 +735,7 @@ void VestigeInstrumentView::toggleGUI( void )
|
||||
{
|
||||
return;
|
||||
}
|
||||
m_vi->m_plugin->toggleUI();
|
||||
m_vi->m_plugin->toggleEditor();
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -67,18 +67,6 @@ ADD_CUSTOM_COMMAND(
|
||||
OUTPUTS ../RemoteVstPlugin
|
||||
)
|
||||
|
||||
IF(QT5)
|
||||
QT5_WRAP_CPP(embed-window_MOC_out EmbedderApplication.h)
|
||||
ELSE()
|
||||
QT4_WRAP_CPP(embed-window_MOC_out EmbedderApplication.h)
|
||||
ENDIF()
|
||||
|
||||
ADD_EXECUTABLE(embed-window embed-window.cpp ${embed-window_MOC_out})
|
||||
TARGET_LINK_LIBRARIES(embed-window ${QT_LIBRARIES})
|
||||
IF(NOT QT5)
|
||||
TARGET_LINK_LIBRARIES(embed-window ${X11_X11_LIB})
|
||||
ENDIF()
|
||||
|
||||
SET_DIRECTORY_PROPERTIES(PROPERTIES ADDITIONAL_MAKE_CLEAN_FILES ../RemoteVstPlugin.exe.so)
|
||||
INSTALL(PROGRAMS "${CMAKE_CURRENT_BINARY_DIR}/../RemoteVstPlugin" "${CMAKE_CURRENT_BINARY_DIR}/../RemoteVstPlugin.exe.so" DESTINATION "${PLUGIN_DIR}")
|
||||
ENDIF(LMMS_BUILD_LINUX AND NOT WANT_VST_NOWINE)
|
||||
|
||||
@@ -1,82 +0,0 @@
|
||||
/*
|
||||
* EmbedderApplication.h - simple application that embeds an external window
|
||||
*
|
||||
* Copyright (c) 2016 Javier Serrano Polo <javier@jasp.net>
|
||||
*
|
||||
* This file is part of LMMS - http://lmms.io
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public
|
||||
* License along with this program (see COPYING); if not, write to the
|
||||
* Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
|
||||
* Boston, MA 02110-1301 USA.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef EMBEDDER_APPLICATION_H
|
||||
#define EMBEDDER_APPLICATION_H
|
||||
|
||||
#include <QApplication>
|
||||
#include <QMainWindow>
|
||||
|
||||
#if QT_VERSION < 0x050000
|
||||
class QX11EmbedContainer;
|
||||
#endif
|
||||
|
||||
|
||||
class MainWindow : public QMainWindow
|
||||
{
|
||||
public:
|
||||
void init( const char * title, unsigned int windowId, int width,
|
||||
int height );
|
||||
|
||||
|
||||
protected:
|
||||
virtual void closeEvent( QCloseEvent *event );
|
||||
|
||||
|
||||
private:
|
||||
#if QT_VERSION < 0x050000
|
||||
QX11EmbedContainer * m_window;
|
||||
#else
|
||||
QWindow * m_window;
|
||||
#endif
|
||||
|
||||
} ;
|
||||
|
||||
|
||||
|
||||
|
||||
class EmbedderApplication : public QApplication
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
EmbedderApplication( int & argc, char * * argv );
|
||||
|
||||
virtual ~EmbedderApplication();
|
||||
|
||||
void init( const char * title, unsigned int windowId, int width,
|
||||
int height );
|
||||
|
||||
|
||||
private:
|
||||
MainWindow m_mainWindow;
|
||||
|
||||
|
||||
private slots:
|
||||
void applicationReady();
|
||||
void readCommand();
|
||||
|
||||
} ;
|
||||
|
||||
|
||||
#endif
|
||||
@@ -52,7 +52,6 @@
|
||||
#include <sched.h>
|
||||
#endif
|
||||
|
||||
#include <sys/wait.h>
|
||||
#include <wine/exception.h>
|
||||
|
||||
#endif
|
||||
@@ -67,7 +66,6 @@
|
||||
#endif
|
||||
|
||||
|
||||
#include <cinttypes>
|
||||
#include <vector>
|
||||
#include <string>
|
||||
|
||||
@@ -108,12 +106,6 @@ struct ERect
|
||||
#include <sys/shm.h>
|
||||
#endif
|
||||
|
||||
#define EMBEDDER_NAME "embed-window"
|
||||
|
||||
#ifdef LMMS_BUILD_LINUX
|
||||
#define USE_LINUX_EMBEDDER
|
||||
#endif
|
||||
|
||||
static VstHostLanguages hlang = LanguageEnglish;
|
||||
|
||||
|
||||
@@ -123,10 +115,6 @@ RemoteVstPlugin * __plugin = NULL;
|
||||
|
||||
DWORD __GuiThreadID = 0;
|
||||
|
||||
#ifdef USE_LINUX_EMBEDDER
|
||||
static char * s_embedderPath;
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
class RemoteVstPlugin : public RemotePluginClient
|
||||
@@ -312,13 +300,6 @@ private:
|
||||
intptr_t m_windowID;
|
||||
int m_windowWidth;
|
||||
int m_windowHeight;
|
||||
#ifdef USE_LINUX_EMBEDDER
|
||||
pid_t m_embedderPid;
|
||||
int m_embedderStdin;
|
||||
int m_embedderStdout;
|
||||
#else
|
||||
PROCESS_INFORMATION m_processInfo;
|
||||
#endif
|
||||
|
||||
bool m_initialized;
|
||||
bool m_registeredWindowClass;
|
||||
@@ -478,47 +459,11 @@ RemoteVstPlugin::~RemoteVstPlugin()
|
||||
|
||||
|
||||
|
||||
#ifdef USE_LINUX_EMBEDDER
|
||||
static void checkExitStatus( int status )
|
||||
{
|
||||
if( WIFEXITED( status ) && WEXITSTATUS( status ) == EXIT_SUCCESS )
|
||||
{
|
||||
return;
|
||||
}
|
||||
fprintf( stderr, "Child process did not exit properly\n" );
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
|
||||
bool RemoteVstPlugin::processMessage( const message & _m )
|
||||
{
|
||||
switch( _m.id )
|
||||
{
|
||||
case IdShowUI:
|
||||
#ifdef USE_LINUX_EMBEDDER
|
||||
if( m_window )
|
||||
{
|
||||
int status;
|
||||
pid_t pid = waitpid( m_embedderPid, &status,
|
||||
WNOHANG );
|
||||
switch( pid )
|
||||
{
|
||||
case -1:
|
||||
perror( "waitpid" );
|
||||
break;
|
||||
|
||||
case 0:
|
||||
break;
|
||||
|
||||
default:
|
||||
checkExitStatus( status );
|
||||
m_embedderPid = -1;
|
||||
destroyEditor();
|
||||
}
|
||||
}
|
||||
#endif
|
||||
initEditor();
|
||||
break;
|
||||
|
||||
@@ -527,39 +472,6 @@ bool RemoteVstPlugin::processMessage( const message & _m )
|
||||
break;
|
||||
|
||||
case IdToggleUI:
|
||||
#ifdef USE_LINUX_EMBEDDER
|
||||
if( m_window )
|
||||
{
|
||||
bool restart = false;
|
||||
int status;
|
||||
pid_t pid = waitpid( m_embedderPid, &status,
|
||||
WNOHANG );
|
||||
switch( pid )
|
||||
{
|
||||
case -1:
|
||||
perror( "waitpid" );
|
||||
break;
|
||||
|
||||
case 0:
|
||||
break;
|
||||
|
||||
default:
|
||||
checkExitStatus( status );
|
||||
m_embedderPid = -1;
|
||||
restart = true;
|
||||
}
|
||||
destroyEditor();
|
||||
|
||||
if( !restart )
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
initEditor();
|
||||
break;
|
||||
#else
|
||||
// Temporary implementation, not using an embedder
|
||||
if( m_window )
|
||||
{
|
||||
destroyEditor();
|
||||
@@ -569,12 +481,22 @@ bool RemoteVstPlugin::processMessage( const message & _m )
|
||||
initEditor();
|
||||
}
|
||||
break;
|
||||
#endif
|
||||
|
||||
case IdVstLoadPlugin:
|
||||
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;
|
||||
@@ -712,20 +634,6 @@ void RemoteVstPlugin::init( const std::string & _plugin_file )
|
||||
|
||||
|
||||
|
||||
#ifdef USE_LINUX_EMBEDDER
|
||||
static void assert_dup2( int oldfd, int newfd )
|
||||
{
|
||||
if( dup2( oldfd, newfd ) == -1 )
|
||||
{
|
||||
perror( "dup2" );
|
||||
exit( EXIT_FAILURE );
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
|
||||
static void close_check( int fd )
|
||||
{
|
||||
if( close( fd ) )
|
||||
@@ -775,11 +683,7 @@ void RemoteVstPlugin::initEditor()
|
||||
}
|
||||
|
||||
m_window = CreateWindowEx( 0, "LVSL", m_shortName.c_str(),
|
||||
#if QT_VERSION < 0x050000 && defined( LMMS_BUILD_LINUX )
|
||||
WS_POPUP | WS_SYSMENU | WS_BORDER,
|
||||
#else
|
||||
( WS_OVERLAPPEDWINDOW | WS_THICKFRAME ) & ~WS_MAXIMIZEBOX,
|
||||
#endif
|
||||
0, 0, 10, 10, NULL, NULL, hInst, NULL );
|
||||
if( m_window == NULL )
|
||||
{
|
||||
@@ -787,6 +691,7 @@ void RemoteVstPlugin::initEditor()
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
pluginDispatch( effEditOpen, 0, 0, m_window );
|
||||
|
||||
ERect * er;
|
||||
@@ -795,159 +700,17 @@ void RemoteVstPlugin::initEditor()
|
||||
m_windowWidth = er->right - er->left;
|
||||
m_windowHeight = er->bottom - er->top;
|
||||
|
||||
#ifdef USE_LINUX_EMBEDDER
|
||||
m_windowID = (intptr_t) GetProp( m_window, "__wine_x11_whole_window" );
|
||||
|
||||
m_embedderPid = -1;
|
||||
m_embedderStdin = -1;
|
||||
m_embedderStdout = -1;
|
||||
|
||||
int infd[2];
|
||||
int outfd[2];
|
||||
if( pipe( infd ) )
|
||||
{
|
||||
perror( "pipe" );
|
||||
destroyEditor();
|
||||
return;
|
||||
}
|
||||
if( pipe( outfd ) )
|
||||
{
|
||||
perror( "pipe" );
|
||||
close_check( infd[0] );
|
||||
close_check( infd[1] );
|
||||
destroyEditor();
|
||||
return;
|
||||
}
|
||||
|
||||
m_embedderPid = fork();
|
||||
switch ( m_embedderPid )
|
||||
{
|
||||
case -1:
|
||||
perror( "fork" );
|
||||
close_check( infd[0] );
|
||||
close_check( infd[1] );
|
||||
close_check( outfd[0] );
|
||||
close_check( outfd[1] );
|
||||
destroyEditor();
|
||||
return;
|
||||
|
||||
case 0:
|
||||
assert_dup2( infd[0], STDIN_FILENO );
|
||||
assert_dup2( outfd[1], STDOUT_FILENO );
|
||||
|
||||
close_check( infd[0] );
|
||||
close_check( infd[1] );
|
||||
close_check( outfd[0] );
|
||||
close_check( outfd[1] );
|
||||
|
||||
char * widStr = new char[2 * sizeof m_windowID + 1];
|
||||
sprintf( widStr, "%" PRIxPTR, m_windowID );
|
||||
char * widthStr
|
||||
= new char[2 * sizeof m_windowWidth + 1];
|
||||
sprintf( widthStr, "%x", m_windowWidth );
|
||||
char * heightStr
|
||||
= new char[2 * sizeof m_windowHeight + 1];
|
||||
sprintf( heightStr, "%x", m_windowHeight );
|
||||
execl( s_embedderPath, s_embedderPath,
|
||||
m_shortName.c_str(), widStr, widthStr,
|
||||
heightStr, (char *) NULL );
|
||||
perror( "execl" );
|
||||
exit( EXIT_FAILURE );
|
||||
}
|
||||
|
||||
close_check( infd[0] );
|
||||
close_check( outfd[1] );
|
||||
m_embedderStdin = infd[1];
|
||||
m_embedderStdout = outfd[0];
|
||||
#else
|
||||
// Pending: Check that Qt 5 embedding works on Windows
|
||||
// Should wait until Qt 4 support is dropped
|
||||
|
||||
// TODO: Set to native window ID
|
||||
m_windowID = 1;
|
||||
|
||||
const char * name = m_shortName.c_str();
|
||||
char * commandLine = new char[sizeof EMBEDDER_NAME " " + strlen( name )
|
||||
+ 1 + 2 * sizeof m_windowID + 1 + 2 * sizeof m_windowWidth + 1
|
||||
+ 2 * sizeof m_windowHeight];
|
||||
sprintf( commandLine, EMBEDDER_NAME " %s %" PRIxPTR " %x %x", name,
|
||||
m_windowID, m_windowWidth, m_windowHeight );
|
||||
|
||||
// Set up the pipes
|
||||
/*
|
||||
SECURITY_ATTRIBUTES saAttr;
|
||||
|
||||
saAttr.nLength = sizeof(SECURITY_ATTRIBUTES);
|
||||
saAttr.bInheritHandle = TRUE;
|
||||
saAttr.lpSecurityDescriptor = NULL;
|
||||
|
||||
if ( !CreatePipe(&g_hChildStd_OUT_Rd, &g_hChildStd_OUT_Wr, &saAttr, 0) )
|
||||
ErrorExit(TEXT("StdoutRd CreatePipe"));
|
||||
|
||||
if ( !SetHandleInformation(g_hChildStd_OUT_Rd, HANDLE_FLAG_INHERIT, 0) )
|
||||
ErrorExit(TEXT("Stdout SetHandleInformation"));
|
||||
|
||||
if (! CreatePipe(&g_hChildStd_IN_Rd, &g_hChildStd_IN_Wr, &saAttr, 0))
|
||||
ErrorExit(TEXT("Stdin CreatePipe"));
|
||||
|
||||
if ( ! SetHandleInformation(g_hChildStd_IN_Wr, HANDLE_FLAG_INHERIT, 0) )
|
||||
ErrorExit(TEXT("Stdin SetHandleInformation"));
|
||||
*/
|
||||
|
||||
STARTUPINFO si;
|
||||
ZeroMemory( &si, sizeof si );
|
||||
si.cb = sizeof si;
|
||||
// si.hStdOutput = g_hChildStd_OUT_Wr;
|
||||
// si.hStdInput = g_hChildStd_IN_Rd;
|
||||
// si.dwFlags |= STARTF_USESTDHANDLES;
|
||||
ZeroMemory( &m_processInfo, sizeof m_processInfo );
|
||||
|
||||
// Pending: Create new process when the embedder is ready
|
||||
// bool ok = CreateProcess( NULL, commandLine, NULL, NULL, TRUE, 0, NULL,
|
||||
// NULL, &si, &m_processInfo );
|
||||
delete[] commandLine;
|
||||
/*
|
||||
if ( !ok )
|
||||
{
|
||||
fprintf( stderr, "CreateProcess failed (%d)\n",
|
||||
GetLastError() );
|
||||
destroyEditor();
|
||||
return;
|
||||
}
|
||||
*/
|
||||
// close unused pipe handles if possible
|
||||
// if ( ! CloseHandle(g_hChildStd_IN_Rd) ) error
|
||||
#endif
|
||||
|
||||
|
||||
SetWindowPos( m_window, 0, 0, 0, m_windowWidth + 8,
|
||||
m_windowHeight + 26, SWP_NOACTIVATE |
|
||||
SWP_NOMOVE | SWP_NOZORDER );
|
||||
pluginDispatch( effEditTop );
|
||||
|
||||
#ifdef USE_LINUX_EMBEDDER
|
||||
char c;
|
||||
if( ::read( m_embedderStdout, &c, 1 ) != 1 )
|
||||
{
|
||||
fprintf( stderr, "Could not read from embedder\n" );
|
||||
destroyEditor();
|
||||
return;
|
||||
}
|
||||
#else
|
||||
// bSuccess = ReadFile(g_hChildStd_OUT_Rd, chBuf, BUFSIZE, &dwRead, NULL);
|
||||
// if ( ! bSuccess || dwRead == 0 ) break;
|
||||
#endif
|
||||
ShowWindow( m_window, SW_SHOWNORMAL );
|
||||
#ifdef USE_LINUX_EMBEDDER
|
||||
if( ::write( m_embedderStdin, "", 1 ) != 1 )
|
||||
{
|
||||
fprintf( stderr, "Could not write to embedder\n" );
|
||||
destroyEditor();
|
||||
return;
|
||||
}
|
||||
#ifdef LMMS_BUILD_LINUX
|
||||
m_windowID = (intptr_t) GetProp( m_window, "__wine_x11_whole_window" );
|
||||
#else
|
||||
// bSuccess = WriteFile(g_hChildStd_IN_Wr, chBuf, dwRead, &dwWritten, NULL);
|
||||
// if ( ! bSuccess ) break;
|
||||
// 64-bit versions of Windows use 32-bit handles for interoperability
|
||||
m_windowID = (intptr_t) m_window;
|
||||
#endif
|
||||
}
|
||||
|
||||
@@ -961,32 +724,6 @@ void RemoteVstPlugin::destroyEditor()
|
||||
return;
|
||||
}
|
||||
|
||||
#ifdef USE_LINUX_EMBEDDER
|
||||
close_check( m_embedderStdin );
|
||||
close_check( m_embedderStdout );
|
||||
if( m_embedderPid != -1 )
|
||||
{
|
||||
int status;
|
||||
pid_t pid = waitpid( m_embedderPid, &status, 0 );
|
||||
if( pid == -1 )
|
||||
{
|
||||
perror( "waitpid" );
|
||||
}
|
||||
else
|
||||
{
|
||||
checkExitStatus( status );
|
||||
}
|
||||
}
|
||||
#else
|
||||
// Close pipes
|
||||
// Wait until child process exits.
|
||||
// WaitForSingleObject( m_processInfo.hProcess, INFINITE );
|
||||
|
||||
// Close process and thread handles.
|
||||
// CloseHandle( m_processInfo.hProcess );
|
||||
// CloseHandle( m_processInfo.hThread );
|
||||
#endif
|
||||
|
||||
pluginDispatch( effEditClose );
|
||||
// Destroying the window takes some time in Wine 1.8.5
|
||||
DestroyWindow( m_window );
|
||||
@@ -2105,13 +1842,6 @@ DWORD WINAPI RemoteVstPlugin::guiEventLoop( LPVOID _param )
|
||||
while( quit == false && GetMessage( &msg, NULL, 0, 0 ) )
|
||||
{
|
||||
TranslateMessage( &msg );
|
||||
|
||||
if( msg.message == WM_SYSCOMMAND && msg.wParam == SC_CLOSE )
|
||||
{
|
||||
_this->destroyEditor();
|
||||
continue;
|
||||
}
|
||||
|
||||
DispatchMessage( &msg );
|
||||
|
||||
if( msg.message == WM_TIMER && _this->isInitialized() )
|
||||
@@ -2151,63 +1881,6 @@ DWORD WINAPI RemoteVstPlugin::guiEventLoop( LPVOID _param )
|
||||
|
||||
|
||||
|
||||
#ifdef USE_LINUX_EMBEDDER
|
||||
static char * findMyPath( const char * argv0 )
|
||||
{
|
||||
// TODO: escape ' or use execlp
|
||||
std::string command = "winepath '";
|
||||
command += argv0;
|
||||
command += '\'';
|
||||
FILE * stream = popen( command.c_str(), "r" );
|
||||
if( !stream )
|
||||
{
|
||||
perror( "popen" );
|
||||
return NULL;
|
||||
}
|
||||
char * unixPath = (char *) malloc( BUFSIZ );
|
||||
char * s = fgets( unixPath, BUFSIZ, stream );
|
||||
if( !s )
|
||||
{
|
||||
perror( "fgets" );
|
||||
free( unixPath );
|
||||
return NULL;
|
||||
}
|
||||
if( strlen( s ) == BUFSIZ - 1 )
|
||||
{
|
||||
//TODO: Read a longer line
|
||||
fprintf( stderr, "findMyPath: Buffer too small\n" );
|
||||
}
|
||||
char * eol = strchr( unixPath, '\n' );
|
||||
if( eol )
|
||||
{
|
||||
*eol = '\0';
|
||||
}
|
||||
if( pclose( stream ) == -1 )
|
||||
{
|
||||
perror( "pclose" );
|
||||
}
|
||||
return unixPath;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
static char * findEmbedderPath( const char * argv0 )
|
||||
{
|
||||
char * myPath = findMyPath( argv0 );
|
||||
const char * slash = myPath ? strrchr( myPath, '/' ) : NULL;
|
||||
size_t prefixLength = slash ? slash - myPath + 1 : 0;
|
||||
char * path = new char[prefixLength + sizeof EMBEDDER_NAME];
|
||||
memcpy( path, myPath, prefixLength );
|
||||
memcpy( path + prefixLength, EMBEDDER_NAME, sizeof EMBEDDER_NAME );
|
||||
free( myPath );
|
||||
return path;
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
|
||||
int main( int _argc, char * * _argv )
|
||||
{
|
||||
#ifdef SYNC_WITH_SHM_FIFO
|
||||
@@ -2245,10 +1918,6 @@ int main( int _argc, char * * _argv )
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef USE_LINUX_EMBEDDER
|
||||
s_embedderPath = findEmbedderPath( _argv[0] );
|
||||
#endif
|
||||
|
||||
// constructor automatically will process messages until it receives
|
||||
// a IdVstLoadPlugin message and processes it
|
||||
#ifdef SYNC_WITH_SHM_FIFO
|
||||
@@ -2273,10 +1942,6 @@ int main( int _argc, char * * _argv )
|
||||
|
||||
delete __plugin;
|
||||
|
||||
#ifdef USE_LINUX_EMBEDDER
|
||||
delete[] s_embedderPath;
|
||||
#endif
|
||||
|
||||
|
||||
#ifdef LMMS_BUILD_WIN32
|
||||
#ifndef __WINPTHREADS_VERSION
|
||||
|
||||
@@ -31,6 +31,16 @@
|
||||
#include <QCloseEvent>
|
||||
#include <QMdiArea>
|
||||
#include <QMdiSubWindow>
|
||||
#ifdef LMMS_BUILD_LINUX
|
||||
#if QT_VERSION < 0x050000
|
||||
#include <QX11EmbedContainer>
|
||||
#include <QX11Info>
|
||||
#else
|
||||
#include <QWindow>
|
||||
#endif
|
||||
#else
|
||||
#include <QLayout>
|
||||
#endif
|
||||
#include <QDomDocument>
|
||||
|
||||
#ifdef LMMS_BUILD_WIN32
|
||||
@@ -46,6 +56,33 @@
|
||||
#include "FileDialog.h"
|
||||
|
||||
|
||||
#if QT_VERSION < 0x050000
|
||||
class vstSubWin : public QMdiSubWindow
|
||||
{
|
||||
public:
|
||||
vstSubWin( QWidget * _parent ) :
|
||||
QMdiSubWindow( _parent )
|
||||
{
|
||||
setAttribute( Qt::WA_DeleteOnClose, false );
|
||||
}
|
||||
|
||||
virtual ~vstSubWin()
|
||||
{
|
||||
}
|
||||
|
||||
virtual void closeEvent( QCloseEvent * e )
|
||||
{
|
||||
// ignore close-events - for some reason otherwise the VST GUI
|
||||
// remains hidden when re-opening
|
||||
hide();
|
||||
e->ignore();
|
||||
}
|
||||
} ;
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
|
||||
VstPlugin::VstPlugin( const QString & _plugin ) :
|
||||
RemotePlugin(),
|
||||
JournallingObject(),
|
||||
@@ -168,15 +205,49 @@ void VstPlugin::showEditor( QWidget * _parent, bool isEffect )
|
||||
return;
|
||||
}
|
||||
|
||||
#if QT_VERSION < 0x050000
|
||||
m_pluginWidget = new QWidget( _parent );
|
||||
m_pluginWidget->setFixedSize( m_pluginGeometry );
|
||||
m_pluginWidget->setWindowTitle( name() );
|
||||
if( _parent == NULL )
|
||||
{
|
||||
vstSubWin * sw = new vstSubWin(
|
||||
gui->mainWindow()->workspace() );
|
||||
if( isEffect )
|
||||
{
|
||||
sw->setAttribute( Qt::WA_TranslucentBackground );
|
||||
sw->setWindowFlags( Qt::FramelessWindowHint );
|
||||
sw->setWidget( m_pluginWidget );
|
||||
QX11EmbedContainer * xe = new QX11EmbedContainer( sw );
|
||||
xe->embedClient( m_pluginWindowID );
|
||||
xe->setFixedSize( m_pluginGeometry );
|
||||
xe->show();
|
||||
}
|
||||
else
|
||||
{
|
||||
sw->setWindowFlags( Qt::WindowCloseButtonHint );
|
||||
sw->setWidget( m_pluginWidget );
|
||||
|
||||
QX11EmbedContainer * xe = new QX11EmbedContainer( sw );
|
||||
xe->embedClient( m_pluginWindowID );
|
||||
xe->setFixedSize( m_pluginGeometry );
|
||||
xe->move( 4, 24 );
|
||||
xe->show();
|
||||
}
|
||||
}
|
||||
#else
|
||||
QWindow * window = QWindow::fromWinId( m_pluginWindowID );
|
||||
m_pluginWidget = QWidget::createWindowContainer( window, _parent,
|
||||
Qt::Window );
|
||||
m_pluginWidget->setFixedSize( m_pluginGeometry );
|
||||
m_pluginWidget->setWindowTitle( name() );
|
||||
// TODO: Synchronize show
|
||||
// Tell remote that it is embedded
|
||||
// Wait for remote reply
|
||||
#endif
|
||||
#endif
|
||||
|
||||
if( m_pluginWidget )
|
||||
{
|
||||
m_pluginWidget->show();
|
||||
}
|
||||
m_pluginWidget->show();
|
||||
}
|
||||
|
||||
|
||||
@@ -184,7 +255,6 @@ void VstPlugin::showEditor( QWidget * _parent, bool isEffect )
|
||||
|
||||
void VstPlugin::hideEditor()
|
||||
{
|
||||
//TODO: Drop m_pluginWidget, showEditor(), hideEditor()
|
||||
QWidget * w = pluginWidget();
|
||||
if( w )
|
||||
{
|
||||
@@ -195,6 +265,18 @@ void VstPlugin::hideEditor()
|
||||
|
||||
|
||||
|
||||
void VstPlugin::toggleEditor()
|
||||
{
|
||||
QWidget * w = m_pluginWidget;
|
||||
if( w )
|
||||
{
|
||||
w->setVisible( !w->isVisible() );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
void VstPlugin::loadSettings( const QDomElement & _this )
|
||||
{
|
||||
if( pluginWidget() != NULL )
|
||||
@@ -240,7 +322,6 @@ void VstPlugin::loadSettings( const QDomElement & _this )
|
||||
|
||||
void VstPlugin::saveSettings( QDomDocument & _doc, QDomElement & _this )
|
||||
{
|
||||
//TODO: Replace with m_plugin->isVisible(), add IdIsUIVisble message
|
||||
if( pluginWidget() != NULL )
|
||||
{
|
||||
_this.setAttribute( "guivisible", pluginWidget()->isVisible() );
|
||||
|
||||
@@ -54,6 +54,7 @@ public:
|
||||
|
||||
void showEditor( QWidget * _parent = NULL, bool isEffect = false );
|
||||
void hideEditor();
|
||||
void toggleEditor();
|
||||
|
||||
inline const QString & name() const
|
||||
{
|
||||
@@ -93,6 +94,7 @@ public:
|
||||
|
||||
inline QWidget * pluginWidget( bool _top_widget = true )
|
||||
{
|
||||
#if QT_VERSION < 0x050000
|
||||
if( _top_widget && m_pluginWidget )
|
||||
{
|
||||
if( m_pluginWidget->parentWidget() )
|
||||
@@ -100,6 +102,7 @@ public:
|
||||
return m_pluginWidget->parentWidget();
|
||||
}
|
||||
}
|
||||
#endif
|
||||
return m_pluginWidget;
|
||||
}
|
||||
|
||||
|
||||
@@ -56,6 +56,8 @@ enum VstRemoteMessageIDs
|
||||
{
|
||||
// vstPlugin -> remoteVstPlugin
|
||||
IdVstLoadPlugin = IdUserBase,
|
||||
// TODO: Drop IdVstPluginWindowInformation, Windows hack for Qt 4
|
||||
IdVstPluginWindowInformation,
|
||||
IdVstClosePlugin,
|
||||
IdVstSetTempo,
|
||||
IdVstSetLanguage,
|
||||
@@ -72,9 +74,6 @@ enum VstRemoteMessageIDs
|
||||
// remoteVstPlugin -> vstPlugin
|
||||
IdVstFailedLoadingPlugin,
|
||||
IdVstBadDllFormat,
|
||||
// Window ID and geometry are only useful if external windows can be
|
||||
// embedded in LMMS, which is not the case in Qt 5 because there are
|
||||
// glitches. If Qt is not fixed, then drop these messages.
|
||||
IdVstPluginWindowID,
|
||||
IdVstPluginEditorGeometry,
|
||||
IdVstPluginName,
|
||||
|
||||
@@ -1,151 +0,0 @@
|
||||
/*
|
||||
* embed-window.cpp - simple application that embeds an external window
|
||||
*
|
||||
* Copyright (c) 2016 Javier Serrano Polo <javier@jasp.net>
|
||||
*
|
||||
* This file is part of LMMS - http://lmms.io
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public
|
||||
* License along with this program (see COPYING); if not, write to the
|
||||
* Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
|
||||
* Boston, MA 02110-1301 USA.
|
||||
*
|
||||
*/
|
||||
|
||||
#include "EmbedderApplication.h"
|
||||
|
||||
#include <QSocketNotifier>
|
||||
#include <QTimer>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#if QT_VERSION < 0x050000
|
||||
#include <QX11EmbedContainer>
|
||||
#include <QX11Info>
|
||||
#include <X11/Xlib.h>
|
||||
#else
|
||||
#include <QWindow>
|
||||
#endif
|
||||
|
||||
|
||||
void MainWindow::init( const char * title, unsigned int windowId, int width,
|
||||
int height )
|
||||
{
|
||||
setWindowTitle( title );
|
||||
#if QT_VERSION < 0x050000
|
||||
m_window = new QX11EmbedContainer( this );
|
||||
QX11EmbedContainer * container = m_window;
|
||||
container->embedClient( windowId );
|
||||
#else
|
||||
m_window = QWindow::fromWinId( windowId );
|
||||
QWidget * container = QWidget::createWindowContainer( m_window, this );
|
||||
#endif
|
||||
container->setFixedSize( width, height );
|
||||
container->show();
|
||||
setFixedSize( width, height );
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
void MainWindow::closeEvent( QCloseEvent *event )
|
||||
{
|
||||
hide();
|
||||
#if QT_VERSION < 0x050000
|
||||
XUnmapWindow( QX11Info::display(), m_window->clientWinId() );
|
||||
m_window->discardClient();
|
||||
#else
|
||||
m_window->setParent( 0 );
|
||||
#endif
|
||||
QMainWindow::closeEvent( event );
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
EmbedderApplication::EmbedderApplication( int & argc, char * * argv ) :
|
||||
QApplication( argc, argv )
|
||||
{
|
||||
QSocketNotifier * notifier = new QSocketNotifier( STDIN_FILENO,
|
||||
QSocketNotifier::Read );
|
||||
connect( notifier, SIGNAL( activated( int ) ), SLOT( readCommand() ) );
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
EmbedderApplication::~EmbedderApplication()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
void EmbedderApplication::init( const char * title, unsigned int windowId,
|
||||
int width, int height )
|
||||
{
|
||||
m_mainWindow.init( title, windowId, width, height );
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
void EmbedderApplication::applicationReady()
|
||||
{
|
||||
putchar( 0 );
|
||||
fflush( stdout );
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
void EmbedderApplication::readCommand()
|
||||
{
|
||||
int c = getchar();
|
||||
if( c == EOF )
|
||||
{
|
||||
m_mainWindow.close();
|
||||
quit();
|
||||
return;
|
||||
}
|
||||
m_mainWindow.show();
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
int main( int argc, char * * argv )
|
||||
{
|
||||
if( argc < 5 )
|
||||
{
|
||||
fputs( "Missing arguments\n", stderr );
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
|
||||
EmbedderApplication * app = new EmbedderApplication( argc, argv );
|
||||
|
||||
const char * title = argv[1];
|
||||
unsigned int windowId = strtol( argv[2], NULL, 16 );
|
||||
int width = strtol( argv[3], NULL, 16 );
|
||||
int height = strtol( argv[4], NULL, 16 );
|
||||
|
||||
app->init( title, windowId, width, height );
|
||||
|
||||
QTimer::singleShot( 0, app, SLOT( applicationReady() ) );
|
||||
|
||||
int ret = app->exec();
|
||||
delete app;
|
||||
|
||||
return ret;
|
||||
}
|
||||
Reference in New Issue
Block a user