From: Daniel Colascione <dan.colascione@gmail.com>
To: Emacs development discussions <emacs-devel@gnu.org>
Subject: [PATCH] system-type cygwin with window-system w32
Date: Sun, 17 Jul 2011 17:01:38 -0700 [thread overview]
Message-ID: <4E2377E2.1020804@gmail.com> (raw)
[-- Attachment #1.1: Type: text/plain, Size: 1019 bytes --]
This patch makes it possible to use the NT GUI with a Cygwin core Emacs.
The patch is still a little rough around the edges, but it works well
enough to let me do real work in this new Emacs configuration. For me,
at least, forgoing the hassle of an X server and gaining some
integration makes the new configuration worthwhile.
(Of course, I don't plan to merge this before the feature freeze ends.
Do we have an emacs-next branch of some sort?)
What works:
- All the usual Cygwin features, including multitty, real ptys, job
control, etc.
- Native NT GUI
- File dialogs
What's new:
- Rewritten clipboard system mostly implemented in lisp
- Preserving formatting when copying text into other applications
(probably better structured as a separate package using the extensible
clipboard system)
What doesn't work yet:
- The normal NT build (I don't have a toolchain to test it)
- Graphical menus in customize
What I haven't tested:
- Image support
[-- Attachment #1.2: cygwin-w32.patch --]
[-- Type: text/plain, Size: 136534 bytes --]
=== modified file 'configure.in'
--- configure.in 2011-07-13 10:36:12 +0000
+++ configure.in 2011-07-17 10:24:18 +0000
@@ -168,6 +168,7 @@
OPTION_DEFAULT_ON([xaw3d],[don't use Xaw3d])
OPTION_DEFAULT_ON([xim],[don't use X11 XIM])
OPTION_DEFAULT_OFF([ns],[use NeXTstep (Cocoa or GNUstep) windowing system])
+OPTION_DEFAULT_OFF([w32], [use a Win32])
OPTION_DEFAULT_ON([gpm],[don't use -lgpm for mouse support on a GNU/Linux console])
OPTION_DEFAULT_ON([dbus],[don't compile with D-Bus support])
@@ -1534,6 +1535,7 @@
NS_HAVE_NSINTEGER=no
fi
fi
+
AC_SUBST(TEMACS_LDFLAGS2)
ns_frag=/dev/null
@@ -1559,6 +1561,31 @@
AC_SUBST(LIB_STANDARD)
AC_SUBST_FILE(ns_frag)
+HAVE_W32=no
+W32_OBJ=
+W32_LIBS=
+if test "${with_w32}" != no; then
+ if test "${opsys}" != "cygwin"; then
+ AC_MSG_ERROR([Using win32 with an autotools build is only supported for Cygwin.])
+ fi
+ AC_CHECK_HEADER([windows.h], [HAVE_W32=yes],
+ [AC_MSG_ERROR([`--with-w32' was specified, but windows.h
+ cannot be found.])])
+ AC_DEFINE(HAVE_NTGUI, 1, [Define to use native Windows GUI.])
+ W32_OBJ="w32fns.o w32menu.o w32reg.o fringe.o"
+ W32_OBJ="$W32_OBJ fontset.o w32font.o w32term.o"
+ W32_OBJ="$W32_OBJ w32xfns.o w32select.o image.o w32uniscribe.o"
+ W32_LIBS="$W32_LIBS -lkernel32 -luser32 -lgdi32 -lole32 -lcomdlg32"
+ W32_LIBS="$W32_LIBS -lusp10 -lcomctl32 -lwinspool"
+fi
+AC_SUBST(W32_OBJ)
+AC_SUBST(W32_LIBS)
+
+if test "${HAVE_W32}" = "yes"; then
+ window_system=w32
+ with_xft=no
+fi
+
case "${window_system}" in
x11 )
HAVE_X_WINDOWS=yes
@@ -1578,6 +1605,11 @@
* ) USE_X_TOOLKIT=maybe ;;
esac
;;
+ w32 )
+ HAVE_X_WINDOWS=no
+ HAVE_X11=no
+ USE_X_TOOLKIT=none
+ ;;
nextstep | none )
HAVE_X_WINDOWS=no
HAVE_X11=no
@@ -2222,6 +2254,9 @@
elif test "${HAVE_NS}" = "yes"; then
AC_DEFINE(USE_TOOLKIT_SCROLL_BARS)
USE_TOOLKIT_SCROLL_BARS=yes
+ elif test "${HAVE_W32}" = "yes"; then
+ AC_DEFINE(USE_TOOLKIT_SCROLL_BARS)
+ USE_TOOLKIT_SCROLL_BARS=yes
fi
fi
@@ -2572,6 +2607,9 @@
OTHER_FILES=ns-app
fi
+if test "${HAVE_W32}" = "yes"; then
+ HAVE_MENUS=yes
+fi
### Use session management (-lSM -lICE) if available
HAVE_X_SM=no
@@ -3317,7 +3355,7 @@
AC_SUBST(RALLOC_OBJ)
if test "$opsys" = "cygwin"; then
- CYGWIN_OBJ="sheap.o"
+ CYGWIN_OBJ="sheap.o cygw32.o"
## Cygwin differs because of its unexec().
PRE_ALLOC_OBJ=
POST_ALLOC_OBJ=lastfile.o
@@ -3467,8 +3505,11 @@
AC_SUBST(LIB_GCC)
-## If we're using X11/GNUstep, define some consequences.
-if test "$HAVE_X_WINDOWS" = "yes" || test "$HAVE_NS" = "yes"; then
+## If we're using X11, GNUstep, or Cygwin-Win32, define some
+## consequences.
+if test "$HAVE_X_WINDOWS" = "yes" || test "$HAVE_NS" = "yes" ||
+ test "$HAVE_W32" = "yes"
+then
AC_DEFINE(HAVE_WINDOW_SYSTEM, 1, [Define if you have a window system.])
AC_DEFINE(HAVE_MOUSE, 1, [Define if you have mouse support.])
fi
=== modified file 'lib/filemode.c'
--- lib/filemode.c 2011-02-20 10:51:50 +0000
+++ lib/filemode.c 2011-07-16 11:34:30 +0000
@@ -73,19 +73,36 @@
if (S_ISSOCK (bits))
return 's';
+#ifdef S_ISCTG
/* Nonstandard file types. */
if (S_ISCTG (bits))
return 'C';
+#endif
+
+#ifdef S_ISDOOR
if (S_ISDOOR (bits))
return 'D';
+#endif
+
+#ifdef S_ISMPB
if (S_ISMPB (bits) || S_ISMPC (bits))
return 'm';
+#endif
+
+#ifdef S_ISNWK
if (S_ISNWK (bits))
return 'n';
+#endif
+
+#ifdef S_ISPORT
if (S_ISPORT (bits))
return 'P';
+#endif
+
+#ifdef S_ISWHT
if (S_ISWHT (bits))
return 'w';
+#endif
return '?';
}
=== modified file 'lisp/battery.el'
--- lisp/battery.el 2011-06-27 08:04:55 +0000
+++ lisp/battery.el 2011-07-17 12:33:54 +0000
@@ -57,7 +57,7 @@
(> (buffer-size) 0)))
(error nil)))
'battery-pmset)
- ((eq system-type 'windows-nt)
+ ((fboundp 'w32-battery-status)
'w32-battery-status))
"Function for getting battery status information.
The function has to return an alist of conversion definitions.
=== modified file 'lisp/faces.el'
--- lisp/faces.el 2011-07-10 02:04:45 +0000
+++ lisp/faces.el 2011-07-17 12:36:34 +0000
@@ -89,7 +89,7 @@
;; This is defined originally in xfaces.c.
(defcustom face-font-registry-alternatives
(mapcar (lambda (arg) (mapcar 'purecopy arg))
- (if (eq system-type 'windows-nt)
+ (if (featurep 'w32)
'(("iso8859-1" "ms-oemlatin")
("gb2312.1980" "gb2312" "gbk" "gb18030")
("jisx0208.1990" "jisx0208.1983" "jisx0208.1978")
=== modified file 'lisp/loadup.el'
--- lisp/loadup.el 2011-07-06 22:43:48 +0000
+++ lisp/loadup.el 2011-07-16 14:45:18 +0000
@@ -207,15 +207,17 @@
(load "term/common-win")
(load "term/x-win")))
-(if (eq system-type 'windows-nt)
+(if (or (eq system-type 'windows-nt)
+ (featurep 'w32))
(progn
(load "w32-vars")
(load "term/common-win")
(load "term/w32-win")
- (load "ls-lisp")
(load "disp-table")
- (load "dos-w32")
- (load "w32-fns")))
+ (when (eq system-type 'windows-nt)
+ (load "ls-lisp")
+ (load "dos-w32")
+ (load "w32-fns"))))
(if (eq system-type 'ms-dos)
(progn
(load "dos-w32")
=== modified file 'lisp/mouse.el'
--- lisp/mouse.el 2011-07-14 14:01:16 +0000
+++ lisp/mouse.el 2011-07-17 12:31:18 +0000
@@ -1277,7 +1277,7 @@
(or mouse-yank-at-point (mouse-set-point click))
(let ((primary
(cond
- ((eq system-type 'windows-nt)
+ ((eq (framep (selected-frame)) 'w32)
;; MS-Windows emulates PRIMARY in x-get-selection, but not
;; in x-get-selection-value (the latter only accesses the
;; clipboard). So try PRIMARY first, in case they selected
=== modified file 'lisp/simple.el'
--- lisp/simple.el 2011-07-13 23:35:36 +0000
+++ lisp/simple.el 2011-07-17 12:38:50 +0000
@@ -6550,7 +6550,7 @@
(if (if (eq normal-erase-is-backspace 'maybe)
(and (not noninteractive)
(or (memq system-type '(ms-dos windows-nt))
- (memq window-system '(ns))
+ (memq window-system '(w32 ns))
(and (memq window-system '(x))
(fboundp 'x-backspace-delete-keys-p)
(x-backspace-delete-keys-p))
=== modified file 'lisp/term/common-win.el'
--- lisp/term/common-win.el 2011-01-25 04:08:28 +0000
+++ lisp/term/common-win.el 2011-07-17 12:26:34 +0000
@@ -57,7 +57,7 @@
On Nextstep, put TEXT in the pasteboard (`x-select-enable-clipboard'
is not used)."
- (cond ((eq system-type 'windows-nt)
+ (cond ((eq (framep (selected-frame)) 'w32)
(if x-select-enable-clipboard
(w32-set-clipboard-data text))
(setq x-last-selected-text text))
=== modified file 'lisp/term/w32-win.el'
--- lisp/term/w32-win.el 2011-05-04 14:03:16 +0000
+++ lisp/term/w32-win.el 2011-07-17 23:04:45 +0000
@@ -36,30 +36,30 @@
;; These are the standard X switches from the Xt Initialize.c file of
;; Release 4.
-;; Command line Resource Manager string
+;; Command line Resource Manager string
-;; +rv *reverseVideo
-;; +synchronous *synchronous
-;; -background *background
-;; -bd *borderColor
-;; -bg *background
-;; -bordercolor *borderColor
-;; -borderwidth .borderWidth
-;; -bw .borderWidth
-;; -display .display
-;; -fg *foreground
-;; -fn *font
-;; -font *font
-;; -foreground *foreground
-;; -geometry .geometry
-;; -i .iconType
-;; -itype .iconType
-;; -iconic .iconic
-;; -name .name
-;; -reverse *reverseVideo
-;; -rv *reverseVideo
+;; +rv *reverseVideo
+;; +synchronous *synchronous
+;; -background *background
+;; -bd *borderColor
+;; -bg *background
+;; -bordercolor *borderColor
+;; -borderwidth .borderWidth
+;; -bw .borderWidth
+;; -display .display
+;; -fg *foreground
+;; -fn *font
+;; -font *font
+;; -foreground *foreground
+;; -geometry .geometry
+;; -i .iconType
+;; -itype .iconType
+;; -iconic .iconic
+;; -name .name
+;; -reverse *reverseVideo
+;; -rv *reverseVideo
;; -selectionTimeout .selectionTimeout
-;; -synchronous *synchronous
+;; -synchronous *synchronous
;; -xrm
;; An alist of X options and the function which handles them. See
@@ -110,23 +110,23 @@
;; before setting the selected frame - otherwise it
;; won't work. <skx@tardis.ed.ac.uk>
(let* ((window (posn-window (event-start event)))
- (coords (posn-x-y (event-start event)))
- (x (car coords))
- (y (cdr coords)))
+ (coords (posn-x-y (event-start event)))
+ (x (car coords))
+ (y (cdr coords)))
(if (and (> x 0) (> y 0))
- (set-frame-selected-window nil window))
+ (set-frame-selected-window nil window))
(mapc (lambda (file-name)
- (let ((f (subst-char-in-string ?\\ ?/ file-name))
- (coding (or file-name-coding-system
- default-file-name-coding-system)))
- (setq file-name
- (mapconcat 'url-hexify-string
- (split-string (encode-coding-string f coding)
- "/")
- "/")))
- (dnd-handle-one-url window 'private
- (concat "file:" file-name)))
- (car (cdr (cdr event)))))
+ (let ((f (subst-char-in-string ?\\ ?/ file-name))
+ (coding (or file-name-coding-system
+ default-file-name-coding-system)))
+ (setq file-name
+ (mapconcat 'url-hexify-string
+ (split-string (encode-coding-string f coding)
+ "/")
+ "/")))
+ (dnd-handle-one-url window 'private
+ (concat "file:" file-name)))
+ (car (cdr (cdr event)))))
(raise-frame)))
(defun w32-drag-n-drop-other-frame (event)
@@ -197,11 +197,11 @@
;; the version we were compiled against. (If we were compiled
;; without PNG support, libpng-version's value is -1.)
(if (>= libpng-version 10400)
- ;; libpng14-14.dll is libpng 1.4.3 from GTK+
- '(png "libpng14-14.dll" "libpng14.dll")
- '(png "libpng12d.dll" "libpng12.dll" "libpng3.dll" "libpng.dll"
- ;; these are libpng 1.2.8 from GTK+
- "libpng13d.dll" "libpng13.dll"))
+ ;; libpng14-14.dll is libpng 1.4.3 from GTK+
+ '(png "libpng14-14.dll" "libpng14.dll")
+ '(png "libpng12d.dll" "libpng12.dll" "libpng3.dll" "libpng.dll"
+ ;; these are libpng 1.2.8 from GTK+
+ "libpng13d.dll" "libpng13.dll"))
'(jpeg "jpeg62.dll" "libjpeg.dll" "jpeg-62.dll" "jpeg.dll")
'(tiff "libtiff3.dll" "libtiff.dll")
'(gif "giflib4.dll" "libungif4.dll" "libungif.dll")
@@ -252,9 +252,9 @@
(condition-case err
(create-fontset-from-fontset-spec w32-standard-fontset-spec t)
(error (display-warning
- 'initialization
- (format "Creation of the standard fontset failed: %s" err)
- :error)))
+ 'initialization
+ (format "Creation of the standard fontset failed: %s" err)
+ :error)))
;; Create fontset specified in X resources "Fontset-N" (N is 0, 1,...).
(create-fontset-from-x-resource)
@@ -313,6 +313,254 @@
(add-to-list 'frame-creation-function-alist '(w32 . x-create-frame-with-faces))
(add-to-list 'window-system-initialization-alist '(w32 . w32-initialize-window-system))
+(declare-function set-message-beep "w32fns.c")
+
+(declare-function w32-raw-clipboard-fetch-data "w32select.c")
+(declare-function x-server-version "w32fns.c" (&optional display))
+
+(defun w32-version ()
+ "Return the MS-Windows version numbers.
+The value is a list of three integers: the major and minor version
+numbers, and the build number."
+ (x-server-version))
+
+;;; Fix interface to (X-specific) mouse.el
+(defun x-set-selection (type data)
+ "Make an X selection of type TYPE and value DATA.
+The argument TYPE (nil means `PRIMARY') says which selection, and
+DATA specifies the contents. TYPE must be a symbol. \(It can also
+be a string, which stands for the symbol with that name, but this
+is considered obsolete.) DATA may be a string, a symbol, an
+integer (or a cons of two integers or list of two integers).
+
+The selection may also be a cons of two markers pointing to the same buffer,
+or an overlay. In these cases, the selection is considered to be the text
+between the markers *at whatever time the selection is examined*.
+Thus, editing done in the buffer after you specify the selection
+can alter the effective value of the selection.
+
+The data may also be a vector of valid non-vector selection values.
+
+The return value is DATA.
+
+Interactively, this command sets the primary selection. Without
+prefix argument, it reads the selection in the minibuffer. With
+prefix argument, it uses the text of the region as the selection value.
+
+Note that on MS-Windows, primary and secondary selections set by Emacs
+are not available to other programs."
+ (put 'x-selections (or type 'PRIMARY) data))
+
+(defun x-get-selection (&optional type _data-type)
+ "Return the value of an X Windows selection.
+The argument TYPE (default `PRIMARY') says which selection,
+and the argument DATA-TYPE (default `STRING') says
+how to convert the data.
+
+TYPE may be any symbol \(but nil stands for `PRIMARY'). However,
+only a few symbols are commonly used. They conventionally have
+all upper-case names. The most often used ones, in addition to
+`PRIMARY', are `SECONDARY' and `CLIPBOARD'.
+
+DATA-TYPE is usually `STRING', but can also be one of the symbols
+in `selection-converter-alist', which see."
+ (get 'x-selections (or type 'PRIMARY)))
+
+;; x-selection-owner-p is used in simple.el
+(defun x-selection-owner-p (&optional type)
+ (and (memq type '(nil PRIMARY SECONDARY))
+ (get 'x-selections (or type 'PRIMARY))))
+
+;; Set to a system sound if you want a fancy bell.
+(set-message-beep nil)
+
+;; The "Windows" keys on newer keyboards bring up the Start menu
+;; whether you want it or not - make Emacs ignore these keystrokes
+;; rather than beep.
+(global-set-key [lwindow] 'ignore)
+(global-set-key [rwindow] 'ignore)
+
+(make-obsolete-variable 'w32-enable-italics
+ 'w32-enable-synthesized-fonts "21.1")
+(make-obsolete-variable 'w32-charset-to-codepage-alist
+ 'w32-charset-info-alist "21.1")
+
+\f
+;;;; Selections
+
+;; We keep track of the last text selected here, so we can check the
+;; current selection against it, and avoid passing back our own text
+;; from x-selection-value.
+(defvar x-last-selected-text nil)
+
+(defun x-get-selection-value ()
+ "Return the value of the current selection.
+Consult the selection. Treat empty strings as if they were unset."
+ (if x-select-enable-clipboard
+ (let (text)
+ ;; Don't die if x-get-selection signals an error.
+ (condition-case c
+ (setq text (w32-get-clipboard-data))
+ (error (message "w32-get-clipboard-data:%s" c)))
+ (if (string= text "") (setq text nil))
+ (cond
+ ((not text) nil)
+ ((eq text x-last-selected-text) nil)
+ ((string= text x-last-selected-text)
+ ;; Record the newer string, so subsequent calls can use the 'eq' test.
+ (setq x-last-selected-text text)
+ nil)
+ (t
+ (setq x-last-selected-text text))))))
+\f
+(defalias 'x-selection-value 'x-get-selection-value)
+
+(defvar w32-clipboard-current-data nil
+ "The value currently advertised as being available on the
+clipboard.")
+
+;; 13 == CF_UNICODETEXT
+(add-hook 'w32-clipboard-render-functions
+ (defun w32-clipboard-render-cf-unicodetext (format)
+ (when (eql format 13)
+ (concat
+ (encode-coding-string w32-clipboard-current-data 'utf-16le-dos t)
+ "\0"))))
+(add-to-list 'w32-clipboard-advertised-types 13)
+
+(defconst w32-clipboard-format-html
+ (w32-register-clipboard-format "HTML Format")
+ "The system-specific numeric ID of the HTML clipboard format.")
+
+(defconst w32-clipboard-html-header
+ (concat "Version:0.9\r\n"
+ "StartHTML:%0006d\r\n"
+ "EndHTML:%0006d\r\n"
+ "StartFragment%0006d\r\n"
+ "EndFragment:%0006d\r\n"))
+
+(defconst w32-clipboard-html-fragment-prefix
+ (concat "<!DOCTYPE HTML>\r\n"
+ "<html><head><title></title></head><body>\r\n"
+ "<!--StartFragment-->\r\n"
+ "<pre%s>"
+))
+
+(defconst w32-clipboard-html-fragment-suffix
+ (concat
+ "</pre>\r\n"
+ "<!--EndFragment-->\r\n"
+ "</body></html>\r\n"))
+
+(defun w32-clipboard-color-string (name color)
+ (if color
+ (progn
+ (setq color (color-values color))
+ (format "%s:#%02x%02x%02x;"
+ name
+ (/ (car color) 256)
+ (/ (car (cdr color)) 256)
+ (/ (car (cdr (cdr color))) 256)))
+ ""))
+
+(defun w32-clipboard-face-as-style (face &optional background)
+ (if (null face)
+ ""
+ (concat
+ " style=\""
+ (w32-clipboard-color-string
+ "color"
+ (face-attribute face :foreground nil 'default))
+ (if background
+ (w32-clipboard-color-string
+ "background-color"
+ (face-attribute face :background nil 'default))
+ "")
+ "\"")))
+
+(defun w32-clipboard-string-to-html (str)
+ "Format a string for Windows HTML interchange via the clipboard."
+ (let (face prev-face
+ body
+ result
+ chr part
+ (i 0) (len (length str)))
+ (while (< i len)
+ (setq chr (aref str i))
+ (cond ((and (>= chr 32)
+ (<= chr 126)
+ (not (memql chr '(?\< ?\> ?\" \?&))))
+ (setq part (char-to-string chr)))
+ ((eql chr ?\n)
+ (setq part "\r\n"))
+ (t
+ (setq part (format "&#x%x;" chr))))
+ (setq face (or (get-text-property i 'face str)))
+ (when (or (not body) (not (eq face prev-face)))
+ (setq body (cons (format (if body "</span><span%s>" "<span%s>")
+ (w32-clipboard-face-as-style face))
+ body))
+ (setq prev-face face))
+ (setq body (cons part body))
+ (setq i (1+ i)))
+
+ (when body
+ (setq body (cons "</span>" body)))
+ (setq body (mapconcat #'identity (nreverse body) ""))
+ (let* ((prefix (format w32-clipboard-html-fragment-prefix
+ (w32-clipboard-face-as-style 'default t)))
+ (suffix w32-clipboard-html-fragment-suffix)
+ (StartHTML (length w32-clipboard-html-header))
+ (StartFragment (+ StartHTML (length prefix)))
+ (EndFragment (+ StartFragment (length body)))
+ (EndHTML (+ EndFragment (length suffix))))
+ (setq result
+ (concat
+ (format w32-clipboard-html-header
+ StartHTML
+ EndHTML
+ StartFragment
+ EndFragment)
+ prefix
+ body
+ suffix))
+ (message "%S" result)
+ result)))
+
+(add-hook 'w32-clipboard-render-functions
+ (defun w32-clipboard-render-cf-html (format)
+ (when (eql format w32-clipboard-format-html)
+ (w32-clipboard-string-to-html w32-clipboard-current-data))))
+(add-to-list 'w32-clipboard-advertised-types w32-clipboard-format-html)
+
+(defun w32-clipboard-render (type)
+ (run-hook-with-args-until-success 'w32-clipboard-render-functions type))
+
+(add-hook 'w32-lost-selection-functions
+ (defun w32-clipboard-lost-selection (cb)
+ (setq w32-clipboard-current-data nil)))
+
+(defun w32-set-clipboard-data (string &optional ignored)
+ (setq w32-clipboard-current-data string)
+ (w32-claim-clipboard))
+
+(defun w32-get-clipboard-data (&optional ignored)
+ "This gets the clipboard data in text format. "
+ ;; Don't return our own selection.
+ (unless w32-clipboard-current-data
+ (let ((raw-unicode (w32-get-raw-clipboard-data 13)))
+ (when raw-unicode
+ (decode-coding-string
+ ;; Trim off trailing nulls
+ (if (> (length raw-unicode) 2)
+ (substring raw-unicode 0 -2)
+ raw-unicode)
+ 'utf-16le t)))))
+
+;; Arrange for the kill and yank functions to set and check the clipboard.
+(setq interprogram-cut-function 'x-select-text)
+(setq interprogram-paste-function 'x-get-selection-value)
+
(provide 'w32-win)
;;; w32-win.el ends here
=== modified file 'lisp/w32-fns.el'
--- lisp/w32-fns.el 2011-06-30 03:13:35 +0000
+++ lisp/w32-fns.el 2011-07-16 14:36:16 +0000
@@ -31,24 +31,13 @@
;;;; Function keys
-(declare-function set-message-beep "w32console.c")
-(declare-function w32-get-clipboard-data "w32select.c")
(declare-function w32-get-locale-info "w32proc.c")
(declare-function w32-get-valid-locale-ids "w32proc.c")
-(declare-function w32-set-clipboard-data "w32select.c")
;; Map all versions of a filename (8.3, longname, mixed case) to the
;; same buffer.
(setq find-file-visit-truename t)
-(declare-function x-server-version "w32fns.c" (&optional display))
-
-(defun w32-version ()
- "Return the MS-Windows version numbers.
-The value is a list of three integers: the major and minor version
-numbers, and the build number."
- (x-server-version))
-
(defun w32-using-nt ()
"Return non-nil if running on a Windows NT descendant.
That includes all Windows systems except for 9X/Me."
@@ -258,53 +247,6 @@
(setq start (match-end 0))))
name)))
-;;; Fix interface to (X-specific) mouse.el
-(defun x-set-selection (type data)
- "Make an X selection of type TYPE and value DATA.
-The argument TYPE (nil means `PRIMARY') says which selection, and
-DATA specifies the contents. TYPE must be a symbol. \(It can also
-be a string, which stands for the symbol with that name, but this
-is considered obsolete.) DATA may be a string, a symbol, an
-integer (or a cons of two integers or list of two integers).
-
-The selection may also be a cons of two markers pointing to the same buffer,
-or an overlay. In these cases, the selection is considered to be the text
-between the markers *at whatever time the selection is examined*.
-Thus, editing done in the buffer after you specify the selection
-can alter the effective value of the selection.
-
-The data may also be a vector of valid non-vector selection values.
-
-The return value is DATA.
-
-Interactively, this command sets the primary selection. Without
-prefix argument, it reads the selection in the minibuffer. With
-prefix argument, it uses the text of the region as the selection value.
-
-Note that on MS-Windows, primary and secondary selections set by Emacs
-are not available to other programs."
- (put 'x-selections (or type 'PRIMARY) data))
-
-(defun x-get-selection (&optional type _data-type)
- "Return the value of an X Windows selection.
-The argument TYPE (default `PRIMARY') says which selection,
-and the argument DATA-TYPE (default `STRING') says
-how to convert the data.
-
-TYPE may be any symbol \(but nil stands for `PRIMARY'). However,
-only a few symbols are commonly used. They conventionally have
-all upper-case names. The most often used ones, in addition to
-`PRIMARY', are `SECONDARY' and `CLIPBOARD'.
-
-DATA-TYPE is usually `STRING', but can also be one of the symbols
-in `selection-converter-alist', which see."
- (get 'x-selections (or type 'PRIMARY)))
-
-;; x-selection-owner-p is used in simple.el
-(defun x-selection-owner-p (&optional type)
- (and (memq type '(nil PRIMARY SECONDARY))
- (get 'x-selections (or type 'PRIMARY))))
-
(defun set-w32-system-coding-system (coding-system)
"Set the coding system used by the Windows system to CODING-SYSTEM.
This is used for things like passing font names with non-ASCII
@@ -326,15 +268,6 @@
;; w32-system-coding-system. Use that instead.
(defvaralias 'w32-system-coding-system 'locale-coding-system)
-;; Set to a system sound if you want a fancy bell.
-(set-message-beep nil)
-
-;; The "Windows" keys on newer keyboards bring up the Start menu
-;; whether you want it or not - make Emacs ignore these keystrokes
-;; rather than beep.
-(global-set-key [lwindow] 'ignore)
-(global-set-key [rwindow] 'ignore)
-
(defvar w32-charset-info-alist) ; w32font.c
(defun w32-add-charset-info (xlfd-charset windows-charset codepage)
@@ -392,45 +325,6 @@
(w32-add-charset-info "tis620-0" 'w32-charset-thai 874)
(w32-add-charset-info "iso8859-1" 'w32-charset-ansi 1252)
-(make-obsolete-variable 'w32-enable-italics
- 'w32-enable-synthesized-fonts "21.1")
-(make-obsolete-variable 'w32-charset-to-codepage-alist
- 'w32-charset-info-alist "21.1")
-
-\f
-;;;; Selections
-
-;; We keep track of the last text selected here, so we can check the
-;; current selection against it, and avoid passing back our own text
-;; from x-selection-value.
-(defvar x-last-selected-text nil)
-
-(defun x-get-selection-value ()
- "Return the value of the current selection.
-Consult the selection. Treat empty strings as if they were unset."
- (if x-select-enable-clipboard
- (let (text)
- ;; Don't die if x-get-selection signals an error.
- (condition-case c
- (setq text (w32-get-clipboard-data))
- (error (message "w32-get-clipboard-data:%s" c)))
- (if (string= text "") (setq text nil))
- (cond
- ((not text) nil)
- ((eq text x-last-selected-text) nil)
- ((string= text x-last-selected-text)
- ;; Record the newer string, so subsequent calls can use the 'eq' test.
- (setq x-last-selected-text text)
- nil)
- (t
- (setq x-last-selected-text text))))))
-\f
-(defalias 'x-selection-value 'x-get-selection-value)
-
-;; Arrange for the kill and yank functions to set and check the clipboard.
-(setq interprogram-cut-function 'x-select-text)
-(setq interprogram-paste-function 'x-get-selection-value)
-
\f
;;;; Support for build process
=== modified file 'src/ChangeLog'
--- src/ChangeLog 2011-07-15 17:41:24 +0000
+++ src/ChangeLog 2011-07-17 06:57:48 +0000
@@ -1,3 +1,8 @@
+2011-07-17 Daniel Colascione <dan.colascione@gmail.com>
+
+ * s/cygwin.h: Remove prohibition against vfork. It's okay to use
+ now.
+
2011-07-09 Lawrence Mitchell <wence@gmx.li>
* gnutls.c (Qgnutls_bootprop_min_prime_bits): New variable.
=== modified file 'src/Makefile.in'
--- src/Makefile.in 2011-07-08 20:20:19 +0000
+++ src/Makefile.in 2011-07-17 10:24:47 +0000
@@ -252,6 +252,13 @@
NS_OBJC_OBJ=@NS_OBJC_OBJ@
## Only set if NS_IMPL_GNUSTEP.
GNU_OBJC_CFLAGS=@GNU_OBJC_CFLAGS@
+## w32fns.o w32menu.c w32reg.o fringe.o fontset.o w32font.o w32term.o
+## w32xfns.o w32select.o image.o w32uniscribe.o if HAVE_W32, else
+## empty.
+W32_OBJ=@W32_OBJ@
+## -lkernel32 -luser32 -lgdi32 -lole32 -lcomdlg32 lusp10 -lcomctl32
+## --lwinspool if HAVE_W32, else empty.
+W32_LIBS=@W32_LIBS@
## Empty if !HAVE_X_WINDOWS
## xfont.o ftfont.o xftfont.o ftxfont.o if HAVE_XFT
@@ -337,7 +344,8 @@
process.o gnutls.o callproc.o \
region-cache.o sound.o atimer.o \
doprnt.o intervals.o textprop.o composite.o xml.o \
- $(MSDOS_OBJ) $(MSDOS_X_OBJ) $(NS_OBJ) $(CYGWIN_OBJ) $(FONT_OBJ)
+ $(MSDOS_OBJ) $(MSDOS_X_OBJ) $(NS_OBJ) $(CYGWIN_OBJ) $(FONT_OBJ) \
+ $(W32_OBJ)
obj = $(base_obj) $(NS_OBJC_OBJ)
## Object files used on some machine or other.
@@ -346,9 +354,9 @@
## in the list, in case they ever add any such entries.
SOME_MACHINE_OBJECTS = dosfns.o msdos.o \
xterm.o xfns.o xmenu.o xselect.o xrdb.o xsmfns.o fringe.o image.o \
- fontset.o dbusbind.o \
+ fontset.o dbusbind.o cygw32.o \
nsterm.o nsfns.o nsmenu.o nsselect.o nsimage.o nsfont.o \
- w32.o w32console.o w32fns.o w32heap.o w32inevt.o \
+ w32.o w32console.o w32fns.o w32heap.o \
w32menu.o w32proc.o w32reg.o w32select.o w32term.o w32xfns.o \
w16select.o widget.o xfont.o ftfont.o xftfont.o ftxfont.o gtkutil.o \
xsettings.o xgselect.o termcap.o
@@ -380,7 +388,7 @@
## Note that SunOS needs -lm to come before -lc; otherwise, you get
## duplicated symbols. If the standard libraries were compiled
## with GCC, we might need LIB_GCC again after them.
-LIBES = $(LIBS) $(LIBX_BASE) $(LIBX_OTHER) $(LIBSOUND) \
+LIBES = $(LIBS) $(W32_LIBS) $(LIBX_BASE) $(LIBX_OTHER) $(LIBSOUND) \
$(RSVG_LIBS) $(IMAGEMAGICK_LIBS) $(DBUS_LIBS) \
$(LIBXML2_LIBS) $(LIBGPM) $(LIBRESOLV) $(LIBS_SYSTEM) \
$(LIBS_TERMCAP) $(GETLOADAVG_LIBS) $(SETTINGS_LIBS) $(LIBSELINUX_LIBS) \
=== added file 'src/cygw32.c'
--- src/cygw32.c 1970-01-01 00:00:00 +0000
+++ src/cygw32.c 2011-07-17 12:08:27 +0000
@@ -0,0 +1,150 @@
+/* Cygwin support routines.
+ Copyright (C) 2011 Free Software Foundation, Inc.
+
+This file is part of GNU Emacs.
+
+GNU Emacs is free software: you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation, either version 3 of the License, or
+(at your option) any later version.
+
+GNU Emacs is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. */
+
+
+#include "cygw32.h"
+
+static Lisp_Object Qutf_16_le;
+
+/* Advance the given string by one character */
+BYTE*
+_mbsinc (const BYTE* current)
+{
+ return (BYTE*)current + 1; /* XXX: stub */
+}
+
+unsigned
+_mbsnextc (const BYTE* current)
+{
+ return *current; /* XXX: stub */
+}
+
+BYTE*
+_mbsncpy (BYTE* dest, const BYTE* src, size_t count)
+{
+ return strncpy (dest, src, count); /* XXX: stub */
+}
+
+extern Lisp_Object
+conv_filename_to_w32_unicode (Lisp_Object in, int absolute_p)
+{
+ ssize_t converted_len;
+ Lisp_Object converted;
+ unsigned flags;
+
+ flags = CCP_POSIX_TO_WIN_W;
+ if (!absolute_p) {
+ flags |= CCP_RELATIVE;
+ }
+
+ in = ENCODE_UTF_8 (in);
+
+ converted_len = cygwin_conv_path (flags, SDATA (in), NULL, 0);
+ if (converted_len < 2)
+ error ("cygwin_conv_path: %s", strerror (errno));
+
+ converted = make_uninit_string (converted_len - 1);
+ if (cygwin_conv_path (flags, SDATA (in),
+ SDATA (converted), converted_len))
+ error ("cygwin_conv_path: %s", strerror (errno));
+
+ return converted;
+}
+
+extern Lisp_Object
+conv_filename_from_w32_unicode (const wchar_t* in, int absolute_p)
+{
+ ssize_t converted_len;
+ Lisp_Object converted;
+ unsigned flags;
+
+ flags = CCP_WIN_W_TO_POSIX;
+ if (!absolute_p) {
+ flags |= CCP_RELATIVE;
+ }
+
+ converted_len = cygwin_conv_path (flags, in, NULL, 0);
+ if (converted_len < 1)
+ error ("cygwin_conv_path: %s", strerror (errno));
+
+ converted = make_uninit_string (converted_len - 1 /*subtract terminator*/);
+ if (cygwin_conv_path (flags, in, SDATA (converted), converted_len))
+ error ("cygwin_conv_path: %s", strerror (errno));
+
+ return code_convert_string_norecord (converted, Qutf_8, 0);
+}
+
+Lisp_Object
+from_unicode (Lisp_Object str)
+{
+ CHECK_STRING (str);
+ if (!STRING_MULTIBYTE (str) &&
+ SBYTES (str) & 1)
+ {
+ str = Fsubstring (str, make_number (0), make_number (-1));
+ }
+
+ return code_convert_string_norecord (str, Qutf_16_le, 0);
+}
+
+wchar_t*
+to_unicode (Lisp_Object str, Lisp_Object* buf)
+{
+ *buf = code_convert_string_norecord (str, Qutf_16_le, 1);
+ /* We need to make an additional copy to ensure that the final
+ string is _doubly_ zero terminated --- that is, that the string
+ is terminated by two zero bytes and one utf-16le null character.
+ Because strings are already terminated with a single zero byte,
+ we just add one additional zero. */
+ str = make_uninit_string (SBYTES (*buf) + 1);
+ memcpy (SDATA (str), SDATA (*buf), SBYTES (*buf));
+ SDATA (str) [SBYTES (*buf)] = '\0';
+ *buf = str;
+ return WCSDATA (*buf);
+}
+
+DEFUN ("cygwin-convert-path-to-windows",
+ Fcygwin_convert_path_to_windows, Scygwin_convert_path_to_windows,
+ 1, 2, 0,
+ doc: /* Convert PATH to a Windows path. If ABSOLUTE-P if
+ non-nil, return an absolute path.*/)
+ (Lisp_Object path, Lisp_Object absolute_p)
+{
+ return from_unicode (
+ conv_filename_to_w32_unicode (path, absolute_p == Qnil ? 0 : 1));
+}
+
+DEFUN ("cygwin-convert-path-from-windows",
+ Fcygwin_convert_path_from_windows, Scygwin_convert_path_from_windows,
+ 1, 2, 0,
+ doc: /* Convert a Windows path to a Cygwin path. If ABSOLUTE-P
+ if non-nil, return an absolute path.*/)
+ (Lisp_Object path, Lisp_Object absolute_p)
+{
+ return conv_filename_from_w32_unicode (to_unicode (path, &path),
+ absolute_p == Qnil ? 0 : 1);
+}
+
+void
+syms_of_cygw32 (void)
+{
+ /* No, not utf-16-le: that one has a BOM. */
+ DEFSYM (Qutf_16_le, "utf-16le");
+ defsubr (&Scygwin_convert_path_from_windows);
+ defsubr (&Scygwin_convert_path_to_windows);
+}
=== modified file 'src/dispextern.h'
--- src/dispextern.h 2011-07-14 17:28:42 +0000
+++ src/dispextern.h 2011-07-16 10:15:54 +0000
@@ -3106,7 +3106,7 @@
int update_window_fringes (struct window *, int);
void compute_fringe_widths (struct frame *, int);
-#ifdef WINDOWSNT
+#ifdef HAVE_NTGUI
void w32_init_fringe (struct redisplay_interface *);
void w32_reset_fringes (void);
#endif
@@ -3207,7 +3207,7 @@
#ifdef HAVE_X_WINDOWS
void gamma_correct (struct frame *, XColor *);
#endif
-#ifdef WINDOWSNT
+#ifdef HAVE_NTGUI
void gamma_correct (struct frame *, COLORREF *);
#endif
=== modified file 'src/emacs.c'
--- src/emacs.c 2011-07-10 08:20:10 +0000
+++ src/emacs.c 2011-07-17 13:41:12 +0000
@@ -35,7 +35,11 @@
#include <fcntl.h>
#include <windows.h> /* just for w32.h */
#include "w32.h"
-#include "w32heap.h" /* for prototype of sbrk */
+#endif
+
+#if WINDOWSNT || HAVE_NTGUI
+#include "w32heap.h"
+#include "w32select.h"
#endif
#ifdef NS_IMPL_GNUSTEP
@@ -1410,6 +1414,11 @@
tzset ();
#endif /* MSDOS */
+#if WINDOWSNT || HAVE_NTGUI
+ hinst = GetModuleHandle(NULL);
+ cache_system_info ();
+#endif
+
#ifdef WINDOWSNT
globals_of_w32 ();
/* Initialize environment from registry settings. */
@@ -1512,6 +1521,9 @@
#ifdef WINDOWSNT
syms_of_ntproc ();
#endif /* WINDOWSNT */
+#ifdef CYGWIN
+ syms_of_cygw32 ();
+#endif /* CYGWIN */
syms_of_window ();
syms_of_xdisp ();
syms_of_font ();
@@ -1542,11 +1554,14 @@
#ifdef HAVE_NTGUI
syms_of_w32term ();
syms_of_w32fns ();
- syms_of_w32select ();
syms_of_w32menu ();
syms_of_fontset ();
#endif /* HAVE_NTGUI */
+#ifdef HAVE_W32SELECT
+ syms_of_w32select ();
+#endif /* HAVE_W32SELECT */
+
#ifdef MSDOS
syms_of_xmenu ();
syms_of_dosfns();
@@ -1588,8 +1603,11 @@
#ifdef HAVE_NTGUI
globals_of_w32fns ();
globals_of_w32menu ();
+#endif /* HAVE_NTGUI */
+
+#ifdef HAVE_W32SELECT
globals_of_w32select ();
-#endif /* HAVE_NTGUI */
+#endif /* HAVE_W32SELECT */
}
init_charset ();
=== modified file 'src/font.c'
--- src/font.c 2011-07-10 08:20:10 +0000
+++ src/font.c 2011-07-16 12:10:21 +0000
@@ -5207,9 +5207,9 @@
#ifdef HAVE_BDFFONT
syms_of_bdffont ();
#endif /* HAVE_BDFFONT */
-#ifdef WINDOWSNT
+#ifdef HAVE_NTGUI
syms_of_w32font ();
-#endif /* WINDOWSNT */
+#endif /* HAVE_NTGUI */
#ifdef HAVE_NS
syms_of_nsfont ();
#endif /* HAVE_NS */
=== modified file 'src/font.h'
--- src/font.h 2011-06-20 05:51:47 +0000
+++ src/font.h 2011-07-16 06:51:09 +0000
@@ -830,11 +830,11 @@
extern void syms_of_bdffont (void);
#endif /* HAVE_BDFFONT */
#endif /* HAVE_X_WINDOWS */
-#ifdef WINDOWSNT
+#ifdef HAVE_NTGUI
extern struct font_driver w32font_driver;
extern struct font_driver uniscribe_font_driver;
extern void syms_of_w32font (void);
-#endif /* WINDOWSNT */
+#endif /* HAVE_NTGUI */
#ifdef HAVE_NS
extern Lisp_Object Qfontsize;
extern struct font_driver nsfont_driver;
=== modified file 'src/fontset.c'
--- src/fontset.c 2011-06-13 04:55:03 +0000
+++ src/fontset.c 2011-07-16 10:55:38 +0000
@@ -45,7 +45,7 @@
#ifdef HAVE_X_WINDOWS
#include "xterm.h"
#endif
-#ifdef WINDOWSNT
+#ifdef HAVE_NTGUI
#include "w32term.h"
#endif
#ifdef HAVE_NS
=== modified file 'src/frame.c'
--- src/frame.c 2011-06-24 21:25:22 +0000
+++ src/frame.c 2011-07-16 12:10:01 +0000
@@ -29,7 +29,7 @@
#ifdef HAVE_X_WINDOWS
#include "xterm.h"
#endif
-#ifdef WINDOWSNT
+#ifdef HAVE_NTGUI
#include "w32term.h"
#endif
#ifdef HAVE_NS
@@ -2734,7 +2734,7 @@
{"tool-bar-position", &Qtool_bar_position},
};
-#ifdef WINDOWSNT
+#ifdef HAVE_NTGUI
/* Calculate fullscreen size. Return in *TOP_POS and *LEFT_POS the
wanted positions of the WM window (not Emacs window).
@@ -2778,7 +2778,7 @@
*height = newheight;
}
-#endif /* WINDOWSNT */
+#endif /* HAVE_NTGUI */
#ifdef HAVE_WINDOW_SYSTEM
=== modified file 'src/frame.h'
--- src/frame.h 2011-06-11 21:31:32 +0000
+++ src/frame.h 2011-07-16 10:13:49 +0000
@@ -1092,7 +1092,7 @@
extern Lisp_Object Qface_set_after_frame_default;
-#ifdef WINDOWSNT
+#ifdef HAVE_NTGUI
extern void x_fullscreen_adjust (struct frame *f, int *, int *,
int *, int *);
#endif
=== modified file 'src/image.c'
--- src/image.c 2011-07-10 08:20:10 +0000
+++ src/image.c 2011-07-16 10:48:39 +0000
@@ -48,10 +48,13 @@
#include "termhooks.h"
#include "font.h"
+#if HAVE_X_WINDOWS || (CYGWIN && HAVE_NTGUI)
+#include <sys/types.h>
+#include <sys/stat.h>
+#endif
+
#ifdef HAVE_X_WINDOWS
#include "xterm.h"
-#include <sys/types.h>
-#include <sys/stat.h>
#define COLOR_TABLE_SUPPORT 1
@@ -67,7 +70,11 @@
#ifdef HAVE_NTGUI
+#if CYGWIN
+#include "cygw32.h"
+#else
#include "w32.h"
+#endif
#include "w32term.h"
/* W32_TODO : Color tables on W32. */
@@ -588,7 +595,7 @@
static void x_emboss (struct frame *, struct image *);
static int x_build_heuristic_mask (struct frame *, struct image *,
Lisp_Object);
-#ifdef HAVE_NTGUI
+#if WINDOWSNT
#define CACHE_IMAGE_TYPE(type, status) \
do { Vlibrary_cache = Fcons (Fcons (type, status), Vlibrary_cache); } while (0)
#else
@@ -2910,7 +2917,7 @@
else
bits = (char *) XBOOL_VECTOR (data)->data;
-#ifdef WINDOWSNT
+#ifdef HAVE_NTGUI
{
char *invertedBits;
int nbytes, i;
@@ -8614,7 +8621,7 @@
of `dynamic-library-alist', which see). */)
(Lisp_Object type, Lisp_Object libraries)
{
-#ifdef HAVE_NTGUI
+#ifdef WINDOWSNT
/* Don't try to reload the library. */
Lisp_Object tested = Fassq (type, Vlibrary_cache);
if (CONSP (tested))
=== modified file 'src/keyboard.c'
--- src/keyboard.c 2011-07-14 18:34:54 +0000
+++ src/keyboard.c 2011-07-17 07:59:27 +0000
@@ -321,7 +321,7 @@
/* Symbols to denote kinds of events. */
static Lisp_Object Qfunction_key;
Lisp_Object Qmouse_click;
-#if defined (WINDOWSNT)
+#if defined (HAVE_NTGUI)
Lisp_Object Qlanguage_change;
#endif
static Lisp_Object Qdrag_n_drop;
@@ -3777,8 +3777,8 @@
#ifdef subprocesses
if (kbd_on_hold_p () && kbd_buffer_nr_stored () < KBD_BUFFER_SIZE/4)
{
- /* Start reading input again, we have processed enough so we can
- accept new events again. */
+ /* Start reading input again because we have processed enough to
+ be able to accept new events again. */
unhold_keyboard_input ();
#ifdef SIGIO
if (!noninteractive)
@@ -3962,7 +3962,7 @@
x_activate_menubar (XFRAME (event->frame_or_window));
}
#endif
-#if defined (WINDOWSNT)
+#if defined (HAVE_NTGUI)
else if (event->kind == LANGUAGE_CHANGE_EVENT)
{
/* Make an event (language-change (FRAME CHARSET LCID)). */
@@ -5412,7 +5412,7 @@
(sizeof (lispy_function_keys)
/ sizeof (lispy_function_keys[0])));
-#ifdef WINDOWSNT
+#ifdef HAVE_NTGUI
case MULTIMEDIA_KEY_EVENT:
if (event->code < (sizeof (lispy_multimedia_keys)
/ sizeof (lispy_multimedia_keys[0]))
@@ -11528,7 +11528,7 @@
DEFSYM (Qconfig_changed_event, "config-changed-event");
DEFSYM (Qmenu_enable, "menu-enable");
-#if defined (WINDOWSNT)
+#if defined (HAVE_NTGUI)
DEFSYM (Qlanguage_change, "language-change");
#endif
=== modified file 'src/keyboard.h'
--- src/keyboard.h 2011-06-23 06:31:41 +0000
+++ src/keyboard.h 2011-07-16 06:28:00 +0000
@@ -511,6 +511,6 @@
extern EMACS_TIME timer_check (void);
extern void mark_kboards (void);
-#ifdef WINDOWSNT
+#ifdef HAVE_NTGUI
extern const char *const lispy_function_keys[];
#endif
=== modified file 'src/lisp.h'
--- src/lisp.h 2011-06-24 21:25:22 +0000
+++ src/lisp.h 2011-07-17 17:34:15 +0000
@@ -27,6 +27,14 @@
#include <intprops.h>
+#define t(...) \
+ ({ \
+ fprintf (stderr, "T:%s:%u: ", \
+ __FUNCTION__, __LINE__); \
+ fprintf (stderr, __VA_ARGS__); \
+ fputc ('\n', stderr); \
+ })
+
/* Use the configure flag --enable-checking[=LIST] to enable various
types of run time checks for Lisp objects. */
=== modified file 'src/process.c'
--- src/process.c 2011-07-06 18:04:23 +0000
+++ src/process.c 2011-07-17 09:23:40 +0000
@@ -108,6 +108,9 @@
#ifdef HAVE_NS
#include "nsterm.h"
#endif
+#ifdef HAVE_NTGUI
+#include "w32term.h"
+#endif
Lisp_Object Qeuid, Qegid, Qcomm, Qstate, Qppid, Qpgrp, Qsess, Qttname, Qtpgid;
Lisp_Object Qminflt, Qmajflt, Qcminflt, Qcmajflt, Qutime, Qstime, Qcstime;
@@ -4531,6 +4534,8 @@
nfds = xg_select
#elif defined (HAVE_NS)
nfds = ns_select
+#elif defined (USE_W32_SELECT)
+ nfds = w32_select
#else
nfds = select
#endif
=== modified file 'src/regex.c'
--- src/regex.c 2011-07-10 08:20:10 +0000
+++ src/regex.c 2011-07-16 16:34:09 +0000
@@ -1891,7 +1891,9 @@
/* Explicit quit checking is only used on NTemacs and whenever we
use polling to process input events. */
-#if defined emacs && (defined WINDOWSNT || defined SYNC_INPUT) && defined QUIT
+#if (defined emacs && \
+ (defined WINDOWSNT || defined HAVE_NTGUI || defined SYNC_INPUT) && \
+ defined QUIT)
extern int immediate_quit;
# define IMMEDIATE_QUIT_CHECK \
do { \
=== modified file 'src/s/cygwin.h'
--- src/s/cygwin.h 2011-03-17 05:15:08 +0000
+++ src/s/cygwin.h 2011-07-17 09:40:15 +0000
@@ -81,10 +81,6 @@
#define HAVE_SOCKETS
-/* vfork() interacts badly with setsid(), causing ptys to fail to
- change their controlling terminal */
-#define vfork fork
-
/* This should work (at least when compiling with gcc). But I have no way
or intention to verify or even test it. If you encounter a problem with
it, feel free to change this setting, but please add a comment here about
@@ -102,3 +98,23 @@
/* Send signals to subprocesses by "typing" special chars at them. */
#define SIGNALS_VIA_CHARACTERS
+
+#ifdef HAVE_NTGUI
+
+/* Work around Cygwin signal bug
+ * <loom.20100428T060408-563@post.gmane.org> */
+#define USE_W32_SELECT
+
+extern int getloadavg (double *, int);
+
+#ifdef EMACSDEBUG
+extern void _DebPrint (const char *fmt, ...);
+#define DebPrint(stuff) _DebPrint stuff
+#else
+#define DebPrint(stuff)
+#endif /* EMACSDEBUG */
+
+#endif /* HAVE_NTGUI */
+
+/* For benefit of normally WINDOWSNT code. */
+
=== modified file 'src/termhooks.h'
--- src/termhooks.h 2011-06-06 19:43:39 +0000
+++ src/termhooks.h 2011-07-16 06:29:45 +0000
@@ -102,9 +102,9 @@
HORIZ_WHEEL_EVENT, /* A wheel event generated by a second
horizontal wheel that is present on some
mice. See WHEEL_EVENT. */
-#if defined (WINDOWSNT)
+#if defined (HAVE_NTGUI)
LANGUAGE_CHANGE_EVENT, /* A LANGUAGE_CHANGE_EVENT is
- generated on WINDOWSNT or Mac OS
+ generated on HAVE_NTGUI or Mac OS
when the keyboard layout or input
language is changed by the
user. */
@@ -183,7 +183,7 @@
, CONFIG_CHANGED_EVENT
-#ifdef WINDOWSNT
+#ifdef HAVE_NTGUI
/* Generated when an APPCOMMAND event is received, in response to
Multimedia or Internet buttons on some keyboards.
Such keys are available as normal function keys on X through the
=== modified file 'src/unexcw.c'
--- src/unexcw.c 2011-03-17 20:18:59 +0000
+++ src/unexcw.c 2011-07-16 06:24:32 +0000
@@ -31,6 +31,8 @@
#define DOTEXE ".exe"
+extern void report_sheap_usage (int);
+
extern int bss_sbrk_did_unexec;
/* emacs symbols that indicate where bss and data end for emacs internals */
=== modified file 'src/w32.c'
--- src/w32.c 2011-07-09 07:00:58 +0000
+++ src/w32.c 2011-07-16 07:04:58 +0000
@@ -31,7 +31,6 @@
#include <sys/file.h>
#include <sys/time.h>
#include <sys/utime.h>
-#include <mbstring.h> /* for _mbspbrk */
#include <math.h>
#include <setjmp.h>
#include <time.h>
@@ -39,6 +38,7 @@
/* must include CRT headers *before* config.h */
#include <config.h>
+#include <mbstring.h> /* for _mbspbrk */
#undef access
#undef chdir
@@ -738,23 +738,6 @@
return (s_pfn_Get_System_times (lpIdleTime, lpKernelTime, lpUserTime));
}
\f
-/* Equivalent of strerror for W32 error codes. */
-char *
-w32_strerror (int error_no)
-{
- static char buf[500];
-
- if (error_no == 0)
- error_no = GetLastError ();
-
- buf[0] = '\0';
- if (!FormatMessage (FORMAT_MESSAGE_FROM_SYSTEM, NULL,
- error_no,
- 0, /* choose most suitable language */
- buf, sizeof (buf), NULL))
- sprintf (buf, "w32 error %u", error_no);
- return buf;
-}
/* Return 1 if P is a valid pointer to an object of size SIZE. Return
0 if P is NOT a valid pointer. Return -1 if we cannot validate P.
=== modified file 'src/w32.h'
--- src/w32.h 2011-05-04 14:03:16 +0000
+++ src/w32.h 2011-07-17 14:01:09 +0000
@@ -133,9 +133,6 @@
extern void syms_of_w32term (void);
extern void syms_of_w32fns (void);
extern void globals_of_w32fns (void);
-extern void syms_of_w32select (void);
-extern void globals_of_w32select (void);
-extern void term_w32select (void);
extern void syms_of_w32menu (void);
extern void globals_of_w32menu (void);
extern void syms_of_fontset (void);
=== modified file 'src/w32console.c'
--- src/w32console.c 2011-05-07 15:44:19 +0000
+++ src/w32console.c 2011-07-16 13:47:54 +0000
@@ -350,53 +350,6 @@
scroll_line (f, n, LEFT);
}
-static unsigned int sound_type = 0xFFFFFFFF;
-#define MB_EMACS_SILENT (0xFFFFFFFF - 1)
-
-void
-w32_sys_ring_bell (struct frame *f)
-{
- if (sound_type == 0xFFFFFFFF)
- {
- Beep (666, 100);
- }
- else if (sound_type == MB_EMACS_SILENT)
- {
- /* Do nothing. */
- }
- else
- MessageBeep (sound_type);
-}
-
-DEFUN ("set-message-beep", Fset_message_beep, Sset_message_beep, 1, 1, 0,
- doc: /* Set the sound generated when the bell is rung.
-SOUND is 'asterisk, 'exclamation, 'hand, 'question, 'ok, or 'silent
-to use the corresponding system sound for the bell. The 'silent sound
-prevents Emacs from making any sound at all.
-SOUND is nil to use the normal beep. */)
- (Lisp_Object sound)
-{
- CHECK_SYMBOL (sound);
-
- if (NILP (sound))
- sound_type = 0xFFFFFFFF;
- else if (EQ (sound, intern ("asterisk")))
- sound_type = MB_ICONASTERISK;
- else if (EQ (sound, intern ("exclamation")))
- sound_type = MB_ICONEXCLAMATION;
- else if (EQ (sound, intern ("hand")))
- sound_type = MB_ICONHAND;
- else if (EQ (sound, intern ("question")))
- sound_type = MB_ICONQUESTION;
- else if (EQ (sound, intern ("ok")))
- sound_type = MB_OK;
- else if (EQ (sound, intern ("silent")))
- sound_type = MB_EMACS_SILENT;
- else
- sound_type = 0xFFFFFFFF;
-
- return sound;
-}
static void
w32con_reset_terminal_modes (struct terminal *t)
@@ -755,6 +708,5 @@
defsubr (&Sset_screen_color);
defsubr (&Sget_screen_color);
defsubr (&Sset_cursor_size);
- defsubr (&Sset_message_beep);
}
=== modified file 'src/w32fns.c'
--- src/w32fns.c 2011-07-08 12:46:17 +0000
+++ src/w32fns.c 2011-07-17 17:45:48 +0000
@@ -45,8 +45,14 @@
#include "fontset.h"
#include "systime.h"
#include "termhooks.h"
+
#include "w32heap.h"
+
+#if CYGWIN
+#include "cygw32.h"
+#else
#include "w32.h"
+#endif
#include "bitmaps/gray.xbm"
@@ -79,6 +85,7 @@
extern void w32_menu_display_help (HWND, HMENU, UINT, UINT);
extern void w32_free_menu_strings (HWND);
extern const char *map_w32_filename (const char *, const char **);
+extern char * w32_strerror (int error_no);
/* If non-zero, a w32 timer that, when it expires, displays an
hourglass cursor on all frames. */
@@ -201,6 +208,30 @@
static void w32_show_hourglass (struct frame *);
static void w32_hide_hourglass (void);
+int faked_key;
+
+/* This gives us the page size and the size of the allocation unit on NT. */
+SYSTEM_INFO sysinfo_cache;
+
+/* This gives us version, build, and platform identification. */
+OSVERSIONINFO osinfo_cache;
+
+unsigned long syspage_mask = 0;
+
+/* The major and minor versions of NT. */
+int w32_major_version;
+int w32_minor_version;
+int w32_build_number;
+
+/* Distinguish between Windows NT and Windows 95. */
+int os_subtype;
+
+#ifdef HAVE_NTGUI
+HINSTANCE hinst = NULL;
+#endif
+
+static unsigned int sound_type = 0xFFFFFFFF;
+#define MB_EMACS_SILENT (0xFFFFFFFF - 1)
\f
/* Error if we are not connected to MS-Windows. */
@@ -1067,12 +1098,20 @@
If ALLOC is nonzero, allocate a new colormap cell. */
int
-w32_defined_color (FRAME_PTR f, char *color, XColor *color_def, int alloc)
+w32_defined_color (FRAME_PTR f, const char *color, XColor *color_def, int alloc)
{
register Lisp_Object tem;
COLORREF w32_color_ref;
-
- tem = x_to_w32_color (color);
+ char* color_tem;
+ USE_SAFE_ALLOCA;
+
+ /* Allocate a temporary copy of COLOR because x_to_w32_color
+ * modifies it and we promised our caller we wouldn't. */
+
+ SAFE_ALLOCA (color_tem, char*, strlen (color));
+ strcpy (color_tem, color);
+ tem = x_to_w32_color (color_tem);
+ SAFE_FREE ();
if (!NILP (tem))
{
@@ -1829,10 +1868,7 @@
/* Do first time app init */
- if (!hprevinst)
- {
- w32_init_class (hinst);
- }
+ w32_init_class (hinst);
if (f->size_hint_flags & USPosition || f->size_hint_flags & PPosition)
{
@@ -2232,6 +2268,58 @@
}
}
+#if EMACSDEBUG
+const char*
+w32_name_of_message (UINT msg)
+{
+ unsigned i;
+ static char buf[64];
+ static const struct {
+ UINT msg;
+ const char* name;
+ } msgnames[] = {
+#define M(msg) { msg, # msg }
+ M (WM_PAINT),
+ M (WM_TIMER),
+ M (WM_USER),
+ M (WM_MOUSEMOVE),
+ M (WM_LBUTTONUP),
+ M (WM_KEYDOWN),
+ M (WM_EMACS_KILL),
+ M (WM_EMACS_CREATEWINDOW),
+ M (WM_EMACS_DONE),
+ M (WM_EMACS_CREATESCROLLBAR),
+ M (WM_EMACS_SHOWWINDOW),
+ M (WM_EMACS_SETWINDOWPOS),
+ M (WM_EMACS_DESTROYWINDOW),
+ M (WM_EMACS_TRACKPOPUPMENU),
+ M (WM_EMACS_SETFOCUS),
+ M (WM_EMACS_SETFOREGROUND),
+ M (WM_EMACS_SETLOCALE),
+ M (WM_EMACS_SETKEYBOARDLAYOUT),
+ M (WM_EMACS_REGISTER_HOT_KEY),
+ M (WM_EMACS_UNREGISTER_HOT_KEY),
+ M (WM_EMACS_TOGGLE_LOCK_KEY),
+ M (WM_EMACS_TRACK_CARET),
+ M (WM_EMACS_DESTROY_CARET),
+ M (WM_EMACS_SHOW_CARET),
+ M (WM_EMACS_HIDE_CARET),
+ M (WM_EMACS_SETCURSOR),
+ M (WM_EMACS_PAINT),
+ M (WM_CHAR),
+#undef M
+ { 0, 0 }
+ };
+
+ for (i = 0; msgnames[i].name; ++i)
+ if (msgnames[i].msg == msg)
+ return msgnames[i].name;
+
+ sprintf (buf, "message 0x%04x", (unsigned)msg);
+ return buf;
+}
+#endif /* EMACSDEBUG */
+
/* Main message dispatch loop. */
static void
@@ -2245,6 +2333,10 @@
while (GetMessage (&msg, NULL, 0, 0))
{
+
+ /* DebPrint (("w32_msg_pump: %s time:%u\n", */
+ /* w32_name_of_message (msg.message), msg.time)); */
+
if (msg.hwnd == NULL)
{
switch (msg.message)
@@ -4653,6 +4745,37 @@
{
return Qnil;
}
+
+DEFUN ("set-message-beep", Fset_message_beep, Sset_message_beep, 1, 1, 0,
+ doc: /* Set the sound generated when the bell is rung.
+SOUND is 'asterisk, 'exclamation, 'hand, 'question, 'ok, or 'silent
+to use the corresponding system sound for the bell. The 'silent sound
+prevents Emacs from making any sound at all.
+SOUND is nil to use the normal beep. */)
+ (Lisp_Object sound)
+{
+ CHECK_SYMBOL (sound);
+
+ if (NILP (sound))
+ sound_type = 0xFFFFFFFF;
+ else if (EQ (sound, intern ("asterisk")))
+ sound_type = MB_ICONASTERISK;
+ else if (EQ (sound, intern ("exclamation")))
+ sound_type = MB_ICONEXCLAMATION;
+ else if (EQ (sound, intern ("hand")))
+ sound_type = MB_ICONHAND;
+ else if (EQ (sound, intern ("question")))
+ sound_type = MB_ICONQUESTION;
+ else if (EQ (sound, intern ("ok")))
+ sound_type = MB_OK;
+ else if (EQ (sound, intern ("silent")))
+ sound_type = MB_EMACS_SILENT;
+ else
+ sound_type = 0xFFFFFFFF;
+
+ return sound;
+}
+
\f
int
x_pixel_width (register struct frame *f)
@@ -5841,7 +5964,7 @@
{
if (msg == WM_NOTIFY)
{
- OFNOTIFY * notify = (OFNOTIFY *)lParam;
+ OFNOTIFYW * notify = (OFNOTIFYW *)lParam;
/* Detect when the Filter dropdown is changed. */
if (notify->hdr.code == CDN_TYPECHANGE
|| notify->hdr.code == CDN_INITDONE)
@@ -5869,7 +5992,7 @@
if (notify->lpOFN->nFilterIndex == 2)
{
CommDlg_OpenSave_SetControlText (dialog, FILE_NAME_TEXT_FIELD,
- "Current Directory");
+ L"Current Directory");
EnableWindow (edit_control, FALSE);
/* Note that at least on Windows 7, the above call to EnableWindow
disables the window that would ordinarily have focus. If we
@@ -5885,7 +6008,7 @@
/* Don't override default filename on init done. */
if (notify->hdr.code == CDN_TYPECHANGE)
CommDlg_OpenSave_SetControlText (dialog,
- FILE_NAME_TEXT_FIELD, "");
+ FILE_NAME_TEXT_FIELD, L"");
EnableWindow (edit_control, TRUE);
}
}
@@ -5893,19 +6016,6 @@
return 0;
}
-/* Since we compile with _WIN32_WINNT set to 0x0400 (for NT4 compatibility)
- we end up with the old file dialogs. Define a big enough struct for the
- new dialog to trick GetOpenFileName into giving us the new dialogs on
- Windows 2000 and XP. */
-typedef struct
-{
- OPENFILENAME real_details;
- void * pReserved;
- DWORD dwReserved;
- DWORD FlagsEx;
-} NEWOPENFILENAME;
-
-
DEFUN ("x-file-dialog", Fx_file_dialog, Sx_file_dialog, 2, 5, 0,
doc: /* Read file name, prompting with PROMPT in directory DIR.
Use a file selection dialog. Select DEFAULT-FILENAME in the dialog's file
@@ -5919,131 +6029,109 @@
{
struct frame *f = SELECTED_FRAME ();
Lisp_Object file = Qnil;
+ Lisp_Object filename = empty_unibyte_string;
+ Lisp_Object filter = Qnil;
int count = SPECPDL_INDEX ();
- struct gcpro gcpro1, gcpro2, gcpro3, gcpro4, gcpro5, gcpro6;
- char filename[MAX_PATH + 1];
- char init_dir[MAX_PATH + 1];
+ wchar_t filename_buf[MAX_PATH * 4];
int default_filter_index = 1; /* 1: All Files, 2: Directories only */
+ struct gcpro gcpro1, gcpro2, gcpro3;
- GCPRO6 (prompt, dir, default_filename, mustmatch, only_dir_p, file);
+ GCPRO3 (file, filename, filter);
CHECK_STRING (prompt);
CHECK_STRING (dir);
+ to_unicode (prompt, &prompt);
+
/* Create the dialog with PROMPT as title, using DIR as initial
directory and using "*" as pattern. */
- dir = Fexpand_file_name (dir, Qnil);
- strncpy (init_dir, SDATA (ENCODE_FILE (dir)), MAX_PATH);
- init_dir[MAX_PATH] = '\0';
- unixtodos_filename (init_dir);
-
- if (STRINGP (default_filename))
- {
- char *file_name_only;
- char *full_path_name = SDATA (ENCODE_FILE (default_filename));
-
- unixtodos_filename (full_path_name);
-
- file_name_only = strrchr (full_path_name, '\\');
- if (!file_name_only)
- file_name_only = full_path_name;
- else
- file_name_only++;
-
- strncpy (filename, file_name_only, MAX_PATH);
- filename[MAX_PATH] = '\0';
- }
- else
- filename[0] = '\0';
-
- /* The code in file_dialog_callback that attempts to set the text
- of the file name edit window when handling the CDN_INITDONE
- WM_NOTIFY message does not work. Setting filename to "Current
- Directory" in the only_dir_p case here does work however. */
- if (filename[0] == 0 && ! NILP (only_dir_p))
- strcpy (filename, "Current Directory");
+ to_unicode (Fexpand_file_name (dir, Qnil), &dir);
+
+ to_unicode (build_string ("All Files (*.*)\0*.*\0Directories\0*|*\0\0"),
+ &filter);
{
- NEWOPENFILENAME new_file_details;
+ OPENFILENAMEW file_details;
BOOL file_opened = FALSE;
- OPENFILENAME * file_details = &new_file_details.real_details;
/* Prevent redisplay. */
specbind (Qinhibit_redisplay, Qt);
BLOCK_INPUT;
- memset (&new_file_details, 0, sizeof (new_file_details));
- /* Apparently NT4 crashes if you give it an unexpected size.
- I'm not sure about Windows 9x, so play it safe. */
- if (w32_major_version > 4 && w32_major_version < 95)
- file_details->lStructSize = sizeof (NEWOPENFILENAME);
- else
- file_details->lStructSize = sizeof (OPENFILENAME);
-
- file_details->hwndOwner = FRAME_W32_WINDOW (f);
+ memset (&file_details, 0, sizeof (file_details));
+ file_details.lStructSize = sizeof (file_details);
+
+ if (wcslen (WCSDATA (filename)) >= MAX_PATH*4) {
+ filename = empty_unibyte_string;
+ }
+ wcscpy (filename_buf, WCSDATA (filename));
+
+ file_details.hwndOwner = FRAME_W32_WINDOW (f);
/* Undocumented Bug in Common File Dialog:
If a filter is not specified, shell links are not resolved. */
- file_details->lpstrFilter = "All Files (*.*)\0*.*\0Directories\0*|*\0\0";
- file_details->lpstrFile = filename;
- file_details->nMaxFile = sizeof (filename);
- file_details->lpstrInitialDir = init_dir;
- file_details->lpstrTitle = SDATA (prompt);
+ file_details.lpstrFilter = WCSDATA (filter);
+ file_details.lpstrFile = filename_buf;
+ file_details.nMaxFile = sizeof (filename_buf) / sizeof (*filename_buf);
+ file_details.lpstrInitialDir = WCSDATA (dir);
+ file_details.lpstrTitle = WCSDATA (prompt);
if (! NILP (only_dir_p))
default_filter_index = 2;
- file_details->nFilterIndex = default_filter_index;
+ file_details.nFilterIndex = default_filter_index;
- file_details->Flags = (OFN_HIDEREADONLY | OFN_NOCHANGEDIR
+ file_details.Flags = (OFN_HIDEREADONLY | OFN_NOCHANGEDIR
| OFN_EXPLORER | OFN_ENABLEHOOK);
if (!NILP (mustmatch))
{
/* Require that the path to the parent directory exists. */
- file_details->Flags |= OFN_PATHMUSTEXIST;
+ file_details.Flags |= OFN_PATHMUSTEXIST;
/* If we are looking for a file, require that it exists. */
if (NILP (only_dir_p))
- file_details->Flags |= OFN_FILEMUSTEXIST;
+ file_details.Flags |= OFN_FILEMUSTEXIST;
}
- file_details->lpfnHook = (LPOFNHOOKPROC) file_dialog_callback;
-
- file_opened = GetOpenFileName (file_details);
+ file_details.lpfnHook = (LPOFNHOOKPROC) file_dialog_callback;
+ file_opened = GetOpenFileNameW (&file_details);
UNBLOCK_INPUT;
if (file_opened)
{
- dostounix_filename (filename);
- if (file_details->nFilterIndex == 2)
+ if (file_details.nFilterIndex == 2)
{
/* "Directories" selected - strip dummy file name. */
- char * last = strrchr (filename, '/');
- *last = '\0';
+ wchar_t * last = wcsrchr (filename_buf, L'\\');
+ if (last)
+ *last = '\0';
}
-
- file = DECODE_FILE (build_string (filename));
+ filename = conv_filename_from_w32_unicode (filename_buf, 0);
}
/* User cancelled the dialog without making a selection. */
else if (!CommDlgExtendedError ())
- file = Qnil;
+ filename = Qnil;
/* An error occurred, fallback on reading from the mini-buffer. */
else
- file = Fcompleting_read (prompt, intern ("read-file-name-internal"),
- dir, mustmatch, dir, Qfile_name_history,
- default_filename, Qnil);
-
- file = unbind_to (count, file);
+ filename = Fcompleting_read (from_unicode (prompt),
+ intern ("read-file-name-internal"),
+ from_unicode (dir),
+ mustmatch,
+ from_unicode (dir),
+ Qfile_name_history,
+ default_filename, Qnil );
+ filename = unbind_to (count, filename);
}
UNGCPRO;
/* Make "Cancel" equivalent to C-g. */
- if (NILP (file))
+ if (NILP (filename))
Fsignal (Qquit, Qnil);
- return unbind_to (count, file);
+ return unbind_to (count, filename);
}
+#ifdef WINDOWSNT
/* Moving files to the system recycle bin.
Used by `move-file-to-trash' instead of the default moving to ~/.Trash */
@@ -6098,6 +6186,8 @@
return Qnil;
}
+#endif /* WINDOWSNT */
+
\f
/***********************************************************************
w32 specialized functions
@@ -6532,7 +6622,7 @@
else
{
char buffer[16];
- _snprintf (buffer, 16, "%d", system_status.BatteryLifePercent);
+ snprintf (buffer, 16, "%d", system_status.BatteryLifePercent);
load_percentage = build_string (buffer);
}
@@ -6543,18 +6633,18 @@
long m;
float h;
char buffer[16];
- _snprintf (buffer, 16, "%ld", seconds_left);
+ snprintf (buffer, 16, "%ld", seconds_left);
seconds = build_string (buffer);
m = seconds_left / 60;
- _snprintf (buffer, 16, "%ld", m);
+ snprintf (buffer, 16, "%ld", m);
minutes = build_string (buffer);
h = seconds_left / 3600.0;
- _snprintf (buffer, 16, "%3.1f", h);
+ snprintf (buffer, 16, "%3.1f", h);
hours = build_string (buffer);
- _snprintf (buffer, 16, "%ld:%02ld", m / 60, m % 60);
+ snprintf (buffer, 16, "%ld:%02ld", m / 60, m % 60);
remain = build_string (buffer);
}
sequences[0] = Fcons (make_number ('L'), line_status);
@@ -6716,10 +6806,10 @@
{
/* a remote printer */
if (*ppi2->pServerName == '\\')
- _snprintf (pname_buf, sizeof (pname_buf), "%s\\%s", ppi2->pServerName,
+ snprintf (pname_buf, sizeof (pname_buf), "%s\\%s", ppi2->pServerName,
ppi2->pShareName);
else
- _snprintf (pname_buf, sizeof (pname_buf), "\\\\%s\\%s", ppi2->pServerName,
+ snprintf (pname_buf, sizeof (pname_buf), "\\\\%s\\%s", ppi2->pServerName,
ppi2->pShareName);
pname_buf[sizeof (pname_buf) - 1] = '\0';
}
@@ -6738,6 +6828,276 @@
return build_string (pname_buf);
}
\f
+
+/* Equivalent of strerror for W32 error codes. */
+char *
+w32_strerror (int error_no)
+{
+ static char buf[500];
+ DWORD ret;
+
+ if (error_no == 0)
+ error_no = GetLastError ();
+
+ ret = FormatMessage (FORMAT_MESSAGE_FROM_SYSTEM |
+ FORMAT_MESSAGE_IGNORE_INSERTS,
+ NULL,
+ error_no,
+ 0, /* choose most suitable language */
+ buf, sizeof (buf), NULL);
+
+ while (ret > 0 && (buf[ret - 1] == '\n' ||
+ buf[ret - 1] == '\r' ))
+ --ret;
+ buf[ret] = '\0';
+ if (!ret)
+ sprintf (buf, "w32 error %u", error_no);
+
+ return buf;
+}
+
+/* For convenience when debugging. */
+int
+w32_last_error (void)
+{
+ return GetLastError ();
+}
+
+/* Cache information describing the NT system for later use. */
+void
+cache_system_info (void)
+{
+ union
+ {
+ struct info
+ {
+ char major;
+ char minor;
+ short platform;
+ } info;
+ DWORD data;
+ } version;
+
+ /* Cache the version of the operating system. */
+ version.data = GetVersion ();
+ w32_major_version = version.info.major;
+ w32_minor_version = version.info.minor;
+
+ if (version.info.platform & 0x8000)
+ os_subtype = OS_WIN95;
+ else
+ os_subtype = OS_NT;
+
+ /* Cache page size, allocation unit, processor type, etc. */
+ GetSystemInfo (&sysinfo_cache);
+ syspage_mask = sysinfo_cache.dwPageSize - 1;
+
+ /* Cache os info. */
+ osinfo_cache.dwOSVersionInfoSize = sizeof (OSVERSIONINFO);
+ GetVersionEx (&osinfo_cache);
+
+ w32_build_number = osinfo_cache.dwBuildNumber;
+ if (os_subtype == OS_WIN95)
+ w32_build_number &= 0xffff;
+
+ w32_num_mouse_buttons = GetSystemMetrics (SM_CMOUSEBUTTONS);
+}
+
+#ifdef EMACSDEBUG
+void
+_DebPrint (const char *fmt, ...)
+{
+ char buf[1024];
+ va_list args;
+
+ va_start (args, fmt);
+ vsprintf (buf, fmt, args);
+ va_end (args);
+#if CYGWIN
+ fprintf (stderr, "%s", buf);
+#endif
+ OutputDebugString (buf);
+}
+#endif
+
+int
+w32_console_toggle_lock_key (int vk_code, Lisp_Object new_state)
+{
+ int cur_state = (GetKeyState (vk_code) & 1);
+
+ if (NILP (new_state)
+ || (NUMBERP (new_state)
+ && ((XUINT (new_state)) & 1) != cur_state))
+ {
+ faked_key = vk_code;
+
+ keybd_event ((BYTE) vk_code,
+ (BYTE) MapVirtualKey (vk_code, 0),
+ KEYEVENTF_EXTENDEDKEY | KEYEVENTF_KEYUP, 0);
+ keybd_event ((BYTE) vk_code,
+ (BYTE) MapVirtualKey (vk_code, 0),
+ KEYEVENTF_EXTENDEDKEY | 0, 0);
+ keybd_event ((BYTE) vk_code,
+ (BYTE) MapVirtualKey (vk_code, 0),
+ KEYEVENTF_EXTENDEDKEY | KEYEVENTF_KEYUP, 0);
+ cur_state = !cur_state;
+ }
+
+ return cur_state;
+}
+
+/* Translate console modifiers to emacs modifiers.
+ German keyboard support (Kai Morgan Zeise 2/18/95). */
+int
+w32_kbd_mods_to_emacs (DWORD mods, WORD key)
+{
+ int retval = 0;
+
+ /* If we recognize right-alt and left-ctrl as AltGr, and it has been
+ pressed, first remove those modifiers. */
+ if (!NILP (Vw32_recognize_altgr)
+ && (mods & (RIGHT_ALT_PRESSED | LEFT_CTRL_PRESSED))
+ == (RIGHT_ALT_PRESSED | LEFT_CTRL_PRESSED))
+ mods &= ~ (RIGHT_ALT_PRESSED | LEFT_CTRL_PRESSED);
+
+ if (mods & (RIGHT_ALT_PRESSED | LEFT_ALT_PRESSED))
+ retval = ((NILP (Vw32_alt_is_meta)) ? alt_modifier : meta_modifier);
+
+ if (mods & (RIGHT_CTRL_PRESSED | LEFT_CTRL_PRESSED))
+ {
+ retval |= ctrl_modifier;
+ if ((mods & (RIGHT_CTRL_PRESSED | LEFT_CTRL_PRESSED))
+ == (RIGHT_CTRL_PRESSED | LEFT_CTRL_PRESSED))
+ retval |= meta_modifier;
+ }
+
+ if (mods & LEFT_WIN_PRESSED)
+ retval |= w32_key_to_modifier (VK_LWIN);
+ if (mods & RIGHT_WIN_PRESSED)
+ retval |= w32_key_to_modifier (VK_RWIN);
+ if (mods & APPS_PRESSED)
+ retval |= w32_key_to_modifier (VK_APPS);
+ if (mods & SCROLLLOCK_ON)
+ retval |= w32_key_to_modifier (VK_SCROLL);
+
+ /* Just in case someone wanted the original behavior, make it
+ optional by setting w32-capslock-is-shiftlock to t. */
+ if (NILP (Vw32_capslock_is_shiftlock)
+ /* Keys that should _not_ be affected by CapsLock. */
+ && ( (key == VK_BACK)
+ || (key == VK_TAB)
+ || (key == VK_CLEAR)
+ || (key == VK_RETURN)
+ || (key == VK_ESCAPE)
+ || ((key >= VK_SPACE) && (key <= VK_HELP))
+ || ((key >= VK_NUMPAD0) && (key <= VK_F24))
+ || ((key >= VK_NUMPAD_CLEAR) && (key <= VK_NUMPAD_DELETE))
+ ))
+ {
+ /* Only consider shift state. */
+ if ((mods & SHIFT_PRESSED) != 0)
+ retval |= shift_modifier;
+ }
+ else
+ {
+ /* Ignore CapsLock state if not enabled. */
+ if (NILP (Vw32_enable_caps_lock))
+ mods &= ~CAPSLOCK_ON;
+ if ((mods & (SHIFT_PRESSED | CAPSLOCK_ON)) != 0)
+ retval |= shift_modifier;
+ }
+
+ return retval;
+}
+
+/* The return code indicates key code size. */
+int
+w32_kbd_patch_key (KEY_EVENT_RECORD *event)
+{
+ unsigned int key_code = event->wVirtualKeyCode;
+ unsigned int mods = event->dwControlKeyState;
+ BYTE keystate[256];
+ static BYTE ansi_code[4];
+ static int isdead = 0;
+
+ if (isdead == 2)
+ {
+ event->uChar.AsciiChar = ansi_code[2];
+ isdead = 0;
+ return 1;
+ }
+ if (event->uChar.AsciiChar != 0)
+ return 1;
+
+ memset (keystate, 0, sizeof (keystate));
+ keystate[key_code] = 0x80;
+ if (mods & SHIFT_PRESSED)
+ keystate[VK_SHIFT] = 0x80;
+ if (mods & CAPSLOCK_ON)
+ keystate[VK_CAPITAL] = 1;
+ /* If we recognize right-alt and left-ctrl as AltGr, set the key
+ states accordingly before invoking ToAscii. */
+ if (!NILP (Vw32_recognize_altgr)
+ && (mods & LEFT_CTRL_PRESSED) && (mods & RIGHT_ALT_PRESSED))
+ {
+ keystate[VK_CONTROL] = 0x80;
+ keystate[VK_LCONTROL] = 0x80;
+ keystate[VK_MENU] = 0x80;
+ keystate[VK_RMENU] = 0x80;
+ }
+
+ /* On NT, call ToUnicode instead and then convert to the current
+ locale's default codepage. */
+ if (os_subtype == OS_NT)
+ {
+ WCHAR buf[128];
+
+ isdead = ToUnicode (event->wVirtualKeyCode, event->wVirtualScanCode,
+ keystate, buf, 128, 0);
+ if (isdead > 0)
+ {
+ char cp[20];
+ int cpId;
+
+ event->uChar.UnicodeChar = buf[isdead - 1];
+
+ GetLocaleInfo (GetThreadLocale (),
+ LOCALE_IDEFAULTANSICODEPAGE, cp, 20);
+ cpId = atoi (cp);
+ isdead = WideCharToMultiByte (cpId, 0, buf, isdead,
+ ansi_code, 4, NULL, NULL);
+ }
+ else
+ isdead = 0;
+ }
+ else
+ {
+ isdead = ToAscii (event->wVirtualKeyCode, event->wVirtualScanCode,
+ keystate, (LPWORD) ansi_code, 0);
+ }
+
+ if (isdead == 0)
+ return 0;
+ event->uChar.AsciiChar = ansi_code[0];
+ return isdead;
+}
+
+void
+w32_sys_ring_bell (struct frame *f)
+{
+ if (sound_type == 0xFFFFFFFF)
+ {
+ Beep (666, 100);
+ }
+ else if (sound_type == MB_EMACS_SILENT)
+ {
+ /* Do nothing. */
+ }
+ else
+ MessageBeep (sound_type);
+}
+
+\f
/***********************************************************************
Initialization
***********************************************************************/
@@ -7105,10 +7465,10 @@
defsubr (&Sfile_system_info);
defsubr (&Sdefault_printer_name);
+ defsubr (&Sset_message_beep);
check_window_system_func = check_w32;
-
hourglass_timer = 0;
hourglass_hwnd = NULL;
@@ -7123,7 +7483,9 @@
staticpro (&last_show_tip_args);
defsubr (&Sx_file_dialog);
+#ifdef WINDOWSNT
defsubr (&Ssystem_move_file_to_trash);
+#endif
}
@@ -7202,9 +7564,3 @@
}
}
-/* For convenience when debugging. */
-int
-w32_last_error (void)
-{
- return GetLastError ();
-}
=== modified file 'src/w32font.c'
--- src/w32font.c 2011-05-12 07:07:06 +0000
+++ src/w32font.c 2011-07-16 11:21:20 +0000
@@ -18,6 +18,7 @@
#include <config.h>
#include <windows.h>
+#include <stdio.h>
#include <math.h>
#include <ctype.h>
#include <commdlg.h>
@@ -1309,6 +1310,9 @@
return 1;
}
+#if !WINDOWSNT
+#define _strlwr strlwr
+#endif
static int
check_face_name (LOGFONT *font, char *full_name)
=== modified file 'src/w32heap.c'
--- src/w32heap.c 2011-05-05 04:00:38 +0000
+++ src/w32heap.c 2011-07-16 10:27:01 +0000
@@ -29,60 +29,6 @@
#define RVA_TO_PTR(rva) ((unsigned char *)((DWORD)(rva) + (DWORD)GetModuleHandle (NULL)))
-/* This gives us the page size and the size of the allocation unit on NT. */
-SYSTEM_INFO sysinfo_cache;
-
-/* This gives us version, build, and platform identification. */
-OSVERSIONINFO osinfo_cache;
-
-unsigned long syspage_mask = 0;
-
-/* The major and minor versions of NT. */
-int w32_major_version;
-int w32_minor_version;
-int w32_build_number;
-
-/* Distinguish between Windows NT and Windows 95. */
-int os_subtype;
-
-/* Cache information describing the NT system for later use. */
-void
-cache_system_info (void)
-{
- union
- {
- struct info
- {
- char major;
- char minor;
- short platform;
- } info;
- DWORD data;
- } version;
-
- /* Cache the version of the operating system. */
- version.data = GetVersion ();
- w32_major_version = version.info.major;
- w32_minor_version = version.info.minor;
-
- if (version.info.platform & 0x8000)
- os_subtype = OS_WIN95;
- else
- os_subtype = OS_NT;
-
- /* Cache page size, allocation unit, processor type, etc. */
- GetSystemInfo (&sysinfo_cache);
- syspage_mask = sysinfo_cache.dwPageSize - 1;
-
- /* Cache os info. */
- osinfo_cache.dwOSVersionInfoSize = sizeof (OSVERSIONINFO);
- GetVersionEx (&osinfo_cache);
-
- w32_build_number = osinfo_cache.dwBuildNumber;
- if (os_subtype == OS_WIN95)
- w32_build_number &= 0xffff;
-}
-
/* Emulate getpagesize. */
int
getpagesize (void)
=== modified file 'src/w32heap.h'
--- src/w32heap.h 2011-01-25 04:08:28 +0000
+++ src/w32heap.h 2011-07-16 10:33:53 +0000
@@ -24,6 +24,23 @@
#include <windows.h>
+extern int w32_major_version;
+extern int w32_minor_version;
+extern int w32_build_number;
+extern BOOL using_dynamic_heap;
+
+enum {
+ OS_WIN95 = 1,
+ OS_NT
+};
+
+extern int os_subtype;
+
+#define get_w32_major_version() w32_major_version
+#define get_w32_minor_version() w32_minor_version
+
+#if WINDOWSNT
+
#define ROUND_UP(p, align) (((DWORD)(p) + (align)-1) & ~((align)-1))
#define ROUND_DOWN(p, align) ((DWORD)(p) & ~((align)-1))
@@ -37,25 +54,12 @@
#define get_page_size() sysinfo_cache.dwPageSize
#define get_allocation_unit() sysinfo_cache.dwAllocationGranularity
#define get_processor_type() sysinfo_cache.dwProcessorType
-#define get_w32_major_version() w32_major_version
-#define get_w32_minor_version() w32_minor_version
extern unsigned char *get_data_start (void);
extern unsigned char *get_data_end (void);
extern unsigned long reserved_heap_size;
extern SYSTEM_INFO sysinfo_cache;
extern OSVERSIONINFO osinfo_cache;
-extern BOOL using_dynamic_heap;
-extern int w32_major_version;
-extern int w32_minor_version;
-extern int w32_build_number;
-
-enum {
- OS_WIN95 = 1,
- OS_NT
-};
-
-extern int os_subtype;
/* Emulation of Unix sbrk(). */
extern void *sbrk (unsigned long size);
@@ -91,5 +95,7 @@
relative virtual address. */
IMAGE_SECTION_HEADER * rva_to_section (DWORD rva, IMAGE_NT_HEADERS * nt_header);
+#endif /* WINDOWSNT */
+
#endif /* NTHEAP_H_ */
=== modified file 'src/w32inevt.c'
--- src/w32inevt.c 2011-05-14 19:06:08 +0000
+++ src/w32inevt.c 2011-07-16 11:24:02 +0000
@@ -97,169 +97,6 @@
return SELECTED_FRAME ();
}
-/* Translate console modifiers to emacs modifiers.
- German keyboard support (Kai Morgan Zeise 2/18/95). */
-int
-w32_kbd_mods_to_emacs (DWORD mods, WORD key)
-{
- int retval = 0;
-
- /* If we recognize right-alt and left-ctrl as AltGr, and it has been
- pressed, first remove those modifiers. */
- if (!NILP (Vw32_recognize_altgr)
- && (mods & (RIGHT_ALT_PRESSED | LEFT_CTRL_PRESSED))
- == (RIGHT_ALT_PRESSED | LEFT_CTRL_PRESSED))
- mods &= ~ (RIGHT_ALT_PRESSED | LEFT_CTRL_PRESSED);
-
- if (mods & (RIGHT_ALT_PRESSED | LEFT_ALT_PRESSED))
- retval = ((NILP (Vw32_alt_is_meta)) ? alt_modifier : meta_modifier);
-
- if (mods & (RIGHT_CTRL_PRESSED | LEFT_CTRL_PRESSED))
- {
- retval |= ctrl_modifier;
- if ((mods & (RIGHT_CTRL_PRESSED | LEFT_CTRL_PRESSED))
- == (RIGHT_CTRL_PRESSED | LEFT_CTRL_PRESSED))
- retval |= meta_modifier;
- }
-
- if (mods & LEFT_WIN_PRESSED)
- retval |= w32_key_to_modifier (VK_LWIN);
- if (mods & RIGHT_WIN_PRESSED)
- retval |= w32_key_to_modifier (VK_RWIN);
- if (mods & APPS_PRESSED)
- retval |= w32_key_to_modifier (VK_APPS);
- if (mods & SCROLLLOCK_ON)
- retval |= w32_key_to_modifier (VK_SCROLL);
-
- /* Just in case someone wanted the original behavior, make it
- optional by setting w32-capslock-is-shiftlock to t. */
- if (NILP (Vw32_capslock_is_shiftlock)
- /* Keys that should _not_ be affected by CapsLock. */
- && ( (key == VK_BACK)
- || (key == VK_TAB)
- || (key == VK_CLEAR)
- || (key == VK_RETURN)
- || (key == VK_ESCAPE)
- || ((key >= VK_SPACE) && (key <= VK_HELP))
- || ((key >= VK_NUMPAD0) && (key <= VK_F24))
- || ((key >= VK_NUMPAD_CLEAR) && (key <= VK_NUMPAD_DELETE))
- ))
- {
- /* Only consider shift state. */
- if ((mods & SHIFT_PRESSED) != 0)
- retval |= shift_modifier;
- }
- else
- {
- /* Ignore CapsLock state if not enabled. */
- if (NILP (Vw32_enable_caps_lock))
- mods &= ~CAPSLOCK_ON;
- if ((mods & (SHIFT_PRESSED | CAPSLOCK_ON)) != 0)
- retval |= shift_modifier;
- }
-
- return retval;
-}
-
-#if 0
-/* Return nonzero if the virtual key is a dead key. */
-static int
-is_dead_key (int wparam)
-{
- unsigned int code = MapVirtualKey (wparam, 2);
-
- /* Windows 95 returns 0x8000, NT returns 0x80000000. */
- return (code & 0x80008000) ? 1 : 0;
-}
-#endif
-
-/* The return code indicates key code size. */
-int
-w32_kbd_patch_key (KEY_EVENT_RECORD *event)
-{
- unsigned int key_code = event->wVirtualKeyCode;
- unsigned int mods = event->dwControlKeyState;
- BYTE keystate[256];
- static BYTE ansi_code[4];
- static int isdead = 0;
-
- if (isdead == 2)
- {
- event->uChar.AsciiChar = ansi_code[2];
- isdead = 0;
- return 1;
- }
- if (event->uChar.AsciiChar != 0)
- return 1;
-
- memset (keystate, 0, sizeof (keystate));
- keystate[key_code] = 0x80;
- if (mods & SHIFT_PRESSED)
- keystate[VK_SHIFT] = 0x80;
- if (mods & CAPSLOCK_ON)
- keystate[VK_CAPITAL] = 1;
- /* If we recognize right-alt and left-ctrl as AltGr, set the key
- states accordingly before invoking ToAscii. */
- if (!NILP (Vw32_recognize_altgr)
- && (mods & LEFT_CTRL_PRESSED) && (mods & RIGHT_ALT_PRESSED))
- {
- keystate[VK_CONTROL] = 0x80;
- keystate[VK_LCONTROL] = 0x80;
- keystate[VK_MENU] = 0x80;
- keystate[VK_RMENU] = 0x80;
- }
-
-#if 0
- /* Because of an OS bug, ToAscii corrupts the stack when called to
- convert a dead key in console mode on NT4. Unfortunately, trying
- to check for dead keys using MapVirtualKey doesn't work either -
- these functions apparently use internal information about keyboard
- layout which doesn't get properly updated in console programs when
- changing layout (though apparently it gets partly updated,
- otherwise ToAscii wouldn't crash). */
- if (is_dead_key (event->wVirtualKeyCode))
- return 0;
-#endif
-
- /* On NT, call ToUnicode instead and then convert to the current
- locale's default codepage. */
- if (os_subtype == OS_NT)
- {
- WCHAR buf[128];
-
- isdead = ToUnicode (event->wVirtualKeyCode, event->wVirtualScanCode,
- keystate, buf, 128, 0);
- if (isdead > 0)
- {
- char cp[20];
- int cpId;
-
- event->uChar.UnicodeChar = buf[isdead - 1];
-
- GetLocaleInfo (GetThreadLocale (),
- LOCALE_IDEFAULTANSICODEPAGE, cp, 20);
- cpId = atoi (cp);
- isdead = WideCharToMultiByte (cpId, 0, buf, isdead,
- ansi_code, 4, NULL, NULL);
- }
- else
- isdead = 0;
- }
- else
- {
- isdead = ToAscii (event->wVirtualKeyCode, event->wVirtualScanCode,
- keystate, (LPWORD) ansi_code, 0);
- }
-
- if (isdead == 0)
- return 0;
- event->uChar.AsciiChar = ansi_code[0];
- return isdead;
-}
-
-
-static int faked_key = 0;
-
/* return code -1 means that event_queue_ptr won't be incremented.
In other word, this event makes two key codes. (by himi) */
static int
@@ -510,32 +347,6 @@
return 1;
}
-int
-w32_console_toggle_lock_key (int vk_code, Lisp_Object new_state)
-{
- int cur_state = (GetKeyState (vk_code) & 1);
-
- if (NILP (new_state)
- || (NUMBERP (new_state)
- && ((XUINT (new_state)) & 1) != cur_state))
- {
- faked_key = vk_code;
-
- keybd_event ((BYTE) vk_code,
- (BYTE) MapVirtualKey (vk_code, 0),
- KEYEVENTF_EXTENDEDKEY | KEYEVENTF_KEYUP, 0);
- keybd_event ((BYTE) vk_code,
- (BYTE) MapVirtualKey (vk_code, 0),
- KEYEVENTF_EXTENDEDKEY | 0, 0);
- keybd_event ((BYTE) vk_code,
- (BYTE) MapVirtualKey (vk_code, 0),
- KEYEVENTF_EXTENDEDKEY | KEYEVENTF_KEYUP, 0);
- cur_state = !cur_state;
- }
-
- return cur_state;
-}
-
/* Mouse position hook. */
void
w32_console_mouse_position (FRAME_PTR *f,
=== modified file 'src/w32menu.c'
--- src/w32menu.c 2011-06-24 21:25:22 +0000
+++ src/w32menu.c 2011-07-16 10:09:02 +0000
@@ -21,7 +21,6 @@
#include <signal.h>
#include <stdio.h>
-#include <mbstring.h>
#include <setjmp.h>
#include "lisp.h"
@@ -40,6 +39,12 @@
if this is not done before the other system files. */
#include "w32term.h"
+#if CYGWIN
+#include "cygw32.h"
+#else
+#include <mbstring.h>
+#endif
+
/* Load sys/types.h if not already loaded.
In some systems loading it twice is suicidal. */
#ifndef makedev
@@ -96,6 +101,11 @@
static int fill_in_menu (HMENU, widget_value *);
void w32_free_menu_strings (HWND);
+
+#if CYGWIN
+
+#endif
+
\f
/* This is set nonzero after the user activates the menu bar, and set
=== modified file 'src/w32proc.c'
--- src/w32proc.c 2011-06-24 21:25:22 +0000
+++ src/w32proc.c 2011-07-16 05:58:37 +0000
@@ -68,20 +68,6 @@
Lisp_Object Qhigh, Qlow;
-#ifdef EMACSDEBUG
-void
-_DebPrint (const char *fmt, ...)
-{
- char buf[1024];
- va_list args;
-
- va_start (args, fmt);
- vsprintf (buf, fmt, args);
- va_end (args);
- OutputDebugString (buf);
-}
-#endif
-
typedef void (_CALLBACK_ *signal_handler) (int);
/* Signal handlers...SIG_DFL == 0 so this is initialized correctly. */
=== modified file 'src/w32select.c'
--- src/w32select.c 2011-06-24 21:25:22 +0000
+++ src/w32select.c 2011-07-17 20:32:49 +0000
@@ -21,58 +21,20 @@
/*
- * Notes on usage of selection-coding-system and
- * next-selection-coding-system on MS Windows:
- *
- * The selection coding system variables apply only to the version of
- * the clipboard data that is closest in type, i.e. when a 16-bit
- * Unicode coding system is given, they apply to he Unicode clipboard
- * (CF_UNICODETEXT), when a well-known console codepage is given, they
- * apply to the console version of the clipboard data (CF_OEMTEXT),
- * else they apply to the normal 8-bit text clipboard (CF_TEXT).
- *
- * When pasting (getting data from the OS), the clipboard format that
- * matches the {next-}selection-coding-system is retrieved. If
- * Unicode is requested, but not available, 8-bit text (CF_TEXT) is
- * used. In all other cases the OS will transparently convert
- * formats, so no other fallback is needed.
+ * Notes:
*
* When copying or cutting (sending data to the OS), the data is
* announced and stored internally, but only actually rendered on
- * request. The requester determines the format provided. The
- * {next-}selection-coding-system is only used, when its corresponding
- * clipboard type matches the type requested.
- *
- * Scenarios to use the facilities for customizing the selection
- * coding system are:
- *
- * ;; Generally use KOI8-R instead of the russian MS codepage for
- * ;; the 8-bit clipboard.
- * (set-selection-coding-system 'koi8-r-dos)
- *
- * Or
- *
- * ;; Create a special clipboard copy function that uses codepage
- * ;; 1253 (Greek) to copy Greek text to a specific non-Unicode
- * ;; application.
- * (defun greek-copy (beg end)
- * (interactive "r")
- * (set-next-selection-coding-system 'cp1253-dos)
- * (copy-region-as-kill beg end))
- * (global-set-key "\C-c\C-c" 'greek-copy)
- */
-
-/*
- * Ideas for further directions:
- *
- * The encoding and decoding routines could be moved to Lisp code
- * similar to how xselect.c does it (using well-known routine names
- * for the delayed rendering). If the definition of which clipboard
- * types should be supported is also moved to Lisp, functionality
- * could be expanded to CF_HTML, CF_RTF and maybe other types.
+ * request. The requester determines the format provided.
+ *
+ * We marshal clipboard writes across to the clipboard thread so that
+ * we can use SetClipboardData in the context of the owning WindowProc
+ * as the documentation suggests. Clipboard reads can be done in any
+ * thread.
*/
#include <config.h>
+#include <stdio.h>
#include <setjmp.h>
#include "lisp.h"
#include "w32term.h" /* for all of the w32 includes */
@@ -82,57 +44,53 @@
#include "coding.h"
#include "composite.h"
-
-static HGLOBAL convert_to_handle_as_ascii (void);
-static HGLOBAL convert_to_handle_as_coded (Lisp_Object coding_system);
-static Lisp_Object render (Lisp_Object oformat);
-static Lisp_Object render_locale (void);
-static Lisp_Object render_all (Lisp_Object ignore);
-static void run_protected (Lisp_Object (*code) (Lisp_Object), Lisp_Object arg);
-static Lisp_Object lisp_error_handler (Lisp_Object error);
+#ifdef CYGWIN
+#include "cygw32.h"
+#endif
+
+/* No conflict because with w32term messages because messages are
+ * disambiguated by recipient. */
+
+/* Sent to owner window to have it claim ownership. */
+#define WM_EMACS_CLAIM_CLIPBOARD (WM_USER + 0)
+
+/* Sent to clipboard window with wParam equal to memory handle and
+ lParam equal to the rendered data type. Use wParam == 0 to
+ terminate. */
+#define WM_EMACS_CLIPBOARD_DATA (WM_USER + 1)
+
static LRESULT CALLBACK owner_callback (HWND win, UINT msg,
WPARAM wp, LPARAM lp);
static HWND create_owner (void);
-static void setup_config (void);
-static BOOL WINAPI enum_locale_callback (/*const*/ char* loc_string);
-static UINT cp_from_locale (LCID lcid, UINT format);
-static Lisp_Object coding_from_cp (UINT codepage);
-static Lisp_Object validate_coding_system (Lisp_Object coding_system);
-static void setup_windows_coding_system (Lisp_Object coding_system,
- struct coding_system * coding);
-
-
/* A remnant from X11: Symbol for the CLIPBORD selection type. Other
selections are not used on Windows, so we don't need symbols for
PRIMARY and SECONDARY. */
Lisp_Object QCLIPBOARD;
+/* Function, defined in Lisp, that renders the clipboard in a given
+ format. */
+Lisp_Object Qw32_clipboard_render;
+Lisp_Object Qw32_lost_selection_functions;
+
/* Internal pseudo-constants, initialized in globals_of_w32select()
based on current system parameters. */
-static LCID DEFAULT_LCID;
-static UINT ANSICP, OEMCP;
-static Lisp_Object QUNICODE, QANSICP, QOEMCP;
+static Lisp_Object QUNICODE;
/* A hidden window just for the clipboard management. */
static HWND clipboard_owner;
+
+/* The thread managing the clipboard_owner window. (Windows have
+ thread affinity, and the main thread doesn't pump messages until we
+ tell it to do so.) */
+static HANDLE clipboard_thread;
+
/* A flag to tell WM_DESTROYCLIPBOARD who is to blame this time (just
checking GetClipboardOwner() doesn't work, sadly). */
static int modifying_clipboard = 0;
-/* Configured transfer parameters, based on the last inspection of
- selection-coding-system. */
-static Lisp_Object cfg_coding_system;
-static UINT cfg_codepage;
-static LCID cfg_lcid;
-static UINT cfg_clipboard_type;
-
-/* The current state for delayed rendering. */
-static Lisp_Object current_text;
-static Lisp_Object current_coding_system;
-static int current_requires_encoding, current_num_nls;
-static UINT current_clipboard_type;
-static LCID current_lcid;
+#undef TRACE
+#define TRACE 1
#if TRACE
#define ONTRACE(stmt) stmt
@@ -140,303 +98,183 @@
#define ONTRACE(stmt) /*stmt*/
#endif
-
-/* This function assumes that there is no multibyte character in
- current_text, so we can short-cut encoding. */
-
-static HGLOBAL
-convert_to_handle_as_ascii (void)
-{
- HGLOBAL htext = NULL;
- int nbytes;
- int truelen;
- unsigned char *src;
- unsigned char *dst;
-
- ONTRACE (fprintf (stderr, "convert_to_handle_as_ascii\n"));
-
- nbytes = SBYTES (current_text) + 1;
- src = SDATA (current_text);
-
- /* We need to add to the size the number of LF chars where we have
- to insert CR chars (the standard CF_TEXT clipboard format uses
- CRLF line endings, while Emacs uses just LF internally). */
-
- truelen = nbytes + current_num_nls;
-
- if ((htext = GlobalAlloc (GMEM_MOVEABLE | GMEM_DDESHARE, truelen)) == NULL)
- return NULL;
-
- if ((dst = (unsigned char *) GlobalLock (htext)) == NULL)
- {
- GlobalFree (htext);
- return NULL;
- }
-
- /* convert to CRLF line endings expected by clipboard */
- while (1)
- {
- unsigned char *next;
- /* copy next line or remaining bytes including '\0' */
- next = _memccpy (dst, src, '\n', nbytes);
- if (next)
- {
- /* copied one line ending with '\n' */
- int copied = next - dst;
- nbytes -= copied;
- src += copied;
- /* insert '\r' before '\n' */
- next[-1] = '\r';
- next[0] = '\n';
- dst = next + 1;
- }
- else
- /* copied remaining partial line -> now finished */
- break;
- }
-
- GlobalUnlock (htext);
-
- return htext;
-}
-
-/* This function assumes that there are multibyte or NUL characters in
- current_text, or that we need to construct Unicode. It runs the
- text through the encoding machinery. */
-
-static HGLOBAL
-convert_to_handle_as_coded (Lisp_Object coding_system)
-{
- HGLOBAL htext;
- unsigned char *dst = NULL;
- struct coding_system coding;
-
- ONTRACE (fprintf (stderr, "convert_to_handle_as_coded: %s\n",
- SDATA (SYMBOL_NAME (coding_system))));
-
- setup_windows_coding_system (coding_system, &coding);
- coding.dst_bytes = SBYTES (current_text) * 2;
- coding.destination = (unsigned char *) xmalloc (coding.dst_bytes);
- encode_coding_object (&coding, current_text, 0, 0,
- SCHARS (current_text), SBYTES (current_text), Qnil);
-
- htext = GlobalAlloc (GMEM_MOVEABLE | GMEM_DDESHARE, coding.produced +2);
-
- if (htext != NULL)
- dst = (unsigned char *) GlobalLock (htext);
-
- if (dst != NULL)
- {
- memcpy (dst, coding.destination, coding.produced);
- /* Add the string terminator. Add two NULs in case we are
- producing Unicode here. */
- dst[coding.produced] = dst[coding.produced+1] = '\0';
-
- GlobalUnlock (htext);
- }
-
- xfree (coding.destination);
-
- return htext;
-}
-
-static Lisp_Object
-render (Lisp_Object oformat)
-{
- HGLOBAL htext = NULL;
- UINT format = XFASTINT (oformat);
-
- ONTRACE (fprintf (stderr, "render\n"));
-
- if (NILP (current_text))
- return Qnil;
-
- if (current_requires_encoding || format == CF_UNICODETEXT)
- {
- if (format == current_clipboard_type)
- htext = convert_to_handle_as_coded (current_coding_system);
- else
- switch (format)
- {
- case CF_UNICODETEXT:
- htext = convert_to_handle_as_coded (QUNICODE);
- break;
- case CF_TEXT:
- case CF_OEMTEXT:
- {
- Lisp_Object cs;
- cs = coding_from_cp (cp_from_locale (current_lcid, format));
- htext = convert_to_handle_as_coded (cs);
- break;
- }
- }
- }
- else
- htext = convert_to_handle_as_ascii ();
-
- ONTRACE (fprintf (stderr, "render: htext = 0x%08X\n", (unsigned) htext));
-
- if (htext == NULL)
- return Qnil;
-
- if (SetClipboardData (format, htext) == NULL)
- {
- GlobalFree (htext);
- return Qnil;
- }
-
- return Qt;
-}
-
-static Lisp_Object
-render_locale (void)
-{
- HANDLE hlocale = NULL;
- LCID * lcid_ptr;
-
- ONTRACE (fprintf (stderr, "render_locale\n"));
-
- if (current_lcid == LOCALE_NEUTRAL || current_lcid == DEFAULT_LCID)
- return Qt;
-
- hlocale = GlobalAlloc (GMEM_MOVEABLE | GMEM_DDESHARE, sizeof (current_lcid));
- if (hlocale == NULL)
- return Qnil;
-
- if ((lcid_ptr = (LCID *) GlobalLock (hlocale)) == NULL)
- {
- GlobalFree (hlocale);
- return Qnil;
- }
-
- *lcid_ptr = current_lcid;
- GlobalUnlock (hlocale);
-
- if (SetClipboardData (CF_LOCALE, hlocale) == NULL)
- {
- GlobalFree (hlocale);
- return Qnil;
- }
-
- return Qt;
-}
-
-/* At the end of the program, we want to ensure that our clipboard
- data survives us. This code will do that. */
-
-static Lisp_Object
-render_all (Lisp_Object ignore)
-{
- ONTRACE (fprintf (stderr, "render_all\n"));
-
- /* According to the docs we should not call OpenClipboard() here,
- but testing on W2K and working code in other projects shows that
- it is actually necessary. */
-
- OpenClipboard (NULL);
-
- /* There is no usefull means to report errors here, there are none
- expected anyway, and even if there were errors, they wouldn't do
- any harm. So we just go ahead and do what has to be done without
- bothering with error handling. */
+static void
+claim_clipboard (void)
+{
+ Lisp_Object format;
+
+ if (!OpenClipboard (clipboard_owner))
+ return;
++modifying_clipboard;
EmptyClipboard ();
--modifying_clipboard;
- /* For text formats that we don't render here, the OS can use its
- own translation rules instead, so we don't really need to offer
- everything. To minimize memory consumption we cover three
- possible situations based on our primary format as detected from
- selection-coding-system (see setup_config()):
-
- - Post CF_TEXT only. Let the OS convert to CF_OEMTEXT and the OS
- (on NT) or the application (on 9x/Me) convert to
- CF_UNICODETEXT.
-
- - Post CF_OEMTEXT only. Similar automatic conversions happen as
- for CF_TEXT.
-
- - Post CF_UNICODETEXT + CF_TEXT. 9x itself ignores
- CF_UNICODETEXT, even though some applications can still handle
- it.
-
- Note 1: We render the less capable CF_TEXT *before* the more
- capable CF_UNICODETEXT, to prevent clobbering through automatic
- conversions, just in case.
-
- Note 2: We could check os_subtype here and only render the
- additional CF_TEXT on 9x/Me. But OTOH with
- current_clipboard_type == CF_UNICODETEXT we don't involve the
- automatic conversions anywhere else, so to get consistent
- results, we probably don't want to rely on it here either. */
-
- render_locale ();
-
- if (current_clipboard_type == CF_UNICODETEXT)
- render (make_number (CF_TEXT));
- render (make_number (current_clipboard_type));
-
- CloseClipboard ();
-
- return Qnil;
-}
-
-static void
-run_protected (Lisp_Object (*code) (Lisp_Object), Lisp_Object arg)
-{
- /* FIXME: This works but it doesn't feel right. Too much fiddling
- with global variables and calling strange looking functions. Is
- this really the right way to run Lisp callbacks? */
-
- extern int waiting_for_input; /* from keyboard.c */
- int owfi;
-
- BLOCK_INPUT;
-
- /* Fsignal calls abort() if it sees that waiting_for_input is
- set. */
- owfi = waiting_for_input;
- waiting_for_input = 0;
-
- internal_condition_case_1 (code, arg, Qt, lisp_error_handler);
-
- waiting_for_input = owfi;
-
- UNBLOCK_INPUT;
-}
-
-static Lisp_Object
-lisp_error_handler (Lisp_Object error)
-{
- Vsignaling_function = Qnil;
- cmd_error_internal (error, "Error in delayed clipboard rendering: ");
- Vinhibit_quit = Qt;
- return Qt;
-}
-
+ for (format = Vw32_clipboard_advertised_types;
+ CONSP (format);
+ format = XCDR (format))
+ {
+ if (INTEGERP (XCAR (format)))
+ SetClipboardData (XFASTINT (XCAR (format)), NULL);
+ }
+
+ CloseClipboard ();
+}
+
+static Lisp_Object
+clipboard_render_cb_unwind (Lisp_Object arg)
+{
+ PostMessage (clipboard_owner, WM_EMACS_CLIPBOARD_DATA, 0, 0);
+ return Qnil;
+}
+
+static Lisp_Object
+global_free_unwind (Lisp_Object arg)
+{
+ HGLOBAL* mem = XSAVE_VALUE (arg)->pointer;
+ if (mem != NULL)
+ GlobalFree (*mem);
+ return Qnil;
+}
+
+static Lisp_Object
+close_clipboard_unwind (Lisp_Object arg)
+{
+ CloseClipboard ();
+ return Qnil;
+}
+
+/* Send a rendered string RENDERED to the clipboard thread, which must
+ be waiting in wait_for_clipboard_render. */
+static void
+send_clipboard_render (UINT format, void* mem, size_t bytes)
+{
+ int count;
+ HGLOBAL htext;
+ void* buf;
+
+ count = SPECPDL_INDEX ();
+ record_unwind_protect (global_free_unwind,
+ make_save_value (&htext, 0));
+
+ htext = GlobalAlloc (GMEM_MOVEABLE | GMEM_DDESHARE, bytes);
+ if (!htext)
+ error ("GlobalAlloc: %s", w32_strerror (GetLastError ()));
+
+ buf = GlobalLock (htext);
+ if (!buf)
+ error ("GlobalLock: %s", w32_strerror (GetLastError ()));
+
+ memcpy (buf, mem, bytes);
+ if (GlobalUnlock (htext) && GetLastError () != NO_ERROR)
+ error ("GlobalUnlock: %s", w32_strerror (GetLastError ()));
+
+ /* Use PostMessage instead of SendMessage so we return faster ---
+ we're on the UI thread, after all. Transfer ownership of htext
+ to the clipboard thread. */
+
+ if (!PostMessage (clipboard_owner, WM_EMACS_CLIPBOARD_DATA,
+ (WPARAM)htext, (LPARAM)format))
+ error ("SendMessage: %s", w32_strerror (GetLastError ()));
+
+ htext = NULL;
+
+ unbind_to (count, Qnil);
+}
+
+/* Run in main thread. Try to render in the given format and if we
+ are successful, send the result back to the clipboard thread via
+ WM_EMACS_CLIPBOARD_DATA. */
+static void
+clipboard_render_cb (struct atimer* at)
+{
+ void* arg = at->client_data;
+ UINT format = (UINT)arg;
+ Lisp_Object ret;
+ int count = SPECPDL_INDEX ();
+
+ record_unwind_protect (clipboard_render_cb_unwind, Qnil);
+ ret = call1 (Qw32_clipboard_render, make_number ((unsigned)arg));
+
+ if (ret != Qnil) {
+ CHECK_STRING (ret);
+ send_clipboard_render (format, SDATA (ret), SBYTES (ret) + 1);
+ }
+
+ unbind_to (count, Qnil);
+}
+
+/* Process rendered data from the currently scheduled render*_cb call
+ and block until it tells us it's done. */
+static void
+wait_for_clipboard_render ()
+{
+ MSG msg;
+ while (GetMessage (&msg, clipboard_owner,
+ WM_EMACS_CLIPBOARD_DATA,
+ WM_EMACS_CLIPBOARD_DATA))
+ {
+ if (msg.message != WM_EMACS_CLIPBOARD_DATA) {
+ eassert (0);
+ DispatchMessage (&msg);
+ continue;
+ }
+
+ t ("Got WM_EMACS_CLIPBOARD_DATA lParam:%x wParam:%x",
+ msg.lParam, msg.wParam);
+
+ if (msg.wParam) {
+ SetClipboardData ((UINT)msg.lParam, (HGLOBAL)msg.wParam);
+ GlobalFree ((HGLOBAL)msg.wParam);
+ } else {
+ break;
+ }
+ }
+}
+
+static void
+clipboard_lost_cb (struct atimer* ignored)
+{
+ Lisp_Object args[2];
+ args[0] = Qw32_lost_selection_functions;
+ args[1] = QCLIPBOARD;
+ run_hook_with_args (2, args, Ffuncall);
+}
static LRESULT CALLBACK
owner_callback (HWND win, UINT msg, WPARAM wp, LPARAM lp)
{
+ t ("owner_callback");
+
switch (msg)
{
+ case WM_EMACS_CLIPBOARD_DATA:
+ ONTRACE (fprintf (stderr, "WM_EMACS_CLIPBOARD_DATA\n"));
+ /* Ignore out-of-context data messages. */
+ return 0;
+
+ case WM_EMACS_CLAIM_CLIPBOARD:
+ ONTRACE (fprintf (stderr, "WM_EMACS_CLAIM_CLIPBOARD\n"));
+ claim_clipboard ();
+ return 0;
+
case WM_RENDERFORMAT:
ONTRACE (fprintf (stderr, "WM_RENDERFORMAT\n"));
- run_protected (render, make_number (wp));
+ call_on_main_thread (clipboard_render_cb, (void*)wp);
+ wait_for_clipboard_render ();
return 0;
case WM_RENDERALLFORMATS:
ONTRACE (fprintf (stderr, "WM_RENDERALLFORMATS\n"));
- run_protected (render_all, Qnil);
+ call_on_main_thread (clipboard_render_cb, (void*)-1);
+ wait_for_clipboard_render ();
return 0;
case WM_DESTROYCLIPBOARD:
if (!modifying_clipboard)
{
ONTRACE (fprintf (stderr, "WM_DESTROYCLIPBOARD (other)\n"));
- current_text = Qnil;
- current_coding_system = Qnil;
+ call_on_main_thread (clipboard_lost_cb, NULL);
}
else
{
@@ -478,536 +316,58 @@
DestroyWindow (clipboard_owner);
}
-static void
-setup_config (void)
-{
- const char *coding_name;
- const char *cp;
- char *end;
- int slen;
- Lisp_Object coding_system;
- Lisp_Object dos_coding_system;
-
- CHECK_SYMBOL (Vselection_coding_system);
-
- coding_system = NILP (Vnext_selection_coding_system) ?
- Vselection_coding_system : Vnext_selection_coding_system;
-
- dos_coding_system = validate_coding_system (coding_system);
- if (NILP (dos_coding_system))
- Fsignal (Qerror,
- list2 (build_string ("Coding system is invalid or doesn't have "
- "an eol variant for dos line ends"),
- coding_system));
-
- /* Check if we have it cached */
- if (!NILP (cfg_coding_system)
- && EQ (cfg_coding_system, dos_coding_system))
- return;
- cfg_coding_system = dos_coding_system;
-
- /* Set some sensible fallbacks */
- cfg_codepage = ANSICP;
- cfg_lcid = LOCALE_NEUTRAL;
- cfg_clipboard_type = CF_TEXT;
-
- /* Interpret the coding system symbol name */
- coding_name = SDATA (SYMBOL_NAME (cfg_coding_system));
-
- /* "(.*-)?utf-16.*" -> CF_UNICODETEXT */
- cp = strstr (coding_name, "utf-16");
- if (cp != NULL && (cp == coding_name || cp[-1] == '-'))
- {
- cfg_clipboard_type = CF_UNICODETEXT;
- return;
- }
-
- /* "cp[0-9]+.*" or "windows-[0-9]+.*" -> CF_TEXT or CF_OEMTEXT */
- slen = strlen (coding_name);
- if (slen >= 4 && coding_name[0] == 'c' && coding_name[1] == 'p')
- cp = coding_name + 2;
- else if (slen >= 10 && memcmp (coding_name, "windows-", 8) == 0)
- cp = coding_name + 8;
- else
- return;
-
- end = (char*)cp;
- cfg_codepage = strtol (cp, &end, 10);
-
- /* Error return from strtol() or number of digits < 2 -> Restore the
- default and drop it. */
- if (cfg_codepage == 0 || (end-cp) < 2 )
- {
- cfg_codepage = ANSICP;
- return;
- }
-
- /* Is it the currently active system default? */
- if (cfg_codepage == ANSICP)
- {
- /* cfg_clipboard_type = CF_TEXT; */
- return;
- }
- if (cfg_codepage == OEMCP)
- {
- cfg_clipboard_type = CF_OEMTEXT;
- return;
- }
-
- /* Else determine a suitable locale the hard way. */
- EnumSystemLocales (enum_locale_callback, LCID_INSTALLED);
-}
-
-static BOOL WINAPI
-enum_locale_callback (/*const*/ char* loc_string)
-{
- LCID lcid;
- UINT codepage;
-
- lcid = strtoul (loc_string, NULL, 16);
-
- /* Is the wanted codepage the "ANSI" codepage for this locale? */
- codepage = cp_from_locale (lcid, CF_TEXT);
- if (codepage == cfg_codepage)
- {
- cfg_lcid = lcid;
- cfg_clipboard_type = CF_TEXT;
- return FALSE; /* Stop enumeration */
- }
-
- /* Is the wanted codepage the OEM codepage for this locale? */
- codepage = cp_from_locale (lcid, CF_OEMTEXT);
- if (codepage == cfg_codepage)
- {
- cfg_lcid = lcid;
- cfg_clipboard_type = CF_OEMTEXT;
- return FALSE; /* Stop enumeration */
- }
-
- return TRUE; /* Continue enumeration */
-}
-
-static UINT
-cp_from_locale (LCID lcid, UINT format)
-{
- char buffer[20] = "";
- UINT variant, cp;
-
- variant =
- format == CF_TEXT ? LOCALE_IDEFAULTANSICODEPAGE : LOCALE_IDEFAULTCODEPAGE;
-
- GetLocaleInfo (lcid, variant, buffer, sizeof (buffer));
- cp = strtoul (buffer, NULL, 10);
-
- if (cp == CP_ACP)
- return ANSICP;
- else if (cp == CP_OEMCP)
- return OEMCP;
- else
- return cp;
-}
-
-static Lisp_Object
-coding_from_cp (UINT codepage)
-{
- char buffer[30];
- sprintf (buffer, "cp%d-dos", (int) codepage);
- return intern (buffer);
- /* We don't need to check that this coding system actually exists
- right here, because that is done later for all coding systems
- used, regardless of where they originate. */
-}
-
-static Lisp_Object
-validate_coding_system (Lisp_Object coding_system)
-{
- Lisp_Object eol_type;
-
- /* Make sure the input is valid. */
- if (NILP (Fcoding_system_p (coding_system)))
- return Qnil;
-
- /* Make sure we use a DOS coding system as mandated by the system
- specs. */
- eol_type = Fcoding_system_eol_type (coding_system);
-
- /* Already a DOS coding system? */
- if (EQ (eol_type, make_number (1)))
- return coding_system;
-
- /* Get EOL_TYPE vector of the base of CODING_SYSTEM. */
- if (!VECTORP (eol_type))
- {
- eol_type = Fcoding_system_eol_type (Fcoding_system_base (coding_system));
- if (!VECTORP (eol_type))
- return Qnil;
- }
-
- return AREF (eol_type, 1);
-}
-
-static void
-setup_windows_coding_system (Lisp_Object coding_system,
- struct coding_system * coding)
-{
- memset (coding, 0, sizeof (*coding));
- setup_coding_system (coding_system, coding);
-
- /* Unset CODING_ANNOTATE_COMPOSITION_MASK. Previous code had
- comments about crashes in encode_coding_iso2022 trying to
- dereference a null pointer when composition was on. Selection
- data should not contain any composition sequence on Windows.
-
- CODING_ANNOTATION_MASK also includes
- CODING_ANNOTATE_DIRECTION_MASK and CODING_ANNOTATE_CHARSET_MASK,
- which both apply to ISO6429 only. We don't know if these really
- need to be unset on Windows, but it probably doesn't hurt
- either. */
- coding->mode &= ~CODING_ANNOTATION_MASK;
- coding->mode |= CODING_MODE_LAST_BLOCK | CODING_MODE_SAFE_ENCODING;
-}
-
-
-
-DEFUN ("w32-set-clipboard-data", Fw32_set_clipboard_data,
- Sw32_set_clipboard_data, 1, 2, 0,
- doc: /* This sets the clipboard data to the given text. */)
- (Lisp_Object string, Lisp_Object ignored)
-{
- BOOL ok = TRUE;
- int nbytes;
- unsigned char *src;
- unsigned char *dst;
- unsigned char *end;
-
- /* This parameter used to be the current frame, but we don't use
- that any more. */
- (void) ignored;
-
- CHECK_STRING (string);
-
- setup_config ();
-
- current_text = string;
- current_coding_system = cfg_coding_system;
- current_clipboard_type = cfg_clipboard_type;
- current_lcid = cfg_lcid;
- current_num_nls = 0;
- current_requires_encoding = 0;
-
- BLOCK_INPUT;
-
- /* Check for non-ASCII characters. While we are at it, count the
- number of LFs, so we know how many CRs we will have to add later
- (just in the case where we can use our internal ASCII rendering,
- see code and comment in convert_to_handle_as_ascii() above). */
- nbytes = SBYTES (string);
- src = SDATA (string);
-
- for (dst = src, end = src+nbytes; dst < end; dst++)
- {
- if (*dst == '\n')
- current_num_nls++;
- else if (*dst >= 0x80 || *dst == 0)
- {
- current_requires_encoding = 1;
- break;
- }
- }
-
- if (!current_requires_encoding)
- {
- /* If all we have is ASCII we don't need to pretend we offer
- anything fancy. */
- current_coding_system = Qraw_text;
- current_clipboard_type = CF_TEXT;
- current_lcid = LOCALE_NEUTRAL;
- }
-
- if (!OpenClipboard (clipboard_owner))
- goto error;
-
- ++modifying_clipboard;
- ok = EmptyClipboard ();
- --modifying_clipboard;
-
- /* If we have something non-ASCII we may want to set a locale. We
- do that directly (non-delayed), as it's just a small bit. */
- if (ok)
- ok = !NILP (render_locale ());
-
- if (ok)
- {
- if (clipboard_owner == NULL)
- {
- /* If for some reason we don't have a clipboard_owner, we
- just set the text format as chosen by the configuration
- and than forget about the whole thing. */
- ok = !NILP (render (make_number (current_clipboard_type)));
- current_text = Qnil;
- current_coding_system = Qnil;
- }
- else
- {
- /* Advertise all supported formats so that whatever the
- requester chooses, only one encoding step needs to be
- made. This is intentionally different from what we do in
- the handler for WM_RENDERALLFORMATS. */
- SetClipboardData (CF_UNICODETEXT, NULL);
- SetClipboardData (CF_TEXT, NULL);
- SetClipboardData (CF_OEMTEXT, NULL);
- }
- }
-
- CloseClipboard ();
-
- /* With delayed rendering we haven't really "used" this coding
- system yet, and it's even unclear if we ever will. But this is a
- way to tell the upper level what we *would* use under ideal
- circumstances.
-
- We don't signal the actually used coding-system later when we
- finally render, because that can happen at any time and we don't
- want to disturb the "foreground" action. */
- if (ok)
- Vlast_coding_system_used = current_coding_system;
-
- Vnext_selection_coding_system = Qnil;
-
- if (ok) goto done;
-
- error:
-
- ok = FALSE;
- current_text = Qnil;
- current_coding_system = Qnil;
-
- done:
- UNBLOCK_INPUT;
-
- return (ok ? string : Qnil);
-}
-
-
-DEFUN ("w32-get-clipboard-data", Fw32_get_clipboard_data,
- Sw32_get_clipboard_data, 0, 1, 0,
- doc: /* This gets the clipboard data in text format. */)
- (Lisp_Object ignored)
+DEFUN ("w32-claim-clipboard",
+ Fw32_claim_clipboard, Sw32_claim_clipboard, 0, 0, 0,
+ doc: /* Claim ownership of the clipboard, clear it, and begin
+advertising our content. The formats advertised are given by the list
+`w32-clipboard-advertised-types'. */)
+ (void)
+{
+ if (!clipboard_owner) {
+ error ("clipboard not initialized");
+ }
+
+ /* Use SendMessage and not PostMessage so the clipboard thread can
+ be confident that we're not GCing or mutating. */
+ SendMessage (clipboard_owner, WM_EMACS_CLAIM_CLIPBOARD, 0, 0);
+}
+
+DEFUN ("w32-get-raw-clipboard-data", Fw32_get_raw_clipboard_data,
+ Sw32_get_raw_clipboard_data, 1, 1, 0,
+ doc: /* Retrieve the Win32 clipboard data of the given type
+TYPE. Return nil if there is nothing in the clipboard of the given
+type. TYPE is an integer giving the raw Win32 clipboard format
+constant.*/)
+ (Lisp_Object format)
{
HGLOBAL htext;
Lisp_Object ret = Qnil;
- UINT actual_clipboard_type;
- int use_configured_coding_system = 1;
-
- /* This parameter used to be the current frame, but we don't use
- that any more. */
- (void) ignored;
-
- /* Don't pass our own text from the clipboard (which might be
- troublesome if the killed text includes null characters). */
- if (!NILP (current_text))
- return ret;
-
- setup_config ();
- actual_clipboard_type = cfg_clipboard_type;
-
- BLOCK_INPUT;
-
- if (!OpenClipboard (clipboard_owner))
- goto done;
-
- if ((htext = GetClipboardData (actual_clipboard_type)) == NULL)
- {
- /* If we want CF_UNICODETEXT but can't get it, the current
- coding system is useless. OTOH we can still try and decode
- CF_TEXT based on the locale that the system gives us and that
- we get down below. */
- if (actual_clipboard_type == CF_UNICODETEXT)
- {
- htext = GetClipboardData (CF_TEXT);
- if (htext != NULL)
- {
- actual_clipboard_type = CF_TEXT;
- use_configured_coding_system = 0;
- }
- }
- }
- if (htext == NULL)
- goto closeclip;
-
- {
- unsigned char *src;
- unsigned char *dst;
- int nbytes;
- int truelen;
- int require_decoding = 0;
-
- if ((src = (unsigned char *) GlobalLock (htext)) == NULL)
- goto closeclip;
-
- /* If the clipboard data contains any non-ascii code, we need to
- decode it with a coding system. */
- if (actual_clipboard_type == CF_UNICODETEXT)
- {
- nbytes = lstrlenW ((WCHAR *)src) * 2;
- require_decoding = 1;
- }
- else
- {
- int i;
-
- nbytes = strlen (src);
-
- for (i = 0; i < nbytes; i++)
- {
- if (src[i] >= 0x80)
- {
- require_decoding = 1;
- break;
- }
- }
- }
-
- if (require_decoding)
- {
- struct coding_system coding;
- Lisp_Object coding_system = Qnil;
- Lisp_Object dos_coding_system;
-
- /* `next-selection-coding-system' should override everything,
- even when the locale passed by the system disagrees. The
- only exception is when `next-selection-coding-system'
- requested CF_UNICODETEXT and we couldn't get that. */
- if (use_configured_coding_system
- && !NILP (Vnext_selection_coding_system))
- coding_system = Vnext_selection_coding_system;
-
- /* If we have CF_TEXT or CF_OEMTEXT, we want to check out
- CF_LOCALE, too. */
- else if (actual_clipboard_type != CF_UNICODETEXT)
- {
- HGLOBAL hlocale;
- LCID lcid = DEFAULT_LCID;
- UINT cp;
-
- /* Documentation says that the OS always generates
- CF_LOCALE info automatically, so the locale handle
- should always be present. Fact is that this is not
- always true on 9x ;-(. */
- hlocale = GetClipboardData (CF_LOCALE);
- if (hlocale != NULL)
- {
- const LCID * lcid_ptr;
- lcid_ptr = (const LCID *) GlobalLock (hlocale);
- if (lcid_ptr != NULL)
- {
- lcid = *lcid_ptr;
- GlobalUnlock (hlocale);
- }
-
- /* 9x has garbage as the sort order (to be exact there
- is another instance of the language id in the upper
- word). We don't care about sort order anyway, so
- we just filter out the unneeded mis-information to
- avoid irritations. */
- lcid = MAKELCID (LANGIDFROMLCID (lcid), SORT_DEFAULT);
- }
-
- /* If we are using fallback from CF_UNICODETEXT, we can't
- use the configured coding system. Also we don't want
- to use it, if the system has supplied us with a locale
- and it is not just the system default. */
- if (!use_configured_coding_system || lcid != DEFAULT_LCID)
- {
- cp = cp_from_locale (lcid, actual_clipboard_type);
- /* If it's just our current standard setting anyway,
- use the coding system that the user has selected.
- Otherwise create a new spec to match the locale
- that was specified by the other side or the
- system. */
- if (!use_configured_coding_system || cp != cfg_codepage)
- coding_system = coding_from_cp (cp);
- }
- }
-
- if (NILP (coding_system))
- coding_system = Vselection_coding_system;
- Vnext_selection_coding_system = Qnil;
-
- dos_coding_system = validate_coding_system (coding_system);
- if (!NILP (dos_coding_system))
- {
- setup_windows_coding_system (dos_coding_system, &coding);
- coding.source = src;
- decode_coding_object (&coding, Qnil, 0, 0, nbytes, nbytes, Qt);
- ret = coding.dst_object;
-
- Vlast_coding_system_used = CODING_ID_NAME (coding.id);
- }
- }
- else
- {
- /* FIXME: We may want to repeat the code in this branch for
- the Unicode case. */
-
- /* Need to know final size after CR chars are removed because
- we can't change the string size manually, and doing an
- extra copy is silly. We only remove CR when it appears as
- part of CRLF. */
-
- truelen = nbytes;
- dst = src;
- /* avoid using strchr because it recomputes the length everytime */
- while ((dst = memchr (dst, '\r', nbytes - (dst - src))) != NULL)
- {
- if (dst[1] == '\n') /* safe because of trailing '\0' */
- truelen--;
- dst++;
- }
-
- ret = make_uninit_string (truelen);
-
- /* Convert CRLF line endings (the standard CF_TEXT clipboard
- format) to LF endings as used internally by Emacs. */
-
- dst = SDATA (ret);
- while (1)
- {
- unsigned char *next;
- /* copy next line or remaining bytes excluding '\0' */
- next = _memccpy (dst, src, '\r', nbytes);
- if (next)
- {
- /* copied one line ending with '\r' */
- int copied = next - dst;
- nbytes -= copied;
- dst += copied;
- src += copied;
- if (*src == '\n')
- dst--; /* overwrite '\r' with '\n' */
- }
- else
- /* copied remaining partial line -> now finished */
- break;
- }
-
- Vlast_coding_system_used = Qraw_text;
- }
-
- GlobalUnlock (htext);
- }
-
- closeclip:
- CloseClipboard ();
-
- done:
- UNBLOCK_INPUT;
-
- return (ret);
+ wchar_t* buf = NULL;
+ int count = SPECPDL_INDEX ();
+
+ CHECK_NUMBER (format);
+
+ if (!OpenClipboard (NULL)) {
+ return Qnil;
+ }
+
+ record_unwind_protect (close_clipboard_unwind, Qnil);
+ htext = GetClipboardData (XFASTINT (format));
+
+ if (htext != NULL) {
+ ret = make_uninit_string (GlobalSize (htext));
+ buf = GlobalLock (htext);
+ if (!buf)
+ error ("GlobalLock: %s", w32_strerror (GetLastError ()));
+
+ memcpy (SDATA (ret), buf, GlobalSize (htext));
+ if (!GlobalUnlock (htext) && GetLastError () != NO_ERROR)
+ error ("GlobalUnlock: %s", w32_strerror (GetLastError ()));
+ }
+
+ return unbind_to (count, ret);
}
-/* Support checking for a clipboard selection. */
-
DEFUN ("x-selection-exists-p", Fx_selection_exists_p, Sx_selection_exists_p,
0, 1, 0,
doc: /* Whether there is an owner for the given X Selection.
@@ -1027,17 +387,11 @@
{
Lisp_Object val = Qnil;
- setup_config ();
-
if (OpenClipboard (NULL))
{
UINT format = 0;
while ((format = EnumClipboardFormats (format)))
- /* Check CF_TEXT in addition to cfg_clipboard_type,
- because we can fall back on that if CF_UNICODETEXT is
- not available. Actually a check for CF_TEXT only
- should be enough. */
- if (format == cfg_clipboard_type || format == CF_TEXT)
+ if (format == CF_UNICODETEXT)
{
val = Qt;
break;
@@ -1049,93 +403,65 @@
return Qnil;
}
+DEFUN ("w32-register-clipboard-format",
+ Fw32_register_clipboard_format, Sw32_register_clipboard_format,
+ 1, 1, 0,
+ doc: /* Return the system-wide numberic identifier for clipboard
+format FORMAT (a string). */)
+ (Lisp_Object format)
+{
+ return make_number (RegisterClipboardFormatW (to_unicode (format, &format)));
+}
+
/* One-time init. Called in the un-dumped Emacs, but not in the
dumped version. */
void
syms_of_w32select (void)
{
- defsubr (&Sw32_set_clipboard_data);
- defsubr (&Sw32_get_clipboard_data);
+ defsubr (&Sw32_get_raw_clipboard_data);
defsubr (&Sx_selection_exists_p);
-
- DEFVAR_LISP ("selection-coding-system", Vselection_coding_system,
- doc: /* Coding system for communicating with other programs.
-
-For MS-Windows and MS-DOS:
-When sending or receiving text via selection and clipboard, the text
-is encoded or decoded by this coding system. The default value is
-the current system default encoding on 9x/Me, `utf-16le-dos'
-\(Unicode) on NT/W2K/XP, and `iso-latin-1-dos' on MS-DOS.
-
-For X Windows:
-When sending text via selection and clipboard, if the target
-data-type matches with the type of this coding system, it is used
-for encoding the text. Otherwise (including the case that this
-variable is nil), a proper coding system is used as below:
-
-data-type coding system
---------- -------------
-UTF8_STRING utf-8
-COMPOUND_TEXT compound-text-with-extensions
-STRING iso-latin-1
-C_STRING no-conversion
-
-When receiving text, if this coding system is non-nil, it is used
-for decoding regardless of the data-type. If this is nil, a
-proper coding system is used according to the data-type as above.
-
-See also the documentation of the variable `x-select-request-type' how
-to control which data-type to request for receiving text.
-
-The default value is nil. */);
- /* The actual value is set dynamically in the dumped Emacs, see
- below. */
- Vselection_coding_system = Qnil;
-
- DEFVAR_LISP ("next-selection-coding-system", Vnext_selection_coding_system,
- doc: /* Coding system for the next communication with other programs.
-Usually, `selection-coding-system' is used for communicating with
-other programs (X Windows clients or MS Windows programs). But, if this
-variable is set, it is used for the next communication only.
-After the communication, this variable is set to nil. */);
- Vnext_selection_coding_system = Qnil;
+ defsubr (&Sw32_claim_clipboard);
+ defsubr (&Sw32_register_clipboard_format);
DEFSYM (QCLIPBOARD, "CLIPBOARD");
-
- cfg_coding_system = Qnil; staticpro (&cfg_coding_system);
- current_text = Qnil; staticpro (¤t_text);
- current_coding_system = Qnil; staticpro (¤t_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 --]
next reply other threads:[~2011-07-18 0:01 UTC|newest]
Thread overview: 51+ messages / expand[flat|nested] mbox.gz Atom feed top
2011-07-18 0:01 Daniel Colascione [this message]
2011-07-18 0:06 ` [PATCH] system-type cygwin with window-system w32 Daniel Colascione
2011-07-18 6:13 ` Eli Zaretskii
2011-07-18 6:29 ` Daniel Colascione
2011-07-18 8:53 ` Eli Zaretskii
2011-07-18 10:10 ` Daniel Colascione
2011-07-18 16:04 ` Paul Eggert
2011-07-18 16:19 ` Eli Zaretskii
2011-07-18 13:55 ` Jason Rumney
2011-07-18 16:13 ` Paul Eggert
2011-07-18 17:34 ` Andreas Schwab
2011-07-18 6:53 ` Eli Zaretskii
2011-07-18 7:01 ` Daniel Colascione
2011-07-18 9:04 ` Eli Zaretskii
2011-07-18 9:41 ` Daniel Colascione
2011-07-18 10:10 ` Eli Zaretskii
2011-07-18 10:49 ` Daniel Colascione
2011-07-18 11:22 ` Juanma Barranquero
2011-07-18 16:41 ` Eli Zaretskii
2011-07-18 16:48 ` Daniel Colascione
2011-07-18 17:08 ` Eli Zaretskii
2011-07-18 22:08 ` Richard Stallman
2011-07-18 22:24 ` Daniel Colascione
2011-07-18 22:45 ` David Kastrup
2011-07-18 22:56 ` Daniel Colascione
2011-07-19 16:49 ` Richard Stallman
2011-07-21 1:44 ` Lennart Borgman
2011-07-18 22:08 ` Richard Stallman
2011-07-18 13:31 ` Jason Rumney
2011-07-18 13:46 ` Richard Riley
2011-07-18 8:42 ` Eli Zaretskii
2011-07-18 10:33 ` Daniel Colascione
2011-07-18 16:29 ` Eli Zaretskii
2011-07-18 17:04 ` Daniel Colascione
2011-07-18 15:54 ` Stefan Monnier
2011-07-18 15:55 ` Stefan Monnier
2011-07-18 17:37 ` Andreas Schwab
-- strict thread matches above, loose matches on Subject: below --
2011-07-18 17:33 grischka
2011-07-18 17:50 ` Daniel Colascione
2011-07-18 18:08 ` Daniel Colascione
2011-07-18 18:52 ` grischka
2011-07-18 19:11 ` Daniel Colascione
2011-07-18 21:01 ` grischka
2011-07-19 2:58 ` Eli Zaretskii
2011-07-19 2:59 ` Daniel Colascione
2011-07-21 17:44 ` Lennart Borgman
2011-07-22 7:30 ` Daniel Colascione
2011-07-22 7:41 ` Lennart Borgman
2011-07-22 21:24 ` chad
2011-07-22 21:57 ` Lennart Borgman
2011-07-18 18:38 ` grischka
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=4E2377E2.1020804@gmail.com \
--to=dan.colascione@gmail.com \
--cc=emacs-devel@gnu.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
Code repositories for project(s) associated with this external index
https://git.savannah.gnu.org/cgit/emacs.git
https://git.savannah.gnu.org/cgit/emacs/org-mode.git
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.