Xlib: la couleur


Dernière révision, le 14 Octobre 1996

Table des matières


Généralités

Jusqu'à présent nous avons spécifié les couleurs au travers des champs foreground et background d'un GC. Pour cela, nous avons utilisé les macros BlackPixel() et WhitePixel() car nous nous étions limités au noir et blanc. Il est cependant possible de mettre dans ces champs une valeur correspondant à une vértitable couleur.

Comment utiliser la couleur ? Comment X gère-t-il les couleurs ?

Parceque X a été conçu pour supporter une large variété d'architectures hardware, les mécanismes de gestion de la couleur proposés par la Xlib sont relativement complexes.

Concepts de base, vocabulaire incontournable

La plupart des écrans couleurs aujourd'hui utilisent le modèle RGB pour le codage des couleurs.

Un écran couleur utilise plusieurs bits par pixels (multiple bit planes screen) pour coder la couleur de ce pixel (pixel value).

Une colormap est utilisée pour transformer la valeur numérique d'un pixel (pixel value) vers la couleur effectivement visible à l'écran. Une colormap est en réalité une table située dans la mémoire du serveur; la valeur numérique d'un pixel est un index dans cette table (pixel value). A une pixel value de 16 correspond une couleur spécifiée par le seizième élément de la colormap. Un élément de la colormap est appelé un colorcell.

En général, chaque colorcell contient 3 valeurs codées sur 16 bits, correspondant aux intensités de chacune des composante RGB.

Si on utilise 8 bits (sur les 16) pour coder chaque composante, un colorcell peut coder 256 puissance 3 couleurs (16 millions).

Le nombre de couleurs pouvant être affichées simultanément à l'écran dépend du nombre de bitplanes utilisés pour coder la pixel value. Un système à 8 bitplanes pourra indexer 2 puissance 8 colorcells (256 couleurs). Un système avec 24 bitplanes pourra afficher 16 millions de couleurs.

Allocation des couleurs

Un client désirant utiliser une couleur donnée ne spécifie pas explicitement la pixel value et la couleur de la colorcell correspondant à cette pixel value. A la place, il demande l'accès à un colorcell dans la colormap (gérée par le serveur X), et une pixel value lui est retournée.

On appelle ce mécanisme l'allocation d'une couleur.

Lorsqu'un client désire utiliser la couleur bleu, c'est comme s'il posait au serveur la question :

"Quelle colorcell dois-je utiliser pour dessiner en bleu ?",

et le serveur lui répond :

"Tu peux utiliser la colorcell correspondant à cette pixel value!"

C'est ça l'allocation des couleurs!

Nommage des couleurs :

La base de données de couleurs standards

X propose une base de données de couleurs standards, qui associe des noms de couleurs à des valeurs RGB. Cette base de données standard encourage le partage des couleurs par les applications clients. Elle se trouve dans /usr/lib/X11/rgb.txt (/usr/openwin/lib/rgb.txt sous OpenWindows) et possède près de 300 entrées.

Le partage des couleurs ne peut intervenir que si deux applications allouent une même couleur read-only, c'est-à-dire une couleur possèdant les mêmes valeurs des composantes R, G et B, et ne pouvant être modifiée (c'est pourquoi on l'appelle read-only). A l'aide de cette base de données, il y a plus de chances pour que les clients partagent les couleurs que s'ils les allouent eux-même en les prenant parmi les 2 puissance 48 combinaisons RGB possibles.

Il est à noter que le serveur X n'utilise pas directement le fichier /usr/lib/X11/lib/rgb.txt, mais une version compilée de celui-ci.

Nommage hexadécimal des couleurs

Il est également possible, même si cela est déconseillé, de spécifier une couleur en hexadécimal.

Quatre formats possibles :



    #RGB           (4 bits pour chaque composante)
    #RRGGBB        (8 bits    "    "    "    "   )
    #RRRGGGBBB     (12 bits   "    "    "    "   )
    # RRRRGGGGBBBB (16 bits   "    "    "    "   )


