unofficial mirror of emacs-devel@gnu.org 
 help / color / mirror / code / Atom feed
* [PATCH] system-type cygwin with window-system w32
@ 2011-07-18  0:01 Daniel Colascione
  2011-07-18  0:06 ` Daniel Colascione
                   ` (6 more replies)
  0 siblings, 7 replies; 51+ messages in thread
From: Daniel Colascione @ 2011-07-18  0:01 UTC (permalink / raw)
  To: Emacs development discussions


[-- 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 --]

^ permalink raw reply	[flat|nested] 51+ messages in thread

* Re: [PATCH] system-type cygwin with window-system w32
  2011-07-18  0:01 [PATCH] system-type cygwin with window-system w32 Daniel Colascione
@ 2011-07-18  0:06 ` Daniel Colascione
  2011-07-18  6:13 ` Eli Zaretskii
                   ` (5 subsequent siblings)
  6 siblings, 0 replies; 51+ messages in thread
From: Daniel Colascione @ 2011-07-18  0:06 UTC (permalink / raw)
  To: Emacs development discussions


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

On 7/17/11 5:01 PM, Daniel Colascione wrote:
> This patch 

Gah. Here's the rest of it.

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

=== added file 'src/cygw32.h'
--- src/cygw32.h	1970-01-01 00:00:00 +0000
+++ src/cygw32.h	2011-07-17 14:35:41 +0000
@@ -0,0 +1,58 @@
+/* Header for 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/>.  */
+
+#ifndef CYGW32_H
+#define CYGW32_H
+#include <config.h>
+#include <windef.h>
+#include <sys/cygwin.h>
+#include <wchar.h>
+
+#include <signal.h>
+#include <stdio.h>
+#include <limits.h>
+#include <errno.h>
+#include <math.h>
+#include <setjmp.h>
+
+#include "lisp.h"
+#include "coding.h"
+
+/* Character conversion */
+#define WCSDATA(x) ((wchar_t*) SDATA (x))
+extern wchar_t* to_unicode (Lisp_Object str, Lisp_Object* buf);
+extern Lisp_Object from_unicode (Lisp_Object str);
+
+/* Path conversion */
+extern Lisp_Object conv_filename_to_w32_unicode (Lisp_Object in,
+                                                 int absolute_p);
+extern Lisp_Object conv_filename_from_w32_unicode (const wchar_t* in,
+                                                   int absolute_p);
+EXFUN (Fcygwin_convert_path_to_windows, 2);
+EXFUN (Fcygwin_convert_path_from_windows, 2);
+
+/* Functions normally provided by the platform C runtime */
+extern BYTE* _mbsinc (const BYTE* current);
+extern unsigned _mbsnextc (const BYTE* current);
+extern BYTE* _mbsncpy (BYTE* dest, const BYTE* src, size_t count);
+
+/* Misc */
+extern void syms_of_cygw32 (void);
+extern char * w32_strerror (int error_no);
+
+#endif /* CYGW32_H */

=== added file 'src/w32select.h'
--- src/w32select.h	1970-01-01 00:00:00 +0000
+++ src/w32select.h	2011-07-17 15:45:14 +0000
@@ -0,0 +1,30 @@
+/* Selection processing for Emacs on the Microsoft W32 API.
+
+Copyright (C) 1993-1994, 2001-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/>.  */
+
+#ifndef W32SELECT_H
+#define W32SELECT_H
+#include <windows.h>
+
+#define HAVE_W32SELECT 1
+
+extern void syms_of_w32select (void);
+extern void globals_of_w32select (void);
+extern void term_w32select (void);
+
+#endif


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

^ permalink raw reply	[flat|nested] 51+ messages in thread

* Re: [PATCH] system-type cygwin with window-system w32
  2011-07-18  0:01 [PATCH] system-type cygwin with window-system w32 Daniel Colascione
  2011-07-18  0:06 ` Daniel Colascione
@ 2011-07-18  6:13 ` Eli Zaretskii
  2011-07-18  6:29   ` Daniel Colascione
  2011-07-18  6:53 ` Eli Zaretskii
                   ` (4 subsequent siblings)
  6 siblings, 1 reply; 51+ messages in thread
From: Eli Zaretskii @ 2011-07-18  6:13 UTC (permalink / raw)
  To: Daniel Colascione; +Cc: emacs-devel

> Date: Sun, 17 Jul 2011 17:01:38 -0700
> From: Daniel Colascione <dan.colascione@gmail.com>
> 
> This patch makes it possible to use the NT GUI with a Cygwin core Emacs.

Thanks.  A few comments:

> === 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

Why did you need to change filemode.c?  Does it have anything to do
with Cygwin on w32?

> === 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

These look just white-space changes.  If so, please leave them out of
the patch.

> +(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>"
> +))

What is this (and related) stuff about?  Why do you need to use HTML
wrt the clipboard?

> +#define t(...)                                          \
> +    ({                                                  \
> +      fprintf (stderr, "T:%s:%u: ",                     \
> +               __FUNCTION__, __LINE__);                 \
> +      fprintf (stderr, __VA_ARGS__);                    \
> +      fputc ('\n', stderr);                             \
> +    })
> +

What is this stuff about?

