windowing/windowserver/nga/SERVER/openwfc/cliwin.cpp
changeset 194 18f84489a694
parent 152 9f1c3fea0f87
--- a/windowing/windowserver/nga/SERVER/openwfc/cliwin.cpp	Fri Sep 17 08:36:49 2010 +0300
+++ b/windowing/windowserver/nga/SERVER/openwfc/cliwin.cpp	Mon Oct 04 02:31:51 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 //
 //