xref: /OK3568_Linux_fs/external/xserver/damageext/damageext.c (revision 4882a59341e53eb6f0b4789bf948001014eff981)
1*4882a593Smuzhiyun /*
2*4882a593Smuzhiyun  * Copyright © 2002 Keith Packard
3*4882a593Smuzhiyun  * Copyright 2013 Red Hat, Inc.
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, and that the name of Keith Packard not be used in
10*4882a593Smuzhiyun  * advertising or publicity pertaining to distribution of the software without
11*4882a593Smuzhiyun  * specific, written prior permission.  Keith Packard makes no
12*4882a593Smuzhiyun  * representations about the suitability of this software for any purpose.  It
13*4882a593Smuzhiyun  * is provided "as is" without express or implied warranty.
14*4882a593Smuzhiyun  *
15*4882a593Smuzhiyun  * KEITH PACKARD DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
16*4882a593Smuzhiyun  * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
17*4882a593Smuzhiyun  * EVENT SHALL KEITH PACKARD BE LIABLE FOR ANY SPECIAL, INDIRECT OR
18*4882a593Smuzhiyun  * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
19*4882a593Smuzhiyun  * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
20*4882a593Smuzhiyun  * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
21*4882a593Smuzhiyun  * PERFORMANCE OF THIS SOFTWARE.
22*4882a593Smuzhiyun  */
23*4882a593Smuzhiyun 
24*4882a593Smuzhiyun #ifdef HAVE_DIX_CONFIG_H
25*4882a593Smuzhiyun #include <dix-config.h>
26*4882a593Smuzhiyun #endif
27*4882a593Smuzhiyun 
28*4882a593Smuzhiyun #include "damageextint.h"
29*4882a593Smuzhiyun #include "damagestr.h"
30*4882a593Smuzhiyun #include "protocol-versions.h"
31*4882a593Smuzhiyun #include "extinit.h"
32*4882a593Smuzhiyun 
33*4882a593Smuzhiyun #ifdef PANORAMIX
34*4882a593Smuzhiyun #include "panoramiX.h"
35*4882a593Smuzhiyun #include "panoramiXsrv.h"
36*4882a593Smuzhiyun 
37*4882a593Smuzhiyun typedef struct {
38*4882a593Smuzhiyun     DamageExtPtr ext;
39*4882a593Smuzhiyun     DamagePtr damage[MAXSCREENS];
40*4882a593Smuzhiyun } PanoramiXDamageRes;
41*4882a593Smuzhiyun 
42*4882a593Smuzhiyun static RESTYPE XRT_DAMAGE;
43*4882a593Smuzhiyun static int (*PanoramiXSaveDamageCreate) (ClientPtr);
44*4882a593Smuzhiyun 
45*4882a593Smuzhiyun #endif
46*4882a593Smuzhiyun 
47*4882a593Smuzhiyun static unsigned char DamageReqCode;
48*4882a593Smuzhiyun static int DamageEventBase;
49*4882a593Smuzhiyun static RESTYPE DamageExtType;
50*4882a593Smuzhiyun 
51*4882a593Smuzhiyun static DevPrivateKeyRec DamageClientPrivateKeyRec;
52*4882a593Smuzhiyun 
53*4882a593Smuzhiyun #define DamageClientPrivateKey (&DamageClientPrivateKeyRec)
54*4882a593Smuzhiyun 
55*4882a593Smuzhiyun static void
DamageNoteCritical(ClientPtr pClient)56*4882a593Smuzhiyun DamageNoteCritical(ClientPtr pClient)
57*4882a593Smuzhiyun {
58*4882a593Smuzhiyun     DamageClientPtr pDamageClient = GetDamageClient(pClient);
59*4882a593Smuzhiyun 
60*4882a593Smuzhiyun     /* Composite extension marks clients with manual Subwindows as critical */
61*4882a593Smuzhiyun     if (pDamageClient->critical > 0) {
62*4882a593Smuzhiyun         SetCriticalOutputPending();
63*4882a593Smuzhiyun         pClient->smart_priority = SMART_MAX_PRIORITY;
64*4882a593Smuzhiyun     }
65*4882a593Smuzhiyun }
66*4882a593Smuzhiyun 
67*4882a593Smuzhiyun static void
damageGetGeometry(DrawablePtr draw,int * x,int * y,int * w,int * h)68*4882a593Smuzhiyun damageGetGeometry(DrawablePtr draw, int *x, int *y, int *w, int *h)
69*4882a593Smuzhiyun {
70*4882a593Smuzhiyun #ifdef PANORAMIX
71*4882a593Smuzhiyun     if (!noPanoramiXExtension && draw->type == DRAWABLE_WINDOW) {
72*4882a593Smuzhiyun         WindowPtr win = (WindowPtr)draw;
73*4882a593Smuzhiyun 
74*4882a593Smuzhiyun         if (!win->parent) {
75*4882a593Smuzhiyun             *x = screenInfo.x;
76*4882a593Smuzhiyun             *y = screenInfo.y;
77*4882a593Smuzhiyun             *w = screenInfo.width;
78*4882a593Smuzhiyun             *h = screenInfo.height;
79*4882a593Smuzhiyun             return;
80*4882a593Smuzhiyun         }
81*4882a593Smuzhiyun     }
82*4882a593Smuzhiyun #endif
83*4882a593Smuzhiyun 
84*4882a593Smuzhiyun     *x = draw->x;
85*4882a593Smuzhiyun     *y = draw->y;
86*4882a593Smuzhiyun     *w = draw->width;
87*4882a593Smuzhiyun     *h = draw->height;
88*4882a593Smuzhiyun }
89*4882a593Smuzhiyun 
90*4882a593Smuzhiyun static void
DamageExtNotify(DamageExtPtr pDamageExt,BoxPtr pBoxes,int nBoxes)91*4882a593Smuzhiyun DamageExtNotify(DamageExtPtr pDamageExt, BoxPtr pBoxes, int nBoxes)
92*4882a593Smuzhiyun {
93*4882a593Smuzhiyun     ClientPtr pClient = pDamageExt->pClient;
94*4882a593Smuzhiyun     DrawablePtr pDrawable = pDamageExt->pDrawable;
95*4882a593Smuzhiyun     xDamageNotifyEvent ev;
96*4882a593Smuzhiyun     int i, x, y, w, h;
97*4882a593Smuzhiyun 
98*4882a593Smuzhiyun     damageGetGeometry(pDrawable, &x, &y, &w, &h);
99*4882a593Smuzhiyun 
100*4882a593Smuzhiyun     UpdateCurrentTimeIf();
101*4882a593Smuzhiyun     ev = (xDamageNotifyEvent) {
102*4882a593Smuzhiyun         .type = DamageEventBase + XDamageNotify,
103*4882a593Smuzhiyun         .level = pDamageExt->level,
104*4882a593Smuzhiyun         .drawable = pDamageExt->drawable,
105*4882a593Smuzhiyun         .damage = pDamageExt->id,
106*4882a593Smuzhiyun         .timestamp = currentTime.milliseconds,
107*4882a593Smuzhiyun         .geometry.x = x,
108*4882a593Smuzhiyun         .geometry.y = y,
109*4882a593Smuzhiyun         .geometry.width = w,
110*4882a593Smuzhiyun         .geometry.height = h
111*4882a593Smuzhiyun     };
112*4882a593Smuzhiyun     if (pBoxes) {
113*4882a593Smuzhiyun         for (i = 0; i < nBoxes; i++) {
114*4882a593Smuzhiyun             ev.level = pDamageExt->level;
115*4882a593Smuzhiyun             if (i < nBoxes - 1)
116*4882a593Smuzhiyun                 ev.level |= DamageNotifyMore;
117*4882a593Smuzhiyun             ev.area.x = pBoxes[i].x1;
118*4882a593Smuzhiyun             ev.area.y = pBoxes[i].y1;
119*4882a593Smuzhiyun             ev.area.width = pBoxes[i].x2 - pBoxes[i].x1;
120*4882a593Smuzhiyun             ev.area.height = pBoxes[i].y2 - pBoxes[i].y1;
121*4882a593Smuzhiyun             WriteEventsToClient(pClient, 1, (xEvent *) &ev);
122*4882a593Smuzhiyun         }
123*4882a593Smuzhiyun     }
124*4882a593Smuzhiyun     else {
125*4882a593Smuzhiyun         ev.area.x = 0;
126*4882a593Smuzhiyun         ev.area.y = 0;
127*4882a593Smuzhiyun         ev.area.width = w;
128*4882a593Smuzhiyun         ev.area.height = h;
129*4882a593Smuzhiyun         WriteEventsToClient(pClient, 1, (xEvent *) &ev);
130*4882a593Smuzhiyun     }
131*4882a593Smuzhiyun 
132*4882a593Smuzhiyun     DamageNoteCritical(pClient);
133*4882a593Smuzhiyun }
134*4882a593Smuzhiyun 
135*4882a593Smuzhiyun static void
DamageExtReport(DamagePtr pDamage,RegionPtr pRegion,void * closure)136*4882a593Smuzhiyun DamageExtReport(DamagePtr pDamage, RegionPtr pRegion, void *closure)
137*4882a593Smuzhiyun {
138*4882a593Smuzhiyun     DamageExtPtr pDamageExt = closure;
139*4882a593Smuzhiyun 
140*4882a593Smuzhiyun     switch (pDamageExt->level) {
141*4882a593Smuzhiyun     case DamageReportRawRegion:
142*4882a593Smuzhiyun     case DamageReportDeltaRegion:
143*4882a593Smuzhiyun         DamageExtNotify(pDamageExt, RegionRects(pRegion),
144*4882a593Smuzhiyun                         RegionNumRects(pRegion));
145*4882a593Smuzhiyun         break;
146*4882a593Smuzhiyun     case DamageReportBoundingBox:
147*4882a593Smuzhiyun         DamageExtNotify(pDamageExt, RegionExtents(pRegion), 1);
148*4882a593Smuzhiyun         break;
149*4882a593Smuzhiyun     case DamageReportNonEmpty:
150*4882a593Smuzhiyun         DamageExtNotify(pDamageExt, NullBox, 0);
151*4882a593Smuzhiyun         break;
152*4882a593Smuzhiyun     case DamageReportNone:
153*4882a593Smuzhiyun         break;
154*4882a593Smuzhiyun     }
155*4882a593Smuzhiyun }
156*4882a593Smuzhiyun 
157*4882a593Smuzhiyun static void
DamageExtDestroy(DamagePtr pDamage,void * closure)158*4882a593Smuzhiyun DamageExtDestroy(DamagePtr pDamage, void *closure)
159*4882a593Smuzhiyun {
160*4882a593Smuzhiyun     DamageExtPtr pDamageExt = closure;
161*4882a593Smuzhiyun 
162*4882a593Smuzhiyun     pDamageExt->pDamage = 0;
163*4882a593Smuzhiyun     if (pDamageExt->id)
164*4882a593Smuzhiyun         FreeResource(pDamageExt->id, RT_NONE);
165*4882a593Smuzhiyun }
166*4882a593Smuzhiyun 
167*4882a593Smuzhiyun void
DamageExtSetCritical(ClientPtr pClient,Bool critical)168*4882a593Smuzhiyun DamageExtSetCritical(ClientPtr pClient, Bool critical)
169*4882a593Smuzhiyun {
170*4882a593Smuzhiyun     DamageClientPtr pDamageClient = GetDamageClient(pClient);
171*4882a593Smuzhiyun 
172*4882a593Smuzhiyun     if (pDamageClient)
173*4882a593Smuzhiyun         pDamageClient->critical += critical ? 1 : -1;
174*4882a593Smuzhiyun }
175*4882a593Smuzhiyun 
176*4882a593Smuzhiyun static int
ProcDamageQueryVersion(ClientPtr client)177*4882a593Smuzhiyun ProcDamageQueryVersion(ClientPtr client)
178*4882a593Smuzhiyun {
179*4882a593Smuzhiyun     DamageClientPtr pDamageClient = GetDamageClient(client);
180*4882a593Smuzhiyun     xDamageQueryVersionReply rep = {
181*4882a593Smuzhiyun         .type = X_Reply,
182*4882a593Smuzhiyun         .sequenceNumber = client->sequence,
183*4882a593Smuzhiyun         .length = 0
184*4882a593Smuzhiyun     };
185*4882a593Smuzhiyun 
186*4882a593Smuzhiyun     REQUEST(xDamageQueryVersionReq);
187*4882a593Smuzhiyun 
188*4882a593Smuzhiyun     REQUEST_SIZE_MATCH(xDamageQueryVersionReq);
189*4882a593Smuzhiyun 
190*4882a593Smuzhiyun     if (stuff->majorVersion < SERVER_DAMAGE_MAJOR_VERSION) {
191*4882a593Smuzhiyun         rep.majorVersion = stuff->majorVersion;
192*4882a593Smuzhiyun         rep.minorVersion = stuff->minorVersion;
193*4882a593Smuzhiyun     }
194*4882a593Smuzhiyun     else {
195*4882a593Smuzhiyun         rep.majorVersion = SERVER_DAMAGE_MAJOR_VERSION;
196*4882a593Smuzhiyun         if (stuff->majorVersion == SERVER_DAMAGE_MAJOR_VERSION &&
197*4882a593Smuzhiyun             stuff->minorVersion < SERVER_DAMAGE_MINOR_VERSION)
198*4882a593Smuzhiyun             rep.minorVersion = stuff->minorVersion;
199*4882a593Smuzhiyun         else
200*4882a593Smuzhiyun             rep.minorVersion = SERVER_DAMAGE_MINOR_VERSION;
201*4882a593Smuzhiyun     }
202*4882a593Smuzhiyun     pDamageClient->major_version = rep.majorVersion;
203*4882a593Smuzhiyun     pDamageClient->minor_version = rep.minorVersion;
204*4882a593Smuzhiyun     if (client->swapped) {
205*4882a593Smuzhiyun         swaps(&rep.sequenceNumber);
206*4882a593Smuzhiyun         swapl(&rep.length);
207*4882a593Smuzhiyun         swapl(&rep.majorVersion);
208*4882a593Smuzhiyun         swapl(&rep.minorVersion);
209*4882a593Smuzhiyun     }
210*4882a593Smuzhiyun     WriteToClient(client, sizeof(xDamageQueryVersionReply), &rep);
211*4882a593Smuzhiyun     return Success;
212*4882a593Smuzhiyun }
213*4882a593Smuzhiyun 
214*4882a593Smuzhiyun static void
DamageExtRegister(DrawablePtr pDrawable,DamagePtr pDamage,Bool report)215*4882a593Smuzhiyun DamageExtRegister(DrawablePtr pDrawable, DamagePtr pDamage, Bool report)
216*4882a593Smuzhiyun {
217*4882a593Smuzhiyun     DamageSetReportAfterOp(pDamage, TRUE);
218*4882a593Smuzhiyun     DamageRegister(pDrawable, pDamage);
219*4882a593Smuzhiyun 
220*4882a593Smuzhiyun     if (report) {
221*4882a593Smuzhiyun         RegionPtr pRegion = &((WindowPtr) pDrawable)->borderClip;
222*4882a593Smuzhiyun         RegionTranslate(pRegion, -pDrawable->x, -pDrawable->y);
223*4882a593Smuzhiyun         DamageReportDamage(pDamage, pRegion);
224*4882a593Smuzhiyun         RegionTranslate(pRegion, pDrawable->x, pDrawable->y);
225*4882a593Smuzhiyun     }
226*4882a593Smuzhiyun }
227*4882a593Smuzhiyun 
228*4882a593Smuzhiyun static DamageExtPtr
DamageExtCreate(DrawablePtr pDrawable,DamageReportLevel level,ClientPtr client,XID id,XID drawable)229*4882a593Smuzhiyun DamageExtCreate(DrawablePtr pDrawable, DamageReportLevel level,
230*4882a593Smuzhiyun                 ClientPtr client, XID id, XID drawable)
231*4882a593Smuzhiyun {
232*4882a593Smuzhiyun     DamageExtPtr pDamageExt = malloc(sizeof(DamageExtRec));
233*4882a593Smuzhiyun     if (!pDamageExt)
234*4882a593Smuzhiyun         return NULL;
235*4882a593Smuzhiyun 
236*4882a593Smuzhiyun     pDamageExt->id = id;
237*4882a593Smuzhiyun     pDamageExt->drawable = drawable;
238*4882a593Smuzhiyun     pDamageExt->pDrawable = pDrawable;
239*4882a593Smuzhiyun     pDamageExt->level = level;
240*4882a593Smuzhiyun     pDamageExt->pClient = client;
241*4882a593Smuzhiyun     pDamageExt->pDamage = DamageCreate(DamageExtReport, DamageExtDestroy, level,
242*4882a593Smuzhiyun                                        FALSE, pDrawable->pScreen, pDamageExt);
243*4882a593Smuzhiyun     if (!pDamageExt->pDamage) {
244*4882a593Smuzhiyun         free(pDamageExt);
245*4882a593Smuzhiyun         return NULL;
246*4882a593Smuzhiyun     }
247*4882a593Smuzhiyun 
248*4882a593Smuzhiyun     if (!AddResource(id, DamageExtType, (void *) pDamageExt))
249*4882a593Smuzhiyun         return NULL;
250*4882a593Smuzhiyun 
251*4882a593Smuzhiyun     DamageExtRegister(pDrawable, pDamageExt->pDamage,
252*4882a593Smuzhiyun                       pDrawable->type == DRAWABLE_WINDOW);
253*4882a593Smuzhiyun 
254*4882a593Smuzhiyun     return pDamageExt;
255*4882a593Smuzhiyun }
256*4882a593Smuzhiyun 
257*4882a593Smuzhiyun static DamageExtPtr
doDamageCreate(ClientPtr client,int * rc)258*4882a593Smuzhiyun doDamageCreate(ClientPtr client, int *rc)
259*4882a593Smuzhiyun {
260*4882a593Smuzhiyun     DrawablePtr pDrawable;
261*4882a593Smuzhiyun     DamageExtPtr pDamageExt;
262*4882a593Smuzhiyun     DamageReportLevel level;
263*4882a593Smuzhiyun 
264*4882a593Smuzhiyun     REQUEST(xDamageCreateReq);
265*4882a593Smuzhiyun 
266*4882a593Smuzhiyun     *rc = dixLookupDrawable(&pDrawable, stuff->drawable, client, 0,
267*4882a593Smuzhiyun                             DixGetAttrAccess | DixReadAccess);
268*4882a593Smuzhiyun     if (*rc != Success)
269*4882a593Smuzhiyun         return NULL;
270*4882a593Smuzhiyun 
271*4882a593Smuzhiyun     switch (stuff->level) {
272*4882a593Smuzhiyun     case XDamageReportRawRectangles:
273*4882a593Smuzhiyun         level = DamageReportRawRegion;
274*4882a593Smuzhiyun         break;
275*4882a593Smuzhiyun     case XDamageReportDeltaRectangles:
276*4882a593Smuzhiyun         level = DamageReportDeltaRegion;
277*4882a593Smuzhiyun         break;
278*4882a593Smuzhiyun     case XDamageReportBoundingBox:
279*4882a593Smuzhiyun         level = DamageReportBoundingBox;
280*4882a593Smuzhiyun         break;
281*4882a593Smuzhiyun     case XDamageReportNonEmpty:
282*4882a593Smuzhiyun         level = DamageReportNonEmpty;
283*4882a593Smuzhiyun         break;
284*4882a593Smuzhiyun     default:
285*4882a593Smuzhiyun         client->errorValue = stuff->level;
286*4882a593Smuzhiyun         *rc = BadValue;
287*4882a593Smuzhiyun         return NULL;
288*4882a593Smuzhiyun     }
289*4882a593Smuzhiyun 
290*4882a593Smuzhiyun     pDamageExt = DamageExtCreate(pDrawable, level, client, stuff->damage,
291*4882a593Smuzhiyun                                  stuff->drawable);
292*4882a593Smuzhiyun     if (!pDamageExt)
293*4882a593Smuzhiyun         *rc = BadAlloc;
294*4882a593Smuzhiyun 
295*4882a593Smuzhiyun     return pDamageExt;
296*4882a593Smuzhiyun }
297*4882a593Smuzhiyun 
298*4882a593Smuzhiyun static int
ProcDamageCreate(ClientPtr client)299*4882a593Smuzhiyun ProcDamageCreate(ClientPtr client)
300*4882a593Smuzhiyun {
301*4882a593Smuzhiyun     int rc;
302*4882a593Smuzhiyun     REQUEST(xDamageCreateReq);
303*4882a593Smuzhiyun     REQUEST_SIZE_MATCH(xDamageCreateReq);
304*4882a593Smuzhiyun     LEGAL_NEW_RESOURCE(stuff->damage, client);
305*4882a593Smuzhiyun     doDamageCreate(client, &rc);
306*4882a593Smuzhiyun     return rc;
307*4882a593Smuzhiyun }
308*4882a593Smuzhiyun 
309*4882a593Smuzhiyun static int
ProcDamageDestroy(ClientPtr client)310*4882a593Smuzhiyun ProcDamageDestroy(ClientPtr client)
311*4882a593Smuzhiyun {
312*4882a593Smuzhiyun     REQUEST(xDamageDestroyReq);
313*4882a593Smuzhiyun     DamageExtPtr pDamageExt;
314*4882a593Smuzhiyun 
315*4882a593Smuzhiyun     REQUEST_SIZE_MATCH(xDamageDestroyReq);
316*4882a593Smuzhiyun     VERIFY_DAMAGEEXT(pDamageExt, stuff->damage, client, DixWriteAccess);
317*4882a593Smuzhiyun     FreeResource(stuff->damage, RT_NONE);
318*4882a593Smuzhiyun     return Success;
319*4882a593Smuzhiyun }
320*4882a593Smuzhiyun 
321*4882a593Smuzhiyun #ifdef PANORAMIX
322*4882a593Smuzhiyun static RegionPtr
DamageExtSubtractWindowClip(DamageExtPtr pDamageExt)323*4882a593Smuzhiyun DamageExtSubtractWindowClip(DamageExtPtr pDamageExt)
324*4882a593Smuzhiyun {
325*4882a593Smuzhiyun     WindowPtr win = (WindowPtr)pDamageExt->pDrawable;
326*4882a593Smuzhiyun     PanoramiXRes *res = NULL;
327*4882a593Smuzhiyun     RegionPtr ret;
328*4882a593Smuzhiyun     int i;
329*4882a593Smuzhiyun 
330*4882a593Smuzhiyun     if (!win->parent)
331*4882a593Smuzhiyun         return &PanoramiXScreenRegion;
332*4882a593Smuzhiyun 
333*4882a593Smuzhiyun     dixLookupResourceByType((void **)&res, win->drawable.id, XRT_WINDOW,
334*4882a593Smuzhiyun                             serverClient, DixReadAccess);
335*4882a593Smuzhiyun     if (!res)
336*4882a593Smuzhiyun         return NULL;
337*4882a593Smuzhiyun 
338*4882a593Smuzhiyun     ret = RegionCreate(NULL, 0);
339*4882a593Smuzhiyun     if (!ret)
340*4882a593Smuzhiyun         return NULL;
341*4882a593Smuzhiyun 
342*4882a593Smuzhiyun     FOR_NSCREENS_FORWARD(i) {
343*4882a593Smuzhiyun         ScreenPtr screen;
344*4882a593Smuzhiyun         if (Success != dixLookupWindow(&win, res->info[i].id, serverClient,
345*4882a593Smuzhiyun                                        DixReadAccess))
346*4882a593Smuzhiyun             goto out;
347*4882a593Smuzhiyun 
348*4882a593Smuzhiyun         screen = win->drawable.pScreen;
349*4882a593Smuzhiyun 
350*4882a593Smuzhiyun         RegionTranslate(ret, -screen->x, -screen->y);
351*4882a593Smuzhiyun         if (!RegionUnion(ret, ret, &win->borderClip))
352*4882a593Smuzhiyun             goto out;
353*4882a593Smuzhiyun         RegionTranslate(ret, screen->x, screen->y);
354*4882a593Smuzhiyun     }
355*4882a593Smuzhiyun 
356*4882a593Smuzhiyun     return ret;
357*4882a593Smuzhiyun 
358*4882a593Smuzhiyun out:
359*4882a593Smuzhiyun     RegionDestroy(ret);
360*4882a593Smuzhiyun     return NULL;
361*4882a593Smuzhiyun }
362*4882a593Smuzhiyun 
363*4882a593Smuzhiyun static void
DamageExtFreeWindowClip(RegionPtr reg)364*4882a593Smuzhiyun DamageExtFreeWindowClip(RegionPtr reg)
365*4882a593Smuzhiyun {
366*4882a593Smuzhiyun     if (reg != &PanoramiXScreenRegion)
367*4882a593Smuzhiyun         RegionDestroy(reg);
368*4882a593Smuzhiyun }
369*4882a593Smuzhiyun #endif
370*4882a593Smuzhiyun 
371*4882a593Smuzhiyun /*
372*4882a593Smuzhiyun  * DamageSubtract intersects with borderClip, so we must reconstruct the
373*4882a593Smuzhiyun  * protocol's perspective of same...
374*4882a593Smuzhiyun  */
375*4882a593Smuzhiyun static Bool
DamageExtSubtract(DamageExtPtr pDamageExt,const RegionPtr pRegion)376*4882a593Smuzhiyun DamageExtSubtract(DamageExtPtr pDamageExt, const RegionPtr pRegion)
377*4882a593Smuzhiyun {
378*4882a593Smuzhiyun     DamagePtr pDamage = pDamageExt->pDamage;
379*4882a593Smuzhiyun 
380*4882a593Smuzhiyun #ifdef PANORAMIX
381*4882a593Smuzhiyun     if (!noPanoramiXExtension) {
382*4882a593Smuzhiyun         RegionPtr damage = DamageRegion(pDamage);
383*4882a593Smuzhiyun         RegionSubtract(damage, damage, pRegion);
384*4882a593Smuzhiyun 
385*4882a593Smuzhiyun         if (pDamageExt->pDrawable->type == DRAWABLE_WINDOW) {
386*4882a593Smuzhiyun             DrawablePtr pDraw = pDamageExt->pDrawable;
387*4882a593Smuzhiyun             RegionPtr clip = DamageExtSubtractWindowClip(pDamageExt);
388*4882a593Smuzhiyun             if (clip) {
389*4882a593Smuzhiyun                 RegionTranslate(clip, -pDraw->x, -pDraw->y);
390*4882a593Smuzhiyun                 RegionIntersect(damage, damage, clip);
391*4882a593Smuzhiyun                 RegionTranslate(clip, pDraw->x, pDraw->y);
392*4882a593Smuzhiyun                 DamageExtFreeWindowClip(clip);
393*4882a593Smuzhiyun             }
394*4882a593Smuzhiyun         }
395*4882a593Smuzhiyun 
396*4882a593Smuzhiyun         return RegionNotEmpty(damage);
397*4882a593Smuzhiyun     }
398*4882a593Smuzhiyun #endif
399*4882a593Smuzhiyun 
400*4882a593Smuzhiyun     return DamageSubtract(pDamage, pRegion);
401*4882a593Smuzhiyun }
402*4882a593Smuzhiyun 
403*4882a593Smuzhiyun static int
ProcDamageSubtract(ClientPtr client)404*4882a593Smuzhiyun ProcDamageSubtract(ClientPtr client)
405*4882a593Smuzhiyun {
406*4882a593Smuzhiyun     REQUEST(xDamageSubtractReq);
407*4882a593Smuzhiyun     DamageExtPtr pDamageExt;
408*4882a593Smuzhiyun     RegionPtr pRepair;
409*4882a593Smuzhiyun     RegionPtr pParts;
410*4882a593Smuzhiyun 
411*4882a593Smuzhiyun     REQUEST_SIZE_MATCH(xDamageSubtractReq);
412*4882a593Smuzhiyun     VERIFY_DAMAGEEXT(pDamageExt, stuff->damage, client, DixWriteAccess);
413*4882a593Smuzhiyun     VERIFY_REGION_OR_NONE(pRepair, stuff->repair, client, DixWriteAccess);
414*4882a593Smuzhiyun     VERIFY_REGION_OR_NONE(pParts, stuff->parts, client, DixWriteAccess);
415*4882a593Smuzhiyun 
416*4882a593Smuzhiyun     if (pDamageExt->level != DamageReportRawRegion) {
417*4882a593Smuzhiyun         DamagePtr pDamage = pDamageExt->pDamage;
418*4882a593Smuzhiyun 
419*4882a593Smuzhiyun         if (pRepair) {
420*4882a593Smuzhiyun             if (pParts)
421*4882a593Smuzhiyun                 RegionIntersect(pParts, DamageRegion(pDamage), pRepair);
422*4882a593Smuzhiyun             if (DamageExtSubtract(pDamageExt, pRepair))
423*4882a593Smuzhiyun                 DamageExtReport(pDamage, DamageRegion(pDamage),
424*4882a593Smuzhiyun                                 (void *) pDamageExt);
425*4882a593Smuzhiyun         }
426*4882a593Smuzhiyun         else {
427*4882a593Smuzhiyun             if (pParts)
428*4882a593Smuzhiyun                 RegionCopy(pParts, DamageRegion(pDamage));
429*4882a593Smuzhiyun             DamageEmpty(pDamage);
430*4882a593Smuzhiyun         }
431*4882a593Smuzhiyun     }
432*4882a593Smuzhiyun 
433*4882a593Smuzhiyun     return Success;
434*4882a593Smuzhiyun }
435*4882a593Smuzhiyun 
436*4882a593Smuzhiyun static int
ProcDamageAdd(ClientPtr client)437*4882a593Smuzhiyun ProcDamageAdd(ClientPtr client)
438*4882a593Smuzhiyun {
439*4882a593Smuzhiyun     REQUEST(xDamageAddReq);
440*4882a593Smuzhiyun     DrawablePtr pDrawable;
441*4882a593Smuzhiyun     RegionPtr pRegion;
442*4882a593Smuzhiyun     int rc;
443*4882a593Smuzhiyun 
444*4882a593Smuzhiyun     REQUEST_SIZE_MATCH(xDamageAddReq);
445*4882a593Smuzhiyun     VERIFY_REGION(pRegion, stuff->region, client, DixWriteAccess);
446*4882a593Smuzhiyun     rc = dixLookupDrawable(&pDrawable, stuff->drawable, client, 0,
447*4882a593Smuzhiyun                            DixWriteAccess);
448*4882a593Smuzhiyun     if (rc != Success)
449*4882a593Smuzhiyun         return rc;
450*4882a593Smuzhiyun 
451*4882a593Smuzhiyun     /* The region is relative to the drawable origin, so translate it out to
452*4882a593Smuzhiyun      * screen coordinates like damage expects.
453*4882a593Smuzhiyun      */
454*4882a593Smuzhiyun     RegionTranslate(pRegion, pDrawable->x, pDrawable->y);
455*4882a593Smuzhiyun     DamageDamageRegion(pDrawable, pRegion);
456*4882a593Smuzhiyun     RegionTranslate(pRegion, -pDrawable->x, -pDrawable->y);
457*4882a593Smuzhiyun 
458*4882a593Smuzhiyun     return Success;
459*4882a593Smuzhiyun }
460*4882a593Smuzhiyun 
461*4882a593Smuzhiyun /* Major version controls available requests */
462*4882a593Smuzhiyun static const int version_requests[] = {
463*4882a593Smuzhiyun     X_DamageQueryVersion,       /* before client sends QueryVersion */
464*4882a593Smuzhiyun     X_DamageAdd,                /* Version 1 */
465*4882a593Smuzhiyun };
466*4882a593Smuzhiyun 
467*4882a593Smuzhiyun static int (*ProcDamageVector[XDamageNumberRequests]) (ClientPtr) = {
468*4882a593Smuzhiyun     /*************** Version 1 ******************/
469*4882a593Smuzhiyun     ProcDamageQueryVersion,
470*4882a593Smuzhiyun     ProcDamageCreate,
471*4882a593Smuzhiyun     ProcDamageDestroy,
472*4882a593Smuzhiyun     ProcDamageSubtract,
473*4882a593Smuzhiyun     /*************** Version 1.1 ****************/
474*4882a593Smuzhiyun     ProcDamageAdd,
475*4882a593Smuzhiyun };
476*4882a593Smuzhiyun 
477*4882a593Smuzhiyun static int
ProcDamageDispatch(ClientPtr client)478*4882a593Smuzhiyun ProcDamageDispatch(ClientPtr client)
479*4882a593Smuzhiyun {
480*4882a593Smuzhiyun     REQUEST(xDamageReq);
481*4882a593Smuzhiyun     DamageClientPtr pDamageClient = GetDamageClient(client);
482*4882a593Smuzhiyun 
483*4882a593Smuzhiyun     if (pDamageClient->major_version >= ARRAY_SIZE(version_requests))
484*4882a593Smuzhiyun         return BadRequest;
485*4882a593Smuzhiyun     if (stuff->damageReqType > version_requests[pDamageClient->major_version])
486*4882a593Smuzhiyun         return BadRequest;
487*4882a593Smuzhiyun     return (*ProcDamageVector[stuff->damageReqType]) (client);
488*4882a593Smuzhiyun }
489*4882a593Smuzhiyun 
490*4882a593Smuzhiyun static int _X_COLD
SProcDamageQueryVersion(ClientPtr client)491*4882a593Smuzhiyun SProcDamageQueryVersion(ClientPtr client)
492*4882a593Smuzhiyun {
493*4882a593Smuzhiyun     REQUEST(xDamageQueryVersionReq);
494*4882a593Smuzhiyun 
495*4882a593Smuzhiyun     swaps(&stuff->length);
496*4882a593Smuzhiyun     REQUEST_SIZE_MATCH(xDamageQueryVersionReq);
497*4882a593Smuzhiyun     swapl(&stuff->majorVersion);
498*4882a593Smuzhiyun     swapl(&stuff->minorVersion);
499*4882a593Smuzhiyun     return (*ProcDamageVector[stuff->damageReqType]) (client);
500*4882a593Smuzhiyun }
501*4882a593Smuzhiyun 
502*4882a593Smuzhiyun static int _X_COLD
SProcDamageCreate(ClientPtr client)503*4882a593Smuzhiyun SProcDamageCreate(ClientPtr client)
504*4882a593Smuzhiyun {
505*4882a593Smuzhiyun     REQUEST(xDamageCreateReq);
506*4882a593Smuzhiyun 
507*4882a593Smuzhiyun     swaps(&stuff->length);
508*4882a593Smuzhiyun     REQUEST_SIZE_MATCH(xDamageCreateReq);
509*4882a593Smuzhiyun     swapl(&stuff->damage);
510*4882a593Smuzhiyun     swapl(&stuff->drawable);
511*4882a593Smuzhiyun     return (*ProcDamageVector[stuff->damageReqType]) (client);
512*4882a593Smuzhiyun }
513*4882a593Smuzhiyun 
514*4882a593Smuzhiyun static int _X_COLD
SProcDamageDestroy(ClientPtr client)515*4882a593Smuzhiyun SProcDamageDestroy(ClientPtr client)
516*4882a593Smuzhiyun {
517*4882a593Smuzhiyun     REQUEST(xDamageDestroyReq);
518*4882a593Smuzhiyun 
519*4882a593Smuzhiyun     swaps(&stuff->length);
520*4882a593Smuzhiyun     REQUEST_SIZE_MATCH(xDamageDestroyReq);
521*4882a593Smuzhiyun     swapl(&stuff->damage);
522*4882a593Smuzhiyun     return (*ProcDamageVector[stuff->damageReqType]) (client);
523*4882a593Smuzhiyun }
524*4882a593Smuzhiyun 
525*4882a593Smuzhiyun static int _X_COLD
SProcDamageSubtract(ClientPtr client)526*4882a593Smuzhiyun SProcDamageSubtract(ClientPtr client)
527*4882a593Smuzhiyun {
528*4882a593Smuzhiyun     REQUEST(xDamageSubtractReq);
529*4882a593Smuzhiyun 
530*4882a593Smuzhiyun     swaps(&stuff->length);
531*4882a593Smuzhiyun     REQUEST_SIZE_MATCH(xDamageSubtractReq);
532*4882a593Smuzhiyun     swapl(&stuff->damage);
533*4882a593Smuzhiyun     swapl(&stuff->repair);
534*4882a593Smuzhiyun     swapl(&stuff->parts);
535*4882a593Smuzhiyun     return (*ProcDamageVector[stuff->damageReqType]) (client);
536*4882a593Smuzhiyun }
537*4882a593Smuzhiyun 
538*4882a593Smuzhiyun static int _X_COLD
SProcDamageAdd(ClientPtr client)539*4882a593Smuzhiyun SProcDamageAdd(ClientPtr client)
540*4882a593Smuzhiyun {
541*4882a593Smuzhiyun     REQUEST(xDamageAddReq);
542*4882a593Smuzhiyun 
543*4882a593Smuzhiyun     swaps(&stuff->length);
544*4882a593Smuzhiyun     REQUEST_SIZE_MATCH(xDamageSubtractReq);
545*4882a593Smuzhiyun     swapl(&stuff->drawable);
546*4882a593Smuzhiyun     swapl(&stuff->region);
547*4882a593Smuzhiyun     return (*ProcDamageVector[stuff->damageReqType]) (client);
548*4882a593Smuzhiyun }
549*4882a593Smuzhiyun 
550*4882a593Smuzhiyun static int (*SProcDamageVector[XDamageNumberRequests]) (ClientPtr) = {
551*4882a593Smuzhiyun     /*************** Version 1 ******************/
552*4882a593Smuzhiyun     SProcDamageQueryVersion,
553*4882a593Smuzhiyun     SProcDamageCreate,
554*4882a593Smuzhiyun     SProcDamageDestroy,
555*4882a593Smuzhiyun     SProcDamageSubtract,
556*4882a593Smuzhiyun     /*************** Version 1.1 ****************/
557*4882a593Smuzhiyun     SProcDamageAdd,
558*4882a593Smuzhiyun };
559*4882a593Smuzhiyun 
560*4882a593Smuzhiyun static int _X_COLD
SProcDamageDispatch(ClientPtr client)561*4882a593Smuzhiyun SProcDamageDispatch(ClientPtr client)
562*4882a593Smuzhiyun {
563*4882a593Smuzhiyun     REQUEST(xDamageReq);
564*4882a593Smuzhiyun     if (stuff->damageReqType >= XDamageNumberRequests)
565*4882a593Smuzhiyun         return BadRequest;
566*4882a593Smuzhiyun     return (*SProcDamageVector[stuff->damageReqType]) (client);
567*4882a593Smuzhiyun }
568*4882a593Smuzhiyun 
569*4882a593Smuzhiyun static int
FreeDamageExt(void * value,XID did)570*4882a593Smuzhiyun FreeDamageExt(void *value, XID did)
571*4882a593Smuzhiyun {
572*4882a593Smuzhiyun     DamageExtPtr pDamageExt = (DamageExtPtr) value;
573*4882a593Smuzhiyun 
574*4882a593Smuzhiyun     /*
575*4882a593Smuzhiyun      * Get rid of the resource table entry hanging from the window id
576*4882a593Smuzhiyun      */
577*4882a593Smuzhiyun     pDamageExt->id = 0;
578*4882a593Smuzhiyun     if (pDamageExt->pDamage) {
579*4882a593Smuzhiyun         DamageDestroy(pDamageExt->pDamage);
580*4882a593Smuzhiyun     }
581*4882a593Smuzhiyun     free(pDamageExt);
582*4882a593Smuzhiyun     return Success;
583*4882a593Smuzhiyun }
584*4882a593Smuzhiyun 
585*4882a593Smuzhiyun static void _X_COLD
SDamageNotifyEvent(xDamageNotifyEvent * from,xDamageNotifyEvent * to)586*4882a593Smuzhiyun SDamageNotifyEvent(xDamageNotifyEvent * from, xDamageNotifyEvent * to)
587*4882a593Smuzhiyun {
588*4882a593Smuzhiyun     to->type = from->type;
589*4882a593Smuzhiyun     cpswaps(from->sequenceNumber, to->sequenceNumber);
590*4882a593Smuzhiyun     cpswapl(from->drawable, to->drawable);
591*4882a593Smuzhiyun     cpswapl(from->damage, to->damage);
592*4882a593Smuzhiyun     cpswaps(from->area.x, to->area.x);
593*4882a593Smuzhiyun     cpswaps(from->area.y, to->area.y);
594*4882a593Smuzhiyun     cpswaps(from->area.width, to->area.width);
595*4882a593Smuzhiyun     cpswaps(from->area.height, to->area.height);
596*4882a593Smuzhiyun     cpswaps(from->geometry.x, to->geometry.x);
597*4882a593Smuzhiyun     cpswaps(from->geometry.y, to->geometry.y);
598*4882a593Smuzhiyun     cpswaps(from->geometry.width, to->geometry.width);
599*4882a593Smuzhiyun     cpswaps(from->geometry.height, to->geometry.height);
600*4882a593Smuzhiyun }
601*4882a593Smuzhiyun 
602*4882a593Smuzhiyun #ifdef PANORAMIX
603*4882a593Smuzhiyun 
604*4882a593Smuzhiyun static void
PanoramiXDamageReport(DamagePtr pDamage,RegionPtr pRegion,void * closure)605*4882a593Smuzhiyun PanoramiXDamageReport(DamagePtr pDamage, RegionPtr pRegion, void *closure)
606*4882a593Smuzhiyun {
607*4882a593Smuzhiyun     PanoramiXDamageRes *res = closure;
608*4882a593Smuzhiyun     DamageExtPtr pDamageExt = res->ext;
609*4882a593Smuzhiyun     WindowPtr pWin = (WindowPtr)pDamage->pDrawable;
610*4882a593Smuzhiyun     ScreenPtr pScreen = pDamage->pScreen;
611*4882a593Smuzhiyun 
612*4882a593Smuzhiyun     /* happens on unmap? sigh xinerama */
613*4882a593Smuzhiyun     if (RegionNil(pRegion))
614*4882a593Smuzhiyun         return;
615*4882a593Smuzhiyun 
616*4882a593Smuzhiyun     /* translate root windows if necessary */
617*4882a593Smuzhiyun     if (!pWin->parent)
618*4882a593Smuzhiyun         RegionTranslate(pRegion, pScreen->x, pScreen->y);
619*4882a593Smuzhiyun 
620*4882a593Smuzhiyun     /* add our damage to the protocol view */
621*4882a593Smuzhiyun     DamageReportDamage(pDamageExt->pDamage, pRegion);
622*4882a593Smuzhiyun 
623*4882a593Smuzhiyun     /* empty our view */
624*4882a593Smuzhiyun     DamageEmpty(pDamage);
625*4882a593Smuzhiyun }
626*4882a593Smuzhiyun 
627*4882a593Smuzhiyun static void
PanoramiXDamageExtDestroy(DamagePtr pDamage,void * closure)628*4882a593Smuzhiyun PanoramiXDamageExtDestroy(DamagePtr pDamage, void *closure)
629*4882a593Smuzhiyun {
630*4882a593Smuzhiyun     PanoramiXDamageRes *damage = closure;
631*4882a593Smuzhiyun     damage->damage[pDamage->pScreen->myNum] = NULL;
632*4882a593Smuzhiyun }
633*4882a593Smuzhiyun 
634*4882a593Smuzhiyun static int
PanoramiXDamageCreate(ClientPtr client)635*4882a593Smuzhiyun PanoramiXDamageCreate(ClientPtr client)
636*4882a593Smuzhiyun {
637*4882a593Smuzhiyun     PanoramiXDamageRes *damage;
638*4882a593Smuzhiyun     PanoramiXRes *draw;
639*4882a593Smuzhiyun     int i, rc;
640*4882a593Smuzhiyun 
641*4882a593Smuzhiyun     REQUEST(xDamageCreateReq);
642*4882a593Smuzhiyun 
643*4882a593Smuzhiyun     REQUEST_SIZE_MATCH(xDamageCreateReq);
644*4882a593Smuzhiyun     LEGAL_NEW_RESOURCE(stuff->damage, client);
645*4882a593Smuzhiyun     rc = dixLookupResourceByClass((void **)&draw, stuff->drawable, XRC_DRAWABLE,
646*4882a593Smuzhiyun                                   client, DixGetAttrAccess | DixReadAccess);
647*4882a593Smuzhiyun     if (rc != Success)
648*4882a593Smuzhiyun         return rc;
649*4882a593Smuzhiyun 
650*4882a593Smuzhiyun     if (!(damage = calloc(1, sizeof(PanoramiXDamageRes))))
651*4882a593Smuzhiyun         return BadAlloc;
652*4882a593Smuzhiyun 
653*4882a593Smuzhiyun     if (!AddResource(stuff->damage, XRT_DAMAGE, damage))
654*4882a593Smuzhiyun         return BadAlloc;
655*4882a593Smuzhiyun 
656*4882a593Smuzhiyun     damage->ext = doDamageCreate(client, &rc);
657*4882a593Smuzhiyun     if (rc == Success && draw->type == XRT_WINDOW) {
658*4882a593Smuzhiyun         FOR_NSCREENS_FORWARD(i) {
659*4882a593Smuzhiyun             DrawablePtr pDrawable;
660*4882a593Smuzhiyun             DamagePtr pDamage = DamageCreate(PanoramiXDamageReport,
661*4882a593Smuzhiyun                                              PanoramiXDamageExtDestroy,
662*4882a593Smuzhiyun                                              DamageReportRawRegion,
663*4882a593Smuzhiyun                                              FALSE,
664*4882a593Smuzhiyun                                              screenInfo.screens[i],
665*4882a593Smuzhiyun                                              damage);
666*4882a593Smuzhiyun             if (!pDamage) {
667*4882a593Smuzhiyun                 rc = BadAlloc;
668*4882a593Smuzhiyun             } else {
669*4882a593Smuzhiyun                 damage->damage[i] = pDamage;
670*4882a593Smuzhiyun                 rc = dixLookupDrawable(&pDrawable, draw->info[i].id, client,
671*4882a593Smuzhiyun                                        M_WINDOW,
672*4882a593Smuzhiyun                                        DixGetAttrAccess | DixReadAccess);
673*4882a593Smuzhiyun             }
674*4882a593Smuzhiyun             if (rc != Success)
675*4882a593Smuzhiyun                 break;
676*4882a593Smuzhiyun 
677*4882a593Smuzhiyun             DamageExtRegister(pDrawable, pDamage, i != 0);
678*4882a593Smuzhiyun         }
679*4882a593Smuzhiyun     }
680*4882a593Smuzhiyun 
681*4882a593Smuzhiyun     if (rc != Success)
682*4882a593Smuzhiyun         FreeResource(stuff->damage, RT_NONE);
683*4882a593Smuzhiyun 
684*4882a593Smuzhiyun     return rc;
685*4882a593Smuzhiyun }
686*4882a593Smuzhiyun 
687*4882a593Smuzhiyun static int
PanoramiXDamageDelete(void * res,XID id)688*4882a593Smuzhiyun PanoramiXDamageDelete(void *res, XID id)
689*4882a593Smuzhiyun {
690*4882a593Smuzhiyun     int i;
691*4882a593Smuzhiyun     PanoramiXDamageRes *damage = res;
692*4882a593Smuzhiyun 
693*4882a593Smuzhiyun     FOR_NSCREENS_BACKWARD(i) {
694*4882a593Smuzhiyun         if (damage->damage[i]) {
695*4882a593Smuzhiyun             DamageDestroy(damage->damage[i]);
696*4882a593Smuzhiyun             damage->damage[i] = NULL;
697*4882a593Smuzhiyun         }
698*4882a593Smuzhiyun     }
699*4882a593Smuzhiyun 
700*4882a593Smuzhiyun     free(damage);
701*4882a593Smuzhiyun     return 1;
702*4882a593Smuzhiyun }
703*4882a593Smuzhiyun 
704*4882a593Smuzhiyun void
PanoramiXDamageInit(void)705*4882a593Smuzhiyun PanoramiXDamageInit(void)
706*4882a593Smuzhiyun {
707*4882a593Smuzhiyun     XRT_DAMAGE = CreateNewResourceType(PanoramiXDamageDelete, "XineramaDamage");
708*4882a593Smuzhiyun     if (!XRT_DAMAGE)
709*4882a593Smuzhiyun         FatalError("Couldn't Xineramify Damage extension\n");
710*4882a593Smuzhiyun 
711*4882a593Smuzhiyun     PanoramiXSaveDamageCreate = ProcDamageVector[X_DamageCreate];
712*4882a593Smuzhiyun     ProcDamageVector[X_DamageCreate] = PanoramiXDamageCreate;
713*4882a593Smuzhiyun }
714*4882a593Smuzhiyun 
715*4882a593Smuzhiyun void
PanoramiXDamageReset(void)716*4882a593Smuzhiyun PanoramiXDamageReset(void)
717*4882a593Smuzhiyun {
718*4882a593Smuzhiyun     ProcDamageVector[X_DamageCreate] = PanoramiXSaveDamageCreate;
719*4882a593Smuzhiyun }
720*4882a593Smuzhiyun 
721*4882a593Smuzhiyun #endif /* PANORAMIX */
722*4882a593Smuzhiyun 
723*4882a593Smuzhiyun void
DamageExtensionInit(void)724*4882a593Smuzhiyun DamageExtensionInit(void)
725*4882a593Smuzhiyun {
726*4882a593Smuzhiyun     ExtensionEntry *extEntry;
727*4882a593Smuzhiyun     int s;
728*4882a593Smuzhiyun 
729*4882a593Smuzhiyun     for (s = 0; s < screenInfo.numScreens; s++)
730*4882a593Smuzhiyun         DamageSetup(screenInfo.screens[s]);
731*4882a593Smuzhiyun 
732*4882a593Smuzhiyun     DamageExtType = CreateNewResourceType(FreeDamageExt, "DamageExt");
733*4882a593Smuzhiyun     if (!DamageExtType)
734*4882a593Smuzhiyun         return;
735*4882a593Smuzhiyun 
736*4882a593Smuzhiyun     if (!dixRegisterPrivateKey
737*4882a593Smuzhiyun         (&DamageClientPrivateKeyRec, PRIVATE_CLIENT, sizeof(DamageClientRec)))
738*4882a593Smuzhiyun         return;
739*4882a593Smuzhiyun 
740*4882a593Smuzhiyun     if ((extEntry = AddExtension(DAMAGE_NAME, XDamageNumberEvents,
741*4882a593Smuzhiyun                                  XDamageNumberErrors,
742*4882a593Smuzhiyun                                  ProcDamageDispatch, SProcDamageDispatch,
743*4882a593Smuzhiyun                                  NULL, StandardMinorOpcode)) != 0) {
744*4882a593Smuzhiyun         DamageReqCode = (unsigned char) extEntry->base;
745*4882a593Smuzhiyun         DamageEventBase = extEntry->eventBase;
746*4882a593Smuzhiyun         EventSwapVector[DamageEventBase + XDamageNotify] =
747*4882a593Smuzhiyun             (EventSwapPtr) SDamageNotifyEvent;
748*4882a593Smuzhiyun         SetResourceTypeErrorValue(DamageExtType,
749*4882a593Smuzhiyun                                   extEntry->errorBase + BadDamage);
750*4882a593Smuzhiyun #ifdef PANORAMIX
751*4882a593Smuzhiyun         if (XRT_DAMAGE)
752*4882a593Smuzhiyun             SetResourceTypeErrorValue(XRT_DAMAGE,
753*4882a593Smuzhiyun                                       extEntry->errorBase + BadDamage);
754*4882a593Smuzhiyun #endif
755*4882a593Smuzhiyun     }
756*4882a593Smuzhiyun }
757