From 0b60f71cb853b35e53d0b407493dbcfc098ed40e Mon Sep 17 00:00:00 2001 From: tobigun Date: Tue, 19 Oct 2010 16:39:31 +0000 Subject: initial commit git-svn-id: svn://svn.code.sf.net/p/ultrastardx/svn/branches/experimental@2684 b956fd51-792f-4845-bead-9b4dfca2ff2c --- mediaplugin/src/base/UPlatformMacOSX.pas | 302 +++++++++++++++++++++++++++++++ 1 file changed, 302 insertions(+) create mode 100644 mediaplugin/src/base/UPlatformMacOSX.pas (limited to 'mediaplugin/src/base/UPlatformMacOSX.pas') diff --git a/mediaplugin/src/base/UPlatformMacOSX.pas b/mediaplugin/src/base/UPlatformMacOSX.pas new file mode 100644 index 00000000..3a3e3f79 --- /dev/null +++ b/mediaplugin/src/base/UPlatformMacOSX.pas @@ -0,0 +1,302 @@ +{* UltraStar Deluxe - Karaoke Game + * + * UltraStar Deluxe is the legal property of its developers, whose names + * are too numerous to list here. Please refer to the COPYRIGHT + * file distributed with this source distribution. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; see the file COPYING. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301, USA. + * + * $URL$ + * $Id$ + *} + +unit UPlatformMacOSX; + +interface + +{$IFDEF FPC} + {$MODE Delphi} +{$ENDIF} + +{$I switches.inc} + +uses + Classes, + ULog, + UPlatform, + UFilesystem, + UPath; + +type + {** + * @abstract(Provides Mac OS X specific details.) + * @lastmod(August 1, 2008) + * The UPlatformMacOSX unit takes care of setting paths to resource folders. + * + * (Note for non-Maccies: "folder" is the Mac name for directory.) + * + * Note on the resource folders: + * 1. Installation of an application on the mac works as follows: Extract and + * copy an application and if you don't like or need the application + * anymore you move the folder to the trash - and you're done. + * 2. The use of folders in the user's home directory is against Apple's + * guidelines and strange to an average user. + * 3. Even worse is using /usr/local/... since all lowercase folders in / are + * not visible to an average user in the Finder, at least not without some + * "tricks". + * + * The best way would be to store everything within the application bundle. + * However, this requires USDX to offer the handling of the resources. Until + * this is implemented, the second best solution is as follows: + * + * According to Aple guidelines handling of resources and folders should follow + * these lines: + * + * Acceptable places for files are folders named UltraStarDeluxe either in + * /Library/Application Support/ + * or + * ~/Library/Application Support/ + * + * So + * GetGameSharedPath could return + * /Library/Application Support/UltraStarDeluxe/. + * GetGameUserPath could return + * ~/Library/Application Support/UltraStarDeluxe/. + * + * Right now, only $HOME/Library/Application Support/UltraStarDeluxe + * is used. So every user needs the complete set of files and folders. + * Future versions may also use shared resources in + * /Library/Application Support/UltraStarDeluxe. However, this is + * not treated yet in the code outside this unit. + * + * USDX checks, whether GetGameUserPath exists. If not, USDX creates it. + * The existence of needed files is then checked and if a file is missing + * it is copied to there from within the folder Contents in the Application + * bundle, which contains the default files. USDX should not delete files or + * folders in Application Support/UltraStarDeluxe automatically or without + * user confirmation. + * + * The log and benchmark files are stored in + * $HOME/Library/Log/UltraStar Deluxe/ + * + * Music should go into ~/Music/UltraStar Deluxe/ + * + * ~/Library/Application Support/UltraStarDeluxe/songs is also used. + * The idea is to remove this at some time. + * + *} + TPlatformMacOSX = class(TPlatform) + private + {** + * GetBundlePath returns the path to the application bundle + * UltraStarDeluxe.app. + *} + function GetBundlePath: IPath; + + {** + * GetApplicationSupportPath returns the path to + * $HOME/Library/Application Support/UltraStarDeluxe. + *} + function GetApplicationSupportPath: IPath; + + {** + * see the description of @link(Init). + *} + procedure CreateUserFolders(); + + {** + * GetHomeDir returns the path to $HOME. + *} + function GetHomeDir: IPath; + + public + {** + * Init simply calls @link(CreateUserFolders), which in turn scans the + * folder UltraStarDeluxe.app/Contents for all files and + * folders. $HOME/Library/Application Support/UltraStarDeluxe + * is then checked for their presence and missing ones are copied. + *} + procedure Init; override; + + {** + * GetLogPath returns the path for log messages. Currently it is set to + * $HOME/Library/Logs/UltraStar Deluxe/. + *} + function GetLogPath: IPath; override; + + {** + * GetMusicPath returns the path for music. Currently it is set to + * $HOME/Music/UltraStar Deluxe/. + *} + function GetMusicPath: IPath; override; + + {** + * GetGameSharedPath returns the path for shared resources. Currently it + * is also set to $HOME/Library/Application Support/UltraStarDeluxe. + * However it is not used. + *} + function GetGameSharedPath: IPath; override; + + {** + * GetGameUserPath returns the path for user resources. Currently it is + * set to $HOME/Library/Application Support/UltraStarDeluxe. + * This is where a user can add themes, .... + *} + function GetGameUserPath: IPath; override; + end; + +implementation + +uses + SysUtils; + +procedure TPlatformMacOSX.Init; +begin + CreateUserFolders(); +end; + +procedure TPlatformMacOSX.CreateUserFolders(); +var + RelativePath: IPath; + // BaseDir contains the path to the folder, where a search is performed. + // It is set to the entries in @link(DirectoryList) one after the other. + BaseDir: IPath; + // OldBaseDir contains the path to the folder, where the search started. + // It is used to return to it, when the search is completed in all folders. + OldBaseDir: IPath; + Iter: IFileIterator; + FileInfo: TFileInfo; + CurPath: IPath; + // These two lists contain all folder and file names found + // within the folder @link(BaseDir). + DirectoryList, FileList: IInterfaceList; + // DirectoryIsFinished contains the index of the folder in @link(DirectoryList), + // which is the last one completely searched. Later folders are still to be + // searched for additional files and folders. + DirectoryIsFinished: longint; + I: longint; + // These three are for creating directories, due to possible symlinks + CreatedDirectory: boolean; + FileAttrs: integer; + DirectoryPath: IPath; + UserPath: IPath; + SrcFile, TgtFile: IPath; +begin + // Get the current folder and save it in OldBaseDir for returning to it, when + // finished. + OldBaseDir := FileSystem.GetCurrentDir(); + + // UltraStarDeluxe.app/Contents contains all the default files and folders. + BaseDir := OldBaseDir.Append('UltraStarDeluxe.app/Contents'); + FileSystem.SetCurrentDir(BaseDir); + + // Right now, only $HOME/Library/Application Support/UltraStarDeluxe is used. + UserPath := GetGameUserPath(); + + DirectoryIsFinished := 0; + // replace with IInterfaceList + DirectoryList := TInterfaceList.Create(); + FileList := TInterfaceList.Create(); + DirectoryList.Add(Path('.')); + + // create the folder and file lists + repeat + RelativePath := (DirectoryList[DirectoryIsFinished] as IPath); + FileSystem.SetCurrentDir(BaseDir.Append(RelativePath)); + Iter := FileSystem.FileFind(Path('*'), faAnyFile); + while (Iter.HasNext) do + begin + FileInfo := Iter.Next; + CurPath := FileInfo.Name; + if CurPath.IsDirectory() then + begin + if (not CurPath.Equals('.')) and + (not CurPath.Equals('..')) and + (not CurPath.Equals('MacOS')) then + DirectoryList.Add(RelativePath.Append(CurPath)); + end + else + Filelist.Add(RelativePath.Append(CurPath)); + end; + Inc(DirectoryIsFinished); + until (DirectoryIsFinished = DirectoryList.Count); + + // create missing folders + UserPath.CreateDirectory(true); // should not be necessary since (UserPathName+'/.') is created. + for I := 0 to DirectoryList.Count-1 do + begin + CurPath := DirectoryList[I] as IPath; + DirectoryPath := UserPath.Append(CurPath); + CreatedDirectory := DirectoryPath.CreateDirectory(); + FileAttrs := DirectoryPath.GetAttr(); + // Maybe analyse the target of the link with FpReadlink(). + // Let's assume the symlink is pointing to an existing directory. + if (not CreatedDirectory) and (FileAttrs and faSymLink > 0) then + Log.LogError('Failed to create the folder "'+ DirectoryPath.ToNative +'"', + 'TPlatformMacOSX.CreateUserFolders'); + end; + + // copy missing files + for I := 0 to Filelist.Count-1 do + begin + CurPath := Filelist[I] as IPath; + SrcFile := BaseDir.Append(CurPath); + TgtFile := UserPath.Append(CurPath); + SrcFile.CopyFile(TgtFile, true); + end; + + // go back to the initial folder + FileSystem.SetCurrentDir(OldBaseDir); +end; + +function TPlatformMacOSX.GetBundlePath: IPath; +begin + // Mac applications are packaged in folders. + // Cutting the last two folders yields the application folder. + Result := GetExecutionDir().GetParent().GetParent(); +end; + +function TPlatformMacOSX.GetHomeDir: IPath; +begin + Result := Path(GetEnvironmentVariable('HOME')); +end; + +function TPlatformMacOSX.GetApplicationSupportPath: IPath; +begin + Result := GetHomeDir.Append('Library/Application Support/UltraStarDeluxe', pdAppend); +end; + +function TPlatformMacOSX.GetLogPath: IPath; +begin + Result := GetHomeDir.Append('Library/Logs/UltraStar Deluxe', pdAppend); +end; + +function TPlatformMacOSX.GetMusicPath: IPath; +begin + Result := GetHomeDir.Append('Music/UltraStar Deluxe', pdAppend); +end; + +function TPlatformMacOSX.GetGameSharedPath: IPath; +begin + Result := GetApplicationSupportPath; +end; + +function TPlatformMacOSX.GetGameUserPath: IPath; +begin + Result := GetApplicationSupportPath; +end; + +end. -- cgit v1.2.3