ViewerAbortImpl.mesa
Copyright Ó 1987 by Xerox Corporation. All rights reserved.
Eric Nickell, January 24, 1987 7:48:31 pm PST
DIRECTORY
ViewerAbort,
Interminal, Process, RefTab, Terminal, TIPUser, ViewerOps;
ViewerAbortImpl: CEDAR MONITOR
IMPORTS Interminal, Process, RefTab, Terminal, ViewerOps
EXPORTS ViewerAbort
~ BEGIN
OPEN ViewerAbort;
abortableViewers: RefTab.Ref ~ RefTab.Create[]; --Keeps LIST OF PROCESS for each viewer
CallWithAbortEnabled: PUBLIC PROC [viewer: Viewer, action: PROC] ~ {
this: PROCESS ~ LOOPHOLE[Process.GetCurrent[]];
EnableAbort: ENTRY PROC ~ {
ENABLE UNWIND => NULL;
oldList: LIST OF PROCESS ~ NARROW[RefTab.Fetch[x: abortableViewers, key: viewer].val];
newList: LIST OF PROCESS ~ CONS[this, oldList];
[] ← RefTab.Store[x: abortableViewers, key: viewer, val: newList];
};
DisableAbort: ENTRY PROC ~ {
ENABLE UNWIND => NULL;
ListWithoutThisProcess: PROC [list: LIST OF PROCESS] RETURNS [LIST OF PROCESS] ~ {
RETURN [SELECT TRUE FROM
list=NIL => NIL,
list.first=this => list.rest,   --Only remove one instance!
ENDCASE => CONS[list.first, ListWithoutThisProcess[list.rest]] --Check rest of list
]
};
oldList: LIST OF PROCESS ~ NARROW[RefTab.Fetch[x: abortableViewers, key: viewer].val];
[] ← RefTab.Store[x: abortableViewers, key: viewer, val: ListWithoutThisProcess[oldList]];
};
{
ENABLE UNWIND => DisableAbort[];
EnableAbort[];
action[];
DisableAbort[];
};
};
Abort: ENTRY PROC [viewer: Viewer] ~ {
ENABLE UNWIND => NULL;
list: LIST OF PROCESS ~ NARROW[RefTab.Fetch[x: abortableViewers, key: viewer].val];
FOR each: LIST OF PROCESS ← list, each.rest UNTIL each=NIL DO
TRUSTED {Process.Abort[each.first]};
ENDLOOP;
[] ← RefTab.Store[x: abortableViewers, key: viewer, val: NIL]; --Don't hit 'em again
};
CheckForAbort: PROC ~ {
tsc: TIPUser.TIPScreenCoords ~ NEW[TIPUser.TIPScreenCoordsRec];
Process.SetPriority[Process.priorityRealTime]; --VERY high!
DO--Forever
vt: Terminal.Virtual ~ Terminal.Current[];
keyBits: Terminal.KeyBits ~ Terminal.GetKeys[vt: vt];
IF (keyBits[LeftShift]=down OR keyBits[RightShift]=down) AND keyBits[Spare3]=down THEN {
mouse: Interminal.MousePosition ~ Interminal.GetMousePosition[];
viewer: Viewer;
tsc^ ← [
mouseX: mouse.mouseX,
mouseY: (IF mouse.color THEN vt.colorHeight ELSE vt.bwHeight) - mouse.mouseY,
color: mouse.color
];
viewer ← ViewerOps.MouseInViewer[tsc: tsc].viewer;
IF viewer#NIL THEN Abort[viewer];
};
Process.Pause[ticks: Process.SecondsToTicks[2]];
ENDLOOP;
};
END.