<> <> <> <> <> <<>> 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... <> FOR tools: ToolList _ registeredTools, tools.rest UNTIL tools=NIL DO IF tools.first.flavor = tool.flavor THEN { tools.first^ _ tool; RETURN; }; ENDLOOP; <> 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 { <> 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.