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.

carla_juce.cpp 4.3KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184
  1. /*
  2. * Carla Plugin Host
  3. * Copyright (C) 2011-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. #ifndef USING_JUCE
  18. # error this file is not meant to be built if not using juce!
  19. #endif
  20. #include "carla_juce.h"
  21. #include "CarlaUtils.hpp"
  22. #include "juce_events/juce_events.h"
  23. #if defined(CARLA_OS_MAC) || defined(CARLA_OS_WIN)
  24. # include "juce_gui_basics/juce_gui_basics.h"
  25. #endif
  26. namespace juce {
  27. bool dispatchNextMessageOnSystemQueue(bool returnIfNoPendingMessages);
  28. }
  29. namespace CarlaJUCE {
  30. void initialiseJuce_GUI()
  31. {
  32. juce::initialiseJuce_GUI();
  33. #if !(defined(CARLA_OS_MAC) || defined(CARLA_OS_WIN))
  34. juce::MessageManager::getInstance()->setCurrentThreadAsMessageThread();
  35. #endif
  36. }
  37. void idleJuce_GUI()
  38. {
  39. #if !(defined(CARLA_OS_MAC) || defined(CARLA_OS_WIN))
  40. juce::dispatchNextMessageOnSystemQueue(true);
  41. #endif
  42. }
  43. void shutdownJuce_GUI()
  44. {
  45. juce::shutdownJuce_GUI();
  46. }
  47. const char* getVersion()
  48. {
  49. static const juce::String version(juce::SystemStats::getJUCEVersion());
  50. return version.toRawUTF8();
  51. }
  52. static int numScopedInitInstances = 0;
  53. ScopedJuceInitialiser_GUI::ScopedJuceInitialiser_GUI()
  54. {
  55. if (numScopedInitInstances++ == 0)
  56. initialiseJuce_GUI();
  57. }
  58. ScopedJuceInitialiser_GUI::~ScopedJuceInitialiser_GUI()
  59. {
  60. if (--numScopedInitInstances == 0)
  61. shutdownJuce_GUI();
  62. }
  63. #ifdef USE_REFCOUNTER_JUCE_MESSAGE_MANAGER
  64. ReferenceCountedJuceMessageMessager::ReferenceCountedJuceMessageMessager()
  65. {
  66. CARLA_SAFE_ASSERT(numScopedInitInstances == 0);
  67. }
  68. ReferenceCountedJuceMessageMessager::~ReferenceCountedJuceMessageMessager()
  69. {
  70. CARLA_SAFE_ASSERT(numScopedInitInstances == 0);
  71. }
  72. void ReferenceCountedJuceMessageMessager::incRef() const
  73. {
  74. if (numScopedInitInstances++ == 0)
  75. {
  76. juce::initialiseJuce_GUI();
  77. juce::MessageManager::getInstance()->setCurrentThreadAsMessageThread();
  78. }
  79. }
  80. void ReferenceCountedJuceMessageMessager::decRef() const
  81. {
  82. if (--numScopedInitInstances == 0)
  83. {
  84. juce::shutdownJuce_GUI();
  85. }
  86. }
  87. void setMessageManagerForThisThread()
  88. {
  89. juce::MessageManager* const msgMgr = juce::MessageManager::getInstanceWithoutCreating();
  90. CARLA_SAFE_ASSERT_RETURN(msgMgr != nullptr,);
  91. if (! msgMgr->isThisTheMessageThread())
  92. {
  93. try {
  94. msgMgr->setCurrentThreadAsMessageThread();
  95. } CARLA_SAFE_EXCEPTION_RETURN("setCurrentThreadAsMessageThread",);
  96. }
  97. }
  98. void dispatchMessageManagerMessages()
  99. {
  100. const juce::MessageManagerLock mml;
  101. juce::dispatchNextMessageOnSystemQueue(true);
  102. }
  103. #endif
  104. #ifdef USE_STANDALONE_JUCE_APPLICATION
  105. static std::function<void()> sIdleFn;
  106. static volatile bool* sClosedSignalPtr;
  107. class CarlaJuceApp : public juce::JUCEApplication,
  108. private juce::Timer
  109. {
  110. public:
  111. CarlaJuceApp() {}
  112. ~CarlaJuceApp() {}
  113. void initialise(const juce::String&) override
  114. {
  115. startTimer(8);
  116. }
  117. void shutdown() override
  118. {
  119. *sClosedSignalPtr = true;
  120. stopTimer();
  121. }
  122. const juce::String getApplicationName() override
  123. {
  124. return "CarlaPlugin";
  125. }
  126. const juce::String getApplicationVersion() override
  127. {
  128. return CARLA_VERSION_STRING;
  129. }
  130. void timerCallback() override
  131. {
  132. sIdleFn();
  133. if (*sClosedSignalPtr)
  134. {
  135. quit();
  136. *sClosedSignalPtr = false;
  137. }
  138. }
  139. };
  140. static juce::JUCEApplicationBase* juce_CreateApplication() { return new CarlaJuceApp(); }
  141. void setupAndUseMainApplication(std::function<void()> idleFn, volatile bool* closedSignalPtr)
  142. {
  143. #ifndef CARLA_OS_WIN
  144. static const int argc = 0;
  145. static const char* argv[] = {};
  146. #endif
  147. sIdleFn = idleFn;
  148. sClosedSignalPtr = closedSignalPtr;
  149. juce::JUCEApplicationBase::createInstance = &juce_CreateApplication;
  150. juce::JUCEApplicationBase::main(JUCE_MAIN_FUNCTION_ARGS);
  151. }
  152. #endif
  153. } // namespace CarlaJUCE