/*
* Copyright (c) 2005-2007 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
*
*/
// INCLUDE FILES
#include <e32svr.h>
#include <w32std.h>
#include <coedef.h>
#include <apgwgnam.h>
#include <coemain.h>
#include <AknFepInternalCRKeys.h>
#include <akniconconfig.h>
#include <AknSgcc.h>
#include <sensorplugindomaincrkeys.h> // KCRUidSensorSettings
#ifdef RD_TACTILE_FEEDBACK
#include <featmgr.h>
#endif //RD_TACTILE_FEEDBACK
#include "peninputclientserver.h"
#include "peninputserver.h"
#include "peninputserversession.h"
#include <PtiEngine.h>
#include <s32mem.h>
#include <gulgcmap.h>
#include "peninputanimclientobj.h"
#include "peninputuilayoutowner.h"
//#include "aknfeppeninputenums.h"
#include <UikonInternalPSKeys.h>
#include "penuiwndctrl.h"
#include "keyrotator.h"
#include <AknDef.h>
#include <aknfeppeninputenums.h>
#include <aknappui.h>
#include "peninputcrpclient.h"
#include <avkondomainpskeys.h>
//#define __WND_TEST_
// CONSTANTS
const TSize KInitialPeninputSize= TSize( 10, 10 );
const TInt KMsgQueueLen = 1000;
const TInt KMsgResponseQueueLen = 10;
const TInt KWsSessionFlushPerioid = 50000;//50ms
const TInt KInvalidValue = -1;
enum TActivationFlag
{
ECmdDeactivate = EFalse,
ECmdActivate = ETrue,
};
enum TUpdateFlag
{
EPartialUpdate = EFalse,
EFullUpdate = ETrue
};
#ifdef __LOG_WNDGROU__
#ifdef __WINS__
_LIT(KLogFile,"c:\\penwndgroup.txt");
#else
_LIT(KLogFile,"\\penwndgroup.txt");
#endif
#endif //__LOG_WNDGROU__
TUid GetAppUidByWndGroupIdL( RWsSession &aWs, TInt aWndGroupId )
{
CApaWindowGroupName* wg = CApaWindowGroupName::NewLC(aWs,aWndGroupId);
TUid id = wg->AppUid();
CleanupStack::PopAndDestroy(wg);
return id;
}
TUid GetFocusAppUid()
{
RWsSession &ws = CCoeEnv::Static()->WsSession();
TInt wgId =ws.GetFocusWindowGroup();
TUid id = TUid::Null();
TRAP_IGNORE( id = GetAppUidByWndGroupIdL( ws, wgId ) );
return id;
}
#ifdef __LOG_WNDGROU__
void Des2Des8(const TDesC& aSrc, TDes8& aDest)
{
aDest.Zero();
const TUint16* ptr = aSrc.Ptr();
for(TInt i = 0; i < aSrc.Length(); ++i)
{
aDest.Append(*((TUint8*)ptr));
ptr++;
}
}
#endif
#ifdef __LOG_WNDGROU__
void WriteDeactivateLogL( RFile& aFile )
{
TInt ret = aFile.Open(CCoeEnv::Static()->FsSession(),KLogFile,EFileShareAny|EFileWrite);
if(ret == KErrNone)
{
_LIT8 (KNotesID, "Notes id: %d \r\n");
TBuf8<30> buf;
buf.Zero();
TInt off = 0;
aFile.Seek(ESeekEnd,off);
RWsSession &ws = CCoeEnv::Static()->WsSession();
TInt wgId =ws.GetFocusWindowGroup();
CApaWindowGroupName* wgname = CApaWindowGroupName::NewLC(ws,wgId);
TInt focusuid = GetFocusAppUid().iUid;
buf.Format(KNotesID, focusuid);
HBufC8* name = HBufC8::NewLC(wgname->Caption().Length());
TPtr8 nameStr = name->Des();
Des2Des8(wgname->Caption(),nameStr);
aFile.Write(_L8(" ..."));
aFile.Write(nameStr);
aFile.Write(buf);
aFile.Write(_L8(" Close UI. \r\n"));
aFile.Close();
CleanupStack::PopAndDestroy(name);
CleanupStack::PopAndDestroy(wgname);
}
}
#endif
TBool IsGlobalNotesApp(TUid& aUid)
{
const TInt KAknCapServerUid = 0x10207218;
const TInt KAknNotifySrvUid = 0x10281EF2;
if(aUid.iUid == KAknCapServerUid || aUid.iUid == KAknNotifySrvUid)
return ETrue;
return EFalse;
}
// ======== MEMBER FUNCTIONS ========
// ---------------------------------------------------------------------------
// CPeninputServer::CPeninputServer
// ---------------------------------------------------------------------------
//
CPeninputServer::CPeninputServer ( TInt aPriority) : CServer2 ( aPriority,ESharableSessions ),
iActive(EFalse),iDispMode(ENone),
iDispModeForMask(ENone),
iFullUpdate(EFalse),
iPrevActive(EFalse),iUILayoutReady(EFalse),
iSupportFeedback(EFalse)
{
AknIconConfig::TPreferredDisplayMode displayMode;
AknIconConfig::PreferredDisplayMode(displayMode, AknIconConfig::EImageTypeIcon);
iDispMode = displayMode.iBitmapMode;
iDispModeForMask = displayMode.iMaskMode;
iSpriteMember.iBitmap = NULL;
iSpriteMember.iMaskBitmap = NULL;
iLayoutId.iUid = 0;
iPrevLayoutId = iLayoutId;
iSpriteSize = KInitialPeninputSize;
iSpritePosition = TPoint(0,0);
//iDispMode = iDispModeForMask= CCoeEnv::Static()->WsSession().GetDefModeMaxNumColors(col,grey);
iPreNonGloebalNotesWndGrpId = -1;
iNoNeedClean = EFalse;
iEnablePriorityChangeOnOriChange = ETrue;
}
// ---------------------------------------------------------------------------
// CPeninputServer::NewL
// ---------------------------------------------------------------------------
//
CPeninputServer* CPeninputServer::NewL()
{
CPeninputServer* pS = new (ELeave) CPeninputServer(
CActive::EPriorityStandard);
CleanupStack::PushL( pS );
pS->ConstructL( );
CleanupStack::Pop(pS);
return pS;
}
// ---------------------------------------------------------------------------
// CPeninputServer::ConstructL
// ---------------------------------------------------------------------------
//
void CPeninputServer::ConstructL( )
{
#ifdef RD_TACTILE_FEEDBACK
FeatureManager::InitializeLibL();
iSupportFeedback = FeatureManager::FeatureSupported( KFeatureIdTactileFeedback );
#endif //RD_TACTILE_FEEDBACK
// start server, leaves if server already running
StartL( KPeninputServerName );
User::LeaveIfError( iKeyEventSemaphore.CreateGlobal(
KAnimKeyEventSemaphore,0) );
iEventBufferQueue = CEventQueue::NewL(this,KMsgEventBufferQueue);
iKeyMsgResponseQueue.CreateGlobal(KMsgEventResponseQueue,KMsgResponseQueueLen);
iFlushTimer = CPeriodic::NewL(CActive::EPriorityHigh);
iHardwareLayoutChangeWatcher = CAknLayoutChangeWatcher::NewL(this,
KUikLayoutState);
iSoftwareLayoutChangeWatcher = CAknLayoutChangeWatcher::NewL(this,
KUikPreferredOrientation);
iHardwareLayoutChangeWatcher->StartWatching();
iSoftwareLayoutChangeWatcher->StartWatching();
RWindowGroup& rootWin = CCoeEnv::Static()->RootWin();
rootWin.EnableFocusChangeEvents (); // For cover UI/status pane refresh problems
rootWin.EnableGroupListChangeEvents();
rootWin.EnableReceiptOfFocus(EFalse);
rootWin.AutoForeground(EFalse);
ConstructSpriteL();
//create animation object
iAnimObj = CPeninputAnimObj::NewL(iSpriteMember);
iLayoutOwner = CPeninputUiLayoutOwner::NewL( *this );
iPenUiCtrl = new(ELeave) CPenUiWndCtrl(CCoeEnv::Static()->RootWin(),iSpriteMember.iBitmap);
iInternalBackgroundCtrl = new(ELeave) CInternalBkCtrl(CCoeEnv::Static()->RootWin());
iInternalBackgroundCtrl->ConstructL();
iPenUiCtrl->ConstructL();
iCurScreenFocusedWndGrpId = GetFocusAppUid().iUid;
#ifdef __LOG_WNDGROU__
iLogFile.Replace(CCoeEnv::Static()->FsSession(),KLogFile,EFileShareAny|EFileWrite);
iLogFile.Close();
#endif
iCurScrMode = CCoeEnv::Static()->ScreenDevice()->CurrentScreenMode();
iCrpService = CPenInputCrpServiceClient::NewL();
iSensorRepository = CRepository::NewL(KCRUidSensorSettings);
User::LeaveIfError(iDiscreetPopProperty.Attach(KPSUidAvkonDomain,
KAknGlobalDiscreetPopupNumChanged));
iDiscreetPopSubscriber = new (ELeave) CSubscriber(
TCallBack( DiscreetPopChangeNotification, this),
iDiscreetPopProperty);
iDiscreetPopSubscriber->SubscribeL();
// Get the pop area
User::LeaveIfError(iAknUiSrv.Connect());
iDiscreetPopArea = iAknUiSrv.GetInUseGlobalDiscreetPopupRect();
if(iDiscreetPopArea.Size().iWidth > 0)
{
HandleDiscreetPopNotification();
}
}
void CPeninputServer::CleanAll()
{
if(iNoNeedClean)
return;
delete iHardwareLayoutChangeWatcher;
delete iSoftwareLayoutChangeWatcher;
if(iAppGc)
CCoeEnv::Static()->SwapSystemGc(iAppGc);
delete iPtiEngine;
iKeyEventSemaphore.Close();
iUiHandlerArray.Close();
// iSprite will be closed by iWsSession.Close()
// but the sprite member bitmaps must be deleted
// explicitly
/*
// iPrevUiLayout is not used any more
if(iPrevUiLayout && iPrevUiLayout!=iUiLayout)
{
iPrevUiLayout->Destroy();
iPrevUiLayout = iUiLayout;
}
*/
if(iUiLayout)
{
iUILayoutReady = EFalse;
iDestroyingLayout = ETrue;
iUiLayout->Destroy();
iUiLayout = NULL;
}
delete iBitmapDevice;
delete iMaskBitmapDevice;
delete iSpriteGc;
delete iSpriteMember.iBitmap;
delete iSpriteMember.iMaskBitmap;
delete iWindowGc;
delete iLayoutEng;
delete iLayoutOwner;
delete iEventBufferQueue;
iKeyMsgResponseQueue.Close();
if(iFlushTimer)
{
iFlushTimer->Cancel();
delete iFlushTimer;
}
#ifdef RD_TACTILE_FEEDBACK
FeatureManager::UnInitializeLib();
iFeedbackAreaArray.Close();
#endif // RD_TACTILE_FEEDBACK
delete iPenUiCtrl;
delete iInternalBackgroundCtrl;
iClientProcess.Close();
iClientLayouts.Close();
#ifdef __LOG_WNDGROU__
iLogFile.Close();
#endif
if (iDiscreetPopSubscriber)
{
iDiscreetPopSubscriber->StopSubscribe();
}
iDiscreetPopProperty.Close();
delete iDiscreetPopSubscriber;
iAknUiSrv.Close();
delete iAnimObj;
iAnimObj = NULL;
iNoNeedClean = ETrue;
delete iCrpService;
iCrpService = NULL;
}
// ---------------------------------------------------------------------------
// CPeninputServer::~CPeninputServer
// Destructor
// ---------------------------------------------------------------------------
//
CPeninputServer::~CPeninputServer()
{
CleanAll();
#ifdef __WINS__
iCloseServer = ETrue;
#endif
delete iSensorRepository;
}
// ---------------------------------------------------------------------------
// CPeninputServer::IncreaseSessionCount
// ---------------------------------------------------------------------------
//
void CPeninputServer::IncreaseSessionCount()
{
++iSessionCount;
}
// ---------------------------------------------------------------------------
// CPeninputServer::DecreaseSessionCount
// ---------------------------------------------------------------------------
//
void CPeninputServer::DecreaseSessionCount(CPeninputServerSession* aSession)
{
if( aSession == iForegroundSession)
{
iForegroundSession = NULL;
Hide();
}
else
{
if( aSession == iForegroundUiHandler )
{
iForegroundUiHandler = NULL;
}
}
//remove the session from list
for(TInt i = 0; i < iUiHandlerArray.Count(); i++)
{
if( aSession == iUiHandlerArray[i] )
iUiHandlerArray.Remove(i);
}
--iSessionCount;
#ifdef __WINS__
if ( iSessionCount == 0 && !iCloseServer)
{
DeactivateSprite();
PrepareExit();
CActiveScheduler::Stop();
}
#endif
}
// ---------------------------------------------------------------------------
// CPeninputServer::ActivateSpriteInGlobalNotesL()
// Activate sprite
// ---------------------------------------------------------------------------
//
void CPeninputServer::ActivateSpriteInGlobalNotesL()
{
TBool notDraw = EFalse;
if(iUiLayout)
{
iUiLayout->HandleCommand( ECmdPeninputDisableLayoutDrawing,
(unsigned char*)¬Draw );
}
// [[[ temporary solution for Virtual keyboard becomes corrupted after several rotations
if(!iUiLayout)
{
return;
}
// we should not be able to activate and show pen ui if this mode is disabled currently
if(iUiLayout->PenInputType() & DisabledByOrientation())
{
// we have activate the animation otherwise we will see the penui but not reponse
// when clicking on it in the case we rotating the screen quickly and continously
if(iAnimObj)
{
iAnimObj->AddActivationCmd(ECmdActivate,EFalse);
}
return;
}
// ]]] temporary solution for Virtual keyboard becomes corrupted after several rotations
if(iActive)
{
if(iUseWindowCtrl)
{
/* RWsSession &ws = CCoeEnv::Static()->WsSession();
TInt wgId =ws.GetFocusWindowGroup();
//TInt wgHandle = ws.GetWindowGroupHandle(wgId);
TInt priority;
//TInt pos;
//wg.Construct(wgHandle);
//pos = wg.FullOrdinalPosition();
priority = ws.GetWindowGroupOrdinalPriority(wgId);*/
//wg.Close();
//iPenUiCtrl->ShowPenUi();
ActivatePenUiLayout(EFalse);
iDimmed = EFalse;
iPenUiCtrl->ShowPenUiL(iDimmed);
}
return;
}
TBool bNeedWait = AnimOpNeedWaiting(ESignalPenUiActivated);
//add animation command
/*
if(iAnimObj->AddActivationCmd(ECmdActivate,bNeedWait))
{
if(bNeedWait)
iForegroundUiHandler->AddDelayedCmd();
//iUiLayout->OnActivate();
ActivatePenUiLayout();
DrawSprite();
iEventBufferQueue->GetEvent();
iActive = ETrue;
if(iUseWindowCtrl)
iPenUiCtrl->ShowPenUi();
}
*/
if(ActivatePenUiLayout(bNeedWait))
{
if(bNeedWait)
iForegroundUiHandler->AddDelayedCmd();
DrawSprite();
iActive = ETrue;
if(iUseWindowCtrl)
{
/*RWsSession &ws = CCoeEnv::Static()->WsSession();
TInt wgId =ws.GetFocusWindowGroup();
//TInt wgHandle = ws.GetWindowGroupHandle(wgId);
TInt priority;
//TInt pos;
//wg.Construct(wgHandle);
//pos = wg.FullOrdinalPosition();
priority = ws.GetWindowGroupOrdinalPriority(wgId);*/
//wg.Close();
iPenUiCtrl->ShowPenUiL(iDimmed);
}
}
}
// ---------------------------------------------------------------------------
// CPeninputServer::ActivateSprite
// Activate sprite
// ---------------------------------------------------------------------------
//
void CPeninputServer::ActivateSprite(TInt aRequiredScrMode)
{
if(!iUiLayout)
return;
if(iCurScrMode != aRequiredScrMode)
{
iUiLayout->OnResourceChange(KEikDynamicLayoutVariantSwitch);
iCurScrMode = aRequiredScrMode;
}
ActivateSprite();
}
// ---------------------------------------------------------------------------
// CPeninputServer::ActivateSprite
// Activate sprite
// ---------------------------------------------------------------------------
//
void CPeninputServer::ActivateSprite()
{
//do nothing if we don't have ui layout or already activated.
TUid focusApp = GetFocusAppUid();
if(!IsGlobalNotesApp(focusApp))
iPreNonGloebalNotesWndGrpId = focusApp.iUid;
if(!iUiLayout)
return;
// [[[ temporary solution for Virtual keyboard becomes corrupted after several rotations
// we should not be able to activate and show pen ui if this mode is disabled currently
if(iUiLayout->PenInputType() & DisabledByOrientation())
{
// we have activate the animation otherwise we will see the penui but not reponse
// when clicking on it in the case we rotating the screen quickly and continously
if(iAnimObj)
{
iAnimObj->AddActivationCmd(ECmdActivate,EFalse);
}
return;
}
// ]]] temporary solution for Virtual keyboard becomes corrupted after several rotations
TBool notDraw = EFalse;
iUiLayout->HandleCommand(ECmdPeninputDisableLayoutDrawing,(unsigned char*)¬Draw);
// move it out from if(!iActive) to make sure that msg bubble can be
// shown if fast swap from other application to msg application.
TBool bNeedWait = AnimOpNeedWaiting(ESignalPenUiActivated);
if(!iActive)
{
/*
TInt scrMode = CCoeEnv::Static()->ScreenDevice()->CurrentScreenMode();
TBool bScrRotated = scrMode != iCurScrMode;
if(bScrRotated)
{
iCurScrMode = scrMode;
iUiLayout->OnResourceChange(KEikDynamicLayoutVariantSwitch);
}
*/
//TBool bNeedWait = AnimOpNeedWaiting(ESignalPenUiActivated);
//add animation command
/*
if(iAnimObj->AddActivationCmd(ECmdActivate,bNeedWait))
{
if(bNeedWait)
iForegroundUiHandler->AddDelayedCmd();
//iUiLayout->OnActivate();
ActivatePenUiLayout();
DrawSprite();
iEventBufferQueue->GetEvent();
iActive = ETrue;
if(iUseWindowCtrl)
iPenUiCtrl->ShowPenUi();
}
*/
if(ActivatePenUiLayout(bNeedWait, ETrue))
{
if(bNeedWait)
iForegroundUiHandler->AddDelayedCmd();
DrawSprite();
iActive = ETrue;
if(iUseWindowCtrl)
{
TRAP_IGNORE( iPenUiCtrl->ShowPenUiL(iDimmed) );
if (iPreNonGloebalNotesWndGrpId != focusApp.iUid &&
IsGlobalNotesApp(focusApp) && !iInGlobalEditorState )
{
iDimmed = ETrue;
DimPenUi();
}
}
}
iIsLayoutReDrawAllowWhenActive = EFalse;
}
else
{
//actived but dimmed by global notes
if(iUseWindowCtrl)
{
/**
* 1. IF THE GLOBAL NOTES HAS BEEN OPENED UP, WE NEED TO REDRAW THE LAYOUT
* 2. IF iIsLayoutReDrawAllowWhenActive was set to be ETrue.
* if we did not put this condition guard, the layout
* redraw will be executed even if the layout is active. But if this flag is
* set to be ture, layout redraw will be carried out even if the layout is active, so
* it will leave this for layout to decide if it need set this flag to be ture or false
* in some special cases: for example for entering and exiting the spell mode.
*
*/
if(iInGlobalNotesApp || iInGlobalEditorState || iIsLayoutReDrawAllowWhenActive )
{
ActivatePenUiLayout(EFalse);
if(iIsLayoutReDrawAllowWhenActive)
{
iIsLayoutReDrawAllowWhenActive = EFalse;
}
}
else
{
ActivatePenUiLayout(EFalse,ETrue);
}
if (iDimmed && (iInGlobalNotesApp || iInGlobalEditorState))
{
DeactivatePenUiLayout(EFalse);
return;
}
TRAP_IGNORE( iPenUiCtrl->ShowPenUiL(iDimmed) );
iDimmed = EFalse;
}
}
}
// ---------------------------------------------------------------------------
// CPeninputServer::ActivatePenUiLayout
// ---------------------------------------------------------------------------
//
TBool CPeninputServer::ActivatePenUiLayout(TBool aWaitFlag, TBool aSkipDraw)
{
RecoverSimulatedKeyEventState();
RecoverButtonEventState();
if (iAnimObj && iAnimObj->AddActivationCmd(ECmdActivate,aWaitFlag))
{
if (iUiLayout)
{
iUiLayout->OnActivate();
if( !aSkipDraw )
iUiLayout->Draw();
}
iEventBufferQueue->GetEvent();
if (iUseWindowCtrl)
{
CPenUiWndCtrl::EditorType type;
if (iInGlobalEditorState)
{
type = CPenUiWndCtrl::EGlobleNotesWithEditor;
}
else
{
TUid focusApp = GetFocusAppUid();
if(IsGlobalNotesApp(focusApp))
{
type = CPenUiWndCtrl::EGlobleNotes;
}
else
{
type = CPenUiWndCtrl::ENoremalEditor;
}
}
iPenUiCtrl->OnActivate(type);
//iPenUiCtrl->ShowPenUi();
}
return ETrue;
}
return EFalse;
}
void CPeninputServer::DimPenUiWnd(TBool aFlag)
{
RecoverSimulatedKeyEventState();
if(aFlag)
{
iEventBufferQueue->Cancel();
if( iUiLayout )
{
iUiLayout->OnDeActivate();
}
if(iUseWindowCtrl)
iPenUiCtrl->OnDeactivate(); //disable non fading
}
else
{
iEventBufferQueue->GetEvent();
if( iUiLayout )
{
iUiLayout->OnActivate();
}
if(iUseWindowCtrl)
iPenUiCtrl->OnActivate(CPenUiWndCtrl::ENoremalEditor); //disable non fading
}
}
// ---------------------------------------------------------------------------
// CPeninputServer::DeactivatePenUiLayout
// ---------------------------------------------------------------------------
//
TBool CPeninputServer::DeactivatePenUiLayout(TBool aWaitFlag)
{
//iEventBufferQueue->Cancel();
if (iAnimObj && iAnimObj->AddActivationCmd(ECmdDeactivate,aWaitFlag))
{
if (iUiLayout)
{
RecoverSimulatedKeyEventState();
RecoverButtonEventState();
iUiLayout->OnDeActivate();
if(iUseWindowCtrl)
iPenUiCtrl->OnDeactivate(); //disable non fading
}
return ETrue;
}
return EFalse;
}
// ---------------------------------------------------------------------------
// CPeninputServer::DeactivatePenUiLayout
// ---------------------------------------------------------------------------
//
TBool CPeninputServer::DeactivateDimPenUiLayout(TBool aWaitFlag)
{
//iEventBufferQueue->Cancel();
if (iAnimObj && iAnimObj->AddActivationCmd(ECmdDeactivate,aWaitFlag))
{
if (iUiLayout)
{
RecoverSimulatedKeyEventState();
iUiLayout->OnDeActivate();
}
return ETrue;
}
return EFalse;
}
// CPeninputServer::DeactivateSprite
// ---------------------------------------------------------------------------
//
void CPeninputServer::DeactivateSprite(TBool aImmediateHideFlag, TBool aRotation)
{
if (!iActive || !iUiLayout)
return;
#ifdef __LOG_WNDGROU__
// TRAP_IGNORE( WriteDeactivateLogL(iLogFile) ) ;
#endif
aRotation = aRotation || iResourceChange;
iActive = EFalse;
if (!aRotation)
{
iDimmed = EFalse;
iInGlobalNotesState = EFalse;
}
iFlushTimer->Cancel();
TBool bNeedWait = !aImmediateHideFlag &&
AnimOpNeedWaiting(ESignalPenUiDeActivated);
if (DeactivatePenUiLayout(bNeedWait) && bNeedWait)
iForegroundUiHandler->AddDelayedCmd();
if (iUseWindowCtrl)
iPenUiCtrl->ClosePenUi(aRotation);
//save current screen mode
iCurScrMode = CCoeEnv::Static()->ScreenDevice()->CurrentScreenMode();
}
// ---------------------------------------------------------------------------
// CPeninputServer::HandleMessageL
// Handle client message
// ---------------------------------------------------------------------------
//
TInt CPeninputServer::HandleMessageL(const RMessage2& aMessage)
{
//It's traped in server session
TInt err = KErrNone;
if(!iPtiEngine || !iLayoutEng)
DoIdleConstructL();
TBool isForeground = IsForegroundSession(
static_cast<CPeninputServerSession*>(aMessage.Session()));
//message requests UI attribute is always handled.
switch(aMessage.Function())
{
case EPeninputRequestUiIsVisible:
{
TPckg<TBool> msg(iActive);
aMessage.WriteL(0,msg);
}
break;
case EPeninputRequestUiGetUiPos:
{
TPckgC<TPoint> msg(iSpritePosition);
TPckgC<TSize> msgSize(iSpriteSize);
aMessage.WriteL(0,msg);
aMessage.WriteL(1,msgSize);
}
break;
case EPenInputRequestGetPenSupportLanguages:
GetPenSupportLanguagesL(aMessage);
break;
case EPenInputRequestGetImePluginIdList:
GetImePluginIdListL(aMessage);
break;
case EPeninputRequestRelinquishForeground:
{
if(isForeground)
iForegroundSession = NULL;
}
break;
case EPeninputRequestSetForeground:
{
TInt msgGroupId;
TPckg<TInt> msgIdData(msgGroupId);
aMessage.ReadL(KMsgSlot0,msgIdData);
//TInt curFocusId = GetFocusAppUid().iUid;
TBool mustOpenFlag;
TPckg<TBool> msgFlagData(mustOpenFlag);
aMessage.ReadL(KMsgSlot1,msgFlagData);
//ignore the command if it's from another focused group.
/*******************************************************************/
//This is a fix to web browse case. When swithing to web, device changeded
// to landscape mode automatically, but previous app with pen UI, e.g.
// Notepad, will gain the foregound, thus open the UI.
/*******************************************************************/
if(!mustOpenFlag && msgGroupId != iCurScreenFocusedWndGrpId) //screen has changed, but foreground is wrong.
{
//only check this if it's not openned by pen click
err = KErrNotWrongFocusedWindowGroup;
//iForegroundSession = NULL;
}
else
{
CPeninputServerSession* session =
static_cast<CPeninputServerSession*>(aMessage.Session());
/*if(!IsSameProcess(iForegroundSession, session))
{
//
}*/
iForegroundSession = session;
//check whether there is ui notification handler from the same process
if(iUiHandlerArray.Count())
SetForeGroundUiHandlerL();
}
TPckgC<TBool> msg(iForegroundSession != NULL);
aMessage.WriteL(KMsgSlot2,msg);
}
break;
case EPeninputRequestIsForeground:
{
TPckgC<TBool> msg(isForeground);
aMessage.WriteL(0,msg);
}
break;
case EPeninputRequestIsLayoutDimmed:
{
TPckgC<TBool> msg(iDimmed);
aMessage.WriteL(0,msg);
}
break;
//other message is only handled when the request session is foreground session.
case EPeninputRequestUiSetUiPos:
if(isForeground)
{
TPoint pt;
TPckg<TPoint> msg(pt);
aMessage.ReadL(KMsgSlot0,msg);
SetPosition(pt);
}
else
{
err = KErrNotForegroundSession;
}
break;
case EPeninputServerRequestSetDisplayMode:
if(isForeground)
{
TDisplayMode mode;
TDisplayMode maskMode;
TPckg<TDisplayMode> data1(mode);
TPckg<TDisplayMode> data2(maskMode);
aMessage.ReadL(KMsgSlot0,data1);
aMessage.ReadL(KMsgSlot1,data2);
ChangeDisplayModeL(mode,maskMode);
}
else
{
err = KErrNotForegroundSession;
}
break;
case EPeninputRequestActivateLayout:
if(isForeground)
{
iInGlobalEditorState = EFalse;
TBool bFlag ;
TPckg<TBool> msg(bFlag );
aMessage.ReadL(KMsgSlot0,msg);
if(bFlag)
{
TInt requiredMode;
TPckg<TInt> scrMsg(requiredMode);
aMessage.ReadL(KMsgSlot1,scrMsg);
ActivateSprite(requiredMode);
static_cast<CPeninputServerSession*>(
aMessage.Session())->DoUpdateAppInfo();
}
else
{
DeactivateSprite();
}
}
else
{
err = KErrNotForegroundSession;
}
break;
case EPeninputRequestActivateLayoutInGlobalNotes:
//if(isForeground)
{
iCurGlobalNotesId = GetFocusAppUid().iUid;
iInGlobalEditorState = ETrue;
ActivateSpriteInGlobalNotesL();
}
/*else
{
err = KErrNotForegroundSession;
}*/
break;
case EPeninputRequestInternalDimLayout:
{
if(iUseWindowCtrl && iActive)
{
TBool dim;
TPckg<TBool> msg(dim);
aMessage.ReadL(KMsgSlot0,msg);
TInt priority;
TPckg<TInt> priorityMsg(priority);
aMessage.ReadL(KMsgSlot1,priorityMsg);
TInt bmpHandle = iSpriteMember.iBitmap->Handle();
TPckg<TInt> handleMsg(bmpHandle);
aMessage.WriteL(KMsgSlot2,handleMsg);
TRect pos = iPenUiCtrl->Rect();
pos.Move(iPenUiCtrl->Position());
TPckg<TRect> extMsg(pos);
aMessage.WriteL(KMsgSlot3,extMsg);
iDimmed = dim;
DimPenInternalUi(iDimmed,priority);
}
}
break;
case EPeninputRequestDimLayout:
if(iUseWindowCtrl && iActive)
{
TBool dim;
TPckg<TBool> msg(dim);
aMessage.ReadL(KMsgSlot0,msg);
TInt priority;
TPckg<TInt> priorityMsg(priority);
aMessage.ReadL(KMsgSlot1,priorityMsg);
TInt bmpHandle = iSpriteMember.iBitmap->Handle();
TPckg<TInt> handleMsg(bmpHandle);
aMessage.WriteL(KMsgSlot2,handleMsg);
TRect pos = iPenUiCtrl->Rect();
pos.Move(iPenUiCtrl->Position());
TPckg<TRect> extMsg(pos);
aMessage.WriteL(KMsgSlot3,extMsg);
if(dim != iDimmed)
{
iDimmed = dim;
DimPenUi();
/*if(iDimmed)
//DeactivatePenUiLayout(EFalse);
DeactivateSprite();
else
ActivatePenUiLayout(EFalse);
*/
}
}
break;
case EPeninputRequestSetUiLayoutId:
case EPeninputRequestSetUiLayoutIdWithData:
if(isForeground || iDimmed)
{
err = CreateLayoutL(aMessage);
}
else
{
err = KErrNotForegroundSession;
}
break;
case EPeninputRequestResourceChanged:
if(isForeground)
{
if(!iUiLayout)
return KErrNoLayout;
if(iPrevActive)
{
ActivateSprite();
iPrevActive = EFalse;
}
}
else
{
err = KErrNotForegroundSession;
}
break;
case EPeninputRequestAddUiObserver:
{
TInt type ;
TPckg<TInt> msg(type);
aMessage.ReadL(KMsgSlot0,msg);
static_cast<CPeninputServerSession*>(aMessage.Session())->
RegisterPenUiType(type);
iUiHandlerArray.Append(static_cast<CPeninputServerSession*>(aMessage.Session()));
if(iForegroundSession)
SetForeGroundUiHandlerL();
}
break;
case EPeninputRequestRemoveUiObserver:
{
CPeninputServerSession* s =static_cast<CPeninputServerSession*>
(aMessage.Session());
if( s == iForegroundUiHandler)
{
s->ProcessPendingEventBeforeExit();
iForegroundUiHandler = NULL;
}
for(TInt i = 0; i < iUiHandlerArray.Count();i++)
{
if(s == iUiHandlerArray[i])
{
iUiHandlerArray.Remove(i);
break;
}
}
}
break;
/*case EPeninputRequestGetDisableLayout:
{
TInt layoyts = 0;
CPeninputServerSession* pSession = static_cast<CPeninputServerSession*>(aMessage.Session());
GetProcessLayouts( pSession->ClientProcessId(), layoyts );
TPckg<TInt> msg(layoyts);
aMessage.WriteL(0,msg);
}
break;
case EPeninputRequestDisableLayout:
{
TInt layouts = aMessage.Int0();
CPeninputServerSession* pSession = static_cast<CPeninputServerSession*>(aMessage.Session());
SetProcessLayouts( pSession->ClientProcessId(), layouts );
}
break;*/
case EPeninputRequestServerThreadId:
{
RThread thread;
TThreadId id = thread.Id();
TPckg<TThreadId> msg(id);
aMessage.WriteL(0,msg);
thread.Close();
}
break;
case EPeninputBackgroudDefaultOri:
{
TInt flag = 0;
TPckg<TInt> msg(flag);
aMessage.ReadL(0,msg);
BackgroudDefaultOri( flag );
}
break;
case EPeninputRequestDimResChangeLayout:
{
TInt flag = 0;
TPckg<TInt> msg(flag);
aMessage.ReadL(0,msg);
iResourceChange = flag;
if(iUseWindowCtrl)
iPenUiCtrl->SetResourceChange(iResourceChange);
}
break;
case EPeninputRequestSupportInputMode:
{
TInt language = 0;
TPckg<TInt> msgLanguage( language );
aMessage.ReadL( 1, msgLanguage );
TInt supportMode = GetSupportModeByLanguageL( language );
TPckg<TInt> msg(supportMode);
aMessage.WriteL(0,msg);
}
break;
case EPeninputRequestSetInputLanguage:
{
TPckg<TInt> msg(iInputLanguage);
aMessage.ReadL(0,msg);
if(iUiLayout)
{
iUiLayout->HandleCommand(ECmdPenInputLanguage,
(unsigned char*)&iInputLanguage);
}
}
break;
case EPeninputEnablePriorityChangeOnOriChange:
{
TPckg<TBool> enablePriority( iEnablePriorityChangeOnOriChange );
aMessage.ReadL( 0, enablePriority );
}
default: //Let user pluging handling the user command
break;
}
return err;
}
// ---------------------------------------------------------------------------
// CPeninputServer::HandleCommandL
// Handle client command
// ---------------------------------------------------------------------------
//
TInt CPeninputServer::HandleCommandL(const RMessage2& aMessage)
{
//let UI layout handles the command
TInt err = KErrNone;
//command is only handled when the request session is foreground session.
/*CPeninputServerSession* s =
static_cast<CPeninputServerSession*>(aMessage.Session());
if( iForegroundSession == static_cast<CPeninputServerSession*>(
aMessage.Session()) )*/
if(IsForegroundSession(static_cast<CPeninputServerSession*>(aMessage.Session())))
{
//get cmd id
TInt cmdId;
TPckg<TInt> cmdMsg(cmdId);
aMessage.ReadL(KMsgSlot0,cmdMsg);
TInt len = aMessage.GetDesLength(KMsgSlot1);
HBufC8* dataBuf = HBufC8::NewLC(len);
TPtr8 msgData = dataBuf->Des();
aMessage.ReadL(KMsgSlot1,msgData);
if(iUiLayout)
{
err = iUiLayout->HandleCommand(cmdId,(unsigned char*)msgData.Ptr());
TPckg<TInt> msg(err);
aMessage.WriteL(KMsgSlot2,msg);
}
CleanupStack::PopAndDestroy(dataBuf);
}
else
{
err = KErrNotForegroundSession;
}
return err;
}
TInt CPeninputServer::CreateLayoutL(const RMessage2& aMessage )
{
//check initialization status
//if(!iAppGc)
// iAppGc = CCoeEnv::Static()->SwapSystemGc(iWindowGc);
TInt id;
TPckg<TInt> msg(id);
aMessage.Read(KMsgSlot0,msg);
TUid uid;
uid.iUid = id;
if(iLayoutId == uid && iUiLayout)
return KErrNone;
iLayoutId = uid;
//clear sprite before delete ui layout
iUILayoutReady = EFalse;
if(iUiLayout)
{
//if(!iUseWindowCtrl)
//{
//ClearSpriteGc();
//}
DeactivateSprite();
iDestroyingLayout = ETrue;
if(iUseWindowCtrl)
{
if(iPenUiCtrl)
{
iPenUiCtrl->Clean();
}
}
iUiLayout->Destroy();
iUiLayout = NULL;
iDestroyingLayout = EFalse;
if(iAnimObj)
{
iAnimObj->AddFlushSessionCmd();
}
#ifdef RD_TACTILE_FEEDBACK
//remove all registered feedback area
const TInt KRemoveAllId = -1;
TTactileFeedbackArea area = {KRemoveAllId,TRect(0,0,0,0)};
RemoveFeedbackArea(area);
#endif
}
if(aMessage.Function() == EPeninputRequestSetUiLayoutId)
{
TPeninputLayoutData layoutData =
{
iPtiEngine,
//iPenUiCtrl
iInternalBackgroundCtrl,
};
//iUiLayout = iLayoutEng->GetUiLayout(iLayoutId,iLayoutOwner,iPtiEngine);
iUiLayout = iLayoutEng->GetUiLayout(iLayoutId,iLayoutOwner,&layoutData);
}
else
{
TInt len = aMessage.GetDesLength(KMsgSlot1);
HBufC8* dataBuf = HBufC8::NewLC(len);
TPtr8 msgData = dataBuf->Des();
aMessage.ReadL(KMsgSlot1,msgData);
iUiLayout=iLayoutEng->GetUiLayout(iLayoutId,iLayoutOwner,msgData.Ptr());
CleanupStack::PopAndDestroy(dataBuf);
}
if(!iUiLayout)
return KErrNoLayout;
iSpriteMember.iInvertMask = EFalse;
TRect layoutRect;
//do we need transparency?
TBool bTransparency = iUiLayout->SemiTransparencyRequired();
if(bTransparency)
{
#ifdef __ALPHA_TRANCEPARENCY__
ChangeDisplayModeL(iDispMode,EGray256);
#else
ChangeDisplayModeL(iDispMode,EColor16MU);
#endif
}
else
{
ChangeDisplayModeL(iDispMode,EGray2); //use black-white mask
}
layoutRect = iUiLayout->Init();
if( layoutRect.IsEmpty() )
{//this is a temp solution for VKB, the layout size can not
//be determined at construct time
TPixelsTwipsAndRotation ptSize;
CCoeEnv::Static()->ScreenDevice()->GetDefaultScreenSizeAndRotation( ptSize );
layoutRect = TRect( TPoint(), ptSize.iPixelSize );
}
iUILayoutReady = ETrue;
// register feedback area
/*if(iSupportFeedback && iFeedbackAreaArray.Count())
{
iAnimObj->AddRegisterFeedbackAreaCmd(iFeedbackAreaArray);
iFeedbackAreaArray.Reset(); }*/
//flush the command
if(iAnimObj)
{
iAnimObj->AddFlushSessionCmd();
}
TSize layoutSize = layoutRect.Size();
iSpriteSize = layoutSize;
/* iBitmapDevice->Resize( layoutSize);
iMaskBitmapDevice->Resize( layoutSize);
//gc must be adjusted
iSpriteGc->Activate(iBitmapDevice);
iSpriteGc->Resized();
*/
ResizeDrawingDevice(layoutSize);
if(iAnimObj)
{
iAnimObj->AddChangeSizeCmd(layoutSize);
}
SetPosition(layoutRect.iTl);
if(iUiLayout->PenInputType() == EPluginInputModeItut ||
iUiLayout->PenInputType() == EPluginInputModeFSQ ||
iUiLayout->PenInputType() == EPluginInputModeFingerHwr )
{
iOpaqueUi = ETrue;
iUseWindowCtrl = ETrue;
if(iUseWindowCtrl)
{
#ifdef FIX_FOR_NGA
TBool flag = ETrue;
iUiLayout->HandleCommand(ECmdPeninputEnableOwnBitmap,reinterpret_cast<TUint8*>(&flag));
#endif
iPenUiCtrl->SetExtent(layoutRect.iTl,layoutSize);
if(iAnimObj)
{
iAnimObj->AddEnalbeSpriteCmd(EFalse);
}
//must swap back when using window background
if(iAppGc)
{
CCoeEnv::Static()->SwapSystemGc(iAppGc);
}
}
else
{
if(iAnimObj)
{
iAnimObj->AddEnalbeSpriteCmd(ETrue);
}
iAppGc = CCoeEnv::Static()->SwapSystemGc(iWindowGc);
}
}
else
{
iOpaqueUi = EFalse;
if(iUseWindowCtrl && iAnimObj) //previous window control used
{
iUseWindowCtrl = EFalse;
iAnimObj->AddEnalbeSpriteCmd(ETrue);
}
}
TInt type = iUiLayout->PenInputType();
TPckg<TBool> typeMsg(type);
aMessage.WriteL(KMsgSlot2,typeMsg);
return KErrNone;
}
// ---------------------------------------------------------------------------
// CPeninputServer::SignalObserverL
// Signal oberver
// ---------------------------------------------------------------------------
//
void CPeninputServer::SignalObserverL(TInt aEventId,const TDesC& aEventData)
{
if(iForegroundSession)
iForegroundSession->SignalClientL(aEventId,aEventData);
}
// ---------------------------------------------------------------------------
// CPeninputServer::NewSessionL
// ---------------------------------------------------------------------------
//
CSession2* CPeninputServer::NewSessionL(const TVersion& aVersion,
const RMessage2& aMessage) const
{
// check we're the right version
TVersion v( KPeninputServerMajorVersionNumber,
KPeninputServerMinorVersionNumber,
KPeninputServerBuildVersionNumber );
if ( !User::QueryVersionSupported(v,aVersion) )
{
User::Leave( KErrNotSupported );
}
// create new session
RThread client;
CleanupClosePushL(client);
CSession2* ret = 0;
if(KErrNone == aMessage.Client(client))
{
//create new one
ret = CPeninputServerSession::NewL(client,
const_cast<CPeninputServer&>(*this));\
}
CleanupStack::PopAndDestroy(&client);
return ret;
}
// ---------------------------------------------------------------------------
// CPeninputServer::RunError
// Handle an error from CPeninputServerSession::ServiceL()
// Reports the error to the client and completes the message
// ---------------------------------------------------------------------------
//
TInt CPeninputServer::RunError( TInt aError )
{
Message().Complete( aError );
// The leave will result in an early return from CServer::RunL(), skipping
// the call to request another message. So do that now in order to keep the
// server running.
ReStart();
return KErrNone;// handled the error fully
}
// ---------------------------------------------------------------------------
// CPeninputServer::ConstructSpriteAnimL
// ---------------------------------------------------------------------------
//
void CPeninputServer::ConstructSpriteL()
{
// create bitmaps for sprite
iSpriteMember.iBitmap = CreateBitmapL( iSpriteSize, iDispMode );
#ifdef __ALPHA_TRANCEPARENCY__
iSpriteMember.iMaskBitmap = CreateBitmapL( iSpriteSize, EGray256);
iDispModeForMask = EGray256;
#else
iSpriteMember.iMaskBitmap = CreateBitmapL( iSpriteSize, iDispModeForMask);
iSpriteMember.iInvertMask = EFalse;
#endif
// set spritemember attributes
iSpriteMember.iOffset.iX = 0;
iSpriteMember.iOffset.iY = 0;
iSpriteMember.iInterval = 0;
iBitmapDevice = CFbsBitmapDevice::NewL(iSpriteMember.iBitmap);
iMaskBitmapDevice = CFbsBitmapDevice::NewL(
iSpriteMember.iMaskBitmap );
iSpriteGc = CFbsBitGc::NewL();
iSpriteGc->Reset();
CWsScreenDevice *screenDevice = CCoeEnv::Static()->ScreenDevice();
iWindowGc = CWindowToBitmapMappingGc::NewL(*screenDevice,*iSpriteGc);
/*iBitmapDevice->Resize( iSpriteSize);
iMaskBitmapDevice->Resize( iSpriteSize); */
ResizeDrawingDevice(iSpriteSize);
}
// ---------------------------------------------------------------------------
// CPeninputServer::CreateBitmapL
// ---------------------------------------------------------------------------
//
CFbsBitmap* CPeninputServer::CreateBitmapL( const TSize& aBitmapSize,
TDisplayMode aDisplayMode ) const
{
CFbsBitmap* const bitmap = new ( ELeave ) CFbsBitmap;
CleanupStack::PushL( bitmap );
// bitmaps are automatically cleared to white when first created
User::LeaveIfError( bitmap->Create( aBitmapSize, aDisplayMode ) );
CleanupStack::Pop(bitmap);
return bitmap;
}
// ---------------------------------------------------------------------------
// CPeninputServer::ChangeDisplayMode
// ---------------------------------------------------------------------------
//
void CPeninputServer::ChangeDisplayModeL(TDisplayMode aMode,
TDisplayMode aMaskMode)
{
if(aMode == iDispMode && aMaskMode == iDispModeForMask)
return;
if(iDispMode != aMode)
{
//use initial size to create small one in the first
CFbsBitmap* bmp = CreateBitmapL( iSpriteSize, aMode );
delete iSpriteMember.iBitmap;
iSpriteMember.iBitmap = bmp;
iDispMode = aMode;
delete iBitmapDevice;
iBitmapDevice = NULL;
iBitmapDevice = CFbsBitmapDevice::NewL(iSpriteMember.iBitmap);
}
if(iDispModeForMask != aMaskMode)
{
CFbsBitmap* maskbmp = CreateBitmapL( iSpriteSize, aMaskMode);
delete iSpriteMember.iMaskBitmap;
iSpriteMember.iMaskBitmap = maskbmp;
delete iMaskBitmapDevice;
iMaskBitmapDevice = NULL;
iMaskBitmapDevice = CFbsBitmapDevice::NewL(
iSpriteMember.iMaskBitmap );
iDispModeForMask = aMaskMode;
}
if(iAnimObj)
{
iAnimObj->AddChangeDispModeCmd(iSpriteMember);
}
}
// ---------------------------------------------------------------------------
// CPeninputServer::ClearSpriteGc
// Clears the bitmap - and mask bitmap devices.
// ---------------------------------------------------------------------------
//
void CPeninputServer::ClearSpriteGc()
{
//bitmap device
TPoint pt(0,0);
TRect rect(pt,iSpriteSize);
iSpriteGc->Activate( iBitmapDevice );
iSpriteGc->SetBrushStyle( CGraphicsContext::ESolidBrush );
iSpriteGc->SetBrushColor( KRgbWhite );
iSpriteGc->Clear(rect);
//mask bitmap device
iSpriteGc->Activate( iMaskBitmapDevice );
iSpriteGc->SetBrushColor( KRgbBlack ); //transparent
iSpriteGc->SetBrushStyle( CGraphicsContext::ESolidBrush );
iSpriteGc->Clear(rect);
}
// ---------------------------------------------------------------------------
// CPeninputServer::DrawSprite
// Draw the sprite
// ---------------------------------------------------------------------------
//
void CPeninputServer::DrawSprite()
{
if(!iUiLayout || iActive)
return;
ClearSpriteGc();
iUiLayout->Draw();
TRect r(TPoint(0,0),iSpriteSize);
if(iUseWindowCtrl)
{
iPenUiCtrl->Invalidate(r,EFullUpdate);
return;
}
else
{
if(iAnimObj)
{
iAnimObj->AddUpdateUiCmd(r,EFullUpdate);
}
//The best place for the timer should also in animation object. Can be refactored
//later
if(!iFlushTimer->IsActive())
{
iFlushTimer->Start(KWsSessionFlushPerioid, KWsSessionFlushPerioid,
TCallBack(FlushTimerCallBack,this));
}
iCurRectNumInBuf = 0;
}
return;
}
//MLayoutOwner
// ---------------------------------------------------------------------------
// CPeninputServer::UpdateArea
// Update sprite rect
// ---------------------------------------------------------------------------
//
void CPeninputServer::UpdateArea(const TRect& aRect,TBool /*aFullUpdate*/,
TBool aImmedFlag)
{
if (!iActive) //only update when sprite is active
return;
if(iUseWindowCtrl)
{
#ifdef FIX_FOR_NGA
iPenUiCtrl->Invalidate(TRect( TPoint(0,0), LayoutRect().Size()),EFalse);
#else
iPenUiCtrl->Invalidate(aRect,EFalse);
#endif
return;
}
TRect rect;
if(aRect.IsEmpty())
{
iSpriteGc->RectDrawnTo(rect);
}
else
rect = aRect;
// if (iOpaqueUi)
// aFullUpdate = EFalse; //never does full update to screen.
TUpdateArea area =
{
aRect,EFalse
};
AddFlushArea(area);
if(aImmedFlag)
{
FlushTimerCallBack(this);
}
else
{
if(!iFlushTimer->IsActive())
{
iFlushTimer->Start(KWsSessionFlushPerioid, KWsSessionFlushPerioid,
TCallBack(FlushTimerCallBack,this));
}
}
}
//from MLayuoutOwner
// ---------------------------------------------------------------------------
// CPeninputServer::BitmapContext
// Get bitmap context
// ---------------------------------------------------------------------------
//
CBitmapContext* CPeninputServer::BitmapContext()
{
return iSpriteGc;
}
// ---------------------------------------------------------------------------
// CPeninputServer::BitmapDevice
// Get bitmap device
// ---------------------------------------------------------------------------
//
CFbsBitmapDevice* CPeninputServer::BitmapDevice()
{
return iBitmapDevice;
}
// ---------------------------------------------------------------------------
// CPeninputServer::MaskBmpDevice
// Get mask bitmap device
// ---------------------------------------------------------------------------
//
CFbsBitmapDevice* CPeninputServer::MaskBmpDevice()
{
return iMaskBitmapDevice;
}
// ---------------------------------------------------------------------------
// CPeninputServer::Hide
// Hide/show sprite
// ---------------------------------------------------------------------------
//
void CPeninputServer::Hide(TBool aHideFlag)
{
if(aHideFlag)
{
DeactivateSprite();
}
else
{
if(!iActive)
{
ActivateSprite();
}
}
}
// ---------------------------------------------------------------------------
// CPeninputServer::LayoutSizeChanged
// Handle layout size change
// ---------------------------------------------------------------------------
//
TInt CPeninputServer::LayoutSizeChanged(const TSize& aSize, TBool aNeedUpdate)
{
TInt ret = KErrNone;
if(iUiLayout)
{
//This is the tricky place. We need to deactivate and activate the sprite,
//otherwise blank area appears.
TSize layoutSize = aSize;
TRect layoutRect = iUiLayout->Init();
layoutSize = layoutRect.Size();
layoutSize.iWidth = layoutSize.iWidth > aSize.iWidth ?
layoutSize.iWidth : aSize.iWidth;
layoutSize.iHeight = layoutSize.iHeight > aSize.iHeight ?
layoutSize.iHeight : aSize.iHeight;
if(iSpriteSize != layoutSize)
{
//deactive sprite first
TBool bRestoreActive = iActive;
//DeactivateSprite();
iSpriteSize = layoutSize;
//iBitmapDevice->Resize( layoutSize);
//iMaskBitmapDevice->Resize( layoutSize);
ResizeDrawingDevice(layoutSize);
if (aNeedUpdate)
{
FlushWsSession();
}
if(iAnimObj)
{
iAnimObj->AddChangeSizeCmd(layoutSize);
}
if(bRestoreActive )
{
//ActivateSprite();
}
}
if (iUseWindowCtrl)
{
iPenUiCtrl->SetExtent(LayoutRect().iTl,layoutSize);
//DrawSprite();
}
}
return ret;
}
void CPeninputServer::DimPenUi()
{
if(iDimmed)
{
RecoverButtonEventState();
DeactivateDimPenUiLayout(EFalse);
if(iUseWindowCtrl)
{
iPenUiCtrl->DimPenUiForMenu();
}
}
else
{
ActivatePenUiLayout(EFalse);
}
}
void CPeninputServer::DimPenInternalUi(TBool /*aFlag*/,TInt aPriority)
{
if(iDimmed)
{
RecoverButtonEventState();
DeactivateDimPenUiLayout(EFalse);
if(iUseWindowCtrl)
{
iPenUiCtrl->DimInternalPenUiForMenu(aPriority);
}
}
else
{
ActivatePenUiLayout(EFalse);
}
}
void CPeninputServer::DimPenUiForMenu(TInt aPriority)
{
if(iUseWindowCtrl)
{
iPenUiCtrl->DimPenUiForMenu(aPriority);
}
}
// ---------------------------------------------------------------------------
// CPeninputServer::SignalOwner
// Signal owner
// ---------------------------------------------------------------------------
//
void CPeninputServer::SignalOwner(TInt aEventType, const TDesC& aEventData)
{
//send fep related event to observer ( application)
if(ESignalFepEventBase <= aEventType)
{
TRAP_IGNORE(SignalObserverL(aEventType,aEventData));
}
else
{
switch(aEventType)
{
case ESignalCapturePointer: //request capture pointer
{
TUint16* buf = const_cast<TUint16* >( aEventData.Ptr() );
TBool flag = *(TBool*)aEventData.Ptr();
TInt captureID = *(TInt* )( buf + sizeof(TUint16));
if(iAnimObj)
{
iAnimObj->AddCapturePointerCmd(flag, captureID);
}
}
break;
case ESignalSimulateEvent: //request simulate event
{
//TBool* flag = (TBool*)aEventData.Ptr();
const TRawEvent* event = reinterpret_cast<const TRawEvent*>(aEventData.Ptr());
TRawEvent* modifyEvent = const_cast<TRawEvent*>( event );
modifyEvent->SetTip( ETrue );
if(iAnimObj)
{
iAnimObj->AddSimulateEventCmd(*event);
}
if( event->Type() == TRawEvent::EKeyDown )
{
static_cast<CAknAppUi*>(CEikonEnv::Static()->EikAppUi())->
DisableNextKeySound( event->ScanCode() );
}
iLastSimulatedKeyEvent = *event;
}
break;
case ESignalImmeSimulateEvent:
{
const TRawEvent* event = reinterpret_cast<const TRawEvent*>( aEventData.Ptr() );
TRawEvent* modifyEvent = const_cast<TRawEvent*>( event );
modifyEvent->SetTip( ETrue );
if(iAnimObj)
{
iAnimObj->ExecuteSimulateEventCmd(*event);
}
if( event->Type() == TRawEvent::EKeyDown )
{
static_cast<CAknAppUi*>(CEikonEnv::Static()->EikAppUi())->
DisableNextKeySound( event->ScanCode() );
}
iLastSimulatedKeyEvent = *event;
}
break;
#ifdef RD_TACTILE_FEEDBACK
case ESignalRegisterFeedbackArea:
{
if(!iSupportFeedback)
return;
AddFeedbackArea(FeedbackData(aEventData));
}
break;
case ESignalDeRegisterFeedbackArea:
{
if(!iSupportFeedback)
return;
RemoveFeedbackArea(FeedbackData(aEventData));
}
break;
case ESignalChangeFeedbackArea:
{
if(!iSupportFeedback)
return;
ChangeFeedbackArea(FeedbackData(aEventData));
}
break;
case ESignalChangeFeedbackType:
{
if(!iSupportFeedback)
return;
ChangeFeedbackType(FeedbackData(aEventData));
}
break;
#endif // RD_TACTILE_FEEDBACK
case ESignalGetAllowedInputMode:
{
TInt disabled = 0;
if ( iForegroundSession )
{
//GetProcessLayouts( iForegroundSession->ClientProcessId(),disabled );
disabled = iForegroundSession->DisabledUiType() | DisabledByOrientation();
if( iForegroundSession->DsaEverHappened() )
{
disabled |= DisabledByDSAFromAnim();
}
}
TInt allowed = SetDisabledLayouts( disabled );
TUint16* buf = const_cast<TUint16* >( aEventData.Ptr() );
TInt* retVal = reinterpret_cast< TInt* > ( buf );
*retVal = allowed;
}
break;
case ESignalPopupWnd:
{
if(iUseWindowCtrl)
{
TUint16* buf = const_cast<TUint16*>( aEventData.Ptr() );
TRect* rects = reinterpret_cast<TRect*>( buf );
TRect rectInLayout = *rects;
TRect rectTrimLayout = *(rects+1);
TRect rectInScreen = rectInLayout;
rectInScreen.Move( iSpritePosition );
iPenUiCtrl->ShowPopup( rectInScreen, rectInLayout, rectTrimLayout );
}
}
break;
case ESignalEnableLayoutRedrawWhenActive:
{
TUint16* buf = const_cast<TUint16* >( aEventData.Ptr() );
TBool* retVal = reinterpret_cast< TBool* > ( buf );
iIsLayoutReDrawAllowWhenActive = *retVal;
}
break;
default:
if(iUseWindowCtrl)
{
iPenUiCtrl->HandleNGASpecificSignal(aEventType, aEventData);
}
break;
}
}
}
// ---------------------------------------------------------------------------
// CPeninputServer::LayoutRect
// Get sprite size and position
// ---------------------------------------------------------------------------
//
TRect CPeninputServer::LayoutRect()
{
return TRect(iSpritePosition,iSpriteSize);
}
// ---------------------------------------------------------------------------
// CPeninputServer::SetPosition
// called when sprite has been moved
// ---------------------------------------------------------------------------
//
TPoint CPeninputServer::SetPosition(const TPoint& aNewPos)
{
if(iSpritePosition != aNewPos)
{
iSpritePosition = aNewPos;
if(iUseWindowCtrl)
iPenUiCtrl->SetPosition(aNewPos);
if(iAnimObj)
{
iAnimObj->AddSetPosCmd(iSpritePosition);
}
}
return iSpritePosition;
}
// ---------------------------------------------------------------------------
// CPeninputServer::FlushTimerCallBack
// CPeriodic callback function: Flush window session
// ---------------------------------------------------------------------------
//
TInt CPeninputServer::FlushTimerCallBack(TAny *aPtr)
{
CPeninputServer* self = static_cast<CPeninputServer*>(aPtr);
self->FlushWsSession();
return EFalse;
}
// ---------------------------------------------------------------------------
// CPeninputServer::FlushWsSession
// Flush window session
// ---------------------------------------------------------------------------
//
void CPeninputServer::FlushWsSession()
{
if (iCurRectNumInBuf)
{
if(iAnimObj)
{
iAnimObj->AddUpdateUiCmd(iFlushArea,iCurRectNumInBuf);
}
iCurRectNumInBuf = 0;
{
iFullUpdate = EFalse;
//cancel the timer
iFlushTimer->Cancel();
}
}
}
// ---------------------------------------------------------------------------
// CPeninputServer::DoIdleConstructL
// Do idle construction.
// ---------------------------------------------------------------------------
//
void CPeninputServer::DoIdleConstructL()
{
if(!iPtiEngine)
{
iPtiEngine = CPtiEngine::NewL(ETrue);
}
if(!iLayoutEng)
{
iLayoutEng = CFepLayoutEngine::NewL(iPtiEngine);
}
//this will only do once
}
// ---------------------------------------------------------------------------
// CPeninputServer::HandleResourceChange
// Handle application resource change
// ---------------------------------------------------------------------------
//
void CPeninputServer::HandleResourceChange(TInt aType)
{
#ifdef FIX_FOR_NGA
// iEnablePriorityChangeOnOriChange will be set to be EFalse, if some dialog in FEP end were opened and
// not close after rotation for example: Symbol Table, Writing Language list and Match Dialog on ITI
if(iUiLayout && iActive && iEnablePriorityChangeOnOriChange && aType == KEikDynamicLayoutVariantSwitch)
{
TPixelsTwipsAndRotation size;
CCoeEnv::Static()->ScreenDevice()->GetDefaultScreenSizeAndRotation(size);
TBool isPortrait = ( size.iPixelSize.iWidth < size.iPixelSize.iHeight );
TBool needToLiftUp = EFalse;
TInt inputMode = 0;
inputMode = iUiLayout->PenInputType();
if(inputMode == EPluginInputModeItut)
{
if(!isPortrait)
{
needToLiftUp = ETrue;
}
}
else if(inputMode == EPluginInputModeFSQ)
{
if(isPortrait)
{
needToLiftUp = ETrue;
}
}
else if(inputMode == EPluginInputModeFingerHwr)
{
ClearSpriteGc();
//Close the UI immediately, without notify UI handler
DeactivateSprite(ETrue, ETrue);
}
if(needToLiftUp)
{
if(iPenUiCtrl)
{
// must lift up the wnd group priority otherwise when rotating screen, the underling application will show first and then
// our PEN UI, but we should keep an eye on this issue. If NGA will fix the fliker assigned on them, we will check if it will
// work if we remove this line of code.
iPenUiCtrl->LiftUpPriority();
}
}
}
#endif
if(iUiLayout && !(iUiLayout->PenInputType() & DisabledByOrientation()) )
{
//hide the layout if it's already shown
if ( iActive )
{
iUiLayout->OnActivate();
}
iUiLayout->OnResourceChange(aType);
if(iUseWindowCtrl)
{
iPenUiCtrl->DrawNow();
}
//show the layout if it's active
}
}
// ---------------------------------------------------------------------------
// CPeninputServer::GetImePluginIdListL
// Get IME plugin implementation id list
// ---------------------------------------------------------------------------
//
void CPeninputServer::GetImePluginIdListL(const RMessage2& aMessage)
{
TInt language = aMessage.Int0();
TInt mode = aMessage.Int1();
TInt maxlen = aMessage.Int2();
const RArray<TInt>& implList = iLayoutEng->ImePluginListL(language, mode);
// +1 means there is extra position for count
TInt count = implList.Count() > (maxlen/sizeof(TInt) - 1)?
(maxlen/sizeof(TInt) - 1): implList.Count();
HBufC8* buf = HBufC8::NewLC((count + 1)*sizeof(TInt));
TPtr8 bufPtr = buf->Des();
RDesWriteStream writeStream;
writeStream.Open(bufPtr);
CleanupClosePushL(writeStream);
writeStream.WriteInt32L(count);
for(TInt ii = 0; ii < count; ++ii)
{
writeStream.WriteInt32L(implList[ii]);
}
writeStream.CommitL();
aMessage.WriteL(KMsgSlot3, *buf);
CleanupStack::PopAndDestroy(&writeStream);
CleanupStack::PopAndDestroy(buf);
}
// ---------------------------------------------------------------------------
// CPeninputServer::GetPenSupportLanguagesL
// Get touch input support language lists
// ---------------------------------------------------------------------------
//
void CPeninputServer::GetPenSupportLanguagesL(const RMessage2& aMessage)
{
TInt maxlen = aMessage.Int0();
const RArray<TInt>& implList = iLayoutEng->TouchSupportLanguagesL();
// +1 means there is extra position for count
TInt count = implList.Count() > (maxlen/sizeof(TInt) - 1)?
(maxlen/sizeof(TInt) - 1): implList.Count();
HBufC8* buf = HBufC8::NewLC((count + 1)*sizeof(TInt));
TPtr8 bufPtr = buf->Des();
RDesWriteStream writeStream;
writeStream.Open(bufPtr);
CleanupClosePushL(writeStream);
writeStream.WriteInt32L(count);
for(TInt ii = 0; ii < count; ++ii)
{
writeStream.WriteInt32L(implList[ii]);
}
writeStream.CommitL();
aMessage.WriteL(KMsgSlot1, *buf);
CleanupStack::PopAndDestroy(&writeStream);
CleanupStack::PopAndDestroy(buf);
}
// ---------------------------------------------------------------------------
// CPeninputServer::PropertyChangeCallBack
// Handle proproty change
// ---------------------------------------------------------------------------
//
TInt CPeninputServer::PropertyChangeCallBack(TAny* aData)
{
TRAP_IGNORE(static_cast<CPeninputServer*>(aData)->HideLayoutTemporaryL());
return 0;
}
// ---------------------------------------------------------------------------
// CPeninputServer::HideLayoutTemporary
// Temporarily hide the layout
// ---------------------------------------------------------------------------
//
void CPeninputServer::HideLayoutTemporaryL()
{
/* if (iUseWindowCtrl)
{
if (iActive && iUiLayout &&
iUiLayout->PenInputType() == EPluginInputModeItut)
{
iUiLayout->HandleCommand(ECmdPenInputRotation, NULL);
ClearSpriteGc();
iPenUiCtrl->ClosePenUi(ETrue);
iActive = EFalse;
}
return;
}
*/
TInt inputMode = iUiLayout ? iUiLayout->PenInputType() : EPluginInputModeNone;
TBool isArabicFingerInput = (inputMode == EPluginInputModeFingerHwr && iInputLanguage == ELangArabic);
if(isArabicFingerInput)
{
return;
}
if(iActive && !iPrevActive && inputMode != EPluginInputModeFSQ && iBackgroudDefaultOri == CAknAppUiBase::EAppUiOrientationUnspecified )
{
#ifdef FIX_FOR_NGA
if(inputMode == EPluginInputModeFingerHwr)
{
iPrevActive = ETrue;
ClearSpriteGc();
//Close the UI immediately, without notify UI handler
DeactivateSprite(ETrue, ETrue);
}
else
{// for other input mode: we are not going to cose UI, since it will cause
// serious fliker: which will have the mixed ui(with other app ui) on pen input ui
if(iUiLayout)
{
//TBool notDraw = ETrue;
//iUiLayout->HandleCommand(ECmdPeninputDisableLayoutDrawing,(unsigned char*)¬Draw);
iUiLayout->OnDeActivate();
}
}
#else
iPrevActive = ETrue;
ClearSpriteGc();
//Close the UI immediately, without notify UI handler
DeactivateSprite(ETrue, ETrue);
#endif
}
}
// ---------------------------------------------------------------------------
// CPeninputServer::SetDisabledLayouts
// Temporarily hide the layout
// ---------------------------------------------------------------------------
//
TInt CPeninputServer::SetDisabledLayouts( TInt aDisabledLayouts )
{
// No spcified logic now, so just store the disabled layout in the CFepUiLayoutBase class.
TInt allowedPlugin = EPluginInputModeNone;// EPluginInputModeHwr | EPluginInputModeVkb | EPluginInputModeItut | EPluginInputModeFSc;
TInt curLanguage = iInputLanguage;
if (curLanguage == 401) curLanguage = 102;
if (curLanguage == 402) curLanguage = 103;
TInt testMode = EPluginInputModeHwr;
while ( testMode < EPluginInputModeAll )
{
if ( iLayoutEng->IsSupportPluginMode( ( TLanguage )curLanguage,
( TPluginInputMode )testMode )
&& !( aDisabledLayouts & testMode ) )
{
allowedPlugin |= testMode;
}
testMode<<=1;
}
return allowedPlugin;
}
// ---------------------------------------------------------------------------
// CPeninputServer::GetProcessLayouts
// ---------------------------------------------------------------------------
//
TInt CPeninputServer::GetProcessLayouts( const TProcessId& aProcessId, TInt& aLayouts )
{
for ( int i = 0 ; i < iClientProcess.Count() ; i ++ )
{
if ( aProcessId == iClientProcess[i] )
{
aLayouts = iClientLayouts[i];
return KErrNone;
}
}
return KErrNotFound;
}
// ---------------------------------------------------------------------------
// CPeninputServer::SetProcessLayouts
// ---------------------------------------------------------------------------
//
TInt CPeninputServer::SetProcessLayouts( const TProcessId& aProcessId, TInt aLayouts)
{
for ( int i = 0 ; i < iClientProcess.Count() ; i ++ )
{
if ( aProcessId == iClientProcess[i] )
{
iClientLayouts[i] = aLayouts;
return KErrNone;
}
}
// not found, Insert
iClientProcess.Append( aProcessId );
iClientLayouts.Append( aLayouts );
return KErrNone;
}
// ---------------------------------------------------------------------------
// CPeninputServer::DelProcessLayouts
// ---------------------------------------------------------------------------
//
void CPeninputServer::DelProcessLayouts( const TProcessId& /*aProcessId*/ )
{
}
void CPeninputServer::ExecutePendingAnimCmd()
{
if( iAnimObj )
{
iAnimObj->ExeOnePendingAnimCmd();
}
}
void CPeninputServer::SetForeGroundUiHandlerL()
{
if(iForegroundUiHandler)
{
iForegroundUiHandler->ProcessPendingEventBeforeExit();
iForegroundUiHandler = NULL;
}
TBool bContinue = ETrue;
for(TInt i = iUiHandlerArray.Count()-1 ; i >= 0 && bContinue; i--)
{
if( (iForegroundSession == iUiHandlerArray[i]) // same session
|| (iForegroundSession->ClientId() == iUiHandlerArray[i]->ClientId())) //same thread
{
iForegroundUiHandler = iUiHandlerArray[i];
bContinue = EFalse; //found, break the loop
}
else
{
//check whether it's from same process
bContinue = !IsSameProcess(iForegroundSession,iUiHandlerArray[i]);
}
}
}
// ---------------------------------------------------------------------------
// CPeninputServer::HandleRawEventL
// Handle event from event queue, i.e, from animation dll
// ---------------------------------------------------------------------------
//
void CPeninputServer::HandleRawEventL(const TRawEvent& aEvent)
{
if(iActive)
{
if( aEvent.Type() == TRawEvent::ENone &&
aEvent.IsTip()
&& iCrpService && iCrpService->IsDsaActive() )
{
SignalOwner( ESignalLayoutClosed, KNullDesC );
}
TBool handled = iUiLayout ? iUiLayout->HandleEventL(ERawEvent,&aEvent)
: EFalse;
if (TRawEvent::EButton1Down == aEvent.Type())
{
iLastRawEvent = aEvent;
}
else if (TRawEvent::EPointerMove != aEvent.Type())
{
iLastRawEvent.Set(TRawEvent::EButton1Up);
}
if(aEvent.Type() == TRawEvent::EKeyDown ||
aEvent.Type() == TRawEvent::EKeyUp)
{
//write response to response queue
iKeyMsgResponseQueue.Send(handled);
//signal the semaphore
iKeyEventSemaphore.Signal();
}
}
}
// ---------------------------------------------------------------------------
// CPeninputServer::HandleRawEventL
// Handle event from window server
// ---------------------------------------------------------------------------
//
void CPeninputServer::HandleWsEventL(const TWsEvent &aEvent,
CCoeControl* /*aDestination*/)
{
switch(aEvent.Type())
{
case EEventWindowGroupListChanged:
{
iCurScreenFocusedWndGrpId = GetFocusAppUid().iUid;
}
break;
case EEventFocusGroupChanged:
{
TUid focusApp = GetFocusAppUid();
if(IsGlobalNotesApp(focusApp))
{
iInGlobalNotesApp = ETrue;
}
else
{
iInGlobalNotesApp = EFalse;
}
if(!(iUiLayout && iActive ))
return;
if(iUseWindowCtrl)
{
/* //Switch to akncapserver or leave
if(iUiLayout->PenInputType() == EPluginInputModeItut ||
iUiLayout->PenInputType() == EPluginInputModeFSQ )
{
DeactivatePenUiLayout(EFalse);
iPenUiCtrl->DimPenUiForMenu();
break;
}
*/
if( IsGlobalNotesApp(focusApp) )
{
iInGlobalNotesState = ETrue;
// add this to enable global dim
DeactivatePenUiLayout(EFalse);
break;
}
/* else if (focusApp.iUid == 0x102750f0)
{
DeactivateSprite();
}
*/ else
{
if(iInGlobalNotesState)
{
//fix for fast swap case
iInGlobalNotesState = EFalse;
if(iPreNonGloebalNotesWndGrpId != focusApp.iUid )
{
iPreNonGloebalNotesWndGrpId = focusApp.iUid;
DeactivateSprite(ETrue);//hide pen ui immediately if switched to another application
// Notify FEP to close touch input window.
// Under this case, touch input window can't be closed without norifying FEP side.
// After close touch input window, FEP must change some states.
SignalOwner( ESignalDeactivateSprite, KNullDesC );
}
}
else
{
DeactivateSprite(ETrue);
}
}
break;
}
DeactivateSprite(ETrue);//hide pen ui immediately
}
break;
default:
break;
}
}
#ifdef RD_TACTILE_FEEDBACK
// ---------------------------------------------------------------------------
// CPeninputServer::AddFeedbackArea
// add the feedback area
// ---------------------------------------------------------------------------
//
void CPeninputServer::AddFeedbackArea(const TTactileFeedbackArea& aAreaData)
{
if( iDestroyingLayout || !iAnimObj )
{
return;
}
iAnimObj->AddRegisterFeedbackAreaCmd(aAreaData,iUILayoutReady);
}
// ---------------------------------------------------------------------------
// CPeninputServer::RemoveFeedbackArea
// remove the feedback area
// ---------------------------------------------------------------------------
//
void CPeninputServer::RemoveFeedbackArea(const TTactileFeedbackArea& aAreaData)
{
if( iDestroyingLayout || !iAnimObj )
{
return;
}
iAnimObj->AddDeRegisterFeedbackAreaCmd(aAreaData,iUILayoutReady);
}
// ---------------------------------------------------------------------------
// CPeninputServer::ChangeFeedbackArea
// change the feedback area
// ---------------------------------------------------------------------------
//
void CPeninputServer::ChangeFeedbackArea(const TTactileFeedbackArea& aAreaData)
{
if( iDestroyingLayout || !iAnimObj )
{
return;
}
iAnimObj->AddChangeFeedbackAreaCmd(aAreaData,iUILayoutReady);
}
// ---------------------------------------------------------------------------
// CPeninputServer::ChangeFeedbackType
// change the feedback type
// ---------------------------------------------------------------------------
//
void CPeninputServer::ChangeFeedbackType(const TTactileFeedbackArea& aAreaData)
{
if( iDestroyingLayout || !iAnimObj)
{
return;
}
iAnimObj->AddChangeFeedbackTypeCmd(aAreaData,iUILayoutReady);
}
// ---------------------------------------------------------------------------
// CPeninputServer::FindFeedbackArea
// Find the feedback area
// ---------------------------------------------------------------------------
//
TInt CPeninputServer::FindFeedbackArea(const TTactileFeedbackArea& aArea)
{
for(TInt i = 0; i < iFeedbackAreaArray.Count(); ++i)
{
TTactileFeedbackArea temp = iFeedbackAreaArray[i];
if(iFeedbackAreaArray[i].iId == aArea.iId)
return i;
}
return KErrNotFound;
}
#endif // RD_TACTILE_FEEDBACK
// ---------------------------------------------------------------------------
// CPeninputServer::AnimOpNeedWaiting
// Check command for this type of event whether needs waiting.
// ---------------------------------------------------------------------------
//
TBool CPeninputServer::AnimOpNeedWaiting(TInt aSignalCode)
{
TBool bNeedWait = EFalse;
if(ESignalPenUiDeActivated == aSignalCode)
{
return EFalse;
}
if(iForegroundUiHandler)
{
TInt uiType = iUiLayout ? iUiLayout->PenInputType() : EPluginInputModeNone;
bNeedWait = iForegroundUiHandler->SignalUiActivationObserver(
aSignalCode,uiType);
}
return bNeedWait;
}
// ---------------------------------------------------------------------------
// CPeninputServer::RecoverSimulatedKeyEventState
// ---------------------------------------------------------------------------
//
void CPeninputServer::RecoverSimulatedKeyEventState()
{
if(!iAnimObj)
{
return;
}
if(iLastSimulatedKeyEvent.Type() == TRawEvent::EKeyDown)
{
//key up event is missing, we must manually simulate the up event.
iLastSimulatedKeyEvent.Set(TRawEvent::EKeyUp,iLastSimulatedKeyEvent.ScanCode());
iAnimObj->AddSimulateEventCmd(iLastSimulatedKeyEvent);
}
}
void CPeninputServer::RecoverButtonEventState()
{
if(!iUiLayout)
{
return;
}
if (TRawEvent::EButton1Down == iLastRawEvent.Type())
{
iLastRawEvent.Set(TRawEvent::EButton1Up);//,iLastSimulatedKeyEvent.ScanCode()
TRAP_IGNORE( iUiLayout->HandleEventL(ERawEvent,&iLastRawEvent) );
}
}
void CPeninputServer::EnsureUpdateBuffer()
{
if(!iAnimObj)
{
return;
}
if(iCurRectNumInBuf >= KMaxRectNumInBuf-1)
{
//flush previous buffer
iAnimObj->AddUpdateUiCmd(iFlushArea,iCurRectNumInBuf);
iCurRectNumInBuf = 0;
}
}
inline TBool ContainsEachOther(const TRect aRt1, const TRect aRt2 )
{
TRect rt(aRt1);
rt.BoundingRect( aRt2 );
return rt == aRt1 || rt == aRt2;
}
void CPeninputServer::PackFlushArea()
{
for( TInt i = iCurRectNumInBuf - 1; i > 0; i-- )
{
for( TInt j = i -1; j >=0; j-- )
{
if( ContainsEachOther(iFlushArea[i].iRect, iFlushArea[j].iRect) )
{
iFlushArea[j].iRect.BoundingRect(iFlushArea[i].iRect);
iCurRectNumInBuf--;
}
}
}
}
void CPeninputServer::AddFlushArea(const TUpdateArea& aArea)
{
for(TInt i = 0 ; i < iCurRectNumInBuf; ++i)
{
if(iFlushArea[i].iRect == aArea.iRect)
{
iFlushArea[i].iFullUpdateFlag |= aArea.iFullUpdateFlag;
return;
}
else if( iFlushArea[i].iFullUpdateFlag == aArea.iFullUpdateFlag )
{
TRect rt(aArea.iRect);
rt.BoundingRect(iFlushArea[i].iRect);
if( rt == iFlushArea[i].iRect || rt == aArea.iRect )
{
iFlushArea[i].iRect = rt;
//PackFlushArea();
return;
}
}
}
//Ensure buffer can hold new data
EnsureUpdateBuffer();
iFlushArea[iCurRectNumInBuf++] = aArea;
}
void CPeninputServer::PrepareExit()
{
CleanAll();
}
// ---------------------------------------------------------------------------
// CPeninputServer::MonitorWsGroupEvent
// Request to enable or disable window group change event
// ---------------------------------------------------------------------------
//
void CPeninputServer::MonitorWsGroupEvent(TBool aMonitorFlag)
{
RWindowGroup& rootWin = CCoeEnv::Static()->RootWin();
if(aMonitorFlag)
{
rootWin.EnableFocusChangeEvents (); // For cover UI/status pane refresh problems
//rootWin.EnableGroupListChangeEvents();
}
else
{
rootWin.DisableFocusChangeEvents (); // For cover UI/status pane refresh problems
//rootWin.DisableGroupListChangeEvents();
}
}
void CPeninputServer::CheckSessionValidL(CPeninputServerSession* aSession1,
CPeninputServerSession* aSession2) const
{
__ASSERT_DEBUG(aSession1 && aSession2, User::Leave(ENullSession));
}
// ---------------------------------------------------------------------------
// CPeninputServer::IsSameProcess
// Tests whether two sessions from same process
// ---------------------------------------------------------------------------
//
inline TBool CPeninputServer::IsSameProcess(CPeninputServerSession* aSession1,
CPeninputServerSession* aSession2) const
{
TRAP_IGNORE(CheckSessionValidL(aSession1, aSession2));
return aSession1->ClientProcessId().Id() == aSession2->ClientProcessId().Id();
}
// ---------------------------------------------------------------------------
// CPeninputServer::IsForegroundSession
// Tests whether current session is the foreground session.
// ---------------------------------------------------------------------------
//
inline TBool CPeninputServer::IsForegroundSession(CPeninputServerSession* aSession) const
{
if(!iForegroundSession)
return EFalse;
if(iForegroundSession == aSession)
return ETrue;
//same thread?
if(iForegroundSession->ClientId() == aSession->ClientId())
return ETrue;
//check whether the session is from the same process of foreground session
return IsSameProcess(iForegroundSession,aSession);
}
// ---------------------------------------------------------------------------
// CPeninputServer::ResizeDrawingDevice
// Resize the drawing device
// ---------------------------------------------------------------------------
//
void CPeninputServer::ResizeDrawingDevice(const TSize& aSize)
{
iSpriteMember.iBitmap->Resize(aSize);
iSpriteMember.iMaskBitmap->Resize(aSize);
iBitmapDevice->Resize( aSize);
iMaskBitmapDevice->Resize( aSize);
//gc must be adjusted
iSpriteGc->Activate(iBitmapDevice);
iSpriteGc->Resized();
}
TInt CPeninputServer::HandleAppInfoChange(CPeninputServerSession* aSession,
const TDesC& aAppInfo, TPeninputAppInfo aType) const
{
if(!iUiLayout)
return KErrNoLayout;
TInt err = KErrNone;
if(IsForegroundSession(aSession))
{
iUiLayout->HandleAppInfoChange(aAppInfo,aType);
}
else
{
err = KErrNotForegroundSession;
}
return err;
}
void CPeninputServer::BackgroudDefaultOri( TInt aOri)
{
iBackgroudDefaultOri = aOri;
}
TInt CPeninputServer::DisabledByDSA()
{
TInt disabled = 0;
TBool dsaOn = iCrpService->IsDsaActive();
//iAnimObj->GetDSAState(dsaOn);
if(dsaOn)
{
disabled = EPluginInputModeVkb | EPluginInputModeHwr | EPluginInputModeFSc;
}
return disabled;
}
TInt CPeninputServer::DisabledByDSAFromAnim()
{
TInt disabled = 0;
TBool dsaOn = EFalse;
if(!iAnimObj)
{
return disabled;
}
iAnimObj->GetDSAState(dsaOn);
if(dsaOn)
{
disabled = EPluginInputModeVkb | EPluginInputModeHwr | EPluginInputModeFSc;
}
return disabled;
}
TInt CPeninputServer::DisabledByOrientation()
{
TInt disabled = 0;
TBool sensorOn = EFalse;
if ( iSensorRepository )
{
iSensorRepository->Get( KSenSettingsSensorsOn, sensorOn );
if ( sensorOn )
{
TInt turnCtrl = 0;
iSensorRepository->Get( KSenSettingsTurnCtrl, turnCtrl );
turnCtrl = turnCtrl >> 2;
if ( turnCtrl )
{
TPixelsTwipsAndRotation size;
CCoeEnv::Static()->ScreenDevice()->GetDefaultScreenSizeAndRotation(size);
if( size.iPixelSize.iWidth < size.iPixelSize.iHeight )
{
return disabled |= EPluginInputModeFSQ;
}
if( size.iPixelSize.iWidth > size.iPixelSize.iHeight )
{
return disabled |= EPluginInputModeItut;
}
}
}
}
return disabled;
}
TInt CPeninputServer::GetSupportModeL()
{
TInt curLanguage = iInputLanguage;
if (curLanguage == 401) curLanguage = 102;
if (curLanguage == 402) curLanguage = 103;
TInt supportMode = EPluginInputModeNone;
TInt tempMode = EPluginInputModeHwr;
iLayoutEng->InitializeL();
while ( tempMode < EPluginInputModeAll )
{
if ( iLayoutEng->IsSupportPluginMode( ( TLanguage )curLanguage,
( TPluginInputMode )tempMode ) )
{
supportMode |= tempMode;
}
tempMode<<=1;
}
return supportMode;
}
TInt CPeninputServer::GetSupportModeByLanguageL( TInt aInputLanguage )
{
TInt curLanguage = aInputLanguage;
if ( curLanguage == 401 )
{
curLanguage = 102;
}
if (curLanguage == 402)
{
curLanguage = 103;
}
TInt supportMode = EPluginInputModeNone;
TInt tempMode = EPluginInputModeHwr;
iLayoutEng->InitializeL();
while ( tempMode < EPluginInputModeAll )
{
if ( iLayoutEng->IsSupportPluginMode( ( TLanguage )curLanguage,
( TPluginInputMode )tempMode ) )
{
supportMode |= tempMode;
}
tempMode<<=1;
}
return supportMode;
}
// ---------------------------------------------------------------------------
// CPeninputServer::DiscreetPopChangeNotification
// handle notification of discreept pop changing
// ---------------------------------------------------------------------------
//
TInt CPeninputServer::DiscreetPopChangeNotification(TAny* aObj)
{
if (aObj)
{
static_cast<CPeninputServer*>(aObj)->HandleDiscreetPopNotification();
return KErrNone;
}
else
{
return KErrArgument;
}
}
// ---------------------------------------------------------------------------
// CPeninputServer::HandleDiscreetPopNotification
// handle notification of discreept pop changing
// ---------------------------------------------------------------------------
//
void CPeninputServer::HandleDiscreetPopNotification()
{
iDiscreetPopArea = iAknUiSrv.GetInUseGlobalDiscreetPopupRect();
iAnimObj->SetDiscreetPopArea(iDiscreetPopArea);
}
// ======== class CEventQueue========
//
// ---------------------------------------------------------------------------
// CEventQueue::CEventQueue
// Constructor. Adds the active object to the active scheduler
// and issues a request for server notification.
// ---------------------------------------------------------------------------
//
CEventQueue::CEventQueue(MRawEventHandler* aHandler):CActive( EPriorityHigh ),
iHandler(aHandler)
{
// issue asynchronous request and set this object active
CActiveScheduler::Add( this );
}
// ---------------------------------------------------------------------------
// CEventQueue::NewL
// factory constructor.
// ---------------------------------------------------------------------------
//
CEventQueue* CEventQueue::NewL(MRawEventHandler* aHandler,const TDesC& aName)
{
CEventQueue* queue = new(ELeave)CEventQueue(aHandler);
CleanupStack::PushL(queue);
queue->ConstructL(aName);
CleanupStack::Pop(queue);
return queue;
}
// ---------------------------------------------------------------------------
// CEventQueue::ConstructL
// 2nd phase constructor
// ---------------------------------------------------------------------------
//
void CEventQueue::ConstructL(const TDesC& aName)
{
//create message queue
User::LeaveIfError(iMsgBufQueue.CreateGlobal(aName,KMsgQueueLen));
}
// ---------------------------------------------------------------------------
// CEventQueue::CEventQueue
// Destructor. Cancels any outstanding requests
// ---------------------------------------------------------------------------
//
CEventQueue::~CEventQueue()
{
Cancel();
iMsgBufQueue.Close();
}
// ---------------------------------------------------------------------------
// CEventQueue::DoCancel
// Cancels the notification requests
// ---------------------------------------------------------------------------
//
void CEventQueue::DoCancel()
{
iMsgBufQueue.CancelDataAvailable();
}
// ---------------------------------------------------------------------------
// CEventQueue::RunL
// ---------------------------------------------------------------------------
//
void CEventQueue::RunL()
{
//iHandler is always there. No need to check it
TRawEventBuffer events;
iMsgBufQueue.Receive(events);
for(TInt i = 0; i < events.iNum; i++)
{
iHandler->HandleRawEventL(events.iEvent[i]);
}
// re-issue request
GetEvent();
}
// ---------------------------------------------------------------------------
// CEventQueue::RunError
// ---------------------------------------------------------------------------
//
TInt CEventQueue::RunError(TInt /*aError*/)
{
// re-issue request
GetEvent();
return KErrNone;
}
// ---------------------------------------------------------------------------
// CEventQueue::GetEvent
// Reissue request for event
// ---------------------------------------------------------------------------
//
void CEventQueue::GetEvent()
{
if(IsActive())
return;
iMsgBufQueue.NotifyDataAvailable(iStatus);
SetActive();
}
// ======== class CAknLayoutChangeWatcher========
//
// ---------------------------------------------------------------------------
// CAknLayoutChangeWatcher::NewL
// Factory constructor.
// ---------------------------------------------------------------------------
//
CAknLayoutChangeWatcher* CAknLayoutChangeWatcher::NewL(
CPeninputServer* aHandler,TUint aKey)
{
CAknLayoutChangeWatcher* self = new(ELeave)CAknLayoutChangeWatcher(
aHandler,aKey);
CActiveScheduler::Add(self);
return self;
}
// ---------------------------------------------------------------------------
// CAknLayoutChangeWatcher::~CAknLayoutChangeWatcher
// Destructor
// ---------------------------------------------------------------------------
//
CAknLayoutChangeWatcher::~CAknLayoutChangeWatcher()
{
Cancel();
}
// ---------------------------------------------------------------------------
// CAknLayoutChangeWatcher::CAknLayoutChangeWatcher
// Default constructor
// ---------------------------------------------------------------------------
//
CAknLayoutChangeWatcher::CAknLayoutChangeWatcher(CPeninputServer* aHandler,
TUint aKey)
: CActive( EPriorityHigh ),iHandler(aHandler)
{
iProperty.Attach(KPSUidUikon,aKey);
iLayoutState = KInvalidValue;
iOrientationState = KInvalidValue;
}
// ---------------------------------------------------------------------------
// CAknLayoutChangeWatcher::StartWatching
// Start to monitor
// ---------------------------------------------------------------------------
//
void CAknLayoutChangeWatcher::StartWatching()
{
iProperty.Subscribe(iStatus);
SetActive();
}
// ---------------------------------------------------------------------------
// CAknLayoutChangeWatcher::DoCancel
// Cancels the notification requests
// ---------------------------------------------------------------------------
//
void CAknLayoutChangeWatcher::DoCancel()
{
iProperty.Cancel();
}
// ---------------------------------------------------------------------------
// CAknLayoutChangeWatcher::RunL
// ---------------------------------------------------------------------------
//
void CAknLayoutChangeWatcher::RunL()
{
TInt layoutstate = KInvalidValue;
TInt orientstate = KInvalidValue;
iProperty.Get(KPSUidUikon, KUikLayoutState, layoutstate);
iProperty.Get(KPSUidUikon, KUikPreferredOrientation, orientstate);
if(layoutstate != iLayoutState || orientstate != iOrientationState)
{
// save the previous state
iLayoutState = layoutstate;
iOrientationState = orientstate;
// hide layout when monitered object change state
iHandler->HideLayoutTemporaryL();
}
StartWatching();
}
// ---------------------------------------------------------------------------
// CEventQueue::RunError
// ---------------------------------------------------------------------------
//
TInt CAknLayoutChangeWatcher::RunError(TInt /*aError*/)
{
// re-issue request
StartWatching();
return KErrNone;
}
// ======== GLOBAL FUNCTIONS ========
// ---------------------------------------------------------
// PanicServer
// ---------------------------------------------------------
//
GLDEF_C void PanicServer(TPeninputServerPanic aPanic)
{
User::Panic( KPeninputServerName, aPanic );
}
// ======== class CSubscriber========
//
CSubscriber::CSubscriber(TCallBack aCallBack, RProperty& aProperty)
:
CActive(EPriorityNormal), iCallBack(aCallBack), iProperty(aProperty)
{
CActiveScheduler::Add(this);
}
CSubscriber::~CSubscriber()
{
Cancel();
}
void CSubscriber::SubscribeL()
{
if (!IsActive())
{
iProperty.Subscribe(iStatus);
SetActive();
}
}
void CSubscriber::StopSubscribe()
{
Cancel();
}
void CSubscriber::RunL()
{
if (iStatus.Int() == KErrNone)
{
iCallBack.CallBack();
SubscribeL();
}
}
void CSubscriber::DoCancel()
{
iProperty.Cancel();
}
// End of File