############################################################################ # # File: xgamma.icn # # Subject: Program to configure X color correction # # Author: Gregg M. Townsend # # Date: November 14, 1994 # ############################################################################ # # This file is in the public domain. # ############################################################################ # # Xgamma sets the root window properties that provide device-independent # color under X windows. Icon derives the default value of the "gamma" # attribute from these properties. # # Ideally, color properties would be set automatically based on # specifications provided by the manufacturer of the monitor. # Lacking such specifications, xgamma synthesizes intensity ramps # for an ideal monitor characterized by a given gamma value. # # The phosphor colors, which must also be set, are set to those of a # Sony Trinitron monitor based on values from the X11R5 distribution. # # There are three ways to call xgamma: # # xgamma m.n set color properties using gamma value m.n # xgamma none remove color properties # xgamma report gamma attribute inferred by Icon # # A pipe to "xcmsdb" is opened, so that program must be in the current # search path. # # The default gamma attribute calculated by Icon does not always exactly # match the value set by xgamma. The reason for this is unclear. # ############################################################################ # # Requires: Version 9 graphics under X11R5 # ############################################################################ # # Links: wopen # ############################################################################ link wopen global ofile procedure main(args) local gamma if *args = 0 then { WOpen("canvas=hidden", "size=200,100") | stop("can't open window") write(left(WAttrib("gamma") + 0.005, 4)) return } if map(args[1]) == ("none" | "off" | "remove") then { system("xcmsdb -remove") return } gamma := real(args[1]) | 2.5 ofile := open("xcmsdb", "wp") | stop("can't open pipe to xcmsdb") write(ofile, "SCREENDATA_BEGIN 0.3") header() matrices() ramps(gamma) write(ofile, ) write(ofile, "SCREENDATA_END") end procedure header() every write(ofile, ![ "", " NAME Unknown monitor", " PART_NUMBER 3", " MODEL Unknown", " SCREEN_CLASS VIDEO_RGB", " REVISION 2.0", ]) end procedure matrices() # Trinitron specs from X11R5 contrib/clients/xcrtca/monitors every write(ofile, " ", \![ "COLORIMETRIC_BEGIN", " XYZtoRGB_MATRIX_BEGIN", " 3.061645878834450 -1.278267953801873 -0.444951165661258", " -1.032702121385028 1.976844500877421 0.008133037520752", " 0.057063919003669 -0.199057800043321 0.779596768525705", " XYZtoRGB_MATRIX_END", " RGBtoXYZ_MATRIX_BEGIN", " 0.422396751969335 0.297093836421011 0.237981555762915", " 0.220555266059938 0.660453956058605 0.118990777881458", " 0.025397273061447 0.146890261130091 1.295677359153649", " RGBtoXYZ_MATRIX_END", "COLORIMETRIC_END", ]) end procedure ramps(gamma) write(ofile, " INTENSITY_PROFILE_BEGIN 0 3") every hue("RED" | "GREEN" | "BLUE", gamma) write(ofile, " INTENSITY_PROFILE_END") end procedure hue(c, gamma) local i, x, v static hextab initial every put((hextab := []), !"0123456789abcdef" || !"0123456789abcdef") write(ofile, " INTENSITY_TBL_BEGIN ", c, " 256") every i := 0 to 255 do { x := hextab[i + 1] v := (i / 255.0) ^ gamma if v < 0.0001 then # avoid "e" notation v := 0.0 write(ofile, " 0x", x, x, " ", left(v, 8, "0")) } write(ofile, " INTENSITY_TBL_END") end