Applied patch 1, to provide a syborg specific minigui oby file.
Need to compare this with the "stripped" version currently in the tree.
This supplied version applies for Nokia builds, but need to repeat the
test for SF builds to see if pruning is needed, or if the file needs to
be device-specific.
// Copyright (c) 1995-2009 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:
//
#include "server.h"
#include "WSGRAPHICDRAWERFACTORY.H"
#include "panics.h"
#include <s32mem.h>
#include "wstop.h"
TInt CWsGraphicDrawerObject::TransientSequence=1;
TBool CWsGraphicDrawerObject::RollOver=EFalse;
CWsGraphicDrawerObject* CWsGraphicDrawerObject::NewL(CWsClient* aClient,const TWsClCmdUnion &aParams)
{
if(!aClient)
{
WS_PANIC_DEBUG(EWsPanicWsGraphic);
User::Leave(KErrGeneral);
}
TGraphicDrawerId id;
id.iId = aParams.CreateGraphic->iId;
id.iIsUid = !(EWsGraphicIdTransient & aParams.CreateGraphic->iFlags);
// check for collision
const CWsGraphicDrawer* dup = aClient->WindowServer().ResolveGraphic(id);
// request-specific checks
if(dup)
{
// must be exact same session
if(&(dup->Owner()) != aClient)
{
/* Someone is squatting on someone else's uid, or trying to,
but there is no good way to know which. */
__DEBUG_ONLY(aClient->PPanic(EWservPanicPermissionDenied);)
User::Leave(KErrAlreadyExists);
}
// dupping or otherwise must be explicitly intended by the client
if(!(EWsGraphicReplace & aParams.CreateGraphic->iFlags))
{
aClient->PPanic(EWservPanicPermissionDenied);
}
}
else
{
// dupping or otherwise must be explicitly intended by the client
if(EWsGraphicReplace & aParams.CreateGraphic->iFlags)
{
aClient->PPanic(EWservPanicPermissionDenied);
}
if(id.iIsUid)
{
// police creation of artwork with UIDs
_LIT_SECURITY_POLICY_C1(KSecurityPolicyCreateWithUid,ECapabilityProtServ);
if(!KSecurityPolicyCreateWithUid.CheckPolicy(aClient->Client()))
{
__DEBUG_ONLY(aClient->PPanic(EWservPanicPermissionDenied);)
User::Leave(KErrPermissionDenied);
}
}
else
{
// allocate a new transient id
// assumption: that there are more values of a TInt than there are possibly Transient objects
do
{
id.iId = TransientSequence++;
RollOver |= !TransientSequence;
}
while(RollOver && aClient->WindowServer().ResolveGraphic(id)); // until no collision
}
}
// create the drawer object
TPtrC8 data;
HBufC8* dataBuf = NULL;
if(aParams.CreateGraphic->iRemoteReadData)
{
const TInt len = aParams.CreateGraphic->iDataLen;
if ((len >= KMaxTInt/4) || (len < 0))
aClient->PPanic(EWservPanicBuffer);
dataBuf = HBufC8::NewLC(len);
TPtr8 des = dataBuf->Des();
aClient->RemoteRead(des,0);
if(des.Size() != len)
{
aClient->PPanic(EWservPanicBuffer);
}
data.Set(des);
}
else
{
data.Set(CWsClient::BufferTPtr8((TText8*)(aParams.CreateGraphic+1),aParams.CreateGraphic->iDataLen));
}
CWsGraphicDrawerObject* drawer = new(ELeave) CWsGraphicDrawerObject(aClient);
CleanupStack::PushL(drawer);
drawer->ConstructL(aParams.CreateGraphic->iType,aClient->WindowServer(),id,data,aParams.CreateGraphic->iClientHandle);
if(!dup)
{
User::LeaveIfError(aClient->WindowServer().AddGraphicDrawer(drawer->Drawer()));
}
else
{
User::LeaveIfError(aClient->WindowServer().SwapGraphicDrawer(drawer->Drawer()));
}
// take off cleanup stack
CleanupStack::Pop(drawer);
if(dataBuf)
{
CleanupStack::PopAndDestroy(dataBuf);
}
// delete dup, which means resolving the object that encapsulates it
if(dup)
{
CWsGraphicDrawerObject* obj = aClient->DrawerObject(dup);
WS_ASSERT_DEBUG(obj, EWsPanicWsGraphic);
if(obj)
{
obj->CloseObject();
}
}
// trigger redraws if anyone is drawing this graphic before it exists
if(id.iIsUid)
{
aClient->WindowServer().Invalidate(id);
}
// done
return drawer;
}
CWsGraphicDrawerObject::CWsGraphicDrawerObject(CWsClient* aOwner):
CWsObject(aOwner,WS_HANDLE_GRAPHIC_DRAWER)
{
}
CWsGraphicDrawerObject::~CWsGraphicDrawerObject()
{
delete iDrawer;
}
void CWsGraphicDrawerObject::ConstructL(TUid aType,MWsGraphicDrawerEnvironment& aEnv,const TGraphicDrawerId& aId,const TDesC8& aData,TInt aClientHandle)
{
CWsGraphicDrawer* drawer = WsGraphicDrawer::CreateLC(aType,aEnv,aId,*WsOwner(),aData);
NewObjL();
iClientHandle = aClientHandle;
iDrawer=drawer;
CleanupStack::Pop(iDrawer);
}
void CWsGraphicDrawerObject::CommandL(TInt aOpcode, const TAny *aCmdData)
{
WS_ASSERT_DEBUG(iDrawer, EWsPanicWsGraphic);
if(iDrawer)
{
TWsClCmdUnion pData;
pData.any = aCmdData;
switch(aOpcode)
{
case EWsGdOpFree:
WsOwner()->WindowServer().RemoveGraphicDrawer(iDrawer->Id());
CloseObject();
return;
case EWsGdOpSendMsg:
case EWsGdOpSendSynchronMsg:
{
const TWsClCmdGdSendMessage& cmd = *pData.GraphicSendMessage;
__ASSERT_DEBUG(cmd.iDataLen,WsOwner()->PPanic(EWservPanicPermissionDenied));
if(cmd.iDataLen)
{
if(cmd.iRemoteReadData)
{
HBufC8* wsAlloc = NULL;
TUint8* drawerAlloc = NULL;
TPtr8 des(NULL,0);
// try to get the drawer to allocate for us
MWsGraphicDrawerMessageAlloc* drawerAllocator = iDrawer->ObjectInterface<MWsGraphicDrawerMessageAlloc>();
if(drawerAllocator)
{
drawerAlloc = reinterpret_cast<TUint8*>(drawerAllocator->Alloc(cmd.iDataLen));
if(drawerAlloc)
des.Set(drawerAlloc,0,cmd.iDataLen);
}
// else use the normal WSERV default heap
if(!drawerAlloc)
{
wsAlloc = HBufC8::NewLC(cmd.iDataLen);
des.Set(wsAlloc->Des());
}
// fetch
WsOwner()->RemoteRead(des,0);
TBool receivedOk = (des.Size() == cmd.iDataLen);
// dispatch
if(receivedOk)
{
if(aOpcode == EWsGdOpSendMsg)
{
iDrawer->HandleMessage(des);
}
else
{
MWsGraphicHandleSynchronMessage* obj = iDrawer->ObjectInterface<MWsGraphicHandleSynchronMessage>();
if(obj)
SetReply(obj->HandleSynchronMessage(des));
else
SetReply(KErrNotSupported);
}
}
// dealloc
if(drawerAlloc)
{
drawerAllocator->Free(drawerAlloc);
}
else
{
CleanupStack::PopAndDestroy(wsAlloc);
}
// defer panic until after dealloc
if(!receivedOk)
{
WsOwner()->PPanic(EWservPanicBuffer);
}
}
else
{
const TPtrC8 data = CWsClient::BufferTPtr8((TText8*)(pData.GraphicSendMessage+1),cmd.iDataLen);
if(aOpcode == EWsGdOpSendMsg)
{
iDrawer->HandleMessage(data);
}
else
{
MWsGraphicHandleSynchronMessage* obj = iDrawer->ObjectInterface<MWsGraphicHandleSynchronMessage>();
if(obj)
SetReply(obj->HandleSynchronMessage(data));
else
SetReply(KErrNotSupported);
}
}
}
}
break;
case EWsGdOpGetGraphicId:
{
__ASSERT_COMPILE(sizeof(TWsClCmdGdGetId) == sizeof(TGraphicDrawerId));
const TGraphicDrawerId id = iDrawer->Id();
CWsClient::ReplyBuf(&id,sizeof(id));
}
break;
case EWsGdOpShareGlobally:
SetReply(iDrawer->ShareGlobally());
break;
case EWsGdOpUnShareGlobally:
SetReply(iDrawer->UnShareGlobally());
break;
case EWsGdOpShare:
{
const TSecureId& secid = *reinterpret_cast<const TSecureId*>(aCmdData);
SetReply(iDrawer->Share(secid));
break;
}
case EWsGdOpUnShare:
{
const TSecureId& secid = *reinterpret_cast<const TSecureId*>(aCmdData);
SetReply(iDrawer->UnShare(secid));
break;
}
default:
WsOwner()->PPanic(EWservPanicOpcode);
}
}
}
CWsGraphicDrawer* CWsGraphicDrawerObject::Drawer()
{
return iDrawer;
}
const CWsGraphicDrawer* CWsGraphicDrawerObject::Drawer() const
{
return iDrawer;
}
// CWsGraphicMessageQueue \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
CWsGraphicMessageQueue::CMessage* CWsGraphicMessageQueue::CMessage::New(const TDesC8& aData)
{
return new(aData.Size()) CMessage(aData);
}
CWsGraphicMessageQueue::CMessage::CMessage(const TDesC8& aData):
iData((reinterpret_cast<TUint8*>(this)+sizeof(*this)),aData.Size())
{
iData = aData;
}
TPtrC8 CWsGraphicMessageQueue::CMessage::Data() const
{
return iData;
}
void CWsGraphicMessageQueue::CMessage::Release()
{
delete this;
}
CWsGraphicMessageQueue::CMessage::~CMessage()
{
}
CWsGraphicMessageQueue::CWsGraphicMessageQueue(CWsClient *aOwner):
CEventBase(aOwner)
{
}
CWsGraphicMessageQueue::~CWsGraphicMessageQueue()
{
while(iHead)
{
CWsMessageData* msg = iHead;
iHead = iHead->iNext;
msg->Release();
}
}
TInt CWsGraphicMessageQueue::TopClientHandle() const
{
if(iHead)
return iHead->iClientHandle;
else
return KErrNotFound;
}
/**
same functionality as CEventBase::GetData, but this one also inserts the integer header in the reply.
*/
void CWsGraphicMessageQueue::GetDataWithHeader(TUint aHeader, const TDesC8& aData, TInt aDataLen)
{
TPckgBuf<TUint> hdr = aHeader | (EWsGraphMessageTypeUser & 0x03);
CWsClient::ReplyBuf(hdr.Ptr(), sizeof(TUint));
GetData((void*)aData.Ptr(), aDataLen);
}
void CWsGraphicMessageQueue::GetGraphicMessage()
{
CWsMessageData* top = Pop();
WS_ASSERT_DEBUG(top && top->Data().Length(), EWsPanicWsGraphic);
if(top)
{
GetDataWithHeader(top->iClientHandle, top->Data(), top->Data().Size());
CWsGraphicDrawerObject* obj = iWsOwner->DrawerObject(top->iDrawer);
if(obj)
{
MWsGraphicMessageCallback* messageCallback = obj->Drawer()->ObjectInterface<MWsGraphicMessageCallback>();
if(messageCallback)
{
messageCallback->HandleMessageDelivery(top->iId, KErrNone);
}
}
top->Release();
}
}
void CWsGraphicMessageQueue::AbortMessage(TInt aError)
{
CWsMessageData* top = Pop();
WS_ASSERT_DEBUG(top, EWsPanicWsGraphic);
if(top)
{
CWsGraphicDrawerObject* obj = iWsOwner->DrawerObject(top->iDrawer);
if(obj)
{
MWsGraphicMessageCallback* messageCallback = obj->Drawer()->ObjectInterface<MWsGraphicMessageCallback>();
if(messageCallback)
{
messageCallback->HandleMessageDelivery(top->iId, aError);
}
}
top->Release();
}
}
void CWsGraphicMessageQueue::EventReady(const RMessagePtr2& aEventMsg)
{
CEventBase::EventReady(aEventMsg);
if(iHead)
{
SignalEvent(sizeof(TInt) + iHead->Data().Size());
}
}
void CWsGraphicMessageQueue::Queue(CWsMessageData* aMessage)
{
WS_ASSERT_DEBUG(aMessage && !aMessage->iNext, EWsPanicWsGraphic);
if(aMessage)
{
if(iHead)
{
iTail->iNext = aMessage;
iTail = aMessage;
}
else
{
iHead = iTail = aMessage;
if(!iEventMsg.IsNull())
SignalEvent(sizeof(TInt) + iHead->Data().Size());
}
}
}
CWsMessageData* CWsGraphicMessageQueue::Pop()
{
CWsMessageData* ret = NULL;
if(iHead)
{
ret = iHead;
iHead = iHead->iNext;
}
return ret;
}