From 7a01b05b3861a667eb32ce2e0fc88ff3bacb99ae Mon Sep 17 00:00:00 2001 From: mogguh Date: Tue, 2 Sep 2008 17:25:26 +0000 Subject: Moved: The folder classes has been renamed to base Updated: ultrastardx.dpr has been changed accordingly git-svn-id: svn://svn.code.sf.net/p/ultrastardx/svn/trunk@1339 b956fd51-792f-4845-bead-9b4dfca2ff2c --- src/base/UPlatformMacOSX.pas | 294 +++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 294 insertions(+) create mode 100644 src/base/UPlatformMacOSX.pas (limited to 'src/base/UPlatformMacOSX.pas') diff --git a/src/base/UPlatformMacOSX.pas b/src/base/UPlatformMacOSX.pas new file mode 100644 index 00000000..2ab2a390 --- /dev/null +++ b/src/base/UPlatformMacOSX.pas @@ -0,0 +1,294 @@ +unit UPlatformMacOSX; + +interface + +{$IFDEF FPC} + {$MODE Delphi} +{$ENDIF} + +{$I switches.inc} + +uses + Classes, + ULog, + UPlatform; + +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 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/Resources/. + * GetGameUserPath could return + * ~/Library/Application Support/UltraStarDeluxe/Resources/. + * + * Right now, only $HOME/Library/Application Support/UltraStarDeluxe/Resources + * 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/Resources. 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 Resources folder 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. + *} + TPlatformMacOSX = class(TPlatform) + private + {** + * GetBundlePath returns the path to the application bundle UltraStarDeluxe.app. + *} + function GetBundlePath: WideString; + + {** + * GetApplicationSupportPath returns the path to + * $HOME/Library/Application Support/UltraStarDeluxe/Resources. + *} + function GetApplicationSupportPath: WideString; + + {** + * see the description of @link(Init). + *} + procedure CreateUserFolders(); + + public + {** + * Init simply calls @link(CreateUserFolders), which in turn scans the folder + * UltraStarDeluxe.app/Contents/Resources for all files and folders. + * $HOME/Library/Application Support/UltraStarDeluxe/Resources is then checked + * for their presence and missing ones are copied. + *} + procedure Init; override; + + {** + * DirectoryFindFiles returns all entries of a folder with names and booleans + * about their type, i.e. file or directory. + *} + function DirectoryFindFiles(Dir, Filter: WideString; ReturnAllSubDirs: boolean): TDirectoryEntryArray; override; + + {** + * GetLogPath returns the path for log messages. Currently it is set to + * $HOME/Library/Application Support/UltraStarDeluxe/Resources/Log. + *} + function GetLogPath : WideString; override; + + {** + * GetGameSharedPath returns the path for shared resources. Currently it is set to + * /Library/Application Support/UltraStarDeluxe/Resources. + * However it is not used. + *} + function GetGameSharedPath : WideString; override; + + {** + * GetGameUserPath returns the path for user resources. Currently it is set to + * $HOME/Library/Application Support/UltraStarDeluxe/Resources. + * This is where a user can add songs, themes, .... + *} + function GetGameUserPath : WideString; override; + end; + +implementation + +uses + SysUtils, + BaseUnix; + +procedure TPlatformMacOSX.Init; +begin + CreateUserFolders(); +end; + +procedure TPlatformMacOSX.CreateUserFolders(); +var + RelativePath: string; + // 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: string; + // 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: string; + // This record contains the result of a file search with FindFirst or FindNext + SearchInfo: TSearchRec; + // These two lists contain all folder and file names found + // within the folder @link(BaseDir). + DirectoryList, FileList: TStringList; + // 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; + Counter: longint; + + UserPathName: string; +const + // used to construct the @link(UserPathName) + PathName: string = '/Library/Application Support/UltraStarDeluxe/Resources'; +begin + // Get the current folder and save it in OldBaseDir for returning to it, when + // finished. + GetDir(0, OldBaseDir); + + // UltraStarDeluxe.app/Contents/Resources contains all the default files and + // folders. + BaseDir := OldBaseDir + '/UltraStarDeluxe.app/Contents/Resources'; + ChDir(BaseDir); + + // Right now, only $HOME/Library/Application Support/UltraStarDeluxe/Resources + // is used. + UserPathName := GetEnvironmentVariable('HOME') + PathName; + + DirectoryIsFinished := 0; + DirectoryList := TStringList.Create(); + FileList := TStringList.Create(); + DirectoryList.Add('.'); + + // create the folder and file lists + repeat + + RelativePath := DirectoryList[DirectoryIsFinished]; + ChDir(BaseDir + '/' + RelativePath); + if (FindFirst('*', faAnyFile, SearchInfo) = 0) then + begin + repeat + if DirectoryExists(SearchInfo.Name) then + begin + if (SearchInfo.Name <> '.') and (SearchInfo.Name <> '..') then + DirectoryList.Add(RelativePath + '/' + SearchInfo.Name); + end + else + Filelist.Add(RelativePath + '/' + SearchInfo.Name); + until (FindNext(SearchInfo) <> 0); + end; + FindClose(SearchInfo); + Inc(DirectoryIsFinished); + until (DirectoryIsFinished = DirectoryList.Count); + + // create missing folders + for Counter := 0 to DirectoryList.Count-1 do + begin + if not ForceDirectories(UserPathName + '/' + DirectoryList[Counter]) then + Log.LogError('Failed to create the folder "'+ UserPathName + '/' + DirectoryList[Counter] +'"', + 'TPlatformMacOSX.CreateUserFolders'); + end; + DirectoryList.Free(); + + // copy missing files + for Counter := 0 to Filelist.Count-1 do + begin + CopyFile(BaseDir + '/' + Filelist[Counter], + UserPathName + '/' + Filelist[Counter], true); + end; + FileList.Free(); + + // go back to the initial folder + ChDir(OldBaseDir); +end; + +function TPlatformMacOSX.GetBundlePath: WideString; +var + i, pos : integer; +begin + // Mac applications are packaged in folders. + // We have to cut the last two folders + // to get the application folder. + + Result := GetExecutionDir(); + for i := 1 to 2 do + begin + pos := Length(Result); + repeat + Delete(Result, pos, 1); + pos := Length(Result); + until (pos = 0) or (Result[pos] = '/'); + end; +end; + +function TPlatformMacOSX.GetApplicationSupportPath: WideString; +const + PathName : string = '/Library/Application Support/UltraStarDeluxe/Resources'; +begin + Result := GetEnvironmentVariable('HOME') + PathName + '/'; +end; + +function TPlatformMacOSX.GetLogPath: WideString; +begin + Result := GetApplicationSupportPath + 'Logs'; +end; + +function TPlatformMacOSX.GetGameSharedPath: WideString; +begin + Result := GetApplicationSupportPath; +end; + +function TPlatformMacOSX.GetGameUserPath: WideString; +begin + Result := GetApplicationSupportPath; +end; + +function TPlatformMacOSX.DirectoryFindFiles(Dir, Filter: WideString; ReturnAllSubDirs: boolean): TDirectoryEntryArray; +var + i : integer; + TheDir : pdir; + ADirent : pDirent; + lAttrib : integer; +begin + i := 0; + Filter := LowerCase(Filter); + + TheDir := FPOpenDir(Dir); + if Assigned(TheDir) then + repeat + ADirent := FPReadDir(TheDir); + + if Assigned(ADirent) and (ADirent^.d_name <> '.') and (ADirent^.d_name <> '..') then + begin + lAttrib := FileGetAttr(Dir + ADirent^.d_name); + if ReturnAllSubDirs and ((lAttrib and faDirectory) <> 0) then + begin + SetLength(Result, i + 1); + Result[i].Name := ADirent^.d_name; + Result[i].IsDirectory := true; + Result[i].IsFile := false; + i := i + 1; + end + else if (Length(Filter) = 0) or (Pos( Filter, LowerCase(ADirent^.d_name)) > 0) then + begin + SetLength(Result, i + 1); + Result[i].Name := ADirent^.d_name; + Result[i].IsDirectory := false; + Result[i].IsFile := true; + i := i + 1; + end; + end; + until ADirent = nil; + + FPCloseDir(TheDir); +end; + +end. -- cgit v1.2.3 From cbc9a8cc44af46886cacdf4cd825b3551894d0f7 Mon Sep 17 00:00:00 2001 From: k-m_schindler Date: Wed, 3 Sep 2008 23:21:38 +0000 Subject: Fixing a crash with Access violation if the folder Resources is missing in Application Support/UltraStarDeluxe git-svn-id: svn://svn.code.sf.net/p/ultrastardx/svn/trunk@1341 b956fd51-792f-4845-bead-9b4dfca2ff2c --- src/base/UPlatformMacOSX.pas | 2 ++ 1 file changed, 2 insertions(+) (limited to 'src/base/UPlatformMacOSX.pas') diff --git a/src/base/UPlatformMacOSX.pas b/src/base/UPlatformMacOSX.pas index 2ab2a390..217d4755 100644 --- a/src/base/UPlatformMacOSX.pas +++ b/src/base/UPlatformMacOSX.pas @@ -190,6 +190,8 @@ begin until (DirectoryIsFinished = DirectoryList.Count); // create missing folders + if not DirectoryExists(UserPathName) then + ForceDirectories(UserPathName); for Counter := 0 to DirectoryList.Count-1 do begin if not ForceDirectories(UserPathName + '/' + DirectoryList[Counter]) then -- cgit v1.2.3 From baa8e6ee782197a75038d0ab39c53f231bb66ba7 Mon Sep 17 00:00:00 2001 From: k-m_schindler Date: Thu, 4 Sep 2008 23:08:20 +0000 Subject: not needed test on presence of dir removed. Courtesy to tobigun git-svn-id: svn://svn.code.sf.net/p/ultrastardx/svn/trunk@1345 b956fd51-792f-4845-bead-9b4dfca2ff2c --- src/base/UPlatformMacOSX.pas | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) (limited to 'src/base/UPlatformMacOSX.pas') diff --git a/src/base/UPlatformMacOSX.pas b/src/base/UPlatformMacOSX.pas index 217d4755..788e0dda 100644 --- a/src/base/UPlatformMacOSX.pas +++ b/src/base/UPlatformMacOSX.pas @@ -190,8 +190,7 @@ begin until (DirectoryIsFinished = DirectoryList.Count); // create missing folders - if not DirectoryExists(UserPathName) then - ForceDirectories(UserPathName); + ForceDirectories(UserPathName); / should not be necessary since (UserPathName+'/.') is created. for Counter := 0 to DirectoryList.Count-1 do begin if not ForceDirectories(UserPathName + '/' + DirectoryList[Counter]) then -- cgit v1.2.3 From f3e8cb5a09ada2c74292047f2fad4fd47a01b99a Mon Sep 17 00:00:00 2001 From: k-m_schindler Date: Sun, 7 Sep 2008 21:41:53 +0000 Subject: fixed typo git-svn-id: svn://svn.code.sf.net/p/ultrastardx/svn/trunk@1350 b956fd51-792f-4845-bead-9b4dfca2ff2c --- src/base/UPlatformMacOSX.pas | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/base/UPlatformMacOSX.pas') diff --git a/src/base/UPlatformMacOSX.pas b/src/base/UPlatformMacOSX.pas index 788e0dda..cd58c3e8 100644 --- a/src/base/UPlatformMacOSX.pas +++ b/src/base/UPlatformMacOSX.pas @@ -190,7 +190,7 @@ begin until (DirectoryIsFinished = DirectoryList.Count); // create missing folders - ForceDirectories(UserPathName); / should not be necessary since (UserPathName+'/.') is created. + ForceDirectories(UserPathName); // should not be necessary since (UserPathName+'/.') is created. for Counter := 0 to DirectoryList.Count-1 do begin if not ForceDirectories(UserPathName + '/' + DirectoryList[Counter]) then -- cgit v1.2.3 From dbf39d5bfc56c24a67d481187c619dc84828221f Mon Sep 17 00:00:00 2001 From: k-m_schindler Date: Tue, 23 Sep 2008 21:17:22 +0000 Subject: gpl header added and property svn:header set to "HeadURL Id" git-svn-id: svn://svn.code.sf.net/p/ultrastardx/svn/trunk@1403 b956fd51-792f-4845-bead-9b4dfca2ff2c --- src/base/UPlatformMacOSX.pas | 25 +++++++++++++++++++++++++ 1 file changed, 25 insertions(+) (limited to 'src/base/UPlatformMacOSX.pas') diff --git a/src/base/UPlatformMacOSX.pas b/src/base/UPlatformMacOSX.pas index cd58c3e8..1aa37cd4 100644 --- a/src/base/UPlatformMacOSX.pas +++ b/src/base/UPlatformMacOSX.pas @@ -1,3 +1,28 @@ +{* 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 -- cgit v1.2.3 From c2416ccb64dc19cc4a690ba9cd6754fab59d709c Mon Sep 17 00:00:00 2001 From: k-m_schindler Date: Wed, 12 Nov 2008 21:18:43 +0000 Subject: some minor reformatting. no code change. git-svn-id: svn://svn.code.sf.net/p/ultrastardx/svn/trunk@1518 b956fd51-792f-4845-bead-9b4dfca2ff2c --- src/base/UPlatformMacOSX.pas | 60 +++++++++++++++++++++++--------------------- 1 file changed, 31 insertions(+), 29 deletions(-) (limited to 'src/base/UPlatformMacOSX.pas') diff --git a/src/base/UPlatformMacOSX.pas b/src/base/UPlatformMacOSX.pas index 1aa37cd4..0b44b76a 100644 --- a/src/base/UPlatformMacOSX.pas +++ b/src/base/UPlatformMacOSX.pas @@ -47,19 +47,21 @@ type * (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 folders in the user's home directory is against Apple's guidelines - * and strange to an average user. + * 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". + * 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: + * 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: + * 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/ @@ -75,8 +77,8 @@ type * Right now, only $HOME/Library/Application Support/UltraStarDeluxe/Resources * 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/Resources. However, this is not - * treated yet in the code outside this unit. + * /Library/Application Support/UltraStarDeluxe/Resources. 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 @@ -88,7 +90,8 @@ type TPlatformMacOSX = class(TPlatform) private {** - * GetBundlePath returns the path to the application bundle UltraStarDeluxe.app. + * GetBundlePath returns the path to the application bundle + * UltraStarDeluxe.app. *} function GetBundlePath: WideString; @@ -102,19 +105,19 @@ type * see the description of @link(Init). *} procedure CreateUserFolders(); - + public {** - * Init simply calls @link(CreateUserFolders), which in turn scans the folder - * UltraStarDeluxe.app/Contents/Resources for all files and folders. - * $HOME/Library/Application Support/UltraStarDeluxe/Resources is then checked - * for their presence and missing ones are copied. + * Init simply calls @link(CreateUserFolders), which in turn scans the + * folder UltraStarDeluxe.app/Contents/Resources for all files and + * folders. $HOME/Library/Application Support/UltraStarDeluxe/Resources + * is then checked for their presence and missing ones are copied. *} procedure Init; override; {** - * DirectoryFindFiles returns all entries of a folder with names and booleans - * about their type, i.e. file or directory. + * DirectoryFindFiles returns all entries of a folder with names and + * booleans about their type, i.e. file or directory. *} function DirectoryFindFiles(Dir, Filter: WideString; ReturnAllSubDirs: boolean): TDirectoryEntryArray; override; @@ -125,15 +128,15 @@ type function GetLogPath : WideString; override; {** - * GetGameSharedPath returns the path for shared resources. Currently it is set to - * /Library/Application Support/UltraStarDeluxe/Resources. + * GetGameSharedPath returns the path for shared resources. Currently it + * is set to /Library/Application Support/UltraStarDeluxe/Resources. * However it is not used. *} function GetGameSharedPath : WideString; override; {** - * GetGameUserPath returns the path for user resources. Currently it is set to - * $HOME/Library/Application Support/UltraStarDeluxe/Resources. + * GetGameUserPath returns the path for user resources. Currently it is + * set to $HOME/Library/Application Support/UltraStarDeluxe/Resources. * This is where a user can add songs, themes, .... *} function GetGameUserPath : WideString; override; @@ -192,7 +195,7 @@ begin DirectoryList := TStringList.Create(); FileList := TStringList.Create(); DirectoryList.Add('.'); - + // create the folder and file lists repeat @@ -203,7 +206,7 @@ begin repeat if DirectoryExists(SearchInfo.Name) then begin - if (SearchInfo.Name <> '.') and (SearchInfo.Name <> '..') then + if (SearchInfo.Name <> '.') and (SearchInfo.Name <> '..') then DirectoryList.Add(RelativePath + '/' + SearchInfo.Name); end else @@ -241,8 +244,7 @@ var i, pos : integer; begin // Mac applications are packaged in folders. - // We have to cut the last two folders - // to get the application folder. + // Cutting the last two folders yields the application folder. Result := GetExecutionDir(); for i := 1 to 2 do @@ -287,7 +289,7 @@ begin i := 0; Filter := LowerCase(Filter); - TheDir := FPOpenDir(Dir); + TheDir := FPOpenDir(Dir); if Assigned(TheDir) then repeat ADirent := FPReadDir(TheDir); -- cgit v1.2.3 From ccbf6ee893829ec067a629d7fa7771d3e73e4081 Mon Sep 17 00:00:00 2001 From: k-m_schindler Date: Sat, 29 Nov 2008 20:37:46 +0000 Subject: folders in Library/Application\ Support/UltraStarDeluxe/Resources can also be symlinks. No aliases, however. Courtesy to Filipe Cabecinhas. git-svn-id: svn://svn.code.sf.net/p/ultrastardx/svn/trunk@1531 b956fd51-792f-4845-bead-9b4dfca2ff2c --- src/base/UPlatformMacOSX.pas | 19 ++++++++++++++----- 1 file changed, 14 insertions(+), 5 deletions(-) (limited to 'src/base/UPlatformMacOSX.pas') diff --git a/src/base/UPlatformMacOSX.pas b/src/base/UPlatformMacOSX.pas index 0b44b76a..9085e337 100644 --- a/src/base/UPlatformMacOSX.pas +++ b/src/base/UPlatformMacOSX.pas @@ -154,6 +154,9 @@ begin end; procedure TPlatformMacOSX.CreateUserFolders(); +const + // used to construct the @link(UserPathName) + PathName: string = '/Library/Application Support/UltraStarDeluxe/Resources'; var RelativePath: string; // BaseDir contains the path to the folder, where a search is performed. @@ -172,11 +175,12 @@ var // searched for additional files and folders. DirectoryIsFinished: longint; Counter: longint; + // These three are for creating directories, due to possible symlinks + CreatedDirectory: boolean; + FileAttrs: integer; + DirectoryPath: string; - UserPathName: string; -const - // used to construct the @link(UserPathName) - PathName: string = '/Library/Application Support/UltraStarDeluxe/Resources'; + UserPathName: string; begin // Get the current folder and save it in OldBaseDir for returning to it, when // finished. @@ -221,7 +225,12 @@ begin ForceDirectories(UserPathName); // should not be necessary since (UserPathName+'/.') is created. for Counter := 0 to DirectoryList.Count-1 do begin - if not ForceDirectories(UserPathName + '/' + DirectoryList[Counter]) then + DirectoryPath := UserPathName + '/' + DirectoryList[Counter]; + CreatedDirectory := ForceDirectories(DirectoryPath); + FileAttrs := FileGetAttr(DirectoryPath); + // Don't know how to analyse the target of the link. + // 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 "'+ UserPathName + '/' + DirectoryList[Counter] +'"', 'TPlatformMacOSX.CreateUserFolders'); end; -- cgit v1.2.3 From 65eed3b389761e9e5b9cf09c7c7456540ca10ce7 Mon Sep 17 00:00:00 2001 From: k-m_schindler Date: Wed, 4 Mar 2009 18:06:26 +0000 Subject: Mac OS X only: change folder hierarchy in Application Support: delete Resources. Requires a new ./configure Attention: This requires manually moving all songs and anything else installed manually. git-svn-id: svn://svn.code.sf.net/p/ultrastardx/svn/trunk@1618 b956fd51-792f-4845-bead-9b4dfca2ff2c --- src/base/UPlatformMacOSX.pas | 32 ++++++++++++++++---------------- 1 file changed, 16 insertions(+), 16 deletions(-) (limited to 'src/base/UPlatformMacOSX.pas') diff --git a/src/base/UPlatformMacOSX.pas b/src/base/UPlatformMacOSX.pas index 9085e337..96e4bc63 100644 --- a/src/base/UPlatformMacOSX.pas +++ b/src/base/UPlatformMacOSX.pas @@ -70,19 +70,19 @@ type * * So * GetGameSharedPath could return - * /Library/Application Support/UltraStarDeluxe/Resources/. + * /Library/Application Support/UltraStarDeluxe/. * GetGameUserPath could return - * ~/Library/Application Support/UltraStarDeluxe/Resources/. + * ~/Library/Application Support/UltraStarDeluxe/. * - * Right now, only $HOME/Library/Application Support/UltraStarDeluxe/Resources + * 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/Resources. However, this is + * /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 Resources folder in the Application + * 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. @@ -97,7 +97,7 @@ type {** * GetApplicationSupportPath returns the path to - * $HOME/Library/Application Support/UltraStarDeluxe/Resources. + * $HOME/Library/Application Support/UltraStarDeluxe. *} function GetApplicationSupportPath: WideString; @@ -109,8 +109,8 @@ type public {** * Init simply calls @link(CreateUserFolders), which in turn scans the - * folder UltraStarDeluxe.app/Contents/Resources for all files and - * folders. $HOME/Library/Application Support/UltraStarDeluxe/Resources + * 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; @@ -123,20 +123,20 @@ type {** * GetLogPath returns the path for log messages. Currently it is set to - * $HOME/Library/Application Support/UltraStarDeluxe/Resources/Log. + * $HOME/Library/Application Support/UltraStarDeluxe/Log. *} function GetLogPath : WideString; override; {** * GetGameSharedPath returns the path for shared resources. Currently it - * is set to /Library/Application Support/UltraStarDeluxe/Resources. + * is set to /Library/Application Support/UltraStarDeluxe. * However it is not used. *} function GetGameSharedPath : WideString; override; {** * GetGameUserPath returns the path for user resources. Currently it is - * set to $HOME/Library/Application Support/UltraStarDeluxe/Resources. + * set to $HOME/Library/Application Support/UltraStarDeluxe. * This is where a user can add songs, themes, .... *} function GetGameUserPath : WideString; override; @@ -156,7 +156,7 @@ end; procedure TPlatformMacOSX.CreateUserFolders(); const // used to construct the @link(UserPathName) - PathName: string = '/Library/Application Support/UltraStarDeluxe/Resources'; + PathName: string = '/Library/Application Support/UltraStarDeluxe'; var RelativePath: string; // BaseDir contains the path to the folder, where a search is performed. @@ -186,12 +186,12 @@ begin // finished. GetDir(0, OldBaseDir); - // UltraStarDeluxe.app/Contents/Resources contains all the default files and + // UltraStarDeluxe.app/Contents contains all the default files and // folders. - BaseDir := OldBaseDir + '/UltraStarDeluxe.app/Contents/Resources'; + BaseDir := OldBaseDir + '/UltraStarDeluxe.app/Contents'; ChDir(BaseDir); - // Right now, only $HOME/Library/Application Support/UltraStarDeluxe/Resources + // Right now, only $HOME/Library/Application Support/UltraStarDeluxe // is used. UserPathName := GetEnvironmentVariable('HOME') + PathName; @@ -268,7 +268,7 @@ end; function TPlatformMacOSX.GetApplicationSupportPath: WideString; const - PathName : string = '/Library/Application Support/UltraStarDeluxe/Resources'; + PathName : string = '/Library/Application Support/UltraStarDeluxe'; begin Result := GetEnvironmentVariable('HOME') + PathName + '/'; end; -- cgit v1.2.3 From 917901e8e33438c425aef50a0a7417f32d77b760 Mon Sep 17 00:00:00 2001 From: s_alexander Date: Mon, 9 Nov 2009 00:27:55 +0000 Subject: merged unicode branch (r1931) into trunk git-svn-id: svn://svn.code.sf.net/p/ultrastardx/svn/trunk@1939 b956fd51-792f-4845-bead-9b4dfca2ff2c --- src/base/UPlatformMacOSX.pas | 194 ++++++++++++++++--------------------------- 1 file changed, 71 insertions(+), 123 deletions(-) (limited to 'src/base/UPlatformMacOSX.pas') diff --git a/src/base/UPlatformMacOSX.pas b/src/base/UPlatformMacOSX.pas index 96e4bc63..1dc0014a 100644 --- a/src/base/UPlatformMacOSX.pas +++ b/src/base/UPlatformMacOSX.pas @@ -36,7 +36,9 @@ interface uses Classes, ULog, - UPlatform; + UPlatform, + UFilesystem, + UPath; type {** @@ -93,19 +95,21 @@ type * GetBundlePath returns the path to the application bundle * UltraStarDeluxe.app. *} - function GetBundlePath: WideString; + function GetBundlePath: IPath; {** * GetApplicationSupportPath returns the path to * $HOME/Library/Application Support/UltraStarDeluxe. *} - function GetApplicationSupportPath: WideString; + function GetApplicationSupportPath: IPath; {** * see the description of @link(Init). *} procedure CreateUserFolders(); + function GetHomeDir(): IPath; + public {** * Init simply calls @link(CreateUserFolders), which in turn scans the @@ -115,38 +119,31 @@ type *} procedure Init; override; - {** - * DirectoryFindFiles returns all entries of a folder with names and - * booleans about their type, i.e. file or directory. - *} - function DirectoryFindFiles(Dir, Filter: WideString; ReturnAllSubDirs: boolean): TDirectoryEntryArray; override; - {** * GetLogPath returns the path for log messages. Currently it is set to * $HOME/Library/Application Support/UltraStarDeluxe/Log. *} - function GetLogPath : WideString; override; + function GetLogPath : IPath; override; {** * GetGameSharedPath returns the path for shared resources. Currently it * is set to /Library/Application Support/UltraStarDeluxe. * However it is not used. *} - function GetGameSharedPath : WideString; override; + 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 songs, themes, .... *} - function GetGameUserPath : WideString; override; + function GetGameUserPath : IPath; override; end; implementation uses - SysUtils, - BaseUnix; + SysUtils; procedure TPlatformMacOSX.Init; begin @@ -154,178 +151,129 @@ begin end; procedure TPlatformMacOSX.CreateUserFolders(); -const - // used to construct the @link(UserPathName) - PathName: string = '/Library/Application Support/UltraStarDeluxe'; var - RelativePath: string; + 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: string; + 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: string; - // This record contains the result of a file search with FindFirst or FindNext - SearchInfo: TSearchRec; + 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: TStringList; + 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; - Counter: longint; + I: longint; // These three are for creating directories, due to possible symlinks CreatedDirectory: boolean; FileAttrs: integer; - DirectoryPath: string; - - UserPathName: string; + DirectoryPath: IPath; + UserPath: IPath; + SrcFile, TgtFile: IPath; begin // Get the current folder and save it in OldBaseDir for returning to it, when // finished. - GetDir(0, OldBaseDir); + OldBaseDir := FileSystem.GetCurrentDir(); - // UltraStarDeluxe.app/Contents contains all the default files and - // folders. - BaseDir := OldBaseDir + '/UltraStarDeluxe.app/Contents'; - ChDir(BaseDir); + // 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. - UserPathName := GetEnvironmentVariable('HOME') + PathName; + // Right now, only $HOME/Library/Application Support/UltraStarDeluxe is used. + UserPath := GetGameUserPath(); DirectoryIsFinished := 0; - DirectoryList := TStringList.Create(); - FileList := TStringList.Create(); - DirectoryList.Add('.'); + // replace with IInterfaceList + DirectoryList := TInterfaceList.Create(); + FileList := TInterfaceList.Create(); + DirectoryList.Add(Path('.')); // create the folder and file lists repeat - - RelativePath := DirectoryList[DirectoryIsFinished]; - ChDir(BaseDir + '/' + RelativePath); - if (FindFirst('*', faAnyFile, SearchInfo) = 0) then + RelativePath := (DirectoryList[DirectoryIsFinished] as IPath); + FileSystem.SetCurrentDir(BaseDir.Append(RelativePath)); + Iter := FileSystem.FileFind(Path('*'), faAnyFile); + while (Iter.HasNext) do begin - repeat - if DirectoryExists(SearchInfo.Name) then - begin - if (SearchInfo.Name <> '.') and (SearchInfo.Name <> '..') then - DirectoryList.Add(RelativePath + '/' + SearchInfo.Name); - end - else - Filelist.Add(RelativePath + '/' + SearchInfo.Name); - until (FindNext(SearchInfo) <> 0); + FileInfo := Iter.Next; + CurPath := FileInfo.Name; + if CurPath.IsDirectory() then + begin + if (not CurPath.Equals('.')) and (not CurPath.Equals('..')) then + DirectoryList.Add(RelativePath.Append(CurPath)); + end + else + Filelist.Add(RelativePath.Append(CurPath)); end; - FindClose(SearchInfo); Inc(DirectoryIsFinished); until (DirectoryIsFinished = DirectoryList.Count); // create missing folders - ForceDirectories(UserPathName); // should not be necessary since (UserPathName+'/.') is created. - for Counter := 0 to DirectoryList.Count-1 do + UserPath.CreateDirectory(true); // should not be necessary since (UserPathName+'/.') is created. + for I := 0 to DirectoryList.Count-1 do begin - DirectoryPath := UserPathName + '/' + DirectoryList[Counter]; - CreatedDirectory := ForceDirectories(DirectoryPath); - FileAttrs := FileGetAttr(DirectoryPath); - // Don't know how to analyse the target of the link. + 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 "'+ UserPathName + '/' + DirectoryList[Counter] +'"', + Log.LogError('Failed to create the folder "'+ DirectoryPath.ToNative +'"', 'TPlatformMacOSX.CreateUserFolders'); end; - DirectoryList.Free(); // copy missing files - for Counter := 0 to Filelist.Count-1 do + for I := 0 to Filelist.Count-1 do begin - CopyFile(BaseDir + '/' + Filelist[Counter], - UserPathName + '/' + Filelist[Counter], true); + CurPath := Filelist[I] as IPath; + SrcFile := BaseDir.Append(CurPath); + TgtFile := UserPath.Append(CurPath); + SrcFile.CopyFile(TgtFile, true); end; - FileList.Free(); // go back to the initial folder - ChDir(OldBaseDir); + FileSystem.SetCurrentDir(OldBaseDir); end; -function TPlatformMacOSX.GetBundlePath: WideString; -var - i, pos : integer; +function TPlatformMacOSX.GetBundlePath: IPath; begin // Mac applications are packaged in folders. // Cutting the last two folders yields the application folder. - - Result := GetExecutionDir(); - for i := 1 to 2 do - begin - pos := Length(Result); - repeat - Delete(Result, pos, 1); - pos := Length(Result); - until (pos = 0) or (Result[pos] = '/'); - end; + Result := GetExecutionDir().GetParent().GetParent(); end; -function TPlatformMacOSX.GetApplicationSupportPath: WideString; +function TPlatformMacOSX.GetApplicationSupportPath: IPath; const - PathName : string = '/Library/Application Support/UltraStarDeluxe'; + PathName: string = 'Library/Application Support/UltraStarDeluxe'; begin - Result := GetEnvironmentVariable('HOME') + PathName + '/'; + Result := GetHomeDir().Append(PathName, pdAppend); end; -function TPlatformMacOSX.GetLogPath: WideString; +function TPlatformMacOSX.GetHomeDir(): IPath; begin - Result := GetApplicationSupportPath + 'Logs'; + Result := Path(GetEnvironmentVariable('HOME')); end; -function TPlatformMacOSX.GetGameSharedPath: WideString; +function TPlatformMacOSX.GetLogPath: IPath; begin - Result := GetApplicationSupportPath; + Result := GetApplicationSupportPath.Append('Logs'); end; -function TPlatformMacOSX.GetGameUserPath: WideString; +function TPlatformMacOSX.GetGameSharedPath: IPath; begin Result := GetApplicationSupportPath; end; -function TPlatformMacOSX.DirectoryFindFiles(Dir, Filter: WideString; ReturnAllSubDirs: boolean): TDirectoryEntryArray; -var - i : integer; - TheDir : pdir; - ADirent : pDirent; - lAttrib : integer; +function TPlatformMacOSX.GetGameUserPath: IPath; begin - i := 0; - Filter := LowerCase(Filter); - - TheDir := FPOpenDir(Dir); - if Assigned(TheDir) then - repeat - ADirent := FPReadDir(TheDir); - - if Assigned(ADirent) and (ADirent^.d_name <> '.') and (ADirent^.d_name <> '..') then - begin - lAttrib := FileGetAttr(Dir + ADirent^.d_name); - if ReturnAllSubDirs and ((lAttrib and faDirectory) <> 0) then - begin - SetLength(Result, i + 1); - Result[i].Name := ADirent^.d_name; - Result[i].IsDirectory := true; - Result[i].IsFile := false; - i := i + 1; - end - else if (Length(Filter) = 0) or (Pos( Filter, LowerCase(ADirent^.d_name)) > 0) then - begin - SetLength(Result, i + 1); - Result[i].Name := ADirent^.d_name; - Result[i].IsDirectory := false; - Result[i].IsFile := true; - i := i + 1; - end; - end; - until ADirent = nil; - - FPCloseDir(TheDir); + Result := GetApplicationSupportPath; end; end. -- cgit v1.2.3 From 9bcf10e01e4bb3b60b295c7173d7e7ce1eb5ed74 Mon Sep 17 00:00:00 2001 From: k-m_schindler Date: Fri, 19 Mar 2010 22:14:57 +0000 Subject: Do not copy the folder Mac OS with the binaries. Not needed. git-svn-id: svn://svn.code.sf.net/p/ultrastardx/svn/trunk@2210 b956fd51-792f-4845-bead-9b4dfca2ff2c --- src/base/UPlatformMacOSX.pas | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'src/base/UPlatformMacOSX.pas') diff --git a/src/base/UPlatformMacOSX.pas b/src/base/UPlatformMacOSX.pas index 1dc0014a..fda49a45 100644 --- a/src/base/UPlatformMacOSX.pas +++ b/src/base/UPlatformMacOSX.pas @@ -205,7 +205,9 @@ begin CurPath := FileInfo.Name; if CurPath.IsDirectory() then begin - if (not CurPath.Equals('.')) and (not CurPath.Equals('..')) then + if (not CurPath.Equals('.')) and + (not CurPath.Equals('..')) and + (not CurPath.Equals('MacOS')) then DirectoryList.Add(RelativePath.Append(CurPath)); end else -- cgit v1.2.3 From 429409de6a59388f26b4857851751b1017eba0ca Mon Sep 17 00:00:00 2001 From: k-m_schindler Date: Fri, 19 Mar 2010 22:21:51 +0000 Subject: lowercase log folder name and soure cosmetics. git-svn-id: svn://svn.code.sf.net/p/ultrastardx/svn/trunk@2211 b956fd51-792f-4845-bead-9b4dfca2ff2c --- src/base/UPlatformMacOSX.pas | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) (limited to 'src/base/UPlatformMacOSX.pas') diff --git a/src/base/UPlatformMacOSX.pas b/src/base/UPlatformMacOSX.pas index fda49a45..d55e8bea 100644 --- a/src/base/UPlatformMacOSX.pas +++ b/src/base/UPlatformMacOSX.pas @@ -121,23 +121,23 @@ type {** * GetLogPath returns the path for log messages. Currently it is set to - * $HOME/Library/Application Support/UltraStarDeluxe/Log. + * $HOME/Library/Application Support/UltraStarDeluxe/log. *} - function GetLogPath : IPath; override; + function GetLogPath: IPath; override; {** * GetGameSharedPath returns the path for shared resources. Currently it * is set to /Library/Application Support/UltraStarDeluxe. * However it is not used. *} - function GetGameSharedPath : IPath; override; + 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 songs, themes, .... *} - function GetGameUserPath : IPath; override; + function GetGameUserPath: IPath; override; end; implementation @@ -159,9 +159,9 @@ var // 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; + Iter: IFileIterator; + FileInfo: TFileInfo; + CurPath: IPath; // These two lists contain all folder and file names found // within the folder @link(BaseDir). DirectoryList, FileList: IInterfaceList; @@ -174,7 +174,7 @@ var CreatedDirectory: boolean; FileAttrs: integer; DirectoryPath: IPath; - UserPath: IPath; + UserPath: IPath; SrcFile, TgtFile: IPath; begin // Get the current folder and save it in OldBaseDir for returning to it, when @@ -265,7 +265,7 @@ end; function TPlatformMacOSX.GetLogPath: IPath; begin - Result := GetApplicationSupportPath.Append('Logs'); + Result := GetApplicationSupportPath.Append('logs'); end; function TPlatformMacOSX.GetGameSharedPath: IPath; -- cgit v1.2.3 From 88f143268a1ad7bd2af9fbb721ca9045f857ca1b Mon Sep 17 00:00:00 2001 From: k-m_schindler Date: Fri, 28 May 2010 06:54:05 +0000 Subject: move LogPath to "~/Library/Logs/UltraStar Deluxe" on Mac OS X git-svn-id: svn://svn.code.sf.net/p/ultrastardx/svn/trunk@2423 b956fd51-792f-4845-bead-9b4dfca2ff2c --- src/base/UPlatformMacOSX.pas | 14 ++++++-------- 1 file changed, 6 insertions(+), 8 deletions(-) (limited to 'src/base/UPlatformMacOSX.pas') diff --git a/src/base/UPlatformMacOSX.pas b/src/base/UPlatformMacOSX.pas index d55e8bea..6f718bcd 100644 --- a/src/base/UPlatformMacOSX.pas +++ b/src/base/UPlatformMacOSX.pas @@ -121,7 +121,7 @@ type {** * GetLogPath returns the path for log messages. Currently it is set to - * $HOME/Library/Application Support/UltraStarDeluxe/log. + * $HOME/Library/Logs/UltraStar Deluxe/. *} function GetLogPath: IPath; override; @@ -251,21 +251,19 @@ begin Result := GetExecutionDir().GetParent().GetParent(); end; -function TPlatformMacOSX.GetApplicationSupportPath: IPath; -const - PathName: string = 'Library/Application Support/UltraStarDeluxe'; +function TPlatformMacOSX.GetHomeDir(): IPath; begin - Result := GetHomeDir().Append(PathName, pdAppend); + Result := Path(GetEnvironmentVariable('HOME')); end; -function TPlatformMacOSX.GetHomeDir(): IPath; +function TPlatformMacOSX.GetApplicationSupportPath: IPath; begin - Result := Path(GetEnvironmentVariable('HOME')); + Result := GetHomeDir().Append('Library/Application Support/UltraStarDeluxe', pdAppend); end; function TPlatformMacOSX.GetLogPath: IPath; begin - Result := GetApplicationSupportPath.Append('logs'); + Result := GetHomeDir().Append('Library/Logs/UltraStar Deluxe', pdAppend); end; function TPlatformMacOSX.GetGameSharedPath: IPath; -- cgit v1.2.3 From cafa9b8034cbff7f7c3507f3f1b0b03a2e5455f7 Mon Sep 17 00:00:00 2001 From: k-m_schindler Date: Fri, 28 May 2010 22:35:34 +0000 Subject: add Music/Ultrastar Deluxe as a song folder. git-svn-id: svn://svn.code.sf.net/p/ultrastardx/svn/trunk@2424 b956fd51-792f-4845-bead-9b4dfca2ff2c --- src/base/UPlatformMacOSX.pas | 26 ++++++++++++++++++++------ 1 file changed, 20 insertions(+), 6 deletions(-) (limited to 'src/base/UPlatformMacOSX.pas') diff --git a/src/base/UPlatformMacOSX.pas b/src/base/UPlatformMacOSX.pas index 6f718bcd..7115a6b0 100644 --- a/src/base/UPlatformMacOSX.pas +++ b/src/base/UPlatformMacOSX.pas @@ -108,7 +108,10 @@ type *} procedure CreateUserFolders(); - function GetHomeDir(): IPath; + {** + * GetHomeDir returns the path to $HOME. + *} + function GetHomeDir: IPath; public {** @@ -125,9 +128,15 @@ type *} 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 set to /Library/Application Support/UltraStarDeluxe. + * is also set to $HOME/Library/Application Support/UltraStarDeluxe. * However it is not used. *} function GetGameSharedPath: IPath; override; @@ -135,7 +144,7 @@ type {** * GetGameUserPath returns the path for user resources. Currently it is * set to $HOME/Library/Application Support/UltraStarDeluxe. - * This is where a user can add songs, themes, .... + * This is where a user can add themes, .... *} function GetGameUserPath: IPath; override; end; @@ -251,19 +260,24 @@ begin Result := GetExecutionDir().GetParent().GetParent(); end; -function TPlatformMacOSX.GetHomeDir(): IPath; +function TPlatformMacOSX.GetHomeDir: IPath; begin Result := Path(GetEnvironmentVariable('HOME')); end; function TPlatformMacOSX.GetApplicationSupportPath: IPath; begin - Result := GetHomeDir().Append('Library/Application Support/UltraStarDeluxe', pdAppend); + Result := GetHomeDir.Append('Library/Application Support/UltraStarDeluxe', pdAppend); end; function TPlatformMacOSX.GetLogPath: IPath; begin - Result := GetHomeDir().Append('Library/Logs/UltraStar Deluxe', pdAppend); + 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; -- cgit v1.2.3