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