1*0Sstevel@tonic-gate /*
2*0Sstevel@tonic-gate * CDDL HEADER START
3*0Sstevel@tonic-gate *
4*0Sstevel@tonic-gate * The contents of this file are subject to the terms of the
5*0Sstevel@tonic-gate * Common Development and Distribution License, Version 1.0 only
6*0Sstevel@tonic-gate * (the "License"). You may not use this file except in compliance
7*0Sstevel@tonic-gate * with the License.
8*0Sstevel@tonic-gate *
9*0Sstevel@tonic-gate * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
10*0Sstevel@tonic-gate * or http://www.opensolaris.org/os/licensing.
11*0Sstevel@tonic-gate * See the License for the specific language governing permissions
12*0Sstevel@tonic-gate * and limitations under the License.
13*0Sstevel@tonic-gate *
14*0Sstevel@tonic-gate * When distributing Covered Code, include this CDDL HEADER in each
15*0Sstevel@tonic-gate * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
16*0Sstevel@tonic-gate * If applicable, add the following below this CDDL HEADER, with the
17*0Sstevel@tonic-gate * fields enclosed by brackets "[]" replaced with your own identifying
18*0Sstevel@tonic-gate * information: Portions Copyright [yyyy] [name of copyright owner]
19*0Sstevel@tonic-gate *
20*0Sstevel@tonic-gate * CDDL HEADER END
21*0Sstevel@tonic-gate */
22*0Sstevel@tonic-gate /*
23*0Sstevel@tonic-gate * Copyright 2004 Sun Microsystems, Inc. All rights reserved.
24*0Sstevel@tonic-gate * Use is subject to license terms.
25*0Sstevel@tonic-gate */
26*0Sstevel@tonic-gate
27*0Sstevel@tonic-gate /* Copyright (c) 1988 AT&T */
28*0Sstevel@tonic-gate /* All Rights Reserved */
29*0Sstevel@tonic-gate
30*0Sstevel@tonic-gate /*
31*0Sstevel@tonic-gate * University Copyright- Copyright (c) 1982, 1986, 1988
32*0Sstevel@tonic-gate * The Regents of the University of California
33*0Sstevel@tonic-gate * All Rights Reserved
34*0Sstevel@tonic-gate *
35*0Sstevel@tonic-gate * University Acknowledgment- Portions of this document are derived from
36*0Sstevel@tonic-gate * software developed by the University of California, Berkeley, and its
37*0Sstevel@tonic-gate * contributors.
38*0Sstevel@tonic-gate */
39*0Sstevel@tonic-gate
40*0Sstevel@tonic-gate #pragma ident "%Z%%M% %I% %E% SMI"
41*0Sstevel@tonic-gate
42*0Sstevel@tonic-gate /*LINTLIBRARY*/
43*0Sstevel@tonic-gate
44*0Sstevel@tonic-gate #include <stdlib.h>
45*0Sstevel@tonic-gate #include "curses_inc.h"
46*0Sstevel@tonic-gate
47*0Sstevel@tonic-gate
48*0Sstevel@tonic-gate /* Functions to make use of insert/delete line caps */
49*0Sstevel@tonic-gate
50*0Sstevel@tonic-gate #define scrco COLS
51*0Sstevel@tonic-gate
52*0Sstevel@tonic-gate typedef struct
53*0Sstevel@tonic-gate {
54*0Sstevel@tonic-gate int _wy, /* matching lines */
55*0Sstevel@tonic-gate _sy;
56*0Sstevel@tonic-gate } IDST;
57*0Sstevel@tonic-gate static IDST *sid, *eid; /* list of idln actions */
58*0Sstevel@tonic-gate static int scrli, /* screen dimensions */
59*0Sstevel@tonic-gate cy, cx; /* current cursor positions */
60*0Sstevel@tonic-gate static bool didcsr; /* scrolling region was used */
61*0Sstevel@tonic-gate static int _use_idln(void), _set_idln(void);
62*0Sstevel@tonic-gate static void _do_idln(int, int, int, int);
63*0Sstevel@tonic-gate
64*0Sstevel@tonic-gate /* Set insert/delete line mode for win */
65*0Sstevel@tonic-gate
66*0Sstevel@tonic-gate int
idlok(WINDOW * win,bool bf)67*0Sstevel@tonic-gate idlok(WINDOW *win, bool bf)
68*0Sstevel@tonic-gate {
69*0Sstevel@tonic-gate _useidln = _use_idln;
70*0Sstevel@tonic-gate _setidln = _set_idln;
71*0Sstevel@tonic-gate
72*0Sstevel@tonic-gate SP->yesidln = (delete_line || parm_delete_line ||
73*0Sstevel@tonic-gate (change_scroll_region && (parm_index || scroll_forward))) &&
74*0Sstevel@tonic-gate (insert_line || parm_insert_line ||
75*0Sstevel@tonic-gate (change_scroll_region && (parm_rindex || scroll_reverse)));
76*0Sstevel@tonic-gate
77*0Sstevel@tonic-gate win->_use_idl = bf;
78*0Sstevel@tonic-gate return (OK);
79*0Sstevel@tonic-gate }
80*0Sstevel@tonic-gate
81*0Sstevel@tonic-gate /*
82*0Sstevel@tonic-gate * Set the places to do insert/delete lines
83*0Sstevel@tonic-gate * Return the start line for such action.
84*0Sstevel@tonic-gate */
85*0Sstevel@tonic-gate
86*0Sstevel@tonic-gate static int
_set_idln(void)87*0Sstevel@tonic-gate _set_idln(void)
88*0Sstevel@tonic-gate {
89*0Sstevel@tonic-gate /*
90*0Sstevel@tonic-gate * The value we want to return is the lower line
91*0Sstevel@tonic-gate * number of the top-most range.
92*0Sstevel@tonic-gate *
93*0Sstevel@tonic-gate * If there is more than one range of lines on which
94*0Sstevel@tonic-gate * we're operating, _find_idln will get called more
95*0Sstevel@tonic-gate * then once; we need to search all the IDST for the
96*0Sstevel@tonic-gate * desired return value.
97*0Sstevel@tonic-gate */
98*0Sstevel@tonic-gate {
99*0Sstevel@tonic-gate IDST *idp;
100*0Sstevel@tonic-gate int rval = scrli;
101*0Sstevel@tonic-gate
102*0Sstevel@tonic-gate for (idp = sid; idp != eid; idp++) {
103*0Sstevel@tonic-gate int tmp;
104*0Sstevel@tonic-gate
105*0Sstevel@tonic-gate if ((tmp = _MIN(idp->_wy, idp->_sy)) < rval)
106*0Sstevel@tonic-gate rval = tmp;
107*0Sstevel@tonic-gate }
108*0Sstevel@tonic-gate return (rval);
109*0Sstevel@tonic-gate }
110*0Sstevel@tonic-gate }
111*0Sstevel@tonic-gate
112*0Sstevel@tonic-gate /* Use hardware line delete/insert */
113*0Sstevel@tonic-gate
114*0Sstevel@tonic-gate static int
_use_idln(void)115*0Sstevel@tonic-gate _use_idln(void)
116*0Sstevel@tonic-gate {
117*0Sstevel@tonic-gate int tsy, bsy, idn, dir, nomore;
118*0Sstevel@tonic-gate IDST *ip, *ep, *eip;
119*0Sstevel@tonic-gate
120*0Sstevel@tonic-gate cy = curscr->_cury;
121*0Sstevel@tonic-gate cx = curscr->_curx;
122*0Sstevel@tonic-gate didcsr = FALSE;
123*0Sstevel@tonic-gate
124*0Sstevel@tonic-gate /* first cycle do deletions, second cycle do insertions */
125*0Sstevel@tonic-gate for (dir = 1; dir > -2; dir -= 2) {
126*0Sstevel@tonic-gate if (dir > 0) {
127*0Sstevel@tonic-gate ip = sid;
128*0Sstevel@tonic-gate eip = eid;
129*0Sstevel@tonic-gate } else {
130*0Sstevel@tonic-gate ip = eid - 1;
131*0Sstevel@tonic-gate eip = sid - 1;
132*0Sstevel@tonic-gate }
133*0Sstevel@tonic-gate
134*0Sstevel@tonic-gate nomore = TRUE;
135*0Sstevel@tonic-gate while (ip != eip) {
136*0Sstevel@tonic-gate /* skip deletions or insertions */
137*0Sstevel@tonic-gate if ((dir > 0 && ip->_wy > ip->_sy) ||
138*0Sstevel@tonic-gate (dir < 0 && ip->_wy < ip->_sy)) {
139*0Sstevel@tonic-gate nomore = FALSE;
140*0Sstevel@tonic-gate ip += dir;
141*0Sstevel@tonic-gate continue;
142*0Sstevel@tonic-gate }
143*0Sstevel@tonic-gate
144*0Sstevel@tonic-gate /* find a contiguous block */
145*0Sstevel@tonic-gate for (ep = ip+dir; ep != eip; ep += dir)
146*0Sstevel@tonic-gate if (ep->_wy != (ep - dir)->_wy + dir ||
147*0Sstevel@tonic-gate ep->_sy != (ep - dir)->_sy + dir) {
148*0Sstevel@tonic-gate break;
149*0Sstevel@tonic-gate }
150*0Sstevel@tonic-gate ep -= dir;
151*0Sstevel@tonic-gate
152*0Sstevel@tonic-gate /* top and bottom lines of the affected region */
153*0Sstevel@tonic-gate if (dir > 0) {
154*0Sstevel@tonic-gate tsy = _MIN(ip->_wy, ip->_sy);
155*0Sstevel@tonic-gate bsy = _MAX(ep->_wy, ep->_sy) + 1;
156*0Sstevel@tonic-gate } else {
157*0Sstevel@tonic-gate tsy = _MIN(ep->_wy, ep->_sy);
158*0Sstevel@tonic-gate bsy = _MAX(ip->_wy, ip->_sy) + 1;
159*0Sstevel@tonic-gate }
160*0Sstevel@tonic-gate
161*0Sstevel@tonic-gate /* amount to insert/delete */
162*0Sstevel@tonic-gate if ((idn = ip->_wy - ip->_sy) < 0)
163*0Sstevel@tonic-gate idn = -idn;
164*0Sstevel@tonic-gate
165*0Sstevel@tonic-gate /* do the actual output */
166*0Sstevel@tonic-gate _do_idln(tsy, bsy, idn, dir == -1);
167*0Sstevel@tonic-gate
168*0Sstevel@tonic-gate /* update change structure */
169*0Sstevel@tonic-gate (void) wtouchln(_virtscr, tsy, bsy - tsy, -1);
170*0Sstevel@tonic-gate
171*0Sstevel@tonic-gate /* update screen image */
172*0Sstevel@tonic-gate /*LINTED*/
173*0Sstevel@tonic-gate curscr->_tmarg = (short)tsy;
174*0Sstevel@tonic-gate curscr->_bmarg = bsy - 1;
175*0Sstevel@tonic-gate /*LINTED*/
176*0Sstevel@tonic-gate curscr->_cury = (short)tsy;
177*0Sstevel@tonic-gate (void) winsdelln(curscr, dir > 0 ? -idn : idn);
178*0Sstevel@tonic-gate curscr->_tmarg = 0;
179*0Sstevel@tonic-gate curscr->_bmarg = scrli - 1;
180*0Sstevel@tonic-gate
181*0Sstevel@tonic-gate /* for next while cycle */
182*0Sstevel@tonic-gate ip = ep + dir;
183*0Sstevel@tonic-gate }
184*0Sstevel@tonic-gate
185*0Sstevel@tonic-gate if (nomore)
186*0Sstevel@tonic-gate break;
187*0Sstevel@tonic-gate }
188*0Sstevel@tonic-gate
189*0Sstevel@tonic-gate /* reset scrolling region */
190*0Sstevel@tonic-gate if (didcsr) {
191*0Sstevel@tonic-gate _PUTS(tparm_p2(change_scroll_region, 0, scrli - 1), scrli);
192*0Sstevel@tonic-gate cy = cx = -1;
193*0Sstevel@tonic-gate }
194*0Sstevel@tonic-gate
195*0Sstevel@tonic-gate /*LINTED*/
196*0Sstevel@tonic-gate curscr->_cury = (short)cy;
197*0Sstevel@tonic-gate /*LINTED*/
198*0Sstevel@tonic-gate curscr->_curx = (short)cx;
199*0Sstevel@tonic-gate return (OK);
200*0Sstevel@tonic-gate }
201*0Sstevel@tonic-gate
202*0Sstevel@tonic-gate /* Do the actual insert/delete lines */
203*0Sstevel@tonic-gate
204*0Sstevel@tonic-gate static void
_do_idln(int tsy,int bsy,int idn,int doinsert)205*0Sstevel@tonic-gate _do_idln(int tsy, int bsy, int idn, int doinsert)
206*0Sstevel@tonic-gate {
207*0Sstevel@tonic-gate int y, usecsr, yesscrl;
208*0Sstevel@tonic-gate short *begns;
209*0Sstevel@tonic-gate
210*0Sstevel@tonic-gate /* change scrolling region */
211*0Sstevel@tonic-gate yesscrl = usecsr = FALSE;
212*0Sstevel@tonic-gate if (tsy > 0 || bsy < scrli) {
213*0Sstevel@tonic-gate if (change_scroll_region) {
214*0Sstevel@tonic-gate _PUTS(tparm_p2(change_scroll_region, tsy, bsy - 1),
215*0Sstevel@tonic-gate bsy - tsy);
216*0Sstevel@tonic-gate cy = cx = -1;
217*0Sstevel@tonic-gate yesscrl = usecsr = didcsr = TRUE;
218*0Sstevel@tonic-gate }
219*0Sstevel@tonic-gate } else {
220*0Sstevel@tonic-gate if (didcsr) {
221*0Sstevel@tonic-gate _PUTS(tparm_p2(change_scroll_region, 0, scrli - 1), scrli);
222*0Sstevel@tonic-gate cy = cx = -1;
223*0Sstevel@tonic-gate didcsr = FALSE;
224*0Sstevel@tonic-gate }
225*0Sstevel@tonic-gate yesscrl = TRUE;
226*0Sstevel@tonic-gate }
227*0Sstevel@tonic-gate
228*0Sstevel@tonic-gate if (doinsert) {
229*0Sstevel@tonic-gate /* memory below, clobber it now */
230*0Sstevel@tonic-gate if (memory_below && clr_eol &&
231*0Sstevel@tonic-gate ((usecsr && non_dest_scroll_region) || bsy == scrli)) {
232*0Sstevel@tonic-gate for (y = bsy - idn, begns = _BEGNS + y;
233*0Sstevel@tonic-gate y < bsy; ++y, ++begns)
234*0Sstevel@tonic-gate if (*begns < scrco) {
235*0Sstevel@tonic-gate (void) mvcur(cy, cx, y, 0);
236*0Sstevel@tonic-gate cy = y;
237*0Sstevel@tonic-gate cx = 0;
238*0Sstevel@tonic-gate _PUTS(clr_eol, 1);
239*0Sstevel@tonic-gate }
240*0Sstevel@tonic-gate }
241*0Sstevel@tonic-gate
242*0Sstevel@tonic-gate /* if not change_scroll_region, delete, then insert */
243*0Sstevel@tonic-gate if (!usecsr && bsy < scrli) {
244*0Sstevel@tonic-gate /* delete appropriate number of lines */
245*0Sstevel@tonic-gate (void) mvcur(cy, cx, bsy - idn, 0);
246*0Sstevel@tonic-gate cy = bsy - idn;
247*0Sstevel@tonic-gate cx = 0;
248*0Sstevel@tonic-gate if (parm_delete_line && (idn > 1 || !delete_line))
249*0Sstevel@tonic-gate _PUTS(tparm_p1(parm_delete_line, idn),
250*0Sstevel@tonic-gate scrli - cy);
251*0Sstevel@tonic-gate else
252*0Sstevel@tonic-gate for (y = 0; y < idn; ++y)
253*0Sstevel@tonic-gate _PUTS(delete_line, scrli - cy);
254*0Sstevel@tonic-gate }
255*0Sstevel@tonic-gate
256*0Sstevel@tonic-gate /* now do insert */
257*0Sstevel@tonic-gate (void) mvcur(cy, cx, tsy, 0);
258*0Sstevel@tonic-gate cy = tsy;
259*0Sstevel@tonic-gate cx = 0;
260*0Sstevel@tonic-gate if (yesscrl) {
261*0Sstevel@tonic-gate if (!parm_rindex && (!scroll_reverse ||
262*0Sstevel@tonic-gate (parm_insert_line && idn > 1))) {
263*0Sstevel@tonic-gate goto hardinsert;
264*0Sstevel@tonic-gate }
265*0Sstevel@tonic-gate if (parm_rindex && (idn > 1 || !scroll_reverse))
266*0Sstevel@tonic-gate _PUTS(tparm_p1(parm_rindex, idn), scrli - cy);
267*0Sstevel@tonic-gate else
268*0Sstevel@tonic-gate for (y = 0; y < idn; ++y)
269*0Sstevel@tonic-gate _PUTS(scroll_reverse, scrli - cy);
270*0Sstevel@tonic-gate } else {
271*0Sstevel@tonic-gate hardinsert:
272*0Sstevel@tonic-gate if (parm_insert_line && (idn > 1 || !insert_line))
273*0Sstevel@tonic-gate _PUTS(tparm_p1(parm_insert_line, idn),
274*0Sstevel@tonic-gate scrli - cy);
275*0Sstevel@tonic-gate else
276*0Sstevel@tonic-gate for (y = 0; y < idn; ++y)
277*0Sstevel@tonic-gate _PUTS(insert_line, scrli - cy);
278*0Sstevel@tonic-gate }
279*0Sstevel@tonic-gate } else {
280*0Sstevel@tonic-gate /* doing deletion */
281*0Sstevel@tonic-gate /* memory above, clobber it now */
282*0Sstevel@tonic-gate if (memory_above && clr_eol &&
283*0Sstevel@tonic-gate ((usecsr && non_dest_scroll_region) || tsy == 0)) {
284*0Sstevel@tonic-gate for (y = 0, begns = _BEGNS + y + tsy;
285*0Sstevel@tonic-gate y < idn; ++y, ++begns)
286*0Sstevel@tonic-gate if (*begns < scrco) {
287*0Sstevel@tonic-gate (void) mvcur(cy, cx, tsy + y, 0);
288*0Sstevel@tonic-gate cy = tsy + y;
289*0Sstevel@tonic-gate cx = 0;
290*0Sstevel@tonic-gate _PUTS(clr_eol, 1);
291*0Sstevel@tonic-gate }
292*0Sstevel@tonic-gate }
293*0Sstevel@tonic-gate
294*0Sstevel@tonic-gate if (yesscrl) {
295*0Sstevel@tonic-gate if (!parm_index && (!scroll_forward ||
296*0Sstevel@tonic-gate (parm_delete_line && idn > 1))) {
297*0Sstevel@tonic-gate goto harddelete;
298*0Sstevel@tonic-gate }
299*0Sstevel@tonic-gate (void) mvcur(cy, cx, bsy - 1, 0);
300*0Sstevel@tonic-gate cy = bsy - 1;
301*0Sstevel@tonic-gate cx = 0;
302*0Sstevel@tonic-gate if (parm_index && (idn > 1 || !scroll_forward))
303*0Sstevel@tonic-gate _PUTS(tparm_p1(parm_index, idn), scrli - cy);
304*0Sstevel@tonic-gate else
305*0Sstevel@tonic-gate for (y = 0; y < idn; ++y)
306*0Sstevel@tonic-gate _PUTS(scroll_forward, scrli - cy);
307*0Sstevel@tonic-gate } else {
308*0Sstevel@tonic-gate harddelete:
309*0Sstevel@tonic-gate /* do deletion */
310*0Sstevel@tonic-gate (void) mvcur(cy, cx, tsy, 0);
311*0Sstevel@tonic-gate cy = tsy;
312*0Sstevel@tonic-gate cx = 0;
313*0Sstevel@tonic-gate if (parm_delete_line && (idn > 1 || !delete_line))
314*0Sstevel@tonic-gate _PUTS(tparm_p1(parm_delete_line, idn),
315*0Sstevel@tonic-gate scrli - cy);
316*0Sstevel@tonic-gate else
317*0Sstevel@tonic-gate for (y = 0; y < idn; ++y)
318*0Sstevel@tonic-gate _PUTS(delete_line, scrli - cy);
319*0Sstevel@tonic-gate }
320*0Sstevel@tonic-gate
321*0Sstevel@tonic-gate /* if not change_scroll_region, do insert to restore bottom */
322*0Sstevel@tonic-gate if (!usecsr && bsy < scrli) {
323*0Sstevel@tonic-gate y = scrli - 1;
324*0Sstevel@tonic-gate begns = _BEGNS + y;
325*0Sstevel@tonic-gate for (; y >= bsy; --y, --begns)
326*0Sstevel@tonic-gate if (*begns < scrco)
327*0Sstevel@tonic-gate break;
328*0Sstevel@tonic-gate if (y >= bsy) {
329*0Sstevel@tonic-gate (void) mvcur(cy, cx, bsy - idn, 0);
330*0Sstevel@tonic-gate cy = bsy - idn;
331*0Sstevel@tonic-gate cx = 0;
332*0Sstevel@tonic-gate if (parm_insert_line &&
333*0Sstevel@tonic-gate (idn > 1 || !insert_line))
334*0Sstevel@tonic-gate _PUTS(tparm_p1(parm_insert_line, idn),
335*0Sstevel@tonic-gate scrli - cy);
336*0Sstevel@tonic-gate else
337*0Sstevel@tonic-gate for (y = 0; y < idn; ++y)
338*0Sstevel@tonic-gate _PUTS(insert_line, scrli - cy);
339*0Sstevel@tonic-gate }
340*0Sstevel@tonic-gate }
341*0Sstevel@tonic-gate }
342*0Sstevel@tonic-gate }
343