[MSOE Homepage]

Dr. Taylor's MSOE Homepage

Courses

Unix is a Four
Letter Word

My Photo Album

My Personal Homepage

CS-321 Main page

CS-321 -- Using Color in the X Windows System

Summer Quarter 1999



Electrical Engineering and Computer Science Department
Dr. Christopher C. Taylor

S-331, 277-7339
t a y l o r@m s o e.e d u (remove spaces)
www.msoe.edu/~taylor/

Acknowledgment

This page was originally developed by Dr. Henry L. Welch

Color in the X Windows System

Color in the X Windows System can be quite confusing at first, but there is a reasonable amount of logic behind the mechanism. To begin you must realize that X uses one of six possible XVisual types to display color, but the one in use for CS321 is a pallette-based color mechanism which it calls a Colormap.

The Colormap is a table lookup mechanism which translates a pixel value (color id) into the actual red, green, and blue components in which to draw. All of these values (and others) are grouped together into the XColor data structure to facilitate parameter passing to functions.

When X is initialized it automatically creates a Colormap to be used called the DefaultColormapOfScreen. Already installed into this Colormap are some common colors already in use such as white, black, and the colors needed by X and Motif to draw the windows on the screen. Typically this may include up to 16 colors or more. You can choose to use the DefaultColormapOfScreen or create one of your own (which is not generally recommended).

Because X tries to use shared resources when possible it is quite possible that the DefaultColormapOfScreen is in use by other applications and users. Thus, it is very important that the Colormap and colors be managed carefully and correctly. This should be done through the color allocation and deallocation process and the exact usage will depend on how your application will be modeling color.

The simplest approach is to use a read-only colorcell in the Colormap. A read-only cell is used when the color to be used is fixed at the time of allocation and is not expected to change as long as it is in use. Because of its fixed nature read-only colorcells are often shared between applications and users. To allocate a read-only cell an XColor object must be initialized with the desired red, green, and blue values of the desired color. X uses an internal 48-bit color depth so each of red, green, and blue range from 0-65,535 (it actually only uses the 8 most-signficant bits). The cell is then allocated using XAllocColor which will in consultation with the display hardware match the requested color to the closest one it is able to draw. It will then check the Colormap to see if the color is already allocated and if not it will assign a new entry for it. In either case it will change the pixel entry in the XColor object and return Success. It is this pixel entry which is used by the GC (via XChangeGC or XSetForeground) to draw shapes to the screen. Since you do not know if the color is new to the Colormap you must deallocate it using XFreeColors when you are done with it. Since X keeps track of who is using which colorcells you need not worry that you will free it while another application or user still needs it. It does this by maintaining a usage count of the number of times a colorcell was allocated which it decrements every time that same cell is freed. Hence, you will not get in trouble as long as you Free for every time you Alloc.

There are a couple of cautions when using XFreeColors. First, you really shouldn't free any colors you didn't allocate (e.g. WhitePixelOfScreen). Second, XFreeColors expects an array of pixel values so if you only want to deallocate one colorcell you must store it in an array first. (The astute C programmer will note that arrays are always passed by a pointer to the first value and as long as you do not access beyond the first array element you can make a single element look like a size one array by passing the address of the single element.) Finally, unless you are working with color planes you should not specify any to free.

There are also some choices on how the red, green, and blue components of the colorcell are to be chosen. The most straightforward is simply to pick values in the range 0-65,535. This can often be unsatisfying since most users do not think or understand color in this way. To help standardize this X provides a set of predefined color names. They can be found on torres in the file /usr/lib/X11/rgb.txt with their 24-bit color values. These color names can be converted automatically to their respective red, green, and blue designations using XParseColor or XAllocNamedColor. As with XAllocColor both of these return the status of the request with Success indicating that the color name exists and in the case of XAllocNamedColor that the read-only colorcell has been allocated. In addition the color parser can handle a color string of the form "#rrggbb" which should be familiar to web page designers.

For the case where a colorcell needs to be changed after it is created a read-write colorcell will be needed. Since this colorcell can change it will not be shared. Read-write colorcells are allocated using XAllocColorCells. This function can also allocate color planes so unless you need them, indicate none. The CS321 Graphics Shell provides a color editing object (Color) which requires the allocation of a read-write colorcell prior to its use. The value in a read-write colorcell can be changed by using XStoreColor. In order for it to take effect, though the DoRed, DoGreen, and DoBlue fields of the XColor should be set and it is probably a good habit to do so from the beginning. Read-write colorcells are deallocated the same way that read-only colorcells are deallocated.

The final complication to this palette-based color model is that the actual pixel value assigned to the colorcell is not guaranteed to be the same each time a program is executed. This provides a complication when color information needs to be preserved in a file for later use. The most convenient way to do this is to use XQueryColor can be used to have the Colormap tell you the current red, green, and blue settings of a colorcell entry. These red, green, and blue values could then be written to the file and during a later read they can be converted into an allocation call which will provide the new pixel value assigned to the color.


Comments on this page should be directed to Dr. Christopher C. Taylor.