initial commit

This commit is contained in:
April Ayres-Griffiths 2019-03-31 14:59:50 +11:00
commit 62792fb097
18 changed files with 7501 additions and 0 deletions

2063
backup/main.lfm Normal file

File diff suppressed because it is too large Load Diff

403
backup/main.pas Normal file
View File

@ -0,0 +1,403 @@
unit main;
{$mode objfpc}{$H+}
interface
uses
Classes, SysUtils, Forms, Controls, Graphics, Dialogs, Menus, ComCtrls,
ExtCtrls, StdCtrls, fphttpclient, LCLType, Buttons, DateUtils,
{$IFDEF WINDOWS}
Windows,
{$ENDIF}
Sockets
;
type
{ TGUIForm }
TGUIForm = class(TForm)
BackdropImage: TImage;
ImageList1: TImageList;
MainMenu1: TMainMenu;
Memo1: TMemo;
MenuItem1: TMenuItem;
MenuItem10: TMenuItem;
MenuItem11: TMenuItem;
MenuItem12: TMenuItem;
MenuItem13: TMenuItem;
MenuItem2: TMenuItem;
embedPanel: TPanel;
menuRebootVM: TMenuItem;
MenuItem4: TMenuItem;
MenuItem5: TMenuItem;
MenuItem6: TMenuItem;
MenuItem7: TMenuItem;
MenuItem8: TMenuItem;
MenuItem9: TMenuItem;
DiskMenu: TPopupMenu;
StatusBar1: TStatusBar;
hc: TFPHttpClient;
CheckTimer: TTimer;
ToolBar1: TToolBar;
procedure Button1Click(Sender: TObject);
procedure CheckTimerTimer(Sender: TObject);
procedure FormActivate(Sender: TObject);
procedure FormChangeBounds(Sender: TObject);
procedure FormCreate(Sender: TObject);
procedure FormDeactivate(Sender: TObject);
procedure FormHide(Sender: TObject);
procedure FormKeyDown(Sender: TObject; var Key: Word; Shift: TShiftState);
procedure FormKeyPress(Sender: TObject; var Key: char);
procedure FormKeyUp(Sender: TObject; var Key: Word; Shift: TShiftState);
procedure FormResize(Sender: TObject);
procedure FormShow(Sender: TObject);
procedure FormUTF8KeyPress(Sender: TObject; var UTF8Key: TUTF8Char);
procedure FormWindowStateChange(Sender: TObject);
procedure MenuItem1Click(Sender: TObject);
procedure MenuItem2Click(Sender: TObject);
procedure Freeze;
procedure UnFreeze;
procedure HideM8;
procedure menuRebootVMClick(Sender: TObject);
procedure ShowM8;
procedure RebootVM;
procedure ReposWindow;
procedure RepaintWindow;
function GetTitleOfActiveWindow: string;
procedure SendKey(key: Char; ScanCode: Integer; KeyAction: Integer; Mods: Integer);
procedure tbDisk1MouseDown(Sender: TObject; Button: TMouseButton;
Shift: TShiftState; X, Y: Integer);
procedure tbDisk2MouseDown(Sender: TObject; Button: TMouseButton;
Shift: TShiftState; X, Y: Integer);
procedure ToolButton5Click(Sender: TObject);
private
lx, ly, lw, lh: integer;
lastShowTime: TDateTime;
lastHideTime: TDateTime;
hidden: boolean;
public
procedure AppActivate(Sender: TObject);
procedure AppDeactivate(Sender: TObject);
constructor Create(TheOwner: TComponent); override;
end;
var
GUIForm: TGUIForm;
implementation
{$R *.lfm}
{ TGUIForm }
constructor TGUIForm.Create(TheOwner: TComponent);
begin
inherited Create(TheOwner);
Application.OnDeactivate:=@AppDeactivate;
Application.OnActivate:=@AppActivate;
end;
procedure TGUIForm.AppActivate(Sender: TObject);
begin
StatusBar1.SimpleText := 'App has gained focus!';
if MillisecondsBetween(Now(), lastHideTime) < 1000 then
exit;
ShowM8;
Memo1.Lines.Add('app is activating');
end;
procedure TGUIForm.AppDeactivate(Sender: TObject);
begin
if MillisecondsBetween(Now(), lastShowTime) < 1000 then
exit;
RepaintWindow;
HideM8;
StatusBar1.SimpleText := 'App has lost focus!';
Memo1.Lines.Add('app is deactivating');
end;
procedure TGUIForm.RebootVM;
begin
self.hc.Get('http://localhost:38911/api/control/system/reboot');
end;
procedure TGUIForm.Freeze;
begin
self.hc.Get('http://localhost:38911/api/control/window/freeze');
end;
procedure TGUIForm.UnFreeze;
begin
self.hc.Get('http://localhost:38911/api/control/window/unfreeze');
end;
procedure TGUIForm.HideM8;
begin
if hidden then
exit;
Memo1.Lines.Add('hiding m8 window');
self.hc.Get('http://localhost:38911/api/control/window/hide');
lastHideTime := Now();
hidden := true;
end;
procedure TGUIForm.menuRebootVMClick(Sender: TObject);
begin
RebootVM;
end;
procedure TGUIForm.ShowM8;
begin
if not hidden then
exit;
Memo1.Lines.Add('showing m8 window');
self.hc.Get('http://localhost:38911/api/control/window/show');
lastShowTime := Now();
hidden := false;
end;
procedure TGUIForm.RepaintWindow;
var
S: TMemoryStream;
filename: string;
begin
S := TMemoryStream.Create();
self.hc.Get('http://localhost:38911/api/control/window/screen', S);
if S.Size > 0 then
begin
filename := GetUserDir + PathSeparator + 'microm8scrn.png';
StatusBar1.SimpleText:='Got '+IntToStr(S.Size)+' bytes of PNG data';
S.SaveToFile(filename);
BackdropImage.Picture.LoadFromFile(filename);
S.Free;
end;
end;
procedure TGUIForm.ReposWindow;
var
x, y, w, h: integer;
json, S: string;
Respo: TStringStream;
p, q: TPoint;
begin
q.X := 0;
q.Y := 0;
p := embedPanel.ClientToScreen(q);
x := p.X;
y := p.Y;
w := embedPanel.Width;
h := embedPanel.Height;
if (lx = x) and (ly = y) and (lw = w) and (lh = h) then
exit;
lx := x;
ly := y;
lw := w;
lh := h;
json := '{"x":' + IntToStr(x) +
',"y":'+IntToStr(y) +
',"w":'+IntToStr(w) +
',"h":'+IntToStr(h) +
'}';
Respo := TStringStream.Create('');
self.hc.SimpleFormPost('http://localhost:38911/api/control/window/position',json,Respo);
S := Respo.DataString;
self.StatusBar1.SimpleText:=S;
Respo.Destroy;
end;
procedure TGUIForm.SendKey(key: Char; ScanCode: Integer; KeyAction: Integer; Mods: Integer);
var
json, S: string;
Respo: TStringStream;
begin
if key = Char(8) then
key := Char(127);
json := '{"key":' + IntToStr(Ord(key)) +
',"scancode":'+IntToStr(ScanCode) +
',"action":'+IntToStr(KeyAction) +
',"modifiers":'+IntToStr(Mods) +
'}';
Respo := TStringStream.Create('');
self.hc.SimpleFormPost('http://localhost:38911/api/control/input/keyevent',json,Respo);
S := Respo.DataString;
self.StatusBar1.SimpleText:=S;
Respo.Destroy;
end;
procedure TGUIForm.tbDisk1MouseDown(Sender: TObject; Button: TMouseButton;
Shift: TShiftState; X, Y: Integer);
begin
DiskMenu.Tag := TToolButton(Sender).Tag;
StatusBar1.SimpleText := 'Disk 1';
end;
procedure TGUIForm.tbDisk2MouseDown(Sender: TObject; Button: TMouseButton;
Shift: TShiftState; X, Y: Integer);
begin
DiskMenu.Tag := TToolButton(Sender).Tag;
StatusBar1.SimpleText := 'Disk 2';
end;
procedure TGUIForm.ToolButton5Click(Sender: TObject);
begin
RebootVM;
end;
procedure TGUIForm.MenuItem1Click(Sender: TObject);
begin
end;
procedure TGUIForm.FormActivate(Sender: TObject);
begin
end;
procedure TGUIForm.FormChangeBounds(Sender: TObject);
begin
self.ReposWindow;
end;
procedure TGUIForm.Button1Click(Sender: TObject);
begin
self.ReposWindow;
end;
{$IFDEF WINDOWS}
function TGUIForm.GetTitleOfActiveWindow: string;
var
AHandle: THandle;
ATitle: string;
ALen: Integer;
begin
Result := '';
AHandle := GetForegroundWindow;
if AHandle <> 0 then begin
ALen := GetWindowTextLength(AHandle) + 1;
SetLength(ATitle, ALen);
GetWindowText(AHandle, PChar(ATitle), ALen);
result := Trim(ATitle);
end;
end;
{$ELSE}
// stub for now
function TGUIForm.GetTitleOfActiveWindow: string;
var s: string;
begin
Result := '';
s := self.hc.Get('http://localhost:38911/api/control/window/focused');
if s = '1' then
Result := 'microM8';
end;
{$ENDIF}
procedure TGUIForm.CheckTimerTimer(Sender: TObject);
begin
//if MilliSecondsBetween(Now(), lastShowTime) < 500 then
// exit;
if WindowState = wsMinimized then
exit;
if hidden then
exit;
if GetTitleOfActiveWindow = 'microM8' then
begin
//Application.Restore;
Application.BringToFront;
{$IFDEF WINDOWS}
SetForegroundWindow(Application.MainForm.Handle);
{$ENDIF}
StatusBar1.SimpleText := 'App is refocussing';
lastShowTime := Now();
end;
end;
procedure TGUIForm.FormCreate(Sender: TObject);
begin
self.hc := TFPHttpClient.Create(Nil);
hidden := true;
end;
procedure TGUIForm.FormDeactivate(Sender: TObject);
begin
end;
procedure TGUIForm.FormHide(Sender: TObject);
begin
RepaintWindow;
HideM8;
end;
procedure TGUIForm.FormKeyDown(Sender: TObject; var Key: Word; Shift: TShiftState
);
var
m: Integer;
begin
m := 0;
if ssShift in Shift then
m := m or 1;
if ssCtrl in Shift then
m := m or 2;
if ssAlt in Shift then
m := m or 4;
SendKey( Char(Key), 0, 1, m );
end;
procedure TGUIForm.FormKeyPress(Sender: TObject; var Key: char);
begin
SendKey( Key, 0, 1, 0 );
end;
procedure TGUIForm.FormKeyUp(Sender: TObject; var Key: Word; Shift: TShiftState);
var
m: Integer;
begin
m := 0;
if ssShift in Shift then
m := m or 1;
if ssCtrl in Shift then
m := m or 2;
if ssAlt in Shift then
m := m or 4;
SendKey( Char(Key), 0, 0, m );
end;
procedure TGUIForm.FormResize(Sender: TObject);
begin
// on form resize we need to send a size request
ReposWindow;
end;
procedure TGUIForm.FormShow(Sender: TObject);
begin
ShowM8;
ReposWindow;
end;
procedure TGUIForm.FormUTF8KeyPress(Sender: TObject; var UTF8Key: TUTF8Char);
begin
end;
procedure TGUIForm.FormWindowStateChange(Sender: TObject);
begin
Memo1.Lines.Add('window state has changed');
if WindowState = wsMinimized then
HideM8
else
ShowM8;
end;
procedure TGUIForm.MenuItem2Click(Sender: TObject);
begin
Application.Terminate();
end;
end.

