From 7869d881f2865052d4894219be5254c394efa7a0 Mon Sep 17 00:00:00 2001
From: Vince <vi.teissier@gmail.com>
Date: Thu, 23 Nov 2023 10:43:18 +0100
Subject: [PATCH] Rectification delta + ressources

---
 main.c             |   2 +-
 prog               | Bin 16720 -> 16720 bytes
 ressources/graph.c | 773 +++++++++++++++++++++++++++++++++++++++++++++
 ressources/graph.h | 149 +++++++++
 4 files changed, 923 insertions(+), 1 deletion(-)
 create mode 100644 ressources/graph.c
 create mode 100644 ressources/graph.h

diff --git a/main.c b/main.c
index fbd6ebd..76ef547 100644
--- a/main.c
+++ b/main.c
@@ -13,7 +13,7 @@
 
 #define DECALEMENT 30
 
-#define delta 1000000L
+#define delta 10000L
 
 
 int ArrondirPixel(int nombre) /* Calcule un arrondi du pixel pour pouvoir respecter la norme des 40 lignes et 60 colonnes */
diff --git a/prog b/prog
index d5705c98207e677f93cea64459b291e21ee4e3c0..285fd4d595e96a424bd8f7917e6c673a361a6b43 100755
GIT binary patch
delta 44
zcmcc6#CV~JaYF^ONW>k1HHxxPVw~F&-9pq}<VMOR>Td2~UL(Z(f|+5nwV0?j0ByMr
A@Bjb+

delta 44
zcmcc6#CV~JaYF^ONX@Q-|Gd2A5l_DzoboQ;HO4dHZ0Y76<~2gh4o>`=t;IyO0mlat
AWdHyG

