egl/eglinterface/src/eglwindowinterface.cpp
author hgs
Thu, 09 Sep 2010 10:13:45 +0300
changeset 171 414d4b727fd9
permissions -rw-r--r--
201034

// Copyright (c) 2010 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:
//


/**
 @file
 @publishedPartner
 @prototype
*/


#include "eglwindowinterface.h"
#include "eglwindow.h"
#include <e32base.h>
#include <w32std.h>
#include <hal.h>


EXPORT_C TEglWindowInterface::TEglWindowInterface(EGLNativeWindowType aNativeWindow) :
    iEglWindow(reinterpret_cast<REglWindowBase*>(aNativeWindow))
    {
    }


EXPORT_C TBool TEglWindowInterface::IsValid() const
    {
    if(iEglWindow->IsRWindow())
        {
        TInt wsHandle = reinterpret_cast<const RWindow*>(iEglWindow)->WsHandle();
        return (wsHandle != 0);
        }
    else
        {
        return iEglWindow->IsValid();
        }
    }


EXPORT_C TSize TEglWindowInterface::SizeInPixels() const
    {
    if(iEglWindow->IsRWindow())
        {
        return reinterpret_cast<const RWindow*>(iEglWindow)->Size();
        }
    else
        {
        return iEglWindow->SizeInPixels();
        }
    }


EXPORT_C TSize TEglWindowInterface::SizeInTwips() const
    {
    if(iEglWindow->IsRWindow())
        {
        //This is a simple solution to get the twip size of an RWindow.
        //A temporary CWsScreenDevice is constructed for the screen that
        //the RWindow exists on and is used to convert the size in pixels
        //to a size in twips. The temporary CWsScreenDevice is then destructed.
        //If this is found to be non-performant, we could use a TLS thread 
        //singleton that lazily creates screen devices and maintains a list
        //thoughout its lifetime. The singleton could be destroyed though a
        //static function on TEglWindowInterface as part of eglReleaseThread().
        //This represents more complexity and should only be considered as an
        //optimisation if it is found to be neccessary. Note that use of the HAL
        //interface is not really an option, since we need to find the pixel 
        //size of the screen and this could be virtualised by the screen.
    
        const RWindow* window = reinterpret_cast<const RWindow*>(iEglWindow);
        RWsSession* winSession = window->Session();
        EGL_WINDOW_ASSERT_DEBUG(winSession, EEglWindowPanicRWindowHasNoSession);
        
        //Do a placement new to avoid the possible KErrNoMemory error.
        TUint8 screenDevMem[sizeof(CWsScreenDevice)];
        CWsScreenDevice* screenDev = new (screenDevMem) CWsScreenDevice(*winSession);

        //Nothing we can do about this error.
        TInt err = screenDev->Construct(window->ScreenNumber());
        if(err != KErrNone)
            {
            screenDev->~CWsScreenDevice();
            return TSize(0,0);
            }
        
        TSize pixelSize = window->Size();
        TInt twipWidth = screenDev->HorizontalPixelsToTwips(pixelSize.iWidth);
        TInt twipHeight = screenDev->VerticalPixelsToTwips(pixelSize.iHeight);
        TSize twipSize(twipWidth, twipHeight);
        
        screenDev->~CWsScreenDevice();
        return twipSize;
        }
    else
        {
        return iEglWindow->SizeInTwips();
        }
    }


EXPORT_C TInt TEglWindowInterface::ScreenNumber() const
    {
    if(iEglWindow->IsRWindow())
        {
        return reinterpret_cast<const RWindow*>(iEglWindow)->ScreenNumber();
        }
    else
        {
        return iEglWindow->ScreenNumber();
        }
    }


EXPORT_C void TEglWindowInterface::SetBackgroundColor(TRgb aColor, TBool aTriggerRedraw)
    {
    if(iEglWindow->IsRWindow())
        {
        RWindow* window = reinterpret_cast<RWindow*>(iEglWindow);
        window->SetBackgroundColor(aColor);
        if(aTriggerRedraw)
            {
            window->Invalidate();
            }
        }
    else
        {
        iEglWindow->SetBackgroundColor(aColor, aTriggerRedraw);
        }
    }


EXPORT_C TInt TEglWindowInterface::SetBackgroundSurface(const TSurfaceConfiguration &aConfiguration, TBool aTriggerRedraw)
    {
    if(iEglWindow->IsRWindow())
        {
#ifdef _DEBUG
        TSurfaceId surface;
        aConfiguration.GetSurfaceId(surface);
        EGL_WINDOW_ASSERT_DEBUG(!surface.IsNull(), EEglWindowPanicInvalidSurface);
#endif
        return reinterpret_cast<RWindow*>(iEglWindow)->SetBackgroundSurface(aConfiguration, aTriggerRedraw);
        }
    else
        {
        return iEglWindow->SetBackgroundSurface(aConfiguration, aTriggerRedraw);
        }
    }


EXPORT_C void TEglWindowInterface::RemoveBackgroundSurface(TBool aTriggerRedraw)
    {
    if(iEglWindow->IsRWindow())
        {
        RWindow* window = reinterpret_cast<RWindow*>(iEglWindow);
        RWsSession* winSession = window->Session();
        EGL_WINDOW_ASSERT_DEBUG(winSession, EEglWindowPanicRWindowHasNoSession);    
        window->RemoveBackgroundSurface(aTriggerRedraw);
        }
    else
        {
        iEglWindow->RemoveBackgroundSurface(aTriggerRedraw);
        }
    }