Annotation of sbbs/sbbs3/ctrl/emulvt.pas, revision 1.1

1.1     ! root        1: {*_* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
        !             2: 
        !             3: Program:      EMULVT.PAS
        !             4: Description:  Delphi component which does Ansi terminal emulation
        !             5:               Not every escape sequence is implemented, but a large subset.
        !             6: Author:       Fran�ois PIETTE
        !             7: EMail:        http://users.swing.be/francois.piette  [email protected]
        !             8:               http://www.rtfm.be/fpiette             [email protected]
        !             9:               [email protected]
        !            10: Creation:     May, 1996
        !            11: Version:      2.16
        !            12: Support:      Use the mailing list [email protected] See website for details.
        !            13: Legal issues: Copyright (C) 1997-2000 by Fran�ois PIETTE
        !            14:               Rue de Grady 24, 4053 Embourg, Belgium. Fax: +32-4-365.74.56
        !            15:               <[email protected]>
        !            16: 
        !            17:               This software is provided 'as-is', without any express or
        !            18:               implied warranty.  In no event will the author be held liable
        !            19:               for any  damages arising from the use of this software.
        !            20: 
        !            21:               Permission is granted to anyone to use this software for any
        !            22:               purpose, including commercial applications, and to alter it
        !            23:               and redistribute it freely, subject to the following
        !            24:               restrictions:
        !            25: 
        !            26:               1. The origin of this software must not be misrepresented,
        !            27:                  you must not claim that you wrote the original software.
        !            28:                  If you use this software in a product, an acknowledgment
        !            29:                  in the product documentation would be appreciated but is
        !            30:                  not required.
        !            31: 
        !            32:               2. Altered source versions must be plainly marked as such, and
        !            33:                  must not be misrepresented as being the original software.
        !            34: 
        !            35:               3. This notice may not be removed or altered from any source
        !            36:                  distribution.
        !            37: 
        !            38:               4. You must register this software by sending a picture postcard
        !            39:                  to the author. Use a nice stamp and mention your name, street
        !            40:                  address, EMail address and any comment you like to say.
        !            41: 
        !            42: Updates:
        !            43: Jul 22, 1997  Some optimization
        !            44:               Adapted to Delphi 3
        !            45: Sep 05, 1997  Version 2.01
        !            46: Dec 16, 1997  V2.02 Corrected a bug int the paint routine which caused GDI
        !            47:                     resource leak when color was used.
        !            48: Feb 24, 1998  V2.03 Added AddFKey function
        !            49: Jul 15, 1998  V2.04 Adapted to Delphi 4 (moved DoKeyBuffer to protected section)
        !            50: Dec 04, 1998  V2.05 Added 'single char paint' and 'char zoom' features.
        !            51: Dec 09, 1998  V2.10 Added graphic char drawing using graphic primitives
        !            52:                     Added (with permission) scroll back code developed by Steve
        !            53:                     Endicott <[email protected]>
        !            54: Dec 21, 1998  V2.11 Corrected some screen update problems related to scrollback.
        !            55:                     Added fixes from Steve Endicott.
        !            56:                     Beautified code.
        !            57: Mar 14, 1999  V2.12 Added OnKeyDown event.
        !            58:                     Corrected a missing band at right of screen when painting.
        !            59: Aug 15, 1999  V2.13 Moved KeyPress procedure to public section for BCB4 compat.
        !            60: Aug 20, 1999  V2.14 Added compile time options. Revised for BCB4.
        !            61: Nov 12, 1999  V2.15 Corrected display attribute error in delete line.
        !            62:                     Checked for range in SetLines/GetLine
        !            63: Aug 09, 2000  V2.16 Wilfried Mestdagh" <[email protected]> and
        !            64:                     Steve Endicott <[email protected]> corrected a
        !            65:                     bug related to scroll back buffer. See WM + SE 09/08/00
        !            66:                     tags in code.
        !            67: 
        !            68:  * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *}
        !            69: unit Emulvt;
        !            70: 
        !            71: {$B-}           { Enable partial boolean evaluation   }
        !            72: {$T-}           { Untyped pointers                    }
        !            73: {$X+}           { Enable extended syntax              }
        !            74: {$IFNDEF VER80} { Not for Delphi 1                    }
        !            75:     {$H+}       { Use long strings                    }
        !            76:     {$J+}       { Allow typed constant to be modified }
        !            77: {$ENDIF}
        !            78: {$IFDEF VER110} { C++ Builder V3.0                    }
        !            79:     {$ObjExportAll On}
        !            80: {$ENDIF}
        !            81: {$IFDEF VER125} { C++ Builder V4.0                    }
        !            82:     {$ObjExportAll On}
        !            83: {$ENDIF}
        !            84: 
        !            85: interface
        !            86: 
        !            87: {$DEFINE SINGLE_CHAR_PAINT}
        !            88: {$DEFINE CHAR_ZOOM}
        !            89: 
        !            90: uses
        !            91:   SysUtils, WinTypes, WinProcs, Messages, Classes, Graphics, Controls,
        !            92:   Forms, Dialogs, StdCtrls, ClipBrd;
        !            93: 
        !            94: const
        !            95:   EmulVTVersion      = 216;
        !            96:   CopyRight : String = ' TEmulVT (c) 1996-2000 F. Piette V2.16 ';
        !            97:   MAX_ROW            = 50; 
        !            98:   MAX_COL            = 132;
        !            99:   TopMargin          = 4;
        !           100:   LeftMargin         = 6;
        !           101:   RightMargin        = 6;
        !           102:   BottomMargin       = 4;
        !           103:   NumPaletteEntries  = 16;
        !           104: 
        !           105: type
        !           106:   TBackColors     = (vtsBlack, vtsRed,     vtsGreen, vtsYellow,
        !           107:                      vtsBlue,  vtsMagenta, vtsCyan,  vtsWhite);
        !           108: 
        !           109:   TScreenOption   = (vtoBackColor, vtoCopyBackOnClear);
        !           110:   TScreenOptions  = set of TScreenOption;
        !           111:   TXlatTable      = array [0..255] of char;
        !           112:   PXlatTable      = ^TXlatTable;
        !           113:   TFuncKeyValue   = String[50];
        !           114:   PFuncKeyValue   = ^TFuncKeyValue;
        !           115:   TFuncKey        = record
        !           116:                         ScanCode : Char;
        !           117:                         Shift    : TShiftState;
        !           118:                         Ext      : Boolean;
        !           119:                         Value    : TFuncKeyValue;
        !           120:                     end;
        !           121:   TFuncKeysTable  = array [0..63] of TFuncKey;
        !           122:   PFuncKeysTable  = ^TFuncKeysTable;
        !           123:   TKeyBufferEvent = procedure (Sender : TObject; Buffer : PChar; Len : Integer) of object;
        !           124:   TKeyDownEvent   = procedure (Sender        : TObject;
        !           125:                                var VirtKey   : Integer;
        !           126:                                var Shift     : TShiftState;
        !           127:                                var ShiftLock : Boolean;
        !           128:                                var ScanCode  : Char;
        !           129:                                var Ext       : Boolean) of object;
        !           130: 
        !           131: 
        !           132: type
        !           133:   { TLine is an object used to hold one line of text on screen }
        !           134:   TLine = class(TObject)
        !           135:   public
        !           136:     Txt : array [0..MAX_COL] of Char;
        !           137:     Att : array [0..MAX_COL] of Byte;
        !           138:     constructor Create;
        !           139:     procedure   Clear(Attr : Byte);
        !           140:   end;
        !           141:   TLineArray      = array [0..16382] of TLine;
        !           142:   PLineArray      = ^TLineArray;
        !           143: 
        !           144:   { TScreen is an object to hold an entire screen of line and handle }
        !           145:   { Ansi escape sequences to update this virtual screen              }
        !           146:   TScreen = class(TObject)
        !           147:   public
        !           148:     FLines           : PLineArray;
        !           149:     FRow             : Integer;
        !           150:     FCol             : Integer;
        !           151:     FRowSaved        : Integer;
        !           152:     FColSaved        : Integer;
        !           153:     FScrollRowTop    : Integer;
        !           154:     FScrollRowBottom : Integer;
        !           155:     FAttribute       : Byte;
        !           156:     FForceHighBit    : Boolean;
        !           157:     FReverseVideo    : Boolean;
        !           158:     FUnderLine       : Boolean;
        !           159:     FRowCount        : Integer;
        !           160:     FColCount        : Integer;
        !           161:     FBackRowCount    : Integer;
        !           162:     FBackEndRow      : Integer;
        !           163:     FBackColor       : TBackColors;
        !           164:     FOptions         : TScreenOptions;
        !           165:     FEscBuffer       : String[80];
        !           166:     FEscFlag         : Boolean;
        !           167:     Focused          : Boolean;
        !           168:     FAutoLF          : Boolean;
        !           169:     FAutoCR          : Boolean;
        !           170:     FAutoWrap        : Boolean;
        !           171:     FCursorOff       : Boolean;
        !           172:     FCKeyMode        : Boolean;
        !           173:     FNoXlat          : Boolean;
        !           174:     FNoXlatInitial   : Boolean;
        !           175:     FCntLiteral      : Integer;
        !           176:     FCarbonMode      : Boolean;
        !           177:     FXlatInputTable  : PXlatTable;
        !           178:     FXlatOutputTable : PXlatTable;
        !           179:     FCharSetG0       : Char;
        !           180:     FCharSetG1       : Char;
        !           181:     FCharSetG2       : Char;
        !           182:     FCharSetG3       : Char;
        !           183:     FAllInvalid      : Boolean;
        !           184:     FInvRect         : TRect;
        !           185:     FOnCursorVisible : TNotifyEvent;
        !           186:     constructor Create;
        !           187:     destructor  Destroy; override;
        !           188:     procedure   AdjustFLines(NewCount : Integer);
        !           189:     procedure   CopyScreenToBack;
        !           190:     procedure   SetRowCount(NewCount : Integer);
        !           191:     procedure   SetBackRowCount(NewCount : Integer);
        !           192:     procedure   InvRect(nRow, nCol : Integer);
        !           193:     procedure   InvClear;
        !           194:     procedure   SetLines(I : Integer; Value : TLine);
        !           195:     function    GetLines(I : Integer) : TLine;
        !           196:     procedure   WriteChar(Ch : Char);
        !           197:     procedure   WriteStr(Str : String);
        !           198:     function    ReadStr : String;
        !           199:     procedure   GotoXY(X, Y : Integer);
        !           200:     procedure   WriteLiteralChar(Ch : Char);
        !           201:     procedure   ProcessEscape(EscCmd : Char);
        !           202:     procedure   SetAttr(Att : Char);
        !           203:     procedure   CursorRight;
        !           204:     procedure   CursorLeft;
        !           205:     procedure   CursorDown;
        !           206:     procedure   CursorUp;
        !           207:     procedure   CarriageReturn;
        !           208:     procedure   ScrollUp;
        !           209:     procedure   ScrollDown;
        !           210:     procedure   ClearScreen;
        !           211:     procedure   BackSpace;
        !           212:     procedure   Eol;
        !           213:     procedure   Eop;
        !           214:     procedure   ProcessESC_D;                { Index                   }
        !           215:     procedure   ProcessESC_M;                { Reverse index           }
        !           216:     procedure   ProcessESC_E;                { Next line               }
        !           217:     procedure   ProcessCSI_u;                { Restore Cursor          }
        !           218:     procedure   ProcessCSI_I;                { Select IBM char set     }
        !           219:     procedure   ProcessCSI_J;                { Clear the screen        }
        !           220:     procedure   ProcessCSI_K;                { Erase to End of Line    }
        !           221:     procedure   ProcessCSI_L;                { Insert Line             }
        !           222:     procedure   ProcessCSI_M;                { Delete Line             }
        !           223:     procedure   ProcessCSI_m_lc;             { Select Attributes       }
        !           224:     procedure   ProcessCSI_n_lc;             { Cursor position report  }
        !           225:     procedure   ProcessCSI_at;               { Insert character        }
        !           226:     procedure   ProcessCSI_r_lc;             { Scrolling margins       }
        !           227:     procedure   ProcessCSI_s_lc;             { Save cursor location    }
        !           228:     procedure   ProcessCSI_u_lc;             { Restore cursor location }
        !           229:     procedure   ProcessCSI_7;                { Save cursor location    }
        !           230:     procedure   ProcessCSI_8;                { Restore cursor location }
        !           231:     procedure   ProcessCSI_H;                { Set Cursor Position     }
        !           232:     procedure   ProcessCSI_h_lc;             { Terminal mode set       }
        !           233:     procedure   ProcessCSI_l_lc;             { Terminal mode reset     }
        !           234:     procedure   ProcessCSI_A;                { Cursor Up               }
        !           235:     procedure   ProcessCSI_B;                { Cursor Down             }
        !           236:     procedure   ProcessCSI_C;                { Cursor Right            }
        !           237:     procedure   ProcessCSI_D;                { Cursor Left             }
        !           238:     procedure   ProcessCSI_P;                { Delete Character        }
        !           239:     procedure   ProcessCSI_S;                { Scroll up               }
        !           240:     procedure   ProcessCSI_T;                { Scroll down             }
        !           241:     procedure   process_charset_G0(EscCmd : Char);{ G0 character set   }
        !           242:     procedure   process_charset_G1(EscCmd : Char);{ G1 character set   }
        !           243:     procedure   process_charset_G2(EscCmd : Char);{ G2 character set   }
        !           244:     procedure   process_charset_G3(EscCmd : Char);{ G3 character set   }
        !           245:     procedure   UnimplementedEscape(EscCmd : Char);
        !           246:     procedure   InvalidEscape(EscCmd : Char);
        !           247:     function    GetEscapeParam(From : Integer; var Value : Integer) : Integer;
        !           248:     property    OnCursorVisible : TNotifyEvent read  FonCursorVisible
        !           249:                                                write FOnCursorVisible;
        !           250:     property    Lines[I : Integer] : TLine read GetLines write SetLines;
        !           251:   end;
        !           252: 
        !           253:   { TCustomEmulVT is an visual component wich does the actual display }
        !           254:   { of a TScreen object wich is the virtual screen                    }
        !           255:   { No property is published. See TEmulVT class                       }
        !           256:   TCustomEmulVT = class(TCustomControl)
        !           257:   private
        !           258:     FScreen          : TScreen;
        !           259:     FFileHandle      : TextFile;
        !           260:     FCursorVisible   : Boolean;
        !           261:     FCaretShown      : Boolean;
        !           262:     FCaretCreated    : Boolean;
        !           263:     FLineHeight      : Integer;
        !           264:     FLineZoom        : Single;
        !           265:     FCharWidth       : Integer;
        !           266:     FCharZoom        : Single;
        !           267:     FGraphicDraw     : Boolean;
        !           268:     FInternalLeading : Integer;
        !           269:     FBorderStyle     : TBorderStyle;
        !           270:     FBorderWidth     : Integer;
        !           271:     FAutoRepaint     : Boolean;
        !           272:     FFont            : TFont;
        !           273:     FVScrollBar      : TScrollBar;
        !           274:     FTopLine         : Integer;
        !           275:     FLocalEcho       : Boolean;
        !           276:     FOnKeyBuffer     : TKeyBufferEvent;
        !           277:     FOnKeyDown       : TKeyDownEvent;
        !           278:     FFKeys           : Integer;
        !           279:     FMonoChrome      : Boolean;
        !           280:     FLog             : Boolean;
        !           281:     FAppOnMessage    : TMessageEvent;
        !           282:     FFlagCirconflexe : Boolean;
        !           283:     FFlagTrema       : Boolean;
        !           284:     FSelectRect      : TRect;
        !           285:     FPal             : HPalette;
        !           286:     FPaletteEntries  : array[0..NumPaletteEntries - 1] of TPaletteEntry;
        !           287:     procedure   WMPaint(var Message: TWMPaint); message WM_PAINT;
        !           288:     procedure   WMSetFocus(var Message: TWMSetFocus); message WM_SETFOCUS;
        !           289:     procedure   WMKillFocus(var Message: TWMKillFocus); message WM_KILLFOCUS;
        !           290:     procedure   WMLButtonDown(var Message: TWMLButtonDown); message WM_LBUTTONDOWN;
        !           291:     procedure   WMPaletteChanged(var Message : TMessage); message WM_PALETTECHANGED;
        !           292:     procedure   VScrollBarScroll(Sender: TObject; ScrollCode: TScrollCode; var ScrollPos: Integer);
        !           293:     procedure   SetCaret;
        !           294:     procedure   AdjustScrollBar;
        !           295:     function    ProcessFKeys(ScanCode: Char; Shift: TShiftState; Ext: Boolean) : Boolean;
        !           296:     function    FindFKeys(ScanCode: Char; Shift: TShiftState;
        !           297:                           Ext: Boolean) : PFuncKeyValue;
        !           298:     procedure   CursorVisibleEvent(Sender : TObject);
        !           299:     procedure   SetFont(Value : TFont);
        !           300:     procedure   SetAutoLF(Value : Boolean);
        !           301:     procedure   SetAutoCR(Value : Boolean);
        !           302:     procedure   SetXlat(Value : Boolean);
        !           303:     procedure   SetLog(Value : Boolean);
        !           304:     procedure   SetRows(Value : Integer);
        !           305:     procedure   SetCols(Value : Integer);
        !           306:     procedure   SetBackRows(Value : Integer);
        !           307:     procedure   SetTopLine(Value : Integer);
        !           308:     procedure   SetBackColor(Value : TBackColors);
        !           309:     procedure   SetOptions(Value : TScreenOptions);
        !           310:     procedure   SetLineHeight(Value : Integer);
        !           311:     function    GetAutoLF : Boolean;
        !           312:     function    GetAutoCR : Boolean;
        !           313:     function    GetXlat : Boolean;
        !           314:     function    GetRows : Integer;
        !           315:     function    GetCols : Integer;
        !           316:     function    GetBackRows : Integer;
        !           317:     function    GetBackColor : TBackColors;
        !           318:     function    GetOptions : TScreenOptions;
        !           319:   protected
        !           320:     procedure   AppMessageHandler(var Msg: TMsg; var Handled: Boolean);
        !           321:     procedure   DoKeyBuffer(Buffer : PChar; Len : Integer); virtual;
        !           322:     procedure   PaintGraphicChar(DC   : HDC;
        !           323:                                  X, Y : Integer;
        !           324:                                  rc   : PRect;
        !           325:                                  ch   : Char);
        !           326:   public
        !           327:     constructor Create(AOwner: TComponent); override;
        !           328:     destructor  Destroy; override;
        !           329:     procedure   ShowCursor;
        !           330:     procedure   SetCursor(Row, Col : Integer);
        !           331:     procedure   WriteChar(Ch : Char);
        !           332:     procedure   WriteStr(Str : String);
        !           333:     procedure   WriteBuffer(Buffer : Pointer; Len : Integer);
        !           334:     function    ReadStr : String;
        !           335:     procedure   CopyHostScreen;
        !           336:     procedure   Clear;
        !           337:     procedure   UpdateScreen;
        !           338:     function    SnapPixelToRow(Y : Integer) : Integer;
        !           339:     function    SnapPixelToCol(X : Integer) : Integer;
        !           340:     function    PixelToRow(Y : Integer) : Integer;
        !           341:     function    PixelToCol(X : Integer) : Integer;
        !           342:     procedure   MouseToCell(X, Y: Integer; var ACol, ARow: Longint);
        !           343:     procedure   SetLineZoom(newValue : Single);
        !           344:     procedure   SetCharWidth(newValue : Integer);
        !           345:     procedure   SetCharZoom(newValue : Single);
        !           346:     procedure   KeyPress(var Key: Char); override;
        !           347:     property    LineZoom  : Single        read FLineZoom    write SetLineZoom;
        !           348:     property    CharWidth : Integer       read FCharWidth   write SetCharWidth;
        !           349:     property    CharZoom  : Single        read FCharZoom    write SetCharZoom;
        !           350:     property    GraphicDraw : Boolean     read FGraphicDraw write FGraphicDraw;
        !           351:     property    TopLine     : Integer     read FTopLine     write SetTopLine;
        !           352:     property    VScrollBar  : TScrollBar  read FVScrollBar;
        !           353:   private
        !           354:     procedure   PaintOneLine(DC: HDC; Y, Y1 : Integer; const Line : TLine;
        !           355:                              nColFrom : Integer; nColTo : Integer);
        !           356:     procedure   SetupFont;
        !           357:     property Text : String read ReadStr write WriteStr;
        !           358:     property OnMouseMove;
        !           359:     property OnMouseDown;
        !           360:     property OnMouseUp;
        !           361:     property OnClick;
        !           362:     property OnKeyPress;
        !           363:     property OnKeyBuffer : TKeyBufferEvent read FOnKeyBuffer write FOnKeyBuffer;
        !           364:     property OnKeyDown   : TKeyDownEvent   read FOnKeyDown   write FOnKeyDown;
        !           365:     property Ctl3D;
        !           366:     property Align;
        !           367:     property TabStop;
        !           368:     property TabOrder;
        !           369:     property BorderStyle: TBorderStyle read FBorderStyle write FBorderStyle;
        !           370:     property AutoRepaint : Boolean     read FAutoRepaint write FAutoRepaint;
        !           371:     property Font : TFont              read FFont        write SetFont;
        !           372:     property LocalEcho : Boolean       read FLocalEcho   write FLocalEcho;
        !           373:     property AutoLF : Boolean          read GetAutoLF    write SetAutoLF;
        !           374:     property AutoCR : Boolean          read GetAutoCR    write SetAutoCR;
        !           375:     property Xlat : Boolean            read GetXlat      write SetXlat;
        !           376:     property MonoChrome : Boolean      read FMonoChrome  write FMonoChrome;
        !           377:     property Log : Boolean             read FLog         write SetLog;
        !           378:     property Rows : Integer            read GetRows      write SetRows;
        !           379:     property Cols : Integer            read GetCols      write SetCols;
        !           380:     property LineHeight : Integer      read FLineHeight  write SetLineHeight;
        !           381:     property FKeys : Integer           read FFKeys       write FFKeys;
        !           382:     property SelectRect : TRect        read FSelectRect  write FSelectRect;
        !           383:     property BackRows : Integer        read GetBackRows  write SetBackRows;
        !           384:     property BackColor : TBackColors   read GetBackColor write SetBackColor;
        !           385:     property Options : TScreenOptions  read GetOptions   write SetOptions;
        !           386:   end;
        !           387: 
        !           388:   { Same as TCustomEmulVT, but with published properties }
        !           389:   TEmulVT = class(TCustomEmulVT)
        !           390:   public
        !           391:     property Screen : TScreen read FScreen;
        !           392:     property SelectRect;
        !           393:     property Text;
        !           394:   published
        !           395:     property OnMouseMove;
        !           396:     property OnMouseDown;
        !           397:     property OnMouseUp;
        !           398:     property OnClick;
        !           399:     property OnKeyPress;
        !           400:     property OnKeyDown;
        !           401:     property OnKeyBuffer;
        !           402:     property Ctl3D;
        !           403:     property Align;
        !           404:     property BorderStyle;
        !           405:     property AutoRepaint;
        !           406:     property Font;
        !           407:     property LocalEcho;
        !           408:     property AutoLF;
        !           409:     property AutoCR;
        !           410:     property Xlat;
        !           411:     property MonoChrome;
        !           412:     property Log;
        !           413:     property Rows;
        !           414:     property Cols;
        !           415:     property BackRows;
        !           416:     property BackColor;
        !           417:     property Options;
        !           418:     property LineHeight;
        !           419:     property CharWidth;
        !           420:     property TabStop;
        !           421:     property TabOrder;
        !           422:     property FKeys;
        !           423:   end;
        !           424: 
        !           425: const
        !           426:   F_BLACK   = $00;
        !           427:   F_BLUE    = $01;
        !           428:   F_GREEN   = $02;
        !           429:   F_CYAN    = $03;
        !           430:   F_RED     = $04;
        !           431:   F_MAGENTA = $05;
        !           432:   F_BROWN   = $06;
        !           433:   F_WHITE   = $07;
        !           434: 
        !           435:   B_BLACK   = $00;
        !           436:   B_BLUE    = $01;
        !           437:   B_GREEN   = $02;
        !           438:   B_CYAN    = $03;
        !           439:   B_RED     = $04;
        !           440:   B_MAGENTA = $05;
        !           441:   B_BROWN   = $06;
        !           442:   B_WHITE   = $07;
        !           443: 
        !           444:   F_INTENSE = $08;
        !           445:   B_BLINK   = $80;
        !           446: 
        !           447:   { Function keys (SCO Console) }
        !           448:   FKeys1 : TFuncKeysTable = (
        !           449:       (ScanCode: #$48; Shift: []; Ext: TRUE ; Value: #$1B + '[A'),   { UP    }
        !           450:       (ScanCode: #$50; Shift: []; Ext: TRUE ; Value: #$1B + '[B'),   { DOWN  }
        !           451:       (ScanCode: #$4D; Shift: []; Ext: TRUE ; Value: #$1B + '[C'),   { RIGHT }
        !           452:       (ScanCode: #$4B; Shift: []; Ext: TRUE ; Value: #$1B + '[D'),   { LEFT  }
        !           453:       (ScanCode: #$49; Shift: []; Ext: TRUE ; Value: #$1B + '[I'),   { PREV  }
        !           454:       (ScanCode: #$51; Shift: []; Ext: TRUE ; Value: #$1B + '[G'),   { NEXT  }
        !           455:       (ScanCode: #$47; Shift: []; Ext: TRUE ; Value: #$1B + '[H'),   { HOME  }
        !           456:       (ScanCode: #$4F; Shift: []; Ext: TRUE ; Value: #$1B + '[F'),   { END   }
        !           457:       (ScanCode: #$52; Shift: []; Ext: TRUE ; Value: #$1B + '[L'),   { INS   }
        !           458:       (ScanCode: #$0F; Shift: []; Ext: FALSE; Value: #$1B + '[Z'),   { RTAB  }
        !           459:       (ScanCode: #$53; Shift: []; Ext: TRUE ; Value: #$7F       ),   { DEL   }
        !           460:       (ScanCode: #$3B; Shift: []; Ext: FALSE; Value: #$1B + '[M'),   { F1    }
        !           461:       (ScanCode: #$3C; Shift: []; Ext: FALSE; Value: #$1B + '[N'),
        !           462:       (ScanCode: #$3D; Shift: []; Ext: FALSE; Value: #$1B + '[O'),
        !           463:       (ScanCode: #$3E; Shift: []; Ext: FALSE; Value: #$1B + '[P'),
        !           464:       (ScanCode: #$3F; Shift: []; Ext: FALSE; Value: #$1B + '[Q'),
        !           465:       (ScanCode: #$40; Shift: []; Ext: FALSE; Value: #$1B + '[R'),
        !           466:       (ScanCode: #$41; Shift: []; Ext: FALSE; Value: #$1B + '[S'),
        !           467:       (ScanCode: #$42; Shift: []; Ext: FALSE; Value: #$1B + '[T'),
        !           468:       (ScanCode: #$43; Shift: []; Ext: FALSE; Value: #$1B + '[U'),
        !           469:       (ScanCode: #$44; Shift: []; Ext: FALSE; Value: #$1B + '[V'),   { F10   }
        !           470:       (ScanCode: #$85; Shift: []; Ext: FALSE; Value: #$1B + '[W'),   { F11   }
        !           471:       (ScanCode: #$86; Shift: []; Ext: FALSE; Value: #$1B + '[X'),   { F12   }
        !           472:       (ScanCode: #$3B; Shift: [ssShift]; Ext: FALSE; Value: #$1B + '[V'),{ SF1 should be 'Y' }
        !           473:       (ScanCode: #$3C; Shift: [ssShift]; Ext: FALSE; Value: #$1B + '[Z'),
        !           474:       (ScanCode: #$3D; Shift: [ssShift]; Ext: FALSE; Value: #$1B + '[a'),
        !           475:       (ScanCode: #$3E; Shift: [ssShift]; Ext: FALSE; Value: #$1B + '[b'),
        !           476:       (ScanCode: #$3F; Shift: [ssShift]; Ext: FALSE; Value: #$1B + '[c'),
        !           477:       (ScanCode: #$40; Shift: [ssShift]; Ext: FALSE; Value: #$1B + '[d'),
        !           478:       (ScanCode: #$41; Shift: [ssShift]; Ext: FALSE; Value: #$1B + '[e'),
        !           479:       (ScanCode: #$42; Shift: [ssShift]; Ext: FALSE; Value: #$1B + '[f'),
        !           480:       (ScanCode: #$43; Shift: [ssShift]; Ext: FALSE; Value: #$1B + '[g'),
        !           481:       (ScanCode: #$44; Shift: [ssShift]; Ext: FALSE; Value: #$1B + '[h'),
        !           482:       (ScanCode: #$85; Shift: [ssShift]; Ext: FALSE; Value: #$1B + '[i'),
        !           483:       (ScanCode: #$86; Shift: [ssShift]; Ext: FALSE; Value: #$1B + '[j'),{ SF10 }
        !           484:       (ScanCode: #$3B; Shift: [ssCtrl]; Ext: FALSE; Value: #$1B + '[k'), { CF1  }
        !           485:       (ScanCode: #$3C; Shift: [ssCtrl]; Ext: FALSE; Value: #$1B + '[l'),
        !           486:       (ScanCode: #$3D; Shift: [ssCtrl]; Ext: FALSE; Value: #$1B + '[m'),
        !           487:       (ScanCode: #$3E; Shift: [ssCtrl]; Ext: FALSE; Value: #$1B + '[n'),
        !           488:       (ScanCode: #$3F; Shift: [ssCtrl]; Ext: FALSE; Value: #$1B + '[o'),
        !           489:       (ScanCode: #$40; Shift: [ssCtrl]; Ext: FALSE; Value: #$1B + '[p'),
        !           490:       (ScanCode: #$41; Shift: [ssCtrl]; Ext: FALSE; Value: #$1B + '[q'),
        !           491:       (ScanCode: #$42; Shift: [ssCtrl]; Ext: FALSE; Value: #$1B + '[r'),
        !           492:       (ScanCode: #$43; Shift: [ssCtrl]; Ext: FALSE; Value: #$1B + '[s'),
        !           493:       (ScanCode: #$44; Shift: [ssCtrl]; Ext: FALSE; Value: #$1B + '[t'),
        !           494:       (ScanCode: #$85; Shift: [ssCtrl]; Ext: FALSE; Value: #$1B + '[u'),
        !           495:       (ScanCode: #$86; Shift: [ssCtrl]; Ext: FALSE; Value: #$1B + '[v'),   { CF12 }
        !           496:       (ScanCode: #$00; Shift: []; Ext: FALSE; Value: ''         ),
        !           497:       (ScanCode: #$00; Shift: []; Ext: FALSE; Value: ''         ),
        !           498:       (ScanCode: #$00; Shift: []; Ext: FALSE; Value: ''         ),
        !           499:       (ScanCode: #$00; Shift: []; Ext: FALSE; Value: ''         ),
        !           500:       (ScanCode: #$00; Shift: []; Ext: FALSE; Value: ''         ),
        !           501:       (ScanCode: #$00; Shift: []; Ext: FALSE; Value: ''         ),
        !           502:       (ScanCode: #$00; Shift: []; Ext: FALSE; Value: ''         ),
        !           503:       (ScanCode: #$00; Shift: []; Ext: FALSE; Value: ''         ),
        !           504:       (ScanCode: #$00; Shift: []; Ext: FALSE; Value: ''         ),
        !           505:       (ScanCode: #$00; Shift: []; Ext: FALSE; Value: ''         ),
        !           506:       (ScanCode: #$00; Shift: []; Ext: FALSE; Value: ''         ),
        !           507:       (ScanCode: #$00; Shift: []; Ext: FALSE; Value: ''         ),
        !           508:       (ScanCode: #$00; Shift: []; Ext: FALSE; Value: ''         ),
        !           509:       (ScanCode: #$00; Shift: []; Ext: FALSE; Value: ''         ),
        !           510:       (ScanCode: #$00; Shift: []; Ext: FALSE; Value: ''         ),
        !           511:       (ScanCode: #$00; Shift: []; Ext: FALSE; Value: ''         ),
        !           512:       (ScanCode: #$00; Shift: []; Ext: FALSE; Value: ''         )
        !           513:       );
        !           514: 
        !           515: { Alternate function keys (ordinary VT keys) }
        !           516:   FKeys2 : TFuncKeysTable = (
        !           517:       (ScanCode: #$48; Shift: []; Ext: TRUE ; Value: #$1B + '[A'),   { UP      }
        !           518:       (ScanCode: #$50; Shift: []; Ext: TRUE ; Value: #$1B + '[B'),   { DOWN    }
        !           519:       (ScanCode: #$4D; Shift: []; Ext: TRUE ; Value: #$1B + '[C'),   { RIGHT   }
        !           520:       (ScanCode: #$4B; Shift: []; Ext: TRUE ; Value: #$1B + '[D'),   { LEFT    }
        !           521:       (ScanCode: #$49; Shift: []; Ext: TRUE ; Value: #$1B + '[5~'),  { PREV    }
        !           522:       (ScanCode: #$51; Shift: []; Ext: TRUE ; Value: #$1B + '[6~'),  { NEXT    }
        !           523:       (ScanCode: #$52; Shift: []; Ext: TRUE ; Value: #$1B + '[2~'),  { INSERT  }
        !           524:       (ScanCode: #$53; Shift: []; Ext: TRUE ; Value: #$7F       ),   { DELETE  }
        !           525:       (ScanCode: #$3B; Shift: []; Ext: FALSE; Value: #$1B + 'OP'),   { F1->PF1 }
        !           526:       (ScanCode: #$3C; Shift: []; Ext: FALSE; Value: #$1B + 'OQ'),   { F2->PF2 }
        !           527:       (ScanCode: #$3D; Shift: []; Ext: FALSE; Value: #$1B + 'OR'),   { F3->PF3 }
        !           528:       (ScanCode: #$3E; Shift: []; Ext: FALSE; Value: #$1B + 'OS'),   { F4->PF4 }
        !           529:       (ScanCode: #$57; Shift: []; Ext: FALSE; Value: #$1B + '[28~'), { F11->Aide }
        !           530:       (ScanCode: #$58; Shift: []; Ext: FALSE; Value: #$1B + '[29~'), { F12->Ex�cuter }
        !           531:       (ScanCode: #$00; Shift: []; Ext: FALSE; Value: ''         ),
        !           532:       (ScanCode: #$00; Shift: []; Ext: FALSE; Value: ''         ),
        !           533:       (ScanCode: #$00; Shift: []; Ext: FALSE; Value: ''         ),
        !           534:       (ScanCode: #$00; Shift: []; Ext: FALSE; Value: ''         ),
        !           535:       (ScanCode: #$00; Shift: []; Ext: FALSE; Value: ''         ),
        !           536:       (ScanCode: #$00; Shift: []; Ext: FALSE; Value: ''         ),
        !           537:       (ScanCode: #$00; Shift: []; Ext: FALSE; Value: ''         ),
        !           538:       (ScanCode: #$00; Shift: []; Ext: FALSE; Value: ''         ),
        !           539:       (ScanCode: #$00; Shift: []; Ext: FALSE; Value: ''         ),
        !           540:       (ScanCode: #$00; Shift: []; Ext: FALSE; Value: ''         ),
        !           541:       (ScanCode: #$00; Shift: []; Ext: FALSE; Value: ''         ),
        !           542:       (ScanCode: #$00; Shift: []; Ext: FALSE; Value: ''         ),
        !           543:       (ScanCode: #$00; Shift: []; Ext: FALSE; Value: ''         ),
        !           544:       (ScanCode: #$00; Shift: []; Ext: FALSE; Value: ''         ),
        !           545:       (ScanCode: #$00; Shift: []; Ext: FALSE; Value: ''         ),
        !           546:       (ScanCode: #$00; Shift: []; Ext: FALSE; Value: ''         ),
        !           547:       (ScanCode: #$00; Shift: []; Ext: FALSE; Value: ''         ),
        !           548:       (ScanCode: #$00; Shift: []; Ext: FALSE; Value: ''         ),
        !           549:       (ScanCode: #$00; Shift: []; Ext: FALSE; Value: ''         ),
        !           550:       (ScanCode: #$00; Shift: []; Ext: FALSE; Value: ''         ),
        !           551:       (ScanCode: #$00; Shift: []; Ext: FALSE; Value: ''         ),
        !           552:       (ScanCode: #$00; Shift: []; Ext: FALSE; Value: ''         ),
        !           553:       (ScanCode: #$00; Shift: []; Ext: FALSE; Value: ''         ),
        !           554:       (ScanCode: #$00; Shift: []; Ext: FALSE; Value: ''         ),
        !           555:       (ScanCode: #$00; Shift: []; Ext: FALSE; Value: ''         ),
        !           556:       (ScanCode: #$00; Shift: []; Ext: FALSE; Value: ''         ),
        !           557:       (ScanCode: #$00; Shift: []; Ext: FALSE; Value: ''         ),
        !           558:       (ScanCode: #$00; Shift: []; Ext: FALSE; Value: ''         ),
        !           559:       (ScanCode: #$00; Shift: []; Ext: FALSE; Value: ''         ),
        !           560:       (ScanCode: #$00; Shift: []; Ext: FALSE; Value: ''         ),
        !           561:       (ScanCode: #$00; Shift: []; Ext: FALSE; Value: ''         ),
        !           562:       (ScanCode: #$00; Shift: []; Ext: FALSE; Value: ''         ),
        !           563:       (ScanCode: #$00; Shift: []; Ext: FALSE; Value: ''         ),
        !           564:       (ScanCode: #$00; Shift: []; Ext: FALSE; Value: ''         ),
        !           565:       (ScanCode: #$00; Shift: []; Ext: FALSE; Value: ''         ),
        !           566:       (ScanCode: #$00; Shift: []; Ext: FALSE; Value: ''         ),
        !           567:       (ScanCode: #$00; Shift: []; Ext: FALSE; Value: ''         ),
        !           568:       (ScanCode: #$00; Shift: []; Ext: FALSE; Value: ''         ),
        !           569:       (ScanCode: #$00; Shift: []; Ext: FALSE; Value: ''         ),
        !           570:       (ScanCode: #$00; Shift: []; Ext: FALSE; Value: ''         ),
        !           571:       (ScanCode: #$00; Shift: []; Ext: FALSE; Value: ''         ),
        !           572:       (ScanCode: #$00; Shift: []; Ext: FALSE; Value: ''         ),
        !           573:       (ScanCode: #$00; Shift: []; Ext: FALSE; Value: ''         ),
        !           574:       (ScanCode: #$00; Shift: []; Ext: FALSE; Value: ''         ),
        !           575:       (ScanCode: #$00; Shift: []; Ext: FALSE; Value: ''         ),
        !           576:       (ScanCode: #$00; Shift: []; Ext: FALSE; Value: ''         ),
        !           577:       (ScanCode: #$00; Shift: []; Ext: FALSE; Value: ''         ),
        !           578:       (ScanCode: #$00; Shift: []; Ext: FALSE; Value: ''         ),
        !           579:       (ScanCode: #$00; Shift: []; Ext: FALSE; Value: ''         ),
        !           580:       (ScanCode: #$00; Shift: []; Ext: FALSE; Value: ''         )
        !           581:       );
        !           582: 
        !           583: { A-Series Telnet function keys (ordinary VT100 keys + specials) }
        !           584:   FKeys3 : TFuncKeysTable = (
        !           585:       (ScanCode: #$48; Shift: []; Ext: TRUE ; Value: #$1B + '[A'),   { UP      }
        !           586:       (ScanCode: #$50; Shift: []; Ext: TRUE ; Value: #$1B + '[B'),   { DOWN    }
        !           587:       (ScanCode: #$4D; Shift: []; Ext: TRUE ; Value: #$1B + '[C'),   { RIGHT   }
        !           588:       (ScanCode: #$4B; Shift: []; Ext: TRUE ; Value: #$1B + '[D'),   { LEFT    }
        !           589:       (ScanCode: #$49; Shift: []; Ext: TRUE ; Value: #$1B + '-'),    { PREV    }
        !           590:       (ScanCode: #$51; Shift: []; Ext: TRUE ; Value: #$1B + '+'),    { NEXT    }
        !           591:       (ScanCode: #$47; Shift: []; Ext: TRUE ; Value: #$1B + 'H'),    { HOME    }
        !           592:       (ScanCode: #$47; Shift: [ssCtrl]; Ext: TRUE ; Value: #$1B + 'C'),{ HOME  }
        !           593:       (ScanCode: #$4F; Shift: []; Ext: TRUE ; Value: #$1B + 'R'),    { END     }
        !           594:       (ScanCode: #$52; Shift: []; Ext: TRUE ; Value: #$1B + 'I'),    { INSERT  }
        !           595:       (ScanCode: #$53; Shift: []; Ext: TRUE ; Value: #$7F       ),   { DELETE  }
        !           596:       (ScanCode: #$3B; Shift: []; Ext: FALSE; Value: #$1B + 'OP'),   { F1->PF1 }
        !           597:       (ScanCode: #$3C; Shift: []; Ext: FALSE; Value: #$1B + 'OQ'),   { F2->PF2 }
        !           598:       (ScanCode: #$3D; Shift: []; Ext: FALSE; Value: #$1B + 'OR'),   { F3->PF3 }
        !           599:       (ScanCode: #$3E; Shift: []; Ext: FALSE; Value: #$1B + 'OS'),   { F4->PF4 }
        !           600:       (ScanCode: #$43; Shift: []; Ext: FALSE; Value: #$1B + 'OP'),   { F9      }
        !           601:       (ScanCode: #$44; Shift: []; Ext: FALSE; Value: ''),            { F10     }
        !           602:       (ScanCode: #$57; Shift: []; Ext: FALSE; Value: #$1B + 'OQ'),   { F11     }
        !           603:       (ScanCode: #$58; Shift: []; Ext: FALSE; Value: #$1B + 'OS'),   { F12     }
        !           604:       (ScanCode: #$0F; Shift: []; Ext: FALSE; Value: #$1B + 'Z'),    { RTAB    }
        !           605:       (ScanCode: #$40; Shift: []; Ext: FALSE; Value: #$1B + 'K'),    { F6      }
        !           606:       (ScanCode: #$53; Shift: [ssCtrl]; Ext: TRUE ; Value: #$1B + 'D'), { CDEL }
        !           607:       (ScanCode: #$52; Shift: [ssCtrl]; Ext: TRUE ; Value: #$1B + 'L'), { CINS }
        !           608:       (ScanCode: #$00; Shift: []; Ext: FALSE; Value: ''         ),
        !           609:       (ScanCode: #$00; Shift: []; Ext: FALSE; Value: ''         ),
        !           610:       (ScanCode: #$00; Shift: []; Ext: FALSE; Value: ''         ),
        !           611:       (ScanCode: #$00; Shift: []; Ext: FALSE; Value: ''         ),
        !           612:       (ScanCode: #$00; Shift: []; Ext: FALSE; Value: ''         ),
        !           613:       (ScanCode: #$00; Shift: []; Ext: FALSE; Value: ''         ),
        !           614:       (ScanCode: #$00; Shift: []; Ext: FALSE; Value: ''         ),
        !           615:       (ScanCode: #$00; Shift: []; Ext: FALSE; Value: ''         ),
        !           616:       (ScanCode: #$00; Shift: []; Ext: FALSE; Value: ''         ),
        !           617:       (ScanCode: #$00; Shift: []; Ext: FALSE; Value: ''         ),
        !           618:       (ScanCode: #$00; Shift: []; Ext: FALSE; Value: ''         ),
        !           619:       (ScanCode: #$00; Shift: []; Ext: FALSE; Value: ''         ),
        !           620:       (ScanCode: #$00; Shift: []; Ext: FALSE; Value: ''         ),
        !           621:       (ScanCode: #$00; Shift: []; Ext: FALSE; Value: ''         ),
        !           622:       (ScanCode: #$00; Shift: []; Ext: FALSE; Value: ''         ),
        !           623:       (ScanCode: #$00; Shift: []; Ext: FALSE; Value: ''         ),
        !           624:       (ScanCode: #$00; Shift: []; Ext: FALSE; Value: ''         ),
        !           625:       (ScanCode: #$00; Shift: []; Ext: FALSE; Value: ''         ),
        !           626:       (ScanCode: #$00; Shift: []; Ext: FALSE; Value: ''         ),
        !           627:       (ScanCode: #$00; Shift: []; Ext: FALSE; Value: ''         ),
        !           628:       (ScanCode: #$00; Shift: []; Ext: FALSE; Value: ''         ),
        !           629:       (ScanCode: #$00; Shift: []; Ext: FALSE; Value: ''         ),
        !           630:       (ScanCode: #$00; Shift: []; Ext: FALSE; Value: ''         ),
        !           631:       (ScanCode: #$00; Shift: []; Ext: FALSE; Value: ''         ),
        !           632:       (ScanCode: #$00; Shift: []; Ext: FALSE; Value: ''         ),
        !           633:       (ScanCode: #$00; Shift: []; Ext: FALSE; Value: ''         ),
        !           634:       (ScanCode: #$00; Shift: []; Ext: FALSE; Value: ''         ),
        !           635:       (ScanCode: #$00; Shift: []; Ext: FALSE; Value: ''         ),
        !           636:       (ScanCode: #$00; Shift: []; Ext: FALSE; Value: ''         ),
        !           637:       (ScanCode: #$00; Shift: []; Ext: FALSE; Value: ''         ),
        !           638:       (ScanCode: #$00; Shift: []; Ext: FALSE; Value: ''         ),
        !           639:       (ScanCode: #$00; Shift: []; Ext: FALSE; Value: ''         ),
        !           640:       (ScanCode: #$00; Shift: []; Ext: FALSE; Value: ''         ),
        !           641:       (ScanCode: #$00; Shift: []; Ext: FALSE; Value: ''         ),
        !           642:       (ScanCode: #$00; Shift: []; Ext: FALSE; Value: ''         ),
        !           643:       (ScanCode: #$00; Shift: []; Ext: FALSE; Value: ''         ),
        !           644:       (ScanCode: #$00; Shift: []; Ext: FALSE; Value: ''         ),
        !           645:       (ScanCode: #$00; Shift: []; Ext: FALSE; Value: ''         ),
        !           646:       (ScanCode: #$00; Shift: []; Ext: FALSE; Value: ''         ),
        !           647:       (ScanCode: #$00; Shift: []; Ext: FALSE; Value: ''         ),
        !           648:       (ScanCode: #$00; Shift: []; Ext: FALSE; Value: ''         )
        !           649:       );
        !           650: 
        !           651:   { Ethernet to screen }
        !           652:   ibm_iso8859_1_G0 : TXlatTable = (
        !           653:       #$00, #$01, #$02, #$03, #$04, #$05, #$06, #$07,   { 00 - 07 }
        !           654:       #$08, #$09, #$0A, #$0B, #$0C, #$0D, #$0E, #$0F,   { 08 - 0F }
        !           655:       #$10, #$11, #$12, #$13, #$14, #$15, #$16, #$17,   { 10 - 17 }
        !           656:       #$18, #$19, #$1A, #$1B, #$1C, #$1D, #$1E, #$1F,   { 18 - 1F }
        !           657:       #$20, #$21, #$22, #$23, #$24, #$25, #$26, #$27,   { 20 - 27 }
        !           658:       #$28, #$29, #$2A, #$2B, #$2C, #$2D, #$2E, #$2F,   { 28 - 2F }
        !           659:       #$30, #$31, #$32, #$33, #$34, #$35, #$36, #$37,   { 30 - 37 }
        !           660:       #$38, #$39, #$3A, #$3B, #$3C, #$3D, #$3E, #$3F,   { 38 - 3F }
        !           661:       #$40, #$41, #$42, #$43, #$44, #$45, #$46, #$47,   { 40 - 47 }
        !           662:       #$48, #$49, #$4A, #$4B, #$4C, #$4D, #$4E, #$4F,   { 48 - 4F }
        !           663:       #$50, #$51, #$52, #$53, #$54, #$55, #$56, #$57,   { 50 - 57 }
        !           664:       #$58, #$59, #$5A, #$5B, #$5C, #$5D, #$5E, #$5F,   { 58 - 5F }
        !           665:       #$60, #$61, #$62, #$63, #$64, #$65, #$66, #$67,   { 60 - 67 }
        !           666:       #$68, #$69, #$6A, #$6B, #$6C, #$6D, #$6E, #$6F,   { 68 - 6F }
        !           667:       #$70, #$71, #$72, #$73, #$74, #$75, #$76, #$77,   { 70 - 77 }
        !           668:       #$78, #$79, #$7A, #$7B, #$7C, #$7D, #$7E, #$7F,   { 78 - 7F }
        !           669:       #$20, #$20, #$20, #$20, #$20, #$20, #$20, #$20,   { 80 - 87 }
        !           670:       #$20, #$20, #$20, #$20, #$20, #$20, #$20, #$20,   { 88 - 8F }
        !           671:       #$20, #$20, #$20, #$20, #$20, #$20, #$20, #$20,   { 90 - 97 }
        !           672:       #$20, #$20, #$20, #$20, #$20, #$20, #$20, #$20,   { 98 - 9F }
        !           673:       #$B1, #$AD, #$9B, #$9C, #$0F, #$9D, #$B3, #$15,   { A0 - A7 }
        !           674:       #$20, #$43, #$A6, #$AE, #$AA, #$C4, #$52, #$C4,   { A8 - AF }
        !           675:       #$F8, #$F1, #$FD, #$20, #$27, #$E6, #$14, #$FA,   { B0 - B7 }
        !           676:       #$2C, #$20, #$A7, #$AF, #$AC, #$AB, #$20, #$A8,   { B8 - BF }
        !           677:       #$41, #$41, #$41, #$41, #$8E, #$8F, #$92, #$80,   { C0 - C7 }
        !           678:       #$45, #$45, #$45, #$45, #$45, #$49, #$49, #$49,   { C8 - CF }
        !           679:       #$44, #$A5, #$4F, #$4F, #$4F, #$4F, #$4F, #$78,   { D0 - D7 }
        !           680:       #$ED, #$55, #$55, #$55, #$55, #$59, #$70, #$E1,   { D8 - DF }
        !           681:       #$85, #$A0, #$83, #$61, #$84, #$86, #$91, #$87,   { E0 - E7 }
        !           682:       #$8A, #$82, #$88, #$89, #$8D, #$A1, #$8C, #$49,   { E8 - EF }
        !           683:       #$64, #$A4, #$95, #$A2, #$93, #$6F, #$94, #$F6,   { F0 - F7 }
        !           684:       #$ED, #$97, #$A3, #$96, #$9A, #$79, #$70, #$98);  { F8 - FF }
        !           685: 
        !           686: { Ethernet to screen }
        !           687:   ibm_iso8859_1_G1 : TXlatTable = (
        !           688:       #$00, #$01, #$02, #$03, #$04, #$05, #$06, #$07,   { 00 - 07 }
        !           689:       #$08, #$09, #$0A, #$0B, #$0C, #$0D, #$0E, #$0F,   { 08 - 0F }
        !           690:       #$10, #$11, #$12, #$13, #$14, #$15, #$16, #$17,   { 10 - 17 }
        !           691:       #$18, #$19, #$1A, #$1B, #$1C, #$1D, #$1E, #$1F,   { 18 - 1F }
        !           692:       #$20, #$21, #$22, #$23, #$24, #$25, #$26, #$27,   { 20 - 27 }
        !           693:       #$28, #$29, #$2A, #$2B, #$2C, #$2D, #$2E, #$2F,   { 28 - 2F }
        !           694:       #$30, #$31, #$32, #$33, #$34, #$35, #$36, #$37,   { 30 - 37 }
        !           695:       #$38, #$39, #$3A, #$3B, #$3C, #$3D, #$3E, #$3F,   { 38 - 3F }
        !           696:       #$40, #$41, #$42, #$43, #$44, #$45, #$46, #$47,   { 40 - 47 }
        !           697:       #$48, #$49, #$4A, #$4B, #$4C, #$4D, #$4E, #$4F,   { 48 - 4F }
        !           698:       #$50, #$51, #$52, #$53, #$54, #$55, #$56, #$57,   { 50 - 57 }
        !           699:       #$58, #$59, #$5A, #$5B, #$5C, #$5D, #$5E, #$5F,   { 58 - 5F }
        !           700:       #$60, #$61, #$62, #$63, #$64, #$65, #$66, #$67,   { 60 - 67 }
        !           701:       #$68, #$69, #$D9, #$BF, #$DA, #$C0, #$C5, #$6F,   { 68 - 6F }
        !           702:       #$70, #$C4, #$72, #$73, #$C3, #$B4, #$C1, #$C2,   { 70 - 77 }
        !           703:       #$B3, #$79, #$7A, #$7B, #$7C, #$7D, #$7E, #$7F,   { 78 - 7F }
        !           704:       #$20, #$20, #$20, #$20, #$20, #$20, #$20, #$20,   { 80 - 87 }
        !           705:       #$20, #$20, #$20, #$20, #$20, #$20, #$20, #$20,   { 88 - 8F }
        !           706:       #$20, #$20, #$20, #$20, #$20, #$20, #$20, #$20,   { 90 - 97 }
        !           707:       #$20, #$20, #$20, #$20, #$20, #$20, #$20, #$20,   { 98 - 9F }
        !           708:       #$B1, #$AD, #$9B, #$9C, #$0F, #$9D, #$B3, #$15,   { A0 - A7 }
        !           709:       #$20, #$43, #$A6, #$AE, #$AA, #$C4, #$52, #$C4,   { A8 - AF }
        !           710:       #$F8, #$F1, #$FD, #$20, #$27, #$E6, #$14, #$FA,   { B0 - B7 }
        !           711:       #$2C, #$20, #$A7, #$AF, #$AC, #$AB, #$20, #$A8,   { B8 - BF }
        !           712:       #$41, #$41, #$41, #$41, #$8E, #$8F, #$92, #$80,   { C0 - C7 }
        !           713:       #$45, #$45, #$45, #$45, #$45, #$49, #$49, #$49,   { C8 - CF }
        !           714:       #$44, #$A5, #$4F, #$4F, #$4F, #$4F, #$4F, #$78,   { D0 - D7 }
        !           715:       #$ED, #$55, #$55, #$55, #$55, #$59, #$70, #$E1,   { D8 - DF }
        !           716:       #$85, #$A0, #$83, #$61, #$84, #$86, #$91, #$87,   { E0 - E7 }
        !           717:       #$8A, #$82, #$88, #$89, #$8D, #$A1, #$8C, #$49,   { E8 - EF }
        !           718:       #$64, #$A4, #$95, #$A2, #$93, #$6F, #$94, #$F6,   { F0 - F7 }
        !           719:       #$ED, #$97, #$A3, #$96, #$9A, #$79, #$70, #$98);  { F8 - FF }
        !           720: 
        !           721: { Keyboard to Ethernet }
        !           722:   Output : TXlatTable = (
        !           723:       #$00, #$01, #$02, #$03, #$04, #$05, #$06, #$07,   { 00 - 07 }
        !           724:       #$08, #$09, #$0A, #$0B, #$0C, #$0D, #$0E, #$0F,   { 08 - 0F }
        !           725:       #$10, #$11, #$12, #$13, #$14, #$15, #$16, #$17,   { 10 - 17 }
        !           726:       #$18, #$19, #$1A, #$1B, #$1C, #$1D, #$1E, #$1F,   { 18 - 1F }
        !           727:       #$20, #$21, #$22, #$23, #$24, #$25, #$26, #$27,   { 20 - 27 }
        !           728:       #$28, #$29, #$2A, #$2B, #$2C, #$2D, #$2E, #$2F,   { 28 - 2F }
        !           729:       #$30, #$31, #$32, #$33, #$34, #$35, #$36, #$37,   { 30 - 37 }
        !           730:       #$38, #$39, #$3A, #$3B, #$3C, #$3D, #$3E, #$3F,   { 38 - 3F }
        !           731:       #$40, #$41, #$42, #$43, #$44, #$45, #$46, #$47,   { 40 - 47 }
        !           732:       #$48, #$49, #$4A, #$4B, #$4C, #$4D, #$4E, #$4F,   { 48 - 4F }
        !           733:       #$50, #$51, #$52, #$53, #$54, #$55, #$56, #$57,   { 50 - 57 }
        !           734:       #$58, #$59, #$5A, #$5B, #$5C, #$5D, #$5E, #$5F,   { 58 - 5F }
        !           735:       #$60, #$61, #$62, #$63, #$64, #$65, #$66, #$67,   { 60 - 67 }
        !           736:       #$68, #$69, #$6A, #$6B, #$6C, #$6D, #$6E, #$6F,   { 68 - 6F }
        !           737:       #$70, #$71, #$72, #$73, #$74, #$75, #$76, #$77,   { 70 - 77 }
        !           738:       #$78, #$79, #$7A, #$7B, #$7C, #$7D, #$7E, #$7F,   { 78 - 7F }
        !           739:       #$C7, #$FC, #$E9, #$E2, #$E4, #$E0, #$E5, #$E7,   { 80 - 87 }
        !           740:       #$EA, #$EB, #$E8, #$EF, #$EE, #$EC, #$C4, #$C5,   { 88 - 8F }
        !           741:       #$C9, #$E6, #$C6, #$F4, #$F6, #$F2, #$FB, #$F9,   { 90 - 97 }
        !           742:       #$FF, #$F6, #$FC, #$A2, #$A3, #$A5, #$DE, #$20,   { 98 - 9F }
        !           743:       #$E1, #$ED, #$F3, #$FA, #$F1, #$D1, #$AA, #$BA,   { A0 - A7 }
        !           744:       #$BF, #$20, #$AC, #$BD, #$BC, #$A1, #$AB, #$BB,   { A8 - AF }
        !           745:       #$A0, #$A0, #$A0, #$A6, #$A6, #$A6, #$A6, #$AD,   { B0 - B7 }
        !           746:       #$2B, #$A6, #$A6, #$2B, #$2B, #$2B, #$2B, #$2B,   { B8 - BF }
        !           747:       #$2B, #$AD, #$AD, #$AD, #$A6, #$AD, #$2B, #$A6,   { C0 - C7 }
        !           748:       #$2B, #$2B, #$AD, #$AD, #$A6, #$AD, #$2B, #$AD,   { C8 - CF }
        !           749:       #$AD, #$AD, #$AD, #$2B, #$2B, #$2B, #$2B, #$2B,   { D0 - D7 }
        !           750:       #$2B, #$2B, #$2B, #$A0, #$A0, #$A0, #$A0, #$A0,   { D8 - DF }
        !           751:       #$20, #$20, #$20, #$AD, #$20, #$20, #$B5, #$20,   { E0 - E7 }
        !           752:       #$20, #$20, #$20, #$20, #$20, #$F8, #$20, #$20,   { E8 - EF }
        !           753:       #$A0, #$B1, #$20, #$20, #$20, #$20, #$F7, #$20,   { F0 - F7 }
        !           754:       #$B0, #$B0, #$B0, #$20, #$20, #$B2, #$A0, #$20);  { F8 - FF }
        !           755: 
        !           756: procedure Register;
        !           757: procedure FKeysToFile(var FKeys : TFuncKeysTable; FName : String);
        !           758: procedure FileToFKeys(var FKeys : TFuncKeysTable; FName : String);
        !           759: function  AddFKey(var FKeys : TFuncKeysTable;
        !           760:                   ScanCode  : Char;
        !           761:                   Shift     : TShiftState;
        !           762:                   Ext       : Boolean;
        !           763:                   Value     : TFuncKeyValue) : Boolean;
        !           764: 
        !           765: 
        !           766: 
        !           767: implementation
        !           768: {$DEFINE Debug}      { Add or remove minus sign before dollar sign to }
        !           769:                      { generate code for debug message output         }
        !           770: var
        !           771:     FCharPos : array [0..MAX_COL + 1] of integer;
        !           772:     FLinePos : array [0..MAX_ROW + 1] of integer;
        !           773: 
        !           774: {* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *}
        !           775: procedure Register;
        !           776: begin
        !           777:     RegisterComponents('FPiette', [TEmulVT]);
        !           778: end;
        !           779: 
        !           780: 
        !           781: {* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *}
        !           782: function ShiftStateToString(var State : TShiftState) : String;
        !           783: begin
        !           784:     Result := '';
        !           785:     if ssShift in State then
        !           786:         Result := Result + 'ssShift ';
        !           787:     if ssAlt in State then
        !           788:         Result := Result + 'ssAlt ';
        !           789:     if ssCtrl in State then
        !           790:         Result := Result + 'ssCtrl ';
        !           791:     if ssLeft in State then
        !           792:         Result := Result + 'ssLeft ';
        !           793:     if ssRight in State then
        !           794:         Result := Result + 'ssRight ';
        !           795:     if ssMiddle in State then
        !           796:         Result := Result + 'ssMiddle ';
        !           797:     if ssDouble in State then
        !           798:         Result := Result + 'ssDouble ';
        !           799:     if Result = '' then
        !           800:         Result := 'ssNormal';
        !           801: end;
        !           802: 
        !           803: 
        !           804: {* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *}
        !           805: function StringToShiftState(var S : String) : TShiftState;
        !           806: begin
        !           807:     Result := [];
        !           808:     if Pos('ssShift', S) <> 0 then
        !           809:         Result := Result + [ssShift];
        !           810:     if Pos('ssAlt', S) <> 0 then
        !           811:         Result := Result + [ssAlt];
        !           812:     if Pos('ssCtrl', S) <> 0 then
        !           813:         Result := Result + [ssCtrl];
        !           814:     if Pos('ssLeft', S) <> 0 then
        !           815:         Result := Result + [ssLeft];
        !           816:     if Pos('ssRight', S) <> 0 then
        !           817:         Result := Result + [ssRight];
        !           818:     if Pos('ssMiddle', S) <> 0 then
        !           819:         Result := Result + [ssMiddle];
        !           820:     if Pos('ssDouble', S) <> 0 then
        !           821:         Result := Result + [ssDouble];
        !           822: end;
        !           823: 
        !           824: 
        !           825: {* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *}
        !           826: function xdigit(Ch : char) : integer;
        !           827: begin
        !           828:     if ch in ['0'..'9'] then
        !           829:         Result := Ord(ch) - ord('0')
        !           830:     else if ch in ['A'..'Z'] then
        !           831:         Result := Ord(ch) - Ord('A') + 10
        !           832:     else if ch in ['a'..'z'] then
        !           833:         Result := Ord(ch) - Ord('a') + 10
        !           834:     else
        !           835:         Result := 0;
        !           836: end;
        !           837: 
        !           838: 
        !           839: {* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *}
        !           840: function xdigit2(S : PChar) : integer;
        !           841: begin
        !           842:     Result := 16 * xdigit(S[0]) + xdigit(S[1]);
        !           843: end;
        !           844: 
        !           845: 
        !           846: {* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *}
        !           847: function FuncKeyValueToString(var S : TFuncKeyValue) : String;
        !           848: var
        !           849:     I : Integer;
        !           850: begin
        !           851:     Result := '';
        !           852:     for I := 1 to Length(S) do begin
        !           853:         if (Ord(S[I]) < 32) or (Ord(S[I]) >= 127) or
        !           854:            (S[I] = '''') or (S[I] = '\') then
        !           855:             Result := Result + '\x' + IntToHex(Ord(S[I]), 2)
        !           856:         else
        !           857:             Result := Result + S[I];
        !           858:     end;
        !           859: end;
        !           860: 
        !           861: 
        !           862: {* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *}
        !           863: function StringToFuncKeyValue(var S : String) : TFuncKeyValue;
        !           864: var
        !           865:     I : Integer;
        !           866: begin
        !           867:     Result := '';
        !           868:     I := 1;
        !           869:     while I <= Length(S) do begin
        !           870:         if (S[I] = '\') and
        !           871:            ((I + 3) <= Length(S)) and
        !           872:            (S[I + 1] = 'x') then begin
        !           873:             Result := Result + chr(xdigit2(@S[I + 2]));
        !           874:             I := I + 3;
        !           875:         end
        !           876:         else
        !           877:             Result := Result + S[I];
        !           878:         Inc(I);
        !           879:     end;
        !           880: end;
        !           881: 
        !           882: 
        !           883: {* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *}
        !           884: function AddFKey(var FKeys : TFuncKeysTable;
        !           885:                   ScanCode  : Char;
        !           886:                   Shift     : TShiftState;
        !           887:                   Ext       : Boolean;
        !           888:                   Value     : TFuncKeyValue) : Boolean;
        !           889: var
        !           890:     I : Integer;
        !           891: begin
        !           892:     { Search for existing key definition to replace it }
        !           893:     for I := Low(FKeys) to High(FKeys) do begin
        !           894:         if (FKeys[I].ScanCode = ScanCode) and
        !           895:            (FKeys[I].Shift    = Shift) and
        !           896:            (FKeys[I].Ext      = Ext) then begin
        !           897:             FKeys[I].Value := Value;
        !           898:             Result         := TRUE;     { Success}
        !           899:             Exit;
        !           900:         end;
        !           901:     end;
        !           902: 
        !           903:     { Key not existing, add in an empty space }
        !           904:     for I := Low(FKeys) to High(FKeys) do begin
        !           905:         if FKeys[I].ScanCode = #0 then begin
        !           906:             FKeys[I].ScanCode := ScanCode;
        !           907:             FKeys[I].Shift    := Shift;
        !           908:             FKeys[I].Ext      := Ext;
        !           909:             FKeys[I].Value    := Value;
        !           910:             Result            := TRUE;     { Success}
        !           911:             Exit;
        !           912:         end;
        !           913:     end;
        !           914: 
        !           915:     { Failure, no more space available }
        !           916:     Result := FALSE;
        !           917: end;
        !           918: 
        !           919: 
        !           920: {* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *}
        !           921: procedure FKeysToFile(var FKeys : TFuncKeysTable; FName : String);
        !           922: var
        !           923:     I : Integer;
        !           924:     F : TextFile;
        !           925: begin
        !           926:     AssignFile(F, FName);
        !           927:     Rewrite(F);
        !           928:     for I := Low(FKeys) to High(FKeys) do begin
        !           929:         with FKeys[I] do begin
        !           930:             if ScanCode <> chr(0) then
        !           931:                 WriteLn(F, IntToHex(Ord(ScanCode), 2), ', ',
        !           932:                            ShiftStateToString(Shift), ', ',
        !           933:                            Ext, ', ''',
        !           934:                            FuncKeyValueToString(Value), '''');
        !           935:         end;
        !           936:     end;
        !           937:     CloseFile(F);
        !           938: end;
        !           939: 
        !           940: 
        !           941: {* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *}
        !           942: function GetToken(var S : String; var I : Integer; Delim : Char) : String;
        !           943: begin
        !           944:     Result := '';
        !           945:     while (I <= Length(S)) and (S[I] = ' ') do
        !           946:         Inc(I);
        !           947:     while (I <= Length(S)) and (S[I] <> Delim) do begin
        !           948:         Result := Result + S[I];
        !           949:         Inc(I);
        !           950:     end;
        !           951: end;
        !           952: 
        !           953: 
        !           954: {* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *}
        !           955: procedure FileToFKeys(var FKeys : TFuncKeysTable; FName : String);
        !           956: var
        !           957:     I, J : Integer;
        !           958:     F : TextFile;
        !           959:     S, T : String;
        !           960:     sc   : Integer;
        !           961: begin
        !           962:     AssignFile(F, FName);
        !           963:  {$I-}
        !           964:     Reset(F);
        !           965:     if IOResult <> 0 then begin
        !           966:         { File do not exist, create default one }
        !           967:         FKeysToFile(FKeys, FName);
        !           968:         Exit;
        !           969:     end;
        !           970: 
        !           971:     for I := Low(FKeys) to High(FKeys) do begin
        !           972:         with FKeys[I] do begin
        !           973:             ScanCode := chr(0);
        !           974:             Shift    := [];
        !           975:             Ext      := FALSE;
        !           976:             Value    := '';
        !           977:             if not Eof(F) then begin
        !           978:                 { 71, ssNormal, TRUE, '\x1B[H' }
        !           979:                 ReadLn(F, S);
        !           980:                 J  := 1;
        !           981:                 T  := GetToken(S, J, ',');
        !           982:                 if (Length(T) > 0) and (T[1] <> ';') then begin
        !           983:                     sc := xdigit2(@T[1]);
        !           984:                     if sc <> 0 then begin
        !           985:                         ScanCode := chr(sc);
        !           986:                         Inc(J);
        !           987:                         T := GetToken(S, J, ',');
        !           988:                         Shift := StringToShiftState(T);
        !           989:                         Inc(J);
        !           990:                         T := GetToken(S, J, ',');
        !           991:                         Ext := UpperCase(T) = 'TRUE';
        !           992:                         Inc(J);
        !           993:                         T := GetToken(S, J, '''');
        !           994:                         Inc(J);
        !           995:                         T := GetToken(S, J, '''');
        !           996:                         Value := StringToFuncKeyValue(T);
        !           997:                     end;
        !           998:                 end;
        !           999:             end;
        !          1000:         end;
        !          1001:     end;
        !          1002:     CloseFile(F);
        !          1003: {$I+}
        !          1004: end;
        !          1005: 
        !          1006: 
        !          1007: {* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *}
        !          1008: procedure DebugString(Msg : String);
        !          1009: const
        !          1010:     Cnt : Integer = 0;
        !          1011: var
        !          1012:     Buf : String[20];
        !          1013: begin
        !          1014: {$IFDEF Debug}
        !          1015:     Cnt := Cnt + 1;
        !          1016:     Buf := IntToHex(Cnt, 4) + ' ' + #0;
        !          1017:     OutputDebugString(@Buf[1]);
        !          1018: 
        !          1019: {$IFNDEF WIN32}
        !          1020:     if Length(Msg) < High(Msg) then
        !          1021:         Msg[Length(Msg) + 1] := #0;
        !          1022: {$ENDIF}
        !          1023: 
        !          1024:     OutputDebugString(@Msg[1]);
        !          1025: {$ENDIF}
        !          1026: end;
        !          1027: 
        !          1028: 
        !          1029: {* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *}
        !          1030: {$IFNDEF WIN32}
        !          1031: procedure SetLength(var S: string; NewLength: Integer);
        !          1032: begin
        !          1033:     S[0] := chr(NewLength);
        !          1034: end;
        !          1035: {$ENDIF}
        !          1036: 
        !          1037: 
        !          1038: {* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *}
        !          1039: constructor TLine.Create;
        !          1040: begin
        !          1041:     inherited Create;
        !          1042:     FillChar(Txt, SizeOf(Txt), ' ');
        !          1043:     FillChar(Att, SizeOf(Att), Chr(F_WHITE));
        !          1044: end;
        !          1045: 
        !          1046: 
        !          1047: {* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *}
        !          1048: procedure TLine.Clear(Attr : Byte);
        !          1049: begin
        !          1050:     FillChar(Txt, SizeOF(Txt), ' ');
        !          1051:     FillChar(Att, SizeOf(Att), Attr);
        !          1052: end;
        !          1053: 
        !          1054: 
        !          1055: {* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *}
        !          1056: constructor TScreen.Create;
        !          1057: begin
        !          1058:     inherited Create;
        !          1059:     FRowCount        := 0;
        !          1060:     FBackRowCount    := 0;
        !          1061:     FBackEndRow      := 0;
        !          1062:     FBackColor       := vtsWhite;
        !          1063:     FOptions         := [vtoBackColor];
        !          1064:     SetRowCount(25);
        !          1065:     FColCount        := 80;
        !          1066:     FRowSaved        := -1;
        !          1067:     FColSaved        := -1;
        !          1068:     FScrollRowTop    := 0;
        !          1069:     {FScrollRowBottom := FRowCount - 1; // WM + SE 09/08/00 }
        !          1070:     FAttribute       := F_WHITE;
        !          1071:     InvClear;
        !          1072: end;
        !          1073: 
        !          1074: 
        !          1075: {* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *}
        !          1076: destructor TScreen.Destroy;
        !          1077: var
        !          1078:     nRow : Integer;
        !          1079: begin
        !          1080:     for nRow := 0 to FRowCount + FBackRowCount - 1 do
        !          1081:         FLines^[nRow].Free;
        !          1082:     FreeMem (FLines, (FRowCount + FBackRowCount) * SizeOf(TObject));
        !          1083: end;
        !          1084: 
        !          1085: 
        !          1086: {* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *}
        !          1087: procedure TScreen.AdjustFLines(NewCount : Integer);
        !          1088: var
        !          1089:     NewLines        : PLineArray;
        !          1090:     CurrCount       : Integer;
        !          1091:     nRow            : Integer;
        !          1092: begin
        !          1093:     CurrCount := FRowCount + FBackRowCount;
        !          1094:     if  (NewCount <> CurrCount) and (NewCount > 0) then begin
        !          1095:         GetMem(NewLines, NewCount * SizeOf(TObject));
        !          1096:         if NewCount > CurrCount then begin
        !          1097:             if CurrCount <> 0 then
        !          1098:                 Move(FLines^, NewLines^, CurrCount * SizeOf(TObject));
        !          1099:             for nRow := CurrCount to NewCount - 1 do
        !          1100:                 NewLines^[nRow] := TLine.Create;
        !          1101:             if CurrCount <> 0 then
        !          1102:                 FreeMem(FLines, CurrCount * SizeOf(TObject));
        !          1103:         end
        !          1104:         else begin
        !          1105:             Move (FLines^, NewLines^, NewCount * SizeOf(TObject));
        !          1106:             for nRow := NewCount to CurrCount - 1 do
        !          1107:                 FLines^[nRow].Free;
        !          1108:             FreeMem(FLines, CurrCount * SizeOf(TObject));
        !          1109:         end;
        !          1110:         FLines := NewLines;
        !          1111:     end;
        !          1112: end;
        !          1113: 
        !          1114: 
        !          1115: {* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *}
        !          1116: procedure TScreen.SetRowCount(NewCount : Integer);
        !          1117: begin
        !          1118:     if NewCount <> FRowCount then begin
        !          1119:         AdjustFLines(NewCount + FBackRowCount);
        !          1120:         FRowCount := NewCount;
        !          1121:         FScrollRowBottom := FRowCount - 1; { WM + SE 09/08/00 }
        !          1122:     end;
        !          1123: end;
        !          1124: 
        !          1125: 
        !          1126: {* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *}
        !          1127: procedure TScreen.SetBackRowCount(NewCount : Integer);
        !          1128: begin
        !          1129:     if NewCount <> FBackRowCount then begin
        !          1130:         AdjustFLines(FRowCount + NewCount);
        !          1131:         FBackRowCount := NewCount;
        !          1132:     end;
        !          1133: end;
        !          1134: 
        !          1135: 
        !          1136: {* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *}
        !          1137: procedure TScreen.CopyScreenToBack;
        !          1138: { Copies the current host screen into the scrollback buffer. }
        !          1139: var
        !          1140:     Temp : TLine;
        !          1141:     Row  : Integer;
        !          1142:     Pass : Integer;
        !          1143:     nCol : Integer;
        !          1144: begin
        !          1145:     if FBackRowCount >= FRowCount then begin
        !          1146:         Dec (FBackEndRow, FRowCount);
        !          1147:         if (0 - FBackEndRow) >= FBackRowCount then
        !          1148:             FBackEndRow := 1 - FBackRowCount;
        !          1149:         { We have to make  FRowCount  lines available at the head of the
        !          1150:           scrollback buffer.  These will come from the end of the scrollback
        !          1151:           buffer.  We'll make  FRowCount  passes through the scrollback buffer
        !          1152:           moving the available lines up to the top and the existing lines
        !          1153:           down a page at a time.
        !          1154:           Net result is that we only move each line once. }
        !          1155:         For Pass := 0 To FRowCount - 1 Do begin
        !          1156:             Row := FBackEndRow + Pass;
        !          1157:             Temp := Lines[Row];
        !          1158:             Inc (Row, FRowCount);
        !          1159:             While Row < 0 Do begin
        !          1160:                 Lines[Row - FRowCount] := Lines[Row];
        !          1161:                 Inc (Row, FRowCount);
        !          1162:             end;
        !          1163:             Lines[Row - FRowCount] := Temp;
        !          1164:         end;
        !          1165: 
        !          1166:         { Now, copy the host screen lines to the ons we made available. }
        !          1167:         For Row := 0 To FRowCount - 1 Do begin
        !          1168:             Move (Lines[Row].Txt, Lines[Row - FRowCount].Txt, FColCount);
        !          1169:             Move (Lines[Row].Att, Lines[Row - FRowCount].Att, FColCount);
        !          1170:             if vtoBackColor in FOptions then begin
        !          1171:                 with Lines[Row - FRowCount] do begin
        !          1172:                     for nCol := 0 to FColCount - 1 do begin
        !          1173:                         Att[nCol] := Att[nCol] And $8F Or (Ord (FBackColor) shl 4);
        !          1174:                     end;
        !          1175:                 end;
        !          1176:             end;
        !          1177:         end;
        !          1178:     end;
        !          1179: end;
        !          1180: 
        !          1181: 
        !          1182: {* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *}
        !          1183: procedure TScreen.ScrollUp;
        !          1184: var
        !          1185:     Temp : TLine;
        !          1186:     Row  : Integer;
        !          1187:     nCol : Integer;
        !          1188: begin
        !          1189:     if FBackRowCount > 0 then begin
        !          1190:         if (0 - FBackEndRow) < (FBackRowCount - 1) then
        !          1191:             Dec (FBackEndRow);
        !          1192:         Temp := Lines[FBackEndRow];
        !          1193:         For Row := FBackEndRow + 1 To -1 Do begin
        !          1194:             Lines[Row - 1] := Lines[Row];
        !          1195:         end;
        !          1196:         Lines[-1] := Lines[FScrollRowTop];
        !          1197:             if vtoBackColor in FOptions then begin
        !          1198:                 with Lines[-1] do begin
        !          1199:                     for nCol := 0 to FColCount - 1 do begin
        !          1200:                         Att[nCol] := Att[nCol] And $8F Or (Ord (FBackColor) shl 4);
        !          1201:                     end;
        !          1202:                 end;
        !          1203:             end;
        !          1204: 
        !          1205:     end
        !          1206:     else
        !          1207:         Temp := Lines[FScrollRowTop];
        !          1208: 
        !          1209:     for Row := FScrollRowTop + 1 to FScrollRowBottom do
        !          1210:         Lines[Row - 1] := Lines[Row];
        !          1211:     Lines[FScrollRowBottom] := Temp;
        !          1212:     Temp.Clear(F_WHITE {FAttribute});
        !          1213:     FAllInvalid := TRUE;
        !          1214: end;
        !          1215: 
        !          1216: 
        !          1217: {* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *}
        !          1218: procedure TScreen.ScrollDown;
        !          1219: var
        !          1220:     Temp : TLine;
        !          1221:     Row  : Integer;
        !          1222: begin
        !          1223:     Temp := Lines[FScrollRowBottom];
        !          1224:     for Row := FScrollRowBottom DownTo FScrollRowTop + 1 do
        !          1225:         Lines[Row] := Lines[Row - 1];
        !          1226:     Lines[FScrollRowTop] := Temp;
        !          1227:     Temp.Clear(F_WHITE {FAttribute});
        !          1228:     FAllInvalid := TRUE;
        !          1229: end;
        !          1230: 
        !          1231: 
        !          1232: {* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *}
        !          1233: procedure TScreen.CursorDown;
        !          1234: begin
        !          1235:     Inc(FRow);
        !          1236:     if FRow > FScrollRowBottom then begin
        !          1237:         FRow := FScrollRowBottom;
        !          1238:         ScrollUp;
        !          1239:     end;
        !          1240: end;
        !          1241: 
        !          1242: 
        !          1243: {* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *}
        !          1244: procedure TScreen.CursorUp;
        !          1245: begin
        !          1246:     Dec(FRow);
        !          1247:     if FRow < 0 then begin
        !          1248:         Inc(FRow);
        !          1249:         ScrollDown;
        !          1250:     end;
        !          1251: end;
        !          1252: 
        !          1253: 
        !          1254: {* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *}
        !          1255: procedure TScreen.CursorRight;
        !          1256: begin
        !          1257:     Inc(FCol);
        !          1258:     if FCol >= FColCount then begin
        !          1259:         FCol := 0;
        !          1260:         CursorDown;
        !          1261:     end;
        !          1262: end;
        !          1263: 
        !          1264: 
        !          1265: {* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *}
        !          1266: procedure TScreen.CursorLeft;
        !          1267: begin
        !          1268:     Dec(FCol);
        !          1269:     if FCol < 0 then begin
        !          1270:         FCol := FColCount - 1;
        !          1271:         CursorUp;
        !          1272:     end;
        !          1273: end;
        !          1274: 
        !          1275: 
        !          1276: {* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *}
        !          1277: procedure TScreen.CarriageReturn;
        !          1278: begin
        !          1279:     FCol := 0;
        !          1280: end;
        !          1281: 
        !          1282: 
        !          1283: {* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *}
        !          1284: function TScreen.GetEscapeParam(From : Integer; var Value : Integer) : Integer;
        !          1285: begin
        !          1286:     while (From <= Length(FEscBuffer)) and (FEscBuffer[From] = ' ') do
        !          1287:         From := From + 1;
        !          1288: 
        !          1289:     Value := 0;
        !          1290:     while (From <= Length(FEscBuffer)) and (FEscBuffer[From] in ['0'..'9']) do begin
        !          1291:         Value := Value * 10 + Ord(FEscBuffer[From]) - Ord('0');
        !          1292:         From := From + 1;
        !          1293:     end;
        !          1294: 
        !          1295:     Result := From;
        !          1296: end;
        !          1297: 
        !          1298: 
        !          1299: {* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *}
        !          1300: procedure TScreen.UnimplementedEscape(EscCmd : Char);
        !          1301: {var
        !          1302:     Buf : String;}
        !          1303: begin
        !          1304:     DebugString('Unimplemented Escape Sequence: ' + FEscBuffer + EscCmd + #13 + #10);
        !          1305: {   Buf := FEscBuffer + EscCmd + #0;
        !          1306:     MessageBox(0, @Buf[1], 'Unimplemented Escape Sequence', MB_OK); }
        !          1307: end;
        !          1308: 
        !          1309: 
        !          1310: {* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *}
        !          1311: procedure TScreen.InvalidEscape(EscCmd : Char);
        !          1312: {var
        !          1313:     Buf : String;}
        !          1314: begin
        !          1315:     DebugString('Invalid Escape Sequence: ' + FEscBuffer + EscCmd + #13 + #10);
        !          1316: {   Buf := FEscBuffer + EscCmd + #0;
        !          1317:     MessageBox(0, @Buf[1], 'Invalid Escape Sequence', MB_OK); }
        !          1318: end;
        !          1319: 
        !          1320: 
        !          1321: {* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *}
        !          1322: procedure TScreen.ProcessESC_D;                   { Index                   }
        !          1323: begin
        !          1324:     UnimplementedEscape('D');
        !          1325: end;
        !          1326: 
        !          1327: 
        !          1328: {* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *}
        !          1329: { Move cursor Up, scroll down if necessary                                  }
        !          1330: procedure TScreen.ProcessESC_M;                   { Reverse index           }
        !          1331: begin
        !          1332:     Dec(FRow);
        !          1333:     if FRow < FScrollRowTop then begin
        !          1334:         FRow := FScrollRowTop;
        !          1335:         ScrollDown;
        !          1336:     end;
        !          1337: end;
        !          1338: 
        !          1339: 
        !          1340: {* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *}
        !          1341: procedure TScreen.ProcessESC_E;                   { Next line               }
        !          1342: begin
        !          1343:     UnimplementedEscape('E');
        !          1344: end;
        !          1345: 
        !          1346: 
        !          1347: {* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *}
        !          1348: procedure TScreen.ProcessCSI_u;                  { Restore Cursor          }
        !          1349: begin
        !          1350:     UnimplementedEscape('u');
        !          1351: end;
        !          1352: 
        !          1353: 
        !          1354: {* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *}
        !          1355: { IBM character set operation (not part of the ANSI standard)              }
        !          1356: { <ESC>[0I             => Set IBM character set                            }
        !          1357: { <ESC>[1;nnnI         => Literal mode for nnn next characters             }
        !          1358: { <ESC>[2;onoffI       => Switch carbon mode on (1) or off (0)             }
        !          1359: { <ESC>[3;ch;cl;sh;slI => Receive carbon mode keyboard code                }
        !          1360: { <ESC>[4I              => Select ANSI character set                        }
        !          1361: procedure TScreen.ProcessCSI_I;
        !          1362: var
        !          1363:     From, mode, nnn : Integer;
        !          1364:     ch, cl, sh, sl  : Integer;
        !          1365: begin
        !          1366:     From := GetEscapeParam(2, Mode);
        !          1367: 
        !          1368:     case Mode of
        !          1369:     0:  begin                { Select IBM character set                     }
        !          1370:             FNoXlat := TRUE;
        !          1371:         end;
        !          1372:     1: begin                { Set literal mode for next N characters       }
        !          1373:             if FEscBuffer[From] = ';' then
        !          1374:                 GetEscapeParam(From + 1, FCntLiteral)
        !          1375:             else
        !          1376:                 FCntLiteral := 1;
        !          1377:         end;
        !          1378:     2: begin                { Switch carbon mode on or off                 }
        !          1379:             if FEscBuffer[From] = ';' then
        !          1380:                 GetEscapeParam(From + 1, nnn)
        !          1381:             else
        !          1382:                 nnn := 0;
        !          1383:             FCarbonMode := (nnn <> 0);
        !          1384:         end;
        !          1385:     3: begin                { Receive carbon mode key code                 }
        !          1386:             ch := 0; cl := 0; sh := 0; sl := 0;
        !          1387:             if FEscBuffer[From] = ';' then begin
        !          1388:                 From := GetEscapeParam(From + 1, cl);
        !          1389:                 if FEscBuffer[From] = ';' then begin
        !          1390:                     From := GetEscapeParam(From + 1, ch);
        !          1391:                     if FEscBuffer[From] = ';' then begin
        !          1392:                         From := GetEscapeParam(From + 1, sl);
        !          1393:                         if FEscBuffer[From] = ';' then begin
        !          1394:                             GetEscapeParam(From + 1, sh);
        !          1395:                         end;
        !          1396:                     end;
        !          1397:                 end;
        !          1398:             end;
        !          1399:             DebugString('Special key ' +
        !          1400:                         IntToHex(ch, 2) + IntToHex(cl, 2) + ' ' +
        !          1401:                         IntToHex(sh, 2) + IntToHex(sl, 2));
        !          1402:         end;
        !          1403:     4: begin                { Select ANSI character set                    }
        !          1404:             FNoXlat := FALSE;
        !          1405:         end;
        !          1406:     else
        !          1407:         UnimplementedEscape('I');
        !          1408:     end;
        !          1409: end;
        !          1410: 
        !          1411: 
        !          1412: {* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *}
        !          1413: procedure TScreen.BackSpace;
        !          1414: begin
        !          1415:     if FCol > 0 then
        !          1416:         Dec(FCol);
        !          1417: end;
        !          1418: 
        !          1419: 
        !          1420: {* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *}
        !          1421: procedure TScreen.ClearScreen;
        !          1422: var
        !          1423:     Row : Integer;
        !          1424: begin
        !          1425:     for Row := 0 to FRowCount - 1 do
        !          1426:         Lines[Row].Clear(FAttribute);
        !          1427:     FRow := 0;
        !          1428:     FCol := 0;
        !          1429:     FAllInvalid := TRUE;
        !          1430: end;
        !          1431: 
        !          1432: 
        !          1433: {* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *}
        !          1434: procedure TScreen.InvClear;
        !          1435: begin
        !          1436:     with FInvRect do begin
        !          1437:         Top    := 9999;
        !          1438:         Left   := 9999;
        !          1439:         Right  := -1;
        !          1440:         Bottom := -1;
        !          1441:     end;
        !          1442:     FAllInvalid := FALSE;
        !          1443: end;
        !          1444: 
        !          1445: 
        !          1446: {* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *}
        !          1447: procedure TScreen.InvRect(nRow, nCol : Integer);
        !          1448: begin
        !          1449:     if not FAllInvalid then begin
        !          1450:         if FInvRect.Top > nRow then
        !          1451:             FInvRect.Top := nRow;
        !          1452:         if FInvRect.Bottom < nRow then
        !          1453:             FInvRect.Bottom := nRow;
        !          1454:         if FInvRect.Left > nCol then
        !          1455:             FInvRect.Left := nCol;
        !          1456:         if FInvRect.Right < nCol then
        !          1457:             FInvRect.Right := nCol;
        !          1458:     end;
        !          1459: end;
        !          1460: 
        !          1461: 
        !          1462: {* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *}
        !          1463: { The FLines array is inverted with the last host line at position 0 and
        !          1464:   the first host line as position FRowCount - 1. }
        !          1465: procedure Tscreen.SetLines(I : Integer; Value : TLine);
        !          1466: begin
        !          1467:     if I >= FRowCount then
        !          1468:         FLines^[0] := Value
        !          1469:     else
        !          1470:         FLines^[FRowCount - 1 - I] := Value;
        !          1471: end;
        !          1472: 
        !          1473: 
        !          1474: {* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *}
        !          1475: function TScreen.GetLines(I : Integer) : TLine;
        !          1476: begin
        !          1477:     if I >= FRowCount then
        !          1478:         Result := FLines^[0]
        !          1479:     else
        !          1480:         Result := FLines^[FRowCount - 1 - I];
        !          1481: end;
        !          1482: 
        !          1483: 
        !          1484: {* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *}
        !          1485: procedure TScreen.Eol;
        !          1486: begin
        !          1487:     with Lines[FRow] do begin
        !          1488:         FillChar(Txt[FCol], FColCount - FCol, ' ');
        !          1489:         FillChar(Att[FCol], (FColCount - FCol) * SizeOf(Att[FCol]), FAttribute);
        !          1490:     end;
        !          1491:     InvRect(Frow, FCol);
        !          1492:     InvRect(Frow, FColCount);
        !          1493: end;
        !          1494: 
        !          1495: 
        !          1496: {* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *}
        !          1497: procedure TScreen.Eop;
        !          1498: var
        !          1499:     Row : Integer;
        !          1500: begin
        !          1501:     Eol;
        !          1502:     for Row := FRow + 1 to FRowCount - 1 do
        !          1503:         Lines[Row].Clear(FAttribute);
        !          1504:     if FRow = 0 then
        !          1505:         FAllInvalid := TRUE
        !          1506:     else begin
        !          1507:        InvRect(FRow, 0);
        !          1508:        InvRect(FRowCount, FColCount);
        !          1509:     end;
        !          1510: end;
        !          1511: 
        !          1512: 
        !          1513: {* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *}
        !          1514: procedure TScreen.ProcessCSI_J;                  { Clear the screen         }
        !          1515: var
        !          1516:     Mode : Integer;
        !          1517:     Row  : Integer;
        !          1518: begin
        !          1519:     GetEscapeParam(2, Mode);
        !          1520:     case Mode of
        !          1521:     0: begin                                   { Cursor to end of screen    }
        !          1522:            FAttribute := F_WHITE;
        !          1523:            Eop;
        !          1524:        end;
        !          1525:     1: begin                                   { Start of screen to cursor  }
        !          1526:            for Row := 0 to FRow do
        !          1527:                Lines[Row].Clear(FAttribute);
        !          1528:            InvRect(0, 0);
        !          1529:            InvRect(FRow, FColCount);
        !          1530:        end;
        !          1531:     2: begin                                   { Entire screen              }
        !          1532:            if vtoCopyBackOnClear in FOptions then CopyScreenToBack;
        !          1533:            ClearScreen;
        !          1534:        end;
        !          1535:     else
        !          1536:         InvalidEscape('J');
        !          1537:     end;
        !          1538: end;
        !          1539: 
        !          1540: 
        !          1541: {* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *}
        !          1542: procedure TScreen.ProcessCSI_K;                  { Erase to End of Line    }
        !          1543: begin
        !          1544:     Eol;
        !          1545: end;
        !          1546: 
        !          1547: 
        !          1548: {* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *}
        !          1549: procedure TScreen.ProcessCSI_L;                   { Insert Line             }
        !          1550: var
        !          1551:     nLine : Integer;
        !          1552:     nRow  : Integer;
        !          1553:     Temp  : TLine;
        !          1554: begin
        !          1555:     FCol := 0;
        !          1556:     GetEscapeParam(2, nLine);
        !          1557:     if nLine = 0 then
        !          1558:         nLine := 1;
        !          1559: 
        !          1560:     if (FRow + nLine) > FScrollRowBottom then begin
        !          1561:         for nRow := FRow to FScrollRowBottom do
        !          1562:             Lines[nRow].Clear(FAttribute);
        !          1563:         Exit;
        !          1564:     end;
        !          1565: 
        !          1566:     for nRow := FScrollRowBottom downto FRow + nLine do begin
        !          1567:         Temp                := Lines[nRow];
        !          1568:         Lines[nRow]         := Lines[nRow - nLine];
        !          1569:         Lines[nRow - nLine] := Temp;
        !          1570:     end;
        !          1571: 
        !          1572:     for nRow := FRow to FRow + nLine - 1 do
        !          1573:         Lines[nRow].Clear(FAttribute);
        !          1574: 
        !          1575:     FAllInvalid := TRUE;
        !          1576: end;
        !          1577: 
        !          1578: 
        !          1579: {* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *}
        !          1580: procedure TScreen.ProcessCSI_M;                   { Delete Line             }
        !          1581: var
        !          1582:     nLine : Integer;
        !          1583:     nRow  : Integer;
        !          1584:     Temp  : TLine;
        !          1585: begin
        !          1586:     FAllInvalid := TRUE;
        !          1587:     FCol := 0;
        !          1588:     GetEscapeParam(2, nLine);
        !          1589:     if nLine = 0 then
        !          1590:         nLine := 1;
        !          1591: 
        !          1592:     if (FRow + nLine) > FScrollRowBottom then begin
        !          1593:         for nRow := FRow to FScrollRowBottom do
        !          1594:             Lines[nRow].Clear(FAttribute);
        !          1595:         Exit;
        !          1596:     end;
        !          1597: 
        !          1598:     for nRow := FRow to FRow + nLine - 1 do
        !          1599:         Lines[nRow].Clear(F_WHITE {FAttribute});  { 12/11/99 }
        !          1600:     for nRow := FRow to FScrollRowBottom - nLine do begin
        !          1601:         Temp                := Lines[nRow];
        !          1602:         Lines[nRow]         := Lines[nRow + nLine];
        !          1603:         Lines[nRow + nLine] := Temp;
        !          1604:     end;
        !          1605: end;
        !          1606: 
        !          1607: 
        !          1608: {* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *}
        !          1609: procedure TScreen.ProcessCSI_m_lc;               { Select Attributes       }
        !          1610: var
        !          1611:     From, n : Integer;
        !          1612: begin
        !          1613:     if FEscBuffer[1] <> '[' then
        !          1614:         Exit;
        !          1615: 
        !          1616:     if Length(FEscBuffer) < 2 then begin
        !          1617:         FAttribute    := F_WHITE;
        !          1618:         FReverseVideo := FALSE;
        !          1619:         Exit;
        !          1620:     end;
        !          1621: 
        !          1622:     From := 2;
        !          1623:     while From <= Length(FEscBuffer) do begin
        !          1624:         if FEscBuffer[From] in [' ', '[', ';'] then
        !          1625:             Inc(From)
        !          1626:         else begin
        !          1627:             From := GetEscapeParam(From, n);
        !          1628:             case n of
        !          1629:            0:  begin                   { All attributes off       }
        !          1630:                    FAttribute    := F_WHITE;
        !          1631:                    FReverseVideo := FALSE;
        !          1632:                     FUnderLine    := FALSE;
        !          1633:                 end;
        !          1634:            1:  begin                   { High intensity           }
        !          1635:                    FAttribute := FAttribute or F_INTENSE;
        !          1636:                end;
        !          1637:             4:  begin                   { Underline                }
        !          1638:                     FUnderLine := TRUE;
        !          1639:                 end;
        !          1640:            5:  begin                   { Blinking                 }
        !          1641:                    FAttribute := FAttribute or B_BLINK;
        !          1642:                end;
        !          1643:            7:  begin                   { Reverse video            }
        !          1644:                    FReverseVideo := TRUE;
        !          1645:                end;
        !          1646:            8:  begin                   { Secret                   }
        !          1647:                    FAttribute := 0;
        !          1648:                end;
        !          1649:            10: begin                   { Don't force high bit     }
        !          1650:                    FForceHighBit := FALSE;
        !          1651:                end;
        !          1652:            12: begin                   { Force high bit on        }
        !          1653:                    FForceHighBit := TRUE;
        !          1654:                end;
        !          1655:            22: begin                   { Normal intensity         }
        !          1656:                    FAttribute := FAttribute and (not F_INTENSE);
        !          1657:                end;
        !          1658:            27: begin                   { Normal characters        }
        !          1659:                    FAttribute    := F_WHITE;
        !          1660:                    FReverseVideo := FALSE;
        !          1661:                end;
        !          1662:            30, 31, 32, 33, 34, 35, 36, 37:
        !          1663:                 begin                  { Foreground color         }
        !          1664:                    FAttribute := (n mod 10) or (FAttribute and $F8);
        !          1665:                end;
        !          1666:            40, 41, 42, 43, 44, 45, 46, 47:
        !          1667:                 begin                   { Background color        }
        !          1668:                    FAttribute := ((n mod 10) shl 4) or (FAttribute and $8F);
        !          1669:                end;
        !          1670:            else
        !          1671:                InvalidEscape('m');
        !          1672:            end;
        !          1673:         end;
        !          1674:     end;
        !          1675:     if FReverseVideo then begin
        !          1676:         FAttribute := ((FAttribute and 7) shl 4) or
        !          1677:                       ((FAttribute shr 4) and 7) or
        !          1678:                       (FAttribute and $88);
        !          1679:     end;
        !          1680: end;
        !          1681: 
        !          1682: 
        !          1683: {* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *}
        !          1684: procedure TScreen.ProcessCSI_n_lc;                { Cursor position report  }
        !          1685: begin
        !          1686:     UnimplementedEscape('n');
        !          1687: end;
        !          1688: 
        !          1689: 
        !          1690: {* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *}
        !          1691: procedure TScreen.ProcessCSI_at;                 { Insert character        }
        !          1692: var
        !          1693:     nChar : Integer;
        !          1694:     nCnt  : Integer;
        !          1695:     nCol  : Integer;
        !          1696:     Line  : TLine;
        !          1697: begin
        !          1698:     GetEscapeParam(2, nChar);
        !          1699:     if nChar = 0 then
        !          1700:         nChar := 1;
        !          1701: 
        !          1702:     nCnt := FColCount - FCol - nChar;
        !          1703:     if nCnt <= 0 then begin
        !          1704:         Eol;
        !          1705:         Exit;
        !          1706:     end;
        !          1707: 
        !          1708:     Line := Lines[FRow];
        !          1709:     for nCol := FColCount - 1 downto FCol + nChar do begin
        !          1710:         Line.Txt[nCol] := Line.Txt[nCol - nChar];
        !          1711:         Line.Att[nCol] := Line.Att[nCol - nChar];
        !          1712:         InvRect(Frow, nCol);
        !          1713:     end;
        !          1714: 
        !          1715:     for nCol := FCol to FCol + nChar - 1 do begin
        !          1716:         Line.Txt[nCol] := ' ';
        !          1717:         Line.Att[nCol] := FAttribute;
        !          1718:         InvRect(Frow, nCol);
        !          1719:     end;
        !          1720: 
        !          1721: end;
        !          1722: 
        !          1723: 
        !          1724: {* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *}
        !          1725: procedure TScreen.ProcessCSI_r_lc;                { Scrolling margins       }
        !          1726: var
        !          1727:     From, Top, Bottom : Integer;
        !          1728: begin
        !          1729:     From := GetEscapeParam(2, Top);
        !          1730:     if Top = 0 then begin                         { Default = full screen   }
        !          1731:         FScrollRowTop    := 0;
        !          1732:         FScrollRowBottom := FRowCount - 1;
        !          1733:     end
        !          1734:     else begin
        !          1735:         while (From <= Length(FEscBuffer)) and (FEscBuffer[From] = ' ') do
        !          1736:             From := From + 1;
        !          1737:         if FEscBuffer[From] = ';' then
        !          1738:             GetEscapeParam(From + 1, Bottom)
        !          1739:         else
        !          1740:             Bottom := 1;
        !          1741: 
        !          1742:         FScrollRowTop    := Top    - 1;
        !          1743:         FScrollRowBottom := Bottom - 1;
        !          1744: 
        !          1745:         if (FScrollRowBottom <= FScrollRowTop) or
        !          1746:            (FScrollRowTop < 0) or
        !          1747:            (FScrollRowBottom >= FRowCount) then begin
        !          1748:             FScrollRowTop    := 0;
        !          1749:             FScrollRowBottom := FRowCount - 1;
        !          1750:         end;
        !          1751:     end;
        !          1752: end;
        !          1753: 
        !          1754: 
        !          1755: {* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *}
        !          1756: procedure TScreen.ProcessCSI_s_lc;                { Save cursor location    }
        !          1757: begin
        !          1758:     ProcessCSI_7;
        !          1759: end;
        !          1760: 
        !          1761: 
        !          1762: {* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *}
        !          1763: procedure TScreen.ProcessCSI_u_lc;                { Restore cursor location }
        !          1764: begin
        !          1765:     ProcessCSI_8;
        !          1766: end;
        !          1767: 
        !          1768: 
        !          1769: {* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *}
        !          1770: procedure TScreen.ProcessCSI_7;                   { Save cursor location    }
        !          1771: begin
        !          1772:     FRowSaved := FRow;
        !          1773:     FColSaved := FCol;
        !          1774: end;
        !          1775: 
        !          1776: 
        !          1777: {* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *}
        !          1778: procedure TScreen.ProcessCSI_8;                   { Restore cursor location }
        !          1779: begin
        !          1780:     if FRowSaved = -1 then
        !          1781:         GotoXY(0, 0)
        !          1782:     else
        !          1783:         GotoXY(FColSaved, FRowSaved);
        !          1784:     FRowSaved := -1;
        !          1785:     FColSaved := -1;
        !          1786: end;
        !          1787: 
        !          1788: 
        !          1789: {* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *}
        !          1790: procedure TScreen.ProcessCSI_H;                   { Set Cursor Position     }
        !          1791: var
        !          1792:     From, Row, Col : Integer;
        !          1793: begin
        !          1794:     From := GetEscapeParam(2, Row);
        !          1795:     while (From <= Length(FEscBuffer)) and (FEscBuffer[From] = ' ') do
        !          1796:         From := From + 1;
        !          1797:     if FEscBuffer[From] = ';' then
        !          1798:         GetEscapeParam(From + 1, Col)
        !          1799:     else
        !          1800:         Col := 1;
        !          1801: 
        !          1802:     GotoXY(Col - 1, Row - 1);
        !          1803: end;
        !          1804: 
        !          1805: 
        !          1806: {* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *}
        !          1807: procedure TScreen.ProcessCSI_h_lc;                { Terminal mode set       }
        !          1808: var
        !          1809:     Priv : Boolean;
        !          1810:     Mode : Integer;
        !          1811: begin
        !          1812:     if FEscBuffer[1] <> '[' then begin
        !          1813:         UnimplementedEscape('h');
        !          1814:         Exit;
        !          1815:     end;
        !          1816: 
        !          1817:     Priv := (FEscBuffer[2] = '?');
        !          1818:     if not Priv then begin
        !          1819:         UnimplementedEscape('h');
        !          1820:         Exit;
        !          1821:     end;
        !          1822: 
        !          1823:     GetEscapeParam(3, Mode);
        !          1824:     case Mode of
        !          1825:     1 :  { ANSI cursor keys }
        !          1826:          FCKeyMode := TRUE;
        !          1827:     4 :  { Smooth scroll OFF }
        !          1828:          { Ignore };
        !          1829:     7:   { Auto-wrap OFF }
        !          1830:          FAutoWrap := TRUE;
        !          1831:     25:  { Cursor visible }
        !          1832:          begin
        !          1833:              FCursorOff := FALSE;
        !          1834:              if Assigned(FOnCursorVisible) then
        !          1835:                  FOnCursorVisible(Self);
        !          1836:          end;
        !          1837:     else
        !          1838:         UnimplementedEscape('h');
        !          1839:     end;
        !          1840: end;
        !          1841: 
        !          1842: 
        !          1843: {* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *}
        !          1844: procedure TScreen.ProcessCSI_l_lc;                { Terminal mode reset     }
        !          1845: var
        !          1846:     Priv : Boolean;
        !          1847:     Mode : Integer;
        !          1848: begin
        !          1849:     if FEscBuffer[1] <> '[' then begin
        !          1850:         UnimplementedEscape('l');
        !          1851:         Exit;
        !          1852:     end;
        !          1853: 
        !          1854:     Priv := (FEscBuffer[2] = '?');
        !          1855:     if not Priv then begin
        !          1856:         UnimplementedEscape('l');
        !          1857:         Exit;
        !          1858:     end;
        !          1859: 
        !          1860:     GetEscapeParam(3, Mode);
        !          1861:     case Mode of
        !          1862:     1 :  { ANSI cursor keys }
        !          1863:          FCKeyMode := FALSE;
        !          1864:     4 :  { Smooth scroll OFF }
        !          1865:          { Ignore };
        !          1866:     7:   { Auto-wrap OFF }
        !          1867:          FAutoWrap := FALSE;
        !          1868:     25:  { Cursor invisible }
        !          1869:          begin
        !          1870:              FCursorOff := TRUE;
        !          1871:              if Assigned(FOnCursorVisible) then
        !          1872:                  FOnCursorVisible(Self);
        !          1873:          end;
        !          1874:     else
        !          1875:         UnimplementedEscape('l');
        !          1876:     end;
        !          1877: end;
        !          1878: 
        !          1879: 
        !          1880: {* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *}
        !          1881: procedure TScreen.ProcessCSI_A;                   { Cursor Up               }
        !          1882: var
        !          1883:     Row : Integer;
        !          1884: begin
        !          1885:     GetEscapeParam(2, Row);
        !          1886:     if Row <= 0 then
        !          1887:         Row := 1;
        !          1888:     FRow := FRow - Row;
        !          1889:     if FRow < 0 then
        !          1890:         FRow := 0;
        !          1891: end;
        !          1892: 
        !          1893: 
        !          1894: {* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *}
        !          1895: procedure TScreen.ProcessCSI_B;                   { Cursor Down             }
        !          1896: var
        !          1897:     Row : Integer;
        !          1898: begin
        !          1899:     GetEscapeParam(2, Row);
        !          1900:     if Row <= 0 then
        !          1901:         Row := 1;
        !          1902:     FRow := FRow + Row;
        !          1903:     if FRow >= FRowCount then
        !          1904:         FRow := FRowCount - 1;
        !          1905: end;
        !          1906: 
        !          1907: 
        !          1908: {* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *}
        !          1909: procedure TScreen.ProcessCSI_C;                   { Cursor Right            }
        !          1910: var
        !          1911:     Col : Integer;
        !          1912: begin
        !          1913:     GetEscapeParam(2, Col);
        !          1914:     if Col <= 0 then
        !          1915:         Col := 1;
        !          1916:     FCol := FCol + Col;
        !          1917:     if FCol >= FColCount then begin
        !          1918:         if FAutoWrap then begin
        !          1919:             FCol := FCol - FColCount;
        !          1920:             Inc(FRow);
        !          1921:             if FRow >= FRowCount then
        !          1922:                 FRow := FRowCount - 1;
        !          1923:         end
        !          1924:         else
        !          1925:             FCol := FColCount - 1;
        !          1926:     end;
        !          1927: end;
        !          1928: 
        !          1929: 
        !          1930: {* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *}
        !          1931: procedure TScreen.ProcessCSI_D;                   { Cursor Left             }
        !          1932: var
        !          1933:     Col : Integer;
        !          1934: begin
        !          1935:     GetEscapeParam(2, Col);
        !          1936:     if Col <= 0 then
        !          1937:         Col := 1;
        !          1938:     FCol := FCol - Col;
        !          1939:     if FCol < 0 then
        !          1940:         FCol := 0;
        !          1941: end;
        !          1942: 
        !          1943: 
        !          1944: {* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *}
        !          1945: procedure TScreen.ProcessCSI_P;                   { Delete Character        }
        !          1946: var
        !          1947:     Count : Integer;
        !          1948:     nCol  : Integer;
        !          1949: begin
        !          1950:     GetEscapeParam(2, Count);
        !          1951:     if Count <= 0 then
        !          1952:         Count := 1;
        !          1953:     with Lines[FRow] do begin
        !          1954:         for nCol := Fcol to FColCount - Count - 1 do begin
        !          1955:             Txt[nCol] := Txt[nCol + Count];
        !          1956:             Att[nCol] := Att[nCol + Count];
        !          1957:         end;
        !          1958:         for nCol := FcolCount - Count - 1 to FColCount - 1 do begin
        !          1959:             Txt[nCol] := ' ';
        !          1960:             Att[nCol] := F_WHITE;
        !          1961:         end;
        !          1962:     end;
        !          1963:     InvRect(Frow, FCol);
        !          1964:     InvRect(Frow, FColCount);
        !          1965: end;
        !          1966: 
        !          1967: 
        !          1968: {* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *}
        !          1969: procedure TScreen.ProcessCSI_S;                   { Scroll up               }
        !          1970: begin
        !          1971:     ScrollUp;
        !          1972: end;
        !          1973: 
        !          1974: 
        !          1975: {* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *}
        !          1976: procedure TScreen.ProcessCSI_T;                  { Scroll down             }
        !          1977: begin
        !          1978:     UnimplementedEscape('T');
        !          1979: end;
        !          1980: 
        !          1981: 
        !          1982: {* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *}
        !          1983: procedure TScreen.process_charset_G0(EscCmd : Char); { G0 character set     }
        !          1984: begin
        !          1985:     case EscCmd of
        !          1986:     '0': begin
        !          1987:              FCharSetG0       := EscCmd;
        !          1988:              FXlatInputTable  := @ibm_iso8859_1_G1;
        !          1989:              FXlatOutputTable := @ibm_iso8859_1_G1;
        !          1990:              FNoXlat          := FNoXlatInitial;
        !          1991: {             FNoXlat          := FALSE;}
        !          1992:          end;
        !          1993:     'B': begin
        !          1994:              FCharSetG0       := EscCmd;
        !          1995:              FXlatInputTable  := @ibm_iso8859_1_G0;
        !          1996:              FXlatOutputTable := @ibm_iso8859_1_G0;
        !          1997:              FNoXlat          := FNoXlatInitial;
        !          1998:          end;
        !          1999:     else
        !          2000:         InvalidEscape(EscCmd);
        !          2001:     end;
        !          2002: end;
        !          2003: 
        !          2004: 
        !          2005: {* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *}
        !          2006: procedure TScreen.process_charset_G1(EscCmd : Char); { G1 character set     }
        !          2007: begin
        !          2008:     FCharSetG1 := EscCmd;
        !          2009: end;
        !          2010: 
        !          2011: 
        !          2012: {* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *}
        !          2013: procedure TScreen.process_charset_G2(EscCmd : Char); { G2 character set     }
        !          2014: begin
        !          2015:     FCharSetG2 := EscCmd;
        !          2016: end;
        !          2017: 
        !          2018: 
        !          2019: {* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *}
        !          2020: procedure TScreen.process_charset_G3(EscCmd : Char); { G2 character set     }
        !          2021: begin
        !          2022:     FCharSetG3 := EscCmd;
        !          2023: end;
        !          2024: 
        !          2025: 
        !          2026: {* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *}
        !          2027: procedure TScreen.ProcessEscape(EscCmd : Char);
        !          2028: begin
        !          2029:     if Length(FEscBuffer) = 0 then begin
        !          2030:         case EscCmd of
        !          2031:         'D': ProcessESC_D;         { Index                   }
        !          2032:         'M': ProcessESC_M;         { Reverse index           }
        !          2033:         'E': ProcessESC_E;         { Next line               }
        !          2034:         'H': ;                     { Tabulation set          }
        !          2035:         '7': ProcessCSI_7;         { Save cursor             }
        !          2036:         '8': ProcessCSI_8;      { Restore Cursor          }
        !          2037:         '=': ;     { VT52 }        { Enter Alternate keypad  }
        !          2038:         '>': ;     { VT52 }        { Exit Alternate keypad   }
        !          2039:         '<': ;     { VT52 }        { Enter ANSI mode         }
        !          2040:         else
        !          2041:             InvalidEscape(EscCmd);
        !          2042:             WriteLiteralChar(EscCmd);
        !          2043:         end;
        !          2044: 
        !          2045:         Exit;
        !          2046:     end;
        !          2047: 
        !          2048:     case FEscBuffer[1] of
        !          2049:     ' ': begin
        !          2050:              case EscCmd of
        !          2051:              'F': ;
        !          2052:              else
        !          2053:                  InvalidEscape(EscCmd);
        !          2054:              end;
        !          2055:          end;
        !          2056:     '[': begin
        !          2057:              case EscCmd of
        !          2058:              'I': ProcessCSI_I;                { Select IBM char set     }
        !          2059:                                                 { Extension F. Piette !!  }
        !          2060:              'J': ProcessCSI_J;                { Clear the screen        }
        !          2061:              'K': ProcessCSI_K;                { Erase to End of Line    }
        !          2062:              'L': ProcessCSI_L;                { Insert Line             }
        !          2063:              'M': ProcessCSI_M;                { Delete Line             }
        !          2064:              'm': ProcessCSI_m_lc;             { Select Attributes       }
        !          2065:              'n': ProcessCSI_n_lc;             { Cursor position report  }
        !          2066:              '@': ProcessCSI_at;               { Insert character        }
        !          2067:              'r': ProcessCSI_r_lc;             { Set Top and Bottom marg }
        !          2068:              's': ProcessCSI_s_lc;             { Save cursor location    }
        !          2069:              'u': ProcessCSI_u_lc;             { Restore cursor location }
        !          2070:              'H': ProcessCSI_H;                { Set Cursor Position     }
        !          2071:              'f': ProcessCSI_H;                { Set Cursor Position     }
        !          2072:              'g': ;                            { Tabulation Clear        }
        !          2073:              'h': ProcessCSI_h_lc;             { Terminal mode set       }
        !          2074:              'l': ProcessCSI_l_lc;             { Terminal mode reset     }
        !          2075:              'A': ProcessCSI_A;                { Cursor Up               }
        !          2076:              'B': ProcessCSI_B;                { Cursor Down             }
        !          2077:              'C': ProcessCSI_C;                { Cursor Right            }
        !          2078:              'D': ProcessCSI_D;                { Cursor Left             }
        !          2079:              'P': ProcessCSI_P;                { Delete Character        }
        !          2080:              'S': ProcessCSI_S;                { Scroll up               }
        !          2081:              'T': ProcessCSI_T;                { Scroll down             }
        !          2082:              '>': ;                            {                         }
        !          2083:              else
        !          2084:                  InvalidEscape(EscCmd);
        !          2085:              end;
        !          2086:          end;
        !          2087:     '(': process_charset_G0(EscCmd);           { G0 character set        }
        !          2088:     ')': process_charset_G1(EscCmd);           { G1 character set        }
        !          2089:     '*': process_charset_G2(EscCmd);           { G2 character set        }
        !          2090:     '+': process_charset_G3(EscCmd);           { G3 character set        }
        !          2091:     else
        !          2092:         InvalidEscape(EscCmd);
        !          2093:     end;
        !          2094: end;
        !          2095: 
        !          2096: 
        !          2097: {* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *}
        !          2098: procedure TScreen.WriteLiteralChar(Ch : Char);
        !          2099: var
        !          2100:     Line : TLine;
        !          2101: begin
        !          2102:     if FCol >= FColCount then begin
        !          2103:         if FAutoWrap then begin
        !          2104:             FCol := 0;
        !          2105:             Inc(FRow);
        !          2106:             if FRow >= FRowCount then begin
        !          2107:                 Dec(FRow);
        !          2108:                 ScrollUp;
        !          2109:             end;
        !          2110:         end;
        !          2111:     end;
        !          2112: 
        !          2113:     if FForceHighBit then
        !          2114:         Ch := Chr(ord(ch) or $80);
        !          2115: 
        !          2116:     Line := Lines[FRow];
        !          2117:     Line.Txt[FCol] := Ch;
        !          2118:     Line.Att[FCol] := FAttribute;
        !          2119:     InvRect(Frow, FCol);
        !          2120: 
        !          2121:     if FCol < High(Line.Txt) then
        !          2122:         Inc(FCol);
        !          2123: end;
        !          2124: 
        !          2125: 
        !          2126: {* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *}
        !          2127: procedure TScreen.SetAttr(Att : Char);
        !          2128: begin
        !          2129:      { Not implemented }
        !          2130: end;
        !          2131: 
        !          2132: 
        !          2133: {* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *}
        !          2134: { Write a single character at current cursor location.                      }
        !          2135: { Update cursor position.                                                   }
        !          2136: procedure TScreen.WriteChar(Ch : Char);
        !          2137: var
        !          2138:     bProcess : Boolean;
        !          2139: begin
        !          2140:     if FCntLiteral > 0 then begin
        !          2141:         if (FCntLiteral and 1) <> 0 then
        !          2142:             WriteLiteralChar(Ch)
        !          2143:         else
        !          2144:             SetAttr(Ch);
        !          2145:         Dec(FCntLiteral);
        !          2146:         Exit;
        !          2147:     end;
        !          2148: 
        !          2149:     if FNoXlat then
        !          2150:         Ch := FXlatInputTable^[ord(Ch)];
        !          2151: 
        !          2152:     if FEscFLag then begin
        !          2153:         bProcess := FALSE;
        !          2154:         if (Length(FEscBuffer) = 0) and
        !          2155:            (Ch in ['D', 'M', 'E', 'H', '7', '8', '=', '>', '<']) then
        !          2156:              bProcess := TRUE
        !          2157:         else if (Length(FEscBuffer) = 1) and
        !          2158:            (FEscBuffer[1] in ['(', ')', '*', '+']) then
        !          2159:             bProcess := TRUE
        !          2160:         else if (Ch in ['0'..'9', ';', '?', ' ']) or
        !          2161:                 ((Length(FEscBuffer) = 0) and
        !          2162:                  (ch in ['[', '(', ')', '*', '+'])) then begin
        !          2163:             FEscBuffer := FEscBuffer + Ch;
        !          2164:             if Length(FEscBuffer) >= High(FEscBuffer) then begin
        !          2165:                 MessageBeep(MB_ICONASTERISK);
        !          2166:                 FEscBuffer := '';
        !          2167:                 FEscFlag   := FALSE;
        !          2168:             end;
        !          2169:         end
        !          2170:         else
        !          2171:             bProcess := TRUE;
        !          2172: 
        !          2173:         if bProcess then begin
        !          2174:             ProcessEscape(Ch);
        !          2175:             FEscBuffer := '';
        !          2176:             FEscFlag   := FALSE;
        !          2177:         end;
        !          2178: 
        !          2179:         Exit;
        !          2180:     end;
        !          2181: 
        !          2182:     case Ch of
        !          2183:     #0:  ;
        !          2184:     #7:  MessageBeep(MB_ICONASTERISK);
        !          2185:     #8:  BackSpace;
        !          2186:     #9:  begin
        !          2187:              repeat
        !          2188:                  Inc(FCol);
        !          2189:              until (FCol Mod 8) = 0;
        !          2190:          end;
        !          2191:     #10: begin
        !          2192:              CursorDown;
        !          2193:              if FAutoCR then
        !          2194:                  CarriageReturn;
        !          2195:          end;
        !          2196:     #13: begin
        !          2197:              CarriageReturn;
        !          2198:              if FAutoLF then
        !          2199:                  CursorDown;
        !          2200:          end;
        !          2201:     #14: begin
        !          2202:              FXlatInputTable  := @ibm_iso8859_1_G1;
        !          2203:              FXlatOutputTable := @ibm_iso8859_1_G1;
        !          2204:          end;
        !          2205:     #15: begin
        !          2206:              FXlatInputTable  := @ibm_iso8859_1_G0;
        !          2207:              FXlatOutputTable := @ibm_iso8859_1_G0;
        !          2208:          end;
        !          2209:     #27: begin
        !          2210:              FEscBuffer := '';
        !          2211:              FEscFlag   := TRUE;
        !          2212:          end;
        !          2213:     else
        !          2214:         WriteLiteralChar(Ch);
        !          2215:     end;
        !          2216: end;
        !          2217: 
        !          2218: 
        !          2219: {* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *}
        !          2220: { Write characters at current cursor location. Update cursor position.      }
        !          2221: procedure TScreen.WriteStr(Str : String);
        !          2222: var
        !          2223:     I : Integer;
        !          2224: begin
        !          2225:     for I := 1 to Length(Str) do
        !          2226:         WriteChar(Str[I]);
        !          2227: end;
        !          2228: 
        !          2229: 
        !          2230: {* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *}
        !          2231: { Read characters from the cursor to end of line                            }
        !          2232: function TScreen.ReadStr : String;
        !          2233: var
        !          2234:     Line : TLine;
        !          2235:     Len  : Integer;
        !          2236: begin
        !          2237:     Line := Lines[FRow];
        !          2238:     Len  := FColCount - FCol;
        !          2239:     if Len <= 0 then
        !          2240:         Result := ''
        !          2241:     else begin
        !          2242:         SetLength(Result, Len);
        !          2243:         Move(Line.Txt[FCol], Result[1], Len);
        !          2244:     end;
        !          2245: end;
        !          2246: 
        !          2247: 
        !          2248: {* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *}
        !          2249: procedure TScreen.GotoXY(X, Y : Integer);
        !          2250: begin
        !          2251:     if X < 0 then
        !          2252:         FCol := 0
        !          2253:     else if X >= FColCount then
        !          2254:         FCol := FColCount - 1
        !          2255:     else
        !          2256:         FCol := X;
        !          2257: 
        !          2258:     if Y < 0 then
        !          2259:         FRow := 0
        !          2260:     else if Y >= FRowCount then
        !          2261:         FRow := FRowCount - 1
        !          2262:     else
        !          2263:         FRow := Y;
        !          2264: end;
        !          2265: 
        !          2266: 
        !          2267: {* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *}
        !          2268: procedure TCustomEmulVT.SetCaret;
        !          2269: begin
        !          2270: {$IFDEF CHAR_ZOOM}
        !          2271:     SetCaretPos(FCharPos[FScreen.FCol] + LeftMargin + 2,
        !          2272:                 FLinePos[FScreen.FRow - FTopLine] + TopMargin + 3);
        !          2273: {$ELSE}
        !          2274:     SetCaretPos(FScreen.FCol * FCharWidth + LeftMargin,
        !          2275:                 (FScreen.FRow - FTopLine) * FLineHeight + TopMargin);
        !          2276: {$ENDIF}
        !          2277: end;
        !          2278: 
        !          2279: 
        !          2280: {* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *}
        !          2281: { Adjusts the scrollbar properties to match the number of host and scrollback
        !          2282:   lines that we can scroll through. }
        !          2283: procedure TCustomEmulVT.AdjustScrollBar;
        !          2284: var
        !          2285:     VisibleLines    : Integer;
        !          2286: begin
        !          2287:     FVScrollBar.Min := FScreen.FBackEndRow;
        !          2288: {$IFDEF CHAR_ZOOM}
        !          2289:     VisibleLines := Trunc((Height - TopMargin - BottomMargin) / (LineHeight * FLineZoom));
        !          2290: {$ELSE}
        !          2291:     VisibleLines := (Height - TopMargin - BottomMargin) Div LineHeight;
        !          2292: {$ENDIF}
        !          2293:     if VisibleLines > FScreen.FRowCount then
        !          2294:         VisibleLines := FScreen.FRowCount;
        !          2295:     FVScrollBar.Max         := FScreen.FRowCount - VisibleLines;
        !          2296:     FVScrollBar.Position    := FTopLine;
        !          2297:     FVScrollBar.SmallChange := 1;
        !          2298:     FVScrollBar.LargeChange := VisibleLines;
        !          2299:     FVScrollBar.Enabled     := FVScrollBar.Max > FVScrollBar.Min;
        !          2300: end;
        !          2301: 
        !          2302: 
        !          2303: {* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *}
        !          2304: procedure TCustomEmulVT.Clear;
        !          2305: begin
        !          2306:     FScreen.ClearScreen;
        !          2307: end;
        !          2308: 
        !          2309: 
        !          2310: {* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *}
        !          2311: procedure TCustomEmulVT.SetCursor(Row, Col : Integer);
        !          2312: begin
        !          2313:     FScreen.GotoXY(Col - 1, Row - 1);
        !          2314: {    SetCaret; }
        !          2315: end;
        !          2316: 
        !          2317: 
        !          2318: {* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *}
        !          2319: procedure TCustomEmulVT.WriteChar(Ch : Char);
        !          2320: begin
        !          2321:     if FCaretCreated and FCaretShown then begin
        !          2322:         HideCaret(Handle);
        !          2323:         FCaretShown := FALSE;
        !          2324:     end;
        !          2325: 
        !          2326:     if FLog then
        !          2327:         Write(FFileHandle, Ch);
        !          2328:     FScreen.WriteChar(ch);
        !          2329:     if FAutoRepaint then
        !          2330:         UpdateScreen;
        !          2331: {    SetCaret;   }
        !          2332: end;
        !          2333: 
        !          2334: 
        !          2335: {* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *}
        !          2336: procedure TCustomEmulVT.WriteStr(Str : String);
        !          2337: var
        !          2338:     I : Integer;
        !          2339: begin
        !          2340:     if FCaretCreated and FCaretShown then begin
        !          2341:         HideCaret(Handle);
        !          2342:         FCaretShown := FALSE;
        !          2343:     end;
        !          2344: 
        !          2345:     for I := 1 to Length(Str) do begin
        !          2346:         if FLog then
        !          2347:             Write(FFileHandle, Str[I]);
        !          2348:         FScreen.WriteChar(Str[I]);
        !          2349:     end;
        !          2350:     if FAutoRepaint then
        !          2351:         UpdateScreen;
        !          2352: {    SetCaret; }
        !          2353: end;
        !          2354: 
        !          2355: 
        !          2356: {* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *}
        !          2357: procedure TCustomEmulVT.WriteBuffer(Buffer : Pointer; Len : Integer);
        !          2358: var
        !          2359:     I : Integer;
        !          2360: begin
        !          2361:     if FCaretCreated and FCaretShown then begin
        !          2362:         HideCaret(Handle);
        !          2363:         FCaretShown := FALSE;
        !          2364:     end;
        !          2365: 
        !          2366:     for I := 0 to Len - 1 do begin
        !          2367:         if FLog then
        !          2368:             Write(FFileHandle, PChar(Buffer)[I]);
        !          2369:         FScreen.WriteChar(PChar(Buffer)[I]);
        !          2370:     end;
        !          2371:     if FAutoRepaint then
        !          2372:         UpdateScreen;
        !          2373: {    SetCaret; }
        !          2374: end;
        !          2375: 
        !          2376: 
        !          2377: {* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *}
        !          2378: function TCustomEmulVT.ReadStr : String;
        !          2379: begin
        !          2380:     Result := FScreen.ReadStr;
        !          2381: end;
        !          2382: 
        !          2383: 
        !          2384: {* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *}
        !          2385: procedure TCustomEmulVT.CopyHostScreen;
        !          2386: begin
        !          2387:     FScreen.CopyScreenToBack;
        !          2388:     AdjustScrollBar;
        !          2389: end;
        !          2390: 
        !          2391: 
        !          2392: {* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *}
        !          2393: constructor TCustomEmulVT.Create(AOwner: TComponent);
        !          2394: type
        !          2395:     TMyLogPalette = record
        !          2396:         palVersion: Word;
        !          2397:         palNumEntries: Word;
        !          2398:         palPalEntry: array[0..NumPaletteEntries - 1] of TPaletteEntry;
        !          2399:     end;
        !          2400:     TPLogPalette = ^TLogPalette;
        !          2401: var
        !          2402:     plgpl      : ^TMyLogPalette;
        !          2403:     I          : Integer;
        !          2404: begin
        !          2405:     inherited Create(AOwner);
        !          2406:     ControlStyle := ControlStyle + [csOpaque];
        !          2407: 
        !          2408:     New(plgpl);
        !          2409:     plgpl^.palNumEntries := High(plgpl^.palPalEntry) + 1;
        !          2410:     plgpl^.palVersion    := $300;
        !          2411: 
        !          2412:     FPaletteEntries[0].peRed    := 0;                { Black }
        !          2413:     FPaletteEntries[0].peGreen  := 0;
        !          2414:     FPaletteEntries[0].peBlue   := 0;
        !          2415:     FPaletteEntries[1].peRed    := 168;              { Red }
        !          2416:     FPaletteEntries[1].peGreen  := 0;
        !          2417:     FPaletteEntries[1].peBlue   := 0;
        !          2418:     FPaletteEntries[2].peRed    := 0;                { Green  }
        !          2419:     FPaletteEntries[2].peGreen  := 168;
        !          2420:     FPaletteEntries[2].peBlue   := 0;
        !          2421:     FPaletteEntries[3].peRed    := 168;              { Yellow }
        !          2422:     FPaletteEntries[3].peGreen  := 168;
        !          2423:     FPaletteEntries[3].peBlue   := 0;
        !          2424:     FPaletteEntries[4].peRed    := 0;                { Dark Blue }
        !          2425:     FPaletteEntries[4].peGreen  := 0;
        !          2426:     FPaletteEntries[4].peBlue   := 168;
        !          2427:     FPaletteEntries[5].peRed    := 168;              { Magenta }
        !          2428:     FPaletteEntries[5].peGreen  := 0;
        !          2429:     FPaletteEntries[5].peBlue   := 168;
        !          2430:     FPaletteEntries[6].peRed    := 0;                { Cyan }
        !          2431:     FPaletteEntries[6].peGreen  := 112;
        !          2432:     FPaletteEntries[6].peBlue   := 216;
        !          2433:     FPaletteEntries[7].peRed    := 200;              { White }
        !          2434:     FPaletteEntries[7].peGreen  := 200;
        !          2435:     FPaletteEntries[7].peBlue   := 200;
        !          2436:     FPaletteEntries[8].peRed    := 84;               { Grey }
        !          2437:     FPaletteEntries[8].peGreen  := 84;
        !          2438:     FPaletteEntries[8].peBlue   := 84;
        !          2439:     FPaletteEntries[9].peRed    := 84;               { Red Highlight }
        !          2440:     FPaletteEntries[9].peGreen  := 84;
        !          2441:     FPaletteEntries[9].peBlue   := 212;
        !          2442:     FPaletteEntries[10].peRed   := 84;               { Green Highlight }
        !          2443:     FPaletteEntries[10].peGreen := 255;
        !          2444:     FPaletteEntries[10].peBlue  := 84;
        !          2445:     FPaletteEntries[11].peRed   := 255;              { Yellow Highlight }
        !          2446:     FPaletteEntries[11].peGreen := 255;
        !          2447:     FPaletteEntries[11].peBlue  := 84;
        !          2448:     FPaletteEntries[12].peRed   := 84;               { Blue Highlight }
        !          2449:     FPaletteEntries[12].peGreen := 84;
        !          2450:     FPaletteEntries[12].peBlue  := 255;
        !          2451:     FPaletteEntries[13].peRed   := 255;              { Magenta Highlight }
        !          2452:     FPaletteEntries[13].peGreen := 84;
        !          2453:     FPaletteEntries[13].peBlue  := 255;
        !          2454:     FPaletteEntries[14].peRed   := 84;               { Cyan highlight }
        !          2455:     FPaletteEntries[14].peGreen := 255;
        !          2456:     FPaletteEntries[14].peBlue  := 255;
        !          2457:     FPaletteEntries[15].peRed   := 255;              { White Highlight }
        !          2458:     FPaletteEntries[15].peGreen := 255;
        !          2459:     FPaletteEntries[15].peBlue  := 255;
        !          2460: 
        !          2461:     for I := 0 to High(plgpl^.palPalEntry) do begin
        !          2462:         plgpl^.PalPalEntry[I].peRed   := FPaletteEntries[I].peRed;
        !          2463:         plgpl^.PalPalEntry[I].peGreen := FPaletteEntries[I].peGreen;
        !          2464:         plgpl^.PalPalEntry[I].peBlue  := FPaletteEntries[I].peBlue;
        !          2465:         plgpl^.PalPalEntry[I].peFlags := PC_NOCOLLAPSE;
        !          2466:     end;
        !          2467: 
        !          2468:     FPal := CreatePalette(TPLogPalette(plgpl)^);
        !          2469:     Dispose(plgpl);
        !          2470: 
        !          2471:     FScreen             := TScreen.Create;
        !          2472:     FVScrollBar         := TScrollBar.Create(Self);
        !          2473:     FFont               := TFont.Create;
        !          2474:     FFont.Name          := 'Terminal';
        !          2475:     FFont.Size          := 12;
        !          2476:     FFont.Style         := [];
        !          2477:     FCharZoom           := 1.0;
        !          2478:     FLineZoom           := 1.0;
        !          2479:     SetupFont;
        !          2480: 
        !          2481:     FScreen.FXlatInputTable     := @ibm_iso8859_1_G0;
        !          2482:     FScreen.FXlatOutputTable    := @ibm_iso8859_1_G0;
        !          2483:     FScreen.OnCursorVisible     := CursorVisibleEvent;
        !          2484: 
        !          2485:     FCursorVisible      := TRUE;
        !          2486:     Width               := 250;
        !          2487:     Height              := 100;
        !          2488:     FBorderStyle        := bsSingle;
        !          2489:     FBorderWidth        := 1;
        !          2490:     FAutoRepaint        := TRUE;
        !          2491:     FFkeys              := 1;
        !          2492:     FGraphicDraw        := FALSE;
        !          2493: 
        !          2494:     with FVScrollBar do begin
        !          2495:         Parent   := Self;
        !          2496:         Kind     := sbVertical;
        !          2497:         Width    := 16;
        !          2498:         Visible  := TRUE;
        !          2499:         Align    := alRight;
        !          2500:         OnScroll := VScrollBarScroll;
        !          2501:     end;
        !          2502:     AdjustScrollBar;
        !          2503: 
        !          2504:     with FScreen do begin
        !          2505:         GotoXY(0, 0);
        !          2506:         WriteStr('EmulVT');
        !          2507:         GotoXY(0, 1);
        !          2508:     end;
        !          2509: end;
        !          2510: 
        !          2511: 
        !          2512: {* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *}
        !          2513: procedure TCustomEmulVT.SetRows(Value : Integer);
        !          2514: begin
        !          2515:     with FScreen do begin
        !          2516:         if FRowCount <> Value then begin
        !          2517:             SetRowCount(Value);
        !          2518:             AdjustScrollBar;
        !          2519:             ClearScreen;
        !          2520:             Repaint;
        !          2521:         end;
        !          2522:     end;
        !          2523: end;
        !          2524: 
        !          2525: 
        !          2526: {* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *}
        !          2527: function TCustomEmulVT.GetRows : Integer;
        !          2528: begin
        !          2529:     Result := FScreen.FRowCount;
        !          2530: end;
        !          2531: 
        !          2532: 
        !          2533: {* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *}
        !          2534: procedure TCustomEmulVT.SetCols(Value : Integer);
        !          2535: begin
        !          2536:     with FScreen do begin
        !          2537:         if FColCount <> Value then begin
        !          2538:             FColCount := Value;
        !          2539:             ClearScreen;
        !          2540:             Repaint;
        !          2541:         end;
        !          2542:     end;
        !          2543: end;
        !          2544: 
        !          2545: 
        !          2546: {* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *}
        !          2547: function TCustomEmulVT.GetCols : Integer;
        !          2548: begin
        !          2549:     Result := FScreen.FColCount;
        !          2550: end;
        !          2551: 
        !          2552: 
        !          2553: {* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *}
        !          2554: procedure TCustomEmulVT.CursorVisibleEvent(Sender : TObject);
        !          2555: begin
        !          2556:     if FScreen.FCursorOff then begin
        !          2557:         if FCaretShown then begin
        !          2558:             HideCaret(Handle);
        !          2559:             FCaretShown := FALSE;
        !          2560:         end;
        !          2561:     end
        !          2562:     else begin
        !          2563:         if FScreen.Focused and not FCaretShown then begin
        !          2564:             ShowCaret(Handle);
        !          2565:             FCaretShown := TRUE;
        !          2566:         end;
        !          2567:     end;
        !          2568: end;
        !          2569: 
        !          2570: 
        !          2571: {* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *}
        !          2572: procedure TCustomEmulVT.SetAutoLF(Value : Boolean);
        !          2573: begin
        !          2574:     FScreen.FAutoLF := Value;
        !          2575: end;
        !          2576: 
        !          2577: 
        !          2578: {* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *}
        !          2579: procedure TCustomEmulVT.SetAutoCR(Value : Boolean);
        !          2580: begin
        !          2581:     FScreen.FAutoCR := Value;
        !          2582: end;
        !          2583: 
        !          2584: 
        !          2585: {* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *}
        !          2586: procedure TCustomEmulVT.SetLog(Value : Boolean);
        !          2587: begin
        !          2588:     if FLog = Value then
        !          2589:         Exit;
        !          2590: 
        !          2591:     FLog := Value;
        !          2592: 
        !          2593:     if FLog then begin
        !          2594: {$I-}
        !          2595:         AssignFile(FFileHandle, 'EMULVT.LOG');
        !          2596:         Append(FFileHandle);
        !          2597:         if IOResult <> 0 then
        !          2598:             Rewrite(FFileHandle);
        !          2599:         Write(FFileHandle, '<Open>');
        !          2600: {$I+}
        !          2601:     end
        !          2602:     else begin
        !          2603:         Write(FFileHandle, '<Close>');
        !          2604:         CloseFile(FFileHandle);
        !          2605:     end;
        !          2606: end;
        !          2607: 
        !          2608: 
        !          2609: {* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *}
        !          2610: procedure TCustomEmulVT.SetXlat(Value : Boolean);
        !          2611: begin
        !          2612:     FScreen.FNoXlat        := not Value;
        !          2613:     FScreen.FNoXlatInitial := not Value;
        !          2614: end;
        !          2615: 
        !          2616: 
        !          2617: {* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *}
        !          2618: function TCustomEmulVT.GetXlat : Boolean;
        !          2619: begin
        !          2620:     Result := not FScreen.FNoXlatInitial;
        !          2621: end;
        !          2622: 
        !          2623: 
        !          2624: {* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *}
        !          2625: function TCustomEmulVT.GetAutoLF : Boolean;
        !          2626: begin
        !          2627:     Result := FScreen.FAutoLF;
        !          2628: end;
        !          2629: 
        !          2630: 
        !          2631: {* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *}
        !          2632: function TCustomEmulVT.GetAutoCR : Boolean;
        !          2633: begin
        !          2634:     Result := FScreen.FAutoCR;
        !          2635: end;
        !          2636: 
        !          2637: 
        !          2638: {* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *}
        !          2639: destructor TCustomEmulVT.Destroy;
        !          2640: begin
        !          2641:     if FLog then
        !          2642:         Log := FALSE;
        !          2643: 
        !          2644:     FFont.Free;
        !          2645:     FVScrollBar.Free;
        !          2646:     FScreen.Free;
        !          2647:     DeleteObject(FPal);
        !          2648:     inherited Destroy;
        !          2649: end;
        !          2650: 
        !          2651: 
        !          2652: {* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *}
        !          2653: procedure TCustomEmulVT.SetBackRows(Value : Integer);
        !          2654: begin
        !          2655:     with FScreen do begin
        !          2656:         if FBackRowCount <> Value then begin
        !          2657:             SetBackRowCount(Value);
        !          2658:             AdjustScrollBar;
        !          2659:         end;
        !          2660:     end;
        !          2661: end;
        !          2662: 
        !          2663: 
        !          2664: {* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *}
        !          2665: procedure TCustomEmulVT.SetTopLine(Value : Integer);
        !          2666: begin
        !          2667:     if Value < FVScrollBar.Min then
        !          2668:         Value := FVScrollBar.Min;
        !          2669:     if Value > FVScrollBar.Max then
        !          2670:         Value := FVScrollBar.Max;
        !          2671:     FTopLine := Value;
        !          2672:     FVScrollBar.Position := FTopLine;
        !          2673:     Repaint;
        !          2674: end;
        !          2675: 
        !          2676: 
        !          2677: {* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *}
        !          2678: function TCustomEmulVT.GetBackRows : Integer;
        !          2679: begin
        !          2680:     Result := FScreen.FBackRowCount;
        !          2681: end;
        !          2682: 
        !          2683: 
        !          2684: {* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *}
        !          2685: procedure TCustomEmulVT.SetBackColor(Value : TBackColors);
        !          2686: begin
        !          2687:     FScreen.FBackColor := Value;
        !          2688: end;
        !          2689: 
        !          2690: 
        !          2691: {* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *}
        !          2692: function TCustomEmulVT.GetBackColor : TBackColors;
        !          2693: begin
        !          2694:     Result := FScreen.FBackColor;
        !          2695: end;
        !          2696: 
        !          2697: 
        !          2698: {* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *}
        !          2699: procedure TCustomEmulVT.SetOptions(Value : TScreenOptions);
        !          2700: begin
        !          2701:     FScreen.FOptions := Value;
        !          2702: end;
        !          2703: 
        !          2704: 
        !          2705: {* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *}
        !          2706: function TCustomEmulVT.GetOptions : TScreenOptions;
        !          2707: begin
        !          2708:     Result := FScreen.FOptions;
        !          2709: end;
        !          2710: 
        !          2711: 
        !          2712: {* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *}
        !          2713: procedure TCustomEmulVT.SetupFont;
        !          2714: var
        !          2715:     DC      : HDC;
        !          2716:     Metrics : TTextMetric;
        !          2717:     hObject : THandle;
        !          2718: begin
        !          2719:     DC      := GetDC(0);
        !          2720:     hObject := SelectObject(DC, FFont.Handle);
        !          2721:     GetTextMetrics(DC, Metrics);
        !          2722:     SelectObject(DC, hOBject);
        !          2723:     ReleaseDC(0, DC);
        !          2724: 
        !          2725:     SetCharWidth(Metrics.tmMaxCharWidth);
        !          2726:     SetLineHeight(Metrics.tmHeight);
        !          2727:     FInternalLeading := Metrics.tmInternalLeading;
        !          2728: end;
        !          2729: 
        !          2730: 
        !          2731: {* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *}
        !          2732: procedure TCustomEmulVT.SetCharWidth(newValue : Integer);
        !          2733: var
        !          2734:     nCol : Integer;
        !          2735: begin
        !          2736:     FCharWidth := newValue;
        !          2737:     for nCol := Low(FCharPos) to High(FCharPos) do
        !          2738:         FCharPos[nCol] := Trunc(FCharWidth * nCol * FCharZoom);
        !          2739: end;
        !          2740: 
        !          2741: 
        !          2742: {* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *}
        !          2743: procedure TCustomEmulVT.SetCharZoom(newValue : Single);
        !          2744: begin
        !          2745:     FCharZoom := newValue;
        !          2746:     SetCharWidth(FCharWidth);
        !          2747: end;
        !          2748: 
        !          2749: 
        !          2750: {* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *}
        !          2751: procedure TCustomEmulVT.SetLineHeight(Value : Integer);
        !          2752: var
        !          2753:     nRow : Integer;
        !          2754: begin
        !          2755:     FLineHeight := Value;
        !          2756:     for nRow := 0 to MAX_ROW do
        !          2757:         FLinePos[nRow] := Trunc(FLineHeight * nRow * FLineZoom);
        !          2758: end;
        !          2759: 
        !          2760: 
        !          2761: {* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *}
        !          2762: procedure TCustomEmulVT.SetLineZoom(newValue : Single);
        !          2763: begin
        !          2764:     FLineZoom := newValue;
        !          2765:     SetLineHeight(FLineHeight);
        !          2766: end;
        !          2767: 
        !          2768: 
        !          2769: {* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *}
        !          2770: procedure TCustomEmulVT.SetFont(Value : TFont);
        !          2771: begin
        !          2772:     FFont.Assign(Value);
        !          2773: {$IFNDEF SINGLE_CHAR_PAINT}
        !          2774:     FFont.Pitch := fpFixed;
        !          2775: {$ENDIF}
        !          2776:     SetupFont;
        !          2777:     SetCaret;
        !          2778: end;
        !          2779: 
        !          2780: 
        !          2781: {* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *}
        !          2782: procedure TCustomEmulVT.WMLButtonDown(var Message: TWMLButtonDown);
        !          2783: begin
        !          2784:     inherited;
        !          2785:     SetFocus;
        !          2786: end;
        !          2787: 
        !          2788: 
        !          2789: {* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *}
        !          2790: procedure TCustomEmulVT.VScrollBarScroll(Sender: TObject; ScrollCode: TScrollCode; var ScrollPos: Integer);
        !          2791: begin
        !          2792:     FTopLine := ScrollPos;
        !          2793:     Repaint;
        !          2794:     SetFocus;
        !          2795: end;
        !          2796: 
        !          2797: 
        !          2798: {* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *}
        !          2799: procedure TCustomEmulVT.DoKeyBuffer(Buffer : PChar; Len : Integer);
        !          2800: var
        !          2801:     J : Integer;
        !          2802:     ch : Char;
        !          2803: begin
        !          2804:     if Assigned(FOnKeyBuffer) then
        !          2805:         FOnKeyBuffer(Self, Buffer, Len)
        !          2806:     else begin
        !          2807:         for J := 0 to Len - 1 do begin
        !          2808:             ch := Buffer[J];
        !          2809:             KeyPress(ch);
        !          2810:         end;
        !          2811:     end;
        !          2812: end;
        !          2813: 
        !          2814: 
        !          2815: {* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *}
        !          2816: function TCustomEmulVT.FindFKeys(ScanCode: Char; Shift: TShiftState;
        !          2817:                                  Ext: Boolean) : PFuncKeyValue;
        !          2818: var
        !          2819:     I      : Integer;
        !          2820:     pFKeys : PFuncKeysTable;
        !          2821: begin
        !          2822:     Result := nil;
        !          2823:     case FKeys of
        !          2824:     0 : pFKeys := @FKeys1;
        !          2825:     1 : pFKeys := @FKeys2;
        !          2826:     2 : pFKeys := @FKeys3;
        !          2827:     else
        !          2828:         pFKeys := @FKeys2;
        !          2829:     end;
        !          2830: 
        !          2831:     for I := Low(pFKeys^) to High(pFKeys^) do begin
        !          2832:         if (pFKeys^[I].ScanCode <> #0) and (pFKeys^[I].ScanCode = ScanCode) and
        !          2833:            (pFKeys^[I].Shift = Shift) and
        !          2834:            (pFKeys^[I].Ext = Ext) then begin
        !          2835:             Result := @pFKeys^[I].Value;
        !          2836:             Break;
        !          2837:         end;
        !          2838:     end;
        !          2839: end;
        !          2840: 
        !          2841: 
        !          2842: {* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *}
        !          2843: function TCustomEmulVT.ProcessFKeys(ScanCode: Char; Shift: TShiftState;
        !          2844:                                     Ext: Boolean) : Boolean;
        !          2845: var
        !          2846:     I      : Integer;
        !          2847:     pFKeys : PFuncKeysTable;
        !          2848: begin
        !          2849:     Result := FALSE;
        !          2850:     case FKeys of
        !          2851:     0 : pFKeys := @FKeys1;
        !          2852:     1 : pFKeys := @FKeys2;
        !          2853:     2 : pFKeys := @FKeys3;
        !          2854:     else
        !          2855:         pFKeys := @FKeys2;
        !          2856:     end;
        !          2857: 
        !          2858:     for I := Low(pFKeys^) to High(pFKeys^) do begin
        !          2859:         if (pFKeys^[I].ScanCode <> #0) and (pFKeys^[I].ScanCode = ScanCode) and
        !          2860:            (pFKeys^[I].Shift = Shift) and
        !          2861:            (pFKeys^[I].Ext = Ext) then begin
        !          2862:             Result := TRUE;
        !          2863:             DoKeyBuffer(@pFKeys^[I].Value[1], Length(pFKeys^[I].Value));
        !          2864:             Break;
        !          2865:         end;
        !          2866:     end;
        !          2867: end;
        !          2868: 
        !          2869: 
        !          2870: {* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *}
        !          2871: procedure TCustomEmulVT.AppMessageHandler(var Msg: TMsg; var Handled: Boolean);
        !          2872: const
        !          2873:     v1 : String = 'aeiou';
        !          2874:     v2 : String = '�����';
        !          2875:     v3 : String = '�����';
        !          2876:     SpyFlag : Boolean = FALSE;
        !          2877: var
        !          2878:     Shift     : TShiftState;
        !          2879:     ShiftLock : Boolean;
        !          2880:     VirtKey   : Integer;
        !          2881:     Key       : Char;
        !          2882:     I         : Integer;
        !          2883:     ScanCode  : Char;
        !          2884:     Ext       : Boolean;
        !          2885:     SpyBuffer : String;
        !          2886:     FnBuffer  : String;
        !          2887:     pFV       : PFuncKeyValue;
        !          2888: begin
        !          2889:     if (Msg.hWnd = Handle) and (Msg.Message = WM_KEYDOWN) then begin
        !          2890:         VirtKey   := Msg.wParam;
        !          2891:         Key       := chr(Msg.wParam and $FF);
        !          2892: {        DebugString('AppMessageHandler KEYDOWN ' + IntToHex(Msg.wParam, 4) + #13 + #10); }
        !          2893:         Shift     := KeyDataToShiftState(Msg.lParam);
        !          2894:         ShiftLock := ((GetKeyState(VK_CAPITAL) and 1) > 0);
        !          2895:         ScanCode  := Chr(LOBYTE(HIWORD(Msg.lParam)));
        !          2896:         Ext       := ((Msg.lParam and $1000000) <> 0);
        !          2897: 
        !          2898:         if Assigned(FOnKeyDown) then begin
        !          2899:             FOnKeyDown(Self, VirtKey, Shift, ShiftLock, ScanCode, Ext);
        !          2900:             if VirtKey = 0 then begin
        !          2901:                 Handled := TRUE;
        !          2902:                 Exit;
        !          2903:             end;
        !          2904:         end;
        !          2905: 
        !          2906:         if (Msg.wParam <> VK_SHIFT) and
        !          2907:            (Msg.wParam <> VK_CONTROL) and
        !          2908:            (Msg.wParam <> VK_MENU) then begin
        !          2909:             if (ScanCode = '7') and
        !          2910:                (Shift = [ssAlt, ssCtrl]) and (Ext = FALSE) then begin
        !          2911:                 { This is CTRL-ALT-* (on num pad) }
        !          2912:                 SpyFlag := TRUE;
        !          2913:                 Handled := TRUE;
        !          2914:                 Exit;
        !          2915:             end;
        !          2916: 
        !          2917:             if SpyFlag then begin
        !          2918:                 SpyFlag   := FALSE;
        !          2919:                 pFV       := FindFKeys(ScanCode, Shift, Ext);
        !          2920:                 SpyBuffer := IntToHex(Ord(ScanCode), 2) + ', ' +
        !          2921:                              ShiftStateToString(Shift) + ', ';
        !          2922: 
        !          2923:                 if Ext then
        !          2924:                     SpyBuffer := SpyBuffer + 'TRUE'
        !          2925:                 else
        !          2926:                     SpyBuffer := SpyBuffer + 'FALSE';
        !          2927: 
        !          2928:                 if pFV <> nil then
        !          2929:                     SpyBuffer := SpyBuffer + ', ''' +
        !          2930:                                  FuncKeyValueToString(pFV^) + '''';
        !          2931: 
        !          2932:                 SpyBuffer := SpyBuffer + #0;
        !          2933:                 ClipBoard.SetTextBuf(@SpyBuffer[1]);
        !          2934: 
        !          2935:                 FnBuffer := 'Key definition from tnchrk' +
        !          2936:                             IntToStr(FKeys) + '.cfg' + #0;
        !          2937:                 Application.MessageBox(@SpyBuffer[1], @FnBuffer[1], MB_OK);
        !          2938:                 Handled := TRUE;
        !          2939:                 Exit;
        !          2940:             end;
        !          2941: 
        !          2942:             if ProcessFKeys(ScanCode, Shift, Ext) then begin
        !          2943:                 Handled := TRUE;
        !          2944:                 Exit;
        !          2945:             end;
        !          2946:         end;
        !          2947: 
        !          2948:         case Msg.wParam of
        !          2949:         VK_SHIFT, VK_CONTROL, VK_MENU: ;
        !          2950: 
        !          2951:         VK_NEXT, VK_PRIOR, VK_UP, VK_DOWN, VK_LEFT, VK_RIGHT, VK_HOME, VK_END:
        !          2952:             begin
        !          2953:                 if ProcessFKeys(ScanCode, Shift, TRUE) then begin
        !          2954:                     Handled := TRUE;
        !          2955:                     Exit;
        !          2956:                 end;
        !          2957:             end;
        !          2958:         VK_TAB, VK_RETURN, VK_ESCAPE, VK_BACK:
        !          2959:             begin
        !          2960:                 Handled := TRUE;
        !          2961:             end;
        !          2962: 
        !          2963:         $DD:
        !          2964:             begin
        !          2965:                 if not (ssAlt in Shift) then begin
        !          2966:                     Key     := #0;
        !          2967:                     Handled := TRUE;
        !          2968:                     if (ssShift in Shift) then
        !          2969:                         FFlagTrema := TRUE
        !          2970:                     else
        !          2971:                         FFlagCirconflexe := TRUE;
        !          2972:                 end;
        !          2973:             end;
        !          2974: 
        !          2975:         ord('A')..ord('Z') :
        !          2976:             begin
        !          2977:                 if (ssCtrl in Shift) then
        !          2978:                     Key := chr(Word(Key) and $1F)
        !          2979:                 else if not ShiftLock and not (ssShift in Shift) then
        !          2980:                     Key := chr(Word(Key) or $20);
        !          2981:                 if (FFlagCirconflexe) then begin
        !          2982:                     for I := Length(v1) downto 1 do begin
        !          2983:                         if Key = v1[I] then begin
        !          2984:                             Key := v2[I];
        !          2985:                             Break;
        !          2986:                         end;
        !          2987:                     end;
        !          2988:                     FFlagCirconflexe := FALSE;
        !          2989:                 end;
        !          2990:                 if (FFlagTrema) then begin
        !          2991:                     for I := Length(v1) downto 1 do begin
        !          2992:                         if Key = v1[I] then begin
        !          2993:                             Key := v3[I];
        !          2994:                             Break;
        !          2995:                         end;
        !          2996:                     end;
        !          2997:                     FFlagTrema       := FALSE;
        !          2998:                 end;
        !          2999:                 Handled := TRUE;
        !          3000:             end;
        !          3001:         end;
        !          3002: 
        !          3003: {        DebugString('Char = ' + IntToHex(Integer(Key), 2) + #13 + #10); }
        !          3004:         if Handled and (Key <> #0) then
        !          3005:             KeyPress(Key);
        !          3006:     end;
        !          3007: 
        !          3008:     if not Handled and Assigned(FAppOnMessage) then
        !          3009:         FAppOnMessage(Msg, Handled);
        !          3010: end;
        !          3011: 
        !          3012: 
        !          3013: {* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *}
        !          3014: procedure TCustomEmulVT.KeyPress(var Key: Char);
        !          3015: begin
        !          3016:     if not FScreen.FNoXlat then
        !          3017:         Key := FScreen.FXlatOutputTable^[ord(Key)];
        !          3018: 
        !          3019:     inherited KeyPress(Key);
        !          3020:     if FLocalEcho then begin
        !          3021:         WriteChar(Key);
        !          3022:         if not FAutoRepaint then
        !          3023:             UpdateScreen;
        !          3024:     end;
        !          3025: end;
        !          3026: 
        !          3027: 
        !          3028: {* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *}
        !          3029: procedure TCustomEmulVT.WMSetFocus(var Message: TWMSetFocus);
        !          3030: begin
        !          3031: {    inherited; }
        !          3032:     FScreen.Focused := TRUE;
        !          3033: {    SetupFont; }
        !          3034: 
        !          3035:     if not FCursorVisible then
        !          3036:         Exit;
        !          3037: 
        !          3038:     CreateCaret(Handle, 0, 2, FLineHeight);
        !          3039:     FCaretCreated := TRUE;
        !          3040:     SetCaret;
        !          3041:     if not FScreen.FCursorOff then begin
        !          3042:         ShowCaret(Handle);
        !          3043:         FCaretShown := TRUE;
        !          3044:     end;
        !          3045: 
        !          3046:     FAppOnMessage := Application.OnMessage;
        !          3047:     Application.OnMessage := AppMessageHandler;
        !          3048: end;
        !          3049: 
        !          3050: 
        !          3051: {* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *}
        !          3052: procedure TCustomEmulVT.WMKillFocus(var Message: TWMKillFocus);
        !          3053: begin
        !          3054: {    inherited; }
        !          3055:     FScreen.Focused := FALSE;
        !          3056: 
        !          3057:     if not FCursorVisible then
        !          3058:         Exit;
        !          3059: 
        !          3060:     if FCaretShown then begin
        !          3061:         HideCaret(Handle);
        !          3062:         FCaretShown := FALSE;
        !          3063:     end;
        !          3064: 
        !          3065:     if FCaretCreated then begin
        !          3066:         DestroyCaret;
        !          3067:         FCaretCreated := FALSE;
        !          3068:     end;
        !          3069: 
        !          3070:     Application.OnMessage := FAppOnMessage;
        !          3071: end;
        !          3072: 
        !          3073: 
        !          3074: {* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *}
        !          3075: procedure TCustomEmulVT.MouseToCell(X, Y: Integer; var ACol, ARow: Longint);
        !          3076: begin
        !          3077: {$IFDEF CHAR_ZOOM}
        !          3078:     aRow := FScreen.FRowCount - 1;
        !          3079:     while (Y - TopMargin) <= FLinePos[aRow] do
        !          3080:         Dec(aRow);
        !          3081: {$ELSE}
        !          3082:     aRow := (Y - TopMargin) div FLineHeight;
        !          3083: {$ENDIF}
        !          3084:     if aRow < 0 then
        !          3085:         aRow := 0
        !          3086:     else if aRow >= FScreen.FRowCount then
        !          3087:         aRow := FScreen.FRowCount - 1;
        !          3088: 
        !          3089: {$IFDEF CHAR_ZOOM}
        !          3090:     aCol := FScreen.FColCount - 1;
        !          3091:     while (X - LeftMargin) <= FCharPos[aCol] do
        !          3092:         Dec(aCol);
        !          3093: {$ELSE}
        !          3094:     aCol := (X - LeftMargin) div FCharWidth;
        !          3095: {$ENDIF}
        !          3096:     if aCol < 0 then
        !          3097:         aCol := 0
        !          3098:     else if aCol >= FScreen.FColCount then
        !          3099:         aCol := FScreen.FColCount - 1;
        !          3100: end;
        !          3101: 
        !          3102: 
        !          3103: {* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *}
        !          3104: procedure TCustomEmulVT.ShowCursor;
        !          3105: begin
        !          3106:     SetCaret;
        !          3107: end;
        !          3108: 
        !          3109: 
        !          3110: {* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *}
        !          3111: procedure TCustomEmulVT.WMPaletteChanged(var Message : TMessage);
        !          3112: {var
        !          3113:     HandleDC : HDC;}
        !          3114: begin
        !          3115: {        if Message.wParam <> Handle then begin
        !          3116:             HandleDC := GetDC(Handle);
        !          3117:             SelectPalette(HandleDC, FPal, FALSE);
        !          3118:             if RealizePalette(HandleDC) <> 0 then begin
        !          3119:                 InvalidateRect(Handle, nil, TRUE);
        !          3120:                 MessageBeep(0);
        !          3121:             end;
        !          3122:             ReleaseDC(Handle, HandleDC);
        !          3123:         end;
        !          3124: }
        !          3125: end;
        !          3126: 
        !          3127: 
        !          3128: {* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *}
        !          3129: procedure TCustomEmulVT.UpdateScreen;
        !          3130: var
        !          3131:     rc : TRect;
        !          3132: begin
        !          3133:     if FScreen.FAllInvalid then
        !          3134:         InvalidateRect(Handle, nil, FALSE)
        !          3135:     else begin
        !          3136: {$Q-}
        !          3137:             with FScreen.FInvRect do begin
        !          3138: {$IFDEF CHAR_ZOOM}
        !          3139:                 if Left = 9999 then begin
        !          3140:                     rc.Top    := 0;
        !          3141:                     rc.Bottom := 0;
        !          3142:                     rc.Left   := 0;
        !          3143:                     rc.Right  := 0;
        !          3144:                 end
        !          3145:                 else begin
        !          3146:                     rc.Top    := TopMargin  + FLinePos[Top - FTopLine] + FInternalLeading;
        !          3147:                     rc.Bottom := TopMargin  + FLinePos[Bottom + 1 - FTopLine] + FInternalLeading;
        !          3148:                     rc.Left   := LeftMargin + FCharPos[Left];
        !          3149:                     rc.Right  := LeftMargin + FCharPos[Right + 1];
        !          3150:                 end;
        !          3151: {$ELSE}
        !          3152:                 rc.Top    := TopMargin  + FLineHeight * (Top - FTopLine) + FInternalLeading;
        !          3153:                 rc.Bottom := TopMargin  + FLineHeight * (Bottom + 1 - FTopLine) + FInternalLeading;
        !          3154:                 rc.Left   := LeftMargin + FCharWidth * Left;
        !          3155:                 rc.Right  := LeftMargin + FCharWidth * (Right + 1);
        !          3156: {$ENDIF}
        !          3157:             end;
        !          3158:             InvalidateRect(Handle, @rc, FALSE);
        !          3159: {$Q+}
        !          3160:     end;
        !          3161: 
        !          3162:     { Invalidate the region where the caret is. I should'nt do that, but }
        !          3163:     { if I do'nt, the caret remains where it is ! Bug ?                  }
        !          3164: {$IFDEF CHAR_ZOOM}
        !          3165:     rc.Top    := FLinePos[FScreen.FRow - FTopLine] + TopMargin;
        !          3166:     rc.Bottom := FLinePos[FScreen.FRow - FTopLine + 1] + TopMargin;
        !          3167:     rc.Left   := LeftMargin + FCharPos[FScreen.FCol];
        !          3168:     rc.Right  := LeftMargin + FCharPos[FScreen.FCol + 1];
        !          3169: {$ELSE}
        !          3170:     rc.Top    := TopMargin  + FLineHeight * (FScreen.FRow - FTopLine);
        !          3171:     rc.Bottom := rc.Top + FLineHeight;
        !          3172:     rc.Left   := LeftMargin + FCharWidth * FScreen.FCol;
        !          3173:     rc.Right  := rc.Left + FCharWidth;
        !          3174: {$ENDIF}
        !          3175:     InvalidateRect(Handle, @rc, FALSE);
        !          3176: 
        !          3177:     FScreen.InvClear;
        !          3178: 
        !          3179:     if FCaretCreated then begin
        !          3180:         ShowCaret(Handle);
        !          3181:         FCaretShown := TRUE;
        !          3182:     end;
        !          3183:     SetCaret;
        !          3184: end;
        !          3185: 
        !          3186: 
        !          3187: {* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *}
        !          3188: function TCustomEmulVT.SnapPixelToRow(Y : Integer) : Integer;
        !          3189: var
        !          3190:     nRow : Integer;
        !          3191: begin
        !          3192:     nRow := PixelToRow(Y);
        !          3193: {$IFDEF CHAR_ZOOM}
        !          3194:     Result := TopMargin + FLinePos[nRow];
        !          3195: {$ELSE}
        !          3196:     Result := TopMargin + nRow * FLineHeight;
        !          3197: {$ENDIF}
        !          3198: end;
        !          3199: 
        !          3200: 
        !          3201: {* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *}
        !          3202: function TCustomEmulVT.SnapPixelToCol(X : Integer) : Integer;
        !          3203: var
        !          3204:     nCol : Integer;
        !          3205: begin
        !          3206:     nCol := PixelToCol(X);
        !          3207: {$IFDEF CHAR_ZOOM}
        !          3208:     Result := LeftMargin + FCharPos[nCol];
        !          3209: {$ELSE}
        !          3210:     Result := LeftMargin + nCol * FCharWidth;
        !          3211: {$ENDIF}
        !          3212: end;
        !          3213: 
        !          3214: 
        !          3215: {* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *}
        !          3216: function TCustomEmulVT.PixelToRow(Y : Integer) : Integer;
        !          3217: var
        !          3218:     nRow : Integer;
        !          3219: begin
        !          3220: {$IFDEF CHAR_ZOOM}
        !          3221:     nRow := FScreen.FRowCount - 1;
        !          3222:     while (nRow > 0) and ((Y - TopMargin) < FLinePos[nRow]) do
        !          3223:         Dec(nRow);
        !          3224: {$ELSE}
        !          3225:     nRow := (Y - TopMargin) div FLineHeight;
        !          3226: {$ENDIF}
        !          3227:     if nRow < 0 then
        !          3228:         nRow := 0;
        !          3229:     Result := nRow;
        !          3230: end;
        !          3231: 
        !          3232: 
        !          3233: {* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *}
        !          3234: function TCustomEmulVT.PixelToCol(X : Integer) : Integer;
        !          3235: var
        !          3236:     nCol : Integer;
        !          3237: begin
        !          3238: {$IFDEF CHAR_ZOOM}
        !          3239:     nCol := FScreen.FColCount - 1;
        !          3240:     while (X - LeftMargin) < FCharPos[nCol] do
        !          3241:         Dec(nCol);
        !          3242: {$ELSE}
        !          3243:     nCol := (X - LeftMargin) div FCharWidth;
        !          3244: {$ENDIF}
        !          3245:     if nCol < 0 then
        !          3246:         nCol := 0;
        !          3247:     Result := nCol;
        !          3248: end;
        !          3249: 
        !          3250: 
        !          3251: {* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *}
        !          3252: { This procedure will paint graphic char from the OEM charset (lines,       }
        !          3253: { corners, T and other like) using GDI functions. This will result in       }
        !          3254: { autosized characters, necessary for example to draw a frame when zoom     }
        !          3255: { affect character and line spacing.                                        }
        !          3256: procedure TCustomEmulVT.PaintGraphicChar(
        !          3257:     DC   : HDC;
        !          3258:     X, Y : Integer;
        !          3259:     rc   : PRect;
        !          3260:     ch   : Char);
        !          3261: const
        !          3262:     OneSpace : Char = ' ';
        !          3263: var
        !          3264:     X1, X2, X3 : Integer;
        !          3265:     Y1, Y2, Y3 : Integer;
        !          3266:     Co         : TColor;
        !          3267: begin
        !          3268:     ExtTextOut(DC,
        !          3269:                X, Y,
        !          3270:                ETO_OPAQUE or ETO_CLIPPED, rc,
        !          3271:                @OneSpace, 1, nil);
        !          3272:     X1 := X;
        !          3273:     X3 := rc^.Right;
        !          3274:     X2 := (X1 + X3) div 2;
        !          3275:     Y1 := rc^.Top;
        !          3276:     Y3 := rc^.Bottom;
        !          3277:     Y2 := (Y1 + Y3) div 2;
        !          3278:     case Ch of
        !          3279:     #$C4: begin       { Horizontal single line }
        !          3280:               Canvas.MoveTo(X1, Y2);
        !          3281:               Canvas.LineTo(X3, Y2);
        !          3282:           end;
        !          3283:     #$B3: begin       { Vertical single line }
        !          3284:               Canvas.MoveTo(X2, Y1);
        !          3285:               Canvas.LineTo(X2, Y3);
        !          3286:           end;
        !          3287:     #$DA: begin       { Upper Left Single Corner }
        !          3288:               Canvas.MoveTo(X3, Y2);
        !          3289:               Canvas.LineTo(X2, Y2);
        !          3290:               Canvas.LineTo(X2, Y3);
        !          3291:           end;
        !          3292:     #$C0: begin       { Bottom Left Single Corner }
        !          3293:               Canvas.MoveTo(X2, Y1);
        !          3294:               Canvas.LineTo(X2, Y2);
        !          3295:               Canvas.LineTo(X3, Y2);
        !          3296:           end;
        !          3297:     #$C1: begin       { Reverse T }
        !          3298:               Canvas.MoveTo(X2, Y1);
        !          3299:               Canvas.LineTo(X2, Y2);
        !          3300:               Canvas.MoveTo(X1, Y2);
        !          3301:               Canvas.LineTo(X3, Y2);
        !          3302:           end;
        !          3303:     #$C2: begin       { T }
        !          3304:               Canvas.MoveTo(X2, Y3);
        !          3305:               Canvas.LineTo(X2, Y2);
        !          3306:               Canvas.MoveTo(X1, Y2);
        !          3307:               Canvas.LineTo(X3, Y2);
        !          3308:           end;
        !          3309:     #$C3: begin       { Left T }
        !          3310:               Canvas.MoveTo(X2, Y1);
        !          3311:               Canvas.LineTo(X2, Y3);
        !          3312:               Canvas.MoveTo(X2, Y2);
        !          3313:               Canvas.LineTo(X3, Y2);
        !          3314:           end;
        !          3315:     #$B4: begin       { Right T }
        !          3316:               Canvas.MoveTo(X2,     Y1);
        !          3317:               Canvas.LineTo(X2,     Y3);
        !          3318:               Canvas.MoveTo(X2,     Y2);
        !          3319:               Canvas.LineTo(X1 - 1, Y2);
        !          3320:           end;
        !          3321:     #$BF: begin       { Top Right Single Corner }
        !          3322:               Canvas.MoveTo(X1, Y2);
        !          3323:               Canvas.LineTo(X2, Y2);
        !          3324:               Canvas.LineTo(X2, Y3);
        !          3325:           end;
        !          3326:     #$D9: begin       { Bottom Right Single Corner }
        !          3327:               Canvas.MoveTo(X1, Y2);
        !          3328:               Canvas.LineTo(X2, Y2);
        !          3329:               Canvas.LineTo(X2, Y1 - 1);
        !          3330:           end;
        !          3331:     #$D6: begin       { Upper Left Single/Double Corner }
        !          3332:               Canvas.MoveTo(X3, Y2);
        !          3333:               Canvas.LineTo(X2 - 1, Y2);
        !          3334:               Canvas.LineTo(X2 - 1, Y3);
        !          3335:               Canvas.MoveTo(X2 + 1, Y2);
        !          3336:               Canvas.LineTo(X2 + 1, Y3);
        !          3337:           end;
        !          3338:     #$D3: begin       { Bottom Left Single/Double Corner }
        !          3339:               Canvas.MoveTo(X2 - 1, Y1);
        !          3340:               Canvas.LineTo(X2 - 1, Y2);
        !          3341:               Canvas.LineTo(X3, Y2);
        !          3342:               Canvas.MoveTo(X2 + 1, Y1);
        !          3343:               Canvas.LineTo(X2 + 1, Y2);
        !          3344:           end;
        !          3345:     #$B7: begin       { Top Right Single/Double Corner }
        !          3346:               Canvas.MoveTo(X1, Y2);
        !          3347:               Canvas.LineTo(X2 + 1, Y2);
        !          3348:               Canvas.LineTo(X2 + 1, Y3);
        !          3349:               Canvas.MoveTo(X2 - 1, Y2);
        !          3350:               Canvas.LineTo(X2 - 1, Y3);
        !          3351:           end;
        !          3352:     #$BD: begin       { Bottom Right Single/Double Corner }
        !          3353:               Canvas.MoveTo(X2 + 1, Y1);
        !          3354:               Canvas.LineTo(X2 + 1, Y2);
        !          3355:               Canvas.LineTo(X1 - 1, Y2);
        !          3356:               Canvas.MoveTo(X2 - 1, Y1);
        !          3357:               Canvas.LineTo(X2 - 1, Y2);
        !          3358:           end;
        !          3359:     #$D5: begin       { Upper Left Double/Single Corner }
        !          3360:               Canvas.MoveTo(X3, Y2 - 1);
        !          3361:               Canvas.LineTo(X2, Y2 - 1);
        !          3362:               Canvas.LineTo(X2, Y3);
        !          3363:               Canvas.MoveTo(X3, Y2 + 1);
        !          3364:               Canvas.LineTo(X2, Y2 + 1);
        !          3365:           end;
        !          3366:     #$D4: begin       { Bottom Left Double/Single Corner }
        !          3367:               Canvas.MoveTo(X2, Y1);
        !          3368:               Canvas.LineTo(X2, Y2 + 1);
        !          3369:               Canvas.LineTo(X3, Y2 + 1);
        !          3370:               Canvas.MoveTo(X2, Y2 - 1);
        !          3371:               Canvas.LineTo(X3, Y2 - 1);
        !          3372:           end;
        !          3373:     #$B8: begin       { Top Right Double/Single Corner }
        !          3374:               Canvas.MoveTo(X1, Y2 - 1);
        !          3375:               Canvas.LineTo(X2, Y2 - 1);
        !          3376:               Canvas.LineTo(X2, Y3);
        !          3377:               Canvas.MoveTo(X1, Y2 + 1);
        !          3378:               Canvas.LineTo(X2, Y2 + 1);
        !          3379:           end;
        !          3380:     #$BE: begin       { Bottom Right Double/Single Corner }
        !          3381:               Canvas.MoveTo(X2,     Y1);
        !          3382:               Canvas.LineTo(X2,     Y2 + 1);
        !          3383:               Canvas.LineTo(X1 - 1, Y2 + 1);
        !          3384:               Canvas.MoveTo(X1,     Y2 - 1);
        !          3385:               Canvas.LineTo(X2,     Y2 - 1);
        !          3386:           end;
        !          3387:     #$CD: begin       { Horizontal Double line }
        !          3388:               Canvas.MoveTo(X1, Y2 + 1);
        !          3389:               Canvas.LineTo(X3, Y2 + 1);
        !          3390:               Canvas.MoveTo(X1, Y2 - 1);
        !          3391:               Canvas.LineTo(X3, Y2 - 1);
        !          3392:           end;
        !          3393:     #$BA: begin       { Vertical Double line }
        !          3394:               Canvas.MoveTo(X2 + 1, Y1);
        !          3395:               Canvas.LineTo(X2 + 1, Y3);
        !          3396:               Canvas.MoveTo(X2 - 1, Y1);
        !          3397:               Canvas.LineTo(X2 - 1, Y3);
        !          3398:           end;
        !          3399:     #$D1: begin       { T Top Horizontal Double line }
        !          3400:               Canvas.MoveTo(X1, Y2 + 1);
        !          3401:               Canvas.LineTo(X3, Y2 + 1);
        !          3402:               Canvas.MoveTo(X1, Y2 - 1);
        !          3403:               Canvas.LineTo(X3, Y2 - 1);
        !          3404:               Canvas.MoveTo(X2, Y2 + 1);
        !          3405:               Canvas.LineTo(X2, Y3);
        !          3406:           end;
        !          3407:     #$CF: begin       { T Bottom Horizontal Double line }
        !          3408:               Canvas.MoveTo(X1, Y2 + 1);
        !          3409:               Canvas.LineTo(X3, Y2 + 1);
        !          3410:               Canvas.MoveTo(X1, Y2 - 1);
        !          3411:               Canvas.LineTo(X3, Y2 - 1);
        !          3412:               Canvas.MoveTo(X2, Y2 - 1);
        !          3413:               Canvas.LineTo(X2, Y1);
        !          3414:           end;
        !          3415:     #$C6: begin       { T Left Horizontal Double line }
        !          3416:               Canvas.MoveTo(X2, Y2 + 1);
        !          3417:               Canvas.LineTo(X3, Y2 + 1);
        !          3418:               Canvas.MoveTo(X2, Y2 - 1);
        !          3419:               Canvas.LineTo(X3, Y2 - 1);
        !          3420:               Canvas.MoveTo(X2, Y1);
        !          3421:               Canvas.LineTo(X2, Y3);
        !          3422:           end;
        !          3423:     #$B5: begin       { T Right Horizontal Double line }
        !          3424:               Canvas.MoveTo(X1, Y2 + 1);
        !          3425:               Canvas.LineTo(X2, Y2 + 1);
        !          3426:               Canvas.MoveTo(X1, Y2 - 1);
        !          3427:               Canvas.LineTo(X2, Y2 - 1);
        !          3428:               Canvas.MoveTo(X2, Y1);
        !          3429:               Canvas.LineTo(X2, Y3);
        !          3430:           end;
        !          3431:     #$C9: begin       { Upper Left Double Corner }
        !          3432:               Canvas.MoveTo(X3,     Y2 - 1);
        !          3433:               Canvas.LineTo(X2 - 1, Y2 - 1);
        !          3434:               Canvas.LineTo(X2 - 1, Y3);
        !          3435:               Canvas.MoveTo(X3,     Y2 + 1);
        !          3436:               Canvas.LineTo(X2 + 1, Y2 + 1);
        !          3437:               Canvas.LineTo(X2 + 1, Y3);
        !          3438:           end;
        !          3439:     #$C8: begin       { Bottom Left Double Corner }
        !          3440:               Canvas.MoveTo(X2 - 1, Y1);
        !          3441:               Canvas.LineTo(X2 - 1, Y2 + 1);
        !          3442:               Canvas.LineTo(X3,     Y2 + 1);
        !          3443:               Canvas.MoveTo(X2 + 1, Y1);
        !          3444:               Canvas.LineTo(X2 + 1, Y2 - 1);
        !          3445:               Canvas.LineTo(X3,     Y2 - 1);
        !          3446:           end;
        !          3447:     #$BB: begin       { Top Right Double Corner }
        !          3448:               Canvas.MoveTo(X1,     Y2 - 1);
        !          3449:               Canvas.LineTo(X2 + 1, Y2 - 1);
        !          3450:               Canvas.LineTo(X2 + 1, Y3);
        !          3451:               Canvas.MoveTo(X1,     Y2 + 1);
        !          3452:               Canvas.LineTo(X2 - 1, Y2 + 1);
        !          3453:               Canvas.LineTo(X2 - 1, Y3);
        !          3454:           end;
        !          3455:     #$BC: begin       { Bottom Right Double Corner }
        !          3456:               Canvas.MoveTo(X2 - 1, Y1);
        !          3457:               Canvas.LineTo(X2 - 1, Y2 - 1);
        !          3458:               Canvas.LineTo(X1 - 1, Y2 - 1);
        !          3459:               Canvas.MoveTo(X2 + 1, Y1);
        !          3460:               Canvas.LineTo(X2 + 1, Y2 + 1);
        !          3461:               Canvas.LineTo(X1 - 1, Y2 + 1);
        !          3462:           end;
        !          3463:     #$CC: begin       { Double left T }
        !          3464:               Canvas.MoveTo(X2 - 1, Y1);
        !          3465:               Canvas.LineTo(X2 - 1, Y3);
        !          3466:               Canvas.MoveTo(X2 + 1, Y1);
        !          3467:               Canvas.LineTo(X2 + 1, Y2 - 1);
        !          3468:               Canvas.LineTo(X3,     Y2 - 1);
        !          3469:               Canvas.MoveTo(X3,     Y2 + 1);
        !          3470:               Canvas.LineTo(X2 + 1, Y2 + 1);
        !          3471:               Canvas.LineTo(X2 + 1, Y3);
        !          3472:           end;
        !          3473:     #$B9: begin       { Double Right T }
        !          3474:               Canvas.MoveTo(X2 + 1, Y1);
        !          3475:               Canvas.LineTo(X2 + 1, Y3);
        !          3476:               Canvas.MoveTo(X2 - 1, Y1);
        !          3477:               Canvas.LineTo(X2 - 1, Y2 - 1);
        !          3478:               Canvas.LineTo(X1 - 1, Y2 - 1);
        !          3479:               Canvas.MoveTo(X1,     Y2 + 1);
        !          3480:               Canvas.LineTo(X2 - 1, Y2 + 1);
        !          3481:               Canvas.LineTo(X2 - 1, Y3);
        !          3482:           end;
        !          3483:     #$C7: begin       { Double T Single Left }
        !          3484:               Canvas.MoveTo(X2 + 1, Y1);
        !          3485:               Canvas.LineTo(X2 + 1, Y3);
        !          3486:               Canvas.MoveTo(X2 - 1, Y1);
        !          3487:               Canvas.LineTo(X2 - 1, Y3);
        !          3488:               Canvas.MoveTo(X2 + 1, Y2);
        !          3489:               Canvas.LineTo(X3,     Y2);
        !          3490:           end;
        !          3491:     #$B6: begin       { Double T Single Right }
        !          3492:               Canvas.MoveTo(X2 + 1, Y1);
        !          3493:               Canvas.LineTo(X2 + 1, Y3);
        !          3494:               Canvas.MoveTo(X2 - 1, Y1);
        !          3495:               Canvas.LineTo(X2 - 1, Y3);
        !          3496:               Canvas.MoveTo(X2 - 1, Y2);
        !          3497:               Canvas.LineTo(X1 - 1, Y2);
        !          3498:           end;
        !          3499:     #$D2: begin       { Single T Double Top }
        !          3500:               Canvas.MoveTo(X1, Y2);
        !          3501:               Canvas.LineTo(X3, Y2);
        !          3502:               Canvas.MoveTo(X2 - 1, Y2);
        !          3503:               Canvas.LineTo(X2 - 1, Y3);
        !          3504:               Canvas.MoveTo(X2 + 1, Y2);
        !          3505:               Canvas.LineTo(X2 + 1, Y3);
        !          3506:           end;
        !          3507:     #$D0: begin       { Single T Double Bottom }
        !          3508:               Canvas.MoveTo(X1, Y2);
        !          3509:               Canvas.LineTo(X3, Y2);
        !          3510:               Canvas.MoveTo(X2 - 1, Y2);
        !          3511:               Canvas.LineTo(X2 - 1, Y1);
        !          3512:               Canvas.MoveTo(X2 + 1, Y2);
        !          3513:               Canvas.LineTo(X2 + 1, Y1);
        !          3514:           end;
        !          3515:     #$DB: begin       { Full Block }
        !          3516:               Canvas.Rectangle(X1, Y1, X3, Y3);
        !          3517:           end;
        !          3518:     #$DC: begin       { Half Bottom Block }
        !          3519:               Canvas.Rectangle(X1, Y2, X3, Y3);
        !          3520:           end;
        !          3521:     #$DD: begin       { Half Left Block }
        !          3522:               Canvas.Rectangle(X1, Y1, X2, Y3);
        !          3523:           end;
        !          3524:     #$DE: begin       { Half Right Block }
        !          3525:               Canvas.Rectangle(X2, Y1, X3, Y3);
        !          3526:           end;
        !          3527:     #$DF: begin       { Half Top Block }
        !          3528:               Canvas.Rectangle(X1, Y1, X2, Y2);
        !          3529:           end;
        !          3530:     #$C5: begin       { Single Cross }
        !          3531:               Canvas.MoveTo(X1, Y2);
        !          3532:               Canvas.LineTo(X3, Y2);
        !          3533:               Canvas.MoveTo(X2, Y1);
        !          3534:               Canvas.LineTo(X2, Y3);
        !          3535:           end;
        !          3536:     #$CE: begin       { Double Cross }
        !          3537:               Canvas.MoveTo(X1,     Y2 - 1);
        !          3538:               Canvas.LineTo(X2 - 1, Y2 - 1);
        !          3539:               Canvas.LineTo(X2 - 1, Y1);
        !          3540:               Canvas.MoveTo(X1,     Y2 + 1);
        !          3541:               Canvas.LineTo(X2 - 1, Y2 + 1);
        !          3542:               Canvas.LineTo(X2 - 1, Y3);
        !          3543:               Canvas.MoveTo(X2 + 1, Y1);
        !          3544:               Canvas.LineTo(X2 + 1, Y2 - 1);
        !          3545:               Canvas.LineTo(X3,     Y2 - 1);
        !          3546:               Canvas.MoveTo(X2 + 1, Y3);
        !          3547:               Canvas.LineTo(X2 + 1, Y2 + 1);
        !          3548:               Canvas.LineTo(X3,     Y2 + 1);
        !          3549:           end;
        !          3550:     #$D8: begin      { Cross Double Horizontal Single vertical }
        !          3551:               Canvas.MoveTo(X1, Y2 + 1);
        !          3552:               Canvas.LineTo(X3, Y2 + 1);
        !          3553:               Canvas.MoveTo(X1, Y2 - 1);
        !          3554:               Canvas.LineTo(X3, Y2 - 1);
        !          3555:               Canvas.MoveTo(X2, Y1);
        !          3556:               Canvas.LineTo(X2, Y3);
        !          3557:           end;
        !          3558:     #$D7: begin      { Cross Single Horizontal Double Vertical }
        !          3559:               Canvas.MoveTo(X2 + 1, Y1);
        !          3560:               Canvas.LineTo(X2 + 1, Y3);
        !          3561:               Canvas.MoveTo(X2 - 1, Y1);
        !          3562:               Canvas.LineTo(X2 - 1, Y3);
        !          3563:               Canvas.MoveTo(X1,     Y2);
        !          3564:               Canvas.LineTo(X3,     Y2);
        !          3565:           end;
        !          3566:     #$CA: begin      { Double T bottom }
        !          3567:               Canvas.MoveTo(X1,     Y2 - 1);
        !          3568:               Canvas.LineTo(X2 - 1, Y2 - 1);
        !          3569:               Canvas.LineTo(X2 - 1, Y1);
        !          3570:               Canvas.MoveTo(X2 + 1, Y1);
        !          3571:               Canvas.LineTo(X2 + 1, Y2 - 1);
        !          3572:               Canvas.LineTo(X3,     Y2 - 1);
        !          3573:               Canvas.MoveTo(X1,     Y2 + 1);
        !          3574:               Canvas.LineTo(X3,     Y2 + 1);
        !          3575:           end;
        !          3576:     #$CB: begin      { Double T  }
        !          3577:               Canvas.MoveTo(X1,     Y2 + 1);
        !          3578:               Canvas.LineTo(X2 - 1, Y2 + 1);
        !          3579:               Canvas.LineTo(X2 - 1, Y3);
        !          3580:               Canvas.MoveTo(X2 + 1, Y3);
        !          3581:               Canvas.LineTo(X2 + 1, Y2 + 1);
        !          3582:               Canvas.LineTo(X3,     Y2 + 1);
        !          3583:               Canvas.MoveTo(X1,     Y2 - 1);
        !          3584:               Canvas.LineTo(X3,     Y2 - 1);
        !          3585:           end;
        !          3586:     #$B0: begin
        !          3587:               Co := Canvas.Pen.Color;
        !          3588:               for Y := Y1 to Y3 do begin
        !          3589:                   X := X1 + (Y mod 3);
        !          3590:                   while X < X3 do begin
        !          3591:                       Canvas.Pixels[X, Y] := Co;
        !          3592:                       X := X + 3;
        !          3593:                   end;
        !          3594:               end;
        !          3595:           end;
        !          3596:     #$B1: begin
        !          3597:               Co := Canvas.Pen.Color;
        !          3598:               for Y := Y1 to Y3 do begin
        !          3599:                   X := X1 + (Y and 1);
        !          3600:                   while X < X3 do begin
        !          3601:                       Canvas.Pixels[X, Y] := Co;
        !          3602:                       X := X + 2;
        !          3603:                   end;
        !          3604:               end;
        !          3605:           end;
        !          3606:     #$B2: begin
        !          3607:               Co := Canvas.Pen.Color;
        !          3608:               for Y := Y1 to Y3 do begin
        !          3609:                   X := X1 + (Y mod 3);
        !          3610:                   while X < X3 do begin
        !          3611:                       Canvas.Pixels[X, Y] := Co;
        !          3612:                       Inc(X);
        !          3613:                       if X < X3 then
        !          3614:                           Canvas.Pixels[X, Y] := Co;
        !          3615:                       Inc(X);
        !          3616:                       Inc(X);
        !          3617:                   end;
        !          3618:               end;
        !          3619:           end;
        !          3620:     end;
        !          3621: end;
        !          3622: 
        !          3623: 
        !          3624: {* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *}
        !          3625: procedure TCustomEmulVT.PaintOneLine(
        !          3626:     DC         : HDC;
        !          3627:     Y, Y1      : Integer;
        !          3628:     const Line : TLine;
        !          3629:     nColFrom   : Integer;
        !          3630:     nColTo     : Integer);
        !          3631: var
        !          3632:     rc       : TRect;
        !          3633:     nCnt     : Integer;
        !          3634:     nAtt     : Byte;
        !          3635:     X        : Integer;
        !          3636:     nChr     : Integer;
        !          3637:     Ch       : Char;
        !          3638: begin
        !          3639:     nAtt := Line.Att[nColFrom];
        !          3640: 
        !          3641: {    if nAtt = $0B then
        !          3642:         X := 0; }
        !          3643: {
        !          3644:     SetBkColor(DC, PALETTEINDEX(nAtt div $0F));
        !          3645:     SetTextColor(DC, PALETTEINDEX(nAtt and $0F));
        !          3646: }
        !          3647:     if not FMonoChrome then begin
        !          3648:         with FPaletteEntries[(nAtt shr 4) and $0F] do
        !          3649:             SetBkColor(DC, PALETTERGB(peRed, peGreen, peBlue));
        !          3650:         with FPaletteEntries[nAtt and $0F] do begin
        !          3651:             SetTextColor(DC, PALETTERGB(peRed, peGreen, peBlue));
        !          3652:             Canvas.Pen.Color   := PALETTERGB(peRed, peGreen, peBlue);
        !          3653:             Canvas.Brush.Color := PALETTERGB(peRed, peGreen, peBlue);
        !          3654:         end;
        !          3655:     end
        !          3656:     else begin
        !          3657:         if (nAtt div $0F) <> 0 then
        !          3658:             SetBkColor(DC, RGB(127, 127, 127))
        !          3659:         else
        !          3660:             SetBkColor(DC, RGB(255, 255, 255));
        !          3661: 
        !          3662:         if (nAtt and $0F) <> 0 then
        !          3663:             SetTextColor(DC, RGB(0, 0, 0))
        !          3664:         else
        !          3665:             SetTextColor(DC, RGB(255, 255, 255));
        !          3666:     end;
        !          3667: 
        !          3668:     nCnt      := nColTo - nColFrom;
        !          3669:     nChr      := 0;
        !          3670: {$IFDEF SINGLE_CHAR_PAINT}
        !          3671:     while nChr < nCnt do begin
        !          3672: {$IFDEF CHAR_ZOOM}
        !          3673:         X         := LeftMargin + FCharPos[nColFrom + nChr];
        !          3674:         rc.Top    := Y  + FInternalLeading;
        !          3675:         rc.Bottom := Y1 + FInternalLeading;
        !          3676:         rc.Left   := X;
        !          3677:         rc.Right  := LeftMargin + FCharPos[nColFrom + nChr + 1];
        !          3678: {$ELSE}
        !          3679:         X         := LeftMargin + (nColFrom + nChr) * FCharWidth;
        !          3680:         rc.Top    := Y  + FInternalLeading;
        !          3681:         rc.Bottom := Y1 + FInternalLeading;
        !          3682:         rc.Left   := X;
        !          3683:         rc.Right  := rc.Left + FCharWidth;
        !          3684: {$ENDIF}
        !          3685:         if (nColFrom + nChr) = 0 then
        !          3686:            rc.Left := rc.Left - LeftMargin;
        !          3687:         if (nColFrom + nChr) >= FScreen.FColCount then
        !          3688:            rc.Right := rc.Right + RightMargin;
        !          3689:         Ch := Line.Txt[nColFrom + nChr];
        !          3690:         if FGraphicDraw and
        !          3691:            (FScreen.FXlatOutputTable = @ibm_iso8859_1_G0) and
        !          3692:            (Ch >= #$B0) and (Ch <= #$DF) and
        !          3693:            (Ch in [#$B3, #$C4, #$DA, #$C0, #$C1, #$C2, #$C3, #$B4, #$BF, #$D9,
        !          3694:                    #$DB, #$DC, #$DD, #$DE, #$DF,
        !          3695:                    #$BA, #$CD, #$C9, #$C8, #$BB, #$BC,
        !          3696:                    #$CC, #$B9, #$C7, #$B6, #$D2, #$D0,
        !          3697:                    #$D5, #$D4, #$B8, #$BE,
        !          3698:                    #$C6, #$D1, #$B5, #$CF,
        !          3699:                    #$D6, #$B7, #$D3, #$BD,
        !          3700:                    #$C5, #$CE, #$D8, #$D7, #$CA, #$CB,
        !          3701:                    #$B0, #$B1, #$B2]) then
        !          3702:             PaintGraphicChar(DC, X, Y, @rc, Ch)
        !          3703:         else
        !          3704:             ExtTextOut(DC, X, Y, ETO_OPAQUE or ETO_CLIPPED, @rc, @Ch, 1, nil);
        !          3705:         Inc(nChr);
        !          3706:     end;
        !          3707: {$ELSE}
        !          3708: {$IFDEF CHAR_ZOOM}
        !          3709:     X         := LeftMargin + FCharPos[nColFrom];
        !          3710:     rc.Top    := Y  + FInternalLeading;
        !          3711:     rc.Bottom := Y1 + FInternalLeading;
        !          3712:     rc.Left   := X;
        !          3713:     rc.Right  := LeftMargin + FCharPos[nColFrom + nCnt];
        !          3714: {$ELSE}
        !          3715:     X         := LeftMargin + nColFrom * FCharWidth;
        !          3716:     rc.Top    := Y  + FInternalLeading;
        !          3717:     rc.Bottom := Y1 + FInternalLeading;
        !          3718:     rc.Left   := X;
        !          3719:     rc.Right  := rc.Left + nCnt * FCharWidth;
        !          3720: {$ENDIF}
        !          3721:     if nColFrom = 0 then
        !          3722:        rc.Left := rc.Left - LeftMargin;
        !          3723:     if nColTo >= FScreen.FColCount then
        !          3724:        rc.Right := rc.Right + RightMargin;
        !          3725:     ExtTextOut(DC,
        !          3726:                X, Y,
        !          3727:                ETO_OPAQUE or ETO_CLIPPED, @rc,
        !          3728:                @Line.Txt[nColFrom], nCnt, nil);
        !          3729: {$ENDIF}
        !          3730: end;
        !          3731: 
        !          3732: 
        !          3733: {* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *}
        !          3734: procedure TCustomEmulVT.WMPaint(var Message: TWMPaint);
        !          3735: var
        !          3736:     DC        : HDC;
        !          3737:     PS        : TPaintStruct;
        !          3738:     Y, Y1     : Integer;
        !          3739:     rc        : TRect;
        !          3740:     OldPen    : THandle;
        !          3741:     OldBrush  : THandle;
        !          3742:     OldFont   : THandle;
        !          3743:     rcPaint   : TRect;
        !          3744:     DrawRct   : TRect;
        !          3745:     nRow      : Integer;
        !          3746:     nCol      : Integer;
        !          3747:     nColFrom  : Integer;
        !          3748:     Line      : TLine;
        !          3749:     BackBrush : HBrush;
        !          3750: begin
        !          3751:     { This may be a bit of overkill but we have to keep the scrollbar tracking
        !          3752:       with the number of lines visible on the screen.  The calling program can
        !          3753:       change the Height of the screen and we don't have a good way to know that.
        !          3754:       This routine will get called whenever the screen gets updated so it is a
        !          3755:       good time to update the scrollbar. }
        !          3756:     AdjustScrollBar;
        !          3757: 
        !          3758:     if not GetUpdateRect(WindowHandle, rc, FALSE) then
        !          3759:         Exit;
        !          3760: 
        !          3761:     BackBrush := 0;
        !          3762:     OldBrush  := 0;
        !          3763: 
        !          3764:     DC := Message.DC;
        !          3765:     if DC = 0 then
        !          3766:         DC := BeginPaint(WindowHandle, PS);
        !          3767:     try
        !          3768:         if not FMonoChrome then begin
        !          3769:             SelectPalette(DC, FPal, FALSE);
        !          3770:             RealizePalette(DC);
        !          3771:             with FPaletteEntries[FScreen.FAttribute div $0F] do
        !          3772:                 BackBrush := CreateSolidBrush(PALETTERGB(peRed, peGreen, peBlue));
        !          3773:             OldBrush := SelectObject(DC, BackBrush);
        !          3774:         end;
        !          3775: 
        !          3776:         WinProcs.GetClientRect(WindowHandle, DrawRct);
        !          3777:         rcPaint  := PS.rcPaint;
        !          3778:         rc.Left  := 2;
        !          3779:         rc.Right := DrawRct.Right - 2;
        !          3780:         nRow     := PixelToRow(rcPaint.top);
        !          3781:         nRow := nRow - 1;
        !          3782:         if nRow < 0 then
        !          3783:             nRow := 0;
        !          3784: 
        !          3785: {$IFDEF CHAR_ZOOM}
        !          3786:         Y  := TopMargin + FLinePos[nRow];
        !          3787:         Y1 := TopMargin + FLinePos[nRow + 1];
        !          3788: {$ELSE}
        !          3789:         Y  := TopMargin + nRow * FLineHeight;
        !          3790:         Y1 := Y + FLineHeight;
        !          3791: {$ENDIF}
        !          3792: 
        !          3793:         if rcPaint.Top <= TopMargin then begin
        !          3794:             OldPen := SelectObject(DC, GetStockObject(NULL_PEN));
        !          3795:             WinProcs.Rectangle(DC, rcPaint.left, rcPaint.Top,
        !          3796:                                rcPaint.Right + 1,
        !          3797:                                TopMargin + FInternalLeading + 1);
        !          3798:             SelectObject(DC, OldPen);
        !          3799:         end;
        !          3800: 
        !          3801:         if (nRow = 0) and (FInternalLeading > 0) then begin
        !          3802:             OldPen := SelectObject(DC, GetStockObject(NULL_PEN));
        !          3803:             WinProcs.Rectangle(DC, rcPaint.left, rcPaint.Top,
        !          3804:                                rcPaint.Right + 1,
        !          3805:                                Y + FInternalLeading + 1);
        !          3806:             SelectObject(DC, OldPen);
        !          3807:         end;
        !          3808: 
        !          3809:         OldFont := SelectObject(DC, FFont.Handle);
        !          3810:         nRow    := nRow + FTopLine;
        !          3811:         while nRow < FScreen.FRowCount do begin
        !          3812:             rc.Top    := Y;
        !          3813:             rc.Bottom := Y + FLineHeight;
        !          3814:             if rc.Bottom > (DrawRct.Bottom - BottomMargin) then begin
        !          3815:                 OldPen := SelectObject(DC, GetStockObject(NULL_PEN));
        !          3816:                 WinProcs.Rectangle(DC, rc.Left - 2, rc.Top, rc.Right + 1,
        !          3817:                                    DrawRct.Bottom - 1);
        !          3818:                 SelectObject(DC, OldPen);
        !          3819:                 Break;
        !          3820:             end;
        !          3821:             Line := FScreen.Lines[nRow];
        !          3822: 
        !          3823:             nCol     := 0;
        !          3824:             nColFrom := 0;
        !          3825:             while nCol < FScreen.FColCount do begin
        !          3826:                 while (nCol < FScreen.FColCount) and
        !          3827:                       (Line.Att[nCol] = Line.Att[nColFrom]) do
        !          3828:                     Inc(nCol);
        !          3829: 
        !          3830:                 PaintOneLine(DC, Y, Y1, Line, nColFrom, nCol);
        !          3831:                 nColFrom := nCol;
        !          3832:             end;
        !          3833: 
        !          3834:             nRow := nRow + 1;
        !          3835: {$IFDEF CHAR_ZOOM}
        !          3836:             Y    := TopMargin + FLinePos[nRow - FTopLine];
        !          3837:             Y1   := TopMargin + FLinePos[nRow + 1 - FTopLine];
        !          3838: {$ELSE}
        !          3839:             Y    := Y + FLineHeight;
        !          3840:             Y1   := Y + FLineHeight;
        !          3841: {$ENDIF}
        !          3842:             if Y > rcPaint.Bottom then
        !          3843:                 Break;
        !          3844:         end;
        !          3845: 
        !          3846:         { Fill region between last text line and bottom of the window }
        !          3847:         OldPen := SelectObject(DC, GetStockObject(NULL_PEN));
        !          3848:         if (FScreen.FRowCount - FTopLine) <= MAX_ROW then { WM + SE 09/08/00 }
        !          3849:            WinProcs.Rectangle(DC, rc.Left - 2,
        !          3850:                               TopMargin + FLinePos[FScreen.FRowCount - FTopLine] + 1,
        !          3851:                               rc.Right + 1, DrawRct.Bottom + 1);
        !          3852:         SelectObject(DC, OldPen);
        !          3853: 
        !          3854: {$IFDEF CHAR_ZOOM}
        !          3855:         if (LeftMargin + FCharPos[FScreen.FColCount]) < rc.Right then begin
        !          3856:             OldPen := SelectObject(DC, GetStockObject(NULL_PEN));
        !          3857:             WinProcs.Rectangle(DC, LeftMargin + FCharPos[FScreen.FColCount],
        !          3858:                                TopMargin,   { 09/03/99 }
        !          3859:                                rcPaint.Right + 1, DrawRct.Bottom + 1);
        !          3860:             SelectObject(DC, OldPen);
        !          3861:         end;
        !          3862: {$ELSE}
        !          3863:         if (LeftMargin + FScreen.FColCount * FCharWidth) < rc.Right then begin
        !          3864:             OldPen := SelectObject(DC, GetStockObject(NULL_PEN));
        !          3865:             WinProcs.Rectangle(DC, LeftMargin + FScreen.FColCount * FCharWidth,
        !          3866:                                TopMargin, rc.Right + 1, DrawRct.Bottom - 1);
        !          3867:             SelectObject(DC, OldPen);
        !          3868:         end;
        !          3869: {$ENDIF}
        !          3870: 
        !          3871:         if FSelectRect.Top <> -1 then begin
        !          3872:             SelectObject(DC, GetStockObject(NULL_BRUSH));
        !          3873:             SelectObject(DC, GetStockObject(BLACK_PEN));
        !          3874:             WinProcs.Rectangle(DC, FSelectRect.Left,
        !          3875:                                    FSelectRect.Top,
        !          3876:                                    FSelectRect.Right + 1,
        !          3877:                                    FSelectRect.Bottom - 1);
        !          3878:             SelectObject(DC, GetStockObject(WHITE_PEN));
        !          3879:             WinProcs.Rectangle(DC, FSelectRect.Left - 1,
        !          3880:                                    FSelectRect.Top - 1,
        !          3881:                                    FSelectRect.Right + 2,
        !          3882:                                    FSelectRect.Bottom);
        !          3883:         end;
        !          3884: 
        !          3885:         SelectObject(DC, OldFont);
        !          3886:         if OldBrush <> 0 then
        !          3887:             SelectObject(DC, OldBrush);
        !          3888:         if BackBrush <> 0 then
        !          3889:             DeleteObject(BackBrush);
        !          3890:     finally
        !          3891:         if Message.DC = 0 then
        !          3892:             EndPaint(WindowHandle, PS);
        !          3893:     end;
        !          3894: end;
        !          3895: 
        !          3896: 
        !          3897: {* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *}
        !          3898: 
        !          3899: end.
        !          3900: 

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.