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.

215 lines
6.5KB

  1. /*
  2. ==============================================================================
  3. This file is part of the JUCE library.
  4. Copyright (c) 2015 - ROLI Ltd.
  5. Permission is granted to use this software under the terms of either:
  6. a) the GPL v2 (or any later version)
  7. b) the Affero GPL v3
  8. Details of these licenses can be found at: www.gnu.org/licenses
  9. JUCE is distributed in the hope that it will be useful, but WITHOUT ANY
  10. WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
  11. A PARTICULAR PURPOSE. See the GNU General Public License for more details.
  12. ------------------------------------------------------------------------------
  13. To release a closed-source product which uses JUCE, commercial licenses are
  14. available: visit www.juce.com for more information.
  15. ==============================================================================
  16. */
  17. #if _MSC_VER || defined (__MINGW32__) || defined (__MINGW64__)
  18. #include <windows.h>
  19. #endif
  20. #include "../../juce_core/system/juce_TargetPlatform.h"
  21. #include "../utility/juce_CheckSettingMacros.h"
  22. #include "juce_IncludeModuleHeaders.h"
  23. namespace juce
  24. {
  25. AudioProcessor::WrapperType PluginHostType::jucePlugInClientCurrentWrapperType = AudioProcessor::wrapperType_Undefined;
  26. }
  27. //==============================================================================
  28. namespace juce
  29. {
  30. #ifndef JUCE_VST3_CAN_REPLACE_VST2
  31. #define JUCE_VST3_CAN_REPLACE_VST2 1
  32. #endif
  33. #if JucePlugin_Build_VST3 && (__APPLE_CPP__ || __APPLE_CC__ || _WIN32 || _WIN64) && JUCE_VST3_CAN_REPLACE_VST2
  34. #define VST3_REPLACEMENT_AVAILABLE 1
  35. // NB: Nasty old-fashioned code in here because it's copied from the Steinberg example code.
  36. void JUCE_API getUUIDForVST2ID (bool forControllerUID, uint8 uuid[16])
  37. {
  38. char uidString[33];
  39. const int vstfxid = (('V' << 16) | ('S' << 8) | (forControllerUID ? 'E' : 'T'));
  40. char vstfxidStr[7] = { 0 };
  41. sprintf (vstfxidStr, "%06X", vstfxid);
  42. strcpy (uidString, vstfxidStr);
  43. char uidStr[9] = { 0 };
  44. sprintf (uidStr, "%08X", JucePlugin_VSTUniqueID);
  45. strcat (uidString, uidStr);
  46. char nameidStr[3] = { 0 };
  47. const size_t len = strlen (JucePlugin_Name);
  48. for (size_t i = 0; i <= 8; ++i)
  49. {
  50. juce::uint8 c = i < len ? static_cast<juce::uint8> (JucePlugin_Name[i]) : 0;
  51. if (c >= 'A' && c <= 'Z')
  52. c += 'a' - 'A';
  53. sprintf (nameidStr, "%02X", c);
  54. strcat (uidString, nameidStr);
  55. }
  56. unsigned long p0;
  57. unsigned int p1, p2;
  58. unsigned int p3[8];
  59. #ifndef _MSC_VER
  60. sscanf
  61. #else
  62. sscanf_s
  63. #endif
  64. (uidString, "%08lX%04X%04X%02X%02X%02X%02X%02X%02X%02X%02X",
  65. &p0, &p1, &p2, &p3[0], &p3[1], &p3[2], &p3[3], &p3[4], &p3[5], &p3[6], &p3[7]);
  66. union q0_u {
  67. uint32 word;
  68. uint8 bytes[4];
  69. } q0;
  70. union q1_u {
  71. uint16 half;
  72. uint8 bytes[2];
  73. } q1, q2;
  74. q0.word = static_cast<uint32> (p0);
  75. q1.half = static_cast<uint16> (p1);
  76. q2.half = static_cast<uint16> (p2);
  77. // VST3 doesn't use COM compatible UUIDs on non windows platforms
  78. #ifndef _WIN32
  79. q0.word = ByteOrder::swap (q0.word);
  80. q1.half = ByteOrder::swap (q1.half);
  81. q2.half = ByteOrder::swap (q2.half);
  82. #endif
  83. for (int i = 0; i < 4; ++i)
  84. uuid[i+0] = q0.bytes[i];
  85. for (int i = 0; i < 2; ++i)
  86. uuid[i+4] = q1.bytes[i];
  87. for (int i = 0; i < 2; ++i)
  88. uuid[i+6] = q2.bytes[i];
  89. for (int i = 0; i < 8; ++i)
  90. uuid[i+8] = static_cast<uint8> (p3[i]);
  91. }
  92. #else
  93. #define VST3_REPLACEMENT_AVAILABLE 0
  94. #endif
  95. #if JucePlugin_Build_VST
  96. bool JUCE_API handleManufacturerSpecificVST2Opcode (int32 index, pointer_sized_int value, void* ptr, float)
  97. {
  98. #if VST3_REPLACEMENT_AVAILABLE
  99. if ((index == 'stCA' || index == 'stCa') && value == 'FUID' && ptr != nullptr)
  100. {
  101. uint8 fuid[16];
  102. getUUIDForVST2ID (false, fuid);
  103. ::memcpy (ptr, fuid, 16);
  104. return true;
  105. }
  106. #else
  107. ignoreUnused (index, value, ptr);
  108. #endif
  109. return false;
  110. }
  111. #endif
  112. } // namespace juce
  113. //==============================================================================
  114. /** Somewhere in the codebase of your plugin, you need to implement this function
  115. and make it return a new instance of the filter subclass that you're building.
  116. */
  117. extern AudioProcessor* JUCE_CALLTYPE createPluginFilter();
  118. #if JucePlugin_Enable_IAA && JucePlugin_Build_STANDALONE && JUCE_IOS && (! JUCE_USE_CUSTOM_AU3_STANDALONE_APP)
  119. extern bool JUCE_CALLTYPE juce_isInterAppAudioConnected();
  120. extern void JUCE_CALLTYPE juce_switchToHostApplication();
  121. #if JUCE_MODULE_AVAILABLE_juce_gui_basics
  122. extern Image JUCE_CALLTYPE juce_getIAAHostIcon (int);
  123. #endif
  124. #endif
  125. AudioProcessor* JUCE_API JUCE_CALLTYPE createPluginFilterOfType (AudioProcessor::WrapperType type)
  126. {
  127. AudioProcessor::setTypeOfNextNewPlugin (type);
  128. AudioProcessor* const pluginInstance = createPluginFilter();
  129. AudioProcessor::setTypeOfNextNewPlugin (AudioProcessor::wrapperType_Undefined);
  130. // your createPluginFilter() method must return an object!
  131. jassert (pluginInstance != nullptr && pluginInstance->wrapperType == type);
  132. return pluginInstance;
  133. }
  134. bool PluginHostType::isInterAppAudioConnected() const
  135. {
  136. #if JucePlugin_Enable_IAA && JucePlugin_Build_STANDALONE && JUCE_IOS && (! JUCE_USE_CUSTOM_AU3_STANDALONE_APP)
  137. if (getPluginLoadedAs() == AudioProcessor::wrapperType_Standalone)
  138. return juce_isInterAppAudioConnected();
  139. #endif
  140. return false;
  141. }
  142. void PluginHostType::switchToHostApplication() const
  143. {
  144. #if JucePlugin_Enable_IAA && JucePlugin_Build_STANDALONE && JUCE_IOS && (! JUCE_USE_CUSTOM_AU3_STANDALONE_APP)
  145. if (getPluginLoadedAs() == AudioProcessor::wrapperType_Standalone)
  146. juce_switchToHostApplication();
  147. #endif
  148. }
  149. #if JUCE_MODULE_AVAILABLE_juce_gui_basics
  150. namespace juce {
  151. extern Image JUCE_API getIconFromApplication (const String&, const int);
  152. Image PluginHostType::getHostIcon (int size) const
  153. {
  154. ignoreUnused (size);
  155. #if JucePlugin_Enable_IAA && JucePlugin_Build_STANDALONE && JUCE_IOS && (! JUCE_USE_CUSTOM_AU3_STANDALONE_APP)
  156. if (isInterAppAudioConnected())
  157. return juce_getIAAHostIcon (size);
  158. #endif
  159. #if JUCE_MAC
  160. String bundlePath (getHostPath().upToLastOccurrenceOf (".app", true, true));
  161. return getIconFromApplication (bundlePath, size);
  162. #endif
  163. return Image();
  164. }
  165. }
  166. #endif