You are on page 1of 7

Chapter 11

Using Color in X

Previous chapters describe how to create windows in X and how to dis-


play graphics and text in them. From these discussions, you know that
each window has a background color and a border color. You also know
that the graphics context (GC), which controls the appearance of all out-
put, incfudes foreground ana ~ackground 20lQrsas attribute: that ar; used
byme ahics and tex:t output functi~~. You know that pixt::lvalues
are the values used when specifYingcolors in a GC or for a windo~ s back-
ground. In Chapter 3, "Exploring X Applications," you learned how to
• name colors, so that as a user you can set the colors in an application.
Workstations differ significantly in the way they handle color. Luckily,
XII incorporates an abstract color model that captures most of the com-
monly encountered color handling capabilities. To use s:ol~r in an X
application, you need to understand the color model used by X. Tllis
chapter describes this model and h~ you can use color in your X a2tili:-
cations.
~

•. A monitor that usually is a cathode ra tube CRT, often


referred to as ~he dGplay screen or, simply, scree~ where the
graphics output appears
Gray level
Figure 11.2. look-Up
A 4-bit plane frame table
Most grayscale displays used in X workstations and X terminals are raster disp a s that construct an
buffer with a 16-bit Digital-lo-analog
Ima e sweel2mg an;: ectron beam back and forth across the face of t onitoc As shown in witk look-up table. converter (DAC)

F1
Figure 11.1, each horizontal sweep across the screen constitutes a raster line and a large number of
such raster lines;;:;- e uB one:jiame;.oLth image. ~ Analog
voltage
16 10 electron
bits gun
Figure 11.1.
Raster scan CRT
..• 16
~
bits


,_._----_._--_. ---_.----
•• "::._. _ ••• _ •••• _ •• _"' Horizontal

~~, . etrac

~, Vertical retrace

~ok-Up Tables
:::::::::::::::;j~:::::::::::: ~ graphics adapter generates the signals that control the intensity of the beam. It does this in
accordance with the contents of the frame buffer location that corresponds to the current pixel on
the screen. If a 4- or 8-bit pixel value is used directly as the intensity of the on-screen pixel, there
The source of the electron beam is called the electron gun. The screen itself is coated with an array can be only 16 (24) or 256 (28) fixed levels of gray in the image.
of dots of phosphors t e p ySI Trtlaf'g!<::l'wwh---eITillt by the electron beam. The intensity of A smarter approach is to allow many more gray levels, but use only 2n of these at any time, where
the electron beam controls the brightness of the phosphor it hits. Thus, a line of the image can be n is the number of bits in the pixel value. As shown in Figure 11.2, this can be done by using the
generated by Fontrolling the intensity of the beam as it scans across the screen. The phosphor fades pixel value as an index into a look-up table. If each entry in the 100k-u2 table is a 16-bit value, there
in a short while, but if the lines are redrawn repeatedly, your persistence of vision creates an illusion will be 216 = 65,536 ossible g~ levels. 0 course, Wit -bit pixel values) only 16·of these levels
of a steady im\lge. Most display monitors redraw an entire screenful of raster lines 50 to 70 times a can e used at any time. -
second.
Figure 11.2 shows an additional component, a digital-to-analog converter (DAC), that converts
the digital gray level from the look-up table into a continuously varying voltage that can be used to
control the CRT's electron guns. This is necessary because the CRTs in most workstations are ana-
Because the image corresponds to an intensity level for each pixel on the screen, you can think of a log devices that expect a continuous electrical voltage for the intensity level.
raster image as a two-dimensional array of values. Indeed, Jra hics adapters s~

- -- drat these values are own as pixel values.


