4 * The contents of this file are subject to the terms of the
5 * Common Development and Distribution License, Version 1.0 only
6 * (the "License"). You may not use this file except in compliance
9 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
10 * or http://www.opensolaris.org/os/licensing.
11 * See the License for the specific language governing permissions
12 * and limitations under the License.
14 * When distributing Covered Code, include this CDDL HEADER in each
15 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
16 * If applicable, add the following below this CDDL HEADER, with the
17 * fields enclosed by brackets "[]" replaced with your own identifying
18 * information: Portions Copyright [yyyy] [name of copyright owner]
23 * Copyright 2004 Sun Microsystems, Inc. All rights reserved.
24 * Use is subject to license terms.
27 /* Copyright (c) 1988 AT&T */
28 /* All Rights Reserved */
31 * University Copyright- Copyright (c) 1982, 1986, 1988
32 * The Regents of the University of California
35 * University Acknowledgment- Portions of this document are derived from
36 * software developed by the University of California, Berkeley, and its
42 #include <sys/types.h>
45 #include "curses_inc.h"
48 * Make the screen look like "win" over the area covered by win.
49 * This routine may use insert/delete char/line and scrolling-region.
50 * win : the window being updated
53 extern int outchcount
;
55 static void _updateln(int), _turn_off_background(void),
56 _setmark1(int, int, chtype
*),
57 _setmark2(int, int, chtype
*), _rmargin(int),
59 static int _useidch(chtype
*, chtype
*, int, int, int *),
60 _prefix(chtype
*, chtype
*, int, int, int *),
63 static short cy
, cx
, /* current cursor coord */
64 scrli
, /* actual screen lines */
65 scrco
; /* actual screen columns */
66 static char **marks
; /* the mark table for cookie terminals */
67 static char **color_marks
; /* color mark table for cookie terminals */
69 #define _ISMARK1(y, x) (marks[y][x / BITSPERBYTE] & (1 << (x % BITSPERBYTE)))
70 #define _ISMARK2(y, x) (color_marks ? (color_marks[y][x / BITSPERBYTE] & \
71 (1 << (x % BITSPERBYTE))) : FALSE)
73 #define _VIDEO(c) ((c) & A_ATTRIBUTES & ~A_COLOR)
74 #define _COLOR(c) ((c) & A_COLOR)
76 #ifdef _VR2_COMPAT_CODE
78 #endif /* _VR2_COMPAT_CODE */
86 int wx
, wy
, nc
, boty
, clby
, idby
, *hs
, curwin
;
88 curwin
= (win
== curscr
);
90 /* don't allow curscr refresh if the screen was just created */
92 if (curwin
&& curscr
->_sync
)
95 /* go thru _stdbody */
96 if (!curwin
&& (win
!= _virtscr
))
97 (void) wnoutrefresh(win
);
99 /* if there is typeahead */
100 if ((_INPUTPENDING
= _chkinput()) == TRUE
) {
102 curscr
->_clear
= TRUE
;
106 if (curwin
|| curscr
->_clear
)
107 _virtscr
->_clear
= TRUE
;
109 /* save curscr cursor coordinates */
113 /* to simplify code in some cases */
115 color_marks
= _COLOR_MARKS
;
116 scrli
= curscr
->_maxy
;
117 scrco
= curscr
->_maxx
;
122 /* make sure we're in program mode */
124 /* If endwin is equal to 2 it means we just did a newscreen. */
125 if (SP
->fl_endwin
== TRUE
) {
126 (void) reset_prog_mode();
128 (void) tputs(keypad_xmit
, 1, _outch
);
132 (void) tputs(meta_on
, 1, _outch
);
133 if (cur_term
->_cursorstate
!= 1)
134 _PUTS(cur_term
->cursor_seq
[cur_term
->
137 _PUTS(enter_ca_mode
, 1);
138 (void) tputs(ena_acs
, 1, _outch
);
140 if (exit_attribute_mode
)
141 _PUTS(tparm_p0(exit_attribute_mode
), 1);
144 * If there is no exit_attribute mode, then vidupdate
145 * could only possibly turn off one of the below three
146 * so that's all we ask it turn off.
148 vidupdate(A_NORMAL
, (A_ALTCHARSET
| A_STANDOUT
|
149 A_UNDERLINE
), _outch
);
151 SP
->fl_endwin
= FALSE
;
153 #ifdef _VR2_COMPAT_CODE
154 _endwin
= (char)FALSE
;
155 #endif /* _VR2_COMPAT_CODE */
158 /* clear the screen if required */
159 if (_virtscr
->_clear
) {
161 if (back_color_erase
)
162 _turn_off_background();
164 _PUTS(clear_screen
, scrli
);
165 cy
= cx
= curscr
->_curx
= curscr
->_cury
= 0;
167 /* _sync indicates that this a new screen */
169 (void) werase(curscr
);
171 nc
= scrco
/ BITSPERBYTE
- (scrco
%
172 BITSPERBYTE
? 0 : 1);
174 bnsch
= _BEGNS
; ensch
= _ENDNS
;
176 for (; wy
>= 0; --wy
) {
181 for (wx
= nc
; wx
>= 0; --wx
)
186 _virtscr
->_clear
= curscr
->_sync
= curscr
->_clear
= FALSE
;
190 /* pretend _virtscr has been totally changed */
191 (void) wtouchln(_virtscr
, 0, scrli
, -1);
193 _VIRTBOT
= scrli
- 1;
195 /* will not do clear-eod or ins/del lines */
200 /* Software soft labels; if _changed == 2, slk's are in clear mode. */
201 if (slk
&& slk
->_win
&& (slk
->_changed
== TRUE
))
204 /* do line updating */
205 _virtscr
->_clear
= FALSE
;
208 bnsch
= _virtscr
->_firstch
+ wy
;
209 ensch
= _virtscr
->_lastch
+ wy
;
211 for (; wy
< boty
; ++wy
, ++bnsch
, ++ensch
) {
212 /* this line is up-to-date */
216 /* there is type-ahead */
217 if (!curwin
&& (_INPUTPENDING
= _chkinput()) == TRUE
) {
219 _VIRTTOP
= (short)wy
;
224 /* now we have to work, check for ceod */
225 clby
= _getceod(wy
, boty
);
227 /* check for insert/delete lines */
228 if (_virtscr
->_use_idl
)
229 idby
= (*_setidln
)();
232 /* try clear-to-eod */
236 /* try ins/del lines */
253 /* do hardware soft labels; if _changed == 2, */
254 /* slk's are in clear mode. */
255 if (slk
&& (slk
->_changed
== TRUE
) && !(slk
->_win
))
259 wy
= _virtscr
->_cury
;
260 wx
= _virtscr
->_curx
;
261 if (wy
!= cy
|| wx
!= cx
) {
262 (void) mvcur(cy
, cx
, wy
, wx
);
269 /* reset the flags */
270 curscr
->_clear
= FALSE
;
271 _virtscr
->_use_idl
= FALSE
;
272 _virtscr
->_use_idc
= TRUE
;
273 _INPUTPENDING
= FALSE
;
275 /* virtual image is now up-to-date */
282 (void) fflush(SP
->term_file
);
286 /* Shift appropriate portions of a line to leave space for cookies. */
291 chtype
*wcp
, *cp
, prev
;
293 int x
, cury
, didshift
;
297 /* allocate space for shifted line */
298 if (length
< scrco
) {
300 line
= (chtype
*) malloc(scrco
* sizeof (chtype
));
301 length
= line
? scrco
: 0;
304 /* no space to do it */
306 return (_virtscr
->_y
[wy
]);
310 wcp
= _virtscr
->_y
[wy
];
311 curx
= _virtscr
->_curx
;
312 cury
= _virtscr
->_cury
;
315 for (x
= 0; x
< scrco
; ++x
, ++wcp
, ++cp
) {
316 if (_ATTR(*wcp
) != prev
) {
317 /* use existing blank */
318 if (_CHAR(*wcp
) == ' ')
319 *cp
= ' ' | _ATTR(*(wcp
+ 1));
320 /* use previous blank */
322 if ((x
> 0) && _CHAR(*(cp
- 1)) == ' ') {
323 *(cp
- 1) = ' ' | _ATTR(*wcp
);
326 if ((curx
>= x
) && (cury
== wy
))
328 *cp
= ' ' | _ATTR(*wcp
);
337 /* make sure that the end of the line is normal */
338 cp
= line
+ scrco
- 1;
339 if (didshift
|| (_ATTR(*cp
) != A_NORMAL
) ||
340 ((wy
== scrli
- 1) && (_ATTR(*(cp
- 1)) != A_NORMAL
))) {
341 *cp
= didshift
? ' ' : _CHAR(*cp
);
343 *(cp
- 1) = didshift
? ' ' : _CHAR(*(cp
- 1));
347 _virtscr
->_curx
= curx
>= scrco
? scrco
- 1 : curx
;
354 * Three schemes of coloring are allowed. The first is the usual
355 * pen-up/pen-down model. The second is the HP26*-like model.
356 * In this case, colorings are specified by intervals, the left
357 * side of the interval has the coloring mark, the right side
358 * has the end-coloring mark. We assume that clear sequences will
359 * clear ALL marks in the affected regions. The second case is
360 * signified by the boolean flag ceol_standout_glitch.
361 * The third case is for terminals that leave visible cookies on
362 * the screen. This last case is at most an approximation of what
369 chtype
*wcp
, *scp
, *wp
, *sp
, wc
, sc
;
370 int wx
, lastx
, x
, mtch
, idch
, blnkx
, idcx
, video_attrx
,
371 color_attrx
, maxi
, endns
, begns
, wx_sav
, multi_col
;
372 bool redraw
, changed
, didcolor
, didvideo
;
374 redraw
= (_virtscr
->_firstch
[wy
] == _REDRAW
);
379 if (!redraw
&& (_virtscr
->_lastch
[wy
] == _BLANK
) && (begns
>= scrco
))
383 wcp
= magic_cookie_glitch
<= 0 ? _virtscr
->_y
[wy
] : _shove(wy
);
384 scp
= curscr
->_y
[wy
];
386 /* the interval to be updated */
387 if (redraw
|| magic_cookie_glitch
>= 0) {
391 wx
= _virtscr
->_firstch
[wy
];
392 lastx
= _virtscr
->_lastch
[wy
] == _BLANK
? scrco
:
393 _virtscr
->_lastch
[wy
] + 1;
396 /* skip equal parts */
398 /* skip the starting equal part */
401 for (; wx
< lastx
; ++wx
)
407 /* start update at an entire character */
408 for (sp
= scp
+wx
, wp
= wcp
+wx
; wp
> wcp
; --wp
, --sp
, --wx
)
409 if (!ISCBIT(*wp
) && !ISCBIT(*sp
))
412 /* skip the ending equal part */
413 wp
= wcp
+ lastx
- 1;
414 sp
= scp
+ lastx
- 1;
415 for (; lastx
> wx
; --lastx
)
422 for (; lastx
< scrco
; ++wp
, ++sp
, ++lastx
)
423 if (!ISCBIT(*wp
) && !ISCBIT(*sp
))
427 /* place to do clear-eol */
428 if (!clr_eol
|| endns
>= lastx
)
431 if (_virtscr
->_lastch
[wy
] == _BLANK
)
434 for (blnkx
= lastx
- 1, wp
= wcp
+ blnkx
;
435 blnkx
>= wx
; --blnkx
, --wp
)
438 for (sp
= scp
+ blnkx
+ 1; blnkx
< scrco
- 1;
442 if (blnkx
+ _COST(Clr_eol
) >= lastx
)
446 /* on cookie terminals, we may need to do more work */
448 /* video_attrx = color_attrx = scrco; */
449 video_attrx
= color_attrx
= (lastx
>= scrco
) ? lastx
- 1 :
452 /* find the last video attribute on the line */
454 wp
= wcp
+ video_attrx
;
455 for (; video_attrx
>= wx
; --video_attrx
, --wp
)
456 if (_VIDEO(*wp
) != A_NORMAL
)
459 /* find the last color attribute on the line */
462 wp
= wcp
+ color_attrx
;
463 for (; color_attrx
>= wx
; --color_attrx
, --wp
)
464 if (_COLOR(*wp
) != A_NORMAL
)
466 if (color_attrx
< lastx
)
469 if (video_attrx
< lastx
)
472 if (video_attrx
>= scrco
)
474 if (color_marks
&& color_attrx
>= scrco
)
476 if (magic_cookie_glitch
> 0 && wy
== scrli
- 1 &&
477 video_attrx
== scrco
- 1)
479 if (color_marks
&& magic_cookie_glitch
> 0 &&
480 wy
== scrli
- 1 && color_attrx
== scrco
- 1)
482 for (wp
= wcp
+video_attrx
; wp
>= wcp
+wx
; --wp
)
487 /* place for insert/delete chars */
489 if (redraw
|| (!SP
->dchok
&& !SP
->ichok
) || !(_virtscr
->_use_idc
) ||
490 endns
< wx
|| (endns
>= lastx
&& (scrco
- lastx
) > SLACK
)) {
496 /* on cookie term, only do idch where no attrs */
498 for (idcx
= scrco
- 1, wp
= wcp
+ idcx
; idcx
>= wx
;
500 if (_ATTR(*wp
) || _ISMARK1(wy
, idcx
) ||
503 if (idcx
>= scrco
- SLACK
)
507 if (idcx
< lastx
&& endns
>= lastx
)
510 /* max amount of insert allow */
511 if (idcx
== scrco
|| !SP
->ichok
)
517 maxi
= lastx
- (endns
+ 1);
522 didvideo
= changed
= FALSE
;
523 didcolor
= (color_marks
) ? FALSE
: TRUE
;
526 /* skip things that are already right */
530 for (; wx
< lastx
; ++wx
, ++wcp
, ++scp
)
535 for (; wx
> wx_sav
; --wx
, --wcp
, --scp
) {
536 if (!ISCBIT(*wcp
) && !ISCBIT(*scp
))
542 /* try clear-bol, we'll assume exclusive clr_bol */
543 if (!changed
&& !marks
&& clr_bol
&& blnkx
> wx
&&
545 for (x
= wx
, wp
= wcp
; x
< lastx
; ++x
, ++wp
)
548 /* clearing only whole screen characters */
549 for (sp
= scp
+(x
-wx
); x
>= wx
; --x
, --sp
)
554 if ((x
- (redraw
? 0 : begns
)) > _COST(Clr_bol
)) {
555 (void) mvcur(cy
, cx
, wy
, x
);
556 /* MORE?: colors - mvcur will shuts of */
557 /* colors when msgr is not defined */
560 if (back_color_erase
)
561 _turn_off_background();
570 (void) memcpy(scp
, wcp
,
571 (mtch
* sizeof (chtype
)));
578 /* screen image is changing */
581 /* move to the point to start refresh */
582 if (cy
!= wy
|| cx
!= wx
)
583 (void) mvcur(cy
, cx
, wy
, wx
);
589 /* update screen image */
594 if (!redraw
&& !multi_col
&& wc
== sc
)
597 /* real video attributes */
599 curscr
->_attrs
= _ATTR(sc
);
604 if (back_color_erase
)
605 _turn_off_background();
609 curscr
->_curx
= (short)wx
;
611 curscr
->_cury
= (short)wy
;
612 (void) wclrtoeol(curscr
);
614 if (marks
&& wx
> 0 && _ATTR(*(scp
- 1)) !=
616 _VIDS(A_NORMAL
, _ATTR(*(scp
- 1)));
617 if (_VIDEO(*scp
- 1))
618 _setmark1(wy
, wx
, NULL
);
619 if (_COLOR(*scp
- 1))
620 _setmark2(wy
, wx
, NULL
);
625 /* try insert/delete chars */
626 if (wx
> idcx
&& !ISCBIT(*scp
) &&
627 (mtch
= _useidch(wcp
, scp
, lastx
- wx
,
636 /* about to output chars, make sure insert */
641 /* color and video attributes */
642 if (_ATTR(wc
) != curscr
->_attrs
) {
643 bool color_change
= FALSE
;
644 bool video_change
= FALSE
;
648 _VIDEO(curscr
->_attrs
)) {
654 _COLOR(curscr
->_attrs
)) {
659 /* the following may occurs when, for */
660 /* example the application */
661 /* is written for color terminal and then */
662 /* run on a monocrome */
664 if (marks
&& !video_change
&& !color_change
)
667 /* prevent spilling out of line */
668 if (marks
&& !(didcolor
&& didvideo
)) {
669 if ((video_change
&& !_ISMARK1(wy
,
670 video_attrx
)) || (color_change
&&
671 !_ISMARK2(wy
, color_attrx
))) {
673 chtype sa
= curscr
->_attrs
;
677 if (!didvideo
&& video_change
&&
678 !_ISMARK1(wy
, video_attrx
)) {
682 _VIDS(_VIDEO(_virtscr
->_y
[wy
]
684 _VIDEO(_virtscr
->_y
[wy
]
686 _setmark1(wy
, video_attrx
,
691 if (!didcolor
&& color_change
&&
692 !_ISMARK2(wy
, color_attrx
)) {
694 tempx
= first
? video_attrx
: wx
;
695 if (tempx
!= color_attrx
)
696 (void) mvcur(wy
, tempx
, wy
,
699 * sc = _COLOR(curscr->_y[wy][color_attrx]);
700 * _VIDS(sc, (~sc & A_COLOR));
702 _VIDS(_COLOR(_virtscr
->_y
[wy
]
704 _COLOR(_virtscr
->_y
[wy
]
706 _setmark2(wy
, color_attrx
, NULL
);
709 (void) mvcur(wy
, (second
? color_attrx
:
710 video_attrx
), wy
, wx
);
715 _VIDS(_ATTR(wc
), curscr
->_attrs
);
717 /* on cookie terminals mark the interval */
719 _setmark1(wy
, wx
, scp
);
721 _setmark2(wy
, wx
, scp
);
728 x
= _curs_scrwidth
[TYPE(RBYTE(wc
))];
729 if (wx
== scrco
- x
) {
734 if (transparent_underline
&& erase_overstrike
&&
737 (void) mvcur(wy
, wx
+ 1, wy
, wx
);
740 /* put out the character */
741 (void) _outwch(tilde_glitch
&& _CHAR(wc
) == '~' ? '`' : wc
);
747 /* output entire multi-byte chars */
748 while (wx
< lastx
&& ISCBIT(*wcp
)) {
749 (void) _outwch(*wcp
);
763 /* update the blank structure */
764 for (wx
= 0, scp
= curscr
->_y
[wy
]; wx
< scrco
; ++wx
, ++scp
)
768 _BEGNS
[wy
] = (short)wx
;
773 scp
= curscr
->_y
[wy
] + wx
;
774 for (; wx
>= 0; --wx
, --scp
)
778 _ENDNS
[wy
] = (short)wx
;
781 /* update the hash structure */
782 _CURHASH
[wy
] = _BEGNS
[wy
] < scrco
? _NOHASH
: 0;
787 * See if a left or right shift is apppropriate
788 * This routine is called only if !cookie_glitch or no video attributes
789 * are used in the affected part.
790 * The main idea is to find a longest common substring which is a
791 * prefix of one of 'wcp' or 'scp', then either delete or
792 * insert depending on where the prefix is.
794 * wcp : what we want the screen to look like
795 * scp : what the screen looks like now
796 * length: the length to be updated
797 * maxi: maximum possible insert amount
798 * id; *id returns the amount of insert/delete
800 * Return the number of chars matched after the shift.
804 _useidch(chtype
*wcp
, chtype
*scp
, int length
, int maxi
, int *id
)
806 int x1
, x2
, blnk
, idch
, cost
, cost_ich1
, match
;
810 if (SP
->dchok
&& _CHAR(*wcp
) != ' ') {
811 if ((match
= _prefix(wcp
, scp
, length
, length
/ 2, &idch
)) > 0)
812 cost
= _COST(dcfixed
) + (parm_dch
? _COST(Parm_dch
) :
813 _COST(Delete_character
) * idch
);
819 if (back_color_erase
)
820 _turn_off_background();
829 _PUTS(enter_delete_mode
, 1);
834 _PUTS(tparm_p1(parm_dch
, idch
), 1);
836 for (x1
= 0; x1
< idch
; ++x1
)
837 _PUTS(delete_character
, 1);
841 SP
->phys_irm
= FALSE
;
842 _PUTS(exit_delete_mode
, 1);
845 /* update screen image */
846 for (x1
= 0, x2
= idch
; x2
< length
; ++x1
, ++x2
)
848 for (; x1
< length
; ++x1
)
856 /* no insertion wanted or possible */
857 if (!(SP
->ichok
) || _CHAR(*scp
) == ' ')
860 /* see if insertion is worth it */
861 maxi
= (idch
= length
/ 2) < maxi
? idch
: maxi
;
862 if ((match
= _prefix(scp
, wcp
, length
, maxi
, &idch
)) <= 0)
865 /* see if inserting blanks only */
866 for (blnk
= 0; blnk
< idch
; ++blnk
)
867 if (wcp
[blnk
] != ' ') {
872 /* see if doing insertion is worth it */
873 cost_ich1
= idch
* _COST(Insert_character
);
875 cost
= SP
->phys_irm
? 0 : _COST(icfixed
);
876 if (blnk
> _COST(Parm_ich
) && _COST(Parm_ich
) < cost_ich1
)
877 cost
+= _COST(Parm_ich
);
879 if (insert_character
)
882 if (parm_ich
&& _COST(Parm_ich
) < cost_ich1
)
883 cost
= _COST(Parm_ich
);
887 if ((cost
- blnk
) > match
)
890 /* perform the insertions */
893 if (back_color_erase
)
894 _turn_off_background();
899 if (blnk
> _COST(Parm_ich
) && _COST(Parm_ich
) < cost_ich1
)
900 _PUTS(tparm_p1(parm_ich
, idch
), 1);
902 if (insert_character
)
905 /* so that we'll do real char insertions */
908 if (parm_ich
&& _COST(Parm_ich
) < cost_ich1
)
909 _PUTS(tparm_p1(parm_ich
, idch
), 1);
912 for (x1
= 0; x1
< idch
; ++x1
)
913 _PUTS(insert_character
, 1);
917 /* inserting desired characters */
919 for (x1
= 0; x1
< idch
; ++x1
) {
921 if (_ATTR(wc
) != curscr
->_attrs
)
922 _VIDS(_ATTR(wc
), curscr
->_attrs
);
923 (void) _outwch(_CHAR(wc
) == '~' &&
924 tilde_glitch
? '`' : wc
);
928 /* update the screen image */
929 for (x1
= length
- 1, x2
= length
- idch
- 1; x2
>= 0; --x1
, --x2
)
931 (void) memcpy(scp
, wcp
, idch
* sizeof (chtype
));
934 return (match
+ idch
);
938 * Find a substring of s2 that match a prefix of s1.
939 * The substring is such that:
940 * 1. it does not start with an element
941 * that is in perfect alignment with one in s1 and
942 * 2: it is at least as long as the displacement.
944 * length: the length of s1, s2.
945 * maxs: only search for match in [1,maxs] of s2.
946 * begm: *begm returns where the match begins.
948 * Return the number of matches.
952 _prefix(chtype
*s1
, chtype
*s2
, int length
, int maxs
, int *begm
)
957 for (m
= 1; m
<= maxs
; ++m
)
958 /* testing for s1[m] != s2[m] is condition 1 */
959 if (s1
[0] == s2
[m
] && s1
[m
] != s2
[m
]) {
960 /* see if it's long enough (condition 2) */
961 for (k
= 2 * m
- 1; k
> m
; --k
)
962 if (s1
[k
- m
] != s2
[k
])
964 /* found a match with a good length */
968 /* count the # of matches */
971 for (n
= m
; n
< length
; ++n
)
982 /* Set video markers for cookie terminal. */
985 _setmark1(int y
, int x
, chtype
*s
)
989 /* set the mark map */
990 marks
[y
][x
/ BITSPERBYTE
] |= (1 << (x
% BITSPERBYTE
));
993 a
= _VIDEO(curscr
->_attrs
);
995 /* set the video attr of the first char here */
997 *s
= _CHAR(*s
) | _COLOR(*s
) | a
;
999 /* now the video attr of the rest of the affected interval */
1000 for (x
+= 1, s
+= 1; x
< scrco
; ++x
, ++s
)
1005 *s
= _CHAR(*s
) | _COLOR(*s
) | a
;
1009 /* Set color markers for cookie terminal. */
1012 _setmark2(int y
, int x
, chtype
*s
)
1016 /* set the mark map */
1017 color_marks
[y
][x
/ BITSPERBYTE
] |= (1 << (x
% BITSPERBYTE
));
1020 a
= _COLOR(curscr
->_attrs
);
1022 /* set the video attr of the first char here */
1024 *s
= _CHAR(*s
) | _VIDEO(*s
) | a
;
1026 /* now the video attr of the rest of the affected interval */
1027 for (x
+= 1, s
+= 1; x
< scrco
; ++x
, ++s
)
1032 *s
= _CHAR(*s
) | _VIDEO(*s
) | a
;
1037 /* At the right margin various weird things can happen. We treat them here. */
1039 /* At the right margin various weird things can happen. We treat them here. */
1046 chtype
*wcp
= _virtscr
->_y
[cy
];
1048 /* screen may scroll */
1049 if (cy
== scrli
- 1) {
1050 /* can't do anything */
1054 /* the width of the new character */
1055 w
= _curs_scrwidth
[TYPE(RBYTE(wcp
[wx
]))];
1056 /* the place to put it without causing scrolling */
1057 for (x
= wx
- 1; x
> 0; --x
)
1058 if (!ISCBIT(wcp
[x
]))
1060 sc
= curscr
->_y
[cy
][x
];
1062 (void) mvcur(cy
, cx
, cy
, x
);
1063 if (_ATTR(wcp
[wx
]) != curscr
->_attrs
)
1064 _VIDS(_ATTR(wcp
[wx
]), curscr
->_attrs
);
1065 (void) _outwch(tilde_glitch
&&
1066 _CHAR(wcp
[wx
]) == '~' ? '`' : wcp
[wx
]);
1068 for (ix
= wx
+ 1; ix
< scrco
; ++ix
) {
1069 (void) _outwch(wcp
[ix
]);
1072 /* insert sc back in and push wcp[wx] right */
1073 (void) mvcur(cy
, x
+w
, cy
, x
);
1076 if (back_color_erase
)
1077 _turn_off_background();
1079 if (SP
->imode
&& !SP
->phys_irm
)
1081 /* width of the old character that was overwritten */
1082 w
= _curs_scrwidth
[TYPE(RBYTE(curscr
->_y
[cy
][x
]))];
1084 if (insert_character
)
1085 for (ix
= 0; ix
< w
; ++ix
)
1086 _PUTS(insert_character
, 1);
1088 if (parm_ich
&& !SP
->imode
)
1089 _PUTS(tparm_p1(parm_ich
, w
), 1);
1091 if (_ATTR(sc
) != curscr
->_attrs
)
1092 _VIDS(_ATTR(sc
), curscr
->_attrs
);
1093 for (ix
= x
; w
> 0; --w
, ++ix
)
1094 (void) _outwch(curscr
->_y
[cy
][ix
]);
1096 /* make sure the video attrs are ok */
1097 if (marks
&& (_ATTR(sc
) || _ATTR(wcp
[wx
])))
1098 _VIDS(_ATTR(wcp
[wx
]), ~_ATTR(sc
));
1100 /* update screen image */
1103 curscr
->_y
[cy
][wx
] = wcp
[wx
];
1104 for (x
= wx
+ 1; x
< scrco
; ++x
) {
1105 (void) _outwch(wcp
[x
]);
1106 curscr
->_y
[cy
][x
] = wcp
[x
];
1111 /* put char out and update screen image */
1112 (void) _outwch(tilde_glitch
&& _CHAR(wcp
[wx
]) == '~' ? '`' : wcp
[wx
]);
1121 curscr
->_y
[cy
][wx
] = wcp
[wx
];
1123 for (x
= wx
+ 1; x
< scrco
; ++x
) {
1124 (void) _outwch(wcp
[x
]);
1125 curscr
->_y
[cy
][x
] = wcp
[x
];
1128 /* make sure that wrap-around happens */
1129 if (!auto_right_margin
|| eat_newline_glitch
) {
1130 (void) _outch('\r');
1131 (void) _outch('\n');
1138 * Find the top-most line to do clear-to-eod.
1140 * topy, boty: the region to consider
1144 _getceod(int topy
, int boty
)
1148 short *begch
, *endch
, *begns
;
1151 if ((topy
+ 1) >= boty
)
1155 begch
= _virtscr
->_firstch
+ wy
;
1156 endch
= _virtscr
->_lastch
+ wy
;
1157 begns
= _BEGNS
+ wy
;
1159 for (; wy
>= topy
; --wy
, --begch
, --endch
, --begns
) {
1160 if (*endch
== _BLANK
|| (*begch
>= scrco
&& *begns
>= scrco
))
1163 wcp
= _virtscr
->_y
[wy
];
1165 for (; wcp
< ecp
; ++wcp
)
1166 if (_DARKCHAR(*wcp
))
1177 /* Use hardware clear-to-bottom. */
1180 _useceod(int topy
, int boty
)
1182 short *begns
, *begch
;
1184 /* skip lines already blanked */
1185 begch
= _virtscr
->_firstch
+ topy
;
1186 begns
= _BEGNS
+ topy
;
1187 for (; topy
< boty
; ++topy
, ++begns
, ++begch
)
1188 if (*begns
< scrco
|| *begch
== _REDRAW
)
1194 if (topy
+ 1 >= boty
)
1197 /* see if bottom is clear */
1198 for (begns
= _BEGNS
+ boty
; boty
< scrli
; ++boty
, ++begns
)
1202 /* use clear-screen if appropriate */
1205 if (back_color_erase
)
1206 _turn_off_background();
1208 _PUTS(clear_screen
, scrli
);
1210 (void) werase(curscr
);
1213 /* use clear-to-end-of-display or delete lines */
1214 if (clr_eos
|| (parm_delete_line
&& !memory_below
)) {
1215 (void) mvcur(cy
, cx
, topy
, 0);
1220 if (back_color_erase
)
1221 _turn_off_background();
1222 _PUTS(clr_eos
? clr_eos
: tparm_p1(parm_delete_line
,
1223 scrli
- topy
), scrli
- topy
);
1227 curscr
->_cury
= (short)topy
;
1229 (void) wclrtobot(curscr
);
1231 /* no hardware support */
1236 /* correct the update structure */
1237 (void) wtouchln(_virtscr
, topy
, scrli
, FALSE
);
1242 _turn_off_background(void)
1244 /* this routine turn the background color to zero. This need to be */
1245 /* done only in forllowing cases: */
1246 /* 1) We are using Tek type terminal (which has bce terminfo */
1248 /* 2) The current background is not already zero */
1250 if (set_background
&& cur_term
->_cur_pair
.background
> 0) {
1251 _PUTS(orig_pair
, 1);
1252 cur_term
->_cur_pair
.foreground
= -1;
1253 cur_term
->_cur_pair
.background
= -1;
1254 curscr
->_attrs
&= ~A_COLOR
;