🚀 go-pugleaf

RetroBBS NetNews Server

Inspired by RockSolid Light RIP Retro Guy

Article View: pl.comp.sys.xwindow
Article #106

X Window System FAQ

#106
From: Maciej MOCHOL
Date: Fri, 27 Feb 1998 16:39
2125 lines
76619 bytes
Hej!

Oto jest - by me and Przemek Borys. Na razie jest to wersja rozwojowa,
ale licze na wasza pomoc i sugestie... Aktualna wersje sciagnac
zawsze mozecie z mojej strony. Niewtajemniczonym przypominam o skasowaniu
tych smieci z adresu www ;-)

--
Codematic                            
 code@beta.cku.pwr.wroc.pl.strasznie.mi.sie.podobaja
 mmochol@elka.pw.edu.pl.te.smieci.na.koncu.adresu.email
 http://home.elka.pw.edu.pl.i.www.rowniez/~mmochol

-----TUTAJ FAQ-----
<html>
<head>
</head>
<pre>
/*
 * pl.comp.sys.xwindow
 *
 * X Window System FAQ
 *
 * Autorzy:
 *  Codematic <mmochol@elka.pw.edu.pl>
 *  Przemek Borys <pborys@p-soft.silesia.linux.org.pl>
 *
 * wersja 25.02.1998
 *
 */

void SPIS_TRESCI {
 I. Co to jest FAQ ?
 II. Ogólnie o X
  1. Co to jest X Window System
  2. Na jakich platformach działa X
  3. Czy X może się przydać w domu
  4. Dlaczego warto postawić na X w mojej firmie
  5. Czym różni się X od Ms Windows i dlaczego to nie to samo
  6. Co to jest XFree86 ?
 III. Instalacja i konfiguracja X Window System
  1. Skad wziac X
  2. Jak zrobic zeby cos zaczelo dzialac
  3. O co chodzi w XF86Config
  4. Czy jest jakas alternatywa dla recznego klepania pliku XF86Config ?
  5. Co zrobic kiedy obraz na monitorze brzydko sie zachowuje (za szeroki, nie
     miesci sie) i co ma do tego xvidtune ?
  6. Wlaczam X i mam szary ekran z krzyzykiem
  7. Moje Xy sa brzydkie... Buuu...
  8. Co to sa zasoby (resources)
  9. Ogonki w X
  10. Co to sa widgety (lopatologicznie) i jak je poustawiac
  11. Metodologia w plikach: .xinit, .Xresource, startx, openwin
  12. Co to jest xdm i do czego sluzy
  13. Chce X-y pod:
     a) DOSem
     b) Win/Win95/WinNT
     c) OS/2
  14. Jakie sa rozne fajne desktopy/window managery ?
     a) FVWM/FVWM2/FVWM95
     b) Afterstep
     c) KDE
 IV. Programowanie w X
  1. Od czego zaczac
  2. X Window dla opornych - short lame ;-) tutorial by Codematic
  3. Motif X Window Programming HOWTO PL - Przemek Borys
  4. Xlib
  5. Gtk, gtk+
  6. Xaw czyli Athena Widgets
  7. Qt
};

==================================
I. Co to jest FAQ ?
==================================

	FAQ (ang. Frequently Asked Questions) wlasnie w tej chwili czytasz.
Znajdziesz w nim opis systemu X Window System w pytaniach i odpowiedziach, 
ktory byc moze pomoze Ci w zrozumieniu/skonfigurowaniu/wykorzystaniu X-ow.
	Wszelkie komentarze i sugestie prosimy kierować e-mailem na w/w
adresy autorów. Nie chcemy żeby to było lame-faq, więc jeśli znajdziesz
tu jakiś błąd lub nieścisłość, to proszę nie wyśmiewaj się z naszej 
indolencji, tylko po prostu prześlij nam info.
	Najświeższą wersję FAQ znajdziesz na:

	http://home.elka.pw.edu.pl/~mmochol

==================================
II. Ogólnie o X
==================================


 /*
  * 1. Co to jest X Window System
  */


	Cytat z mana:
"X Window System jest 'przezroczystym sieciowo' systemem okienkowym, 
który działa na dużej liczbie komputerowych i graficznych maszyn.
Powinno być stosunkowo prosto skompilować oprogramowanie z X Consortium
na większosci systemow zgodnych z C i POSIX. Dostępne są rownież
komercyjne implementacje na dużej liczbie platform.".
	Mam nadzieję, że ten opis jest stosunkowo przejrzysty.
Zapraszam tez do pierwszej części tutoriala "X Window System dla 
opornych" umieszczonego w tym FAQ, ktory - być może - wprowadzi
Was w X Window System.
	Wyjaśnić też trzeba na początku, że X to nie jest jakiś
program, albo system operacyjny. X to jest zbiór protokołów, tak jak
telnet, ftp, http, ktore pozwalają na zbudowanie rozproszonego 
systemu okienkowego. Musimy tez powiedziec że X jest oparty na 
technologii klient-serwer. X Server to program, ktory działa na 
Maszynie użytkownika. Akceptuje on połączenia z różnych maszyn,
wyświetlając okienka. Po sieci przekazywane są informacje o kliknięciu
myszką, zdarzeniach klawiatury - od X Servera do X Clienta. X Client
to jest program napisany dla X. On z kolei wysyła do X Servera polecenia
narysowania okienka, itd. X Server i X Client moga oczywiscie byc na
różnych maszynach. No, to tyle jesli chodzi o podstawy.
	I nie należy pisać X-Windows.
Aha, chciałbym również powiedzieć co jest - moim zdaniem - największą
wadą X. Otóż, sądzę że największą wadą X jest to, że jest ... za darmo.
Tak tak, zerowy marketing i reklama spowodowały że jest to naprawdę
dobry, ale niedoceniony system. W chwili powstawania wyprzedzał swoją
epokę (podobnie jak MacIntosh). Wlaściwie bez większych zmian ta sama
specyfikacja, te same kody źródłowe sprzed 10 lat (!) są wykorzystywane 
do czegoś, co z powodzeniem konkuruje z dzisiejszymi, firmowymi systemami.
Wydaje mi się, że z chwilą upowszechnienia się Linuxa/FreeBSD, gdy sami
dowiecie się więcej o X, zaczniecie się zastanawiać nad tym paradoksem.



 /*
  * 2. Na jakich platformach działa X
  */


	Jak już wspomniałem - na dużej liczbie platform. To znaczy
na większości. Będąc bardziej precyzyjnym - trudno znaleźć platformę,
na której X nie działa. Systemy zgodne z C i POSIX oznaczają praktycznie
wszystkie poważniejsze Unixy. Sa X Serwery dla DOS, Windows (95/NT),
OS/2. X działa na QNX. Czyli wlaściwie wszystkie liczące się systemy 
dla platformy Intela. Natomiast na innych procesorach X jest najczęściej
dostarczane razem z systemem operacyjnym przez producenta - po co 
wyważac otwarte drzwi i tworzyć GUI od nowa.





 /*
  * 3. Czy X może się przydać w domu
  */

	Oczywiście że X może się przydać w domu. Mimo, że jest to
w zasadzie system sieciowy, to jednak nic nie stoi na przeszkodzie,
żeby używać go na jednej maszynie. W praktyce X nazwano okienkami
dla Unixa - nieco niepoprawnie wprawdzie, jednakże dobrze to oddaje
czym jest X. X w domu może slużyć do zabawy, pracy i w ogole do 
korzystania z komputera.
	X jest bardzo zaawansowany graficznie. Jest naprawdę dobry
do np. zastosowań CAD, ze względu na wykorzystanie mozliwosci
akcelelatorów sprzętowych na większości X Serwerów. X przewiduje
również protokół PEX do grafiki 3D - który tym się różni od np. 
OpenGL i DirectX - ze jest na niższym poziomie. Niestety mało kto
słyszał o PEX i nie widziałem na niego żadnej gry :-(



 /*
  * 4. Dlaczego warto postawić na X w mojej firmie
  */

	X to nie to samo, z czym powszechnie kojarzy sie nam Windows.
Windows byl to na poczatku graficzny interfejs uzytkownika, o sieci
wtedy nikt nie myslal. Natomiast X to zupelnie co innego. X jest
sieciowy. Wiekszosc z Was slyszala zapewne o Javie oraz o idei komputera
sieciowego (NetPC, NC, Network Computer). Wiecie dlaczego te pomysly sa
tak atrakcyjne ? Bo pozwalaja zapomniec o klopotach z konfiguracja dla
poszczegolnych uzytkownikow. Pozwalaja tez zaoszczedzic na twardych
dyskach. Mowimy wiec o braku klopotow z awariami i konfiguracja.
	X tym sie rozni od Javy, ze na komputerze uzytkownika nie musza
byc uruchamiane zadne programy. Oznacza to oszczednosc - wystarczy nam
zwykly i386, zeby uruchomic np. XAppeal i uzyskac w pelni funkcjonalna
stacje robocza. Mowimy zatem o kosztach. Pokazmy na przykladzie malutkiej
sieci jak przedstawiaja sie typowe rozwiazania w firmach, a jak mogly by
byc rozwiazane przy uzyciu X. Jako system operacyjny w tym drugim
przypadku niech to bedzie Linux (badz FreeBSD).
	[... Jeszcze coś tu napiszę...]



 /*
  * 5. Czym różni się X od Ms Windows i dlaczego to nie to samo
  */
	Podstawową różnicą jest to, że X'y są sieciowe, a Windows nie.
Jak to ? - krzykną windziarze - przecież Windows mają obsługę sieci !
Ale nie o to chodzi. X Window jest rozproszone, programy dla X mogą
się wykonywać na innej maszynie, niż tej przy której siedzi użytkownik.
	Po drugie, Windows jest raczej interfejsem użytkownika, środowiskiem
dla programów, taką "nakładką" na system operacyjny (DOS lub NT). 
Natomiast X to protokól sieciowy, pozwalający na zbudowanie takiego 
interfejsu. X'y są bardzo elastyczne, można w nich zmienić dokładnie
wszystko, od kursora po kształt okienek (nazywa się to Shape Extensions).
	Najbardziej mi się podoba to, że X'y mogą wyglądać jak dowolne 
inne srodowisko. Wystarczy, że zmienimy Window Managera i mamy coś, co
do złudzenia przypomina nam Microsoft. Instalujemy CDE lub KDE i 
otrzymujemy coś absolutnie innego, zupełnie niepodobnego do poprzedniego
środowiska. X'y mogą wyglądać jak NextStep, jak Amiga, albo jak konsola
Enterprise ze StarTrek - jeśli tylko chciało by się Wam napisać
odpowiednie GUI ;-)
	Poza tym X'y nic nie wymuszają. Programy dla X mogą teoretycznie
dzialać na różnych maszynach, na dowolnym systemie operacyjnym. Powtarzam,
X to protokół, a nie OS ! Tak jak ftp, klient X Window teoretycznie 
może działać na dowolnym systemie operacyjnym. Teoretycznie, bo ja słyszałem 
tylko o wersjach na różne Unixy oraz OS/2. Ale jest to możliwe. 
Open standard... Programy dla X mogą dowolnie korzystać ze środowiska 
w którym pracują. Np. jednocześnie mogą wyświetlać okienka na ekranie 
OS/2 ...
	Nie inaczej się rzecz ma z Xserwerem. Odsyłam do odpowiedniego
