Google
 

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