]> git.sesse.net Git - rdpsrv/blob - Xserver/programs/Xserver/cfb/cfbfillrct.c
Support RDP5 logon packets.
[rdpsrv] / Xserver / programs / Xserver / cfb / cfbfillrct.c
1 /*
2  * Fill rectangles.
3  */
4
5 /*
6
7 Copyright (c) 1989  X Consortium
8
9 Permission is hereby granted, free of charge, to any person obtaining a copy
10 of this software and associated documentation files (the "Software"), to deal
11 in the Software without restriction, including without limitation the rights
12 to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
13 copies of the Software, and to permit persons to whom the Software is
14 furnished to do so, subject to the following conditions:
15
16 The above copyright notice and this permission notice shall be included in
17 all copies or substantial portions of the Software.
18
19 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
20 IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
21 FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL THE
22 X CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
23 AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
24 CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
25
26 Except as contained in this notice, the name of the X Consortium shall not be
27 used in advertising or otherwise to promote the sale, use or other dealings
28 in this Software without prior written authorization from the X Consortium.
29 */
30
31 /* $XConsortium: cfbfillrct.c,v 5.18 94/04/17 20:28:47 dpw Exp $ */
32 /* $XFree86: xc/programs/Xserver/cfb/cfbfillrct.c,v 3.1.4.1 1997/05/10 07:02:48 hohndel Exp $ */
33
34 #include "X.h"
35 #include "Xmd.h"
36 #include "servermd.h"
37 #include "gcstruct.h"
38 #include "window.h"
39 #include "pixmapstr.h"
40 #include "scrnintstr.h"
41 #include "windowstr.h"
42
43 #include "cfb.h"
44 #include "cfbmskbits.h"
45 #include "mergerop.h"
46
47
48 void
49 cfbFillBoxTileOdd (pDrawable, n, rects, tile, xrot, yrot)
50     DrawablePtr pDrawable;
51     int         n;
52     BoxPtr      rects;
53     PixmapPtr   tile;
54     int         xrot, yrot;
55 {
56 #if PSZ == 24
57     if (tile->drawable.width & 3)
58 #else
59     if (tile->drawable.width & PIM)
60 #endif
61         cfbFillBoxTileOddCopy (pDrawable, n, rects, tile, xrot, yrot, GXcopy, ~0L);
62     else
63         cfbFillBoxTile32sCopy (pDrawable, n, rects, tile, xrot, yrot, GXcopy, ~0L);
64 }
65
66 void
67 cfbFillRectTileOdd (pDrawable, pGC, nBox, pBox)
68     DrawablePtr pDrawable;
69     GCPtr       pGC;
70     int         nBox;
71     BoxPtr      pBox;
72 {
73     int xrot, yrot;
74     void    (*fill)();
75
76     xrot = pDrawable->x + pGC->patOrg.x;
77     yrot = pDrawable->y + pGC->patOrg.y;
78 #if PSZ == 24
79     if (pGC->tile.pixmap->drawable.width & 3)
80 #else
81     if (pGC->tile.pixmap->drawable.width & PIM)
82 #endif
83     {
84         fill = cfbFillBoxTileOddGeneral;
85         if ((pGC->planemask & PMSK) == PMSK)
86         {
87             if (pGC->alu == GXcopy)
88                 fill = cfbFillBoxTileOddCopy;
89         }
90     }
91     else
92     {
93         fill = cfbFillBoxTile32sGeneral;
94         if ((pGC->planemask & PMSK) == PMSK)
95         {
96             if (pGC->alu == GXcopy)
97                 fill = cfbFillBoxTile32sCopy;
98         }
99     }
100     (*fill) (pDrawable, nBox, pBox, pGC->tile.pixmap, xrot, yrot, pGC->alu, pGC->planemask);
101 }
102
103 #define NUM_STACK_RECTS 1024
104
105 void
106 cfbPolyFillRect(pDrawable, pGC, nrectFill, prectInit)
107     DrawablePtr pDrawable;
108     register GCPtr pGC;
109     int         nrectFill;      /* number of rectangles to fill */
110     xRectangle  *prectInit;     /* Pointer to first rectangle to fill */
111 {
112     xRectangle      *prect;
113     RegionPtr       prgnClip;
114     register BoxPtr pbox;
115     register BoxPtr pboxClipped;
116     BoxPtr          pboxClippedBase;
117     BoxPtr          pextent;
118     BoxRec          stackRects[NUM_STACK_RECTS];
119     cfbPrivGC       *priv;
120     int             numRects;
121     void            (*BoxFill)();
122     int             n;
123     int             xorg, yorg;
124
125 #if PSZ != 8
126     if ((pGC->fillStyle == FillStippled) ||
127         (pGC->fillStyle == FillOpaqueStippled)) {
128        miPolyFillRect(pDrawable, pGC, nrectFill, prectInit);
129        return;
130     }
131 #endif
132
133     priv = cfbGetGCPrivate(pGC);
134     prgnClip = priv->pCompositeClip;
135
136     BoxFill = 0;
137     switch (pGC->fillStyle)
138     {
139     case FillSolid:
140         switch (priv->rop) {
141         case GXcopy:
142             BoxFill = cfbFillRectSolidCopy;
143             break;
144         case GXxor:
145             BoxFill = cfbFillRectSolidXor;
146             break;
147         default:
148             BoxFill = cfbFillRectSolidGeneral;
149             break;
150         }
151         break;
152     case FillTiled:
153         if (!cfbGetGCPrivate(pGC)->pRotatedPixmap)
154             BoxFill = cfbFillRectTileOdd;
155         else
156         {
157             if (pGC->alu == GXcopy && (pGC->planemask & PMSK) == PMSK)
158                 BoxFill = cfbFillRectTile32Copy;
159             else
160                 BoxFill = cfbFillRectTile32General;
161         }
162         break;
163 #if PSZ == 8
164     case FillStippled:
165         if (!cfbGetGCPrivate(pGC)->pRotatedPixmap)
166             BoxFill = cfb8FillRectStippledUnnatural;
167         else
168             BoxFill = cfb8FillRectTransparentStippled32;
169         break;
170     case FillOpaqueStippled:
171         if (!cfbGetGCPrivate(pGC)->pRotatedPixmap)
172             BoxFill = cfb8FillRectStippledUnnatural;
173         else
174             BoxFill = cfb8FillRectOpaqueStippled32;
175         break;
176 #endif
177     }
178     prect = prectInit;
179     xorg = pDrawable->x;
180     yorg = pDrawable->y;
181     if (xorg || yorg)
182     {
183         prect = prectInit;
184         n = nrectFill;
185         while(n--)
186         {
187             prect->x += xorg;
188             prect->y += yorg;
189             prect++;
190         }
191     }
192
193     prect = prectInit;
194
195     numRects = REGION_NUM_RECTS(prgnClip) * nrectFill;
196     if (numRects > NUM_STACK_RECTS)
197     {
198         pboxClippedBase = (BoxPtr)ALLOCATE_LOCAL(numRects * sizeof(BoxRec));
199         if (!pboxClippedBase)
200             return;
201     }
202     else
203         pboxClippedBase = stackRects;
204
205     pboxClipped = pboxClippedBase;
206         
207     if (REGION_NUM_RECTS(prgnClip) == 1)
208     {
209         int x1, y1, x2, y2, bx2, by2;
210
211         pextent = REGION_RECTS(prgnClip);
212         x1 = pextent->x1;
213         y1 = pextent->y1;
214         x2 = pextent->x2;
215         y2 = pextent->y2;
216         while (nrectFill--)
217         {
218             if ((pboxClipped->x1 = prect->x) < x1)
219                 pboxClipped->x1 = x1;
220     
221             if ((pboxClipped->y1 = prect->y) < y1)
222                 pboxClipped->y1 = y1;
223     
224             bx2 = (int) prect->x + (int) prect->width;
225             if (bx2 > x2)
226                 bx2 = x2;
227             pboxClipped->x2 = bx2;
228     
229             by2 = (int) prect->y + (int) prect->height;
230             if (by2 > y2)
231                 by2 = y2;
232             pboxClipped->y2 = by2;
233
234             prect++;
235             if ((pboxClipped->x1 < pboxClipped->x2) &&
236                 (pboxClipped->y1 < pboxClipped->y2))
237             {
238                 pboxClipped++;
239             }
240         }
241     }
242     else
243     {
244         int x1, y1, x2, y2, bx2, by2;
245
246         pextent = REGION_EXTENTS(pGC->pScreen, prgnClip);
247         x1 = pextent->x1;
248         y1 = pextent->y1;
249         x2 = pextent->x2;
250         y2 = pextent->y2;
251         while (nrectFill--)
252         {
253             BoxRec box;
254     
255             if ((box.x1 = prect->x) < x1)
256                 box.x1 = x1;
257     
258             if ((box.y1 = prect->y) < y1)
259                 box.y1 = y1;
260     
261             bx2 = (int) prect->x + (int) prect->width;
262             if (bx2 > x2)
263                 bx2 = x2;
264             box.x2 = bx2;
265     
266             by2 = (int) prect->y + (int) prect->height;
267             if (by2 > y2)
268                 by2 = y2;
269             box.y2 = by2;
270     
271             prect++;
272     
273             if ((box.x1 >= box.x2) || (box.y1 >= box.y2))
274                 continue;
275     
276             n = REGION_NUM_RECTS (prgnClip);
277             pbox = REGION_RECTS(prgnClip);
278     
279             /* clip the rectangle to each box in the clip region
280                this is logically equivalent to calling Intersect()
281             */
282             while(n--)
283             {
284                 pboxClipped->x1 = max(box.x1, pbox->x1);
285                 pboxClipped->y1 = max(box.y1, pbox->y1);
286                 pboxClipped->x2 = min(box.x2, pbox->x2);
287                 pboxClipped->y2 = min(box.y2, pbox->y2);
288                 pbox++;
289
290                 /* see if clipping left anything */
291                 if(pboxClipped->x1 < pboxClipped->x2 && 
292                    pboxClipped->y1 < pboxClipped->y2)
293                 {
294                     pboxClipped++;
295                 }
296             }
297         }
298     }
299     if (pboxClipped != pboxClippedBase)
300         (*BoxFill) (pDrawable, pGC,
301                     pboxClipped-pboxClippedBase, pboxClippedBase);
302     if (pboxClippedBase != stackRects)
303         DEALLOCATE_LOCAL(pboxClippedBase);
304 }