1 /* grX11su2.c -
2  *
3  *     *********************************************************************
4  *     * Copyright (C) 1985, 1990 Regents of the University of California. *
5  *     * Permission to use, copy, modify, and distribute this              *
6  *     * software and its documentation for any purpose and without        *
7  *     * fee is hereby granted, provided that the above copyright          *
8  *     * notice appear in all copies.  The University of California        *
9  *     * makes no representations about the suitability of this            *
10  *     * software for any purpose.  It is provided "as is" without         *
11  *     * express or implied warranty.  Export of this software outside     *
12  *     * of the United States of America may require an export license.    *
13  *     *********************************************************************
14  *
15  * This file contains additional functions to manipulate an X
16  * color display.  Included here are rectangle drawing and color map
17  * loading.
18  */
19 
20 /* #define HIRESDB */	/* debugging only */
21 
22 #include <stdio.h>
23 #include <stdlib.h>
24 
25 #include <X11/Xlib.h>
26 #include <X11/Xutil.h>
27 
28 #include "utils/magic.h"
29 #include "textio/textio.h"
30 #include "utils/geometry.h"
31 #include "graphics/graphics.h"
32 #include "windows/windows.h"
33 #include "graphics/graphicsInt.h"
34 #include "grX11Int.h"
35 
36 extern char *DBWStyleType;
37 extern unsigned long grPlanes[256];
38 extern unsigned long grPixels[256];
39 extern XColor   colors[256*3];	/* Unique colors used by Magic */
40 extern Colormap grXcmap;
41 
42 
43 /*---------------------------------------------------------
44  * GrXSetCMap:
45  *
46  * Results:
47  *	None.
48  *
49  * Side Effects:
50  *	The values in the color map are set from the system
51  *	colormap (see grCMap.c).  X color cells are allocated
52  *	if this display has more than 1 plane.
53  *
54  *---------------------------------------------------------
55  */
56 
57 void
GrX11SetCMap()58 GrX11SetCMap ()
59 {
60     int i, j;
61     int red, green, blue;
62     int red_size, green_size, blue_size;
63     int red_shift, green_shift, blue_shift;
64     unsigned long grCompleteMask;
65 
66     /* grCompleteMask is a mask of all the planes not used by this
67      * technology.  It is OR'd in with the mask that magic supplies
68      * to ensure that unused bits of the pixel are cleared.
69      */
70 
71 #ifdef HIRESDB
72     TxPrintf("planeCount %d, realColors %d\n", grDisplay.planeCount,
73 		grDisplay.realColors);
74 #endif  /* HIRESDB */
75 
76     if (grDisplay.planeCount > 8) {
77         grCompleteMask = 0;
78 	if (grDisplay.planeCount == 16)
79 	{
80 	    red_size = 5;
81 	    green_size = 6;
82 	    blue_size = 5;
83 	}
84         else if (grDisplay.planeCount == 15)
85 	{
86 	    red_size = 5;
87 	    green_size = 5;
88 	    blue_size = 5;
89 	} else {
90 	    red_size = 8;
91 	    green_size = 8;
92 	    blue_size = 8;
93 	}
94         red_shift = green_size + blue_size;
95         green_shift = blue_size;
96         if ((grDisplay.planeCount == 24) && (grDisplay.red_mask == 0xff))
97 	{
98 	    /* this is SUN Solaris doing it backwards: BGR  */
99             red_shift = 0; green_shift = red_size;
100             blue_shift = green_size + red_size;
101 	}
102 
103 	/* DANGER! Modify the code below with care: gcc 2.7.2 generates bad */
104 	/* code if the masks are not used as below.			    */
105 
106         for (i = 0; i != grDisplay.colorCount; i++)
107 	{
108 	    if (!GrGetColor(i, &red, &green, &blue)) break;
109 
110 	    if ((grDisplay.planeCount == 16) || (grDisplay.planeCount ==15))
111 	    {
112 		grPixels[i] = (long)((red >> (8 - red_size))
113 			<< (green_size + blue_size)) & grDisplay.red_mask; /* red */
114 		grPixels[i] |= (long)((green >> (8 - green_size))
115 			<< blue_size) & grDisplay.green_mask;		   /* green */
116 		grPixels[i] |= (long)(blue >> (8 - blue_size))
117 			& grDisplay.blue_mask; 				   /* blue */
118 	    }
119 	    else if ((grDisplay.planeCount == 24) && (grDisplay.red_mask == 0xff))
120 	    {
121 		/* this is SUN Solaris doing it backwards: BGR  */
122 		grPixels[i] = (long)(red & grDisplay.red_mask);
123 		/* here is where gcc really goes wrong (sign extends) */
124 		grPixels[i] |= (long)((green << green_shift) & grDisplay.green_mask);
125 		grPixels[i] |= (long)((blue << blue_shift) & grDisplay.blue_mask);
126 	    }
127 	    else {
128 		grPixels[i] =  (long)((red << red_shift) & grDisplay.red_mask);
129 		grPixels[i] |= (long)((green << green_shift) & grDisplay.green_mask);
130 		grPixels[i] |= (long)(blue & grDisplay.blue_mask);
131 	    }
132 	}
133 
134 #ifdef HIRESDB
135 	TxPrintf("grPixels: %6x %6x %6x %6x\n", grPixels[0], grPixels[1],
136 		grPixels[2], grPixels[3]);
137 #endif  /* HIRESDB */
138 
139 	for (i = 0; i < grDisplay.planeCount; i++)
140 	{
141 	    grDisplay.planes[i] = 1 << i;
142 	    grPlanes[i] = 0;
143 	    for (j = 0; j != grDisplay.planeCount; j++)
144 		if (i & (1 << j))
145 		{
146 		    grPlanes[i] |= grDisplay.planes[j];
147 		}
148         }
149     }
150     else { 	/* grDisplay.planeCount <= 8 */
151 
152 	if (grDisplay.planeCount < 0)
153 	{
154 	    TxError("number of bit planes must be 0 to 8 in this display.");
155 	    GrX11Close();
156 	    MainExit(1);
157 	}
158 
159 	grCompleteMask = 0;
160 	for (i = 0; i < grDisplay.planeCount; i++)
161 	    grCompleteMask |= grDisplay.planes[i];
162 
163 	grCompleteMask = AllPlanes & ~grCompleteMask;
164 
165 	for (i = 0; i != grDisplay.colorCount; i++)
166 	{
167 	    grPixels[i] = grDisplay.basepixel;
168 	    grPlanes[i] = grCompleteMask;
169 	    for (j = 0; j < grDisplay.planeCount; j++)
170 		if (i & (1 << j))
171 		{
172 		    grPixels[i] |= grDisplay.planes[j];
173 		    grPlanes[i] |= grDisplay.planes[j];
174 		}
175 	}
176     }
177 
178     if (grDisplay.depth)
179     {
180 	for (i = 0; i < grDisplay.realColors; i++)
181 	{
182 	    if (!GrGetColor(i, &red, &green, &blue)) break;
183 	    colors[i].pixel = grPixels[i];
184 	    colors[i].red = (unsigned short)(red << 8);
185 	    colors[i].green = (unsigned short)(green << 8);
186 	    colors[i].blue = (unsigned short)(blue << 8);
187 	    colors[i].flags = DoRed | DoGreen | DoBlue;
188 	}
189 	if (grDisplay.planeCount <= 8)
190 	{
191 #ifdef HIRESDB
192 	    TxPrintf("XStoreColors: planeCount %d, realColors %d\n",
193 			grDisplay.planeCount, grDisplay.realColors);
194 #endif  /* HIRESDB */
195 	    XStoreColors(grXdpy, grXcmap, colors, grDisplay.realColors);
196 	}
197     }
198     else
199     {
200 	grPixels[0] = WhitePixel(grXdpy,grXscrn);
201 	grPixels[1] = BlackPixel(grXdpy,grXscrn);
202 	grPlanes[0] = 0;
203 	grPlanes[1] = AllPlanes;
204     }
205 }
206 
207 XSegment grx11Lines[X11_BATCH_SIZE];
208 int grx11NbLines=0;
209 XRectangle grx11Rects[X11_BATCH_SIZE];
210 int grx11NbRects=0;
211 
212 
213 /*---------------------------------------------------------
214  * grxDrawLines:
215  *	This routine draws a batch of lines.
216  *
217  * Results:	None.
218  *
219  * Side Effects:
220  *	Draw a bunch of lines.
221  *---------------------------------------------------------
222  */
223 
224 void
grx11DrawLines(lines,nb)225 grx11DrawLines(lines, nb)
226     XSegment lines[];
227     int nb;
228 {
229     XDrawSegments(grXdpy, grCurrent.window, grGCDraw,
230 	      lines, nb);
231 }
232 
233 /*---------------------------------------------------------
234  * grxDrawLine:
235  *	This routine draws a line.
236  *
237  * Results:	None.
238  *
239  * Side Effects:
240  *	Draw a line for (x1, y1) to (x2, y2) inclusive.
241  *---------------------------------------------------------
242  */
243 
244 void
grx11DrawLine(x1,y1,x2,y2)245 grx11DrawLine (x1, y1, x2, y2)
246     int x1, y1;			/* Screen coordinates of first point. */
247     int x2, y2;			/* Screen coordinates of second point. */
248 {
249     if (grx11NbLines == X11_BATCH_SIZE) GR_X_FLUSH_LINES();
250     grx11Lines[grx11NbLines].x1 = x1;
251     grx11Lines[grx11NbLines].y1 = grMagicToX(y1);
252     grx11Lines[grx11NbLines].x2 = x2;
253     grx11Lines[grx11NbLines].y2 = grMagicToX(y2);
254     grx11NbLines++;
255 }
256 
257 
258 /*---------------------------------------------------------
259  * grxFillRects:
260  *	This routine draws a bunch of solid rectangles.
261  *
262  * Results:	None.
263  *
264  * Side Effects:
265  *	Drawing.
266  *---------------------------------------------------------
267  */
268 
269 void
grx11FillRects(rects,nb)270 grx11FillRects(rects, nb)
271     XRectangle rects[];
272     int nb;
273 {
274     XFillRectangles(grXdpy, grCurrent.window, grGCFill, rects, nb);
275 }
276 
277 
278 /*---------------------------------------------------------
279  * grxFillRect:
280  *	This routine draws a solid rectangle.
281  *
282  * Results:	None.
283  *
284  * Side Effects:
285  *	Drawing.
286  *---------------------------------------------------------
287  */
288 
289 void
grx11FillRect(r)290 grx11FillRect(r)
291     Rect *r;	/* Address of a rectangle in screen
292 			 * coordinates.
293 			 */
294 {
295     if (grx11NbRects == X11_BATCH_SIZE) GR_X_FLUSH_RECTS();
296     grx11Rects[grx11NbRects].x = r->r_xbot;
297     grx11Rects[grx11NbRects].y = grMagicToX(r->r_ytop);
298     grx11Rects[grx11NbRects].width = r->r_xtop - r->r_xbot + 1;
299     grx11Rects[grx11NbRects].height = r->r_ytop - r->r_ybot + 1;
300     grx11NbRects++;
301 }
302 
303 /*---------------------------------------------------------
304  * grx11FillPolygon:
305  *	This routine draws a solid polygon
306  *
307  * Results:     None.
308  *
309  * Side Effects:
310  *	Drawing.
311  *---------------------------------------------------------
312  */
313 
314 void
grx11FillPolygon(tp,np)315 grx11FillPolygon(tp, np)
316     Point *tp;
317     int np;
318 {
319     XPoint xp[5];
320     int i;
321 
322     for (i = 0; i < np; i++)
323     {
324 	xp[i].x = tp[i].p_x;
325 	xp[i].y = grMagicToX(tp[i].p_y);
326     }
327     XFillPolygon(grXdpy, grCurrent.window, grGCFill, xp, np,
328 		Convex, CoordModeOrigin);
329 }
330 
331