Wednesday, July 9, 2014

Using another tablet/computer as a second screen with Open Source

Note: This trick requires an the intel xorg driver. While there may be other ways to do this I'll only be explaining this one method I found.

How it works:

The basic idea behind this is that we tell the GPU to write to a much larger screen than we actually have, then we send a section of that big screen to another computer/tablet to be displayed.
Rendering to a larger screen is trivial with XRandR. If you want to render to a screen large enough to fit to 1920x1080 monitors inside you can simply run: xrandr --fb 3840x1080
However, doing this doesn't tell your window manager about the extra space. As far as it's concerned that space doesn't exist so you won't be able to do much with it.
To get window managers to acknowledge space outside of your physical screen we can use a new feature of Intel's xorg driver called VirtualHeads. These are virtual outputs which act the same as a real output except without the actual output part.

The steps:

Get the right Intel xorg drivers

We need the relatively recently added VirtualHeads of the Intel xorg driver to make this work. On Fedora 20 the latest version I could get  was 2.21.15 which was too old so I compiled and installed the latest source package from Rawhide. How to get these drivers will very from distro to distro.

Update your xorg.conf files

In order to actually use VirtualHeads you need to the Device section for your Intel card in your xorg.conf. Some distributions (like Fedora) don't use an xorg.conf file any more because the default configuration is very sane. I had to add a new file: /etc/X11/xorg.conf.d/20-intel.conf with the following:
Section "Device"
    Identifier "Device0"
    Option "AccelMethod" "sna"
    Option "VirtualHeads" "1"
    Driver "intel"
Note: The AccelMethod is important as VirtualHeads is only supported with sna.
Before continuing you'll have to restart X to get these settings loaded. If you did everything right then when you run xrandr you should see a new output named VIRTUAL1.

Set your virtual output's resolution

By default this new virtual output will have no resolutions associated with it. While you can set it to whatever you want, it likely makes the most sense to set it to it to match the resolution of your other device.

Add new mode

If your primary display can be set to the resolution you want you can simply skip this step. If not we'll need to add a new mode to XRandR. XRandR modelines can be a little complicated, but luckily there are tools which largely handle them for us. Simply run
cvt <width> <height>
To get out the right modeline. For example, if I want to add a new 2560x1600 mode I would type:
cvt 2560 1600
which results in
Modeline "2560x1600_60.00"  348.50  2560 2760 3032 3504  1600 1603 1609 1658 -hsync +vsync
To add this to XrandR type: xrandr --newmode
then copy everything after "Modeline"
In my case I'd end up with:
xrandr --newmode "2560x1600_60.00"  348.50  2560 2760 3032 3504  1600 1603 1609 1658 -hsync +vsync\

Add mode to virtual output

To associate this mode with our virtual output we simply run:
xrandr --addmode VIRTUAL1 <mode name>
In my case I'd run:
xrandr --addmode VIRTUAL1 "2560x1600_60.00"

Start up the virtual output

Now we need to enable the virtual output. Here you use xrandr just like you would for a physical monitor. In my case I could run:
xrandr --output VIRTUAL1 --mode "2560x1600_60.00" --right-of eDP1
You can also use a graphical tool like arandr to do this step.
At this point your window manager should act as though you have two monitors.

Point your other device at the virtual display

There are several ways to point your other device at your new virtual display. I'm only going to cover how using x11vnc as I've yet to find anything better.
If you don't already have it installed, install x11vnc.
The simplest way to do this is to simply run:
x11vnc -clip xinerama1
However, there are lots of x11vnc options you may want to use which allow you to do things such as add a password or set the display to be read-only.
Finally, to get your other device to connect you just install a VNC viewer and point it at the VNC server you just started. Don't forget to allow VNC through any firewall you might have.

Hopefully this helped some people re-use one of their devices as an external monitor. Let me know if you have any problems or suggestions!