CDVCursorImpl.mesa
Copyright © 1984 by Xerox Corporation. All rights reserved.
by Christian Jacobi, September 6, 1984 9:29:18 am PDT
last edited by Christian Jacobi, February 11, 1986 9:37:47 am PST
DIRECTORY
Basics USING [BITSHIFT, LongMult, bitsPerWord],
CD,
CDColors,
CDVPrivate,
CDVScale,
RuntimeError,
PrincOps,
PrincOpsUtils,
Terminal,
ViewerClasses;
CDVCursorImpl:
CEDAR
MONITOR
IMPORTS Basics, CDVPrivate, RuntimeError, PrincOpsUtils, Terminal
EXPORTS CDVPrivate =
BEGIN
VRef: TYPE = CDVPrivate.VRef;
CursorRec: TYPE = RECORD [mode: REF, doit: CDVPrivate.CursorModeProc];
CursorList: TYPE = LIST OF CursorRec;
cursorList: CursorList ←
LIST[CursorRec[mode:
NIL, doit: UseDefaultCursor]];
--never NIL; used by ImplementACursor
virtual: Terminal.Virtual = Terminal.Current[];
blackBrick: REF CDColors.Brick = NEW[CDColors.Brick←ALL[LAST[CARDINAL]]];
ImplementACursor:
PUBLIC ENTRY
PROC[mode:
ATOM, proc: CDVPrivate.CursorModeProc] =
BEGIN
--invert the order: efficiency hack: the first installed cursor is found the fastest
--cursorList is never NIL
FOR list: CursorList ← cursorList, list.rest
DO
IF list.first.mode=mode THEN {list.first.doit ← proc; EXIT}
ELSE IF list.rest=NIL THEN {list.rest ← LIST[CursorRec[mode: mode, doit: proc]]; EXIT}
ENDLOOP
END;
SetCursorMode:
PUBLIC
PROC[me: VRef, mode:
REF] =
BEGIN
FOR list: CursorList ← cursorList, list.rest
WHILE list#
NIL
DO
IF list.first.mode=mode
THEN {
list.first.doit[me, mode ! RuntimeError.UNCAUGHT => CONTINUE];
RETURN
}
ENDLOOP;
--error catch; cursorList is never NIL
cursorList.first.doit[me, NIL ! RuntimeError.UNCAUGHT => CONTINUE];
END;
DefaultCursor:
PUBLIC
PROC[me: VRef] =
BEGIN
--probably this will be overwritten by a client
END;
UseDefaultCursor: CDVPrivate.CursorModeProc = {
me.designRec.outlineProcLC ← DefaultCursor
};
InvertArea:
PUBLIC
PROC[me: VRef, x1, y1, x2, y2:
INT] =
TRUSTED BEGIN
ENABLE RuntimeError.
UNCAUGHT => {
IF CDVPrivate.catchAnyWhichDeadlock THEN GOTO oops ELSE REJECT;
};
xBit: CARDINAL;
xc1: CARDINAL ← MIN[MAX[x1, 0], LONG[me.viewer.cw-2]];
yc1: CARDINAL ← MIN[MAX[y1, 1], LONG[me.viewer.ch-1]];
xc2: CARDINAL ← MIN[MAX[x2, 0], LONG[me.viewer.cw-2]];
yc2: CARDINAL ← MIN[MAX[y2, 1], LONG[me.viewer.ch-1]];
IF xc1>xc2 THEN {t: CARDINAL=xc1; xc1←xc2; xc2←t};
IF yc1>yc2 THEN {t: CARDINAL=yc1; yc1←yc2; yc2←t};
me.xBBptr.width ← Basics.BITSHIFT[(xc2+1-xc1), me.logbpp];
me.xBBptr.height ← (yc2+1-yc1);
xBit ← Basics.BITSHIFT[(xc1+me.vx), me.logbpp];
yc1 ← me.vy-yc2;
me.xBBptr.dst ← [
me.screen
+ Basics.LongMult[yc1, me.scWidthWords]
+ LONG[(xBit/Basics.bitsPerWord)],,
xBit MOD Basics.bitsPerWord
];
me.xBBptr.flags.dstFunc ← xor;
me.xBBptr.src ← [LOOPHOLE[blackBrick, LONG POINTER],,0];
me.xBBptr.srcDesc ← PrincOps.SrcDesc[gray[PrincOps.GrayParm[
yOffset: 0,
widthMinusOne: 0, --words
heightMinusOne: 0 --lines
]]];
IF me.display=bw THEN PrincOpsUtils.BITBLT[me.xBBptr]
ELSE {
Blit:
PROC [] =
TRUSTED {
PrincOpsUtils.BITBLT[me.xBBptr];
};
Terminal.ModifyColorFrame[vt: virtual,
action: Blit,
xmin: xc1+me.vx,
ymin: yc1 ,
xmax: xc2+me.vx+1,
ymax: yc1+me.xBBptr.height
];
};
EXITS oops => NULL;
END;
END.