Friday, September 08, 2006

Multiseat (IV): evdev and Xephyr

(...comes from step III)




What is evdev?


evdev is the generic input event device driver. It passes the events generated in the kernel (since version 2.6.8) straight to the program, with timestamps.

The evdev driver is able to separate and distinguish events coming from different keyboards and mouses plugged into the computer. The xorg supports evdev input driver module since version 6.9/7.0 . This way, it can get separated input events coming from every seat (keyboard and mouse pair) on the system.


This is a great step compared to previous multiseat solutions, since it makes possible to have multiterminal systems without having to patch neither the kernel nor the X server.

What is Xephyr?

Xephyr is a kdrive based X Server which targets a window on a host X Server as its framebuffer. In other words, it is a piece of software which creates a X server on top of another X server. That will allow us to run as many Xephyr instances as seats we have in our system. Every Xephyr instance will cover the area shown in a given display, and finally, evdev will allow us to separate the different input devices.

The good news

Xephyr is included in the universe repository from Ubuntu.

The bad news

The Xephyr version included in the Ubuntu repository, does not support evdev. I hope in a near future Xephyr comes with evdev upport.

Right now, you will have either to patch the Xephyr sources and compile it, or download an already patched solution. Download links for both solutions are available here.

# wget http://www.c3sl.ufpr.br/multiterminal/howtos/xephyr-precompiled.tar.bz2
# tar -xjf xephyr-precompiled.tar.bz2 --directory /usr/local/

Now it is time to plug your second set of keyboard and mouse. The evdev driver will access the input coming from every device by means of a given event in the form of /dev/input/eventNN. You must obtain the event id associated to every input device.

A new problem arises, since the event number assigned can change (in fact, it changes) between different boots. To solve this problem we well use a wrapper script. The script is the same as proposed here, but modified in order to obtain the event number given the physical connection of the device. We are assuming that the devices will be always plugged in the same position (you can label the back connectors to remember the correct position). Since the physical device addresses do not change between boots, the script can obtain the corresponding event id and match it properly with one physical keyboard or mouse.

Input devices and events, once plugged the second keyboard and mouse:

# cat /proc/bus/input/devices
I: Bus=0011 Vendor=0001 Product=0001 Version=ab41
N: Name="AT Translated Set 2 keyboard"
P: Phys=isa0060/serio0/input0
S: Sysfs=/class/input/input0
H: Handlers=kbd event0
B: EV=120013
B: KEY=4 2000000 3802078 f840d001 f2ffffdf ffefffff ffffffff fffffffe
B: MSC=10
B: LED=7

I: Bus=0011 Vendor=0002 Product=0005 Version=0000
N: Name="ImPS/2 Generic Wheel Mouse"
P: Phys=isa0060/serio1/input0
S: Sysfs=/class/input/input1
H: Handlers=mouse0 event1 ts0
B: EV=7
B: KEY=70000 0 0 0 0 0 0 0 0
B: REL=103

I: Bus=0010 Vendor=001f Product=0001 Version=0100
N: Name="PC Speaker"
P: Phys=isa0061/input0
S: Sysfs=/class/input/input2
H: Handlers=kbd event2
B: EV=40001
B: SND=6

I: Bus=0003 Vendor=0d62 Product=001c Version=0202
N: Name="Darfon USB Combo Keyboard"
P: Phys=usb-0000:00:1d.1-1/input0
S: Sysfs=/class/input/input5
H: Handlers=kbd event4
B: EV=120003
B: KEY=10000 7 ff87207a c14057ff febeffdf ffefffff ffffffff fffffffe
B: LED=7

I: Bus=0003 Vendor=0d62 Product=001c Version=0202
N: Name="Darfon USB Combo Keyboard"
P: Phys=usb-0000:00:1d.1-1/input1
S: Sysfs=/class/input/input6
H: Handlers=kbd event5
B: EV=3
B: KEY=3078 d801d101 1e0000 0 0 0