Chaque lettre correspond à un chiffre hexadécimal. #3a7 et #3000a0007000 sont équivalents.

Différents types d'écrans (Displays hardware)

Ecrans les plus courants (mid-range display hardware)

Les machines les plus courantes possèdent entre 4 et 8 bitplanes pour l'affichage et utilisent les techniques de colormaps indexées présentées précedemment (colormap, colorcell et pixel values).

La correspondance pixel value <-> colorcell autorise un grand choix de couleurs possibles, même si on ne peut en visualiser qu'un nombre limité simultanément.

En général, on ne dispose que d'une seule colormap harware. Toutes les fenêtres affichées à l'écran utilisent les couleurs de cette colormap. Chaque application peut cependant modifier dynamiquement la valeur des colorcells, et ainsi configurer à souhait la colormap hardware.

X propose le concept de colormap virtuelle ou colormap privée, qui permet de gérer plusieurs colormaps, chacune proposant une palette différente; mais une seule peut être active à un moment donné. Ces colormaps sont swappées (échangées avec la colormap hardware) par le Window Manager lorsque le focus passe d'une fenêtre à l'autre. Conséquence de cette limitation : les fenêtres présentes à l'écran voient leurs couleurs s'altérer lorsque le focus est dans une fenêtre possèdant une colormap différente.

Ecrans Monochrome ou en niveaux de gris (Gray Scale)

Les écrans Monochromes possèdent un seul bitplan. Chaque pixel value peut valoir 0 (noir) ou 1 (blanc).

Les écrans en niveaux de gris fonctionnent également avec des pixel values et une colormap mais les colorcells ne contiennent qu'une seule valeur correspondant à l'intensité du niveau de gris (au lieu de 3 intensités RGB pour un écran couleur).

Ecrans couleurs haute performance

En général il s'agit d'écrans possèdant au moins 24 bitplanes, et permettant d'afficher 16 million de couleurs simultanément. Toutes les couleurs disponibles sont affichables simultanément.

Dans ce mode, il n'est pas possible de gérer les colormaps de la même manière qu'avec les écrans courants, dont la colormap n'excède pas 256 entrées. On n'imagine pas en effet une colormap de 16 million de lignes!

A la place, les 24 bits de la pixel value sont scindés en 3 valeurs 8 bits, chacune correspondant à l'indice d'un colorcell dans la colormap, chacune correspondant à chaque couleur primaire RGB. Avec ce système il suffit de 3 colormaps primaires, chacune possèdant 256 entrées, pour spécifier 16 million de couleurs sur un écran 24 bits.

Comment X décrit le support couleur avec les Visuals

Qu'est-ce qu'un visual

Un visual décrit les caractèristiques d'une colormap destinée à être utilisée sur un type d'écran donné. Pratiquement, il s'agit d'un pointeur sur une structure de type Visual qui contient des informations concernant un moyen d'utiliser un écran donné (ouf!)

Il est nécessaire de spécifier un visual lors de la création d'une colormap ou de la création d'une fenêtre, et le même visual doit être utilisé lors de ces deux création si la colormap va être associée à la fenêtre. La plupart des fenêtres héritent du visual; bien souvent, lors de la création d'une fenêtre on utilise la macro DefaultVisual() qui retourne le visual de la Root Window, et donc on utilise la colormap par défaut. Une fenêtre crée avec XCreateSimpleWindow() utilise la colormap par défaut.

La structure Visual est opaque. On ne peut accèder aux informations qu'elle renferme directement.


Rappel: un visual décrit UNE MANIERE d'utiliser la couleur sur un écran, mais un écran peut supporter plusieurs visuals. Par exemple, sur un systéme couleur, on peut utiliser à la fois un visual Monochrome et un visual couleur.

Obtenir des informations concernant les visuals supportés par un écran

Deux fonctions sont disponibles : XMatchVisualInfo() et XGetVisualInfo(). Elles renvoient une structure de type XVisualInfo qui est publique (contrairement à la structure Visual qui est opaque).

