1 /**
2  ** fd_xwin.c - the X Window color frame driver
3  **
4  ** Author:     Ulrich Leodolter
5  ** E-mail:     ulrich@lab1.psy.univie.ac.at
6  ** Date:       Thu Sep 28 10:31:08 1995
7  ** RCSId:      $Id: fd_xwin.c 1.1 1995/11/19 17:42:55 ulrich Exp $
8  **
9  ** This file is part of the GRX graphics library.
10  **
11  ** The GRX graphics library is free software; you can redistribute it
12  ** and/or modify it under some conditions; see the "copying.grx" file
13  ** for details.
14  **
15  ** This library is distributed in the hope that it will be useful,
16  ** but WITHOUT ANY WARRANTY; without even the implied warranty of
17  ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
18  **
19  ** Contributions by: (See "doc/credits.doc" for details)
20  ** Hartmut Schirmer (hsc@techfak.uni-kiel.de)
21  ** 070505 M.Alvarez, Using a Pixmap for BackingStore
22  ** 080801 M.Alvarez, Sanitized pixel cache code
23  ** 080801 M.Alvarez, New faster and specific for X11 putscanline function
24  **
25  **/
26 
27 #include <string.h>
28 #include "libgrx.h"
29 #include "libxwin.h"
30 #include "arith.h"
31 #include "memfill.h"
32 #include "grdriver.h"
33 
34 INLINE
_XGrCopyBStore(int x,int y,int width,int lenght)35 void _XGrCopyBStore(int x, int y, int width, int lenght)
36 {
37   if (USE_PIXMAP_FOR_BS) {
38     XCopyArea (_XGrDisplay,
39                _XGrBStore,
40                _XGrWindow,
41                DefaultGC (_XGrDisplay, _XGrScreen),
42                x,
43                y,
44                width,
45                lenght,
46                x,
47                y);
48   }
49 }
50 
51 static INLINE
_XGrSetForeColor(GrColor color)52 void _XGrSetForeColor (GrColor color)
53 {
54   GRX_ENTER();
55   color &= GrCVALUEMASK;
56   if (color != _XGrForeColor)
57     {
58       DBGPRINTF(DBG_DRIVER,("New foreground color: %x\n",(unsigned)color));
59       _XGrForeColor = color;
60       XSetForeground (_XGrDisplay, _XGrGC, _XGrForeColor);
61     }
62   GRX_LEAVE();
63 }
64 
65 static INLINE
_XGrSetBackColor(GrColor color)66 void _XGrSetBackColor (GrColor color)
67 {
68   GRX_ENTER();
69   color &= GrCVALUEMASK;
70   if (color != _XGrBackColor)
71     {
72       DBGPRINTF(DBG_DRIVER,("New background color: %x\n",(unsigned)color));
73       _XGrBackColor = color;
74       XSetBackground (_XGrDisplay, _XGrGC, _XGrBackColor);
75     }
76   GRX_LEAVE();
77 }
78 
79 static INLINE
_XGrSetColorOper(GrColor color)80 void _XGrSetColorOper (GrColor color)
81 {
82   static int _GXtable[4] = {
83     GXcopy,     /* C_WRITE */
84     GXxor,      /* C_XOR */
85     GXor,       /* C_OR */
86     GXand       /* C_AND */
87   };
88   unsigned int coper;
89 
90   GRX_ENTER();
91   coper = C_OPER(color) & 0x03;
92   if (coper != _XGrColorOper)
93     {
94       _XGrColorOper = coper;
95       XSetFunction (_XGrDisplay, _XGrGC, _GXtable[_XGrColorOper]);
96     }
97   GRX_LEAVE();
98 }
99 
100 /*
101  * PixelCache uses complete rows now
102  * Designed for loops like:
103  *
104  * for (y = 0; y < height; y++)
105  *   for (x = 0; x < width; x++)
106  *     *dest++ = GrPixel (x, y);
107  */
108 
109 #define PIXEL_CACHE_HEIGHT 4
110 
111 static XImage * _XGrPixelCacheImage     = NULL;
112 static Drawable _XGrPixelCacheDrawable  = None;
113 static int      _XGrPixelCacheWidth = 0;
114 static int      _XGrPixelCacheHeight = 0;
115 static int      _XGrPixelCacheY1 = 0;
116 static int      _XGrPixelCacheY2 = 0;
117 
118 /* y1 <= y2 required ! */
119 #define AREA_OVERLAP_PIXEL_CACHE(y1,y2) \
120 	(   (y2) >= _XGrPixelCacheY1          \
121 	 && (y1) <=  _XGrPixelCacheY2 )
122 
123 #define PIXEL_CACHE_INVALIDATE() do {              \
124 	    _XGrPixelCacheDrawable = None;         \
125 	    if (_XGrPixelCacheImage) {             \
126 	      XDestroyImage (_XGrPixelCacheImage); \
127 	      _XGrPixelCacheImage = NULL;          \
128 	    }                                      \
129 	} while (0)
130 
131 static INLINE
_XGrCheckPixelCache(int y1,int y2)132 void _XGrCheckPixelCache(int y1, int y2)
133 {
134   if (_XGrPixelCacheDrawable == None) return;
135   if (AREA_OVERLAP_PIXEL_CACHE(y1,y2))
136     PIXEL_CACHE_INVALIDATE();
137 }
138 
139 static
readpixel(GrFrame * c,int x,int y)140 GrColor readpixel(GrFrame *c, int x, int y)
141 {
142   GrColor col;
143   GRX_ENTER();
144   if (_XGrPixelCacheDrawable != (Drawable) c->gf_baseaddr[0]
145       || _XGrPixelCacheImage == NULL
146       || !AREA_OVERLAP_PIXEL_CACHE(y,y)) {
147 
148     if (_XGrPixelCacheImage) {
149       XDestroyImage (_XGrPixelCacheImage);
150       _XGrPixelCacheImage = NULL;
151     }
152     _XGrPixelCacheDrawable = (Drawable) c->gf_baseaddr[0];
153 
154     _XGrPixelCacheWidth = GrScreenX();
155     _XGrPixelCacheY1 = y;
156     _XGrPixelCacheY2 = y + PIXEL_CACHE_HEIGHT - 1;
157     if (_XGrPixelCacheY2 >= GrScreenY())
158       _XGrPixelCacheY2 = GrScreenY() - 1;
159     _XGrPixelCacheHeight = _XGrPixelCacheY2 - _XGrPixelCacheY1 + 1;
160 
161     _XGrPixelCacheImage = XGetImage (_XGrDisplay,
162 				     _XGrPixelCacheDrawable,
163 				     0,
164 				     _XGrPixelCacheY1,
165 				     _XGrPixelCacheWidth,
166 				     _XGrPixelCacheHeight,
167 				     AllPlanes,
168 				     ZPixmap);
169     if (! _XGrPixelCacheImage) {
170 	  col = GrNOCOLOR;
171 	  goto done;
172 	}
173       }
174   col = XGetPixel (_XGrPixelCacheImage, x, y - _XGrPixelCacheY1);
175 done:
176   GRX_RETURN( col );
177 }
178 
179 static INLINE
drawpixel(int x,int y,GrColor c)180 void drawpixel(int x,int y,GrColor c)
181 {
182   GRX_ENTER();
183   _XGrSetForeColor (c);
184   _XGrSetColorOper (c);
185   XDrawPoint (_XGrDisplay,
186 	      (Drawable) CURC->gc_baseaddr[0],
187 	      _XGrGC,
188 	      x,
189 	      y);
190   _XGrCopyBStore(x, y, 1, 1);
191   _XGrCheckPixelCache(y, y);
192 
193   GRX_LEAVE();
194 }
195 
196 static
drawhline(int x,int y,int w,GrColor c)197 void drawhline(int x,int y,int w,GrColor c)
198 {
199   int x2;
200 
201   GRX_ENTER();
202   _XGrSetForeColor (c);
203   _XGrSetColorOper (c);
204   x2 = x + w - 1;
205   XDrawLine (_XGrDisplay,
206 	     (Drawable) CURC->gc_baseaddr[0],
207 	     _XGrGC,
208 	     x,  y,
209 	     x2, y);
210   _XGrCopyBStore(x, y, w, 1);
211   _XGrCheckPixelCache(y, y);
212 
213   GRX_LEAVE();
214 }
215 
216 static
drawvline(int x,int y,int h,GrColor c)217 void drawvline(int x,int y,int h,GrColor c)
218 {
219   int y2;
220 
221   GRX_ENTER();
222   _XGrSetForeColor (c);
223   _XGrSetColorOper (c);
224   y2 = y + h - 1;
225   XDrawLine (_XGrDisplay,
226 	     (Drawable) CURC->gc_baseaddr[0],
227 	     _XGrGC,
228 	     x, y,
229 	     x, y2);
230   _XGrCopyBStore(x, y, 1, h);
231   _XGrCheckPixelCache(y, y2);
232 
233   GRX_LEAVE();
234 }
235 
236 static
drawblock(int x,int y,int w,int h,GrColor c)237 void drawblock(int x,int y,int w,int h,GrColor c)
238 {
239   GRX_ENTER();
240   _XGrSetForeColor (c);
241   _XGrSetColorOper (c);
242   XFillRectangle (_XGrDisplay,
243 		  (Drawable) CURC->gc_baseaddr[0],
244 		  _XGrGC,
245 		  x,
246 		  y,
247 		  w,
248 		  h);
249   _XGrCopyBStore(x, y, w, h);
250   _XGrCheckPixelCache(y, y+h-1);
251 
252   GRX_LEAVE();
253 }
254 
255 
256 static
drawline(int x,int y,int dx,int dy,GrColor c)257 void drawline(int x,int y,int dx,int dy,GrColor c)
258 {
259   GRX_ENTER();
260   _XGrSetForeColor (c);
261   _XGrSetColorOper (c);
262   dx += x;
263   dy += y;
264   XDrawLine (_XGrDisplay,
265 	     (Drawable) CURC->gc_baseaddr[0],
266 	     _XGrGC,
267 	     x, y,
268 	     dx, dy);
269       isort(x,dx);
270       isort(y,dy);
271   _XGrCopyBStore(x, y, dx-x+1, dy-y+1);
272   _XGrCheckPixelCache(y, dy);
273 
274   GRX_LEAVE();
275 }
276 
277 static
drawbitmap(int x,int y,int w,int h,char far * bmp,int pitch,int start,GrColor fg,GrColor bg)278 void drawbitmap(int x,int y,int w,int h,char far *bmp,int pitch,int start,GrColor fg,GrColor bg)
279 {
280   XImage ximage;
281 
282   GRX_ENTER();
283   bmp += (unsigned int)start >> 3;
284   start &= 7;
285 
286   ximage.width          = w;
287   ximage.height         = h;
288   ximage.xoffset        = start;
289   ximage.format         = XYBitmap;
290   ximage.data           = bmp;
291   ximage.byte_order     = LSBFirst;
292   ximage.bitmap_unit    = 8;
293   ximage.bitmap_bit_order = MSBFirst;
294   ximage.bitmap_pad     = 8;
295   ximage.depth          = 1;
296   ximage.bytes_per_line = pitch;
297   ximage.bits_per_pixel = 1;
298   ximage.red_mask       = 0L;
299   ximage.green_mask     = 0L;
300   ximage.blue_mask      = 0L;
301   ximage.obdata         = NULL;
302   sttzero(&ximage.f);
303 
304 # ifndef PRE_R6_ICCCM
305   if ( XInitImage (&ximage) != 0)
306 # endif
307   {
308     if ((C_OPER(fg) == C_OPER(bg)) && (fg != GrNOCOLOR)) {
309       _XGrSetForeColor (fg);
310       _XGrSetBackColor (bg);
311       _XGrSetColorOper (fg);
312       DBGPRINTF(DBG_DRIVER,("Calling XPutImage (1) ...\n"));
313       XPutImage (_XGrDisplay,
314 		 (Drawable) CURC->gc_baseaddr[0],
315 		 _XGrGC,
316 		 &ximage,
317 		 0,
318 		 0,
319 		 x,
320 		 y,
321 		 w,
322 		 h);
323       DBGPRINTF(DBG_DRIVER,("Calling XPutImage (1) done\n"));
324     }
325     else {
326       if (fg != GrNOCOLOR) {
327 	XSetForeground (_XGrDisplay, _XGrBitmapGC, 1);
328 	XSetBackground (_XGrDisplay, _XGrBitmapGC, 0);
329 	DBGPRINTF(DBG_DRIVER,("Calling XPutImage (2) ...\n"));
330 	XPutImage (_XGrDisplay,
331 		   _XGrBitmap,
332 		   _XGrBitmapGC,
333 		   &ximage,
334 		   0,
335 		   0,
336 		   0,
337 		   0,
338 		   w,
339 		   h);
340 	DBGPRINTF(DBG_DRIVER,("Calling XPutImage (2) done\n"));
341 	XSetStipple (_XGrDisplay, _XGrGC, _XGrBitmap);
342 	XSetTSOrigin (_XGrDisplay, _XGrGC, x, y);
343 	XSetFillStyle (_XGrDisplay, _XGrGC, FillStippled);
344 	_XGrSetForeColor (fg);
345 	_XGrSetColorOper (fg);
346 	XFillRectangle (_XGrDisplay,
347 			(Drawable) CURC->gc_baseaddr[0],
348 			_XGrGC,
349 			x,
350 			y,
351 			w,
352 			h);
353       }
354       if (bg != GrNOCOLOR) {
355 	XSetForeground (_XGrDisplay, _XGrBitmapGC, 0);
356 	XSetBackground (_XGrDisplay, _XGrBitmapGC, 1);
357 	DBGPRINTF(DBG_DRIVER,("Calling XPutImage (3) ...\n"));
358 	XPutImage (_XGrDisplay,
359 		   _XGrBitmap,
360 		   _XGrBitmapGC,
361 		   &ximage,
362 		   0,
363 		   0,
364 		   0,
365 		   0,
366 		   w,
367 		   h);
368 	DBGPRINTF(DBG_DRIVER,("Calling XPutImage (3) done\n"));
369 	XSetStipple (_XGrDisplay, _XGrGC, _XGrBitmap);
370 	XSetTSOrigin (_XGrDisplay, _XGrGC, x, y);
371 	XSetFillStyle (_XGrDisplay, _XGrGC, FillStippled);
372 	_XGrSetForeColor (bg);
373 	_XGrSetColorOper (bg);
374 	XFillRectangle (_XGrDisplay,
375 			(Drawable) CURC->gc_baseaddr[0],
376 			_XGrGC,
377 			x,
378 			y,
379 			w,
380 			h);
381       }
382       XSetFillStyle (_XGrDisplay, _XGrGC, FillSolid);
383     }
384 
385     _XGrCopyBStore(x, y, w, h);
386     _XGrCheckPixelCache(y, y+h-1);
387   }
388   GRX_LEAVE();
389 }
390 
391 /* Note: drawpattern is not tested because it's not used in this GRX version */
392 static
drawpattern(int x,int y,int w,char patt,GrColor fg,GrColor bg)393 void drawpattern(int x,int y,int w,char patt,GrColor fg,GrColor bg)
394 {
395   XImage ximage;
396 
397   GRX_ENTER();
398   ximage.width          = 8;
399   ximage.height         = 1;
400   ximage.xoffset        = 0;
401   ximage.format         = XYBitmap;
402   ximage.data           = &patt;
403   ximage.byte_order     = LSBFirst;
404   ximage.bitmap_unit    = 8;
405   ximage.bitmap_bit_order = MSBFirst;
406   ximage.bitmap_pad     = 8;
407   ximage.depth          = 1;
408   ximage.bytes_per_line = 1;
409   ximage.bits_per_pixel = 1;
410   ximage.red_mask       = 0L;
411   ximage.green_mask     = 0L;
412   ximage.blue_mask      = 0L;
413   ximage.obdata         = NULL;
414   sttzero(&ximage.f);
415 
416 # ifndef PRE_R6_ICCCM
417   if (XInitImage (&ximage) != 0)
418 # endif
419   {
420     if ((C_OPER(fg) == C_OPER(bg)) && (fg != GrNOCOLOR)) {
421       XSetForeground (_XGrDisplay, _XGrPatternGC, 1);
422       XSetBackground (_XGrDisplay, _XGrPatternGC, 0);
423       XPutImage (_XGrDisplay,
424 		 _XGrPattern,
425 		 _XGrPatternGC,
426 		 &ximage,
427 		 0,
428 		 0,
429 		 0,
430 		 0,
431 		 8,
432 		 1);
433       XSetStipple (_XGrDisplay, _XGrGC, _XGrPattern);
434       XSetTSOrigin (_XGrDisplay, _XGrGC, x, y);
435       XSetFillStyle (_XGrDisplay, _XGrGC, FillOpaqueStippled);
436       _XGrSetForeColor (fg);
437       _XGrSetBackColor (bg);
438       _XGrSetColorOper (fg);
439       XFillRectangle (_XGrDisplay,
440 		      (Drawable) CURC->gc_baseaddr[0],
441 		      _XGrGC,
442 		      x,
443 		      y,
444 		      w,
445 		      1);
446     }
447     else {
448       if (fg != GrNOCOLOR) {
449 	XSetForeground (_XGrDisplay, _XGrPatternGC, 1);
450 	XSetBackground (_XGrDisplay, _XGrPatternGC, 0);
451 	XPutImage (_XGrDisplay,
452 		   _XGrPattern,
453 		   _XGrPatternGC,
454 		   &ximage,
455 		   0,
456 		   0,
457 		   0,
458 		   0,
459 		   8,
460 		   1);
461 	XSetStipple (_XGrDisplay, _XGrGC, _XGrPattern);
462 	XSetTSOrigin (_XGrDisplay, _XGrGC, x, y);
463 	XSetFillStyle (_XGrDisplay, _XGrGC, FillStippled);
464 	_XGrSetForeColor (fg);
465 	_XGrSetColorOper (fg);
466 	XFillRectangle (_XGrDisplay,
467 			(Drawable) CURC->gc_baseaddr[0],
468 			_XGrGC,
469 			x,
470 			y,
471 			w,
472 			1);
473       }
474       if (bg != GrNOCOLOR) {
475 	XSetForeground (_XGrDisplay, _XGrPatternGC, 0);
476 	XSetBackground (_XGrDisplay, _XGrPatternGC, 1);
477 	XPutImage (_XGrDisplay,
478 		   _XGrPattern,
479 		   _XGrPatternGC,
480 		   &ximage,
481 		   0,
482 		   0,
483 		   0,
484 		   0,
485 		   8,
486 		   1);
487 	XSetStipple (_XGrDisplay, _XGrGC, _XGrPattern);
488 	XSetTSOrigin (_XGrDisplay, _XGrGC, x, y);
489 	XSetFillStyle (_XGrDisplay, _XGrGC, FillStippled);
490 	_XGrSetForeColor (bg);
491 	_XGrSetColorOper (bg);
492 	XFillRectangle (_XGrDisplay,
493 			(Drawable) CURC->gc_baseaddr[0],
494 			_XGrGC,
495 			x,
496 			y,
497 			w,
498 			1);
499       }
500     }
501     XSetFillStyle (_XGrDisplay, _XGrGC, FillSolid);
502 
503     _XGrCopyBStore(x, y, w, 1);
504     _XGrCheckPixelCache(y, y);
505   }
506   GRX_LEAVE();
507 }
508 
509 static
bitblt(GrFrame * dst,int dx,int dy,GrFrame * src,int x,int y,int w,int h,GrColor op)510 void bitblt(GrFrame *dst,int dx,int dy,GrFrame *src,int x,int y,int w,int h,GrColor op)
511 {
512   GRX_ENTER();
513   _XGrSetColorOper (op);
514   XCopyArea (_XGrDisplay,
515 	     (Drawable) src->gf_baseaddr[0],
516 	     (Drawable) dst->gf_baseaddr[0],
517 	     _XGrGC,
518 	     x,
519 	     y,
520 	     w,
521 	     h,
522 	     dx,
523 	     dy);
524 
525   _XGrCopyBStore(dx, dy, w, h);
526   _XGrCheckPixelCache(dy, dy+h-1);
527 
528   GRX_LEAVE();
529 }
530 
531 static
bltv2r(GrFrame * dst,int dx,int dy,GrFrame * src,int sx,int sy,int w,int h,GrColor op)532 void bltv2r(GrFrame *dst,int dx,int dy,GrFrame *src,int sx,int sy,int w,int h,GrColor op)
533 {
534   GRX_ENTER();
535   if(GrColorMode(op) == GrIMAGE)
536     _GrFrDrvGenericBitBlt(dst,dx,dy,
537 			  src,sx,sy,
538 			  w,h,
539 			  op
540 			  );
541   else {
542     XImage *ximage;
543 
544     ximage = XGetImage (_XGrDisplay,
545 			(Drawable) src->gf_baseaddr[0],
546 			sx,
547 			sy,
548 			w,
549 			h,
550 			AllPlanes,
551 			ZPixmap);
552     if (ximage) {
553       int bytes_per_pixel = _XGrBitsPerPixel >> 3;
554       GrFrame tmp = *dst;
555 
556       tmp.gf_baseaddr[0] =
557 	tmp.gf_baseaddr[1] =
558 	  tmp.gf_baseaddr[2] =
559 	    tmp.gf_baseaddr[3] = ximage->data;
560       tmp.gf_lineoffset = ximage->bytes_per_line;
561 
562       _GrFrDrvPackedBitBltR2R(dst, (dx * bytes_per_pixel), dy,
563 			      &tmp, 0, 0,
564 			      (w * bytes_per_pixel), h,
565 			      op
566 			      );
567       XDestroyImage (ximage);
568     }
569   }
570   GRX_LEAVE();
571 }
572 
bltr2v(GrFrame * dst,int dx,int dy,GrFrame * src,int sx,int sy,int w,int h,GrColor op)573 static void bltr2v(GrFrame *dst,int dx,int dy,GrFrame *src,int sx,int sy,int w,int h,GrColor op)
574 {
575   GRX_ENTER();
576   if(GrColorMode(op) == GrIMAGE)
577     _GrFrDrvGenericBitBlt(dst,dx,dy,
578 			  src,sx,sy,
579 			  w,h,
580 			  op
581 			  );
582   else {
583     XImage ximage;
584     Visual *visual = DefaultVisual(_XGrDisplay,_XGrScreen);
585 
586     ximage.width        = sx + w;
587     ximage.height       = sy + h;
588     ximage.xoffset      = 0;
589     ximage.format       = ZPixmap;
590     ximage.data         = src->gf_baseaddr[0];
591     ximage.byte_order   = LSBFirst;
592     ximage.bitmap_unit  = BitmapUnit(_XGrDisplay);
593     ximage.bitmap_bit_order = BitmapBitOrder(_XGrDisplay);
594     ximage.bitmap_pad   = BitmapPad(_XGrDisplay);
595     ximage.depth        = _XGrDepth;
596     ximage.bytes_per_line = src->gf_lineoffset;
597     ximage.bits_per_pixel = _XGrBitsPerPixel;
598     ximage.red_mask     = visual->red_mask;
599     ximage.green_mask   = visual->green_mask;
600     ximage.blue_mask    = visual->blue_mask;
601     ximage.obdata       = NULL;
602     sttzero(&ximage.f);
603 
604 # ifndef PRE_R6_ICCCM
605       if (XInitImage (&ximage) != 0)
606 # endif
607     {
608       _XGrSetColorOper (op);
609       XPutImage (_XGrDisplay,
610 		 (Drawable) dst->gf_baseaddr[0],
611 		 _XGrGC,
612 		 &ximage,
613 		 sx,
614 		 sy,
615 		 dx,
616 		 dy,
617 		 w,
618 		 h);
619       _XGrCopyBStore(dx, dy, w, h);
620       _XGrCheckPixelCache(dy, dy+h-1);
621     }
622   }
623   GRX_LEAVE();
624 }
625 
626 static
putscanline(int x,int y,int w,const GrColor * scl,GrColor op)627 void putscanline(int x, int y, int w, const GrColor *scl, GrColor op)
628 {
629   GrColor skipc;
630   int ind;
631   GRX_ENTER();
632   skipc = op ^ GrIMAGE;
633   _XGrSetColorOper(op);
634 
635   for (ind = 0; ind < w; ind++) {
636     if (scl[ind] != skipc) {
637       _XGrSetForeColor(scl[ind]);
638       XDrawPoint (_XGrDisplay,
639                   (Drawable) CURC->gc_baseaddr[0],
640                   _XGrGC, x+ind, y);
641     }
642   }
643 
644   _XGrCopyBStore(x, y, w, 1);
645   _XGrCheckPixelCache(y, y);
646 
647   GRX_LEAVE();
648 }
649 
650 #define ROUNDCOLORCOMP(x,n) (                                   \
651     ((uint)(x) >= CLRINFO->mask[n]) ?                           \
652 	CLRINFO->mask[n] :                                      \
653 	(((x) + CLRINFO->round[n]) & CLRINFO->mask[n])          \
654 )
655 
init(GrVideoMode * mp)656 static int init(GrVideoMode *mp)
657 {
658 
659   if (_XGrColorNumPixels == 1) {
660     unsigned long i;
661 
662     for (i = 0; i < CLRINFO->ncolors; i++) {
663       if (i >= _XGrColorPixels[0] && i <= _XGrColorPixels[1]) {
664 	CLRINFO->ctable[i].defined  = FALSE;
665       }
666       else {
667 	int r, g, b;
668 	XColor xcolor;
669 
670 	xcolor.red   = 0;
671 	xcolor.green = 0;
672 	xcolor.blue  = 0;
673 	xcolor.pixel = i;
674 	XQueryColors (_XGrDisplay, _XGrColormap, &xcolor, 1);
675 	r = xcolor.red   >> 8;
676 	g = xcolor.green >> 8;
677 	b = xcolor.blue  >> 8;
678 	/*
679 	 * Preallocate Cell; Only a buggy program will free this entry.
680 	 */
681 	CLRINFO->ctable[i].r    = ROUNDCOLORCOMP(r,0);
682 	CLRINFO->ctable[i].g    = ROUNDCOLORCOMP(g,1);
683 	CLRINFO->ctable[i].b    = ROUNDCOLORCOMP(b,2);
684 	CLRINFO->ctable[i].defined      = TRUE;
685 	CLRINFO->ctable[i].writable     = FALSE;
686 	CLRINFO->ctable[i].nused        = 1;
687 	CLRINFO->nfree--;
688       }
689     }
690   }
691   PIXEL_CACHE_INVALIDATE();
692   return(TRUE);
693 }
694 
695 
696 GrFrameDriver _GrFrameDriverXWIN8 = {
697   GR_frameXWIN8,                /* frame mode */
698   GR_frameRAM8,                 /* compatible RAM frame mode */
699   TRUE,                         /* onscreen */
700   4,                            /* line width alignment */
701   1,                            /* number of planes */
702   8,                            /* bits per pixel */
703   8*16*1024L*1024L,             /* max plane size the code can handle */
704   init,
705   readpixel,
706   drawpixel,
707   drawline,
708   drawhline,
709   drawvline,
710   drawblock,
711   drawbitmap,
712   drawpattern,
713   bitblt,
714   bltv2r,
715   bltr2v,
716   _GrFrDrvGenericGetIndexedScanline,
717   putscanline
718 };
719 
720 GrFrameDriver _GrFrameDriverXWIN16 = {
721   GR_frameXWIN16,               /* frame mode */
722   GR_frameRAM16,                /* compatible RAM frame mode */
723   TRUE,                         /* onscreen */
724   4,                            /* line width alignment */
725   1,                            /* number of planes */
726   16,                           /* bits per pixel */
727   16*16*1024L*1024L,            /* max plane size the code can handle */
728   init,
729   readpixel,
730   drawpixel,
731   drawline,
732   drawhline,
733   drawvline,
734   drawblock,
735   drawbitmap,
736   drawpattern,
737   bitblt,
738   bltv2r,
739   bltr2v,
740   _GrFrDrvGenericGetIndexedScanline,
741   putscanline
742 };
743 
744 GrFrameDriver _GrFrameDriverXWIN24 = {
745   GR_frameXWIN24,               /* frame mode */
746   GR_frameRAM24,                /* compatible RAM frame mode */
747   TRUE,                         /* onscreen */
748   4,                            /* line width alignment */
749   1,                            /* number of planes */
750   24,                           /* bits per pixel */
751   24*16*1024L*1024L,            /* max plane size the code can handle */
752   init,
753   readpixel,
754   drawpixel,
755   drawline,
756   drawhline,
757   drawvline,
758   drawblock,
759   drawbitmap,
760   drawpattern,
761   bitblt,
762   bltv2r,
763   bltr2v,
764   _GrFrDrvGenericGetIndexedScanline,
765   putscanline
766 };
767 
768 GrFrameDriver _GrFrameDriverXWIN32L = {
769   GR_frameXWIN32L,              /* frame mode */
770   GR_frameRAM32L,               /* compatible RAM frame mode */
771   TRUE,                         /* onscreen */
772   4,                            /* line width alignment */
773   1,                            /* number of planes */
774   32,                           /* bits per pixel */
775   32*16*1024L*1024L,            /* max plane size the code can handle */
776   init,
777   readpixel,
778   drawpixel,
779   drawline,
780   drawhline,
781   drawvline,
782   drawblock,
783   drawbitmap,
784   drawpattern,
785   bitblt,
786   bltv2r,
787   bltr2v,
788   _GrFrDrvGenericGetIndexedScanline,
789   putscanline
790 };
791 
792 GrFrameDriver _GrFrameDriverXWIN32H = {
793   GR_frameXWIN32H,              /* frame mode */
794   GR_frameRAM32H,                /* compatible RAM frame mode */
795   TRUE,                         /* onscreen */
796   4,                            /* line width alignment */
797   1,                            /* number of planes */
798   32,                           /* bits per pixel */
799   32*16*1024L*1024L,            /* max plane size the code can handle */
800   init,
801   readpixel,
802   drawpixel,
803   drawline,
804   drawhline,
805   drawvline,
806   drawblock,
807   drawbitmap,
808   drawpattern,
809   bitblt,
810   bltv2r,
811   bltr2v,
812   _GrFrDrvGenericGetIndexedScanline,
813   putscanline
814 };
815