Google
 

Trailing-Edge - PDP-10 Archives - bb-h138e-bm_tops20_v6_1_distr - 6-1-sources/chmeinput.bli
There are 11 other files named chmeinput.bli in the archive. Click here to see a list.
 %TITLE 'CHMEINPUT - read with echo if possible'
MODULE CHMEINPUT (				! Read with echo if possible
		IDENT = '3-003'			! File: CHMEINPUT.BLI Edit: CJG3003
		) =
BEGIN
!
!			  COPYRIGHT (c) 1981, 1985 BY
!	      DIGITAL EQUIPMENT CORPORATION, MAYNARD, MASS.
!		ALL RIGHTS RESERVED.
!
! THIS SOFTWARE IS FURNISHED UNDER A LICENSE AND MAY BE USED AND  COPIED
! ONLY  IN  ACCORDANCE  WITH  THE  TERMS  OF  SUCH  LICENSE AND WITH THE
! INCLUSION OF THE ABOVE COPYRIGHT NOTICE.  THIS SOFTWARE OR  ANY  OTHER
! COPIES  THEREOF MAY NOT BE PROVIDED OR OTHERWISE MADE AVAILABLE TO ANY
! OTHER PERSON.  NO TITLE TO AND OWNERSHIP OF  THE  SOFTWARE  IS  HEREBY
! TRANSFERRED.
!
! THE INFORMATION IN THIS SOFTWARE IS SUBJECT TO CHANGE  WITHOUT  NOTICE
! AND  SHOULD  NOT  BE  CONSTRUED  AS  A COMMITMENT BY DIGITAL EQUIPMENT
! CORPORATION.
!
! DIGITAL ASSUMES NO RESPONSIBILITY FOR THE USE OR  RELIABILITY  OF  ITS
! SOFTWARE ON EQUIPMENT WHICH IS NOT SUPPLIED BY DIGITAL.
!

!++
! FACILITY:	EDT -- The DEC Standard Editor
!
! ABSTRACT:
!
!	This module determines whether a special read can be performed
!	which leaves character echoing to the terminal driver, and does the
!	read if so.
!
! ENVIRONMENT:	Runs at any access mode - AST reentrant
!
! AUTHOR: Bob Kushlis, CREATION DATE: Unknown
!
! MODIFIED BY:
!
! 1-001	- Original.  DJS 04-Feb-1981.  This module was created by
!	extracting the routine EDT$$RD_ECHO  from module CHANGE.BLI.
! 1-002	- regularize headers.  JBS 27-Feb-1981
! 1-003	- Fix module name.  JBS 02-Mar-1981
! 1-004	- Revise journaling, and only do line reads if we can read at least
!	   four characters.  JBS 18-Jun-1981
! 1-005	- Prompt from the global string, if requested.  JBS 21-Oct-1981
! 1-006	- Remove length of prompt string.  JBS 23-Oct-1981
! 1-007	- Make the reads shorter to allow for the cursor positioning sequence.
!	   JBS 29-Jan-1982
! 1-008	- Don't make the lengths of the reads depend on the special prompt;
!	   otherwise the QA system has trouble.  JBS 29-Jan-1982
! 1-009	- Add JOU_VALID.  JBS 09-Apr-1982
! 1-010	- Worry about control C.  JBS 24-May-1982
! 1-011	- New screen update logic.  JBS 13-Sep-1982
! 1-012	- Include the EOL test routine, since it was only called from here.  JBS 22-Sep-1982
! 1-013	- Correct a misspelling in edit 1-012.  JBS 23-Sep-1982
! 1-014	- Add insert mode for VT102s.  JBS 27-Sep-1982
! 1-015	- Use a local text buffer, to avoid clobbering text if we are inserting.  JBS 27-Sep-1982
! 1-016	- Fix journaling of inserted text.  JBS 28-Sep-1982
! 1-017	- Remove EDT$$G_LN_NO for new screen update logic.  JBS 29-Sep-1982
! 1-018	- Keep EDT$$G_PRV_COL up to date.  JBS 05-Oct-1982
! 1-019	- Allow for fat characters to the right of the cursor.  JBS 06-Oct-1982
! 1-020	- Don't do optimized input if there is text on the message line.  JBS 06-Oct-1982
! 1-021 - Don't write out to the journal file here. STS 07-Oct-1982
! 1-022	- Fix call to EDT$$FMT_CHWID.  JBS 13-Oct-1982
! 1-023	- Don't send the CR and reposition the cursor unless the terminal
!	   driver needs it.  JBS 16-Oct-1982
! 1-024	- Handle some cases of DEL.  JBS 10-Nov-1982
! 1-025	- Don't redundently enter insert mode.  JBS 11-Nov-1982
! 1-026	- Take into account characters already read when allowing for end of line.  JBS 16-Nov-1982
! 1-027	- Take into account characters already read when positioning the cursor.  JBS 22-Nov-1982
! 1-028	- Don't forget that DEL also repositions the cursor.  JBS 24-Nov-1982
! 1-029	- Don't forget to journal the DEL.  Also, repaint the line if NOTRUNCATE.  JBS 25-Nov-1982
! 1-030	- Journal the correct text after DEL.  JBS 25-Nov-1982
! 1-031	- Change the call to EDT$$TST_KEYDEF.  JBS 14-Dec-1982
! 1-032	- Remove EDT$$G_SHF.  JBS 14-Dec-1982
! 1-033	- Don't do it at the front of any line, even a continuation line.  JBS 20-Dec-1982
! 1-034	- Change the call to EDT$$MRK_LNCHG.  JBS 27-Dec-1982
! 1-035	- Maintain EDT$$G_CS_OLDCHNO.  JBS 27-Dec-1982
! 1-036	- If the screen is shifted don't do it.  JBS 29-Dec-1982
! 1-037	- Start on improving quality by going closer to the right margin before quitting.  JBS 14-Jan-1982
! 1-038	- Never read more than 70 characters at a time.  JBS 08-Feb-1983
! 1-039	- Read closer to the right margin.  JBS 09-Feb-1983
! 3-001 - Fix for TOPS-20 operation. GB 8-Jun-1983
! 3-002 - Modify to use EDT$$TI_BUFSTR for journalling. CJG 15-Jun-1983
! 3-003 - Modify ASSERT macro to include error code. CJG 30-Jan-1984
!--

