DIRECTORY Basics USING [BITAND, bitsPerWord, LongDivMod, LongMult, LowHalf], BasicTime USING [GMT, Now, nullGMT, Period, ToPupTime], DebuggerSwap USING [EnableSwatWatcher], Idle USING [BitmapRef, BitmapRep, ImageProc], IO USING [PutRope, STREAM], KeyboardFace USING [KeyBits, KeyStation], Keys USING [KeyBits, KeyName], PrincOps USING [BBptr, BBTableSpace, BitAddress], PrincOpsUtils USING [AlignedBBTable, BITBLT], Process USING [Pause, SecondsToTicks, Ticks], ProcessorFace USING [PowerOff], Rope USING [Equal, Length, ROPE], SimpleTerminal USING [InputTimeout, SetInputTimeout, TurnOff, TurnOn], Terminal USING [ BWCursorBitmap, Create, Current, DisableKeyboardWatcher, EnableKeyboardWatcher, GetBitBltTable, GetKeys, Select, SetBWBackground, SetBWBitmapState, SetBWCursorPosition, Virtual, WaitForBWVerticalRetrace], UserCredentials USING [Get, Login], UserProfile USING [ProfileChanged]; IdleImpl: CEDAR MONITOR IMPORTS Basics, BasicTime, DebuggerSwap, IO, PrincOpsUtils, Process, ProcessorFace, Rope, SimpleTerminal, Terminal, UserCredentials, UserProfile EXPORTS Idle = BEGIN ActionProc: TYPE = PROC RETURNS [wake: BOOL]; -- Global Variables (not exported) -- vt: Terminal.Virtual = Terminal.Create[]; sleeping: BOOLEAN _ FALSE; napOver: CONDITION _ [timeout: 0]; -- Exports to Idle -- Sleep: PUBLIC PROC [ proc: Idle.ImageProc _ DefaultImageProc, powerOff: BasicTime.GMT _ BasicTime.nullGMT] = { NapNeeded: ENTRY PROC RETURNS [needed: BOOL] = INLINE { IF (needed _ ~sleeping) THEN sleeping _ TRUE ELSE WHILE sleeping DO WAIT napOver ENDLOOP; }; WakeUp: ENTRY PROC = {sleeping _ FALSE; BROADCAST napOver}; DoLogin: PROC RETURNS [wake: BOOL _ TRUE] = { TerminalOn: PROC RETURNS [in, out: IO.STREAM] = { [in, out] _ SimpleTerminal.TurnOn[]; out.PutRope["\NPlease login...\N"]; SimpleTerminal.SetInputTimeout[Process.SecondsToTicks[30]]; }; TerminalOff: PROC [in, out: IO.STREAM] = { SimpleTerminal.SetInputTimeout[0]; SimpleTerminal.TurnOff[]; }; name, password: Rope.ROPE; [name, password] _ UserCredentials.Get[]; IF password.Length[] = 0 THEN RETURN; -- wasn't previously logged in. UserCredentials.Login[ startInteraction: TerminalOn, endInteraction: TerminalOff, options: [confirmCredentialsOverwrite: TRUE, alwaysInteract: TRUE] ! SimpleTerminal.InputTimeout => {wake _ FALSE; CONTINUE}]; IF ~name.Equal[UserCredentials.Get[].name, FALSE] THEN UserProfile.ProfileChanged[$rollBack]; }; currentVT: Terminal.Virtual; IF ~NapNeeded[] THEN RETURN; DebuggerSwap.EnableSwatWatcher[FALSE]; Terminal.DisableKeyboardWatcher[]; currentVT _ Terminal.Current[]; SleepInternal[proc, DoLogin, powerOff]; currentVT.Select[]; Terminal.EnableKeyboardWatcher[]; DebuggerSwap.EnableSwatWatcher[TRUE]; WakeUp[]; }; -- Sleep stuff -- SleepInternal: PROC [ imageProc: Idle.ImageProc, actionProc: ActionProc, powerOff: BasicTime.GMT] = TRUSTED { ticksPerSecond: Process.Ticks = Process.SecondsToTicks[1]; DO -- loops only if actionProc returns FALSE bbTable: PrincOps.BBTableSpace; bbt: PrincOps.BBptr = PrincOpsUtils.AlignedBBTable[@bbTable]; x: CARDINAL _ Random[] MOD vt.bwWidth; y: CARDINAL _ Random[] MOD vt.bwHeight; image: Idle.BitmapRef _ NIL; org: PrincOps.BitAddress; -- origin of display bitmap bpl: LONG CARDINAL; -- raster width of display bitmap white: CARDINAL _ 0; XYToBitAddress: PROC [x, y: CARDINAL] RETURNS [PrincOps.BitAddress] = TRUSTED { q, r: CARDINAL; [q, r] _ Basics.LongDivMod[org.bit + Basics.LongMult[y, bpl] + x, Basics.bitsPerWord]; RETURN[[word: org.word + q, bit: r]] }; vt.Select[]; [] _ vt.SetBWBitmapState[$allocated]; bbt^ _ vt.GetBitBltTable[]; org _ bbt.dst; bpl _ bbt.dstBpl; bbt.src _ [@white, 0, 0]; bbt.srcDesc _ [gray[[0, 0, 0, 0]]]; bbt.flags _ [gray: TRUE]; PrincOpsUtils.BITBLT[bbt]; [] _ vt.SetBWBitmapState[$displayed]; DO w, h: CARDINAL; x _ UpdateAndClip[x, vt.bwWidth, IF image = NIL THEN 0 ELSE image.width]; y _ UpdateAndClip[y, vt.bwHeight, IF image = NIL THEN 0 ELSE image.height]; w _ vt.bwWidth - x; h _ vt.bwHeight - y; IF image ~= NIL THEN { bbt.src _ [@white, 0, 0]; bbt.srcDesc _ [gray[[0, 0, 0, 0]]]; bbt.flags _ [gray: TRUE]; PrincOpsUtils.BITBLT[bbt]; }; image _ imageProc[w: w, h: h]; IF image ~= NIL THEN { bbt.dst _ XYToBitAddress[x, y]; bbt.src _ [word: LOOPHOLE[image.base], bit: 0]; bbt.srcDesc _ [srcBpl[image.raster*Basics.bitsPerWord]]; bbt.width _ MIN[image.width, w]; bbt.height _ MIN[image.height, h]; bbt.flags _ [disjoint: TRUE]; PrincOpsUtils.BITBLT[bbt]; }; THROUGH [0..(((Random[] MOD 8) + 1) * ticksPerSecond) / 4) DO IF KeyTyped[] THEN GO TO keyTyped; Process.Pause[1]; ENDLOOP; IF powerOff ~= BasicTime.nullGMT AND BasicTime.Period[from: BasicTime.Now[], to: powerOff] >= 0 THEN ProcessorFace.PowerOff[]; REPEAT keyTyped => NULL; ENDLOOP; [] _ vt.SetBWBitmapState[$none]; IF actionProc[] THEN EXIT; ENDLOOP; }; defaultBitmap: Idle.BitmapRef = NEW[Idle.BitmapRep _ [ base: NEW[Terminal.BWCursorBitmap _ [ 002000B, 074000B, 140000B, 012767B, 012525B, 053566B, 111113B, 163100B, 000000B, 000000B, 154000B, 053520B, 062520B, 053360B, 155440B, 000140B ]], raster: 1, width: Basics.bitsPerWord, height: Terminal.BWCursorBitmap.SIZE ]]; DefaultImageProc: PUBLIC Idle.ImageProc = {RETURN[defaultBitmap]}; KeyTyped: PROC RETURNS [somethingWasDown: BOOL] = { KeyArray: TYPE = MACHINE DEPENDENT RECORD [ SELECT OVERLAID * FROM nb => [namedBits: Keys.KeyBits], ub => [unnamedBits: KeyboardFace.KeyBits], wds => [words: ARRAY [0..SIZE[Keys.KeyBits]) OF WORD], ENDCASE ]; SomethingIsDown: PROC RETURNS [BOOL _ FALSE] = { InterestingKeys: TYPE = KeyboardFace.KeyStation[16..77]; up: KeyArray = [nb[namedBits: ALL[$up]]]; keys: KeyArray = [nb[namedBits: vt.GetKeys[]]]; FOR i: NAT IN [0..SIZE[KeyArray]) DO IF keys.words[i] ~= up.words[i] THEN FOR k: KeyboardFace.KeyStation IN [i*Basics.bitsPerWord..(i+1)*Basics.bitsPerWord) DO IF k ~= Keys.KeyName[$Lock].ORD AND k IN InterestingKeys AND keys.unnamedBits[k] = $down THEN RETURN[TRUE]; ENDLOOP; ENDLOOP; }; IF (somethingWasDown _ SomethingIsDown[]) THEN DO vt.WaitForBWVerticalRetrace[]; IF ~SomethingIsDown[] THEN EXIT; ENDLOOP; }; nRandoms: CARDINAL = 20; RandIndex: TYPE = [0..nRandoms); randTable: ARRAY RandIndex OF CARDINAL _ [ 30200, 27432, 62096, 39855, 17884, 58726, 55595, 20904, 28164, 27447, 34709, 35231, 33770, 31508, 40689, 1411, 20373, 3422, 62938, 40035]; randIndex: RandIndex _ Basics.LowHalf[BasicTime.ToPupTime[BasicTime.Now[]]] MOD nRandoms; Random: PROC RETURNS [r: CARDINAL] = { i: RandIndex; randIndex _ IF randIndex = LAST[RandIndex] THEN FIRST[RandIndex] ELSE SUCC[randIndex]; i _ (randIndex + 3) MOD nRandoms; r _ randTable[i] _ randTable[randIndex] + randTable[i]; }; UpdateAndClip: PROC [v: CARDINAL, limit: CARDINAL, scale: CARDINAL _ 16] RETURNS [newV: CARDINAL] = INLINE { r: CARDINAL = Random[]; x: INTEGER _ v; x _ x + (SELECT TRUE FROM Basics.BITAND[r, 100000B] ~= 0 => 0, Basics.BITAND[r, 40000B] ~= 0 => scale, ENDCASE => -scale); RETURN [ SELECT x FROM < 0 => limit - scale, >= INTEGER[limit - scale] => 0, ENDCASE => x ] }; -- ***************** -- -- *** Main Body *** -- -- ***************** -- [] _ vt.SetBWBackground[$black]; vt.SetBWCursorPosition[[x: -SIZE[Terminal.BWCursorBitmap], y: -SIZE[Terminal.BWCursorBitmap]]]; END. "IdleImpl.mesa last edited by Levin on December 12, 1983 4:00 pm The user name isn't what it was before we went to sleep, so we notify anyone who might care. blacken the entire bitmap (bbt.dst, bbt.height, and bbt.width are set up) unpaint old image This algorithm is stolen from DMT. Κ – "Cedar" style˜Jšœ ™ Jšœ1™1J˜šΟk ˜ Jšœœœ.˜BJšœ œœ#˜7Jšœ œ˜'Jšœœ#˜-Jšœœ œ˜Jšœ œ˜)Jšœœ˜Jšœ œ#˜1Jšœœœ˜-Jšœœ ˜-Jšœœ ˜Jšœœœ˜!Jšœœ2˜Fšœ œ˜JšœΜ˜Μ—Jšœœ˜#Jšœ œ˜#—J˜šœ œ˜š˜Jšœ!œe˜ˆ—Jšœ˜J˜—Jš˜J˜Jš Οn œœœœœ˜-J˜J˜JšΟc%˜%J˜J˜Jšœ)˜)J˜Jšœ œœ˜Jšœ  œ˜"J˜J˜JšŸ˜J˜J˜šžœœœ˜Jšœ=œ˜Yš ž œœœœ œœ˜7Jšœœ ˜,Jš œœ œœ œ˜,J˜—Jš žœœœœ œ ˜;š žœœœœœ˜-š ž œœœ œœ˜1Jšœ$˜$J˜#Jšœ;˜;Jšœ˜—šž œœ œœ˜*J˜"Jšœ˜Jšœ˜—Jšœœ˜J˜)JšœœœŸ˜Fšœ˜Jšœ˜Jšœ˜Jšœ'œœ˜BJšœ)œœ˜;—šœ)œ˜6Jšœ\™\J˜&—J˜—J˜Jšœœœ˜Jšœœ˜&Jšœ"˜"J˜Jšœ'˜'J˜Jšœ!˜!Jšœœ˜%J˜ J˜J˜J˜—JšŸ˜J˜J˜šž œœ˜JšœGœœ˜WJ˜:šœŸ)˜-Jšœ ˜ Jšœ=˜=Jšœœ œ ˜&Jšœ œ œ ˜'Jšœœ˜JšœŸ˜6JšœœœŸ!˜6Jšœœ˜š žœœœœœ˜OJšœœ˜JšœV˜VJšœ˜$Jšœ˜—J˜ J˜%J˜J˜J˜JšœI™IJšœ˜J˜#Jšœœ˜Jšœœ˜J˜%š˜Jšœœ˜Jš œ!œ œœœ˜IJš œ"œ œœœ˜KJšœ˜Jšœ˜šœ œœ˜Jšœ™Jšœ˜J˜#Jšœœ˜Jšœœ˜J˜—Jšœ˜šœ œœ˜J˜Jšœœ˜/J˜8Jšœ œ˜ Jšœ œ˜"Jšœœ˜Jšœœ˜J˜—šœœ ˜=Jšœ œœœ ˜"Jšœ˜Jšœ˜—šœ˜$šœ;˜?J˜——š˜Jšœ œ˜—Jšœ˜—J˜ Jšœœœ˜Jšœ˜—J˜J˜—šœ œ˜6šœœ˜%J˜GJ˜FJ˜—J˜ J˜Jšœ ˜$J˜—J˜Jšœœœ˜BJ˜šžœœœœ˜3š œ œœ œœ˜+šœœ˜Jšœ ˜ Jšœ*˜*Jš œœœœœ˜6Jš˜—Jšœ˜—š žœœœœœ˜0Jšœœ#˜8Jšœœ˜)Jšœ/˜/š œœœœ ˜$šœ˜$šœœ2˜UJšœœœœœœœœ˜kJšœ˜——Jšœ˜—J˜—šœ(˜.š˜J˜Jšœœœ˜ Jšœ˜——J˜J˜—Jšœ œ˜Jšœ œ˜ šœ œ œœ˜*J˜EJ˜D—J˜JšœLœ ˜YJ˜šžœœœœ˜&Jšœ"™"J˜ Jš œ œ œ œœ œœ ˜VJšœœ ˜!J˜7J˜—J˜š ž œœœ œ œ˜HJšœœœ˜#Jšœœ ˜Jšœœ˜˜šœœœ˜Jšœœ˜$Jšœœ˜(Jšœ ˜——šœ˜šœ˜ J˜Jšœœ˜Jšœ˜ —J˜—šœ˜J˜——J˜J˜J˜JšŸ˜JšŸ˜JšŸ˜J˜J˜ šœœœ˜_J˜—Jšœ˜J˜J˜—…—6&[