Blame SOURCES/0003-damageext-Xineramify-v6.patch

70130e
From 728866dbc1246a04dc614fac94b81f6baed19959 Mon Sep 17 00:00:00 2001
70130e
From: Adam Jackson <ajax@redhat.com>
70130e
Date: Mon, 16 Sep 2013 15:17:26 -0400
70130e
Subject: [PATCH 3/6] damageext: Xineramify (v6)
70130e
70130e
v6:
70130e
- Clip window damages even more excruciatingly correctly
70130e
70130e
Screen 0 holds the "real" damage for all drawable types; the window
70130e
report hooks for other screens look up screen 0 and pile on.  Therefore
70130e
we don't need to wrap Subtract, though we do have to be careful how we
70130e
subtract since we need to clip to the (apparent) root window geometry.
70130e
The real compexity is the cleverness required for deferring writing the
70130e
events, but there's no getting around that.
70130e
70130e
Add is probably (still) somewhat broken since it will only hit screen 0,
70130e
but Add really only exists for DRI1's sake, and DRI1 disables itself
70130e
with Xinerama enabled anyway.  In the absence of a use case, I'm leaving
70130e
it unwrapped under Xinerama; if someone wants to define how it ought to
70130e
work, be my guest.
70130e
70130e
Signed-off-by: Adam Jackson <ajax@redhat.com>
70130e
70130e
stuff
70130e
---
70130e
 Xext/panoramiX.c         |   3 +
70130e
 Xext/panoramiX.h         |   3 +
70130e
 damageext/damageext.c    | 425 ++++++++++++++++++++++++++++++++++++++++++-----
70130e
 damageext/damageextint.h |   4 +
70130e
 4 files changed, 390 insertions(+), 45 deletions(-)
70130e
70130e
diff --git a/Xext/panoramiX.c b/Xext/panoramiX.c
70130e
index 15c38a9..ce0d072 100644
70130e
--- a/Xext/panoramiX.c
70130e
+++ b/Xext/panoramiX.c
70130e
@@ -54,6 +54,7 @@ Equipment Corporation.
70130e
 #include "resource.h"
70130e
 #include "picturestr.h"
70130e
 #include "xfixesint.h"
70130e
+#include "damageextint.h"
70130e
 #ifdef COMPOSITE
70130e
 #include "compint.h"
70130e
 #endif
70130e
@@ -582,6 +583,7 @@ PanoramiXExtensionInit(void)
70130e
 
70130e
     PanoramiXRenderInit();
70130e
     PanoramiXFixesInit();
70130e
+    PanoramiXDamageInit();
70130e
 #ifdef COMPOSITE
70130e
     PanoramiXCompositeInit();
70130e
 #endif
70130e
@@ -887,6 +889,7 @@ PanoramiXResetProc(ExtensionEntry * extEntry)
70130e
 
70130e
     PanoramiXRenderReset();
70130e
     PanoramiXFixesReset();
70130e
+    PanoramiXDamageReset();
70130e
 #ifdef COMPOSITE
70130e
     PanoramiXCompositeReset ();
70130e
 #endif
70130e
diff --git a/Xext/panoramiX.h b/Xext/panoramiX.h
70130e
index 6578dfa..b06fce4 100644
70130e
--- a/Xext/panoramiX.h
70130e
+++ b/Xext/panoramiX.h
70130e
@@ -64,6 +64,9 @@ typedef struct {
70130e
         struct {
70130e
             Bool root;
70130e
         } pict;
70130e
+        struct {
70130e
+            Bool queued;
70130e
+        } damage;
70130e
         char raw_data[4];
70130e
     } u;
70130e
 } PanoramiXRes;
