ColorMapsImpl.mesa
Copyright © 1985 by Xerox Corporation. All rights reserved.
by Christian Jacobi, December 23, 1985 12:52:29 pm PST
last edited by Christian Jacobi, February 12, 1986 10:16:42 am PST
DIRECTORY
Buttons,
Commander,
CommandTool,
ColorMaps,
FS,
FileNames,
Imager,
ImagerColorMap,
ImagerDitherContext,
ImagerTerminal,
InterminalBackdoor,
IO,
List,
MessageWindow,
Rope,
SymTab,
Terminal,
TerminalIO,
UserProfile,
ViewerPrivate,
WindowManager;
ColorMapsImpl:
CEDAR
MONITOR
IMPORTS Buttons, Commander, CommandTool, FS, FileNames, ImagerColorMap, ImagerDitherContext, ImagerTerminal, InterminalBackdoor, IO, List, MessageWindow, Rope, SymTab, Terminal, TerminalIO, UserProfile, ViewerPrivate, WindowManager
EXPORTS ColorMaps =
last: Rope.ROPE ← NIL;
terminal: Terminal.Virtual ← InterminalBackdoor.terminal;
useMapEntries: ImagerDitherContext.MapEntries ← NIL;
useCursor: Terminal.ColorCursorPresentation ← onesAreWhite;
regTab: SymTab.Ref ← SymTab.Create[5];
callBackList: LIST OF PROC←NIL;
ContextCreator: ViewerPrivate.ContextCreatorProc =
BEGIN
context: Imager.Context;
SELECT screen
FROM
bw => context ← ImagerTerminal.BWContext[vt: terminal, pixelUnits: TRUE];
color => {
context ← ImagerTerminal.ColorContext[vt: terminal, pixelUnits: TRUE];
IF useMapEntries#
NIL
THEN
ImagerDitherContext.SetDitherMap[context, useMapEntries];
--experimenting showed that the following line was necessary....
[] ← Terminal.SetColorCursorPresentation[terminal, useCursor];
}
ENDCASE => ERROR;
RETURN [context]
END;
ForceColors:
PROC [mapEntries: ImagerDitherContext.MapEntries, allBitsCursor:
BOOL←
TRUE] =
BEGIN
ImagerColorMap.LoadEntries[vt: terminal, mapEntries: mapEntries, gamma: 1, shared: FALSE];
useCursor ← IF allBitsCursor THEN onesAreWhite ELSE onesAreBlack;
[] ← Terminal.SetColorCursorPresentation[terminal, useCursor];
[] ← ViewerPrivate.SetCreator[ContextCreator];
END;
Last:
PUBLIC PROC []
RETURNS [fileName: Rope.
ROPE] =
BEGIN
RETURN [last];
END;
On8Bits:
PUBLIC PROC [forceOn:
BOOL←
TRUE, force8bit:
BOOL←
TRUE]
RETURNS [
BOOL←
FALSE] =
BEGIN
StartWindowManager:
PROC [] = {
WindowManager.StartColorViewers[
screenPos: (IF Rope.Equal["right", UserProfile.Token[key: "ColorDisplay.Side"], FALSE] THEN right ELSE left),
bitsPerPixel: 8
];
};
Is8:
PROC []
RETURNS [
BOOL] = {
m: Terminal.ColorMode = Terminal.GetColorMode[terminal];
RETURN [~m.full AND m.bitsPerPixelChannelA=8];
};
IF terminal.hasColorDisplay
THEN {
IF ~WindowManager.colorDisplayOn AND forceOn THEN StartWindowManager[];
IF WindowManager.colorDisplayOn
AND ~Is8[]
AND force8bit
THEN {
WindowManager.StopColorViewers[];
StartWindowManager[];
};
RETURN [ WindowManager.colorDisplayOn AND Is8[] ];
}
END;
SetUpFile:
PROC [fileName: Rope.
ROPE, forceOn:
BOOL←
TRUE, force8bit:
BOOL←
TRUE, msgs:
IO.
STREAM←
NIL] =
BEGIN
fastList: LIST OF ImagerColorMap.MapEntry←NIL;
slowList: LIST OF ImagerColorMap.MapEntry←NIL;
cdCursor: BOOL ← TRUE;
OneLine:
PROC [line: Rope.
ROPE] =
BEGIN
Range:
PROC [i:
INT]
RETURNS [c: [0..256)] = {
i ← MAX[0, MIN[i, 255]];
c ← i
};
stream: IO.STREAM ←IO.RIS[line];
i, index, r, g, b: INT;
mapEntrie: ImagerColorMap.MapEntry;
i ← IO.GetInt[stream];
r ← IO.GetInt[stream];
g ← IO.GetInt[stream];
b ← IO.GetInt[stream];
index ← ABS[i] MOD 256;
mapEntrie ← [Range[index], Range[r], Range[g], Range[b]];
fastList ← CONS[mapEntrie, fastList];
IF index=i THEN slowList ← CONS[mapEntrie, slowList];
END;
IF On8Bits[forceOn, force8bit]
THEN {
file: IO.STREAM ← NIL; line: Rope.ROPE;
IF msgs=NIL THEN msgs ← TerminalIO.TOS[];
fileName ← ExtendName[fileName];
file ←
FS.StreamOpen[fileName !
FS.Error => {
IO.PutF[msgs, "not done: %g\n", IO.rope[error.explanation]];
GOTO thatsIt
}];
line ← IO.GetTokenRope[file ! IO.EndOfStream => GOTO thatsIt].token;
IF ~Rope.Equal[line, "ColorMap",
FALSE]
THEN {
IO.PutRope[msgs, "not a ColorMap file\n"]
};
line ← IO.GetTokenRope[file ! IO.EndOfStream => GOTO thatsIt].token;
IF Rope.Equal[line, "onesAreBlack", FALSE] THEN cdCursor ← FALSE;
BEGIN
DO
line ← IO.GetLineRope[file ! IO.EndOfStream => {GOTO eof}];
IF ~Rope.IsEmpty[line] THEN OneLine[line];
ENDLOOP;
EXITS eof => NULL
END;
useMapEntries ← slowList;
ForceColors[fastList, cdCursor];
last ← fileName;
IO.Close[file];
};
EXITS thatsIt => NULL
END;
SetUpOff:
PROC [] =
BEGIN
last ← NIL;
IF terminal.hasColorDisplay THEN WindowManager.StopColorViewers[];
END;
SetUpCedar:
PROC[] =
BEGIN
last ← NIL;
IF terminal.hasColorDisplay
THEN {
[] ← ViewerPrivate.SetCreator[NIL];
[] ← On8Bits[];
ImagerTerminal.SetStandardColorMap[terminal];
WindowManager.RestoreCursor[];
[] ← Terminal.SetColorCursorPresentation[terminal, onesAreBlack];
};
END;
SetUp:
PUBLIC
PROC [fileName: Rope.
ROPE, forceOn:
BOOL←
TRUE, forceBits:
BOOL←
TRUE, msgs:
IO.
STREAM←
NIL] =
BEGIN
WHILE Rope.Equal[fileName, "type filename",
FALSE]
DO
fileName ← TerminalIO.RequestRope["filename for colormap file (///) >"];
ENDLOOP;
IF Rope.Equal[fileName, "cedar-8-bit", FALSE] THEN SetUpCedar[]
ELSE IF Rope.Equal[fileName, "off", FALSE] THEN SetUpOff[]
ELSE
IF Rope.Equal[fileName, "?",
FALSE]
THEN {
msgs.PutRope["current color map from: "]; msgs.PutRope[last]; msgs.PutRope["\n"];
RETURN
}
ELSE
IF ~Rope.IsEmpty[fileName]
THEN
--IF ~Rope.Equal[fileName, Last[], FALSE] THEN
--bad optimiztion: disables reset after other tool
SetUpFile[fileName, forceOn, forceBits, msgs];
CallList[];
END;
ExtendName:
PROC [name: Rope.
ROPE]
RETURNS [fn: Rope.
ROPE] =
BEGIN
fn ← name;
IF Rope.Find[fn, "."]<1 THEN fn ← Rope.Concat[fn, ".ColorMap"];
END;
RegisterMenu:
PUBLIC
PROC [entryName: Rope.
ROPE, fileName: Rope.
ROPE←
NIL] =
BEGIN
IF Rope.IsEmpty[fileName] THEN [] ← regTab.Delete[entryName]
ELSE [] ← regTab.Store[entryName, fileName]
END;
CallBack:
PUBLIC ENTRY
PROC [p:
PROC] =
BEGIN
IF p#NIL THEN callBackList ← CONS [p, callBackList];
END;
CallList:
PROC [] =
BEGIN
FOR l:
LIST
OF
PROC ← callBackList, l.rest
WHILE l#
NIL
DO
l.first[]
ENDLOOP
END;
Create:
PUBLIC
PROC [fileName: Rope.
ROPE, special:
REF←
NIL, msgs:
IO.
STREAM←
NIL] =
BEGIN
file: IO.STREAM;
IF msgs=NIL THEN msgs ← TerminalIO.TOS[];
IF ~On8Bits[
FALSE,
FALSE]
THEN {
msgs.PutRope["not done; not in 8 bit mode\n"];
GOTO thatsIt
};
file ←
FS.StreamOpen[ExtendName[fileName], create !
FS.Error => {
msgs.PutRope["not done:"]; msgs.PutRope[error.explanation]; msgs.PutRope["\n"];
GOTO thatsIt
}];
IO.PutRope[file, "ColorMap\n"];
IF Terminal.GetColorCursorPresentation[terminal]=onesAreBlack
THEN
IO.PutRope[file, "onesAreBlack\n"]
ELSE
IO.PutRope[file, "onesAreWhite\n"];
FOR i: Terminal.ChannelValue
IN Terminal.ChannelValue
DO
red, green, blue: Terminal.ColorValue;
index: INT ← i;
[red, green, blue] ← Terminal.GetColor[terminal, i];
IF special=$i THEN index ← -index;
IO.PutF[file, " %g %g %g %g\n", IO.int[index], IO.card[red], IO.card[green], IO.card[blue]];
ENDLOOP;
IO.Close[file];
EXITS thatsIt => NULL
END;
ButtonHit: Buttons.ButtonProc =
BEGIN
ENABLE TerminalIO.UserAbort => GOTO aborted;
choice: INT ← 0;
lor: LIST OF Rope.ROPE ← NIL;
Each: SymTab.EachPairAction = {
lor ← CONS[key, lor]; quit ← FALSE
};
[] ← regTab.Pairs[Each];
IF lor#NIL THEN choice ← TerminalIO.RequestSelection["color", lor];
IF choice>0
THEN
TRUSTED {
entry: Rope.ROPE ← NARROW[List.NthElement[LOOPHOLE[lor], choice]];
name: Rope.ROPE ← NARROW[regTab.Fetch[entry].val];
SetUp[name];
};
Message[];
EXITS aborted => NULL;
END;
Message:
PROC [] =
BEGIN
r: Rope.ROPE ← Last[];
IF r=NIL THEN r ← "not loaded from a file";
MessageWindow.Append[Rope.Concat["color map: ", r], TRUE];
END;
ColorMapCommand: Commander.CommandProc =
BEGIN
argv: CommandTool.ArgumentVector
← CommandTool.Parse[cmd ! CommandTool.Failed => {msg ← errorMsg; GO TO oops}];
IF argv.argc<=1 OR argv[1].IsEmpty[] THEN GO TO oops;
IF argv[1].Fetch[0]#'- THEN SetUp[argv[1], TRUE, TRUE, cmd.out]
ELSE {
--switches..
SELECT
TRUE
FROM
Rope.Equal[argv[1], "-n",
FALSE] => {
--read without forcing display
IF argv.argc<=2 THEN {msg ← "needs filename"; GO TO oops};
SetUp[argv[2], FALSE, FALSE, cmd.out];
};
Rope.Equal[argv[1], "-register",
FALSE] => {
--register menu command
fn: Rope.ROPE;
IF argv.argc<=3 THEN {msg ← "needs key and filename"; GO TO oops};
fn ← FileNames.FileWithSearchRules[root: argv[3], defaultExtension: ".ColorMap", searchRules: NIL].fullPath;
IF Rope.IsEmpty[fn] THEN {msg ← "file not found"; GO TO oops};
RegisterMenu[argv[2], fn];
};
Rope.Equal[argv[1], "-create",
FALSE] => {
--create file
IF argv.argc<=2 THEN {msg ← "needs filename"; GO TO oops};
Create[argv[2], NIL, cmd.out];
};
ENDCASE => {msg ← "only known switches: -n, -register, -create"; GO TO oops};
};
EXITS oops => result ← $Failure;
END;
IF terminal.hasColorDisplay
THEN
[] ← Buttons.Create[info: [name: "8-bit colors"], proc: ButtonHit, fork: TRUE];
RegisterMenu["cedar-8-bit", "cedar-8-bit"];
RegisterMenu["off", "off"];
Commander.Register[key: "///Commands/ColorMap", proc: ColorMapCommand, doc: "reads 8 bit colormap from file [-n, -register, -create]"];
END.