Rename a pipe method, add docs
[carla.git] / source / utils / JucePluginWindow.hpp
blobe7f644834c4cc77a81f3a0d69a51b7b11cb7b1ac
1 /*
2 * Juce Plugin Window Helper
3 * Copyright (C) 2013-2021 Filipe Coelho <falktx@falktx.com>
5 * This program is free software; you can redistribute it and/or
6 * modify it under the terms of the GNU General Public License as
7 * published by the Free Software Foundation; either version 2 of
8 * the License, or any later version.
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
15 * For a full copy of the GNU General Public License see the doc/GPL.txt file.
18 #ifndef JUCE_PLUGIN_WINDOW_HPP_INCLUDED
19 #define JUCE_PLUGIN_WINDOW_HPP_INCLUDED
21 #include "CarlaJuceUtils.hpp"
22 #include "CarlaVst2Utils.hpp"
23 #include "CarlaVst3Utils.hpp"
25 #include "AppConfig.h"
26 #include "juce_gui_basics/juce_gui_basics.h"
28 #if defined(CARLA_OS_LINUX) && defined(HAVE_X11)
29 # include <X11/Xlib.h>
30 #elif defined(CARLA_OS_MAC)
31 # ifdef __MAC_10_12
32 # define Component CocoaComponent
33 # define MemoryBlock CocoaMemoryBlock
34 # define Point CocoaPoint
35 # endif
36 # import <Cocoa/Cocoa.h>
37 # undef Component
38 # undef MemoryBlock
39 # undef Point
40 #endif
42 // -----------------------------------------------------------------------
44 namespace juce {
46 class JucePluginWindow : public DialogWindow
48 public:
49 JucePluginWindow(const uintptr_t parentId, const bool isStandalone,
50 AEffect* const vst2effect, v3_plugin_view** const vst3view)
51 : DialogWindow("JucePluginWindow", Colour(50, 50, 200), true, false),
52 fIsStandalone(isStandalone),
53 fClosed(false),
54 fShown(false),
55 fTransientId(parentId),
56 fLastKeys(),
57 fVst2Effect(vst2effect),
58 fVst3View(vst3view)
60 carla_zeroStruct(fLastKeys);
61 setVisible(false);
62 setOpaque(true);
63 setResizable(false, false);
64 setUsingNativeTitleBar(true);
67 void show(Component* const comp)
69 fClosed = false;
70 fShown = true;
72 centreWithSize(comp->getWidth(), comp->getHeight());
73 setContentNonOwned(comp, true);
75 if (! isOnDesktop())
76 addToDesktop();
78 #ifndef CARLA_OS_LINUX
79 setAlwaysOnTop(true);
80 #endif
81 setTransient();
82 setVisible(true);
83 toFront(true);
85 #ifndef CARLA_OS_LINUX
86 postCommandMessage(0);
87 #endif
90 bool keyPressed (const KeyPress& key) override
92 if (DialogWindow::keyPressed (key))
93 return true;
95 if (fVst2Effect != nullptr)
97 const int juceKeyCode = key.getKeyCode();
98 int vstKeyIndex = 0;
99 int vstKeyValue = 0;
101 do {
102 /**/ if (juceKeyCode == KeyPress::spaceKey) vstKeyValue = 7;
103 else if (juceKeyCode == KeyPress::escapeKey) vstKeyValue = 6;
104 else if (juceKeyCode == KeyPress::returnKey) vstKeyValue = 19; // NOTE: 4 is '\r' while 19 is '\n'
105 else if (juceKeyCode == KeyPress::tabKey) vstKeyValue = 2;
107 else if (juceKeyCode == KeyPress::deleteKey) vstKeyValue = 22;
108 else if (juceKeyCode == KeyPress::backspaceKey) vstKeyValue = 1;
109 else if (juceKeyCode == KeyPress::insertKey) vstKeyValue = 21;
111 else if (juceKeyCode == KeyPress::upKey) vstKeyValue = 12;
112 else if (juceKeyCode == KeyPress::downKey) vstKeyValue = 14;
113 else if (juceKeyCode == KeyPress::leftKey) vstKeyValue = 11;
114 else if (juceKeyCode == KeyPress::rightKey) vstKeyValue = 13;
115 else if (juceKeyCode == KeyPress::pageUpKey) vstKeyValue = 15;
116 else if (juceKeyCode == KeyPress::pageDownKey) vstKeyValue = 16;
117 else if (juceKeyCode == KeyPress::homeKey) vstKeyValue = 10;
118 else if (juceKeyCode == KeyPress::endKey) vstKeyValue = 9;
120 else if (juceKeyCode == KeyPress::F1Key) vstKeyValue = 40;
121 else if (juceKeyCode == KeyPress::F2Key) vstKeyValue = 41;
122 else if (juceKeyCode == KeyPress::F3Key) vstKeyValue = 42;
123 else if (juceKeyCode == KeyPress::F4Key) vstKeyValue = 43;
124 else if (juceKeyCode == KeyPress::F5Key) vstKeyValue = 44;
125 else if (juceKeyCode == KeyPress::F6Key) vstKeyValue = 45;
126 else if (juceKeyCode == KeyPress::F7Key) vstKeyValue = 46;
127 else if (juceKeyCode == KeyPress::F8Key) vstKeyValue = 47;
128 else if (juceKeyCode == KeyPress::F9Key) vstKeyValue = 48;
129 else if (juceKeyCode == KeyPress::F10Key) vstKeyValue = 49;
130 else if (juceKeyCode == KeyPress::F11Key) vstKeyValue = 50;
131 else if (juceKeyCode == KeyPress::F12Key) vstKeyValue = 51;
133 else if (juceKeyCode == KeyPress::F13Key) break;
134 else if (juceKeyCode == KeyPress::F14Key) break;
135 else if (juceKeyCode == KeyPress::F15Key) break;
136 else if (juceKeyCode == KeyPress::F16Key) break;
137 else if (juceKeyCode == KeyPress::F17Key) break;
138 else if (juceKeyCode == KeyPress::F18Key) break;
139 else if (juceKeyCode == KeyPress::F19Key) break;
140 else if (juceKeyCode == KeyPress::F20Key) break;
141 else if (juceKeyCode == KeyPress::F21Key) break;
142 else if (juceKeyCode == KeyPress::F22Key) break;
143 else if (juceKeyCode == KeyPress::F23Key) break;
144 else if (juceKeyCode == KeyPress::F24Key) break;
145 else if (juceKeyCode == KeyPress::F25Key) break;
146 else if (juceKeyCode == KeyPress::F26Key) break;
147 else if (juceKeyCode == KeyPress::F27Key) break;
148 else if (juceKeyCode == KeyPress::F28Key) break;
149 else if (juceKeyCode == KeyPress::F29Key) break;
150 else if (juceKeyCode == KeyPress::F30Key) break;
151 else if (juceKeyCode == KeyPress::F31Key) break;
152 else if (juceKeyCode == KeyPress::F32Key) break;
153 else if (juceKeyCode == KeyPress::F33Key) break;
154 else if (juceKeyCode == KeyPress::F34Key) break;
155 else if (juceKeyCode == KeyPress::F35Key) break;
157 else if (juceKeyCode == KeyPress::numberPad0) vstKeyValue = 24;
158 else if (juceKeyCode == KeyPress::numberPad1) vstKeyValue = 25;
159 else if (juceKeyCode == KeyPress::numberPad2) vstKeyValue = 26;
160 else if (juceKeyCode == KeyPress::numberPad3) vstKeyValue = 27;
161 else if (juceKeyCode == KeyPress::numberPad4) vstKeyValue = 28;
162 else if (juceKeyCode == KeyPress::numberPad5) vstKeyValue = 29;
163 else if (juceKeyCode == KeyPress::numberPad6) vstKeyValue = 30;
164 else if (juceKeyCode == KeyPress::numberPad7) vstKeyValue = 31;
165 else if (juceKeyCode == KeyPress::numberPad8) vstKeyValue = 32;
166 else if (juceKeyCode == KeyPress::numberPad9) vstKeyValue = 33;
168 else if (juceKeyCode == KeyPress::numberPadAdd) vstKeyValue = 35;
169 else if (juceKeyCode == KeyPress::numberPadSubtract) vstKeyValue = 37;
170 else if (juceKeyCode == KeyPress::numberPadMultiply) vstKeyValue = 34;
171 else if (juceKeyCode == KeyPress::numberPadDivide) vstKeyValue = 39;
172 else if (juceKeyCode == KeyPress::numberPadSeparator) vstKeyValue = 36;
173 else if (juceKeyCode == KeyPress::numberPadDecimalPoint) vstKeyValue = 38;
174 else if (juceKeyCode == KeyPress::numberPadEquals) vstKeyValue = 57;
176 else if (juceKeyCode == KeyPress::numberPadDelete) break;
178 else if (juceKeyCode == KeyPress::playKey) break;
179 else if (juceKeyCode == KeyPress::stopKey) break;
180 else if (juceKeyCode == KeyPress::fastForwardKey) break;
181 else if (juceKeyCode == KeyPress::rewindKey) break;
183 else vstKeyIndex = juceKeyCode;
184 } while (false);
186 fLastKeys.vst2.index = vstKeyIndex;
187 fLastKeys.vst2.value = vstKeyValue;
188 return fVst2Effect->dispatcher (fVst2Effect, effEditKeyDown, vstKeyIndex, vstKeyValue, nullptr, 0.0f) != 0;
191 if (fVst3View != nullptr)
193 const int juceKeyCode = key.getKeyCode();
194 const int juceKeyMods = key.getModifiers().getRawFlags();
195 int16_t vst3KeyChar = 0;
196 int16_t vst3KeyCode = 0;
197 int16_t vst3KeyMods = 0;
199 // KEY_NEXT 8
200 // KEY_SELECT 17
201 // KEY_SELECT 18
202 // KEY_SNAPSHOT 20
203 // KEY_HELP 23
204 // KEY_NUMLOCK 52
205 // KEY_SCROLL 53
206 // KEY_VOLUME_UP 63
207 // KEY_VOLUME_DOWN 64
209 do {
210 /**/ if (juceKeyCode == KeyPress::spaceKey)
212 vst3KeyChar = ' ';
213 vst3KeyCode = 7;
215 else if (juceKeyCode == KeyPress::escapeKey)
217 vst3KeyCode = 6;
219 else if (juceKeyCode == KeyPress::returnKey)
221 vst3KeyChar = '\n';
222 vst3KeyCode = 19; // NOTE: 4 is '\r' while 19 is '\n'
224 else if (juceKeyCode == KeyPress::tabKey)
226 vst3KeyChar = '\t';
227 vst3KeyCode = 2;
230 else if (juceKeyCode == KeyPress::deleteKey) vst3KeyCode = 22;
231 else if (juceKeyCode == KeyPress::backspaceKey) vst3KeyCode = 1;
232 else if (juceKeyCode == KeyPress::insertKey) vst3KeyCode = 21;
234 else if (juceKeyCode == KeyPress::upKey) vst3KeyCode = 12;
235 else if (juceKeyCode == KeyPress::downKey) vst3KeyCode = 14;
236 else if (juceKeyCode == KeyPress::leftKey) vst3KeyCode = 11;
237 else if (juceKeyCode == KeyPress::rightKey) vst3KeyCode = 13;
238 else if (juceKeyCode == KeyPress::pageUpKey) vst3KeyCode = 15;
239 else if (juceKeyCode == KeyPress::pageDownKey) vst3KeyCode = 16;
240 else if (juceKeyCode == KeyPress::homeKey) vst3KeyCode = 10;
241 else if (juceKeyCode == KeyPress::endKey) vst3KeyCode = 9;
243 else if (juceKeyCode == KeyPress::F1Key) vst3KeyCode = 40;
244 else if (juceKeyCode == KeyPress::F2Key) vst3KeyCode = 41;
245 else if (juceKeyCode == KeyPress::F3Key) vst3KeyCode = 42;
246 else if (juceKeyCode == KeyPress::F4Key) vst3KeyCode = 43;
247 else if (juceKeyCode == KeyPress::F5Key) vst3KeyCode = 44;
248 else if (juceKeyCode == KeyPress::F6Key) vst3KeyCode = 45;
249 else if (juceKeyCode == KeyPress::F7Key) vst3KeyCode = 46;
250 else if (juceKeyCode == KeyPress::F8Key) vst3KeyCode = 47;
251 else if (juceKeyCode == KeyPress::F9Key) vst3KeyCode = 48;
252 else if (juceKeyCode == KeyPress::F10Key) vst3KeyCode = 49;
253 else if (juceKeyCode == KeyPress::F11Key) vst3KeyCode = 50;
254 else if (juceKeyCode == KeyPress::F12Key) vst3KeyCode = 51;
256 else if (juceKeyCode == KeyPress::F13Key) vst3KeyCode = 65;
257 else if (juceKeyCode == KeyPress::F14Key) vst3KeyCode = 66;
258 else if (juceKeyCode == KeyPress::F15Key) vst3KeyCode = 67;
259 else if (juceKeyCode == KeyPress::F16Key) vst3KeyCode = 68;
260 else if (juceKeyCode == KeyPress::F17Key) vst3KeyCode = 69;
261 else if (juceKeyCode == KeyPress::F18Key) vst3KeyCode = 70;
262 else if (juceKeyCode == KeyPress::F19Key) vst3KeyCode = 71;
263 else if (juceKeyCode == KeyPress::F20Key) break;
264 else if (juceKeyCode == KeyPress::F21Key) break;
265 else if (juceKeyCode == KeyPress::F22Key) break;
266 else if (juceKeyCode == KeyPress::F23Key) break;
267 else if (juceKeyCode == KeyPress::F24Key) break;
268 else if (juceKeyCode == KeyPress::F25Key) break;
269 else if (juceKeyCode == KeyPress::F26Key) break;
270 else if (juceKeyCode == KeyPress::F27Key) break;
271 else if (juceKeyCode == KeyPress::F28Key) break;
272 else if (juceKeyCode == KeyPress::F29Key) break;
273 else if (juceKeyCode == KeyPress::F30Key) break;
274 else if (juceKeyCode == KeyPress::F31Key) break;
275 else if (juceKeyCode == KeyPress::F32Key) break;
276 else if (juceKeyCode == KeyPress::F33Key) break;
277 else if (juceKeyCode == KeyPress::F34Key) break;
278 else if (juceKeyCode == KeyPress::F35Key) break;
280 else if (juceKeyCode == KeyPress::numberPad0) vst3KeyCode = 24;
281 else if (juceKeyCode == KeyPress::numberPad1) vst3KeyCode = 25;
282 else if (juceKeyCode == KeyPress::numberPad2) vst3KeyCode = 26;
283 else if (juceKeyCode == KeyPress::numberPad3) vst3KeyCode = 27;
284 else if (juceKeyCode == KeyPress::numberPad4) vst3KeyCode = 28;
285 else if (juceKeyCode == KeyPress::numberPad5) vst3KeyCode = 29;
286 else if (juceKeyCode == KeyPress::numberPad6) vst3KeyCode = 30;
287 else if (juceKeyCode == KeyPress::numberPad7) vst3KeyCode = 31;
288 else if (juceKeyCode == KeyPress::numberPad8) vst3KeyCode = 32;
289 else if (juceKeyCode == KeyPress::numberPad9) vst3KeyCode = 33;
291 else if (juceKeyCode == KeyPress::numberPadAdd) vst3KeyCode = 35;
292 else if (juceKeyCode == KeyPress::numberPadSubtract) vst3KeyCode = 37;
293 else if (juceKeyCode == KeyPress::numberPadMultiply) vst3KeyCode = 34;
294 else if (juceKeyCode == KeyPress::numberPadDivide) vst3KeyCode = 39;
295 else if (juceKeyCode == KeyPress::numberPadSeparator) vst3KeyCode = 36;
296 else if (juceKeyCode == KeyPress::numberPadDecimalPoint) vst3KeyCode = 38;
297 else if (juceKeyCode == KeyPress::numberPadEquals) vst3KeyCode = 57;
299 else if (juceKeyCode == KeyPress::numberPadDelete) break;
301 else if (juceKeyCode == KeyPress::playKey) vst3KeyCode = 59;
302 else if (juceKeyCode == KeyPress::stopKey) vst3KeyCode = 60;
303 else if (juceKeyCode == KeyPress::fastForwardKey) vst3KeyCode = 62;
304 else if (juceKeyCode == KeyPress::rewindKey) vst3KeyCode = 61;
306 else
308 vst3KeyChar = static_cast<int16_t>(juceKeyCode);
310 if ((juceKeyCode >= 0x30 && juceKeyCode <= 0x39) || (juceKeyCode >= 0x41 && juceKeyCode <= 0x5A))
311 vst3KeyCode = static_cast<int16_t>(juceKeyCode - 0x30 + 128);
313 } while (false);
315 if (juceKeyMods & ModifierKeys::shiftModifier)
316 vst3KeyMods |= 1 << 0;
317 if (juceKeyMods & ModifierKeys::altModifier)
318 vst3KeyMods |= 1 << 1;
319 if (juceKeyMods & ModifierKeys::commandModifier)
320 vst3KeyMods |= 1 << 2;
321 #if JUCE_MAC || JUCE_IOS
322 if (juceKeyMods & ModifierKeys::ctrlModifier)
323 vst3KeyMods |= 1 << 3;
324 #endif
326 fLastKeys.vst3.keychar = vst3KeyChar;
327 fLastKeys.vst3.keycode = vst3KeyCode;
328 fLastKeys.vst3.keymods = vst3KeyMods;
329 return v3_cpp_obj(fVst3View)->on_key_down (fVst3View, vst3KeyChar, vst3KeyCode, vst3KeyMods) == V3_TRUE;
332 if (Component* const comp = getContentComponent())
333 return comp->keyPressed (key);
335 return false;
338 bool keyStateChanged (bool isKeyDown) override
340 if (DialogWindow::keyStateChanged (isKeyDown))
341 return true;
343 if (fVst2Effect != nullptr && (fLastKeys.vst2.index != 0 || fLastKeys.vst2.value != 0) && ! isKeyDown)
345 const int vstKeyIndex = fLastKeys.vst2.index;
346 const int vstKeyValue = fLastKeys.vst2.value;
347 fLastKeys.vst2.index = fLastKeys.vst2.value = 0;
348 return fVst2Effect->dispatcher (fVst2Effect, effEditKeyUp, vstKeyIndex, vstKeyValue, nullptr, 0.0f) != 0;
351 if (fVst3View != nullptr && (fLastKeys.vst3.keychar != 0 || fLastKeys.vst3.keycode != 0) && ! isKeyDown)
353 const int16_t vst3KeyChar = fLastKeys.vst3.keychar;
354 const int16_t vst3KeyCode = fLastKeys.vst3.keycode;
355 const int16_t vst3KeyMods = fLastKeys.vst3.keymods;
356 fLastKeys.vst3.keychar = fLastKeys.vst3.keycode = fLastKeys.vst3.keymods = 0;
357 return v3_cpp_obj(fVst3View)->on_key_up (fVst3View, vst3KeyChar, vst3KeyCode, vst3KeyMods) == V3_TRUE;
360 if (Component* const comp = getContentComponent())
361 return comp->keyStateChanged (isKeyDown);
363 return false;
366 void modifierKeysChanged (const ModifierKeys& modifiers) override
368 DialogWindow::modifierKeysChanged (modifiers);
370 if (fVst2Effect != nullptr)
372 const int oldRawFlags = fLastKeys.vst2.rmods;
373 const int newRawFlags = modifiers.getRawFlags();
375 if ((oldRawFlags & ModifierKeys::shiftModifier) != (newRawFlags & ModifierKeys::shiftModifier))
377 fVst2Effect->dispatcher (fVst2Effect,
378 (newRawFlags & ModifierKeys::shiftModifier) ? effEditKeyDown : effEditKeyUp,
379 0, 54, nullptr, 0.0f);
382 if ((oldRawFlags & ModifierKeys::ctrlModifier) != (newRawFlags & ModifierKeys::ctrlModifier))
384 fVst2Effect->dispatcher (fVst2Effect,
385 (newRawFlags & ModifierKeys::ctrlModifier) ? effEditKeyDown : effEditKeyUp,
386 0, 55, nullptr, 0.0f);
389 if ((oldRawFlags & ModifierKeys::altModifier) != (newRawFlags & ModifierKeys::altModifier))
391 fVst2Effect->dispatcher (fVst2Effect,
392 (newRawFlags & ModifierKeys::altModifier) ? effEditKeyDown : effEditKeyUp,
393 0, 56, nullptr, 0.0f);
396 if ((oldRawFlags & ModifierKeys::popupMenuClickModifier) != (newRawFlags & ModifierKeys::popupMenuClickModifier))
398 fVst2Effect->dispatcher (fVst2Effect,
399 (newRawFlags & ModifierKeys::popupMenuClickModifier) ? effEditKeyDown : effEditKeyUp,
400 0, 58, nullptr, 0.0f);
403 fLastKeys.vst2.rmods = newRawFlags;
406 if (fVst3View != nullptr)
408 const int oldRawFlags = fLastKeys.vst3.rmods;
409 const int newRawFlags = modifiers.getRawFlags();
411 if ((oldRawFlags & ModifierKeys::shiftModifier) != (newRawFlags & ModifierKeys::shiftModifier))
413 if (newRawFlags & ModifierKeys::shiftModifier)
414 v3_cpp_obj(fVst3View)->on_key_down (fVst3View, 0, 54, fLastKeys.vst3.keymods);
415 else
416 v3_cpp_obj(fVst3View)->on_key_up (fVst3View, 0, 54, fLastKeys.vst3.keymods);
419 if ((oldRawFlags & ModifierKeys::ctrlModifier) != (newRawFlags & ModifierKeys::ctrlModifier))
421 if (newRawFlags & ModifierKeys::ctrlModifier)
422 v3_cpp_obj(fVst3View)->on_key_down (fVst3View, 0, 55, fLastKeys.vst3.keymods);
423 else
424 v3_cpp_obj(fVst3View)->on_key_up (fVst3View, 0, 55, fLastKeys.vst3.keymods);
427 if ((oldRawFlags & ModifierKeys::altModifier) != (newRawFlags & ModifierKeys::altModifier))
429 if (newRawFlags & ModifierKeys::altModifier)
430 v3_cpp_obj(fVst3View)->on_key_down (fVst3View, 0, 56, fLastKeys.vst3.keymods);
431 else
432 v3_cpp_obj(fVst3View)->on_key_up (fVst3View, 0, 56, fLastKeys.vst3.keymods);
435 if ((oldRawFlags & ModifierKeys::popupMenuClickModifier) != (newRawFlags & ModifierKeys::popupMenuClickModifier))
437 if (newRawFlags & ModifierKeys::popupMenuClickModifier)
438 v3_cpp_obj(fVst3View)->on_key_down (fVst3View, 0, 58, fLastKeys.vst3.keymods);
439 else
440 v3_cpp_obj(fVst3View)->on_key_up (fVst3View, 0, 58, fLastKeys.vst3.keymods);
443 fLastKeys.vst3.rmods = newRawFlags;
447 void focusGained (const FocusChangeType cause) override
449 DialogWindow::focusGained (cause);
451 if (fVst3View != nullptr)
452 v3_cpp_obj(fVst3View)->on_focus (fVst3View, true);
455 void focusLost (const FocusChangeType cause) override
457 if (fVst3View != nullptr)
458 v3_cpp_obj(fVst3View)->on_focus (fVst3View, false);
460 DialogWindow::focusLost (cause);
463 void hide()
465 setVisible(false);
467 if (isOnDesktop())
468 removeFromDesktop();
470 clearContentComponent();
473 bool wasClosedByUser() const noexcept
475 return fClosed;
478 protected:
479 void closeButtonPressed() override
481 fClosed = true;
484 bool escapeKeyPressed() override
486 fClosed = true;
487 return true;
490 int getDesktopWindowStyleFlags() const override
492 int wflags = 0;
493 wflags |= ComponentPeer::windowHasCloseButton;
494 wflags |= ComponentPeer::windowHasDropShadow;
495 wflags |= ComponentPeer::windowHasTitleBar;
496 if (fIsStandalone)
497 wflags |= ComponentPeer::windowAppearsOnTaskbar;
498 return wflags;
501 #ifndef CARLA_OS_LINUX
502 void handleCommandMessage(const int comamndId) override
504 CARLA_SAFE_ASSERT_RETURN(comamndId == 0,);
506 if (fShown)
508 fShown = false;
509 setAlwaysOnTop(false);
512 #endif
514 private:
515 const bool fIsStandalone;
516 volatile bool fClosed;
517 bool fShown;
518 const uintptr_t fTransientId;
519 union {
520 struct {
521 int index;
522 int value;
523 int rmods;
524 } vst2;
526 struct {
527 int16_t keychar;
528 int16_t keycode;
529 int16_t keymods;
530 int rmods;
531 } vst3;
532 } fLastKeys;
533 AEffect* const fVst2Effect;
534 v3_plugin_view** const fVst3View;
536 void setTransient()
538 if (fTransientId == 0)
539 return;
541 #if defined(CARLA_OS_LINUX) && defined(HAVE_X11)
542 Display* const display = XWindowSystem::getInstance()->getDisplay();
543 CARLA_SAFE_ASSERT_RETURN(display != nullptr,);
545 ::Window window = (::Window)getWindowHandle();
547 CARLA_SAFE_ASSERT_RETURN(window != 0,);
549 XSetTransientForHint(display, window, static_cast<::Window>(fTransientId));
550 #endif
552 #ifdef CARLA_OS_MAC
553 NSView* const view = (NSView*)getWindowHandle();
554 CARLA_SAFE_ASSERT_RETURN(view != nullptr,);
556 NSWindow* const window = [view window];
557 CARLA_SAFE_ASSERT_RETURN(window != nullptr,);
559 NSWindow* const parentWindow = [NSApp windowWithWindowNumber:fTransientId];
560 CARLA_SAFE_ASSERT_RETURN(parentWindow != nullptr,);
562 [parentWindow addChildWindow:window
563 ordered:NSWindowAbove];
564 #endif
566 #ifdef CARLA_OS_WIN
567 const HWND window = (HWND)getWindowHandle();
568 CARLA_SAFE_ASSERT_RETURN(window != nullptr,);
570 SetWindowLongPtr(window, GWLP_HWNDPARENT, static_cast<LONG_PTR>(fTransientId));
571 #endif
574 CARLA_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR(JucePluginWindow)
577 } // namespace juce
579 using juce::JucePluginWindow;
581 // -----------------------------------------------------------------------
583 #endif // JUCE_PLUGIN_WINDOW_HPP_INCLUDED