<> <> <> <<>> DIRECTORY Commander, Loader, Menus, PrincOps, PrincOpsUtils, Process, ReadEvalPrint, Rope, UserProfile, ViewerClasses, ViewerOps; CommanderPriority: CEDAR PROGRAM IMPORTS Commander, Loader, Menus, PrincOpsUtils, Process, UserProfile, ViewerOps = BEGIN ROPE: TYPE = Rope.ROPE; Handle: TYPE = ReadEvalPrint.Handle; PDA: PrincOps.PDABase = PrincOps.PDA; normalButtonName, foregroundButtonName, backgroundButtonName: ROPE; NoteProfile: PROC [reason: UserProfile.ProfileChangeReason] --UserProfile.ProfileChangedProc-- = { normalButtonName _ UserProfile.Token["CommanderPriority.NormalButtonName", "N"]; foregroundButtonName _ UserProfile.Token["CommanderPriority.ForegroundButtonName", "F"]; backgroundButtonName _ UserProfile.Token["CommanderPriority.BackgroundButtonName", "B"]; }; Background: Menus.MenuProc = { <<[parent: REF, clientData: REF, mouseButton: MouseButton, shift, control: BOOL]>> h: Handle _ NARROW[clientData, Handle]; [] _ ResetPriority[h.mainLoopProcess, Process.priorityBackground ! Process.InvalidProcess => CONTINUE]; }; Foreground: Menus.MenuProc = { <<[parent: REF, clientData: REF, mouseButton: MouseButton, shift, control: BOOL]>> h: Handle _ NARROW[clientData, Handle]; [] _ ResetPriority[h.mainLoopProcess, Process.priorityForeground ! Process.InvalidProcess => CONTINUE]; }; Normal: Menus.MenuProc = { <<[parent: REF, clientData: REF, mouseButton: MouseButton, shift, control: BOOL]>> h: Handle _ NARROW[clientData, Handle]; [] _ ResetPriority[h.mainLoopProcess, Process.priorityNormal ! Process.InvalidProcess => CONTINUE]; }; ResetPriority: PROC [process: PROCESS, new: PrincOps.Priority] RETURNS [success: BOOL _ TRUE] = TRUSTED { <> <> old: PrincOps.Priority; psb: PrincOps.PsbHandle; psb _ PrincOpsUtils.PsbIndexToHandle[LOOPHOLE[process]]; PrincOpsUtils.DisableInterrupts[]; old _ PDA[psb].link.priority; IF old # new THEN { self: PrincOps.PsbHandle = PrincOpsUtils.PsbIndexToHandle[ PDA[PrincOpsUtils.PsbIndexToHandle[PDA.ready.tail]].link.next]; npsb: PrincOps.PsbHandle _ PrincOpsUtils.PsbIndexToHandle[PDA[self].link.next]; IF PDA[psb].link.vector THEN { <> nsv: PrincOps.StateVectorHandle _ PDA.state[new]; IF nsv = PrincOps.NullStateVectorHandle THEN GO TO fail; <> <> PDA.state[new] _ LOOPHOLE[PDA[nsv].stk[0]]; <> PDA[nsv].stk[0] _ LOOPHOLE[PDA.state[old]]; PDA.state[old] _ nsv; }; <> PDA[psb].link.priority _ new; <> DO IF npsb = self THEN EXIT; IF npsb = psb THEN { PrincOpsUtils.Requeue[@PDA.ready, @PDA.ready, psb]; EXIT; }; npsb _ PrincOpsUtils.PsbIndexToHandle[PDA[npsb].link.next]; ENDLOOP; EXITS fail => {success _ FALSE}; }; PrincOpsUtils.EnableInterrupts[]; }; Greet: PROC [handle: Handle, cmd: Commander.Handle, paint: BOOL] = { v: ViewerClasses.Viewer _ handle.viewer; Add: PROC [me: Menus.MenuEntry, name: ROPE] = { old: Menus.MenuEntry = Menus.FindEntry[v.menu, name]; IF old = NIL THEN Menus.AppendMenuEntry[v.menu, me] ELSE Menus.ReplaceMenuEntry[v.menu, old, me]; }; Add[Menus.CreateEntry[name: normalButtonName, proc: Normal, fork: TRUE, clientData: handle], normalButtonName]; Add[Menus.CreateEntry[name: foregroundButtonName, proc: Foreground, fork: TRUE, clientData: handle], foregroundButtonName]; Add[Menus.CreateEntry[name: backgroundButtonName, proc: Background, fork: TRUE, clientData: handle], backgroundButtonName]; IF paint THEN ViewerOps.PaintViewer[v, menu]; }; CommanderPriorityCmdProc: Commander.CommandProc ~ { handle: ReadEvalPrint.Handle _ NARROW[ Commander.GetProperty[$ReadEvalPrintHandle, cmd.propertyList]]; Greet[handle, cmd, TRUE]; }; Loader.MakeProcedureResident[ResetPriority]; UserProfile.CallWhenProfileChanges[NoteProfile]; Commander.Register[key: "///Commands/CommanderPriority", proc: CommanderPriorityCmdProc, doc: "registers CommandTool menu buttons priority changes."]; END. <<>>