Multistation
Пока это только черновик
Введение
Первая проблема с которой я столкнулся, разыскивая информацию по этой теме - это терминология. Multiseat, multistation, multiterminal - всё это термины, обозначающие рабочую станцию, предназначенную для одновременного использования несколькими пользователями (также multihead workstation). Естественно, для каждого пользователя необходимы персональные монитор, клавиатура и мышь. Соответственно, должна быть возможность подключить всё это к мультистанции, тоесть нужное количество видеовыходов на видеокарте(видеокартах) и USB либо PS/2 входов для клавиатур и мышей. Ниже описывается настройка мультистанции для двух рабочих мест.
Оборудование и ПО
Hardware
- некая рабочая станция
- двуголовый (dualhead) видеоадаптер Nvidia GeForce FX 5500
- монитор Sony,
- монитор Nec,
- клавиатура белая PS/2,
- клавиатура чёрная USB,
- мышь черная PS/2
- мышь черная с полоской USB.
Software
- ALT Linux branch 4.0.
Постановка задачи и проблемы
Наша задача — получить на каждом мониторе отдельный X-сервер со своими клавиатурой и мышью. Основная проблема заключалась в том, что это достаточно просто на двух разных видеокартах и вероятно невозможно (судя по некоторым почтовым рассылкам) на двуголовой видеокарте. После продолжительного гугления удалось найти замечательное руководство именно на эту тему, где был предложен вариант решения проблемы с помощью компонента Xorg под названием Xephyr из пакета xorg-x11-xephyr. Что такое Xephyr? Xephyr представляет из себя полноценный X-сервер, который выполняется поверх другого X-сервера. Он создан для тестов и отладки графических программ, однако он как нельзя лучше подойдёт для нашей задачи. То есть запускать мы будем всё же один X-сервер, а поверх него уже X-сервера для каждого рабочего места. Вторая проблема - отсутствие поддержки evdev в Xephyr - решается с помошью этогопатча
Установим драйверы
Для начала установим нужные драйверы. Для GeForce FX 5500 подойдёт legacy-драйвер версии 9639. К сожалению, на момент написания статьи в branch4 их ещё не было. Поэтому подключаем apt-репозторий сизифа или качаем вручную с ftp.altlinux.org и устанавливаем:
apt-get install kernel-modules-nvidia_legacy_96xx-std-smp nvidia_glx_legacy_96xx_1.0.9639 nvidia_glx_common
Настройка Xorg
Тут наша задача увидеть работающий X-сервер на обоих мониторах одновременно. Для начала конфигурируем мониторы. Монитор Sony был сконфигурирован инсталлятором дистрибутива автоматически. Я добавил второй монитор - LG:
Section "Monitor" Identifier "Sony CPD-210GS/210EST/T9|0" DisplaySize 330 240 HorizSync 30.0 - 70.0 VertRefresh 48.0 - 120.0 EndSection Section "Monitor" Identifier "LG" Option "DPMS" "true" EndSection
Теперь добавим конфигурацию для нашей видеокарты. Для этого создаётся две одинаковые секции device в xorg.conf но с разными параметрами Screen, означающими разные "головы" видеокарты:
Section "Device" Identifier "GeForce out 1" Driver "nvidia" BusID "AGP:1:0:0" Option "RenderAccel" "true" Screen 0 Option "NoLogo" EndSection Section "Device" Identifier "GeForce out 2" Driver "nvidia" BusID "AGP:1:0:0" Option "RenderAccel" "true" Screen 1 Option "NoLogo" EndSection
Создадим две секции Layout. Одну для "одноголовой" конфигурации и вторую для "двуголовой". Различаются эти секции только параметрами Screen.
Section "ServerLayout" Identifier "dualhead" InputDevice "Keyboard0" "CoreKeyboard" InputDevice "PS/2 mouse" "CorePointer" Screen 0 "RightScreen" 0 0 Screen 1 "LeftScreen" LeftOf "RightScreen" EndSection Section "ServerLayout" Identifier "onehead" InputDevice "Keyboard0" "CoreKeyboard" InputDevice "PS/2 mouse" "CorePointer" EndSection
Так же понадобится отключит сочетание клавиш ctrl+alt+backspace, убивающее X-сервер, в секции ServerFlags:
Section "ServerFlags" Option "AllowMouseOpenFail" "yes" Option "DontVTSwitch" "yes" Option "DontZap" "yes" EndSection
В целом, мой xorg.conf выглядит вот так:
Section "ServerLayout" Identifier "dualhead" InputDevice "Keyboard0" "CoreKeyboard" InputDevice "PS/2 mouse" "CorePointer" Screen 0 "RightScreen" 0 0 Screen 1 "LeftScreen" LeftOf "RightScreen" EndSection Section "ServerLayout" Identifier "onehead" InputDevice "Keyboard0" "CoreKeyboard" InputDevice "PS/2 mouse" "CorePointer" EndSection Section "Module" Load "type1" Load "freetype" Load "glx" # Load "dri" Load "dbe" Load "ddc" SubSection "extmod" Option "omit xfree86-dga" EndSubSection EndSection Section "InputDevice" Identifier "Keyboard0" Driver "kbd" EndSection Section "InputDevice" Identifier "PS/2 mouse" Driver "mouse" Option "Device" "/dev/input/mice" Option "Protocol" "IMPS/2" Option "ZAxisMapping" "4 5" EndSection Section "Monitor" Identifier "Sony CPD-210GS/210EST/T9|0" DisplaySize 330 240 HorizSync 30.0 - 70.0 VertRefresh 48.0 - 120.0 EndSection Section "Monitor" Identifier "LG" Option "DPMS" "true" EndSection Section "Device" Identifier "GeForce out 1" Driver "nvidia" BusID "AGP:1:0:0" Option "RenderAccel" "true" Screen 0 Option "NoLogo" EndSection Section "Device" Identifier "GeForce out 2" Driver "nvidia" BusID "AGP:1:0:0" Option "RenderAccel" "true" Screen 1 Option "NoLogo" EndSection Section "Screen" Identifier "RightScreen" Device "GeForce out 1" Monitor "Sony CPD-210GS/210EST/T9|0" DefaultDepth 24 SubSection "Display" Depth 24 Modes "1024x768" "832x624" "800x600" "720x400" "640x480" EndSubSection EndSection Section "Screen" Identifier "LeftScreen" Device "GeForce out 2" Monitor "LG" DefaultDepth 24 SubSection "Display" Depth 24 Modes "1024x768" "832x624" "800x600" "720x400" "640x480" EndSubSection EndSection Section "ServerFlags" Option "AllowMouseOpenFail" "yes" Option "DontVTSwitch" "yes" Option "DontZap" "yes" EndSection
Запустите X и убедитесь что оба ваших монитора работают:
startx -- -layout dualhead
Если вы не увидели работающего X-сервера читайте логи и исправляйте xorg.conf
Далее нам бы установить Xephyr, но в текущей его версии отсутствует поддержка evdev. Нам без evdev никак, по этому вам надо либо самостоятельно пропатчить xorg-x11-server, либо взять уже пропатчиную версию здес ь. Надеюсь исправления скоро попадут в дистрибутив и установка станет проще.
apt-get install xorg-x11-server xorg-x11-xephyr
Ещё раз проверьте, что всё у вас запускается и можно двигаться дальше. Итак, с мониторами разобрались, теперь разберёмся с клавиатурами и мышами.
Смотрим, как у нас обстоят дела с устройствами:
# 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
Следующая проблема, которую необходимо решить, состоит в том, что после перезагрузки сменится event id. Для этого в файле /usr/sbin/Xephyr.sh разместим скрипт-обёртку для xephyr:
#!/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[@]}"
Поскольку device id не меняется после перезагрузок, этот скрипт связывает event id и нужную нам клавиатуру или мышь.
Так же этот скрипт-обёртку можно установить из репозитория Sisyphus:
apt-get install multistation-scripts
Так же установите скрипт для более удобного запуска xephyr c evdev и конфиг для kdm (либо для gdm, если используете его)
multistation-scripts kdm-multistation-config (либо gdm-multistation-config)
и найдите нужные значения Phys для ваших устройств. В соответствии с ними выставите параметры -kbdphys и -mousephys в файле ...
Прописать display manager в /etc/sysconfig/desktop : для gdm -- GNOME, для kdm -- KDE.
Перезапустите X. Всё готово.
Ссылки
1. Альтернативный вариант с запуском Xgl вместо Xephyr http://research.edm.uhasselt.be/~jori/page/index.php?n=Misc.DualSeatX
Dual-seat X on a dual-head graphics card using Xgl 1. Introduction This document describes how you can use a dual-head graphics card to create a dual-seat X configuration. The approach is very general and can easily be extended to more seats, creating a multi-seat X configuration. The dual-seat configuration is created by starting a 'master' X server which initializes the two monitors connected to the video card. On each screen, an Xgl server is then started and using a separate program, events from keyboards and mice are redirected to the appropriate Xgl servers. 2. Disclaimer This document is distributed in the hope that it will be useful, but without any warranty. The information in this document is correct to the best of my knowledge, but there's a always a chance I've made some mistakes, so don't follow everything too blindly, especially if it seems wrong. Nothing here should have a detrimental effect on your computer, but just in case I take no responsibility for any damages incurred from the use of the information contained herein. 3. Configuring the 'master' X server Here are some sections from my own xorg.conf file, illustrating how two monitors can be controlled by the main X server. Adjust where needed. I've defined two monitor sections: Section "Monitor" Identifier "My Monitor0" HorizSync 31.5 - 64.3 VertRefresh 40-65 EndSection Section "Monitor" Identifier "My Monitor1" HorizSync 31.5 - 64.3 VertRefresh 40-65 EndSection Two devices, corresponding to the two outputs of my video card: Section "Device" Identifier "nvidia0" Driver "nvidia" BusID "PCI:01:00:0" Screen 0 Option "UseDisplayDevice" "CRT-1" Option "RenderAccel" "true" EndSection Section "Device" Identifier "nvidia1" Driver "nvidia" BusID "PCI:01:00:0" Screen 1 Option "UseDisplayDevice" "CRT-0" Option "RenderAccel" "true" EndSection Two screens, each one connecting a device to a monitor: Section "Screen" Identifier "Screen0" Device "nvidia0" Monitor "My Monitor0" DefaultDepth 24 Subsection "Display" Depth 24 Modes "1280x1024" ViewPort 0 0 EndSubsection EndSection Section "Screen" Identifier "Screen1" Device "nvidia1" Monitor "My Monitor1" DefaultDepth 24 Subsection "Display" Depth 24 Modes "1280x1024" ViewPort 0 0 EndSubsection EndSection Finally, the server layout tells the X server to actually use both screens. Section "ServerLayout" Identifier "Layout1" Screen 0 "Screen0" Screen 1 "Screen1" rightOf "Screen0" InputDevice "Keyboard1" "CoreKeyboard" InputDevice "Mouse1" "CorePointer" EndSection 4. Helper programs 4.1 XglScript.sh You may have to adjust some settings in the script to reflect your own configuration. Note that if you don't copy the XglScript.sh file in /usr/local/sbin, you'll have to adjust the 'command' lines in the gdm.conf settings below. 4.2 XevdevScript.sh Here too, you may have to adjust some settings at the top of the script. The gdm.conf settings below assume that this script is installed in the directory /usr/local/sbin. 4.3 The 'startsched' program This allows you to start a program with a higher priority. Something like the 'nice' program, but with real-time priorities. I've found it helpful to start 'xevdevserver' with a real-time priority, to make sure that input events are handled right away. The XglScript.sh and XevdevScript.sh files look in /usr/local/sbin/ for this program, unless you modify the scripts. To compile the program, simply type: gcc -o startsched startsched.c 4.4 XevdevServer This program can capture a keyboard and mouse, and redirect the events to a specified X display. Compile xevdevserver and copy the executable to any location you like. I've installed mine in /usr/local/sbin and this is the default location in the XglScript.sh and XevdevScript.sh files. You'll need xevdevserver-1.3.0 for the scripts to work. 5. GDM configuration 5.1 First approach In this approach, the main X server is started first. Then, when each Xgl server is started, an xevdevserver instance is started at the same time. In the [daemon] section, set: AlwaysRestartServer=true For the servers you'll have to do something like this: [servers] 0=MainServer 1=Xgl1 2=Xgl2 [server-MainServer] name=MainServer command=/usr/X11R6/bin/Xorg handled=false flexible=false [server-Xgl1] name=Xgl1 command=/usr/local/sbin/XglScript.sh -display :0.1 -keyboard /dev/input/event4 -mouse /dev/input/event1 -dpi 86 -fullscreen -ac -accel glx:pbuffer -accel xv:pbuffer -xkbmap be -softcursor handled=true flexible=false [server-Xgl2] name=Xgl2 command=/usr/local/sbin/XglScript.sh -display :0.0 -keyboard /dev/input/event2 -mouse /dev/input/event0 -dpi 86 -fullscreen -ac -accel glx:pbuffer -accel xv:pbuffer -xkbmap be handled=true flexible=false 5.2 Second approach In this second approach, all the required xevdevserver instances are started even before the actual main X server is started. These xevdevserver instances keep trying to connect to their Xgl servers, so shortly after an Xgl server has been started, it will receive the input from the corresponding xevdevserver. In the [daemon] section, set: AlwaysRestartServer=true For the servers you'll have to do something like this: [servers] 0=MainServer 1=Xgl1 2=Xgl2 [server-MainServer] name=MainServer command=/usr/local/sbin/XevdevScript.sh -xevdev ":1,/dev/input/event4,/dev/input/event1" -xevdev ":2,/dev/input/event2,/dev/input/event0" handled=false flexible=false [server-Xgl1] name=Xgl1 command=/usr/local/sbin/XglScript.sh -display :0.1 -dpi 86 -fullscreen -ac -accel glx:pbuffer -accel xv:pbuffer -xkbmap be -softcursor handled=true flexible=false [server-Xgl2] name=Xgl2 command=/usr/local/sbin/XglScript.sh -display :0.0 -dpi 86 -fullscreen -ac -accel glx:pbuffer -accel xv:pbuffer -xkbmap be handled=true flexible=false The script XevdevScript.sh accepts parameters like -xevdev ":1,/dev/input/event4,/dev/input/event1" This means that an xevdevserver will be started, redirecting input events from the keyboard device /dev/input/event4 and mouse device /dev/input/event1 to the Xgl display :1 5.3 General remarks Make sure you adjust the input devices and your keyboard map. Instead of using identifiers like /dev/input/event0, you can also use other identifiers listed in /proc/bus/input/devices. For example, for an entry like I: Bus=0003 Vendor=045e Product=0040 Version=0300 N: Name="Microsoft Microsoft 3-Button Mouse with IntelliEye(TM)" P: Phys=usb-0000:00:03.0-1/input0 S: Sysfs=/class/input/input0 H: Handlers=mouse0 event0 B: EV=7 B: KEY=70000 0 0 0 0 0 0 0 0 B: REL=103 you can use -mouse usb-0000:00:03.0-1/input0 or even -mouse "Microsoft Microsoft 3-Button Mouse with IntelliEye(TM)" and something similar for '-xevdev' arguments. The script XglScript.sh will translate such identifiers to an appropriate device name like /dev/input/event0. Be careful when using the 'Name' identifier as this might not be unique. Unfortunately only one of the monitors connected to a single card can use the hardware cursor, which is why the software cursor has been enabled in one of the Xgl instances. I'm not sure which 'accel' options are best, you can always take a look at http://www.freedesktop.org/wiki/Software_2fXgl for some other settings.