drag and drop!
[wmaker-crm.git] / wrlib / StdCmap.c
blobcf29770314dccc195022fe26de24f8d7b0a042d8
1 /* $XConsortium: StdCmap.c,v 1.14 94/04/17 20:16:14 rws Exp $ */
3 /*
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
34 #include <stdio.h>
35 #include <X11/Xlib.h>
36 #include <X11/Xatom.h>
37 #include <X11/Xutil.h>
38 #include "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;
70 Status status;
71 XVisualInfo vinfo_template, *vinfo;
72 long vinfo_mask;
73 int n;
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)
81 return 0;
83 /* Check the validity of the combination of visual characteristics,
84 * allocation, and colormap property. Create an XStandardColormap
85 * structure.
88 if (! valid_args(vinfo, red_max, green_max, blue_max, property)
89 || ((stdcmap = XAllocStandardColormap()) == NULL)) {
90 XFree((char *) vinfo);
91 return 0;
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,
100 (unsigned long) 0,
101 (XSetWindowAttributes *)NULL);
102 stdcmap->killid = (XID) XCreatePixmap(dpy, win, 1, 1, depth);
103 XDestroyWindow(dpy, win);
104 stdcmap->colormap = cmap;
105 } else {
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);
119 } else {
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);
132 /* Clean up */
134 XFree((char *) vinfo);
135 if (!status) {
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;
146 return stdcmap;
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)) {
160 unsigned long mask;
162 mask = vinfo->red_mask;
163 while (!(mask & 1))
164 mask >>= 1;
165 if (red_max > mask)
166 return 0;
167 mask = vinfo->green_mask;
168 while (!(mask & 1))
169 mask >>= 1;
170 if (green_max > mask)
171 return 0;
172 mask = vinfo->blue_mask;
173 while (!(mask & 1))
174 mask >>= 1;
175 if (blue_max > mask)
176 return 0;
177 } else if (property == XA_RGB_GRAY_MAP) {
178 ncolors = red_max + green_max + blue_max + 1;
179 if (ncolors > vinfo->colormap_size)
180 return 0;
181 } else {
182 ncolors = (red_max + 1) * (green_max + 1) * (blue_max + 1);
183 if (ncolors > vinfo->colormap_size)
184 return 0;
187 /* Determine that the allocation and visual make sense for the property */
189 switch (property)
191 case XA_RGB_DEFAULT_MAP:
192 if (red_max == 0 || green_max == 0 || blue_max == 0)
193 return 0;
194 break;
195 case XA_RGB_RED_MAP:
196 if (red_max == 0)
197 return 0;
198 break;
199 case XA_RGB_GREEN_MAP:
200 if (green_max == 0)
201 return 0;
202 break;
203 case XA_RGB_BLUE_MAP:
204 if (blue_max == 0)
205 return 0;
206 break;
207 case XA_RGB_BEST_MAP:
208 if (red_max == 0 || green_max == 0 || blue_max == 0)
209 return 0;
210 break;
211 case XA_RGB_GRAY_MAP:
212 if (red_max == 0 || blue_max == 0 || green_max == 0)
213 return 0;
214 break;
215 default:
216 return 0;
218 return 1;