Prima Homepage
Ravi Homepage
Le langage scml et la doc Ravi
Le module modxdraw
Installation Ravi sur Ensibull - PIA99
ImaLab

[PREV]

Un fichier .ph expliqué

Le module "expérimental" d'interface avec X11 utilisant beaucoup de struct, il a servi de cobaye pour mettre au point la gestion des struct. Les auteurs de ce module sont Christophe et Jerôme.

Notre objectif est de faire en sorte que, vu de ravi, une structure comme XEvent ou XFontStruct puisse être traitée comme une classe. On veut donc des déclarations permettant

  • La génération des méthodes d'accès aux différents champs.
  • Le traitement d'une fonction extérieure comme une méthode de classe.

et cela de facon modulable: certains champs doivent rester privés.


%%declare ((eval
	    (begin
	      (set! *struct-defaults* '((export-fields (default-value get))
					(export-methods #f)
					(is-class #t)
					(make-constructor #t)))

Comme son nom l'indique, la variable *struct-defaults* définit l'interface par défaut. Comme les valeurs standard ne conviennent pas, on les modifie.

(export-fields (default-value get))
Le get signifie "accès aux champs du struct en lecture". (La valeur standard #t indique lecture et écriture.

(is-class #t)
signifie que le struct sera généré comme une classe, et que les accès aux champs seront donc des méthodes. En standard, is-class vaut #f, et l'accès aux champs passe par des fonctions.

(make-constructor #t)
génère un constructeur sans argument.


	      (set! *preprocess-flag* #t)
	      ))

Ceci active le traitement des commandes du préprocesseur à l'intérieur de r-ig. (r-ig est le générateur d'interface) Le fichier "X.h", pour lequel il y a un %%input "X.h" plus loin, contient des définitions de constantes avec des #define, et on voudra exporter ces définitions vers le module x11.


	   (struct XColor
		   (print-function print_XColor))

Le génération de XColor suivra les défaut définis plus haut. L'attribut print-function est décrit avec la déclaration classe. Très généralement, les déclarations struct et class sont sensiblement les mêmes.


	   (struct XFontStruct
		   (export-fields fid)
		   (print-function print_XFontStruct))

Seul le champ fid sera exporté. La seule méthode (en plus du constructeur) générée pour la classe XFontStruct sera donc get-fid.


	   ... on saute quelques lignes ...
	   (struct XMotionEvent
		   (export-fields type window x y state is_hint)
		   print-function)

(struct XSetWindowAttributes (export-fields (default-value #t)))

La fonction d'impression de XMotionEvent sera générée (nouveau!).

On exporte tous les champs de XSetWindowAttributes en lecture et écriture: méthodes get-champ et set-champ!

(struct XVisualInfo (export-fields (default-value #t)) (print-function print_XVisualInfo))

(C->Sc "XVisualInfo *" PMakeXVisualInfo) ; voir fonction ravi_XGetVisualInfo

Cette déclaration genère une fonction inline de profil
inline ScVal PMakeXVisualInfo(XVisualInfo * x)
qui traduit en ScVal une valeur C++ de type "XVisualInfo *". Cela nous facilitera la construction d'une liste-Scheme avec des XVisualInfos.


	   (struct Display print-function)

(struct Window print-function) (class GC) (class Colormap) (struct Visual print-function)

(scheme-name << decalage_gauche) (scheme-name >> decalage_droite) (scheme-name XCreateImage ravi_XCreateImage) (scheme-name AllPlanes ravi_AllPlanes) (scheme-name XFetchName ravi_XFetchName) (scheme-name XMatchVisualInfo ravi_XMatchVisualInfo) (scheme-name XListDepths ravi_XListDepths) (no-export rien))

Ce (no-export rien) est bizarre: il positionne le flag d'exportation de facon que tout sera exporté (sauf le symbole rien ...)

On saute maintenant les phases %%input pour lesquelles il n'y a rien à signaler.

%%input *

%%input "X.h" %%input "/usr/include/X11/cursorfont.h"

%%include

#include <X11/Xlib.h> #include <X11/Xutil.h> typedef long Class ;

%%typefunctions

La phase %%typefunctions provôque la génération des fonctions de gestion des types - dans notre cas, c'est uniquement la fonction PMakeXVisualInfo générée par la déclaration C->Sc. Elle doit être placée avant la phase %%function qui vient ensuite.

La suite du fichier x11.ph contient la définition de nombreuses fonctions. On montre juste un détail intéressant: la fonction qui construit une liste Scheme avec des XVisualInfo:


static ScVal ravi_XGetVisualInfo(Display *dpy, long mask, XVisualInfo *vis)
  // returns Scheme list of XVisualInfos
{
  int num;
  int i;
  XVisualInfo * xres= XGetVisualInfo(dpy,mask,vis,&num);
  ScVal res = Cons(ScNil,ScNil), q=res;
  for(i=0;i<num;i++)
    {
      SetCdr(q,
	     Cons(PMakeXVisualInfo(&xres[i]),ScNil));
      q=Cdr(q);
    }
  return Cdr(res);
}

Enfin, à la fin du fichier, la phase %%scheme-input contient ceci:

%%scheme-input * ... (add-method 'XEvent 'ButtonEvent? XEvent_get_ButtonEvent) (add-method 'XEvent 'MotionEvent? XEvent_get_MotionEvent)

Cela complète la classe XEvent telle qu'elle sera vue dans Ravi.