diff -r 000000000000 -r eb1f2e154e89 fep/frontendprocessor/test/feps/tfep2be.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/fep/frontendprocessor/test/feps/tfep2be.cpp Tue Feb 02 01:02:04 2010 +0200 @@ -0,0 +1,560 @@ +// Copyright (c) 2005-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: +// + +/** + @file + @internalComponent +*/ + +#include +#include +#include +#include +#include +#include +#include +#include + +#include "tfep2be.h" +#include "tfep2com.h" + +#define DEBUGGING_MESSAGES + +// numeric constants + +const TInt KPanicClientFromServer=1; // must be greater than zero (CTstHandWritingRecognizer::OfferRawEvent assumes this to be true) + +// literal constant text + +#if defined(_DEBUG) +_LIT(KLitTFEP2BE, "TFEP2BE"); +#endif + +// local and global functions + +#if defined(_DEBUG) + +enum TPanic + { + EPanicUnexpectedError=1, + EPanicBadDataInDllTls, + EPanicUnexpectedRawEvent, + EPanicTimerActive1, + EPanicTimerActive2, + EPanicNoPendingCharactersToMove, + EPanicUnexpectedNullPointer1, + EPanicUnexpectedNullPointer2, + EPanicBadGranularity, + EPanicAlreadyConstructed, + EPanicNonAlignedDescriptorLength1, + EPanicNonAlignedDescriptorLength2, + EPanicNonAlignedDescriptorMaximumLength, + EPanicBadDescriptorLength, + EPanicBadNumberOfCharacters1, + EPanicBadNumberOfCharacters2 + }; + +LOCAL_C void Panic(TPanic aPanic) + { + User::Panic(KLitTFEP2BE, aPanic); + } + +#endif + +LOCAL_C void PanicClientFromServer() + { + User::Leave(KPanicClientFromServer); + } + +LOCAL_C void HandleErrorIfErrorL(MAnimGeneralFunctions& aFunctions, TInt aError) + { + switch (aError) + { + case KErrNone: + break; + case KPanicClientFromServer: + aFunctions.Panic(); + break; + default: + User::Leave(aError); + break; + } + } + +LOCAL_C void HandleErrorIfError(MAnimGeneralFunctions& aFunctions, TInt aError) + { + switch (aError) + { + case KErrNone: + break; + case KPanicClientFromServer: + aFunctions.Panic(); + break; + default: +#if defined(_DEBUG) + Panic(EPanicUnexpectedError); +#endif + break; + } + } + +GLDEF_C TInt E32Dll( + ) + { + return KErrNone; + } + +// CTstHandWritingRecognizer + +CTstHandWritingRecognizer::CTstHandWritingRecognizer() + :iFlags(0), + iArrayOfPolyLines(12), + iArrayOfCharactersPending(10), + iTimeOutTimer(NULL), + iMessage_RequestForNotificationOfStartOfTransaction(), + iMessage_RequestForCharacters(), + iMaximumLengthOfClientSideCharacterBuffer(0), + iMainBitmap(NULL), + iMaskBitmap(NULL), + iGraphicsContext(NULL) + { + } + +CTstHandWritingRecognizer::~CTstHandWritingRecognizer() + { + iFunctions->GetRawEvents(EFalse); + iSpriteFunctions->Activate(EFalse); + if (iFlags&EFlagReferenceCountIncremented) + { + SBitmapHandlesWithReferenceCount* const bitmapHandlesWithReferenceCount=STATIC_CAST(SBitmapHandlesWithReferenceCount*, Dll::Tls()); + __ASSERT_DEBUG((bitmapHandlesWithReferenceCount!=NULL) && (bitmapHandlesWithReferenceCount->iReferenceCount>0), Panic(EPanicBadDataInDllTls)); + --bitmapHandlesWithReferenceCount->iReferenceCount; + if (bitmapHandlesWithReferenceCount->iReferenceCount==0) + { + delete bitmapHandlesWithReferenceCount; + Dll::SetTls(NULL); + } + } + iArrayOfPolyLines.ResetAndDestroy(); + iArrayOfPolyLines.Close(); + iArrayOfCharactersPending.Close(); + delete iTimeOutTimer; + delete iGraphicsContext; + delete iMainBitmap; + delete iMaskBitmap; + } + +void CTstHandWritingRecognizer::HandleTimeOut() + { + TRAPD(error, DoRecognitionL()); + CompleteRequestForCharacters(error); + } + +void CTstHandWritingRecognizer::ConstructLP(TAny* /*aParameters*/) + { + // this functions does not actually construct anything, but simply writes the bitmap handles stored in Dll::Tls() (if any) to the client's descriptor + STstBitmapHandles bitmapHandles(0, 0); + const SBitmapHandlesWithReferenceCount* const bitmapHandlesWithReferenceCount=REINTERPRET_CAST(const SBitmapHandlesWithReferenceCount*, Dll::Tls()); + if (bitmapHandlesWithReferenceCount!=NULL) + { + bitmapHandles=bitmapHandlesWithReferenceCount->iBitmapHandles; + } + iFunctions->Message()->WriteL(EIpcSlot, TPckgC(bitmapHandles)); + } + +TInt CTstHandWritingRecognizer::CommandReplyLP(TInt aOpcode, TAny* aParameters) + { + switch (aOpcode) + { + case EHandWritingRecognizerCommandFinishConstructionL: + { + __ASSERT_ALWAYS(iFlags==0, PanicClientFromServer()); + iFunctions->SetSync(MAnimGeneralFunctions::ESyncNone); + iSpriteFunctions->SizeChangedL(); + iArrayOfCharactersPending.ConstructL(); + iTimeOutTimer=CTimeOutTimer::NewL(*this); + const TSpriteMember* const spriteMember=iSpriteFunctions->GetSpriteMember(0); + __ASSERT_ALWAYS((spriteMember!=NULL) && (spriteMember->iBitmap!=NULL) && (spriteMember->iMaskBitmap!=NULL), PanicClientFromServer()); + const STstBitmapHandles bitmapHandles(spriteMember->iBitmap->Handle(), spriteMember->iMaskBitmap->Handle()); + SBitmapHandlesWithReferenceCount* bitmapHandlesWithReferenceCount=STATIC_CAST(SBitmapHandlesWithReferenceCount*, Dll::Tls()); + if (bitmapHandlesWithReferenceCount!=NULL) + { + __ASSERT_ALWAYS((bitmapHandlesWithReferenceCount->iBitmapHandles.iMain==bitmapHandles.iMain) && (bitmapHandlesWithReferenceCount->iBitmapHandles.iMask==bitmapHandles.iMask), PanicClientFromServer()); + ++bitmapHandlesWithReferenceCount->iReferenceCount; + } + else + { + bitmapHandlesWithReferenceCount=new(ELeave) SBitmapHandlesWithReferenceCount; + CleanupStack::PushL(bitmapHandlesWithReferenceCount); + bitmapHandlesWithReferenceCount->iBitmapHandles=bitmapHandles; + bitmapHandlesWithReferenceCount->iReferenceCount=1; + User::LeaveIfError(Dll::SetTls(bitmapHandlesWithReferenceCount)); + CleanupStack::Pop(); // bitmapHandlesWithReferenceCount + } + iFlags|=EFlagReferenceCountIncremented; +#if defined(DEBUGGING_MESSAGES) + RDebug::Print(_L("reference-count of the bitmap handles: %d"), bitmapHandlesWithReferenceCount->iReferenceCount); +#endif + iMainBitmap=CFbsBitmapDevice::NewL(spriteMember->iBitmap); + iMaskBitmap=CFbsBitmapDevice::NewL(spriteMember->iMaskBitmap); + iGraphicsContext=CFbsBitGc::NewL(); + iGraphicsContext->SetBrushStyle(CGraphicsContext::ESolidBrush); + iGraphicsContext->SetBrushColor(KRgbWhite); + iGraphicsContext->SetPenStyle(CGraphicsContext::ESolidPen); + iGraphicsContext->SetPenColor(KRgbBlack); + } + break; + case EHandWritingRecognizerCommandRequestNotificationOfStartOfTransaction: + __ASSERT_ALWAYS(iMessage_RequestForNotificationOfStartOfTransaction.IsNull(), PanicClientFromServer()); + iMessage_RequestForNotificationOfStartOfTransaction=*iFunctions->Message(); + __ASSERT_ALWAYS(!iMessage_RequestForNotificationOfStartOfTransaction.IsNull(), PanicClientFromServer()); + break; + case EHandWritingRecognizerCommandCancelRequestForNotificationOfStartOfTransaction: + if (!iMessage_RequestForNotificationOfStartOfTransaction.IsNull()) + { + iMessage_RequestForNotificationOfStartOfTransaction.Complete(KErrCancel); + } + break; + case EHandWritingRecognizerCommandRequestCharacters: + __ASSERT_ALWAYS(iMessage_RequestForCharacters.IsNull() && (iMaximumLengthOfClientSideCharacterBuffer==0), PanicClientFromServer()); + iMessage_RequestForCharacters=*iFunctions->Message(); + iMaximumLengthOfClientSideCharacterBuffer=iFunctions->Message()->GetDesMaxLength(EAsyncIpcSlot); + __ASSERT_ALWAYS((!iMessage_RequestForCharacters.IsNull()) && (iMaximumLengthOfClientSideCharacterBuffer>=STATIC_CAST(TInt, sizeof(TUint))), PanicClientFromServer()); + if (iArrayOfCharactersPending.Count()>0) + { + TRAPD(error, MovePendingCharactersToClientBufferL()); + CompleteRequestForCharacters(error); + } + else + { + iFunctions->GetRawEvents(ETrue); + iSpriteFunctions->Activate(ETrue); + } + break; + case EHandWritingRecognizerCommandCancelRequestForCharacters: + if (!iMessage_RequestForCharacters.IsNull()) + { + CompleteRequestForCharacters(KErrCancel); + } + break; + case EHandWritingRecognizerCommandSetUpperCase: + { + STstParametersForHandWritingRecognizerCommandSetUpperCase* const parameters=REINTERPRET_CAST(STstParametersForHandWritingRecognizerCommandSetUpperCase*, aParameters); + if (parameters->iUpperCase) + { + iFlags|=EFlagUpperCase; + } + else + { + iFlags&=~EFlagUpperCase; + } + } + break; + default: + PanicClientFromServer(); + break; + } + return KErrNone; // dummy return to prevent compiler error + } + +TBool CTstHandWritingRecognizer::OfferRawEventLP(const TRawEvent& aRawEvent) + { + __ASSERT_DEBUG(!iMessage_RequestForCharacters.IsNull(), Panic(EPanicUnexpectedRawEvent)); + switch (aRawEvent.Type()) + { + case TRawEvent::EPointerMove: + { + if (iFlags&EFlagPointerIsDown) // this test is needed in the cases where (i) the TRawEvent::EPointerMove event occurs when the pointer is not "down" (this is possible for some pointing devices, e.g. a mouse), and (ii) there was a "leave" when handling the TRawEvent::EButton1Down event + { + __ASSERT_DEBUG(!iTimeOutTimer->IsActive(), Panic(EPanicTimerActive1)); + const TPoint thisPoint=aRawEvent.Pos(); + CArrayFix& polyLine=*iArrayOfPolyLines[iArrayOfPolyLines.Count()-1]; + polyLine.AppendL(thisPoint); + const TPoint previousPoint=polyLine[polyLine.Count()-2]; + TRect rectangleDrawnTo; + DrawLine(*iMainBitmap, rectangleDrawnTo, EPenWidthForMainBitmap, previousPoint, thisPoint); + TRect temp; + DrawLine(*iMaskBitmap, temp, EPenWidthForMaskBitmap, previousPoint, thisPoint); + rectangleDrawnTo.BoundingRect(temp); + Plot(*iMainBitmap, temp, EPenWidthForMainBitmap, thisPoint); + rectangleDrawnTo.BoundingRect(temp); + Plot(*iMaskBitmap, temp, EPenWidthForMaskBitmap, thisPoint); + rectangleDrawnTo.BoundingRect(temp); + iSpriteFunctions->UpdateMember(0, rectangleDrawnTo, EFalse); + } + } + return ETrue; + case TRawEvent::EButton1Down: + { + iTimeOutTimer->Cancel(); + const TPoint thisPoint=aRawEvent.Pos(); + CArrayFix* const polyLine=new(ELeave) CArrayFixSeg(50); + CleanupStack::PushL(polyLine); + polyLine->AppendL(thisPoint); + User::LeaveIfError(iArrayOfPolyLines.Append(polyLine)); + CleanupStack::Pop(); // polyLine + TRect rectangleDrawnTo; + Plot(*iMainBitmap, rectangleDrawnTo, EPenWidthForMainBitmap, thisPoint); + TRect temp; + Plot(*iMaskBitmap, temp, EPenWidthForMaskBitmap, thisPoint); + rectangleDrawnTo.BoundingRect(temp); + iSpriteFunctions->UpdateMember(0, rectangleDrawnTo, EFalse); + iFlags|=EFlagPointerIsDown; + if ((iArrayOfPolyLines.Count()==1) && (!iMessage_RequestForNotificationOfStartOfTransaction.IsNull())) + { + iMessage_RequestForNotificationOfStartOfTransaction.Complete(KErrNone); + } + } + return ETrue; + case TRawEvent::EButton1Up: + if (iFlags&EFlagPointerIsDown) // this test is needed in the case where there was a "leave" when handling the TRawEvent::EButton1Down event + { + __ASSERT_DEBUG(!iTimeOutTimer->IsActive(), Panic(EPanicTimerActive2)); + iTimeOutTimer->After(ETimeOutInMicroSeconds); + iFlags&=~EFlagPointerIsDown; + } + return ETrue; + default: + return EFalse; + } + } + +void CTstHandWritingRecognizer::DoRecognitionL() + { + TInt i; + TInt minimumX=KMaxTInt; + TInt maximumX=KMinTInt; + for (i=iArrayOfPolyLines.Count()-1; i>=0; --i) + { + const CArrayFix& polyLine=*iArrayOfPolyLines[i]; + for (TInt j=polyLine.Count()-1; j>=0; --j) + { + const TInt x=polyLine[j].iX; + if (minimumX>x) + { + minimumX=x; + } + if (maximumX0, Panic(EPanicNoPendingCharactersToMove)); + __ASSERT_DEBUG((!iMessage_RequestForCharacters.IsNull()) && (iMaximumLengthOfClientSideCharacterBuffer>=STATIC_CAST(TInt, sizeof(TUint))), Panic(EPanicUnexpectedNullPointer1)); + const TInt numberOfCharactersToMove=Min(iArrayOfCharactersPending.Count(), iMaximumLengthOfClientSideCharacterBuffer/sizeof(TUint)); + iMessage_RequestForCharacters.WriteL(EAsyncIpcSlot, iArrayOfCharactersPending.DescriptorFromStart(numberOfCharactersToMove), 0); + iArrayOfCharactersPending.RemoveFromStart(numberOfCharactersToMove); + } + +void CTstHandWritingRecognizer::CompleteRequestForCharacters(TInt aErrorCode) + { + __ASSERT_DEBUG((!iMessage_RequestForCharacters.IsNull()) && (iMaximumLengthOfClientSideCharacterBuffer>=STATIC_CAST(TInt, sizeof(TUint))), Panic(EPanicUnexpectedNullPointer2)); + iArrayOfPolyLines.ResetAndDestroy(); + iArrayOfCharactersPending.Reset(); + iTimeOutTimer->Cancel(); + iMessage_RequestForCharacters.Complete(aErrorCode); + iMaximumLengthOfClientSideCharacterBuffer=NULL; + iFunctions->GetRawEvents(EFalse); + iSpriteFunctions->Activate(EFalse); + ClearBitmap(*iMainBitmap); + ClearBitmap(*iMaskBitmap); + // there is no need to call iSpriteFunctions->UpdateMember as the sprite has just been de-activated (3 lines above) + } + +void CTstHandWritingRecognizer::ClearBitmap(CFbsBitmapDevice& aBitmap) + { + iGraphicsContext->Activate(&aBitmap); + iGraphicsContext->Clear(); + } + +void CTstHandWritingRecognizer::DrawLine(CFbsBitmapDevice& aBitmap, TRect& aRectangleDrawnTo, TInt aPenSize, const TPoint& aPoint1, const TPoint& aPoint2) + { + iGraphicsContext->Activate(&aBitmap); + iGraphicsContext->SetPenSize(TSize(aPenSize, aPenSize)); + iGraphicsContext->DrawLine(aPoint1, aPoint2); + iGraphicsContext->RectDrawnTo(aRectangleDrawnTo); + } + +void CTstHandWritingRecognizer::Plot(CFbsBitmapDevice& aBitmap, TRect& aRectangleDrawnTo, TInt aPenSize, const TPoint& aPoint) + { + iGraphicsContext->Activate(&aBitmap); + iGraphicsContext->SetPenSize(TSize(aPenSize, aPenSize)); + iGraphicsContext->Plot(aPoint); + iGraphicsContext->RectDrawnTo(aRectangleDrawnTo); + } + +void CTstHandWritingRecognizer::ConstructL(TAny* aParameters) + { + TRAPD(error, ConstructLP(aParameters)); + HandleErrorIfErrorL(*iFunctions, error); + } + +TInt CTstHandWritingRecognizer::CommandReplyL(TInt aOpcode, TAny* aParameters) + { + TInt returnVal=0; // dummy initialization to prevent compiler warning + TRAPD(error, returnVal=CommandReplyLP(aOpcode, aParameters)); + HandleErrorIfErrorL(*iFunctions, error); + return returnVal; + } + +void CTstHandWritingRecognizer::Command(TInt, TAny*) + { + iFunctions->Panic(); + } + +void CTstHandWritingRecognizer::Animate(TDateTime*) + { + } + +TBool CTstHandWritingRecognizer::OfferRawEvent(const TRawEvent& aRawEvent) + { + TBool returnVal=0; // dummy initialization to prevent compiler warning + TRAPD(error, returnVal=OfferRawEventLP(aRawEvent)); + if (error>=0) // if error is a KErrXxxxx, ignore it (as OfferRawEvent cannot leave) + { + HandleErrorIfError(*iFunctions, error); + } + return returnVal; + } + +// CTstHandWritingRecognizer::RFlatArrayOfCharacters + +CTstHandWritingRecognizer::RFlatArrayOfCharacters::RFlatArrayOfCharacters(TInt aGranularity) + :iGranularity(aGranularity), + iDescriptor(NULL) + { + __ASSERT_DEBUG(aGranularity>0, Panic(EPanicBadGranularity)); + } + +void CTstHandWritingRecognizer::RFlatArrayOfCharacters::ConstructL() + { + __ASSERT_DEBUG(iDescriptor==NULL, Panic(EPanicAlreadyConstructed)); + iDescriptor=HBufC8::NewL(iGranularity*sizeof(TUint)); + } + +void CTstHandWritingRecognizer::RFlatArrayOfCharacters::Close() + { + delete iDescriptor; + iDescriptor=NULL; + } + +void CTstHandWritingRecognizer::RFlatArrayOfCharacters::AppendL(TUint aCharacter) + { + const TInt oldDescriptorLength=iDescriptor->Length(); + __ASSERT_DEBUG(oldDescriptorLength%sizeof(TUint)==0, Panic(EPanicNonAlignedDescriptorLength1)); + const TInt oldDescriptorMaximumLength=iDescriptor->Des().MaxLength(); + __ASSERT_DEBUG(oldDescriptorMaximumLength%sizeof(TUint)==0, Panic(EPanicNonAlignedDescriptorMaximumLength)); + if (oldDescriptorLength>=oldDescriptorMaximumLength) + { + iDescriptor=iDescriptor->ReAllocL(oldDescriptorLength+(iGranularity*sizeof(TUint))); + } + TPtr8 descriptor(iDescriptor->Des()); + __ASSERT_DEBUG(oldDescriptorLength==descriptor.Length(), Panic(EPanicBadDescriptorLength)); + descriptor.SetLength(oldDescriptorLength+sizeof(TUint)); + *REINTERPRET_CAST(TUint*, CONST_CAST(TUint8*, descriptor.Ptr()+oldDescriptorLength))=aCharacter; + } + +TInt CTstHandWritingRecognizer::RFlatArrayOfCharacters::Count() const + { + const TInt descriptorLength=iDescriptor->Length(); + __ASSERT_DEBUG(descriptorLength%sizeof(TUint)==0, Panic(EPanicNonAlignedDescriptorLength2)); + return descriptorLength/sizeof(TUint); + } + +TPtrC8 CTstHandWritingRecognizer::RFlatArrayOfCharacters::DescriptorFromStart(TInt aNumberOfCharacters) const + { + __ASSERT_DEBUG((aNumberOfCharacters>0) && (aNumberOfCharacters<=Count()), Panic(EPanicBadNumberOfCharacters1)); + return iDescriptor->Left(aNumberOfCharacters*sizeof(TUint)); + } + +void CTstHandWritingRecognizer::RFlatArrayOfCharacters::RemoveFromStart(TInt aNumberOfCharacters) + { + __ASSERT_DEBUG((aNumberOfCharacters>0) && (aNumberOfCharacters<=Count()), Panic(EPanicBadNumberOfCharacters2)); + TPtr8 descriptor(iDescriptor->Des()); + descriptor.Delete(0, aNumberOfCharacters*sizeof(TUint)); + // we could "iDescriptor=iDescriptor->ReAllocL" here to free up unused memory, but it's probably not worth it as iDescriptor will never grow very large + } + +void CTstHandWritingRecognizer::RFlatArrayOfCharacters::Reset() + { + TPtr8 descriptor(iDescriptor->Des()); + descriptor.SetLength(0); + // we could "iDescriptor=iDescriptor->ReAllocL" here to free up unused memory, but it's probably not worth it as iDescriptor will never grow very large + } + +// CTstHandWritingRecognizer::CTimeOutTimer + +CTstHandWritingRecognizer::CTimeOutTimer* CTstHandWritingRecognizer::CTimeOutTimer::NewL(CTstHandWritingRecognizer& aHandWritingRecognizer) + { + CTimeOutTimer* const timeOutTimer=new(ELeave) CTimeOutTimer(aHandWritingRecognizer); + CleanupStack::PushL(timeOutTimer); + CActiveScheduler::Add(timeOutTimer); + timeOutTimer->ConstructL(); + CleanupStack::Pop(); // timeOutTimer + return timeOutTimer; + } + +CTstHandWritingRecognizer::CTimeOutTimer::~CTimeOutTimer() + { + Cancel(); + } + +CTstHandWritingRecognizer::CTimeOutTimer::CTimeOutTimer(CTstHandWritingRecognizer& aHandWritingRecognizer) + :CTimer(EPriorityLow), + iHandWritingRecognizer(aHandWritingRecognizer) + { + } + +void CTstHandWritingRecognizer::CTimeOutTimer::RunL() + { + iHandWritingRecognizer.HandleTimeOut(); + } + +// CTstDll + +CAnim* CTstDll::CreateInstanceL(TInt aType) + { + switch (aType) + { + case EAnimTypeHandWritingRecognizer: + return new(ELeave) CTstHandWritingRecognizer; + default: + User::Leave(KErrArgument); + return NULL; // dummy return to prevent compiler error + } + } + +// the exported function + +EXPORT_C CAnimDll* CreateCAnimDllL() + { + return new(ELeave) CTstDll; + } +