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