I know this sounds really dumb, and I don't plan on using this much, but is there a way with xrandr or something similar to make my display show the equivalent of grayscale but using a color instead of gray? I think it would be a really cool effect for some applications.

4 Answers 4


(This only addresses X11, not Wayland or other display management systems. Some of these techniques can be applied using other tools, e.g. the accessibility features of GNOME Shell.)

I can think of two ways of getting an amber display: insert a compositing plugin which fixes up all colours, and creating a colour profile which corrects all colours to an amber equivalent. Both of these probably involve more effort than they’re worth (apart from the learning side of things).

You can get a good approximation for primary colour displays by manipulating the per-channel gamma, as explained in sigvei’s answer; xcalib can also give access to this, and allows controlling the brightness and contrast directly as well as specifying the gamma value:

xcalib -blue 1.0 0 1.0 -red 1.0 0 1.0 -alter

results in a green display. Brightness and contrast are applied to the gamma ramps so xrandr will allow you to achieve the same results.

It’s possible to control the gamma ramps more finely still, but that won’t allow you to remap everything to amber colours anyway. You can “clamp” channels to certain ranges, so for example a bright red will have some green introduced and thus appear more amber-ish, but then dark reds would appear green...

The following code shows how to go about this (with no error-handling):

#include <X11/Xos.h>
#include <X11/Xlib.h>
#include <X11/extensions/xf86vmode.h>
#include <stdlib.h>

int main(int argc, char **argv) {
  Display * dpy = NULL;
  int screen = -1;
  u_int16_t * r_ramp = NULL, * g_ramp = NULL, * b_ramp = NULL;
  unsigned int ramp_size = 256;
  int r_tgt = 255, g_tgt = 191, b_tgt = 0;
  int i;

  dpy = XOpenDisplay(NULL);
  screen = DefaultScreen(dpy);

  /* Set up ramps */
  XF86VidModeGetGammaRampSize(dpy, screen, &ramp_size);
  r_ramp = (unsigned short *) calloc(ramp_size, sizeof(u_int16_t));
  g_ramp = (unsigned short *) calloc(ramp_size, sizeof(u_int16_t));
  b_ramp = (unsigned short *) calloc(ramp_size, sizeof(u_int16_t));
  for (i = 0; i < ramp_size; i++) {
    r_ramp[i] = r_tgt * 256 * i / ramp_size;
    g_ramp[i] = g_tgt * 256 * i / ramp_size;
    b_ramp[i] = b_tgt * 256 * i / ramp_size;
  XF86VidModeSetGammaRamp(dpy, screen, ramp_size, r_ramp, g_ramp, b_ramp);

(You’ll need -lX11 -lXxf86vm to link.)

  • Very cool! I haven't tried the xcalib command yet just because I don't have it installed, but the c program is pretty neat. Like I said, I don't really intend to have my display constantly tinted a certain color, but I appreciate learning about it. Thanks! Jun 24, 2019 at 20:56

xrandr --output $OUTPUT --gamma 1:0.01:0.01 gives you an almost monochrome red-on black.

The triplet of numbers are rgb values for the gamma correction, separated by :, in the range of 0-1. Replace 1:0.01:0.01 with 0.01:1:0.01 for green, and 0.01:0.01:1 for blue. It's hard to make any other color than these three basic ones. It becomes very much visible once you start letting more than one color through.

This method only works with dark/black backgrounds, because the gamma correction of bright white is just white.

Use xrandr -q to find the output ID to use for $OUTPUT; my laptop screen is LVDS-1, for instance.

  • Still see white background on this very page. Apr 11, 2020 at 2:49

If you use a compositing window manager that supports plugins, you can likely make a plugin that will alter the screen pixels as you wish, i.e. calculate luminance of the input pixel and modulate the result with amber color (applying gamma correction back and forth as needed).

Here's an example of a hack on the Invert effect in KDE window manager, KWin, to achieve this. This hack consists of simply replacing Invert effect's shader located in the KWin source tree under effects/invert/data/1.40/invert.frag (assuming your GPU is capable of GLSL 1.40) with customized code:

#version 140
uniform sampler2D sampler;
uniform vec4 modulation;
uniform float saturation;

in vec2 texcoord0;

out vec4 fragColor;

void main()
    vec4 tex = texture(sampler, texcoord0);
    float luminance = dot(vec3(0.2126729,0.7151522,0.0721750), pow(tex.rgb,vec3(2.2)));
    float desaturated = pow(luminance, 1./2.2);

    const vec3 amber=vec3(1.,0.5,0.);
    tex.rgb = desaturated*amber;
    tex *= modulation;
    tex.rgb *= tex.a;

    fragColor = tex;

In KDE4 KWin you could simply replace the shader file installed into /usr/share/apps/kwin/shaders/1.40/invert.frag (having replaced texcoord0 in the code given above with varyingTexCoords). Since KDE5, unfortunately, the shader is built into plugin binary as Qt resource, so you'll have to recompile KWin with the file edited in the source tree for the new shader to apply.

The result looks like the screenshot below shows when the effect is activated by its shortcut key combo (tested on KDE4 KWin, on Geforce GTX 750Ti with proprietary nvidia driver). Note that mouse cursor remains unchanged, because it's normally rendered not by the window manager, so it should be changed in another way, or simulated as the Zoom effect does.

screenshot of the effect in action


Whew! While it's possible to change the color of your terminal. I'm pretty sure you don't intend to convert your Desktop experience into Grayscale.

That said, there's a couple of moving parts involved here. The most relevant being your chosen terminal emutator. For example xterm (FreeBSD) (Linux) allows for the modification of many aspects of presentation. If you were looking for Amber text on a Black background (Amber Monochrome). You could accomplish it this way,

Create a Xterm window 87 rows by 57 columns in the top left-hand corner of my Desktop having a black background, with amber text, using my login shell, and an Amber blinking block cursor

xterm -geometry 84x57+0+0 -C -ls -bg black -fg gold -cr gold

You can even change the color of the pointer -ms color

NOTE I chose the color Gold, as it appeared the closest to the actual color I remember my Amber monochrome monitor to look like. You can find all the colors available in the X11 color table

Speaking of Login Shells; another influencing factor is your chosen shell. Mine is (t)csh, and given I'm familiar with that I'll provide another example for that;

Here's the relevant excerpt from my .cshrc


setenv  PAGER   less
setenv  BLOCKSIZE   K
setenv  CLICOLOR

# Colors!
set     red="%{\033[1;31m%}"
set   green="%{\033[0;32m%}"
set  yellow="%{\033[1;33m%}"
set    blue="%{\033[1;34m%}"
set magenta="%{\033[1;35m%}"
set    cyan="%{\033[1;36m%}"
set   white="%{\033[0;37m%}"
set     end="%{\033[0m%}" # This is needed at the end


# Prompt style
set prompt = "${yellow}`/bin/hostname -s` %#${end} "
set promptchars = "%#"

This will effectively provide an Amber prompt on a Black background. You can adjust the ANSI escape sequence to acquire the exact shade of yellow (Amber) you're looking for. You can also apply those escape sequences to any other shell prompt, as well.

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .