diff --git a/CMakeLists.txt b/CMakeLists.txt index ed2c331..de68bf3 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -168,6 +168,20 @@ set(MAIN_SOURCE source_group("MKXP Source" FILES ${MAIN_SOURCE} ${MAIN_HEADERS}) +## Platform source ## + +if(LINUX) + set(PLATFORM_SOURCE + src/platform_linux.cpp + ) +elseif(APPLE) + set(PLATFORM_SOURCE + src/platform_osx.mm + ) +else() + message(FATAL_ERROR "No platform source for this platform") +endif() + ## Setup embedded source ## set(EMBEDDED_INPUT @@ -340,6 +354,7 @@ add_executable(${PROJECT_NAME} MACOSX_BUNDLE ${BINDING_HEADERS} ${BINDING_SOURCE} ${EMBEDDED_SOURCE} + ${PLATFORM_SOURCE} ) target_compile_definitions(${PROJECT_NAME} PRIVATE diff --git a/src/config.cpp b/src/config.cpp index 7e3091f..e2eb338 100644 --- a/src/config.cpp +++ b/src/config.cpp @@ -50,7 +50,9 @@ Config::Config() anyAltToggleFS(false), allowSymlinks(false), pathCache(true) -{} +{ + setupPaths(); +} void Config::read(int argc, char *argv[]) { diff --git a/src/config.h b/src/config.h index 411ce51..ec956e5 100644 --- a/src/config.h +++ b/src/config.h @@ -50,6 +50,8 @@ struct Config bool pathCache; std::string iconPath; + + std::string desktopPath; std::string customScript; std::vector<std::string> rtps; @@ -64,6 +66,8 @@ struct Config void read(int argc, char *argv[]); void readGameINI(); +private: + void setupPaths(); }; #endif // CONFIG_H diff --git a/src/graphics.cpp b/src/graphics.cpp index 22236ff..9394539 100644 --- a/src/graphics.cpp +++ b/src/graphics.cpp @@ -544,7 +544,8 @@ struct GraphicsPrivate snprintf(filename, sizeof(filename), "%d%02d%02d-%02d%02d%02d.png", tm.tm_year+1900, tm.tm_mon+1, tm.tm_mday, tm.tm_hour, tm.tm_min, tm.tm_sec); - writeScreenshot(filename); + std::string path = threadData->config.desktopPath + filename; + writeScreenshot(path.c_str()); } }; diff --git a/src/platform_linux.cpp b/src/platform_linux.cpp new file mode 100644 index 0000000..fb4ba82 --- /dev/null +++ b/src/platform_linux.cpp @@ -0,0 +1,91 @@ +#include "config.h" + +#include <stdlib.h> +#include <fstream> +#include <string> +#include <unistd.h> +#include <boost/algorithm/string.hpp> + +inline void ensure_trailing_slash(std::string& path) +{ + if (path.size() && path[path.size()-1] != '/') { + path += "/"; + } +} + +static std::string find_xdg_config_dir() +{ + std::string path; + const char* env = getenv("XDG_CONFIG_HOME"); + if (env) { + path = env; + ensure_trailing_slash(path); + } else { + env = getenv("HOME"); + if (!env) { + return ""; + } + path = env; + ensure_trailing_slash(path); + path += ".config/"; + } + return path; +} + +static std::string get_desktop_dir() +{ + std::string desktopPath; + + std::string cfg_dir = find_xdg_config_dir(); + if (!cfg_dir.empty()) { + std::string cfg_file = cfg_dir + "user-dirs.dirs"; + if (access(cfg_file.c_str(), F_OK) == 0) { + std::ifstream fin(cfg_file.c_str()); + std::string line; + while (std::getline(fin, line)) { + /* skip blank and comment lines */ + if (line.empty() || line[0] == '#') continue; + + std::vector<std::string> parts; + boost::split(parts, line, boost::is_any_of("=")); + if (parts.size() == 2) { + std::string key = boost::trim_copy(parts[0]); + if (key == "XDG_DESKTOP_DIR") { + std::string val = boost::trim_copy_if(parts[1], boost::is_any_of(" \n\r\t\"")); + desktopPath = val; + break; + } + } + } + } + } + const char* home = getenv("HOME"); + if (home) { + size_t pos = desktopPath.find("$HOME"); + if (pos != desktopPath.npos) { + desktopPath.replace(pos, pos + 5, home); + } + pos = desktopPath.find("${HOME}"); + if (pos != desktopPath.npos) { + desktopPath.replace(pos, pos + 7, home); + } + } + if (desktopPath.empty() || access(desktopPath.c_str(), F_OK) != 0) { + if (home) { + desktopPath = home; + ensure_trailing_slash(desktopPath); + if (access((desktopPath + "Desktop").c_str(), F_OK) == 0) { + desktopPath += "Desktop/"; + } + } else { + desktopPath = ""; + } + } + ensure_trailing_slash(desktopPath); + return desktopPath; +} + +void Config::setupPaths() +{ + desktopPath = get_desktop_dir(); +} \ No newline at end of file diff --git a/src/platform_osx.mm b/src/platform_osx.mm new file mode 100644 index 0000000..e84f022 --- /dev/null +++ b/src/platform_osx.mm @@ -0,0 +1,35 @@ +#include "config.h" + +#include <string> + +#import <Foundation/Foundation.h> + +static void ensure_trailing_slash(std::string& path) +{ + if (path.size() && path[path.size()-1] != '/') { + path += "/"; + } +} + +static std::string get_desktop_dir() +{ + std::string ret; + NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init]; + + NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDesktopDirectory, NSUserDomainMask, YES); + NSString *path = [paths objectAtIndex: 0]; + + ret = [path fileSystemRepresentation]; + + [pool drain]; + + ensure_trailing_slash(ret); + return ret; +} + + +void Config::setupPaths() +{ + desktopPath = get_desktop_dir(); +} +