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.

145 lines
3.3KB

  1. #if defined ARCH_MAC
  2. #include <CoreFoundation/CoreFoundation.h>
  3. #include <CoreServices/CoreServices.h>
  4. #include <pwd.h>
  5. #endif
  6. #if defined ARCH_WIN
  7. #include <Windows.h>
  8. #include <Shlobj.h>
  9. #include <Shlwapi.h>
  10. #endif
  11. #if defined ARCH_LIN
  12. #include <unistd.h>
  13. #include <sys/types.h>
  14. #include <pwd.h>
  15. #endif
  16. #include <asset.hpp>
  17. #include <system.hpp>
  18. #include <settings.hpp>
  19. #include <string.hpp>
  20. #include <plugin/Plugin.hpp>
  21. #include <engine/Module.hpp>
  22. #include <app/common.hpp>
  23. namespace rack {
  24. namespace asset {
  25. static void initSystemDir() {
  26. if (!systemDir.empty())
  27. return;
  28. if (settings::devMode) {
  29. systemDir = system::getWorkingDir();
  30. return;
  31. }
  32. #if defined ARCH_MAC
  33. CFBundleRef bundle = CFBundleGetMainBundle();
  34. assert(bundle);
  35. // Check if we're running as a command-line program or an app bundle.
  36. CFURLRef bundleUrl = CFBundleCopyBundleURL(bundle);
  37. // Thanks Ken Thomases! https://stackoverflow.com/a/58369256/272642
  38. CFStringRef uti;
  39. if (CFURLCopyResourcePropertyForKey(bundleUrl, kCFURLTypeIdentifierKey, &uti, NULL) && uti && UTTypeConformsTo(uti, kUTTypeApplicationBundle)) {
  40. char bundleBuf[PATH_MAX];
  41. Boolean success = CFURLGetFileSystemRepresentation(bundleUrl, TRUE, (UInt8*) bundleBuf, sizeof(bundleBuf));
  42. assert(success);
  43. bundlePath = bundleBuf;
  44. }
  45. CFURLRef resourcesUrl = CFBundleCopyResourcesDirectoryURL(bundle);
  46. char resourcesBuf[PATH_MAX];
  47. Boolean success = CFURLGetFileSystemRepresentation(resourcesUrl, TRUE, (UInt8*) resourcesBuf, sizeof(resourcesBuf));
  48. assert(success);
  49. CFRelease(resourcesUrl);
  50. systemDir = resourcesBuf;
  51. #endif
  52. #if defined ARCH_WIN
  53. // Get path to executable
  54. wchar_t moduleBufW[MAX_PATH] = L"";
  55. DWORD length = GetModuleFileNameW(NULL, moduleBufW, LENGTHOF(moduleBufW));
  56. assert(length > 0);
  57. // Get directory of executable
  58. PathRemoveFileSpecW(moduleBufW);
  59. systemDir = string::UTF16toUTF8(moduleBufW);
  60. #endif
  61. #if defined ARCH_LIN
  62. // Use the current working directory as the default path on Linux.
  63. systemDir = system::getWorkingDir();
  64. #endif
  65. }
  66. static void initUserDir() {
  67. if (!userDir.empty())
  68. return;
  69. if (settings::devMode) {
  70. userDir = systemDir;
  71. return;
  72. }
  73. #if defined ARCH_WIN
  74. // Get "My Documents" path
  75. wchar_t documentsBufW[MAX_PATH] = L".";
  76. HRESULT result = SHGetFolderPathW(NULL, CSIDL_MYDOCUMENTS, NULL, SHGFP_TYPE_CURRENT, documentsBufW);
  77. assert(result == S_OK);
  78. userDir = system::join(string::UTF16toUTF8(documentsBufW), "Rack");
  79. #endif
  80. #if defined ARCH_MAC
  81. // Get home directory
  82. struct passwd* pw = getpwuid(getuid());
  83. assert(pw);
  84. userDir = system::join(pw->pw_dir, "Documents/Rack");
  85. #endif
  86. #if defined ARCH_LIN
  87. // Get home directory
  88. const char* homeBuf = getenv("HOME");
  89. if (!homeBuf) {
  90. struct passwd* pw = getpwuid(getuid());
  91. assert(pw);
  92. homeBuf = pw->pw_dir;
  93. }
  94. userDir = system::join(homeBuf, ".Rack");
  95. #endif
  96. }
  97. void init() {
  98. initSystemDir();
  99. initUserDir();
  100. system::createDir(userDir);
  101. }
  102. std::string system(std::string filename) {
  103. return system::join(systemDir, filename);
  104. }
  105. std::string user(std::string filename) {
  106. return system::join(userDir, filename);
  107. }
  108. std::string plugin(plugin::Plugin* plugin, std::string filename) {
  109. assert(plugin);
  110. return system::join(plugin->path, filename);
  111. }
  112. std::string systemDir;
  113. std::string userDir;
  114. std::string bundlePath;
  115. } // namespace asset
  116. } // namespace rack