#include <stdlib.h>
#include "curses_inc.h"
#define scrco COLS
typedef struct
{
int _wy,
_sy;
} IDST;
static IDST *sid, *eid;
static int scrli,
cy, cx;
static bool didcsr;
static int _use_idln(void), _set_idln(void);
static void _do_idln(int, int, int, int);
int
idlok(WINDOW *win, bool bf)
{
_useidln = _use_idln;
_setidln = _set_idln;
SP->yesidln = (delete_line || parm_delete_line ||
(change_scroll_region && (parm_index || scroll_forward))) &&
(insert_line || parm_insert_line ||
(change_scroll_region && (parm_rindex || scroll_reverse)));
win->_use_idl = bf;
return (OK);
}
static int
_set_idln(void)
{
{
IDST *idp;
int rval = scrli;
for (idp = sid; idp != eid; idp++) {
int tmp;
if ((tmp = _MIN(idp->_wy, idp->_sy)) < rval)
rval = tmp;
}
return (rval);
}
}
static int
_use_idln(void)
{
int tsy, bsy, idn, dir, nomore;
IDST *ip, *ep, *eip;
cy = curscr->_cury;
cx = curscr->_curx;
didcsr = FALSE;
for (dir = 1; dir > -2; dir -= 2) {
if (dir > 0) {
ip = sid;
eip = eid;
} else {
ip = eid - 1;
eip = sid - 1;
}
nomore = TRUE;
while (ip != eip) {
if ((dir > 0 && ip->_wy > ip->_sy) ||
(dir < 0 && ip->_wy < ip->_sy)) {
nomore = FALSE;
ip += dir;
continue;
}
for (ep = ip+dir; ep != eip; ep += dir)
if (ep->_wy != (ep - dir)->_wy + dir ||
ep->_sy != (ep - dir)->_sy + dir) {
break;
}
ep -= dir;
if (dir > 0) {
tsy = _MIN(ip->_wy, ip->_sy);
bsy = _MAX(ep->_wy, ep->_sy) + 1;
} else {
tsy = _MIN(ep->_wy, ep->_sy);
bsy = _MAX(ip->_wy, ip->_sy) + 1;
}
if ((idn = ip->_wy - ip->_sy) < 0)
idn = -idn;
_do_idln(tsy, bsy, idn, dir == -1);
(void) wtouchln(_virtscr, tsy, bsy - tsy, -1);
curscr->_tmarg = (short)tsy;
curscr->_bmarg = bsy - 1;
curscr->_cury = (short)tsy;
(void) winsdelln(curscr, dir > 0 ? -idn : idn);
curscr->_tmarg = 0;
curscr->_bmarg = scrli - 1;
ip = ep + dir;
}
if (nomore)
break;
}
if (didcsr) {
_PUTS(tparm_p2(change_scroll_region, 0, scrli - 1), scrli);
cy = cx = -1;
}
curscr->_cury = (short)cy;
curscr->_curx = (short)cx;
return (OK);
}
static void
_do_idln(int tsy, int bsy, int idn, int doinsert)
{
int y, usecsr, yesscrl;
short *begns;
yesscrl = usecsr = FALSE;
if (tsy > 0 || bsy < scrli) {
if (change_scroll_region) {
_PUTS(tparm_p2(change_scroll_region, tsy, bsy - 1),
bsy - tsy);
cy = cx = -1;
yesscrl = usecsr = didcsr = TRUE;
}
} else {
if (didcsr) {
_PUTS(tparm_p2(change_scroll_region, 0, scrli - 1), scrli);
cy = cx = -1;
didcsr = FALSE;
}
yesscrl = TRUE;
}
if (doinsert) {
if (memory_below && clr_eol &&
((usecsr && non_dest_scroll_region) || bsy == scrli)) {
for (y = bsy - idn, begns = _BEGNS + y;
y < bsy; ++y, ++begns)
if (*begns < scrco) {
(void) mvcur(cy, cx, y, 0);
cy = y;
cx = 0;
_PUTS(clr_eol, 1);
}
}
if (!usecsr && bsy < scrli) {
(void) mvcur(cy, cx, bsy - idn, 0);
cy = bsy - idn;
cx = 0;
if (parm_delete_line && (idn > 1 || !delete_line))
_PUTS(tparm_p1(parm_delete_line, idn),
scrli - cy);
else
for (y = 0; y < idn; ++y)
_PUTS(delete_line, scrli - cy);
}
(void) mvcur(cy, cx, tsy, 0);
cy = tsy;
cx = 0;
if (yesscrl) {
if (!parm_rindex && (!scroll_reverse ||
(parm_insert_line && idn > 1))) {
goto hardinsert;
}
if (parm_rindex && (idn > 1 || !scroll_reverse))
_PUTS(tparm_p1(parm_rindex, idn), scrli - cy);
else
for (y = 0; y < idn; ++y)
_PUTS(scroll_reverse, scrli - cy);
} else {
hardinsert:
if (parm_insert_line && (idn > 1 || !insert_line))
_PUTS(tparm_p1(parm_insert_line, idn),
scrli - cy);
else
for (y = 0; y < idn; ++y)
_PUTS(insert_line, scrli - cy);
}
} else {
if (memory_above && clr_eol &&
((usecsr && non_dest_scroll_region) || tsy == 0)) {
for (y = 0, begns = _BEGNS + y + tsy;
y < idn; ++y, ++begns)
if (*begns < scrco) {
(void) mvcur(cy, cx, tsy + y, 0);
cy = tsy + y;
cx = 0;
_PUTS(clr_eol, 1);
}
}
if (yesscrl) {
if (!parm_index && (!scroll_forward ||
(parm_delete_line && idn > 1))) {
goto harddelete;
}
(void) mvcur(cy, cx, bsy - 1, 0);
cy = bsy - 1;
cx = 0;
if (parm_index && (idn > 1 || !scroll_forward))
_PUTS(tparm_p1(parm_index, idn), scrli - cy);
else
for (y = 0; y < idn; ++y)
_PUTS(scroll_forward, scrli - cy);
} else {
harddelete:
(void) mvcur(cy, cx, tsy, 0);
cy = tsy;
cx = 0;
if (parm_delete_line && (idn > 1 || !delete_line))
_PUTS(tparm_p1(parm_delete_line, idn),
scrli - cy);
else
for (y = 0; y < idn; ++y)
_PUTS(delete_line, scrli - cy);
}
if (!usecsr && bsy < scrli) {
y = scrli - 1;
begns = _BEGNS + y;
for (; y >= bsy; --y, --begns)
if (*begns < scrco)
break;
if (y >= bsy) {
(void) mvcur(cy, cx, bsy - idn, 0);
cy = bsy - idn;
cx = 0;
if (parm_insert_line &&
(idn > 1 || !insert_line))
_PUTS(tparm_p1(parm_insert_line, idn),
scrli - cy);
else
for (y = 0; y < idn; ++y)
_PUTS(insert_line, scrli - cy);
}
}
}
}