xref: /original-bsd/lib/libcurses/cr_put.c (revision 6c57d260)
1 # include	"curses.ext"
2 # include	"cr_ex.h"
3 
4 # define	HARDTABS	8
5 
6 extern char	*tgoto();
7 int		plodput();
8 
9 /*
10  * Terminal driving and line formatting routines.
11  * Basic motion optimizations are done here as well
12  * as formatting of lines (printing of control characters,
13  * line numbering and the like).
14  *
15  * 01/26/81 (Berkeley) @(#)cr_put.c	1.1
16  */
17 
18 /*
19  * Sync the position of the output cursor.
20  * Most work here is rounding for terminal boundaries getting the
21  * column position implied by wraparound or the lack thereof and
22  * rolling up the screen to get destline on the screen.
23  */
24 
25 static int	outcol, outline, destcol, destline, plodcnt;
26 
27 WINDOW		*_win;
28 
29 mvcur(ly, lx, y, x)
30 int	ly, lx, y, x; {
31 
32 #ifdef DEBUG
33 	fprintf(outf, "MVCUR: moving cursor from (%d,%d) to (%d,%d)\n", ly, lx, y, x);
34 #endif
35 	destcol = x;
36 	destline = y;
37 	outcol = lx;
38 	outline = ly;
39 	fgoto();
40 }
41 
42 fgoto() {
43 
44 	reg char	*cgp;
45 	reg int		l, c;
46 
47 	if (destcol > COLS - 1) {
48 		destline += destcol / COLS;
49 		destcol %= COLS;
50 	}
51 	if (outcol > COLS - 1) {
52 		l = (outcol + 1) / COLS;
53 		outline += l;
54 		outcol %= COLS;
55 		if (AM == 0) {
56 			while (l > 0) {
57 				putchar('\n');
58 				if (_pfast)
59 					putchar('\r');
60 				l--;
61 			}
62 			outcol = 0;
63 		}
64 		if (outline > LINES - 1) {
65 			destline -= outline - (LINES - 1);
66 			outline = LINES - 1;
67 		}
68 	}
69 	if (destline > LINES - 1) {
70 		l = destline;
71 		destline = LINES - 1;
72 		if (outline < LINES - 1) {
73 			c = destcol;
74 			if (_pfast == 0 && !CA)
75 				destcol = 0;
76 			fgoto();
77 			destcol = c;
78 		}
79 		while (l > LINES - 1) {
80 			putchar('\n');
81 			l--;
82 			if (_pfast == 0)
83 				outcol = 0;
84 		}
85 	}
86 	if (destline < outline && !(CA || UP != NULL))
87 		destline = outline;
88 	cgp = tgoto(CM, destcol, destline);
89 	if (CA)
90 		if (plod(strlen(cgp)) > 0)
91 			plod(0);
92 		else
93 			tputs(cgp, 0, _putchar);
94 	else
95 		plod(0);
96 	outline = destline;
97 	outcol = destcol;
98 }
99 
100 char
101 _putchar(c)
102 reg char	c; {
103 
104 	putchar(c);
105 #ifdef DEBUG
106 	fprintf(outf, "_PUTCHAR(%s)\n", unctrl(c));
107 #endif
108 }
109 
110 extern bool	plodflg;
111 extern int	plodcnt;
112 
113 plod(cnt)
114 int	cnt; {
115 
116 	reg int		i, j, k;
117 	reg int		soutcol, soutline;
118 	reg char	c;
119 
120 	plodcnt = plodflg = cnt;
121 	soutcol = outcol;
122 	soutline = outline;
123 	if (HO) {
124 		if (GT)
125 			i = (destcol / HARDTABS) + (destcol % HARDTABS);
126 		else
127 			i = destcol;
128         if (destcol >= outcol) {
129                 j = destcol / HARDTABS - outcol / HARDTABS;
130                 if (GT && j)
131                         j += destcol % HARDTABS;
132 		else
133 			j = destcol - outcol;
134         } else
135 			if (outcol - destcol <= i && (BS || BC))
136 				i = j = outcol - destcol;
137 			else
138 				j = i + 1;
139 		k = outline - destline;
140 		if (k < 0)
141 			k = -k;
142 		j += k;
143 		if (i + destline < j) {
144 			tputs(HO, 0, plodput);
145 			outcol = outline = 0;
146 		} else if (LL) {
147 			k = (LINES - 1) - destline;
148 			if (i + k + 2 < j) {
149 				tputs(LL, 0, plodput);
150 				outcol = 0;
151 				outline = LINES - 1;
152 			}
153 		}
154 	}
155 	if (GT)
156         i = destcol % HARDTABS + destcol / HARDTABS;
157 	else
158 		i = destcol;
159 /*
160 	if (BT && outcol > destcol && (j = (((outcol+7) & ~7) - destcol - 1) >> 3)) {
161 		j *= (k = strlen(BT));
162 		if ((k += (destcol&7)) > 4)
163 			j += 8 - (destcol&7);
164 		else
165 			j += k;
166 	} else
167 */
168 		j = outcol - destcol;
169 	/*
170 	 * If we will later need a \n which will turn into a \r\n by
171 	 * the system or the terminal, then don't bother to try to \r.
172 	 */
173 	if ((NONL || !_pfast) && outline < destline)
174 		goto dontcr;
175 	/*
176 	 * If the terminal will do a \r\n and there isn't room for it,
177 	 * then we can't afford a \r.
178 	 */
179 	if (NC && outline >= destline)
180 		goto dontcr;
181 	/*
182 	 * If it will be cheaper, or if we can't back up, then send
183 	 * a return preliminarily.
184 	 */
185 	if (j > i + 1 || outcol > destcol && !BS && !BC) {
186 		plodput('\r');
187 		if (NC) {
188 			plodput('\n');
189 			outline++;
190 		}
191 		outcol = 0;
192 	}
193 dontcr:
194 	while (outline < destline) {
195 		outline++;
196 		plodput('\n');
197 		if (plodcnt < 0)
198 			goto out;
199 		if (NONL || _pfast == 0)
200 			outcol = 0;
201 	}
202 	if (BT)
203 		k = strlen(BT);
204 	while (outcol > destcol) {
205 		if (plodcnt < 0)
206 			goto out;
207 /*
208 		if (BT && outcol - destcol > 4+k) {
209 			tputs(BT, 0, plodput);
210 			outcol--;
211 			outcol &= ~7;
212 			continue;
213 		}
214 */
215 		outcol--;
216 		if (BC)
217 			tputs(BC, 0, plodput);
218 		else
219 			plodput('\b');
220 	}
221 	while (outline > destline) {
222 		outline--;
223 		tputs(UP, 0, plodput);
224 		if (plodcnt < 0)
225 			goto out;
226 	}
227 	if (GT && destcol - outcol > 1) {
228         for (;;) {
229                 i = (outcol / HARDTABS + 1) * HARDTABS;
230                 if (i > destcol)
231                         break;
232 			if (TA)
233 				tputs(TA, 0, plodput);
234 			else
235 				plodput('\t');
236 			outcol = i;
237 		}
238 		if (destcol - outcol > 4 && i < COLS && (BC || BS)) {
239 			if (TA)
240 				tputs(TA, 0, plodput);
241 			else
242 				plodput('\t');
243 			outcol = i;
244 			while (outcol > destcol) {
245 				outcol--;
246 				if (BC)
247 					tputs(BC, 0, plodput);
248 				else
249 					plodput('\b');
250 			}
251 		}
252 	}
253 	while (outcol < destcol) {
254 		if (_win != NULL)
255 			if (plodflg)	/* avoid a complex calculation */
256 				plodcnt--;
257 			else {
258 				c = _win->_y[outline-_win->_begy][outcol-_win->_begx];
259 				if ((c&_STANDOUT) == (curscr->_flags&_STANDOUT))
260 					putchar(c);
261 				else
262 					goto nondes;
263 			}
264 		else
265 nondes:
266 		     if (ND)
267 			tputs(ND, 0, plodput);
268 		else
269 			plodput(' ');
270 		outcol++;
271 		if (plodcnt < 0)
272 			goto out;
273 	}
274 out:
275 	if (plodflg) {
276 		outcol = soutcol;
277 		outline = soutline;
278 	}
279 	return(plodcnt);
280 }
281 
282 /*
283  * Move (slowly) to destination.
284  * Hard thing here is using home cursor on really deficient terminals.
285  * Otherwise just use cursor motions, hacking use of tabs and overtabbing
286  * and backspace.
287  */
288 
289 static	bool	plodflg;
290 
291 plodput(c)
292 reg char	c; {
293 
294 	if (plodflg)
295 		plodcnt--;
296 	else {
297 		putchar(c);
298 #ifdef DEBUG
299 		fprintf(outf, "PLODPUT(%s)\n", unctrl(c));
300 #endif
301 	}
302 }
303 
304 /*
305  * Put with padding
306  */
307 putpad(cp)
308 reg char	*cp; {
309 
310 	fflush(stdout);
311 #ifdef DEBUG
312 	fprintf(outf, "PUTPAD: _puts(\"%s\")\n", cp);
313 #endif
314 	_puts(cp);
315 }
316