{***********************************************************************}
{									}
{ __ReadScn  Read a string from the screen				}
{									}
{ procedure __ReadScn(X,Y : byte; BufferPtr : Pointer;			}
{				    NoChars : word;			}
{				       Mode : byte);			}
{									}
{	      X,Y	Column and row position from where the string	}
{			is to be read.					}
{	      BufferPtr Pointer to buffer in which the characters	}
{			(and attributes) are to be placed.		}
{	      NoChars	The number of characters to be read.		}
{	      Mode	The mode value tells __ReadScn how the buffer	}
{			is constructed and where to position the cursor }
{			when the string has been read.	The four	}
{			possible values are:				}
{									}
{			Mode Value  Description 			}
{			----------  ----------------------------------- }
{			    0	    The cursor is not moved, and the	}
{				    buffer contains just characters.	}
{			    1	    The cursor is positioned after the	}
{				    last character read, and the	}
{				    buffer contains just characters.	}
{			    2	    The cursor is not moved, but the	}
{				    buffer is made up of character fol- }
{				    lowed by attribute bytes.		}
{			    3	    Like mode 2, but the cursor is	}
{				    positioned as in mode 1.		}
{									}
{ Description __ReadScn reads a string (and possibly attributes) from	}
{	      the current display page and places the results in a	}
{	      specified buffer.  It is the responsibility of the	}
{	      calling program to provide enough space within the buffer }
{	      whose address is passed to hold the returned data.	}
{	      For modes 2 and 3, the buffer will be formatted		}
{	      in the form char,attr,char,attr,.... (that is, like	}
{	      the _ScnPos type).  For modes 0 and 1, the buffer just	}
{	      contains characters, and the attributes on the screen	}
{	      are ignored. For modes 0 and 2 the cursor is not		}
{	      repositioned, but for modes 1 and 3 it is placed after	}
{	      the last character read.	If a pointer to a string is	}
{	      passed, the length byte is NOT altered, so it must be	}
{	      initialized in the calling program.			}
{									}
{	      If the end of the line is encountered, the next row will	}
{	      be read starting at column 1, and if the end of the	}
{	      screen is encountered as well, the characters starting	}
{	      at row 1 and column 1 are read.				}
{									}
{ Version     4.01 (C)Copyright Blaise Computing Inc.  1988		}
{_______________________________________________________________________}

procedure __ReadScn(X,Y : byte; BufferPtr : Pointer;
				  NoChars : word;
				     Mode : byte);

  type
    MemoryPtr = ^_MemoryChar;	       { Declared in Unit_Sup		}

  var
    Fore,Back	    : byte;
    DisplayCh	    : char;
    CursorOn	    : boolean;
    BufPtr	    : _ScnImagePtr absolute BufferPtr;
    StrPtr	    : MemoryPtr    absolute BufferPtr;
    X1,Y1,Top,Bot   : byte;
    I		    : word;

  begin {__ReadScn}

    CursorOn := __IsCurScn;
    if (CursorOn) then		       { If the cursor is on, then	}
       __COffScn(TRUE); 	       { turn it off.			}
    if (Mode > 4) then		       { If the mode is out of range,	}
       Mode := 0;		       { use the default value of zero. }

    __WhereScn(X1,Y1,Top,Bot);	       { Get current location.		}
    for I := 1 to NoChars do
      begin
	__GotoScn(X,Y);
	DisplayCh := __RCharScn(Fore,Back);
	if (Mode < 2) then
	   StrPtr^[I] := DisplayCh
	else
	   with BufPtr^[I] do
	     begin
	       _Ch   := DisplayCh;
	       _Attr := __2ByteSup(Back,Fore)
	     end;
	Inc(X);
	if (X > _CurColumns) then
	   begin
	     X := 1;		       { Move the first column, and	}
	     Inc(Y);		       { the next row. But, if at end	}
	     if (Y > _CurRows) then    { then wrap around to the top.	}
		Y := 1
	   end;
      end;

    if (not Odd(Mode)) then	       { Reposition the cursor	to the	}
       __GotoScn(X1,Y1);	       { original location.		}
    if (CursorOn) then		       { Turn the cursor back on, if it }
       __COffScn(FALSE) 	       { was originally.		}

  end;	{__ReadScn}
