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;

              }   

       }

}