Trailing-Edge
-
PDP-10 Archives
-
bb-h138f-bm
-
7-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) 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 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