mirror of
https://github.com/ctm/executor.git
synced 2024-09-25 22:56:22 +00:00
411 lines
12 KiB
C
411 lines
12 KiB
C
/* Copyright 1989 - 2000 by Abacus Research and
|
|
* Development, Inc. All rights reserved.
|
|
*/
|
|
|
|
#if !defined (OMIT_RCSID_STRINGS)
|
|
char ROMlib_rcsid_listAddDel[] =
|
|
"$Id: listAddDel.c 74 2004-12-30 03:38:55Z ctm $";
|
|
#endif
|
|
|
|
/* Forward declarations in ListMgr.h (DO NOT DELETE THIS LINE) */
|
|
|
|
#include "rsys/common.h"
|
|
#include "ListMgr.h"
|
|
#include "MemoryMgr.h"
|
|
#include "rsys/list.h"
|
|
|
|
P3(PUBLIC pascal trap, INTEGER, LAddColumn, INTEGER, count, /* IMIV-271 */
|
|
INTEGER, coln, ListHandle, list)
|
|
{
|
|
Rect todraw;
|
|
Cell c;
|
|
INTEGER ncols, nrows, noffsets, offset;
|
|
Size nbefore, nafter;
|
|
Ptr ip, op;
|
|
int i;
|
|
Point p;
|
|
|
|
nrows = Hx(list, dataBounds.bottom) - Hx(list, dataBounds.top);
|
|
noffsets = count * nrows;
|
|
if (coln > Hx(list, dataBounds.right))
|
|
coln = Hx(list, dataBounds.right);
|
|
|
|
if (coln < Hx(list, dataBounds.left))
|
|
coln = Hx(list, dataBounds.left);
|
|
|
|
HxX(list, dataBounds.right) = CW(Hx(list, dataBounds.right) + count);
|
|
|
|
if (noffsets) {
|
|
TRAPBEGIN();
|
|
SetHandleSize((Handle) list,
|
|
GetHandleSize((Handle) list) + noffsets * sizeof(INTEGER));
|
|
ncols = Hx(list, dataBounds.right) - Hx(list, dataBounds.left);
|
|
nbefore = (coln - Hx(list, dataBounds.left)) * sizeof(INTEGER);
|
|
nafter = (ncols - count) * sizeof(INTEGER) - nbefore;
|
|
ip = (Ptr) (HxX(list, cellArray) + nrows * (ncols - count) + 1);
|
|
op = (Ptr) (HxX(list, cellArray) + nrows * ncols + 1);
|
|
op -= sizeof(INTEGER);
|
|
ip -= sizeof(INTEGER);
|
|
*(INTEGER *)op = *(INTEGER *)ip; /* sentinel */
|
|
/* SPEEDUP: merge the two BlockMoves ... (unroll begining and end) */
|
|
while (--nrows >= 0) {
|
|
ip -= nafter;
|
|
op -= nafter;
|
|
BlockMove(ip, op, nafter);
|
|
offset = CW(*(INTEGER *)op) & 0x7FFF;
|
|
for (i = 0; ++i <= count; )
|
|
{
|
|
op -= sizeof(INTEGER);
|
|
*(INTEGER *)op = CW(offset);
|
|
}
|
|
ip -= nbefore;
|
|
op -= nbefore;
|
|
BlockMove(ip, op, nbefore);
|
|
}
|
|
|
|
p.h = Hx(list, cellSize.h);
|
|
p.v = Hx(list, cellSize.v);
|
|
C_LCellSize(p, list); /* recalcs visible */
|
|
|
|
if (Hx(list, listFlags) & DODRAW) {
|
|
todraw = HxX(list, dataBounds);
|
|
todraw.left = CW(coln);
|
|
SectRect(&todraw, &HxX(list, visible), &todraw);
|
|
for (c.v = CW(todraw.top) ; c.v < CW(todraw.bottom); c.v++)
|
|
for (c.h = CW(todraw.left) ; c.h < CW(todraw.right); c.h++)
|
|
C_LDraw(c, list);
|
|
}
|
|
TRAPEND();
|
|
}
|
|
return coln;
|
|
}
|
|
|
|
P3(PUBLIC pascal trap, INTEGER, LAddRow, INTEGER, count, /* IMIV-271 */
|
|
INTEGER, rown, ListHandle, list)
|
|
{
|
|
Rect todraw;
|
|
Cell c;
|
|
INTEGER ncols, nrows, noffsets, offset;
|
|
Size nbefore, nafter;
|
|
INTEGER *ip, *op;
|
|
Point p;
|
|
|
|
ncols = Hx(list, dataBounds.right) - Hx(list, dataBounds.left);
|
|
noffsets = count * ncols;
|
|
if (rown > Hx(list, dataBounds.bottom))
|
|
rown = Hx(list, dataBounds.bottom);
|
|
|
|
if (rown < Hx(list, dataBounds.top))
|
|
rown = Hx(list, dataBounds.top);
|
|
|
|
HxX(list, dataBounds.bottom) = CW(Hx(list, dataBounds.bottom) + count);
|
|
|
|
if (noffsets) {
|
|
TRAPBEGIN();
|
|
SetHandleSize((Handle) list,
|
|
GetHandleSize((Handle) list) + noffsets * sizeof(INTEGER));
|
|
nrows = Hx(list, dataBounds.bottom) - Hx(list, dataBounds.top);
|
|
nbefore = (rown - Hx(list, dataBounds.top));
|
|
nafter = ((nrows - count) - nbefore) * ncols;
|
|
ip = HxX(list, cellArray) + (nrows - count) * ncols + 1;
|
|
op = HxX(list, cellArray) + nrows * ncols + 1;
|
|
*--op = *--ip; /* sentinel */
|
|
ip -= nafter;
|
|
op -= nafter;
|
|
offset = CW(*ip) & 0x7FFF;
|
|
BlockMove((Ptr) ip, (Ptr) op, nafter * sizeof(INTEGER));
|
|
/* move the after rows */
|
|
while (--noffsets >= 0)
|
|
*--op = CW(offset);
|
|
|
|
p.h = Hx(list, cellSize.h);
|
|
p.v = Hx(list, cellSize.v);
|
|
C_LCellSize(p, list); /* recalcs visible */
|
|
|
|
if (Hx(list, listFlags) & DODRAW) {
|
|
todraw = HxX(list, dataBounds);
|
|
todraw.top = CW(rown);
|
|
SectRect(&todraw, &HxX(list, visible), &todraw);
|
|
for (c.v = CW(todraw.top) ; c.v < CW(todraw.bottom); c.v++)
|
|
for (c.h = CW(todraw.left) ; c.h < CW(todraw.right); c.h++)
|
|
C_LDraw(c, list);
|
|
}
|
|
TRAPEND();
|
|
}
|
|
return rown;
|
|
}
|
|
|
|
PRIVATE void
|
|
compute_visible_rect (Rect *rp, ListHandle list, INTEGER top, INTEGER left,
|
|
INTEGER bottom, INTEGER right)
|
|
{
|
|
INTEGER h, v;
|
|
INTEGER new_top, new_left, new_bottom, new_right;
|
|
|
|
h = Hx (list, cellSize.h);
|
|
v = Hx (list, cellSize.v);
|
|
|
|
new_top = Hx (list, rView.top ) + (top - Hx (list, visible.top )) * v;
|
|
new_left = Hx (list, rView.left) + (left - Hx (list, visible.left)) * h;
|
|
new_bottom = new_top + (bottom - top ) * v;
|
|
new_right = new_left + (right - left) * h;
|
|
|
|
rp->top = CW (new_top);
|
|
rp->left = CW (new_left);
|
|
rp->bottom = CW (new_bottom);
|
|
rp->right = CW (new_right);
|
|
|
|
SectRect (rp, &HxX (list, rView), rp);
|
|
}
|
|
|
|
P3(PUBLIC pascal trap, void, LDelColumn, INTEGER, count, /* IMIV-271 */
|
|
INTEGER, coln, ListHandle, list)
|
|
{
|
|
Rect todraw;
|
|
Cell c;
|
|
INTEGER ncols, nrows, noffsets, delta;
|
|
Size nbefore, nafter, ntomove;
|
|
unsigned short int *ip, *op; /* unsigned INTEGER */
|
|
Ptr dataip, dataop;
|
|
INTEGER off1, off2, off3, off4, off5;
|
|
int i;
|
|
ControlHandle control;
|
|
Point p;
|
|
|
|
if (!list || coln >= Hx(list, dataBounds.right))
|
|
/*-->*/ return; /* invalid */
|
|
|
|
if (count == 0 || (coln == Hx(list, dataBounds.left) &&
|
|
count >= Hx(list, dataBounds.right) - Hx(list, dataBounds.left))) {
|
|
SetHandleSize((Handle) HxP(list, cells), (Size) 0);
|
|
SetHandleSize((Handle) list, sizeof(ListRec));
|
|
HxX(list, cellArray)[0] = 0;
|
|
HxX(list, dataBounds.right) = HxX(list, dataBounds.left);
|
|
HxX(list, visible.left) = HxX(list, dataBounds.left);
|
|
p.h = Hx(list, cellSize.h);
|
|
p.v = Hx(list, cellSize.v);
|
|
C_LCellSize(p, list); /* recalcs visible */
|
|
if (Hx(list, listFlags) & DODRAW)
|
|
EraseRect(&HxX(list, rView));
|
|
if ((control = HxP(list, hScroll)))
|
|
SetCtlMax(control, Hx(control, contrlMin));
|
|
/*-->*/ return; /* quick delete of everything */
|
|
}
|
|
|
|
if (coln + count > Hx(list, dataBounds.right))
|
|
count = Hx(list, dataBounds.right) - coln;
|
|
|
|
nrows = Hx(list, dataBounds.bottom) - Hx(list, dataBounds.top);
|
|
noffsets = count * nrows;
|
|
if (coln > Hx(list, dataBounds.right))
|
|
coln = Hx(list, dataBounds.right);
|
|
|
|
HxX(list, dataBounds.right) = CW(Hx(list, dataBounds.right) - count);
|
|
|
|
if (noffsets) {
|
|
INTEGER visible_right, bounds_right;
|
|
|
|
TRAPBEGIN();
|
|
ncols = Hx(list, dataBounds.right) - Hx(list, dataBounds.left);
|
|
nbefore = (coln - Hx(list, dataBounds.left));
|
|
nafter = ncols - nbefore;
|
|
ip = op = (unsigned short int *) HxX(list, cellArray);
|
|
dataip = dataop = (Ptr) STARH(HxP(list, cells));
|
|
delta = 0;
|
|
/* SPEEDUP: partial loop unrolling ... combine things and don't
|
|
bother adding delta when we know that it's zero */
|
|
while (--nrows >= 0) {
|
|
off1 = CW(*ip) & 0x7FFF;
|
|
for (i = nbefore; --i >= 0; ) /* copy before-offsets */
|
|
*op++ = CW(CW(*ip++) - delta);
|
|
|
|
off2 = CW(*ip) & 0x7FFF;
|
|
ntomove = off2 - off1;
|
|
BlockMove(dataip, dataop, ntomove); /* copy before-data */
|
|
dataip += ntomove;
|
|
dataop += ntomove;
|
|
|
|
ip += count; /* skip count offsets */
|
|
|
|
off3 = CW(*ip) & 0x7FFF;
|
|
ntomove = off3 - off2;
|
|
dataip += ntomove; /* skip appropriate data */
|
|
delta += ntomove; /* note this */
|
|
|
|
off4 = CW(*ip) & 0x7FFF;
|
|
for (i = nafter; --i >= 0; ) /* copy after-offsets */
|
|
*op++ = CW(CW(*ip++) - delta);
|
|
|
|
off5 = CW(*ip) & 0x7FFF;
|
|
ntomove = off5 - off4;
|
|
BlockMove(dataip, dataop, ntomove); /* copy before-data */
|
|
dataip += ntomove;
|
|
dataop += ntomove;
|
|
}
|
|
*op++ = CW(CW(*ip++) - delta); /* sentinel */
|
|
SetHandleSize((Handle) list,
|
|
GetHandleSize((Handle) list) - noffsets * sizeof(INTEGER));
|
|
SetHandleSize((Handle) HxP(list, cells),
|
|
GetHandleSize((Handle) HxP(list, cells)) - delta);
|
|
|
|
p.h = Hx(list, cellSize.h);
|
|
p.v = Hx(list, cellSize.v);
|
|
|
|
|
|
/* save visible_right and bounds_right now, because LCellSize
|
|
will adjust them and we won't be able to figure out if we
|
|
needed to force a scroll */
|
|
|
|
visible_right = Hx(list, visible.right);
|
|
bounds_right = Hx(list, dataBounds.right);
|
|
C_LCellSize(p, list); /* recalcs visible */
|
|
if ((control = HxP(list, hScroll))) {
|
|
INTEGER visible_left;
|
|
|
|
visible_left = Hx(list, visible.left);
|
|
|
|
/* Determine whether or not we need to scroll up one location
|
|
(because we were maximally scrolled down and we deleted
|
|
something that was visible) */
|
|
|
|
if (visible_left > 0 && visible_right > bounds_right) {
|
|
--visible_left;
|
|
HxX(list, visible.left) = CW (visible_left);
|
|
coln = visible_left;
|
|
}
|
|
}
|
|
|
|
if (Hx(list, listFlags) & DODRAW) {
|
|
Rect eraser;
|
|
|
|
compute_visible_rect (&eraser, list, Hx (list, visible.top),
|
|
Hx (list, visible.right),
|
|
Hx (list, visible.bottom),
|
|
visible_right);
|
|
EraseRect (&eraser);
|
|
|
|
todraw = HxX(list, dataBounds);
|
|
todraw.left = CW(coln);
|
|
SectRect(&todraw, &HxX(list, visible), &todraw);
|
|
for (c.v = CW(todraw.top) ; c.v < CW(todraw.bottom); c.v++)
|
|
for (c.h = CW(todraw.left) ; c.h < CW(todraw.right); c.h++)
|
|
C_LDraw(c, list);
|
|
}
|
|
TRAPEND();
|
|
}
|
|
}
|
|
|
|
P3(PUBLIC pascal trap, void, LDelRow, INTEGER, count, /* IMIV-272 */
|
|
INTEGER, rown, ListHandle, list)
|
|
{
|
|
Rect todraw;
|
|
Cell c;
|
|
INTEGER ncols, nrows, noffsets;
|
|
Size nbefore, nafter;
|
|
unsigned short int *ip, *op;
|
|
ControlHandle control;
|
|
INTEGER off1, off2, off3;
|
|
Size delta, ntomove;
|
|
Point p;
|
|
|
|
if (!list || rown >= Hx(list, dataBounds.bottom))
|
|
/*-->*/ return; /* invalid */
|
|
|
|
if (count == 0 || (rown == Hx(list, dataBounds.top) &&
|
|
count >= Hx(list, dataBounds.bottom) - Hx(list, dataBounds.top))) {
|
|
SetHandleSize((Handle) HxP(list, cells), (Size) 0);
|
|
SetHandleSize((Handle) list, sizeof(ListRec));
|
|
HxX(list, cellArray)[0] = CWC(0);
|
|
HxX(list, dataBounds.bottom) = HxX(list, dataBounds.top);
|
|
HxX(list, visible.top) = HxX(list, dataBounds.top);
|
|
p.h = Hx(list, cellSize.h);
|
|
p.v = Hx(list, cellSize.v);
|
|
C_LCellSize(p, list); /* recalcs visible */
|
|
if (Hx(list, listFlags) & DODRAW)
|
|
EraseRect(&HxX(list, rView));
|
|
if ((control = HxP(list, vScroll)))
|
|
SetCtlMax(control, Hx(control, contrlMin));
|
|
/*-->*/ return; /* quick delete of all */
|
|
}
|
|
|
|
if (rown + count > Hx(list, dataBounds.bottom))
|
|
count = Hx(list, dataBounds.bottom) - rown;
|
|
|
|
ncols = Hx(list, dataBounds.right) - Hx(list, dataBounds.left);
|
|
noffsets = count * ncols;
|
|
|
|
HxX(list, dataBounds.bottom) = CW(Hx(list, dataBounds.bottom) - count);
|
|
|
|
if (noffsets) {
|
|
INTEGER visible_bottom, bounds_bottom;
|
|
|
|
TRAPBEGIN();
|
|
nrows = Hx(list, dataBounds.bottom) - Hx(list, dataBounds.top);
|
|
nbefore = (rown - Hx(list, dataBounds.top)) * ncols;
|
|
nafter = nrows * ncols - nbefore;
|
|
ip = op = (unsigned short int *) HxX(list, cellArray) + nbefore;
|
|
ip += noffsets;
|
|
off1 = CW(*op) & 0x7FFF;
|
|
off2 = CW(*ip) & 0x7FFF;
|
|
delta = off2 - off1;
|
|
|
|
while (--nafter >= 0)
|
|
*op++ = CW(CW(*ip++) - delta);
|
|
off3 = CW(*ip) & 0x7FFF;
|
|
*op = CW(CW(*ip) - delta); /* sentinel */
|
|
|
|
ntomove = off3 - off2;
|
|
BlockMove((Ptr) STARH(HxP(list, cells)) + off2,
|
|
(Ptr) STARH(HxP(list, cells)) + off1, ntomove);
|
|
|
|
SetHandleSize((Handle) list,
|
|
GetHandleSize((Handle) list) - noffsets * sizeof(INTEGER));
|
|
SetHandleSize((Handle) HxP(list, cells),
|
|
GetHandleSize((Handle) HxP(list, cells)) - delta);
|
|
|
|
p.h = Hx(list, cellSize.h);
|
|
p.v = Hx(list, cellSize.v);
|
|
|
|
/* save visible_bottom and bounds_bottom now, because LCellSize
|
|
will adjust them and we won't be able to figure out if we
|
|
needed to force a scroll */
|
|
|
|
visible_bottom = Hx(list, visible.bottom);
|
|
bounds_bottom = Hx(list, dataBounds.bottom);
|
|
C_LCellSize(p, list); /* recalcs visible */
|
|
if ((control = HxP(list, vScroll))) {
|
|
INTEGER visible_top;
|
|
|
|
visible_top = Hx(list, visible.top);
|
|
|
|
/* Determine whether or not we need to scroll up one location
|
|
(because we were maximally scrolled down and we deleted
|
|
something that was visible) */
|
|
|
|
if (visible_top > 0 && visible_bottom > bounds_bottom) {
|
|
--visible_top;
|
|
HxX(list, visible.top) = CW (visible_top);
|
|
rown = visible_top;
|
|
}
|
|
}
|
|
|
|
if (Hx(list, listFlags) & DODRAW) {
|
|
Rect eraser;
|
|
|
|
compute_visible_rect (&eraser, list, Hx (list, visible.bottom),
|
|
Hx (list, visible.left), visible_bottom,
|
|
Hx (list, visible.right));
|
|
EraseRect (&eraser);
|
|
|
|
todraw = HxX(list, dataBounds);
|
|
todraw.top = CW(rown);
|
|
SectRect(&todraw, &HxX(list, visible), &todraw);
|
|
|
|
for (c.v = CW(todraw.top) ; c.v < CW(todraw.bottom); c.v++)
|
|
for (c.h = CW(todraw.left) ; c.h < CW(todraw.right); c.h++)
|
|
C_LDraw(c, list);
|
|
}
|
|
TRAPEND();
|
|
}
|
|
}
|