From 594a430782d12499543637915fd974483523f500 Mon Sep 17 00:00:00 2001 From: Eli Zaretskii Date: Mon, 12 Aug 2013 16:15:01 +0300 Subject: [PATCH] Fix build with zlib on MS-Windows. configure.ac (LIBZ): Comment on w32 peculiarities regarding LIBZ. src/decompress.c [WINDOWSNT]: Include windows.h and w32.h. (DEF_ZLIB_FN, LOAD_ZLIB_FN) [WINDOWSNT]: New macros. Use them to define static variables that are pointers to zlib functions to be dynamically loaded. (init_zlib_functions) [WINDOWSNT]: New function. (fn_inflateInit2_, fn_inflate, fn_inflateEnd, fn_inflateInit2): New macros. (Fdecompress_gzipped_region, unwind_decompress): Use the fn_* macros instead of invoking the zlib functions directly. (syms_of_decompress): DEFSYM Qzlib_dll. Staticpro Szlib_available_p. lisp/term/w32-win.el (dynamic-library-alist): Add DLLs for zlib. --- ChangeLog | 4 +++ configure.ac | 3 ++ lisp/ChangeLog | 4 +++ lisp/term/w32-win.el | 3 +- src/ChangeLog | 14 ++++++++ src/decompress.c | 80 ++++++++++++++++++++++++++++++++++++++++++-- 6 files changed, 104 insertions(+), 4 deletions(-) diff --git a/ChangeLog b/ChangeLog index 1feddc0a8e2..641cbefce20 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,7 @@ +2013-08-12 Eli Zaretskii + + * configure.ac (LIBZ): Comment on w32 peculiarities regarding LIBZ. + 2013-08-12 Paul Eggert Merge from gnulib, incorporating: diff --git a/configure.ac b/configure.ac index 3a311989887..5daf84be2ba 100644 --- a/configure.ac +++ b/configure.ac @@ -2948,6 +2948,9 @@ LIBZ= if test "${with_zlib}" != "no"; then if test "${HAVE_PNG}" = "yes"; then ### PNG depends on zlib, so if we have PNG, we have zlib. + ### Note: w32 does not link against libpng, but instead loads it + ### dynamically, but it also does the same with zlib. So it is OK + ### not to have -lz in LIBZ on w32. HAVE_ZLIB=yes else ### No PNG, so check zlib ourselves. diff --git a/lisp/ChangeLog b/lisp/ChangeLog index 1b7aceb5979..8d838622680 100644 --- a/lisp/ChangeLog +++ b/lisp/ChangeLog @@ -1,3 +1,7 @@ +2013-08-12 Eli Zaretskii + + * term/w32-win.el (dynamic-library-alist): Add DLLs for zlib. + 2013-08-12 Glenn Morris * format.el (format-annotate-function): diff --git a/lisp/term/w32-win.el b/lisp/term/w32-win.el index acadb0fad43..55181ab7d6d 100644 --- a/lisp/term/w32-win.el +++ b/lisp/term/w32-win.el @@ -229,7 +229,8 @@ See the documentation of `create-fontset-from-fontset-spec' for the format.") '(glib "libglib-2.0-0.dll") '(gobject "libgobject-2.0-0.dll") '(gnutls "libgnutls-28.dll" "libgnutls-26.dll") - '(libxml2 "libxml2-2.dll" "libxml2.dll"))) + '(libxml2 "libxml2-2.dll" "libxml2.dll") + '(zlib "zlib1.dll" "libz-1.dll"))) ;;; multi-tty support (defvar w32-initialized nil diff --git a/src/ChangeLog b/src/ChangeLog index 679b82ba63c..44af7c6b385 100644 --- a/src/ChangeLog +++ b/src/ChangeLog @@ -1,3 +1,17 @@ +2013-08-12 Eli Zaretskii + + * decompress.c [WINDOWSNT]: Include windows.h and w32.h. + (DEF_ZLIB_FN, LOAD_ZLIB_FN) [WINDOWSNT]: New macros. Use them to + define static variables that are pointers to zlib functions to be + dynamically loaded. + (init_zlib_functions) [WINDOWSNT]: New function. + (fn_inflateInit2_, fn_inflate, fn_inflateEnd, fn_inflateInit2): + New macros. + (Fdecompress_gzipped_region, unwind_decompress): Use the fn_* + macros instead of invoking the zlib functions directly. + (syms_of_decompress): DEFSYM Qzlib_dll. Staticpro + Szlib_available_p. + 2013-08-12 Dmitry Antipov Avoid looping over all frame windows to freeze and unfreeze. diff --git a/src/decompress.c b/src/decompress.c index 866f4f51516..af8435b2fd0 100644 --- a/src/decompress.c +++ b/src/decompress.c @@ -26,6 +26,58 @@ along with GNU Emacs. If not, see . */ #include "character.h" #include "buffer.h" +static Lisp_Object Qzlib_dll; + +#ifdef WINDOWSNT +#include +#include "w32.h" + +/* Macro for defining functions that will be loaded from the zlib DLL. */ +#define DEF_ZLIB_FN(rettype,func,args) static rettype (FAR CDECL *fn_##func)args + +/* Macro for loading zlib functions from the library. */ +#define LOAD_ZLIB_FN(lib,func) { \ + fn_##func = (void *) GetProcAddress (lib, #func); \ + if (!fn_##func) return 0; \ + } + +DEF_ZLIB_FN (int, inflateInit2_, + (z_streamp strm, int windowBits, const char *version, int stream_size)); + +DEF_ZLIB_FN (int, inflate, + (z_streamp strm, int flush)); + +DEF_ZLIB_FN (int, inflateEnd, + (z_streamp strm)); + +static bool +init_zlib_functions (void) +{ + HMODULE library = w32_delayed_load (Qzlib_dll); + + if (!library) + { + message1 ("zlib library not found"); + return 0; + } + + LOAD_ZLIB_FN (library, inflateInit2_); + LOAD_ZLIB_FN (library, inflate); + LOAD_ZLIB_FN (library, inflateEnd); + return 1; +} + +#else /* !WINDOWSNT */ + +#define fn_inflateInit2_ inflateInit2_ +#define fn_inflate inflate +#define fn_inflateEnd inflateEnd + +#endif /* WINDOWSNT */ + +#define fn_inflateInit2(strm, windowBits) \ + fn_inflateInit2_((strm), (windowBits), ZLIB_VERSION, sizeof(z_stream)) + struct decompress_unwind_data { @@ -37,7 +89,7 @@ static void unwind_decompress (void *ddata) { struct decompress_unwind_data *data = ddata; - inflateEnd (data->stream); + fn_inflateEnd (data->stream); /* Delete any uncompressed data already inserted and restore point. */ if (data->start) @@ -47,6 +99,26 @@ unwind_decompress (void *ddata) } } +DEFUN ("zlib-available-p", Fzlib_available_p, Szlib_available_p, 0, 0, 0, + doc: /* Return t if zlib decompression is available in this instance of Emacs. */) + (void) +{ +#ifdef WINDOWSNT + Lisp_Object found = Fassq (Qzlib_dll, Vlibrary_cache); + if (CONSP (found)) + return XCDR (found); + else + { + Lisp_Object status; + status = init_zlib_functions () ? Qt : Qnil; + Vlibrary_cache = Fcons (Fcons (Qzlib_dll, status), Vlibrary_cache); + return status; + } +#else + return Qt; +#endif +} + DEFUN ("decompress-gzipped-region", Fdecompress_gzipped_region, Sdecompress_gzipped_region, 2, 2, 0, @@ -80,7 +152,7 @@ This function can be called only in unibyte buffers. */) stream.next_in = Z_NULL; /* This magic number apparently means "this is gzip". */ - if (inflateInit2 (&stream, 16 + MAX_WBITS) != Z_OK) + if (fn_inflateInit2 (&stream, 16 + MAX_WBITS) != Z_OK) return Qnil; unwind_data.start = iend; @@ -111,7 +183,7 @@ This function can be called only in unibyte buffers. */) stream.avail_in = avail_in; stream.next_out = GPT_ADDR; stream.avail_out = avail_out; - inflate_status = inflate (&stream, Z_NO_FLUSH); + inflate_status = fn_inflate (&stream, Z_NO_FLUSH); pos_byte += avail_in - stream.avail_in; decompressed = avail_out - stream.avail_out; insert_from_gap (decompressed, decompressed, 0); @@ -137,7 +209,9 @@ This function can be called only in unibyte buffers. */) void syms_of_decompress (void) { + DEFSYM (Qzlib_dll, "zlib"); defsubr (&Sdecompress_gzipped_region); + defsubr (&Szlib_available_p); } #endif /* HAVE_ZLIB */ -- 2.39.2