the image cache using XmInstallImage(), which takes the following form:
Boolean
XmInstallImage(image, image_name)
XImage *image;
char *image_name;
The image parameter is a pointer to an XImage data structure that has been previously created or, more commonly,
statically initialized by the application. It is possible to create an image dynamically from an existing window or
pixmap using XGetImage(), but this is not the way the function is typically used.
If you attempt to install an image using an image_name that matches one already in the cache, the function returns
False and the image is not installed. Otherwise, the function returns True. You can uninstall an image by calling
XmUninstallImage(). Once the image is uninstalled, it cannot be referenced by name anymore and a new image
may be installed with the same name. The XImage structure is not copied by XmInstallImage(), so if the image
pointer you pass has been allocated using XCreateImage() or XGetImage(), you must not free the data until
after you call XmUninstallImage().
If XmGetPixmap() or XmGetPixmapByDepth() finds a match in the image cache, it creates the pixmap based
on the image data, not on the image itself. As a result, the pixmap that is created is not affected by the image being
uninstalled by XmUninstallImage().
If the pixmap retrieval routines do not find a match in the image cache, the pixmap is loaded from a file. If
image_name starts with a slash character (/), it is taken as a full pathname. Otherwise, the routines look for the file
using a search path. On POSIX systems, the environment variable XBMLANGPATH can be set to specify a desired
directory in which to search for bitmap files. If this variable is not set, the pathname used is based on the values of the
XAPPLRESDIR, HOME, and LANG environment variables. See the reference page in Volume Six B, Motif
Reference Manual, for complete details on the search path that is used.
When XmGetPixmap() or XmGetPixmapByDepth() looks in the pixmap cache for a image name, the pathname
must match completely for the routine to return a cached image. The file xlogo64 will not match a previously−loaded
pixmap that has the name /usr/include/X11/bitmaps/xlogo64. If you do not need to worry about using different
pixmaps for different environments, we recommended that you always specify a full pathname to these routines to be
assured that you get the desired file.
4.4.6 Color
Color plays an important role in a graphical user interface. It appeals to the senses, so it can provide an aesthetic
quality, while at the same time it can be used to convey information to the user. However, for all the power of color, it
is frequently abused by applications. A color combination that appeals to some people may offend others. The safest
bet with color is to avoid hard−coding any use of color in your application and provide enough flexibility so that the
user can configure colors in a resource file or interactively using the application. Of course, many applications are
based on the use of color, so this sweeping generalization only applies to those parts of an application that are not
dependent on color.
The Motif widget set provides a number of widget resources that specify colors. All of the Motif widgets use the
XmNforeground and XmNbackground resources. However, Motif gadgets do not use these resources because
they are rendered using the foreground and background colors of their parent. Although every widget class makes
different use of the XmN-background and foreground resources, text is typically rendered in the foreground
color and everything else is shown using the background color. Some widgets provide additional color resources for
particular aspects of their appearance. For example, ToggleButtons use the XmNselectColor resource for the
4 Overview of the Motif Toolkit 4.4.6 Color
73
square/diamond selection indicator, PushButtons use XmNarmColor as their background when they are armed, and
ScrollBars use XmNtroughColor to set the color of the area behind the slider and directional arrows.
The XmNborderColor resource is another resource that can be specified for any widget, as it is defined by the Core
widget class. Since Motif widgets typically have a border width of 0, this resource is rarely used. The
XmNhighlightColor resource specifies the color of the highlighting rectangle that is displayed around the
interface component that has the keyboard focus. This resource is defined by the Gadget, Manager, and Primitive
metaclasses, so it can be specified for any Motif component.
Perhaps the most troublesome of all the color resources are XmNtopShadowColor and
XmNbottomShadowColor. These are the colors that give Motif widgets their 3D appearance on a color display. If
set inappropriately, these colors can ruin the aesthetics of a interface. These resources are set automatically by the
toolkit based on the background color of the object, so the colors are not normally a problem. If the background color
of a PushButton is blue when it is created, the toolkit automatically calculates the XmNtopShadowColor to be a
slightly lighter shade of blue and the XmNbottomShadowColor to be a slightly darker shade.
The problems arise if you want to change the background color of a widget dynamically because the toolkit does not
automatically change the shadow colors for you. So if you change the XmNbackground of the PushButton to red,
the top and bottom shadow colors remain the different shades of blue. It is important to note that the shadow resources
are only used by widgets, not gadgets. If you dynamically change the background color of a manager widget, it
automatically recalculates the top and bottom shadow colors and redisplays its gadgets correctly. Many consider the
fact that this process is not automated for widgets to be a design flaw in the Motif toolkit.
If you need to change the background color of a widget dynamically, you can recalculate the shadow colors and set
the resources yourself. If you are using Motif 1.2, you can use the new XmChangeColor() routine, which takes the
following form:
void
XmChangeColor(widget, background)
Widget widget;
Pixel background;
This routine changes all the foreground color, shadow colors, and select color for the specified widget based on the
background color. The select color only applies to ToggleButtons (XmNselectColor) and PushButtons
(XmNarmColor).
If you are using Motif 1.1, you have to do a bit more work to change the colors for a widget. In this case, you need to
use XmGetColors(), which takes the following form:
void
XmGetColors(screen, colormap, bg, fg, top_shadow,
bottom_shadow, select)
Screen *screen;
Colormap colormap;
Pixel bg;
Pixel *fg;
Pixel *top_shadow;
Pixel *bottom_shadow;
Pixel *select;
This routine takes a colormap and a background color and calculates and returns an appropriate foreground color, top
and bottom shadow colors, and select color. Once you have the colors, you need to specify the appropriate resources
for the widget. The following code fragment demonstrates how to set the background of a PushButton to red:
4 Overview of the Motif Toolkit 4.4.6 Color
74
Get Volume 6A: Motif Programming Manual now with the O’Reilly learning platform.
O’Reilly members experience books, live events, courses curated by job role, and more from O’Reilly and nearly 200 top publishers.