Le champ class de la structure XVisualInfo correspond à une des six classes possibles: DirectColor, GrayScale, PseudoColor, StaticColor, StaticGray et TrueColor.

On peut connaître les visuals supportés par un écran donné à l'aide de la commande xdpyinfo.

Colormap Type Read/Write Read-Only
Monochrome/Gray GrayScale StaticGray
Single Index for RGB PseudoColor StaticColor
Decomposed Index for RGB DirectColor TrueColor

Comparaison des différents visuals

En pratique, on utilisera le plus souvent le DefaultVisual() qui est celui qui correspond le plus souvent aux besoins usuels et qui exploite au mieux le hardware dont on dispose.

Je ne comprend plus! Entre les visuals, les colormaps Read-Only ou Read/Write, les colorcells qui sont elles aussi Read-Only ou Read/Write, qu'ai je le droit de faire ?

On va essayer de s'y retrouver:

Attention: les colormaps modifiables (Read/Write) ont deux types de colorcells:

Avantages des colormaps immuables:

Désavantages des colormaps immuables:

Avantages des colormaps modifiables:

Désavantages des colormaps modifiables:

REMARQUE: la colormap par défaut contient des colorcells en Read-Only et en Read-Write. Si une application ne trouve pas dans cette colormap toutes les couleurs dont elle a besoin, elle pourra modifier, si elles sont disponibles, les colorcells en Read/Write. Il faut néanmoins remarquer que ces colorcells ne seront plus disponibles pour les autres applications tant qu'elles ne seront pas libérées. Dans ce cas, la seule solution pour l'application en manque de couleurs consiste à allouer une nouvelle colormap (une colormap privée). C'est ce que font certaines applications comme XV.

Allocation de couleurs partagées

Lorsqu'on peut s'en contenter, pour les raisons précedemment citées, il est fortement conseillé d'allouer des couleurs en Read-Only.

La pixel value retournée par les fonctions d'allocation de couleur servira à positionner les champs foreground ou background d'un GC ou bien les attributs background_pixel ou border_pixel d'une window.

Fonctions d'allocation de couleurs en Read-Only

XAllocColor()
Renvoie la pixel value (indice de colorcell dans la colormap) qui contient la valeur RGB demandée, ou qui contient la valeur RGB la plus proche disponible sur cet écran.
XAllocNamedColor()
Renvoie la pixel value (indice de colorcell dans la colormap) qui contient la valeur RGB correspondant au nom passé en paramètre (qui doit être dans la base de données des couleurs standards), ou qui contient la valeur RGB la plus proche disponible sur cet écran. L'utilisation de cette fonction est recommandé car les couleurs ont plus de chances d'être partagées.

XParseColor() parse le nom d'une couleur ou la spécification hexadécimale d'une couleur et renvoie les valeurs RGB correspondantes. On l'utilise en général en tandem avec XAllocColor().

L'utilisation de ces deux fonctions au lieu de XAllocNamedColor() permet de repérer de manière plus fine les erreurs de syntaxe dans la spécification de la couleur.

Connaître les valeurs RGB de chaque colorcell

Les fonctions XQueryColor() et XQueryColors() permettent de connaître les valeurs RGB de chaque colorcell.


ATTENTION : il n'est pas possible de savoir si une colorcell est Read/Write ou Read-Only!

La seule manière de savoir combien de colorcells sont disponibles pour l'allocation consiste à allouer N couleurs à l'aide de la fonction XAllocColorCells(), avec une grande valeur de N, puis à recommencer en diminuant la valeur de N jusqu'à ce que l'allocation ait réussi (il est recommandé de ruser en procèdant par dichotomie).


