Permalink
Browse files

POSIX: Set the default screenshots path to the XDG Pictures directory

  • Loading branch information...
bgK committed Nov 16, 2018
1 parent e6dbdb8 commit add9a0b49a39a9e2a3c3cd3376afd3a4b7f71937
Showing with 101 additions and 0 deletions.
  1. +2 −0 README
  2. +95 −0 backends/platform/sdl/posix/posix.cpp
  3. +4 −0 backends/platform/sdl/posix/posix.h
2 README
@@ -2896,6 +2896,8 @@ The default location, when no screenshot path is defined in the config file,
depends on the OS:
Windows: In Users\username\My Pictures\ScummVM Screenshots.
macOS X: On the Desktop.
Other unices: In the XDG Pictures user directory,
e.g. ~/Pictures/ScummVM Screenshots.
Any other OS: In the current directory.
@@ -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");
@@ -42,6 +42,8 @@ class OSystem_POSIX : public OSystem_SDL {
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 @@ class OSystem_POSIX : public OSystem_SDL {
virtual Common::WriteStream *createLogFile();
Common::String getXdgUserDir(const char *name);
virtual AudioCDManager *createAudioCDManager();
bool launchBrowser(const Common::String& client, const Common::String &url);

0 comments on commit add9a0b

Please sign in to comment.