DIRECTORY Booting USING [CallBootingProcs], Buttons USING [ButtonProc, Create], Commander USING [CommandProc, Register], CommandTool USING [ParseToList], DeviceCleanup USING[Perform], IO USING [PutF], MessageWindow USING [Append, Blink-- , Confirm--], PrincOpsUtils USING[DisableInterrupts], ProcessorFace USING[PowerOff], Rope USING[Concat, Equal, ROPE], ViewerOps USING[ChangeColumn, EnumProc, EnumerateViewers]; PowerOff: CEDAR PROGRAM IMPORTS Booting, Buttons, Commander, CommandTool, DeviceCleanup, IO, MessageWindow, PrincOpsUtils, ProcessorFace, Rope, ViewerOps ~ BEGIN PowerOffButton: Buttons.ButtonProc ~ TRUSTED BEGIN DoPowerOff[FALSE, TRUE]; END; DoPowerOff: PROC [force: BOOL, confirm: BOOL] = TRUSTED BEGIN rejection: Rope.ROPE _ NIL; I: INT _ 0 ; IF ~force AND SomethingWorthSaving[confirm] THEN RETURN; rejection _ Booting.CallBootingProcs[]; IF ~force AND rejection # NIL THEN { MessageWindow.Blink[]; MessageWindow.Append[message: Rope.Concat["Power off rejected due to", rejection], clearFirst: TRUE]; }; PrincOpsUtils.DisableInterrupts[]; -- make it hold still first DeviceCleanup.Perform[turnOff]; ProcessorFace.PowerOff[]; DO I _ I + 1; ENDLOOP; END; SomethingWorthSaving: PROC [confirm: BOOL] RETURNS [BOOL] = { dirty: BOOL _ FALSE; CheckDirty: ViewerOps.EnumProc = { IF v.newVersion OR v.newFile THEN dirty _ TRUE ELSE RETURN; IF v.offDeskTop THEN ViewerOps.ChangeColumn[v, left]; }; ViewerOps.EnumerateViewers[CheckDirty]; IF dirty AND confirm THEN { MessageWindow.Blink[]; MessageWindow.Append[message: "Dirty viewer => no power off", clearFirst: TRUE]; }; RETURN[dirty] }; PowerOffCmdProc: Commander.CommandProc = { skip: BOOL _ FALSE; force: BOOL _ FALSE; cmdLine: LIST OF Rope.ROPE; cmdLine _ CommandTool.ParseToList[cmd].list; IF cmdLine # NIL THEN { IF Rope.Equal[cmdLine.first, "-f", FALSE] AND cmdLine.rest = NIL THEN force _ TRUE ELSE { IO.PutF[cmd.err, "Usage: PowerOff [-f]\n"]; skip _ TRUE; }; }; IF ~skip THEN DoPowerOff[force, FALSE]; result _ $Failure; msg _ "PowerOff not done because there are unsaved viewers."; }; [] _ Buttons.Create[info: [name: "PowerOff"], proc: PowerOffButton, guarded: TRUE]; Commander.Register[key: "PowerOff", proc: PowerOffCmdProc, doc: "Perform a somewhat orderly system shutdown, and power the machine off. The command will fail if there are any unsaved viewers. The f switch can be used to override."]; END. ’PowerOff.mesa Bob Hagmann, November 1, 1985 3:57:48 pm PST Make a PowerOff button. Check to make sure that there are no unsaved edits, and try to do an orderly shutdown. IF ~MessageWindow.Confirm["Confirm discard of edits . . . "] THEN { MessageWindow.Append["power off aborted."]; RETURN[TRUE] } ELSE RETURN[FALSE]; Bob Hagmann November 1, 1985 3:53:21 pm PST changes to: DIRECTORY, DoPowerOff, PowerOff Κ|˜J™ J™,J™J™oJ™šΟk ˜ Jšœœ˜!Jšœœ˜#Jšœ Οsœ˜(Jšœ žœ˜ Jšœœ ˜Jšœœ˜Jšœœ˜2Jšœœ˜'Jšœœ ˜Jšœœ˜ Jšœ œ+˜:J˜J˜—šœ  ˜Jšœ:œ>˜Jšœ˜J˜J˜šΟbœ ˜2Jšœ˜J˜J˜—š Πbn œœ œ œœ˜=Jšœœœ˜Jšœœ˜ Jšœœœœ˜8Jšœ'˜'šœœ œœ˜$J˜Jšœ_œ˜eJšœ˜—Jšœ#Οc˜>Jšœ˜Jšœ˜š˜Jšœ ˜ Jšœ˜—Jšœ˜—J˜š Οnœœ œœœ˜=Jšœœœ˜šœ"˜"Jš œœ œ œœœ˜;Jšœœ!˜5Jšœ˜—J˜'šœœ œ˜J˜JšœJœ˜Pšœ;œ™CJ™+Jšœœ™ Jšœ™—Jšœœœœ™Jšœ˜—Jšœ˜ Jšœ˜J˜—šΠbvœ˜*Jšœœœ˜Jšœœœ˜Jšœ œœœ˜Jšœ,˜,šœ œœ˜Jš œ!œœœœ ˜Ršœœ˜Jšœ)˜+Jšœœ˜ J˜—J˜—Jšœœœ˜'Jšœ˜Jšœ=˜=J˜J˜—JšœMœ˜SJšœκ˜κJ˜Jšœ˜—code™+Kšœ Οr™+—K™K™—…— Zx