diff -r 000000000000 -r eb1f2e154e89 textinput/peninputarc/src/peninputserverapp/peninputserversession.cpp --- /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 + +#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 msg(num); + + aMessage.WriteL(0,msg); + } + break; + + case EPeninputRequestGetDisableLayout: + { + //TInt layoyts = 0; + //CPeninputServerSession* pSession = static_cast(aMessage.Session()); + //GetProcessLayouts( pSession->ClientProcessId(), layoyts ); + TInt dsaDisableUIType = iPenInputSvr.DisabledByDSA(); + TInt orientationDisableType = iPenInputSvr.DisabledByOrientation(); + if( dsaDisableUIType ) + { + iDsaEverHappened = ETrue; + } + TPckg msg(iDisabledUiType | dsaDisableUIType | orientationDisableType); + + aMessage.WriteL(0,msg); + } + break; + case EPeninputRequestDisableLayout: + { + TInt layouts = aMessage.Int0(); + //CPeninputServerSession* pSession = static_cast(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 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