summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Xext/shape.c95
-rw-r--r--dix/dispatch.c6
-rw-r--r--dix/events.c37
-rw-r--r--dix/window.c13
-rw-r--r--include/windowstr.h2
-rwxr-xr-xxfixes/region.c31
6 files changed, 144 insertions, 40 deletions
diff --git a/Xext/shape.c b/Xext/shape.c
index 1e8cdb1bd..50a403443 100644
--- a/Xext/shape.c
+++ b/Xext/shape.c
@@ -320,7 +320,6 @@ ProcShapeRectangles (client)
RegionPtr srcRgn;
RegionPtr *destRgn;
CreateDftPtr createDefault;
- int destBounding;
REQUEST_AT_LEAST_SIZE (xShapeRectanglesReq);
UpdateCurrentTime();
@@ -329,13 +328,14 @@ ProcShapeRectangles (client)
return BadWindow;
switch (stuff->destKind) {
case ShapeBounding:
- destBounding = 1;
createDefault = CreateBoundingShape;
break;
case ShapeClip:
- destBounding = 0;
createDefault = CreateClipShape;
break;
+ case ShapeInput:
+ createDefault = CreateBoundingShape;
+ break;
default:
client->errorValue = stuff->destKind;
return BadValue;
@@ -359,10 +359,19 @@ ProcShapeRectangles (client)
if (!pWin->optional)
MakeWindowOptional (pWin);
- if (destBounding)
+ switch (stuff->destKind) {
+ case ShapeBounding:
destRgn = &pWin->optional->boundingShape;
- else
+ break;
+ case ShapeClip:
destRgn = &pWin->optional->clipShape;
+ break;
+ case ShapeInput:
+ destRgn = &pWin->optional->inputShape;
+ break;
+ default:
+ return BadValue;
+ }
return RegionOperate (client, pWin, (int)stuff->destKind,
destRgn, srcRgn, (int)stuff->op,
@@ -410,7 +419,6 @@ ProcShapeMask (client)
RegionPtr *destRgn;
PixmapPtr pPixmap;
CreateDftPtr createDefault;
- int destBounding;
REQUEST_SIZE_MATCH (xShapeMaskReq);
UpdateCurrentTime();
@@ -419,13 +427,14 @@ ProcShapeMask (client)
return BadWindow;
switch (stuff->destKind) {
case ShapeBounding:
- destBounding = 1;
createDefault = CreateBoundingShape;
break;
case ShapeClip:
- destBounding = 0;
createDefault = CreateClipShape;
break;
+ case ShapeInput:
+ createDefault = CreateBoundingShape;
+ break;
default:
client->errorValue = stuff->destKind;
return BadValue;
@@ -448,10 +457,19 @@ ProcShapeMask (client)
if (!pWin->optional)
MakeWindowOptional (pWin);
- if (destBounding)
+ switch (stuff->destKind) {
+ case ShapeBounding:
destRgn = &pWin->optional->boundingShape;
- else
+ break;
+ case ShapeClip:
destRgn = &pWin->optional->clipShape;
+ break;
+ case ShapeInput:
+ destRgn = &pWin->optional->inputShape;
+ break;
+ default:
+ return BadValue;
+ }
return RegionOperate (client, pWin, (int)stuff->destKind,
destRgn, srcRgn, (int)stuff->op,
@@ -508,7 +526,6 @@ ProcShapeCombine (client)
CreateDftPtr createDefault;
CreateDftPtr createSrc;
RegionPtr tmp;
- int destBounding;
REQUEST_SIZE_MATCH (xShapeCombineReq);
UpdateCurrentTime();
@@ -519,13 +536,14 @@ ProcShapeCombine (client)
MakeWindowOptional (pDestWin);
switch (stuff->destKind) {
case ShapeBounding:
- destBounding = 1;
createDefault = CreateBoundingShape;
break;
case ShapeClip:
- destBounding = 0;
createDefault = CreateClipShape;
break;
+ case ShapeInput:
+ createDefault = CreateBoundingShape;
+ break;
default:
client->errorValue = stuff->destKind;
return BadValue;
@@ -544,6 +562,10 @@ ProcShapeCombine (client)
srcRgn = wClipShape (pSrcWin);
createSrc = CreateClipShape;
break;
+ case ShapeInput:
+ srcRgn = wInputShape (pSrcWin);
+ createSrc = CreateBoundingShape;
+ break;
default:
client->errorValue = stuff->srcKind;
return BadValue;
@@ -562,10 +584,19 @@ ProcShapeCombine (client)
if (!pDestWin->optional)
MakeWindowOptional (pDestWin);
- if (destBounding)
+ switch (stuff->destKind) {
+ case ShapeBounding:
destRgn = &pDestWin->optional->boundingShape;
- else
+ break;
+ case ShapeClip:
destRgn = &pDestWin->optional->clipShape;
+ break;
+ case ShapeInput:
+ destRgn = &pDestWin->optional->inputShape;
+ break;
+ default:
+ return BadValue;
+ }
return RegionOperate (client, pDestWin, (int)stuff->destKind,
destRgn, srcRgn, (int)stuff->op,
@@ -627,6 +658,9 @@ ProcShapeOffset (client)
case ShapeClip:
srcRgn = wClipShape(pWin);
break;
+ case ShapeInput:
+ srcRgn = wInputShape (pWin);
+ break;
default:
client->errorValue = stuff->destKind;
return BadValue;
@@ -888,7 +922,8 @@ SendShapeNotify (pWin, which)
pHead = (ShapeEventPtr *) LookupIDByType(pWin->drawable.id, EventType);
if (!pHead)
return;
- if (which == ShapeBounding) {
+ switch (which) {
+ case ShapeBounding:
region = wBoundingShape(pWin);
if (region) {
extents = *REGION_EXTENTS(pWin->drawable.pScreen, region);
@@ -900,7 +935,8 @@ SendShapeNotify (pWin, which)
extents.y2 = pWin->drawable.height + wBorderWidth (pWin);
shaped = xFalse;
}
- } else {
+ break;
+ case ShapeClip:
region = wClipShape(pWin);
if (region) {
extents = *REGION_EXTENTS(pWin->drawable.pScreen, region);
@@ -912,6 +948,22 @@ SendShapeNotify (pWin, which)
extents.y2 = pWin->drawable.height;
shaped = xFalse;
}
+ break;
+ case ShapeInput:
+ region = wInputShape(pWin);
+ if (region) {
+ extents = *REGION_EXTENTS(pWin->drawable.pScreen, region);
+ shaped = xTrue;
+ } else {
+ extents.x1 = -wBorderWidth (pWin);
+ extents.y1 = -wBorderWidth (pWin);
+ extents.x2 = pWin->drawable.width + wBorderWidth (pWin);
+ extents.y2 = pWin->drawable.height + wBorderWidth (pWin);
+ shaped = xFalse;
+ }
+ break;
+ default:
+ return;
}
for (pShapeEvent = *pHead; pShapeEvent; pShapeEvent = pShapeEvent->next) {
client = pShapeEvent->client;
@@ -995,6 +1047,9 @@ ProcShapeGetRectangles (client)
case ShapeClip:
region = wClipShape(pWin);
break;
+ case ShapeInput:
+ region = wInputShape (pWin);
+ break;
default:
client->errorValue = stuff->kind;
return BadValue;
@@ -1017,6 +1072,12 @@ ProcShapeGetRectangles (client)
rects->width = pWin->drawable.width;
rects->height = pWin->drawable.height;
break;
+ case ShapeInput:
+ rects->x = - (int) wBorderWidth (pWin);
+ rects->y = - (int) wBorderWidth (pWin);
+ rects->width = pWin->drawable.width + wBorderWidth (pWin);
+ rects->height = pWin->drawable.height + wBorderWidth (pWin);
+ break;
}
} else {
BoxPtr box;
diff --git a/dix/dispatch.c b/dix/dispatch.c
index 6a93dacbb..bad17beaf 100644
--- a/dix/dispatch.c
+++ b/dix/dispatch.c
@@ -1249,6 +1249,12 @@ ProcTranslateCoords(register ClientPtr client)
&& (!wBoundingShape(pWin) ||
POINT_IN_REGION(pWin->drawable.pScreen,
&pWin->borderSize, x, y, &box))
+
+ && (!wInputShape(pWin) ||
+ POINT_IN_REGION(pWin->drawable.pScreen,
+ wInputShape(pWin),
+ x - pWin->drawable.x,
+ y - pWin->drawable.y, &box))
#endif
)
{
diff --git a/dix/events.c b/dix/events.c
index fcd6eec29..29fe78924 100644
--- a/dix/events.c
+++ b/dix/events.c
@@ -1988,26 +1988,32 @@ static WindowPtr
XYToWindow(int x, int y)
{
register WindowPtr pWin;
+ BoxRec box;
spriteTraceGood = 1; /* root window still there */
pWin = ROOT->firstChild;
while (pWin)
{
if ((pWin->mapped) &&
- (x >= pWin->drawable.x - wBorderWidth (pWin)) &&
- (x < pWin->drawable.x + (int)pWin->drawable.width +
- wBorderWidth(pWin)) &&
- (y >= pWin->drawable.y - wBorderWidth (pWin)) &&
- (y < pWin->drawable.y + (int)pWin->drawable.height +
- wBorderWidth (pWin))
+ (x >= pWin->drawable.x - wBorderWidth (pWin)) &&
+ (x < pWin->drawable.x + (int)pWin->drawable.width +
+ wBorderWidth(pWin)) &&
+ (y >= pWin->drawable.y - wBorderWidth (pWin)) &&
+ (y < pWin->drawable.y + (int)pWin->drawable.height +
+ wBorderWidth (pWin))
#ifdef SHAPE
- /* When a window is shaped, a further check
- * is made to see if the point is inside
- * borderSize
- */
- && (!wBoundingShape(pWin) || PointInBorderSize(pWin, x, y))
+ /* When a window is shaped, a further check
+ * is made to see if the point is inside
+ * borderSize
+ */
+ && (!wBoundingShape(pWin) || PointInBorderSize(pWin, x, y))
+ && (!wInputShape(pWin) ||
+ POINT_IN_REGION(pWin->drawable.pScreen,
+ wInputShape(pWin),
+ x - pWin->drawable.x,
+ y - pWin->drawable.y, &box))
#endif
- )
+ )
{
if (spriteTraceGood >= spriteTraceSize)
{
@@ -2277,7 +2283,12 @@ XineramaPointInWindowIsVisible(
x = xoff - panoramiXdataPtr[i].x;
y = yoff - panoramiXdataPtr[i].y;
- if(POINT_IN_REGION(pScreen, &pWin->borderClip, x, y, &box))
+ if(POINT_IN_REGION(pScreen, &pWin->borderClip, x, y, &box)
+ && (!wInputShape(pWin) ||
+ POINT_IN_REGION(pWin->drawable.pScreen,
+ wInputShape(pWin),
+ x - pWin->drawable.x,
+ y - pWin->drawable.y, &box)))
return TRUE;
}
diff --git a/dix/window.c b/dix/window.c
index 27d3d05ec..ac6f775ba 100644
--- a/dix/window.c
+++ b/dix/window.c
@@ -414,6 +414,7 @@ CreateRootWindow(ScreenPtr pScreen)
#ifdef SHAPE
pWin->optional->boundingShape = NULL;
pWin->optional->clipShape = NULL;
+ pWin->optional->inputShape = NULL;
#endif
#ifdef XINPUT
pWin->optional->inputMasks = NULL;
@@ -800,6 +801,8 @@ FreeWindowResources(register WindowPtr pWin)
REGION_DESTROY(pScreen, wBoundingShape (pWin));
if (wClipShape (pWin))
REGION_DESTROY(pScreen, wClipShape (pWin));
+ if (wInputShape (pWin))
+ REGION_DESTROY(pScreen, wInputShape (pWin));
#endif
if (pWin->borderIsPixel == FALSE)
(*pScreen->DestroyPixmap)(pWin->border.pixmap);
@@ -3182,7 +3185,12 @@ PointInWindowIsVisible(register WindowPtr pWin, int x, int y)
if (!pWin->realized)
return (FALSE);
if (POINT_IN_REGION(pWin->drawable.pScreen, &pWin->borderClip,
- x, y, &box))
+ x, y, &box)
+ && (!wInputShape(pWin) ||
+ POINT_IN_REGION(pWin->drawable.pScreen,
+ wInputShape(pWin),
+ x - pWin->drawable.x,
+ y - pWin->drawable.y, &box)))
return(TRUE);
return(FALSE);
}
@@ -3558,6 +3566,8 @@ CheckWindowOptionalNeed (register WindowPtr w)
return;
if (optional->clipShape != NULL)
return;
+ if (optional->inputShape != NULL)
+ return;
#endif
#ifdef XINPUT
if (optional->inputMasks != NULL)
@@ -3603,6 +3613,7 @@ MakeWindowOptional (register WindowPtr pWin)
#ifdef SHAPE
optional->boundingShape = NULL;
optional->clipShape = NULL;
+ optional->inputShape = NULL;
#endif
#ifdef XINPUT
optional->inputMasks = NULL;
diff --git a/include/windowstr.h b/include/windowstr.h
index bce01ba97..89e3ee10b 100644
--- a/include/windowstr.h
+++ b/include/windowstr.h
@@ -86,6 +86,7 @@ typedef struct _WindowOpt {
#ifdef SHAPE
RegionPtr boundingShape; /* default: NULL */
RegionPtr clipShape; /* default: NULL */
+ RegionPtr inputShape; /* default: NULL */
#endif
#ifdef XINPUT
struct _OtherInputMasks *inputMasks; /* default: NULL */
@@ -174,6 +175,7 @@ extern Mask DontPropagateMasks[];
#ifdef SHAPE
#define wBoundingShape(w) wUseDefault(w, boundingShape, NULL)
#define wClipShape(w) wUseDefault(w, clipShape, NULL)
+#define wInputShape(w) wUseDefault(w, inputShape, NULL)
#endif
#define wClient(w) (clients[CLIENT_ID((w)->drawable.id)])
#define wBorderWidth(w) ((int) (w)->borderWidth)
diff --git a/xfixes/region.c b/xfixes/region.c
index d80776d8c..b0073f5b3 100755
--- a/xfixes/region.c
+++ b/xfixes/region.c
@@ -675,7 +675,6 @@ ProcXFixesSetWindowShapeRegion (ClientPtr client)
ScreenPtr pScreen;
RegionPtr pRegion;
RegionPtr *pDestRegion;
- int destBounding;
REQUEST(xXFixesSetWindowShapeRegionReq);
REQUEST_SIZE_MATCH(xXFixesSetWindowShapeRegionReq);
@@ -686,18 +685,16 @@ ProcXFixesSetWindowShapeRegion (ClientPtr client)
return BadWindow;
}
VERIFY_REGION_OR_NONE(pRegion, stuff->region, client, SecurityWriteAccess);
+ pScreen = pWin->drawable.pScreen;
switch (stuff->destKind) {
case ShapeBounding:
- destBounding = 1;
- break;
case ShapeClip:
- destBounding = 0;
+ case ShapeInput:
break;
default:
client->errorValue = stuff->destKind;
return BadValue;
}
- pScreen = pWin->drawable.pScreen;
if (pRegion)
{
pRegion = XFixesRegionCopy (pRegion);
@@ -705,10 +702,18 @@ ProcXFixesSetWindowShapeRegion (ClientPtr client)
return BadAlloc;
if (!pWin->optional)
MakeWindowOptional (pWin);
- if (destBounding)
+ switch (stuff->destKind) {
+ default:
+ case ShapeBounding:
pDestRegion = &pWin->optional->boundingShape;
- else
+ break;
+ case ShapeClip:
pDestRegion = &pWin->optional->clipShape;
+ break;
+ case ShapeInput:
+ pDestRegion = &pWin->optional->inputShape;
+ break;
+ }
if (stuff->xOff || stuff->yOff)
REGION_TRANSLATE (0, pRegion, stuff->xOff, stuff->yOff);
}
@@ -716,10 +721,18 @@ ProcXFixesSetWindowShapeRegion (ClientPtr client)
{
if (pWin->optional)
{
- if (destBounding)
+ switch (stuff->destKind) {
+ default:
+ case ShapeBounding:
pDestRegion = &pWin->optional->boundingShape;
- else
+ break;
+ case ShapeClip:
pDestRegion = &pWin->optional->clipShape;
+ break;
+ case ShapeInput:
+ pDestRegion = &pWin->optional->inputShape;
+ break;
+ }
}
else
pDestRegion = &pRegion; /* a NULL region pointer */