(*########################################################################## M A G I C T E R M I N A L ########################################################################## Emuliert ein VT52-Terminal in einem w„hlbaren Bildschirmbereich. ########################################################################## V2.0 19.10.90 Peter Hellinger Anpassung an neues MagicSys V1.3 11.05.90 Peter Hellinger GEM-Fonthandling eingebaut V1.2 06.05.90 Peter Hellinger Es werden jetzt alle Escapes unter- sttzt, auch die, die mehrere Para- meter ben”tigen. V1.1 04.05.90 Peter Hellinger Wordwrapping wird jetzt untersttzt Default ist jedoch immer WrapOff! V1.0 29.04.90 Peter Hellinger Implementation fr TDI-Modula-2 ##########################################################################*) IMPLEMENTATION MODULE mtTerminal; (*------------------------------*) (* COMPILERSWITCHES *) (*------------------------------*) (* TDI-Version: DEAKTIVIERT *) (*------------------------------*) (* V- Overflow-Checks *) (* R- Range-Checks *) (* S- Stack-Check *) (* N- NIL-Checks *) (* T- TDI-Compiler vor 3.01 *) (* Q+ Branch statt Jumps *) (* *) (*------------------------------*) (* MM2-Version: AKTIVIERT *) (*------------------------------*) (*$R- Range-Checks *) (*$S- Stack-Check *) (* *) (*------------------------------*) FROM SYSTEM IMPORT ADDRESS, ADR; FROM Storage IMPORT ALLOCATE, DEALLOCATE; FROM MagicStrings IMPORT Assign, Append, Length; FROM mtConvert IMPORT CardToStr, IntToStr, LCardToStr, LIntToStr, LRealToStr, RealToStr; FROM MagicVDI IMPORT VDIIntIn, VDIPtsIn, VDICall; FROM mtAppl IMPORT VDIHandle, MaxWidth, MaxHeight, Bitplanes, OpenWorkstation, CloseWorkstation, FontCode, SelectFont, ScaleFont, Monospaced, FontInfo, LoadFonts, MouseOn, MouseOff; FROM MagicSys IMPORT Nil, Null, Bit0, Bit1, Bit2, Bit3, Bit4, Bit5, Bit6, Bit7, Bit8, Bit9, Bit10, Bit11, Bit12, Bit13, Bit14, Bit15, LOC, Byte, ByteSet, sWORD, sINTEGER, sCARDINAL, sBITSET, lWORD, lINTEGER, lCARDINAL, lBITSET, CastToChar, CastToByte, CastToByteset, CastToInt, CastToCard, CastToBitset, CastToWord, CastToLInt, CastToLCard, CastToLBitset, CastToLWord, CastToAddr; IMPORT MagicBIOS, MagicDOS, MagicAES, MagicVDI; (*--------------------------------------------------------------------------* * Zustandsflags des Terminals * *--------------------------------------------------------------------------*) CONST cActive = 0; (* Terminal aktiv (Vordergrund) *) cErase = 1; (* Zeichen vorl”schen? *) cCursor = 2; (* Cursor ein? *) cBlink = 3; (* Cursor blinkend? *) cWrap = 4; (* Word-Wrapping *) cEscape = 5; (* Escape wurde ausgegeben *) cEscYs = 6; (* Escape Y: Spaltenwert wird erwartet *) cEscYz = 7; (* Escape Y: Zeilenwert wird erwartet *) cEscb = 8; (* Escape b: Vordergrundfarbe wird erwartet *) cEscc = 9; (* Escape c: Hintergrundfarbe wird erwartet *) cBColor = 10; (* Hintergrundfarbe beim Schreiben *) cRedraw = 11; (* Redrawfeature eingeschaltet *) cFlag12 = 12; cFlag13 = 13; cFlag14 = 14; cFlag15 = 15; (*--------------------------------------------------------------------------*) TYPE TERMINAL = POINTER TO TerminalTyp; TerminalTyp = RECORD x: sINTEGER; (* X-Koordinate *) y: sINTEGER; (* Y-Koordinate *) px: sINTEGER; (* X-Pixelpos des Cursor *) py: sINTEGER; (* Y-Pixelpos des Cursors *) mx: sINTEGER; (* Position rechter Rand *) my: sINTEGER; (* Position linker Rand *) lastCol: sINTEGER; (* Pixelpos der letzten Spalte *) lastLn: sINTEGER; (* Pixelpos der letzten Zeile *) zBreite: sINTEGER; (* Zeichenbreite *) zHoehe: sINTEGER; (* Zeichenh”he *) chwidth: sINTEGER; (* Breite des Zeichens - 1 *) linehi: sINTEGER; (* H”he der Bildschirmzeile - 1 *) pmx: sINTEGER; (* Cursor-Breite *) pmy: sINTEGER; (* Cursor-H”he *) sx: sINTEGER; (* *) sy: sINTEGER; (* *) xoff: sINTEGER; (* Offset fr kursive Schrift *) yoff: sINTEGER; (* fr tiefgestellte Schrift *) w: sINTEGER; (* Breite in Pixel *) h: sINTEGER; (* H”he in Pixel *) sp: sINTEGER; (* Anzahl der Spalten *) zl: sINTEGER; (* Anzahl der Zeilen *) font: sINTEGER; (* Fontnummer *) size: sINTEGER; (* Fontgr”že *) vColor: sINTEGER; (* Vordergrundfarbe (Text) *) hColor: sINTEGER; (* Hintergrundfarbe *) tab: sINTEGER; (* Tabweite *) effect: Attribut; (* Texteffekte *) zustand: sBITSET; (* Zustand des Terminals *) END; (* TerminalTyp *) (*--------------------------------------------------------------------------*) TYPE tRect = RECORD x, y, w, h: sINTEGER; END; VAR d, q: MagicVDI.MFDB; dPtr: ADDRESS; qPtr: ADDRESS; VAR control7: POINTER TO ADDRESS; control9: POINTER TO ADDRESS; VAR InversHandle: sINTEGER; NormalHandle: sINTEGER; TextHandle: sINTEGER; VAR rect: tRect; rect2: tRect; VAR Half: sINTEGER; (* H”he fr Hoch/Tiefgestellt *) Full: sINTEGER; (* H”he fr Normale Schrift *) Status: sINTEGER; VAR MaxLines: sINTEGER; (* max. Anzahl Zeilen des Bildschirms *) MaxColumns: sINTEGER; (* max. Anzahl Spalten des Bildschirms *) MinX: sINTEGER; (* Ursprung des Bildschirms *) MinY: sINTEGER; VAR GEMFonts: BOOLEAN; (* GEMFonts benutzen, default off *) (*--------------------------------------------------------------------------*) VAR conterm[0484H]: ByteSet; PROCEDURE Glocke; CONST glocke = 2; VAR stack: ADDRESS; BEGIN stack:= 0; MagicDOS.Super (stack); IF (glocke IN conterm) THEN MagicBIOS.Bconout (MagicBIOS.CON, CHR(7)); END; MagicDOS.Super (stack); END Glocke; PROCEDURE Cursor; (* Schaltet Cursor ein und aus, XOR-Modus *) BEGIN WITH Terminal^ DO IF cCursor IN zustand THEN VDIPtsIn[0]:= px; VDIPtsIn[1]:= py; VDIPtsIn[2]:= pmx; VDIPtsIn[3]:= pmy; VDICall(114, 2, 0, 0, InversHandle); END; (* IF cCursor *) END; (* WITH *) END Cursor; PROCEDURE Scrollup; (* Geht davon aus, daž Maus und Cursor aus sind. Diese Routine wird nur * intern aufgerufen, so daž dieses Vorgehen keine Probleme bereitet *) BEGIN WITH Terminal^ DO VDIPtsIn[0]:= x; VDIPtsIn[1]:= y + zHoehe; VDIPtsIn[2]:= mx; VDIPtsIn[3]:= my; VDIPtsIn[4]:= x; VDIPtsIn[5]:= y; VDIPtsIn[6]:= mx; VDIPtsIn[7]:= lastLn; VDIIntIn[0]:= 3; control7^:= qPtr; control9^:= dPtr; VDICall(109, 4, 1, 0, NormalHandle); VDIPtsIn[0]:= x; VDIPtsIn[1]:= lastLn; VDIPtsIn[2]:= mx; VDIPtsIn[3]:= my; VDICall (114, 2, 0, 0, NormalHandle); END; END Scrollup; VAR wert1: sINTEGER; wert2: sINTEGER; PROCEDURE Emulator (ch: CHAR); (* Handled alles, was mit Escape eingeleitet wurde *) BEGIN WITH Terminal^ DO IF {cEscYs, cEscYz, cEscb, cEscc} <= zustand THEN IF cEscYs IN zustand THEN wert1:= ORD(ch) - 32; INCL (zustand, cEscYz); EXCL (zustand, cEscYs); ELSIF cEscYz IN zustand THEN wert2:= ORD(ch) - 32; IF wert2 < 0 THEN wert2:= 0; END; EXCL (zustand, cEscYz); GotoXY (wert2, wert1); ELSIF cEscb IN zustand THEN ForegroundColor (ORD (ch)); ELSIF cEscc IN zustand THEN BackgroundColor (ORD (ch)); END; IF {cEscYz, cEscb, cEscc} <= zustand THEN EXCL (zustand, cEscape); END; ELSE CASE ch OF 'A': IF py > y THEN DEC (py, zHoehe); DEC (pmy, zHoehe); END;| 'B': IF py < lastLn THEN INC (py, zHoehe); INC (pmy, zHoehe); END;| 'C': IF px > x THEN DEC (px, zBreite); DEC (pmx, zBreite); END;| 'D': IF px < lastCol THEN INC(px, zBreite); INC(pmx, zBreite); END;| 'E': ClearScreen;| 'H': GotoXY (0, 0);| 'I': IF py > y THEN DEC (py, zHoehe); DEC (pmy, zHoehe); END; IF py = y THEN InsertLine; END;| 'J': ClearEndOfScreen;| 'K': ClearLine;| 'L': InsertLine;| 'M': DeleteLine;| 'Y': INCL (zustand, cEscYs); RETURN;| 'b': INCL (zustand, cEscb); RETURN;| 'c': INCL (zustand, cEscc); RETURN;| 'd': ClearStartOfScreen;| 'e': CursorOn;| 'f': CursorOff;| 'j': sx:= px; sy:= py;| 'k': px:= sx; py:= sy; pmx:= px + chwidth; pmy:= py + linehi;| 'l': ClearLine; px:= x; pmx:= px + chwidth;| 'o': ClearStartOfLine;| 'p': INCL (effect, invers);| 'q': EXCL (effect, invers);| 'v': INCL (zustand, cWrap);| 'w': EXCL (zustand, cWrap);| CHR(128)..CHR(255): SetAttribut (Attribut (ch));| ELSE; END; (* CASE *) EXCL(zustand, cEscape); END; (* IF *) END; (* WITH *) END Emulator; PROCEDURE ControlChar (ch: CHAR); (* Bearbeitet alles was kleiner als Blank ist *) VAR b: Attribut; s: sINTEGER; BEGIN WITH Terminal^ DO CASE ORD(ch) OF 0: | 7: Glocke; | 8: (* Backspace *) IF px > x THEN DEC (px, zBreite); DEC (pmx, zBreite); END; VDIPtsIn[0]:= px; VDIPtsIn[1]:= py; VDIPtsIn[2]:= pmx; VDIPtsIn[3]:= pmy; VDICall (114, 2, 0, 0, NormalHandle); | 9: (* TAB *) s:= x + (((((px - x) DIV zBreite) DIV tab) + 1) * tab) * zBreite; DEC (s, zBreite); IF (px + s) < lastCol THEN px:= s; ELSE px:= lastCol; END; pmx:= px + chwidth; | 10: (* Linefeed *) INC(py, linehi); IF py > lastLn THEN py:= lastLn; Scrollup; END; pmy:= py + linehi; | 12: (* Home *) ClearScreen; | 13: (* Carriage-Return *) px:= x; pmx:= px + chwidth; | 27: (* Escape *) INCL(zustand, cEscape); | ELSE b:= effect; INCL (effect, invers); WriteChar (CHR(ORD(ch)+ 64)); effect:= b; END; (* CASE *) END; (* WITH *) END ControlChar; PROCEDURE WriteChar (ch: CHAR); VAR i: sINTEGER; BEGIN MouseOff; Cursor; WITH Terminal^ DO IF cEscape IN zustand THEN Emulator(ch); ELSIF ORD(ch) < 32 THEN ControlChar(ch); ELSE (* Normales Zeichen *) IF px > lastCol THEN IF cWrap IN zustand THEN px:= x; INC(py, zHoehe); IF py > lastLn THEN py:= lastLn; Scrollup; END; pmx:= px + chwidth; pmy:= py + linehi; ELSE px:= lastCol; pmx:= px + chwidth; END; END; VDIPtsIn[0]:= px; VDIPtsIn[1]:= py; i:= px; INC(px, zBreite); IF {cErase, cBColor} <= zustand THEN (* Zeichen l”schen *) VDIPtsIn[2]:= px; VDIPtsIn[3]:= pmy; VDICall (114, 2, 0, 0, NormalHandle); END; VDIIntIn[0]:= ORD(ch); VDIIntIn[1]:= 0; INC(VDIPtsIn[0], xoff); INC(VDIPtsIn[1], yoff); VDICall (8, 1, 1, 0, TextHandle); IF invers IN effect THEN VDIPtsIn[0]:= i; VDIPtsIn[1]:= py; VDIPtsIn[2]:= i + chwidth; VDIPtsIn[3]:= pmy; VDICall (114, 2, 0, 0, InversHandle); END; pmx:= px + chwidth; pmy:= py + linehi; Cursor; END; (* IF *) END; (* WITH *) END WriteChar; PROCEDURE WriteLine (VAR string: ARRAY OF CHAR); VAR c, d, l: sCARDINAL; i, j: sINTEGER; BEGIN MouseOff; Cursor; c:= 0; l:= HIGH(string); LOOP IF (c > l) THEN EXIT; END; (* String zu Ende *) CASE ORD(string[c]) OF 0: EXIT; (* String zu Ende *) | 27: INC(c); INCL(Terminal^.zustand, cEscape); WHILE cEscape IN Terminal^.zustand DO Emulator (string[c]); INC(c); IF (c > l) THEN EXIT; END; END; | 1..26, 28..31: ControlChar(string[c]); INC(c); | ELSE (* Scanne String bis Zeichen < Blank und gebe ihn aus *) WITH Terminal^ DO d:= 0; i:= px; WHILE (px <= lastCol) & (string[c] > 37C) & (c <= l) DO VDIIntIn[d]:= ORD(string[c]); INC(d); INC(c); INC(px, zBreite); END; VDIPtsIn[0]:= i; VDIPtsIn[1]:= py; IF {cErase, cBColor} <= zustand THEN VDIPtsIn[2]:= px; VDIPtsIn[3]:= pmy; VDICall (114, 2, 0, 0, NormalHandle); END; VDIIntIn[d]:= 0; INC(VDIPtsIn[0], xoff); INC(VDIPtsIn[1], yoff); VDICall (8, 1, d, 0, TextHandle); IF invers IN effect THEN VDIPtsIn[0]:= i; VDIPtsIn[1]:= py; VDIPtsIn[2]:= px - sINTEGER(1); VDIPtsIn[3]:= pmy; VDICall (114, 2, 0, 0, InversHandle); END; IF px > lastCol THEN IF cWrap IN zustand THEN px:= x; INC(py, zHoehe); IF py > lastLn THEN py:= lastLn; Scrollup; END; pmx:= px + chwidth; pmy:= py + linehi; ELSE px:= lastCol; EXIT; END; END; END; (* WITH *) END; (* CASE *) END; (* LOOP *) WITH Terminal^ DO pmx:= px + chwidth; END; Cursor; END WriteLine; PROCEDURE WriteConst (string: ARRAY OF CHAR); BEGIN WriteLine(string); END WriteConst; PROCEDURE WriteLn; BEGIN MouseOff; Cursor; WITH Terminal^ DO px:= x; INC(py, zHoehe); IF py > lastLn THEN py:= lastLn; Scrollup; END; pmx:= px + chwidth; pmy:= py + linehi; END; Cursor; END WriteLn; VAR string: ARRAY [0..255] OF CHAR; PROCEDURE WriteCard (wert: sCARDINAL; len: sCARDINAL); BEGIN CardToStr (wert, len, string); WriteLine (string); END WriteCard; PROCEDURE WriteInt (wert: sINTEGER; len: sCARDINAL); BEGIN IntToStr (wert, len, string); WriteLine (string); END WriteInt; PROCEDURE WriteLongCard (wert: lCARDINAL; len: sCARDINAL); BEGIN LCardToStr (wert, len, string); WriteLine (string); END WriteLongCard; PROCEDURE WriteLongInt (wert: lINTEGER; len: sCARDINAL); BEGIN LIntToStr (wert, len, string); WriteLine (string); END WriteLongInt; PROCEDURE WriteReal (wert: REAL; len: sCARDINAL); BEGIN RealToStr (wert, len, string); WriteLine (string); END WriteReal; PROCEDURE WriteLongReal (wert: LONGREAL; len: sCARDINAL); BEGIN LRealToStr (wert, len, string); WriteLine (string); END WriteLongReal; PROCEDURE InsertLine; BEGIN WITH Terminal^ DO MouseOff; Cursor; px:= x; pmx:= px + chwidth; VDIPtsIn[0]:= px; VDIPtsIn[1]:= py; VDIPtsIn[2]:= mx; VDIPtsIn[3]:= my - zHoehe; VDIPtsIn[4]:= px; VDIPtsIn[5]:= py + zHoehe; VDIPtsIn[6]:= mx; VDIPtsIn[7]:= my; VDIIntIn[0]:= 3; control7^:= qPtr; control9^:= dPtr; VDICall (109, 4, 1, 0, NormalHandle); VDIPtsIn[0]:= x; VDIPtsIn[1]:= py; VDIPtsIn[2]:= mx; VDIPtsIn[3]:= pmy; VDICall (114, 2, 0, 0, NormalHandle); END; END InsertLine; PROCEDURE DeleteLine; BEGIN WITH Terminal^ DO MouseOff; Cursor; px:= x; pmx:= px + chwidth; VDIPtsIn[0]:= px; VDIPtsIn[1]:= py + zHoehe; VDIPtsIn[2]:= mx; VDIPtsIn[3]:= my; VDIPtsIn[4]:= px; VDIPtsIn[5]:= py; VDIPtsIn[6]:= mx; VDIPtsIn[7]:= lastLn; VDIIntIn[0]:= 3; control7^:= qPtr; control9^:= dPtr; VDICall (109, 4, 1, 0, NormalHandle); VDIPtsIn[0]:= x; VDIPtsIn[1]:= lastLn; VDIPtsIn[2]:= mx; VDIPtsIn[3]:= my; VDICall (114, 2, 0, 0, NormalHandle); END; END DeleteLine; PROCEDURE WhereXY (VAR spalte, zeile: sCARDINAL); BEGIN WITH Terminal^ DO spalte:= (px - x) DIV zBreite; zeile:= (py - y) DIV zHoehe; END; END WhereXY; PROCEDURE GotoXY (spalte, zeile: sCARDINAL); (* Die Home-Position wurde auf 0, 0 festgelegt *) BEGIN WITH Terminal^ DO MouseOff; Cursor; (* Cursor ausschalten *) px:= x + (CastToInt (spalte) * zBreite); py:= y + (CastToInt (zeile) * zHoehe); IF px < x THEN px:= x; END; IF py < y THEN py:= y; END; IF px > mx THEN px:= mx - zBreite; END; IF py > lastLn THEN py:= lastLn; END; pmx:= px + chwidth; pmy:= py + linehi; Cursor; END; (* WITH *) END GotoXY; PROCEDURE CursorOn; BEGIN IF NOT (cCursor IN Terminal^.zustand) THEN MouseOff; INCL(Terminal^.zustand, cCursor); Cursor; END; END CursorOn; PROCEDURE CursorOff; BEGIN IF cCursor IN Terminal^.zustand THEN MouseOff; Cursor; EXCL(Terminal^.zustand, cCursor); END; END CursorOff; PROCEDURE CursorStop; (* Wird ggw. nicht untersttzt *) END CursorStop; PROCEDURE CursorBlink; (* Wird ggw. nicht untersttzt *) END CursorBlink; PROCEDURE WrapOff; BEGIN EXCL(Terminal^.zustand, cWrap); END WrapOff; PROCEDURE WrapOn; BEGIN INCL(Terminal^.zustand, cWrap); END WrapOn; PROCEDURE ClearLine; BEGIN WITH Terminal^ DO MouseOff; Cursor; px:= x; pmx:= px + chwidth; VDIPtsIn[0]:= x; VDIPtsIn[1]:= py; VDIPtsIn[2]:= x + w -1; VDIPtsIn[3]:= pmy; VDICall (114, 2, 0, 0, NormalHandle); Cursor; END; END ClearLine; PROCEDURE ClearStartOfLine; BEGIN WITH Terminal^ DO MouseOff; Cursor; VDIPtsIn[0]:= x; VDIPtsIn[1]:= py; VDIPtsIn[2]:= px; VDIPtsIn[3]:= pmy; VDICall (114, 2, 0, 0, NormalHandle); Cursor; END; END ClearStartOfLine; PROCEDURE ClearEndOfLine; BEGIN WITH Terminal^ DO MouseOff; Cursor; VDIPtsIn[0]:= px; VDIPtsIn[1]:= py; VDIPtsIn[2]:= x + w - 1; VDIPtsIn[3]:= pmy; VDICall (114, 2, 0, 0, NormalHandle); Cursor; END; END ClearEndOfLine; PROCEDURE ClearScreen; BEGIN WITH Terminal^ DO MouseOff; Cursor; GotoXY (0, 0); VDIPtsIn[0]:= px; VDIPtsIn[1]:= py; VDIPtsIn[2]:= x + w - 1; VDIPtsIn[3]:= y + h - 1; VDICall (114, 2, 0, 0, NormalHandle); Cursor; END; (* WITH *) END ClearScreen; PROCEDURE ClearStartOfScreen; BEGIN WITH Terminal^ DO MouseOff; Cursor; VDIPtsIn[0]:= px; VDIPtsIn[1]:= py; VDIPtsIn[2]:= x; VDIPtsIn[3]:= pmy; VDICall (114, 2, 0, 0, NormalHandle); VDIPtsIn[0]:= x; VDIPtsIn[1]:= y; VDIPtsIn[2]:= x + w - 1; VDIPtsIn[3]:= py; VDICall (114, 2, 0, 0, NormalHandle); Cursor; END; (* WITH *) END ClearStartOfScreen; PROCEDURE ClearEndOfScreen; BEGIN WITH Terminal^ DO MouseOff; Cursor; VDIPtsIn[0]:= px; VDIPtsIn[1]:= py; VDIPtsIn[2]:= x + w - 1; VDIPtsIn[3]:= pmy; VDICall (114, 2, 0, 0, NormalHandle); VDIPtsIn[0]:= x; VDIPtsIn[1]:= py + zHoehe; VDIPtsIn[2]:= x + w - 1; VDIPtsIn[3]:= y + h - 1; VDICall (114, 2, 0, 0, NormalHandle); Cursor; END; (* WITH *) END ClearEndOfScreen; PROCEDURE ForegroundColor (color: sINTEGER); VAR old: sINTEGER; BEGIN Terminal^.vColor:= color; old:= MagicVDI.SetTextcolor (TextHandle, color); old:= MagicVDI.SetFillcolor (InversHandle, color); END ForegroundColor; PROCEDURE BackgroundColor (color: sINTEGER); VAR old, wm: sINTEGER; BEGIN Terminal^.hColor:= color; old:= MagicVDI.SetFillcolor (NormalHandle, color); IF color > 0 THEN INCL (Terminal^.zustand, cBColor); wm:= MagicVDI.SetWritemode (TextHandle, MagicVDI.XOR); ELSE EXCL (Terminal^.zustand, cBColor); wm:= MagicVDI.SetWritemode (TextHandle, MagicVDI.REPLACE); END; END BackgroundColor; PROCEDURE InversOn; BEGIN INCL (Terminal^.effect, invers); END InversOn; PROCEDURE InversOff; BEGIN EXCL (Terminal^.effect, invers); END InversOff; PROCEDURE SetAttribut (attrib: Attribut); VAR i: sINTEGER; bs: sBITSET; BEGIN MouseOff; WITH Terminal^ DO IF Attribut{subscript, superscript, italic} <= attrib THEN (* Das zu schreibende Zeichen muž am Bildschirm vorgel”scht werden *) INCL(zustand, cErase); END; (* Bei kursiver Schrift muž das Zeichen um einen Offset nach rechts * verschoben werden, da durch die Umsetzung des Alignments das Zeichen * nach links gezeichnet wird (kompliziert, ich geb's zu...) *) IF italic IN attrib THEN xoff:= zBreite DIV 2; rect.x:= x; rect.y:= y; rect.w:= x + w - 2; rect.h:= y + h - 2; MagicVDI.SetClipping(TextHandle, rect, TRUE); ELSIF italic IN effect THEN xoff:= 0; MagicVDI.SetClipping(TextHandle, rect, FALSE); ELSE xoff:= 0; END; (* Beim Tiefstellen von Zeichen muž noch ein Offset addiert werden, * da unsere Cursorposition immer die oberste Rasterzeile des Zeichens * beschreibt. *) IF Attribut{subscript, superscript} <= attrib THEN yoff:= zHoehe DIV 4; size:= MagicVDI.SetCharpoints (TextHandle, Half, i, i, i, i); ELSIF subscript IN attrib THEN yoff:= zHoehe DIV 2; size:= MagicVDI.SetCharpoints (TextHandle, Half, i, i, i, i); ELSIF superscript IN attrib THEN yoff:= 0; size:= MagicVDI.SetCharpoints (TextHandle, Half, i, i, i, i); ELSE (* Normale Zeichenh”he *) yoff:= 0; size:= MagicVDI.SetCharpoints (TextHandle, Full, i, i, i, i); END; (* Leider werden nicht alle verwendeten Attribute vom VDI untersttzt. * So werden Hoch-, Tiefstellen und Invers in MagicTerm emuliert. * Diese Bits mssen wir ausblenden, sonst gibts Verwirrung *) bs:= {}; IF fat IN attrib THEN INCL (bs, MagicVDI.Fat); END; IF light IN attrib THEN INCL (bs, MagicVDI.Light); END; IF italic IN attrib THEN INCL (bs, MagicVDI.Italic); END; IF underline IN attrib THEN INCL (bs, MagicVDI.Underline); END; VDIIntIn[0]:= CastToInt (bs); VDICall (106, 0, 1, 0, TextHandle); effect:= attrib; END; (* WITH *) END SetAttribut; PROCEDURE SetTabspace (tab: sINTEGER); BEGIN Terminal^.tab:= tab; END SetTabspace; PROCEDURE SetParameter; BEGIN WITH Terminal^ DO Lines:= zl; Columns:= sp; Xpos:= x; Ypos:= y; Width:= w; Height:= h; FontNum:= font; FontSize:= size; CurrWidth:= zBreite; CurrHeight:= zHoehe; END; END SetParameter; (*--------------------------------------------------------------------------* * GDOS-Fonthandling * *--------------------------------------------------------------------------*) PROCEDURE GemFonts (use: BOOLEAN); BEGIN GEMFonts:= use; END GemFonts; PROCEDURE GetFont (VAR font, width, height: sINTEGER); VAR att: ARRAY [0..9] OF sINTEGER; BEGIN MagicVDI.InqText (TextHandle, att); FontNum:= FontCode (att[0]); CurrWidth:= att[8]; CurrHeight:= att[9]; font:= FontNum; width:= CurrWidth; height:= CurrHeight; END GetFont; PROCEDURE SetFont (fnt: sINTEGER); VAR i, s: sINTEGER; BEGIN IF GEMFonts THEN i:= LoadFonts (TextHandle); IF i < 0 THEN RETURN; END; IF fnt # Terminal^.font THEN IF Monospaced (fnt) THEN SelectFont (TextHandle, fnt, Full); (* Font setzen *) Half:= Full - 1; ClearScreen; (* Muž erzwungen werden!!! *) WITH Terminal^ DO (* neue Dimensionen bestimmen *) GetFont(font, zBreite, zHoehe); chwidth:= zBreite - 1; linehi:= zHoehe - 1; sp:= w DIV zBreite; zl:= h DIV zHoehe; mx:= x + (sp * zBreite) - 1; my:= y + (zl * zHoehe) - 1; lastCol:= mx - chwidth; lastLn:= my - linehi; px:= x; py:= y; pmx:= x + chwidth; pmy:= y + linehi; END; END; END; END; SetParameter; END SetFont; PROCEDURE SizeFont (siz: sINTEGER); VAR i, a, b: sINTEGER; BEGIN WITH Terminal^ DO (* neue Dimensionen bestimmen *) size:= ScaleFont (TextHandle, siz, a, b); ClearScreen; (* Muž erzwungen werden!!! *) GetFont(font, zBreite, zHoehe); chwidth:= zBreite - 1; linehi:= zHoehe - 1; sp:= w DIV zBreite; zl:= h DIV zHoehe; mx:= x + (sp * zBreite) - 1; my:= y + (zl * zHoehe) - 1; lastCol:= mx - chwidth; lastLn:= my - linehi; px:= x; py:= y; pmx:= x + chwidth; pmy:= y + linehi; END; SetParameter; END SizeFont; (*--------------------------------------------------------------------------* * Support fr mehrere Terminals * *--------------------------------------------------------------------------*) VAR a, b, c: sINTEGER; count: sINTEGER; PROCEDURE OpenTerminal (tx, ty, tw, th: sINTEGER): TERMINAL; VAR term: TERMINAL; BEGIN NEW (term); IF term = NIL THEN RETURN NIL END; WITH term^ DO GetFont (font, zBreite, zHoehe); chwidth:= zBreite - 1; linehi:= zHoehe - 1; x:= tx; y:= ty; w:= tw; h:= th; IF (w + x) > MaxWidth THEN w:= MaxWidth - x; END; IF (h + y) > MaxHeight THEN h:= MaxHeight - y; END; sp:= w DIV zBreite; zl:= h DIV zHoehe; mx:= x + (sp * zBreite) - 1; my:= y + (zl * zHoehe) - 1; lastCol:= mx - chwidth; lastLn:= my - linehi; px:= x; py:= y; pmx:= x + chwidth; pmy:= y + linehi; vColor:= 1; hColor:= 0; xoff:= 0; yoff:= 0; tab:= 8; effect:= Attribut{}; zustand:= {}; END; (* WITH *) RETURN term; SetParameter; END OpenTerminal; PROCEDURE CloseTerminal (VAR term: TERMINAL); BEGIN DISPOSE (term); term:= NIL; END CloseTerminal; PROCEDURE ChangeTerminal (term: TERMINAL): TERMINAL; VAR old: TERMINAL; BEGIN old:= Terminal; EXCL (old^.zustand, cActive); INCL (term^.zustand, cActive); Terminal:= term; WITH Terminal^ DO ForegroundColor (vColor); BackgroundColor (hColor); IF old^.font # font THEN SetFont (font); END; SetAttribut (effect); END; SetParameter; RETURN old; END ChangeTerminal; PROCEDURE GetMaximum (VAR x, y, w, h, sp, zl: sINTEGER); BEGIN x:= MinX; y:= MinY; w:= MaxWidth; h:= MaxHeight; sp:= MaxColumns; zl:= MaxLines; END GetMaximum; PROCEDURE GetTerminal (term: TERMINAL; VAR tx, ty, tw, th, ts, tz, font: sINTEGER); BEGIN IF term # NIL THEN tx:= term^.x; ty:= term^.y; tw:= term^.w; th:= term^.h; ts:= term^.sp; tz:= term^.zl; font:= term^.font; END; END GetTerminal; PROCEDURE SetTerminal (term: TERMINAL; tx, ty, tw, th: sINTEGER); BEGIN IF term # NIL THEN WITH term^ DO GetFont (font, zBreite, zHoehe); chwidth:= zBreite - 1; linehi:= zHoehe - 1; x:= tx; y:= ty; w:= tw; h:= th; IF (w + x) > MaxWidth THEN w:= MaxWidth - x; END; IF (h + y) > MaxHeight THEN h:= MaxHeight - y; END; sp:= w DIV zBreite; zl:= h DIV zHoehe; mx:= x + (sp * zBreite) - 1; my:= y + (zl * zHoehe) - 1; lastCol:= mx - chwidth; lastLn:= my - linehi; px:= x; py:= y; pmx:= x + chwidth; pmy:= y + linehi; IF cActive IN zustand THEN SetParameter; END; END; END; END SetTerminal; PROCEDURE ClipRect (doit: BOOLEAN; a, b, c, d: sINTEGER); BEGIN IF doit THEN rect.x:= a; rect.y:= b; rect.w:= a + c - 1; rect.h:= b + d - 1; MagicVDI.SetClipping(TextHandle, rect, TRUE); MagicVDI.SetClipping(NormalHandle, rect, TRUE); MagicVDI.SetClipping(InversHandle, rect, TRUE); ELSIF (italic IN Terminal^.effect) THEN rect.x:= Terminal^.x; rect.y:= Terminal^.y; rect.w:= Terminal^.mx; rect.h:= Terminal^.my; MagicVDI.SetClipping(TextHandle, rect, TRUE); MagicVDI.SetClipping(NormalHandle, rect, FALSE); MagicVDI.SetClipping(InversHandle, rect, FALSE); ELSE MagicVDI.SetClipping(TextHandle, rect, FALSE); MagicVDI.SetClipping(NormalHandle, rect, FALSE); MagicVDI.SetClipping(InversHandle, rect, FALSE); END; END ClipRect; PROCEDURE RedrawTerminal (term: TERMINAL; x, y, w, h: sINTEGER); BEGIN END RedrawTerminal; (*-------------------------------------------------------------------------*) VAR i, i1, i2, i3, i4: sINTEGER; x: TERMINAL; BEGIN (* TermBase *) GEMFonts:= FALSE; count:= 0; dPtr:= ADR(d); qPtr:= ADR(q); control7:= ADR(MagicVDI.VDIControl[7]); control9:= ADR(MagicVDI.VDIControl[9]); IF Bitplanes >= 2 THEN Full:= 9; Half:= 8; ELSE Full:= 10; Half:= 9; END; InversHandle:= OpenWorkstation (); i:= MagicVDI.SetWritemode (InversHandle, MagicVDI.XOR); i:= MagicVDI.SetFillinterior (InversHandle, MagicVDI.Full); i:= MagicVDI.SetFillcolor (InversHandle, 1); NormalHandle:= OpenWorkstation (); i:= MagicVDI.SetWritemode (NormalHandle, MagicVDI.REPLACE); i:= MagicVDI.SetFillinterior (NormalHandle, MagicVDI.Full); i:= MagicVDI.SetFillcolor (NormalHandle, 0); TextHandle:= OpenWorkstation (); i:= MagicVDI.SetCharpoints (TextHandle, Full, i1, i2, i3, i4); i:= MagicVDI.SetWritemode (TextHandle, MagicVDI.REPLACE); i:= MagicVDI.SetTextcolor (TextHandle, 1); MagicVDI.SetTextalignment (TextHandle, 0, 5, i, i); MagicAES.GrafHandle (i, ChWidth, ChHeight, BoxWidth, BoxHeight); Terminal:= OpenTerminal (0, 0, MaxWidth, MaxHeight); IF Terminal = NIL THEN HALT; END; Terminal^.zustand:= {cActive}; SetParameter; END mtTerminal.