Input shaping
Soeren Sandmann
sandmann at redhat.com
Thu Mar 24 12:05:46 PST 2005
In this thread:
http://lists.freedesktop.org/pipermail/xorg/2005-January/005962.html
Keith describes and extension to the Shape extension allowing windows
to have an "input shape" in addition to the exisiting clip and
bounding shapes.
The patch attached to that message was committed to Keith's xserver
tree, but not
to the xorg tree. At
http://www.daimi.au.dk/~sandmann/input-shape.patch
there is a port of his patch to the xorg tree. The patch is also
attached to this message.
If this is considered a good idea, I will update the protocol and
library documentation
for the shape protocol.
I originally posted about this to the xorg list, and Roland pointed out
that xorg-arch
is really the right list to discuss this since it is an API extension.
He also pointed out that
the Xnest and Xdmx may need to be updated to be in sync with this change.
Søren
-------------- next part --------------
Index: include/extensions/shape.h
===================================================================
RCS file: /cvs/xorg/xc/include/extensions/shape.h,v
retrieving revision 1.2
diff -u -p -u -r1.2 shape.h
--- include/extensions/shape.h 23 Apr 2004 18:43:06 -0000 1.2
+++ include/extensions/shape.h 15 Mar 2005 22:47:17 -0000
@@ -50,6 +50,7 @@ in this Software without prior written a
#define ShapeBounding 0
#define ShapeClip 1
+#define ShapeInput 2
#define ShapeNotifyMask (1L << 0)
#define ShapeNotify 0
Index: include/extensions/shapestr.h
===================================================================
RCS file: /cvs/xorg/xc/include/extensions/shapestr.h,v
retrieving revision 1.1.1.1
diff -u -p -u -r1.1.1.1 shapestr.h
--- include/extensions/shapestr.h 14 Nov 2003 16:48:43 -0000 1.1.1.1
+++ include/extensions/shapestr.h 15 Mar 2005 22:47:17 -0000
@@ -42,7 +42,7 @@ in this Software without prior written a
#define SHAPENAME "SHAPE"
#define SHAPE_MAJOR_VERSION 1 /* current version numbers */
-#define SHAPE_MINOR_VERSION 0
+#define SHAPE_MINOR_VERSION 1
typedef struct _ShapeQueryVersion {
CARD8 reqType; /* always ShapeReqCode */
Index: lib/X11/CrWindow.c
Index: programs/Xserver/Xext/shape.c
===================================================================
RCS file: /cvs/xorg/xc/programs/Xserver/Xext/shape.c,v
retrieving revision 1.4
diff -u -p -u -r1.4 shape.c
--- programs/Xserver/Xext/shape.c 29 Jul 2004 23:43:39 -0000 1.4
+++ programs/Xserver/Xext/shape.c 15 Mar 2005 22:47:18 -0000
@@ -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;
Index: programs/Xserver/dix/dispatch.c
===================================================================
RCS file: /cvs/xorg/xc/programs/Xserver/dix/dispatch.c,v
retrieving revision 1.7
diff -u -p -u -r1.7 dispatch.c
--- programs/Xserver/dix/dispatch.c 7 Mar 2005 23:02:58 -0000 1.7
+++ programs/Xserver/dix/dispatch.c 15 Mar 2005 22:47:18 -0000
@@ -1249,6 +1249,12 @@ ProcTranslateCoords(register ClientPtr c
&& (!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
)
{
Index: programs/Xserver/dix/events.c
===================================================================
RCS file: /cvs/xorg/xc/programs/Xserver/dix/events.c,v
retrieving revision 1.7
diff -u -p -u -r1.7 events.c
--- programs/Xserver/dix/events.c 7 Mar 2005 23:02:58 -0000 1.7
+++ programs/Xserver/dix/events.c 15 Mar 2005 22:47:18 -0000
@@ -1896,26 +1896,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)
{
@@ -2161,7 +2167,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;
}
Index: programs/Xserver/dix/window.c
===================================================================
RCS file: /cvs/xorg/xc/programs/Xserver/dix/window.c,v
retrieving revision 1.7
diff -u -p -u -r1.7 window.c
--- programs/Xserver/dix/window.c 7 Mar 2005 23:02:59 -0000 1.7
+++ programs/Xserver/dix/window.c 15 Mar 2005 22:47:19 -0000
@@ -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 p
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 WindowPt
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 Window
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 p
#ifdef SHAPE
optional->boundingShape = NULL;
optional->clipShape = NULL;
+ optional->inputShape = NULL;
#endif
#ifdef XINPUT
optional->inputMasks = NULL;
Index: programs/Xserver/include/windowstr.h
===================================================================
RCS file: /cvs/xorg/xc/programs/Xserver/include/windowstr.h,v
retrieving revision 1.4
diff -u -p -u -r1.4 windowstr.h
--- programs/Xserver/include/windowstr.h 31 Jul 2004 08:24:13 -0000 1.4
+++ programs/Xserver/include/windowstr.h 15 Mar 2005 22:47:21 -0000
@@ -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)
Index: programs/Xserver/xfixes/region.c
===================================================================
RCS file: /cvs/xorg/xc/programs/Xserver/xfixes/region.c,v
retrieving revision 1.3
diff -u -p -u -r1.3 region.c
--- programs/Xserver/xfixes/region.c 31 Jul 2004 07:26:50 -0000 1.3
+++ programs/Xserver/xfixes/region.c 15 Mar 2005 22:47:23 -0000
@@ -675,7 +675,6 @@ ProcXFixesSetWindowShapeRegion (ClientPt
ScreenPtr pScreen;
RegionPtr pRegion;
RegionPtr *pDestRegion;
- int destBounding;
REQUEST(xXFixesSetWindowShapeRegionReq);
REQUEST_SIZE_MATCH(xXFixesSetWindowShapeRegionReq);
@@ -686,18 +685,16 @@ ProcXFixesSetWindowShapeRegion (ClientPt
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 (ClientPt
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 (ClientPt
{
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 */
More information about the xorg-arch
mailing list