Share your linux screen over ipad (for free)

Akash Kumar Dutta
4 min readMay 25, 2020

--

It is important to get your ergonomics right. For me, having an extra monitor with laptop/primary-monitor is a much needed productivity boost. I tried to use my ipad for screen sharing, since we all are confined to work from home during covid, finding hacky ways to achieve good becomes the norm. The end result of this hack was surprisingly good!

Note: There are paid apps like duet display in apple store that extend windows and mac os to ipad, but in this post we are talking all about a free setup (which would enable screen sharing even on an android tablet).

Tools you’ll need

Check you have following command line tools installed in your linux distro:

  1. xrandr : A resize and rotation manager for X displays. Basically manages your monitor display settings. It is by default bundled with all linux distros having X windows manager.
  2. cvt : It generates modeline description for X servers given the horizontal and vertical resolution. Modeline is a string which states the configuration for new display to be created by xrandr. Again, it comes bundled by default.
  3. x11vnc : A vnc (virtual network computing) server. This enables clients with vnc support to connect to real X displays. Install this from the source to get the latest version (because the version from apt repository is outdated and does not support features like multiptr which we’ll come to shortly).

Setup

Now that we have the tools, let’s set them up.

My output for command xrandr is shown below:

Screen 0: minimum 8 x 8, current 1920 x 1080, maximum 32767 x 32767
eDP1 connected primary 1920x1080+0+0 (normal left inverted right x axis y axis) 340mm x 190mm
1920x1080 60.02*+ 59.93
1680x1050 59.88
1600x1024 60.17
... ...
DP1 disconnected (normal left inverted right x axis y axis)
DP2 disconnected (normal left inverted right x axis y axis)
HDMI1 disconnected (normal left inverted right x axis y axis)
HDMI2 disconnected (normal left inverted right x axis y axis)
HDMI3 disconnected (normal left inverted right x axis y axis)
VIRTUAL1 disconnected (normal left inverted right x axis y axis)
VIRTUAL2 disconnected (normal left inverted right x axis y axis)

The last two lines are VIRTUAL outputs, which we will use for rendering the secondary screen display. These outputs are video card specific. If you cannot see the VIRTUAL display listed there, see here how to enable it for an intel-based card.

For nvidia-based card, add the following into /usr/share/X11/xorg.conf.d/30-virtscreen.conf (source):

# nvidia/nouveau/amdgpu device should be configured first before Intel GPU
Section "Device"
Identifier "nvidiagpu0"
Driver "nvidia" # Because you are using Nvidia proprietary driver. Change to "nouveau" if you are using open source nouveau driver
EndSection

# Then configure intel internal GPU
Section "Device"
Identifier "intelgpu0"
Driver "intel"
# You may put Option "VirtualHeads" "1" here but it seem you don't need to put this for Ubuntu 18.04.
EndSection

Note: Using a powerful gpu would give a better performance as screen rendering is embarrassingly parallel.

Now that we have got our VIRTUAL outputs, we’ll add a display mode into it and position it to the right of our current screen, so that our new screen is on the right of our primary display.

Follow along the commands in your terminal:

#! /bin/bashWIDTH=1600
HEIGHT=1200
OUTPUT="VIRTUAL1"
# Gets the Primary Output
PRIMARY_OUTPUT=$(xrandr | sed -n "s/\(\w*\)\s*connected\s*primary.*/\1/p")
# This generates a new mode description
MODE_DESCRIPTION=$(cvt "$WIDTH" "$HEIGHT" 60 | sed -n "s/^.*Modeline\s*\".*\"\s*//p")
# Mode name needs to follow a pattern based on resolution
MODE_NAME=$(cvt "$WIDTH" "$HEIGHT" 60 | sed -n "s/^.*Modeline\s*\"\(.*\)\".*/\1/p")
# Create the new mode
echo $MODE_NAME $MODE_DESCRIPTION | xargs xrandr --newmode
# Attach the new mode to OUTPUT
echo $OUTPUT $MODE_NAME | xargs xrandr --addmode
# Display the new OUTPUT
xrandr --output $OUTPUT --mode $MODE_NAME
# Place the OUTPUT to the right of PRIMARY DISPLAY (your current screen)
# See --help for more positions to attach
xrandr --output $OUTPUT --right-of $PRIMARY_OUTPUT
# Capture the position for new Display
OUTPUT_POSITION=$(xrandr | sed -n "s/^$OUTPUT\s*connected\s*\([0-9]*x[0-9]*+[0-9]*+[0-9]*\).*/\1/p")

# Run the VNC server on that clip position, enable multiptr that replicates server cursor movement on client as well, also add a buffer of 10 pixels cache to increase performance
x11vnc -multiptr -ncache 10 -repeat -cursor most -clip $OUTPUT_POSITION

Now, you should have a vnc server up and running (by default on port 5900) !

Connect ipad/android tablet

Use any vnc client for your ipad/android to connect with your machine. I use VNC Viewer, which is free and it works flawlessly.

Note: You must setup a password to keep your connection private, and if it’s over a public network, enable ssl protection as well. Check github page of x11vnc for more details.

It is thus really easy to set this up. Although X windows were originally built in a way to allow remote connection (ssh -X for example), x11vnc uses an optimized alogrithm for graphic pixel sharing and has much better performance.

To remove screen sharing, use:

# Remove the display for OUTPUT
xrandr --output $OUTPUT --off
# Delete the mode from OUTPUT
xrandr --delmode $OUTPUT $MODE_NAME

Let me know if you’ve got any questions. Thanks for the read!

--

--

Akash Kumar Dutta
Akash Kumar Dutta

Written by Akash Kumar Dutta

Tinkering down my bits for tomorrow.

No responses yet