Trailing-Edge
-
PDP-10 Archives
-
bb-r775d-bm_tops20_ks_upd_4
-
sources/scrrlin.bli
There are 10 other files named scrrlin.bli in the archive. Click here to see a list.
%TITLE 'SCRRLIN - refresh a screen line'
MODULE SCRRLIN ( ! Refresh a screen line
IDENT = '3-003' ! File: SCRRLIN.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 refreshes a single line on the screen.
!
! ENVIRONMENT: Runs at any access mode - AST reentrant
!
! AUTHOR: Bob Kushlis, CREATION DATE: September 8, 1979
!
! MODIFIED BY:
!
! 1-001 - Original. DJS 12-Feb-1981. This module was created by
! extracting the routine EDT$$SC_RFRELN from module SCREEN.
! 1-002 - Regularize headers. JBS 13-Mar-1981
! 1-003 - Change [EOB] to user defined string STS 06-Oct-1981
! 1-004 - Do an absolute cursor position before writing the blob at
! end of line, to avoid running off the edge of the screen.
! Also, show the blob only if the text exceeds the screen
! width. JBS 02-Apr-1982
! 1-005 - Show characters all the way to end edge of the screen. JBS 06-Apr-1982
! 1-006 - Worry about wide characters at the edge of the screen. JBS 15-Apr-1982
! 1-007 - Continue work on edit 1-006. JBS 16-Apr-1982
! 1-008 - Always show [EOB] (or whatever text it has been set to) in non-reverse
! video. JBS 16-Apr-1982
! 1-009 - Make the edge of the screen logic work on a VT100, which clears its
! wrap flag only when a character is printed. JBS 19-Apr-1982
! 1-010 - Don't erase the message lines if an error occurs during select.
! SMB 01-Jul-1982
! 1-011 - Fix bug introduced by edit 1-010. SMB 20-Jul-1982
! 1-012 - Add check for message flag to erasure of screen. SMB 23-Jul-1982
! 1-013 - Change the flag checked in edit 1-012. SMB 28-Jul-1982
! 1-014 - Go back to edit 1-012. SMB 17-Aug-1982
! 1-015 - Modify fo the new screen updater. SMB 24-Sep-1982
! 1-016 - Simplify for the new screen update logic. This version always repaints
! any changed line. JBS 30-Sep-1982
! 1-017 - Remove unused external declaration of EDT$$FMT_LIT. JBS 05-Oct-1982
! 1-018 - Fix painting of select range. JBS 08-Oct-1982
! 1-019 - Put call to fsetcol in line. STS 11-Oct-1982
! 1-020 - Start work on NOTRUNCATE mode. JBS 11-Oct-1982
! 1-021 - Debug NOTRUNCATE mode. JBS 12-Oct-1982
! 1-022 - Fix the call to EDT$$FMT_CHWID. JBS 13-Oct-1982
! 1-023 - Add the second argument. JBS 23-Oct-1982
! 1-024 - Use SCR_EDIT_MINPOS. JBS 28-Oct-1982
! 1-025 - Be sure to print at least one character before the last character
! of a line, so we won't be hit by the VT100's autowrap. JBS 10-Nov-1982
! 1-026 - Set the final MINPOS to CHR_TO, so CHMEINPUT's text won't have to be rewritten. JBS 02-Dec-1982
! 1-027 - Change the handling of SHF. JBS 14-Dec-1982
! 1-028 - Maintain and use SCR_EDIT_MAXPOS. JBS 27-Dec-1982
! 1-029 - Don't erase to end of line if we do not repaint the whole line. JBS 27-Dec-1982
! 1-030 - Put the most common cases of character formatting in-line, to improve speed. JBS 04-Jan-1983
! 3-002 - Speed up the code which writes characters. CJG 6-Jan-1984
! 3-003 - Fix a problem with the edge of the screen. CJG 9-Jan-1984
!--
%SBTTL 'Declarations'
!
! TABLE OF CONTENTS:
!
REQUIRE 'EDTSRC:TRAROUNAM';
FORWARD ROUTINE
EDT$$SC_RFRELN : NOVALUE;
!
! INCLUDE FILES:
!
REQUIRE 'EDTSRC:EDTREQ';
!
! MACROS:
!
! NONE
!
! EQUATED SYMBOLS:
!
! NONE
!
! OWN STORAGE:
!
! NONE
!
! EXTERNAL REFERENCES:
!
! In the routine
%SBTTL 'EDT$$SC_RFRELN - refresh a line on the screen'
GLOBAL ROUTINE EDT$$SC_RFRELN ( ! Refresh a line on the screen
SCRPTR, ! address of line info being refreshed
ERASED ! 1 = line has been erased
) : NOVALUE =
!++
! FUNCTIONAL DESCRIPTION:
!
! This routine refreshes a single line on the screen. It expects CS_LNO
! to be the screen line number to be refreshed. This routine operates only on
! the specified line; it does not clear the screen after an [EOB], for example.
!
! FORMAL PARAMETERS:
!
! SCRPTR Pointer to the screen block for the line being refreshed
!
! ERASED 1 = the line has already been erased
!
! IMPLICIT INPUTS:
!
! CS_LNO
! SEL_BUF
! SHF
! TI_WID
! WK_LN
! FMT_LNPOS
! CUR_TBCB
! EOB_SCRPTR
! FMT_CUR
! FMT_FREE
! PRV_COL
! FMT_BUF
!
! IMPLICIT OUTPUTS:
!
! FMT_CUR
! FMT_FREE
! PRV_COL
!
! ROUTINE VALUE:
!
! NONE
!
! SIDE EFFECTS:
!
! Writes on the screen.
!
!--
BEGIN
EXTERNAL ROUTINE
EDT$$FMT_CH : NOVALUE, ! Output a character
EDT$$FMT_CHWID, ! Compute the width of a character
EDT$$SC_SHWBLOB : NOVALUE, ! Output a blob
EDT$$SC_REVIDCHK : NOVALUE, ! Check for reverse video based on select region
EDT$$SC_NONREVID : NOVALUE, ! Go to normal video
EDT$$SC_POSCSIF : NOVALUE, ! Position the cursor
EDT$$SC_ERATOEOL : NOVALUE, ! Erase to end of line
EDT$$SC_ERAALL : NOVALUE, ! Erase to end of screen
EDT$$FMT_TEXT : NOVALUE, ! Print [EOB]
EDT$$OUT_FMTBUF; ! Output the format buffer
EXTERNAL
EOB_SCRPTR : REF SCREEN_LINE, ! Special line block for [EOB]
CS_LNO, ! current screen line
SEL_BUF, ! select buffer.
SHF, ! The number of columns shifted.
TI_WID, ! Width of terminal line.
WK_LN : REF LIN_BLOCK, ! Current line pointer.
FMT_LNPOS, ! Current column number
CUR_BUF : REF TBCB_BLOCK, ! Pointer to current text control block
FMT_CUR, ! Pointer to next char in output buffer
FMT_FREE, ! Space left in format buffer
FMT_BUF : BLOCK [CH$ALLOCATION (FMT_BUFLEN)], ! Output buffer
PRV_COL; ! The cursor column number
MAP
SCRPTR : REF SCREEN_LINE;
LOCAL
NUMC,
TXTPTR,
LEN,
CHAR,
CHAR_WIDTH,
LEFT,
FIRST_CHAR,
WIDTH,
SIMPLE_CHAR,
MAXPOS;
!+
! Check for EOB.
!-
IF (.SCRPTR EQLA .EOB_SCRPTR)
THEN
BEGIN
EDT$$SC_POSCSIF (.CS_LNO, 0);
EDT$$SC_NONREVID ();
EDT$$FMT_TEXT (0);
IF ( NOT .ERASED) THEN EDT$$SC_ERATOEOL ();
!+
! Mark the line as finished with its edit.
!-
SCRPTR [SCR_EDIT_MINPOS] = 255;
SCRPTR [SCR_EDIT_MAXPOS] = 0;
SCRPTR [SCR_EDIT_FLAGS] = .SCRPTR [SCR_EDIT_FLAGS] AND ( NOT (SCR_EDIT_MODIFY OR SCR_EDIT_INSLN));
RETURN;
END;
!+
! Not EOB. Position to the first character to be updated in the line,
! keeping track of the screen column which it will occupy.
!-
WIDTH = .TI_WID + .SHF;
LEFT = .SCRPTR [SCR_CHR_FROM];
LEN = MIN (.SCRPTR [SCR_CHR_TO] + 1, .WK_LN [LIN_LENGTH]) - .LEFT;
TXTPTR = CH$PTR (WK_LN [LIN_TEXT], .LEFT, BYTE_SIZE);
FMT_LNPOS = 0;
CHAR = CH$RCHAR_A (TXTPTR);
NUMC = 1;
IF ((.CHAR GEQ %X'20') AND (.CHAR LEQ %X'7E'))
THEN
BEGIN
CHAR_WIDTH = 1;
SIMPLE_CHAR = 1;
END
ELSE
BEGIN
CHAR_WIDTH = EDT$$FMT_CHWID (.CHAR, .FMT_LNPOS);
SIMPLE_CHAR = 0;
END;
!+
! Skip over unmodified characters on this line.
!-
WHILE ((.NUMC LEQ .SCRPTR [SCR_EDIT_MINPOS]) AND (.LEN GTR 0)
AND (.FMT_LNPOS LSS (.WIDTH - .CHAR_WIDTH - 1))) DO
BEGIN
!+
! Account for the blob at the front of continued lines.
!-
IF ((.FMT_LNPOS EQL 0) AND (.SCRPTR [SCR_LINE_IDX] NEQ 0))
THEN
FMT_LNPOS = .SHF + 2;
FMT_LNPOS = .FMT_LNPOS + .CHAR_WIDTH;
LEN = .LEN - 1;
CHAR = CH$RCHAR_A (TXTPTR);
NUMC = .NUMC + 1;
IF ((.CHAR GEQ %X'20') AND (.CHAR LEQ %X'7E'))
THEN
BEGIN
CHAR_WIDTH = 1;
SIMPLE_CHAR = 1;
END
ELSE
BEGIN
CHAR_WIDTH = EDT$$FMT_CHWID (.CHAR, .FMT_LNPOS);
SIMPLE_CHAR = 0;
END;
END;
!+
! Put the characters into the format buffer.
!-
FIRST_CHAR = 1;
!+
! If this is a continued line, indicate this at the front of the line.
!-
IF ((.SCRPTR [SCR_LINE_IDX] NEQ 0) AND (.FMT_LNPOS EQL 0))
THEN
BEGIN
FMT_LNPOS = .SHF;
EDT$$SC_POSCSIF (.CS_LNO, .FMT_LNPOS - .SHF);
FIRST_CHAR = 0;
EDT$$SC_SHWBLOB ();
EDT$$FMT_CH (%C' ');
END;
!+
! Preset some values here to speed up the loop below.
!-
MAXPOS = .SCRPTR [SCR_EDIT_MAXPOS];
!+
! This is the loop that actually puts characters into the format buffer for output to the screen.
! The time around this loop is critical to EDT's performance in screen mode.
!-
WHILE ((.LEN GTR 0) AND (.FMT_LNPOS LSS (.WIDTH - .CHAR_WIDTH))
AND ((.NUMC - 1) LEQ .MAXPOS)) DO
BEGIN
IF (.SEL_BUF EQL .CUR_BUF) !
THEN
EDT$$SC_REVIDCHK (CH$DIFF (.TXTPTR, CH$PTR (WK_LN [LIN_TEXT], 0, BYTE_SIZE)) - 1);
IF (.FMT_LNPOS GEQ .SHF)
THEN
BEGIN
IF .FIRST_CHAR
THEN
BEGIN
EDT$$SC_POSCSIF (.CS_LNO, .FMT_LNPOS - .SHF);
FIRST_CHAR = 0;
END;
!+
! Put the character in the format buffer.
! Do simple characters in-line; call EDT$$FMT_CH for complex characters.
!-
IF .SIMPLE_CHAR
THEN
BEGIN
FMT_LNPOS = .FMT_LNPOS + 1;
IF (.FMT_FREE EQL 0)
THEN
BEGIN
!+
! We have reached the end of the buffer; empty it.
!-
LOCAL
SAV_LNPOS;
SAV_LNPOS = .FMT_LNPOS;
EDT$$OUT_FMTBUF ();
FMT_LNPOS = .SAV_LNPOS;
END;
CH$WCHAR_A (.CHAR, FMT_CUR);
FMT_FREE = .FMT_FREE - 1;
PRV_COL = .PRV_COL + 1;
END
ELSE
EDT$$FMT_CH (.CHAR);
END
ELSE
FMT_LNPOS = .FMT_LNPOS + .CHAR_WIDTH;
LEN = .LEN - 1;
NUMC = .NUMC + 1;
CHAR = CH$RCHAR_A (TXTPTR);
IF ((.CHAR GEQ %X'20') AND (.CHAR LEQ %X'7E'))
THEN
BEGIN
CHAR_WIDTH = 1;
SIMPLE_CHAR = 1;
END
ELSE
BEGIN
CHAR_WIDTH = EDT$$FMT_CHWID (.CHAR, .FMT_LNPOS);
SIMPLE_CHAR = 0;
END;
END;
!+
! If we have not finished the line, it may be because the line won't fit on the screen.
! Since the loop above stops one column short of the right edge of the screen, there
! may be just room for one more character; if so, put it out. If not, put a blob in the
! last column.
!-
IF ((.LEN GTR 0) AND ((.NUMC - 1) LEQ .MAXPOS))
THEN
BEGIN
IF ((.LEN EQL 1) AND (.FMT_LNPOS EQL (.WIDTH - .CHAR_WIDTH)) AND !
(.FMT_LNPOS GEQ .SHF))
THEN
BEGIN
IF (.SEL_BUF EQL .CUR_BUF) !
THEN
EDT$$SC_REVIDCHK (CH$DIFF (.TXTPTR, CH$PTR (WK_LN [LIN_TEXT], 0, BYTE_SIZE)) - 1);
IF .FIRST_CHAR
THEN
BEGIN
EDT$$SC_POSCSIF (.CS_LNO, .FMT_LNPOS - .SHF);
FIRST_CHAR = 0;
END;
EDT$$FMT_CH (.CHAR);
LEN = .LEN - 1;
END
ELSE
BEGIN
IF (( NOT .ERASED) AND (.SCRPTR [SCR_EDIT_MAXPOS] EQL 255))
THEN
BEGIN
EDT$$SC_POSCSIF (.CS_LNO, MAX (0, .FMT_LNPOS - .SHF));
EDT$$SC_ERATOEOL ();
END;
!+
! If there is room left on the line, it may be that we have printed no characters.
! Therefore, print a space to be sure that the VT100's autowrap flag is not set.
!-
IF (.FMT_LNPOS LSS (.TI_WID - 1)) THEN EDT$$FMT_CH (%C' ');
EDT$$SC_POSCSIF (.CS_LNO, .TI_WID - 1);
EDT$$SC_SHWBLOB ();
END;
END
!+
! Throw in an erase to end of line sequence if we have painted as close as we can to the right margin.
! Suppress the sequence if we have just put a character at the right margin or if the line is already erased.
!-
ELSE
IF (( NOT .ERASED) AND (.SCRPTR [SCR_EDIT_MAXPOS] EQL 255))
THEN
BEGIN
IF .FIRST_CHAR THEN EDT$$SC_POSCSIF (.CS_LNO, MAX (0, .FMT_LNPOS - .SHF));
EDT$$SC_ERATOEOL ();
END;
!+
! Mark the line as finished with its edit.
!-
SCRPTR [SCR_EDIT_MINPOS] = MIN (.SCRPTR [SCR_CHR_TO] - .SCRPTR [SCR_CHR_FROM] + 1, 255);
SCRPTR [SCR_EDIT_MAXPOS] = 0;
SCRPTR [SCR_EDIT_FLAGS] = .SCRPTR [SCR_EDIT_FLAGS] AND ( NOT (SCR_EDIT_MODIFY OR SCR_EDIT_INSLN));
END; ! of routine EDT$$SC_RFRELN
!<BLF/PAGE>
END ! of module EDT$SCRRLIN
ELUDOM