DESS Technologies et Stratégies Industrielles
Option : Mécanique et Applications
Etudiants : SOIDIKI Ali Youssouf
MOHAMED EL-MOUSTAPHA Ould Hamoud

Enseignant IPST
M. Patrick TRAU

 

 

Année Universitaire 2001/2002

 

REMERCIEMENTS

Pour la réalisation de ce projet Informatique, nous tenons à remercier tout particulièrement

M. Patrick TRAU pour sa disponibilité

 


I- INTRODUCTION

II- LES BASES DE LA PROGRAMMATION AVEC Xlib

II-1 CONTACTER LE SERVEUR 
II-2 CREER UNE FENETRE ET L'AFFICHER 
II-3 GERER LES EVENNEMENTS DANS LA FENETRE... 

III- EXEMPLES

IV- BIBLIOGRAPHIE 

ANNEXES

Exemple1 : fsimpl.c
Exemple2 : freppositif.c
Exemple3 : frepgeneral.c
Exemple4 : fline.c
Exemple5 : fmeca.c
Exemple6 : fenetre.c, xfenetre.h, xfenetre.c

I-INTRODUCTION :

Le but de notre Projet Informatique est d'examiner les possibilités offerts par Xlib-Bibliothèque graphique de base sous UNIX- pour réaliser du graphique en C.

Ce projet permet d'initialiser le lecteur à la programmation sous le système graphique X11, en utilisent des exemples simples et en introduisent les concepts principaux de la programmation X.

Notre démarche consiste, suite à une recherche bibliographique, à tester différents programmes et identifier les fonctions importantes qui nous permettent d'afficher des courbes. Ainsi nous créerons différentes fenêtres qui permettront d'accéder rapidement à une application précise sans avoir à refaire le programme..

II- LES BASES DE LA PROGRAMMATION AVEC Xlib

Un programme X comprend trois étapes essentielles : la première consiste à contacter le serveur de la station avec laquelle il interagit, c'est le rôle du XOpenDisplay ; puis il doit créer des fenêtres et positionner leurs paramètres, ce que font ici XCreateSimpleWindow et XMapWindow ; finalement, il doit gérer les événements qui se produisent dans la fenêtre, ce que fait la boucle infinie qui termine la fonction main.

II-1 CONTACTER LE SERVEUR :

if ((d = XOpenDisplay(getenv("DISPLAY"))) == NULL)
  { 
    fprintf(stderr,"Impossible de contacter le serveur\n"); 
    exit(1); 
  } 

La fonction XOpenDisplay renvoie NULL quand elle ne réussit pas à contacter un serveur ; sinon elle renvoi un pointeur sur un Display. Un Display est en réalité une structure(nommée _XDisplay et définie dans /usr/include/X11/Xlib.h), qui contient les paramètres qui décrivent la station contrôlée par le serveur et l'état de la communication avec le serveur. Ce pointeur sera ensuite utilisé par tous les appels de la librairie X qui échangent des données avec le serveur.

II-2 CREER UNE FENETRE ET L'AFFICHER :

w = XCreateSimpleWindow(d, RootWindow(d, DefaultScreen(d)),
			0, 0, larg, haut,
			2, BlackPixel(d, DefaultScreen(d)),
			WhitePixel(d, DefaultScreen(d)));
XMapWindow(d, w);

Pour créer une fenêtre, le programme utilise XCreateSimpleWindow, ses arguments permettront au serveur de dessiner la fenêtre sur l 'écran :
il s'agit de la station et de la fenêtre dans laquelle la nouvelle fenêtre doit être créée(d, RootWindow(d, DefaultScreen(d)), sa position et sa taille(0, 0, larg, haut,), l'épaisseur et la couleur de son cadre et la couleur de son fond(2, BlackPixel(d, DefaultScreen(d)), WhitePixel(d, DefaultScreen(d))).

La position de la fenêtre est indiquée par les deux entiers suivants :
elle est mesurée en pixels à partir du coin en haut à gauche dans le système de coordonnées de la fenêtre parent. Le premier indique la distance horizontalement et le second la distance verticalement. Sa taille est également mesurée en pixel ; le premier indique la largeur et le second la hauteur. C'est une façon, ici, de désigner un rectangle sous X.

