Multiterminais/Multiterminal com Xnest

Vamos descrever aqui como fazer um Multiterminal com Xnest. Há muitas maneiras de se fazer multiterminais, pra vê-las, veja a seção Veja também.

A partir de uma modificação realizada no programa Xnest, foi possível implementar uma nova solução para multiterminal. Como o sistema utiliza apenas um servidor X, que controla todas as placas de vídeo, a solução funciona com diversas combinações de placas de vídeo.

Como fazer editar

Sistema operacional editar

Debian Sarge

Introdução editar

O Xnest é, basicamente, um servidor X que roda dentro de outro servidor X. O Xnest é um programa que é cliente e servidor, ao mesmo tempo. Ele é cliente do servidor X verdadeiro, mas é também servidor para outros aplicativos, que enxergam o Xnest como se fosse um servidor X normal. O Xnest normalmente é utilizado para se trabalhar em dois ou mais desktops simultaneamente, no entanto, fizemos alterações em seu código para permitir que ele seja utilizado para implementar um sistema multiterminal.

O sistema opera da seguinte maneira. Roda-se apenas um servidor X, configurado para utilizar várias telas (screens), sendo que cada tela estará associada a uma placa de vídeo. Após a inicialização do X, abre-se, em tela cheia, um Xnest para cada tela, o qual será utilizado pelo usuário, de maneira transparente.

O Xnest original obtêm os eventos de mouse e teclado a partir do seu servidor X pai. No entanto, para permitir a utilização do Xnest no multiterminal, tivemos que alterar seu código fonte para que ele lêsse os eventos diretamente dos dispositivos, sem intermediação do servidor X. Para ler os eventos do mouse e do teclado utiliza-se o protocolo evdev.

A grande vantagem do multiXnest (nossa proposta de multiterminal com o Xnest modificado) é que o gerenciamento das diversas placas de vídeo é feito por um único X, o que elimina os problemas de compatibilidade e conflitos presentes nas outras maneiras de implementar o multiterminal. Isso significa que o multiterminal funciona com qualquer combinação de placas de vídeo que o X consiga gerenciar.

Evdev e Udev editar

Certifique-se de que seu kernel (núcleo do sistema) esteja compilado com suporte ao módulo evdev.

É necessária também a instalação do udev, que provê um diretório /dev dinâmico e atualizado de acordo com os dispositivos conectados:

apt-get install udev

O udev exige um kernel 2.6.

Dispositivos de Entrada editar

Antes de prosseguir, é preciso verificar se os dispositivos de entrada (mouses e teclados) foram detectados. Para isso analise o arquivo /proc/bus/input/devices, que informa detalhes sobre os dispositivos de entrada encontrados pelo kernel. Um exemplo deste arquivo é apresentado abaixo. Apenas dois campos nos interessam: o nome de cada dispositivo, indicado nas linhas que começam com “N: Name=”, e o nome do arquivo relacionado ao dispositivo, mostrado nas linhas que começam com “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

Note que o arquivo parece indicar a presença de três teclados, embora no sistema aferido existam apenas dois. A razão do dispositivo adicional é que muitos teclados USB contém teclas especiais (por exemplo, de controle multimídia ou acesso à Internet), detectadas pelo kernel como pertencentes a um teclado secundário, cujo endereço físico termina em “input1”. Configuraremos apenas os teclados primários, com endereço físico terminado em “input0”. Portanto, a seção correspondente ao teclado secundário de endereço físico “usb-0000:00:10.2-1/input1” será ignorada.

Podemos perceber, pelo arquivo de exemplo, a presença de 2 teclados, relacionados aos arquivos /dev/input/event0 e /dev/input/event2, respectivamente, e 2 mouses, associados aos arquivos /dev/input/event1 e /dev/input/event4, respectivamente. Esses arquivos são importantes, pois são utilizados, como descreveremos posteriormente, para relacionar cada cabeça do multiterminal aos dispositivos de entrada corretos.

Instalação do servidor XOrg editar

Aqui descreveremos os passos para configurar o multiterminal utilizando o servidor XOrg, mas é possível utilizar o XFree86, com poucas alterações. Para instalar o XOrg, no Debian Sarge, proceda da seguinte maneira:

1. Faça uma cópia de segurança (backup) e remova o arquivo /etc/init.d/xfree-common. 2. Adicione as seguintes linhas ao arquivo /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. Instale o pacote xserver-xorg:

apt-get update
apt-get install xserver-xorg
apt-get upgrade

Download do Xnest Modificado editar

1. Faça o download do binário do servidor Xnest modificado aqui. Você pode, caso desejar, encontrar o patch para o código fonte do Xnest (Xorg 6.8.2) aqui. Você deve copiar o arquivo multiXnest para o diretório /usr/local/bin. 2. Faça o download do script "wrapper" multiXnest.sh, responsável por carregar o servidor multiXnest. O script deve ser copiado para o diretório /usr/sbin.

Configuração do Servidor X(XOrg) editar

Para um multiterminal de N terminais, o arquivo /etc/X11/xorg.conf deve ser configurado da seguinte forma:

1. Defina um layout contendo 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"
      	InputDevice	"Configured Mouse 1"
      EndSection

