<> <> <> <> <> DIRECTORY ColorDisplay, InterminalExtraExtra USING [GetColorDisplaySide, SetColorDisplaySide], MonitorToolDefsExtras USING [Start640Monitor, Start1024Monitor], Process USING [Detach, InitializeCondition, Pause, Ticks], Rope USING [Equal, ROPE], Terminal USING [BitmapState, ChannelsVisible, ColorMode, Current, GetColorBitmapState, GetColorMode, GetVisibility, SetColorBitmapState, Virtual], UserProfile USING [Number, Token], ViewerClasses USING [Viewer], ViewerOps USING [ChangeColumn, CloseViewer, ComputeColumn, EnumerateViewers, EnumProc, OpenIcon], WindowManager USING [colorDisplayOn, ScreenPos, StartColorViewers, StopColorViewers]; ColorDisplayImpl: CEDAR MONITOR IMPORTS InterminalExtraExtra, MonitorToolDefsExtras, Process, Rope, Terminal, UserProfile, ViewerOps, WindowManager EXPORTS ColorDisplay ~ { OPEN ColorDisplay; <> bppLast: PUBLIC CARDINAL _ 8; onLeftLast: PUBLIC BOOLEAN _ TRUE; 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] ~ { SELECT TRUE FROM ~WindowManager.colorDisplayOn => onLeft _ onLeftLast; InterminalExtraExtra.GetColorDisplaySide[] = left => onLeft _ TRUE; ENDCASE => onLeft _ FALSE; 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[], bpp: CARDINAL _ DefaultBpp[], monitorType: Rope.ROPE _ DefaultMonitorType[]] ~ { NOTIFY forCDChanges; --Let the informant know... IF (on=WindowManager.colorDisplayOn AND bpp=Bpp[] AND monitorType=monitorTypeLast) THEN { --Only side of display possibly changing... IF on THEN InterminalExtraExtra.SetColorDisplaySide[IF onLeft THEN left ELSE right]; RETURN; }; { <> colorViewerList, colorIconList: LIST OF ViewerClasses.Viewer _ NIL; 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: FALSE]; 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; 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] => TRUSTED {MonitorToolDefsExtras.Start640Monitor[bitsPerPixel: bpp, pos: side]}; Rope.Equal[s1: monitorType, s2: "1024x768", case: FALSE] => TRUSTED {MonitorToolDefsExtras.Start1024Monitor[bitsPerPixel: bpp, pos: side]}; ENDCASE => WindowManager.StartColorViewers[screenPos: side, bitsPerPixel: bpp]; ReopenColorViewers[]; }; }; }; GetColorDisplayStatus: PUBLIC ENTRY PROC RETURNS [on, onLeft: BOOLEAN, bpp: CARDINAL, monitorType: Rope.ROPE] ~ { ENABLE UNWIND => NULL; [on, onLeft, bpp, monitorType] _ GetColorDisplayStatusInternal[]; }; GetCDState: INTERNAL PROC RETURNS [state: CDState] ~ INLINE { [state.on, state.onLeft, state.bpp, state.monitorType] _ GetColorDisplayStatusInternal[]; }; GetColorDisplayStatusInternal: INTERNAL PROC RETURNS [on, onLeft: BOOLEAN, bpp: CARDINAL, monitorType: Rope.ROPE] ~ { on _ WindowManager.colorDisplayOn; onLeft _ OnLeft[]; bpp _ Bpp[]; monitorType _ monitorTypeLast; }; 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 CDNotifyProc _ NIL; RegisterCDNotifyProc: PUBLIC ENTRY PROC [proc: CDNotifyProc] ~ { ENABLE UNWIND => NULL; procList _ CONS[proc, procList]; }; 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 CDNotifyProc _ procList, each.rest UNTIL each=NIL DO TRUSTED {Process.Detach[FORK each.first[old, new]];} ENDLOOP; old _ new; ENDLOOP; }; SleepColorDisplay: PUBLIC ENTRY 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]; }; Init: PROC[] RETURNS[] ~ { <> [,onLeftLast, bppLast, monitorTypeLast] _ GetColorDisplayProfile[]; TRUSTED { Process.InitializeCondition[@forCDChanges, 300]; Process.Detach[FORK WatchForChanges[]]; }; }; Init[]; }.