%SBTTL 'Declarations'
!
! TABLE OF CONTENTS:
!

REQUIRE 'EDTSRC:TRAROUNAM';

FORWARD ROUTINE
    EDT$$RD_ECHO;				! Try to optimize terminal input

!
! INCLUDE FILES:
!

REQUIRE 'EDTSRC:EDTREQ';

!
! MACROS:
!
!	NONE
!
! EQUATED SYMBOLS:
!
LITERAL
    CHAR_LIMIT_1 = 2,			! Do optimized input even if only this many characters can be read
    CHAR_LIMIT_2 = 1;			! Read this many chars less than we can
!
! OWN STORAGE:
!
!	NONE
!
! EXTERNAL REFERENCES:
!
!	In the routine
%SBTTL 'EDT$$RD_ECHO  - read with echo if possible'

GLOBAL ROUTINE EDT$$RD_ECHO 			! Read with echo if possible
    =

!++
! FUNCTIONAL DESCRIPTION:
!
!	This routine determines whether or not an optimization for terminal
!	input can be done.  If we are currently positioned at the end of a line,
!	or if the terminal has the VT102 "insert character mode" feature,
!	then it is possible to let the terminal driver do the echoing of printable
!	characters for us up to the input of a character which may be a definable
!	key, or to near the end of the line, where even a non-definable key needs
!	special handling, such as wrap or display of a diamond.  This is much more
!	efficient than the single character input with no echo which is normally donem
!
!	This routine checks a whole series of conditions which must be met before
!	optimized input is possible, then comes up with the number of
!	characters which can be read with echo.  If this is large enough then a special
!	read routine is called to do the input.  If the input is terminated by an
!	escape or control character, that character will be put in the type-ahead
!	character, so it will be the next character returned by EDT$$TI_INPCH.
!
! FORMAL PARAMETERS:
!
!	NONE
!
! IMPLICIT INPUTS:
!
!	CUR_COL
!	CS_LNO
!	SEL_BUF
!	SHF
!	KPAD
!	RCOV_MOD
!	CUR_BUF
!	TI_WID
!	WD_WRAP
!	LN_BUF
!	LN_PTR
!	LN_END
!	WK_LN
!	PRV_COL
!	PMT_KPD
!	MSGFLG
!	TI_DUMB
!	RD_AHED
!	RD_AHEDBF
!	TRUN
!	CSR_SCRPTR
!
! IMPLICIT OUTPUTS:
!
!	LN_PTR
!	PRV_COL
!	LN_CHGD
!	JOU_VALID
!	CC_DONE
!	RD_AHED
!	VERT
!	T_DEL_CH
!	DEL_CHLEN
!	CS_OLDCHNO
!
! ROUTINE VALUE:
!
!	0 = read with echo not possible, 1 = read with echo done.
!
! SIDE EFFECTS:
!
!	NONE
!
!--

    BEGIN

    EXTERNAL ROUTINE
	EDT$$CHK_CC,				! Test for a control C
	EDT$$FMT_LIT : NOVALUE,			! Format a literal string
	EDT$$TI_RDSTR : NOVALUE,		! Read with echo
	EDT$$TI_BUFCH : NOVALUE,		! Put characters in the journal buffer
	EDT$$TI_BUFSTR : NOVALUE,		! Put a string in the journal file
	EDT$$UPD_LNLEN : NOVALUE,		! Update the length of the current line
	EDT$$SC_POSCSIF : NOVALUE,		! Position the cursor if necessary
	EDT$$SC_NONREVID : NOVALUE,		! End reverse video
	EDT$$SC_REVID : NOVALUE,		! Start reverse video
	EDT$$SEL_RNGPOS,			! Compare the select line with the current line
	EDT$$FMT_CHWID,				! Compute the width of a character
	EDT$$TST_KEYDEF,			! Test a key for a given definition
	EDT$$SC_ERATOEOL : NOVALUE,		! Erase to end of line
	EDT$$MRK_LNCHG : NOVALUE;		! Mark a line as having changed

    EXTERNAL
	CUR_COL,				! current column
	LN_CHGD,				! Indicates current line has changed.
	CS_LNO,					! cursor line.
	SEL_BUF,				! Pointer to select buffer.
	VERT,					! Last entity was VERT flag.
	KPAD,					! Keypad activated?
	RCOV_MOD,				! In recovery mode?
	CUR_BUF : REF TBCB_BLOCK,		! The current buffer tbcb
	TI_WID,					! Width of terminal line
	WD_WRAP,				! Word wrap
	LN_BUF,					! Current line buffer
	LN_PTR : REF VECTOR,			! Current character pointer
	LN_END,					! Pointer to end of current line
	PRV_COL,				! Previous column number
	PMT_KPD : VECTOR,			! Counted ASCII string for keypad prompt
	JOU_VALID,				! The journal record is valid
	CC_DONE,				! Control C actually aborted something
	WK_LN,					! The curent work line
	EOB_LN,					! The specal line that marks end of buffer
	TI_EDIT,				! 1= This terminal has insert character mode
	MSGFLG,					! 1 = There is text on the message line
	TI_DUMB,				! 1 = Trminal driver needs CR to avoid wrapping lines
	RDAHED,					! Number of chars in read ahead buffer
	RDAHEDBF,				! The read-ahead buffer
	DEL_CH,					! Deleted character buffer.
	DEL_CHLEN,				! Length of deleted character buffer
	TRUN,					! 0 = NOTRUNCATE mode
	CSR_SCRPTR : REF SCREEN_LINE,		! Pointer to current screen info for current line
	CS_OLDCHNO,				! Old character position on the line
	SHF;					! Screen shift amount
	
    LOCAL
	CPTR,
	BUF_LEFT,
	NUM_CHARS,
	COUNT,
	NUM_READ,
	READ,
	READ_DONE,
	TERMINATOR_PROCESSED,
	INS_MODE,
	TEXT_BUF : BLOCK [CH$ALLOCATION (132, BYTE_SIZE)];


