1 { This file is part of WineLauncher.
3 WineLauncher is free software: you can redistribute it and/or modify
4 it under the terms of the GNU General Public License as published by
5 the Free Software Foundation, version 3 of the License.
7 WineLauncher is distributed in the hope that it will be useful,
8 but WITHOUT ANY WARRANTY; without even the implied warranty of
9 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10 GNU General Public License for more details.
12 You should have received a copy of the GNU General Public License
13 along with WineLauncher. If not, see <http://www.gnu.org/licenses/>.
23 Classes
, SysUtils
, strutils
, BaseUnix
, Process
, StdCtrls
, FileUtil
, Graphics
;
25 procedure Log(Level
:integer; Channel
:string; LogText
:string);
27 procedure LogVar(MyVar
:string; MyVarName
:string);
30 function Wrap(Input
:string):string; { Makes Paths look better, E.G. " ( Input ) " }
31 function WinToUnixPath(Path
:string):string;
32 function UnixToWinPath(Path
:string; DriveChar
:Char):string;
33 function GetUnixDirPath(FilePath
:string):string;
34 function FileExistsAndIsExecutable(FullPath
:string; JustCheckExists
:boolean): boolean ;
35 function WorkDirTemplate(FolderPath
:string):string;
36 function DoesFolderExists(Path
:string; FolderName
:string): boolean;
37 function DoesFoldersExists(Path
:string; FolderNames
:Tstrings
): boolean;
38 function DirExistsIfNotMakeIt(Path
:string; FolderName
:string ): boolean;
39 function DirExistsIfNotMakeIt(PathWithFolder
:string): boolean;
40 function CheckPaths():boolean;
41 function SetupGit():boolean;
42 function MakeFile(FullPath
:string;Data
:string):boolean;
43 function SetExecutableFlag(FullPath
:string):boolean;
44 function ColourCheck(Input
: TEdit
):boolean;
45 function CutUpFlags(Flags
:string):boolean;
46 function FindPrefixInt(PrefixName
:string):integer;
47 function GetWinFileName(FullPath
:string):string;
58 function FileExistsAndIsExecutable(FullPath
:string; JustCheckExists
:boolean): boolean ;
62 ChannelLocal
:= ('FileExistsAndIsExecutable');
64 if JustCheckExists
= true then
66 if FileExists(FullPath
) then
69 if JustCheckExists
= true then Log(3, ChannelLocal
, 'File' + Wrap(FullPath
) + 'exists.');
75 Log(4, ChannelLocal
,'File' + Wrap(FullPath
) + 'does not exists.');
81 if FpAccess(FullPath
, X_OK
{Exe flag check}) <> 0 then
83 Log(4, ChannelLocal
,'File' + Wrap(FullPath
) + 'is not executable.');
89 Log(3, ChannelLocal
,'File' + Wrap(FullPath
) + 'is executable.');
97 function Wrap(Input
: string):string;
99 Result
:= ( ' ( ' + Input
+ ' ) ' );
102 function DoesFoldersExists(Path
:string; FolderNames
:Tstrings
): boolean;
107 { Take a path and check to see if the listed folders exists in that path. }
108 { TODO : Add a way to check the result from each one and return it. }
109 for loop
:= 0 to ( FolderNames
.Count
- 1 ) do
111 if DoesFolderExists(Path
, FolderNames
[loop
]) = false then
119 function DoesFolderExists(Path
:string; FolderName
:string): boolean;
123 ChannelLocal
:= 'DoesFolderExists';
124 if DirectoryExists(Path
+ FolderName
) = true then
128 UnitMain
.form1
.LogWithDebug(3, ChannelLocal
, ('Folder' + Wrap(Path
+ FolderName
) + 'exists.'));
134 Log(4, ChannelLocal
, ('Folder' + Wrap(Path
+ FolderName
) + 'does not exists.'));
138 procedure Log(Level
:integer; Channel
:string; LogText
:string);
147 {Level 4 "Dev-Error"}
148 {Level 5 is for uses with custom functions.}
151 0: LevelString
:= 'Info';
152 1: LevelString
:= 'Error';
153 2: LevelString
:= 'Variable';
154 3: LevelString
:= 'Dev-Info';
155 4: LevelString
:= 'Dev-Error';
164 if HideChannel
= true then
166 OutPut
:= (LevelString
+ ': ' + LogText
);
170 OutPut
:= (LevelString
+ ':' + Channel
+ ': ' + LogText
);
175 if UnitMain
.form1
<> nil then
177 UnitMain
.form1
.Memo_LogOutPut
.Lines
.Add(OutPut
);
181 function WinToUnixPath(Path
:string):string;
183 PathUpToDosdevices
:string;
184 DriveNameWithSlash
:string;
187 {Get the path up to Dosdevices.}
188 PathUpToDosdevices
:= (GetEnvironmentVariable('HOME') + '/' + WineUserFolder
+ '/prefix/' + UnitMain
.form1
.ComboBox_PreFix
.Text + '/dosdevices/' );
189 {Take the DriveName off 'path' and replace '\' with '/'.}
190 DriveNameWithSlash
:= (AnsiLowerCase( Copy2SymbDel( Path
, '\' )) + '/');
191 {Replace all '\' to '/'.}
192 Path
:= AnsiReplaceText(Path
, '\', '/');
194 FullUnixPath
:= (PathUpToDosdevices
+ DriveNameWithSlash
+ Path
);
196 {$IFDEF MOREDEBUG_WinToUnixPath}
197 logVar(PathUpToDosdevices
, 'PathUpToDosdevices');
198 logVar(DriveNameWithSlash
, 'DriveNameWithSlash');
199 logVar(Path
, 'Path');
201 logVar(FullUnixPath
, 'FullUnixPath');
203 Result
:= FullUnixPath
;
208 function UnixToWinPath(Path
:string; DriveChar
:Char):string;
210 WindowsFilePath
:string;
220 Path
:= AnsiReverseString(Path
);
221 SmallPath
:= Copy2SymbDel(Path
, ':');
222 SmallPath
:= AnsiReverseString(SmallPath
);
223 Cleanup
:= AnsiReplaceText(SmallPath
, '/', '\');
224 WindowsFilePath
:= (DriveChar
+ ':' + Cleanup
);
227 logVar(WindowsFilePath
, 'WindowsFilePath');
229 Result
:= WindowsFilePath
;
233 function GetUnixDirPath(FilePath
:string):string;
236 //LocalChannel:string;
238 DirPath
:= LeftStr(FilePath
, (Rpos('/',FilePath
) ));
239 //log(0, LocalChannel, ( 'VAR ' + DirPath));
244 function WorkDirTemplate(FolderPath
:string):string;
246 Result
:= ('cd "' + FolderPath
+ '";' + #10 );
250 procedure LogVar(MyVar
: string; MyVarName
: string);
252 Log(2, 'LogVar', ( Wrap( MyVarName
) + 'is' + Wrap( MyVar
)) );
256 function CheckPaths():boolean;
261 if DirExistsIfNotMakeIt(GetEnvironmentVariable('HOME'), '/.config') <> true then
266 if DirExistsIfNotMakeIt(ConfigPath
) <> true then
272 if DirExistsIfNotMakeIt(GetEnvironmentVariable('HOME') + '/' , WineUserFolder
) = false then
277 if DirExistsIfNotMakeIt(GetEnvironmentVariable('HOME') + '/' + WineUserFolder
+ '/', 'prefix') = false then
283 if DoesFolderExists(GetEnvironmentVariable('HOME') + '/' + WineUserFolder
+ '/', 'git') = false then
290 if DirExistsIfNotMakeIt(GetEnvironmentVariable('HOME') + '/' + WineUserFolder
+ '/', 'wine') = false then
301 function SetupGit():boolean;
309 Process
:= TProcess
.Create(nil);
311 ChannelLocal
:= 'SetupGit';
313 script
:= '#! /bin/sh' +{linebrake}#10 +
314 'echo This script will fetch Wine and compile it. ;'+{linebrake}#10 +
315 'echo If it fails please install the dependencies and rerun WineLauncher, see http://wiki.winehq.org/Recommended_Packages for more help.' +{linebrake}#10 +
316 'cd ' + GetEnvironmentVariable('HOME') + '/' + WineUserFolder
+ ' ;' +{linebrake}#10 +
317 'git clone git://source.winehq.org/git/wine.git git ;' +{linebrake}#10 +
318 'cd ./git ;' +{linebrake}#10 +
319 'git checkout -b stable-1.0.1 wine-1.0.1 ;' +{linebrake}#10 +
320 'Dname=`lsb_release -si` ;' +{linebrake}#10 +
321 'Dversion=`lsb_release -sr` ;' +{linebrake}#10 +
322 'Aname=`uname -m` ;' +{linebrake}#10 +
323 './configure --prefix=' + GetEnvironmentVariable('HOME') + '/' + WineUserFolder
+ '/wine/$Dname/$Dversion/$Aname/stable-1.0.1 ;' +{linebrake}#10 +
324 'make ;' +{linebrake}#10 +
325 'make install;' +{linebrake}#10 +
326 GetEnvironmentVariable('HOME') + '/' + WineUserFolder
+ '/wine/$Dname/$Dversion/$Aname/stable-1.0.1/bin/wineprefixcreate --prefix "' + GetEnvironmentVariable('HOME') + '/' + WineUserFolder
+ '/prefix/default/"' +{linebrake}#10 ;
329 if MakeFile((ConfigPath
+ '/SetupGit'),script
) = true then
332 {Set executable flag}
333 if SetExecutableFlag(ConfigPath
+ '/SetupGit') = false then
338 if FileExistsAndIsExecutable('/usr/bin/gnome-terminal',false) = true then
340 Terminal
:= 'gnome-terminal -x ';
344 if FileExistsAndIsExecutable('/usr/bin/gnome-terminal',false) = true then
346 Terminal
:= '/usr/bin/konsole -x ';
349 if FileExistsAndIsExecutable('/usr/bin/gnome-terminal',false) = true then
351 Terminal
:= '/usr/bin/xterm ';
356 if RunYes
= true then
358 Log(0, ChannelLocal
, 'Script One has being executed.');
359 Process
.CommandLine
:= Terminal
+ ConfigPath
+'/SetupGit';
363 while Process
.Running
= true do
368 Result
:= Process
.WaitOnExit
;
375 function DirExistsIfNotMakeIt(Path
:string; FolderName
:string ): boolean;
377 LocalChannel
:string; {Ignore this for now}
381 if FolderName
<> '' then
383 if DirectoryExists( Path
+ FolderName
) = true then
385 Log(0, LocalChannel
, ('Directory' + Wrap( Path
+ FolderName
) + 'exists.')) ;
390 Log(0, LocalChannel
, ('Directory' + Wrap( Path
+ FolderName
) + ' does not exists.')) ;
391 if CreateDir( Path
+ FolderName
) then
393 Log(0, LocalChannel
, ('File' + Wrap( Path
+ FolderName
) + 'has being created.')) ;
398 Log(0, LocalChannel
, ('File' + Wrap( Path
+ FolderName
) + 'can not be created.')) ;
410 function DirExistsIfNotMakeIt(PathWithFolder
:string): boolean;
415 {E.G. PathWithFolder := '/home/test/hello/'.}
417 {If PathWithfolder has '/' at the end remove it.}
418 RemoveTrailingChars(PathWithFolder
,['/']);
420 {FolderName := 'hello'.}
421 FolderName
:= ExtractFileName(PathWithFolder
);
423 {FolderPath := '/home/test/'.}
424 FolderPath
:= ExtractFilePath(PathWithFolder
);
427 logVar(FolderName
, 'FolderName');
428 logVar(FolderPath
, 'FolderPath');
431 {Pass the data to real function and get the result back.}
432 if DirExistsIfNotMakeIt(FolderPath
, FolderName
) = true then Result
:= true else Result
:= false;
435 function MakeFile(FullPath
:string;Data
:string):boolean;
443 FD1
:= fpOpen (FullPath
, O_WrOnly
or O_Creat
);
446 if length(Data
)<>fpwrite (FD1
,Data
[1],Length(Data
)) then
449 Log(1, CL
, ('When writing to' + Wrap(FullPath
)) );
454 Log(3, CL
, ('File' + Wrap(FullPath
) + 'has being created'));
462 function SetExecutableFlag(FullPath
:string):boolean;
466 {770 is owner rwx, group rwx, other nothing}
467 if fpChmod (FullPath
,&770) <> 0 then {0 = no error}
469 Log(1, ChannelLocal
, ('Can not set executable flag on' + Wrap(FullPath
)) );
475 Log(0, ChannelLocal
, ('Executable flag has being set on' + Wrap(FullPath
)) );
481 function ColourCheck(Input
: TEdit
):boolean;
486 LocalChannel
:= 'ColourCheck';
487 {This does a CaseInsensitive check to see if the file exists. Wine does not care about the executable flag. }
488 {I can not find FindDiskFileCaseInsensitive in the doc.}
489 {If it can not find the file it will return nothing and it will clear the string.}
490 temp
:= WinToUnixPath(Input
.Text);
492 if FindDiskFileCaseInsensitive(temp
) <> '' then
494 {$IFDEF MoreTrue}Log(3, LocalChannel
, 'File' + Wrap(temp
) + 'exists.');{$ENDIF}
495 Input
.Font
.Color
:= clgreen
;
500 Log(4, LocalChannel
,'File' + Wrap(Input
.Text) + 'does not exists.');
501 Input
.Font
.Color
:= clred
;
506 function CutUpFlags(Flags
:string):boolean;
512 UnitMain
.form1
.CheckListBox_Flags
.Items
.Clear
;
514 for loop
:= 0 to ( WordCount( Flags
, [';'] ) ) do
516 Dump
:= FindPart( ';', Flags
);
517 Temp
:= LeftStr( Flags
, Dump
- 1);
518 if Temp
<> '' then UnitMain
.form1
.CheckListBox_Flags
.Items
.Add(Temp
);
519 Delete(Flags
, 1, (Dump
)) ;
521 if Flags
<> '' then UnitMain
.form1
.CheckListBox_Flags
.Items
.Add(Flags
);
525 function FindPrefixInt(PrefixName
:string):integer;
534 for loop
:= 0 to (UnitMain
.form1
.ComboBox_PreFix
.items
.Count
-1) do begin
535 if Data
[loop
].PrefixName
= PrefixName
then
542 if Result
= -1 then log(1, C
, ('Prefix' + Wrap(PrefixName
) + 'does not exist.'));
545 function GetWinFileName(FullPath
:string):string;
547 {Take path and return the file name only.}
548 {d:\Somefoldername\'Setup'.exe}
550 FullPath
:= AnsiReverseString(FullPath
);
551 FullPath
:= Copy2Symb(FullPath
, '\');
552 Copy2SymbDel(FullPath
, '.');
553 FullPath
:= AnsiReverseString(FullPath
);