Multiseat in Ubuntu 9.04

Multiseat configuration in Ubuntu 9.04 is very similar to that of Ubuntu 8.04. Some software components have been updated, so the overall system has some improvements over the previous version, while other problems are still remaining.

The computer is just identical to that used in the previous version:
Pentium 4 at 3GHz, 512MB of RAM and a 80GB hard disk. The video card is an ATI Radeon X300 PCIe by Gigabyte with two outputs (VGA and DVI). On the DVI output we have a DVI to VGA converter so we can connect two simple VGA analog monitors. The monitors are just two generic TFT/LCD displays with a resolution of 1280x1024.

1.- We install the Ubuntu 9.04 version on the computer. You can do this using a live-media, such as a live-CD/live-DVD or a live-USB. Since most of the computers today support booting from USB, we recommend you to choose the USB option. The installation process will be much faster compared to installing from a CD/DVD.

2.- Update your system to the latest available packages. You can do that either using the graphical tools (update manager / synaptic) or using the command line in a terminal:

$ sudo apt-get update

3.- Install some additional components (xserver-xephyr and wmctrl). These are not included in the default installation, but they are in the official repositories. These packages are necessary in order to obtain the desired multiseat system.

$ sudo apt-get install xserver-xephyr wmctrl

Before starting any modifications related to the multiseat configuration, you should do the necessary adjustments and setup for your particular scenario (network configuration, user creation, etc). Some tools and applications related to Gnome configuration do not work when the user is logged in a multiseat session, because the operating system detect multiple gnome-sessions and some of the system configuration tools are not able to create the necessary locks.

It is very convenient to maintain a copy of the original configuration of the two files (/etc/X11/xorg.conf and /etc/gdm/gdm.conf) that are going to be modified, since they can be necessary if you want to come back to the initial configuration.

Once configured your network and created your users (we suggest you creating something like user1/user2, uleft/uright if you are going to have generic users) you can proceed with the process of multiseat setup.

Initially, after the default installation, the system will start with the two displays in "clone" mode.
If we have a look at the output of the xrandr command, we will see the details about our current setup. In our particular case, we obtain this output:

$ xrandr -q
Screen 0: minimum 320 x 200, current 1280 x 1024, maximum 1280 x 1200
VGA-0 connected 1280x1024+0+0 (normal left inverted right x axis y axis) 338mm x 270mm
1280x1024 60.0*+ 75.0 60.0*
1152x864 75.0
1024x768 75.0 60.0
832x624 74.6
800x600 75.0 60.3
640x480 75.0 59.9
720x400 70.1
DVI-0 connected 1280x1024+0+0 (normal left inverted right x axis y axis) 338mm x 270mm
1280x1024 60.0*+ 75.0 60.0*
1152x864 75.0
1024x768 75.0 70.1 60.0
832x624 74.6
800x600 72.2 75.0 60.3
640x480 75.0 72.8 59.9
720x400 70.1
S-video disconnected (normal left inverted right x axis y axis)

Next thing, we edit /etc/X11/xorg.conf to indicate how to obtain an "extended desktop" configuration. If you have any doubts on this topic, you can find additional information on the official Ubuntu wiki: manual multihead setup.

On recent Linux versions, several things related to device management are being changed and moved to other parts of the system, such as hal and udev, so we can see that there is no need to indicate anything related to keyboard and mouse in the xorg.conf file.

After having done a backup of the original xorg.conf file, we modify it in order to indicate the new setup with two monitors. We also include some convenient options (section "ServerFlags") in a multiseat system.

Section "Device"
Identifier "Card0"
BoardName "ATI Technologies Inc RV370 5B60 [Radeon X300 (PCIE)]"
Driver "ati"
BusID "PCI:1:0:0"
Option "Monitor-VGA-0" "Mon-VGA"
Option "Monitor-DVI-0" "Mon-DVI"

Section "Monitor"
Identifier "Mon-VGA"
Option "DPMS"

Section "Monitor"
Identifier "Mon-DVI"
Option "DPMS"
Option "Below" "Mon-VGA"

Section "Screen"
Identifier "Screen-base"
Device "Card0"
Monitor "Mon-VGA"
DefaultDepth 24
Subsection "Display"
Depth 24
Modes "1280x1024"
Virtual 1280 2048

Section "ServerFlags"
# Even if mouse detection fails, X will start
Option "AllowMouseOpenFail" "yes"

# VT switching is disabled
Option "DontVTSwitch" "yes"

# X restart (Ctrl+Alt+Backspace) is disabled
Option "DontZap" "yes"

