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
40 #pragma ident "%Z%%M% %I% %E% SMI"
45 #include "curses_inc.h"
48 /* Functions to make use of insert/delete line caps */
54 int _wy
, /* matching lines */
57 static IDST
*sid
, *eid
; /* list of idln actions */
58 static int scrli
, /* screen dimensions */
59 cy
, cx
; /* current cursor positions */
60 static bool didcsr
; /* scrolling region was used */
61 static int _use_idln(void), _set_idln(void);
62 static void _do_idln(int, int, int, int);
64 /* Set insert/delete line mode for win */
67 idlok(WINDOW
*win
, bool bf
)
72 SP
->yesidln
= (delete_line
|| parm_delete_line
||
73 (change_scroll_region
&& (parm_index
|| scroll_forward
))) &&
74 (insert_line
|| parm_insert_line
||
75 (change_scroll_region
&& (parm_rindex
|| scroll_reverse
)));
82 * Set the places to do insert/delete lines
83 * Return the start line for such action.
90 * The value we want to return is the lower line
91 * number of the top-most range.
93 * If there is more than one range of lines on which
94 * we're operating, _find_idln will get called more
95 * then once; we need to search all the IDST for the
96 * desired return value.
102 for (idp
= sid
; idp
!= eid
; idp
++) {
105 if ((tmp
= _MIN(idp
->_wy
, idp
->_sy
)) < rval
)
112 /* Use hardware line delete/insert */
117 int tsy
, bsy
, idn
, dir
, nomore
;
124 /* first cycle do deletions, second cycle do insertions */
125 for (dir
= 1; dir
> -2; dir
-= 2) {
136 /* skip deletions or insertions */
137 if ((dir
> 0 && ip
->_wy
> ip
->_sy
) ||
138 (dir
< 0 && ip
->_wy
< ip
->_sy
)) {
144 /* find a contiguous block */
145 for (ep
= ip
+dir
; ep
!= eip
; ep
+= dir
)
146 if (ep
->_wy
!= (ep
- dir
)->_wy
+ dir
||
147 ep
->_sy
!= (ep
- dir
)->_sy
+ dir
) {
152 /* top and bottom lines of the affected region */
154 tsy
= _MIN(ip
->_wy
, ip
->_sy
);
155 bsy
= _MAX(ep
->_wy
, ep
->_sy
) + 1;
157 tsy
= _MIN(ep
->_wy
, ep
->_sy
);
158 bsy
= _MAX(ip
->_wy
, ip
->_sy
) + 1;
161 /* amount to insert/delete */
162 if ((idn
= ip
->_wy
- ip
->_sy
) < 0)
165 /* do the actual output */
166 _do_idln(tsy
, bsy
, idn
, dir
== -1);
168 /* update change structure */
169 (void) wtouchln(_virtscr
, tsy
, bsy
- tsy
, -1);
171 /* update screen image */
173 curscr
->_tmarg
= (short)tsy
;
174 curscr
->_bmarg
= bsy
- 1;
176 curscr
->_cury
= (short)tsy
;
177 (void) winsdelln(curscr
, dir
> 0 ? -idn
: idn
);
179 curscr
->_bmarg
= scrli
- 1;
181 /* for next while cycle */
189 /* reset scrolling region */
191 _PUTS(tparm_p2(change_scroll_region
, 0, scrli
- 1), scrli
);
196 curscr
->_cury
= (short)cy
;
198 curscr
->_curx
= (short)cx
;
202 /* Do the actual insert/delete lines */
205 _do_idln(int tsy
, int bsy
, int idn
, int doinsert
)
207 int y
, usecsr
, yesscrl
;
210 /* change scrolling region */
211 yesscrl
= usecsr
= FALSE
;
212 if (tsy
> 0 || bsy
< scrli
) {
213 if (change_scroll_region
) {
214 _PUTS(tparm_p2(change_scroll_region
, tsy
, bsy
- 1),
217 yesscrl
= usecsr
= didcsr
= TRUE
;
221 _PUTS(tparm_p2(change_scroll_region
, 0, scrli
- 1), scrli
);
229 /* memory below, clobber it now */
230 if (memory_below
&& clr_eol
&&
231 ((usecsr
&& non_dest_scroll_region
) || bsy
== scrli
)) {
232 for (y
= bsy
- idn
, begns
= _BEGNS
+ y
;
233 y
< bsy
; ++y
, ++begns
)
234 if (*begns
< scrco
) {
235 (void) mvcur(cy
, cx
, y
, 0);
242 /* if not change_scroll_region, delete, then insert */
243 if (!usecsr
&& bsy
< scrli
) {
244 /* delete appropriate number of lines */
245 (void) mvcur(cy
, cx
, bsy
- idn
, 0);
248 if (parm_delete_line
&& (idn
> 1 || !delete_line
))
249 _PUTS(tparm_p1(parm_delete_line
, idn
),
252 for (y
= 0; y
< idn
; ++y
)
253 _PUTS(delete_line
, scrli
- cy
);
257 (void) mvcur(cy
, cx
, tsy
, 0);
261 if (!parm_rindex
&& (!scroll_reverse
||
262 (parm_insert_line
&& idn
> 1))) {
265 if (parm_rindex
&& (idn
> 1 || !scroll_reverse
))
266 _PUTS(tparm_p1(parm_rindex
, idn
), scrli
- cy
);
268 for (y
= 0; y
< idn
; ++y
)
269 _PUTS(scroll_reverse
, scrli
- cy
);
272 if (parm_insert_line
&& (idn
> 1 || !insert_line
))
273 _PUTS(tparm_p1(parm_insert_line
, idn
),
276 for (y
= 0; y
< idn
; ++y
)
277 _PUTS(insert_line
, scrli
- cy
);
281 /* memory above, clobber it now */
282 if (memory_above
&& clr_eol
&&
283 ((usecsr
&& non_dest_scroll_region
) || tsy
== 0)) {
284 for (y
= 0, begns
= _BEGNS
+ y
+ tsy
;
285 y
< idn
; ++y
, ++begns
)
286 if (*begns
< scrco
) {
287 (void) mvcur(cy
, cx
, tsy
+ y
, 0);
295 if (!parm_index
&& (!scroll_forward
||
296 (parm_delete_line
&& idn
> 1))) {
299 (void) mvcur(cy
, cx
, bsy
- 1, 0);
302 if (parm_index
&& (idn
> 1 || !scroll_forward
))
303 _PUTS(tparm_p1(parm_index
, idn
), scrli
- cy
);
305 for (y
= 0; y
< idn
; ++y
)
306 _PUTS(scroll_forward
, scrli
- cy
);
310 (void) mvcur(cy
, cx
, tsy
, 0);
313 if (parm_delete_line
&& (idn
> 1 || !delete_line
))
314 _PUTS(tparm_p1(parm_delete_line
, idn
),
317 for (y
= 0; y
< idn
; ++y
)
318 _PUTS(delete_line
, scrli
- cy
);
321 /* if not change_scroll_region, do insert to restore bottom */
322 if (!usecsr
&& bsy
< scrli
) {
325 for (; y
>= bsy
; --y
, --begns
)
329 (void) mvcur(cy
, cx
, bsy
- idn
, 0);
332 if (parm_insert_line
&&
333 (idn
> 1 || !insert_line
))
334 _PUTS(tparm_p1(parm_insert_line
, idn
),
337 for (y
= 0; y
< idn
; ++y
)
338 _PUTS(insert_line
, scrli
- cy
);