X Window System on verkkoläpinäkyvä ikkunointijärjestelmä. Järjestelmässä kaikki ikkunat ovat hierarkisessa järjestyksessä. Ylimmäisenä on juuri-ikkuna (roow window), jolla on lapsi-ikkunoita, joilla voi olla omia lapsi-ikkunoita.
X-protokolla on asynkroninen, jolloin kaikkea ei välttämättä piirretä heti kun funktiota kutsutaan. XSync() odottaa kunnes xserver on toteuttanut kaikki operaatiot.
Yhteys palvelimelle avataan funktiolla
Display *XOpenDisplay(char *display_name); Display_name sisältää palvelimen osoitteen ja avattavan ruudun (screen) numeron. Se voi kuitenkin olla NULL, jolloin käytetään DISPLAY-ympäristömuuttujaa.
Ikkunan luominen
Ikkuna voidaan luoda XCreateWindow- tai XCreateSimpleWindow-funktiolla.
Window XCreateWindow(Display *display, Window parent, int x, int y, unsigned int width, unsigned int height, unsigned int border_width, int depth, unsigned int class, Visual *visual, unsigned long valuemask, XSetWindowAttributes *attributes);
Window XCreateSimpleWindow(Display *display, Window parent, int x, int y, unsigned int width, unsigned int height, unsigned int border_width, unsigned long border, unsigned long background);
Esimerkissä käytetään XCreateSimpleWindow-funktiota. Funktiolle kerrotaan siis näyttö, isäntäikkuna, x- sekä y-koordinaatit, leveys, korkeus, reunan väri, sekä reunan ja taustan väri.
Isäntäikkunan saa kutsulla
RootWindow(display, DefaultScreen(display)).
X-protokolla sisältää mahdollisuuden siihen, että asiakas voi pyytää palvelinta ilmoittamaan tietyistä tapahtumista, kuten näppäimenpainalluksista tai hiiren liikkeistä. Tämä tapahtuu funktiolla XSelectInput. Seuraava koodinpätkä pyytää tiedot window-ikkunalle tapahtuvista hiirenpainalluksista sekä tiedon siitä kun ikkuna täytyy piirtää uudelleen.
XSelectInput(display, window, ButtonPressMask | ExposureMask);
Tämän jälkeen mapataan ikkuna näytölle (näkyväksi).
XMapWindow(display, window);Tapahtumien käsittely
Palvelin lähettää asiakkaalle asiakkaan haluamat tapahtumat ja ne siirtyvät asiakkaan tapahtumajonoon.
Tapahtumia voi tapahtumajonosta tarkastella seuraavilla funktioilla.
int XNextEvent(Display *display, XEvent *event_return);
int XPeekEvent(Display *display, XEvent *event_return);
int XWindowEvent(Display *display, Window w, long event_mask, XEvent *event_return);
XNextEvent palauttaa ensimmäisen tapahtuman tapahtumajonosta ja poistaa sen jonosta. Jos jono on tyhjä, funktio odottaa tapahtumia.
XPeekEvent palauttaa tapahtuman poistamatta sitä jonosta. XWindowEventillä voi puolestaan etsiä tapahtumia ikkunakohtaisesti.
Kaikki tapahtumat sisältävät tiedon niiden näytöstä, lähdeikkunasta ja lähdeajasta (koska kutsut tapahtuvat asynkronisesti niin niiden toteuttamisessa voi olla viivettä). Lisäksi tapahtumat sisältävät tapahtumakohtaisia tietoja, kuten hiiren liikkuessa hiiren koordinaatit.
Grafiikan piirtäminen
Jotta ikkunaan voisi piirtää, täytyy luoda piirtokonteksti (graphics context). Piirtokontekstille voit tämän jälkeen piirtää erilaisilla funktioilla. Tässä muutama ja lisää löytyy manuaalista:
- XDrawLine
- XDrawPoint
- XDrawString
- XFillPolygon
Seuraava koodinpätkä tulostaa ruudulle "Hello world!"
GC gc = XCreateGC(display, window, 0, 0);
const char *hello = "Hello world!";
XDrawString(display, window, gc, 30, 50, hello, std::strlen(hello));
XFreeGC(display, gc);
Esimerkkiohjelma
#include <X11/Xlib.h>
#include <cstring>
#include <iostream>
int main(int argc, char **argv)
{
Display *display = XOpenDisplay(NULL);;
if(display == NULL) {
std::cerr << "Can't connect to the xserver.\n";
return 1;
}
int screen_num = DefaultScreen(display);
Window window = XCreateSimpleWindow(display,
RootWindow(display, screen_num),
200, 200, 200, 200, 10,
BlackPixel(display, screen_num),
WhitePixel(display, screen_num));
XSelectInput(display, window,
ButtonPressMask | ExposureMask);
XMapWindow(display, window);
GC gc = XCreateGC(display, window, 0, 0);
bool running = true;
while(running) {
XEvent event;
XNextEvent(display, &event);
switch(event.type) {
case Expose:
{
const char *hello = "Hello world!";
XDrawString(display, window, gc, 30, 50,
hello, std::strlen(hello));
break;
}
case ButtonPress:
running = false;
default:
break;
}
}
XUnmapWindow(display, window);
XFreeGC(display, gc);
XDestroyWindow(display, window);
XCloseDisplay(display);
return 0;
}
g++ -g xhello.cc -o xhello -lX11./xhello
Ikkuna näyttää tältä
Enlightenmentia käytettäessä.

Ilman ikkunamanageria ikkuna voisi näyttää tältä. Ikkunalla ei ole otsikkopalkkia eikä sitä voi liikuttaa. (Voit tietenkin koodata ohjelmaan otsikkopalkin ja napata hiiritapahtumat ja kutsua XMoveWindow-funktiota)
Ohjelman voi sammuttaa napsauttamalla sitä hiirellä.