From 019fc27ce6dc2a1809107be10d4deb80e0fa436b Mon Sep 17 00:00:00 2001 From: marha Date: Thu, 14 Apr 2011 06:41:54 +0000 Subject: server xkeyboard-config mesa git update 14 Apr 2011 --- xorg-server/damageext/damageext.c | 1042 ++++++++++++++++++------------------- 1 file changed, 521 insertions(+), 521 deletions(-) (limited to 'xorg-server/damageext') diff --git a/xorg-server/damageext/damageext.c b/xorg-server/damageext/damageext.c index 2b1514872..02db88a8e 100644 --- a/xorg-server/damageext/damageext.c +++ b/xorg-server/damageext/damageext.c @@ -1,521 +1,521 @@ -/* - * Copyright © 2002 Keith Packard - * - * Permission to use, copy, modify, distribute, and sell this software and its - * documentation for any purpose is hereby granted without fee, provided that - * the above copyright notice appear in all copies and that both that - * copyright notice and this permission notice appear in supporting - * documentation, and that the name of Keith Packard not be used in - * advertising or publicity pertaining to distribution of the software without - * specific, written prior permission. Keith Packard makes no - * representations about the suitability of this software for any purpose. It - * is provided "as is" without express or implied warranty. - * - * KEITH PACKARD DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, - * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO - * EVENT SHALL KEITH PACKARD BE LIABLE FOR ANY SPECIAL, INDIRECT OR - * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, - * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER - * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR - * PERFORMANCE OF THIS SOFTWARE. - */ - -#ifdef HAVE_DIX_CONFIG_H -#include -#endif - -#include "damageextint.h" -#include "protocol-versions.h" - -static unsigned char DamageReqCode; -static int DamageEventBase; -static RESTYPE DamageExtType; -static RESTYPE DamageExtWinType; - -static DevPrivateKeyRec DamageClientPrivateKeyRec; -#define DamageClientPrivateKey (&DamageClientPrivateKeyRec) - -static void -DamageExtNotify (DamageExtPtr pDamageExt, BoxPtr pBoxes, int nBoxes) -{ - ClientPtr pClient = pDamageExt->pClient; - DamageClientPtr pDamageClient = GetDamageClient (pClient); - DrawablePtr pDrawable = pDamageExt->pDrawable; - xDamageNotifyEvent ev; - int i; - - UpdateCurrentTimeIf (); - ev.type = DamageEventBase + XDamageNotify; - ev.level = pDamageExt->level; - ev.drawable = pDamageExt->drawable; - ev.damage = pDamageExt->id; - ev.timestamp = currentTime.milliseconds; - ev.geometry.x = pDrawable->x; - ev.geometry.y = pDrawable->y; - ev.geometry.width = pDrawable->width; - ev.geometry.height = pDrawable->height; - if (pBoxes) - { - for (i = 0; i < nBoxes; i++) - { - ev.level = pDamageExt->level; - if (i < nBoxes - 1) - ev.level |= DamageNotifyMore; - ev.area.x = pBoxes[i].x1; - ev.area.y = pBoxes[i].y1; - ev.area.width = pBoxes[i].x2 - pBoxes[i].x1; - ev.area.height = pBoxes[i].y2 - pBoxes[i].y1; - WriteEventsToClient (pClient, 1, (xEvent *) &ev); - } - } - else - { - ev.area.x = 0; - ev.area.y = 0; - ev.area.width = pDrawable->width; - ev.area.height = pDrawable->height; - WriteEventsToClient (pClient, 1, (xEvent *) &ev); - } - /* Composite extension marks clients with manual Subwindows as critical */ - if (pDamageClient->critical > 0) - { - SetCriticalOutputPending (); - pClient->smart_priority = SMART_MAX_PRIORITY; - } -} - -static void -DamageExtReport (DamagePtr pDamage, RegionPtr pRegion, void *closure) -{ - DamageExtPtr pDamageExt = closure; - - switch (pDamageExt->level) { - case DamageReportRawRegion: - case DamageReportDeltaRegion: - DamageExtNotify (pDamageExt, RegionRects(pRegion), RegionNumRects(pRegion)); - break; - case DamageReportBoundingBox: - DamageExtNotify (pDamageExt, RegionExtents(pRegion), 1); - break; - case DamageReportNonEmpty: - DamageExtNotify (pDamageExt, NullBox, 0); - break; - case DamageReportNone: - break; - } -} - -static void -DamageExtDestroy (DamagePtr pDamage, void *closure) -{ - DamageExtPtr pDamageExt = closure; - - pDamageExt->pDamage = 0; - if (pDamageExt->id) - FreeResource (pDamageExt->id, RT_NONE); -} - -void -DamageExtSetCritical (ClientPtr pClient, Bool critical) -{ - DamageClientPtr pDamageClient = GetDamageClient (pClient); - - if (pDamageClient) - pDamageClient->critical += critical ? 1 : -1; -} - -static int -ProcDamageQueryVersion(ClientPtr client) -{ - DamageClientPtr pDamageClient = GetDamageClient (client); - xDamageQueryVersionReply rep; - register int n; - REQUEST(xDamageQueryVersionReq); - - REQUEST_SIZE_MATCH(xDamageQueryVersionReq); - rep.type = X_Reply; - rep.length = 0; - rep.sequenceNumber = client->sequence; - if (stuff->majorVersion < SERVER_DAMAGE_MAJOR_VERSION) { - rep.majorVersion = stuff->majorVersion; - rep.minorVersion = stuff->minorVersion; - } else { - rep.majorVersion = SERVER_DAMAGE_MAJOR_VERSION; - if (stuff->majorVersion == SERVER_DAMAGE_MAJOR_VERSION && - stuff->minorVersion < SERVER_DAMAGE_MINOR_VERSION) - rep.minorVersion = stuff->minorVersion; - else - rep.minorVersion = SERVER_DAMAGE_MINOR_VERSION; - } - pDamageClient->major_version = rep.majorVersion; - pDamageClient->minor_version = rep.minorVersion; - if (client->swapped) { - swaps(&rep.sequenceNumber, n); - swapl(&rep.length, n); - swapl(&rep.majorVersion, n); - swapl(&rep.minorVersion, n); - } - WriteToClient(client, sizeof(xDamageQueryVersionReply), (char *)&rep); - return Success; -} - -static int -ProcDamageCreate (ClientPtr client) -{ - DrawablePtr pDrawable; - DamageExtPtr pDamageExt; - DamageReportLevel level; - RegionPtr pRegion; - int rc; - - REQUEST(xDamageCreateReq); - - REQUEST_SIZE_MATCH(xDamageCreateReq); - LEGAL_NEW_RESOURCE(stuff->damage, client); - rc = dixLookupDrawable(&pDrawable, stuff->drawable, client, 0, - DixGetAttrAccess|DixReadAccess); - if (rc != Success) - return rc; - - switch (stuff->level) { - case XDamageReportRawRectangles: - level = DamageReportRawRegion; - break; - case XDamageReportDeltaRectangles: - level = DamageReportDeltaRegion; - break; - case XDamageReportBoundingBox: - level = DamageReportBoundingBox; - break; - case XDamageReportNonEmpty: - level = DamageReportNonEmpty; - break; - default: - client->errorValue = stuff->level; - return BadValue; - } - - pDamageExt = malloc(sizeof (DamageExtRec)); - if (!pDamageExt) - return BadAlloc; - pDamageExt->id = stuff->damage; - pDamageExt->drawable = stuff->drawable; - pDamageExt->pDrawable = pDrawable; - pDamageExt->level = level; - pDamageExt->pClient = client; - pDamageExt->pDamage = DamageCreate (DamageExtReport, - DamageExtDestroy, - level, - FALSE, - pDrawable->pScreen, - pDamageExt); - if (!pDamageExt->pDamage) - { - free(pDamageExt); - return BadAlloc; - } - if (!AddResource (stuff->damage, DamageExtType, (pointer) pDamageExt)) - return BadAlloc; - - DamageSetReportAfterOp (pDamageExt->pDamage, TRUE); - DamageRegister (pDamageExt->pDrawable, pDamageExt->pDamage); - - if (pDrawable->type == DRAWABLE_WINDOW) - { - pRegion = &((WindowPtr) pDrawable)->borderClip; - DamageDamageRegion(pDrawable, pRegion); - } - - return Success; -} - -static int -ProcDamageDestroy (ClientPtr client) -{ - REQUEST(xDamageDestroyReq); - DamageExtPtr pDamageExt; - - REQUEST_SIZE_MATCH(xDamageDestroyReq); - VERIFY_DAMAGEEXT(pDamageExt, stuff->damage, client, DixWriteAccess); - FreeResource (stuff->damage, RT_NONE); - return Success; -} - -static int -ProcDamageSubtract (ClientPtr client) -{ - REQUEST(xDamageSubtractReq); - DamageExtPtr pDamageExt; - RegionPtr pRepair; - RegionPtr pParts; - - REQUEST_SIZE_MATCH(xDamageSubtractReq); - VERIFY_DAMAGEEXT(pDamageExt, stuff->damage, client, DixWriteAccess); - VERIFY_REGION_OR_NONE(pRepair, stuff->repair, client, DixWriteAccess); - VERIFY_REGION_OR_NONE(pParts, stuff->parts, client, DixWriteAccess); - - if (pDamageExt->level != DamageReportRawRegion) - { - DamagePtr pDamage = pDamageExt->pDamage; - if (pRepair) - { - if (pParts) - RegionIntersect(pParts, DamageRegion (pDamage), pRepair); - if (DamageSubtract (pDamage, pRepair)) - DamageExtReport (pDamage, DamageRegion (pDamage), (void *) pDamageExt); - } - else - { - if (pParts) - RegionCopy(pParts, DamageRegion (pDamage)); - DamageEmpty (pDamage); - } - } - return Success; -} - -static int -ProcDamageAdd (ClientPtr client) -{ - REQUEST(xDamageAddReq); - DrawablePtr pDrawable; - RegionPtr pRegion; - int rc; - - REQUEST_SIZE_MATCH(xDamageAddReq); - VERIFY_REGION(pRegion, stuff->region, client, DixWriteAccess); - rc = dixLookupDrawable(&pDrawable, stuff->drawable, client, 0, - DixWriteAccess); - if (rc != Success) - return rc; - - /* The region is relative to the drawable origin, so translate it out to - * screen coordinates like damage expects. - */ - RegionTranslate(pRegion, pDrawable->x, pDrawable->y); - DamageDamageRegion(pDrawable, pRegion); - RegionTranslate(pRegion, -pDrawable->x, -pDrawable->y); - - return Success; -} - -/* Major version controls available requests */ -static const int version_requests[] = { - X_DamageQueryVersion, /* before client sends QueryVersion */ - X_DamageAdd, /* Version 1 */ -}; - -#define NUM_VERSION_REQUESTS (sizeof (version_requests) / sizeof (version_requests[0])) - -static int (*ProcDamageVector[XDamageNumberRequests])(ClientPtr) = { -/*************** Version 1 ******************/ - ProcDamageQueryVersion, - ProcDamageCreate, - ProcDamageDestroy, - ProcDamageSubtract, -/*************** Version 1.1 ****************/ - ProcDamageAdd, -}; - - -static int -ProcDamageDispatch (ClientPtr client) -{ - REQUEST(xDamageReq); - DamageClientPtr pDamageClient = GetDamageClient (client); - - if (pDamageClient->major_version >= NUM_VERSION_REQUESTS) - return BadRequest; - if (stuff->damageReqType > version_requests[pDamageClient->major_version]) - return BadRequest; - return (*ProcDamageVector[stuff->damageReqType]) (client); -} - -static int -SProcDamageQueryVersion(ClientPtr client) -{ - register int n; - REQUEST(xDamageQueryVersionReq); - - swaps(&stuff->length, n); - REQUEST_SIZE_MATCH(xDamageQueryVersionReq); - swapl(&stuff->majorVersion, n); - swapl(&stuff->minorVersion, n); - return (*ProcDamageVector[stuff->damageReqType]) (client); -} - -static int -SProcDamageCreate (ClientPtr client) -{ - register int n; - REQUEST(xDamageCreateReq); - - swaps (&stuff->length, n); - REQUEST_SIZE_MATCH(xDamageCreateReq); - swapl (&stuff->damage, n); - swapl (&stuff->drawable, n); - return (*ProcDamageVector[stuff->damageReqType]) (client); -} - -static int -SProcDamageDestroy (ClientPtr client) -{ - register int n; - REQUEST(xDamageDestroyReq); - - swaps (&stuff->length, n); - REQUEST_SIZE_MATCH(xDamageDestroyReq); - swapl (&stuff->damage, n); - return (*ProcDamageVector[stuff->damageReqType]) (client); -} - -static int -SProcDamageSubtract (ClientPtr client) -{ - register int n; - REQUEST(xDamageSubtractReq); - - swaps (&stuff->length, n); - REQUEST_SIZE_MATCH(xDamageSubtractReq); - swapl (&stuff->damage, n); - swapl (&stuff->repair, n); - swapl (&stuff->parts, n); - return (*ProcDamageVector[stuff->damageReqType]) (client); -} - -static int -SProcDamageAdd (ClientPtr client) -{ - register int n; - REQUEST(xDamageAddReq); - - swaps (&stuff->length, n); - REQUEST_SIZE_MATCH(xDamageSubtractReq); - swapl (&stuff->drawable, n); - swapl (&stuff->region, n); - return (*ProcDamageVector[stuff->damageReqType]) (client); -} - -static int (*SProcDamageVector[XDamageNumberRequests])(ClientPtr) = { -/*************** Version 1 ******************/ - SProcDamageQueryVersion, - SProcDamageCreate, - SProcDamageDestroy, - SProcDamageSubtract, -/*************** Version 1.1 ****************/ - SProcDamageAdd, -}; - -static int -SProcDamageDispatch (ClientPtr client) -{ - REQUEST(xDamageReq); - if (stuff->damageReqType >= XDamageNumberRequests) - return BadRequest; - return (*SProcDamageVector[stuff->damageReqType]) (client); -} - -static void -DamageClientCallback (CallbackListPtr *list, - pointer closure, - pointer data) -{ - NewClientInfoRec *clientinfo = (NewClientInfoRec *) data; - ClientPtr pClient = clientinfo->client; - DamageClientPtr pDamageClient = GetDamageClient (pClient); - - pDamageClient->critical = 0; - pDamageClient->major_version = 0; - pDamageClient->minor_version = 0; -} - -/*ARGSUSED*/ -static void -DamageResetProc (ExtensionEntry *extEntry) -{ - DeleteCallback (&ClientStateCallback, DamageClientCallback, 0); -} - -static int -FreeDamageExt (pointer value, XID did) -{ - DamageExtPtr pDamageExt = (DamageExtPtr) value; - - /* - * Get rid of the resource table entry hanging from the window id - */ - pDamageExt->id = 0; - if (WindowDrawable(pDamageExt->pDrawable->type)) - FreeResourceByType (pDamageExt->pDrawable->id, DamageExtWinType, TRUE); - if (pDamageExt->pDamage) - { - DamageUnregister (pDamageExt->pDrawable, pDamageExt->pDamage); - DamageDestroy (pDamageExt->pDamage); - } - free(pDamageExt); - return Success; -} - -static int -FreeDamageExtWin (pointer value, XID wid) -{ - DamageExtPtr pDamageExt = (DamageExtPtr) value; - - if (pDamageExt->id) - FreeResource (pDamageExt->id, RT_NONE); - return Success; -} - -static void -SDamageNotifyEvent (xDamageNotifyEvent *from, - xDamageNotifyEvent *to) -{ - to->type = from->type; - cpswaps (from->sequenceNumber, to->sequenceNumber); - cpswapl (from->drawable, to->drawable); - cpswapl (from->damage, to->damage); - cpswaps (from->area.x, to->area.x); - cpswaps (from->area.y, to->area.y); - cpswaps (from->area.width, to->area.width); - cpswaps (from->area.height, to->area.height); - cpswaps (from->geometry.x, to->geometry.x); - cpswaps (from->geometry.y, to->geometry.y); - cpswaps (from->geometry.width, to->geometry.width); - cpswaps (from->geometry.height, to->geometry.height); -} - -void -DamageExtensionInit(void) -{ - ExtensionEntry *extEntry; - int s; - - for (s = 0; s < screenInfo.numScreens; s++) - DamageSetup (screenInfo.screens[s]); - - DamageExtType = CreateNewResourceType (FreeDamageExt, "DamageExt"); - if (!DamageExtType) - return; - - DamageExtWinType = CreateNewResourceType (FreeDamageExtWin, "DamageExtWin"); - if (!DamageExtWinType) - return; - - if (!dixRegisterPrivateKey(&DamageClientPrivateKeyRec, PRIVATE_CLIENT, sizeof (DamageClientRec))) - return; - - if (!AddCallback (&ClientStateCallback, DamageClientCallback, 0)) - return; - - if ((extEntry = AddExtension(DAMAGE_NAME, XDamageNumberEvents, - XDamageNumberErrors, - ProcDamageDispatch, SProcDamageDispatch, - DamageResetProc, StandardMinorOpcode)) != 0) - { - DamageReqCode = (unsigned char)extEntry->base; - DamageEventBase = extEntry->eventBase; - EventSwapVector[DamageEventBase + XDamageNotify] = - (EventSwapPtr) SDamageNotifyEvent; - SetResourceTypeErrorValue(DamageExtType, extEntry->errorBase + BadDamage); - } -} +/* + * Copyright © 2002 Keith Packard + * + * Permission to use, copy, modify, distribute, and sell this software and its + * documentation for any purpose is hereby granted without fee, provided that + * the above copyright notice appear in all copies and that both that + * copyright notice and this permission notice appear in supporting + * documentation, and that the name of Keith Packard not be used in + * advertising or publicity pertaining to distribution of the software without + * specific, written prior permission. Keith Packard makes no + * representations about the suitability of this software for any purpose. It + * is provided "as is" without express or implied warranty. + * + * KEITH PACKARD DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, + * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO + * EVENT SHALL KEITH PACKARD BE LIABLE FOR ANY SPECIAL, INDIRECT OR + * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, + * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +#ifdef HAVE_DIX_CONFIG_H +#include +#endif + +#include "damageextint.h" +#include "protocol-versions.h" + +static unsigned char DamageReqCode; +static int DamageEventBase; +static RESTYPE DamageExtType; +static RESTYPE DamageExtWinType; + +static DevPrivateKeyRec DamageClientPrivateKeyRec; +#define DamageClientPrivateKey (&DamageClientPrivateKeyRec) + +static void +DamageExtNotify (DamageExtPtr pDamageExt, BoxPtr pBoxes, int nBoxes) +{ + ClientPtr pClient = pDamageExt->pClient; + DamageClientPtr pDamageClient = GetDamageClient (pClient); + DrawablePtr pDrawable = pDamageExt->pDrawable; + xDamageNotifyEvent ev; + int i; + + UpdateCurrentTimeIf (); + ev.type = DamageEventBase + XDamageNotify; + ev.level = pDamageExt->level; + ev.drawable = pDamageExt->drawable; + ev.damage = pDamageExt->id; + ev.timestamp = currentTime.milliseconds; + ev.geometry.x = pDrawable->x; + ev.geometry.y = pDrawable->y; + ev.geometry.width = pDrawable->width; + ev.geometry.height = pDrawable->height; + if (pBoxes) + { + for (i = 0; i < nBoxes; i++) + { + ev.level = pDamageExt->level; + if (i < nBoxes - 1) + ev.level |= DamageNotifyMore; + ev.area.x = pBoxes[i].x1; + ev.area.y = pBoxes[i].y1; + ev.area.width = pBoxes[i].x2 - pBoxes[i].x1; + ev.area.height = pBoxes[i].y2 - pBoxes[i].y1; + WriteEventsToClient (pClient, 1, (xEvent *) &ev); + } + } + else + { + ev.area.x = 0; + ev.area.y = 0; + ev.area.width = pDrawable->width; + ev.area.height = pDrawable->height; + WriteEventsToClient (pClient, 1, (xEvent *) &ev); + } + /* Composite extension marks clients with manual Subwindows as critical */ + if (pDamageClient->critical > 0) + { + SetCriticalOutputPending (); + pClient->smart_priority = SMART_MAX_PRIORITY; + } +} + +static void +DamageExtReport (DamagePtr pDamage, RegionPtr pRegion, void *closure) +{ + DamageExtPtr pDamageExt = closure; + + switch (pDamageExt->level) { + case DamageReportRawRegion: + case DamageReportDeltaRegion: + DamageExtNotify (pDamageExt, RegionRects(pRegion), RegionNumRects(pRegion)); + break; + case DamageReportBoundingBox: + DamageExtNotify (pDamageExt, RegionExtents(pRegion), 1); + break; + case DamageReportNonEmpty: + DamageExtNotify (pDamageExt, NullBox, 0); + break; + case DamageReportNone: + break; + } +} + +static void +DamageExtDestroy (DamagePtr pDamage, void *closure) +{ + DamageExtPtr pDamageExt = closure; + + pDamageExt->pDamage = 0; + if (pDamageExt->id) + FreeResource (pDamageExt->id, RT_NONE); +} + +void +DamageExtSetCritical (ClientPtr pClient, Bool critical) +{ + DamageClientPtr pDamageClient = GetDamageClient (pClient); + + if (pDamageClient) + pDamageClient->critical += critical ? 1 : -1; +} + +static int +ProcDamageQueryVersion(ClientPtr client) +{ + DamageClientPtr pDamageClient = GetDamageClient (client); + xDamageQueryVersionReply rep; + register int n; + REQUEST(xDamageQueryVersionReq); + + REQUEST_SIZE_MATCH(xDamageQueryVersionReq); + rep.type = X_Reply; + rep.length = 0; + rep.sequenceNumber = client->sequence; + if (stuff->majorVersion < SERVER_DAMAGE_MAJOR_VERSION) { + rep.majorVersion = stuff->majorVersion; + rep.minorVersion = stuff->minorVersion; + } else { + rep.majorVersion = SERVER_DAMAGE_MAJOR_VERSION; + if (stuff->majorVersion == SERVER_DAMAGE_MAJOR_VERSION && + stuff->minorVersion < SERVER_DAMAGE_MINOR_VERSION) + rep.minorVersion = stuff->minorVersion; + else + rep.minorVersion = SERVER_DAMAGE_MINOR_VERSION; + } + pDamageClient->major_version = rep.majorVersion; + pDamageClient->minor_version = rep.minorVersion; + if (client->swapped) { + swaps(&rep.sequenceNumber, n); + swapl(&rep.length, n); + swapl(&rep.majorVersion, n); + swapl(&rep.minorVersion, n); + } + WriteToClient(client, sizeof(xDamageQueryVersionReply), (char *)&rep); + return Success; +} + +static int +ProcDamageCreate (ClientPtr client) +{ + DrawablePtr pDrawable; + DamageExtPtr pDamageExt; + DamageReportLevel level; + RegionPtr pRegion; + int rc; + + REQUEST(xDamageCreateReq); + + REQUEST_SIZE_MATCH(xDamageCreateReq); + LEGAL_NEW_RESOURCE(stuff->damage, client); + rc = dixLookupDrawable(&pDrawable, stuff->drawable, client, 0, + DixGetAttrAccess|DixReadAccess); + if (rc != Success) + return rc; + + switch (stuff->level) { + case XDamageReportRawRectangles: + level = DamageReportRawRegion; + break; + case XDamageReportDeltaRectangles: + level = DamageReportDeltaRegion; + break; + case XDamageReportBoundingBox: + level = DamageReportBoundingBox; + break; + case XDamageReportNonEmpty: + level = DamageReportNonEmpty; + break; + default: + client->errorValue = stuff->level; + return BadValue; + } + + pDamageExt = malloc(sizeof (DamageExtRec)); + if (!pDamageExt) + return BadAlloc; + pDamageExt->id = stuff->damage; + pDamageExt->drawable = stuff->drawable; + pDamageExt->pDrawable = pDrawable; + pDamageExt->level = level; + pDamageExt->pClient = client; + pDamageExt->pDamage = DamageCreate (DamageExtReport, + DamageExtDestroy, + level, + FALSE, + pDrawable->pScreen, + pDamageExt); + if (!pDamageExt->pDamage) + { + free(pDamageExt); + return BadAlloc; + } + if (!AddResource (stuff->damage, DamageExtType, (pointer) pDamageExt)) + return BadAlloc; + + DamageSetReportAfterOp (pDamageExt->pDamage, TRUE); + DamageRegister (pDamageExt->pDrawable, pDamageExt->pDamage); + + if (pDrawable->type == DRAWABLE_WINDOW) + { + pRegion = &((WindowPtr) pDrawable)->borderClip; + DamageReportDamage(pDamageExt->pDamage, pRegion); + } + + return Success; +} + +static int +ProcDamageDestroy (ClientPtr client) +{ + REQUEST(xDamageDestroyReq); + DamageExtPtr pDamageExt; + + REQUEST_SIZE_MATCH(xDamageDestroyReq); + VERIFY_DAMAGEEXT(pDamageExt, stuff->damage, client, DixWriteAccess); + FreeResource (stuff->damage, RT_NONE); + return Success; +} + +static int +ProcDamageSubtract (ClientPtr client) +{ + REQUEST(xDamageSubtractReq); + DamageExtPtr pDamageExt; + RegionPtr pRepair; + RegionPtr pParts; + + REQUEST_SIZE_MATCH(xDamageSubtractReq); + VERIFY_DAMAGEEXT(pDamageExt, stuff->damage, client, DixWriteAccess); + VERIFY_REGION_OR_NONE(pRepair, stuff->repair, client, DixWriteAccess); + VERIFY_REGION_OR_NONE(pParts, stuff->parts, client, DixWriteAccess); + + if (pDamageExt->level != DamageReportRawRegion) + { + DamagePtr pDamage = pDamageExt->pDamage; + if (pRepair) + { + if (pParts) + RegionIntersect(pParts, DamageRegion (pDamage), pRepair); + if (DamageSubtract (pDamage, pRepair)) + DamageExtReport (pDamage, DamageRegion (pDamage), (void *) pDamageExt); + } + else + { + if (pParts) + RegionCopy(pParts, DamageRegion (pDamage)); + DamageEmpty (pDamage); + } + } + return Success; +} + +static int +ProcDamageAdd (ClientPtr client) +{ + REQUEST(xDamageAddReq); + DrawablePtr pDrawable; + RegionPtr pRegion; + int rc; + + REQUEST_SIZE_MATCH(xDamageAddReq); + VERIFY_REGION(pRegion, stuff->region, client, DixWriteAccess); + rc = dixLookupDrawable(&pDrawable, stuff->drawable, client, 0, + DixWriteAccess); + if (rc != Success) + return rc; + + /* The region is relative to the drawable origin, so translate it out to + * screen coordinates like damage expects. + */ + RegionTranslate(pRegion, pDrawable->x, pDrawable->y); + DamageDamageRegion(pDrawable, pRegion); + RegionTranslate(pRegion, -pDrawable->x, -pDrawable->y); + + return Success; +} + +/* Major version controls available requests */ +static const int version_requests[] = { + X_DamageQueryVersion, /* before client sends QueryVersion */ + X_DamageAdd, /* Version 1 */ +}; + +#define NUM_VERSION_REQUESTS (sizeof (version_requests) / sizeof (version_requests[0])) + +static int (*ProcDamageVector[XDamageNumberRequests])(ClientPtr) = { +/*************** Version 1 ******************/ + ProcDamageQueryVersion, + ProcDamageCreate, + ProcDamageDestroy, + ProcDamageSubtract, +/*************** Version 1.1 ****************/ + ProcDamageAdd, +}; + + +static int +ProcDamageDispatch (ClientPtr client) +{ + REQUEST(xDamageReq); + DamageClientPtr pDamageClient = GetDamageClient (client); + + if (pDamageClient->major_version >= NUM_VERSION_REQUESTS) + return BadRequest; + if (stuff->damageReqType > version_requests[pDamageClient->major_version]) + return BadRequest; + return (*ProcDamageVector[stuff->damageReqType]) (client); +} + +static int +SProcDamageQueryVersion(ClientPtr client) +{ + register int n; + REQUEST(xDamageQueryVersionReq); + + swaps(&stuff->length, n); + REQUEST_SIZE_MATCH(xDamageQueryVersionReq); + swapl(&stuff->majorVersion, n); + swapl(&stuff->minorVersion, n); + return (*ProcDamageVector[stuff->damageReqType]) (client); +} + +static int +SProcDamageCreate (ClientPtr client) +{ + register int n; + REQUEST(xDamageCreateReq); + + swaps (&stuff->length, n); + REQUEST_SIZE_MATCH(xDamageCreateReq); + swapl (&stuff->damage, n); + swapl (&stuff->drawable, n); + return (*ProcDamageVector[stuff->damageReqType]) (client); +} + +static int +SProcDamageDestroy (ClientPtr client) +{ + register int n; + REQUEST(xDamageDestroyReq); + + swaps (&stuff->length, n); + REQUEST_SIZE_MATCH(xDamageDestroyReq); + swapl (&stuff->damage, n); + return (*ProcDamageVector[stuff->damageReqType]) (client); +} + +static int +SProcDamageSubtract (ClientPtr client) +{ + register int n; + REQUEST(xDamageSubtractReq); + + swaps (&stuff->length, n); + REQUEST_SIZE_MATCH(xDamageSubtractReq); + swapl (&stuff->damage, n); + swapl (&stuff->repair, n); + swapl (&stuff->parts, n); + return (*ProcDamageVector[stuff->damageReqType]) (client); +} + +static int +SProcDamageAdd (ClientPtr client) +{ + register int n; + REQUEST(xDamageAddReq); + + swaps (&stuff->length, n); + REQUEST_SIZE_MATCH(xDamageSubtractReq); + swapl (&stuff->drawable, n); + swapl (&stuff->region, n); + return (*ProcDamageVector[stuff->damageReqType]) (client); +} + +static int (*SProcDamageVector[XDamageNumberRequests])(ClientPtr) = { +/*************** Version 1 ******************/ + SProcDamageQueryVersion, + SProcDamageCreate, + SProcDamageDestroy, + SProcDamageSubtract, +/*************** Version 1.1 ****************/ + SProcDamageAdd, +}; + +static int +SProcDamageDispatch (ClientPtr client) +{ + REQUEST(xDamageReq); + if (stuff->damageReqType >= XDamageNumberRequests) + return BadRequest; + return (*SProcDamageVector[stuff->damageReqType]) (client); +} + +static void +DamageClientCallback (CallbackListPtr *list, + pointer closure, + pointer data) +{ + NewClientInfoRec *clientinfo = (NewClientInfoRec *) data; + ClientPtr pClient = clientinfo->client; + DamageClientPtr pDamageClient = GetDamageClient (pClient); + + pDamageClient->critical = 0; + pDamageClient->major_version = 0; + pDamageClient->minor_version = 0; +} + +/*ARGSUSED*/ +static void +DamageResetProc (ExtensionEntry *extEntry) +{ + DeleteCallback (&ClientStateCallback, DamageClientCallback, 0); +} + +static int +FreeDamageExt (pointer value, XID did) +{ + DamageExtPtr pDamageExt = (DamageExtPtr) value; + + /* + * Get rid of the resource table entry hanging from the window id + */ + pDamageExt->id = 0; + if (WindowDrawable(pDamageExt->pDrawable->type)) + FreeResourceByType (pDamageExt->pDrawable->id, DamageExtWinType, TRUE); + if (pDamageExt->pDamage) + { + DamageUnregister (pDamageExt->pDrawable, pDamageExt->pDamage); + DamageDestroy (pDamageExt->pDamage); + } + free(pDamageExt); + return Success; +} + +static int +FreeDamageExtWin (pointer value, XID wid) +{ + DamageExtPtr pDamageExt = (DamageExtPtr) value; + + if (pDamageExt->id) + FreeResource (pDamageExt->id, RT_NONE); + return Success; +} + +static void +SDamageNotifyEvent (xDamageNotifyEvent *from, + xDamageNotifyEvent *to) +{ + to->type = from->type; + cpswaps (from->sequenceNumber, to->sequenceNumber); + cpswapl (from->drawable, to->drawable); + cpswapl (from->damage, to->damage); + cpswaps (from->area.x, to->area.x); + cpswaps (from->area.y, to->area.y); + cpswaps (from->area.width, to->area.width); + cpswaps (from->area.height, to->area.height); + cpswaps (from->geometry.x, to->geometry.x); + cpswaps (from->geometry.y, to->geometry.y); + cpswaps (from->geometry.width, to->geometry.width); + cpswaps (from->geometry.height, to->geometry.height); +} + +void +DamageExtensionInit(void) +{ + ExtensionEntry *extEntry; + int s; + + for (s = 0; s < screenInfo.numScreens; s++) + DamageSetup (screenInfo.screens[s]); + + DamageExtType = CreateNewResourceType (FreeDamageExt, "DamageExt"); + if (!DamageExtType) + return; + + DamageExtWinType = CreateNewResourceType (FreeDamageExtWin, "DamageExtWin"); + if (!DamageExtWinType) + return; + + if (!dixRegisterPrivateKey(&DamageClientPrivateKeyRec, PRIVATE_CLIENT, sizeof (DamageClientRec))) + return; + + if (!AddCallback (&ClientStateCallback, DamageClientCallback, 0)) + return; + + if ((extEntry = AddExtension(DAMAGE_NAME, XDamageNumberEvents, + XDamageNumberErrors, + ProcDamageDispatch, SProcDamageDispatch, + DamageResetProc, StandardMinorOpcode)) != 0) + { + DamageReqCode = (unsigned char)extEntry->base; + DamageEventBase = extEntry->eventBase; + EventSwapVector[DamageEventBase + XDamageNotify] = + (EventSwapPtr) SDamageNotifyEvent; + SetResourceTypeErrorValue(DamageExtType, extEntry->errorBase + BadDamage); + } +} -- cgit v1.2.3