/* $Log: pslide.c,v $ /* Revision 1.1.1.1 2000/12/16 20:45:29 stuart /* Released TUIPeer sources /* */ #include #include "hackterm.h" static void swaprow(int c1,int c2,int r1,int r2) { int c; CHTYPE *cp1, *cp2; struct rowdata p, *p1, *p2; p1 = &curscr->d[r1]; p2 = &curscr->d[r2]; p = *p1; *p1 = *p2; *p2 = p; p2->srow = -1; /* will erase line */ p2->modc = 0; cp1 = curscr->data + p1->data; cp2 = curscr->data + p2->data; for (c = c2;;) { CHTYPE ch; if (++c >= PScols) c = 0; if (c == c1) break; if (cp1[c] == cp2[c]) continue; ch = cp1[c]; cp1[c] = cp2[c] | A_MODIFIED; if (c < p1->modc) p1->modc = c; cp2[c] = ch | A_MODIFIED; } } static void moverow(int c1,int c2,int r1,int r2) { int c; CHTYPE *cp1, *cp2; struct rowdata *p; p = &curscr->d[r1]; cp1 = curscr->data + p->data; cp2 = curscr->data + curscr->d[r2].data; for (c = c1; c <= c2; ++c) { if (cp1[c] != cp2[c]) { cp1[c] = cp2[c] | A_MODIFIED; if (c < p->modc) p->modc = c; } } } bool PSslide(const RECT *sr,enum dir dir,int dist) { RECT r; int i; static int caninsdel = -1; if (!clip(sr,PSrows,PScols,&r) || dist == 0) return TRUE; if (caninsdel < 0) caninsdel = ((parm_insert_line||insert_line) && (parm_delete_line||delete_line)) ? 1 : 0; switch (dir) { case DIR_UP: dist = -dist; case DIR_DOWN: if (dist < 0) { i = r.r1; if (i + dist < 0) i = -dist; if (caninsdel && RWIDTH(&r) > PScols/2) { while (i <= r.r2) { swaprow(r.c1,r.c2,i + dist,i); ++i; } i += dist; while (i <= r.r1) { /* middle lines wiped */ int j; struct rowdata *p = &curscr->d[i]; CHTYPE *cp = curscr->data + p->data; p->modc = 0; p->srow = -1; for (j = 0; j < PScols; ++j) cp[j] |= A_MODIFIED; ++i; } } else while (i <= r.r2) { moverow(r.c1,r.c2,i + dist,i); ++i; } } else { i = r.r2; if (i + dist >= PSrows) i = PSrows - 1 - dist; if (caninsdel && RWIDTH(&r) > PScols/2) { while (i >= r.r1) { swaprow(r.c1,r.c2,i + dist,i); --i; } i += dist; while (i >= r.r2) { /* middle lines wiped */ int j; struct rowdata *p = &curscr->d[i]; CHTYPE *cp = curscr->data + p->data; p->modc = 0; p->srow = -1; for (j = 0; j < PScols; ++j) cp[j] |= A_MODIFIED; --i; } } else while (i >= r.r1) { moverow(r.c1,r.c2,i + dist,i); --i; } } return TRUE; case DIR_LEFT: dist = -dist; case DIR_RIGHT: /* ins/del char not used yet */ for (i = r.r1; i <= r.r2; ++i) { int c; struct rowdata *p = &curscr->d[i]; CHTYPE *cp = curscr->data + p->data; if (dist < 0) { c = r.c1; if (c + dist < 0) c = -dist; while (c <= r.c2) { if (cp[c] != cp[c + dist]) { cp[c + dist] = cp[c] | A_MODIFIED; if (c + dist < p->modc) p->modc = c + dist; } ++c; } } else { c = r.c2; if (c + dist >= PScols) c = dist - PScols + 1; while (c >= r.c1) { if (cp[c] != cp[c + dist]) { cp[c + dist] = cp[c] | A_MODIFIED; if (c + dist < p->modc) p->modc = c + dist; } --c; } } } return TRUE; case DIR_NONE: break; } return FALSE; }