Τα προγράμματα αυτά με την σειρά τους το λαμβάνουν, το επεξεργάζονται και αντιδρούν αναλόγως. Με τον τρόπο αυτό τόσο ο εξυπηρετητής όσο και τα προγράμματα - πελάτες του βρίσκονται σε συνεχώς είτε σε κατάσταση αναμονής μηνυμάτων, είτε σε κατάσταση αντίδρασης σε αυτά. Προγραμματιστικά το μοντέλο αυτό υλοποιείται με ένα βρόχο αναμονής μηνυμάτων, ο οποίος σε περίπτωση λήψης μηνύματος μεταβιβάζει τον έλεγχο στο τμήμα εκείνο του προγράμματος που εξυπηρετεί το συγκεκριμένο μήνυμα. Στο τέλος της εξυπηρέτησης ο έλεγχος επιστρέφει στο βρόχο αναμονής για το επόμενο μήνυμα.
Τα γεγονότα που συμβαίνουν κατά την λειτουργία των Χ Windows είναι πολλά και
ποικίλα. To κάθε πρόγραμμα πρέπει να ορίζει, κατά την εκκίνησή του , για
ποιά γεγονότα θέλει να ενημερώνεται από τον εξυπηρετητή των Χ Windows. Για
το σκοπό αυτό υπάρχει η συνάρτηση XSelectInput
:
XSelectInput( Display* /* display */, Window /* window */, long /* event_mask */ );Η
XSelectInput
παίρνει τρία ορίσματα, το display, το παράθυρο του
προγράμματος και μια μάσκα που ορίζει για το τι τύπου γεγονότα να
ενημερώνεται το πρόγραμμα. Η τιμή της μάσκας σχηματίζεται με τον γνωστό
τρόπο με βάση προκαθορισμένες σταθερές που ορίζονται στο αρχείο Χ.h
. Για
παράδειγμα με την επόμενη εντολή ορίζουμε πως το παράθυρο window θα
ειδοποιείται όταν πατηθεί κάποιο κουμπί του ποντικιού (ButtonPressMask
),
κάποιο πλήκτρο του πληκτρολογίου (KeyPressMask
) ή όταν εμφανιστεί το
παράθυρο:
XSelectInput( display, newwindow, ButtonPressMask | KeyPressMask | ExposureMask );Από τη στιγμή που ορίζουμε τι μηνύματα θέλουμε να έρχονται στο πρόγραμμά μας και εμφανίσουμε (map) το παράθυρο που θα τα λαμβάνει είμαστε έτοιμοι να τα δεχθούμε. Η λήψη των γεγονότων - μηνυμάτων γίνεται με τη συνάρτηση
XNextEvent
:
XNextEvent( Display* /* display */, XEvent* /* event_return */ );Η
XNextEvent
μπλοκάρει το πρόγραμμά μας περιμένοντας να λάβει κάποιο
γεγονός. Όταν αυτό φθάσει μεταφέρει τις πληροφορίες του σε μια ένωση (union)
XEvent
(το δεύτερο όρισμα). Η ένωση XEvent
, η οποία ορίζεται στο αρχείο
Xlib
, έχει περισσότερα από τριάντα πεδία στα οποία περιέχει όλες τις
αναγκαίες πληροφορίες για τον τύπο του γεγονότους και τον τρόπο που
προκλήθηκε. Σημαντικότερο πεδίο είναι το πρώτο (XEvent.type
) που
προσδιορίζει τον τύπο του γεγονότους (πάτημα πλήκτρου, κουμπιού του
ποντικιού κτλ.). Το κάθε ένα από τα υπόλοιπα πεδία αφορά ένα συγκεκριμένο
τύπο γεγονότους. Σε κάθε περίπτωση η ένωση XEvent
περιέχει το πρώτο πεδίο με
τον τύπο του γεγονότους και ένα μόνο δεύτερο πεδίο αυτό που αντιστοιχεί στο
γεγονός. Η τιμή του πρώτου πεδίου είναι μια από τις προκαθορισμένες
σταθερές, ονόματα των γεγονότων, που ορίζονται στο αρχείο Χ.h
. Με βάση την
τιμή αυτή το πρόγραμμα ενεργεί αναλόγως, όπως στο παράδειγμα που ακολουθεί
σαν συνέχεια της παραπάνω εντολής XSelectInput
:
XEvent xevent; int done = 0; . . . while( !done ) { XNextEvent( display, &xevent ); switch( xevent.type ) { case ButtonPress: done = buttonpressed( &xevent ); break; case KeyPress: done = keypressed( &xevent ); break; case Expose: redrawwindow(); break; } } . . .Στο παραπάνω απόσπασμα η
XNextEvent
περιμένει για το γεγονός. Όταν αυτό
έρθει μεταφέρονται τα στοιχεία του στην xevent και ο έλεγχος μεταβαίνει στην
εντολή switch. Εκεί αναλόγως με το είδος του γεγονότους (ButtonPress
,
KeyPress
ή Expose
) εκτελείται η αντίστοιχη συνάρτηση του προγράμματος. Στις
συναρτήσεις αυτές περνάμε σαν όρισμα την xevent
για να είναι δυνατή η
περαιτέρω διερεύνηση του γεγονότους. Η διαδικασία αυτή συνεχίζεται συνεχώς
μέσα στο while ώσπου να γίνει η done διάφορη του μηδενός.