C.
RECANATI
Interfaces
Graphiques
ILOG
2, septembre 2004
TP 1 : Création de
fenêtres
Compilation :
gcc –g –o exo exo.c –lX11
Exercice
1: (programmes creation.c et overrideRed.c)
1)
Créez une fenêtre avec XCreateSimpleWindow
et une deuxième, fille de la première, avec un bord d’une
certaine épaisseur. Affichez les deux fenêtres, puis
déplacez la fille dans la mère avec XMoveWindow sur chaque entrée de caractère lu.
Quittez le programme en cas de lecture d’un caractère
‘Q’. (Voir les indications données dans le squelette de
programme à la fin).
2)
Créez une fenêtre principale (fille de la racine) ayant un bord
d’épaisseur 10 à l’aide cette fois de la
fonction XCreateWindow. Mettre son attribut override_redirect à True et l’afficher sur
l’écran. Comparez
le résultat de l’exécution du programme en ayant
l’attribut override_redirect à False.
Exercice
2: (programme winGravity.c)
Le
but de l’exercice est de tester l’attribut win_gravity des fenêtres filles. Pour cela, reprendre la
première question de l’exercice précédent, mais
créer la fille avec XCreateWindow et un
attribut win_gravity dont la valeur sera fournie par le premier argument
du programme (passer une chaîne indiquant une valeur de win_gravity). Observez le résultat obtenu selon ces
différentes valeurs quand vous changez la taille de la fenêtre
mère.
Exercice
3: (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 la commande bitmap, car elle est
buguée). Editer ce fichier. L’inclure ensuite en tête du
programme et utilisez XCreatePixmapFromBitmapData pour créer un Pixmap, que
vous attribuerez ensuite comme fond à une fenêtre
créée avec XCreateWindow.
Exercice 4: (programme events.c)
1) Sélectionner sur une fenêtre les événements de type ButtonPress, ButtonRelease et MotionNotify.
Dans la boucle de traitement des événements, pour chaque type d’événement reçu, imprimer le type de l’événement, l’identificateur de la fenêtre ayant reçu l’événement (comme entier) et la position en (x, y) de la souris.
2) Faites varier ensuite le masque de sélection
des événements de la fenêtre pour ne recevoir les
événements de mouvement souris que lorsque le bouton 2 est
enfoncé.
Exercice 5: (programme scrollRoot.c)
Créez un Pixmap suffisamment grand pour y copier le contenu de la racine grâce à la fonction XCopyArea. Le recopier ensuite dans une autre fenêtre (quand elle sera présente à l’écran) sur enfoncement d’un bouton souris, et le faire défiler dans la fenêtre quand l’utilisateur déplacera la souris avec un bouton enfoncé.
Indications : pour faire défiler le contenu, on utilise encore lXCopyArea. XCopyArea (comme XCopyPlane) effectue une copie de rectangle d’un drawable vers un autre, c’est-à-dire fait une copie entre des fenêtres et/ou des Pixmap. On peut donc l’utiliser pour faire la copie d’une fenêtre (par exemple la racine) vers un Pixmap, et ensuite copier un Pixmap (notre copie d’écran initiale) vers une autre fenêtre.
Exercice
1 question 1):
#include
<stdio.h>
#include
<X11/Xlib.h>
#define
LARGEUR 300
#define
HAUTEUR 400
char*
nom_de_station
= NULL;
unsigned
long pixel_blanc,
pixel_noir;
Display*
dpy;
Window
root;
int
screen;
/*
* Une fonction pour imprimer un message
d’erreur et
* quitter le
programme
*/
void
erreur (char *message, unsigned long a1, unsigned long a2, unsigned
long a3) ;
{
printf
(message, a1, a2, a3);
exit (1);
}
int
main (int argc, char ** argv) ;
{
Window
Fenetre,
sous_fenetre;
char
lire; /* caractere pour quitter*/
/*
* 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
* screen, root, pixel_blanc et
pixel_noir
*/
dpy =
XOpenDisplay (nom_de_station);
if (dpy ==
NULL)
erreur
("%s: Impossible d'ouvrir%s\n", argv[0],
XDisplayName(nom_de_station));
screen = DefaultScreen (dpy);
root
=
RootWindow (dpy,
screen);
pixel_blanc
= WhitePixel
(dpy, screen);
pixel_noir =
BlackPixel
(dpy, screen);
/*
* Creation de la fenetre principale
*/
Fenetre = XCreateSimpleWindow (dpy, root, 100,
100,
LARGEUR,
HAUTEUR, 2,
pixel_blanc,
pixel_noir);
/*
* Creer la sous-fenetre
*/
sous_fenetre = …
/*
* Demander l’affichage des fenetres a
l’ecran
*/
XMapSubwindows
(dpy, Fenetre);
XMapWindow
(dpy, Fenetre);
/*
* Envoyer les requetes au
serveur
* et attendre
*/
XFlush
(dpy); /*
pour envoyer les requetes au serveur */
sleep(3);
/* pour augmenter le
suspens */
lire =
getchar(); /* pour
controler l'attente */
/*
* Deplacer la sous-fenetre
*/
while (
(lire = getchar()) != ‘Q’) {
…
};
exit(1) ;
}
Exercice
1 : ajouts pour la question 2):
…
#include
<X11/Xutil.h>
…
main
(argc, argv) char **argv;
{
Window
Fenetre,
sous_fenetre;
XSetWindowAttributes xsw;
…
/*
* Creer la fenetre avec XCreateWindow et
donner une valeur
* pour override_redirect et les couleurs
*/
xsw.background_pixel
= pixel_noir ;
xsw.border_pixel
=
pixel_blanc ;
xsw.override_redirect
=
True;
Fenetre =
XCreateWindow (dpy, root, 100, 100,
LARGEUR,
HAUTEUR, 10,
CopyFromParent,
InputOutput, CopyFromParent,
CWBackPixel
| CWBorderPixel
|
CWOverrideRedirect,
&xsw);
…
}
Exercice
4:
int main
(int argc, char ** argv);
{
/* toujours le meme
debut */
…
Fenetre =
XCreateSimpleWindow (dpy, root, 100, 100,
LARGEUR,HAUTEUR,
2,
pixel_blanc,
pixel_noir);
XSelectInput(dpy,
Fenetre,
ButtonPressMask
| ButtonReleaseMask
|
PointerMotionMask);
XMapWindow
(dpy, Fenetre);
events();
}
void
events () {
XEvent ev;
for (
; ; ) {
XNextEvent (dpy, &ev); /* récupérer l’événement * /
switch
(ev.type) {
/*
le traiter selon son type */
case
ButtonPress:
/*
On affiche lÕidentificateur de la fenetre
* en masquant les bits de
poids forts
*/
printf
("Fenetre n°%d: Bouton n¡%d \n",
ev.xbutton.window
& 0xff, ev.xbutton.button);
break;
case
ButtonRelease:
printf
("Fenetre #%d: Bouton n¡%d relache\n",
ev.xbutton.window
& 0xff,ev.xbutton.button);
break;
case
MotionNotify:
printf
("Fenetre #%d: Mouvement souris\n
\en %d
%d",
ev.xbutton.window
& 0xff,
ev.xbutton.x,
ev.xbutton.y );
break;
}
}
}