Fix playhead smoothing when auditioning.
[ardour.git] / gtk2_ardour / lxvst_plugin_ui.cc
index f5265cffa8d0f45a212b44416f99145de209e1e1..161ceabe47610b7e070b0183a39ff0ae8b7d5107 100644 (file)
 
 */
 
+
+#include "gtkmm2ext/gui_thread.h"
 #include "ardour/lxvst_plugin.h"
 #include "ardour/linux_vst_support.h"
 #include "lxvst_plugin_ui.h"
-#include "timers.h"
-#include <gdk/gdkx.h>
+
+#include <gdk/gdkx.h> /* must come later than glibmm/object.h */
 
 #define LXVST_H_FIDDLE 40
 
@@ -38,53 +40,31 @@ LXVSTPluginUI::LXVSTPluginUI (boost::shared_ptr<PluginInsert> pi, boost::shared_
 
 LXVSTPluginUI::~LXVSTPluginUI ()
 {
-       _screen_update_connection.disconnect();
+       _resize_connection.disconnect();
 
        // plugin destructor destroys the custom GUI, via the vstfx engine,
        // and then our PluginUIWindow does the rest
 }
 
-
-bool
-LXVSTPluginUI::start_updating (GdkEventAny*)
-{
-       _screen_update_connection.disconnect();
-       _screen_update_connection = Timers::rapid_connect (mem_fun(*this, &LXVSTPluginUI::resize_callback));
-       return false;
-}
-
-bool
-LXVSTPluginUI::stop_updating (GdkEventAny*)
-{
-       _screen_update_connection.disconnect();
-       return false;
-}
-
-
 void
 LXVSTPluginUI::resize_callback ()
 {
-       /* We could maybe use this to resize the plugin GTK parent window
-          if required
-       */
-
-       if (!_vst->state()->want_resize) {
-               return;
-       }
-
-       int new_height = _vst->state()->height;
-       int new_width = _vst->state()->width;
-
-       void* gtk_parent_window = _vst->state()->extra_data;
+       void* gtk_parent_window = _vst->state()->gtk_window_parent;
 
        if (gtk_parent_window) {
+               int width  = _vst->state()->width;
+               int height = _vst->state()->height;
+#ifndef NDEBUG
+               printf ("LXVSTPluginUI::resize_callback %d x %d\n", width, height);
+#endif
                _socket.set_size_request(
-                               new_width + _vst->state()->hoffset,
-                               new_height + _vst->state()->voffset);
+                               width  + _vst->state()->hoffset,
+                               height + _vst->state()->voffset);
 
-               ((Gtk::Window*) gtk_parent_window)->resize (new_width, new_height + LXVST_H_FIDDLE);
+               ((Gtk::Window*) gtk_parent_window)->resize (width, height + LXVST_H_FIDDLE);
+               if (_vst->state()->linux_plugin_ui_window) {
+               }
        }
-       _vst->state()->want_resize = 0;
 }
 
 int
@@ -106,22 +86,66 @@ int
 LXVSTPluginUI::package (Gtk::Window& win)
 {
        VSTPluginUI::package (win);
+       _vst->state()->gtk_window_parent = (void*) (&win);
 
        /* Map the UI start and stop updating events to 'Map' events on the Window */
 
-       win.signal_map_event().connect (mem_fun (*this, &LXVSTPluginUI::start_updating));
-       win.signal_unmap_event().connect (mem_fun (*this, &LXVSTPluginUI::stop_updating));
-
-       _vst->state()->extra_data = (void*) (&win);
-       _vst->state()->want_resize = 0;
-
+       _vst->VSTSizeWindow.connect (_resize_connection, invalidator (*this), boost::bind (&LXVSTPluginUI::resize_callback, this), gui_context());
        return 0;
 }
 
 void
-LXVSTPluginUI::forward_key_event (GdkEventKey*)
+LXVSTPluginUI::forward_key_event (GdkEventKey* gdk_key)
 {
-       std::cerr << "LXVSTPluginUI : keypress forwarding to linuxVSTs unsupported" << std::endl;
+       if (!_vst->state()->gtk_window_parent) {
+               return;
+       }
+
+       Glib::RefPtr<Gdk::Window> gdk_window = ((Gtk::Window*) _vst->state()->gtk_window_parent)->get_window();
+
+       if (!gdk_window) {
+               return;
+       }
+
+       XEvent xev;
+       int mask;
+
+       switch (gdk_key->type) {
+       case GDK_KEY_PRESS:
+               xev.xany.type = KeyPress;
+               mask = KeyPressMask;
+               break;
+       case GDK_KEY_RELEASE:
+               xev.xany.type = KeyRelease;
+               mask = KeyReleaseMask;
+               break;
+       default:
+               return;
+       }
+
+       /* XXX relies on GDK using X11 definitions for these fields */
+
+       xev.xkey.state = gdk_key->state;
+       xev.xkey.keycode = gdk_key->hardware_keycode; /* see gdk/x11/gdkevents-x11.c:translate_key_event() */
+
+       xev.xkey.x = 0;
+       xev.xkey.y = 0;
+       xev.xkey.x_root = 0;
+       xev.xkey.y_root = 0;
+       xev.xkey.root = gdk_x11_get_default_root_xwindow();
+       xev.xkey.window = _vst->state()->linux_plugin_ui_window ? _vst->state()->linux_plugin_ui_window : _vst->state()->xid;
+       xev.xkey.subwindow = None;
+       xev.xkey.time = gdk_key->time;
+
+       xev.xany.serial = 0; /* we don't have one */
+       xev.xany.send_event = true; /* pretend we are using XSendEvent */
+       xev.xany.display = GDK_WINDOW_XDISPLAY (gdk_window->gobj());
+
+       if (_vst->state()->eventProc) {
+               _vst->state()->eventProc (&xev);
+       } else if (!dispatch_effeditkey (gdk_key)) {
+               XSendEvent (xev.xany.display, xev.xany.window, TRUE, mask, &xev);
+       }
 }
 
 int
@@ -181,4 +205,3 @@ gui_init (int* argc, char** argv[])
        the_gtk_display = gdk_x11_display_get_xdisplay (gdk_display_get_default());
        gtk_error_handler = XSetErrorHandler (gtk_xerror_handler);
 }
-