Notice that this time, we have defined a vertical setup of the monitors. This is just to test if 3D acceleration works with horizontal and vertical dimensions of the virtual screen lower (or equal) than 2048 pixels. If you feel more comfortable with an horizontal setup, just use leftOf or rightOf instead of below, and change the virtual size to the proper one according to the desired layout.

After having done this change, if we restart the X server we will see a vertical desktop with these characteristics:

$ xrandr -q
Screen 0: minimum 320 x 200, current 1280 x 2048, maximum 1280 x 2048
VGA-0 connected 1280x1024+0+0 (normal left inverted right x axis y axis) 338mm x 270mm
1280x1024 60.0*+ 75.0 60.0*
1152x864 75.0
1024x768 75.0 60.0
832x624 74.6
800x600 75.0 60.3
640x480 75.0 59.9
720x400 70.1
DVI-0 connected 1280x1024+0+1024 (normal left inverted right x axis y axis) 338mm x 270mm
1280x1024 60.0*+ 75.0 60.0*
1152x864 75.0
1024x768 75.0 70.1 60.0
832x624 74.6
800x600 72.2 75.0 60.3
640x480 75.0 72.8 59.9
720x400 70.1
S-video disconnected (normal left inverted right x axis y axis)

Once we have modified the xorg.conf file and having already obtained a big desktop covering the two monitors (either with an horizontal or with a vertical layout), the next thing is to configure gdm to launch two Xephyr sessions, one for every seat.

Previously, you will need to obtain the information related to the input events on your system.

$ ls -la /dev/input/by-path/ | grep event | grep kbd
lrwxrwxrwx 1 root root 9 2009-06-18 13:11 pci-0000:00:1d.2-usb-0:2:1.0-event-kbd -> ../event5
lrwxrwxrwx 1 root root 9 2009-06-18 13:11 platform-i8042-serio-0-event-kbd -> ../event3

$ ls -la /dev/input/by-path/ | grep event | grep mouse
lrwxrwxrwx 1 root root 9 2009-06-18 13:11 pci-0000:00:1d.2-usb-0:1:1.0-event-mouse -> ../event4
lrwxrwxrwx 1 root root 9 2009-06-18 13:11 platform-i8042-serio-1-event-mouse -> ../event8

In this case, we have a set of PS2 keyboard + mouse for one seat, and a pair of USB keyboard + mouse for the second one. The values that you are obtaining here will be used to configure the corresponding input device for every seat.

The next step is to create a launcher in order to execute Xephyr with the proper parameters and input events. To achieve that, we create a file that will be used as a launcher script. You can name the file and place it as you consider most appropriated. We have chosen to create it as /usr/sbin/Xephyr-path.sh

Use your favorite editor (vi, gedit, ...) to create it, and do not forget to make it executable by root (the file owner).

$ sudo gedit /usr/sbin/Xephyr-path.sh
$ sudo chmod 744 /usr/sbin/Xephyr-path.sh

You should create a file with something like these contents (change the xkblayout parameter according to your language):

$ cat /usr/sbin/Xephyr-path.sh


# 200906 - josean
# http://netpatia.blogspot.com/

trap "" usr1



while [ ! -z "$1" ]; do
if [[ "$1" == "-kbdpath" ]]; then
if [ ! -z "$1" ]; then
args=("${args[@]}" "-keybd")
args=("${args[@]}" "evdev,,device=/dev/input/by-path/$1,xkbrules=xorg,xkbmodel=evdev,xkblayout=es")
elif [[ "$1" == "-mousepath" ]]; then
if [ ! -z "$1" ]; then
args=("${args[@]}" "-mouse")
args=("${args[@]}" "evdev,,device=/dev/input/by-path/$1")
args=("${args[@]}" "$1")
# echo "+++ args $1 +++" >> /tmp/logXephyr

# Next line is just to create a log file with the invocation parameters, for debug purposes
echo $XEPHYR "${args[@]}" >> /tmp/logXephyr
exec $XEPHYR "${args[@]}"

After the creation of this script, you can proceed with the modifications to the /etc/gdm/gdm.conf file.
On the [servers] section of gdm.conf, we comment out the rules corresponding to the original layout and define the new one. We modify the file to create the base X server and two Xephyr sessions (one for every seat) over the base X.

# ****************************************************************************


# 0=Standard
# Means that DISPLAY ":0" will start an X server as defined in the
# [server-Standard] section.

# ****************************************************************************

# Multiseat setup (200906)


command=/usr/bin/X -br -dpms -s 0

