diff --git a/Makefile b/Makefile index 75eafc0..38f2d4b 100644 --- a/Makefile +++ b/Makefile @@ -14,6 +14,14 @@ else BASE_CFLAGS+= -std=c++03 endif +#This is used to detect Mac because Mac needs CoreServices for linking +ifneq ($(OS),Windows_NT) +UNAME := $(shell uname -s) +ifeq ($(UNAME),Darwin) +BASE_LIBS+= -framework CoreServices +endif +endif + PROGRAMNAME=platform_folders O_FILES=${PROGRAMNAME}.o sago/platform_folders.o diff --git a/sago/platform_folders.cpp b/sago/platform_folders.cpp index b7d5779..f9b5e14 100644 --- a/sago/platform_folders.cpp +++ b/sago/platform_folders.cpp @@ -58,6 +58,22 @@ static std::string GetAppDataCommon() { static std::string GetAppDataLocal() { return GetWindowsFolder(CSIDL_LOCAL_APPDATA, "LocalAppData could not be found"); } +#elif defined(__APPLE__) +#include + +static std::string GetMacFolder(OSType folderType, const char* errorMsg) { + std::string ret; + FSRef ref; + char path[PATH_MAX]; + OSStatus err = FSFindFolder( kUserDomain, folderType, kCreateFolder, &ref ); + if (err != noErr) { + throw std::runtime_error(errorMsg); + } + FSRefMakePath( &ref, (UInt8*)&path, PATH_MAX ); + ret = path; + return ret; +} + #else #include #include @@ -147,6 +163,8 @@ namespace sago { std::string getDataHome() { #if defined(_WIN32) return GetAppData(); +#elif defined(__APPLE__) + return GetMacFolder(kApplicationSupportFolderType, "Failed to find the Application Support Folder"); #else return getLinuxFolderDefault("XDG_DATA_HOME", ".local/share"); #endif @@ -155,6 +173,8 @@ std::string getDataHome() { std::string getConfigHome() { #if defined(_WIN32) return GetAppData(); +#elif defined(__APPLE__) + return GetMacFolder(kApplicationSupportFolderType, "Failed to find the Application Support Folder"); #else return getLinuxFolderDefault("XDG_CONFIG_HOME", ".config"); #endif @@ -163,6 +183,8 @@ std::string getConfigHome() { std::string getCacheDir() { #if defined(_WIN32) return GetAppDataLocal(); +#elif defined(__APPLE__) + return GetMacFolder(kCachedDataFolderType, "Failed to find the Application Support Folder"); #else return getLinuxFolderDefault("XDG_CONFIG_HOME", ".cache"); #endif @@ -171,6 +193,7 @@ std::string getCacheDir() { void appendAdditionalDataDirectories(std::vector& homes) { #if defined(_WIN32) homes.push_back(GetAppDataCommon()); +#elif defined(__APPLE__) #else appendExtraFolders("XDG_DATA_DIRS", "/usr/local/share/:/usr/share/", homes); #endif @@ -179,12 +202,14 @@ void appendAdditionalDataDirectories(std::vector& homes) { void appendAdditionalConfigDirectories(std::vector& homes) { #if defined(_WIN32) homes.push_back(GetAppDataCommon()); +#elif defined(__APPLE__) #else appendExtraFolders("XDG_CONFIG_DIRS", "/etc/xdg", homes); #endif } #if defined(_WIN32) +#elif defined(__APPLE__) #else struct PlatformFolders::PlatformFoldersData { std::map folders; @@ -226,6 +251,7 @@ static void PlatformFoldersFillData(std::map& folders) PlatformFolders::PlatformFolders() { #if defined(_WIN32) +#elif defined(__APPLE__) #else this->data = new PlatformFolders::PlatformFoldersData(); try { @@ -239,6 +265,7 @@ PlatformFolders::PlatformFolders() { PlatformFolders::~PlatformFolders() { #if defined(_WIN32) +#elif defined(__APPLE__) #else delete this->data; #endif @@ -247,6 +274,8 @@ PlatformFolders::~PlatformFolders() { std::string PlatformFolders::getDocumentsFolder() const { #if defined(_WIN32) return GetWindowsFolder(CSIDL_PERSONAL, "Failed to find My Documents folder"); +#elif defined(__APPLE__) + return GetMacFolder(kDocumentsFolderType, "Failed to find Documents Folder"); #else return data->folders["XDG_DOCUMENTS_DIR"]; #endif @@ -255,6 +284,8 @@ std::string PlatformFolders::getDocumentsFolder() const { std::string PlatformFolders::getDesktopFolder() const { #if defined(_WIN32) return GetWindowsFolder(CSIDL_DESKTOP, "Failed to find Desktop folder"); +#elif defined(__APPLE__) + return GetMacFolder(kDesktopFolderType, "Failed to find Desktop folder"); #else return data->folders["XDG_DESKTOP_DIR"]; #endif @@ -263,6 +294,8 @@ std::string PlatformFolders::getDesktopFolder() const { std::string PlatformFolders::getPicturesFolder() const { #if defined(_WIN32) return GetWindowsFolder(CSIDL_MYPICTURES, "Failed to find My Pictures folder"); +#elif defined(__APPLE__) + return GetMacFolder(kPictureDocumentsFolderType, "Failed to find Picture folder"); #else return data->folders["XDG_PICTURES_DIR"]; #endif @@ -272,6 +305,8 @@ std::string PlatformFolders::getDownloadFolder1() const { #if defined(_WIN32) //Pre Vista. Files was downloaded to the desktop return GetWindowsFolder(CSIDL_DESKTOP, "Failed to find My Downloads (Desktop) folder"); +#elif defined(__APPLE__) + return GetMacFolder(kDownloadsFolderType, "Failed to find Download folder"); #else return data->folders["XDG_DOWNLOAD_DIR"]; #endif @@ -280,6 +315,8 @@ std::string PlatformFolders::getDownloadFolder1() const { std::string PlatformFolders::getMusicFolder() const { #if defined(_WIN32) return GetWindowsFolder(CSIDL_MYMUSIC, "Failed to find My Music folder"); +#elif defined(__APPLE__) + return GetMacFolder(kMusicDocumentsFolderType, "Failed to find Music folder"); #else return data->folders["XDG_MUSIC_DIR"]; #endif @@ -288,6 +325,8 @@ std::string PlatformFolders::getMusicFolder() const { std::string PlatformFolders::getVideoFolder() const { #if defined(_WIN32) return GetWindowsFolder(CSIDL_MYVIDEO, "Failed to find My Video folder"); +#elif defined(__APPLE__) + return GetMacFolder(kMovieDocumentsFolderType, "Failed to find Movie folder"); #else return data->folders["XDG_VIDEOS_DIR"]; #endif @@ -298,6 +337,8 @@ std::string PlatformFolders::getSaveGamesFolder1() const { //A dedicated Save Games folder was not introduced until Vista. For XP and older save games are most often saved in a normal folder named "My Games". //Data that should not be user accessible should be placed under GetDataHome() instead return GetWindowsFolder(CSIDL_PERSONAL, "Failed to find My Documents folder")+"\\My Games"; +#elif defined(__APPLE__) + return GetMacFolder(kApplicationSupportFolderType, "Failed to find Application Support Folder"); #else return getDataHome(); #endif