85
backup/poc.lpi Normal file
View File

@ -0,0 +1,85 @@
<?xml version="1.0" encoding="UTF-8"?>
<CONFIG>
<ProjectOptions>
<Version Value="11"/>
<PathDelim Value="\"/>
<General>
<SessionStorage Value="InProjectDir"/>
<MainUnit Value="0"/>
<Title Value="poc"/>
<Scaled Value="True"/>
<ResourceType Value="res"/>
<UseXPManifest Value="True"/>
<XPManifest>
<DpiAware Value="True"/>
</XPManifest>
<Icon Value="0"/>
</General>
<BuildModes Count="1">
<Item1 Name="Default" Default="True"/>
</BuildModes>
<PublishOptions>
<Version Value="2"/>
<UseFileFilters Value="True"/>
</PublishOptions>
<RunParams>
<FormatVersion Value="2"/>
<Modes Count="0"/>
</RunParams>
<RequiredPackages Count="3">
<Item1>
<PackageName Value="LazOpenGLContext"/>
</Item1>
<Item2>
<PackageName Value="indylaz"/>
</Item2>
<Item3>
<PackageName Value="LCL"/>
</Item3>
</RequiredPackages>
<Units Count="2">
<Unit0>
<Filename Value="poc.lpr"/>
<IsPartOfProject Value="True"/>
</Unit0>
<Unit1>
<Filename Value="main.pas"/>
<IsPartOfProject Value="True"/>
<ComponentName Value="GUIForm"/>
<HasResources Value="True"/>
<ResourceBaseClass Value="Form"/>
</Unit1>
</Units>
</ProjectOptions>
<CompilerOptions>
<Version Value="11"/>
<PathDelim Value="\"/>
<Target>
<Filename Value="poc"/>
</Target>
<SearchPaths>
<IncludeFiles Value="$(ProjOutDir)"/>
<UnitOutputDirectory Value="lib\$(TargetCPU)-$(TargetOS)"/>
</SearchPaths>
<Linking>
<Options>
<Win32>
<GraphicApplication Value="True"/>
</Win32>
</Options>
</Linking>
</CompilerOptions>
<Debugging>
<Exceptions Count="3">
<Item1>
<Name Value="EAbort"/>
</Item1>
<Item2>
<Name Value="ECodetoolError"/>
</Item2>
<Item3>
<Name Value="EFOpenError"/>
</Item3>
</Exceptions>
</Debugging>
</CONFIG>

