--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/javauis/lcdui_akn/lcdgr/src/LcdWindowSurface.cpp Tue Apr 27 16:30:29 2010 +0300
@@ -0,0 +1,429 @@
+/*
+* Copyright (c) 2005 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 <coemain.h>
+#include <coecntrl.h>
+#include <reflcdui.h>
+#include <hal.h>
+
+#include "LcdWindowSurface.h"
+
+/**
+ * Utility function to query the frame buffer attributes for screen aScreenNo
+ * when set to displayMode aMode.
+ */
+LOCAL_C TInt GetScreenInfo(TAcceleratedBitmapInfo& aScreen, TInt aScreenNo, TDisplayMode aMode);
+
+CLcdWindowSurface* CLcdWindowSurface::NewL(CCoeControl& aWindow, MDirectContainer& aContainer, TBool aUpdate)
+{
+ CLcdWindowSurface* surface = new(ELeave) CLcdWindowSurface(aContainer, aUpdate);
+ CleanupStack::PushL(surface);
+ surface->ConstructL(aWindow);
+ CleanupStack::Pop(surface);
+ return surface;
+}
+
+CLcdWindowSurface::CLcdWindowSurface(MDirectContainer& aContainer, TBool aUpdate)
+ : iContainer(&aContainer)
+ , iWsSession(CCoeEnv::Static()->WsSession())
+ , iWsDevice(*CCoeEnv::Static()->ScreenDevice())
+ , iUpdate(aUpdate)
+{
+ ASSERT(iContainer);
+ //
+ // Risk of configuration problem if screen mode does not match the configured
+ // primary mode. In that case it would not be possible to use any of the
+ // transforming blitters and a frame buffer bitmap would have to be used.
+ //
+ // Solution is to provide opaque converter blitters from/to all target modes,
+ // or generic blitter (as BITGDI) via XRGB8888.
+ //
+ iImageType.iColorMode = iWsDevice.DisplayMode();
+ iImageType.iAlphaMode = ENone;
+ iImageType.iTransparency = ETransparencyNone;
+}
+
+CLcdWindowSurface::~CLcdWindowSurface()
+{
+ if (iContainer)
+ {
+ iContainer->MdcRemoveContent(this);
+ }
+ Deactivate();
+ delete iWsContext;
+ iEmptyRegion.Close();
+ iUpdateRegion.Close();
+}
+
+void CLcdWindowSurface::ConstructL(CCoeControl& aWindow)
+{
+ iContainer->MdcAddContent(this);
+ User::LeaveIfError(iWsDevice.CreateContext(iWsContext));
+ if (aWindow.IsBackedUp())
+ {
+ User::Leave(KErrArgument);
+ }
+ else
+ {
+ ActivateL((RWindow*)aWindow.DrawableWindow());
+ }
+ TRect bounds(aWindow.PositionRelativeToScreen(), aWindow.Size());
+ iBounds = bounds;
+ iVisible = aWindow.IsVisible();
+}
+
+CLcdSurface::TSurfaceType CLcdWindowSurface::Type() const
+{
+ return CLcdSurface::EWindowSurface;
+}
+
+void CLcdWindowSurface::Update(const TRect& aRect)
+{
+ if (iStarted && iUpdate && iVisible)
+ {
+ ASSERT(iWsAccess);
+
+ iUpdateRegion.AddRect(aRect);
+
+ (void) DoUpdate();
+ }
+}
+
+TInt CLcdWindowSurface::DoUpdate()
+{
+ CFbsScreenDevice* device = iWsAccess->ScreenDevice();
+ RRegion& visibleRegion = *iWsAccess->DrawingRegion();
+
+ const TInt updateCount = iUpdateRegion.Count();
+ const TInt visibleCount = visibleRegion.Count();
+ if (updateCount && visibleCount)
+ {
+ iUpdateRegion.Intersect(visibleRegion);
+ device->Update(iUpdateRegion);
+ }
+ iUpdateRegion.Clear();
+
+ return updateCount;
+}
+
+void CLcdWindowSurface::Begin(TAcceleratedBitmapInfo& aBitmap, TBitmapLockCount& /*aCount*/)
+{
+ if (!iStarted && iEnabled)
+ {
+ iStarted = Start();
+ }
+
+#ifdef _DEBUG
+ if (iStarted)
+ {
+ ASSERT(NULL != iScreen.iAddress);
+ }
+ else
+ {
+ ASSERT(NULL == iScreen.iAddress);
+ }
+#endif
+
+ aBitmap = iScreen;
+}
+
+void CLcdWindowSurface::End(TBitmapLockCount& /*aCount*/)
+{
+}
+
+TRect CLcdWindowSurface::Bounds() const
+{
+ return iBounds;
+}
+
+RRegion* CLcdWindowSurface::VisibleRegion() const
+{
+ if (iStarted)
+ {
+ ASSERT(iWsAccess);
+ return iWsAccess->DrawingRegion();
+ }
+ return const_cast<RRegion*>(&iEmptyRegion);
+}
+
+CBitmapContext* CLcdWindowSurface::Context() const
+{
+ CBitmapContext* context = iWsAccess->Gc();
+ if (context)
+ {
+ return context;
+ }
+ return iWsContext;
+}
+
+TImageType CLcdWindowSurface::ImageType() const
+{
+ return iImageType;
+}
+
+TBool CLcdWindowSurface::Start()
+{
+ ASSERT(iWsAccess);
+ TRAPD(err, iWsAccess->StartL());
+ if (KErrNone == err)
+ {
+ const TInt screenNo = iWsDevice.GetScreenNumber();
+
+ //
+ // DisplayMode may change dynamically on some devices.
+ //
+ const TDisplayMode displayMode = iWsDevice.DisplayMode();
+
+ if (displayMode != iImageType.iColorMode)
+ {
+ // this surface doesn't match the current screen mode.
+ // Any lcdgd device created for this surface will fail.
+ err = KErrNotSupported;
+ }
+ else
+ {
+ //
+ // Hardware bitmaps handles that reference screen framebuffers
+ // start at -1 decending with the correspondance:
+ //
+ // handle = -(1 + screenNo) == ~screenNo
+ //
+ RHardwareBitmap screenHwb(~screenNo);
+
+ TAcceleratedBitmapSpec screenSpec(screenHwb);
+
+ err = screenSpec.GetInfo(iScreen);
+ if (err)
+ {
+ // hardware bitmaps screen references may not be supported on
+ // all ports. In that case we fall back to querying the HAL
+ // in GetScreenInfo().
+ //
+ err = GetScreenInfo(iScreen, screenNo, displayMode);
+ }
+ }
+
+ if (err)
+ {
+ Mem::FillZ(&iScreen, sizeof(iScreen));
+ iWsAccess->Cancel();
+ }
+
+ //
+ // Record current scale, size and rotation settings
+ //
+ TPixelsAndRotation sizeAndRotation;
+ iWsDevice.GetDefaultScreenSizeAndRotation(sizeAndRotation);
+
+ // screen size and orientation determine coordinate transform
+ // we should be using during rendering.
+ iScreenCoords.iSize = sizeAndRotation.iPixelSize;
+ iScreenCoords.iOrientation = sizeAndRotation.iRotation;
+ iScreenCoords.iScale = iWsDevice.GetCurrentScreenModeScale();
+ iScreenCoords.iOrigin = iWsDevice.GetDefaultScreenModeOrigin();
+ }
+
+ return (KErrNone == err);
+}
+
+void CLcdWindowSurface::ActivateL(RWindow* aWindow)
+{
+ if (iWsWindow)
+ {
+ Deactivate();
+ }
+ iWsWindow = aWindow;
+ if (iWsWindow)
+ {
+ iWsContext->Activate(*iWsWindow);
+ iWsAccess = CDirectScreenAccess::NewL(iWsSession, iWsDevice, *iWsWindow, *this);
+ iEnabled = ETrue;
+ }
+}
+
+void CLcdWindowSurface::Deactivate()
+{
+ if (iWsWindow && iWsContext)
+ {
+ iWsContext->Deactivate();
+ }
+ delete iWsAccess;
+ iWsAccess = NULL;
+ iStarted = EFalse;
+ iEnabled = EFalse;
+ iWsWindow = NULL;
+}
+
+/* CONTENT INTERFACE */
+
+/**
+Notify content that container visiblity has changed. The content must not
+be displayed when it's container is invisible.
+@param "aVisible" ETrue if the container is visible, EFalse if it is invisible.
+*/
+void CLcdWindowSurface::MdcContainerVisibilityChanged(TBool aVisible)
+{
+ iVisible = aVisible;
+}
+
+/**
+Notify content that the container bounds have changed.
+@param "aRect" Maximum area the content can occupy in screen co-ordinates.
+The content should be clipped to this area.
+*/
+void CLcdWindowSurface::MdcContentBoundsChanged(const TRect& aRect)
+{
+ iBounds = aRect;
+}
+
+/**
+Notify content that its display area has changed.
+This should only be called when the content is displayed on an Item.
+@param "aDisplayRect" Display area in Item co-ordinates.
+@param "aScreenRect" Display area in screen co-ordinates.
+*/
+void CLcdWindowSurface::MdcItemContentRectChanged(const TRect& /*aContentRect*/,const TRect& /*aScreenRect*/)
+{
+ ASSERT(EFalse);
+}
+
+void CLcdWindowSurface::MdcContainerDestroyed()
+{
+ Deactivate();
+ iContainer = NULL;
+}
+
+
+void CLcdWindowSurface::MdcAbortDSA()
+{
+ // Empty implementation.
+ // This DSA event is delivered via AbortNow.
+}
+
+
+void CLcdWindowSurface::MdcResumeDSA()
+{
+ // Empty implementation.
+ // This DSA event is delivered via Restart.
+}
+
+
+/**
+ * MDirectScreenAccess
+ */
+void CLcdWindowSurface::AbortNow(RDirectScreenAccess::TTerminationReasons /*aReasons*/)
+{
+ iWsAccess->Cancel();
+ iStarted=EFalse;
+ iEnabled=EFalse;
+}
+
+void CLcdWindowSurface::Restart(RDirectScreenAccess::TTerminationReasons /*aReasons*/)
+{
+ //
+ // Don't bother restarting until next Begin comes through.
+ //
+ iEnabled=ETrue;
+}
+
+RWindow* CLcdWindowSurface::Window() const
+{
+ return iWsWindow;
+}
+
+void CLcdWindowSurface::GetCoordinateSystem(TCoordinateSystem& aCoords) const
+{
+ aCoords = iScreenCoords;
+}
+
+LOCAL_C TUint Log2(TInt aVal)
+{
+ ASSERT(aVal > 0);
+ TUint v = 1;
+ TInt x = 0;
+ while (v < aVal)
+ {
+ v <<= 1;
+ ++x;
+ }
+ return x;
+}
+
+LOCAL_C TInt GetScreenInfo(TAcceleratedBitmapInfo& aScreen, TInt aScreenNo, TDisplayMode aMode)
+{
+ // 'current mode' attributes. These should not need the
+ // displayMode but this could depend on video driver.
+ //
+ TInt err = 0;
+ TInt mode = 0;
+ TInt address = 0;
+ TInt width = 0;
+ TInt height = 0;
+
+ // 'request mode' attributes. These need the displayMode
+ // passed in the attribute value argument.
+ TInt offset = aMode;
+ TInt linePitch = aMode;
+ TInt bpp = aMode;
+
+ err = HAL::Get(aScreenNo, HALData::EDisplayMode, mode);
+ ASSERT(mode == (TInt)aMode);
+
+ if (KErrNone == err)
+ {
+ err = HAL::Get(aScreenNo, HALData::EDisplayMemoryAddress, address);
+ }
+
+ if (KErrNone == err)
+ {
+ err = HAL::Get(aScreenNo, HALData::EDisplayXPixels, width);
+ }
+
+ if (KErrNone == err)
+ {
+ err = HAL::Get(aScreenNo, HALData::EDisplayYPixels, height);
+ }
+
+ if (KErrNone == err)
+ {
+ offset = mode; // Parameter must be set to mode on input.
+ err = HAL::Get(aScreenNo, HALData::EDisplayOffsetToFirstPixel, offset);
+ }
+
+ if (KErrNone == err)
+ {
+ linePitch = mode; // Parameter must be set to mode on input.
+ err = HAL::Get(aScreenNo, HALData::EDisplayOffsetBetweenLines, linePitch);
+ }
+
+ if (KErrNone == err)
+ {
+ bpp = mode; // Parameter must be set to mode on input.
+ err = HAL::Get(aScreenNo, HALData::EDisplayBitsPerPixel, bpp);
+ }
+
+ aScreen.iPhysicalAddress = NULL;
+ aScreen.iDisplayMode = aMode;
+ aScreen.iAddress = reinterpret_cast<TUint8*>(address + offset);
+ aScreen.iLinePitch = linePitch;
+ aScreen.iSize.iWidth = width;
+ aScreen.iSize.iHeight = height;
+ aScreen.iPixelShift = Log2(bpp);
+
+ return err;
+}