Une fois la fenêtre créée, le programme demande explicitement au serveur de l'aficher avec XMapWindow ; à cet appel correspond vraiment une modification de l'écrant provoquée par l'affichage de la fenêtre.

II-3 GERER LES EVENEMENTS DANS LA FENETRE :

for(;;)
     XNextEvent(d, &e);

Lorsque le serveur a quelque chose à envoyer au programme, il le fait sous la forme d'un événement. Les programmes utilisent la fonction XNextEvent, avec les arguments Display et l'adresse d'une union XEvent, pour aller chercher les événements dans les fonctions de la bibliothèques.

III- EXEMPLES

Dans cette partie on va commenté comment on fait la programmation avec Xlib :

# include <X11/Xlib.h>
# include <stdio.h>
int larg,haut,s;
char * detenv();
Display * d;
Window w;
GC gc;
XFontStruct * fd;
XEvent e;
XGCValues gcv;
main()
{
printf("Donner la largeur de la fenetre(nombre entier)");
scanf("%d",&larg);
printf("Donner la hauteur de la fenetre(nombre entier)");
scanf("%d",&haut);
printf("Donner la hauteur de la fenetre pour le Titre (nombre entier)");
scanf("%d",&s);
if ((d = XOpenDisplay(getenv("DISPLAY"))) == NULL)
  {
    fprintf(stderr,"Impossible de contacter le serveur\n");
    exit(1); }
w = XCreateSimpleWindow(d, RootWindow(d, DefaultScreen(d)),
			0, 0, larg, haut,
			2, BlackPixel(d, DefaultScreen(d)),
			WhitePixel(d, DefaultScreen(d)));
if ((fd=XLoadQueryFont(d, "fixed")) == NULL)
  {
    fprintf(stderr, "Impossible de charger la police fixed\n");
    exit(1); }
gcv.font = fd->fid;
gcv.foreground = BlackPixel(d, DefaultScreen(d));
gc = XCreateGC(d, w, GCFont | GCForeground, &gcv);
XMapWindow(d, w);
for(;;)
    XNextEvent(d, &e);
} 

Dans l'annexe on trouve six exemples, qui aide à comprendre quelques usages élémentaires de la programmation avec Xlib.

Le premier exemple a pour but de montrer comment créer une fenêtre (annexe : fichier : fsimple.c).

Le deuxième et le troisième exemples illustrent comment créer un repère dans une fenêtre (annexe : fichier freppositif.c et frepgeneral.c).

Le quatrième exemple est un programme qui, après avoir créé une fenêtre, y trace une ligne (annexe : fichier : fline.c).

Le cinquième exemple permet d'afficher les résultats d'un calcul mécanique plastique sous forme d'une ligne qui représente l'écrouissage linaire(annexe : fichier : fmeca.c).

Le sixième exemple a pour objectif de faire le premier pas pour créer une bibliothèque pour utiliser une fonction qui fait l' affichage d'une fenêtre en appelant la bibliothèque, dans laquelle on a définie cette fonction. pour cela on a les trois programmes suivants (voir annexe):
xfenetre.c : qui définie la fonction d'affichage de la fenêtre (fenetre()).
xfenetre.h : qui fait le lien entre les deux programmes : xfenetre.c et fenetre.c
fenetre.c : programme d'exécution.

Pour compiler un programme sous l'environnement unix, on utilise :

	gcc nomdufichier.c -o -lX11 nom

pour l'exemple cinq, on utilise :

	gcc fmeca.c -o -lX11 -lm fmeca

pour l'exemple six, on utilise :

	gcc fenetre.c xfenetre.c -o -lX11 fenetre

IV- BIBLIOGRAPHIE


Exemple1 : fsimpl.c

# include <X11/Xlib.h>
# include <stdio.h>
int larg,haut,s;
char * detenv();
 Display * d;
  Window w;
  GC gc;
  XFontStruct * fd;
  XEvent e;
main()
{
initialiser();

               /*decider quand dessiner ou ecrire ou les deux*/
XSelectInput(d,w, ExposureMask);
}

