textinput/peninputarc/src/peninputserverapp/peninputserversession.cpp
changeset 0 eb1f2e154e89
child 13 1bbdde98cc2d
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/textinput/peninputarc/src/peninputserverapp/peninputserversession.cpp	Tue Feb 02 01:02:04 2010 +0200
@@ -0,0 +1,568 @@
+/*
+* Copyright (c) 2005-2006 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""
+* which accompanies this distribution, and is available
+* at the URL "http://www.eclipse.org/legal/epl-v10.html".
+*
+* Initial Contributors:
+* Nokia Corporation - initial contribution.
+*
+* Contributors:
+*
+* Description:  Implementation for peninput server session class
+*
+*/
+
+
+//INCLUDE FILES
+#include <e32svr.h>
+
+#include "peninputcmd.h"
+#include "peninputclientserver.h"
+#include "peninputanimcommand.h"
+#include "peninputserver.h"
+#include "peninputserversession.h"
+
+const TInt KAllEventIndex = -1;
+const TInt KFirstEventIndex = 0;
+const TInt KMaxEventBuf = 50;
+// ======== MEMBER FUNCTIONS ========
+
+// ---------------------------------------------------------------------------
+// CPeninputServerSession::CPeninputServerSession
+// ---------------------------------------------------------------------------
+//
+CPeninputServerSession::CPeninputServerSession( RThread &aClient, 
+                            CPeninputServer& aServer)
+	                        : iPenInputSvr( aServer ),
+    	                      iObserverActive(EFalse),
+    	                      iCombinedMsgNum(0),
+    	                      iCombinedEventId(ESignalKeyEvent),
+    	                      iAppInfoType(EAppIndicatorMsg),
+    	                      iDisabledUiType(0)
+    {
+    iPenInputSvr.IncreaseSessionCount();
+    iClientId = aClient.Id();
+    RProcess process;
+    if ( KErrNone == aClient.Process(  process ) )
+        {
+        iClientProcess = process.Id();   
+        process.Close();
+        }
+    }
+// ---------------------------------------------------------------------------
+// CPeninputServerSession::ConstructL
+// ---------------------------------------------------------------------------
+//
+void CPeninputServerSession::ConstructL()
+    {
+    iAppInfo = KNullDesC().AllocL();
+    iCombinedEventBuf.CreateMaxL(KMaxEventBuf);
+    iCombinedEventBuf.Zero();    
+    }
+
+// ---------------------------------------------------------------------------
+// CPeninputServerSession::NewL
+// ---------------------------------------------------------------------------
+//
+CPeninputServerSession* CPeninputServerSession::NewL( RThread &aClient, 
+                            						CPeninputServer& aServer)
+    {
+    CPeninputServerSession* session = new(ELeave) CPeninputServerSession(
+                                           aClient, aServer);
+    CleanupStack::PushL(session);
+    session->ConstructL();
+    CleanupStack::Pop(session);
+    return session;
+    }
+
+
+// ---------------------------------------------------------------------------
+// CPeninputServerSession::ServiceL
+// Possible leave is handled by the CPeninputServer::RunError
+// ---------------------------------------------------------------------------
+//
+void CPeninputServerSession::ServiceL( const RMessage2& aMessage )
+    {
+    
+    switch ( aMessage.Function() )
+        {
+
+        case EPeninputServerRequestMessageNotification:
+            // asynchnorous observation request issued, store it
+            // a client can have only one observation request at a time
+            if(!iObserverActive)
+                {
+                iPendingRequest = aMessage;
+                iObserverActive = ETrue;
+                //if already some events buffered,send the event
+                if(iDataBuf.Count())
+                    {
+                    iPendingRequest.Complete(iSignalCodeArray[0]);                
+                    iObserverActive = EFalse;
+                    }
+                }
+            else
+                {
+                // cancel this request because notify request has already been issued
+                aMessage.Complete(KErrCancel);
+                }
+            
+            break;
+
+        case EPeninputServerCancelMessageNotification:
+            {
+            aMessage.Complete(KErrNone);  
+            if(iObserverActive)
+                {
+                iPendingRequest.Complete(KErrCancel);
+                iObserverActive = EFalse;
+                }
+            ProcessPendingEventBeforeExit();
+            //iSemaphore.Signal();            
+            }
+            break;
+            
+        default:
+            {
+            
+            //TRAPD(err, DoServiceL(aMessage));
+            //if(KErrNone != err)
+            //    aMessage.Complete(err);
+            TInt ret = DoServiceL(aMessage);
+            //aMessage.Complete(ret);
+            
+            }
+        }
+    }
+
+// ---------------------------------------------------------------------------
+// CPeninputServerSession::GetDisabledLayouts
+// ---------------------------------------------------------------------------
+//
+const TProcessId& CPeninputServerSession::ClientProcessId( )
+    {
+    return iClientProcess ;
+    }
+    
+TInt CPeninputServerSession::BuildEventData()
+    {
+    if(iCombinedMsgNum > 0)     //the previous combined msg was not sent yet. No need to do again
+        return iCombinedMsgNum;    
+    TInt n = 0;
+    //check how many signal can be combined
+    while( n < iSignalCodeArray.Count() && iSignalCodeArray[n] == iCombinedEventId)
+         ++n;
+    if(n <= 0)
+        return 0;
+    iCombinedMsgNum = 0;
+    for(; iCombinedMsgNum < n ; ++iCombinedMsgNum)
+        {
+        //check memory fist
+        if(iCombinedEventBuf.MaxLength() < iCombinedEventBuf.Length() + iDataBuf[iCombinedMsgNum]->Length()) 
+            {
+            TInt err = iCombinedEventBuf.ReAlloc( KMaxEventBuf + 
+                                      iCombinedEventBuf.Length() + 
+                                      iDataBuf[iCombinedMsgNum]->Length());
+            if(err != KErrNone)
+                {
+                break;
+                }
+            }
+        //copy data
+        iCombinedEventBuf.Append(*(iDataBuf[iCombinedMsgNum]));        
+        }
+    return iCombinedMsgNum;
+    }
+    
+void CPeninputServerSession::RemoveEventDatas(TInt aNum)
+    {
+    aNum = aNum > 0 ? aNum : 1;
+    for(TInt i = 0 ; i < aNum; ++i)
+        RemoveEventDataByIdx(KFirstEventIndex); 
+    iCombinedEventBuf.Zero();
+    iCombinedMsgNum = 0;
+    }
+    
+TInt CPeninputServerSession::SendEventData(const RMessage2& aMessage, const TDesC& aData)
+    {
+    TInt ret = KErrNone;
+    TInt maxBufLen = aMessage.Int0();    
+    if(maxBufLen >= aData.Length())
+        {
+        TRAP_IGNORE(aMessage.WriteL(1,aData));
+        
+        //remove the data
+        RemoveEventDatas(iCombinedMsgNum > 0 ? iCombinedMsgNum : 1);
+        }
+    else
+        {
+        ret = aData.Length();
+        }
+    
+    return ret;    
+    }
+// ---------------------------------------------------------------------------
+// CPeninputServerSession::DoServiceL
+// Possible leave is handled by the CPeninputServer::RunError
+// ---------------------------------------------------------------------------
+//
+TInt CPeninputServerSession::DoServiceL( const RMessage2& aMessage )
+    {
+    
+    //TInt err = KErrNone;
+    TInt ret = KErrNone;
+    switch ( aMessage.Function() )
+        {            
+        case EPeninputRequestUiNotificationCompleted:
+            {
+            RemoveEventDataByIdx(KFirstEventIndex);
+            iPenInputSvr.ExecutePendingAnimCmd();
+            }
+            break;
+            
+        case EPeninputServerClearServerEvent:
+            {
+            RemoveEventDataByIdx(KAllEventIndex);
+            }
+            break;
+            
+        case EPeninputRequestGetServerEventData:
+            {
+            if(iDataBuf.Count())
+                {                
+                TInt combinedEventNum = BuildEventData();
+                if(combinedEventNum)
+                    ret = SendEventData(aMessage,iCombinedEventBuf);
+                else
+                    ret = SendEventData(aMessage,*iDataBuf[KFirstEventIndex]);
+                
+//                if(ret == KErrNone)
+  //                  RemoveEventDatas(combinedEventNum);
+                }
+            else
+                {
+                aMessage.WriteL(1,KNullDesC);
+                }
+            }
+            break;        
+            
+        case EPeninputRequestGetServerEventDataNumber:
+            {
+            TInt num = iDataBuf.Count();
+            TPckgC<TInt> msg(num);
+            
+            aMessage.WriteL(0,msg);
+            }
+            break;
+          
+        case EPeninputRequestGetDisableLayout:
+            {
+            //TInt layoyts = 0;
+            //CPeninputServerSession* pSession = static_cast<CPeninputServerSession*>(aMessage.Session());
+            //GetProcessLayouts( pSession->ClientProcessId(), layoyts );
+            TInt dsaDisableUIType = iPenInputSvr.DisabledByDSA();
+            TInt orientationDisableType = iPenInputSvr.DisabledByOrientation();
+            if( dsaDisableUIType )
+            	{
+            	iDsaEverHappened = ETrue;
+            	}
+            TPckg<TInt> msg(iDisabledUiType | dsaDisableUIType | orientationDisableType);
+
+            aMessage.WriteL(0,msg);            
+            }
+            break;            
+        case EPeninputRequestDisableLayout:
+            {
+            TInt layouts  = aMessage.Int0(); 
+            //CPeninputServerSession* pSession = static_cast<CPeninputServerSession*>(aMessage.Session());
+            //SetProcessLayouts( pSession->ClientProcessId(), layouts );
+            if(layouts < 0 )
+                {
+                iDisabledUiType = 0; //reset.
+                }
+            else
+                {
+                iDisabledUiType |= layouts;
+                }
+            }
+            break;
+            
+        case EPeninputRequestUiIsVisible:
+        case EPeninputServerRequestSetDisplayMode:
+        case EPeninputRequestUiEditorMaxLength:
+        case EPeninputRequestUiSetUiPos:        
+        case EPeninputRequestUiGetUiPos:        
+        case EPeninputRequestUiSendAppEditorText:        
+        case EPeninputRequestActivateLayout:  
+        case EPeninputRequestActivateLayoutInGlobalNotes:
+        case EPeninputRequestDimLayout:
+        case EPeninputRequestSetUiLayoutId:
+        case EPeninputRequestSetUiLayoutIdWithData:
+        case EPeninputRequestResourceChanged:
+        case EPenInputRequestGetImePluginIdList:
+        case EPenInputRequestGetPenSupportLanguages:
+        case EPeninputRequestIsForeground:
+        case EPeninputRequestSetForeground:
+        case EPeninputRequestRelinquishForeground:
+        case EPeninputRequestAddUiObserver:
+        case EPeninputRequestIsLayoutDimmed:
+        //case EPeninputRequestChangeUiObserverType:
+        case EPeninputRequestRemoveUiObserver:            
+        //case EPeninputRequestDisableLayout:   
+        case EPeninputRequestServerThreadId:
+        //case EPeninputRequestGetDisableLayout:
+        case EPeninputBackgroudDefaultOri:
+        case EPeninputRequestInternalDimLayout:
+        case EPeninputRequestDimResChangeLayout:
+        case EPeninputRequestSupportInputMode:
+        case EPeninputRequestSetInputLanguage:
+            ret = iPenInputSvr.HandleMessageL(aMessage);            
+            break;
+        case EPeninputRequestUpdateAppInfo:            
+            {
+            ret = HandleAppInfoChange(aMessage);
+            if (ret == EBadRequest)
+                {
+                PanicClient(aMessage,EBadRequest );
+                return EBadRequest;                
+                }
+            }
+            break;
+        case EPeninputRequestHandleClientCommand:
+            {              
+            ret = iPenInputSvr.HandleCommandL(aMessage);
+            }
+            break;        
+            
+        // requests we don't understand at all are a different thing,
+        // so panic the client here, this function also completes the message
+        default:
+            {
+            PanicClient(aMessage,EBadRequest );
+            return EBadRequest;
+            }
+        }
+
+    aMessage.Complete(ret);
+    return ret;
+    }
+
+
+// ---------------------------------------------------------------------------
+// CPeninputServerSession::SignalClientL
+// ---------------------------------------------------------------------------
+//
+TBool CPeninputServerSession::CompletePendingRequestL(TInt aSignalCode,
+                                        const TDesC& aEventData, int aPos)
+    {
+    TBool ok = EFalse;
+    HBufC* data = aEventData.AllocLC();
+//    iDataBuf.AppendL(data);
+    if(aPos < 0) //append to the end
+        {        
+        iSignalCodeArray.Append(aSignalCode);
+        iDataBuf.AppendL(data);
+        }
+    else
+        {
+        iSignalCodeArray.Insert(aSignalCode,aPos);
+        iDataBuf.InsertL(data,aPos);        
+        }    
+    CleanupStack::Pop();//data
+    
+    if(iObserverActive)
+        {             
+        iPendingRequest.Complete(aSignalCode);
+        iObserverActive = EFalse;
+        ok = ETrue;
+        }
+    return ok;
+    }
+// ---------------------------------------------------------------------------
+// CPeninputServerSession::SignalClientL
+// ---------------------------------------------------------------------------
+//
+TBool CPeninputServerSession::SignalClientL(TInt aSignalCode,
+                                                const TDesC& aEventData)
+    {
+    return CompletePendingRequestL(aSignalCode,aEventData);    
+    }
+
+
+// ---------------------------------------------------------------------------
+// CPeninputServerSession::SignalUiActivationObserver
+// ---------------------------------------------------------------------------
+//
+TBool CPeninputServerSession::SignalUiActivationObserver(TInt aSignalCode, 
+                                                         TInt aType)
+    {    
+    //check registerd UI type
+    if((aType & iRegistedPenUiType) || (iRegistedPenUiType == EPluginInputModeAll))
+        {        
+        //insert the notification event before other event as anim object is waiting 
+        // for client process.
+        TInt i = iSignalCodeArray.Count() - 1;
+        for( ; i >=0 ; i--)
+            {
+            if(ESignalPenUiActivated == iSignalCodeArray[i] ||
+                        ESignalPenUiDeActivated == iSignalCodeArray[i])
+                        break;
+            }
+        TRAP_IGNORE( CompletePendingRequestL(aSignalCode,KNullDesC,++i) );
+        return ETrue;
+        }    
+        
+    return EFalse;
+    }
+
+// ---------------------------------------------------------------------------
+// CPeninputServerSession::ProcessPendingEventBeforeExit
+// ---------------------------------------------------------------------------
+//
+void CPeninputServerSession::ProcessPendingEventBeforeExit()
+    {
+    //only process pen ui notification event. Other events are discarded
+    
+    //for(TInt i = 0; i < iDelayedCmd.Count(); i++)
+    //for(TInt i = 0; i < iDelayedCmd; i++)
+        {
+        iPenInputSvr.ExecutePendingAnimCmd();       
+      //  iDelayedCmd --;
+        }
+    //remove any command
+    for(TInt i = 0; i < iDataBuf.Count(); i++)
+        {
+        delete iDataBuf[i];
+        }
+    iDataBuf.Reset();    
+    iSignalCodeArray.Reset();        
+    //iDelayedCmd.Reset();
+    iDelayedCmd = 0;
+    }
+// ---------------------------------------------------------------------------
+// CPeninputServerSession::PanicClient
+// ---------------------------------------------------------------------------
+//
+void CPeninputServerSession::PanicClient(const RMessage2& aMessage,TInt aPanic)
+    {
+    aMessage.Panic(KPeninputServerName, aPanic);
+    }
+
+// ---------------------------------------------------------------------------
+// CPeninputServerSession::~CPeninputServerSession
+// ---------------------------------------------------------------------------
+//
+CPeninputServerSession::~CPeninputServerSession()
+    {
+    ProcessPendingEventBeforeExit();
+    iPenInputSvr.DecreaseSessionCount(this);
+    iPenInputSvr.DelProcessLayouts( iClientProcess );
+    iDataBuf.Close();
+    iSignalCodeArray.Close();
+    iCombinedEventBuf.Close();
+    //iDelayedCmd.Close();
+    delete iAppInfo;
+    }
+
+// ---------------------------------------------------------------------------
+// CPeninputServerSession::ClientId
+// ---------------------------------------------------------------------------
+//
+TInt CPeninputServerSession::ClientId()
+    {
+    return iClientId;
+    }
+    
+void CPeninputServerSession::RemoveEventDataByIdx(TInt aIndex)
+    {
+    //remove all if aIndex < 0
+    if( aIndex == KAllEventIndex )
+        {
+        for(TInt i = iDataBuf.Count() - 1; i >= 0; i--)
+            {        
+            HBufC* usedData = iDataBuf[i];
+            iDataBuf.Remove(i);
+            delete usedData;
+            iSignalCodeArray.Remove(i);
+            }
+        }
+    else
+        {
+        if( aIndex >= 0 && aIndex < iDataBuf.Count() ) 
+            {
+            HBufC* usedData = iDataBuf[aIndex];
+            iDataBuf.Remove(aIndex);
+            delete usedData;
+            iSignalCodeArray.Remove(aIndex);
+            }
+        }        
+    }
+
+//void CPeninputServerSession::AddDelayedCmd(TAnimationCommand aCmd)
+void CPeninputServerSession::AddDelayedCmd()
+    {
+    //iDelayedCmd.Append(aCmd);
+    //iDelayedCmd++;
+    }
+    
+void CPeninputServerSession::RegisterPenUiType(TInt aType)
+    {
+    iRegistedPenUiType = aType;
+    }
+    
+TInt CPeninputServerSession::HandleAppInfoChange(const RMessage2& aMessage)
+    {
+    TInt ret = 0;
+    TRAP_IGNORE(ret = HandleAppInfoChangeL(aMessage));	
+    return ret;
+    }
+
+TInt CPeninputServerSession::HandleAppInfoChangeL(const RMessage2& aMessage)
+    {
+    //TPeninputAppInfo type;
+    if (aMessage.Ptr0() == NULL || aMessage.Ptr1() == NULL)
+        {
+        return EBadRequest;
+        }
+
+    TPckg<TPeninputAppInfo> typeData(iAppInfoType);            
+    TInt rst = aMessage.Read(KMsgSlot0,typeData);
+    if (rst != KErrNone)
+        {
+        return EBadRequest;
+        }
+    
+    delete iAppInfo;
+    iAppInfo = NULL;
+    TInt len = aMessage.GetDesLength(KMsgSlot1);
+    if (len < 0)
+        {
+        return EBadRequest;
+        }
+    iAppInfo = HBufC::NewL(len);
+    TPtr appInfo = iAppInfo->Des();
+    rst = aMessage.Read(KMsgSlot1,appInfo);
+    if (rst != KErrNone)
+        {
+        return EBadRequest;
+        }    
+    return DoUpdateAppInfo();
+    }
+    
+TInt CPeninputServerSession::DoUpdateAppInfo()
+    {
+    return iPenInputSvr.HandleAppInfoChange(this,*iAppInfo,iAppInfoType);  
+    }
+    
+    
+TInt CPeninputServerSession::DisabledUiType()
+    {
+    return iDisabledUiType;
+    }
+    
+//end of implementation of Class CPeninputServerSession
+
+// End of File