Professional Documents
Culture Documents
Whether you are using shared or private colormap cells, you should free the colors when they are
no longer needed. When an application terminates, the X server automatically frees the colors used
by that application. However, if your application allocates colors often (for example, every time an
image is displayed in a window), you should call XFreeColors to free the colors you no longer
need:
Display *p_disp;
Colormap colormap; f* Cells freed in this colormap *f
unsigned long pixels[]; f* Identifies cells being freed *f
int numpix; f* Number of cells being freed *j
unsigned long planes; f* Identifies planes being freed *f
For private, read-write cells, use a logical OR of rhe plane masks rhat were rerurned by an earlier call
to XAllocColorCells.
Sometimes your application needs more colors than there are free entries in the default colormap.
To display a multicolored image, you may need all available color cells supported by the display
hardware. In these cases, you have to create and set up your own colormap.
When the colormap is ready, you have to associate the colormap with the window in which you
plan to use the colors. Because most displays support only one colormap at a time, you have to
install your colormap before its effects can be seen. The X Window System's rules of eriquette dic-
tate that applications should not insrall colormaps haphazardly. Instead, a window manager should
decide when to install the colormap--usually when the window in question has the input focus.
}
Consult your window manager's documentation and the Inter-Client Communication
else
Conventiom.Manual (ICCCM) for information on using multiple colormaps. {
/* Failed to find a visual. Exit, if application cannot do
.* without this visual.
*/
S~ecting a Visual
;[he first step in creating a colormap is to pick a visual. In particular, the visual's class determines
how the color cells in the colormap are interpreted and used; its depth determines the number of After returning from XMatchVisualInfo, the vis_info structure will have the necessary informa-
entries in the colormap. This is the number of colors you can display simultaneously. If the default tion to use the matched visual. In particular, when a function needs a Visual * argument, you
visual meets your needs (it has enough depth and is of the right class),you can use the Defaul tVisual should use vis info. visual.
macro wherever you have to specifYa visual.
Visual Matching One problem with XmatchVisualInfo is that it fails ifboth the depth and the class do not ex-
If the default visual does not meet your needs, you do not have to give up. Many X displays provide actly match one of the visuals supported by the display. In many instances, all you need is a visual
more than one visual. If you know the exact depth and class of visual you want, you can use the that is better than some minimum acceptable level. For example, if you want to handle an image
XMatchVisualInfo function to locate a matching visual. This function returns a nonzero value if with 3-bit pixel values, a visual of depth greater than 3 will suffice. For these situations, you can use
a matching visual is found and fills in certain fields in an XVisualInfo structure, which is defined another approach to determine a suitable visual:
in <X11/Xutil. h> as the following: 1. Use XGetVisualInfo to retrieve a list of visuals supported by the screen you plan to use.
typedef struct To do this, set the screen member in an XVisualInfo structure and call
{ XGetVisualInfo:
Visual *visual; /* Pointer to Vi~ual struct */
VisualIO visualid; /* Visual resource 10 */ XVisualInfo *vis_list, Vis_template;
int screen; /* Screen number. */ int num_visuals,
int depth; /* Bits per pixel value */
int class; /* One of: OirectColor, */
/* TrueColor, PseudoColor, */ /* Get a list of all visuals for this screen */
/* StaticColor, GrayScale, */ vis_template.screen = theScreen;
/* or StaticGray */
unsigned long red_mask; Vis_list XGetVisual1nfo(theOisplay,
/* Identifies bits in pixel */
unsigned long green_mask; /* value used for the red, */ VisualScreenMask, &vis_template,
unsigned long blue_mask; /* green, and blue levels */ &num_visuals)j
int colormap_size; /* Max. colormap cells */
int if(num_visuals == 0)
bits_perJgb; /* Hardware uses these many */
/* bits to store each of red*/
/* green and blue levels */ fprintf(stderr, 'No visuals foundl\n');
exit(0);
For example, if you want a PseudoColor visual of depth 4, you can call XMatchVisualInfo:
Display *p_disp; Here, the VisualScreenMask constant in the argument list asks XGetVisualInfo to
XVisual1nfo Vis_info; return all visuals for the screen specified by vis_template. screen. The number of visuals
is returned in the integer whose address you provide as the last argument to
XGetVisualInfo. The return value from XGetVisualInfo is a pointer to an array of
XVisualInfo structures.
if(XMatchVisual1nfo(p_disp, screen, 4, PseudoColor, &xvis_info))
{
2. Search through this list and locate a visual that meets your needs. For example, here is the
pick_visual function used in the viewpcx program of Chapter 12, "Pixmaps, Bitmaps, Suppose you want a copy of the default colormap (assume that the default visual meets your needs).
and Images," to pick a visual with class matching class_wanted and depth greater than You can create such a colormap with the following block of code:
or equal to depth_wanted: Display *p_disp;
XVisualInfo int screen, i;
*vis_list; 1* List of visuals returned by *1 XColor 'colors;
1* prior call to: XGetVisualInfo *1 Colormap new_colormap;
int num_visuals; 1* Number of visuals in Vis_list *1
Visual screen = DefaultScreen(p_disp);
theVisual; 1* Selected visual *1 colormap_size = DisplayCells(p_disp, screen);
int Vis_depth; 1* Depth of selected visual *1
XVisualInfo 'p_visinfo;
1* Get RGB values from default colormap *1
int i, status = 0;
XQueryColors(p_disp, DefaultColormap(p_disp, screen),
colors, colormap_size);
forti = 0, p_visinfo = Vis_list; i < num_visuals;
1* Create the new colormap *1
i++, p_visinfo++)
new colormap = XCreateColormap(p_disp,
- RootWindow(p_disp, screen),
if(p_visinfo->class == class_wanted && DefaultVisual(p_disp, screen),
AllocAll) ;
p_visinfo->depth > depth_wanted)
1* Store the colors in the new colormap *1
theVisual p_visinfo->visual; XStoreColors(p_disp, new_colormap, colors, color.map_size);
viS_depth p_visinfo->depth; 1* Now we can release the memory used by the colors
status = 1; * because the X server already has this information.
break; *1
(For further discussion of properties, see Chaptrr 16, "Advanced Topics in X.")
xswa.colormap = new_colormapj
Once this properry has been defined, mwmalso enables you to switch colormaps interactively. To do
xswa.background_pixel = WhitePixel(p_disp,
DefaultScreen(p_disp»; this, bind the function f. next_cmap to one of the keys or mouse buttons. This is done in the . mwmrc
file in your home directory. (See Chapter 2, "Clients, Servers, and Window Managers," for more
xswa.border_pixel = BlackPixel(p_disp,
information on the OSF/Motif window manager.)
DefaultScreen(p_disp»j
Suppose you want the colormaps to switch when you press the Alt key together with the third mouse
/* Window at (xpos, ypos) with dimensions width x height
* w1th border width bdwidth. Visual's depth is vis depth. button, with the mouse pointer in the subwindow that has its own colormap. For this to work,
* The parent window's ID "theMain" - make sure the following line appears in the button-binding section of the. mwmrcfile (in the
*/
DefaultButtonBindings, ExplicitButtonBindings, and PointerButtonBindings sections):
new_win XCreateWindow(p_disp, theMain, xpos, ypos,
Width, height, bdwidth, Vis_depth,
InputOutput, visual,
CWColormap : CWBackPixel : CWBorderPixel,
&xswa) ;
Display *P_disp;
Colormap new_colormapj
Window
int
new_win, theMain;
screen;
Summary
Atom ATOM_WM~COLMAP_WIN; This chapter describes how ou can use color in your X applications. Although X displays vary,in
how co or IS andled inlli!lally, ill h_avecertam commo
-- -......... .
screen DefaultScreen(p_uisp); •. They use fmme b!!ffers with one or more bit planes.
/* Set the WM_COLORMAP_WINDOWS property so that the OSF/Motif •. Colors ar~ composed from different intensities of the primary colors: red, green, and blue
w1ndow manager knows about windows with their (RGB).
:/own colormap. In this case, we have only 1 such window.
•. The hardware uses a colormap or a gra,yscalemap to convert pixel values in the frame
if(new_colormap != DefaultColormap(p_disp, screen» buffer into colors or intensities on the screen.
{