70130e
diff --git a/damageext/damageext.c b/damageext/damageext.c
70130e
index 9521c26..7c86491 100644
70130e
--- a/damageext/damageext.c
70130e
+++ b/damageext/damageext.c
70130e
@@ -1,5 +1,6 @@
70130e
 /*
70130e
  * Copyright © 2002 Keith Packard
70130e
+ * Copyright 2013 Red Hat, Inc.
70130e
  *
70130e
  * Permission to use, copy, modify, distribute, and sell this software and its
70130e
  * documentation for any purpose is hereby granted without fee, provided that
70130e
@@ -28,6 +29,15 @@
70130e
 #include "protocol-versions.h"
70130e
 #include "extinit.h"
70130e
 
70130e
+#ifdef PANORAMIX
70130e
+#include "panoramiX.h"
70130e
+#include "panoramiXsrv.h"
70130e
+
70130e
+static RESTYPE XRT_DAMAGE;
70130e
+static int (*PanoramiXSaveDamageVector[XDamageNumberRequests]) (ClientPtr);
70130e
+
70130e
+#endif
70130e
+
70130e
 static unsigned char DamageReqCode;
70130e
 static int DamageEventBase;
70130e
 static RESTYPE DamageExtType;
70130e
@@ -37,25 +47,61 @@ static DevPrivateKeyRec DamageClientPrivateKeyRec;
70130e
 #define DamageClientPrivateKey (&DamageClientPrivateKeyRec)
70130e
 
70130e
 static void
70130e
+DamageNoteCritical(ClientPtr pClient)
70130e
+{
70130e
+    DamageClientPtr pDamageClient = GetDamageClient(pClient);
70130e
+
70130e
+    /* Composite extension marks clients with manual Subwindows as critical */
70130e
+    if (pDamageClient->critical > 0) {
70130e
+        SetCriticalOutputPending();
70130e
+        pClient->smart_priority = SMART_MAX_PRIORITY;
70130e
+    }
70130e
+}
70130e
+
70130e
+static void
70130e
+damageGetGeometry(DrawablePtr draw, int *x, int *y, int *w, int *h)
70130e
+{
70130e
+#ifdef PANORAMIX
70130e
+    if (!noPanoramiXExtension && draw->type == DRAWABLE_WINDOW) {
70130e
+        WindowPtr win = (WindowPtr)draw;
70130e
+
70130e
+        if (!win->parent) {
70130e
+            *x = screenInfo.x;
70130e
+            *y = screenInfo.y;
70130e
+            *w = screenInfo.width;
70130e
+            *h = screenInfo.height;
70130e
+            return;
70130e
+        }
70130e
+    }
70130e
+#endif
70130e
+
70130e
+    *x = draw->x;
70130e
+    *y = draw->y;
70130e
+    *w = draw->width;
70130e
+    *h = draw->height;
70130e
+}
70130e
+
70130e
+static void
70130e
 DamageExtNotify(DamageExtPtr pDamageExt, BoxPtr pBoxes, int nBoxes)
