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.

169 lines
4.6KB

  1. /*
  2. * Carla macOS utils
  3. * Copyright (C) 2018-2023 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 "CarlaDefines.h"
  18. #ifdef CARLA_OS_MAC
  19. #include "CarlaMacUtils.hpp"
  20. #include "CarlaString.hpp"
  21. #include <sys/xattr.h>
  22. #ifdef __MAC_10_12
  23. # define Component CocoaComponent
  24. # define MemoryBlock CocoaMemoryBlock
  25. # define Point CocoaPoint
  26. #endif
  27. #import <Cocoa/Cocoa.h>
  28. #import <Foundation/Foundation.h>
  29. #undef Component
  30. #undef MemoryBlock
  31. #undef Point
  32. CARLA_BACKEND_START_NAMESPACE
  33. // --------------------------------------------------------------------------------------------------------------------
  34. void initStandaloneApplication()
  35. {
  36. [[NSApplication sharedApplication] retain];
  37. [NSApp setActivationPolicy:NSApplicationActivationPolicyRegular];
  38. [NSApp activateIgnoringOtherApps:YES];
  39. }
  40. const char* findBinaryInBundle(const char* const bundleDir)
  41. {
  42. const CFURLRef urlRef = CFURLCreateFromFileSystemRepresentation(0, (const UInt8*)bundleDir, (CFIndex)strlen(bundleDir), true);
  43. CARLA_SAFE_ASSERT_RETURN(urlRef != nullptr, nullptr);
  44. const CFBundleRef bundleRef = CFBundleCreate(kCFAllocatorDefault, urlRef);
  45. CARLA_SAFE_ASSERT_RETURN(bundleRef != nullptr, nullptr);
  46. const CFURLRef exeRef = CFBundleCopyExecutableURL(bundleRef);
  47. CARLA_SAFE_ASSERT_RETURN(exeRef != nullptr, nullptr);
  48. const CFURLRef absoluteURL = CFURLCopyAbsoluteURL(exeRef);
  49. CARLA_SAFE_ASSERT_RETURN(absoluteURL != nullptr, nullptr);
  50. const NSString* strRef = (NSString*)CFURLCopyFileSystemPath(absoluteURL, kCFURLPOSIXPathStyle);
  51. CARLA_SAFE_ASSERT_RETURN(strRef != nullptr, nullptr);
  52. static CarlaString ret;
  53. ret = [strRef UTF8String];
  54. CFRelease(absoluteURL);
  55. CFRelease(exeRef);
  56. CFRelease(bundleRef);
  57. CFRelease(urlRef);
  58. return ret.buffer();
  59. }
  60. bool removeFileFromQuarantine(const char* const filename)
  61. {
  62. return removexattr(filename, "com.apple.quarantine", 0) == 0;
  63. }
  64. // --------------------------------------------------------------------------------------------------------------------
  65. AutoNSAutoreleasePool::AutoNSAutoreleasePool()
  66. : pool([NSAutoreleasePool new]) {}
  67. AutoNSAutoreleasePool::~AutoNSAutoreleasePool()
  68. {
  69. NSAutoreleasePool* rpool = (NSAutoreleasePool*)pool;
  70. [rpool drain];
  71. }
  72. // --------------------------------------------------------------------------------------------------------------------
  73. struct BundleLoader::PrivateData {
  74. CFBundleRef ref;
  75. CFBundleRefNum refNum;
  76. PrivateData() noexcept
  77. : ref(nullptr),
  78. refNum(0) {}
  79. ~PrivateData()
  80. {
  81. if (ref == nullptr)
  82. return;
  83. #pragma clang diagnostic push
  84. #pragma clang diagnostic ignored "-Wdeprecated-declarations"
  85. CFBundleCloseBundleResourceMap(ref, refNum);
  86. #pragma clang diagnostic pop
  87. if (CFGetRetainCount(ref) == 1)
  88. CFBundleUnloadExecutable(ref);
  89. if (CFGetRetainCount(ref) > 0)
  90. CFRelease(ref);
  91. }
  92. bool load(const char* const filename)
  93. {
  94. const CFURLRef urlRef = CFURLCreateFromFileSystemRepresentation(0, (const UInt8*)filename, (CFIndex)std::strlen(filename), true);
  95. CARLA_SAFE_ASSERT_RETURN(urlRef != nullptr, false);
  96. ref = CFBundleCreate(kCFAllocatorDefault, urlRef);
  97. CFRelease(urlRef);
  98. CARLA_SAFE_ASSERT_RETURN(ref != nullptr, false);
  99. if (! CFBundleLoadExecutable(ref))
  100. {
  101. CFRelease(ref);
  102. ref = nullptr;
  103. return false;
  104. }
  105. #pragma clang diagnostic push
  106. #pragma clang diagnostic ignored "-Wdeprecated-declarations"
  107. refNum = CFBundleOpenBundleResourceMap(ref);
  108. #pragma clang diagnostic pop
  109. return true;
  110. }
  111. };
  112. BundleLoader::BundleLoader()
  113. : pData(new PrivateData){}
  114. BundleLoader::~BundleLoader()
  115. {
  116. delete pData;
  117. }
  118. bool BundleLoader::load(const char* const filename)
  119. {
  120. return pData->load(filename);
  121. }
  122. CFBundleRef BundleLoader::getRef() const noexcept
  123. {
  124. return pData->ref;
  125. }
  126. // --------------------------------------------------------------------------------------------------------------------
  127. CARLA_BACKEND_END_NAMESPACE
  128. #endif // CARLA_OS_MAC