lazarus/ide/laztty.pas

175 lines
4.6 KiB
ObjectPascal

{
* This is copied from the Free Pascal Compiler source file comptty.pas
Copyright (c) 2020 by the Free Pascal development team
This unit contains platform-specific code for checking TTY output
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
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. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
****************************************************************************
}
unit LazTTY;
{$mode objfpc}
{$H+}
interface
function IsATTY(var t : text) : Boolean;
const
(* This allows compile-time removal of the colouring functionality under not supported platforms *)
{$if defined(linux) or defined(MSWINDOWS) or defined(OS2) or defined(GO32V2) or defined(WATCOM) or defined(DARWIN)}
TTYCheckSupported = true;
{$else defined(linux) or defined(MSWINDOWS) or defined(OS2) or defined(GO32V2) or defined(WATCOM) or defined(DARWIN)}
TTYCheckSupported = false;
{$endif defined(linux) or defined(MSWINDOWS) or defined(OS2) or defined(GO32V2) or defined(WATCOM) or defined(DARWIN)}
implementation
{$if defined(linux) or defined(darwin)}
uses
termio;
{$endif defined(linux) or defined(darwin)}
{$ifdef mswindows}
uses
windows;
{$endif mswindows}
{$ifdef os2}
uses
doscalls;
{$endif os2}
{$if defined(GO32V2) or defined(WATCOM)}
uses
dos;
{$endif defined(GO32V2) or defined(WATCOM)}
const
CachedIsATTY : Boolean = false;
IsATTYValue : Boolean = false;
{$if defined(linux) or defined(darwin)}
function LinuxIsATTY(var t : text) : Boolean; inline;
begin
LinuxIsATTY:=termio.IsATTY(t)=1;
end;
{$endif defined(linux) or defined(darwin)}
{$ifdef MSWINDOWS}
const
ENABLE_VIRTUAL_TERMINAL_PROCESSING = $0004;
function WindowsIsATTY(var t : text) : Boolean; inline;
const
dwMode: dword = 0;
begin
WindowsIsATTY := false;
if GetConsoleMode(TextRec(t).handle, dwMode) then
begin
dwMode := dwMode or ENABLE_VIRTUAL_TERMINAL_PROCESSING;
if SetConsoleMode(TextRec(t).handle, dwMode) then
WindowsIsATTY := true;
end;
end;
{$endif MSWINDOWS}
{$IFDEF OS2}
function OS2IsATTY(var t : text) : Boolean; inline;
var
HT, Attr: cardinal;
{$IFDEF EMX}
OK: boolean;
{$ENDIF EMX}
const
dhDevice = 1;
begin
{$IFDEF EMX}
if os_mode = osOS2 then
begin
{$ENDIF EMX}
OS2IsATTY := (DosQueryHType (TextRec (T).Handle, HT, Attr) = 0)
and (HT = dhDevice);
{$IFDEF EMX}
end
else
begin
OK := false;
{$ASMMODE INTEL}
asm
mov ebx, TextRec (T).Handle
mov eax, 4400h
call syscall
jc @IsDevEnd
test edx, 80h { bit 7 is set if it is a device or a pipe }
jz @IsDevEnd
mov eax, 1A00h { Check ANSI.SYS availability }
int 2Fh
inc al { If it was FFh, then OK }
jnz @IsDevEnd
mov OK, true
@IsDevEnd:
end;
OS2IsATTY := OK;
end;
{$ENDIF EMX}
end;
{$ENDIF OS2}
{$if defined(GO32V2) or defined(WATCOM)}
function DosIsATTY(var t : text) : Boolean; inline;
var
Regs: Registers;
begin
Regs.EBX := TextRec (T).Handle;
Regs.EAX := $4400;
MsDos (Regs);
if (Regs.Flags and FCarry <> 0) or (Regs.EDX and $80 = 0) then
{ bit 7 is set if it is a device or a pipe }
DosIsATTY := false
else
begin
Regs.EAX := $1A00; { Check ANSI.SYS availability }
Intr ($2F, Regs);
DosIsATTY := Regs.AL = $FF; { If it was FFh, then OK }
end;
end;
{$endif defined(GO32V2) or defined(WATCOM)}
function IsATTY(var t : text) : Boolean;
begin
if not(CachedIsATTY) then
begin
(* If none of the supported values is defined, false is returned by default. *)
{$if defined(linux) or defined(darwin)}
IsATTYValue:=LinuxIsATTY(t);
{$endif defined(linux) or defined(darwin)}
{$ifdef MSWINDOWS}
IsATTYValue:=WindowsIsATTY(t);
{$endif MSWINDOWS}
{$ifdef OS2}
IsATTYValue:=OS2IsATTY(t);
{$endif OS2}
{$if defined(GO32V2) or defined(WATCOM)}
IsATTYValue:=DosIsATTY(t);
{$endif defined(GO32V2) or defined(WATCOM)}
CachedIsATTY:=true;
end;
Result:=IsATTYValue;
end;
end.