Dual Monitor (Multi seat) setup with Displaylink USB Montors

This blog post was published 12 years ago and may or may not have aged well. While reading please keep in mind that it may no longer be accurate or even relevant.

This tutorial shows you a working setup for operating 2 monitors (one conventional one connected to the normal VGA output of your graphics card and one USB monitor with a Displaylink chip), demonstrated on Ubuntu 12.10 and Debian GNU/Linux 7 (Wheezy).

Introduction

First, I should mention that there is a lot of movement in working with Displaylink based USB monitors in GNU/Linux. Almost all documentation in the internet is either outdated or does not work, despite great interest in running many seats with just one machine.

Earlier tutorials in the internet concentrate on the xserver-xorg-video-displaylink package for the X Window System. To my great surprise, it as been removed from Ubuntu in August 2012 because the “displaylink KMS driver in the quantal kernel and x-x-v-modesetting replaces -displaylink”. After pulling some threads for an hour or so, it turned out that there is work going on to add displaylink support directly into the Kernel — this new support seems to be different from the already existing capability of the kernel to create a framebuffer device node like /dev/fb1. This DRM kernel module is called udl(announcement here and here), but the version at the point of this writing is 0.0.1 and, for now, it seems to do nothing more than to register and deregister Displaylink chips when plugged in and out.

If you research further, you will see that a new service manager called systemd is being developed as better replacement for existing startup/service managers, and that the udl Kernel module is supposted to work with systemd. Apparently it should be possible to have a single X11 server also ‘serve’ USB displays, so that you can share your desktop across several screens in true hotplug fashion.

This sounds very cool, but since all of that is in an extremely early stage, we can assume that a working plug and play for USB monitors will happen only a few years in the future, so going this route is a dead end, at least for now, and when you’re not a hardcore Kernel Module / X Windows developer that has a lot of experience in driving microchips.

In researching the alternatives, I found a working solution in running a separate X instance for the USB monitor. This second instance (apart from the first one that is ‘there’ by default) can either be started from a script — or from a Display Manager that supports Multi Seat setups.

In trying various configurations for X, it turned out that it is possible to make X use the framebuffer device node (like /dev/fb1) directly, even without the now obsolete xserver-xorg-video-displaylink package, by using the driver “fbdev” instead of the obsolete driver “displaylink”. How exactly this is set up, see the instructions below. In any case, you need to run 2 separate instances of X in parallel.

Once I knew that X worked with the USB monitor, the next step was to research Display Managers to find out methods how to start this second X instance. I have looked into LightDM and the Gnome Display Manager gdm3.

To my dismay, I found out that LightDM, while advertised as very small and lean, almost has no useful documentation, and I spent several hours restarting lightdm to find out working settings in trial-and-error. Even though I found working settings for LightDM, those still seem to be extremely brittle and subject to bugs over bugs in LightDM. The advantage of lightdm over gdm is that it supports a Multi Seat setup, whereas newer versions (!) of gdm outright do not support multi seats any more. The subjectively perceived ‘brittleness’ of LightDM is such, that it will start only Unity whenever the slightest thing goes wrong in its configuration. Once Unity is started (by mistake), LightDM will remember Unity in a handful of configuration files and it becomes very hard again to get rid of Unity.

So, below we’ll present 2 solutions:

  1. LightDM multi-seat setup in Ubuntu 12.10, where two X servers are spawned from LightDM, running 2 instaces of the X Window System, with two different system users.
  2. Manual start of a second X server in Debian Wheezy, because gdm3 does not allow for Multi Seat configuration

Ubuntu 12.10 with LightDM and Window Managers “Unity” and “Fvwm”

Ubuntu 12.10 already prefers the new udl Kernel module over the udlfbframebuffer module, which means that you won’t get the “green screen of success” on Displaylink based USB monitors during system boot. Instead, you get the repeating test patterns, but we need the green screen for this method to work. So, we have to blacklist udl and un-blacklist udlfb:

  1. add blacklist udl to /etc/modprobe.d/blacklist-custom.conf
  2. comment out blacklist udlfb from /etc/modprobe.d/blacklist-framebuffer.conf

When you reboot, the USB monitor should be green.

In the course of my experimentation, I found that running “Unity” on the USB Displaylink monitor had severe distortions of color and window geometry, which rendered “Unity” useless for my purpose. So I chose a simpler and faster Window Manager as a workaround. I decided for “Fvwm”, which you can install with

