ColorDisplayImpl.mesa
Created from old ColorDisplay by Mik Lamming and Ken Pier
Last Edited by: Nickell, April 1, 1985 5:01:29 am PST
Last Edited by: Beach, August 17, 1984 5:24:14 pm PDT
Last Edited by: Pier, November 19, 1984 3:10:48 pm PST
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 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.
bppLast: PUBLIC CARDINAL ← 8;
onLeftLast: PUBLIC BOOLEANTRUE;
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;
};
{
Here, we need to play with everything...
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];
Reset the icons that WOULD have been opened on the color display back there
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[] ~ {
Read the user profile to establish the initial back settings...
[,onLeftLast, bppLast, monitorTypeLast] ← GetColorDisplayProfile[];
TRUSTED {
Process.InitializeCondition[@forCDChanges, 300];
Process.Detach[FORK WatchForChanges[]];
};
};
Init[];
}.