pytania w FAQ (Chcę X'y pod...). Sa X Servery dla najróżniejszych
systemów operacyjnych i tu się rzecz ma zdecydowanie lepiej niz z
xclientami. 
	Powtórzę jeszcze jedną myśl: X'y nie są interfejsem użytkownika.
Natomiast można sobie na nich taki interfejs zbudować.


 /*
  * 6. Co to jest XFree86 ?
  */
Nie wiecie co to jest ?
==================================
III. Instalacja i konfiguracja X Window System
==================================


 /*
  * 1. Skad wziac X
  */
Nie ma odpowiedzi na to pytanie. Poczekaj na nastepne FAQ.

 /*
  * 2. Jak zrobic zeby cos zaczelo dzialac
  */
Nie ma odpowiedzi na to pytanie. Poczekaj na nastepne FAQ.

 /*
  * 3. O co chodzi w XF86Config
  */
(c) 1998 Przemek Borys

0. Do wielu zastosowań nie potrzebujesz zagłębiać się w ten plik
samodzielnie. Możesz użyć programu XF86Setup, który zautomatyzuje proces
konfiguracji, uruchomiając roboczo X-y w najsłabszej możliwej konfiguracji.
Możesz tam swobodnie wybrać sobie kartę video, typ monitora, klawiaturę itd.
Iście po windziarsku :)
Możesz także użyć programu "xf86config", który przeprowadza konfigurację w
trybie tekstowym. (ma niezbyt ładny interfejs).

1. Teraz zrobimy sobie mały spacerek po żywym pliku XF86Config, i omówimy
wszystko co tam jest. Zaczynamy.

---
#
# Copyright (c) 1995 by The XFree86 Project, Inc.
#
---

Na początek, jak zresztą nietrudno się domyślić, powiedzmy że znaczek '#'
oznacza początek komentarza, który kończy się na końcu linii.

---
Section "Files"
---

Tu widzimy pewne słówko kluczowe. Mianowicie "Section". Wszystko w pliku
XF86Config jest zgrupowane w sekcje. Jest sekcja opisująca pliki, sekcja
opisująca klawiaturę, itd. Nazwy sekcji (tu "Files") są też ważne - dzięki
nim konfigurator orientuje się co chcemy definiować. Sekcja "Files" służy 
do zdefiniowania ścieżek do różnych ważnych plików, tj. bazy kolorów 
zdefiniowanych przez RGB, oraz ścieżki do fontów. Np:

---
    RgbPath	"/usr/X11R6/lib/X11/rgb"
    FontPath   "/usr/X11R6/lib/X11/fonts/misc/"
    FontPath   "/usr/X11R6/lib/X11/fonts/75dpi/:unscaled"
    FontPath   "/usr/X11R6/lib/X11/fonts/Type1/"
    FontPath   "/usr/X11R6/lib/X11/fonts/Speedo/"
    FontPath   "/usr/X11R6/lib/X11/fonts/75dpi/"
---

Można opcjonalnie tez zdefiniować ścieżkę do modułów ładowanych dynamicznie,
np:

---
    ModulePath "/usr/X11R6/lib/modules"
---

Po zakończeniu definiowania określonej sekcji, uzywamy słówka kluczowego
"EndSection", np:

---
EndSection
---

Przejdźmy do następnego elementu naszego spaceru - opcjonalny fragment:

---
# Section "Module"
# Load "xf86Jstk.so"
# EndSection
---

Sekcja ta umożliwia doładowywanie dynamicznych modułów (driverów) w sposób
pokazany dla modułu o nazwie "xf86Jstk.so" (moduł obsługi joysticka).

Kolejna sekcja to

---
Section "ServerFlags"
---

Która opisuje różne właściwości serwera. Są to kolejno:

---
#    NoTrapSignals
---

Powoduje uwrażliwienie serwera na nieprzewidywane sygnały i zarzucanie core.
Przydatne do debugowania programów.

---
#    DontZap
---

Powoduje wyłączenie sekwencji ctrl+alt+bckspc killującej serwer.

---
#    DontZoom
---

Powoduje wyłączenie przełączania się między trybami video z pomocą szarego
plusa i minusa.

---
#       DisableVidModeExtension
---

Uniemożliwia dostrajanie trybu video za pomocą "xvidtune".

---
#       AllowNonLocalXvidtune
---

Umożliwia wywołanie "xvidtune" z maszyny innej niż lokalna. Domyślnie jest
to zabronione.

---
#       DisableModInDev
---

Uniemożliwia dynamiczne modyfikowanie urządzeń wejściowych (myszy lub
klawiatury).

---
#       AllowNonLocalModInDev
---

Uniemożliwia dokonywania zdalnych modyfikacji urządzeń wejściowych.


Teraz skręćmy w ulicę (pamiętajmy że spacerujemy ;) o nazwie

---
#Section "Keyboard"
---

Jak widać, sekcja ta opisuje parametry klawiatury i rzeczy z nią związanych.
Oto one:

---
#    Protocol	"Standard"
---

Definiuje to protokół, w jakim obsługiwana jest klawiatura. Poza "Standard",
może być jeszcze "XQueue". (używane na SVR4 i SVR5).

---
#    AutoRepeat	500 5
---

Określa częstość samopowtarzania klawiatury (tu cyfra 5), oraz opóźnienie 
przed rozpoczęciem samopowtarzania (tu 500). Czasem to nie działa.

---
#    ServerNumLock
---

Serwer obsługując klawiaturę przy ustawionej tej opcji, w zależności od
stanu num-locka, traktuje keypad jako keypad, lub klawiaturę numeryczną.

---
#    Xleds      1 2 3
---

Ta opcja występuje z parametrem (parametrami) liczbowymi, określającymi
numer diody (Scroll Lock, Caps Lock, Num Lock), którą serwer ma oddać do 
użytku klientom (programom pod X), zamiast samodzielnie korzystać z jej
standardowej funkcji.

---
     LeftAlt	Meta
     RightAlt	ModeShift
     ScrollLock Compose
     RightCtl  Control
---

Te opcje umożliwiają przemapowywanie funkcji klawiszy. Np. lewy alt
traktowany jest jako klawisz "meta" - tj. normalny alt, a prawy alt jest
używany do np. pisania polskimi literkami.

---
#   XkbDisable
---

Wyłącza rozszerzenia XKEYBOARD

---
#    XkbRules    "xfree86"
---

Definiuje plik z regułami, na podstawie którego korzystać z komend dla
niektórych pól sekcji keyboard.

---
#    XkbModel    "pc102"
---

Ustawia model klawiatury. Może być np. "pc102", "pc101", "microsoft" itd.
Sprawdź najlepiej plik /usr/X11R6/lib/xkb/rules/xfree86 (sekcja "model"). 

---
#    XkbLayout   "de"
---

Ustawia układ klawiatury. W tym wypadku niemiecki. Może być też "us" -
amerykański. Znowu - definicje są w pliku /usr/X11R6/lib/xkb/rules/xfree86
(sekcja "model layout").

---
#    XkbVariant  "nodeadkeys"
---

Wybiera wariant dla nieamerykańskich klawiatur. Narazie dopuszczalny jest
tylko "nodeadkeys". (nie wiem konkretnie co to jest, ale przypuszczam, że
chodzi o eliminację niestandardowych klawiszy). (jak ktoś wie, niech powie
;)

---
#    XkbOptions  "grp:toggle"
---

Definiuje różne opcje klawiaturowe. Jak zwykle dostępne są zdefiniowane w
pliku z regułami (/usr/X11R6/lib/xkb/rules/xfree86) jako odnośniki do pliku
z symbolami. Przykład powyżej przełącza pod prawym altem klawiaturę z grupy
znaków podstawowego zbioru na zbiór drugi i na odwrót. (wszystko jest
napisane w odpowiednich plikach z symbolami).

---
#    XkbKeymap   "xfree86(us)"
---

Ustala mapowanie klawiszy na określone symbole.


Czas przejść do następnej sekcji. Będzie to

---
Section "Pointer"
---

sekcja opisująca urządzenie wskazujące - tj. w większości wypadków myszkę.

---
    Protocol    "Microsoft"
---

Protokół według którego X-y mają się porozumiewać z myszką. (może być
"Microsoft", "BusMouse", "Logitech", "MMSeries", "Mouseman", "MouseSystems",
"PS/2", "MMHitTab", "GlidePoint", "XQueue", "OSMouse"). Zazwyczaj mamy do
czynienia z myszami "Microsoft".

---
    Device      "/dev/mouse"
---

Określa urządzenie przez które komunikujemy się z myszą. Tu "/dev/mouse".

---
#    BaudRate	9600
#    SampleRate	150
---

Te wartości potrzebne są tylko niektórym myszom Logitech. Baudrate określa
szybkość transmisji danych między myszką a komputerem. Standard to 1200.
Samplerate określa częstość wywoływania zdarzeń poruszenia myszą/naciśnięcia
guzika w systemie.

---
# Emulate3Buttons
---

Emuluje trzeci guzik na dwuguzikowych myszkach poprzez naciśnięcie ich obu
naraz.

---
# Emulate3Timeout 50
---

Określa czas po którym serwer stwierdza, że dwa klawisze rzeczywiście były
wciśnięte razem. Czas podaje się w milisekundach.

---
#    ChordMiddle
---

Trzeba ustawić tą opcję przy myszach Logitech, które wciśnięcie środkowego
klawisza traktują jako wciśnięcie naraz lewego i prawego.


Teraz przejdziemy do kolejnej sekcji - opcjonalnej - konfigurującej
dodatkowe urządzenia wejściowe, np. joystick.

---
# Section "Xinput" 
---

Ta sekcja nazywa się jak widać "Xinput". Wszelkie urządzenia wejściowe
konfigurujemy dalej w _podsekcjach_, nie w ciele nadrzędnej sekcji. Np:

---
Subsection "Joystick"
Endsubsection
---

