{***********************************************************************}
{									}
{ __StuffKey  Place characters in the keyboard buffer directly		}
{									}
{ function  __StuffKey(CharStr : String) : String			}
{									}
{	      CharStr	The character string to place in the keyboard	}
{			buffer.  The portion that cannot be put in the	}
{			buffer (for example, if it fills) is returned	}
{			as the functional value.			}
{									}
{ Description This function places the character string directly into	}
{	      the keyboard buffer.  If the buffer fills, the remaining	}
{	      characters are returned as the functional value.	The	}
{	      keyboard buffer is implemented as a circular queue of 16	}
{	      words (a character byte followed by the scan code).  Be-	}
{	      cause one location is required for overhead, the buffer	}
{	      can hold up to 15 characters and associated scan codes.	}
{	      The pointers to the head and tail of the queue are memory }
{	      locations immediately in front of the queue, and are up-	}
{	      dated as characters are placed into and removed from the	}
{	      keyboard buffer.						}
{									}
{	      For standard characters, __StuffKey just places the	}
{	      associated scan code retrieved from _KeyTable in the	}
{	      buffer.  If the character having ASCII code 255 is	}
{	      encountered in the input string, it is assumed that the	}
{	      next character represents the scan code of an extended	}
{	      key sequence.  In this case, __StuffKey places ASCII zero }
{	      in the character byte, and the ASCII code specified in	}
{	      the scan code byte.					}
{									}
{ Version     4.00 (C)Copyright Blaise Computing Inc.  1987		}
{_______________________________________________________________________}

function  __StuffKey(CharStr : string) : string;

  { PlaceKey  This function places a key stroke in the buffer, and if	}
  {	      successful returns TRUE, but if the buffer is full, re-	}
  {	      turns FALSE.						}

  function PlaceKey(KeyStroke : _KeySeq) : boolean;

    var
      NextPos	: integer;
      Index	: integer;
      KeyBuffer : _KeyBoard absolute _BIOSSEG:$001A;

    begin {PlaceKey}

      with KeyBuffer do
	begin
	  NextPos     := _BufferTail + 2;
	  if (NextPos > Ofs(_KbBuffer[16])) then  { We have wrap around }
	     NextPos  := Ofs(_KbBuffer[1]);
	  if (NextPos = _BufferHead) then	  { The buffer is full. }
	     PlaceKey := FALSE
	  else
	     begin				  { Put the sequence in }
	       Index := ((_BufferTail - $1E) div 2) + 1; { right here.	}
	       Inline($FA);			  { Disable interrupts	}
	       _KbBuffer[Index] := KeyStroke;
	       _BufferTail	:= NextPos;
	       Inline($FB);			  { Enable interrupts	}
	       PlaceKey := TRUE
	     end
	end

    end;  {PlaceKey}

  var
    I,J       : integer;
    LenStr    : integer;
    KeyStroke : _KeySeq;
    Stuffed   : boolean;

  begin  {__StuffKey}

    LenStr := Length(CharStr);
    if (LenStr = 0) then	       { Not much to do, so return	}
       begin
	 __StuffKey := CharStr;
	 Exit
       end;

    I := 0;			       { Can assume CharStr is not empty}
    repeat
      Inc(I);
      J := I;			       { Save character position in	}
      with KeyStroke do 	       { case it cannot be stuffed.	}
	if ((CharStr[I] = #255) and (LenStr > I)) then
	   begin		       { Extended key sequence		}
	     Inc(I);
	     if (CharStr[I] = #255) then
		begin		       { Just the character #255 after	}
		  _Ch	    := #255;   { all, and not an extended	}
		  _ScanCode := 0       { sequence.			}
		end
	     else
		begin
		  _Ch	    := #0;
		  _ScanCode := byte(CharStr[I])
		end
	   end
	else			       { Standard key sequence		}

	   { For a standard key sequence, if the character is an ASCII	}
	   { character with value less than 128, the scan code can be	}
	   { retrieved from _KeyTable (the first 128 entries are indexed}
	   { by ASCII code), otherwise the scan code is set to zero.	}

	   begin
	     _Ch := CharStr[I];
	     if (_Ch < #128) then
		_ScanCode := _KeyTable[_Keys(byte(_Ch))]._ScanCode
	     else
		_ScanCode := 0
	   end;
      Stuffed := PlaceKey(KeyStroke)
    until ((I = LenStr) or (not Stuffed));

    if (not Stuffed) then
       __StuffKey := Copy(CharStr,J,LenStr)
    else
       __StuffKey := ''

  end;	{__StuffKey}
