13. SERWER UNIXOWEGO PROTOKOŁU GRAFICZNEGO
Unixowy protokół graficzny (X protokół) jest protokołem wysokiego poziomu
(warstwy prezentacji)
służącym do przesyłania informacji graficznej pomiędzy programem użytkowym
(X klientem),
a programem obsługującym terminal graficzny (X serwerem).
Terminal graficzny
(X terminal)
klawiatura
wskaźnik
(mysz)
komputer główny
(host)
monitor
1
monitor 2
monitor
n
X serwer
X klient
Model logiczny pary X klient - X serwer
Uwaga.
1) Konfiguracja oprogramowania jest odwrotna, niż zazwyczaj (serwer w
terminalu, klient
w komputerze głównym).
2) Terminal graficzny może być zarządzany przez tylko jeden X serwer, w
komputerze głównym
może być uruchomionych wielu klientów.
3) Ogólny model jest modelem sieciowym: wiele komputerów i wiele terminali
może być połączonych
w sieć, dowolny proces na dowolnym komputerze (być może pełniącym
jednocześnie rolę terminala
graficznego) może łączyć się z dowolnym X serwerem, jeśli tylko posiada
odpowiednią autoryzację.
4) Autoryzacja (prawo do komunikowania się) może być przydzielana przez
właściciela procesu
X serwera wybranym użytkownikom sieci, wybranym komputerom lub
wszystkim użytkownikom.
W Unixie służy do tego polecenie xhost.
5) Wielu klientów może komunikować się współbieżnie z jednym X serwerem i
rywalizować
o generowane przez niego sygnały. Programy klientów powinny być tak
konstruowane, żeby
nie dezorganizowały sobie wzajemnie pracy.
X serwer nie musi być programem unixowym. Różne X serwery pracujące pod
różnymi systemami
operacyjnymi na rozmaitym sprzęcie mogą mieć bardzo zróżnicowane własności
(jeśli chodzi
o rozdzielczość, paletę kolorów, zbiory czcionek, zbiory wykonywanych funkcji i
inne). Prawidłowo
skonstruowane programy użytkowe (X klienci) powinny na początku testować
możliwości X serwera,
z którym aktualnie się komunikują, i dostosowywać się do nich.
Unixowa biblioteka funkcji Xlib jest interfejsem programów w języku C do
protokołu graficznego
(funkcjonującego zazwyczaj w oparciu o protokół TCP lub protokół do komunikacji
lokalnej). Jest
to biblioteka niskiego poziomu (oferująca funkcje typu otwarcie/zamknięcie
terminala graficznego,
otwarcie/zamknięcie okna na terminalu, nakreślenie linii prostej, łuku okręgu lub
wypisanie tekstu).
Na jej bazie powstały biblioteki wyższego poziomu, np. Xt (X toolkit) oferujące
obsługę bardziej
złożonych obiektów, takich jak przyciski, menu rozwijalne czy okienka dialogowe.
Kompilacja programów w języku C korzystających z biblioteki Xlib wymaga
umieszczenia w programie
odpowiednich plików nagłówkowych oraz podania opcji kompilatora powodującej
dołączenie odpo-
wiednich funkcji bibliotecznych do programu wynikowego.
( W naszym przypadku: gcc -L/usr/X11R6/lib -lX11 nazwa.c )
Najważniejsze funkcje i struktury danych
Funkcje Xlib operują na standardowych strukturach danych, do których dostęp jest
możliwy zazwyczaj
tylko za ich pośrednictwem. Struktury te są logicznym obrazem fragmentów
sprzętu, na którym
operuje X serwer:
{Uwaga: do tej pory nie istnieją polskie odpowiedniki wielu
nazw angielskich}
terminal graficzny
(display)
- odpowiada pojęciu graficznej stacji roboczej (z
urządzeniami we/wy)
ekran
(screen)
- odpowiada obrazowi na ekranie monitora
okno
(window)
- odpowiada oknu (zwykle jednemu z wielu) wyświetlanemu na
ekranie
mapa pikselowa
(pixmap)
- odpowiada obszarowi w pamięci operacyjnej
przechowującemu obraz,
który może być wyświetlony w oknie
rysowisko
(drawable)
- wspólna nazwa dla okien i map pikselowych
i wiele innych.
Istotnym pojęciem jest pojęcie zdarzenia, które może dotyczyć zarówno użycia
klawiatury lub
wskaźnika (myszy), jak i rozwoju wydarzeń na ekranie - przesłonięcia/odsłonięcia
okna, zmiany
okna aktywnego i innych. Program klienta może być wykonywany w trybie
asynchronicznym
(z kolejkowaniem zdarzeń poszczególnych rodzajów) lub w trybie
synchronicznym (wielokrotnie
wolniejszym, wykorzystywanym głównie do celów diagnostycznych).
Aby móc wykonywać operacje na oknach, X serwer musi komunikować się z
zarządcą okien
(window manager)
. Proces ten jest specjalnym klientem X serwera (zazwyczaj
wykonywanym na
tym samym komputerze, co X serwer), który musi być aktywny przez cały czas
działania X serwera.
Decyduje on o wszystkich szczegółach technicznych związanych z wyświetlaniem
okien, które nie są
ujęte w specyfikacji X protokołu.
Uwaga.
Programy X klientów mogą decydować o tym, czy chcą, czy też nie chcą
korzystać z usług zarządcy
okien (i wyświetlać obraz w postaci „surowych” okien nieprzemieszczalnych po
ekranie).
Display XOpenDisplay (char nazwa);
Zwraca: wskaźnik do struktury typu Display w przypadku sukcesu;
wskaźnik pusty (NULL) w przypadku błędu.
nazwa - łańcuch pusty lub o postaci:
adres:numer.ekran gdzie
adres - adres sieciowy komputera (o postaci zależnej od używanego
protokołu warstwy
transportowej, w przypadku protokołu TCP może być cyfrowy lub
symboliczny (jeśli
dostępny jest serwer nazw), może też być pusty - wtedy dobierany
jest jeden z proto-
kołów w dziedzinie Unixa)
numer - numer terminala graficznego (zazwyczaj podajemy tu 0, większe
liczby mogą się
pojawić, jeśli jeden komputer steruje kilkoma „nieinteligentnymi”
graficznymi
stacjami roboczymi)
ekran - numer monitora domyślnego w zestawie graficznej stacji roboczej
(tę część wraz
z kropką pomijamy, jeśli stacja robocza ma tylko jeden monitor)
Działanie: ustanawia połączenie między procesem wywołującym tę funkcję a X
serwerem o podanym
adresie i zapisuje uzyskane informacje o X serwerze w strukturze, do
której zwraca wskaźnik.
W przypadku, jeśli zamiast nazwy został podany łańcuch pusty, pobiera
nazwę domyślną
zapisaną w zmiennej środowiska DISPLAY.
Uwaga.
Niektóre systemy unixowe tworzą automatycznie zmienną DISPLAY już w
momencie zalogowania się
na nie (na przykład przy użyciu telnetu), niektóre należy skłonić do tego
odpowiednim poleceniem
(najlepiej umieszczonym w skrypcie logowania).
void XCloseDisplay (Display terminal);
terminal - wskaźnik do struktury zwrócony przez funkcję XOpenDisplay
Działanie: zapamiętuje niektóre ustawienia (na życzenie programisty) i zrywa
połączenie z X serwerem.
Istnieje cała seria funkcji służących do testowania struktury utworzonej przez
funkcję XOpenDisplay
(co umożliwia dostosowanie działania programu do możliwości X serwera).
Żeby można było cokolwiek wyświetlić na ekranie terminala, należy otworzyć na
nim okno. Okazuje
się to nadspodziewanie skomplikowaną czynnością, bo trzeba określić mnóstwo
różnych atrybutów -
rozmiary okna, szerokość ramki, kolory ramki i tła, czy korzystamy z usług
zarządcy okien, czy okno
ma samo odtwarzać brakujące fragmenty po odsłonięciu itd. Możemy też
zasugerować początkowe
położenie okna na ekranie (co w przypadku korzystania z usług zarządcy okien
niekoniecznie musi
być spełnione). Niektóre z tych atrybutów określamy oddzielnymi funkcjami, a
niektóre podajemy
jako argumenty funkcji tworzącej okno (XCreateWindow). Dalsze czynności są
jeszcze bardziej
skomplikowane (określenie palety kolorów, kontekstu graficznego itd.).
Początkującym programistom może trochę ułatwić pracę korzystanie z wartości
domyślnych
(funkcje Default Screen, DefaultVisual, XCreateSimpleWindow i inne).