initialiser()
{
   XGCValues gcv;
   printf("Donner la largeur de la fenetre(nombre entier)");
   scanf("%d",&larg);
   printf("Donner la hauteur de la fenetre(nombre entier)");
   scanf("%d",&haut);
   printf("Donner la hauteur de la fenetre pour le Titre (nombre entier)");
   scanf("%d",&s);

                  /*contacte le serveur*/
   if ((d = XOpenDisplay(getenv("DISPLAY"))) == NULL)
    {     fprintf(stderr,"Impossible de contacter le serveur\n");
     exit(1);    }
                  /*crée une fenetre*/
w = XCreateSimpleWindow(d, RootWindow(d, DefaultScreen(d)),
			0, 0, larg, haut,
			2, BlackPixel(d, DefaultScreen(d)),
			WhitePixel(d, DefaultScreen(d)));
                     /*chargement d une police de caracteres*/
 if ((fd=XLoadQueryFont(d, "fixed")) == NULL)
   {
   fprintf(stderr, "Impossible de charger la police fixed\n");   exit(1);
   }                      /*creation d un contexte graphique*/
gcv.font = fd->fid;
gcv.foreground = BlackPixel(d, DefaultScreen(d));
gc = XCreateGC(d, w, GCFont | GCForeground, &gcv);
XMapWindow(d, w);
for(;;)
  XNextEvent(d, &e);
}

Exemple2 : freppositif.c

# include <X11/Xlib.h>
# include <stdio.h>
# include <math.h>
int larg,haut,s;
char * detenv();
 Display * d;
  Window w;
  GC gc;
  XFontStruct * fd;
main()
{
initialiser();

               /*decider quand dessiner ou ecrire ou les deux*/
XSelectInput(d,w, ExposureMask);
rouler();
}

initialiser()
{
   XGCValues gcv;
   printf("Donner la largeur de la fenetre(nombre entier)");
   scanf("%d",&larg);
   printf("Donner la hauteur de la fenetre(nombre entier)");
   scanf("%d",&haut);
   printf("Donner la hauteur de la fenetre pour le Titre (nombre entier)");
   scanf("%d",&s);

                  /*contacte le serveur*/
   if ((d = XOpenDisplay(getenv("DISPLAY"))) == NULL)
    {
     fprintf(stderr,"Impossible de contacter le serveur\n");
     exit(1);
    }
                  /*crée une fenetre*/
w = XCreateSimpleWindow(d, RootWindow(d, DefaultScreen(d)),
			0, 0, larg, haut,
			2, BlackPixel(d, DefaultScreen(d)),
			WhitePixel(d, DefaultScreen(d)));

                     /*chargement d une police de caracteres*/
 if ((fd=XLoadQueryFont(d, "fixed")) == NULL)
   {
   fprintf(stderr, "Impossible de charger la police fixed\n");
   exit(1);
   }
                      /*creation d un contexte graphique*/
gcv.font = fd->fid;
gcv.foreground = BlackPixel(d, DefaultScreen(d));
gc = XCreateGC(d, w, GCFont | GCForeground, &gcv);
XMapWindow(d, w);

}

rouler()
{
XEvent e;
float xmax,ymax;
        char h='%';
	int Ye,i;
	printf("donner les coordoner maximum de votre raiper(xmax,ymax)\n");
        scanf("%d",&xmax);
        scanf("%d",&ymax);
	for(;;)
   {
  XNextEvent(d, &e);
  switch(e.type)
      {
  default:
     fprintf(stderr, "J'ai reçu un évènement %d\n", e.type);
     break;
  case Expose :
     printf("Expose : %dx%d+%d+%d\n", e.xexpose.width, e.xexpose.height,
	     e.xexpose.x, e.xexpose.y);
     XDrawString(d, w, gc, s, s,"Y]",strlen("Y"));
     XDrawString(d, w, gc, (larg-s), (haut-s),"X",strlen("X"));
     XDrawLine(d, w, gc,s,(2*s),s,(haut-s));
     XDrawLine(d, w, gc,s,(haut-s),(larg-s),(haut-s));
     }
  }
}

Exemple 3 : frepgeneral.c

# include <X11/Xlib.h>
# include <stdio.h>
int larg,haut,s;
char * detenv();
 Display * d;
  Window w;
  GC gc;
  XFontStruct * fd;
main()
{
initialiser();

               /*decider quand dessiner ou ecrire ou les deux*/
XSelectInput(d,w, ExposureMask);
rouler();
}

initialiser()
{
   XGCValues gcv;
   printf("Donner la largeur de la fenetre(nombre entier)");
   scanf("%d",&larg);
   printf("Donner la hauteur de la fenetre(nombre entier)");
   scanf("%d",&haut);
   printf("Donner la hauteur de la fenetre pour le Titre (nombre entier)");
   scanf("%d",&s);

                  /*contacte le serveur*/
   if ((d = XOpenDisplay(getenv("DISPLAY"))) == NULL)
    {
     fprintf(stderr,"Impossible de contacter le serveur\n");
     exit(1);
    }
                  /*crée une fenetre*/
w = XCreateSimpleWindow(d, RootWindow(d, DefaultScreen(d)),
			0, 0, larg, haut,
			2, BlackPixel(d, DefaultScreen(d)),
			WhitePixel(d, DefaultScreen(d)));

                     /*chargement d une police de caracteres*/
 if ((fd=XLoadQueryFont(d, "fixed")) == NULL)
   {
   fprintf(stderr, "Impossible de charger la police fixed\n");
   exit(1);
   }
                      /*creation d un contexte graphique*/
gcv.font = fd->fid;
gcv.foreground = BlackPixel(d, DefaultScreen(d));
gc = XCreateGC(d, w, GCFont | GCForeground, &gcv);
XMapWindow(d, w);

}
rouler()
{
XEvent e;
float xmax,ymax;
printf("donner les coordoner maximum de votre raiper(xmax,ymax)\n");
scanf("%f",&xmax);
scanf("%f",&ymax);
for(;;)
   {
  XNextEvent(d, &e);
  switch(e.type)
      {
  default:
     fprintf(stderr, "J'ai reçu un évènement %d\n", e.type);
     break;
  case Expose :
     printf("Expose : %dx%d+%d+%d\n", e.xexpose.width, e.xexpose.height,
	     e.xexpose.x, e.xexpose.y);
     XDrawString(d, w, gc, (larg/2), (2*s),"Y",strlen("Y"));
     XDrawString(d, w, gc, (larg-s), (haut/2),"X",strlen("X"));
     XDrawLine(d, w, gc,(larg/2),(2*s),(larg/2),(haut-2*s));
     XDrawLine(d, w, gc,s,(haut/2),(larg-s),(haut/2));
    }
  }
}

Exemple 4 : fline.c

# include <X11/Xlib.h>
# include <stdio.h>
int larg,haut,s;
char * detenv();
 Display * d;
  Window w;
  GC gc;
  XFontStruct * fd;
main()
{
initialiser();

               /*decider quand dessiner ou ecrire ou les deux*/
XSelectInput(d,w, ExposureMask);
rouler();
}

initialiser()
{
   XGCValues gcv;
   printf("Donner la largeur de la fenetre(nombre entier)");
   scanf("%d",&larg);
   printf("Donner la hauteur de la fenetre(nombre entier)");
   scanf("%d",&haut);
   printf("Donner la hauteur de la fenetre pour le Titre (nombre entier)");
   scanf("%d",&s);

                  /*contacte le serveur*/
   if ((d = XOpenDisplay(getenv("DISPLAY"))) == NULL)
    {
     fprintf(stderr,"Impossible de contacter le serveur\n");
     exit(1);
    }
                  /*crée une fenetre*/
w = XCreateSimpleWindow(d, RootWindow(d, DefaultScreen(d)),
			0, 0, larg, haut,
			2, BlackPixel(d, DefaultScreen(d)),
			WhitePixel(d, DefaultScreen(d)));

                     /*chargement d une police de caracteres*/
 if ((fd=XLoadQueryFont(d, "fixed")) == NULL)
   {
   fprintf(stderr, "Impossible de charger la police fixed\n");
   exit(1);
   }
                      /*creation d un contexte graphique*/
gcv.font = fd->fid;
gcv.foreground = BlackPixel(d, DefaultScreen(d));
gc = XCreateGC(d, w, GCFont | GCForeground, &gcv);
XMapWindow(d, w);

}
rouler()
{
XEvent e;
int i;
float x,y,xmax,ymax;
printf("donner les coordoner maximum de votre raiper(xmax,ymax)\n");
scanf("%f",&xmax);
scanf("%f",&ymax);
for(;;)
   {
  XNextEvent(d, &e);
  switch(e.type)
      {
  default:
     fprintf(stderr, "J'ai reçu un évènement %d\n", e.type);
     break;
  case Expose :
     printf("Expose : %dx%d+%d+%d\n", e.xexpose.width, e.xexpose.height,
	     e.xexpose.x, e.xexpose.y);
     XDrawString(d, w, gc, (larg/2), (2*s),"Y",strlen("Y"));
     XDrawString(d, w, gc, (larg-s), (haut/2),"X",strlen("X"));
     XDrawLine(d, w, gc,(larg/2),(2*s),(larg/2),(haut-2*s));
     XDrawLine(d, w, gc,s,(haut/2),(larg-s),(haut/2));
     for(i=0; i<500; i++)
     {x=-100+i;
     y=4*x+200;
     XDrawLine(d, w, gc,(int)((larg/2)+(x*((larg/2)-s)/xmax)),(int)((haut/2)-(y*((haut/2)-2*s)/ymax)),(int)((larg/2)+(x*((larg/2)-s)/xmax)),(int)((haut/2)-(y*((haut/2)-2*s)/ymax)));
     }
     break;
    }
  }
}

