Next | Prev | Up | Top | Contents | Index

Creating a Colormap and a Window

A colormap determines the mapping of pixel values in the framebuffer to color values on the screen. Colormaps are created with respect to a specific visual.

When you create a window, you must supply a colormap for it. The visual associated with a colormap must match the visual of the window using the colormap. Most X programs use the default colormap because most X programs use the default visual. The easiest way to obtain the colormap for a particular visual is to call XCreateColormap():

Colormap XCreateColormap (Display *display, Window w, Visual *visual, 
                         int alloc)
Here's how Example 3-2 calls XCreateColormap():

swa.colormap = XCreateColormap(dpy, RootWindow(dpy, vi->screen),
                                      vi->visual, AllocNone);
The parameters specify the display, window, and visual, and the number of colormap entries to allocate. The alloc parameter can have the special value AllocAll or AllocNone. While it is easy to simply call XCreateColormap(), you are encouraged to share colormaps. See Example 4-2 for details on how to do this.

Note that you can't use AllocAll if the colormap corresponds to a visual that has transparent pixels, because the colormap cell that corresponds to the transparent pixel cannot be allocated with AllocAll. For more information about colormaps, see "Using Colormaps". For information on overlays, which use a visual with a transparent pixel, see "Using Overlays".

You can then create a window using XCreateWindow(). Before calling XCreateWindow(), set the attributes you want in the attributes variable. When you make the call, indicate valuemask by OR-ing together symbolic constants that specify the attributes you've set. Here's how Example 3-2 does it:

swa.background_pixmap = None;
swa.border_pixel = 0;
swa.event_mask = ExposureMask | StructureNotifyMask | KeyPressMask;
win = XCreateWindow(

dpy, /*display*/

RootWindow(dpy, vi->screen), /*parent*/

0, /*x coordinate*/

0, /*y coordinate*/

300, /*width*/

300, /*height*/

0, /*border width*/

vi->depth, /*depth*/

InputOutput, /*class*/

vi->visual, /*visual*/

CWBackPixmap|CWBorderPixel|CWColormap|CWEventMask,

/*valuemask*/

&swa /*attributes*/

);
Most of the parameters are self-explanatory. Here are three that are not:

Note: If the window's visual or colormap does not match the visual or colormap of the window's parent, you must specify a border pixel to avoid a BadMatch X protocol error. Most windows specify a border zero pixels wide, so the value of the border pixel is unimportant; zero works fine. If the window you are creating is a top-level window (meaning it was created as a child of the root window), consider calling XSetWMProperties() to set the window's properties after you've created it.

void XSetWMProperties(Display *display, Window w,
                     XTextProperty *window_name, XTextProperty *icon_name,
                     char **argv, int argc, XSizeHints *normal_hints,
                     XWMHints *wm_hints, XClassHint *class_hints)
XSetWMProperties() provides a convenient interface for setting a variety of important window properties at once. It merely calls a series of other property-setting functions, passing along the values you pass in. For more information, see the reference page.

Note that two useful properties are the window name and the icon name. The example program calls XStoreName() instead to set the window and icon names.


Installing the Colormap

Applications should rely on the window manager to install the colormaps instead of calling XInstallColormap() directly. The window manager automatically installs the appropriate colormaps for a window, whenever that window gets keyboard focus.

By default, the window manager looks at the top-level window of a window hierarchy and installs that colormap when the window gets keyboard focus. For a typical X-based application, this is sufficient, but an application based on OpenGL typically uses multiple colormaps: the top-level window uses the default X colormap, and the Open GL window uses a colormap suitable for OpenGL.

To address this multiple colormap issue, call the function XSetWMColormapWindows() passing the display, the top-level window, a list of windows whose colormaps should be installed, and the number of windows in the list.

The list of windows should include one window for each colormap, including the top-level window's colormap (normally represented by the top-level window). For a typical OpenGL program that does not use overlays, the list contains two windows: the OpenGL window and the top-level window. The top-level window should normally be last in the list. Xt programs may use XtSetWMColormapWindows() instead of XSetWMColormapWindows(), which uses widgets instead of windows.

Note: The program must call XSetWMColormapWindows() even if it is using a TrueColor visual. Some hardware simulates TrueColor through the use of a colormap. Even though the application doesn't interact with the colormap directly, it is still there. If you don't call XSetWMColormapWindows(), your program may run correctly only some of the time, and only on some systems. Use the xprop program to determine whether XSetWMColormapWindows() was called. Click the window and look for the WM_COLORMAP_WINDOWS property. This should be a list of the windows. The last one should be the top-level window. Use xwininfo, providing the ID of the window as an argument, to determine what colormap the specified window is using, and whether that colormap is installed.


Next | Prev | Up | Top | Contents | Index