Dalsze opisy będą bazować na konfiguracji joysticka - poza nim X-y obsługują
również urządzenia takie jak "WacomStylus", "WacomCursor", "WacomEraser",
"Elographics", "Mouse". Tak! Można tu skonfigurować również mysz :) (na
zasadach takich jak w sekcji "Pointer".
Wróćmy jednak do konfiguracji joysticka.

---
#        Port "/dev/joy0"
---

Określa urządzenie z którego korzystać do komunikowania się z joystickiem.

---
#        DeviceName "Joystick"
---

Ustawia nazwę dla tego X-urządzenia.

---
#        TimeOut 10
---

Milisekundowy okres między kolejnymi akcjami sterownika joysticka.

---
#        MinimumXPosition 100
#        MaximumXPosition 1300
#        MinimumYPosition 100
#        MaximumYPosition 1100
#        # CenterX 700
#        # CenterY 600
---

Określa współrzędne zwracane przez sterownik zależnie od wychylenia
joysticka.

---
#        Delta 20
---

Określa czułość joysticka.


A teraz zaczyna się dopiero zabawa. Przechodzimy do pierwszej sekcji 
definiującej wizję.

---
Section "Monitor"
---

Jest to sekcja opisująca monitor.

---
    Identifier  "My Monitor"
---

Tu podajemy identyfikator, którym będzie się można później posługiwać w tym
pliku. (Można zdefiniować wiele monitorów, więc trzeba je jakoś rozróżnić).

---
    VendorName  "Unknown"
    ModelName   "Unknown"
---

Opcjonalne pola, określające producenta i model sprzętu.

---
    HorizSync   31.5, 35.15, 37.8
---

Określa dostępne częstotliwości poziome monitora w kHz. (Częstotliwość
pozioma, to ilość rysowanych linii poziomych na sekundę). Musisz sprawdzić
jak pisze w dokumentacji twojego monitora.

---
#    HorizSync	30-64         # multisync
---

Tak (z kreseczką) podajemy te wartości dla monitorów multisync.

---
    VertRefresh 50-90
---

Częstotliwość pionowa monitora w Hz. Częstotliwość pionowa to ilość
rysowanych ekranów obrazu na sekundę.

---
#    ModeLine "1024x768" 45 1024 1048 1208 1264 768 776 784 817 Interlace
---

Określa przykładowy tryb video dla danego monitora. Kolejne parametry tego
pola to:

"1724x768" - nazwa trybu (używana wewnątrz pliku konfiguracyjnego)
45         - impuls punktu - Częstotliwość w MHz z jaką stawiane są punkty.
1024       - szerokość widzialnego obrazu.
1048       - początek repozycjonowania (synchronizacji - stąd sync) poziomego.
1208       - koniec repozycjonowania poziomego.
1264       - całkowita długość linii.
768        - wysokość widzialnego obrazu.
776        - początek repozycjonowania pionowego wiązki elektronów.
784        - koniec repozycjonowania pionowego.
817        - całkowita wysokość obrazu.
Interlace  - włącza tryb interlaced dla danego trybu video. Gdy tej opcji
             nie będzie, tryb będzie normalny, nie-interlaced. Poza
             "interlace" są jeszcze inne flagi, np. "DoubleScan",
	     określający, że każda linia jest podwojona, i inne. (man
	     XF86Config)

---
    Mode "1024x768"
        DotClock	45
        HTimings	1024 1048 1208 1264
        VTimings	768 776 784 817
        Flags		"Interlace"
    EndMode
---

Powyżej mamy alternatywną formę jednoliniowej definicji trybu video.


Monitor mamy z głowy. Teraz przejdźmy do następnej sekcji,

---
Section "Device"
---

do określenia urządzenia video, karty graficznej.

---
    Identifier	"Generic VGA"
---

Identyfikator, którym będziemy się posługiwać wewnątrz pliku
konfiguracyjengo. (można zdefiniować wiele kart graficznych, i wtedy trzeba
je jakoś rozróżnić).

---
    VendorName	"Unknown"
    BoardName	"Unknown"
---

Opcjonalne pola określające producenta i nazwę karty graficznej.

---
    Chipset	"generic"
---

To pole określa, z jakiego chipsetu korzystać. Jest to opcjonalne -
normalnie serwer sam to sprawdza.

---
#    VideoRam	256
---

Wielkość pamięci RAM karty video.

---
#    Clocks	25.2 28.3
---

Dopuszczalne impulsy punktu oferowane przez kartę.

A oto dodatkowe, opcjonalne pola dopuszczalne w tej sekcji:

---
#    Ramdac	"ATT20C490"
---

Określa model Ramdac'a (przetwornika video RAM na sygnał dla monitora) 
używanego na karcie. Normalnie X serwer wykrywa go automatycznie.

---
#    Dacspeed	110
---

Szybkość RAMDAC-a w MHz. To pole jest również domyślnie wykrywane
automatycznie.

---
#    Option	"dac_8_bit"
---

To pole umożliwia wykorzystanie opcji dawanych przez konkretny sterownik.
Można używać wielu takich pól w sekcji.

Poza wyżej wymienionymi polami, jest ich jeszcze kilka opisanych w manualu
od XF86Config, ale chyba nie są one zbyt istotne, skoro nie ma ich w
przykładowym pliku konfiguracyjnym, po którym właśnie robimy spacerek. :)


Pozostała nam już ostatnia sekcja - sekcja opisująca ekran. Nie kartę video,
nie monitor, lecz to co się liczy dla użytkownika - obraz na ekranie.

---
Section "Screen"
---

Sekcja ta nazywa się "Screen". Oto pola w niej dostępne:

---
    Driver      "svga"
---

Definiuje z jakiego serwera korzystamy w tej sekcji (bo znowu - sekcji
"screen" może być wiele). Może to być "svga", "accel", "mono", "vga2", 
"vga16".

---
    Device      "Trident 8900/9000 (generic)"
---

Tutaj określamy, z jakiej karty graficznej chcemy korzystać. Jako parametr
pola "Device" podajemy identyfikator karty video, który zdefiniowaliśmy
wcześniej w sekcji "Device".

---
    Monitor     "My Monitor"
---

Tu określamy, z jakiego monitora chcemy korzystać. Jako parametr pola
"Monitor" podajemy identyfikator monitora, który wcześniej zdefiniowaliśmy w
sekcji "Monitor".

---
   DefaultColorDepth	8
---

Ten parametr określa domyślną głębie koloru. Tu ustawiono kolor 8-bitowy.

---
   BlankTime	       10
---

Określa okres (w minutach) po którym włączyć wygaszacz ekranu.

---
    Subsection "Display"
---

Sekcja "Screen" jest tak obszera, że potrzebuje podsekcji. W podsekcji
"display", definiujemy z jakich trybów video i w jaki sposób można korzystać
dla danego zestawu sprzętowego.

---
        Depth       8
---

Określa głębię koloru dla tej podsekcji. (tu 8-bitowy).

---
        Modes       "800x600" "640x480"
---

Określa tryby, jakie są dostępne w tej podsekcji.

---
        ViewPort    0 0
---

Określa, jakie współrzędne ekranu mają się znaleźć w lewym górnym rogu (to
pole istnieje z uwagi na pole następne).

---
        Virtual     800 600
---

Określa wirtualny ekran, większy od tego, który widać na monitorze, który
można programowo przesuwać na fizyczny monitor.


 /*
  * 4. Czy jest jakas alternatywa dla recznego klepania pliku XF86Config ?
  */
	I owszem. Po pierwsze xf86config - ktory jest niezbyt "user
friendly". Trzeba po prostu odpowiadac na pytania. Po drugie XF86Setup, 
ktory jest "user friendly" i nie trzeba byc zbytnim ekspertem zeby
z niego korzystac...

 /*
  * 5. Co zrobic kiedy obraz na monitorze brzydko sie zachowuje (za szeroki, nie
     miesci sie) i co ma do tego xvidtune ?
  */
	W pliku XF86Config jest taka sekcja Monitor. W tej sekcji mamy
takie linijki: Modeline i rozne cyferki. Widzicie ? To sa parametry 
danego trybu, czestotliwosc odswiezania pionowego, poziomego i rozne 
takie. Na monitorach cyfrowych mozemy sobie ustawic dla kazdego trybu
te parametry, przesunac obraz w lewo, rozciagnac, etc. i w ten sposob
dopasowac ekran do X'ow. Natomiast na monitorach analogowych - owszem -
tez sobie mozna przesuwac ekran, ale - gdy wyjdziemy z X to tryb
tekstowy bardzo brzydko nam zjedzie... Wiec trzeba dopasowac X'y do 
monitora: uruchamiamy xvidtune i ustawiamy obraz tak aby sie nam spodobal
dla kazdego trybu - 640x480, 800x600, itd. Nastepnie widzimy ze xvidtune
pokazal nam rzad cyferek, zadziwiajaco podobnych do tych z XF86Config...
Wiec wpisujemy je do wlasciwej Modeline i zapisujemy XF86Config. Po
nastepnym uruchomieniu X powinno byc ok.


 /*
  * 6. Wlaczam X i mam szary ekran z krzyzykiem
  */
Nie ma odpowiedzi na to pytanie. Poczekaj na nastepne FAQ.

 /*
  * 7. Moje Xy sa brzydkie... Buuu...
  */
Nie ma odpowiedzi na to pytanie. Poczekaj na nastepne FAQ.

 /*
  * 8. Co to sa zasoby (resources)
  */
Nie ma odpowiedzi na to pytanie. Poczekaj na nastepne FAQ.

 /*
  * 9. Ogonki w X
  */
Nie ma odpowiedzi na to pytanie. Poczekaj na nastepne FAQ.

 /*
  * 10. Co to sa widgety (lopatologicznie) i jak je poustawiac
  */
Nie ma odpowiedzi na to pytanie. Poczekaj na nastepne FAQ.

 /*
  * 11. Metodologia w plikach: .xinit, .Xresource, startx, openwin
  */
Nie ma odpowiedzi na to pytanie. Poczekaj na nastepne FAQ.

 /*
  * 12. Co to jest xdm i do czego sluzy
  */
Nie ma odpowiedzi na to pytanie. Poczekaj na nastepne FAQ.

 /*
  * 13. Chce X-y pod:
     a) DOSem
     b) Win/Win95/WinNT
     c) OS/2
  */
Nie ma odpowiedzi na to pytanie. Poczekaj na nastepne FAQ.

 /*
  * 14. Jakie sa rozne fajne desktopy/window managery ?
     a) FVWM/FVWM2/FVWM95
     b) Afterstep
     c) KDE
  */
Nie ma odpowiedzi na to pytanie. Poczekaj na nastepne FAQ.
==================================
IV. Programowanie w X
==================================


 /*
  * 1. Od czego zaczac
  */
	Yeah. To pytanie bylo pierwszym, ktore sobie zadalem przerazony
spogladajac na __MEGABAJTY__ dokumentacji z X Consortium i kilogramy
ksiazek w rodzaju serii z ORA. No coz... Dobrym pomyslem jest przeczytanie
w calosci tego FAQ. Nastepnie rozwoj uzalezniony jest od znajomosci
jezyka. Niestety nie znalazlem zbyt wielu dokumentow po polsku o X'ach,
a o programowaniu tym bardziej... Prawde mowiac zadnego nie widzialem,
oprocz XFree86 HowTo, przetlumaczonego przez Piotra Teczynskiego w
ramach projektu JTZ. Nie wiem jakich rad moglbym udzielic zielonym,
ja zawsze uwazalem ze najlepiej i najszybciej jest zajrzec do kodu
zrodlowego. Sciagnijcie sobie prosciutkie programiki, jakies proste
gierki w rodzaju xbill, przegladarki - np. xpdf. Ta ostatnia zreszta
jest bardzo fajnie napisana. Kodow z X Consortium do celow edukacyjnych
w fazie poczatkowej nie polecam. Nawet taki programik jak xlogo,
wydawalo by sie banalny, tworzy skubany wlasny widget, korzysta z jakichs
dziwnych bibliotek, ee tam... Za madre jak dla mnie. Mozecie tez poszukac
na sieci Motif-FAQ:

      ftp://ftp.cen.com/pub/Motif-FAQ     or
      ftp://ftp.cen.com/pub/Motif-FAQ.gz  or
      ftp://ftp.cen.com/pub/Motif-FAQ.Z
      http://www.cen.com/mw3/faq/motif-faq.html         [NEW Nov. 1996]

 jesli chcecie od razu rozpoczac nauke od X Toolkitu. Oczywiscie FAQ
to odnosi sie rowniez do Lesstifa, darmowego klona Motifa (w wiekszosci
w kazdym razie).
	No wlasnie.
	Pozostaje kwestia na co wlasciwie postawic. Mysle ze nie 
warto uczyc sie Xlib, przynajmniej na poczatku. Wiekszosc z Was zapewne
zna C++ lub Turbo Pascala, ma wiec niejakie pojecie o programowaniu
obiektowym. Na tym zasadza sie idea XtIntrinsics, a co za tym idzie
wiekszosci toolkitow w rodzaju Motifa czy OpenLooka. I jest to raczej
proste programowanie obiektowe.
	Prawde powiedziawszy programowanie w X przy pomocy X Toolkitow
