The JUCE cross-platform C++ framework, with DISTRHO/KXStudio specific changes
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.

247 lines
7.4KB

  1. /*
  2. ==============================================================================
  3. This file is part of the JUCE library.
  4. Copyright (c) 2017 - ROLI Ltd.
  5. JUCE is an open source library subject to commercial or open-source
  6. licensing.
  7. By using JUCE, you agree to the terms of both the JUCE 5 End-User License
  8. Agreement and JUCE 5 Privacy Policy (both updated and effective as of the
  9. 27th April 2017).
  10. End User License Agreement: www.juce.com/juce-5-licence
  11. Privacy Policy: www.juce.com/juce-5-privacy-policy
  12. Or: You may also use this code under the terms of the GPL v3 (see
  13. www.gnu.org/licenses).
  14. JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER
  15. EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE
  16. DISCLAIMED.
  17. ==============================================================================
  18. */
  19. #if _MSC_VER || defined (__MINGW32__) || defined (__MINGW64__)
  20. #include <windows.h>
  21. #endif
  22. #include "../../juce_core/system/juce_TargetPlatform.h"
  23. #include "../utility/juce_CheckSettingMacros.h"
  24. #include "juce_IncludeModuleHeaders.h"
  25. using namespace juce;
  26. namespace juce
  27. {
  28. AudioProcessor::WrapperType PluginHostType::jucePlugInClientCurrentWrapperType = AudioProcessor::wrapperType_Undefined;
  29. std::function<bool(AudioProcessor&)> PluginHostType::jucePlugInIsRunningInAudioSuiteFn = nullptr;
  30. #if JucePlugin_Build_Unity
  31. bool juce_isRunningInUnity() { return PluginHostType::getPluginLoadedAs() == AudioProcessor::wrapperType_Unity; }
  32. #endif
  33. #if JUCE_MODULE_AVAILABLE_juce_opengl && (JucePlugin_Build_VST || JucePlugin_Build_VST3)
  34. bool juce_shouldDoubleScaleNativeGLWindow()
  35. {
  36. auto wrapperType = PluginHostType::getPluginLoadedAs();
  37. if (wrapperType == AudioProcessor::wrapperType_VST || wrapperType == AudioProcessor::wrapperType_VST3)
  38. return getHostType().type == PluginHostType::SteinbergCubase10;
  39. return false;
  40. }
  41. #endif
  42. #ifndef JUCE_VST3_CAN_REPLACE_VST2
  43. #define JUCE_VST3_CAN_REPLACE_VST2 1
  44. #endif
  45. #if JucePlugin_Build_VST3 && (__APPLE_CPP__ || __APPLE_CC__ || _WIN32 || _WIN64) && JUCE_VST3_CAN_REPLACE_VST2
  46. #define VST3_REPLACEMENT_AVAILABLE 1
  47. // NB: Nasty old-fashioned code in here because it's copied from the Steinberg example code.
  48. void JUCE_API getUUIDForVST2ID (bool forControllerUID, uint8 uuid[16])
  49. {
  50. char uidString[33];
  51. const int vstfxid = (('V' << 16) | ('S' << 8) | (forControllerUID ? 'E' : 'T'));
  52. char vstfxidStr[7] = { 0 };
  53. sprintf (vstfxidStr, "%06X", vstfxid);
  54. strcpy (uidString, vstfxidStr);
  55. char uidStr[9] = { 0 };
  56. sprintf (uidStr, "%08X", JucePlugin_VSTUniqueID);
  57. strcat (uidString, uidStr);
  58. char nameidStr[3] = { 0 };
  59. const size_t len = strlen (JucePlugin_Name);
  60. for (size_t i = 0; i <= 8; ++i)
  61. {
  62. juce::uint8 c = i < len ? static_cast<juce::uint8> (JucePlugin_Name[i]) : 0;
  63. if (c >= 'A' && c <= 'Z')
  64. c += 'a' - 'A';
  65. sprintf (nameidStr, "%02X", c);
  66. strcat (uidString, nameidStr);
  67. }
  68. unsigned long p0;
  69. unsigned int p1, p2;
  70. unsigned int p3[8];
  71. #ifndef _MSC_VER
  72. sscanf
  73. #else
  74. sscanf_s
  75. #endif
  76. (uidString, "%08lX%04X%04X%02X%02X%02X%02X%02X%02X%02X%02X",
  77. &p0, &p1, &p2, &p3[0], &p3[1], &p3[2], &p3[3], &p3[4], &p3[5], &p3[6], &p3[7]);
  78. union q0_u {
  79. uint32 word;
  80. uint8 bytes[4];
  81. } q0;
  82. union q1_u {
  83. uint16 half;
  84. uint8 bytes[2];
  85. } q1, q2;
  86. q0.word = static_cast<uint32> (p0);
  87. q1.half = static_cast<uint16> (p1);
  88. q2.half = static_cast<uint16> (p2);
  89. // VST3 doesn't use COM compatible UUIDs on non windows platforms
  90. #ifndef _WIN32
  91. q0.word = ByteOrder::swap (q0.word);
  92. q1.half = ByteOrder::swap (q1.half);
  93. q2.half = ByteOrder::swap (q2.half);
  94. #endif
  95. for (int i = 0; i < 4; ++i)
  96. uuid[i+0] = q0.bytes[i];
  97. for (int i = 0; i < 2; ++i)
  98. uuid[i+4] = q1.bytes[i];
  99. for (int i = 0; i < 2; ++i)
  100. uuid[i+6] = q2.bytes[i];
  101. for (int i = 0; i < 8; ++i)
  102. uuid[i+8] = static_cast<uint8> (p3[i]);
  103. }
  104. #else
  105. #define VST3_REPLACEMENT_AVAILABLE 0
  106. #endif
  107. #if JucePlugin_Build_VST
  108. bool JUCE_API handleManufacturerSpecificVST2Opcode (int32 index, pointer_sized_int value, void* ptr, float)
  109. {
  110. #if VST3_REPLACEMENT_AVAILABLE
  111. if ((index == 'stCA' || index == 'stCa') && value == 'FUID' && ptr != nullptr)
  112. {
  113. uint8 fuid[16];
  114. getUUIDForVST2ID (false, fuid);
  115. ::memcpy (ptr, fuid, 16);
  116. return true;
  117. }
  118. #else
  119. ignoreUnused (index, value, ptr);
  120. #endif
  121. return false;
  122. }
  123. #endif
  124. } // namespace juce
  125. //==============================================================================
  126. /** Somewhere in the codebase of your plugin, you need to implement this function
  127. and make it return a new instance of the filter subclass that you're building.
  128. */
  129. extern AudioProcessor* JUCE_CALLTYPE createPluginFilter();
  130. #if JucePlugin_Enable_IAA && JucePlugin_Build_Standalone && JUCE_IOS && (! JUCE_USE_CUSTOM_PLUGIN_STANDALONE_APP)
  131. extern bool JUCE_CALLTYPE juce_isInterAppAudioConnected();
  132. extern void JUCE_CALLTYPE juce_switchToHostApplication();
  133. #if JUCE_MODULE_AVAILABLE_juce_gui_basics
  134. extern Image JUCE_CALLTYPE juce_getIAAHostIcon (int);
  135. #endif
  136. #endif
  137. AudioProcessor* JUCE_API JUCE_CALLTYPE createPluginFilterOfType (AudioProcessor::WrapperType type)
  138. {
  139. AudioProcessor::setTypeOfNextNewPlugin (type);
  140. AudioProcessor* const pluginInstance = createPluginFilter();
  141. AudioProcessor::setTypeOfNextNewPlugin (AudioProcessor::wrapperType_Undefined);
  142. // your createPluginFilter() method must return an object!
  143. jassert (pluginInstance != nullptr && pluginInstance->wrapperType == type);
  144. return pluginInstance;
  145. }
  146. bool PluginHostType::isInterAppAudioConnected() const
  147. {
  148. #if JucePlugin_Enable_IAA && JucePlugin_Build_Standalone && JUCE_IOS && (! JUCE_USE_CUSTOM_PLUGIN_STANDALONE_APP)
  149. if (getPluginLoadedAs() == AudioProcessor::wrapperType_Standalone)
  150. return juce_isInterAppAudioConnected();
  151. #endif
  152. return false;
  153. }
  154. void PluginHostType::switchToHostApplication() const
  155. {
  156. #if JucePlugin_Enable_IAA && JucePlugin_Build_Standalone && JUCE_IOS && (! JUCE_USE_CUSTOM_PLUGIN_STANDALONE_APP)
  157. if (getPluginLoadedAs() == AudioProcessor::wrapperType_Standalone)
  158. juce_switchToHostApplication();
  159. #endif
  160. }
  161. bool PluginHostType::isInAAXAudioSuite (AudioProcessor& processor)
  162. {
  163. #if JucePlugin_Build_AAX
  164. if (PluginHostType::getPluginLoadedAs() == AudioProcessor::wrapperType_AAX
  165. && jucePlugInIsRunningInAudioSuiteFn != nullptr)
  166. {
  167. return jucePlugInIsRunningInAudioSuiteFn (processor);
  168. }
  169. #endif
  170. ignoreUnused (processor);
  171. return false;
  172. }
  173. #if JUCE_MODULE_AVAILABLE_juce_gui_basics
  174. namespace juce {
  175. extern Image JUCE_API getIconFromApplication (const String&, const int);
  176. Image PluginHostType::getHostIcon (int size) const
  177. {
  178. ignoreUnused (size);
  179. #if JucePlugin_Enable_IAA && JucePlugin_Build_Standalone && JUCE_IOS && (! JUCE_USE_CUSTOM_PLUGIN_STANDALONE_APP)
  180. if (isInterAppAudioConnected())
  181. return juce_getIAAHostIcon (size);
  182. #endif
  183. #if JUCE_MAC
  184. String bundlePath (getHostPath().upToLastOccurrenceOf (".app", true, true));
  185. return getIconFromApplication (bundlePath, size);
  186. #endif
  187. return Image();
  188. }
  189. }
  190. #endif