166
backup/poc.lps Normal file
View File

@ -0,0 +1,166 @@
<?xml version="1.0" encoding="UTF-8"?>
<CONFIG>
<ProjectSession>
<PathDelim Value="\"/>
<Version Value="11"/>
<BuildModes Active="Default"/>
<Units Count="3">
<Unit0>
<Filename Value="poc.lpr"/>
<IsPartOfProject Value="True"/>
<EditorIndex Value="-1"/>
<WindowIndex Value="-1"/>
<TopLine Value="-1"/>
<CursorPos X="-1" Y="-1"/>
<UsageCount Value="73"/>
</Unit0>
<Unit1>
<Filename Value="main.pas"/>
<IsPartOfProject Value="True"/>
<ComponentName Value="GUIForm"/>
<HasResources Value="True"/>
<ResourceBaseClass Value="Form"/>
<IsVisibleTab Value="True"/>
<TopLine Value="124"/>
<CursorPos X="27" Y="140"/>
<UsageCount Value="73"/>
<Loaded Value="True"/>
<LoadedDesigner Value="True"/>
</Unit1>
<Unit2>
<Filename Value="C:\lazarus\lcl\include\picture.inc"/>
<EditorIndex Value="1"/>
<TopLine Value="576"/>
<CursorPos X="49" Y="591"/>
<UsageCount Value="13"/>
<Loaded Value="True"/>
</Unit2>
</Units>
<JumpHistory Count="30" HistoryIndex="29">
<Position1>
<Filename Value="main.pas"/>
<Caret Line="182" Column="13" TopLine="159"/>
</Position1>
<Position2>
<Filename Value="main.pas"/>
<Caret Line="180" Column="23" TopLine="164"/>
</Position2>
<Position3>
<Filename Value="main.pas"/>
<Caret Line="179" Column="41" TopLine="163"/>
</Position3>
<Position4>
<Filename Value="main.pas"/>
<Caret Line="169" Column="38" TopLine="163"/>
</Position4>
<Position5>
<Filename Value="main.pas"/>
<Caret Line="168" Column="38" TopLine="162"/>
</Position5>
<Position6>
<Filename Value="main.pas"/>
<Caret Line="170" Column="16" TopLine="162"/>
</Position6>
<Position7>
<Filename Value="main.pas"/>
<Caret Line="182" Column="46" TopLine="162"/>
</Position7>
<Position8>
<Filename Value="main.pas"/>
<Caret Line="9" Column="86"/>
</Position8>
<Position9>
<Filename Value="main.pas"/>
<Caret Line="177" Column="15" TopLine="160"/>
</Position9>
<Position10>
<Filename Value="main.pas"/>
<Caret Line="170" Column="13" TopLine="162"/>
</Position10>
<Position11>
<Filename Value="main.pas"/>
<Caret Line="185" Column="13" TopLine="163"/>
</Position11>
<Position12>
<Filename Value="main.pas"/>
<Caret Line="187" Column="31" TopLine="166"/>
</Position12>
<Position13>
<Filename Value="main.pas"/>
<Caret Line="185" Column="58" TopLine="166"/>
</Position13>
<Position14>
<Filename Value="main.pas"/>
<Caret Line="191" Column="43" TopLine="166"/>
</Position14>
<Position15>
<Filename Value="main.pas"/>
<Caret Line="195" Column="31" TopLine="166"/>
</Position15>
<Position16>
<Filename Value="main.pas"/>
<Caret Line="179" Column="75" TopLine="166"/>
</Position16>
<Position17>
<Filename Value="main.pas"/>
<Caret Line="181" Column="45" TopLine="161"/>
</Position17>
<Position18>
<Filename Value="main.pas"/>
<Caret Line="135" Column="12" TopLine="111"/>
</Position18>
<Position19>
<Filename Value="main.pas"/>
<Caret Line="59" Column="21" TopLine="133"/>
</Position19>
<Position20>
<Filename Value="main.pas"/>
<Caret Line="135" Column="31" TopLine="111"/>
</Position20>
<Position21>
<Filename Value="main.pas"/>
<Caret Line="134" Column="31" TopLine="110"/>
</Position21>
<Position22>
<Filename Value="main.pas"/>
<Caret Line="312" Column="29" TopLine="333"/>
</Position22>
<Position23>
<Filename Value="main.pas"/>
<Caret Line="69" Column="14" TopLine="47"/>
</Position23>
<Position24>
<Filename Value="main.pas"/>
<Caret Line="11" Column="11"/>
</Position24>
<Position25>
<Filename Value="main.pas"/>
<Caret Line="44" Column="48" TopLine="60"/>
</Position25>
<Position26>
<Filename Value="main.pas"/>
<Caret Line="181" Column="14" TopLine="159"/>
</Position26>
<Position27>
<Filename Value="main.pas"/>
<Caret Line="146" Column="36" TopLine="118"/>
</Position27>
<Position28>
<Filename Value="main.pas"/>
<Caret Line="104" Column="9" TopLine="82"/>
</Position28>
<Position29>
<Filename Value="main.pas"/>
<Caret Line="78" Column="21" TopLine="93"/>
</Position29>
<Position30>
<Filename Value="main.pas"/>
<Caret Line="139" Column="27" TopLine="123"/>
</Position30>
</JumpHistory>
<RunParams>
<FormatVersion Value="2"/>
<Modes Count="0" ActiveMode=""/>
</RunParams>
</ProjectSession>
</CONFIG>

