From d3a71efeb0c30333230c38abd90d41782b70fab5 Mon Sep 17 00:00:00 2001 From: Adam Jackson Date: Thu, 7 Nov 2013 14:06:09 -0500 Subject: [PATCH] Merge Xinerama+{Damage,Render,Composite} fix series --- 0001-xinerama-Export-the-screen-region.patch | 42 ++ 0002-dix-Add-PostDispatchCallback.patch | 60 ++ 0003-damageext-Xineramify-v6.patch | 630 ++++++++++++++++++ ...posite-Fix-COW-creation-for-Xinerama.patch | 35 + ...miXSetPictureClipRegion-for-window-p.patch | 55 ++ ...es-Fix-PanoramiXSetWindowShapeRegion.patch | 50 ++ xorg-x11-server.spec | 13 +- 7 files changed, 884 insertions(+), 1 deletion(-) create mode 100644 0001-xinerama-Export-the-screen-region.patch create mode 100644 0002-dix-Add-PostDispatchCallback.patch create mode 100644 0003-damageext-Xineramify-v6.patch create mode 100644 0004-composite-Fix-COW-creation-for-Xinerama.patch create mode 100644 0005-fixes-Fix-PanoramiXSetPictureClipRegion-for-window-p.patch create mode 100644 0006-fixes-Fix-PanoramiXSetWindowShapeRegion.patch diff --git a/0001-xinerama-Export-the-screen-region.patch b/0001-xinerama-Export-the-screen-region.patch new file mode 100644 index 0000000..51f761b --- /dev/null +++ b/0001-xinerama-Export-the-screen-region.patch @@ -0,0 +1,42 @@ +From 7a9c524d0f68127baa0ced0a7f6b52b899a7cccb Mon Sep 17 00:00:00 2001 +From: Adam Jackson +Date: Tue, 29 Oct 2013 10:44:07 -0400 +Subject: [PATCH 1/6] xinerama: Export the screen region + +damageext wants this so it can intersect subtract requests against the +root window geometry. + +Signed-off-by: Adam Jackson +--- + Xext/panoramiX.c | 2 +- + Xext/panoramiXsrv.h | 1 + + 2 files changed, 2 insertions(+), 1 deletion(-) + +diff --git a/Xext/panoramiX.c b/Xext/panoramiX.c +index 2b3a570..15c38a9 100644 +--- a/Xext/panoramiX.c ++++ b/Xext/panoramiX.c +@@ -73,7 +73,7 @@ int PanoramiXPixWidth = 0; + int PanoramiXPixHeight = 0; + int PanoramiXNumScreens = 0; + +-static RegionRec PanoramiXScreenRegion = { {0, 0, 0, 0}, NULL }; ++_X_EXPORT RegionRec PanoramiXScreenRegion = { {0, 0, 0, 0}, NULL }; + + static int PanoramiXNumDepths; + static DepthPtr PanoramiXDepths; +diff --git a/Xext/panoramiXsrv.h b/Xext/panoramiXsrv.h +index 7c605fe..0fcde4f 100644 +--- a/Xext/panoramiXsrv.h ++++ b/Xext/panoramiXsrv.h +@@ -11,6 +11,7 @@ + extern _X_EXPORT int PanoramiXNumScreens; + extern _X_EXPORT int PanoramiXPixWidth; + extern _X_EXPORT int PanoramiXPixHeight; ++extern _X_EXPORT RegionRec PanoramiXScreenRegion; + + extern _X_EXPORT VisualID PanoramiXTranslateVisualID(int screen, VisualID orig); + extern _X_EXPORT void PanoramiXConsolidate(void); +-- +1.8.3.1 + diff --git a/0002-dix-Add-PostDispatchCallback.patch b/0002-dix-Add-PostDispatchCallback.patch new file mode 100644 index 0000000..ef32a97 --- /dev/null +++ b/0002-dix-Add-PostDispatchCallback.patch @@ -0,0 +1,60 @@ +From 13f334e3699d8ca1fe02d07b1cbff8a348c47e49 Mon Sep 17 00:00:00 2001 +From: Adam Jackson +Date: Wed, 2 Oct 2013 11:01:16 -0400 +Subject: [PATCH 2/6] dix: Add PostDispatchCallback + +This is required to Xineramify the Damage extension, since we need to +collect regions across screens. You can't quite use FlushCallback for +this since WriteEventsToClient can itself trigger FlushCallback and you +recurse. + +There are probably other cases where this would be useful though, for +example some of our abuse of BlockHandler may want to move to this +callback. + +Signed-off-by: Adam Jackson +--- + dix/dispatch.c | 5 ++++- + include/dixstruct.h | 1 + + 2 files changed, 5 insertions(+), 1 deletion(-) + +diff --git a/dix/dispatch.c b/dix/dispatch.c +index 4fecfea..53cabdf 100644 +--- a/dix/dispatch.c ++++ b/dix/dispatch.c +@@ -167,6 +167,7 @@ static int nextFreeClientID; /* always MIN free client ID */ + static int nClients; /* number of authorized clients */ + + CallbackListPtr ClientStateCallback; ++CallbackListPtr PostDispatchCallback; + + /* dispatchException & isItTimeToYield must be declared volatile since they + * are modified by signal handlers - otherwise optimizer may assume it doesn't +@@ -428,9 +429,11 @@ Dispatch(void) + result = BadLength; + else { + result = XaceHookDispatch(client, client->majorOp); +- if (result == Success) ++ if (result == Success) { + result = + (*client->requestVector[client->majorOp]) (client); ++ CallCallbacks(&PostDispatchCallback, &result); ++ } + XaceHookAuditEnd(client, result); + } + #ifdef XSERVER_DTRACE +diff --git a/include/dixstruct.h b/include/dixstruct.h +index 456e633..d55b047 100644 +--- a/include/dixstruct.h ++++ b/include/dixstruct.h +@@ -39,6 +39,7 @@ SOFTWARE. + */ + + extern _X_EXPORT CallbackListPtr ClientStateCallback; ++extern _X_EXPORT CallbackListPtr PostDispatchCallback; + + typedef struct { + ClientPtr client; +-- +1.8.3.1 + diff --git a/0003-damageext-Xineramify-v6.patch b/0003-damageext-Xineramify-v6.patch new file mode 100644 index 0000000..7f23b88 --- /dev/null +++ b/0003-damageext-Xineramify-v6.patch @@ -0,0 +1,630 @@ +From 728866dbc1246a04dc614fac94b81f6baed19959 Mon Sep 17 00:00:00 2001 +From: Adam Jackson +Date: Mon, 16 Sep 2013 15:17:26 -0400 +Subject: [PATCH 3/6] damageext: Xineramify (v6) + +v6: +- Clip window damages even more excruciatingly correctly + +Screen 0 holds the "real" damage for all drawable types; the window +report hooks for other screens look up screen 0 and pile on. Therefore +we don't need to wrap Subtract, though we do have to be careful how we +subtract since we need to clip to the (apparent) root window geometry. +The real compexity is the cleverness required for deferring writing the +events, but there's no getting around that. + +Add is probably (still) somewhat broken since it will only hit screen 0, +but Add really only exists for DRI1's sake, and DRI1 disables itself +with Xinerama enabled anyway. In the absence of a use case, I'm leaving +it unwrapped under Xinerama; if someone wants to define how it ought to +work, be my guest. + +Signed-off-by: Adam Jackson + +stuff +--- + Xext/panoramiX.c | 3 + + Xext/panoramiX.h | 3 + + damageext/damageext.c | 425 ++++++++++++++++++++++++++++++++++++++++++----- + damageext/damageextint.h | 4 + + 4 files changed, 390 insertions(+), 45 deletions(-) + +diff --git a/Xext/panoramiX.c b/Xext/panoramiX.c +index 15c38a9..ce0d072 100644 +--- a/Xext/panoramiX.c ++++ b/Xext/panoramiX.c +@@ -54,6 +54,7 @@ Equipment Corporation. + #include "resource.h" + #include "picturestr.h" + #include "xfixesint.h" ++#include "damageextint.h" + #ifdef COMPOSITE + #include "compint.h" + #endif +@@ -582,6 +583,7 @@ PanoramiXExtensionInit(void) + + PanoramiXRenderInit(); + PanoramiXFixesInit(); ++ PanoramiXDamageInit(); + #ifdef COMPOSITE + PanoramiXCompositeInit(); + #endif +@@ -887,6 +889,7 @@ PanoramiXResetProc(ExtensionEntry * extEntry) + + PanoramiXRenderReset(); + PanoramiXFixesReset(); ++ PanoramiXDamageReset(); + #ifdef COMPOSITE + PanoramiXCompositeReset (); + #endif +diff --git a/Xext/panoramiX.h b/Xext/panoramiX.h +index 6578dfa..b06fce4 100644 +--- a/Xext/panoramiX.h ++++ b/Xext/panoramiX.h +@@ -64,6 +64,9 @@ typedef struct { + struct { + Bool root; + } pict; ++ struct { ++ Bool queued; ++ } damage; + char raw_data[4]; + } u; + } PanoramiXRes; +diff --git a/damageext/damageext.c b/damageext/damageext.c +index 9521c26..7c86491 100644 +--- a/damageext/damageext.c ++++ b/damageext/damageext.c +@@ -1,5 +1,6 @@ + /* + * Copyright © 2002 Keith Packard ++ * Copyright 2013 Red Hat, Inc. + * + * Permission to use, copy, modify, distribute, and sell this software and its + * documentation for any purpose is hereby granted without fee, provided that +@@ -28,6 +29,15 @@ + #include "protocol-versions.h" + #include "extinit.h" + ++#ifdef PANORAMIX ++#include "panoramiX.h" ++#include "panoramiXsrv.h" ++ ++static RESTYPE XRT_DAMAGE; ++static int (*PanoramiXSaveDamageVector[XDamageNumberRequests]) (ClientPtr); ++ ++#endif ++ + static unsigned char DamageReqCode; + static int DamageEventBase; + static RESTYPE DamageExtType; +@@ -37,25 +47,61 @@ static DevPrivateKeyRec DamageClientPrivateKeyRec; + #define DamageClientPrivateKey (&DamageClientPrivateKeyRec) + + static void ++DamageNoteCritical(ClientPtr pClient) ++{ ++ DamageClientPtr pDamageClient = GetDamageClient(pClient); ++ ++ /* Composite extension marks clients with manual Subwindows as critical */ ++ if (pDamageClient->critical > 0) { ++ SetCriticalOutputPending(); ++ pClient->smart_priority = SMART_MAX_PRIORITY; ++ } ++} ++ ++static void ++damageGetGeometry(DrawablePtr draw, int *x, int *y, int *w, int *h) ++{ ++#ifdef PANORAMIX ++ if (!noPanoramiXExtension && draw->type == DRAWABLE_WINDOW) { ++ WindowPtr win = (WindowPtr)draw; ++ ++ if (!win->parent) { ++ *x = screenInfo.x; ++ *y = screenInfo.y; ++ *w = screenInfo.width; ++ *h = screenInfo.height; ++ return; ++ } ++ } ++#endif ++ ++ *x = draw->x; ++ *y = draw->y; ++ *w = draw->width; ++ *h = draw->height; ++} ++ ++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; ++ int i, x, y, w, h; ++ ++ damageGetGeometry(pDrawable, &x, &y, &w, &h); + + UpdateCurrentTimeIf(); + ev = (xDamageNotifyEvent) { + .type = DamageEventBase + XDamageNotify, + .level = pDamageExt->level, + .drawable = pDamageExt->drawable, +- .damage = pDamageExt->id, ++ .damage = pDamageExt->report_id, + .timestamp = currentTime.milliseconds, +- .geometry.x = pDrawable->x, +- .geometry.y = pDrawable->y, +- .geometry.width = pDrawable->width, +- .geometry.height = pDrawable->height ++ .geometry.x = x, ++ .geometry.y = y, ++ .geometry.width = w, ++ .geometry.height = h + }; + if (pBoxes) { + for (i = 0; i < nBoxes; i++) { +@@ -72,15 +118,12 @@ DamageExtNotify(DamageExtPtr pDamageExt, BoxPtr pBoxes, int nBoxes) + else { + ev.area.x = 0; + ev.area.y = 0; +- ev.area.width = pDrawable->width; +- ev.area.height = pDrawable->height; ++ ev.area.width = w; ++ ev.area.height = h; + 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; +- } ++ ++ DamageNoteCritical(pClient); + } + + static void +@@ -162,19 +205,55 @@ ProcDamageQueryVersion(ClientPtr client) + return Success; + } + ++static DamageExtPtr ++DamageExtCreate(DrawablePtr pDrawable, DamageReportLevel level, ++ ClientPtr client, XID id, XID drawable, XID report_id, ++ DamageReportFunc reportFunc) ++{ ++ DamageExtPtr pDamageExt = malloc(sizeof(DamageExtRec)); ++ if (!pDamageExt) ++ return NULL; ++ ++ pDamageExt->id = id; ++ pDamageExt->report_id = report_id; ++ pDamageExt->drawable = drawable; ++ pDamageExt->pDrawable = pDrawable; ++ pDamageExt->level = level; ++ pDamageExt->pClient = client; ++ pDamageExt->pDamage = DamageCreate(reportFunc, DamageExtDestroy, level, ++ FALSE, pDrawable->pScreen, pDamageExt); ++ if (!pDamageExt->pDamage) { ++ free(pDamageExt); ++ return NULL; ++ } ++ ++ if (!AddResource(id, DamageExtType, (pointer) pDamageExt)) ++ return NULL; ++ ++ DamageSetReportAfterOp(pDamageExt->pDamage, TRUE); ++ DamageRegister(pDrawable, pDamageExt->pDamage); ++ ++ if (pDrawable->type == DRAWABLE_WINDOW) { ++ RegionPtr pRegion = &((WindowPtr) pDrawable)->borderClip; ++ RegionTranslate(pRegion, -pDrawable->x, -pDrawable->y); ++ DamageReportDamage(pDamageExt->pDamage, pRegion); ++ RegionTranslate(pRegion, pDrawable->x, pDrawable->y); ++ } ++ ++ return pDamageExt; ++} ++ + static int +-ProcDamageCreate(ClientPtr client) ++doDamageCreate(ClientPtr client, XID reportDrawable, XID reportDamage, ++ DamageReportFunc reportFunc) + { + 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) +@@ -198,39 +277,25 @@ ProcDamageCreate(ClientPtr client) + return BadValue; + } + +- pDamageExt = malloc(sizeof(DamageExtRec)); ++ pDamageExt = DamageExtCreate(pDrawable, level, client, stuff->damage, ++ reportDrawable, reportDamage, reportFunc); + 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; +- RegionTranslate(pRegion, -pDrawable->x, -pDrawable->y); +- DamageReportDamage(pDamageExt->pDamage, pRegion); +- RegionTranslate(pRegion, pDrawable->x, pDrawable->y); +- } + + return Success; + } + + static int ++ProcDamageCreate(ClientPtr client) ++{ ++ REQUEST(xDamageCreateReq); ++ REQUEST_SIZE_MATCH(xDamageCreateReq); ++ LEGAL_NEW_RESOURCE(stuff->damage, client); ++ return doDamageCreate(client, stuff->drawable, stuff->damage, ++ DamageExtReport); ++} ++ ++static int + ProcDamageDestroy(ClientPtr client) + { + REQUEST(xDamageDestroyReq); +@@ -242,6 +307,88 @@ ProcDamageDestroy(ClientPtr client) + return Success; + } + ++#ifdef PANORAMIX ++static RegionPtr ++DamageExtSubtractWindowClip(DamageExtPtr pDamageExt) ++{ ++ WindowPtr win = (WindowPtr)pDamageExt->pDrawable; ++ PanoramiXRes *res = NULL; ++ RegionPtr ret; ++ int i; ++ ++ if (!win->parent) ++ return &PanoramiXScreenRegion; ++ ++ dixLookupResourceByType((void **)&res, win->drawable.id, XRT_WINDOW, ++ serverClient, DixReadAccess); ++ if (!res) ++ return NULL; ++ ++ ret = RegionCreate(NULL, 0); ++ if (!ret) ++ return NULL; ++ ++ FOR_NSCREENS_FORWARD(i) { ++ ScreenPtr screen; ++ if (Success != dixLookupWindow(&win, res->info[i].id, serverClient, ++ DixReadAccess)) ++ goto out; ++ ++ screen = win->drawable.pScreen; ++ ++ RegionTranslate(ret, -screen->x, -screen->y); ++ if (!RegionUnion(ret, ret, &win->borderClip)) ++ goto out; ++ RegionTranslate(ret, screen->x, screen->y); ++ } ++ ++ return ret; ++ ++out: ++ RegionDestroy(ret); ++ return NULL; ++} ++ ++static void ++DamageExtFreeWindowClip(RegionPtr reg) ++{ ++ if (reg != &PanoramiXScreenRegion) ++ RegionDestroy(reg); ++} ++#endif ++ ++/* ++ * DamageSubtract intersects with borderClip, so we must reconstruct the ++ * protocol's perspective of same... ++ */ ++static Bool ++DamageExtSubtract(DamageExtPtr pDamageExt, const RegionPtr pRegion) ++{ ++ DamagePtr pDamage = pDamageExt->pDamage; ++ ++#ifdef PANORAMIX ++ if (!noPanoramiXExtension) { ++ RegionPtr damage = DamageRegion(pDamage); ++ RegionSubtract(damage, damage, pRegion); ++ ++ if (pDamageExt->pDrawable->type == DRAWABLE_WINDOW) { ++ DrawablePtr pDraw = pDamageExt->pDrawable; ++ RegionPtr clip = DamageExtSubtractWindowClip(pDamageExt); ++ if (clip) { ++ RegionTranslate(clip, -pDraw->x, -pDraw->y); ++ RegionIntersect(damage, damage, clip); ++ RegionTranslate(clip, pDraw->x, pDraw->y); ++ DamageExtFreeWindowClip(clip); ++ } ++ } ++ ++ return RegionNotEmpty(damage); ++ } ++#endif ++ ++ return DamageSubtract(pDamage, pRegion); ++} ++ + static int + ProcDamageSubtract(ClientPtr client) + { +@@ -261,7 +408,7 @@ ProcDamageSubtract(ClientPtr client) + if (pRepair) { + if (pParts) + RegionIntersect(pParts, DamageRegion(pDamage), pRepair); +- if (DamageSubtract(pDamage, pRepair)) ++ if (DamageExtSubtract(pDamageExt, pRepair)) + DamageExtReport(pDamage, DamageRegion(pDamage), + (void *) pDamageExt); + } +@@ -271,6 +418,7 @@ ProcDamageSubtract(ClientPtr client) + DamageEmpty(pDamage); + } + } ++ + return Success; + } + +@@ -460,6 +608,188 @@ SDamageNotifyEvent(xDamageNotifyEvent * from, xDamageNotifyEvent * to) + cpswaps(from->geometry.height, to->geometry.height); + } + ++#ifdef PANORAMIX ++ ++static void ++damageDispatchCallback(CallbackListPtr *cbl, void *closure, void *unused) ++{ ++ DamageExtPtr pDamageExt = closure; ++ RegionPtr pRegion = DamageRegion(pDamageExt->pDamage); ++ PanoramiXRes *damage = NULL; ++ ++ DamageExtReport(pDamageExt->pDamage, pRegion, pDamageExt); ++ DeleteCallback(&PostDispatchCallback, damageDispatchCallback, pDamageExt); ++ ++ dixLookupResourceByType((void **)&damage, pDamageExt->id, XRT_DAMAGE, ++ serverClient, DixWriteAccess); ++ ++ if (damage) ++ damage->u.damage.queued = FALSE; ++} ++ ++/* for screen 0 */ ++static void ++PanoramiXDamageQueue(DamagePtr pDamage, RegionPtr pRegion, void *closure) ++{ ++ DamageExtPtr pDamageExt = closure; ++ PanoramiXRes *damage = NULL; ++ ++ /* happens on unmap? sigh xinerama */ ++ if (RegionNil(pRegion)) ++ return; ++ ++ dixLookupResourceByType((void **)&damage, pDamageExt->report_id, XRT_DAMAGE, ++ serverClient, DixWriteAccess); ++ ++ if (damage) { ++ if (!damage->u.damage.queued) { ++ AddCallback(&PostDispatchCallback, damageDispatchCallback, ++ pDamageExt); ++ damage->u.damage.queued = TRUE; ++ } ++ } ++ ++ DamageNoteCritical(pDamageExt->pClient); ++} ++ ++/* for screens 1 to n */ ++static void ++PanoramiXDamageAccumulate(DamagePtr pDamage, RegionPtr pRegion, void *closure) ++{ ++ DamageExtPtr pDamageExt = closure, pDamageExt0 = NULL; ++ PanoramiXRes *damage = NULL; ++ ++ /* happens on unmap? sigh xinerama */ ++ if (RegionNil(pRegion)) ++ return; ++ ++ dixLookupResourceByType((void **)&damage, pDamageExt->report_id, XRT_DAMAGE, ++ serverClient, DixWriteAccess); ++ ++ if (damage) { ++ dixLookupResourceByType((void **)&pDamageExt0, damage->info[0].id, ++ DamageExtType, serverClient, DixWriteAccess); ++ ++ if (pDamageExt0) { ++ DrawablePtr pDrawable = pDamageExt->pDrawable; ++ ScreenPtr pScreen = pDrawable->pScreen; ++ ++ if (pDrawable->type == DRAWABLE_WINDOW) { ++ WindowPtr pWin = (WindowPtr)pDrawable; ++ ++ if (!pWin->parent) ++ if (RegionNotEmpty(pRegion)) ++ RegionTranslate(pRegion, pScreen->x, pScreen->y); ++ } ++ ++ DamageReportDamage(pDamageExt0->pDamage, pRegion); ++ DamageEmpty(pDamageExt->pDamage); ++ } ++ } ++} ++ ++static int ++PanoramiXDamageCreate(ClientPtr client) ++{ ++ PanoramiXRes *draw, *damage; ++ int i, rc; ++ ++ REQUEST(xDamageCreateReq); ++ ++ REQUEST_SIZE_MATCH(xDamageCreateReq); ++ LEGAL_NEW_RESOURCE(stuff->damage, client); ++ rc = dixLookupResourceByClass((void **)&draw, stuff->drawable, XRC_DRAWABLE, ++ client, DixGetAttrAccess | DixReadAccess); ++ if (rc != Success) ++ return rc; ++ ++ if (!(damage = calloc(1, sizeof(PanoramiXRes)))) ++ return BadAlloc; ++ ++ damage->type = XRT_DAMAGE; ++ if (!AddResource(stuff->damage, XRT_DAMAGE, damage)) ++ return BadAlloc; ++ ++ /* pixmaps exist on all screens, so just watching screen 0 works */ ++ if (draw->type == XRT_PIXMAP) { ++ damage->info[0].id = stuff->damage; ++ ++ rc = PanoramiXSaveDamageVector[X_DamageCreate](client); ++ if (rc != Success) { ++ FreeResource(damage->info[0].id, None); ++ return rc; ++ } ++ } else { ++ rc = doDamageCreate(client, stuff->drawable, stuff->damage, ++ PanoramiXDamageQueue); ++ if (rc == Success) { ++ panoramix_setup_ids(damage, client, stuff->damage); ++ ++ FOR_NSCREENS_FORWARD_SKIP(i) { ++ stuff->damage = damage->info[i].id; ++ stuff->drawable = draw->info[i].id; ++ rc = doDamageCreate(client, draw->info[0].id, ++ damage->info[0].id, ++ PanoramiXDamageAccumulate); ++ if (rc != Success) ++ FreeResource(damage->info[0].id, None); ++ } ++ } else { ++ FreeResource(damage->info[0].id, None); ++ } ++ } ++ ++ return rc; ++} ++ ++static int ++PanoramiXDamageDestroy(ClientPtr client) ++{ ++ REQUEST(xDamageDestroyReq); ++ PanoramiXRes *damage; ++ int i, rc = Success; ++ ++ REQUEST_SIZE_MATCH(xDamageDestroyReq); ++ ++ rc = dixLookupResourceByType((void **)&damage, stuff->damage, XRT_DAMAGE, ++ client, DixDestroyAccess); ++ if (rc != Success) ++ return rc; ++ ++ FOR_NSCREENS_BACKWARD(i) { ++ stuff->damage = damage->info[i].id; ++ if (stuff->damage) { ++ rc = PanoramiXSaveDamageVector[X_DamageDestroy](client); ++ if (rc != Success) ++ break; ++ } ++ } ++ ++ return rc; ++} ++ ++void ++PanoramiXDamageInit(void) ++{ ++ XRT_DAMAGE = CreateNewResourceType(XineramaDeleteResource, ++ "XineramaDamage"); ++ ++ memcpy(PanoramiXSaveDamageVector, ProcDamageVector, ++ sizeof(ProcDamageVector)); ++ ++ ProcDamageVector[X_DamageCreate] = PanoramiXDamageCreate; ++ ProcDamageVector[X_DamageDestroy] = PanoramiXDamageDestroy; ++} ++ ++void ++PanoramiXDamageReset(void) ++{ ++ memcpy(ProcDamageVector, PanoramiXSaveDamageVector, ++ sizeof(ProcDamageVector)); ++} ++ ++#endif /* PANORAMIX */ ++ + void + DamageExtensionInit(void) + { +@@ -490,5 +820,10 @@ DamageExtensionInit(void) + (EventSwapPtr) SDamageNotifyEvent; + SetResourceTypeErrorValue(DamageExtType, + extEntry->errorBase + BadDamage); ++#ifdef PANORAMIX ++ if (XRT_DAMAGE) ++ SetResourceTypeErrorValue(XRT_DAMAGE, ++ extEntry->errorBase + BadDamage); ++#endif + } + } +diff --git a/damageext/damageextint.h b/damageext/damageextint.h +index 2723379..7319a1d 100644 +--- a/damageext/damageextint.h ++++ b/damageext/damageextint.h +@@ -54,6 +54,7 @@ typedef struct _DamageExt { + DamageReportLevel level; + ClientPtr pClient; + XID id; ++ XID report_id; + XID drawable; + } DamageExtRec, *DamageExtPtr; + +@@ -67,4 +68,7 @@ typedef struct _DamageExt { + void + DamageExtSetCritical(ClientPtr pClient, Bool critical); + ++void PanoramiXDamageInit(void); ++void PanoramiXDamageReset(void); ++ + #endif /* _DAMAGEEXTINT_H_ */ +-- +1.8.3.1 + diff --git a/0004-composite-Fix-COW-creation-for-Xinerama.patch b/0004-composite-Fix-COW-creation-for-Xinerama.patch new file mode 100644 index 0000000..fa492d3 --- /dev/null +++ b/0004-composite-Fix-COW-creation-for-Xinerama.patch @@ -0,0 +1,35 @@ +From cb020861deb8bfa91579de72f3860c445ed752d3 Mon Sep 17 00:00:00 2001 +From: Adam Jackson +Date: Thu, 7 Nov 2013 13:59:30 -0500 +Subject: [PATCH 4/6] composite: Fix COW creation for Xinerama + +Say you have two 800x600 screens left/right of each other. A window +that's 200x200 at +700+0 in protocol coordinate space will appear to be +at -100+0 in the coordinate space of the right hand screen. Put another +way: windows are in the coordinate space of their root window pixmap. + +We weren't doing this translation for the COW, so when rendering came in +to it you'd see the top-left chunk of the COW on all screens. Cool +effect and all, but wrong. + +Signed-off-by: Adam Jackson +--- + composite/compoverlay.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/composite/compoverlay.c b/composite/compoverlay.c +index d3cfaf0..575be42 100644 +--- a/composite/compoverlay.c ++++ b/composite/compoverlay.c +@@ -142,7 +142,7 @@ compCreateOverlayWindow(ScreenPtr pScreen) + #endif + + pWin = cs->pOverlayWin = +- CreateWindow(cs->overlayWid, pRoot, 0, 0, w, h, 0, ++ CreateWindow(cs->overlayWid, pRoot, -pScreen->x, -pScreen->y, w, h, 0, + InputOutput, CWBackPixmap | CWOverrideRedirect, &attrs[0], + pRoot->drawable.depth, + serverClient, pScreen->rootVisual, &result); +-- +1.8.3.1 + diff --git a/0005-fixes-Fix-PanoramiXSetPictureClipRegion-for-window-p.patch b/0005-fixes-Fix-PanoramiXSetPictureClipRegion-for-window-p.patch new file mode 100644 index 0000000..378b6ab --- /dev/null +++ b/0005-fixes-Fix-PanoramiXSetPictureClipRegion-for-window-p.patch @@ -0,0 +1,55 @@ +From b355ac5f3ab8cea52ebb61271247cb1cded6f9bf Mon Sep 17 00:00:00 2001 +From: Adam Jackson +Date: Mon, 4 Nov 2013 17:49:33 -0500 +Subject: [PATCH 5/6] fixes: Fix PanoramiXSetPictureClipRegion for window + pictures + +Windows in Xinerama are in the coordinate space of their root window +pixmap, not in protocol space. This fixes 'xcompmgr -n' when Xinerama +is active. + +Signed-off-by: Adam Jackson +--- + xfixes/region.c | 15 +++++++++++++++ + 1 file changed, 15 insertions(+) + +diff --git a/xfixes/region.c b/xfixes/region.c +index 0e9ca44..eb4a082 100644 +--- a/xfixes/region.c ++++ b/xfixes/region.c +@@ -886,6 +886,8 @@ PanoramiXFixesSetPictureClipRegion(ClientPtr client) + REQUEST(xXFixesSetPictureClipRegionReq); + int result = Success, j; + PanoramiXRes *pict; ++ PicturePtr pPicture; ++ RegionPtr reg = NULL; + + REQUEST_SIZE_MATCH(xXFixesSetPictureClipRegionReq); + +@@ -896,10 +898,23 @@ PanoramiXFixesSetPictureClipRegion(ClientPtr client) + return result; + } + ++ VERIFY_PICTURE(pPicture, stuff->picture, client, DixSetAttrAccess); ++ if (pPicture->pDrawable && pPicture->pDrawable->type == DRAWABLE_WINDOW) ++ VERIFY_REGION_OR_NONE(reg, stuff->region, client, DixReadAccess); ++ + FOR_NSCREENS_BACKWARD(j) { ++ ScreenPtr screen = screenInfo.screens[j]; + stuff->picture = pict->info[j].id; ++ ++ if (reg) ++ RegionTranslate(reg, -screen->x, -screen->y); ++ + result = + (*PanoramiXSaveXFixesVector[X_XFixesSetPictureClipRegion]) (client); ++ ++ if (reg) ++ RegionTranslate(reg, screen->x, screen->y); ++ + if (result != Success) + break; + } +-- +1.8.3.1 + diff --git a/0006-fixes-Fix-PanoramiXSetWindowShapeRegion.patch b/0006-fixes-Fix-PanoramiXSetWindowShapeRegion.patch new file mode 100644 index 0000000..f7cf0d5 --- /dev/null +++ b/0006-fixes-Fix-PanoramiXSetWindowShapeRegion.patch @@ -0,0 +1,50 @@ +From ad2ba329d91157cd5ad09d871d0d5a74998d2518 Mon Sep 17 00:00:00 2001 +From: Adam Jackson +Date: Mon, 4 Nov 2013 17:49:34 -0500 +Subject: [PATCH 6/6] fixes: Fix PanoramiXSetWindowShapeRegion + +Windows in Xinerama are in the coordinate space of their root window +pixmap, not in protocol space. + +Signed-off-by: Adam Jackson +--- + xfixes/region.c | 12 ++++++++++++ + 1 file changed, 12 insertions(+) + +diff --git a/xfixes/region.c b/xfixes/region.c +index eb4a082..752cef1 100644 +--- a/xfixes/region.c ++++ b/xfixes/region.c +@@ -857,6 +857,7 @@ PanoramiXFixesSetWindowShapeRegion(ClientPtr client) + { + int result = Success, j; + PanoramiXRes *win; ++ RegionPtr reg = NULL; + + REQUEST(xXFixesSetWindowShapeRegionReq); + +@@ -869,10 +870,21 @@ PanoramiXFixesSetWindowShapeRegion(ClientPtr client) + return result; + } + ++ VERIFY_REGION_OR_NONE(reg, stuff->region, client, DixReadAccess); ++ + FOR_NSCREENS_FORWARD(j) { ++ ScreenPtr screen = screenInfo.screens[j]; + stuff->dest = win->info[j].id; ++ ++ if (reg) ++ RegionTranslate(reg, -screen->x, -screen->y); ++ + result = + (*PanoramiXSaveXFixesVector[X_XFixesSetWindowShapeRegion]) (client); ++ ++ if (reg) ++ RegionTranslate(reg, screen->x, screen->y); ++ + if (result != Success) + break; + } +-- +1.8.3.1 + diff --git a/xorg-x11-server.spec b/xorg-x11-server.spec index 5b3b78c..9fd164c 100644 --- a/xorg-x11-server.spec +++ b/xorg-x11-server.spec @@ -42,7 +42,7 @@ Summary: X.Org X11 X server Name: xorg-x11-server Version: 1.14.99.901 -Release: 2%{?gitdate:.%{gitdate}}%{dist} +Release: 3%{?gitdate:.%{gitdate}}%{dist} URL: http://www.x.org License: MIT Group: User Interface/X @@ -159,6 +159,14 @@ Patch9002: 0001-xwayland-Just-send-the-bounding-box-of-the-damage.patch # submitted: http://lists.x.org/archives/xorg-devel/2013-November/038768.html Patch9003: 0001-present-Don-t-try-to-initialize-when-building-withou.patch +# also submitted +Patch9011: 0001-xinerama-Export-the-screen-region.patch +Patch9012: 0002-dix-Add-PostDispatchCallback.patch +Patch9013: 0003-damageext-Xineramify-v6.patch +Patch9014: 0004-composite-Fix-COW-creation-for-Xinerama.patch +Patch9015: 0005-fixes-Fix-PanoramiXSetPictureClipRegion-for-window-p.patch +Patch9016: 0006-fixes-Fix-PanoramiXSetWindowShapeRegion.patch + %global moduledir %{_libdir}/xorg/modules %global drimoduledir %{_libdir}/dri %global sdkdir %{_includedir}/xorg @@ -654,6 +662,9 @@ rm -rf $RPM_BUILD_ROOT %{xserver_source_dir} %changelog +* Thu Nov 07 2013 Adam Jackson 1.14.99.901-3 +- Merge Xinerama+{Damage,Render,Composite} fix series + * Thu Nov 07 2013 Adam Jackson 1.14.99.901-2 - Fix build with --disable-present