home *** CD-ROM | disk | FTP | other *** search
- {
- ════════════════════════════════════════════════════════════════════════════
-
- Visionix ANSI In/Out Driver Unit (VANSIIOU)
- Version 0.2
- Copyright 1991,92,93 Visionix
- ALL RIGHTS RESERVED
-
- ────────────────────────────────────────────────────────────────────────────
-
- ** revision history in reverse chronological order **
-
- Initials Date Comment
- ──────── ──────── ────────────────────────────────────────────────────────
-
- jrt 12/22/93 Added even more function documentation.
-
- jrt 11/22/93 Added function documentation.
-
- jrt 11/17/93 Moved code out of VANSIu to here.
-
- jrt 11/15/93 Finished out driver and out filter.
-
- mep 05/08/93 Drivers (local and buffer) might work now - doubt it :)
-
- ────────────────────────────────────────────────────────────────────────────
- }
-
- (*-
-
- [SECTION: Section 2: The Text I/O Libraries]
- [CHAPTER: Chapter 1: The ANSI Driver & Filter I/O Unit]
-
- [TEXT]
-
- <Overview>
-
- The VANSIiou unit contains only two procedures: ANSIFilter and
- ANSIOutDriverProc. As the names imply, ANSIFilter is a VOUT filter
- for ANSI commands, and ANSIOutDriverProc is an VOUT output driver
- for ANSI.
-
- For more information on text filters, drivers, sub-channels, etc., be sure
- to read the VOUTu and VINu chapters.
-
-
- <<The ANSIFilter>>
-
- The ANSI Filter is a VOUT filter procedure. ANSIFilter can be
- attached to a VOUT sub-channel via a call to VOutFilterAttach.
- After the ANSIFilter has been attached, it will "filter" all of the
- ANSI commands in the text-stream sent to that channel, and convert
- the ANSI commands one or more "out driver packets", which is the
- internal command format used by VOUT.
-
- <<<What the heck does this mean?>>>
-
- Basically it means that after you attach the ANSIfilter to a
- sub-channel, you can write ANSI commands into that sub-channel, and
- the ANSI commands will be properly interpreted and executed on the
- sub-channels display. For example, if you were to attach the ANSI
- filter to the sub-channel used by VCRTu, you could then use
- ANSI commands in your WRITE and WRITELN statements, and the appropriate
- colors, text, actions, etc would appear on your monitor.
-
- <<<Examples and usage>>>
-
- To attach the ANSI filter to the VCRTU's output sub-channel (which is
- created automatically in the VCRTu units init-code):
-
- VOutFilterAttach( CrtOCH,
- 0,
- 'ANSIFILTER',
- 'Bx00VMEM',
- AnsiFilter,
- 0,0,0 );
-
-
- CrtOCH is the channel handle for VCRTus output-channel.
- As a paramater to VOutFilterAttach, it tells VOUT which channel
- to attach the filter to.
-
- The second parameter, 0, is the flags parameter. ANSIFilter
- currently has no flags.
-
- The third parameter, 'ANSIFILTER', is the name by which this
- instance of the filter is managed.
-
- The fourth parameter, 'Bx00VMEM', is the name of the sub-channel
- off of the "CrtOCH" channel to which the filter should be
- attached. 'Bx00VMEM' is the name that VCRTu uses for the default
- sub-channel it creates which goes to the primary displays
- video memory.
-
- The fifth parameter, AnsiFilter, is the filter procedure to
- attach. Since we are attaching the ANSI filter, we specify
- the procedure AnsiFilter.
-
- The last three parameters to VOutFilterAttach are parameters/values
- which are passed to the AnsiFilter. Currently AnsiFilter has
- no parameters, so we leave them all set to 0.
-
- To attach an ANSI filter to a new sub-channel, which happens to use
- the ANSI Driver:
-
- { first we create a new-sub channel off of the CRT output channel }
- { this new-sub channel will use the ANSI output driver procedure. }
- { note that the ANSIOutDriverProc is very different from the }
- { ANSI filter. We'll explain shortly... }
-
- { part 1 }
-
- VOutSubChannelNew( CrtOCH,
- 0,
- 'ANSIOUT',
- ANSIOutDriverProc,
- caoDOS,0,0 );
-
-
- { Then we attach the ANSI filter to the new sub-channel }
-
- { part 2 }
-
-
- VOutFilterAttach( CrtOCH,
- 0,
- 'ANSIFILTER',
- 'ANSIOUT', {<--note we specify the new sub-chan name}
- AnsiFilter,
- 0,0,0 );
-
- In "Part 1" of this example we create a new-sub channel. We specify
- that this sub-channel will use the ANSIOutDriverProc. The
- ANSIOutDriverProc is very different from the ANSIFilter. The
- ANSIFilter converts ANSI commands into the "Out driver packets"
- used internally within VOUT, and the ANSIOutDriverProc performs
- "Out driver Packets" by generating ANSI commands and sending them
- to a text-stream output device.
-
- In "Part 2" of this example, we attach the ANSI filter to this
- newly created sub-channel.
-
- What we end up with as a result of these actions is a sub-channel
- that converts ANSI commands to output driver packets, and then
- converts the output-driver packets back into ANSI commands. This
- may seem a little uncessarry, but in fact it is not. We need
- the intermediate conversion step so that (1) any other filters
- which are added to the sub-channel can "understand" the ANSI commands
- (since they are now converted to Out driver packets, (2) so that
- the ANSI driver (or any other driver we may use) can respond
- appropriately. For the ANSI driver, an appropriate response is not
- to just send out ANSI commands. It must also "track" everything it
- does (IE: keep track of the current text color, current cursor
- x/y,etc). By converting the ANSI commands into Out driver
- packets, the ANSI driver now has a format by which it can understand
- and track the ANSI commands "passing through" it.
-
- How about some simple-english:
-
- Even though this example creates a sub-channel which _generates_
- ANSI commands, we still need the ANSI filter to interpret any
- ANSI commands sent into the sub-channel by applications which
- use VOUT our VCRTu. Why? Because although it may not seem like
- it, the easiest way to implement and manage a sub-channel which can
- both interpret and generate ANSI commands is to break the two tasks
- up into seperate modules: In this case, the ANSIFilter (which
- interprets ANSI commands), and the ANSIOutDriverProc (which generates
- ANSI commands).
-
- For more information on filter, driver, sub-channels, etc., be sure
- to read the VOUTu and VINu chapters.
-
- <<ANSIOutDriverProc>>
-
- The ANSI output-driver procedure is a VOUT output driver. This
- output-driver procedure lets you create a sub-channel which will
- send ANSI commands to a specified device in response to VOUT text
- I/O calls (IE: VOutClrScr, VOutWrite, etc). By default, the
- ANSI output-driver sends its output to the local, primary ANSI
- device (IE: DOS' ANSI.SYS or OS/2 VIO). However, by specifying
- other paramaters when a sub-channel using this driver is created,
- ANSI will send its output to any other device, including a VSER
- based serial port.
-
- <<<And what does all that mean?>>>
-
- The ANSIOutDriverProc responds to VOUTClrScr, VOutClrEol, VOutWrite,
- etc. calls by generating ANSI commands. These ANSI commands can be
- sent to ANSI.SYS, OS/2 VIO, a serial port, or just about anywhere you
- want by specifying the appropriate parameters on a call to
- VOutSubChannelNew. This driver is the key part that allows you,
- for example, to use the normal TP CRT API functions (ClrScr, Write,
- etc) over the serial port--because VCRTu's CRT API functions work
- via VOUT, and VOUT can generate ANSI via this driver!
-
- <<<Examples and usage>>>
-
- To create a new-sub channel which uses the ANSIOutDriverProc
- and sends its ANSI output to DOS CON: / ANSI.SYS
-
- { Here we create a new-sub channel off of the CRT output channel }
- { this new-sub channel will use the ANSI output driver procedure. }
-
- { part 1 }
-
- VOutSubChannelNew( CrtOCH,
- 0,
- 'ANSIOUT',
- ANSIOutDriverProc,
- caoDOS,0,0 );
-
- CrtOCH is the channel handle for VCRTus output-channel.
- As a paramater to VOutSubChannelNew, it tells VOUT which channel
- to create a new sub-channel off of.
-
- The second parameter, 0, is the flags parameter. VOutSubChanneNew
- currently has no flags.
-
- The third parameter, 'ANSIOUT', is the name by which this
- new sub-channel will be managed.
-
-
- The fourth parameter, AnsiOutDriverProc, is the driver-procedure
- which the new sub-channel will use or be "anchored" by. In this
- example, we specify ANSIOutDriverProc, which creates a sub-channel
- which will generate ANSI commands in response to calls to
- VOutClrScr, VOutWrite, VOUTGotoXY, etc.
-
- The last three parameters are parameters which are passed to the
- ANSIOutDriverProc.
-
- For the ANSIOutDriverProc, the first of these parameters is a
- value which specifies where the ANSI drivers output stream
- should be sent. In this example, we specify caoDOS, which tells
- the ANSI driver to send its output to the default ANSI device,
- which in DOS is CON: (or ANSI.SYS) and in OS/2 is the
- VIOWriteTTY function.
-
- When the first of these parameters is caoDOS, the other
- two parameters are not used.
-
-
- To create a new-sub channel which uses the ANSIOutDriverProc
- and sends its ANSI output to a custom stream device.
-
- Procedure MySend( Idata : POINTER; Var St : STRING ); Far;
-
- BEGIN
-
- { write ST to wherever here }
-
-
- END;
-
-
- VOutSubChannelNew( CrtOCH,
- 0,
- 'CustANSIOUT',
- ANSIOutDriverProc,
- caoCustom,
- Longint(@MySend),
- 0 );
-
-
- CrtOCH is the channel handle for VCRTus output-channel.
- As a paramater to VOutSubChannelNew, it tells VOUT which channel
- to create a new sub-channel off of.
-
- The second parameter, 0, is the flags parameter. VOutSubChanneNew
- currently has no flags.
-
- The third parameter, 'CustANSIOUT', is the name by which this
- new sub-channel will be managed.
-
- The fourth parameter, AnsiOutDriverProc, is the driver-procedure
- which the new sub-channel will use or be "anchored" by. In this
- example, we specify ANSIOutDriverProc, which creates a sub-channel
- which will generate ANSI commands in response to calls to
- VOutClrScr, VOutWrite, VOUTGotoXY, etc.
-
- The last three parameters are parameters which are passed to the
- ANSIOutDriverProc.
-
- For the ANSIOutDriverProc, the first of these parameters is a
- value which specifies where the ANSI drivers output stream
- should be sent. In this example, we specify caoCustom, which tells
- the ANSI driver to send its output to a custom send-procedure.
-
- When the first of these parameters is caoCustom, the second
- parameter should be a pointer to the procedure to call when
- ANSIOutDriverProc needs to send out text. Since this
- parameter is defined as a longint, this procedure-pointer needs
- to be cast to a LONGINT.
-
- When using caoCustom, the third parameter is a 32-bit instance
- data value that will be passed to the custom send-procedure.
- Every time it is called (This is the IData paramater on the
- MySend procedure). You can use this 32-bit value for whatever
- you'd like. (IE: as a pointer to other information your
- custom send-procedure might need, etc)
-
- For more information on text filters, drivers, sub-channels, etc., be sure
- to read the VOUTu and VINu chapters.
-
- <Interface>
-
- -*)
-
- Unit VAnsiIOu;
-
- Interface
-
- Uses
-
- VCRTu,
- VAnsiU,
- DOS,
- VInlineu,
- VInu,
- VOutu,
- VTypesu,
- VStringu,
- {$IFDEF OS2}
- VVioI,
- {$ENDIF}
- VGenu;
-
-
- Const
-
- caoDos = 0;
- caoCustom = $80;
-
-
- {-----------------------------}
- { ANSI Emulation state record }
- {-----------------------------}
-
- Type
-
- TANSIEmu = RECORD
-
- Cmd : STRING;
- StringMode : BOOLEAN;
- AttrBold : BYTE;
- SaveX : BYTE;
- SaveY : BYTE;
-
- X : BYTE;
- Y : BYTE;
- N : BYTE;
- TmpS : STRING;
-
- END;
-
- PAnsiEmu = ^TAnsiEmu;
-
-
- Type
-
-
- TANSIScreen = RECORD
-
- CurX : INTEGER;
- CurY : INTEGER;
- CurAttr : BYTE;
-
- WinX1 : WORD;
- WinX2 : WORD;
- WinY1 : WORD;
- WinY2 : WORD;
-
- CurType : WORD;
-
- WinIsScreen : BOOLEAN;
-
- AttrIsKnown : BOOLEAN;
-
- KnownCurAttr: BYTE;
- KnownCurX : INTEGER;
- KnownCurY : INTEGER;
-
- END; { TScreen }
-
- PANSIScreen = ^TANSIScreen;
-
- PAnsiOutDriverIdata = ^TAnsiOutDriverIdata;
-
- TAnsiSendProc = PROCEDURE( IData : PAnsiOutDriverIData; Var ST : STRING );
-
- TANSIOutDriverIData = Record
-
- Off : WORD;
- Name : TProcName;
-
- Param1 : LONGINT;
- Param2 : LONGINT;
- Param3 : LONGINT;
-
- SendProc : TAnsiSendProc;
- SendBuff : STRING;
-
- EmuBuf : STRING;
-
- DisplayMode: BYTE;
-
- Cols : WORD;
- Rows : WORD;
-
- YMult : WORD;
-
- NumScreens : BYTE;
-
- AScreen : BYTE;
-
- Screen : Array[1..8] of TANSIScreen;
-
- END; { TANSIOutDriverIData }
-
-
-
-
- Procedure ANSIFilter( ODP : POutDriverPacket );
-
- Procedure ANSIOutDriverProc( ODP : POutDriverPacket );
-
-
- Procedure AttachAnsiFilter( Chan : TChanHandle;
- SubChan : STRING );
-
-
-
-
- Implementation
-
-
-
-
-
- {────────────────────────────────────────────────────────────────────────────}
-
-
-
- (*-
-
- [FUNCTION]
-
- Procedure ANSIFilter( ODP : POutDriverPacket );
-
- [PARAMETERS]
-
- ODP Pointer to a VOUT Out-driver request packet
-
- [RETURNS]
-
- (None)
-
- [DESCRIPTION]
-
- This procedure is an ANSI filter for the Visionix Input/Output
- architecture.
-
- This procedure will "filter" incoming ANSI requests and generate
- the appropriate Out-Driver-Packets (ODP), and pass the new ODP
- packets down the driver stack of the sub-channel this filter
- is attached to.
-
- This procedure should NOT be called directly. Instead, use the
- VOutFilterAttach function to attach this filter to a previously
- created output sub-channel.
-
- [SEE-ALSO]
-
- (None)
-
- [EXAMPLE]
-
- VOutFilterAttach( TheChan,
- 0,
- 'ANSIfilter',
- 'TheSubChan',
- ANSIFilter,
- NIL );
-
- -*)
-
-
- Procedure ANSIFilter( ODP : POutDriverPacket );
-
- Type
-
-
- TCharBuff = Array[1..32768] of CHAR;
- PCharBuff = ^TCharBuff;
-
- TANSIFilterIData = Record
-
- Off : WORD;
- Name : TProcName;
-
- AnsiEMU : TAnsiEmu;
-
- END; { TANSIFilterIData }
-
- PAnsiFilterIData = ^TAnsiFilterIData;
-
- {----}
-
- Var
- IData : PAnsiFilterIData;
-
- Z : INTEGER;
-
- SBuff : STRING;
-
- {---------------------------------------------------}
-
- Procedure SBuffFlush;
-
-
- Var
- MyODP : TOutDriverPacket;
-
- BEGIN
-
- If SBuff<>'' Then
- BEGIN
-
- MyODP.Func := ODF_WriteBlock;
- MyODP.Buff := @SBuff[1];
- MyODP.Size := Byte(SBuff[0]);
- MyODP.Start := 1;
- MyODP.NextDriver := ODP^.NextDriver;
- MyODP.Status := 0;
-
- CallNextDriver( @MyODP );
-
- SBuff := '';
-
- END;
-
- END;
-
- {---------------------------------------------------}
-
- Procedure ANSItoODP( TheANSIEmu : PAnsiEMU;
- Ch : CHAR;
- OrigODP : POutDriverPacket );
-
- Var
-
- L1 : INTEGER;
- L2 : BYTE;
- L3 : BYTE;
-
- ODP : TOutDriverPacket;
-
- aTextAttr : BYTE;
-
- Function ANSITakeParam( Var Cmd : STRING ) : STRING;
-
- Var
-
- Idx : BYTE;
- Cnt : BYTE;
-
- BEGIN
-
- Idx := Pos(';', Cmd);
-
- If Idx = 0 Then
- BEGIN
-
- Cnt := Byte(Cmd[0]) - 2;
-
- ANSITakeParam := Copy(Cmd, 3, Cnt);
- Delete(Cmd, 3, Cnt);
-
- END
- Else
- BEGIN
-
- Dec(Idx);
- Cnt := Idx - 2;
-
- ANSITakeParam := Copy(Cmd, 3, Cnt);
- Delete(Cmd, 3, Succ(Cnt));
-
- END;
-
- END;
-
- {───────────────────────────────────────────────────────}
-
- Function ANSITakeInt( Var Cmd : STRING ) : INTEGER;
-
- BEGIN
-
- ANSITakeInt := StrToInt( ANSITakeParam(Cmd) );
-
- END;
-
- {───────────────────────────────────────────────────────}
-
- Function ANSINextParam( Var Cmd : STRING ) : INTEGER;
-
- { -1 = no parameter }
- { 1 = string parameter }
- { 2 = command }
- { 3 = number parameter }
- { 4 = blank parameter ';' }
-
- BEGIN
-
- If Byte(Cmd[0]) < 3 Then
- ANSINextParam := -1
- Else
- If Cmd[Byte(Cmd[0])] = '"' Then
- ANSINextParam := 1
- Else
- If NOT IsNum(Cmd[Byte(Cmd[0])]) Then
- ANSINextParam := 2
- Else
- If Cmd[3] = ';' Then
- BEGIN
- Delete(Cmd, 3, 1); { yuck - but works! }
- ANSINextParam := 4;
- END
- Else
- ANSINextParam := 3;
-
- END;
-
- {─────────────────────────────────────────────────────}
-
- Procedure ResetCmd;
-
- BEGIN
-
- TheANSIEmu^.Cmd := '';
-
- END;
-
- {─────────────────────────────────────────────────────}
-
- Procedure MyWrite( CH: CHAR );
-
- BEGIN
-
- { SBuff := SBuff + CH; }
-
- StrAddCh( SBuff, CH );
-
-
- (*
- ODP.Func := ODF_WriteChar;
- ODP.CH := CH;
- ODP.Status := 0;
-
- CallNextDriver( @ODP );
- *)
-
- END;
-
- Procedure MyWriteStr( S : STRING );
-
- Var
- Z : INTEGER;
-
- BEGIN
-
- { SBuff := SBuff + S; }
-
- StrAddStr( Sbuff, S );
-
- (*
- For Z:=1 to Length( S ) Do
- MyWrite( S[Z] );
- *)
-
-
- END;
-
- {─────────────────────────────────────────────────────}
-
-
- BEGIN
-
- { ODP := OrigODP^; }
-
- ODP.NextDriver := OrigODP^.NextDriver;
-
- With TheANSIEmu^ Do
- BEGIN
-
- If Cmd[0] > NUL Then
- BEGIN
-
- If Byte(Cmd[0]) = 1 Then
- BEGIN
-
- If Ch = '[' Then
- StrAddCh( Cmd, CH )
- Else
- BEGIN
-
- MyWrite(Ch);
- ResetCmd;
-
- END;
-
- END
- Else
- BEGIN
-
- If StringMode AND (Ch <> '"') Then
- StrAddCh( Cmd, CH )
- Else
- Case Ch of
-
- '0'..'9', { inputing number(s) values }
- ';' :
- StrAddCH( Cmd, CH );
-
- 'A' : { Up Row }
-
- BEGIN
-
- If ANSINextParam(Cmd) = 3 Then
- L1 := ANSITakeInt(Cmd)
- Else
- L1 := 1;
-
- SBuffFlush;
-
- ODP.Func := ODF_CursorUp;
- ODP.Status := 0;
- ODP.NumVal := L1;
- CallNextDriver( @ODP );
-
- ResetCmd;
-
- END;
-
- 'B' : { Down Row }
-
- BEGIN
-
- If ANSINextParam(Cmd) = 3 Then
- L1 := ANSITakeInt(Cmd)
- Else
- L1 := 1;
-
- SBuffFlush;
-
- ODP.Func := ODF_CursorDown;
- ODP.Status := 0;
- ODP.NumVal := L1;
- CallNextDriver( @ODP );
-
- ResetCmd;
-
- END;
-
- 'C' : { Right Col }
-
- BEGIN
-
- If ANSINextParam(Cmd) = 3 Then
- L1 := ANSITakeInt(Cmd)
- Else
- L1 := 1;
-
- SBuffFlush;
-
- ODP.Func := ODF_CursorRight;
- ODP.Status := 0;
- ODP.NumVal := L1;
- CallNextDriver( @ODP );
-
- ResetCmd;
-
- END;
-
- 'D' : { Left Col }
-
- BEGIN
-
- If ANSINextParam(Cmd) = 3 Then
- L1 := ANSITakeInt(Cmd)
- Else
- L1 := 1;
-
- SBuffFlush;
-
- ODP.Func := ODF_CursorLeft;
- ODP.Status := 0;
- ODP.NumVal := L1;
- CallNextDriver( @ODP );
-
- ResetCmd;
-
- END;
-
- 'H', { Home/GotoRC }
- 'f' :
-
- BEGIN
-
- With TheANSIEmu^ Do
- BEGIN
-
- X := 1;
- Y := 1;
-
- If ANSINextParam(Cmd) = 3 Then
- Inc( Y, Pred(ANSITakeInt(Cmd)) );
- If ANSINextParam(Cmd) = 3 Then
- Inc( X, Pred(ANSITakeInt(Cmd)) );
-
- SBuffFlush;
-
- ODP.Func := ODF_GetWin;
- ODP.Status := 0;
- CallNextDriver( @ODP );
-
- ODP.Func := ODF_GotoXY;
- ODP.X1 := LesserInt( (ODP.X2-ODP.X1)+1, X );
- ODP.Y1 := LesserInt( (ODP.Y2-ODP.Y1)+1, Y );
- ODP.Status := 0;
-
- CallNextDriver( @ODP );
-
- END;
-
- ResetCmd;
-
- END;
-
- 's' : { Save Cursor Position }
-
- BEGIN
-
- SBuffFlush;
-
- ODP.Func := ODF_GetXY;
- ODP.Status := 0;
- CallNextDriver( @ODP );
-
- TheAnsiEmu^.SaveX := ODP.X1;
- TheAnsiEmu^.SaveY := ODP.Y1;
-
- ResetCmd;
-
- END;
-
- 'u' : { Restore Cursor Position }
-
- BEGIN
-
- If (TheANSIEmu^.SaveX > 0) and
- (TheANSIEmu^.SaveY > 0) Then
- BEGIN
-
- SBuffFlush;
-
- ODP.Func := ODF_GotoXY;
- ODP.X1 := TheAnsiEmu^.SaveX;
- ODP.Y1 := TheAnsiEmu^.SaveY;
- ODP.Status := 0;
- CallNextDriver( @ODP );
-
- END;
-
- ResetCmd;
-
- END;
-
- 'm' : { Graphics }
-
- BEGIN
-
- SBuffFlush;
-
- While ( ANSINextParam(Cmd) = 3 ) Do
- BEGIN
-
- With TheANSIEmu^ Do
- BEGIN
-
- ODP.Func := ODF_GetAttr;
- ODP.Status := 0;
- CallNextDriver( @ODP );
-
- aTextAttr := ODP.Attr;
-
- AttrBold := aTextAttr AND $8;
-
- L3 := ANSITakeInt(Cmd);
-
- Case L3 of
-
- 0 : { Attrs OFF }
- BEGIN
-
- AttrBold := 0;
- aTextAttr := 7;
-
- END;
-
- 1 : { Bold ON }
- BEGIN
-
- AttrBold := 8;
- aTextAttr := aTextAttr OR $8;
-
- END;
-
- 5 : aTextAttr := aTextAttr OR $80; { Blink ON }
- 7 : aTextAttr := aTextAttr XOR $FF; { Rev. Video ON }
- {nonono!}
-
- 22 :
- BEGIN
- aTextAttr := aTextAttr and $F7; {turn boldoff}
- AttrBold := 0;
- END;
-
- 25 : aTextAttr := aTextAttr AND NOT $80; { Blink OFF }
- 27 : aTextAttr := aTextAttr XOR $FF; { Rev. Video OFF }
-
- 30 : atextAttr := (aTextAttr and $F8)+(Black );
- 31 : atextAttr := (aTextAttr and $F8)+(Red );
- 32 : atextAttr := (aTextAttr and $F8)+(Green );
- 33 : atextAttr := (aTextAttr and $F8)+(Brown );
- 34 : atextAttr := (aTextAttr and $F8)+(Blue );
- 35 : atextAttr := (aTextAttr and $F8)+(Magenta );
- 36 : atextAttr := (aTextAttr and $F8)+(Cyan );
- 37 : atextAttr := (aTextAttr and $F8)+(LightGray );
-
- 40 : atextAttr := (aTextAttr and $8F)+(BackBlack );
- 41 : atextAttr := (aTextAttr and $8F)+(BackRed );
- 42 : atextAttr := (aTextAttr and $8F)+(BackGreen );
- 43 : atextAttr := (aTextAttr and $8F)+(BackBrown );
- 44 : atextAttr := (aTextAttr and $8F)+(BackBlue );
- 45 : atextAttr := (aTextAttr and $8F)+(BackMagenta );
- 46 : atextAttr := (aTextAttr and $8F)+(BackCyan );
- 47 : atextAttr := (aTextAttr and $8F)+(BackLightGray);
-
- End;
-
- ODP.Func := ODF_SetAttr;
- ODP.Attr := aTextAttr;
- ODP.Status := 0;
- CallNextDriver( @ODP );
-
- END;
-
- END;
-
- ResetCmd;
-
- END;
-
- 'J' : { ClrScr }
-
- BEGIN
-
- With TheANSIEmu^ Do
- BEGIN
-
- If ANSINextParam(Cmd) = 3 Then
- L3 := ANSITakeInt(Cmd)
- Else
- BEGIN { ClrScr >= }
-
- SBuffFlush;
-
- ODP.Func := ODF_ClrScr;
- ODP.Status := 0;
- CallNextDriver( @ODP );
-
- (*
- X := WhereX;
- Y := WhereY;
- L1 := X;
- L2 := Y;
-
- While ( L2 <= Hi(WindMax)) Do
- BEGIN
-
- While (L1 <= Lo(WindMax)) Do
- BEGIN
-
- Inc(L1);
- Write(SP);
-
- END;
-
- Inc(L2);
- L1 := Lo(WindMin);
- GotoXY(L1, L2);
-
- END;
-
- GotoXY(X, Y);
- *)
-
- END;
-
- If L3 = 2 Then { ClrScr }
- BEGIN
-
- SBuffFlush;
-
- ODP.Func := ODF_ClrScr;
- ODP.Status := 0;
- CallNextDriver( @ODP );
-
- ODP.Func := ODF_SetAttr;
- ODP.Attr := 7;
- ODP.Status := 0;
- CallNextDriver( @ODP );
-
- (*
- ClrScr;
- TextAttr := 7;
- *)
-
- END
- Else
- If L3 = 1 Then { ClrScr <= }
- BEGIN
-
- With TheANSIEmu^ Do
- BEGIN
- (*
- X := WhereX;
- Y := WhereY;
- L1 := X;
- L2 := Y;
-
- GotoXY( Lo(WindMin), Hi(WindMin) );
- While (WhereY < L2) Do
- BEGIN
-
- While ( WhereX < Lo(WindMax) ) Do
- BEGIN
-
- GotoXY(Succ(WhereX), WhereY);
- Write(SP);
-
- END;
-
- GotoXY( Lo(WindMin), Succ(WhereY));
-
- END;
-
- While (WhereX <= L1) Do
- BEGIN
-
- GotoXY(Succ(WhereX), WhereY);
- Write(SP);
-
- END;
-
- GotoXY(X, Y);
- *)
-
- END;
-
- END;
-
- END;
-
- ResetCmd;
-
- END;
-
- 'K' : { ClrEol }
-
- BEGIN
-
- SBuffFlush;
-
- ODP.Func := ODF_ClrEOL;
- ODP.Status := 0;
- CallNextDriver( @ODP );
-
- { ClrEol; }
-
- ResetCmd;
-
- END;
-
- 'L' : { InsLine }
-
- BEGIN
-
- SBuffFlush;
-
- If ANSINextParam(Cmd) = 3 Then
- L1 := ANSITakeInt(Cmd)
- Else
- L1 := 1;
- For L2 := 1 to L1 Do
- BEGIN
-
- ODP.Func := ODF_InsLine;
- ODP.Status := 0;
- CallNextDriver( @ODP );
-
- { InsLine; }
-
- END;
-
- ResetCmd;
-
- END;
-
- 'M' : { DelLine }
-
- BEGIN
-
- SBuffFlush;
-
- If ANSINextParam(Cmd) = 3 Then
- L1 := ANSITakeInt(Cmd)
- Else
- L1 := 1;
- For L2 := 1 to L1 Do
- BEGIN
-
- ODP.Func := ODF_DelLine;
- ODP.Status := 0;
- CallNextDriver( @ODP );
-
- {DelLine;}
-
- END;
-
- ResetCmd;
-
- END;
-
- 'n' : { Device Status Report }
-
- BEGIN
-
- If ANSINextParam(Cmd) = 3 Then
- L1 := ANSITakeInt(Cmd)
- Else
- L1 := 1;
-
- ODP.Func := ODF_GetXY;
-
- If L1 = 6 Then
- MyWriteStr('[' + IntToStr(ODP.Y1) + ';' +
- IntToStr(ODP.X1) + 'R' );
-
- ResetCmd;
-
- END;
-
- '@' : { Inserts Characters on Line }
-
- BEGIN
-
- If ANSINextParam(Cmd) = 3 Then
- L1 := ANSITakeInt(Cmd)
- Else
- L1 := 1;
- For L2 := 1 to L1 Do
- BEGIN
-
- END;
-
- ResetCmd;
-
- END;
-
- 'P' : { Deletes Characters on Line }
-
- BEGIN
-
- If ANSINextParam(Cmd) = 3 Then
- L1 := ANSITakeInt(Cmd)
- Else
- L1 := 1;
- For L2 := 1 to L1 Do
- BEGIN
-
- END;
-
- ResetCmd;
-
- END;
-
- 'h' : { Set Graphic Modes }
-
- BEGIN
-
- If (ANSINextParam(Cmd) = 3) Then
- BEGIN
-
- L3 := Byte(ANSITakeInt(Cmd));
-
- (*
- ASM
-
- MOV AH, 0
- MOV AL, L3
- INT 10h
-
- END;
- *)
-
- END;
-
- ResetCmd;
-
- END;
-
- 'l' : { Reset Graphic Modes }
-
- BEGIN
-
- If (ANSINextParam(Cmd) = 3) Then
- BEGIN
-
- L3 := Byte(ANSITakeInt(Cmd));
- (*
- ASM
-
- MOV AH, 0
- MOV AL, L3
- INT 10h
- END;
- *)
-
- END;
-
- ResetCmd;
-
- END;
-
- 'p' : { Keyboard Redefination }
- BEGIN
-
- ResetCmd;
-
- END;
-
- '"' : { inputing a string value }
- BEGIN
-
- StringMode := NOT StringMode;
- StrAddCh( Cmd, CH );
-
- END;
-
- '?',
- '=' :
- StrAddCh( Cmd, CH );
- Else
- BEGIN
-
- MyWrite(Ch);
- ResetCmd;
-
- END
-
- End;{of case}
-
- END;
-
- END
- Else
- BEGIN
-
- If Byte(CH)<32 Then
- BEGIN
-
- Case CH Of
- #8:
- BEGIN
- SBuffFlush;
- ODP.Func := ODF_CursorLeft;
- ODP.NumVal := 1;
- ODP.Status := 0;
- CallNextDriver( @ODP );
- END;
- #12:
- BEGIN
- SBuffFlush;
- ODP.Func := ODF_ClrScr;
- ODP.NumVal := 1;
- ODP.Status := 0;
- CallNextDriver( @ODP );
-
- END;
- #27:StrAddCH( Cmd, CH );
- ELSE
- MyWrite( CH );
- END;
-
- END
- ELSE
- MyWrite(CH);
-
- END;
-
- END;
-
- END; { ansi to odp }
-
- {---------------------------------------------------}
-
-
-
- BEGIN { AnsiFilterProc }
-
- IData := ODP^.ID;
-
- If ODP^.Status = 0 Then
- BEGIN
-
- Case ODP^.Func Of
-
- ODF_DriverNew:
- BEGIN
-
- {-----------------------------}
- { are they telling me to new? }
- {-----------------------------}
-
- IF @ODP^.OutDriverProc = @AnsiFilter Then
- BEGIN
-
- {-------------------------}
- { Get a new Instance Data }
- { master node. }
- {-------------------------}
-
- New( Idata );
-
- IData^.Off := 0;
-
- IData^.Name := ODP^.Name^;
-
- FillChar( Idata^.ANSIEmu, SizeOf(TANSIEmu), 0 );
-
- ODP^.Status := ODS_Install+ODS_Changed;
- ODP^.ID := IData;
-
- END; { If ODP^.OutDriverProc --> Us }
-
- END; { ODF_DriverNew }
-
- {----}
-
- ODF_DriverOff:
- BEGIN
-
- If ODP^.Name^ = IData^.Name Then
- BEGIN
-
- Inc( Idata^.Off );
-
- END; { If ODP^.Name^ }
-
- END; { ODF_DriverOff }
-
- {----}
-
- ODF_DriverOn:
- BEGIN
-
- If ODP^.Name^ = IData^.Name Then
- BEGIN
-
- If Idata^.Off <> 0 Then
- Dec( Idata^.Off );
-
- END; { ODP^.Name^ }
-
- END; { ODF_DriverOn }
-
- {----}
-
- ODF_DriverDispose:
- BEGIN
-
- If ODP^.Name^ = IData^.Name Then
- BEGIN
-
- {RemoveFromOutDriverStack }
-
- Dispose( IData );
-
- END; { If ODP^.Name^ }
-
- END; { ODF_DriverDispose }
-
- {----}
-
- ODF_WriteChar:
- BEGIN
-
- SBuff := '';
-
- ANSItoODP( @IData^.AnsiEmu,
- ODP^.CH,
- ODP );
-
- SBuffFlush;
-
- {make sure ODP.func hasnt changed to make us }
- { do another part of the case statement }
-
- END; { ODF_WriteChar }
-
- {----}
-
- ODF_WriteBlock:
- BEGIN
-
- SBuff := '';
-
- For Z:=ODP^.Start to ODP^.Size Do
- BEGIN
-
- ANSItoODP( @IData^.AnsiEmu,
- PCharBuff( ODP^.Buff )^[Z],
- ODP );
-
- END; { For Z }
-
- ODP^.Start := ODP^.Size;
-
- SBuffFlush;
-
- END; { ODF_WriteBlock }
-
- {----}
-
- Else { Else Case }
-
- CallNextDriver( ODP );
-
- END; { Case ODP^.Func }
-
- END; { If ODP^.Status = 0 }
-
- END; { ANSIFilter }
-
-
- {────────────────────────────────────────────────────────────────────────────}
-
-
- Procedure DosSendSt( IData : PANSIOutDriverIData;
- Var ST2 : STRING ); Far;
-
- {$IFNDEF OS2}
-
- Var
- R : REGISTERS;
- L : BYTE;
- S,O: WORD;
- BEGIN
-
- {$IFDEF DOSWRITE}
-
- L := Byte( ST2[0] );
- S := Seg( ST2[1] );
- O := ofs( ST2[1] );
- ASM
-
- PUSH DS
-
- MOV AH, $40
- MOV BX, 1
- MOV CL, L
- XOR CH, CH
-
- PUSH S
- POP DS
- MOV DX, O
-
- INT $21
-
- POP DS
-
- END;
-
- {$ELSE}
-
- ASM
-
- { Save DS }
-
- PUSH DS
-
- { Make DS:SI --> ST2 }
-
- LDS SI, [ST2]
-
- { Load CL with the count of bytes to write }
-
- MOV CL, DS:[SI]
-
- { move DS:SI --> down to the text }
-
- INC SI
-
- { WRITE OUT THE STRING VIA INT $29 (Dos fast console output) }
-
- @@1:
-
- LODSB
- INT $29
- LOOP @@1
-
- { Restore DS }
-
- POP DS
-
- END;
-
- {$ENDIF}
-
- END;
-
- {$ELSE}
-
- BEGIN
-
- VioWrtTTY( @St2[1], Length(St2), 0 );
-
- END;
-
- {$ENDIF}
-
- {────────────────────────────────────────────────────────────────────────────}
-
- (*-
-
- [FUNCTION]
-
- Procedure ANSIOutDriverProc( ODP : POutDriverPacket );
-
- [PARAMETERS]
-
- ODP Pointer to Output Driver Packet
-
- [RETURNS]
-
- (None)
-
- [DESCRIPTION]
-
- Visionix input/output architecture ANSI driver. This driver converts
- vout out-driver-packets into the appropriate ANSI commands.
-
- This is an out driver procedure which is used to anchor a sub-channel
- when it is created. It should not be called directly, but should be
- used with the VOutSubChannelNew function in VOut.
-
- [SEE-ALSO]
-
- [EXAMPLE]
-
- VOutSubChannelNew( TheChan,
- 0,
- 'TheSubChan',
- ANSIOutDriverProc,
- NIL );
-
-
- -*)
-
-
- Procedure ANSIOutDriverProc( ODP : POutDriverPacket );
-
- Type
-
-
- TCell = Record
-
- Char : CHAR;
- Attr : BYTE;
-
- END; { TCell }
-
- TScreenStore = Array[0..32000] of TCell;
-
- PScreenStore = ^TScreenStore;
-
- {----}
-
- {----}
-
- Var
-
- IData : PANSIOutDriverIData;
-
- YMult : WORD;
-
- AS : PANSIScreen;
-
- Z : INTEGER;
- Z2 : INTEGER;
- Z3 : INTEGER;
-
- S : STRING;
- P : POINTER;
-
- SaveCurX : WORD;
- SaveCurY : WORD;
- SaveAttr : BYTE;
-
- savewinx1,savewiny1,savewinx2,savewiny2:integer;
-
- {────────────────────────────────────────────────────────────────────────}
-
- Procedure InitIData;
-
- Var
-
- L : WORD;
-
- BEGIN
-
- IData^.Off := 0;
- IData^.Name := ODP^.Name^;
- IData^.EmuBuf := '';
-
- IData^.Cols := 80;
- IData^.Rows := 25;
- IData^.YMult := 80;
- IData^.NumScreens := 1;
- IData^.AScreen := 1;
-
- IData^.SendBuff := '';
-
- For L := 1 to Idata^.NumScreens Do
- BEGIN
- IData^.Screen[L].KnownCurX := 255;
- IData^.Screen[L].KnownCurY := 255;
- IData^.Screen[L].KnownCurAttr:= 255;
-
- IData^.Screen[L].CurX := 0;
- IData^.Screen[L].CurY := 0;
- IData^.Screen[L].CurAttr := 7;
- IData^.Screen[L].WinX1 := 0;
- IData^.Screen[L].WinY1 := 0;
- IData^.Screen[L].WinX2 := Idata^.Cols-1;
- IData^.Screen[L].WinY2 := Idata^.Rows-1;
-
- IData^.Screen[L].WinIsScreen := TRUE;
-
- END;
-
- {------------------------------}
- { copy the params to our IDATA }
- {------------------------------}
-
- IData^.Param1 := ODP^.DriverParam1;
- IData^.Param2 := ODP^.DriverParam2;
- IData^.Param3 := ODP^.DriverParam3;
-
- {-----------------------}
- { Setup the output proc }
- {-----------------------}
-
- Case ODP^.DriverParam1 of
-
- caoDOS : IData^.SendProc := DosSendSt;
- caoCustom : IData^.SendProc :=
- TAnsiSendProc( ODP^.DriverParam2 );
-
- ELSE
-
- IData^.SendProc := DosSendSt;
-
- END;
-
- END; { InitIData }
-
- {────────────────────────────────────────────────────────────────────────}
-
- Procedure AddBufCh( Buf : CHAR );
- Var
- s : string[1];
-
- BEGIN
-
- If Length(IData^.SendBuff)=255 Then
- BEGIN
- IData^.SendProc( IData, IData^.SendBuff );
- IData^.SendBuff := Buf;
- END
- ELSE
- StrAddCh( IData^.SendBuff, Buf );
-
- (*
- s:=buf;
- IData^.SendProc( IData, S );
- *)
- END;
-
- {────────────────────────────────────────────────────────────────────────}
-
- Procedure AddBuf( Buf : STRING );
-
- BEGIN
-
- If Length(IData^.SendBuff)+Length(Buf)>255 Then
- BEGIN
- IData^.SendProc( IData, Idata^.SendBuff );
- IData^.SendBuff := Buf;
- END
- ELSE
- StrAddStr( IData^.SendBuff, Buf );
-
- (*
- IData^.SendProc( IData, Buf );
- *)
-
- END;
-
- {────────────────────────────────────────────────────────────────────────}
-
- Procedure FlushBuff;
-
- BEGIN
-
- If Length(IData^.SendBuff)>0 Then
- BEGIN
- IData^.SendProc( IData, IData^.SendBuff );
- IData^.SendBuff := '';
- END;
-
- END;
-
- {────────────────────────────────────────────────────────────────────────}
-
- {$IFDEF CHECKCURXY}
-
- Procedure CheckCurXY;
-
- {$IFNDEF OS2}
-
- Var
- R : REGISTERS;
-
- BEGIN
-
- R.AH :=$03;
- R.BH :=0;
- R.ES :=$0;
- R.DS :=$0;
-
- Intr( $10, R );
-
- If (R.DL<>AS^.CurX) or (R.DH<>AS^.CurY) Then
- BEGIN
-
- R.DL := R.DL;
-
- END;
-
-
- END;
-
- {$ELSE}
-
- BEGIN
-
- END;
-
- {$ENDIF}
-
- {$ENDIF} { ifdef checkcurxy }
-
- {────────────────────────────────────────────────────────────────────────}
-
- Procedure ChkTextAttr;
-
- BEGIN
-
- (*
-
- If (IData^.Win[IData^.InWin].CurTextAttr <> TextAttr) Then
- BEGIN
-
- AddBuf( ANSITextAttr(TextAttr) );
- IData^.Win[IData^.InWin].CurTextAttr := TextAttr;
-
- END;
-
- *)
-
- END;
-
- {────────────────────────────────────────────────────────────────────────}
-
- Procedure MySyncAttr;
-
- Var
-
- S : STRING[30];
-
- newattr, oldattr : byte;
-
- label done;
-
- BEGIN
-
- With AS^ Do
- BEGIN
-
- NewAttr := CurAttr;
- OldAttr := KnownCurAttr;
-
- { are the attrs the same? }
-
- IF NewAttr<>OldAttr Then
- BEGIN
-
- S:=#27+'[';
-
- { is the new attr the default attr? }
-
- If newattr=$07 then
- BEGIN
- StrAddConstStr( S, '0;' );
- goto DONE;
- END;
-
- { is blink being turned off? }
-
- If ((NewAttr and $80)=0) and ((OldAttr and $80)>0) Then
- BEGIN
- StrAddConstStr( S, '0;' );
- OldAttr := $07;
- END
- ELSE
- { is blink being turned on? }
-
- If ((NewAttr and $80)>0) and ((OldAttr and $80)=0) Then
- BEGIN
- StrAddConstStr( S, '5;' );
- END;
-
- { is intensity being turned off ? }
-
- If ((NewAttr and $08)=0) and ((OldAttr and $08)>0) Then
- BEGIN
- StrAddConstStr( S, '0;' );
- OldAttr := $07;
- END
- ELSE
- { isintensity being turned on ? }
-
- If ((NewAttr and $08)>0) and ((OldAttr and $08)=0) Then
- BEGIN
- StrAddConstStr( S, '1;' );
- END;
-
- { is the background changing? }
-
- If (NewAttr and $70)<>(OldAttr AND $70) Then
- BEGIN
- Case ((NewAttr AND $70) SHR 4) of
- Black : StrAddConstStr( S, '40;' );
- Blue : StrAddConstStr( S, '44;' );
- Green : StrAddConstStr( S, '42;' );
- Cyan : StrAddConstStr( S, '46;' );
- Red : StrAddConstStr( S, '41;' );
- Magenta : StrAddConstStr( S, '45;' );
- Brown : StrAddConstStr( S, '43;' );
- LightGray : StrAddConstStr( S, '47;' );
- END;
- END;
-
- { isthe foreground changing? }
-
- If (NewAttr and $07)<>(OldAttr AND $07) Then
- BEGIN
- Case (NewAttr AND $07) of
- Black : StrAddConstStr( S, '30;' );
- Blue : StrAddConstStr( S, '34;' );
- Green : StrAddConstStr( S, '32;' );
- Cyan : StrAddConstStr( S, '36;' );
- Red : StrAddConstStr( S, '31;' );
- Magenta : StrAddConstStr( S, '35;' );
- Brown : StrAddConstStr( S, '33;' );
- LightGray : StrAddConstStr( S, '37;' );
- END;
- END;
-
- DONE:
-
- S[Length(S)]:='m';
-
- AddBuf( S );
-
- KnownCurAttr := NewAttr;
-
- END; { if newattr<>curattr }
-
- (*
- If (CurAttr AND $0F)<>(KnownCurAttr AND $0F) Then
- BEGIN
-
- { textcolors dont match }
-
- If (CurAttr AND $F0)<>(KnownCurAttr AND $F0) Then
- AddBuf( AnsiTextattr( CurAttr ) )
- Else
- Addbuf( AnsiTextColor( CurAttr AND $0F ) );
-
- END
- ELSE
- If (CurAttr AND $F0)<>(KnownCurAttr and $F0) Then
- BEGIN
-
- { textbackground/blink doesnt match }
-
- {
- If (CurAttr AND $80)<>(KnownCurAttr and $80) Then
- AddBuf( AnsiTextAttr( CurAttr ) )
- ELSE
- Addbuf( AnsiTextBackGround( (CurAttr AND $70) SHR 4 ) );
- }
-
- AddBuf( AnsiTextAttr( CurAttr ) );
-
- END;
-
- KnownCurAttr := CurAttr;
- *)
-
- (*
- If CurAttr<>KnownCurAttr Then
- BEGIN
- AddBuf( AnsiTextAttr( CurAttr ) );
- KnownCurAttr := CurAttr;
- END;
- *)
-
- END;
-
- END;
-
- Procedure MyTextAttr( Attr : BYTE );
-
- BEGIN
-
- With AS^ Do
- If Attr<>KnownCurAttr Then
- BEGIN
- AddBuf( AnsiTextAttr( Attr ) );
- KnownCurAttr := Attr;
- END;
-
- END;
-
- {────────────────────────────────────────────────────────────────────────}
-
- Procedure MySyncCurXY;
-
- Var
-
- S : STRING[30];
- S2: STRING[30];
- XDiff : INTEGER;
- YDiff : INTEGER;
-
- BEGIN
-
- With AS^ Do
- If (CurX<>KnownCurX) or (CurY<>KnownCurY) Then
- BEGIN
- S2:= '';
- S := ANSIGotoXY( CurX+1, CurY+1 );
-
- XDiff := KnownCurX-CurX;
- YDiff := KnownCurY-CurY;
-
- If XDiff<>0 Then
- If XDiff<0 Then
- BEGIN
- If Abs(XDiff)=1 Then
- StrAddConstStr( S2, AnsiRight )
- ELSE
- StrAddConstStr( S2, AnsiRightCount( Abs( XDiff ) ) );
- END { move right }
- Else
- BEGIN
- If XDiff=1 Then
- StrAddConstStr( S2, AnsiLeft )
- ELSE
- StrAddConstStr( S2, AnsiLeftCount( XDiff ) );
- END; { move right / else }
-
- If YDiff<>0 Then
- If YDiff<0 Then
- BEGIN
- If Abs(YDiff)=1 Then
- StrAddConstStr( S2, AnsiDown )
- ELSE
- StrAddConstStr( S2, AnsiDownCount( Abs(YDiff) ) );
- END { move down }
- Else
- BEGIN
- If YDiff=1 Then
- StrAddConstStr( S2, AnsiUp )
- ELSE
- StrAddConstStr( S2, AnsiUpCount( YDiff ) );
- END; { moveup }
-
- (*
- If XDiff<>0 Then
- If XDiff<0 Then
- S2 := S2 + AnsiRightCount( Abs(XDiff) )
- END
- Else
- S2 := S2 + AnsiLeftCount( XDiff );
-
- If YDiff<>0 Then
- If YDiff<0 Then
- S2 := S2 + AnsiDownCount( Abs(YDiff) )
- Else
- S2 := S2 + AnsiUpCount( YDiff );
- *)
-
-
-
- If Length(S)<=Length(S2) Then
- Addbuf( S )
- ELSE
- AddBuf( S2 );
-
- { AddBuf( AnsiGotoXY( CurX+1, CurY+1 ) ); }
-
- KnownCurX := CurX;
- KnownCurY := CurY;
- END;
-
- END;
-
- Procedure MySyncGotoXY( x, y : INTEGER );
-
- BEGIN
-
- With AS^ Do
- BEGIN
- Curx := x;
- CurY := y;
- If (CurX<>KnownCurX) or (CurY<>KnownCurY) Then
- BEGIN
- AddBuf( AnsiGotoXY( CurX+1, CurY+1 ) );
- KnownCurX := CurX;
- KnownCurY := CurY;
- END;
- END;
- END;
-
- Procedure MyKnownGotoXY( newx, newy : INTEGER );
-
- BEGIN
-
- With AS^ Do
- If (CurX<>NewX) or (CurY<>NewY) Then
- BEGIN
- AddBuf( AnsiGotoXY( NewX, NewY ) );
- KnownCurX := NewX;
- KnownCurY := NewY;
- END;
-
- END;
-
- Procedure MyKnownCurXY( x,y : INTEGER );
-
- BEGIN
-
- With AS^ Do
- BEGIN
- KnownCurX := X;
- KnownCurY := Y;
- END;
-
- END;
-
- {────────────────────────────────────────────────────────────────────────}
- (*
- Procedure CursorDown( Sync : BOOLEAN );
-
- BEGIN
-
- With AS^ Do
- BEGIN
-
- Inc( CurY );
-
- If CurY > WinY2 Then
- BEGIN
-
- { scroll the region }
-
- Dec( CurY );
-
- END { if cur>winy2 }
- ELSE
- BEGIN
-
- AddBuff( AnsiDown );
-
- END;
-
- {
- If (Sync) Then
- RealCursorGoto( IData^.AScreen-1, CurX, CurY );
- }
-
- END; { With AS^ }
-
- END; { CursorDown }
- *)
-
- {────────────────────────────────────────────────────────────────────────}
-
-
- Procedure MyClrEOL;
-
- BEGIN
-
- With AS^ DO
- BEGIN
-
- MySyncCurXy;
- MySyncAttr;
-
- { does the right-edge of the window = right-edge of screen? }
-
- If WinX2=Idata^.Cols-1 Then
- BEGIN
-
- { use Clear to end of line's }
-
- Addbuf( ANSIClrEOL );
-
- END
- ELSE
-
- (*
- { does the left-edge of the win = left-edge of screen? }
-
- If WinX1=0 Then
- BEGIN
-
- { use Clear to START of line's }
-
- AddBuf( AnsiGotoXY( WinX2+1, CurY+1 ) );
- Addbuf( ANSIClrSOL );
- AddBuf( AnsiGotoXY( CurX+1, CurY+1 ) );
-
- END
- ELSE
- *)
-
- BEGIN
-
- { otherwise use spaces }
-
- S := RepeatString( ' ', (WinX2-WinX1)+1 );
-
- Addbuf( S );
-
- MyKnownCurXY( Curx+Length(S), CurY );
-
- MySyncCurXY;
-
- { MyGotoXY( CurX+1, CurY+1 ); }
- { AddBuf( AnsiGotoXY( CurX+1, CurY+1 ) ); }
-
- END; { if winx2=cols/else if winx1=1/else }
-
- {$IFDEF CHECKCURSOR}
- CheckCurXY;
- {$ENDIF}
-
- END; { with as^ }
-
- END; { procedure MyClrEol }
-
-
- {────────────────────────────────────────────────────────────────────────}
-
- Function CursorNextChar( Sync : BOOLEAN ):WORD;
-
- Var
- Ret : WORD;
-
- BEGIN
-
- Ret := 0;
-
- With AS^ Do
- BEGIN
-
- { if the window is the same size as the screen }
-
- If WinIsScreen Then
- BEGIN
-
- Inc( CurX );
- Inc( KnownCurX );
-
- If CurX>WinX2 Then
- BEGIN
-
- CurX := 0;
- KnownCurX := 0;
-
- If CurY<WinY2 Then
- BEGIN
- Inc( CurY );
- Inc( KnownCurY );
- END;
-
- END;
-
- {$IFDEF CHECKCURSOR}
- CheckCurXY;
- {$ENDIF}
-
- END { if window is same size as screen }
- ELSE
- BEGIN
-
- Inc( CurX );
- Inc( KnownCurX );
-
- { here we see if the known has changed because }
- { we moved past the edge of the physical screen }
-
- If (AS^.Winx2=IData^.Cols-1) Then
- BEGIN
- KnownCurx := 0;
- If AS^.CurY<Idata^.Rows-1 Then
- Inc( KnownCurY );
- END;
-
- { if past right-edge of window }
-
- If CurX>WinX2 Then
- BEGIN
-
- CurX := winX1;
-
- { if not at bottom-edgeof window }
-
- If CurY<WinY2 Then
- BEGIN
-
- Inc( CurY );
-
- MySyncCurXY;
-
- { AddBuf( AnsiGotoXY( CurX+1, CurY+1 ) ); }
-
- END
- ELSE
- BEGIN
-
-
- { AddBuf( AnsiGotoXY( CurX+1, CurY+1 ) ); }
-
- MySyncCurXy;
-
- { clear this line since it "scrolled" }
-
- MyClrEol;
-
- { we are at the bottom edge }
- { inform filters before us on the stack that we need a scroll }
-
- ODP^.Status := ODS_CantDo;
- ODP^.StatusMsg := ODS_MsgNeedScrollUp;
-
- Ret := 1;
-
- END;
-
- { put the cursor to where we will want it }
- END;
-
- {$IFDEF CHECKCURSOR}
- CheckCurXY;
- {$ENDIF}
-
- END; { if window is same size as screen / else }
-
- (*
- If (Sync) and (IData^.VirtualCRT=FALSE) Then
- RealCursorGoto( IData^.AScreen-1, CurX, CurY );
- *)
-
- END; { With AS^ }
-
- CursorNextChar := Ret;
-
- END; { CursorNextChar }
-
- {────────────────────────────────────────────────────────────────────────}
-
- Function MyWriteChar( CH : CHAR ):WORD;
-
- Var
-
- Ret : WORD;
-
- BEGIN
-
- Ret := 0;
-
- With AS^ Do
- BEGIN
-
- Case Ch Of
-
- #13:
- BEGIN
-
- If WinX1=1 Then
- AddBufCh( #13 )
- ELSE
- BEGIN
- CurX := WinX1;
- MySyncCurXY;
-
- { AddBuf( AnsiGotoXY( CurX+1, CurY+1 ) ); }
- END;
-
- END; { #13 }
-
- #10:
- BEGIN
-
- If WinIsScreen Then
- BEGIN
-
- AddBufCh( #10 );
-
- If CurY<WinY2 Then
- BEGIN
- Inc( CurY );
- Inc( KnownCurY );
- END;
-
- {$IFDEF CHECKCURSOR}
- CheckCurXY;
- {$ENDIF}
-
- END { if winy2=rows / else }
- ELSE
- BEGIN
-
- { if not at bottom-edge of window }
-
- If CurY<WinY2 Then
- BEGIN
-
- { move down a line }
-
- AddBufCh( #10 );
- Inc( CurY );
- Inc( KnownCurY );
-
- {$IFDEF CHECKCURSOR}
- CheckCurXY;
- {$ENDIF}
-
- END
- ELSE
- BEGIN
-
- { at bottom edge of window, so }
- { scroll the window up }
- { by telling filters before }
- { us on the stack we need a }
- { scroll. }
-
- ODP^.Status := ODS_CantDo;
- ODP^.StatusMsg := ODS_MsgNeedScrollUp;
-
- Ret := 1;
-
- { scroll window }
- END;
-
- END; { if winy2=rows / else }
-
- { CursorDown( TRUE ); }
-
- END; { #10 }
-
- #26:AddbufCh( CH );
-
- Else
-
- AddBufCh( Ch );
-
- Ret := CursorNextChar( TRUE );
-
- END; { Case Ch }
-
- END; { With AS^ }
-
- MyWriteChar := Ret;
-
- END; { MyWriteChar }
-
- {────────────────────────────────────────────────────────────────────────}
-
- Procedure SwapCoords( Var A,B : WORD );
-
- Var
- Temp : WORD;
-
- BEGIN
-
- Temp := A;
- A := B;
- B := Temp;
-
- END; { SwapCoords }
-
- {────────────────────────────────────────────────────────────────────────}
-
- Procedure MyWriteRegion;
-
- Var
- YLoop : INTEGER;
- XLoop : INTEGER;
- StoreOfs : WORD;
- SaveAttr : BYTE;
- LastAttr : BYTE;
- NewCell : TCell;
-
- BEGIN
-
- With AS^ Do
- BEGIN
-
- {-------------------------------}
- { save the xy position and attr }
- {-------------------------------}
-
- AddBuf( ANSISavePos );
-
- SaveAttr := AS^.CurAttr;
-
- {-------------------------------}
- { setup variables used in loops }
- {-------------------------------}
-
- StoreOfs :=0; {offset into region store buffer }
-
- LastAttr := AS^.curAttr;
-
- {---------------}
- { for each line }
- {---------------}
-
- For YLoop := ODP^.Y1 To ODP^.Y2 Do
- BEGIN
-
- { ^!^ do goto optimizations!!! }
-
- { goto }
-
- AddBuf( ANSIGotoXY( ODP^.X1, YLoop ) );
-
- { for each cell in the line }
-
- For XLoop := ODP^.X1 To ODP^.X2 Do
- BEGIN
-
- { get the new cell }
-
- NewCell := PScreenStore( ODP^.Region )^[StoreOfs];
-
- MyTextAttr( NewCell.Attr );
-
- (*
- { if the newcell's attr <> the lastattr, update attr }
-
- If NewCell.Attr<>LastAttr Then
- BEGIN
- AddBuf( ANSITextAttr( NewCell.Attr ) );
- LastAttr := NewCell.Attr;
- END;
- *)
-
- { write out the character }
-
- AddBufCh( NewCell.Char );
-
- { move our offset }
-
- Inc( StoreOfs );
-
- END; { for xloop }
-
- END; { for yloop }
-
- {--------------------------------}
- { restore the attr and cursor xy }
- {--------------------------------}
-
- (*
- If LastAttr<>SaveAttr Then
- Addbuf( ANSITextAttr( SaveAttr ) );
- *)
-
- { MyTextAttr( SaveAttr ) }
-
- Addbuf( ANSIRestorePos );
-
- END; { with AS^ }
-
- END; { procedure MyWriteRegion }
-
- {────────────────────────────────────────────────────────────────────────}
-
-
-
-
- BEGIN { ANSIOutDriverProc }
-
- IData := ODP^.ID;
-
- If ODP^.Func<> ODF_DriverNew Then
- BEGIN
-
- AS := @IData^.Screen[ IData^.AScreen ];
- YMult := IData^.YMult;
-
- END; { ODP^.Func }
-
-
- If ODP^.Status = 0 Then
- BEGIN
-
- Case ODP^.Func Of
-
- ODF_DriverNew:
- BEGIN
-
- If @ODP^.OutDriverProc = @ANSIOutDriverProc Then
- BEGIN
-
- {-------------------------}
- { Get a new Instance Data }
- { master node. }
- {-------------------------}
-
- New( Idata );
-
- InitIData;
-
- {--------}
- { Return }
- {--------}
-
- ODP^.Status := ODS_Install+ODS_Changed;
-
- ODP^.ID := IData;
-
- END; { If ODP^.OutDriverProc --> Us }
-
- END; { ODF_DriverNew }
-
- {----}
-
- ODF_DriverOff:
- BEGIN
-
- If ODP^.Name^ = IData^.Name Then
- BEGIN
-
- Inc( Idata^.Off );
-
- END; { If ODP^.Name^ }
-
- END; { ODF_DriverOff }
-
- {----}
-
- ODF_DriverOn:
- BEGIN
-
- If ODP^.Name^ = IData^.Name Then
- BEGIN
-
- If Idata^.Off <> 0 Then
- Dec( Idata^.Off );
-
- END; { ODP^.Name^ }
-
- END; { ODF_DriverOn }
-
- {----}
-
- ODF_DriverDispose:
- BEGIN
-
- If ODP^.Name^ = IData^.Name Then
- BEGIN
-
- {-----------------------------}
- { Remove from OutDriver stack }
- {-----------------------------}
-
- Dispose( IData );
-
- END; { If ODP^.Name^ }
-
- END; { ODF_DriverDispose }
-
- {----}
-
- ODF_WriteChar:
- BEGIN
-
- MySyncAttr;
- MySyncCurXY;
-
- MyWriteChar( ODP^.CH );
-
- (*
- ChkTextAttr;
-
- AddBufCh( ODP^.Ch );
- *)
-
- END; { ODF_WriteChar }
-
- {----}
-
- ODF_WriteBlock:
- BEGIN
-
- ChkTextAttr;
-
- MySyncAttr;
-
- MySyncCurXY;
-
- (*
-
- Z2 := ODP^.NumVal;
- Z3 := ODP^.Size;
-
- {-----------------------}
- { anything left to do ? }
- {-----------------------}
-
- If (Z2<Z3) Then
- BEGIN
-
- P := Addr( TCharArray( ODP^.Buff^)[Z2] );
-
- ASM
-
- PUSH DS
-
- { setup the registers }
-
- MOV CX, Z3 { get total }
- SUB CX, Z2 { subtract amount already done }
-
- LDS SI, dword PTR [P] { make DS:SI = p }
-
- CLD { go forward... }
-
- { loop through the buffer }
-
- @@1:
-
- LODSB { get the character }
- PUSH AX { push the char (param) }
- CALL MyWriteChar { call the write }
- CMP AX, 1 { Q: did write say scroll? }
- JE @@2 { Y: get outa here... }
-
- LOOP @@1 { loop de loop }
-
- { we did all the characters }
-
- MOV BX, Z3 { get total }
- MOV Z2, BX { we did em all. }
- MOV Z, 0 { we dont need a scroll }
-
- JMP @@3 { get outa here }
-
- @@2:
-
- { write func said to scroll }
-
- MOV BX, Z3 { get total }
- SUB BX, CX { subtract # of chars left }
- MOV Z2, BX { store it as # of chars done }
- MOV Z, 1 { we need a scroll }
-
- @@3:
-
- POP DS
-
- END; { asm }
-
- IF Z=1 Then
- BEGIN
- ODP^.Status := ODS_CantDo;
- ODP^.StatusMsg := ODS_MsgNeedScrollUp;
- END;
-
- END; { if z2<>z3 (stuff left) }
-
- *)
-
- Z := ODP^.Start;
- Z2 := ODP^.Size;
- Z3 := 0;
-
- While (Z<=Z2) and (Z3=0) Do
- BEGIN
-
- Z3:=MyWriteChar( TCharArray(ODP^.Buff^)[Z] );
-
- Inc( Z );
-
- END;
-
- If Z>ODP^.Size Then
- ODP^.Start := ODP^.Size
- ELSE
- ODP^.Start := Z;
-
- { ODP^.NumVal := Z-1; }
-
- If Z3=1 Then
- BEGIN
- ODP^.Status := ODS_CantDo;
- ODP^.StatusMsg := ODS_MsgNeedScrollUp;
- END;
-
-
- (*
- For Z := ODP^.NumVal to ODP^.Size Do
- MyWriteChar( TCharArray(ODP^.Buff^)[Z] );
- *)
-
- END; { ODF_WriteBlock }
-
- {----}
-
- ODF_WriteVert:
- BEGIN
-
- ChkTextAttr;
-
- MySyncAttr;
- MySyncCurXY;
-
- { how about when it writes vert out of the window }
-
- For Z := 1 to ODP^.Size Do
- BEGIN
-
- AddBufCh( TCharArray(ODP^.Buff^)[Z] );
- AddBuf( ANSIGotoXY(Pred(WhereX), Succ(WhereY)) );
-
- END;
-
- END; { ODF_WriteVert }
-
- {----}
-
- ODF_WriteCharAt:
- BEGIN
-
- {!^! goto optimizations!}
-
- AddBuf( ANSISavePos );
-
- AddBuf( ANSIGotoXY(ODP^.X1, ODP^.Y1) );
-
- ChkTextAttr;
-
- MyTextAttr( ODP^.Attr );
-
-
- AddBufCh( ODP^.Ch );
-
- AddBuf( ANSIRestorePos );
-
- END; { ODF_WriteCharAt }
-
- {----}
-
- ODF_WriteBlockAt:
- BEGIN
-
-
- SaveCurX := AS^.CurX;
- SaveCurY := AS^.CurY;
- SaveWinX1 := AS^.WinX1;
- SaveWinY1 := AS^.WinY1;
- SaveWinX2 := AS^.WinX2;
- SaveWinY2 := AS^.WinY2;
-
- { AddBuf( ANSISavePos ); }
-
- { MyKnownGotoXY( ODP^.X1, ODP^.Y1 ); }
-
- AS^.CurX := ODP^.X1-1;
- AS^.CurY := ODP^.Y1-1;
-
- AS^.WinX1:= 0;
- AS^.WinY1:= 0;
- AS^.WinX2:= IData^.Cols-1;
- AS^.WinY2:= IData^.Rows-1;
-
- MySyncCurXY;
-
- { MySyncGotoXY( ODP^.X1, ODP^.Y1 ); }
-
- { AddBuf( ANSIGotoXY(ODP^.X1, ODP^.Y1) ); }
-
- ChkTextAttr;
-
- MyTextAttr( ODP^.Attr );
-
-
- (*
- SaveAttr := AS^.CurAttr;
-
- If ODP^.Attr<>SaveAttr Then
- AddBuf( AnsiTextAttr( ODP^.Attr ) );
- *)
-
-
- {-}
-
- Z := 1;
- Z2 := ODP^.Size;
- Z3 := 0;
-
- While (Z<=Z2) and (Z3=0) Do
- BEGIN
-
- Z3:=MyWriteChar( TCharArray(ODP^.Buff^)[Z] );
-
- Inc( Z );
-
- END;
-
- ODP^.NumVal := Z-1;
-
- If Z3=1 Then
- BEGIN
- ODP^.Status := ODS_CantDo;
- ODP^.StatusMsg := ODS_MsgNeedScrollUp;
- END;
-
- ODP^.Status := 0;
-
- {-}
-
- (*
- For Z := 1 to ODP^.Size Do
- AddBufCh( TCharArray(ODP^.Buff^)[Z] );
- *)
-
-
- (*
- If ODP^.Attr<>SaveAttr Then
- AddBuf( AnsiTextAttr( SaveAttr ) );
- *)
-
- {!^! JRT NEW!}
- AS^.CurAttr := SaveAttr;
-
- { Addbuf( AnsiGotoXY( SaveCurX+1, SaveCurY+1 ) ); }
-
- AS^.WinX1:= SaveWinX1;
- AS^.WinY1:= SaveWinY1;
- AS^.WinX2:= SaveWinX2;
- AS^.WinY2:= SaveWinY2;
-
- AS^.CurX := SaveCurX;
- AS^.CurY := SaveCurY;
-
- MySyncCurXY;
-
- { AddBuf( ANSIRestorePos ); }
-
- END; { ODF_WriteBlockAt }
-
- {----}
-
- ODF_WriteVertAt:
- BEGIN
-
- AddBuf( ANSISavePos );
-
- AddBuf( ANSIGotoXY(ODP^.X1, ODP^.Y1) );
-
- { MyKnownGotoXY( ODP^.X, ODP^.Y1 ); }
-
- {!^! JRT NEW }
- SaveAttr := AS^.CurAttr;
-
- ChkTextAttr;
-
- MyTextAttr( ODP^.Attr );
-
- For Z := 1 to ODP^.Size Do
- BEGIN
-
- AddBufCh( TCharArray(ODP^.Buff^)[Z] );
- {AddBuf( ANSIGotoXY(Pred(WhereX), Succ(WhereY)) );}
-
- END;
-
- {!^! JRT NEW}
- AS^.CurAttr := SaveAttr;
-
- AddBuf( ANSIRestorePos );
-
- END; { ODF_WriteVertAt }
-
- {----}
-
- ODF_ClrEOL: MyClrEol;
-
- {----}
-
- ODF_ClrScr:
- BEGIN
-
- With AS^ DO
- BEGIN
-
- MySyncAttr;
- MySyncCurXY;
-
- If WinIsScreen Then
- BEGIN
-
- { use a clear screen }
-
- AddBuf( ANSIClrScr );
-
- CurX := 0;
- CurY := 0;
-
- KnownCurX := 0;
- KnownCurY := 0;
-
- {$IFDEF CHECKCURSOR}
- CheckCurXY;
- {$ENDIF}
-
- END { if window=screen }
- ELSE
- BEGIN
-
- { does the right-edge of the window = right-edge of screen? }
-
- If WinX2=Idata^.Cols-1 Then
- BEGIN
-
- { use Clear to end of line's }
-
- For Z:=WinY1 To WinY2 Do
- BEGIN
- MyKnownGotoXY( WinX1+1, Z+1 );
- { Addbuf( ANSIGotoXY( WinX1+1, Z+1 ) ); }
- Addbuf( ANSIClrEOL )
- END;
-
- END
- ELSE
-
- (*
- { does the left-edge of the win = left-edge of screen? }
-
- If WinX1=0 Then
- BEGIN
-
- { use Clear to START of line's }
-
- For Z:=WinY1 To WinY2 Do
- BEGIN
- Addbuf( ANSIGotoXY( WinX2+1, Z+1 ) );
- Addbuf( ANSIClrSOL )
- END;
-
- END
- ELSE
-
- *)
-
- BEGIN
-
- { otherwise use spaces }
-
- S := RepeatString( ' ', (WinX2-WinX1)+1 );
-
- For Z:=WinY1 To WinY2 Do
- BEGIN
- MyKnownGotoXY( WinX1+1, Z+1 );
- { Addbuf( ANSIGotoXY( WinX1+1, Z+1 ) ); }
- Addbuf( S )
- END;
-
- END; { if winx2=cols/else if winx1=1/else }
-
- CurX := WinX1;
- CurY := WinY1;
-
- MySyncCurXy;
-
- { AddBuf( ANSIGotoXY( CurX+1, CurY+1 ) ); }
-
- {$IFDEF CHECKCURSOR}
- CheckCurXY;
- {$ENDIF}
-
- END; { if window=screen / else }
-
- END; { with as^ }
-
- END;
-
- {----}
-
- ODF_DelLine:
- BEGIN
-
- MySyncAttr;
- MySyncCurXY;
-
- AddBuf( ANSIDelLine );
-
- END;
-
- {----}
-
- ODF_InsLine:
- BEGIN
-
- MySyncAttr;
- MySyncCurXY;
-
- AddBuf( ANSIInsLine );
-
- END;
-
- {----}
-
- ODF_GotoXY:
- BEGIN
-
- With AS^ Do
- BEGIN
-
- CurX := WinX1+(ODP^.X1-1);
- CurY := WinY1+(ODP^.Y1-1);
-
- MySyncCurXY;
-
- { AddBuf( ANSIGotoXY( CurX+1, CurY+1 ) ); }
-
- {$IFDEF CHECKCURSOR}
- CheckCurXY;
- {$ENDIF}
-
- END;
-
- END;
-
- {----}
-
- ODF_Window:
- BEGIN
-
- With AS^ Do
- BEGIN
-
- WinX1 := ODP^.X1-1;
- WinY1 := ODP^.Y1-1;
- WinX2 := ODP^.X2-1;
- WinY2 := ODP^.Y2-1;
-
- If WinX2<WinX1 Then SwapCoords( WinX1, WinX2 );
- If WinY2<WinY1 Then SwapCoords( WinY1, WinY2 );
-
- WinIsScreen := (winx1=0 ) and (winy1=0 ) and
- (Winx2=IData^.Cols-1) and (Winy2=Idata^.rows-1);
-
-
- CurX := WinX1;
- CurY := WinY1;
-
- MySyncCurXY;
-
- { AddBuf( ANSIGotoXY( CurX+1, CurY+1 ) ); }
-
-
- { RealCursorGoto( IData^.Ascreen-1, CurX, Cury );}
-
- { call visionix services to set window coords }
-
- END; { With AS^ }
-
- (*
- With IData^.Win[IData^.InWin] Do
- BEGIN
-
- SaveXY := 0;
- CursorXY := (ODP^.Y1 SHL 8) + ODP^.X1;
- WindMinXY := (Pred(ODP^.Y1) SHL 8) + Pred(ODP^.X1);
- WindMaxXY := (Pred(ODP^.Y2) SHL 8) + Pred(ODP^.X2);
- CurTextAttr := TextAttr;
-
- END;
- *)
-
- END; { ODF_Window }
-
- {----}
-
- ODF_ColorText:
- BEGIN
-
- With AS^ Do
- BEGIN
-
- CurAttr := (CurAttr AND $F0) + (ODP^.TheColor AND $0F);
-
- { AddBuf( ANSITextColor(ODP^.TheColor) ); }
-
- END; { With AS^ }
-
- END;
-
-
- {----}
-
- ODF_ColorBack:
- BEGIN
-
- With AS^ Do
- BEGIN
-
- CurAttr := (CurAttr AND $0F) + ((ODP^.TheColor AND $07) SHL 4);
-
- { AddBuf( ANSITextBackground(ODP^.TheColor) ); }
-
- END; { With AS^ }
-
- END; { ODF_ColorBack }
-
-
- {----}
-
- ODF_GetWin:
- BEGIN
-
- With AS^ Do
- BEGIN
-
- ODP^.X1 := WinX1+1;
- ODP^.Y1 := WinY1+1;
- ODP^.X2 := WinX2+1;
- ODP^.Y2 := WinY2+1;
-
- ODP^.Status := ODS_Changed;
-
- END; { With AS^ }
-
- END; { ODF_GetWin }
-
- {----}
-
- ODF_GetAttr:
- BEGIN
-
- ODP^.Attr := AS^.CurAttr;
- ODP^.Status := ODS_Changed;
-
- END; { ODF_GetAttr }
-
- {----}
-
- ODF_SetAttr:
- BEGIN
-
- AS^.CurAttr := ODP^.Attr;
-
- { AddBuf( ANSITextAttr(ODP^.Attr) ); }
-
- END; { ODF_SetAttr }
-
-
- {----}
-
- ODF_GetXY:
- BEGIN
-
- ODP^.X1 := (AS^.CurX+1)-AS^.WinX1;
- ODP^.Y1 := (AS^.CurY+1)-AS^.WinY1;
-
- ODP^.Status := ODS_Changed;
-
- END; { ODF_GetXY }
-
- {----}
-
- ODF_GetNumScreens:
- BEGIN
-
-
- ODP^.Screens := IData^.NumScreens;
-
- ODP^.Status := ODS_Changed;
-
- END; { ODF_GetNumScreens }
-
- {----}
-
- ODF_GoScreen:
- BEGIN
-
- END; { ODF_GoScreen }
-
- {----}
-
- ODF_SetCursorType:
- BEGIN
-
- END; { ODF_SetCursorType }
-
- {----}
-
- ODF_DrawVLine:
- BEGIN
-
- END; { ODF_DrawVLine }
-
- {----}
-
- ODF_DrawHLine:
- BEGIN
-
- END; { ODF_DrawHLine }
-
- {----}
-
- ODF_DrawBox:
- BEGIN
-
- END; { ODF_DrawBox }
-
- {----}
-
- ODF_ReadChar:
- BEGIN
-
- ODP^.Status := ODS_CantDo;
- ODP^.StatusMsg := ODS_MsgNoScreenBuff;
-
- END; { ODF_ReadChar }
-
- {----}
-
- ODF_ReadAttr:
- BEGIN
-
- ODP^.Status := ODS_CantDo;
- ODP^.StatusMsg := ODS_MsgNoScreenBuff;
-
- END; { ODF_ReadAttr }
-
- {----}
-
- ODF_WriteAttr:
- BEGIN
-
- MySyncAttr;
-
- ODP^.Status := ODS_CantDo;
- ODP^.StatusMsg := ODS_MsgNoScreenBuff;
-
- END; { ODF_WriteAttr }
-
- {----}
-
- ODF_QueryRegion:
- BEGIN
-
- ODP^.Status := ODS_CantDo;
- ODP^.StatusMsg := ODS_MsgNoScreenBuff;
-
- END; { ODF_QueryRegion }
-
- {----}
-
- ODF_ReadRegion:
- BEGIN
-
- ODP^.Status := ODS_CantDo;
- ODP^.StatusMsg := ODS_MsgNoScreenBuff;
-
- END; { ODF_ReadRegion }
-
- {----}
-
- ODF_WriteRegion:
- BEGIN
-
- MyWriteRegion;
-
- END; { ODF_WriteRegion }
-
- {----}
-
- ODF_DriverRenew:
- BEGIN
-
- END; { ODF_DriverRenew }
-
- {----}
-
- ODF_CursorUp:
- BEGIN
-
- With AS^Do
- BEGIN
-
- If CurY-ODP^.NumVal<WinY1 Then
- CurY:=WinY1
- ELSE
- Dec(CurY,ODP^.NumVal);
-
- MySyncCurXY;
-
- (*
- For Z:=1 to ODP^.NumVal Do
- If CurY>WinY1 Then
- BEGIN
- Dec(CurY);
- AddBuf( ANSIUp );
- Dec(KnownCurY);
- END;
- *)
-
- END; { With AS^ }
-
- END; { ODF_CursorUp }
-
- {----}
-
- ODF_CursorDown:
- BEGIN
-
- With AS^Do
- BEGIN
-
- If CurY+ODP^.NumVal>WinY2 Then
- CurY:=WinY2
- ELSE
- Inc(CurY,ODP^.NumVal);
-
- MySyncCurXY;
-
- (*
-
- For Z:=1 to ODP^.NumVal Do
- If CurY<WinY2 Then
- BEGIN
- Inc(CurY);
- AddBuf( ANSIDown );
- Inc(KnownCurY);
- END;
-
- *)
-
- END; { With AS^ }
-
- END; { ODF_CursorDown }
-
- {----}
-
- ODF_CursorLeft:
- BEGIN
-
- With AS^ Do
- BEGIN
-
- If CurX-ODP^.NumVal<WinX1 Then
- CurX:=WinX1
- ELSE
- Dec(CurX,ODP^.NumVal);
-
- MySyncCurXY;
-
- (*
- For Z:=1 to ODP^.Numval Do
- If CurX>WinX1 Then
- BEGIN
- Dec(CurX);
- AddBuf( ANSILeft );
- Dec(KnownCurX);
- END;
- *)
-
- END; { With AS^ }
-
- END; { ODF_CursorLeft }
-
- {----}
-
- ODF_CursorRight:
- BEGIN
-
- With AS^Do
- BEGIN
-
- If CurX+ODP^.NumVal>WinX2 Then
- CurX:=WinX2
- ELSE
- Inc(CurX,ODP^.NumVal);
-
- MySyncCurXY;
-
- (*
- For Z:=1 to ODP^.Numval Do
- If CurX<WinX2 Then
- BEGIN
- Inc(CurX);
- AddBuf( ANSIRight );
- Inc(KnownCurX);
- END;
- *)
-
- END; { With AS^ }
-
- END; { ODF_CursorRight }
-
- {----}
-
- ODF_RegionScrUp:
- BEGIN
-
- (*
-
- If (winx1=x1) and (winx2=x2)
-
-
- *)
-
- END; { ODF_RegionScrUp }
-
- {----}
-
- ODF_RegionScrDown:
- BEGIN
-
- END; { ODF_RegionScrDown }
-
- {----}
-
- ODF_RegionCopy:
- BEGIN
-
- END; { ODF_RegionCopy }
-
- {----}
-
- ODF_RegionFill:
- BEGIN
- With AS^ DO
- BEGIN
-
- AddBuf( ANSISavePos );
-
- MyTextAttr( ODP^.Attr );
-
- S := RepeatString( ODP^.CH, (ODP^.X2-ODP^.X1)+1 );
-
- For Z:=ODP^.Y1 To ODP^.Y2 Do
- BEGIN
- AddBuf( ANSIGotoXY( ODP^.X1, Z ) );
- Addbuf( S )
- END;
-
- AddBuf( AnsiRestorePos );
-
- END;
-
- END; { ODF_RegionFill }
-
- {----}
-
- ODF_RegionFillA:
- BEGIN
- ODP^.Status := ODS_CantDo;
- ODP^.StatusMsg := ODS_MsgNoScreenBuff;
- END; { ODF_RegionFillA }
-
- {----}
-
- ODF_RegionFillC:
- BEGIN
- ODP^.Status := ODS_CantDo;
- ODP^.StatusMsg := ODS_MsgNoScreenBuff;
- END; { ODF_RegionFillC }
-
- {----}
-
- ODF_RepeatChar:
- BEGIN
-
- MySyncAttr;
- MySyncCurXY;
-
- If (ODP^.CH <> #13) AND (ODP^.CH <> #10) Then
- For Z := 1 to ODP^.NumVal Do
- AddBufCh( ODP^.Ch );
-
- END; { ODF_RepeatChar }
-
- {----}
-
- ODF_RepeatCharAt:
- BEGIN
-
- { goto optimizations! }
-
- AddBuf( ANSISavePos );
-
- AddBuf( ANSIGotoXY(ODP^.X1, ODP^.Y1) );
-
- MyTextAttr( ODP^.Attr );
-
- If (ODP^.CH <> #13) AND (ODP^.CH <> #10) Then
- For Z := 1 to ODP^.NumVal Do
- AddBufCh( ODP^.Ch );
-
- AddBuf( ANSIRestorePos );
-
- END; { ODF_RepeatCharAt }
-
- {----}
-
- ODF_GetScreenSize:
- BEGIN
-
- With AS^ Do
- BEGIN
-
- ODP^.X1 := IData^.Cols;
- ODP^.Y1 := Idata^.Rows;
-
- END; { With AS^ }
-
- END; { ODF_GetScreenSize }
-
- {----}
-
- ODF_RepeatBlock:
- BEGIN
-
- ChkTextAttr;
-
- MySyncAttr;
-
- MySyncCurXY;
-
- Z := ODP^.Start;
- Z2 := ODP^.Size;
- Z3 := 0;
-
- While (ODP^.NumVal>0) and (Z3=0) Do
- BEGIN
-
- While (Z<=Z2) and (Z3=0) Do
- BEGIN
-
- Z3:=MyWriteChar( TCharArray(ODP^.Buff^)[Z] );
-
- Inc( Z );
-
- END;
-
- IF Z>Z2 Then
- BEGIN
- Dec( ODP^.NumVal);
- If ODP^.NumVal>0 Then
- Z:=1;
- END;
-
- END; { while ODP^.numval>0 }
-
- If Z>ODP^.Size Then
- ODP^.Start := ODP^.Size
- ELSE
- ODP^.Start := Z;
-
- If Z3=1 Then
- BEGIN
- ODP^.Status := ODS_CantDo;
- ODP^.StatusMsg := ODS_MsgNeedScrollUp;
- END;
-
- END; { ODF_WriteBlock }
-
-
- {----}
-
- ODF_FlushBuffers:
- BEGIN
-
- FlushBuff;
-
- END;
-
-
- {----}
-
- Else { Else Case }
-
- END; { Case ODP^.Func }
-
- FlushBuff;
-
- END; { If ODP^.Status = 0 }
-
- END; { ANSIOutDriverProc }
-
- {────────────────────────────────────────────────────────────────────────────}
-
- Procedure AttachAnsiFilter( Chan : TChanHandle;
- SubChan : STRING );
-
- BEGIN
-
- VOutFilterAttach( Chan,
- 0,
- 'ANSIFILTER',
- SubChan,
- AnsiFilter,
- 0,0,0 );
-
-
-
- END;
-
-
-
-
- {────────────────────────────────────────────────────────────────────────────}
- {────────────────────────────────────────────────────────────────────────────}
- {────────────────────────────────────────────────────────────────────────────}
-
-
- BEGIN
-
- END.