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.

240 lines
6.7KB

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