2052
lib/x86_64-win64/main.lfm Normal file

File diff suppressed because it is too large Load Diff

BIN
lib/x86_64-win64/main.o Normal file

Binary file not shown.

BIN
lib/x86_64-win64/main.ppu Normal file

Binary file not shown.

View File

@ -0,0 +1,5 @@
<?xml version="1.0" encoding="UTF-8"?>
<CONFIG>
<Compiler Value="C:\lazarus\fpc\3.0.4\bin\x86_64-win64\fpc.exe" Date="1313017496"/>
<Params Value=" -MObjFPC -Scghi -O1 -g -gl -WG -l -vewnhibq -FiC:\Users\aag65\Documents\poc\lib\x86_64-win64 -FuC:\Users\aag65\AppData\Local\lazarus\onlinepackagemanager\packages\Indy10\lib\x86_64-win64 -FuC:\lazarus\components\ideintf\units\x86_64-win64\win32 -FuC:\lazarus\components\opengl\lib\x86_64-win64\win32 -FuC:\lazarus\components\lazcontrols\lib\x86_64-win64\win32 -FuC:\lazarus\lcl\units\x86_64-win64\win32 -FuC:\lazarus\lcl\units\x86_64-win64 -FuC:\lazarus\components\lazutils\lib\x86_64-win64 -FuC:\lazarus\packager\units\x86_64-win64 -FuC:\Users\aag65\Documents\poc\ -FUC:\Users\aag65\Documents\poc\lib\x86_64-win64\ -FEC:\Users\aag65\Documents\poc\ -oC:\Users\aag65\Documents\poc\poc.exe -dLCL -dLCLwin32 poc.lpr"/>
</CONFIG>

BIN
lib/x86_64-win64/poc.o Normal file

Binary file not shown.

BIN
lib/x86_64-win64/poc.obj Normal file

Binary file not shown.

BIN
lib/x86_64-win64/poc.res Normal file

Binary file not shown.

2052
main.lfm Normal file

File diff suppressed because it is too large Load Diff

402
main.pas Normal file
View File

@ -0,0 +1,402 @@
unit main;
{$mode objfpc}{$H+}
interface
uses
Classes, SysUtils, Forms, Controls, Graphics, Dialogs, Menus, ComCtrls,
ExtCtrls, StdCtrls, fphttpclient, LCLType, Buttons, DateUtils,
{$IFDEF WINDOWS}
Windows,
{$ENDIF}
Sockets
;
type
{ TGUIForm }
TGUIForm = class(TForm)
BackdropImage: TImage;
ImageList1: TImageList;
MainMenu1: TMainMenu;
MenuItem1: TMenuItem;
MenuItem10: TMenuItem;
MenuItem11: TMenuItem;
MenuItem12: TMenuItem;
MenuItem13: TMenuItem;
MenuItem2: TMenuItem;
embedPanel: TPanel;
menuRebootVM: TMenuItem;
MenuItem4: TMenuItem;
MenuItem5: TMenuItem;
MenuItem6: TMenuItem;
MenuItem7: TMenuItem;
MenuItem8: TMenuItem;
MenuItem9: TMenuItem;
DiskMenu: TPopupMenu;
StatusBar1: TStatusBar;
hc: TFPHttpClient;
CheckTimer: TTimer;
ToolBar1: TToolBar;
procedure Button1Click(Sender: TObject);
procedure CheckTimerTimer(Sender: TObject);
procedure FormActivate(Sender: TObject);
procedure FormChangeBounds(Sender: TObject);
procedure FormCreate(Sender: TObject);
procedure FormDeactivate(Sender: TObject);
procedure FormHide(Sender: TObject);
procedure FormKeyDown(Sender: TObject; var Key: Word; Shift: TShiftState);
procedure FormKeyPress(Sender: TObject; var Key: char);
procedure FormKeyUp(Sender: TObject; var Key: Word; Shift: TShiftState);
procedure FormResize(Sender: TObject);
procedure FormShow(Sender: TObject);
procedure FormUTF8KeyPress(Sender: TObject; var UTF8Key: TUTF8Char);
procedure FormWindowStateChange(Sender: TObject);
procedure MenuItem1Click(Sender: TObject);
procedure MenuItem2Click(Sender: TObject);
procedure Freeze;
procedure UnFreeze;
procedure HideM8;
procedure menuRebootVMClick(Sender: TObject);
procedure ShowM8;
procedure RebootVM;
procedure ReposWindow;
procedure RepaintWindow;
function GetTitleOfActiveWindow: string;
procedure SendKey(key: Char; ScanCode: Integer; KeyAction: Integer; Mods: Integer);
procedure tbDisk1MouseDown(Sender: TObject; Button: TMouseButton;
Shift: TShiftState; X, Y: Integer);
procedure tbDisk2MouseDown(Sender: TObject; Button: TMouseButton;
Shift: TShiftState; X, Y: Integer);
procedure ToolButton5Click(Sender: TObject);
private
lx, ly, lw, lh: integer;
lastShowTime: TDateTime;
lastHideTime: TDateTime;
hidden: boolean;
public
procedure AppActivate(Sender: TObject);
procedure AppDeactivate(Sender: TObject);
constructor Create(TheOwner: TComponent); override;
end;
var
GUIForm: TGUIForm;
implementation
{$R *.lfm}
{ TGUIForm }
constructor TGUIForm.Create(TheOwner: TComponent);
begin
inherited Create(TheOwner);
Application.OnDeactivate:=@AppDeactivate;
Application.OnActivate:=@AppActivate;
end;
procedure TGUIForm.AppActivate(Sender: TObject);
begin
StatusBar1.SimpleText := 'App has gained focus!';
if MillisecondsBetween(Now(), lastHideTime) < 1000 then
exit;
ShowM8;
//Memo1.Lines.Add('app is activating');
end;
procedure TGUIForm.AppDeactivate(Sender: TObject);
begin
if MillisecondsBetween(Now(), lastShowTime) < 1000 then
exit;
RepaintWindow;
HideM8;
StatusBar1.SimpleText := 'App has lost focus!';
//Memo1.Lines.Add('app is deactivating');
end;
procedure TGUIForm.RebootVM;
begin
self.hc.Get('http://localhost:38911/api/control/system/reboot');
end;
procedure TGUIForm.Freeze;
begin
self.hc.Get('http://localhost:38911/api/control/window/freeze');
end;
procedure TGUIForm.UnFreeze;
begin
self.hc.Get('http://localhost:38911/api/control/window/unfreeze');
end;
procedure TGUIForm.HideM8;
begin
if hidden then
exit;
//Memo1.Lines.Add('hiding m8 window');
self.hc.Get('http://localhost:38911/api/control/window/hide');
lastHideTime := Now();
hidden := true;
end;
procedure TGUIForm.menuRebootVMClick(Sender: TObject);
begin
RebootVM;
end;
procedure TGUIForm.ShowM8;
begin
if not hidden then
exit;
//Memo1.Lines.Add('showing m8 window');
self.hc.Get('http://localhost:38911/api/control/window/show');
lastShowTime := Now();
hidden := false;
end;
procedure TGUIForm.RepaintWindow;
var
S: TMemoryStream;
filename: string;
begin
S := TMemoryStream.Create();
self.hc.Get('http://localhost:38911/api/control/window/screen', S);
if S.Size > 0 then
begin
filename := GetUserDir + PathSeparator + 'microm8scrn.png';
StatusBar1.SimpleText:='Got '+IntToStr(S.Size)+' bytes of PNG data';
S.SaveToFile(filename);
BackdropImage.Picture.LoadFromFile(filename);
S.Free;
end;
end;
procedure TGUIForm.ReposWindow;
var
x, y, w, h: integer;
json, S: string;
Respo: TStringStream;
p, q: TPoint;
begin
q.X := 0;
q.Y := 0;
p := embedPanel.ClientToScreen(q);
x := p.X;
y := p.Y;
w := embedPanel.Width;
h := embedPanel.Height;
if (lx = x) and (ly = y) and (lw = w) and (lh = h) then
exit;
lx := x;
ly := y;
lw := w;
lh := h;
json := '{"x":' + IntToStr(x) +
',"y":'+IntToStr(y) +
',"w":'+IntToStr(w) +
',"h":'+IntToStr(h) +
'}';
Respo := TStringStream.Create('');
self.hc.SimpleFormPost('http://localhost:38911/api/control/window/position',json,Respo);
S := Respo.DataString;
self.StatusBar1.SimpleText:=S;
Respo.Destroy;
end;
procedure TGUIForm.SendKey(key: Char; ScanCode: Integer; KeyAction: Integer; Mods: Integer);
var
json, S: string;
Respo: TStringStream;
begin
if key = Char(8) then
key := Char(127);
json := '{"key":' + IntToStr(Ord(key)) +
',"scancode":'+IntToStr(ScanCode) +
',"action":'+IntToStr(KeyAction) +
',"modifiers":'+IntToStr(Mods) +
'}';
Respo := TStringStream.Create('');
self.hc.SimpleFormPost('http://localhost:38911/api/control/input/keyevent',json,Respo);
S := Respo.DataString;
self.StatusBar1.SimpleText:=S;
Respo.Destroy;
end;
procedure TGUIForm.tbDisk1MouseDown(Sender: TObject; Button: TMouseButton;
Shift: TShiftState; X, Y: Integer);
begin
DiskMenu.Tag := TToolButton(Sender).Tag;
StatusBar1.SimpleText := 'Disk 1';
end;
procedure TGUIForm.tbDisk2MouseDown(Sender: TObject; Button: TMouseButton;
Shift: TShiftState; X, Y: Integer);
begin
DiskMenu.Tag := TToolButton(Sender).Tag;
StatusBar1.SimpleText := 'Disk 2';
end;
procedure TGUIForm.ToolButton5Click(Sender: TObject);
begin
RebootVM;
end;
procedure TGUIForm.MenuItem1Click(Sender: TObject);
begin
end;
procedure TGUIForm.FormActivate(Sender: TObject);
begin
end;
procedure TGUIForm.FormChangeBounds(Sender: TObject);
begin
self.ReposWindow;
end;
procedure TGUIForm.Button1Click(Sender: TObject);
begin
self.ReposWindow;
end;
{$IFDEF WINDOWS}
function TGUIForm.GetTitleOfActiveWindow: string;
var
AHandle: THandle;
ATitle: string;
ALen: Integer;
begin
Result := '';
AHandle := GetForegroundWindow;
if AHandle <> 0 then begin
ALen := GetWindowTextLength(AHandle) + 1;
SetLength(ATitle, ALen);
GetWindowText(AHandle, PChar(ATitle), ALen);
result := Trim(ATitle);
end;
end;
{$ELSE}
// stub for now
function TGUIForm.GetTitleOfActiveWindow: string;
var s: string;
begin
Result := '';
s := self.hc.Get('http://localhost:38911/api/control/window/focused');
if s = '1' then
Result := 'microM8';
end;
{$ENDIF}
procedure TGUIForm.CheckTimerTimer(Sender: TObject);
begin
//if MilliSecondsBetween(Now(), lastShowTime) < 500 then
// exit;
if WindowState = wsMinimized then
exit;
if hidden then
exit;
if GetTitleOfActiveWindow = 'microM8' then
begin
//Application.Restore;
Application.BringToFront;
{$IFDEF WINDOWS}
SetForegroundWindow(Application.MainForm.Handle);
{$ENDIF}
StatusBar1.SimpleText := 'App is refocussing';
lastShowTime := Now();
end;
end;
procedure TGUIForm.FormCreate(Sender: TObject);
begin
self.hc := TFPHttpClient.Create(Nil);
hidden := true;
end;
procedure TGUIForm.FormDeactivate(Sender: TObject);
begin
end;
procedure TGUIForm.FormHide(Sender: TObject);
begin
RepaintWindow;
HideM8;
end;
procedure TGUIForm.FormKeyDown(Sender: TObject; var Key: Word; Shift: TShiftState
);
var
m: Integer;
begin
m := 0;
if ssShift in Shift then
m := m or 1;
if ssCtrl in Shift then
m := m or 2;
if ssAlt in Shift then
m := m or 4;
SendKey( Char(Key), 0, 1, m );
end;
procedure TGUIForm.FormKeyPress(Sender: TObject; var Key: char);
begin
SendKey( Key, 0, 1, 0 );
end;
procedure TGUIForm.FormKeyUp(Sender: TObject; var Key: Word; Shift: TShiftState);
var
m: Integer;
begin
m := 0;
if ssShift in Shift then
m := m or 1;
if ssCtrl in Shift then
m := m or 2;
if ssAlt in Shift then
m := m or 4;
SendKey( Char(Key), 0, 0, m );
end;
procedure TGUIForm.FormResize(Sender: TObject);
begin
// on form resize we need to send a size request
ReposWindow;
end;
procedure TGUIForm.FormShow(Sender: TObject);
begin
ShowM8;
ReposWindow;
end;
procedure TGUIForm.FormUTF8KeyPress(Sender: TObject; var UTF8Key: TUTF8Char);
begin
end;
procedure TGUIForm.FormWindowStateChange(Sender: TObject);
begin
//Memo1.Lines.Add('window state has changed');
if WindowState = wsMinimized then
HideM8
else
ShowM8;
end;
procedure TGUIForm.MenuItem2Click(Sender: TObject);
begin
Application.Terminate();
end;
end.

BIN
poc.ico Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 134 KiB

85
poc.lpi Normal file
View File

@ -0,0 +1,85 @@
<?xml version="1.0" encoding="UTF-8"?>
<CONFIG>
<ProjectOptions>
<Version Value="11"/>
<PathDelim Value="\"/>
<General>
<SessionStorage Value="InProjectDir"/>
<MainUnit Value="0"/>
<Title Value="poc"/>
<Scaled Value="True"/>
<ResourceType Value="res"/>
<UseXPManifest Value="True"/>
<XPManifest>
<DpiAware Value="True"/>
</XPManifest>
<Icon Value="0"/>
</General>
<BuildModes Count="1">
<Item1 Name="Default" Default="True"/>
</BuildModes>
<PublishOptions>
<Version Value="2"/>
<UseFileFilters Value="True"/>
</PublishOptions>
<RunParams>
<FormatVersion Value="2"/>
<Modes Count="0"/>
</RunParams>
<RequiredPackages Count="3">
<Item1>
<PackageName Value="LazOpenGLContext"/>
</Item1>
<Item2>
<PackageName Value="indylaz"/>
</Item2>
<Item3>
<PackageName Value="LCL"/>
</Item3>
</RequiredPackages>
<Units Count="2">
<Unit0>
<Filename Value="poc.lpr"/>
<IsPartOfProject Value="True"/>
</Unit0>
<Unit1>
<Filename Value="main.pas"/>
<IsPartOfProject Value="True"/>
<ComponentName Value="GUIForm"/>
<HasResources Value="True"/>
<ResourceBaseClass Value="Form"/>
</Unit1>
</Units>
</ProjectOptions>
<CompilerOptions>
<Version Value="11"/>
<PathDelim Value="\"/>
<Target>
<Filename Value="poc"/>
</Target>
<SearchPaths>
<IncludeFiles Value="$(ProjOutDir)"/>
<UnitOutputDirectory Value="lib\$(TargetCPU)-$(TargetOS)"/>
</SearchPaths>
<Linking>
<Options>
<Win32>
<GraphicApplication Value="True"/>
</Win32>
</Options>
</Linking>
</CompilerOptions>
<Debugging>
<Exceptions Count="3">
<Item1>
<Name Value="EAbort"/>
</Item1>
<Item2>
<Name Value="ECodetoolError"/>
</Item2>
<Item3>
<Name Value="EFOpenError"/>
</Item3>
</Exceptions>
</Debugging>
</CONFIG>

