aboutsummaryrefslogtreecommitdiff
path: root/pkg/utilities/nttools/tedit/display/screen/psfill.x
blob: 2ceee221e8a07cfe9328d6851ded55e017842d04 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
include	<ctype.h>
include	"../curses.h"

# PS_FILL -- Fill a rectangle with a single character and attribute
#
# B.Simon	19-Jan-89	Original
# B.Simon	26-Sep-90	Updated to use screen buffer
# B.Simon	31-Oct-90	Changed to skip correct lines

procedure ps_fill (source, ch, att)

int	source[RSIZE]	# i: Rectangle
int	ch		# i: Fill character
int	att		# i: Fill attribute
#--
include	"screen.com"

bool	canclear, bufflag
char	blank, fill, cell
int	dest[RSIZE]
int	ncols, nrows, irow, icol
pointer	sp, buf, scr

data	blank	/ ' ' /

bool	ps_intersect(), ttygetb()
pointer	ps_screen()

begin
	# Clip the rectangle to the screen boundary
	# If the rectangle is entirely off the screen, return

	if (! ps_intersect (source, lines, cols, dest))
	    return


	# Check for the special cases:
	# Clear entire screen (cl) and clear to end of screen (cd)

	canclear = (ch == ' ' && att == A_NORM)
	ncols = RWIDTH(dest)
	nrows = RHEIGHT(dest)

	if (canclear && ncols == cols && nrows == lines) {
	    if (ttygetb (term, "cl")) {
		call ps_updcur (1, 1)
		call ps_sendcap ("cl", nrows)
		call amovkc (blank, Memc[termscr], lines*cols) 
		return
	    }
	}
		
	if (canclear && ncols == cols && RBOT(dest) == lines) {
	    if (ttygetb (term, "cd")) {
		call ps_setcur (RTOP(dest), 1)
		call ps_sendcap ("cd", nrows)
		scr = ps_screen (RTOP(dest), 1)
		call amovkc (blank, Memc[scr], nrows*cols)
		return
	    }
	}

	# Write the rectangle a line at a time

	call smark (sp)
	call salloc (buf, cols, TY_CHAR)

	if (IS_PRINT(ch))
	    fill = ch
	else
	    fill = blank

	cell = fill + att
	bufflag = false

	canclear = canclear && ttygetb (term, "ce")

	do irow = RTOP(dest), RBOT(dest) {

	    # Check to see if line is already correct
	    # If so, skip to the next line

	    scr = ps_screen (irow, RLEFT(dest))

	    for (icol = 1; icol <= ncols; icol = icol + 1) {
		if (Memc[scr+icol-1] != cell)
		    break
	    }

	    if (icol > ncols)
		next

	    # Move cursor to beginning of line and set attribute

	    call ps_setcur (irow, RLEFT(dest))

	    if (att != A_NORM)
		call ps_sendcap ("so", 1)

	    # Special case: clear to end of line

	    if (canclear && RRIGHT(dest) == cols) {
		call ps_sendcap ("ce", 1)
		call amovkc (blank, Memc[scr], ncols)

	    } else {

		# Fill buffer with character and write to terminal

		if (! bufflag) {
		    bufflag = true
		    call amovkc (fill, Memc[buf], ncols)
		}

		# Don't write to lower right corner if screen will scroll

		if (irow == lines && RRIGHT(dest) == cols) {
		    if (ttygetb (term, "am"))
			ncols = ncols - 1
		}

		call write (ttyout, Memc[buf], ncols)
		call amovkc (cell, Memc[scr], ncols)
		call ps_updcur (irow, RRIGHT(dest) + 1)
	    }

	    # Set attribute back to normal

	    if (att != A_NORM)
		call ps_sendcap ("se", 1)

	}

	call sfree (sp)
end