WineLauncher: Turn on Heaptrc, it's used to find memory leaks.
[WineLauncher.git] / UnitMain.pas
blob53f17a89286a0094e6d48995afba329802066a24
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/>.
16 {Made with Lazarus 0.9.26.3 fixes branch.}
17 {Free Pascal Compiler version 2.2.5.}
19 unit UnitMain;
21 {$mode objfpc}{$H+}
23 interface
25 uses
26 Classes, SysUtils, LResources, Forms, Controls, Graphics, Dialogs, StdCtrls,
27 DbCtrls, strutils, BaseUnix, Process, CheckLst, Math, ExtCtrls, ComCtrls, UnitCreatePrefix, UnitAbout, Errors;
29 type
31 { TForm1 }
33 TForm1 = class(TForm)
34 Btn_Run: TButton;
35 Btn_DebugChannelsConfig: TButton;
36 Btn_Settings: TButton;
37 Btn_StopScan: TButton;
38 Button_Regedit: TButton;
39 Button_Winecfg: TButton;
40 CheckBox_UseSoundWrapper: TCheckBox;
41 CheckBox_DebugChannelUse: TCheckBox;
42 CheckListBox_Flags: TCheckListBox;
43 Check_Terminal: TCheckBox;
44 ComboBox_WineVersion: TComboBox;
45 ComboBox_ProgramsList: TComboBox;
46 ComboBox_PreFix: TComboBox;
47 ComboBox_SoundWrapper: TComboBox;
48 ComboBox_TerminalName: TComboBox;
49 EditBox_ProgramPath: TEdit;
50 Label_WineVersion: TLabel;
51 Label_Flags: TLabel;
52 Label_ProgramPath: TLabel;
53 Label_ProgramsList: TLabel;
54 Label_WinePreFix: TLabel;
55 Memo_LogOutPut: TMemo;
56 PageControl1: TPageControl;
57 Tab_Log: TTabSheet;
58 TogBtn_Listdrive: TToggleBox;
60 procedure Btn_DebugChannelsConfigClick(Sender: TObject);
61 procedure Btn_RunClick(Sender: TObject);
62 procedure Btn_SettingsClick(Sender: TObject);
63 procedure Btn_StopScanClick(Sender: TObject);
64 procedure Button_RegeditClick(Sender: TObject);
65 procedure Button_WinecfgClick(Sender: TObject);
66 procedure ComboBox_PreFixChange(Sender: TObject);
67 procedure ComboBox_ProgramsListChange(Sender: TObject);
68 procedure ComboBox_WineVersionEditingDone(Sender: TObject);
69 procedure ComboBox_WineVersionEnter(Sender: TObject);
70 procedure EditBox_ProgramPathChange(Sender: TObject);
71 procedure FormClose(Sender: TObject; var CloseAction: TCloseAction);
72 procedure FormCreate(Sender: TObject);
73 procedure FormDestroy(Sender: TObject);
74 procedure TogBtn_ListdriveChange(Sender: TObject);
75 procedure TimerOnTimer(Sender: TObject);
77 private { private declarations }
79 public { public declarations }
81 end;
83 var
84 Form1: TForm1;
85 start_S1:string; { Script to write to the file. }
86 wine_version_full:string; { New code uses this to. }
87 RunIn:string; { terminal or shell set here }
88 NoError:Boolean; { Tbh this should not be here but im not sure need to check. }
89 Sh_Path:string; { Path for the shell }
90 GetCurrentDir:string;
91 Channel:string; { Debug channel name }
92 UnixDirPath:string; { Needed for setting the working dir at 'Run'. }
93 Mode:boolean;
94 Timer:TTimer; {The timer is a workaround.}
95 {Frames}
96 FrameCreatePrefix:TFrameCreatePrefix;
97 FrameAbout:TFrameAbout;
99 implementation
100 uses
101 UnitInitialization,
102 UnitMainBackend,
103 UnitMisc,
104 UnitDebugConfig,
105 UnitSettings,
106 UnitProgramsList;
108 procedure TForm1.FormCreate(Sender: TObject);
109 begin
110 {The timer is a workaround.}
111 Timer := TTimer.Create(nil) ;
112 Timer.OnTimer := @TimerOnTimer;
113 Timer.Enabled := false;
114 Timer.Interval := 100;
116 {Scan for wine.}
117 ComboBox_WineVersionEnter(Self);
119 {Select first item.}
120 if ComboBox_SoundWrapper.items.Count <> 0 then ComboBox_SoundWrapper.Text := ComboBox_SoundWrapper.Items[0];
121 if ComboBox_TerminalName.items.Count <> 0 then ComboBox_TerminalName.Text := ComboBox_TerminalName.Items[0];
122 if ComboBox_WineVersion.Items.Count <> 0 then ComboBox_WineVersion.Text := ComboBox_WineVersion.Items[0];
124 {Frame Create prefix.}
125 AddTabToPageControl(PageControl1, 'Create prefix');
126 FrameCreatePrefix := TFrameCreatePrefix.Create(Self);
127 EmbedFrame(FrameCreatePrefix, PageControl1.PageCount -1);
128 {Frame about.}
129 AddTabToPageControl(PageControl1, 'About');
130 FrameAbout := TFrameAbout.Create(Self);
131 EmbedFrame(FrameAbout, PageControl1.PageCount -1);
133 FrameAbout.Memo_About.Lines.Add('');
134 {When the is a new release update the version number in the file called 'VERSION.inc'.}
135 FrameAbout.Memo_About.Lines.Add('WineLauncher Version: ' + WineLauncherVersion);
136 FrameAbout.Memo_About.Lines.Add(BuiltWithFpcVersion);
138 {Load LastUsedConfig.}
139 LoadLastUsedConfig();
141 {$IFDEF GuiTest}
142 Btn_StopScan.Visible := true;
143 {$ENDIF}
144 end;
146 procedure TForm1.FormDestroy(Sender: TObject);
147 begin
148 Timer.Destroy;
149 XmlLastUsedConfig.Destroy;
151 {stuff configed in UnitInitialization.}
152 AProcess.Destroy;
153 CreatePrefixProcess.Destroy;
154 AsyncProcessScan.Destroy;
155 end;
157 procedure TForm1.TimerOnTimer(Sender: TObject);
159 TempList:Tstrings;
160 begin
161 {We should not use a timer to check this. The is a bug in lazarus, 'OnTerminate' of AsyncProcess never runs.}
162 if AsyncProcessScan.Active = true then
163 begin
164 Timer.Enabled := true;
165 Btn_StopScan.Visible := true;
167 else
168 begin
169 Btn_StopScan.Visible := false;
170 TempList := TStringlist.Create;
171 Timer.Enabled := false;
172 TempList.LoadFromStream(AsyncProcessScan.OutPut);
174 if TempList.Count = 0 then
175 begin
176 DiscErrorText := 'Drive' + wrap('D' + ':') + 'has no executable files.';
177 LastReadLinkPath := '';
179 else
180 begin
181 DiscErrorText := '';
182 end;
184 while TempList.Count <> 0 do
185 begin
186 CdData.Add(UnixToWinPath(TempList.Strings[0],'d'));
187 TempList.Delete(0);
188 end;
190 ComboBox_PreFixChange(self);
191 TempList.Destroy;
193 CheckListBox_Flags.Clear;
194 end;
195 end;
197 procedure TForm1.TogBtn_ListdriveChange(Sender: TObject);
198 begin
199 if Mode = true then
200 begin
201 Mode := false;
202 AsyncProcessScan.Active := false;
203 Btn_StopScan.Visible := false;
204 CheckListBox_Flags.Enabled := true;
205 EditBox_ProgramPath.Clear;
206 ComboBox_PreFixChange(self);
207 ComboBox_ProgramsListChange(self);
209 else
210 begin
211 Mode := true;
212 if CdData = nil then CdData := TStringlist.Create;
213 if CdDataName = nil then CdDataName := TStringlist.Create;
215 log(0,'', LastReadLinkPath);
216 ComboBox_PreFixChange(self);
217 CheckListBox_Flags.Clear;
218 EditBox_ProgramPath.Clear;
219 end;
220 end;
225 procedure TForm1.Btn_RunClick(Sender: TObject);
226 begin
227 RunWineCheck( '', '' );
228 end;
230 procedure TForm1.Btn_SettingsClick(Sender: TObject);
231 begin
232 UnitSettings.Form4.Show ;
233 end;
235 procedure TForm1.Btn_StopScanClick(Sender: TObject);
236 begin
237 AsyncProcessScan.Active := false;
238 end;
240 procedure TForm1.Button_RegeditClick(Sender: TObject);
241 begin
242 RunWineCheck( 'Regedit', '' );
243 end;
245 procedure TForm1.Button_WinecfgClick(Sender: TObject);
246 begin
247 RunWineCheck( 'winecfg', '' );
248 end;
251 procedure TForm1.ComboBox_PreFixChange(Sender: TObject);
253 ChannelLocal:string;
254 myloop:integer;
255 temp:string;
256 PrefixInt:integer;
257 begin
258 ComboBox_ProgramsList.Items.Clear;
260 EditBox_ProgramPath.Enabled := true;
261 ComboBox_ProgramsList.Enabled := true;
263 if Mode = false then
264 begin
265 for myloop := 1 to (Data[ComboBox_PreFix.ItemIndex].Grid.RowCount -1) do
266 begin
267 if Data[ComboBox_PreFix.ItemIndex].Grid.Cells[DataNameCol, myloop] <> '' then
268 begin
269 ComboBox_ProgramsList.Items.Add(Data[ComboBox_PreFix.ItemIndex].Grid.Cells[DataNameCol, myloop]);
271 else
272 begin
273 break;
274 end;
275 end;
277 if ComboBox_ProgramsList.Items.Count <> 0 then
278 begin
279 ComboBox_ProgramsList.ItemIndex := 0;
280 EditBox_ProgramPath.Enabled := true;
281 ComboBox_ProgramsList.Enabled := true;
282 ComboBox_ProgramsListChange(Self);
284 else
285 begin
286 ComboBox_ProgramsList.Text := '';
287 EditBox_ProgramPath.Text := '';
288 EditBox_ProgramPath.Enabled := false;
289 ComboBox_ProgramsList.Enabled := false;
290 end;
293 else
294 begin
295 ListProgramsOnDisc(CdData, 'D');
296 if CdData.Text <> '' then
297 begin
298 CdDataName.Clear;
299 CdDataName.AddStrings(CdData);
301 {Write some code to clean up the names, keep then usefull and unique.}
303 ComboBox_ProgramsList.Items := CdDataName;
304 if ComboBox_ProgramsList.Items.Count <> 0 then
305 begin
306 ComboBox_ProgramsList.Text := ComboBox_ProgramsList.Items[0];
307 EditBox_ProgramPath.Enabled := true;
308 ComboBox_ProgramsList.Enabled := true;
309 ComboBox_ProgramsListChange(self);
310 end;
313 else
314 begin
315 ComboBox_ProgramsList.Items.Add(DiscErrorText);
316 ComboBox_ProgramsList.ItemIndex := 0;
317 EditBox_ProgramPath.Text := '';
318 EditBox_ProgramPath.Enabled := false;
319 ComboBox_ProgramsList.Enabled := false;
320 CheckListBox_Flags.Clear;
321 end;
323 end;
324 end;
326 procedure TForm1.ComboBox_ProgramsListChange(Sender: TObject);
328 ProgramsListSelectedItem:integer;
329 PrefixInt:integer;
330 begin
331 if Mode = false then
332 begin
333 PrefixInt := FindPrefixInt(ComboBox_PreFix.Items.Strings[ComboBox_PreFix.ItemIndex]);
334 EditBox_ProgramPath.Enabled := true;
335 {Plus one to line it up with the grid}
336 ProgramsListSelectedItem := (Data[PrefixInt].Grid.cols[DataNameCol].IndexOf(Data[PrefixInt].Grid.cols[DataNameCol].Strings[ComboBox_ProgramsList.ItemIndex]) +1);
337 {Cells[{Col},{Row}]}
338 EditBox_ProgramPath.Text := Data[PrefixInt].Grid.Cells[DataPathCol, ProgramsListSelectedItem] ;
339 CutUpFlags(Data[PrefixInt].Grid.Cells[DataFlagsCol, ProgramsListSelectedItem]);
341 else
342 begin
343 if CdData.Text <> '' then
344 begin
345 EditBox_ProgramPath.Text := CdData.Strings[CdDataName.IndexOf(ComboBox_ProgramsList.Text)] ;
346 end;
347 end;
348 end;
350 procedure TForm1.ComboBox_WineVersionEditingDone(Sender: TObject);
351 begin
352 OnWineVersionChange();
353 end;
355 procedure TForm1.ComboBox_WineVersionEnter(Sender: TObject);
357 a:string;
358 SystemSidePath:string;
359 begin
360 {Note FpSymLink does not have a string version with fpc 2.2.5.}
361 {This is not best way adding the system side wine but it works.}
362 SystemSidePath := PathToWine + '/System Side Wine';
363 {link wine.}
364 a := SearchForBin('wine');
365 if SearchForBin(a) <> '' then
366 begin
367 if DirExistsIfNotMakeIt(SystemSidePath) = true then
368 begin
369 if DirExistsIfNotMakeIt(SystemSidePath + '/bin') = true then
370 begin
371 SystemSidePath := (SystemSidePath + '/bin');
372 FpUnlink(SystemSidePath + '/wine');
373 if FpSymLink(PChar(a), PChar(SystemSidePath + '/wine') ) <> 0 then
374 begin
375 log(1,'','Can not create symlink: ' + StrError(fpgeterrno));
376 end;
377 {link wineprefixcreate.}
378 a := SearchForBin('wineprefixcreate');
379 if SearchForBin(a) <> '' then
380 begin
381 FpUnlink(SystemSidePath + '/wineprefixcreate');
382 if FpSymLink(PChar(a), PChar(SystemSidePath + '/wineprefixcreate') ) <> 0 then
383 begin
384 log(1,'','Can not create symlink: ' + StrError(fpgeterrno));
385 end;
386 end;
387 end;
388 end;
389 end;
391 FolderScan(ComboBox_WineVersion, PathToWine);
392 OnWineVersionChange();
393 end;
395 procedure TForm1.EditBox_ProgramPathChange(Sender: TObject);
396 begin
397 ColourCheck(EditBox_ProgramPath);
398 end;
400 procedure TForm1.FormClose(Sender: TObject; var CloseAction: TCloseAction);
401 begin
402 SaveLastUsedConfig();
403 end;
406 procedure TForm1.Btn_DebugChannelsConfigClick(Sender: TObject);
407 begin
408 UnitDebugConfig.Form2.Show ;
409 end;
414 initialization
415 {$I UnitMain.lrs}
417 end.