ardour
lxvst_plugin_ui.cc
Go to the documentation of this file.
1 /*
2  Copyright (C) 2004 Paul Davis
3 
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.
8 
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.
13 
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.
17 
18 */
19 
20 #include "ardour/lxvst_plugin.h"
22 #include "lxvst_plugin_ui.h"
23 #include "timers.h"
24 #include <gdk/gdkx.h>
25 
26 #define LXVST_H_FIDDLE 40
27 
28 using namespace std;
29 using namespace Gtk;
30 using namespace ARDOUR;
31 using namespace PBD;
32 
33 LXVSTPluginUI::LXVSTPluginUI (boost::shared_ptr<PluginInsert> pi, boost::shared_ptr<VSTPlugin> lxvp)
34  : VSTPluginUI (pi, lxvp)
35 {
36  vstfx_run_editor (_vst->state ());
37 }
38 
39 LXVSTPluginUI::~LXVSTPluginUI ()
40 {
41  _screen_update_connection.disconnect();
42 
43  // plugin destructor destroys the custom GUI, via the vstfx engine,
44  // and then our PluginUIWindow does the rest
45 }
46 
47 
48 bool
49 LXVSTPluginUI::start_updating (GdkEventAny*)
50 {
51  _screen_update_connection.disconnect();
52  _screen_update_connection = Timers::rapid_connect (mem_fun(*this, &LXVSTPluginUI::resize_callback));
53  return false;
54 }
55 
56 bool
57 LXVSTPluginUI::stop_updating (GdkEventAny*)
58 {
59  _screen_update_connection.disconnect();
60  return false;
61 }
62 
63 
64 void
65 LXVSTPluginUI::resize_callback ()
66 {
67  /* We could maybe use this to resize the plugin GTK parent window
68  if required
69  */
70 
71  if (!_vst->state()->want_resize) {
72  return;
73  }
74 
75  int new_height = _vst->state()->height;
76  int new_width = _vst->state()->width;
77 
78  void* gtk_parent_window = _vst->state()->extra_data;
79 
80  if (gtk_parent_window) {
81  ((Gtk::Window*) gtk_parent_window)->resize (new_width, new_height + LXVST_H_FIDDLE);
82  }
83 
84  _vst->state()->want_resize = 0;
85 }
86 
87 int
88 LXVSTPluginUI::get_preferred_height ()
89 {
90  /* XXX: FIXME */
91 
92  /* We have to return the required height of the plugin UI window + a fiddle factor
93  because we can't know how big the preset menu bar is until the window is realised
94  and we can't realise it until we have told it how big we would like it to be
95  which we can't do until it is realised etc
96  */
97 
98  // May not be 40 for all screen res etc
100 }
101 
102 int
103 LXVSTPluginUI::package (Gtk::Window& win)
104 {
105  VSTPluginUI::package (win);
106 
107  /* Map the UI start and stop updating events to 'Map' events on the Window */
108 
109  win.signal_map_event().connect (mem_fun (*this, &LXVSTPluginUI::start_updating));
110  win.signal_unmap_event().connect (mem_fun (*this, &LXVSTPluginUI::stop_updating));
111 
112  _vst->state()->extra_data = (void*) (&win);
113  _vst->state()->want_resize = 0;
114 
115  return 0;
116 }
117 
118 void
119 LXVSTPluginUI::forward_key_event (GdkEventKey*)
120 {
121  std::cerr << "LXVSTPluginUI : keypress forwarding to linuxVSTs unsupported" << std::endl;
122 }
123 
124 int
125 LXVSTPluginUI::get_XID ()
126 {
127  /* Wait for the lock to become free - otherwise
128  the window might be in the process of being
129  created and we get bad Window errors when trying
130  to embed it in the GTK UI
131  */
132 
133  pthread_mutex_lock (&(_vst->state()->lock));
134 
135  /* The Window may be scheduled for creation
136  but not actually created by the gui_event_loop yet -
137  spin here until it has been activated. Possible
138  deadlock if the window never gets activated but
139  should not be called here if the window doesn't
140  exist or will never exist
141  */
142 
143  while (!(_vst->state()->been_activated)) {
144  Glib::usleep (1000);
145  }
146 
147  int const id = _vst->state()->xid;
148 
149  pthread_mutex_unlock (&(_vst->state()->lock));
150 
151  /* Finally it might be safe to return the ID -
152  problems will arise if we return either a zero ID
153  and GTK tries to socket it or if we return an ID
154  which hasn't yet become real to the server
155  */
156 
157  return id;
158 }
159 
160 typedef int (*error_handler_t)( Display *, XErrorEvent *);
161 static Display *the_gtk_display;
164 
165 static int
166 gtk_xerror_handler (Display*, XErrorEvent*)
167 {
168  std::cerr << "** ERROR ** LXVSTPluginUI : Trapped an X Window System Error" << std::endl;
169 
170  return 0;
171 }
172 
173 void
174 gui_init (int* argc, char** argv[])
175 {
176  vstfx_error_handler = XSetErrorHandler (NULL);
177  gtk_init (argc, argv);
178  the_gtk_display = gdk_x11_display_get_xdisplay (gdk_display_get_default());
179  gtk_error_handler = XSetErrorHandler (gtk_xerror_handler);
180 }
181 
static error_handler_t vstfx_error_handler
LIBARDOUR_API int vstfx_run_editor(VSTState *)
Definition: ardour_ui.h:130
void gui_init(int *argc, char **argv[])
Definition: Beats.hpp:239
virtual int package(Gtk::Window &)
#define LXVST_H_FIDDLE
Definition: amp.h:29
int(* error_handler_t)(Display *, XErrorEvent *)
static Display * the_gtk_display
static error_handler_t gtk_error_handler
virtual int get_preferred_height()
Definition: debug.h:30
static int gtk_xerror_handler(Display *, XErrorEvent *)
sigc::connection rapid_connect(const sigc::slot< void > &slot)
Definition: timers.cc:183