apt-get install fvwm

Next, we need to create the X configuration for the second X instance. We will call the second X instance with the explicit path to the configuration file, so this does not need to go into /etc/X11/xorg.conf.d, and you also don’t need to generate a working xorg.conf first. Modern distributions come without this file anyway, and X autodetects everything. Simply create the file /root/displaylink.conf with the following contents:

Section "ServerLayout"
Identifier "displaylink"
Screen "DisplayLinkScreen"
InputDevice "Mouse0"
EndSection

Section "Screen"
Identifier "DisplayLinkScreen"
Device "DisplayLinkDevice"
Monitor "DisplayLinkMonitor"
SubSection "Display"
Depth 24
Modes "800x480"
EndSubSection
EndSection

Section "Monitor"
Identifier "DisplayLinkMonitor"
EndSection

Section "Device"
Identifier "DisplayLinkDevice"
driver "fbdev"
Option "fbdev" "/dev/fb1"
EndSection

Section "InputDevice"
Identifier "Keyboard0"
Driver "kbd"
EndSection

Section "InputDevice"
Identifier "Mouse0"
Driver "mouse"
Option "Protocol" "auto"
Option "Device" "/dev/input/mice"
Option "ZAxisMapping" "4 5 6 7"
EndSection

Change /dev/fb1 to the device node that is created for you automatically by the Kernel when you plug in the USB monitor. Also, change the resolution “800x480” to the actual resolution you monitor has.

Now, in order to run two different Window Managers, we need to create 2 system users (the main user will have set “Unity” for the main monitor, and the second user will use “Fvwm” on the USB monitor). You cannot have both with just 1 user, we tried it and it does not work. Below, the main user is called “my_user1”, the second user “my_user2”. Create the user “my_user2” in the Settings dialog in Unity and set up a password. Of course, “my_user1” and “my_user2” are just examples, so make sure you use the real names in the configuration file below.

Next, change /etc/lightdm/lightdm.conf to enable Multi Seats:

\[SeatDefaults\]
autologin-guest=false
autologin-user-timeout=0
greeter-session=unity-greeter

\[Seat:0\]
autologin-user=my\_user1
user-session=ubuntu
autologin-session=ubuntu
xserver-command=/usr/bin/X :0 -auth /var/run/lightdm/root/:0 -nolisten tcp vt7 -novtswitch -sharevts

\[Seat:1\]
xserver-config=/root/displaylink.conf
autologin-user=my\_user2
user-session=Fvwm
autologin-session=Fvwm
xserver-command=/usr/bin/X :1 -auth /var/run/lightdm/root/:1 -nolisten tcp vt8 -novtswitch -sharevts

The keys autologin-session and user-session should, in theory (but only in theory) determine which Window Manager to start. The values “Fvwm” and “ubuntu” correspond to the .desktop files in the directory /usr/share/xsessions. Now, here is an explanation of why LightDM is so brittle. Thanks to long and painful reverse-engineering, I found out that the keys user-session and autologin-session are outright ignored when there are other ‘magic’ files present in the file system, which ‘cache’ these settings. The files in question are /var/cache/lightdm/dmrc/my_user1.dmrc and /home/my_user1/.dmrc where the contents are:

[Desktop]
Session=ubuntu

and the file /var/lib/AccountsService/users/my_user1 which has the content

[User]
XSession=ubuntu

Changing the values of user-session and autologin-session in lightdm.conf will be useless, since it seems that the values of ALL 3 files must match so that lightdm does not default to “Unity”. Once it defaults to “Unity”, it will add “ubuntu” into all of these 3 files. Since we want “my_user2” to use “Fvwm”, we have to add the string “Fvwm” to all of those 3 files AND lightdm.conf. If you now reboot, in theory, you should be auto-logged in in both X sessions, and you should have “Unity” on one screen and “Fvwm” on the USB monitor.

If you want to ‘autostart’ a few programs together with “Fvwm”, create a file /home/my_user2/.xsessionrc and make it chmod u+x. Add a few test programs:

#!/bin/bash
xterm &
xeyes &
chromium-browser &

Here is the proof that it worked for me:

If you need to configure screen blanking and keyboard/mouse, see sections below.

Debian GNU/Linux 7 (Wheezy) with gdm display manager

Since the Gnome Display Manager gdm does not support Multi Seat configuration in its newer versions, we have to start the second X server manually. Also, the new udl kernel driver is not yet active (as opposed to Ubuntu 12.10), so we don’t have to do the blacklisting as described in the previous section of this tutorial.