!+
! We can only do this in keypad mode.
!-

    IF ( NOT .KPAD) THEN RETURN (0);

!+
! If we are on a continuation line don't do it.
!-

    IF (.CSR_SCRPTR EQLA 0) THEN RETURN (0);

    IF (.CSR_SCRPTR [SCR_CHR_FROM] NEQ 0) THEN RETURN (0);

!+
! If we are at the left margin don't do it.
!-

    IF (.CSR_SCRPTR [SCR_CHR_FROM] EQL CH$DIFF (.LN_PTR, CH$PTR (LN_BUF,, BYTE_SIZE)))
	 THEN RETURN (0);

!+
! If in recovery mode don't do it.
!-

    IF .RCOV_MOD THEN RETURN (0);

!+
! If at end of buffer don't do it.
!-

    IF (.WK_LN EQLA EOB_LN) THEN RETURN (0);

!+
! If there is text on the message line don't do it, since we want
! to erase the text at the next keystroke.  After that keystroke
! the message line will be erased and we will come back here to
! check again for optimized input.
!-

    IF (.MSGFLG) THEN RETURN (0);

!+
! If the screen is shifted don't do it.
!-

    IF (.SHF NEQ 0) THEN RETURN (0);

!+
! If this terminal has editing features don't do it if there is
! a tab to the right of the cursor.  If this terminal does not
! have editing features, don't do it if there is anything to the
! right of the cursor.
!-

    IF .TI_EDIT
    THEN
	BEGIN

	IF ( NOT CH$FAIL (CH$FIND_CH (CH$DIFF (.LN_END, .LN_PTR), .LN_PTR, ASC_K_TAB)))
	THEN
	    RETURN (0);

	END
    ELSE

	IF (CH$DIFF (.LN_END, .LN_PTR) NEQ 0) THEN RETURN (0);

