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

Feuille n°4 : Pixmap et contexte graphique

Exercice1 (programme includeBitmap.c)
A l’aide de la commande bitmap, créez un fichier toto.bm au format bitmap. (Attention à ne pas avoir le pavé numérique bloqué par NumLock quand vous utilisez bitmap, car la commande est buguée). Editez ce fichier. L’inclure ensuite en tête du programme par #include "toto.bm" et utilisez la fonction XCreatePixmapFromBitmapData pour créer un Pixmap utilisant les définitions de toto.bm. 
Vous attribuerez ensuite le Pixmap ainsi créé comme motif de fond pour une fenêtre créée avec XCreateWindow. Vous devez utiliser cette fonction, car si vous utilisez XCreateSimpleWindow, votre fenêtre possède alors une couleur de fond et le motif de l’attribut BackgroundPixmap sera ignoré.

Exercice 2 (programme copyScrollRoot.c)
1) Créez un Pixmap suffisamment grand pour pouvoir y copier le contenu de la racine (cf. XCreatePixmap). 
Indication : les dimensions de la racine sont fournies par des macros fonctions du Display (cf. début poly). 
2) Copier la fenêtre racine dans le Pixmap en utilisant la fonction XCopyArea.
Indications : on a besoin d’un argument gc de type GC (graphic context). On dispose d’un gc par défaut dans les macros du Display, et on peut aussi un créer un nouveau avec XCreateGC. Mais dans les deux cas, il faut prendre garde à ce que ses attributs soient conformes à nos besoins. En particulier, pour que la copie de la racine se fasse intégralement, il faut que l’attribut subwindow_mode du gc soit à True (cela permet la copie des dessins contenus dans les sous-fenêtres de la racine !).
3) Créer une fenêtre simple que vous afficherez à l’écran. Sur un clic de souris dans cette fenêtre (sélectionner l’événement requis avant l’affichage), on recopiera le Pixmap précédent dans la fenêtre (toujours grâce à XCopyArea).
4) Sélectionnez aussi les mouvements de souris (bouton enfoncé), et
faites défiler le contenu du Pixmap dans la fenêtre quand on bouge la souris en maintenant le bouton enfoncé.
Indications : sélectionnez les événements de mouvements avec ButtonMotionMask. Dans la boucle des événements, recopier le Pixmap dans la fenêtre (avec XCopyArea) sur réception d’un ButtonPress, et faites la même chose avec un certain décalage (fonction de la position de la souris), sur la réception des événements de mouvements (MotionNotify).

Exercice3 (programme readBitmap.c)
On vient de voir (Exercice1) comment créer un Pixmap à partir de données au format bitmap incluses dans le programme, en utilisant la fonction XCreatePixmapFromBitmapData. 
Une deuxième méthode permet de créer un Pixmap à partir d’un fichier au format bitmap, sans avoir à l’inclure en dur dans le programme. 
La fonction XReadBitmapFile dont on dispose pour lire des données au format bitmap crée un Pixmap de profondeur 1 (un seul plan) ; c’est un Pixmap qui n’est pas acceptable comme fond pour une fenêtre dont la profondeur est celle de l’écran. Mais on peut créer un Pixmap de profondeur correcte à partir d’un tel Pixmap, en utilisant la fonction XCopyPlane, qui permet de copier un plan de Pixmap dans un autre.
Déclarez deux variables de type Pixmap : pixmap et bitmap. 
1) Récupérez un Pixmap bitmap correspondant aux données au format bitmap du fichier avec XReadBitmapFile.
2) Créez un Pixmap pixmap qui servira de fond de fenêtre avec la fonction XCreatePixmap (avec les dimensions récupérées par la fonction précédente et la profondeur par défaut).
3) Copiez bitmap dans pixmap avec XCopyPlane. La copie s’effectue selon un 1 plan et deux couleurs permettant d’interpréter les bits à 0 comme d’une couleur d’arrière-plan, et ceux à 1 comme d’une couleur avant-plan.
4) Affectez ensuite le Pixmap obtenu (variable pixmap) comme fond d’une fenêtre que vous afficherez pour tester le programme.