]> git.sesse.net Git - rdpsrv/blob - Xserver/programs/Xserver/cfb/cfbgc.c
Support RDP5 logon packets.
[rdpsrv] / Xserver / programs / Xserver / cfb / cfbgc.c
1 /***********************************************************
2
3 Copyright (c) 1987  X Consortium
4
5 Permission is hereby granted, free of charge, to any person obtaining a copy
6 of this software and associated documentation files (the "Software"), to deal
7 in the Software without restriction, including without limitation the rights
8 to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 copies of the Software, and to permit persons to whom the Software is
10 furnished to do so, subject to the following conditions:
11
12 The above copyright notice and this permission notice shall be included in
13 all copies or substantial portions of the Software.
14
15 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL THE
18 X CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
19 AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
20 CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
21
22 Except as contained in this notice, the name of the X Consortium shall not be
23 used in advertising or otherwise to promote the sale, use or other dealings
24 in this Software without prior written authorization from the X Consortium.
25
26
27 Copyright 1987 by Digital Equipment Corporation, Maynard, Massachusetts.
28
29                         All Rights Reserved
30
31 Permission to use, copy, modify, and distribute this software and its 
32 documentation for any purpose and without fee is hereby granted, 
33 provided that the above copyright notice appear in all copies and that
34 both that copyright notice and this permission notice appear in 
35 supporting documentation, and that the name of Digital not be
36 used in advertising or publicity pertaining to distribution of the
37 software without specific, written prior permission.  
38
39 DIGITAL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
40 ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
41 DIGITAL BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR
42 ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
43 WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
44 ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
45 SOFTWARE.
46
47 ******************************************************************/
48
49 /* $XConsortium: cfbgc.c,v 5.62 94/04/17 20:28:49 dpw Exp $ */
50
51 #include "X.h"
52 #include "Xmd.h"
53 #include "Xproto.h"
54 #include "cfb.h"
55 #include "fontstruct.h"
56 #include "dixfontstr.h"
57 #include "gcstruct.h"
58 #include "windowstr.h"
59 #include "pixmapstr.h"
60 #include "scrnintstr.h"
61 #include "region.h"
62
63 #include "mistruct.h"
64 #include "mibstore.h"
65 #include "migc.h"
66
67 #include "cfbmskbits.h"
68 #include "cfb8bit.h"
69
70 #if PSZ == 8
71 # define useTEGlyphBlt  cfbTEGlyphBlt8
72 #else
73 # ifdef WriteBitGroup
74 #  define useTEGlyphBlt cfbImageGlyphBlt8
75 # else
76 #  define useTEGlyphBlt cfbTEGlyphBlt
77 # endif
78 #endif
79
80 #ifdef WriteBitGroup
81 # define useImageGlyphBlt       cfbImageGlyphBlt8
82 # define usePolyGlyphBlt        cfbPolyGlyphBlt8
83 #else
84 # define useImageGlyphBlt       miImageGlyphBlt
85 # define usePolyGlyphBlt        miPolyGlyphBlt
86 #endif
87
88 #ifdef FOUR_BIT_CODE
89 # define usePushPixels  cfbPushPixels8
90 #else
91 # define usePushPixels  mfbPushPixels
92 #endif
93
94 #ifdef PIXEL_ADDR
95 # define ZeroPolyArc    cfbZeroPolyArcSS8Copy
96 #else
97 # define ZeroPolyArc    miZeroPolyArc
98 #endif
99
100 GCFuncs cfbGCFuncs = {
101     cfbValidateGC,
102     miChangeGC,
103     miCopyGC,
104     miDestroyGC,
105     miChangeClip,
106     miDestroyClip,
107     miCopyClip,
108 };
109
110 GCOps   cfbTEOps1Rect = {
111     cfbSolidSpansCopy,
112     cfbSetSpans,
113     cfbPutImage,
114     cfbCopyArea,
115     cfbCopyPlane,
116     cfbPolyPoint,
117 #ifdef PIXEL_ADDR
118     cfb8LineSS1Rect,
119     cfb8SegmentSS1Rect,
120 #else
121     cfbLineSS,
122     cfbSegmentSS,
123 #endif
124     miPolyRectangle,
125     ZeroPolyArc,
126     cfbFillPoly1RectCopy,
127     cfbPolyFillRect,
128     cfbPolyFillArcSolidCopy,
129     miPolyText8,
130     miPolyText16,
131     miImageText8,
132     miImageText16,
133     useTEGlyphBlt,
134     usePolyGlyphBlt,
135     usePushPixels
136 #ifdef NEED_LINEHELPER
137     ,NULL
138 #endif
139 };
140
141 GCOps   cfbNonTEOps1Rect = {
142     cfbSolidSpansCopy,
143     cfbSetSpans,
144     cfbPutImage,
145     cfbCopyArea,
146     cfbCopyPlane,
147     cfbPolyPoint,
148 #ifdef PIXEL_ADDR
149     cfb8LineSS1Rect,
150     cfb8SegmentSS1Rect,
151 #else
152     cfbLineSS,
153     cfbSegmentSS,
154 #endif
155     miPolyRectangle,
156     ZeroPolyArc,
157     cfbFillPoly1RectCopy,
158     cfbPolyFillRect,
159     cfbPolyFillArcSolidCopy,
160     miPolyText8,
161     miPolyText16,
162     miImageText8,
163     miImageText16,
164     useImageGlyphBlt,
165     usePolyGlyphBlt,
166     usePushPixels
167 #ifdef NEED_LINEHELPER
168     ,NULL
169 #endif
170 };
171
172 GCOps   cfbTEOps = {
173     cfbSolidSpansCopy,
174     cfbSetSpans,
175     cfbPutImage,
176     cfbCopyArea,
177     cfbCopyPlane,
178     cfbPolyPoint,
179     cfbLineSS,
180     cfbSegmentSS,
181     miPolyRectangle,
182     ZeroPolyArc,
183     miFillPolygon,
184     cfbPolyFillRect,
185     cfbPolyFillArcSolidCopy,
186     miPolyText8,
187     miPolyText16,
188     miImageText8,
189     miImageText16,
190     useTEGlyphBlt,
191     usePolyGlyphBlt,
192     usePushPixels
193 #ifdef NEED_LINEHELPER
194     ,NULL
195 #endif
196 };
197
198 GCOps   cfbNonTEOps = {
199     cfbSolidSpansCopy,
200     cfbSetSpans,
201     cfbPutImage,
202     cfbCopyArea,
203     cfbCopyPlane,
204     cfbPolyPoint,
205     cfbLineSS,
206     cfbSegmentSS,
207     miPolyRectangle,
208 #ifdef PIXEL_ADDR
209     cfbZeroPolyArcSS8Copy,
210 #else
211     miZeroPolyArc,
212 #endif
213     miFillPolygon,
214     cfbPolyFillRect,
215     cfbPolyFillArcSolidCopy,
216     miPolyText8,
217     miPolyText16,
218     miImageText8,
219     miImageText16,
220     useImageGlyphBlt,
221     usePolyGlyphBlt,
222     usePushPixels
223 #ifdef NEED_LINEHELPER
224     ,NULL
225 #endif
226 };
227
228 GCOps *
229 cfbMatchCommon (pGC, devPriv)
230     GCPtr           pGC;
231     cfbPrivGCPtr    devPriv;
232 {
233     if (pGC->lineWidth != 0)
234         return 0;
235     if (pGC->lineStyle != LineSolid)
236         return 0;
237     if (pGC->fillStyle != FillSolid)
238         return 0;
239     if (devPriv->rop != GXcopy)
240         return 0;
241     if (pGC->font &&
242         FONTMAXBOUNDS(pGC->font,rightSideBearing) -
243         FONTMINBOUNDS(pGC->font,leftSideBearing) <= 32 &&
244         FONTMINBOUNDS(pGC->font,characterWidth) >= 0)
245     {
246         if (TERMINALFONT(pGC->font)
247 #ifdef FOUR_BIT_CODE
248             && FONTMAXBOUNDS(pGC->font,characterWidth) >= PGSZB
249 #endif
250         )
251 #ifdef NO_ONE_RECT
252             return &cfbTEOps1Rect;
253 #else
254             if (devPriv->oneRect)
255                 return &cfbTEOps1Rect;
256             else
257                 return &cfbTEOps;
258 #endif
259         else
260 #ifdef NO_ONE_RECT
261             return &cfbNonTEOps1Rect;
262 #else
263             if (devPriv->oneRect)
264                 return &cfbNonTEOps1Rect;
265             else
266                 return &cfbNonTEOps;
267 #endif
268     }
269     return 0;
270 }
271
272 Bool
273 cfbCreateGC(pGC)
274     register GCPtr pGC;
275 {
276     cfbPrivGC  *pPriv;
277
278     if (PixmapWidthPaddingInfo[pGC->depth].padPixelsLog2 == LOG2_BITMAP_PAD)
279         return (mfbCreateGC(pGC));
280     pGC->clientClip = NULL;
281     pGC->clientClipType = CT_NONE;
282
283     /*
284      * some of the output primitives aren't really necessary, since they
285      * will be filled in ValidateGC because of dix/CreateGC() setting all
286      * the change bits.  Others are necessary because although they depend
287      * on being a color frame buffer, they don't change 
288      */
289
290     pGC->ops = &cfbNonTEOps;
291     pGC->funcs = &cfbGCFuncs;
292
293     /* cfb wants to translate before scan conversion */
294     pGC->miTranslate = 1;
295
296     pPriv = cfbGetGCPrivate(pGC);
297     pPriv->rop = pGC->alu;
298     pPriv->oneRect = FALSE;
299     pPriv->fExpose = TRUE;
300     pPriv->freeCompClip = FALSE;
301     pPriv->pRotatedPixmap = (PixmapPtr) NULL;
302     return TRUE;
303 }
304
305 /* Clipping conventions
306         if the drawable is a window
307             CT_REGION ==> pCompositeClip really is the composite
308             CT_other ==> pCompositeClip is the window clip region
309         if the drawable is a pixmap
310             CT_REGION ==> pCompositeClip is the translated client region
311                 clipped to the pixmap boundary
312             CT_other ==> pCompositeClip is the pixmap bounding box
313 */
314
315 void
316 cfbValidateGC(pGC, changes, pDrawable)
317     register GCPtr  pGC;
318     unsigned long   changes;
319     DrawablePtr     pDrawable;
320 {
321     int         mask;           /* stateChanges */
322     int         index;          /* used for stepping through bitfields */
323     int         new_rrop;
324     int         new_line, new_text, new_fillspans, new_fillarea;
325     int         new_rotate;
326     int         xrot, yrot;
327     /* flags for changing the proc vector */
328     cfbPrivGCPtr devPriv;
329     int         oneRect;
330
331     new_rotate = pGC->lastWinOrg.x != pDrawable->x ||
332                  pGC->lastWinOrg.y != pDrawable->y;
333
334     pGC->lastWinOrg.x = pDrawable->x;
335     pGC->lastWinOrg.y = pDrawable->y;
336     devPriv = cfbGetGCPrivate(pGC);
337
338     new_rrop = FALSE;
339     new_line = FALSE;
340     new_text = FALSE;
341     new_fillspans = FALSE;
342     new_fillarea = FALSE;
343
344     /*
345      * if the client clip is different or moved OR the subwindowMode has
346      * changed OR the window's clip has changed since the last validation
347      * we need to recompute the composite clip 
348      */
349
350     if ((changes & (GCClipXOrigin|GCClipYOrigin|GCClipMask|GCSubwindowMode)) ||
351         (pDrawable->serialNumber != (pGC->serialNumber & DRAWABLE_SERIAL_BITS))
352         )
353     {
354         miComputeCompositeClip (pGC, pDrawable);
355 #ifdef NO_ONE_RECT
356         devPriv->oneRect = FALSE;
357 #else
358         oneRect = REGION_NUM_RECTS(devPriv->pCompositeClip) == 1;
359         if (oneRect != devPriv->oneRect)
360             new_line = TRUE;
361         devPriv->oneRect = oneRect;
362 #endif
363     }
364
365     mask = changes;
366     while (mask) {
367         index = lowbit (mask);
368         mask &= ~index;
369
370         /*
371          * this switch acculmulates a list of which procedures might have
372          * to change due to changes in the GC.  in some cases (e.g.
373          * changing one 16 bit tile for another) we might not really need
374          * a change, but the code is being paranoid. this sort of batching
375          * wins if, for example, the alu and the font have been changed,
376          * or any other pair of items that both change the same thing. 
377          */
378         switch (index) {
379         case GCFunction:
380         case GCForeground:
381             new_rrop = TRUE;
382             break;
383         case GCPlaneMask:
384             new_rrop = TRUE;
385             new_text = TRUE;
386             break;
387         case GCBackground:
388             break;
389         case GCLineStyle:
390         case GCLineWidth:
391             new_line = TRUE;
392             break;
393         case GCJoinStyle:
394         case GCCapStyle:
395             break;
396         case GCFillStyle:
397             new_text = TRUE;
398             new_fillspans = TRUE;
399             new_line = TRUE;
400             new_fillarea = TRUE;
401             break;
402         case GCFillRule:
403             break;
404         case GCTile:
405             new_fillspans = TRUE;
406             new_fillarea = TRUE;
407             break;
408
409         case GCStipple:
410             if (pGC->stipple)
411             {
412                 int width = pGC->stipple->drawable.width;
413                 PixmapPtr nstipple;
414
415                 if ((width <= PGSZ) && !(width & (width - 1)) &&
416                     (nstipple = cfbCopyPixmap(pGC->stipple)))
417                 {
418                     cfbPadPixmap(nstipple);
419                     (*pGC->pScreen->DestroyPixmap)(pGC->stipple);
420                     pGC->stipple = nstipple;
421                 }
422             }
423             new_fillspans = TRUE;
424             new_fillarea = TRUE;
425             break;
426
427         case GCTileStipXOrigin:
428             new_rotate = TRUE;
429             break;
430
431         case GCTileStipYOrigin:
432             new_rotate = TRUE;
433             break;
434
435         case GCFont:
436             new_text = TRUE;
437             break;
438         case GCSubwindowMode:
439             break;
440         case GCGraphicsExposures:
441             break;
442         case GCClipXOrigin:
443             break;
444         case GCClipYOrigin:
445             break;
446         case GCClipMask:
447             break;
448         case GCDashOffset:
449             break;
450         case GCDashList:
451             break;
452         case GCArcMode:
453             break;
454         default:
455             break;
456         }
457     }
458
459     /*
460      * If the drawable has changed,  ensure suitable
461      * entries are in the proc vector. 
462      */
463     if (pDrawable->serialNumber != (pGC->serialNumber & (DRAWABLE_SERIAL_BITS))) {
464         new_fillspans = TRUE;   /* deal with FillSpans later */
465     }
466
467     if (new_rotate || new_fillspans)
468     {
469         Bool new_pix = FALSE;
470
471         xrot = pGC->patOrg.x + pDrawable->x;
472         yrot = pGC->patOrg.y + pDrawable->y;
473
474         switch (pGC->fillStyle)
475         {
476         case FillTiled:
477             if (!pGC->tileIsPixel)
478             {
479                 int width = pGC->tile.pixmap->drawable.width * PSZ;
480
481                 if ((width <= PGSZ) && !(width & (width - 1)))
482                 {
483                     cfbCopyRotatePixmap(pGC->tile.pixmap,
484                                         &devPriv->pRotatedPixmap,
485                                         xrot, yrot);
486                     new_pix = TRUE;
487                 }
488             }
489             break;
490 #ifdef FOUR_BIT_CODE
491         case FillStippled:
492         case FillOpaqueStippled:
493             {
494                 int width = pGC->stipple->drawable.width;
495
496                 if ((width <= PGSZ) && !(width & (width - 1)))
497                 {
498                     mfbCopyRotatePixmap(pGC->stipple,
499                                         &devPriv->pRotatedPixmap, xrot, yrot);
500                     new_pix = TRUE;
501                 }
502             }
503             break;
504 #endif
505         }
506         if (!new_pix && devPriv->pRotatedPixmap)
507         {
508             (*pGC->pScreen->DestroyPixmap)(devPriv->pRotatedPixmap);
509             devPriv->pRotatedPixmap = (PixmapPtr) NULL;
510         }
511     }
512
513     if (new_rrop)
514     {
515         int old_rrop;
516
517         old_rrop = devPriv->rop;
518         devPriv->rop = cfbReduceRasterOp (pGC->alu, pGC->fgPixel,
519                                            pGC->planemask,
520                                            &devPriv->and, &devPriv->xor);
521         if (old_rrop == devPriv->rop)
522             new_rrop = FALSE;
523         else
524         {
525 #ifdef PIXEL_ADDR
526             new_line = TRUE;
527 #endif
528 #ifdef WriteBitGroup
529             new_text = TRUE;
530 #endif
531             new_fillspans = TRUE;
532             new_fillarea = TRUE;
533         }
534     }
535
536     if (new_rrop || new_fillspans || new_text || new_fillarea || new_line)
537     {
538         GCOps   *newops;
539
540         if (newops = cfbMatchCommon (pGC, devPriv))
541         {
542             if (pGC->ops->devPrivate.val)
543                 miDestroyGCOps (pGC->ops);
544             pGC->ops = newops;
545             new_rrop = new_line = new_fillspans = new_text = new_fillarea = 0;
546         }
547         else
548         {
549             if (!pGC->ops->devPrivate.val)
550             {
551                 pGC->ops = miCreateGCOps (pGC->ops);
552                 pGC->ops->devPrivate.val = 1;
553             }
554         }
555     }
556
557     /* deal with the changes we've collected */
558     if (new_line)
559     {
560         pGC->ops->FillPolygon = miFillPolygon;
561 #ifdef NO_ONE_RECT
562         if (pGC->fillStyle == FillSolid)
563         {
564             switch (devPriv->rop) {
565             case GXcopy:
566                 pGC->ops->FillPolygon = cfbFillPoly1RectCopy;
567                 break;
568             default:
569                 pGC->ops->FillPolygon = cfbFillPoly1RectGeneral;
570                 break;
571             }
572         }
573 #else
574         if (devPriv->oneRect && pGC->fillStyle == FillSolid)
575         {
576             switch (devPriv->rop) {
577             case GXcopy:
578                 pGC->ops->FillPolygon = cfbFillPoly1RectCopy;
579                 break;
580             default:
581                 pGC->ops->FillPolygon = cfbFillPoly1RectGeneral;
582                 break;
583             }
584         }
585 #endif
586         if (pGC->lineWidth == 0)
587         {
588 #ifdef PIXEL_ADDR
589             if ((pGC->lineStyle == LineSolid) && (pGC->fillStyle == FillSolid))
590             {
591                 switch (devPriv->rop)
592                 {
593                 case GXxor:
594                     pGC->ops->PolyArc = cfbZeroPolyArcSS8Xor;
595                     break;
596                 case GXcopy:
597                     pGC->ops->PolyArc = cfbZeroPolyArcSS8Copy;
598                     break;
599                 default:
600                     pGC->ops->PolyArc = cfbZeroPolyArcSS8General;
601                     break;
602                 }
603             }
604             else
605 #endif
606                 pGC->ops->PolyArc = miZeroPolyArc;
607         }
608         else
609             pGC->ops->PolyArc = miPolyArc;
610         pGC->ops->PolySegment = miPolySegment;
611         switch (pGC->lineStyle)
612         {
613         case LineSolid:
614             if(pGC->lineWidth == 0)
615             {
616                 if (pGC->fillStyle == FillSolid)
617                 {
618 #if defined(PIXEL_ADDR) && !defined(NO_ONE_RECT)
619                     if (devPriv->oneRect &&
620                         ((pDrawable->x >= pGC->pScreen->width - 32768) &&
621                          (pDrawable->y >= pGC->pScreen->height - 32768)))
622                     {
623                         pGC->ops->Polylines = cfb8LineSS1Rect;
624                         pGC->ops->PolySegment = cfb8SegmentSS1Rect;
625                     } else
626 #endif
627 #ifdef NO_ONE_RECT
628                     {
629                         pGC->ops->Polylines = cfb8LineSS1Rect;
630                         pGC->ops->PolySegment = cfb8SegmentSS1Rect;
631                     }
632 #else
633                     {
634                         pGC->ops->Polylines = cfbLineSS;
635                         pGC->ops->PolySegment = cfbSegmentSS;
636                     }
637 #endif
638                 }
639                 else
640                     pGC->ops->Polylines = miZeroLine;
641             }
642             else
643                 pGC->ops->Polylines = miWideLine;
644             break;
645         case LineOnOffDash:
646         case LineDoubleDash:
647             if (pGC->lineWidth == 0 && pGC->fillStyle == FillSolid)
648             {
649                 pGC->ops->Polylines = cfbLineSD;
650                 pGC->ops->PolySegment = cfbSegmentSD;
651             } else
652                 pGC->ops->Polylines = miWideDash;
653             break;
654         }
655     }
656
657     if (new_text && (pGC->font))
658     {
659         if (FONTMAXBOUNDS(pGC->font,rightSideBearing) -
660             FONTMINBOUNDS(pGC->font,leftSideBearing) > 32 ||
661             FONTMINBOUNDS(pGC->font,characterWidth) < 0)
662         {
663             pGC->ops->PolyGlyphBlt = miPolyGlyphBlt;
664             pGC->ops->ImageGlyphBlt = miImageGlyphBlt;
665         }
666         else
667         {
668 #ifdef WriteBitGroup
669             if (pGC->fillStyle == FillSolid)
670             {
671                 if (devPriv->rop == GXcopy)
672                     pGC->ops->PolyGlyphBlt = cfbPolyGlyphBlt8;
673                 else
674 #ifdef FOUR_BIT_CODE
675                     pGC->ops->PolyGlyphBlt = cfbPolyGlyphRop8;
676 #else
677                     pGC->ops->PolyGlyphBlt = miPolyGlyphBlt;
678 #endif
679             }
680             else
681 #endif
682                 pGC->ops->PolyGlyphBlt = miPolyGlyphBlt;
683             /* special case ImageGlyphBlt for terminal emulator fonts */
684 #if !defined(WriteBitGroup) || PSZ == 8
685             if (TERMINALFONT(pGC->font) &&
686                 (pGC->planemask & PMSK) == PMSK
687 #ifdef FOUR_BIT_CODE
688                 && FONTMAXBOUNDS(pGC->font,characterWidth) >= PGSZB
689 #endif
690                 )
691             {
692                 pGC->ops->ImageGlyphBlt = useTEGlyphBlt;
693             }
694             else
695 #endif
696             {
697 #ifdef WriteBitGroup
698                 if (devPriv->rop == GXcopy &&
699                     pGC->fillStyle == FillSolid &&
700                     (pGC->planemask & PMSK) == PMSK)
701                     pGC->ops->ImageGlyphBlt = cfbImageGlyphBlt8;
702                 else
703 #endif
704                     pGC->ops->ImageGlyphBlt = miImageGlyphBlt;
705             }
706         }
707     }    
708
709
710     if (new_fillspans) {
711         switch (pGC->fillStyle) {
712         case FillSolid:
713             switch (devPriv->rop) {
714             case GXcopy:
715                 pGC->ops->FillSpans = cfbSolidSpansCopy;
716                 break;
717             case GXxor:
718                 pGC->ops->FillSpans = cfbSolidSpansXor;
719                 break;
720             default:
721                 pGC->ops->FillSpans = cfbSolidSpansGeneral;
722                 break;
723             }
724             break;
725         case FillTiled:
726             if (devPriv->pRotatedPixmap)
727             {
728                 if (pGC->alu == GXcopy && (pGC->planemask & PMSK) == PMSK)
729                     pGC->ops->FillSpans = cfbTile32FSCopy;
730                 else
731                     pGC->ops->FillSpans = cfbTile32FSGeneral;
732             }
733             else
734                 pGC->ops->FillSpans = cfbUnnaturalTileFS;
735             break;
736         case FillStippled:
737 #ifdef FOUR_BIT_CODE
738             if (devPriv->pRotatedPixmap)
739                 pGC->ops->FillSpans = cfb8Stipple32FS;
740             else
741 #endif
742                 pGC->ops->FillSpans = cfbUnnaturalStippleFS;
743             break;
744         case FillOpaqueStippled:
745 #ifdef FOUR_BIT_CODE
746             if (devPriv->pRotatedPixmap)
747                 pGC->ops->FillSpans = cfb8OpaqueStipple32FS;
748             else
749 #endif
750                 pGC->ops->FillSpans = cfbUnnaturalStippleFS;
751             break;
752         default:
753             FatalError("cfbValidateGC: illegal fillStyle\n");
754         }
755     } /* end of new_fillspans */
756
757     if (new_fillarea) {
758 #ifndef FOUR_BIT_CODE
759         pGC->ops->PolyFillRect = miPolyFillRect;
760         if (pGC->fillStyle == FillSolid || pGC->fillStyle == FillTiled)
761         {
762             pGC->ops->PolyFillRect = cfbPolyFillRect;
763         }
764 #endif
765 #ifdef FOUR_BIT_CODE
766         pGC->ops->PushPixels = mfbPushPixels;
767         if (pGC->fillStyle == FillSolid && devPriv->rop == GXcopy)
768             pGC->ops->PushPixels = cfbPushPixels8;
769 #endif
770         pGC->ops->PolyFillArc = miPolyFillArc;
771         if (pGC->fillStyle == FillSolid)
772         {
773             switch (devPriv->rop)
774             {
775             case GXcopy:
776                 pGC->ops->PolyFillArc = cfbPolyFillArcSolidCopy;
777                 break;
778             default:
779                 pGC->ops->PolyFillArc = cfbPolyFillArcSolidGeneral;
780                 break;
781             }
782         }
783     }
784 }