]> git.sesse.net Git - rdpsrv/blob - Xserver/programs/Xserver/mi/migc.c
Support RDP5 logon packets.
[rdpsrv] / Xserver / programs / Xserver / mi / migc.c
1 /* $XConsortium: migc.c,v 1.4 94/04/17 20:27:36 dpw Exp $ */
2 /*
3
4 Copyright (c) 1993  X Consortium
5
6 Permission is hereby granted, free of charge, to any person obtaining
7 a copy of this software and associated documentation files (the
8 "Software"), to deal in the Software without restriction, including
9 without limitation the rights to use, copy, modify, merge, publish,
10 distribute, sublicense, and/or sell copies of the Software, and to
11 permit persons to whom the Software is furnished to do so, subject to
12 the following conditions:
13
14 The above copyright notice and this permission notice shall be included
15 in all copies or substantial portions of the Software.
16
17 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
18 OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
19 MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
20 IN NO EVENT SHALL THE X CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR
21 OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
22 ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
23 OTHER DEALINGS IN THE SOFTWARE.
24
25 Except as contained in this notice, the name of the X Consortium shall
26 not be used in advertising or otherwise to promote the sale, use or
27 other dealings in this Software without prior written authorization
28 from the X Consortium.
29
30 */
31
32
33 #include "scrnintstr.h"
34 #include "gcstruct.h"
35 #include "pixmapstr.h"
36 #include "windowstr.h"
37 #include "migc.h"
38
39 /* This structure has to line up with the mfb and cfb gc private structures so
40  * that when it is superimposed on them, the three fields that migc.c needs to
41  * see will be accessed correctly.  I know this is not beautiful, but it seemed
42  * better than all the code duplication in cfb and mfb.
43  */
44 typedef struct {
45     unsigned char       pad1;
46     unsigned char       pad2;
47     unsigned char       pad3;
48     unsigned            pad4:1;
49     unsigned            freeCompClip:1;
50     PixmapPtr           pRotatedPixmap;
51     RegionPtr           pCompositeClip;
52 } miPrivGC;
53
54 static int miGCPrivateIndex;
55
56 void
57 miRegisterGCPrivateIndex(gcindex)
58     int gcindex;
59 {
60     miGCPrivateIndex = gcindex;
61 }
62
63 /* ARGSUSED */
64 void
65 miChangeGC(pGC, mask)
66     GCPtr           pGC;
67     unsigned long   mask;
68 {
69     return;
70 }
71
72 void
73 miDestroyGC(pGC)
74     GCPtr           pGC;
75 {
76     miPrivGC       *pPriv;
77
78     pPriv = (miPrivGC *) (pGC->devPrivates[miGCPrivateIndex].ptr);
79     if (pPriv->pRotatedPixmap)
80         (*pGC->pScreen->DestroyPixmap) (pPriv->pRotatedPixmap);
81     if (pPriv->freeCompClip)
82         REGION_DESTROY(pGC->pScreen, pPriv->pCompositeClip);
83     miDestroyGCOps(pGC->ops);
84 }
85
86 /*
87  * create a private op array for a gc
88  */
89
90 GCOpsPtr
91 miCreateGCOps(prototype)
92     GCOpsPtr        prototype;
93 {
94     GCOpsPtr        ret;
95     extern Bool     Must_have_memory;
96
97      /* XXX */ Must_have_memory = TRUE;
98     ret = (GCOpsPtr) xalloc(sizeof(GCOps));
99      /* XXX */ Must_have_memory = FALSE;
100     if (!ret)
101         return 0;
102     *ret = *prototype;
103     ret->devPrivate.val = 1;
104     return ret;
105 }
106
107 void
108 miDestroyGCOps(ops)
109     GCOpsPtr        ops;
110 {
111     if (ops->devPrivate.val)
112         xfree(ops);
113 }
114
115
116 void
117 miDestroyClip(pGC)
118     GCPtr           pGC;
119 {
120     if (pGC->clientClipType == CT_NONE)
121         return;
122     else if (pGC->clientClipType == CT_PIXMAP)
123     {
124         (*pGC->pScreen->DestroyPixmap) ((PixmapPtr) (pGC->clientClip));
125     }
126     else
127     {
128         /*
129          * we know we'll never have a list of rectangles, since ChangeClip
130          * immediately turns them into a region
131          */
132         REGION_DESTROY(pGC->pScreen, pGC->clientClip);
133     }
134     pGC->clientClip = NULL;
135     pGC->clientClipType = CT_NONE;
136 }
137
138 void
139 miChangeClip(pGC, type, pvalue, nrects)
140     GCPtr           pGC;
141     int             type;
142     pointer         pvalue;
143     int             nrects;
144 {
145     (*pGC->funcs->DestroyClip) (pGC);
146     if (type == CT_PIXMAP)
147     {
148         /* convert the pixmap to a region */
149         pGC->clientClip = (pointer) BITMAP_TO_REGION(pGC->pScreen,
150                                                         (PixmapPtr) pvalue);
151         (*pGC->pScreen->DestroyPixmap) (pvalue);
152     }
153     else if (type == CT_REGION)
154     {
155         /* stuff the region in the GC */
156         pGC->clientClip = pvalue;
157     }
158     else if (type != CT_NONE)
159     {
160         pGC->clientClip = (pointer) RECTS_TO_REGION(pGC->pScreen, nrects,
161                                                       (xRectangle *) pvalue,
162                                                                     type);
163         xfree(pvalue);
164     }
165     pGC->clientClipType = (type != CT_NONE && pGC->clientClip) ? CT_REGION : CT_NONE;
166     pGC->stateChanges |= GCClipMask;
167 }
168
169 void
170 miCopyClip(pgcDst, pgcSrc)
171     GCPtr           pgcDst, pgcSrc;
172 {
173     RegionPtr       prgnNew;
174
175     switch (pgcSrc->clientClipType)
176     {
177       case CT_PIXMAP:
178         ((PixmapPtr) pgcSrc->clientClip)->refcnt++;
179         /* Fall through !! */
180       case CT_NONE:
181         (*pgcDst->funcs->ChangeClip) (pgcDst, (int) pgcSrc->clientClipType,
182                                    pgcSrc->clientClip, 0);
183         break;
184       case CT_REGION:
185         prgnNew = REGION_CREATE(pgcSrc->pScreen, NULL, 1);
186         REGION_COPY(pgcDst->pScreen, prgnNew,
187                                         (RegionPtr) (pgcSrc->clientClip));
188         (*pgcDst->funcs->ChangeClip) (pgcDst, CT_REGION, (pointer) prgnNew, 0);
189         break;
190     }
191 }
192
193 /* ARGSUSED */
194 void
195 miCopyGC(pGCSrc, changes, pGCDst)
196     GCPtr           pGCSrc;
197     unsigned long   changes;
198     GCPtr           pGCDst;
199 {
200     return;
201 }
202
203 void
204 miComputeCompositeClip(pGC, pDrawable)
205     GCPtr           pGC;
206     DrawablePtr     pDrawable;
207 {
208     ScreenPtr       pScreen = pGC->pScreen;
209     miPrivGC *devPriv = (miPrivGC *) (pGC->devPrivates[miGCPrivateIndex].ptr);
210
211     if (pDrawable->type == DRAWABLE_WINDOW)
212     {
213         WindowPtr       pWin = (WindowPtr) pDrawable;
214         RegionPtr       pregWin;
215         Bool            freeTmpClip, freeCompClip;
216
217         if (pGC->subWindowMode == IncludeInferiors)
218         {
219             pregWin = NotClippedByChildren(pWin);
220             freeTmpClip = TRUE;
221         }
222         else
223         {
224             pregWin = &pWin->clipList;
225             freeTmpClip = FALSE;
226         }
227         freeCompClip = devPriv->freeCompClip;
228
229         /*
230          * if there is no client clip, we can get by with just keeping the
231          * pointer we got, and remembering whether or not should destroy (or
232          * maybe re-use) it later.  this way, we avoid unnecessary copying of
233          * regions.  (this wins especially if many clients clip by children
234          * and have no client clip.)
235          */
236         if (pGC->clientClipType == CT_NONE)
237         {
238             if (freeCompClip)
239                 REGION_DESTROY(pScreen, devPriv->pCompositeClip);
240             devPriv->pCompositeClip = pregWin;
241             devPriv->freeCompClip = freeTmpClip;
242         }
243         else
244         {
245             /*
246              * we need one 'real' region to put into the composite clip. if
247              * pregWin the current composite clip are real, we can get rid of
248              * one. if pregWin is real and the current composite clip isn't,
249              * use pregWin for the composite clip. if the current composite
250              * clip is real and pregWin isn't, use the current composite
251              * clip. if neither is real, create a new region.
252              */
253
254             REGION_TRANSLATE(pScreen, pGC->clientClip,
255                                          pDrawable->x + pGC->clipOrg.x,
256                                          pDrawable->y + pGC->clipOrg.y);
257
258             if (freeCompClip)
259             {
260                 REGION_INTERSECT(pGC->pScreen, devPriv->pCompositeClip,
261                                             pregWin, pGC->clientClip);
262                 if (freeTmpClip)
263                     REGION_DESTROY(pScreen, pregWin);
264             }
265             else if (freeTmpClip)
266             {
267                 REGION_INTERSECT(pScreen, pregWin, pregWin, pGC->clientClip);
268                 devPriv->pCompositeClip = pregWin;
269             }
270             else
271             {
272                 devPriv->pCompositeClip = REGION_CREATE(pScreen, NullBox, 0);
273                 REGION_INTERSECT(pScreen, devPriv->pCompositeClip,
274                                        pregWin, pGC->clientClip);
275             }
276             devPriv->freeCompClip = TRUE;
277             REGION_TRANSLATE(pScreen, pGC->clientClip,
278                                          -(pDrawable->x + pGC->clipOrg.x),
279                                          -(pDrawable->y + pGC->clipOrg.y));
280         }
281     }   /* end of composite clip for a window */
282     else
283     {
284         BoxRec          pixbounds;
285
286         /* XXX should we translate by drawable.x/y here ? */
287         pixbounds.x1 = 0;
288         pixbounds.y1 = 0;
289         pixbounds.x2 = pDrawable->width;
290         pixbounds.y2 = pDrawable->height;
291
292         if (devPriv->freeCompClip)
293         {
294             REGION_RESET(pScreen, devPriv->pCompositeClip, &pixbounds);
295         }
296         else
297         {
298             devPriv->freeCompClip = TRUE;
299             devPriv->pCompositeClip = REGION_CREATE(pScreen, &pixbounds, 1);
300         }
301
302         if (pGC->clientClipType == CT_REGION)
303         {
304             REGION_TRANSLATE(pScreen, devPriv->pCompositeClip,
305                                          -pGC->clipOrg.x, -pGC->clipOrg.y);
306             REGION_INTERSECT(pScreen, devPriv->pCompositeClip,
307                                 devPriv->pCompositeClip, pGC->clientClip);
308             REGION_TRANSLATE(pScreen, devPriv->pCompositeClip,
309                                          pGC->clipOrg.x, pGC->clipOrg.y);
310         }
311     }   /* end of composite clip for pixmap */
312 } /* end miComputeCompositeClip */