Mercurial > projects > dwt-linux
view dwt/internal/gtk/runtime/Loader.d @ 11:5f725d09c076
Added dynamic loader from gtkd with cleanup and modifications. Tango only support. No OS.d tie-in yet.
author | John Reimer<terminal.node@gmail.com> |
---|---|
date | Sat, 05 Jan 2008 15:13:44 -0800 |
parents | |
children | 8cec8f536af3 |
line wrap: on
line source
/***************************************************************************** license: version: Dynamic loader for gtk symbol names History: 2004-12-11 initial version by John Reimer 2005-02-21 class and symbol names change; versioning modification 2005-05-05 linux fixes 2007-12-23 source cleanup 2007-12-30 merge Paths.d into Loader.d 2008-01-05 Tango only version using tango.sys.SharedLib Note: Design inspired by Kris Bell's ICU.d, the dynamic loader from an early version of mango ******************************************************************************/ module dwt.internal.gtk.runtime.Loader; private import tango.io.Stdout, tango.sys.SharedLib; /***************************************************************************** *****************************************************************************/ enum LIBRARY { ATK, CAIRO, GDK, GDKPIXBUF, GLIB, GMODULE, GOBJECT, GTHREAD, GTK, PANGO, GLGDK, GLGTK, GL, GLU, GLEXT, GDA, GLADE, GSV, GSTREAMER, GSTINTERFACES } /***************************************************************************** *****************************************************************************/ version (Windows) { const char[][LIBRARY.max+1] importLibs = [ LIBRARY.ATK: "libatk-1.0-0.dll", LIBRARY.CAIRO: "libcairo-2.dll", LIBRARY.GDK: "libgdk-win32-2.0-0.dll", LIBRARY.GDKPIXBUF: "libgdk_pixbuf-2.0-0.dll", LIBRARY.GLIB: "libglib-2.0-0.dll", LIBRARY.GMODULE: "libgmodule-2.0-0.dll", LIBRARY.GOBJECT: "libgobject-2.0-0.dll", LIBRARY.GTHREAD: "libgthread-2.0-0.dll", LIBRARY.GTK: "libgtk-win32-2.0-0.dll", LIBRARY.PANGO: "libpango-1.0-0.dll", LIBRARY.GLGDK: "libgdkglext-win32-1.0-0.dll", LIBRARY.GLGTK: "libgtkglext-win32-1.0-0.dll", LIBRARY.GL: "opengl32.dll", LIBRARY.GLU: "glu32.dll", LIBRARY.GDA: "libgda-2.dll", LIBRARY.GLADE: "libglade-2.0.dll", LIBRARY.GSV: "libgtksourceview-1.0-0.dll", LIBRARY.GSTREAMER: "libgstreamer-0.10.dll", LIBRARY.GSTINTERFACES: "libgstinterfaces-0.10.dll" ]; } /***************************************************************************** *****************************************************************************/ version(linux) { const char[][LIBRARY.max+1] importLibs = [ LIBRARY.ATK: "libatk-1.0.so", LIBRARY.CAIRO: "libcairo.so.2", LIBRARY.GDK: "libgdk-x11-2.0.so", LIBRARY.GDKPIXBUF: "libgdk_pixbuf-2.0.so", LIBRARY.GLIB: "libglib-2.0.so", LIBRARY.GMODULE: "libgmodule-2.0.so", LIBRARY.GOBJECT: "libgobject-2.0.so", LIBRARY.GTHREAD: "libgthread-2.0.so", LIBRARY.GTK: "libgtk-x11-2.0.so", LIBRARY.PANGO: "libpango-1.0.so", LIBRARY.GLGDK: "libgdkglext-x11-1.0.so", LIBRARY.GLGTK: "libgtkglext-x11-1.0.so", LIBRARY.GL: "libGL.so", LIBRARY.GLU: "libGLU.so", LIBRARY.GLEXT: "libGL.so", LIBRARY.GDA: "libgda-2.so.3", LIBRARY.GLADE: "libglade-2.0.so", LIBRARY.GSV: "libgtksourceview-1.0.so", LIBRARY.GSTREAMER: "libgstreamer-0.10.so", LIBRARY.GSTINTERFACES: "libgstinterfaces-0.10.so" ]; } /***************************************************************************** getLibraryPath -- place holder for future expansion ******************************************************************************/ version(Windows) { char[] getLibraryPath() { return "\\Program Files\\GTK2-Runtime\\lib\\"; } } /***************************************************************************** getLibraryPath is empty for linux because default path is known by ld ******************************************************************************/ version(linux) { char[] getLibraryPath() { return ""; } } /***************************************************************************** ProcLink is used to record the library, function, and function name that will be loaded by the dynamic loader. ******************************************************************************/ public struct Symbol { char[] name; void** pointer; } /***************************************************************************** The Linker class: handles loading of the library and exported functions ******************************************************************************/ public class Linker { static char[][][char[]] loadFailures; /************************************************************************* Gets all the failed loads for a specific library. This is filled in only if the default onFailure method is used during load. returns: an array of the names that failed to load for a specific library or null if none was found. **************************************************************************/ public static char[][] getLoadFailures(char[] libName) { if ( libName in loadFailures ) { return loadFailures[libName]; } else { return null; } } /************************************************************************* Loads all libraries. This is filled in only if the default onFailure method is used during load. returns: an array of the library names. **************************************************************************/ public static char[][] getLoadLibraries() { return loadFailures.keys; } /************************************************************************* isPerfectLoad -- Checks if any symbol failed to load. Returns: true if ALL symbols loaded. **************************************************************************/ public static bool isPerfectLoad() { return loadFailures.keys.length == 0; } /************************************************************************* **************************************************************************/ public static void dumpFailedLoads() { foreach ( char[] lib ; Linker.getLoadLibraries() ) { foreach ( char[] symbol ; Linker.getLoadFailures(lib) ) { version(Tango) Stdout.formatln("failed ({}) {}", lib, symbol).newline; } } } /************************************************************************* **************************************************************************/ private SharedLib primaryLib; private SharedLib alternateLib; private char[] libraryName; private char[] alternateLibraryName; alias void function( char[] libraryName, char[] symbolName, char[] message=null) FailureCallback; private FailureCallback onLoadFailure; /************************************************************************* **************************************************************************/ this( char[] libraryName, char[] alternateLibraryName=null ) { this(libraryName, alternateLibraryName, &(Linker.defaultFail)); } /************************************************************************* **************************************************************************/ this (char[] libraryName, char[] alternateLibraryName, FailureCallback fn ) { this.libraryName = libraryName; this.alternateLibraryName = alternateLibraryName; onLoadFailure = fn; SharedLib.throwExceptions = false; primaryLib = SharedLib.load( this.libraryName ); version(linux) { if (this.primaryLib is null) primaryLib = SharedLib.load( this.libraryName ~ ".0\0" ); } if ( alternateLibraryName !is null ) { alternateLib = SharedLib.load( this.alternateLibraryName ); } if (primaryLib is null) { throw new Exception("Library load failed: " ~ libraryName); } } /************************************************************************* Default load failure callback. Logs the symbols that failed to load. **************************************************************************/ static void defaultFail( char[] libraryName, char[] symbolName, char[] message=null ) { if ( !(libraryName in loadFailures) ) { char[][] cc; loadFailures[libraryName] = cc; } loadFailures[libraryName] ~= symbolName.dup; } /************************************************************************* Loads all the symbols for this library. **************************************************************************/ void link( inout Symbol[] symbols ) { foreach( Symbol link; symbols ) { *link.pointer = primaryLib.getSymbol ( (link.name~"\0").ptr); if (*link.pointer is null) { if ( alternateLib !is null ) { *link.pointer = alternateLib.getSymbol( (link.name~"\0").ptr); Stdout("Loader.Linker.link trying alternate lib: ", link.name).newline; } if (*link.pointer is null) { onLoadFailure( libraryName, link.name ); } } } } }