AdjustColorImpl.mesa
Copyright © 1984 by Xerox Corporation. All rights reserved.
Created Saturday, September 8, 1984 7:32 pm PDT
Last edited by Eric Nickell, December 19, 1985 12:37:55 pm PST
Implements the arbitration for having several types of tools trying to control the color maps simultaneously so that everyone can know who has the ball, etc.
DIRECTORY
ColorDisplay USING [CDNotifyProc, RegisterCDNotifyProc],
Gammas USING [gamma, BuildGammaTable, GammaCorrect, InstallGammaTable],
Terminal USING [ChannelValue, ColorValue, Current, SetRedMap, SetGreenMap, SetBlueMap, Virtual],
AdjustColor
;
AdjustColorImpl:
CEDAR MONITOR
IMPORTS ColorDisplay, Gammas, Terminal
EXPORTS AdjustColor
= BEGIN
OPEN AdjustColor;
ToolList: TYPE ~ LIST OF AdjustColorTool;
NoSuchFlavor: PUBLIC ERROR ~ CODE;
AlreadyExists: PUBLIC ERROR ~ CODE;
term: Terminal.Virtual ~ Terminal.Current[];
inControl: AdjustColorTool ← NIL; --Tool currently able to adjust colors
registeredTools: ToolList ← NIL; --All registered tools. NOTE that a NIL flavor implies an unregistered tool.
redTab: PUBLIC TRC;
grnTab: PUBLIC TRC;
bluTab: PUBLIC TRC;
RegisterAdjustColorTool:
PUBLIC
ENTRY
PROC [tool: AdjustColorToolRec] ~ {
ENABLE UNWIND => NULL;
IF tool.flavor = NIL THEN ERROR; --C'mon! No messing around here...
Check for duplication
FOR tools: ToolList ← registeredTools, tools.rest
UNTIL tools=
NIL
DO
IF tools.first.flavor = tool.flavor
THEN {
tools.first^ ← tool;
RETURN;
};
ENDLOOP;
Add tool to the list of those registered
registeredTools ← CONS[NEW[AdjustColorToolRec ← tool], registeredTools];
};
UnRegisterAdjustColorTool:
PUBLIC PROC [flavor: Flavor] ~ {
FOR tools: ToolList ← registeredTools, tools.rest
UNTIL tools=
NIL
DO
IF tools.first.flavor = flavor
THEN {
IF inControl#NIL AND inControl.flavor=flavor THEN inControl ← NIL;
tools.first.flavor ← NIL;
RETURN
};
ENDLOOP;
ERROR NoSuchFlavor;
};
InControl:
PUBLIC
ENTRY
PROC
RETURNS [flavor: Flavor] ~ {
ENABLE UNWIND => NULL;
RETURN [IF inControl=NIL THEN NIL ELSE inControl.flavor]
};
RequestControl:
PUBLIC
ENTRY
PROC [flavor: Flavor]
RETURNS [granted:
BOOLEAN] ~ {
ENABLE UNWIND => NULL;
FOR tools: ToolList ← registeredTools, tools.rest
UNTIL tools=
NIL
DO
IF tools.first.flavor = flavor
THEN {
IF inControl#
NIL
AND inControl.byebye#
NIL
THEN {
The call-back procedure is forked off, so that our clients may monitor such information, and properly set up WAIT's, etc. If we were to use this process, the MONITOR mechanism could deadlock.
p: PROCESS ← FORK inControl.byebye[inControl.flavor, flavor]; --Warn tool losing control
};
inControl ← tools.first; --Turn over control
RETURN [TRUE];
};
ENDLOOP;
ERROR NoSuchFlavor;
};
ClientDataForFlavor:
PUBLIC
ENTRY
PROC [flavor: Flavor]
RETURNS [
REF] ~ {
ENABLE UNWIND => NULL;
FOR tools: ToolList ← registeredTools, tools.rest
UNTIL tools=
NIL
DO
IF tools.first.flavor = flavor
THEN {
RETURN [tools.first.clientData];
};
ENDLOOP;
ERROR NoSuchFlavor;
};
AdjustColors:
PUBLIC
ENTRY
PROC [flavor: Flavor, red, green, blue:
REF
TRC]
RETURNS [done:
BOOL] ~ {
ENABLE UNWIND => NULL;
IF inControl = NIL OR flavor # inControl.flavor THEN RETURN [FALSE]; --If our caller is not in control, ignore him.
IF red=
NIL
OR green=
NIL
OR blue=
NIL
THEN
TRUSTED {
IF red#
NIL
THEN
FOR index: Color
IN Color
DO
SetRedMap[index, red[index]];
ENDLOOP;
IF green#
NIL
THEN
FOR index: Color
IN Color
DO
SetGreenMap[index, green[index]];
ENDLOOP;
IF blue#
NIL
THEN
FOR index: Color
IN Color
DO
SetBlueMap[index, blue[index]];
ENDLOOP;
}
ELSE
TRUSTED {
FOR index: Color
IN Color
DO
SetRedMap[index, red[index]];
SetGreenMap[index, green[index]];
SetBlueMap[index, blue[index]];
ENDLOOP;
};
};
NewGamma:
PUBLIC
PROC [gammaValue:
REAL ← 2.2] ~
TRUSTED {
Gammas.InstallGammaTable[Gammas.BuildGammaTable[gammaValue]];
FOR index: Color
IN Color
DO
Terminal.SetRedMap[term, index, Gammas.GammaCorrect[redTab[index]]];
Terminal.SetGreenMap[term, index, Gammas.GammaCorrect[grnTab[index]]];
Terminal.SetBlueMap[term, index, Gammas.GammaCorrect[bluTab[index]]];
ENDLOOP;
};
SetRedMap:
PROC [index:
CARDINAL, c: Color] ~
TRUSTED
INLINE {
IF redTab[index]#c THEN Terminal.SetRedMap[term, index, Gammas.GammaCorrect[redTab[index] ← c]];
};
SetGreenMap:
PROC [index:
CARDINAL, c: Color] ~
TRUSTED
INLINE {
IF grnTab[index]#c THEN Terminal.SetGreenMap[term, index, Gammas.GammaCorrect[grnTab[index] ← c]];
};
SetBlueMap:
PROC [index:
CARDINAL, c: Color] ~
TRUSTED
INLINE {
IF bluTab[index]#c THEN Terminal.SetBlueMap[term, index, Gammas.GammaCorrect[bluTab[index] ← c]];
};
RespecifyMaps:
ENTRY ColorDisplay.CDNotifyProc ~
TRUSTED {
IF new.on
AND new.bpp=24
AND (new.on#old.on
OR new.bpp#old.bpp)
THEN {
FOR index: Color
IN Color
DO
Terminal.SetRedMap[term, index, Gammas.GammaCorrect[redTab[index]]];
Terminal.SetGreenMap[term, index, Gammas.GammaCorrect[grnTab[index]]];
Terminal.SetBlueMap[term, index, Gammas.GammaCorrect[bluTab[index]]];
ENDLOOP;
};
};
Init:
PROC ~
TRUSTED {
[] ← ColorDisplay.RegisterCDNotifyProc[RespecifyMaps, NIL];
FOR index: Color
IN Color
DO
redTab[index] ← grnTab[index] ← bluTab[index] ← index;
Terminal.SetRedMap[term, index, Gammas.GammaCorrect[index]];
Terminal.SetGreenMap[term, index, Gammas.GammaCorrect[index]];
Terminal.SetBlueMap[term, index, Gammas.GammaCorrect[index]];
ENDLOOP;
};
Init[];
END.