We can use the following to produce a cms with the same colors:
static Xv_singlecolor colors[ ] = {
{ 255, 255, 255, }, /* white */
{ 255, 0, 0 }, /* red */
{ 0, 255 0, }, /* green */
{ 0, 0, 255 }, /* blue */
};
cms = xv_create(NULL, CMS,
CMS_SIZE, 4,
CMS_COLORS, colors,
NULL);
Alternatively, you can use the attribute CMS_X_COLORS to specify an array of XColor struc-
tures, defined in <X11/Xlib.h> as:
typedef struct {
unsigned long pixel;
unsigned short red, green, blue;
char flags; /* do_red, do_green, do_blue */
char pad;
} XColor;
Here is a way to produce a colormap segment with the same colors but using an array of
XColors:
static XColor colors[ ] = {
/* white */ { 0, 255<<8, 255<<8, 255<<8, DoRed|DoGreen|DoBlue, 0 },
/* red */ { 0, 255<<8, 0, 0, DoRed|DoGreen|DoBlue, 0 },
/* green */ { 0, 0, 255<<8, 0, DoRed|DoGreen|DoBlue, 0 },
/* blue */ { 0, 0, 0, 255<<8, DoRed|DoGreen|DoBlue, 0 },
};
cms = xv_create(NULL, CMS,
CMS_SIZE, 4,
CMS_X_COLORS, colors,
NULL);
Note that the color values in the red, green, and blue fields of the XColor data structure are
left-shifted by 8. For more details on specifying colors with Xlib, see Volume One, Xlib Pro-
gramming Manual.
When storing colors, if the colormap segment type is static, XView uses XAllocColor().
If the colormap segment type is dynamic, XView uses XAllocColorCells() and
XStoreColors() to allocate a dynamic colormap and store the requested colors in it.
After setting colors in a cms, the pixel values for the colors can be retrieved. These pixel val-
ues are indices into the colormap itself, not the colormap segment. See Section 21.3, “Color
and Pixel Values.”
The XView attributes to set colors can be used to get the colors from the cms as well. For
example, to get the colors into an array of Xv_singlecolor, use:
Xv_singlecolor colors[SIZE];
xv_get(cms, CMS_COLORS, colors);
The size of the colors array must be the same size as the color segment because
xv_get() gets the entire colormap segment and stores the colors at the base of the array.
518 XView Programming Manual
You cannot get a partial list of colors from the cms. The same is true for getting the colors
into an array of XColor:
XColor colors[SIZE];
xv_get(cms, CMS_X_COLORS, &colors);
In each case, xv_get() returns a pointer to the base of the array of data structures passed as
the third argument. We choose to ignore it here because the array itself is sufficient.
21.2.2 Cms Name
Colormap segments can be named using CMS_NAME.* Windows can change between color-
maps by setting their WIN_CMS_NAME to the names of allocated colormap segments. How-
ever, this old-style method of specifying colormap segments for windows is made obsolete by
the attribute WIN_CMS, the recommended method for assigning colormap segments to win-
dows.
If unnamed, a cms will get a unique name assigned to it. You can retrieve that name using
xv_get() and
CMS_NAME. CMS_NAME is also the only attribute for which you can use
xv_find() for the CMS package.
21.3 Color and Pixel Values
By now, you know that a color is defined to be a set of red, green, and blue (RGB) intensity
values. For example, red is represented by a full intensity for the red value and no intensity
for the green and blue values. Other shades are achieved by raising or lowering the intensi-
ties of one or more of the RGB values. A colormap is an array of RGB values; a pixel is an
index into that array.
21.3.0.1 Logical versus real indices
If a colormap segment of size n is created, its logical indices range from 0 to n-1. XView
attributes that take color values (e.g.,
WIN_FOREGROUND_COLOR, PANEL_ITEM_COLOR, etc.)
always deal with logical index values.
The real indices of a colormap segment are the actual indices into the hardware colormap.
Each colormap segment maintains an internal table to translate from logical to real indices.
Real index values (pixels) are used for setting the foreground and background colors in GCs
used in Xlib calls.
*CMS_NAME is defined to be XV_NAME.
Color
Color 519
The index table from a colormap segment can be obtained using the attribute CMS_
INDEX_TABLE
.
unsigned long *colors;
colors = (unsigned long *)xv_get(cms, CMS_INDEX_TABLE);
Similarly, the pixel values from a window-based object can be obtained using the window at-
tribute, WIN_X_COLOR_INDICES:
unsigned long *colors;
colors = (unsigned long *)xv_get(canvas, WIN_X_COLOR_INDICES);
Note the object passed to xv_get().
In both cases, the returned value is a pointer to an array of unsigned long types. For a
colormap segment of size n, colors[0], colors[1], . . . colors[n-1] contain
the actual pixel values corresponding to the colors in the underlying X11 colormap. These
pixel values can be used in calls to XSetForeground() or XSetBackground() to
change GC values.
To get the real pixel value corresponding to a logical index value, you can use the CMS_PIX-
EL
attribute:
Cms cms;
unsigned long red, blue;
cms = (Cms)xv_create(NULL, CMS,
CMS_SIZE, 2,
CMS_NAMED_COLORS, "red", "blue", NULL,
NULL);
red = (unsigned long)xv_get(cms, CMS_PIXEL, 0);
blue = (unsigned long)xv_get(cms, CMS_PIXEL, 1);
CMS_PIXEL
can only be used to get the value of pixels; you cannot use it to set cms color val-
ues.
As discussed earlier, the CMS_X_COLORS attribute can be used to get an array of XColor ele-
ments. This data structure has a pixel field that can be referenced to get the pixel values
associated with colors.
21.3.1 Foreground and Background Colors
Foreground and background colors correspond to the last and first colors in a colormap seg-
ment. That is, the segment’s background color corresponds to the logical index 0 in the cms,
whereas the foreground color corresponds to the logical index n-1 (where n is the size of the
cms).
Identifying the foreground and background colors on certain XView objects may not be as
straightforward as it appears. For example, the background color of a canvas is the color the
entire canvas is painted with when XClearArea() is called. The foreground color is a thin
border color around the inside perimeter of each canvas view window. This is not
520 XView Programming Manual
necessarily the color in which graphics are rendered into the canvas using XCopyArea() or
XDrawString(). The color of the graphical images you see in a canvas is dependent on
the foreground color set in the GC used by the Xlib routines.
The real pixel values for the foreground and background colors of a cms may be obtained di-
rectly using the attributes CMS_FOREGROUND_PIXEL and CMS_BACKGROUND_PIXEL.
Cms cms;
unsigned long fg, bg;
bg = (unsigned long)xv_get(cms, CMS_BACKGROUND_PIXEL);
fg = (unsigned long)xv_get(cms, CMS_FOREGROUND_PIXEL);
21.3.1.1 Colors of control objects
A control object in XView refers to panels, scrollbars, notices, and menus. These packages
cannot have their foreground and background modified programmatically in the same way as
other window-based objects. This restriction applies to the 3D interface; the 2D interface
may allow the foreground and background colors to be modified. However,
OPEN LOOK
states that the background of all control objects appear consistent; thus, a single control color
is used. On panels, it is possible, but not recommended, to set the
WIN_FOREGROUND_COLOR
and WIN_BACKGROUND_COLOR attributes. Panel items, may have their colors set by setting
PANEL_ITEM_COLOR to a logical index into the panel’s cms. XView allows the user, not the
programmer, to set the background color for control objects via the resource database. This
is discussed in Section 21.5, “The Control Colormap Segment.”
21.4 The color_logo.c Program
Using the basic principles discussed so far, we present Example 21-1 to demonstrate the cre-
ation and initialization of a colormap segment for an XView canvas. Pixel values are
extracted from the colormap segment and set into a GC’s foreground. Xlib calls are then
used to render various items in the same four basic colors we’ve been using.
Example 21-1. The color_logo.c program
/* color_logo.c --
* This program demonstrates the combined use of the XView color
* model/API and Xlib graphics calls. The program uses XView to
* create and manage its colormap segment while doing its actual
* drawing using Xlib routines.
* The program draws the X logo in red, green and blue in a canvas.
*/
#include <xview/xview.h>
#include <xview/canvas.h>
#include <xview/cms.h>
#include <xview/xv_xrect.h>
#include <X11/bitmaps/xlogo64>
/* Color indices */
Color
Color 521
Example 21-1. The color_logo.c program (continued)
#define WHITE 0
#define RED 1
#define GREEN 2
#define BLUE 3
#define NUM_COLORS 4
GC gc; /* used for rendering logos */
unsigned long *pixel_table; /* pixel values for colors */
Pixmap xlogo; /* the xlogo */
/* Create a frame, canvas, and a colormap segment and assign the
* cms to the canvas. CMS_INDEX_TABLE returns the actual colormap
* indices and are used to set the gcs foreground for XCopyPlane
* calls.
*/
main(argc,argv)
int argc;
char *argv[ ];
{
Frame frame;
XGCValues gc_val;
XGCValues gcvalues;
void canvas_repaint_proc();
Cms cms;
static Xv_singlecolor colors[ ] = {
{ 255, 255, 255 }, /* white */
{ 255, 0, 0 }, /* red */
{ 0, 255, 0 }, /* green */
{ 0, 0, 255 }, /* blue */
};
xv_init(XV_INIT_ARGC_PTR_ARGV, &argc, argv, NULL);
cms = (Cms) xv_create(NULL, CMS,
CMS_SIZE, 4,
CMS_COLORS, colors,
NULL);
frame = (Frame)xv_create(XV_NULL, FRAME,
FRAME_LABEL, argv[0 ],
XV_WIDTH, 448,
XV_HEIGHT, 192,
NULL);
(void) xv_create(frame, CANVAS,
CANVAS_X_PAINT_WINDOW, TRUE,
CANVAS_REPAINT_PROC, canvas_repaint_proc,
WIN_CMS, cms,
NULL);
/* Get the actual indices into the colormap */
pixel_table = (unsigned long *)xv_get(cms, CMS_INDEX_TABLE);
/* create the xlogo -- get display/window from the frame obj */
xlogo = XCreateBitmapFromData(
xv_get(frame, XV_DISPLAY), xv_get(frame, XV_XID),
522 XView Programming Manual

Get Volume 7A: XView 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.