DIRECTORY Atom, Buttons, ColorDisplayManager, ColorMaps, Commander, CommandTool, Convert, FS, FileNames, Imager, ImagerColorMap, ImagerDitherContext, InterminalBackdoor, IO, MessageWindow, PopUpMenus, Rope, SymTab, Terminal, UserProfile, WindowManager; ColorMapsImpl: CEDAR MONITOR IMPORTS Atom, Buttons, ColorDisplayManager, Commander, CommandTool, Convert, FS, FileNames, ImagerColorMap, ImagerDitherContext, InterminalBackdoor, IO, MessageWindow, PopUpMenus, Rope, SymTab, Terminal, UserProfile, WindowManager EXPORTS ColorMaps = BEGIN OPEN ColorMaps; myAtom: ATOM = $ColorMapsFromFile; last: Rope.ROPE _ NIL; terminal: Terminal.Virtual _ InterminalBackdoor.terminal; regTab: SymTab.Ref _ SymTab.Create[]; callBackList: LIST OF PROC _ NIL; Equal: PROC [s1, s2: Rope.ROPE] RETURNS [BOOL] = { RETURN [Rope.Equal[s1, s2, FALSE]] }; RegisterSetUp: PUBLIC PROC [entryName: Rope.ROPE, fileName: Rope.ROPE_NIL] = { IF Rope.IsEmpty[fileName] THEN [] _ SymTab.Delete[regTab, entryName] ELSE [] _ SymTab.Store[regTab, entryName, fileName] }; RegisterCallBack: PUBLIC ENTRY PROC [p: PROC] = { IF p#NIL THEN callBackList _ CONS [p, callBackList]; }; CallList: PROC [] = { FOR l: LIST OF PROC _ callBackList, l.rest WHILE l#NIL DO l.first[] ENDLOOP }; LastFile: PUBLIC PROC [] RETURNS [fileName: Rope.ROPE] = { RETURN [last]; }; Side: PROC [] RETURNS [side: ColorDisplayManager.Side] = { old: ColorDisplayManager.State = ColorDisplayManager.NextState[]; side _ IF old.type#NIL THEN old.side ELSE IF Equal["left", UserProfile.Token[key: "ColorDisplay.Side"]] THEN left ELSE right }; SetUp: PUBLIC PROC [name: Rope.ROPE, msgs: IO.STREAM_NIL] = { CheckSetUpSpecials: PROC [name: Rope.ROPE] RETURNS [done: BOOL_TRUE] = { old: ColorDisplayManager.State = ColorDisplayManager.NextState[]; SELECT TRUE FROM Equal[name, "LowRes"] => ColorDisplayManager.Start[type: old.type, side: Side[], level: old.level, resolution: standard]; Equal[name, "HighRes"] => ColorDisplayManager.Start[type: old.type, side: Side[], level: old.level, resolution: highResolution]; Equal[name, "Left"] => ColorDisplayManager.Start[type: old.type, side: left, level: old.level]; Equal[name, "Right"] => ColorDisplayManager.Start[type: old.type, side: right, level: old.level]; Equal[name, "Off"] => {ColorDisplayManager.Stop[]; last _ NIL}; Equal[name, "onesAreWhite"] => [] _ Terminal.SetColorCursorPresentation[terminal, onesAreWhite]; Equal[name, "onesAreBlack"] => [] _ Terminal.SetColorCursorPresentation[terminal, onesAreBlack]; ENDCASE => done _ FALSE }; CheckSetupStandard: PROC [name: Rope.ROPE] RETURNS [done: BOOL_FALSE] = { old: ColorDisplayManager.State = ColorDisplayManager.NextState[]; FOR each: LIST OF ATOM _ old.registered, each.rest UNTIL each = NIL DO n: Rope.ROPE _ Atom.GetPName[each.first]; IF Equal[name, n] THEN { last _ n; ColorDisplayManager.Start[type: each.first, side: Side[]]; RETURN [TRUE]; }; ENDLOOP; }; IF ~terminal.hasColorDisplay OR Rope.IsEmpty[name] THEN RETURN ELSE IF Equal[name, "Standard"] THEN { [] _ CheckSetupStandard["Dither8"]; [] _ Terminal.SetColorCursorPresentation[terminal, onesAreBlack]; } ELSE IF Equal[name, "?"] THEN { IO.PutRope[msgs, "current color map from: "]; IO.PutRope[msgs, last]; IO.PutRope[msgs, "\n"]; RETURN } ELSE IF CheckSetupStandard[name] THEN NULL ELSE IF CheckSetUpSpecials[name] THEN NULL ELSE IF SetUpFile[name, msgs] THEN NULL ELSE RETURN; CallList[]; }; ButtonHit: Buttons.ButtonProc = { state: ColorDisplayManager.State = ColorDisplayManager.NextState[]; menu: PopUpMenus.Menu _ PopUpMenus.Create["Color Display"]; EachRegisteredFile: SymTab.EachPairAction = {quit _ FALSE; [] _ PopUpMenus.Entry[menu: menu, entry: key, doc: NARROW[val], entryData: val]; }; IF WindowManager.colorDisplayOn THEN { [] _ PopUpMenus.Entry[menu: menu, entry: "Off", doc: "Turn off the color display", entryData: $Off]; IF state.side=left THEN [] _ PopUpMenus.Entry[menu: menu, entry: "Right", doc: "Color Display on right on B&W display", entryData: $Right] ELSE [] _ PopUpMenus.Entry[menu: menu, entry: "Left", doc: "Color Display on left on B&W display", entryData: $Left]; IF state.resolution=highResolution THEN [] _ PopUpMenus.Entry[menu: menu, entry: "LowRes", doc: "Change to low resolution", entryData: $LowRes] ELSE [] _ PopUpMenus.Entry[menu: menu, entry: "HighRes", doc: "Change to high resolution", entryData: $HighRes]; IF Terminal.GetColorCursorPresentation[terminal]=onesAreWhite THEN [] _ PopUpMenus.Entry[menu: menu, entry: "Cursor black", doc: "Color cursor representation onesAreBlack", entryData: $onesAreBlack] ELSE [] _ PopUpMenus.Entry[menu: menu, entry: "Cursor white", doc: "Color cursor representation onesAreWhite", entryData: $onesAreWhite]; }; [] _ SymTab.Pairs[regTab, EachRegisteredFile]; FOR each: LIST OF ATOM _ state.registered, each.rest UNTIL each = NIL DO IF each.first=myAtom THEN LOOP; [] _ PopUpMenus.Entry[menu: menu, entry: Atom.GetPName[each.first], entryData: each.first, doc: ColorDisplayManager.FetchCreator[each.first].documentation ]; ENDLOOP; [] _ PopUpMenus.Timeout[menu, 120]; WITH PopUpMenus.Call[menu] SELECT FROM a: ATOM => SetUp[Atom.GetPName[a]]; r: Rope.ROPE => SetUp[r]; ENDCASE => NULL; Message[]; }; Message: PROC [] = { r: Rope.ROPE _ LastFile[]; IF r=NIL THEN r _ "not loaded from a file"; MessageWindow.Append[Rope.Concat["color map: ", r], TRUE]; }; ForceColors: PROC [fullMap, subsetMap: ImagerDitherContext.MapEntries, useCursor: Terminal.ColorCursorPresentation _ onesAreBlack, gamma: REAL _ 2.2, bpp: INT _ 8] = { IF bpp<1 OR bpp>8 THEN bpp _ 8; ImagerDitherContext.RegisterDisplayType[type: myAtom, documentation: "Color map read from file", bitsPerPixel: bpp, mapEntries: fullMap, gamma: 1]; ColorDisplayManager.Start[type: myAtom, side: Side[]]; [] _ Terminal.SetColorCursorPresentation[terminal, useCursor]; ImagerColorMap.SetGamma[terminal, gamma]; }; ExtendName: PROC [name: Rope.ROPE] RETURNS [fn: Rope.ROPE] = { fn _ name; IF Rope.Find[fn, "."]<1 THEN fn _ Rope.Concat[fn, ".ColorMap"]; }; SetUpFile: PROC [fileName: Rope.ROPE, msgs: IO.STREAM_NIL] RETURNS [done: BOOL_FALSE] = { fullMap: LIST OF ImagerColorMap.MapEntry _ NIL; subsetMap: LIST OF ImagerColorMap.MapEntry _ NIL; cursor: Terminal.ColorCursorPresentation _ onesAreBlack; gamma: REAL _ 1; bpp: INT _ 8; maxIndex: INT _ 255; OneLine: PROC [line: Rope.ROPE] = { 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 _ MIN[maxIndex, ABS[i] MOD 256]; mapEntrie _ [Range[index], Range[r], Range[g], Range[b]]; fullMap _ CONS[mapEntrie, fullMap]; IF index=i THEN subsetMap _ CONS[mapEntrie, subsetMap]; }; IF terminal.hasColorDisplay THEN { file: IO.STREAM _ NIL; line: Rope.ROPE; IF msgs=NIL THEN msgs _ IO.noWhereStream; fileName _ ExtendName[fileName]; file _ FS.StreamOpen[fileName ! FS.Error => { IO.PutF[msgs, "not done: %g\n", IO.rope[error.explanation]]; GOTO oops }]; line _ IO.GetLineRope[file ! IO.EndOfStream => GOTO oops]; IF ~Rope.Match["*ColorMap*", line, FALSE] THEN { IO.PutRope[msgs, "not a ColorMap file\n"]; GOTO oops }; line _ IO.GetLineRope[file ! IO.EndOfStream => GOTO oops]; DO SELECT TRUE FROM Rope.Match["*onesAreBlack*", line, FALSE] => cursor _ onesAreBlack; Rope.Match["*onesAreWhite*", line, FALSE] => cursor _ onesAreWhite; Rope.Match["*Gamma*", line, FALSE] => { line _ Rope.Substr[line, Rope.Find[line, "Gamma", 0, FALSE]+5]; gamma _ Convert.RealFromRope[line ! Convert.Error => CONTINUE]; }; Rope.Match["*BitsPerPixel*", line, FALSE] => { line _ Rope.Substr[line, Rope.Find[line, "BitsPerPixel", 0, FALSE]+12]; bpp _ Convert.IntFromRope[line ! Convert.Error => CONTINUE]; SELECT bpp FROM 8 => maxIndex _ 255; 4 => maxIndex _ 15; 2 => maxIndex _ 3; 1 => maxIndex _ 1; ENDCASE => {GOTO oops}; }; ENDCASE => EXIT; line _ IO.GetLineRope[file ! IO.EndOfStream => GOTO oops]; ENDLOOP; IF ~Terminal.LegalColorMode[terminal, [FALSE, bpp, 0]] THEN { IO.PutRope[msgs, "not done: bits per pixel not supported"] } ELSE { BEGIN DO IF ~Rope.IsEmpty[line] THEN OneLine[line]; line _ IO.GetLineRope[file ! IO.EndOfStream => {GOTO eof}]; ENDLOOP; EXITS eof => NULL END; ForceColors[fullMap, subsetMap, cursor, gamma, bpp]; done _ TRUE; last _ fileName; }; IO.Close[file]; }; EXITS oops => NULL }; CreateFile: PUBLIC PROC [fileName: Rope.ROPE, special: REF_NIL, msgs: IO.STREAM_NIL] = { m: Terminal.ColorMode = Terminal.GetColorMode[terminal]; max: BYTE; file: IO.STREAM; IF msgs=NIL THEN msgs _ IO.noWhereStream; IF ~WindowManager.colorDisplayOn THEN { IO.PutRope[msgs, "not done; color display not on\n"]; GOTO oops }; IF m.full THEN { IO.PutRope[msgs, "not done; color display in full color mode\n"]; GOTO oops }; SELECT m.bitsPerPixelChannelA FROM 1 => max _ 1; 2 => max _ 3; 4 => max _ 15; 8 => max _ 255; ENDCASE => { IO.PutRope[msgs, "not done; bits per pixel mode not supported for files\n"]; GOTO oops }; fileName _ ExtendName[fileName]; file _ FS.StreamOpen[fileName, create ! FS.Error => { IO.PutRope[msgs, "not done:"]; IO.PutRope[msgs, error.explanation]; IO.PutRope[msgs, "\n"]; GOTO oops }]; IO.PutRope[file, "ColorMap\n"]; IF Terminal.GetColorCursorPresentation[terminal]=onesAreBlack THEN IO.PutRope[file, "onesAreBlack\n"] ELSE IO.PutRope[file, "onesAreWhite\n"]; IO.PutF1[file, "Gamma %g\n", [real[ImagerColorMap.GetGamma[terminal]]]]; IO.PutF1[file, "BitsPerPixel %g\n", [integer[m.bitsPerPixelChannelA]]]; FOR i: Terminal.ChannelValue IN [0..max] 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]; IO.PutF[msgs, "color map file %g created\n", [rope[fileName]]]; EXITS oops => NULL }; ColorMapCommand: Commander.CommandProc = { argv: CommandTool.ArgumentVector _ CommandTool.Parse[cmd ! CommandTool.Failed => {msg _ errorMsg; GO TO oops}]; IF argv.argc<=1 OR argv[1].IsEmpty[] THEN RETURN; IF argv[1].Fetch[0]#'- THEN SetUp[argv[1], cmd.out] ELSE { --switches.. SELECT TRUE FROM Equal[argv[1], "-register"] => { --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", requireExtension: FALSE, requireExact: TRUE, searchRules: NIL].fullPath; IF Rope.IsEmpty[fn] THEN {msg _ "file not found"; GO TO oops}; RegisterSetUp[argv[2], FileNames.StripVersionNumber[fn]]; }; Equal[argv[1], "-create"] => {--create file IF argv.argc<=2 THEN {msg _ "needs filename"; GO TO oops}; CreateFile[argv[2], NIL, cmd.out]; }; ENDCASE => {msg _ "only known switches: -register, -create"; GO TO oops}; }; EXITS oops => result _ $Failure; }; documentation: Rope.ROPE = "Set up color display ColorMaps {name | -register menuEntry fileName | -create fileName}"; IF terminal.hasColorDisplay THEN [] _ Buttons.Create[info: [name: "Color Display"], proc: ButtonHit, fork: TRUE]; Commander.Register[key: "ColorMaps", proc: ColorMapCommand, doc: documentation]; Commander.Register[key: "///7.0/Commands/ColorMaps", proc: ColorMapCommand, doc: documentation]; END. ώColorMapsImpl.mesa Copyright c 1985, 1987 by Xerox Corporation. All rights reserved. Created by Christian Jacobi, December 23, 1985 12:52:29 pm PST Last edited by: Christian Jacobi, March 10, 1987 2:41:35 pm PST IF subsetMap#NIL THEN ImagerColorMap.LoadEntries[vt: terminal, mapEntries: subsetMap, gamma: 1, shared: FALSE]; --don't optimize and check what most recently loaded; --an other package might have fooled around unnoticed --needs full path registration because of funny people in DA group Κρ˜codešœ™Kšœ Οmœ7™BKšœ?™?K™?—K˜šΟk ˜ Kšœ˜Kšœ˜Kšœ˜Kšœ ˜ Kšœ ˜ Kšœ ˜ K˜K˜Kšœ ˜ Kšœ˜Kšœ˜Kšœ˜Kšœ˜Kšžœ˜Kšœ˜Kšœ ˜ Kšœ˜Kšœ˜Kšœ ˜ Kšœ ˜ Kšœ˜—K˜šΟn œžœžœ˜KšžœDžœFžœO˜ζKšžœ ˜—šž œ ˜K˜—Kšœžœ˜"Kšœ žœžœ˜Kšœ9˜9Kšœ%˜%Jš œžœžœžœžœ˜!K˜š Ÿœžœžœžœžœ˜2Kšžœžœ˜"Kšœ˜—K˜š Ÿ œžœžœžœžœžœ˜NKšžœžœ&˜DKšžœ/˜3Kšœ˜—J˜š Ÿœžœžœžœžœ˜1Jšžœžœžœžœ˜4Jšœ˜—K˜šŸœžœ˜Kšžœžœžœžœžœžœžœ ž˜KKšœ˜K˜—š Ÿœžœžœžœžœ˜:Kšžœ˜Kšœ˜—K˜šŸœžœžœ%˜:KšœA˜Ašœžœ žœžœ ˜$Kšžœžœ<žœ˜MKšžœ˜ —K˜—K˜šŸœžœžœžœžœžœžœ˜>K˜š Ÿœžœ žœžœžœžœ˜HKšœA˜Ašžœžœž˜•StartOfExpansionŠ[type: ATOM, side: Interminal.Side, level: ColorDisplayManager.Level _ viewers, resolution: ColorDisplayManager.Resolution _ none]šœ˜Kšœ`˜`—–Š[type: ATOM, side: Interminal.Side, level: ColorDisplayManager.Level _ viewers, resolution: ColorDisplayManager.Resolution _ none]šœ˜Kšœf˜f—šœ˜KšœH˜H—šœ˜KšœI˜I—Kšœ:žœ˜?šœ˜KšœA˜A—šœ˜KšœA˜A—Kšžœ ž˜—Kšœ˜—K˜š Ÿœžœ žœžœžœžœ˜IKšœA˜Aš žœžœžœžœžœžœž˜FKšœžœ˜)šžœžœ˜Kšœ ˜ Kšœ:˜:Kšžœžœ˜K˜—Kšžœ˜—K˜—K˜Kšžœžœžœž˜>šžœžœžœ˜&Kšœ$˜$KšœA˜AKšœ˜—šžœžœžœ˜Kšžœ,žœžœ˜]Kšž˜K˜—Kšžœžœžœž˜*Kšžœžœžœž˜*Kšžœžœžœž˜'Kšžœžœ˜ Kšœ ˜ Kšœ˜—K˜šŸ œ˜!KšœC˜CKšœ;˜;šŸœ"žœ˜:Kšœ3žœ˜PK˜—šžœžœ˜&Kšœd˜dšžœ˜Kšžœs˜wKšžœq˜u—šžœ!˜#Kšžœh˜lKšžœl˜p—šžœ<˜>Kšžœ„˜ˆKšžœ…˜‰—K˜—Kšœ.˜.š žœžœžœžœžœžœž˜HKšžœžœžœ˜šœ"˜"Kšœ8˜8Kšœ?˜?Kšœ˜—Kšžœ˜—Kšœ#˜#šžœžœž˜&Kšœžœ˜#Kšœžœ ˜Kšžœžœ˜—Kšœ ˜ Kšœ˜—K˜šŸœžœ˜Kšœžœ˜Kšžœžœžœ˜+Kšœ4žœ˜:Kšœ˜—K˜šŸ œžœyžœ žœ ˜§Jšžœžœžœ ˜!Kšœ“˜“Kšœ6˜6Kšœ>˜>šžœ žœžœ™KšœRžœ™Y—Kšœ)˜)Kšœ˜—K˜š Ÿ œžœ žœžœ žœ˜>Kšœ ˜ Kšžœžœ#˜?Kšœ˜—K˜šŸ œžœžœžœžœžœžœžœžœ˜YKšΟc6™6Kš 5™5Kšœ žœžœžœ˜/Kšœ žœžœžœ˜1Kšœ8˜8Kšœžœ˜Kšœžœ˜Kšœ žœ˜K˜šŸœžœ žœ˜#šŸœžœžœžœ˜.Kšœžœžœ ˜Kšœ˜Kšœ˜—Kš œžœžœžœžœ˜!Kšœžœ˜Kšœ#˜#Kšœžœ˜Kšœžœžœžœ˜DKšœžœ žœžœ˜&Kšœ9˜9Kšœ žœ˜#Kšžœ žœ žœ˜7Kšœ˜—K˜šžœžœ˜"Kš œžœžœžœžœ˜(Kšžœžœžœžœ˜)Kšœ ˜ šœžœžœ ˜-Kšžœžœ˜=Kšžœ˜ Kšœ˜—Kšœžœžœžœ˜:šžœ!žœžœ˜0Kšžœ)žœ˜4K˜—Kšœžœžœžœ˜:šž˜šžœžœž˜Kšœ#žœ˜DKšœ#žœ˜Dšœžœ˜'Kšœ5žœ˜?Kšœ5žœ˜?K˜—šœ#žœ˜.Kšœ<žœ˜GKšœ2žœ˜<šžœž˜Kšœ˜Kšœ˜Kšœ˜Kšœ˜Kšžœžœ˜—K˜—Kšžœžœ˜—Kšœžœžœžœ˜:Kšž˜—šžœ%žœ žœ˜>Kšžœ8˜:K˜—šžœ˜šž˜šž˜Kšžœžœ˜*Kš œžœΟrΠkr‘ œžœ˜;Kšžœ˜—Kšžœž˜Kšžœ˜—Kšœ4˜4Kšœžœ˜K˜—Kšžœ ˜K˜—Kšžœ ž˜Kšœ˜—K˜šŸ œžœžœžœ žœžœžœžœžœ˜XKšœ8˜8Kšœžœžœžœ˜Kšžœžœžœžœ˜)šžœžœ˜'Kšžœ4˜6Kšžœ˜ Kšœ˜—šžœžœ˜Kšžœ@˜BKšžœ˜ Kšœ˜—šžœž˜"Kšœ ˜ Kšœ ˜ Kšœ˜Kšœ˜šžœ˜ KšžœK˜MKšžœ˜ Kšœ˜——K˜Kšœ ˜ šœžœžœ ˜5Kšžœžœ#žœ˜\Kšžœ˜ Kšœ˜—Kšžœ˜šžœ<˜>Kšžœžœ!˜(Kšžœžœ!˜(—KšžœF˜HKšžœE˜Gšžœžœ ž˜+Kšœ.žœ˜6Kšœ4˜4Kšžœ žœ˜"Kš žœžœ žœ žœžœ ˜\Kšžœ˜—Kšžœ ˜Kšžœ=˜?Kšžœ ž˜Kšœ˜—K˜šŸœ˜*šœ ˜ KšœAžœžœ˜N—Kšžœžœžœžœ˜1Kšžœžœ˜3šžœ  ˜šžœžœž˜šœ! ˜8Kšœ žœ˜Kšžœžœ"žœžœ˜BKšœcžœžœžœ ˜™Kšžœžœžœžœ˜>Kšœ9˜9K˜—šœ  ˜+Kšžœžœžœžœ˜:Kšœžœ ˜"K˜—Kšžœ6žœžœ˜I—K˜—Kšžœ˜ Kšœ˜K˜—Kšœžœ]˜ušžœžœ˜!KšœJžœ˜P—KšœP˜Pšœ`˜`K™B—Kšžœ˜—…—,T=C