2 Copyright (C) 2004 Paul Davis
4 This program is free software; you can redistribute it and/or modify
5 it under the terms of the GNU General Public License as published by
6 the Free Software Foundation; either version 2 of the License, or
7 (at your option) any later version.
9 This program is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 GNU General Public License for more details.
14 You should have received a copy of the GNU General Public License
15 along with this program; if not, write to the Free Software
16 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
20 #include "gtkmm2ext/gui_thread.h"
21 #include "ardour/lxvst_plugin.h"
22 #include "ardour/linux_vst_support.h"
23 #include "lxvst_plugin_ui.h"
26 #define LXVST_H_FIDDLE 40
30 using namespace ARDOUR;
33 LXVSTPluginUI::LXVSTPluginUI (boost::shared_ptr<PluginInsert> pi, boost::shared_ptr<VSTPlugin> lxvp)
34 : VSTPluginUI (pi, lxvp)
36 vstfx_run_editor (_vst->state ());
39 LXVSTPluginUI::~LXVSTPluginUI ()
41 _resize_connection.disconnect();
43 // plugin destructor destroys the custom GUI, via the vstfx engine,
44 // and then our PluginUIWindow does the rest
48 LXVSTPluginUI::resize_callback ()
50 void* gtk_parent_window = _vst->state()->gtk_window_parent;
52 if (gtk_parent_window) {
53 int width = _vst->state()->width;
54 int height = _vst->state()->height;
56 printf ("LXVSTPluginUI::resize_callback %d x %d\n", width, height);
58 _socket.set_size_request(
59 width + _vst->state()->hoffset,
60 height + _vst->state()->voffset);
62 ((Gtk::Window*) gtk_parent_window)->resize (width, height + LXVST_H_FIDDLE);
63 if (_vst->state()->linux_plugin_ui_window) {
69 LXVSTPluginUI::get_preferred_height ()
73 /* We have to return the required height of the plugin UI window + a fiddle factor
74 because we can't know how big the preset menu bar is until the window is realised
75 and we can't realise it until we have told it how big we would like it to be
76 which we can't do until it is realised etc
79 // May not be 40 for all screen res etc
80 return VSTPluginUI::get_preferred_height () + LXVST_H_FIDDLE;
84 LXVSTPluginUI::package (Gtk::Window& win)
86 VSTPluginUI::package (win);
87 _vst->state()->gtk_window_parent = (void*) (&win);
89 /* Map the UI start and stop updating events to 'Map' events on the Window */
91 _vst->VSTSizeWindow.connect (_resize_connection, invalidator (*this), boost::bind (&LXVSTPluginUI::resize_callback, this), gui_context());
96 LXVSTPluginUI::forward_key_event (GdkEventKey*)
98 std::cerr << "LXVSTPluginUI : keypress forwarding to linuxVSTs unsupported" << std::endl;
102 LXVSTPluginUI::get_XID ()
104 /* Wait for the lock to become free - otherwise
105 the window might be in the process of being
106 created and we get bad Window errors when trying
107 to embed it in the GTK UI
110 pthread_mutex_lock (&(_vst->state()->lock));
112 /* The Window may be scheduled for creation
113 but not actually created by the gui_event_loop yet -
114 spin here until it has been activated. Possible
115 deadlock if the window never gets activated but
116 should not be called here if the window doesn't
117 exist or will never exist
120 while (!(_vst->state()->been_activated)) {
124 int const id = _vst->state()->xid;
126 pthread_mutex_unlock (&(_vst->state()->lock));
128 /* Finally it might be safe to return the ID -
129 problems will arise if we return either a zero ID
130 and GTK tries to socket it or if we return an ID
131 which hasn't yet become real to the server
137 typedef int (*error_handler_t)( Display *, XErrorEvent *);
138 static Display *the_gtk_display;
139 static error_handler_t vstfx_error_handler;
140 static error_handler_t gtk_error_handler;
143 gtk_xerror_handler (Display*, XErrorEvent*)
145 std::cerr << "** ERROR ** LXVSTPluginUI : Trapped an X Window System Error" << std::endl;
151 gui_init (int* argc, char** argv[])
153 vstfx_error_handler = XSetErrorHandler (NULL);
154 gtk_init (argc, argv);
155 the_gtk_display = gdk_x11_display_get_xdisplay (gdk_display_get_default());
156 gtk_error_handler = XSetErrorHandler (gtk_xerror_handler);