diff -r 000000000000 -r 15bf7259bb7c uiacceltk/hitchcock/ServerCore/Src/alfhierarchymodel.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/uiacceltk/hitchcock/ServerCore/Src/alfhierarchymodel.cpp Tue Feb 02 07:56:43 2010 +0200 @@ -0,0 +1,1184 @@ +/* +* Copyright (c) 2008 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 +#include +#include +#include +#include +#include +#include +#include + +#include "alfhierarchymodel.h" +#include "alfstreamerconsts.h" +#include "alfstreamerserver.h" +#include "alfwindowmanager.h" +#include "alfstreamerbridge.h" +#include "alfwindow.h" +#include "alflogger.h" +#ifdef ALF_DEBUG_TRACK_DRAWING +#include "alfcommanddebug.h" +#endif +#include "alfnodes.h" +#include "huiwscanvascommands.h" + +#include "mwsgraphicscontexttobitgdimappings.h" + +const TInt KChunkCommitBatchSize = 10000; +const TInt KChunkMaxSize = 500000; +const TInt KFrameOffsetTemplate = 12345678; + +// --------------------------------------------------------------------------- +// NewL +// --------------------------------------------------------------------------- +// +CAlfHierarchyModel* CAlfHierarchyModel::NewL(CAlfStreamerServer& aServer) + { + CAlfHierarchyModel* self = new(ELeave)CAlfHierarchyModel(aServer); + CleanupStack::PushL(self); + self->ConstructL(); + CleanupStack::Pop(self); + return self; + } + +// --------------------------------------------------------------------------- +// ConstructL +// --------------------------------------------------------------------------- +// +void CAlfHierarchyModel::ConstructL() + { + iWindowPos = TPoint(0, 0 ); + iSema.CreateLocal(); + if (iServer.Bridge()) + { + iServer.Bridge()->SetBatchObserver(this); + } +#ifdef ALF_DEBUG_TRACK_DRAWING + iCommandDebugger = CAlfCommandDebug::NewL(); +#endif + } + +// --------------------------------------------------------------------------- +// AppendScreenL +// --------------------------------------------------------------------------- +// +void CAlfHierarchyModel::AppendScreen( TInt aScreenNumber ) + { + __ALFLOGSTRING1("CAlfHierarchyModel::AppendScreenL( %d )", aScreenNumber ); + if ( aScreenNumber > 0 ) // first display comes with the package. only the following are created when requested + { + iServer.Bridge()->AddData( EAlfDSCreateNewDisplay, aScreenNumber, 0, NULL ); + } + } + +// --------------------------------------------------------------------------- +// RemoveScreenL +// --------------------------------------------------------------------------- +// +void CAlfHierarchyModel::RemoveScreen( TInt aScreenNumber ) + { + if ( aScreenNumber < 1 ) + { + // The main display cannot be removed. + return; + } + + __ALFLOGSTRING1("CAlfHierarchyModel::RemoveDisplayL( %d )", aScreenNumber ); + // NOTE & TODO: This works fine, if we are removing the last added display. If we happen to remove display in the middle, + // then referring to displays by their indeces would be a major problem + // TODO: Who destroyes the nodes on this display? wserv? + iServer.Bridge()->AddData( EAlfDSDestroyDisplay, aScreenNumber, 0, NULL ); + } + +// --------------------------------------------------------------------------- +// destructor +// --------------------------------------------------------------------------- +// +CAlfHierarchyModel::~CAlfHierarchyModel() + { + // we do not complete pending messages + iPendingAlfWindowDataMessages.Close(); + iNodeHashArray.Close(); + if (iServer.Bridge()) + { + iServer.Bridge()->SetBatchObserver(0); + } + delete iPeriodic; + iSema.Close(); + if(iStream) + { + iStream->Close(); + delete iStream; + iStream = NULL; + } + iChunk.Close(); +#ifdef ALF_DEBUG_TRACK_DRAWING + delete iCommandDebugger; +#endif + } + +// --------------------------------------------------------------------------- +// ReleaseSemaphor +// --------------------------------------------------------------------------- +// +void ReleaseSemaphor(TAny* aAlfHierarchyModel) + { + CAlfHierarchyModel* me = (CAlfHierarchyModel*)aAlfHierarchyModel; + me->DoReleaseSemaphor(); + } + +// --------------------------------------------------------------------------- +// DoReleaseSemaphor +// --------------------------------------------------------------------------- +// +void CAlfHierarchyModel::DoReleaseSemaphor() + { + iSema.Signal(); + } + +// --------------------------------------------------------------------------- +// RequestPacketEndCallback +// +// This is used to notify when certain offset in the chunk is freed. To avoid +// excessive notifications (and callbacks), skip some of the notifications. +// --------------------------------------------------------------------------- +// +void CAlfHierarchyModel::RequestPacketEndCallback( TInt aOffset ) + { + if ( aOffset > iPreviousCallbackOffset + KChunkCommitBatchSize || aOffset < iPreviousCallbackOffset ) + { + iPreviousCallbackOffset = aOffset; + iServer.Bridge()->RequestCommandReadNotification( aOffset ); + } + } + +// --------------------------------------------------------------------------- +// RequestFrameEndCallback +// --------------------------------------------------------------------------- +// +void CAlfHierarchyModel::RequestFrameEndCallback( ) + { + __ALFLOGSTRING( "CAlfHierarchyModel::RequestFrameEndCallback" ); + iServer.Bridge()->StartNewBlock(); + } +// --------------------------------------------------------------------------- +// HandleMessageL +// --------------------------------------------------------------------------- +// +void CAlfHierarchyModel::HandleMessageL( const RMessage2& aMessage ) + { + iSema.Wait(); + CleanupStack::PushL(TCleanupItem(ReleaseSemaphor, this)); + TBool doComplete= EFalse; + // __ALFLOGSTRING1( "CAlfHierarchyModel::HandleMessageL %d", aMessage.Function() ); + switch (aMessage.Function()) + { + case EAlfBridgerRequestDataBlock: + { + ShareChunkL( aMessage ); + return; + } + case EDsNotifyNativeWindowData: + { + User::Leave(KErrNotSupported); + return; + } + case EAlfBridgerAsyncronousData: + { + if ( iChunk.Handle() ) + { + ExecuteCommandsL(); + if ( iBatchAlreadyCommited ) + { + // This may happen, if alfstreamerbridge happens to process the commands (containing the EAlfCommitBatch) + // before this asyncronous request is received. + __ALFLOGSTRING("Batch already completed. Complete immediately"); + aMessage.Complete( EAlfBridgerAsyncronousData ); + iBatchAlreadyCommited = EFalse; + } + else + { + SetSynchMessage(&aMessage); + } + } + break; + } + case EAlfBridgerBlindSend: + { + ExecuteCommandsL(); + CleanupStack::PopAndDestroy(); // releases iSema + aMessage.Complete( EAlfBridgerBlindSend ); + return; + } + case EAlfBridgerSendChunk: + { + OpenChunkL( aMessage ); + aMessage.Complete( EAlfBridgerSendChunk ); + return; + } + default: + { + doComplete= ETrue; + __ALFLOGSTRING("CAlfHierarchyModel::HandleMessageL, default case reached."); + break; + } + } + if (doComplete && !aMessage.IsNull()) + { + aMessage.Complete(KErrNotSupported); + } + + CleanupStack::PopAndDestroy(); // releases iSema + } + +// --------------------------------------------------------------------------- +// ShareChunkL +// --------------------------------------------------------------------------- +// +void CAlfHierarchyModel::ShareChunkL( const RMessage2& aMessage ) + { + if ( !iChunk.Handle() ) + { + // For security reasons, alfserver owns the chunk. Because it is nameless, it cannot be accessed + // unless a handle to the chunk is given by alfserver + // + // TODO:CHECK what if somebody else wants to send EAlfBridgerRequestDataBlock. Currently we are giving the chunk + // to anybody who connects to the server. + iChunk.CreateDisconnectedGlobal( KNullDesC, 0, KChunkMaxSize, KChunkMaxSize ); //CreateDisconnectedGlobal + iChunkHeader = reinterpret_cast(iChunk.Base()); + memset( iChunkHeader, 0, sizeof( TChunkHeader ) ); + } + TInt screenNumber = aMessage.Int1(); + TPckg pkgLength( KChunkMaxSize ); + AppendScreen( screenNumber ); + aMessage.WriteL(0, pkgLength ); + aMessage.Complete( iChunk ); + if ( iStream ) + { + iStream->Close(); + } + else + { + iStream = new(ELeave)RMemReadStream; + } + iStream->Open( iChunk.Base() + sizeof( TChunkHeader), KChunkMaxSize ); + + CleanupStack::PopAndDestroy(); // releases iSema +} + +// --------------------------------------------------------------------------- +// ShareChunkL +// --------------------------------------------------------------------------- +// +void CAlfHierarchyModel::OpenChunkL( const RMessage2& aMessage ) + { + TInt size = aMessage.Int0(); + TInt32 handle = aMessage.Int1(); + TBool openForReading = aMessage.Int2(); + + iCacheChunks.Insert( handle, RChunk() ); + iCacheChunks.Find( handle )->SetHandle( aMessage.Int1() ); + iCacheChunks.Find( handle )->Open( aMessage, 1, EFalse, EOwnerProcess ); + + if ( openForReading ) + { + if (iStream) + { + iStream->Close(); + } + else + { + iStream = new(ELeave)RMemReadStream; + } + + TUint8* base = iCacheChunks.Find( handle )->Base(); + iStream->Open( base + sizeof( TChunkHeader), size ); + + __ALFLOGSTRING1("Chunk in use %d", iChunkInUse ); + iChunkInUse = handle; + iChunkHeader = reinterpret_cast(base); + } + CleanupStack::PopAndDestroy(); // releases iSema + +} + +// --------------------------------------------------------------------------- +// CloseChunkL +// --------------------------------------------------------------------------- +// +void CAlfHierarchyModel::CloseChunk( TInt32 aChunkHandle ) + { + __ALFLOGSTRING1("CAlfHierarchyModel::CloseChunkL: closing %d", aChunkHandle ); + RChunk* chunk = iCacheChunks.Find( aChunkHandle ); + iCacheChunks.Remove( aChunkHandle ); + if ( chunk ) + { + chunk->Close(); + } + else + { + __ALFLOGSTRING1( "CAlfHierarchyModel::CloseChunkL - Warning: chunk %d not found!", aChunkHandle ); + } + } + +// --------------------------------------------------------------------------- +// ReadEndMarkerL +// --------------------------------------------------------------------------- +// +void CAlfHierarchyModel::ReadEndMarkerL() + { + TUint8 marker = iStream->ReadInt8L(); + ASSERT( marker == EAlfCommandEndMarker ) ; // endmarker + } + +// --------------------------------------------------------------------------- +// ReadRectL +// --------------------------------------------------------------------------- +// +void CAlfHierarchyModel::ReadRectL( TRect& aRect, RMemReadStream* aStream ) + { + aStream->ReadL( (TUint8*)&(aRect.iTl.iX), sizeof( TRect) ); + } + +// --------------------------------------------------------------------------- +// ReadRegionL +// --------------------------------------------------------------------------- +// +void CAlfHierarchyModel::ReadRegionL( RMemReadStream* aStream, RRegion& aRegion, TPoint aWindowPos ) + { + aRegion.Clear(); + TRect rect; + TInt count = aStream->ReadInt32L(); + for (TInt i = 0 ; i < count ; i++ ) + { + ReadRectL( rect, aStream ); + rect.Move(-aWindowPos); + aRegion.AddRect( rect ); + } + } + + +// --------------------------------------------------------------------------- +// ExecuteCommandsL +// --------------------------------------------------------------------------- +// +void CAlfHierarchyModel::ExecuteCommandsL( ) + { + if ( !iStream ) + { + return; + } + TInt offset = iStream->Source()->TellL( MStreamBuf::ERead ).Offset(); + + +#ifdef _ALF_LOGGING + TInt commandCount(0); + TSgcCanvasCommands previousCommand; +#endif + TSgcCanvasCommands command = EAlfCommandNotInitialized; + TTime beginTime; + beginTime.HomeTime(); + + __ALFLOGSTRING1( "CAlfHierarchyModel::ExecuteCommandsL - Committed write offset: %d", iChunkHeader->iCommittedWriteOffset ); + while( iChunkHeader->iCommittedWriteOffset != offset ) + { +#ifdef _ALF_LOGGING + previousCommand = command; +#endif + TRAPD( err, + command = (TSgcCanvasCommands)iStream->ReadUint8L(); + iScreenNumber = iStream->ReadUint8L(); + ); + if ( err != KErrNone ) + { +#ifdef _ALF_LOGGING + __ALFLOGSTRING3("CAlfHierarchyModel::ExecuteCommandsL - Cmd: %d, Previous Cmd: %d, Count: %d..", command, previousCommand, commandCount ); +#endif + __ALFLOGSTRING2("..CAlfHierarchyModel::ExecuteCommandsL - Offset: %d, LEAVE WITH ERROR: %d", offset, err ); + } + +#ifdef ALF_DEBUG_TRACK_DRAWING + commandCount++; + iUsedCommands[command]++; + + iCommandDebugger->SetDescription( command ); + __ALFLOGSTRING3("CAlfHierarchyModel::ExecuteCommandsL (%d) %S offset: %d,", command, &iCommandDebugger->Text(), offset ); +#endif + switch ( command ) + { + case EAlfSetWindowId: + { + TUint32 nodeId = (TUint32)iStream->ReadUint32L(); + CAlfNodeVisual* node = (CAlfNodeVisual*)FindNode( nodeId ); + + if ( node ) + { +#ifdef ALF_DEBUG_TRACK_DRAWING + if (node->iId == iSearchNode || node->Tracking() ) + { + RDebug::Print( _L( "CAlfHierarchyModel::ExecuteCommandsL - Tracking")); + } +#endif +#ifdef ALF_DEBUG_PRINT_NODE_INFO + _LIT( KText, "Drawing"); + // node->PrintInfo(0, node, TPtrC(KText) , iSearchNode); +#endif + + node->DrawWindowFrameL( *iStream ); + } + else + { + ProcessUnknownNodeDrawingL( *iStream ); + } + break; + } + case EAlfNodeCreated: + { + DoNodeCreatedL(); + break; + } + case EAlfNodeReleased: + { + DoNodeReleasedL(); + break; + } + case EAlfNodeActivated: + { + DoNodeActivatedL(); + break; + } + case EAlfNodeExtentChanged: + { + DoNodeExtentChangedL(); + break; + } + case EAlfNodeSiblingOrderChanged: + { + DoNodeSiblingOrderChangedL(); + break; + } + case EAlfNodeFlagChanged: + { + DoNodeFlagChangedL(); + break; + } + case EAlfNodeFadeCountChanged: + { + DoNodeFadeCountChangedL(); + break; + } + case EAlfNodeFadeAllChildren: + { + DoNodeFadeAllChildrenL(); + break; + } + case EAlfNodeTransparentRegionChanged: + { + DoNodeTransparentRegionChangedL(); + break; + } + case EAlfNodeLayerAdded: + { + DoNodeLayerAddedL(); + break; + } + case EAlfNodeLayerExtentChanged: + { + DoNodeLayerExtentChangedL(); + break; + } + case EAlfNodeLayerUsesAlphaFlagChanged: + { + DoNodeLayerUsesAlphaFlagChangedL(); + break; + } + case EAlfNodeMovedToWindowGroup: + { + DoNodeMovedToWindowGroupL(); + break; + } + case EAlfNodeWindowGroupChained: + { + DoNodeWindowGroupChainedL(); + break; + } + case EAlfNodeWindowGroupChainBrokenAfter: + { + DoNodeWindowGroupChainBrokenAfterL(); + break; + } + case EAlfWrap: + { + ReadEndMarkerL(); // futile, but just in case somet + iStream->Source()->SeekL( MStreamBuf::ERead, TStreamPos(0)); + iChunkHeader->iReadOffset = 0; + break; + } + case EAlfNodeAttributeChanged: // currently only textcursor may receive these events + { + DoNodeAttributeChangedL(); + break; + } + case EAlfCommitBatch: + { + RequestFrameEndCallback(); + break; + } +#ifdef ALF_DEBUG_TRACK_DRAWING + case EAlfDebugTrackNode: + { + DoNodeDebugTrackL(); + break; + } +#endif + case EAlfDestroyChunk: + { + TInt chunkId = iStream->ReadInt32L(); + iServer.Bridge()->AddData( EAlfReleaseTemporaryChunk, chunkId ); + break; + } + case EAlfJumpToAnotherChunk: + { + RequestPacketEndCallback( offset ); + TInt32 readChunkId = iStream->ReadInt32L(); + TInt size = iStream->ReadInt32L(); + ReadEndMarkerL(); + // __ALFLOGSTRING1("Next chunk: %d, size: %d, previous chunk: %d"), readChunkId, size, iChunkInUse ); + + if ( readChunkId == 0 ) + { + iChunkHeader = reinterpret_cast(iChunk.Base()); + iStream->Close(); + iStream->Open( iChunk.Base() + sizeof( TChunkHeader), KChunkMaxSize ); + iStream->Source()->SeekL( MStreamBuf::ERead, TStreamPos(0)); + } + else + { + iStream->Close(); + iStream->Open( iCacheChunks.Find( readChunkId )->Base() + sizeof( TChunkHeader), size ); + iChunkHeader = reinterpret_cast(iCacheChunks.Find( readChunkId )->Base()); + } + iChunkInUse = readChunkId; + + break; + } + default: + { + __ALFLOGSTRING("CAlfHierarchyModel::ExecuteCommandsL, off track"); +#ifdef _ALF_LOGGING + __ALFLOGSTRING3("CAlfHierarchyModel::ExecuteCommandsL, off track - Cmd: %d, Previous Cmd: %d, Count: %d..", command, previousCommand, commandCount ); +#endif + __ALFLOGSTRING1("..CAlfHierarchyModel::ExecuteCommandsL, unrecoverable error : HALTING at offset: %d", offset ); + USER_INVARIANT(); + break; + } + } + ReadEndMarkerL(); + offset = iStream->Source()->TellL( MStreamBuf::ERead ).Offset(); + RequestPacketEndCallback( offset ); + //__ALFLOGSTRING1("end offset %d offset %d, command %d"), aEndOffset, offset, command ); + }; + iFrame++; + } + +// --------------------------------------------------------------------------- +// BridgerCallback +// This is called by CAlfStreamBridge when EAlfCommitBatch is processed. +// +// Note: This call comes from another thread, Alf server thread. Beware that +// Alf streamer/decoder server thread might access the class data +// concurrently! +// --------------------------------------------------------------------------- +// +void CAlfHierarchyModel::BridgerCallback( TInt aOp, TInt aInt ) + { + // hackish, just do the panic release for window server + // Trying to mimize changes on existing logic + if (aOp == KRELEASEWINDOWSERVER) + { + __ALFLOGSTRING1("CAlfHierarchyModel::BridgerCallback, iMessage is null: %d", iMessage.IsNull()); + + if (!iMessage.IsNull()) + { + __ALFLOGSTRING("CAlfHierarchyModel::BridgerCallback, emergency releasing of window server"); + iMessage.Complete(EAlfBridgerAsyncronousData); + iDidForcedComplete = ETrue; + } + else if (aInt == KRELEASEDBEFOREQUEUE) + { + iBatchAlreadyCommited = ETrue; + } + + return; + } + + switch( aOp ) + { + case EAlfDSGetAlfNativeWindowData: + { + iSema.Wait(); + // Complete the pending message + RMessage2* rsMessage = (RMessage2*)aInt; + for (TInt i = 0; i < iPendingAlfWindowDataMessages.Count(); i++) + { + if (&(iPendingAlfWindowDataMessages[i]) == rsMessage) + { + // Complete the message to RS + rsMessage->Complete(KErrNone); + iPendingAlfWindowDataMessages.Remove(i); + break; + } + } + iSema.Signal(); + break; + } + + case EAlfRequestCommandReadNotification: + { + if (iChunkHeader) + { + iChunkHeader->iReadOffset = aInt; // last read offset + } + + // TODO: If you can absolute guaranteen to count the available space correctly, then this can also complete iSpaceNotificationMessage + break; + } + case EAlfRequestCommitBatch: + { + __ALFLOGSTRING1("CAlfHierarchyModel::BridgerCallback, iMessage.IsNull %d", iMessage.IsNull()); + if ( iMessage.IsNull()) + { + if (!iDidForcedComplete) + { + __ALFLOGSTRING("request for this message has not arrived. complete on arrival"); + iBatchAlreadyCommited = ETrue; + } + } + else + { + iBatchAlreadyCommited = EFalse; + iMessage.Complete(EAlfBridgerAsyncronousData); + } + iDidForcedComplete = EFalse; + break; + } + case EAlfReleaseTemporaryChunk: + { + CloseChunk( aInt ); + break; + } + default: + { + USER_INVARIANT(); + } + } + } + +// --------------------------------------------------------------------------- +// DoNodeCreatedL +// --------------------------------------------------------------------------- +// +void CAlfHierarchyModel::DoNodeCreatedL() + { +#ifdef ALF_DEBUG_TRACK_DRAWING + TBool trackThisNode(EFalse); +#endif + CAlfNode* node = NULL; + // Nodes add themself to iNodeStructArray, which "owns" the nodes. Nodes are created and destroyed only if requested by the Wserv + MWsWindowTreeNode::TType nodeType = (MWsWindowTreeNode::TType)iStream->ReadInt32L(); + switch (nodeType) + { + case MWsWindowTreeNode::EWinTreeNodeClient: + { + node = CAlfNodeWindow::NewL( this, iStream, iScreenNumber ); + break; + } + case MWsWindowTreeNode::EWinTreeNodeRoot: + { + node = CAlfNodeRoot::NewL( this ,iStream, iScreenNumber ); + iRootNode = (CAlfNodeRoot*)node; + break; + } + case MWsWindowTreeNode::EWinTreeNodeGroup: + { + node = CAlfNodeGroup::NewL( this, iStream, iScreenNumber ); + break; + } + case MWsWindowTreeNode::EWinTreeNodeAnim: + { + node = CAlfNodeAnim::NewL(this, iStream, iScreenNumber ); + break; + } + case MWsWindowTreeNode::EWinTreeNodeSprite: + { + node = CAlfNodeSprite::NewL( this, iStream, iScreenNumber ); + break; + } + case MWsWindowTreeNode::EWinTreeNodeStandardTextCursor: + { + node = CAlfNodeTextCursor::NewL( this, iStream, iScreenNumber ); + break; + } + default: + { + __ALFLOGSTRING1("CAlfHierarchyModel::DoNodeCreatedL, unknown node type: %i", nodeType); + break; + } + } + // Note to Debuggers + // You can track certain type of nodes and their draw buffers by changing the trackThisNode value to 1. + // Then enable breakpoints in + // some places marked in code using the ALF_DEBUG_TRACK_DRAWING and HUI_DEBUG_TRACK_DRAWING . The macro + // must be enabled in + // alfappservercore.mmp + // coretoolkit.mmp and + // alfrenderstageplugin.mmp + +#ifdef ALF_DEBUG_TRACK_DRAWING + if ( trackThisNode ) + { + node->SetTracking( trackThisNode ); + } +#endif + +#ifdef ALF_DEBUG_PRINT_NODE_INFO + if ( node ) + { + RDebug::Print(_L("DoNodeCreatedL")); + iRootNode->iLogging = 1; + CAlfNode::PrintNodeTree(iRootNode, node->iId); + iRootNode->iLogging = 0; + //CAlfNode::PrintInfo( 0, (CAlfNodeVisual*)node, TPtrC(KText) , iSearchNode); + } +#endif + } + +// --------------------------------------------------------------------------- +// DoNodeReleasedL +// --------------------------------------------------------------------------- +// +void CAlfHierarchyModel::DoNodeReleasedL() + { + MWsWindowTreeNode::TType nodeType = (MWsWindowTreeNode::TType)iStream->ReadInt32L(); + TUint32 nodeId = (TUint32)iStream->ReadUint32L(); + CAlfNode* node = FindNode( nodeId ); + +#ifdef ALF_DEBUG_PRINT_NODE_INFO + if ( node ) + { + //_LIT(KText,"DoNodeReleasedL"); + CAlfNode::PrintNodeTree(iRootNode, node->iId); + +// CAlfNode::PrintInfo( 0, (CAlfNodeVisual*)node, TPtrC(KText) , iSearchNode); + } +#endif + if ( node ) + { + delete node; + } + else + { + USER_INVARIANT(); + } + } + +// --------------------------------------------------------------------------- +// DoNodeActivatedL +// --------------------------------------------------------------------------- +// +void CAlfHierarchyModel::DoNodeActivatedL() + { + TInt nodeType = iStream->ReadInt32L(); + TUint32 nodeId = (TUint32)iStream->ReadUint32L(); + CAlfNode* node = FindNode( nodeId ); + if ( node ) + { + node->ActivateNode(); + } + else + { + USER_INVARIANT(); + } + } + +// --------------------------------------------------------------------------- +// DoNodeExtentChangedL +// --------------------------------------------------------------------------- +// +void CAlfHierarchyModel::DoNodeExtentChangedL() + { + TRect rect; + ReadRectL( rect, iStream); + TUint32 nodeId = (TUint32)iStream->ReadUint32L(); + + CAlfNodeVisual* node = (CAlfNodeVisual*)FindNode( nodeId ); + if ( node ) + { + node->SetExtent( rect ); + } + else + { + USER_INVARIANT(); + } +#ifdef ALF_DEBUG_PRINT_NODE_INFO + if ( node ) + { + RDebug::Print(_L("Extent changed")); + CAlfNode::PrintNodeTree(iRootNode, node->iId); + //CAlfNode::PrintInfo( 0, (CAlfNodeVisual*)node, TPtrC(KText), iSearchNode); + } +#endif + + } + +// --------------------------------------------------------------------------- +// DoNodeSiblingOrderChangedL +// --------------------------------------------------------------------------- +// +void CAlfHierarchyModel::DoNodeSiblingOrderChangedL() + { + TInt newPos = iStream->ReadInt32L(); + TUint32 nodeId = (TUint32)iStream->ReadUint32L(); + + CAlfNode* node = FindNode( nodeId ); + if ( node ) + { + node->SiblingOrderChanged( newPos ); + } + else + { +#ifdef _DEBUG + RDebug::Print( _L("Missing a node %d"), nodeId ); +#endif + // USER_INVARIANT(); + } + +#ifdef ALF_DEBUG_PRINT_NODE_INFO + if ( node ) + { + RDebug::Print(_L("Sibling order changed")); + CAlfNode::PrintNodeTree(iRootNode, node->iId); + + // CAlfNode::PrintInfo( 0, (CAlfNodeVisual*)node, TPtrC(KText), iSearchNode ); + } +#endif + } + +// --------------------------------------------------------------------------- +// DoNodeFlagChangedL +// --------------------------------------------------------------------------- +// +void CAlfHierarchyModel::DoNodeFlagChangedL() + { + MWsWindowTreeObserver::TFlags flag = (MWsWindowTreeObserver::TFlags)iStream->ReadUint32L(); + TBool newValue = (TBool)iStream->ReadInt32L(); + TUint32 nodeId = (TUint32)iStream->ReadUint32L(); + + CAlfNode* node = FindNode( nodeId ); + if ( node ) + { + node->FlagChanged( flag, newValue ); + + } + else + { + USER_INVARIANT(); + } + } + +// --------------------------------------------------------------------------- +// DoNodeFadeAllChildrenL +// --------------------------------------------------------------------------- +// +void CAlfHierarchyModel::DoNodeFadeAllChildrenL() + { + TUint32 nodeId = (TUint32)iStream->ReadUint32L(); + TBool faded = (TBool)iStream->ReadInt32L(); + + CAlfNode* node = FindNode( nodeId ); + if ( node ) + { + node->FadeAllChildren( faded ); + } + else + { + USER_INVARIANT(); + } + } + +// --------------------------------------------------------------------------- +// DoNodeFadeCountChangedL +// --------------------------------------------------------------------------- +// +void CAlfHierarchyModel::DoNodeFadeCountChangedL() + { + TUint32 nodeId = (TUint32)iStream->ReadUint32L(); + TInt fadeCount = (TInt)iStream->ReadUint32L(); + + CAlfNode* node = FindNode( nodeId ); + if ( node ) + { + node->FadeCountChanged( fadeCount ); + } + else + { + USER_INVARIANT(); + } + } + +// --------------------------------------------------------------------------- +// DoNodeTransparentRegionChangedL +// --------------------------------------------------------------------------- +// +void CAlfHierarchyModel::DoNodeTransparentRegionChangedL() + { + TUint32 nodeId = (TUint32)iStream->ReadUint32L(); + iStream->ReadInt8L(); + RRegion newTransparentRegion; + RRegion newOpaqueRegion; + ReadRegionL( iStream, newTransparentRegion ); + iStream->ReadInt8L(); + ReadRegionL( iStream, newOpaqueRegion ); + // TODO: Implement actions + } + +// --------------------------------------------------------------------------- +// DoNodeLayerAddedL +// --------------------------------------------------------------------------- +// +void CAlfHierarchyModel::DoNodeLayerAddedL() + { + DoNodeLayerExtentChangedL(); + } + +// --------------------------------------------------------------------------- +// DoNodeLayerExtentChangedL +// --------------------------------------------------------------------------- +// +void CAlfHierarchyModel::DoNodeLayerExtentChangedL() + { + // Set composition surface extent + TUint32 nodeId = (TUint32)iStream->ReadUint32L(); + TRect extent = TRect(0,0,0,0); + ReadRectL(extent, iStream); + CAlfNodeVisual* node = (CAlfNodeVisual*)FindNode( nodeId ); + if ( node && node->Window() ) + { + // SetSurfaceExtent is not supported for image visual + node->Window()->SetSurfaceExtent( extent ); + } + else if( node ) // this would mean that node has being orphaneded but not yet deleted + { + __ALFLOGSTRING1("CAlfHierarchyModel::DoNodeLayerExtentChangedL node found but window %d was destroyed", nodeId); + } + } + +// --------------------------------------------------------------------------- +// DoNodeLayerUsesAlphaFlagChangedL +// --------------------------------------------------------------------------- +// +void CAlfHierarchyModel::DoNodeLayerUsesAlphaFlagChangedL() + { + // Set composition surface extent + TUint32 nodeId = (TUint32)iStream->ReadUint32L(); + TBool enabled = (TBool)iStream->ReadInt32L(); + CAlfNodeVisual* node = (CAlfNodeVisual*)FindNode( nodeId ); + if ( node && node->Window() ) + { + // SetLayerUsesAplhaFlag is not supported for image visual + node->Window()->SetLayerUsesAplhaFlag( enabled ); + } + else if( node ) // this would mean that node has being orphaneded but not yet deleted + { + __ALFLOGSTRING1("CAlfHierarchyModel::DoNodeLayerUsesAlphaFlagChangedL node found but window %d was destroyed", nodeId); + } + } + + +// --------------------------------------------------------------------------- +// DoNodeMovedToWindowGroupL +// --------------------------------------------------------------------------- +// +void CAlfHierarchyModel::DoNodeMovedToWindowGroupL() + { + TUint32 nodeId = (TUint32)iStream->ReadUint32L(); + TUint32 newWindowgroupNode = (TUint32)iStream->ReadUint32L(); + CAlfNodeWindow* node = (CAlfNodeWindow*)FindNode( nodeId ); + if ( node ) + { + node->MoveToWindowGroup( newWindowgroupNode ); + } + } + +// --------------------------------------------------------------------------- +// DoNodeWindowGroupChainedL +// --------------------------------------------------------------------------- +// +void CAlfHierarchyModel::DoNodeWindowGroupChainedL() + { + TUint32 parentNode = (TUint32)iStream->ReadUint32L(); + TUint32 childNode = (TUint32)iStream->ReadUint32L(); + CAlfNodeGroup* node = (CAlfNodeGroup*)FindNode( parentNode ); + if ( node ) + { + node->WindowGroupChained( childNode ); + } + } + +// --------------------------------------------------------------------------- +// DoNodeWindowGroupChainBrokenAfterL +// --------------------------------------------------------------------------- +// +void CAlfHierarchyModel::DoNodeWindowGroupChainBrokenAfterL() + { + TUint32 nodeId = (TUint32)iStream->ReadUint32L(); + CAlfNodeGroup* node = (CAlfNodeGroup*)FindNode( nodeId ); + if ( node ) + { + node->GroupChainBrokenAfter(); + } + } + +// --------------------------------------------------------------------------- +// DoNodeAttributeChangedL +// --------------------------------------------------------------------------- +// +void CAlfHierarchyModel::DoNodeAttributeChangedL() + { + TUint32 nodeId = (TUint32)iStream->ReadUint32L(); + CAlfNodeTextCursor* node = (CAlfNodeTextCursor*)FindNode( nodeId); + if ( node && node->Type() == MWsWindowTreeNode::EWinTreeNodeStandardTextCursor ) + { + node->AttributeChangedL( iStream ); + +#ifdef ALF_DEBUG_PRINT_NODE_INFO + if ( node ) + { + //_LIT(KText,"Attribute changed"); + //CAlfNode::PrintInfo( 0, (CAlfNodeVisual*)node, TPtrC(KText) , iSearchNode); + //CAlfNode::PrintNodeTree(iRootNode, KText, node->iId); + + } +#endif + } + else + { + USER_INVARIANT(); // attribute change for unexpected node type. new code needed! + } + } +// --------------------------------------------------------------------------- +// DoNodeWindowGroupChainBrokenAfterL +// --------------------------------------------------------------------------- +// +#ifdef ALF_DEBUG_TRACK_DRAWING +void CAlfHierarchyModel::DoNodeDebugTrackL() + { + TUint32 nodeId = (TUint32)iStream->ReadUint32L(); + TBool trackingValue = iStream->ReadUint32L(); + CAlfNodeGroup* node = (CAlfNodeGroup*)FindNode( nodeId ); + if ( node ) + { + node->SetTracking( trackingValue ); + } + } +#endif +// --------------------------------------------------------------------------- +// FindNode +// --------------------------------------------------------------------------- +// +CAlfNode* CAlfHierarchyModel::FindNode( TUint32 aWindowId ) + { + if ( iPreviouslySearchedNode && iPreviouslySearchedNode->iId == aWindowId ) + { + return iPreviouslySearchedNode; + } + CNodeHashStruct* nodeHashStruct = iNodeHashArray.Find( aWindowId ); + if (nodeHashStruct) + { + iPreviouslySearchedNode = nodeHashStruct->iNode; + return iPreviouslySearchedNode; + } + return NULL; + } + +// --------------------------------------------------------------------------- +// InsertNode +// --------------------------------------------------------------------------- +// +TInt CAlfHierarchyModel::InsertNode( TUint32 aWindowId, CAlfNode* aNode ) + { + return iNodeHashArray.Insert( aWindowId, CNodeHashStruct( aNode )); + } + +// --------------------------------------------------------------------------- +// RemoveNode +// --------------------------------------------------------------------------- +// +TBool CAlfHierarchyModel::RemoveNode( TUint32 aWindowId ) + { + iPreviouslySearchedNode = NULL; + return iNodeHashArray.Remove( aWindowId ); + } + +// --------------------------------------------------------------------------- +// RemoveAllNodes +// --------------------------------------------------------------------------- +// +void CAlfHierarchyModel::RemoveAllNodes( ) + { + // TODO: Is this useless? wserv will remove its nodes anyway, if screen is destroyed + } + +// --------------------------------------------------------------------------- +// ProcessUnknownNodeDrawingL +// --------------------------------------------------------------------------- +// +void CAlfHierarchyModel::ProcessUnknownNodeDrawingL( RMemReadStream& aStream ) + { + TInt32 chunkInUse = aStream.ReadInt32L(); + TInt nextFramePos = aStream.ReadInt32L(); + + // jump to the next frame + if ( nextFramePos == KFrameOffsetTemplate ) + { + __ALFLOGSTRING("CAlfHierarchyModel::PostBufferL, Address of the frame has not been initialized!"); + } + TUint8 padding = aStream.ReadInt8L(); + aStream.ReadInt8L(); + while( padding--) + { + aStream.ReadInt8L(); + } + TInt currentPos = aStream.Source()->TellL( MStreamBuf::ERead ).Offset(); + aStream.Source()->SeekL( MStreamBuf::ERead, TStreamPos(nextFramePos)); + TSgcCanvasCommands packetState = (TSgcCanvasCommands)aStream.ReadInt8L(); + switch( packetState ) + { + case EAlfPacketReady: // fall through + case EAlfPacketNotReady: + default: + { + __ALFLOGSTRING1("CAlfHierarchyModel::PostBufferL endMarker: %d ", packetState); + break; + } + } + } + +