command=/usr/sbin/Xephyr-path.sh -br -screen 1280x1024 -kbdpath platform-i8042-serio-0-event-kbd -mousepath platform-i8042-serio-1-event-mouse

command=/usr/sbin/Xephyr-path.sh -br -screen 1280x1024 -kbdpath pci-0000:00:1d.2-usb-0:2:1.0-event-kbd -mousepath pci-0000:00:1d.2-usb-0:1:1.0-event-mouse

# ****************************************************************************

Notice that this is the script where you will have to indicate what the input devices (their physical connections) are for every seat.

The second change to the gdm.conf file is related to the greeter. There are still things that need to be done manually.

We encounter the already known problem of having every Xephyr window properly placed (one Xephyr session appearing on every display). The current Xephyr version does not support the geometry parameter that most X applications include, so it is not possible to place the Xephyr window in the desired place. In order to circumvent this problem, we create a script that will be called instead of doing a direct call to the session greeter. Such script invokes some command line tools in order to place every Xephyr window just in the place where we want to have it. We will use the following command line tools: xwininfo, wmctrl to move one of the Xephyr sessions to the second monitor, so that they do not overlap anymore. That is the reason why we installed the wmctrl package.

In the [daemon] section of gdm.conf change the reference to the original greeter for a reference to a new script. This script, apart for invoking the greeter, will place properly every Xephyr window:

# ****************************************************************************


# The greeter for attached (non-xdmcp) logins. Change gdmlogin to gdmgreeter
# to get the new graphical greeter.
# Greeter=/usr/lib/gdm/gdmgreeter

# ****************************************************************************

We will have to create the script responsible of the greeter/login (in our case, /usr/sbin/Xephyr-login.sh). This script will be executed by the gdm user, so we create a file owned by gdm and give execution permission just for that user.

$ sudo gedit /usr/sbin/Xephyr-login.sh
$ sudo chown gdm:gdm /usr/sbin/Xephyr-login.sh
$ sudo chmod 744 /usr/sbin/Xephyr-login.sh

After the creation of such script, it should look like this:

$ cat /usr/sbin/Xephyr-login.sh

# /usr/sbin/Xephyr-login.sh


XEP=$(XAUTHORITY=$XAUTH_BASE xwininfo -root -children -display :0 | grep "Xephyr on :1" --max-count=1)
echo ${XEP} >> /tmp/logXephyrLogin

# assign values to positional parameters to obtain the id (first parameter) of the Xephyr window
set ${XEP}
DISPLAY=$DISPL_BASE XAUTHORITY=$XAUTH_BASE wmctrl -i -r $1 -e 0,0,1024,-1,-1
# echo $1 >> /tmp/logXephyrLogin_1


In our case, we move one of the sessions 1024 pixels vertically (remember that our layout consists of two 1280x1024 displays vertically aligned).

As you can see, when the greeter is expected to be invoked, the wrapper script (including greeter invocation) is executed instead. The user(s) finally sees every greeter in a different display and the rest of the process is almost unnoticeable.

The last comment is about the greeter. The old style gdmlogin was some time ago replaced by a more modern gdmgreeter. There is something wrong about screen size detection with this default gdm greeter (gdmgreeter). It always try to start at a resolution of 1600x1200, so we had to change to the old greeter (gdmlogin) which detects properly the screen resolutions of the Xephyr sessions.

Maybe gdmgreeter uses xrandr to detect the resolution of every Xephyr session, since 1600x1200 is the max output reported by xrandr on every Xephyr session. The Xephyr windows are in fact resizable by means of xrandr, so we are not sure if this is a bug of xrandr that sould only report the current size, or a bug of gdmgreeter assuming that it must change the window size to the biggest available.

$ DISPLAY=:1 xrandr -q
Screen 0: minimum 160 x 160, current 1280 x 1024, maximum 1600 x 1200
default connected 1280x1024+0+0 (normal left inverted right x axis y axis) 0mm x 0mm
1600x1200 0.0
1400x1050 0.0
1280x960 0.0
1280x1024 0.0*
1152x864 0.0
1024x768 0.0
832x624 0.0
800x600 0.0
720x400 0.0
480x640 0.0
640x480 0.0
640x400 0.0
320x240 0.0
240x320 0.0
160x160 0.0

In order to avoid this problem, we use gdmlogin instead of gdmgreeter.

The Ubuntu 9.04 version of the multiseat setup, achieves some improvements over previous versions:
* Mouse wheel works properly.
* Keyboard led indicators are not messed up.

Resource: http://netpatia.blogspot.com

Related Links:

No comments: