2003-07-28 10:59:42 +00:00
|
|
|
///////////////////////////////////////////////////////////////////////////////
|
2006-09-14 16:04:18 +00:00
|
|
|
// Name: src/common/rendcmn.cpp
|
2003-07-28 10:59:42 +00:00
|
|
|
// Purpose: wxRendererNative common functions
|
|
|
|
// Author: Vadim Zeitlin
|
|
|
|
// Modified by:
|
|
|
|
// Created: 28.07.03
|
|
|
|
// RCS-ID: $Id$
|
|
|
|
// Copyright: (c) 2003 Vadim Zeitlin <vadim@wxwindows.org>
|
2004-05-25 17:31:17 +00:00
|
|
|
// License: wxWindows license
|
2003-07-28 10:59:42 +00:00
|
|
|
///////////////////////////////////////////////////////////////////////////////
|
|
|
|
|
|
|
|
// ============================================================================
|
|
|
|
// declarations
|
|
|
|
// ============================================================================
|
|
|
|
|
|
|
|
// ----------------------------------------------------------------------------
|
|
|
|
// headers
|
|
|
|
// ----------------------------------------------------------------------------
|
|
|
|
|
|
|
|
#include "wx/wxprec.h"
|
|
|
|
|
|
|
|
#ifdef __BORLANDC__
|
|
|
|
#pragma hdrstop
|
|
|
|
#endif
|
|
|
|
|
|
|
|
#ifndef WX_PRECOMP
|
2003-07-28 19:25:06 +00:00
|
|
|
#include "wx/app.h"
|
2003-08-10 17:25:36 +00:00
|
|
|
#include "wx/log.h"
|
|
|
|
#include "wx/intl.h"
|
2003-07-28 10:59:42 +00:00
|
|
|
#endif //WX_PRECOMP
|
|
|
|
|
|
|
|
#include "wx/apptrait.h"
|
|
|
|
#include "wx/renderer.h"
|
|
|
|
|
|
|
|
#include "wx/ptr_scpd.h"
|
|
|
|
|
2003-08-06 18:14:44 +00:00
|
|
|
#if wxUSE_DYNLIB_CLASS
|
|
|
|
#include "wx/dynlib.h"
|
|
|
|
#endif // wxUSE_DYNLIB_CLASS
|
|
|
|
|
2003-07-28 10:59:42 +00:00
|
|
|
// ----------------------------------------------------------------------------
|
|
|
|
// wxRendererPtr: auto pointer holding the global renderer
|
|
|
|
// ----------------------------------------------------------------------------
|
|
|
|
|
2008-04-14 20:13:06 +00:00
|
|
|
typedef wxScopedPtr<wxRendererNative> wxRendererPtrBase;
|
2003-07-28 10:59:42 +00:00
|
|
|
|
|
|
|
class wxRendererPtr : public wxRendererPtrBase
|
|
|
|
{
|
|
|
|
public:
|
|
|
|
// return true if we have a renderer, false otherwise
|
|
|
|
bool IsOk()
|
|
|
|
{
|
|
|
|
if ( !m_initialized )
|
|
|
|
{
|
|
|
|
// only try to create the renderer once
|
|
|
|
m_initialized = true;
|
|
|
|
|
|
|
|
DoInit();
|
|
|
|
}
|
|
|
|
|
|
|
|
return get() != NULL;
|
|
|
|
}
|
|
|
|
|
2003-08-06 18:14:44 +00:00
|
|
|
// return the global and unique wxRendererPtr
|
2005-05-17 20:58:41 +00:00
|
|
|
static wxRendererPtr& Get();
|
2003-08-06 18:14:44 +00:00
|
|
|
|
2003-07-28 10:59:42 +00:00
|
|
|
private:
|
2003-08-06 18:14:44 +00:00
|
|
|
wxRendererPtr() : wxRendererPtrBase(NULL) { m_initialized = false; }
|
|
|
|
|
2003-07-28 10:59:42 +00:00
|
|
|
void DoInit()
|
|
|
|
{
|
|
|
|
wxAppTraits *traits = wxTheApp ? wxTheApp->GetTraits() : NULL;
|
|
|
|
if ( traits )
|
|
|
|
{
|
|
|
|
// ask the traits object to create a renderer for us
|
|
|
|
reset(traits->CreateRenderer());
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
bool m_initialized;
|
|
|
|
|
2003-08-10 15:51:30 +00:00
|
|
|
// just to suppress a gcc warning
|
|
|
|
friend class wxRendererPtrDummyFriend;
|
|
|
|
|
2003-07-28 10:59:42 +00:00
|
|
|
DECLARE_NO_COPY_CLASS(wxRendererPtr)
|
|
|
|
};
|
|
|
|
|
2005-05-17 20:58:41 +00:00
|
|
|
// return the global and unique wxRendererPtr
|
|
|
|
/*static*/ wxRendererPtr& wxRendererPtr::Get()
|
|
|
|
{
|
|
|
|
static wxRendererPtr s_renderer;
|
|
|
|
|
|
|
|
return s_renderer;
|
|
|
|
}
|
|
|
|
|
2003-08-06 18:14:44 +00:00
|
|
|
#if wxUSE_DYNLIB_CLASS
|
|
|
|
|
|
|
|
// ----------------------------------------------------------------------------
|
|
|
|
// wxRendererFromDynLib: represents a renderer dynamically loaded from a DLL
|
|
|
|
// ----------------------------------------------------------------------------
|
|
|
|
|
|
|
|
class wxRendererFromDynLib : public wxDelegateRendererNative
|
|
|
|
{
|
|
|
|
public:
|
|
|
|
// create the object wrapping the given renderer created from this DLL
|
|
|
|
//
|
|
|
|
// we take ownership of the pointer and will delete it (and also unload the
|
|
|
|
// DLL) when we're deleted
|
|
|
|
wxRendererFromDynLib(wxDynamicLibrary& dll, wxRendererNative *renderer)
|
|
|
|
: wxDelegateRendererNative(*renderer),
|
|
|
|
m_renderer(renderer),
|
|
|
|
m_dllHandle(dll.Detach())
|
|
|
|
{
|
|
|
|
}
|
|
|
|
|
|
|
|
virtual ~wxRendererFromDynLib()
|
|
|
|
{
|
|
|
|
delete m_renderer;
|
|
|
|
wxDynamicLibrary::Unload(m_dllHandle);
|
|
|
|
}
|
|
|
|
|
|
|
|
private:
|
|
|
|
wxRendererNative *m_renderer;
|
|
|
|
wxDllType m_dllHandle;
|
|
|
|
};
|
|
|
|
|
|
|
|
#endif // wxUSE_DYNLIB_CLASS
|
|
|
|
|
2003-07-28 10:59:42 +00:00
|
|
|
// ============================================================================
|
|
|
|
// wxRendererNative implementation
|
|
|
|
// ============================================================================
|
|
|
|
|
2003-08-10 15:51:30 +00:00
|
|
|
wxRendererNative::~wxRendererNative()
|
|
|
|
{
|
|
|
|
// empty but necessary
|
|
|
|
}
|
|
|
|
|
2003-08-06 18:14:44 +00:00
|
|
|
// ----------------------------------------------------------------------------
|
|
|
|
// Managing the global renderer
|
|
|
|
// ----------------------------------------------------------------------------
|
|
|
|
|
2003-07-28 10:59:42 +00:00
|
|
|
/* static */
|
|
|
|
wxRendererNative& wxRendererNative::Get()
|
|
|
|
{
|
2003-08-06 18:14:44 +00:00
|
|
|
wxRendererPtr& renderer = wxRendererPtr::Get();
|
2003-07-28 10:59:42 +00:00
|
|
|
|
2003-08-06 18:14:44 +00:00
|
|
|
return renderer.IsOk() ? *renderer.get() : GetDefault();
|
2003-07-28 10:59:42 +00:00
|
|
|
}
|
|
|
|
|
2003-08-06 18:14:44 +00:00
|
|
|
/* static */
|
|
|
|
wxRendererNative *wxRendererNative::Set(wxRendererNative *rendererNew)
|
|
|
|
{
|
|
|
|
wxRendererPtr& renderer = wxRendererPtr::Get();
|
|
|
|
|
|
|
|
wxRendererNative *rendererOld = renderer.release();
|
|
|
|
|
|
|
|
renderer.reset(rendererNew);
|
|
|
|
|
|
|
|
return rendererOld;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// ----------------------------------------------------------------------------
|
|
|
|
// Dynamic renderers loading
|
|
|
|
// ----------------------------------------------------------------------------
|
|
|
|
|
|
|
|
#if wxUSE_DYNLIB_CLASS
|
|
|
|
|
|
|
|
/* static */
|
|
|
|
wxRendererNative *wxRendererNative::Load(const wxString& name)
|
|
|
|
{
|
|
|
|
wxString fullname = wxDynamicLibrary::CanonicalizePluginName(name);
|
|
|
|
|
|
|
|
wxDynamicLibrary dll(fullname);
|
|
|
|
if ( !dll.IsLoaded() )
|
|
|
|
return NULL;
|
|
|
|
|
|
|
|
// each theme DLL must export a wxCreateRenderer() function with this
|
|
|
|
// signature
|
|
|
|
typedef wxRendererNative *(*wxCreateRenderer_t)();
|
|
|
|
|
|
|
|
wxDYNLIB_FUNCTION(wxCreateRenderer_t, wxCreateRenderer, dll);
|
|
|
|
if ( !pfnwxCreateRenderer )
|
|
|
|
return NULL;
|
|
|
|
|
2003-08-10 15:51:30 +00:00
|
|
|
// create a renderer object
|
2003-08-06 18:14:44 +00:00
|
|
|
wxRendererNative *renderer = (*pfnwxCreateRenderer)();
|
|
|
|
if ( !renderer )
|
|
|
|
return NULL;
|
|
|
|
|
2003-08-10 15:51:30 +00:00
|
|
|
// check that its version is compatible with ours
|
|
|
|
wxRendererVersion ver = renderer->GetVersion();
|
|
|
|
if ( !wxRendererVersion::IsCompatible(ver) )
|
|
|
|
{
|
|
|
|
wxLogError(_("Renderer \"%s\" has incompatible version %d.%d and couldn't be loaded."),
|
|
|
|
name.c_str(), ver.version, ver.age);
|
|
|
|
delete renderer;
|
|
|
|
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
|
|
|
|
// finally wrap the renderer in an object which will delete it and unload
|
|
|
|
// the library when it is deleted and return it to the caller
|
2003-08-06 18:14:44 +00:00
|
|
|
return new wxRendererFromDynLib(dll, renderer);
|
|
|
|
}
|
|
|
|
|
|
|
|
#endif // wxUSE_DYNLIB_CLASS
|