Maitriser X11 avec eForth linux
publication: 6 décembre 2023 / mis à jour 6 décembre 2023
Les caractéristiques principales de X11 sont:
- l'utilisation d'une architecture client/serveur et cela dans une totale hétérogénéité (le serveur et le client peuvent fonctionner sur des architectures totalement différentes). Le dialogue entre le serveur et les clients se fait conformément au protocole X ce qui permet d'assurer la transparence du dialogue.
- la portabilité des librairies et des applications X11. Avec eForth Linux, on communique avec le serveur X sous Linux. On peut monter un serveur X sous Windows et utiliser le même code eForth sans changer une ligne de code.
En dépit des avantages de X11, le nombre de fonctions à connaître est important et la documentation titanesque et parfois difficile à aborder. Cet article va aborder en priorité l’aspect graphique du serveur X11.
Un programme X peut se diviser en trois parties:
- l'ouverture d'une connexion à un serveur X (serveur local ou terminal).
- les initialisations des fenêtres (cas de la Xlib) ou des objets (cas d'un toolkit)
- l'attente d'évènements (souris, clavier, ou autres...) dans une boucle infinie dont on ne sort qu'à la fin du programme.
Avec eForth Linux, le serveur X11 est accessible au travers du vocabulaire x11
:
x11 vlist \ display content of x11 vocabulary
Les concepts de base
Le display
Le display
définit la connexion de l'application à un serveur X. Une fois initialisée,
la valeur du display
sera utilisée dans tous les appels aux fonctions X. display
est calculé ainsi:
also x11 0 XOpenDisplay constant display
L´écran (screen)
Pour un display
donné, on peut avoir plusieurs unités d’affichage.
Initialisation d’un screen
:
display XDefaultScreen constant screen
A partir des éléments display
et screen
, on récupère
les paramètres de pixel:
display screen XBlackPixel constant black display screen XWhitePixel constant white
Les fenêtres
La fenêtre est un des concepts les plus importants sous X. Voici l’initialisation d’une fenêtre racine:
display screen XRootWindow constant root-window
Le type X correspondant à la fenêtre est le type Window. Pour créer simplement une fenêtre,
on utilisera XcreateSimpleWindow
:
display root-window 0 0 640 480 0 black white XCreateSimpleWindow constant window
La fenêtre window
nécessite les paramètres suivants:
display
qui est la connexion au serveur Xroot-window
est la fenêtre parent0 0
qui indique la position de départ de la nouvelle fenêtre dans la fenêtre parent640 480
indiquent la taille de la fenêtre window0 black white
sélectionnent respectivement l’épaisseur de la bordure, la couleur de bordure, la couleur de fond générale de la fenêtre window.
Pour afficher la fenêtre, on utilisera XMapWindow
:
display window XMapWindow drop
Et pour terminer le paramétrage de fenêtre, il nous faut encore définir la constante
gc
(pour Graphic Content):
display window 0 NULL XCreateGC constant gc
Voici une manière élégante de factoriser l’initialisation de l’environnement des fenêtres dans X11:
also x11 0 value display 0 value screen 0 value black 0 value white 0 value root-window 0 value window 0 value gc : new-window { width height -- } 0 XOpenDisplay to display display XDefaultScreen to screen display screen XBlackPixel to black display screen XWhitePixel to white display screen XRootWindow to root-window display root-window 0 0 width height 0 black white XCreateSimpleWindow to window display window XMapWindow drop display window 0 NULL XCreateGC to gc ;
Application graphique
Un vieil adage dit: «une image vaut mieux qu’un long discours». C’est en mettant en pratique ces sages paroles que nous allons aborder ceci au moyen d’un exemple très pratique et graphique.
Extension du vocabulaire X11
Le vocabulaire x11 est déjà très riche, mais il manque encore quelques fonctions graphiques que nous définirons ainsi:
x11 definitions z" XDrawPoint" 5 xlib XDrawPoint ( display win gc x y -- void ) z" XDrawLine" 7 xlib XDrawLine ( display win gc x y dx dy -- void ) z" XDrawRectangle" 7 xlib XDrawRectangle ( display win gc x y w h -- void ) forth definitions
Ce vocabulaire est facilement extensible. Prenons le cas de Xdrawline
.
La documentation X11 indique ceci:
Syntax XDrawLine(display, d, gc, x1, y1, x2, y2) Display *display; Drawable d; GC gc; int x1, y1, x2, y2;
On voit que cette fonction demande sept paramètres. On définira donc la version FORTH ainsi:
z" XDrawLine" 7 xlib XdrawLine
En tête de ligne, on a une z-chaîne qui indique le nom de la fonction X11 à appeler dans la librairie X11:
z" XDrawLine" 7 xlib XdrawLine
Enfin, après xlib, nous avons le mot tel qu’il doit être enregistré dans le vocabulaire
x11
. Nous aurions pu lui donner n’importe quel nom:
z" XDrawLine" 7 xlib draw-a-simple-line-from-x0y0-to-x1y1
Pour des raisons pratiques, on donnera au mot le même nom que celui de la fonction X11,
en l’occurence XdrawLine
dans notre exemple.
Simplification de certains mots x11
Nous programmons en langage FORTH. Il est donc très facile de définir des mots qui vont nous simplifier la lisibilité et l’utilisation du code des fonctions graphiques.
On va commencer par écrire deux mots qui sélectionneront les couleurs d’arrière plan et d’avant plan:
\ set background color : set-bg { color -- } display gc color XSetBackground drop ; \ set foreground color : set-fg { color -- } display gc color XSetForeground drop ;
Ici, on va passer un paramètre de couleur. Définissons quelques couleurs:
$000000 constant COLOR_BLACK $FFFFFF constant COLOR_WHITE $ff0000 constant COLOR_RED $0000FF constant COLOR_BLUE
Pour dessiner un rectangle vide, on définira la couleur de tracé comme ceci:
COLOR_RED set-fg display window gc x y width height XDrawRectangle drop
Le tracé de rectangle reste verbeux. Simplifions cela:
: rect { x y width height -- } display window gc x y width height XDrawRectangle drop ; : box { x y width height -- } display window gc x y width height XFillRectangle drop ;
Voici comment on peut maintenant définir un tracé simple:
: draw ( -- )
COLOR_WHITE set-bg
COLOR_BLUE set-fg
10 10 40 30 box
COLOR_RED set-fg
50 50 200 40 rect
display window XMapWindow drop
;
Il reste à encapsuler ceci dans une boucle de traitement:
: gg ( -- )
640 480 new-window
begin
draw
display Xflush
again
;
L’exécution de gg
ouvre une nouvelle fenêtre avec ceci affiché dans cette fenêtre:

Le codage général est encore très incomplet. Il reste à gérer les événements et plein d’autres fonctionnalités pour exploiter pleinement la librairie X11.
Legal: site web personnel sans commerce / personal site without seling