jest nietrudne, przy pewnym oblataniu w programowaniu Unixowym i znajomosci
takich zagadnien jak kompilacja, laczenie, etc. kazdy moze spokojnie w 
tydzien nauczyc sie tworzyc samodzielnie wlasne programy. 
	Co innego jednak jest korzystac z X Toolkitu, a pisac wlasne
widgety. To drugie to wyzsza szkola jazdy i trzeba wtedy znac mechanizmy
Intrinsics, Xlib i w ogole wiedziec o co chodzi w te klocki. Najprosciej
i najlepiej jednak sciagnac sobie z Sieci wlasciwy widget, o ktory nam
chodzi. A jest ich mnostwo. Wystarczy poszukac. Jest nawet taka organizacja
Free Widget Foundation, nie wiem jednak nic wiecej. Mozna spojrzec na

ftp://ftp.icm.edu.pl

Tam w odpowiednim katalogu sa rozne ciekawe rzeczy.

	Konkurencja dla widgetow jest np. biblioteka xforms. Jest tez
wiele konkurencyjnych bibliotek, niektore oparte sa na C++. Ostatnio
wiele sie slyszy o Qt i KDE. Jest to naprawde dobry pomysl na nauczenie
sie tego. Ciekawa propozycja jest tez toolkit Gtk+, napisany przez autorow
GIMPa na potrzeby tego programu, a ktory sie okazal tak dobry, ze powstaje
teraz przy jego uzyciu kilka ciekawych projektow. Zapraszam na 

http://www.gnome.org.

	Ale prawdziwym rarytasem beda na pewno kody Netscape. W chwili
gdy pisze ten tekst jeszcze ich nie ma (21.02.1998), ale wyglada na to
ze beda. To dopiero bedzie szal.
	No, to tyle. Zycze sukcesow ;-)



 /*
  * 2. X Window dla opornych - short lame ;-) tutorial by Codematic
  */
++++++++++++++++++++++++++++++++
================================
X Window System dla opornych
================================
++++++++++++++++++++++++++++++++

Copyright <c> 11.1997 by Codematic
All Rights Reserved

Autor nie odpowiada za ewentualne uszkodzenia danych, sprzetu, zdrowia
czy czegokolwiek powstale w wyniku lektury czy tez innych sposobow
wykorzystania tego artykulu.

Autor nie zezwala na modyfikacje bez jego zgody. Kopiowanie, rozpowszechnianie
dozwolone, a odczyty publiczne wrecz zalecane :)


                        XWindow dla opornych, cz I

        Poniewaz jest to artykul dla opornych, wiec bede mowil tu o rzeczach
ktore zapewne wielu wydadza sie oczywiste. Zaczne wiec od tego

CO TO JEST X WINDOW SYSTEM ?
----------------------------

Nie sa to zadne okienka dla Unixa (Linuxa) jak wielu powszechnie uwaza.
Jest to rozproszony, potezny graficzny system sieciowy. Wiecej informacji
w man X :) No nie, jednak powiem cos wiecej.
Po pierwsze trzeba wiedziec ze Xy sa oparte na technologii klient-serwer,
ktora moze sie wydac dosyc dziwna dla osob ktore sie juz z tym styknely.
A mianowicie ze na terminalu pracuje serwer, natomiast na tym co powszechnie
wiekszosc utozsamialaby z serwerem pracuje XClient. Dla wyjasnienia posluze
sie odpowiednim przykladem.

Jestem na komputerze lamebox.com.pl. Mam przed soba X okienka. Telnetuje sie
na maszyne lamer.chaker.zgroza.pl. Ustawiam sobie wtedy zmienna

DISPLAY=lamebox.com.pl:0.0 (dla przykladu, ale tak jest najczesciej).

I odpalam jakis program Xowy, np. xpaint. I co sie dzieje ?
Na lamebox pojawia sie okienko z xpaintem ! Tym, ktorzy jeszcze na to nie
wpadli uprzejmie wyjasniam ze xpaint jest w tym przypadku xclientem.
Chetnym wyprobowac ten przyklad przypominam ze na lamebox trzeba najpierw
uruchomic program xhost i dodac do niego maszyne lamer.chaker.zgroza.pl.

I to jest caly power X-ow, takie proste, a takie potezne. Na przyklad na
Sun Enterprise 10000 odpalam netscape, a na kompie klasy 386DX pojawia sie
okienko z mozilla pracujaca z sila wodospadu. Na Sunie pracuje xclient,
na 386 xserwer.

Teraz podam kilka ciekawostek, ktore byc moze zburza pare mitow.

Pierwsza ciekawostka to taka ze ani X-client, ani X-serwer nie musza byc
programami unixowymi. Jest kilka serwerow X dla DOS, Windows, Macintoshy,
zarowno komercyjnych jak i pol-darmowych. Jednym z bardziej znanych jest
XAppeal, ale nie jest jedyny. Tak samo X klienci. Podobno (nie widzialem
zadnego, ale musze kiedys poszukac) jest nawet xclient dla Windows !
Bardzo fajne, odpalam np. M$Worda i pracuje sobie na nim na zupelnie innej
maszynie.

Druga ciekawostka to taka, ze X-y nie definiuja interfejsu uzytkownika.
Natomiast mozna sobie na nich taki interfejs zbudowac. Jest cos takiego
jak Window Manager, xclient ktory zarzadza okienkami. To on jest
odpowiedzialny za wyglad np. ramek, przyciskow, itp. - a nie XSerwer.
Oznacza to ze mozemy sobie dowolnie wybierac pomiedzy naszymi ulubionymi
okienkami. Sa rozne window managery, najbardziej znane to olwm (Open Look
Window Manager ktory jest produktem Suna), mwm (Motif Window Manager),
fvwm95 (a la W95) i jeszcze kilka (twm, enlightenment i jeszcze jakis co
do zludzenia przypomina W95, ale zapomnialem jak sie nazywa). W kazdym razie
jest ich wiele.
Krotki komentarz nalezy sie rowniez KDE - ktory jest nie tylko wm'em, ale
wspanialym desktopem. Czym to sie rozni ? Otoz desktop to caloksztalt,
file manager, integracja wszystkiego, a nawet specjalne API dla
programistow, ktorzy - jesli chca wykorzystac mozliwosci danego desktopu -
moga np. spowodowac wywolanie okienka z helpem. KDE jest za darmo, po
_polsku_, polecam jego sciagniecie.

/* Commment by Bohdan R. <ethanak@free.com.pl> */
Dodatkowo: amiwm, oferujacy rowniez bezbolesne przejscie z Amiga Workbench,
zachowuje sie pratkycznie tak samo, nawet wady ma te same :)


KROTKA HISTORIA X
-----------------

X powstal dawno temu w M.I.T, i po jakims czasie jego istnienia powolano
MIT CONSORTIUM ktore mialo sie opiekowac rozwojem X'ow. Pozniej prawa
autorskie MIT CONSORTIUM przekazano XConsortium ktore wniosly wspanialy
wklad w rozwoj X. XConsortium przestalo istniec w koncu 1996 roku (jak
wyczytalem z powodu odejscia wielu najwazniejszych czlonkow na emeryture)
i przekazalo swoje prawa Open Software Foundation. Wszystkie te organizacje
byly niedochodowe i nie zadaly zadnych oplat licencyjnych za swoje dzielo.
X dla Linuxa sa dzielem XFreeProject. Najlepiej wiecej informacji szukac
na: http://www.opengroup.org/x/, http://www.xfree86.com.

X FREE
------

To jest sprawa bardzo extra. Po prostu dostajemy cale Xy, z kodem zrodlowym,
dokumentacja i narzedziami gratis. Zwlaszcza dokumentacja jest extra. 
Jest instalowana w katalogu xbooks i sa to __MEGABAJTY__ tekstu, z ktorego
sie mozna dowiedziec wszystkiego. Sa tam rowniez many do X.

PROTOKOLY I STANDARDY
---------------------

Poniewaz Xy sa systemem sieciowym, wiec autorzy lubia protokoly. W zasadzie
w x-ach jest wiele protokolow-standardow. Najwazniejszy to oczywiscie 

X Protocol.

Jest to protokol ktorym XClient dogaduje sie z XSerwerem. Wiecej informacji
bedzie w czesci II.

O innych standardach mozna sie dowiedziec w "man XStandards". Sa tam m.in.
protokoly obslugi bitmap, fontow, komunikacji miedzy klientami, obslugi
wejscia, klawiatury, protokol rozszerzen Xserwera, protokol XWindow Manager
i rozne inne. 

Warto tez poczytac o XDM (protokol XDCMP), oraz o rstartd czyli zdalnym
uruchamianiu programow X-owych.


NAJNOWSZE X
-----------

Czyli Broadway. Nie wiem dlaczego o nim tak cicho (moze ja slabo slucham).
Glowne zmiany to wprowadzenie protokolu do obslugi nisko-przepustowych lacz,
czyli ni mniej ni wiecej tylko X-y przez modem. Innym niezmiernie waznym
rozszerzeniem jest integracja X z WWW. Autorzy na swojej stronie
(zajrzyjcie na www.opengroup.org/x/, tam bedzie odnosnik) pokazali demonstracje tej 
techniki. Jest tam mianowicie pare pluginow, ktore trzeba wczytac do netscape
i mozna zagrac w szachy z BigBlue.

Ciekawa rzecza na ktora sie natknalem jest standard PEX5. Jak zobaczylem
plik naglowkowy <X11/PEX5/PEXlib.h> to mnie zamurowalo. 100 kb deklaracji,
a wszystko to do obslugi grafiki 3D przez XServer. Dokumentacja prezentuje
sie jeszcze ciekawiej, zachecam do lektury w xbooks. Polecam w tym celu
Ghostview, no chyba ze macie duzo papieru (tak z tone :)).


To by bylo na tyle. W nastepnej czesci bedzie o Xprotokole, Xlib,
Xtoolkitach, Motifie, OpenLook, Athena Widgets, Xaw3d, xforms oraz jak
nauczyc sie robic dzialajace okienkowe programy w tydzien. Albo w dwa dni,
zalezy ile kto spi :)

code


                        XWindow dla opornych, cz II

	No dobra, czas przejsc do spraw praktycznych, czyli jak szybko sie
nauczyc programowac w X-ach.

X-protocol
----------

	Mam nadzieje ze rozumiecie idee X'ow i cos wyniesliscie z
I-ej czesci. Podstawa calego systemu jest X-protocol, jezyk w ktorym
"dogaduja sie" X-clienci z X-serwerem. Nie bede go tutaj szerzej opisywal.
Mozecie sobie jednak wyobrazic analogie z procesorem. X-protocol 
porownuje sie z kodem maszynowym, czystymi liczbami szesnastkowymi.
Asemblerem jest biblioteka Xlib o ktorej za chwile. Jezykami wysokiego
poziomu sa X-toolkity o ktorych na koncu. Od razu widac, ze programowanie
w czystym X-protocole - chociaz mozliwe - jest trudne i bez sensu. Jedyne
co potrzeba zeby napisac program dla Xow dzialajacy na zasadzie Xprotokolu
to jakas implementacja TCP/IP w jakimkolwiek systemie operacyjnym. Po
prostu laczycie sie z serwerem i slecie rozne szesnastki :)
Tak na powaznie jedyne co warto wiedziec o tym protokole jest to ze jego
podstawa sa tzw. requesty. X-client wysyla np. request narysowania 
okienka - i serwer rysuje okienko. Sa rozne requesty, jak widac request
dziala w strone od clienta do servera. W druga strone sa eventy. Event jest
wtedy jak sie cos stanie po stronie serwera, np. user kliknie myszka albo
nacisnie klawisz. Oprocz eventow i request sa jeszcze errory. Error jest
wtedy jak cos serwerowi nie wyszlo, np. nie mial pamieci do narysowania 
okienka. Jest jeszcze cos czwarte, ale zapomnialem co. Nevermind.

