diff options
Diffstat (limited to 'backends')
-rw-r--r-- | backends/platform/sdl/posix/posix.cpp | 95 | ||||
-rw-r--r-- | backends/platform/sdl/posix/posix.h | 4 |
2 files changed, 99 insertions, 0 deletions
diff --git a/backends/platform/sdl/posix/posix.cpp b/backends/platform/sdl/posix/posix.cpp index 4665228b1a..227f8ef0b3 100644 --- a/backends/platform/sdl/posix/posix.cpp +++ b/backends/platform/sdl/posix/posix.cpp @@ -156,6 +156,101 @@ Common::String OSystem_POSIX::getDefaultConfigFileName() { return configFile; } +Common::String OSystem_POSIX::getXdgUserDir(const char *name) { + // The xdg-user-dirs configuration path is stored in the XDG config + // home directory. We start by retrieving this value. + Common::String configHome = getenv("XDG_CONFIG_HOME"); + if (configHome.empty()) { + const char *home = getenv("HOME"); + if (!home) { + return ""; + } + + configHome = Common::String::format("%s/.config", home); + } + + // Find the requested directory line in the xdg-user-dirs configuration file + // Example line value: XDG_PICTURES_DIR="$HOME/Pictures" + Common::FSNode userDirsFile(configHome + "/user-dirs.dirs"); + if (!userDirsFile.exists() || !userDirsFile.isReadable() || userDirsFile.isDirectory()) { + return ""; + } + + Common::SeekableReadStream *userDirsStream = userDirsFile.createReadStream(); + if (!userDirsStream) { + return ""; + } + + Common::String dirLinePrefix = Common::String::format("XDG_%s_DIR=", name); + + Common::String directoryValue; + while (!userDirsStream->eos() && !userDirsStream->err()) { + Common::String userDirsLine = userDirsStream->readLine(); + userDirsLine.trim(); + + if (userDirsLine.hasPrefix(dirLinePrefix)) { + directoryValue = Common::String(userDirsLine.c_str() + dirLinePrefix.size()); + break; + } + } + + delete userDirsStream; + + // Extract the path from the value + // Example value: "$HOME/Pictures" + if (directoryValue.empty() || directoryValue[0] != '"') { + return ""; + } + + if (directoryValue[directoryValue.size() - 1] != '"') { + return ""; + } + + // According to the spec the value is shell-escaped, and would need to be + // unescaped to be used, but neither the GTK+ nor the Qt implementation seem to + // properly perform that step, it's probably fine if we don't do it either. + Common::String directoryPath(directoryValue.c_str() + 1, directoryValue.size() - 2); + + if (directoryPath.hasPrefix("$HOME/")) { + const char *home = getenv("HOME"); + directoryPath = Common::String::format("%s%s", home, directoryPath.c_str() + 5); + } + + // At this point, the path must be absolute + if (directoryPath.empty() || directoryPath[0] != '/') { + return ""; + } + + return directoryPath; +} + +Common::String OSystem_POSIX::getScreenshotsPath() { + // If the user has configured a screenshots path, use it + const Common::String path = OSystem_SDL::getScreenshotsPath(); + if (!path.empty()) { + return path; + } + + // Otherwise, the default screenshots path is the "ScummVM Screenshots" + // directory in the XDG "Pictures" user directory, as defined in the + // xdg-user-dirs spec: https://www.freedesktop.org/wiki/Software/xdg-user-dirs/ + Common::String picturesPath = getXdgUserDir("PICTURES"); + if (picturesPath.empty()) { + return ""; + } + + if (!picturesPath.hasSuffix("/")) { + picturesPath += "/"; + } + + static const char *SCREENSHOTS_DIR_NAME = "ScummVM Screenshots"; + if (!Posix::assureDirectoryExists(SCREENSHOTS_DIR_NAME, picturesPath.c_str())) { + return ""; + } + + return picturesPath + SCREENSHOTS_DIR_NAME + "/"; +} + void OSystem_POSIX::addSysArchivesToSearchSet(Common::SearchSet &s, int priority) { #ifdef DATA_PATH const char *snap = getenv("SNAP"); diff --git a/backends/platform/sdl/posix/posix.h b/backends/platform/sdl/posix/posix.h index bd3a069d5b..fd9bbadc9a 100644 --- a/backends/platform/sdl/posix/posix.h +++ b/backends/platform/sdl/posix/posix.h @@ -42,6 +42,8 @@ public: virtual void addSysArchivesToSearchSet(Common::SearchSet &s, int priority = 0); + Common::String getScreenshotsPath() override; + protected: /** * Base string for creating the default path and filename for the @@ -64,6 +66,8 @@ protected: virtual Common::WriteStream *createLogFile(); + Common::String getXdgUserDir(const char *name); + virtual AudioCDManager *createAudioCDManager(); bool launchBrowser(const Common::String& client, const Common::String &url); |