home *** CD-ROM | disk | FTP | other *** search
/ POINT Software Programming / PPROG1.ISO / pascal / visionix / voutu.pas < prev    next >
Encoding:
Pascal/Delphi Source File  |  1993-12-28  |  106.1 KB  |  4,834 lines

  1. {
  2.  ════════════════════════════════════════════════════════════════════════════
  3.  
  4.  Visionix Output Unit (VOUT)
  5.    Version 0.7
  6.  Copyright 1991,92,93 Visionix
  7.  ALL RIGHTS RESERVED
  8.  
  9.  ────────────────────────────────────────────────────────────────────────────
  10.  
  11.  Revision history in reverse chronological order:
  12.  
  13.  Initials  Date      Comment
  14.  ────────  ────────  ────────────────────────────────────────────────────────
  15.  
  16.  jrt       12/05/93  Changed single DriverParam parameter on
  17.                      VOutSubChannelNew and VOutFilterAttach to
  18.                      DriverParam1, DriverParam2, and DriverParam3.
  19.  
  20.  jrt       11/10/93  Added RegionFillxxx functions
  21.                      Added RegionFillxxx cases to VirtScreenFilter
  22.  
  23.  jrt       07/10/93  Start of new channel/subchannel/filter architecture
  24.  
  25.  lpg       03/16/93  Added Source Documentation
  26.  
  27.  mep       02/11/93  Cleaned up code for beta release
  28.  
  29.  jrt       02/08/93  Sync with beta 0.12 release
  30.  
  31.  jrt       02/08/93  Added VOutGetScreenSize
  32.  
  33.  jrt       12/07/92  Sync with beta 0.11 release
  34.  
  35.  jrt       11/21/92  Sync with beta 0.08
  36.  
  37.  jrt       09/01/92  First logged revision.
  38.  
  39.  ════════════════════════════════════════════════════════════════════════════
  40.  
  41.  C A V E A T S :
  42.  
  43.    When we have a sub-channel with a driver and a filter, and the driver
  44.    doesn't know how to scroll (and thus returns an ODS_CantDo/
  45.    ODS_MsgNeedScrollxxx, the filter/driver can get out or sync if
  46.    multiple-scroll commands come right after each other.
  47.  
  48.    This is because the filter does all of its work before it calls the
  49.    driver, and so the filter will have already done all of its scrolling.
  50.    When the driver asks for help with scrolling, the filter may no
  51.    longer have all the information about the region to scroll, because
  52.    it has already scrolled the stuff out of the region.
  53.  
  54.    Two solutions are currently proposed:
  55.  
  56.      1) filter will perform ops until it needs to scroll.  Filter will
  57.         then call the Driver until it says it needs to scroll.  Filter
  58.         will then scroll both in a synchronized manner.
  59.  
  60.      2) callback on scroll (yuck)
  61.  
  62.  
  63. }
  64.  
  65.  
  66. (*-
  67.  
  68. [TEXT]
  69.  
  70. <About VOUT>
  71.  
  72.  
  73. <Overview>
  74.  
  75. - VOUT functions.  VOUT contains an extensive collection of video
  76.   text output functions, such as VOutClrScr, VOutWriteString,
  77.   VOutInsLine, VOutWindow, Etc.
  78.  
  79. - Multiple channels.  Every VOUT function takes a "channel handle".
  80.   This tells VOUT which channel to perform the function on.
  81.   "Multiple channels" can be used to perform operations on
  82.   seperate video displays.  For example, two seperate channels
  83.   could be set up for the primary and secondary monitors.  Commands
  84.   sent to the first channel would go to the primary montior.  Commands
  85.   sent to the second channel would go to the secondary monitor.
  86.   Each monitor would then have a different display.
  87.  
  88. - Multiple sub-channels.  Sub-channels are synchronzied branches from
  89.   a channel.
  90.  
  91.   Sub-channels allow the same output commands to be "synchronized"
  92.   on different video displays.  For example, one channel could
  93.   be created with two sub-channels.  One sub-channel would be
  94.   setup for the local video display, and another could be setup
  95.   to send ANSI over a serial port.  Commands to this channel would
  96.   then be sent both to the local video display and out over the
  97.   serial port.
  98.  
  99.   This could be used as the text-output interface for a BBS program
  100.   or other host communications software.
  101.  
  102.  
  103. <Implemenatation>
  104.  
  105. The following example shows how VOUTu is actually implemented.
  106. In the example, we have two channels.  One for VCRT, and another
  107. which could be for any other unit or program.
  108.  
  109. The VCRT channel has two-sub
  110.  
  111.  
  112.               |   ^
  113.               1   |
  114.               |   14
  115.               V   |
  116.     +----------------------------+  +-----------------------------+
  117. A   | VCRTu TP CRT API Unit      |  |  Other VOUT dependent Unit  |
  118.     +----------------------------+  +-----------------------------+
  119.               |   ^                              |    |
  120.               2   |                              |    |
  121.               |   13                             |    |
  122.               V   |                              |    |
  123.     +-------------------------------------------------------------+
  124. B   |      VOUTu Visionix text input/output architecture unit     |
  125.     +-------------------------------------------------------------+
  126.               |   ^                              |    ^
  127.               3   |                              |    |
  128.               |   12                             |    |
  129.               V   |                              V    |
  130.     +--------------------------+       +--------------------------+
  131. C   | VCRT Output channel      |       | Other Output Channel     |
  132.     | (CallChannel function)   |       | (CallChannel function)   |
  133.     +--------------------------+       +--------------------------+
  134.         |   ^         |   ^               |   ^          |    ^
  135.         4   |        11   |               |   |          |    |
  136.         |   |         |   |               |   |          |    |
  137.         |   |         V   |               V   |          V    |
  138.      - - - - - - +  - - - - - -         - - - - - - +  - - - - - -
  139. D   | VidMem       | SerANSI   |       | Other Sub    | Other     |
  140.       Subchannel |   Subchannel          Channel    |   SubChannel
  141.     + - - - - - -  + - - - - - +       + - - - - - -  + - - - - - +
  142.         |   |         |   |               |   ^          |    ^
  143.         |   |         |   |               |   |          |    |
  144.         |   10        |   |               |   |          |    |
  145.         V   |         |   |               |   |          V    |
  146.     +------------+    |   |               |   |       +-----------+
  147. E   | ANSI       |    |   |               |   |       | Other     |
  148.     | Filter     |    12  |               |   |       | Filter    |
  149.     +------------+    |   |               |   |       +-----------+
  150.         |   ^         |   |               |   |          |    ^
  151.         6   |         |   |               |   |          |    |
  152.         |   9         |   |               |   |          |    |
  153.         V   |         V   |               V   |          V    |
  154.     +------------+    |   |               |   |       +-----------+
  155. E   | Avatar     |    |   |               |   |       | Other     |
  156.     | Filter     |    |   13              |   |       | Filter    |
  157.     +------------+    |   |               |   |       +-----------+
  158.         |   ^         |   |               |   |          |    ^
  159.         7   |         |   |               |   |          |    |
  160.         |   8         |   |               |   |          |    |
  161.         V   |         V   |               V   |          V    |
  162.     +------------+ +-----------+       +------------+ +-----------+
  163. F   | VidMem     | | ANSI      |       | Other      | | Other     |
  164.     | Out channel| | OutChannel|       | OutChannel | | OutChannel|
  165.     | driverproc | | driverproc|       | DriverProc | | Driverproc|
  166.     +------------+ +-----------+       +------------+ +-----------+
  167.                         |
  168.                         |
  169.                         V
  170.                    +-----------+
  171.                    | To VSEru  |
  172.                    +-----------+
  173.  
  174.  
  175. (1)  An application makes a call to the VCRTu TP CRT API replacement
  176.      unit to perform video a video text output operation.
  177.  
  178. (2)  VCRTu then calls the appropriate function in VOUTu, passing a handle
  179.      which indicates that the operation should be performed on the
  180.      "VCRT output channel"
  181.  
  182. (3)  VOUTu builds an "Out Driver Packet" (or ODP) with all the
  183.      information about the current video text output operation.
  184.      VOUTu then calls the "CallChannel" function to send the
  185.      ODP to the appropriate output channel (as determined by the
  186.      handle in #2)
  187.  
  188. (4)  The channel passes the ODP to the first sub-channel that it has.
  189.      Each sub-channel is what is known as a "driver stack".
  190.      A sub-channel is a "driver stack" because multiple "filters"
  191.      can be stacked on top of a driver.
  192.  
  193.      The channel passes the ODP to the sub-channel by calling the
  194.      first "filter" or "driver" on the sub-channels driver stack.
  195.  
  196. (5)  The ODP is received by a filter.
  197.      A filter can examine the ODP and determine if it wants to "filter"
  198.      the ODP.  "Filtering" can include either changing the ODP and
  199.      sending it on or generating 1 or more new ODPs and sending it/them
  200.      on.  A good example a filter is the ANSI filter, which converts
  201.      all ANSI commands within ODP "Write Text" commands to the ODP
  202.      equivalents of the ANSI commands, and passes them on.
  203.  
  204.      ODPs are "passed on" by calling the next filter/driver on the
  205.      sub-channels driver stack.
  206.  
  207. (6)  The ODP is received by another filter.  In this example, the
  208.      filter is an Avatar filter, which converts all Avatar commands
  209.      within ODP "write text" commands their ODP equivalents, and
  210.      passes them on.
  211.  
  212.      ODPs are again "passed on" by calling the next filter/driver on the
  213.      sub-channels driver stack.
  214.  
  215. (7)  An "Output driver" receives an ODPs.  Several different varieties of
  216.      ODPs exist.  The CrtVidMem driver takes ODPs and performs them
  217.      on video memory, thereby updating the local screen.  The
  218.      AnsiDriver converts ODPs into ANSI command sequences, which can
  219.      then be sent to the DOS/OS-2 ANSI driver or out over the serial
  220.      port.
  221.  
  222. (8)  When the "Output driver" has completed performing the ODP,
  223.      it marks the ODP as completed and returns to whoever called it.
  224.      If the "output driver" cannot complete the request for some
  225.      reason (for example: if the Output driver was an ANSI one, and the
  226.      ODP is a request to read video memory.  Their is no ANSI
  227.      "read video memory" command, so the ANSI driver could not
  228.      complete the ODP), the ODP marks the packet as incomplete.
  229.  
  230.      The driver then returns to whoever called it.  In this example,
  231.      it is the "Avatar" filter, which was immediately before the driver
  232.      on the driver stack.
  233.  
  234. (9)  The Avatar filter sees that the ODP was completed, and returns
  235.      to whomever called it.  (In this case, the ANSI filter)
  236.  
  237. (10) The ANSI filter sees that the ODP was completed, and returns to
  238.      whomever called it.  (In this case, the CallChannel function)
  239.  
  240. (11) The CallChannel function passes the ODP to the next sub-channel
  241.      it has.   A sequence of events similar to 5-10 occurs again.
  242.      The CallChannel function does this for each sub-channel it has.
  243.  
  244. (12) The CallChannel function returns to the procedure in the VOUTu
  245.      unit that called it.
  246.  
  247. (13) The VOUTu unit extracts any return information from the ODP
  248.      (IE: error code, current text attribute, current X/Y, etc)
  249.      and returns that information to the VCRTu function which called
  250.      it.
  251.  
  252. (14) VCRTu returns to the function which called it.
  253.  
  254.  
  255. The text output operation has now been completed.  Although it might
  256. seem that all of these operations would take an excessive amount
  257. of time to complete, optimizations throughout the VOUTu architecture
  258. insure that everything is accomplished rather quickly.
  259.  
  260.  
  261. -*)
  262.  
  263.  
  264. {$V-}
  265.  
  266. Unit VOutU;
  267.  
  268. Interface
  269.  
  270. Uses
  271.  
  272.   VTypesu,
  273.   VGenu,
  274.   VMultiu;
  275.  
  276. {────────────────────────────────────────────────────────────────────────────}
  277.  
  278.  
  279. {
  280.   OutDriver --> Hardware
  281.   OutDriver --> BIOS
  282.   OutDriver --> DOS/ANSI
  283.   OutDriver --> Crt
  284.   OutDriver --> OpCrt
  285. }
  286.  
  287. {--------------}
  288. { cursor types }
  289. {--------------}
  290.  
  291. Const
  292.  
  293.   cctNone           = 0;
  294.   cctSmall          = 1;
  295.   cctHalf           = 2;
  296.   cctBig            = 3;
  297.  
  298. Const
  299.  
  300.   ODF_DriverNew     = 1;  { <'A'> }
  301.   ODF_DriverOff     = 2;
  302.   ODF_DriverOn      = 3;
  303.   ODF_DriverDispose = 4;
  304.   ODF_WriteChar     = 5;
  305.   ODF_WriteBlock    = 6;
  306.   ODF_WriteVert     = 7;  { <^V><1><len><chars...> }
  307.   ODF_ClrEOL        = 8;
  308.   ODF_ClrScr        = 9;
  309.   ODF_DelLine       = 10;
  310.   ODF_InsLine       = 11;
  311.   ODF_GotoXY        = 12;
  312.   ODF_Window        = 13; { <^V><A><X1><Y1><X2><Y2>            }
  313.   ODF_ColorText     = 14;
  314.   ODF_ColorBack     = 15;
  315.  
  316.   ODF_GetWin        = 16; { <^V><B>                            }
  317.   ODF_GetAttr       = 17; { <^V><C>                            }
  318.   ODF_SetAttr       = 18;
  319.   ODF_GetXY         = 19; { <^V><D>                            }
  320.   ODF_GetNumScreens = 20; { <^V><E>                            }
  321.   ODF_GoScreen      = 21; { <^V><F><screen>                    }
  322.   ODF_SetCursorType = 22; { <^V><G><type>                      }
  323.   ODF_DrawHLine     = 23; { <^V><H><X1><Y1><type><count>       }
  324.   ODF_DrawVLine     = 24; { <^V><I><X1><Y1><type><count>       }
  325.   ODF_DrawBox       = 25; { <^V><J><X1><Y1><X2><Y2><type>      }
  326.  
  327.   ODF_ReadChar      = 26; { <^V><K><X1><Y1>                    }
  328.   ODF_ReadAttr      = 27; { <^V><L><X1><Y1>                    }
  329.   ODF_WriteAttr     = 28; { <^V><M><X1><Y1><attr>              }
  330.  
  331.   ODF_QueryRegion   = 29; { <^V><N><X1><X2><Y1><Y2>            }
  332.   ODF_ReadRegion    = 30; { <^V><O><X1><X2><Y1><Y2>            }
  333.   ODF_WriteRegion   = 31; { <^V><P><X1><X2><Y1><Y2>            }
  334.  
  335.   ODF_DriverRenew   = 32; { <^V><Q><cols><rows>                }
  336.  
  337.   ODF_WriteCharAt   = 33; { <^V><R><X1><Y1><attr>              }
  338.   ODF_WriteBlockAt  = 34; { <^V><S><X1><Y1><attr><count>       }
  339.   ODF_WriteVertAt   = 35; { <^V><T><X1><Y1><attr><count>       }
  340.  
  341.   ODF_GetScreenSize = 36;
  342.  
  343.   ODF_CursorUp      = 40;
  344.   ODF_CursorDown    = 41;
  345.   ODF_CursorLeft    = 42;
  346.   ODF_CursorRight   = 43;
  347.  
  348.   ODF_RegionScrUp   = 44;
  349.   ODF_RegionScrDown = 45;
  350.   ODF_RegionCopy    = 46;
  351.  
  352.   ODF_RegionFill    = 47;
  353.   ODF_RegionFillA   = 48;
  354.   ODF_RegionFillC   = 49;
  355.  
  356.   ODF_RepeatChar    = 50;
  357.   ODF_RepeatCharAt  = 51;
  358.  
  359.   {ODF_RepeatAttr   = 52; }
  360.   {ODF_RepeatAttrAt = 53; }
  361.  
  362.   ODF_RepeatBlock   = 54;
  363.   ODF_RepeatBlockAt = 55;
  364.  
  365.   ODF_FlushBuffers  = 56;
  366.  
  367.   {--------------}
  368.  
  369.   ODS_Changed        = 1;            { the odp has been changed        }
  370.   ODS_Install        = 2;            { When NEWing -- install me       }
  371.   ODS_Sequence       = 4;            { packet is part of a sequence    }
  372.  
  373.  
  374.  
  375.   ODS_CantDo         = 8;            { I cant do/finish what you asked }
  376.                                      { reason will be in the MSG field }
  377.  
  378.   ODS_MsgNoScreenBuff   = 1;         { I dont have a screen buffer     }
  379.   ODS_MsgNeedScrollUp   = 2;         { I need to scroll the window up  }
  380.   ODS_MsgNeedScrollDown = 3;         { I need to scroll the window down}
  381.  
  382.  
  383.  
  384.  
  385.   OLT_UseChar        = 1;
  386.   OLT_ASCII          = 2;
  387.   OLT_UnderLine      = 3;
  388.   OLT_Single         = 4;
  389.   OLT_Double         = 5;
  390.  
  391. Type
  392.  
  393.  
  394.   POutDriverPacket=^TOutDriverPacket;
  395.  
  396.   TOutDriverProc = Procedure( ODPacket : POutDriverPacket );
  397.  
  398.   TProcName = String[20];
  399.  
  400.   PProcName = ^TProcName;
  401.  
  402.   {----}
  403.  
  404.   POutDriverProcLLNode = ^TOutDriverProcLLNode;
  405.  
  406.   {----}
  407.  
  408.   TOutDriverPacket = Record
  409.  
  410.     Func          : WORD;
  411.     ID            : Pointer;
  412.     OutDriverProc : TOutDriverProc;
  413.     Name          : PProcName;
  414. {    DriverInfo    : Pointer; }
  415.  
  416.     DriverParam1  : LONGINT;
  417.     DriverParam2  : LONGINT;
  418.     DriverParam3  : LONGINT;
  419.  
  420.     NextDriver    : POutDriverProcLLNode;
  421.  
  422.     Ch            : CHAR;
  423.  
  424.     NumVal        : WORD;
  425.  
  426.     Start         : WORD;
  427.     Size          : WORD;
  428.     Buff          : Pointer;
  429.  
  430.     X1            : WORD;
  431.     Y1            : WORD;
  432.     X2            : WORD;
  433.     Y2            : WORD;
  434.  
  435.     TheColor      : WORD;
  436.  
  437.     Attr          : WORD;
  438.  
  439.     Screens       : WORD;
  440.     Cursor        : WORD;
  441.     Mode          : WORD;
  442.  
  443.     LineType      : WORD;
  444.     LineLen       : WORD;
  445.  
  446.     BoxType       : WORD;
  447.  
  448.     BoxTL         : CHAR;
  449.     BoxT          : CHAR;
  450.     BoxTR         : CHAR;
  451.     BoxR          : CHAR;
  452.     BoxBR         : CHAR;
  453.     BoxB          : CHAR;
  454.     BoxBL         : CHAR;
  455.     BoxL          : CHAR;
  456.  
  457.     RegionSize    : LONGINT;
  458.     Region        : Pointer;
  459.  
  460.     Status        : WORD;
  461.     StatusMsg     : WORD;
  462.  
  463.   End;
  464.  
  465.   POutDriverProc = ^TOutDriverProc;
  466.  
  467.   POutDriverList = ^TOutDriverList;
  468.  
  469.   TOutDriverList = Record
  470.  
  471.     Proc      : TOutDriverProc;
  472.     ID        : Pointer;
  473.     Next      : POutDriverList;
  474.  
  475.   End;
  476.  
  477.   TOutDriverIData = Record
  478.  
  479.     Off     : WORD;
  480.     Name    : TProcName;
  481.  
  482.   END;
  483.  
  484.   POutDriverIData = ^TOutDriverIData;
  485.  
  486. (*
  487.   TChanInfo = Record
  488.  
  489.     ODP               : TOutDriverPacket;
  490.  
  491.     OutDriverListHead : POutDriverList;
  492.     OutDriverListTail : POutDriverList;
  493.     OutDriverListCurr : Array[1..64] of POutDriverList;
  494.  
  495.   END;
  496. *)
  497.  
  498.   {------------------------------------------}
  499.   { out driver proc link-list / driver stack }
  500.   {------------------------------------------}
  501.  
  502.  
  503.   TOutDriverProcLLNode = RECORD
  504.  
  505.     Name        : STRING;
  506.     Proc        : TOutDriverProc;
  507.     ID          : Pointer;
  508.     NextPLLNode : POutDriverProcLLNode;
  509.  
  510.   END;
  511.  
  512.   {--------------------------------}
  513.   { sub-channel circular link-list }
  514.   {--------------------------------}
  515.  
  516.   PSubChannelList = ^TSubChannelList;
  517.  
  518.   TSubChannelList = RECORD
  519.  
  520.     Name        : STRING;
  521.     Flags       : WORD;
  522. {    ID          : POINTER; }
  523.  
  524.     FirstProc   : POutDriverProcLLNode;
  525.  
  526.     NextSubChan : PSubChannelList;
  527.  
  528.   END;
  529.  
  530.   {------------------}
  531.   { The Channel type }
  532.   {------------------}
  533.  
  534.   TChannel = RECORD
  535.  
  536.     Sig             : WORD; { $1976 }
  537.  
  538.     Flags           : WORD;
  539.     Name            : STRING;
  540.  
  541.     ODP             : TOutDriverPacket;
  542.  
  543.     SubChanListHead : PSubChannelList;
  544.     SubChanListTail : PSubChannelList;
  545.     SubChanListCurr : Array[1..64] of PSubChannelList;
  546.  
  547.   END;
  548.  
  549.  
  550. (*
  551.   TChannel = RECORD
  552.  
  553.     Sig       : WORD; { $1976 }
  554.  
  555.     Flags     : WORD;
  556.     Name      : STRING;
  557.  
  558.     ODP               : TOutDriverPacket;
  559.  
  560.     OutDriverListHead : POutDriverList;
  561.     OutDriverListTail : POutDriverList;
  562.     OutDriverListCurr : Array[1..64] of POutDriverList;
  563.  
  564.   END;
  565. *)
  566.  
  567.  
  568.   TChanHandle = ^TChannel;
  569.  
  570. {────────────────────────────────────────────────────────────────────────────}
  571.  
  572. Procedure CallNextDriver( ODP : POutDriverPacket );
  573.  
  574.  
  575. Function  VOutChannelNew(         Flags          : WORD;
  576.                                   Name           : STRING     ):TChanHandle;
  577.  
  578. Function  VOutChannelDispose(     Chan           : TChanHandle ) : WORD;
  579.  
  580. {----------------------}
  581. { subchannel functions }
  582. {----------------------}
  583.  
  584. Function  VOutSubChannelNew(      Chan           : TChanHandle;
  585.                                   Flags          : WORD;
  586.                                   SubChanName    : STRING;
  587.                                   DriverProc     : TOutDriverProc;
  588.                                   DriverParam1   : LONGINT;
  589.                                   DriverParam2   : LONGINT;
  590.                                   DriverParam3   : LONGINT      ):WORD;
  591.  
  592. Procedure VOutSubChannelOff(      Chan           : TChanHandle;
  593.                                   Name           : TProcName  );
  594.  
  595. Procedure VOutSubChannelOn(       Chan           : TChanHandle;
  596.                                   Name           : TProcName  );
  597.  
  598. Procedure VOutSubChannelDispose(  Chan           : TChanHandle;
  599.                                   Name           : TProcName  );
  600.  
  601.  
  602.  
  603. {------------------}
  604. { filter functions }
  605. {------------------}
  606.  
  607.  
  608. Function  VOutFilterAttach(       Chan           : TChanHandle;
  609.                                   Flags          : WORD;
  610.                                   FilterName     : STRING;
  611.                                   SubChanName    : STRING;
  612.                                   Filter         : TOutDriverProc;
  613.                                   FilterParam1   : LONGINT;
  614.                                   FilterParam2   : LONGINT;
  615.                                   FilterParam3   : LONGINT      ):WORD;
  616.  
  617. Procedure VOutFilterOff(          Chan           : TChanHandle;
  618.                                   Name           : TProcName  );
  619.  
  620. Procedure VOutFilterOn(           Chan           : TChanHandle;
  621.                                   Name           : TProcName  );
  622.  
  623. Procedure VOutFilterDetach(       Chan           : TChanHandle;
  624.                                   Name           : TProcName  );
  625.  
  626.  
  627. {-------------------------}
  628. { default out driver proc }
  629. {-------------------------}
  630.  
  631. Procedure DefaultOutDriverProc(   ODP            : POutDriverPacket );
  632.  
  633.  
  634. {-----------------------------}
  635. { VOUT presentation functions }
  636. {-----------------------------}
  637.  
  638. Procedure VOutWriteChar(          Chan           : TChanHandle;
  639.                                   Ch             : Char          );
  640.  
  641. Procedure VOutWriteBlock(         Chan           : TChanHandle;
  642.                                   Block          : Pointer;
  643.                                   Size           : WORD      );
  644.  
  645. Procedure VOutWriteString(        Chan           : TChanHandle;
  646.                                   S              : STRING    );
  647.  
  648. Procedure VOutWriteBlockVert(     Chan           : TChanHandle;
  649.                                   Block          : Pointer;
  650.                                   Size           : WORD      );
  651.  
  652. Procedure VOutWriteStringVert(    Chan           : TChanHandle;
  653.                                   S              : STRING    );
  654.  
  655. Procedure VOutWriteCharAt(        Chan           : TChanHandle;
  656.                                   X              : WORD;
  657.                                   Y              : WORD;
  658.                                   F              : WORD;
  659.                                   B              : WORD;
  660.                                   Ch             : CHAR      );
  661.  
  662. Procedure VOutWriteBlockAt(       Chan           : TChanHandle;
  663.                                   X              : WORD;
  664.                                   Y              : WORD;
  665.                                   F              : WORD;
  666.                                   B              : WORD;
  667.                                   Block          : Pointer;
  668.                                   Size           : WORD      );
  669.  
  670. Procedure VOutWriteStringAt(      Chan           : TChanHandle;
  671.                                   X              : WORD;
  672.                                   Y              : WORD;
  673.                                   F              : WORD;
  674.                                   B              : WORD;
  675.                                   S              : STRING    );
  676.  
  677. Procedure VOutWriteBlockVertAt(   Chan           : TChanHandle;
  678.                                   X              : WORD;
  679.                                   Y              : WORD;
  680.                                   F              : WORD;
  681.                                   B              : WORD;
  682.                                   Block          : Pointer;
  683.                                   Size           : WORD      );
  684.  
  685. Procedure VOutWriteStringVertAt(  Chan           : TChanHandle;
  686.                                   X              : WORD;
  687.                                   Y              : WORD;
  688.                                   F              : WORD;
  689.                                   B              : WORD;
  690.                                   S              : STRING    );
  691.  
  692. Procedure VOutClrEOL(             Chan           : TChanHandle   );
  693.  
  694. Procedure VOutClrScr(             Chan           : TChanHandle   );
  695.  
  696. Procedure VOutDelLine(            Chan           : TChanHandle   );
  697.  
  698. Procedure VOutInsLine(            Chan           : TChanHandle   );
  699.  
  700. Procedure VOutGotoXY(             Chan           : TChanHandle;
  701.                                   X              : WORD;
  702.                                   Y              : WORD      );
  703.  
  704. Procedure VOutWindow(             Chan           : TChanHandle;
  705.                                   X1             : WORD;
  706.                                   Y1             : WORD;
  707.                                   X2             : WORD;
  708.                                   Y2             : WORD      );
  709.  
  710. Procedure VOutTextColor(          Chan           : TChanHandle;
  711.                                   TheColor       : WORD      );
  712.  
  713. Procedure VOutTextBackGround(     Chan           : TChanHandle;
  714.                                   TheColor       : WORD      );
  715.  
  716.  
  717. Function  VOutTextAttrGet(        Chan           : TChanHandle ): WORD;
  718.  
  719. Procedure VOutTextAttrSet(        Chan           : TChanHandle;
  720.                                   Attr           : WORD      );
  721.  
  722.  
  723. Function  VOutWhereX(             Chan           : TChanHandle ) : WORD;
  724.  
  725. Function  VOUtWhereY(             Chan           : TChanHandle ) : WORD;
  726.  
  727.  
  728. Procedure VOutSetCursorType(      Chan           : TCHanHandle;
  729.                                   CurType        : WORD         );
  730.  
  731.  
  732. Function  VOutQueryRegion(        Chan           : TChanHandle;
  733.                                   X1             : WORD;
  734.                                   Y1             : WORD;
  735.                                   X2             : WORD;
  736.                                   Y2             : WORD      ) : LONGINT;
  737.  
  738. Procedure VOutReadRegion(         Chan           : TChanHandle;
  739.                                   X1             : WORD;
  740.                                   Y1             : WORD;
  741.                                   X2             : WORD;
  742.                                   Y2             : WORD;
  743.                                   Region         : Pointer   );
  744.  
  745. Procedure VOutWriteRegion(        Chan           : TChanHandle;
  746.                                   X1             : WORD;
  747.                                   Y1             : WORD;
  748.                                   X2             : WORD;
  749.                                   Y2             : WORD;
  750.                                   Region         : Pointer   );
  751.  
  752. Function  VOutCharRead(           Chan           : TChanHandle;
  753.                                   X1             : WORD;
  754.                                   Y1             : WORD      ) : CHAR;
  755.  
  756. Function  VOutAttrRead(           Chan           : TChanHandle;
  757.                                   X1             : WORD;
  758.                                   Y1             : WORD      ) : BYTE;
  759.  
  760. Procedure VOutAttrWrite(          Chan           : TChanHandle;
  761.                                   X1             : WORD;
  762.                                   Y1             : WORD;
  763.                                   Attr           : BYTE      );
  764.  
  765.  
  766.  
  767. Procedure VOutGetScreenSize(      Chan           : TChanHandle;
  768.                               Var Rows           : BYTE;
  769.                               Var Cols           : BYTE      );
  770.  
  771. Procedure VOutCursorUp(           Chan           : TChanHandle;
  772.                                   UpCount        : WORD      );
  773.  
  774. Procedure VOutCursorDown(         Chan           : TChanHandle;
  775.                                   UpCount        : WORD      );
  776.  
  777. Procedure VOutCursorLeft(         Chan           : TChanHandle;
  778.                                   UpCount        : WORD      );
  779.  
  780. Procedure VOutCursorRight(        Chan           : TChanHandle;
  781.                                   UpCount        : WORD      );
  782.  
  783. Procedure VOutFillRegion(         Chan           : TChanHandle;
  784.                                   X1             : WORD;
  785.                                   Y1             : WORD;
  786.                                   X2             : WORD;
  787.                                   Y2             : WORD;
  788.                                   Attr           : BYTE;
  789.                                   Ch             : CHAR      );
  790.  
  791. Procedure VOutFillRegionAttr(     Chan           : TChanHandle;
  792.                                   X1             : WORD;
  793.                                   Y1             : WORD;
  794.                                   X2             : WORD;
  795.                                   Y2             : WORD;
  796.                                   Attr           : BYTE       );
  797.  
  798. Procedure VOutFillRegionChar(     Chan           : TChanHandle;
  799.                                   X1             : WORD;
  800.                                   Y1             : WORD;
  801.                                   X2             : WORD;
  802.                                   Y2             : WORD;
  803.                                   Ch             : CHAR      );
  804.  
  805.  
  806. Procedure VOutRepeatBlock(        Chan           : TChanHandle;
  807.                                   RepeatCount    : WORD;
  808.                                   Block          : Pointer;
  809.                                   Size           : WORD      );
  810.  
  811. Procedure VOutRepeatString(       Chan           : TChanHandle;
  812.                                   RepeatCount    : WORD;
  813.                                   S              : STRING    );
  814.  
  815. Procedure VOutFlush(              Chan           : TChanHandle );
  816.  
  817.  
  818. Procedure VirtScreenFilter(       ODP            : POutDriverPacket );
  819.  
  820. {────────────────────────────────────────────────────────────────────────────}
  821.  
  822. Implementation
  823.  
  824.  
  825. {────────────────────────────────────────────────────────────────────────────}
  826.  
  827.  
  828. (*-
  829.  
  830. [FUNCTION]
  831.  
  832. Procedure DefaultOutDriverProc(   ODP       : POutDriverPacket );
  833.  
  834. [PARAMETERS]
  835.  
  836. ODP         Pointer to Out-Driver Packet
  837.  
  838. [RETURNS]
  839.  
  840. (None)
  841.  
  842. [DESCRIPTION]
  843.  
  844. [SEE-ALSO]
  845.  
  846. [EXAMPLE]
  847.  
  848. -*)
  849.  
  850. Procedure DefaultOutDriverProc(   ODP       : POutDriverPacket );
  851.  
  852. BEGIN
  853. (*
  854.   OpCrtOutDriverProc( ODP );
  855. *)
  856. END;  { DefaultOutDriverProc }
  857.  
  858. {────────────────────────────────────────────────────────────────────────────}
  859.  
  860. (*-
  861.  
  862. [FUNCTION]
  863.  
  864. Procedure CallChannel(         ODP       : POutDriverPacket );
  865.  
  866. [PARAMETERS]
  867.  
  868. ODP         Pointer to Out-Driver Packet
  869.  
  870. [RETURNS]
  871.  
  872. (None)
  873.  
  874. [DESCRIPTION]
  875.  
  876. [SEE-ALSO]
  877.  
  878. [EXAMPLE]
  879.  
  880. -*)
  881.  
  882. Procedure CallChannel(   Chan      : TChanHandle;
  883.                             ODP       : POutDriverPacket );
  884.  
  885. Var
  886. (*
  887.   ODN           : POutDriverList;
  888.   NextCurrProc  : POutDriverList;
  889. *)
  890.   SCN             : PSubChannelList;
  891.   NextCurrSubChan : PSubChannelList;
  892.   SaveStart       : WORD;
  893.  
  894. BEGIN
  895.  
  896.   SCN := Chan^.SubChanListCurr[ ODP^.Func ];
  897.  
  898.   NextCurrSubChan := Chan^.SubChanListCurr[ ODP^.Func ]^.NextSubChan;
  899.  
  900.   ODP^. Status := 0;
  901.  
  902.   SaveStart := ODP^.Start;
  903.  
  904.   If SCN <> NIL Then
  905.   BEGIN
  906.  
  907.     Repeat
  908.  
  909.       ODP^.Start := SaveStart;
  910.  
  911.       {--------------------------------------------}
  912.       { Here we prime the sub-channel driver stack }
  913.       { by calling the first driver on the stack.  }
  914.       {--------------------------------------------}
  915.  
  916.       ODP^.ID := SCN^.FirstProc^.ID;
  917.  
  918.       ODP^.NextDriver := SCN^.FirstProc^.NextPLLNode;
  919.  
  920.       SCN^.FirstProc^.Proc( ODP );
  921.  
  922.       {-----------------------------------------}
  923.       { if the sub-channel reports back that it }
  924.       { is executing a sequence of events,      }
  925.       { make it so that next time around, we    }
  926.       { will call this sub-channel first again. }
  927.       {-----------------------------------------}
  928.  
  929.       If ODP^.Status and ODS_Sequence>0 Then
  930.       BEGIN
  931.  
  932.         NextCurrSubChan := SCN;
  933.         ODP^.Status     := ODP^.Status - ODS_Sequence;
  934.  
  935.       END;  { If ODP^.Status }
  936.  
  937.       SCN := SCN^.NextSubChan;
  938.  
  939.     Until SCN = Chan^.SubChanListCurr[ ODP^.Func ];
  940.  
  941.     Chan^.SubChanListCurr[ ODP^.Func ] := NextCurrSubChan;
  942.  
  943.   END; { If ODN }
  944.  
  945. END;  { CallChannel }
  946.  
  947.  
  948. {────────────────────────────────────────────────────────────────────────────}
  949.  
  950. (*-
  951.  
  952. [FUNCTION]
  953.  
  954. Procedure CallNextDriver( ODP : POutDriverPacket );
  955.  
  956. [PARAMETERS]
  957.  
  958. ODP         Pointer to Out-Driver Packet
  959.  
  960. [RETURNS]
  961.  
  962. (None)
  963.  
  964. [DESCRIPTION]
  965.  
  966. [SEE-ALSO]
  967.  
  968. [EXAMPLE]
  969.  
  970. -*)
  971.  
  972. Procedure CallNextDriver( ODP : POutDriverPacket );
  973.  
  974. Var
  975.  
  976.   CurrDriver : POutDriverProcLLNode;
  977.  
  978. BEGIN
  979.  
  980.   If ODP^.NextDriver <> NIL Then
  981.   BEGIN
  982.  
  983.     CurrDriver      := ODP^.NextDriver;
  984.  
  985.     ODP^.NextDriver := ODP^.NextDriver^.NextPLLNode;
  986.  
  987.     ODP^.ID         := CurrDriver^.ID;
  988.  
  989.     CurrDriver^.Proc( ODP );
  990.  
  991.     ODP^.NextDriver := CurrDriver;
  992.  
  993.   END;
  994.  
  995. END;
  996.  
  997. {────────────────────────────────────────────────────────────────────────────}
  998.  
  999.  
  1000. Function  VOutChannelNew(         Flags          : WORD;
  1001.                                   Name           : STRING     ):TChanHandle;
  1002.  
  1003.  
  1004. Var
  1005.  
  1006.   NCH : TChanHandle;
  1007.  
  1008. BEGIN
  1009.  
  1010.   { Allocate a Channel handle }
  1011.  
  1012.   New( NCH );
  1013.  
  1014.   { fill in the new channel handle }
  1015.  
  1016.  
  1017.   NCH^.Sig   := $1976;
  1018.   NCH^.Flags := Flags;
  1019.   NCH^.Name  := Name;
  1020.  
  1021.   NCH^.SubChanListHead    := NIL;
  1022.   NCH^.SubChanListTail    := NIL;
  1023.   NCH^.SubChanListCurr[1] := NIL;
  1024.  
  1025.   VoutChannelNew := NCH;
  1026.  
  1027. END;
  1028.  
  1029. {────────────────────────────────────────────────────────────────────────────}
  1030.  
  1031.  
  1032. Function  VOutChannelDispose(     Chan           : TChanHandle ) : WORD;
  1033.  
  1034.  
  1035. BEGIN
  1036.  
  1037.  
  1038.   Dispose( Chan );
  1039.  
  1040. END;
  1041.  
  1042. {────────────────────────────────────────────────────────────────────────────}
  1043.  
  1044.  
  1045.  
  1046. (*-
  1047.  
  1048. [FUNCTION]
  1049.  
  1050. Function  VOutSubChannelNew(      Chan           : TChanHandle;
  1051.                                   Flags          : WORD;
  1052.                                   SubChanName    : STRING;
  1053.                                   DriverProc     : TOutDriverProc;
  1054.                                   DriverParam1   : LONGINT;
  1055.                                   DriverParam2   : LONGINT;
  1056.                                   DriverParam3   : LONGINT;     ):WORD;
  1057.  
  1058. [PARAMETERS]
  1059.  
  1060. Proc        Out-Driver Procedure
  1061. Name        ?
  1062. DriverInfo  Pointer to Out-Driver Information
  1063. Err         VAR Returned Error Code
  1064.  
  1065. [RETURNS]
  1066.  
  1067. Function : None
  1068. (VAR     : [Err] Error Code) (0=Success)
  1069.  
  1070. [DESCRIPTION]
  1071.  
  1072. [SEE-ALSO]
  1073.  
  1074. [EXAMPLE]
  1075.  
  1076. -*)
  1077.  
  1078. Function  VOutSubChannelNew(      Chan           : TChanHandle;
  1079.                                   Flags          : WORD;
  1080.                                   SubChanName    : STRING;
  1081.                                   DriverProc     : TOutDriverProc;
  1082.                                   DriverParam1   : LONGINT;
  1083.                                   DriverParam2   : LONGINT;
  1084.                                   DriverParam3   : LONGINT      ):WORD;
  1085.  
  1086.  
  1087. Var
  1088.  
  1089.   DLN : POutDriverList;
  1090.   Z   : INTEGER;
  1091.  
  1092.   SLN : PSubChannelList;
  1093.  
  1094.   DLN2: POutDriverProcLLNode;
  1095.  
  1096. BEGIN
  1097.  
  1098.   With Chan^ Do
  1099.   BEGIN
  1100.  
  1101.     {-----------------------------------}
  1102.     { Build the OutDriverPacket for the }
  1103.     { "New" function                    }
  1104.     {-----------------------------------}
  1105.  
  1106.     ODP.Func          := ODF_DriverNew;
  1107.  
  1108.     ODP.ID            := NIL;
  1109.     ODP.OutDriverProc := DriverProc;
  1110.     ODP.Name          := @Name;
  1111.     ODP.DriverParam1  := DriverParam1;
  1112.     ODP.DriverParam2  := DriverParam2;
  1113.     ODP.DriverParam3  := DriverParam3;
  1114.  
  1115.     ODP.Status        := 0;
  1116.  
  1117.     ODP.NextDriver    := NIL;
  1118.  
  1119.     { call da oder drivers }
  1120.  
  1121.     {---------------------------}
  1122.     { Call the "New" Out Driver }
  1123.     {---------------------------}
  1124.  
  1125.     DriverProc( @ODP );
  1126.  
  1127.     {---------------------------------------}
  1128.     { Was the OutDriverPacket returned with }
  1129.     { the install bit set?                  }
  1130.     {---------------------------------------}
  1131.  
  1132.     If ODP.Status and ODS_Install <>0 Then
  1133.     BEGIN
  1134.  
  1135.       New( SLN  );
  1136.  
  1137.       New( DLN2 );
  1138.  
  1139.       {-----------------------------------}
  1140.       { Build the start of the out driver }
  1141.       { stack / linked list               }
  1142.       {-----------------------------------}
  1143.  
  1144.       DLN2^.Name        := SubChanName;
  1145.       DLN2^.Proc        := DriverProc;
  1146.       DLN2^.ID          := ODP.ID;
  1147.       DLN2^.NextPLLNode := NIL;
  1148.  
  1149.       {----------------------------}
  1150.       { Build the sub-channel node }
  1151.       {----------------------------}
  1152.  
  1153.       SLN^.Name         := SubChanName;
  1154.       SLN^.Flags        := Flags;
  1155.   {   SLN^.ID           := DriverParams; } {!^! what is this used for}
  1156.       SLN^.FirstProc    := DLN2;
  1157.  
  1158.       {--------------------------------}
  1159.       { Is this the first sub-channel? }
  1160.       {--------------------------------}
  1161.  
  1162.       If SubChanListHead = NIL Then
  1163.       BEGIN
  1164.  
  1165.         SubChanListHead := SLN;
  1166.         SubChanListTail := SLN;
  1167.  
  1168.         For Z := 1 to 64 Do
  1169.           SubChanListCurr[ Z ] := SLN;
  1170.  
  1171.       END;  { If SubChanListHead=NIL }
  1172.  
  1173.       {----------------------------------------------}
  1174.       { Fill out the next field to point to the head }
  1175.       {----------------------------------------------}
  1176.  
  1177.       SLN^.NextSubChan := SubChanListHead;
  1178.  
  1179.       {---------------------------------}
  1180.       { and put it in the SubChanList   }
  1181.       {---------------------------------}
  1182.  
  1183.       SubChanListTail^.NextSubChan := SLN;
  1184.  
  1185.       SubChanListTail := SLN;
  1186.  
  1187.  
  1188. (*
  1189.       {---------------------------------}
  1190.       { Create a new OutDriverList node }
  1191.       {---------------------------------}
  1192.  
  1193.       New( DLN );
  1194.  
  1195.       {-------------------------------}
  1196.       { Is this the first Out driver? }
  1197.       {-------------------------------}
  1198.  
  1199.       If OutDriverListHead = NIL Then
  1200.       BEGIN
  1201.  
  1202.         OutDriverListHead := DLN;
  1203.         OutDriverListTail := DLN;
  1204.  
  1205.         For Z := 1 to 64 Do
  1206.           OutDriverListCurr[ Z ] := DLN;
  1207.  
  1208.       END;  { If C.OutDriverListHead }
  1209.  
  1210.       {-----------------------}
  1211.       { Fill out the new node }
  1212.       {-----------------------}
  1213.  
  1214.       DLN^.Proc := DriverProc;
  1215.       DLN^.ID   := ODP.ID;
  1216.       DLN^.Next := OutDriverListHead;
  1217.  
  1218.       {---------------------------------}
  1219.       { and put it in the OutDriverList }
  1220.       {---------------------------------}
  1221.  
  1222.       OutDriverListTail^.Next := DLN;
  1223.  
  1224.       OutDriverListTail := DLN;
  1225. *)
  1226.  
  1227.     END; { If ODP^.Status = Install }
  1228.  
  1229.   END; { With Chan^ }
  1230.  
  1231. END; { VOutDriverNew }
  1232.  
  1233. {────────────────────────────────────────────────────────────────────────────}
  1234.  
  1235. (*-
  1236.  
  1237. [FUNCTION]
  1238.  
  1239. Procedure VOutSubChannelOff(      Chan           : TChanHandle;
  1240.                                   Name           : TProcName  );
  1241.  
  1242. [PARAMETERS]
  1243.  
  1244. Name        ?
  1245.  
  1246. [RETURNS]
  1247.  
  1248. (None)
  1249.  
  1250. [DESCRIPTION]
  1251.  
  1252. [SEE-ALSO]
  1253.  
  1254. [EXAMPLE]
  1255.  
  1256. -*)
  1257.  
  1258. Procedure VOutSubChannelOff(      Chan           : TChanHandle;
  1259.                                   Name           : TProcName  );
  1260.  
  1261. BEGIN
  1262.  
  1263.   With Chan^ Do
  1264.   BEGIN
  1265.  
  1266.     ODP.Func := ODF_DriverOff;
  1267.     ODP.Name := @Name;
  1268.  
  1269.     CallChannel( Chan, @ODP );
  1270.  
  1271.   END;  { With C }
  1272.  
  1273. END;  { VOutDriverOff }
  1274.  
  1275. {────────────────────────────────────────────────────────────────────────────}
  1276.  
  1277. (*-
  1278.  
  1279. [FUNCTION]
  1280.  
  1281. Procedure VOutSubChannelOn(       Chan           : TChanHandle;
  1282.                                   Name           : TProcName  );
  1283.  
  1284. [PARAMETERS]
  1285.  
  1286. Name        ?
  1287.  
  1288. [RETURNS]
  1289.  
  1290. (None)
  1291.  
  1292. [DESCRIPTION]
  1293.  
  1294. [SEE-ALSO]
  1295.  
  1296. [EXAMPLE]
  1297.  
  1298. -*)
  1299.  
  1300. Procedure VOutSubChannelOn(       Chan           : TChanHandle;
  1301.                                   Name           : TProcName  );
  1302.  
  1303. BEGIN
  1304.  
  1305.   With Chan^ Do
  1306.   BEGIN
  1307.  
  1308.     ODP.Func := ODF_DriverOn;
  1309.     ODP.Name := @Name;
  1310.  
  1311.     CallChannel( Chan, @ODP );
  1312.  
  1313.   END;  { With C }
  1314.  
  1315. END;  { VOutDriverOn }
  1316.  
  1317. {────────────────────────────────────────────────────────────────────────────}
  1318.  
  1319. (*-
  1320.  
  1321. [FUNCTION]
  1322.  
  1323. Procedure VOutSubChannelDispose(  Chan           : TChanHandle;
  1324.                                   Name           : TProcName  );
  1325.  
  1326. [PARAMETERS]
  1327.  
  1328. Name        ?
  1329.  
  1330. [RETURNS]
  1331.  
  1332. (None)
  1333.  
  1334. [DESCRIPTION]
  1335.  
  1336. [SEE-ALSO]
  1337.  
  1338. [EXAMPLE]
  1339.  
  1340. -*)
  1341.  
  1342. Procedure VOutSubChannelDispose(  Chan           : TChanHandle;
  1343.                                   Name           : TProcName  );
  1344.  
  1345. BEGIN
  1346.  
  1347.   With Chan^ Do
  1348.   BEGIN
  1349.  
  1350.     ODP.Func := ODF_DriverDispose;
  1351.     ODP.Name := @Name;
  1352.  
  1353.     CallChannel( Chan, @ODP );
  1354.  
  1355.   END;  { With C }
  1356.  
  1357. END;  { VOutSubChannelDispose }
  1358.  
  1359.  
  1360. {────────────────────────────────────────────────────────────────────────────}
  1361.  
  1362.  
  1363.  
  1364. Function  VOutFilterAttach(       Chan           : TChanHandle;
  1365.                                   Flags          : WORD;
  1366.                                   FilterName     : STRING;
  1367.                                   SubChanName    : STRING;
  1368.                                   Filter         : TOutDriverProc;
  1369.                                   FilterParam1   : LONGINT;
  1370.                                   FilterParam2   : LONGINT;
  1371.                                   FilterParam3   : LONGINT      ):WORD;
  1372.  
  1373. Var
  1374.  
  1375.   TheSubChan   : PSubChannelList;
  1376.  
  1377.   DLN2         : POutDriverProcLLNode;
  1378.  
  1379. BEGIN
  1380.  
  1381.  
  1382.   With Chan^ Do
  1383.   BEGIN
  1384.  
  1385.     {----------------------}
  1386.     { Find the sub-channel }
  1387.     {----------------------}
  1388.  
  1389.     TheSubChan := Chan^.SubChanListHead;
  1390.  
  1391.     While (TheSubChan^.Name<>SubChanName                  ) and
  1392.           (TheSubChan^.NextSubChan<>Chan^.SubChanListHead ) Do
  1393.  
  1394.       TheSubChan := TheSubChan^.NextSubChan;
  1395.  
  1396.  
  1397.     If TheSubChan^.Name=SubChanName Then
  1398.     BEGIN
  1399.  
  1400.       {-----------------------------------}
  1401.       { Build the OutDriverPacket for the }
  1402.       { "New" function                    }
  1403.       {-----------------------------------}
  1404.  
  1405.       ODP.Func          := ODF_DriverNew;
  1406.  
  1407.       ODP.ID            := NIL;
  1408.       ODP.OutDriverProc := Filter;
  1409.       ODP.Name          := @FilterName;
  1410.  
  1411.       ODP.DriverParam1  := FilterParam1;
  1412.       ODP.DriverParam2  := FilterParam2;
  1413.       ODP.DriverParam3  := FilterParam3;
  1414.  
  1415.       ODP.Status        := 0;
  1416.  
  1417.       ODP.NextDriver    := NIL;
  1418.  
  1419.       {---------------------------}
  1420.       { Call the "New" Filter     }
  1421.       {---------------------------}
  1422.  
  1423.       Filter( @ODP );
  1424.  
  1425.       {---------------------------------------}
  1426.       { Was the OutDriverPacket returned with }
  1427.       { the install bit set?                  }
  1428.       {---------------------------------------}
  1429.  
  1430.       If ODP.Status and ODS_Install <>0 Then
  1431.       BEGIN
  1432.  
  1433.         New( DLN2 );
  1434.  
  1435.         {-----------------------------------}
  1436.         { Build the start of the out driver }
  1437.         { stack / linked list               }
  1438.         {-----------------------------------}
  1439.  
  1440.         DLN2^.Name        := FilterName;
  1441.         DLN2^.Proc        := Filter;
  1442.         DLN2^.ID          := ODP.ID;
  1443.         DLN2^.NextPLLNode := TheSubChan^.FirstProc;
  1444.  
  1445.  
  1446.         {---------------------}
  1447.         { put it on the stack }
  1448.         {---------------------}
  1449.  
  1450.         TheSubChan^.FirstProc := DLN2;
  1451.  
  1452.       END; { If ODP^.Status = Install }
  1453.  
  1454.     END; { If TheSubChan^.Name=SubChanname }
  1455.  
  1456.   END; { With Chan^ }
  1457.  
  1458. END;
  1459.  
  1460. {────────────────────────────────────────────────────────────────────────────}
  1461.  
  1462.  
  1463. Procedure VOutFilterOff(          Chan           : TChanHandle;
  1464.                                   Name           : TProcName  );
  1465.  
  1466. BEGIN
  1467.  
  1468. END;
  1469.  
  1470. {────────────────────────────────────────────────────────────────────────────}
  1471.  
  1472.  
  1473. Procedure VOutFilterOn(           Chan           : TChanHandle;
  1474.                                   Name           : TProcName  );
  1475.  
  1476. BEGIN
  1477.  
  1478. END;
  1479.  
  1480. {────────────────────────────────────────────────────────────────────────────}
  1481.  
  1482.  
  1483. Procedure VOutFilterDetach(       Chan           : TChanHandle;
  1484.                                   Name           : TProcName  );
  1485.  
  1486.  
  1487.  
  1488. BEGIN
  1489.  
  1490. END;
  1491.  
  1492. {────────────────────────────────────────────────────────────────────────────}
  1493.  
  1494. (*-
  1495.  
  1496. [FUNCTION]
  1497.  
  1498. Procedure VOutWriteChar(          Chan           : TChanHandle;
  1499.                                   Ch             : Char          );
  1500.  
  1501. [PARAMETERS]
  1502.  
  1503. Ch          Character to Write
  1504.  
  1505. [RETURNS]
  1506.  
  1507. (None)
  1508.  
  1509. [DESCRIPTION]
  1510.  
  1511. [SEE-ALSO]
  1512.  
  1513. [EXAMPLE]
  1514.  
  1515. -*)
  1516.  
  1517. Procedure VOutWriteChar(          Chan           : TChanHandle;
  1518.                                   Ch             : Char          );
  1519.  
  1520. BEGIN
  1521.  
  1522.   With Chan^ Do
  1523.   BEGIN
  1524.  
  1525.     ODP.Func := ODF_WriteChar;
  1526.     ODP.CH   := CH;
  1527.  
  1528.     CallChannel( Chan, @ODP );
  1529.  
  1530.   END;  { With Chan^ }
  1531.  
  1532. END;  { VOutWriteChar }
  1533.  
  1534. {────────────────────────────────────────────────────────────────────────────}
  1535.  
  1536. (*-
  1537.  
  1538. [FUNCTION]
  1539.  
  1540. Procedure VOutWriteBlock(         Chan           : TChanHandle;
  1541.                                   Block          : Pointer;
  1542.                                   Size           : WORD      );
  1543.  
  1544. [PARAMETERS]
  1545.  
  1546. Block       Pointer to Block Data to Write
  1547. Size        Size of Block Data in Bytes
  1548.  
  1549. [RETURNS]
  1550.  
  1551. (None)
  1552.  
  1553. [DESCRIPTION]
  1554.  
  1555. [SEE-ALSO]
  1556.  
  1557. [EXAMPLE]
  1558.  
  1559. -*)
  1560.  
  1561. Procedure VOutWriteBlock(         Chan           : TChanHandle;
  1562.                                   Block          : Pointer;
  1563.                                   Size           : WORD      );
  1564.  
  1565. BEGIN
  1566.  
  1567.   With Chan^ Do
  1568.   BEGIN
  1569.  
  1570.     ODP.Func   := ODF_WriteBlock;
  1571.     ODP.Start  := 1;
  1572.     ODP.Size   := Size;
  1573.     ODP.Buff   := Block;
  1574.  
  1575.     CallChannel( Chan, @ODP );
  1576.  
  1577.   END;  { With Chan^ }
  1578.  
  1579. END;  { VOutWriteBlock }
  1580.  
  1581. {────────────────────────────────────────────────────────────────────────────}
  1582.  
  1583. (*-
  1584.  
  1585. [FUNCTION]
  1586.  
  1587. Procedure VOutWriteString(        Chan           : TChanHandle;
  1588.                                   S              : STRING    );
  1589.  
  1590. [PARAMETERS]
  1591.  
  1592. S           String to Write
  1593.  
  1594. [RETURNS]
  1595.  
  1596. (None)
  1597.  
  1598. [DESCRIPTION]
  1599.  
  1600. [SEE-ALSO]
  1601.  
  1602. [EXAMPLE]
  1603.  
  1604. -*)
  1605.  
  1606. Procedure VOutWriteString(        Chan           : TChanHandle;
  1607.                                   S              : STRING    );
  1608.  
  1609. BEGIN
  1610.  
  1611.   With Chan^ Do
  1612.   BEGIN
  1613.  
  1614.     ODP.Func   := ODF_WriteBlock;
  1615.     ODP.Start  := 1;
  1616.     ODP.Size   := Byte(S[0]);
  1617.     ODP.Buff   := @S[1];
  1618.  
  1619.     CallChannel( Chan, @ODP );
  1620.  
  1621.   END;  { With Chan^ }
  1622.  
  1623. END;  { VOutWriteString }
  1624.  
  1625. {────────────────────────────────────────────────────────────────────────────}
  1626.  
  1627. (*-
  1628.  
  1629. [FUNCTION]
  1630.  
  1631. Procedure VOutWriteBlockVert(     Chan           : TChanHandle;
  1632.                                   Block          : Pointer;
  1633.                                   Size           : WORD      );
  1634.  
  1635. [PARAMETERS]
  1636.  
  1637. Block       Pointer to Block Data to Write Vertically
  1638. Size        Size of Block Data in Bytes
  1639.  
  1640. [RETURNS]
  1641.  
  1642. (None)
  1643.  
  1644. [DESCRIPTION]
  1645.  
  1646. [SEE-ALSO]
  1647.  
  1648. [EXAMPLE]
  1649.  
  1650. -*)
  1651.  
  1652. Procedure VOutWriteBlockVert(     Chan           : TChanHandle;
  1653.                                   Block          : Pointer;
  1654.                                   Size           : WORD      );
  1655.  
  1656. BEGIN
  1657.  
  1658.   With Chan^ Do
  1659.   BEGIN
  1660.  
  1661.     ODP.Func := ODF_WriteVert;
  1662.     ODP.Size := Size;
  1663.     ODP.Buff := Block;
  1664.  
  1665.     CallChannel( Chan, @ODP );
  1666.  
  1667.   END;  { With Chan^ }
  1668.  
  1669. END;  { VOutWriteBlockVert }
  1670.  
  1671. {────────────────────────────────────────────────────────────────────────────}
  1672.  
  1673. (*-
  1674.  
  1675. [FUNCTION]
  1676.  
  1677. Procedure VOutWriteStringVert(    Chan           : TChanHandle;
  1678.                                   S              : STRING    );
  1679.  
  1680. [PARAMETERS]
  1681.  
  1682. S           String to Write Vertically
  1683. [RETURNS]
  1684.  
  1685. (None)
  1686.  
  1687. [DESCRIPTION]
  1688.  
  1689. [SEE-ALSO]
  1690.  
  1691. [EXAMPLE]
  1692.  
  1693. -*)
  1694.  
  1695. Procedure VOutWriteStringVert(    Chan           : TChanHandle;
  1696.                                   S              : STRING    );
  1697.  
  1698. BEGIN
  1699.  
  1700.   With Chan^ Do
  1701.   BEGIN
  1702.  
  1703.     ODP.Func := ODF_WriteVert;
  1704.     ODP.Size := Byte(S[0]);
  1705.     ODP.Buff := @S[1];
  1706.  
  1707.     CallChannel( Chan, @ODP );
  1708.  
  1709.   END;  { With Chan^ }
  1710.  
  1711. END;  { VOutWriteStringVert }
  1712.  
  1713. {────────────────────────────────────────────────────────────────────────────}
  1714.  
  1715. (*-
  1716.  
  1717. [FUNCTION]
  1718.  
  1719. Procedure VOutWriteCharAt(        Chan           : TChanHandle;
  1720.                                   X              : WORD;
  1721.                                   Y              : WORD;
  1722.                                   F              : WORD;
  1723.                                   B              : WORD;
  1724.                                   Ch             : CHAR      );
  1725.  
  1726. [PARAMETERS]
  1727.  
  1728. X           X Screen Coordinate
  1729. Y           Y Screen Coordinate
  1730. F           Foreground Color
  1731. B           Background Color
  1732. Ch          Character to Write
  1733.  
  1734. [RETURNS]
  1735.  
  1736. (None)
  1737.  
  1738. [DESCRIPTION]
  1739.  
  1740. [SEE-ALSO]
  1741.  
  1742. [EXAMPLE]
  1743.  
  1744. -*)
  1745.  
  1746. Procedure VOutWriteCharAt(        Chan           : TChanHandle;
  1747.                                   X              : WORD;
  1748.                                   Y              : WORD;
  1749.                                   F              : WORD;
  1750.                                   B              : WORD;
  1751.                                   Ch             : CHAR      );
  1752.  
  1753. BEGIN
  1754.  
  1755.   With Chan^ Do
  1756.   BEGIN
  1757.  
  1758.     ODP.Func := ODF_WriteCharAt;
  1759.     ODP.X1   := X;
  1760.     ODP.Y1   := Y;
  1761.  
  1762.     ODP.Attr := (VOutTextAttrGet( Chan ) and $FF80) +
  1763.                 ((B AND $0F) SHL 4)         +
  1764.                 (F AND $0F);
  1765.  
  1766.     ODP.CH   := CH;
  1767.  
  1768.     CallChannel( Chan, @ODP );
  1769.  
  1770.   END;  { With Chan^ }
  1771.  
  1772. END;  { VOutWriteCharAt }
  1773.  
  1774. {────────────────────────────────────────────────────────────────────────────}
  1775.  
  1776. (*-
  1777.  
  1778. [FUNCTION]
  1779.  
  1780. Procedure VOutWriteBlockAt(       Chan           : TChanHandle;
  1781.                                   X              : WORD;
  1782.                                   Y              : WORD;
  1783.                                   F              : WORD;
  1784.                                   B              : WORD;
  1785.                                   Block          : Pointer;
  1786.                                   Size           : WORD      );
  1787.  
  1788. [PARAMETERS]
  1789.  
  1790. X           X Screen Coordinate
  1791. Y           Y Screen Coordinate
  1792. F           Foreground Color
  1793. B           Background Color
  1794. Block       Pointer to Block Data to Write
  1795. Size        Size of Block Data in Bytes
  1796.  
  1797. [RETURNS]
  1798.  
  1799. (None)
  1800.  
  1801. [DESCRIPTION]
  1802.  
  1803. [SEE-ALSO]
  1804.  
  1805. [EXAMPLE]
  1806.  
  1807. -*)
  1808.  
  1809. Procedure VOutWriteBlockAt(       Chan           : TChanHandle;
  1810.                                   X              : WORD;
  1811.                                   Y              : WORD;
  1812.                                   F              : WORD;
  1813.                                   B              : WORD;
  1814.                                   Block          : Pointer;
  1815.                                   Size           : WORD      );
  1816.  
  1817. BEGIN
  1818.  
  1819.   With Chan^ Do
  1820.   BEGIN
  1821.  
  1822.     ODP.Func := ODF_WriteBlockAt;
  1823.     ODP.X1   := X;
  1824.     ODP.Y1   := Y;
  1825.     ODP.Attr := (VOutTextAttrGet( Chan ) and $FF80) + ((B AND $0F) SHL 4) + (F AND $0F);
  1826.     ODP.Size := Size;
  1827.     ODP.Buff := Block;
  1828.  
  1829.     CallChannel( Chan, @ODP );
  1830.  
  1831.   END;  { With Chan^ }
  1832.  
  1833. END;  { VOutWriteBlockAt }
  1834.  
  1835. {────────────────────────────────────────────────────────────────────────────}
  1836.  
  1837. (*-
  1838.  
  1839. [FUNCTION]
  1840.  
  1841. Procedure VOutWriteStringAt(      Chan           : TChanHandle;
  1842.                                   X              : WORD;
  1843.                                   Y              : WORD;
  1844.                                   F              : WORD;
  1845.                                   B              : WORD;
  1846.                                   S              : STRING    );
  1847.  
  1848. [PARAMETERS]
  1849.  
  1850. X           X Screen Coordinate
  1851. Y           Y Screen Coordinate
  1852. F           Foreground Color
  1853. B           Background Color
  1854. S           String to Write
  1855.  
  1856. [RETURNS]
  1857.  
  1858. (None)
  1859.  
  1860. [DESCRIPTION]
  1861.  
  1862. [SEE-ALSO]
  1863.  
  1864. [EXAMPLE]
  1865.  
  1866. -*)
  1867.  
  1868. Procedure VOutWriteStringAt(      Chan           : TChanHandle;
  1869.                                   X              : WORD;
  1870.                                   Y              : WORD;
  1871.                                   F              : WORD;
  1872.                                   B              : WORD;
  1873.                                   S              : STRING    );
  1874.  
  1875. BEGIN
  1876.  
  1877.   With Chan^ Do
  1878.   BEGIN
  1879.  
  1880.     ODP.Attr := (VOutTextAttrGet( Chan ) and $FF80) + ((B AND $0F) SHL 4) + (F AND $0F);
  1881.  
  1882.     ODP.Func := ODF_WriteBlockAt;
  1883.     ODP.X1   := X;
  1884.     ODP.Y1   := Y;
  1885.     ODP.Size := Byte(S[0]);
  1886.     ODP.Buff := @S[1];
  1887.  
  1888.     CallChannel( Chan, @ODP );
  1889.  
  1890.   END;  { With Chan^ }
  1891.  
  1892. END;  { VOutWriteStringAt }
  1893.  
  1894. {────────────────────────────────────────────────────────────────────────────}
  1895.  
  1896. (*-
  1897.  
  1898. [FUNCTION]
  1899.  
  1900. Procedure VOutWriteBlockVertAt(   Chan           : TChanHandle;
  1901.                                   X              : WORD;
  1902.                                   Y              : WORD;
  1903.                                   F              : WORD;
  1904.                                   B              : WORD;
  1905.                                   Block          : Pointer;
  1906.                                   Size           : WORD      );
  1907.  
  1908.  
  1909. [PARAMETERS]
  1910.  
  1911. X           X Screen Coordinate
  1912. Y           Y Screen Coordinate
  1913. F           Foreground Color
  1914. B           Background Color
  1915. Block       Pointer to Block Data to Write
  1916. Size        Size of Block Data in Bytes
  1917.  
  1918. [RETURNS]
  1919.  
  1920. (None)
  1921.  
  1922. [DESCRIPTION]
  1923.  
  1924. [SEE-ALSO]
  1925.  
  1926. [EXAMPLE]
  1927.  
  1928. -*)
  1929.  
  1930. Procedure VOutWriteBlockVertAt(   Chan           : TChanHandle;
  1931.                                   X              : WORD;
  1932.                                   Y              : WORD;
  1933.                                   F              : WORD;
  1934.                                   B              : WORD;
  1935.                                   Block          : Pointer;
  1936.                                   Size           : WORD      );
  1937.  
  1938.  
  1939. BEGIN
  1940.  
  1941.   With Chan^ Do
  1942.   BEGIN
  1943.  
  1944.     ODP.Func := ODF_WriteVertAt;
  1945.     ODP.X1   := X;
  1946.     ODP.Y1   := Y;
  1947.     ODP.Attr := (VOutTextAttrGet( Chan )and $FF80) + ((B AND $0F) SHL 4) + (F AND $0F);
  1948.     ODP.Size := Size;
  1949.     ODP.Buff := Block;
  1950.  
  1951.     CallChannel( Chan, @ODP );
  1952.  
  1953.   END;  { With Chan^ }
  1954.  
  1955. END;  { VOutWriteBlockVertAt }
  1956.  
  1957. {────────────────────────────────────────────────────────────────────────────}
  1958.  
  1959. (*-
  1960.  
  1961. [FUNCTION]
  1962.  
  1963. Procedure VOutWriteStringVertAt(  Chan           : TChanHandle;
  1964.                                   X              : WORD;
  1965.                                   Y              : WORD;
  1966.                                   F              : WORD;
  1967.                                   B              : WORD;
  1968.                                   S              : STRING    );
  1969.  
  1970. [PARAMETERS]
  1971.  
  1972. X           X Screen Coordinate
  1973. Y           Y Screen Coordinate
  1974. F           Foreground Color
  1975. B           Background Color
  1976. S           String to Write
  1977.  
  1978. [RETURNS]
  1979.  
  1980. (None)
  1981.  
  1982. [DESCRIPTION]
  1983.  
  1984. [SEE-ALSO]
  1985.  
  1986. [EXAMPLE]
  1987.  
  1988. -*)
  1989.  
  1990. Procedure VOutWriteStringVertAt(  Chan           : TChanHandle;
  1991.                                   X              : WORD;
  1992.                                   Y              : WORD;
  1993.                                   F              : WORD;
  1994.                                   B              : WORD;
  1995.                                   S              : STRING    );
  1996.  
  1997. BEGIN
  1998.  
  1999.   With Chan^ Do
  2000.   BEGIN
  2001.  
  2002.     ODP.Func := ODF_WriteVertAt;
  2003.     ODP.X1   := X;
  2004.     ODP.Y1   := Y;
  2005.     ODP.Attr := (VOutTextAttrGet( Chan ) and $FF80) + ((B AND $0F) SHL 4) + (F AND $0F);
  2006.     ODP.Size := Byte(S[0]);
  2007.     ODP.Buff := @S[1];
  2008.  
  2009.     CallChannel( Chan, @ODP );
  2010.  
  2011.   END;  { With Chan^ }
  2012.  
  2013. END;  { VOutWriteStringVertAt }
  2014.  
  2015. {────────────────────────────────────────────────────────────────────────────}
  2016.  
  2017. (*-
  2018.  
  2019. [FUNCTION]
  2020.  
  2021. Procedure VOutClrEOL(             Chan           : TChanHandle   );
  2022.  
  2023. [PARAMETERS]
  2024.  
  2025. (None)
  2026.  
  2027. [RETURNS]
  2028.  
  2029. (None)
  2030.  
  2031. [DESCRIPTION]
  2032.  
  2033. [SEE-ALSO]
  2034.  
  2035. [EXAMPLE]
  2036.  
  2037. -*)
  2038.  
  2039. Procedure VOutClrEOL(             Chan           : TChanHandle   );
  2040.  
  2041. BEGIN
  2042.  
  2043.   With Chan^ Do
  2044.   BEGIN
  2045.  
  2046.     ODP.Func := ODF_ClrEOL;
  2047.     CallChannel( Chan, @ODP );
  2048.  
  2049.   END;  { With Chan^ }
  2050.  
  2051. END;  { VoutClrEOL }
  2052.  
  2053. {────────────────────────────────────────────────────────────────────────────}
  2054.  
  2055. (*-
  2056.  
  2057. [FUNCTION]
  2058.  
  2059. Procedure VOutClrScr(             Chan           : TChanHandle   );
  2060.  
  2061. [PARAMETERS]
  2062.  
  2063. (None)
  2064.  
  2065. [RETURNS]
  2066.  
  2067. (None)
  2068.  
  2069. [DESCRIPTION]
  2070.  
  2071. [SEE-ALSO]
  2072.  
  2073. [EXAMPLE]
  2074.  
  2075. -*)
  2076.  
  2077. Procedure VOutClrScr(             Chan           : TChanHandle   );
  2078.  
  2079. BEGIN
  2080.  
  2081.   With Chan^ Do
  2082.   BEGIN
  2083.  
  2084.     ODP.Func := ODF_ClrScr;
  2085.  
  2086.     CallChannel( Chan, @ODP );
  2087.  
  2088.   END;  { With Chan^ }
  2089.  
  2090. END;  { VOutClrScr }
  2091.  
  2092. {────────────────────────────────────────────────────────────────────────────}
  2093.  
  2094. (*-
  2095.  
  2096. [FUNCTION]
  2097.  
  2098. Procedure VOutDelLine(            Chan           : TChanHandle   );
  2099.  
  2100. [PARAMETERS]
  2101.  
  2102. (None)
  2103.  
  2104. [RETURNS]
  2105.  
  2106. (None)
  2107.  
  2108. [DESCRIPTION]
  2109.  
  2110. [SEE-ALSO]
  2111.  
  2112. [EXAMPLE]
  2113.  
  2114. -*)
  2115.  
  2116. Procedure VOutDelLine(            Chan           : TChanHandle   );
  2117.  
  2118. BEGIN
  2119.  
  2120.   With Chan^ Do
  2121.   BEGIN
  2122.  
  2123.     ODP.Func := ODF_DelLine;
  2124.     CallChannel( Chan, @ODP );
  2125.  
  2126.   END;  { With Chan^ }
  2127.  
  2128. END;  { VOutDelLine }
  2129.  
  2130. {────────────────────────────────────────────────────────────────────────────}
  2131.  
  2132. (*-
  2133.  
  2134. [FUNCTION]
  2135.  
  2136.  
  2137. [PARAMETERS]
  2138.  
  2139. (None)
  2140.  
  2141. [RETURNS]
  2142.  
  2143. (None)
  2144.  
  2145. [DESCRIPTION]
  2146.  
  2147. [SEE-ALSO]
  2148.  
  2149. [EXAMPLE]
  2150.  
  2151. -*)
  2152.  
  2153. Procedure VOutInsLine(            Chan           : TChanHandle   );
  2154.  
  2155. BEGIN
  2156.  
  2157.   With Chan^ Do
  2158.   BEGIN
  2159.  
  2160.     ODP.Func := ODF_InsLine;
  2161.     CallChannel( Chan, @ODP );
  2162.  
  2163.   END;  { With Chan^ }
  2164.  
  2165. END;  { VOutInsLine }
  2166.  
  2167. {────────────────────────────────────────────────────────────────────────────}
  2168.  
  2169. (*-
  2170.  
  2171. [FUNCTION]
  2172.  
  2173. Procedure VOutGotoXY(             Chan           : TChanHandle;
  2174.                                   X              : WORD;
  2175.                                   Y              : WORD      );
  2176.  
  2177. [PARAMETERS]
  2178.  
  2179. X           New X Screen Coordinate
  2180. Y           New Y Screen Coordinate
  2181.  
  2182. [RETURNS]
  2183.  
  2184. (None)
  2185.  
  2186. [DESCRIPTION]
  2187.  
  2188. [SEE-ALSO]
  2189.  
  2190. [EXAMPLE]
  2191.  
  2192. -*)
  2193.  
  2194. Procedure VOutGotoXY(             Chan           : TChanHandle;
  2195.                                   X              : WORD;
  2196.                                   Y              : WORD      );
  2197.  
  2198. BEGIN
  2199.  
  2200.   With Chan^ Do
  2201.   BEGIN
  2202.  
  2203.     ODP.Func := ODF_GotoXY;
  2204.     ODP.X1   := X;
  2205.     ODP.Y1   := Y;
  2206.  
  2207.     CallChannel( Chan, @ODP );
  2208.  
  2209.   END;  { With Chan^ }
  2210.  
  2211. END;  { VOutGotoXY }
  2212.  
  2213. {────────────────────────────────────────────────────────────────────────────}
  2214.  
  2215. (*-
  2216.  
  2217. [FUNCTION]
  2218.  
  2219. Procedure VOutWindow(             Chan           : TChanHandle;
  2220.                                   X1             : WORD;
  2221.                                   Y1             : WORD;
  2222.                                   X2             : WORD;
  2223.                                   Y2             : WORD      );
  2224.  
  2225. [PARAMETERS]
  2226.  
  2227. X1          Window Left Screen Coordinate
  2228. Y1          Window Top Screen Coordinate
  2229. X2          Window Right Screen Coordinate
  2230. Y2          Window Bottom Screen Coordinate
  2231.  
  2232. [RETURNS]
  2233.  
  2234. (None)
  2235.  
  2236. [DESCRIPTION]
  2237.  
  2238. [SEE-ALSO]
  2239.  
  2240. [EXAMPLE]
  2241.  
  2242. -*)
  2243.  
  2244. Procedure VOutWindow(             Chan           : TChanHandle;
  2245.                                   X1             : WORD;
  2246.                                   Y1             : WORD;
  2247.                                   X2             : WORD;
  2248.                                   Y2             : WORD      );
  2249.  
  2250. BEGIN
  2251.  
  2252.   With Chan^ Do
  2253.   BEGIN
  2254.  
  2255.     ODP.Func := ODF_Window;
  2256.     ODP.X1   := X1;
  2257.     ODP.Y1   := Y1;
  2258.     ODP.X2   := X2;
  2259.     ODP.Y2   := Y2;
  2260.  
  2261.     CallChannel( Chan, @ODP );
  2262.  
  2263.   END;  { With Chan^ }
  2264.  
  2265. END;  { VOutWindow }
  2266.  
  2267. {────────────────────────────────────────────────────────────────────────────}
  2268.  
  2269. (*-
  2270.  
  2271. [FUNCTION]
  2272.  
  2273. Procedure VOutTextColor(          Chan           : TChanHandle;
  2274.                                   TheColor       : WORD      );
  2275.  
  2276. [PARAMETERS]
  2277.  
  2278. TheColor    New Text Foreground Color
  2279.  
  2280. [RETURNS]
  2281.  
  2282. (None)
  2283.  
  2284. [DESCRIPTION]
  2285.  
  2286. [SEE-ALSO]
  2287.  
  2288. [EXAMPLE]
  2289.  
  2290. -*)
  2291.  
  2292. Procedure VOutTextColor(          Chan           : TChanHandle;
  2293.                                   TheColor       : WORD      );
  2294.  
  2295. BEGIN
  2296.  
  2297.   With Chan^ Do
  2298.   BEGIN
  2299.  
  2300.     ODP.Func     := ODF_ColorText;
  2301.     ODP.TheColor := TheColor;
  2302.  
  2303.     CallChannel( Chan, @ODP );
  2304.  
  2305.   END;  { With Chan^ }
  2306.  
  2307. END;  { VOutTextColor }
  2308.  
  2309. {────────────────────────────────────────────────────────────────────────────}
  2310.  
  2311. (*-
  2312.  
  2313. [FUNCTION]
  2314.  
  2315. Procedure VOutTextBackGround(     Chan           : TChanHandle;
  2316.                                   TheColor       : WORD      );
  2317.  
  2318. [PARAMETERS]
  2319.  
  2320. TheColor    New Text Background Color
  2321.  
  2322. [RETURNS]
  2323.  
  2324. (None)
  2325.  
  2326. [DESCRIPTION]
  2327.  
  2328. [SEE-ALSO]
  2329.  
  2330. [EXAMPLE]
  2331.  
  2332. -*)
  2333.  
  2334. Procedure VOutTextBackGround(     Chan           : TChanHandle;
  2335.                                   TheColor       : WORD      );
  2336.  
  2337. BEGIN
  2338.  
  2339.   With Chan^ Do
  2340.   BEGIN
  2341.  
  2342.     ODP.Func     := ODF_ColorBack;
  2343.     ODP.TheColor := TheColor;
  2344.  
  2345.     CallChannel( Chan, @ODP );
  2346.  
  2347.   END;  { With Chan^ }
  2348.  
  2349. END;  { VOutTextBackGround }
  2350.  
  2351. {────────────────────────────────────────────────────────────────────────────}
  2352.  
  2353. (*-
  2354.  
  2355. [FUNCTION]
  2356.  
  2357. Function  VOutTextAttrGet(        Chan           : TChanHandle ): WORD;
  2358.  
  2359.  
  2360. [PARAMETERS]
  2361.  
  2362. (None)
  2363.  
  2364. [RETURNS]
  2365.  
  2366. Current Text Attribute
  2367.  
  2368. [DESCRIPTION]
  2369.  
  2370. [SEE-ALSO]
  2371.  
  2372. [EXAMPLE]
  2373.  
  2374. -*)
  2375.  
  2376. Function  VOutTextAttrGet(        Chan           : TChanHandle ): WORD;
  2377.  
  2378.  
  2379. BEGIN
  2380.  
  2381.   With Chan^ Do
  2382.   BEGIN
  2383.  
  2384.     ODP.Func     := ODF_GetAttr;
  2385.  
  2386.     CallChannel( Chan, @ODP );
  2387.  
  2388.     VOutTextAttrGet := ODP.Attr;
  2389.  
  2390.   END;  { With Chan^ }
  2391.  
  2392. END;  { VOutTextAttrGet }
  2393.  
  2394. {────────────────────────────────────────────────────────────────────────────}
  2395.  
  2396. (*-
  2397.  
  2398. [FUNCTION]
  2399.  
  2400. Procedure VOutTextAttrSet(        Chan           : TChanHandle;
  2401.                                   Attr           : WORD      );
  2402.  
  2403.  
  2404. [PARAMETERS]
  2405.  
  2406. Attr        New Text Attribute
  2407.  
  2408. [RETURNS]
  2409.  
  2410. (None)
  2411.  
  2412. [DESCRIPTION]
  2413.  
  2414. [SEE-ALSO]
  2415.  
  2416. [EXAMPLE]
  2417.  
  2418. -*)
  2419.  
  2420. Procedure VOutTextAttrSet(        Chan           : TChanHandle;
  2421.                                   Attr           : WORD      );
  2422.  
  2423.  
  2424. BEGIN
  2425.  
  2426.   With Chan^ Do
  2427.   BEGIN
  2428.  
  2429.     ODP.Func     := ODF_SetAttr;
  2430.     ODP.Attr     := Attr;
  2431.  
  2432.     CallChannel( Chan, @ODP );
  2433.  
  2434.   END;  { With Chan^ }
  2435.  
  2436. END;  { VOutTextAttrSet }
  2437.  
  2438. {────────────────────────────────────────────────────────────────────────────}
  2439.  
  2440. (*-
  2441.  
  2442. [FUNCTION]
  2443.  
  2444. Function  VOutWhereX(             Chan           : TChanHandle ) : WORD;
  2445.  
  2446. [PARAMETERS]
  2447.  
  2448. (None)
  2449.  
  2450. [RETURNS]
  2451.  
  2452. Current Cursor X Screen Coordinate
  2453.  
  2454. [DESCRIPTION]
  2455.  
  2456. [SEE-ALSO]
  2457.  
  2458. [EXAMPLE]
  2459.  
  2460. -*)
  2461.  
  2462. Function  VOUtWhereX(             Chan           : TChanHandle ) : WORD;
  2463.  
  2464. BEGIN
  2465.  
  2466.   With Chan^ Do
  2467.   BEGIN
  2468.  
  2469.     ODP.Func     := ODF_GetXY;
  2470.  
  2471.     CallChannel( Chan, @ODP );
  2472.  
  2473.     VOutWhereX := ODP.X1;
  2474.  
  2475.   END;  { With Chan^ }
  2476.  
  2477. END;  { VOutWhereX }
  2478.  
  2479. {────────────────────────────────────────────────────────────────────────────}
  2480.  
  2481. (*-
  2482.  
  2483. [FUNCTION]
  2484.  
  2485. Function  VOUtWhereY(             Chan           : TChanHandle ) : WORD;
  2486.  
  2487. [PARAMETERS]
  2488.  
  2489. (None)
  2490.  
  2491. [RETURNS]
  2492.  
  2493. Current Cursor Y Screen Coordinate
  2494.  
  2495. [DESCRIPTION]
  2496.  
  2497. [SEE-ALSO]
  2498.  
  2499. [EXAMPLE]
  2500.  
  2501. -*)
  2502.  
  2503.  
  2504. Function  VOUtWhereY(             Chan           : TChanHandle ) : WORD;
  2505.  
  2506. BEGIN
  2507.  
  2508.   With Chan^ Do
  2509.   BEGIN
  2510.  
  2511.     ODP.Func     := ODF_GetXY;
  2512.  
  2513.     CallChannel( Chan, @ODP );
  2514.  
  2515.     VOutWhereY := ODP.Y1;
  2516.  
  2517.   END;  { With Chan^ }
  2518.  
  2519. END;  { VOutWhereY }
  2520.  
  2521. {────────────────────────────────────────────────────────────────────────────}
  2522.  
  2523. Procedure VOutSetCursorType(      CHan           : TCHanHandle;
  2524.                                   CurType        : WORD         );
  2525.  
  2526. BEGIN
  2527.  
  2528.   With Chan^ Do
  2529.   BEGIN
  2530.  
  2531.     ODP.Func     := ODF_SetCursorType;
  2532.     ODP.NumVal   := CurType;
  2533.  
  2534.     CallChannel( Chan, @ODP );
  2535.  
  2536.   END;
  2537.  
  2538. END;
  2539.  
  2540.  
  2541. {────────────────────────────────────────────────────────────────────────────}
  2542.  
  2543. (*-
  2544.  
  2545. [FUNCTION]
  2546.  
  2547. Function  VOutQueryRegion(        Chan           : TChanHandle;
  2548.                                   X1             : WORD;
  2549.                                   Y1             : WORD;
  2550.                                   X2             : WORD;
  2551.                                   Y2             : WORD      ) : LONGINT;
  2552.  
  2553.  
  2554. [PARAMETERS]
  2555.  
  2556. X1          Region Left Screen Coordinate
  2557. Y1          Region Top Screen Coordinate
  2558. X2          Region Right Screen Coordinate
  2559. Y2          Region Bottom Screen Coordinate
  2560.  
  2561. [RETURNS]
  2562.  
  2563. [DESCRIPTION]
  2564.  
  2565. [SEE-ALSO]
  2566.  
  2567. [EXAMPLE]
  2568.  
  2569. -*)
  2570.  
  2571. Function  VOutQueryRegion(        Chan           : TChanHandle;
  2572.                                   X1             : WORD;
  2573.                                   Y1             : WORD;
  2574.                                   X2             : WORD;
  2575.                                   Y2             : WORD      ) : LONGINT;
  2576.  
  2577.  
  2578. BEGIN
  2579.  
  2580.   VOutQueryRegion := ((1+X2-X1)*2) * (1+Y2-Y1);
  2581.  
  2582. END;  { VOutQueryRegion }
  2583.  
  2584. {────────────────────────────────────────────────────────────────────────────}
  2585.  
  2586. (*-
  2587.  
  2588. [FUNCTION]
  2589.  
  2590. Procedure VOutReadRegion(         Chan           : TChanHandle;
  2591.                                   X1             : WORD;
  2592.                                   Y1             : WORD;
  2593.                                   X2             : WORD;
  2594.                                   Y2             : WORD;
  2595.                                   Region         : Pointer   );
  2596.  
  2597. [PARAMETERS]
  2598.  
  2599. X1          Region Left Screen Coordinate
  2600. Y1          Region Top Screen Coordinate
  2601. X2          Region Right Screen Coordinate
  2602. Y2          Region Bottom Screen Coordinate
  2603. Region      Pointer to Region Read Data
  2604.  
  2605. [RETURNS]
  2606.  
  2607. (None)
  2608.  
  2609. [DESCRIPTION]
  2610.  
  2611. [SEE-ALSO]
  2612.  
  2613. [EXAMPLE]
  2614.  
  2615. -*)
  2616.  
  2617. Procedure VOutReadRegion(         Chan           : TChanHandle;
  2618.                                   X1             : WORD;
  2619.                                   Y1             : WORD;
  2620.                                   X2             : WORD;
  2621.                                   Y2             : WORD;
  2622.                                   Region         : Pointer   );
  2623.  
  2624. BEGIN
  2625.  
  2626.   With Chan^ Do
  2627.   BEGIN
  2628.  
  2629.     ODP.Func   := ODF_ReadRegion;
  2630.     ODP.X1     := X1;
  2631.     ODP.Y1     := Y1;
  2632.     ODP.X2     := X2;
  2633.     ODP.Y2     := Y2;
  2634.     ODP.Region := Region;
  2635.  
  2636.     CallChannel( Chan, @ODP );
  2637.  
  2638.   END;  { With Chan^ }
  2639.  
  2640. END; { VOutReadRegion }
  2641.  
  2642. {────────────────────────────────────────────────────────────────────────────}
  2643.  
  2644. (*-
  2645.  
  2646. [FUNCTION]
  2647.  
  2648. Procedure VOutWriteRegion(        Chan           : TChanHandle;
  2649.                                   X1             : WORD;
  2650.                                   Y1             : WORD;
  2651.                                   X2             : WORD;
  2652.                                   Y2             : WORD;
  2653.                                   Region         : Pointer   );
  2654.  
  2655.  
  2656. [PARAMETERS]
  2657.  
  2658. X1          Region Left Screen Coordinate
  2659. Y1          Region Top Screen Coordinate
  2660. X2          Region Right Screen Coordinate
  2661. Y2          Region Bottom Screen Coordinate
  2662. Region      Pointer to Region Write Data
  2663.  
  2664. [RETURNS]
  2665.  
  2666. (None)
  2667.  
  2668. [DESCRIPTION]
  2669.  
  2670. [SEE-ALSO]
  2671.  
  2672. [EXAMPLE]
  2673.  
  2674. -*)
  2675.  
  2676. Procedure VOutWriteRegion(        Chan           : TChanHandle;
  2677.                                   X1             : WORD;
  2678.                                   Y1             : WORD;
  2679.                                   X2             : WORD;
  2680.                                   Y2             : WORD;
  2681.                                   Region         : Pointer   );
  2682.  
  2683. BEGIN
  2684.  
  2685.   With Chan^ Do
  2686.   BEGIN
  2687.  
  2688.     ODP.Func   := ODF_WriteRegion;
  2689.     ODP.X1     := X1;
  2690.     ODP.Y1     := Y1;
  2691.     ODP.X2     := X2;
  2692.     ODP.Y2     := Y2;
  2693.     ODP.Region := Region;
  2694.  
  2695.     CallChannel( Chan, @ODP );
  2696.  
  2697.   END;  { With Chan^ }
  2698.  
  2699. END;  { VOutWriteRegion }
  2700.  
  2701. {────────────────────────────────────────────────────────────────────────────}
  2702.  
  2703. (*-
  2704.  
  2705. [FUNCTION]
  2706.  
  2707. Function  VOutCharRead(           Chan           : TChanHandle;
  2708.                                   X1             : WORD;
  2709.                                   Y1             : WORD      ) : CHAR;
  2710.  
  2711.  
  2712. [PARAMETERS]
  2713.  
  2714. X1          X Screen Coordinate
  2715. Y1          Y Screen Coordinate
  2716.  
  2717. [RETURNS]
  2718.  
  2719. Character Read at Screen Coordinates
  2720.  
  2721. [DESCRIPTION]
  2722.  
  2723. [SEE-ALSO]
  2724.  
  2725. [EXAMPLE]
  2726.  
  2727. -*)
  2728.  
  2729.  
  2730. Function  VOutCharRead(           Chan           : TChanHandle;
  2731.                                   X1             : WORD;
  2732.                                   Y1             : WORD      ) : CHAR;
  2733.  
  2734. BEGIN
  2735.  
  2736.   With Chan^ Do
  2737.   BEGIN
  2738.  
  2739.     ODP.Func   := ODF_ReadChar;
  2740.     ODP.X1     := X1;
  2741.     ODP.Y1     := Y1;
  2742.  
  2743.     CallChannel( Chan, @ODP );
  2744.  
  2745.     VOutCharRead := ODP.CH;
  2746.  
  2747.   END;  { With Chan^ }
  2748.  
  2749. END;  { VOutCharRead }
  2750.  
  2751. {────────────────────────────────────────────────────────────────────────────}
  2752.  
  2753. (*-
  2754.  
  2755. [FUNCTION]
  2756.  
  2757. Function  VOutAttrRead(           Chan           : TChanHandle;
  2758.                                   X1             : WORD;
  2759.                                   Y1             : WORD      ) : BYTE;
  2760.  
  2761.  
  2762. [PARAMETERS]
  2763.  
  2764. X1          X Screen Coordinate
  2765. Y1          Y Screen Coordinate
  2766.  
  2767. [RETURNS]
  2768.  
  2769. Attribute Read at Screen Coordinates
  2770.  
  2771. [DESCRIPTION]
  2772.  
  2773. [SEE-ALSO]
  2774.  
  2775. [EXAMPLE]
  2776.  
  2777. -*)
  2778.  
  2779. Function  VOutAttrRead(           Chan           : TChanHandle;
  2780.                                   X1             : WORD;
  2781.                                   Y1             : WORD      ) : BYTE;
  2782.  
  2783. BEGIN
  2784.  
  2785.   With Chan^ Do
  2786.   BEGIN
  2787.  
  2788.     ODP.Func   := ODF_ReadAttr;
  2789.     ODP.X1     := X1;
  2790.     ODP.Y1     := Y1;
  2791.  
  2792.     CallChannel( Chan, @ODP );
  2793.  
  2794.     VOutAttrRead := ODP.Attr;
  2795.  
  2796.   END;  { With Chan^ }
  2797.  
  2798. END;  { VOutAttrRead }
  2799.  
  2800. {────────────────────────────────────────────────────────────────────────────}
  2801.  
  2802. (*-
  2803.  
  2804. [FUNCTION]
  2805.  
  2806. Procedure VOutAttrWrite(          Chan           : TChanHandle;
  2807.                                   X1             : WORD;
  2808.                                   Y1             : WORD;
  2809.                                   Attr           : BYTE      );
  2810.  
  2811.  
  2812. [PARAMETERS]
  2813.  
  2814. X1          X Screen Coordinate
  2815. Y1          Y Screen Coordinate
  2816. Attr        Attribute to Write
  2817.  
  2818. [RETURNS]
  2819.  
  2820. (None)
  2821.  
  2822. [DESCRIPTION]
  2823.  
  2824. [SEE-ALSO]
  2825.  
  2826. [EXAMPLE]
  2827.  
  2828. -*)
  2829.  
  2830. Procedure VOutAttrWrite(          Chan           : TChanHandle;
  2831.                                   X1             : WORD;
  2832.                                   Y1             : WORD;
  2833.                                   Attr           : BYTE      );
  2834.  
  2835.  
  2836. BEGIN
  2837.  
  2838.   With Chan^ Do
  2839.   BEGIN
  2840.  
  2841.     ODP.Func   := ODF_WriteAttr;
  2842.     ODP.X1     := X1;
  2843.     ODP.Y1     := Y1;
  2844.     ODP.Attr   := Attr;
  2845.  
  2846.     CallChannel( Chan, @ODP );
  2847.  
  2848.   END;  { With Chan^ }
  2849.  
  2850. END;  { VOutAttrWrite }
  2851.  
  2852. {────────────────────────────────────────────────────────────────────────────}
  2853.  
  2854. (*-
  2855.  
  2856. [FUNCTION]
  2857.  
  2858. Procedure VOutGetScreenSize(      Chan           : TChanHandle;
  2859.                               Var Rows           : BYTE;
  2860.                               Var Cols           : BYTE      );
  2861.  
  2862. [PARAMETERS]
  2863.  
  2864. Rows        VAR Returned Screen Height
  2865. Cols        VAR Returned Screen Width
  2866.  
  2867. [RETURNS]
  2868.  
  2869. Function : None
  2870. (VAR     : [Rows] Screen Height)
  2871. (VAR     : [Cols] Screen Width)
  2872.  
  2873. [DESCRIPTION]
  2874.  
  2875. [SEE-ALSO]
  2876.  
  2877. [EXAMPLE]
  2878.  
  2879. -*)
  2880.  
  2881. Procedure VOutGetScreenSize(      Chan           : TChanHandle;
  2882.                               Var Rows           : BYTE;
  2883.                               Var Cols           : BYTE      );
  2884.  
  2885.  
  2886. BEGIN
  2887.  
  2888.   With Chan^ Do
  2889.   BEGIN
  2890.  
  2891.     ODP.Func   := ODF_GetScreenSize;
  2892.  
  2893.     CallChannel( Chan, @ODP );
  2894.  
  2895.     Rows := ODP.Y1;
  2896.     Cols := ODP.X1;
  2897.  
  2898.   END;  { With Chan^ }
  2899.  
  2900. END;  { VOutGetScreenSize }
  2901.  
  2902. {────────────────────────────────────────────────────────────────────────────}
  2903.  
  2904. Procedure VOutCursorUp(           Chan           : TChanHandle;
  2905.                                   UpCount        : WORD      );
  2906.  
  2907. BEGIN
  2908.  
  2909.   With Chan^ Do
  2910.   BEGIN
  2911.  
  2912.     ODP.Func   := ODF_CursorUp;
  2913.     ODP.Numval := Upcount;
  2914.  
  2915.     CallChannel( Chan, @ODP );
  2916.  
  2917.   END;  { With Chan^ }
  2918.  
  2919. END;  { VOutCursor         }
  2920.  
  2921. {────────────────────────────────────────────────────────────────────────────}
  2922.  
  2923. Procedure VOutCursorDown(         Chan           : TChanHandle;
  2924.                                   UpCount        : WORD      );
  2925.  
  2926. BEGIN
  2927.  
  2928.   With Chan^ Do
  2929.   BEGIN
  2930.  
  2931.     ODP.Func   := ODF_CursorDown;
  2932.     ODP.Numval := Upcount;
  2933.  
  2934.     CallChannel( Chan, @ODP );
  2935.  
  2936.   END;  { With Chan^ }
  2937.  
  2938. END;  { VOutCursor         }
  2939.  
  2940. {────────────────────────────────────────────────────────────────────────────}
  2941.  
  2942. Procedure VOutCursorLeft(         Chan           : TChanHandle;
  2943.                                   UpCount        : WORD      );
  2944.  
  2945.  
  2946. BEGIN
  2947.  
  2948.   With Chan^ Do
  2949.   BEGIN
  2950.  
  2951.     ODP.Func   := ODF_CursorLeft;
  2952.     ODP.Numval := Upcount;
  2953.  
  2954.     CallChannel( Chan, @ODP );
  2955.  
  2956.   END;  { With Chan^ }
  2957.  
  2958. END;  { VOutCursor         }
  2959.  
  2960. {────────────────────────────────────────────────────────────────────────────}
  2961.  
  2962.  
  2963. Procedure VOutCursorRight(        Chan           : TChanHandle;
  2964.                                   UpCount        : WORD      );
  2965.  
  2966.  
  2967. BEGIN
  2968.  
  2969.   With Chan^ Do
  2970.   BEGIN
  2971.  
  2972.     ODP.Func   := ODF_CursorRight;
  2973.     ODP.Numval := Upcount;
  2974.  
  2975.     CallChannel( Chan, @ODP );
  2976.  
  2977.   END;  { With Chan^ }
  2978.  
  2979. END;  { VOutCursor         }
  2980.  
  2981.  
  2982. (*-
  2983.  
  2984. [FUNCTION]
  2985.  
  2986. Procedure VirtScreenFilter(       ODP            : POutDriverPacket );
  2987.  
  2988. [PARAMETERS]
  2989.  
  2990. ODP         Pointer to Output Driver Packet
  2991.  
  2992. [RETURNS]
  2993.  
  2994. (None)
  2995.  
  2996. [DESCRIPTION]
  2997.  
  2998.  
  2999. [SEE-ALSO]
  3000.  
  3001. [EXAMPLE]
  3002.  
  3003. -*)
  3004.  
  3005. Procedure VirtScreenFilter(       ODP            : POutDriverPacket );
  3006.  
  3007. Type
  3008.  
  3009.   TCharBuff = Array[1..32768] of CHAR;
  3010.   PCharBuff = ^TCharBuff;
  3011.  
  3012.   {----}
  3013.  
  3014.   TCell = Record
  3015.  
  3016.     Char    : CHAR;
  3017.     Attr    : BYTE;
  3018.  
  3019.   END;  { TCell }
  3020.  
  3021.   {----}
  3022.  
  3023.   TScreenStore = Array[0..32000] of TCell;
  3024.  
  3025.   PScreenStore = ^TScreenStore;
  3026.  
  3027.   {----}
  3028.  
  3029.   TScreen = RECORD
  3030.  
  3031.     CurX      : WORD;
  3032.     CurY      : WORD;
  3033.     CurAttr   : BYTE;
  3034.  
  3035.     WinX1     : WORD;
  3036.     WinX2     : WORD;
  3037.     WinY1     : WORD;
  3038.     WinY2     : WORD;
  3039.  
  3040.     CurType   : WORD;
  3041.  
  3042.     S         : PScreenStore;
  3043.  
  3044.   END;  { TScreen }
  3045.  
  3046.   PScreen = ^TScreen;
  3047.  
  3048.   {----}
  3049.  
  3050.   TVirtScreenFilterIData = Record
  3051.  
  3052.     Off        : WORD;
  3053.     Name       : TProcName;
  3054.  
  3055.     VirtualCRT : BOOLEAN;
  3056.  
  3057.     DisplayMode: BYTE;
  3058.  
  3059.     Cols       : WORD;
  3060.     Rows       : WORD;
  3061.  
  3062.     YMult      : WORD;
  3063.  
  3064.     NumScreens : BYTE;
  3065.  
  3066.     AScreen    : BYTE;
  3067.  
  3068.     Screen     : Array[1..8] of TScreen;
  3069.  
  3070.     MyODP      : TOutDriverPacket;
  3071.  
  3072.   END;  { TVirtScreenFilterIData }
  3073.  
  3074.   PVirtScreenFilterIData = ^TVirtScreenFilterIData;
  3075.  
  3076.   {----}
  3077.  
  3078.   TVirtScreenFilterInfo = RECORD
  3079.  
  3080.     Cols    : WORD;
  3081.     Rows    : WORD;
  3082.     Screens : WORD;
  3083.  
  3084.   END;  { TVirtScreenFilterInfo }
  3085.  
  3086.   PVirtScreenFilterInfo = ^TVirtScreenFilterInfo;
  3087.  
  3088.   MyPByte = ^Byte;
  3089.   MyPWord = ^Word;
  3090.  
  3091. Var
  3092.  
  3093.   IData      : PVirtScreenFilterIData;
  3094.   YMult      : WORD;
  3095.  
  3096.   AS         : PScreen;
  3097.  
  3098.   Z          : INTEGER;
  3099.   Z2         : INTEGER;
  3100.   Z3         : INTEGER;
  3101.  
  3102.   SaveCurX   : WORD;
  3103.   SaveCurY   : WORD;
  3104.  
  3105.   CallNext   : BOOLEAN;
  3106.  
  3107.   {────────────────────────────────────────────────────────────────────────}
  3108.  
  3109.   Procedure RegionScroll(         X1,Y1,X2,Y2    : WORD;
  3110.                                   Count          : INTEGER   );
  3111.  
  3112.   Var
  3113.  
  3114.     Z : INTEGER;
  3115.     CL: INTEGER;
  3116.  
  3117.     P : POINTER;
  3118.  
  3119.     NC: TCell;
  3120.  
  3121.     Wid : WORD;
  3122.  
  3123.   BEGIN
  3124.  
  3125.  
  3126.     Wid := (X2-X1)+1;
  3127.  
  3128.     NC.Char := ' ';
  3129.     NC.Attr := AS^.CurAttr;
  3130.  
  3131.     If Count<0 Then
  3132.     BEGIN
  3133.  
  3134.       { scroll up }
  3135.  
  3136.       For CL:=1 to Abs(Count) Do
  3137.       BEGIN
  3138.  
  3139.         For Z:= Y1 To Y2 Do
  3140.         BEGIN
  3141.  
  3142.           Move( AS^.S^[ ((Z+1)*YMult)+X1 ],
  3143.                 AS^.S^[ (Z*YMult)+X1     ],
  3144.                 Wid*2                         );
  3145.  
  3146.  
  3147.         END;  { For Z }
  3148.  
  3149.         P := Addr( AS^.S^[ (Y2*YMult)+X1     ] );
  3150.  
  3151.         ASM
  3152.           LES BX, [p]
  3153.           MOV AX, NC
  3154.           MOV CX, Wid
  3155.           CLD
  3156.           REPZ STOSW
  3157.         END;
  3158.  
  3159.       END; { for cl=1 to count }
  3160.  
  3161.     END  { if count<0 }
  3162.     ELSE
  3163.     BEGIN
  3164.  
  3165.       { scroll down/back }
  3166.  
  3167.       For CL:=1 to Count Do
  3168.       BEGIN
  3169.  
  3170.         For Z:= Y2 downTo Y1+1 Do
  3171.         BEGIN
  3172.  
  3173.           Move( AS^.S^[ ((Z-1)*YMult)+X1 ],
  3174.                 AS^.S^[ (Z*YMult)+X1     ],
  3175.                 Wid*2                         );
  3176.  
  3177.         END;  { For Z }
  3178.  
  3179.         P := Addr( AS^.S^[ (Y1*YMult)+X1     ] );
  3180.  
  3181.         ASM
  3182.           LES BX, [p]
  3183.           MOV AX, NC
  3184.           MOV CX, Wid
  3185.           CLD
  3186.           REPZ STOSW
  3187.         END;
  3188.  
  3189.       END; { for cl=1 to count }
  3190.  
  3191.     END; { if count<0 / else }
  3192.  
  3193.   END; { regionscroll }
  3194.  
  3195.  
  3196.   {────────────────────────────────────────────────────────────────────────}
  3197.  
  3198.   (*-
  3199.  
  3200.   [FUNCTION]
  3201.  
  3202.   Procedure RegionRead(             X1,Y1,X2,Y2    : WORD;
  3203.                                     Region         : PScreenStore );
  3204.  
  3205.   [PARAMETERS]
  3206.  
  3207.   X1          Source Left Screen Region Coordinate
  3208.   Y1          Source Top Screen Region Coordinate
  3209.   X2          Source Right Region Screen Region Coordinate
  3210.   Y2          Source Bottom Screen Region Coordinate
  3211.   Region      Pointer to Region Read Data
  3212.  
  3213.   [RETURNS]
  3214.  
  3215.   (None)
  3216.  
  3217.   [DESCRIPTION]
  3218.  
  3219.   Reads a region from the display console to a region store buffer.
  3220.   "Region" should be a pointer to a buffer which is big enough to hold
  3221.   the region data.  Use RegionMemQuery to determine how many bytes must
  3222.   be allocated.
  3223.  
  3224.   [SEE-ALSO]
  3225.  
  3226.   [EXAMPLE]
  3227.  
  3228.   -*)
  3229.  
  3230.   Procedure RegionRead(           X1,Y1,X2,Y2    : WORD;
  3231.                                   Region         : PScreenStore );
  3232.   Var
  3233.     Wid  : WORD;
  3234.     Z    : INTEGER;
  3235.  
  3236.   BEGIN
  3237.  
  3238.     Wid := (X2-X1)+1;
  3239.  
  3240.     For Z:= Y1 To Y2 Do
  3241.     BEGIN
  3242.  
  3243.       Move( AS^.S^[ (Z*YMult)+X1 ], Region^[ (Z-Y1)*Wid ], Wid*2 );
  3244.  
  3245.     END;  { For Z }
  3246.  
  3247.   END;  { RegionRead }
  3248.  
  3249.   {────────────────────────────────────────────────────────────────────────}
  3250.  
  3251.   (*-
  3252.  
  3253.   [FUNCTION]
  3254.  
  3255.   Procedure RegionWrite(            X1,Y1,X2,Y2    : WORD;
  3256.                                     Region         : PScreenStore );
  3257.  
  3258.   [PARAMETERS]
  3259.  
  3260.   X1          Left Screen Region Coordinate
  3261.   Y1          Top Screen Region Coordinate
  3262.   X2          Right Region Screen Region Coordinate
  3263.   Y2          Bottom Screen Region Coordinate
  3264.   Region      Pointer to Region Write Data
  3265.  
  3266.   [RETURNS]
  3267.  
  3268.   (None)
  3269.  
  3270.   [DESCRIPTION]
  3271.  
  3272.   [SEE-ALSO]
  3273.  
  3274.   [EXAMPLE]
  3275.  
  3276.   -*)
  3277.  
  3278.   Procedure RegionWrite(          X1,Y1,X2,Y2    : WORD;
  3279.                                   Region         : PScreenStore );
  3280.  
  3281.   Var
  3282.     Wid  : WORD;
  3283.     Z    : INTEGER;
  3284.  
  3285.   BEGIN
  3286.  
  3287.     Wid := (X2-X1)+1;
  3288.  
  3289.     For Z:= Y1 To Y2 Do
  3290.     BEGIN
  3291.  
  3292.       Move( Region^[ (Z-Y1)*Wid ], AS^.S^[ (Z*YMult)+X1 ], Wid*2 );
  3293.  
  3294.     END;  { For Z }
  3295.  
  3296.   END;  { RegionWrite }
  3297.  
  3298.   {────────────────────────────────────────────────────────────────────────}
  3299.  
  3300.  
  3301.   Procedure CursorDown(           Sync           : BOOLEAN   );
  3302.  
  3303.   BEGIN
  3304.  
  3305.     With AS^ Do
  3306.     BEGIN
  3307.  
  3308.       Inc( CurY );
  3309.  
  3310.       If CurY > WinY2 Then
  3311.       BEGIN
  3312.  
  3313.         RegionScroll( WinX1,
  3314.                       WinY1,
  3315.                       WinX2,
  3316.                       WinY2,
  3317.                       -1        );
  3318.  
  3319.         Dec( CurY );
  3320.  
  3321.       END;  { If CurY }
  3322.  
  3323.  
  3324.     END; { With AS^ }
  3325.  
  3326.   END; { CursorDown }
  3327.  
  3328.   {────────────────────────────────────────────────────────────────────────}
  3329.  
  3330.   Procedure CursorNextChar(       Sync           : BOOLEAN   );
  3331.  
  3332.   BEGIN
  3333.  
  3334.     With   AS^ Do
  3335.     BEGIN
  3336.  
  3337.       Inc( CurX );
  3338.  
  3339.       If CurX > WinX2 Then
  3340.       BEGIN
  3341.  
  3342.         CurX := WinX1;
  3343.  
  3344.         CursorDown( Sync );
  3345.  
  3346.       END;  { If CurX }
  3347.  
  3348.  
  3349.     END; { With AS^ }
  3350.  
  3351.   END; { CursorNextChar }
  3352.  
  3353.   {────────────────────────────────────────────────────────────────────────}
  3354.  
  3355.   Procedure SwapCoords( Var A,B : WORD );
  3356.  
  3357.   Var
  3358.     Temp : WORD;
  3359.  
  3360.   BEGIN
  3361.  
  3362.     Temp := A;
  3363.     A    := B;
  3364.     B    := Temp;
  3365.  
  3366.   END;  { SwapCoords }
  3367.  
  3368.   {────────────────────────────────────────────────────────────────────────}
  3369.  
  3370.   Procedure HelpNextGuyScrollUp;
  3371.  
  3372.   Var
  3373.  
  3374.     P : PScreenStore;
  3375.  
  3376.     x1,y1,x2,y2 : INTEGER;
  3377.  
  3378.   BEGIN
  3379.  
  3380.     x1 := AS^.WinX1;
  3381.     y1 := AS^.WinY1;
  3382.     x2 := AS^.WinX2;
  3383.     y2 := AS^.WinY2;
  3384.  
  3385.     { get mem for a region }
  3386.  
  3387.     GetMem( P, ((X2-X1)+1)*((Y2-Y1)+1)*2 );
  3388.  
  3389.     { read into the region }
  3390.  
  3391.     { we dont have to add one because we already scrolled it }
  3392.  
  3393.     RegionRead( X1, Y1,
  3394.                 X2, Y2,
  3395.                 pointer(p)               );
  3396.  
  3397.     { tell next guys to write the region }
  3398.     { (offset by one line)               }
  3399.  
  3400.  
  3401.     IData^.MyOdp.Func   := ODF_WriteRegion;
  3402.     IData^.MyOdp.X1     := X1+1;
  3403.     IData^.MyOdp.Y1     := Y1+1;
  3404.     IData^.MyOdp.X2     := X2+1;
  3405.     IData^.MyOdp.Y2     := Y2;
  3406.     IData^.MyOdp.Region := P;
  3407.  
  3408.     IData^.MyOdp.NextDriver := ODP^.NextDriver;
  3409.  
  3410.     IData^.MyOdp.Status := 0;
  3411.  
  3412.     CallNextDriver( @IData^.MyODP );
  3413.  
  3414.     { zero out bottom of window, someone!! }
  3415.  
  3416.     FreeMem( P, ((X2-X1)+1)*((Y2-Y1)+1)*2 );
  3417.  
  3418.  
  3419.     IData^.MyODP.Func   := ODF_ClrEol;
  3420.     IData^.MyODP.Status := 0;
  3421.  
  3422.     CallNextDriver( @IData^.MyODP );
  3423.  
  3424.   END;
  3425.  
  3426.   {────────────────────────────────────────────────────────────────────────}
  3427.  
  3428.   Procedure SyncRegion( X1,Y1,X2,Y2 : INTEGER );
  3429.  
  3430.   Var
  3431.  
  3432.     P : PScreenStore;
  3433.  
  3434.   BEGIN
  3435.  
  3436.     { get the memory }
  3437.  
  3438.     GetMem( P, ((X2-X1)+1)*((Y2-Y1)+1)*2 );
  3439.  
  3440.     { read into the region }
  3441.  
  3442.     RegionRead( X1, Y1,
  3443.                 X2, Y2,
  3444.                 pointer(p)               );
  3445.  
  3446.     { tell next guys to write the region }
  3447.  
  3448.     IData^.MyOdp.Func   := ODF_WriteRegion;
  3449.     IData^.MyOdp.X1     := Succ(X1);
  3450.     IData^.MyOdp.Y1     := Succ(Y1);
  3451.     IData^.MyOdp.X2     := Succ(X2);
  3452.     IData^.MyOdp.Y2     := Succ(Y2);
  3453.     IData^.MyOdp.Region := P;
  3454.  
  3455.     IData^.MyOdp.NextDriver := ODP^.NextDriver;
  3456.  
  3457.     IData^.MyOdp.Status := 0;
  3458.  
  3459.     CallNextDriver( @IData^.MyODP );
  3460.  
  3461.     { free the memory }
  3462.  
  3463.     FreeMem( P, ((X2-X1)+1)*((Y2-Y1)+1)*2 );
  3464.  
  3465.  
  3466.   END;
  3467.  
  3468.  
  3469.   {────────────────────────────────────────────────────────────────────────}
  3470.  
  3471.   Procedure MyClrScr;
  3472.  
  3473.   Var
  3474.  
  3475.    P   : POINTER;
  3476.    Z2  : INTEGER;
  3477.    Wid : WORD;
  3478.    NC  : TCell;
  3479.  
  3480.   BEGIN
  3481.  
  3482.     With AS^ DO
  3483.     BEGIN
  3484.  
  3485.       Wid := (WinX2-WinX1)+1;
  3486.  
  3487.       NC.Char := ' ';
  3488.       NC.Attr := AS^.CurAttr;
  3489.  
  3490.       For Z2:=WinY1 to WinY2 Do
  3491.       BEGIN
  3492.  
  3493.         P := Addr( AS^.S^[ (Z2*YMult)+WinX1     ] );
  3494.  
  3495.         ASM
  3496.           LES BX, [p]
  3497.           MOV AX, NC
  3498.           MOV CX, Wid
  3499.           CLD
  3500.           REPZ STOSW
  3501.         END;
  3502.  
  3503.       END; { For Z2 (y) }
  3504.  
  3505.       CurX := WinX1;
  3506.       CurY := WinY1;
  3507.  
  3508.     END; { With AS^ }
  3509.  
  3510.   END; { myclrscr }
  3511.  
  3512.   {────────────────────────────────────────────────────────────────────────}
  3513.  
  3514.  
  3515. BEGIN  { CRTOutDriverProc }
  3516.  
  3517.   CallNext := TRUE;
  3518.  
  3519.   IData := ODP^.ID;
  3520.  
  3521.   If ODP^.Func<> ODF_DriverNew Then
  3522.   BEGIN
  3523.  
  3524.     AS    := @IData^.Screen[ IData^.AScreen ];
  3525.     YMult := IData^.YMult;
  3526.  
  3527.   END;  { ODP^.Func }
  3528.  
  3529.   If ODP^.Status = 0 Then
  3530.   BEGIN
  3531.  
  3532.     Case ODP^.Func Of
  3533.  
  3534.       ODF_DriverNew:
  3535.       BEGIN
  3536.  
  3537.         IF @ODP^.OutDriverProc = @VirtScreenFilter Then
  3538.         BEGIN
  3539.  
  3540.           {-------------------------}
  3541.           { Get a new Instance Data }
  3542.           { master node.            }
  3543.           {-------------------------}
  3544.  
  3545.           New( Idata );
  3546.  
  3547.           { Here we check to see if we are being told to init }
  3548.           { as an actual crt driver or as a virtual.  This    }
  3549.           { needs to be yanked as this filter can only be     }
  3550.           { inited as a virtual! !^!                          }
  3551.  
  3552.           If (ODP^.DriverParam1 = 0) or
  3553.              (ODP^.DriverParam2 = 0) Then
  3554.           BEGIN
  3555.  
  3556.             IData^.VirtualCRT := TRUE;
  3557.  
  3558.             IData^.Name       := ODP^.Name^;
  3559.             IData^.Off        := 0;
  3560.  
  3561.             IData^.Cols       := 80;
  3562.             IData^.Rows       := 25;
  3563.             IData^.NumScreens := 1;
  3564.  
  3565.             IData^.YMult      := IData^.Cols;
  3566.  
  3567.             {------------------------}
  3568.             { Get the Virtual Screen }
  3569.             { stores.                }
  3570.             {------------------------}
  3571.  
  3572.             Z := (IData^.Cols) * (IData^.Rows) * SizeOf( TCell );
  3573.  
  3574.             For Z2 := 1 to IData^.NumScreens Do
  3575.             BEGIN
  3576.               GetMem( IData^.Screen[Z2].S, Z );
  3577.  
  3578.               IData^.Screen[Z2].CurX    := 0;
  3579.               IData^.Screen[Z2].CurY    := 0;
  3580.               IData^.Screen[Z2].CurAttr := $07;
  3581.               IData^.Screen[Z2].WinX1   := 0;
  3582.               IData^.Screen[Z2].WinY1   := 0;
  3583.               IData^.Screen[Z2].WinX2   := Idata^.Cols-1;
  3584.               IData^.Screen[Z2].WinY2   := Idata^.Rows-1;
  3585.               IData^.Screen[Z2].CurType := 0;
  3586.             END;
  3587.  
  3588.             {-----------------------}
  3589.             { Set the active screen }
  3590.             {-----------------------}
  3591.  
  3592.             IData^.AScreen := 1;
  3593.  
  3594.             {--------}
  3595.             { Return }
  3596.             {--------}
  3597.  
  3598.             ODP^.Status := ODS_Install+ODS_Changed;
  3599.             ODP^.ID     := IData;
  3600.  
  3601.           END  { If ODP^.Driverinfo }
  3602.  
  3603.           ELSE
  3604.           BEGIN
  3605.  
  3606.             {-------------------------------------------}
  3607.             { DriverData --> virtual CRT driverinfo, so }
  3608.             { we allocate virtual screen stores and     }
  3609.             { run in virtual CRT mode.                  }
  3610.             {-------------------------------------------}
  3611.  
  3612.             IData^.VirtualCRT := TRUE;
  3613.  
  3614.             IData^.Name       := ODP^.Name^;
  3615.             IData^.Off        := 0;
  3616.  
  3617.             IData^.Cols       := PVirtScreenFilterInfo( ODP^.DriverParam2 )^.Cols;
  3618.             IData^.Rows       := PVirtScreenFilterInfo( ODP^.DriverParam2 )^.Rows;
  3619.             IData^.NumScreens := PVirtScreenFilterInfo( ODP^.DriverParam2 )^.Screens;
  3620.  
  3621.             IData^.YMult      := IData^.Cols;
  3622.  
  3623.             {------------------------}
  3624.             { Get the Virtual Screen }
  3625.             { stores.                }
  3626.             {------------------------}
  3627.  
  3628.             Z := (IData^.Cols) * (IData^.Rows) * SizeOf( TCell );
  3629.  
  3630.             For Z2 := 1 to IData^.NumScreens Do
  3631.             BEGIN
  3632.               GetMem( IData^.Screen[Z2].S, Z );
  3633.  
  3634.               IData^.Screen[Z2].CurX    := 1;
  3635.               IData^.Screen[Z2].CurY    := 1;
  3636.               IData^.Screen[Z2].CurAttr := $07;
  3637.               IData^.Screen[Z2].WinX1   := 1;
  3638.               IData^.Screen[Z2].WinY1   := 1;
  3639.               IData^.Screen[Z2].WinX2   := Idata^.Cols;
  3640.               IData^.Screen[Z2].WinY2   := Idata^.Rows;
  3641.               IData^.Screen[Z2].CurType := 0;
  3642.             END;
  3643.  
  3644.             {-----------------------}
  3645.             { Set the active screen }
  3646.             {-----------------------}
  3647.  
  3648.             IData^.AScreen := 1;
  3649.  
  3650.             {--------}
  3651.             { Return }
  3652.             {--------}
  3653.  
  3654.             ODP^.Status := ODS_Install+ODS_Changed;
  3655.             ODP^.ID     := IData;
  3656.  
  3657.           END; {IF ODP^.Driverinfo / Else }
  3658.  
  3659.         END; { If ODP^.OutDriverProc --> Us }
  3660.  
  3661.       END; { ODF_DriverNew }
  3662.  
  3663.       {----}
  3664.  
  3665.       ODF_DriverOff:
  3666.       BEGIN
  3667.  
  3668.         If ODP^.Name^ = IData^.Name Then
  3669.         BEGIN
  3670.  
  3671.           Inc( Idata^.Off );
  3672.  
  3673.         END;  { If ODP^.Name^ }
  3674.  
  3675.       END;  { ODF_DriverOff }
  3676.  
  3677.       {----}
  3678.  
  3679.       ODF_DriverOn:
  3680.       BEGIN
  3681.  
  3682.         If ODP^.Name^ = IData^.Name Then
  3683.         BEGIN
  3684.  
  3685.           If Idata^.Off <> 0 Then
  3686.             Dec( Idata^.Off );
  3687.  
  3688.         END;  { ODP^.Name^ }
  3689.  
  3690.       END;  { ODF_DriverOn }
  3691.  
  3692.       {----}
  3693.  
  3694.       ODF_DriverDispose:
  3695.       BEGIN
  3696.  
  3697.         If ODP^.Name^ = IData^.Name Then
  3698.         BEGIN
  3699.  
  3700.           {RemoveFromOutDriverStack }
  3701.  
  3702.           Dispose( IData );
  3703.  
  3704.         END;  { If ODP^.Name^ }
  3705.  
  3706.       END;  { ODF_DriverDispose }
  3707.  
  3708.       {----}
  3709.  
  3710.       ODF_WriteChar:
  3711.       BEGIN
  3712.  
  3713.         With AS^ Do
  3714.         BEGIN
  3715.  
  3716.           Case ODP^.Ch Of
  3717.  
  3718.             #13:
  3719.             BEGIN
  3720.  
  3721.               CurX := WinX1;
  3722.  
  3723.             END;  { #13 }
  3724.  
  3725.             #10:
  3726.             BEGIN
  3727.  
  3728.               CursorDown( TRUE );
  3729.  
  3730.             END;  { #10 }
  3731.  
  3732.           Else
  3733.  
  3734.             S^[ (CurY*YMult)+CurX ].Char := ODP^.CH;
  3735.             S^[ (CurY*YMult)+CurX ].Attr := CurAttr;
  3736.  
  3737.             CursorNextChar( TRUE );
  3738.  
  3739.           END;  { Case ODP^.Ch }
  3740.  
  3741.         END; { With AS^ }
  3742.  
  3743.         CallNextDriver( ODP );
  3744.  
  3745.         If (ODP^.Status    = ODS_CantDo          ) and
  3746.            (ODP^.StatusMsg = ODS_MsgNeedScrollUp ) Then
  3747.           HelpNextGuyScrollUp;
  3748.  
  3749.         CallNext := FALSE;
  3750.  
  3751.       END;  { ODF_WriteChar }
  3752.  
  3753.       {----}
  3754.  
  3755.       ODF_WriteBlock:
  3756.       BEGIN
  3757.  
  3758.         With AS^ DO
  3759.         BEGIN
  3760.  
  3761.           For Z:=ODP^.Start to ODP^.Size Do
  3762.           BEGIN
  3763.  
  3764.             Case PCharBuff( ODP^.Buff)^[Z] Of
  3765.  
  3766.               #13:
  3767.               BEGIN
  3768.  
  3769.                 CurX := WinX1;
  3770.  
  3771.                 CursorDown( TRUE );
  3772.  
  3773.               END;  { #13 }
  3774.  
  3775.               #10: {do nothing, man} ;
  3776.  
  3777.             Else
  3778.  
  3779.               S^[ (CurY*YMult)+CurX ].Char := PCharBuff( ODP^.Buff )^[Z];
  3780.               S^[ (CurY*YMult)+CurX ].Attr := CurAttr;
  3781.  
  3782.               CursorNextChar( TRUE );
  3783.  
  3784.             END;  { Case PCharBuff( ODP^.Buf)^[Z] }
  3785.  
  3786.           END; { For Z }
  3787.  
  3788.         END; { With AS^ }
  3789.  
  3790.         Repeat
  3791.           ODP^.Status := 0;
  3792.  
  3793.           CallNextDriver( ODP );
  3794.  
  3795.           If (ODP^.Status    = ODS_CantDo          ) and
  3796.              (ODP^.StatusMsg = ODS_MsgNeedScrollUp ) Then
  3797.             HelpNextGuyScrollUp;
  3798.  
  3799.         Until ODP^.Start=ODP^.Size;
  3800.  
  3801.         CallNext := FALSE;
  3802.  
  3803.       END;  { ODF_WriteBlock }
  3804.  
  3805.       {----}
  3806.  
  3807.       ODF_WriteVert:
  3808.       BEGIN
  3809.  
  3810.         With AS^ DO
  3811.         BEGIN
  3812.  
  3813.           For Z:=1 to ODP^.Size Do
  3814.           BEGIN
  3815.  
  3816.             S^[ (CurY*YMult)+CurX ].Char := PCharBuff( ODP^.Buff )^[Z];
  3817.             S^[ (CurY*YMult)+CurX ].Attr := CurAttr;
  3818.  
  3819.             CursorDown( TRUE );
  3820.  
  3821.           END;  { For Z }
  3822.  
  3823.         END; { With AS^ }
  3824.  
  3825.       END;  { ODF_WriteVert }
  3826.  
  3827.       {----}
  3828.  
  3829.       ODF_WriteCharAt:
  3830.       BEGIN
  3831.  
  3832.         With AS^ Do
  3833.         BEGIN
  3834.  
  3835.           S^[ (Pred(ODP^.Y1)*YMult)+Pred(ODP^.X1) ].Char := ODP^.CH;
  3836.  
  3837.           S^[ (Pred(ODP^.Y1)*YMult)+Pred(ODP^.X1) ].Attr :=
  3838.                                                          ODP^.Attr;
  3839.  
  3840.                                             {CRTColorMap[ ODP^.Attr ];}
  3841.  
  3842.         END; { With AS^ }
  3843.  
  3844.       END;  { ODF_WriteCharAt }
  3845.  
  3846.       {----}
  3847.  
  3848.       ODF_WriteBlockAt:
  3849.       BEGIN
  3850.  
  3851.         With AS^ DO
  3852.         BEGIN
  3853.  
  3854.           SaveCurX := CurX;
  3855.           SaveCurY := CurY;
  3856.  
  3857.           For Z:=1 to ODP^.Size Do
  3858.           BEGIN
  3859.  
  3860.             S^[ (Pred(ODP^.Y1)*YMult)+ODP^.X1+Z-2].Char :=
  3861.                                         PCharBuff( ODP^.Buff )^[Z];
  3862.  
  3863.             S^[ (Pred(ODP^.Y1)*YMult)+ODP^.X1+Z-2].Attr :=
  3864.                                                           ODP^.Attr
  3865.                                             {CRTColorMap[ ODP^.Attr ];}
  3866.  
  3867.           END; { For Z }
  3868.  
  3869.         END; { With AS^ }
  3870.  
  3871.       END;  { ODF_WriteBlockAt }
  3872.  
  3873.       {----}
  3874.  
  3875.       ODF_WriteVertAt:
  3876.       BEGIN
  3877.  
  3878.         With AS^ DO
  3879.         BEGIN
  3880.  
  3881.           For Z:=1 to ODP^.Size Do
  3882.           BEGIN
  3883.  
  3884.             S^[ ((ODP^.Y1+Z-2)*YMult)+Pred(ODP^.X1) ].Char :=
  3885.                                         PCharBuff( ODP^.Buff )^[Z];
  3886.  
  3887.             S^[ ((ODP^.Y1+Z-2)*YMult)+Pred(ODP^.X1) ].Attr :=
  3888.                                                       ODP^.Attr;
  3889.                                         {CRTColorMap[ ODP^.Attr ];}
  3890.  
  3891.           END;  { For Z }
  3892.  
  3893.         END; { With AS^ }
  3894.  
  3895.       END;  { ODF_WriteVertAt }
  3896.  
  3897.       {----}
  3898.  
  3899.       ODF_ClrEOL:
  3900.       BEGIN
  3901.  
  3902.         With AS^ DO
  3903.         BEGIN
  3904.  
  3905.           For Z:=CurX to WinX2 Do
  3906.           BEGIN
  3907.  
  3908.             S^[ (CurY*YMult)+Z ].Char := ' ';
  3909.             S^[ (CurY*YMult)+Z ].Attr := CurAttr;
  3910.  
  3911.           END;  { For Z }
  3912.  
  3913.           { Cursor to next line? }
  3914.  
  3915.         END; { With AS^ }
  3916.  
  3917.       END;  { ODF_ClrEOL }
  3918.  
  3919.       {----}
  3920.  
  3921.       ODF_ClrScr:
  3922.       BEGIN
  3923.  
  3924.         MyClrScr;
  3925.  
  3926.  
  3927.       END;  { ODF_ClrScr }
  3928.  
  3929.       {----}
  3930.  
  3931.       ODF_DelLine:
  3932.       BEGIN
  3933.  
  3934.         With AS^ Do
  3935.         BEGIN
  3936.  
  3937.           RegionScroll( WinX1,
  3938.                         CurY,
  3939.                         WinX2,
  3940.                         WinY2,
  3941.                         -1         );
  3942.  
  3943.           { Cursor to WinX1?? }
  3944.  
  3945.         END;  { With AS^ }
  3946.  
  3947.       END;  { ODF_DelLine }
  3948.  
  3949.       {----}
  3950.  
  3951.       ODF_InsLine:
  3952.       BEGIN
  3953.  
  3954.         With AS^ Do
  3955.         BEGIN
  3956.  
  3957.           RegionScroll( WinX1,
  3958.                         CurY,
  3959.                         WinX2,
  3960.                         WinY2,
  3961.                         1         );
  3962.  
  3963.           { Cursor to WinX1?? }
  3964.  
  3965.         END;  { With AS^ }
  3966.  
  3967.       END;  { ODF_InsLine }
  3968.  
  3969.       {----}
  3970.  
  3971.       ODF_GotoXY:
  3972.       BEGIN
  3973.  
  3974.         With AS^Do
  3975.         BEGIN
  3976.  
  3977.           CurX := WinX1+(ODP^.X1-1);
  3978.           CurY := WinY1+(ODP^.Y1-1);
  3979.  
  3980.  
  3981.         END;  { With AS^ }
  3982.  
  3983.       END;  { ODF_GotoXY }
  3984.  
  3985.       {----}
  3986.  
  3987.       ODF_Window:
  3988.       BEGIN
  3989.  
  3990.         With AS^ Do
  3991.         BEGIN
  3992.  
  3993.           WinX1 := ODP^.X1-1;
  3994.           WinY1 := ODP^.Y1-1;
  3995.           WinX2 := ODP^.X2-1;
  3996.           WinY2 := ODP^.Y2-1;
  3997.  
  3998.           If WinX2<WinX1 Then SwapCoords( WinX1, WinX2 );
  3999.           If WinY2<WinY1 Then SwapCoords( WinY1, WinY2 );
  4000.  
  4001.           CurX  := WinX1;
  4002.           CurY  := WinY1;
  4003.  
  4004.  
  4005.           { call visionix services to set window coords }
  4006.  
  4007.         END;  { With AS^ }
  4008.  
  4009.       END;  { ODF_Window }
  4010.  
  4011.       {----}
  4012.  
  4013.       { 7 6 5 4 3 2 1 0 }
  4014.       { F B B B T T T T }
  4015.  
  4016.       ODF_ColorText:
  4017.       BEGIN
  4018.  
  4019.         With AS^ Do
  4020.         BEGIN
  4021.  
  4022.           CurAttr := (CurAttr AND $F0) + (ODP^.TheColor AND $0F);
  4023.  
  4024.         END;  { With AS^ }
  4025.  
  4026.       END;  { ODF_ColorText }
  4027.  
  4028.       {----}
  4029.  
  4030.       ODF_ColorBack:
  4031.       BEGIN
  4032.  
  4033.         With AS^ Do
  4034.         BEGIN
  4035.  
  4036.           CurAttr := (CurAttr AND $0F) + ((ODP^.TheColor AND $07) SHL 4);
  4037.  
  4038.         END;  { With AS^ }
  4039.  
  4040.       END;  { ODF_ColorBack }
  4041.  
  4042.       {----}
  4043.  
  4044.       ODF_GetWin:
  4045.       BEGIN
  4046.  
  4047.         With AS^ Do
  4048.         BEGIN
  4049.  
  4050.           ODP^.X1 := WinX1+1;
  4051.           ODP^.Y1 := WinY1+1;
  4052.           ODP^.X2 := WinX2+1;
  4053.           ODP^.Y2 := WinY2+1;
  4054.  
  4055.           ODP^.Status := ODS_Changed;
  4056.  
  4057.         END;  { With AS^ }
  4058.  
  4059.       END;  { ODF_GetWin }
  4060.  
  4061.       {----}
  4062.  
  4063.       ODF_GetAttr:
  4064.       BEGIN
  4065.  
  4066.         ODP^.Attr   := AS^.CurAttr;
  4067.  
  4068.         ODP^.Status := ODS_Changed;
  4069.  
  4070.       END;  { ODF_GetAttr }
  4071.  
  4072.       {----}
  4073.  
  4074.       ODF_SetAttr:
  4075.       BEGIN
  4076.  
  4077.         AS^.CurAttr := ODP^.Attr;
  4078.  
  4079.       END;  { ODF_SetAttr }
  4080.  
  4081.       {----}
  4082.  
  4083.       ODF_GetXY:
  4084.       BEGIN
  4085.  
  4086.         ODP^.X1 := (AS^.CurX+1)-AS^.WinX1;
  4087.         ODP^.Y1 := (AS^.CurY+1)-AS^.WinY1;
  4088.  
  4089.         ODP^.Status := ODS_Changed;
  4090.  
  4091.       END;  { ODF_GetXY }
  4092.  
  4093.       {----}
  4094.  
  4095.       ODF_GetNumScreens:
  4096.       BEGIN
  4097.  
  4098.         ODP^.Screens := IData^.NumScreens;
  4099.  
  4100.         ODP^.Status  := ODS_Changed;
  4101.  
  4102.       END;  { ODF_GetNumScreens }
  4103.  
  4104.       {----}
  4105.  
  4106.       ODF_GoScreen:
  4107.       BEGIN
  4108.  
  4109.         If ODP^.Screens <= IData^.NumScreens Then
  4110.           IData^.AScreen := ODP^.Screens;
  4111.  
  4112.       END;  { ODF_GoScreen }
  4113.  
  4114.       {----}
  4115.  
  4116.       ODF_SetCursorType:
  4117.       BEGIN
  4118.  
  4119.  
  4120.         { AS^.CurType :=  }
  4121.  
  4122.       END;  { ODF_SetCursorType }
  4123.  
  4124.       {----}
  4125.  
  4126.  
  4127.       ODF_DrawVLine:
  4128.       BEGIN
  4129.  
  4130.       END;  { ODF_DrawVLine }
  4131.  
  4132.       {----}
  4133.  
  4134.       ODF_DrawHLine:
  4135.       BEGIN
  4136.  
  4137.       END;  { ODF_DrawHLine }
  4138.  
  4139.       {----}
  4140.  
  4141.       ODF_DrawBox:
  4142.       BEGIN
  4143.  
  4144.       END;  { ODF_DrawBox }
  4145.  
  4146.       {----}
  4147.  
  4148.       ODF_ReadChar:
  4149.       BEGIN
  4150.  
  4151.         ODP^.CH := AS^.S^[ (Pred(ODP^.Y1)*YMult)+Pred(ODP^.X1) ].Char;
  4152.  
  4153.         ODP^.Status := ODS_Changed;
  4154.  
  4155.         CallNext := FALSE;
  4156.  
  4157.       END;  { ODF_ReadChar }
  4158.  
  4159.       {----}
  4160.  
  4161.       ODF_ReadAttr:
  4162.       BEGIN
  4163.  
  4164.         ODP^.Attr := AS^.S^[ (Pred(ODP^.Y1)*YMult)+ODP^.X1-1 ].Attr;
  4165.  
  4166.         ODP^.Status := ODS_Changed;
  4167.  
  4168.         CallNext := FALSE;
  4169.  
  4170.       END;  { ODF_ReadAttr }
  4171.  
  4172.       {----}
  4173.  
  4174.       ODF_WriteAttr:
  4175.       BEGIN
  4176.  
  4177.         AS^.S^[ (Pred(ODP^.Y1)*YMult)+ODP^.X1-1 ].Attr :=
  4178.                                                            ODP^.Attr;
  4179.                                              {CRTColorMap[ ODP^.Attr ];}
  4180.  
  4181.         CallNextDriver( ODP );
  4182.  
  4183.         {--------------------------------------}
  4184.         { can the rest of 'em do a write attr? }
  4185.         {--------------------------------------}
  4186.  
  4187.         If ODP^.Status=ODS_CantDo Then
  4188.         BEGIN
  4189.  
  4190.           { rewrite the cell by using the "region write" func }
  4191.  
  4192.           IData^.MyODP.Func := ODF_WriteRegion;
  4193.  
  4194.           IData^.MyODP.X1 := ODP^.X1;
  4195.           IData^.MyODP.Y1 := ODP^.Y1;
  4196.           IData^.MyODP.X2 := ODP^.X1;
  4197.           IData^.MyODP.Y2 := ODP^.Y1;
  4198.  
  4199.           IData^.MyODP.NextDriver := ODP^.NextDriver;
  4200.  
  4201.           IData^.MyODP.Region :=
  4202.                       Addr( AS^.S^[ (Pred(ODP^.Y1)*YMult)+ODP^.X1-1 ] );
  4203.  
  4204.           IData^.MyODP.Status := 0;
  4205.  
  4206.           CallNextDriver( @IData^.MyODP );
  4207.  
  4208.           ODP^.Status := 0;
  4209.  
  4210.         END;
  4211.  
  4212.         CallNext := FALSE;
  4213.  
  4214.  
  4215.       END;  { ODF_WriteAttr }
  4216.  
  4217.       {----}
  4218.  
  4219.  
  4220.       ODF_QueryRegion:
  4221.       BEGIN
  4222.  
  4223.         ODP^.RegionSize := ((ODP^.Y2-ODP^.Y1)+1)*((ODP^.X2-ODP^.X1)+1)*2;
  4224.  
  4225.       END;  { ODF_QueryRegion }
  4226.  
  4227.       {----}
  4228.  
  4229.  
  4230.       ODF_ReadRegion:
  4231.       BEGIN
  4232.  
  4233.         If ODP^.Status AND ODS_Changed=0 Then
  4234.  
  4235.           RegionRead( Pred(ODP^.X1), Pred(ODP^.Y1),
  4236.                       Pred(ODP^.X2), Pred(ODP^.Y2), ODP^.Region );
  4237.  
  4238.         ODP^.Status := ODS_Changed;
  4239.  
  4240.         CallNext := FALSE;
  4241.  
  4242.       END;  { ODF_ReadRegion }
  4243.  
  4244.       {----}
  4245.  
  4246.       ODF_WriteRegion:
  4247.       BEGIN
  4248.  
  4249.         RegionWrite( ODP^.X1-1, ODP^.Y1-1,
  4250.                      ODP^.X2-1, ODP^.Y2-1, ODP^.Region );
  4251.  
  4252.       END;  { ODF_WriteRegion }
  4253.  
  4254.       {----}
  4255.  
  4256.  
  4257.       ODF_DriverRenew:
  4258.       BEGIN
  4259.  
  4260.       END;  { ODF_DriverRenew }
  4261.  
  4262.       {----}
  4263.  
  4264.       ODF_CursorUp:
  4265.       BEGIN
  4266.  
  4267.         With AS^Do
  4268.         BEGIN
  4269. (*
  4270.           If (CurY-ODP^.Numval) >= WinY1 Then
  4271.             Dec( CurY, ODP^.NumVal )
  4272.           Else
  4273.             CurY := WinY1;
  4274. *)
  4275.  
  4276.           For Z:=1 to ODP^.NumVal Do
  4277.             If CurY>WinY1 Then
  4278.               Dec(CurY);
  4279.  
  4280.  
  4281.  
  4282.         END;  { With AS^ }
  4283.  
  4284.       END;  { ODF_CursorUp }
  4285.  
  4286.      {----}
  4287.  
  4288.       ODF_CursorDown:
  4289.       BEGIN
  4290.  
  4291.         With AS^Do
  4292.         BEGIN
  4293. (*
  4294.           If (CurY+ODP^.Numval) <= WinY2 Then
  4295.             Inc( CurY, ODP^.NumVal )
  4296.           Else
  4297.             CurY := WinY2;
  4298. *)
  4299.           For Z:=1 to ODP^.NumVal Do
  4300.             If CurY<WinY2 Then
  4301.               Inc(CurY);
  4302.  
  4303.  
  4304.         END;  { With AS^ }
  4305.  
  4306.       END;  { ODF_CursorDown }
  4307.  
  4308.     {----}
  4309.  
  4310.       ODF_CursorLeft:
  4311.       BEGIN
  4312.  
  4313.         With AS^ Do
  4314.         BEGIN
  4315. (*
  4316.           If (CurX-ODP^.Numval) >= WinX1 Then
  4317.             Dec( CurY, ODP^.NumVal )
  4318.           Else
  4319.             CurX := WinX1;
  4320. *)
  4321.  
  4322.           For Z:=1 to ODP^.Numval Do
  4323.             If CurX>WinX1 Then
  4324.               Dec(CurX);
  4325.  
  4326.  
  4327.  
  4328.         END;  { With AS^ }
  4329.  
  4330.       END;  { ODF_CursorLeft }
  4331.  
  4332.      {----}
  4333.  
  4334.       ODF_CursorRight:
  4335.       BEGIN
  4336.  
  4337.         With AS^Do
  4338.         BEGIN
  4339. (*
  4340.           If (CurX+ODP^.NumVal) <= WinX2 Then
  4341.             Inc( CurX, ODP^.NumVal )
  4342.           Else
  4343.             CurY := WinX2;
  4344. *)
  4345.           For Z:=1 to ODP^.Numval Do
  4346.             If CurX<WinX2 Then
  4347.               Inc(CurX);
  4348.  
  4349.  
  4350.  
  4351.         END;  { With AS^ }
  4352.  
  4353.       END;  { ODF_CursorRight }
  4354.  
  4355.      {----}
  4356.  
  4357.       ODF_RegionScrUp:
  4358.       BEGIN
  4359.  
  4360.         RegionScroll( Pred(ODP^.X1), Pred(ODP^.Y1),
  4361.                       Pred(ODP^.X2), Pred(ODP^.Y2),
  4362.                       ODP^.NumVal         );
  4363.  
  4364.       END;  { ODF_RegionScrUp }
  4365.  
  4366.      {----}
  4367.  
  4368.       ODF_RegionScrDown:
  4369.       BEGIN
  4370.  
  4371.         RegionScroll( Pred(ODP^.X1), Pred(ODP^.Y1),
  4372.                       Pred(ODP^.X2), Pred(ODP^.Y2),
  4373.                       0-ODP^.NumVal         );
  4374.  
  4375.       END;  { ODF_RegionScrDown }
  4376.  
  4377.      {----}
  4378.  
  4379.       ODF_RegionCopy:
  4380.       BEGIN
  4381.  
  4382.       END;  { ODF_RegionCopy }
  4383.  
  4384.      {----}
  4385.  
  4386.       ODF_RegionFill:
  4387.       BEGIN
  4388.  
  4389.         With AS^ DO
  4390.         BEGIN
  4391.  
  4392.           For Z2:=Pred(ODP^.Y1) to Pred(ODP^.Y2) Do
  4393.           BEGIN
  4394.  
  4395.             For Z:=Pred(ODP^.X1) to Pred(ODP^.X2) Do
  4396.             BEGIN
  4397.  
  4398.               S^[ (Z2*YMult)+Z ].Char := ODP^.CH;
  4399.               S^[ (Z2*YMult)+Z ].Attr := ODP^.Attr;
  4400.  
  4401.             END; { For Z (x) }
  4402.  
  4403.           END; { For Z2 (y) }
  4404.  
  4405.         END; { With AS^ }
  4406.  
  4407.       END;  { ODF_RegionFill }
  4408.  
  4409.      {----}
  4410.  
  4411.       ODF_RegionFillA:
  4412.       BEGIN
  4413.  
  4414.         With AS^ DO
  4415.         BEGIN
  4416.  
  4417.           For Z2:=Pred(ODP^.Y1) to Pred(ODP^.Y2) Do
  4418.           BEGIN
  4419.  
  4420.             For Z:=Pred(ODP^.X1) to Pred(ODP^.X2) Do
  4421.             BEGIN
  4422.  
  4423.               S^[ (Z2*YMult)+Z ].Attr := ODP^.Attr;
  4424.  
  4425.             END; { For Z (x) }
  4426.  
  4427.           END; { For Z2 (y) }
  4428.  
  4429.         END; { With AS^ }
  4430.  
  4431.         CallNextDriver( ODP );
  4432.  
  4433.         If (ODP^.Status    = ODS_CantDo          ) and
  4434.            (ODP^.StatusMsg = ODS_MsgNoScreenBuff ) Then
  4435.         BEGIN
  4436.  
  4437.           SyncRegion( Pred(ODP^.X1), Pred(ODP^.Y1),
  4438.                       Pred(ODP^.X2), Pred(ODP^.Y2)  );
  4439.  
  4440.         END;
  4441.  
  4442.         CallNext := FALSE;
  4443.  
  4444.       END;  { ODF_RegionFillA }
  4445.  
  4446.      {----}
  4447.  
  4448.       ODF_RegionFillC:
  4449.       BEGIN
  4450.  
  4451.         With AS^ DO
  4452.         BEGIN
  4453.  
  4454.           For Z2:=Pred(ODP^.Y1) to Pred(ODP^.Y2) Do
  4455.           BEGIN
  4456.  
  4457.             For Z:=Pred(ODP^.X1) to Pred(ODP^.X2) Do
  4458.             BEGIN
  4459.  
  4460.               S^[ (Z2*YMult)+Z ].Char := ODP^.CH;
  4461.  
  4462.             END; { For Z (x) }
  4463.  
  4464.           END; { For Z2 (y) }
  4465.  
  4466.         END; { With AS^ }
  4467.  
  4468.         CallNextDriver( ODP );
  4469.  
  4470.         If (ODP^.Status    = ODS_CantDo          ) and
  4471.            (ODP^.StatusMsg = ODS_MsgNoScreenBuff ) Then
  4472.         BEGIN
  4473.  
  4474.           SyncRegion( Pred(ODP^.X1), Pred(ODP^.Y1),
  4475.                       Pred(ODP^.X2), Pred(ODP^.Y2)  );
  4476.  
  4477.         END;
  4478.  
  4479.         CallNext := FALSE;
  4480.  
  4481.       END;  { ODF_RegionFillC }
  4482.  
  4483.      {----}
  4484.  
  4485.       ODF_RepeatChar:
  4486.       BEGIN
  4487.  
  4488.         With AS^ Do
  4489.         BEGIN
  4490.  
  4491.           IF (ODP^.CH<>#13) and (ODP^.CH<>#10) Then
  4492.           BEGIN
  4493.  
  4494.             For Z:=1 to ODP^.NumVal Do
  4495.             BEGIN
  4496.  
  4497.               S^[ (CurY*YMult)+CurX ].Char := ODP^.CH;
  4498.               S^[ (CurY*YMult)+CurX ].Attr := CurAttr;
  4499.  
  4500.               CursorNextChar( FALSE );
  4501.  
  4502.             END;  { For Z }
  4503.  
  4504.  
  4505.           END;  { If ODP^.Ch }
  4506.  
  4507.         END; { With AS^ }
  4508.  
  4509.       END;  { ODF_RepeatChar }
  4510.  
  4511.      {----}
  4512.  
  4513.       ODF_RepeatCharAt:
  4514.       BEGIN
  4515.  
  4516.         With AS^ DO
  4517.         BEGIN
  4518.  
  4519.           SaveCurX := CurX;
  4520.           SaveCurY := CurY;
  4521.  
  4522.           For Z:=1 to ODP^.NumVal Do
  4523.           BEGIN
  4524.  
  4525.             S^[ (Pred(ODP^.Y1)*YMult)+ODP^.X1+Z-2].Char := ODP^.CH;
  4526.  
  4527.             S^[ (Pred(ODP^.Y1)*YMult)+ODP^.X1+Z-2].Attr :=
  4528.                                                          ODP^.Attr;
  4529.                                             {CRTColorMap[ ODP^.Attr ];}
  4530.  
  4531.           END; { For Z }
  4532.  
  4533.         END; { With AS^ }
  4534.  
  4535.       END;  { ODF_RepeatCharAt }
  4536.  
  4537.      {----}
  4538.  
  4539.       ODF_GetScreenSize:
  4540.       BEGIN
  4541.  
  4542.         With AS^ Do
  4543.         BEGIN
  4544.  
  4545.           ODP^.X1 := IData^.Cols;
  4546.           ODP^.Y1 := Idata^.Rows;
  4547.  
  4548.         END;  { With AS^ }
  4549.  
  4550.       END;  { ODF_GetScreenSize }
  4551.  
  4552.      {----}
  4553.  
  4554.       ODF_RepeatBlock:
  4555.       BEGIN
  4556.  
  4557.         With AS^ DO
  4558.         BEGIN
  4559.  
  4560.           Z3 := ODP^.Start;
  4561.  
  4562.           For Z2:=1 to ODP^.NumVal Do
  4563.           BEGIN
  4564.  
  4565.             For Z:=Z3 to ODP^.Size Do
  4566.             BEGIN
  4567.  
  4568.               Case PCharBuff( ODP^.Buff)^[Z] Of
  4569.  
  4570.                 #13:
  4571.                 BEGIN
  4572.  
  4573.                   CurX := WinX1;
  4574.  
  4575.                   CursorDown( TRUE );
  4576.  
  4577.                 END;  { #13 }
  4578.  
  4579.                 #10: {do nothing, man} ;
  4580.  
  4581.               Else
  4582.  
  4583.                 S^[ (CurY*YMult)+CurX ].Char := PCharBuff( ODP^.Buff )^[Z];
  4584.                 S^[ (CurY*YMult)+CurX ].Attr := CurAttr;
  4585.  
  4586.                 CursorNextChar( TRUE );
  4587.  
  4588.               END;  { Case PCharBuff( ODP^.Buf)^[Z] }
  4589.  
  4590.             END; { For Z }
  4591.  
  4592.             Z3 := 1;
  4593.  
  4594.           END; { for Z2 }
  4595.  
  4596.         END; { With AS^ }
  4597.  
  4598.  
  4599.         { for each repeat }
  4600.  
  4601.         While ODP^.NumVal>0 Do
  4602.         BEGIN
  4603.  
  4604.           Repeat
  4605.             ODP^.Status := 0;
  4606.  
  4607.             CallNextDriver( ODP );
  4608.  
  4609.             If (ODP^.Status    = ODS_CantDo          ) and
  4610.                (ODP^.StatusMsg = ODS_MsgNeedScrollUp ) Then
  4611.               HelpNextGuyScrollUp;
  4612.  
  4613.           Until ODP^.Start=ODP^.Size;
  4614.  
  4615.           { Dec( ODP^.NumVal ); }
  4616.  
  4617.         END; { while }
  4618.  
  4619.         ODP^.Start := ODP^.Size;
  4620.  
  4621.         CallNext := FALSE;
  4622.  
  4623.       END;  { ODF_RepeatBlock }
  4624.  
  4625.      {----}
  4626.  
  4627.       ODF_RepeatBlockAt:
  4628.       BEGIN
  4629.  
  4630.         With AS^ DO
  4631.         BEGIN
  4632.  
  4633.           SaveCurX := CurX;
  4634.           SaveCurY := CurY;
  4635.  
  4636.           For Z:=1 to ODP^.NumVal Do
  4637.           BEGIN
  4638.  
  4639.             S^[ (Pred(ODP^.Y1)*YMult)+ODP^.X1+Z-2].Char := ODP^.CH;
  4640.  
  4641.             S^[ (Pred(ODP^.Y1)*YMult)+ODP^.X1+Z-2].Attr :=
  4642.                                                          ODP^.Attr;
  4643.                                             {CRTColorMap[ ODP^.Attr ];}
  4644.  
  4645.           END; { For Z }
  4646.  
  4647.         END; { With AS^ }
  4648.  
  4649.       END;  { ODF_RepeatCharAt }
  4650.  
  4651.  
  4652.      {----}
  4653.      {----}
  4654.  
  4655.     Else { Else Case }
  4656.  
  4657.     END;  { Case ODP^.Func }
  4658.  
  4659.   END; { If ODP^.Status = 0 }
  4660.  
  4661.   If CallNext Then
  4662.     CallNextDriver( ODP );
  4663.  
  4664. END;  { VirtScreenFilter }
  4665.  
  4666. {────────────────────────────────────────────────────────────────────────────}
  4667.  
  4668.  
  4669. Procedure VOutFillRegion(         Chan           : TChanHandle;
  4670.                                   X1             : WORD;
  4671.                                   Y1             : WORD;
  4672.                                   X2             : WORD;
  4673.                                   Y2             : WORD;
  4674.                                   Attr           : BYTE;
  4675.                                   Ch             : CHAR      );
  4676.  
  4677. BEGIN
  4678.  
  4679.   With Chan^ Do
  4680.   BEGIN
  4681.  
  4682.     ODP.Func   := ODF_RegionFill;
  4683.     ODP.X1     := X1;
  4684.     ODP.Y1     := Y1;
  4685.     ODP.X2     := X2;
  4686.     ODP.Y2     := Y2;
  4687.     ODP.Ch     := CH;
  4688.     ODP.Attr   := Attr;
  4689.  
  4690.     CallChannel( Chan, @ODP );
  4691.  
  4692.   END;  { With Chan^ }
  4693.  
  4694.  
  4695. END;
  4696.  
  4697. {────────────────────────────────────────────────────────────────────────────}
  4698.  
  4699.  
  4700. Procedure VOutFillRegionAttr(     Chan           : TChanHandle;
  4701.                                   X1             : WORD;
  4702.                                   Y1             : WORD;
  4703.                                   X2             : WORD;
  4704.                                   Y2             : WORD;
  4705.                                   Attr           : BYTE       );
  4706.  
  4707. BEGIN
  4708.  
  4709.   With Chan^ Do
  4710.   BEGIN
  4711.  
  4712.     ODP.Func   := ODF_RegionFillA;
  4713.     ODP.X1     := X1;
  4714.     ODP.Y1     := Y1;
  4715.     ODP.X2     := X2;
  4716.     ODP.Y2     := Y2;
  4717.     ODP.Attr   := Attr;
  4718.  
  4719.     CallChannel( Chan, @ODP );
  4720.  
  4721.   END;  { With Chan^ }
  4722.  
  4723. END;
  4724.  
  4725. {────────────────────────────────────────────────────────────────────────────}
  4726.  
  4727.  
  4728. Procedure VOutFillRegionChar(     Chan           : TChanHandle;
  4729.                                   X1             : WORD;
  4730.                                   Y1             : WORD;
  4731.                                   X2             : WORD;
  4732.                                   Y2             : WORD;
  4733.                                   Ch             : CHAR      );
  4734.  
  4735. BEGIN
  4736.  
  4737. BEGIN
  4738.  
  4739.   With Chan^ Do
  4740.   BEGIN
  4741.  
  4742.     ODP.Func   := ODF_RegionFillC;
  4743.     ODP.X1     := X1;
  4744.     ODP.Y1     := Y1;
  4745.     ODP.X2     := X2;
  4746.     ODP.Y2     := Y2;
  4747.     ODP.Ch     := CH;
  4748.  
  4749.     CallChannel( Chan, @ODP );
  4750.  
  4751.   END;  { With Chan^ }
  4752.  
  4753. END;  { VOutCursor         }
  4754.  
  4755. END;
  4756.  
  4757. {────────────────────────────────────────────────────────────────────────────}
  4758.  
  4759. Procedure VOutRepeatBlock(        Chan           : TChanHandle;
  4760.                                   RepeatCount    : WORD;
  4761.                                   Block          : Pointer;
  4762.                                   Size           : WORD      );
  4763.  
  4764.  
  4765. BEGIN
  4766.  
  4767.   With Chan^ Do
  4768.   BEGIN
  4769.  
  4770.     ODP.Func   := ODF_RepeatBlock;
  4771.     ODP.NumVal := RepeatCount;
  4772.     ODP.Start  := 1;
  4773.     ODP.Size   := Size;
  4774.     ODP.Buff   := Block;
  4775.  
  4776.     CallChannel( Chan, @ODP );
  4777.  
  4778.   END;  { With Chan^ }
  4779.  
  4780. END;
  4781.  
  4782. {────────────────────────────────────────────────────────────────────────────}
  4783.  
  4784. Procedure VOutRepeatString(       Chan           : TChanHandle;
  4785.                                   RepeatCount    : WORD;
  4786.                                   S              : STRING    );
  4787.  
  4788. BEGIN
  4789.  
  4790.   With Chan^ Do
  4791.   BEGIN
  4792.  
  4793.     ODP.Func   := ODF_RepeatBlock;
  4794.     ODP.NumVal := RepeatCount;
  4795.     ODP.Start  := 1;
  4796.     ODP.Size   := Byte(S[0]);
  4797.     ODP.Buff   := @S[1];
  4798.  
  4799.     CallChannel( Chan, @ODP );
  4800.  
  4801.   END;  { With Chan^ }
  4802.  
  4803.  
  4804. END;
  4805.  
  4806. {────────────────────────────────────────────────────────────────────────────}
  4807.  
  4808. Procedure VOutFlush(              Chan           : TChanHandle );
  4809.  
  4810. BEGIN
  4811.  
  4812.   With Chan^ Do
  4813.   BEGIN
  4814.  
  4815.     ODP.Func   := ODF_FlushBuffers;
  4816.  
  4817.     CallChannel( Chan, @ODP );
  4818.  
  4819.   END;  { With Chan^ }
  4820.  
  4821.  
  4822. END;
  4823.  
  4824. {────────────────────────────────────────────────────────────────────────────}
  4825. {────────────────────────────────────────────────────────────────────────────}
  4826. {────────────────────────────────────────────────────────────────────────────}
  4827.  
  4828. BEGIN
  4829.  
  4830.  
  4831. END.
  4832.  
  4833.  
  4834.