Windows VST GUI related rework
authorRobin Gareus <robin@gareus.org>
Fri, 21 Feb 2014 17:00:12 +0000 (18:00 +0100)
committerRobin Gareus <robin@gareus.org>
Sat, 22 Feb 2014 02:11:48 +0000 (03:11 +0100)
gtk2_ardour/vst_plugin_ui.cc
gtk2_ardour/windows_vst_plugin_ui.cc
libs/ardour/session_vst.cc
libs/ardour/vst_plugin.cc

index be8eae3240269a052241b3642e408fa4436b6a3f..2bd9724b871b6c72920cd747b6ce0271427abf97 100644 (file)
@@ -39,7 +39,9 @@ VSTPluginUI::VSTPluginUI (boost::shared_ptr<ARDOUR::PluginInsert> 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;
 }
 
index e902b638607c81d42ef733cbdda5f093a7b1612d..72e9952dece2d368b1edce9bf9ea9f011442c47e 100644 (file)
 
 #include "windows_vst_plugin_ui.h"
 
+#ifdef GDK_WINDOWING_X11
 #include <gdk/gdkx.h>
+#elif defined GDK_WINDOWING_WIN32
+#include <gdk/gdkwin32.h>
+#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<PluginInsert> pi, boost::shared_ptr<VSTPlugin> 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
 }
 
index c746a9d388d03d97a2c9575e1641a6211b8bca25..3f2054aadca55477227fc6b9902f94770c5ef27b 100644 (file)
@@ -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:
index 5c9c94bdac9a5d303570bc81729125201bf1f10f..f22ddf525eff0ab4e1f6ec47588be3e60ad2d756 100644 (file)
@@ -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;
 }