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
~ {
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 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;
};
{
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[]];
};
};
}.