70130e
 {
70130e
     ClientPtr pClient = pDamageExt->pClient;
70130e
-    DamageClientPtr pDamageClient = GetDamageClient(pClient);
70130e
     DrawablePtr pDrawable = pDamageExt->pDrawable;
70130e
     xDamageNotifyEvent ev;
70130e
-    int i;
70130e
+    int i, x, y, w, h;
70130e
+
70130e
+    damageGetGeometry(pDrawable, &x, &y, &w, &h);
70130e
 
70130e
     UpdateCurrentTimeIf();
70130e
     ev = (xDamageNotifyEvent) {
70130e
         .type = DamageEventBase + XDamageNotify,
70130e
         .level = pDamageExt->level,
70130e
         .drawable = pDamageExt->drawable,
70130e
-        .damage = pDamageExt->id,
70130e
+        .damage = pDamageExt->report_id,
70130e
         .timestamp = currentTime.milliseconds,
70130e
-        .geometry.x = pDrawable->x,
70130e
-        .geometry.y = pDrawable->y,
70130e
-        .geometry.width = pDrawable->width,
70130e
-        .geometry.height = pDrawable->height
70130e
+        .geometry.x = x,
70130e
+        .geometry.y = y,
70130e
+        .geometry.width = w,
70130e
+        .geometry.height = h
70130e
     };
70130e
     if (pBoxes) {
70130e
         for (i = 0; i < nBoxes; i++) {
70130e
@@ -72,15 +118,12 @@ DamageExtNotify(DamageExtPtr pDamageExt, BoxPtr pBoxes, int nBoxes)
70130e
     else {
70130e
         ev.area.x = 0;
70130e
         ev.area.y = 0;
70130e
-        ev.area.width = pDrawable->width;
70130e
-        ev.area.height = pDrawable->height;
70130e
+        ev.area.width = w;
70130e
+        ev.area.height = h;
70130e
         WriteEventsToClient(pClient, 1, (xEvent *) &ev;;
70130e
     }
70130e
-    /* Composite extension marks clients with manual Subwindows as critical */
70130e
-    if (pDamageClient->critical > 0) {
70130e
-        SetCriticalOutputPending();
70130e
-        pClient->smart_priority = SMART_MAX_PRIORITY;
70130e
-    }
70130e
+
70130e
+    DamageNoteCritical(pClient);
70130e
 }
70130e
 
70130e
 static void
70130e
@@ -162,19 +205,55 @@ ProcDamageQueryVersion(ClientPtr client)
70130e
     return Success;
70130e
 }
70130e
 
70130e
+static DamageExtPtr
70130e
+DamageExtCreate(DrawablePtr pDrawable, DamageReportLevel level,
70130e
+                ClientPtr client, XID id, XID drawable, XID report_id,
70130e
+                DamageReportFunc reportFunc)
70130e
+{
70130e
+    DamageExtPtr pDamageExt = malloc(sizeof(DamageExtRec));
70130e
+    if (!pDamageExt)
70130e
+        return NULL;
70130e
+
70130e
+    pDamageExt->id = id;
70130e
+    pDamageExt->report_id = report_id;
70130e
+    pDamageExt->drawable = drawable;
70130e
+    pDamageExt->pDrawable = pDrawable;
70130e
+    pDamageExt->level = level;
70130e
+    pDamageExt->pClient = client;
70130e
+    pDamageExt->pDamage = DamageCreate(reportFunc, DamageExtDestroy, level,
70130e
+                                       FALSE, pDrawable->pScreen, pDamageExt);
70130e
+    if (!pDamageExt->pDamage) {
70130e
+        free(pDamageExt);
70130e
+        return NULL;
70130e
+    }
70130e
+
70130e
+    if (!AddResource(id, DamageExtType, (pointer) pDamageExt))
70130e
+        return NULL;
70130e
+
70130e
+    DamageSetReportAfterOp(pDamageExt->pDamage, TRUE);
70130e
+    DamageRegister(pDrawable, pDamageExt->pDamage);
70130e
+
70130e
+    if (pDrawable->type == DRAWABLE_WINDOW) {
70130e
+        RegionPtr pRegion = &((WindowPtr) pDrawable)->borderClip;
70130e
+        RegionTranslate(pRegion, -pDrawable->x, -pDrawable->y);
70130e
+        DamageReportDamage(pDamageExt->pDamage, pRegion);
70130e
+        RegionTranslate(pRegion, pDrawable->x, pDrawable->y);
70130e
+    }
70130e
+
70130e
+    return pDamageExt;
70130e
+}
70130e
+
70130e
 static int
70130e
-ProcDamageCreate(ClientPtr client)
70130e
+doDamageCreate(ClientPtr client, XID reportDrawable, XID reportDamage,
70130e
+               DamageReportFunc reportFunc)
70130e
 {
70130e
     DrawablePtr pDrawable;
70130e
     DamageExtPtr pDamageExt;
70130e
     DamageReportLevel level;
70130e
-    RegionPtr pRegion;
70130e
     int rc;
70130e
 
70130e
     REQUEST(xDamageCreateReq);
70130e
 
70130e
-    REQUEST_SIZE_MATCH(xDamageCreateReq);
70130e
-    LEGAL_NEW_RESOURCE(stuff->damage, client);
70130e
     rc = dixLookupDrawable(&pDrawable, stuff->drawable, client, 0,
70130e
                            DixGetAttrAccess | DixReadAccess);
70130e
     if (rc != Success)
70130e
@@ -198,39 +277,25 @@ ProcDamageCreate(ClientPtr client)
70130e
         return BadValue;
70130e
     }
70130e
 
70130e
-    pDamageExt = malloc(sizeof(DamageExtRec));
70130e
+    pDamageExt = DamageExtCreate(pDrawable, level, client, stuff->damage,
70130e
+                                 reportDrawable, reportDamage, reportFunc);
70130e
     if (!pDamageExt)
70130e
         return BadAlloc;
70130e
-    pDamageExt->id = stuff->damage;
70130e
-    pDamageExt->drawable = stuff->drawable;
70130e
-    pDamageExt->pDrawable = pDrawable;
70130e
-    pDamageExt->level = level;
70130e
-    pDamageExt->pClient = client;
70130e
-    pDamageExt->pDamage = DamageCreate(DamageExtReport,
70130e
-                                       DamageExtDestroy,
70130e
-                                       level,
70130e
-                                       FALSE, pDrawable->pScreen, pDamageExt);
70130e
-    if (!pDamageExt->pDamage) {
70130e
-        free(pDamageExt);
70130e
-        return BadAlloc;
70130e
-    }
70130e
-    if (!AddResource(stuff->damage, DamageExtType, (pointer) pDamageExt))
70130e
-        return BadAlloc;
70130e
-
70130e
-    DamageSetReportAfterOp(pDamageExt->pDamage, TRUE);
70130e
-    DamageRegister(pDamageExt->pDrawable, pDamageExt->pDamage);
70130e
-
70130e
-    if (pDrawable->type == DRAWABLE_WINDOW) {
70130e
-        pRegion = &((WindowPtr) pDrawable)->borderClip;
70130e
-        RegionTranslate(pRegion, -pDrawable->x, -pDrawable->y);
70130e
-        DamageReportDamage(pDamageExt->pDamage, pRegion);
70130e
-        RegionTranslate(pRegion, pDrawable->x, pDrawable->y);
70130e
-    }
70130e
 
70130e
     return Success;
70130e
 }
70130e
 
70130e
 static int
70130e
+ProcDamageCreate(ClientPtr client)
70130e
+{
70130e
+    REQUEST(xDamageCreateReq);
70130e
+    REQUEST_SIZE_MATCH(xDamageCreateReq);
70130e
+    LEGAL_NEW_RESOURCE(stuff->damage, client);
70130e
+    return doDamageCreate(client, stuff->drawable, stuff->damage,
70130e
+                          DamageExtReport);
70130e
+}
70130e
+
70130e
+static int
70130e
 ProcDamageDestroy(ClientPtr client)
70130e
 {
70130e
     REQUEST(xDamageDestroyReq);
70130e
@@ -242,6 +307,88 @@ ProcDamageDestroy(ClientPtr client)
70130e
     return Success;
70130e
 }
70130e
 
70130e
+#ifdef PANORAMIX
70130e
+static RegionPtr
70130e
+DamageExtSubtractWindowClip(DamageExtPtr pDamageExt)
70130e
+{
70130e
+    WindowPtr win = (WindowPtr)pDamageExt->pDrawable;
70130e
+    PanoramiXRes *res = NULL;
70130e
+    RegionPtr ret;
70130e
+    int i;
70130e
+
70130e
+    if (!win->parent)
70130e
+        return &PanoramiXScreenRegion;
70130e
+
70130e
+    dixLookupResourceByType((void **)&res, win->drawable.id, XRT_WINDOW,
70130e
+                            serverClient, DixReadAccess);
70130e
+    if (!res)
70130e
+        return NULL;
70130e
+
70130e
+    ret = RegionCreate(NULL, 0);
70130e
+    if (!ret)
70130e
+        return NULL;
70130e
+
70130e
+    FOR_NSCREENS_FORWARD(i) {
70130e
+        ScreenPtr screen;
70130e
+        if (Success != dixLookupWindow(&win, res->info[i].id, serverClient,
70130e
+                                       DixReadAccess))
70130e
+            goto out;
70130e
+
70130e
+        screen = win->drawable.pScreen;
70130e
+
70130e
+        RegionTranslate(ret, -screen->x, -screen->y);
70130e
+        if (!RegionUnion(ret, ret, &win->borderClip))
70130e
+            goto out;
70130e
+        RegionTranslate(ret, screen->x, screen->y);
70130e
+    }
70130e
+
70130e
+    return ret;
70130e
+
70130e
+out:
70130e
+    RegionDestroy(ret);
70130e
+    return NULL;
70130e
+}
70130e
+
70130e
+static void
70130e
+DamageExtFreeWindowClip(RegionPtr reg)
70130e
+{
70130e
+    if (reg != &PanoramiXScreenRegion)
70130e
+        RegionDestroy(reg);
70130e
+}
70130e
+#endif
70130e
+
70130e
+/*
70130e
+ * DamageSubtract intersects with borderClip, so we must reconstruct the
70130e
+ * protocol's perspective of same...
70130e
+ */
70130e
+static Bool
70130e
+DamageExtSubtract(DamageExtPtr pDamageExt, const RegionPtr pRegion)
70130e
+{
70130e
+    DamagePtr pDamage = pDamageExt->pDamage;
70130e
+
70130e
+#ifdef PANORAMIX
70130e
+    if (!noPanoramiXExtension) {
70130e
+        RegionPtr damage = DamageRegion(pDamage);
70130e
+        RegionSubtract(damage, damage, pRegion);
70130e
+
70130e
+        if (pDamageExt->pDrawable->type == DRAWABLE_WINDOW) {
70130e
+            DrawablePtr pDraw = pDamageExt->pDrawable;
70130e
+            RegionPtr clip = DamageExtSubtractWindowClip(pDamageExt);
70130e
+            if (clip) {
70130e
+                RegionTranslate(clip, -pDraw->x, -pDraw->y);
70130e
+                RegionIntersect(damage, damage, clip);
70130e
+                RegionTranslate(clip, pDraw->x, pDraw->y);
70130e
+                DamageExtFreeWindowClip(clip);
70130e
+            }
70130e
+        }
70130e
+
70130e
+        return RegionNotEmpty(damage);
70130e
+    }
70130e
+#endif
70130e
+
70130e
+    return DamageSubtract(pDamage, pRegion);
70130e
+}
70130e
+
70130e
 static int
70130e
 ProcDamageSubtract(ClientPtr client)
70130e
 {
70130e
@@ -261,7 +408,7 @@ ProcDamageSubtract(ClientPtr client)
70130e
         if (pRepair) {
70130e
             if (pParts)
70130e
                 RegionIntersect(pParts, DamageRegion(pDamage), pRepair);
70130e
-            if (DamageSubtract(pDamage, pRepair))
70130e
+            if (DamageExtSubtract(pDamageExt, pRepair))
70130e
                 DamageExtReport(pDamage, DamageRegion(pDamage),
70130e
                                 (void *) pDamageExt);
70130e
         }
70130e
@@ -271,6 +418,7 @@ ProcDamageSubtract(ClientPtr client)
70130e
             DamageEmpty(pDamage);
70130e
         }
70130e
     }
