/* propagat.c */ /* propagation d'evenements */ #include <stdio.h> #include <string.h> #include <X11/Xlib.h> #include <X11/Xutil.h> GC gc; Display *display; int screen; Window win, subwin[4], root; unsigned long white_pixel, black_pixel; XSetWindowAttributes attrib; int i; main() { 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, 300, 300, 5, black_pixel, white_pixel); XSelectInput (display, win, ExposureMask | ButtonPressMask ); XStoreName (display, win, "propagat"); attrib.background_pixel = white_pixel ; attrib.border_pixel = black_pixel ; for (i = 0 ; i < 4 ; ++i ) { attrib.do_not_propagate_mask = (i<2) ? ButtonPressMask : 0 ; subwin[i] = XCreateWindow (display, win, (i%2==0) ? 10 : 120, (i<2) ? 10 : 120, 100, 100, 2, CopyFromParent, InputOutput, CopyFromParent, CWBackPixel | CWBorderPixel | ((i<2) ? CWDontPropagate : 0), &attrib); XSelectInput (display, subwin[i], ((i%2==0) ? ButtonPressMask : 0) | ExposureMask); } XMapSubwindows (display, win); XMapWindow (display, win); for (;;) { XEvent ev; char buf[40]; XNextEvent (display, &ev); switch (ev.type) { case Expose : for (i=0 ; i<4 ; ++i) { if (ev.xexpose.window == subwin[i]) { sprintf(buf, "subwin %d", i); XDrawString (display, subwin[i], gc, 5, 10, buf, strlen(buf)); XDrawString (display, subwin[i], gc, 5, 30, (i<2) ? "do_not_propagate" : "propagate ", 16); XDrawString (display, subwin[i], gc, 5, 50, "ButtonPress", 11); XDrawString (display, subwin[i], gc, 5, 70, "select Mask", 11); XDrawString (display, subwin[i], gc, 5, 85, (i%2==0) ? "ButtonPress" : "rien ", 11); } } if (ev.xexpose.window == win) XDrawString (display, win, gc, 5, 280, "Select Mask tout !", 18); break; case ButtonPress : if (ev.xbutton.window == win) { sprintf(buf, "evenement ButtonPress fenetre win\n"); write(1, buf, strlen(buf)); } for (i=0 ; i<4 ; ++i) { if (ev.xbutton.window == subwin[i]) { sprintf(buf, "evenement ButtonPress fenetre subwin %d\n", i); write(1, buf, strlen(buf)); } } break; default : break; } } }
Cliquez dans les différentes fenêtres. Regardez la propagation et la réception des événements affichées dans la fenêtre Xterm;
Si un événement est non sélectionné par une fenêtre, normalement (par défaut) il est transmit à sa parente qui le réceptionne si elle l'a sélectionné, et ainsi de suite. L'attribut do_not_propagate_mask d'une fenêtre permet de spécifier les événements à ne pas transmettre.
Utilisez la propagation d'événement pour réaliser un ascenseur : une tirette (40x40) dans une barre de défilement (400x40). La tirette se positionnera à la position cliquée dans la barre. Et avec la souris enfoncée sur la tirette, vous pourrez la bouger dans la barre. La propagation d'événement vous permettera de traiter tous les événements au niveau d'une fenêtre barre.
programme suivant | index général | fonctions de la XLib | événements | types dans XLib |