textinput/peninputarc/src/peninputanim/peninputanim.cpp
changeset 0 eb1f2e154e89
child 5 a47de9135b21
equal deleted inserted replaced
-1:000000000000 0:eb1f2e154e89
       
     1 /*
       
     2 * Copyright (c) 2005-2007 Nokia Corporation and/or its subsidiary(-ies).
       
     3 * All rights reserved.
       
     4 * This component and the accompanying materials are made available
       
     5 * under the terms of "Eclipse Public License v1.0""
       
     6 * which accompanies this distribution, and is available
       
     7 * at the URL "http://www.eclipse.org/legal/epl-v10.html".
       
     8 *
       
     9 * Initial Contributors:
       
    10 * Nokia Corporation - initial contribution.
       
    11 *
       
    12 * Contributors:
       
    13 *
       
    14 * Description:  Implementation for peninput animation dll
       
    15 *
       
    16 */
       
    17 
       
    18 
       
    19 /*
       
    20 * ============================================================================
       
    21 *
       
    22 * Refactoring by Steven Yao
       
    23 * 
       
    24 * 2007-03-23
       
    25 *
       
    26 * ============================================================================
       
    27 */
       
    28 
       
    29 //INCLUDE
       
    30 #include "peninputanim.h" 
       
    31 #include "peninputcmdparam.h"
       
    32 #include "peninputcmdparamext.h"
       
    33 #include "peninputcmd.h"
       
    34 // Modify for bug ETMA-7X2C5Y begin
       
    35 #include "penpointereventsuppressor.h"
       
    36 // Modify for bug ETMA-7X2C5Y end
       
    37 // ----------- Touch feedback additions start
       
    38 #ifdef RD_TACTILE_FEEDBACK
       
    39 #include <coecntrl.h>
       
    40 #include <tactilefeedbackserver.h>
       
    41 #include <featmgr.h>
       
    42 #endif //RD_TACTILE_FEEDBACK
       
    43 // ----------- Touch feedback additions start
       
    44 
       
    45 #include <avkondomainpskeys.h>
       
    46 //CONSTANT
       
    47 const TInt KMsgSlot1 = 1;	//msg slot 2 in IPC
       
    48 const TInt KMsgSlot2 = 2; 	//msg slot 2 in IPC
       
    49 const TInt KFlushTimerPeriod = 1000;		//1/1000 second
       
    50 const TInt KResponseQueueWaitTime = 100000;		//1/10 second
       
    51 
       
    52 // ======== GLOBAL FUNCTIONS ========
       
    53 
       
    54 // ---------------------------------------------------------------------------
       
    55 // CreateCAnimDllL
       
    56 // This is called by the window server, at the request of the animation 
       
    57 // client, to construct the CAnimDll derived server side DLL class.
       
    58 // ---------------------------------------------------------------------------
       
    59 //
       
    60 EXPORT_C CAnimDll *CreateCAnimDllL()
       
    61     {
       
    62 	return(new (ELeave) CPeninputAnimDll()); 
       
    63     }
       
    64 
       
    65 // ======== MEMBER FUNCTIONS ========
       
    66 
       
    67 // class CAnimDll
       
    68 
       
    69 // ---------------------------------------------------------------------------
       
    70 // CPeninputAnimDll::CreateInstanceL
       
    71 // Factory function for animation DLL.
       
    72 // ---------------------------------------------------------------------------
       
    73 //
       
    74 CAnim* CPeninputAnimDll::CreateInstanceL(TInt /*aType*/)
       
    75     {
       
    76 	return new(ELeave) CPeninputAnim();
       
    77     }
       
    78 
       
    79 // class CPeninputAnim
       
    80 
       
    81 // ---------------------------------------------------------------------------
       
    82 // CPeninputAnim::CPeninputAnim
       
    83 // Constructor
       
    84 // ---------------------------------------------------------------------------
       
    85 //
       
    86 CPeninputAnim::CPeninputAnim()
       
    87     {
       
    88 	iIsActive = EFalse;
       
    89 	//iSpritePosition and iSpriteSize are initialized to 0 by default constructor
       
    90 	//iSpritePosition = TPoint(0, 0);
       
    91 	//iSpriteSize = TSize(0, 0);
       
    92 	iIsPointerCaptured = EFalse;
       
    93 	iIsPenDown = EFalse;
       
    94 	
       
    95 	iPrimaryTouchPtNum = 0;
       
    96 	iPrimaryTouchPtDetected = EFalse;
       
    97 
       
    98 	
       
    99 #ifdef RD_TACTILE_FEEDBACK	
       
   100 	TRAPD( err, FeatureManager::InitializeLibL() );
       
   101     if( err == KErrNone )
       
   102         {
       
   103         iTactileSupported =  FeatureManager::FeatureSupported( KFeatureIdTactileFeedback );
       
   104         }
       
   105 	iFeedback = MTactileFeedbackServer::Instance();
       
   106 #endif // RD_TACTILE_FEEDBACK	
       
   107     
       
   108     iEnableSprite = ETrue;	
       
   109     iDSAState = EFalse;	
       
   110     }
       
   111 
       
   112 // ---------------------------------------------------------------------------
       
   113 // CPeninputAnim::~CPeninputAnim
       
   114 // Destructor
       
   115 // ---------------------------------------------------------------------------
       
   116 //
       
   117 CPeninputAnim::~CPeninputAnim()
       
   118     {
       
   119 	Deactivate();
       
   120 
       
   121 	iMsgBufQueue.Close();
       
   122 	iKeyMsgResponseQueue.Close();
       
   123 	iResponseQueueSemaphore.Close();
       
   124 	
       
   125 	delete iFlushTimer;
       
   126 #ifdef RD_TACTILE_FEEDBACK	
       
   127 	FeatureManager::UnInitializeLib();
       
   128 	iTactileControl.Close();
       
   129 	iBackupTactileControl.Close();
       
   130 #endif // RD_TACTILE_FEEDBACK	
       
   131 	// Modify for bug ETMA-7X2C5Y begin
       
   132 	delete iPointerEventSuppressor;
       
   133 	// Modify for bug ETMA-7X2C5Y end
       
   134 	if (iDiscreetPopSubscriber)
       
   135 	    {
       
   136 	    iDiscreetPopSubscriber->StopSubscribe();
       
   137 	    }
       
   138 	iDiscreetPopProperty.Close();
       
   139 	delete iDiscreetPopSubscriber;
       
   140 	iAknUiSrv.Close();
       
   141     }
       
   142 
       
   143 // ---------------------------------------------------------------------------
       
   144 // CPeninputAnim::ConstructL
       
   145 // Second phase constructor
       
   146 // ---------------------------------------------------------------------------
       
   147 //
       
   148 void CPeninputAnim::ConstructL(TAny* /*aParameters*/)
       
   149     {
       
   150 	// the animation feature is not used
       
   151 	iFunctions->SetInterval(0);
       
   152 	iFlushTimer = CPeriodic::NewL(CActive::EPriorityStandard);
       
   153 	
       
   154     iFunctions->RegisterForNotifications(EDirectScreenAccess);
       
   155 	// Modify for bug ETMA-7X2C5Y begin
       
   156     iPointerEventSuppressor = CPenPointerEventSuppressor::NewL();
       
   157     // Modify for bug ETMA-7X2C5Y end
       
   158     User::LeaveIfError(iDiscreetPopProperty.Attach(KPSUidAvkonDomain, 
       
   159                                          KAknGlobalDiscreetPopupNumChanged));
       
   160     iDiscreetPopSubscriber = new (ELeave) CSubscriber(
       
   161 			TCallBack( DiscreetPopChangeNotification, this), 
       
   162 			iDiscreetPopProperty);
       
   163     iDiscreetPopSubscriber->SubscribeL();
       
   164 	
       
   165 	User::LeaveIfError(iAknUiSrv.Connect());
       
   166 	iDiscreetPopArea = iAknUiSrv.GetInUseGlobalDiscreetPopupRect();
       
   167     if(iDiscreetPopArea.Size().iWidth > 0)
       
   168     	{
       
   169 		iDiscreetPoped = ETrue;
       
   170     	}
       
   171     }
       
   172 
       
   173 
       
   174 // ---------------------------------------------------------------------------
       
   175 // CPeninputAnim::Animate
       
   176 // Create layout
       
   177 // ---------------------------------------------------------------------------
       
   178 //
       
   179 void CPeninputAnim::Animate(TDateTime* /*aDateTime*/)
       
   180     {
       
   181     // do nothing
       
   182     }
       
   183 
       
   184 
       
   185 void CPeninputAnim::HandleNotification(const TWsEvent& aEvent)
       
   186     {
       
   187     switch (aEvent.Type())
       
   188         {
       
   189         case EEventDirectScreenAccessBegin:
       
   190             SetDSAState(ETrue);
       
   191             break;
       
   192         case EEventDirectScreenAccessEnd:
       
   193             SetDSAState(EFalse);
       
   194             break;
       
   195         default:
       
   196             break;
       
   197         }
       
   198     }
       
   199     
       
   200 void CPeninputAnim::SetDSAState(TBool aFlag)
       
   201     {
       
   202     iDSAState = aFlag;
       
   203     if(aFlag && iEnableSprite) //close sprite when DSA is on
       
   204         {
       
   205         TRawEvent event;
       
   206         event.Set( TRawEvent::ENone );
       
   207         event.SetTip( ETrue );
       
   208         PostRawEvent( event );
       
   209         FlushRawEventBuffer();
       
   210         //Deactivate(); 
       
   211         //iEnableSprite = EFalse;
       
   212         }
       
   213     /*else
       
   214         {
       
   215         iEnableSprite = iESPrevState;
       
   216         }*/
       
   217     }
       
   218 // ---------------------------------------------------------------------------
       
   219 // CPeninputAnim::OfferRawEvent
       
   220 // handle raw events, e.g. key presses, pen events, power buttons etc. 
       
   221 // if the event can be handled then return ETrue, or return EFalse
       
   222 // ---------------------------------------------------------------------------
       
   223 //
       
   224 TBool CPeninputAnim::OfferRawEvent(const TRawEvent& aRawEvent)
       
   225     {
       
   226     if( iIsSimulatedEvent )
       
   227         {
       
   228     	return EFalse;
       
   229         }
       
   230     
       
   231     // Suppress multi-touch events
       
   232     switch ( aRawEvent.Type() )
       
   233         {
       
   234         case TRawEvent::EButton1Down:
       
   235         case TRawEvent::EButton1Up:
       
   236         case TRawEvent::EPointerMove:
       
   237             {
       
   238             if ( iPrimaryTouchPtDetected )
       
   239                 {
       
   240                 if ( aRawEvent.PointerNumber() != iPrimaryTouchPtNum )
       
   241                     {
       
   242                     return ETrue;
       
   243                     }
       
   244                 }
       
   245             else
       
   246                 {
       
   247                 iPrimaryTouchPtNum = aRawEvent.PointerNumber();
       
   248                 iPrimaryTouchPtDetected = ETrue;
       
   249                 }
       
   250             }
       
   251             break;
       
   252         default:
       
   253             break;
       
   254         }
       
   255 
       
   256     
       
   257 	// Suppress unexpected drag events, refer to error ETMA-7X2C5Y
       
   258     TPointerEvent pointerEvent;
       
   259     switch ( aRawEvent.Type() )
       
   260         {
       
   261         case TRawEvent::EButton1Down:
       
   262             {
       
   263             pointerEvent.iType = TPointerEvent::EButton1Down;
       
   264             pointerEvent.iPosition = aRawEvent.Pos();
       
   265             break;
       
   266             }
       
   267         case TRawEvent::EButton1Up:
       
   268             {
       
   269             pointerEvent.iType = TPointerEvent::EButton1Up;
       
   270             break;
       
   271             }
       
   272         case TRawEvent::EPointerMove:
       
   273             {
       
   274             pointerEvent.iType = TPointerEvent::EDrag;
       
   275             pointerEvent.iPosition = aRawEvent.Pos();
       
   276             break;
       
   277             }
       
   278         default:
       
   279             pointerEvent.iType = TPointerEvent::ENullType;
       
   280         }
       
   281     
       
   282     TBool result = iPointerEventSuppressor->SuppressPointerEvent( pointerEvent );
       
   283     if ( result )
       
   284         {
       
   285         return ETrue;
       
   286         }
       
   287 
       
   288     
       
   289 	switch(aRawEvent.Type())
       
   290 	    {
       
   291 		case TRawEvent::EKeyUp:
       
   292 		case TRawEvent::EKeyDown:
       
   293 		    {
       
   294 			return OnRawKeyEvent(aRawEvent);        	
       
   295 		    }
       
   296 		case TRawEvent::EButton1Down:
       
   297 		    {
       
   298 			return OnRawButton1Down(aRawEvent);
       
   299 		    }
       
   300 		case TRawEvent::EButton1Up:
       
   301 		    {
       
   302 			return OnRawButton1Up(aRawEvent);
       
   303 		    }
       
   304 		case TRawEvent::EPointerMove:
       
   305 		    {
       
   306 			return OnRawPointerMove(aRawEvent);
       
   307 		    }
       
   308 		default:
       
   309 		    {
       
   310 			return EFalse;
       
   311 		    }            
       
   312 	    }	
       
   313     }
       
   314 
       
   315 // ---------------------------------------------------------------------------
       
   316 // CPeninputAnim::Command
       
   317 // The window server calls this function in response to application 
       
   318 // calls to the client side command function RAnim::Command()
       
   319 // ---------------------------------------------------------------------------
       
   320 //
       
   321 void CPeninputAnim::Command(TInt aOpcode, TAny* aParams)
       
   322     {
       
   323     switch(aOpcode)
       
   324         {
       
   325 		case EPeninputOpActivate:
       
   326             {
       
   327             Activate();
       
   328             break;
       
   329             }        
       
   330         case EPeninputOpDeactivate:
       
   331             {
       
   332             Deactivate();
       
   333             break;
       
   334             }        
       
   335         case EPeninputOpLayoutUpdateArea:
       
   336             {
       
   337             PanicClientIfNoParam(aParams);	                
       
   338 			TUpdateDataArea* area = static_cast<TUpdateDataArea*>(aParams);
       
   339 			iSpriteFunctions->UpdateMember( 0, area->iRect, area->iUpdateFlag );
       
   340 			break;
       
   341 		    }			
       
   342         case EPeninputOpCapturePointer:
       
   343             {
       
   344             PanicClientIfNoParam(aParams);            
       
   345 	        iIsPointerCaptured = *(static_cast<TBool*>(aParams));
       
   346 	        break;
       
   347             }
       
   348         case EPeninputOpSimulateEvent:
       
   349             {
       
   350             PanicClientIfNoParam(aParams);
       
   351             TRawEvent event = *(static_cast<TRawEvent*>(aParams));
       
   352             iIsSimulatedEvent = ETrue;
       
   353             iFunctions->PostRawEvent(event);
       
   354             iIsSimulatedEvent = EFalse;
       
   355 
       
   356             break;
       
   357             }
       
   358 
       
   359 #ifdef RD_TACTILE_FEEDBACK         
       
   360         case EPeninputOpRegisterFeedbackArea:
       
   361             {
       
   362             //add the rect to feedback list
       
   363             PanicClientIfNoParam(aParams);
       
   364             TTactileFeedbackArea area = *(static_cast<TTactileFeedbackArea*>(aParams));
       
   365             
       
   366             //Advanced Tactile feedback REQ417-47932
       
   367             TTactileControlInfo controlitem(area.iId, area.iNewRect, area.iTactileType);
       
   368             iTactileControl.Append(controlitem); 
       
   369             }
       
   370             break;
       
   371         case EPeninputOpDeRegisterFeedbackArea:
       
   372             {
       
   373             PanicClientIfNoParam(aParams);
       
   374             TTactileFeedbackArea area = *(static_cast<TTactileFeedbackArea*>(aParams));
       
   375             const TInt KRemoveAllId = -1;
       
   376             
       
   377             if( area.iId == KRemoveAllId && area.iNewRect == TRect(0,0,0,0) )
       
   378                 {
       
   379                 //remove all
       
   380                 iTactileControl.Reset();
       
   381                 break;
       
   382                 }
       
   383             TTactileControlInfo controlitem(area.iId, area.iNewRect, area.iTactileType);
       
   384             TInt idx = iTactileControl.Find(controlitem, 
       
   385             		TIdentityRelation<TTactileControlInfo>(CPeninputAnim::MatchItemByControlID));
       
   386             if(idx != KErrNotFound)
       
   387                 {  
       
   388                 iTactileControl.Remove(idx);
       
   389                 }
       
   390             }
       
   391             break;  
       
   392         case EPeninputOpChangeFeedbackArea:
       
   393             {
       
   394             PanicClientIfNoParam(aParams);
       
   395             TTactileFeedbackArea area = *(static_cast<TTactileFeedbackArea*>(aParams));
       
   396             TTactileControlInfo controlitem(area.iId, area.iPrevRect, area.iTactileType);           
       
   397             TInt idx = iTactileControl.Find(controlitem, 
       
   398                     TIdentityRelation<TTactileControlInfo>(CPeninputAnim::MatchItemByControlIDAndArea));
       
   399             if(idx != KErrNotFound)
       
   400                 {                                
       
   401                 //change the rect
       
   402                 iTactileControl[idx].iArea = area.iNewRect;
       
   403                 }  
       
   404             }
       
   405             break; 
       
   406         case EPeninputOpChangeFeedbackType:
       
   407         	{
       
   408         	PanicClientIfNoParam(aParams);
       
   409             TTactileFeedbackArea area = *(static_cast<TTactileFeedbackArea*>(aParams));
       
   410             TTactileControlInfo controlitem(area.iId, area.iNewRect, area.iTactileType);
       
   411             TInt idx = iTactileControl.Find(controlitem,                    
       
   412 					TIdentityRelation<TTactileControlInfo>(CPeninputAnim::MatchItemByControlID));
       
   413             if(idx != KErrNotFound)
       
   414                 {                                
       
   415                 //change the tactile type
       
   416                 iTactileControl[idx].iTactileType = area.iTactileType;
       
   417                 }        	
       
   418         	}
       
   419             break;
       
   420 #endif // RD_TACTILE_FEEDBACK
       
   421         case EPeninputOpEnalbeSprite:
       
   422             {
       
   423             PanicClientIfNoParam(aParams);
       
   424             iEnableSprite = *(static_cast<TBool*>(aParams));            
       
   425             }
       
   426             break;
       
   427           
       
   428 
       
   429         default:
       
   430             {
       
   431             //panic the client for unknown command
       
   432             iFunctions->Panic();
       
   433             break;
       
   434             }
       
   435 	    }
       
   436     }
       
   437 
       
   438 
       
   439 // ---------------------------------------------------------------------------
       
   440 // CPeninputAnim::CommandReplyL
       
   441 // The window server calls this function in response to application calls 
       
   442 // to the client side command function RAnim::CommandReplyL(). 
       
   443 // This function can't leave. Otherwise window server panic
       
   444 // ---------------------------------------------------------------------------
       
   445 //
       
   446 TInt CPeninputAnim::CommandReplyL( TInt aOpcode, TAny* /*aParams*/)
       
   447     {
       
   448     TInt retValue = KErrNone;
       
   449     const RMessagePtr2* msg = iFunctions->Message();
       
   450     switch ( aOpcode )
       
   451         {
       
   452         case EPeninputOpFinishConstructionL:
       
   453             {
       
   454             iFunctions->SetSync( MAnimGeneralFunctions::ESyncNone );
       
   455             
       
   456             retValue = iMsgBufQueue.OpenGlobal(KMsgEventBufferQueue);
       
   457             //event queue for key event response from pen input servers
       
   458             iKeyMsgResponseQueue.OpenGlobal(KMsgEventResponseQueue);
       
   459             iResponseQueueSemaphore.OpenGlobal(KAnimKeyEventSemaphore);
       
   460 
       
   461 			break;
       
   462             }
       
   463 
       
   464         case EPeninputOpActivate:
       
   465             {
       
   466             Activate();
       
   467             break;
       
   468             }
       
   469         
       
   470         case EPeninputOpDeactivate:
       
   471             {
       
   472             Deactivate();
       
   473             break;
       
   474             }       
       
   475             
       
   476         case EPeninputOpLayoutUpdateArea:
       
   477         	{
       
   478         	//TUpdateDataArea s;
       
   479 			//TPckg<TUpdateDataArea> pkg(s);        	
       
   480 			TRect rect;
       
   481 			TBool flag;
       
   482 		    TPckg<TRect> rectMsg(rect);			
       
   483 		    TPckg<TBool> flagMsg(flag);    
       
   484 			
       
   485 			msg->ReadL(KMsgSlot1,rectMsg);
       
   486 			msg->ReadL(KMsgSlot2,flagMsg);
       
   487 			iSpriteFunctions->UpdateMember(0, rect,flag);			
       
   488         	  }
       
   489         	  break;
       
   490         case EPeninputOpLayoutUpdateAreaRegion:
       
   491             {
       
   492             TInt num;
       
   493             TPckg<TInt> numMsg(num);    
       
   494             msg->ReadL(KMsgSlot1,numMsg);
       
   495             TInt len = msg->GetDesLengthL(KMsgSlot2);
       
   496             TUint8* buf = new (ELeave) TUint8[len*sizeof(TUpdateArea)];
       
   497             CleanupArrayDeletePushL( buf );
       
   498             
       
   499             TPtr8 ptr(buf,len);
       
   500             msg->ReadL(KMsgSlot2,ptr);
       
   501 
       
   502             TUpdateArea* area = reinterpret_cast<TUpdateArea*>(buf);
       
   503 
       
   504             for(TInt i = 0; i < num; ++i)
       
   505                 {
       
   506                 iSpriteFunctions->UpdateMember(0, area[i].iRect,area[i].iFullUpdateFlag);
       
   507                 }
       
   508 
       
   509             CleanupStack::PopAndDestroy( buf );
       
   510         	}
       
   511         	break;
       
   512         case EPeninputOpSetLayoutPos:
       
   513             {
       
   514             TPoint pt;
       
   515             TPckg<TPoint> msgData(pt);
       
   516             msg->ReadL(KMsgSlot1,msgData);
       
   517             SetPosition(pt);            
       
   518             }
       
   519             break;
       
   520             
       
   521         case EPeninputOpCapturePointer:
       
   522             {
       
   523             TInt captureCtrlID;
       
   524 			TPckg<TBool> msgData(iIsPointerCaptured);
       
   525 			TPckg<TInt> msgCaptureCtrlIDData(captureCtrlID);
       
   526             
       
   527             msg->ReadL(KMsgSlot1,msgData);
       
   528             msg->ReadL(KMsgSlot2,msgCaptureCtrlIDData);
       
   529 #ifdef RD_TACTILE_FEEDBACK
       
   530 			// When pointer is captured by some ctrl,
       
   531 			// only the captured ctrl has tactile feedback ablity,
       
   532 			// disable all other one's.
       
   533             if (iIsPointerCaptured)
       
   534             	{
       
   535             	// Back up all the tactile area
       
   536             	iBackupTactileControl.Reset();        	
       
   537 		        TInt count = iTactileControl.Count();
       
   538 		        for(TInt i = 0; i < count; ++i)
       
   539 		            {
       
   540 		            iBackupTactileControl.Append(iTactileControl[i]);
       
   541 		            }
       
   542 		        
       
   543 		        // Clean up the original tactile area
       
   544 		        iTactileControl.Reset();		       
       
   545 		        
       
   546 		        // Find the captured ctrl, restore its tactile ablity
       
   547 		        for(TInt i = 0; i < count; ++i)
       
   548 		            {
       
   549 		            if (iBackupTactileControl[i].iId == captureCtrlID)
       
   550 		            	{
       
   551 		            	iTactileControl.Append(iBackupTactileControl[i]);
       
   552 		            	}
       
   553 		            }
       
   554 
       
   555             	}
       
   556             // When pointer released captured, 
       
   557             // restore all original tactile area.
       
   558             else 
       
   559             	{
       
   560             	if (iBackupTactileControl.Count() != 0)
       
   561             		{
       
   562             		iTactileControl.Reset();			       
       
   563 	            	
       
   564 			        TInt count = iBackupTactileControl.Count();
       
   565 			        for(TInt i = 0; i < count; ++i)
       
   566 			            {
       
   567 			            iTactileControl.Append(iBackupTactileControl[i]);
       
   568 			            }
       
   569 			        iBackupTactileControl.Reset();
       
   570             		}
       
   571             	}
       
   572 #endif            	
       
   573             }
       
   574             break;
       
   575         case EPeninputOpLayoutSizeChangedWithSize:
       
   576                 {
       
   577                 TPckg<TSize> msgData(iSpriteSize);
       
   578                 msg->ReadL(1,msgData); 
       
   579                 iSpriteFunctions->SizeChangedL();
       
   580                 }
       
   581             break;
       
   582         case EPeninputOpSimulateEvent:
       
   583             {
       
   584             TRawEvent event;
       
   585             TPckg<TRawEvent> msgData(event);
       
   586             msg->ReadL(KMsgSlot1,msgData); 
       
   587             iIsSimulatedEvent = ETrue;
       
   588             iFunctions->PostRawEvent(event);
       
   589             iIsSimulatedEvent = EFalse;
       
   590             
       
   591             }
       
   592             break;    
       
   593             
       
   594 #ifdef RD_TACTILE_FEEDBACK             
       
   595         case EPeninputOpRegisterFeedbackArea:
       
   596             {						
       
   597             GetFeedbackAreaDataL(iTactileControl,msg);            
       
   598             }
       
   599             break;
       
   600             
       
   601         case EPeninputOpDeRegisterFeedbackArea:
       
   602             {
       
   603             //Advanced Tactile feedback REQ417-47932
       
   604             RArray<TTactileControlInfo> controlarray;
       
   605             CleanupClosePushL(controlarray);
       
   606             
       
   607             GetFeedbackAreaDataL(controlarray,msg);
       
   608             
       
   609             //remove all registered feedback area
       
   610             const TInt KRemoveAllId = -1;           
       
   611             if(controlarray.Count() && controlarray[0].iId == KRemoveAllId && 
       
   612 										controlarray[0].iArea == TRect(0,0,0,0))
       
   613                 {
       
   614                 //remove all
       
   615                 iTactileControl.Reset();
       
   616                 }
       
   617             else
       
   618                 {
       
   619                 //remove the area
       
   620                 for(TInt i = 0; i < controlarray.Count(); ++i)
       
   621                     {
       
   622                     //find id first
       
   623                     TInt idx = iTactileControl.Find(controlarray[i], 
       
   624 								TIdentityRelation<TTactileControlInfo>(CPeninputAnim::MatchItemByControlID));
       
   625                     
       
   626                     if(idx != KErrNotFound)
       
   627                         {
       
   628                         iTactileControl.Remove(idx);                       
       
   629                         }
       
   630                     }
       
   631                 }
       
   632                 
       
   633             CleanupStack::PopAndDestroy( 1, &controlarray );
       
   634             }
       
   635             break;
       
   636         
       
   637             
       
   638         case EPeninputOpChangeFeedbackArea:            
       
   639             {
       
   640             //Advanced Tactile feedback REQ417-47932
       
   641             RArray<TTactileControlInfo> controlarray;
       
   642             RArray<TRect> prevArea;
       
   643             
       
   644             CleanupClosePushL(controlarray);
       
   645             CleanupClosePushL(prevArea);
       
   646             
       
   647             GetFeedbackAreaDataL(controlarray,msg,&prevArea);
       
   648             //change the area one by one            
       
   649             for(TInt i = 0; i < controlarray.Count(); ++i)
       
   650                 {
       
   651                 //find id first
       
   652                 TInt idx = iTactileControl.Find(controlarray[i], 
       
   653                 		   TIdentityRelation<TTactileControlInfo>(CPeninputAnim::MatchItemByControlID));
       
   654                                     
       
   655                 if(idx != KErrNotFound)
       
   656                     {
       
   657                     //check the rect
       
   658                     if(prevArea[i] == iTactileControl[idx].iArea)
       
   659                         {
       
   660                         //change the rect
       
   661                         iTactileControl[idx].iArea = controlarray[i].iArea;
       
   662                         break;
       
   663                         }
       
   664                     }
       
   665                 }
       
   666             
       
   667             CleanupStack::PopAndDestroy( 2, &controlarray );
       
   668             }
       
   669         
       
   670             break;
       
   671             
       
   672         //Advanced Tactile feedback REQ417-47932    
       
   673         case EPeninputOpChangeFeedbackType:            
       
   674             {           
       
   675             RArray<TTactileControlInfo> controlarray;
       
   676             CleanupClosePushL(controlarray);
       
   677             
       
   678             GetFeedbackAreaDataL(controlarray,msg);
       
   679             //change the area one by one
       
   680             for(TInt i = 0; i < controlarray.Count(); ++i)
       
   681                 {
       
   682                 //find id first
       
   683                 TInt idx = iTactileControl.Find(controlarray[i],                 		   
       
   684 						   TIdentityRelation<TTactileControlInfo>(CPeninputAnim::MatchItemByControlID));
       
   685                 if(idx != KErrNotFound)
       
   686                     {
       
   687                     //change the tactile feedback type
       
   688 					iTactileControl[idx].iTactileType = controlarray[i].iTactileType;
       
   689                     break;
       
   690                     }
       
   691                 }
       
   692             
       
   693             CleanupStack::PopAndDestroy( 1, &controlarray );
       
   694             }
       
   695   
       
   696             break;
       
   697             
       
   698 #endif // RD_TACTILE_FEEDBACK 
       
   699         case EPeninputOpRequestDSAState:                        
       
   700             {
       
   701 		    TPckgC<TBool> flagMsg(iDSAState);    
       
   702 			
       
   703 			msg->WriteL(KMsgSlot1,flagMsg);
       
   704             
       
   705             }
       
   706             break;
       
   707         default:
       
   708             // unsupported opcode, panic the client
       
   709             {                
       
   710             iFunctions->Panic();
       
   711             retValue = KErrNotSupported;
       
   712             }
       
   713             break;
       
   714         }
       
   715 
       
   716     return retValue;
       
   717     }
       
   718 
       
   719 // ---------------------------------------------------------------------------
       
   720 // CPeninputAnim::Activate
       
   721 // Makes PENINPUT window visible
       
   722 // ---------------------------------------------------------------------------
       
   723 //
       
   724 void CPeninputAnim::Activate()
       
   725     {
       
   726 	if(!iIsActive)
       
   727 	    {
       
   728 		iSpriteFunctions->SetPosition(iSpritePosition);
       
   729 		if(iEnableSprite)
       
   730 		    iSpriteFunctions->Activate(ETrue);
       
   731 		iFunctions->GetRawEvents(ETrue);
       
   732 		iIsActive = ETrue;		
       
   733 
       
   734 		StartTimer();
       
   735 	    }        
       
   736     }
       
   737 
       
   738 // ---------------------------------------------------------------------------
       
   739 // CPeninputAnim::Deactivate
       
   740 // Makes PENINPUT window invisible
       
   741 // ---------------------------------------------------------------------------
       
   742 //
       
   743 void CPeninputAnim::Deactivate()
       
   744     {
       
   745 	if(iIsActive)
       
   746 	    {
       
   747 	    if(iEnableSprite)
       
   748 		    iSpriteFunctions->Activate(EFalse);
       
   749 		iFunctions->GetRawEvents(EFalse);        
       
   750 		iIsActive = EFalse;
       
   751 		
       
   752 		StopTimer();
       
   753 	    }        
       
   754     }
       
   755     
       
   756 #ifdef RD_TACTILE_FEEDBACK
       
   757 // ---------------------------------------------------------------------------
       
   758 // CPeninputAnim::DoTactileFeedBack
       
   759 // Give tactile feedback
       
   760 // ---------------------------------------------------------------------------
       
   761 //						
       
   762 void CPeninputAnim::DoTactileFeedBack(const TPoint& aPos)
       
   763     {
       
   764     if ( iFeedback ) 
       
   765         {
       
   766         TInt count = iTactileControl.Count();
       
   767         for(TInt i = 0; i < count; ++i)
       
   768             {
       
   769             if(iTactileControl[i].iArea.Contains(aPos))
       
   770                 {
       
   771                 iFeedback->InstantFeedback((TTouchLogicalFeedback)iTactileControl[i].iTactileType);
       
   772                 return;
       
   773                 }                 
       
   774         	}           
       
   775         }
       
   776     }
       
   777 #endif // RD_TACTILE_FEEDBACK
       
   778 
       
   779 // ---------------------------------------------------------------------------
       
   780 // CPeninputAnim::OnRawButton1Down
       
   781 // Handles raw pen down events
       
   782 // Can't leave, since this is run in window server side.
       
   783 // return value indicating whether the event was handled by this function    
       
   784 // ---------------------------------------------------------------------------
       
   785 //
       
   786 
       
   787 TBool CPeninputAnim::OnRawButton1Down(const TRawEvent& aRawEvent)
       
   788     {
       
   789 	if(iIsSimulatedEvent)
       
   790 	    {
       
   791 		return EFalse;
       
   792 	    }
       
   793 		
       
   794     if(iDirty )
       
   795         {
       
   796         Refresh();
       
   797         }
       
   798     
       
   799 	if(iDiscreetPoped && iDiscreetPopArea.Contains(aRawEvent.Pos()))
       
   800 		{
       
   801 		iDiscreetPopedCapture = ETrue;
       
   802 		return EFalse;
       
   803 		}
       
   804 	TRect rect(iSpritePosition, iSpriteSize);        
       
   805 	if(rect.Contains(aRawEvent.Pos()))
       
   806 	    {                
       
   807 #ifdef RD_TACTILE_FEEDBACK		    
       
   808 	    //give tactile feedback	    
       
   809 	    if(iTactileSupported)
       
   810             DoTactileFeedBack(aRawEvent.Pos() - rect.iTl);
       
   811 #endif // RD_TACTILE_FEEDBACK	
       
   812 		iIsPenDown = ETrue;
       
   813 		PostRawEvent(aRawEvent); 
       
   814 		return ETrue;
       
   815 	    }
       
   816 
       
   817 	if(iIsPointerCaptured)
       
   818 	    {                    
       
   819 		PostRawEvent(aRawEvent);
       
   820 		return ETrue;
       
   821 	    }
       
   822 
       
   823 	//pointer outside of input area,inform layout
       
   824 	SendRawEvent(aRawEvent);
       
   825 
       
   826 	return EFalse;
       
   827     }
       
   828 
       
   829 TBool CPeninputAnim::OnRawButton1Up(const TRawEvent& aRawEvent)
       
   830     {
       
   831 	if(iIsSimulatedEvent)
       
   832 	    {
       
   833 		return EFalse;
       
   834 	    }
       
   835 
       
   836 	//For discreetPop
       
   837 	if(iDiscreetPopedCapture )
       
   838 		{
       
   839 		iDiscreetPopedCapture = EFalse;
       
   840 		return EFalse;
       
   841 		}
       
   842 	if(iIsPenDown)
       
   843 	    {      
       
   844 		iIsPenDown = EFalse;
       
   845 		
       
   846 		TRect rect(iSpritePosition, iSpriteSize);        
       
   847 		if(rect.Contains(aRawEvent.Pos()))
       
   848 		    {
       
   849 			//send pen up event immediately
       
   850 			SendRawEvent(aRawEvent);
       
   851 			return ETrue;                    
       
   852 		    }
       
   853 	    }
       
   854 	
       
   855 	if(iIsPointerCaptured)
       
   856 	    {                    
       
   857 		PostRawEvent(aRawEvent);
       
   858 		return ETrue;
       
   859 	    }
       
   860     
       
   861 	//pointer outside of input area,inform layout
       
   862 	SendRawEvent(aRawEvent);
       
   863 
       
   864 	return EFalse;	
       
   865     }
       
   866 
       
   867 TBool CPeninputAnim::OnRawPointerMove(const TRawEvent& aRawEvent)
       
   868     {
       
   869 	if(iIsSimulatedEvent)
       
   870 	    {
       
   871 		return EFalse;
       
   872 	    }
       
   873 	if(iDiscreetPopedCapture)
       
   874 	    {
       
   875 	    return EFalse;
       
   876 	    }
       
   877 #ifdef RD_TACTILE_FEEDBACK		    
       
   878 	TRect rect(iSpritePosition, iSpriteSize);        
       
   879 	if( iIsPenDown && iIsPointerCaptured)
       
   880 	    {                
       
   881 	    //give tactile feedback	    
       
   882 
       
   883 		PostRawEvent(aRawEvent); 
       
   884 		return ETrue;
       
   885 	    }
       
   886 #endif // RD_TACTILE_FEEDBACK	
       
   887 
       
   888 	if(iIsPointerCaptured || iIsPenDown)
       
   889 	    {                    
       
   890 		PostRawEvent(aRawEvent);
       
   891 		return ETrue;
       
   892 	    }
       
   893 	
       
   894 	return EFalse;
       
   895     }
       
   896 
       
   897 // ---------------------------------------------------------------------------
       
   898 // CPeninputAnim::SetPosition
       
   899 // called when sprite has been moved
       
   900 // ---------------------------------------------------------------------------
       
   901 //
       
   902 
       
   903 TPoint CPeninputAnim::SetPosition(const TPoint& aNewPos)
       
   904     {
       
   905 	if(aNewPos != iSpritePosition)
       
   906 	    {
       
   907 		iSpritePosition = aNewPos;
       
   908 		iSpriteFunctions->SetPosition(iSpritePosition);	
       
   909 	    }
       
   910 	return iSpritePosition;
       
   911     }
       
   912 
       
   913 // ---------------------------------------------------------------------------
       
   914 // CPeninputAnim::UpdateArea
       
   915 // Update sprite rect
       
   916 // ---------------------------------------------------------------------------
       
   917 //
       
   918 void CPeninputAnim::UpdateArea(const TRect& aRect, TBool aFullUpdate)
       
   919     {
       
   920 	if(iIsActive)
       
   921         {
       
   922 	    // if function is called without specifying the parameter aRect
       
   923 	    // (using default param value) the whole area drawn to is updated
       
   924 	    iSpriteFunctions->UpdateMember(0, aRect, aFullUpdate);
       
   925         }
       
   926     }
       
   927 
       
   928 // ---------------------------------------------------------------------------
       
   929 // CPeninputAnim::TimerCallBack
       
   930 // Callback function of CPeriodic
       
   931 // ---------------------------------------------------------------------------
       
   932 //
       
   933 TInt CPeninputAnim::FlushTimerCallBack(TAny* aPtr)
       
   934     {
       
   935     CPeninputAnim* self = static_cast<CPeninputAnim*>(aPtr);            
       
   936     self->FlushRawEventBuffer();            
       
   937     return KErrNone;
       
   938     }
       
   939   
       
   940 // ---------------------------------------------------------------------------
       
   941 // CPeninputAnim::SendRawEvent
       
   942 // Send event to pen input server by buffering it
       
   943 // ---------------------------------------------------------------------------
       
   944 //    
       
   945 void CPeninputAnim::SendRawEvent(const TRawEvent& aRawEvent)
       
   946     {
       
   947     //save to buffer first
       
   948     iEventBuffer.iEvent[iEventBuffer.iNum] = aRawEvent;
       
   949     iEventBuffer.iNum++;
       
   950 
       
   951     FlushRawEventBuffer();
       
   952     }
       
   953 
       
   954 // ---------------------------------------------------------------------------
       
   955 // CPeninputAnim::PostRawEvent
       
   956 // Save the event to the buffer
       
   957 // ---------------------------------------------------------------------------
       
   958 //        
       
   959 void CPeninputAnim::PostRawEvent(const TRawEvent& aRawEvent)
       
   960     {
       
   961     if(iEventBuffer.iNum >= KMaxEvent)
       
   962         {
       
   963         FlushRawEventBuffer();
       
   964 	    }
       
   965 	
       
   966     iEventBuffer.iEvent[iEventBuffer.iNum] = aRawEvent;
       
   967     iEventBuffer.iNum++;
       
   968     }
       
   969 
       
   970 // ---------------------------------------------------------------------------
       
   971 // CPeninputAnim::FlushRowEventBuffer
       
   972 // Send pointer event to pen input serrver, and return error code
       
   973 // ---------------------------------------------------------------------------
       
   974 //
       
   975 TInt CPeninputAnim::FlushRawEventBuffer()
       
   976     {
       
   977 	TInt ret = KErrNone;
       
   978 	
       
   979     if(iEventBuffer.iNum > 0)
       
   980 	    {
       
   981         ret = iMsgBufQueue.Send(iEventBuffer);
       
   982        	iEventBuffer.iNum = 0;        	
       
   983         }
       
   984     
       
   985     return ret;
       
   986     }
       
   987 
       
   988 // ---------------------------------------------------------------------------
       
   989 // CPeninputAnim::OnRawKeyEvent
       
   990 // Send raw key event to pen input server for processing.
       
   991 // Wait until it's processed or timer out
       
   992 // ---------------------------------------------------------------------------
       
   993 //    
       
   994 TBool CPeninputAnim::OnRawKeyEvent(const TRawEvent& aRawEvent)
       
   995     {
       
   996 	TInt ret = KErrNone;
       
   997 	
       
   998 	//first sends all buffered event out
       
   999     FlushRawEventBuffer();
       
  1000     
       
  1001     //clear the signal and the response msg queue
       
  1002     TBool isHandled = EFalse;
       
  1003     ret = iKeyMsgResponseQueue.Receive(isHandled);
       
  1004     while(ret == KErrNone)
       
  1005 	    {
       
  1006         iResponseQueueSemaphore.Wait();
       
  1007         ret = iKeyMsgResponseQueue.Receive(isHandled);
       
  1008         }
       
  1009 
       
  1010 	//send the event directly        
       
  1011     iEventBuffer.iNum = 1;
       
  1012     iEventBuffer.iEvent[0] = aRawEvent;
       
  1013     ret = FlushRawEventBuffer();
       
  1014     
       
  1015     isHandled = EFalse;
       
  1016     if(ret == KErrNone) 
       
  1017         {
       
  1018 	    //wait for the key event processed.    
       
  1019 	    ret = iResponseQueueSemaphore.Wait(KResponseQueueWaitTime);
       
  1020 	    if(ret == KErrNone)
       
  1021 	        {        
       
  1022 	        //read the response from msg queue
       
  1023 	        iKeyMsgResponseQueue.Receive(isHandled);
       
  1024 	        }
       
  1025         }
       
  1026 
       
  1027     return isHandled;
       
  1028     }
       
  1029 
       
  1030 // ---------------------------------------------------------------------------
       
  1031 // CPeninputAnim::StartTimer
       
  1032 // Initial and start timer
       
  1033 // ---------------------------------------------------------------------------
       
  1034 // 
       
  1035 void CPeninputAnim::StartTimer()
       
  1036     {
       
  1037 	iFlushTimer->Start(
       
  1038 		KFlushTimerPeriod, 
       
  1039 		KFlushTimerPeriod, 
       
  1040 		TCallBack(FlushTimerCallBack, this));	
       
  1041     }
       
  1042 	
       
  1043 // ---------------------------------------------------------------------------
       
  1044 // CPeninputAnim::StopTimer
       
  1045 // Cancel timer
       
  1046 // ---------------------------------------------------------------------------
       
  1047 // 
       
  1048 void CPeninputAnim::StopTimer()
       
  1049     {
       
  1050 	iFlushTimer->Cancel();	
       
  1051     }
       
  1052 
       
  1053 #ifdef RD_TACTILE_FEEDBACK
       
  1054 void CPeninputAnim::GetFeedbackAreaDataL(RArray<TTactileControlInfo>& aTactileControlArray,
       
  1055 										 const RMessagePtr2* msg, 
       
  1056                                          RArray<TRect>* aPrevRectArray)
       
  1057     {
       
  1058     TInt num;
       
  1059     TPckg<TInt> numBuf(num);
       
  1060     msg->ReadL(KMsgSlot1,numBuf);
       
  1061     TTactileFeedbackArea* area = new(ELeave) TTactileFeedbackArea[num];
       
  1062 
       
  1063     CleanupArrayDeletePushL( area );
       
  1064 
       
  1065     TPtr msgData(reinterpret_cast<TUint16*>(area), num*sizeof(TTactileFeedbackArea)/2);
       
  1066     msg->ReadL(KMsgSlot2,msgData);           
       
  1067             
       
  1068     for(TInt i = 0 ; i < num; ++i)
       
  1069         {
       
  1070         //Advanced Tactile feedback REQ417-47932
       
  1071         aTactileControlArray.Append(TTactileControlInfo(area[i].iId,
       
  1072 									area[i].iNewRect,area[i].iTactileType));      
       
  1073         //aRectArray.Append(area[i].iNewRect);                
       
  1074         if(aPrevRectArray)
       
  1075             aPrevRectArray->Append(area[i].iPrevRect);                    
       
  1076         }
       
  1077 
       
  1078     CleanupStack::PopAndDestroy( area );            
       
  1079     }
       
  1080 
       
  1081 // ---------------------------------------------------------------------------
       
  1082 // CPeninputAnim::MatchItemByControlID
       
  1083 // Compare the Item by ID
       
  1084 // ---------------------------------------------------------------------------
       
  1085 // 
       
  1086 TBool CPeninputAnim::MatchItemByControlID (const TTactileControlInfo& aFirst, const TTactileControlInfo& aSecond)
       
  1087 	{
       
  1088 	if (aFirst.iId == aSecond.iId)
       
  1089 		return ETrue;
       
  1090 	return EFalse;
       
  1091 	}
       
  1092 
       
  1093 // ---------------------------------------------------------------------------
       
  1094 // CPeninputAnim::MatchItemByControlIDAndArea
       
  1095 // Compare the Item by ID and Area
       
  1096 // ---------------------------------------------------------------------------
       
  1097 // 
       
  1098 TBool CPeninputAnim::MatchItemByControlIDAndArea (const TTactileControlInfo& aFirst, const TTactileControlInfo& aSecond)
       
  1099 	{
       
  1100 	if ((aFirst.iId == aSecond.iId) && (aFirst.iArea == aSecond.iArea))
       
  1101 		return ETrue;
       
  1102 	return EFalse;
       
  1103 	}
       
  1104 #endif // RD_TACTILE_FEEDBACK    
       
  1105 TInt CPeninputAnim::DiscreetPopChangeNotification(TAny* aObj)
       
  1106     {
       
  1107     if (aObj)
       
  1108         {
       
  1109         static_cast<CPeninputAnim*>(aObj)->HandleDiscreetPopNotification();
       
  1110         return KErrNone;
       
  1111         }
       
  1112     else
       
  1113         {
       
  1114         return KErrArgument;
       
  1115         }
       
  1116     }
       
  1117 
       
  1118 void CPeninputAnim::Refresh()
       
  1119     {
       
  1120     iDiscreetPopArea = iAknUiSrv.GetInUseGlobalDiscreetPopupRect();
       
  1121     if(iDiscreetPopArea.Size().iWidth > 0)
       
  1122         {
       
  1123         iDiscreetPoped = ETrue;
       
  1124         }    
       
  1125     else
       
  1126         {
       
  1127         iDiscreetPoped = EFalse;
       
  1128         iDiscreetPopedCapture = EFalse;
       
  1129         }
       
  1130     iDirty = EFalse;
       
  1131     }
       
  1132 
       
  1133 void CPeninputAnim::HandleDiscreetPopNotification()
       
  1134     {
       
  1135     iDirty = ETrue;
       
  1136     }
       
  1137     
       
  1138 CSubscriber::CSubscriber(TCallBack aCallBack, RProperty& aProperty)
       
  1139     :
       
  1140     CActive(EPriorityNormal), iCallBack(aCallBack), iProperty(aProperty)
       
  1141     {
       
  1142     CActiveScheduler::Add(this);
       
  1143     }
       
  1144 
       
  1145 CSubscriber::~CSubscriber()
       
  1146     {
       
  1147     Cancel();
       
  1148     }
       
  1149 
       
  1150 void CSubscriber::SubscribeL()
       
  1151     {
       
  1152     if (!IsActive())
       
  1153         {
       
  1154         iProperty.Subscribe(iStatus);
       
  1155         SetActive();
       
  1156         }
       
  1157     }
       
  1158 
       
  1159 void CSubscriber::StopSubscribe()
       
  1160     {
       
  1161     Cancel();
       
  1162     }
       
  1163 
       
  1164 void CSubscriber::RunL()
       
  1165     {
       
  1166     if (iStatus.Int() == KErrNone)
       
  1167         {
       
  1168         iCallBack.CallBack();
       
  1169         SubscribeL();
       
  1170         }
       
  1171     }
       
  1172 
       
  1173 void CSubscriber::DoCancel()
       
  1174     {
       
  1175     iProperty.Cancel();
       
  1176     }
       
  1177 // End of File