--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/windowing/windowserver/nonnga/SERVER/TCURSOR.CPP Tue Feb 02 01:47:50 2010 +0200
@@ -0,0 +1,381 @@
+// 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:
+// The text cursor
+//
+//
+
+#include <e32std.h>
+#include "server.h"
+#include "tcursor.h"
+#include "windowgroup.h"
+#include "wstop.h"
+#include "panics.h"
+#include "offscreenbitmap.h"
+#include "EVENT.H"
+#include "graphics/windowserverconstants.h"
+
+void RWsTextCursor::ConstructL(CWsWindowGroup *aGroupWin)
+ {
+ iInternalFlags = 0;
+ iGroupWin=aGroupWin;
+ iCustomTextCursor = NULL;
+ }
+
+void RWsTextCursor::Close()
+ {
+ iDrawRegion.Close();
+ Cancel();
+ }
+
+void RWsTextCursor::SetL(const TWsWinCmdSetTextCursor &aSet, TBool aClipped)
+ {
+ if (aSet.cursor.iType < TTextCursor::ETypeFirst ||
+ (aSet.cursor.iType > TTextCursor::ETypeLast &&
+ aSet.cursor.iType <= TTextCursor::ETypeLastBasic) ||
+ (aSet.cursor.iFlags&static_cast<TUint>(ETextCursorPrivateFlags)))
+ {
+ Cancel();
+ iGroupWin->OwnerPanic(EWservPanicInvalidTextCursor);
+ }
+ else
+ {
+ CWsClientWindow* win = NULL;
+ iGroupWin->WsOwner()->HandleToClientWindow(aSet.window, &win);
+
+ // Check window is a child of the group window
+ CWsWindowBase* searchWin = NULL;
+ for(searchWin=win; searchWin->WinType()!=EWinTypeGroup; searchWin=searchWin->BaseParent())
+ {}
+ if (iGroupWin != searchWin)
+ {
+ Cancel();
+ iGroupWin->OwnerPanic(EWservPanicWindow);
+ }
+
+ TPoint pos(aSet.pos.iX, aSet.pos.iY-aSet.cursor.iAscent);
+ TSize size(aSet.cursor.iWidth, aSet.cursor.iHeight);
+ TUint flags = aSet.cursor.iFlags;
+ TInt type = aSet.cursor.iType;
+ TRect clipRect = iClipRect;
+ TRgb color = aSet.cursor.iColor;
+ CWsCustomTextCursor* customTextCursor = iCustomTextCursor;
+ TBool changed = EFalse;
+
+ TPoint clipOrigo;
+ TSize clipSize;
+
+ if (type > TTextCursor::ETypeLastBasic)
+ {
+ changed = ETrue;
+
+ customTextCursor = CWsClient::FindCustomTextCursor(type);
+ if (!customTextCursor)
+ {
+ Cancel();
+ iGroupWin->OwnerPanic(EWservPanicNoCustomTextCursor);
+ return;
+ }
+
+ if( !customTextCursor->HasSpriteMember() )
+ {
+ iGroupWin->OwnerPanic(EWservPanicNoSpriteMember);
+ return;
+ }
+
+ TInt yAdjust=0;
+ switch (customTextCursor->Alignment())
+ {
+ case RWsSession::ECustomTextCursorAlignTop:
+ break;
+ case RWsSession::ECustomTextCursorAlignBaseline:
+ yAdjust = aSet.cursor.iAscent-1;
+ break;
+ case RWsSession::ECustomTextCursorAlignBottom:
+ yAdjust = aSet.cursor.iHeight-1;
+ break;
+ default:
+ Cancel();
+ iGroupWin->OwnerPanic(EWservPanicCustomTextCursorAlign);
+ return;
+ }
+ pos.iY += yAdjust;
+ // Start with a clipping rect to be the whole window
+ // relative cursor pos and shrink down to what we want
+ clipOrigo = -pos;
+ clipSize = win->Size();
+ if (flags & TTextCursor::EFlagClipHorizontal)
+ {
+ clipOrigo.iX = 0;
+ clipSize.iWidth = size.iWidth;
+ }
+ if (flags & TTextCursor::EFlagClipVertical)
+ {
+ clipOrigo.iY = -yAdjust;
+ clipSize.iHeight = aSet.cursor.iHeight;
+ }
+ }
+ else
+ {
+ customTextCursor = NULL;
+ }
+
+ if (aClipped)
+ {
+ flags|=ETextCursorFlagClipped;
+ clipRect=aSet.rect;
+ }
+
+ if (pos != iPos || size != iSize || iType != type ||
+ flags != iFlags || clipRect != iClipRect || color != iColor ||
+ customTextCursor != iCustomTextCursor || win != iWin)
+ {
+ // There is a change in the cursor.
+ changed = ETrue;
+ }
+
+ if (iInternalFlags&EHasFocus && changed)
+ {
+ TCursorSprite::Hide();
+ }
+
+ iPos = pos;
+ iSize = size;
+ iType = type;
+ iFlags= flags;
+ iClipRect = clipRect;
+ iColor = color;
+ iCustomTextCursor = customTextCursor;
+ iWin = win;
+ if (customTextCursor && iInternalFlags&EHasFocus)
+ {
+ customTextCursor->CompleteL(win, !(flags&TTextCursor::EFlagNoFlash), flags & (TTextCursor::EFlagClipHorizontal | TTextCursor::EFlagClipVertical), clipOrigo, clipSize);
+ customTextCursor->SetPositionNoRedraw(pos);
+ }
+
+ if (iInternalFlags&EHasFocus && changed)
+ {
+ TCursorSprite::SetCurrentCursor(this, win);
+ }
+ }
+ }
+
+void RWsTextCursor::Cancel()
+ {
+ if (iType!=TTextCursor::ETypeNone)
+ {
+ if (iInternalFlags&EHasFocus)
+ TCursorSprite::SetFocus(NULL);
+ iType=TTextCursor::ETypeNone;
+ iWin=NULL;
+ }
+ }
+
+void RWsTextCursor::Disable()
+ {
+ if (iWin)
+ {
+ TCursorSprite::Hide();
+ }
+ }
+
+void RWsTextCursor::Enable()
+ {
+ if (iWin)
+ {
+ TCursorSprite::Reveal();
+ }
+ }
+
+void RWsTextCursor::LostFocus()
+ {
+ TCursorSprite::SetFocus(NULL);
+ iInternalFlags &= ~EHasFocus;
+ }
+
+void RWsTextCursor::ReceivedFocus()
+ {
+ iInternalFlags |= EHasFocus;
+ if (iType!=TTextCursor::ETypeNone && iWin)
+ {
+ TCursorSprite::SetFocus(this,iWin);
+ if (iCustomTextCursor)
+ {
+ iCustomTextCursor->SetPositionNoRedraw(iPos);
+ }
+ }
+ }
+
+TRect RWsTextCursor::RectRelativeToScreen() const
+ {
+ TRect rect;
+ rect.iTl=iPos+iWin->Origin();
+ rect.iBr=rect.iTl+iSize;
+ return(rect);
+ }
+
+void RWsTextCursor::doDraw(CFbsBitGc* aGc, const TRegion& aRegion)
+ {
+ TRegionFix<1> justInCase;
+ const TRegion *pr= &aRegion;
+ if (aRegion.CheckError())
+ {
+ justInCase.AddRect(iWin->AbsRect());
+ pr= &justInCase;
+ }
+ if (!pr->IsEmpty())
+ {
+ aGc->SetUserDisplayMode(iWin->DisplayMode());
+ aGc->SetDitherOrigin(iWin->Origin());
+ aGc->SetDrawMode(CGraphicsContext::EDrawModeXOR);
+ switch (iType)
+ {
+ case TTextCursor::ETypeRectangle:
+ {
+ aGc->SetBrushStyle(CGraphicsContext::ESolidBrush);
+ aGc->SetPenStyle(CGraphicsContext::ENullPen);
+ aGc->SetBrushColor(iColor);
+ }
+ break;
+ case TTextCursor::ETypeHollowRectangle:
+ {
+ aGc->SetBrushStyle(CGraphicsContext::ENullBrush);
+ aGc->SetPenStyle(CGraphicsContext::ESolidPen);
+ aGc->SetPenColor(iColor);
+ }
+ break;
+ default:
+ WS_PANIC_ALWAYS(EWsPanicInvalidCursorType);
+ }
+ aGc->SetClippingRegion(pr);
+ aGc->DrawRect(RectRelativeToScreen());
+ aGc->SetUserDisplayMode(ENone);
+
+ TWindowServerEvent::NotifyScreenDrawingEvent(pr);
+ }
+ }
+
+void RWsTextCursor::Draw(CFbsBitGc* aGc, const TRegion& aRegion)
+ {
+ iDrawRegion.Copy(iWin->VisibleRegion());
+ if (iFlags&ETextCursorFlagClipped)
+ {
+ TRect rect(iClipRect);
+ rect.Move(iWin->Origin());
+ iDrawRegion.ClipRect(rect);
+ }
+
+ // Need to clip against a possible recent screen size change.
+ iDrawRegion.ClipRect(iWin->Screen()->DrawDevice()->SizeInPixels());
+
+
+ RWsRegion tmpRegion;
+ tmpRegion.Intersection(iDrawRegion, aRegion);
+ if (tmpRegion.CheckError())
+ doDraw(aGc, iDrawRegion);
+ else
+ {
+ if (!tmpRegion.IsEmpty())
+ {
+ doDraw(aGc, tmpRegion);
+ }
+ }
+ tmpRegion.Close();
+ }
+
+void RWsTextCursor::WindowDisconnected(CWsWindow *aWindow)
+ {
+ if (iWin==aWindow)
+ Cancel();
+ }
+
+TBool RWsTextCursor::IsStandardCursorActive()
+ {
+ return TCursorSprite::IsStandardCursorActive();
+ }
+
+TBool RWsTextCursor::IsFlashing() const
+ {
+ return !(iFlags&TTextCursor::EFlagNoFlash);
+ }
+
+void RWsTextCursor::ScheduleReDrawNow()
+ {
+ iGroupWin->Screen()->ScheduleAnimation(RectRelativeToScreen(), 0, 0, 0);
+ }
+
+
+// Cursor sprite handling
+
+TBool TCursorSprite::iHidden=ETrue;
+RWsTextCursor *TCursorSprite::iCurrentCursor=NULL;
+
+//
+
+// Hide / Reveal text cursors.
+void TCursorSprite::Hide()
+ {
+ if (!iHidden && iCurrentCursor)
+ {
+ iHidden=ETrue;
+ if (iCurrentCursor->iCustomTextCursor)
+ {
+ iCurrentCursor->iCustomTextCursor->Deactivate();
+ }
+ else
+ {
+ iCurrentCursor->ScheduleReDrawNow();
+ }
+ }
+ }
+
+void TCursorSprite::Reveal()
+ {
+ if(iHidden && iCurrentCursor)
+ {
+ iHidden=EFalse;
+ if (iCurrentCursor->iCustomTextCursor)
+ {
+ iCurrentCursor->iCustomTextCursor->Activate();
+ }
+ else
+ {
+ iCurrentCursor->ScheduleReDrawNow();
+ }
+ }
+ }
+
+void TCursorSprite::SetFocus(RWsTextCursor* aFocus,CWsClientWindow* aWin/*=NULL*/)
+ {
+ if (iCurrentCursor!=aFocus)
+ {
+ Hide();
+ SetCurrentCursor(aFocus, aWin);
+ }
+ }
+
+void TCursorSprite::SetCurrentCursor(RWsTextCursor* aFocus, CWsClientWindow* aWin)
+ {
+ iCurrentCursor = aFocus;
+ if (aWin && iCurrentCursor && iCurrentCursor->iCustomTextCursor)
+ {
+ iCurrentCursor->iCustomTextCursor->SetWindow(aWin);
+ }
+ Reveal();
+ }
+
+TBool TCursorSprite::IsStandardCursorActive()
+ {
+ return iCurrentCursor && !iCurrentCursor->iCustomTextCursor && !iHidden;
+ }
+