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