From: Juanma Barranquero <jmbarranquero@wke.es>
Subject: [PATCH] Delayed loading of image libraries
Date: Thu, 10 Jun 2004 14:38:46 +0200 [thread overview]
Message-ID: <20040610133420.CAC7.JMBARRANQUERO@wke.es> (raw)
OK, this is the (hopefully) final version of the "delayed loading" patch.
It is almost identical to the last one, except for renaming a few things
and adding a missing staticpro that was causing problems on
bootstrapping. I've added docs to display.texi, and an entry to
etc/NEWS (though I'm, as always, unsure about the right place to put the
entry). The only thing lacking is ChangeLog entries.
As I said a few days ago, I'd like to install this on trunk, if no one
has objections.
Any comments welcome, of course.
Juanma
--- old/etc/NEWS 2004-06-10 09:27:32.000000000 +0200
+++ new/etc/NEWS 2004-06-10 13:32:53.000000000 +0200
@@ -17,4 +17,8 @@
* Installation Changes in Emacs 21.4
+** On MS Windows, Emacs now loads the image libraries on demand.
+You can configure the supported image types and their associated dynamic
+libraries by setting the variable `image-library-alist'.
+
---
** A Bulgarian translation of the Emacs Tutorial is available.
diff -Bru2 old/lisp/image.el new/lisp/image.el
--- old/lisp/image.el 2004-06-10 09:27:54.000000000 +0200
+++ new/lisp/image.el 2004-06-10 11:46:40.000000000 +0200
@@ -49,4 +49,15 @@
a non-nil value, TYPE is the image's type.")
+;;;###autoload
+(defvar image-library-alist nil
+ "Alist of image types vs external libraries needed to display them.
+
+Each element is a list (IMAGE-TYPE LIBRARY...), where the car is a symbol
+representing a supported image type, and the rest are strings giving
+alternate filenames for the corresponding external libraries to load.
+They are tried in the order they appear on the list; if none of them can
+be loaded, the running session of Emacs won't display the image type.
+No entries are needed for pbm and xbm images; they're always supported.")
+;;;###autoload (put 'image-library-alist 'risky-local-variable t)
(defun image-jpeg-p (data)
@@ -112,6 +123,6 @@
"Value is non-nil if image type TYPE is available.
Image types are symbols like `xbm' or `jpeg'."
- (and (boundp 'image-types) (not (null (memq type image-types)))))
-
+ (and (fboundp 'init-image-library)
+ (init-image-library type image-library-alist)))
;;;###autoload
diff -Bru2 old/lisp/term/w32-win.el new/lisp/term/w32-win.el
--- old/lisp/term/w32-win.el 2004-06-10 09:28:04.000000000 +0200
+++ new/lisp/term/w32-win.el 2004-06-10 11:46:41.000000000 +0200
@@ -1262,4 +1262,12 @@
(error "Font not found")))))
+;;; Set default known names for image libraries
+(setq image-library-alist
+ '((xpm "libXpm-nox4.dll" "libxpm.dll")
+ (png "libpng13d.dll" "libpng13.dll" "libpng12d.dll" "libpng12.dll" "libpng.dll")
+ (jpeg "jpeg62.dll" "libjpeg.dll" "jpeg-62.dll" "jpeg.dll")
+ (tiff "libtiff3.dll" "libtiff.dll")
+ (gif "libungif.dll")))
+
;;; arch-tag: 69fb1701-28c2-4890-b351-3d1fe4b4f166
;;; w32-win.el ends here
diff -Bru2 old/lispref/display.texi new/lispref/display.texi
--- old/lispref/display.texi 2004-06-10 09:28:10.000000000 +0200
+++ new/lispref/display.texi 2004-06-10 13:01:02.000000000 +0200
@@ -2876,6 +2876,11 @@
Emacs can display a number of different image formats; some of them
-are supported only if particular support libraries are installed on your
-machine. The supported image formats include XBM, XPM (needing the
+are supported only if particular support libraries are installed on
+your machine. In some environments, Emacs allows loading image
+libraries on demand; if so, the variable @code{image-library-alist}
+can be used to modify the set of known names for these dynamic
+libraries (though it is not posible to add new image formats).
+
+ The supported image formats include XBM, XPM (needing the
libraries @code{libXpm} version 3.4k and @code{libz}), GIF (needing
@code{libungif} 4.1.0), Postscript, PBM, JPEG (needing the
@@ -2888,9 +2893,47 @@
@defvar image-types
+@vindex image-types
This variable contains a list of those image type symbols that are
-supported in the current configuration.
+potentially supported in the current configuration.
+@emph{Potentially} here means that Emacs knows about the image types,
+not necessarily that they can be loaded (they could depend on
+unavailable dynamic libraries, for example).
+
+To know which image types are really available, use
+@code{image-type-available-p}.
+@end defvar
+
+@defvar image-library-alist
+@vindex image-library-alist
+This in an alist of image types vs external libraries needed to
+display them.
+
+Each element is a list @code{(@var{IMAGE-TYPE} @var{LIBRARY}...)},
+where the car is a supported image format from @code{image-types}, and
+the rest are strings giving alternate filenames for the corresponding
+external libraries to load.
+
+They are tried in the order they appear on the list; if none of them
+can be loaded, the running session of Emacs won't support the image
+type. No entries are needed for @code{pbm} and @code{xbm} images;
+they're always supported.
+
+This variable is ignored if the image libraries are statically linked
+into Emacs.
@end defvar
+@defun image-type-available-p type
+@findex image-type-available-p
+
+This function returns non-nil if image type TYPE is available, i.e.,
+if images of this type can be loaded and displayed in Emacs. TYPE
+should be one of the types contained in @code{image-types}.
+
+For image types whose support libraries are statically linked, this
+function always returns @code{t}; for other image types, it returns
+@code{t} if the dynamic library could be loaded, @code{nil} otherwise.
+@end defun
+
@menu
* Image Descriptors:: How to specify an image for use in @code{:display}.
--- old/src/dispextern.h 2004-06-10 09:28:19.000000000 +0200
+++ new/src/dispextern.h 2004-06-10 11:46:41.000000000 +0200
@@ -2569,5 +2569,4 @@
extern int mode_line_in_non_selected_windows;
extern int redisplaying_p;
-extern Lisp_Object Vimage_types;
extern void add_to_log P_ ((char *, Lisp_Object, Lisp_Object));
extern int help_echo_showing_p;
@@ -2655,4 +2654,6 @@
#ifdef HAVE_WINDOW_SYSTEM
+extern Lisp_Object Vimage_types;
+
extern int x_bitmap_height P_ ((struct frame *, int));
extern int x_bitmap_width P_ ((struct frame *, int));
diff -Bru2 old/src/image.c new/src/image.c
--- old/src/image.c 2004-06-10 09:28:20.000000000 +0200
+++ new/src/image.c 2004-06-10 11:51:49.000000000 +0200
@@ -606,4 +606,12 @@
static struct image_type *image_types;
+/* A list of symbols, one for each supported image type. */
+
+Lisp_Object Vimage_types;
+
+/* Cache for delayed-loading image types. */
+
+static Lisp_Object Vimage_type_cache;
+
/* The symbol `xbm' which is used as the type symbol for XBM images. */
@@ -630,5 +638,5 @@
/* Function prototypes. */
-static void define_image_type P_ ((struct image_type *type));
+static Lisp_Object define_image_type P_ ((struct image_type *type, int loaded));
static struct image_type *lookup_image_type P_ ((Lisp_Object symbol));
static void image_error P_ ((char *format, Lisp_Object, Lisp_Object));
@@ -638,19 +646,35 @@
Lisp_Object));
+#define CACHE_IMAGE_TYPE(type, status) \
+ do { Vimage_type_cache = Fcons (Fcons (type, status), Vimage_type_cache); } while (0)
+
+#define ADD_IMAGE_TYPE(type) \
+ do { Vimage_types = Fcons (type, Vimage_types); } while (0)
/* Define a new image type from TYPE. This adds a copy of TYPE to
- image_types and adds the symbol *TYPE->type to Vimage_types. */
+ image_types and caches the loading status of TYPE. */
-static void
-define_image_type (type)
+static Lisp_Object
+define_image_type (type, loaded)
struct image_type *type;
+ int loaded;
{
- /* Make a copy of TYPE to avoid a bus error in a dumped Emacs.
- The initialized data segment is read-only. */
- struct image_type *p = (struct image_type *) xmalloc (sizeof *p);
- bcopy (type, p, sizeof *p);
- p->next = image_types;
- image_types = p;
- Vimage_types = Fcons (*p->type, Vimage_types);
+ Lisp_Object success;
+
+ if (!loaded)
+ success = Qnil;
+ else
+ {
+ /* Make a copy of TYPE to avoid a bus error in a dumped Emacs.
+ The initialized data segment is read-only. */
+ struct image_type *p = (struct image_type *) xmalloc (sizeof *p);
+ bcopy (type, p, sizeof *p);
+ p->next = image_types;
+ image_types = p;
+ success = Qt;
+ }
+
+ CACHE_IMAGE_TYPE(*type->type, success);
+ return success;
}
@@ -1789,4 +1813,31 @@
}
+/* Load a DLL implementing an image type.
+ The `image-library-alist' variable associates a symbol,
+ identifying an image type, to a list of possible filenames.
+ The function returns NULL if no library could be loaded for
+ the given image type, or if the library was previously loaded;
+ else the handle of the DLL. */
+static HMODULE
+w32_delayed_load (Lisp_Object libraries, Lisp_Object type)
+{
+ HMODULE library = NULL;
+
+ if (CONSP (libraries) && NILP (Fassq (type, Vimage_type_cache)))
+ {
+ Lisp_Object dlls = Fassq (type, libraries);
+
+ if (CONSP (dlls))
+ for (dlls = XCDR (dlls); CONSP (dlls); dlls = XCDR (dlls))
+ {
+ CHECK_STRING_CAR (dlls);
+ if (library = LoadLibrary (SDATA (XCAR (dlls))))
+ break;
+ }
+ }
+
+ return library;
+}
+
#endif /* HAVE_NTGUI */
@@ -3489,11 +3540,10 @@
DEF_IMGLIB_FN (XImageFree);
-
static int
-init_xpm_functions (void)
+init_xpm_functions (Lisp_Object libraries)
{
HMODULE library;
- if (!(library = LoadLibrary ("libXpm.dll")))
+ if (!(library = w32_delayed_load (libraries, Qxpm)))
return 0;
@@ -5589,19 +5639,10 @@
static int
-init_png_functions (void)
+init_png_functions (Lisp_Object libraries)
{
HMODULE library;
- /* Ensure zlib is loaded. Try debug version first. */
- if (!LoadLibrary ("zlibd.dll")
- && !LoadLibrary ("zlib.dll"))
- return 0;
-
/* Try loading libpng under probable names. */
- if (!(library = LoadLibrary ("libpng13d.dll"))
- && !(library = LoadLibrary ("libpng13.dll"))
- && !(library = LoadLibrary ("libpng12d.dll"))
- && !(library = LoadLibrary ("libpng12.dll"))
- && !(library = LoadLibrary ("libpng.dll")))
+ if (!(library = w32_delayed_load (libraries, Qpng)))
return 0;
@@ -6247,11 +6288,9 @@
static int
-init_jpeg_functions (void)
+init_jpeg_functions (Lisp_Object libraries)
{
HMODULE library;
- if (!(library = LoadLibrary ("libjpeg.dll"))
- && !(library = LoadLibrary ("jpeg-62.dll"))
- && !(library = LoadLibrary ("jpeg.dll")))
+ if (!(library = w32_delayed_load (libraries, Qjpeg)))
return 0;
@@ -6684,9 +6723,9 @@
static int
-init_tiff_functions (void)
+init_tiff_functions (Lisp_Object libraries)
{
HMODULE library;
- if (!(library = LoadLibrary ("libtiff.dll")))
+ if (!(library = w32_delayed_load (libraries, Qtiff)))
return 0;
@@ -7104,9 +7143,9 @@
static int
-init_gif_functions (void)
+init_gif_functions (Lisp_Object libraries)
{
HMODULE library;
- if (!(library = LoadLibrary ("libungif.dll")))
+ if (!(library = w32_delayed_load (libraries, Qgif)))
return 0;
@@ -7881,7 +7920,79 @@
***********************************************************************/
+#ifdef HAVE_NTGUI
+/* Image types that rely on external libraries are loaded dynamically
+ if the library is available. */
+#define CHECK_LIB_AVAILABLE(image_type, init_lib_fn) \
+ define_image_type (image_type, init_lib_fn (libraries))
+#else
+#define CHECK_LIB_AVAILABLE(image_type, init_lib_fn) \
+ define_image_type (image_type, TRUE)
+#endif /* HAVE_NTGUI */
+
+DEFUN ("init-image-library", Finit_image_library, Sinit_image_library, 2, 2, 0,
+ doc: /* Initialize image library implementing image type TYPE.
+Return non-nil if TYPE is a supported image type.
+
+Image types pbm and xbm are prebuilt; other types are loaded here.
+Libraries to load are specified in alist LIBRARIES (usually, the value
+of `image-library-alist', which see. */)
+ (type, libraries)
+{
+ Lisp_Object tested;
+
+ /* Don't try to reload the library. */
+ tested = Fassq (type, Vimage_type_cache);
+ if (CONSP (tested))
+ return XCDR (tested);
+
+#if defined (HAVE_XPM) || defined (MAC_OS)
+ if (EQ (type, Qxpm))
+ return CHECK_LIB_AVAILABLE(&xpm_type, init_xpm_functions);
+#endif
+
+#if defined (HAVE_JPEG) || defined (MAC_OS)
+ if (EQ (type, Qjpeg))
+ return CHECK_LIB_AVAILABLE(&jpeg_type, init_jpeg_functions);
+#endif
+
+#if defined (HAVE_TIFF) || defined (MAC_OS)
+ if (EQ (type, Qtiff))
+ return CHECK_LIB_AVAILABLE(&tiff_type, init_tiff_functions);
+#endif
+
+#if defined (HAVE_GIF) || defined (MAC_OS)
+ if (EQ (type, Qgif))
+ return CHECK_LIB_AVAILABLE(&gif_type, init_gif_functions);
+#endif
+
+#if defined (HAVE_PNG) || defined (MAC_OS)
+ if (EQ (type, Qpng))
+ return CHECK_LIB_AVAILABLE(&png_type, init_png_functions);
+#endif
+
+#ifdef HAVE_GHOSTSCRIPT
+ if (EQ (type, Qpostscript))
+ return CHECK_LIB_AVAILABLE(&gs_type, init_gs_functions);
+#endif
+
+ /* If the type is not recognized, avoid testing it ever again. */
+ CACHE_IMAGE_TYPE(type, Qnil);
+ return Qnil;
+}
+
void
syms_of_image ()
{
+ /* Must be defined now becase we're going to update it below, while
+ defining the supported image types. */
+ DEFVAR_LISP ("image-types", &Vimage_types,
+ doc: /* List of potentially supported image types.
+Each element of the list is a symbol for a image type, like 'jpeg or 'png.
+To check whether it is really supported, use `image-type-available-p'. */);
+ Vimage_types = Qnil;
+
+ Vimage_type_cache = Qnil;
+ staticpro (&Vimage_type_cache);
+
QCascent = intern (":ascent");
staticpro (&QCascent);
@@ -7917,4 +8028,5 @@
staticpro (&Qpostscript);
#ifdef HAVE_GHOSTSCRIPT
+ ADD_IMAGE_TYPE(Qpostscript);
QCloader = intern (":loader");
staticpro (&QCloader);
@@ -7929,11 +8041,14 @@
Qpbm = intern ("pbm");
staticpro (&Qpbm);
+ ADD_IMAGE_TYPE(Qpbm);
Qxbm = intern ("xbm");
staticpro (&Qxbm);
+ ADD_IMAGE_TYPE(Qxbm);
#if defined (HAVE_XPM) || defined (MAC_OS)
Qxpm = intern ("xpm");
staticpro (&Qxpm);
+ ADD_IMAGE_TYPE(Qxpm);
#endif
@@ -7941,4 +8056,5 @@
Qjpeg = intern ("jpeg");
staticpro (&Qjpeg);
+ ADD_IMAGE_TYPE(Qjpeg);
#endif
@@ -7946,4 +8062,5 @@
Qtiff = intern ("tiff");
staticpro (&Qtiff);
+ ADD_IMAGE_TYPE(Qtiff);
#endif
@@ -7951,4 +8068,5 @@
Qgif = intern ("gif");
staticpro (&Qgif);
+ ADD_IMAGE_TYPE(Qgif);
#endif
@@ -7956,6 +8074,8 @@
Qpng = intern ("png");
staticpro (&Qpng);
+ ADD_IMAGE_TYPE(Qpng);
#endif
+ defsubr (&Sinit_image_library);
defsubr (&Sclear_image_cache);
defsubr (&Simage_size);
@@ -7985,50 +8105,11 @@
}
-
-#ifdef HAVE_NTGUI
-/* Image types that rely on external libraries are loaded dynamically
- if the library is available. */
-#define IF_LIB_AVAILABLE(init_lib_fn) if (init_lib_fn())
-#else
-#define IF_LIB_AVAILABLE(init_func) /* Load unconditionally */
-#endif /* HAVE_NTGUI */
-
void
init_image ()
{
image_types = NULL;
- Vimage_types = Qnil;
- define_image_type (&xbm_type);
- define_image_type (&pbm_type);
-
-#if defined (HAVE_XPM) || defined (MAC_OS)
- IF_LIB_AVAILABLE(init_xpm_functions)
- define_image_type (&xpm_type);
-#endif
-
-#if defined (HAVE_JPEG) || defined (MAC_OS)
- IF_LIB_AVAILABLE(init_jpeg_functions)
- define_image_type (&jpeg_type);
-#endif
-
-#if defined (HAVE_TIFF) || defined (MAC_OS)
- IF_LIB_AVAILABLE(init_tiff_functions)
- define_image_type (&tiff_type);
-#endif
-
-#if defined (HAVE_GIF) || defined (MAC_OS)
- IF_LIB_AVAILABLE(init_gif_functions)
- define_image_type (&gif_type);
-#endif
-
-#if defined (HAVE_PNG) || defined (MAC_OS)
- IF_LIB_AVAILABLE(init_png_functions)
- define_image_type (&png_type);
-#endif
-
-#ifdef HAVE_GHOSTSCRIPT
- define_image_type (&gs_type);
-#endif
+ define_image_type (&xbm_type, TRUE);
+ define_image_type (&pbm_type, TRUE);
#ifdef MAC_OS
diff -Bru2 old/src/xdisp.c new/src/xdisp.c
--- old/src/xdisp.c 2004-06-10 09:28:26.000000000 +0200
+++ new/src/xdisp.c 2004-06-10 11:46:41.000000000 +0200
@@ -671,8 +671,4 @@
Lisp_Object Vhscroll_step;
-/* A list of symbols, one for each supported image type. */
-
-Lisp_Object Vimage_types;
-
/* The variable `resize-mini-windows'. If nil, don't resize
mini-windows. If t, always resize them to fit the text they
@@ -22260,9 +22256,4 @@
Vhscroll_step = make_number (0);
- DEFVAR_LISP ("image-types", &Vimage_types,
- doc: /* List of supported image types.
-Each element of the list is a symbol for a supported image type. */);
- Vimage_types = Qnil;
-
DEFVAR_BOOL ("message-truncate-lines", &message_truncate_lines,
doc: /* If non-nil, messages are truncated instead of resizing the echo area.
next reply other threads:[~2004-06-10 12:38 UTC|newest]
Thread overview: 25+ messages / expand[flat|nested] mbox.gz Atom feed top
2004-06-10 12:38 Juanma Barranquero [this message]
2004-06-30 10:15 ` [PATCH] Delayed loading of image libraries Andreas Schwab
2004-06-30 11:13 ` Juanma Barranquero
2004-06-30 11:24 ` Andreas Schwab
2004-06-30 11:34 ` Juanma Barranquero
2004-06-30 11:41 ` Andreas Schwab
2004-06-30 13:00 ` Juanma Barranquero
2004-06-30 15:42 ` Miles Bader
2004-07-01 9:30 ` Juanma Barranquero
2004-07-01 9:48 ` Miles Bader
2004-07-01 10:13 ` Juanma Barranquero
2004-07-02 1:16 ` Miles Bader
2004-07-02 7:02 ` Juanma Barranquero
2004-07-02 7:10 ` David Kastrup
2004-07-02 7:41 ` Juanma Barranquero
2004-07-02 7:56 ` Miles Bader
2004-07-02 8:10 ` Juanma Barranquero
2004-07-02 8:20 ` Miles Bader
2004-07-02 8:45 ` Juanma Barranquero
2004-07-02 8:59 ` Miles Bader
2004-07-02 9:02 ` Miles Bader
2004-07-02 8:11 ` David Kastrup
2004-07-02 8:34 ` Juanma Barranquero
2004-07-03 18:21 ` Richard Stallman
2004-06-30 14:19 ` Stefan
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
List information: https://www.gnu.org/software/emacs/
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20040610133420.CAC7.JMBARRANQUERO@wke.es \
--to=jmbarranquero@wke.es \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
Code repositories for project(s) associated with this public inbox
https://git.savannah.gnu.org/cgit/emacs.git
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).