!+
! Finally, it looks possible.  Keep doing it as long as we can.
!-
    READ_DONE = 0;
    READ = 0;
    INS_MODE = 0;

    DO
	BEGIN
	TERMINATOR_PROCESSED = 0;
!+
! Compute the number of characters left on the line.
!-
	NUM_CHARS = .TI_WID - 1;

!+
! If we are in wrap mode, make sure we get control at the wrap column.
!-

	IF (.WD_WRAP LSS .NUM_CHARS) THEN NUM_CHARS = .WD_WRAP;

!+
! Subtract the current cursor position.
!-
	NUM_CHARS = .NUM_CHARS - .CUR_COL - .READ;
!+
! Subtract the width of the characters to the right of the cursor.  Note that
! unless we are on a terminal with screen editing features this will always
! be zero.  Note also that there can be no HTs to the right of the cursor,
! so the widths of the characters are independent of their position on the line.
! Hence the second parameter to EDT$$FMT_CHWID will not be used.
!-

	CPTR = .LN_PTR;
	DECR COUNT FROM CH$DIFF (.LN_END, .LN_PTR) TO 0 DO
	    NUM_CHARS = .NUM_CHARS - EDT$$FMT_CHWID (CH$RCHAR_A (CPTR), 0);

!+
! Make sure there is enough room left in the line buffer.
!-
	BUF_LEFT = 255 - CH$DIFF (.LN_PTR, CH$PTR (LN_BUF,, BYTE_SIZE));

	IF (.BUF_LEFT LSS .NUM_CHARS) THEN NUM_CHARS = .BUF_LEFT;

!+
! Don't try to read more than the space we have in our local bufferg
!-

	IF ((.NUM_CHARS + .READ) GTR 132) THEN NUM_CHARS = 132 - .READ;

!+
! Now, if we have a reasonable size, we can read with echo.
!-

	IF (.NUM_CHARS GTR CHAR_LIMIT_1)
	THEN
	    BEGIN
!+
! We will do a read with echo.  Make sure the video attributes are right.
!-

	    IF (.SEL_BUF EQL .CUR_BUF)
	    THEN
		BEGIN

		IF (EDT$$SEL_RNGPOS () LEQ 0) THEN EDT$$SC_REVID () ELSE EDT$$SC_NONREVID ()

		END
	    ELSE
		EDT$$SC_NONREVID ();

!+
! If we are not at the end of the line, put the terminal in insert mode.  This
! can only be done on terminals that have the 'edit' feature.
!-

	    IF ((CH$DIFF (.LN_END, .LN_PTR) NEQ 0) AND ( NOT .INS_MODE))
	    THEN
		BEGIN
		ASSERT (5, .TI_EDIT);
		EDT$$FMT_LIT (CH$PTR (UPLIT (%STRING (%CHAR (ASC_K_ESC), '[4h'))), 4);
		INS_MODE = 1;
		END;

!+
! Put out a carriage return to make the terminal driver think we are at the
! beginning of a line, then reposition the cursor.  This is needed only for
! some terminal drivers, that lose track of the cursor and output a CRLF
! if they think that the user is about to type to the right of the screen.
!-

	    IF .TI_DUMB
	    THEN
		BEGIN
		EDT$$FMT_LIT (CH$PTR (UPLIT (%STRING (%CHAR (ASC_K_CR)))), 1);
		PRV_COL = 0;
		END;

!+
! Make sure the cursor is positioned correctly.
!-
	    EDT$$SC_POSCSIF (.CS_LNO, .CUR_COL + .READ);
!+
! Do the special read with echo.  Optionally prompt.  Since the terminal driver may
! count the length of the prompt, it must be short enough that our "worst case" estimate
! of 10 characters in the repositioning allows for it.  Don't read more than 70 characters
! at a time.
!-

	    IF (.PMT_KPD [0] GTR 0)
	    THEN
		EDT$$FMT_LIT (CH$PTR (PMT_KPD [1],, BYTE_SIZE), .PMT_KPD [0]);

	    EDT$$TI_RDSTR (CH$PTR (TEXT_BUF ,.READ, BYTE_SIZE),
		 MIN (70, .NUM_CHARS - CHAR_LIMIT_2), NUM_READ);
	    PRV_COL = .PRV_COL + .NUM_READ;
	    READ_DONE = 1;
	    END
	ELSE
	    NUM_READ = 0;
