Change to the linux kernel coding style
[wmaker-crm.git] / wrlib / StdCmap.c
1 /* $XConsortium: StdCmap.c,v 1.14 94/04/17 20:16:14 rws Exp $ */
2
3 /*
4
5 Copyright (c) 1989 X Consortium
6
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:
13
14 The above copyright notice and this permission notice shall be included in
15 all copies or substantial portions of the Software.
16
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.
23
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.
27
28 */
29
30 /*
31 * Author: Donna Converse, MIT X Consortium
32 */
33
34 #include <stdio.h>
35 #include <X11/Xlib.h>
36 #include <X11/Xatom.h>
37 #include <X11/Xutil.h>
38 #include "StdCmap.h"
39
40 #define lowbit(x) ((x) & (~(x) + 1))
41
42 static Status valid_args(); /* argument restrictions */
43
44 /*
45 * To create any one standard colormap, use XmuStandardColormap().
46 *
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.
52 *
53 * XmuStandardColormap() calls XmuCreateColormap() to create the map.
54 *
55 * Resources created by this function are not made permanent; that is the
56 * caller's responsibility.
57 */
58
59 XStandardColormap *XmuStandardColormap(dpy, screen, visualid, depth, property, cmap, red_max, green_max, blue_max)
60 Display *dpy; /* specifies X server connection */
61 int screen; /* specifies display screen */
62 VisualID visualid; /* identifies the visual type */
63 unsigned int depth; /* identifies the visual type */
64 Atom property; /* a standard colormap property */
65 Colormap cmap; /* specifies colormap ID or None */
66 unsigned long red_max, green_max, blue_max; /* allocations */
67 {
68 XStandardColormap *stdcmap;
69 Status status;
70 XVisualInfo vinfo_template, *vinfo;
71 long vinfo_mask;
72 int n;
73
74 /* Match the required visual information to an actual visual */
75 vinfo_template.visualid = visualid;
76 vinfo_template.screen = screen;
77 vinfo_template.depth = depth;
78 vinfo_mask = VisualIDMask | VisualScreenMask | VisualDepthMask;
79 if ((vinfo = XGetVisualInfo(dpy, vinfo_mask, &vinfo_template, &n)) == NULL)
80 return 0;
81
82 /* Check the validity of the combination of visual characteristics,
83 * allocation, and colormap property. Create an XStandardColormap
84 * structure.
85 */
86
87 if (!valid_args(vinfo, red_max, green_max, blue_max, property)
88 || ((stdcmap = XAllocStandardColormap()) == NULL)) {
89 XFree((char *)vinfo);
90 return 0;
91 }
92
93 /* Fill in the XStandardColormap structure */
94
95 if (cmap == DefaultColormap(dpy, screen)) {
96 /* Allocating out of the default map, cannot use XFreeColormap() */
97 Window win = XCreateWindow(dpy, RootWindow(dpy, screen), 1, 1, 1, 1,
98 0, 0, InputOnly, vinfo->visual,
99 (unsigned long)0,
100 (XSetWindowAttributes *) NULL);
101 stdcmap->killid = (XID) XCreatePixmap(dpy, win, 1, 1, depth);
102 XDestroyWindow(dpy, win);
103 stdcmap->colormap = cmap;
104 } else {
105 stdcmap->killid = ReleaseByFreeingColormap;
106 stdcmap->colormap = XCreateColormap(dpy, RootWindow(dpy, screen), vinfo->visual, AllocNone);
107 }
108 stdcmap->red_max = red_max;
109 stdcmap->green_max = green_max;
110 stdcmap->blue_max = blue_max;
111 if (property == XA_RGB_GRAY_MAP)
112 stdcmap->red_mult = stdcmap->green_mult = stdcmap->blue_mult = 1;
113 else if (vinfo->class == TrueColor || vinfo->class == DirectColor) {
114 stdcmap->red_mult = lowbit(vinfo->red_mask);
115 stdcmap->green_mult = lowbit(vinfo->green_mask);
116 stdcmap->blue_mult = lowbit(vinfo->blue_mask);
117 } else {
118 stdcmap->red_mult = (red_max > 0)
119 ? (green_max + 1) * (blue_max + 1) : 0;
120 stdcmap->green_mult = (green_max > 0) ? blue_max + 1 : 0;
121 stdcmap->blue_mult = (blue_max > 0) ? 1 : 0;
122 }
123 stdcmap->base_pixel = 0; /* base pixel may change */
124 stdcmap->visualid = vinfo->visualid;
125
126 /* Make the colormap */
127
128 status = XmuCreateColormap(dpy, stdcmap);
129
130 /* Clean up */
131
132 XFree((char *)vinfo);
133 if (!status) {
134
135 /* Free the colormap or the pixmap, if we created one */
136 if (stdcmap->killid == ReleaseByFreeingColormap)
137 XFreeColormap(dpy, stdcmap->colormap);
138 else if (stdcmap->killid != None)
139 XFreePixmap(dpy, stdcmap->killid);
140
141 XFree((char *)stdcmap);
142 return (XStandardColormap *) NULL;
143 }
144 return stdcmap;
145 }
146
147 /****************************************************************************/
148 static Status valid_args(vinfo, red_max, green_max, blue_max, property)
149 XVisualInfo *vinfo; /* specifies visual */
150 unsigned long red_max, green_max, blue_max; /* specifies alloc */
151 Atom property; /* specifies property name */
152 {
153 unsigned long ncolors; /* number of colors requested */
154
155 /* Determine that the number of colors requested is <= map size */
156
157 if ((vinfo->class == DirectColor) || (vinfo->class == TrueColor)) {
158 unsigned long mask;
159
160 mask = vinfo->red_mask;
161 while (!(mask & 1))
162 mask >>= 1;
163 if (red_max > mask)
164 return 0;
165 mask = vinfo->green_mask;
166 while (!(mask & 1))
167 mask >>= 1;
168 if (green_max > mask)
169 return 0;
170 mask = vinfo->blue_mask;
171 while (!(mask & 1))
172 mask >>= 1;
173 if (blue_max > mask)
174 return 0;
175 } else if (property == XA_RGB_GRAY_MAP) {
176 ncolors = red_max + green_max + blue_max + 1;
177 if (ncolors > vinfo->colormap_size)
178 return 0;
179 } else {
180 ncolors = (red_max + 1) * (green_max + 1) * (blue_max + 1);
181 if (ncolors > vinfo->colormap_size)
182 return 0;
183 }
184
185 /* Determine that the allocation and visual make sense for the property */
186
187 switch (property) {
188 case XA_RGB_DEFAULT_MAP:
189 if (red_max == 0 || green_max == 0 || blue_max == 0)
190 return 0;
191 break;
192 case XA_RGB_RED_MAP:
193 if (red_max == 0)
194 return 0;
195 break;
196 case XA_RGB_GREEN_MAP:
197 if (green_max == 0)
198 return 0;
199 break;
200 case XA_RGB_BLUE_MAP:
201 if (blue_max == 0)
202 return 0;
203 break;
204 case XA_RGB_BEST_MAP:
205 if (red_max == 0 || green_max == 0 || blue_max == 0)
206 return 0;
207 break;
208 case XA_RGB_GRAY_MAP:
209 if (red_max == 0 || blue_max == 0 || green_max == 0)
210 return 0;
211 break;
212 default:
213 return 0;
214 }
215 return 1;
216 }