Obs: A disposição das telas apresentadas no layout acima não é relevante.

2. Defina as seções das N placas de vídeo.

      Section "Device"
      	Identifier	"Placa de Vídeo Genérica 1"
      	Driver		"sis"	
      	BusID		"PCI:0:5:0"	
      	Screen		0	
      EndSection	
      	#
      	# Substitua o driver da placa de vídeo de acordo com o seu hardware.
      	#
      	# A opção BusId identifica qual o endereço da placa de vídeo que está sendo utilizada.
      	# Para obter o BusId de suas placas digite "lspci | grep VGA"
      	# Tome cuidado com os valores, pois o endereço fornecido por lspci eh em Hexadecimal enquando que o X
      	# espera um valor em decimal. Para conversão use "echo $((0xVALOR_HEXADECIMAL))"
      	.
      	.
      	.
      Section "Device"
      	Identifier	"Placa de Vídeo Genérica N"
      	Driver		"sis"
      	BusID		"PCI:0:6:0"
      	Screen		0	
      EndSection

3. Defina as seções dos N monitores.

      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. Defina as seções das N screen's.

      Section "Screen"
      	Identifier	"Screen 1"
      	Device		"Placa de Vídeo Genérica 1"
      	Monitor		"Monitor 1"
      	DefaultDepth	24	
      	SubSection "Display"
      		Depth		24
      		Modes		"1024x768" "800x600" "640x480"
      	EndSubSection
      EndSection
      	.
      	.
      	.
      Section "Screen"
      	Identifier	"Screen N"
      	Device		"Placa de Vídeo Genérica N"
      	Monitor		"Monitor N"
      	DefaultDepth	24	
      	SubSection "Display"
      		Depth		24
      		Modes		"1024x768" "800x600" "640x480"
      	EndSubSection
      EndSection

5. As definições de teclado e mouse podem continuar idênticas as já existentes em seu xorg.conf.

6. Para evitar problemas na inicialização do Servidor X devido ao não reconhecimento do mouse, você pode incluir, sem problemas, a seguinte seção:

      Section "ServerFlags"
      	Option "AllowMouseOpenFail"	"yes"
      EndSection

Obs: Isso não afetará o multiterminal pois os dispositivos mouses/teclados serão passados como parametros, posteriormente, para o Xnest.

7. Finalmente, para evitar que o servidor X entre no modo de economia de energia, e para desabilitar a troca de VT's e as teclas Ctrl+Alt+Backspace, verifique que a seção "ServerFlags" possui as seguintes opções:

      Section "ServerFlags"
             ...
              # Estas opções evitam que o X entre em modo de economia de energia
              Option    "BlankTime"    "0"
              Option    "StandbyTime"  "0"
              Option    "SuspendTime"  "0"
              Option    "OffTime"      "0"
              
              # Desativar VT Switching
              Option    "DontVTSwitch" "yes"

              # Desativa o uso das teclas Ctrl+Alt+Backspace
              Option    "DontZap"       "yes"
             ...
      EndSection

Configuração XKB editar

Agora é necessário criar um arquivo de configuração XKB para cada multiXnest, para configurar os teclados. O arquivo de configuração do primeiro multiXnest deve ser colocado no arquivo /usr/X11R6/lib/X11/xkb/X1-config.keyboard, o do segundo em /usr/X11R6/lib/X11/xkb/X2-config.keyboard, e assim em diante. Um exemplo de um arquivo de configuração para um teclado ABNT2 pode ser visto a seguir:

rules = "xorg"
model = "abnt2"
layout = "br"

Configuração do Gdm editar

O último passo é configurar o gerenciador de login para iniciar o servidor X principal e também para rodar os scripts "wrappers" que serão responsáveis por abrir o Xnest em cada tela. Trataremos apenas do GDM. Outros gerenciadores como o XDM e o KDM podem ser configurados por um processo similar.

Edite o arquivo /etc/gdm/gdm.conf na seção [servers] inserindo o seguinte:

	[servers]
	0=Hardware
	# Hardware será o servidor X principal, naquele onde serão executados os demais N servidores Xnest's
	
	1=multiXnest1
	2=multiXnest2
	3=multiXnest3
	.
	.
	N=multiXnestN
	# multiXnest{1..N} é cada um dos servidores multiXnest's.

	[server-Hardware]
	name=Hardware
	command=/usr/X11R6/bin/X
	handled=false	
	flexible=false
	# A opção handled=false impede que seja carregado o gerenciador de login no servidor X principal.

	[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
	#
	# A opção -kbd e -ptr identificam, respectivamente, qual teclado e mouse serão associados ao servidor Xnest1
	# conforme analisado no arquivo /proc/bus/input/devices
	#
	# multiXnest.sh é o script que carrega o servidor Xnest.
	.
	.
	.
	[server-multiXnestN]
	name=multiXnestN
	command=/usr/sbin/multiXnest.sh -display :0.(N-1) -xauthority /var/lib/gdm/:0.Xauth -geometry 1024x768+0+0
	-kbd /dev/input/eventXX -ptr /dev/input/eventYY -dpi 92
	handled=true
	flexible=false

Veja também editar

 
Wikipedia
A Wikipédia tem mais sobre este assunto:
multiterminal