I: Bus=0003 Vendor=046d Product=c03f Version=2000
N: Name="Logitech USB-PS/2 Optical Mouse"
P: Phys=usb-0000:00:1d.1-2/input0
S: Sysfs=/class/input/input8
H: Handlers=mouse1 event3 ts1
B: EV=7
B: KEY=f0000 0 0 0 0 0 0 0 0
B: REL=103


The Name section will help us to identify the device. The Phys section is the parameter that we will send to the wrapper script in order to start every Xephyr instance.

The Xephyr wrapper

Now, it is time to create the wrapper script. The original one is modified to obtain the event numbers from the physical addresses

# vi /usr/sbin/Xephyr.sh


This is the final wrapper script:

#!/bin/bash

# 20060905 - josean - added get_event() function to obtain eventNN from a physical address
# Original version:
# http://en.wikibooks.org/wiki/Multiterminal_with_Xephyr
# http://www.c3sl.ufpr.br/multiterminal/howtos/Xephyr.sh

trap "" usr1

XEPHYR=/usr/local/bin/Xephyr

get_event()
{
evento=`grep -A2 $1 /proc/bus/input/devices | grep 'H: Handlers=' | grep --only-matching -e 'event[0-9]*'`
}

args=()

while [ ! -z "$1" ]; do
if [[ "$1" == "-xauthority" ]]; then
shift
if [ ! -z "$1" ]; then
export XAUTHORITY="$1"
fi
elif [[ "$1" == "-display" ]]; then
shift
if [ ! -z "$1" ]; then
export DISPLAY="$1"
fi
elif [[ "$1" == "-kbdphys" ]]; then
shift
if [ ! -z "$1" ]; then
get_event $1
args=("${args[@]}" "-keyboard")
args=("${args[@]}" "/dev/input/$evento")
fi
elif [[ "$1" == "-mousephys" ]]; then
shift
if [ ! -z "$1" ]; then
get_event $1
args=("${args[@]}" "-mouse")
args=("${args[@]}" "/dev/input/$evento,5")
fi
else
if ! expr match $1 'vt[0-9][0-9]*' >/dev/null; then
args=("${args[@]}" "$1")
fi
fi

shift
done

# echo $XEPHYR "${args[@]}" >> /tmp/logXephyr

exec $XEPHYR "${args[@]}"


Finally, be sure to allow the script to be executed.

# chmod +x /usr/sbin/Xephyr.sh


(continues on step V...)

22 comments:

josean said...

Some minor updates have been made today in order to give a bit more details on these steps.

Anonymous said...

Thanks for that very nice tutorial!

But I can't download that modified precompiled Xephyr :(
www.c3sl.ufpr.br can't be reached...

could you upload this file somewhere else or mail it to me?
ns AT vivid-planet.com

thanks
niko

Anonymous said...

The server at www.c3sl.ufpr.br seems to be down or unreachable sometimes. Now it is working and the files can be downloaded.

Niko said...

ah, its working again :D :D

Anonymous said...

I like your article. I have a single card (nvidia) with dual output (VGA & DVI) - like your picture. The only problem I have is the Xephyr. It doesn't take the -kbdphys option. I can't get different keypads or mice to map to the screen. Is there a different switch or option?

josean said...

Xephyr does not support such parameters. It is the wrapper script (Xephyr.sh) who uses those values to assign the correct input devices to each terminal

Anonymous said...

I'm having problems with Xephyr. I'm using the precompiled version. The keyboard mapping is wrong, so all of the keyboard values are wrong (making it very hard to login or do anything). I get this message in the log:

Couldn't load XKB keymap, falling back to pre-XKB keymap.

using setxkbmap - the model is set to pc101. I think pc105 will change it, but I can't get there. I tried using the X1-config.keyboard file, but it didn't work. Do you know where it's looking? I've tried changing xorg.conf also and nothing seems to work. Do I have to build Xephyr myself?

Mike said...

Hi,

I always get this error message when I start Xephyr:

Fatal server error:
could not open default font 'fixed'

Any idea how this comes and how it could be fixed? Is there a way to specify other font than "fixed" ?

Thanks in advance!

Mike

josean said...

There is another interesting approach using xglx instead of xephyr. You can read about it here

Anonymous said...

