ImplErrorsImpl.mesa; written by S. McGregor
Last Edited by: McGregor, August 4, 1983 11:20 am
Last Edited by: Maxwell, January 3, 1983 12:56 pm
DIRECTORY
ClassIncreek USING [Increek],
Cursors USING [CursorType, SetCursor],
Imager USING [black, Context, Create, MaskIntRectangle, MaskCharacters, SetColor, SetIntCP, white],
ImplErrors,
InputFocus,
MessageWindow USING [Append, Blink, messageWindow],
Process USING [GetPriority, MsecToTicks, Pause, Priority, priorityForeground,
SetPriority],
Rope USING [ROPE],
TIPUser USING [DiscardTypeAhead],
UserProfile USING [Boolean, CallWhenProfileChanges, ProfileChangedProc],
UserTerminal USING [BlinkDisplay, keyboard],
VFonts USING [defaultFont],
ViewerClasses USING [Viewer],
ViewerOps USING [EnumerateViewers, EnumProc, PaintViewer, SaveAllEdits],
ViewersSnapshot USING [RollBack],
WindowManager USING [RestoreCursor];
ImplErrorsImpl: CEDAR MONITOR
IMPORTS Cursors, Imager, InputFocus, MessageWindow, Process, TIPUser,
UserProfile, UserTerminal, VFonts, ViewerOps, ViewersSnapshot, WindowManager
EXPORTS ImplErrors
SHARES InputFocus, MessageWindow, TIPUser =
BEGIN OPEN ImplErrors;
Error: PUBLIC SIGNAL [severity: Severity ← fatal, msg: Rope.ROPENIL] = CODE;
UserErrorQuery: PUBLIC ENTRY PROC RETURNS [continue: BOOL] =
TRUSTED BEGIN OPEN Imager, MessageWindow.messageWindow;
try to flush current TIP notification to client
only use low-level interfaces to avoid monitors and potentially broken code
ENABLE UNWIND => NULL;
oldPriority: Process.Priority = Process.GetPriority[];
context: Context;
mouseBitsRec: TYPE = MACHINE DEPENDENT RECORD [ -- mouse buttons are inverted
fill: [0..8192), red: BOOL, blue: BOOL, yellow: BOOL];
mouse: LONG POINTER TO mouseBitsRec = LOOPHOLE[UserTerminal.keyboard];
IF ~worldSwapDebug THEN RETURN[FALSE];
Process.SetPriority[Process.priorityForeground];
TIPUser.DiscardTypeAhead[InputFocus.focusTIP];
context ← Create[$LFDisplay];
SetColor[context, white];
MaskIntRectangle[context, [cx, cy, cw, ch]];
SetColor[context, black];
SetIntCP[context, [cx+2, cy+2]];
THROUGH [0..3) DO
UserTerminal.BlinkDisplay[];
Process.Pause[Process.MsecToTicks[100]];
ENDLOOP;
MaskCharacters[context, VFonts.defaultFont, " Uncaught Signal! Red: Proceed, Yellow: Save edits then rollback, Blue: Reject."];
WHILE ~mouse.red OR ~mouse.yellow OR ~mouse.blue DO
ENDLOOP; -- spin until buttons go up
Cursors.SetCursor[questionMark];
DOIF ~mouse.red THEN {
continue ← TRUE;
MessageWindow.Append["Pressing on in spite of crash! Maybe you should boot.", TRUE];
EXIT}
ELSE IF ~mouse.yellow THEN {
continue ← TRUE;
Cursors.SetCursor[hourGlass];
ViewerOps.SaveAllEdits[! ANY => CONTINUE];
Cursors.SetCursor[retry];
ViewersSnapshot.RollBack[! ANY => CONTINUE]; -- usually no return
MessageWindow.Append["Rollback failed! Maybe you should boot.", TRUE];
ViewerOps.EnumerateViewers[Paint]; -- update headers of saved viewers
EXIT}
ELSE IF ~mouse.blue THEN {continue ← FALSE; EXIT};
ENDLOOP;
InputFocus.EnableInput[];
Process.SetPriority[oldPriority];
IF NOT continue THEN RETURN;
WindowManager.RestoreCursor[];
MessageWindow.Blink[];
END;
Paint: ViewerOps.EnumProc = BEGIN
IF v.column#static THEN ViewerOps.PaintViewer[v, caption ! ANY => CONTINUE];
RETURN[TRUE];
END;
worldSwapDebug: BOOL;
Init: UserProfile.ProfileChangedProc = CHECKED
{worldSwapDebug ← UserProfile.Boolean["WorldSwapDebug", FALSE]};
UserProfile.CallWhenProfileChanges[Init];
END.