133 lines
4.3 KiB
C++
133 lines
4.3 KiB
C++
/*
|
|
* This Source Code Form is subject to the terms of the Mozilla Public
|
|
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
|
* file, You can obtain one at https://mozilla.org/MPL/2.0/.
|
|
*/
|
|
|
|
#include "PlatformFolders.hpp"
|
|
#include <iostream>
|
|
|
|
#if __APPLE__
|
|
#include <TargetConditionals.h>
|
|
#endif
|
|
|
|
#ifdef _WIN32
|
|
#include <winerror.h>
|
|
// For SHGetFolderPathW and various CSIDL "magic numbers"
|
|
#include <shlobj.h>
|
|
#include <utf8.h>
|
|
#include <memory>
|
|
|
|
namespace OpenVulkano
|
|
{
|
|
namespace
|
|
{
|
|
std::string GetKnownWindowsFolder(REFKNOWNFOLDERID folderId, std::string name)
|
|
{
|
|
LPWSTR wszPath = NULL;
|
|
HRESULT hr;
|
|
hr = SHGetKnownFolderPath(folderId, KF_FLAG_CREATE, NULL, &wszPath);
|
|
std::unique_ptr<wchar_t, decltype(&CoTaskMemFree)> scopeBoundMemory(wszPath, &CoTaskMemFree);
|
|
|
|
if (!SUCCEEDED(hr))
|
|
{
|
|
throw std::runtime_error("Failed to find " + name + "folder.");
|
|
}
|
|
std::wstring winPath(wszPath);
|
|
std::string str;
|
|
utf8::utf16to8(winPath.begin(), winPath.end(), std::back_inserter(str));
|
|
return str;
|
|
}
|
|
}
|
|
}
|
|
#endif
|
|
|
|
namespace OpenVulkano
|
|
{
|
|
namespace
|
|
{
|
|
std::filesystem::path GetHome()
|
|
{
|
|
auto home = std::getenv("HOME");
|
|
if (home == nullptr) throw std::runtime_error("HOME environment variable not set!");
|
|
return home;
|
|
}
|
|
|
|
[[nodiscard]] std::filesystem::path GetXDGFolderDefault(const char* envName, std::string_view defaultRelativePath)
|
|
{
|
|
#ifndef TARGET_OS_IOS != 1
|
|
const char* envValue = std::getenv(envName);
|
|
if (envValue)
|
|
{
|
|
if (envValue[0] == '/') return envValue;
|
|
std::cerr << "Ignoring environment '" << envName << "' (value: '" << envValue << "') because it's relative! XDG specifies it should be absolute path. Falling back to default path.";
|
|
}
|
|
#endif
|
|
return GetHome() / defaultRelativePath;
|
|
}
|
|
}
|
|
|
|
PlatformFolders::PlatformFolders()
|
|
{
|
|
#ifdef __APPLE__
|
|
#if TARGET_OS_IOS == 1
|
|
dataHome = GetHome() / "Documents/";
|
|
configHome = dataHome;
|
|
stateDir = dataHome;
|
|
dataCache = GetHome() / "Library/Caches/";
|
|
tempDir = dataCache;
|
|
#else
|
|
const auto home = GetHome();
|
|
dataHome = home / "Library/Application Support";
|
|
configHome = dataHome;
|
|
stateDir = dataHome;
|
|
dataCache = home / "Library/Caches";
|
|
tempDir = GetXDGFolderDefault("TMPDIR", "tmp");
|
|
#endif
|
|
#elif defined(_WIN32)
|
|
dataHome = GetKnownWindowsFolder(FOLDERID_RoamingAppData, "RoamingAppData");
|
|
configHome = GetKnownWindowsFolder(FOLDERID_RoamingAppData, "RoamingAppData");
|
|
stateDir = GetKnownWindowsFolder(FOLDERID_LocalAppData, "LocalAppData");
|
|
dataCache = GetKnownWindowsFolder(FOLDERID_LocalAppData, "LocalAppData");
|
|
desktop = GetKnownWindowsFolder(FOLDERID_Desktop, "Desktop");
|
|
documents = GetKnownWindowsFolder(FOLDERID_Documents, "Documents");
|
|
downloads = GetKnownWindowsFolder(FOLDERID_Downloads, "Downloads");
|
|
pictures = GetKnownWindowsFolder(FOLDERID_Pictures, "Pictures");
|
|
publicDir = GetKnownWindowsFolder(FOLDERID_Public, "Public");
|
|
music = GetKnownWindowsFolder(FOLDERID_Music, "Music");
|
|
video = GetKnownWindowsFolder(FOLDERID_Videos, "Videos");
|
|
savedGames = GetKnownWindowsFolder(FOLDERID_SavedGames, "Saved Games");
|
|
#else
|
|
dataHome = GetXDGFolderDefault("XDG_DATA_HOME", ".local/share");
|
|
configHome = GetXDGFolderDefault("XDG_CONFIG_HOME", ".config");
|
|
stateDir = GetXDGFolderDefault("XDG_STATE_HOME", ".local/state");
|
|
dataCache = GetXDGFolderDefault("XDG_CACHE_HOME", ".cache");
|
|
#endif
|
|
#ifndef __APPLE__
|
|
tempDir = std::filesystem::temp_directory_path();
|
|
#endif
|
|
|
|
// Use XDG resolution on Linux and MacOS (will skip the env variable check on MacOS and just use the fallbacks, since they align with apple)
|
|
#ifndef _WIN32
|
|
desktop = GetXDGFolderDefault("XDG_DESKTOP_DIR", "Desktop");
|
|
documents = GetXDGFolderDefault("XDG_DOCUMENTS_DIR", "Documents");
|
|
downloads = GetXDGFolderDefault("XDG_DOWNLOAD_DIR", "Downloads");
|
|
pictures = GetXDGFolderDefault("XDG_PICTURES_DIR", "Pictures");
|
|
publicDir = GetXDGFolderDefault("XDG_PUBLICSHARE_DIR", "Public");
|
|
music = GetXDGFolderDefault("XDG_MUSIC_DIR", "Music");
|
|
#ifdef __APPLE__
|
|
video = GetXDGFolderDefault("XDG_VIDEOS_DIR", "Movies");
|
|
#else
|
|
video = GetXDGFolderDefault("XDG_VIDEOS_DIR", "Videos");
|
|
#endif
|
|
savedGames = documents / "Saved Games";
|
|
#endif
|
|
}
|
|
|
|
PlatformFolders& PlatformFolders::GetInstance()
|
|
{
|
|
static PlatformFolders instance;
|
|
return instance;
|
|
}
|
|
}
|