Josean, server ww.c3sl.ufpr.br is down...
could you mail precompiled Xephyr to me? mita(at)inbox.ru
Thank you

Community Research Connections said...

There's other bad news, for me at least. This method got the multiseat going (with an ATI Radeon 9250 video card), but it's not very stable. X regularly restarts without warning, with only the following message in /var/log/syslog:

ubuntu gconfd (lwaldron-5494): Received signal 15, shutting down cleanly

This may have something to do with the fact Xephyr has been inactive since Nov. 2004. Additionally, certain applications (like R) can no longer find any fonts, and suspend doesn't work anymore. I am going to try again using x.org's built-in multihead support with xinerama... keeping my fingers crossed.

Anonymous said...

I also had the XKB keyboard mapping problem. Xephyr was compile to look in a certain location to find the files it needs. I added some sym links and stuff, so it works for me now. Here's what I did:

> ln –s /usr/share/X11/xkb /usr/lib/X11/xkb
> cp `which xkbcomp` /usr/lib/X11/xkb
> mkdir /usr/lib/X11/xkb/compiled
> rm –R /usr/lib/X11/fonts/encodings
> ln –s /usr/share/fonts/X11/misc /usr/lib/X11/fonts/misc
> ln –s /usr/share/fonts/X11/75dpi /usr/lib/X11/fonts/75dpi
> ln –s /usr/share/fonts/X11/100dpi /usr/lib/X11/fonts/100dpi
> ln –s /usr/share/fonts/X11/Type1 /usr/lib/X11/fonts/Type1
> ln –s /usr/share/fonts/X11/encodings /usr/lib/X11/fonts/encodings

Frederik said...

Hello,

I want to make a Six-user multiseat. Everything works perfect to 5 user (5 seats), but the 6 seats doesn't work. It gives a Xepher fault.

How many screens can one xorg make ?
How many Xepher versions can be run ?

Can that doesn't work with more than 5 seats ?

Anonymous said...

hello,i try to exec Xephyr in a gentoo system...i interesting in the -geometry parameter....i see (with a revdep-rebuild) the problem with libraries , the startx don´t exec, I'm no be able to re emerge por example xf86-video-i810, etc...if I delete the extract folder...all it's right.I try to extract the tar.gz in a temporal folder (/tmp/test/) and revdep-rebuild finish correctly, the startx execs correctly and i dont have problem with emerge xf86-video-intel....there is some reason for extrac the precompiled-xephyr in /usr/local/ ?? ¿It is a better solution to install precompiled xephyr at /usr/local/ and then remake the necesary links?

thanks

aneolf said...

The repository link is broken. Could you say me if are there anyone else, or if are there any other newer method to install a multiseat system in the computer?

aneolf said...
This comment has been removed by the author.
aneolf said...

¡Vaya! Parece que hablas castellano, jeje ;-) Entonces es posible que nos entendamos algo mejor.

He intentado seguir todos los pasos del tutorial para instalar dos monitores con sus respectivos teclado y ratón, pero cuando llego al paso de descargarme el paquete xephyr del repositorio, no lo encuentra y me descarga la página principal. ¿Funcionaria igual con el paquete xserver-xephyr de los repositorios de Lenny?
Perdona mi comentario anterior. Mi inglés es muy pobre.

josean said...

Te recomiendo que pruebes con una versión más actualizada de este artículo: Multiseat en Ubuntu 8.04

Ahí ya no hay dependencias externas y todo lo que necesitas está en los repositorios oficiales de la versión en cuestión.

aneolf said...

Vaya. No había visto que había una versión más nueva sobre lo mismo. En fin, tendré que volver a traducir todo el post para no pasarme nada.

Muchas gracias por todo.

Денис Радченко said...

Also precompiled Xephyr you can download from http://home.doomer.ru/files/xephyr-precompiled.tar.bz2

Anonymous said...

xephyr-precompiled.tar.bz2

http://massmirror.com/4c540e5d269b1755ae086be31a06dfb9.html

Samir (Equipe Multiterminal IFCE Maracanaú) said...

http://www.2shared.com/file/5251338/63f43c36/xephyr-precompiledtar.html