215 lines
5.6 KiB
ObjectPascal
215 lines
5.6 KiB
ObjectPascal
|
program FlameSS;
|
||
|
|
||
|
uses
|
||
|
Forms,
|
||
|
Dialogs,
|
||
|
SysUtils,
|
||
|
Render,
|
||
|
controlpoint,
|
||
|
windows,
|
||
|
graphics,
|
||
|
messages,
|
||
|
ScrConfig in '..\..\ScreenSaver\ScrConfig.pas' {frmConfig},
|
||
|
ScrMain in '..\..\ScreenSaver\ScrMain.pas' {frmMain},
|
||
|
FlameIO in '..\..\ScreenSaver\FlameIO.pas';
|
||
|
|
||
|
{$E SCR}
|
||
|
|
||
|
{$R *.res}
|
||
|
|
||
|
type TSSMode = (ssSetPwd,ssPreview,ssConfig,ssRun);
|
||
|
|
||
|
var
|
||
|
MySem: THandle;
|
||
|
|
||
|
function GetScreenSaverMode: TSSMode;
|
||
|
var
|
||
|
ParamChar: Char;
|
||
|
begin
|
||
|
Result := ssRun;
|
||
|
if ParamCount = 0 then
|
||
|
Exit;
|
||
|
|
||
|
if Length(ParamStr(1)) = 1 then
|
||
|
ParamChar := ParamStr(1)[1]
|
||
|
else
|
||
|
ParamChar := ParamStr(1)[2];
|
||
|
|
||
|
Case ParamChar of
|
||
|
'A', 'a':
|
||
|
Result := ssSetPwd;
|
||
|
'P', 'p':
|
||
|
Result := ssPreview;
|
||
|
'C', 'c':
|
||
|
Result := ssConfig;
|
||
|
else
|
||
|
Result := ssRun;
|
||
|
end;
|
||
|
end;
|
||
|
|
||
|
procedure SetPassWord;
|
||
|
var
|
||
|
SysDir: string;
|
||
|
NewLen: integer;
|
||
|
MyMod: THandle;
|
||
|
PwdFunc: function (a : PChar; ParentHandle : THandle; b, c : Integer) :
|
||
|
Integer; stdcall;
|
||
|
begin
|
||
|
SetLength(SysDir,MAX_PATH);
|
||
|
NewLen := GetSystemDirectory(PChar(SysDir),MAX_PATH);
|
||
|
SetLength(SysDir,NewLen);
|
||
|
|
||
|
MyMod := LoadLibrary(PChar(IncludeTrailingPathDelimiter(SysDir) + 'MPR.DLL'));
|
||
|
if MyMod <> 0 then begin
|
||
|
PwdFunc := GetProcAddress(MyMod,'PwdChangePasswordA');
|
||
|
if Assigned(PwdFunc) then
|
||
|
PwdFunc('SCRSAVE',StrToInt(paramstr(2)),0,0);
|
||
|
FreeLibrary(MyMod);
|
||
|
end;
|
||
|
end;
|
||
|
|
||
|
function WindowProc(Wnd: HWnd; Msg: Integer; wParam: Word; lParam: Integer): Integer; far; stdcall;
|
||
|
begin
|
||
|
|
||
|
{ Window procedure for the saver preview. Only used for terminating the preview
|
||
|
version of the saver. }
|
||
|
if (Msg = WM_DESTROY) or (Msg = WM_CLOSE) then PostMessage(Wnd, WM_QUIT, 0, 0);
|
||
|
Result := DefWindowProc(Wnd, Msg, wParam, lParam);
|
||
|
|
||
|
end;
|
||
|
|
||
|
procedure Preview;
|
||
|
var
|
||
|
PreviewCanvas: TCanvas;
|
||
|
PreviewRect: TRect;
|
||
|
WndClass: TWndClass;
|
||
|
DC: hDC;
|
||
|
MyWnd: hWnd;
|
||
|
Msg: TMsg;
|
||
|
ParentHandle: THandle;
|
||
|
cp : TControlPoint;
|
||
|
Render: TRenderer;
|
||
|
bm: TBitmap;
|
||
|
begin
|
||
|
{ To run the preview, you need to create a window class corresponding with the
|
||
|
little display in the screensaver control panel. This doesn't look very
|
||
|
elegant in a Delphi project, but I don't think you can use VCL functionality
|
||
|
to do this... }
|
||
|
with WndClass do
|
||
|
begin
|
||
|
style := CS_PARENTDC;
|
||
|
lpfnWndProc := @WindowProc;
|
||
|
cbClsExtra := 0;
|
||
|
cbWndExtra := 0;
|
||
|
hIcon := 0;
|
||
|
hCursor := 0;
|
||
|
hbrBackground := 0;
|
||
|
lpszMenuName := nil;
|
||
|
lpszClassName := 'DeskSpin';
|
||
|
end;
|
||
|
WndClass.hInstance := hInstance;
|
||
|
Windows.RegisterClass(WndClass);
|
||
|
|
||
|
ParentHandle := StrToInt(ParamStr(2));
|
||
|
|
||
|
// Initialize a Rect that matches the preview area:
|
||
|
GetWindowRect(Parenthandle, PreviewRect);
|
||
|
PreviewRect.Right := PreviewRect.Right - PreviewRect.Left;
|
||
|
PreviewRect.Bottom := PreviewRect.Bottom - PreviewRect.Top;
|
||
|
PreviewRect.Left := 0;
|
||
|
PreviewRect.Top := 0;
|
||
|
|
||
|
// Instantiate the window class so we can draw to the preview area:
|
||
|
MyWnd := CreateWindow('DeskSpin', 'DeskSpin',
|
||
|
WS_CHILD or WS_DISABLED or WS_VISIBLE, 0, 0,
|
||
|
PreviewRect.Right, PreviewRect.Bottom, ParentHandle,
|
||
|
0, hInstance, nil);
|
||
|
|
||
|
// We need a DC before we can draw:
|
||
|
DC := GetDC(MyWnd);
|
||
|
{ We can create a TCanvas matching the DC, so we can draw the preview with
|
||
|
familiar functions: }
|
||
|
PreviewCanvas := TCanvas.Create;
|
||
|
PreviewCanvas.Handle := DC;
|
||
|
|
||
|
randomize;
|
||
|
cp := TControlPoint.Create;
|
||
|
Render := TRenderer.Create;
|
||
|
|
||
|
cp.ParseString('pixels_per_unit 277.456647 center -1.0982659 0 gamma 2 spatial_filter_radius' +
|
||
|
' 0.5 contrast 1 brightness 1.5 zoom 0 spatial_oversample 1 sample_density 1 nbatches' +
|
||
|
' 1 white_level 200 cmap_inter 0 time 0 cmap 33 xform 0 density 1 color 0 var 0 0 0 1 0' +
|
||
|
' 0 0 coefs 0.466381997 -0.0618700013 0.0792416036 0.610638022 -0.475656986 -0.28115499'+
|
||
|
' xform 1 density 1 color 1 var 0 0 0 0 1 0 0 coefs -0.513867021 0.271649003 -0.254521996' +
|
||
|
' -0.550984025 -0.674094975 -0.600323975');
|
||
|
|
||
|
cp.sample_density := 1;
|
||
|
cp.Width := PreviewRect.Right - PreviewRect.Left;
|
||
|
cp.Height := PreviewRect.Bottom - PreviewRect.Top;
|
||
|
cp.spatial_oversample := 2;
|
||
|
cp.spatial_filter_radius := 0.1;
|
||
|
cp.Gamma := 4;
|
||
|
cp.brightness := 4;
|
||
|
cp.CalcBoundbox;
|
||
|
Render.SetCP(cp);
|
||
|
Render.Render;
|
||
|
BM := Render.GetImage;
|
||
|
PreviewCanvas.Draw(0,0,bm);
|
||
|
|
||
|
|
||
|
{ Enter a message loop to keep the preview going. I've kept the preview simple
|
||
|
(plain text output), but if you wanted, you could initialize OpenGL for the
|
||
|
DC you already have, and actually let your saver render to that. }
|
||
|
while GetMessage(Msg, 0, 0, 0) do
|
||
|
begin
|
||
|
PreviewCanvas.Draw(0,0,bm);
|
||
|
|
||
|
// PreviewCanvas.FillRect(PreviewRect);
|
||
|
// PreviewCanvas.TextOut(5, 5, 'Your preview here.');
|
||
|
TranslateMessage(Msg);
|
||
|
DispatchMessage(Msg);
|
||
|
end;
|
||
|
PreviewCanvas.Free;
|
||
|
|
||
|
// Close and destroy the preview window:
|
||
|
CloseWindow(MyWnd);
|
||
|
DestroyWindow(MyWnd);
|
||
|
|
||
|
Render.Free;
|
||
|
cp.Free;
|
||
|
end;
|
||
|
|
||
|
begin
|
||
|
Case GetScreenSaverMode of
|
||
|
ssSetPwd:
|
||
|
begin
|
||
|
Application.Initialize;
|
||
|
SetPassWord;
|
||
|
end;
|
||
|
ssConfig:
|
||
|
begin
|
||
|
Application.Initialize;
|
||
|
Application.Title := 'Flame Screensaver';
|
||
|
Application.CreateForm(TfrmConfig, frmConfig);
|
||
|
Application.Run;
|
||
|
end;
|
||
|
ssPreview:
|
||
|
Preview;
|
||
|
else // ssrun
|
||
|
// Test if screen save was already started
|
||
|
MySem := CreateSemaphore(nil,0,1,'ESDSaverSemaphore');
|
||
|
if (MySem <> 0) and (GetLastError = ERROR_ALREADY_EXISTS) then begin
|
||
|
CloseHandle(MySem);
|
||
|
Exit;
|
||
|
end;
|
||
|
|
||
|
Application.Initialize;
|
||
|
Application.CreateForm(TfrmMain, frmMain);
|
||
|
Application.Run;
|
||
|
|
||
|
if (MySem <> 0) then
|
||
|
CloseHandle(MySem);
|
||
|
end; // Case GetScreenSaverMode of
|
||
|
|
||
|
end.
|