From dfeb68aeb4cfb23b335e3a171314b78327d832e3 Mon Sep 17 00:00:00 2001 From: Robin Gareus Date: Fri, 21 Feb 2014 18:00:12 +0100 Subject: [PATCH] Windows VST GUI related rework --- gtk2_ardour/vst_plugin_ui.cc | 12 +++++++++++- gtk2_ardour/windows_vst_plugin_ui.cc | 23 ++++++++++++++++++++++- libs/ardour/session_vst.cc | 22 ++++++++++++++++++++-- libs/ardour/vst_plugin.cc | 22 ++++++++++++++++++++++ 4 files changed, 75 insertions(+), 4 deletions(-) diff --git a/gtk2_ardour/vst_plugin_ui.cc b/gtk2_ardour/vst_plugin_ui.cc index be8eae3240..2bd9724b87 100644 --- a/gtk2_ardour/vst_plugin_ui.cc +++ b/gtk2_ardour/vst_plugin_ui.cc @@ -39,7 +39,9 @@ VSTPluginUI::VSTPluginUI (boost::shared_ptr insert, boost: bypass_button.set_active (!insert->active ()); pack_start (*box, false, false); +#ifdef GDK_WINDOWING_X11 pack_start (_socket, true, true); +#endif } VSTPluginUI::~VSTPluginUI () @@ -50,14 +52,18 @@ VSTPluginUI::~VSTPluginUI () void VSTPluginUI::preset_selected () { +#ifdef GDK_WINDOWING_X11 _socket.grab_focus (); +#endif PlugUIBase::preset_selected (); } int VSTPluginUI::get_preferred_height () { - return _vst->state()->height; + int preferred_height = _vst->state()->height; + preferred_height += _vst->state()->voffset; + return preferred_height; } int @@ -69,11 +75,13 @@ VSTPluginUI::get_preferred_width () int VSTPluginUI::package (Gtk::Window& win) { +#ifdef GDK_WINDOWING_X11 /* Forward configure events to plugin window */ win.signal_configure_event().connect (sigc::mem_fun (*this, &VSTPluginUI::configure_handler), false); /* This assumes that the window's owner understands the XEmbed protocol */ _socket.add_id (get_XID ()); +#endif return 0; } @@ -96,6 +104,7 @@ VSTPluginUI::on_window_hide() bool VSTPluginUI::configure_handler (GdkEventConfigure*) { +#ifdef GDK_WINDOWING_X11 XEvent event; gint x, y; GdkWindow* w; @@ -129,6 +138,7 @@ VSTPluginUI::configure_handler (GdkEventConfigure*) XSendEvent (GDK_WINDOW_XDISPLAY (w), GDK_WINDOW_XWINDOW (w), False, StructureNotifyMask, &event); gdk_error_trap_pop (); +#endif return false; } diff --git a/gtk2_ardour/windows_vst_plugin_ui.cc b/gtk2_ardour/windows_vst_plugin_ui.cc index e902b63860..72e9952dec 100644 --- a/gtk2_ardour/windows_vst_plugin_ui.cc +++ b/gtk2_ardour/windows_vst_plugin_ui.cc @@ -25,7 +25,13 @@ #include "windows_vst_plugin_ui.h" +#ifdef GDK_WINDOWING_X11 #include +#elif defined GDK_WINDOWING_WIN32 +#include +#elif defined GDK_WINDOWING_QUARTZ +/* not yet supported */ +#endif using namespace Gtk; using namespace ARDOUR; @@ -34,7 +40,17 @@ using namespace PBD; WindowsVSTPluginUI::WindowsVSTPluginUI (boost::shared_ptr pi, boost::shared_ptr vp) : VSTPluginUI (pi, vp) { + +#ifdef GDK_WINDOWING_WIN32 + GtkWindow* wobj = win->gobj(); + gtk_widget_realize(GTK_WIDGET(wobj)); + void* hWndHost = gdk_win32_drawable_get_handle(GTK_WIDGET(wobj)->window); + + fst_run_editor (_vst->state(), hWndHost); +#else fst_run_editor (_vst->state(), NULL); +#endif + pack_start (plugin_analysis_expander, true, true); } @@ -108,6 +124,7 @@ WindowsVSTPluginUI::get_XID () return _vst->state()->xid; } +#ifdef GDK_WINDOWING_X11 typedef int (*error_handler_t)( Display *, XErrorEvent *); static Display *the_gtk_display; static error_handler_t wine_error_handler; @@ -124,13 +141,17 @@ fst_xerror_handler (Display* disp, XErrorEvent* ev) return wine_error_handler (disp, ev); } } +#endif void windows_vst_gui_init (int *argc, char **argv[]) { - wine_error_handler = XSetErrorHandler (NULL); gtk_init (argc, argv); + +#ifdef GDK_WINDOWING_X11 + wine_error_handler = XSetErrorHandler (NULL); the_gtk_display = gdk_x11_display_get_xdisplay (gdk_display_get_default()); gtk_error_handler = XSetErrorHandler (fst_xerror_handler); +#endif } diff --git a/libs/ardour/session_vst.cc b/libs/ardour/session_vst.cc index c746a9d388..3f2054aadc 100644 --- a/libs/ardour/session_vst.cc +++ b/libs/ardour/session_vst.cc @@ -90,7 +90,7 @@ intptr_t Session::vst_callback ( case audioMasterVersion: SHOW_CALLBACK ("amc: audioMasterVersion\n"); // vst version, currently 2 (0 for older) - return 2; + return 2; // XXX 2400 case audioMasterCurrentId: SHOW_CALLBACK ("amc: audioMasterCurrentId\n"); @@ -102,6 +102,24 @@ intptr_t Session::vst_callback ( SHOW_CALLBACK ("amc: audioMasterIdle\n"); // call application idle routine (this will // call effEditIdle for all open editors too) + +#if 0 // TODO -> emit to GUI OR better delegete to fst/fst + + // This allows the main GUI window to update if needed. + // Some plugins take over the GUI event loop + // which causes the main GUI to freeze while the plugin GUI continues to run. This code + // prevents the main GUI from being frozen. + + do { +#ifdef GDK_WINDOWING_X11 + gtk_main_iteration_do(false); +#else + gtk_main_iteration() +#endif + } while (gtk_events_pending()); +#endif + printf("audioMasterIdle\n"); + if (effect) { effect->dispatcher(effect, effEditIdle, 0, 0, NULL, 0.0f); } @@ -404,7 +422,7 @@ intptr_t Session::vst_callback ( case audioMasterCanDo: SHOW_CALLBACK ("amc: audioMasterCanDo\n"); - // string in ptr, see below + // string in ptr, (const char*)ptr return 0; case audioMasterGetLanguage: diff --git a/libs/ardour/vst_plugin.cc b/libs/ardour/vst_plugin.cc index 5c9c94bdac..f22ddf525e 100644 --- a/libs/ardour/vst_plugin.cc +++ b/libs/ardour/vst_plugin.cc @@ -351,8 +351,30 @@ VSTPlugin::load_plugin_preset (PresetRecord r) #else sscanf (r.uri.c_str(), "VST:%d:%d", &id, &index); #endif + +#ifdef PLATFORM_WINDOWS + int const vst_version = _plugin->dispatcher (_plugin, effGetVstVersion, 0, 0, NULL, 0); + if (vst_version >= 2) { + _plugin->dispatcher (_plugin, effBeginSetProgram, 0, 0, NULL, 0); + } + + _plugin->dispatcher (_plugin, effSetProgram, 0, index, NULL, 0); + + if (vst_version >= 2) { + _plugin->dispatcher (_plugin, effEndSetProgram, 0, 0, NULL, 0); + } + + //unfortunately, we don't get any opcodes back from the plugin when this happens (?!) + //so we have to manually update param values from the plugin to our listeners + for (int n = 0; n < parameter_count(); n++ ) { + float p = get_parameter(n); //ask the plugin what its new setting is + Plugin::set_parameter (which, newval); + } + +#else _state->want_program = index; +#endif return true; }