31

I am not sure if it is the only possible way, but I read that in order to put a single pixel onto the screen at a location of your choice one has to write something into a place called framebuffer. So I became curious, if it is possible to enter into this place and write something into it in order to display a single pixel somewhere on the screen.

Gilles 'SO- stop being evil'
  • 807,993
  • 194
  • 1,674
  • 2,175
Abdul Al Hazred
  • 25,760
  • 23
  • 64
  • 88

2 Answers2

29

yes, outside X-server, in tty, try command:

cat /dev/urandom >/dev/fb0

if colourfull pixels fills the screen, then your setup is ok, and you can try playing with this small script:

#!/usr/bin/env bash

fbdev=/dev/fb0 ;   width=1280 ; bpp=4
color="\x00\x00\xFF\x00" #red colored

function pixel()
{  xx=$1 ; yy=$2
   printf "$color" | dd bs=$bpp seek=$(($yy * $width + $xx)) \
                        of=$fbdev &>/dev/null
}
x=0 ; y=0 ; clear
for i in {1..500}; do
   pixel $((x++)) $((y++))
done

where function 'pixel' should be an answer... write a pixel to screen by changing byte values (blue-green-red-alpha) on x-y offset of device /dev/fbX which is frame buffer for the video-card.

or try one liner pixel draw (yellow on x:y=200:100, if width is 1024):

printf "\x00\xFF\xFF\x00" | dd bs=4 seek=$((100 * 1024 + 200)) >/dev/fb0

UPDATE: this code works even inside X-server, if we just configure X to use frame buffer. by specifying fb0 inside /usr/share/X11/xorg.conf.d/99-fbdev.conf

Asain Kujovic
  • 1,681
  • 15
  • 18
  • There's a couple of dangerous things going on here: the first example appears to write random bytes to a floppy disk, for some reason. The follow up commands use `dd` which has often been called "Disk Destroy" for specific reasons ... don't go near these commands unless you know what you're doing ... – robert Mar 27 '15 at 08:31
  • 5
    @robert I think Omar meant `/dev/fbX` and the `/dev/fd` was just a typo. And yes, `dd` is dangerous but so is `rm`. That doesn't mean it shouldn't be used. It just means that it should be used with care. – terdon Mar 27 '15 at 11:35
  • 1
    ah `/dev/fb0` makes more sense! Everybody knows what `rm` means, but `dd` is a little more obscure, still think it should carry a health warning. – robert Mar 27 '15 at 11:37
  • 3
    "yes, outside X-server, in tty, try command:" I do not understand if I got it right, so I tried just opening the terminal and writing "cat /dev/urandom > /dev/fd0" but I only got an error message : "cat: write error: no space left on device". I really do not know how to get out of the xserver. – Abdul Al Hazred Mar 27 '15 at 15:34
  • 1
    ... i called it tty, but it is virtual console, non-gui thing, terminal over all screen, that you reach with ctrl-alt-f1,2,3... or "sudo chvt 1" ... 'no space left' seems like it will be ok, just you are still in X-session. – Asain Kujovic Mar 27 '15 at 17:03
  • @AsainKujovic, Why does this not work while X is running? I observed the same "no space left on device" error after the entire screen was filled with random pixel values. Is it a result of X also writing to the fb and causing the driver to fill quickly? – sherrellbc Nov 02 '16 at 22:51
  • @sherrellbc, "no space left" is normal because random is infinite and screen has fixed number of WxH pixels... writing to FB do not work inside X because X uses some other lower level way of communication with video-card. There is also DRM, KMS... KODI for example uses OpenMax. FrameBuffer is just one of methods and not the lowest one. – Asain Kujovic Nov 03 '16 at 15:22
  • @sherrellbc, ... actually now i know that it can work easily inside X, your question leaded me to above 'update'. – Asain Kujovic Nov 03 '16 at 15:56
1

I just posted this this morning, still investigating why it only works on Raspberry Pis. https://www.raspberrypi.org/forums/viewtopic.php?f=72&t=213964&p=1428891#p1428891

Open /dev/fb0, mmap it so you get a pointer, and it's much faster. Doesn't use X at all but it will happily ignore X, it's just something on the screen.

Oh, from a command line, sort of, you can write to /dev/fb0. But whatever you write at offset 0 will be in the upper left corner so it will immediately scroll off the screen. You could do a for loop in Bash and write a couple thousand times. Or use /dev/urandom. Destroying what's in the screenbuffer, especially while you're in X, is no big deal. As soon as you drag a window over the area X causes an expose event and repaints it. You don't need to kill the power to recover.

Alan Corey
  • 247
  • 2
  • 5