C. Recanati
Option C avancé, avec X-Window
Licence 3, 2008

TPn°2 : Fenêtres et événements

Exercice n° 1 (identique à l’exercice 2 du TP n°1 sur la redirection au gestionnaire de fenêtres)
1) Créez une fenêtre avec XCreateWindow, en position (0,0) avec un bord assez épais. Affichez-la à l’écran. Que constatez-vous ? 
2) Mettez son attribut override_redirect à la valeur True et comparez l’exécution du programme qui en résulte avec l’exécution précédente. Conclusion ?

Exercice n° 2 (programme winGravity.c)
Le but de l’exercice est de tester l’attribut win_gravity d’une fenêtre fille. Pour cela, reprendre l’exercice 1 du TP 1, mais créez la fille avec XCreateWindow avec un attribut win_gravity que vous ferez varier (par des valeurs différentes dans différents programmes). Cette fois, on ne fait pas bouger la sous-fenêtre. On se contente d’afficher les deux fenêtres à l’écran. Exécutez le programme et observez ce qui se passe quand vous changez la taille de la fenêtre mère à l’aide de la souris (par l’intermédiaire du gestionnaire de fenêtre). 

Exercice n° 3 (programme events.c)
1) Sélectionner sur une fenêtre les événements de type  ButtonPress, ButtonRelease et MotionNotify.
Dans la boucle d’événements, pour chaque type d’événement reçu, imprimez : le type de l’événement (en toutes lettres), l’identificateur de la fenêtre ayant reçu l’événement (comme entier, mais vous pouvez tronquer les bits de poids forts) et la position en (x, y) de la souris dans la fenêtre. Pour ButtonPress et ButtonRelease, vous pouvez aussi afficher le numéro du bouton de souris enfoncé.
2) Observez ce qui se passe quand vous cliquez dans la fenêtre, déplacez la souris en maintenant le bouton enfoncé, puis sortez de la fenêtre et relâchez la souris à l’extérieur. Comparez ce comportement avec celui obtenu si vous déplacez simplement la souris à l’extérieur (sans maintenir le bouton enfoncé).
3) Modifiez le masque de sélection des événements sur la fenêtre pour ne recevoir les mouvements de souris que quand un bouton de souris est enfoncé. Comment faire pour que les mouvements ne soient reçus que si le bouton 2 est enfoncé (par opposition au bouton 1 ou au bouton 3) ?

Exercice 4 (programme expose.c)
Le but de l’exercice est de tester les événements de type Expose. Pour cela, créer une fenêtre qui sélectionne ce type d’événement. Imprimer dans le terminal pour chaque événement Expose reçu  les champs count, x, y, width, et height de cet événement. Pour tester ce programme lors de son exécution, il faudra mettre en avant ou en arrière d’autres fenêtres présentes à l’écran qui chevauchent la fenêtre du programme (en gardant visible de terminal de lancement pour observer les messages d’impression).

Schéma d’exercice :
#include <stdio.h>
#include <stdlib.h>
#include <X11/Xlib.h>
#include <X11/Xutil.h>

#define 	LARGEUR	300	
#define 	HAUTEUR	400	

char*					nom_de_station = NULL; 
unsigned long	blanc, noir;
Display*			dpy;
Window				root;
int						screen;

int main (int argc, char ** argv)
{
		Window 			Fenetre ;	
		XSetWindowAttributes  xswa;
		
	/*
	 * Regarder si on a un argument au programme,
	 *  si oui vérifier l’option et modifier  nom_de_station
	 */
		if (argc == 3 && !strcmp (argv [1], "-d"))
				nom_de_station = argv [2];

	/*
	 * Connexion au serveur et initialisation des variables globales
	 */
		dpy = XOpenDisplay (nom_de_station);
	
		if (dpy == NULL) {
				printf ("%s: Impossible d'ouvrir %s\n", argv[0], 
														XDisplayName(nom_de_station));
				return (EXIT_FAILURE);
		}
		screen 		= 	DefaultScreen (dpy);		
		root 			= 	RootWindow (dpy, screen);
		blanc 			= 	WhitePixel (dpy, screen);
		noir 			= 	BlackPixel (dpy, screen);
	/*
	 * Creation de la fenetre principale avec XCreateWindow :
			Preparation des valeurs des attributs pour cette creation
			dans la structure xswa 
	 */
		xswa.background_pixel 		= 	noir ;
		xswa.border_pixel 					= 	blanc ;

//		pour supprimer la redirection au gestionnaire de fenetres
//		xswa.override_redirect 			= 	True;

//		pour selectionner les clics dans la fenetre
	    xswa.event_mask					=  ButtonPressMask ;

		Fenetre = XCreateWindow (dpy, root, 100, 100,  
																LARGEUR, HAUTEUR, 10,
								CopyFromParent, InputOutput,CopyFromParent,
						CWBackPixel | CWBorderPixel | CW...,   &xswa);
	/*
	 * Afficher la fenêtre puis entrer dans la boucle infinie
	 * qui traite les événements
	 */
		XMapWindow (dpy, Fenetre);
		for (  ;  ;  ) {
				XEvent	ev ;

				ev = XNextEvent(dpy, &ev) ;
				switch (ev.type) {
						case ButtonPress : printf("clic souris\n") ;
																break ;
						case MotionNotify :  printf("mouvement souris\n") ;
																break ;
						default : printf("evenement inconnu\n") ;
																break ;
				}
		}	
}