DIRECTORY BackStop, BasicTime, Carets, Imager, ImagerFont, ImagerPixelMap, ImagerRaster, Process, Random, Rope, Terminal, ViewerLocks; MakeDoAux2Impl: CEDAR PROGRAM IMPORTS BackStop, BasicTime, Carets, Imager, ImagerFont, ImagerPixelMap, ImagerRaster, Process, Random, Terminal, ViewerLocks = BEGIN ROPE: TYPE = Rope.ROPE; PixelMap: TYPE = ImagerPixelMap.PixelMap; Context: TYPE = Imager.Context; rs: Random.RandomStream = Random.Create[seed: -1]; font: ImagerFont.Font _ ImagerFont.Find["Xerox/PressFonts/TimesRoman-MRR"]; Drain: PROC [subject, replaceWith: PixelMap, divS, divF: INTEGER--the drain, in device coordinates--] = { bounds: ImagerPixelMap.DeviceRectangle _ subject.Window[]; WHILE bounds.sSize > 0 AND bounds.fSize > 0 DO n: INT = rs.ChooseInt[0, bounds.sSize + bounds.fSize - 1]; IF n < bounds.sSize THEN { doomedS: NAT = n + bounds.sMin; IF doomedS < divS THEN { moveSize: NAT = doomedS - bounds.sMin; IF moveSize > 0 THEN { move: PixelMap = subject.Clip[[bounds.sMin, bounds.fMin, moveSize+1, bounds.fSize]]; move.Transfer[move.ShiftMap[1, 0]]; }; subject.Clip[[bounds.sMin, bounds.fMin, 1, bounds.fSize]].Transfer[replaceWith]; bounds.sMin _ bounds.sMin + 1; } ELSE { last: NAT = bounds.sMin + bounds.sSize - 1; moveSize: NAT = last - doomedS; IF moveSize > 0 THEN { move: PixelMap = subject.Clip[[doomedS, bounds.fMin, moveSize+1, bounds.fSize]]; move.ShiftMap[1, 0].Transfer[move]; }; subject.Clip[[last, bounds.fMin, 1, bounds.fSize]].Transfer[replaceWith]; }; bounds.sSize _ bounds.sSize - 1; } ELSE { doomedF: NAT = n - bounds.sSize + bounds.fMin; IF doomedF < divF THEN { moveSize: NAT = doomedF - bounds.fMin; IF moveSize > 0 THEN { move: PixelMap = subject.Clip[[bounds.sMin, bounds.fMin, bounds.sSize, moveSize+1]]; move.Transfer[move.ShiftMap[0, 1]]; }; subject.Clip[[bounds.sMin, bounds.fMin, bounds.sSize, 1]].Transfer[replaceWith]; bounds.fMin _ bounds.fMin + 1; } ELSE { last: NAT = bounds.fMin + bounds.fSize - 1; moveSize: NAT = last - doomedF; IF moveSize > 0 THEN { move: PixelMap = subject.Clip[[bounds.sMin, doomedF, bounds.sSize, moveSize+1]]; move.ShiftMap[0, 1].Transfer[move]; }; subject.Clip[[bounds.sMin, last, bounds.sSize, 1]].Transfer[replaceWith]; }; bounds.fSize _ bounds.fSize - 1; }; ENDLOOP; }; GetCurrentFrameBuffer: PROC RETURNS [pm: PixelMap] = TRUSTED { fb: Terminal.FrameBuffer = Terminal.Current[].GetBWFrameBuffer[]; pm _ ImagerPixelMap.CreateFrameBuffer[ pointer: fb.base, words: LONG[fb.wordsPerLine]*fb.height, lgBitsPerPixel: Lg[fb.bitsPerPixel], rast: fb.wordsPerLine, lines: fb.height, ref: fb]; }; Lg: PROC [n: NAT] RETURNS [lg: [0 .. 4]] = { lg _ SELECT n FROM 1 => 0, 2 => 1, 4 => 2, 8 => 3, 16 => 4, ENDCASE => ERROR; }; AllocSame: PROC [pattern: PixelMap] RETURNS [same: PixelMap] = { same _ ImagerPixelMap.Create[pattern.refRep.lgBitsPerPixel, pattern.BufferBounds[]].Clip[pattern.Window[]]; }; PMContext: PROC [pm: PixelMap] RETURNS [context: Context] = { context _ ImagerRaster.Create[ImagerRaster.NewBitmapDevice[pm], TRUE]; }; screen: PixelMap _ GetCurrentFrameBuffer[]; bounds: ImagerPixelMap.DeviceRectangle = screen.BoundedWindow[]; screenCopy: PixelMap _ AllocSame[screen]; mine: PixelMap _ AllocSame[screen]; Setup: PROC = { myContext: Context = PMContext[mine]; scaledFont: ImagerFont.Font = font.Scale[bounds.sSize/2.2]; ae: ImagerFont.Extents = scaledFont.RopeBoundingBox["April"]; fe: ImagerFont.Extents = scaledFont.RopeBoundingBox["Fool!"]; Imager.SetColor[myContext, Imager.black]; Imager.MaskRectangle[myContext, [0, 0, bounds.fSize, bounds.sSize]]; Imager.SetColor[myContext, Imager.white]; Imager.SetFont[myContext, scaledFont]; Imager.SetXY[myContext, [ x: (bounds.fSize - (fe.rightExtent + fe.leftExtent))/2, y: (bounds.sSize/2 - (fe.ascent + fe.descent))/2]]; Imager.ShowRope[myContext, "Fool!"]; Imager.TranslateT[myContext, [bounds.fSize, bounds.sSize]]; Imager.ScaleT[myContext, -1]; Imager.SetXY[myContext, [ x: (bounds.fSize - (ae.rightExtent + ae.leftExtent))/2, y: (bounds.sSize/2 - (ae.ascent + ae.descent))/2]]; Imager.ShowRope[myContext, "April"]; }; GiveMsg: PROC = { Inner: PROC = { ReallyInner: PROC = { screenCopy.Transfer[screen]; Drain[screen, mine, bounds.sMin + bounds.sSize/2, bounds.fMin + bounds.fSize/2]; Drain[screen, screenCopy, bounds.sMin + bounds.sSize/2, bounds.fMin + bounds.fSize/2]; }; errorMessage _ BackStop.Call[ReallyInner]; }; screen _ GetCurrentFrameBuffer[]; Carets.SuspendCarets[]; ViewerLocks.CallUnderViewerTreeLock[Inner]; Carets.ResumeCarets[]; }; errorMessage: ROPE _ NIL; Messenger: PROC = { DO unpacked: BasicTime.Unpacked = BasicTime.Unpack[BasicTime.Now[]]; IF unpacked.month > April OR (unpacked.month = April AND unpacked.day > 1) THEN EXIT; IF unpacked.month < April THEN {Process.Pause[halfAnHour]; LOOP}; Process.Pause[Process.SecondsToTicks[rs.ChooseInt[minPause, maxPause]]]; GiveMsg[]; ENDLOOP; }; halfAnHour: Process.Ticks _ Process.SecondsToTicks[1800]; minPause: INTEGER _ 1000; maxPause: INTEGER _ 2000; ForkMessenger: PROC = TRUSTED {Process.Detach[FORK Messenger[]]}; Setup[]; ForkMessenger[]; END. ~MakeDoAux2Impl.Mesa Last Edited by: Spreitzer, March 30, 1986 3:10:27 pm PST Carl Hauser, April 11, 1985 3:43:34 pm PST สส– "cedar" style˜code™J™8K™*—K˜Kšฯk œ}˜†K˜šัbnxœœ˜Kšœv˜}Kšœ˜—K˜Kš˜K˜Kšœœœ˜Kšœ œ˜)Kšœ œ˜K˜Kšœ2˜2K˜KK˜šฯnœœ.ฯc$œ˜iKšœ:˜:šœœ˜.Kšœœ4˜:šœœ˜Kšœ œ˜šœœ˜Kšœ œ˜&šœœ˜KšœT˜TKšœ#˜#Kšœ˜—K˜PK˜K˜—šœ˜Kšœœ"˜+Kšœ œ˜šœœ˜KšœP˜PKšœ#˜#Kšœ˜—KšœI˜IK˜—K˜ K˜—šœ˜Kšœ œ"˜.šœœ˜Kšœ œ˜&šœœ˜KšœT˜TKšœ#˜#Kšœ˜—K˜PK˜K˜—šœ˜Kšœœ"˜+Kšœ œ˜šœœ˜KšœP˜PKšœ#˜#Kšœ˜—KšœI˜IK˜—K˜ K˜—Kšœ˜—K˜—K˜šŸœœœœ˜>KšœA˜Ašœ&˜&K˜Kšœœ˜'Kšœ$˜$Kšœ˜K˜K˜ —K˜—K˜šŸœœœœ˜,šœœ˜K˜K˜K˜K˜K˜Kšœœ˜—K˜—K˜šŸ œœœ˜@Kšœk˜kK˜—K˜šŸ œœœ˜=Kšœ@œ˜FK˜—K˜Kšœ+˜+Kšœ@˜@Kšœ)˜)Kšœ#˜#K˜šŸœœ˜Kšœ%˜%K˜;Kšœ=˜=Kšœ=˜=K˜)K˜DK˜)K˜&˜K˜7Kšœ3˜3—K˜$Kšœ;˜;Kšœ˜˜K˜7Kšœ3˜3—K˜$K˜—K˜šŸœœ˜šœœ˜šŸ œœ˜Kšœ˜KšœP˜PKšœV˜VK˜—K˜*K˜—Kšœ!˜!K˜Kšœ+˜+K˜K˜—K˜Kšœœœ˜K˜šŸ œœ˜š˜K˜AKš œœœœœ˜UKšœœœ˜AKšœH˜HKšœ ˜ Kšœ˜—K˜Kšœ9˜9Kšœ œ˜Kšœ œ˜—K˜KšŸ œœœœ˜AK˜K˜K˜K˜Kšœ˜—…—า