EndOpsImpl.mesa
Copyright Ó 1985, 1986, 1988, 1991 by Xerox Corporation. All rights reserved.
Russ Atkinson (RRA) April 18, 1986 3:52:53 pm PST
Doug Wyatt, September 21, 1987 3:15:00 pm PDT
Last tweaked by Mike Spreitzer on June 4, 1987 2:44:49 pm PDT
Willie-Sue, May 11, 1988 3:04:42 pm PDT
Pier, November 18, 1988 1:48:03 pm PST
Bier, December 8, 1988 12:18:18 pm PST
DIRECTORY
BasicTime, Buttons, EndOps, Idle, Process, Rope, RuntimeError, UserProfile, ViewerClasses, ViewerPrivate;
EndOpsImpl: CEDAR MONITOR
IMPORTS BasicTime, Buttons, Idle, Process, RuntimeError, UserProfile
EXPORTS EndOps, ViewerPrivate
= BEGIN
EndOps related stuff
ProcList: TYPE ~ LIST OF PROC;
registerHead: ProcList ¬ NIL;
registerTail: ProcList ¬ NIL;
Register: PUBLIC ENTRY PROC [proc: PROC] = {
prev: ProcList ~ registerTail;
registerTail ¬ LIST[proc];
IF prev=NIL THEN registerHead ¬ registerTail ELSE prev.rest ¬ registerTail;
};
ProcessEndOpsRegistry: PUBLIC PROC = {
FOR list: ProcList ¬ registerHead, list.rest UNTIL list = NIL DO
list.first[ ! RuntimeError.UNCAUGHT => CONTINUE];
ENDLOOP;
};
Auto-Idle stuff (formerly in ViewerProcessesImpl)
autoIdleTimeout: INT--seconds-- ¬ 20*60;
AutoIdle terminates when not running in this process.
neverEnableAutoIdle: BOOL ¬ FALSE;
To make AutoIdle ignore the profile, set this to TRUE
sampleTimer: CONDITION;
checkpointing: INT ¬ 0;
lastInput: BasicTime.GMT ¬ BasicTime.Now[];
NoteAutoIdleChange: ENTRY UserProfile.ProfileChangedProc = TRUSTED {
[reason: UserProfile.ProfileChangeReason]
ENABLE UNWIND => NULL;
minutes: INT ¬ UserProfile.Number["Viewers.AutoIdleTimeout", 20];
IF neverEnableAutoIdle OR NOT minutes IN (0 .. 40) THEN minutes ¬ 0;
autoIdleTimeout ¬ minutes*60;
RETURN};
<<AutoIdle: ENTRY PROC = TRUSTED {
ENABLE UNWIND => NULL;
now: BasicTime.GMT;
DO
ENABLE ABORTED => LOOP;
WAIT sampleTimer;
now ¬ BasicTime.Now[];
IF TerminalActivity.hadInput THEN {
TerminalActivity.hadInput ¬ FALSE;
lastInput ¬ now;
}
ELSE {
IF autoIdleTimeout>0 AND BasicTime.Period[from: lastInput, to: now] >= autoIdleTimeout AND NOT (checkpointing>0 OR Idle.IsIdle[]) THEN Process.Detach[FORK IdleMother[NIL]];
};
ENDLOOP;
};
>>
<<OnCheckpoint: ENTRY PROC [clientData: REF ANY] RETURNS [rejection: Rope.ROPE ¬ NIL] --Booting.CheckpointProc-- ~ {
ENABLE UNWIND => NULL;
checkpointing ¬ checkpointing + 1;
};
OnRollback: ENTRY PROC [clientData: REF ANY] --Booting.RollbackProc-- ~ {
ENABLE UNWIND => NULL;
IF (checkpointing ¬ checkpointing - 1) = 0 THEN lastInput ¬ BasicTime.Now[];
};
OnBoot: PROC [clientData: REF ANY] RETURNS [rejection: Rope.ROPE ¬ NIL] --Booting.CheckpointProc-- ~ {
dirty: INT ¬ 0;
CheckDirty: ViewerOps.EnumProc = {
IF v.newVersion OR v.newFile THEN dirty ¬ dirty+1;
};
ViewerOps.EnumerateViewers[CheckDirty];
IF dirty#0 THEN
IF NOT MessageWindow.Confirm["Confirm ignoring unsaved viewers"] THEN
rejection ¬ "There are unsaved viewers.";
};>>
IdleMother: Buttons.ButtonProc = {
IF NOT Idle.IsIdle[] THEN {
Idle.Sleep[];
};
};
CreateIdleButton: PUBLIC PROC [] = {
[] ¬ Buttons.Create[
info: [name: "Idle"], proc: IdleMother, fork: TRUE,
documentation: "Hide desktop pending user login"];
};
Init: PROC = TRUSTED {
Process.SetTimeout[@sampleTimer, Process.SecondsToTicks[30]];
};
Init[];
KAP for PCedar November 17, 1988
Booting.RegisterProcs[c: OnCheckpoint, r: OnRollback, b: OnBoot];
TRUSTED {Process.Detach[FORK AutoIdle[]]};
UserProfile.CallWhenProfileChanges[NoteAutoIdleChange];
END.