Trailing-Edge
-
PDP-10 Archives
-
CFS_TSU04_19910205_1of1
-
update/t20src/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) DIGITAL EQUIPMENT CORPORATION 1981, 1988. 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 THAT 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