Multistation

Материал из ALT Linux Wiki
Freesource-logo.png Blue Glass Arrow.svg MediaWiki logo.png
Эта страница была перемещена с freesource.info.
Эта страница наверняка требует чистки и улучшения — смело правьте разметку и ссылки.
Просьба по окончанию убрать этот шаблон со страницы.


Пока это только черновик

Введение

Первая проблема с которой я столкнулся, разыскивая информацию по этой теме - это терминология. 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
Внимание: на момент написания статьи планировалось совместить текущие драйверы и legacy-драйверы в одном пакете: будьте внимательны, названия пакетов могут измениться

Настройка 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.
  • страница ссылок MultiHead
  • Ещё один вариант настройки DualSeat

Ссылки