Autres articles / Other articles

Maitriser X11 avec eForth linux

publication: 6 décembre 2023 / mis à jour 6 décembre 2023

Read this page in english

 

Les caractéristiques principales de X11 sont:

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:

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:

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