3 * Copyright (C) 2014-2023 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 #include "CarlaBridgeFormat.hpp"
19 #include "CarlaBridgeToolkit.hpp"
21 #include "CarlaMainLoop.hpp"
22 #include "CarlaPluginUI.hpp"
23 #include "CarlaTimeUtils.hpp"
24 #include "CarlaUtils.h"
26 #if defined(CARLA_OS_MAC) && defined(BRIDGE_COCOA)
27 # include "CarlaMacUtils.hpp"
30 #if defined(HAVE_X11) && defined(BRIDGE_X11)
31 # include <X11/Xlib.h>
34 CARLA_BRIDGE_UI_START_NAMESPACE
36 using CARLA_BACKEND_NAMESPACE::runMainLoopOnce
;
38 // -------------------------------------------------------------------------
40 class CarlaBridgeToolkitNative
: public CarlaBridgeToolkit
,
41 private CarlaPluginUI::Callback
44 CarlaBridgeToolkitNative(CarlaBridgeFormat
* const format
)
45 : CarlaBridgeToolkit(format
),
49 carla_debug("CarlaBridgeToolkitNative::CarlaBridgeToolkitNative(%p)", format
);
52 ~CarlaBridgeToolkitNative() override
54 CARLA_SAFE_ASSERT_RETURN(fHostUI
== nullptr,);
55 carla_debug("CarlaBridgeToolkitNative::~CarlaBridgeToolkitNative()");
58 bool init(const int /*argc*/, const char** /*argv[]*/) override
60 CARLA_SAFE_ASSERT_RETURN(fHostUI
== nullptr, false);
61 carla_debug("CarlaBridgeToolkitNative::init()");
63 const CarlaBridgeFormat::Options
& options(fPlugin
->getOptions());
65 #if defined(CARLA_OS_MAC) && defined(BRIDGE_COCOA)
66 CARLA_BACKEND_NAMESPACE::initStandaloneApplication();
67 fHostUI
= CarlaPluginUI::newCocoa(this, 0, options
.isStandalone
, options
.isResizable
);
68 #elif defined(CARLA_OS_WIN) && defined(BRIDGE_HWND)
69 fHostUI
= CarlaPluginUI::newWindows(this, 0, options
.isStandalone
, options
.isResizable
);
70 #elif defined(HAVE_X11) && defined(BRIDGE_X11)
72 fHostUI
= CarlaPluginUI::newX11(this, 0, options
.isStandalone
, options
.isResizable
, true);
74 CARLA_SAFE_ASSERT_RETURN(fHostUI
!= nullptr, false);
77 if (options
.isStandalone
)
78 fPlugin
->setScaleFactor(carla_get_desktop_scale_factor());
81 fHostUI
->setTitle(options
.windowTitle
.buffer());
84 if (options
.transientWindowId
!= 0)
86 fHostUI
->setTransientWinId(options
.transientWindowId
);
88 else if (const char* const winIdStr
= std::getenv("ENGINE_OPTION_FRONTEND_WIN_ID"))
90 if (const long long winId
= std::strtoll(winIdStr
, nullptr, 16))
91 fHostUI
->setTransientWinId(static_cast<uintptr_t>(winId
));
98 void exec(const bool showUI
) override
100 CARLA_SAFE_ASSERT_RETURN(fPlugin
!= nullptr,);
101 CARLA_SAFE_ASSERT_RETURN(fHostUI
!= nullptr,);
102 carla_debug("CarlaBridgeToolkitNative::exec(%s)", bool2str(showUI
));
112 for (; runMainLoopOnce() && fIdling
;)
114 if (fPlugin
->isPipeRunning())
119 #if defined(CARLA_OS_MAC) || defined(CARLA_OS_WIN)
120 // MacOS and Win32 have event-loops to run, so minimize sleep time
130 carla_debug("CarlaBridgeToolkitNative::quit()");
134 if (fHostUI
!= nullptr)
144 CARLA_SAFE_ASSERT_RETURN(fHostUI
!= nullptr,);
145 carla_debug("CarlaBridgeToolkitNative::show()");
150 void focus() override
152 CARLA_SAFE_ASSERT_RETURN(fHostUI
!= nullptr,);
153 carla_debug("CarlaBridgeToolkitNative::focus()");
160 CARLA_SAFE_ASSERT_RETURN(fHostUI
!= nullptr,);
161 carla_debug("CarlaBridgeToolkitNative::hide()");
166 void setChildWindow(void* const ptr
) override
168 CARLA_SAFE_ASSERT_RETURN(fHostUI
!= nullptr,);
169 CARLA_SAFE_ASSERT_RETURN(ptr
!= nullptr,);
170 carla_debug("CarlaBridgeToolkitNative::setChildWindow(%p)", ptr
);
172 fHostUI
->setChildWindow(ptr
);
175 void setSize(const uint width
, const uint height
) override
177 CARLA_SAFE_ASSERT_RETURN(fHostUI
!= nullptr,);
178 CARLA_SAFE_ASSERT_RETURN(width
> 0,);
179 CARLA_SAFE_ASSERT_RETURN(height
> 0,);
180 carla_debug("CarlaBridgeToolkitNative::resize(%i, %i)", width
, height
);
182 fHostUI
->setSize(width
, height
, false, false);
185 void setTitle(const char* const title
) override
187 CARLA_SAFE_ASSERT_RETURN(fHostUI
!= nullptr,);
188 carla_debug("CarlaBridgeToolkitNative::setTitle(\"%s\")", title
);
190 fHostUI
->setTitle(title
);
193 void* getContainerId() const override
195 CARLA_SAFE_ASSERT_RETURN(fHostUI
!= nullptr, nullptr);
197 return fHostUI
->getPtr();
201 void* getContainerId2() const override
203 CARLA_SAFE_ASSERT_RETURN(fHostUI
!= nullptr, nullptr);
205 return fHostUI
->getDisplay();
209 // ---------------------------------------------------------------------
212 void handlePluginUIClosed() override
217 void handlePluginUIResized(const uint width
, const uint height
) override
219 fPlugin
->uiResized(width
, height
);
222 // ---------------------------------------------------------------------
225 CarlaPluginUI
* fHostUI
;
228 CARLA_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR(CarlaBridgeToolkitNative
)
231 // -------------------------------------------------------------------------
233 CarlaBridgeToolkit
* CarlaBridgeToolkit::createNew(CarlaBridgeFormat
* const format
)
235 return new CarlaBridgeToolkitNative(format
);
238 // -------------------------------------------------------------------------
240 CARLA_BRIDGE_UI_END_NAMESPACE
242 #define CARLA_PLUGIN_UI_CLASS_PREFIX ToolkitNative
243 #include "CarlaPluginUI.cpp"
244 #include "utils/Windows.cpp"
246 // -------------------------------------------------------------------------