diff --git a/ressources/graph.c b/ressources/graph.c
new file mode 100644
index 0000000..deda835
--- /dev/null
+++ b/ressources/graph.c
@@ -0,0 +1,773 @@
+#include<X11/Xlib.h>
+#include<X11/cursorfont.h>
+#include<X11/Xatom.h>
+#include<X11/Xutil.h>
+#include<X11/keysym.h>
+
+#include<stdio.h> 
+#include<stdlib.h>
+#include<string.h>
+#include<time.h>
+
+#include "config.h"
+
+#ifdef HAVE_XPM
+#include<X11/xpm.h>
+#endif
+
+
+#include "graph.h"
+#include "image.h"
+#define N 50
+
+
+void _get_GC(Window win, GC *gc);
+
+typedef struct
+{
+	int posx,posy;
+	int tx,ty;
+	int etat;
+	Pixmap s;
+	Pixmap smask;
+	Pixmap sauvegarde;
+}
+sprite;
+
+sprite S[N];                        /* tableau de sprite    */
+int S_alloue[N];					/* tableau d'allocation */
+
+/******************** variables globales  beurk ****************************/
+
+Display *display;
+int screen;
+int display_width=0,display_height=0;
+int X_fen,Y_fen;
+int connecte=0;
+int nbfen=0;
+Window win;
+XColor coul;
+unsigned long couleur_dess;
+XEvent report;		                 /* structure des evenements */
+
+GC gc;					             /* ID du contexte graphique */
+unsigned int border_w=4; 
+Cursor croix;
+XSetWindowAttributes attribut;
+Colormap pal;					     /* palette 			*/
+Font f[3];							 /* polices d'ecriture          */
+XFontStruct *s[3];
+XFontStruct *stemp;
+Pixmap icone=NULL,icone_mask=NULL;
+XPoint sommet[3];
+int num_ecran=0;
+Window ecran[NB_PIXMAP+1];
+int app=0;
+XWMHints  * wm_hints;
+XClassHint  * class_hints;
+XSizeHints  * size_hints;
+
+XTextProperty nom_fenetre,nom_icone;
+char *nf="IUT de Fontainebleau"; // changer si vous voulez :-)
+char *ni="mon_icone";          
+
+int _X=0,_Y=0;
+
+//#include "image.c"
+
+void  ChoisirModeDessin(int m)
+{
+	switch(m)
+	{
+		case 0 : XSetFunction(display,gc,GXcopy);
+				 break;
+		case 1 : XSetFunction(display,gc,GXxor);
+				 break;
+		case 2 : XSetFunction(display,gc,GXinvert);
+				 break;
+		default : XSetFunction(display,gc,GXcopy); 
+	}  
+}
+void ChoisirCouleurDessin(unsigned long couleur)
+{
+	couleur_dess=couleur;
+	XSetForeground(display,gc,couleur);
+	XFlush(display);
+}
+
+void ChoisirEcran(int n)
+{
+	if (0<=n&&n<=NB_PIXMAP) num_ecran=n;
+}
+
+int InitialiserGraphique()
+{
+	if (!connecte)
+	{
+		if((display=XOpenDisplay(NULL))==NULL) {
+			fprintf(stderr,"erreur : ne peut pas se connecter ");
+			fprintf(stderr,"au serveur %s\n",XDisplayName(NULL));
+			return 0;
+		}
+		if (connecte) //return 0;
+		return 1;	
+
+		/* Recuperer les informations concernant l'ecran (root window) sur
+		   lequel on va afficher notre application. Le numero de l'ecran
+		   par defaut s'obtient a l'aide de la macro DefaultScreen(), la
+		   taille a l'aide des macros DisplayWidth() et
+		   DisplayHeight().*/
+
+		screen = DefaultScreen(display);
+		display_width = DisplayWidth(display,screen);
+		display_height = DisplayHeight(display,screen);
+		pal=DefaultColormap(display,screen);
+		connecte=1;
+		return 1;
+	}
+}
+
+int CreerFenetre(int posx,int posy,int X,int Y)
+{
+	int i;
+	Visual *v;
+	char buf[1024]; 
+	int trouve;
+
+	if (!connecte) 
+	{
+		perror("initialisez d'abord le mode graphique\n");
+		//return (1);
+		return 0;
+	}
+
+	if (nbfen==1) 
+	{
+		printf("une seule fentre on a dit !!!!\n");
+		//return(1);
+		return 0;
+	}
+
+	ecran[0] = XCreateSimpleWindow(display, RootWindow(display, screen), 
+			posx, posy,X, Y, border_w,
+			BlackPixel(display,screen),
+			WhitePixel(display,screen));
+
+	/* sensibilisation de la fenêtre */
+
+	XSelectInput(display, ecran[0], 
+			ExposureMask | KeyPressMask |ButtonPressMask  );
+
+
+	/* creation d'un contexte graphique pour cette fenetre,
+	   indispensable pour dessiner ou afficher du texte */
+
+	_get_GC(ecran[0], &gc);
+
+	/* creation d'une fonte curseur */
+
+	croix=XCreateFontCursor(display,XC_crosshair);
+	XDefineCursor(display,ecran[0],croix);
+
+	/* le contenu de la fenetre est persistant : le serveur le supporte-t-il ? */       
+
+	attribut.backing_store=Always;
+	XChangeWindowAttributes(display,ecran[0],CWBackingStore,&attribut);
+
+	/* chargement d'une font par defaut pour l'ecriture de texte */
+
+	trouve=0;
+	i=10;
+	while(!trouve&&i<=15)
+	{
+		sprintf(buf,"-adobe-helvetica-*-r-*-*-%d-*-*-*-*-*-*-*",i);
+		stemp=XLoadQueryFont(display,buf);
+		if (stemp==NULL) i++;
+		else
+			trouve=1;
+	}
+
+	if (!trouve) 
+	{
+		sprintf(buf,"6x13");
+		if ((stemp=XLoadQueryFont(display,buf))==NULL)
+			stemp=XLoadQueryFont(display,"fixed");
+	}
+	f[0]=stemp->fid;
+	s[0]=stemp;
+
+
+	trouve=0;
+	i=20;
+	while(!trouve&&i<=25)
+	{
+		sprintf(buf,"-adobe-helvetica-*-r-*-*-%d-*-*-*-*-*-*-*",i);
+		stemp=XLoadQueryFont(display,buf);
+		if (stemp==NULL) i++;
+		else
+			trouve=1;
+	}
+	if (!trouve) 
+	{
+		sprintf(buf,"8x16");
+		if ((stemp=XLoadQueryFont(display,buf))==NULL)
+			stemp=XLoadQueryFont(display,"fixed");
+	}
+	f[1]=stemp->fid;
+	s[1]=stemp;
+
+
+	trouve=0;
+	i=30;
+	while(!trouve&&i<=35)
+	{
+		sprintf(buf,"-adobe-helvetica-*-r-*-*-%d-*-*-*-*-*-*-*",i);
+		stemp=XLoadQueryFont(display,buf);
+		if (stemp==NULL) i++;
+		else
+			trouve=1;
+	}
+	if (!trouve) 
+	{
+		sprintf(buf,"12x24");
+		if ((stemp=XLoadQueryFont(display,buf))==NULL)
+			stemp=XLoadQueryFont(display,"fixed");
+	}
+
+	f[2]=stemp->fid;
+	s[2]=stemp;
+
+
+	XSetFont(display,gc,f[1]);
+
+
+
+	/* creation des pixmaps pour la sauvegarde d'images */
+
+	for(i=1;i<=NB_PIXMAP;i++)
+	{ 
+		ecran[i]=XCreatePixmap( display , DefaultRootWindow(display), X , Y , DefaultDepth(display,screen) );
+	} 
+	/* variables globales pour la taille de la fenetre */
+
+	X_fen=X;
+	Y_fen=Y;
+
+	bzero(S_alloue,N*sizeof(int));
+	wm_hints=XAllocWMHints();
+	class_hints=XAllocClassHint();
+	size_hints=XAllocSizeHints();
+
+	XStringListToTextProperty(&nf,1,&nom_fenetre);
+	XStringListToTextProperty(&ni,1,&nom_icone);
+	wm_hints->initial_state=NormalState;
+	wm_hints->input=True;
+	wm_hints->flags=StateHint|InputHint;
+	size_hints->x=posx;
+	size_hints->y=posy;
+	size_hints->flags=USPosition;
+	//class_hints->res_name="Graphique";
+	XSetWMProperties(display,ecran[0],&nom_fenetre,&nom_icone,NULL,0,size_hints,wm_hints,NULL);
+	//XSetWMNormalHints(display,ecran[0],size_hints);
+	XSetIconName(display,ecran[0],"Super");
+	//  XStoreName(display,ecran[0],"D.M Entertainment");
+	XMapWindow(display,ecran[0]);
+
+	XFree(wm_hints);
+	XFree(size_hints);
+	XFree(class_hints);
+	wm_hints=XGetWMHints(display,ecran[0]);
+	do 
+	{
+		XWindowEvent(display,ecran[0],ExposureMask,&report);
+	}
+	while(report.xexpose.count);
+	nbfen=1;
+	return 1;
+}
+
+void ChoisirTitreFenetre(char *s)
+{
+	XStoreName(display,ecran[0],s );
+}
+void ChoisirCurseur(unsigned int forme)
+{
+	XFreeCursor(display,croix);
+	croix=XCreateFontCursor(display,forme);
+	XDefineCursor(display,ecran[0],croix);
+}
+
+
+/*----------------------*/
+
+void _get_GC(Window win, GC *gc)
+
+{
+	unsigned long valuemask = 0;                /* Ignore XGCvalues et prend les
+												   valeurs par defaut */
+	XGCValues values;
+
+	/* creation d'un contexte graphique par defaut */
+
+	*gc = XCreateGC(display, ecran[0], valuemask, &values);
+
+
+	/* specification d'un background noir, puisque par defaut on fait du
+	   blanc sur du blanc */
+	//XSetBackground(display,*gc,154);
+
+	XSetForeground(display, *gc, BlackPixel(display, screen));
+	XSetGraphicsExposures(display,*gc,False);	 
+
+	/* inutile d'enfler la file d'evenements avec les evenements
+	   Noexpose et GraphicsExpose */
+}
+
+int Maxx()
+{
+	if (!connecte) return -1;
+	else return display_width;
+}
+
+int Maxy()
+{
+	if (!connecte) return -1;
+	else return display_height;
+}
+
+void DessinerPixelC(int x,int y,unsigned long couleur)
+{
+	XSetForeground(display,gc,couleur);
+	XDrawPoint(display,ecran[num_ecran],gc,x,y);
+	XSetForeground(display,gc,couleur_dess);
+	XFlush(display);
+}
+
+void DessinerPixel(int x,int y)
+{
+	XDrawPoint(display,ecran[num_ecran],gc,x,y);
+	XFlush(display);
+}
+
+void DessinerSegmentC(int x,int y,int xx,int yy,unsigned long couleur)
+{
+	XSetForeground(display,gc,couleur);
+	XDrawLine(display,ecran[num_ecran],gc,x,y,xx,yy);
+	XSetForeground(display,gc,couleur_dess);
+	XFlush(display);
+}
+void DessinerSegment(int x,int y,int xx,int yy)
+{
+	XDrawLine(display,ecran[num_ecran],gc,x,y,xx,yy);
+	XFlush(display);
+}
+
+void FermerGraphique()
+{ 
+	int i;
+	XSync(display,True);
+	for (i=0;i<3;i++) XUnloadFont(display,f[i]);
+	for (i=1;i<=NB_PIXMAP;i++)
+		XFreePixmap(display,ecran[i]);
+	for(i=0;i<N;i++) LibererSprite(i);
+	XFreeGC(display,gc);
+	XCloseDisplay(display);
+	nbfen=0;
+	connecte=0;
+	app=0;
+}
+
+unsigned long CouleurParNom(char * nom)
+{
+	XParseColor(display,pal,nom,&coul);
+	XAllocColor(display,pal,&coul);
+	return coul.pixel;
+}
+
+void DessinerRectangleC(int x,int y,int l,int h,unsigned long c)
+{
+	XSetForeground(display,gc,c);
+	XDrawRectangle(display,ecran[num_ecran],gc,x,y,l,h);
+	XSetForeground(display,gc,couleur_dess);
+	XFlush(display);
+}
+void DessinerRectangle(int x,int y,int l,int h)
+{
+
+	XDrawRectangle(display,ecran[num_ecran],gc,x,y,l,h);
+	XFlush(display);
+
+}
+void RemplirRectangle(int x,int y,int l,int h)
+{
+	XFillRectangle(display,ecran[num_ecran],gc,x,y,l,h);
+	XFlush(display);
+}
+
+void DessinerArcC(int x,int y,int l,int h,int angle1,int angle2,unsigned long c)
+{
+	XSetForeground(display,gc,c);
+	XDrawArc(display,ecran[num_ecran],gc,x,y,l,h,angle1*64,angle2*64);
+	XSetForeground(display,gc,couleur_dess);
+	XFlush(display);
+}
+
+void DessinerArc(int x,int y,int l,int h,int angle1,int angle2)
+{
+	XDrawArc(display,ecran[num_ecran],gc,x,y,l,h,angle1*64,angle2*64);
+	XFlush(display);
+
+}
+
+void RemplirArc(int x,int y,int l,int h,int angle1,int angle2)
+{
+	XFillArc(display,ecran[num_ecran],gc,x,y,l,h,angle1*64,angle2*64);
+	XFlush(display);
+}
+
+
+void DessinerSegments(Point * sommets,int nb_sommet)
+{
+	XDrawLines(display,ecran[num_ecran],gc,
+			sommets,nb_sommet, CoordModeOrigin);
+}
+
+void RemplirPolygone(Point * sommets,int nb_sommet)
+{
+	XFillPolygon(display, ecran[num_ecran],gc, sommets,
+			nb_sommet, Complex,CoordModeOrigin);
+}
+void RemplirTriangle(int x,int y,int xx,int yy,int xxx,int yyy)
+{
+	sommet[0].x=(short)x;
+	sommet[0].y=(short)y;
+	sommet[1].x=(short)xx;
+	sommet[1].y=(short)yy;
+	sommet[2].x=(short)xxx;
+	sommet[2].y=(short)yyy;
+	XFillPolygon(display,ecran[num_ecran],gc,sommet,3,Convex,CoordModeOrigin);
+	XFlush(display);
+}
+
+int ToucheEnAttente()
+{
+	if (app==1) return 1;
+	if (XCheckWindowEvent(display,ecran[0],KeyPressMask,&report)) 
+	{
+		app=1;
+		return 1;
+	}
+	//app=0;
+	return 0;
+}
+
+
+KeySym Touche()
+{
+	/* fonction bloquante si aucune touche dans le buffer
+	*/
+	int  buffer;
+	int c;
+	KeySym t;
+	if (app==0)	XWindowEvent(display,ecran[0],KeyPressMask,&report);
+	c=XLookupString(&(report.xkey), NULL, sizeof(KeySym), &t,NULL);
+	app=0;
+	return t;
+}
+
+void EffacerEcran(unsigned long c)
+{
+	if (num_ecran==0)
+	{
+		XSetWindowBackground(display,ecran[num_ecran],c);
+		XClearWindow(display,ecran[num_ecran]);
+	}
+	else 
+	{ 
+		XSetForeground(display,gc,c);
+		XFillRectangle(display,ecran[num_ecran],gc,0,0,X_fen,Y_fen);
+		XSetForeground(display,gc,couleur_dess);
+	}
+	XFlush(display);
+}
+
+void EcrireTexteC(int x,int y,char *texte,int mode,unsigned long c)
+{
+	if (mode<0||mode>2) return;
+	XSetFont(display,gc,f[mode]);
+	XSetForeground(display,gc,c);
+	XDrawString(display,ecran[num_ecran],gc,x,y,texte,strlen(texte));
+	XSetForeground(display,gc,couleur_dess);
+	XFlush(display);
+}
+
+void EcrireTexte(int x,int y,char *texte,int mode)
+{
+	if (mode<0||mode>2) return;
+	XSetFont(display,gc,f[mode]);
+	XDrawString(display,ecran[num_ecran],gc,x,y,texte,strlen(texte));
+	XFlush(display);
+
+}
+#ifdef HAVE_XPM
+void SauverImage(char * file,int x,int y,int l,int h)
+{
+	XEvent report;
+	Pixmap p1=0;
+	p1=XCreatePixmap( display , DefaultRootWindow(display), X_fen , Y_fen , DefaultDepth(display,screen) );
+	XCopyArea(display,ecran[num_ecran],p1,gc,x,y,l,h,0,0);
+	XpmWriteFileFromPixmap(display,file,p1,0,NULL);
+	if (p1) XFreePixmap(display,p1);
+	while(XCheckWindowEvent(display,ecran[0],ExposureMask,&report));
+	while(XCheckTypedEvent(display,GraphicsExpose,&report));
+	while(XCheckTypedEvent(display,NoExpose,&report));
+}
+#endif
+
+int ChargerImage(char *file,int x,int y,int xx,int yy,int l,int h)
+{
+	XEvent report;
+	Pixmap p1=0,p1mask=0;
+	int wi,hi;
+	if (!_chargerimage(file, &wi,&hi,&p1 , &p1mask,display,gc,screen)) return 0;
+
+	//XpmReadFileToPixmap(display,ecran[num_ecran],file,&p1,&p1mask,NULL);
+
+	XSetClipMask(display,gc,p1mask);
+	XSetClipOrigin(display,gc,x,y);
+	XCopyArea(display,p1,ecran[num_ecran],gc,xx,yy,l,h,x,y);
+
+	XSetClipMask(display,gc,None);
+	if (p1) XFreePixmap(display,p1);
+	if (p1mask) XFreePixmap(display,p1mask);
+
+	//XFlush(display);
+
+	while(XCheckWindowEvent(display,ecran[0],ExposureMask,&report));
+	while(XCheckTypedEvent(display,GraphicsExpose,&report));
+	while(XCheckTypedEvent(display,NoExpose,&report));    
+	return 1;
+
+}
+
+void ChargerImageFond(char *file)
+{ 
+	XSetWindowAttributes att;
+	Pixmap pbackground=0,pmask=0;
+	int i=num_ecran;
+	int x,y;
+	if (i<0 || i>NB_PIXMAP) return ;
+
+	switch(i)
+	{
+		case 0 :
+			//XpmReadFileToPixmap(display,ecran[i],file,&pbackground,&pmask,NULL);
+			_chargerimage(file, &x,&y,&pbackground , &pmask,display,gc,screen);
+			att.background_pixmap=pbackground;
+			XChangeWindowAttributes(display,ecran[i],CWBackPixmap,&att);
+			XClearWindow(display,ecran[i]);
+
+			if (pbackground) XFreePixmap(display,pbackground);
+			if (pmask) XFreePixmap(display,pmask);
+			XFlush(display);
+			break;
+		default:
+			ChargerImage(file,0,0,0,0,X_fen,Y_fen);
+	} 
+}
+
+int TailleChaineEcran(char *t,int mode)
+{
+	if (mode<0||mode>2) return -1;
+	else return XTextWidth(s[mode],t,strlen(t));
+}
+int TailleSupPolice(int mode)
+{
+	if (mode<0||mode>2) return -1;
+	return s[mode]->ascent;
+}
+
+int TailleInfPolice(int mode)
+{
+	if (mode<0||mode>2) return -1;
+	return s[mode]->descent;
+}
+
+
+void CopierZone(int src,int dst,int ox,int oy,int L,int H,int dx,int dy)
+{
+	XEvent report;
+	XCopyArea(display,ecran[src],ecran[dst],gc,ox,oy,L,H,dx,dy);
+	XFlush(display);
+	while(XCheckWindowEvent(display,ecran[0],ExposureMask,&report));
+	while(XCheckTypedEvent(display,GraphicsExpose,&report));
+	while(XCheckTypedEvent(display,NoExpose,&report));
+}
+
+
+void CacherFenetre()
+{
+	XUnmapWindow(display,ecran[0]);
+	XFlush(display);
+};
+
+void AfficherFenetre(void)
+{
+	XMapWindow(display,ecran[0]);
+	XFlush(display);
+}
+
+
+unsigned long CouleurParComposante(unsigned char r, unsigned char v,unsigned char b)
+{
+	/* on suppose qu'on est en True Color */
+	/* C'est a ameliorer !!!              */
+	/* XColor c;
+	   c.red=r;
+	   c.red<<=8;
+	   c.green=v;
+	   c.green<<=8;
+	   c.blue=b;
+	   c.blue<<=8;
+	   XAllocColor(display,DefaultColormap(display,screen),&c);
+	   return c.pixel;*/
+	unsigned long cr=r,cg=v,cb=b;
+	return (cr<<16)|(cg<<8)|cb;
+}
+
+
+unsigned long Microsecondes()
+{
+	struct timeval t;
+	gettimeofday(&t, NULL);
+	return t.tv_usec+t.tv_sec*1000000;
+}
+
+
+/*
+   int souris(int *X,int *Y)
+   {
+   XEvent r;
+   if (XCheckWindowEvent(display,ecran[0],PointerMotionMask,&r))
+   {*X=r.xmotion.x;*Y=r.xmotion.y;return 1;}
+   return 0;
+   }
+   */
+
+
+
+void SourisPosition()
+{
+	int x,y,rx,ry;
+	unsigned int etat;
+	Window a,b;
+	XQueryPointer(display, ecran[0], &a, &b, &rx, &ry, &x, &y, &etat);
+	_X=x;_Y=y;
+}
+
+int _longueur()
+{
+	return XQLength(display);
+}
+
+int SourisCliquee()
+{
+	XEvent r;
+	if (XCheckWindowEvent(display,ecran[0],ButtonPressMask,&r))
+	{
+		_X=r.xbutton.x;
+		_Y=r.xbutton.y;
+		return 1;
+	}
+	return 0;
+}
+int SpriteLibre()
+{
+	int i;
+	for(i=0;i<N;i++) if (S_alloue[i]==0) return i;
+	return -1;
+}
+
+int ChargerSprite(char *file)
+{
+	Pixmap p1=0,p1mask=0;
+	int nu,w,h;
+#ifdef HAVE_XPM
+	XpmAttributes a;
+	a.valuemask=XpmSize;
+#endif
+	nu=SpriteLibre();
+	if (nu==-1) return -1;
+	S_alloue[nu]=1;
+	if (!_chargerimage(file, &w,&h,&p1 , &p1mask,display,gc,screen))
+		//if (XpmReadFileToPixmap(display,ecran[num_ecran],file,&p1,&p1mask,&a)!=0)
+	{
+		S_alloue[nu]=0;
+		return -1;
+	}
+	S[nu].posx=-1;
+	S[nu].posy=-1;
+	S[nu].etat=0;
+	//S[nu].tx=a.width;
+	//S[nu].ty=a.height;
+	S[nu].tx=w;
+	S[nu].ty=h;
+	S[nu].s=p1;
+	S[nu].smask=p1mask;
+	S[nu].sauvegarde=0;
+	S[nu].etat=0;
+
+	return nu+1;
+}
+
+void AfficherSprite(int n,int x,int y)
+{
+	Pixmap p;
+	n--;
+	if (n<0||n>=N) return;
+	if (S_alloue[n]!=1) return;	
+	/*	if ((S[n].etat)==0)
+		{
+		p=XCreatePixmap( display , DefaultRootWindow(display), S[n].tx ,S[n].ty  , DefaultDepth(display,screen) );
+		XCopyArea(display,ecran[num_ecran],p,gc,x,y,S[n].tx,S[n].ty,0,0);
+		S[n].sauvegarde=p;
+
+
+		}*/
+
+	/* restitue la zone */
+
+	//XSetClipMask(display,gc,None);
+	//if (S[n].etat!=0) XCopyArea(display,S[n].sauvegarde,ecran[num_ecran],gc,0,0,S[n].tx,S[n].ty,S[n].posx,S[n].posy);
+
+	//XCopyArea(display,ecran[num_ecran],S[n].sauvegarde,gc,x,y,S[n].tx,S[n].ty,0,0);
+	if (S[n].smask!=0) {
+		XSetClipMask(display,gc,S[n].smask);
+		XSetClipOrigin(display,gc,x,y);
+	}
+	XCopyArea(display,S[n].s,ecran[num_ecran],gc,0,0,S[n].tx,S[n].ty,x,y);
+	S[n].posx=x;
+	S[n].posy=y;
+	S[n].etat=1;
+	XFlush(display);
+	XSetClipMask(display,gc,None);
+}
+
+/*void EffacerSprite(int n)
+{
+	n--;
+	if (S[n].etat!=0) XCopyArea(display,S[n].sauvegarde,ecran[num_ecran],gc,0,0,S[n].tx,S[n].ty,S[n].posx,S[n].posy);
+	S[n].etat=0;
+}*/
+
+void LibererSprite(int n)
+{
+	n--;
+	if (n<0||n>=N) return;
+	if (S_alloue[n]!=1) return;
+	if (S[n].s>0) XFreePixmap(display,S[n].s);
+	if (S[n].smask>0) XFreePixmap(display,S[n].smask);
+	if (S[n].sauvegarde>0) XFreePixmap(display,S[n].sauvegarde);
+	S_alloue[n]=0;
+}
+
diff --git a/ressources/graph.h b/ressources/graph.h
new file mode 100644
index 0000000..8244e09
--- /dev/null
+++ b/ressources/graph.h
@@ -0,0 +1,149 @@
+#ifndef _GRAPH_H
+#define _GRAPH_H
+
+#include<X11/Xlib.h>
+#include<X11/Xutil.h>
+#include<X11/keysym.h>
+
+extern int _X;
+extern int _Y;
+
+#define NB_PIXMAP 10
+
+typedef unsigned long couleur;
+typedef XPoint Point;
+
+int InitialiserGraphique();
+/* initialise le mode graphique : renvoie 1 en cas de succes, 0 sinon */
+
+int CreerFenetre(int posx,int posy,int X,int Y);
+/* creer la fenetre graphique de largeur X et longueur Y, et la positionne
+   sur l'ecran au point (posx,posy). Une seule fenetre autoris�e */
+
+void ChoisirTitreFenetre(char *s);
+/* change le titre de la fenetre */
+
+void ChoisirCurseur(unsigned int forme);
+/* change le curseur de la fenetre */
+
+void CacherFenetre(void);
+/* cache la fenetre */
+
+void AfficherFenetre(void);
+/* affiche la fenetre */
+
+void ChoisirEcran(int n);
+/* fixe l'ecran ou le dessin est effectue : cette ecran est soit 0 (la fenetre
+   visible, ecran par defaut au demarrage), soit le numero de l'�cran  virtuel correspondant */
+
+void ChoisirCouleurDessin(couleur c);
+/* fixe la couleur qui sert au dessin */
+
+couleur CouleurParNom(char * nom);
+/* fait la traduction d'une couleur a partir de son nom : le fichier rgb.txt
+   contient la liste des couleurs accessibles via leur nom */
+
+couleur CouleurParComposante(unsigned char r, unsigned char v,unsigned char b); 
+/* renvoie la couleur d�finie par ses trois composantes */
+
+int Maxx();
+/* renvoie la largeur de l'ecran : il faut que le mode graphique ait �t� 
+   initialise !!! */
+
+int Maxy();
+/* renvoie la hauteur de l'ecran : il faut que le mode graphique ait �t� 
+   initialise !!! */
+
+void DessinerPixel(int x,int y);
+/* allume un pixel avec la couleur de dessin */
+
+void DessinerSegment(int x,int y,int xx,int yy);
+/* idem precedent, mais avec la couleur de dessin */
+
+void DessinerSegments(Point * sommets,int nb_sommets);
+/* trace pour chaque paire sommet[i],sommet[i+1] le segment correspondant. Si le deux extr�mit�s correspondent, le polygone est ferm� */
+
+void DessinerRectangle(int x,int y,int l,int h);
+/* idem, mais utilise la couleur de dessin */
+
+void RemplirRectangle(int x,int y,int l,int h);
+/* trace un rectangle plein, rempli avec c */
+
+void DessinerArc(int x,int y,int l,int h,int angle1,int angle2);
+/* idem, mais utilise la couleur de dessin */
+
+void RemplirArc(int x,int y,int l,int h,int angle1,int angle2);
+/* trace un arc plein avec c */
+
+void RemplirTriangle(int x,int y,int xx,int yy,int xxx,int yyy);
+/* trace un triangle plein */
+
+void RemplirPolygone(Point * sommets,int nb_sommet);
+/* Trace un polygone plein d�fini par son tableau de sommets. Si les extremit�s ne coincident pas, le polygone est ferm� automatiquement.
+*/
+
+int ToucheEnAttente();
+/* renvoie 1 si une touche a �t� enfonc�e, 0 sinon */
+
+KeySym Touche();
+/* renvoie la premiere touche du tampon : cette fonction est bloquante => 
+   utiliser ToucheEnAttente  pour la rendre non bloquante */
+
+void EcrireTexte(int x,int y,char *texte,int taille);
+/* ecrit la chaine texte au point (x,y) : taille indique la taille (0<->petit,1<->moyen,2<->grand) */
+#ifdef HAVE_XPM
+void SauverImage(char * file,int x,int y,int l,int h);
+/* sauvegarde d'une partie de la fenetre (x,y,x+l,y+h) au format xpm */
+#endif
+
+int ChargerImage(char *file,int x,int y,int xx,int yy,int l,int h);
+/* charge une partie (xx,yy,xx+l,yy+h) d'image au format xpm dans 
+la fenetre a la position (x,y) */
+
+void ChargerImageFond(char *file);
+/* charge une image qui remplit le fond de la fen\^etre, en la r\'ep\'etant si necessaire */
+
+void EffacerEcran(couleur c);
+/* efface l'ecran avec la couleur c*/
+
+void ChoisirModeDessin(int m);
+/* fixe le mode d'affichage : 0<->ecrasement 1<->xor */
+
+int TailleChaineEcran(char *t,int taile);
+/* renvoie, en pixel, la taille horizontale occupee par la chaine � l'�cran :taille est la taille de la police (0,1,2) */
+
+int TailleSupPolice(int taille);
+/* renvoie la taiile maximale de la police, en pixel, au dessus de la ligne d'�criture */
+
+int TailleInfPolice(int taille);
+/* renvoie la taille maximale de la police, en pixel, en dessous de la ligne d'�criture */
+
+void CopierZone(int src,int dst,int ox,int oy,int L,int H,int dx,int dy);
+/* copie une zone de l'�cran vers l'�cran dst. La zone copi�e est le rectangle delimite par le coin superieure hauche (ox,oy) et sa largeur l et hauteur h. Cette zone est copi� au point (dx,dy) de l'ecran dst */ 
+
+void FermerGraphique();
+/* fermeture du mode graphique */
+
+unsigned long Microsecondes();
+/* renvoie le nombre de microsecondes ecoul�es depuis le
+lancement du programme */
+
+void SourisPosition();
+/* recupere les coordonnees de la souris dans la fenetre et les place dans _X et _Y*/
+
+int SourisCliquee();
+/* indique un clic de souris (1 si oui, 0 sinon), et recupere si c'est le cas la position au moment du clic dans _X et _Y */
+
+
+/* fonctions a r��crire proprement */
+
+int ChargerSprite(char *file);
+/* charge un srpite en m�moire, et renvoie son num�ro 
+ * -1 en cas d'echec */
+void AfficherSprite(int n,int x,int y);
+/* affiche le sprite correspondant � son num�ro */
+void LibererSprite(int n);
+/* libere les ressources associ�es au sprite
+ * n */
+
+#endif