Exemple5: fmeca.c

# include <X11/Xlib.h>
# include <stdio.h>
# include <math.h>
int larg,haut,s;
char * detenv();
 Display * d;
  Window w;
  GC gc;
  XFontStruct * fd;
main()
{
initialiser();

               /*decider quand dessiner ou ecrire ou les deux*/
XSelectInput(d,w, ExposureMask);
rouler();
}

initialiser()
{
   XGCValues gcv;
   printf("Donner la largeur de la fenetre(nombre entier)");
   scanf("%d",&larg);
   printf("Donner la hauteur de la fenetre(nombre entier)");
   scanf("%d",&haut);
   printf("Donner la hauteur de la fenetre pour le Titre (nombre entier)");
   scanf("%d",&s);

                  /*contacte le serveur*/
   if ((d = XOpenDisplay(getenv("DISPLAY"))) == NULL)
    {
     fprintf(stderr,"Impossible de contacter le serveur\n");
     exit(1);
    }
                  /*crée une fenetre*/
w = XCreateSimpleWindow(d, RootWindow(d, DefaultScreen(d)),
			0, 0, larg, haut,
			2, BlackPixel(d, DefaultScreen(d)),
			WhitePixel(d, DefaultScreen(d)));

                     /*chargement d une police de caracteres*/
 if ((fd=XLoadQueryFont(d, "fixed")) == NULL)
   {
   fprintf(stderr, "Impossible de charger la police fixed\n");
   exit(1);
   }
                      /*creation d un contexte graphique*/
gcv.font = fd->fid;
gcv.foreground = BlackPixel(d, DefaultScreen(d));
gc = XCreateGC(d, w, GCFont | GCForeground, &gcv);
XMapWindow(d, w);

}

rouler()
{
XEvent e;
float Ye,Y0,Y,dy,de,v,v1,v2,v3,s1,s2,s3,k,G,xmax,ymax,deprec,Yeprec;
        int i;
	printf("donner les coordoner maximum de votre raiper(xmax,ymax)\n");
        scanf("%f",&xmax);
        scanf("%f",&ymax);
	printf("donner la contrainte Y0\n Y0=");
	scanf("%f",&Y0);

	printf("donner  G  \n G=");
	scanf("%f",&G);

	printf("donner la vitesse v \n v=");
	scanf("%f",&v);
	v1=-v/2;
	v2=-v/2;
	v3=v;
	k=G/20;
	for(;;)
   {
  XNextEvent(d, &e);
  switch(e.type)
      {
  default:
     fprintf(stderr, "J'ai reçu un évènement %d\n", e.type);
     break;
  case Expose :
     printf("Expose : %dx%d+%d+%d\n", e.xexpose.width, e.xexpose.height,
	     e.xexpose.x, e.xexpose.y);
     XDrawString(d, w, gc, larg/2, s,"tracer une droite",strlen("voila une droite"));
     XDrawString(d, w, gc, s, s,"Syy[N/mm2]",strlen("Syy[N/mm2]"));
     XDrawString(d, w, gc, (larg-s), (haut-s),"e[%]",strlen("e[%]"));
     XDrawLine(d, w, gc,s,(2*s),s,(haut-s));
     XDrawLine(d, w, gc,s,(haut-s),(larg-s),(haut-s));
     Y=Y0;
     Yeprec=Y0;
     de=0;
     deprec=de;
     for(i=0;i<21;i++)
	 {
	   if(i==0) dy=k*de;
		Y=Y+dy;
		s1=(2*Y*v1)/(3*v);
		s2=(2*Y*v2)/(3*v);
		s3=(2*Y*v3)/(3*v);
		Ye=sqrt((3*(s1*s1+s2*s2+s3*s3)/2));
		printf(" %2.0f   \t  %5.2f \n", 100*de, Ye);
		printf("%f %f %f %f \n", (s+((100*de*(larg-2*s))/xmax)),((haut-s)-((Ye*(haut-3*s))/ymax)),(s+(100*de*(larg-2*s)/xmax)),((haut-s)-(Ye*(haut-3*s)/ymax)));
		XDrawLine(d, w, gc, ((int)(s+(100*deprec*(larg-2*s)/xmax))),((int)((haut-s)-(Yeprec*(haut-3*s)/ymax))),((int)(s+(100*de*(larg-2*s)/xmax))),((int)((haut-s)-(Ye*(haut-3*s)/ymax))));
                deprec=de;
                Yeprec=Ye;
		de=(de+0.01);
		dy=(k*0.01);
	}
          break;
    }
  }
}

