--- imlib-1.9.15.orig/gdk_imlib/local-hack-gmodule/gmodule-dl.c +++ imlib-1.9.15/gdk_imlib/local-hack-gmodule/gmodule-dl.c @@ -0,0 +1,158 @@ +/* GMODULE - GLIB wrapper code for dynamic module loading + * Copyright (C) 1998, 2000 Tim Janik + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with this library; if not, write to the + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + */ + +/* + * Modified by the GLib Team and others 1997-1999. See the AUTHORS + * file for a list of people on the GLib Team. See the ChangeLog + * files for a list of changes. These files are distributed with + * GLib at ftp://ftp.gtk.org/pub/gtk/. + */ + +/* + * MT safe + */ + +#include + +/* Perl includes and instead of on some systmes? */ + + +/* dlerror() is not implemented on all systems + */ +#ifndef LOCAL_HACK_G_MODULE_HAVE_DLERROR +# ifdef __NetBSD__ +# define dlerror() g_strerror (errno) +# else /* !__NetBSD__ */ +/* could we rely on errno's state here? */ +# define dlerror() "unknown dl-error" +# endif /* !__NetBSD__ */ +#endif /* LOCAL_HACK_G_MODULE_HAVE_DLERROR */ + +/* some flags are missing on some systems, so we provide + * harmless defaults. + * The Perl sources say, RTLD_LAZY needs to be defined as (1), + * at least for Solaris 1. + * + * Mandatory: + * RTLD_LAZY - resolve undefined symbols as code from the dynamic library + * is executed. + * RTLD_NOW - resolve all undefined symbols before dlopen returns, and fail + * if this cannot be done. + * Optionally: + * RTLD_GLOBAL - the external symbols defined in the library will be made + * available to subsequently loaded libraries. + */ +#ifndef RTLD_LAZY +#define RTLD_LAZY 1 +#endif /* RTLD_LAZY */ +#ifndef RTLD_NOW +#define RTLD_NOW 0 +#endif /* RTLD_NOW */ +/* some systems (OSF1 V5.0) have broken RTLD_GLOBAL linkage */ +#ifdef LOCAL_HACK_G_MODULE_BROKEN_RTLD_GLOBAL +#undef RTLD_GLOBAL +#endif /* LOCAL_HACK_G_MODULE_BROKEN_RTLD_GLOBAL */ +#ifndef RTLD_GLOBAL +#define RTLD_GLOBAL 0 +#endif /* RTLD_GLOBAL */ + + +/* --- functions --- */ +static gchar* +fetch_dlerror (void) +{ + gchar *msg = dlerror (); + + /* make sure we always return an error message != NULL */ + + return msg ? msg : "unknown dl-error"; +} + +static gpointer +_local_hack_g_module_open (const gchar *file_name, + gboolean bind_lazy) +{ + gpointer handle; + + handle = dlopen (file_name, (bind_lazy ? RTLD_LAZY : RTLD_NOW)); + if (!handle) + local_hack_g_module_set_error (fetch_dlerror ()); + + return handle; +} + +static gpointer +_local_hack_g_module_self (void) +{ + gpointer handle; + + /* to query symbols from the program itself, special link options + * are required on some systems. + */ + + handle = dlopen (NULL, RTLD_LAZY); + if (!handle) + local_hack_g_module_set_error (fetch_dlerror ()); + + return handle; +} + +static void +_local_hack_g_module_close (gpointer handle, + gboolean is_unref) +{ + /* are there any systems out there that have dlopen()/dlclose() + * without a reference count implementation? + */ + is_unref |= 1; + + if (is_unref) + { + if (dlclose (handle) != 0) + local_hack_g_module_set_error (fetch_dlerror ()); + } +} + +static gpointer +_local_hack_g_module_symbol (gpointer handle, + const gchar *symbol_name) +{ + gpointer p; + + p = dlsym (handle, symbol_name); + if (!p) + local_hack_g_module_set_error (fetch_dlerror ()); + + return p; +} + +static gchar* +_local_hack_g_module_build_path (const gchar *directory, + const gchar *module_name) +{ + if (directory && *directory) { + if (strncmp (module_name, "lib", 3) == 0) + return g_strconcat (directory, "/", module_name, NULL); + else + return g_strconcat (directory, "/lib", module_name, ".so", NULL); + } else if (strncmp (module_name, "lib", 3) == 0) + return g_strdup (module_name); + else + return g_strconcat ("lib", module_name, ".so", NULL); +} --- imlib-1.9.15.orig/gdk_imlib/local-hack-gmodule/gmodule-local.h +++ imlib-1.9.15/gdk_imlib/local-hack-gmodule/gmodule-local.h @@ -0,0 +1,100 @@ +/* GMODULE - GLIB wrapper code for dynamic module loading + * Copyright (C) 1998 Tim Janik + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with this library; if not, write to the + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + */ + +/* + * Modified by the GLib Team and others 1997-1999. See the AUTHORS + * file for a list of people on the GLib Team. See the ChangeLog + * files for a list of changes. These files are distributed with + * GLib at ftp://ftp.gtk.org/pub/gtk/. + */ + +#ifndef __GMODULE_H__ +#define __GMODULE_H__ + +#include + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + +/* exporting and importing functions, this is special cased + * to feature Windows dll stubs. + */ +#define LOCAL_HACK_G_MODULE_IMPORT extern +#ifdef NATIVE_WIN32 +# define LOCAL_HACK_G_MODULE_EXPORT __declspec(dllexport) +#else /* !NATIVE_WIN32 */ +# define LOCAL_HACK_G_MODULE_EXPORT +#endif /* !NATIVE_WIN32 */ + +typedef enum +{ + LOCAL_HACK_G_MODULE_BIND_LAZY = 1 << 0, + LOCAL_HACK_G_MODULE_BIND_MASK = 0x01 +} LocalHackGModuleFlags; + +typedef struct _LocalHackGModule LocalHackGModule; +typedef const gchar* (*LocalHackGModuleCheckInit) (LocalHackGModule *module); +typedef void (*LocalHackGModuleUnload) (LocalHackGModule *module); + +/* return TRUE if dynamic module loading is supported */ +gboolean local_hack_g_module_supported (void); + +/* open a module `file_name' and return handle, which is NULL on error */ +LocalHackGModule* local_hack_g_module_open (const gchar *file_name, + LocalHackGModuleFlags flags); + +/* close a previously opened module, returns TRUE on success */ +gboolean local_hack_g_module_close (LocalHackGModule *module); + +/* make a module resident so local_hack_g_module_close on it will be ignored */ +void local_hack_g_module_make_resident (LocalHackGModule *module); + +/* query the last module error as a string */ +gchar* local_hack_g_module_error (void); + +/* retrive a symbol pointer from `module', returns TRUE on success */ +gboolean local_hack_g_module_symbol (LocalHackGModule *module, + const gchar *symbol_name, + gpointer *symbol); + +/* retrive the file name from an existing module */ +gchar* local_hack_g_module_name (LocalHackGModule *module); + + +/* Build the actual file name containing a module. `directory' is the + * directory where the module file is supposed to be, or NULL or empty + * in which case it should either be in the current directory or, on + * some operating systems, in some standard place, for instance on the + * PATH. Hence, to be absoultely sure to get the correct module, + * always pass in a directory. The file name consists of the directory, + * if supplied, and `module_name' suitably decorated accoring to + * the operating system's conventions (for instance lib*.so or *.dll). + * + * No checks are made that the file exists, or is of correct type. + */ +gchar* local_hack_g_module_build_path (const gchar *directory, + const gchar *module_name); + +#ifdef __cplusplus +} +#endif /* __cplusplus */ + + +#endif /* __GMODULE_H__ */ --- imlib-1.9.15.orig/gdk_imlib/local-hack-gmodule/gmoduleconf.h +++ imlib-1.9.15/gdk_imlib/local-hack-gmodule/gmoduleconf.h @@ -0,0 +1,45 @@ +/* GMODULE - GLIB wrapper code for dynamic module loading + * Copyright (C) 1998 Tim Janik + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with this library; if not, write to the + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + */ +#ifndef __LOCAL_HACK_G_MODULE_CONF_H__ +#define __LOCAL_HACK_G_MODULE_CONF_H__ + + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + + +#define LOCAL_HACK_G_MODULE_IMPL_NONE 0 +#define LOCAL_HACK_G_MODULE_IMPL_DL 1 +#define LOCAL_HACK_G_MODULE_IMPL_DLD 2 +#define LOCAL_HACK_G_MODULE_IMPL_WIN32 3 + +#define LOCAL_HACK_G_MODULE_IMPL LOCAL_HACK_G_MODULE_IMPL_DL +#undef LOCAL_HACK_G_MODULE_HAVE_DLERROR +#if (1) +#define LOCAL_HACK_G_MODULE_HAVE_DLERROR +#endif + + +#ifdef __cplusplus +} +#endif /* __cplusplus */ + + +#endif /* __LOCAL_HACK_G_MODULE_CONF_H__ */ --- imlib-1.9.15.orig/gdk_imlib/local-hack-gmodule/gmodule-local.c +++ imlib-1.9.15/gdk_imlib/local-hack-gmodule/gmodule-local.c @@ -0,0 +1,418 @@ +/* GMODULE - GLIB wrapper code for dynamic module loading + * Copyright (C) 1998 Tim Janik + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with this library; if not, write to the + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + */ + +/* + * Modified by the GLib Team and others 1997-1999. See the AUTHORS + * file for a list of people on the GLib Team. See the ChangeLog + * files for a list of changes. These files are distributed with + * GLib at ftp://ftp.gtk.org/pub/gtk/. + */ + +/* + * MT safe + */ + +#include "gmodule-local.h" +#include "gmoduleconf.h" +#include +#include + + +/* We maintain a list of modules, so we can reference count them. + * That's needed because some platforms don't support refernce counts on + * modules e.g. the shl_* implementation of HP-UX + * (http://www.stat.umn.edu/~luke/xls/projects/dlbasics/dlbasics.html). + * Also, the module for the program itself is kept seperatedly for + * faster access and because it has special semantics. + */ + + +/* --- structures --- */ +struct _LocalHackGModule +{ + gchar *file_name; + gpointer handle; + guint ref_count : 31; + guint is_resident : 1; + LocalHackGModuleUnload unload; + LocalHackGModule *next; +}; + + +/* --- prototypes --- */ +static gpointer _local_hack_g_module_open (const gchar *file_name, + gboolean bind_lazy); +static void _local_hack_g_module_close (gpointer handle, + gboolean is_unref); +static gpointer _local_hack_g_module_self (void); +static gpointer _local_hack_g_module_symbol (gpointer handle, + const gchar *symbol_name); +static gchar* _local_hack_g_module_build_path (const gchar *directory, + const gchar *module_name); +static inline void local_hack_g_module_set_error (const gchar *error); +static inline LocalHackGModule* local_hack_g_module_find_by_handle (gpointer handle); +static inline LocalHackGModule* local_hack_g_module_find_by_name (const gchar *name); + + +/* --- variables --- */ +G_LOCK_DEFINE_STATIC (LocalHackGModule); +static LocalHackGModule *modules = NULL; +static LocalHackGModule *main_module = NULL; +static GStaticPrivate module_error_private = G_STATIC_PRIVATE_INIT; + + +/* --- inline functions --- */ +static inline LocalHackGModule* +local_hack_g_module_find_by_handle (gpointer handle) +{ + LocalHackGModule *module; + LocalHackGModule *retval = NULL; + + G_LOCK (LocalHackGModule); + if (main_module && main_module->handle == handle) + retval = main_module; + else + for (module = modules; module; module = module->next) + if (handle == module->handle) + { + retval = module; + break; + } + G_UNLOCK (LocalHackGModule); + + return retval; +} + +static inline LocalHackGModule* +local_hack_g_module_find_by_name (const gchar *name) +{ + LocalHackGModule *module; + LocalHackGModule *retval = NULL; + + G_LOCK (LocalHackGModule); + for (module = modules; module; module = module->next) + if (strcmp (name, module->file_name) == 0) + { + retval = module; + break; + } + G_UNLOCK (LocalHackGModule); + + return retval; +} + +static inline void +local_hack_g_module_set_error (const gchar *error) +{ + g_static_private_set (&module_error_private, g_strdup (error), g_free); + errno = 0; +} + + +/* --- include platform specifc code --- */ +#define SUPPORT_OR_RETURN(rv) { local_hack_g_module_set_error (NULL); } +#if (LOCAL_HACK_G_MODULE_IMPL == LOCAL_HACK_G_MODULE_IMPL_DL) +#include "gmodule-dl.c" +#elif (LOCAL_HACK_G_MODULE_IMPL == LOCAL_HACK_G_MODULE_IMPL_DLD) +#include "gmodule-dld.c" +#elif (LOCAL_HACK_G_MODULE_IMPL == LOCAL_HACK_G_MODULE_IMPL_WIN32) +#include "gmodule-win32.c" +#else +#undef SUPPORT_OR_RETURN +#define SUPPORT_OR_RETURN(rv) { local_hack_g_module_set_error ("dynamic modules are " \ + "not supported by this system"); return rv; } +static gpointer +_local_hack_g_module_open (const gchar *file_name, + gboolean bind_lazy) +{ + return NULL; +} +static void +_local_hack_g_module_close (gpointer handle, + gboolean is_unref) +{ +} +static gpointer +_local_hack_g_module_self (void) +{ + return NULL; +} +static gpointer +_local_hack_g_module_symbol (gpointer handle, + const gchar *symbol_name) +{ + return NULL; +} +static gchar* +_local_hack_g_module_build_path (const gchar *directory, + const gchar *module_name) +{ + return NULL; +} +#endif /* no implementation */ + +#if defined (NATIVE_WIN32) && defined (__LCC__) +int __stdcall +LibMain (void *hinstDll, + unsigned long dwReason, + void *reserved) +{ + return 1; +} +#endif /* NATIVE_WIN32 && __LCC__ */ + + +/* --- functions --- */ +gboolean +local_hack_g_module_supported (void) +{ + SUPPORT_OR_RETURN (FALSE); + + return TRUE; +} + +LocalHackGModule* +local_hack_g_module_open (const gchar *file_name, + LocalHackGModuleFlags flags) +{ + LocalHackGModule *module; + gpointer handle; + + SUPPORT_OR_RETURN (NULL); + + if (!file_name) + { + G_LOCK (LocalHackGModule); + if (!main_module) + { + handle = _local_hack_g_module_self (); + if (handle) + { + main_module = g_new (LocalHackGModule, 1); + main_module->file_name = NULL; + main_module->handle = handle; + main_module->ref_count = 1; + main_module->is_resident = TRUE; + main_module->unload = NULL; + main_module->next = NULL; + } + } + G_UNLOCK (LocalHackGModule); + + return main_module; + } + + /* we first search the module list by name */ + module = local_hack_g_module_find_by_name (file_name); + if (module) + { + module->ref_count++; + + return module; + } + + /* open the module */ + handle = _local_hack_g_module_open (file_name, (flags & LOCAL_HACK_G_MODULE_BIND_LAZY) != 0); + if (handle) + { + gchar *saved_error; + LocalHackGModuleCheckInit check_init; + const gchar *check_failed = NULL; + + /* search the module list by handle, since file names are not unique */ + module = local_hack_g_module_find_by_handle (handle); + if (module) + { + _local_hack_g_module_close (module->handle, TRUE); + module->ref_count++; + local_hack_g_module_set_error (NULL); + + return module; + } + + saved_error = g_strdup (local_hack_g_module_error ()); + local_hack_g_module_set_error (NULL); + + module = g_new (LocalHackGModule, 1); + module->file_name = g_strdup (file_name); + module->handle = handle; + module->ref_count = 1; + module->is_resident = FALSE; + module->unload = NULL; + G_LOCK (LocalHackGModule); + module->next = modules; + modules = module; + G_UNLOCK (LocalHackGModule); + + /* check initialization */ + if (local_hack_g_module_symbol (module, "local_hack_g_module_check_init", (gpointer) &check_init)) + check_failed = check_init (module); + + /* we don't call unload() if the initialization check failed. */ + if (!check_failed) + local_hack_g_module_symbol (module, "local_hack_g_module_unload", (gpointer) &module->unload); + + if (check_failed) + { + gchar *error; + + error = g_strconcat ("LocalHackGModule initialization check failed: ", check_failed, NULL); + local_hack_g_module_close (module); + module = NULL; + local_hack_g_module_set_error (error); + g_free (error); + } + else + local_hack_g_module_set_error (saved_error); + + g_free (saved_error); + } + + return module; +} + +gboolean +local_hack_g_module_close (LocalHackGModule *module) +{ + SUPPORT_OR_RETURN (FALSE); + + g_return_val_if_fail (module != NULL, FALSE); + g_return_val_if_fail (module->ref_count > 0, FALSE); + + module->ref_count--; + + if (!module->ref_count && !module->is_resident && module->unload) + { + LocalHackGModuleUnload unload; + + unload = module->unload; + module->unload = NULL; + unload (module); + } + + if (!module->ref_count && !module->is_resident) + { + LocalHackGModule *last; + LocalHackGModule *node; + + last = NULL; + + G_LOCK (LocalHackGModule); + node = modules; + while (node) + { + if (node == module) + { + if (last) + last->next = node->next; + else + modules = node->next; + break; + } + last = node; + node = last->next; + } + module->next = NULL; + G_UNLOCK (LocalHackGModule); + + _local_hack_g_module_close (module->handle, FALSE); + g_free (module->file_name); + + g_free (module); + } + + return local_hack_g_module_error() == NULL; +} + +void +local_hack_g_module_make_resident (LocalHackGModule *module) +{ + g_return_if_fail (module != NULL); + + module->is_resident = TRUE; +} + +gchar* +local_hack_g_module_error (void) +{ + return g_static_private_get (&module_error_private); +} + +gboolean +local_hack_g_module_symbol (LocalHackGModule *module, + const gchar *symbol_name, + gpointer *symbol) +{ + gchar *module_error; + + if (symbol) + *symbol = NULL; + SUPPORT_OR_RETURN (FALSE); + + g_return_val_if_fail (module != NULL, FALSE); + g_return_val_if_fail (symbol_name != NULL, FALSE); + g_return_val_if_fail (symbol != NULL, FALSE); + +#ifdef LOCAL_HACK_G_MODULE_NEED_USCORE + { + gchar *name; + + name = g_strconcat ("_", symbol_name, NULL); + *symbol = _local_hack_g_module_symbol (module->handle, name); + g_free (name); + } +#else /* !LOCAL_HACK_G_MODULE_NEED_USCORE */ + *symbol = _local_hack_g_module_symbol (module->handle, symbol_name); +#endif /* !LOCAL_HACK_G_MODULE_NEED_USCORE */ + + module_error = local_hack_g_module_error (); + if (module_error) + { + gchar *error; + + error = g_strconcat ("`", symbol_name, "': ", module_error, NULL); + local_hack_g_module_set_error (error); + g_free (error); + *symbol = NULL; + + return FALSE; + } + + return TRUE; +} + +gchar* +local_hack_g_module_name (LocalHackGModule *module) +{ + g_return_val_if_fail (module != NULL, NULL); + + if (module == main_module) + return "main"; + + return module->file_name; +} + +gchar* +local_hack_g_module_build_path (const gchar *directory, + const gchar *module_name) +{ + g_return_val_if_fail (module_name != NULL, NULL); + + return _local_hack_g_module_build_path (directory, module_name); +}