DIRECTORY Ascii USING [Lower], Buttons USING [Button, ButtonProc, Create, SetDisplayStyle], ColorDisplay USING [CDNotifyProc, CDRegistration, CDState], ColorDisplayDefs USING [colorMode24, ColorDisplayType, ColorMode], ColorDisplayFace USING [SetDisplayType], Commander USING [CommandProc, Register], Containers USING [Container, Create], Imager, ImagerDevice, ImagerTerminal, InterminalBackdoor, ImagerCache, ImagerRaster, ImagerColorMap, ImagerColor USING [ColorFromGray], ImagerForkContext USING [Create], ImagerGray USING [Create, LikeScreen], ImagerMaskContext USING [Create], ImagerPixelMap USING [PixelMap, PixelMapRep], Interminal USING [GetColorDisplaySide, SetColorDisplaySide], IO USING [card, EndOfStream, GetTokenRope, IDProc, PutF, RIS, rope, STREAM], MessageWindow USING [Append, Blink], Process USING [Detach, Pause, SetTimeout, Ticks], Rope USING [Equal, Fetch, Length, ROPE, Translate, TranslatorType], SafeStorage USING [ReclaimCollectibleObjects], Terminal USING [BitmapState, CantDoIt, ChannelsVisible, ColorMode, Current, FrameBuffer, GetColorBitmapState, GetColorMode, GetColorFrameBufferA, GetColorFrameBufferB, GetVisibility, SetColorBitmapState, SetColorCursorPresentation, SetColorMode, Virtual], UserProfile USING [Boolean, Number, Token], ViewerClasses USING [Viewer], ViewerOps USING [ChangeColumn, CloseViewer, ComputeColumn, EnumerateViewers, EnumProc, OpenIcon, PaintEverything, SetOpenHeight], ViewerPrivate USING [Screen, SetCreator], WindowManager USING [colorDisplayOn, ScreenPos, StartColorViewers, StopColorViewers]; ColorDisplayImpl: CEDAR MONITOR IMPORTS Ascii, Buttons, ColorDisplayFace, Commander, Containers, ImagerCache, ImagerColor, ImagerColorMap, ImagerForkContext, ImagerGray, ImagerMaskContext, ImagerRaster, ImagerTerminal, Interminal, InterminalBackdoor, IO, MessageWindow, Process, Rope, SafeStorage, Terminal, UserProfile, ViewerOps, ViewerPrivate, WindowManager EXPORTS ColorDisplay ~ BEGIN OPEN ColorDisplay; bppLast: PUBLIC CARDINAL _ 8; bppBLast: PUBLIC CARDINAL _ 0; onLeftLast: PUBLIC BOOLEAN _ TRUE; grayLast: PUBLIC BOOLEAN _ FALSE; monitorTypeLast: PUBLIC Rope.ROPE _ "640x480"; DefaultBpp, Bpp: PUBLIC PROC RETURNS [bpp: CARDINAL] ~ { -- remembers bpp IF WindowManager.colorDisplayOn THEN { OPEN Terminal; colorMode: ColorMode _ GetColorMode[Current[]]; bpp _ (IF colorMode.full THEN 24 ELSE colorMode.bitsPerPixelChannelA); } ELSE bpp _ bppLast; bppLast _ bpp; --Remember the setting of the screen }; DefaultBppB, BppB: PUBLIC PROC RETURNS [bpp: CARDINAL] ~ { -- remembers bpp IF WindowManager.colorDisplayOn THEN { OPEN Terminal; colorMode: ColorMode _ GetColorMode[Current[]]; bpp _ (IF colorMode.full THEN 0 ELSE colorMode.bitsPerPixelChannelB); } ELSE bpp _ bppBLast; bppBLast _ bpp; --Remember the setting of the screen }; DefaultOnLeft, OnLeft: PUBLIC PROC RETURNS [onLeft: BOOLEAN] ~ { onLeft _ IF WindowManager.colorDisplayOn THEN Interminal.GetColorDisplaySide[] = left ELSE onLeftLast; onLeftLast _ onLeft; }; DefaultGray, Gray: PUBLIC PROC RETURNS [onLeft: BOOLEAN] ~ { RETURN[grayLast]; }; DefaultOn: PUBLIC PROC RETURNS [BOOLEAN] ~ { RETURN[WindowManager.colorDisplayOn]; }; DefaultMonitorType: PUBLIC PROC RETURNS [Rope.ROPE] ~ { RETURN[monitorTypeLast]; }; MessageBlink: PROC [message: Rope.ROPE] ~ { MessageWindow.Append[message, TRUE]; MessageWindow.Blink[]; }; SetColorDisplayStatus: PUBLIC ENTRY PROC [on: BOOLEAN _ DefaultOn[], onLeft: BOOLEAN _ DefaultOnLeft[], gray: BOOL _ DefaultGray[], bpp: CARDINAL _ DefaultBpp[], bppB: CARDINAL _ DefaultBppB[], monitorType: Rope.ROPE _ DefaultMonitorType[]] = { ENABLE UNWIND => NULL; NOTIFY forCDChanges; --Let the informant know... IF NOT InterminalBackdoor.terminal.hasColorDisplay THEN RETURN; -- No color display. SELECT bpp FROM 1, 2, 4, 8, 24 => NULL; ENDCASE => {MessageBlink["Invalid bits per pixel."]; RETURN}; SELECT bppB FROM 0, 1, 2 => NULL; ENDCASE => {MessageBlink["Invalid bits per pixel on chan B."]; RETURN}; IF NOT (Rope.Equal[s1: monitorType, s2: "640x480", case: FALSE] OR Rope.Equal[s1: monitorType, s2: "1024x768", case: FALSE]) THEN { MessageBlink["Invalid monitor type."]; RETURN}; SELECT TRUE FROM (on = WindowManager.colorDisplayOn AND bpp = Bpp[] AND bppB = BppB[] AND Rope.Equal[monitorType, monitorTypeLast, FALSE] AND onLeft=OnLeft[] AND gray=Gray[]) => RETURN; (on = WindowManager.colorDisplayOn AND Rope.Equal[monitorType, monitorTypeLast, FALSE] AND Bpp[] = bpp AND gray # Gray[] AND on) => {IF Gray[] THEN DefaultViewers[] ELSE GrayViewers[]; grayLast _ NOT grayLast; RETURN}; (on = WindowManager.colorDisplayOn AND Rope.Equal[monitorType, monitorTypeLast, FALSE] AND Bpp[] # 8 AND gray # Gray[] AND on) => {RETURN}; (on = WindowManager.colorDisplayOn AND bpp = Bpp[] AND bppB = BppB[] AND Rope.Equal[monitorType, monitorTypeLast, FALSE] AND gray=Gray[] AND on) => { IF Interminal.GetColorDisplaySide[] = left THEN Interminal.SetColorDisplaySide[right] ELSE Interminal.SetColorDisplaySide[left]}; ENDCASE => TRUSTED { colorViewerList, colorIconList: LIST OF ViewerClasses.Viewer _ NIL; --Really only viewers, tho ListColorViewers: PROC ~ TRUSTED { -- Constructs a list of the color viewers EnumColorViewers: ViewerOps.EnumProc ~ TRUSTED { IF v.column=color THEN IF v.iconic THEN colorIconList _ CONS[v,colorIconList] ELSE { ViewerOps.CloseViewer[v, FALSE]; colorViewerList _ CONS[v, colorViewerList]; }; }; ViewerOps.EnumerateViewers[enum: EnumColorViewers]; ViewerOps.ComputeColumn[static]; }; ReopenColorViewers: PROC ~ TRUSTED { -- Reopen the listed color viewers FOR each: LIST OF ViewerClasses.Viewer _ colorViewerList, each.rest UNTIL each=NIL DO ViewerOps.ChangeColumn[each.first, color]; ViewerOps.OpenIcon[icon: each.first, paint: TRUE]; -- should be FALSE but call below to ComputeColumn doesn't repaint if no size change! ENDLOOP; ViewerOps.ComputeColumn[color]; FOR each: LIST OF ViewerClasses.Viewer _ colorIconList, each.rest UNTIL each=NIL DO ViewerOps.ChangeColumn[each.first, color]; ENDLOOP; }; side: WindowManager.ScreenPos _ IF onLeft THEN left ELSE right; ok: BOOL _ FALSE; onLeftLast _ onLeft; bppLast _ bpp; bppBLast _ bppB; grayLast _ gray; monitorTypeLast _ monitorType; --Back up the given parameters ListColorViewers[]; -- Make a list of all the viewers on the color display (if any) WindowManager.StopColorViewers[]; -- Turn off display IF on THEN { SELECT TRUE FROM Rope.Equal[s1: monitorType, s2: "640x480", case: FALSE] => ok _ Start640Monitor[bitsPerPixel: bpp, bitsPerPixelB: bppB, pos: side]; Rope.Equal[s1: monitorType, s2: "1024x768", case: FALSE] => ok _ Start1024Monitor[bitsPerPixel: bpp, bitsPerPixelB: bppB, pos: side]; ENDCASE => MessageBlink["Invalid monitor type!!"]; IF NOT ok THEN {MessageBlink["Can't turn on color!"]; RETURN}; IF bpp = 8 THEN {IF grayLast THEN GrayViewers[] ELSE DefaultViewers[]}; ReopenColorViewers[]; }; }; }; StartMonitor: PROC [type: ColorDisplayDefs.ColorDisplayType, bitsPerPixel, bitsPerPixelB: CARDINAL, pos: WindowManager.ScreenPos] ~ { mode: ColorDisplayDefs.ColorMode ~ IF bitsPerPixel = 24 THEN ColorDisplayDefs.colorMode24 ELSE [FALSE, bitsPerPixel, bitsPerPixelB]; []_ ColorDisplayFace.SetDisplayType[type]; FOR try: CARDINAL IN [1..3] DO []_ Terminal.SetColorMode[InterminalBackdoor.terminal, mode ! Terminal.CantDoIt => { --Try a bit of garbage collection SELECT try FROM 1 => { MessageWindow.Append["Couldn't allocate frame. Garbage collecting...", TRUE]; SafeStorage.ReclaimCollectibleObjects[]; LOOP; }; 2 => { MessageWindow.Append[".....GARBAGE COLLECTING!!!"]; SafeStorage.ReclaimCollectibleObjects[traceAndSweep: TRUE]; LOOP; }; 3 => { MessageWindow.Append["Couldn't do it. Sure you have a color display?", TRUE]; }; ENDCASE => ERROR; }; ]; ENDLOOP; WindowManager.StartColorViewers[pos, bitsPerPixel]; }; Start640Monitor: PUBLIC PROCEDURE [bitsPerPixel: CARDINAL _ 8, bitsPerPixelB:CARDINAL _ 0, pos: WindowManager.ScreenPos _ left] RETURNS [ok: BOOL _ TRUE] = { StartMonitor[standard, bitsPerPixel, bitsPerPixelB, pos]; }; Start1024Monitor: PUBLIC PROCEDURE [bitsPerPixel: CARDINAL _ 8, bitsPerPixelB:CARDINAL _ 0, pos: WindowManager.ScreenPos _ left] RETURNS [ok: BOOL _ TRUE] = { IF bitsPerPixel = 24 THEN RETURN [FALSE]; StartMonitor[highResolution, bitsPerPixel, bitsPerPixelB, pos]; }; GetColorDisplayStatus: PUBLIC ENTRY PROC RETURNS [on, onLeft, gray: BOOLEAN, bpp, bppB: CARDINAL, monitorType: Rope.ROPE] ~ { ENABLE UNWIND => NULL; [on, onLeft, gray, bpp, bppB, monitorType] _ GetColorDisplayStatusInternal[]; }; GetCDState: INTERNAL PROC RETURNS [state: CDState] ~ INLINE { [state.on, state.onLeft, state.gray, state.bpp, state.bppB, state.monitorType] _ GetColorDisplayStatusInternal[]; }; GetColorDisplayStatusInternal: INTERNAL PROC RETURNS [on, onLeft, gray: BOOLEAN, bpp, bppB: CARDINAL, monitorType: Rope.ROPE] ~ { on _ WindowManager.colorDisplayOn; onLeft _ OnLeft[]; bpp _ Bpp[]; bppB _ BppB[]; monitorType _ monitorTypeLast; gray _ grayLast; }; GetColorDisplayProfile: PUBLIC PROC RETURNS [on, onLeft, gray: BOOLEAN, bpp, bppB: CARDINAL, monitorType: Rope.ROPE] ~ { RightOrLeft: PROC RETURNS[rl: Rope.ROPE] ~ INLINE {rl _ IF onLeftLast THEN "left" ELSE "right"}; tBpp, tBppB: INTEGER; --Temporary bits per pixel on _ WindowManager.colorDisplayOn; SELECT tBpp _ UserProfile.Number["ColorDisplay.BitsPerPoint", Bpp[]] FROM 1, 2, 4, 8, 24 => bpp _ tBpp; ENDCASE => bpp _ Bpp[]; SELECT tBppB _ UserProfile.Number["ColorDisplay.BitsPerPointB", BppB[]] FROM 0, 1, 2 => bppB _ tBppB; ENDCASE => bppB _ Bpp[]; onLeft _ Rope.Equal[UserProfile.Token["ColorDisplay.Side", RightOrLeft[]], "left", FALSE]; monitorType _ UserProfile.Token["ColorDisplay.Type", monitorTypeLast]; gray _ UserProfile.Boolean["ColorDisplay.Gray", grayLast]; }; procList: LIST OF REF NotifyRecord _ NIL; --Dummy NotifyRecord: TYPE ~ RECORD [ proc: CDNotifyProc, clientData: REF ]; RegisterCDNotifyProc: PUBLIC ENTRY PROC [proc: CDNotifyProc, clientData: REF] RETURNS [reg: CDRegistration] ~ { ENABLE UNWIND => NULL; state: CDState ~ GetCDState[]; ref: REF NotifyRecord ~ NEW[NotifyRecord _ [proc: proc, clientData: clientData]]; procList _ CONS[ref, procList]; TRUSTED {Process.Detach[FORK proc[state, state, clientData]]}; RETURN [ref] }; UnregisterCDNotifyProc: PUBLIC ENTRY PROC [reg: CDRegistration] ~ { ENABLE UNWIND => NULL; ref: REF NotifyRecord ~ NARROW[reg]; WHILE procList # NIL AND procList.first = ref DO --Eliminate if at beginning procList _ procList.rest; ENDLOOP; FOR p: LIST OF REF NotifyRecord _ procList, p.rest UNTIL p=NIL DO WHILE p.rest # NIL AND p.rest.first = reg DO p.rest _ p.rest.rest; ENDLOOP; ENDLOOP; }; forCDChanges: CONDITION; WatchForChanges: ENTRY PROC ~ { ENABLE UNWIND => NULL; old, new: CDState _ GetCDState[]; DO WHILE old = (new _ GetCDState[]) DO WAIT forCDChanges; ENDLOOP; FOR each: LIST OF REF NotifyRecord _ procList, each.rest UNTIL each = NIL DO TRUSTED {Process.Detach[FORK each.first.proc[old, new, each.first.clientData]];} ENDLOOP; old _ new; ENDLOOP; }; SleepColorDisplay: PUBLIC ENTRY UNSAFE PROC [ticks: Process.Ticks] ~ { ENABLE UNWIND => NULL; vt: Terminal.Virtual _ InterminalBackdoor.terminal; state: Terminal.BitmapState _ Terminal.GetColorBitmapState[vt]; mode: Terminal.ColorMode _ Terminal.GetColorMode[vt]; visible: Terminal.ChannelsVisible _ Terminal.GetVisibility[vt]; IF state # displayed THEN RETURN; [] _ Terminal.SetColorBitmapState[vt, allocated, mode, none]; Process.Pause[ticks]; [] _ Terminal.SetColorBitmapState[vt, state, mode, visible]; }; Context: TYPE ~ Imager.Context; GrayCreateContext: PROC [screen: ViewerPrivate.Screen] RETURNS [context: Imager.Context] ~ { terminal: Terminal.Virtual ~ InterminalBackdoor.terminal; SELECT screen FROM bw => context _ ImagerTerminal.BWContext[vt: terminal, pixelUnits: TRUE]; color => { contextB, contextM: Imager.Context; fb: Terminal.FrameBuffer _ Terminal.GetColorFrameBufferB[terminal]; context _ GrayContext[vt: terminal, pixelUnits: TRUE]; IF fb#NIL AND ~Terminal.GetColorMode[terminal].full THEN { frame: ImagerPixelMap.PixelMap ~ PixelMapFromFrameBuffer[fb]; contextB _ ImagerGray.Create[frame, $Intensity, ImagerGray.LikeScreen[frame.sSize], 1, NIL, NIL, TRUE]; contextM _ ImagerMaskContext.Create[contextB, ImagerColor.ColorFromGray[1]]; context _ ImagerForkContext.Create[context, contextM]; }; } ENDCASE => ERROR; }; DitherCreateContext: PROC [screen: ViewerPrivate.Screen] RETURNS [context: Imager.Context] ~ { terminal: Terminal.Virtual ~ InterminalBackdoor.terminal; SELECT screen FROM bw => context _ ImagerTerminal.BWContext[vt: terminal, pixelUnits: TRUE]; color => { contextB, contextM: Imager.Context; fb: Terminal.FrameBuffer _ Terminal.GetColorFrameBufferB[terminal]; context _ ImagerTerminal.ColorContext[vt: terminal, pixelUnits: TRUE]; IF fb#NIL AND ~Terminal.GetColorMode[terminal].full THEN { frame: ImagerPixelMap.PixelMap ~ PixelMapFromFrameBuffer[fb]; contextB _ ImagerGray.Create[frame, $Intensity, ImagerGray.LikeScreen[frame.sSize], 1, NIL, NIL, TRUE]; contextM _ ImagerMaskContext.Create[contextB, ImagerColor.ColorFromGray[1]]; context _ ImagerForkContext.Create[context, contextM]; }; }; ENDCASE => ERROR; }; PixelMapFromFrameBuffer: PROC [frameBuffer: Terminal.FrameBuffer] RETURNS [ImagerPixelMap.PixelMap] ~ { Lg: PROC [n: NAT] RETURNS [NAT] ~ { RETURN[SELECT n FROM 1 => 0, 2 => 1, 4 => 2, 8 => 3, 16 => 4, ENDCASE => ERROR] }; refRep: REF ImagerPixelMap.PixelMapRep ~ NEW[ImagerPixelMap.PixelMapRep _ [ ref: frameBuffer, pointer: frameBuffer.base, words: INT[frameBuffer.wordsPerLine]*INT[frameBuffer.height], lgBitsPerPixel: Lg[frameBuffer.bitsPerPixel], rast: frameBuffer.wordsPerLine, lines: frameBuffer.height ]]; frame: ImagerPixelMap.PixelMap ~ [ sOrigin: 0, fOrigin: 0, sMin: 0, fMin: 0, sSize: frameBuffer.height, fSize: frameBuffer.width, refRep: refRep ]; RETURN[frame]; }; gamma: REAL _ 2.2; fontCacheID: ATOM ~ $ColorDisplay; fontCacheSize: NAT _ 10000; fontRastWeight: REAL _ 0.0; GrayContext: PROC [vt: Terminal.Virtual, pixelUnits: BOOL] RETURNS [Context] ~ { mode: Terminal.ColorMode ~ Terminal.GetColorMode[vt]; IF Terminal.GetColorBitmapState[vt]=none THEN RETURN[NIL] ELSE { frameBuffer: Terminal.FrameBuffer ~ Terminal.GetColorFrameBufferA[vt]; fontCache: ImagerCache.Ref ~ ImagerCache.GetNamedCache[ atom: fontCacheID, createSize: fontCacheSize]; device: ImagerDevice.Device ~ ImagerRaster.NewGrayDevice[vt]; [] _ Terminal.SetColorCursorPresentation[vt, onesAreBlack]; ImagerColorMap.SetStandardGrayMap[vt: vt, gamma: gamma]; RETURN[ImagerRaster.Create[device: device, pixelUnits: pixelUnits, fontCache: fontCache, rastWeight: fontRastWeight]]; }; }; GrayViewers: PUBLIC PROC ~ { [] _ ViewerPrivate.SetCreator[GrayCreateContext]; ViewerOps.PaintEverything[]; }; DefaultViewers: PUBLIC PROC ~ { [] _ ViewerPrivate.SetCreator[DitherCreateContext]; ImagerColorMap.SetStandardColorMap[vt: InterminalBackdoor.terminal, gamma: gamma]; ViewerOps.PaintEverything[]; }; Init: PROC[] RETURNS[] ~ { -- DefaultViewers[]; [ , onLeftLast, grayLast, bppLast, bppBLast, monitorTypeLast] _ GetColorDisplayProfile[]; TRUSTED { Process.SetTimeout[@forCDChanges, 300]; Process.Detach[FORK WatchForChanges[]]; }; Commander.Register[key:"ColorDisplay", proc: FiddleWithDisplay, doc: "Configure color monitor"]; [] _ Buttons.Create[ info: [name: "Color"], proc: BugColor, fork: FALSE ]; }; FiddleWithDisplay: Commander.CommandProc ~ { MyLower: Rope.TranslatorType = BEGIN RETURN[Ascii.Lower[old]]; END; myOn, myGray: BOOLEAN; myBpp, myBppB: CARDINAL; myOnLeft: BOOLEAN; myMonType: Rope.ROPE; noParams: BOOLEAN _ TRUE; s: IO.STREAM _ IO.RIS[Rope.Translate[base: cmd.commandLine, translator: MyLower]]; [myOn, myOnLeft, myGray, myBpp, myBppB, myMonType] _ GetColorDisplayStatus[]; DO f: Rope.ROPE _ IO.GetTokenRope[s, IO.IDProc ! IO.EndOfStream => EXIT].token; noParams _ FALSE; SELECT Rope.Fetch[f, 0] FROM '0 => myOn _ FALSE; '1 => IF Rope.Equal[f, "1024x768"] THEN { myMonType _ "1024x768"; myOn _ TRUE } ELSE IF Rope.Length[f]=1 THEN {myBpp _ 1; myOn _ TRUE; } ELSE { IO.PutF[cmd.err, "Option %g that begins with a 1 has to be 1024x768 or 1 exactly.\n", IO.rope[f]]; RETURN; }; '2 => IF Rope.Equal[f, "24"] THEN { myOn _ TRUE; myBpp _ 24 } ELSE IF Rope.Length[f]=1 THEN { myBpp _ 2; myOn _ TRUE } ELSE { IO.PutF[cmd.err, "Can't do %g bpp\n", IO.rope[f]]; RETURN; }; '4 => { myBpp _ 4; myOn _ TRUE }; '6 => { IF Rope.Equal[f, "640x480"] THEN { myMonType _ "640x480"; myOn _ TRUE } ELSE { IO.PutF[cmd.err, "%g is an invalid key\n", IO.rope[f]]; RETURN; }; }; '8 => { myBpp _ 8; myOn _ TRUE }; 'l => { myOnLeft _ TRUE; myOn _ TRUE }; 'r => { myOnLeft _ FALSE; myOn _ TRUE }; 'd => { IF Rope.Equal[f, "default"] THEN [myOn, myOnLeft, myGray, myBpp, myBppB, myMonType] _ GetColorDisplayProfile[] ELSE {myGray _ FALSE; myOn _ TRUE }; }; '+ => { SELECT TRUE FROM Rope.Equal[f, "+2"] => { myBppB _ 2; myOn _ TRUE }; Rope.Equal[f, "+1"] => { myBppB _ 1; myOn _ TRUE }; Rope.Equal[f, "+0"] => { myBppB _ 0; myOn _ TRUE }; ENDCASE => { IO.PutF[cmd.err, "valid B channel values are 0,1,2\n"]; RETURN; }; }; 'o => IF Rope.Equal[f, "on"] THEN myOn _ TRUE ELSE IF Rope.Equal[f, "off"] THEN myOn _ FALSE ELSE { IO.PutF[cmd.err, "%g is an invalid key\n", IO.rope[f]]; RETURN; }; 'g => { myGray _ TRUE; myOn _ TRUE }; '? => IO.PutF[cmd.err, "%g, %g bpp, %g, %g, %g\n", IO.rope[IF myOn THEN "on" ELSE "off"], IO.card[myBpp], IO.rope[IF myOnLeft THEN "left" ELSE "right"], IO.rope[myMonType], IO.rope[(IF myGray THEN "Gray" ELSE "Dither")]]; ENDCASE => { IO.PutF[cmd.err, "%g is an invalid key\n", IO.rope[f]]; RETURN[]; }; ENDLOOP; IF noParams THEN myOn _ ~myOn; SetColorDisplayStatus[myOn, myOnLeft, myGray, myBpp, myBppB, myMonType]; }; ButtonSet: TYPE ~ RECORD [ on, off, left, right, lowres, highres, c1, c2, c4, c8, c24, gray, dither: Buttons.Button _ NIL, reg: CDRegistration _ NIL, cdt: Containers.Container _ NIL ]; CreateColorDisplayTool: PROC ~ { bs: REF ButtonSet ~ NEW[ButtonSet]; prev: Buttons.Button; hMargin: INT ~ -1; hSeparator: INT ~ 10; vMargin: INT ~ 5; vHeight: INT ~ 10; thisX, thisY: INT; CreateCDTButton: PROC [name: Rope.ROPE, proc: Buttons.ButtonProc, extraOffset: INT _ 0] RETURNS [button: Buttons.Button] ~ { button _ prev _ Buttons.Create[ info: [ name: name, wx: thisX, wy: thisY, parent: bs.cdt, border: TRUE ], proc: proc ]; thisX _ thisX + prev.ww + hMargin + extraOffset; }; bs.cdt _ Containers.Create[ info: [ name: "ColorDisplayTool", column: right, scrollable: FALSE ] ]; thisX _ hMargin+hSeparator; thisY _ vMargin; bs.on _ CreateCDTButton["On", CDTOn]; --On Button bs.off _ CreateCDTButton["Off", CDTOff, hSeparator]; --Off Button bs.c1 _ CreateCDTButton["1 ", CDT1]; --1 Button bs.c2 _ CreateCDTButton["2 ", CDT2]; --2 Button bs.c4 _ CreateCDTButton["4 ", CDT4]; --4 Button bs.c8 _ CreateCDTButton["8 ", CDT8]; --8 Button bs.c24 _ CreateCDTButton["24 ", CDT24, hSeparator]; --24 Button bs.left _ CreateCDTButton["Left", CDTLeft]; --Left Button bs.right _ CreateCDTButton["Right", CDTRight, hSeparator]; --Right Button bs.lowres _ CreateCDTButton["640x480", CDTLowRes]; --640x480 Button bs.highres _ CreateCDTButton["1024x768", CDTHighRes, hSeparator]; --1024x768 Button bs.gray _ CreateCDTButton["Gray", CDTGray]; bs.dither _ CreateCDTButton["Dither", CDTDither, hSeparator]; bs.reg _ RegisterCDNotifyProc[MonitorButtons, bs]; ViewerOps.SetOpenHeight[bs.cdt, thisY + vHeight + 2*vMargin]; ViewerOps.OpenIcon[icon: bs.cdt, bottom: FALSE]; }; shouldBeLit: ARRAY BOOLEAN OF ATOM ~ [$BlackOnWhite, $WhiteOnBlack]; MonitorButtons: CDNotifyProc ~ { Repaint: PROC [button: Buttons.Button, condition: BOOLEAN] ~ INLINE { OPEN Buttons; Buttons.SetDisplayStyle[button, shouldBeLit[condition]]; }; bs: REF ButtonSet ~ NARROW[clientData]; IF bs.cdt=NIL OR bs.cdt.destroyed THEN { --No point blowing ourselves to smithereens. UnregisterCDNotifyProc[bs.reg]; RETURN; }; Repaint[bs.on, new.on]; Repaint[bs.off, ~ new.on]; Repaint[bs.c1, new.bpp = 1]; Repaint[bs.c2, new.bpp = 2]; Repaint[bs.c4, new.bpp = 4]; Repaint[bs.c8, new.bpp = 8]; Repaint[bs.c24, new.bpp = 24]; Repaint[bs.left, new.onLeft]; Repaint[bs.right, ~ new.onLeft]; Repaint[bs.lowres, new.monitorType.Equal["640x480"]]; Repaint[bs.highres, ~ new.monitorType.Equal["640x480"]]; Repaint[bs.gray, new.gray]; Repaint[bs.dither, ~ new.gray]; }; CDTOn: Buttons.ButtonProc ~ {SetColorDisplayStatus[on: TRUE]}; CDTOff: Buttons.ButtonProc ~ {SetColorDisplayStatus[on: FALSE]}; CDTLeft: Buttons.ButtonProc ~ {SetColorDisplayStatus[onLeft: TRUE]}; CDTRight: Buttons.ButtonProc ~ {SetColorDisplayStatus[onLeft: FALSE]}; CDTLowRes: Buttons.ButtonProc ~ {SetColorDisplayStatus[monitorType: "640x480"]}; CDTHighRes: Buttons.ButtonProc ~ {SetColorDisplayStatus[monitorType: "1024x768"]}; CDT1: Buttons.ButtonProc ~ {SetColorDisplayStatus[on: FALSE, bpp: 1]}; CDT2: Buttons.ButtonProc ~ {SetColorDisplayStatus[on: FALSE, bpp: 2]}; CDT4: Buttons.ButtonProc ~ {SetColorDisplayStatus[on: FALSE, bpp: 4]}; CDT8: Buttons.ButtonProc ~ {SetColorDisplayStatus[on: FALSE, bpp: 8]}; CDT24: Buttons.ButtonProc ~ { IF grayLast THEN MessageBlink["Can't be gray and 24bpp."] ELSE SetColorDisplayStatus[on: FALSE, bpp: 24, gray: FALSE, monitorType: "640x480"]; }; CDTGray: Buttons.ButtonProc ~ { IF bppLast = 24 THEN MessageBlink["Can't be gray and 24bpp."] ELSE SetColorDisplayStatus[gray: TRUE]; }; CDTDither: Buttons.ButtonProc ~ {SetColorDisplayStatus[gray: FALSE]}; BugColor: Buttons.ButtonProc ~ { SELECT mouseButton FROM red => SetColorDisplayStatus[on: ~GetColorDisplayStatus[].on]; yellow => TRUSTED {SleepColorDisplay[300]}; blue => CreateColorDisplayTool[]; ENDCASE; }; Init[]; END.  ColorDisplayImpl.mesa Copyright c 1985, 1986 by Xerox Corporation. All rights reserved. Tim Diebert: May 20, 1986 10:56:50 am PDT Bloomenthal, August 15, 1986 2:29:47 pm PDT Last edited by: Mik Lamming - July 30, 1986 5:43:04 pm PDT bppLast and sideLast are examined only when the color display is off. This lets the ColorDisplay package know where to default them to when the color display is turned on again. NOTE: Every call to the ColorDisplay package will cause these values to be updated with the actual state of the machine, if it is on. Check for nothing changed Check for change in gray in 8 bpp Check for change in gray in 8 bpp Check for just switching sides. Otherwise, we need to check the whole ball of wax Reset the icons that WOULD have been opened on the color display back there -- this should probably get its context from ImagerGray instead of -- ImagerRaster.NewGrayDevice. However while it works don't fix it -- Mik Read the user profile to establish the initial back settings... Register the program with the commander and read user profile Establish the 'color' button up at the top From ColorDisplayCommand The various buttons Set the height of the viewer as a whole This proc toggles the color of the buttons to show currect state of display ÊQ˜code™Kšœ Ïmœ7™BK™)K™+K™:—K˜šÏk ˜ Jšœžœ ˜Jšœžœ/˜Jšžœ˜——šžœžœ3žœ˜?šžœ3žœžœ˜CJšœ&˜&Jšžœ˜——šžœžœž˜K™šœ"˜"Kšžœ ˜Kšžœ˜Kšžœ*žœ˜3Kšžœ˜Kšžœžœ˜—K™K™!šœ"˜"Kšžœ*žœ˜3Kšžœ ˜Kšžœ˜šžœ žœžœžœ˜?Kšœ žœ ˜Kšžœ˜——K™K™!šœ"˜"Kšžœ*žœ˜3Kšžœ ˜ Kšžœ˜Kšžœ žœ˜—K˜K™šœ"˜"Kšžœ ˜Kšžœ˜Kšžœ*žœ˜3Kšžœ ˜šžœ ˜ šžœ(˜*Kšžœ&˜*Kšžœ'˜+———K™K™1šžœžœ˜Kšœ žœžœžœ¡˜_š œžœžœ¡)˜Mš œžœ˜0šžœž˜šžœ žœžœžœ˜=Kšœžœ˜ Kšœžœ˜+Kšœ˜——K˜—K˜3K˜ K˜—š œžœžœ¡"˜Hš žœžœžœ3žœžœž˜UK˜*Kšœ,žœ¡ Ðck¡C˜‰Kšž˜—K˜K™K™Kš žœžœžœ1žœžœž˜SK˜*Kšž˜—K˜—K™Kšœ žœžœžœ˜?Kšœžœžœ˜K˜K˜K˜K˜Kšœ ¡˜>Kšœ¡@˜UKšœ#¡˜6šžœžœ˜ šžœžœž˜K•StartOfExpansion[]šœ1žœM˜ƒK–[]šœ2žœN˜…Kšžœ+˜2—šžœžœž˜Kšœ&˜&Kšžœ˜—šžœž˜Kšœžœ žœžœ˜7—K˜K˜—Kšœ˜——Kšœ˜K˜—š  œžœHžœ%˜‡Kš œ#žœžœžœžœ˜„Kšœ*˜*šžœžœžœž˜šœ;˜;šœ¡!˜;šžœž˜šœ˜KšœHžœ˜NKšœ(˜(Kšžœ˜Kšœ˜—šœ˜Kšœ3˜3Kšœ5žœ˜;Kšžœ˜Kšœ˜—šœ˜KšœHžœ˜NKšœ˜—Kšžœžœ˜—Kšœ˜—Kšœ˜—Kšžœ˜—K˜Kšœ3˜3K˜—š œžœž œžœžœ+žœžœžœ˜Kšœ9˜9K˜—K˜š œžœž œžœžœ*žœžœžœ˜žKšžœžœžœžœ˜)Kšœ?˜?K˜—K˜K˜š œž œžœžœžœ žœžœ˜}Kšžœžœžœ˜KšœM˜MKšœ˜K˜—š   œžœžœžœžœ˜=Kšœq˜qK˜K˜—š œžœžœžœžœ žœžœ˜Kšœ"˜"Kšœ˜Kšœ ˜ Kšœ˜Kšœ˜K˜K˜K˜—š œžœžœžœžœ žœžœ˜xKš  œžœžœ žœžœžœ žœžœ ˜`Kšœ žœ¡˜1K˜Kšœ"˜"šžœ?ž˜IKšœ˜Kšžœ˜—šžœBž˜LKšœ˜Kšžœ˜—KšœSžœ˜ZKšœF˜FKšœ:˜:Kšœ˜K˜—Kš œ žœžœžœžœ¡˜1šœžœžœ˜K˜Kšœ ž˜Kšœ˜—š  œžœžœžœ"žœžœ˜oKšžœžœžœ˜K˜Kšœžœžœ6˜QKšœ žœ˜Kšžœžœ"˜>Kšžœ˜ K˜—š œžœžœžœ˜CKšžœžœžœ˜Kšœžœžœ˜$š žœ žœžœžœ¡˜LK˜Kšžœ˜—š žœžœžœžœ!žœžœž˜Ašžœ žœžœž˜,K˜Kšžœ˜—Kšžœ˜—K˜K˜—Kšœž œ˜š œž œ˜Kšžœžœžœ˜K˜!šž˜šžœž˜#Kšžœ˜Kšž˜—š žœžœžœžœ$žœžœž˜LKšžœžœ4˜PKšž˜—K˜ Kšž˜—K˜K˜—š  œžœžœžœžœ˜FKšžœžœžœ˜K˜3K˜?K˜5K˜?K˜Kšžœžœžœ˜!K˜=K˜K˜Jš œ2žœ˜@Jš œ6žœ˜DJš œ6žœ˜FJš  œG˜PJš  œH˜RJš œ2žœ ˜FJš œ2žœ ˜FJš œ2žœ ˜FJš œ2žœ ˜Fš œ˜šžœ ˜ Jšžœ)˜-Jšžœžœžœ˜T—Jšœ˜—š œ˜šžœ ˜Jšžœ)˜-Jšžœžœ˜'—Jšœ˜—Jš  œ4žœ˜EJ˜š œ˜ šžœ ž˜J˜>Jšœ žœ˜+J˜!Jšžœ˜—J˜J˜—J˜˜K˜˜K˜——K˜K˜Kšžœ˜K™——…—TtqÏ