Une requête d'allocation de couleur peut échouer parcequ'il n'y a plus de colorcell de libre dans la colormap, ou, dans le cas d'allocation de couleur en read-only, s'il n'y a pas de colorcell dans la colormap dont la couleur est suffisamment proche de la couleur RGB demandée. Ainsi, les applications doivent allouer les couleurs en testant la valeur de retour de chaque requête. SI la valeur de retour de XAlloc...() est False alors il faut recommencer l'allocation avec des paramètres différents. Si vraiment il y a trop d'echecs, alors il faudra soit travailler avec un nombre de couleurs limité, soit allouer une colomap privée. Netscape travaille indifféremment avec la colormap standard ou avec une colomap privée (netscape -install...). Les résultats sont bien différents lorsque la colormap standard est déjà squattée par de nombreuses applications (window manager avec de nombreuses icônes, etc...)

La structure XColor

XAllocColor() et XAllocNamedColor() ont comme argument un objet de type XColor. Cette structure contient les valeurs RGB désirées et la pixel value renvoyée.



     typedef struct {
          unsigned long pixel;               /* pixel value */
          unsigned short red, green, blue;   /* rgb values */
          char flags;                       /* DoRed, DoGreen, DoBlue */
          char pad;
     } XColor;


Lors de l'utilisation de XAllocColor() ou de XAllocNamedColor(), le champ pixel contient la pixel value qu'il faudra utiliser lors du positionnement du GC ou des attributs d'une window. Avec XStoreColor() (étudiée plus tard) et XQueryColor(), ce champ indique quelle colorcell est utilisée (read/write colorcell déjà allouée).

Les champs red, green et blue sont codés sur 16 bits.

Exemple de code allouant des couleurs en Read-Only

Ci-dessous le fichier get_color.ro.c se trouvant dans le répertoire /basicwin/color/ des exemples du volume 1 du livre "XLib programming manual". Vous trouverez ces exemples dans ~buffa/cours/minfo/xlib/exemples_oreilly/*.

Vous pourrez étudier également le programme basic.ro qui utilise ce fichier.



/*
 * Copyright 1989 O'Reilly and Associates, Inc.
 * See ../Copyright for complete rights and liability information.
 */
#include <X11/Xlib.h>
#include <X11/Xutil.h>
#include <X11/Xos.h>
#include <stdio.h>

extern Display *display;
extern int screen_num;
extern Screen *screen_ptr;
extern unsigned long foreground_pixel, background_pixel, border_pixel;
extern char *progname;

#define MAX_COLORS 3

static char *visual_class[] = {
"StaticGray",
"GrayScale",
"StaticColor",
"PseudoColor",
"TrueColor",
"DirectColor"
};

