unofficial mirror of emacs-devel@gnu.org 
 help / color / mirror / code / Atom feed
From: Daniel Colascione <dan.colascione@gmail.com>
To: Emacs development discussions <emacs-devel@gnu.org>
Subject: [PATCH] system-type cygwin with window-system w32
Date: Sun, 17 Jul 2011 17:01:38 -0700	[thread overview]
Message-ID: <4E2377E2.1020804@gmail.com> (raw)


[-- Attachment #1.1: Type: text/plain, Size: 1019 bytes --]

This patch makes it possible to use the NT GUI with a Cygwin core Emacs.
 The patch is still a little rough around the edges, but it works well
enough to let me do real work in this new Emacs configuration.  For me,
at least, forgoing the hassle of an X server and gaining some
integration makes the new configuration worthwhile.

(Of course, I don't plan to merge this before the feature freeze ends.
Do we have an emacs-next branch of some sort?)

What works:

  - All the usual Cygwin features, including multitty, real ptys, job
control, etc.

  - Native NT GUI

  - File dialogs

What's new:

  - Rewritten clipboard system mostly implemented in lisp

  - Preserving formatting when copying text into other applications
(probably better structured as a separate package using the extensible
clipboard system)

What doesn't work yet:

  - The normal NT build (I don't have a toolchain to test it)

  - Graphical menus in customize

What I haven't tested:

  - Image support




[-- Attachment #1.2: cygwin-w32.patch --]
[-- Type: text/plain, Size: 136534 bytes --]

=== modified file 'configure.in'
--- configure.in	2011-07-13 10:36:12 +0000
+++ configure.in	2011-07-17 10:24:18 +0000
@@ -168,6 +168,7 @@
 OPTION_DEFAULT_ON([xaw3d],[don't use Xaw3d])
 OPTION_DEFAULT_ON([xim],[don't use X11 XIM])
 OPTION_DEFAULT_OFF([ns],[use NeXTstep (Cocoa or GNUstep) windowing system])
+OPTION_DEFAULT_OFF([w32], [use a Win32])
 
 OPTION_DEFAULT_ON([gpm],[don't use -lgpm for mouse support on a GNU/Linux console])
 OPTION_DEFAULT_ON([dbus],[don't compile with D-Bus support])
@@ -1534,6 +1535,7 @@
     NS_HAVE_NSINTEGER=no
   fi
 fi
+
 AC_SUBST(TEMACS_LDFLAGS2)
 
 ns_frag=/dev/null
@@ -1559,6 +1561,31 @@
 AC_SUBST(LIB_STANDARD)
 AC_SUBST_FILE(ns_frag)
 
+HAVE_W32=no
+W32_OBJ=
+W32_LIBS=
+if test "${with_w32}" != no; then
+  if test "${opsys}" != "cygwin"; then
+    AC_MSG_ERROR([Using win32 with an autotools build is only supported for Cygwin.])
+  fi
+  AC_CHECK_HEADER([windows.h], [HAVE_W32=yes],
+                  [AC_MSG_ERROR([`--with-w32' was specified, but windows.h
+                  cannot be found.])])
+  AC_DEFINE(HAVE_NTGUI, 1, [Define to use native Windows GUI.])
+  W32_OBJ="w32fns.o w32menu.o w32reg.o fringe.o"
+  W32_OBJ="$W32_OBJ fontset.o w32font.o w32term.o"
+  W32_OBJ="$W32_OBJ w32xfns.o w32select.o image.o w32uniscribe.o"
+  W32_LIBS="$W32_LIBS -lkernel32 -luser32 -lgdi32 -lole32 -lcomdlg32"
+  W32_LIBS="$W32_LIBS -lusp10 -lcomctl32 -lwinspool"
+fi
+AC_SUBST(W32_OBJ)
+AC_SUBST(W32_LIBS)
+
+if test "${HAVE_W32}" = "yes"; then
+  window_system=w32
+  with_xft=no
+fi
+
 case "${window_system}" in
   x11 )
     HAVE_X_WINDOWS=yes
@@ -1578,6 +1605,11 @@
       * ) USE_X_TOOLKIT=maybe ;;
     esac
   ;;
+  w32 )
+    HAVE_X_WINDOWS=no
+    HAVE_X11=no
+    USE_X_TOOLKIT=none
+  ;;
   nextstep | none )
     HAVE_X_WINDOWS=no
     HAVE_X11=no
@@ -2222,6 +2254,9 @@
   elif test "${HAVE_NS}" = "yes"; then
     AC_DEFINE(USE_TOOLKIT_SCROLL_BARS)
     USE_TOOLKIT_SCROLL_BARS=yes
+  elif test "${HAVE_W32}" = "yes"; then
+    AC_DEFINE(USE_TOOLKIT_SCROLL_BARS)
+    USE_TOOLKIT_SCROLL_BARS=yes
   fi
 fi
 
@@ -2572,6 +2607,9 @@
   OTHER_FILES=ns-app
 fi
 
+if test "${HAVE_W32}" = "yes"; then
+  HAVE_MENUS=yes
+fi
 
 ### Use session management (-lSM -lICE) if available
 HAVE_X_SM=no
@@ -3317,7 +3355,7 @@
 AC_SUBST(RALLOC_OBJ)
 
 if test "$opsys" = "cygwin"; then
-  CYGWIN_OBJ="sheap.o"
+  CYGWIN_OBJ="sheap.o cygw32.o"
   ## Cygwin differs because of its unexec().
   PRE_ALLOC_OBJ=
   POST_ALLOC_OBJ=lastfile.o
@@ -3467,8 +3505,11 @@
 AC_SUBST(LIB_GCC)
 
 
-## If we're using X11/GNUstep, define some consequences.
-if test "$HAVE_X_WINDOWS" = "yes" || test "$HAVE_NS" = "yes"; then
+## If we're using X11, GNUstep, or Cygwin-Win32, define some
+## consequences.
+if test "$HAVE_X_WINDOWS" = "yes" || test "$HAVE_NS" = "yes" ||
+   test "$HAVE_W32" = "yes"
+then
   AC_DEFINE(HAVE_WINDOW_SYSTEM, 1, [Define if you have a window system.])
   AC_DEFINE(HAVE_MOUSE, 1, [Define if you have mouse support.])
 fi

=== modified file 'lib/filemode.c'
--- lib/filemode.c	2011-02-20 10:51:50 +0000
+++ lib/filemode.c	2011-07-16 11:34:30 +0000
@@ -73,19 +73,36 @@
   if (S_ISSOCK (bits))
     return 's';
 
+#ifdef S_ISCTG
   /* Nonstandard file types.  */
   if (S_ISCTG (bits))
     return 'C';
+#endif
+
+#ifdef S_ISDOOR
   if (S_ISDOOR (bits))
     return 'D';
+#endif
+
+#ifdef S_ISMPB
   if (S_ISMPB (bits) || S_ISMPC (bits))
     return 'm';
+#endif
+
+#ifdef S_ISNWK
   if (S_ISNWK (bits))
     return 'n';
+#endif
+
+#ifdef S_ISPORT
   if (S_ISPORT (bits))
     return 'P';
+#endif
+
+#ifdef S_ISWHT
   if (S_ISWHT (bits))
     return 'w';
+#endif
 
   return '?';
 }

=== modified file 'lisp/battery.el'
--- lisp/battery.el	2011-06-27 08:04:55 +0000
+++ lisp/battery.el	2011-07-17 12:33:54 +0000
@@ -57,7 +57,7 @@
 			 (> (buffer-size) 0)))
 		(error nil)))
 	 'battery-pmset)
-	((eq system-type 'windows-nt)
+	((fboundp 'w32-battery-status)
 	 'w32-battery-status))
   "Function for getting battery status information.
 The function has to return an alist of conversion definitions.

=== modified file 'lisp/faces.el'
--- lisp/faces.el	2011-07-10 02:04:45 +0000
+++ lisp/faces.el	2011-07-17 12:36:34 +0000
@@ -89,7 +89,7 @@
 ;; This is defined originally in xfaces.c.
 (defcustom face-font-registry-alternatives
   (mapcar (lambda (arg) (mapcar 'purecopy arg))
-  (if (eq system-type 'windows-nt)
+  (if (featurep 'w32)
       '(("iso8859-1" "ms-oemlatin")
 	("gb2312.1980" "gb2312" "gbk" "gb18030")
 	("jisx0208.1990" "jisx0208.1983" "jisx0208.1978")

=== modified file 'lisp/loadup.el'
--- lisp/loadup.el	2011-07-06 22:43:48 +0000
+++ lisp/loadup.el	2011-07-16 14:45:18 +0000
@@ -207,15 +207,17 @@
       (load "term/common-win")
       (load "term/x-win")))
 
-(if (eq system-type 'windows-nt)
+(if (or (eq system-type 'windows-nt)
+        (featurep 'w32))
     (progn
       (load "w32-vars")
       (load "term/common-win")
       (load "term/w32-win")
-      (load "ls-lisp")
       (load "disp-table")
-      (load "dos-w32")
-      (load "w32-fns")))
+      (when (eq system-type 'windows-nt)
+        (load "ls-lisp")
+        (load "dos-w32")
+        (load "w32-fns"))))
 (if (eq system-type 'ms-dos)
     (progn
       (load "dos-w32")

=== modified file 'lisp/mouse.el'
--- lisp/mouse.el	2011-07-14 14:01:16 +0000
+++ lisp/mouse.el	2011-07-17 12:31:18 +0000
@@ -1277,7 +1277,7 @@
   (or mouse-yank-at-point (mouse-set-point click))
   (let ((primary
 	 (cond
-	  ((eq system-type 'windows-nt)
+	  ((eq (framep (selected-frame)) 'w32)
 	   ;; MS-Windows emulates PRIMARY in x-get-selection, but not
 	   ;; in x-get-selection-value (the latter only accesses the
 	   ;; clipboard).  So try PRIMARY first, in case they selected

=== modified file 'lisp/simple.el'
--- lisp/simple.el	2011-07-13 23:35:36 +0000
+++ lisp/simple.el	2011-07-17 12:38:50 +0000
@@ -6550,7 +6550,7 @@
        (if (if (eq normal-erase-is-backspace 'maybe)
                (and (not noninteractive)
                     (or (memq system-type '(ms-dos windows-nt))
-			(memq window-system '(ns))
+			(memq window-system '(w32 ns))
                         (and (memq window-system '(x))
                              (fboundp 'x-backspace-delete-keys-p)
                              (x-backspace-delete-keys-p))

=== modified file 'lisp/term/common-win.el'
--- lisp/term/common-win.el	2011-01-25 04:08:28 +0000
+++ lisp/term/common-win.el	2011-07-17 12:26:34 +0000
@@ -57,7 +57,7 @@
 
 On Nextstep, put TEXT in the pasteboard (`x-select-enable-clipboard'
 is not used)."
-  (cond ((eq system-type 'windows-nt)
+  (cond ((eq (framep (selected-frame)) 'w32)
 	 (if x-select-enable-clipboard
 	     (w32-set-clipboard-data text))
 	 (setq x-last-selected-text text))

=== modified file 'lisp/term/w32-win.el'
--- lisp/term/w32-win.el	2011-05-04 14:03:16 +0000
+++ lisp/term/w32-win.el	2011-07-17 23:04:45 +0000
@@ -36,30 +36,30 @@
 ;; These are the standard X switches from the Xt Initialize.c file of
 ;; Release 4.
 
-;; Command line		Resource Manager string
+;; Command line         Resource Manager string
 
-;; +rv			*reverseVideo
-;; +synchronous		*synchronous
-;; -background		*background
-;; -bd			*borderColor
-;; -bg			*background
-;; -bordercolor		*borderColor
-;; -borderwidth		.borderWidth
-;; -bw			.borderWidth
-;; -display		.display
-;; -fg			*foreground
-;; -fn			*font
-;; -font		*font
-;; -foreground		*foreground
-;; -geometry		.geometry
-;; -i			.iconType
-;; -itype		.iconType
-;; -iconic		.iconic
-;; -name		.name
-;; -reverse		*reverseVideo
-;; -rv			*reverseVideo
+;; +rv                  *reverseVideo
+;; +synchronous         *synchronous
+;; -background          *background
+;; -bd                  *borderColor
+;; -bg                  *background
+;; -bordercolor         *borderColor
+;; -borderwidth         .borderWidth
+;; -bw                  .borderWidth
+;; -display             .display
+;; -fg                  *foreground
+;; -fn                  *font
+;; -font                *font
+;; -foreground          *foreground
+;; -geometry            .geometry
+;; -i                   .iconType
+;; -itype               .iconType
+;; -iconic              .iconic
+;; -name                .name
+;; -reverse             *reverseVideo
+;; -rv                  *reverseVideo
 ;; -selectionTimeout    .selectionTimeout
-;; -synchronous		*synchronous
+;; -synchronous         *synchronous
 ;; -xrm
 
 ;; An alist of X options and the function which handles them.  See
@@ -110,23 +110,23 @@
     ;; before setting the selected frame - otherwise it
     ;; won't work.  <skx@tardis.ed.ac.uk>
     (let* ((window (posn-window (event-start event)))
-	   (coords (posn-x-y (event-start event)))
-	   (x (car coords))
-	   (y (cdr coords)))
+           (coords (posn-x-y (event-start event)))
+           (x (car coords))
+           (y (cdr coords)))
       (if (and (> x 0) (> y 0))
-	  (set-frame-selected-window nil window))
+          (set-frame-selected-window nil window))
       (mapc (lambda (file-name)
-		(let ((f (subst-char-in-string ?\\ ?/ file-name))
-		      (coding (or file-name-coding-system
-				  default-file-name-coding-system)))
-		  (setq file-name
-			(mapconcat 'url-hexify-string
-				   (split-string (encode-coding-string f coding)
-						 "/")
-				   "/")))
-		(dnd-handle-one-url window 'private
-				    (concat "file:" file-name)))
-		(car (cdr (cdr event)))))
+                (let ((f (subst-char-in-string ?\\ ?/ file-name))
+                      (coding (or file-name-coding-system
+                                  default-file-name-coding-system)))
+                  (setq file-name
+                        (mapconcat 'url-hexify-string
+                                   (split-string (encode-coding-string f coding)
+                                                 "/")
+                                   "/")))
+                (dnd-handle-one-url window 'private
+                                    (concat "file:" file-name)))
+                (car (cdr (cdr event)))))
   (raise-frame)))
 
 (defun w32-drag-n-drop-other-frame (event)
@@ -197,11 +197,11 @@
        ;; the version we were compiled against.  (If we were compiled
        ;; without PNG support, libpng-version's value is -1.)
        (if (>= libpng-version 10400)
-	   ;; libpng14-14.dll is libpng 1.4.3 from GTK+
-	   '(png "libpng14-14.dll" "libpng14.dll")
-	 '(png "libpng12d.dll" "libpng12.dll" "libpng3.dll" "libpng.dll"
-	       ;; these are libpng 1.2.8 from GTK+
-	       "libpng13d.dll" "libpng13.dll"))
+           ;; libpng14-14.dll is libpng 1.4.3 from GTK+
+           '(png "libpng14-14.dll" "libpng14.dll")
+         '(png "libpng12d.dll" "libpng12.dll" "libpng3.dll" "libpng.dll"
+               ;; these are libpng 1.2.8 from GTK+
+               "libpng13d.dll" "libpng13.dll"))
        '(jpeg "jpeg62.dll" "libjpeg.dll" "jpeg-62.dll" "jpeg.dll")
        '(tiff "libtiff3.dll" "libtiff.dll")
        '(gif "giflib4.dll" "libungif4.dll" "libungif.dll")
@@ -252,9 +252,9 @@
   (condition-case err
       (create-fontset-from-fontset-spec w32-standard-fontset-spec t)
     (error (display-warning
-	    'initialization
-	    (format "Creation of the standard fontset failed: %s" err)
-	    :error)))
+            'initialization
+            (format "Creation of the standard fontset failed: %s" err)
+            :error)))
   ;; Create fontset specified in X resources "Fontset-N" (N is 0, 1,...).
   (create-fontset-from-x-resource)
 
@@ -313,6 +313,254 @@
 (add-to-list 'frame-creation-function-alist '(w32 . x-create-frame-with-faces))
 (add-to-list 'window-system-initialization-alist '(w32 . w32-initialize-window-system))
 
+(declare-function set-message-beep "w32fns.c")
+
+(declare-function w32-raw-clipboard-fetch-data "w32select.c")
+(declare-function x-server-version "w32fns.c" (&optional display))
+
+(defun w32-version ()
+  "Return the MS-Windows version numbers.
+The value is a list of three integers: the major and minor version
+numbers, and the build number."
+  (x-server-version))
+
+;;; Fix interface to (X-specific) mouse.el
+(defun x-set-selection (type data)
+  "Make an X selection of type TYPE and value DATA.
+The argument TYPE (nil means `PRIMARY') says which selection, and
+DATA specifies the contents.  TYPE must be a symbol.  \(It can also
+be a string, which stands for the symbol with that name, but this
+is considered obsolete.)  DATA may be a string, a symbol, an
+integer (or a cons of two integers or list of two integers).
+
+The selection may also be a cons of two markers pointing to the same buffer,
+or an overlay.  In these cases, the selection is considered to be the text
+between the markers *at whatever time the selection is examined*.
+Thus, editing done in the buffer after you specify the selection
+can alter the effective value of the selection.
+
+The data may also be a vector of valid non-vector selection values.
+
+The return value is DATA.
+
+Interactively, this command sets the primary selection.  Without
+prefix argument, it reads the selection in the minibuffer.  With
+prefix argument, it uses the text of the region as the selection value.
+
+Note that on MS-Windows, primary and secondary selections set by Emacs
+are not available to other programs."
+  (put 'x-selections (or type 'PRIMARY) data))
+
+(defun x-get-selection (&optional type _data-type)
+  "Return the value of an X Windows selection.
+The argument TYPE (default `PRIMARY') says which selection,
+and the argument DATA-TYPE (default `STRING') says
+how to convert the data.
+
+TYPE may be any symbol \(but nil stands for `PRIMARY').  However,
+only a few symbols are commonly used.  They conventionally have
+all upper-case names.  The most often used ones, in addition to
+`PRIMARY', are `SECONDARY' and `CLIPBOARD'.
+
+DATA-TYPE is usually `STRING', but can also be one of the symbols
+in `selection-converter-alist', which see."
+  (get 'x-selections (or type 'PRIMARY)))
+
+;; x-selection-owner-p is used in simple.el
+(defun x-selection-owner-p (&optional type)
+  (and (memq type '(nil PRIMARY SECONDARY))
+       (get 'x-selections (or type 'PRIMARY))))
+
+;; Set to a system sound if you want a fancy bell.
+(set-message-beep nil)
+
+;; The "Windows" keys on newer keyboards bring up the Start menu
+;; whether you want it or not - make Emacs ignore these keystrokes
+;; rather than beep.
+(global-set-key [lwindow] 'ignore)
+(global-set-key [rwindow] 'ignore)
+
+(make-obsolete-variable 'w32-enable-italics
+                        'w32-enable-synthesized-fonts "21.1")
+(make-obsolete-variable 'w32-charset-to-codepage-alist
+                        'w32-charset-info-alist "21.1")
+
+\f
+;;;; Selections
+
+;; We keep track of the last text selected here, so we can check the
+;; current selection against it, and avoid passing back our own text
+;; from x-selection-value.
+(defvar x-last-selected-text nil)
+
+(defun x-get-selection-value ()
+  "Return the value of the current selection.
+Consult the selection.  Treat empty strings as if they were unset."
+  (if x-select-enable-clipboard
+      (let (text)
+        ;; Don't die if x-get-selection signals an error.
+        (condition-case c
+            (setq text (w32-get-clipboard-data))
+          (error (message "w32-get-clipboard-data:%s" c)))
+        (if (string= text "") (setq text nil))
+        (cond
+         ((not text) nil)
+         ((eq text x-last-selected-text) nil)
+         ((string= text x-last-selected-text)
+          ;; Record the newer string, so subsequent calls can use the 'eq' test.
+          (setq x-last-selected-text text)
+          nil)
+         (t
+          (setq x-last-selected-text text))))))
+\f
+(defalias 'x-selection-value 'x-get-selection-value)
+
+(defvar w32-clipboard-current-data nil
+  "The value currently advertised as being available on the
+clipboard.")
+
+;; 13 == CF_UNICODETEXT
+(add-hook 'w32-clipboard-render-functions
+  (defun w32-clipboard-render-cf-unicodetext (format)
+    (when (eql format 13)
+      (concat
+       (encode-coding-string w32-clipboard-current-data 'utf-16le-dos t)
+       "\0"))))
+(add-to-list 'w32-clipboard-advertised-types 13)
+
+(defconst w32-clipboard-format-html
+  (w32-register-clipboard-format "HTML Format")
+  "The system-specific numeric ID of the HTML clipboard format.")
+
+(defconst w32-clipboard-html-header
+  (concat "Version:0.9\r\n"
+          "StartHTML:%0006d\r\n"
+          "EndHTML:%0006d\r\n"
+          "StartFragment%0006d\r\n"
+          "EndFragment:%0006d\r\n"))
+
+(defconst w32-clipboard-html-fragment-prefix
+  (concat "<!DOCTYPE HTML>\r\n"
+          "<html><head><title></title></head><body>\r\n"
+          "<!--StartFragment-->\r\n"
+          "<pre%s>"
+))
+
+(defconst w32-clipboard-html-fragment-suffix
+  (concat
+   "</pre>\r\n"
+   "<!--EndFragment-->\r\n"
+   "</body></html>\r\n"))
+
+(defun w32-clipboard-color-string (name color)
+  (if color
+      (progn
+        (setq color (color-values color))
+        (format "%s:#%02x%02x%02x;"
+                name
+                (/ (car color) 256)
+                (/ (car (cdr color)) 256)
+                (/ (car (cdr (cdr color))) 256)))
+    ""))
+
+(defun w32-clipboard-face-as-style (face &optional background)
+  (if (null face)
+      ""
+    (concat
+     " style=\""
+     (w32-clipboard-color-string 
+      "color"
+      (face-attribute face :foreground nil 'default))
+     (if background
+         (w32-clipboard-color-string 
+          "background-color"
+          (face-attribute face :background nil 'default))
+       "")
+    "\"")))
+
+(defun w32-clipboard-string-to-html (str)
+  "Format a string for Windows HTML interchange via the clipboard."
+  (let (face prev-face
+             body
+             result
+             chr part
+             (i 0) (len (length str)))
+    (while (< i len)
+      (setq chr (aref str i))
+      (cond ((and (>= chr 32)
+                  (<= chr 126)
+                  (not (memql chr '(?\< ?\> ?\" \?&))))
+             (setq part (char-to-string chr)))
+            ((eql chr ?\n)
+             (setq part "\r\n"))
+            (t
+             (setq part (format "&#x%x;" chr))))
+      (setq face (or (get-text-property i 'face str)))
+      (when (or (not body) (not (eq face prev-face)))
+        (setq body (cons (format (if body "</span><span%s>" "<span%s>")
+                                 (w32-clipboard-face-as-style face))
+                         body))
+        (setq prev-face face))
+      (setq body (cons part body))
+      (setq i (1+ i)))
+
+    (when body
+      (setq body (cons "</span>" body)))
+    (setq body (mapconcat #'identity (nreverse body) ""))
+    (let* ((prefix (format w32-clipboard-html-fragment-prefix
+                           (w32-clipboard-face-as-style 'default t)))
+           (suffix w32-clipboard-html-fragment-suffix)
+           (StartHTML (length w32-clipboard-html-header))
+           (StartFragment (+ StartHTML (length prefix)))
+           (EndFragment (+ StartFragment (length body)))
+           (EndHTML (+ EndFragment (length suffix))))
+      (setq result
+            (concat
+             (format w32-clipboard-html-header
+                     StartHTML
+                     EndHTML
+                     StartFragment
+                     EndFragment)
+             prefix
+             body
+             suffix))
+      (message "%S" result)
+      result)))
+
+(add-hook 'w32-clipboard-render-functions
+  (defun w32-clipboard-render-cf-html (format)
+    (when (eql format w32-clipboard-format-html)
+      (w32-clipboard-string-to-html w32-clipboard-current-data))))
+(add-to-list 'w32-clipboard-advertised-types w32-clipboard-format-html)
+
+(defun w32-clipboard-render (type)
+  (run-hook-with-args-until-success 'w32-clipboard-render-functions type))
+
+(add-hook 'w32-lost-selection-functions
+  (defun w32-clipboard-lost-selection (cb)
+    (setq w32-clipboard-current-data nil)))
+
+(defun w32-set-clipboard-data (string &optional ignored)
+  (setq w32-clipboard-current-data string)
+  (w32-claim-clipboard))
+
+(defun w32-get-clipboard-data (&optional ignored)
+  "This gets the clipboard data in text format.  "
+  ;; Don't return our own selection.
+  (unless w32-clipboard-current-data
+    (let ((raw-unicode (w32-get-raw-clipboard-data 13)))
+      (when raw-unicode
+        (decode-coding-string
+         ;; Trim off trailing nulls
+         (if (> (length raw-unicode) 2)
+             (substring raw-unicode 0 -2)
+           raw-unicode)
+         'utf-16le t)))))
+
+;; Arrange for the kill and yank functions to set and check the clipboard.
+(setq interprogram-cut-function 'x-select-text)
+(setq interprogram-paste-function 'x-get-selection-value)
+
 (provide 'w32-win)
 
 ;;; w32-win.el ends here

=== modified file 'lisp/w32-fns.el'
--- lisp/w32-fns.el	2011-06-30 03:13:35 +0000
+++ lisp/w32-fns.el	2011-07-16 14:36:16 +0000
@@ -31,24 +31,13 @@
 
 ;;;; Function keys
 
-(declare-function set-message-beep "w32console.c")
-(declare-function w32-get-clipboard-data "w32select.c")
 (declare-function w32-get-locale-info "w32proc.c")
 (declare-function w32-get-valid-locale-ids "w32proc.c")
-(declare-function w32-set-clipboard-data "w32select.c")
 
 ;; Map all versions of a filename (8.3, longname, mixed case) to the
 ;; same buffer.
 (setq find-file-visit-truename t)
 
-(declare-function x-server-version "w32fns.c" (&optional display))
-
-(defun w32-version ()
-  "Return the MS-Windows version numbers.
-The value is a list of three integers: the major and minor version
-numbers, and the build number."
-  (x-server-version))
-
 (defun w32-using-nt ()
   "Return non-nil if running on a Windows NT descendant.
 That includes all Windows systems except for 9X/Me."
@@ -258,53 +247,6 @@
 	  (setq start (match-end 0))))
       name)))
 
-;;; Fix interface to (X-specific) mouse.el
-(defun x-set-selection (type data)
-  "Make an X selection of type TYPE and value DATA.
-The argument TYPE (nil means `PRIMARY') says which selection, and
-DATA specifies the contents.  TYPE must be a symbol.  \(It can also
-be a string, which stands for the symbol with that name, but this
-is considered obsolete.)  DATA may be a string, a symbol, an
-integer (or a cons of two integers or list of two integers).
-
-The selection may also be a cons of two markers pointing to the same buffer,
-or an overlay.  In these cases, the selection is considered to be the text
-between the markers *at whatever time the selection is examined*.
-Thus, editing done in the buffer after you specify the selection
-can alter the effective value of the selection.
-
-The data may also be a vector of valid non-vector selection values.
-
-The return value is DATA.
-
-Interactively, this command sets the primary selection.  Without
-prefix argument, it reads the selection in the minibuffer.  With
-prefix argument, it uses the text of the region as the selection value.
-
-Note that on MS-Windows, primary and secondary selections set by Emacs
-are not available to other programs."
-  (put 'x-selections (or type 'PRIMARY) data))
-
-(defun x-get-selection (&optional type _data-type)
-  "Return the value of an X Windows selection.
-The argument TYPE (default `PRIMARY') says which selection,
-and the argument DATA-TYPE (default `STRING') says
-how to convert the data.
-
-TYPE may be any symbol \(but nil stands for `PRIMARY').  However,
-only a few symbols are commonly used.  They conventionally have
-all upper-case names.  The most often used ones, in addition to
-`PRIMARY', are `SECONDARY' and `CLIPBOARD'.
-
-DATA-TYPE is usually `STRING', but can also be one of the symbols
-in `selection-converter-alist', which see."
-  (get 'x-selections (or type 'PRIMARY)))
-
-;; x-selection-owner-p is used in simple.el
-(defun x-selection-owner-p (&optional type)
-  (and (memq type '(nil PRIMARY SECONDARY))
-       (get 'x-selections (or type 'PRIMARY))))
-
 (defun set-w32-system-coding-system (coding-system)
   "Set the coding system used by the Windows system to CODING-SYSTEM.
 This is used for things like passing font names with non-ASCII
@@ -326,15 +268,6 @@
 ;; w32-system-coding-system. Use that instead.
 (defvaralias 'w32-system-coding-system 'locale-coding-system)
 
-;; Set to a system sound if you want a fancy bell.
-(set-message-beep nil)
-
-;; The "Windows" keys on newer keyboards bring up the Start menu
-;; whether you want it or not - make Emacs ignore these keystrokes
-;; rather than beep.
-(global-set-key [lwindow] 'ignore)
-(global-set-key [rwindow] 'ignore)
-
 (defvar w32-charset-info-alist)		; w32font.c
 
 (defun w32-add-charset-info (xlfd-charset windows-charset codepage)
@@ -392,45 +325,6 @@
 (w32-add-charset-info "tis620-0" 'w32-charset-thai 874)
 (w32-add-charset-info "iso8859-1" 'w32-charset-ansi 1252)
 
-(make-obsolete-variable 'w32-enable-italics
-                        'w32-enable-synthesized-fonts "21.1")
-(make-obsolete-variable 'w32-charset-to-codepage-alist
-                        'w32-charset-info-alist "21.1")
-
-\f
-;;;; Selections
-
-;; We keep track of the last text selected here, so we can check the
-;; current selection against it, and avoid passing back our own text
-;; from x-selection-value.
-(defvar x-last-selected-text nil)
-
-(defun x-get-selection-value ()
-  "Return the value of the current selection.
-Consult the selection.  Treat empty strings as if they were unset."
-  (if x-select-enable-clipboard
-      (let (text)
-	;; Don't die if x-get-selection signals an error.
-	(condition-case c
-	    (setq text (w32-get-clipboard-data))
-	  (error (message "w32-get-clipboard-data:%s" c)))
-	(if (string= text "") (setq text nil))
-	(cond
-	 ((not text) nil)
-	 ((eq text x-last-selected-text) nil)
-	 ((string= text x-last-selected-text)
-	  ;; Record the newer string, so subsequent calls can use the 'eq' test.
-	  (setq x-last-selected-text text)
-	  nil)
-	 (t
-	  (setq x-last-selected-text text))))))
-\f
-(defalias 'x-selection-value 'x-get-selection-value)
-
-;; Arrange for the kill and yank functions to set and check the clipboard.
-(setq interprogram-cut-function 'x-select-text)
-(setq interprogram-paste-function 'x-get-selection-value)
-
 \f
 ;;;; Support for build process
 

=== modified file 'src/ChangeLog'
--- src/ChangeLog	2011-07-15 17:41:24 +0000
+++ src/ChangeLog	2011-07-17 06:57:48 +0000
@@ -1,3 +1,8 @@
+2011-07-17  Daniel Colascione  <dan.colascione@gmail.com>
+
+	* s/cygwin.h: Remove prohibition against vfork.  It's okay to use
+	now.
+
 2011-07-09  Lawrence Mitchell  <wence@gmx.li>
 
 	* gnutls.c (Qgnutls_bootprop_min_prime_bits): New variable.

=== modified file 'src/Makefile.in'
--- src/Makefile.in	2011-07-08 20:20:19 +0000
+++ src/Makefile.in	2011-07-17 10:24:47 +0000
@@ -252,6 +252,13 @@
 NS_OBJC_OBJ=@NS_OBJC_OBJ@
 ## Only set if NS_IMPL_GNUSTEP.
 GNU_OBJC_CFLAGS=@GNU_OBJC_CFLAGS@
+## w32fns.o w32menu.c w32reg.o fringe.o fontset.o w32font.o w32term.o
+## w32xfns.o w32select.o image.o w32uniscribe.o if HAVE_W32, else
+## empty.
+W32_OBJ=@W32_OBJ@
+## -lkernel32 -luser32 -lgdi32 -lole32 -lcomdlg32 lusp10 -lcomctl32
+## --lwinspool if HAVE_W32, else empty.
+W32_LIBS=@W32_LIBS@
 
 ## Empty if !HAVE_X_WINDOWS
 ## xfont.o ftfont.o xftfont.o ftxfont.o if HAVE_XFT
@@ -337,7 +344,8 @@
 	process.o gnutls.o callproc.o \
 	region-cache.o sound.o atimer.o \
 	doprnt.o intervals.o textprop.o composite.o xml.o \
-	$(MSDOS_OBJ) $(MSDOS_X_OBJ) $(NS_OBJ) $(CYGWIN_OBJ) $(FONT_OBJ)
+	$(MSDOS_OBJ) $(MSDOS_X_OBJ) $(NS_OBJ) $(CYGWIN_OBJ) $(FONT_OBJ) \
+	$(W32_OBJ)
 obj = $(base_obj) $(NS_OBJC_OBJ)
 
 ## Object files used on some machine or other.
@@ -346,9 +354,9 @@
 ## in the list, in case they ever add any such entries.
 SOME_MACHINE_OBJECTS = dosfns.o msdos.o \
   xterm.o xfns.o xmenu.o xselect.o xrdb.o xsmfns.o fringe.o image.o \
-  fontset.o dbusbind.o \
+  fontset.o dbusbind.o cygw32.o \
   nsterm.o nsfns.o nsmenu.o nsselect.o nsimage.o nsfont.o \
-  w32.o w32console.o w32fns.o w32heap.o w32inevt.o \
+  w32.o w32console.o w32fns.o w32heap.o \
   w32menu.o w32proc.o w32reg.o w32select.o w32term.o w32xfns.o \
   w16select.o widget.o xfont.o ftfont.o xftfont.o ftxfont.o gtkutil.o \
   xsettings.o xgselect.o termcap.o
@@ -380,7 +388,7 @@
 ## Note that SunOS needs -lm to come before -lc; otherwise, you get
 ## duplicated symbols.  If the standard libraries were compiled
 ## with GCC, we might need LIB_GCC again after them.
-LIBES = $(LIBS) $(LIBX_BASE) $(LIBX_OTHER) $(LIBSOUND) \
+LIBES = $(LIBS) $(W32_LIBS) $(LIBX_BASE) $(LIBX_OTHER) $(LIBSOUND) \
    $(RSVG_LIBS) $(IMAGEMAGICK_LIBS) $(DBUS_LIBS) \
    $(LIBXML2_LIBS) $(LIBGPM) $(LIBRESOLV) $(LIBS_SYSTEM) \
    $(LIBS_TERMCAP) $(GETLOADAVG_LIBS) $(SETTINGS_LIBS) $(LIBSELINUX_LIBS) \

=== added file 'src/cygw32.c'
--- src/cygw32.c	1970-01-01 00:00:00 +0000
+++ src/cygw32.c	2011-07-17 12:08:27 +0000
@@ -0,0 +1,150 @@
+/* Cygwin support routines.
+   Copyright (C) 2011  Free Software Foundation, Inc.
+
+This file is part of GNU Emacs.
+
+GNU Emacs is free software: you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation, either version 3 of the License, or
+(at your option) any later version.
+
+GNU Emacs 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 General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Emacs.  If not, see <http://www.gnu.org/licenses/>.  */
+
+
+#include "cygw32.h"
+
+static Lisp_Object Qutf_16_le;
+
+/* Advance the given string by one character */
+BYTE*
+_mbsinc (const BYTE* current)
+{
+  return (BYTE*)current + 1; /* XXX: stub */
+}
+
+unsigned
+_mbsnextc (const BYTE* current)
+{
+  return *current; /* XXX: stub */
+}
+
+BYTE*
+_mbsncpy (BYTE* dest, const BYTE* src, size_t count)
+{
+  return strncpy (dest, src, count); /* XXX: stub */
+}
+
+extern Lisp_Object
+conv_filename_to_w32_unicode (Lisp_Object in, int absolute_p)
+{
+  ssize_t converted_len;
+  Lisp_Object converted;
+  unsigned flags;
+
+  flags = CCP_POSIX_TO_WIN_W;
+  if (!absolute_p) {
+    flags |= CCP_RELATIVE;
+  }
+
+  in = ENCODE_UTF_8 (in);
+
+  converted_len = cygwin_conv_path (flags, SDATA (in), NULL, 0);
+  if (converted_len < 2)
+    error ("cygwin_conv_path: %s", strerror (errno));
+  
+  converted = make_uninit_string (converted_len - 1);
+  if (cygwin_conv_path (flags, SDATA (in),
+                        SDATA (converted), converted_len))
+    error ("cygwin_conv_path: %s", strerror (errno));
+  
+  return converted;
+}
+
+extern Lisp_Object
+conv_filename_from_w32_unicode (const wchar_t* in, int absolute_p)
+{
+  ssize_t converted_len;
+  Lisp_Object converted;
+  unsigned flags;
+
+  flags = CCP_WIN_W_TO_POSIX;
+  if (!absolute_p) {
+    flags |= CCP_RELATIVE;
+  }
+
+  converted_len = cygwin_conv_path (flags, in, NULL, 0);
+  if (converted_len < 1)
+    error ("cygwin_conv_path: %s", strerror (errno));
+  
+  converted = make_uninit_string (converted_len - 1 /*subtract terminator*/);
+  if (cygwin_conv_path (flags, in, SDATA (converted), converted_len))
+    error ("cygwin_conv_path: %s", strerror (errno));
+  
+  return code_convert_string_norecord (converted, Qutf_8, 0);
+}
+
+Lisp_Object
+from_unicode (Lisp_Object str)
+{
+  CHECK_STRING (str);
+  if (!STRING_MULTIBYTE (str) &&
+      SBYTES (str) & 1)
+    {
+      str = Fsubstring (str, make_number (0), make_number (-1));
+    }
+  
+  return code_convert_string_norecord (str, Qutf_16_le, 0);
+}
+
+wchar_t*
+to_unicode (Lisp_Object str, Lisp_Object* buf)
+{
+  *buf = code_convert_string_norecord (str, Qutf_16_le, 1);
+  /* We need to make an additional copy to ensure that the final
+     string is _doubly_ zero terminated --- that is, that the string
+     is terminated by two zero bytes and one utf-16le null character.
+     Because strings are already terminated with a single zero byte,
+     we just add one additional zero. */
+  str = make_uninit_string (SBYTES (*buf) + 1);
+  memcpy (SDATA (str), SDATA (*buf), SBYTES (*buf));
+  SDATA (str) [SBYTES (*buf)] = '\0';
+  *buf = str;
+  return WCSDATA (*buf);
+}
+
+DEFUN ("cygwin-convert-path-to-windows",
+       Fcygwin_convert_path_to_windows, Scygwin_convert_path_to_windows,
+       1, 2, 0,
+       doc: /* Convert PATH to a Windows path.  If ABSOLUTE-P if
+               non-nil, return an absolute path.*/)
+  (Lisp_Object path, Lisp_Object absolute_p)
+{
+  return from_unicode (
+    conv_filename_to_w32_unicode (path, absolute_p == Qnil ? 0 : 1));
+}
+
+DEFUN ("cygwin-convert-path-from-windows",
+       Fcygwin_convert_path_from_windows, Scygwin_convert_path_from_windows,
+       1, 2, 0,
+       doc: /* Convert a Windows path to a Cygwin path.  If ABSOLUTE-P
+               if non-nil, return an absolute path.*/)
+  (Lisp_Object path, Lisp_Object absolute_p)
+{
+  return conv_filename_from_w32_unicode (to_unicode (path, &path),
+                                         absolute_p == Qnil ? 0 : 1);
+}
+
+void
+syms_of_cygw32 (void)
+{
+  /* No, not utf-16-le: that one has a BOM.  */
+  DEFSYM (Qutf_16_le, "utf-16le"); 
+  defsubr (&Scygwin_convert_path_from_windows);
+  defsubr (&Scygwin_convert_path_to_windows);
+}

=== modified file 'src/dispextern.h'
--- src/dispextern.h	2011-07-14 17:28:42 +0000
+++ src/dispextern.h	2011-07-16 10:15:54 +0000
@@ -3106,7 +3106,7 @@
 int update_window_fringes (struct window *, int);
 void compute_fringe_widths (struct frame *, int);
 
-#ifdef WINDOWSNT
+#ifdef HAVE_NTGUI
 void w32_init_fringe (struct redisplay_interface *);
 void w32_reset_fringes (void);
 #endif
@@ -3207,7 +3207,7 @@
 #ifdef HAVE_X_WINDOWS
 void gamma_correct (struct frame *, XColor *);
 #endif
-#ifdef WINDOWSNT
+#ifdef HAVE_NTGUI
 void gamma_correct (struct frame *, COLORREF *);
 #endif
 

=== modified file 'src/emacs.c'
--- src/emacs.c	2011-07-10 08:20:10 +0000
+++ src/emacs.c	2011-07-17 13:41:12 +0000
@@ -35,7 +35,11 @@
 #include <fcntl.h>
 #include <windows.h> /* just for w32.h */
 #include "w32.h"
-#include "w32heap.h" /* for prototype of sbrk */
+#endif
+
+#if WINDOWSNT || HAVE_NTGUI
+#include "w32heap.h"
+#include "w32select.h"
 #endif
 
 #ifdef NS_IMPL_GNUSTEP
@@ -1410,6 +1414,11 @@
     tzset ();
 #endif /* MSDOS */
 
+#if WINDOWSNT || HAVE_NTGUI
+  hinst = GetModuleHandle(NULL);
+  cache_system_info ();
+#endif
+
 #ifdef WINDOWSNT
   globals_of_w32 ();
   /* Initialize environment from registry settings.  */
@@ -1512,6 +1521,9 @@
 #ifdef WINDOWSNT
       syms_of_ntproc ();
 #endif /* WINDOWSNT */
+#ifdef CYGWIN
+      syms_of_cygw32 ();
+#endif /* CYGWIN */
       syms_of_window ();
       syms_of_xdisp ();
       syms_of_font ();
@@ -1542,11 +1554,14 @@
 #ifdef HAVE_NTGUI
       syms_of_w32term ();
       syms_of_w32fns ();
-      syms_of_w32select ();
       syms_of_w32menu ();
       syms_of_fontset ();
 #endif /* HAVE_NTGUI */
 
+#ifdef HAVE_W32SELECT
+      syms_of_w32select ();
+#endif /* HAVE_W32SELECT */
+      
 #ifdef MSDOS
       syms_of_xmenu ();
       syms_of_dosfns();
@@ -1588,8 +1603,11 @@
 #ifdef HAVE_NTGUI
       globals_of_w32fns ();
       globals_of_w32menu ();
+#endif  /* HAVE_NTGUI */
+
+#ifdef HAVE_W32SELECT
       globals_of_w32select ();
-#endif  /* HAVE_NTGUI */
+#endif /* HAVE_W32SELECT */
     }
 
   init_charset ();

=== modified file 'src/font.c'
--- src/font.c	2011-07-10 08:20:10 +0000
+++ src/font.c	2011-07-16 12:10:21 +0000
@@ -5207,9 +5207,9 @@
 #ifdef HAVE_BDFFONT
   syms_of_bdffont ();
 #endif	/* HAVE_BDFFONT */
-#ifdef WINDOWSNT
+#ifdef HAVE_NTGUI
   syms_of_w32font ();
-#endif	/* WINDOWSNT */
+#endif	/* HAVE_NTGUI */
 #ifdef HAVE_NS
   syms_of_nsfont ();
 #endif	/* HAVE_NS */

=== modified file 'src/font.h'
--- src/font.h	2011-06-20 05:51:47 +0000
+++ src/font.h	2011-07-16 06:51:09 +0000
@@ -830,11 +830,11 @@
 extern void syms_of_bdffont (void);
 #endif	/* HAVE_BDFFONT */
 #endif	/* HAVE_X_WINDOWS */
-#ifdef WINDOWSNT
+#ifdef HAVE_NTGUI
 extern struct font_driver w32font_driver;
 extern struct font_driver uniscribe_font_driver;
 extern void syms_of_w32font (void);
-#endif	/* WINDOWSNT */
+#endif	/* HAVE_NTGUI */
 #ifdef HAVE_NS
 extern Lisp_Object Qfontsize;
 extern struct font_driver nsfont_driver;

=== modified file 'src/fontset.c'
--- src/fontset.c	2011-06-13 04:55:03 +0000
+++ src/fontset.c	2011-07-16 10:55:38 +0000
@@ -45,7 +45,7 @@
 #ifdef HAVE_X_WINDOWS
 #include "xterm.h"
 #endif
-#ifdef WINDOWSNT
+#ifdef HAVE_NTGUI
 #include "w32term.h"
 #endif
 #ifdef HAVE_NS

=== modified file 'src/frame.c'
--- src/frame.c	2011-06-24 21:25:22 +0000
+++ src/frame.c	2011-07-16 12:10:01 +0000
@@ -29,7 +29,7 @@
 #ifdef HAVE_X_WINDOWS
 #include "xterm.h"
 #endif
-#ifdef WINDOWSNT
+#ifdef HAVE_NTGUI
 #include "w32term.h"
 #endif
 #ifdef HAVE_NS
@@ -2734,7 +2734,7 @@
   {"tool-bar-position",		&Qtool_bar_position},
 };
 
-#ifdef WINDOWSNT
+#ifdef HAVE_NTGUI
 
 /* Calculate fullscreen size.  Return in *TOP_POS and *LEFT_POS the
    wanted positions of the WM window (not Emacs window).
@@ -2778,7 +2778,7 @@
   *height = newheight;
 }
 
-#endif /* WINDOWSNT */
+#endif /* HAVE_NTGUI */
 
 #ifdef HAVE_WINDOW_SYSTEM
 

=== modified file 'src/frame.h'
--- src/frame.h	2011-06-11 21:31:32 +0000
+++ src/frame.h	2011-07-16 10:13:49 +0000
@@ -1092,7 +1092,7 @@
 
 extern Lisp_Object Qface_set_after_frame_default;
 
-#ifdef WINDOWSNT
+#ifdef HAVE_NTGUI
 extern void x_fullscreen_adjust (struct frame *f, int *, int *,
                                  int *, int *);
 #endif

=== modified file 'src/image.c'
--- src/image.c	2011-07-10 08:20:10 +0000
+++ src/image.c	2011-07-16 10:48:39 +0000
@@ -48,10 +48,13 @@
 #include "termhooks.h"
 #include "font.h"
 
+#if HAVE_X_WINDOWS || (CYGWIN && HAVE_NTGUI)
+#include <sys/types.h>
+#include <sys/stat.h>
+#endif
+
 #ifdef HAVE_X_WINDOWS
 #include "xterm.h"
-#include <sys/types.h>
-#include <sys/stat.h>
 
 #define COLOR_TABLE_SUPPORT 1
 
@@ -67,7 +70,11 @@
 
 
 #ifdef HAVE_NTGUI
+#if CYGWIN
+#include "cygw32.h"
+#else
 #include "w32.h"
+#endif
 #include "w32term.h"
 
 /* W32_TODO : Color tables on W32.  */
@@ -588,7 +595,7 @@
 static void x_emboss (struct frame *, struct image *);
 static int x_build_heuristic_mask (struct frame *, struct image *,
                                    Lisp_Object);
-#ifdef HAVE_NTGUI
+#if WINDOWSNT
 #define CACHE_IMAGE_TYPE(type, status) \
   do { Vlibrary_cache = Fcons (Fcons (type, status), Vlibrary_cache); } while (0)
 #else
@@ -2910,7 +2917,7 @@
 	  else
 	    bits = (char *) XBOOL_VECTOR (data)->data;
 
-#ifdef WINDOWSNT
+#ifdef HAVE_NTGUI
           {
             char *invertedBits;
             int nbytes, i;
@@ -8614,7 +8621,7 @@
 of `dynamic-library-alist', which see).  */)
   (Lisp_Object type, Lisp_Object libraries)
 {
-#ifdef HAVE_NTGUI
+#ifdef WINDOWSNT
   /* Don't try to reload the library.  */
   Lisp_Object tested = Fassq (type, Vlibrary_cache);
   if (CONSP (tested))

=== modified file 'src/keyboard.c'
--- src/keyboard.c	2011-07-14 18:34:54 +0000
+++ src/keyboard.c	2011-07-17 07:59:27 +0000
@@ -321,7 +321,7 @@
 /* Symbols to denote kinds of events.  */
 static Lisp_Object Qfunction_key;
 Lisp_Object Qmouse_click;
-#if defined (WINDOWSNT)
+#if defined (HAVE_NTGUI)
 Lisp_Object Qlanguage_change;
 #endif
 static Lisp_Object Qdrag_n_drop;
@@ -3777,8 +3777,8 @@
 #ifdef subprocesses
   if (kbd_on_hold_p () && kbd_buffer_nr_stored () < KBD_BUFFER_SIZE/4)
     {
-      /* Start reading input again, we have processed enough so we can
-         accept new events again.  */
+      /* Start reading input again because we have processed enough to
+         be able to accept new events again.  */
       unhold_keyboard_input ();
 #ifdef SIGIO
       if (!noninteractive)
@@ -3962,7 +3962,7 @@
 	    x_activate_menubar (XFRAME (event->frame_or_window));
 	}
 #endif
-#if defined (WINDOWSNT)
+#if defined (HAVE_NTGUI)
       else if (event->kind == LANGUAGE_CHANGE_EVENT)
 	{
 	  /* Make an event (language-change (FRAME CHARSET LCID)).  */
@@ -5412,7 +5412,7 @@
 				  (sizeof (lispy_function_keys)
 				   / sizeof (lispy_function_keys[0])));
 
-#ifdef WINDOWSNT
+#ifdef HAVE_NTGUI
     case MULTIMEDIA_KEY_EVENT:
       if (event->code < (sizeof (lispy_multimedia_keys)
                          / sizeof (lispy_multimedia_keys[0]))
@@ -11528,7 +11528,7 @@
   DEFSYM (Qconfig_changed_event, "config-changed-event");
   DEFSYM (Qmenu_enable, "menu-enable");
 
-#if defined (WINDOWSNT)
+#if defined (HAVE_NTGUI)
   DEFSYM (Qlanguage_change, "language-change");
 #endif
 

=== modified file 'src/keyboard.h'
--- src/keyboard.h	2011-06-23 06:31:41 +0000
+++ src/keyboard.h	2011-07-16 06:28:00 +0000
@@ -511,6 +511,6 @@
 extern EMACS_TIME timer_check (void);
 extern void mark_kboards (void);
 
-#ifdef WINDOWSNT
+#ifdef HAVE_NTGUI
 extern const char *const lispy_function_keys[];
 #endif

=== modified file 'src/lisp.h'
--- src/lisp.h	2011-06-24 21:25:22 +0000
+++ src/lisp.h	2011-07-17 17:34:15 +0000
@@ -27,6 +27,14 @@
 
 #include <intprops.h>
 
+#define t(...)                                          \
+    ({                                                  \
+      fprintf (stderr, "T:%s:%u: ",                     \
+               __FUNCTION__, __LINE__);                 \
+      fprintf (stderr, __VA_ARGS__);                    \
+      fputc ('\n', stderr);                             \
+    })
+
 /* Use the configure flag --enable-checking[=LIST] to enable various
    types of run time checks for Lisp objects.  */
 

=== modified file 'src/process.c'
--- src/process.c	2011-07-06 18:04:23 +0000
+++ src/process.c	2011-07-17 09:23:40 +0000
@@ -108,6 +108,9 @@
 #ifdef HAVE_NS
 #include "nsterm.h"
 #endif
+#ifdef HAVE_NTGUI
+#include "w32term.h"
+#endif
 
 Lisp_Object Qeuid, Qegid, Qcomm, Qstate, Qppid, Qpgrp, Qsess, Qttname, Qtpgid;
 Lisp_Object Qminflt, Qmajflt, Qcminflt, Qcmajflt, Qutime, Qstime, Qcstime;
@@ -4531,6 +4534,8 @@
           nfds = xg_select
 #elif defined (HAVE_NS)
 	  nfds = ns_select
+#elif defined (USE_W32_SELECT)
+          nfds = w32_select  
 #else
 	  nfds = select
 #endif

=== modified file 'src/regex.c'
--- src/regex.c	2011-07-10 08:20:10 +0000
+++ src/regex.c	2011-07-16 16:34:09 +0000
@@ -1891,7 +1891,9 @@
 
 /* Explicit quit checking is only used on NTemacs and whenever we
    use polling to process input events.  */
-#if defined emacs && (defined WINDOWSNT || defined SYNC_INPUT) && defined QUIT
+#if (defined emacs &&                                                   \
+     (defined WINDOWSNT || defined HAVE_NTGUI || defined SYNC_INPUT) && \
+     defined QUIT)
 extern int immediate_quit;
 # define IMMEDIATE_QUIT_CHECK			\
     do {					\

=== modified file 'src/s/cygwin.h'
--- src/s/cygwin.h	2011-03-17 05:15:08 +0000
+++ src/s/cygwin.h	2011-07-17 09:40:15 +0000
@@ -81,10 +81,6 @@
 
 #define HAVE_SOCKETS
 
-/* vfork() interacts badly with setsid(), causing ptys to fail to
-   change their controlling terminal */
-#define vfork fork
-
 /* This should work (at least when compiling with gcc).  But I have no way
    or intention to verify or even test it.  If you encounter a problem with
    it, feel free to change this setting, but please add a comment here about
@@ -102,3 +98,23 @@
 
 /* Send signals to subprocesses by "typing" special chars at them.  */
 #define SIGNALS_VIA_CHARACTERS
+
+#ifdef HAVE_NTGUI
+
+/* Work around Cygwin signal bug
+ * <loom.20100428T060408-563@post.gmane.org> */
+#define USE_W32_SELECT
+
+extern int getloadavg (double *, int);
+
+#ifdef EMACSDEBUG
+extern void _DebPrint (const char *fmt, ...);
+#define DebPrint(stuff) _DebPrint stuff
+#else
+#define DebPrint(stuff)
+#endif /* EMACSDEBUG */
+
+#endif /* HAVE_NTGUI */
+
+/* For benefit of normally WINDOWSNT code. */
+

=== modified file 'src/termhooks.h'
--- src/termhooks.h	2011-06-06 19:43:39 +0000
+++ src/termhooks.h	2011-07-16 06:29:45 +0000
@@ -102,9 +102,9 @@
   HORIZ_WHEEL_EVENT,            /* A wheel event generated by a second
                                    horizontal wheel that is present on some
                                    mice. See WHEEL_EVENT.  */
-#if defined (WINDOWSNT)
+#if defined (HAVE_NTGUI)
   LANGUAGE_CHANGE_EVENT,	/* A LANGUAGE_CHANGE_EVENT is
-				   generated on WINDOWSNT or Mac OS
+				   generated on HAVE_NTGUI or Mac OS
 				   when the keyboard layout or input
 				   language is changed by the
 				   user.  */
@@ -183,7 +183,7 @@
 
   , CONFIG_CHANGED_EVENT
 
-#ifdef WINDOWSNT
+#ifdef HAVE_NTGUI
   /* Generated when an APPCOMMAND event is received, in response to
      Multimedia or Internet buttons on some keyboards.
      Such keys are available as normal function keys on X through the

=== modified file 'src/unexcw.c'
--- src/unexcw.c	2011-03-17 20:18:59 +0000
+++ src/unexcw.c	2011-07-16 06:24:32 +0000
@@ -31,6 +31,8 @@
 
 #define DOTEXE ".exe"
 
+extern void report_sheap_usage (int);
+
 extern int bss_sbrk_did_unexec;
 
 /* emacs symbols that indicate where bss and data end for emacs internals */

=== modified file 'src/w32.c'
--- src/w32.c	2011-07-09 07:00:58 +0000
+++ src/w32.c	2011-07-16 07:04:58 +0000
@@ -31,7 +31,6 @@
 #include <sys/file.h>
 #include <sys/time.h>
 #include <sys/utime.h>
-#include <mbstring.h>	/* for _mbspbrk */
 #include <math.h>
 #include <setjmp.h>
 #include <time.h>
@@ -39,6 +38,7 @@
 /* must include CRT headers *before* config.h */
 
 #include <config.h>
+#include <mbstring.h>	/* for _mbspbrk */
 
 #undef access
 #undef chdir
@@ -738,23 +738,6 @@
   return (s_pfn_Get_System_times (lpIdleTime, lpKernelTime, lpUserTime));
 }
 \f
-/* Equivalent of strerror for W32 error codes.  */
-char *
-w32_strerror (int error_no)
-{
-  static char buf[500];
-
-  if (error_no == 0)
-    error_no = GetLastError ();
-
-  buf[0] = '\0';
-  if (!FormatMessage (FORMAT_MESSAGE_FROM_SYSTEM, NULL,
-		      error_no,
-		      0, /* choose most suitable language */
-		      buf, sizeof (buf), NULL))
-    sprintf (buf, "w32 error %u", error_no);
-  return buf;
-}
 
 /* Return 1 if P is a valid pointer to an object of size SIZE.  Return
    0 if P is NOT a valid pointer.  Return -1 if we cannot validate P.

=== modified file 'src/w32.h'
--- src/w32.h	2011-05-04 14:03:16 +0000
+++ src/w32.h	2011-07-17 14:01:09 +0000
@@ -133,9 +133,6 @@
 extern void syms_of_w32term (void);
 extern void syms_of_w32fns (void);
 extern void globals_of_w32fns (void);
-extern void syms_of_w32select (void);
-extern void globals_of_w32select (void);
-extern void term_w32select (void);
 extern void syms_of_w32menu (void);
 extern void globals_of_w32menu (void);
 extern void syms_of_fontset (void);

=== modified file 'src/w32console.c'
--- src/w32console.c	2011-05-07 15:44:19 +0000
+++ src/w32console.c	2011-07-16 13:47:54 +0000
@@ -350,53 +350,6 @@
   scroll_line (f, n, LEFT);
 }
 
-static unsigned int sound_type = 0xFFFFFFFF;
-#define MB_EMACS_SILENT (0xFFFFFFFF - 1)
-
-void
-w32_sys_ring_bell (struct frame *f)
-{
-  if (sound_type == 0xFFFFFFFF)
-    {
-      Beep (666, 100);
-    }
-  else if (sound_type == MB_EMACS_SILENT)
-    {
-      /* Do nothing.  */
-    }
-  else
-    MessageBeep (sound_type);
-}
-
-DEFUN ("set-message-beep", Fset_message_beep, Sset_message_beep, 1, 1, 0,
-       doc: /* Set the sound generated when the bell is rung.
-SOUND is 'asterisk, 'exclamation, 'hand, 'question, 'ok, or 'silent
-to use the corresponding system sound for the bell.  The 'silent sound
-prevents Emacs from making any sound at all.
-SOUND is nil to use the normal beep.  */)
-  (Lisp_Object sound)
-{
-  CHECK_SYMBOL (sound);
-
-  if (NILP (sound))
-      sound_type = 0xFFFFFFFF;
-  else if (EQ (sound, intern ("asterisk")))
-      sound_type = MB_ICONASTERISK;
-  else if (EQ (sound, intern ("exclamation")))
-      sound_type = MB_ICONEXCLAMATION;
-  else if (EQ (sound, intern ("hand")))
-      sound_type = MB_ICONHAND;
-  else if (EQ (sound, intern ("question")))
-      sound_type = MB_ICONQUESTION;
-  else if (EQ (sound, intern ("ok")))
-      sound_type = MB_OK;
-  else if (EQ (sound, intern ("silent")))
-      sound_type = MB_EMACS_SILENT;
-  else
-      sound_type = 0xFFFFFFFF;
-
-  return sound;
-}
 
 static void
 w32con_reset_terminal_modes (struct terminal *t)
@@ -755,6 +708,5 @@
   defsubr (&Sset_screen_color);
   defsubr (&Sget_screen_color);
   defsubr (&Sset_cursor_size);
-  defsubr (&Sset_message_beep);
 }
 

=== modified file 'src/w32fns.c'
--- src/w32fns.c	2011-07-08 12:46:17 +0000
+++ src/w32fns.c	2011-07-17 17:45:48 +0000
@@ -45,8 +45,14 @@
 #include "fontset.h"
 #include "systime.h"
 #include "termhooks.h"
+
 #include "w32heap.h"
+
+#if CYGWIN
+#include "cygw32.h"
+#else
 #include "w32.h"
+#endif
 
 #include "bitmaps/gray.xbm"
 
@@ -79,6 +85,7 @@
 extern void w32_menu_display_help (HWND, HMENU, UINT, UINT);
 extern void w32_free_menu_strings (HWND);
 extern const char *map_w32_filename (const char *, const char **);
+extern char * w32_strerror (int error_no);
 
 /* If non-zero, a w32 timer that, when it expires, displays an
    hourglass cursor on all frames.  */
@@ -201,6 +208,30 @@
 static void w32_show_hourglass (struct frame *);
 static void w32_hide_hourglass (void);
 
+int faked_key;
+
+/* This gives us the page size and the size of the allocation unit on NT.  */
+SYSTEM_INFO sysinfo_cache;
+
+/* This gives us version, build, and platform identification.  */
+OSVERSIONINFO osinfo_cache;
+
+unsigned long syspage_mask = 0;
+
+/* The major and minor versions of NT.  */
+int w32_major_version;
+int w32_minor_version;
+int w32_build_number;
+
+/* Distinguish between Windows NT and Windows 95.  */
+int os_subtype;
+
+#ifdef HAVE_NTGUI
+HINSTANCE hinst = NULL;
+#endif
+
+static unsigned int sound_type = 0xFFFFFFFF;
+#define MB_EMACS_SILENT (0xFFFFFFFF - 1)
 
 \f
 /* Error if we are not connected to MS-Windows.  */
@@ -1067,12 +1098,20 @@
    If ALLOC is nonzero, allocate a new colormap cell.  */
 
 int
-w32_defined_color (FRAME_PTR f, char *color, XColor *color_def, int alloc)
+w32_defined_color (FRAME_PTR f, const char *color, XColor *color_def, int alloc)
 {
   register Lisp_Object tem;
   COLORREF w32_color_ref;
-
-  tem = x_to_w32_color (color);
+  char* color_tem;
+  USE_SAFE_ALLOCA;
+
+  /* Allocate a temporary copy of COLOR because x_to_w32_color
+   * modifies it and we promised our caller we wouldn't. */
+
+  SAFE_ALLOCA (color_tem, char*, strlen (color));
+  strcpy (color_tem, color);
+  tem = x_to_w32_color (color_tem);
+  SAFE_FREE ();
 
   if (!NILP (tem))
     {
@@ -1829,10 +1868,7 @@
 
   /* Do first time app init */
 
-  if (!hprevinst)
-    {
-      w32_init_class (hinst);
-    }
+  w32_init_class (hinst);
 
   if (f->size_hint_flags & USPosition || f->size_hint_flags & PPosition)
     {
@@ -2232,6 +2268,58 @@
     }
 }
 
+#if EMACSDEBUG
+const char*
+w32_name_of_message (UINT msg)
+{
+  unsigned i;
+  static char buf[64];
+  static const struct {
+    UINT msg;
+    const char* name;
+  } msgnames[] = {
+#define M(msg) { msg, # msg }
+      M (WM_PAINT),
+      M (WM_TIMER),
+      M (WM_USER),
+      M (WM_MOUSEMOVE),
+      M (WM_LBUTTONUP),
+      M (WM_KEYDOWN),
+      M (WM_EMACS_KILL),
+      M (WM_EMACS_CREATEWINDOW),
+      M (WM_EMACS_DONE),
+      M (WM_EMACS_CREATESCROLLBAR),
+      M (WM_EMACS_SHOWWINDOW),
+      M (WM_EMACS_SETWINDOWPOS),
+      M (WM_EMACS_DESTROYWINDOW),
+      M (WM_EMACS_TRACKPOPUPMENU),
+      M (WM_EMACS_SETFOCUS),
+      M (WM_EMACS_SETFOREGROUND),
+      M (WM_EMACS_SETLOCALE),
+      M (WM_EMACS_SETKEYBOARDLAYOUT),
+      M (WM_EMACS_REGISTER_HOT_KEY),
+      M (WM_EMACS_UNREGISTER_HOT_KEY),
+      M (WM_EMACS_TOGGLE_LOCK_KEY),
+      M (WM_EMACS_TRACK_CARET),
+      M (WM_EMACS_DESTROY_CARET),
+      M (WM_EMACS_SHOW_CARET),
+      M (WM_EMACS_HIDE_CARET),
+      M (WM_EMACS_SETCURSOR),
+      M (WM_EMACS_PAINT),
+      M (WM_CHAR),
+#undef M
+      { 0, 0 }
+  };
+
+  for (i = 0; msgnames[i].name; ++i)
+    if (msgnames[i].msg == msg)
+      return msgnames[i].name;
+
+  sprintf (buf, "message 0x%04x", (unsigned)msg);
+  return buf;    
+}
+#endif /* EMACSDEBUG */
+
 /* Main message dispatch loop. */
 
 static void
@@ -2245,6 +2333,10 @@
 
   while (GetMessage (&msg, NULL, 0, 0))
     {
+      
+      /* DebPrint (("w32_msg_pump: %s time:%u\n", */
+      /*            w32_name_of_message (msg.message), msg.time)); */
+      
       if (msg.hwnd == NULL)
 	{
 	  switch (msg.message)
@@ -4653,6 +4745,37 @@
 {
   return Qnil;
 }
+
+DEFUN ("set-message-beep", Fset_message_beep, Sset_message_beep, 1, 1, 0,
+       doc: /* Set the sound generated when the bell is rung.
+SOUND is 'asterisk, 'exclamation, 'hand, 'question, 'ok, or 'silent
+to use the corresponding system sound for the bell.  The 'silent sound
+prevents Emacs from making any sound at all.
+SOUND is nil to use the normal beep.  */)
+  (Lisp_Object sound)
+{
+  CHECK_SYMBOL (sound);
+
+  if (NILP (sound))
+      sound_type = 0xFFFFFFFF;
+  else if (EQ (sound, intern ("asterisk")))
+      sound_type = MB_ICONASTERISK;
+  else if (EQ (sound, intern ("exclamation")))
+      sound_type = MB_ICONEXCLAMATION;
+  else if (EQ (sound, intern ("hand")))
+      sound_type = MB_ICONHAND;
+  else if (EQ (sound, intern ("question")))
+      sound_type = MB_ICONQUESTION;
+  else if (EQ (sound, intern ("ok")))
+      sound_type = MB_OK;
+  else if (EQ (sound, intern ("silent")))
+      sound_type = MB_EMACS_SILENT;
+  else
+      sound_type = 0xFFFFFFFF;
+
+  return sound;
+}
+
 \f
 int
 x_pixel_width (register struct frame *f)
@@ -5841,7 +5964,7 @@
 {
   if (msg == WM_NOTIFY)
     {
-      OFNOTIFY * notify = (OFNOTIFY *)lParam;
+      OFNOTIFYW * notify = (OFNOTIFYW *)lParam;
       /* Detect when the Filter dropdown is changed.  */
       if (notify->hdr.code == CDN_TYPECHANGE
 	  || notify->hdr.code == CDN_INITDONE)
@@ -5869,7 +5992,7 @@
 	  if (notify->lpOFN->nFilterIndex == 2)
 	    {
 	      CommDlg_OpenSave_SetControlText (dialog, FILE_NAME_TEXT_FIELD,
-					       "Current Directory");
+					       L"Current Directory");
 	      EnableWindow (edit_control, FALSE);
 	      /* Note that at least on Windows 7, the above call to EnableWindow
 		 disables the window that would ordinarily have focus.	If we
@@ -5885,7 +6008,7 @@
 	      /* Don't override default filename on init done.  */
 	      if (notify->hdr.code == CDN_TYPECHANGE)
 		CommDlg_OpenSave_SetControlText (dialog,
-						 FILE_NAME_TEXT_FIELD, "");
+						 FILE_NAME_TEXT_FIELD, L"");
 	      EnableWindow (edit_control, TRUE);
 	    }
 	}
@@ -5893,19 +6016,6 @@
   return 0;
 }
 
-/* Since we compile with _WIN32_WINNT set to 0x0400 (for NT4 compatibility)
-   we end up with the old file dialogs. Define a big enough struct for the
-   new dialog to trick GetOpenFileName into giving us the new dialogs on
-   Windows 2000 and XP.  */
-typedef struct
-{
-  OPENFILENAME real_details;
-  void * pReserved;
-  DWORD dwReserved;
-  DWORD FlagsEx;
-} NEWOPENFILENAME;
-
-
 DEFUN ("x-file-dialog", Fx_file_dialog, Sx_file_dialog, 2, 5, 0,
        doc: /* Read file name, prompting with PROMPT in directory DIR.
 Use a file selection dialog.  Select DEFAULT-FILENAME in the dialog's file
@@ -5919,131 +6029,109 @@
 {
   struct frame *f = SELECTED_FRAME ();
   Lisp_Object file = Qnil;
+  Lisp_Object filename = empty_unibyte_string;
+  Lisp_Object filter = Qnil;
   int count = SPECPDL_INDEX ();
-  struct gcpro gcpro1, gcpro2, gcpro3, gcpro4, gcpro5, gcpro6;
-  char filename[MAX_PATH + 1];
-  char init_dir[MAX_PATH + 1];
+  wchar_t filename_buf[MAX_PATH * 4];
   int default_filter_index = 1; /* 1: All Files, 2: Directories only  */
+  struct gcpro gcpro1, gcpro2, gcpro3;
 
-  GCPRO6 (prompt, dir, default_filename, mustmatch, only_dir_p, file);
+  GCPRO3 (file, filename, filter);
   CHECK_STRING (prompt);
   CHECK_STRING (dir);
 
+  to_unicode (prompt, &prompt);
+
   /* Create the dialog with PROMPT as title, using DIR as initial
      directory and using "*" as pattern.  */
-  dir = Fexpand_file_name (dir, Qnil);
-  strncpy (init_dir, SDATA (ENCODE_FILE (dir)), MAX_PATH);
-  init_dir[MAX_PATH] = '\0';
-  unixtodos_filename (init_dir);
-
-  if (STRINGP (default_filename))
-    {
-      char *file_name_only;
-      char *full_path_name = SDATA (ENCODE_FILE (default_filename));
-
-      unixtodos_filename (full_path_name);
-
-      file_name_only = strrchr (full_path_name, '\\');
-      if (!file_name_only)
-        file_name_only = full_path_name;
-      else
-	file_name_only++;
-
-      strncpy (filename, file_name_only, MAX_PATH);
-      filename[MAX_PATH] = '\0';
-    }
-  else
-    filename[0] = '\0';
-
-  /* The code in file_dialog_callback that attempts to set the text
-     of the file name edit window when handling the CDN_INITDONE
-     WM_NOTIFY message does not work.  Setting filename to "Current
-     Directory" in the only_dir_p case here does work however.  */
-  if (filename[0] == 0 && ! NILP (only_dir_p))
-    strcpy (filename, "Current Directory");
+  to_unicode (Fexpand_file_name (dir, Qnil), &dir);
+
+  to_unicode (build_string ("All Files (*.*)\0*.*\0Directories\0*|*\0\0"),
+              &filter);
 
   {
-    NEWOPENFILENAME new_file_details;
+    OPENFILENAMEW file_details;
     BOOL file_opened = FALSE;
-    OPENFILENAME * file_details = &new_file_details.real_details;
 
     /* Prevent redisplay.  */
     specbind (Qinhibit_redisplay, Qt);
     BLOCK_INPUT;
 
-    memset (&new_file_details, 0, sizeof (new_file_details));
-    /* Apparently NT4 crashes if you give it an unexpected size.
-       I'm not sure about Windows 9x, so play it safe.  */
-    if (w32_major_version > 4 && w32_major_version < 95)
-      file_details->lStructSize = sizeof (NEWOPENFILENAME);
-    else
-      file_details->lStructSize = sizeof (OPENFILENAME);
-
-    file_details->hwndOwner = FRAME_W32_WINDOW (f);
+    memset (&file_details, 0, sizeof (file_details));
+    file_details.lStructSize = sizeof (file_details);
+
+    if (wcslen (WCSDATA (filename)) >= MAX_PATH*4) {
+      filename = empty_unibyte_string;
+    }
+    wcscpy (filename_buf, WCSDATA (filename));
+
+    file_details.hwndOwner = FRAME_W32_WINDOW (f);
     /* Undocumented Bug in Common File Dialog:
        If a filter is not specified, shell links are not resolved.  */
-    file_details->lpstrFilter = "All Files (*.*)\0*.*\0Directories\0*|*\0\0";
-    file_details->lpstrFile = filename;
-    file_details->nMaxFile = sizeof (filename);
-    file_details->lpstrInitialDir = init_dir;
-    file_details->lpstrTitle = SDATA (prompt);
+    file_details.lpstrFilter = WCSDATA (filter);
+    file_details.lpstrFile = filename_buf;
+    file_details.nMaxFile = sizeof (filename_buf) / sizeof (*filename_buf);
+    file_details.lpstrInitialDir = WCSDATA (dir);
+    file_details.lpstrTitle = WCSDATA (prompt);
 
     if (! NILP (only_dir_p))
       default_filter_index = 2;
 
-    file_details->nFilterIndex = default_filter_index;
+    file_details.nFilterIndex = default_filter_index;
 
-    file_details->Flags = (OFN_HIDEREADONLY | OFN_NOCHANGEDIR
+    file_details.Flags = (OFN_HIDEREADONLY | OFN_NOCHANGEDIR
 			  | OFN_EXPLORER | OFN_ENABLEHOOK);
     if (!NILP (mustmatch))
       {
 	/* Require that the path to the parent directory exists.  */
-	file_details->Flags |= OFN_PATHMUSTEXIST;
+	file_details.Flags |= OFN_PATHMUSTEXIST;
 	/* If we are looking for a file, require that it exists.  */
 	if (NILP (only_dir_p))
-	  file_details->Flags |= OFN_FILEMUSTEXIST;
+	  file_details.Flags |= OFN_FILEMUSTEXIST;
       }
 
-    file_details->lpfnHook = (LPOFNHOOKPROC) file_dialog_callback;
-
-    file_opened = GetOpenFileName (file_details);
+    file_details.lpfnHook = (LPOFNHOOKPROC) file_dialog_callback;
+    file_opened = GetOpenFileNameW (&file_details);
 
     UNBLOCK_INPUT;
 
     if (file_opened)
       {
-	dostounix_filename (filename);
 
-	if (file_details->nFilterIndex == 2)
+	if (file_details.nFilterIndex == 2)
 	  {
 	    /* "Directories" selected - strip dummy file name.  */
-	    char * last = strrchr (filename, '/');
-	    *last = '\0';
+	    wchar_t * last = wcsrchr (filename_buf, L'\\');
+            if (last)
+              *last = '\0';
 	  }
-
-	file = DECODE_FILE (build_string (filename));
+        filename = conv_filename_from_w32_unicode (filename_buf, 0);
       }
     /* User cancelled the dialog without making a selection.  */
     else if (!CommDlgExtendedError ())
-      file = Qnil;
+      filename = Qnil;
     /* An error occurred, fallback on reading from the mini-buffer.  */
     else
-      file = Fcompleting_read (prompt, intern ("read-file-name-internal"),
-			       dir, mustmatch, dir, Qfile_name_history,
-			       default_filename, Qnil);
-
-    file = unbind_to (count, file);
+      filename = Fcompleting_read (from_unicode (prompt),
+                                   intern ("read-file-name-internal"),
+                                   from_unicode (dir),
+                                   mustmatch,
+                                   from_unicode (dir),
+                                   Qfile_name_history,
+                                   default_filename, Qnil );
+    filename = unbind_to (count, filename);
   }
 
   UNGCPRO;
 
   /* Make "Cancel" equivalent to C-g.  */
-  if (NILP (file))
+  if (NILP (filename))
     Fsignal (Qquit, Qnil);
 
-  return unbind_to (count, file);
+  return unbind_to (count, filename);
 }
 
+#ifdef WINDOWSNT
 
 /* Moving files to the system recycle bin.
    Used by `move-file-to-trash' instead of the default moving to ~/.Trash  */
@@ -6098,6 +6186,8 @@
   return Qnil;
 }
 
+#endif /* WINDOWSNT */
+
 \f
 /***********************************************************************
                          w32 specialized functions
@@ -6532,7 +6622,7 @@
       else
 	{
 	  char buffer[16];
-	  _snprintf (buffer, 16, "%d", system_status.BatteryLifePercent);
+	  snprintf (buffer, 16, "%d", system_status.BatteryLifePercent);
 	  load_percentage = build_string (buffer);
 	}
 
@@ -6543,18 +6633,18 @@
 	  long m;
 	  float h;
 	  char buffer[16];
-	  _snprintf (buffer, 16, "%ld", seconds_left);
+	  snprintf (buffer, 16, "%ld", seconds_left);
 	  seconds = build_string (buffer);
 
 	  m = seconds_left / 60;
-	  _snprintf (buffer, 16, "%ld", m);
+	  snprintf (buffer, 16, "%ld", m);
 	  minutes = build_string (buffer);
 
 	  h = seconds_left / 3600.0;
-	  _snprintf (buffer, 16, "%3.1f", h);
+	  snprintf (buffer, 16, "%3.1f", h);
 	  hours = build_string (buffer);
 
-	  _snprintf (buffer, 16, "%ld:%02ld", m / 60, m % 60);
+	  snprintf (buffer, 16, "%ld:%02ld", m / 60, m % 60);
 	  remain = build_string (buffer);
 	}
       sequences[0] = Fcons (make_number ('L'), line_status);
@@ -6716,10 +6806,10 @@
         {
 	  /* a remote printer */
 	  if (*ppi2->pServerName == '\\')
-	    _snprintf (pname_buf, sizeof (pname_buf), "%s\\%s", ppi2->pServerName,
+	    snprintf (pname_buf, sizeof (pname_buf), "%s\\%s", ppi2->pServerName,
 		       ppi2->pShareName);
 	  else
-	    _snprintf (pname_buf, sizeof (pname_buf), "\\\\%s\\%s", ppi2->pServerName,
+	    snprintf (pname_buf, sizeof (pname_buf), "\\\\%s\\%s", ppi2->pServerName,
 		       ppi2->pShareName);
 	  pname_buf[sizeof (pname_buf) - 1] = '\0';
 	}
@@ -6738,6 +6828,276 @@
   return build_string (pname_buf);
 }
 \f
+
+/* Equivalent of strerror for W32 error codes.  */
+char *
+w32_strerror (int error_no)
+{
+  static char buf[500];
+  DWORD ret;
+
+  if (error_no == 0)
+    error_no = GetLastError ();
+
+  ret = FormatMessage (FORMAT_MESSAGE_FROM_SYSTEM |
+                       FORMAT_MESSAGE_IGNORE_INSERTS,
+                       NULL,
+                       error_no,
+                       0, /* choose most suitable language */
+                       buf, sizeof (buf), NULL);
+  
+  while (ret > 0 && (buf[ret - 1] == '\n' ||
+                     buf[ret - 1] == '\r' ))
+      --ret;
+  buf[ret] = '\0';
+  if (!ret)
+    sprintf (buf, "w32 error %u", error_no);
+  
+  return buf;
+}
+
+/* For convenience when debugging.  */
+int
+w32_last_error (void)
+{
+  return GetLastError ();
+}
+
+/* Cache information describing the NT system for later use.  */
+void
+cache_system_info (void)
+{
+  union
+    {
+      struct info
+	{
+	  char  major;
+	  char  minor;
+	  short platform;
+	} info;
+      DWORD data;
+    } version;
+
+  /* Cache the version of the operating system.  */
+  version.data = GetVersion ();
+  w32_major_version = version.info.major;
+  w32_minor_version = version.info.minor;
+
+  if (version.info.platform & 0x8000)
+    os_subtype = OS_WIN95;
+  else
+    os_subtype = OS_NT;
+
+  /* Cache page size, allocation unit, processor type, etc.  */
+  GetSystemInfo (&sysinfo_cache);
+  syspage_mask = sysinfo_cache.dwPageSize - 1;
+
+  /* Cache os info.  */
+  osinfo_cache.dwOSVersionInfoSize = sizeof (OSVERSIONINFO);
+  GetVersionEx (&osinfo_cache);
+
+  w32_build_number = osinfo_cache.dwBuildNumber;
+  if (os_subtype == OS_WIN95)
+    w32_build_number &= 0xffff;
+
+  w32_num_mouse_buttons = GetSystemMetrics (SM_CMOUSEBUTTONS);
+}
+
+#ifdef EMACSDEBUG
+void
+_DebPrint (const char *fmt, ...)
+{
+  char buf[1024];
+  va_list args;
+
+  va_start (args, fmt);
+  vsprintf (buf, fmt, args);
+  va_end (args);
+#if CYGWIN
+  fprintf (stderr, "%s", buf);
+#endif
+  OutputDebugString (buf);
+}
+#endif
+
+int
+w32_console_toggle_lock_key (int vk_code, Lisp_Object new_state)
+{
+  int cur_state = (GetKeyState (vk_code) & 1);
+
+  if (NILP (new_state)
+      || (NUMBERP (new_state)
+	  && ((XUINT (new_state)) & 1) != cur_state))
+    {
+      faked_key = vk_code;
+
+      keybd_event ((BYTE) vk_code,
+		   (BYTE) MapVirtualKey (vk_code, 0),
+		   KEYEVENTF_EXTENDEDKEY | KEYEVENTF_KEYUP, 0);
+      keybd_event ((BYTE) vk_code,
+		   (BYTE) MapVirtualKey (vk_code, 0),
+		   KEYEVENTF_EXTENDEDKEY | 0, 0);
+      keybd_event ((BYTE) vk_code,
+		   (BYTE) MapVirtualKey (vk_code, 0),
+		   KEYEVENTF_EXTENDEDKEY | KEYEVENTF_KEYUP, 0);
+      cur_state = !cur_state;
+    }
+
+  return cur_state;
+}
+
+/* Translate console modifiers to emacs modifiers.
+   German keyboard support (Kai Morgan Zeise 2/18/95).  */
+int
+w32_kbd_mods_to_emacs (DWORD mods, WORD key)
+{
+  int retval = 0;
+
+  /* If we recognize right-alt and left-ctrl as AltGr, and it has been
+     pressed, first remove those modifiers.  */
+  if (!NILP (Vw32_recognize_altgr)
+      && (mods & (RIGHT_ALT_PRESSED | LEFT_CTRL_PRESSED))
+      == (RIGHT_ALT_PRESSED | LEFT_CTRL_PRESSED))
+    mods &= ~ (RIGHT_ALT_PRESSED | LEFT_CTRL_PRESSED);
+
+  if (mods & (RIGHT_ALT_PRESSED | LEFT_ALT_PRESSED))
+    retval = ((NILP (Vw32_alt_is_meta)) ? alt_modifier : meta_modifier);
+
+  if (mods & (RIGHT_CTRL_PRESSED | LEFT_CTRL_PRESSED))
+    {
+      retval |= ctrl_modifier;
+      if ((mods & (RIGHT_CTRL_PRESSED | LEFT_CTRL_PRESSED))
+	  == (RIGHT_CTRL_PRESSED | LEFT_CTRL_PRESSED))
+	retval |= meta_modifier;
+    }
+
+  if (mods & LEFT_WIN_PRESSED)
+    retval |= w32_key_to_modifier (VK_LWIN);
+  if (mods & RIGHT_WIN_PRESSED)
+    retval |= w32_key_to_modifier (VK_RWIN);
+  if (mods & APPS_PRESSED)
+    retval |= w32_key_to_modifier (VK_APPS);
+  if (mods & SCROLLLOCK_ON)
+    retval |= w32_key_to_modifier (VK_SCROLL);
+
+  /* Just in case someone wanted the original behavior, make it
+     optional by setting w32-capslock-is-shiftlock to t.  */
+  if (NILP (Vw32_capslock_is_shiftlock)
+      /* Keys that should _not_ be affected by CapsLock.  */
+      && (    (key == VK_BACK)
+	   || (key == VK_TAB)
+	   || (key == VK_CLEAR)
+	   || (key == VK_RETURN)
+	   || (key == VK_ESCAPE)
+	   || ((key >= VK_SPACE) && (key <= VK_HELP))
+	   || ((key >= VK_NUMPAD0) && (key <= VK_F24))
+	   || ((key >= VK_NUMPAD_CLEAR) && (key <= VK_NUMPAD_DELETE))
+	 ))
+    {
+      /* Only consider shift state.  */
+      if ((mods & SHIFT_PRESSED) != 0)
+	retval |= shift_modifier;
+    }
+  else
+    {
+      /* Ignore CapsLock state if not enabled.  */
+      if (NILP (Vw32_enable_caps_lock))
+	mods &= ~CAPSLOCK_ON;
+      if ((mods & (SHIFT_PRESSED | CAPSLOCK_ON)) != 0)
+	retval |= shift_modifier;
+    }
+
+  return retval;
+}
+
+/* The return code indicates key code size. */
+int
+w32_kbd_patch_key (KEY_EVENT_RECORD *event)
+{
+  unsigned int key_code = event->wVirtualKeyCode;
+  unsigned int mods = event->dwControlKeyState;
+  BYTE keystate[256];
+  static BYTE ansi_code[4];
+  static int isdead = 0;
+
+  if (isdead == 2)
+    {
+      event->uChar.AsciiChar = ansi_code[2];
+      isdead = 0;
+      return 1;
+    }
+  if (event->uChar.AsciiChar != 0)
+    return 1;
+
+  memset (keystate, 0, sizeof (keystate));
+  keystate[key_code] = 0x80;
+  if (mods & SHIFT_PRESSED)
+    keystate[VK_SHIFT] = 0x80;
+  if (mods & CAPSLOCK_ON)
+    keystate[VK_CAPITAL] = 1;
+  /* If we recognize right-alt and left-ctrl as AltGr, set the key
+     states accordingly before invoking ToAscii.  */
+  if (!NILP (Vw32_recognize_altgr)
+      && (mods & LEFT_CTRL_PRESSED) && (mods & RIGHT_ALT_PRESSED))
+    {
+      keystate[VK_CONTROL] = 0x80;
+      keystate[VK_LCONTROL] = 0x80;
+      keystate[VK_MENU] = 0x80;
+      keystate[VK_RMENU] = 0x80;
+    }
+
+  /* On NT, call ToUnicode instead and then convert to the current
+     locale's default codepage.  */
+  if (os_subtype == OS_NT)
+    {
+      WCHAR buf[128];
+
+      isdead = ToUnicode (event->wVirtualKeyCode, event->wVirtualScanCode,
+			  keystate, buf, 128, 0);
+      if (isdead > 0)
+	{
+	  char cp[20];
+	  int cpId;
+
+	  event->uChar.UnicodeChar = buf[isdead - 1];
+
+	  GetLocaleInfo (GetThreadLocale (),
+			 LOCALE_IDEFAULTANSICODEPAGE, cp, 20);
+	  cpId = atoi (cp);
+	  isdead = WideCharToMultiByte (cpId, 0, buf, isdead,
+					ansi_code, 4, NULL, NULL);
+	}
+      else
+	isdead = 0;
+    }
+  else
+    {
+      isdead = ToAscii (event->wVirtualKeyCode, event->wVirtualScanCode,
+                        keystate, (LPWORD) ansi_code, 0);
+    }
+
+  if (isdead == 0)
+    return 0;
+  event->uChar.AsciiChar = ansi_code[0];
+  return isdead;
+}
+
+void
+w32_sys_ring_bell (struct frame *f)
+{
+  if (sound_type == 0xFFFFFFFF)
+    {
+      Beep (666, 100);
+    }
+  else if (sound_type == MB_EMACS_SILENT)
+    {
+      /* Do nothing.  */
+    }
+  else
+    MessageBeep (sound_type);
+}
+
+\f
 /***********************************************************************
 			    Initialization
  ***********************************************************************/
@@ -7105,10 +7465,10 @@
 
   defsubr (&Sfile_system_info);
   defsubr (&Sdefault_printer_name);
+  defsubr (&Sset_message_beep);
 
   check_window_system_func = check_w32;
 
-
   hourglass_timer = 0;
   hourglass_hwnd = NULL;
 
@@ -7123,7 +7483,9 @@
   staticpro (&last_show_tip_args);
 
   defsubr (&Sx_file_dialog);
+#ifdef WINDOWSNT
   defsubr (&Ssystem_move_file_to_trash);
+#endif
 }
 
 
@@ -7202,9 +7564,3 @@
     }
 }
 
-/* For convenience when debugging.  */
-int
-w32_last_error (void)
-{
-  return GetLastError ();
-}

=== modified file 'src/w32font.c'
--- src/w32font.c	2011-05-12 07:07:06 +0000
+++ src/w32font.c	2011-07-16 11:21:20 +0000
@@ -18,6 +18,7 @@
 
 #include <config.h>
 #include <windows.h>
+#include <stdio.h>
 #include <math.h>
 #include <ctype.h>
 #include <commdlg.h>
@@ -1309,6 +1310,9 @@
   return 1;
 }
 
+#if !WINDOWSNT
+#define _strlwr strlwr
+#endif
 
 static int
 check_face_name (LOGFONT *font, char *full_name)

=== modified file 'src/w32heap.c'
--- src/w32heap.c	2011-05-05 04:00:38 +0000
+++ src/w32heap.c	2011-07-16 10:27:01 +0000
@@ -29,60 +29,6 @@
 
 #define RVA_TO_PTR(rva) ((unsigned char *)((DWORD)(rva) + (DWORD)GetModuleHandle (NULL)))
 
-/* This gives us the page size and the size of the allocation unit on NT.  */
-SYSTEM_INFO sysinfo_cache;
-
-/* This gives us version, build, and platform identification.  */
-OSVERSIONINFO osinfo_cache;
-
-unsigned long syspage_mask = 0;
-
-/* The major and minor versions of NT.  */
-int w32_major_version;
-int w32_minor_version;
-int w32_build_number;
-
-/* Distinguish between Windows NT and Windows 95.  */
-int os_subtype;
-
-/* Cache information describing the NT system for later use.  */
-void
-cache_system_info (void)
-{
-  union
-    {
-      struct info
-	{
-	  char  major;
-	  char  minor;
-	  short platform;
-	} info;
-      DWORD data;
-    } version;
-
-  /* Cache the version of the operating system.  */
-  version.data = GetVersion ();
-  w32_major_version = version.info.major;
-  w32_minor_version = version.info.minor;
-
-  if (version.info.platform & 0x8000)
-    os_subtype = OS_WIN95;
-  else
-    os_subtype = OS_NT;
-
-  /* Cache page size, allocation unit, processor type, etc.  */
-  GetSystemInfo (&sysinfo_cache);
-  syspage_mask = sysinfo_cache.dwPageSize - 1;
-
-  /* Cache os info.  */
-  osinfo_cache.dwOSVersionInfoSize = sizeof (OSVERSIONINFO);
-  GetVersionEx (&osinfo_cache);
-
-  w32_build_number = osinfo_cache.dwBuildNumber;
-  if (os_subtype == OS_WIN95)
-    w32_build_number &= 0xffff;
-}
-
 /* Emulate getpagesize.  */
 int
 getpagesize (void)

=== modified file 'src/w32heap.h'
--- src/w32heap.h	2011-01-25 04:08:28 +0000
+++ src/w32heap.h	2011-07-16 10:33:53 +0000
@@ -24,6 +24,23 @@
 
 #include <windows.h>
 
+extern int    	      w32_major_version;
+extern int    	      w32_minor_version;
+extern int    	      w32_build_number;
+extern BOOL   	      using_dynamic_heap;
+
+enum {
+  OS_WIN95 = 1,
+  OS_NT
+};
+
+extern int os_subtype;
+
+#define get_w32_major_version()  	w32_major_version
+#define get_w32_minor_version()  	w32_minor_version
+
+#if WINDOWSNT
+
 #define ROUND_UP(p, align)   (((DWORD)(p) + (align)-1) & ~((align)-1))
 #define ROUND_DOWN(p, align) ((DWORD)(p) & ~((align)-1))
 
@@ -37,25 +54,12 @@
 #define get_page_size()			sysinfo_cache.dwPageSize
 #define get_allocation_unit()		sysinfo_cache.dwAllocationGranularity
 #define get_processor_type()		sysinfo_cache.dwProcessorType
-#define get_w32_major_version()  	w32_major_version
-#define get_w32_minor_version()  	w32_minor_version
 
 extern unsigned char *get_data_start (void);
 extern unsigned char *get_data_end (void);
 extern unsigned long  reserved_heap_size;
 extern SYSTEM_INFO    sysinfo_cache;
 extern OSVERSIONINFO  osinfo_cache;
-extern BOOL   	      using_dynamic_heap;
-extern int    	      w32_major_version;
-extern int    	      w32_minor_version;
-extern int    	      w32_build_number;
-
-enum {
-  OS_WIN95 = 1,
-  OS_NT
-};
-
-extern int os_subtype;
 
 /* Emulation of Unix sbrk().  */
 extern void *sbrk (unsigned long size);
@@ -91,5 +95,7 @@
    relative virtual address. */
 IMAGE_SECTION_HEADER * rva_to_section (DWORD rva, IMAGE_NT_HEADERS * nt_header);
 
+#endif /* WINDOWSNT */
+
 #endif /* NTHEAP_H_ */
 

=== modified file 'src/w32inevt.c'
--- src/w32inevt.c	2011-05-14 19:06:08 +0000
+++ src/w32inevt.c	2011-07-16 11:24:02 +0000
@@ -97,169 +97,6 @@
   return SELECTED_FRAME ();
 }
 
-/* Translate console modifiers to emacs modifiers.
-   German keyboard support (Kai Morgan Zeise 2/18/95).  */
-int
-w32_kbd_mods_to_emacs (DWORD mods, WORD key)
-{
-  int retval = 0;
-
-  /* If we recognize right-alt and left-ctrl as AltGr, and it has been
-     pressed, first remove those modifiers.  */
-  if (!NILP (Vw32_recognize_altgr)
-      && (mods & (RIGHT_ALT_PRESSED | LEFT_CTRL_PRESSED))
-      == (RIGHT_ALT_PRESSED | LEFT_CTRL_PRESSED))
-    mods &= ~ (RIGHT_ALT_PRESSED | LEFT_CTRL_PRESSED);
-
-  if (mods & (RIGHT_ALT_PRESSED | LEFT_ALT_PRESSED))
-    retval = ((NILP (Vw32_alt_is_meta)) ? alt_modifier : meta_modifier);
-
-  if (mods & (RIGHT_CTRL_PRESSED | LEFT_CTRL_PRESSED))
-    {
-      retval |= ctrl_modifier;
-      if ((mods & (RIGHT_CTRL_PRESSED | LEFT_CTRL_PRESSED))
-	  == (RIGHT_CTRL_PRESSED | LEFT_CTRL_PRESSED))
-	retval |= meta_modifier;
-    }
-
-  if (mods & LEFT_WIN_PRESSED)
-    retval |= w32_key_to_modifier (VK_LWIN);
-  if (mods & RIGHT_WIN_PRESSED)
-    retval |= w32_key_to_modifier (VK_RWIN);
-  if (mods & APPS_PRESSED)
-    retval |= w32_key_to_modifier (VK_APPS);
-  if (mods & SCROLLLOCK_ON)
-    retval |= w32_key_to_modifier (VK_SCROLL);
-
-  /* Just in case someone wanted the original behavior, make it
-     optional by setting w32-capslock-is-shiftlock to t.  */
-  if (NILP (Vw32_capslock_is_shiftlock)
-      /* Keys that should _not_ be affected by CapsLock.  */
-      && (    (key == VK_BACK)
-	   || (key == VK_TAB)
-	   || (key == VK_CLEAR)
-	   || (key == VK_RETURN)
-	   || (key == VK_ESCAPE)
-	   || ((key >= VK_SPACE) && (key <= VK_HELP))
-	   || ((key >= VK_NUMPAD0) && (key <= VK_F24))
-	   || ((key >= VK_NUMPAD_CLEAR) && (key <= VK_NUMPAD_DELETE))
-	 ))
-    {
-      /* Only consider shift state.  */
-      if ((mods & SHIFT_PRESSED) != 0)
-	retval |= shift_modifier;
-    }
-  else
-    {
-      /* Ignore CapsLock state if not enabled.  */
-      if (NILP (Vw32_enable_caps_lock))
-	mods &= ~CAPSLOCK_ON;
-      if ((mods & (SHIFT_PRESSED | CAPSLOCK_ON)) != 0)
-	retval |= shift_modifier;
-    }
-
-  return retval;
-}
-
-#if 0
-/* Return nonzero if the virtual key is a dead key.  */
-static int
-is_dead_key (int wparam)
-{
-  unsigned int code = MapVirtualKey (wparam, 2);
-
-  /* Windows 95 returns 0x8000, NT returns 0x80000000.  */
-  return (code & 0x80008000) ? 1 : 0;
-}
-#endif
-
-/* The return code indicates key code size. */
-int
-w32_kbd_patch_key (KEY_EVENT_RECORD *event)
-{
-  unsigned int key_code = event->wVirtualKeyCode;
-  unsigned int mods = event->dwControlKeyState;
-  BYTE keystate[256];
-  static BYTE ansi_code[4];
-  static int isdead = 0;
-
-  if (isdead == 2)
-    {
-      event->uChar.AsciiChar = ansi_code[2];
-      isdead = 0;
-      return 1;
-    }
-  if (event->uChar.AsciiChar != 0)
-    return 1;
-
-  memset (keystate, 0, sizeof (keystate));
-  keystate[key_code] = 0x80;
-  if (mods & SHIFT_PRESSED)
-    keystate[VK_SHIFT] = 0x80;
-  if (mods & CAPSLOCK_ON)
-    keystate[VK_CAPITAL] = 1;
-  /* If we recognize right-alt and left-ctrl as AltGr, set the key
-     states accordingly before invoking ToAscii.  */
-  if (!NILP (Vw32_recognize_altgr)
-      && (mods & LEFT_CTRL_PRESSED) && (mods & RIGHT_ALT_PRESSED))
-    {
-      keystate[VK_CONTROL] = 0x80;
-      keystate[VK_LCONTROL] = 0x80;
-      keystate[VK_MENU] = 0x80;
-      keystate[VK_RMENU] = 0x80;
-    }
-
-#if 0
-  /* Because of an OS bug, ToAscii corrupts the stack when called to
-     convert a dead key in console mode on NT4.  Unfortunately, trying
-     to check for dead keys using MapVirtualKey doesn't work either -
-     these functions apparently use internal information about keyboard
-     layout which doesn't get properly updated in console programs when
-     changing layout (though apparently it gets partly updated,
-     otherwise ToAscii wouldn't crash).  */
-  if (is_dead_key (event->wVirtualKeyCode))
-    return 0;
-#endif
-
-  /* On NT, call ToUnicode instead and then convert to the current
-     locale's default codepage.  */
-  if (os_subtype == OS_NT)
-    {
-      WCHAR buf[128];
-
-      isdead = ToUnicode (event->wVirtualKeyCode, event->wVirtualScanCode,
-			  keystate, buf, 128, 0);
-      if (isdead > 0)
-	{
-	  char cp[20];
-	  int cpId;
-
-	  event->uChar.UnicodeChar = buf[isdead - 1];
-
-	  GetLocaleInfo (GetThreadLocale (),
-			 LOCALE_IDEFAULTANSICODEPAGE, cp, 20);
-	  cpId = atoi (cp);
-	  isdead = WideCharToMultiByte (cpId, 0, buf, isdead,
-					ansi_code, 4, NULL, NULL);
-	}
-      else
-	isdead = 0;
-    }
-  else
-    {
-      isdead = ToAscii (event->wVirtualKeyCode, event->wVirtualScanCode,
-                        keystate, (LPWORD) ansi_code, 0);
-    }
-
-  if (isdead == 0)
-    return 0;
-  event->uChar.AsciiChar = ansi_code[0];
-  return isdead;
-}
-
-
-static int faked_key = 0;
-
 /* return code -1 means that event_queue_ptr won't be incremented.
    In other word, this event makes two key codes.   (by himi)       */
 static int
@@ -510,32 +347,6 @@
   return 1;
 }
 
-int
-w32_console_toggle_lock_key (int vk_code, Lisp_Object new_state)
-{
-  int cur_state = (GetKeyState (vk_code) & 1);
-
-  if (NILP (new_state)
-      || (NUMBERP (new_state)
-	  && ((XUINT (new_state)) & 1) != cur_state))
-    {
-      faked_key = vk_code;
-
-      keybd_event ((BYTE) vk_code,
-		   (BYTE) MapVirtualKey (vk_code, 0),
-		   KEYEVENTF_EXTENDEDKEY | KEYEVENTF_KEYUP, 0);
-      keybd_event ((BYTE) vk_code,
-		   (BYTE) MapVirtualKey (vk_code, 0),
-		   KEYEVENTF_EXTENDEDKEY | 0, 0);
-      keybd_event ((BYTE) vk_code,
-		   (BYTE) MapVirtualKey (vk_code, 0),
-		   KEYEVENTF_EXTENDEDKEY | KEYEVENTF_KEYUP, 0);
-      cur_state = !cur_state;
-    }
-
-  return cur_state;
-}
-
 /* Mouse position hook.  */
 void
 w32_console_mouse_position (FRAME_PTR *f,

=== modified file 'src/w32menu.c'
--- src/w32menu.c	2011-06-24 21:25:22 +0000
+++ src/w32menu.c	2011-07-16 10:09:02 +0000
@@ -21,7 +21,6 @@
 
 #include <signal.h>
 #include <stdio.h>
-#include <mbstring.h>
 #include <setjmp.h>
 
 #include "lisp.h"
@@ -40,6 +39,12 @@
    if this is not done before the other system files.  */
 #include "w32term.h"
 
+#if CYGWIN
+#include "cygw32.h"
+#else
+#include <mbstring.h>
+#endif
+
 /* Load sys/types.h if not already loaded.
    In some systems loading it twice is suicidal.  */
 #ifndef makedev
@@ -96,6 +101,11 @@
 static int fill_in_menu (HMENU, widget_value *);
 
 void w32_free_menu_strings (HWND);
+
+#if CYGWIN
+
+#endif
+
 \f
 
 /* This is set nonzero after the user activates the menu bar, and set

=== modified file 'src/w32proc.c'
--- src/w32proc.c	2011-06-24 21:25:22 +0000
+++ src/w32proc.c	2011-07-16 05:58:37 +0000
@@ -68,20 +68,6 @@
 
 Lisp_Object Qhigh, Qlow;
 
-#ifdef EMACSDEBUG
-void
-_DebPrint (const char *fmt, ...)
-{
-  char buf[1024];
-  va_list args;
-
-  va_start (args, fmt);
-  vsprintf (buf, fmt, args);
-  va_end (args);
-  OutputDebugString (buf);
-}
-#endif
-
 typedef void (_CALLBACK_ *signal_handler) (int);
 
 /* Signal handlers...SIG_DFL == 0 so this is initialized correctly.  */

=== modified file 'src/w32select.c'
--- src/w32select.c	2011-06-24 21:25:22 +0000
+++ src/w32select.c	2011-07-17 20:32:49 +0000
@@ -21,58 +21,20 @@
 
 
 /*
- * Notes on usage of selection-coding-system and
- * next-selection-coding-system on MS Windows:
- *
- * The selection coding system variables apply only to the version of
- * the clipboard data that is closest in type, i.e. when a 16-bit
- * Unicode coding system is given, they apply to he Unicode clipboard
- * (CF_UNICODETEXT), when a well-known console codepage is given, they
- * apply to the console version of the clipboard data (CF_OEMTEXT),
- * else they apply to the normal 8-bit text clipboard (CF_TEXT).
- *
- * When pasting (getting data from the OS), the clipboard format that
- * matches the {next-}selection-coding-system is retrieved.  If
- * Unicode is requested, but not available, 8-bit text (CF_TEXT) is
- * used.  In all other cases the OS will transparently convert
- * formats, so no other fallback is needed.
+ * Notes:
  *
  * When copying or cutting (sending data to the OS), the data is
  * announced and stored internally, but only actually rendered on
- * request.  The requester determines the format provided.  The
- * {next-}selection-coding-system is only used, when its corresponding
- * clipboard type matches the type requested.
- *
- * Scenarios to use the facilities for customizing the selection
- * coding system are:
- *
- *   ;; Generally use KOI8-R instead of the russian MS codepage for
- *   ;; the 8-bit clipboard.
- *   (set-selection-coding-system 'koi8-r-dos)
- *
- * Or
- *
- *   ;; Create a special clipboard copy function that uses codepage
- *   ;; 1253 (Greek) to copy Greek text to a specific non-Unicode
- *   ;; application.
- *   (defun greek-copy (beg end)
- *     (interactive "r")
- *     (set-next-selection-coding-system 'cp1253-dos)
- *     (copy-region-as-kill beg end))
- *   (global-set-key "\C-c\C-c" 'greek-copy)
- */
-
-/*
- * Ideas for further directions:
- *
- * The encoding and decoding routines could be moved to Lisp code
- * similar to how xselect.c does it (using well-known routine names
- * for the delayed rendering).  If the definition of which clipboard
- * types should be supported is also moved to Lisp, functionality
- * could be expanded to CF_HTML, CF_RTF and maybe other types.
+ * request.  The requester determines the format provided.
+ *
+ * We marshal clipboard writes across to the clipboard thread so that
+ * we can use SetClipboardData in the context of the owning WindowProc
+ * as the documentation suggests.  Clipboard reads can be done in any
+ * thread.
  */
 
 #include <config.h>
+#include <stdio.h>
 #include <setjmp.h>
 #include "lisp.h"
 #include "w32term.h"	/* for all of the w32 includes */
@@ -82,57 +44,53 @@
 #include "coding.h"
 #include "composite.h"
 
-
-static HGLOBAL convert_to_handle_as_ascii (void);
-static HGLOBAL convert_to_handle_as_coded (Lisp_Object coding_system);
-static Lisp_Object render (Lisp_Object oformat);
-static Lisp_Object render_locale (void);
-static Lisp_Object render_all (Lisp_Object ignore);
-static void run_protected (Lisp_Object (*code) (Lisp_Object), Lisp_Object arg);
-static Lisp_Object lisp_error_handler (Lisp_Object error);
+#ifdef CYGWIN
+#include "cygw32.h"
+#endif
+
+/* No conflict because with w32term messages because messages are
+ * disambiguated by recipient.  */
+
+/* Sent to owner window to have it claim ownership.  */
+#define WM_EMACS_CLAIM_CLIPBOARD (WM_USER + 0)
+
+/* Sent to clipboard window with wParam equal to memory handle and
+   lParam equal to the rendered data type.  Use wParam == 0 to
+   terminate.  */
+#define WM_EMACS_CLIPBOARD_DATA  (WM_USER + 1)
+
 static LRESULT CALLBACK owner_callback (HWND win, UINT msg,
 					WPARAM wp, LPARAM lp);
 static HWND create_owner (void);
 
-static void setup_config (void);
-static BOOL WINAPI enum_locale_callback (/*const*/ char* loc_string);
-static UINT cp_from_locale (LCID lcid, UINT format);
-static Lisp_Object coding_from_cp (UINT codepage);
-static Lisp_Object validate_coding_system (Lisp_Object coding_system);
-static void setup_windows_coding_system (Lisp_Object coding_system,
-					 struct coding_system * coding);
-
-
 /* A remnant from X11: Symbol for the CLIPBORD selection type.  Other
    selections are not used on Windows, so we don't need symbols for
    PRIMARY and SECONDARY.  */
 Lisp_Object QCLIPBOARD;
 
+/* Function, defined in Lisp, that renders the clipboard in a given
+   format.  */
+Lisp_Object Qw32_clipboard_render;
+Lisp_Object Qw32_lost_selection_functions;
+
 /* Internal pseudo-constants, initialized in globals_of_w32select()
    based on current system parameters. */
-static LCID DEFAULT_LCID;
-static UINT ANSICP, OEMCP;
-static Lisp_Object QUNICODE, QANSICP, QOEMCP;
+static Lisp_Object QUNICODE;
 
 /* A hidden window just for the clipboard management. */
 static HWND clipboard_owner;
+
+/* The thread managing the clipboard_owner window.  (Windows have
+   thread affinity, and the main thread doesn't pump messages until we
+   tell it to do so.) */
+static HANDLE clipboard_thread;
+
 /* A flag to tell WM_DESTROYCLIPBOARD who is to blame this time (just
    checking GetClipboardOwner() doesn't work, sadly). */
 static int modifying_clipboard = 0;
 
-/* Configured transfer parameters, based on the last inspection of
-   selection-coding-system.  */
-static Lisp_Object cfg_coding_system;
-static UINT cfg_codepage;
-static LCID cfg_lcid;
-static UINT cfg_clipboard_type;
-
-/* The current state for delayed rendering. */
-static Lisp_Object current_text;
-static Lisp_Object current_coding_system;
-static int current_requires_encoding, current_num_nls;
-static UINT current_clipboard_type;
-static LCID current_lcid;
+#undef TRACE
+#define TRACE 1
 
 #if TRACE
 #define ONTRACE(stmt) stmt
@@ -140,303 +98,183 @@
 #define ONTRACE(stmt) /*stmt*/
 #endif
 
-
-/* This function assumes that there is no multibyte character in
-   current_text, so we can short-cut encoding.  */
-
-static HGLOBAL
-convert_to_handle_as_ascii (void)
-{
-  HGLOBAL htext = NULL;
-  int nbytes;
-  int truelen;
-  unsigned char *src;
-  unsigned char *dst;
-
-  ONTRACE (fprintf (stderr, "convert_to_handle_as_ascii\n"));
-
-  nbytes = SBYTES (current_text) + 1;
-  src = SDATA (current_text);
-
-  /* We need to add to the size the number of LF chars where we have
-     to insert CR chars (the standard CF_TEXT clipboard format uses
-     CRLF line endings, while Emacs uses just LF internally).  */
-
-  truelen = nbytes + current_num_nls;
-
-  if ((htext = GlobalAlloc (GMEM_MOVEABLE | GMEM_DDESHARE, truelen)) == NULL)
-    return NULL;
-
-  if ((dst = (unsigned char *) GlobalLock (htext)) == NULL)
-    {
-      GlobalFree (htext);
-      return NULL;
-    }
-
-  /* convert to CRLF line endings expected by clipboard */
-  while (1)
-    {
-      unsigned char *next;
-      /* copy next line or remaining bytes including '\0' */
-      next = _memccpy (dst, src, '\n', nbytes);
-      if (next)
-	{
-	  /* copied one line ending with '\n' */
-	  int copied = next - dst;
-	  nbytes -= copied;
-	  src += copied;
-	  /* insert '\r' before '\n' */
-	  next[-1] = '\r';
-	  next[0] = '\n';
-	  dst = next + 1;
-	}
-      else
-	/* copied remaining partial line -> now finished */
-	break;
-    }
-
-  GlobalUnlock (htext);
-
-  return htext;
-}
-
-/* This function assumes that there are multibyte or NUL characters in
-   current_text, or that we need to construct Unicode.  It runs the
-   text through the encoding machinery.  */
-
-static HGLOBAL
-convert_to_handle_as_coded (Lisp_Object coding_system)
-{
-  HGLOBAL htext;
-  unsigned char *dst = NULL;
-  struct coding_system coding;
-
-  ONTRACE (fprintf (stderr, "convert_to_handle_as_coded: %s\n",
-		    SDATA (SYMBOL_NAME (coding_system))));
-
-  setup_windows_coding_system (coding_system, &coding);
-  coding.dst_bytes = SBYTES (current_text) * 2;
-  coding.destination = (unsigned char *) xmalloc (coding.dst_bytes);
-  encode_coding_object (&coding, current_text, 0, 0,
-			SCHARS (current_text), SBYTES (current_text), Qnil);
-
-  htext = GlobalAlloc (GMEM_MOVEABLE | GMEM_DDESHARE, coding.produced +2);
-
-  if (htext != NULL)
-    dst = (unsigned char *) GlobalLock (htext);
-
-  if (dst != NULL)
-    {
-      memcpy (dst, coding.destination, coding.produced);
-      /* Add the string terminator.  Add two NULs in case we are
-	 producing Unicode here.  */
-      dst[coding.produced] = dst[coding.produced+1] = '\0';
-
-      GlobalUnlock (htext);
-    }
-
-  xfree (coding.destination);
-
-  return htext;
-}
-
-static Lisp_Object
-render (Lisp_Object oformat)
-{
-  HGLOBAL htext = NULL;
-  UINT format = XFASTINT (oformat);
-
-  ONTRACE (fprintf (stderr, "render\n"));
-
-  if (NILP (current_text))
-    return Qnil;
-
-  if (current_requires_encoding || format == CF_UNICODETEXT)
-    {
-      if (format == current_clipboard_type)
-	htext = convert_to_handle_as_coded (current_coding_system);
-      else
-	switch (format)
-	  {
-	  case CF_UNICODETEXT:
-	    htext = convert_to_handle_as_coded (QUNICODE);
-	    break;
-	  case CF_TEXT:
-	  case CF_OEMTEXT:
-	    {
-	      Lisp_Object cs;
-	      cs = coding_from_cp (cp_from_locale (current_lcid, format));
-	      htext = convert_to_handle_as_coded (cs);
-	      break;
-	    }
-	  }
-    }
-  else
-    htext = convert_to_handle_as_ascii ();
-
-  ONTRACE (fprintf (stderr, "render: htext = 0x%08X\n", (unsigned) htext));
-
-  if (htext == NULL)
-    return Qnil;
-
-  if (SetClipboardData (format, htext) == NULL)
-    {
-      GlobalFree (htext);
-      return Qnil;
-    }
-
-  return Qt;
-}
-
-static Lisp_Object
-render_locale (void)
-{
-  HANDLE hlocale = NULL;
-  LCID * lcid_ptr;
-
-  ONTRACE (fprintf (stderr, "render_locale\n"));
-
-  if (current_lcid == LOCALE_NEUTRAL || current_lcid == DEFAULT_LCID)
-    return Qt;
-
-  hlocale = GlobalAlloc (GMEM_MOVEABLE | GMEM_DDESHARE, sizeof (current_lcid));
-  if (hlocale == NULL)
-    return Qnil;
-
-  if ((lcid_ptr = (LCID *) GlobalLock (hlocale)) == NULL)
-    {
-      GlobalFree (hlocale);
-      return Qnil;
-    }
-
-  *lcid_ptr = current_lcid;
-  GlobalUnlock (hlocale);
-
-  if (SetClipboardData (CF_LOCALE, hlocale) == NULL)
-    {
-      GlobalFree (hlocale);
-      return Qnil;
-    }
-
-  return Qt;
-}
-
-/* At the end of the program, we want to ensure that our clipboard
-   data survives us.  This code will do that.  */
-
-static Lisp_Object
-render_all (Lisp_Object ignore)
-{
-  ONTRACE (fprintf (stderr, "render_all\n"));
-
-  /* According to the docs we should not call OpenClipboard() here,
-     but testing on W2K and working code in other projects shows that
-     it is actually necessary.  */
-
-  OpenClipboard (NULL);
-
-  /* There is no usefull means to report errors here, there are none
-     expected anyway, and even if there were errors, they wouldn't do
-     any harm.  So we just go ahead and do what has to be done without
-     bothering with error handling.  */
+static void
+claim_clipboard (void)
+{
+  Lisp_Object format;
+
+  if (!OpenClipboard (clipboard_owner))
+    return;
 
   ++modifying_clipboard;
   EmptyClipboard ();
   --modifying_clipboard;
 
-  /* For text formats that we don't render here, the OS can use its
-     own translation rules instead, so we don't really need to offer
-     everything.  To minimize memory consumption we cover three
-     possible situations based on our primary format as detected from
-     selection-coding-system (see setup_config()):
-
-     - Post CF_TEXT only.  Let the OS convert to CF_OEMTEXT and the OS
-       (on NT) or the application (on 9x/Me) convert to
-       CF_UNICODETEXT.
-
-     - Post CF_OEMTEXT only.  Similar automatic conversions happen as
-       for CF_TEXT.
-
-     - Post CF_UNICODETEXT + CF_TEXT.  9x itself ignores
-       CF_UNICODETEXT, even though some applications can still handle
-       it.
-
-       Note 1: We render the less capable CF_TEXT *before* the more
-       capable CF_UNICODETEXT, to prevent clobbering through automatic
-       conversions, just in case.
-
-       Note 2: We could check os_subtype here and only render the
-       additional CF_TEXT on 9x/Me.  But OTOH with
-       current_clipboard_type == CF_UNICODETEXT we don't involve the
-       automatic conversions anywhere else, so to get consistent
-       results, we probably don't want to rely on it here either.  */
-
-  render_locale ();
-
-  if (current_clipboard_type == CF_UNICODETEXT)
-    render (make_number (CF_TEXT));
-  render (make_number (current_clipboard_type));
-
-  CloseClipboard ();
-
-  return Qnil;
-}
-
-static void
-run_protected (Lisp_Object (*code) (Lisp_Object), Lisp_Object arg)
-{
-  /* FIXME: This works but it doesn't feel right.  Too much fiddling
-     with global variables and calling strange looking functions.  Is
-     this really the right way to run Lisp callbacks?  */
-
-  extern int waiting_for_input; /* from keyboard.c */
-  int owfi;
-
-  BLOCK_INPUT;
-
-  /* Fsignal calls abort() if it sees that waiting_for_input is
-     set.  */
-  owfi = waiting_for_input;
-  waiting_for_input = 0;
-
-  internal_condition_case_1 (code, arg, Qt, lisp_error_handler);
-
-  waiting_for_input = owfi;
-
-  UNBLOCK_INPUT;
-}
-
-static Lisp_Object
-lisp_error_handler (Lisp_Object error)
-{
-  Vsignaling_function = Qnil;
-  cmd_error_internal (error, "Error in delayed clipboard rendering: ");
-  Vinhibit_quit = Qt;
-  return Qt;
-}
-
+  for (format = Vw32_clipboard_advertised_types;
+       CONSP (format);
+       format = XCDR (format))
+    {
+      if (INTEGERP (XCAR (format)))
+        SetClipboardData (XFASTINT (XCAR (format)), NULL);
+    }
+  
+  CloseClipboard ();
+}
+
+static Lisp_Object
+clipboard_render_cb_unwind (Lisp_Object arg)
+{
+  PostMessage (clipboard_owner, WM_EMACS_CLIPBOARD_DATA, 0, 0);
+  return Qnil;
+}
+
+static Lisp_Object
+global_free_unwind (Lisp_Object arg)
+{
+  HGLOBAL* mem = XSAVE_VALUE (arg)->pointer;
+  if (mem != NULL)
+    GlobalFree (*mem);
+  return Qnil;
+}
+
+static Lisp_Object
+close_clipboard_unwind (Lisp_Object arg)
+{
+  CloseClipboard ();
+  return Qnil;
+}
+
+/* Send a rendered string RENDERED to the clipboard thread, which must
+   be waiting in wait_for_clipboard_render.  */
+static void
+send_clipboard_render (UINT format, void* mem, size_t bytes)
+{
+  int count;
+  HGLOBAL htext;
+  void* buf;
+
+  count = SPECPDL_INDEX ();
+  record_unwind_protect (global_free_unwind,
+                         make_save_value (&htext, 0));
+
+  htext = GlobalAlloc (GMEM_MOVEABLE | GMEM_DDESHARE, bytes);
+  if (!htext)
+    error ("GlobalAlloc: %s", w32_strerror (GetLastError ()));
+
+  buf = GlobalLock (htext);
+  if (!buf)
+    error ("GlobalLock: %s", w32_strerror (GetLastError ()));
+
+  memcpy (buf, mem, bytes);
+  if (GlobalUnlock (htext) && GetLastError () != NO_ERROR)
+    error ("GlobalUnlock: %s", w32_strerror (GetLastError ()));
+
+  /* Use PostMessage instead of SendMessage so we return faster ---
+     we're on the UI thread, after all.  Transfer ownership of htext
+     to the clipboard thread.  */
+
+  if (!PostMessage (clipboard_owner, WM_EMACS_CLIPBOARD_DATA,
+                    (WPARAM)htext, (LPARAM)format))
+    error ("SendMessage: %s", w32_strerror (GetLastError ()));
+
+  htext = NULL;
+
+  unbind_to (count, Qnil);
+}
+
+/* Run in main thread.  Try to render in the given format and if we
+   are successful, send the result back to the clipboard thread via
+   WM_EMACS_CLIPBOARD_DATA.  */
+static void
+clipboard_render_cb (struct atimer* at)
+{
+  void* arg = at->client_data;
+  UINT format = (UINT)arg;
+  Lisp_Object ret;
+  int count = SPECPDL_INDEX ();
+
+  record_unwind_protect (clipboard_render_cb_unwind, Qnil);
+  ret = call1 (Qw32_clipboard_render, make_number ((unsigned)arg));
+
+  if (ret != Qnil) {
+    CHECK_STRING (ret);
+    send_clipboard_render (format, SDATA (ret), SBYTES (ret) + 1);
+  }
+
+  unbind_to (count, Qnil);
+}
+
+/* Process rendered data from the currently scheduled render*_cb call
+   and block until it tells us it's done.  */
+static void
+wait_for_clipboard_render ()
+{
+  MSG msg;
+  while (GetMessage (&msg, clipboard_owner,
+                     WM_EMACS_CLIPBOARD_DATA,
+                     WM_EMACS_CLIPBOARD_DATA))
+    {
+      if (msg.message != WM_EMACS_CLIPBOARD_DATA) {
+        eassert (0);
+        DispatchMessage (&msg);
+        continue;
+      }
+
+      t ("Got WM_EMACS_CLIPBOARD_DATA lParam:%x wParam:%x",
+         msg.lParam, msg.wParam);
+
+      if (msg.wParam) {
+        SetClipboardData ((UINT)msg.lParam, (HGLOBAL)msg.wParam);
+        GlobalFree ((HGLOBAL)msg.wParam);
+      } else {
+        break;
+      }
+    }
+}
+
+static void
+clipboard_lost_cb (struct atimer* ignored)
+{
+  Lisp_Object args[2];
+  args[0] = Qw32_lost_selection_functions;
+  args[1] = QCLIPBOARD;
+  run_hook_with_args (2, args, Ffuncall);
+}
 
 static LRESULT CALLBACK
 owner_callback (HWND win, UINT msg, WPARAM wp, LPARAM lp)
 {
+  t ("owner_callback");
+
   switch (msg)
     {
+    case WM_EMACS_CLIPBOARD_DATA:
+      ONTRACE (fprintf (stderr, "WM_EMACS_CLIPBOARD_DATA\n"));
+      /* Ignore out-of-context data messages. */
+      return 0;
+
+    case WM_EMACS_CLAIM_CLIPBOARD:
+      ONTRACE (fprintf (stderr, "WM_EMACS_CLAIM_CLIPBOARD\n"));
+      claim_clipboard ();
+      return 0;
+
     case WM_RENDERFORMAT:
       ONTRACE (fprintf (stderr, "WM_RENDERFORMAT\n"));
-      run_protected (render, make_number (wp));
+      call_on_main_thread (clipboard_render_cb, (void*)wp);
+      wait_for_clipboard_render ();
       return 0;
 
     case WM_RENDERALLFORMATS:
       ONTRACE (fprintf (stderr, "WM_RENDERALLFORMATS\n"));
-      run_protected (render_all, Qnil);
+      call_on_main_thread (clipboard_render_cb, (void*)-1);
+      wait_for_clipboard_render ();
       return 0;
 
     case WM_DESTROYCLIPBOARD:
       if (!modifying_clipboard)
 	{
 	  ONTRACE (fprintf (stderr, "WM_DESTROYCLIPBOARD (other)\n"));
-	  current_text = Qnil;
-	  current_coding_system = Qnil;
+          call_on_main_thread (clipboard_lost_cb, NULL);
 	}
       else
 	{
@@ -478,536 +316,58 @@
     DestroyWindow (clipboard_owner);
 }
 
-static void
-setup_config (void)
-{
-  const char *coding_name;
-  const char *cp;
-  char *end;
-  int slen;
-  Lisp_Object coding_system;
-  Lisp_Object dos_coding_system;
-
-  CHECK_SYMBOL (Vselection_coding_system);
-
-  coding_system = NILP (Vnext_selection_coding_system) ?
-    Vselection_coding_system : Vnext_selection_coding_system;
-
-  dos_coding_system = validate_coding_system (coding_system);
-  if (NILP (dos_coding_system))
-    Fsignal (Qerror,
-	     list2 (build_string ("Coding system is invalid or doesn't have "
-				  "an eol variant for dos line ends"),
-		    coding_system));
-
-  /* Check if we have it cached */
-  if (!NILP (cfg_coding_system)
-      && EQ (cfg_coding_system, dos_coding_system))
-    return;
-  cfg_coding_system = dos_coding_system;
-
-  /* Set some sensible fallbacks */
-  cfg_codepage = ANSICP;
-  cfg_lcid = LOCALE_NEUTRAL;
-  cfg_clipboard_type = CF_TEXT;
-
-  /* Interpret the coding system symbol name */
-  coding_name = SDATA (SYMBOL_NAME (cfg_coding_system));
-
-  /* "(.*-)?utf-16.*" -> CF_UNICODETEXT */
-  cp = strstr (coding_name, "utf-16");
-  if (cp != NULL && (cp == coding_name || cp[-1] == '-'))
-    {
-      cfg_clipboard_type = CF_UNICODETEXT;
-      return;
-    }
-
-  /* "cp[0-9]+.*" or "windows-[0-9]+.*" -> CF_TEXT or CF_OEMTEXT */
-  slen = strlen (coding_name);
-  if (slen >= 4 && coding_name[0] == 'c' && coding_name[1] == 'p')
-    cp = coding_name + 2;
-  else if (slen >= 10 && memcmp (coding_name, "windows-", 8) == 0)
-    cp = coding_name + 8;
-  else
-    return;
-
-  end = (char*)cp;
-  cfg_codepage = strtol (cp, &end, 10);
-
-  /* Error return from strtol() or number of digits < 2 -> Restore the
-     default and drop it. */
-  if (cfg_codepage == 0 || (end-cp) < 2 )
-    {
-      cfg_codepage = ANSICP;
-      return;
-    }
-
-  /* Is it the currently active system default? */
-  if (cfg_codepage == ANSICP)
-    {
-      /* cfg_clipboard_type = CF_TEXT; */
-      return;
-    }
-  if (cfg_codepage == OEMCP)
-    {
-      cfg_clipboard_type = CF_OEMTEXT;
-      return;
-    }
-
-  /* Else determine a suitable locale the hard way. */
-  EnumSystemLocales (enum_locale_callback, LCID_INSTALLED);
-}
-
-static BOOL WINAPI
-enum_locale_callback (/*const*/ char* loc_string)
-{
-  LCID lcid;
-  UINT codepage;
-
-  lcid = strtoul (loc_string, NULL, 16);
-
-  /* Is the wanted codepage the "ANSI" codepage for this locale? */
-  codepage = cp_from_locale (lcid, CF_TEXT);
-  if (codepage == cfg_codepage)
-    {
-      cfg_lcid = lcid;
-      cfg_clipboard_type = CF_TEXT;
-      return FALSE; /* Stop enumeration */
-    }
-
-  /* Is the wanted codepage the OEM codepage for this locale? */
-  codepage = cp_from_locale (lcid, CF_OEMTEXT);
-  if (codepage == cfg_codepage)
-    {
-      cfg_lcid = lcid;
-      cfg_clipboard_type = CF_OEMTEXT;
-      return FALSE; /* Stop enumeration */
-    }
-
-  return TRUE; /* Continue enumeration */
-}
-
-static UINT
-cp_from_locale (LCID lcid, UINT format)
-{
-  char buffer[20] = "";
-  UINT variant, cp;
-
-  variant =
-    format == CF_TEXT ? LOCALE_IDEFAULTANSICODEPAGE : LOCALE_IDEFAULTCODEPAGE;
-
-  GetLocaleInfo (lcid, variant, buffer, sizeof (buffer));
-  cp = strtoul (buffer, NULL, 10);
-
-  if (cp == CP_ACP)
-    return ANSICP;
-  else if (cp == CP_OEMCP)
-    return OEMCP;
-  else
-    return cp;
-}
-
-static Lisp_Object
-coding_from_cp (UINT codepage)
-{
-  char buffer[30];
-  sprintf (buffer, "cp%d-dos", (int) codepage);
-  return intern (buffer);
-  /* We don't need to check that this coding system actually exists
-     right here, because that is done later for all coding systems
-     used, regardless of where they originate.  */
-}
-
-static Lisp_Object
-validate_coding_system (Lisp_Object coding_system)
-{
-  Lisp_Object eol_type;
-
-  /* Make sure the input is valid. */
-  if (NILP (Fcoding_system_p (coding_system)))
-    return Qnil;
-
-  /* Make sure we use a DOS coding system as mandated by the system
-     specs. */
-  eol_type = Fcoding_system_eol_type (coding_system);
-
-  /* Already a DOS coding system? */
-  if (EQ (eol_type, make_number (1)))
-    return coding_system;
-
-  /* Get EOL_TYPE vector of the base of CODING_SYSTEM.  */
-  if (!VECTORP (eol_type))
-    {
-      eol_type = Fcoding_system_eol_type (Fcoding_system_base (coding_system));
-      if (!VECTORP (eol_type))
-	return Qnil;
-    }
-
-  return AREF (eol_type, 1);
-}
-
-static void
-setup_windows_coding_system (Lisp_Object coding_system,
-			     struct coding_system * coding)
-{
-  memset (coding, 0, sizeof (*coding));
-  setup_coding_system (coding_system, coding);
-
-  /* Unset CODING_ANNOTATE_COMPOSITION_MASK.  Previous code had
-     comments about crashes in encode_coding_iso2022 trying to
-     dereference a null pointer when composition was on.  Selection
-     data should not contain any composition sequence on Windows.
-
-     CODING_ANNOTATION_MASK also includes
-     CODING_ANNOTATE_DIRECTION_MASK and CODING_ANNOTATE_CHARSET_MASK,
-     which both apply to ISO6429 only.  We don't know if these really
-     need to be unset on Windows, but it probably doesn't hurt
-     either.  */
-  coding->mode &= ~CODING_ANNOTATION_MASK;
-  coding->mode |= CODING_MODE_LAST_BLOCK | CODING_MODE_SAFE_ENCODING;
-}
-
-
-
-DEFUN ("w32-set-clipboard-data", Fw32_set_clipboard_data,
-       Sw32_set_clipboard_data, 1, 2, 0,
-       doc: /* This sets the clipboard data to the given text.  */)
-  (Lisp_Object string, Lisp_Object ignored)
-{
-  BOOL ok = TRUE;
-  int nbytes;
-  unsigned char *src;
-  unsigned char *dst;
-  unsigned char *end;
-
-  /* This parameter used to be the current frame, but we don't use
-     that any more. */
-  (void) ignored;
-
-  CHECK_STRING (string);
-
-  setup_config ();
-
-  current_text = string;
-  current_coding_system = cfg_coding_system;
-  current_clipboard_type = cfg_clipboard_type;
-  current_lcid = cfg_lcid;
-  current_num_nls = 0;
-  current_requires_encoding = 0;
-
-  BLOCK_INPUT;
-
-  /* Check for non-ASCII characters.  While we are at it, count the
-     number of LFs, so we know how many CRs we will have to add later
-     (just in the case where we can use our internal ASCII rendering,
-     see code and comment in convert_to_handle_as_ascii() above).  */
-  nbytes = SBYTES (string);
-  src = SDATA (string);
-
-  for (dst = src, end = src+nbytes; dst < end; dst++)
-    {
-      if (*dst == '\n')
-	current_num_nls++;
-      else if (*dst >= 0x80 || *dst == 0)
-	{
-	  current_requires_encoding = 1;
-	  break;
-	}
-    }
-
-  if (!current_requires_encoding)
-    {
-      /* If all we have is ASCII we don't need to pretend we offer
-	 anything fancy. */
-      current_coding_system = Qraw_text;
-      current_clipboard_type = CF_TEXT;
-      current_lcid = LOCALE_NEUTRAL;
-    }
-
-  if (!OpenClipboard (clipboard_owner))
-    goto error;
-
-  ++modifying_clipboard;
-  ok = EmptyClipboard ();
-  --modifying_clipboard;
-
-  /* If we have something non-ASCII we may want to set a locale.  We
-     do that directly (non-delayed), as it's just a small bit.  */
-  if (ok)
-    ok = !NILP (render_locale ());
-
-  if (ok)
-    {
-      if (clipboard_owner == NULL)
-	{
-	  /* If for some reason we don't have a clipboard_owner, we
-	     just set the text format as chosen by the configuration
-	     and than forget about the whole thing.  */
-	  ok = !NILP (render (make_number (current_clipboard_type)));
-	  current_text = Qnil;
-	  current_coding_system = Qnil;
-	}
-      else
-	{
-	  /* Advertise all supported formats so that whatever the
-	     requester chooses, only one encoding step needs to be
-	     made.  This is intentionally different from what we do in
-	     the handler for WM_RENDERALLFORMATS.  */
-	  SetClipboardData (CF_UNICODETEXT, NULL);
-	  SetClipboardData (CF_TEXT, NULL);
-	  SetClipboardData (CF_OEMTEXT, NULL);
-	}
-    }
-
-  CloseClipboard ();
-
-  /* With delayed rendering we haven't really "used" this coding
-     system yet, and it's even unclear if we ever will.  But this is a
-     way to tell the upper level what we *would* use under ideal
-     circumstances.
-
-     We don't signal the actually used coding-system later when we
-     finally render, because that can happen at any time and we don't
-     want to disturb the "foreground" action. */
-  if (ok)
-    Vlast_coding_system_used = current_coding_system;
-
-  Vnext_selection_coding_system = Qnil;
-
-  if (ok) goto done;
-
- error:
-
-  ok = FALSE;
-  current_text = Qnil;
-  current_coding_system = Qnil;
-
- done:
-  UNBLOCK_INPUT;
-
-  return (ok ? string : Qnil);
-}
-
-
-DEFUN ("w32-get-clipboard-data", Fw32_get_clipboard_data,
-       Sw32_get_clipboard_data, 0, 1, 0,
-       doc: /* This gets the clipboard data in text format.  */)
-  (Lisp_Object ignored)
+DEFUN ("w32-claim-clipboard",
+       Fw32_claim_clipboard, Sw32_claim_clipboard, 0, 0, 0,
+       doc: /* Claim ownership of the clipboard, clear it, and begin
+advertising our content.  The formats advertised are given by the list
+`w32-clipboard-advertised-types'.  */)
+     (void)
+{
+  if (!clipboard_owner) {
+    error ("clipboard not initialized");
+  }
+
+  /* Use SendMessage and not PostMessage so the clipboard thread can
+     be confident that we're not GCing or mutating.  */
+  SendMessage (clipboard_owner, WM_EMACS_CLAIM_CLIPBOARD, 0, 0);
+}
+
+DEFUN ("w32-get-raw-clipboard-data", Fw32_get_raw_clipboard_data,
+       Sw32_get_raw_clipboard_data, 1, 1, 0,
+       doc: /* Retrieve the Win32 clipboard data of the given type
+TYPE.  Return nil if there is nothing in the clipboard of the given
+type.  TYPE is an integer giving the raw Win32 clipboard format
+constant.*/)
+  (Lisp_Object format)
 {
   HGLOBAL htext;
   Lisp_Object ret = Qnil;
-  UINT actual_clipboard_type;
-  int use_configured_coding_system = 1;
-
-  /* This parameter used to be the current frame, but we don't use
-     that any more. */
-  (void) ignored;
-
-  /* Don't pass our own text from the clipboard (which might be
-     troublesome if the killed text includes null characters).  */
-  if (!NILP (current_text))
-    return ret;
-
-  setup_config ();
-  actual_clipboard_type = cfg_clipboard_type;
-
-  BLOCK_INPUT;
-
-  if (!OpenClipboard (clipboard_owner))
-    goto done;
-
-  if ((htext = GetClipboardData (actual_clipboard_type)) == NULL)
-    {
-      /* If we want CF_UNICODETEXT but can't get it, the current
-	 coding system is useless.  OTOH we can still try and decode
-	 CF_TEXT based on the locale that the system gives us and that
-	 we get down below.  */
-      if (actual_clipboard_type == CF_UNICODETEXT)
-	{
-	  htext = GetClipboardData (CF_TEXT);
-	  if (htext != NULL)
-	    {
-	      actual_clipboard_type = CF_TEXT;
-	      use_configured_coding_system = 0;
-	    }
-	}
-    }
-  if (htext == NULL)
-    goto closeclip;
-
-  {
-    unsigned char *src;
-    unsigned char *dst;
-    int nbytes;
-    int truelen;
-    int require_decoding = 0;
-
-    if ((src = (unsigned char *) GlobalLock (htext)) == NULL)
-      goto closeclip;
-
-    /* If the clipboard data contains any non-ascii code, we need to
-       decode it with a coding system.  */
-    if (actual_clipboard_type == CF_UNICODETEXT)
-      {
-	nbytes = lstrlenW ((WCHAR *)src) * 2;
-	require_decoding = 1;
-      }
-    else
-      {
-	int i;
-
-	nbytes = strlen (src);
-
-	for (i = 0; i < nbytes; i++)
-	  {
-	    if (src[i] >= 0x80)
-	      {
-		require_decoding = 1;
-		break;
-	      }
-	  }
-      }
-
-    if (require_decoding)
-      {
-	struct coding_system coding;
-	Lisp_Object coding_system = Qnil;
-	Lisp_Object dos_coding_system;
-
-	/* `next-selection-coding-system' should override everything,
-	   even when the locale passed by the system disagrees.  The
-	   only exception is when `next-selection-coding-system'
-	   requested CF_UNICODETEXT and we couldn't get that. */
-	if (use_configured_coding_system
-	    && !NILP (Vnext_selection_coding_system))
-	    coding_system = Vnext_selection_coding_system;
-
-	/* If we have CF_TEXT or CF_OEMTEXT, we want to check out
-	   CF_LOCALE, too. */
-	else if (actual_clipboard_type != CF_UNICODETEXT)
-	  {
-	    HGLOBAL hlocale;
-	    LCID lcid = DEFAULT_LCID;
-	    UINT cp;
-
-	    /* Documentation says that the OS always generates
-	       CF_LOCALE info automatically, so the locale handle
-	       should always be present.  Fact is that this is not
-	       always true on 9x ;-(.  */
-	    hlocale = GetClipboardData (CF_LOCALE);
-	    if (hlocale != NULL)
-	      {
-		const LCID * lcid_ptr;
-		lcid_ptr = (const LCID *) GlobalLock (hlocale);
-		if (lcid_ptr != NULL)
-		  {
-		    lcid = *lcid_ptr;
-		    GlobalUnlock (hlocale);
-		  }
-
-		/* 9x has garbage as the sort order (to be exact there
-		   is another instance of the language id in the upper
-		   word).  We don't care about sort order anyway, so
-		   we just filter out the unneeded mis-information to
-		   avoid irritations. */
-		lcid = MAKELCID (LANGIDFROMLCID (lcid), SORT_DEFAULT);
-	      }
-
-	    /* If we are using fallback from CF_UNICODETEXT, we can't
-	       use the configured coding system.  Also we don't want
-	       to use it, if the system has supplied us with a locale
-	       and it is not just the system default. */
-	    if (!use_configured_coding_system || lcid != DEFAULT_LCID)
-	      {
-		cp = cp_from_locale (lcid, actual_clipboard_type);
-		/* If it's just our current standard setting anyway,
-		   use the coding system that the user has selected.
-		   Otherwise create a new spec to match the locale
-		   that was specified by the other side or the
-		   system.  */
-		if (!use_configured_coding_system || cp != cfg_codepage)
-		  coding_system = coding_from_cp (cp);
-	      }
-	  }
-
-	if (NILP (coding_system))
-	  coding_system = Vselection_coding_system;
-	Vnext_selection_coding_system = Qnil;
-
-	dos_coding_system = validate_coding_system (coding_system);
-	if (!NILP (dos_coding_system))
-	  {
-	    setup_windows_coding_system (dos_coding_system, &coding);
-	    coding.source = src;
-	    decode_coding_object (&coding, Qnil, 0, 0, nbytes, nbytes, Qt);
-	    ret = coding.dst_object;
-
-	    Vlast_coding_system_used = CODING_ID_NAME (coding.id);
-	  }
-      }
-    else
-      {
-	/* FIXME: We may want to repeat the code in this branch for
-	   the Unicode case. */
-
-	/* Need to know final size after CR chars are removed because
-	   we can't change the string size manually, and doing an
-	   extra copy is silly.  We only remove CR when it appears as
-	   part of CRLF.  */
-
-	truelen = nbytes;
-	dst = src;
-	/* avoid using strchr because it recomputes the length everytime */
-	while ((dst = memchr (dst, '\r', nbytes - (dst - src))) != NULL)
-	  {
-	    if (dst[1] == '\n')	/* safe because of trailing '\0' */
-	      truelen--;
-	    dst++;
-	  }
-
-	ret = make_uninit_string (truelen);
-
-	/* Convert CRLF line endings (the standard CF_TEXT clipboard
-	   format) to LF endings as used internally by Emacs.  */
-
-	dst = SDATA (ret);
-	while (1)
-	  {
-	    unsigned char *next;
-	    /* copy next line or remaining bytes excluding '\0' */
-	    next = _memccpy (dst, src, '\r', nbytes);
-	    if (next)
-	      {
-		/* copied one line ending with '\r' */
-		int copied = next - dst;
-		nbytes -= copied;
-		dst += copied;
-		src += copied;
-		if (*src == '\n')
-		  dst--;	/* overwrite '\r' with '\n' */
-	      }
-	    else
-	      /* copied remaining partial line -> now finished */
-	      break;
-	  }
-
-	Vlast_coding_system_used = Qraw_text;
-      }
-
-    GlobalUnlock (htext);
-  }
-
- closeclip:
-  CloseClipboard ();
-
- done:
-  UNBLOCK_INPUT;
-
-  return (ret);
+  wchar_t* buf = NULL;
+  int count = SPECPDL_INDEX ();
+
+  CHECK_NUMBER (format);
+
+  if (!OpenClipboard (NULL)) {
+    return Qnil;
+  }
+
+  record_unwind_protect (close_clipboard_unwind, Qnil);
+  htext = GetClipboardData (XFASTINT (format));
+
+  if (htext != NULL) {
+    ret = make_uninit_string (GlobalSize (htext));
+    buf = GlobalLock (htext);
+    if (!buf)
+      error ("GlobalLock: %s", w32_strerror (GetLastError ()));
+
+    memcpy (SDATA (ret), buf, GlobalSize (htext));
+    if (!GlobalUnlock (htext) && GetLastError () != NO_ERROR)
+      error ("GlobalUnlock: %s", w32_strerror (GetLastError ()));
+  }
+
+  return unbind_to (count, ret);
 }
 
-/* Support checking for a clipboard selection. */
-
 DEFUN ("x-selection-exists-p", Fx_selection_exists_p, Sx_selection_exists_p,
        0, 1, 0,
        doc: /* Whether there is an owner for the given X Selection.
@@ -1027,17 +387,11 @@
     {
       Lisp_Object val = Qnil;
 
-      setup_config ();
-
       if (OpenClipboard (NULL))
 	{
 	  UINT format = 0;
 	  while ((format = EnumClipboardFormats (format)))
-	    /* Check CF_TEXT in addition to cfg_clipboard_type,
-	       because we can fall back on that if CF_UNICODETEXT is
-	       not available.  Actually a check for CF_TEXT only
-	       should be enough.  */
-	    if (format == cfg_clipboard_type || format == CF_TEXT)
+	    if (format == CF_UNICODETEXT)
 	      {
 		val = Qt;
 		break;
@@ -1049,93 +403,65 @@
   return Qnil;
 }
 
+DEFUN ("w32-register-clipboard-format",
+       Fw32_register_clipboard_format, Sw32_register_clipboard_format,
+       1, 1, 0,
+       doc: /* Return the system-wide numberic identifier for clipboard
+format FORMAT (a string).  */)
+  (Lisp_Object format)
+{
+  return make_number (RegisterClipboardFormatW (to_unicode (format, &format)));
+}
+
 /* One-time init.  Called in the un-dumped Emacs, but not in the
    dumped version. */
 
 void
 syms_of_w32select (void)
 {
-  defsubr (&Sw32_set_clipboard_data);
-  defsubr (&Sw32_get_clipboard_data);
+  defsubr (&Sw32_get_raw_clipboard_data);
   defsubr (&Sx_selection_exists_p);
-
-  DEFVAR_LISP ("selection-coding-system", Vselection_coding_system,
-	       doc: /* Coding system for communicating with other programs.
-
-For MS-Windows and MS-DOS:
-When sending or receiving text via selection and clipboard, the text
-is encoded or decoded by this coding system.  The default value is
-the current system default encoding on 9x/Me, `utf-16le-dos'
-\(Unicode) on NT/W2K/XP, and `iso-latin-1-dos' on MS-DOS.
-
-For X Windows:
-When sending text via selection and clipboard, if the target
-data-type matches with the type of this coding system, it is used
-for encoding the text.  Otherwise (including the case that this
-variable is nil), a proper coding system is used as below:
-
-data-type	coding system
----------	-------------
-UTF8_STRING	utf-8
-COMPOUND_TEXT	compound-text-with-extensions
-STRING		iso-latin-1
-C_STRING	no-conversion
-
-When receiving text, if this coding system is non-nil, it is used
-for decoding regardless of the data-type.  If this is nil, a
-proper coding system is used according to the data-type as above.
-
-See also the documentation of the variable `x-select-request-type' how
-to control which data-type to request for receiving text.
-
-The default value is nil.  */);
-  /* The actual value is set dynamically in the dumped Emacs, see
-     below. */
-  Vselection_coding_system = Qnil;
-
-  DEFVAR_LISP ("next-selection-coding-system", Vnext_selection_coding_system,
-	       doc: /* Coding system for the next communication with other programs.
-Usually, `selection-coding-system' is used for communicating with
-other programs (X Windows clients or MS Windows programs).  But, if this
-variable is set, it is used for the next communication only.
-After the communication, this variable is set to nil.  */);
-  Vnext_selection_coding_system = Qnil;
+  defsubr (&Sw32_claim_clipboard);
+  defsubr (&Sw32_register_clipboard_format);
 
   DEFSYM (QCLIPBOARD, "CLIPBOARD");
-
-  cfg_coding_system = Qnil;     staticpro (&cfg_coding_system);
-  current_text = Qnil;		staticpro (&current_text);
-  current_coding_system = Qnil; staticpro (&current_coding_system);
-
   DEFSYM (QUNICODE, "utf-16le-dos");
-  QANSICP = Qnil; staticpro (&QANSICP);
-  QOEMCP = Qnil;  staticpro (&QOEMCP);
-}
-
-/* One-time init.  Called in the dumped Emacs, but not in the
-   un-dumped version. */
+  DEFSYM (Qw32_clipboard_render, "w32-clipboard-render");
+  DEFSYM (Qw32_lost_selection_functions, "w32-lost-selection-functions");
+
+  DEFVAR_LISP ("w32-lost-selection-functions", Vw32_lost_selection_functions,
+	       doc: /* A list of functions to be called when Emacs
+loses an X selection.  \(This happens when some other client makes its
+own selection or when a Lisp program explicitly clears the selection.)
+The functions are called with one argument, the selection type \(a
+symbol, typically `PRIMARY', `SECONDARY', or `CLIPBOARD').  */);
+  Vw32_lost_selection_functions = Qnil;
+
+  DEFVAR_LISP ("w32-clipboard-advertised-types",
+               Vw32_clipboard_advertised_types,
+               doc: /* A list of data types to offer other programs
+via the clipboard.  Each one is an integer giving the number ID of the
+type to offer.  The correct values can be found in the platform
+SDK.  */);
+  Vw32_clipboard_advertised_types = Qnil;
+}
+
+static DWORD CALLBACK
+clipboard_threadproc (LPVOID ignored)
+{
+  MSG msg;
+  clipboard_owner = create_owner ();
+  while (GetMessage (&msg, NULL, 0, 0)) {
+    DispatchMessage (&msg);
+  }
+}
 
 void
 globals_of_w32select (void)
 {
-  DEFAULT_LCID = GetUserDefaultLCID ();
-  /* Drop the sort order from the LCID, so we can compare this with
-     CF_LOCALE objects that have the same fix on 9x.  */
-  DEFAULT_LCID = MAKELCID (LANGIDFROMLCID (DEFAULT_LCID), SORT_DEFAULT);
-
-  ANSICP = GetACP ();
-  OEMCP = GetOEMCP ();
-
-  QANSICP = coding_from_cp (ANSICP);
-  QOEMCP = coding_from_cp (OEMCP);
-
-  if (os_subtype == OS_NT)
-    Vselection_coding_system = QUNICODE;
-  else if (inhibit_window_system)
-    Vselection_coding_system = QOEMCP;
-  else
-    Vselection_coding_system = QANSICP;
-
-  clipboard_owner = create_owner ();
+  clipboard_owner = NULL;
+  clipboard_thread = CreateThread (NULL, 0,
+                                   clipboard_threadproc,
+                                   NULL, 0, NULL);
 }
 

=== modified file 'src/w32term.c'
--- src/w32term.c	2011-05-28 22:39:39 +0000
+++ src/w32term.c	2011-07-17 16:31:27 +0000
@@ -52,7 +52,14 @@
 #include "atimer.h"
 #include "keymap.h"
 
+#ifdef WINDOWSNT
 #include "w32heap.h"
+#endif
+
+#ifndef WINDOWSNT
+#include <io.h> /* for get_osfhandle */
+#endif
+
 #include <shellapi.h>
 
 #include "font.h"
@@ -188,6 +195,11 @@
 static int input_signal_count;
 #endif
 
+#ifdef USE_W32_SELECT
+int w32_evt_pipe[2] = { -1, -1 };
+HANDLE w32_evt_write;
+#endif /* USE_W32_SELECT */
+
 /* Keyboard code page - may be changed by language-change events.  */
 static int keyboard_codepage;
 
@@ -4057,12 +4069,27 @@
       struct input_event inev;
       int do_help = 0;
 
+      /* DebPrint (("w32_read_socket: %s time:%u\n", */
+      /*            w32_name_of_message (msg.msg.message), */
+      /*            msg.msg.time)); */
+
       EVENT_INIT (inev);
       inev.kind = NO_EVENT;
       inev.arg = Qnil;
 
       switch (msg.msg.message)
 	{
+        case WM_EMACS_MT_CALL:
+          {
+            EMACS_TIME interval;
+            void* data;
+
+            EMACS_SET_SECS_USECS (interval, 0, 0);
+            memcpy (&data, &msg.rect, sizeof(data));
+            start_atimer (ATIMER_RELATIVE, interval,
+                          (atimer_callback)msg.msg.lParam, data);
+          }
+          break;
 	case WM_EMACS_PAINT:
 	  f = x_window_to_frame (dpyinfo, msg.msg.hwnd);
 
@@ -6168,8 +6195,13 @@
     w32_defined_color (0, "black", &color, 1);
   }
 
-  /* Add the default keyboard.  */
+#ifdef WINDOWSNT
+  /* Add the default keyboard.  When !WINDOWSNT, we're using the
+     standard Emacs console handling machinery and don't need an
+     explicit FD here; w32_select will take care of waking Emacs when
+     we have GUI input.  */
   add_keyboard_wait_descriptor (0);
+#endif
 
   /* Create Fringe Bitmaps and store them for later use.
 
@@ -6180,15 +6212,6 @@
      the bitmaps.  */
   w32_init_fringe (terminal->rif);
 
-#ifdef F_SETOWN
-  fcntl (connection, F_SETOWN, getpid ());
-#endif /* ! defined (F_SETOWN) */
-
-#ifdef SIGIO
-  if (interrupt_input)
-    init_sigio (connection);
-#endif /* ! defined (SIGIO) */
-
   UNBLOCK_INPUT;
 
   return dpyinfo;
@@ -6238,6 +6261,46 @@
 
   w32_reset_fringes ();
 }
+
+\f
+/* Event loop integration when we're not running on bare NT. */
+
+#ifdef USE_W32_SELECT
+
+/* Unless we're a native Windows program, we're integrated into normal
+ * Emacs event loop.  This function is just like select, but also
+ * returns when we have pending Win32 events. */
+int
+w32_select (int nfds, fd_set *readfds, fd_set *writefds,
+            fd_set *exceptfds, struct timeval *timeout)
+{
+  fd_set modified_readfds;
+  char buf;
+
+  if (w32_evt_pipe[0] == -1) {
+    return select (nfds, readfds, writefds, exceptfds, timeout);
+  }
+
+  modified_readfds = *readfds;
+  FD_SET (w32_evt_pipe[0],  &modified_readfds);
+  nfds = select (max (nfds, w32_evt_pipe[0] + 1),
+                 &modified_readfds, writefds, exceptfds, timeout);
+  if (nfds < 1) {
+    return nfds;
+  }
+
+  if (FD_ISSET (w32_evt_pipe[0], &modified_readfds)) {
+    FD_CLR (w32_evt_pipe[0], &modified_readfds);
+    read (w32_evt_pipe[0], &buf, sizeof(buf));
+  }
+
+  *readfds = modified_readfds;
+  return nfds;
+}
+
+
+#endif /* USE_W32_SELECT */
+
 \f
 /* Set up use of W32.  */
 
@@ -6275,6 +6338,15 @@
 	set_user_model (L"GNU.Emacs");
     }
 
+#ifdef USE_W32_SELECT
+  if (pipe (w32_evt_pipe)) {
+    fatal ("pipe: %s", strerror (errno));
+  }
+  fcntl (w32_evt_pipe[0], F_SETFD, FD_CLOEXEC);
+  fcntl (w32_evt_pipe[1], F_SETFD, FD_CLOEXEC);
+  w32_evt_write = (HANDLE)get_osfhandle (w32_evt_pipe[1]);
+#endif /* USE_W32_SELET */
+
   /* Initialize w32_use_visible_system_caret based on whether a screen
      reader is in use.  */
   if (!SystemParametersInfo (SPI_GETSCREENREADER, 0,
@@ -6434,4 +6506,6 @@
 
   staticpro (&last_mouse_motion_frame);
   last_mouse_motion_frame = Qnil;
+
+  Fprovide (intern_c_string ("w32"), Qnil);
 }

=== modified file 'src/w32term.h'
--- src/w32term.h	2011-06-22 06:16:16 +0000
+++ src/w32term.h	2011-07-17 16:31:05 +0000
@@ -19,6 +19,8 @@
 /* Added by Kevin Gallo */
 
 #include "w32gui.h"
+#include "frame.h"
+#include "atimer.h"
 
 \f
 #define BLACK_PIX_DEFAULT(f) PALETTERGB(0,0,0)
@@ -195,11 +197,47 @@
                                     Lisp_Object, Lisp_Object,
                                     Lisp_Object, Lisp_Object);
 
+extern void x_focus_on_frame (struct frame *f); 
+
+/* also defined in xterm.h XXX: factor out to common header */
+
 extern struct w32_display_info *w32_term_init (Lisp_Object,
 					       char *, char *);
-
+extern void check_w32 (void);
+extern int w32_defined_color (FRAME_PTR f, const char *color,
+                              XColor *color_def, int alloc);
+extern void set_frame_menubar (struct frame *f, int first_time, int deep_p);
+extern void x_set_window_size (struct frame *f, int change_grav,
+                              int cols, int rows);
 extern int x_display_pixel_height (struct w32_display_info *);
 extern int x_display_pixel_width (struct w32_display_info *);
+extern void x_sync (struct frame *);
+extern Lisp_Object x_get_focus_frame (struct frame *);
+extern void x_set_mouse_position (struct frame *f, int h, int v);
+extern void x_set_mouse_pixel_position (struct frame *f, int pix_x, int pix_y);
+extern void x_make_frame_visible (struct frame *f);
+extern void x_make_frame_invisible (struct frame *f);
+extern void x_iconify_frame (struct frame *f);
+extern int x_char_width (struct frame *f);
+extern int x_char_height (struct frame *f);
+extern int x_pixel_width (struct frame *f);
+extern int x_pixel_height (struct frame *f);
+extern void x_set_frame_alpha (struct frame *f);
+extern void x_set_menu_bar_lines (struct frame *, Lisp_Object, Lisp_Object);
+extern void x_set_tool_bar_lines (struct frame *f,
+                                  Lisp_Object value,
+                                  Lisp_Object oldval);
+extern void x_activate_menubar (struct frame *);
+extern int x_bitmap_icon (struct frame *, Lisp_Object);
+extern void initialize_frame_menubar (struct frame *);
+extern void x_free_frame_resources (struct frame *);
+extern void x_wm_set_size_hint (struct frame *, long, int);
+extern void x_real_positions (struct frame *, int *, int *);
+
+/* w32inevt.c */
+extern int w32_kbd_patch_key (KEY_EVENT_RECORD *event);
+extern int w32_kbd_mods_to_emacs (DWORD mods, WORD key);
+
 
 \f
 #define PIX_TYPE COLORREF
@@ -576,7 +614,8 @@
 #define WM_EMACS_HIDE_CARET            (WM_EMACS_START + 18)
 #define WM_EMACS_SETCURSOR             (WM_EMACS_START + 19)
 #define WM_EMACS_PAINT                 (WM_EMACS_START + 20)
-#define WM_EMACS_END                   (WM_EMACS_START + 21)
+#define WM_EMACS_MT_CALL               (WM_EMACS_START + 21)
+#define WM_EMACS_END                   (WM_EMACS_START + 22)
 
 #define WND_FONTWIDTH_INDEX    (0)
 #define WND_LINEHEIGHT_INDEX   (4)
@@ -598,6 +637,8 @@
     RECT rect;
 } W32Msg;
 
+extern BOOL prepend_msg (W32Msg *lpmsg);
+
 /* Structure for recording message when input thread must return a
    result that depends on lisp thread to compute.  Lisp thread can
    complete deferred messages out of order.  */
@@ -630,6 +671,8 @@
 extern BOOL post_msg (W32Msg *);
 extern void complete_deferred_msg (HWND hwnd, UINT msg, LRESULT result);
 
+extern void call_on_main_thread (atimer_callback callback, void* data);
+
 extern BOOL parse_button (int, int, int *, int *);
 
 extern void w32_sys_ring_bell (struct frame *f);
@@ -701,3 +744,24 @@
 extern int w32_system_caret_height;
 extern int w32_system_caret_x;
 extern int w32_system_caret_y;
+
+#if EMACSDEBUG
+extern const char*
+w32_name_of_message (UINT msg);
+#endif /* EMACSDEBUG */
+
+#ifdef USE_W32_SELECT
+
+/* Ordinarily, we'd just send SIGALRM to ourselves when we have input,
+ * terminating a normal select call with EINTR.  However, Cygwin has a
+ * known bug [1] that causes us to crash when sending a signal to our
+ * main thread from our message pump thread.  The workaround is to use
+ * an old-fashioned self-pipe.
+ *
+ * [1] <loom.20100428T060408-563@post.gmane.org>
+ */
+extern int w32_evt_pipe[2];
+extern HANDLE w32_evt_write;
+extern int w32_select (int nfds, fd_set *readfds, fd_set *writefds,
+                       fd_set *exceptfds, struct timeval *timeout);
+#endif /* USE_W32_SELECT */

=== modified file 'src/w32xfns.c'
--- src/w32xfns.c	2011-03-12 19:19:47 +0000
+++ src/w32xfns.c	2011-07-17 14:35:53 +0000
@@ -20,6 +20,11 @@
 #include <signal.h>
 #include <stdio.h>
 #include <setjmp.h>
+
+#if CYGWIN
+#include <signal.h>
+#endif
+
 #include "lisp.h"
 #include "keyboard.h"
 #include "frame.h"
@@ -33,7 +38,11 @@
 #define myfree(lp) GlobalFreePtr (lp)
 
 CRITICAL_SECTION critsect;
+
+#if WINDOWSNT
 extern HANDLE keyboard_handle;
+#endif
+
 HANDLE input_available = NULL;
 HANDLE interrupt_handle = NULL;
 
@@ -44,7 +53,11 @@
 
   /* For safety, input_available should only be reset by get_next_msg
      when the input queue is empty, so make it a manual reset event. */
-  keyboard_handle = input_available = CreateEvent (NULL, TRUE, FALSE, NULL);
+  input_available = CreateEvent (NULL, TRUE, FALSE, NULL);
+
+#if WINDOWSNT
+  keyboard_handle = input_available;
+#endif
 
   /* interrupt_handle is signaled when quit (C-g) is detected, so that
      blocking system calls can be interrupted.  We make it a manual
@@ -241,6 +254,47 @@
   return (bRet);
 }
 
+extern char * w32_strerror (int error_no);
+
+/* Tell waiters that we have input available.  Call with lock
+ * held.  */
+static void
+notify_msg_ready (void)
+{
+  SetEvent (input_available);
+  
+#ifdef USE_W32_SELECT
+  {
+    /* Signal main thread that an event is ready.  Use pure Win32 to
+     * do it so as not to quicken the wrath of the undefined
+     * behavior Cygwin gods.  Use overlapped IO because Cygwin
+     * creates pipes as overlapped files in order to select on
+     * them.  */
+      
+    char buf = '\0';
+    DWORD nr_written;
+    OVERLAPPED op;
+    static HANDLE ev = NULL;
+    BOOL status;
+
+    if (ev == NULL) {
+      ev = CreateEvent (NULL, TRUE /*manual-reset*/, FALSE, NULL);
+    }
+    ResetEvent (ev);
+    memset (&op, 0, sizeof(op));
+    op.hEvent = ev;
+    status = WriteFile (w32_evt_write, &buf, sizeof(buf), &nr_written, &op);
+    if (status == FALSE && GetLastError () == ERROR_IO_PENDING) {
+      status = GetOverlappedResult (w32_evt_write, &op, &nr_written, TRUE);
+    }
+
+    if (status == FALSE) {
+      fatal ("writing to evt pipe: %s", w32_strerror (GetLastError ()));
+    }
+  }
+#endif
+}
+
 BOOL
 post_msg (W32Msg * lpmsg)
 {
@@ -264,13 +318,23 @@
     }
 
   lpTail = lpNew;
-  SetEvent (input_available);
-
+  notify_msg_ready ();
   leave_crit ();
 
   return (TRUE);
 }
 
+void
+call_on_main_thread (atimer_callback callback, void* data)
+{
+  W32Msg cbmsg;
+  memset (&cbmsg, 0, sizeof (cbmsg));
+  cbmsg.msg.message = WM_EMACS_MT_CALL;
+  cbmsg.msg.lParam = (LPARAM) callback;
+  memcpy (&cbmsg.rect, &data, sizeof(data));
+  post_msg (&cbmsg);
+}
+
 BOOL
 prepend_msg (W32Msg *lpmsg)
 {
@@ -438,7 +502,7 @@
 
 /* x_sync is a no-op on W32.  */
 void
-x_sync (void *f)
+x_sync (struct frame *f)
 {
 }
 

=== modified file 'src/window.c'
--- src/window.c	2011-07-14 17:28:42 +0000
+++ src/window.c	2011-07-16 06:02:55 +0000
@@ -40,7 +40,7 @@
 #ifdef HAVE_X_WINDOWS
 #include "xterm.h"
 #endif	/* HAVE_X_WINDOWS */
-#ifdef WINDOWSNT
+#ifdef HAVE_NTGUI
 #include "w32term.h"
 #endif
 #ifdef MSDOS

=== modified file 'src/xdisp.c'
--- src/xdisp.c	2011-07-15 10:50:03 +0000
+++ src/xdisp.c	2011-07-16 10:34:55 +0000
@@ -302,7 +302,7 @@
 #ifdef HAVE_X_WINDOWS
 #include "xterm.h"
 #endif
-#ifdef WINDOWSNT
+#ifdef HAVE_NTGUI
 #include "w32term.h"
 #endif
 #ifdef HAVE_NS
@@ -27809,7 +27809,7 @@
 
 /* Since w32 does not support atimers, it defines its own implementation of
    the following three functions in w32fns.c.  */
-#ifndef WINDOWSNT
+#ifndef HAVE_NTGUI
 
 /* Platform-independent portion of hourglass implementation. */
 
@@ -27867,4 +27867,4 @@
     hide_hourglass ();
 #endif
 }
-#endif /* ! WINDOWSNT  */
+#endif /* ! HAVE_NTGUI  */

=== modified file 'src/xfaces.c'
--- src/xfaces.c	2011-07-10 08:20:10 +0000
+++ src/xfaces.c	2011-07-16 05:43:00 +0000
@@ -225,7 +225,7 @@
 #include "dosfns.h"
 #endif
 
-#ifdef WINDOWSNT
+#ifdef HAVE_NTGUI
 #include "w32term.h"
 #include "fontset.h"
 /* Redefine X specifics to W32 equivalents to avoid cluttering the
@@ -236,7 +236,7 @@
 #define FRAME_X_FONT_TABLE FRAME_W32_FONT_TABLE
 #define check_x check_w32
 #define GCGraphicsExposures 0
-#endif /* WINDOWSNT */
+#endif /* HAVE_NTGUI */
 
 #ifdef HAVE_NS
 #include "nsterm.h"
@@ -667,7 +667,7 @@
 
 #endif /* HAVE_X_WINDOWS */
 
-#ifdef WINDOWSNT
+#ifdef HAVE_NTGUI
 /* W32 emulation of GCs */
 
 static inline GC
@@ -691,7 +691,7 @@
   xfree (gc);
 }
 
-#endif  /* WINDOWSNT */
+#endif  /* HAVE_NTGUI */
 
 #ifdef HAVE_NS
 /* NS emulation of GCs */
@@ -785,7 +785,7 @@
 #ifdef HAVE_X_WINDOWS
   if (!FRAME_X_P (f) || FRAME_X_WINDOW (f))
 #endif
-#ifdef WINDOWSNT
+#ifdef HAVE_NTGUI
   if (!FRAME_WINDOW_P (f) || FRAME_W32_WINDOW (f))
 #endif
 #ifdef HAVE_NS
@@ -1159,7 +1159,7 @@
   else if (FRAME_X_P (f))
     return x_defined_color (f, color_name, color_def, alloc);
 #endif
-#ifdef WINDOWSNT
+#ifdef HAVE_NTGUI
   else if (FRAME_W32_P (f))
     return w32_defined_color (f, color_name, color_def, alloc);
 #endif
@@ -3239,7 +3239,7 @@
 	    param = Qbackground_color;
 	}
 #ifdef HAVE_WINDOW_SYSTEM
-#ifndef WINDOWSNT
+#ifndef HAVE_NTGUI
       else if (EQ (face, Qscroll_bar))
 	{
 	  /* Changing the colors of `scroll-bar' sets frame parameters
@@ -3249,7 +3249,7 @@
 	  else if (EQ (attr, QCbackground))
 	    param = Qscroll_bar_background;
 	}
-#endif /* not WINDOWSNT */
+#endif /* not HAVE_NTGUI */
       else if (EQ (face, Qborder))
 	{
 	  /* Changing background color of `border' sets frame parameter
@@ -6293,7 +6293,7 @@
 	    if (num >= 0 && name[num] == '\n')
 	      name[num] = 0;
 	    cmap = Fcons (Fcons (build_string (name),
-#ifdef WINDOWSNT
+#ifdef HAVE_NTGUI
 				 make_number (RGB (red, green, blue))),
 #else
 				 make_number ((red << 16) | (green << 8) | blue)),


[-- Attachment #2: OpenPGP digital signature --]
[-- Type: application/pgp-signature, Size: 195 bytes --]

             reply	other threads:[~2011-07-18  0:01 UTC|newest]

Thread overview: 51+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2011-07-18  0:01 Daniel Colascione [this message]
2011-07-18  0:06 ` [PATCH] system-type cygwin with window-system w32 Daniel Colascione
2011-07-18  6:13 ` Eli Zaretskii
2011-07-18  6:29   ` Daniel Colascione
2011-07-18  8:53     ` Eli Zaretskii
2011-07-18 10:10       ` Daniel Colascione
2011-07-18 16:04         ` Paul Eggert
2011-07-18 16:19         ` Eli Zaretskii
2011-07-18 13:55     ` Jason Rumney
2011-07-18 16:13     ` Paul Eggert
2011-07-18 17:34       ` Andreas Schwab
2011-07-18  6:53 ` Eli Zaretskii
2011-07-18  7:01   ` Daniel Colascione
2011-07-18  9:04     ` Eli Zaretskii
2011-07-18  9:41       ` Daniel Colascione
2011-07-18 10:10         ` Eli Zaretskii
2011-07-18 10:49           ` Daniel Colascione
2011-07-18 11:22             ` Juanma Barranquero
2011-07-18 16:41             ` Eli Zaretskii
2011-07-18 16:48               ` Daniel Colascione
2011-07-18 17:08                 ` Eli Zaretskii
2011-07-18 22:08             ` Richard Stallman
2011-07-18 22:24               ` Daniel Colascione
2011-07-18 22:45                 ` David Kastrup
2011-07-18 22:56                   ` Daniel Colascione
2011-07-19 16:49                     ` Richard Stallman
2011-07-21  1:44               ` Lennart Borgman
2011-07-18 22:08             ` Richard Stallman
2011-07-18 13:31       ` Jason Rumney
2011-07-18 13:46         ` Richard Riley
2011-07-18  8:42 ` Eli Zaretskii
2011-07-18 10:33   ` Daniel Colascione
2011-07-18 16:29     ` Eli Zaretskii
2011-07-18 17:04       ` Daniel Colascione
2011-07-18 15:54 ` Stefan Monnier
2011-07-18 15:55 ` Stefan Monnier
2011-07-18 17:37 ` Andreas Schwab
  -- strict thread matches above, loose matches on Subject: below --
2011-07-18 17:33 grischka
2011-07-18 17:50 ` Daniel Colascione
2011-07-18 18:08   ` Daniel Colascione
2011-07-18 18:52     ` grischka
2011-07-18 19:11       ` Daniel Colascione
2011-07-18 21:01         ` grischka
2011-07-19  2:58           ` Eli Zaretskii
2011-07-19  2:59             ` Daniel Colascione
2011-07-21 17:44           ` Lennart Borgman
2011-07-22  7:30             ` Daniel Colascione
2011-07-22  7:41               ` Lennart Borgman
2011-07-22 21:24                 ` chad
2011-07-22 21:57                   ` Lennart Borgman
2011-07-18 18:38   ` grischka

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=4E2377E2.1020804@gmail.com \
    --to=dan.colascione@gmail.com \
    --cc=emacs-devel@gnu.org \
    /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).