mirror of
https://gitlab.com/freepascal.org/fpc/source.git
synced 2025-06-06 05:18:30 +02:00
1138 lines
30 KiB
ObjectPascal
1138 lines
30 KiB
ObjectPascal
{
|
|
$Id$
|
|
This file is part of the Free Pascal Integrated Development Environment
|
|
Copyright (c) 1998 by Berczi Gabor
|
|
|
|
User screen support routines
|
|
|
|
See the file COPYING.FPC, included in this distribution,
|
|
for details about the copyright.
|
|
|
|
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.
|
|
|
|
**********************************************************************}
|
|
{$i globdir.inc}
|
|
unit FPUsrScr;
|
|
|
|
interface
|
|
|
|
uses
|
|
{$ifdef win32}
|
|
windows,
|
|
{$endif win32}
|
|
video,Objects;
|
|
|
|
type
|
|
|
|
PScreen = ^TScreen;
|
|
TScreen = object(TObject)
|
|
function GetWidth: integer; virtual;
|
|
function GetHeight: integer; virtual;
|
|
procedure GetLine(Line: integer; var Text, Attr: string); virtual;
|
|
procedure GetCursorPos(var P: TPoint); virtual;
|
|
{ copy the initial video screen in the ide screen }
|
|
procedure Capture; virtual;
|
|
{ move up or down if supported by OS }
|
|
function Scroll(i : integer) : integer; virtual;
|
|
{ saves the current IDE screen }
|
|
procedure SaveIDEScreen; virtual;
|
|
{ saves the current console screen }
|
|
procedure SaveConsoleScreen; virtual;
|
|
{ restores the saved console screen }
|
|
procedure SwitchToConsoleScreen; virtual;
|
|
{ restores the saved IDE screen }
|
|
procedure SwitchBackToIDEScreen; virtual;
|
|
end;
|
|
|
|
{$ifdef DOS}
|
|
TDOSVideoInfo = record
|
|
Mode : word;
|
|
ScreenSize: word;
|
|
Page : byte;
|
|
Rows,Cols : integer;
|
|
CurPos : TPoint;
|
|
CurShapeT : integer;
|
|
CurShapeB : integer;
|
|
StateSize : word;
|
|
StateBuf : pointer;
|
|
end;
|
|
|
|
PDOSScreen = ^TDOSScreen;
|
|
TDOSScreen = object(TScreen)
|
|
constructor Init;
|
|
destructor Done; virtual;
|
|
public
|
|
function GetWidth: integer; virtual;
|
|
function GetHeight: integer; virtual;
|
|
procedure GetLine(Line: integer; var Text, Attr: string); virtual;
|
|
procedure GetCursorPos(var P: TPoint); virtual;
|
|
procedure Capture; virtual;
|
|
procedure SaveIDEScreen; virtual;
|
|
procedure SaveConsoleScreen; virtual;
|
|
procedure SwitchToConsoleScreen; virtual;
|
|
procedure SwitchBackToIDEScreen; virtual;
|
|
private
|
|
ConsoleVideoInfo : TDOSVideoInfo;
|
|
VBufferSize : longint;
|
|
VIDEBufferSize : longint;
|
|
VBuffer : PByteArray;
|
|
VIDEBuffer : PByteArray;
|
|
IDEVideoInfo : TDOSVideoInfo;
|
|
ctrl_c_state : boolean;
|
|
function GetLineStartOfs(Line: integer): word;
|
|
procedure GetBuffer(Size: word);
|
|
procedure FreeBuffer;
|
|
procedure GetVideoMode(var MI: TDOSVideoInfo);
|
|
procedure SetVideoMode(MI: TDOSVideoInfo);
|
|
end;
|
|
{$endif}
|
|
|
|
{$ifdef Unix}
|
|
PLinuxScreen = ^TLinuxScreen;
|
|
TLinuxScreen = object(TScreen)
|
|
constructor Init;
|
|
destructor Done; virtual;
|
|
public
|
|
function GetWidth: integer; virtual;
|
|
function GetHeight: integer; virtual;
|
|
procedure GetLine(Line: integer; var Text, Attr: string); virtual;
|
|
procedure GetCursorPos(var P: TPoint); virtual;
|
|
procedure Capture; virtual;
|
|
procedure SaveIDEScreen; virtual;
|
|
procedure SaveConsoleScreen; virtual;
|
|
procedure SwitchToConsoleScreen; virtual;
|
|
procedure SwitchBackToIDEScreen; virtual;
|
|
private
|
|
IDE_screen: pvideobuf;
|
|
IDE_size : longint;
|
|
IsXterm : boolean;
|
|
end;
|
|
{$endif}
|
|
|
|
{$ifdef win32}
|
|
PWin32Screen = ^TWin32Screen;
|
|
TWin32Screen = object(TScreen)
|
|
constructor Init;
|
|
destructor Done; virtual;
|
|
public
|
|
function GetWidth: integer; virtual;
|
|
function GetHeight: integer; virtual;
|
|
procedure GetLine(Line: integer; var Text, Attr: string); virtual;
|
|
procedure GetCursorPos(var P: TPoint); virtual;
|
|
function Scroll(i : integer) : integer; virtual;
|
|
procedure Capture; virtual;
|
|
procedure SaveIDEScreen; virtual;
|
|
procedure SaveConsoleScreen; virtual;
|
|
procedure SwitchToConsoleScreen; virtual;
|
|
procedure SwitchBackToIDEScreen; virtual;
|
|
private
|
|
DosScreenBufferHandle,
|
|
IDEScreenBufferHandle,
|
|
StartScreenBufferHandle,
|
|
DummyScreenBufferHandle,
|
|
NewScreenBufferHandle : THandle;
|
|
IDEActive : boolean;
|
|
ConsoleMode,IdeMode : Dword;
|
|
procedure BufferCopy(src,dest : THandle);
|
|
end;
|
|
{$endif}
|
|
|
|
procedure InitUserScreen;
|
|
procedure DoneUserScreen;
|
|
|
|
const UserScreen : PScreen = nil;
|
|
|
|
implementation
|
|
|
|
uses
|
|
Dos
|
|
(* {$ifdef TP}
|
|
{$ifdef DPMI}
|
|
,WinAPI
|
|
{$endif}
|
|
{$endif}*)
|
|
{$ifdef FPC}
|
|
{$ifdef GO32V2}
|
|
,Dpmiexcp, Go32
|
|
{$endif}
|
|
{$endif}
|
|
{$ifdef fvision}
|
|
,Drivers
|
|
{$endif}
|
|
{$ifdef VESA}
|
|
,VESA
|
|
{$endif}
|
|
;
|
|
|
|
function TScreen.GetWidth: integer;
|
|
begin
|
|
Getwidth:=0;
|
|
Abstract;
|
|
end;
|
|
|
|
function TScreen.GetHeight: integer;
|
|
begin
|
|
Getheight:=0;
|
|
Abstract;
|
|
end;
|
|
|
|
procedure TScreen.GetLine(Line: integer; var Text, Attr: string);
|
|
begin
|
|
Abstract;
|
|
end;
|
|
|
|
procedure TScreen.GetCursorPos(var P: TPoint);
|
|
begin
|
|
Abstract;
|
|
end;
|
|
|
|
procedure TScreen.Capture;
|
|
begin
|
|
Abstract;
|
|
end;
|
|
|
|
procedure TScreen.SwitchToConsoleScreen;
|
|
begin
|
|
Abstract;
|
|
end;
|
|
|
|
procedure TScreen.SwitchBackToIDEScreen;
|
|
begin
|
|
Abstract;
|
|
end;
|
|
|
|
procedure TScreen.SaveIDEScreen;
|
|
begin
|
|
Abstract;
|
|
end;
|
|
|
|
function TScreen.Scroll(i : integer) : integer;
|
|
begin
|
|
Scroll:=0;
|
|
end;
|
|
|
|
procedure TScreen.SaveConsoleScreen;
|
|
begin
|
|
Abstract;
|
|
end;
|
|
|
|
|
|
{****************************************************************************
|
|
TDOSScreen
|
|
****************************************************************************}
|
|
|
|
{$ifdef DOS}
|
|
|
|
constructor TDOSScreen.Init;
|
|
begin
|
|
inherited Init;
|
|
Capture;
|
|
{ get the current ctrl-C state }
|
|
Ctrl_c_state:=djgpp_set_ctrl_c(false);
|
|
djgpp_set_ctrl_c(Ctrl_c_state);
|
|
end;
|
|
|
|
|
|
destructor TDOSScreen.Done;
|
|
begin
|
|
FreeBuffer;
|
|
if assigned(VIDEBuffer) then
|
|
FreeMem(VIDEBuffer,VIDEBufferSize);
|
|
inherited Done;
|
|
end;
|
|
|
|
|
|
function TDOSScreen.GetWidth: integer;
|
|
begin
|
|
GetWidth:=ConsoleVideoInfo.Cols;
|
|
end;
|
|
|
|
|
|
function TDOSScreen.GetHeight: integer;
|
|
begin
|
|
GetHeight:=ConsoleVideoInfo.Rows;
|
|
end;
|
|
|
|
|
|
procedure TDOSScreen.GetLine(Line: integer; var Text, Attr: string);
|
|
var X: integer;
|
|
W: word;
|
|
begin
|
|
Text:=''; Attr:='';
|
|
if Line<GetHeight then
|
|
begin
|
|
W:=GetLineStartOfs(Line);
|
|
for X:=0 to GetWidth-1 do
|
|
begin
|
|
{Text:=Text+chr(VBuffer^[W+X*2]);
|
|
Attr:=Attr+chr(VBuffer^[W+X*2+1]);}
|
|
System.Insert(chr(VBuffer^[W+X*2]),Text,Length(Text)+1);
|
|
System.Insert(chr(VBuffer^[W+X*2+1]),Attr,Length(Attr)+1);
|
|
end;
|
|
end;
|
|
end;
|
|
|
|
|
|
procedure TDOSScreen.GetCursorPos(var P: TPoint);
|
|
begin
|
|
P:=ConsoleVideoInfo.CurPos;
|
|
end;
|
|
|
|
|
|
procedure TDOSScreen.Capture;
|
|
begin
|
|
SaveConsoleScreen;
|
|
end;
|
|
|
|
procedure TDosScreen.SaveIDEScreen;
|
|
var
|
|
VSeg,SOfs: word;
|
|
begin
|
|
GetVideoMode(IDEVideoInfo);
|
|
{ First keep a copy of IDE screen }
|
|
if ConsoleVideoInfo.Mode=7 then
|
|
VSeg:=SegB000
|
|
else
|
|
VSeg:=SegB800;
|
|
SOfs:=MemW[Seg0040:$4e];
|
|
if not assigned(VIDEBuffer) or (VIDEBufferSize<>IDEVideoInfo.ScreenSize) then
|
|
begin
|
|
if assigned(VIDEBuffer) then
|
|
FreeMem(VIDEBuffer,VIDEBufferSize);
|
|
GetMem(VIDEBuffer,IDEVideoInfo.ScreenSize);
|
|
VIDEBufferSize:=IDEVideoInfo.ScreenSize;
|
|
end;
|
|
{$ifdef FPC}
|
|
DosmemGet(VSeg,SOfs,VIDEBuffer^,IDEVideoInfo.ScreenSize);
|
|
{$else}
|
|
Move(ptr(VSeg,SOfs)^,VIDEBuffer^,IDEVideoInfo.ScreenSize);
|
|
{$endif}
|
|
end;
|
|
|
|
procedure TDosScreen.SaveConsoleScreen;
|
|
var
|
|
VSeg,SOfs: word;
|
|
begin
|
|
GetVideoMode(ConsoleVideoInfo);
|
|
GetBuffer(ConsoleVideoInfo.ScreenSize);
|
|
if ConsoleVideoInfo.Mode=7 then
|
|
VSeg:=SegB000
|
|
else
|
|
VSeg:=SegB800;
|
|
SOfs:=MemW[Seg0040:$4e];
|
|
{$ifdef FPC}
|
|
DosmemGet(VSeg,SOfs,VBuffer^,ConsoleVideoInfo.ScreenSize);
|
|
{$else}
|
|
Move(ptr(VSeg,SOfs)^,VBuffer^,ConsoleVideoInfo.ScreenSize);
|
|
{$endif}
|
|
end;
|
|
|
|
procedure TDOSScreen.SwitchToConsoleScreen;
|
|
var
|
|
VSeg,SOfs: word;
|
|
begin
|
|
SetVideoMode(ConsoleVideoInfo);
|
|
|
|
if ConsoleVideoInfo.Mode=7 then
|
|
VSeg:=SegB000
|
|
else
|
|
VSeg:=SegB800;
|
|
SOfs:=MemW[Seg0040:$4e];
|
|
{$ifdef FPC}
|
|
DosmemPut(VSeg,SOfs,VBuffer^,ConsoleVideoInfo.ScreenSize);
|
|
djgpp_set_ctrl_c(Ctrl_c_state);
|
|
{$else}
|
|
Move(VBuffer^,ptr(VSeg,SOfs)^,ConsoleVideoInfo.ScreenSize);
|
|
{$endif}
|
|
end;
|
|
|
|
|
|
procedure TDOSScreen.SwitchBackToIDEScreen;
|
|
var
|
|
VSeg,SOfs: word;
|
|
begin
|
|
SetVideoMode(IDEVideoInfo);
|
|
if ConsoleVideoInfo.Mode=7 then
|
|
VSeg:=SegB000
|
|
else
|
|
VSeg:=SegB800;
|
|
SOfs:=MemW[Seg0040:$4e];
|
|
if assigned(VIDEBuffer) then
|
|
{$ifdef FPC}
|
|
DosmemPut(VSeg,SOfs,VIDEBuffer^,IDEVideoInfo.ScreenSize);
|
|
Ctrl_c_state := djgpp_set_ctrl_c(false);
|
|
{$else}
|
|
Move(VIDEBuffer^,ptr(VSeg,SOfs)^,IDEVideoInfo.ScreenSize);
|
|
{$endif}
|
|
end;
|
|
|
|
|
|
function TDOSScreen.GetLineStartOfs(Line: integer): word;
|
|
begin
|
|
GetLineStartOfs:=(ConsoleVideoInfo.Cols*Line)*2;
|
|
end;
|
|
|
|
|
|
procedure TDOSScreen.GetBuffer(Size: word);
|
|
begin
|
|
if (VBuffer<>nil) and (VBufferSize=Size) then Exit;
|
|
if VBuffer<>nil then FreeBuffer;
|
|
VBufferSize:=Size;
|
|
GetMem(VBuffer,VBufferSize);
|
|
end;
|
|
|
|
|
|
procedure TDOSScreen.FreeBuffer;
|
|
begin
|
|
if (VBuffer<>nil) and (VBufferSize>0) then FreeMem(VBuffer,VBufferSize);
|
|
VBuffer:=nil;
|
|
end;
|
|
|
|
|
|
procedure TDOSScreen.GetVideoMode(var MI: TDOSVideoInfo);
|
|
var
|
|
r: registers;
|
|
{$ifdef TP}
|
|
P: pointer;
|
|
Sel: longint;
|
|
(* {$I realintr.inc} *)
|
|
{$endif}
|
|
begin
|
|
if (MI.StateSize>0) and (MI.StateBuf<>nil) then
|
|
begin FreeMem(MI.StateBuf,MI.StateSize); MI.StateBuf:=nil; end;
|
|
|
|
MI.ScreenSize:=MemW[Seg0040:$4c];
|
|
r.ah:=$0f;
|
|
intr($10,r);
|
|
MI.Mode:=r.al;
|
|
MI.Page:=r.bh;
|
|
MI.Cols:=r.ah;
|
|
{$ifdef VESA}
|
|
VESAGetMode(MI.Mode);
|
|
{$endif}
|
|
MI.Rows:=MI.ScreenSize div (MI.Cols*2);
|
|
if MI.Rows=51 then MI.Rows:=50;
|
|
r.ah:=$03;
|
|
r.bh:=MI.Page;
|
|
intr($10,r);
|
|
with MI do
|
|
begin
|
|
CurPos.X:=r.dl; CurPos.Y:=r.dh;
|
|
CurShapeT:=r.ch; CurShapeB:=r.cl;
|
|
end;
|
|
|
|
(*
|
|
{$ifdef TP}
|
|
{ check VGA functions }
|
|
MI.StateSize:=0;
|
|
r.ah:=$1c; r.al:=0; r.cx:=7; intr($10,r);
|
|
if (r.al=$1c) and ((r.flags and fCarry)=0) and (r.bx>0) then
|
|
begin
|
|
MI.StateSize:=r.bx;
|
|
GetMem(MI.StateBuf,MI.StateSize); FillChar(MI.StateBuf^,MI.StateSize,0);
|
|
P:=MI.StateBuf;
|
|
{$ifdef DPMI}
|
|
Sel:=GlobalDosAlloc(MI.StateSize);
|
|
P:=Ptr(Sel shr 16,0);
|
|
{$endif}
|
|
r.ah:=$1c; r.al:=1; r.cx:=7;
|
|
r.es:=PtrRec(P).Seg; r.bx:=PtrRec(P).Ofs;
|
|
{$ifdef DPMI}realintr($10,r);{$else}intr($10,r);{$endif}
|
|
{$ifdef DPMI}
|
|
Move(Ptr(Sel and $ffff,0)^,MI.StateBuf^,MI.StateSize);
|
|
GlobalDosFree(Sel and $ffff);
|
|
{$endif}
|
|
end;
|
|
{$endif}
|
|
*)
|
|
end;
|
|
|
|
|
|
procedure TDOSScreen.SetVideoMode(MI: TDOSVideoInfo);
|
|
var r: registers;
|
|
CM: TDOSVideoInfo;
|
|
{$ifdef TP}
|
|
P: pointer;
|
|
Sel: longint;
|
|
{$I realintr.inc}
|
|
{$endif}
|
|
begin
|
|
FillChar(CM,sizeof(CM),0);
|
|
GetVideoMode(CM);
|
|
|
|
if (CM.Mode<>MI.Mode) or (CM.Cols<>MI.Cols) or (CM.Rows<>MI.Rows) then
|
|
begin
|
|
{$ifdef VESA}
|
|
if MI.Mode>=$100 then
|
|
VESASetMode(MI.Mode)
|
|
else
|
|
{$endif}
|
|
begin
|
|
r.ah:=$00; r.al:=MI.Mode; intr($10,r);
|
|
end;
|
|
if (MI.Mode=3) and (MI.Cols=80) and (MI.Rows=50) then
|
|
begin
|
|
r.ax:=$1112; r.bx:=$0;
|
|
intr($10,r);
|
|
end;
|
|
end;
|
|
r.ah:=$05; r.al:=MI.Page; intr($10,r);
|
|
r.ah:=$02; r.bh:=MI.Page; r.dl:=MI.CurPos.X; r.dh:=MI.CurPos.Y; intr($10,r);
|
|
r.ah:=$01; r.ch:=MI.CurShapeT; r.cl:=MI.CurShapeB; intr($10,r);
|
|
|
|
(*
|
|
{$ifdef TP}
|
|
if (MI.StateSize>0) and (MI.StateBuf<>nil) then
|
|
begin
|
|
P:=MI.StateBuf;
|
|
{$ifdef DPMI}
|
|
Sel:=GlobalDosAlloc(MI.StateSize);
|
|
Move(MI.StateBuf^,ptr(Sel and $ffff,0)^,MI.StateSize);
|
|
P:=Ptr(Sel shr 16,0);
|
|
{$endif}
|
|
r.ah:=$1c; r.al:=2; r.cx:=7;
|
|
r.es:=PtrRec(P).Seg; r.bx:=PtrRec(P).Ofs;
|
|
{$ifdef DPMI}realintr($10,r);{$else}intr($10,r);{$endif}
|
|
{$ifdef DPMI}
|
|
GlobalDosFree(Sel and $ffff);
|
|
{$endif}
|
|
end;
|
|
{$endif}
|
|
*)
|
|
end;
|
|
|
|
{$endif}
|
|
|
|
|
|
{****************************************************************************
|
|
TLinuxScreen
|
|
****************************************************************************}
|
|
|
|
{$ifdef Unix}
|
|
|
|
constructor TLinuxScreen.Init;
|
|
begin
|
|
inherited Init;
|
|
IDE_screen := nil;
|
|
IsXterm:=getenv('TERM')='xterm';
|
|
Capture;
|
|
end;
|
|
|
|
|
|
destructor TLinuxScreen.Done;
|
|
begin
|
|
inherited Done;
|
|
end;
|
|
|
|
|
|
function TLinuxScreen.GetWidth: integer;
|
|
begin
|
|
GetWidth:=ScreenWidth;
|
|
end;
|
|
|
|
|
|
function TLinuxScreen.GetHeight: integer;
|
|
begin
|
|
GetHeight:=ScreenHeight;
|
|
end;
|
|
|
|
|
|
procedure TLinuxScreen.GetLine(Line: integer; var Text, Attr: string);
|
|
begin
|
|
Text:='';
|
|
Attr:='';
|
|
end;
|
|
|
|
|
|
procedure TLinuxScreen.GetCursorPos(var P: TPoint);
|
|
begin
|
|
P.X:=0;
|
|
P.Y:=0;
|
|
end;
|
|
|
|
|
|
procedure TLinuxScreen.Capture;
|
|
begin
|
|
SaveConsoleScreen;
|
|
end;
|
|
|
|
procedure TLinuxScreen.SaveIDEScreen;
|
|
begin
|
|
if assigned(IDE_screen) then
|
|
dispose(IDE_screen);
|
|
getmem(IDE_screen,videobufsize);
|
|
Ide_size:=videobufsize;
|
|
move(videobuf^,IDE_screen^,videobufsize);
|
|
end;
|
|
|
|
procedure TLinuxScreen.SaveConsoleScreen;
|
|
begin
|
|
if IsXTerm then
|
|
write(#27'7'#27'[?47h');
|
|
end;
|
|
|
|
|
|
procedure TLinuxScreen.SwitchToConsoleScreen;
|
|
begin
|
|
if IsXterm then
|
|
begin
|
|
write(#27'[0m');
|
|
write(#27'[?47l'#27'8'#27'[m');
|
|
end;
|
|
end;
|
|
|
|
procedure TLinuxScreen.SwitchBackToIDEScreen;
|
|
begin
|
|
if IDE_screen = nil then
|
|
exit;
|
|
move(IDE_screen^,videobuf^,videobufsize);
|
|
freemem(IDE_screen,Ide_size);
|
|
IDE_screen := nil;
|
|
end;
|
|
|
|
{$endif}
|
|
|
|
{****************************************************************************
|
|
TWin32Screen
|
|
****************************************************************************}
|
|
|
|
{$ifdef win32}
|
|
|
|
procedure UpdateFileHandles;
|
|
begin
|
|
{StdInputHandle:=longint(GetStdHandle(STD_INPUT_HANDLE));}
|
|
StdOutputHandle:=longint(GetStdHandle(STD_OUTPUT_HANDLE));
|
|
{StdErrorHandle:=longint(GetStdHandle(STD_ERROR_HANDLE));}
|
|
TextRec(Output).Handle:=StdOutputHandle;
|
|
TextRec(StdOut).Handle:=StdOutputHandle;
|
|
{TextRec(StdErr).Handle:=StdErrorHandle;}
|
|
end;
|
|
|
|
constructor TWin32Screen.Init;
|
|
var
|
|
SecurityAttr : Security_attributes;
|
|
BigWin : Coord;
|
|
res : longbool;
|
|
Error : dword;
|
|
ConsoleScreenBufferInfo : Console_screen_buffer_info;
|
|
begin
|
|
inherited Init;
|
|
{if GetConsoleOutputCP<>437 then
|
|
res:=SetConsoleOutputCP(437);}
|
|
SecurityAttr.nLength:=SizeOf(Security_attributes);
|
|
SecurityAttr.lpSecurityDescriptor:=nil;
|
|
SecurityAttr.bInheritHandle:=true;
|
|
NewScreenBufferHandle:=CreateConsoleScreenBuffer(
|
|
GENERIC_READ or GENERIC_WRITE,
|
|
FILE_SHARE_READ or FILE_SHARE_WRITE,SecurityAttr,
|
|
CONSOLE_TEXTMODE_BUFFER,nil);
|
|
DummyScreenBufferHandle:=CreateConsoleScreenBuffer(
|
|
GENERIC_READ or GENERIC_WRITE,
|
|
FILE_SHARE_READ or FILE_SHARE_WRITE,SecurityAttr,
|
|
CONSOLE_TEXTMODE_BUFFER,nil);
|
|
StartScreenBufferHandle:=GetStdHandle(STD_OUTPUT_HANDLE);
|
|
GetConsoleMode(GetStdHandle(Std_Input_Handle), @ConsoleMode);
|
|
IdeMode:=ConsoleMode;
|
|
{$ifdef debug}
|
|
{define win32bigwin}
|
|
{$endif debug}
|
|
{$ifdef win32bigwin}
|
|
GetConsoleScreenBufferInfo(StartScreenBufferHandle,
|
|
@ConsoleScreenBufferInfo);
|
|
BigWin.X:=ConsoleScreenBufferInfo.dwSize.X;
|
|
BigWin.Y:=200;
|
|
{ Try to allow to store more info }
|
|
res:=SetConsoleScreenBufferSize(NewScreenBufferHandle,BigWin);
|
|
if not res then
|
|
error:=GetLastError;
|
|
res:=SetConsoleScreenBufferSize(StartScreenBufferHandle,BigWin);
|
|
if not res then
|
|
error:=GetLastError;
|
|
{$endif win32bigwin}
|
|
GetConsoleScreenBufferInfo(StartScreenBufferHandle,
|
|
@ConsoleScreenBufferInfo);
|
|
{ make sure that the IDE Screen Handle has the maximum display size
|
|
this removes the scroll bars if it is maximized }
|
|
res:=SetConsoleScreenBufferSize(NewScreenBufferHandle,
|
|
ConsoleScreenBufferInfo.dwMaximumWindowSize);
|
|
if not res then
|
|
error:=GetLastError;
|
|
IDEScreenBufferHandle:=NewScreenBufferHandle;
|
|
DosScreenBufferHandle:=StartScreenBufferHandle;
|
|
Capture;
|
|
{$ifdef fvision}
|
|
if TextModeGFV then
|
|
{$endif fvision}
|
|
SwitchBackToIDEScreen;
|
|
end;
|
|
|
|
destructor TWin32Screen.Done;
|
|
begin
|
|
{ copy the Dos buffer content into the original ScreenBuffer
|
|
which remains the startup std_output_handle PM }
|
|
{if StartScreenBufferHandle=IDEScreenBufferHandle then}
|
|
BufferCopy(DosScreenBufferHandle,IDEScreenBufferHandle);
|
|
SetConsoleActiveScreenBuffer(StartScreenBufferHandle);
|
|
SetStdHandle(Std_Output_Handle,StartScreenBufferHandle);
|
|
UpdateFileHandles;
|
|
CloseHandle(NewScreenBufferHandle);
|
|
CloseHandle(DummyScreenBufferHandle);
|
|
inherited Done;
|
|
end;
|
|
|
|
function TWin32Screen.GetWidth: integer;
|
|
var
|
|
ConsoleScreenBufferInfo : Console_screen_buffer_info;
|
|
begin
|
|
GetConsoleScreenBufferInfo(DosScreenBufferHandle,
|
|
@ConsoleScreenBufferInfo);
|
|
GetWidth:=ConsoleScreenBufferInfo.dwSize.X;
|
|
end;
|
|
|
|
function TWin32Screen.GetHeight: integer;
|
|
var
|
|
ConsoleScreenBufferInfo : Console_screen_buffer_info;
|
|
begin
|
|
GetConsoleScreenBufferInfo(DosScreenBufferHandle,
|
|
@ConsoleScreenBufferInfo);
|
|
GetHeight:=ConsoleScreenBufferInfo.dwSize.Y;
|
|
end;
|
|
|
|
function TWin32Screen.Scroll(i : integer) : integer;
|
|
var
|
|
ConsoleScreenBufferInfo : Console_screen_buffer_info;
|
|
ConsoleWindow : Small_rect;
|
|
begin
|
|
GetConsoleScreenBufferInfo(DosScreenBufferHandle,
|
|
@ConsoleScreenBufferInfo);
|
|
if (ConsoleScreenBufferInfo.srWindow.Top + i < 0) then
|
|
i:= -ConsoleScreenBufferInfo.srWindow.Top;
|
|
if (ConsoleScreenBufferInfo.srWindow.Bottom + i > ConsoleScreenBufferInfo.dwSize.Y) then
|
|
i:= ConsoleScreenBufferInfo.dwSize.Y - ConsoleScreenBufferInfo.srWindow.Bottom;
|
|
if i<>0 then
|
|
begin
|
|
ConsoleWindow.Left:=ConsoleScreenBufferInfo.srWindow.Left;
|
|
ConsoleWindow.Right:=ConsoleScreenBufferInfo.srWindow.Right;
|
|
ConsoleWindow.Top:=ConsoleScreenBufferInfo.srWindow.Top+i;
|
|
ConsoleWindow.Bottom:=ConsoleScreenBufferInfo.srWindow.Bottom+i;
|
|
SetConsoleWindowInfo(DosScreenBufferHandle,true,ConsoleWindow);
|
|
Scroll:=i;
|
|
end
|
|
else
|
|
Scroll:=0;
|
|
end;
|
|
|
|
procedure TWin32Screen.GetLine(Line: integer; var Text, Attr: string);
|
|
type
|
|
CharInfoArray = Array [0..255] of Char_Info;
|
|
var
|
|
LineBuf : ^CharInfoArray;
|
|
BufSize,BufCoord : Coord;
|
|
i,LineSize : longint;
|
|
WriteRegion : SMALL_RECT;
|
|
begin
|
|
GetMem(LineBuf,SizeOf(CharInfoArray));
|
|
LineSize:=ScreenWidth;
|
|
If LineSize>256 then
|
|
LineSize:=256;
|
|
BufSize.X:=LineSize;
|
|
BufSize.Y:=1;
|
|
BufCoord.X:=0;
|
|
BufCoord.Y:=0;
|
|
with WriteRegion do
|
|
begin
|
|
Top :=Line;
|
|
Left :=0;
|
|
Bottom := Line+1;
|
|
Right := LineSize-1;
|
|
end;
|
|
ReadConsoleOutput(DosScreenBufferHandle, PChar_info(LineBuf),
|
|
BufSize, BufCoord, @WriteRegion);
|
|
for i:=1 to LineSize do
|
|
begin
|
|
Text[i]:=LineBuf^[i-1].AsciiChar;
|
|
Attr[i]:=char(byte(LineBuf^[i-1].Attributes));
|
|
end;
|
|
FreeMem(LineBuf,SizeOf(CharInfoArray));
|
|
Text[0]:=char(byte(LineSize));
|
|
Attr[0]:=char(byte(LineSize));
|
|
end;
|
|
|
|
|
|
procedure TWin32Screen.GetCursorPos(var P: TPoint);
|
|
var
|
|
ConsoleScreenBufferInfo : Console_screen_buffer_info;
|
|
begin
|
|
GetConsoleScreenBufferInfo(DosScreenBufferHandle,
|
|
@ConsoleScreenBufferInfo);
|
|
P.X:=ConsoleScreenBufferInfo.dwCursorPosition.X;
|
|
P.Y:=ConsoleScreenBufferInfo.dwCursorPosition.Y;
|
|
end;
|
|
|
|
procedure TWin32Screen.BufferCopy(Src, Dest : THandle);
|
|
type
|
|
CharInfoArray = Array [0..256*255-1] of Char_Info;
|
|
var
|
|
LineBuf : ^CharInfoArray;
|
|
BufSize,BufCoord : Coord;
|
|
Error, LineSize,
|
|
Part, OnePartY: longint;
|
|
res : boolean;
|
|
WriteRegion : SMALL_RECT;
|
|
ConsoleScreenBufferInfo : Console_screen_buffer_info;
|
|
DestConsoleScreenBufferInfo : Console_screen_buffer_info;
|
|
begin
|
|
GetConsoleScreenBufferInfo(Src,
|
|
@ConsoleScreenBufferInfo);
|
|
GetConsoleScreenBufferInfo(Dest,
|
|
@DestConsoleScreenBufferInfo);
|
|
GetMem(LineBuf,SizeOf(CharInfoArray));
|
|
FillChar(LineBuf^,SizeOf(CharInfoArray),#0);
|
|
|
|
LineSize:=ConsoleScreenBufferInfo.dwSize.X;
|
|
If LineSize>256 then
|
|
LineSize:=256;
|
|
BufSize.X:=LineSize;
|
|
BufSize.Y:=ConsoleScreenBufferInfo.dwSize.Y;
|
|
BufCoord.X:=0;
|
|
BufCoord.Y:=0;
|
|
with WriteRegion do
|
|
begin
|
|
Top :=0;
|
|
Left :=0;
|
|
Bottom := ConsoleScreenBufferInfo.dwSize.Y-1;
|
|
Right := LineSize-1;
|
|
end;
|
|
if BufSize.X*BufSize.Y*Sizeof(CHAR_INFO) >= $8000 then
|
|
begin
|
|
OnePartY := ($8000 -1) div (BufSize.X * SizeOf(Char_Info) );
|
|
BufSize.Y:=OnePartY;
|
|
Part:=0;
|
|
while ((Part+1)*OnePartY < ConsoleScreenBufferInfo.dwSize.Y) do
|
|
begin
|
|
WriteRegion.Top := Part*OnePartY;
|
|
WriteRegion.Bottom := (Part+1)*OnePartY-1;
|
|
res:=ReadConsoleOutput(Src, PChar_info(LineBuf),
|
|
BufSize, BufCoord, @WriteRegion);
|
|
if not res then
|
|
Error:=GetLastError;
|
|
res:=WriteConsoleOutput(Dest, PChar_info(LineBuf),
|
|
BufSize, BufCoord, @WriteRegion);
|
|
if not res then
|
|
Error:=GetLastError;
|
|
Inc(Part);
|
|
end;
|
|
BufSize.Y:=ConsoleScreenBufferInfo.dwSize.Y - Part*OnePartY;
|
|
WriteRegion.Top := Part*OnePartY;
|
|
WriteRegion.Bottom := ConsoleScreenBufferInfo.dwSize.Y-1;
|
|
res:=ReadConsoleOutput(Src, PChar_info(LineBuf),
|
|
BufSize, BufCoord, @WriteRegion);
|
|
if not res then
|
|
Error:=GetLastError;
|
|
res:=WriteConsoleOutput(Dest, PChar_info(LineBuf),
|
|
BufSize, BufCoord, @WriteRegion);
|
|
if not res then
|
|
Error:=GetLastError;
|
|
end
|
|
else
|
|
begin
|
|
res:=ReadConsoleOutput(Src, PChar_info(LineBuf),
|
|
BufSize, BufCoord, @WriteRegion);
|
|
if not res then
|
|
Error:=GetLastError;
|
|
res:=WriteConsoleOutput(Dest, PChar_info(LineBuf),
|
|
BufSize, BufCoord, @WriteRegion);
|
|
if not res then
|
|
Error:=GetLastError;
|
|
end;
|
|
FreeMem(LineBuf,SizeOf(CharInfoArray));
|
|
SetConsoleCursorPosition(Dest, ConsoleScreenBufferInfo.dwCursorPosition);
|
|
end;
|
|
|
|
procedure TWin32Screen.Capture;
|
|
begin
|
|
{if StartScreenBufferHandle=IdeScreenBufferHandle then
|
|
BufferCopy(IDEScreenBufferHandle,DosScreenBufferHandle)
|
|
else
|
|
BufferCopy(DosScreenBufferHandle,IDEScreenBufferHandle);}
|
|
SaveConsoleScreen;
|
|
end;
|
|
|
|
{ dummy for win32 as the Buffer screen
|
|
do hold all the info }
|
|
procedure TWin32Screen.SaveIDEScreen;
|
|
begin
|
|
{$ifdef fvision}
|
|
if TextModeGFV then
|
|
{$endif fvision}
|
|
begin
|
|
GetConsoleMode(GetStdHandle(Std_Input_Handle), @IdeMode);
|
|
{ set the dummy buffer as active already now PM }
|
|
SetStdHandle(Std_Output_Handle,DummyScreenBufferHandle);
|
|
UpdateFileHandles;
|
|
end;
|
|
end;
|
|
|
|
{ dummy for win32 as the Buffer screen
|
|
do hold all the info }
|
|
procedure TWin32Screen.SaveConsoleScreen;
|
|
begin
|
|
{$ifdef fvision}
|
|
if TextModeGFV then
|
|
{$endif fvision}
|
|
begin
|
|
GetConsoleMode(GetStdHandle(Std_Input_Handle), @ConsoleMode);
|
|
{ set the dummy buffer as active already now PM }
|
|
SetStdHandle(Std_Output_Handle,DummyScreenBufferHandle);
|
|
UpdateFileHandles;
|
|
end;
|
|
end;
|
|
|
|
procedure TWin32Screen.SwitchToConsoleScreen;
|
|
begin
|
|
{$ifdef fvision}
|
|
if TextModeGFV then
|
|
{$endif fvision}
|
|
begin
|
|
SetConsoleActiveScreenBuffer(DosScreenBufferHandle);
|
|
SetStdHandle(Std_Output_Handle,DosScreenBufferHandle);
|
|
SetConsoleMode(GetStdHandle(Std_Input_Handle), ConsoleMode);
|
|
UpdateFileHandles;
|
|
end;
|
|
IDEActive:=false;
|
|
end;
|
|
|
|
procedure TWin32Screen.SwitchBackToIDEScreen;
|
|
var
|
|
ConsoleScreenBufferInfo : Console_screen_buffer_info;
|
|
WindowPos : Small_rect;
|
|
res : boolean;
|
|
error : longint;
|
|
begin
|
|
{$ifdef fvision}
|
|
if TextModeGFV then
|
|
{$endif fvision}
|
|
begin
|
|
SetStdHandle(Std_Output_Handle,IDEScreenBufferHandle);
|
|
UpdateFileHandles;
|
|
GetConsoleScreenBufferInfo(IDEScreenBufferHandle,
|
|
@ConsoleScreenBufferInfo);
|
|
SetConsoleActiveScreenBuffer(IDEScreenBufferHandle);
|
|
{$ifdef fvision}
|
|
{ Needed to force InitSystemMsg to use the right console handle }
|
|
DoneEvents;
|
|
InitEvents;
|
|
{$endif fvision}
|
|
IdeMode:=(IdeMode or ENABLE_MOUSE_INPUT or ENABLE_WINDOW_INPUT) and not ENABLE_PROCESSED_INPUT;
|
|
SetConsoleMode(GetStdHandle(Std_Input_Handle), IdeMode);
|
|
WindowPos.left:=0;
|
|
WindowPos.right:=ConsoleScreenBufferInfo.srWindow.right
|
|
-ConsoleScreenBufferInfo.srWindow.left;
|
|
WindowPos.top:=0;
|
|
WindowPos.bottom:=ConsoleScreenBufferInfo.srWindow.bottom
|
|
-ConsoleScreenBufferInfo.srWindow.top;
|
|
with ConsoleScreenBufferInfo.dwMaximumWindowSize do
|
|
begin
|
|
if WindowPos.Right<X-1 then
|
|
WindowPos.right:=X-1;
|
|
if WindowPos.Bottom<Y-1 then
|
|
WindowPos.Bottom:=Y-1;
|
|
end;
|
|
res:=SetConsoleWindowInfo(IDEScreenBufferHandle,true,WindowPos);
|
|
if not res then
|
|
error:=GetLastError;
|
|
end;
|
|
IDEActive:=true;
|
|
end;
|
|
|
|
{$endif}
|
|
|
|
|
|
{****************************************************************************
|
|
Initialize
|
|
****************************************************************************}
|
|
|
|
procedure InitUserScreen;
|
|
begin
|
|
{$ifdef DOS}
|
|
UserScreen:=New(PDOSScreen, Init);
|
|
{$else}
|
|
{$ifdef Unix}
|
|
UserScreen:=New(PLinuxScreen, Init);
|
|
{$else}
|
|
|
|
{$ifdef Win32}
|
|
UserScreen:=New(PWin32Screen, Init);
|
|
{$else}
|
|
UserScreen:=New(PScreen, Init);
|
|
{$endif Win32}
|
|
{$endif Unix}
|
|
{$endif Dos}
|
|
end;
|
|
|
|
|
|
procedure DoneUserScreen;
|
|
begin
|
|
if UserScreen<>nil then
|
|
begin
|
|
UserScreen^.SwitchToConsoleScreen;
|
|
Dispose(UserScreen, Done);
|
|
UserScreen:=nil;
|
|
end;
|
|
end;
|
|
|
|
end.
|
|
{
|
|
$Log$
|
|
Revision 1.13 2002-06-13 11:18:32 pierre
|
|
+ xterm window switching support
|
|
|
|
Revision 1.12 2002/06/07 14:10:24 pierre
|
|
* try to get resizing to work
|
|
|
|
Revision 1.11 2002/06/06 14:10:34 pierre
|
|
* allow window input for fvsion system messages
|
|
|
|
Revision 1.10 2002/06/06 06:46:28 pierre
|
|
* No videobuffer switch necessary for fvision win32 graphic version
|
|
|
|
Revision 1.9 2002/04/25 13:34:17 pierre
|
|
* fix the disappearing desktop for win32
|
|
|
|
Revision 1.8 2002/01/22 16:29:52 pierre
|
|
* try to fix win32 problem with Dos program ouptut in command shell
|
|
Warning, to debug under win32 with GDB you must use "set new-console on"
|
|
|
|
Revision 1.7 2001/11/08 17:06:22 pierre
|
|
* impose the correct size for win32 console window
|
|
|
|
Revision 1.6 2001/11/08 16:38:25 pierre
|
|
* fix win32 scrolling
|
|
+ always go back to 0,0 position in IDE mode
|
|
|
|
Revision 1.5 2001/11/08 16:07:41 pierre
|
|
* overcome buffer win32 problem due to a bug in ReadConsoleOutput
|
|
|
|
Revision 1.4 2001/10/24 14:17:27 pierre
|
|
* try to fix the Win2000 mouse problem
|
|
|
|
Revision 1.3 2001/09/09 20:44:53 carl
|
|
* bugfix of console sharing mode (on NT this would bug all
|
|
std_input access).
|
|
|
|
Revision 1.2 2001/08/12 00:04:50 pierre
|
|
* some speed improvements for string operations
|
|
|
|
Revision 1.1 2001/08/04 11:30:24 peter
|
|
* ide works now with both compiler versions
|
|
|
|
Revision 1.1.2.10 2001/06/14 09:15:16 pierre
|
|
TScreen methods reorganized:
|
|
SwitchTo method renamed SwitchToConsoleScreen
|
|
SwitchBack method renamed SwitchBackToIDEScreen
|
|
+ method Scroll added
|
|
+ SaveIDEScreen and SaveConsoleScreen methods added
|
|
|
|
Revision 1.1.2.9 2001/04/04 08:52:01 pierre
|
|
* allow inheritance for win32 DosScreenBufferHandle
|
|
|
|
Revision 1.1.2.8 2001/03/16 17:45:54 pierre
|
|
* free VIDEBuffer of TDosScreen
|
|
|
|
Revision 1.1.2.7 2000/11/30 13:04:01 pierre
|
|
* fix for bug 1205
|
|
|
|
Revision 1.1.2.6 2000/11/29 00:54:45 pierre
|
|
+ preserve window number and save special windows
|
|
|
|
Revision 1.1.2.5 2000/11/22 12:47:21 pierre
|
|
* fix the screen saving at start for win32
|
|
|
|
Revision 1.1.2.4 2000/11/14 09:23:56 marco
|
|
* Second batch
|
|
|
|
Revision 1.1.2.3 2000/10/10 21:24:56 pierre
|
|
* avoid writing past IDE_screen buffer length
|
|
|
|
Revision 1.1.2.2 2000/08/21 12:10:19 jonas
|
|
* fixed errors in my previous commit, it now works properly
|
|
|
|
Revision 1.1.2.1 2000/08/21 10:51:13 jonas
|
|
* IDE screen saving/restoring implemented for Linux
|
|
|
|
Revision 1.1 2000/07/13 09:48:36 michael
|
|
+ Initial import
|
|
|
|
Revision 1.13 2000/06/16 15:00:20 pierre
|
|
* accord to new WriteConsoleOuput declarations
|
|
|
|
Revision 1.12 2000/04/25 08:42:33 pierre
|
|
* New Gabor changes : see fixes.txt
|
|
|
|
Revision 1.11 2000/04/18 11:42:37 pierre
|
|
lot of Gabor changes : see fixes.txt
|
|
|
|
Revision 1.10 2000/03/13 20:30:37 pierre
|
|
+ stores IDE screen before Switching for DOS
|
|
|
|
Revision 1.9 2000/02/04 23:17:25 pierre
|
|
* Keep the entry ScreenBuffer at exit
|
|
|
|
Revision 1.8 1999/12/01 16:17:18 pierre
|
|
* Restore std_output_handle correctly at exit for GDB
|
|
|
|
Revision 1.7 1999/11/10 17:12:00 pierre
|
|
* Win32 screen problems solved
|
|
|
|
Revision 1.6 1999/09/22 13:02:00 pierre
|
|
+ Twin32Screen added
|
|
|
|
Revision 1.5 1999/08/16 18:25:24 peter
|
|
* Adjusting the selection when the editor didn't contain any line.
|
|
* Reserved word recognition redesigned, but this didn't affect the overall
|
|
syntax highlight speed remarkably (at least not on my Amd-K6/350).
|
|
The syntax scanner loop is a bit slow but the main problem is the
|
|
recognition of special symbols. Switching off symbol processing boosts
|
|
the performance up to ca. 200%...
|
|
* The editor didn't allow copying (for ex to clipboard) of a single character
|
|
* 'File|Save as' caused permanently run-time error 3. Not any more now...
|
|
* Compiler Messages window (actually the whole desktop) did not act on any
|
|
keypress when compilation failed and thus the window remained visible
|
|
+ Message windows are now closed upon pressing Esc
|
|
+ At 'Run' the IDE checks whether any sources are modified, and recompiles
|
|
only when neccessary
|
|
+ BlockRead and BlockWrite (Ctrl+K+R/W) implemented in TCodeEditor
|
|
+ LineSelect (Ctrl+K+L) implemented
|
|
* The IDE had problems closing help windows before saving the desktop
|
|
|
|
Revision 1.4 1999/06/28 19:32:25 peter
|
|
* fixes from gabor
|
|
|
|
Revision 1.3 1999/02/02 16:41:42 peter
|
|
+ automatic .pas/.pp adding by opening of file
|
|
* better debuggerscreen changes
|
|
|
|
Revision 1.2 1999/01/04 11:49:51 peter
|
|
* 'Use tab characters' now works correctly
|
|
+ Syntax highlight now acts on File|Save As...
|
|
+ Added a new class to syntax highlight: 'hex numbers'.
|
|
* There was something very wrong with the palette managment. Now fixed.
|
|
+ Added output directory (-FE<xxx>) support to 'Directories' dialog...
|
|
* Fixed some possible bugs in Running/Compiling, and the compilation/run
|
|
process revised
|
|
|
|
Revision 1.1 1998/12/28 15:47:53 peter
|
|
+ Added user screen support, display & window
|
|
+ Implemented Editor,Mouse Options dialog
|
|
+ Added location of .INI and .CFG file
|
|
+ Option (INI) file managment implemented (see bottom of Options Menu)
|
|
+ Switches updated
|
|
+ Run program
|
|
|
|
Revision 1.0 1998/12/24 09:55:49 gabor
|
|
Original implementation
|
|
|
|
}
|