No dobra, uproszczony schemat dzialania programu Xowego mozemy juz
przytoczyc. Niech to bedzie program, ktory bedzie pokazywal okienko,
na ktorym bedzie napisane "Lamer", a potem bedzie czekal az user nacisnie
enter zeby zmazac okienko.

1. Nasz program - Xclient - wysyla request do serwera OpenDisplay. To jest
zawsze pierwszy request. Potem czeka na odpowiedz, jesli nie bedzie
odpowiedzi to sie wysypie z napisem "cannot open display". To jest
standardowy komunikat ktory wkurza wszystkich lamerow, mysla wtedy ze 
to jest cos w rodzaju "core dumped". Madrzejsi juz wiedza, ze trzeba wtedy
ustawic zmienna DISPLAY (np. set DISPLAY=lamer.lamenet.com.pl:0.0).

2. Zalozmy ze sie udalo, czyli program polaczyl sie z serwerem. To teraz
wysyla request CreateWindow (zgadnijcie po co). Teraz jeszcze okienka nie
widac. Potem OpenFont (czy jakos tak), potem rysuje w tym okienku napis.
Potem MapWindow (chyba). Pewnie nie wiecie po co to Map. Otoz po zrobieniu 
CreateWindow serwer owszem, utworzy okienko, ale niewidzialne. Zeby je
pokazac trzeba wlasnie zrobic MapWindow. Zeby schowac, trzeba je odmapowac
(UnmapWindow).

3. To byly caly czas requesty. W tej chwili mamy na ekranie okienko z
napisem. Program przechodzi wiec w faze nasluchiwania eventow, czy czasem
user nie nacisnie entera. Nasluchiwanie eventow jest banalne:

do {
 event = ListenForEvent();
 switch (event) {
  case ...
 }
} while (event != kb_enter)

Oczywiscie to by sie wam nie skompilowalo, ale mam nadzieje ze kumacie.

4. User nacisnal enter, program dostal event, teraz wiec usuwamy okienko
i konczymy zabawe.

X-lib
-----

Czyli ten asembler. Ma ona postac zwyklej biblioteki C. Czyli zeby napisac
program dla X przy uzyciu Xlib potrzeba nam tak:

1) Checi ;-)
2) Kompilator C
3) Xlib (zatem musi to byc Unix, np. Linux, albo jakis system w ktorym jest
Xlib, w praktyce nie widzialem zadnej implementacji Xlib na cos innego).
Dalej wiec bede mowil o Linuxie i o X-ach dla Linuxa - XFree.


Musimy w tym celu wlaczyc odpowiednie naglowki. Siedza one w 
/usr/X11/include/. Kompilator zreszta powinien znac sciezki, wiec w 
programie wystarczy zeby bylo:

#include <X11/X.h> /* np. X.h - opis X-protokolu */

Program nalezy skompilowac:
gcc -L/usr/X11/lib -lX11 -o gowno gowno.c 

-L musi byc jezeli sa problemy z odczytywaniem tych bibliotek (cos skopane
w konfiguracji ldconfig). 
-lX11 - to oznacza ze kompilator ma wlaczyc biblioteke libX11.so, ktora
wlasnie jest biblioteka Xlib.

Programowanie w Xlib jest problematyczne, a mowiac dosadnie - pojebane.
W jakims podreczniku do X-ow program okienkowa wersja "hello world" napisana
dla Xlib zajmowala 3 strony ! 

O Xlib warto wiedziec to, ze czasem sie jej uzywa jak trzeba zrobic cos
niestandardowego. Standardowo robi sie okienka, przyciski, czyli w ogole
GUI. Z Xlib korzysta sie wtedy gdy chcemy np. narysowac kreske w okienku.
Xlib jest zbudowana w ten sposob ze jej funkcje to sa w zasadzie
odpowiedniki requestow. Po prostu typowa funkcja Xlib pobiera argumenty,
pakuje je do bufora i sle do serwera. Jest jeszcze taka sprawa, ze requesty
sa buforowane. To znaczy wywolacie np. 5 funkcji Xlib i nic do serwera wam
nie dojdzie. Dlaczego ? Trzeba ten bufor oproznic (flush). Flush bufora
nastepuje w 4 przypadkach:

1) Jest przepelnienie
2) Wywolalismy funkcje Flush cos tam
3) Wywolalismy jakas funkcje ktora czeka na argument
4) cos tam jeszcze


X-toolkit's, Intrinsics
-----------------------

To jest to od czego nalezy rozpoczac nauke programowania w X-ach. Jest to
biblioteka, podobnie jak Xlib, oparta na zasadach programowania obiektowego.
Pojeciem kluczowym jest widget. Widget jest to obiekt przedstawiajacy soba
jakis element GUI, np. przycisk, lista, itp. Xtoolkit (zawarty w bibliotece
libXt.so, wiec trzeba kompilowac z opcja -lXt) mozna podzielic na dwie
czesci: jedna przeznaczona dla projektantow bibliotek, tworcow widgetow,
czyli ta ktora was nie obchodzi. Druga jest dla programistow-uzytkownikow.
Xtoolkit ma taka przyjemna wlasciwosc ze jest jakby nadwarstwa. Po prostu 
niezaleznie jakiego toolkitu uzywacie, Atheny, Motifa czy czegokolwiek
programuje sie w ten sam sposob i uzywa sie tych samych procedur. 

Athena widgets, Xaw3d
---------------------

Athena widgets to zestaw widgetow opracowanych na potrzeby XtIntrinsics
(czyli Xtoolkit) w ramach Project Athena. Byl to chyba pierwszy toolkit
dla X, jest dostepny za darmo i dostarczany bezplatnie z kazda dystrybucja
Xow. Jest w bibliotece  libXaw.so (jak sie domyslacie trzeba kompilowac
-lXt -lXaw). Jego charakterystyczna cecha jest to, ze jest okropnie brzydki,
te przyciski i w ogole wyglad interfejsu jest tak dretwy ze mozna sie 
poplakac. Rozwiazaniem na to jest Xaw3d. Athena Widgets 3D to ladny, mily,
kolorowy xtoolkit majacy te przyjemna ceche ze jest calkowicie zgodny z 
Xaw. Programuje sie go zatem tak samo. Jedyne co trzeba zrobic to zamienic
libXaw.so na libXaw3d.so, albo wrecz fizycznie przemianowac ten plik. Wtedy
wszystkie aplikacje Atheny beda ladne i kolorowe.

Motif
-----

To bardzo znany produkt OSF. Sklada sie z Xtoolkitu, Motif Window Managera
(mwm), FileManagera. Jest dobry ale ma ewidentna wade - nie jest za darmo.
Jest inicjatywa FSF (free software foundation - powinna sie wam kojarzyc),
nazywa sie lesstif. Teraz rozwijaja go - zdaje sie - Hungry Programmers.
Calkiem spoko.

OpenLook
--------

To sa widgety i window manager (olwm) Suna. Nie wiem jak jest z licencjami,
programy najczesciej z tego nie korzystaja. 

Jak sie w tym programuje
------------------------

Podstawa jest XtIntrinsics czyli to co jest w Intrinsic.h. Nie wdajac sie 
zbytnio w szczegoly pokaze wam wersje hello world dla Atheny:

/* xwhello.c by Codematic 11.1997 */

#include <X11/Intrinsic.h>
#include <X11/StringDefs.h>
#include <X11/Xaw/XawInit.h>
#include <X11/Xaw/Box.h>
#include <X11/Xaw/Command.h>

static Arg args[10];

Widget main_widget, form_widget, hello_message, exit_button, op_button;

static void FuncQuit(Widget w,caddr_t client_data,XtPointer p)
{
 XtCloseDisplay(XtDisplay(w));
 exit(0);
}

void setup_main_widgets()
{
 form_widget = XtCreateManagedWidget("Form", boxWidgetClass, main_widget, 
   NULL, 0);
 
 XtSetArg(args[0],XtNlabel,"OK");              
 exit_button = XtCreateManagedWidget("Exit",commandWidgetClass, form_widget, 
  (ArgList) args, 1);

 XtSetArg(args[0],XtNlabel,"Wyjscie");              
 op_button = XtCreateManagedWidget("Op",commandWidgetClass, form_widget, 
  (ArgList) args, 1);  
 XtAddCallback(op_button,"callback",(XtCallbackProc) FuncQuit,NULL);
}

void main(int argc, char **argv)
{
 main_widget = XtInitialize(argv[0], "XMHello",NULL,0,&argc,argv);
 XtSetArg(args[0],XtNheight,200);
 XtSetArg(args[1],XtNwidth,100);
 XtSetValues(main_widget, args, 2);

 setup_main_widgets();
 
 XtRealizeWidget(main_widget);
 XtMainLoop();
}

Co to cos robi ? Opisze krok po kroku. Nie bede analizowal wszystkich 
parametrow, jak czegos nie wiecie to man "nazwa funkcji".

Najpierw deklarujemy glowny widget aplikacji, "krol" wszystkich widgetow.
Poniewaz widgety sa obiektowe, wiec jest tu zachowana hierarchia drzewiasta.
Po prostu kazdy widget moze miec swojego rodzica (parent) lub dzieci.
XtInitialize jest pierwsza funkcja wywolywana przez program korzystajacy
z Intrinsics. Argumenty chyba rozumiecie, jak nie to man.

XtSetArg jest podstawowa funkcja uzywana do konfigurowania widgetow.
Chodzi o to ze kazdy widget ma swoje parametry. Sa one najczesciej ustawiane
defaultowo i odpowiadaja roznym wlasciwosciom obiektow na ekranie (np. kolor
przycisku, tlo, tekst, itp). Zeby konfigurowac widgety deklarujemy sobie
tablice odpowiednia duza elementow typu Arg. Potem te elementy ustawiamy
XtSetArg. A na koncu robimy XtSetValue podajac jako parametry ta tablice
oraz widget ktory chcemy skonfigurowac. Parametry widgetu sa identyfikowane
poprzez stringi; XtNheight, XtNwidth sa to stale - lancuchy znakow.
Jak widac ustawiamy w ten sposob dlugosc i szerokosc okienka.

Potem jest setup_main_widgets. O tym dalej.

XtRealizeWidget wyswietla wam to wszystko na ekranie i w ogole uruchamia
cala maszynerie.

XtMainLoop to glowna petla, zawsze jako ostatnia wywolana powoduje ze
wszystko ladnie dziala.

