Bug #2799: Input shape. (Keith Packard)

This commit is contained in:
Adam Jackson 2005-06-10 04:01:14 +00:00
parent d24ed90547
commit 988ffddfe0
6 changed files with 144 additions and 40 deletions

View File

@ -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;

View File

@ -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
)
{

View File

@ -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;
}

View File

@ -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;

View File

@ -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)

View File

@ -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 */