Handler d'événement

Contexte d'association

/* handler.c  */
/* handler d'evenement  */

#include <stdio.h>
#include <X11/Xlib.h>
#include <X11/Xutil.h>
#include <X11/cursorfont.h>
#define NBR_EV 20

typedef void (*traite_ev) () ; /* type des fonctions de traitement */
XContext tab_context [NBR_EV] ; /* tableau des contextes */

Display *display; 
GC      gc;
int     screen; 
Window  root; 
unsigned long white_pixel, black_pixel;  
int fini=0;

void creer_methode (win, type_ev, fct)      /* fct sera la fonction-handler */ 
     Window win;                            /* pour cet evenement survenu   */ 
     int type_ev ;                          /* sur cette fenetre            */
     traite_ev fct ;
{
  traite_ev f ;
  XContext context;
  context = tab_context[type_ev] ; /* contexte indexe par evenement */
  if (context == 0)
    context = tab_context[type_ev] = XUniqueContext () ; 
                                     /* cree un contexte */
  if (XFindContext (display, win, context, (XPointer*)&f) == 0) 
                                            /*cast XPointer necessaire*/
    XDeleteContext (display, win, context);           
  XSaveContext (display, win, context, (XPointer)fct) ; 
               /* associe dans ce contexte d'evenement
                  une fenetre et une fonction*/
}                      

void boucle_principale () {
  XEvent ev ;
  XContext context ;
  traite_ev fct ;
  while (! fini) {
    XNextEvent (display, &ev) ;
    context = tab_context[ev.type] ; 
    if (context != 0 &&
	XFindContext (display, ev.xany.window, context, (XPointer*)&fct) == 0) 
      /* recherche la fonction a traiter pour cette fenetre 
         et cet evenement */
      (*fct) (&ev) ; /* execution de la fonction-handler */
    else
      write (2, "evenement non traite", 20) ;
  }
}

/* les handlers : fonctions de traitements /*
void expose_win(XEvent *ev) {
  XDrawString (display, ev->xexpose.window, gc, 30, 10, "coucou", 6);
}
void buttonpress_win(XEvent *ev) {
  fini=1;
}
void buttonpress_subwin(XEvent *ev) {
  XClearWindow(display, ev->xbutton.window);
  XDrawString (display, ev->xexpose.window, gc, 10, 20, "coucou", 6);
}
 
main() { 
  int     i; 
  Window  win, subwin[3];  
  Cursor cursor;
  if ((display = XOpenDisplay ("")) == NULL) { 
    fprintf (stderr, "Can't open Display\n"); 
    exit (1); 
  } 
  gc = DefaultGC (display, screen); 
  screen = DefaultScreen (display); 
  root = RootWindow (display, screen); 
  white_pixel = WhitePixel (display, screen); 
  black_pixel = BlackPixel (display, screen); 
  win = XCreateSimpleWindow (display, root,  
			     0, 0, 100, 350, 5, black_pixel, white_pixel); 
  cursor = XCreateFontCursor(display, XC_man);
  XDefineCursor(display, win, cursor);
  XStoreName (display, win, "handler"); 
  XMapWindow (display, win); 
  XSelectInput(display, win, ExposureMask|ButtonPressMask);
  creer_methode (win, Expose, expose_win); 
  creer_methode (win, ButtonPress, buttonpress_win); 
  for (i=0; i<3; ++i) {
    subwin[i] = XCreateSimpleWindow (display, win, 20, 20+i*110, 60, 100, 2,
				     black_pixel, white_pixel); 
    cursor = XCreateFontCursor(display, XC_man +i+1);
    XDefineCursor(display, subwin[i], cursor);
    XMapWindow (display, subwin[i]);
    XSelectInput(display, subwin[i], ButtonPressMask);
    creer_methode (subwin[i], ButtonPress, buttonpress_subwin); 
  }
  boucle_principale();
}


Exécution :

Cliquez dans les sous-fenêtres puis dans la principale.

Fonctionnement de ce programme :

Un contexte d'association (type XContext) permets d'associer dynamiquement des données à des fenêtres. En langage C, ces données peuvent être des valeurs, tableaux, ect ..., mais aussi des fonctions (pointeurs de fonctions).

XUniqueContext crée un contexte d'association.

XSaveContext ajoute dans un contexte une association entre des données et une fenêtre.

XDeleteContext supprime une association.

XFindContext fournit les données associées à une fenêtre pour un contexte donné.

Dans ce programme, est mise en oeuvre la gestion d'handler d'événement : à un couple (événement survenu, fenêtre affectée par cet événement) est associé une fonction (handler) de traitement.

 

programme suivant compléments index général fonctions de la XLib événements types dans XLib