root/trunk/cairo/cairo/loader.d

Revision 228, 9.6 kB (checked in by DRK, 5 years ago)

* Updated the bindings to support cairo 1.2 and cairo 1.4. Support for these can be enabled with the cairo_1_2 and cairo_1_4 version identifiers.
* Added pdf, ps and svg support.
* Updated the build script appropriately.
* Note that cairooo is not likely to receive any further updates in its current form. It is being forked and rewritten for Tango's graphics package, although a port back to Phobos isn't out of the question.

Line 
1 /**
2  * This file implements the code to dynamically load the cairo
3  * library under various platforms.  It is largely stolen from
4  * the Derelict project's loader.d file.
5  *
6  * Authors: Derelict developers, Daniel Keep
7  * Copyright: 2005-2006 Derelict developers, 2006 Daniel Keep.
8  * License: BSD v2 (http://www.opensource.org/licenses/bsd-license.php).
9  */
10 /*
11  * Copyright © 2006 Daniel Keep.
12  * All rights reserved.
13  *
14  * Redistribution and use in source and binary forms, with or without
15  * modification, are permitted provided that the following conditions are
16  * met:
17  *
18  * * Redistributions of source code must retain the above copyright
19  *   notice, this list of conditions and the following disclaimer.
20  *
21  * * Redistributions in binary form must reproduce the above copyright
22  *   notice, this list of conditions and the following disclaimer in the
23  *   documentation and/or other materials provided with the distribution.
24  *
25  * * Neither the name of this software, nor the names of its contributors
26  *   may be used to endorse or promote products derived from this software
27  *   without specific prior written permission.
28  *
29  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
30  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
31  * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
32  * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
33  * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
34  * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
35  * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
36  * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
37  * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
38  * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
39  * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
40  */
41 /*
42  * Copyright (c) 2005-2006 Derelict Developers
43  * All rights reserved.
44  *
45  * Redistribution and use in source and binary forms, with or without
46  * modification, are permitted provided that the following conditions are
47  * met:
48  *
49  * * Redistributions of source code must retain the above copyright
50  *   notice, this list of conditions and the following disclaimer.
51  *
52  * * Redistributions in binary form must reproduce the above copyright
53  *   notice, this list of conditions and the following disclaimer in the
54  *   documentation and/or other materials provided with the distribution.
55  *
56  * * Neither the names 'Derelict', 'DerelictUtil', nor the names of its contributors
57  *   may be used to endorse or promote products derived from this software
58  *   without specific prior written permission.
59  *
60  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
61  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
62  * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
63  * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
64  * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
65  * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
66  * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
67  * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
68  * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
69  * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
70  * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
71  */
72 module cairo.loader;
73
74 private
75 {
76     import std.string;
77 }
78
79 /**
80  * This class represents a loaded library.  The actual instances
81  * will likely by of a subclassed type specific to the current
82  * platform.
83  */
84 class SharedLib
85 {
86 private:
87     char[] name;
88
89     this(char[] name)
90     {
91         this.name = name;
92     }
93
94 public:
95     char[] toString()
96     {
97         return "SharedLib("~name~")";
98     }
99 }
100
101 class CairoLoaderException : Exception
102 {
103     this(char[] msg)
104     {
105         super(msg);
106     }
107 }
108
109 class SharedLibLoadException : CairoLoaderException
110 {
111     this(char[] libName)
112     {
113         super("Failed to load shared library \""
114                 ~ libName ~ "\".");
115     }
116 }
117
118 class ProcNotFoundException : CairoLoaderException
119 {
120     this(SharedLib lib, char[] procName)
121     {
122         super("Could not find procedure \""
123                 ~ procName ~ "\" in shared library \""
124                 ~ lib.name ~ "\".");
125     }
126 }
127
128 /**
129  * Attempts to load the given library.
130  */
131 SharedLib loadSharedLib(char[] libName)
132 in
133 {
134     assert(libName !is null);
135 }
136 out(result)
137 {
138     assert(result !is null);
139 }
140 body
141 {
142     return loadSharedLibPlatform(libName);
143 }
144
145 /**
146  * Unloads the given shared library.  It is safe to call this
147  * method on a library that has already been unloaded.
148  */
149 void unloadSharedLib(SharedLib lib)
150 in
151 {
152     assert(lib !is null);
153 }
154 body
155 {
156     if( lib !is null )
157         unloadSharedLibPlatform(lib);
158 }
159
160 /**
161  * Attempts to load the given procedure from the shared
162  * library.
163  */
164 void* getProc(SharedLib lib, char[] procName)
165 in
166 {
167     assert(lib !is null);
168     assert(lib !is null);
169 }
170 out(result)
171 {
172     assert(result != null);
173 }
174 body
175 {
176     return getProcPlatform(lib, procName);
177 }
178
179 /**
180  * Windows-specific implementation.
181  */
182 version(Windows)
183 {
184     private import std.c.windows.windows;
185
186     class WinSharedLib : SharedLib
187     {
188     private:
189         HMODULE handle;
190
191         this(HMODULE handle, char[] name)
192         {
193             super(name);
194             this.handle = handle;
195         }
196     }
197
198     SharedLib loadSharedLibPlatform(char[] libName)
199     in
200     {
201         assert(libName !is null);
202         assert(libName.length > 0);
203     }
204     out(result)
205     {
206         assert(result !is null);
207         assert(cast(WinSharedLib)result !is null);
208         assert((cast(WinSharedLib)result).handle != null);
209     }
210     body
211     {
212         HMODULE hlib = LoadLibraryA(toStringz(libName));
213         if( hlib is null )
214             throw new SharedLibLoadException(libName);
215
216         return new WinSharedLib(hlib, libName);
217     }
218
219     void unloadSharedLibPlatform(SharedLib lib)
220     in
221     {
222         assert(cast(WinSharedLib)lib !is null);
223     }
224     out
225     {
226         assert((cast(WinSharedLib)lib).handle is null);
227     }
228     body
229     {
230         WinSharedLib winlib = cast(WinSharedLib)lib;
231         if( winlib.handle != null )
232         {
233             FreeLibrary(winlib.handle);
234             winlib.handle = cast(HMODULE)null;
235         }
236     }
237
238     void* getProcPlatform(SharedLib lib, char[] procName)
239     in
240     {
241         assert(lib !is null);
242         assert(cast(WinSharedLib)lib !is null);
243         assert(procName !is null);
244         assert(procName.length > 0);
245     }
246     out(result)
247     {
248         assert(result != null);
249     }
250     body
251     {
252         auto winlib = cast(WinSharedLib)lib;
253         void* proc = GetProcAddress(winlib.handle, toStringz(procName));
254         if( proc == null )
255             throw new ProcNotFoundException(lib, procName);
256
257         return proc;
258     }
259 }
260 /**
261  * Linux-specific implementation.
262  */
263 else version(linux)
264 {
265     version(build)
266     {
267         pragma(link, dl);
268     }
269     else
270     {
271         pragma(lib, "dl.a");
272     }
273    
274     private import std.c.linux.linux;
275
276     private typedef void* HLIB;
277    
278     class LinuxSharedLib : SharedLib
279     {
280     private:
281         HLIB handle;
282
283         this(HLIB handle, char[] libName)
284         {
285             super(libName);
286             this.handle = handle;
287         }
288     }
289    
290     SharedLib loadSharedLibPlatform(char[] libName)
291     in
292     {
293         assert(libName !is null);
294         assert(libName.length > 0);
295     }
296     out(result)
297     {
298         assert(result !is null);
299         assert(cast(LinuxSharedLib)result !is null);
300         assert((cast(LinuxSharedLib)result).handle != null);
301     }
302     body
303     {
304         HLIB handle = cast(HLIB)dlopen(toStringz(libName), RTLD_NOW);
305         if( handle == null )
306             throw new SharedLibLoadException(libName);
307
308         return new LinuxSharedLib(handle, libName);
309     }
310
311     void unloadSharedLibPlatform(SharedLib lib)
312     in
313     {
314         assert(lib !is null);
315         assert(cast(LinuxSharedLib)lib !is null);
316     }
317     out
318     {
319         assert((cast(LinuxSharedLib)lib).handle == null);
320     }
321     body
322     {
323         auto plib = cast(LinuxSharedLib)lib;
324         if( plib.handle != null )
325         {
326             dlclose(cast(void*)plib.handle);
327             plib.handle = null;
328         }
329     }
330
331     void* getProcPlatform(SharedLib lib, char[] procName)
332     in
333     {
334         assert(lib !is null);
335         assert(cast(LinuxSharedLib)lib !is null);
336         assert((cast(LinuxSharedLib)lib).handle != null);
337         assert(procName !is null);
338         assert(procName.length > 0);
339     }
340     out(result)
341     {
342         assert(result != null);
343     }
344     body
345     {
346         auto plib = cast(LinuxSharedLib)lib;
347         void* proc = dlsym(cast(void*)plib.handle, toStringz(procName));
348         if( proc == null )
349             throw new ProcNotFoundException(lib, procName);
350
351         return proc;
352     }
353 }
354 else
355 {
356     pragma(msg, "Sorry; the cairo loader isn't supported on your system.");
357     pragma(msg, "If you would like to help, please check the cairo/loader.d"
358                 " file, and see if you can implement the *Platform"
359                 " functions for your platform, then send them to us so we"
360                 " can incorporate them into the official distribution."
361                 "  Thankyou, and sorry for the inconvenience.");
362     static assert(0);
363 }
Note: See TracBrowser for help on using the browser.