damageext.c revision 8223e2f2
105b261ecSmrg/* 205b261ecSmrg * Copyright © 2002 Keith Packard 305b261ecSmrg * 405b261ecSmrg * Permission to use, copy, modify, distribute, and sell this software and its 505b261ecSmrg * documentation for any purpose is hereby granted without fee, provided that 605b261ecSmrg * the above copyright notice appear in all copies and that both that 705b261ecSmrg * copyright notice and this permission notice appear in supporting 805b261ecSmrg * documentation, and that the name of Keith Packard not be used in 905b261ecSmrg * advertising or publicity pertaining to distribution of the software without 1005b261ecSmrg * specific, written prior permission. Keith Packard makes no 1105b261ecSmrg * representations about the suitability of this software for any purpose. It 1205b261ecSmrg * is provided "as is" without express or implied warranty. 1305b261ecSmrg * 1405b261ecSmrg * KEITH PACKARD DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, 1505b261ecSmrg * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO 1605b261ecSmrg * EVENT SHALL KEITH PACKARD BE LIABLE FOR ANY SPECIAL, INDIRECT OR 1705b261ecSmrg * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, 1805b261ecSmrg * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER 1905b261ecSmrg * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR 2005b261ecSmrg * PERFORMANCE OF THIS SOFTWARE. 2105b261ecSmrg */ 2205b261ecSmrg 2305b261ecSmrg#ifdef HAVE_DIX_CONFIG_H 2405b261ecSmrg#include <dix-config.h> 2505b261ecSmrg#endif 2605b261ecSmrg 2705b261ecSmrg#include "damageextint.h" 286747b715Smrg#include "protocol-versions.h" 2905b261ecSmrg 3005b261ecSmrgstatic unsigned char DamageReqCode; 3105b261ecSmrgstatic int DamageEventBase; 3205b261ecSmrgstatic RESTYPE DamageExtType; 3305b261ecSmrgstatic RESTYPE DamageExtWinType; 3405b261ecSmrg 356747b715Smrgstatic DevPrivateKeyRec DamageClientPrivateKeyRec; 366747b715Smrg#define DamageClientPrivateKey (&DamageClientPrivateKeyRec) 3705b261ecSmrg 3805b261ecSmrgstatic void 3905b261ecSmrgDamageExtNotify (DamageExtPtr pDamageExt, BoxPtr pBoxes, int nBoxes) 4005b261ecSmrg{ 4105b261ecSmrg ClientPtr pClient = pDamageExt->pClient; 4205b261ecSmrg DamageClientPtr pDamageClient = GetDamageClient (pClient); 4305b261ecSmrg DrawablePtr pDrawable = pDamageExt->pDrawable; 4405b261ecSmrg xDamageNotifyEvent ev; 4505b261ecSmrg int i; 4605b261ecSmrg 4705b261ecSmrg UpdateCurrentTimeIf (); 4805b261ecSmrg ev.type = DamageEventBase + XDamageNotify; 4905b261ecSmrg ev.level = pDamageExt->level; 506747b715Smrg ev.drawable = pDamageExt->drawable; 5105b261ecSmrg ev.damage = pDamageExt->id; 5205b261ecSmrg ev.timestamp = currentTime.milliseconds; 5305b261ecSmrg ev.geometry.x = pDrawable->x; 5405b261ecSmrg ev.geometry.y = pDrawable->y; 5505b261ecSmrg ev.geometry.width = pDrawable->width; 5605b261ecSmrg ev.geometry.height = pDrawable->height; 5705b261ecSmrg if (pBoxes) 5805b261ecSmrg { 5905b261ecSmrg for (i = 0; i < nBoxes; i++) 6005b261ecSmrg { 6105b261ecSmrg ev.level = pDamageExt->level; 6205b261ecSmrg if (i < nBoxes - 1) 6305b261ecSmrg ev.level |= DamageNotifyMore; 6405b261ecSmrg ev.area.x = pBoxes[i].x1; 6505b261ecSmrg ev.area.y = pBoxes[i].y1; 6605b261ecSmrg ev.area.width = pBoxes[i].x2 - pBoxes[i].x1; 6705b261ecSmrg ev.area.height = pBoxes[i].y2 - pBoxes[i].y1; 686747b715Smrg WriteEventsToClient (pClient, 1, (xEvent *) &ev); 6905b261ecSmrg } 7005b261ecSmrg } 7105b261ecSmrg else 7205b261ecSmrg { 7305b261ecSmrg ev.area.x = 0; 7405b261ecSmrg ev.area.y = 0; 7505b261ecSmrg ev.area.width = pDrawable->width; 7605b261ecSmrg ev.area.height = pDrawable->height; 776747b715Smrg WriteEventsToClient (pClient, 1, (xEvent *) &ev); 7805b261ecSmrg } 7905b261ecSmrg /* Composite extension marks clients with manual Subwindows as critical */ 8005b261ecSmrg if (pDamageClient->critical > 0) 8105b261ecSmrg { 8205b261ecSmrg SetCriticalOutputPending (); 8305b261ecSmrg pClient->smart_priority = SMART_MAX_PRIORITY; 8405b261ecSmrg } 8505b261ecSmrg} 8605b261ecSmrg 8705b261ecSmrgstatic void 8805b261ecSmrgDamageExtReport (DamagePtr pDamage, RegionPtr pRegion, void *closure) 8905b261ecSmrg{ 9005b261ecSmrg DamageExtPtr pDamageExt = closure; 9105b261ecSmrg 9205b261ecSmrg switch (pDamageExt->level) { 9305b261ecSmrg case DamageReportRawRegion: 9405b261ecSmrg case DamageReportDeltaRegion: 956747b715Smrg DamageExtNotify (pDamageExt, RegionRects(pRegion), RegionNumRects(pRegion)); 9605b261ecSmrg break; 9705b261ecSmrg case DamageReportBoundingBox: 986747b715Smrg DamageExtNotify (pDamageExt, RegionExtents(pRegion), 1); 9905b261ecSmrg break; 10005b261ecSmrg case DamageReportNonEmpty: 10105b261ecSmrg DamageExtNotify (pDamageExt, NullBox, 0); 10205b261ecSmrg break; 10305b261ecSmrg case DamageReportNone: 10405b261ecSmrg break; 10505b261ecSmrg } 10605b261ecSmrg} 10705b261ecSmrg 10805b261ecSmrgstatic void 10905b261ecSmrgDamageExtDestroy (DamagePtr pDamage, void *closure) 11005b261ecSmrg{ 11105b261ecSmrg DamageExtPtr pDamageExt = closure; 11205b261ecSmrg 11305b261ecSmrg pDamageExt->pDamage = 0; 11405b261ecSmrg if (pDamageExt->id) 11505b261ecSmrg FreeResource (pDamageExt->id, RT_NONE); 11605b261ecSmrg} 11705b261ecSmrg 11805b261ecSmrgvoid 11905b261ecSmrgDamageExtSetCritical (ClientPtr pClient, Bool critical) 12005b261ecSmrg{ 12105b261ecSmrg DamageClientPtr pDamageClient = GetDamageClient (pClient); 12205b261ecSmrg 12305b261ecSmrg if (pDamageClient) 12405b261ecSmrg pDamageClient->critical += critical ? 1 : -1; 12505b261ecSmrg} 12605b261ecSmrg 12705b261ecSmrgstatic int 12805b261ecSmrgProcDamageQueryVersion(ClientPtr client) 12905b261ecSmrg{ 13005b261ecSmrg DamageClientPtr pDamageClient = GetDamageClient (client); 13105b261ecSmrg xDamageQueryVersionReply rep; 13205b261ecSmrg register int n; 13305b261ecSmrg REQUEST(xDamageQueryVersionReq); 13405b261ecSmrg 13505b261ecSmrg REQUEST_SIZE_MATCH(xDamageQueryVersionReq); 13605b261ecSmrg rep.type = X_Reply; 13705b261ecSmrg rep.length = 0; 13805b261ecSmrg rep.sequenceNumber = client->sequence; 1396747b715Smrg if (stuff->majorVersion < SERVER_DAMAGE_MAJOR_VERSION) { 14005b261ecSmrg rep.majorVersion = stuff->majorVersion; 14105b261ecSmrg rep.minorVersion = stuff->minorVersion; 14205b261ecSmrg } else { 1436747b715Smrg rep.majorVersion = SERVER_DAMAGE_MAJOR_VERSION; 1446747b715Smrg if (stuff->majorVersion == SERVER_DAMAGE_MAJOR_VERSION && 1456747b715Smrg stuff->minorVersion < SERVER_DAMAGE_MINOR_VERSION) 14605b261ecSmrg rep.minorVersion = stuff->minorVersion; 14705b261ecSmrg else 1486747b715Smrg rep.minorVersion = SERVER_DAMAGE_MINOR_VERSION; 14905b261ecSmrg } 15005b261ecSmrg pDamageClient->major_version = rep.majorVersion; 15105b261ecSmrg pDamageClient->minor_version = rep.minorVersion; 15205b261ecSmrg if (client->swapped) { 15305b261ecSmrg swaps(&rep.sequenceNumber, n); 15405b261ecSmrg swapl(&rep.length, n); 15505b261ecSmrg swapl(&rep.majorVersion, n); 15605b261ecSmrg swapl(&rep.minorVersion, n); 15705b261ecSmrg } 15805b261ecSmrg WriteToClient(client, sizeof(xDamageQueryVersionReply), (char *)&rep); 1596747b715Smrg return Success; 16005b261ecSmrg} 16105b261ecSmrg 16205b261ecSmrgstatic int 16305b261ecSmrgProcDamageCreate (ClientPtr client) 16405b261ecSmrg{ 16505b261ecSmrg DrawablePtr pDrawable; 16605b261ecSmrg DamageExtPtr pDamageExt; 16705b261ecSmrg DamageReportLevel level; 16805b261ecSmrg RegionPtr pRegion; 16905b261ecSmrg int rc; 17005b261ecSmrg 17105b261ecSmrg REQUEST(xDamageCreateReq); 17205b261ecSmrg 17305b261ecSmrg REQUEST_SIZE_MATCH(xDamageCreateReq); 17405b261ecSmrg LEGAL_NEW_RESOURCE(stuff->damage, client); 17505b261ecSmrg rc = dixLookupDrawable(&pDrawable, stuff->drawable, client, 0, 1764642e01fSmrg DixGetAttrAccess|DixReadAccess); 17705b261ecSmrg if (rc != Success) 17805b261ecSmrg return rc; 17905b261ecSmrg 18005b261ecSmrg switch (stuff->level) { 18105b261ecSmrg case XDamageReportRawRectangles: 18205b261ecSmrg level = DamageReportRawRegion; 18305b261ecSmrg break; 18405b261ecSmrg case XDamageReportDeltaRectangles: 18505b261ecSmrg level = DamageReportDeltaRegion; 18605b261ecSmrg break; 18705b261ecSmrg case XDamageReportBoundingBox: 18805b261ecSmrg level = DamageReportBoundingBox; 18905b261ecSmrg break; 19005b261ecSmrg case XDamageReportNonEmpty: 19105b261ecSmrg level = DamageReportNonEmpty; 19205b261ecSmrg break; 19305b261ecSmrg default: 19405b261ecSmrg client->errorValue = stuff->level; 19505b261ecSmrg return BadValue; 19605b261ecSmrg } 19705b261ecSmrg 1986747b715Smrg pDamageExt = malloc(sizeof (DamageExtRec)); 19905b261ecSmrg if (!pDamageExt) 20005b261ecSmrg return BadAlloc; 20105b261ecSmrg pDamageExt->id = stuff->damage; 2026747b715Smrg pDamageExt->drawable = stuff->drawable; 20305b261ecSmrg pDamageExt->pDrawable = pDrawable; 20405b261ecSmrg pDamageExt->level = level; 20505b261ecSmrg pDamageExt->pClient = client; 20605b261ecSmrg pDamageExt->pDamage = DamageCreate (DamageExtReport, 20705b261ecSmrg DamageExtDestroy, 20805b261ecSmrg level, 20905b261ecSmrg FALSE, 21005b261ecSmrg pDrawable->pScreen, 21105b261ecSmrg pDamageExt); 21205b261ecSmrg if (!pDamageExt->pDamage) 21305b261ecSmrg { 2146747b715Smrg free(pDamageExt); 21505b261ecSmrg return BadAlloc; 21605b261ecSmrg } 21705b261ecSmrg if (!AddResource (stuff->damage, DamageExtType, (pointer) pDamageExt)) 21805b261ecSmrg return BadAlloc; 21905b261ecSmrg 2206747b715Smrg DamageSetReportAfterOp (pDamageExt->pDamage, TRUE); 22105b261ecSmrg DamageRegister (pDamageExt->pDrawable, pDamageExt->pDamage); 22205b261ecSmrg 22305b261ecSmrg if (pDrawable->type == DRAWABLE_WINDOW) 22405b261ecSmrg { 22505b261ecSmrg pRegion = &((WindowPtr) pDrawable)->borderClip; 2268223e2f2Smrg DamageDamageRegion(pDrawable, pRegion); 22705b261ecSmrg } 22805b261ecSmrg 2296747b715Smrg return Success; 23005b261ecSmrg} 23105b261ecSmrg 23205b261ecSmrgstatic int 23305b261ecSmrgProcDamageDestroy (ClientPtr client) 23405b261ecSmrg{ 23505b261ecSmrg REQUEST(xDamageDestroyReq); 23605b261ecSmrg DamageExtPtr pDamageExt; 23705b261ecSmrg 23805b261ecSmrg REQUEST_SIZE_MATCH(xDamageDestroyReq); 23905b261ecSmrg VERIFY_DAMAGEEXT(pDamageExt, stuff->damage, client, DixWriteAccess); 24005b261ecSmrg FreeResource (stuff->damage, RT_NONE); 2416747b715Smrg return Success; 24205b261ecSmrg} 24305b261ecSmrg 24405b261ecSmrgstatic int 24505b261ecSmrgProcDamageSubtract (ClientPtr client) 24605b261ecSmrg{ 24705b261ecSmrg REQUEST(xDamageSubtractReq); 24805b261ecSmrg DamageExtPtr pDamageExt; 24905b261ecSmrg RegionPtr pRepair; 25005b261ecSmrg RegionPtr pParts; 25105b261ecSmrg 25205b261ecSmrg REQUEST_SIZE_MATCH(xDamageSubtractReq); 25305b261ecSmrg VERIFY_DAMAGEEXT(pDamageExt, stuff->damage, client, DixWriteAccess); 25405b261ecSmrg VERIFY_REGION_OR_NONE(pRepair, stuff->repair, client, DixWriteAccess); 25505b261ecSmrg VERIFY_REGION_OR_NONE(pParts, stuff->parts, client, DixWriteAccess); 25605b261ecSmrg 25705b261ecSmrg if (pDamageExt->level != DamageReportRawRegion) 25805b261ecSmrg { 25905b261ecSmrg DamagePtr pDamage = pDamageExt->pDamage; 26005b261ecSmrg if (pRepair) 26105b261ecSmrg { 26205b261ecSmrg if (pParts) 2636747b715Smrg RegionIntersect(pParts, DamageRegion (pDamage), pRepair); 26405b261ecSmrg if (DamageSubtract (pDamage, pRepair)) 26505b261ecSmrg DamageExtReport (pDamage, DamageRegion (pDamage), (void *) pDamageExt); 26605b261ecSmrg } 26705b261ecSmrg else 26805b261ecSmrg { 26905b261ecSmrg if (pParts) 2706747b715Smrg RegionCopy(pParts, DamageRegion (pDamage)); 27105b261ecSmrg DamageEmpty (pDamage); 27205b261ecSmrg } 27305b261ecSmrg } 2746747b715Smrg return Success; 27505b261ecSmrg} 27605b261ecSmrg 27705b261ecSmrgstatic int 27805b261ecSmrgProcDamageAdd (ClientPtr client) 27905b261ecSmrg{ 28005b261ecSmrg REQUEST(xDamageAddReq); 28105b261ecSmrg DrawablePtr pDrawable; 28205b261ecSmrg RegionPtr pRegion; 28305b261ecSmrg int rc; 28405b261ecSmrg 28505b261ecSmrg REQUEST_SIZE_MATCH(xDamageAddReq); 28605b261ecSmrg VERIFY_REGION(pRegion, stuff->region, client, DixWriteAccess); 28705b261ecSmrg rc = dixLookupDrawable(&pDrawable, stuff->drawable, client, 0, 2884642e01fSmrg DixWriteAccess); 28905b261ecSmrg if (rc != Success) 29005b261ecSmrg return rc; 29105b261ecSmrg 29205b261ecSmrg /* The region is relative to the drawable origin, so translate it out to 29305b261ecSmrg * screen coordinates like damage expects. 29405b261ecSmrg */ 2956747b715Smrg RegionTranslate(pRegion, pDrawable->x, pDrawable->y); 2968223e2f2Smrg DamageDamageRegion(pDrawable, pRegion); 2976747b715Smrg RegionTranslate(pRegion, -pDrawable->x, -pDrawable->y); 29805b261ecSmrg 2996747b715Smrg return Success; 30005b261ecSmrg} 30105b261ecSmrg 30205b261ecSmrg/* Major version controls available requests */ 30305b261ecSmrgstatic const int version_requests[] = { 30405b261ecSmrg X_DamageQueryVersion, /* before client sends QueryVersion */ 30505b261ecSmrg X_DamageAdd, /* Version 1 */ 30605b261ecSmrg}; 30705b261ecSmrg 30805b261ecSmrg#define NUM_VERSION_REQUESTS (sizeof (version_requests) / sizeof (version_requests[0])) 30905b261ecSmrg 31005b261ecSmrgstatic int (*ProcDamageVector[XDamageNumberRequests])(ClientPtr) = { 31105b261ecSmrg/*************** Version 1 ******************/ 31205b261ecSmrg ProcDamageQueryVersion, 31305b261ecSmrg ProcDamageCreate, 31405b261ecSmrg ProcDamageDestroy, 31505b261ecSmrg ProcDamageSubtract, 31605b261ecSmrg/*************** Version 1.1 ****************/ 31705b261ecSmrg ProcDamageAdd, 31805b261ecSmrg}; 31905b261ecSmrg 32005b261ecSmrg 32105b261ecSmrgstatic int 32205b261ecSmrgProcDamageDispatch (ClientPtr client) 32305b261ecSmrg{ 32405b261ecSmrg REQUEST(xDamageReq); 32505b261ecSmrg DamageClientPtr pDamageClient = GetDamageClient (client); 32605b261ecSmrg 32705b261ecSmrg if (pDamageClient->major_version >= NUM_VERSION_REQUESTS) 32805b261ecSmrg return BadRequest; 32905b261ecSmrg if (stuff->damageReqType > version_requests[pDamageClient->major_version]) 33005b261ecSmrg return BadRequest; 33105b261ecSmrg return (*ProcDamageVector[stuff->damageReqType]) (client); 33205b261ecSmrg} 33305b261ecSmrg 33405b261ecSmrgstatic int 33505b261ecSmrgSProcDamageQueryVersion(ClientPtr client) 33605b261ecSmrg{ 33705b261ecSmrg register int n; 33805b261ecSmrg REQUEST(xDamageQueryVersionReq); 33905b261ecSmrg 34005b261ecSmrg swaps(&stuff->length, n); 34105b261ecSmrg REQUEST_SIZE_MATCH(xDamageQueryVersionReq); 34205b261ecSmrg swapl(&stuff->majorVersion, n); 34305b261ecSmrg swapl(&stuff->minorVersion, n); 34405b261ecSmrg return (*ProcDamageVector[stuff->damageReqType]) (client); 34505b261ecSmrg} 34605b261ecSmrg 34705b261ecSmrgstatic int 34805b261ecSmrgSProcDamageCreate (ClientPtr client) 34905b261ecSmrg{ 35005b261ecSmrg register int n; 35105b261ecSmrg REQUEST(xDamageCreateReq); 35205b261ecSmrg 35305b261ecSmrg swaps (&stuff->length, n); 35405b261ecSmrg REQUEST_SIZE_MATCH(xDamageCreateReq); 35505b261ecSmrg swapl (&stuff->damage, n); 35605b261ecSmrg swapl (&stuff->drawable, n); 35705b261ecSmrg return (*ProcDamageVector[stuff->damageReqType]) (client); 35805b261ecSmrg} 35905b261ecSmrg 36005b261ecSmrgstatic int 36105b261ecSmrgSProcDamageDestroy (ClientPtr client) 36205b261ecSmrg{ 36305b261ecSmrg register int n; 36405b261ecSmrg REQUEST(xDamageDestroyReq); 36505b261ecSmrg 36605b261ecSmrg swaps (&stuff->length, n); 36705b261ecSmrg REQUEST_SIZE_MATCH(xDamageDestroyReq); 36805b261ecSmrg swapl (&stuff->damage, n); 36905b261ecSmrg return (*ProcDamageVector[stuff->damageReqType]) (client); 37005b261ecSmrg} 37105b261ecSmrg 37205b261ecSmrgstatic int 37305b261ecSmrgSProcDamageSubtract (ClientPtr client) 37405b261ecSmrg{ 37505b261ecSmrg register int n; 37605b261ecSmrg REQUEST(xDamageSubtractReq); 37705b261ecSmrg 37805b261ecSmrg swaps (&stuff->length, n); 37905b261ecSmrg REQUEST_SIZE_MATCH(xDamageSubtractReq); 38005b261ecSmrg swapl (&stuff->damage, n); 38105b261ecSmrg swapl (&stuff->repair, n); 38205b261ecSmrg swapl (&stuff->parts, n); 38305b261ecSmrg return (*ProcDamageVector[stuff->damageReqType]) (client); 38405b261ecSmrg} 38505b261ecSmrg 38605b261ecSmrgstatic int 38705b261ecSmrgSProcDamageAdd (ClientPtr client) 38805b261ecSmrg{ 38905b261ecSmrg register int n; 39005b261ecSmrg REQUEST(xDamageAddReq); 39105b261ecSmrg 39205b261ecSmrg swaps (&stuff->length, n); 39305b261ecSmrg REQUEST_SIZE_MATCH(xDamageSubtractReq); 39405b261ecSmrg swapl (&stuff->drawable, n); 39505b261ecSmrg swapl (&stuff->region, n); 39605b261ecSmrg return (*ProcDamageVector[stuff->damageReqType]) (client); 39705b261ecSmrg} 39805b261ecSmrg 39905b261ecSmrgstatic int (*SProcDamageVector[XDamageNumberRequests])(ClientPtr) = { 40005b261ecSmrg/*************** Version 1 ******************/ 40105b261ecSmrg SProcDamageQueryVersion, 40205b261ecSmrg SProcDamageCreate, 40305b261ecSmrg SProcDamageDestroy, 40405b261ecSmrg SProcDamageSubtract, 40505b261ecSmrg/*************** Version 1.1 ****************/ 40605b261ecSmrg SProcDamageAdd, 40705b261ecSmrg}; 40805b261ecSmrg 40905b261ecSmrgstatic int 41005b261ecSmrgSProcDamageDispatch (ClientPtr client) 41105b261ecSmrg{ 41205b261ecSmrg REQUEST(xDamageReq); 41305b261ecSmrg if (stuff->damageReqType >= XDamageNumberRequests) 41405b261ecSmrg return BadRequest; 41505b261ecSmrg return (*SProcDamageVector[stuff->damageReqType]) (client); 41605b261ecSmrg} 41705b261ecSmrg 41805b261ecSmrgstatic void 41905b261ecSmrgDamageClientCallback (CallbackListPtr *list, 42005b261ecSmrg pointer closure, 42105b261ecSmrg pointer data) 42205b261ecSmrg{ 42305b261ecSmrg NewClientInfoRec *clientinfo = (NewClientInfoRec *) data; 42405b261ecSmrg ClientPtr pClient = clientinfo->client; 42505b261ecSmrg DamageClientPtr pDamageClient = GetDamageClient (pClient); 42605b261ecSmrg 42705b261ecSmrg pDamageClient->critical = 0; 42805b261ecSmrg pDamageClient->major_version = 0; 42905b261ecSmrg pDamageClient->minor_version = 0; 43005b261ecSmrg} 43105b261ecSmrg 43205b261ecSmrg/*ARGSUSED*/ 43305b261ecSmrgstatic void 43405b261ecSmrgDamageResetProc (ExtensionEntry *extEntry) 43505b261ecSmrg{ 43605b261ecSmrg DeleteCallback (&ClientStateCallback, DamageClientCallback, 0); 43705b261ecSmrg} 43805b261ecSmrg 43905b261ecSmrgstatic int 44005b261ecSmrgFreeDamageExt (pointer value, XID did) 44105b261ecSmrg{ 44205b261ecSmrg DamageExtPtr pDamageExt = (DamageExtPtr) value; 44305b261ecSmrg 44405b261ecSmrg /* 44505b261ecSmrg * Get rid of the resource table entry hanging from the window id 44605b261ecSmrg */ 44705b261ecSmrg pDamageExt->id = 0; 44805b261ecSmrg if (WindowDrawable(pDamageExt->pDrawable->type)) 44905b261ecSmrg FreeResourceByType (pDamageExt->pDrawable->id, DamageExtWinType, TRUE); 45005b261ecSmrg if (pDamageExt->pDamage) 45105b261ecSmrg { 45205b261ecSmrg DamageUnregister (pDamageExt->pDrawable, pDamageExt->pDamage); 45305b261ecSmrg DamageDestroy (pDamageExt->pDamage); 45405b261ecSmrg } 4556747b715Smrg free(pDamageExt); 45605b261ecSmrg return Success; 45705b261ecSmrg} 45805b261ecSmrg 45905b261ecSmrgstatic int 46005b261ecSmrgFreeDamageExtWin (pointer value, XID wid) 46105b261ecSmrg{ 46205b261ecSmrg DamageExtPtr pDamageExt = (DamageExtPtr) value; 46305b261ecSmrg 46405b261ecSmrg if (pDamageExt->id) 46505b261ecSmrg FreeResource (pDamageExt->id, RT_NONE); 46605b261ecSmrg return Success; 46705b261ecSmrg} 46805b261ecSmrg 46905b261ecSmrgstatic void 47005b261ecSmrgSDamageNotifyEvent (xDamageNotifyEvent *from, 47105b261ecSmrg xDamageNotifyEvent *to) 47205b261ecSmrg{ 47305b261ecSmrg to->type = from->type; 47405b261ecSmrg cpswaps (from->sequenceNumber, to->sequenceNumber); 47505b261ecSmrg cpswapl (from->drawable, to->drawable); 47605b261ecSmrg cpswapl (from->damage, to->damage); 47705b261ecSmrg cpswaps (from->area.x, to->area.x); 47805b261ecSmrg cpswaps (from->area.y, to->area.y); 47905b261ecSmrg cpswaps (from->area.width, to->area.width); 48005b261ecSmrg cpswaps (from->area.height, to->area.height); 48105b261ecSmrg cpswaps (from->geometry.x, to->geometry.x); 48205b261ecSmrg cpswaps (from->geometry.y, to->geometry.y); 48305b261ecSmrg cpswaps (from->geometry.width, to->geometry.width); 48405b261ecSmrg cpswaps (from->geometry.height, to->geometry.height); 48505b261ecSmrg} 48605b261ecSmrg 48705b261ecSmrgvoid 48805b261ecSmrgDamageExtensionInit(void) 48905b261ecSmrg{ 49005b261ecSmrg ExtensionEntry *extEntry; 49105b261ecSmrg int s; 49205b261ecSmrg 49305b261ecSmrg for (s = 0; s < screenInfo.numScreens; s++) 49405b261ecSmrg DamageSetup (screenInfo.screens[s]); 49505b261ecSmrg 4966747b715Smrg DamageExtType = CreateNewResourceType (FreeDamageExt, "DamageExt"); 49705b261ecSmrg if (!DamageExtType) 49805b261ecSmrg return; 49905b261ecSmrg 5006747b715Smrg DamageExtWinType = CreateNewResourceType (FreeDamageExtWin, "DamageExtWin"); 50105b261ecSmrg if (!DamageExtWinType) 50205b261ecSmrg return; 50305b261ecSmrg 5046747b715Smrg if (!dixRegisterPrivateKey(&DamageClientPrivateKeyRec, PRIVATE_CLIENT, sizeof (DamageClientRec))) 50505b261ecSmrg return; 5066747b715Smrg 50705b261ecSmrg if (!AddCallback (&ClientStateCallback, DamageClientCallback, 0)) 50805b261ecSmrg return; 50905b261ecSmrg 51005b261ecSmrg if ((extEntry = AddExtension(DAMAGE_NAME, XDamageNumberEvents, 51105b261ecSmrg XDamageNumberErrors, 51205b261ecSmrg ProcDamageDispatch, SProcDamageDispatch, 51305b261ecSmrg DamageResetProc, StandardMinorOpcode)) != 0) 51405b261ecSmrg { 51505b261ecSmrg DamageReqCode = (unsigned char)extEntry->base; 51605b261ecSmrg DamageEventBase = extEntry->eventBase; 51705b261ecSmrg EventSwapVector[DamageEventBase + XDamageNotify] = 51805b261ecSmrg (EventSwapPtr) SDamageNotifyEvent; 5196747b715Smrg SetResourceTypeErrorValue(DamageExtType, extEntry->errorBase + BadDamage); 52005b261ecSmrg } 52105b261ecSmrg} 522