get_colors()
{
    int default_depth;
    Visual *default_visual;
    static char *name[] = {"Red", "Yellow", "Green"};
    XColor exact_def;
    Colormap default_cmap;
    int ncolors = 0;
    int colors[MAX_COLORS];
    int i = 5;
    XVisualInfo visual_info;
        
    /* Try to allocate colors for PseudoColor, TrueColor, 
     * DirectColor, and StaticColor.  Use black and white
     * for StaticGray and GrayScale */

    default_depth = DefaultDepth(display, screen_num);
    default_visual = DefaultVisual(display, screen_num);
    default_cmap   = DefaultColormap(display, screen_num);

    if (default_depth == 1) {
        /* must be StaticGray, use black and white */
        border_pixel = BlackPixel(display, screen_num);
        background_pixel = WhitePixel(display, screen_num);
        foreground_pixel = BlackPixel(display, screen_num);
        return(0);
    }

    while (!XMatchVisualInfo(display, screen_num, default_depth, 
                             /* visual class */i--, &visual_info));

    printf("%s: found a %s class visual at default_depth.\n", 
            progname, visual_class[++i]);
        
    if (i < 2) {
        /* No color visual available at default_depth.
         * Some applications might call XMatchVisualInfo
         * here to try for a GrayScale visual 
         * if they can use gray to advantage, before 
         * giving up and using black and white.
         */
        border_pixel = BlackPixel(display, screen_num);
        background_pixel = WhitePixel(display, screen_num);
        foreground_pixel = BlackPixel(display, screen_num);
        return(0);
    }

    /* otherwise, got a color visual at default_depth */

    /* The visual we found is not necessarily the 
     * default visual, and therefore it is not necessarily
     * the one we used to create our window.  However,
     * we now know for sure that color is supported, so the
     llowing code will work (or fail in a controlled way).
     * Let's check just out of curiosity: */
    if (visual_info.visual != default_visual)
        printf("%s: PseudoColor visual at default depth is not default 
                visual!\nContinuing anyway...\n", progname);

    for (i = 0; i < MAX_COLORS; i++) {
        printf("allocating %s\n", name[i]);

        if (!XParseColor (display, default_cmap, name[i], &exact_def)) {
            fprintf(stderr, "%s: color name %s not in database", 
                    progname, name[i]);
            exit(0);
        }

        printf("The RGB values from the database are %d, %d, %d\n", 
                exact_def.red, exact_def.green, exact_def.blue);

        if (!XAllocColor(display, default_cmap, &exact_def)) {
            fprintf(stderr, "%s: can't allocate color: all colorcells 
                    allocated and no matching cell found.\n", progname);
            exit(0);
        }

        printf("The RGB values actually allocated are %d, %d, %d\n", 
                exact_def.red, exact_def.green, exact_def.blue);
        colors[i] = exact_def.pixel;
        ncolors++;
    }

    printf("%s: allocated %d read-only color cells\n", progname, ncolors);

    border_pixel = colors[0];
    background_pixel = colors[1];
    foreground_pixel = colors[2];
    return(1);
}


REMARQUE: le visual trouvé en premier n'est peut-être pas le default visual. Ce n'est pas très grave dans cet exemple car si un visual couleur est disponible, il est probable que le visual par défaut est aussi un visual couleur; dans ce cas on peut sans craintes allouer des couleurs.

Avec XMatchVisualInfo() il est difficile de trouver un algorithme capable de trouver à coup sûr le default visual. Il est préférable dans ce cas d'utiliser XGetVisualInfo() qui retourne une liste de structures spécifiant les visuals disponibles.

Allocation de couleurs privées (Read/Write colorcells)

Avec des visuals PseudoColor ou TrueColor, un client peut allouer des colorcells en Read/Write.

Quand dois-t-on allouer des couleurs privées ?

Plusieurs cas se présentent :

REMARQUE: l'allocation de couleurs privées n'est pas possible avec des visuals TrueColor ou StaticColor.

Fonctions d'allocation/manipulation de couleurs privées

XAllocColorCells()
Cette fonction permet d'allouer des colorcells privées, dont on peut par la suite changer dynamiquement les valeurs RGB.

Pour allouer simplement quelques colorcells, il suffit de positionner le paramètre ncolors à la valeur désirée et de mettre le paramètre nplanes à 0. Toutes les pixel values seront retournées dans le tableau pixels.

On positionnera les valeurs RGB des colorcells allouées à l'aide des fonctions XStoreColor(), XStoreColors() ou XStoreNamedColor().

XAllocColorPlanes()
Cette fonction ne sera pas étudiée dans l'immédiat.
XStoreColor()
permet de modifier la colorcell READ/Write correpondant à la pixel value passée en paramètre, en lui attribuant les valeurs RGB les plus proches de celles passées en paramètre dans la structure XColor. Ne pas oublier de positionner les flags DoRed, Dogreen et DoBlue correspondants aux composantes RGB qui doivent être modifiées.
XStoreColors()
Idem, mais permet de modifier plusieurs colorcells d'un coup.
XStoreNamedColors()
Très semblable à XStoreColor() sauf que la valeur RGB que va prendre la colorcell correspond à un nom de couleur (qui doit être dans la base de données des couleurs standards).

Exemple de code comprenant l'allocation de couleurs privées

Ci-dessous le fichier get_color.rw.c se trouvant dans le répertoire /basicwin/color/ des exemples du volume 1 du livre "XLib programming manual". Vous trouverez ces exemples dans ~buffa/cours/minfo/xlib/exemples_oreilly/*.

Vous pourrez étudier également le programme basicwin.rw qui utilise ce fichier.



/*
 * Copyright 1989 O'Reilly and Associates, Inc.
 * See ../Copyright for complete rights and liability information.
 */
#include <X11/Xlib.h>
#include <X11/Xutil.h>
#include <X11/Xos.h>
#include <stdio.h>

extern Display *display;
extern int screen_num;
extern unsigned long foreground_pixel, background_pixel, border_pixel;

#define MAX_COLORS 3

get_colors()
{
    int default_depth;
    Visual *default_visual;
    static char *name[] = {"Red", "Yellow", "Green"};
    XColor exact_defs[MAX_COLORS];
    Colormap default_cmap;
    int ncolors = MAX_COLORS;
    int plane_masks[1];
    int colors[MAX_COLORS];
    int i;
    XVisualInfo visual_info;
    int class;

    class = PseudoColor;
    default_depth = DefaultDepth(display, screen_num);
    default_visual = DefaultVisual(display, screen_num);
    default_cmap   = DefaultColormap(display, screen_num);

    if (default_depth == 1) {
        /* must be StaticGray, use black and white */
        border_pixel = BlackPixel(display, screen_num);
        background_pixel = WhitePixel(display, screen_num);
        foreground_pixel = BlackPixel(display, screen_num);
        return(0);
    }

    if (!XMatchVisualInfo(display, screen_num, default_depth, 
                          PseudoColor, &visual_info)) {
        if (!XMatchVisualInfo(display, screen_num, default_depth, 
                              DirectColor, &visual_info)) {

            /* No PseudoColor visual available at default_depth.
             * Some applications might try for a GrayScale visual 
             * here if they can use gray to advantage, before 
             * giving up and using black and white.
             */
            border_pixel = BlackPixel(display, screen_num);
            background_pixel = WhitePixel(display, screen_num);
            foreground_pixel = BlackPixel(display, screen_num);
            return(0);
         }
    }

    /* got PseudoColor visual at default_depth */

    /* The visual we found is not necessarily the 
     * default visual, and therefore it is not necessarily
     * the one we used to create our window.  However,
     * we now know for sure that color is supported, so the
     * following code will work (or fail in a controlled way).
     */

    /* allocate as many cells as we can */
    ncolors = MAX_COLORS;

    while (1) {
        if (XAllocColorCells (display, default_cmap, False, 
                              plane_masks, 0, colors, ncolors))
            break;

        ncolors--;

        if (ncolors = 0)
            fprintf(stderr, "basic: couldn't allocate read/write colors\n");
            exit(0);
     }

     printf("basic: allocated %d read/write color cells\n", ncolors);

     for (i = 0; i < ncolors; i++) {
         if (!XParseColor (display, default_cmap, name[i], 
                           &exact_defs[i])) {
             fprintf(stderr, "basic: color name %s not in database", name[i]);
             exit(0);
         }

         /* set pixel value in struct to the allocated one */
         exact_defs[i].pixel = colors[i];
     }

     /* this sets the color of read/write cell */
     XStoreColors (display, default_cmap, exact_defs, ncolors);
     border_pixel = colors[0];
     background_pixel = colors[1];
     foreground_pixel = colors[2];
}



Le programme principal qui appelle cette fonction get_colors() contient un appel à XQueryColor() pour connaître les valeurs RGB des colorcells allouées par get_colors() (fichiers séparés).

Le main fait également appel à XStoreColor() pour modifier dynamiquement la couleur du texte qui est affiché dans la fenêtre sans avoir à le re-dessiner. Essayez donc le programme basic.rw et cliquez sur un bouton souris pour modifier la couleur du texte.



void main(argc, argv)
int argc;
char **argv;
{
    XColor color;
    unsigned short red, green, blue;
        .
        .
        .
    /* open display, etc... */

    color.pixel = foreground_pixel;
    XQueryColor(display, DefaultColormap(display, screen_num), &color);

    printf("red is %d, green is %d, blue is %d\n", 
            color.red, color.green, color.blue);

    while (1)  {
        XNextEvent(display, &report);
        switch  (report.type) {
            .
            .
            .
            case ButtonPress:
                color.red += 5000;
                color.green -= 5000;
                color.blue += 3000;

                printf("red is %d, green is %d, blue is %d\n", 
                        color.red, color.green, color.blue);

                XStoreColor(display,  DefaultColormap(display, screen_num), 
                            &color);
                break;
            .
            .
            .
    }
}


Colormaps standards

A COMPLETER

Création et installation de colormaps

Introduction

Nous avons parlé de colormaps hardware et de colormaps privées ou colormaps virtuelles. Nous allons étudier ici comment manipuler ces objets.

Une colormap hardware est un objet physique dont le contenu (valeurs RGB) est lu par le hardware vidéo de l'écran pour afficher les couleurs. La plupart des stations de travail possèdent une seule colormap hardware. Certaines machines haut de gamme en possèdent plusieurs (station de travail Indy de Sillicon Graphics par exemple), ce qui permet à plusieurs fenêtres d'avoir chacune sa propre colormap hardware.

En général, on peut modifier les valeurs RGB des colorcells de la colormap hardware, ou bien on peut swapper l'ensemble des valeurs de la colormap hardware avec celles d'une colormap située dans la mémoire de l'ordinateur (colormap virtuelle ou privée). Les visuals DirectColor, GrayScale et PseudoColor ne sont disponibles que sur des écrans ayant ces possibilités.

Jusqu'à présent, nous n'avons alloué que des couleurs dans la colormap par défaut (créée lors du lancement du serveur). Sur des écrans limités à 256 couleurs, il arrive souvent que des clients gourmands en couleurs, ou qui nécessitent des couleurs précises pour fonctionner correctement (comme XV, Netscape, Xemacs), allouent la totalité des colorcells disponibles en Read/Write.

Dans ce cas, la solution pour une application en manque de couleurs consiste à utiliser une colormap privée. Le Window Manager se chargera de faire l'échange entre la colormap hardware et cette colormap privée lorsque le focus sera dans une fenêtre de l'application.

Lorsqu'une application crée une colormap privée, elle doit positionner l'attribut colormap de sa top-level window avec l'identificateur de cette colormap, afin que le Window Manager sache quelle colormap installer.

Rappel : le WM ne peut dialoguer qu'avec les top-level windows.

Fonctions de manipulation des colormaps

XCreateColormap()
Crée une colormap correspondant au visual passé en paramètre, avec toutes les colorcells allouées en Read/Write, ou sans allocation de colorcells. Si on n'alloue pas les colorcells lors de l'appel, on pourra par la suite les allouer indépendamment en Read-Only ou en Read/Write à l'aide des fonctions de manipulation de colorcells déjà étudiées. Si on alloue les colorcells lors de l'appel, il suffit ensuite de les initialiser à l'aide de XStoreColors() par exemple.
XfreeColormap()
Libère les ressources occupées par une colormap privée. Envoie un événement ColormapNotify à toutes les fenêtres qui utilisaient cette colormap.
XlistInstalledColormaps()
Liste les colormaps installées.
XCopyColorMapAndFree()
Permet de copier une colormap dans une autre, et de libérer l'ancienne. Ceci est utile lorsque l'allocation des colorcells échoue aprés que certaines colorcells aient été allouées avec succès. Ca évite de re-créer une colormap et de recommencer l'allocation des colorcells depuis le début.
XSetWindowColormap()
Positionne l'attribut colormap d'une window.
XInstallColormap()
Non étudiée. Utile si on veut écrire un Window Manager.
XUninstallColormap()
Non étudiée. Utile si on veut écrire un Window Manager.


michel.buffa@essi.fr