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.

245 lines
6.8KB

  1. /*
  2. * Carla Bridge UI
  3. * Copyright (C) 2014-2021 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 CarlaBackend::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. CarlaBackend::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. if (options.isStandalone)
  63. fPlugin->setScaleFactor(carla_get_desktop_scale_factor());
  64. fHostUI->setTitle(options.windowTitle.buffer());
  65. #ifndef CARLA_OS_MAC
  66. if (options.transientWindowId != 0)
  67. {
  68. fHostUI->setTransientWinId(options.transientWindowId);
  69. }
  70. else if (const char* const winIdStr = std::getenv("ENGINE_OPTION_FRONTEND_WIN_ID"))
  71. {
  72. if (const long long winId = std::strtoll(winIdStr, nullptr, 16))
  73. fHostUI->setTransientWinId(static_cast<uintptr_t>(winId));
  74. }
  75. #endif
  76. return true;
  77. }
  78. void exec(const bool showUI) override
  79. {
  80. CARLA_SAFE_ASSERT_RETURN(fPlugin != nullptr,);
  81. CARLA_SAFE_ASSERT_RETURN(fHostUI != nullptr,);
  82. carla_debug("CarlaBridgeToolkitNative::exec(%s)", bool2str(showUI));
  83. if (showUI)
  84. {
  85. fHostUI->show();
  86. fHostUI->focus();
  87. }
  88. fIdling = true;
  89. for (; runMainLoopOnce() && fIdling;)
  90. {
  91. if (fPlugin->isPipeRunning())
  92. fPlugin->idlePipe();
  93. fPlugin->idleUI();
  94. fHostUI->idle();
  95. #if defined(CARLA_OS_MAC) || defined(CARLA_OS_WIN)
  96. // MacOS and Win32 have event-loops to run, so minimize sleep time
  97. carla_msleep(1);
  98. #else
  99. carla_msleep(33);
  100. #endif
  101. }
  102. }
  103. void quit() override
  104. {
  105. carla_debug("CarlaBridgeToolkitNative::quit()");
  106. fIdling = false;
  107. if (fHostUI != nullptr)
  108. {
  109. fHostUI->hide();
  110. delete fHostUI;
  111. fHostUI = nullptr;
  112. }
  113. }
  114. void show() override
  115. {
  116. CARLA_SAFE_ASSERT_RETURN(fHostUI != nullptr,);
  117. carla_debug("CarlaBridgeToolkitNative::show()");
  118. fHostUI->show();
  119. }
  120. void focus() override
  121. {
  122. CARLA_SAFE_ASSERT_RETURN(fHostUI != nullptr,);
  123. carla_debug("CarlaBridgeToolkitNative::focus()");
  124. fHostUI->focus();
  125. }
  126. void hide() override
  127. {
  128. CARLA_SAFE_ASSERT_RETURN(fHostUI != nullptr,);
  129. carla_debug("CarlaBridgeToolkitNative::hide()");
  130. fHostUI->hide();
  131. }
  132. void setChildWindow(void* const ptr) override
  133. {
  134. CARLA_SAFE_ASSERT_RETURN(fHostUI != nullptr,);
  135. CARLA_SAFE_ASSERT_RETURN(ptr != nullptr,);
  136. carla_debug("CarlaBridgeToolkitNative::setChildWindow(%p)", ptr);
  137. fHostUI->setChildWindow(ptr);
  138. }
  139. void setSize(const uint width, const uint height) override
  140. {
  141. CARLA_SAFE_ASSERT_RETURN(fHostUI != nullptr,);
  142. CARLA_SAFE_ASSERT_RETURN(width > 0,);
  143. CARLA_SAFE_ASSERT_RETURN(height > 0,);
  144. carla_debug("CarlaBridgeToolkitNative::resize(%i, %i)", width, height);
  145. fHostUI->setSize(width, height, false);
  146. }
  147. void setTitle(const char* const title) override
  148. {
  149. CARLA_SAFE_ASSERT_RETURN(fHostUI != nullptr,);
  150. carla_debug("CarlaBridgeToolkitNative::setTitle(\"%s\")", title);
  151. fHostUI->setTitle(title);
  152. }
  153. void* getContainerId() const override
  154. {
  155. CARLA_SAFE_ASSERT_RETURN(fHostUI != nullptr, nullptr);
  156. return fHostUI->getPtr();
  157. }
  158. #ifdef HAVE_X11
  159. void* getContainerId2() const override
  160. {
  161. CARLA_SAFE_ASSERT_RETURN(fHostUI != nullptr, nullptr);
  162. return fHostUI->getDisplay();
  163. }
  164. #endif
  165. // ---------------------------------------------------------------------
  166. protected:
  167. void handlePluginUIClosed() override
  168. {
  169. fIdling = false;
  170. }
  171. void handlePluginUIResized(const uint width, const uint height) override
  172. {
  173. fPlugin->uiResized(width, height);
  174. }
  175. // ---------------------------------------------------------------------
  176. private:
  177. CarlaPluginUI* fHostUI;
  178. bool fIdling;
  179. CARLA_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR(CarlaBridgeToolkitNative)
  180. };
  181. // -------------------------------------------------------------------------
  182. CarlaBridgeToolkit* CarlaBridgeToolkit::createNew(CarlaBridgeFormat* const format)
  183. {
  184. return new CarlaBridgeToolkitNative(format);
  185. }
  186. // -------------------------------------------------------------------------
  187. CARLA_BRIDGE_UI_END_NAMESPACE
  188. #define CARLA_PLUGIN_UI_CLASS_PREFIX ToolkitNative
  189. #include "CarlaPluginUI.cpp"
  190. #include "CarlaMacUtils.cpp"
  191. #include "utils/Windows.cpp"
  192. // -------------------------------------------------------------------------