* Copyright (c) 1981 Regents of the University of California.
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* This product includes software developed by the University of
* California, Berkeley and its contributors.
* 4. Neither the name of the University nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
static char sccsid
[] = "@(#)cr_put.c 5.5 (Berkeley) 6/1/90";
* Terminal driving and line formatting routines.
* Basic motion optimizations are done here as well
* as formatting of lines (printing of control characters,
* line numbering and the like).
* Sync the position of the output cursor.
* Most work here is rounding for terminal boundaries getting the
* column position implied by wraparound or the lack thereof and
* rolling up the screen to get destline on the screen.
static int outcol
, outline
, destcol
, destline
;
fprintf(outf
, "MVCUR: moving cursor from (%d,%d) to (%d,%d)\n", ly
, lx
, y
, x
);
destline
+= destcol
/ COLS
;
if (outline
> LINES
- 1) {
destline
-= outline
- (LINES
- 1);
if (outline
< LINES
- 1) {
* The following linefeed (or simulation thereof)
* is supposed to scroll up the screen, since we
* are on the bottom line. We make the assumption
* that linefeed will scroll. If ns is in the
* capability list this won't work. We should
* probably have an sc capability but sf will
* generally take the place if it works.
* Superbee glitch: in the middle of the screen we
* have to use esc B (down) because linefeed screws up
* in "Efficient Paging" (what a joke) mode (which is
* essential in some SB's because CRLF mode puts garbage
* in at end of memory), but you must use linefeed to
* scroll since down arrow won't go past memory end.
* I turned this off after recieving Paul Eggert's
* Superbee description which wins better.
if (NL
/* && !XB */ && _pfast
)
if (destline
< outline
&& !(CA
|| UP
))
cgp
= tgoto(CM
, destcol
, destline
);
if (plod(strlen(cgp
)) > 0)
* Move (slowly) to destination.
* Hard thing here is using home cursor on really deficient terminals.
* Otherwise just use cursor motions, hacking use of tabs and overtabbing
static int plodcnt
, plodflg
;
register int soutcol
, soutline
;
* Consider homing and moving down/right from there, vs moving
* directly with local motions to the right spot.
* i is the cost to home and tab/space to the right to
* get to the proper column. This assumes ND space costs
* 1 char. So i+destcol is cost of motion with home.
i
= (destcol
/ HARDTABS
) + (destcol
% HARDTABS
);
* j is cost to move locally without homing
if (destcol
>= outcol
) { /* if motion is to the right */
j
= destcol
/ HARDTABS
- outcol
/ HARDTABS
;
/* leftward motion only works if we can backspace. */
if (outcol
- destcol
<= i
&& (BS
|| BC
))
i
= j
= outcol
- destcol
; /* cheaper to backspace */
j
= i
+ 1; /* impossibly expensive */
/* k is the absolute value of vertical distance */
* Decision. We may not have a choice if no UP.
if (i
+ destline
< j
|| (!UP
&& destline
< outline
)) {
* Cheaper to home. Do it now and pretend it's a
* Quickly consider homing down and moving from there.
* Assume cost of LL is 2.
k
= (LINES
- 1) - destline
;
if (i
+ k
+ 2 < j
&& (k
<=0 || UP
)) {
* No home and no up means it's impossible.
if (!UP
&& destline
< outline
)
i
= destcol
% HARDTABS
+ destcol
/ HARDTABS
;
if (BT && outcol > destcol && (j = (((outcol+7) & ~7) - destcol - 1) >> 3)) {
if ((k += (destcol&7)) > 4)
* If we will later need a \n which will turn into a \r\n by
* the system or the terminal, then don't bother to try to \r.
if ((NONL
|| !_pfast
) && outline
< destline
)
* If the terminal will do a \r\n and there isn't room for it,
* then we can't afford a \r.
if (NC
&& outline
>= destline
)
* If it will be cheaper, or if we can't back up, then send
* a return preliminarily.
if (j
> i
+ 1 || outcol
> destcol
&& !BS
&& !BC
) {
* BUG: this doesn't take the (possibly long) length
while (outline
< destline
) {
while (outcol
> destcol
) {
if (BT && outcol - destcol > k + 4) {
while (outline
> destline
) {
if (GT
&& destcol
- outcol
> 1) {
i
= tabcol(outcol
, HARDTABS
);
if (destcol
- outcol
> 4 && i
< COLS
&& (BC
|| BS
)) {
while (outcol
> destcol
) {
while (outcol
< destcol
) {
* move one char to the right. We don't use ND space
* because it's better to just print the char we are
if (plodflg
) /* avoid a complex calculation */
i
= curscr
->_y
[outline
][outcol
];
if ((i
&_STANDOUT
) == (curscr
->_flags
&_STANDOUT
))
* Return the column number that results from being in column col and
* hitting a tab, where tabs are set every ts columns. Work right for
* the case where col > COLS, even if ts does not divide COLS.
offset
= COLS
* (col
/ COLS
);
return col
+ ts
- (col
% ts
) + offset
;