> -/* Equivalent of strerror for W32 error codes.  */
> -char *
> -w32_strerror (int error_no)
> -{
> -  static char buf[500];

I don't like the idea of moving this to w32fns.c, because it doesn't
belong there.  Can you come up with an alternative idea?

> +#if EMACSDEBUG
> +const char*
> +w32_name_of_message (UINT msg)

Why is this needed?

> +      
> +      /* DebPrint (("w32_msg_pump: %s time:%u\n", */
> +      /*            w32_name_of_message (msg.message), msg.time)); */
> +      

Can this be removed?  These DebPrint messages are a PITA when
debugging, so if it isn't absolutely necessary, let's not add new
ones.

This is based on reviewing only a part of the patch, I will have more
later.  The patch is very large and complicated, and the lack of a
ChangeLog that describes the changes, particularly those which move
code between different files, does not help...



^ permalink raw reply	[flat|nested] 51+ messages in thread

* Re: [PATCH] system-type cygwin with window-system w32
  2011-07-18  6:13 ` Eli Zaretskii
@ 2011-07-18  6:29   ` Daniel Colascione
  2011-07-18  8:53     ` Eli Zaretskii
                       ` (2 more replies)
  0 siblings, 3 replies; 51+ messages in thread
From: Daniel Colascione @ 2011-07-18  6:29 UTC (permalink / raw)
  To: Eli Zaretskii; +Cc: emacs-devel

[-- Attachment #1: Type: text/plain, Size: 3617 bytes --]

Hi Eli,

Thanks for reviewing the patch.

On 7/17/11 11:13 PM, Eli Zaretskii wrote:
> Why did you need to change filemode.c?  Does it have anything to do
> with Cygwin on w32?

S_ISCTG and such aren't being defined under Cygwin, causing compilation
errors.  There's probably a better way to deal with the underlying problem.

> What is this (and related) stuff about?  Why do you need to use HTML
> wrt the clipboard?

Windows uses HTML as a data interchange format --- supporting it as a
clipboard format allows formatting to be preserved in pastes into other
programs.  This code could easily be structured as a separate package,
however, and I'll end up doing that.

See http://msdn.microsoft.com/en-us/library/ms649015%28v=vs.85%29.aspx

>> -/* Equivalent of strerror for W32 error codes.  */
>> -char *
>> -w32_strerror (int error_no)
>> -{
>> -  static char buf[500];
>
> I don't like the idea of moving this to w32fns.c, because it doesn't
> belong there.  Can you come up with an alternative idea?

The fundamental problem is that we now have two Windows platforms:
WINDOWSNT and (CYGWIN && HAVE_NTGUI).  The common code has to live
somewhere; with my patch, we only build w32.o in the NTEMACS case
because w32.c contains mostly compatibility wrappers; the
non-compatibility portions I moved to w32fns.c, which we compile in both
cases.  Cygwin-NT-specific code goes in the new file cygw32.c.

Another option would be to further refactor the Win32 code into distinct
and explicit WINDOWSNT and HAVE_NTGUI files and introduce common headers
for common functionality.  This approach would involve even more code
movement, however, which is why I initially avoided it.

>> +#define t(...)                                          \
>> +    ({                                                  \
>> +      fprintf (stderr, "T:%s:%u: ",                     \
>> +               __FUNCTION__, __LINE__);                 \
>> +      fprintf (stderr, __VA_ARGS__);                    \
>> +      fputc ('\n', stderr);                             \
>> +    })
>> +
> 
> What is this stuff about?

Debug scaffolding --- in this case, generally useful, I think, at least
as a replacement for the numerous bespoke tracing macros scattered
everywhere in the code.

> 
>> -/* Equivalent of strerror for W32 error codes.  */
>> -char *
>> -w32_strerror (int error_no)
>> -{
>> -  static char buf[500];
> 
> I don't like the idea of moving this to w32fns.c, because it doesn't
> belong there.  Can you come up with an alternative idea?
> 
>> +#if EMACSDEBUG
>> +const char*
>> +w32_name_of_message (UINT msg)
> 
> Why is this needed?

Debug scaffolding.

>> +      
>> +      /* DebPrint (("w32_msg_pump: %s time:%u\n", */
>> +      /*            w32_name_of_message (msg.message), msg.time)); */
>> +      
> 
> Can this be removed?  These DebPrint messages are a PITA when
> debugging, so if it isn't absolutely necessary, let's not add new
> ones.

Sure.  I'd actually prefer, though, to leave the existing tracing, but
move it all to a common macro so that the debug spam is easier to
disable and enable as needed.

> 
> This is based on reviewing only a part of the patch, I will have more
> later.  The patch is very large and complicated, and the lack of a
> ChangeLog that describes the changes, particularly those which move
> code between different files, does not help...

Of course. It's a work in progress --- a first stab, really.  Once I
clean up the code a bit, I'll put it into a form that's easier to consume.


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

^ permalink raw reply	[flat|nested] 51+ messages in thread

* Re: [PATCH] system-type cygwin with window-system w32
  2011-07-18  0:01 [PATCH] system-type cygwin with window-system w32 Daniel Colascione
  2011-07-18  0:06 ` Daniel Colascione
  2011-07-18  6:13 ` Eli Zaretskii
@ 2011-07-18  6:53 ` Eli Zaretskii
  2011-07-18  7:01   ` Daniel Colascione
  2011-07-18  8:42 ` Eli Zaretskii
                   ` (3 subsequent siblings)
  6 siblings, 1 reply; 51+ messages in thread
From: Eli Zaretskii @ 2011-07-18  6:53 UTC (permalink / raw)
  To: Daniel Colascione; +Cc: emacs-devel

Could you please explain this part of the patch:

>    /* 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);

AFAICT, to_unicode encodes the file name in UTF-16.  If so, this will
not work in the native Windows build, because it does not use Unicode
APIs for file names.  In the original code, ENCODE_FILE would use the
ANSI encoding, not UTF-16.  So, unless I'm missing something, the
replacement is not equivalent to the original, and could break the
native build.

If my analysis is correct, could you please explain the rationale for
this change?



^ permalink raw reply	[flat|nested] 51+ messages in thread

* Re: [PATCH] system-type cygwin with window-system w32
  2011-07-18  6:53 ` Eli Zaretskii
@ 2011-07-18  7:01   ` Daniel Colascione
  2011-07-18  9:04     ` Eli Zaretskii
  0 siblings, 1 reply; 51+ messages in thread
From: Daniel Colascione @ 2011-07-18  7:01 UTC (permalink / raw)
  To: Eli Zaretskii; +Cc: emacs-devel

[-- Attachment #1: Type: text/plain, Size: 2502 bytes --]

On 7/17/11 11:53 PM, Eli Zaretskii wrote:
> Could you please explain this part of the patch:
> 
>>    /* 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);
> 
> AFAICT, to_unicode encodes the file name in UTF-16.  If so, this will
> not work in the native Windows build, because it does not use Unicode
> APIs for file names.

Not today, no.

> In the original code, ENCODE_FILE would use the
> ANSI encoding, not UTF-16.  So, unless I'm missing something, the
> replacement is not equivalent to the original, and could break the
> native build.

Yes, the change would make Emacs Unicode-only --- but every Windows OS
in common use supports unicode.  Why would requiring unicode support be
a problem? IIUC, Unicode is strictly a superset of all the single-byte
encoding schemes supported by Windows.

> If my analysis is correct, could you please explain the rationale for
> this change?

The change needed to be made anyway --- we need to translate between NT
and Cygwin paths now --- so why not transition to unicode at the same
time?  (I want to stub out the path conversion functions for native NT
builds.)


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

^ permalink raw reply	[flat|nested] 51+ messages in thread

* Re: [PATCH] system-type cygwin with window-system w32
  2011-07-18  0:01 [PATCH] system-type cygwin with window-system w32 Daniel Colascione
                   ` (2 preceding siblings ...)
  2011-07-18  6:53 ` Eli Zaretskii
@ 2011-07-18  8:42 ` Eli Zaretskii
  2011-07-18 10:33   ` Daniel Colascione
  2011-07-18 15:54 ` Stefan Monnier
                   ` (2 subsequent siblings)
  6 siblings, 1 reply; 51+ messages in thread
From: Eli Zaretskii @ 2011-07-18  8:42 UTC (permalink / raw)
  To: Daniel Colascione; +Cc: emacs-devel

> 
> === 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);

Why was it necessary to remove these prototypes? These functions are
still called outside of the source file where they are defined,
AFAICT.

> -  if (!hprevinst)
> -    {
> -      w32_init_class (hinst);
> -    }
> +  w32_init_class (hinst);

Not sure why the test was deleted here.  Can you explain?

> -      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");

Any changes that use the Unicode APIs unconditionally should be tested
on Windows 9X before we adopt them.  I would like to avoid the kind of
breakage that we fixed a couple of months ago (wrt to font APIs)
through a non-trivial effort which needed a motivated and able
individual with access to W9X.  We were lucky to have such help in
that case, but we need to avoid pushing that luck.

So changes like that need (a) a very good reason, and (b) given that
such a reason is provided, some kind of verification that the result
still works on W9X, where one needs a special DLL to have Unicode
support.

> -/* 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;

Why was this removed?

> +    file_details.lpstrFilter = WCSDATA (filter);

What is WCSDATA?  I don't see it defined anywhere.  Apologies if I'm
blind.

> -	file = DECODE_FILE (build_string (filename));
> +        filename = conv_filename_from_w32_unicode (filename_buf, 0);

AFAICS, conv_filename_from_w32_unicode will only be compiled on
Cygwin, so it cannot be used unconditionally here.  (And likewise with
from_unicode and to_unicode?)

> -	  _snprintf (buffer, 16, "%d", system_status.BatteryLifePercent);
> +	  snprintf (buffer, 16, "%d", system_status.BatteryLifePercent);

This breaks the non-MinGW build, I think.  The MS library doesn't have
snprintf, at least not in all versions we support.

> +#if CYGWIN
> +
> +#endif

???

> === 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

I understand that these changes are an enhancement for clipboard
operations.  If so, they should be in a separate changeset, and I
would appreciate some discussion of the rationale and the
implementation strategy to go with it.

Still, a few comments.

> +  htext = GlobalAlloc (GMEM_MOVEABLE | GMEM_DDESHARE, bytes);
> +  if (!htext)
> +    error ("GlobalAlloc: %s", w32_strerror (GetLastError ()));

Such cryptic error messages are not useful, because users are not
required to know what GlobalAlloc is.  Please modify the text to be
more palatable to mere mortals (here and elsewhere in this part of the
patch).

> +static void
> +wait_for_clipboard_render ()
> +{
> +  MSG msg;
> +  while (GetMessage (&msg, clipboard_owner,
> +                     WM_EMACS_CLIPBOARD_DATA,
> +                     WM_EMACS_CLIPBOARD_DATA))
> +    {

I'm not sure it is a good idea to call GetMessage in yet another
thread.  Won't this get in the way of the main message pump?  How
would we ensure they are synchronized and not step on each other's
toes?

> +      if (msg.message != WM_EMACS_CLIPBOARD_DATA) {
> +        eassert (0);

Did you really intend to crash when a message other that
WM_EMACS_CLIPBOARD_DATA is received?  Why?

> -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);

AFAICT, this portion of the code is just deleted.  Will the
replacement be 100% compatible, including on Windows 9X (where AFAIK
the clipboard does not work in UTF-16)?

> +  return make_number (RegisterClipboardFormatW (to_unicode (format,

Once again: using Unicode APIs should be tested on W9X first.

>        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;

What is this part about?

> -#ifdef F_SETOWN
> -  fcntl (connection, F_SETOWN, getpid ());
> -#endif /* ! defined (F_SETOWN) */
> -
> -#ifdef SIGIO
> -  if (interrupt_input)
> -    init_sigio (connection);
> -#endif /* ! defined (SIGIO) */

Are you sure these are never used in any Windows build?

> +#ifdef USE_W32_SELECT

Is this supposed to be defined only in the Cygwin build?  If not, then
could you please explain why there's a need for two `select' calls?

> +#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]);

Unless this is for Cygwin only, there should be #ifdef's for using
`pipe', F_SETFD, and FD_CLOEXEC.  If it is for Cygwin only (which I
understand is the case), why use USE_W32_SELECT and not a
Cygwin-specific macro?

> +#endif /* USE_W32_SELET */
                     ^^^^^
A typo.

> +  Fprovide (intern_c_string ("w32"), Qnil);

I think this should be for Cygwin only, and its name should reflect
that.  If you think otherwise, I'd appreciate any arguments you have
for making it a general-purpose feature.

Finally, this will eventually need additions to NEWS and perhaps to
the user manual.

Thanks again for working on this.



^ permalink raw reply	[flat|nested] 51+ messages in thread

* Re: [PATCH] system-type cygwin with window-system w32
  2011-07-18  6:29   ` Daniel Colascione
@ 2011-07-18  8:53     ` Eli Zaretskii
  2011-07-18 10:10       ` Daniel Colascione
  2011-07-18 13:55     ` Jason Rumney
  2011-07-18 16:13     ` Paul Eggert
  2 siblings, 1 reply; 51+ messages in thread
From: Eli Zaretskii @ 2011-07-18  8:53 UTC (permalink / raw)
  To: Daniel Colascione; +Cc: emacs-devel

> Date: Sun, 17 Jul 2011 23:29:19 -0700
> From: Daniel Colascione <dan.colascione@gmail.com>
> CC: emacs-devel@gnu.org
> 
> On 7/17/11 11:13 PM, Eli Zaretskii wrote:
> > Why did you need to change filemode.c?  Does it have anything to do
> > with Cygwin on w32?
> 
> S_ISCTG and such aren't being defined under Cygwin, causing compilation
> errors.  There's probably a better way to deal with the underlying problem.

Yes, the files in lib/sys_stat.in.h is supposed to do that already.
I'm curious why it didn't work for you.

> > What is this (and related) stuff about?  Why do you need to use HTML
> > wrt the clipboard?
> 
> Windows uses HTML as a data interchange format --- supporting it as a
> clipboard format allows formatting to be preserved in pastes into other
> programs.  This code could easily be structured as a separate package,
> however, and I'll end up doing that.

Yes, let's have this as a separate changeset.

> > I don't like the idea of moving this to w32fns.c, because it doesn't
> > belong there.  Can you come up with an alternative idea?
> 
> The fundamental problem is that we now have two Windows platforms:
> WINDOWSNT and (CYGWIN && HAVE_NTGUI).  The common code has to live
> somewhere; with my patch, we only build w32.o in the NTEMACS case
> because w32.c contains mostly compatibility wrappers; the
> non-compatibility portions I moved to w32fns.c, which we compile in both
> cases.  Cygwin-NT-specific code goes in the new file cygw32.c.
> 
> Another option would be to further refactor the Win32 code into distinct
> and explicit WINDOWSNT and HAVE_NTGUI files and introduce common headers
> for common functionality.  This approach would involve even more code
> movement, however, which is why I initially avoided it.

I'd prefer a separate file common to w2 and Cygwin-on-w32, if that's
needed.  w32fns.c tries to be as similar to xfns.c as possible, so
putting there stuff that's not relevant would be a disadvantage.

> >> +#define t(...)                                          \
> >> +    ({                                                  \
> >> +      fprintf (stderr, "T:%s:%u: ",                     \
> >> +               __FUNCTION__, __LINE__);                 \
> >> +      fprintf (stderr, __VA_ARGS__);                    \
> >> +      fputc ('\n', stderr);                             \
> >> +    })
> >> +
> > 
> > What is this stuff about?
> 
> Debug scaffolding --- in this case, generally useful, I think, at least
> as a replacement for the numerous bespoke tracing macros scattered
> everywhere in the code.

Fine, but (a) please see if there's no macro already available that
can be used instead; and (b) let's have this a separate changeset.

> >> +      /* DebPrint (("w32_msg_pump: %s time:%u\n", */
> >> +      /*            w32_name_of_message (msg.message), msg.time)); */
> >> +      
> > 
> > Can this be removed?  These DebPrint messages are a PITA when
> > debugging, so if it isn't absolutely necessary, let's not add new
> > ones.
> 
> Sure.  I'd actually prefer, though, to leave the existing tracing, but
> move it all to a common macro so that the debug spam is easier to
> disable and enable as needed.

Fine with me.

> > This is based on reviewing only a part of the patch, I will have more
> > later.  The patch is very large and complicated, and the lack of a
> > ChangeLog that describes the changes, particularly those which move
> > code between different files, does not help...
> 
> Of course. It's a work in progress --- a first stab, really.  Once I
> clean up the code a bit, I'll put it into a form that's easier to consume.

My point was that there are several issues here that need to be
discussed before you invest too much energy into them.  So please
consider starting these discussion sooner rather than later, and the
additional information I didn't find in the ChangeLog would be
instrumental at that time.

TIA



^ permalink raw reply	[flat|nested] 51+ messages in thread

* Re: [PATCH] system-type cygwin with window-system w32
  2011-07-18  7:01   ` Daniel Colascione
@ 2011-07-18  9:04     ` Eli Zaretskii
  2011-07-18  9:41       ` Daniel Colascione
  2011-07-18 13:31       ` Jason Rumney
  0 siblings, 2 replies; 51+ messages in thread
From: Eli Zaretskii @ 2011-07-18  9:04 UTC (permalink / raw)
  To: Daniel Colascione; +Cc: emacs-devel

> Date: Mon, 18 Jul 2011 00:01:30 -0700
> From: Daniel Colascione <dan.colascione@gmail.com>
> CC: emacs-devel@gnu.org
> 
> > AFAICT, to_unicode encodes the file name in UTF-16.  If so, this will
> > not work in the native Windows build, because it does not use Unicode
> > APIs for file names.
> 
> Not today, no.
> 
> > In the original code, ENCODE_FILE would use the
> > ANSI encoding, not UTF-16.  So, unless I'm missing something, the
> > replacement is not equivalent to the original, and could break the
> > native build.
> 
> Yes, the change would make Emacs Unicode-only --- but every Windows OS
> in common use supports unicode.  Why would requiring unicode support be
> a problem?

Two reasons: (1) we still support running Emacs on Windows 9X, where
the Unicode file APIs are (AFAIK) not supported, even if unicows.dll
is installed; and (2) going Unicode means that all the existing APIs
used by Emacs will have to be switched to Unicode.  The latter part is
a formidable job, involving at the very least reviewing all the
file-related code in w32*.c for compatibility.  I'm quite sure a large
part of that will break, e.g. because it uses `char *' instead of
`wchar *' or TCHAR etc.  In addition, Posix-like interfaces will need
to be amended to use their wide-character counterparts, or emulated
with low-level Win32 APIs.  Non-file APIs are likely to need similar
changes as well, because file names are sometimes read or written from
and to other kinds of objects, such as the Registry.

I'm all for such a migration, but it's a very large job, and making
the change in some small part of the code will simply break Emacs,
rather than improve it.

> The change needed to be made anyway --- we need to translate between NT
> and Cygwin paths now --- so why not transition to unicode at the same
> time?

See above: it's a much larger job than that.  Witness how much time it
took Cygwin, with dedicated developers, to make this migration.



^ permalink raw reply	[flat|nested] 51+ messages in thread

* Re: [PATCH] system-type cygwin with window-system w32
  2011-07-18  9:04     ` Eli Zaretskii
@ 2011-07-18  9:41       ` Daniel Colascione
  2011-07-18 10:10         ` Eli Zaretskii
  2011-07-18 13:31       ` Jason Rumney
  1 sibling, 1 reply; 51+ messages in thread
From: Daniel Colascione @ 2011-07-18  9:41 UTC (permalink / raw)
  To: Eli Zaretskii; +Cc: emacs-devel

[-- Attachment #1: Type: text/plain, Size: 778 bytes --]

On 7/18/11 2:04 AM, Eli Zaretskii wrote:
>> Yes, the change would make Emacs Unicode-only --- but every Windows OS
>> in common use supports unicode.  Why would requiring unicode support be
>> a problem?
> 
> Two reasons: (1) we still support running Emacs on Windows 9X, where
> the Unicode file APIs are (AFAIK) not supported, even if unicows.dll
> is installed

The 9X family is long dead.  There's no vendor or driver support;  I
don't know how I would even go about testing 9X support.  We shouldn't
forgo technical improvement on the account of a dead system.

> and (2) going Unicode means that all the existing APIs
> used by Emacs will have to be switched to Unicode. 

Why not do it piecemeal?  We can directly call Unicode APIs where
appropriate.


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

^ permalink raw reply	[flat|nested] 51+ messages in thread

* Re: [PATCH] system-type cygwin with window-system w32
  2011-07-18  9:41       ` Daniel Colascione
@ 2011-07-18 10:10         ` Eli Zaretskii
  2011-07-18 10:49           ` Daniel Colascione
  0 siblings, 1 reply; 51+ messages in thread
From: Eli Zaretskii @ 2011-07-18 10:10 UTC (permalink / raw)
  To: Daniel Colascione; +Cc: emacs-devel

> Date: Mon, 18 Jul 2011 02:41:08 -0700
> From: Daniel Colascione <dan.colascione@gmail.com>
> CC: emacs-devel@gnu.org
> 
> The 9X family is long dead.

Not in the 3rd world, where there are still many machines running it.
Or so we were told last time this issue popped up.  RMS personally
asked not to drop W9X on this behalf.

> We shouldn't forgo technical improvement on the account of a dead
> system.

I didn't say we should stop the improvement.  You will find quite a
few Emacs features that use APIs which are unavailable on W9X.  But
they do it in a way that lets Emacs still run on W9X and produce
reasonable results, be that some fallback or just plain message saying
that this nifty feature is not available.  (Of course, disabling menus
or file access cannot use the latter fire escape, because they are too
basic and without them Emacs would become unusable.)

So this is the requirement: use the new APIs, but test safely for
their availability and provide fallbacks for when they are not
available.  If the fallback does not use Unicode APIs, then it does
not even need to be specifically tested on W9X, if that specific API
is documented to exist on W9X.

> > and (2) going Unicode means that all the existing APIs
> > used by Emacs will have to be switched to Unicode. 
> 
> Why not do it piecemeal?  We can directly call Unicode APIs where
> appropriate.

I'm not sure I understand the details of your proposal.  The situation
that worries me is this:

  . user uses the file dialog to return a file name in UTF-16 which
    includes characters not available in the system codepage (this is
    quite possible on NTFS)

  . the file name is passed to file-attributes or insert-file-name or
    some other primitive that accepts file names

  . if the underlying file APIs used by these primitives (`stat',
    `open', `opendir', etc.) are not Unicode, these primitives will
    fail in weird ways, like "file does not exist" etc., that would
    just confuse the user.



^ permalink raw reply	[flat|nested] 51+ messages in thread

* Re: [PATCH] system-type cygwin with window-system w32
  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
  0 siblings, 2 replies; 51+ messages in thread
From: Daniel Colascione @ 2011-07-18 10:10 UTC (permalink / raw)
  To: Eli Zaretskii; +Cc: emacs-devel

[-- Attachment #1: Type: text/plain, Size: 2567 bytes --]

On 7/18/11 1:53 AM, Eli Zaretskii wrote:
>> S_ISCTG and such aren't being defined under Cygwin, causing compilation
>> errors.  There's probably a better way to deal with the underlying problem.
> 
> Yes, the files in lib/sys_stat.in.h is supposed to do that already.
> I'm curious why it didn't work for you.

I didn't look into why it didn't work.  I can do some investigation, but
I'm not very familiar with how gnulib stuff actually works.

> I'd prefer a separate file common to w2 and Cygwin-on-w32, if that's
> needed.  w32fns.c tries to be as similar to xfns.c as possible, so
> putting there stuff that's not relevant would be a disadvantage.

Fair enough.  I'll move some code around; would you object to having
w32.c, cygw32.c, and ntw32.c and corresponding headers?

>>>> +#define t(...)                                          \
>>>> +    ({                                                  \
>>>> +      fprintf (stderr, "T:%s:%u: ",                     \
>>>> +               __FUNCTION__, __LINE__);                 \
>>>> +      fprintf (stderr, __VA_ARGS__);                    \
>>>> +      fputc ('\n', stderr);                             \
>>>> +    })
>>>> +
>>>
>>> What is this stuff about?
>>
>> Debug scaffolding --- in this case, generally useful, I think, at least
>> as a replacement for the numerous bespoke tracing macros scattered
>> everywhere in the code.
> 
> Fine, but (a) please see if there's no macro already available that
> can be used instead; 

I didn't see anything suitable.

and (b) let's have this a separate changeset.

Fair enough, though I'll keep it in the patch for now just to make
debugging easier.  (gdb under Cygwin is problematic at best, IME.)

>>> This is based on reviewing only a part of the patch, I will have more
>>> later.  The patch is very large and complicated, and the lack of a
>>> ChangeLog that describes the changes, particularly those which move
>>> code between different files, does not help...
>>
>> Of course. It's a work in progress --- a first stab, really.  Once I
>> clean up the code a bit, I'll put it into a form that's easier to consume.
> 
> My point was that there are several issues here that need to be
> discussed before you invest too much energy into them.  So please
> consider starting these discussion sooner rather than later, and the
> additional information I didn't find in the ChangeLog would be
> instrumental at that time.

Sure, but there's also something to be said for building a prototype as
well.


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

^ permalink raw reply	[flat|nested] 51+ messages in thread

* Re: [PATCH] system-type cygwin with window-system w32
  2011-07-18  8:42 ` Eli Zaretskii
@ 2011-07-18 10:33   ` Daniel Colascione
  2011-07-18 16:29     ` Eli Zaretskii
  0 siblings, 1 reply; 51+ messages in thread
From: Daniel Colascione @ 2011-07-18 10:33 UTC (permalink / raw)
  To: Eli Zaretskii; +Cc: emacs-devel

[-- Attachment #1: Type: text/plain, Size: 10356 bytes --]

On 7/18/11 1:42 AM, Eli Zaretskii wrote:
>>
>> === 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);
> 
> Why was it necessary to remove these prototypes? These functions are
> still called outside of the source file where they are defined,
> AFAICT.

I moved these prototypes to w32select.h.

>> -  if (!hprevinst)
>> -    {
>> -      w32_init_class (hinst);
>> -    }
>> +  w32_init_class (hinst);
> 
> Not sure why the test was deleted here.  Can you explain?

hprevinst isn't trivially available under Cygwin, and I don't see what
the test is buying us: class registration is inexpensive.

>> -      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");
> 
> Any changes that use the Unicode APIs unconditionally should be tested
> on Windows 9X...
> So changes like that need (a) a very good reason, and (b) given that
> such a reason is provided, some kind of verification that the result
> still works on W9X, where one needs a special DLL to have Unicode
> support.

Let's confine this discussion to the other subthread.

>> -/* 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;
> 
> Why was this removed?

Once we unconditionally use unicode APIs, we don't need to lie about the
structure size anymore. NEWOPENFILENAME's only purpose was to fill in
for a newer version of OPENFILENAME.

>> +    file_details.lpstrFilter = WCSDATA (filter);
> 
> What is WCSDATA?  I don't see it defined anywhere.  Apologies if I'm
> blind.

It's in cygw32.h.

>> -	file = DECODE_FILE (build_string (filename));
>> +        filename = conv_filename_from_w32_unicode (filename_buf, 0);
> 
> AFAICS, conv_filename_from_w32_unicode will only be compiled on
> Cygwin, so it cannot be used unconditionally here.  (And likewise with
> from_unicode and to_unicode?)

Correct; this disparity is one reason I'm confident I broke the NT
build. :-)  to_unicode and from_unicode, I'll put in common w32 code.
The NT build will have no-op versions of the conv_filename_ functions,
whereas the Cygwin versions will use the Cygwin path functions.

>> -	  _snprintf (buffer, 16, "%d", system_status.BatteryLifePercent);
>> +	  snprintf (buffer, 16, "%d", system_status.BatteryLifePercent);
> 
> This breaks the non-MinGW build, I think.  The MS library doesn't have
> snprintf, at least not in all versions we support.

See above; I plan to just #define away the difference on the NT build.

> 
>> +#if CYGWIN
>> +
>> +#endif
> 
> ???

Oops.

> 
>> === 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
> 
> I understand that these changes are an enhancement for clipboard
> operations.  If so, they should be in a separate changeset, and I
> would appreciate some discussion of the rationale and the
> implementation strategy to go with it.

The clipboard changes are integral to the cygwin-w32 port; without the
new clipboard implementations, applications that try to paste
Emacs-owned clipboard data will hang until the Emacs main thread begins
pumping messages, which will usually happen only when the user actually
interacts with Emacs somehow.

> 
> Still, a few comments.
> 
>> +  htext = GlobalAlloc (GMEM_MOVEABLE | GMEM_DDESHARE, bytes);
>> +  if (!htext)
>> +    error ("GlobalAlloc: %s", w32_strerror (GetLastError ()));
> 
> Such cryptic error messages are not useful, because users are not
> required to know what GlobalAlloc is.  Please modify the text to be
> more palatable to mere mortals (here and elsewhere in this part of the
> patch).

Well, it's better than what we used to do much of the time, which was to
not check error codes at all.  How would you suggest changing the
messages?  We don't know any better than the user how to interpret what
went wrong, but it's important to communicate that there was a problem,
and if we do that, we might as well provide relevant information.

>> +static void
>> +wait_for_clipboard_render ()
>> +{
>> +  MSG msg;
>> +  while (GetMessage (&msg, clipboard_owner,
>> +                     WM_EMACS_CLIPBOARD_DATA,
>> +                     WM_EMACS_CLIPBOARD_DATA))
>> +    {
> 
> I'm not sure it is a good idea to call GetMessage in yet another
> thread.  Won't this get in the way of the main message pump?  How
> would we ensure they are synchronized and not step on each other's
> toes?

I'll have to add a comment explaining what's going on here.  In the
meantime: the main thread doesn't usually pump messages because it's
blocked on select(2) instead.  If we don't pump messages for the
clipboard window, other applications hang when they try to interact with
Emacs-owned clipboard content.  Because win32 windows have thread
affinity, most interactions with a particular window have to happen on
the same thread, so it makes sense to hoist the clipboard infrastructure
to its own thread.

We could just the UI thread for this purpose instead of a dedicated one,
but that too tightly couples the win32 clipboard and HAVE_NTGUI, I
think.  What if I want to create a GUI-less Emacs that can nevertheless
can interact with the system clipboard?

>> +      if (msg.message != WM_EMACS_CLIPBOARD_DATA) {
>> +        eassert (0);
> 
> Did you really intend to crash when a message other that
> WM_EMACS_CLIPBOARD_DATA is received?  Why?

Yes.  Because the call to GetMessage above is predicated on
WM_EMACS_CLIPBOARD_DATA, we should never pull a message of a different
type out of the queue.  The purpose of this loop is to block and wait
for the main thread to render some clipboard content, and we shouldn't
be doing anything else in the meantime.

> 
>> -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);
> 
> AFAICT, this portion of the code is just deleted.  Will the
> replacement be 100% compatible, including on Windows 9X (where AFAIK
> the clipboard does not work in UTF-16)?

Let's have this discussion in the other subthread.

>>        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;
> 
> What is this part about?

The new clipboard uses WM_EMACS_MT_CALL (indirectly via
call_on_main_thread) to run the Lisp code responsible for actually
rendering clipboard content.  The jump through the atimer code ensures
that we're running in a sane place (i.e., in a place that any other
filter could run) instead of wherever we happen to have received an event.

>> -#ifdef F_SETOWN
>> -  fcntl (connection, F_SETOWN, getpid ());
>> -#endif /* ! defined (F_SETOWN) */
>> -
>> -#ifdef SIGIO
>> -  if (interrupt_input)
>> -    init_sigio (connection);
>> -#endif /* ! defined (SIGIO) */
> 
> Are you sure these are never used in any Windows build?

The section was #if 0ed out and it wouldn't compile anyway ---
connection doesn't exist in w32term.c.  This block of code was a
holdover from xterm.c, and we shouldn't keep it around.

>> +#ifdef USE_W32_SELECT
> 
> Is this supposed to be defined only in the Cygwin build?  If not, then
> could you please explain why there's a need for two `select' calls?

We use USE_W32_SELECT to compile in the self-pipe wakeup mechanism.
When the Cygwin bug I mentioned is fixed and signals begin working
again, we can solve the same problem more cleanly (and with the normal
select(2)) using signals, so I think it makes sense to isolate the
workaround using its own preprocessor macro.

>> +#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]);
> 
> Unless this is for Cygwin only, there should be #ifdef's for using
> `pipe', F_SETFD, and FD_CLOEXEC.  If it is for Cygwin only (which I
> understand is the case), why use USE_W32_SELECT and not a
> Cygwin-specific macro?

USE_W32_SELECT is only necessary on Unixish systems like Cygwin anyway.

>> +#endif /* USE_W32_SELET */
>                      ^^^^^
> A typo.

Thanks.

>> +  Fprovide (intern_c_string ("w32"), Qnil);
> 
> I think this should be for Cygwin only, and its name should reflect
> that.  If you think otherwise, I'd appreciate any arguments you have
> for making it a general-purpose feature.
> 
> Finally, this will eventually need additions to NEWS and perhaps to
> the user manual.

Eventually, sure.



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

^ permalink raw reply	[flat|nested] 51+ messages in thread

* Re: [PATCH] system-type cygwin with window-system w32
  2011-07-18 10:10         ` Eli Zaretskii
@ 2011-07-18 10:49           ` Daniel Colascione
  2011-07-18 11:22             ` Juanma Barranquero
                               ` (3 more replies)
  0 siblings, 4 replies; 51+ messages in thread
From: Daniel Colascione @ 2011-07-18 10:49 UTC (permalink / raw)
  To: Eli Zaretskii; +Cc: emacs-devel

[-- Attachment #1: Type: text/plain, Size: 3678 bytes --]

On 7/18/11 3:10 AM, Eli Zaretskii wrote:
>> Date: Mon, 18 Jul 2011 02:41:08 -0700
>> From: Daniel Colascione <dan.colascione@gmail.com>
>> CC: emacs-devel@gnu.org
>>
>> The 9X family is long dead.
> 
> Not in the 3rd world, where there are still many machines running it.
> Or so we were told last time this issue popped up.  RMS personally
> asked not to drop W9X on this behalf.

I don't recall that discussion.  Can we reopen it?  According to [1],
Windows 98 has a market share of 0.03%.  I suspect there are more VMS
users, and we dropped support for that OS.

Besides: shouldn't we be encouraging computationally indigent third
world users to switch to use free operating systems instead?  9X users
have no protection against security vulnerabilities.

>> We shouldn't forgo technical improvement on the account of a dead
>> system.
> 
> I didn't say we should stop the improvement.  You will find quite a
> few Emacs features that use APIs which are unavailable on W9X.  But
> they do it in a way that lets Emacs still run on W9X and produce
> reasonable results, be that some fallback or just plain message saying
> that this nifty feature is not available.  (Of course, disabling menus
> or file access cannot use the latter fire escape, because they are too
> basic and without them Emacs would become unusable.)

These fallbacks involve significant complexity, and they're
lightly-tested at best.  I'd prefer to eliminate the complexity involved
in supporting these alleged 9X users by simply dropping the support.
Moving to all-Unicode APIs would improve Emacs' internationalization
support _and_ simplify the codebase.

>>> and (2) going Unicode means that all the existing APIs
>>> used by Emacs will have to be switched to Unicode. 
>>
>> Why not do it piecemeal?  We can directly call Unicode APIs where
>> appropriate.
> 
> I'm not sure I understand the details of your proposal.  The situation
> that worries me is this:
> 
>   . user uses the file dialog to return a file name in UTF-16 which
>     includes characters not available in the system codepage (this is
>     quite possible on NTFS)
> 
>   . the file name is passed to file-attributes or insert-file-name or
>     some other primitive that accepts file names

It'd be straightforward to locate all calls to CreateFile and such and
update them to use unicode APIs.  Cygwin supports UTF-8 filenames natively.

But even if we don't --- why does it matter?  You can create files using
the NT native API that can't be opened using Win32 calls; it doesn't
cause a problem in practice.  Likewise, users who have strange
filesnames might not be able to use them with all Emacs features right
away, but they'll be able to work with more reasonable filenames just as
they did before.

>   . if the underlying file APIs used by these primitives (`stat',
>     `open', `opendir', etc.) are not Unicode, these primitives will
>     fail in weird ways, like "file does not exist" etc., that would
>     just confuse the user.

I'd prefer to go all-Unicode because I don't think unencodable filenames
are common enough to warrant much concern here.  Any file users can
manipulate today, they'll be able to manipulate with a
partially-Unicodeized Emacs.

Still, if we can't do that, then as a temporary measure, we can still
use Unicode APIs (the 9X discussion notwithstanding), but as a temporary
measure, filter their results so that we reject filenames that can't be
used with the system codepage.


[1]
http://marketshare.hitslink.com/operating-system-market-share.aspx?spider=1&qprid=10&qpcal=1&qpcal=1&qptimeframe=M&qpsp=148


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

^ permalink raw reply	[flat|nested] 51+ messages in thread

* Re: [PATCH] system-type cygwin with window-system w32
  2011-07-18 10:49           ` Daniel Colascione
@ 2011-07-18 11:22             ` Juanma Barranquero
  2011-07-18 16:41             ` Eli Zaretskii
                               ` (2 subsequent siblings)
  3 siblings, 0 replies; 51+ messages in thread
From: Juanma Barranquero @ 2011-07-18 11:22 UTC (permalink / raw)
  To: Daniel Colascione; +Cc: Eli Zaretskii, emacs-devel

On Mon, Jul 18, 2011 at 12:49, Daniel Colascione
<dan.colascione@gmail.com> wrote:

> I don't recall that discussion.  Can we reopen it?  According to [1],
> Windows 98 has a market share of 0.03%.

What methodology do they use to compute that market share? Isn't hard
to believe they could miss millons of "pirated" copies of Windows 95
running on old, non-networked computers on the third world.

> I suspect there are more VMS users

I was a VMS user, and I haven't seen one for years and years (not
saying that it is not used, only not frequently). OTOH, the last
Windows 95 I saw in actual, daily use was in a client of mine, and
they retired the computer less than a year ago (and did so kicking and
screaming, I should add). It was an original, pre-SP1 Windows 95 that
had never been upgraded. FWIW, Emacs did not run on it.

    Juanma



^ permalink raw reply	[flat|nested] 51+ messages in thread

* Re: [PATCH] system-type cygwin with window-system w32
  2011-07-18  9:04     ` Eli Zaretskii
  2011-07-18  9:41       ` Daniel Colascione
@ 2011-07-18 13:31       ` Jason Rumney
  2011-07-18 13:46         ` Richard Riley
  1 sibling, 1 reply; 51+ messages in thread
From: Jason Rumney @ 2011-07-18 13:31 UTC (permalink / raw)
  To: Eli Zaretskii; +Cc: Daniel Colascione, emacs-devel

Eli Zaretskii <eliz@gnu.org> writes:

> Two reasons: (1) we still support running Emacs on Windows 9X

Emacs 25 is probably a good point to drop that though, as it is holding
us back on going completely Unicode, and the number of users is already
tiny with Emacs 23 (how long was it between the release of Emacs 23.1
and when we finally got a bug report that Emacs 23 did not work on
WIndows 98?).



^ permalink raw reply	[flat|nested] 51+ messages in thread

* Re: [PATCH] system-type cygwin with window-system w32
  2011-07-18 13:31       ` Jason Rumney
@ 2011-07-18 13:46         ` Richard Riley
  0 siblings, 0 replies; 51+ messages in thread
From: Richard Riley @ 2011-07-18 13:46 UTC (permalink / raw)
  To: emacs-devel

Jason Rumney <jasonr@gnu.org> writes:

> Eli Zaretskii <eliz@gnu.org> writes:
>
>> Two reasons: (1) we still support running Emacs on Windows 9X
>
> Emacs 25 is probably a good point to drop that though, as it is holding
> us back on going completely Unicode, and the number of users is already
> tiny with Emacs 23 (how long was it between the release of Emacs 23.1
> and when we finally got a bug report that Emacs 23 did not work on
> WIndows 98?).

Probably not popular but... be practical. Move on. They can continue to
use older emacs so they are being denied nothing. The usage is *tiny*.








^ permalink raw reply	[flat|nested] 51+ messages in thread

* Re: [PATCH] system-type cygwin with window-system w32
  2011-07-18  6:29   ` Daniel Colascione
  2011-07-18  8:53     ` Eli Zaretskii
@ 2011-07-18 13:55     ` Jason Rumney
  2011-07-18 16:13     ` Paul Eggert
  2 siblings, 0 replies; 51+ messages in thread
From: Jason Rumney @ 2011-07-18 13:55 UTC (permalink / raw)
  To: Daniel Colascione; +Cc: Eli Zaretskii, emacs-devel

Daniel Colascione <dan.colascione@gmail.com> writes:

> Windows uses HTML as a data interchange format --- supporting it as a
> clipboard format allows formatting to be preserved in pastes into other
> programs.  This code could easily be structured as a separate package,
> however, and I'll end up doing that.

Most of the patch should be OS agnostic, as I am sure many GNU/Linux and
OSX programs also support HTML on the clipboard, and there is no good
reason to introduce such a feature only on Windows.



^ permalink raw reply	[flat|nested] 51+ messages in thread

* Re: [PATCH] system-type cygwin with window-system w32
  2011-07-18  0:01 [PATCH] system-type cygwin with window-system w32 Daniel Colascione
                   ` (3 preceding siblings ...)
  2011-07-18  8:42 ` Eli Zaretskii
@ 2011-07-18 15:54 ` Stefan Monnier
  2011-07-18 15:55 ` Stefan Monnier
  2011-07-18 17:37 ` Andreas Schwab
  6 siblings, 0 replies; 51+ messages in thread
From: Stefan Monnier @ 2011-07-18 15:54 UTC (permalink / raw)
  To: Daniel Colascione; +Cc: Emacs development discussions

> This patch makes it possible to use the NT GUI with a Cygwin core Emacs.

I have not looked at the code and probably won't be able to in the
foreseeable future, but at least I like the idea of separating the NT
GUI from the Windows support in the non-GUI part of the code.

Of course, another desirable step would be to let both the NT GUI and
the X11 GUI coexist in the same executable, but that is
a different story.


        Stefan



^ permalink raw reply	[flat|nested] 51+ messages in thread

* Re: [PATCH] system-type cygwin with window-system w32
  2011-07-18  0:01 [PATCH] system-type cygwin with window-system w32 Daniel Colascione
                   ` (4 preceding siblings ...)
  2011-07-18 15:54 ` Stefan Monnier
@ 2011-07-18 15:55 ` Stefan Monnier
  2011-07-18 17:37 ` Andreas Schwab
  6 siblings, 0 replies; 51+ messages in thread
From: Stefan Monnier @ 2011-07-18 15:55 UTC (permalink / raw)
  To: Daniel Colascione; +Cc: Emacs development discussions

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

There's a `pending' branch for patches which are ready for installing in
the trunk but not appropriate because of the feature freeze.  I don't
think that would be appropriate for your work either.  Better make a new
branch in the repository.


        Stefan



^ permalink raw reply	[flat|nested] 51+ messages in thread

* Re: [PATCH] system-type cygwin with window-system w32
  2011-07-18 10:10       ` Daniel Colascione
@ 2011-07-18 16:04         ` Paul Eggert
  2011-07-18 16:19         ` Eli Zaretskii
  1 sibling, 0 replies; 51+ messages in thread
From: Paul Eggert @ 2011-07-18 16:04 UTC (permalink / raw)
  To: Daniel Colascione; +Cc: Eli Zaretskii, emacs-devel

On 07/18/11 03:10, Daniel Colascione wrote:
> I didn't look into why it didn't work.  I can do some investigation, but
> I'm not very familiar with how gnulib stuff actually works.

It is supposed to work, as gnulib-based stuff runs on Cygwin all the
time.  What is the output of the following commands on your Cygwin build,
in your lib subdirectory?

diff -u sys_stat.in.h sys/stat.h

gcc -E -I. -I../src filemode.c

If you are using special GCC options you may need to add them to the
second command.



^ permalink raw reply	[flat|nested] 51+ messages in thread

* Re: [PATCH] system-type cygwin with window-system w32
  2011-07-18  6:29   ` Daniel Colascione
  2011-07-18  8:53     ` Eli Zaretskii
  2011-07-18 13:55     ` Jason Rumney
@ 2011-07-18 16:13     ` Paul Eggert
  2011-07-18 17:34       ` Andreas Schwab
  2 siblings, 1 reply; 51+ messages in thread
From: Paul Eggert @ 2011-07-18 16:13 UTC (permalink / raw)
  To: Daniel Colascione; +Cc: emacs-devel

I have qualms about this part of the patch, in lisp.h:

+#define t(...)                                          \
+    ({                                                  \
+      fprintf (stderr, "T:%s:%u: ",                     \
+               __FUNCTION__, __LINE__);                 \
+      fprintf (stderr, __VA_ARGS__);                    \
+      fputc ('\n', stderr);                             \
+    })
+

Is this some sort of test scaffolding that is intended to be
removed before the patch actually goes in?  If not, it has
some problems.  The name "t" is too short and cryptic.
The ({...}} construction is not standard C and won't work
with many non-GCC compilers.  The __FUNCTION__ macro is also
GCC-specific.



^ permalink raw reply	[flat|nested] 51+ messages in thread

* Re: [PATCH] system-type cygwin with window-system w32
  2011-07-18 10:10       ` Daniel Colascione
  2011-07-18 16:04         ` Paul Eggert
@ 2011-07-18 16:19         ` Eli Zaretskii
  1 sibling, 0 replies; 51+ messages in thread
From: Eli Zaretskii @ 2011-07-18 16:19 UTC (permalink / raw)
  To: Daniel Colascione; +Cc: emacs-devel

> Date: Mon, 18 Jul 2011 03:10:11 -0700
> From: Daniel Colascione <dan.colascione@gmail.com>
> CC: emacs-devel@gnu.org
> 
> On 7/18/11 1:53 AM, Eli Zaretskii wrote:
> >> S_ISCTG and such aren't being defined under Cygwin, causing compilation
> >> errors.  There's probably a better way to deal with the underlying problem.
> > 
> > Yes, the files in lib/sys_stat.in.h is supposed to do that already.
> > I'm curious why it didn't work for you.
> 
> I didn't look into why it didn't work.

Please do.  This works even in the DOS build, so it surely should for
Cygwin.

> I can do some investigation, but I'm not very familiar with how
> gnulib stuff actually works.

Perhaps Paul Eggert could help you out here.

> I'll move some code around; would you object to having
> w32.c, cygw32.c, and ntw32.c and corresponding headers?

How about calling the latter one ntgui.c?  That's what it's about,
right?




^ permalink raw reply	[flat|nested] 51+ messages in thread

* Re: [PATCH] system-type cygwin with window-system w32
  2011-07-18 10:33   ` Daniel Colascione
@ 2011-07-18 16:29     ` Eli Zaretskii
  2011-07-18 17:04       ` Daniel Colascione
  0 siblings, 1 reply; 51+ messages in thread
From: Eli Zaretskii @ 2011-07-18 16:29 UTC (permalink / raw)
  To: Daniel Colascione; +Cc: emacs-devel

> Date: Mon, 18 Jul 2011 03:33:59 -0700
> From: Daniel Colascione <dan.colascione@gmail.com>
> CC: emacs-devel@gnu.org
> 
> >> -  if (!hprevinst)
> >> -    {
> >> -      w32_init_class (hinst);
> >> -    }
> >> +  w32_init_class (hinst);
> > 
> > Not sure why the test was deleted here.  Can you explain?
> 
> hprevinst isn't trivially available under Cygwin, and I don't see what
> the test is buying us: class registration is inexpensive.

But then for Cygwin the condition will always be false, and the net
effect is to always call the function, as you wanted, right?  So I
would rather we left the code alone.

> >> +  htext = GlobalAlloc (GMEM_MOVEABLE | GMEM_DDESHARE, bytes);
> >> +  if (!htext)
> >> +    error ("GlobalAlloc: %s", w32_strerror (GetLastError ()));
> > 
> > Such cryptic error messages are not useful, because users are not
> > required to know what GlobalAlloc is.  Please modify the text to be
> > more palatable to mere mortals (here and elsewhere in this part of the
> > patch).
> 
> Well, it's better than what we used to do much of the time, which was to
> not check error codes at all.  How would you suggest changing the
> messages?

How about calling memory_full?

Or maybe error ("Not enough memory <TO DO WHATEVER THIS CODE DOES>") ?

> We could just the UI thread for this purpose instead of a dedicated one,

This is what I had in mind as the alternative, yes.

> What if I want to create a GUI-less Emacs that can nevertheless
> can interact with the system clipboard?

GUI-less Emacs normally doesn't interact with the clipboard, so
there's no need to choose a design that complicates things just
because we would like to make this feature available on a single
platform.

Anyway, I'm hardly an expert on this particular issue (i.e. Windows
GUI and the message pump).  I'm just worried by the fact that we will
have 2 threads calling GetMessage; in my experience this could lead to
hard-to-debug problems.



^ permalink raw reply	[flat|nested] 51+ messages in thread

* Re: [PATCH] system-type cygwin with window-system w32
  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 22:08             ` Richard Stallman
  2011-07-18 22:08             ` Richard Stallman
  3 siblings, 1 reply; 51+ messages in thread
From: Eli Zaretskii @ 2011-07-18 16:41 UTC (permalink / raw)
  To: Daniel Colascione; +Cc: emacs-devel

> Date: Mon, 18 Jul 2011 03:49:41 -0700
> From: Daniel Colascione <dan.colascione@gmail.com>
> CC: emacs-devel@gnu.org
> 
> > Not in the 3rd world, where there are still many machines running it.
> > Or so we were told last time this issue popped up.  RMS personally
> > asked not to drop W9X on this behalf.
> 
> I don't recall that discussion.  Can we reopen it?

Let's wait for Richard to chime in.

> > I didn't say we should stop the improvement.  You will find quite a
> > few Emacs features that use APIs which are unavailable on W9X.  But
> > they do it in a way that lets Emacs still run on W9X and produce
> > reasonable results, be that some fallback or just plain message saying
> > that this nifty feature is not available.  (Of course, disabling menus
> > or file access cannot use the latter fire escape, because they are too
> > basic and without them Emacs would become unusable.)
> 
> These fallbacks involve significant complexity, and they're
> lightly-tested at best.  I'd prefer to eliminate the complexity involved
> in supporting these alleged 9X users by simply dropping the support.

I'd prefer that as well, as soon as we drop W9X support.

> >   . user uses the file dialog to return a file name in UTF-16 which
> >     includes characters not available in the system codepage (this is
> >     quite possible on NTFS)
> > 
> >   . the file name is passed to file-attributes or insert-file-name or
> >     some other primitive that accepts file names
> 
> It'd be straightforward to locate all calls to CreateFile and such and
> update them to use unicode APIs.

I'm afraid it isn't straightforward.  I suspect there's a lot of
supporting code that still assumes unibyte characters.  But I'll
welcome patches in that area (if we agree to drop W9X support).

> Cygwin supports UTF-8 filenames natively.

I know that, but it isn't relevant to the native w32 build, because
that needs to use UTF-16, not UTF-8.

> But even if we don't --- why does it matter?  You can create files using
> the NT native API that can't be opened using Win32 calls; it doesn't
> cause a problem in practice.  Likewise, users who have strange
> filesnames might not be able to use them with all Emacs features right
> away, but they'll be able to work with more reasonable filenames just as
> they did before.

But switching to Unicode doesn't make sense _unless_ you want to
support "strange file names": all the non-strange file names are
already supported under the current ``ANSI'' APIs.  It's when I want
to see file names with characters not from my system locale that I
need Unicode.

> >   . if the underlying file APIs used by these primitives (`stat',
> >     `open', `opendir', etc.) are not Unicode, these primitives will
> >     fail in weird ways, like "file does not exist" etc., that would
> >     just confuse the user.
> 
> I'd prefer to go all-Unicode because I don't think unencodable filenames
> are common enough to warrant much concern here.

Sorry, I disagree.  I have quite a few on my system, for example.  If
you want to know how I got them, then they came with zip files that
included dictionaries in all kinds of languages, I brought them in
when I worked in a Windows port of Ispell.  And that's just one
example that came to my mind, I'm sure I would find more if I cared to
look.  E.g., I remember seeing file names with Kanji characters at
some point.

IMO, a half-broken feature is worse than an absent feature.
Especially if the breakage reveals itself as subtly as "file does not
exist" when I just selected it from a dialog.

> Any file users can manipulate today, they'll be able to manipulate
> with a partially-Unicodeized Emacs.

See above: for those, the Unicode interfaces give no advantage.

> Still, if we can't do that, then as a temporary measure, we can still
> use Unicode APIs (the 9X discussion notwithstanding), but as a temporary
> measure, filter their results so that we reject filenames that can't be
> used with the system codepage.

But then this is just complication with no benefits, isn't it?



^ permalink raw reply	[flat|nested] 51+ messages in thread

* Re: [PATCH] system-type cygwin with window-system w32
  2011-07-18 16:41             ` Eli Zaretskii
@ 2011-07-18 16:48               ` Daniel Colascione
  2011-07-18 17:08                 ` Eli Zaretskii
  0 siblings, 1 reply; 51+ messages in thread
From: Daniel Colascione @ 2011-07-18 16:48 UTC (permalink / raw)
  To: Eli Zaretskii; +Cc: emacs-devel

[-- Attachment #1: Type: text/plain, Size: 2129 bytes --]

On 7/18/11 9:41 AM, Eli Zaretskii wrote:
> I'm afraid it isn't straightforward.  I suspect there's a lot of
> supporting code that still assumes unibyte characters.  But I'll
> welcome patches in that area (if we agree to drop W9X support).

I meant that we can convert to UTF-8 (or our internal multibyte
encoding) until the very last moment before calling a system function;
we know UTF-8 support works already, and the conversation preserves
everything.

>> Cygwin supports UTF-8 filenames natively.
> 
> I know that, but it isn't relevant to the native w32 build, because
> that needs to use UTF-16, not UTF-8.
> 
>> But even if we don't --- why does it matter?  You can create files using
>> the NT native API that can't be opened using Win32 calls; it doesn't
>> cause a problem in practice.  Likewise, users who have strange
>> filesnames might not be able to use them with all Emacs features right
>> away, but they'll be able to work with more reasonable filenames just as
>> they did before.
> 
> But switching to Unicode doesn't make sense _unless_ you want to
> support "strange file names": all the non-strange file names are
> already supported under the current ``ANSI'' APIs.  It's when I want
> to see file names with characters not from my system locale that I
> need Unicode.

Unicode APIs are also more modern in a sense --- new ANSI APIs aren't
being created anymore.

> [snip]

> 
> See above: for those, the Unicode interfaces give no advantage.
> 
>> Still, if we can't do that, then as a temporary measure, we can still
>> use Unicode APIs (the 9X discussion notwithstanding), but as a temporary
>> measure, filter their results so that we reject filenames that can't be
>> used with the system codepage.
> 
> But then this is just complication with no benefits, isn't it?

Not necessarily --- this approach would allow us to gradually migrate to
Unicode without introducing the possibility of delivering
incomprehensible error messages to users.  When we've updated all the
relevant bits, we can just remove the filtering and have a pure Unicode
Emacs.


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

^ permalink raw reply	[flat|nested] 51+ messages in thread

* Re: [PATCH] system-type cygwin with window-system w32
  2011-07-18 16:29     ` Eli Zaretskii
@ 2011-07-18 17:04       ` Daniel Colascione
  0 siblings, 0 replies; 51+ messages in thread
From: Daniel Colascione @ 2011-07-18 17:04 UTC (permalink / raw)
  To: Eli Zaretskii; +Cc: emacs-devel

[-- Attachment #1: Type: text/plain, Size: 2822 bytes --]

On 7/18/11 9:29 AM, Eli Zaretskii wrote:
>> Date: Mon, 18 Jul 2011 03:33:59 -0700
>> From: Daniel Colascione <dan.colascione@gmail.com>
>> CC: emacs-devel@gnu.org
>>
>>>> -  if (!hprevinst)
>>>> -    {
>>>> -      w32_init_class (hinst);
>>>> -    }
>>>> +  w32_init_class (hinst);
>>>
>>> Not sure why the test was deleted here.  Can you explain?
>>
>> hprevinst isn't trivially available under Cygwin, and I don't see what
>> the test is buying us: class registration is inexpensive.
> 
> But then for Cygwin the condition will always be false, and the net
> effect is to always call the function, as you wanted, right?  So I
> would rather we left the code alone.

We'd still need the variable with your proposal, and I don't see what
the existing behavior has, even in the NT case.

>>>> +  htext = GlobalAlloc (GMEM_MOVEABLE | GMEM_DDESHARE, bytes);
>>>> +  if (!htext)
>>>> +    error ("GlobalAlloc: %s", w32_strerror (GetLastError ()));
>>>
>>> Such cryptic error messages are not useful, because users are not
>>> required to know what GlobalAlloc is.  Please modify the text to be
>>> more palatable to mere mortals (here and elsewhere in this part of the
>>> patch).
>>
>> Well, it's better than what we used to do much of the time, which was to
>> not check error codes at all.  How would you suggest changing the
>> messages?
> 
> How about calling memory_full?
> 
> Or maybe error ("Not enough memory <TO DO WHATEVER THIS CODE DOES>") ?

The error isn't necessarily fatal --- and in general (speaking to other
instances of w32_strerror in the patch) we don't always know what
exactly went wrong.  It'd be nice to give users an opportunity to figure
it out.  Maybe we can recognize a subset of error codes and forward
those to memory_full.

>> We could just the UI thread for this purpose instead of a dedicated one,
> 
> This is what I had in mind as the alternative, yes.
> 
>> What if I want to create a GUI-less Emacs that can nevertheless
>> can interact with the system clipboard?
> 
> GUI-less Emacs normally doesn't interact with the clipboard, so
> there's no need to choose a design that complicates things just
> because we would like to make this feature available on a single
> platform.

The complexity has to be present regardless.

> Anyway, I'm hardly an expert on this particular issue (i.e. Windows
> GUI and the message pump).  I'm just worried by the fact that we will
> have 2 threads calling GetMessage; in my experience this could lead to
> hard-to-debug problems.

Calling GetMessage in two threads is very common and well-supported, and
won't by itself cause problems. If anything, separating the message
loops makes the program more robust --- each message loop is less
complex and thereby easier to understand.


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

^ permalink raw reply	[flat|nested] 51+ messages in thread

* Re: [PATCH] system-type cygwin with window-system w32
  2011-07-18 16:48               ` Daniel Colascione
@ 2011-07-18 17:08                 ` Eli Zaretskii
  0 siblings, 0 replies; 51+ messages in thread
From: Eli Zaretskii @ 2011-07-18 17:08 UTC (permalink / raw)
  To: Daniel Colascione; +Cc: emacs-devel

> Date: Mon, 18 Jul 2011 09:48:44 -0700
> From: Daniel Colascione <dan.colascione@gmail.com>
> CC: emacs-devel@gnu.org
> 
> I meant that we can convert to UTF-8 (or our internal multibyte
> encoding) until the very last moment before calling a system function;

We already do that.  The problem is with processing the strings which
don't come from Lisp nor are going to be passed to the Lisp level.
Just take a look at w32.c, and you will see what I mean.



^ permalink raw reply	[flat|nested] 51+ messages in thread

* Re: [PATCH] system-type cygwin with window-system w32
@ 2011-07-18 17:33 grischka
  2011-07-18 17:50 ` Daniel Colascione
  0 siblings, 1 reply; 51+ messages in thread
From: grischka @ 2011-07-18 17:33 UTC (permalink / raw)
  To: dan.colascione; +Cc: emacs-devel

Daniel Colascione wrote:
> I'll have to add a comment explaining what's going on here.  In the
> meantime: the main thread doesn't usually pump messages because it's
> blocked on select(2) instead.  

Doesn't cygwin have a pseudo device /dev/windows to select for
incoming WM_xxx messages?

--- grischka



^ permalink raw reply	[flat|nested] 51+ messages in thread

* Re: [PATCH] system-type cygwin with window-system w32
  2011-07-18 16:13     ` Paul Eggert
@ 2011-07-18 17:34       ` Andreas Schwab
  0 siblings, 0 replies; 51+ messages in thread
From: Andreas Schwab @ 2011-07-18 17:34 UTC (permalink / raw)
  To: Paul Eggert; +Cc: Daniel Colascione, emacs-devel

Paul Eggert <eggert@cs.ucla.edu> writes:

> I have qualms about this part of the patch, in lisp.h:
>
> +#define t(...)                                          \
> +    ({                                                  \
> +      fprintf (stderr, "T:%s:%u: ",                     \
> +               __FUNCTION__, __LINE__);                 \
> +      fprintf (stderr, __VA_ARGS__);                    \
> +      fputc ('\n', stderr);                             \
> +    })
> +
>
> Is this some sort of test scaffolding that is intended to be
> removed before the patch actually goes in?  If not, it has
> some problems.  The name "t" is too short and cryptic.
> The ({...}} construction is not standard C and won't work
> with many non-GCC compilers.  The __FUNCTION__ macro is also
> GCC-specific.

This is all not a problem if the macro is unused, but the C99 variable
argument list will cause C89 compilers to trip over.

Andreas.

-- 
Andreas Schwab, schwab@linux-m68k.org
GPG Key fingerprint = 58CA 54C7 6D53 942B 1756  01D3 44D5 214B 8276 4ED5
"And now for something completely different."



^ permalink raw reply	[flat|nested] 51+ messages in thread

* Re: [PATCH] system-type cygwin with window-system w32
  2011-07-18  0:01 [PATCH] system-type cygwin with window-system w32 Daniel Colascione
                   ` (5 preceding siblings ...)
  2011-07-18 15:55 ` Stefan Monnier
@ 2011-07-18 17:37 ` Andreas Schwab
  6 siblings, 0 replies; 51+ messages in thread
From: Andreas Schwab @ 2011-07-18 17:37 UTC (permalink / raw)
  To: Daniel Colascione; +Cc: Emacs development discussions

Daniel Colascione <dan.colascione@gmail.com> writes:

> +  to_unicode (build_string ("All Files (*.*)\0*.*\0Directories\0*|*\0\0"),
> +              &filter);

build_string takes a C string, so this won't work.

Andreas.

-- 
Andreas Schwab, schwab@linux-m68k.org
GPG Key fingerprint = 58CA 54C7 6D53 942B 1756  01D3 44D5 214B 8276 4ED5
"And now for something completely different."



^ permalink raw reply	[flat|nested] 51+ messages in thread

* Re: [PATCH] system-type cygwin with window-system w32
  2011-07-18 17:33 grischka
@ 2011-07-18 17:50 ` Daniel Colascione
  2011-07-18 18:08   ` Daniel Colascione
  2011-07-18 18:38   ` grischka
  0 siblings, 2 replies; 51+ messages in thread
From: Daniel Colascione @ 2011-07-18 17:50 UTC (permalink / raw)
  To: grischka; +Cc: emacs-devel

[-- Attachment #1: Type: text/plain, Size: 1814 bytes --]

On 7/18/11 10:33 AM, grischka wrote:
> Daniel Colascione wrote:
>> I'll have to add a comment explaining what's going on here.  In the
>> meantime: the main thread doesn't usually pump messages because it's
>> blocked on select(2) instead.  
> 
> Doesn't cygwin have a pseudo device /dev/windows to select for
> incoming WM_xxx messages?
> 
> --- grischka

Wow.  Thanks for the tip.  /dev/windows doesn't appear to be well-documented
externally, but from fhandler_windows.cc in the Cygwin tree:

/*
The following unix-style calls are supported:

	open ("/dev/windows", flags, mode=0)
		- create a unix fd for message queue.

	read (fd, buf, len)
		- return next message from queue. buf must point to MSG
		  structure, len must be >= sizeof (MSG). If read is set to
		  non-blocking and the queue is empty, read call returns -1
		  immediately with errno set to EAGAIN, otherwise it blocks
		  untill the message will be received.

	write (fd, buf, len)
		- send a message pointed by buf. len argument ignored.

	ioctl (fd, command, *param)
		- control read()/write() behavior.
		ioctl (fd, WINDOWS_POST, NULL): write() will PostMessage();
		ioctl (fd, WINDOWS_SEND, NULL): write() will SendMessage();
		ioctl (fd, WINDOWS_HWND, &hWnd): read() messages for
			hWnd window.

	select () call marks read fd when any message posted to queue.
*/


If it works, /dev/windows would allow us to get rid of not only the self-pipe
and the clipboard thread, but the UI thread as well, though it'd be easier to
keep the last of these for compatibility for the NT build.  Thanks.

By the way: why do we use a separate UI thread in the NT case at all?  AIUI, we
can do everything we need asynchronously via overlapped IO, so we should never
have to block and not pump messages.


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

^ permalink raw reply	[flat|nested] 51+ messages in thread

* Re: [PATCH] system-type cygwin with window-system w32
  2011-07-18 17:50 ` Daniel Colascione
@ 2011-07-18 18:08   ` Daniel Colascione
  2011-07-18 18:52     ` grischka
  2011-07-18 18:38   ` grischka
  1 sibling, 1 reply; 51+ messages in thread
From: Daniel Colascione @ 2011-07-18 18:08 UTC (permalink / raw)
  To: grischka; +Cc: emacs-devel

[-- Attachment #1: Type: text/plain, Size: 1183 bytes --]

On 7/18/11 10:50 AM, Daniel Colascione wrote:
> If it works, /dev/windows would allow us to get rid of not only the self-pipe
> and the clipboard thread, but the UI thread as well, though it'd be easier to
> keep the last of these for compatibility for the NT build.

Actually, I spoke too soon regarding the clipboard thread: the problem is that
when we receive a WM_RENDERFORMAT message, we have to call SetClipboardData
_before we return from the window procedure_.  This requirement is incompatible
with using lisp code to render clipboard content: we might have received a
window message at an inopportune time for calling back into Lisp, and we can't
delay the response to WM_RENDERFORMAT by re-queuing or somesuch.  Today's NT
clipboard code doesn't have to address the issue because it never calls into Lisp.

We can address this problem by using a separate message loop for the clipboard;
that way, the clipboard windowproc can wait as long as it wants to reply to
WM_RENDERFORMAT while the main thread does its thing and eventually gets around
to calling our queued timer.  I think this approach (which my patch implements)
is ultimately the right one.


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

^ permalink raw reply	[flat|nested] 51+ messages in thread

* Re: [PATCH] system-type cygwin with window-system w32
  2011-07-18 17:50 ` Daniel Colascione
  2011-07-18 18:08   ` Daniel Colascione
@ 2011-07-18 18:38   ` grischka
  1 sibling, 0 replies; 51+ messages in thread
From: grischka @ 2011-07-18 18:38 UTC (permalink / raw)
  To: Daniel Colascione; +Cc: emacs-devel

Daniel Colascione wrote:
> If it works, /dev/windows would allow us to get rid of not only the self-pipe
> and the clipboard thread, but the UI thread as well, though it'd be easier to
> keep the last of these for compatibility for the NT build.  Thanks.

Actually the NT build works quite well with one single thread.
Already tested here.

> By the way: why do we use a separate UI thread in the NT case at all?  AIUI, we
> can do everything we need asynchronously via overlapped IO, so we should never
> have to block and not pump messages.

The 'sys_select' wrapper DOES pump messages, just for the wrong
thread.  So it needs the thread because it has the thread. :)

Well, there are two other things needed:
* peek for messages in the QUIT macro (say via ELSE_PENDING_SIGNALS)
   which is for C-g to interrupt lisp.
* break command_loop_1() such that it can be used to handle just one
   event which is to handle scrollbar messages because the widgets
   run their own message loop deep in windows.  Otherwise all the
   scrolling would happen only after you release the mouse button.

--- grischka




^ permalink raw reply	[flat|nested] 51+ messages in thread

* Re: [PATCH] system-type cygwin with window-system w32
  2011-07-18 18:08   ` Daniel Colascione
@ 2011-07-18 18:52     ` grischka
  2011-07-18 19:11       ` Daniel Colascione
  0 siblings, 1 reply; 51+ messages in thread
From: grischka @ 2011-07-18 18:52 UTC (permalink / raw)
  To: Daniel Colascione; +Cc: emacs-devel

Daniel Colascione wrote:
> This requirement is incompatible
> with using lisp code to render clipboard content: we might have received a
> window message at an inopportune time for calling back into Lisp, and we can't
> delay the response to WM_RENDERFORMAT by re-queuing or somesuch.  Today's NT
> clipboard code doesn't have to address the issue because it never calls into Lisp.

Well, you can do this if you have a function to pump elisp
events, say drain_lisp_queue():

That would be basically command_loop_1() with
     while (1)
replaced by
     while (detect_input_pending())

Then, in window_proc:
     case WM_RENDERFORMAT:
         queue_lisp_event(); //I guess it's "kbd_buffer_store_event_hold"
         drain_lisp_queue();
         break;

Or such.

--- grischka




^ permalink raw reply	[flat|nested] 51+ messages in thread

* Re: [PATCH] system-type cygwin with window-system w32
  2011-07-18 18:52     ` grischka
@ 2011-07-18 19:11       ` Daniel Colascione
  2011-07-18 21:01         ` grischka
  0 siblings, 1 reply; 51+ messages in thread
From: Daniel Colascione @ 2011-07-18 19:11 UTC (permalink / raw)
  To: grischka; +Cc: emacs-devel

[-- Attachment #1: Type: text/plain, Size: 3552 bytes --]

On 7/18/2011 11:38 AM, grischka wrote:
> Daniel Colascione wrote:
>> If it works, /dev/windows would allow us to get rid of not only the
>> self-pipe
>> and the clipboard thread, but the UI thread as well, though it'd be
>> easier to
>> keep the last of these for compatibility for the NT build.  Thanks.
>
> Actually the NT build works quite well with one single thread.
> Already tested here.

Do you have a patch handy?

>> By the way: why do we use a separate UI thread in the NT case at all?
>> AIUI, we
>> can do everything we need asynchronously via overlapped IO, so we
>> should never
>> have to block and not pump messages.
>
> The 'sys_select' wrapper DOES pump messages, just for the wrong
> thread.  So it needs the thread because it has the thread. :)

Of course.  I suspect the initial motivation behind the separate thread
is a long, somnolent story involving QUIT.

> Well, there are two other things needed:
> * peek for messages in the QUIT macro (say via ELSE_PENDING_SIGNALS)
>   which is for C-g to interrupt lisp.

I don't think this approach alone would be sufficient.  I may be wrong,
but I think the Windows window manager will consider a program to be
"unresponsive" if it stops actually pumping messages; I don't think
peeking is sufficient.  Also, [1] says that we shouldn't delay pumping
messages even if we're able to guarantee we'll get around to them later.
(Running lisp code is indistinguishable from sleep in this case.)

Using PeekMessage in lisp code instead of actually pumping messages
would be like telling your credit card company, "Yeah, I got the bill,
and I'll get around to responding sometime in the next two years".  I
don't think it'd go over well.

Actually, on that note, I should add a timeout to my WM_RENDERFORMAT
code: we shouldn't block other applications forever merely because Emacs
is spinning in Lisp.

> * break command_loop_1() such that it can be used to handle just one
>   event which is to handle scrollbar messages because the widgets
>   run their own message loop deep in windows.  Otherwise all the
>   scrolling would happen only after you release the mouse button.

I doubt that the scrollbar is the only special case we'd need to consider.

On 7/18/2011 11:52 AM, grischka wrote:
> Daniel Colascione wrote:
>> This requirement is incompatible
>> with using lisp code to render clipboard content: we might have
>> received a
>> window message at an inopportune time for calling back into Lisp, and
>> we can't
>> delay the response to WM_RENDERFORMAT by re-queuing or somesuch. 
>> Today's NT
>> clipboard code doesn't have to address the issue because it never
>> calls into Lisp.
> 
> Well, you can do this if you have a function to pump elisp
> events, say drain_lisp_queue():
> 
> That would be basically command_loop_1() with
>     while (1)
> replaced by
>     while (detect_input_pending())
> 
> Then, in window_proc:
>     case WM_RENDERFORMAT:
>         queue_lisp_event(); //I guess it's "kbd_buffer_store_event_hold"
>         drain_lisp_queue();
>         break;
> 
> Or such.
> 

I don't understand how this approach helps.  The problem, AIUI, isn't
that we have Lisp events, but that we read input and wait for processes
in many places, and it's hard to be confident that each place we pump
messages is a safe place to process lisp code.  I don't understand how
draining the lisp event queue would help.

[1] http://blogs.msdn.com/b/oldnewthing/archive/2006/02/10/529525.aspx


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

^ permalink raw reply	[flat|nested] 51+ messages in thread

* Re: [PATCH] system-type cygwin with window-system w32
  2011-07-18 19:11       ` Daniel Colascione
@ 2011-07-18 21:01         ` grischka
  2011-07-19  2:58           ` Eli Zaretskii
  2011-07-21 17:44           ` Lennart Borgman
  0 siblings, 2 replies; 51+ messages in thread
From: grischka @ 2011-07-18 21:01 UTC (permalink / raw)
  To: Daniel Colascione; +Cc: emacs-devel

[-- Attachment #1: Type: text/plain, Size: 3157 bytes --]

Daniel Colascione wrote:
>> Actually the NT build works quite well with one single thread.
>> Already tested here.
> 
> Do you have a patch handy?

Attached.  Patch was against state at commit:

       Jan D. <jan.h.d@swipnet.se>  2011-02-01 09:53:03
       Use add/delete_read_fd in xsmfns to simplify.  Also ...

Hopefully still applies cleanly.

It is minimal, and maybe not quite obvious.  Basically the two window
message switches (w32fns.c and w32term.c) could be merged into one.
The patch calls the one from the other.

There is an elisp variable 'w32-single-thread' which should return 1
if you want to make sure you're using the right build. :)

Note that you can for example drag the "Open File" dialog across the
main window and it still gets redrawn.

>> * peek for messages in the QUIT macro (say via ELSE_PENDING_SIGNALS)
>>   which is for C-g to interrupt lisp.
> 
> I don't think this approach alone would be sufficient.  I may be wrong,
> but I think the Windows window manager will consider a program to be
> "unresponsive" if it stops actually pumping messages; I don't think
> peeking is sufficient.  Also, [1] says that we shouldn't delay pumping
> messages even if we're able to guarantee we'll get around to them later.
> (Running lisp code is indistinguishable from sleep in this case.)

> Using PeekMessage in lisp code instead of actually pumping messages
> would be like telling your credit card company, "Yeah, I got the bill,
> and I'll get around to responding sometime in the next two years".  I
> don't think it'd go over well.

"Two years" or anyway "indistinguishable from sleep" is never really
acceptable.  Because then emacs can't process key/mouse events
regardless how many threads you have in the backend.

We need to think in terms of UI timings here.  Reference is the kbd
repeat rate, say 30ms, which is also in the range of eye perception
capability and frame repeat rates.  Up to this is smooth.  More can
be tolerable though, even up to 1 or more seconds.  Say for popping
up new windows, frames, etc.

So if your elisp doesn't finish in 30ms, you know ;)

>> * break command_loop_1() such that it can be used to handle just one
>>   event which is to handle scrollbar messages because the widgets
>>   run their own message loop deep in windows.  Otherwise all the
>>   scrolling would happen only after you release the mouse button.
> 
> I doubt that the scrollbar is the only special case we'd need to consider.

AFAICS scrollbar and paint. And maybe clipboard rendering.  Emacs
handles paint directly via expose_frame() though, not via the event
queue.

> I don't understand how this approach helps.  The problem, AIUI, isn't
> that we have Lisp events, but that we read input and wait for processes
> in many places, and it's hard to be confident that each place we pump
> messages is a safe place to process lisp code.  I don't understand how
> draining the lisp event queue would help.

As I see it this is just recursion.   Such things happen all the time
in all GUIs that use callbacks.  Windows, GTK, whatever.  It happens
in emacs already:

       (run-with-idle-timer ... lisp-code)

--- grischka


[-- Attachment #2: gr-w32-singlethread.patch --]
[-- Type: text/plain, Size: 13052 bytes --]

diff --git a/nt/config.nt b/nt/config.nt
index d612a41..dd4cd38 100644
--- a/nt/config.nt
+++ b/nt/config.nt
@@ -467,6 +467,8 @@ extern char *getenv ();
 #endif
 #endif
 
+#define SINGLE_THREAD
+
 /* Redefine abort.  */
 #ifdef HAVE_NTGUI
 #define abort	w32_abort
diff --git a/src/keyboard.c b/src/keyboard.c
index d533213..e824682 100644
--- a/src/keyboard.c
+++ b/src/keyboard.c
@@ -1290,7 +1290,7 @@ cancel_hourglass_unwind (Lisp_Object arg)
 EXFUN (Fwindow_system, 1);
 
 Lisp_Object
-command_loop_1 (void)
+command_loop_1a (int repeat)
 {
   Lisp_Object cmd;
   Lisp_Object keybuf[30];
@@ -1336,7 +1336,7 @@ command_loop_1 (void)
   if (!CONSP (last_command_event))
     current_kboard->Vlast_repeatable_command = real_this_command;
 
-  while (1)
+  while (repeat || detect_input_pending())
     {
       if (! FRAME_LIVE_P (XFRAME (selected_frame)))
 	Fkill_emacs (Qnil);
@@ -1659,6 +1659,12 @@ command_loop_1 (void)
     }
 }
 
+Lisp_Object
+command_loop_1 ()
+{
+    return command_loop_1a(1);
+}
+
 /* Adjust point to a boundary of a region that has such a property
    that should be treated intangible.  For the moment, we check
    `composition', `display' and `invisible' properties.
diff --git a/src/lisp.h b/src/lisp.h
index cfff42a..efe76f6 100644
--- a/src/lisp.h
+++ b/src/lisp.h
@@ -2013,6 +2013,10 @@ extern char *stack_bottom;
    This is a good thing to do around a loop that has no side effects
    and (in particular) cannot call arbitrary Lisp code.  */
 
+#if defined HAVE_NTGUI && defined SINGLE_THREAD
+#define ELSE_PENDING_SIGNALS else w32_peek_messages();
+void w32_peek_messages();
+#else
 #ifdef SYNC_INPUT
 extern void process_pending_signals (void);
 extern int pending_signals;
@@ -2022,6 +2026,7 @@ extern int pending_signals;
 #else  /* not SYNC_INPUT */
 #define ELSE_PENDING_SIGNALS
 #endif	/* not SYNC_INPUT */
+#endif	/* not HAVE_NTGUI */
 
 #define QUIT						\
   do {							\
diff --git a/src/w32fns.c b/src/w32fns.c
index b09bb0b..93f80f9 100644
--- a/src/w32fns.c
+++ b/src/w32fns.c
@@ -87,6 +87,10 @@ extern const char *const lispy_function_keys[];
 static unsigned hourglass_timer = 0;
 static HWND hourglass_hwnd = NULL;
 
+#ifdef SINGLE_THREAD
+int w32_single_thread;
+#endif
+
 #ifndef IDC_HAND
 #define IDC_HAND MAKEINTRESOURCE(32649)
 #endif
@@ -2242,17 +2246,15 @@ unregister_hot_keys (HWND hwnd)
 
 /* Main message dispatch loop. */
 
-static void
-w32_msg_pump (deferred_msg * msg_buf)
+unsigned dispatch_msg (MSG *pmsg)
 {
   MSG msg;
   int result;
   HWND focus_window;
 
-  msh_mousewheel = RegisterWindowMessage (MSH_MOUSEWHEEL);
+  result = 0;
+  msg = *pmsg;
 
-  while (GetMessage (&msg, NULL, 0, 0))
-    {
       if (msg.hwnd == NULL)
 	{
 	  switch (msg.message)
@@ -2269,8 +2271,10 @@ w32_msg_pump (deferred_msg * msg_buf)
                  and older versions will never be patched.  */
               CoInitialize (NULL);
 	      w32_createwindow ((struct frame *) msg.wParam);
+#ifndef SINGLE_THREAD
 	      if (!PostThreadMessage (dwMainThreadId, WM_EMACS_DONE, 0, 0))
 		abort ();
+#endif
 	      break;
 	    case WM_EMACS_SETLOCALE:
 	      SetThreadLocale (msg.wParam);
@@ -2278,9 +2282,11 @@ w32_msg_pump (deferred_msg * msg_buf)
 	      break;
 	    case WM_EMACS_SETKEYBOARDLAYOUT:
 	      result = (int) ActivateKeyboardLayout ((HKL) msg.wParam, 0);
+#ifndef SINGLE_THREAD
 	      if (!PostThreadMessage (dwMainThreadId, WM_EMACS_DONE,
 				      result, 0))
 		abort ();
+#endif
 	      break;
 	    case WM_EMACS_REGISTER_HOT_KEY:
 	      focus_window = GetFocus ();
@@ -2300,8 +2306,10 @@ w32_msg_pump (deferred_msg * msg_buf)
                  cell is never made into garbage and is not relocated by
                  GC.  */
 	      XSETCAR ((Lisp_Object) ((EMACS_INT) msg.lParam), Qnil);
+#ifndef SINGLE_THREAD
 	      if (!PostThreadMessage (dwMainThreadId, WM_EMACS_DONE, 0, 0))
 		abort ();
+#endif
 	      break;
 	    case WM_EMACS_TOGGLE_LOCK_KEY:
 	      {
@@ -2331,9 +2339,12 @@ w32_msg_pump (deferred_msg * msg_buf)
 				 KEYEVENTF_EXTENDEDKEY | KEYEVENTF_KEYUP, 0);
 		    cur_state = !cur_state;
 		  }
+#ifndef SINGLE_THREAD
 		if (!PostThreadMessage (dwMainThreadId, WM_EMACS_DONE,
 					cur_state, 0))
 		  abort ();
+#endif
+		result = cur_state;
 	      }
 	      break;
 #ifdef MSG_DEBUG
@@ -2349,11 +2360,37 @@ w32_msg_pump (deferred_msg * msg_buf)
 	  DispatchMessage (&msg);
 	}
 
+    return result;
+}
+
+static void
+w32_msg_pump (deferred_msg * msg_buf)
+{
+#ifndef SINGLE_THREAD
+  MSG msg;
+  msh_mousewheel = RegisterWindowMessage (MSH_MOUSEWHEEL);
+  while (GetMessage (&msg, NULL, 0, 0))
+    {
+      dispatch_msg(&msg);
       /* Exit nested loop when our deferred message has completed.  */
       if (msg_buf->completed)
 	break;
     }
+#endif
+}
+
+#ifdef SINGLE_THREAD
+unsigned do_thread_msg(unsigned threadid, unsigned umsg, WPARAM wParam, LPARAM lParam)
+{
+    MSG msg;
+    msg.hwnd = NULL;
+    msg.message = umsg;
+    msg.wParam = wParam;
+    msg.lParam = lParam;
+    return dispatch_msg(&msg);
 }
+#endif
+
 
 deferred_msg * deferred_msg_head;
 
@@ -2427,7 +2464,9 @@ complete_deferred_msg (HWND hwnd, UINT msg, LRESULT result)
   msg_buf->completed = 1;
 
   /* Ensure input thread is woken so it notices the completion.  */
+#ifndef SINGLE_THREAD
   PostThreadMessage (dwWindowsThreadId, WM_NULL, 0, 0);
+#endif
 }
 
 static void
@@ -2448,7 +2487,9 @@ cancel_all_deferred_msgs (void)
   /* leave_crit (); */
 
   /* Ensure input thread is woken so it notices the completion.  */
+#ifndef SINGLE_THREAD
   PostThreadMessage (dwWindowsThreadId, WM_NULL, 0, 0);
+#endif
 }
 
 DWORD WINAPI
@@ -2654,6 +2695,10 @@ w32_wnd_proc (HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
 	       dedicated to one frame and does not bother checking
 	       that hwnd matches before combining them.  */
             my_post_msg (&wmsg, hwnd, WM_EMACS_PAINT, wParam, lParam);
+#ifdef SINGLE_THREAD
+            w32_read_socket(0, 0, NULL);
+            //command_loop_1a(0);
+#endif
 
             return 0;
           }
@@ -3205,6 +3250,10 @@ w32_wnd_proc (HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
   	{
 	  wmsg.dwModifiers = w32_get_modifiers ();
 	  my_post_msg (&wmsg, hwnd, msg, wParam, lParam);
+#ifdef SINGLE_THREAD
+          if (msg == WM_VSCROLL)
+            command_loop_1a(0);
+#endif
 	  return 0;
   	}
 
@@ -3808,11 +3857,15 @@ w32_wnd_proc (HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
 static void
 my_create_window (struct frame * f)
 {
+#ifdef SINGLE_THREAD
+  do_thread_msg (dwWindowsThreadId, WM_EMACS_CREATEWINDOW, (WPARAM)f, 0);
+#else
   MSG msg;
 
   if (!PostThreadMessage (dwWindowsThreadId, WM_EMACS_CREATEWINDOW, (WPARAM)f, 0))
     abort ();
   GetMessage (&msg, NULL, WM_EMACS_DONE, WM_EMACS_DONE);
+#endif
 }
 
 
@@ -6308,6 +6361,15 @@ The return value is the hotkey-id if registered, otherwise nil.  */)
 
       /* Notify input thread about new hot-key definition, so that it
 	 takes effect without needing to switch focus.  */
+#ifdef SINGLE_THREAD
+#ifdef USE_LISP_UNION_TYPE
+      do_thread_msg (dwWindowsThreadId, WM_EMACS_REGISTER_HOT_KEY,
+                         (WPARAM) key.i, 0);
+#else
+      do_thread_msg (dwWindowsThreadId, WM_EMACS_REGISTER_HOT_KEY,
+                         (WPARAM) key, 0);
+#endif
+#else
 #ifdef USE_LISP_UNION_TYPE
       PostThreadMessage (dwWindowsThreadId, WM_EMACS_REGISTER_HOT_KEY,
 			 (WPARAM) key.i, 0);
@@ -6315,6 +6377,7 @@ The return value is the hotkey-id if registered, otherwise nil.  */)
       PostThreadMessage (dwWindowsThreadId, WM_EMACS_REGISTER_HOT_KEY,
 			 (WPARAM) key, 0);
 #endif
+#endif
     }
 
   return key;
@@ -6336,6 +6399,16 @@ DEFUN ("w32-unregister-hot-key", Fw32_unregister_hot_key,
     {
       /* Notify input thread about hot-key definition being removed, so
 	 that it takes effect without needing focus switch.  */
+#ifdef SINGLE_THREAD
+#ifdef USE_LISP_UNION_TYPE
+      do_thread_msg (dwWindowsThreadId, WM_EMACS_UNREGISTER_HOT_KEY,
+                             (WPARAM) XINT (XCAR (item)), (LPARAM) item.i);
+#else
+      do_thread_msg (dwWindowsThreadId, WM_EMACS_UNREGISTER_HOT_KEY,
+                             (WPARAM) XINT (XCAR (item)), (LPARAM) item);
+
+#endif
+#else
 #ifdef USE_LISP_UNION_TYPE
       if (PostThreadMessage (dwWindowsThreadId, WM_EMACS_UNREGISTER_HOT_KEY,
 			     (WPARAM) XINT (XCAR (item)), (LPARAM) item.i))
@@ -6347,6 +6420,7 @@ DEFUN ("w32-unregister-hot-key", Fw32_unregister_hot_key,
 	  MSG msg;
 	  GetMessage (&msg, NULL, WM_EMACS_DONE, WM_EMACS_DONE);
 	}
+#endif
       return Qt;
     }
   return Qnil;
@@ -6401,6 +6475,9 @@ is set to off if the low bit of NEW-STATE is zero, otherwise on.  */)
   (Lisp_Object key, Lisp_Object new_state)
 {
   int vk_code;
+#ifdef SINGLE_THREAD
+  unsigned ret;
+#endif
 
   if (EQ (key, intern ("capslock")))
     vk_code = VK_CAPITAL;
@@ -6414,6 +6491,16 @@ is set to off if the low bit of NEW-STATE is zero, otherwise on.  */)
   if (!dwWindowsThreadId)
     return make_number (w32_console_toggle_lock_key (vk_code, new_state));
 
+#ifdef SINGLE_THREAD
+#ifdef USE_LISP_UNION_TYPE
+  ret = do_thread_msg (dwWindowsThreadId, WM_EMACS_TOGGLE_LOCK_KEY,
+                         (WPARAM) vk_code, (LPARAM) new_state.i);
+#else
+  ret = do_thread_msg (dwWindowsThreadId, WM_EMACS_TOGGLE_LOCK_KEY,
+                         (WPARAM) vk_code, (LPARAM) new_state);
+#endif
+  return make_number (ret);
+#else
 #ifdef USE_LISP_UNION_TYPE
   if (PostThreadMessage (dwWindowsThreadId, WM_EMACS_TOGGLE_LOCK_KEY,
 			 (WPARAM) vk_code, (LPARAM) new_state.i))
@@ -6427,6 +6514,7 @@ is set to off if the low bit of NEW-STATE is zero, otherwise on.  */)
       return make_number (msg.wParam);
     }
   return Qnil;
+#endif
 }
 
 DEFUN ("w32-window-exists-p", Fw32_window_exists_p, Sw32_window_exists_p,
@@ -7053,6 +7141,14 @@ Set this to nil to get the old behavior for repainting; this should
 only be necessary if the default setting causes problems.  */);
   w32_strict_painting = 1;
 
+#ifdef SINGLE_THREAD
+  DEFVAR_BOOL ("w32-single-thread",
+	       &w32_single_thread,
+	       doc: /* using single thread */);
+
+  w32_single_thread = 1;
+#endif
+
 #if 0 /* TODO: Port to W32 */
   defsubr (&Sx_change_window_property);
   defsubr (&Sx_delete_window_property);
diff --git a/src/w32proc.c b/src/w32proc.c
index 1c009c7..49eab27 100644
--- a/src/w32proc.c
+++ b/src/w32proc.c
@@ -2028,7 +2028,11 @@ If successful, the new locale id is returned, otherwise nil.  */)
   /* Need to set input thread locale if present.  */
   if (dwWindowsThreadId)
     /* Reply is not needed.  */
+#ifdef SINGLE_THREAD
+    do_thread_msg (dwWindowsThreadId, WM_EMACS_SETLOCALE, XINT (lcid), 0);
+#else
     PostThreadMessage (dwWindowsThreadId, WM_EMACS_SETLOCALE, XINT (lcid), 0);
+#endif
 
   return make_number (GetThreadLocale ());
 }
@@ -2194,6 +2198,10 @@ If successful, the new layout id is returned, otherwise nil.  */)
   /* Synchronize layout with input thread.  */
   if (dwWindowsThreadId)
     {
+#ifdef SINGLE_THREAD
+      if (0 == do_thread_msg (dwWindowsThreadId, WM_EMACS_SETKEYBOARDLAYOUT, (WPARAM) kl, 0))
+        return Qnil;
+#else
       if (PostThreadMessage (dwWindowsThreadId, WM_EMACS_SETKEYBOARDLAYOUT,
 			     (WPARAM) kl, 0))
 	{
@@ -2203,6 +2211,7 @@ If successful, the new layout id is returned, otherwise nil.  */)
 	  if (msg.wParam == 0)
 	    return Qnil;
 	}
+#endif
     }
   else if (!ActivateKeyboardLayout ((HKL) kl, 0))
     return Qnil;
diff --git a/src/w32term.c b/src/w32term.c
index cd4ee54..83eed4a 100644
--- a/src/w32term.c
+++ b/src/w32term.c
@@ -4018,7 +4018,7 @@ static char dbcs_lead = 0;
    recursively with different messages by the system.
 */
 
-static int
+int
 w32_read_socket (struct terminal *terminal, int expected,
 		 struct input_event *hold_quit)
 {
@@ -6294,6 +6294,12 @@ w32_initialize (void)
 		   GetCurrentProcess (), &hMainThread, 0, TRUE, DUPLICATE_SAME_ACCESS);
 
   /* Wait for thread to start */
+#ifdef SINGLE_THREAD
+  DuplicateHandle (GetCurrentProcess (), GetCurrentThread (),
+                   GetCurrentProcess (), &hWindowsThread, 0, TRUE, DUPLICATE_SAME_ACCESS);
+  dwWindowsThreadId = GetCurrentThreadId ();
+  msh_mousewheel = RegisterWindowMessage (MSH_MOUSEWHEEL);
+#else
   {
     MSG msg;
 
@@ -6305,6 +6311,7 @@ w32_initialize (void)
 
     GetMessage (&msg, NULL, WM_EMACS_DONE, WM_EMACS_DONE);
   }
+#endif
 
   /* It is desirable that mainThread should have the same notion of
      focus window and active window as windowsThread.  Unfortunately, the
diff --git a/src/w32xfns.c b/src/w32xfns.c
index df9acca..a3c1af4 100644
--- a/src/w32xfns.c
+++ b/src/w32xfns.c
@@ -299,11 +299,19 @@ drain_message_queue (void)
   MSG msg;
   while (PeekMessage (&msg, NULL, 0, 0, PM_REMOVE))
     {
+#ifdef SINGLE_THREAD
+      dispatch_msg(&msg);
+#else
       TranslateMessage (&msg);
       DispatchMessage (&msg);
+#endif
     }
 }
 
+void w32_peek_messages()
+{
+    drain_message_queue ();
+}
 
 /*
  *    XParseGeometry parses strings of the form

^ permalink raw reply related	[flat|nested] 51+ messages in thread

* Re: [PATCH] system-type cygwin with window-system w32
  2011-07-18 10:49           ` Daniel Colascione
  2011-07-18 11:22             ` Juanma Barranquero
  2011-07-18 16:41             ` Eli Zaretskii
@ 2011-07-18 22:08             ` Richard Stallman
  2011-07-18 22:24               ` Daniel Colascione
  2011-07-21  1:44               ` Lennart Borgman
  2011-07-18 22:08             ` Richard Stallman
  3 siblings, 2 replies; 51+ messages in thread
From: Richard Stallman @ 2011-07-18 22:08 UTC (permalink / raw)
  To: Daniel Colascione; +Cc: eliz, emacs-devel

    I don't recall that discussion.  Can we reopen it?  According to [1],
    Windows 98 has a market share of 0.03%.

That must be hundreds of thousands of people.

We should not be in a hurry to delete code that is already in Emacs
and might be useful for someone.


-- 
Dr Richard Stallman
President, Free Software Foundation
51 Franklin St
Boston MA 02110
USA
www.fsf.org  www.gnu.org
Skype: No way! That's nonfree (freedom-denying) software.
  Use free telephony http://directory.fsf.org/category/tel/



^ permalink raw reply	[flat|nested] 51+ messages in thread

* Re: [PATCH] system-type cygwin with window-system w32
  2011-07-18 10:49           ` Daniel Colascione
                               ` (2 preceding siblings ...)
  2011-07-18 22:08             ` Richard Stallman
@ 2011-07-18 22:08             ` Richard Stallman
  3 siblings, 0 replies; 51+ messages in thread
From: Richard Stallman @ 2011-07-18 22:08 UTC (permalink / raw)
  To: Daniel Colascione; +Cc: eliz, emacs-devel

What is meant by "going all Unicode"?  That sounds like a drastic change.

-- 
Dr Richard Stallman
President, Free Software Foundation
51 Franklin St
Boston MA 02110
USA
www.fsf.org  www.gnu.org
Skype: No way! That's nonfree (freedom-denying) software.
  Use free telephony http://directory.fsf.org/category/tel/



^ permalink raw reply	[flat|nested] 51+ messages in thread

* Re: [PATCH] system-type cygwin with window-system w32
  2011-07-18 22:08             ` Richard Stallman
@ 2011-07-18 22:24               ` Daniel Colascione
  2011-07-18 22:45                 ` David Kastrup
  2011-07-21  1:44               ` Lennart Borgman
  1 sibling, 1 reply; 51+ messages in thread
From: Daniel Colascione @ 2011-07-18 22:24 UTC (permalink / raw)
  To: rms; +Cc: eliz, emacs-devel

[-- Attachment #1: Type: text/plain, Size: 1182 bytes --]

On 7/18/2011 3:08 PM, Richard Stallman wrote:
>     I don't recall that discussion.  Can we reopen it?  According to [1],
>     Windows 98 has a market share of 0.03%.
> 
> That must be hundreds of thousands of people.

~300,000 if we assume 1 billion people worldwide.  That's still
miniscule in proportion --- and of those 300,000, how many are savvy
enough to be Emacs users?

If there _are_ any remaining Windows 9X Emacs users, dropping 9X support
will be doing them a favor: using an OS that doesn't receive security
updates is terribly dangerous.  Besides, they'll always have Emacs 24
and below.

> We should not be in a hurry to delete code that is already in Emacs
> and might be useful for someone.

The code will always be there in the version control history.

On 7/18/2011 3:08 PM, Richard Stallman wrote:
> What is meant by "going all Unicode"?  That sounds like a drastic
> change.

Not really --- Each Windows API comes in two versions: an "ANSI" one
that accepts strings using legacy character encoding and a "Unicode" one
that accepts UTF-16LE strings.  All we have to do is start calling the
latter functions instead of the former.


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

^ permalink raw reply	[flat|nested] 51+ messages in thread

* Re: [PATCH] system-type cygwin with window-system w32
  2011-07-18 22:24               ` Daniel Colascione
@ 2011-07-18 22:45                 ` David Kastrup
  2011-07-18 22:56                   ` Daniel Colascione
  0 siblings, 1 reply; 51+ messages in thread
From: David Kastrup @ 2011-07-18 22:45 UTC (permalink / raw)
  To: emacs-devel

Daniel Colascione <dan.colascione@gmail.com> writes:

> On 7/18/2011 3:08 PM, Richard Stallman wrote:
>>     I don't recall that discussion.  Can we reopen it?  According to [1],
>>     Windows 98 has a market share of 0.03%.
>> 
>> That must be hundreds of thousands of people.
>
> ~300,000 if we assume 1 billion people worldwide.  That's still
> miniscule in proportion --- and of those 300,000, how many are savvy
> enough to be Emacs users?
>
> If there _are_ any remaining Windows 9X Emacs users, dropping 9X
> support will be doing them a favor: using an OS that doesn't receive
> security updates is terribly dangerous.

Why?  Not every computer is used for browsing the internet.

-- 
David Kastrup




^ permalink raw reply	[flat|nested] 51+ messages in thread

* Re: [PATCH] system-type cygwin with window-system w32
  2011-07-18 22:45                 ` David Kastrup
@ 2011-07-18 22:56                   ` Daniel Colascione
  2011-07-19 16:49                     ` Richard Stallman
  0 siblings, 1 reply; 51+ messages in thread
From: Daniel Colascione @ 2011-07-18 22:56 UTC (permalink / raw)
  To: David Kastrup; +Cc: emacs-devel

[-- Attachment #1: Type: text/plain, Size: 1432 bytes --]

On 7/18/2011 3:45 PM, David Kastrup wrote:
> Daniel Colascione <dan.colascione@gmail.com> writes:
> 
>> On 7/18/2011 3:08 PM, Richard Stallman wrote:
>>>     I don't recall that discussion.  Can we reopen it?  According to [1],
>>>     Windows 98 has a market share of 0.03%.
>>>
>>> That must be hundreds of thousands of people.
>>
>> ~300,000 if we assume 1 billion people worldwide.  That's still
>> miniscule in proportion --- and of those 300,000, how many are savvy
>> enough to be Emacs users?
>>
>> If there _are_ any remaining Windows 9X Emacs users, dropping 9X
>> support will be doing them a favor: using an OS that doesn't receive
>> security updates is terribly dangerous.
> 
> Why?  Not every computer is used for browsing the internet.

I'd argue that the vast majority of "computers" that can run Emacs are,
in fact, network-connected.  Most of what Emacs is good for involves the
network at one point or another.

Sure, there might be a few special-purpose known-good "appliance"
computers, but if one of these machines is still running Windows 9X, it
was probably configured years and years ago and not touched since,
except perhaps for the occasional goat sacrifice made to keep it
running.  Installing a new version of Emacs on these machines would be a
high-risk operation and wouldn't happen, and we're not talking about
retroactively removing support in older Emacs versions.


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

^ permalink raw reply	[flat|nested] 51+ messages in thread

* Re: [PATCH] system-type cygwin with window-system w32
  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
  1 sibling, 1 reply; 51+ messages in thread
From: Eli Zaretskii @ 2011-07-19  2:58 UTC (permalink / raw)
  To: dan.colascione; +Cc: emacs-devel

> Date: Mon, 18 Jul 2011 23:01:43 +0200
> From: grischka <grishka@gmx.de>
> Cc: emacs-devel@gnu.org
> 
> > Do you have a patch handy?
> 
> Attached.

Beware: grischka won't sign legal papers for getting his code into
Emacs, so you better not use this patch in your code, or else it will
not be accepted.



^ permalink raw reply	[flat|nested] 51+ messages in thread

* Re: [PATCH] system-type cygwin with window-system w32
  2011-07-19  2:58           ` Eli Zaretskii
@ 2011-07-19  2:59             ` Daniel Colascione
  0 siblings, 0 replies; 51+ messages in thread
From: Daniel Colascione @ 2011-07-19  2:59 UTC (permalink / raw)
  To: Eli Zaretskii; +Cc: emacs-devel

[-- Attachment #1: Type: text/plain, Size: 467 bytes --]

On 7/18/2011 7:58 PM, Eli Zaretskii wrote:
>> Date: Mon, 18 Jul 2011 23:01:43 +0200
>> From: grischka <grishka@gmx.de>
>> Cc: emacs-devel@gnu.org
>>
>>> Do you have a patch handy?
>>
>> Attached.
> 
> Beware: grischka won't sign legal papers for getting his code into
> Emacs, so you better not use this patch in your code, or else it will
> not be accepted.

Thanks for the tip --- it's a good thing I haven't had a chance to read
the patch anyway.


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

^ permalink raw reply	[flat|nested] 51+ messages in thread

* Re: [PATCH] system-type cygwin with window-system w32
  2011-07-18 22:56                   ` Daniel Colascione
@ 2011-07-19 16:49                     ` Richard Stallman
  0 siblings, 0 replies; 51+ messages in thread
From: Richard Stallman @ 2011-07-19 16:49 UTC (permalink / raw)
  To: Daniel Colascione; +Cc: dak, emacs-devel

Any machine that is running Windows ought to be defenestrated, moved to
GNU/Linux.  But it makes no sense to try to pressure people to do this
by dropping our Emacs support for some or all versions of Windows.

As for moving from one version of Windows to another, we should never
adopt that as a goal.  To encourage people to a upgrade Windows grants
legitimacy to Windows, and therefore contradicts the GNU Project
philosophy.  Please do not argue on that basis here.

-- 
Dr Richard Stallman
President, Free Software Foundation
51 Franklin St
Boston MA 02110
USA
www.fsf.org  www.gnu.org
Skype: No way! That's nonfree (freedom-denying) software.
  Use free telephony http://directory.fsf.org/category/tel/



^ permalink raw reply	[flat|nested] 51+ messages in thread

* Re: [PATCH] system-type cygwin with window-system w32
  2011-07-18 22:08             ` Richard Stallman
  2011-07-18 22:24               ` Daniel Colascione
@ 2011-07-21  1:44               ` Lennart Borgman
  1 sibling, 0 replies; 51+ messages in thread
From: Lennart Borgman @ 2011-07-21  1:44 UTC (permalink / raw)
  To: rms; +Cc: eliz, Daniel Colascione, emacs-devel

On Tue, Jul 19, 2011 at 00:08, Richard Stallman <rms@gnu.org> wrote:
>    I don't recall that discussion.  Can we reopen it?  According to [1],
>    Windows 98 has a market share of 0.03%.
>
> That must be hundreds of thousands of people.
>
> We should not be in a hurry to delete code that is already in Emacs
> and might be useful for someone.

If there really are any such users I doubt that they will upgrade to a
newer Emacs on that machine. So I see no reason keeping the support
for W9x.



^ permalink raw reply	[flat|nested] 51+ messages in thread

* Re: [PATCH] system-type cygwin with window-system w32
  2011-07-18 21:01         ` grischka
  2011-07-19  2:58           ` Eli Zaretskii
@ 2011-07-21 17:44           ` Lennart Borgman
  2011-07-22  7:30             ` Daniel Colascione
  1 sibling, 1 reply; 51+ messages in thread
From: Lennart Borgman @ 2011-07-21 17:44 UTC (permalink / raw)
  To: grischka; +Cc: Daniel Colascione, emacs-devel

What happened to this? Is not this a very important problem?

On Mon, Jul 18, 2011 at 23:01, grischka <grishka@gmx.de> wrote:
> Daniel Colascione wrote:
>>>
>>> Actually the NT build works quite well with one single thread.
>>> Already tested here.
>>
>> Do you have a patch handy?
>
> Attached.  Patch was against state at commit:
>
>      Jan D. <jan.h.d@swipnet.se>  2011-02-01 09:53:03
>      Use add/delete_read_fd in xsmfns to simplify.  Also ...
>
> Hopefully still applies cleanly.
>
> It is minimal, and maybe not quite obvious.  Basically the two window
> message switches (w32fns.c and w32term.c) could be merged into one.
> The patch calls the one from the other.
>
> There is an elisp variable 'w32-single-thread' which should return 1
> if you want to make sure you're using the right build. :)
>
> Note that you can for example drag the "Open File" dialog across the
> main window and it still gets redrawn.
>
>>> * peek for messages in the QUIT macro (say via ELSE_PENDING_SIGNALS)
>>>  which is for C-g to interrupt lisp.
>>
>> I don't think this approach alone would be sufficient.  I may be wrong,
>> but I think the Windows window manager will consider a program to be
>> "unresponsive" if it stops actually pumping messages; I don't think
>> peeking is sufficient.  Also, [1] says that we shouldn't delay pumping
>> messages even if we're able to guarantee we'll get around to them later.
>> (Running lisp code is indistinguishable from sleep in this case.)
>
>> Using PeekMessage in lisp code instead of actually pumping messages
>> would be like telling your credit card company, "Yeah, I got the bill,
>> and I'll get around to responding sometime in the next two years".  I
>> don't think it'd go over well.
>
> "Two years" or anyway "indistinguishable from sleep" is never really
> acceptable.  Because then emacs can't process key/mouse events
> regardless how many threads you have in the backend.
>
> We need to think in terms of UI timings here.  Reference is the kbd
> repeat rate, say 30ms, which is also in the range of eye perception
> capability and frame repeat rates.  Up to this is smooth.  More can
> be tolerable though, even up to 1 or more seconds.  Say for popping
> up new windows, frames, etc.
>
> So if your elisp doesn't finish in 30ms, you know ;)
>
>>> * break command_loop_1() such that it can be used to handle just one
>>>  event which is to handle scrollbar messages because the widgets
>>>  run their own message loop deep in windows.  Otherwise all the
>>>  scrolling would happen only after you release the mouse button.
>>
>> I doubt that the scrollbar is the only special case we'd need to consider.
>
> AFAICS scrollbar and paint. And maybe clipboard rendering.  Emacs
> handles paint directly via expose_frame() though, not via the event
> queue.
>
>> I don't understand how this approach helps.  The problem, AIUI, isn't
>> that we have Lisp events, but that we read input and wait for processes
>> in many places, and it's hard to be confident that each place we pump
>> messages is a safe place to process lisp code.  I don't understand how
>> draining the lisp event queue would help.
>
> As I see it this is just recursion.   Such things happen all the time
> in all GUIs that use callbacks.  Windows, GTK, whatever.  It happens
> in emacs already:
>
>      (run-with-idle-timer ... lisp-code)
>
> --- grischka
>
>
> diff --git a/nt/config.nt b/nt/config.nt
> index d612a41..dd4cd38 100644
> --- a/nt/config.nt
> +++ b/nt/config.nt
> @@ -467,6 +467,8 @@ extern char *getenv ();
>  #endif
>  #endif
>
> +#define SINGLE_THREAD
> +
>  /* Redefine abort.  */
>  #ifdef HAVE_NTGUI
>  #define abort  w32_abort
> diff --git a/src/keyboard.c b/src/keyboard.c
> index d533213..e824682 100644
> --- a/src/keyboard.c
> +++ b/src/keyboard.c
> @@ -1290,7 +1290,7 @@ cancel_hourglass_unwind (Lisp_Object arg)
>  EXFUN (Fwindow_system, 1);
>
>  Lisp_Object
> -command_loop_1 (void)
> +command_loop_1a (int repeat)
>  {
>   Lisp_Object cmd;
>   Lisp_Object keybuf[30];
> @@ -1336,7 +1336,7 @@ command_loop_1 (void)
>   if (!CONSP (last_command_event))
>     current_kboard->Vlast_repeatable_command = real_this_command;
>
> -  while (1)
> +  while (repeat || detect_input_pending())
>     {
>       if (! FRAME_LIVE_P (XFRAME (selected_frame)))
>        Fkill_emacs (Qnil);
> @@ -1659,6 +1659,12 @@ command_loop_1 (void)
>     }
>  }
>
> +Lisp_Object
> +command_loop_1 ()
> +{
> +    return command_loop_1a(1);
> +}
> +
>  /* Adjust point to a boundary of a region that has such a property
>    that should be treated intangible.  For the moment, we check
>    `composition', `display' and `invisible' properties.
> diff --git a/src/lisp.h b/src/lisp.h
> index cfff42a..efe76f6 100644
> --- a/src/lisp.h
> +++ b/src/lisp.h
> @@ -2013,6 +2013,10 @@ extern char *stack_bottom;
>    This is a good thing to do around a loop that has no side effects
>    and (in particular) cannot call arbitrary Lisp code.  */
>
> +#if defined HAVE_NTGUI && defined SINGLE_THREAD
> +#define ELSE_PENDING_SIGNALS else w32_peek_messages();
> +void w32_peek_messages();
> +#else
>  #ifdef SYNC_INPUT
>  extern void process_pending_signals (void);
>  extern int pending_signals;
> @@ -2022,6 +2026,7 @@ extern int pending_signals;
>  #else  /* not SYNC_INPUT */
>  #define ELSE_PENDING_SIGNALS
>  #endif /* not SYNC_INPUT */
> +#endif /* not HAVE_NTGUI */
>
>  #define QUIT                                           \
>   do {                                                 \
> diff --git a/src/w32fns.c b/src/w32fns.c
> index b09bb0b..93f80f9 100644
> --- a/src/w32fns.c
> +++ b/src/w32fns.c
> @@ -87,6 +87,10 @@ extern const char *const lispy_function_keys[];
>  static unsigned hourglass_timer = 0;
>  static HWND hourglass_hwnd = NULL;
>
> +#ifdef SINGLE_THREAD
> +int w32_single_thread;
> +#endif
> +
>  #ifndef IDC_HAND
>  #define IDC_HAND MAKEINTRESOURCE(32649)
>  #endif
> @@ -2242,17 +2246,15 @@ unregister_hot_keys (HWND hwnd)
>
>  /* Main message dispatch loop. */
>
> -static void
> -w32_msg_pump (deferred_msg * msg_buf)
> +unsigned dispatch_msg (MSG *pmsg)
>  {
>   MSG msg;
>   int result;
>   HWND focus_window;
>
> -  msh_mousewheel = RegisterWindowMessage (MSH_MOUSEWHEEL);
> +  result = 0;
> +  msg = *pmsg;
>
> -  while (GetMessage (&msg, NULL, 0, 0))
> -    {
>       if (msg.hwnd == NULL)
>        {
>          switch (msg.message)
> @@ -2269,8 +2271,10 @@ w32_msg_pump (deferred_msg * msg_buf)
>                  and older versions will never be patched.  */
>               CoInitialize (NULL);
>              w32_createwindow ((struct frame *) msg.wParam);
> +#ifndef SINGLE_THREAD
>              if (!PostThreadMessage (dwMainThreadId, WM_EMACS_DONE, 0, 0))
>                abort ();
> +#endif
>              break;
>            case WM_EMACS_SETLOCALE:
>              SetThreadLocale (msg.wParam);
> @@ -2278,9 +2282,11 @@ w32_msg_pump (deferred_msg * msg_buf)
>              break;
>            case WM_EMACS_SETKEYBOARDLAYOUT:
>              result = (int) ActivateKeyboardLayout ((HKL) msg.wParam, 0);
> +#ifndef SINGLE_THREAD
>              if (!PostThreadMessage (dwMainThreadId, WM_EMACS_DONE,
>                                      result, 0))
>                abort ();
> +#endif
>              break;
>            case WM_EMACS_REGISTER_HOT_KEY:
>              focus_window = GetFocus ();
> @@ -2300,8 +2306,10 @@ w32_msg_pump (deferred_msg * msg_buf)
>                  cell is never made into garbage and is not relocated by
>                  GC.  */
>              XSETCAR ((Lisp_Object) ((EMACS_INT) msg.lParam), Qnil);
> +#ifndef SINGLE_THREAD
>              if (!PostThreadMessage (dwMainThreadId, WM_EMACS_DONE, 0, 0))
>                abort ();
> +#endif
>              break;
>            case WM_EMACS_TOGGLE_LOCK_KEY:
>              {
> @@ -2331,9 +2339,12 @@ w32_msg_pump (deferred_msg * msg_buf)
>                                 KEYEVENTF_EXTENDEDKEY | KEYEVENTF_KEYUP, 0);
>                    cur_state = !cur_state;
>                  }
> +#ifndef SINGLE_THREAD
>                if (!PostThreadMessage (dwMainThreadId, WM_EMACS_DONE,
>                                        cur_state, 0))
>                  abort ();
> +#endif
> +               result = cur_state;
>              }
>              break;
>  #ifdef MSG_DEBUG
> @@ -2349,11 +2360,37 @@ w32_msg_pump (deferred_msg * msg_buf)
>          DispatchMessage (&msg);
>        }
>
> +    return result;
> +}
> +
> +static void
> +w32_msg_pump (deferred_msg * msg_buf)
> +{
> +#ifndef SINGLE_THREAD
> +  MSG msg;
> +  msh_mousewheel = RegisterWindowMessage (MSH_MOUSEWHEEL);
> +  while (GetMessage (&msg, NULL, 0, 0))
> +    {
> +      dispatch_msg(&msg);
>       /* Exit nested loop when our deferred message has completed.  */
>       if (msg_buf->completed)
>        break;
>     }
> +#endif
> +}
> +
> +#ifdef SINGLE_THREAD
> +unsigned do_thread_msg(unsigned threadid, unsigned umsg, WPARAM wParam,
> LPARAM lParam)
> +{
> +    MSG msg;
> +    msg.hwnd = NULL;
> +    msg.message = umsg;
> +    msg.wParam = wParam;
> +    msg.lParam = lParam;
> +    return dispatch_msg(&msg);
>  }
> +#endif
> +
>
>  deferred_msg * deferred_msg_head;
>
> @@ -2427,7 +2464,9 @@ complete_deferred_msg (HWND hwnd, UINT msg, LRESULT
> result)
>   msg_buf->completed = 1;
>
>   /* Ensure input thread is woken so it notices the completion.  */
> +#ifndef SINGLE_THREAD
>   PostThreadMessage (dwWindowsThreadId, WM_NULL, 0, 0);
> +#endif
>  }
>
>  static void
> @@ -2448,7 +2487,9 @@ cancel_all_deferred_msgs (void)
>   /* leave_crit (); */
>
>   /* Ensure input thread is woken so it notices the completion.  */
> +#ifndef SINGLE_THREAD
>   PostThreadMessage (dwWindowsThreadId, WM_NULL, 0, 0);
> +#endif
>  }
>
>  DWORD WINAPI
> @@ -2654,6 +2695,10 @@ w32_wnd_proc (HWND hwnd, UINT msg, WPARAM wParam,
> LPARAM lParam)
>               dedicated to one frame and does not bother checking
>               that hwnd matches before combining them.  */
>             my_post_msg (&wmsg, hwnd, WM_EMACS_PAINT, wParam, lParam);
> +#ifdef SINGLE_THREAD
> +            w32_read_socket(0, 0, NULL);
> +            //command_loop_1a(0);
> +#endif
>
>             return 0;
>           }
> @@ -3205,6 +3250,10 @@ w32_wnd_proc (HWND hwnd, UINT msg, WPARAM wParam,
> LPARAM lParam)
>        {
>          wmsg.dwModifiers = w32_get_modifiers ();
>          my_post_msg (&wmsg, hwnd, msg, wParam, lParam);
> +#ifdef SINGLE_THREAD
> +          if (msg == WM_VSCROLL)
> +            command_loop_1a(0);
> +#endif
>          return 0;
>        }
>
> @@ -3808,11 +3857,15 @@ w32_wnd_proc (HWND hwnd, UINT msg, WPARAM wParam,
> LPARAM lParam)
>  static void
>  my_create_window (struct frame * f)
>  {
> +#ifdef SINGLE_THREAD
> +  do_thread_msg (dwWindowsThreadId, WM_EMACS_CREATEWINDOW, (WPARAM)f, 0);
> +#else
>   MSG msg;
>
>   if (!PostThreadMessage (dwWindowsThreadId, WM_EMACS_CREATEWINDOW,
> (WPARAM)f, 0))
>     abort ();
>   GetMessage (&msg, NULL, WM_EMACS_DONE, WM_EMACS_DONE);
> +#endif
>  }
>
>
> @@ -6308,6 +6361,15 @@ The return value is the hotkey-id if registered,
> otherwise nil.  */)
>
>       /* Notify input thread about new hot-key definition, so that it
>         takes effect without needing to switch focus.  */
> +#ifdef SINGLE_THREAD
> +#ifdef USE_LISP_UNION_TYPE
> +      do_thread_msg (dwWindowsThreadId, WM_EMACS_REGISTER_HOT_KEY,
> +                         (WPARAM) key.i, 0);
> +#else
> +      do_thread_msg (dwWindowsThreadId, WM_EMACS_REGISTER_HOT_KEY,
> +                         (WPARAM) key, 0);
> +#endif
> +#else
>  #ifdef USE_LISP_UNION_TYPE
>       PostThreadMessage (dwWindowsThreadId, WM_EMACS_REGISTER_HOT_KEY,
>                         (WPARAM) key.i, 0);
> @@ -6315,6 +6377,7 @@ The return value is the hotkey-id if registered,
> otherwise nil.  */)
>       PostThreadMessage (dwWindowsThreadId, WM_EMACS_REGISTER_HOT_KEY,
>                         (WPARAM) key, 0);
>  #endif
> +#endif
>     }
>
>   return key;
> @@ -6336,6 +6399,16 @@ DEFUN ("w32-unregister-hot-key",
> Fw32_unregister_hot_key,
>     {
>       /* Notify input thread about hot-key definition being removed, so
>         that it takes effect without needing focus switch.  */
> +#ifdef SINGLE_THREAD
> +#ifdef USE_LISP_UNION_TYPE
> +      do_thread_msg (dwWindowsThreadId, WM_EMACS_UNREGISTER_HOT_KEY,
> +                             (WPARAM) XINT (XCAR (item)), (LPARAM) item.i);
> +#else
> +      do_thread_msg (dwWindowsThreadId, WM_EMACS_UNREGISTER_HOT_KEY,
> +                             (WPARAM) XINT (XCAR (item)), (LPARAM) item);
> +
> +#endif
> +#else
>  #ifdef USE_LISP_UNION_TYPE
>       if (PostThreadMessage (dwWindowsThreadId, WM_EMACS_UNREGISTER_HOT_KEY,
>                             (WPARAM) XINT (XCAR (item)), (LPARAM) item.i))
> @@ -6347,6 +6420,7 @@ DEFUN ("w32-unregister-hot-key",
> Fw32_unregister_hot_key,
>          MSG msg;
>          GetMessage (&msg, NULL, WM_EMACS_DONE, WM_EMACS_DONE);
>        }
> +#endif
>       return Qt;
>     }
>   return Qnil;
> @@ -6401,6 +6475,9 @@ is set to off if the low bit of NEW-STATE is zero,
> otherwise on.  */)
>   (Lisp_Object key, Lisp_Object new_state)
>  {
>   int vk_code;
> +#ifdef SINGLE_THREAD
> +  unsigned ret;
> +#endif
>
>   if (EQ (key, intern ("capslock")))
>     vk_code = VK_CAPITAL;
> @@ -6414,6 +6491,16 @@ is set to off if the low bit of NEW-STATE is zero,
> otherwise on.  */)
>   if (!dwWindowsThreadId)
>     return make_number (w32_console_toggle_lock_key (vk_code, new_state));
>
> +#ifdef SINGLE_THREAD
> +#ifdef USE_LISP_UNION_TYPE
> +  ret = do_thread_msg (dwWindowsThreadId, WM_EMACS_TOGGLE_LOCK_KEY,
> +                         (WPARAM) vk_code, (LPARAM) new_state.i);
> +#else
> +  ret = do_thread_msg (dwWindowsThreadId, WM_EMACS_TOGGLE_LOCK_KEY,
> +                         (WPARAM) vk_code, (LPARAM) new_state);
> +#endif
> +  return make_number (ret);
> +#else
>  #ifdef USE_LISP_UNION_TYPE
>   if (PostThreadMessage (dwWindowsThreadId, WM_EMACS_TOGGLE_LOCK_KEY,
>                         (WPARAM) vk_code, (LPARAM) new_state.i))
> @@ -6427,6 +6514,7 @@ is set to off if the low bit of NEW-STATE is zero,
> otherwise on.  */)
>       return make_number (msg.wParam);
>     }
>   return Qnil;
> +#endif
>  }
>
>  DEFUN ("w32-window-exists-p", Fw32_window_exists_p, Sw32_window_exists_p,
> @@ -7053,6 +7141,14 @@ Set this to nil to get the old behavior for
> repainting; this should
>  only be necessary if the default setting causes problems.  */);
>   w32_strict_painting = 1;
>
> +#ifdef SINGLE_THREAD
> +  DEFVAR_BOOL ("w32-single-thread",
> +              &w32_single_thread,
> +              doc: /* using single thread */);
> +
> +  w32_single_thread = 1;
> +#endif
> +
>  #if 0 /* TODO: Port to W32 */
>   defsubr (&Sx_change_window_property);
>   defsubr (&Sx_delete_window_property);
> diff --git a/src/w32proc.c b/src/w32proc.c
> index 1c009c7..49eab27 100644
> --- a/src/w32proc.c
> +++ b/src/w32proc.c
> @@ -2028,7 +2028,11 @@ If successful, the new locale id is returned,
> otherwise nil.  */)
>   /* Need to set input thread locale if present.  */
>   if (dwWindowsThreadId)
>     /* Reply is not needed.  */
> +#ifdef SINGLE_THREAD
> +    do_thread_msg (dwWindowsThreadId, WM_EMACS_SETLOCALE, XINT (lcid), 0);
> +#else
>     PostThreadMessage (dwWindowsThreadId, WM_EMACS_SETLOCALE, XINT (lcid),
> 0);
> +#endif
>
>   return make_number (GetThreadLocale ());
>  }
> @@ -2194,6 +2198,10 @@ If successful, the new layout id is returned,
> otherwise nil.  */)
>   /* Synchronize layout with input thread.  */
>   if (dwWindowsThreadId)
>     {
> +#ifdef SINGLE_THREAD
> +      if (0 == do_thread_msg (dwWindowsThreadId,
> WM_EMACS_SETKEYBOARDLAYOUT, (WPARAM) kl, 0))
> +        return Qnil;
> +#else
>       if (PostThreadMessage (dwWindowsThreadId, WM_EMACS_SETKEYBOARDLAYOUT,
>                             (WPARAM) kl, 0))
>        {
> @@ -2203,6 +2211,7 @@ If successful, the new layout id is returned,
> otherwise nil.  */)
>          if (msg.wParam == 0)
>            return Qnil;
>        }
> +#endif
>     }
>   else if (!ActivateKeyboardLayout ((HKL) kl, 0))
>     return Qnil;
> diff --git a/src/w32term.c b/src/w32term.c
> index cd4ee54..83eed4a 100644
> --- a/src/w32term.c
> +++ b/src/w32term.c
> @@ -4018,7 +4018,7 @@ static char dbcs_lead = 0;
>    recursively with different messages by the system.
>  */
>
> -static int
> +int
>  w32_read_socket (struct terminal *terminal, int expected,
>                 struct input_event *hold_quit)
>  {
> @@ -6294,6 +6294,12 @@ w32_initialize (void)
>                   GetCurrentProcess (), &hMainThread, 0, TRUE,
> DUPLICATE_SAME_ACCESS);
>
>   /* Wait for thread to start */
> +#ifdef SINGLE_THREAD
> +  DuplicateHandle (GetCurrentProcess (), GetCurrentThread (),
> +                   GetCurrentProcess (), &hWindowsThread, 0, TRUE,
> DUPLICATE_SAME_ACCESS);
> +  dwWindowsThreadId = GetCurrentThreadId ();
> +  msh_mousewheel = RegisterWindowMessage (MSH_MOUSEWHEEL);
> +#else
>   {
>     MSG msg;
>
> @@ -6305,6 +6311,7 @@ w32_initialize (void)
>
>     GetMessage (&msg, NULL, WM_EMACS_DONE, WM_EMACS_DONE);
>   }
> +#endif
>
>   /* It is desirable that mainThread should have the same notion of
>      focus window and active window as windowsThread.  Unfortunately, the
> diff --git a/src/w32xfns.c b/src/w32xfns.c
> index df9acca..a3c1af4 100644
> --- a/src/w32xfns.c
> +++ b/src/w32xfns.c
> @@ -299,11 +299,19 @@ drain_message_queue (void)
>   MSG msg;
>   while (PeekMessage (&msg, NULL, 0, 0, PM_REMOVE))
>     {
> +#ifdef SINGLE_THREAD
> +      dispatch_msg(&msg);
> +#else
>       TranslateMessage (&msg);
>       DispatchMessage (&msg);
> +#endif
>     }
>  }
>
> +void w32_peek_messages()
> +{
> +    drain_message_queue ();
> +}
>
>  /*
>  *    XParseGeometry parses strings of the form
>
>



^ permalink raw reply	[flat|nested] 51+ messages in thread

* Re: [PATCH] system-type cygwin with window-system w32
  2011-07-21 17:44           ` Lennart Borgman
@ 2011-07-22  7:30             ` Daniel Colascione
  2011-07-22  7:41               ` Lennart Borgman
  0 siblings, 1 reply; 51+ messages in thread
From: Daniel Colascione @ 2011-07-22  7:30 UTC (permalink / raw)
  To: Lennart Borgman; +Cc: grischka, emacs-devel

[-- Attachment #1: Type: text/plain, Size: 265 bytes --]

On 7/21/11 10:44 AM, Lennart Borgman wrote:
> What happened to this? Is not this a very important problem?

No.  Our current multi-thread approach may be clunky, but it's worked fine for
many years.  I don't see a reason to change it for cleanliness's sake.


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

^ permalink raw reply	[flat|nested] 51+ messages in thread

* Re: [PATCH] system-type cygwin with window-system w32
  2011-07-22  7:30             ` Daniel Colascione
@ 2011-07-22  7:41               ` Lennart Borgman
  2011-07-22 21:24                 ` chad
  0 siblings, 1 reply; 51+ messages in thread
From: Lennart Borgman @ 2011-07-22  7:41 UTC (permalink / raw)
  To: Daniel Colascione; +Cc: grischka, emacs-devel

On Fri, Jul 22, 2011 at 09:30, Daniel Colascione
<dan.colascione@gmail.com> wrote:
> On 7/21/11 10:44 AM, Lennart Borgman wrote:
>> What happened to this? Is not this a very important problem?
>
> No.  Our current multi-thread approach may be clunky, but it's worked fine for
> many years.  I don't see a reason to change it for cleanliness's sake.

I do not think it works very well all the time. There are problems
with timing when creating frames for example. Emacs can become
unresponsive due to those and also because of network activity.

Did not grishka had some other examples too?



^ permalink raw reply	[flat|nested] 51+ messages in thread

* Re: [PATCH] system-type cygwin with window-system w32
  2011-07-22  7:41               ` Lennart Borgman
@ 2011-07-22 21:24                 ` chad
  2011-07-22 21:57                   ` Lennart Borgman
  0 siblings, 1 reply; 51+ messages in thread
From: chad @ 2011-07-22 21:24 UTC (permalink / raw)
  To: Lennart Borgman; +Cc: grischka, Emacs devel

On Jul 22, 2011, at 12:41 AM, Lennart Borgman wrote:

> I do not think it works very well all the time. There are problems
> with timing when creating frames for example. Emacs can become
> unresponsive due to those and also because of network activity.
> 
> Did not grishka had some other examples too?

Unless Eli was wrong or Grishka has changed his mind, the patch is 
unusable, so what would you like to do about it?

Are there specific problems that you can report, or is it more of a
heisen-race?

*Chad




^ permalink raw reply	[flat|nested] 51+ messages in thread

* Re: [PATCH] system-type cygwin with window-system w32
  2011-07-22 21:24                 ` chad
@ 2011-07-22 21:57                   ` Lennart Borgman
  0 siblings, 0 replies; 51+ messages in thread
From: Lennart Borgman @ 2011-07-22 21:57 UTC (permalink / raw)
  To: chad; +Cc: grischka, Emacs devel

On Fri, Jul 22, 2011 at 23:24, chad <yandros@mit.edu> wrote:
> On Jul 22, 2011, at 12:41 AM, Lennart Borgman wrote:
>
>> I do not think it works very well all the time. There are problems
>> with timing when creating frames for example. Emacs can become
>> unresponsive due to those and also because of network activity.
>>
>> Did not grishka had some other examples too?
>
> Unless Eli was wrong or Grishka has changed his mind, the patch is
> unusable, so what would you like to do about it?
>
> Are there specific problems that you can report, or is it more of a
> heisen-race?

There is nothing I can report now. I am not using Emacs that way right
now and I do not remember the details.



^ permalink raw reply	[flat|nested] 51+ messages in thread

end of thread, other threads:[~2011-07-22 21:57 UTC | newest]

Thread overview: 51+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2011-07-18  0:01 [PATCH] system-type cygwin with window-system w32 Daniel Colascione
2011-07-18  0:06 ` 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

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).