70130e
+
70130e
     return Success;
70130e
 }
70130e
 
70130e
@@ -460,6 +608,188 @@ SDamageNotifyEvent(xDamageNotifyEvent * from, xDamageNotifyEvent * to)
70130e
     cpswaps(from->geometry.height, to->geometry.height);
70130e
 }
70130e
 
70130e
+#ifdef PANORAMIX
70130e
+
70130e
+static void
70130e
+damageDispatchCallback(CallbackListPtr *cbl, void *closure, void *unused)
70130e
+{
70130e
+    DamageExtPtr pDamageExt = closure;
70130e
+    RegionPtr pRegion = DamageRegion(pDamageExt->pDamage);
70130e
+    PanoramiXRes *damage = NULL;
70130e
+
70130e
+    DamageExtReport(pDamageExt->pDamage, pRegion, pDamageExt);
70130e
+    DeleteCallback(&PostDispatchCallback, damageDispatchCallback, pDamageExt);
70130e
+
70130e
+    dixLookupResourceByType((void **)&damage, pDamageExt->id, XRT_DAMAGE,
70130e
+                            serverClient, DixWriteAccess);
70130e
+
70130e
+    if (damage)
70130e
+        damage->u.damage.queued = FALSE;
70130e
+}
70130e
+
70130e
+/* for screen 0 */
70130e
+static void
70130e
+PanoramiXDamageQueue(DamagePtr pDamage, RegionPtr pRegion, void *closure)
70130e
+{
70130e
+    DamageExtPtr pDamageExt = closure;
70130e
+    PanoramiXRes *damage = NULL;
70130e
+
70130e
+    /* happens on unmap? sigh xinerama */
70130e
+    if (RegionNil(pRegion))
70130e
+        return;
70130e
+
70130e
+    dixLookupResourceByType((void **)&damage, pDamageExt->report_id, XRT_DAMAGE,
70130e
+                            serverClient, DixWriteAccess);
70130e
+
70130e
+    if (damage) {
70130e
+        if (!damage->u.damage.queued) {
70130e
+            AddCallback(&PostDispatchCallback, damageDispatchCallback,
70130e
+                        pDamageExt);
70130e
+            damage->u.damage.queued = TRUE;
70130e
+        }
70130e
+    }
70130e
+
70130e
+    DamageNoteCritical(pDamageExt->pClient);
70130e
+}
70130e
+
70130e
+/* for screens 1 to n */
70130e
+static void
70130e
+PanoramiXDamageAccumulate(DamagePtr pDamage, RegionPtr pRegion, void *closure)
70130e
+{
70130e
+    DamageExtPtr pDamageExt = closure, pDamageExt0 = NULL;
70130e
+    PanoramiXRes *damage = NULL;
70130e
+
70130e
+    /* happens on unmap? sigh xinerama */
70130e
+    if (RegionNil(pRegion))
70130e
+        return;
70130e
+
70130e
+    dixLookupResourceByType((void **)&damage, pDamageExt->report_id, XRT_DAMAGE,
70130e
+                            serverClient, DixWriteAccess);
70130e
+
70130e
+    if (damage) {
70130e
+        dixLookupResourceByType((void **)&pDamageExt0, damage->info[0].id,
70130e
+                                DamageExtType, serverClient, DixWriteAccess);
70130e
+
70130e
+        if (pDamageExt0) {
70130e
+            DrawablePtr pDrawable = pDamageExt->pDrawable;
70130e
+            ScreenPtr pScreen = pDrawable->pScreen;
70130e
+
70130e
+            if (pDrawable->type == DRAWABLE_WINDOW) {
70130e
+                WindowPtr pWin = (WindowPtr)pDrawable;
70130e
+
70130e
+                if (!pWin->parent)
70130e
+                    if (RegionNotEmpty(pRegion))
70130e
+                        RegionTranslate(pRegion, pScreen->x, pScreen->y);
70130e
+            }
70130e
+
70130e
+            DamageReportDamage(pDamageExt0->pDamage, pRegion);
70130e
+            DamageEmpty(pDamageExt->pDamage);
70130e
+        }
70130e
+    }
70130e
+}
70130e
+
70130e
+static int
70130e
+PanoramiXDamageCreate(ClientPtr client)
70130e
+{
70130e
+    PanoramiXRes *draw, *damage;
70130e
+    int i, rc;
70130e
+
70130e
+    REQUEST(xDamageCreateReq);
70130e
+
70130e
+    REQUEST_SIZE_MATCH(xDamageCreateReq);
70130e
+    LEGAL_NEW_RESOURCE(stuff->damage, client);
70130e
+    rc = dixLookupResourceByClass((void **)&draw, stuff->drawable, XRC_DRAWABLE,
70130e
+                                  client, DixGetAttrAccess | DixReadAccess);
70130e
+    if (rc != Success)
70130e
+        return rc;
70130e
+
70130e
+    if (!(damage = calloc(1, sizeof(PanoramiXRes))))
70130e
+        return BadAlloc;
70130e
+
70130e
+    damage->type = XRT_DAMAGE;
70130e
+    if (!AddResource(stuff->damage, XRT_DAMAGE, damage))
70130e
+        return BadAlloc;
70130e
+
70130e
+    /* pixmaps exist on all screens, so just watching screen 0 works */
70130e
+    if (draw->type == XRT_PIXMAP) {
70130e
+        damage->info[0].id = stuff->damage;
70130e
+
70130e
+        rc = PanoramiXSaveDamageVector[X_DamageCreate](client);
70130e
+        if (rc != Success) {
70130e
+            FreeResource(damage->info[0].id, None);
70130e
+            return rc;
70130e
+        }
70130e
+    } else {
70130e
+        rc = doDamageCreate(client, stuff->drawable, stuff->damage,
70130e
+                            PanoramiXDamageQueue);
70130e
+        if (rc == Success) {
70130e
+            panoramix_setup_ids(damage, client, stuff->damage);
70130e
+
70130e
+            FOR_NSCREENS_FORWARD_SKIP(i) {
70130e
+                stuff->damage = damage->info[i].id;
70130e
+                stuff->drawable = draw->info[i].id;
70130e
+                rc = doDamageCreate(client, draw->info[0].id,
70130e
+                                    damage->info[0].id,
70130e
+                                    PanoramiXDamageAccumulate);
70130e
+                if (rc != Success)
70130e
+                    FreeResource(damage->info[0].id, None);
70130e
+            }
70130e
+        } else {
70130e
+            FreeResource(damage->info[0].id, None);
70130e
+        }
70130e
+    }
70130e
+
70130e
+    return rc;
70130e
+}
70130e
+
70130e
+static int
70130e
+PanoramiXDamageDestroy(ClientPtr client)
70130e
+{
70130e
+    REQUEST(xDamageDestroyReq);
70130e
+    PanoramiXRes *damage;
70130e
+    int i, rc = Success;
70130e
+
70130e
+    REQUEST_SIZE_MATCH(xDamageDestroyReq);
70130e
+
70130e
+    rc = dixLookupResourceByType((void **)&damage, stuff->damage, XRT_DAMAGE,
70130e
+                                 client, DixDestroyAccess);
70130e
+    if (rc != Success)
70130e
+        return rc;
70130e
+
70130e
+    FOR_NSCREENS_BACKWARD(i) {
70130e
+        stuff->damage = damage->info[i].id;
70130e
+        if (stuff->damage) {
70130e
+            rc = PanoramiXSaveDamageVector[X_DamageDestroy](client);
70130e
+            if (rc != Success)
70130e
+                break;
70130e
+        }
70130e
+    }
70130e
+
70130e
+    return rc;
70130e
+}
70130e
+
70130e
+void
70130e
+PanoramiXDamageInit(void)
70130e
+{
70130e
+    XRT_DAMAGE = CreateNewResourceType(XineramaDeleteResource,
70130e
+                                       "XineramaDamage");
70130e
+
70130e
+    memcpy(PanoramiXSaveDamageVector, ProcDamageVector,
70130e
+           sizeof(ProcDamageVector));
70130e
+
70130e
+    ProcDamageVector[X_DamageCreate] = PanoramiXDamageCreate;
70130e
+    ProcDamageVector[X_DamageDestroy] = PanoramiXDamageDestroy;
70130e
+}
70130e
+
70130e
+void
70130e
+PanoramiXDamageReset(void)
70130e
+{
70130e
+    memcpy(ProcDamageVector, PanoramiXSaveDamageVector,
70130e
+           sizeof(ProcDamageVector));
70130e
+}
70130e
+
70130e
+#endif /* PANORAMIX */
70130e
+
70130e
 void
