1 /*
2 * Copyright (C) 2020 Robin Gareus <robin@gareus.org>
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 along
15 * with this program; if not, write to the Free Software Foundation, Inc.,
16 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
17 */
18
19 #ifdef WAF_BUILD
20 #include "gtk2ardour-config.h"
21 #endif
22
23 #include <glibmm/main.h>
24
25 #include "pbd/unwind.h"
26
27 #include "ardour/plugin_insert.h"
28 #include "ardour/vst3_plugin.h"
29
30 #include "gtkmm2ext/gui_thread.h"
31
32 #include "vst3_hwnd_plugin_ui.h"
33
34 #include <gdk/gdkwin32.h>
35
36 using namespace ARDOUR;
37 using namespace Steinberg;
38
39
VST3HWNDPluginUI(boost::shared_ptr<PluginInsert> pi,boost::shared_ptr<VST3Plugin> vst3)40 VST3HWNDPluginUI::VST3HWNDPluginUI (boost::shared_ptr<PluginInsert> pi, boost::shared_ptr<VST3Plugin> vst3)
41 : VST3PluginUI (pi, vst3)
42 {
43 /* TODO register window class, implement wndproc etc */
44
45 pack_start (_gui_widget, true, true);
46
47 _gui_widget.signal_realize().connect (mem_fun (this, &VST3HWNDPluginUI::view_realized));
48 _gui_widget.signal_size_request ().connect (mem_fun (this, &VST3HWNDPluginUI::view_size_request));
49 _gui_widget.signal_size_allocate ().connect (mem_fun (this, &VST3HWNDPluginUI::view_size_allocate));
50 _gui_widget.signal_scroll_event ().connect (sigc::mem_fun (*this, &VST3HWNDPluginUI::forward_scroll_event), false);
51
52 _gui_widget.show ();
53 }
54
~VST3HWNDPluginUI()55 VST3HWNDPluginUI::~VST3HWNDPluginUI ()
56 {
57 assert (_view_realized);
58 _vst3->close_view ();
59 }
60
61 void
view_realized()62 VST3HWNDPluginUI::view_realized ()
63 {
64 IPlugView* view = _vst3->view ();
65 HWND hwnd = (HWND) gdk_win32_drawable_get_handle (GTK_WIDGET(_gui_widget.gobj())->window);
66 // SetWindowLongPtr (hwnd, GWLP_USERDATA, (__int3264) (LONG_PTR)this);
67 if (kResultOk != view->attached (reinterpret_cast<void*> (hwnd), Steinberg::kPlatformTypeHWND)) {
68 assert (0);
69 }
70 _view_realized = true;
71
72 ViewRect rect;
73 if (view->getSize (&rect) == kResultOk) {
74 _req_width = rect.right - rect.left;
75 _req_height = rect.bottom - rect.top;
76 }
77
78 _gui_widget.queue_resize ();
79 }
80
81 void
view_size_request(GtkRequisition * requisition)82 VST3HWNDPluginUI::view_size_request (GtkRequisition* requisition)
83 {
84 requisition->width = _req_width;
85 requisition->height = _req_height;
86 }
87
88 void
view_size_allocate(Gtk::Allocation & allocation)89 VST3HWNDPluginUI::view_size_allocate (Gtk::Allocation& allocation)
90 {
91 IPlugView* view = _vst3->view ();
92 if (!view || !_view_realized) {
93 return;
94 }
95 PBD::Unwinder<bool> uw (_resize_in_progress, true);
96 ViewRect rect;
97 if (view->getSize (&rect) == kResultOk
98 && ! (rect.right - rect.left == allocation.get_width () && rect.bottom - rect.top == allocation.get_height ()))
99 {
100 rect.right = rect.left + allocation.get_width ();
101 rect.bottom = rect.top + allocation.get_height ();
102 #if 0
103 if (view->checkSizeConstraint (&rect) != kResultTrue) {
104 view->getSize (&rect);
105 }
106 allocation.set_width (rect.right - rect.left);
107 allocation.set_height (rect.bottom - rect.top);
108 #endif
109 if (view->canResize() == kResultTrue) {
110 view->onSize (&rect);
111 }
112 }
113 }
114
115 void
resize_callback(int width,int height)116 VST3HWNDPluginUI::resize_callback (int width, int height)
117 {
118 //printf ("VST3HWNDPluginUI::resize_callback %d x %d\n", width, height);
119 IPlugView* view = _vst3->view ();
120 if (!view || _resize_in_progress) {
121 return;
122 }
123 if (view->canResize() == kResultTrue) {
124 gint xx, yy;
125 if (gtk_widget_translate_coordinates (
126 GTK_WIDGET(_gui_widget.gobj()),
127 GTK_WIDGET(get_toplevel()->gobj()),
128 0, 0, &xx, &yy))
129 {
130 get_window()->resize (width + xx, height + yy);
131 }
132 } else {
133 _req_width = width;
134 _req_height = height;
135 _gui_widget.queue_resize ();
136 }
137 }
138
139 bool
on_window_show(const std::string &)140 VST3HWNDPluginUI::on_window_show (const std::string& /*title*/)
141 {
142 IPlugView* view = _vst3->view ();
143 if (!view) {
144 return false;
145 }
146
147 gtk_widget_realize (GTK_WIDGET(_gui_widget.gobj()));
148 _gui_widget.show_all ();
149 _gui_widget.queue_resize ();
150 return true;
151 }
152
153 void
on_window_hide()154 VST3HWNDPluginUI::on_window_hide ()
155 {
156 _gui_widget.hide ();
157 }
158
159 void
grab_focus()160 VST3HWNDPluginUI::grab_focus ()
161 {
162 #if 0
163 IPlugView* view = _vst3->view ();
164 if (view) {
165 view->onFocus (true);
166 }
167 #endif
168 }
169