How can I customize a full-screen console background (TTY)?

I used to use full-screen consoles (those opened with Ctrl+Alt+F1...F6) actively and have come to an idea that I would like to try decorating it with a "wallpaper" of a sort (a rather dark and monotonous one of course so that it wouldn't decrease readability), perhaps this could look and feel nice (or not, but I need to try). It would even better if I could set different pictures as different console's background (one for Ctrl+Alt+F1, another for Ctrl+Alt+F2 etc).

The fact the consoles have much higher resolution that pure text mode provides suggests that full-fledged graphical mode is used for them and everything is possible. But how?


Solution 1:

I'm pretty sure that the Linux console driver does not have this ability built in, however there is an application called fbterm which can do this. In order to make background images work, you will also need a utility which can display an image on the framebuffer such as fbi:

sudo apt-get install fbterm fbi

fbterm does not actually read or display background images itself, it expects some other program to set up the background image on the screen before it starts. There are instructions in the fbterm man page on how to do this using fbv, an absolutely antiquated and unsupported utility I couldn't even get to compile on a modern Ubuntu system. fbi is a much cleaner and nicer image viewer for the framebuffer, but unfortunately does not have the "set it and exit" functionality of the simpler fbv, and thus interferes with fbterm if you try to use it directly. However, I was able to come up with an alternative which works:

First, you will need to use fbi and cat to display the image you want and then dump it to a "framebuffer raw format" image file. As root, in a framebuffer console, run:

( sleep 1; cat /dev/fb0 > nifty-background.fbimg ) & fbi -t 2 -1 --noverbose -a nifty-background.png

(This will display the image for a couple of seconds and then exit, having saved the result in the file nifty-background.fbimg. Replace nifty-background.fbimg and nifty-background.png with whatever filenames you wish, of course.)

The first part of the command waits for 1 second before catting the framebuffer contents to a file. At the same time, the second part (after the &) launches fbi to display the image on the framebuffer, so that when the cat command gets around to executing (1 second later), there's an image there to dump. The reason they're in that order is because I found that fbi had issues if it wasn't running in the foreground, which means it has to be the last command in the list.

From then on, whenever you want to run fbterm, you can start it like so (you may want to create a little wrapper script):

export FBTERM_BACKGROUND_IMAGE=1
cat nifty-background.fbimg > /dev/fb0; fbterm

Solution 2:

I can distinguish real text mode from its graphical emulation.

… which is one of the ways in which the observant could distinguish a real BSOD on Windows from the actions of the joke BSOD screen-saver that did the rounds a decade or so ago. The display of block graphics characters using the display adapter hardware in graphics mode was subtly different from the characters generated by the display adapter hardware in text mode.

Yes, the display adapter is in graphics mode. It has been this way for quite some while, now. It was always this way on systems without PC display adapter hardware. In the early years of Linux, on PC compatibles the console would have the display adapter hardware in text mode. But this use has quietly eroded to pretty much nothing. Unicode support for most users nowadays requires a bigger glyph set than the text-mode hardware has. The machine firmware (of course) uses graphics mode for splash screens (with pretty pictures and company logos), as does the Linux loader and system initialization.

There's a terminal emulator program built into the Linux kernel. It's layered on top of the framebuffer and the input event subsystem, which it uses internal kernel interfaces to access. It presents itself to application-mode systems as a series of kernel virtual terminal devices, /dev/tty1 and so forth.

This program is fairly limited compared to terminal emulators that run outwith the Linux kernel, as ordinary applications programs. It only emulates a limited subset of a real terminal's functionality, and it lacks the added features of the latter terminal emulators.

It is those that you need to look to for this. You may be familiar with the terminal emulators that use X for their input/output, such as xterm, lxterminal, gnome-console, konsole, eterm, wterm, and the rest. Less well known are the ones that use the framebuffer device(s) and the input event devices for their input/output. providing user-space virtual terminals:

  • zhcon (Ubuntu package),
  • fbpad,
  • fbterm (Ubuntu package) and its forks such as jfbterm (Ubuntu package),
  • bogl-bterm (Ubuntu package),
  • the nosh console-terminal-emulator and console-fb-realizer, and
  • kmscon.

Some of these latter can do what you want.

fbterm can be configured to use whatever is in the framebuffer at startup as a background image, for example. So all that one needs to do is use one of the several other utilities for displaying images directly to a Linux framebuffer deviceto set up a background image before running fbterm. There are several such tools, including:

  • dfbg (Ubuntu package),
  • Ali Gholami Rudi's fbvis, and
  • fbi (Ubuntu package).

fbvis and fbi clear the screen at exit, and require the convolutions that are explained in more detail in Foogod's answer. dfbg, though, doesn't clean up after itself, making it more suitable for this particular task.

Further reading

  • https://unix.stackexchange.com/a/177209/5132
  • https://unix.stackexchange.com/a/178807/5132
  • https://unix.stackexchange.com/a/194218/5132
  • Jonathan de Boyne Pollard (2015). "user-space virtual terminals". nosh Guide. 1.20. nosh. JdeBP's Softwares.
  • Jonathan de Boyne Pollard (2015). A quick look at user-space virtual terminals nosh. JdeBP's Softwares.
  • Geert Uytterhoeven (1998-10-25). FYI: Frame buffer console changes since 2.1.107. linux-kernel.