/* 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(); }
Cliquez dans les sous-fenêtres puis dans la principale.
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 |