Co sie teraz dzieje w setup_main_widget ? Jak mogliscie zauwazyc i/lub
domyslic sie programowanie w Xtoolkicie jest podobne do budowania wiezy 
z klockow. Po prostu dodajemy widgety do hierarchii, konfigurujemy je
i puszczamy petle. No i dodajemy, no wlasnie, callbacki. Callback jest
funkcja ktora jest parametrem widgetu, jest wywolana kiedy user cos 
zadziala. Np. dla przycisku jest definiowany callback, ktory jest generowany
jak user nacisnie "OK". Domyslnie nie ma zadnego callbacka, widget po prostu
nie reaguje. My mozemy dodawac wlasne akcje. Jeden widget moze miec
oczywiscie wiele callbackow.

Na poczatku dodajemy form_widget typu boxWidgetClass. Jest on pojemnikiem,
po prostu polem na okienku na ktorym dodajemy nowe widgety. Widgety tworzy
sie funkcja XtCreateWidget, jednakze potem trzeba nimi zarzadzic - 
XtManageWidget. DLa prostoty wiec uruchamiamy XtCreateManagedWidget ktora
robi obie rzeczy naraz. Potem dodajemy dwa buttony. Jak widzicie dodajemy 
je juz nie do main_widget tylko do form_widget - on jest rodzicem.
Ustawiamy w nich parametr XtNlabel - czyli tekst na klawiszu. Do ostatniego
buttona dodajemy callback funkcja XtAddCallback ktora konczy cala zabawe. 
Jak widzicie jest to banalne.

W praktyce robi sie tak. Otwiera sie jedna konsole ze swoim programem,
druga do mana a trzecia z shellem w ktorym biezaca sciezka jest
/usr/X11/include/Xaw/ (albo Xm/ dla Motifa). Potem myslimy co ma byc w tej 
aplikacji wiec wybieramy widgety. Kazdy widget ma swoj wlasny plik 
naglowkowy, np. Box. Tam sa takie fajne opiski parametrow kazdego widgetu,
nie trzeba szukac po manach zeby wiedziec ze tekst na buttonie to XtNlabel.
Sa tam tez #define'y takie jak XtNlabel, ktore ulatwiaja programowanie.
Zamiast XtNlabel mozna bowiem napisac "label", ale po co. Oprocz kazdego
parametru jest jego wartosc domyslna, typ i klasa. To wszystko jest w 
takiej fajnej tabelce.

Motifa programuje sie w zasadzie tak samo, tyle ze ma wiecej widgetow i
inaczej sie nazywaja. Zasada jest ta sama. 

HINT: jesli chcecie sie nauczyc dokladniej zapraszam do lektury kodu gierki
xbill, szczegolnie pliki widgets.h, widgets.c, athenawidgets.c,
motifwidgets.c (sorki jak sie pomyslilem, ale jakos tak). Tam jest bardzo
fajnie zrobiony interfejs do Motifa i Atheny, takze te zestawy mozna sobie
wybrac przy kompilacji. Zobaczcie jak tam to autor zrobil.

X-forms
-------

To jest fajna sprawa. Autorzy omineli cala maszyne Xtoolkitu i napisali 
wszystko od podstaw w Xlib. Nie opisze tu jak to programowac, ale zobaczcie
przyklady w /usr/doc/xforms. Sa naprawde za*******. Calosc ma tylko jeden
plik naglowkowy "forms.h" i do tego jest dolaczony wizualny generator
fdesign. Potrafi on stworzyc kod w c wiec formsy moga byc naprawde szybkim
sposobem na programowanie w X. Zaleta widgetow jest jednak to ze sa bardziej
popularne.

No to by bylo na tyle. Mam nadzieje ze doszliscie do konca.
Codematic.



 /*
  * 3. Motif X Window Programming HOWTO PL - Przemek Borys
  */
+++++++++++++++++++++++++++++++++++
===================================
Motif X Window Programming HOWTO PL
===================================
+++++++++++++++++++++++++++++++++++

Motif X window programming HOWTO PL

(c) 1998 Przemek Borys
Konsultacja - Codematic 

Literatura:
Motif workshop Seana Butlera
/usr/X11R6/man/man3
Dokumentacja lessdox
Przykłady z katalogu testowego lesstifa
Pliki nagłówkowe lesstifa
Specyfikacja Xlib - C Lanugage
Kody źródłowe różnych programów

*****
Przedwstęp

    Teoretycznie, tekst ten opisuje programowanie pod motifa, lecz w
rzeczywistości, przedstawione tu techniki programowania są identyczne w 
każdej bibliotece widgetów (powtarzam - widgetów - bo są też biblioteki 
obiektowe). Trzeba do szczęścia znać po prosto kilka strategicznych funkcji
z pakietu Xtoolkit (standardowo dostarczany z X-ami) na krzyż i już.
Opisy poszczególnych widgetów dla każdej biblioteki widgetów (jeśli 
brakuje dokumentacji) można znaleźć w plikach nagłówkowych.

*****
Wstęp

    Męczę się już z programowaniem pod X-y od jakiegoś czasu. Nie ma nigdzie
niestety odpowiednich podręczników, czy choćby tutoriali w sieci. Tzn. są,
ale mówią tyle co nic. Dlatego teraz uszczęśliwię świat pierwszym polskim 
HOWTO o programowaniu pod X Window System.

    Programowanie to zademonstruję na najwyższym poziomie pisania aplikacji - 
na poziomie biblioteki GUI. Jest wiele bibliotek GUI dla X-ów, np. XForms 
(darmowa biblioteka z wizualnymi narzędziami), qt (biblioteka przypominająca
mi OWL Borlanda - tj. zbiór różnych użytecznych klas zawierających 
najważniejsze narzędzia - też darmowa), Athena (darmowa biblioteka widgetów 
(co to jest widget napiszę dalej) - standardowo dostarczana w dystrybucjach 
X-ów - ma swoje odmiany: Xaw - zwykła (brzydka) Athena, Xaw3d - Athena z 
trójwymiarowymi obiektam, Xaw95 - klon GUI z Windows95).

    Jednak Open Software Foundation wylansowała zupełnie inną bibliotekę, 
która króluje obecnie wśród programów pisanych pod X-y. Jest nią Motif. 
Niestety nie jest darmowy - kosztuje ok 100$. Na szczęście jednak, niedawno 
(jesień 1995) powstał darmowy klon motifa - lesstif. Ma on pewne wady 
(m.in jest zaimplementowany na niewielu /w porównaniu z oryginalnym motifem/
platformach - różne unixy i OS/2), ale ogólnie nadaje się do użytku.

    Jeszcze jedno - na końcu tego tekstu znajduje się przykładowy programik
pod motifa - jeśli należysz do tych osób, które lubią widzieć najpierw kod,
potem teorię, to informuję cię o jego istnieniu :)

*****
Filozofia systemu X

    System X-ów jest odmienny niż to co znamy z firmy M$. Jest to system w 
pełni sieciowy - co za tym idzie, może być w dużej mierze niezależny od 
sprzętu.

    X-y również nie oferują standardowo takich obiektów, jak suwaki,
guziki, menu itd. Tego w podstawowym API (czyli bibliotece Xlib) nie ma. 
Zamiast tego, w X-ach postawiono na inną filozofię - na widgety. Widgety to 
tak jakby klasy definiujące określone obiekty. (np. guzik, suwak, tabela,
pole tekstowe, itd.) Dobre jest to, że można definiować własne widgety.

    Będąc przy opisie widgetów, muszę jeszcze powiedzieć, czym one się 
charakteryzują. Widgety mają dwie (patrząc z mojego obecnego zaawansowania) 
własności - mają definiowalne zasoby (resources), oraz callbacki.

    Zasoby to takie rzeczy, jak np. kolor, współrzędne obiektu na ekranie,
jego szerokość, wysokość, sposób buczenia (jeśli takowy istnieje), itd. 
Słowem, są to zależności, określające właściwości obiektu.

    Callbacki określają akcje na zdarzenia, na jakie reaguje widget. Np. 
guzik można nacisnąć, co spowoduje wywołanie takiej a takiej funkcji, itd.

    Na koniec, muszę jeszcze powiedzieć, że widgety w aplikacji są zawsze
uporządkowane hierarchicznie. Każdy widget ma swój widget macierzysty, oraz
(opcjonalnie) swoje własne potomstwo. Np. taka aplikacja:

      ______________________
     |-|    aplikacja   |%|.|
     |   _box______         |
     |  |          |        |
     |  | [guzik1] |        |
     |  | [guzik2] |        |
     |  |__________|[guzik3]|
     |______________________|

Będzie miała następującą strukturę widgetów:
                                               /-guzik3
    Okno główne<-aplikacja<-tablica ogłoszeń<-+
                                               \        /- guzik1
					        \-box<-+
                                                        \- guzik2

