6

I want to take screenshots simultaneously from multiple X servers on one desktop PC.

I have multiple users logged in different terminals (tty1, tty2, tty3, tty4) who start multiple Xservers with startx /usr/bin/openbox-session -- :1 (and :2, :3, :4 respectively). So I can access each one of them with Ctrl+Alt+F8, +F9, +F10, +F11.

There is only one monitor on that desktop.

I want to take screenshots for each of these X servers, preferably with scrot, but I currently get a black/blank image whenever I try it. Only when I am active on that X server I get a proper screenshot.

For example, if I am on Ctrl+Alt+F8 and run scrot test.png I get a proper screenshot; if I understand correctly I do not have to set the $DISPLAY, since being on Ctrl+Alt+F8 I get echo $DISPLAY > :1. But if I run sleep 10; scrot test.png and go to Ctrl+Alt+F7, then I get a black image.

How can I get multiple screenshots from each one of those terminals simultaneously?

What worked for me was Xephyr. The only problem with this solution seems to be that when I run extremely fast xdotool commands it is not as responsive as X.

For future reference, what I did for every of the four users and terminals was:

In ~/.profile, I set each user to auto-login after my system boot, like:

if [[ -z $DISPLAY ]] && [[ $(tty) = /dev/tty1 ]]; then
     sleep 30 # for some reason it crashes if I do not let 
              # it sleep for a while, not necessarily so long. 
              # I guess it has to do with my "normal" X at DISPLAY=:0 . 
              # Thus for tty2 I let it sleep 40 seconds, 
              # for tty3 50 seconds and so on.
     startx
fi

In ~/.Xsession, I start an Xserver/client (with blackbox) and Xephyr (with openbox) in it like:

Xephyr -fullscreen -screen 1920x1200 :11 &
exec blackbox & 
sleep 3 # Perhaps sleeping is redundant.
DISPLAY=:11 /usr/bin/openbox-session

I want the "final" window manager do be openbox-session. I would like to use openbox for both the Xserver and Xephyr, but exec openbox & DISPLAY=:11 /usr/bin/openbox-session crashes, while exec openbox & DISPLAY=:11 /usr/bin/openbox does not.

This way, the user in :11 can take screenshot, while the monitor shows :0. (or :13, :14, etc.).

I did not try XVnc, but I have the feeling that it might be slower than Xephyr; please correct me if I am wrong.

6
  • The $DISPLAY variable needs to change for scrot. This will not happen if it remains in the subshell launched from the Xserver you just switched from.
    – mikeserv
    Commented Aug 21, 2014 at 1:36
  • each one of those VTs is a separate X server. If you are on one of them and switch to another you're looking at a different X server - a different $DISPLAY. So when you run a delayed scrot with one $DISPLAY and switch to a different one before it executes its $DISPLAY goes dark. It would have worked without Xephyr at all - and, in truth, layering the servers that way only complicates the issue further, though it can be made to work.
    – mikeserv
    Commented Aug 22, 2014 at 0:01
  • @mikeserv I appreciate very much your support and it seems I misunderstand something very basic. How could it work without Xephyr? When on the VT of Ctrl+Alt+F8 I run sleep 3; DISPLAY=$(echo $DISPLAY) scrot test.png (which is the same as sleep 3; DISPLAY=:1 scrot test.png and within 3 seconds I switch to Ctrl+Alt+F7 (where $DISPLAY is :0) I get a blank test.png. Commented Aug 22, 2014 at 7:38
  • This is the reason: the scrot process is a child of VT8 - its $DISPLAY is always :1 - even after you switch. That is the value exported into its environment by its parent shell - which you leave behind when you switch to VT7. Think about it this way - if there were no Xservers running at all and only the console - at boot you'd get a login prompt then a shell. If you switch to another you'll get another login prompt and another shell. Different VTs, different shells. Different VTs, different $DISPLAYs scrot gets left behind. Do DISPLAY=:0 scrot test.png.
    – mikeserv
    Commented Aug 22, 2014 at 7:47
  • When I am at VT8 and run sleep 3; DISPLAY=:0 scrot test.png and switch within 3 seconds to VT7, I get the screenshot of VT7. Is this what you mean? I want to work on VT7, and get the screenshot of VT8. Is this possible without Xephyr? Commented Aug 22, 2014 at 7:51

2 Answers 2

6

Method #1 - Using xwd

You could just use the command line tool xwd to grab the X displays like so:

$ xwd -display :1 -root -out 1.xwd

You could loop through 1 to 4 like so:

$ for i in {1..4};do xwd -display :$i -root $i.xwd; done

NOTE: The resulting .xwd files are a special type of X Windows dump file.

$ file 1.xwd 
1.xwd: XWD X Window Dump image data, "xwdump", 4160x1440x24

You can use xwud to display them like so:

$ xwud -in 1.xwd

Or you can use ImageMagick's display command to view them:

$ display 1.xwd

Method #2 - Using import

You can also use ImagMagick's import command to do something similar:

$ import -window root -display :0.0 -screen /tmp/0.png

Method #3 - using scrot

Or as was suggested by @mikeserv in the comments, try setting the $DISPLAY so that scrot can find the active X display correctly:

$ DISPLAY=:1 scrot 1.png

This could be looped like so:

$ for i in {1..4};do DISPLAY=:$i scrot $i.png; done

References

9
  • 1
    @mikeserv - I was able to view the resulting xwd dump file using display out of ImageMagick. I don't even have access to that tool, xwud on F20. Querying the YUM repos to see if it's buried somewhere else 8-)
    – slm
    Commented Aug 21, 2014 at 14:59
  • @mikeserv - found it, it's buried in this pkg: xorg-x11-apps-0:7.7-7.fc20.x86_64.
    – slm
    Commented Aug 21, 2014 at 15:02
  • @mikeserv - yeah they do, my mistake. I ran that on F19 last night, and now I'm on F20 and didn't have that pkg installed...yet 8-). Updated the A with your info as well, thanks!
    – slm
    Commented Aug 21, 2014 at 15:07
  • I may be missing something, but I understood the question as that the OP did try a solution like these, and got a black screen only - so I would expect that these methods do not work too? It the OP just did not set DISPLAY, he would get an error, not a black image, I think. Commented Aug 21, 2014 at 15:25
  • @VolkerSiegel - he didn't explicitly say that he did set $DISPLAY, also with these methods he does not need to set $DISPLAY since these commands take the display arg. directly. Also I 1/2 suspect that he might need to export $DISPLAY, so that scrot can pick it up. These will just sit here until he confirms all this for us.
    – slm
    Commented Aug 21, 2014 at 15:29
3

I understand the problem in the question as follows:

  • You are on a text console tty,
    so there is no X running on the tty where you are running the screenshot command.

  • You can run command line screenshot commands for the X displays.

  • You have specified the X displays for the screenshot commands, like in
    DISPLAY=:2 scrot out.png.

  • The screen shot command does not give you an error


But you get a black image as output.


The problem could be that the X server is not painting the image into some image buffer, and the screenshot is taken from that empty buffer. But it could also be that it's a compositing window manager, like compiz, that is not painting. At least if you capture single windows, that could be the problem. I think it's worth trying to use a not compositing window manager, like metacity.

If that does not solve it, there is a completely different approach:

Run all your X servers as nested X servers on one display. Each nested X server is showing it's screen output in a window. You can then either make full screen screenshots of the nested display, or window screenshots on the main display.

As implementation of a nested X server, Xephyr seems to be the most current. There are also the older Xnest and Xvfb:

From man Xephyr:

 NAME
        Xephyr - X server outputting to a window on a pre-existing X display

 DESCRIPTION
        Xephyr  is a kdrive server that outputs to a window on a pre-existing "host" X dis‐
        play.  Think Xnest but with support for modern extensions  like  composite,  damage
        and randr.

        Unlike  Xnest  which is an X proxy, i.e.  limited to the capabilities of the host X
        server, Xephyr is a real X server which uses the host X server  window  as  "frame‐
        buffer" via fast SHM XImages.

In a similar way, Xvnc (from package vnc4server) could be used, providing access by VNC protocol additionally:

From Xvnc4:

 NAME
        Xvnc - the X VNC server

 DESCRIPTION
        Xvnc  is the X VNC (Virtual Network Computing) server.  It is based on a standard X
        server, but it has a "virtual" screen rather than a physical one.   X  applications
        display  themselves  on  it  as if it were a normal X display, but they can only be
        accessed via a VNC viewer - see vncviewer(1).

        So Xvnc is really two servers in one. To the applications it is an X server, and to
        the  remote  VNC  users it is a VNC server. By convention we have arranged that the
        VNC server display number will be the same as the X server  display  number,  which
        means  you  can  use eg. snoopy:2 to refer to display 2 on machine "snoopy" in both
        the X world and the VNC world.

(Xvnc is available as package vnc4server in Ubuntu)

1
  • the asker has specifically not set the $DISPLAY variable to other than the current VT. - see? if I understand correctly I do not have to set the $DISPLAY, since being on Ctrl+Alt+F8 I get echo $DISPLAY > :1. But if I run sleep 10; scrot test.png and go to Ctrl+Alt+F7, then I get a black image.
    – mikeserv
    Commented Aug 21, 2014 at 23:57

You must log in to answer this question.

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