]> git.saurik.com Git - wxWidgets.git/blob - src/common/rendcmn.cpp
Improved wxDCPen/BrushChangers.
[wxWidgets.git] / src / common / rendcmn.cpp
1 ///////////////////////////////////////////////////////////////////////////////
2 // Name: common/rendcmn.cpp
3 // Purpose: wxRendererNative common functions
4 // Author: Vadim Zeitlin
5 // Modified by:
6 // Created: 28.07.03
7 // RCS-ID: $Id$
8 // Copyright: (c) 2003 Vadim Zeitlin <vadim@wxwindows.org>
9 // License: wxWindows license
10 ///////////////////////////////////////////////////////////////////////////////
11
12 // ============================================================================
13 // declarations
14 // ============================================================================
15
16 // ----------------------------------------------------------------------------
17 // headers
18 // ----------------------------------------------------------------------------
19
20 #include "wx/wxprec.h"
21
22 #ifdef __BORLANDC__
23 #pragma hdrstop
24 #endif
25
26 #ifndef WX_PRECOMP
27 #include "wx/app.h"
28 #include "wx/log.h"
29 #include "wx/intl.h"
30 #endif //WX_PRECOMP
31
32 #include "wx/apptrait.h"
33 #include "wx/renderer.h"
34
35 #include "wx/ptr_scpd.h"
36
37 #if wxUSE_DYNLIB_CLASS
38 #include "wx/dynlib.h"
39 #endif // wxUSE_DYNLIB_CLASS
40
41 // ----------------------------------------------------------------------------
42 // wxRendererPtr: auto pointer holding the global renderer
43 // ----------------------------------------------------------------------------
44
45 wxDECLARE_SCOPED_PTR(wxRendererNative, wxRendererPtrBase)
46 wxDEFINE_SCOPED_PTR(wxRendererNative, wxRendererPtrBase)
47
48 class wxRendererPtr : public wxRendererPtrBase
49 {
50 public:
51 // return true if we have a renderer, false otherwise
52 bool IsOk()
53 {
54 if ( !m_initialized )
55 {
56 // only try to create the renderer once
57 m_initialized = true;
58
59 DoInit();
60 }
61
62 return get() != NULL;
63 }
64
65 // return the global and unique wxRendererPtr
66 static wxRendererPtr& Get();
67
68 private:
69 wxRendererPtr() : wxRendererPtrBase(NULL) { m_initialized = false; }
70
71 void DoInit()
72 {
73 wxAppTraits *traits = wxTheApp ? wxTheApp->GetTraits() : NULL;
74 if ( traits )
75 {
76 // ask the traits object to create a renderer for us
77 reset(traits->CreateRenderer());
78 }
79 }
80
81 bool m_initialized;
82
83 // just to suppress a gcc warning
84 friend class wxRendererPtrDummyFriend;
85
86 DECLARE_NO_COPY_CLASS(wxRendererPtr)
87 };
88
89 // return the global and unique wxRendererPtr
90 /*static*/ wxRendererPtr& wxRendererPtr::Get()
91 {
92 static wxRendererPtr s_renderer;
93
94 return s_renderer;
95 }
96
97 #if wxUSE_DYNLIB_CLASS
98
99 // ----------------------------------------------------------------------------
100 // wxRendererFromDynLib: represents a renderer dynamically loaded from a DLL
101 // ----------------------------------------------------------------------------
102
103 class wxRendererFromDynLib : public wxDelegateRendererNative
104 {
105 public:
106 // create the object wrapping the given renderer created from this DLL
107 //
108 // we take ownership of the pointer and will delete it (and also unload the
109 // DLL) when we're deleted
110 wxRendererFromDynLib(wxDynamicLibrary& dll, wxRendererNative *renderer)
111 : wxDelegateRendererNative(*renderer),
112 m_renderer(renderer),
113 m_dllHandle(dll.Detach())
114 {
115 }
116
117 virtual ~wxRendererFromDynLib()
118 {
119 delete m_renderer;
120 wxDynamicLibrary::Unload(m_dllHandle);
121 }
122
123 private:
124 wxRendererNative *m_renderer;
125 wxDllType m_dllHandle;
126 };
127
128 #endif // wxUSE_DYNLIB_CLASS
129
130 // ============================================================================
131 // wxRendererNative implementation
132 // ============================================================================
133
134 wxRendererNative::~wxRendererNative()
135 {
136 // empty but necessary
137 }
138
139 // ----------------------------------------------------------------------------
140 // Managing the global renderer
141 // ----------------------------------------------------------------------------
142
143 /* static */
144 wxRendererNative& wxRendererNative::Get()
145 {
146 wxRendererPtr& renderer = wxRendererPtr::Get();
147
148 return renderer.IsOk() ? *renderer.get() : GetDefault();
149 }
150
151 /* static */
152 wxRendererNative *wxRendererNative::Set(wxRendererNative *rendererNew)
153 {
154 wxRendererPtr& renderer = wxRendererPtr::Get();
155
156 wxRendererNative *rendererOld = renderer.release();
157
158 renderer.reset(rendererNew);
159
160 return rendererOld;
161 }
162
163
164 // ----------------------------------------------------------------------------
165 // Dynamic renderers loading
166 // ----------------------------------------------------------------------------
167
168 #if wxUSE_DYNLIB_CLASS
169
170 /* static */
171 wxRendererNative *wxRendererNative::Load(const wxString& name)
172 {
173 wxString fullname = wxDynamicLibrary::CanonicalizePluginName(name);
174
175 wxDynamicLibrary dll(fullname);
176 if ( !dll.IsLoaded() )
177 return NULL;
178
179 // each theme DLL must export a wxCreateRenderer() function with this
180 // signature
181 typedef wxRendererNative *(*wxCreateRenderer_t)();
182
183 wxDYNLIB_FUNCTION(wxCreateRenderer_t, wxCreateRenderer, dll);
184 if ( !pfnwxCreateRenderer )
185 return NULL;
186
187 // create a renderer object
188 wxRendererNative *renderer = (*pfnwxCreateRenderer)();
189 if ( !renderer )
190 return NULL;
191
192 // check that its version is compatible with ours
193 wxRendererVersion ver = renderer->GetVersion();
194 if ( !wxRendererVersion::IsCompatible(ver) )
195 {
196 wxLogError(_("Renderer \"%s\" has incompatible version %d.%d and couldn't be loaded."),
197 name.c_str(), ver.version, ver.age);
198 delete renderer;
199
200 return NULL;
201 }
202
203 // finally wrap the renderer in an object which will delete it and unload
204 // the library when it is deleted and return it to the caller
205 return new wxRendererFromDynLib(dll, renderer);
206 }
207
208 #endif // wxUSE_DYNLIB_CLASS
209