1
/* $XConsortium: StdCmap.c,v 1.14 94/04/17 20:16:14 rws Exp $ */
5
Copyright (c) 1989 X Consortium
7
Permission is hereby granted, free of charge, to any person obtaining a copy
8
of this software and associated documentation files (the "Software"), to deal
9
in the Software without restriction, including without limitation the rights
10
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
11
copies of the Software, and to permit persons to whom the Software is
12
furnished to do so, subject to the following conditions:
14
The above copyright notice and this permission notice shall be included in
15
all copies or substantial portions of the Software.
17
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
18
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
19
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
20
X CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
21
AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
22
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
24
Except as contained in this notice, the name of the X Consortium shall not be
25
used in advertising or otherwise to promote the sale, use or other dealings
26
in this Software without prior written authorization from the X Consortium.
31
* Author: Donna Converse, MIT X Consortium
36
#include <X11/Xatom.h>
37
#include <X11/Xutil.h>
38
#include "x11/StdCmap.h"
40
#define lowbit(x) ((x) & (~(x) + 1))
42
static Status valid_args(); /* argument restrictions */
45
* To create any one standard colormap, use XmuStandardColormap().
47
* Create a standard colormap for the given screen, visualid, and visual
48
* depth, with the given red, green, and blue maximum values, with the
49
* given standard property name. Return a pointer to an XStandardColormap
50
* structure which describes the newly created colormap, upon success.
51
* Upon failure, return NULL.
53
* XmuStandardColormap() calls XmuCreateColormap() to create the map.
55
* Resources created by this function are not made permanent; that is the
56
* caller's responsibility.
59
XStandardColormap *XmuStandardColormap(dpy, screen, visualid, depth, property,
60
cmap, red_max, green_max, blue_max)
61
Display *dpy; /* specifies X server connection */
62
int screen; /* specifies display screen */
63
VisualID visualid; /* identifies the visual type */
64
unsigned int depth; /* identifies the visual type */
65
Atom property; /* a standard colormap property */
66
Colormap cmap; /* specifies colormap ID or None */
67
unsigned long red_max, green_max, blue_max; /* allocations */
69
XStandardColormap *stdcmap;
71
XVisualInfo vinfo_template, *vinfo;
75
/* Match the required visual information to an actual visual */
76
vinfo_template.visualid = visualid;
77
vinfo_template.screen = screen;
78
vinfo_template.depth = depth;
79
vinfo_mask = VisualIDMask | VisualScreenMask | VisualDepthMask;
80
if ((vinfo = XGetVisualInfo(dpy, vinfo_mask, &vinfo_template, &n)) == NULL)
83
/* Check the validity of the combination of visual characteristics,
84
* allocation, and colormap property. Create an XStandardColormap
88
if (! valid_args(vinfo, red_max, green_max, blue_max, property)
89
|| ((stdcmap = XAllocStandardColormap()) == NULL)) {
90
XFree((char *) vinfo);
94
/* Fill in the XStandardColormap structure */
96
if (cmap == DefaultColormap(dpy, screen)) {
97
/* Allocating out of the default map, cannot use XFreeColormap() */
98
Window win = XCreateWindow(dpy, RootWindow(dpy, screen), 1, 1, 1, 1,
99
0, 0, InputOnly, vinfo->visual,
101
(XSetWindowAttributes *)NULL);
102
stdcmap->killid = (XID) XCreatePixmap(dpy, win, 1, 1, depth);
103
XDestroyWindow(dpy, win);
104
stdcmap->colormap = cmap;
106
stdcmap->killid = ReleaseByFreeingColormap;
107
stdcmap->colormap = XCreateColormap(dpy, RootWindow(dpy, screen),
108
vinfo->visual, AllocNone);
110
stdcmap->red_max = red_max;
111
stdcmap->green_max = green_max;
112
stdcmap->blue_max = blue_max;
113
if (property == XA_RGB_GRAY_MAP)
114
stdcmap->red_mult = stdcmap->green_mult = stdcmap->blue_mult = 1;
115
else if (vinfo->class == TrueColor || vinfo->class == DirectColor) {
116
stdcmap->red_mult = lowbit(vinfo->red_mask);
117
stdcmap->green_mult = lowbit(vinfo->green_mask);
118
stdcmap->blue_mult = lowbit(vinfo->blue_mask);
120
stdcmap->red_mult = (red_max > 0)
121
? (green_max + 1) * (blue_max + 1) : 0;
122
stdcmap->green_mult = (green_max > 0) ? blue_max + 1 : 0;
123
stdcmap->blue_mult = (blue_max > 0) ? 1 : 0;
125
stdcmap->base_pixel = 0; /* base pixel may change */
126
stdcmap->visualid = vinfo->visualid;
128
/* Make the colormap */
130
status = XmuCreateColormap(dpy, stdcmap);
134
XFree((char *) vinfo);
137
/* Free the colormap or the pixmap, if we created one */
138
if (stdcmap->killid == ReleaseByFreeingColormap)
139
XFreeColormap(dpy, stdcmap->colormap);
140
else if (stdcmap->killid != None)
141
XFreePixmap(dpy, stdcmap->killid);
143
XFree((char *) stdcmap);
144
return (XStandardColormap *) NULL;
149
/****************************************************************************/
150
static Status valid_args(vinfo, red_max, green_max, blue_max, property)
151
XVisualInfo *vinfo; /* specifies visual */
152
unsigned long red_max, green_max, blue_max; /* specifies alloc */
153
Atom property; /* specifies property name */
155
unsigned long ncolors; /* number of colors requested */
157
/* Determine that the number of colors requested is <= map size */
159
if ((vinfo->class == DirectColor) || (vinfo->class == TrueColor)) {
162
mask = vinfo->red_mask;
167
mask = vinfo->green_mask;
170
if (green_max > mask)
172
mask = vinfo->blue_mask;
177
} else if (property == XA_RGB_GRAY_MAP) {
178
ncolors = red_max + green_max + blue_max + 1;
179
if (ncolors > vinfo->colormap_size)
182
ncolors = (red_max + 1) * (green_max + 1) * (blue_max + 1);
183
if (ncolors > vinfo->colormap_size)
187
/* Determine that the allocation and visual make sense for the property */
191
case XA_RGB_DEFAULT_MAP:
192
if (red_max == 0 || green_max == 0 || blue_max == 0)
199
case XA_RGB_GREEN_MAP:
203
case XA_RGB_BLUE_MAP:
207
case XA_RGB_BEST_MAP:
208
if (red_max == 0 || green_max == 0 || blue_max == 0)
211
case XA_RGB_GRAY_MAP:
212
if (red_max == 0 || blue_max == 0 || green_max == 0)