This article describes a way to make a Multiterminal with Xnest. For other ways, see multiterminal.
There are modifications in Xnest that make possible to use it in order to implement a multiterminal system. The system is configured to run one X server controlling all video cards, and one Xnest for each screen, running above the main X server.
While normal Xnest receives events from its parent X server, multiXnest (modified Xnest) reads the input devices events directly from kernel event interface, bypassing the X.
Operating System required
Xnest is an X server that runs inside another X server. Xnest is both an X client and an X server, simultaneously. Xnest is a client of the real X server, but also a server to its own clients. Xnest is normally used to allow working on two or more desktops at the same time, however, we've made modifications in its code to make possible to use Xnest to implement a multiterminal system.
The system works in the following way. Only one "real" X server is run, configured to use several screens, each of which will be associated to one video card. After the X start-up, one Xnest is run inside each screen. Each user will use one Xnest, in a transparent way.
The original Xnest gets the input devices events from its parent X server. However, to allow Xnest to be used in the multiterminal, we had to modify its source code to make it read the events directly from kernel event interface, bypassing the X.
The great advantage of this approach is the possibility to make a multiterminal with any combination of video cards, as long as they are supported by the X.
Evdev and Udev
Make sure your kernel is compiled with evdev support.
Also install udev, which provides a dynamic /dev directory, updated according to the connected devices:
apt-get install udev
Udev requires a kernel 2.6.12 or later.
Now, you need to check if your input devices (mouses and keyboards) have been correctly detected by the kernel. In order to do this, analyze the file /proc/bus/input/devices, which show details about the input devices detected by the kernel.
An example of this file is shown below. Only two fields are of interest: the name of each device, shown in the lines starting with “N: Name=”, and the name of the file related to each device, shown in the lines starting with “H: Handlers”.
I: Bus=0011 Vendor=0001 Product=0001 Version=ab41 N: Name="AT Translated Set 2 keyboard" P: Phys=isa0060/serio0/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 H: Handlers=mouse0 event1 B: EV=7 B: KEY=70000 0 0 0 0 0 0 0 0 B: REL=103 I: Bus=0003 Vendor=0a81 Product=0101 Version=0110 N: Name="CHESEN USB Keyboard" P: Phys=usb-0000:00:10.2-1/input0 H: Handlers=kbd event2 B: EV=120003 B: KEY=10000 7 ff87207a c14057ff febeffdf ffefffff ffffffff fffffffe B: LED=7 I: Bus=0003 Vendor=0a81 Product=0101 Version=0110 N: Name="CHESEN USB Keyboard" P: Phys=usb-0000:00:10.2-1/input1 H: Handlers=kbd event3 B: EV=3 B: KEY=1f 0 20000 3878 d801d101 1e0000 0 0 0 I: Bus=0003 Vendor=04fc Product=0013 Version=06b0 N: Name="USB OpticalWheel Mouse" P: Phys=usb-0000:00:10.2-2/input0 H: Handlers=mouse1 event4 B: EV=7 B: KEY=70000 0 0 0 0 0 0 0 0 B: REL=103
Notice that the file seem to indicate the presence of 3 keyboards, although the system in question actually has only two. This happens because many USB keyboards have special keys (to control multimedia or access the internet, for instance), which are detected by the kernel as a secoundary keyboard, whose physical address finishes with “input1”. You need to configure only the primary keyboards, whose physical address finishes with “input0”.
The example given show the precense of 2 "primary" keyboards, related to the files /dev/input/event0 and /dev/input/event2, respectively, and 2 mouses, related to the files /dev/input/event1 and /dev/input/event4, respectively.
We'll describe the necessary steps to configure a multiterminal using Xorg, but it's possible to use XFree86, with few changes. To install XOrg, on Debian Sarge, do the following:
1. Make a backup and delete the file /etc/init.d/xfree-common. 2. Add the following lines to the file /etc/apt/sources.list:
deb http://people.debian.org/~nobse/xorg-x11/ sarge main deb-src http://people.debian.org/~nobse/xorg-x11/ sarge main
3. Install the xserver-xorg package:
apt-get update apt-get install xserver-xorg apt-get upgrade
Modified Xnest (multiXnest) download
1. Download the multiXnest binary (version 0.1.3) here. The binary should be put in the directory /usr/local/bin. You can download the patch to Xnest (from Xorg 6.8.2) here. 2. Download the wrapper script necessary to run Xnest: multiXnest.sh. The script must be coppied to /usr/sbin.
To configure a multiterminal with N terminals, edit the file /etc/X11/xorg.conf, and do the following:
1. Define a layout with N screen's.
Section "ServerLayout" Identifier "Layout" Screen "Default Screen 1" Screen "Default Screen 2" Below "Default Screen 1" Screen "Default Screen 3" Below "Default Screen 2" . . Screen "Default Screen N" Below "Default Screen N-1" InputDevice "Generic Keyboard 1" EndSection
2. Define one Device Section for each video card:
Section "Device" Identifier "Video Card 1" Driver "sis" BusID "PCI:0:5:0" Screen 0 EndSection # # Change the video card driver and the BusID according to you hardware. # # The BusID option identifies your video card. To obtain the BusIDs of your video cards, #use the command "lscpi | grep VGA". # Beware: the lscpi command shows address in hexadecimal, while X expects decimal numbers. #The command "echo $((0xHEX_NUMBER))" is your friend. . . . Section "Device" Identifier "Video Card N" Driver "sis" BusID "PCI:0:6:0" Screen 0 EndSection
3. Define the Monitor Sections.
Section "Monitor" Identifier "Monitor 1" HorizSync 30-71 VertRefresh 50-160 Option "DPMS" EndSection . . . Section "Monitor" Identifier "Monitor N" HorizSync 30-71 VertRefresh 50-160 Option "DPMS" EndSection
4. Define the Screen Sections
Section "Screen" Identifier "Screen 1" Device "Video Card 1" Monitor "Monitor 1" DefaultDepth 24 SubSection "Display" Depth 24 Modes "1024x768" "800x600" "640x480" EndSubSection EndSection . . . Section "Screen" Identifier "Screen N" Device "Video Card N" Monitor "Monitor N" DefaultDepth 24 SubSection "Display" Depth 24 Modes "1024x768" "800x600" "640x480" EndSubSection EndSection
5. Xorg.conf should have only one keyboard section, like this:
Section "InputDevice" Identifier "Keyboard0" Driver "kbd" EndSection
The mouse section can be deleted, which is recommended, but you must add the AllowMouseOpenFail option to the ServerFlags Section, as shown below, otherwise the X server will fail to start.
6. Make sure the ServerFlags section has the following options:
Section "ServerFlags" ... # These options keep the X Server from entering in power saving mode: Option "BlankTime" "0" Option "StandbyTime" "0" Option "SuspendTime" "0" Option "OffTime" "0" # Allow the server to start without mouse Option "AllowMouseOpenFail" "yes" # Disable VT Switching Option "DontVTSwitch" "yes" # This disallows the use of the Ctrl+Alt+Backspace sequence Option "DontZap" "yes" ... EndSection
Now it's necessary to create an XKB configuration file for each multiXnest. The XKB configuration for the first multiXnest should be placed in the file /usr/X11R6/lib/X11/xkb/X1-config.keyboard, for the second multiXnest in /usr/X11R6/lib/X11/xkb/X2-config.keyboard, and so on. You can see an example of an XKB configuration file below.
rules = "xorg" model = "pc105" layout = "us"
The last step is to configure the login manager to start the main X server and also to run the wrapper scripts that will open Xnest. We'll explain how to do his on GDM, but other managers, like XDM and KDM, can be configured in a similar way.
Edit the file /etc/X11/gdm.conf in the servers section, adding the following:
[servers] 0=Hardware # Hardware is the main X server 1=multiXnest1 2=multiXnest2 3=multiXnest3 . . N=multiXnestN [server-Hardware] name=Hardware command=/usr/X11R6/bin/X handled=false flexible=false [server-multiXnest1] name=multiXnest1 command=/usr/sbin/multiXnest.sh -display :0.0 -xauthority /var/lib/gdm/:0.Xauth -geometry 1024x768+0+0 -kbd /dev/input/event0 -ptr /dev/input/event1 -dpi 92 handled=true flexible=false # # The options -kbd and -ptr identify, respectively, to which keyboard and which mouse the Xnest will be associated. # # multiXnest.sh is the wrapper that runs Xnest server. . . . [server-XnestN] name=XnestN command=/usr/sbin/multiXnest -display :0.N -xauthority /var/lib/gdm/:0.Xauth -geometry 1024x768+0+0 -kbd /dev/input/eventXX -ptr /dev/input/eventYY -dpi 92 handled=true flexible=false