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, June 5, 1985 12:22:47 pm PDT
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
MyGraphicRef: TYPE = CDVPrivate.MyGraphicRef;
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] =
--teaches SetCursorMode to call proc if mode mode is set
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: MyGraphicRef, 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: MyGraphicRef] =
BEGIN
--probably this will be overwritten by a client
END;
UseDefaultCursor: CDVPrivate.CursorModeProc = {
me.designRec.outlineProcLC ← DefaultCursor
};
InvertArea: PUBLIC PROC[me: MyGraphicRef, x1, y1, x2, y2: INT] =
--x1, y1, x2, y2 in viewers coordinates; inverts all the border points
TRUSTED BEGIN
ENABLE RuntimeError.UNCAUGHT => {
IF CDVPrivate.catchAnyWhichDeadlock THEN GOTO SomeError ELSE REJECT;
};
xBit: CARDINAL;
xc1: CARDINALMIN[MAX[x1, 0], LONG[me.viewer.cw-1]];
yc1: CARDINALMIN[MAX[y1, 0], LONG[me.viewer.ch-1]];
xc2: CARDINALMIN[MAX[x2, 0], LONG[me.viewer.cw-1]];
yc2: CARDINALMIN[MAX[y2, 0], 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; --IF coordSys=top THEN yc1+me.vy ELSE 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; -- cursoring is monitored; no drawing!
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 BEGIN
PrincOpsUtils.BITBLT[me.xBBptr];
END;
Terminal.ModifyColorFrame[vt: virtual,
action: Blit,
xmin: xc1+me.vx,
ymin: yc1,
xmax: xc2+me.vx+1,
ymax: yc1+me.xBBptr.height
];
};
EXITS
SomeError => NULL;
END;
END.