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