--- a/windowing/windowserver/nga/SERVER/openwfc/cliwin.cpp Thu Sep 09 10:13:45 2010 +0300
+++ b/windowing/windowserver/nga/SERVER/openwfc/cliwin.cpp Fri Sep 17 17:00:49 2010 +0300
@@ -1,4 +1,4 @@
-// Copyright (c) 1995-2009 Nokia Corporation and/or its subsidiary(-ies).
+// Copyright (c) 1995-2010 Nokia Corporation and/or its subsidiary(-ies).
// All rights reserved.
// This component and the accompanying materials are made available
// under the terms of "Eclipse Public License v1.0"
@@ -511,6 +511,10 @@
RecalcChildAbs(&offset); // Also calls UpdateElementExtent(offset)
TWalkWindowTreeOffsetTransparentRegions offsetTransparent(offset);
WalkWindowTree(offsetTransparent, EWalkChildren);
+
+ // move the pointer region
+ if(iPointerRegion)
+ iPointerRegion->Offset(offset);
}
if (sizeChanged)
@@ -644,6 +648,7 @@
//
CWsWindow::Shutdown();
DeleteBaseArea();
+ DeletePointerRegion();
CWsPointerBuffer::Disconnect(this);
iFlags&=~EFlagShutDownInProgress;
}
@@ -1028,7 +1033,22 @@
windowTreeObserver->FlagChanged(*this, MWsWindowTreeObserver::EAlphaChannelTransparencyEnabled, ETrue);
}
break;
- }
+ case EWsWinOpSetPointerAcceptanceRegion:
+ {
+ TInt recs=*pData.Int;
+
+ // Use cases
+ // No Region => normal behaviour using window rect ( but how can we delete an existing region? )
+ // Empty Region => no pointer events will hit
+ // Non-Empty region => pointer events must hit the defined region
+
+ // allow for 0 rects, empty region implies no pointer events will hit
+ RWsRegion* region=recs>0 ? GetRegionFromClientL(iWsOwner,recs) : new(ELeave) RWsRegion;
+
+ // CWsClientWindow takes ownership of returned region
+ SetPointerAcceptanceRegion(region);
+ }
+ break;
default:
if (iRedraw->CommandL(aOpcode,pData)==EFalse)
{
@@ -1394,11 +1414,90 @@
{
return iOriginalSrcElementRect;
}
+
TRect CWsClientWindow::GetOriginalDestElementRect() const
{
return iOriginalDestElementRect;
}
+
+/** Sets a region of a window that can receive pointer events.
+
+Once this region is set, pointer events must be within both this region and the window's base area to be received.
+If an empty pointer acceptance region is set, then no pointer events will be received.
+Prior to calling this API the whole base area of the window can receive pointer events.
+
+If a window is moved, the pointer acceptance region will move with it.
+
+If a window changes shape, and the pointer acceptance region should also change shape with it,
+then the client must use this API to re-set the pointer acceptance region.
+
+This function always causes a flush of the window server buffer.
+
+@param aRegion Region defining the pointer acceptance region shape in window relative coordinates, CWsClientWindow takes ownership of this.
+*/
+void CWsClientWindow::SetPointerAcceptanceRegion(RWsRegion* aRegion)
+ {
+#ifdef LOG_WSERV_EVENTS
+ if(aRegion)
+ {
+ TRect boundingRect = aRegion->BoundingRect();
+ RDebug::Printf("_WSEVENT: CWsClientWindow::SetPointerRegion Rect Count=%d, bounding rect (%d,%d),(%d,%d)",
+ aRegion->Count(),
+ boundingRect.iTl.iX, boundingRect.iTl.iY,
+ boundingRect.iBr.iX, boundingRect.iBr.iY);
+ }
+ else
+ {
+ // This should probably NEVER be seen because the client side RWindowBase API takes a reference.
+ RDebug::Printf("_WSEVENT: CWsClientWindow::SetPointerRegion aRegion is NULL");
+ }
+#endif
+ DeletePointerRegion();
+
+ // take ownership
+ iPointerRegion = aRegion;
+ // move it to the same absolute origin as the window
+ if(iPointerRegion)
+ iPointerRegion->Offset(Origin());
+ // N.B. Does NOT need to be clipped while iBaseArea is also used.
+ }
+
+void CWsClientWindow::DeletePointerRegion()
+ {
+ if (iPointerRegion)
+ {
+ iPointerRegion->Destroy();
+ iPointerRegion = NULL;
+ }
+ }
+
+/* Checks if a point is should be considered to be within this window or not.
+
+For a hit Point must be within the window's base area, and also within the pointer acceptance region if it exists.
+
+@param aPoint The coordinates to test for a hit
+@return ETrue for a hit, EFalse for a miss
+*/
+TBool CWsClientWindow::PointerHit(const TPoint& aPoint) const
+ {
+ TBool isHit = EFalse;
+
+ if(iBaseArea->Contains(aPoint))
+ {
+ if(iPointerRegion)
+ {
+ isHit = iPointerRegion->TRegion::Contains(aPoint);
+ }
+ else
+ {
+ // there is no pointer region, so default to using the base area only
+ isHit = ETrue;
+ }
+ }
+ return isHit;
+ }
+
//
// Code for CWsTopClientWindow, a client window that connects to a group window //
//