From a0e75893e0ac2ce094556bbc952fc42916cd0b1b Mon Sep 17 00:00:00 2001 From: Paul Davis Date: Sat, 11 Aug 2018 13:50:42 -0400 Subject: [PATCH] initial implementation of keyboard event forwarding for LXVST --- gtk2_ardour/lxvst_plugin_ui.cc | 57 ++++++++++++++++++++++++++++++++-- 1 file changed, 54 insertions(+), 3 deletions(-) diff --git a/gtk2_ardour/lxvst_plugin_ui.cc b/gtk2_ardour/lxvst_plugin_ui.cc index 4638116fba..25ee0f2aea 100644 --- a/gtk2_ardour/lxvst_plugin_ui.cc +++ b/gtk2_ardour/lxvst_plugin_ui.cc @@ -17,11 +17,13 @@ */ + #include "gtkmm2ext/gui_thread.h" #include "ardour/lxvst_plugin.h" #include "ardour/linux_vst_support.h" #include "lxvst_plugin_ui.h" -#include + +#include /* must come later than glibmm/object.h */ #define LXVST_H_FIDDLE 40 @@ -93,9 +95,58 @@ LXVSTPluginUI::package (Gtk::Window& win) } 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 = ((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 = KeyPress; + 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()->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()); + xev.xany.window = _vst->state()->xid; + + if (!_vst->state()->eventProc) { + XSendEvent (xev.xany.display, xev.xany.window, TRUE, mask, &xev); + } else { + _vst->state()->eventProc (&xev); + } } int