--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/graphicsdeviceinterface/directgdi/src/directgdidriver.cpp Tue Feb 02 01:47:50 2010 +0200
@@ -0,0 +1,451 @@
+// Copyright (c) 2007-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:
+//
+
+#include "directgdipaniccodes.h" // Included first to resolve dependency
+
+#include <graphics/sgimage.h>
+#include <graphics/directgdiimagetarget.h>
+#include <graphics/directgdidrawablesource.h>
+#include <graphics/directgdipanics.h>
+#include <graphics/directgdidriverinternal.h>
+#include <e32svr.h>
+#include <u32hal.h>
+
+#include "directgdidriver.h"
+#include "directgditypes.h"
+#include "directgdidriverinternallibrary.inl"
+
+typedef TInt (*TDriverCreateFunction)(CDirectGdiDriverInternal*&, RLibrary);
+
+/**
+Returns the singleton instance of CDirectGdiDriver for the calling thread.
+
+@return Pointer to an opened CDirectGdiDriver object else NULL if a CDirectGdiDriver had not been opened yet.
+*/
+EXPORT_C CDirectGdiDriver* CDirectGdiDriver::Static()
+ {
+ return static_cast<CDirectGdiDriver*>(Dll::Tls());
+ }
+
+/**
+Creates a new CDirectGdiDriver object if one has not already been created in this thread.
+Performs any adaptation initialisation that is needed to allow the calling thread to use
+functionality provided by the new DirectGDI interfaces. Calling this method multiple times
+from the same client thread has no effect after the first call, other than to increase the
+open count.
+
+@see CDirectGdiDriver::Close()
+
+@pre None.
+@post The object reference counter is incremented. Adaptation resources for the
+calling thread are created and initialised. The new DirectGDI interfaces are ready
+to be used from the calling thread.
+
+@return KErrNone if successful, otherwise one of the system-wide error codes.
+*/
+EXPORT_C TInt CDirectGdiDriver::Open()
+ {
+ TInt err = KErrNone;
+ CDirectGdiDriver* self = Static();
+
+ // Check we're not already opened
+ if (!self)
+ {
+ self = new CDirectGdiDriver();
+ if (!self)
+ {
+ err = KErrNoMemory;
+ return err;
+ }
+
+#ifdef __WINS__
+ // Dynamically load DirectGDI adapter library.
+ // Under WINS two dlls will be available - directgdiadapter_sw.dll and directgdiadapter_vg.dll
+ // Need to select which dll to load. The value of the keyword SYMBIAN_GRAPHICS_DIRECTGDI_USE
+ // in the epoc.ini file will determine the dll to load.
+ // If this keyword does not appear in the epoc.ini file, the software version of
+ // directgdiadapter will be loaded by default.
+ _LIT(KVgAdapterDllName, "directgdiadapter_vg.dll");
+ _LIT(KSwAdapterDllName, "directgdiadapter_sw.dll");
+ TBool useOpenVg = EFalse;
+ UserSvr::HalFunction(EHalGroupEmulator, EEmulatorHalBoolProperty, (TAny*)"symbian_graphics_directgdi_use_openvg", &useOpenVg);
+ TPtrC libraryName;
+ if(useOpenVg)
+ {
+ libraryName.Set(KVgAdapterDllName);
+ }
+ else
+ {
+ libraryName.Set(KSwAdapterDllName);
+ }
+ RLibrary lib;
+ err = lib.Load(libraryName);
+ if (err != KErrNone)
+ {
+ delete self;
+ return (err==KErrNotFound ? KErrNotSupported : err);
+ }
+
+ // Create internal driver
+ err = self->CreateInternalDriver(lib);
+ if (err != KErrNone)
+ {
+ delete self;
+ lib.Close();
+ return err;
+ }
+#else
+ // Under armv5, the appropriate dll (software or vg) is determined at rom build time.
+ err = self->CreateInternalDriver();
+ if (err != KErrNone)
+ {
+ delete self;
+ return err;
+ }
+#endif
+
+ // Store a pointer to the new driver instance in thread local storage:
+ err = Dll::SetTls(self);
+ if (err != KErrNone)
+ {
+ delete self;
+ }
+ }
+
+ if (err == KErrNone)
+ {
+ ++(self->iOpenCount);
+ }
+
+ return err;
+ }
+
+/**
+Create the adaptation/internal object for this driver.
+
+@pre The adaptation/internal driver object has not been created yet.
+@post The adaptation/internal object has been created.
+
+@return KErrNone if successful, otherwise one of the system-wide error codes.
+ */
+#ifdef __WINS__
+TInt CDirectGdiDriver::CreateInternalDriver(const RLibrary& aLibrary)
+ {
+ // Function at ordinal 1 creates new CDirectGdiDriverInternal
+ TDriverCreateFunction create = reinterpret_cast<TDriverCreateFunction>(aLibrary.Lookup(1));
+ return create(iDriverInternal, aLibrary);
+ }
+#else
+TInt CDirectGdiDriver::CreateInternalDriver()
+ {
+ return CDirectGdiDriverInternal::New(iDriverInternal, RLibrary());
+ }
+#endif
+
+/**
+Performs adaptation termination which is needed to release any internal resources
+allocated by the calling thread. It will also perform an implicit Finish() by submitting
+all outstanding requests from the calling thread. A DirectGDI client's thread that
+uses the new DirectGDI interfaces must call this method at the end of its lifetime.
+
+@see CDirectGdiDriver::Open()
+
+@pre The driver is open from a call to Open().
+@post The object open count is decremented. If the open count reaches zero, any
+adaptation resources allocated to the calling thread must be released, and the CDirectGdiDriver
+object for the calling thread is destroyed.
+
+@panic DGDI 14, if Close() is called on a CDirectGdiDriver object that is not open.
+*/
+EXPORT_C void CDirectGdiDriver::Close()
+ {
+ GRAPHICS_ASSERT_ALWAYS(iOpenCount > 0, EDirectGdiPanicDriverOpenCountError);
+
+ if (--iOpenCount == 0)
+ {
+ // We call Finish() instead of Flush() because it will decrease the reference count
+ // of images used in DrawResource() (if any) and is guaranteed that it will complete.
+ // Flush() cannot guarantee completion so we can't decrement image reference counts.
+ Finish();
+
+ // Get the handle to the DLL used by iDriverInternal so that we can close
+ // it once iDriverInternal has been deleted.
+ RLibrary lib = iDriverInternal->Library();
+ delete this;
+ lib.Close();
+
+ // Free the space we saved for the driver singleton pointer in thead local storage
+ Dll::FreeTls();
+ }
+ }
+
+/**
+Ensures all outstanding requests on the calling thread are submitted for processing.
+The method immediately returns and does not wait until all outstanding requests are
+completely processed. Clients can continue issuing rendering requests after calling
+this method.
+
+@see CDirectGdiDriver::Finish()
+
+@pre CDirectGdiDriver object has been initialised for the calling thread.
+@post All outstanding requests have been submitted for processing.
+*/
+EXPORT_C void CDirectGdiDriver::Flush()
+ {
+ iDriverInternal->Flush();
+ }
+
+/**
+Ensures all outstanding rendering requests from the calling thread are submitted
+and processed. This method will wait until all the outstanding rendering requests
+have been completely processed.
+
+@see CDirectGdiDriver::Flush()
+
+@pre CDirectGdiDriver object has been initialised for the calling thread.
+@post All outstanding requests have been completely processed.
+*/
+EXPORT_C void CDirectGdiDriver::Finish()
+ {
+ iDriverInternal->Finish();
+ }
+
+/**
+Returns the first error code (as the result of calling any DirectGDI API), if any,
+since the last call to this function or, if it has not previously been called, since
+the CDirectGdiDriver was initialised. Calling this function clears the error code.
+
+@see CDirectGdiDriver::SetError(TInt)
+
+@pre CDirectGdiDriver object has been initialised for the calling thread.
+@post The error code has been reset after being read.
+
+@return The first error code, if any, since the last call to this function or,
+ if it has not previously been called, since the CDirectGdiDriver was initialised.
+ KErrNone will indicate that no such error has occurred.
+*/
+EXPORT_C TInt CDirectGdiDriver::GetError()
+ {
+ return iDriverInternal->GetError();
+ }
+
+
+/**
+Sets the error code on the driver. If the error code is already set to a value other
+than KErrNone, the error code will not be modified.
+
+@see CDirectGdiDriver::GetError()
+
+@param aErr The error code to set.
+
+@pre CDirectGdiDriver object has been initialised for the calling thread.
+@post The error code has been set.
+*/
+EXPORT_C void CDirectGdiDriver::SetError(TInt aErr)
+ {
+ iDriverInternal->SetError(aErr);
+ }
+
+/**
+Retrieves a pointer to an instance of the requested extension interface implementation, if provided.
+
+@param aInterfaceId The globally unique identifier of the requested interface.
+@param aInterface On return, holds the specified interface, or NULL if the interface cannot be found.
+
+@pre CDirectGdiDriver object has been initialised for the calling thread.
+
+@return KErrNone If the interface is supported, KErrExtensionNotSupported otherwise.
+ */
+EXPORT_C TInt CDirectGdiDriver::GetInterface(TUid aInterfaceId, TAny*& aInterface)
+ {
+ return iDriverInternal->GetInterface(aInterfaceId, aInterface);
+ }
+
+/**
+CDirectGdiDriver private constructor as this class is singleton.
+
+@pre None.
+@post Initialises the member reference counter to zero.
+*/
+CDirectGdiDriver::CDirectGdiDriver()
+ {
+ }
+
+/**
+CDirectGdiDriver default destructor.
+
+@pre None.
+@post None.
+
+@panic DGDI 15, if the resource count is not zero.
+*/
+CDirectGdiDriver::~CDirectGdiDriver()
+ {
+ GRAPHICS_ASSERT_ALWAYS(iOpenCount == 0, EDirectGdiPanicDriverDestructorOpenCountError);
+ delete iDriverInternal;
+ }
+
+/**
+Delegates the call to the CDirectGdiDriverInternal object, which creates a DirectGDI
+adaptation-specific resource from the given drawable resource so it can be drawn
+using the DirectGDI rendering API.
+
+@see CloseDrawableSource()
+
+@param aRDirectGdiDrawableSource The RDirectGdiDrawableSource object to be created
+@param aRSgDrawable The RSgDrawable object to use when creating aRDirectGdiDrawableSource
+
+@pre CDirectGdiDriver object has been initialised from the calling thread.
+@post The DirectGDI adaptation-specific resource that is bound to the given
+drawable resource is created and this handle is now associated with it. The reference
+counter on the drawable resource is incremented. The CDirectGdiDriver for this thread
+is now aware of and owns the adaptation specific resource.
+
+@return KErrNone if successful, KErrNotSupported if the drawable resource is not
+created with the correct usage (ESgUsageDirectGdiSource must be set), otherwise one of the system-wide error codes.
+
+@panic DGDI 19, if this handle is already associated with a DirectGDI adaptation-specific drawable resource.
+@panic DGDI 20, if the drawable resource is not valid.
+*/
+TInt CDirectGdiDriver::CreateDrawableSource(RDirectGdiDrawableSource& aRDirectGdiDrawableSource, const RSgDrawable& aRSgDrawable)
+ {
+ GRAPHICS_ASSERT_ALWAYS(aRDirectGdiDrawableSource.Handle() == KNullHandle, EDirectGdiPanicDrawableSourceAlreadyExists);
+
+ if(aRSgDrawable.DrawableType() == KSgImageTypeUid)
+ {// make sure that drawable was created with the flag ESgUsageDirectGdiSource
+ RSgImage *image = (RSgImage*) &aRSgDrawable;
+ TSgImageInfo info;
+ TInt err = image ->GetInfo (info);
+ GRAPHICS_ASSERT_ALWAYS(err == KErrNone, EDirectGdiPanicImageSourceInfoError);
+
+ if (!(info.iUsage & ESgUsageDirectGdiSource))
+ {
+ return KErrNotSupported;
+ }
+ }
+ return iDriverInternal->CreateDrawableSource(aRDirectGdiDrawableSource.iHandle, aRSgDrawable);
+ }
+
+/**
+Delegates call to the CDirectGdiDriverInternal object, which destroys the DirectGDI
+adaptation-specific resource associated with this handle. Calling this method on a
+handle that is not associated with any DirectGDI adaptation specific resource will
+do nothing. Once Close() is called, this handle can be reused.
+
+@see CreateDrawableSource()
+
+@param aSource The RDirectGdiDrawableSource object.
+
+@pre CDirectGdiDriver object has been initialised from the calling thread.
+@post The DirectGDI specific resource associated with this handle will be
+destroyed (at any time preferred by the adaptation). This handle is no longer
+associated with a DirectGDI specific resource. The reference counter of the
+underlying non-image resource is decremented.
+*/
+void CDirectGdiDriver::CloseDrawableSource(RDirectGdiDrawableSource& aSource)
+ {
+ iDriverInternal->CloseDrawableSource(aSource.iHandle);
+ }
+
+/**
+Delegates call to the CDirectGdiDriverInternal object, which creates a DirectGDI
+adaptation-specific resource from the given image resource so it can be used as a
+target of DirectGDI rendering.
+
+@see CloseImageTarget()
+
+@param aTarget The RDirectGdiImageTarget object.
+@param aImage The RSgImage object.
+
+@pre CDirectGdiDriver object has been initialised from the calling thread.
+The image resource has been fully constructed and created with the correct usage
+that allows it to be used as a DirectGDI target.
+
+@post The DirectGDI adaptation-specific resource that is bound to the given image
+resource is created and this handle is now associated with it. The reference counter
+on the image resource is incremented.
+
+@return KErrNone if successful, KErrNotSupported if the image resource is not
+created with the correct usage, otherwise one of the system-wide error codes.
+
+@panic DGDI 17, if this handle is already associated with a DirectGDI adaptation-specific resource.
+@panic DGDI 21, if the image resource is not valid.
+*/
+TInt CDirectGdiDriver::CreateImageTarget(RDirectGdiImageTarget& aTarget, const RSgImage& aImage)
+ {
+ GRAPHICS_ASSERT_ALWAYS(aTarget.Handle() == KNullHandle, EDirectGdiPanicImageTargetAlreadyExists);
+ TSgImageInfo info;
+ TInt err = aImage.GetInfo(info);
+ GRAPHICS_ASSERT_ALWAYS(err == KErrNone, EDirectGdiPanicImageTargetInfoError);
+
+ if (!(info.iUsage & ESgUsageDirectGdiTarget))
+ {
+ return KErrNotSupported;
+ }
+ return iDriverInternal->CreateImageTarget(aTarget.iHandle, aImage);
+ }
+
+/**
+Delegates call to the CDirectGdiDriverInternal object, which destroys the DirectGDI
+adaptation specific resource associated with this handle. Calling this method on a
+handle that is not associated with any DirectGDI adaptation specific resource will
+do nothing. Once Close() is called, this handle can be reused.
+
+@see CreateImageTarget()
+
+@param aTarget The RDirectGdiImageTarget object.
+
+@pre CDirectGdiDriver object has been initialised from the calling thread.
+
+@post The DirectGDI specific resource associated with this handle will be destroyed
+(at any time preferred by the adaptation). This handle is no longer associated with
+a DirectGDI specific resource. The reference counter of the underlying image
+resource is decremented.
+*/
+void CDirectGdiDriver::CloseImageTarget(RDirectGdiImageTarget& aTarget)
+ {
+ iDriverInternal->CloseImageTarget(aTarget.iHandle);
+ }
+
+/**
+Delegates call to the CDirectGdiDriverInternal object, which creates a
+MDirectGdiEngine object.
+
+@param aEngine The MDirectGdiEngine object.
+
+@pre CDirectGdiDriver object has been initialised from the calling thread.
+@post None.
+
+@return KErrNone if successful, otherwise one of the system-wide error codes.
+*/
+TInt CDirectGdiDriver::CreateEngine(MDirectGdiEngine*& aEngine)
+ {
+ return iDriverInternal->CreateEngine(aEngine);
+ }
+
+/**
+Delegates call to the CDirectGdiDriverInternal object, which destroys a
+MDirectGdiEngine object.
+
+@param aEngine The MDirectGdiEngine object.
+
+@pre CDirectGdiDriver object has been initialised from the calling thread.
+@post None.
+*/
+void CDirectGdiDriver::DestroyEngine(MDirectGdiEngine* aEngine)
+ {
+ iDriverInternal->DestroyEngine(aEngine);
+ }
+