DIRECTORY ColorDisplay, ColorDisplayDefs USING [colorMode24, ColorDisplayType, ColorMode], ColorDisplayFace USING [SetDisplayType], Imager, ImagerDevice, ImagerTerminal, InterminalBackdoor, ImagerCache, ImagerRaster, ImagerColorMap, Interminal USING [GetColorDisplaySide, SetColorDisplaySide], MessageWindow USING [Append, Blink], Process USING [Detach, Pause, SetTimeout, Ticks], Rope USING [Equal, ROPE], SafeStorage USING [ReclaimCollectibleObjects], Terminal USING [BitmapState, CantDoIt, ChannelsVisible, ColorMode, Current, FrameBuffer, GetColorBitmapState, GetColorMode, GetColorFrameBufferA, GetVisibility, SetColorBitmapState, SetColorCursorPresentation, SetColorMode, Virtual], UserProfile USING [Number, Token], ViewerClasses USING [Viewer], ViewerPrivate, ViewerOps USING [ChangeColumn, CloseViewer, ComputeColumn, EnumerateViewers, EnumProc, OpenIcon, PaintEverything], WindowManager USING [colorDisplayOn, ScreenPos, StartColorViewers, StopColorViewers]; ColorDisplayImpl: CEDAR MONITOR IMPORTS ColorDisplayFace, ImagerTerminal, InterminalBackdoor, ImagerCache, ImagerRaster, ImagerColorMap, Interminal, MessageWindow, Process, Rope, SafeStorage, Terminal, UserProfile, ViewerOps, ViewerPrivate, WindowManager EXPORTS ColorDisplay ~ BEGIN OPEN ColorDisplay; bppLast: PUBLIC CARDINAL _ 8; onLeftLast: PUBLIC BOOLEAN _ TRUE; nowGray: PUBLIC BOOLEAN _ FALSE; monitorTypeLast: PUBLIC Rope.ROPE _ "640x480"; DefaultBpp, Bpp: PUBLIC PROC RETURNS [bpp: CARDINAL] ~ { --Has side effect of remembering 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 }; DefaultOnLeft, OnLeft: PUBLIC PROC RETURNS [onLeft: BOOLEAN] ~ { onLeft _ IF WindowManager.colorDisplayOn THEN Interminal.GetColorDisplaySide[] = left ELSE onLeftLast; onLeftLast _ onLeft; }; DefaultOn: PUBLIC PROC RETURNS [BOOLEAN] ~ { RETURN[WindowManager.colorDisplayOn]; }; DefaultMonitorType: PUBLIC PROC RETURNS [Rope.ROPE] ~ { RETURN[monitorTypeLast]; }; SetColorDisplayStatus: PUBLIC ENTRY PROC [on: BOOLEAN _ DefaultOn[], onLeft: BOOLEAN _ DefaultOnLeft[], gray: BOOL _ FALSE, bpp: CARDINAL _ DefaultBpp[], monitorType: Rope.ROPE _ DefaultMonitorType[]] ~ { ENABLE UNWIND => NULL; NOTIFY forCDChanges; --Let the informant know... SELECT TRUE FROM (on=WindowManager.colorDisplayOn AND bpp=Bpp[] AND monitorType=monitorTypeLast AND onLeft=OnLeft[] AND gray=nowGray) => RETURN; (on=WindowManager.colorDisplayOn AND gray#nowGray) => {IF nowGray THEN DefaultViewers[] ELSE GrayViewers[]; nowGray _ NOT nowGray; RETURN}; (on=WindowManager.colorDisplayOn AND bpp=Bpp[] AND monitorType=monitorTypeLast 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; monitorTypeLast _ monitorType; --Back up the given parameters ListColorViewers[]; WindowManager.StopColorViewers[]; IF on THEN { SELECT TRUE FROM Rope.Equal[s1: monitorType, s2: "640x480", case: FALSE] => ok _ Start640Monitor[bitsPerPixel: bpp, pos: side]; Rope.Equal[s1: monitorType, s2: "1024x768", case: FALSE] => ok _ Start1024Monitor[bitsPerPixel: bpp, pos: side]; ENDCASE => {MessageWindow.Append["Invalid monitor type!!", TRUE]; MessageWindow.Blink[]}; IF NOT ok THEN {MessageWindow.Append["Can't turn on color!"]; MessageWindow.Blink[]; RETURN}; IF nowGray#gray THEN {IF nowGray THEN DefaultViewers[] ELSE GrayViewers[]; nowGray _ NOT nowGray}; ReopenColorViewers[]; }; }; }; StartMonitor: PROC [type: ColorDisplayDefs.ColorDisplayType, bitsPerPixel: CARDINAL, pos: WindowManager.ScreenPos] ~ { mode: ColorDisplayDefs.ColorMode ~ IF bitsPerPixel = 24 THEN ColorDisplayDefs.colorMode24 ELSE [FALSE, 8, 0]; []_ ColorDisplayFace.SetDisplayType[type]; FOR try: CARDINAL IN [1..3] DO []_ Terminal.SetColorMode[Terminal.Current[], 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, pos: WindowManager.ScreenPos _ left] RETURNS [ok: BOOL _ TRUE] = { WindowManager.StopColorViewers[]; StartMonitor[standard, bitsPerPixel, pos]; }; Start1024Monitor: PUBLIC PROCEDURE [bitsPerPixel: CARDINAL _ 8, pos: WindowManager.ScreenPos _ left] RETURNS [ok: BOOL _ TRUE] = { WindowManager.StopColorViewers[]; IF bitsPerPixel = 24 THEN RETURN [FALSE]; StartMonitor[highResolution, bitsPerPixel, pos]; }; GetColorDisplayStatus: PUBLIC ENTRY PROC RETURNS [on, onLeft, gray: BOOLEAN, bpp: CARDINAL, monitorType: Rope.ROPE] ~ { ENABLE UNWIND => NULL; [on, onLeft, gray, bpp, monitorType] _ GetColorDisplayStatusInternal[]; }; GetCDState: INTERNAL PROC RETURNS [state: CDState] ~ INLINE { [state.on, state.onLeft, state.gray, state.bpp, state.monitorType] _ GetColorDisplayStatusInternal[]; }; GetColorDisplayStatusInternal: INTERNAL PROC RETURNS [on, onLeft, gray: BOOLEAN, bpp: CARDINAL, monitorType: Rope.ROPE] ~ { on _ WindowManager.colorDisplayOn; onLeft _ OnLeft[]; bpp _ Bpp[]; monitorType _ monitorTypeLast; gray _ nowGray; }; GetColorDisplayProfile: PUBLIC PROC RETURNS [on, onLeft: BOOLEAN, bpp: CARDINAL, monitorType: Rope.ROPE] ~ { RightOrLeft: PROC RETURNS[rl: Rope.ROPE] ~ INLINE { rl _ IF onLeftLast THEN "left" ELSE "right"}; tBpp: 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[]; onLeft _ Rope.Equal[UserProfile.Token["ColorDisplay.Side", RightOrLeft[]], "left", FALSE]; monitorType _ UserProfile.Token["ColorDisplay.Type", monitorTypeLast]; }; 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] ~ { OPEN Terminal; ENABLE UNWIND => NULL; vt: Virtual _ Current[]; state: BitmapState _ GetColorBitmapState[vt]; mode: ColorMode _ GetColorMode[vt]; visible: ChannelsVisible _ GetVisibility[vt]; IF state#displayed THEN RETURN; [] _ SetColorBitmapState[vt, allocated, mode, none]; Process.Pause[ticks]; [] _ 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 => context _ GrayContext[vt: terminal, pixelUnits: TRUE]; ENDCASE => ERROR; }; gamma: REAL _ 2.2; fontCacheID: ATOM ~ $ColorDisplay; fontCacheSize: NAT _ 4000; 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[NIL]; ImagerColorMap.SetStandardColorMap[vt: InterminalBackdoor.terminal, gamma: gamma]; ViewerOps.PaintEverything[]; }; Init: PROC[] RETURNS[] ~ { [,onLeftLast, bppLast, monitorTypeLast] _ GetColorDisplayProfile[]; TRUSTED { Process.SetTimeout[@forCDChanges, 300]; Process.Detach[FORK WatchForChanges[]]; }; }; Init[]; END. όColorDisplayImpl.mesa Copyright c 1985 by Xerox Corporation. All rights reserved. Created from old ColorDisplay by Mik Lamming and Ken Pier Last Edited by: Nickell, June 22, 1985 12:42:40 pm PDT Last Edited by: Beach, August 17, 1984 5:24:14 pm PDT Last Edited by: Pier, November 19, 1984 3:10:48 pm PST Rick Beach, December 9, 1985 11:04:48 am PST Tim Diebert: October 24, 1985 5:38:30 pm PDT Tim Diebert May 17, 1985 4:50:03 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 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 Read the user profile to establish the initial back settings... CHANGE LOG Rick Beach, December 9, 1985 11:03:49 am PST changes to: SetColorDisplayStatus, ReopenColorViewers (local of SetColorDisplayStatus) to force repaint of color viewer because ComputeColumn does not guarantee to paint all the viewers Κ u˜code™Kšœ Οmœ1™K˜K˜!šžœžœ˜ šžœžœž˜K•StartOfExpansion[]šœ1žœ8˜nK–[]šœ2žœ9˜pšžœ4žœ˜AKšœ˜——šžœžœž˜KšœE˜EKšžœ˜—Kš žœžœžœ žœžœžœ ˜bK˜K˜—Kšœ˜——Kšœ˜K˜—š  œžœ9žœ%˜xKš œ#žœžœžœžœ˜mKšœ*˜*šžœžœžœž˜šœ2˜2šœ‘!˜;šžœž˜šœ˜KšœHžœ˜NKšœ(˜(Kšžœ˜Kšœ˜—šœ˜Kšœ3˜3Kšœ5žœ˜;Kšžœ˜Kšœ˜—šœ˜KšœHžœ˜NKšœ˜—Kšžœžœ˜—Kšœ˜—Kšœ˜—Kšžœ˜—K˜Kšœ3˜3K˜—š œžœž œžœ-žœžœžœ˜ƒK˜!Kšœ*˜*K˜—K˜š œžœž œžœ,žœžœžœ˜„K˜!Kšžœžœžœžœ˜)Kšœ0˜0K˜—K˜K˜š œž œžœžœžœžœžœ˜wKšžœžœžœ˜KšœG˜GKšœ˜K˜—š   œžœžœžœžœ˜=Kšœe˜eK˜K˜—š œžœžœžœžœžœžœ˜{Kšœ"˜"Kšœ˜Kšœ ˜ Kšœ˜K˜K˜K˜—š œžœžœžœžœžœžœ˜lš   œžœžœ žœžœ˜3Kšœžœ žœžœ ˜-—Kšœžœ‘˜+K˜Kšœ"˜"šžœ?ž˜IKšœ˜Kšžœ˜—KšœSžœ˜ZKšœF˜FKšœ˜K˜—Kš œ žœžœžœžœ‘˜1šœžœžœ˜K˜Kšœ ž˜Kšœ˜—š  œžœžœžœ"žœžœ˜oKšžœžœžœ˜K˜Kšœžœžœ6˜QKšœ žœ˜Kšžœžœ"˜>Kšžœ˜ K˜—š œžœžœžœ˜CKšžœžœžœ˜Kšœžœžœ˜$š žœ žœžœžœ‘˜HK˜Kšžœ˜—š žœžœžœžœ!žœžœž˜Ašžœžœžœž˜(K˜Kšžœ˜—Kšžœ˜—K˜K˜—Kšœž œ˜š œž œ˜Kšžœžœžœ˜K˜!šž˜šžœž˜#Kšžœ˜Kšž˜—š žœžœžœžœ$žœžœž˜JKšžœžœ4˜PKšž˜—K˜ Kšž˜—K˜K˜—š  œžœžœžœžœ˜FKšžœ ˜Kšžœžœžœ˜K˜K˜-K˜#K˜-K˜Kšžœžœžœ˜K˜4K˜K˜3K˜K˜—šœ žœ˜K˜—š œžœ žœ˜\Kšœ9˜9šžœž˜KšœCžœ˜IKšœ9žœ˜?Kšžœžœ˜—K˜K˜—šœžœ˜K˜—Kšœ žœ˜"Kšœžœ˜šœžœ˜K˜—š  œžœ$žœžœ˜PK˜5Kšžœ'žœžœžœ˜9šžœ˜KšœF˜FKšœf˜fKšœ=˜=Kšœ;˜;K–-[vt: Terminal.Virtual, gamma: REAL _ 2.2]šœ8˜8Kšžœq˜wK˜—K˜K˜—š  œžœžœ˜Kšœ1˜1K˜Kšœ˜K˜—š œžœžœ˜Kšœžœ˜#K–-[vt: Terminal.Virtual, gamma: REAL _ 2.2]šœR˜RK˜Kšœ˜—š œžœžœ˜K™?K˜Cšžœ˜ Kšœ'˜'Kšœžœ˜'Kšœ˜—K˜K˜—˜K˜——K˜K˜Kšžœ˜K™šžœž™ K™,Kšœ Οr)œ„™Ή—K™—…—)z:λ