diff -r 000000000000 -r 5d03bc08d59c windowing/windowserver/nonnga/SERVER/cliwin.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/windowing/windowserver/nonnga/SERVER/cliwin.cpp Tue Feb 02 01:47:50 2010 +0200 @@ -0,0 +1,1082 @@ +// 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: +// Client window functions +// +// + +#include "W32CLICK.H" +#include "server.h" +#include "cliwin.h" +#include "gc.h" +#include "rootwin.h" +#include "windowgroup.h" +#include "walkwindowtree.h" +#include "ScrDev.H" +#include "wstop.h" +#include "EVQUEUE.H" +#include "KEYCLICK.H" +#include "panics.h" +#include "password.h" +#include "pointer.h" +#include "EVENT.H" +#include "backedupwindow.h" +#include "redrawmsgwindow.h" + +TBool CWsClientWindow::iAbsoluteFading = EFalse; + +const TPoint corner1[1]={TPoint(1,1)}; +const TPoint corner2[2]={TPoint(2,1),TPoint(1,1)}; +const TPoint corner3[2]={TPoint(3,1),TPoint(1,2)}; +const TPoint corner5[4]={TPoint(5,1),TPoint(3,1),TPoint(2,1),TPoint(1,2)}; + +/*CWsClientWindow*/ + +CWsClientWindow::CWsClientWindow(CWsClient* aOwner, CScreen* aScreen) : CWsWindow(aOwner,WS_HANDLE_WINDOW,aScreen) + { + iWinType=EWinTypeClient; + } + +void CWsClientWindow::ConstructL(const TWsClCmdCreateWindow &aCmd, CWsWindowBase *aParent, TBool aScreenDeviceIsInvalid) + { + CWsWindow::Construct(); + NewObjL(); + if (aCmd.clientHandle==NULL) + OwnerPanic(EWservPanicNullHandle); +#if defined(_DEBUG) + if (IsClientHandleInUse(aCmd.clientHandle)) + OwnerPanic(EWservPanicDuplicateHandle); +#endif + iPointerFilter=EPointerFilterEnterExit|EPointerFilterMove|EPointerFilterDrag; + iClientHandle=aCmd.clientHandle; + CWsWindow* inherit=static_cast(aParent); + if (aParent->WinType()==EWinTypeGroup) + inherit=RootWindow(); + SetPointerCursor(aParent->PointerCursor()); + iAbs=inherit->Abs(); + iOrigin=aParent->Origin(); + iRel.iBr.iX=inherit->Rel().iBr.iX-inherit->Rel().iTl.iX; + iRel.iBr.iY=inherit->Rel().iBr.iY-inherit->Rel().iTl.iY; + switch(aCmd.type) + { + case EWinRedraw: + iRedraw=new(ELeave) CWsRedrawMsgWindow(this); + break; + case EWinBackedUp: + iRedraw=new(ELeave) CWsBackedUpWindow(this, aCmd.displayMode); + iAbs.iBr=iAbs.iTl; + iRel.iBr=iRel.iTl; + break; + case EWinBlank: + iRedraw=new(ELeave) CWsBlankWindow(this); + break; + default: + OwnerPanic(EWservPanicRedrawType); + } + ResetHiddenFlag(); + CWsWindowBase::ConstructL(aParent); + if (aScreenDeviceIsInvalid) + { + iFlags|=EFlagScreenDeviceInvalid; + ResetHiddenFlag(); + } + SetCornerTypeL(EWindowCornerSquare,0); + iRedraw->ConstructL(); + } + +void CWsClientWindow::SetClippedBaseArea(RWsRegion &aRegion) const + { + if(iBaseArea) + { + aRegion.Copy(*iBaseArea); + } + aRegion.ClipRect(iAbs); + } + +void CWsClientWindow::SetOpaqueClippedBaseArea(RWsRegion &aRegion) const + { + if (IsTranslucent()) + { + if (iUserDefinedOpaqueRegion) + { + aRegion.Copy(*iUserDefinedOpaqueRegion); + aRegion.ClipRect(iAbs); + } + else + { + aRegion.Clear(); + } + } + else + { + SetClippedBaseArea(aRegion); + } + } + +void CWsClientWindow::ResetHiddenFlag() +// +// Reset the status of the hidden flag based on the current states of the active and invisible flags +// + { + CWsClientWindow *parent=static_cast(iParent); + + TBool wasHidden = iFlags&EFlagHidden; + TBool nowHidden = (parent==NULL || + (parent->WinType()==EWinTypeClient && !parent->IsVisible()) || + !(iFlags&EFlagActive) || + (iFlags&EFlagInvisible) || + (iFlags&EFlagScreenDeviceInvalid)); + + if (nowHidden) + { + iFlags|=EFlagHidden; + iFlags&=~EFlagDrawnToScreen; + } + else + { + iFlags&=~EFlagHidden; + } + if ((!nowHidden) != (!wasHidden)) + { + // intentionally call the screen directly + iScreen->ScheduleRegionUpdate(&iVisibleRegion); + } + } + +void CWsClientWindow::ResetHiddenFlags() + { + CWsClientWindow *win=this; + FOREVER + { + TUint oldHiddenFlag=win->iFlags&EFlagHidden; + win->ResetHiddenFlag(); + if ((win->iFlags&EFlagHidden)!=oldHiddenFlag) // If hidden status hasn't changed nothing to do + { + if (win->Child()) + { + win=win->Child(); + continue; + } + } + if (win==this) + return; + while(!win->NextSibling()) + { + win=(CWsClientWindow *)win->BaseParent(); + if (win==this) + return; + } + win=win->NextSibling(); + } + } + +void CWsClientWindow::OffsetBaseArea(const TPoint &aOffset) + { + iBaseArea->Offset(aOffset); + } + +void CWsClientWindow::CalcBaseArea() +// +// The windows basic area before any clipping is done +// + { + TInt cornerType=iCornerData&ECornerTypeMask; + if (cornerType==EWindowCornerRegion) + iBaseArea->ClipRect(FullRect()); + else + { + TSize size=Size(); + iBaseArea->Clear(); + const TPoint *corners=NULL; + TInt count=0; + switch(cornerType) + { + case EWindowCorner1: + count=sizeof(corner1)/sizeof(TPoint); + corners=corner1; + break; + case EWindowCorner2: + count=sizeof(corner2)/sizeof(TPoint); + corners=corner2; + break; + case EWindowCorner3: + count=sizeof(corner3)/sizeof(TPoint); + corners=corner3; + break; + case EWindowCorner5: + count=sizeof(corner5)/sizeof(TPoint); + corners=corner5; + break; + default: + break; + } + TInt top=0; + TInt bot=size.iHeight; + for(TInt index=0;indexAddRect(TRect(iCornerData&EWindowCornerNotTL?0:xadjust,top, + size.iWidth-(iCornerData&EWindowCornerNotTR?0:xadjust),top+yadjust)); + top+=yadjust; + } + if ((iCornerData&(EWindowCornerNotBL|EWindowCornerNotBR))!=(EWindowCornerNotBL|EWindowCornerNotBR)) + { + iBaseArea->AddRect(TRect(iCornerData&EWindowCornerNotBL?0:xadjust,bot-yadjust, + size.iWidth-(iCornerData&EWindowCornerNotBR?0:xadjust),bot)); + bot-=yadjust; + } + } + iBaseArea->AddRect(TRect(0,top,size.iWidth,bot)); + iBaseArea->Offset(Origin()); + iBaseArea->ClipRect(FullRect()); + iBaseArea->Sort(); + } + } + +void CWsClientWindow::GenerateArea(RWsRegion &aArea, TBool aClipTranslucent) const +// +// Create the window area list. +// + { + aArea.Clear(); + if (IsVisible()) + { + aArea.Copy(*iBaseArea); + aArea.ClipRect(iAbs); + const CWsClientWindow *win=this; + FOREVER + { + if (win->IsTopClientWindow()) + break; + ClipWindows(aArea,(CWsClientWindow *)win->BaseParent()->BaseChild(),win,aClipTranslucent); + win=(CWsClientWindow *)win->iParent; + } + TInt tidyCount=0; + for(const CWsClientWindow *cwin=RootWindow()->FirstTopClientWindow();aArea.Count() && cwin!=win;cwin=cwin->NextSiblingMultiParent()) + { + if (!tidyCount--) + { + aArea.Tidy(); + tidyCount=ETidyCountSetting; // Tidy every ETidyCountSetting times around + } + if (cwin->IsVisible()) + { + if (cwin->IsTranslucent() && !aClipTranslucent) + { + if (cwin->iUserDefinedOpaqueRegion) + { + aArea.SubRegion(*cwin->iUserDefinedOpaqueRegion); + } + } + else + { + aArea.SubRegion(*cwin->iBaseArea); + } + } + } + aArea.Tidy(); + } + } + +void CWsClientWindow::ClipWindows(TRegion ®ion,const CWsClientWindow *start, const CWsClientWindow *end, TBool aClipTranslucent) +// +// Remove out of the region the opaque part of the abs rect of all the windows starting from 'start' +// along the sibling list to (and not including) the end window. +// + { + for(const CWsClientWindow *win=start;region.Count() && win!=end;win=win->NextSibling()) + { + if (win->IsVisible()) + { + if (win->IsTranslucent() && !aClipTranslucent) + { + if (win->iUserDefinedOpaqueRegion) + { + region.SubRegion(*win->iUserDefinedOpaqueRegion); + } + } + else + { + region.SubRegion(*win->iBaseArea); + } + } + } + } + +void CWsClientWindow::GenerateTopRegion(RWsRegion& aRegion) const + { + GenerateArea(aRegion,ETrue); + if (iChild) + ClipWindows(aRegion,Child(),NULL,ETrue); + } + +void CWsClientWindow::GenerateWindowRegion(RWsRegion &aRegion) const +// +// Calculate the windows clipping region without using the usual stored iArea or iRegion fields +// this function is used by the screen backup code to calculate "what if" regions to work out +// whether something would be visible if the backed up window didn't exist, on this basis we +// don't want to modify the existing copies of iArea & iRegion. +// + { + GenerateArea(aRegion,EFalse); + if (iChild) + ClipWindows(aRegion,Child(),NULL,EFalse); + } + +void CWsClientWindow::RecalcChildAbs(const TPoint *aOffset) + { + CWsClientWindow *win=this; + FOREVER + { + FOREVER + { + win->SetAbsFromRel(); + if (aOffset) + win->OffsetBaseArea(*aOffset); + if (win->Child()==NULL) + break; + win=win->Child(); + } + FOREVER + { + if (win==this) + return; + if (win->NextSibling()!=NULL) + { + win=win->NextSibling(); + break; + } + win=(CWsClientWindow *)win->iParent; // The cast is safe as the loop is aborted when win==this + } + } + } + +void CWsClientWindow::SetAbsFromRel() + { + iOrigin=iRel.iTl+iParent->Origin(); + iAbs=iRel; + iAbs.Move(iParent->Origin()); + iAbs.Intersection(iParent->AbsRect()); + } + +void CWsClientWindow::SetExtentL(const TPoint *aPos,const TSize *aSize) + { + if (iParent==NULL) + OwnerPanic(EWservPanicParentDeleted); + TPoint offset = TPoint(0,0); + TSize oldSize; + TSize newSize; + TBool sizeChanged = EFalse; + TBool posChanged = EFalse; + + if (aPos) + { + offset = *aPos+iParent->Origin()-iOrigin; + if (offset.iX != 0 || offset.iY != 0) + { + posChanged = ETrue; + } + } + + if (posChanged) + { + TWalkWindowTreeScheduleRedraws wwt; + WalkWindowTree(wwt, EWalkChildren); + } + + if (aSize) + { + newSize=*aSize; + if (newSize.iWidth<0) + newSize.iWidth=0; + if (newSize.iHeight<0) + newSize.iHeight=0; + // This should be the only part of resizing that can fail + // and it can only fail for backedup windows. + iRedraw->PrepareForResizeL(newSize,oldSize); + sizeChanged = *aSize != iRel.Size(); + } + + if (posChanged) + { + iRel.Move(offset); + RecalcChildAbs(&offset); + TWalkWindowTreeOffsetTransparentRegions offsetTransparent(offset); + WalkWindowTree(offsetTransparent, EWalkChildren); + } + + if (sizeChanged) + { + iRel.SetSize(newSize); + RecalcChildAbs(NULL); + CalcBaseArea(); + iRedraw->Resize(newSize,oldSize); + } + + if (posChanged || sizeChanged) + { + iRedraw->ClipInvalidRegion(TRect(iRel.Size())); + iRedraw->Moved(); + ScheduleRegionUpdate(NULL); + TWalkWindowTreeRecalcOpaque recalcOpaque; + WalkWindowTree(recalcOpaque, EWalkChildren); + } + } + +void CWsClientWindow::Scroll(const TRect &aClipRect, const TPoint &aOffset, const TRect &aRect) + { + if (iParent==NULL) + OwnerPanic(EWservPanicParentDeleted); +// + iRedraw->Scroll(aClipRect, aOffset,aRect); +// + CWsTop::TriggerRedraws(RootWindow()); + } + +void CWsClientWindow::DeleteBaseArea() + { + WS_ASSERT_DEBUG(iBaseArea!=&nullRegion, EWsPanicRegionNull); + if ((iCornerData&ECornerTypeMask)==EWindowCornerRegion) + ((RWsRegion *)iBaseArea)->Destroy(); + else + delete iBaseArea; + } + +CWsClientWindow::~CWsClientWindow() + { + iFlags|=EFlagShutDownInProgress; + if (CClick::IsHandler()) + { + TWindowCloseData params; + params.iClientHandle=iClientHandle; + //if parent already shutdown (or disconnected) send 0 + params.iWindowGroupId=iParent ? WinGroup()->Identifier():0; + CClick::OtherEvent(EEventWindowClose,¶ms); + } + RemoveAllKeyRects(); + while(iWinGcList) + iWinGcList->Deactivate(); +// + iFlags|=EFlagInvisible; // First make it invisble + if (iParent) // In case window wasn't fully constructed + ResetHiddenFlags(); +// + CWsWindow::Shutdown(); // Two phase destruction + + DeleteBaseArea(); + CWsPointerBuffer::Disconnect(this); + iFlags&=~EFlagShutDownInProgress; + SetUserTransparentRegion(0); + CWsPassword::WindowDestroyed(this); + } + +void CWsClientWindow::Activate() + { + if (iFlags&EFlagActive) + OwnerPanic(EWservPanicWindowActive); + iFlags|=EFlagActive; + + ResetHiddenFlags(); + } + +void CWsClientWindow::SetCornerTypeL(TCornerType aCornerType, TInt aCornerFlags, TRegion *aNewBaseArea) + { + TRegion *baseArea=NULL; + if (aCornerFlags&ECornerTypeMask) + OwnerPanic(EWservPanicCornerParams); + switch (aCornerType) + { + case EWindowCornerSquare: + baseArea=new(ELeave) TRegionFix<1>(); + break; + case EWindowCorner1: + baseArea=new(ELeave) TRegionFix<3>(); + break; + case EWindowCorner2: + case EWindowCorner3: + baseArea=new(ELeave) TRegionFix<5>(); + break; + case EWindowCorner5: + baseArea=new(ELeave) TRegionFix<9>(); + break; + case EWindowCornerRegion: + User::LeaveIfNull(baseArea=aNewBaseArea); + baseArea->Offset(Origin()); + break; + default: + OwnerPanic(EWservPanicCornerParams); + } + DeleteBaseArea(); + iCornerData=aCornerType; + iCornerData|=aCornerFlags; + iBaseArea=baseArea; + CalcBaseArea(); + ScheduleRegionUpdate(NULL); + } + +void CWsClientWindow::SetVisible(TBool aState) + { + if (aState) + { + if (iParent==NULL) + OwnerPanic(EWservPanicParentDeleted); + if (!(iFlags&EFlagInvisible)) // Already visible + return; + iFlags&=~EFlagInvisible; + ResetHiddenFlags(); + } + else + { + if (iFlags&EFlagInvisible || !iParent) // Already invisible or parent has been deleted + return; + TWalkWindowTreePurgeEvents wwt; + WalkWindowTree(wwt,EWalkChildren); // Destroy all events on this and all children + iFlags|=EFlagInvisible; + ResetHiddenFlags(); + } + } + +void CWsClientWindow::CommandL(TInt aOpcode, const TAny *aCmdData) + { +#ifdef _DEBUG + // Save root window for performing CheckTree at the end of this func. + // When aOpcode is EWsWinOpFree, this object would've been destroyed + // and a call to RootWindow() in that case would be impossible + CWsRootWindow* rootWindow=RootWindow(); +#endif + TWsWinCmdUnion pData; + pData.any=aCmdData; + if (CWsWindowBase::CommandL(aOpcode,pData)==EFalse) + { + switch(aOpcode) + { + case EWsWinOpActivate: + Activate(); + break; + case EWsWinOpSetPos: + SetExtentL(pData.pos,NULL); + break; + case EWsWinOpSetExtent: + case EWsWinOpSetExtentErr: + SetExtentL(&pData.SetEx->pos,&pData.SetEx->size); + break; + case EWsWinOpSetSize: + case EWsWinOpSetSizeErr: + SetExtentL(NULL,pData.size); + break; + case EWsWinOpInquireOffset: + CWsClient::ReplyPoint(InquireOffset(*pData.UInt)); + break; + case EWsWinOpPosition: + CWsClient::ReplyPoint(iRel.iTl); + break; + case EWsWinOpAbsPosition: + CWsClient::ReplyPoint(iOrigin); + break; + case EWsWinOpSize: + CWsClient::ReplySize(iRel.Size()); + break; + case EWsWinOpTestInvariant: + SetReply(EFalse); + break; + case EWsWinOpPointerFilter: + { + TUint old=iPointerFilter; + iPointerFilter&=~pData.PointerFilter->mask; + iPointerFilter|=pData.PointerFilter->mask&pData.PointerFilter->flags; + if (old&EPointerFilterEnterExit) + WsPointer::ReLogWindow(this); + } + break; + case EWsWinOpSetPointerGrab: + if (*pData.Bool==EFalse) + iFlags&=~EFlagPointerGrab; + else + iFlags|=EFlagPointerGrab; + break; + case EWsWinOpClaimPointerGrab: + if (!iParent) + OwnerPanic(EWservPanicParentDeleted); + WsPointer::ClaimGrab(this,*pData.Bool); + break; + case EWsWinOpSetPointerCapture: + iFlags&=~(EFlagPointerCaptured|EFlagPointerCaptureDragDrop|EFlagPointerCaptureAllGroups); + if ((*pData.UInt)&RWindowBase::TCaptureFlagEnabled) + { + iFlags|=EFlagPointerCaptured; + if ((*pData.UInt)&RWindowBase::TCaptureFlagDragDrop) + iFlags|=EFlagPointerCaptureDragDrop; + if ((*pData.UInt)&RWindowBase::TCaptureFlagAllGroups) + iFlags|=EFlagPointerCaptureAllGroups; + + } + WsPointer::ReLogCurrentWindow(); + break; + case EWsWinOpSetPointerCapturePriority: + iPointerCapturePriority=*pData.Int; + break; + case EWsWinOpGetPointerCapturePriority: + SetReply(iPointerCapturePriority); + break; + case EWsWinOpSetVisible: + SetVisible(*pData.Bool); + break; + case EWsWinOpScroll: + { + TPoint origin(0,0); + TRect src(TRect(origin,iRel.Size())); + src.Move(-pData.ScrollRect->offset); + Scroll(TRect(TPoint(0,0),iRel.Size()),pData.ScrollRect->offset,src); + } + break; + case EWsWinOpScrollClip: + { + TPoint origin(0,0); + TRect src(TRect(origin,iRel.Size())); + src.Move(-pData.ScrollRect->offset); + TRect clip(pData.ScrollRect->clip); + Scroll(clip,pData.ScrollRect->offset,src); + } + break; + case EWsWinOpScrollRect: + { + TRect src(pData.ScrollRect->rect); + Scroll(TRect(TPoint(0,0),iRel.Size()),pData.ScrollRect->offset,src); + } + break; + case EWsWinOpScrollClipRect: + { + TRect src(pData.ScrollRect->rect); + TRect clip(pData.ScrollRect->clip); + Scroll(clip, pData.ScrollRect->offset,src); + } + break; + case EWsWinOpSetOrdinalPositionPri: + iOrdinalPriority=pData.OrdinalPos->ordinalPriority; + SetOrdinalPosition(pData.OrdinalPos->pos); + break; + case EWsWinOpSetShadowHeight: + if ((*pData.Int)<0) + OwnerPanic(EWservPanicNegativeShadowHeight); + break; + case EWsWinOpShadowDisabled: + break; + case EWsWinOpSetCornerType: + SetCornerTypeL(pData.SetCornerType->type, pData.SetCornerType->flags); + break; + case EWsWinOpSetShape: + SetCornerTypeL(EWindowCornerRegion,0,GetRegionFromClientL(iWsOwner, *pData.Int)); + break; + case EWsWinOpRequiredDisplayMode: + if (Backup()!=NULL) + OwnerPanic(EWservPanicBackupDisplayMode); + SetReply(DisplayMode()); + break; + case EWsWinOpGetDisplayMode: + SetReply(DisplayMode()); + break; + case EWsWinOpRequestPointerRepeatEvent: + if (!iParent) + OwnerPanic(EWservPanicParentDeleted); + WsPointer::RequestPointerRepeatEvent(this,pData.RequestPointerRepeatEvent->time,pData.RequestPointerRepeatEvent->rect); + break; + case EWsWinOpCancelPointerRepeatEventRequest: + WsPointer::CancelPointerRepeatEventRequest(); + break; + case EWsWinOpAllocPointerMoveBuffer: + CWsPointerBuffer::ConnectL(this,pData.AllocPointerMoveBuffer->maxNumPoints,pData.AllocPointerMoveBuffer->flags); + iFlags|=EFlagUsingPointerBuffer|EFlagHasPointerBuffer; + break; + case EWsWinOpFreePointerMoveBuffer: + CWsPointerBuffer::Disconnect(this); + iFlags&=~(EFlagUsingPointerBuffer|EFlagHasPointerBuffer); + break; + case EWsWinOpRetrievePointerMoveBuffer: + CWsPointerBuffer::RetrievePointerMoveBuffer(this,*pData.Int); + break; + case EWsWinOpEnablePointerMoveBuffer: + if (!(iFlags&EFlagHasPointerBuffer)) + OwnerPanic(EWservPanicNoPointerBuffer); + iFlags|=EFlagUsingPointerBuffer; + break; + case EWsWinOpDisablePointerMoveBuffer: + iFlags&=~EFlagUsingPointerBuffer; + /*Fall Through*/ + case EWsWinOpDiscardPointerMoveBuffer: + CWsPointerBuffer::DiscardPointerMoveBuffer(this); + break; + case EWsWinOpAddKeyRect: + AddKeyRectL(pData.AddKeyRect->rect, pData.AddKeyRect->scanCode, pData.AddKeyRect->activatedByPointerSwitchOn); + break; + case EWsWinOpRemoveAllKeyRects: + RemoveAllKeyRects(); + break; + case EWsWinOpPasswordWindow: + if (!iParent) + OwnerPanic(EWservPanicParentDeleted); + CWsPassword::SetPasswordWindowL(this, *pData.PasswordMode); + break; + case EWsWinOpEnableBackup: + if (!iParent) + OwnerPanic(EWservPanicParentDeleted); + if (*pData.UInt==0) + iBackupsRequested|=EWindowBackupAreaBehind; //For backwards compatibility + else + iBackupsRequested|=*pData.UInt; + break; + case EWsWinOpFadeBehind: + { + if (!iParent) + OwnerPanic(EWservPanicParentDeleted); + TUint8 blackMap; + TUint8 whiteMap; + iScreen->GetFadingParams(blackMap,whiteMap); + SetFadeBehind(*pData.Bool); + TWalkWindowTreeSetFaded wwt(*pData.Bool,this,blackMap,whiteMap); + WalkWindowTree(wwt,EWalkBehind); + if (CWsTop::IsFadeEnabled()) + { + Screen()->AcceptFadeRequest( this, *pData.Bool, ETrue, EFalse ); + } + } + break; + case EWsWinOpGetIsFaded: + SetReply(iFadeCount); + break; + case EWsWinOpGetIsNonFading: + SetReply(iFlags&EFlagNonFadingWindow); + break; + case EWsWinOpMoveToGroup: + if (!iParent) + OwnerPanic(EWservPanicParentDeleted); + if (iParent->WinType()!=EWinTypeGroup) + OwnerPanic(EWservPanicNotTopClient); + DoMoveWindowToGroupL(*pData.Int); + break; + case EWsWinOpTestLowPriorityRedraw: + { + // This is purely for testing purposes + // Returns the redraw priority + TUint priority=0; + TPckgBuf priBuf; + priority=WsOwner()->RedrawQueue()->RedrawPriority((CWsWindowRedraw*)this->iRedraw); + priBuf()=priority; + CWsClient::ReplyBuf(priBuf); + } + break; + case EWsWinOpEnableVisibilityChangeEvents: + iFlags |= EFlagGeneratesVisibilityEvents; + if (iFlags&EFlagActive) + { + iScreen->DoRedrawNow(); + PossibleVisibilityChangedEvent(ETrue); + } + break; + case EWsWinOpDisableVisibilityChangeEvents: + iFlags &= ~EFlagGeneratesVisibilityEvents; + break; + case EWsWinOpSetTransparentRegion: + { + if (IsTranslucent()) + { + TInt recs=*pData.Int; + RWsRegion* reg=recs>0? GetRegionFromClientL(iWsOwner,recs) : new(ELeave) RWsRegion; + SetUserTransparentRegion(reg); + SetReply(KErrNone); + } + else + { + OwnerPanic(EWservPanicTransparencyObjNotCreated); + } + } + break; + case EWsWinOpSetTransparencyPolicy: + { + if (IsTranslucent()) + SetReply(KErrNone); + else + OwnerPanic(EWservPanicTransparencyObjNotCreated); + } + break; + case EWsWinOpSetTransparencyAlphaChannel: + { + iFlags |= static_cast(EFlagHasAlpha); + SetReply(KErrNone); + break; + } + default: + if (iRedraw->CommandL(aOpcode,pData)==EFalse) + { + OwnerPanic(EWservPanicOpcode); + } + } + } +#if defined(_DEBUG) + rootWindow->CheckTree(); +#endif + } + +void CWsClientWindow::GcActivated(CWsGc *aGc) + { + aGc->SetNextWinGc(iWinGcList); + iWinGcList=aGc; + } + +void CWsClientWindow::GcDeactivated(CWsGc *aGc) + { + if (aGc==iWinGcList) + iWinGcList=aGc->NextWinGc(); + else + { + CWsGc *gc=iWinGcList; + CWsGc *next; + FOREVER + { + next=gc->NextWinGc(); + WS_ASSERT_DEBUG(next!=NULL, EWsPanicBadActiveGcList); + if (next==aGc) + { + gc->SetNextWinGc(next->NextWinGc()); + break; + } + gc=next; + } + } + aGc->SetNextWinGc(NULL); + } + +void CWsClientWindow::ReactivateGcs() + { + for (CWsGc * gc = iWinGcList; gc; gc = gc->NextWinGc()) + { + gc->Reactivate(); + } + } + +void CWsClientWindow::OffsetUserTransparentRegion(const TPoint& aOffset) + { + if (iUserDefinedTransparentRegion) + { + iUserDefinedTransparentRegion->Offset(aOffset); + } + } + +void CWsClientWindow::SetUserTransparentRegion(RWsRegion* aRegion) + { + if (iUserDefinedTransparentRegion) + { + iUserDefinedTransparentRegion->Close(); + delete iUserDefinedTransparentRegion; + iUserDefinedTransparentRegion = 0; + } + + if (aRegion) + { + aRegion->Offset(iOrigin); + iUserDefinedTransparentRegion=aRegion; + } + + SetUserOpaqueRegion(); + } + +void CWsClientWindow::SetUserOpaqueRegion() + { + if (iUserDefinedOpaqueRegion) + { + iUserDefinedOpaqueRegion->Close(); + delete iUserDefinedOpaqueRegion; + iUserDefinedOpaqueRegion = 0; + } + if (iUserDefinedTransparentRegion) + { + iUserDefinedOpaqueRegion=new RWsRegion; + if (iUserDefinedOpaqueRegion) + { + iUserDefinedOpaqueRegion->Copy(*iBaseArea); + iUserDefinedOpaqueRegion->SubRegion(*iUserDefinedTransparentRegion); + if (iUserDefinedOpaqueRegion->CheckError() || iUserDefinedOpaqueRegion->Count() == 0) + { + iUserDefinedOpaqueRegion->Close(); + delete iUserDefinedOpaqueRegion; + iUserDefinedOpaqueRegion = 0; + } + } + } + } + +TUint CWsClientWindow::RedrawPriority(TInt *aShift) const + { + if (IsTopClientWindow()) + { + TUint ordinalPos=OrdinalPosition(EFalse); + if (ordinalPos>KWinRedrawPriMaxOrdinal) // Algorithm only works for upto KWinRedrawPriMaxOrdinal windows, + ordinalPos=KWinRedrawPriMaxOrdinal; // make all windows after this equal in priority + if (aShift) + *aShift=KWinRedrawPriMaxLevel; + return(ordinalPos<<(KWinRedrawPriMaxLevel*KWinRedrawPriBitsPerLevel)); + } + else + { + TUint ordinalPos=OrdinalPosition(EFalse)+1; + if (ordinalPos>KWinRedrawPriMaxOrdinal) // Algorithm only works upto 15 , make all windows after 15 equal in priority + ordinalPos=KWinRedrawPriMaxOrdinal; + TInt shift; + TUint parent=((CWsClientWindow *)iParent)->RedrawPriority(&shift); + if (shift>0) + shift--; + if (aShift) + *aShift=shift; + return(parent+(ordinalPos<<(shift*KWinRedrawPriBitsPerLevel))); + } + } + +TDblQue *CWsClientWindow::PointerKeyList() const + { + return(iPointerKeyList); + } + +void CWsClientWindow::AddKeyRectL(const TRect &aRect, TInt aScanCode, TBool aActivatedByPointerSwitchOn) + { + if (!iPointerKeyList) + iPointerKeyList=new(ELeave) TDblQue(_FOFF(TPointerKeyList,iQue)); + TPointerKeyList *pkl=new(ELeave) TPointerKeyList(); + iPointerKeyList->AddLast(*pkl); + pkl->iRect=aRect; + pkl->iScanCode=aScanCode; + pkl->iActivatedByPointerSwitchOn=aActivatedByPointerSwitchOn; + } + +void CWsClientWindow::RemoveAllKeyRects() + { + if (iPointerKeyList) + { + TPointerKeyList *pkl=NULL; + for(TDblQueIter iter(*iPointerKeyList);(pkl=iter++)!=NULL;) + { + pkl->iQue.Deque(); + delete pkl; + } + delete iPointerKeyList; + iPointerKeyList=NULL; + } + } + +TBool CWsClientWindow::IsHidden() + { + return (!IsVisible()) || VisibleRegion().IsEmpty(); + } + +void CWsClientWindow::SetFaded(TBool aFade,TUint8 aBlackMap,TUint8 aWhiteMap) + { + iBlackMap=aBlackMap; + iWhiteMap=aWhiteMap; + if (iAbsoluteFading) + { + if (aFade) + { + iFadeCount = 1; + } + else + { + iFadeCount = 0; + } + } + else + { + if (aFade) + { + ++iFadeCount; + } + else if (iFadeCount > 0) + { + --iFadeCount; + } + } + } + +void CWsClientWindow::ResetHiddenFlagsInParentAndChildren() + { + ResetHiddenFlag(); + for(CWsClientWindow* child=Child();child;child=child->NextSibling()) + { + child->ResetHiddenFlagsInParentAndChildren(); + } + } + +const TRegion& CWsClientWindow::WindowArea() const + { + return *iBaseArea; + } + +void CWsClientWindow::Invalidate(const TRect * aRect) + { + iRedraw->Invalidate(aRect); + } + +void CWsClientWindow::ScheduleRegionUpdate(const TRegion* aDefinitelyDirty) + { + if (IsVisible()) + { + iScreen->ScheduleRegionUpdate(aDefinitelyDirty); + } + } + +TBool CWsClientWindow::IsDSAHost() const + { + TBool res = CWsWindow::IsDSAHost(); + if ( !res ) + { // check for grace period when DSA is being restarted (after aborting but before client started DSA again) + res = Screen()->IsDSAClientWindow( this ); + } + return res; + } +void CWsClientWindow::SetScreenDeviceValidState(TBool aState) + { + if (SetScreenDeviceValidStateFlag(aState)) + ResetHiddenFlags(); + } + +TBool CWsClientWindow::SetScreenDeviceValidStateFlag(TBool aState) + { + TBool isSet=iFlags&EFlagScreenDeviceInvalid; + if (!isSet==!aState) + { + if (aState) + iFlags&=~EFlagScreenDeviceInvalid; + else + iFlags|=EFlagScreenDeviceInvalid; + return ETrue; + } + return EFalse; + } + +void CWsClientWindow::DoMoveWindowToGroupL(TInt aIdentifier) + { + CWsWindowGroup* group=CWsWindowGroup::WindowGroupFromIdentifierL(aIdentifier); + if (group==iParent) + return; + if (group->WsOwner()!=WsOwner()) + User::Leave(KErrNotFound); + ChangeWindowPosition(0, group); + CWsTop::TriggerRedraws(RootWindow()); + } + +void CWsClientWindow::SetInactive() + { + iFlags&=~EFlagActive; + ResetHiddenFlags(); + } +