1*4882a593Smuzhiyun /*
2*4882a593Smuzhiyun
3*4882a593Smuzhiyun Copyright 1993, 1998 The Open Group
4*4882a593Smuzhiyun
5*4882a593Smuzhiyun Permission to use, copy, modify, distribute, and sell this software and its
6*4882a593Smuzhiyun documentation for any purpose is hereby granted without fee, provided that
7*4882a593Smuzhiyun the above copyright notice appear in all copies and that both that
8*4882a593Smuzhiyun copyright notice and this permission notice appear in supporting
9*4882a593Smuzhiyun documentation.
10*4882a593Smuzhiyun
11*4882a593Smuzhiyun The above copyright notice and this permission notice shall be included
12*4882a593Smuzhiyun in all copies or substantial portions of the Software.
13*4882a593Smuzhiyun
14*4882a593Smuzhiyun THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
15*4882a593Smuzhiyun OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
16*4882a593Smuzhiyun MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
17*4882a593Smuzhiyun IN NO EVENT SHALL THE OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR
18*4882a593Smuzhiyun OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
19*4882a593Smuzhiyun ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
20*4882a593Smuzhiyun OTHER DEALINGS IN THE SOFTWARE.
21*4882a593Smuzhiyun
22*4882a593Smuzhiyun Except as contained in this notice, the name of The Open Group shall
23*4882a593Smuzhiyun not be used in advertising or otherwise to promote the sale, use or
24*4882a593Smuzhiyun other dealings in this Software without prior written authorization
25*4882a593Smuzhiyun from The Open Group.
26*4882a593Smuzhiyun
27*4882a593Smuzhiyun */
28*4882a593Smuzhiyun
29*4882a593Smuzhiyun #ifdef HAVE_DIX_CONFIG_H
30*4882a593Smuzhiyun #include <dix-config.h>
31*4882a593Smuzhiyun #endif
32*4882a593Smuzhiyun
33*4882a593Smuzhiyun #include <X11/X.h>
34*4882a593Smuzhiyun #include "scrnintstr.h"
35*4882a593Smuzhiyun #include "mi.h"
36*4882a593Smuzhiyun #include "misc.h"
37*4882a593Smuzhiyun #include "os.h"
38*4882a593Smuzhiyun #include "windowstr.h"
39*4882a593Smuzhiyun #include "resource.h"
40*4882a593Smuzhiyun #include "dixstruct.h"
41*4882a593Smuzhiyun #include "gcstruct.h"
42*4882a593Smuzhiyun #include "servermd.h"
43*4882a593Smuzhiyun #include "site.h"
44*4882a593Smuzhiyun #include "X11/extensions/render.h"
45*4882a593Smuzhiyun #include "picturestr.h"
46*4882a593Smuzhiyun #include "randrstr.h"
47*4882a593Smuzhiyun /*
48*4882a593Smuzhiyun * Scratch pixmap management and device independent pixmap allocation
49*4882a593Smuzhiyun * function.
50*4882a593Smuzhiyun */
51*4882a593Smuzhiyun
52*4882a593Smuzhiyun /* callable by ddx */
53*4882a593Smuzhiyun PixmapPtr
GetScratchPixmapHeader(ScreenPtr pScreen,int width,int height,int depth,int bitsPerPixel,int devKind,void * pPixData)54*4882a593Smuzhiyun GetScratchPixmapHeader(ScreenPtr pScreen, int width, int height, int depth,
55*4882a593Smuzhiyun int bitsPerPixel, int devKind, void *pPixData)
56*4882a593Smuzhiyun {
57*4882a593Smuzhiyun PixmapPtr pPixmap = pScreen->pScratchPixmap;
58*4882a593Smuzhiyun
59*4882a593Smuzhiyun if (pPixmap)
60*4882a593Smuzhiyun pScreen->pScratchPixmap = NULL;
61*4882a593Smuzhiyun else
62*4882a593Smuzhiyun /* width and height of 0 means don't allocate any pixmap data */
63*4882a593Smuzhiyun pPixmap = (*pScreen->CreatePixmap) (pScreen, 0, 0, depth, 0);
64*4882a593Smuzhiyun
65*4882a593Smuzhiyun if (pPixmap) {
66*4882a593Smuzhiyun if ((*pScreen->ModifyPixmapHeader) (pPixmap, width, height, depth,
67*4882a593Smuzhiyun bitsPerPixel, devKind, pPixData))
68*4882a593Smuzhiyun return pPixmap;
69*4882a593Smuzhiyun (*pScreen->DestroyPixmap) (pPixmap);
70*4882a593Smuzhiyun }
71*4882a593Smuzhiyun return NullPixmap;
72*4882a593Smuzhiyun }
73*4882a593Smuzhiyun
74*4882a593Smuzhiyun /* callable by ddx */
75*4882a593Smuzhiyun void
FreeScratchPixmapHeader(PixmapPtr pPixmap)76*4882a593Smuzhiyun FreeScratchPixmapHeader(PixmapPtr pPixmap)
77*4882a593Smuzhiyun {
78*4882a593Smuzhiyun if (pPixmap) {
79*4882a593Smuzhiyun ScreenPtr pScreen = pPixmap->drawable.pScreen;
80*4882a593Smuzhiyun
81*4882a593Smuzhiyun pPixmap->devPrivate.ptr = NULL; /* lest ddx chases bad ptr */
82*4882a593Smuzhiyun if (pScreen->pScratchPixmap)
83*4882a593Smuzhiyun (*pScreen->DestroyPixmap) (pPixmap);
84*4882a593Smuzhiyun else
85*4882a593Smuzhiyun pScreen->pScratchPixmap = pPixmap;
86*4882a593Smuzhiyun }
87*4882a593Smuzhiyun }
88*4882a593Smuzhiyun
89*4882a593Smuzhiyun Bool
CreateScratchPixmapsForScreen(ScreenPtr pScreen)90*4882a593Smuzhiyun CreateScratchPixmapsForScreen(ScreenPtr pScreen)
91*4882a593Smuzhiyun {
92*4882a593Smuzhiyun unsigned int pixmap_size;
93*4882a593Smuzhiyun
94*4882a593Smuzhiyun pixmap_size = sizeof(PixmapRec) + dixScreenSpecificPrivatesSize(pScreen, PRIVATE_PIXMAP);
95*4882a593Smuzhiyun pScreen->totalPixmapSize =
96*4882a593Smuzhiyun BitmapBytePad(pixmap_size * 8);
97*4882a593Smuzhiyun
98*4882a593Smuzhiyun /* let it be created on first use */
99*4882a593Smuzhiyun pScreen->pScratchPixmap = NULL;
100*4882a593Smuzhiyun return TRUE;
101*4882a593Smuzhiyun }
102*4882a593Smuzhiyun
103*4882a593Smuzhiyun void
FreeScratchPixmapsForScreen(ScreenPtr pScreen)104*4882a593Smuzhiyun FreeScratchPixmapsForScreen(ScreenPtr pScreen)
105*4882a593Smuzhiyun {
106*4882a593Smuzhiyun FreeScratchPixmapHeader(pScreen->pScratchPixmap);
107*4882a593Smuzhiyun }
108*4882a593Smuzhiyun
109*4882a593Smuzhiyun /* callable by ddx */
110*4882a593Smuzhiyun PixmapPtr
AllocatePixmap(ScreenPtr pScreen,int pixDataSize)111*4882a593Smuzhiyun AllocatePixmap(ScreenPtr pScreen, int pixDataSize)
112*4882a593Smuzhiyun {
113*4882a593Smuzhiyun PixmapPtr pPixmap;
114*4882a593Smuzhiyun
115*4882a593Smuzhiyun assert(pScreen->totalPixmapSize > 0);
116*4882a593Smuzhiyun
117*4882a593Smuzhiyun if (pScreen->totalPixmapSize > ((size_t) - 1) - pixDataSize)
118*4882a593Smuzhiyun return NullPixmap;
119*4882a593Smuzhiyun
120*4882a593Smuzhiyun pPixmap = calloc(1, pScreen->totalPixmapSize + pixDataSize);
121*4882a593Smuzhiyun if (!pPixmap)
122*4882a593Smuzhiyun return NullPixmap;
123*4882a593Smuzhiyun
124*4882a593Smuzhiyun dixInitScreenPrivates(pScreen, pPixmap, pPixmap + 1, PRIVATE_PIXMAP);
125*4882a593Smuzhiyun return pPixmap;
126*4882a593Smuzhiyun }
127*4882a593Smuzhiyun
128*4882a593Smuzhiyun /* callable by ddx */
129*4882a593Smuzhiyun void
FreePixmap(PixmapPtr pPixmap)130*4882a593Smuzhiyun FreePixmap(PixmapPtr pPixmap)
131*4882a593Smuzhiyun {
132*4882a593Smuzhiyun dixFiniPrivates(pPixmap, PRIVATE_PIXMAP);
133*4882a593Smuzhiyun free(pPixmap);
134*4882a593Smuzhiyun }
135*4882a593Smuzhiyun
PixmapUnshareSlavePixmap(PixmapPtr slave_pixmap)136*4882a593Smuzhiyun void PixmapUnshareSlavePixmap(PixmapPtr slave_pixmap)
137*4882a593Smuzhiyun {
138*4882a593Smuzhiyun int ihandle = -1;
139*4882a593Smuzhiyun ScreenPtr pScreen = slave_pixmap->drawable.pScreen;
140*4882a593Smuzhiyun pScreen->SetSharedPixmapBacking(slave_pixmap, ((void *)(long)ihandle));
141*4882a593Smuzhiyun }
142*4882a593Smuzhiyun
PixmapShareToSlave(PixmapPtr pixmap,ScreenPtr slave)143*4882a593Smuzhiyun PixmapPtr PixmapShareToSlave(PixmapPtr pixmap, ScreenPtr slave)
144*4882a593Smuzhiyun {
145*4882a593Smuzhiyun PixmapPtr spix;
146*4882a593Smuzhiyun int ret;
147*4882a593Smuzhiyun void *handle;
148*4882a593Smuzhiyun ScreenPtr master = pixmap->drawable.pScreen;
149*4882a593Smuzhiyun int depth = pixmap->drawable.depth;
150*4882a593Smuzhiyun
151*4882a593Smuzhiyun ret = master->SharePixmapBacking(pixmap, slave, &handle);
152*4882a593Smuzhiyun if (ret == FALSE)
153*4882a593Smuzhiyun return NULL;
154*4882a593Smuzhiyun
155*4882a593Smuzhiyun spix = slave->CreatePixmap(slave, 0, 0, depth,
156*4882a593Smuzhiyun CREATE_PIXMAP_USAGE_SHARED);
157*4882a593Smuzhiyun slave->ModifyPixmapHeader(spix, pixmap->drawable.width,
158*4882a593Smuzhiyun pixmap->drawable.height, depth, 0,
159*4882a593Smuzhiyun pixmap->devKind, NULL);
160*4882a593Smuzhiyun
161*4882a593Smuzhiyun /* have the slave pixmap take a reference on the master pixmap
162*4882a593Smuzhiyun later we destroy them both at the same time */
163*4882a593Smuzhiyun pixmap->refcnt++;
164*4882a593Smuzhiyun
165*4882a593Smuzhiyun spix->master_pixmap = pixmap;
166*4882a593Smuzhiyun
167*4882a593Smuzhiyun ret = slave->SetSharedPixmapBacking(spix, handle);
168*4882a593Smuzhiyun if (ret == FALSE) {
169*4882a593Smuzhiyun slave->DestroyPixmap(spix);
170*4882a593Smuzhiyun return NULL;
171*4882a593Smuzhiyun }
172*4882a593Smuzhiyun
173*4882a593Smuzhiyun return spix;
174*4882a593Smuzhiyun }
175*4882a593Smuzhiyun
176*4882a593Smuzhiyun static void
PixmapDirtyDamageDestroy(DamagePtr damage,void * closure)177*4882a593Smuzhiyun PixmapDirtyDamageDestroy(DamagePtr damage, void *closure)
178*4882a593Smuzhiyun {
179*4882a593Smuzhiyun PixmapDirtyUpdatePtr dirty = closure;
180*4882a593Smuzhiyun
181*4882a593Smuzhiyun dirty->damage = NULL;
182*4882a593Smuzhiyun }
183*4882a593Smuzhiyun
184*4882a593Smuzhiyun Bool
PixmapStartDirtyTracking(DrawablePtr src,PixmapPtr slave_dst,int x,int y,int dst_x,int dst_y,Rotation rotation)185*4882a593Smuzhiyun PixmapStartDirtyTracking(DrawablePtr src,
186*4882a593Smuzhiyun PixmapPtr slave_dst,
187*4882a593Smuzhiyun int x, int y, int dst_x, int dst_y,
188*4882a593Smuzhiyun Rotation rotation)
189*4882a593Smuzhiyun {
190*4882a593Smuzhiyun ScreenPtr screen = src->pScreen;
191*4882a593Smuzhiyun PixmapDirtyUpdatePtr dirty_update;
192*4882a593Smuzhiyun RegionPtr damageregion;
193*4882a593Smuzhiyun RegionRec dstregion;
194*4882a593Smuzhiyun BoxRec box;
195*4882a593Smuzhiyun
196*4882a593Smuzhiyun dirty_update = calloc(1, sizeof(PixmapDirtyUpdateRec));
197*4882a593Smuzhiyun if (!dirty_update)
198*4882a593Smuzhiyun return FALSE;
199*4882a593Smuzhiyun
200*4882a593Smuzhiyun dirty_update->src = src;
201*4882a593Smuzhiyun dirty_update->slave_dst = slave_dst;
202*4882a593Smuzhiyun dirty_update->x = x;
203*4882a593Smuzhiyun dirty_update->y = y;
204*4882a593Smuzhiyun dirty_update->dst_x = dst_x;
205*4882a593Smuzhiyun dirty_update->dst_y = dst_y;
206*4882a593Smuzhiyun dirty_update->rotation = rotation;
207*4882a593Smuzhiyun dirty_update->damage = DamageCreate(NULL, PixmapDirtyDamageDestroy,
208*4882a593Smuzhiyun DamageReportNone, TRUE, screen,
209*4882a593Smuzhiyun dirty_update);
210*4882a593Smuzhiyun
211*4882a593Smuzhiyun if (rotation != RR_Rotate_0) {
212*4882a593Smuzhiyun RRTransformCompute(x, y,
213*4882a593Smuzhiyun slave_dst->drawable.width,
214*4882a593Smuzhiyun slave_dst->drawable.height,
215*4882a593Smuzhiyun rotation,
216*4882a593Smuzhiyun NULL,
217*4882a593Smuzhiyun &dirty_update->transform,
218*4882a593Smuzhiyun &dirty_update->f_transform,
219*4882a593Smuzhiyun &dirty_update->f_inverse);
220*4882a593Smuzhiyun }
221*4882a593Smuzhiyun if (!dirty_update->damage) {
222*4882a593Smuzhiyun free(dirty_update);
223*4882a593Smuzhiyun return FALSE;
224*4882a593Smuzhiyun }
225*4882a593Smuzhiyun
226*4882a593Smuzhiyun /* Damage destination rectangle so that the destination pixmap contents
227*4882a593Smuzhiyun * will get fully initialized
228*4882a593Smuzhiyun */
229*4882a593Smuzhiyun box.x1 = dirty_update->x;
230*4882a593Smuzhiyun box.y1 = dirty_update->y;
231*4882a593Smuzhiyun if (dirty_update->rotation == RR_Rotate_90 ||
232*4882a593Smuzhiyun dirty_update->rotation == RR_Rotate_270) {
233*4882a593Smuzhiyun box.x2 = dirty_update->x + slave_dst->drawable.height;
234*4882a593Smuzhiyun box.y2 = dirty_update->y + slave_dst->drawable.width;
235*4882a593Smuzhiyun } else {
236*4882a593Smuzhiyun box.x2 = dirty_update->x + slave_dst->drawable.width;
237*4882a593Smuzhiyun box.y2 = dirty_update->y + slave_dst->drawable.height;
238*4882a593Smuzhiyun }
239*4882a593Smuzhiyun RegionInit(&dstregion, &box, 1);
240*4882a593Smuzhiyun damageregion = DamageRegion(dirty_update->damage);
241*4882a593Smuzhiyun RegionUnion(damageregion, damageregion, &dstregion);
242*4882a593Smuzhiyun RegionUninit(&dstregion);
243*4882a593Smuzhiyun
244*4882a593Smuzhiyun DamageRegister(src, dirty_update->damage);
245*4882a593Smuzhiyun xorg_list_add(&dirty_update->ent, &screen->pixmap_dirty_list);
246*4882a593Smuzhiyun return TRUE;
247*4882a593Smuzhiyun }
248*4882a593Smuzhiyun
249*4882a593Smuzhiyun Bool
PixmapStopDirtyTracking(DrawablePtr src,PixmapPtr slave_dst)250*4882a593Smuzhiyun PixmapStopDirtyTracking(DrawablePtr src, PixmapPtr slave_dst)
251*4882a593Smuzhiyun {
252*4882a593Smuzhiyun ScreenPtr screen = src->pScreen;
253*4882a593Smuzhiyun PixmapDirtyUpdatePtr ent, safe;
254*4882a593Smuzhiyun
255*4882a593Smuzhiyun xorg_list_for_each_entry_safe(ent, safe, &screen->pixmap_dirty_list, ent) {
256*4882a593Smuzhiyun if (ent->src == src && ent->slave_dst == slave_dst) {
257*4882a593Smuzhiyun if (ent->damage)
258*4882a593Smuzhiyun DamageDestroy(ent->damage);
259*4882a593Smuzhiyun xorg_list_del(&ent->ent);
260*4882a593Smuzhiyun free(ent);
261*4882a593Smuzhiyun }
262*4882a593Smuzhiyun }
263*4882a593Smuzhiyun return TRUE;
264*4882a593Smuzhiyun }
265*4882a593Smuzhiyun
266*4882a593Smuzhiyun static void
PixmapDirtyCopyArea(PixmapPtr dst,PixmapDirtyUpdatePtr dirty,RegionPtr dirty_region)267*4882a593Smuzhiyun PixmapDirtyCopyArea(PixmapPtr dst,
268*4882a593Smuzhiyun PixmapDirtyUpdatePtr dirty,
269*4882a593Smuzhiyun RegionPtr dirty_region)
270*4882a593Smuzhiyun {
271*4882a593Smuzhiyun DrawablePtr src = dirty->src;
272*4882a593Smuzhiyun ScreenPtr pScreen = src->pScreen;
273*4882a593Smuzhiyun int n;
274*4882a593Smuzhiyun BoxPtr b;
275*4882a593Smuzhiyun GCPtr pGC;
276*4882a593Smuzhiyun
277*4882a593Smuzhiyun n = RegionNumRects(dirty_region);
278*4882a593Smuzhiyun b = RegionRects(dirty_region);
279*4882a593Smuzhiyun
280*4882a593Smuzhiyun pGC = GetScratchGC(src->depth, pScreen);
281*4882a593Smuzhiyun if (pScreen->root) {
282*4882a593Smuzhiyun ChangeGCVal subWindowMode;
283*4882a593Smuzhiyun
284*4882a593Smuzhiyun subWindowMode.val = IncludeInferiors;
285*4882a593Smuzhiyun ChangeGC(NullClient, pGC, GCSubwindowMode, &subWindowMode);
286*4882a593Smuzhiyun }
287*4882a593Smuzhiyun ValidateGC(&dst->drawable, pGC);
288*4882a593Smuzhiyun
289*4882a593Smuzhiyun while (n--) {
290*4882a593Smuzhiyun BoxRec dst_box;
291*4882a593Smuzhiyun int w, h;
292*4882a593Smuzhiyun
293*4882a593Smuzhiyun dst_box = *b;
294*4882a593Smuzhiyun w = dst_box.x2 - dst_box.x1;
295*4882a593Smuzhiyun h = dst_box.y2 - dst_box.y1;
296*4882a593Smuzhiyun
297*4882a593Smuzhiyun pGC->ops->CopyArea(src, &dst->drawable, pGC,
298*4882a593Smuzhiyun dirty->x + dst_box.x1, dirty->y + dst_box.y1, w, h,
299*4882a593Smuzhiyun dirty->dst_x + dst_box.x1,
300*4882a593Smuzhiyun dirty->dst_y + dst_box.y1);
301*4882a593Smuzhiyun b++;
302*4882a593Smuzhiyun }
303*4882a593Smuzhiyun FreeScratchGC(pGC);
304*4882a593Smuzhiyun }
305*4882a593Smuzhiyun
306*4882a593Smuzhiyun static void
PixmapDirtyCompositeRotate(PixmapPtr dst_pixmap,PixmapDirtyUpdatePtr dirty,RegionPtr dirty_region)307*4882a593Smuzhiyun PixmapDirtyCompositeRotate(PixmapPtr dst_pixmap,
308*4882a593Smuzhiyun PixmapDirtyUpdatePtr dirty,
309*4882a593Smuzhiyun RegionPtr dirty_region)
310*4882a593Smuzhiyun {
311*4882a593Smuzhiyun ScreenPtr pScreen = dirty->src->pScreen;
312*4882a593Smuzhiyun PictFormatPtr format = PictureWindowFormat(pScreen->root);
313*4882a593Smuzhiyun PicturePtr src, dst;
314*4882a593Smuzhiyun XID include_inferiors = IncludeInferiors;
315*4882a593Smuzhiyun int n = RegionNumRects(dirty_region);
316*4882a593Smuzhiyun BoxPtr b = RegionRects(dirty_region);
317*4882a593Smuzhiyun int error;
318*4882a593Smuzhiyun
319*4882a593Smuzhiyun src = CreatePicture(None,
320*4882a593Smuzhiyun dirty->src,
321*4882a593Smuzhiyun format,
322*4882a593Smuzhiyun CPSubwindowMode,
323*4882a593Smuzhiyun &include_inferiors, serverClient, &error);
324*4882a593Smuzhiyun if (!src)
325*4882a593Smuzhiyun return;
326*4882a593Smuzhiyun
327*4882a593Smuzhiyun dst = CreatePicture(None,
328*4882a593Smuzhiyun &dst_pixmap->drawable,
329*4882a593Smuzhiyun format, 0L, NULL, serverClient, &error);
330*4882a593Smuzhiyun if (!dst)
331*4882a593Smuzhiyun return;
332*4882a593Smuzhiyun
333*4882a593Smuzhiyun error = SetPictureTransform(src, &dirty->transform);
334*4882a593Smuzhiyun if (error)
335*4882a593Smuzhiyun return;
336*4882a593Smuzhiyun while (n--) {
337*4882a593Smuzhiyun BoxRec dst_box;
338*4882a593Smuzhiyun
339*4882a593Smuzhiyun dst_box = *b;
340*4882a593Smuzhiyun dst_box.x1 += dirty->x;
341*4882a593Smuzhiyun dst_box.x2 += dirty->x;
342*4882a593Smuzhiyun dst_box.y1 += dirty->y;
343*4882a593Smuzhiyun dst_box.y2 += dirty->y;
344*4882a593Smuzhiyun pixman_f_transform_bounds(&dirty->f_inverse, &dst_box);
345*4882a593Smuzhiyun
346*4882a593Smuzhiyun CompositePicture(PictOpSrc,
347*4882a593Smuzhiyun src, NULL, dst,
348*4882a593Smuzhiyun dst_box.x1,
349*4882a593Smuzhiyun dst_box.y1,
350*4882a593Smuzhiyun 0, 0,
351*4882a593Smuzhiyun dst_box.x1,
352*4882a593Smuzhiyun dst_box.y1,
353*4882a593Smuzhiyun dst_box.x2 - dst_box.x1,
354*4882a593Smuzhiyun dst_box.y2 - dst_box.y1);
355*4882a593Smuzhiyun b++;
356*4882a593Smuzhiyun }
357*4882a593Smuzhiyun
358*4882a593Smuzhiyun FreePicture(src, None);
359*4882a593Smuzhiyun FreePicture(dst, None);
360*4882a593Smuzhiyun }
361*4882a593Smuzhiyun
362*4882a593Smuzhiyun /*
363*4882a593Smuzhiyun * this function can possibly be improved and optimised, by clipping
364*4882a593Smuzhiyun * instead of iterating
365*4882a593Smuzhiyun * Drivers are free to implement their own version of this.
366*4882a593Smuzhiyun */
PixmapSyncDirtyHelper(PixmapDirtyUpdatePtr dirty)367*4882a593Smuzhiyun Bool PixmapSyncDirtyHelper(PixmapDirtyUpdatePtr dirty)
368*4882a593Smuzhiyun {
369*4882a593Smuzhiyun ScreenPtr pScreen = dirty->src->pScreen;
370*4882a593Smuzhiyun RegionPtr region = DamageRegion(dirty->damage);
371*4882a593Smuzhiyun PixmapPtr dst;
372*4882a593Smuzhiyun SourceValidateProcPtr SourceValidate;
373*4882a593Smuzhiyun RegionRec pixregion;
374*4882a593Smuzhiyun BoxRec box;
375*4882a593Smuzhiyun
376*4882a593Smuzhiyun dst = dirty->slave_dst->master_pixmap;
377*4882a593Smuzhiyun if (!dst)
378*4882a593Smuzhiyun dst = dirty->slave_dst;
379*4882a593Smuzhiyun
380*4882a593Smuzhiyun box.x1 = 0;
381*4882a593Smuzhiyun box.y1 = 0;
382*4882a593Smuzhiyun if (dirty->rotation == RR_Rotate_90 ||
383*4882a593Smuzhiyun dirty->rotation == RR_Rotate_270) {
384*4882a593Smuzhiyun box.x2 = dst->drawable.height;
385*4882a593Smuzhiyun box.y2 = dst->drawable.width;
386*4882a593Smuzhiyun } else {
387*4882a593Smuzhiyun box.x2 = dst->drawable.width;
388*4882a593Smuzhiyun box.y2 = dst->drawable.height;
389*4882a593Smuzhiyun }
390*4882a593Smuzhiyun RegionInit(&pixregion, &box, 1);
391*4882a593Smuzhiyun
392*4882a593Smuzhiyun /*
393*4882a593Smuzhiyun * SourceValidate is used by the software cursor code
394*4882a593Smuzhiyun * to pull the cursor off of the screen when reading
395*4882a593Smuzhiyun * bits from the frame buffer. Bypassing this function
396*4882a593Smuzhiyun * leaves the software cursor in place
397*4882a593Smuzhiyun */
398*4882a593Smuzhiyun SourceValidate = pScreen->SourceValidate;
399*4882a593Smuzhiyun pScreen->SourceValidate = miSourceValidate;
400*4882a593Smuzhiyun
401*4882a593Smuzhiyun RegionTranslate(&pixregion, dirty->x, dirty->y);
402*4882a593Smuzhiyun RegionIntersect(&pixregion, &pixregion, region);
403*4882a593Smuzhiyun
404*4882a593Smuzhiyun if (RegionNil(&pixregion)) {
405*4882a593Smuzhiyun RegionUninit(&pixregion);
406*4882a593Smuzhiyun return FALSE;
407*4882a593Smuzhiyun }
408*4882a593Smuzhiyun
409*4882a593Smuzhiyun RegionTranslate(&pixregion, -dirty->x, -dirty->y);
410*4882a593Smuzhiyun
411*4882a593Smuzhiyun if (!pScreen->root || dirty->rotation == RR_Rotate_0)
412*4882a593Smuzhiyun PixmapDirtyCopyArea(dst, dirty, &pixregion);
413*4882a593Smuzhiyun else
414*4882a593Smuzhiyun PixmapDirtyCompositeRotate(dst, dirty, &pixregion);
415*4882a593Smuzhiyun pScreen->SourceValidate = SourceValidate;
416*4882a593Smuzhiyun return TRUE;
417*4882a593Smuzhiyun }
418