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.

163 lines
4.1KB

  1. #include <asset.hpp>
  2. #include <system.hpp>
  3. #include <settings.hpp>
  4. #include <string.hpp>
  5. #include <plugin/Plugin.hpp>
  6. #include <app/common.hpp>
  7. #if defined ARCH_MAC
  8. #include <CoreFoundation/CoreFoundation.h>
  9. #include <pwd.h>
  10. #endif
  11. #if defined ARCH_WIN
  12. #include <Windows.h>
  13. #include <Shlobj.h>
  14. #include <Shlwapi.h>
  15. #endif
  16. #if defined ARCH_LIN
  17. #include <unistd.h>
  18. #include <sys/types.h>
  19. #include <pwd.h>
  20. #endif
  21. namespace rack {
  22. namespace asset {
  23. void init() {
  24. // Get system dir
  25. if (systemDir.empty()) {
  26. if (settings::devMode) {
  27. systemDir = ".";
  28. }
  29. else {
  30. #if defined ARCH_MAC
  31. CFBundleRef bundle = CFBundleGetMainBundle();
  32. assert(bundle);
  33. CFURLRef bundleUrl = CFBundleCopyBundleURL(bundle);
  34. char bundleBuf[PATH_MAX];
  35. Boolean success = CFURLGetFileSystemRepresentation(bundleUrl, TRUE, (UInt8*) bundleBuf, sizeof(bundleBuf));
  36. assert(success);
  37. bundlePath = bundleBuf;
  38. // If the bundle path doesn't end with ".app", assume it's a fake app bundle run from the command line.
  39. if (string::filenameExtension(string::filename(bundlePath)) != "app")
  40. bundlePath = "";
  41. CFURLRef resourcesUrl = CFBundleCopyResourcesDirectoryURL(bundle);
  42. char resourcesBuf[PATH_MAX];
  43. success = CFURLGetFileSystemRepresentation(resourcesUrl, TRUE, (UInt8*) resourcesBuf, sizeof(resourcesBuf));
  44. assert(success);
  45. CFRelease(resourcesUrl);
  46. systemDir = resourcesBuf;
  47. #endif
  48. #if defined ARCH_WIN
  49. // Get path to executable
  50. wchar_t moduleBufW[MAX_PATH];
  51. DWORD length = GetModuleFileNameW(NULL, moduleBufW, LENGTHOF(moduleBufW));
  52. assert(length > 0);
  53. // Get folder of executable
  54. PathRemoveFileSpecW(moduleBufW);
  55. // Convert to short path to avoid Unicode
  56. wchar_t moduleBufShortW[MAX_PATH];
  57. GetShortPathNameW(moduleBufW, moduleBufShortW, LENGTHOF(moduleBufShortW));
  58. systemDir = string::fromWstring(moduleBufShortW);
  59. #endif
  60. #if defined ARCH_LIN
  61. // Users should launch Rack from their terminal in the system directory
  62. systemDir = ".";
  63. #endif
  64. }
  65. }
  66. // Get user dir
  67. if (userDir.empty()) {
  68. if (settings::devMode) {
  69. userDir = ".";
  70. }
  71. else {
  72. #if defined ARCH_WIN
  73. // Get "My Documents" folder
  74. wchar_t documentsBufW[MAX_PATH] = L".";
  75. HRESULT result = SHGetFolderPathW(NULL, CSIDL_MYDOCUMENTS, NULL, SHGFP_TYPE_CURRENT, documentsBufW);
  76. assert(result == S_OK);
  77. // Convert to short path to avoid Unicode
  78. wchar_t documentsBufShortW[MAX_PATH];
  79. GetShortPathNameW(documentsBufW, documentsBufShortW, LENGTHOF(documentsBufShortW));
  80. userDir = string::fromWstring(documentsBufShortW);
  81. userDir += "/Rack";
  82. #endif
  83. #if defined ARCH_MAC
  84. // Get home directory
  85. struct passwd* pw = getpwuid(getuid());
  86. assert(pw);
  87. userDir = pw->pw_dir;
  88. userDir += "/Documents/Rack";
  89. #endif
  90. #if defined ARCH_LIN
  91. // Get home directory
  92. const char* homeBuf = getenv("HOME");
  93. if (!homeBuf) {
  94. struct passwd* pw = getpwuid(getuid());
  95. assert(pw);
  96. homeBuf = pw->pw_dir;
  97. }
  98. userDir = homeBuf;
  99. userDir += "/.Rack";
  100. #endif
  101. }
  102. }
  103. system::createDirectory(systemDir);
  104. system::createDirectory(userDir);
  105. // Set paths
  106. if (settings::devMode) {
  107. pluginsPath = userDir + "/plugins";
  108. settingsPath = userDir + "/settings.json";
  109. autosavePath = userDir + "/autosave.vcv";
  110. templatePath = userDir + "/template.vcv";
  111. }
  112. else {
  113. logPath = userDir + "/log.txt";
  114. pluginsPath = userDir + "/plugins-v" + app::ABI_VERSION;
  115. settingsPath = userDir + "/settings-v" + app::ABI_VERSION + ".json";
  116. autosavePath = userDir + "/autosave-v" + app::ABI_VERSION + ".vcv";
  117. templatePath = userDir + "/template-v" + app::ABI_VERSION + ".vcv";
  118. }
  119. }
  120. std::string system(std::string filename) {
  121. return systemDir + "/" + filename;
  122. }
  123. std::string user(std::string filename) {
  124. return userDir + "/" + filename;
  125. }
  126. std::string plugin(plugin::Plugin* plugin, std::string filename) {
  127. assert(plugin);
  128. return plugin->path + "/" + filename;
  129. }
  130. std::string systemDir;
  131. std::string userDir;
  132. std::string logPath;
  133. std::string pluginsPath;
  134. std::string settingsPath;
  135. std::string autosavePath;
  136. std::string templatePath;
  137. std::string bundlePath;
  138. } // namespace asset
  139. } // namespace rack