<> <> <> <> <<>> <> <<>> DIRECTORY GCCallBack, Process, RuntimeError, X11Viewers; X11ViewersGCHackImpl: CEDAR MONITOR IMPORTS GCCallBack, Process, RuntimeError, X11Viewers SHARES X11Viewers ~ BEGIN gcCursorNeedsChange: BOOL ¬ FALSE; gcCursorSwitchToIt: BOOL ¬ FALSE; gcCursorJobReady: CONDITION; gcCursorDoneOrTimedOut: CONDITION; BeforeGarbageCollection: ENTRY PROC [x: REF] = { gcCursorSwitchToIt ¬ TRUE; gcCursorNeedsChange ¬ TRUE; NOTIFY gcCursorJobReady; WAIT gcCursorDoneOrTimedOut; }; AfterGarbageCollection: ENTRY PROC [x: REF] = { gcCursorSwitchToIt ¬ FALSE; gcCursorNeedsChange ¬ TRUE; NOTIFY gcCursorJobReady; }; WaitForRequest: ENTRY PROC [] RETURNS [switchOn: BOOL] = { NOTIFY gcCursorDoneOrTimedOut; --previous execution of loop WHILE ~gcCursorNeedsChange DO WAIT gcCursorJobReady ENDLOOP; gcCursorNeedsChange ¬ FALSE; switchOn ¬ gcCursorSwitchToIt; }; CursorChangeProcess: PROC [] = { Protected: PROC [] = { DO --forever needGCCursor: BOOL ¬ WaitForRequest[]; X11Viewers.SetGCMode[needGCCursor]; ENDLOOP }; Process.SetPriority[Process.priorityClient3]; DO Protected[! RuntimeError.UNCAUGHT => IF ~X11Viewers.debugging THEN CONTINUE]; Process.PauseMsec[4000]; ENDLOOP }; Init: PROC ~ { TRUSTED {Process.SetTimeout[@gcCursorDoneOrTimedOut, Process.MsecToTicks[300]]}; TRUSTED {Process.Detach[FORK CursorChangeProcess[]]}; GCCallBack.RegisterAfter[AfterGarbageCollection]; GCCallBack.RegisterBefore[BeforeGarbageCollection]; }; Init[]; END.