/*
* 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 client
*
*/
#include "peninputclientserver.h"
#include "peninputclientimpl.h"
#include "peninputcmd.h"
#include "peninputsrvobserver.h"
#include <apgtask.h>
#include <w32std.h>
#include <apacmdln.h>
#include <apgcli.h>
#include <s32mem.h>
#include <coemain.h>
#include <apgwgnam.h>
#include "peninputclient.h"
#ifndef FIX_FOR_NGA
#define FIX_FOR_NGA
#endif
const TUint KDefaultMessageSlots = 4;
const TInt KMaxSupportLanguages = 100;
const TInt KMaxImeImplementations = 10;
const TUid KSingletonClientId =
{
0x10281854
};
TUid GetAppUidByWndGroupIdL( RWsSession &aWs, TInt aWndGroupId )
{
CApaWindowGroupName* wg = CApaWindowGroupName::NewLC(aWs,aWndGroupId);
TUid id = wg->AppUid();
CleanupStack::PopAndDestroy(wg);
return id;
}
TUid AppUidFromWndGroupIdL(TInt aWndGrpId)
{
RWsSession &ws = CCoeEnv::Static()->WsSession();
//TInt wgId =ws.GetFocusWindowGroup();
CApaWindowGroupName* wg = CApaWindowGroupName::NewLC(ws,aWndGrpId);
TUid id = wg->AppUid();
CleanupStack::PopAndDestroy(wg);
return id;
}
TUid AppUidFromWndGroupId(TInt aWndGrpId)
{
TUid id = {0x00000000};
TRAP_IGNORE(id = AppUidFromWndGroupIdL(aWndGrpId));
return id;
}
inline TUid GetFocusAppUid()
{
return AppUidFromWndGroupId(CCoeEnv::Static()->WsSession().GetFocusWindowGroup());
}
TUid GetCurAppUid()
{
return AppUidFromWndGroupId(CCoeEnv::Static()->RootWin().Identifier());
}
CPeninputServerWaiter* CPeninputServerWaiter::NewL()
{
CPeninputServerWaiter* self = new(ELeave)CPeninputServerWaiter;
CleanupStack::PushL(self);
self->ConstructL();
CleanupStack::Pop(self);
return self;
}
void CPeninputServerWaiter::ConstructL()
{
iWaitScheduler = new(ELeave) CActiveSchedulerWait;
}
CPeninputServerWaiter::~CPeninputServerWaiter()
{
delete iWaitScheduler;
}
void CPeninputServerWaiter::Start()
{
iWaitScheduler->Start();
}
void CPeninputServerWaiter::Stop(TInt aFlag)
{
//if(aFlag)
iError = aFlag ? KErrNone : aFlag;
iWaitScheduler->AsyncStop();
}
// ======== MEMBER FUNCTIONS ========
// ---------------------------------------------------------------------------
// RPeninputServerImpl::NewL
// ---------------------------------------------------------------------------
//
RPeninputServerImpl* RPeninputServerImpl::NewL(TRequestStatus* aStatus)
{
//check for singleton existence
CCoeStatic * obj = CCoeEnv::Static()->FindStatic(KSingletonClientId);
CPenInputSingletonClient* client =
static_cast<CPenInputSingletonClient*>(obj);
if(client && client->IsValid())
{
RPeninputServerImpl* server = client->GetSingletonServer();
TInt err = server->ServerReady() ? KErrNone : KErrLaunchingServer;
if ( aStatus )
{
User::RequestComplete( aStatus, err );
}
return server;
}
RPeninputServerImpl* self = new(ELeave) RPeninputServerImpl();
CleanupStack::PushL(self);
self->ConstructL(KSingletonClientId,aStatus);
CleanupStack::Pop(self);
return self;
}
// ---------------------------------------------------------------------------
// RPeninputServerImpl::RPeninputServerImpl
// ---------------------------------------------------------------------------
//
RPeninputServerImpl::RPeninputServerImpl() : iPosition(0,0),iSize(0,0)
{
iObserver = 0;
iIsForegroundSession = EFalse;
iServerExit = EFalse;
iLaunchServer = EFalse;
iCurPenUiType = -1;
iWaitScheduler = NULL;
iAppPrefferedUiMode = EPluginInputModeNone;
iAutoOpenFlag = ETrue;
iBackgroundCtrl = 0;
iResourceChange = EFalse;
iWaiterAo = NULL;
iPendingRequest = NULL;
iServerReady = EFalse;
}
void RPeninputServerImpl::ConstructL(const TUid& aUid, TRequestStatus* aStatus)
{
CCoeStatic * obj = CCoeEnv::Static()->FindStatic(aUid);
CPenInputSingletonClient* client;
//__ASSERT_ALWAYS(obj == NULL, User::Leave(KErrAlreadyExists));
if(obj)
{
client = static_cast<CPenInputSingletonClient*>(obj);
client->ReplaceServer(this);
}
else
client = new (ELeave)CPenInputSingletonClient(aUid,this);
//Note: The client is destroyed by the control environment automatically
//User::LeaveIfError(DoConnectL());
TRAPD(err, DoConnectL(aStatus));
if(KErrNone != err)
{
client->SetInvalid();
User::LeaveIfError(err);
}
}
// ---------------------------------------------------------------------------
// RPeninputServerImpl::DoConnectL
// ---------------------------------------------------------------------------
//
/*TInt RPeninputServerImpl::Connect()
{
//do nothing
return KErrNone;
}
*/
// ---------------------------------------------------------------------------
// RPeninputServerImpl::Close
// ---------------------------------------------------------------------------
//
void RPeninputServerImpl::Close()
{
CCoeStatic * obj = CCoeEnv::Static()->FindStatic(KSingletonClientId);
CPenInputSingletonClient* client =
static_cast<CPenInputSingletonClient*>(obj);
if(client)
{
TInt ref = client->DecreaseRef();
if (ref <= 0)
{
// delete the CCoeStatic object of CPenInputSingletonClient when
// Peninput server was closed.
// Basiccaly, all CCoeStatic objects are deleted in CCoeEnv destructor.
// However, it is necessary to delete the CCoeStatic object when
// changing from avkon fep to other fep.
delete client;
}
}
}
// ---------------------------------------------------------------------------
// RPeninputServerImpl::DoConnectL
// ---------------------------------------------------------------------------
//
TInt RPeninputServerImpl::DoConnectL(TRequestStatus* aStatus)
{
iPendingRequest = aStatus;
TInt error = KErrNone;
/*************** Note ************************************************/
// Multi-thread case is not considered here!
/*************** Note ************************************************/
// try to connect to the server
error = CreateSession( KPeninputServerName,
Version(),
KDefaultMessageSlots,EIpcSession_Sharable);
if( error == KErrNotFound || error == KErrServerTerminated )
{
// server does not yet exist or it has terminated
// try to create the server
if(!aStatus) //sync call
{
error = StartThreadL();
if(KErrNone == error)
{
error = CreateSession( KPeninputServerName,
Version(),
KDefaultMessageSlots,EIpcSession_Sharable);
AddObserver();
}
}
else
{
StartThreadAsyncL();
return KErrNone;
}
}
else if ( error == KErrNone )//server alreay there
{
iServerReady = ETrue;
AddObserver();
if(aStatus)
User::RequestComplete(iPendingRequest, error);
}
return error;
}
void RPeninputServerImpl::AddObserver()
{
TThreadId srvThreadId;
TIpcArgs arg;
TPckg<TThreadId> msg(srvThreadId);
arg.Set(KMsgSlot0,&msg);
SendReceive(EPeninputRequestServerThreadId,arg);
iServerExit = EFalse;
if(iObserver)
{
TRAP_IGNORE(iObserver->ReConstructL(srvThreadId));
}
else
{
TRAP_IGNORE(iObserver = CPeninputServerObserver::NewL(this,srvThreadId));
}
}
TBool RPeninputServerImpl::ServerReady()
{
return iServerReady;
}
// ---------------------------------------------------------------------------
// RPeninputServerImpl::Version
// ---------------------------------------------------------------------------
//
TVersion RPeninputServerImpl::Version(void) const
{
return( TVersion( KPeninputServerMajorVersionNumber,
KPeninputServerMinorVersionNumber,
KPeninputServerBuildVersionNumber ) );
}
// ---------------------------------------------------------------------------
// RPeninputServerImpl::RequestMessageNotification
// Register to require message notification
// ---------------------------------------------------------------------------
//
void RPeninputServerImpl::RequestMessageNotification( TRequestStatus& aStatus )
{
TInt data=0;
SendReceive( EPeninputServerRequestMessageNotification, TIpcArgs(data), aStatus );
}
// ---------------------------------------------------------------------------
// RPeninputServerImpl::CancelMessageNotification
// Cancel message notification
// ---------------------------------------------------------------------------
//
void RPeninputServerImpl::CancelMessageNotification()
{
SendReceive( EPeninputServerCancelMessageNotification);
}
void RPeninputServerImpl::DimUiLayout(TBool aFlag)
{
TRAP_IGNORE(DimUiLayoutL(aFlag));
}
void RPeninputServerImpl::DimUiLayoutL(TBool aFlag)
{
TInt priority = iPriority;
TPckgC<TBool> msg(aFlag);
TIpcArgs arg;
arg.Set(KMsgSlot0,&msg);
TPckgC<TInt> prioriryMsg(priority);//p
arg.Set(KMsgSlot1,&prioriryMsg);
TInt bmpHandle = -1;
TPckg<TInt> handleMsg(bmpHandle);
arg.Set(KMsgSlot2,&handleMsg);
TRect extend;
TPckg<TRect> posMsg(extend);
arg.Set(KMsgSlot3,&posMsg);
if (iInternalPopup)
{
SendReceive(EPeninputRequestInternalDimLayout,arg);
}
else
{
SendReceive(EPeninputRequestDimLayout,arg);
}
if(aFlag)
{
//show the background control
if(!iBackgroundCtrl)
{
iBackgroundCtrl = CPenUiBackgroundWnd::NewL(CCoeEnv::Static()->RootWin(),bmpHandle);
}
if(iBackgroundCtrl)
iBackgroundCtrl->Show(extend, iGlobalNotes,
iInternalPopup,priority, iResourceChange);
}
else //undim the window
{
if(iBackgroundCtrl)
#ifdef FIX_FOR_NGA
{
delete iBackgroundCtrl;
iBackgroundCtrl = 0;
}
#else
{
iBackgroundCtrl->Hide();
}
#endif
}
}
// ---------------------------------------------------------------------------
// RPeninputServerImpl::ActivateLayout
// Activate/Deactivate a ui layout
// ---------------------------------------------------------------------------
//
void RPeninputServerImpl::ActivateLayout(TBool aFlag)
{
if(iBackgroundCtrl && iBackgroundCtrl->IsVisible())
iBackgroundCtrl->Hide();
//inform UI activation handler
for(TInt i = 0 ; i < iPenUiNotificationHandler.Count(); ++i)
{
if(iPenUiNotificationHandler[i].iType & iCurPenUiType)
{
if(aFlag)
iPenUiNotificationHandler[i].iHandler->OnPeninputUiActivated();
else
iPenUiNotificationHandler[i].iHandler->OnPeninputUiDeactivated();
}
}
if ( aFlag || ( !aFlag && IsVisible() ) )
{
TPckgC<TBool> msg(aFlag);
TIpcArgs arg;
arg.Set(KMsgSlot0,&msg);
TInt scrMode = CCoeEnv::Static()->ScreenDevice()->CurrentScreenMode();
TPckgC<TInt> scrMsg(scrMode);
arg.Set(KMsgSlot1,&scrMsg);
SendReceive(EPeninputRequestActivateLayout,arg);
}
}
void RPeninputServerImpl::ActivatePeninputInNotesL()
{
SendReceive(EPeninputRequestActivateLayoutInGlobalNotes);
}
// ---------------------------------------------------------------------------
// RPeninputServerImpl::GetServerEventData
// Retrieve server event data
// ---------------------------------------------------------------------------
//
TInt RPeninputServerImpl::GetServerEventData(TDes& aBuf)
{
if(iServerExit) // ???
return -1;
TIpcArgs arg;
aBuf.Zero();
arg.Set(KMsgSlot0,aBuf.MaxLength());
arg.Set(KMsgSlot1,&aBuf);
return SendReceive(EPeninputRequestGetServerEventData,arg);
}
// ---------------------------------------------------------------------------
// RPeninputServerImpl::ServerEventDfataNum
// Get the number of server event
// ---------------------------------------------------------------------------
//
TInt RPeninputServerImpl::ServerEventDataNum()
{
TInt num = -1;
TPckg<TInt> msg(num);
TIpcArgs arg;
arg.Set(KMsgSlot0,&msg);
TInt err = SendReceive(EPeninputRequestGetServerEventDataNumber,arg);
if(err != KErrNone)
num = err;//set the error code
return num;
}
// ---------------------------------------------------------------------------
// RPeninputServerImpl::ResourceChanged
// Tell server the client resource changed
// ---------------------------------------------------------------------------
//
void RPeninputServerImpl::ResourceChanged(TInt aType)
{
TIpcArgs arg;
TPckgC<TInt> msg(aType);
arg.Set(KMsgSlot0,&msg);
SendReceive(EPeninputRequestResourceChanged,arg);
}
// ---------------------------------------------------------------------------
// RPeninputServerImpl::SetUiLayoutPos
// Set ui layout position
// ---------------------------------------------------------------------------
//
TInt RPeninputServerImpl::SetUiLayoutPos(const TPoint& aPos)
{
TPckgC<TPoint> msg(aPos);
TIpcArgs arg;
arg.Set(KMsgSlot0,&msg);
return SendReceive(EPeninputRequestUiSetUiPos,arg);
}
// ---------------------------------------------------------------------------
// RPeninputServerImpl::UiLayoutPos
// get ui layout position
// ---------------------------------------------------------------------------
//
void RPeninputServerImpl::GetUiLayoutPosAndSize()
{
TPckg<TPoint> msgPos(iPosition);
TPckg<TSize> msgSize(iSize);
TIpcArgs arg;
arg.Set(KMsgSlot0,&msgPos);
arg.Set(KMsgSlot1,&msgSize);
SendReceive(EPeninputRequestUiGetUiPos,arg);
}
// ---------------------------------------------------------------------------
// RPeninputServer::UiLayoutPos
// get ui layout position
// ---------------------------------------------------------------------------
//
TPoint RPeninputServerImpl::UiLayoutPos()
{
GetUiLayoutPosAndSize();
return iPosition;
}
// ---------------------------------------------------------------------------
// RPeninputServer::UiLayoutSize
// get ui layout size
// ---------------------------------------------------------------------------
//
TSize RPeninputServerImpl::UiLayoutSize()
{
GetUiLayoutPosAndSize();
return iSize;
}
// ---------------------------------------------------------------------------
// RPeninputServerImpl::SetUiLayoutId
// Create a ui layout
// ---------------------------------------------------------------------------
//
TInt RPeninputServerImpl::SetUiLayoutId(TUid aId)
{
TInt uid = aId.iUid;
TPckgC<TInt> msg(uid);
TIpcArgs arg;
arg.Set(KMsgSlot0,&msg);
TPckg<TInt> type(iCurPenUiType);
arg.Set(KMsgSlot2,&type);
return SendReceive(EPeninputRequestSetUiLayoutId,arg);
}
// ---------------------------------------------------------------------------
// RPeninputServerImpl::SetUiLayoutId
// Create a ui layout
// ---------------------------------------------------------------------------
//
TInt RPeninputServerImpl::SetUiLayoutId(TUid aId,const TDesC8& aData)
{
TInt uid = aId.iUid;
TPckgC<TInt> idMsg(uid);
TIpcArgs arg;
arg.Set(KMsgSlot0,&idMsg);
arg.Set(KMsgSlot1,&aData);
TPckg<TInt> type(iCurPenUiType);
arg.Set(KMsgSlot2,&type);
return SendReceive(EPeninputRequestSetUiLayoutIdWithData,arg);
}
// ---------------------------------------------------------------------------
// RPeninputServerImpl::HandleCommand
// Ask ui layout handle command
// ---------------------------------------------------------------------------
//
TInt RPeninputServerImpl::HandleCommand(TInt aCmd,const TDesC8& aBuf)
{
TInt ret;
return HandleCommand(aCmd,aBuf,ret);
}
// ---------------------------------------------------------------------------
// RPeninputServerImpl::HandleCommand
// Ask ui layout handle command
// ---------------------------------------------------------------------------
//
TInt RPeninputServerImpl::HandleCommand(TInt aCmd)
{
TInt ret;
return HandleCommand(aCmd,KNullDesC8,ret);
}
// ---------------------------------------------------------------------------
// RPeninputServerImpl::HandleCommand
// Ask ui layout handle command
// ---------------------------------------------------------------------------
//
TInt RPeninputServerImpl::HandleCommand(TInt aCmd,const TDesC8& aBuf, TInt &aResult)
{
//if(iSingletonServer != this)
// return iSingletonServer->HandleCommand(aCmd,aBuf, aResult);
if(!IsForegroundSession()) // not handle non-foregound session command
return EFalse;
TIpcArgs arg;
TPckgC<TInt> cmdMsg(aCmd);
arg.Set(KMsgSlot0,&cmdMsg);
arg.Set(KMsgSlot1,&aBuf);
TPckg<TInt> retMsg(aResult);
arg.Set(KMsgSlot2,&retMsg);
return SendReceive(EPeninputRequestHandleClientCommand,arg);
}
// ---------------------------------------------------------------------------
// RPeninputServerImpl::IsVisible
// ---------------------------------------------------------------------------
//
TBool RPeninputServerImpl::IsVisible()
{
TBool bVisible;
TIpcArgs arg;
TPckg<TBool> msg(bVisible);
arg.Set(KMsgSlot0,&msg);
SendReceive(EPeninputRequestUiIsVisible,arg);
return bVisible;
}
// ---------------------------------------------------------------------------
// RPeninputServerImpl::IsVisible
// ---------------------------------------------------------------------------
//
TBool RPeninputServerImpl::IsDimmed()
{
TBool bDimmed;
TIpcArgs arg;
TPckg<TBool> msg(bDimmed);
arg.Set(KMsgSlot0,&msg);
SendReceive(EPeninputRequestIsLayoutDimmed,arg);
return bDimmed;
}
// ---------------------------------------------------------------------------
// RPeninputServerImpl::IsDimmed
// ---------------------------------------------------------------------------
//
TInt RPeninputServerImpl::SupportInputMode( TInt aLanguage )
{
TInt supportMode = 0;
TIpcArgs arg;
TPckg<TInt> msg(supportMode);
arg.Set(KMsgSlot0,&msg);
TPckg<TInt> language( aLanguage );
arg.Set( KMsgSlot1,&language );
SendReceive(EPeninputRequestSupportInputMode,arg);
return supportMode;
}
TInt RPeninputServerImpl::SetInputLanguage( TInt aLanguage )
{
TIpcArgs arg;
TPckgC<TInt> msg(aLanguage);
arg.Set(KMsgSlot0,&msg);
return SendReceive(EPeninputRequestSetInputLanguage, arg);
}
void RPeninputServerImpl::BackgroudDefaultOri( TInt aOri )
{
TIpcArgs arg;
TPckgC<TInt> msg(aOri);
arg.Set(KMsgSlot0,&msg);
SendReceive(EPeninputBackgroudDefaultOri,arg);
}
// ---------------------------------------------------------------------------
// RPeninputServerImpl::SetAppBackgroundL
// Set server running in background
// ---------------------------------------------------------------------------
//
/*void RPeninputServerImpl::SetAppBackgroundL(RProcess& aServer)
{
CApaCommandLine* commandLine = CApaCommandLine::NewLC();
commandLine->SetDocumentNameL(KNullDesC);
commandLine->SetExecutableNameL(KPeninputServerExe);
//if (aType == EBackgroundApplicationType )
commandLine->SetCommandL( EApaCommandBackground );
commandLine->SetProcessEnvironmentL(aServer);
CleanupStack::PopAndDestroy(commandLine);
}
*/
TInt RPeninputServerImpl::StartThreadAsyncL()
{
//ASSERT_DUBUG(!iWaiterAo)
iWaiterAo = new CWaitingServerAo(this);
TInt ret = KErrNone;
RProcess server;
User::LeaveIfError(server.Create(KPeninputServerExe,KNullDesC()));
server.Rendezvous(iWaiterAo->RequestStatus());
server.Resume();
server.Close();
return ret;
}
// ---------------------------------------------------------------------------
// RPeninputServerImpl::StartThread
// Creates the server thread on WINS and server process on MARM.
// Access to the thread/process creation is controlled with
// a global mutex which allows only one client thread to do
// the actual server creation in WINS. In MARM the creation of
// new server exits with KErrAlreadyExits if another thread
// already created it.
// ---------------------------------------------------------------------------
//
TInt RPeninputServerImpl::StartThreadL()
{
TInt ret = KErrNone;
RProcess server;
User::LeaveIfError(server.Create(KPeninputServerExe,KNullDesC()));
TRequestStatus status;
server.Rendezvous(status);
server.Resume();
server.Close();
User::WaitForRequest(status);
if(ESignalServerReady != status.Int())
ret = KErrGeneral;
else
iServerReady = ETrue;
return ret;
}
// ---------------------------------------------------------------------------
// RPeninputServerImpl::AddPeninputServerObserverL
// Add observer
// ---------------------------------------------------------------------------
//
void RPeninputServerImpl::AddPeninputServerObserverL(
MPeninputServerEventHandler* aHandler)
{
//can only set once
iObserver->AddEventHandler(aHandler);
}
// ---------------------------------------------------------------------------
// RPeninputServerImpl::RemovePeninputServerObserver
// Remove observer
// ---------------------------------------------------------------------------
//
void RPeninputServerImpl::RemovePeninputServerObserver()
{
CCoeStatic * obj = CCoeEnv::Static()->FindStatic(KSingletonClientId);
if ( !obj )
{
return;
}
delete iObserver;
iObserver = NULL;
}
// ---------------------------------------------------------------------------
// RPeninputServerImpl::RemovePeninputServerObserver
// Remove observer
// ---------------------------------------------------------------------------
//
void RPeninputServerImpl::RemovePeninputServerObserver(
MPeninputServerEventHandler* /*aHandler*/)
{
CCoeStatic * obj = CCoeEnv::Static()->FindStatic(KSingletonClientId);
if ( !obj )
{
return;
}
delete iObserver;
iObserver = NULL;
}
// ---------------------------------------------------------------------------
// RPeninputServerImpl::SetDisplayMode
// Set the display mode
// ---------------------------------------------------------------------------
//
void RPeninputServerImpl::SetDisplayMode(TDisplayMode aDisplayMode,
TDisplayMode aMaskDisplayMode)
{
TPckgC<TDisplayMode> msg(aDisplayMode);
TPckgC<TDisplayMode> msg2(aMaskDisplayMode);
TIpcArgs arg;
arg.Set(KMsgSlot0,&msg);
arg.Set(KMsgSlot1,&msg2);
SendReceive( EPeninputServerRequestSetDisplayMode, arg);
}
// ---------------------------------------------------------------------------
// RPeninputServerImpl::ClearServerEvent
// Set the display mode
// ---------------------------------------------------------------------------
//
void RPeninputServerImpl::ClearServerEvent()
{
if(iObserver->IsActive())
{
TInt data=0;
SendReceive(EPeninputServerClearServerEvent, TIpcArgs(data) );
}
}
// ---------------------------------------------------------------------------
// RPeninputServerImpl::AfterUiNotification
// Tell server Ui notification has been processed.
// ---------------------------------------------------------------------------
//
/*void RPeninputServerImpl::Continue()
{
iSingletonServer->SendReceive(EPeninputRequestUiNotificationCompleted);
}
*/
// ---------------------------------------------------------------------------
// RPeninputServerImpl::SetDisplayMode
// To disable specified layouts at a time.
// ---------------------------------------------------------------------------
//
void RPeninputServerImpl::SetDisabledLayout( TInt aLayouts )
{
TIpcArgs arg;
arg.Set(KMsgSlot0,aLayouts);
SendReceive( EPeninputRequestDisableLayout, arg );
}
// ---------------------------------------------------------------------------
// RPeninputServerImpl::SetDisplayMode
// To disable specified layouts at a time.
// ---------------------------------------------------------------------------
//
TInt RPeninputServerImpl::DisabledLayout()
{
TInt layouts = 0;
TIpcArgs arg;
TPckg<TInt> msg(layouts);
arg.Set(KMsgSlot0,&msg);
SendReceive( EPeninputRequestGetDisableLayout, arg );
return layouts;
}
// ---------------------------------------------------------------------------
// RPeninputServerImpl::GetImePluginIdListL
// Get IME plugin list for a language
// ---------------------------------------------------------------------------
//
void RPeninputServerImpl::GetImePluginIdListL(TInt aLanguage,
TInt aPluginMode,
RArray<TInt>& aImplmentationIds)
{
TInt size = sizeof(TInt) * (KMaxImeImplementations + 1);
HBufC8* buf = HBufC8::NewLC(size);
TPtr8 bufPtr = buf->Des();
TIpcArgs args;
args.Set(KMsgSlot0, aLanguage);
args.Set(KMsgSlot1, aPluginMode);
args.Set(KMsgSlot2, size);
args.Set(KMsgSlot3, &bufPtr);
aImplmentationIds.Reset();
TInt err = SendReceive(EPenInputRequestGetImePluginIdList,args);
if( err == KErrNone )
{
ReadIntArrayFromBufL(*buf, aImplmentationIds);
}
CleanupStack::PopAndDestroy(buf);
}
// ---------------------------------------------------------------------------
// RPeninputServerImpl::PenSupportLanguagesL
// Get pen supported langauge
// ---------------------------------------------------------------------------
//
void RPeninputServerImpl::PenSupportLanguagesL(RArray<TInt>& aLanguageLists)
{
TInt size = sizeof(TInt) * (KMaxSupportLanguages + 1);
HBufC8* buf = HBufC8::NewLC(size);
TPtr8 bufPtr = buf->Des();
TIpcArgs args;
args.Set(KMsgSlot0, size);
args.Set(KMsgSlot1, &bufPtr);
aLanguageLists.Reset();
TInt err = SendReceive(EPenInputRequestGetPenSupportLanguages,args);
if( err == KErrNone )
{
TRAP(err, ReadIntArrayFromBufL(*buf, aLanguageLists));
}
CleanupStack::PopAndDestroy(buf);
}
// ---------------------------------------------------------------------------
// RPeninputServerImpl::ReadIntArrayFromBufL
// Read buffer
// ---------------------------------------------------------------------------
//
void RPeninputServerImpl::ReadIntArrayFromBufL(const TDesC8& aBuf, RArray<TInt>& aResult)
{
CleanupClosePushL( aResult );
RDesReadStream readStream;
readStream.Open(aBuf);
CleanupClosePushL(readStream);
const TInt entryCount = readStream.ReadInt32L();
for(TInt i = 0; i < entryCount; ++i)
{
aResult.AppendL(readStream.ReadInt32L());
}
CleanupStack::PopAndDestroy(&readStream);
CleanupStack::Pop( &aResult );
}
// ---------------------------------------------------------------------------
// RPeninputServerImpl::SetForeground
// Set current session to be foreground application session
// ---------------------------------------------------------------------------
//
TBool RPeninputServerImpl::SetForeground(TBool aMustConnectFlag)
{
// if(iIsForegroundSession)
// return ETrue;
TInt curAppId;
TRAP_IGNORE( curAppId = GetAppUidByWndGroupIdL(CCoeEnv::Static()->WsSession(),
CCoeEnv::Static()->RootWin().Identifier()).iUid);
TIpcArgs arg;
TPckgC<TInt> idData(curAppId);
arg.Set(KMsgSlot0,&idData);
TPckgC<TBool> flagMsg(aMustConnectFlag);
arg.Set(KMsgSlot1,&flagMsg);
TPckg<TInt> retMsg(iIsForegroundSession);
arg.Set(KMsgSlot2,&retMsg);
SendReceive(EPeninputRequestSetForeground,arg);
return iIsForegroundSession;
}
// ---------------------------------------------------------------------------
// RPeninputServerImpl::LoseForeground
// Indicates current client lost foreground
// ---------------------------------------------------------------------------
//
void RPeninputServerImpl::LoseForeground()
{
iIsForegroundSession = EFalse;
SendReceive(EPeninputRequestRelinquishForeground);
}
// ---------------------------------------------------------------------------
// RPeninputServerImpl::IsForeground
// Test whether this session is the forground application session
// ---------------------------------------------------------------------------
//
TBool RPeninputServerImpl::IsForeground()
{
TBool bIsForeground;
TIpcArgs arg;
TPckg<TBool> msg(bIsForeground);
arg.Set(KMsgSlot0,&msg);
SendReceive(EPeninputRequestIsForeground,arg);
//__ASSERT_DEBUG(bIsForeground == iIsForegroundSession,User::Leave(-1));
return bIsForeground;
}
/*void RPeninputServerImpl::DoAddPenUiActivationHandler()
{
TPckgC<TInt> msg(iPenUiNotificationHandler->RegisteredType());
TIpcArgs arg;
arg.Set(KMsgSlot0,&msg);
iSingletonServer->SendReceive(EPeninputRequestAddUiObserver,arg);
}
*/
void RPeninputServerImpl::OnServerReady( TBool aFlag)
{
//iLaunchServer = EFalse;
iWaitScheduler->Stop(aFlag);//AsyncStop();
//if(iPenUiNotificationHandler)
// DoAddPenUiActivationHandler();
}
// ---------------------------------------------------------------------------
// RPeninputServerImpl::AddPenUiActivationHandler
// Add an UI activate/deactivation handler
// ---------------------------------------------------------------------------
//
TInt RPeninputServerImpl::AddPenUiActivationHandler(
MPenUiActivationHandler* aHandler,TInt aType)
{
iPenUiNotificationHandler.Append(TUiNotificationHandler(aHandler,aType));
return KErrNone;
}
// ---------------------------------------------------------------------------
// RPeninputServerImpl::RemovePenUiActivationHandler
// Remove all UI activate/deactivation handler
// ---------------------------------------------------------------------------
//
void RPeninputServerImpl::RemovePenUiActivationHandler()
{
CCoeStatic * obj = CCoeEnv::Static()->FindStatic(KSingletonClientId);
if ( !obj )
{
return;
}
iPenUiNotificationHandler.Reset();
}
// ---------------------------------------------------------------------------
// RPeninputServerImpl::RemovePenUiActivationHandler
// Remove an UI activate/deactivation handler
// Deprecated API
// ---------------------------------------------------------------------------
//
void RPeninputServerImpl::RemovePenUiActivationHandler(MPenUiActivationHandler
*aHandler)
{
CCoeStatic * obj = CCoeEnv::Static()->FindStatic(KSingletonClientId);
if ( !obj )
{
return;
}
for(TInt i = iPenUiNotificationHandler.Count() - 1; i >= 0 ; --i)
{
if(aHandler == iPenUiNotificationHandler[i].iHandler)
{
iPenUiNotificationHandler.Remove(i);
}
}
}
// ---------------------------------------------------------------------------
// RPeninputServerImpl::UpdateAppInfo
// Update current application information
// ---------------------------------------------------------------------------
//
void RPeninputServerImpl::UpdateAppInfo(const TDesC& aInfo, TPeninputAppInfo aType)
{
TPckgC<TPeninputAppInfo> typeMsg(aType);
TIpcArgs arg;
arg.Set(KMsgSlot0,&typeMsg);
arg.Set(KMsgSlot1,&aInfo);
SendReceive(EPeninputRequestUpdateAppInfo,arg);
}
void RPeninputServerImpl::HandleServerExit()
{
iServerExit = ETrue;
}
TBool RPeninputServerImpl::IsForegroundSession()
{
return iIsForegroundSession;
}
void RPeninputServerImpl::FinalClose()
{
delete iBackgroundCtrl;
delete iWaitScheduler;
iWaitScheduler = 0;
iPenUiNotificationHandler.Close();
delete iObserver;
iObserver = NULL;
if ( iWaiterAo )
{
iWaiterAo->Cancel();
delete iWaiterAo;
iWaiterAo = NULL;
}
RSessionBase::Close();
}
// ---------------------------------------------------------------------------
// RPeninputServerImpl::SetAutoOpen
// Enable/disable the auto-open feature
// ---------------------------------------------------------------------------
//
void RPeninputServerImpl::SetAutoOpen(TBool aFlag)
{
iAutoOpenFlag = aFlag;
}
// ---------------------------------------------------------------------------
// RPeninputServerImpl::AutoOpen
// get the the auto-open feature flag
// ---------------------------------------------------------------------------
//
TBool RPeninputServerImpl::AutoOpen()
{
return iAutoOpenFlag;
}
// ---------------------------------------------------------------------------
// RPeninputServerImpl::SetPrefferredUiMode
// Set the app preferred pen ui mode.
// ---------------------------------------------------------------------------
//
void RPeninputServerImpl::SetPreferredUiMode(TPluginInputMode aMode)
{
iAppPrefferedUiMode = aMode;
}
// ---------------------------------------------------------------------------
// RPeninputServerImpl::PrefferredUiMode
// Get the app preferred pen ui mode.
// ---------------------------------------------------------------------------
//
TPluginInputMode RPeninputServerImpl::PreferredUiMode()
{
return iAppPrefferedUiMode;
}
void RPeninputServerImpl::SetGlobalNotes(TBool aFlag)
{
iGlobalNotes = aFlag;
}
void RPeninputServerImpl::SetInternalPopUp(TBool aFlag)
{
iInternalPopup = aFlag;
}
void RPeninputServerImpl::SetEditorPriority(TInt aFlag)
{
iPriority = aFlag;
}
void RPeninputServerImpl::ClearTouchUI()
{
if(iBackgroundCtrl)
{
iBackgroundCtrl->Hide();
iBackgroundCtrl->MakeVisible(EFalse);
}
}
void RPeninputServerImpl::SetResourceChange(TBool aFlag)
{
iResourceChange = aFlag;
TBool bChange = aFlag;
TIpcArgs arg;
TPckg<TBool> msg(bChange);
arg.Set(KMsgSlot0,&msg);
SendReceive(EPeninputRequestDimResChangeLayout,arg);
}
//end of class RPeninputServerImpl
// Class CPeninputServerObserver
CPeninputServerObserver* CPeninputServerObserver::NewL(
RPeninputServerImpl* aServer,
TThreadId aSrvThreadId)
{
CPeninputServerObserver* self = new(ELeave) CPeninputServerObserver(aServer,
aSrvThreadId);
CleanupStack::PushL(self);
self->ConstructL();
CleanupStack::Pop();
return self;
}
// ---------------------------------------------------------------------------
// CPeninputServerObserver::CPeninputServerObserver
// Constructor. Adds the active object to the active scheduler
// and issues a request for server notification.
// ---------------------------------------------------------------------------
//
CPeninputServerObserver::CPeninputServerObserver(
RPeninputServerImpl* aPeninputServer,
TThreadId aSrvThreadId)
:CActive( EPriorityHigh ),
iPeninputServer( aPeninputServer ),
iSrvThreadId(aSrvThreadId),
iServerExit(EFalse)
{
__ASSERT_ALWAYS( !IsActive(), User::Panic( KPeninputServerName,
KErrObserverAlreadyActive ) );
//__ASSERT_DEBUG(aHandler, User::Panic( KPeninputServerName,
// KErrObserverNoHandler ));
AddEventHandler(this); //set own as the dummy handler
/*if(aPrevObserver)
{
iHandler = aPrevObserver->iHandler;
iUiActivationHandler = aPrevObserver->iUiActivationHandler;
}*/
// issue asynchronous request and set this object active
CActiveScheduler::Add( this );
}
void CPeninputServerObserver::ConstructL()
{
if(iPeninputServer->Handle() > 0) //valid one
iPeninputServer->RequestMessageNotification(iStatus);
SetActive();
}
void CPeninputServerObserver::ReConstructL(TThreadId aId)
{
iSrvThreadId = aId;
if(IsActive())
{
Cancel();
}
ConstructL();
}
// ---------------------------------------------------------------------------
// CPeninputServerObserver::~CPeninputServerObserver
// Destructor. Cancels any outstanding requests
// ---------------------------------------------------------------------------
//
CPeninputServerObserver::~CPeninputServerObserver()
{
Cancel();
}
// ---------------------------------------------------------------------------
// CPeninputServerObserver::DoCancel
// Cancels the notification requests
// ---------------------------------------------------------------------------
//
void CPeninputServerObserver::DoCancel()
{
if(!iServerExit)
iPeninputServer->CancelMessageNotification();
}
// ---------------------------------------------------------------------------
// CPeninputServerObserver::RunL
// ---------------------------------------------------------------------------
//
void CPeninputServerObserver::RunL()
{
//iHandler is always there. No need to check it
TInt ret = EFalse;
if(iStatus.Int() < 0)
{
//check server status
RThread srvThread;
TInt err = srvThread.Open(iSrvThreadId);
TInt exitReason = 0;
if(err == KErrNone) //thread is just closed
{
exitReason = srvThread.ExitReason();
srvThread.Close();
iPeninputServer->OnServerReady(-1000);
}
if(err != KErrNone || exitReason != 0) //server has exited
{
iServerExit = ETrue;
iPeninputServer->HandleServerExit();
iHandler->HandleServerEventL(ESignalServerExit);
return;
}
}
if(iStatus.Int() == ESignalServerReady) //server has started
{
iPeninputServer->OnServerReady();
return;
}
//if there is also iUiActivationHandler, handle it first
if(iUiActivationHandler)
ret = iUiActivationHandler->HandleServerEventL(iStatus.Int());
if(!ret)
ret = iHandler->HandleServerEventL(iStatus.Int());
// re-issue request if request
if(ret)
{
iPeninputServer->RequestMessageNotification(iStatus);
SetActive();
}
}
// ---------------------------------------------------------------------------
// CPeninputServerObserver::RunError
// ---------------------------------------------------------------------------
//
TInt CPeninputServerObserver::RunError(TInt /*aError*/)
{
// re-issue request
iPeninputServer->RequestMessageNotification(iStatus);
SetActive();
return KErrNone;
}
void CPeninputServerObserver::AddEventHandler(MPeninputServerEventHandler* aHandler)
{
// if(iHandler)
// return;
iHandler = aHandler;
}
void CPeninputServerObserver::AddUiActivationHandler(MPeninputServerEventHandler* aHandler)
{
iUiActivationHandler = aHandler;
}
TBool CPeninputServerObserver::HandleServerEventL(TInt /*aEventId*/)
{
//consume all events
return ETrue;
}
TUiNotificationHandler::TUiNotificationHandler(
MPenUiActivationHandler* aHandler,TInt aType)
:iHandler(aHandler),iType(aType)
{
}
//class CPenInputSingletonClient
CPenInputSingletonClient::CPenInputSingletonClient(const TUid& aUid,
RPeninputServerImpl* aServer)
: CCoeStatic(aUid,EApp),
iServer(aServer),iReferrence(1),iIsValid(ETrue)
{
}
RPeninputServerImpl* CPenInputSingletonClient::GetSingletonServer()
{
RPeninputServerImpl* ret = 0;
if(iIsValid && iServer->Handle())
{
++iReferrence;
ret = iServer;
}
return ret;
}
TInt CPenInputSingletonClient::DecreaseRef()
{
--iReferrence;
if( 0 == iReferrence && iIsValid)
{
iServer->FinalClose();
delete iServer;
iServer = 0;
iIsValid = EFalse;
}
return iReferrence;
}
TBool CPenInputSingletonClient::IsValid()
{
return iIsValid;
}
void CPenInputSingletonClient::SetInvalid()
{
iIsValid = EFalse;
}
void CPenInputSingletonClient::ReplaceServer(RPeninputServerImpl* aServer)
{
iServer = aServer;
iIsValid = ETrue;
iReferrence = 1;
}
CPenInputSingletonClient::~CPenInputSingletonClient()
{
if ( iServer )
{
iServer->FinalClose();
delete iServer;
}
}
//for class background wnd
TBool IsGlobalNotesApp(TUid& aUid)
{
const TInt KAknCapServerUid = 0x10207218;
const TInt KAknNotifySrvUid = 0x10281EF2;
if(aUid.iUid == KAknCapServerUid || aUid.iUid == KAknNotifySrvUid)
return ETrue;
return EFalse;
}
CPenUiBackgroundWnd* CPenUiBackgroundWnd::NewL(RWindowGroup& aWndGroup,TInt aBmpHandle)
{
CPenUiBackgroundWnd* self = new(ELeave) CPenUiBackgroundWnd(aWndGroup);
CleanupStack::PushL(self);
self->ConstructL(aBmpHandle);
CleanupStack::Pop(self);
return self;
}
CPenUiBackgroundWnd::CPenUiBackgroundWnd(RWindowGroup& aWndGroup)
:iWndGroup(aWndGroup)
{
}
CPenUiBackgroundWnd::~CPenUiBackgroundWnd()
{
delete iBitmap;
// if (iBitmapCpoy)
{
// delete iBitmapCpoy;
// iBitmapCpoy = NULL;
}
}
void CPenUiBackgroundWnd::CreateBitmapL(TInt aBmpHandle)
{
iBitmap = new (ELeave) CFbsBitmap;
TInt ret = iBitmap->Duplicate(aBmpHandle);
if(KErrNone != ret)
{
delete iBitmap;
iBitmap = NULL;
}
}
void CPenUiBackgroundWnd::ConstructL(TInt aBmpHandle)
{
CreateWindowL(iWndGroup);
SetComponentsToInheritVisibility();
Window().SetRequiredDisplayMode( EColor16MA );
MakeVisible( EFalse );
CreateBitmapL(aBmpHandle);
TBool b = IsNonFocusing();
SetFocusing(EFalse);
}
void CPenUiBackgroundWnd::Show(const TRect& aExtend, TBool aGlobalNotes,
TBool aInternal, TInt aPriority, TBool aResource)
{
//Show the window will cause a focus group change in global notes showing case.
if (!iBitmap)
{
return;
}
TUid curApp = GetCurAppUid();
TUid focusApp = GetFocusAppUid();
//dim effect due to global notes will not done by background control
if(!aInternal || aGlobalNotes)
return;
// if (iBitmapCpoy)
{
// delete iBitmapCpoy;
// iBitmapCpoy = NULL;
}
SetRect(aExtend);
TRAP_IGNORE(ActivateL());
MakeVisible(ETrue);
if (!aResource)
{
RWsSession &ws = CCoeEnv::Static()->WsSession();
TInt wgId =ws.GetFocusWindowGroup();
TInt priority = ws.GetWindowGroupOrdinalPriority(wgId);
iWndGroup.SetOrdinalPosition( 0, aPriority);
Window().SetOrdinalPosition(0,aPriority);
// The code runs well on 5.0 platform, but on tb92,
// it will make the backgourd screen black purely.
//Window().SetFaded(ETrue,RWindowTreeNode::EFadeWindowOnly);
}
else
{
Window().SetFaded(ETrue,RWindowTreeNode::EFadeWindowOnly);
}
Window().Invalidate();
DrawNow();
}
void CPenUiBackgroundWnd::Draw(const TRect& aRect) const
{
CWindowGc& gc = SystemGc();
// if (iBitmapCpoy)
// gc.BitBlt(aRect.iTl,iBitmapCpoy,aRect);
if (iBitmap)
gc.BitBlt(aRect.iTl,iBitmap,aRect);
}
void CPenUiBackgroundWnd::Hide()
{
MakeVisible( EFalse );
}
void RPeninputServerImpl::OnServerStarted(TInt aErr)
{
if(KErrNone == aErr)
{
iServerReady = ETrue;
//create session
aErr = CreateSession( KPeninputServerName,
Version(),
KDefaultMessageSlots,EIpcSession_Sharable);
if(KErrNone == aErr)
{
AddObserver();
}
}
User::RequestComplete(iPendingRequest, aErr);
}
CWaitingServerAo::CWaitingServerAo(RPeninputServerImpl* aClient)
: CActive(CActive::EPriorityStandard),
iClient(aClient)
{
CActiveScheduler::Add(this);
SetActive();
iStatus = KRequestPending;
}
void CWaitingServerAo::RunL()
{
TInt err = ESignalServerReady == iStatus.Int() ? KErrNone : KErrGeneral;
iClient->OnServerStarted(err);
}
void CWaitingServerAo::DoCancel()
{
}
TInt CWaitingServerAo::RunError(TInt /*aError*/)
{
return KErrNone;
}
TRequestStatus& CWaitingServerAo::RequestStatus()
{
return iStatus;
}
// End of File