!+
! Cause the characters to appear in the next journal record.
!-

	CPTR = CH$PTR (TEXT_BUF, .READ, BYTE_SIZE);
	EDT$$TI_BUFSTR (.CPTR, .NUM_READ);

	JOU_VALID = 1;
	READ = .READ + .NUM_READ;
!+
! If the line was terminated by a control C bail out.  If any characters were
! read the insert is aborted; otherwise the control C is effectively ignored.
!-

	IF EDT$$CHK_CC ()
	THEN
	    BEGIN

	    IF (.READ GTR 0) THEN CC_DONE = 1;

!+
! If we have put the terminal in insert mode, take it out.
!-

	    IF .INS_MODE
	    THEN
		BEGIN
		ASSERT (5, .TI_EDIT);
		EDT$$FMT_LIT (CH$PTR (UPLIT (%STRING (%CHAR (ASC_K_ESC), '[4l'))), 4);
		INS_MODE = 0;
		END;

	    RETURN (0);
	    END;

!+
! If there is a single terminator, and if it is defined to delete
! the last character, shorten the string by one and do another read.
!-

	IF ((.RDAHED EQL 1) AND 		!
	    EDT$$TST_KEYDEF (CH$RCHAR (CH$PTR (RDAHEDBF,, BYTE_SIZE)),
		 UPLIT (%STRING ('D-C.')), 4, 0) AND (.READ GEQ 1))
	THEN
	    BEGIN
!+
! Make sure the delete character appears in the journal.
!-
	    EDT$$TI_BUFCH (CH$RCHAR (CH$PTR (RDAHEDBF,, BYTE_SIZE)));
	    READ = .READ - 1;
	    EDT$$SC_POSCSIF (.CS_LNO, .PRV_COL - 1);

	    IF .INS_MODE
	    THEN
		BEGIN
!+
! We must delete exactly one character.
!-
		EDT$$FMT_LIT (CH$PTR (UPLIT (%STRING (%CHAR (ASC_K_ESC), '[P'))), 3);
		END
	    ELSE
		BEGIN
!+
! We are just before the character to delete, and there are no visible characters after
! the character to delete.  We can erase to end of line.
!-
		EDT$$SC_ERATOEOL ();
		END;

!+
! Store the character deleted in the delete character buffer.
!-
	    DEL_CHLEN = 1;
	    CPTR = CH$PTR (DEL_CH,, BYTE_SIZE);
	    CH$WCHAR_A (DIR_BACKWARD, CPTR);
	    CH$WCHAR (CH$RCHAR (CH$PTR (TEXT_BUF, .READ, BYTE_SIZE)), CPTR);
	    RDAHED = 0;
	    VERT = 0;
	    TERMINATOR_PROCESSED = 1;
	    END;

!+
! Keep reading if we processed the terminator.
!-
	END
    UNTIL ( NOT .TERMINATOR_PROCESSED);

!+
! Insert the characters read into the line.
!-
    EDT$$CPY_STR (CH$DIFF (.LN_END, .LN_PTR), .LN_PTR, CH$PLUS (.LN_PTR, .READ));
    EDT$$CPY_STR (.READ, CH$PTR (TEXT_BUF,, BYTE_SIZE), .LN_PTR);

!+
! Add the number of characters read to the line size.
!-
    EDT$$UPD_LNLEN (.READ);
!+
! If we actually read some characters update the cursor position.
!-

    IF (.READ NEQ 0)
    THEN
	BEGIN
	CUR_COL = .CUR_COL + .READ;
	VERT = 0;
!+
! Note that the line is not marked as changed for the screen
! updater, since the modification to the screen has already
! been made.  However, we must note for the work file system
! that the current line has been changed.
!-
	LN_CHGD = 1;
	END;

!+
! Update the current character pointer.
!-
    LN_PTR = CH$PLUS (.LN_PTR, .READ);
    CS_OLDCHNO = .CS_OLDCHNO + .READ;
!+
! If we have put the terminal in insert mode, take it out.
!-

    IF .INS_MODE
    THEN
	BEGIN
	ASSERT (5, .TI_EDIT);
	EDT$$FMT_LIT (CH$PTR (UPLIT (%STRING (%CHAR (ASC_K_ESC), '[4l'))), 4);
	INS_MODE = 0;
	END;

    RETURN (.READ_DONE);
    END;					! of routine EDT$$RD_ECHO

END						! of module CHMEINPUT

ELUDOM