Audio plugin host https://kx.studio/carla
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

246 lines
6.8KB

  1. /*
  2. * Carla Bridge UI
  3. * Copyright (C) 2014-2022 Filipe Coelho <falktx@falktx.com>
  4. *
  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.
  9. *
  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.
  14. *
  15. * For a full copy of the GNU General Public License see the doc/GPL.txt file.
  16. */
  17. #include "CarlaBridgeFormat.hpp"
  18. #include "CarlaBridgeToolkit.hpp"
  19. #include "CarlaMainLoop.hpp"
  20. #include "CarlaPluginUI.hpp"
  21. #include "CarlaUtils.h"
  22. #if defined(CARLA_OS_MAC) && defined(BRIDGE_COCOA)
  23. # include "CarlaMacUtils.hpp"
  24. #endif
  25. #if defined(HAVE_X11) && defined(BRIDGE_X11)
  26. # include <X11/Xlib.h>
  27. #endif
  28. CARLA_BRIDGE_UI_START_NAMESPACE
  29. using CARLA_BACKEND_NAMESPACE::runMainLoopOnce;
  30. // -------------------------------------------------------------------------
  31. class CarlaBridgeToolkitNative : public CarlaBridgeToolkit,
  32. private CarlaPluginUI::Callback
  33. {
  34. public:
  35. CarlaBridgeToolkitNative(CarlaBridgeFormat* const format)
  36. : CarlaBridgeToolkit(format),
  37. fHostUI(nullptr),
  38. fIdling(false)
  39. {
  40. carla_debug("CarlaBridgeToolkitNative::CarlaBridgeToolkitNative(%p)", format);
  41. }
  42. ~CarlaBridgeToolkitNative() override
  43. {
  44. CARLA_SAFE_ASSERT_RETURN(fHostUI == nullptr,);
  45. carla_debug("CarlaBridgeToolkitNative::~CarlaBridgeToolkitNative()");
  46. }
  47. bool init(const int /*argc*/, const char** /*argv[]*/) override
  48. {
  49. CARLA_SAFE_ASSERT_RETURN(fHostUI == nullptr, false);
  50. carla_debug("CarlaBridgeToolkitNative::init()");
  51. const CarlaBridgeFormat::Options& options(fPlugin->getOptions());
  52. #if defined(CARLA_OS_MAC) && defined(BRIDGE_COCOA)
  53. CARLA_BACKEND_NAMESPACE::initStandaloneApplication();
  54. fHostUI = CarlaPluginUI::newCocoa(this, 0, options.isStandalone, options.isResizable);
  55. #elif defined(CARLA_OS_WIN) && defined(BRIDGE_HWND)
  56. fHostUI = CarlaPluginUI::newWindows(this, 0, options.isStandalone, options.isResizable);
  57. #elif defined(HAVE_X11) && defined(BRIDGE_X11)
  58. XInitThreads();
  59. fHostUI = CarlaPluginUI::newX11(this, 0, options.isStandalone, options.isResizable, true);
  60. #endif
  61. CARLA_SAFE_ASSERT_RETURN(fHostUI != nullptr, false);
  62. #ifndef CARLA_OS_MAC
  63. if (options.isStandalone)
  64. fPlugin->setScaleFactor(carla_get_desktop_scale_factor());
  65. #endif
  66. fHostUI->setTitle(options.windowTitle.buffer());
  67. #ifndef CARLA_OS_MAC
  68. if (options.transientWindowId != 0)
  69. {
  70. fHostUI->setTransientWinId(options.transientWindowId);
  71. }
  72. else if (const char* const winIdStr = std::getenv("ENGINE_OPTION_FRONTEND_WIN_ID"))
  73. {
  74. if (const long long winId = std::strtoll(winIdStr, nullptr, 16))
  75. fHostUI->setTransientWinId(static_cast<uintptr_t>(winId));
  76. }
  77. #endif
  78. return true;
  79. }
  80. void exec(const bool showUI) override
  81. {
  82. CARLA_SAFE_ASSERT_RETURN(fPlugin != nullptr,);
  83. CARLA_SAFE_ASSERT_RETURN(fHostUI != nullptr,);
  84. carla_debug("CarlaBridgeToolkitNative::exec(%s)", bool2str(showUI));
  85. if (showUI)
  86. {
  87. fHostUI->show();
  88. fHostUI->focus();
  89. }
  90. fIdling = true;
  91. for (; runMainLoopOnce() && fIdling;)
  92. {
  93. if (fPlugin->isPipeRunning())
  94. fPlugin->idlePipe();
  95. fPlugin->idleUI();
  96. fHostUI->idle();
  97. #if defined(CARLA_OS_MAC) || defined(CARLA_OS_WIN)
  98. // MacOS and Win32 have event-loops to run, so minimize sleep time
  99. carla_msleep(1);
  100. #else
  101. carla_msleep(33);
  102. #endif
  103. }
  104. }
  105. void quit() override
  106. {
  107. carla_debug("CarlaBridgeToolkitNative::quit()");
  108. fIdling = false;
  109. if (fHostUI != nullptr)
  110. {
  111. fHostUI->hide();
  112. delete fHostUI;
  113. fHostUI = nullptr;
  114. }
  115. }
  116. void show() override
  117. {
  118. CARLA_SAFE_ASSERT_RETURN(fHostUI != nullptr,);
  119. carla_debug("CarlaBridgeToolkitNative::show()");
  120. fHostUI->show();
  121. }
  122. void focus() override
  123. {
  124. CARLA_SAFE_ASSERT_RETURN(fHostUI != nullptr,);
  125. carla_debug("CarlaBridgeToolkitNative::focus()");
  126. fHostUI->focus();
  127. }
  128. void hide() override
  129. {
  130. CARLA_SAFE_ASSERT_RETURN(fHostUI != nullptr,);
  131. carla_debug("CarlaBridgeToolkitNative::hide()");
  132. fHostUI->hide();
  133. }
  134. void setChildWindow(void* const ptr) override
  135. {
  136. CARLA_SAFE_ASSERT_RETURN(fHostUI != nullptr,);
  137. CARLA_SAFE_ASSERT_RETURN(ptr != nullptr,);
  138. carla_debug("CarlaBridgeToolkitNative::setChildWindow(%p)", ptr);
  139. fHostUI->setChildWindow(ptr);
  140. }
  141. void setSize(const uint width, const uint height) override
  142. {
  143. CARLA_SAFE_ASSERT_RETURN(fHostUI != nullptr,);
  144. CARLA_SAFE_ASSERT_RETURN(width > 0,);
  145. CARLA_SAFE_ASSERT_RETURN(height > 0,);
  146. carla_debug("CarlaBridgeToolkitNative::resize(%i, %i)", width, height);
  147. fHostUI->setSize(width, height, false);
  148. }
  149. void setTitle(const char* const title) override
  150. {
  151. CARLA_SAFE_ASSERT_RETURN(fHostUI != nullptr,);
  152. carla_debug("CarlaBridgeToolkitNative::setTitle(\"%s\")", title);
  153. fHostUI->setTitle(title);
  154. }
  155. void* getContainerId() const override
  156. {
  157. CARLA_SAFE_ASSERT_RETURN(fHostUI != nullptr, nullptr);
  158. return fHostUI->getPtr();
  159. }
  160. #ifdef HAVE_X11
  161. void* getContainerId2() const override
  162. {
  163. CARLA_SAFE_ASSERT_RETURN(fHostUI != nullptr, nullptr);
  164. return fHostUI->getDisplay();
  165. }
  166. #endif
  167. // ---------------------------------------------------------------------
  168. protected:
  169. void handlePluginUIClosed() override
  170. {
  171. fIdling = false;
  172. }
  173. void handlePluginUIResized(const uint width, const uint height) override
  174. {
  175. fPlugin->uiResized(width, height);
  176. }
  177. // ---------------------------------------------------------------------
  178. private:
  179. CarlaPluginUI* fHostUI;
  180. bool fIdling;
  181. CARLA_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR(CarlaBridgeToolkitNative)
  182. };
  183. // -------------------------------------------------------------------------
  184. CarlaBridgeToolkit* CarlaBridgeToolkit::createNew(CarlaBridgeFormat* const format)
  185. {
  186. return new CarlaBridgeToolkitNative(format);
  187. }
  188. // -------------------------------------------------------------------------
  189. CARLA_BRIDGE_UI_END_NAMESPACE
  190. #define CARLA_PLUGIN_UI_CLASS_PREFIX ToolkitNative
  191. #include "CarlaPluginUI.cpp"
  192. #include "utils/Windows.cpp"
  193. // -------------------------------------------------------------------------