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.

167 lines
3.9KB

  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 <app/common.hpp>
  22. namespace rack {
  23. namespace asset {
  24. static void initSystemDir() {
  25. if (systemDir != "")
  26. return;
  27. if (settings::devMode) {
  28. systemDir = system::getWorkingDirectory();
  29. return;
  30. }
  31. #if defined ARCH_MAC
  32. CFBundleRef bundle = CFBundleGetMainBundle();
  33. assert(bundle);
  34. // Check if we're running as a command-line program or an app bundle.
  35. CFURLRef bundleUrl = CFBundleCopyBundleURL(bundle);
  36. // Thanks Ken Thomases! https://stackoverflow.com/a/58369256/272642
  37. CFStringRef uti;
  38. if (CFURLCopyResourcePropertyForKey(bundleUrl, kCFURLTypeIdentifierKey, &uti, NULL) && uti && UTTypeConformsTo(uti, kUTTypeApplicationBundle)) {
  39. char bundleBuf[PATH_MAX];
  40. Boolean success = CFURLGetFileSystemRepresentation(bundleUrl, TRUE, (UInt8*) bundleBuf, sizeof(bundleBuf));
  41. assert(success);
  42. bundlePath = bundleBuf;
  43. }
  44. CFURLRef resourcesUrl = CFBundleCopyResourcesDirectoryURL(bundle);
  45. char resourcesBuf[PATH_MAX];
  46. Boolean success = CFURLGetFileSystemRepresentation(resourcesUrl, TRUE, (UInt8*) resourcesBuf, sizeof(resourcesBuf));
  47. assert(success);
  48. CFRelease(resourcesUrl);
  49. systemDir = resourcesBuf;
  50. #endif
  51. #if defined ARCH_WIN
  52. // Get path to executable
  53. char16_t moduleBufU16[MAX_PATH] = u"";
  54. DWORD length = GetModuleFileNameW(NULL, (wchar_t*) moduleBufU16, LENGTHOF(moduleBufU16));
  55. assert(length > 0);
  56. // Get folder of executable
  57. PathRemoveFileSpecW((wchar_t*) moduleBufU16);
  58. systemDir = string::UTF16toUTF8(moduleBufU16);
  59. #endif
  60. #if defined ARCH_LIN
  61. // Use the current working directory as the default path on Linux.
  62. systemDir = system::getWorkingDirectory();
  63. #endif
  64. }
  65. static void initUserDir() {
  66. if (userDir != "")
  67. return;
  68. if (settings::devMode) {
  69. userDir = systemDir;
  70. return;
  71. }
  72. #if defined ARCH_WIN
  73. // Get "My Documents" folder
  74. char16_t documentsBufU16[MAX_PATH] = u".";
  75. HRESULT result = SHGetFolderPathW(NULL, CSIDL_MYDOCUMENTS, NULL, SHGFP_TYPE_CURRENT, (wchar_t*) documentsBufU16);
  76. assert(result == S_OK);
  77. userDir = string::UTF16toUTF8(documentsBufU16);
  78. userDir += "/Rack";
  79. #endif
  80. #if defined ARCH_MAC
  81. // Get home directory
  82. struct passwd* pw = getpwuid(getuid());
  83. assert(pw);
  84. userDir = pw->pw_dir;
  85. userDir += "/Documents/Rack";
  86. #endif
  87. #if defined ARCH_LIN
  88. // Get home directory
  89. const char* homeBuf = getenv("HOME");
  90. if (!homeBuf) {
  91. struct passwd* pw = getpwuid(getuid());
  92. assert(pw);
  93. homeBuf = pw->pw_dir;
  94. }
  95. userDir = homeBuf;
  96. userDir += "/.Rack";
  97. #endif
  98. }
  99. void init() {
  100. initSystemDir();
  101. initUserDir();
  102. system::createDirectory(userDir);
  103. // Set paths
  104. if (settings::devMode) {
  105. pluginsPath = userDir + "/plugins";
  106. settingsPath = userDir + "/settings.json";
  107. autosavePath = userDir + "/autosave.vcv";
  108. templatePath = userDir + "/template.vcv";
  109. }
  110. else {
  111. logPath = userDir + "/log.txt";
  112. pluginsPath = userDir + "/plugins-v" + ABI_VERSION;
  113. settingsPath = userDir + "/settings-v" + ABI_VERSION + ".json";
  114. autosavePath = userDir + "/autosave-v" + ABI_VERSION + ".vcv";
  115. templatePath = userDir + "/template-v" + ABI_VERSION + ".vcv";
  116. }
  117. }
  118. std::string system(std::string filename) {
  119. return systemDir + "/" + filename;
  120. }
  121. std::string user(std::string filename) {
  122. return userDir + "/" + filename;
  123. }
  124. std::string plugin(plugin::Plugin* plugin, std::string filename) {
  125. assert(plugin);
  126. return plugin->path + "/" + filename;
  127. }
  128. std::string systemDir;
  129. std::string userDir;
  130. std::string logPath;
  131. std::string pluginsPath;
  132. std::string settingsPath;
  133. std::string autosavePath;
  134. std::string templatePath;
  135. std::string bundlePath;
  136. } // namespace asset
  137. } // namespace rack