=== modified file 'lisp/term/w32-win.el'
--- lisp/term/w32-win.el	2011-02-03 07:31:42 +0000
+++ lisp/term/w32-win.el	2011-05-02 01:12:42 +0000
@@ -208,7 +208,8 @@
         '(svg "librsvg-2-2.dll")
         '(gdk-pixbuf "libgdk_pixbuf-2.0-0.dll")
         '(glib "libglib-2.0-0.dll")
-	'(gobject "libgobject-2.0-0.dll")))
+       '(gobject "libgobject-2.0-0.dll")
+       '(gnutls "libgnutls-26.dll")))
 
 ;;; multi-tty support
 (defvar w32-initialized nil

=== modified file 'src/gnutls.c'
--- src/gnutls.c	2011-05-02 02:49:06 +0000
+++ src/gnutls.c	2011-05-03 02:21:35 +0000
@@ -34,6 +34,7 @@
 static int
 emacs_gnutls_handle_error (gnutls_session_t, int err);
 
+static Lisp_Object Qgnutls_dll;
 static Lisp_Object Qgnutls_log_level;
 static Lisp_Object Qgnutls_code;
 static Lisp_Object Qgnutls_anon, Qgnutls_x509pki;
@@ -55,6 +56,145 @@
 /* Callback keys for `gnutls-boot'.  Unused currently.  */
 static Lisp_Object Qgnutls_bootprop_callbacks_verify;
 
+#ifdef WINDOWSNT
+
+/* Macro for defining functions that will be loaded from the GnuTLS DLL.  */
+#define DEF_GNUTLS_FN(rettype,func,args) rettype (FAR CDECL *fn_##func)args
+
+/* Macro for loading GnuTLS functions from the library.  */
+#define LOAD_GNUTLS_FN(lib,func) {					\
+    fn_##func = (void *) GetProcAddress (lib, #func);			\
+    if (!fn_##func) return 0;						\
+  }
+
+DEF_GNUTLS_FN (gnutls_alert_description_t, gnutls_alert_get, (gnutls_session_t));
+DEF_GNUTLS_FN (const char *, gnutls_alert_get_name, (gnutls_alert_description_t));
+DEF_GNUTLS_FN (int, gnutls_alert_send_appropriate, (gnutls_session_t, int));
+DEF_GNUTLS_FN (int, gnutls_anon_allocate_client_credentials, (gnutls_anon_client_credentials_t *));
+DEF_GNUTLS_FN (void, gnutls_anon_free_client_credentials, (gnutls_anon_client_credentials_t));
+DEF_GNUTLS_FN (int, gnutls_bye, (gnutls_session_t, gnutls_close_request_t));
+DEF_GNUTLS_FN (int, gnutls_certificate_allocate_credentials, (gnutls_certificate_credentials_t *));
+DEF_GNUTLS_FN (void, gnutls_certificate_free_credentials, (gnutls_certificate_credentials_t));
+DEF_GNUTLS_FN (const gnutls_datum_t *, gnutls_certificate_get_peers, (gnutls_session_t, unsigned int *));
+DEF_GNUTLS_FN (void, gnutls_certificate_set_verify_flags, (gnutls_certificate_credentials_t, unsigned int));
+DEF_GNUTLS_FN (int, gnutls_certificate_set_x509_crl_file, (gnutls_certificate_credentials_t, const char *, gnutls_x509_crt_fmt_t));
+DEF_GNUTLS_FN (int, gnutls_certificate_set_x509_trust_file, (gnutls_certificate_credentials_t, const char *, gnutls_x509_crt_fmt_t));
+DEF_GNUTLS_FN (gnutls_certificate_type_t, gnutls_certificate_type_get, (gnutls_session_t));
+DEF_GNUTLS_FN (int, gnutls_certificate_verify_peers2, (gnutls_session_t, unsigned int *));
+DEF_GNUTLS_FN (int, gnutls_credentials_set, (gnutls_session_t, gnutls_credentials_type_t, void *));
+DEF_GNUTLS_FN (void, gnutls_deinit, (gnutls_session_t));
+DEF_GNUTLS_FN (int, gnutls_error_is_fatal, (int));
+DEF_GNUTLS_FN (int, gnutls_global_init, (void));
+DEF_GNUTLS_FN (void, gnutls_global_set_log_function, (gnutls_log_func));
+DEF_GNUTLS_FN (void, gnutls_global_set_log_level, (int));
+DEF_GNUTLS_FN (int, gnutls_handshake, (gnutls_session_t));
+DEF_GNUTLS_FN (int, gnutls_init, (gnutls_session_t *, gnutls_connection_end_t));
+DEF_GNUTLS_FN (int, gnutls_priority_set_direct, (gnutls_session_t, const char *, const char **));
+DEF_GNUTLS_FN (size_t, gnutls_record_check_pending, (gnutls_session_t));
+DEF_GNUTLS_FN (ssize_t, gnutls_record_recv, (gnutls_session_t, void *, size_t));
+DEF_GNUTLS_FN (ssize_t, gnutls_record_send, (gnutls_session_t, const void *, size_t));
+DEF_GNUTLS_FN (const char *, gnutls_strerror, (int));
+DEF_GNUTLS_FN (void, gnutls_transport_set_errno, (gnutls_session_t, int));
+DEF_GNUTLS_FN (void, gnutls_transport_set_lowat, (gnutls_session_t, int));
+DEF_GNUTLS_FN (void, gnutls_transport_set_ptr2, (gnutls_session_t, gnutls_transport_ptr_t, gnutls_transport_ptr_t));
+DEF_GNUTLS_FN (void, gnutls_transport_set_pull_function, (gnutls_session_t, gnutls_pull_func));
+DEF_GNUTLS_FN (void, gnutls_transport_set_push_function, (gnutls_session_t, gnutls_push_func));
+DEF_GNUTLS_FN (int, gnutls_x509_crt_check_hostname, (gnutls_x509_crt_t, const char *));
+DEF_GNUTLS_FN (void, gnutls_x509_crt_deinit, (gnutls_x509_crt_t));
+DEF_GNUTLS_FN (int, gnutls_x509_crt_import, (gnutls_x509_crt_t, const gnutls_datum_t *, gnutls_x509_crt_fmt_t));
+DEF_GNUTLS_FN (int, gnutls_x509_crt_init, (gnutls_x509_crt_t *));
+
+static int
+init_gnutls_functions (Lisp_Object libraries)
+{
+  HMODULE library;
+
+  if (!(library = w32_delayed_load (libraries, Qgnutls_dll)))
+    return 0;
+
+  LOAD_GNUTLS_FN (library, gnutls_alert_get);
+  LOAD_GNUTLS_FN (library, gnutls_alert_get_name);
+  LOAD_GNUTLS_FN (library, gnutls_alert_send_appropriate);
+  LOAD_GNUTLS_FN (library, gnutls_anon_allocate_client_credentials);
+  LOAD_GNUTLS_FN (library, gnutls_anon_free_client_credentials);
+  LOAD_GNUTLS_FN (library, gnutls_bye);
+  LOAD_GNUTLS_FN (library, gnutls_certificate_allocate_credentials);
+  LOAD_GNUTLS_FN (library, gnutls_certificate_free_credentials);
+  LOAD_GNUTLS_FN (library, gnutls_certificate_get_peers);
+  LOAD_GNUTLS_FN (library, gnutls_certificate_set_verify_flags);
+  LOAD_GNUTLS_FN (library, gnutls_certificate_set_x509_crl_file);
+  LOAD_GNUTLS_FN (library, gnutls_certificate_set_x509_trust_file);
+  LOAD_GNUTLS_FN (library, gnutls_certificate_type_get);
+  LOAD_GNUTLS_FN (library, gnutls_certificate_verify_peers2);
+  LOAD_GNUTLS_FN (library, gnutls_credentials_set);
+  LOAD_GNUTLS_FN (library, gnutls_deinit);
+  LOAD_GNUTLS_FN (library, gnutls_error_is_fatal);
+  LOAD_GNUTLS_FN (library, gnutls_global_init);
+  LOAD_GNUTLS_FN (library, gnutls_global_set_log_function);
+  LOAD_GNUTLS_FN (library, gnutls_global_set_log_level);
+  LOAD_GNUTLS_FN (library, gnutls_handshake);
+  LOAD_GNUTLS_FN (library, gnutls_init);
+  LOAD_GNUTLS_FN (library, gnutls_priority_set_direct);
+  LOAD_GNUTLS_FN (library, gnutls_record_check_pending);
+  LOAD_GNUTLS_FN (library, gnutls_record_recv);
+  LOAD_GNUTLS_FN (library, gnutls_record_send);
+  LOAD_GNUTLS_FN (library, gnutls_strerror);
+  LOAD_GNUTLS_FN (library, gnutls_transport_set_errno);
+  LOAD_GNUTLS_FN (library, gnutls_transport_set_lowat);
+  LOAD_GNUTLS_FN (library, gnutls_transport_set_ptr2);
+  LOAD_GNUTLS_FN (library, gnutls_transport_set_pull_function);
+  LOAD_GNUTLS_FN (library, gnutls_transport_set_push_function);
+  LOAD_GNUTLS_FN (library, gnutls_x509_crt_check_hostname);
+  LOAD_GNUTLS_FN (library, gnutls_x509_crt_deinit);
+  LOAD_GNUTLS_FN (library, gnutls_x509_crt_import);
+  LOAD_GNUTLS_FN (library, gnutls_x509_crt_init);
+
+  return 1;
+}
+
+#else /* !WINDOWSNT */
+
+#define fn_gnutls_alert_get			gnutls_alert_get
+#define fn_gnutls_alert_get_name		gnutls_alert_get_name
+#define fn_gnutls_alert_send_appropriate	gnutls_alert_send_appropriate
+#define fn_gnutls_anon_allocate_client_credentials gnutls_anon_allocate_client_credentials
+#define fn_gnutls_anon_free_client_credentials	gnutls_anon_free_client_credentials
+#define fn_gnutls_bye				gnutls_bye
+#define fn_gnutls_certificate_allocate_credentials gnutls_certificate_allocate_credentials
+#define fn_gnutls_certificate_free_credentials	gnutls_certificate_free_credentials
+#define fn_gnutls_certificate_get_peers		gnutls_certificate_get_peers
+#define fn_gnutls_certificate_set_verify_flags	gnutls_certificate_set_verify_flags
+#define fn_gnutls_certificate_set_x509_crl_file	gnutls_certificate_set_x509_crl_file
+#define fn_gnutls_certificate_set_x509_trust_file gnutls_certificate_set_x509_trust_file
+#define fn_gnutls_certificate_type_get		gnutls_certificate_type_get
+#define fn_gnutls_certificate_verify_peers2	gnutls_certificate_verify_peers2
+#define fn_gnutls_credentials_set		gnutls_credentials_set
+#define fn_gnutls_deinit			gnutls_deinit
+#define fn_gnutls_error_is_fatal		gnutls_error_is_fatal
+#define fn_gnutls_global_init			gnutls_global_init
+#define fn_gnutls_global_set_log_function	gnutls_global_set_log_function
+#define fn_gnutls_global_set_log_level		gnutls_global_set_log_level
+#define fn_gnutls_handshake			gnutls_handshake
+#define fn_gnutls_init				gnutls_init
+#define fn_gnutls_priority_set_direct		gnutls_priority_set_direct
+#define fn_gnutls_record_check_pending		gnutls_record_check_pending
+#define fn_gnutls_record_recv			gnutls_record_recv
+#define fn_gnutls_record_send			gnutls_record_send
+#define fn_gnutls_strerror			gnutls_strerror
+#define fn_gnutls_transport_set_errno		gnutls_transport_set_errno
+#define fn_gnutls_transport_set_lowat		gnutls_transport_set_lowat
+#define fn_gnutls_transport_set_ptr2		gnutls_transport_set_ptr2
+#define fn_gnutls_transport_set_pull_function	gnutls_transport_set_pull_function
+#define fn_gnutls_transport_set_push_function	gnutls_transport_set_push_function
+#define fn_gnutls_x509_crt_check_hostname	gnutls_x509_crt_check_hostname
+#define fn_gnutls_x509_crt_deinit		gnutls_x509_crt_deinit
+#define fn_gnutls_x509_crt_import		gnutls_x509_crt_import
+#define fn_gnutls_x509_crt_init			gnutls_x509_crt_init
+
+#endif /* !WINDOWSNT */
+
+
+
 static void
 gnutls_log_function (int level, const char* string)
 {
@@ -82,11 +222,11 @@
       /* On W32 we cannot transfer socket handles between different runtime
          libraries, so we tell GnuTLS to use our special push/pull
          functions.  */
-      gnutls_transport_set_ptr2 (state,
+      fn_gnutls_transport_set_ptr2 (state,
                                  (gnutls_transport_ptr_t) proc,
                                  (gnutls_transport_ptr_t) proc);
-      gnutls_transport_set_push_function (state, &emacs_gnutls_push);
-      gnutls_transport_set_pull_function (state, &emacs_gnutls_pull);
+      fn_gnutls_transport_set_push_function (state, &emacs_gnutls_push);
+      fn_gnutls_transport_set_pull_function (state, &emacs_gnutls_pull);
 
       /* For non blocking sockets or other custom made pull/push
          functions the gnutls_transport_set_lowat must be called, with
@@ -95,12 +235,12 @@
          (Note: this is probably not strictly necessary as the lowat
           value is only used when no custom pull/push functions are
           set.)  */
-      gnutls_transport_set_lowat (state, 0);
+      fn_gnutls_transport_set_lowat (state, 0);
 #else
       /* This is how GnuTLS takes sockets: as file descriptors passed
          in.  For an Emacs process socket, infd and outfd are the
          same but we use this two-argument version for clarity.  */
-      gnutls_transport_set_ptr2 (state,
+      fn_gnutls_transport_set_ptr2 (state,
         			 (gnutls_transport_ptr_t) (long) proc->infd,
         			 (gnutls_transport_ptr_t) (long) proc->outfd);
 #endif
@@ -110,10 +250,10 @@
 
   do
     {
-      ret = gnutls_handshake (state);
+      ret = fn_gnutls_handshake (state);
       emacs_gnutls_handle_error (state, ret);
     }
-  while (ret < 0 && gnutls_error_is_fatal (ret) == 0);
+  while (ret < 0 && fn_gnutls_error_is_fatal (ret) == 0);
 
   proc->gnutls_initstage = GNUTLS_STAGE_HANDSHAKE_TRIED;
 
@@ -124,11 +264,23 @@
     }
   else
     {
-        gnutls_alert_send_appropriate (state, ret);
+        fn_gnutls_alert_send_appropriate (state, ret);
     }
   return ret;
 }
 
+int
+emacs_gnutls_record_check_pending (gnutls_session_t state)
+{
+  return fn_gnutls_record_check_pending (state);
+}
+
+void
+emacs_gnutls_transport_set_errno (gnutls_session_t state, int err)
+{
+  fn_gnutls_transport_set_errno (state, err);
+}
+
 EMACS_INT
 emacs_gnutls_write (int fildes, struct Lisp_Process *proc, const char *buf,
                     EMACS_INT nbyte)
@@ -151,7 +303,7 @@
 
   while (nbyte > 0)
     {
-      rtnval = gnutls_write (state, buf, nbyte);
+      rtnval = fn_gnutls_record_send (state, buf, nbyte);
 
       if (rtnval < 0)
         {
@@ -182,7 +334,7 @@
       emacs_gnutls_handshake (proc);
       return -1;
     }
-  rtnval = gnutls_read (state, buf, nbyte);
+  rtnval = fn_gnutls_record_recv (state, buf, nbyte);
   if (rtnval >= 0)
     return rtnval;
   else if (emacs_gnutls_handle_error (state, rtnval) == 0)
@@ -214,11 +366,11 @@
 
   /* TODO: use gnutls-error-fatalp and gnutls-error-string.  */
 
-  str = gnutls_strerror (err);
+  str = fn_gnutls_strerror (err);
   if (!str)
     str = "unknown";
 
-  if (gnutls_error_is_fatal (err))
+  if (fn_gnutls_error_is_fatal (err))
     {
       ret = err;
       GNUTLS_LOG2 (0, max_log_level, "fatal error:", str);
@@ -233,9 +385,9 @@
   if (err == GNUTLS_E_WARNING_ALERT_RECEIVED
       || err == GNUTLS_E_FATAL_ALERT_RECEIVED)
     {
-      int alert = gnutls_alert_get (session);
+      int alert = fn_gnutls_alert_get (session);
       int level = (err == GNUTLS_E_FATAL_ALERT_RECEIVED) ? 0 : 1;
-      str = gnutls_alert_get_name (alert);
+      str = fn_gnutls_alert_get_name (alert);
       if (!str)
 	str = "unknown";
 
@@ -313,7 +465,7 @@
   if (!NUMBERP (err))
     error ("Not an error symbol or code");
 
-  if (0 == gnutls_error_is_fatal (XINT (err)))
+  if (0 == fn_gnutls_error_is_fatal (XINT (err)))
     return Qnil;
 
   return Qt;
@@ -345,7 +497,7 @@
   if (!NUMBERP (err))
     return build_string ("Not an error symbol or code");
 
-  return build_string (gnutls_strerror (XINT (err)));
+  return build_string (fn_gnutls_strerror (XINT (err)));
 }
 
 DEFUN ("gnutls-deinit", Fgnutls_deinit, Sgnutls_deinit, 1, 1, 0,
@@ -360,13 +512,34 @@
 
   if (GNUTLS_INITSTAGE (proc) >= GNUTLS_STAGE_INIT)
     {
-      gnutls_deinit (state);
+      fn_gnutls_deinit (state);
       GNUTLS_INITSTAGE (proc) = GNUTLS_STAGE_INIT - 1;
     }
 
   return Qt;
 }
 
+DEFUN ("gnutls-available-p", Fgnutls_available_p, Sgnutls_available_p, 0, 0, 0,
+       doc: /* Return t if GnuTLS is available in this instance of Emacs.  */)
+     (void)
+{
+#ifdef WINDOWSNT
+  Lisp_Object found = Fassq (Qgnutls_dll, Vlibrary_cache);
+  if (CONSP (found))
+    return XCDR (found);
+  else
+    {
+      Lisp_Object status;
+      status = init_gnutls_functions (Vdynamic_library_alist) ? Qt : Qnil;
+      Vlibrary_cache = Fcons (Fcons (Qgnutls_dll, status), Vlibrary_cache);
+      return status;
+    }
+#else
+  return Qt;
+#endif
+}
+
+
 /* Initializes global GnuTLS state to defaults.
 Call `gnutls-global-deinit' when GnuTLS usage is no longer needed.
 Returns zero on success.  */
@@ -376,8 +549,7 @@
   int ret = GNUTLS_E_SUCCESS;
 
   if (!gnutls_global_initialized)
-    ret = gnutls_global_init ();
-
+    ret = fn_gnutls_global_init ();
   gnutls_global_initialized = 1;
 
   return gnutls_make_error (ret);
@@ -483,6 +655,12 @@
   CHECK_SYMBOL (type);
   CHECK_LIST (proplist);
 
+  if (NILP (Fgnutls_available_p ()))
+    {
+      error ("GnuTLS not available");
+      return gnutls_make_error (GNUTLS_EMACS_ERROR_NOT_LOADED);
+    }
+
   hostname              = Fplist_get (proplist, Qgnutls_bootprop_hostname);
   priority_string       = Fplist_get (proplist, Qgnutls_bootprop_priority);
   trustfiles            = Fplist_get (proplist, Qgnutls_bootprop_trustfiles);
@@ -503,8 +681,8 @@
 
   if (NUMBERP (loglevel))
     {
-      gnutls_global_set_log_function (gnutls_log_function);
-      gnutls_global_set_log_level (XINT (loglevel));
+      fn_gnutls_global_set_log_function (gnutls_log_function);
+      fn_gnutls_global_set_log_level (XINT (loglevel));
       max_log_level = XINT (loglevel);
       XPROCESS (proc)->gnutls_log_level = max_log_level;
     }
@@ -523,13 +701,13 @@
 	{
           GNUTLS_LOG (2, max_log_level, "deallocating x509 credentials");
           x509_cred = XPROCESS (proc)->gnutls_x509_cred;
-          gnutls_certificate_free_credentials (x509_cred);
+          fn_gnutls_certificate_free_credentials (x509_cred);
 	}
       else if (EQ (type, Qgnutls_anon))
 	{
           GNUTLS_LOG (2, max_log_level, "deallocating anon credentials");
           anon_cred = XPROCESS (proc)->gnutls_anon_cred;
-          gnutls_anon_free_client_credentials (anon_cred);
+          fn_gnutls_anon_free_client_credentials (anon_cred);
 	}
       else
 	{
@@ -552,7 +730,7 @@
     {
       GNUTLS_LOG (2, max_log_level, "allocating x509 credentials");
       x509_cred = XPROCESS (proc)->gnutls_x509_cred;
-      if (gnutls_certificate_allocate_credentials (&x509_cred) < 0)
+      if (fn_gnutls_certificate_allocate_credentials (&x509_cred) < 0)
         memory_full ();
 
       if (NUMBERP (verify_flags))
@@ -570,13 +748,13 @@
           /* The default is already GNUTLS_VERIFY_ALLOW_X509_V1_CA_CRT.  */
           GNUTLS_LOG (2, max_log_level, "ignoring invalid verify-flags");
         }
-      gnutls_certificate_set_verify_flags (x509_cred, gnutls_verify_flags);
+      fn_gnutls_certificate_set_verify_flags (x509_cred, gnutls_verify_flags);
     }
   else if (EQ (type, Qgnutls_anon))
     {
       GNUTLS_LOG (2, max_log_level, "allocating anon credentials");
       anon_cred = XPROCESS (proc)->gnutls_anon_cred;
-      if (gnutls_anon_allocate_client_credentials (&anon_cred) < 0)
+      if (fn_gnutls_anon_allocate_client_credentials (&anon_cred) < 0)
         memory_full ();
     }
   else
@@ -599,7 +777,7 @@
             {
               GNUTLS_LOG2 (1, max_log_level, "setting the trustfile: ",
                            SSDATA (trustfile));
-              ret = gnutls_certificate_set_x509_trust_file
+              ret = fn_gnutls_certificate_set_x509_trust_file
                 (x509_cred,
                  SSDATA (trustfile),
                  file_format);
@@ -621,7 +799,7 @@
             {
               GNUTLS_LOG2 (1, max_log_level, "setting the keyfile: ",
                            SSDATA (keyfile));
-              ret = gnutls_certificate_set_x509_crl_file
+              ret = fn_gnutls_certificate_set_x509_crl_file
                 (x509_cred,
                  SSDATA (keyfile),
                  file_format);
@@ -649,7 +827,7 @@
 
   GNUTLS_LOG (1, max_log_level, "gnutls_init");
 
-  ret = gnutls_init (&state, GNUTLS_CLIENT);
+  ret = fn_gnutls_init (&state, GNUTLS_CLIENT);
 
   if (ret < GNUTLS_E_SUCCESS)
     return gnutls_make_error (ret);
@@ -672,7 +850,7 @@
 
   GNUTLS_LOG (1, max_log_level, "setting the priority string");
 
-  ret = gnutls_priority_set_direct (state,
+  ret = fn_gnutls_priority_set_direct (state,
 				    priority_string_ptr,
 				    NULL);
 
@@ -683,11 +861,11 @@
 
   if (EQ (type, Qgnutls_x509pki))
     {
-      ret = gnutls_cred_set (state, GNUTLS_CRD_CERTIFICATE, x509_cred);
+      ret = fn_gnutls_credentials_set (state, GNUTLS_CRD_CERTIFICATE, x509_cred);
     }
   else if (EQ (type, Qgnutls_anon))
     {
-      ret = gnutls_cred_set (state, GNUTLS_CRD_ANON, anon_cred);
+      ret = fn_gnutls_credentials_set (state, GNUTLS_CRD_ANON, anon_cred);
     }
   else
     {
@@ -715,7 +893,7 @@
      check of the certificate's hostname with
      gnutls_x509_crt_check_hostname() against :hostname.  */
 
-  ret = gnutls_certificate_verify_peers2 (state, &peer_verification);
+  ret = fn_gnutls_certificate_verify_peers2 (state, &peer_verification);
 
   if (ret < GNUTLS_E_SUCCESS)
     return gnutls_make_error (ret);
@@ -766,15 +944,15 @@
   /* Up to here the process is the same for X.509 certificates and
      OpenPGP keys.  From now on X.509 certificates are assumed.  This
      can be easily extended to work with openpgp keys as well.  */
-  if (gnutls_certificate_type_get (state) == GNUTLS_CRT_X509)
+  if (fn_gnutls_certificate_type_get (state) == GNUTLS_CRT_X509)
     {
-      ret = gnutls_x509_crt_init (&gnutls_verify_cert);
+      ret = fn_gnutls_x509_crt_init (&gnutls_verify_cert);
 
       if (ret < GNUTLS_E_SUCCESS)
         return gnutls_make_error (ret);
 
       gnutls_verify_cert_list =
-        gnutls_certificate_get_peers (state, &gnutls_verify_cert_list_size);
+        fn_gnutls_certificate_get_peers (state, &gnutls_verify_cert_list_size);
 
       if (NULL == gnutls_verify_cert_list)
         {
@@ -782,17 +960,17 @@
         }
 
       /* We only check the first certificate in the given chain.  */
-      ret = gnutls_x509_crt_import (gnutls_verify_cert,
+      ret = fn_gnutls_x509_crt_import (gnutls_verify_cert,
                                     &gnutls_verify_cert_list[0],
                                     GNUTLS_X509_FMT_DER);
 
       if (ret < GNUTLS_E_SUCCESS)
         {
-          gnutls_x509_crt_deinit (gnutls_verify_cert);
+          fn_gnutls_x509_crt_deinit (gnutls_verify_cert);
           return gnutls_make_error (ret);
         }
 
-      if (!gnutls_x509_crt_check_hostname (gnutls_verify_cert, c_hostname))
+      if (!fn_gnutls_x509_crt_check_hostname (gnutls_verify_cert, c_hostname))
         {
           if (NILP (verify_hostname_error))
             {
@@ -801,13 +979,13 @@
             }
           else
             {
-              gnutls_x509_crt_deinit (gnutls_verify_cert);
+              fn_gnutls_x509_crt_deinit (gnutls_verify_cert);
               error ("The x509 certificate does not match \"%s\"",
                      c_hostname);
             }
         }
 
-      gnutls_x509_crt_deinit (gnutls_verify_cert);
+      fn_gnutls_x509_crt_deinit (gnutls_verify_cert);
     }
 
   return gnutls_make_error (ret);
@@ -836,7 +1014,7 @@
 
   state = XPROCESS (proc)->gnutls_state;
 
-  ret = gnutls_bye (state,
+  ret = fn_gnutls_bye (state,
                     NILP (cont) ? GNUTLS_SHUT_RDWR : GNUTLS_SHUT_WR);
 
   return gnutls_make_error (ret);
@@ -847,6 +1025,9 @@
 {
   gnutls_global_initialized = 0;
 
+  Qgnutls_dll = intern_c_string ("gnutls");
+  staticpro (&Qgnutls_dll);
+
   Qgnutls_log_level = intern_c_string ("gnutls-log-level");
   staticpro (&Qgnutls_log_level);
 
@@ -917,6 +1098,7 @@
   defsubr (&Sgnutls_boot);
   defsubr (&Sgnutls_deinit);
   defsubr (&Sgnutls_bye);
+  defsubr (&Sgnutls_available_p);
 }
 
 #endif /* HAVE_GNUTLS */

=== modified file 'src/gnutls.h'
--- src/gnutls.h	2011-04-25 01:30:51 +0000
+++ src/gnutls.h	2011-05-03 01:08:23 +0000
@@ -42,6 +42,7 @@
   GNUTLS_STAGE_READY,
 } gnutls_initstage_t;
 
+#define GNUTLS_EMACS_ERROR_NOT_LOADED GNUTLS_E_APPLICATION_ERROR_MIN + 1
 #define GNUTLS_EMACS_ERROR_INVALID_TYPE GNUTLS_E_APPLICATION_ERROR_MIN
 
 #define GNUTLS_INITSTAGE(proc) (XPROCESS (proc)->gnutls_initstage)
@@ -52,13 +53,16 @@
 
 #define GNUTLS_LOG2(level, max, string, extra) if (level <= max) { gnutls_log_function2 (level, "(Emacs) " string, extra); }
 
-EMACS_INT
+extern EMACS_INT
 emacs_gnutls_write (int fildes, struct Lisp_Process *proc, const char *buf,
                     EMACS_INT nbyte);
-EMACS_INT
+extern EMACS_INT
 emacs_gnutls_read (int fildes, struct Lisp_Process *proc, char *buf,
                    EMACS_INT nbyte);
 
+extern int emacs_gnutls_record_check_pending (gnutls_session_t state);
+extern void emacs_gnutls_transport_set_errno (gnutls_session_t state, int err);
+
 extern void syms_of_gnutls (void);
 
 #endif

=== modified file 'src/image.c'
--- src/image.c	2011-04-25 21:34:39 +0000
+++ src/image.c	2011-05-02 01:48:17 +0000
@@ -67,6 +67,7 @@
 
 
 #ifdef HAVE_NTGUI
+#include "w32.h"
 #include "w32term.h"
 
 /* W32_TODO : Color tables on W32.  */
@@ -556,10 +557,6 @@
 
 static struct image_type *image_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.  */
 
 static Lisp_Object Qxbm;
@@ -589,7 +586,7 @@
                                    Lisp_Object);
 
 #define CACHE_IMAGE_TYPE(type, status) \
-  do { Vimage_type_cache = Fcons (Fcons (type, status), Vimage_type_cache); } while (0)
+  do { Vlibrary_cache = Fcons (Fcons (type, status), Vlibrary_cache); } while (0)
 
 #define ADD_IMAGE_TYPE(type) \
   do { Vimage_types = Fcons (type, Vimage_types); } while (0)
@@ -1900,34 +1897,6 @@
     if (!fn_##func) return 0;						\
   }
 
-/* Load a DLL implementing an image type.
-   The argument LIBRARIES is usually the variable
-   `dynamic-library-alist', which associates a symbol, identifying
-   an external DLL library, to a list of possible filenames.
-   The function returns NULL if no library could be loaded for
-   the given symbol, 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 */
 
 static int x_create_x_image_and_pixmap (struct frame *, int, int, int,
@@ -8634,7 +8603,7 @@
   Lisp_Object tested;
 
   /* Don't try to reload the library.  */
-  tested = Fassq (type, Vimage_type_cache);
+  tested = Fassq (type, Vlibrary_cache);
   if (CONSP (tested))
     return XCDR (tested);
 
@@ -8714,9 +8683,6 @@
 non-numeric, there is no explicit limit on the size of images.  */);
   Vmax_image_size = make_float (MAX_IMAGE_SIZE);
 
-  Vimage_type_cache = Qnil;
-  staticpro (&Vimage_type_cache);
-
   Qpbm = intern_c_string ("pbm");
   staticpro (&Qpbm);
   ADD_IMAGE_TYPE (Qpbm);

=== modified file 'src/process.c'
--- src/process.c	2011-04-30 09:31:01 +0000
+++ src/process.c	2011-05-03 01:08:37 +0000
@@ -4540,7 +4540,7 @@
           if (nfds == 0 && 
               wait_proc && wait_proc->gnutls_p /* Check for valid process.  */
               /* Do we have pending data?  */
-              && gnutls_record_check_pending (wait_proc->gnutls_state) > 0)
+              && emacs_gnutls_record_check_pending (wait_proc->gnutls_state) > 0)
           {
               nfds = 1;
               /* Set to Available.  */

=== modified file 'src/w32.c'
--- src/w32.c	2011-04-28 19:51:12 +0000
+++ src/w32.c	2011-05-03 01:10:10 +0000
@@ -5712,6 +5712,40 @@
   return localtime (t);
 }
 
+
+
+/* Delayed loading of libraries.  */
+
+Lisp_Object Vlibrary_cache;
+
+/* The argument LIBRARIES is usually the variable
+   `dynamic-library-alist', which associates a symbol, identifying
+   an external DLL library, to a list of possible filenames.
+   The function returns NULL if no library could be loaded for
+   the given symbol, or if the library was previously loaded;
+   else the handle of the DLL.  */
+HMODULE
+w32_delayed_load (Lisp_Object libraries, Lisp_Object library_id)
+{
+  HMODULE library_dll = NULL;
+
+  if (CONSP (libraries) && NILP (Fassq (library_id, Vlibrary_cache)))
+    {
+      Lisp_Object dlls = Fassq (library_id, libraries);
+
+      if (CONSP (dlls))
+        for (dlls = XCDR (dlls); CONSP (dlls); dlls = XCDR (dlls))
+          {
+            CHECK_STRING_CAR (dlls);
+            if (library_dll = LoadLibrary (SDATA (XCAR (dlls))))
+              break;
+          }
+    }
+
+  return library_dll;
+}
+
+
 static void
 check_windows_init_file (void)
 {
@@ -5910,6 +5944,9 @@
   get_process_times_fn = (GetProcessTimes_Proc)
     GetProcAddress (kernel32, "GetProcessTimes");
 
+  Vlibrary_cache = Qnil;
+  staticpro (&Vlibrary_cache);
+
   g_b_init_is_windows_9x = 0;
   g_b_init_open_process_token = 0;
   g_b_init_get_token_information = 0;
@@ -6178,7 +6215,7 @@
             err = errno; /* Other errors are just passed on.  */
         }
 
-      gnutls_transport_set_errno (process->gnutls_state, err);
+      emacs_gnutls_transport_set_errno (process->gnutls_state, err);
 
       return -1;
     }
@@ -6197,7 +6234,7 @@
 
   /* Negative bytes written means we got an error in errno.
      Translate the WSAEWOULDBLOCK alias EWOULDBLOCK to EAGAIN.  */
-  gnutls_transport_set_errno (process->gnutls_state,
+  emacs_gnutls_transport_set_errno (process->gnutls_state,
                               errno == EWOULDBLOCK ? EAGAIN : errno);
 
   return -1;

=== modified file 'src/w32.h'
--- src/w32.h	2011-04-25 01:30:51 +0000
+++ src/w32.h	2011-05-02 01:47:27 +0000
@@ -1,6 +1,8 @@
 #ifndef EMACS_W32_H
 #define EMACS_W32_H
 
+#include "lisp.h"
+
 /* Support routines for the NT version of Emacs.
    Copyright (C) 1994, 2001-2011  Free Software Foundation, Inc.
 
@@ -143,6 +145,9 @@
 extern int _sys_read_ahead (int fd);
 extern int _sys_wait_accept (int fd);
 
+extern Lisp_Object Vlibrary_cache;
+extern HMODULE w32_delayed_load (Lisp_Object, Lisp_Object);
+
 #ifdef HAVE_GNUTLS
 #include <gnutls/gnutls.h>
 

