ColorTrixInfoImpl.mesa
Copyright © 1985 by Xerox Corporation. All rights reserved.
Bloomenthal, September 13, 1986 1:00:40 pm PDT
DIRECTORY Args, CedarProcess, ClassIncreek, ColorDisplay, ColorTrixBasics, ColorTrixMap, Commander, ImagerPixelMap, IO, Process, Rope, Terminal, TerminalDefs, TypeScript, ViewerClasses, ViewerIO, ViewerOps;
ColorTrixInfoImpl: CEDAR PROGRAM
IMPORTS Args, CedarProcess, ClassIncreek, ColorDisplay, ColorTrixBasics, ColorTrixMap, Commander, ImagerPixelMap, IO, Process, Rope, Terminal, TypeScript, ViewerIO, ViewerOps
~ BEGIN
ROPE:    TYPE ~ Rope.ROPE;
STREAM:   TYPE ~ IO.STREAM;
Viewer:   TYPE ~ ViewerClasses.Viewer;
PixelMap:   TYPE ~ ColorTrixBasics.PixelMap;
PixelMapMisc: TYPE ~ ColorTrixBasics.PixelMapMisc;
Cmap:    TYPE ~ ColorTrixMap.Cmap;
CtInfoData:  TYPE ~ REF CtInfoDataRec;
CtInfoDataRec: TYPE ~ RECORD [
viewer:     Viewer ← NIL,
colorDisplayChanged: BOOLFALSE,
out:      STREAMNIL,
pm:      PixelMapMisc,
cmap:      Cmap ← NIL,
x, y:      INTEGER ← 0
];
PixelInfo:   TYPE ~ RECORD [
pval:      CARDINAL,
red:      CARDINAL,
grn:      CARDINAL,
blu:      CARDINAL
];
SeColorDisplayInfo: PROC [info: CtInfoData] ~ {
info.pm ← ColorTrixBasics.GetColorDisplayPmMisc[];
info.cmap ← IF info.pm.bpp = 8 THEN ColorTrixMap.Read[] ELSE NIL;
};
CtInfo: Commander.CommandProc ~ {
nArgs: INTEGER ← Args.NArgs[cmd];
IF nArgs # 0 AND nArgs # 2
THEN RETURN[$Failure, Rope.Concat["Bad argument(s); usage: ", ctInfoUsage]]
ELSE SELECT nArgs FROM
0 => {
info: CtInfoData ← NEW[CtInfoDataRec];
SeColorDisplayInfo[info];
info.viewer ← TypeScript.Create[info: [openHeight: 400, name: "CtInfo", data: info, scrollable: TRUE, column: right, iconic: TRUE]];
ViewerOps.OpenIcon[info.viewer];
info.out ← ViewerIO.CreateViewerStreams[NIL, info.viewer].out;
TRUSTED {Process.Detach[FORK Informer[info]]};
};
2 => {
x: Args.Arg ← Args.ArgInt[cmd, 0];
y: Args.Arg ← Args.ArgInt[cmd, 1];
pm: PixelMapMisc ← ColorTrixBasics.GetColorDisplayPmMisc[];
cmap: Cmap ← IF pm.bpp = 8 THEN ColorTrixMap.Read[] ELSE NIL;
IF NOT x.ok OR NOT y.ok THEN RETURN[$Failure, "Bad argument(s)."];
IF NOT CoordinatesOK[pm, x.int, y.int] THEN RETURN[
$Failure,
IO.PutFR["(x, y) must be ([0..%g), [0..%g))", IO.int[pm.w], IO.int[pm.h]]];
APixel[cmd.out, pm, cmap, x.int, y.int];
};
ENDCASE => NULL;
};
CDNotifyProc: ColorDisplay.CDNotifyProc ~ {
IF old # new THEN NARROW[clientData, CtInfoData].colorDisplayChanged ← TRUE;
};
Informer: PROC [info: CtInfoData] ~ TRUSTED {
report: BOOLFALSE;
key: TerminalDefs.KeyName;
action: ClassIncreek.ActionBody;
increek: ClassIncreek.Increek ← ClassIncreek.NewStdIncreek[];
viewPosition: ClassIncreek.ViewPosition ← ClassIncreek.GetPositionFrom[increek];
cdReg: ColorDisplay.CDRegistration ← ColorDisplay.RegisterCDNotifyProc[CDNotifyProc, info];
CedarProcess.SetPriority[background];
IO.PutRope[info.out, "\n"];
WHILE NOT info.viewer.destroyed DO
IF info.colorDisplayChanged THEN {
SeColorDisplayInfo[info];
info.colorDisplayChanged ← FALSE;
};
action ← ClassIncreek.GetAction[self: increek, acceptance: clicksAndMotion];
IF viewPosition.mousePosition.color THEN {
WITH ac: action SELECT FROM
keyDown => IF ac.value IN [Red..Yellow] THEN {key ← ac.value; report ← TRUE};
keyUp => IF ac.value IN [Red..Yellow] THEN {key ← ac.value; report ← FALSE};
ENDCASE;
IF report THEN {
WITH ac: action SELECT FROM
keyDown, deltaMouse => {
info.x ← viewPosition.mousePosition.mouseX;
info.y ← info.pm.h-viewPosition.mousePosition.mouseY;
};
ENDCASE;
IF key = Blue
THEN WITH ac: action SELECT FROM
keyDown => ManyPixels[info];
ENDCASE
ELSE WITH ac: action SELECT FROM
keyDown, deltaMouse => APixel[info.out, info.pm, info.cmap, info.x, info.y];
ENDCASE;
};
};
ENDLOOP;
ColorDisplay.UnregisterCDNotifyProc[cdReg];
};
APixel: PROC [out: STREAM, pm: PixelMapMisc, cmap: Cmap, x, y: INTEGER] ~ {
pix: PixelInfo ← GetPixelInfo[pm, cmap, x, y];
SELECT pm.bpp FROM
8 =>
IO.PutRope[out, Rope.Concat[
IO.PutFR["8 bit pixel at (%g, %g): %g ", IO.int[x], IO.int[y], IO.card[pix.pval]],
IO.PutFR["(r: %g, g: %g, b: %g)\n",
IO.int[cmap[0][pix.pval]], IO.int[cmap[1][pix.pval]], IO.int[cmap[2][pix.pval]]]]];
24 =>
IO.PutRope[out, IO.PutFR["24 bit pixel at (%g, %g), r: %g, g: %g, b: %g\n",
IO.int[x], IO.int[y], IO.card[pix.red], IO.card[pix.grn], IO.card[pix.blu]]];
ENDCASE => NULL;
};
ManyPixels: PROC [info: CtInfoData] ~ {
pixs: ARRAY [0..5) OF ARRAY [0..5) OF PixelInfo;
Bar: PROC ~ {
IF info.pm.bpp = 8
THEN IO.PutF[info.out, "——————————————————————————————————\n"]
ELSE IO.PutF[info.out, "——————————————————————\n"]
};
PrintLine: PROC [j: INTEGER, proc: PROC [i, j: INTEGER], report: BOOLFALSE] ~ {
IF proc # PrintX THEN IO.PutRope[info.out, "| "];
FOR i: NAT IN [0..5) DO proc[i, j]; ENDLOOP;
IF report THEN IO.PutF[info.out, " %g", IO.int[info.y-2+j]];
IO.PutRope[info.out, "\n"];
};
PrintX: PROC [i, j: INTEGER] ~ {
IF info.pm.bpp = 8
THEN IO.PutF[info.out, " %3g\t", IO.int[info.x-2+i]]
ELSE IO.PutF[info.out, " %3g\t", IO.int[info.x-2+i]];
};
PrintPval: PROC [i, j: INTEGER] ~ {
IO.PutF[info.out, " %-3g\t\t|", IO.card[pixs[i][j].pval]];
};
PrintRed: PROC [i, j: INTEGER] ~ {PrintCard["r", pixs[i][j].red]};
PrintGrn: PROC [i, j: INTEGER] ~ {PrintCard["g", pixs[i][j].grn]};
PrintBlu: PROC [i, j: INTEGER] ~ {PrintCard["b", pixs[i][j].blu]};
PrintCard: PROC [rope: ROPE, card: CARDINAL] ~ {
IF info.pm.bpp = 8
THEN IO.PutF[info.out, " %g: %3g\t|", IO.rope[rope], IO.card[card]]
ELSE IO.PutF[info.out, " %3g\t|", IO.card[card]];
};
FOR j: NAT IN [0..5) DO
y: INTEGER ← info.y-2+j;
FOR i: NAT IN [0..5) DO
pixs[i][j] ← GetPixelInfo[info.pm, info.cmap, info.x-2+i, y];
ENDLOOP;
ENDLOOP;
IO.PutF[
info.out, "\n%g bit pixels centered at (%g, %g):\n",
IO.int[info.pm.bpp], IO.int[info.x], IO.int[info.y]];
Process.Pause[Process.MsecToTicks[100]];
[] ← info.viewer.class.scroll[info.viewer, thumb, 100];
PrintLine[0, PrintX];
Bar[];
FOR line: NAT IN [0..5) DO
IF info.pm.bpp = 8 THEN PrintLine[line, PrintPval];
PrintLine[line, PrintRed];
PrintLine[line, PrintGrn, TRUE];
PrintLine[line, PrintBlu];
Bar[];
ENDLOOP
};
CoordinatesOK: PROC [pm: PixelMapMisc, x, y: INTEGER] RETURNS [BOOL] ~ {
RETURN[x IN [0..pm.w) AND y IN [0..pm.h)];
};
GetPixelInfo: PROC [pm: PixelMapMisc, cmap: Cmap, x, y: INTEGER] RETURNS [PixelInfo] ~ {
pix: PixelInfo;
GetInner: PROC ~ {
IF CoordinatesOK[pm, x, y] THEN SELECT pm.bpp FROM
8 => {
pix.pval ← ImagerPixelMap.GetPixel[pm.bw, y, x];
pix.red ← cmap[0][pix.pval];
pix.grn ← cmap[1][pix.pval];
pix.blu ← cmap[2][pix.pval];
};
24 =>
[pix.red, pix.grn, pix.blu] ← ColorTrixBasics.GetRGBPixel[pm, x, y];
ENDCASE => NULL;
};
Terminal.ModifyColorFrame[Terminal.Current[], GetInner, x, y, x+1, y+1];
RETURN[pix];
};
ctInfoUsage: ROPE ~ "\nctInfo [<x: INTEGER> <y: INTEGER>] -- Print the pixel value at (x, y).";
ViewerOps.RegisterViewerClass[$Info, NEW[ViewerClasses.ViewerClassRec]];
Commander.Register["///Commands/CtInfo", CtInfo, ctInfoUsage];
END.