-- FastMouse.mesa -- Revised by McGregor: June 24, 1983 4:54 pm -- Revised by Randy Gobbel: 10-May-83 9:56:34 -- Written by: CharlieLevy <> <> <> DIRECTORY Commander USING [Handle, Register], Terminal USING [Current, Position, GetMousePosition, SetMousePosition, WaitForBWVerticalRetrace, Virtual], Interminal USING [GetMousePosition], IO USING [EndOf, GetTokenRope, RIS, SkipWhitespace, STREAM], Process USING [SetPriority, priorityClient3], PrincOpsUtils USING [VERSION], UserProfile USING [ProfileChangedProc, Number, Token, CallWhenProfileChanges], Rope USING [Equal, ROPE]; FastMouse: CEDAR MONITOR IMPORTS Commander, Terminal, Interminal, IO, Process, PrincOpsUtils, UserProfile, Rope ~ BEGIN ROPE: TYPE = Rope.ROPE; mouseProcess: PROCESS _ NIL; vt: Terminal.Virtual; position, prevPosition: Terminal.Position; width: NAT; height: NAT; cursorInColorDisplay: BOOLEAN _ FALSE; speedUpLinear: BOOLEAN _ TRUE; -- Acceleration law (linear or squared) threshold: INTEGER _ 2; ampxTen: INTEGER _ 15; enabled: BOOL _ TRUE; shouldRun: BOOL _ TRUE; running: BOOL _ FALSE; ShouldRun: ENTRY PROC RETURNS [run: BOOL] = { IF NOT (run _ shouldRun) THEN RETURN; IF running THEN RETURN [FALSE]; running _ TRUE; }; NoteNotRunning: ENTRY PROC = {running _ FALSE}; DoradoMouseProcess: PROCEDURE = BEGIN IF NOT ShouldRun[] THEN RETURN; {ENABLE UNWIND => NoteNotRunning[]; Process.SetPriority[Process.priorityClient3]; -- this priority is one below fault handlers vt _ Terminal.Current[]; prevPosition _ Terminal.GetMousePosition[vt]; width _ vt.bwWidth; height _ vt.bwHeight; WHILE shouldRun DO amp, xDelta, yDelta: INTEGER; Terminal.WaitForBWVerticalRetrace[vt]; position _ Terminal.GetMousePosition[vt]; IF prevPosition = position THEN LOOP; TRUSTED { IF cursorInColorDisplay # Interminal.GetMousePosition[].color THEN { prevPosition _ position; cursorInColorDisplay _ Interminal.GetMousePosition[].color; IF cursorInColorDisplay THEN { width _ vt.colorWidth; height _ vt.colorHeight; } ELSE { width _ vt.bwWidth; height _ vt.bwHeight; }; LOOP; }; }; xDelta _ position.x - prevPosition.x; yDelta _ position.y - prevPosition.y; amp _ MAX[ ABS[xDelta], ABS[yDelta] ]; IF amp > threshold THEN { IF speedUpLinear THEN position _ [ -- linear law speedup MAX[ MIN[ position.x + (xDelta * ampxTen / 10), width], 0], MAX[ MIN[ position.y + (yDelta * ampxTen / 10), height], 0] ] ELSE position _ [ -- square law speedup MAX[ MIN[ position.x + (xDelta * amp / threshold), width], 0], MAX[ MIN[ position.y + (yDelta * amp / threshold), height], 0] ]; Terminal.SetMousePosition[vt, position]; }; prevPosition _ position; ENDLOOP; }; NoteNotRunning[]; END; -- DoradoMouseProcess DandelionMouseProcess: PROCEDURE = BEGIN IF NOT ShouldRun[] THEN RETURN; {ENABLE UNWIND => NoteNotRunning[]; Process.SetPriority[Process.priorityClient3]; -- this priority is one below fault handlers vt _ Terminal.Current[]; prevPosition _ Terminal.GetMousePosition[vt]; width _ vt.bwWidth; height _ vt.bwHeight; WHILE shouldRun DO <> Terminal.WaitForBWVerticalRetrace[vt]; position _ Terminal.GetMousePosition[vt]; <> <> <> <> < threshold THEN {>> <> <> <> <> <> <> <> <> <<};>> <> ENDLOOP; }; NoteNotRunning[]; END; -- MouseProcess FastMouseCmd: PROC [cmd: Commander.Handle] RETURNS [result: REF ANY _ NIL, msg: ROPE _ NIL] -- Commander.CommandProc-- = BEGIN in: IO.STREAM _ IO.RIS[cmd.commandLine]; ok, on: BOOL _ FALSE; [] _ in.SkipWhitespace[]; IF NOT in.EndOf[] THEN { arg: ROPE _ in.GetTokenRope[].token; [] _ in.SkipWhitespace[]; IF NOT in.EndOf[] THEN NULL ELSE IF arg.Equal["on", FALSE] THEN {ok _ TRUE; on _ TRUE} ELSE IF arg.Equal["off", FALSE] THEN {ok _ TRUE; on _ FALSE}; }; IF ok THEN {enabled _ on; HandleChange[]} ELSE {result _ $Failure; msg _ "Usage: FastMouse on|off"} END; ProcessProfile: UserProfile.ProfileChangedProc = TRUSTED BEGIN enableToken: ROPE _ UserProfile.Token["FastMouse.Enabled", "UNSPECIFIED"]; IF enableToken.Equal["TRUE"] THEN enabled _ TRUE ELSE IF enableToken.Equal["FALSE"] THEN enabled _ FALSE; threshold _ UserProfile.Number["FastMouse.Threshold", 2]; ampxTen _ UserProfile.Number["FastMouse.AmpxTen", 15]; speedUpLinear _ Rope.Equal[UserProfile.Token["FastMouse.SpeedUp", "linear"], "linear"]; HandleChange[]; END; HandleChange: ENTRY PROC = { shouldRun _ enabled; IF shouldRun AND NOT running THEN SELECT PrincOpsUtils.VERSION[].machineType FROM dorado => mouseProcess _ FORK DoradoMouseProcess[]; dandelion => mouseProcess _ FORK DandelionMouseProcess[]; dolphin => mouseProcess _ FORK DoradoMouseProcess[]; ENDCASE; }; Init: PROCEDURE = BEGIN UserProfile.CallWhenProfileChanges[ProcessProfile]; Commander.Register[key: "FastMouse", proc: FastMouseCmd, doc: "Turn mouse speedup on or off"]; END; Init[]; END.