CDColorsImpl.mesa
by Ch. Jacobi October 28, 1983 4:21 pm
last edited by Christian Jacobi November 1, 1983 2:44 pm
DIRECTORY
CDExtras,
CDSequencer,
ColorMap,
ColorWorld,
Commander USING [CommandProc, Register],
Convert,
FS,
IO,
Rope,
Terminal,
TerminalIO,
UserProfile,
WindowManager;
CDColorsImpl: CEDAR PROGRAM
IMPORTS CDExtras, CDSequencer, ColorMap, ColorWorld, Commander, Convert, FS, IO, Rope, Terminal, TerminalIO, UserProfile, WindowManager =
BEGIN
virtual: Terminal.Virtual = Terminal.Current[];
MyBackGround: TYPE = {whiteBackground, blackBackground};
myBackGround: MyBackGround ← whiteBackground;
Is4BitMode: PROC [] RETURNS [yes: BOOLFALSE] =
BEGIN
IF virtual.hasColorDisplay AND WindowManager.colorDisplayOn THEN {
m: Terminal.ColorMode = Terminal.GetColorMode[virtual];
yes ← ~m.full AND m.bitsPerPixelChannelA=4
};
END;
XCursor: PROC[] =
BEGIN
c: Terminal.ColorCursorPresentation ← Terminal.GetColorCursorPresentation[virtual];
c ← IF c=onesAreWhite THEN onesAreBlack ELSE onesAreWhite;
[] ← Terminal.SetColorCursorPresentation[virtual, c];
END;
SetCursor: PROC[onesWhite: BOOL] =
BEGIN
c: Terminal.ColorCursorPresentation ← Terminal.GetColorCursorPresentation[virtual];
IF onesWhite THEN {IF c#onesAreWhite THEN XCursor[]}
ELSE {IF c=onesAreWhite THEN XCursor[]};
END;
SetMyColor: PROC [p: MyBackGround←whiteBackground] =
BEGIN
SetParityColors: PROC [p: MyBackGround] =
--p only in [whiteBackground, blackBackground]
BEGIN
IF virtual.hasColorDisplay THEN {
m: Terminal.ColorMode = Terminal.GetColorMode[virtual];
highIndex: CARDINAL = IF m.bitsPerPixelChannelA=8 THEN 255 ELSE 15;
IF m.full THEN RETURN;
IF p=blackBackground THEN {
ColorMap.SetRGBColor[index: highIndex, r:1, g:1, b:1]; -- [white] outline
ColorMap.SetRGBColor[index: 0, r:0, g:0, b:0]; -- [black] background
}
ELSE {
ColorMap.SetRGBColor[index: highIndex, r:0, g:0, b:0]; -- [black] outline
ColorMap.SetRGBColor[index: 0, r:1, g:1, b:1]; -- [white] background
}
}
END;
myBackGround ← p;
IF virtual.hasColorDisplay AND WindowManager.colorDisplayOn THEN
BEGIN
m: Terminal.ColorMode = Terminal.GetColorMode[virtual];
IF m.full OR m.bitsPerPixelChannelA<4 THEN RETURN;
[] ← Terminal.SetColorCursorPresentation[virtual, onesAreWhite];
SetParityColors[p];
ColorMap.SetRGBColor[index: 1, r:0, g:1, b:0]; -- [green] diff
ColorMap.SetRGBColor[index: 2, r:0, g:0, b:1]; -- [blue] met
ColorMap.SetRGBColor[index: 4, r:1, g:0, b:0]; -- [red] poly
ColorMap.SetRGBColor[index: 8, r:0.9, g:0.9, b:0];
ColorMap.SetRGBColor[index: 3, r:0, g:0.4, b:0.7]; -- met+diff
ColorMap.SetRGBColor[index: 5, r:0.8, g:0.3, b:0]; -- poly+diff
ColorMap.SetRGBColor[index: 6, r:0.5, g:0, b:0.5]; -- poly+met
ColorMap.SetRGBColor[index: 7, r:0.8, g:0.3, b:0.6]; -- poly+diff+met
ColorMap.SetRGBColor[index: 9, r:0.9, g:0.8, b:0.9]; --nearly background
ColorMap.SetRGBColor[index: 10, r:0.8, g:0.9, b:0.8]; -- nearly background
ColorMap.SetRGBColor[index: 11, r:0.0, g:0.9, b:0.8];
ColorMap.SetRGBColor[index: 12, r:1, g:0.2, b:0.2];
ColorMap.SetRGBColor[index: 13, r:1, g:1, b:0.2];
ColorMap.SetRGBColor[index: 14, r:1, g:1, b:0.0]; -- [yellow] imp
END
END;
cTabCnt: CARDINAL ← 0;
colorTabsNum: CARDINAL = 40;
colorTabs: REF ColorTabs ← NEW[ColorTabs];
ColorTabs: TYPE = ARRAY [0..colorTabsNum) OF ARRAY [0..49) OF CARDINAL;
SetChipmonkColorMap: PROC [i: INT] =
BEGIN
IF i=0 THEN {SetMyColor[myBackGround]; RETURN};
IF Is4BitMode[] THEN {
IF i>0 AND i<=cTabCnt THEN {
--gamma: REAL = ColorMap.GetGamma[];
ColorMap.SetGamma[1.0];
i ← i-1;
FOR j: CARDINAL IN [0..16) DO
r: REAL = MAX[0, MIN[1, 1.0/255*(255-colorTabs[i][1+j*3])]];
g: REAL = MAX[0, MIN[1, 1.0/255*(255-colorTabs[i][2+j*3])]];
b: REAL = MAX[0, MIN[1, 1.0/255*(255-colorTabs[i][3+j*3])]];
ColorMap.SetRGBColor[index: j, r:r, g:g, b:b];
ENDLOOP;
--ColorMap.SetGamma[gamma];
ColorMap.SetGamma[2.2];
}
ELSE TerminalIO.WriteRope["out of range\n"];
}
ELSE TerminalIO.WriteRope["not in 4 bit mode\n"];
END;
SetColorBPP: PROC [bpp: CARDINAL, pos: WindowManager.ScreenPos, force: BOOLFALSE] =
--force position by putting off and on again
BEGIN
m: Terminal.ColorMode = Terminal.GetColorMode[virtual];
IF WindowManager.colorDisplayOn THEN {
IF NOT force AND NOT m.full AND m.bitsPerPixelChannelA=bpp THEN {
SetMyColor[myBackGround];
RETURN;
};
WindowManager.StopColorViewers[];
};
WindowManager.StartColorViewers[screenPos: pos, bitsPerPixel: bpp];
SetMyColor[myBackGround];
END;
DoColor: PROC[] =
BEGIN
n: CARDINAL;
IF NOT ColorWorld.HasMode[4] THEN
{TerminalIO.WriteRope["no color display\n"]; RETURN};
n ← TerminalIO.RequestSelection[
label: "color",
choice: IF ColorWorld.HasMode[8] THEN
LIST["cedar", "readentry", "mycolors", "Cursor-X", "4 bit left", "4 bit right", "8 bit left", "8 bit right"]
ELSE LIST["cedar", "readentry", "mycolors", "Cursor-X", "4 bit left", "4 bit right"]
];
SELECT n FROM
1 => {ColorMap.StandardMap[]; WindowManager.RestoreCursor[]; SetCursor[FALSE]};
2 => {SetColorMap[]};
3 => SetMyColor[IF myBackGround=whiteBackground THEN blackBackground ELSE whiteBackground];
4 => XCursor[];
5 => SetColorBPP[4, left, TRUE];
6 => SetColorBPP[4, right, TRUE];
7 => SetColorBPP[8, left, TRUE];
8 => SetColorBPP[8, right, TRUE];
ENDCASE => TerminalIO.WriteRope["skipped\n"];
END;
SetColorMap: PROC [val: INT←-1, file: Rope.ROPENIL] =
-- val<0 : read it
-- val>=0 : use it
BEGIN
IF cTabCnt=0 THEN ReadCMColorMap[file];
IF cTabCnt=0 THEN {TerminalIO.WriteRope["no color map table read\n"]; RETURN};
IF NOT Is4BitMode[] THEN {TerminalIO.WriteRope["not in 4 bit mode\n"]; RETURN};
IF val<0 THEN {
TerminalIO.WriteRope["color map ( <="];
TerminalIO.WriteInt[cTabCnt];
TerminalIO.WriteRope[") > "];
val ← TerminalIO.RequestInt["" ! TerminalIO.UserAbort => GOTO UserAbort];
};
SetChipmonkColorMap[val]
EXITS
UserAbort => {NULL};
END;
ReadCMColorMap: PROC [fileName: Rope.ROPENIL] =
BEGIN
binfile: IO.STREAM;
k, i: CARDINAL;
GetByte: PROC [] RETURNS[c: [0..255]] = INLINE {
c ← LOOPHOLE[IO.GetChar[binfile], [0..255]];
};
Get2Bytes: PROC [] RETURNS [c: CARDINAL] = INLINE {
h: [0..255] = GetByte[];
c ← h*256+GetByte[];
};
IF Rope.IsEmpty[fileName] THEN fileName←UserProfile.Token[
key: "Chipndale.ChipmonkColorMaps",
default: "default.CDColorMaps"
];
fileName ← CDExtras.AppendExt[fileName, "CDColorMaps"];
binfile ← FS.StreamOpen[fileName ! FS.Error =>
IF error.group # bug THEN {
TerminalIO.WriteRope[fileName];
TerminalIO.WriteRope[" not opened: "];
TerminalIO.WriteRope[error.explanation];
TerminalIO.WriteLn[];
GOTO FileName
}];
cTabCnt ← 0;
k ← MIN[Get2Bytes[], colorTabsNum];
FOR k IN [0..k) DO
FOR i IN [0..49) DO colorTabs[k][i] ← Get2Bytes[]; ENDLOOP;
ENDLOOP;
IO.Close[binfile];
cTabCnt ← k
EXITS
FileName => {NULL};
END;
ColorMenu: CDSequencer.CommandProc = {DoColor[]};
ColorMapMenu: CDSequencer.CommandProc = {SetColorMap[]};
ColorComm: Commander.CommandProc =
BEGIN
s: IO.STREAM ~ IO.RIS[cmd.commandLine];
bbp: INT ← 0;
side: INT ← 0;
DO
token: Rope.ROPEIO.GetTokenRope[s ! IO.EndOfStream => EXIT].token;
IF Rope.IsEmpty[token] THEN EXIT;
SELECT Rope.Fetch[token, 0] FROM
'4 => bbp ← 4;
'8 => bbp ← 8;
'r, 'R => side ← 1;
'l, 'L => side ← -1;
ENDCASE => EXIT;
ENDLOOP;
IF bbp>0 AND side#0 THEN SetColorBPP[bbp, IF side=1 THEN right ELSE left, TRUE]
ELSE DoColor[]
END;
ColorMapComm: Commander.CommandProc =
BEGIN
mapNum: INT ← -1;
mapFile: Rope.ROPENIL;
s: IO.STREAM ~ IO.RIS[cmd.commandLine];
DO
token: Rope.ROPEIO.GetTokenRope[s ! IO.EndOfStream => EXIT].token;
IF Rope.IsEmpty[token] THEN EXIT;
IF Rope.Fetch[token, 0] IN ['0..'9] THEN {
mapNum ← Convert.IntFromRope[token ! Convert.Error => EXIT];
}
ELSE mapFile ← CDExtras.AppendExt[token, "CDColorMaps"];
ENDLOOP;
SetColorMap[mapNum, mapFile]
END;
-- Module initialization
IF ColorWorld.HasMode[4] OR ColorWorld.HasMode[8] THEN {
--strategy is
-- -1 don't touch
-- 0 take bitmode as is and initialize, if possible
-- >0 do bitmode and initialize, if possible
strategy: INT = UserProfile.Number[key: "Chipndale.ColorStartBits", default: -1];
colorMapNum: INT = UserProfile.Number[key: "Chipndale.ChipmonkColorMapNum", default: -1];
pos: WindowManager.ScreenPos =
IF UserProfile.Boolean[key: "Chipndale.ColorStartLeft", default: TRUE] THEN left ELSE right;
myBackGround: MyBackGround ← whiteBackground;
IF UserProfile.Boolean[key: "Chipndale.ColorBackWhite", default: FALSE] THEN myBackGround ← whiteBackground;
IF UserProfile.Boolean[key: "Chipndale.ColorBackBlack", default: FALSE] THEN myBackGround ← blackBackground;
SetCursor[UserProfile.Boolean[key: "Chipndale.CursorOnesWhite", default: TRUE]];
IF strategy=0 THEN {SetMyColor[myBackGround]}
ELSE IF strategy=4 THEN SetColorBPP[4, pos]
ELSE IF strategy=8 THEN SetColorBPP[8, pos];
IF colorMapNum>0 THEN {
ReadCMColorMap[];
SetChipmonkColorMap[colorMapNum]
};
};
Commander.Register[
 key: "CDColor",
 proc: ColorComm,
 doc: "Chipndale color setup"
 ];
Commander.Register[
key: "CDColorMap",
proc: ColorMapComm,
doc: "read colormap from chipmonk file"
];
CDSequencer.ImplementCommand[$ColorMenu, ColorMenu];
END.