1 /*
2 * Xaw3dP.c
3 *
4 * Global functions that don't really belong anywhere else.
5 */
6
7 /*********************************************************************
8 Copyright (C) 1992 Kaleb Keithley
9 Copyright (C) 2000, 2003 David J. Hawkey Jr.
10
11 All Rights Reserved
12
13 Permission to use, copy, modify, and distribute this software and
14 its documentation for any purpose and without fee is hereby granted,
15 provided that the above copyright notice appear in all copies and
16 that both that copyright notice and this permission notice appear in
17 supporting documentation, and that the names of the copyright holders
18 not be used in advertising or publicity pertaining to distribution
19 of the software without specific, written prior permission.
20
21 THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS
22 SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
23 FITNESS. IN NO EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY
24 SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER
25 RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF
26 CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
27 CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
28 *********************************************************************/
29
30 #include "Xaw3dP.h"
31 #ifdef XAW_MULTIPLANE_PIXMAPS
32 #include <stdio.h>
33 #include <X11/xpm.h>
34 #endif
35
36 #ifdef XAW_GRAY_BLKWHT_STIPPLES
37 /* ARGSUSED */
38 unsigned long
grayPixel(p,dpy,scn)39 grayPixel(p, dpy, scn)
40 unsigned long p; /* unused */
41 Display *dpy;
42 Screen *scn;
43 {
44 static XColor Gray =
45 {
46 0, /* pixel */
47 0, 0, 0, /* red, green, blue */
48 0, /* flags */
49 0 /* pad */
50 };
51
52 if (!Gray.pixel)
53 {
54 XColor exact;
55
56 (void)XAllocNamedColor(dpy, DefaultColormapOfScreen(scn),
57 "gray", &Gray, &exact); /* Blindflug */
58 }
59
60 return Gray.pixel;
61 }
62 #endif
63
64 #ifdef XAW_MULTIPLANE_PIXMAPS
65 #define IS_EVEN(x) (((x) % 2) == 0)
66 #define IS_ODD(x) (((x) % 2) == 1)
67
68 /* ARGSUSED */
69 Pixmap
stipplePixmap(w,pm,cm,bg,d)70 stipplePixmap(w, pm, cm, bg, d)
71 Widget w;
72 Pixmap pm;
73 Colormap cm;
74 Pixel bg;
75 unsigned int d;
76 {
77 static Pixmap pixmap;
78 Display *dpy;
79 XpmImage image;
80 XpmAttributes attr;
81 XpmColor *src_table, *dst_table;
82 int i, j, index = -1;
83
84 if (pm == None)
85 return (None);
86 if (XtIsRealized(w) == False)
87 return (None);
88
89 dpy = XtDisplayOfObject(w);
90
91 attr.colormap = cm;
92 attr.closeness = 32768; /* might help on 8-bpp displays? */
93 attr.valuemask = XpmColormap | XpmCloseness;
94
95 if (XpmCreateXpmImageFromPixmap(dpy, pm, None,
96 &image, &attr) != XpmSuccess)
97 return (None);
98 if (image.height == 0 || image.width == 0)
99 {
100 XpmFreeXpmImage(&image);
101 return (None);
102 }
103
104 if (d > 1)
105 {
106 XColor x_color;
107 XpmColor *dst_color;
108 char dst_rgb[14];
109
110 /*
111 * Multi-plane (XPM) pixmap. Don't bother scanning the color table
112 * for the background color, it might not be there. Copy the color
113 * table, add an entry for the background color, and set the index
114 * to that.
115 */
116
117 x_color.pixel = bg;
118 XQueryColor(dpy, cm, &x_color);
119 sprintf(dst_rgb, "#%04X%04X%04X",
120 x_color.red, x_color.green, x_color.blue);
121
122 dst_table = (XpmColor *) XtCalloc(sizeof(XpmColor),
123 image.ncolors + 1);
124 memcpy(dst_table, image.colorTable, image.ncolors * sizeof(XpmColor));
125
126 dst_color = &dst_table[image.ncolors];
127 switch (w->core.depth)
128 {
129 case 1:
130 dst_color->m_color = dst_rgb;
131 break;
132 case 4:
133 dst_color->g4_color = dst_rgb;
134 break;
135 case 6:
136 dst_color->g_color = dst_rgb;
137 break;
138 case 8:
139 default:
140 dst_color->c_color = dst_rgb;
141 break;
142 }
143 dst_color->string = "\x01"; /* ! */
144
145 src_table = image.colorTable;
146 image.colorTable = dst_table;
147
148 index = image.ncolors++;
149 }
150 else
151 {
152 XpmColor *src_color;
153 char *src_rgb;
154
155 /*
156 * Single-plane (XBM) pixmap. Set the index to the white color.
157 */
158
159 for (i = 0, src_color = image.colorTable; i < image.ncolors;
160 i++, src_color++)
161 {
162 switch (w->core.depth)
163 {
164 case 1:
165 src_rgb = src_color->m_color;
166 break;
167 case 4:
168 src_rgb = src_color->g4_color;
169 break;
170 case 6:
171 src_rgb = src_color->g_color;
172 break;
173 case 8:
174 default:
175 src_rgb = src_color->c_color;
176 break;
177 }
178 if (strcmp(src_rgb, "#000000000000") == 0)
179 {
180 index = i;
181 break;
182 }
183 }
184
185 if (index == -1)
186 {
187 XpmFreeXpmImage(&image);
188 return (None);
189 }
190 }
191
192 for (i = 0; i < image.height; i++)
193 for (j = 0; j < image.width; j++)
194 if ((IS_ODD(i) && IS_EVEN(j)) || (IS_EVEN(i) && IS_ODD(j)))
195 image.data[(i * image.width) + j] = index;
196
197 attr.depth = d;
198 attr.valuemask |= XpmDepth;
199
200 i = XpmCreatePixmapFromXpmImage(dpy, pm, &image, &pixmap, NULL, &attr);
201
202 if (d > 1)
203 {
204 XtFree((void *)image.colorTable); /* dst_table */
205 image.colorTable = src_table;
206 image.ncolors--;
207 }
208 XpmFreeXpmImage(&image);
209
210 return ((i == XpmSuccess) ? pixmap : None);
211 }
212 #endif
213