70130e
 DamageExtensionInit(void)
70130e
 {
70130e
@@ -490,5 +820,10 @@ DamageExtensionInit(void)
70130e
             (EventSwapPtr) SDamageNotifyEvent;
70130e
         SetResourceTypeErrorValue(DamageExtType,
70130e
                                   extEntry->errorBase + BadDamage);
70130e
+#ifdef PANORAMIX
70130e
+        if (XRT_DAMAGE)
70130e
+            SetResourceTypeErrorValue(XRT_DAMAGE,
70130e
+                                      extEntry->errorBase + BadDamage);
70130e
+#endif
70130e
     }
70130e
 }
70130e
diff --git a/damageext/damageextint.h b/damageext/damageextint.h
70130e
index 2723379..7319a1d 100644
70130e
--- a/damageext/damageextint.h
70130e
+++ b/damageext/damageextint.h
70130e
@@ -54,6 +54,7 @@ typedef struct _DamageExt {
70130e
     DamageReportLevel level;
70130e
     ClientPtr pClient;
70130e
     XID id;
70130e
+    XID report_id;
70130e
     XID drawable;
70130e
 } DamageExtRec, *DamageExtPtr;
70130e
 
70130e
@@ -67,4 +68,7 @@ typedef struct _DamageExt {
70130e
 void
70130e
  DamageExtSetCritical(ClientPtr pClient, Bool critical);
70130e
 
70130e
+void PanoramiXDamageInit(void);
70130e
+void PanoramiXDamageReset(void);
70130e
+
70130e
 #endif                          /* _DAMAGEEXTINT_H_ */
70130e
-- 
70130e
1.8.3.1
70130e