DIRECTORY BasicTime, IO, Rope, SimpleFeedback, Xl, XlPrivateErrorHandling, XlPrivate; XlErrorHandlingWithFeedback: CEDAR MONITOR IMPORTS BasicTime, IO, Rope, SimpleFeedback, XlPrivate, XlPrivateErrorHandling SHARES Xl ~ BEGIN Explain: PROC [errorEvent: Xl.ErrorNotifyEvent] = { Ap0: PROC [r: Rope.ROPE] = { ev.explanation ฌ Rope.Cat[ev.explanation, r, " "]; }; Ap: PROC [format: Rope.ROPE, v1: IO.Value ฌ [null[]]] = { Ap0[IO.PutFR1[format, v1]] }; ev: REF Xl.EventRep.errorNotify; IF errorEvent#NIL AND errorEvent.explanation=NIL THEN { TRUSTED { ev ฌ LOOPHOLE[errorEvent] }; --read-write ev.originalCodeByte ฌ ORD[Xl.EventCode[errorNotify]]; WITH ev.replyText SELECT FROM r: XlPrivate.Reply => { IF XlPrivate.Get8[r, 0]#0 THEN Ap0["package is not an error event"] ELSE { XlPrivate.SetPos[r, 1]; ev.errorKind ฌ VAL[XlPrivate.Read8[r]]; ev.seq ฌ XlPrivate.ERead16[r]; ev.badValue ฌ XlPrivate.ERead32[r]; ev.minorOpCode ฌ XlPrivate.ERead16[r]; ev.majorOpCode ฌ VAL[XlPrivate.ERead8[r]]; SELECT ev.errorKind FROM nil => Ap0["nil error"]; request => Ap["bad request: %g", IO.card[ev.majorOpCode]]; value => Ap["bad value: %g", IO.card[ev.badValue]]; window => Ap["bad window id: %g", IO.card[ev.badValue]]; pixmap => Ap["bad pixmap id: %g", IO.card[ev.badValue]]; atom => Ap["bad atom id: %g", IO.card[ev.badValue]]; cursor => Ap["bad cursor id: %g", IO.card[ev.badValue]]; font => Ap["bad font id: %g", IO.card[ev.badValue]]; match => Ap0["match error"]; drawable => Ap["bad drawable id: %g", IO.card[ev.badValue]]; access => Ap0["access error"]; alloc => Ap0["server out of memory"]; colormap => Ap["bad colormap id: %g", IO.card[ev.badValue]]; gContext => Ap["bad gContext id: %g", IO.card[ev.badValue]]; idChoice => Ap["idChoice error: bad id: %g", IO.card[ev.badValue]]; name => Ap0["name error"]; length => Ap0["length error"]; implementation => Ap0["implementation error"]; connectionWedged => Ap0["connection wedged"]; requestFromDeadConnection => Ap0["connection closed"]; VAL[241] => Ap0["reply inconsistent"]; ENDCASE => Ap["unknown error (%g)", IO.card[ORD[ev.errorKind]]]; Ap[" (majorOpCode: %g)", IO.card[ev.majorOpCode]]; IF ev.minorOpCode#0 THEN Ap[" (minorOpCode: %g)", IO.card[ev.minorOpCode]]; }; }; ENDCASE => {Ap0["reply wrong"]}; }; }; lastErrorEvent, secondLastErrorEvent: Xl.ErrorNotifyEvent ฌ NIL; lastTime: BasicTime.GMT ฌ BasicTime.earliestGMT; SwapLastError: ENTRY PROC [newLastError: Xl.ErrorNotifyEvent, now: BasicTime.GMT] RETURNS [previous, older: Xl.ErrorNotifyEvent, time: BasicTime.GMT] = { previous ฌ lastErrorEvent; older ฌ secondLastErrorEvent; secondLastErrorEvent ฌ lastErrorEvent; lastErrorEvent ฌ newLastError; time ฌ lastTime; lastTime ฌ now; }; ErrorEventProc: Xl.EventProcType = { c: Xl.Connection ฌ event.connection; message: Rope.ROPE ฌ "Xl: unknown error"; WITH event SELECT FROM error: Xl.ErrorNotifyEvent => { XlPrivateErrorHandling.Explain[error]; BEGIN -- little hack to avoid reporting the same kind of error message over and over now: BasicTime.GMT ฌ BasicTime.earliestGMT; previous, previous2: Xl.ErrorNotifyEvent; lastTime: BasicTime.GMT; now ฌ BasicTime.Now[! BasicTime.TimeNotKnown => CONTINUE]; [previous, previous2, lastTime] ฌ SwapLastError[error, now]; IF previous#NIL AND previous.connection=c THEN { IF previous.errorKind=error.errorKind THEN { IF BasicTime.Period[from: lastTime, to: now]<=2 THEN { IF previous2=NIL OR previous2.connection#c THEN { SimpleFeedback.Append[$X11Errors, oneLiner, $XlErrors, "...Similar X window error(s) suppressed...\n"]; } ELSE { }; RETURN } } }; END; message ฌ IO.PutFR["XError [%g, kind:%g", IO.rope[error.explanation], IO.card[ORD[error.errorKind]]]; message ฌ IO.PutFR["%g, major:%g, minor:%g", IO.rope[message], IO.card[error.majorOpCode], IO.card[error.minorOpCode]]; message ฌ IO.PutFR["%g, bad:%g", IO.rope[message], IO.card[error.badValue]]; IF c#NIL THEN { message ฌ IO.PutFR["%g, event sequenceNo: %g last sequenceNo: %g", IO.rope[message], IO.card[error.seq], IO.card[c.sequenceNumber]]; }; message ฌ Rope.Concat[message, "]"]; }; ENDCASE => {}; SimpleFeedback.Append[$X11Errors, oneLiner, $XlErrors, message]; SimpleFeedback.Blink[$X11Errors, $XlError]; }; XlPrivateErrorHandling.RegisterErrorReportProc[ErrorEventProc]; XlPrivateErrorHandling.RegisterExplainer[Explain]; END. ŽXlErrorHandlingWithFeedback.mesa Copyright ำ 1991, 1992 by Xerox Corporation. All rights reserved. Created by Christian Jacobi, November 6, 1991 10:11:20 am PST Christian Jacobi, February 2, 1993 11:35 am PST Willie-s, November 25, 1991 4:48 pm PST Non essential impl module for Xl. Registers error handlers making X errors legible. --ok, we surpress some messaging --be completely quiet สฎ–(cedarcode) style•NewlineDelimiter ˜codešœ ™ Kšœ ฯeœ7™BKšœ=™=K™/K™'K™K™!K™1K™—šฯk œ˜ Kšœ žœ>˜KK˜—šฯnœžœžœ˜+Kšžœ žœ9˜NKšžœ˜ —Kšžœ˜K˜šŸœžœ&˜3šŸœžœ žœ˜Kšœ2˜2K˜—šŸœžœžœžœ˜9Kšœžœ˜K˜—Kšœžœ˜ š žœ žœžœžœžœ˜7Kšžœžœฯc ˜3Kšœžœ˜5šžœžœž˜˜Kšžœžœ%˜Cšžœ˜Kšœ˜Kšœžœ˜'Kšœ˜Kšœ#˜#Kšœ&˜&Kšœžœ˜*šžœž˜Kšœ˜Kšœ!žœ˜:Kšœžœ˜3Kšœ"žœ˜8Kšœ"žœ˜8Kšœžœ˜4Kšœ"žœ˜8Kšœžœ˜4Kšœ˜Kšœ&žœ˜žœ˜BKšœ0žœ˜:K˜<šžœ žœžœžœ˜0šžœ$žœ˜,šžœ.žœ˜6K™ šžœ žœžœ˜+šžœ˜K˜gK˜—šžœ˜K™K˜——Kšž˜K˜—K˜—K˜—Kšžœ˜—Kš œ žœžœžœžœ˜eKš œ žœ!žœžœžœ˜wKšœ žœžœžœ˜Lšžœžœžœ˜Kš œ žœ7žœžœžœ˜„K˜—K˜$K˜—Kšžœ˜—Kšœ@˜@Kšœ+˜+Kšœ˜—K˜K˜?Kšœ2˜2Kšžœ˜K˜—…—ฮ