[!uwaga: poniższy fragment piszę w oparciu o moją niepełną wiedzę z zakresu
xlib'a]

Gdzie "Okno główne", to okno, w którym są uruchamiane aplikacje (window
manager), "aplikacja", to widget aplikacji (nie posiadający konkretnej
reprezentacji na ekranie), "tablica ogłoszeń", to taki specjalny widget 
(nazywa się BulletinBoard), który jest po prostu "tablicą ogłoszeń", czyli 
pustą planszą, na której można coś ustawiać - w naszym konkretnym wypadku 
ustawiamy na nim guzik3, oraz ramkę "box", a w tej ramce "box" tworzymy 
dwa guziki.

[właściwie niektóryzy powiedzą, że to nie do końca tak, ale widget jest dość
płynnym pojęciem]

*****
Parę funkcji i zmiennych.

    Na cóż by się zdało to HOWTO, jeśli bym nie poruszył tego tematu. Zacznijmy 
od zmiennych. Jednym z najważniejszych typów w programowaniu pod X-y jest typ
"Widget". Zmienne tego typu identyfikują potem wszelkie widgety, jakie tylko
zdefiniujemy sobie na ekranie. Np. deklaracja:

Widget aplikacja, guzik;

po odpowiednim zainicjalizowaniu (o czym będzie dalej), stworzy nam
"deskryptory" dwóch widgetów - np. widget "aplikacja" możemy zainicjalizować
tak by był widgetem /obiektem/ aplikacji, a widget "guzik"  możemy 
zainicjalizować tak, by był guzikiem na ekranie.

    Widget aplikacji (czyli ten najwyższy z którym coś można robić),
inicjalizuje się w następujący sposób, korzystając z funkcji 
XtVaAppInitialize o prototypie:

       Widget XtVaAppInitialize(app_context_return, applica-
       tion_class, options, num_options, argc_in_out,
       argv_in_out, fallback_resources, ...)
             XtAppContext app_context_return;
             String application_class;
             XrmOptionDescRec* options;
             Cardinal num_options;
             int* argc_in_out;
             String* argv_in_out;
             String* fallback_resources;

Gdzie "app_context_return", to zmienna typu "XtAppContext", która zostanie
załadowana kontekstem nowo utworzonej aplikacji, "application_class" oznacza
nazwę zasobu aplikacji. (dzięki której będzie można konfigurować z poziomu
pliku .Xdefaults wszelkie widgety aplikacji). Dalsze parametry:
"options" zawiera tablicę określającą akcje na podane w command-line
argumenty. Tablica ta składa się z rekordów w postaci:

typedef struct {
    char            *option;        /* Option abbreviation in argv*/
    char            *specifier;     /* Resource specifier*/
    XrmOptionKind   argKind;        /* Which style of option it is*/
    XPointer        value;          /* Value to provide if XrmoptionNoArg*/
} XrmOptionDescRec, *XrmOptionDescList;

Gdzie string "option" określa opcję podawaną w command-line, np. "-help",
jeśli program wywołujemy właśnie z takim parametrem, "specifier" określa,
który z zasobów będzie modyfikowany, "argKind" mówi, jaki jest format tej
opcji podanej w command-line (może być format "opcja argument", lub po
prostu "opcja" itp.) Można użyć jednego z następujących określeń:

typedef enum {
    XrmoptionNoArg,     /* Value is specified in OptionDescRec.value*/
    XrmoptionIsArg,     /* Value is the option string itself*/
    XrmoptionStickyArg, /* Value is characters immediately following option*/
    XrmoptionSepArg,    /* Value is next argument in argv*/
    XrmoptionResArg,    /* Resource and value in next argument in argv*/
    XrmoptionSkipArg,   /* Ignore this option and the next argument in argv*/
    XrmoptionSkipLine,  /* Ignore this option and the rest of argv*/
    XrmoptionSkipNArgs  /* Ignore this option and the next                           OptionDescRes.value arguments in argv */
} XrmOptionKind;

Kolejny parametr funkcji XtVaAppInitialize, "num_options", określa ile
wpisów jest zrobionych w powyższej tablicy z opcjami. Parametry
"argc_in_out" oraz "argv_in_out" okeślają argumenty funkcji main(int
argc,char *argv[]). Ostatni parametr - "fallback_resources", określa zasoby,
z jakich korzystać, gdy nastąpi błąd w tworzeniu kontekstu aplikacji. (można
zostawić jako NULL).

Oto przykład inicjalizacji aplikacji powyższą funkcją:

-----
Widget aplikacja;
XtAppContext kontekst_aplikacji;

aplikacja=XtVaAppInitialize(&kontekst_aplikacji,"zasob_aplikacji",
                            NULL,0,
                            &argc,argv,
                            NULL,NULL);
-----

    Po utworzeniu widgetu aplikacji, zazwyczaj następuje konstrukcja widgetów
podrzędnych, oraz ich powiązań (tj. np. wciśnięcie guzika powoduje otwarcie
dialogu, itp.). Po zakończeniu tych wszystkich definicji, pod koniec programu
uruchomiamy tą naszą całą konstrukcję. Jak to robimy? Uruchomiamy po prostu
najbardziej nadrzędny widget (powyżej był to widget "aplikacja"). Robi się
to funkcją 

XtRealizeWidget(Widget)

Np:

-----
    XtRealizeWidget(aplikacja)
-----

Istnieje też funkcja podobna do tej, która nazywa się 

void XtManageChild(Widget)

    Po uruchomieniu struktury, mamy jednak jeszcze pewien problem. Załóżmy,
że cała nasza konstrukcja widgetów się wykona (np. użytkownik wciśnie guzik 
i wykona się cały ciąg akcji, w ten sposób, że już żaden widget nie 
pozostanie do wykonania). Nasz program się wtedy zakończy. Zazwyczaj nie jest 
to pożądane, więc stosuje się następującą funkcję:

void XtAppMainLoop(XtAppContext)

Czyli, posługując się zmiennymi z przykładu do funkcji "XtVaAppInitialize",
może to wyglądać w praktyce np. tak:

-----
    XtAppMainLoop(kontekst_aplikacji);
-----

Zpętli nam to strukturę widgetów na zawsze (chyba, że umyślnie zakończymy
program np. standardową funkcją "exit", lub korzystając z menu systemowego
okienka). Teraz już nasz hipotetyczny program z guziczkiem nie zakończy
działania po jego wciśnięciu.

*****
Tworzenie widgetów i callback'ów

    Wśród tego całego ględzenia, nie powiedzieliśmy sobie jeszcze, jak 
utworzyć widget i jak sprawić, by wywoływał on jakąś akcję (np. wciskany 
guzik).

    Widgety tworzymy bardzo prosto, korzystając z rodziny funkcji 
XtCreateWidget - najuniwersalniejsza jest chyba XtVaCreateManagedWidget
(tworzy ona widget, na którym od razu wywołuje się funkcję
"XtRealizeWidget", tak że później nie trzeba już ręcznie tego widgetu
uruchamiać):

       Widget XtVaCreateManagedWidget(name, widget_class, parent, ...)
             String name;
             WidgetClass widget_class;
             Widget parent;

Gdzie "name" określa nazwę zasobu (do którego potem można się dostać w pliku
~/.Xdefaults lub ~/.Xresources, np. w następujący sposób (np. gdy 
name="zasob"):

aplikacja*zasob.fontList: -*-helvetica-bold-r-*-*-17-*-*-*-*-*-*-*

Gdzie "aplikacja" to specyfikator zasobu, ustalany w funkcji
"XtVaAppInitialize".

Dalsze parametry "XtVaCreateManagedWidget", to "widget_class" - który
określa klasę widgetu (tzn. to, czy jest on guzikiem, menu, scrollbarem, czy
jeszcze czymś innym, "parent" określa "rodzica" - widget nadrzędny nowo
tworzonego widgetu, a wielokropek umożliwia przedefiniowywanie zasobów (o
tym poniżej). Teraz przykład utworzenia widgetu:

-----
Widget guzik;

guzik=XtVaCreateManagedWidget("wcisnij",xmPushButtonWidgetClass,
                                aplikacja,
                                XmNx,10,
                                XmNy,5,
                                NULL);
-----

    Co tutaj się dzieje? Tworzymy widget o nazwie zasobu "wcisnij", należący 
do klasy "xmPushButtonWidgetClass" (czyli guzik do wciskania), który jest 
potomkiem widgetu aplikacji (co niesie za sobą specjalne własności,
konkretnie potomkowie tego widgetu są samodzielnymi oknami), i który ma 
przedefiniowane  dwa zasoby położenia - XmNx  współrzędna x) - ustawiony 
na 10, i XmNy (współrzędna y) - ustawiony na 5. Można w tej funkcji 
przedefiniowywać dowolnie wiele zasobów - a gdy przedefiniujemy co 
potrzebowaliśmy, na koniec zwyczajnie dodać NULL. Np. gdybym chciał ten sam 
guzik zrobić dodatkowo z określoną szerokością,  to definicja wyszłaby tak:

-----
guzik=XtVaCreateManagedWidget("wcisnij",xmPushButtonWidgetClass,
                                aplikacja,
                                XmNx,10,
                                XmNy,5,
                                XmNwidth,40,
                                NULL);
-----
   
    Poza tą metodą ustawiania argumentów, można je ustawiać też później, po
utworzeniu widgetu. Służy do tego funkcja "XtSetArg" oraz "XtSetValues".
"XtSetArg" działa następująco:

       XtSetArg(arg, name, value)
             Arg arg;
             String name;
             XtArgVal value;

Ustawia zmienną "arg" (którą później przekazuje się do "XtSetValues"), tak
że zmienna ta określa ustawienie zasobu "name" na "value". Np:

------
Arg arg[1];
//...
XtSetArg(arg[0],XmNx,10);
------

Po załadowaniu tablicy argumentów (w przykładzie "arg"), korzystając z
funkcji "XtSetValues", włączamy je do widgetu.

       void XtSetValues(w, args, num_args)
             Widget w;
             ArgList args;
             Cardinal num_args;

"w" określa tutaj widget, którego zasoby ustawiamy, "args", to tablica
argumentów, ustawiona przez "XtSetArg", a "num_args", to liczba argumentów w
tablicy "args".

    To jeszcze nie wszystko jeśli chodzi o tworzenie widgetów. Nie całkiem. 
Teoretycznie wszystkie możliwe widgety można skonstruować w taki sposób. 
Jednak czasem po prostu szkoda czasu. Dlatego większość widgetów posiada 
swoje funkcje publiczne, które umożliwiają szybkie tworzenie "wyrafionowanych" 
widgetów. I tak, np. menu można stworzyć, korzystając z widgetu "tabelki" 
(klasa XRowColumn), korzystając z funkcji np.

   Widget XmCreateMenuBar(Widget Parent,char *Name,Arg *arglist,
				Cardinal count)

itd. (patrz Lessdox, choć jeśli chodzi o tworzenie menu, to wrócę jeszcze do
tego na końcu).


    Zostało nam jeszcze definiowanie callback'ów. Callbacki określają nam, 
jakie funkcje mają być wywoływane, gdy widgetowi przytrafi się określone 
zdarzenie. Np. ustawmy callback, powodujący zakończenie programu pod widget
wyżej zdefiniowanego guzika. Callbacki ustawiamy funkcją "XtAddCallback".

       void XtAddCallback(w, callback_name, callback, client_data)
             Widget w;
             String callback_name;
             XtCallbackProc callback;
             XtPointer client_data;

Gdzie "w" określa widget, któremu nadajemy callback, "callback_name" określa
rodzaj eventu, na który reagujemy, "callback" to procedura która będzie
wywoływana jako callback w odpowiedzi na ten event, "client_data" to wskaźnik,
przekazujący procedurze callbackowej określone dane (gdy nie przekazujemy
danych, może to być NULL).
Jeszcze tylko jedna uwaga co do procedur callbackowych. Są to funkcje
następującego formatu:

-----
void funkcja_callbackowa(Widget w, XtPointer dane_klienta,
                         XtPointer dane_eventu);
-----

Parametr "w" określa tutaj widget, na którym zachodzi callback,
"dane_klienta", to omówiony przy opisie funkcji "XtAddCallback" wskaźnik
"client_data", a "dane_eventu" to dane związane z eventem, np. wskaźnik do
XmPushButtonCallbackStruct, itp. (patrz pliki nagłówkowe).

    A oto przykład ustawiania callback'u:

-----
void koniec(Widget w, XtPointer dane_klienta, Xtpointer dane_eventu)
    {
    exit(0);
    }
/*
[...]
*/

XtAddCallback(guzik,XmNactivateCallback,koniec,NULL);
-----

    Co my tutaj mamy? Pierwszy parametr funkcji, to widget, któremu 
ustawiamy callback (utworzony ostatnio guzik). Drugi, to zdarzenie, które 
wywołuje callback. W tym wypadku jest to wciśnięcie guzika. (jeśli masz
wątpliwości, sprawdź w dokumentacji lesstifa przy opisie tego widgetu) 
Trzeci parametr, to funkcja callback'owa. Żadnych specjalnych danych funkcji
callbackowej nie przekazujemy - więc ostatni parametr to NULL.

*****
Obiecany paragraf o tworzeniu menu

    Menu tworzymy bardzo łatwo. Najpierw, korzystając z funkcji
"XmCreateMenuBar", tworzymy widget paska menu. Później, korzystając z funkcji
"XmCreatePulldownMenu", tworzymy widgety, odpowiadające poszczególnym
"submenus" paska menu. Potem, mając widget submenu, tworzymy widgety jemu
potomne (np. guziki pushbutton (normalne opcje), lub kolejne widgety
submenu). Później, korzystając z widgetu tworzenia kaskady guzików 
(xmCascadeButtonWidgetClass), powodujemy, że menu fizycznie zaczyna istnieć.
Zresztą ten akurat problem ładnie jest pokazany w załączonym przykładzie.

*****
Wiemy wszystko!

    No, nie wszystko, ale z grubsza już wiadomo o co chodzi w motifie. Spis
wszystkich widgetów wraz z ich przedefinowywanymi zasobami, oraz eventami 
można znaleźć w dokumentacji (lessdox -
ftp://sunsite.icm.edu.pl/pub/Linux/Lesstif/lessdox.tar.gz). Teraz pozostaje 
nam już tylko składać (jak klocki ;) widgety i tworzyć aplikacje...
Oto przykład prostego programiku pod motifa wraz z Makefile'em.

%%%%%%% początek test.c %%%%%%%
/*
Otwieramy niezbędbe nagłówki biblioteki
*/

//Biblioteka podstawowa motifa - Xm.h
#include <Xm/Xm.h>
//Biblioteka zawierająca prototyp widgetu BulletinBoard
#include <Xm/BulletinB.h>
//Biblioteka zawierająca prototyp widgetu PushButton
#include <Xm/PushB.h>
//Biblioteka zawierająca prototyp widgetu DialogShell
#include <Xm/DialogS.h>
//Biblioteka zaiwerająca prototyp widgetu RowColumn
#include <Xm/RowColumn.h>
//Biblioteka zawierająca prototyp widgetu CascadeButton
#include <Xm/CascadeB.h>

Widget aplikacja;  			//deklaracja widgetu aplikacji
/*
deklaracja funkcji callbackowej, reagującej na guzik [koniec]
funkcja ta tworzy dialog, w ktorym sie pyta czy naprawde chcesz zakonczyc
aplikacje
*/
void Wyjscie(Widget w, XtPointer dane_klienta, XtPointer dane_eventu);

/*
deklaracja funkcji callbackowej, wywoływanej z dialogu funkcji wyjscie
*/
void ZakonczProgram(Widget w, XtPointer dane_klienta, XtPointer dane_eventu);

void main(int argc, char *argv[])
	{
	/*
	Deklaracje widgetów. Poszczególne widgety będą:
	
	guzik_wyjscia - będzie widgetem guzika [koniec]
	shell - będzie planszą okna programu
	pasek_menu - będzie paskiem menu
	podmenu - będzie to submenu dla jedynej zdefiniowanej opcji paska menu
	podpodmenu - będzie to submenu, wywoływane z widgetu podmenu
	kaskada1 - będzie to wizualny obraz podmenu
	kaskada2 - będzie to wizualny obraz podpodmenu
	opcja1 - będzie to opcja 1 w podmenu
	opcja2 - będzie to opcja 3 w podmenu
	opcja3 - będzie to opcja w podpodmenu
	
	Wizualnie aplikacja będzie wyglądać tak:
	 __________________             _______________
	|-|____________|%|.|           |-| Koniec? |%|.|
	|[pasek menu]      |	       |               |
	|[opcja1      ]    |           | [tak]   [nie] |
	|[podpodmenu >][opcja3]        |_______________| (to okienko po
	|[opcja2      ]    |				  wciśnięciu guzika
	|                  |				  [koniec])
	| [koniec]         |
 	 ~~~~~~~~~~~~~~~~~~
	
	*/
	
	Widget guzik_wyjscia, shell;
	Widget pasek_menu,podmenu,podpodmenu,okno_dla_menu;
	Widget kaskada1,kaskada2,opcja1,opcja2,opcja3;

	XtAppContext kontekst_aplikacji; //deklaracja kontekstu aplikacji

	/*
	Zadeklarowanie zmiennej typu XmString. W celu nadania nazwy (tej 
	widzianej przez użytkownika) guzikowi [koniec]. Właściwie, nie jest to 
	konieczne (normalnie ta nazwa jest taka, jak nazwa zasobu), ale
	typ XmString ma kilka właściwości, np. przechowuje font, itd.
	*/

	XmString napis_na_guziku;	 
	
	/*
	Inicjalizacja aplikacji. Ładujemy zmienną kontekst_aplikacji,
	nadajemy kwalifikatorowi zasobu aplikacji nazwę "test1", itd.
	*/
	
	aplikacja=XtVaAppInitialize(&kontekst_aplikacji,"test1",
					NULL,0,&argc,argv,NULL,NULL);
	
	/*
	Tworzymy widget planszy okna głównego aplikacji. Na nim będziemy 
	teraz ustawiać menu i guzik (nasze widgety)
	*/				
						
	shell=XtVaCreateWidget("test!",xmBulletinBoardWidgetClass,
					aplikacja,
					XmNwidth, 200,
					XmNheight,150,
					NULL);
	/*
	Tworzymy widget paska menu
	*/					
					
	pasek_menu=XmCreateMenuBar(shell,"pasekmenu",NULL,0);
	
	/*
	Tworzymy widget submenu
	*/
	
	podmenu=XmCreatePulldownMenu(pasek_menu,"podmenu",NULL,0);
	
	/*
	Tworzymy widget kaskady guzików i wiążemy go z połączeniem 
	menu-podmenu (zasób XmNsubMenuId)
	*/
	
	kaskada1=XtVaCreateManagedWidget("Podmenu",xmCascadeButtonWidgetClass,
					pasek_menu,
					XmNsubMenuId,podmenu,
					NULL);

	/*
	Tworzymy guzik - opcję submenu
	*/					
					
	opcja1=XtVaCreateManagedWidget("opcja1",xmPushButtonWidgetClass,
					podmenu,
					NULL);
	/*
	Tworzymy podpodmenu - zagnieżdżone submenu w istniejącym submenu
	*/

	podpodmenu=XmCreatePulldownMenu(podmenu,"podpodmenu",NULL,0);
	
	/*
	Wiążemy podpodmenu z podmenu, tworząc kaskadę guzików (tak jak 
	poprzednio)
	*/
		
	kaskada2=XtVaCreateManagedWidget("podpodmenu",xmCascadeButtonWidgetClass,
					podmenu,
					XmNsubMenuId,podpodmenu,
					NULL);
	
	/*
	Tworzymy resztę widgetów guzikowych opcji dla potrzeb menu
	*/

	opcja2=XtVaCreateManagedWidget("opcja2",xmPushButtonWidgetClass,
					podmenu,
					NULL);
	opcja3=XtVaCreateManagedWidget("opcja3",xmPushButtonWidgetClass,
					podpodmenu,
					NULL);
	
	/*
	Tworzymy string, który będzie wyświetlony na guziku [koniec].
	Korzystamy z najprostszej funkcji, nie ruszamy w ogóle fontu itd.
	*/ 
						
	napis_na_guziku=XmStringCreateSimple("Koniec");
	
	/*
	Tworzymy widget guzika koniec i nakładamy na niego wcześniej utworzony 
	string (zasób XmNlabel). Poza tym, pozycjujemy guzik 50 pikseli od 
	górnej części widgetu planszy okna.
	*/
	
	guzik_wyjscia=XtVaCreateManagedWidget("wyjscie",xmPushButtonWidgetClass,
					shell,
					XmNlabelString, napis_na_guziku,
					XmNy,50,
					NULL);
					
	/*
	Zwalniamy string, który został już skopiowany do wnętrza widgetu 
	guzik_wyjscia
	*/
	
	XmStringFree(napis_na_guziku);

	/*
	Zakładamy callback na guzik [koniec] - funkcję callbackową 
	"ZakonczProgram"
	*/

	XtAddCallback(guzik_wyjscia,XmNactivateCallback,ZakonczProgram,NULL);
	
	/*
	Widgety shell i pasek_menu zostały utworzone funkcją, która ich nie 
	uruchomiła, więc musimy to zrobić ręcznie
	*/
	
	XtManageChild(shell);
	XtManageChild(pasek_menu);
	
	/*
	I... odpalamy aplikację
	*/
	
	XtRealizeWidget(aplikacja);
	
	/*
	oraz zapętlamy ją na wieki wieków
	*/
	
	XtAppMainLoop(kontekst_aplikacji);
	}

void Wyjscie(Widget w, XtPointer dane_klienta, XtPointer dane_eventu)
	{
	exit(0);
	}
void ZakonczProgram(Widget w, XtPointer dane_klienta, XtPointer dane_eventu)
	{
	/*
	Deklaracja widgetów. Poszczególne z nich to:
	
	shell - okno dialogowe
	okienko - plansza na której układamy następne widgety (w sumie 
		  niepotrzebna /można bezpośrednio na shell/, ale już 
		  nie będę zmieniać ;)
	tak - guzik tak
	nie - guzik nie	
	*/
	
	Widget shell, okienko, tak, nie;
	
	/*
	Tworzymy okienko dialogowe (widget DialogShell) o wymiarach 100x50
	*/

	shell=XtVaCreateWidget("Koniec?",xmDialogShellWidgetClass,
					aplikacja,
					XmNwidth, 100,
					XmNheight,50,
					NULL);

	/*
	Tworzymy planszę, nałożoną na widget shell
	*/				
						
	okienko=XtVaCreateWidget("okienko",xmBulletinBoardWidgetClass,
					shell,
					NULL);

	/*
	Tworzymy guziki "tak" i "nie" oraz dodajemy na "tak" callback do
	funkcji "Wyjscie", która wywołuje "exit(0)"
	*/
						
	tak=XtVaCreateManagedWidget("tak",xmPushButtonWidgetClass,
					okienko,
					XmNx, 10,
					NULL);
	XtAddCallback(tak,XmNactivateCallback,Wyjscie,NULL);
	nie=XtVaCreateManagedWidget("nie",xmPushButtonWidgetClass,
					okienko,
					XmNx, 60,
					NULL);
	/*
	Uruchamiamy akcję okienka dialogowego
	*/
	
	XtManageChild(okienko);
	}

%%%%%%%% koniec test.c %%%%%%%%

Uwaga! W poniższym Makefile, kolejność bibliotek w zmiennej LIBS jest istotna!
Przy jej zaburzeniu, mogą się zdarzyć dziwne rzeczy (np. program nie ruszy).

%%%%%%% początek Makefile %%%%%%%
LIBS= -L/usr/X11R6/lib -L/usr/lesstif/lib -lXm -lXt -lX11
INCLUDE= -I/usr/include/X11 -I/usr/lesstif/include

all: test.o
	gcc test.o $(LIBS) -otest

test.o: test.c
	gcc -c $(INCLUDE) test.c
%%%%%%%% koniec Makefile %%%%%%%%


 /*
  * 4. Xlib
  */
Nie ma odpowiedzi na to pytanie. Poczekaj na nastepne FAQ.

 /*
  * 5. Gtk, gtk+
  */
Nie ma odpowiedzi na to pytanie. Poczekaj na nastepne FAQ.

 /*
  * 6. Xaw czyli Athena Widgets
  */
Nie ma odpowiedzi na to pytanie. Poczekaj na nastepne FAQ.

 /*
  * 7. Qt
  */
Brak opisu.
</pre>
</html>
</html>
</html>
Technical Details
Message-ID: <Pine.GSO.3.96.980227173618.24683A-100000@elektron.elka.pw.edu.pl>
Path: mbox-mo1.pugleaf.net!news-archive.icm.edu.pl!pingwin.icm.edu.pl!news.icm.edu.pl!elektron.elka.pw.edu.pl!mmochol

Show Full Headers
Complete Article Headers
Path: mbox-mo1.pugleaf.net!news-archive.icm.edu.pl!pingwin.icm.edu.pl!news.icm.edu.pl!elektron.elka.pw.edu.pl!mmochol
From: Maciej MOCHOL <mmochol@elka.pw.edu.pl>
Newsgroups: pl.comp.sys.xwindow,pl.comp.os.linux
Subject: X Window System FAQ
Date: Fri, 27 Feb 1998 17:39:07 +0100
Organization: ICM's news server
Lines: 2398
Message-ID: <Pine.GSO.3.96.980227173618.24683A-100000@elektron.elka.pw.edu.pl>
NNTP-Posting-Host: elektron.elka.pw.edu.pl
Mime-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit