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>
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)