<> <> <> 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: BOOL _ FALSE, out: STREAM _ NIL, 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: BOOL _ FALSE; 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: BOOL _ FALSE] ~ { 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 [ ] -- Print the pixel value at (x, y)."; ViewerOps.RegisterViewerClass[$Info, NEW[ViewerClasses.ViewerClassRec]]; Commander.Register["///Commands/CtInfo", CtInfo, ctInfoUsage]; END.