unit uATerm;

      {=================================================================}
      {                                                                 }
      {  SW pro terminaly SofCon                V2.52   17.03.2003 Bu   }
      {                                                                 }
      {  Objekt abstraktniho terminalu                                  }
      {                                                                 }
      {  (C) 1996-1997, SofCon s.r.o., Stresovicka 49, Praha 6          }
      {                 Vypracoval: V.Kastner, P.Weber, R.Bukovsky      }
      {=================================================================}

{$ifdef USE_SETS_INC} { Pokud chces tak nastav v Compiler Options/Conditional defines }
   {$I Sets.inc}
{$endif}

interface
uses
 {$IFDEF DEBUGSYSFC}
  uSysf,
 {$ENDIF}
  Objects,    { koren objektove hierarchie }
  ChnVirt,    { Abstraktni komunikacni kanal }
  Kernel,     { jadro operacniho systemu realneho casu }
  uString,    { jednotka pro praci s textovymi retezci }
  Timer,      { objekt casovace }
  uCharBuf,   { prace s buffrem znaku }
  NumToStr;   { prevody cisel na string }                                     

const
  cVerNo = $0510; { BCD format }
  cVer   = '05.10,23.09.2005';

const
  zBell     = #$07;     {znak pro Bell}
  zLf       = #$0a;     {line feed}
  zCr       = #$0d;     {carridge return}
  zBs       = #$08;     {backspace }
  zHt       = #$09;     {horizont. tabulator}
  zSBs      = #$1C;     {vymaz znaku doleva do konce = rychly BS}
  zEsc      = #$1B;     {znak pro ESC}
  zSpace    = #$20;     {znak pro mezeru}
  zDel      = #$7f;     {znak Del pro vymaz znaku}
  zUp       = #$c8;     {Cursor up}
  zDn       = #$d0;     {Cursor down}
  zLe       = #$cb;     {Cursor left}
  zRi       = #$cd;     {Cursor right}
  zF1       = #$bb;     {znak pro F1}
  zF2       = #$bc;     {znak pro F2}
  zF3       = #$bd;     {znak pro F3}
  zF4       = #$be;     {znak pro F4}
  zF5       = #$bf;     {znak pro F4}
  zF6       = #$c0;     {znak pro F6}
  zF7       = #$c1;     {znak pro F7}
  zF8       = #$c2;     {znak pro F8}
  zF9       = #$c3;     {znak pro F8}
  zF10      = #$c4;     {znak pro F10}
  zHome     = #$c7;     {znak pro Home}
  zPgUp     = #$c9;     {znak pro PgUp}
  zEnd      = #$cf;     {znak pro End}
  zPgDn     = #$d1;     {znak pro PgDn}
  zIns      = #$d2;     {znak pro Ins}

  zClrScr   = #$1f;     {znak pro smazani obrazovky}
  zCursorPc = #$DB;     {znak pro kursor simulatoru}
  zStart    = #$E0;     {znak pro klavesu START na klavesnici TERM10}
  zStop     = #$E1;     {znak pro klavesu STOP  na klavesnici TERM10}
  zCursor   = #$FF;     {znak pro kursor terminalu TERM01}

  zShiftEnter=#$9C;     {znak pro vstup do Terminal Setup}

  zHelp     = zF1;      {znak pro napovedu = F1}
  zTab      = zHt;

  TimeOutStr  : String[16]=zEsc+zEsc+zEsc+zEsc+zEsc+zEsc+zEsc+zEsc; { string pri TimeOut Keyb }
  BellStr     : String[1]= ZBell;
  HomeStr     : String[4]= zEsc+'Y'+#$0+#$0;


  esc_ScrBegin      = '{'; { ESC char begin screen   string }
  esc_ScrEnd        = '}'; { ESC char end   screen   string }
  esc_GraphicBegin  = '('; { ESC char begin graphic  string }
  esc_GraphicEnd    = ')'; { ESC char end   graphic  string }
  esc_BkGroundBegin = '<'; { ESC char begin BkGround string }
  esc_BkGroundEnd   = '>'; { ESC char end   BkGround string }
  esc_StylesBegin   = '['; { ESC char begin styles   string }
  esc_StylesEnd     = ']'; { ESC char end   styles   string }
  esc_CursorBegin   = '@'; { ESC char begin styles   string }
  esc_CursorEnd     = '&'; { ESC char end   styles   string }
  esc_LedBegin      = '!'; { ESC char begin led      string }
  esc_LedEnd        = '?'; { ESC char end   led      string }
  esc_SoundBegin    = '*'; { ESC char begin sound    string }
  esc_SoundEnd      = '/'; { ESC char end   sound    string }
  esc_OutBegin      = '''';{ ESC char begin out      string }
  esc_OutEnd        = '"'; { ESC char end   out      string }

type
  {!Po-Feb,2001}
  tEdit = (edStrings,edBinNum,edDecNum,edHexNum,edASCII,edLetters,edUnsDec,
           edRealNum);
  {definuje typ editovaneho znaku pro UpDn mod editace}
  tBuf    = array[0..$fff0] of Char;
  pBuf    = ^tBuf;

  tCharPoint  = record
    X,Y : byte;       { souradnice znaku ve znakovem rastru [X=sloupec,Y=radek] }
  end;

  tCharRect   = record
    X,Y,W,H : byte;   { miry ve znacich }
  end;

  tCharWin    = object
    X,Y  : byte;      { znakove souradnice pozice kurzoru }
    Rect : tCharRect;
    procedure AssignCursorPos(cx,cy:byte);
  end;

  tSetChar  = set of Char;

  tEvBeep   = (evBeep_Off,    { vypni  pipnuti }
               evBeep_On,     { zapni  pipnuti }
               evBeep_OnOff); { kratke pipnuti }

  pAKeyb = ^tAKeyb;
  pADisp = ^tADisp;
  pATerm = ^tATerm;

{=================================================================================================}
{                   A b s t r a c t    K  E  Y  B  O  A  R  D                                     }
{=================================================================================================}
  tAKeyb = object(tObject)
    OwnerTerm   : pATerm;    { ref_only na terminal, ktery tento objekt displej vlastni }
    constructor Init(TermOwner:pATerm;Len:word); { Len - delka vyrovnavaciho bufferu }
    destructor  Done;                                        virtual;

{$ifdef Ver70}
  public { properties }
{$endif}
  { protected properties }
  { public methods }
{$ifdef Ver60}
    procedure SetKeybParam(S:tParamStr);               virtual; { nastavi klavesnici }
    function  GetKeybParam(KeyStr:tParamStr):tParamStr;virtual; { navrati nastaveni klavesnice }
{$endif}
{$ifdef Ver70}
    procedure SetKeybParam(const S:tParamStr);               virtual; { nastavi klavesnici }
    function  GetKeybParam(const KeyStr:tParamStr):tParamStr;virtual; { navrati nastaveni klavesnice }
{$endif}
    function  ResultKeybParam: Boolean;                      virtual; { navrati vysledek inicializace,
                                                                        klavesnice False=>vporadku}
    procedure FlushKeyb;                                     virtual; { vyprazdni vyrovnavaci buffer }
    function  ReadKeybBuf(DstBuf:pBuf;DstSize:word):word;    virtual; { preda vyrovnavaci buffer, vraci delku  }
    function  KeyPressed:Boolean;                            virtual; { True - je k dispozici znak }
    function  ReadKey: Char;                                 virtual; { doda jeden znak z vyrovnavaciho bufferu, nebo #$0 }
    function  ShowKey: Char;                                 virtual; { ukaze znak ve vyrovnavacim bufferu, nebo #$0 }
    procedure InsertKey(Key: Char);                          virtual; { vlozi znak do vyrovnavaciho bufferu }
    function  KeybStatus: word;                              virtual; { status klavesnice - stlacene klavesy, ... }
    procedure Tick;                                                   { periodicky dotaz na klavesnici }
  { protected methods }
    procedure KTick;                                         virtual;

  private { properties }
    KeybBuf           : pBuf;    { vyrovnavaci buffer klavesnice }
    LKeybBuf          : word;    { delka vyrovnavaciho bufferu klavesnice }
    UKeybBuf          : word;    { index pro ulozeni znaku }
    VKeybBuf          : word;    { index pro vyzvednuti znaku }
    KeybSts           : word;    { status klavesnice }
    KeybCtrl          : word;    { stav automatu }
    ParamErr          : Boolean; { true = chyba }
    KTickRunning      : Boolean; { je vykonavana cinnost Tick }
  { private methods }
    procedure IncP(var W: word);
  end;

{=================================================================================================}
{                   A b s t r a c t    D  I  S  P  L  A  Y                                        }
{=================================================================================================}
{ Abstraktni displej je implementovan jako znakovy displej  X x Y znaku.                          }
{ Display umi zobrazovat pozici znakoveho kurzoru v ruznych modech                                }
(*

          ridici zn |         zobrazovana cast bufferu
       +--------------------------------------------------------+
       +  Ctrl Chrs |  radek   |  radek   |  radek   |  radek   |
       +--------------------------------------------------------+
       ^            ^                                           ^
       |            |                                           |
       |          BufRef+DispShowBufOfs                  BufRef+BufRefSize
       |
     BufRef


     Znaky jsou v zobrazovane casti bufferu ulozeny po radcich delky DispCharSizeX znaku.
     Pocet radek je dan hodnotou DispCharSizeY.
*)

  tCursorMode   = (CursorOff,
                   CursorOn,
                   CursorBlink);

  tDispBufState = (DispSts_Clear,        { zobrazovana cast bufferu obsahuje same mezery   }
                   DispSts_Accepted,     { buffer obsahuje data, ktera jsou jiz zobrazena  }
                   DispSts_Modified);    { obsah bufferu byl zmenen                        }

  TCursorAttrReaderWriter = object(TPropertyReaderWriter)
    A_CursorBufPos    : Word;        { Ofset pozice kurzoru vuci pocatku znakoveho bufferu }
    A_ShowCursor      : Boolean;     { True - kurzor ma byt viditelny }
    constructor Init;
{$ifdef Ver60}
    procedure ReadProperty  (var j:integer; S:string);               virtual; { override }
{$endif}
{$ifdef Ver70}
    procedure ReadProperty  (var j:integer;const S:string);          virtual; { override }
{$endif}
    procedure WriteProperty (DestBuf:pointer;DestSize:word);         virtual; { override }
  end;

  tADisp = object(TObject)
{$ifdef Ver70}
  public { properties ------------------------------------------------------------------------------}
{$endif}
    OwnerTerm         : pATerm;      { ref_only na terminal, ktery tento objekt displej vlastni }
    DispCharSizeX     : byte;        { pocet znakovych sloupcu displeje }
    DispCharSizeY     : byte;        { pocet znakovych radek   displeje }
    DispShowBufOfs    : word;        { Ofset pocatku znakoveho bufferu se znaky k zobrazeni }

  {------ protected properties ---------------------------------------------------------------------}
    BufRef            : pBuf;        { buffer vypisu je o RefOfs na zacatku vetsi nez OwnerTerm^.Buf^ }
    BufRefSize        : Word;        { alokovana delka BufRef^ }
    BufRefState       : tDispBufState;
    DispCursorBufPos  : Word;        { Ofset pozice kurzoru vuci pocatku znakoveho bufferu }
    ShowCursor        : Boolean;     { True - kurzor ma byt viditelny }
    NewDataToShow     : Boolean;     { True - DTick_GetDisplayData predal nova data k zobrazeni }
    ParRefresh        : Boolean;     { Param: True - povoleni obnovy displej }
    SavedParRefresh   : Boolean;     {        slouzi pro uschovu statickeho nastaveni }
    ParCursorMode     : tCursorMode; { Param: typ kurzoru }
    ParCursorChar     : Char;        { Param: znak pro kurzor pro urcity typ displej }

  {------ public methods ---------------------------------------------------------------------------}
    constructor Init(TermOwner:pATerm;CharColls,CharRows:byte;NewDispShowBufOfs:word);
    destructor  Done;                                        virtual;

{$ifdef Ver60}
    procedure SetDispParam(S:tParamStr);                     virtual; { nastaveni parametru pro displej }
    function  GetDispParam(KeyStr:tParamStr):tParamStr;      virtual; { vraci nastaveni parametru displeje }
{$endif}
{$ifdef Ver70}
    procedure SetDispParam(const S:tParamStr);               virtual; { nastaveni parametru pro displej }
    function  GetDispParam(const KeyStr:tParamStr):tParamStr;virtual; { vraci nastaveni parametru displeje }
{$endif}
    function  ResultDispParam:Boolean;                       virtual; { vrati vysl.nastav. param. displeje 0=ord(False)=O.K.}

    procedure SuspendRefresh;                { docasne potlaci provadeni Display refresh }
    procedure ReleaseRefresh;                { uvolni provadeni Display refresh }
    function  RefreshSuspended:Boolean;      { vraci stav provadeni Display refresh }

    function  GetDispBufPtr:pointer;     { vraci pointer na pocatek zobrazovane casti znakovehi bufferu }
    function  GetDispBufSize:word;       { vraci delku zobrazovane casti znakoveho bufferu }
    procedure WriteCtrlBuf(CtrlBuf:pointer;CtrlBufSize:word); { Zapis do ridici  casti bufferu }
    procedure WriteCharBuf(CharBuf:pointer;CharBufSize:word); { Zapis do znakove casti bufferu }
{$ifdef Ver60}
    procedure WriteCharBufAsStr(CharStr:string);              { Zapis do znakove casti bufferu }
{$endif}
{$ifdef Ver70}
    procedure WriteCharBufAsStr(const CharStr:string);        { Zapis do znakove casti bufferu }
{$endif}
    procedure SetCursorAttr(CX,CY:byte;NewShowCursor:Boolean);{ Nastaveni pozice a zobrazeni znakoveho kurzoru }
{$ifdef Ver60}
    procedure SetCursorAttrAsStr(CursorStr:string);           { Nastaveni kurzoru as Str  }
{$endif}
{$ifdef Ver70}
    procedure SetCursorAttrAsStr(const CursorStr:string);     { Nastaveni kurzoru as Str  }
{$endif}
    function  FillTrBufWith_CursorAttr(DestBuf:pointer;DestSize:word):word;

    procedure Tick;                          { periodicky volana z procesu terminal "Tick" }
    procedure UpDateDisplay;                 { procedura zpusobi prime zobrazeni dat na displej }
    procedure InvalidateDisplay;             { procedura zpusobi co nejrychlejsi zobrazeni dat na displej }

    procedure ShowCursorIfBlink;             { zobrazi kurzor a vynuluje casovac pro blikani kurzoru }
    procedure HideCursorIfBlink;             { ukryje kurzor a vynuluje casovac pro blikani kurzoru }

  {- protected methods -----------------------------------------------------------------------------}
    procedure DTick;                         virtual; { osetreni blikani kurzoru a vypis na displej }
    procedure DTickRefreshScr;               virtual; { vykona vypis na na displej                  }


  private { properties -----------------------------------------------------------------------------}
    LRef              : longint;     { interval automaticke refresh, refresh mozno mimo interval vyzadat pomoci RQRefresh }
    DispRefreshReq    : Boolean;     { ridi cetnost volani DTickRefreshScr z DTick - dle RTimer nebo explicitne }
    ParamErr          : Boolean;     { False=nastaveni parametru O.K. }
    DTickRunning      : Boolean;     { flag vstupu do procedury DTick - ochrana vstupu z vice procesu }
    RTimer            : tTimer;      { slouzi pro casovani DTickRefreshScr }
    CursorVisible     : Boolean;     { flag vyuzivany pro blikani kurzoru }
  end;

{=================================================================================================}
{                   A b s t r a c t    T  E  R  M  I  N  A  L                                     }
{=================================================================================================}
{ definuje virtualni rozhrani pro vsechny objekty, ktere se na objekt terminalu odkazuji          }
tATerm = object(tObject)
  Disp              : pADisp;  { object tADisp}
  Keyb              : pAKeyb;  { object tAKeyb}
  ChnTerm           : pChnVirt;{ ref_Only ! - objekt nainicializovaneho komunikacniho kanalu  }
  ChnRecBuf         : pointer; { ref_Only ! - adresa prijimaciho bufferu komunikacniho kanalu }
  ParamErr          : Boolean; { Chyba nastaveni parametru terminalu }
  EChar             : Char;    { Znak ktery se bude nahrazovat ESC }
  constructor Init(NewDisp:pADisp;NewKeyb:pAKeyb;NewChnTerm:pChnVirt;NewChnRecBuf:pointer);
  destructor Done;                                                      virtual;

{ Nastavovaci funkce terminalu }
{$ifdef Ver60}
  procedure SetTermParam(S:tParamStr);                                  virtual;{ nastaveni terminalu    }
  function  GetTermParam(KeyStr:tParamStr):tParamStr;                   virtual;{ vraci nastaveni terminalu }
{$endif}
{$ifdef Ver70}
  procedure SetTermParam(const S:tParamStr);                            virtual;{ nastaveni terminalu    }
  function  GetTermParam(const KeyStr:tParamStr):tParamStr;             virtual;{ vraci nastaveni terminalu }
{$endif}
  function  ResultTerm:Boolean;{ navrati vysl. inicializace,False=O.K.} virtual;

{ Nastavovaci funkce displej }
{$ifdef Ver60}
  procedure SetTDispParam(S:tParamStr); { nastaveni displeje }          virtual;
  function  GetTDispParam(KeyStr:tParamStr):tParamStr;                  virtual;{ navraci nastaveni displeje }
{$endif}
{$ifdef Ver70}
  procedure SetTDispParam(const S:tParamStr); { nastaveni displeje }    virtual;
  function  GetTDispParam(const KeyStr:tParamStr):tParamStr;            virtual;{ navraci nastaveni displeje }
{$endif}
  function  ResultTDispParam:Boolean;{ navrati vysledek Set..., False=O.K.} virtual;

{ Nastavovaci funkce klavesnice }
{$ifdef Ver60}
  procedure SetTKeybParam(S:tParamStr);  { nastavi klavesnici }         virtual;
  function  GetTKeybParam(KeyStr:tParamStr):tParamStr;                  virtual; { navrati nastaveni klavesnice }
{$endif}
{$ifdef Ver70}
  procedure SetTKeybParam(const S:tParamStr);  { nastavi klavesnici }   virtual;
  function  GetTKeybParam(const KeyStr:tParamStr):tParamStr;            virtual; { navrati nastaveni klavesnice }
{$endif}
  function  ResultTKeybParam:Boolean;{ navrati vysledek Set... ,False=O.K.} virtual;

{ Nastavovaci funkce komunikacniho kanalu }
{$ifdef Ver60}
  procedure SetTChnParam(S:tParamStr); { nastaveni komunikace }         virtual;
  function  GetTChnParam(KeyStr:tParamStr):tParamStr;                   virtual;{ vraci nastaveni komunikace}
{$endif}
{$ifdef Ver70}
  procedure SetTChnParam(const S:tParamStr); { nastaveni komunikace }   virtual;
  function  GetTChnParam(const KeyStr:tParamStr):tParamStr;             virtual;{ vraci nastaveni komunikace}
{$endif}
  function  ResultTChnParam:Boolean; { vraci vysledek nastaveni, False=ok}virtual;

{ ovladani klavesnice }
  procedure FlushKeyb;  { vyprazdni vyrovnavaci buffer klavesnice }     virtual;
  function  KeyPressed:Boolean;                                         virtual;
  function  ReadKey:Char;                                               virtual;
  function  ShowKey:Char;                                               virtual;
  procedure InsertKey(Key:Char);                                        virtual;
  function  KeybStatus:word;                                            virtual;

{ ovladani displeje }
  procedure Suspend_DispRefresh;                                        virtual;
  procedure Release_DispRefresh;                                        virtual;

{ ovladani doplnujicich funkci terminalu }
  procedure Beep(EvBeep:tEvBeep);                                       virtual;

{ procedura pro pocatecni zobrazeni inicializovaneho terminalu }
  procedure ShowFirstScreen;                                            virtual;
{ procedura pro pocatecni nastaveni inicializovaneho terminalu }
  procedure SetupTerminal;                                              virtual;
{ procedura ulozi do zalohovane pameti nastaveni terminalu }
  procedure StoreTerminalSetup;                                         virtual;
{ procedura obnovi ze zalohovane pameti nastaveni terminalu }
  procedure LoadTerminalSetup;                                          virtual;
{ procedura pro periodicke volani funkci terminalu }
  procedure Tick;                                                       virtual;
{ toto procedurou pozaduje Disp predani vsech dat pro zobrazeni, vraci flag novych dat }
  function  DTick_GetDisplayData:Boolean;                               virtual;
{ tato procedura je abstrakci poslani dat po komunikaci na vzdaleny terminal }
  procedure SendDataToRemoteTerm(TrBufPtr:pBuf;TrBufSize:word);         virtual;
{ tato procedure prevezme obsah prijimaciho bufferu komunikace }
  procedure ReceiveDataFromRemoteTerm(RecBufPtr:pBuf;RecBufSize:word);  virtual;
end;

{#################################################################################################}
implementation

procedure tCharWin.AssignCursorPos(cx,cy:byte);
begin
  if cx > Rect.W then X:=Rect.W else X:=cx;
  if cy > Rect.H then Y:=Rect.H else Y:=cy;
end;

{=================================================================================================}
{                   A b s t r a c t    K  E  Y  B  O  A  R  D                                     }
{=================================================================================================}
constructor tAKeyb.Init(TermOwner:pATerm;Len:word);
begin
 {$ifdef Ver60}
  tObject.Init;
 {$else}
  inherited Init;
 {$endif}
  OwnerTerm:=TermOwner;  { ref_only na terminal, ktery tento objekt displej vlastni }
  KTickRunning:=False;
  LKeybBuf:=Len;
  GetMem(KeybBuf,LKeybBuf);
 {$ifdef MRE}
  if KeybBuf=nil then RunError(203);
 {$endif}
  FillChar(KeybBuf^,LKeybBuf,0);
  UKeybBuf:=1;
  VKeybBuf:=1;
  KeybSts:=$0000;
  ParamErr:=False;
end;

destructor tAKeyb.Done;
begin
 {$ifdef Ver60}
  if KeybBuf<>nil then FreeMem(KeybBuf,LKeybBuf);
  tObject.Done;
 {$else}
  if Assigned(KeybBuf) then FreeMem(KeybBuf,LKeybBuf);
  inherited Done;
 {$endif}
end;

{$ifdef Ver60}
procedure tAKeyb.SetKeybParam(S:tParamStr);
{$endif}
{$ifdef Ver70}
procedure tAKeyb.SetKeybParam(const S:tParamStr);
{$endif}
begin
end;

{$ifdef Ver60}
function  tAKeyb.GetKeybParam(KeyStr:tParamStr):tParamStr;
{$endif}
{$ifdef Ver70}
function  tAKeyb.GetKeybParam(const KeyStr:tParamStr):tParamStr;
{$endif}
begin
  GetKeybParam:='';
end;

function tAKeyb.ResultKeybParam: Boolean;
begin
  ResultKeybParam := ParamErr;
end;


procedure tAKeyb.FlushKeyb;
begin
  UKeybBuf := 1;
  VKeybBuf := 1;
end;

{ preda neprectenou cast vyrovnavaciho bufferu }
function tAKeyb.ReadKeybBuf(DstBuf:pBuf;DstSize:word):word;
var i :integer;
begin
  i := 0;
{$ifdef Ver60}
  if DstBuf<>nil then
{$endif}
{$ifdef Ver70}
  if Assigned(DstBuf) then
{$endif}
    while (UKeybBuf<>VKeybBuf) and (DstSize>i) do
    begin
      DstBuf^[i]:=ReadKey;Inc(i);
    end;
  ReadKeybBuf:=i;
end;

function tAKeyb.KeyPressed: Boolean;
begin
  { pozor na volani z kontextu jineho procesu nez "TICK" proto pouze je/li Tick reentrantni ! }
  {=====}
   Tick;
  {=====}
  KeyPressed:=UKeybBuf<>VKeybBuf;
end;

procedure tAKeyb.IncP(var W: word);
begin
{!Ka !!!
  Inc(W);
  if W=LKeybBuf then W := 0;
}
  if (W+1)>=LKeybBuf then W := 0
  else Inc(W);
end;

function tAKeyb.ShowKey:char;
begin
  ShowKey := KeybBuf^[VKeybBuf];
end;

function tAKeyb.ReadKey:char;
begin
  ReadKey := ShowKey;
  IncP(VKeybBuf);
end;

procedure tAKeyb.InsertKey(Key: Char);
begin
  KeybBuf^[UKeybBuf] := Key;
  IncP(UKeybBuf);
end;

function tAKeyb.KeybStatus: word;
begin
  KeybStatus := KeybSts;
end;

{ procedura Tick je volana z procesu "TICK", pomoci flagu KTickRunning  je ochranen
  vicenasobny vstup do procedury KTick. Skutecnost, ze se cinnost KTick nekdy neprovede,
  nesmi byt na zavadu }
procedure tAKeyb.Tick;
begin
  asm { lock zakazem preruseni mezi testem KTickRunning a nastavenim KTickRunning }
    pushf
    cli
  end;
  if KTickRunning then { test }
  asm
    popf
  end
  else
  begin
    KTickRunning := True; { nastaveni }
    asm
      popf
    end;
   {==========================================================}
    KTick;{ do teto procedury smi vstoupit pouze jeden proces }
   {==========================================================}
    KTickRunning := False;
  end;
end;

procedure tAKeyb.KTick;
begin
  { musi dodefinovat dedic - dotaz a cteni kodu stisknutych klaves z konkretni klavesnice }
end;

const
  MaxDispColumns =  80;     { maximalni pocet sloupcu displeje }
  MaxDispRows    =  50;     { maximalni pocet radek displeje   }

constructor TCursorAttrReaderWriter.Init;
begin
 {$ifdef Ver60}
  TPropertyReaderWriter.Init;
 {$else}
  inherited Init;
 {$endif}
  A_CursorBufPos := 0;     { Ofset pozice kurzoru vuci pocatku znakoveho bufferu }
  A_ShowCursor   := False; { True - kurzor ma byt viditelny }
end;

{$ifdef Ver60}
procedure TCursorAttrReaderWriter.ReadProperty(var j:integer; S:string);
{$endif}
{$ifdef Ver70}
procedure TCursorAttrReaderWriter.ReadProperty(var j:integer;const S:string);
{$endif}
var NumVal :integer;
begin
  Err            := True;  { predpoklad ve fazi ciselnych polozek }
  A_CursorBufPos := 0;     { Ofset pozice kurzoru vuci pocatku znakoveho bufferu }
  A_ShowCursor   := False; { True - kurzor ma byt viditelny }

  if not GetNextNumber(j,S,integer(A_CursorBufPos),0,maxint) then Exit;

  while (S[j]<>',') and (j<Length(S)) do Inc(j);

  if not GetNextNumber(j,S,NumVal,0,1) then Exit;
  A_ShowCursor := NumVal<>0;

  Err :=False;
end;

procedure TCursorAttrReaderWriter.WriteProperty(DestBuf:pointer;DestSize:word);
begin
{$ifdef Ver60}
  if (DestBuf<>nil) and (DestSize>=10) then
{$endif}
{$ifdef Ver70}
  if Assigned(DestBuf) and (DestSize>=10) then
{$endif}
  begin
    string(DestBuf^) := IntegerStrDec(A_CursorBufPos,0)+','+IntegerStrDec(ord(A_ShowCursor),0);
    Err:=False;
  end
  else
    Err:=True;
end;

{=================================================================================================}
{                   A b s t r a c t    D  I  S  P  L  A  Y                                        }
{=================================================================================================}
constructor tADisp.Init(TermOwner:pATerm;CharColls,CharRows:byte;NewDispShowBufOfs:word);
begin
 {$ifdef Ver60}
  tObject.Init;
 {$else}
  inherited Init;
 {$endif}
  { polozky zadane pri inicializaci }
  OwnerTerm    :=TermOwner;
  if CharColls > MaxDispColumns
  then DispCharSizeX:=MaxDispColumns
  else DispCharSizeX:=CharColls;
  if CharRows  > MaxDispRows
  then DispCharSizeY:=MaxDispRows
  else DispCharSizeY:=CharRows;
  DispShowBufOfs := NewDispShowBufOfs;

  { polozky odvozovane }
  DispCursorBufPos  :=DispShowBufOfs;{ Ofset pozice kurzoru vuci pocatku znakoveho bufferu }
  BufRefSize        :=DispShowBufOfs+DispCharSizeX*DispCharSizeY;
  GetMem(BufRef,BufRefSize);
 {$ifdef MRE}
  if BufRef=nil then RunError(203);
 {$endif}
  FillChar(BufRef^,BufRefSize,' ');
  BufRefState       :=DispSts_Clear;

  { polozky zadavane pomoci tParamStr }
  ParRefresh      :=True;
  SavedParRefresh :=ParRefresh;
  ParCursorMode   :=CursorBlink;
  ParCursorChar   :=zCursor;

  { polozky s pocatecni implicitni hodnotou }
  ShowCursor        :=False;
  NewDataToShow     :=False;

  LRef              :=500; { perioda autoamticke refresh, resp. blikani kurzoru }
  ParamErr          :=False;

  DTickRunning      :=False;

  DispRefreshReq    :=True;
  CursorVisible     :=False;

  RTimer.Init;
  RTimer.SaveTime;

end;

destructor tADisp.Done;
begin
 {$ifdef Ver60}
  if BufRef<>nil then FreeMem(BufRef,BufRefSize);
  tObject.Done;
 {$else}
  if Assigned(BufRef) then FreeMem(BufRef,BufRefSize);
  inherited Done;
 {$endif}
end;


{$ifdef Ver60}
procedure tADisp.SetDispParam(S: tParamStr);
{$endif}
{$ifdef Ver70}
procedure tADisp.SetDispParam(const S: tParamStr);
{$endif}
const
  cOn  = 'ON';    { hodnota pro P_REF }
  cOff = 'OFF';   { hodnota pro P_REF }
type
  tParamD = (P_ERR,
             P_CCHR,  { znak pro kurzor }
             P_CMODE, { typ kurzoru }
             P_REF    { povoleni/zakaz obnovy obrazovky }
             );
const
  StrParam = 'CCH|CMO|REF|';
var
  PomS  : String[10];
  PomCh : Char;
  PomL  : longint;
  Param : tParamD;
  CmdL  : tCmd;
begin
  CmdL.InitCmd(S);
  Poms:=CmdL.ReadWord;
  ParamErr:=False;
  while (Poms<>'') and not ParamErr do
  begin
    Param:=tParamD(NDelim(Poms,StrParam));
    case Param of
      P_ERR:
        ParamErr:=True;
      P_CCHR:
        begin
          Poms:=CmdL.ReadWord;
          ParCursorChar:=PomS[1];
        end;
      P_CMODE:
        begin
          CmdL.ReadLVal(PomL,ParamErr);
          if ((PomL<ord(CursorOff))or(PomL>ord(CursorBlink)))
          then ParamErr:=True
          else if not ParamErr
               then byte(ParCursorMode):=PomL;
        end;
      P_REF:
        begin
          Poms:=CmdL.ReadWord;
          if PomS=cON  then ParRefresh:=True;
          if PomS=cOff then ParRefresh:=False;
        end;
    end; {case}
    Poms:=CmdL.ReadWord;
  end;
end;


{$ifdef Ver60}
function tADisp.GetDispParam(KeyStr:tParamStr):tParamStr;
{$endif}
{$ifdef Ver70}
function tADisp.GetDispParam(const KeyStr:tParamStr):tParamStr;
{$endif}
var  PomS  :string[10];
     ss    :tParamStr;
begin
  ss:='CCH='+ParCursorChar+' CMO=';
  Str(byte(ParCursorMode),PomS);
  ss:=ss+PomS;
  if ParRefresh=True
  then ss:=ss+' REF=ON'
  else ss:=ss+' REF=OFF';
  GetDispParam:=ss;
end;

function tADisp.ResultDispParam: Boolean;
begin
  ResultDispParam:= ParamErr;
end;

{ docasne zabrani provadeni refresh }
procedure tADisp.SuspendRefresh;
begin
  SavedParRefresh:=ParRefresh; { uschova staticke nastaveni flagu }
  ParRefresh:=False;
end;

{ uvolni provadeni refresh pokud bylo statickym parametrem povoleno }
procedure tADisp.ReleaseRefresh;
begin
  ParRefresh:=SavedParRefresh; { vrati staticke nastaveni flagu }
end;

function tADisp.RefreshSuspended:Boolean;
begin
  RefreshSuspended:=not ParRefresh;
end;

function tADisp.GetDispBufPtr:pointer;
begin
  GetDispBufPtr:=Addr(BufRef^[DispShowBufOfs]);
end;

function tADisp.GetDispBufSize:word;
begin
  GetDispBufSize:=BufRefSize-DispShowBufOfs;
end;

{ Zapis do ridici  casti bufferu }
procedure tADisp.WriteCtrlBuf(CtrlBuf:pointer;CtrlBufSize:word);
begin
  if DispShowBufOfs <= CtrlBufSize
  then begin
         Move(CtrlBuf^,BufRef^,DispShowBufOfs);
         BufRefState:=DispSts_Modified;
       end
  else begin
         FillChar(BufRef^,DispShowBufOfs,#0);
         Move(CtrlBuf^,BufRef^,CtrlBufSize);
         BufRefState:=DispSts_Modified;
       end;
end;

{ Zapis do znakove casti bufferu }
procedure tADisp.WriteCharBuf(CharBuf:pointer;CharBufSize:word);
begin
  if GetDispBufSize <= CharBufSize then
  begin
    { pokud je BufRefState = DispSts_Clear, je obsah bufferu nedefinovany
      a nema smysl porovnavat }

    if (BufRefState = DispSts_Clear) or
       (BufLComp(CharBuf,GetDispBufPtr,GetDispBufSize)<>0) then
    begin
      Move(CharBuf^,GetDispBufPtr^,GetDispBufSize);
      BufRefState:=DispSts_Modified;
    end;

  end
  else
  begin
    FillChar(GetDispBufPtr^,GetDispBufSize,' ');
    Move(CharBuf^,GetDispBufPtr^,CharBufSize);
    BufRefState:=DispSts_Modified;
  end;
end;

{$ifdef Ver60}
procedure tADisp.WriteCharBufAsStr(CharStr:string);
{$endif}
{$ifdef Ver70}
procedure tADisp.WriteCharBufAsStr(const CharStr:string);
{$endif}
begin
  if GetDispBufSize <= Length(CharStr) then
  begin
    if BufLComp(Addr(CharStr[1]),GetDispBufPtr,GetDispBufSize)<>0 then
    begin
      Move(CharStr[1],GetDispBufPtr^,GetDispBufSize);
      BufRefState:=DispSts_Modified;
    end;
  end
  else
  begin
    if (BufLComp(Addr(CharStr[1]),GetDispBufPtr,Length(CharStr))<>0)
    or (Length(CharStr)=0) then
    begin
      FillChar(GetDispBufPtr^,GetDispBufSize,' ');
      Move(CharStr[1],GetDispBufPtr^,Length(CharStr));
      BufRefState:=DispSts_Modified;
    end;
  end;
end;

{ Nastaveni pozice a zobrazeni znakoveho kurzoru }
procedure tADisp.SetCursorAttr(CX,CY:byte;NewShowCursor:Boolean);
begin
  DispCursorBufPos:=DispShowBufOfs+DispCharSizeX*(CY-1)+CX-1;
  if DispCursorBufPos >= BufRefSize then DispCursorBufPos:= BufRefSize-1;
  ShowCursor          :=NewShowCursor;
end;

{ Nastaveni kurzoru as Str  }
{$ifdef Ver60}
procedure tADisp.SetCursorAttrAsStr(CursorStr:string);
{$endif}
{$ifdef Ver70}
procedure tADisp.SetCursorAttrAsStr(const CursorStr:string);
{$endif}
var i                :integer;
    CursorAttrReader :TCursorAttrReaderWriter;
begin
  i:=1;
  CursorAttrReader.Init;
  CursorAttrReader.ReadProperty(i,CursorStr);
  if not CursorAttrReader.Err then
  with CursorAttrReader do
  begin
    DispCursorBufPos:=A_CursorBufPos;
    if DispCursorBufPos >= BufRefSize then DispCursorBufPos:= BufRefSize-1;
    ShowCursor         :=A_ShowCursor;
  end;
end;

procedure tADisp.ShowCursorIfBlink;
begin
  if ParCursorMode = CursorBlink then
  begin
    CursorVisible := True;
    RTimer.SaveTime;
  end;
end;

procedure tADisp.HideCursorIfBlink;
begin
  if ParCursorMode = CursorBlink then
  begin
    CursorVisible := False;
    RTimer.SaveTime;
  end;
end;

function  tADisp.FillTrBufWith_CursorAttr(DestBuf:pointer;DestSize:word):word;
var ResLng           :word;
    CharBufMan      :TCharBufMan;
    CursorAttrWriter :TCursorAttrReaderWriter;
    CursorAttrStr    :string[20];
begin
  ResLng:=0;
  CursorAttrStr:='';
  CursorAttrWriter.Init;
  with CursorAttrWriter do
  begin
    A_CursorBufPos:=DispCursorBufPos;
    A_ShowCursor     :=ShowCursor;
    WriteProperty(Addr(CursorAttrStr),SizeOf(CursorAttrStr));
  end;
{$ifdef Ver60}
  if (DestBuf<>nil) and (DestSize>=Length(CursorAttrStr)+4{ridici zn}) and (CursorAttrStr<>'')then
{$endif}
{$ifdef Ver70}
  if Assigned(DestBuf) and (DestSize>=Length(CursorAttrStr)+4{ridici zn}) and (CursorAttrStr<>'')then
{$endif}
  with CharBufMan do
  begin
    AssignCharBuf(DestBuf,DestSize);
    AddStrToEnd(zESC+esc_CursorBegin,ResLng); { 2 ridici znaky }
    AddStrToEnd(CursorAttrStr       ,ResLng);
    AddStrToEnd(zESC+esc_CursorEnd  ,ResLng); { 2 ridici znaky }
  end;
  FillTrBufWith_CursorAttr:=ResLng;
end;




{ procedura Tick je volana z procesu "TICK", pomoci flagu DTickRunning  je ochranen
  vicenasobny vstup do procedury DTick. Skutecnost, ze se cinnost DTick nekdy neprovede,
  nesmi byt na zavadu }
procedure tADisp.Tick;
begin
  if ParRefresh then { explicitne povoleny/zakazany refresh na displej }
  begin
    asm { lock zakazem preruseni mezi testem DTickRunning a nastavenim DTickRunning }
      pushf
      cli
    end;
    if DTickRunning
    then asm
          popf
         end
    else begin
           DTickRunning:=True; { blokovani vstupu do procedury DTick pro ostatni }
           asm
             popf
           end;
           {===========================================================}
            DTick; { do teto procedury smi vstoupit pouze jeden proces }
           {===========================================================}
           DTickRunning:=False; { uvolneni procedury DTick }
         end;
  end;
end;

{ procedura zpusobi prime zobrazeni dat na displej }
procedure tADisp.UpDateDisplay;
begin
  {$IFDEF DEB_DTICK}
  Lock;
  writelnsysout('tADisp.UpDateDisplay Entry');
  UnLock;
  {$ENDIF}
 { zde implementovano explicitni zadosti o provedeni Refresh v pristim DTick
   mimo poradi dle RTimer }
  DispRefreshReq:=True;
  {=======}
    Tick; { v protected variante mozno se pokusit zavolat prepis primo na displej }
  {=======}
  {$IFDEF DEB_DTICK}
  Lock;
  writelnsysout('tADisp.UpDateDisplay Exit');
  UnLock;
  {$ENDIF}
end;

{ procedura zpusobi co nejrychlejsi zobrazeni dat na displej }
procedure tADisp.InvalidateDisplay;
begin
 { zde implementovano explicitni zadosti o provedeni Refresh v pristim DTick
   mimo poradi dle RTimer }
  DispRefreshReq:=True;
end;


procedure tADisp.DTick;
begin
  {$IFDEF DEB_DTICK}
  Lock;
  writelnsysout('-->tADisp.DTick');
  UnLock;
  {$ENDIF}
  {-- zobrazovani kurzoru ----------}
  if RTimer.TstTime(LRef) then
  begin
    RTimer.SaveTime;
    DispRefreshReq:=True;
    case ParCursorMode of
      CursorOff  : CursorVisible:=False;      { zobrazeni kurzoru potlaceno  }
      CursorOn   : CursorVisible:=True;       { zobrazeni kurzoru trvale     }
      CursorBlink: CursorVisible:=not CursorVisible; { blikani kurzoru }
    end;
    {$IFDEF DEB_DTICK}
     Lock;
     writelnsysout('..Zmena stavu kurzoru');
     UnLock;
    {$ENDIF}
  end;
  {--------------------------------}
  { ????while protoze flRefresh muze nastavit take UpDateDisplay nebo InvalidateDisplay }
  if DispRefreshReq then
  begin
    DispRefreshReq:=False;
   {===============================================}
    DTickRefreshScr; { provedeni vlastniho refresh }
   {===============================================}
  end;
end;

procedure tADisp.DTickRefreshScr;
begin
  {$IFDEF DEB_DTICK}
  Lock;
  writelnsysout('--->tADisp.DTickRefreshScr');
  UnLock;
  {$ENDIF}
  LockKernel;
  {===== prevzeti dat jako kriticka sekce, aby byla zarucena logicka konzistence dat =====}
  {        Objekt Terminalu je pozadan o predani vsech dat pro zobrazeni na displej       }
  NewDataToShow:=pATerm(OwnerTerm)^.DTick_GetDisplayData;
  {=======================================================================================}
  UnLockKernel;
  if CursorVisible and ShowCursor           { kurzor je prave zobrazovan & ma byt viditelny }
  then begin
         {$IFDEF DEB_DTICK}
          Lock;
          writelnsysout('..Zobrazeni viditelneho kurzoru');
          UnLock;
         {$ENDIF}
         if BufRef^[DispCursorBufPos]<>ParCursorChar then
         begin
           BufRef^[DispCursorBufPos]:=ParCursorChar;
           BufRefState:=DispSts_Modified;
           NewDataToShow:=True;{ zmena kurzoru }
           {$IFDEF DEB_DTICK}
            Lock;
            writelnsysout('..Zobrazeni zmena znaku kurzoru');
            UnLock;
           {$ENDIF}
         end;
       end;

  { ............................................................................ }
  { ....... dalsi cinnost dedicu po volani teto procedury jako inherited ....... }
  { ............................................................................ }

end;



{=================================================================================================}
{                   A b s t r a c t    T  E  R  M  I  N  A  L                                     }
{=================================================================================================}
constructor tATerm.Init(NewDisp:pADisp;NewKeyb:pAKeyb;NewChnTerm:pChnVirt;NewChnRecBuf:pointer);
begin
  {$ifdef Deb_ATerminal}
  Lock;
  writelnsysout('tATerm.Init - Entry --');
  UnLock;
  {$endif}
 {$ifdef ver60}
  tObject.Init;
  Keyb := NewKeyb; if Keyb<>nil then Keyb^.OwnerTerm:=@Self;
  Disp := NewDisp; if Disp<>nil then Disp^.OwnerTerm:=@Self;
 {$else}
  inherited Init;
  Keyb := NewKeyb; if Assigned(Keyb) then Keyb^.OwnerTerm:=@Self;
  Disp := NewDisp; if Assigned(Disp) then Disp^.OwnerTerm:=@Self;
 {$endif}
  ChnTerm   := NewChnTerm;    { ref_Only ! }
  ChnRecBuf := NewChnRecBuf; { ref_Only ! }
  {$ifdef Deb_ATerminal}
  Lock;
  writelnsysout('tATerm.Init - Exit  --');
  UnLock;
  {$endif}
  EChar:=zEsc;
end;

destructor tATerm.Done;
begin
 {$ifdef Ver60}
  if Disp<>nil then Dispose(Disp,Done);
  if Keyb<>nil then Dispose(Keyb,Done);
  tObject.Done;
 {$else}
  if Assigned(Disp) then Dispose(Disp,Done);
  if Assigned(Keyb) then Dispose(Keyb,Done);
  inherited Done;
 {$endif}
end;

{$ifdef Ver60}
procedure tATerm.SetTermParam(S:tParamStr);
{$endif}
{$ifdef Ver70}
procedure tATerm.SetTermParam(const S:tParamStr);
{$endif}
type
  tParamT = (P_ERR,
             P_ECH,
             P_XXX { zatim nevyuzito }
            );

const
  StrParam = 'ECH|XXX|';
var
  PomS  : String[10];
  PomL  : longint;
  Param : tParamT;
  CmdL  : tCmd;
begin
  CmdL.InitCmd(S);
  Poms:=CmdL.ReadWord;
  ParamErr:=False;
  while (Poms<>'') and not ParamErr do
  begin
    Param:=tParamT(NDelim(Poms,StrParam));
    case Param of
      P_ERR:
        ParamErr:=True;
      P_ECH:
        begin
          PomS:=CmdL.ReadWord;
          if Length(PomS)>=1 then
            EChar:=PomS[1];
        end;
      P_XXX:
        begin
          CmdL.ReadLVal(PomL,ParamErr);
          ParamErr:=True
        end;
    end;
    Poms:=CmdL.ReadWord;
  end;
end;

{$ifdef Ver60}
function  tATerm.GetTermParam(KeyStr:tParamStr):tParamStr;
{$endif}
{$ifdef Ver70}
function  tATerm.GetTermParam(const KeyStr:tParamStr):tParamStr;
{$endif}
begin
  GetTermParam:='';
end;

function tATerm.ResultTerm:Boolean;
begin
  ResultTerm:=ParamErr;
end;


{$ifdef Ver60}
procedure tATerm.SetTDispParam(S:tParamStr);
{$endif}
{$ifdef Ver70}
procedure tATerm.SetTDispParam(const S:tParamStr);
{$endif}
begin
{$ifdef Ver60}
  if Disp<>nil then Disp^.SetDispParam(S);
{$endif}
{$ifdef Ver70}
  if Assigned(Disp) then Disp^.SetDispParam(S);
{$endif}
end;

{$ifdef Ver60}
function  tATerm.GetTDispParam(KeyStr:tParamStr):tParamStr;
{$endif}
{$ifdef Ver70}
function  tATerm.GetTDispParam(const KeyStr:tParamStr):tParamStr;
{$endif}
begin
{$ifdef Ver60}
  if Disp<>nil
{$endif}
{$ifdef Ver70}
  if Assigned(Disp)
{$endif}
  then GetTDispParam:=Disp^.GetDispParam(KeyStr)
  else GetTDispParam:='';
end;

function tATerm.ResultTDispParam:Boolean;
begin
{$ifdef Ver60}
  if Disp<>nil
{$endif}
{$ifdef Ver70}
  if Assigned(Disp)
{$endif}
  then ResultTDispParam:=Disp^.ResultDispParam
  else ResultTDispParam:=True{err};
end;

{$ifdef Ver60}
procedure tATerm.SetTKeybParam(S:tParamStr);
{$endif}
{$ifdef Ver70}
procedure tATerm.SetTKeybParam(const S:tParamStr);
{$endif}
begin
{$ifdef Ver60}
  if Keyb<>nil then Keyb^.SetKeybParam(S);
{$endif}
{$ifdef Ver70}
  if Assigned(Keyb) then Keyb^.SetKeybParam(S);
{$endif}
end;

{$ifdef Ver60}
function  tATerm.GetTKeybParam(KeyStr:tParamStr):tParamStr;
{$endif}
{$ifdef Ver70}
function  tATerm.GetTKeybParam(const KeyStr:tParamStr):tParamStr;
{$endif}
begin
{$ifdef Ver60}
  if Keyb<>nil
{$endif}
{$ifdef Ver70}
  if Assigned(Keyb)
{$endif}
  then GetTKeybParam:=Keyb^.GetKeybParam(KeyStr)
  else GetTKeybParam:='';
end;

function  tATerm.ResultTKeybParam:Boolean;
begin
{$ifdef Ver60}
  if Keyb<>nil
{$endif}
{$ifdef Ver70}
  if Assigned(Keyb)
{$endif}
  then ResultTKeybParam:=Keyb^.ResultKeybParam
  else ResultTKeybParam:=True{err};
end;

{$ifdef Ver60}
procedure tATerm.SetTChnParam(S:tParamStr);
{$endif}
{$ifdef Ver70}
procedure tATerm.SetTChnParam(const S:tParamStr);
{$endif}
begin
{$ifdef Ver60}
  if ChnTerm<>nil then ChnTerm^.ChSetParam(S);
{$endif}
{$ifdef Ver70}
  if Assigned(ChnTerm) then ChnTerm^.ChSetParam(S);
{$endif}
end;

{$ifdef Ver60}
function  tATerm.GetTChnParam(KeyStr:tParamStr):tParamStr;
{$endif}
{$ifdef Ver70}
function  tATerm.GetTChnParam(const KeyStr:tParamStr):tParamStr;
{$endif}
begin
{$ifdef Ver60}
  if ChnTerm<>nil
{$endif}
{$ifdef Ver70}
  if Assigned(ChnTerm)
{$endif}
  then GetTChnParam:=ChnTerm^.ChGetParam(KeyStr)
  else GetTChnParam:='';
end;

function  tATerm.ResultTChnParam:Boolean;
begin
{$ifdef Ver60}
  if ChnTerm<>nil
{$endif}
{$ifdef Ver70}
  if Assigned(ChnTerm)
{$endif}
  then ResultTChnParam:=(ChnTerm^.CHResult<>res_OK)
  else ResultTChnParam:=True;
end;

procedure tATerm.FlushKeyb;
begin
  Keyb^.FlushKeyb;
end;

function tATerm.KeyPressed:Boolean;
begin
  KeyPressed:=Keyb^.KeyPressed;
end;

function tATerm.ReadKey:Char;
begin
  ReadKey:=Keyb^.ReadKey;
end;

function tATerm.ShowKey:Char;
begin
  ShowKey:=Keyb^.ShowKey;
end;

procedure tATerm.InsertKey(Key:Char);
begin
  Keyb^.InsertKey(Key);
end;

function tATerm.KeybStatus:word;
begin
  KeybStatus:=Keyb^.KeybStatus;
end;

procedure tATerm.Suspend_DispRefresh;
begin
  Disp^.SuspendRefresh;
end;

procedure tATerm.Release_DispRefresh;
begin
  Disp^.ReleaseRefresh;
end;

procedure tATerm.Beep(EvBeep:tEvBeep);
begin
  { Abstract }
end;

{ procedura pro pocatecni zobrazeni inicializovaneho terminalu }
procedure tATerm.ShowFirstScreen;
begin
  { Abstract }
end;

{ procedura pro pocatecni nastaveni inicializovaneho terminalu }
procedure tATerm.SetupTerminal;
begin
  { Abstract }
end;

{ procedura ulozi do zalohovane pameti nastaveni terminalu }
procedure tATerm.StoreTerminalSetup;
begin
  { Abstract }
end;

{ procedura obnovi ze zalohovane pameti nastaveni terminalu }
procedure tATerm.LoadTerminalSetup;
begin
  { Abstract }
end;

{ procedura pro periodicke volani funkci terminalu }
procedure tATerm.Tick;
begin
  { Abstract }
end;

{ toto procedurou pozaduje Disp predani vsech dat pro zobrazeni, vraci flag novych dat }
function tATerm.DTick_GetDisplayData:Boolean;
begin
  DTick_GetDisplayData:=False;{tj. nemam nova data k zobrazeni }
  { Abstract }
end;

{ tato procedura je abstrakci poslani dat po komunikaci na vzdaleny terminal }
procedure tATerm.SendDataToRemoteTerm(TrBufPtr:pBuf;TrBufSize:word);
begin
  { Abstract }
end;

{ tato procedure prevezme obsah prijimaciho bufferu komunikace }
procedure tATerm.ReceiveDataFromRemoteTerm(RecBufPtr:pBuf;RecBufSize:word);
begin
  { Abstract }
end;

end.
