Trailing-Edge
-
PDP-10 Archives
-
bb-r775d-bm_tops20_ks_upd_4
-
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