XOpenDisplay
, μπορούμε να προχωρήσουμε στη δημιουργία των παραθύρων. Για το
σκοπό αυτό υπάρχει η συνάρτηση XCreateWindow
. Η XCreateWindow
έχει τα
ακόλουθα ορίσματα (απόσπασμα από το Xlib.h
):
(Window) XCreateWindow( Display* /* display */, Window /* parent */, int /* x */, int /* y */, unsigned int /* width */, unsigned int /* height */, unsigned int /* border_width */, int /* depth */, unsigned int /* class */, Visual* /* visual */, unsigned long /* valuemask */, XSetWindowAttributes* /* attributes */ );Το πρώτο όρισμα (τύπου
Display
) της XCreateWindow
είναι ο δείκτης στο
display στο οποίο έχουμε ήδη συνδεθεί. Δεύτερο όρισμα (τύπου Window
) είναι
το παράθυρο - πατέρας του παραθύρου που ανοίγουμε (βλ. σχήμα 1.1). Το βασικό
παράθυρο κάθε προγράμματος έχει πατέρα το root window. Στην περίπτωση αυτή
μπορούμε να χρησιμοποιήσουμε την μακροεντολή DefaultRootWindow
ως όρισμα. Τα
επόμενα τέσσερα ορίσματα προσδιορίζουν την θέση (x από πάνω, y από αριστερά)
και το μέγεθος (πλάτος,ύψος) του παραθύρου μέσα στο παράθυρο πατέρα του. Το
επόμενο όρισμα είναι το βάθος του παραθύρου, δηλαδή πόσα bits θα
χρησιμοποιούνται ανά pixel ή αλλιώς πόσα bitplans θα έχει το παράθυρο. Και
σε αυτή την περίπτωση μπορούμε να χρησιμοποιήσουμε την μακροεντολή
DefaultDepth
, έτσι ώστε το παράθυρο να έχει τον ίδιο βάθος με την οθόνη στην
οποία θα εμφανιστεί.
Στη συνέχεια ορίζουμε την κλάση του παραθύρου. Η τιμή που δίνουμε εδώ είναι
συνήθως η προκαθορισμένη σταθερά (define) InputOutput
που σημαίνει ότι το
παράθυρο θα είναι εισόδου και εξόδου. Το επόμενο όρισμα (τύπου Visual*
)
παίρνει και αυτό συνήθως την προκαθορισμένη τιμή CopyFromParent
που σημαίνει
ότι το παράθυρο κληρονομεί την αντίστοιχη δομή Visual
του πατρικού
παραθύρου. Η περιγραφή της δομής Visual
είναι εκτός των ορίων του
συγγράμματος αυτού. Τέλος τα δύο τελευταία ορίσματα ορίζουν κάποια επιπλέον
χαρακτηριστικά του παραθύρου με την χρήση της δομής XSetWindowAttributes
. Το
πρώτο από τα δύο ορίσματα (η μάσκα όπως ορίζεται) καθορίζει ποιές από τις
τιμές της δομής XSetWindowAttributes
θέλουμε να προσδιορίσουμε, ενώ το
δεύτερο όρισμα είναι η καθ'αυτή δομή XSetWindowAttributes
με τα δεδομένα.
Η δομή XSetWindowAttributes
, ο ορισμός της οποίας βρίσκεται, μαζί με τους
υπόλοιπους, στο αρχείο Xlib.h
είναι:
typedef struct { /* background or None or ParentRelative */ Pixmap background_pixmap; /* background pixel */ unsigned long background_pixel; /* border of the window */ Pixmap border_pixmap; /* border pixel value */ unsigned long border_pixel; /* one of bit gravity values */ int bit_gravity; /* one of the window gravity values */ int win_gravity; /* NotUseful, WhenMapped, Always */ int backing_store; /* planes to be preseved if possible */ unsigned long backing_planes; /* value to use in restoring planes */ unsigned long backing_pixel;\ /* should bits under be saved? (popups) */ Bool save_under; /* set of events that should be saved */ long event_mask; /* set of events that should not propagate */ long do_not_propagate_mask; /* boolean value for override-redirect */ Bool override_redirect; /* color map to be associated with window */ Colormap colormap; /* cursor to be displayed (or None) */ Cursor cursor; } XSetWindowAttributes;Περιέχει δεδομένα για το σχέδιο και το χρώμα του φόντου του παραθύρου (
background_pixmap
και background_pixel
), αντιστοίχως και για το περιθώριο
(border
) του παραθύρου (border_pixmap
και border_pixel
), για τα χρώματα
(colormap
), για το σχήμα του δείκτη του ποντικιού μέσα στο παράθυρο (cursor
)
και άλλα. Δεν είναι αναγκαίο να δώσουμε σε όλα τα μέλη της δομής τιμές παρά
μόνο σε όσα επιθυμούμε. Τα υπόλοιπα θα λάβουν τις default τιμές τους. Για
παράδειγμα αν δεν ορίσουμε το colormap του παραθύρου, αυτό θα κληρονομήσει
τα χρώματα του πατέρα του. Για να προσδιορισουμε σε ποιά μέλη δίνουμε τιμή
χρησιμοποιούμε το όρισμα valuemask
σαν μάσκα. Η τιμή του valuemask
προκύπτει
από το λογικό άθροισμα προκαθορισμένων σταθερών (defines), κάθε μια από τις
οποίες αντιστοιχεί και σε ένα μέλος της δομής που λαμβάνει τιμή. Οι σταθερές
αυτές ορίζονται στο αρχείο Χ.h
. Ο συγκεκριμένος τρόπος για την μερική
απόδοση τιμών σε μια δομή με τη χρήση μάσκας είναι αρκετά διαδεδομένος στον
προγραμματισμό των Χ Windows.
Στο παρακάτω απόσπασμα κώδικα δίνουμε τιμές στα μέλη background_pixel
,
border_pixel
και cursor
. Στη συνέχεια ανοίγουμε ένα παράθυρο χρησιμοποιώντας
τα στοιχεία αυτά (θεωρείται δεδομένη η μεταβλητή display
από το προηγούμενο
απόσπασμα):
#include <Χ11/cursorfont.h> . . . Window window; XSetWindowAttributes windowattributes; unsigned windowmask; . . . windowattributes.background_pixel = WhitePixel( display, DefaultScreen( display ) ); windowattributes.border_pixel = BlackPixel( display, DefaultScreen( display ) ); windowattributes.cursor = XCreateFontCursor( display,XC_cross ); windowmask = CWBackPixel | CWBorderPixel | CWCursor; window = XCreateWindow( display, RootWindow(display, DefaultScreen(display)), 300, 200, 250, 400, 2, DefaultDepth(display,DefaultScreen(display)), InputOutput, CopyFromParent, windowmask, &windowattributes ); . . .Στο παραπάνω παράδειγμα χρησιμοποιούνται οι μακροεντολές
WhitePixel
και
BlackPixel
οι οποίες επιστρέφουν τα βασικά δύο χρώματα (ανοικτόχρωμο και
σκουρόχρωμο) που χρησιμοποιούνται στο συγκεκριμένο display
. Για τον ορισμό
του δείκτη του ποντικιού (cursor
) χρησιμοποιείται η συνάρτηση
XCreateFontCursor
η οποία παίρνει δύο ορίσματα το δείκτη στο display
και ένα
define που προδιορίζει το σχήμα. Η επιλογή γίνεται μέσα από τη γραμματοσειρά
cursor που περιέχει μια ποικιλία σχημάτων (αντί γραμμάτων). Οι
προκαθορισμένες σταθερές (defines) που προσδιορίζουν τα διάφορα σχήματα της
γραμματοσειράς cursor βρίσκονται στο include file
cursorfont.h
γι'αυτό και το συμπεριλαμβάνουμε στο πρόγραμμά μας.
Σημειώνουμε εδώ ότι για να κλείσουμε ένα παράθυρο υπάρχει η συνάρτηση
XDestroyWindow
με ορίσματα το display και το παράθυρο:
. . . XDestroyWindow( display, window );