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 srcRgn;
RegionPtr *destRgn; RegionPtr *destRgn;
CreateDftPtr createDefault; CreateDftPtr createDefault;
int destBounding;
REQUEST_AT_LEAST_SIZE (xShapeRectanglesReq); REQUEST_AT_LEAST_SIZE (xShapeRectanglesReq);
UpdateCurrentTime(); UpdateCurrentTime();
@ -329,13 +328,14 @@ ProcShapeRectangles (client)
return BadWindow; return BadWindow;
switch (stuff->destKind) { switch (stuff->destKind) {
case ShapeBounding: case ShapeBounding:
destBounding = 1;
createDefault = CreateBoundingShape; createDefault = CreateBoundingShape;
break; break;
case ShapeClip: case ShapeClip:
destBounding = 0;
createDefault = CreateClipShape; createDefault = CreateClipShape;
break; break;
case ShapeInput:
createDefault = CreateBoundingShape;
break;
default: default:
client->errorValue = stuff->destKind; client->errorValue = stuff->destKind;
return BadValue; return BadValue;
@ -359,10 +359,19 @@ ProcShapeRectangles (client)
if (!pWin->optional) if (!pWin->optional)
MakeWindowOptional (pWin); MakeWindowOptional (pWin);
if (destBounding) switch (stuff->destKind) {
case ShapeBounding:
destRgn = &pWin->optional->boundingShape; destRgn = &pWin->optional->boundingShape;
else break;
case ShapeClip:
destRgn = &pWin->optional->clipShape; destRgn = &pWin->optional->clipShape;
break;
case ShapeInput:
destRgn = &pWin->optional->inputShape;
break;
default:
return BadValue;
}
return RegionOperate (client, pWin, (int)stuff->destKind, return RegionOperate (client, pWin, (int)stuff->destKind,
destRgn, srcRgn, (int)stuff->op, destRgn, srcRgn, (int)stuff->op,
@ -410,7 +419,6 @@ ProcShapeMask (client)
RegionPtr *destRgn; RegionPtr *destRgn;
PixmapPtr pPixmap; PixmapPtr pPixmap;
CreateDftPtr createDefault; CreateDftPtr createDefault;
int destBounding;
REQUEST_SIZE_MATCH (xShapeMaskReq); REQUEST_SIZE_MATCH (xShapeMaskReq);
UpdateCurrentTime(); UpdateCurrentTime();
@ -419,13 +427,14 @@ ProcShapeMask (client)
return BadWindow; return BadWindow;
switch (stuff->destKind) { switch (stuff->destKind) {
case ShapeBounding: case ShapeBounding:
destBounding = 1;
createDefault = CreateBoundingShape; createDefault = CreateBoundingShape;
break; break;
case ShapeClip: case ShapeClip:
destBounding = 0;
createDefault = CreateClipShape; createDefault = CreateClipShape;
break; break;
case ShapeInput:
createDefault = CreateBoundingShape;
break;
default: default:
client->errorValue = stuff->destKind; client->errorValue = stuff->destKind;
return BadValue; return BadValue;
@ -448,10 +457,19 @@ ProcShapeMask (client)
if (!pWin->optional) if (!pWin->optional)
MakeWindowOptional (pWin); MakeWindowOptional (pWin);
if (destBounding) switch (stuff->destKind) {
case ShapeBounding:
destRgn = &pWin->optional->boundingShape; destRgn = &pWin->optional->boundingShape;
else break;
case ShapeClip:
destRgn = &pWin->optional->clipShape; destRgn = &pWin->optional->clipShape;
break;
case ShapeInput:
destRgn = &pWin->optional->inputShape;
break;
default:
return BadValue;
}
return RegionOperate (client, pWin, (int)stuff->destKind, return RegionOperate (client, pWin, (int)stuff->destKind,
destRgn, srcRgn, (int)stuff->op, destRgn, srcRgn, (int)stuff->op,
@ -508,7 +526,6 @@ ProcShapeCombine (client)
CreateDftPtr createDefault; CreateDftPtr createDefault;
CreateDftPtr createSrc; CreateDftPtr createSrc;
RegionPtr tmp; RegionPtr tmp;
int destBounding;
REQUEST_SIZE_MATCH (xShapeCombineReq); REQUEST_SIZE_MATCH (xShapeCombineReq);
UpdateCurrentTime(); UpdateCurrentTime();
@ -519,13 +536,14 @@ ProcShapeCombine (client)
MakeWindowOptional (pDestWin); MakeWindowOptional (pDestWin);
switch (stuff->destKind) { switch (stuff->destKind) {
case ShapeBounding: case ShapeBounding:
destBounding = 1;
createDefault = CreateBoundingShape; createDefault = CreateBoundingShape;
break; break;
case ShapeClip: case ShapeClip:
destBounding = 0;
createDefault = CreateClipShape; createDefault = CreateClipShape;
break; break;
case ShapeInput:
createDefault = CreateBoundingShape;
break;
default: default:
client->errorValue = stuff->destKind; client->errorValue = stuff->destKind;
return BadValue; return BadValue;
@ -544,6 +562,10 @@ ProcShapeCombine (client)
srcRgn = wClipShape (pSrcWin); srcRgn = wClipShape (pSrcWin);
createSrc = CreateClipShape; createSrc = CreateClipShape;
break; break;
case ShapeInput:
srcRgn = wInputShape (pSrcWin);
createSrc = CreateBoundingShape;
break;
default: default:
client->errorValue = stuff->srcKind; client->errorValue = stuff->srcKind;
return BadValue; return BadValue;
@ -562,10 +584,19 @@ ProcShapeCombine (client)
if (!pDestWin->optional) if (!pDestWin->optional)
MakeWindowOptional (pDestWin); MakeWindowOptional (pDestWin);
if (destBounding) switch (stuff->destKind) {
case ShapeBounding:
destRgn = &pDestWin->optional->boundingShape; destRgn = &pDestWin->optional->boundingShape;
else break;
case ShapeClip:
destRgn = &pDestWin->optional->clipShape; destRgn = &pDestWin->optional->clipShape;
break;
case ShapeInput:
destRgn = &pDestWin->optional->inputShape;
break;
default:
return BadValue;
}
return RegionOperate (client, pDestWin, (int)stuff->destKind, return RegionOperate (client, pDestWin, (int)stuff->destKind,
destRgn, srcRgn, (int)stuff->op, destRgn, srcRgn, (int)stuff->op,
@ -627,6 +658,9 @@ ProcShapeOffset (client)
case ShapeClip: case ShapeClip:
srcRgn = wClipShape(pWin); srcRgn = wClipShape(pWin);
break; break;
case ShapeInput:
srcRgn = wInputShape (pWin);
break;
default: default:
client->errorValue = stuff->destKind; client->errorValue = stuff->destKind;
return BadValue; return BadValue;
@ -888,7 +922,8 @@ SendShapeNotify (pWin, which)
pHead = (ShapeEventPtr *) LookupIDByType(pWin->drawable.id, EventType); pHead = (ShapeEventPtr *) LookupIDByType(pWin->drawable.id, EventType);
if (!pHead) if (!pHead)
return; return;
if (which == ShapeBounding) { switch (which) {
case ShapeBounding:
region = wBoundingShape(pWin); region = wBoundingShape(pWin);
if (region) { if (region) {
extents = *REGION_EXTENTS(pWin->drawable.pScreen, region); extents = *REGION_EXTENTS(pWin->drawable.pScreen, region);
@ -900,7 +935,8 @@ SendShapeNotify (pWin, which)
extents.y2 = pWin->drawable.height + wBorderWidth (pWin); extents.y2 = pWin->drawable.height + wBorderWidth (pWin);
shaped = xFalse; shaped = xFalse;
} }
} else { break;
case ShapeClip:
region = wClipShape(pWin); region = wClipShape(pWin);
if (region) { if (region) {
extents = *REGION_EXTENTS(pWin->drawable.pScreen, region); extents = *REGION_EXTENTS(pWin->drawable.pScreen, region);
@ -912,6 +948,22 @@ SendShapeNotify (pWin, which)
extents.y2 = pWin->drawable.height; extents.y2 = pWin->drawable.height;
shaped = xFalse; 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) { for (pShapeEvent = *pHead; pShapeEvent; pShapeEvent = pShapeEvent->next) {
client = pShapeEvent->client; client = pShapeEvent->client;
@ -995,6 +1047,9 @@ ProcShapeGetRectangles (client)
case ShapeClip: case ShapeClip:
region = wClipShape(pWin); region = wClipShape(pWin);
break; break;
case ShapeInput:
region = wInputShape (pWin);
break;
default: default:
client->errorValue = stuff->kind; client->errorValue = stuff->kind;
return BadValue; return BadValue;
@ -1017,6 +1072,12 @@ ProcShapeGetRectangles (client)
rects->width = pWin->drawable.width; rects->width = pWin->drawable.width;
rects->height = pWin->drawable.height; rects->height = pWin->drawable.height;
break; 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 { } else {
BoxPtr box; BoxPtr box;

View File

@ -1249,6 +1249,12 @@ ProcTranslateCoords(register ClientPtr client)
&& (!wBoundingShape(pWin) || && (!wBoundingShape(pWin) ||
POINT_IN_REGION(pWin->drawable.pScreen, POINT_IN_REGION(pWin->drawable.pScreen,
&pWin->borderSize, x, y, &box)) &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 #endif
) )
{ {

View File

@ -1988,6 +1988,7 @@ static WindowPtr
XYToWindow(int x, int y) XYToWindow(int x, int y)
{ {
register WindowPtr pWin; register WindowPtr pWin;
BoxRec box;
spriteTraceGood = 1; /* root window still there */ spriteTraceGood = 1; /* root window still there */
pWin = ROOT->firstChild; pWin = ROOT->firstChild;
@ -2006,6 +2007,11 @@ XYToWindow(int x, int y)
* borderSize * borderSize
*/ */
&& (!wBoundingShape(pWin) || PointInBorderSize(pWin, x, y)) && (!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 #endif
) )
{ {
@ -2277,7 +2283,12 @@ XineramaPointInWindowIsVisible(
x = xoff - panoramiXdataPtr[i].x; x = xoff - panoramiXdataPtr[i].x;
y = yoff - panoramiXdataPtr[i].y; 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; return TRUE;
} }

View File

@ -414,6 +414,7 @@ CreateRootWindow(ScreenPtr pScreen)
#ifdef SHAPE #ifdef SHAPE
pWin->optional->boundingShape = NULL; pWin->optional->boundingShape = NULL;
pWin->optional->clipShape = NULL; pWin->optional->clipShape = NULL;
pWin->optional->inputShape = NULL;
#endif #endif
#ifdef XINPUT #ifdef XINPUT
pWin->optional->inputMasks = NULL; pWin->optional->inputMasks = NULL;
@ -800,6 +801,8 @@ FreeWindowResources(register WindowPtr pWin)
REGION_DESTROY(pScreen, wBoundingShape (pWin)); REGION_DESTROY(pScreen, wBoundingShape (pWin));
if (wClipShape (pWin)) if (wClipShape (pWin))
REGION_DESTROY(pScreen, wClipShape (pWin)); REGION_DESTROY(pScreen, wClipShape (pWin));
if (wInputShape (pWin))
REGION_DESTROY(pScreen, wInputShape (pWin));
#endif #endif
if (pWin->borderIsPixel == FALSE) if (pWin->borderIsPixel == FALSE)
(*pScreen->DestroyPixmap)(pWin->border.pixmap); (*pScreen->DestroyPixmap)(pWin->border.pixmap);
@ -3182,7 +3185,12 @@ PointInWindowIsVisible(register WindowPtr pWin, int x, int y)
if (!pWin->realized) if (!pWin->realized)
return (FALSE); return (FALSE);
if (POINT_IN_REGION(pWin->drawable.pScreen, &pWin->borderClip, 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(TRUE);
return(FALSE); return(FALSE);
} }
@ -3558,6 +3566,8 @@ CheckWindowOptionalNeed (register WindowPtr w)
return; return;
if (optional->clipShape != NULL) if (optional->clipShape != NULL)
return; return;
if (optional->inputShape != NULL)
return;
#endif #endif
#ifdef XINPUT #ifdef XINPUT
if (optional->inputMasks != NULL) if (optional->inputMasks != NULL)
@ -3603,6 +3613,7 @@ MakeWindowOptional (register WindowPtr pWin)
#ifdef SHAPE #ifdef SHAPE
optional->boundingShape = NULL; optional->boundingShape = NULL;
optional->clipShape = NULL; optional->clipShape = NULL;
optional->inputShape = NULL;
#endif #endif
#ifdef XINPUT #ifdef XINPUT
optional->inputMasks = NULL; optional->inputMasks = NULL;

View File

@ -86,6 +86,7 @@ typedef struct _WindowOpt {
#ifdef SHAPE #ifdef SHAPE
RegionPtr boundingShape; /* default: NULL */ RegionPtr boundingShape; /* default: NULL */
RegionPtr clipShape; /* default: NULL */ RegionPtr clipShape; /* default: NULL */
RegionPtr inputShape; /* default: NULL */
#endif #endif
#ifdef XINPUT #ifdef XINPUT
struct _OtherInputMasks *inputMasks; /* default: NULL */ struct _OtherInputMasks *inputMasks; /* default: NULL */
@ -174,6 +175,7 @@ extern Mask DontPropagateMasks[];
#ifdef SHAPE #ifdef SHAPE
#define wBoundingShape(w) wUseDefault(w, boundingShape, NULL) #define wBoundingShape(w) wUseDefault(w, boundingShape, NULL)
#define wClipShape(w) wUseDefault(w, clipShape, NULL) #define wClipShape(w) wUseDefault(w, clipShape, NULL)
#define wInputShape(w) wUseDefault(w, inputShape, NULL)
#endif #endif
#define wClient(w) (clients[CLIENT_ID((w)->drawable.id)]) #define wClient(w) (clients[CLIENT_ID((w)->drawable.id)])
#define wBorderWidth(w) ((int) (w)->borderWidth) #define wBorderWidth(w) ((int) (w)->borderWidth)

View File

@ -675,7 +675,6 @@ ProcXFixesSetWindowShapeRegion (ClientPtr client)
ScreenPtr pScreen; ScreenPtr pScreen;
RegionPtr pRegion; RegionPtr pRegion;
RegionPtr *pDestRegion; RegionPtr *pDestRegion;
int destBounding;
REQUEST(xXFixesSetWindowShapeRegionReq); REQUEST(xXFixesSetWindowShapeRegionReq);
REQUEST_SIZE_MATCH(xXFixesSetWindowShapeRegionReq); REQUEST_SIZE_MATCH(xXFixesSetWindowShapeRegionReq);
@ -686,18 +685,16 @@ ProcXFixesSetWindowShapeRegion (ClientPtr client)
return BadWindow; return BadWindow;
} }
VERIFY_REGION_OR_NONE(pRegion, stuff->region, client, SecurityWriteAccess); VERIFY_REGION_OR_NONE(pRegion, stuff->region, client, SecurityWriteAccess);
pScreen = pWin->drawable.pScreen;
switch (stuff->destKind) { switch (stuff->destKind) {
case ShapeBounding: case ShapeBounding:
destBounding = 1;
break;
case ShapeClip: case ShapeClip:
destBounding = 0; case ShapeInput:
break; break;
default: default:
client->errorValue = stuff->destKind; client->errorValue = stuff->destKind;
return BadValue; return BadValue;
} }
pScreen = pWin->drawable.pScreen;
if (pRegion) if (pRegion)
{ {
pRegion = XFixesRegionCopy (pRegion); pRegion = XFixesRegionCopy (pRegion);
@ -705,10 +702,18 @@ ProcXFixesSetWindowShapeRegion (ClientPtr client)
return BadAlloc; return BadAlloc;
if (!pWin->optional) if (!pWin->optional)
MakeWindowOptional (pWin); MakeWindowOptional (pWin);
if (destBounding) switch (stuff->destKind) {
default:
case ShapeBounding:
pDestRegion = &pWin->optional->boundingShape; pDestRegion = &pWin->optional->boundingShape;
else break;
case ShapeClip:
pDestRegion = &pWin->optional->clipShape; pDestRegion = &pWin->optional->clipShape;
break;
case ShapeInput:
pDestRegion = &pWin->optional->inputShape;
break;
}
if (stuff->xOff || stuff->yOff) if (stuff->xOff || stuff->yOff)
REGION_TRANSLATE (0, pRegion, stuff->xOff, stuff->yOff); REGION_TRANSLATE (0, pRegion, stuff->xOff, stuff->yOff);
} }
@ -716,10 +721,18 @@ ProcXFixesSetWindowShapeRegion (ClientPtr client)
{ {
if (pWin->optional) if (pWin->optional)
{ {
if (destBounding) switch (stuff->destKind) {
default:
case ShapeBounding:
pDestRegion = &pWin->optional->boundingShape; pDestRegion = &pWin->optional->boundingShape;
else break;
case ShapeClip:
pDestRegion = &pWin->optional->clipShape; pDestRegion = &pWin->optional->clipShape;
break;
case ShapeInput:
pDestRegion = &pWin->optional->inputShape;
break;
}
} }
else else
pDestRegion = &pRegion; /* a NULL region pointer */ pDestRegion = &pRegion; /* a NULL region pointer */