First, create /root/displaylink.conf with the exact same contents as posted in the previous section of this tutorial.

You can call X directly only as superuser, since it needs raw access to hardware. So, execute the following command as superuser to test:

startx -- :1 -layout displaylink -config /root/displaylink.conf -nolisten tcp vt8 -novtswitch -sharevts

This should start Gnome on the USB screen. Press Ctrl + C to quit X, since it does not detach to the background. To choose “Fvwm” as a faster and smaller Window Manager alternative, install Fvwm …

apt-get install fvwm

then add “fvwm” to the above command:

startx fvwm -- :1 -layout displaylink -config /root/displaylink.conf -nolisten tcp vt8 -novtswitch -sharevts

It is not very flexible or elegant to add the command “fvwm” directly into the X startup line. We will copy it to a file called /root/startupprograms.shinstead, so that we can add other startup programs later. Create this file and make it chmod u+x. I am going to use my USB screen as a fullscreen web terminal, so I also start Chromium in kiosk mode. My /root/startupprograms.sh looks like this:

#!/bin/sh
fvwm &
chromium-browser --user-data-dir=~/.chromium --window-size=800,480 --window-position=0,0 --kiosk --incognito http://example.com

Of course, the X startup command now becomes

startx /root/startupprograms.sh -- :1 -layout displaylink -config /root/displaylink.conf -nolisten tcp vt8 -novtswitch -sharevts

Now we need to add this command as a startup script called displaylink (or any other name) in /etc/init.d, so that we don’t have to run it manually, and that it will start during boot time:

cd /etc/init.d

Add the following to a file called displaylink:

#! /bin/sh

case "$1" in
start)
echo "Starting X server"
startx /root/startupprograms.sh -- :1 -layout displaylink -config /root/displaylink.conf -nolisten tcp vt8 -novtswitch -sharevts &
;;
stop)
echo "Cannot stop X server because I don't know the PID"
;;
*)
echo "Usage: /etc/init.d/displaylink {start|stop}"
exit 1
;;
esac

exit 0

This script must be executable:

chmod u+x displaylink

It must be symlinked to the Debian runlevel 2:

update-rc.d displaylink defaults

This creates a symlink in /etc/rc2.d/Sxxdisplaylink, where xx is a number automatically determined by update-rc.d.

Now if you reboot, you will get 2 working terminals: Gnome on the main monitor, and the fullscreen Chromium running on Fvwm on the USB monitor. Here is the proof:

Disabling mouse and keyboard for the USB Monitor

Your mouse and keyboard will be enabled for both screens, which is undesirable. Disable keyboard and mouse in the X configuration file we’ve created above, /root/displaylink.conf, by adding the following into the Section "ServerLayout":

Option "AutoEnableDevices" "false"
Option "AutoAddDevices" "false"
Option "AllowEmptyInput" "true"

To move the mouse cursor to the bottom right corner (so that it is barely visible), add to /root/startupprograms.sh after installing apt-get install xdotool:

xdotool mousemove 10000 10000

Before you start a browser that accesses a web application on localhost, you have to add a delay with sleep 10, otherwise Apache won’t be running yet at this point of time.

Prevent screen blanks

In a Point of Sale setting, blanking or turning off the screen is not welcome. To keep displays on, you can either use the Energy settings in your display manager, but on our test system, in Gnome3, the maximum on-period of the monitor is 1 hour, and it would blank the screen anyway. You may need to override this manually, for both monitors. To keep your USB monitor turned on always, add the following commands to our startup file /root/startupprograms.sh:

xset s off
xset -dpms
setterm -blank 0 -powersave off -powerdown 0

To keep your main monitor turned on with Gnome, create a file energysaveoff.sh in the home directory of your normal system user:

#!/bin/bash
xset s off
xset -dpms
setterm -blank 0 -powersave off -powerdown 0

Make this file executable with chmod a+x energysaveoff.sh. Then, add it as a Gnome startup program: In the Gnome Activities menu, enter “startup” as search term and start up this helper utility.

After you have rebooted, check in a terminal if the settings have been taken. Run xset q and check that DPMS is disabled.

If you found a mistake in this blog post, or would like to suggest an improvement to this blog post, please me an e-mail to michael@franzl.name; as subject please use the prefix "Comment to blog post" and append the post title.
 
Copyright © 2023 Michael Franzl