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:
BOOL←
FALSE] =
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:
BOOL←
FALSE] =
--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.
ROPE←
NIL] =
-- 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.
ROPE←
NIL] =
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.ROPE ← IO.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.ROPE ← NIL;
s: IO.STREAM ~ IO.RIS[cmd.commandLine];
DO
token: Rope.ROPE ← IO.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]
-- 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.