22
poc.lpr Normal file
View File

@ -0,0 +1,22 @@
program poc;
{$mode objfpc}{$H+}
uses
{$IFDEF UNIX}{$IFDEF UseCThreads}
cthreads,
{$ENDIF}{$ENDIF}
Interfaces, // this includes the LCL widgetset
Forms, lazopenglcontext, indylaz, main
{ you can add units after this };
{$R *.res}
begin
RequireDerivedFormResource:=True;
Application.Scaled:=True;
Application.Initialize;
Application.CreateForm(TGUIForm, GUIForm);
Application.Run;
end.

166
poc.lps Normal file
View File

@ -0,0 +1,166 @@
<?xml version="1.0" encoding="UTF-8"?>
<CONFIG>
<ProjectSession>
<PathDelim Value="\"/>
<Version Value="11"/>
<BuildModes Active="Default"/>
<Units Count="3">
<Unit0>
<Filename Value="poc.lpr"/>
<IsPartOfProject Value="True"/>
<EditorIndex Value="-1"/>
<WindowIndex Value="-1"/>
<TopLine Value="-1"/>
<CursorPos X="-1" Y="-1"/>
<UsageCount Value="73"/>
</Unit0>
<Unit1>
<Filename Value="main.pas"/>
<IsPartOfProject Value="True"/>
<ComponentName Value="GUIForm"/>
<HasResources Value="True"/>
<ResourceBaseClass Value="Form"/>
<IsVisibleTab Value="True"/>
<TopLine Value="357"/>
<CursorPos X="8" Y="151"/>
<UsageCount Value="73"/>
<Loaded Value="True"/>
<LoadedDesigner Value="True"/>
</Unit1>
<Unit2>
<Filename Value="C:\lazarus\lcl\include\picture.inc"/>
<EditorIndex Value="1"/>
<TopLine Value="576"/>
<CursorPos X="49" Y="591"/>
<UsageCount Value="14"/>
<Loaded Value="True"/>
</Unit2>
</Units>
<JumpHistory Count="30" HistoryIndex="29">
<Position1>
<Filename Value="main.pas"/>
<Caret Line="180" Column="23" TopLine="164"/>
</Position1>
<Position2>
<Filename Value="main.pas"/>
<Caret Line="179" Column="41" TopLine="163"/>
</Position2>
<Position3>
<Filename Value="main.pas"/>
<Caret Line="169" Column="38" TopLine="163"/>
</Position3>
<Position4>
<Filename Value="main.pas"/>
<Caret Line="168" Column="38" TopLine="162"/>
</Position4>
<Position5>
<Filename Value="main.pas"/>
<Caret Line="170" Column="16" TopLine="162"/>
</Position5>
<Position6>
<Filename Value="main.pas"/>
<Caret Line="182" Column="46" TopLine="162"/>
</Position6>
<Position7>
<Filename Value="main.pas"/>
<Caret Line="9" Column="86"/>
</Position7>
<Position8>
<Filename Value="main.pas"/>
<Caret Line="177" Column="15" TopLine="160"/>
</Position8>
<Position9>
<Filename Value="main.pas"/>
<Caret Line="170" Column="13" TopLine="162"/>
</Position9>
<Position10>
<Filename Value="main.pas"/>
<Caret Line="185" Column="13" TopLine="163"/>
</Position10>
<Position11>
<Filename Value="main.pas"/>
<Caret Line="187" Column="31" TopLine="166"/>
</Position11>
<Position12>
<Filename Value="main.pas"/>
<Caret Line="185" Column="58" TopLine="166"/>
</Position12>
<Position13>
<Filename Value="main.pas"/>
<Caret Line="191" Column="43" TopLine="166"/>
</Position13>
<Position14>
<Filename Value="main.pas"/>
<Caret Line="195" Column="31" TopLine="166"/>
</Position14>
<Position15>
<Filename Value="main.pas"/>
<Caret Line="179" Column="75" TopLine="166"/>
</Position15>
<Position16>
<Filename Value="main.pas"/>
<Caret Line="181" Column="45" TopLine="161"/>
</Position16>
<Position17>
<Filename Value="main.pas"/>
<Caret Line="135" Column="12" TopLine="111"/>
</Position17>
<Position18>
<Filename Value="main.pas"/>
<Caret Line="59" Column="21" TopLine="133"/>
</Position18>
<Position19>
<Filename Value="main.pas"/>
<Caret Line="135" Column="31" TopLine="111"/>
</Position19>
<Position20>
<Filename Value="main.pas"/>
<Caret Line="134" Column="31" TopLine="110"/>
</Position20>
<Position21>
<Filename Value="main.pas"/>
<Caret Line="312" Column="29" TopLine="333"/>
</Position21>
<Position22>
<Filename Value="main.pas"/>
<Caret Line="69" Column="14" TopLine="47"/>
</Position22>
<Position23>
<Filename Value="main.pas"/>
<Caret Line="11" Column="11"/>
</Position23>
<Position24>
<Filename Value="main.pas"/>
<Caret Line="44" Column="48" TopLine="60"/>
</Position24>
<Position25>
<Filename Value="main.pas"/>
<Caret Line="181" Column="14" TopLine="159"/>
</Position25>
<Position26>
<Filename Value="main.pas"/>
<Caret Line="146" Column="36" TopLine="118"/>
</Position26>
<Position27>
<Filename Value="main.pas"/>
<Caret Line="104" Column="9" TopLine="82"/>
</Position27>
<Position28>
<Filename Value="main.pas"/>
<Caret Line="78" Column="21" TopLine="93"/>
</Position28>
<Position29>
<Filename Value="main.pas"/>
<Caret Line="139" Column="27" TopLine="123"/>
</Position29>
<Position30>
<Filename Value="main.pas"/>
<Caret Line="107" Column="45" TopLine="83"/>
</Position30>
</JumpHistory>
<RunParams>
<FormatVersion Value="2"/>
<Modes Count="0" ActiveMode=""/>
</RunParams>
</ProjectSession>
</CONFIG>

BIN
poc.res Normal file

Binary file not shown.