diff -r 000000000000 -r f63038272f30 bluetoothengine/bthid/mouse/Sesame_client/src/clientimagecommander.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/bluetoothengine/bthid/mouse/Sesame_client/src/clientimagecommander.cpp Mon Jan 18 20:28:57 2010 +0200 @@ -0,0 +1,483 @@ +/* +* Copyright (c) 2004 - 2006 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of "Eclipse Public License v1.0" +* which accompanies this distribution, and is available +* at the URL "http://www.eclipse.org/legal/epl-v10.html". +* +* Initial Contributors: +* Nokia Corporation - initial contribution. +* +* Contributors: +* +* Description: +* +*/ + + +// INCLUDE FILES + + +#include +#include +#include +#include +#include +#include +#include +#include +#include "clientimagecommander.h" + +#ifndef DBG +#ifdef _DEBUG +#define DBG(a) a +#else +#define DBG(a) +#endif +#endif + +_LIT( KBTMOUSEMBMFileName, "\\resource\\apps\\BTMouseBitMaps.mbm" ); + + +// ============================ MEMBER FUNCTIONS =============================== + +// ----------------------------------------------------------------------------- +// RImageCommander::RImageCommander() +// Create a new animation object. +// ----------------------------------------------------------------------------- +// +EXPORT_C RImageCommander::RImageCommander( RAnimDll &aAnimDll, RWsSession& aWsSession ) : + RAnim( aAnimDll ), iSession(aWsSession), + iBaseBitmap(NULL), + iBaseMaskBitmap(NULL), + iMouseButtonPressed(EFalse), + iWakeUpCalculator(0) + { + DBG(RDebug::Print(_L("RImageCommander::RImageCommander"))); + + // No implementation required + } + +EXPORT_C RImageCommander::~RImageCommander( ) + { + iSprite.Close(); + + if ( iPointBufferQueue ) + { + delete iPointBufferQueue; + iPointBufferQueue = NULL; + } + + if ( iBaseBitmap) + { + delete iBaseBitmap; + iBaseBitmap = NULL; + } + + if ( iBaseMaskBitmap ) + { + delete iBaseMaskBitmap; + iBaseMaskBitmap = NULL; + } + RAnim::Close(); + } + +// ----------------------------------------------------------------------------- +// RImageCommander::ImageConstruct() +// Construct a new animation object. +// ----------------------------------------------------------------------------- +// +EXPORT_C void RImageCommander::ImageConstructL( RWindowGroup& aWindowGroup, TSize aSize ) + { + // Send the parameters to the animation server object construction + + DBG(RDebug::Print(_L("RImageCommander::ImageConstructL IN"))); + + iPointBufferQueue = NULL; + iPointBufferQueue = CPointQueue::NewL(this,KMsgBTMouseBufferQueue); + + CreateSpriteL(aSize, aWindowGroup); + + DBG(RDebug::Print(_L("RImageCommander::ImageConstructL Construct Anim"))); + + TPtrC8 des(NULL,0); + RAnim::Construct( iSprite, 0, des ); + + DBG(RDebug::Print(_L("RImageCommander::ImageConstructL OUT"))); + } + +// ---------------------------------------------------------------------------- +// RImageCommander::CreateSpriteL(TSize aSize, RWindowGroup& aGroup) +// ---------------------------------------------------------------------------- +// +void RImageCommander::CreateSpriteL(TSize aSize, RWindowGroup& aGroup) + { + DBG(RDebug::Print(_L("RImageCommander::CreateSpriteL START"))); + TSpriteMember member; + + + DBG(RDebug::Print(_L("RImageCommander::CreateSpriteL size %d,%d"), aSize.iWidth, aSize.iHeight)); + (void)aSize; + + iSprite=RWsSprite(iSession); + TInt error = iSprite.Construct(aGroup, TPoint(),ESpriteNoChildClip|ESpriteNoShadows); + User::LeaveIfError(error); + iBaseBitmap = new (ELeave) CFbsBitmap; + // Drive Letter: + TFileName file(CEikonEnv::Static()->EikAppUi()->Application()->AppFullName().Left(2)); + // Path and file name: + file.Append( KBTMOUSEMBMFileName ); // always safe + + User::LeaveIfError(iBaseBitmap->Load(file, EMbmBtmousebitmapsCursor)); + iBaseMaskBitmap = new (ELeave) CFbsBitmap; + User::LeaveIfError(iBaseMaskBitmap->Load(file, EMbmBtmousebitmapsCursormask)); + FillInSpriteMember(member, iBaseBitmap, iBaseMaskBitmap); + User::LeaveIfError(iSprite.AppendMember(member)); + + DBG(RDebug::Print(_L("RImageCommander::CreateSpriteL END"))); + + } + +// ---------------------------------------------------------------------------- +// RImageCommander::FillInSpriteMember(TSpriteMember& aMember, CFbsBitmap* icon, CFbsBitmap* iconMask) +// ---------------------------------------------------------------------------- +// +void RImageCommander::FillInSpriteMember(TSpriteMember& aMember, CFbsBitmap* icon, CFbsBitmap* iconMask) + { + DBG(RDebug::Print(_L("RImageCommander::FillInSpriteMember")); + + if ( ( icon == NULL) || ( iconMask == NULL) ) + { + RDebug::Print(_L("RImageCommander::FillInSpriteMember no icons !")); + } + ) + aMember.iBitmap=icon; + aMember.iMaskBitmap=iconMask; + aMember.iInvertMask=EFalse; + aMember.iDrawMode = CGraphicsContext::EDrawModeWriteAlpha; + aMember.iOffset=TPoint(0,0); + + DBG(RDebug::Print(_L("RImageCommander::FillInSpriteMember END"))); + + } + +// ----------------------------------------------------------------------------- +// RImageCommander::ImageCommand() +// Send a command (aCommand) to the animation server object. +// Because there is no way to return an error from the server side using this +// method, it is important that any server side code for these commands should +// not be able to fail or leave. If the operation can fail, then the method +// TInt CommandReply(TInt aOpcode) should be used instead +// ----------------------------------------------------------------------------- +// +EXPORT_C void RImageCommander::ImageCommand( TInt aCommand ) + { + // Could optionally decode the commands here + DBG(RDebug::Print(_L("RImageCommander::ImageCommand %d"), aCommand)); + + RAnim::Command( aCommand ); + + DBG(RDebug::Print(_L("RImageCommander::ImageCommand OUT"))); + + } + +TRawEvent::TType RImageCommander::PointerEventToRawEvent(TPointerEvent::TType aEventType) + { + TRawEvent::TType aType; + switch(aEventType) + { + case TPointerEvent::EButton1Down: + { + aType=TRawEvent::EButton1Down; + break; + } + case TPointerEvent::EButton1Up: + { + aType=TRawEvent::EButton1Up; + break; + } + case TPointerEvent::EMove: + { + aType=TRawEvent::EPointerMove; + break; + } + case TPointerEvent::ESwitchOn: + { + aType=TRawEvent::EPointerSwitchOn; + break; + } + default: + { + aType=TRawEvent::ENone; + break; + } + } + return aType; + } + +TInt RImageCommander::SendPointerEvent(TPointerEvent::TType aEventType) + { + DBG(RDebug::Print(_L("RImageCommander::SendPointerEvent"))); + + TRawEvent rawEvent; + TPoint point(iCurrentPoint); + TRawEvent::TType type = PointerEventToRawEvent(aEventType); + rawEvent.Set(type, point.iX, point.iY, 30); + typedef TPckgBuf< TRawEvent > TRawEventDataPckg; + TRawEventDataPckg rawEventPckg(rawEvent); + RAnim::Command( KSendRawEvent, rawEventPckg ); + return KErrNone; + } + + +TBool RImageCommander::RestrictPos() + { + TBool notInScreen(EFalse); + TPixelsAndRotation sizeAndRotation; + sizeAndRotation.iPixelSize.SetSize(360,640); // Just a guess + CWsScreenDevice* screen(CEikonEnv::Static()->ScreenDevice()); + if (screen) + { + TInt mode(screen->CurrentScreenMode()); + screen->GetScreenModeSizeAndRotation(mode, sizeAndRotation); + } + TRect validRect(sizeAndRotation.iPixelSize); + if (! validRect.Contains(iCurrentPoint)) + { + notInScreen = ETrue; + if (iCurrentPoint.iX<0) + iCurrentPoint.iX=0; + else if (iCurrentPoint.iX>=validRect.iBr.iX) + iCurrentPoint.iX=validRect.iBr.iX-1; + + if (iCurrentPoint.iY<0) + iCurrentPoint.iY=0; + else if (iCurrentPoint.iY>=validRect.iBr.iY) + iCurrentPoint.iY=validRect.iBr.iY-1; + } + return notInScreen; + } + +inline TBool RImageCommander::CheckCurrentPoint() + { + DBG(TPoint pos(iCurrentPoint)); + + TBool outSide(RestrictPos()); + + DBG( + if (outSide) + { + RDebug::Print(_L("RImageCommander::CheckCurrentPoint not in screen (%d,%d)"), pos.iX, pos.iY); + } + ) + return outSide; + } + +TInt RImageCommander::SendWakeUp() + { + TRawEvent rawEvent; + rawEvent.Set(TRawEvent::ESwitchOn); + return UserSvr::AddEvent(rawEvent); + } + +void RImageCommander::HandlePointL(const TPoint& aPoint) + { + DBG(RDebug::Print(_L("RImageCommander::HandlePointL pos (%d,%d)"), + aPoint.iX, aPoint.iY)); + + if ( ( aPoint.iX != 0) || ( aPoint.iY != 0) ) + { + iCurrentPoint += aPoint; + TBool notInScreen(CheckCurrentPoint()); + if (iMouseButtonPressed) + { + // Dragging possible now: + if (notInScreen) + { + SendPointerEvent(TPointerEvent::EButton1Up); + iMouseButtonPressed = EFalse; + } + else + { + SendPointerEvent(TPointerEvent::EMove); + } + } + else + { + typedef TPckgBuf< TPoint > TPointDataPckg; + TPointDataPckg pointPckg(iCurrentPoint); + RAnim::Command( KChangeCursor, pointPckg ); + } + } + iWakeUpCalculator++; + if (iWakeUpCalculator > KWakeUpNeeded) + { + SendWakeUp(); + iWakeUpCalculator = 0; + } + } + +void RImageCommander::SendEventL(TPointerEvent::TType aEventType) + { + DBG(RDebug::Print(_L("RImageCommander::SendEventL (%d)"), aEventType)); + + if (aEventType == TPointerEvent::EButton1Down) + { + iMouseButtonPressed = ETrue; + SendWakeUp(); + } + else if (aEventType == TPointerEvent::EButton1Up) + { + iMouseButtonPressed = EFalse; + } + SendPointerEvent(aEventType); + } + +// ======== class CPointQueue======== +// +// --------------------------------------------------------------------------- +// CPointQueue::CPointQueue +// Constructor. Adds the active object to the active scheduler +// and issues a request for server notification. +// --------------------------------------------------------------------------- +// + +CPointQueue::CPointQueue(MPointHandler* aHandler):CActive( EPriorityHigh ), + iHandler(aHandler) + { + // issue asynchronous request and set this object active + DBG(RDebug::Print(_L("(CCPointQueue::CPointQueue"))); + + CActiveScheduler::Add( this ); + + DBG( RDebug::Print(_L("(CCPointQueue::CPointQueue Out"))); + + } + +// --------------------------------------------------------------------------- +// CPointQueue::NewL +// factory constructor. +// --------------------------------------------------------------------------- +// +CPointQueue* CPointQueue::NewL(MPointHandler* aHandler,const TDesC& aName) + { + DBG(RDebug::Print(_L("(CCPointQueue::NewL"))); + + CPointQueue* queue = new(ELeave)CPointQueue(aHandler); + CleanupStack::PushL(queue); + queue->ConstructL(aName); + CleanupStack::Pop(queue); + // Start receiving: + queue->GetPoint(); + + DBG(RDebug::Print(_L("(CCPointQueue::NewL Out"))); + + return queue; + } + +// --------------------------------------------------------------------------- +// CPointQueue::ConstructL +// 2nd phase constructor +// --------------------------------------------------------------------------- +// +void CPointQueue::ConstructL(const TDesC& aName) + { + (void) aName; + //Open message queue + TInt err = iPointBufQueue.OpenGlobal(KMsgBTMouseBufferQueue); + if (err == KErrNotFound) + { + User::LeaveIfError(iPointBufQueue.CreateGlobal(KMsgBTMouseBufferQueue, KPointQueueLen)); + } + else + { + User::LeaveIfError( err ); + } + } +// --------------------------------------------------------------------------- +// CPointQueue::CPointQueue +// Destructor. Cancels any outstanding requests +// --------------------------------------------------------------------------- +// +CPointQueue::~CPointQueue() + { + Cancel(); + iPointBufQueue.Close(); + } + +// --------------------------------------------------------------------------- +// CPointQueue::DoCancel +// Cancels the notification requests +// --------------------------------------------------------------------------- +// +void CPointQueue::DoCancel() + { + iPointBufQueue.CancelDataAvailable(); + } + +// --------------------------------------------------------------------------- +// CPointQueue::RunL +// --------------------------------------------------------------------------- +// +void CPointQueue::RunL() + { + DBG(RDebug::Print(_L("CCPointQueue::RunL"))); + + TInt ret; + //iHandler is always there. No need to check it + TPointBuffer points; + ret = iPointBufQueue.Receive(points); + DBG(RDebug::Print(_L("CCPointQueue::RunL , ret = %d, points %d"), ret, points.iNum)); + + if (ret == KErrNone) + { + TPoint pos(0,0); + for(TInt ii = 0; ii < points.iNum; ii++) + { + pos += points.iPoint[ii]; + if ( ( points.iType[ii] == KBufferPenDown ) || + ( points.iType[ii] == KBufferPenUp ) ) + { + iHandler->SendEventL( ( points.iType[ii] == KBufferPenDown ) ? + TPointerEvent::EButton1Down : + TPointerEvent::EButton1Up ); + iHandler->HandlePointL(pos); + pos.SetXY(0,0); + } + } + iHandler->HandlePointL(pos); + } + // re-issue request + GetPoint(); + } + +// --------------------------------------------------------------------------- +// CPointQueue::RunError +// --------------------------------------------------------------------------- +// +TInt CPointQueue::RunError(TInt /*aError*/) + { + DBG(RDebug::Print(_L("CCPointQueue::RunError"))); + // re-issue request + GetPoint(); + return KErrNone; + } + +// --------------------------------------------------------------------------- +// CPointQueue::GetPoint +// Reissue request for point +// --------------------------------------------------------------------------- +// +void CPointQueue::GetPoint() + { + DBG(RDebug::Print(_L("CCPointQueue::GetPoint"))); + + if(!IsActive()) + { + iPointBufQueue.NotifyDataAvailable(iStatus); + SetActive(); + } + DBG(RDebug::Print(_L("CCPointQueue::GetPoint Out"))); + } +// End of File