Google
 

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