he intensitY,level
f each ixel the gray level) in a block of memory known as thr;.ftame br:ffer or video memory. Re- L Raster Displays
Color displays represent any k~ by a combination of th ree rimal:¥,colors:..recl(R), reen G ,
Each pixel value is represented b a fixe ber of bits-usually 4 or 8, even 24 or 32 in higher- and blue (B . A color CRT uses three electron beams--one for each rimary co or.
~erformance Qisplays.Conceptu y, you can thin of the frame buffer organized as a number o'fbir
planes with as many planes as there are bits in each pixel value (see Figure 11.2). T.h,e.number of bit The screen in a color CRT has a repeated triangular pattern of red, green, and blue phosphor dots.
planes is also known as the depth of the display. Each phosphor glows in its color when the electron beam impinges on it. As shown in Figure 11.3,
a pe orated metal screen, known as the shadow mask ensures that each electron beam excites the
correct hos hor. By v ing the intet.lsity 0 e e ec rop earns, many sha es of colors can be dis-
played.
Part Three: Drawing in an X Window

/ Colormaps
In color dis lacs vtith fewer bit planes, the full color scheme is more a£proe.riate with intermediate

-~ -----
look-up tables for each rimary color. These ok;.up,tables are called color look-up' tables or colorma s.
There are two e~owlorma .
•. Each entry of the colormap specifies the i~ten~ty of ~~ of the R, G, and B color~~In t~.is
'case, there are three colorma one for each of the R, G, and B colors .
Magnetic
•. Each e::;-in'the colormap specifies a ingle combination of R, G, and B intensities. In
deflection
Red, green, and
coils
blue phosphor
this case, a sin Ie colorma defines the avai a Ie colors. -- ----
dots in a
triangular Figure 11.5 illu;trates th~ type of colorma ; in this case, each 12-bit pixel value is decomposed
pattern
into three 4-bit values, o&eac orrhe red, green, and blue components. Tnese 4-bit values are
us d as indic into ree colormaps comaming 8-oit iiuensiry values for each color. The intensity
value from the colormaps go to digital-to-analog converters whose outputs control the intensities
of the red, green, and blue guns. Wirh this scheme, there can be 4,096 (212) simultaneous colors out
As in a grayscale display, rhe frame buffeJ;..Qf.8c.color
display storc;srhejnforn:ation that col?-!£olsthe
of a possible 256x256x256 = 16,777,216 (because each colormap is 8 bits wide). Without the
•.intensity of each electron beam. There are two ways of using the information stored in the frame
colormaps, there would be only 4,096 distinct colors.
buffer:
•. Directly, as intensity: levels ofR, G, a~olor~ ./
•. Indirectly, as indices in a color look-u a J Figure 11.5.
A 12-bit fUll colorftame
buffir with an 8-bit
Figure 11.4 shows the situation for a 24-bit color frame buffer. In this case, 8-bit planes are assigned colormap fOr red, green,
to each primary color. Each 8-bir value drives an 8-bit digital-to-analog circuit (DAC) whose out- and blue.
Analog
put is used as the intensity of one of the electron guns. This scheme allows 256 (28) intensity levels voltages
to electron
for each of the red, green, and blue colors. Thus, the display can show 256x256x256 = 16,777,216 guns

(16 million) distinct. colors at once. Such high-performance frame buffers are often known as fUll
colorframe buffers because the entire range of allowable colors is available for use any time.

Figure 11.4.
A 24-bit fUll color
ftame buffer.
Analog
voltages
to electron
guns

The ~second kind


c
of'.\In·
gt
colormaJ>, often employed in displays with 4- or 8-bit frame buffers, uses the
JIP • •

entire rxel value as an index into a single colormap that defines the RGB'leveis. In thiS case, each
colormap entry decomposes into intensity levels of the red, green, and blue electron guns. Figure
11.6 shows a 4-bit frame buffer that indexes into an 18-bit wide colormap. The 18-bit value in each
colormap cell is interpreted as three 6-bit quantities, one each for the R, G, and B components.
Because each component can have 64 (26) possible values, this approach allows a total of 262, 144
(64x64x64) possible colors, of which only 16 (24) can be used at anyone time.
Figure 11.6. 4-bit pixel value •. Using the entire pixel valu~ as an index for a s~ which yields the RGB
from frame buffer Digital-ta-analog components of the-desired color (see Figure 11.6)

t
A 4-bit colorframe buffir

t
converters (DAe)
with an i8-bit wide
colormap (6 bits each for
red, green, and blue).
"-18"-
bits Because g@yscale.-ilisplayscontrol only the intensity of the pixels, the entire pixel value is used to
lpok up the gray level from a single colormap.
Analog
Blue voltages You can think of all color and grayscal~ displays as frame buffers that store pixel values that are used

~
1B-b~ wide
colormap
G:::~t)91
(6-b~)
to electron
guns to look up color or gray levels from one or more colormaps. Even the full-color display of Figure
11.4 falls into this category because that display implicitly assumes a fixed colormap that maps an
index to itself.
Red .
Color displays are further classified on the basis of the number of colormaps: a single colormap
,'""', ~G ,
indexed by the pixel value or three separate colormaps (one each for R, G, and B) indexed by spe-
cific bits of the pixel value.

