3.2.2 Η ΔΗΜΙΟΥΡΓΙΑ ΠΑΡΑΘΥΡΩΝ


Έχοντας ανοίξει μια σύνδεση με τον εξυπηρετητή, με τη χρήση της 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 );

[prev] [up] [next] [contents] [index]