Exemple6 :

fenetre.c

#include<stdio.h>
# include <X11/Xlib.h>
#include"xfenetre.h"
main()
{
int x1,x2,y1,y2;
fenetre();
printf("donner les coordoner du premier point (x1,y1)\n");
scanf("%d",&x1);
scanf("%d",&y1);
printf("donner les coordoner du deuxieme point (x2,y2)\n");
scanf("%d",&x2);
scanf("%d",&y2);

               /*decider quand dessiner ou ecrire ou les deux*/
XSelectInput(d,w, ExposureMask);
for(;;)
{
  XNextEvent(d, &e);
  switch(e.type)
{
  default:
     fprintf(stderr, "J'ai reçu un évènement %d\n", e.type);
     break;
  case Expose :
     printf("Expose : %dx%d+%d+%d\n", e.xexpose.width, e.xexpose.height,
	     e.xexpose.x, e.xexpose.y);
     XDrawString(d, w, gc, (larg/2), 40,"Syy[Nmm]",strlen("Syy[Nmm]"));
     XDrawString(d, w, gc, (larg-40), (haut/2),"e[%]",strlen("e[%]"));
     XDrawLine(d, w, gc,(larg/2),40,(larg/2),(haut-40));
     XDrawLine(d, w, gc,40,(haut/2),(larg-40),(haut/2));
     XDrawLine(d, w, gc,((larg/2)+x1),((haut/2)-y1),((larg/2)+x2),((haut/2)-y2));
     break;
     }
}
}

xfenetre.h

/*déclaration de la xfenetre*/
# include <X11/Xlib.h>
int larg,haut;
char * detenv();
 Display * d;
  Window w;
  GC gc;
  XEvent e;
  XFontStruct * fd;
  XGCValues gcv;
fenetre();

xfenetre.c

#include<stdio.h>
#include "xfenetre.h"

fenetre()
{
   printf("Donner la largeur de la fenetre(nombre entier)");
   scanf("%d",&larg);
   printf("Donner la hauteur de la fenetre(nombre entier)");
   scanf("%d",&haut);

                  /*contacte le serveur*/
   if ((d = XOpenDisplay(getenv("DISPLAY"))) == NULL)
{
     fprintf(stderr,"Impossible de contacter le serveur\n");
     exit(1);
}
                  /*crée une fenetre*/
w = XCreateSimpleWindow(d, RootWindow(d, DefaultScreen(d)),
			0, 0, larg, haut,
			2, BlackPixel(d, DefaultScreen(d)),
			WhitePixel(d, DefaultScreen(d)));

                     /*chargement d une police de caracteres*/
 if ((fd=XLoadQueryFont(d, "fixed")) == NULL)
{
   fprintf(stderr, "Impossible de charger la police fixed\n");
   exit(1);
   }
                      /*creation d un contexte graphique*/
gcv.font = fd->fid;
gcv.foreground = BlackPixel(d, DefaultScreen(d));
gc = XCreateGC(d, w, GCFont | GCForeground, &gcv);
XMapWindow(d, w);

}

retour présentation graphique M.M. HAMOUD / SOIDIKI - 2001/2002