• read-
,
X encapsulates the common features of the display hardware in a data structure called t e Visual.
However, it adds an important twist to encourage,sfiaring 0 co ormaps: X allows colormaps to e
-write. Cells in the read-write colorma s can be changed d naml
colormaps are fixed.
; rea -on y

Each sC,reenin an X display has a Visual structure that characterizes its capabilities. The class
Colormap entries specifying R, G, Bleve1s are called RGB,values.
. member of the Visual structure in icates these capabilities. Figure 11.7 shows tIie classification
"' •..• ~ - of
coror and grays~j!1~disRla~ed on the common features of the hardware together~-
Most color workstations use this approach and they typically provide an 8-bit frame buffer with a tio.n of rea<j-write and read-only colormaps. As shown in the figure, this claSSIficationof displays
24-bit wide colormap (8 bits each per R, G, and B). Such color displays support 256 simultaneous results in six distinct classesof Visual, identified by the following constants (defined in <X11 / X. h»:
colors from a palette of over 16 million (256x256x256 = 16,777,216) colors. •. DirectColor visual class models the display shown in Figure 11.5, in which the pixel
v ue IS e mTiposed into qit fields that index into individual colormaps for the R, c:-
and
com onents. 't:co~entries can bediangeaaynamically. This visual class is
Concept of Color in X common among displays with 8 or mote bit planes.
There are several ways to implement a color frame buffer in-hardware. Nevertheless, enough com- •. TrueColor displays are the same as DirectColor, but their colormaps are fixed. The full-
monality exists among the color handling schemes to allow an abstract model that can handle a co or· isp ay Illustrated in Figure 11.4 is modeled by this visual class.
wide variety of color and grayscale displays. This section describes the _~~olor model, many aspects
seudoColor visual class models a commonly encountered dis lau<!rdware-one
of which are directly related to the hardware impiementations of frame buffers. -
erem eac pixe value looks up an GB v ue an t e colormap can be modified any
tim.
aticColor dis l~s are similar to PseudoColor except that the colormap cannot be
If you look carefully at the various ways frame buffers are implemented in hardware, you immedi- modi fie .
ately notice that all graphics displays with multiple bit planes fall into one of two categories: color •. m-a~a-le visual class models a grayscale monitor that enables the intensity map to be
or grayscale. mo Ie. t is the grayscale equivalent of the PseudoColor visual.
urthermore, in color frame buffers, the pixel values can be used in two ways: •. StaticGray is similar to GrayScale, but with a fixed gray level map. Black-and-white
1 me ISPays are modeled by a StaticGray visual with a unity depth.
•. Decomposing the bits in each pixel value into fields that are used to look up the R, G, and
B levels from three separate colormaps (see Figure 11.5)
Figure 11.7.
Visual classes in X
J case PseudoColor:
printf('PseudoColor\n');
break;
~

(
/) (GraYSCale)
case GrayScale:
printf('GrayScale\n');
break;
case DirectColor:
printf('DirectColor\n');
break;

/
"
case TrueColor:
printf ('TrueColor\ n' );
break;
default :
printf('Unknown ...ERROR\n');
break;

StaticGray
.---
Each screen in an X display has at least one associated Visual structure. Many servers provide more
than one visual [or a screen. For instance, the server for an 8-bit display might provide a PseudoColor tAte switchstat:ement in this example directly uses the class member of me screen's
visual of depth 8 and a StaticGray visual of depth 1. Thus, the same screen can be used as a color .v4ual. Bet;q.usethe details of the V:j.sual data structure are supposed to be hidden from
screen or, in the case of StaticGray, as a monochrome one. Later in this chapter you learn how theiiog!~e/.',.this ~xample violates the data-hiding principle. One approach to mini-.
you can select an appropriate visual for your application. ,i,n1:.j,zetll~~~Qa~'S dependence on the definition of Visual is to use a macro to access its
=:r.rreltlb~t;:ForexampM, you might define the following: .
Even if a server supports multiple visuals, one of them is the default visual. You can refer to this :iF'©f~f\i';;, " '," '

default visual by the macro Defaul tVisual (display, screen), which returns a pointer to the Visual I; '#dflfine(;IassOfVisual(v)
~ %' "
«v) ·>c~as$)
structure of the specified screen in the X display identified by display. "aydtis.e ,ClassOfVistlal (v isual) in place of visual· >class. That way, you can
Note that when creating a window, you have to specifY an associated Visual. If you use the a,(:cQriunqdateth,anges in me definition ofVi.sual by simply redefming me macro.
'il'y,,'; /;; . .',' , f

XCreateSimpleWindow function to create a window, the window is automatically created for the
default visual-the visual of the root window.
($~~~'~~ (\{J'~:/j
Display *p_disp; with hardware frame buffers, !.heX color model also uses a~lormap. In X, each window has an
int screen;
associated colormap that determiIi~pow the pixel values are translated into colors (or gray levels in
grayscale monitors). Although the hardware might allow only one colormap, X allows each window
to have its own colormap-as.long as the visual class of the screen is not one of TrueColor,
display = XOpenDisplay(");
screen DefaultScreen(p_disp);
StaticColor, or StaticGray. Before the pixel values in a window are interpreted according to
such a virtual colormap, it has to be installed into the hardware colormap. You need a window manager
visual DefaultVisual(p_disp, screen); to take care of this chore. By convention, most window maflagers implement a policy of installing
depth = DefaultDepth(p_disp, screen); /* same as visual->depth */
a window's colormap into the hardware as soon as the window gains input focus.
printf ('Display type: \n');
if (depth == 1) A colQrma is a resour~~0~ the X seITer. Normally, you do not have to create a new colormap for
printf('Monochrome\n'); your app !Canon. en the server is started, it creates and installs a default colormap. The server
else usually defines only two color cells in this default colormap. The rest of the cells c;m be allocated
{
and used by any X application.
Sharing the Default Colormap When allocating colors or defining new colormap entries, you provide information about the color
in an XColor structure, which is defined in <X11/Xlib. h> as the following:
Often, the default colormap has enough color cells to provide all the colors that a simple applica-
typedef struct
tion needs. All the examples used so far in this book use the default colormap. Before using this
{
colormap, you should understand how X 'expects you to share colors in a colormap. unsigned long pixel; /* Pixel value (after allocation) */
unsigned short red, /* Red intensity (0 . 65,535) */
To use colors from a colorma u first have to find the colormap's identifier, which is a variable green, /* Green intensity (0 . 65,535) */
of type Colormap. en you create a new colormap, you ge! back an 10. For the default colormap, blue; /* Blue intensity (0 . 65,535) */
char flags; /* Used when storing colors */
the colormap's 10 is returned by the macro DefaultColormap( display, screen), which requires
char pad; /* Just so structure size is even */
you to identifY the display and the screen. ou can use Defaul tScreen (display) as the screen };
argument to Defaul tColormap.
You specifY a color by indicating the intensities of the RGB components in the fields red, green,
and blue. These intensities range from 0 to 65,535, where 0 implies no intensity and 65,535 means
Allocating Color Cells full intensity. The server automatically scales these values to the range of intensities needed by the
display screen's hardware.
When you use color in X, you have- to specifY a pix.e;Lya.lue.This value implies a particular color
depending on the contents of the colQ[1n~'p-cell that "itreferences. Th.e first step in using a color in The member named pixel is the pixel value you use to display the color corresponding to the RGB
~o obtain the index of a colormap cell that contains the red, g~een, and blue intensities appro- value in red, green, and blue. When allocating a color, you provide the RGB values for the color
pt=iatefor the color you want. To do this, you request that the X server allocate a colormap cell (in and the server returns the pixel value corresponding tu the colormap cell with that color.
a specified colormap) with your color. When requesting a colormap celf,~ provide the desired
red, green, and blue levels; the X server returns an index that you can use as the pixel value corre-
sponding to that color.---- - -- Allocating Shared Colormap Cells
Xlib provides rwo functions for allocating shared, read-only colormap cells: XAllOccolo,r and
Because many applications may use similar colors, X provides rwo ways to allocate colormap cells:
, , . XAllocNamedColo r. The XAllocColo r function requires that you define an XColor structure and
V • Asking for sh~!ed read-only cells fill the red, green, and blue fields with the RGB levels appropriate for the color you want. You
/. Asking for private read-write cells also have to specifY the colormap in which you want to allocate the color. Typically, you use
XAllocColor in conjunction with XParseColor, which accepts the name of a color and sets up the
\ You can allocate shared read-only cells in any visual class, but to allocate read-write cells, the visual
corresponding RGB values in an XColor structure.
class must allow the colormap to be altered. That means the visual class has to be DirectColor,
PseudoColor, or GrayScale. To allocate a light cyan color in the default colormap and use it as the background of a window,
you might use this code:
For each colormap, the X server keeps track of cells currently in use. When the server receives a
request for a shared read-only cell in a colormap, it determines !he closest color the hardware can Display *p_disp;
XColor color;
support. Then it searches any previously allocated read-only cells in that colormap for one that may Colormap default_cmap;
already contain that color. If the server finds such a cell, it returns the information about that cell. unsigned long bgpixel;
Otherwise, if the visual class permits writing to the colormap, the server allocates a new cell for read-
default_cmap = DefaultColormap(p_disp,
only use, loads the requested color into the cell, and returns that information. DefaultScreen(p_disp»;
The nice thing about shared, read-only colormap cells is that you can use them on any visual; bur
to allocate private, read-write colormap cells, you have to make sure the visual is DirectColor,
PseudoColor, or GrayScale. if (XParseColor(p_disp, default_cmap, "light cyan",
&color) == 0 ::
'V Private, read-write cells also have some advantages. They enable you to alter the mapping of pixels XAllocColor(p_disp, default_cmap, &color) == 0)
{
t;Color ;;:;y ti~e. This ~n be useful when displaying images-you can change the colors of an /* Use white background in case of failure */
image by altering the colormap entries-without having to redraw the image with new pixel values. bgpixe.l = WhitePixel(p_disp, DefaultScreen(p_disp»;
Also, private colormap cells can be allocated in a single contiguous block so that the pixel values are }
else
in sequence. This can be useful if the application requires that rhe displayed colors relare to the
{
pixel values in a well-defined way. /* Colormap cell successfully allocated */
that it is easy to map the data into colors. You may also want to alter the mapping of data to colors
to bring out features of the data. This type of need is best handled by allocating a contiguous block
of private, read-write colormap cells.

(See Chapter 3 for information on naming colors in X applications.)


First, XPars9Coior sets up the RGB values in color for the color named light cyan. Then, The XAllocColorCells function is a convenient way to allocate read-write color cells. Of course,
befote you use this function, you must make sure that the screen's visual class allows alterations to
XAllocColor requests a read-only color cell with that RGB value. If all goes well, both functions
return nonzero values and the pixel member of color contains the pixel value that you should use the colormap (the class must be DirectColor, PseudoGolor, or GrayScale).
wherever you need the light cyan color. If rhe functions fail, you must include some means of You call XAllocColorCells as follows:
handling the situation. In this example, if the allocation fails, the white is used as the background
Display *p_disp;
color. The server always allocates the white and black colors in the default colormap. You can cmapi /* Colormap where cells are allocated*/
Colormap
refer to these colors by the macros WhitePixel(display,screen) and Bool contig i /* True = allocate contiguous planes */
BlackPixel (display, screen), respectively. unsigned long planesl]j /* Array to hold plane masks */
unsigned int nplanesj /* Number of planes to allocate */
unsigned long pixelsl]i /* Array to hold pixel values */
unsigned int npixelsi /* Number of pixels to allocate */

XAllocColorCells(p_disp, cmap, contig, planes, nplanes, pixels,


The X server provides a color database that applications can Use to translate textual names npixels) j
of colors into red, green, and blue intensities appropriate for that particular display screen.
X requires you to specify the read-write colormap cells in a unique manner. You speei.~ the number
The functions XParse~olor and XAllocNamedColor use t,his database.
of pixel values, npixels, and the number of planes, nplanes. npixels must be posltlve; nplanes
can be 0 or positive. In return, the server reserves np,ixels*2nplanes colormap cells and returns
XAllocNamedColor is similar to XAllocColor except thilt it directly takes the name of a color as a the information about the usable cells in the arrays pixels and planes. There will be npixels
string. For instance, when you use XAllocNamedColor, the earlier example of allocating a light values returned in pixels and nplanes bitmasks returned in the planes array.
cyan color cell becomes the following: The npixels argu~ent to XAllocColorCells is not the total number of pixel values that you can
use. To determine.the pixel values that your application can use, consider the following example.
if (XAlloCNamedColor(p_disp, default_cmap, "light cyan", Suppose, for an 8-bit visual, you call XAllocColorCells requesting three pixel values and twO~ol?r
&exact, &color) == 0) planes (npixels = 3 and nplanes = 2). On return from XAllocColor.gells, the three entrles m
{
/* Use white background in case of failure */ the pixels array and the two entries in the planes array are as follows (in binary):
bgpixel = WhitePixel(p_disp, DefaultScreen(p_disp))j
} pixels: 1010 0000 planes: 0000 0100
else 0110 0000 0000 0001
{ 0001 0010
/* Colormap cell successfully allocated */
To arrive at the list of usable pixel values, first form the four possible combinations of masks by
bgpixel = color.pixelj
OR-ing together zero or more entries in the planes array with each other:
XAllocNamedColor requires two XCo1.orarguments. In exact, it returns the exact RGB value for All possible combinations of plane masks:
the requested color (from the database) and in color, it returns the closest color supported by hard-
0000 0000
ware and the pixel value corresponding to the allocated colormap cell (when allocation succeeds). 0000 0001
0000 0100
0000 0101
AJlocating Private Colonnap Cells Next, OR each entty in the pixels array with these masks. There are three entries and four masks,
Some applications need colors to be allocated in the colormap in a specific way. For instance, you so you get the following 12 pixel values for your use:
can display a two-dimensional array of data points as an image, wherein the color of each pixel rep-
12 pixel values:
.resents a data point. When displaying such an image, you may want all pixel values in sequence so