From 0fda9b750e337d876c9461db7d4426a3f0b81482 Mon Sep 17 00:00:00 2001 From: Daniel Colascione Date: Mon, 17 Sep 2012 03:55:02 -0800 Subject: [PATCH] Implement cygw32 Here, we use the generic window-system configuration system we just implemented to support the w32 window-system in the mainline build under Cygwin. (Previously, the w32 window system could only be compiled as part of the NT-native Emacs build process.) The changes in this patch need to be applied atomically in order to avoid breaking Emacs. The changes include: - Changes throughout the Lisp and C code to not assume that NT Emacs and the w32 window system are synonymous. - Wiring up the regular select(2) event loop to Windows messages - Cleaning up the w32 drag-and-drop receiving code. - Exposing Cygwin path conversion functions to elisp. - Unicode file dialog support when compiling for Cygwin. - Splitting the w32 term lisp initialization code into code applicable to any w32 window-system and code specific to system-type windows-nt. - Integrating the old and new w32 code into the build system. --- configure.ac | 82 +++- lisp/battery.el | 2 +- lisp/faces.el | 2 +- lisp/frame.el | 4 +- lisp/international/mule-cmds.el | 3 +- lisp/loadup.el | 13 +- lisp/mouse.el | 2 +- lisp/simple.el | 2 +- lisp/term/common-win.el | 2 +- lisp/term/w32-win.el | 42 +- lisp/w32-fns.el | 105 +---- lisp/w32-vars.el | 24 +- src/Makefile.in | 25 +- src/conf_post.h | 14 + src/dispextern.h | 4 +- src/emacs.c | 28 +- src/font.c | 4 +- src/font.h | 4 +- src/fontset.c | 2 +- src/frame.c | 4 +- src/frame.h | 5 +- src/image.c | 62 ++- src/keyboard.c | 12 +- src/keyboard.h | 2 +- src/menu.c | 4 + src/process.c | 1 + src/termhooks.h | 6 +- src/unexw32.c | 2 +- src/w32.c | 19 +- src/w32.h | 17 +- src/w32console.c | 49 +-- src/w32fns.c | 732 ++++++++++++++++++++++++++------ src/w32font.c | 4 + src/w32heap.c | 41 +- src/w32inevt.c | 172 +------- src/w32menu.c | 26 +- src/w32proc.c | 14 - src/w32select.c | 5 + src/w32term.c | 52 ++- src/w32term.h | 63 ++- src/w32xfns.c | 32 +- src/window.c | 2 +- src/xdisp.c | 6 +- src/xfaces.c | 18 +- src/xterm.h | 1 - 45 files changed, 1046 insertions(+), 669 deletions(-) diff --git a/configure.ac b/configure.ac index 43686361d0..7b1ea53312 100644 --- a/configure.ac +++ b/configure.ac @@ -180,6 +180,7 @@ OPTION_DEFAULT_ON([toolkit-scroll-bars],[don't use Motif or Xaw3d scroll bars]) 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 native Windows GUI]) 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]) @@ -1524,6 +1525,7 @@ fail; AC_DEFINE(NS_HAVE_NSINTEGER, 1, [Define to 1 if `NSInteger' is defined.]) fi fi + AC_SUBST(TEMACS_LDFLAGS2) INSTALL_ARCH_INDEP_EXTRA=install-etc @@ -1567,6 +1569,30 @@ AC_SUBST(NS_OBJC_OBJ) 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 w32 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 w32font.o w32term.o" + W32_OBJ="$W32_OBJ w32xfns.o w32select.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 + ## $window_system is now set to the window system we will ## ultimately use. @@ -1600,6 +1626,9 @@ dnl use the toolkit if we have gtk, or X11R5 or newer. nextstep ) term_header=nsterm.h ;; + w32 ) + term_header=w32term.h + ;; esac if test -n "${term_header}"; then @@ -2286,6 +2315,9 @@ if test "${with_toolkit_scroll_bars}" != "no"; then 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 @@ -2452,6 +2484,41 @@ AC_SUBST(M17N_FLT_LIBS) ### Use -lXpm if available, unless `--with-xpm=no'. HAVE_XPM=no LIBXPM= + +if test "${HAVE_W32}" = "yes"; then + if test "${with_xpm}" != "no"; then + SAVE_CPPFLAGS="$CPPFLAGS" + SAVE_LDFLAGS="$LDFLAGS" + CPPFLAGS="$CPPFLAGS -I/usr/include/noX" + LDFLAGS="$LDFLAGS -L/usr/lib/noX" + AC_CHECK_HEADER(X11/xpm.h, + [AC_CHECK_LIB(Xpm, XpmReadFileToImage, HAVE_XPM=yes)]) + if test "${HAVE_XPM}" = "yes"; then + AC_MSG_CHECKING(for XpmReturnAllocPixels preprocessor define) + AC_EGREP_CPP(no_return_alloc_pixels, + [#include "X11/xpm.h" +#ifndef XpmReturnAllocPixels +no_return_alloc_pixels +#endif + ], HAVE_XPM=no, HAVE_XPM=yes) + + if test "${HAVE_XPM}" = "yes"; then + REAL_CPPFLAGS="$REAL_CPPFLAGS -I/usr/include/noX" + AC_MSG_RESULT(yes) + else + AC_MSG_RESULT(no) + CPPFLAGS="$SAVE_CPPFLAGS" + LDFLAGS="$SAVE_LDFLAGS" + fi + fi + fi + + if test "${HAVE_XPM}" = "yes"; then + AC_DEFINE(HAVE_XPM, 1, [Define to 1 if you have the Xpm libary (-lXpm).]) + LIBXPM=-lXpm + fi +fi + if test "${HAVE_X11}" = "yes"; then if test "${with_xpm}" != "no"; then AC_CHECK_HEADER(X11/xpm.h, @@ -2478,12 +2545,13 @@ no_return_alloc_pixels LIBXPM=-lXpm fi fi + AC_SUBST(LIBXPM) ### Use -ljpeg if available, unless `--with-jpeg=no'. HAVE_JPEG=no LIBJPEG= -if test "${HAVE_X11}" = "yes"; then +if test "${HAVE_X11}" = "yes" || test "${HAVE_W32}" = "yes"; then if test "${with_jpeg}" != "no"; then dnl Checking for jpeglib.h can lose because of a redefinition of dnl HAVE_STDLIB_H. @@ -2511,7 +2579,7 @@ AC_SUBST(LIBJPEG) ### Use -lpng if available, unless `--with-png=no'. HAVE_PNG=no LIBPNG= -if test "${HAVE_X11}" = "yes"; then +if test "${HAVE_X11}" = "yes" || test "${HAVE_W32}" = "yes"; then if test "${with_png}" != "no"; then # Debian unstable as of July 2003 has multiple libpngs, and puts png.h # in /usr/include/libpng. @@ -2544,7 +2612,7 @@ AC_SUBST(LIBPNG) ### Use -ltiff if available, unless `--with-tiff=no'. HAVE_TIFF=no LIBTIFF= -if test "${HAVE_X11}" = "yes"; then +if test "${HAVE_X11}" = "yes" || test "${HAVE_W32}" = "yes"; then if test "${with_tiff}" != "no"; then AC_CHECK_HEADER(tiffio.h, [tifflibs="-lz -lm" @@ -2564,7 +2632,8 @@ AC_SUBST(LIBTIFF) ### Use -lgif or -lungif if available, unless `--with-gif=no'. HAVE_GIF=no LIBGIF= -if test "${HAVE_X11}" = "yes" && test "${with_gif}" != "no"; then +if test "${HAVE_X11}" = "yes" && test "${with_gif}" != "no" \ + || test "${HAVE_W32}" = "yes"; then AC_CHECK_HEADER(gif_lib.h, # EGifPutExtensionLast only exists from version libungif-4.1.0b1. # Earlier versions can crash Emacs. @@ -2646,6 +2715,9 @@ if test "${HAVE_NS}" = "yes"; then 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 @@ -4144,7 +4216,7 @@ fi 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 diff --git a/lisp/battery.el b/lisp/battery.el index 8e98291b11..69d25643bb 100644 --- a/lisp/battery.el +++ b/lisp/battery.el @@ -60,7 +60,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. diff --git a/lisp/faces.el b/lisp/faces.el index 6a477e172e..d004ae650c 100644 --- a/lisp/faces.el +++ b/lisp/faces.el @@ -96,7 +96,7 @@ ALTERNATIVE2 etc." ;; 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") diff --git a/lisp/frame.el b/lisp/frame.el index 01225639ec..9be64a6b7f 100644 --- a/lisp/frame.el +++ b/lisp/frame.el @@ -524,7 +524,7 @@ The optional argument PARAMETERS specifies additional frame parameters." (ns-initialize-window-system)) (make-frame `((window-system . ns) (display . ,display) . ,parameters))) - ((eq system-type 'windows-nt) + ((eq window-system 'w32) ;; On Windows, ignore DISPLAY. (make-frame parameters)) (t @@ -1260,7 +1260,7 @@ frame's display)." (cond ((eq frame-type 'pc) (msdos-mouse-p)) - ((eq system-type 'windows-nt) + ((eq frame-type 'w32) (with-no-warnings (> w32-num-mouse-buttons 0))) ((memq frame-type '(x ns)) diff --git a/lisp/international/mule-cmds.el b/lisp/international/mule-cmds.el index 2fc9759972..177ac8eaa9 100644 --- a/lisp/international/mule-cmds.el +++ b/lisp/international/mule-cmds.el @@ -2670,7 +2670,8 @@ See also `locale-charset-language-names', `locale-language-names', ;; On Windows, override locale-coding-system, ;; default-file-name-coding-system, keyboard-coding-system, ;; terminal-coding-system with system codepage. - (when (boundp 'w32-ansi-code-page) + (when (and (eq system-type 'windows-nt) + (boundp 'w32-ansi-code-page)) (let ((code-page-coding (intern (format "cp%d" w32-ansi-code-page)))) (when (coding-system-p code-page-coding) (unless frame (setq locale-coding-system code-page-coding)) diff --git a/lisp/loadup.el b/lisp/loadup.el index a460fcab33..c70b417822 100644 --- a/lisp/loadup.el +++ b/lisp/loadup.el @@ -224,15 +224,18 @@ (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 "w32-vars") (load "term/w32-win") - (load "ls-lisp") (load "disp-table") - (load "dos-w32") - (load "w32-fns"))) + (load "w32-common-fns") + (when (eq system-type 'windows-nt) + (load "w32-fns") + (load "ls-lisp") + (load "dos-w32")))) (if (eq system-type 'ms-dos) (progn (load "dos-w32") diff --git a/lisp/mouse.el b/lisp/mouse.el index 4ea84288f6..14e69c9f34 100644 --- a/lisp/mouse.el +++ b/lisp/mouse.el @@ -1151,7 +1151,7 @@ regardless of where you click." (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 diff --git a/lisp/simple.el b/lisp/simple.el index b7a24f4f97..b81e0d7ee8 100644 --- a/lisp/simple.el +++ b/lisp/simple.el @@ -6870,7 +6870,7 @@ call `normal-erase-is-backspace-mode' (which see) instead." (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)) diff --git a/lisp/term/common-win.el b/lisp/term/common-win.el index 067b996d1f..b44e092cc0 100644 --- a/lisp/term/common-win.el +++ b/lisp/term/common-win.el @@ -57,7 +57,7 @@ clipboard as well. 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)) diff --git a/lisp/term/w32-win.el b/lisp/term/w32-win.el index a4fac3441d..dd577af0ae 100644 --- a/lisp/term/w32-win.el +++ b/lisp/term/w32-win.el @@ -1,4 +1,4 @@ -;;; w32-win.el --- parse switches controlling interface with W32 window system +;;; w32-win.el --- parse switches controlling interface with W32 window system -*- lexical-binding: t -*- ;; Copyright (C) 1993-1994, 2001-2012 Free Software Foundation, Inc. @@ -102,7 +102,22 @@ ;; (interactive "e") ;; (princ event)) -(defun w32-drag-n-drop (event) +(defun w32-handle-dropped-file (window file-name) + (let ((f (if (eq system-type 'cygwin) + (cygwin-convert-path-from-windows file-name t) + (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))) + +(defun w32-drag-n-drop (event &optional new-frame) "Edit the files listed in the drag-n-drop EVENT. Switch to a buffer editing the last file dropped." (interactive "e") @@ -116,26 +131,21 @@ Switch to a buffer editing the last file dropped." (y (cdr coords))) (if (and (> x 0) (> y 0)) (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))))) - (raise-frame))) + + (when new-frame + (select-frame (make-frame))) + (raise-frame) + (setq window (selected-window)) + + (mapc (apply-partially #'w32-handle-dropped-file window) + (car (cdr (cdr event))))))) (defun w32-drag-n-drop-other-frame (event) "Edit the files listed in the drag-n-drop EVENT, in other frames. May create new frames, or reuse existing ones. The frame editing the last file dropped is selected." (interactive "e") - (mapcar 'find-file-other-frame (car (cdr (cdr event))))) + (w32-drag-n-drop event t)) ;; Bind the drag-n-drop event. (global-set-key [drag-n-drop] 'w32-drag-n-drop) diff --git a/lisp/w32-fns.el b/lisp/w32-fns.el index 1769ee73be..813a8fd4d9 100644 --- a/lisp/w32-fns.el +++ b/lisp/w32-fns.el @@ -26,34 +26,20 @@ ;;; Code: (require 'w32-vars) +(require 'w32-common-fns) (defvar explicit-shell-file-name) ;;;; 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." - (and (eq system-type 'windows-nt) (getenv "SystemRoot"))) - (defun w32-shell-name () "Return the name of the shell being used." (or (bound-and-true-p shell-file-name) @@ -240,53 +226,6 @@ requires it (see `w32-shell-dos-semantics')." (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 @@ -311,14 +250,6 @@ This function is provided for backward compatibility, since ;; 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) "Function to add character sets to display with Windows fonts. Creates entries in `w32-charset-info-alist'. @@ -380,40 +311,6 @@ bit output with no translation." 'w32-charset-info-alist "21.1") -;;;; 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)))))) - -(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) - - ;;;; Support for build process ;; From autoload.el diff --git a/lisp/w32-vars.el b/lisp/w32-vars.el index c8716ef6c3..0e152b125b 100644 --- a/lisp/w32-vars.el +++ b/lisp/w32-vars.el @@ -44,17 +44,19 @@ X does. See `w32-fixed-font-alist' for the font menu definition." "Include proportional fonts in the default font dialog.") (make-obsolete-variable 'w32-list-proportional-fonts "no longer used." "23.1") -(defcustom w32-allow-system-shell nil - "Disable startup warning when using \"system\" shells." - :type 'boolean - :group 'w32) - -(defcustom w32-system-shells '("cmd" "cmd.exe" "command" "command.com" - "4nt" "4nt.exe" "4dos" "4dos.exe" - "tcc" "tcc.exe" "ndos" "ndos.exe") - "List of strings recognized as Windows system shells." - :type '(repeat string) - :group 'w32) +(unless (eq system-type 'cygwin) + (defcustom w32-allow-system-shell nil + "Disable startup warning when using \"system\" shells." + :type 'boolean + :group 'w32)) + +(unless (eq system-type 'cygwin) + (defcustom w32-system-shells '("cmd" "cmd.exe" "command" "command.com" + "4nt" "4nt.exe" "4dos" "4dos.exe" + "tcc" "tcc.exe" "ndos" "ndos.exe") + "List of strings recognized as Windows system shells." + :type '(repeat string) + :group 'w32)) ;; Want "menu" custom type for this. (defcustom w32-fixed-font-alist diff --git a/src/Makefile.in b/src/Makefile.in index a809216f09..847a5e58fd 100644 --- a/src/Makefile.in +++ b/src/Makefile.in @@ -135,13 +135,10 @@ LIB_MATH=@LIB_MATH@ ## -lpthreads, or empty. LIB_PTHREAD=@LIB_PTHREAD@ -LIBTIFF=@LIBTIFF@ -LIBJPEG=@LIBJPEG@ -LIBPNG=@LIBPNG@ -LIBGIF=@LIBGIF@ -LIBXPM=@LIBXPM@ +LIBIMAGE=@LIBTIFF@ @LIBJPEG@ @LIBPNG@ @LIBGIF@ @LIBXPM@ + XFT_LIBS=@XFT_LIBS@ -LIBX_EXTRA=$(LIBTIFF) $(LIBJPEG) $(LIBPNG) $(LIBGIF) $(LIBXPM) -lX11 $(XFT_LIBS) +LIBX_EXTRA=-lX11 $(XFT_LIBS) FONTCONFIG_CFLAGS = @FONTCONFIG_CFLAGS@ FONTCONFIG_LIBS = @FONTCONFIG_LIBS@ @@ -263,6 +260,13 @@ NS_OBJ=@NS_OBJ@ 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 @@ -343,7 +347,7 @@ base_obj = dispnew.o frame.o scroll.o xdisp.o menu.o $(XMENU_OBJ) window.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) \ - $(WINDOW_SYSTEM_OBJ) + $(W32_OBJ) $(WINDOW_SYSTEM_OBJ) obj = $(base_obj) $(NS_OBJC_OBJ) ## Object files used on some machine or other. @@ -352,9 +356,9 @@ obj = $(base_obj) $(NS_OBJC_OBJ) ## 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 @@ -386,7 +390,8 @@ otherobj= $(TERMCAP_OBJ) $(PRE_ALLOC_OBJ) $(GMALLOC_OBJ) $(RALLOC_OBJ) \ ## 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) $(LIBIMAGE) \ + $(LIBX_OTHER) $(LIBSOUND) \ $(RSVG_LIBS) $(IMAGEMAGICK_LIBS) $(LIB_CLOCK_GETTIME) $(DBUS_LIBS) \ $(LIB_EXECINFO) \ $(LIBXML2_LIBS) $(LIBGPM) $(LIBRESOLV) $(LIBS_SYSTEM) \ diff --git a/src/conf_post.h b/src/conf_post.h index f90ef90fb8..8bd66be2c4 100644 --- a/src/conf_post.h +++ b/src/conf_post.h @@ -164,6 +164,20 @@ You lose; /* Emacs for DOS must be compiled with DJGPP */ #endif #endif +#if defined(HAVE_NTGUI) && !defined(DebPrint) +# if defined(EMACSDEBUG) +extern void _DebPrint (const char *fmt, ...); +# define DebPrint(stuff) _DebPrint stuff +# else +# define DebPrint(stuff) +# endif /* EMACSDEBUG */ +#endif /* DebPrint */ + +#if defined(CYGWIN) && defined(HAVE_NTGUI) +#define NTGUI_UNICODE /* Cygwin runs only on UNICODE-supporting systems */ +#define _WIN32_WINNT 0x500 /* Win2k */ +#endif /* CYGWIN && HAVE_NTGUI */ + #ifdef emacs /* Don't do this for lib-src. */ /* Tell regex.c to use a type compatible with Emacs. */ #define RE_TRANSLATE_TYPE Lisp_Object diff --git a/src/dispextern.h b/src/dispextern.h index 1140d98f8a..1aff547f18 100644 --- a/src/dispextern.h +++ b/src/dispextern.h @@ -3139,7 +3139,7 @@ int draw_window_fringes (struct window *, int); 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 @@ -3241,7 +3241,7 @@ extern char unspecified_fg[], unspecified_bg[]; #ifdef HAVE_X_WINDOWS void gamma_correct (struct frame *, XColor *); #endif -#ifdef WINDOWSNT +#ifdef HAVE_NTGUI void gamma_correct (struct frame *, COLORREF *); #endif diff --git a/src/emacs.c b/src/emacs.c index adfff6ff3e..9a9309546a 100644 --- a/src/emacs.c +++ b/src/emacs.c @@ -37,9 +37,20 @@ along with GNU Emacs. If not, see . */ #ifdef WINDOWSNT #include -#include /* just for w32.h */ #include "w32.h" -#include "w32heap.h" /* for prototype of sbrk */ +#endif + +#if defined (WINDOWSNT) +#include "w32heap.h" +#endif + +#if defined (WINDOWSNT) || defined (HAVE_NTGUI) +#include "w32select.h" +#include "w32font.h" +#endif + +#if defined (HAVE_NTGUI) && defined (CYGWIN) +#include "cygw32.h" #endif #ifdef NS_IMPL_GNUSTEP @@ -1484,6 +1495,9 @@ Using an Emacs configured with --with-x-toolkit=lucid does not have this problem #ifdef WINDOWSNT syms_of_ntproc (); #endif /* WINDOWSNT */ +#if defined (CYGWIN) && defined (HAVE_NTGUI) + syms_of_cygw32 (); +#endif /* defined(CYGWIN) && defined (HAVE_NTGUI) */ syms_of_window (); syms_of_xdisp (); syms_of_font (); @@ -1514,11 +1528,14 @@ Using an Emacs configured with --with-x-toolkit=lucid does not have this problem #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 (); @@ -1561,8 +1578,11 @@ Using an Emacs configured with --with-x-toolkit=lucid does not have this problem globals_of_w32font (); globals_of_w32fns (); globals_of_w32menu (); - globals_of_w32select (); #endif /* HAVE_NTGUI */ + +#ifdef HAVE_W32SELECT + globals_of_w32select (); +#endif /* HAVE_W32SELECT */ } init_charset (); diff --git a/src/font.c b/src/font.c index cf9964f08f..c775b56caa 100644 --- a/src/font.c +++ b/src/font.c @@ -5207,9 +5207,9 @@ EMACS_FONT_LOG is set. Otherwise, it is set to t. */); #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 */ diff --git a/src/font.h b/src/font.h index 6e9387f763..5ed9affa9e 100644 --- a/src/font.h +++ b/src/font.h @@ -826,11 +826,11 @@ extern struct font_driver ftxfont_driver; 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; diff --git a/src/fontset.c b/src/fontset.c index 01e38fe45e..783f99c210 100644 --- a/src/fontset.c +++ b/src/fontset.c @@ -43,7 +43,7 @@ along with GNU Emacs. If not, see . */ #ifdef HAVE_X_WINDOWS #include "xterm.h" #endif -#ifdef WINDOWSNT +#ifdef HAVE_NTGUI #include "w32term.h" #endif #ifdef HAVE_NS diff --git a/src/frame.c b/src/frame.c index 968cb4905a..aa1508e6d2 100644 --- a/src/frame.c +++ b/src/frame.c @@ -2693,7 +2693,7 @@ static const struct frame_parm_table frame_parms[] = {"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). @@ -2737,7 +2737,7 @@ x_fullscreen_adjust (struct frame *f, int *width, int *height, int *top_pos, int *height = newheight; } -#endif /* WINDOWSNT */ +#endif /* HAVE_NTGUI */ #ifdef HAVE_WINDOW_SYSTEM diff --git a/src/frame.h b/src/frame.h index 1fe3ebd918..2e0bcee432 100644 --- a/src/frame.h +++ b/src/frame.h @@ -621,7 +621,7 @@ typedef struct frame *FRAME_PTR; #define FRAME_INITIAL_P(f) ((f)->output_method == output_initial) #define FRAME_TERMCAP_P(f) ((f)->output_method == output_termcap) #define FRAME_X_P(f) ((f)->output_method == output_x_window) -#ifndef WINDOWSNT +#ifndef HAVE_NTGUI #define FRAME_W32_P(f) (0) #else #define FRAME_W32_P(f) ((f)->output_method == output_w32) @@ -1213,7 +1213,7 @@ extern Lisp_Object x_new_font (struct frame *, Lisp_Object, int); 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 @@ -1285,6 +1285,7 @@ extern char *x_get_resource_string (const char *, const char *); #endif extern void x_query_colors (struct frame *f, XColor *, int); +extern void x_query_color (struct frame *f, XColor *); /* In xmenu.c */ extern void set_frame_menubar (FRAME_PTR, int, int); diff --git a/src/image.c b/src/image.c index d4e78d4100..b5a2e0328e 100644 --- a/src/image.c +++ b/src/image.c @@ -76,7 +76,11 @@ typedef struct x_bitmap_record Bitmap_Record; #endif /* HAVE_X_WINDOWS */ #ifdef HAVE_NTGUI -#include "w32.h" +# ifdef WINDOWSNT +/* We only need (or want) w32.h when we're _not_ + * compiling for Cygwin */ +# include "w32.h" +# endif /* WINDOWSNT */ /* W32_TODO : Color tables on W32. */ #undef COLOR_TABLE_SUPPORT @@ -569,13 +573,14 @@ static void x_laplace (struct frame *, struct image *); static void x_emboss (struct frame *, struct image *); static int x_build_heuristic_mask (struct frame *, struct image *, Lisp_Object); -#ifdef HAVE_NTGUI -extern Lisp_Object Vlibrary_cache, QCloaded_from; +#ifdef WINDOWSNT +extern Lisp_Object Vlibrary_cache; + #define CACHE_IMAGE_TYPE(type, status) \ do { Vlibrary_cache = Fcons (Fcons (type, status), Vlibrary_cache); } while (0) #else #define CACHE_IMAGE_TYPE(type, status) -#endif +#endif /* WINDOWSNT */ #define ADD_IMAGE_TYPE(type) \ do { Vimage_types = Fcons (type, Vimage_types); } while (0) @@ -1861,7 +1866,7 @@ mark_image_cache (struct image_cache *c) X / NS / W32 support code ***********************************************************************/ -#ifdef HAVE_NTGUI +#ifdef WINDOWSNT /* Macro for defining functions that will be loaded from image DLLs. */ #define DEF_IMGLIB_FN(rettype,func,args) static rettype (FAR CDECL *fn_##func)args @@ -1872,7 +1877,7 @@ mark_image_cache (struct image_cache *c) if (!fn_##func) return 0; \ } -#endif /* HAVE_NTGUI */ +#endif /* WINDOWSNT */ static int x_create_x_image_and_pixmap (struct frame *, int, int, int, XImagePtr *, Pixmap *); @@ -2935,7 +2940,7 @@ xbm_load (struct frame *f, struct image *img) else bits = (char *) XBOOL_VECTOR (data)->data; -#ifdef WINDOWSNT +#ifdef HAVE_NTGUI { char *invertedBits; int nbytes, i; @@ -3243,7 +3248,7 @@ xpm_free_colors (Display *dpy, Colormap cmap, Pixel *pixels, int npixels, void * #endif /* ALLOC_XPM_COLORS */ -#ifdef HAVE_NTGUI +#ifdef WINDOWSNT /* XPM library details. */ @@ -3269,8 +3274,15 @@ init_xpm_functions (Lisp_Object libraries) return 1; } -#endif /* HAVE_NTGUI */ +#endif /* WINDOWSNT */ +#ifdef HAVE_NTGUI +/* Glue for code below */ +#define fn_XpmReadFileToImage XpmReadFileToImage +#define fn_XpmCreateImageFromBuffer XpmCreateImageFromBuffer +#define fn_XImageFree XImageFree +#define fn_XpmFreeAttributes XpmFreeAttributes +#endif /* HAVE_NTGUI */ /* Value is non-zero if COLOR_SYMBOLS is a valid color symbols list for XPM images. Such a list must consist of conses whose car and @@ -5414,7 +5426,7 @@ png_image_p (Lisp_Object object) #ifdef HAVE_PNG -#ifdef HAVE_NTGUI +#ifdef WINDOWSNT /* PNG library details. */ DEF_IMGLIB_FN (png_voidp, png_get_io_ptr, (png_structp)); @@ -5514,7 +5526,7 @@ init_png_functions (Lisp_Object libraries) #define fn_png_set_longjmp_fn png_set_longjmp_fn #endif /* libpng version >= 1.5 */ -#endif /* HAVE_NTGUI */ +#endif /* WINDOWSNT */ #if (PNG_LIBPNG_VER < 10500) @@ -6045,14 +6057,20 @@ jpeg_image_p (Lisp_Object object) #define __WIN32__ 1 #endif +/* Work around conflict between jpeg boolean and rpcndr.h + under Windows. */ +#define boolean jpeg_boolean #include #include +/* Don't undefine boolean --- use the JPEG boolean + through the rest of the file. */ + #ifdef HAVE_STLIB_H_1 #define HAVE_STDLIB_H 1 #endif -#ifdef HAVE_NTGUI +#ifdef WINDOWSNT /* JPEG library details. */ DEF_IMGLIB_FN (void, jpeg_CreateDecompress, (j_decompress_ptr, int, size_t)); @@ -6102,7 +6120,7 @@ jpeg_resync_to_restart_wrapper (j_decompress_ptr cinfo, int desired) #define fn_jpeg_std_error jpeg_std_error #define jpeg_resync_to_restart_wrapper jpeg_resync_to_restart -#endif /* HAVE_NTGUI */ +#endif /* WINDOWSNT */ struct my_jpeg_error_mgr { @@ -6583,7 +6601,7 @@ tiff_image_p (Lisp_Object object) #include -#ifdef HAVE_NTGUI +#ifdef WINDOWSNT /* TIFF library details. */ DEF_IMGLIB_FN (TIFFErrorHandler, TIFFSetErrorHandler, (TIFFErrorHandler)); @@ -6627,7 +6645,7 @@ init_tiff_functions (Lisp_Object libraries) #define fn_TIFFReadRGBAImage TIFFReadRGBAImage #define fn_TIFFClose TIFFClose #define fn_TIFFSetDirectory TIFFSetDirectory -#endif /* HAVE_NTGUI */ +#endif /* WINDOWSNT */ /* Reading from a memory buffer for TIFF images Based on the PNG @@ -7056,7 +7074,7 @@ gif_image_p (Lisp_Object object) #endif /* HAVE_NTGUI */ -#ifdef HAVE_NTGUI +#ifdef WINDOWSNT /* GIF library details. */ DEF_IMGLIB_FN (int, DGifCloseFile, (GifFileType *)); @@ -7086,7 +7104,7 @@ init_gif_functions (Lisp_Object libraries) #define fn_DGifOpen DGifOpen #define fn_DGifOpenFileName DGifOpenFileName -#endif /* HAVE_NTGUI */ +#endif /* WINDOWSNT */ /* Reading a GIF image from memory Based on the PNG memory stuff to a certain extent. */ @@ -8075,7 +8093,7 @@ svg_image_p (Lisp_Object object) #include -#ifdef HAVE_NTGUI +#ifdef WINDOWSNT /* SVG library functions. */ DEF_IMGLIB_FN (RsvgHandle *, rsvg_handle_new); @@ -8153,7 +8171,7 @@ init_svg_functions (Lisp_Object libraries) #define fn_g_type_init g_type_init #define fn_g_object_unref g_object_unref #define fn_g_error_free g_error_free -#endif /* !HAVE_NTGUI */ +#endif /* !WINDOWSNT */ /* Load SVG image IMG for use on frame F. Value is non-zero if successful. this function will go into the svg_type structure, and @@ -8701,7 +8719,7 @@ DEFUN ("lookup-image", Flookup_image, Slookup_image, 1, 1, 0, "") Initialization ***********************************************************************/ -#ifdef HAVE_NTGUI +#ifdef WINDOWSNT /* Image types that rely on external libraries are loaded dynamically if the library is available. */ #define CHECK_LIB_AVAILABLE(image_type, init_lib_fn, libraries) \ @@ -8709,7 +8727,7 @@ DEFUN ("lookup-image", Flookup_image, Slookup_image, 1, 1, 0, "") #else #define CHECK_LIB_AVAILABLE(image_type, init_lib_fn, libraries) \ define_image_type (image_type, 1) -#endif /* HAVE_NTGUI */ +#endif /* WINDOWSNT */ DEFUN ("init-image-library", Finit_image_library, Sinit_image_library, 2, 2, 0, doc: /* Initialize image library implementing image type TYPE. @@ -8720,7 +8738,7 @@ Libraries to load are specified in alist LIBRARIES (usually, the value 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)) diff --git a/src/keyboard.c b/src/keyboard.c index ff2b75e351..992d1a97b3 100644 --- a/src/keyboard.c +++ b/src/keyboard.c @@ -314,7 +314,7 @@ static Lisp_Object Qmouse_fixup_help_message; /* 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; @@ -3828,8 +3828,8 @@ kbd_buffer_get_event (KBOARD **kbp, #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) @@ -4015,7 +4015,7 @@ kbd_buffer_get_event (KBOARD **kbp, 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 CODEPAGE LANGUAGE-ID)). */ @@ -5470,7 +5470,7 @@ make_lispy_event (struct input_event *event) (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])) @@ -11499,7 +11499,7 @@ syms_of_keyboard (void) 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 diff --git a/src/keyboard.h b/src/keyboard.h index 98b1933f3f..69fa533fd0 100644 --- a/src/keyboard.h +++ b/src/keyboard.h @@ -552,7 +552,7 @@ extern int tty_read_avail_input (struct terminal *, int, extern EMACS_TIME timer_check (void); extern void mark_kboards (void); -#ifdef WINDOWSNT +#ifdef HAVE_NTGUI extern const char *const lispy_function_keys[]; #endif diff --git a/src/menu.c b/src/menu.c index 2077053732..336e1a9e31 100644 --- a/src/menu.c +++ b/src/menu.c @@ -41,7 +41,11 @@ along with GNU Emacs. If not, see . */ #endif /* HAVE_WINDOW_SYSTEM */ #ifdef HAVE_NTGUI +# ifdef NTGUI_UNICODE +# define unicode_append_menu AppendMenuW +# else /* !NTGUI_UNICODE */ extern AppendMenuW_Proc unicode_append_menu; +# endif /* NTGUI_UNICODE */ extern HMENU current_popup_menu; #endif /* HAVE_NTGUI */ diff --git a/src/process.c b/src/process.c index bfac054c3c..b45ba73363 100644 --- a/src/process.c +++ b/src/process.c @@ -4675,6 +4675,7 @@ wait_reading_process_output (intmax_t time_limit, int nsecs, int read_kbd, process_output_skip = 0; } #endif + #if defined (USE_GTK) || defined (HAVE_GCONF) || defined (HAVE_GSETTINGS) nfds = xg_select #elif defined (HAVE_NS) diff --git a/src/termhooks.h b/src/termhooks.h index 46962a1217..0864b80da8 100644 --- a/src/termhooks.h +++ b/src/termhooks.h @@ -107,9 +107,9 @@ enum event_kind 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 when HAVE_NTGUI or on Mac OS when the keyboard layout or input language is changed by the user. */ @@ -188,7 +188,7 @@ enum event_kind , 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 diff --git a/src/unexw32.c b/src/unexw32.c index 52b2ec4bf2..8061227d3a 100644 --- a/src/unexw32.c +++ b/src/unexw32.c @@ -83,7 +83,7 @@ DWORD extra_bss_size_static = 0; PIMAGE_SECTION_HEADER heap_section; #ifdef HAVE_NTGUI -HINSTANCE hinst = NULL; +extern HINSTANCE hinst; HINSTANCE hprevinst = NULL; LPSTR lpCmdLine = ""; int nCmdShow = 0; diff --git a/src/w32.c b/src/w32.c index 84a46e522b..d779d74072 100644 --- a/src/w32.c +++ b/src/w32.c @@ -31,7 +31,6 @@ along with GNU Emacs. If not, see . */ #include #include #include -#include /* for _mbspbrk */ #include #include #include @@ -39,6 +38,7 @@ along with GNU Emacs. If not, see . */ /* must include CRT headers *before* config.h */ #include +#include /* for _mbspbrk */ #undef access #undef chdir @@ -867,23 +867,6 @@ create_symbolic_link (LPTSTR lpSymlinkFilename, return retval; } -/* 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. diff --git a/src/w32.h b/src/w32.h index 73d57a65a4..b83b716b61 100644 --- a/src/w32.h +++ b/src/w32.h @@ -19,6 +19,12 @@ 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 . */ +#ifdef CYGWIN +#error "w32.h is not compatible with Cygwin" +#endif + +#include + /* File descriptor set emulation. */ @@ -130,17 +136,6 @@ extern LPBYTE w32_get_resource (char * key, LPDWORD type); extern void init_ntproc (void); extern void term_ntproc (void); extern void globals_of_w32 (void); -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); -extern void syms_of_w32font (void); -extern void check_windows_init_file (void); extern int _sys_read_ahead (int fd); extern int _sys_wait_accept (int fd); diff --git a/src/w32console.c b/src/w32console.c index 76585851e7..76b7bb0b45 100644 --- a/src/w32console.c +++ b/src/w32console.c @@ -37,6 +37,7 @@ along with GNU Emacs. If not, see . */ #include "termhooks.h" #include "termchar.h" #include "dispextern.h" +#include "w32term.h" #include "w32heap.h" /* for os_subtype */ #include "w32inevt.h" @@ -431,53 +432,6 @@ w32con_delete_glyphs (struct frame *f, int n) 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) @@ -851,5 +805,4 @@ scroll-back buffer. */); defsubr (&Sset_screen_color); defsubr (&Sget_screen_color); defsubr (&Sset_cursor_size); - defsubr (&Sset_message_beep); } diff --git a/src/w32fns.c b/src/w32fns.c index 5a1b6dfaba..16a2fb4dfd 100644 --- a/src/w32fns.c +++ b/src/w32fns.c @@ -45,8 +45,14 @@ along with GNU Emacs. If not, see . */ #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" @@ -59,9 +65,6 @@ along with GNU Emacs. If not, see . */ #include #include -#define FILE_NAME_TEXT_FIELD edt1 -#define FILE_NAME_COMBO_BOX cmb13 -#define FILE_NAME_LIST lst1 #include "font.h" #include "w32font.h" @@ -79,6 +82,7 @@ extern int w32_console_toggle_lock_key (int, Lisp_Object); 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. */ @@ -164,7 +168,11 @@ ImmSetCompositionWindow_Proc set_ime_composition_window_fn = NULL; MonitorFromPoint_Proc monitor_from_point_fn = NULL; GetMonitorInfo_Proc get_monitor_info_fn = NULL; +#ifdef NTGUI_UNICODE +#define unicode_append_menu AppendMenuW +#else /* !NTGUI_UNICODE */ extern AppendMenuW_Proc unicode_append_menu; +#endif /* NTGUI_UNICODE */ /* Flag to selectively ignore WM_IME_CHAR messages. */ static int ignore_ime_char = 0; @@ -202,6 +210,33 @@ extern int uniscribe_available; static void w32_show_hourglass (struct frame *); static void w32_hide_hourglass (void); +#ifdef WINDOWSNT +/* From w32inevet.c */ +extern int faked_key; +#endif /* WINDOWSNT */ + +/* 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) /* Error if we are not connected to MS-Windows. */ @@ -1847,10 +1882,7 @@ w32_createwindow (struct frame *f) /* 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) { @@ -2250,6 +2282,58 @@ unregister_hot_keys (HWND hwnd) } } +#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 @@ -2263,6 +2347,10 @@ w32_msg_pump (deferred_msg * msg_buf) while ((w32_unicode_gui ? GetMessageW : GetMessageA) (&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) @@ -2350,7 +2438,7 @@ w32_msg_pump (deferred_msg * msg_buf) /* Broadcast messages make it here, so you need to be looking for something in particular for this to be useful. */ default: - DebPrint (("msg %x not expected by w32_msg_pump\n", msg.message)); + DebPrint (("msg %x not expected by w32_msg_pump\n", msg.message)); #endif } } @@ -4692,6 +4780,37 @@ If omitted or nil, that stands for the selected frame's display. */) { 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; +} + int x_pixel_width (register struct frame *f) @@ -5865,6 +5984,18 @@ Value is t if tooltip was open, nil otherwise. */) File selection dialog ***********************************************************************/ +#define FILE_NAME_TEXT_FIELD edt1 +#define FILE_NAME_COMBO_BOX cmb13 +#define FILE_NAME_LIST lst1 + +#ifdef NTGUI_UNICODE +#define GUISTR(x) (L ## x) +typedef wchar_t guichar_t; +#else /* !NTGUI_UNICODE */ +#define GUISTR(x) x +typedef char guichar_t; +#endif /* NTGUI_UNICODE */ + /* Callback for altering the behavior of the Open File dialog. Makes the Filename text field contain "Current Directory" and be read-only when "Directories" is selected in the filter. This @@ -5875,7 +6006,11 @@ file_dialog_callback (HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam) { if (msg == WM_NOTIFY) { - OFNOTIFY * notify = (OFNOTIFY *)lParam; +#ifdef NTGUI_UNICODE + OFNOTIFYW * notify = (OFNOTIFYW *)lParam; +#else /* !NTGUI_UNICODE */ + OFNOTIFYA * notify = (OFNOTIFYA *)lParam; +#endif /* NTGUI_UNICODE */ /* Detect when the Filter dropdown is changed. */ if (notify->hdr.code == CDN_TYPECHANGE || notify->hdr.code == CDN_INITDONE) @@ -5903,7 +6038,7 @@ file_dialog_callback (HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam) if (notify->lpOFN->nFilterIndex == 2) { CommDlg_OpenSave_SetControlText (dialog, FILE_NAME_TEXT_FIELD, - "Current Directory"); + GUISTR ("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 @@ -5919,7 +6054,8 @@ file_dialog_callback (HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam) /* 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, + GUISTR ("")); EnableWindow (edit_control, TRUE); } } @@ -5927,19 +6063,6 @@ file_dialog_callback (HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam) 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 @@ -5951,134 +6074,203 @@ Motif or Gtk toolkits. With the Motif toolkit, ONLY-DIR-P is ignored. Otherwise, if ONLY-DIR-P is non-nil, the user can only select directories. */) (Lisp_Object prompt, Lisp_Object dir, Lisp_Object default_filename, Lisp_Object mustmatch, Lisp_Object only_dir_p) { + /* Filter index: 1: All Files, 2: Directories only */ + static const guichar_t filter[] = + GUISTR ("All Files (*.*)\0*.*\0Directories\0*|*\0"); + + Lisp_Object filename = default_filename; struct frame *f = SELECTED_FRAME (); - Lisp_Object file = Qnil; - ptrdiff_t count = SPECPDL_INDEX (); + BOOL file_opened = FALSE; + Lisp_Object orig_dir = dir; + Lisp_Object orig_prompt = prompt; + + /* If 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 newer versions of Windows. */ + struct { +#ifdef NTGUI_UNICODE + OPENFILENAMEW details; +#else /* !NTGUI_UNICODE */ + OPENFILENAMEA details; +#endif /* NTGUI_UNICODE */ + +#if _WIN32_WINNT < 0x500 /* < win2k */ + PVOID pvReserved; + DWORD dwReserved; + DWORD FlagsEx; +#endif /* < win2k */ + } new_file_details; + +#ifdef NTGUI_UNICODE + wchar_t filename_buf[MAX_PATH + 1]; + OPENFILENAMEW * file_details = &new_file_details.details; +#else /* not NTGUI_UNICODE */ + char filename_buf[MAX_PATH + 1]; + OPENFILENAMEA * file_details = &new_file_details.details; +#endif /* NTGUI_UNICODE */ + struct gcpro gcpro1, gcpro2, gcpro3, gcpro4, gcpro5, gcpro6; - char filename[MAX_PATH + 1]; - char init_dir[MAX_PATH + 1]; - int default_filter_index = 1; /* 1: All Files, 2: Directories only */ - - GCPRO6 (prompt, dir, default_filename, mustmatch, only_dir_p, file); - CHECK_STRING (prompt); - CHECK_STRING (dir); - - /* 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)); + GCPRO6 (prompt, dir, default_filename, mustmatch, only_dir_p, filename); - unixtodos_filename (full_path_name); + { + struct gcpro gcpro1, gcpro2; + GCPRO2 (orig_dir, orig_prompt); /* There is no GCPRON, N>6. */ - file_name_only = strrchr (full_path_name, '\\'); - if (!file_name_only) - file_name_only = full_path_name; - else - file_name_only++; + /* Note: under NTGUI_UNICODE, we do _NOT_ use ENCODE_FILE: the + system file encoding expected by the platform APIs (e.g. Cygwin's + POSIX implementation) may not the same as the encoding expected + by the Windows API! */ - strncpy (filename, file_name_only, MAX_PATH); - filename[MAX_PATH] = '\0'; - } - else - filename[0] = '\0'; + CHECK_STRING (prompt); + CHECK_STRING (dir); - /* 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"); + dir = Fexpand_file_name (dir, Qnil); - { - NEWOPENFILENAME new_file_details; - BOOL file_opened = FALSE; - OPENFILENAME * file_details = &new_file_details.real_details; + if (STRINGP (filename)) + filename = Ffile_name_nondirectory (filename); + else + filename = empty_unibyte_string; - /* Prevent redisplay. */ - specbind (Qinhibit_redisplay, Qt); - BLOCK_INPUT; +#ifdef CYGWIN + dir = Fcygwin_convert_path_to_windows (dir, Qt); + if (SCHARS (filename) > 0) + filename = Fcygwin_convert_path_to_windows (filename, Qnil); +#endif + CHECK_STRING (dir); + CHECK_STRING (filename); + + /* 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 (SCHARS (filename) == 0 && ! NILP (only_dir_p)) + filename = build_string ("Current Directory"); + + /* Convert the values we've computed so far to system form. */ +#ifdef NTGUI_UNICODE + to_unicode (prompt, &prompt); + to_unicode (dir, &dir); + to_unicode (filename, &filename); +#else /* !NTGUI_UNICODE */ + prompt = ENCODE_FILE (prompt); + dir = ENCODE_FILE (dir); + filename = ENCODE_FILE (filename); + + /* We modify these in-place, so make copies for safety. */ + dir = Fcopy_sequence (dir); + unixtodos_filename (SDATA (dir)); + filename = Fcopy_sequence (filename); + unixtodos_filename (SDATA (filename)); +#endif /* NTGUI_UNICODE */ + + /* Fill in the structure for the call to GetOpenFileName below. For + NTGUI_UNICODE builds (which run only on NT), we just use the + actual size of the structure. For non-NTGUI_UNICODE builds, we + tell the OS we're using an old version of the structure if it's not + new enough to support the newer version. */ 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); + file_details->lStructSize = sizeof (new_file_details); else - file_details->lStructSize = sizeof (OPENFILENAME); + file_details->lStructSize = sizeof (*file_details); + + /* Set up the inout parameter for the selected file name. */ + if (SBYTES (filename) + 1 > sizeof (filename_buf)) + error ("filename too long"); + + memcpy (filename_buf, SDATA (filename), SBYTES (filename) + 1); + file_details->lpstrFile = filename_buf; + file_details->nMaxFile = sizeof (filename_buf) / sizeof (*filename_buf); 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); - - if (! NILP (only_dir_p)) - default_filter_index = 2; - - file_details->nFilterIndex = default_filter_index; - + file_details->lpstrFilter = filter; + file_details->lpstrInitialDir = (guichar_t*) SDATA (dir); + file_details->lpstrTitle = (guichar_t*) SDATA (prompt); + file_details->nFilterIndex = NILP (only_dir_p) ? 1 : 2; file_details->Flags = (OFN_HIDEREADONLY | OFN_NOCHANGEDIR - | OFN_EXPLORER | OFN_ENABLEHOOK); + | OFN_EXPLORER | OFN_ENABLEHOOK); + if (!NILP (mustmatch)) { - /* Require that the path to the parent directory exists. */ - 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; + /* Require that the path to the parent directory exists. */ + 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->lpfnHook = (LPOFNHOOKPROC) file_dialog_callback; - - file_opened = GetOpenFileName (file_details); + { + int count = SPECPDL_INDEX (); + specbind (Qinhibit_redisplay, Qt); + BLOCK_INPUT; + file_details->lpfnHook = file_dialog_callback; - UNBLOCK_INPUT; +#ifdef NTGUI_UNICODE + file_opened = GetOpenFileNameW (file_details); +#else /* !NTGUI_UNICODE */ + file_opened = GetOpenFileNameA (file_details); +#endif /* NTGUI_UNICODE */ + UNBLOCK_INPUT; + unbind_to (count, Qnil); + } if (file_opened) { - dostounix_filename (filename); - - if (file_details->nFilterIndex == 2) - { - /* "Directories" selected - strip dummy file name. */ - char * last = strrchr (filename, '/'); - *last = '\0'; - } - - file = DECODE_FILE (build_string (filename)); + /* Get an Emacs string from the value Windows gave us. */ +#ifdef NTGUI_UNICODE + filename = from_unicode ( + make_unibyte_string ( + (char*) filename_buf, + /* we get one of the two final 0 bytes for free. */ + 1 + sizeof (wchar_t) * wcslen (filename_buf))); +#else /* !NTGUI_UNICODE */ + dostounix_filename (filename_buf); + filename = DECODE_FILE (build_string (filename_buf)); +#endif /* NTGUI_UNICODE */ + +#ifdef CYGWIN + filename = Fcygwin_convert_path_from_windows (filename, Qt); +#endif /* CYGWIN */ + + /* Strip the dummy filename off the end of the string if we + added it to select a directory. */ + if (file_details->nFilterIndex == 2) + { + filename = Ffile_name_directory (filename); + } } /* User canceled 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); + filename = Fcompleting_read ( + orig_prompt, + intern ("read-file-name-internal"), + orig_dir, + mustmatch, + orig_dir, + Qfile_name_history, + default_filename, + Qnil); - file = unbind_to (count, file); + UNGCPRO; } - UNGCPRO; - /* Make "Cancel" equivalent to C-g. */ - if (NILP (file)) + if (NILP (filename)) Fsignal (Qquit, Qnil); - return unbind_to (count, file); + RETURN_UNGCPRO (filename); } - + +#ifdef WINDOWSNT /* Moving files to the system recycle bin. Used by `move-file-to-trash' instead of the default moving to ~/.Trash */ DEFUN ("system-move-file-to-trash", Fsystem_move_file_to_trash, @@ -6132,6 +6324,8 @@ DEFUN ("system-move-file-to-trash", Fsystem_move_file_to_trash, return Qnil; } +#endif /* WINDOWSNT */ + /*********************************************************************** w32 specialized functions @@ -6549,7 +6743,7 @@ The following %-sequences are provided: else { char buffer[16]; - _snprintf (buffer, 16, "%d", system_status.BatteryLifePercent); + snprintf (buffer, 16, "%d", system_status.BatteryLifePercent); load_percentage = build_string (buffer); } @@ -6560,18 +6754,18 @@ The following %-sequences are provided: 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); } @@ -6733,10 +6927,10 @@ DEFUN ("default-printer-name", Fdefault_printer_name, Sdefault_printer_name, { /* 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'; } @@ -6755,6 +6949,292 @@ DEFUN ("default-printer-name", Fdefault_printer_name, Sdefault_printer_name, return build_string (pname_buf); } + +/* 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_9X; + 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_9X) + 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)) + { +#ifdef WINDOWSNT + faked_key = vk_code; +#endif /* WINDOWSNT */ + + 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. cpID is the codepage to + use for translation to Unicode; -1 means use the current console + input codepage. */ +int +w32_kbd_patch_key (KEY_EVENT_RECORD *event, int cpId) +{ + 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 + console input codepage. */ + if (os_subtype == OS_NT) + { + WCHAR buf[128]; + + isdead = ToUnicode (event->wVirtualKeyCode, event->wVirtualScanCode, + keystate, buf, 128, 0); + if (isdead > 0) + { + /* When we are called from the GUI message processing code, + we are passed the current keyboard codepage, a positive + number, to use below. */ + if (cpId == -1) + cpId = GetConsoleCP (); + + event->uChar.UnicodeChar = buf[isdead - 1]; + 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); +} + + /*********************************************************************** Initialization ***********************************************************************/ @@ -7121,10 +7601,10 @@ only be necessary if the default setting causes problems. */); defsubr (&Sfile_system_info); defsubr (&Sdefault_printer_name); + defsubr (&Sset_message_beep); check_window_system_func = check_w32; - hourglass_timer = 0; hourglass_hwnd = NULL; @@ -7139,7 +7619,9 @@ only be necessary if the default setting causes problems. */); staticpro (&last_show_tip_args); defsubr (&Sx_file_dialog); +#ifdef WINDOWSNT defsubr (&Ssystem_move_file_to_trash); +#endif } @@ -7223,9 +7705,3 @@ w32_abort (void) } } -/* For convenience when debugging. */ -int -w32_last_error (void) -{ - return GetLastError (); -} diff --git a/src/w32font.c b/src/w32font.c index cfd453282d..c135d061e7 100644 --- a/src/w32font.c +++ b/src/w32font.c @@ -18,6 +18,7 @@ along with GNU Emacs. If not, see . */ #include #include +#include #include #include #include @@ -1436,6 +1437,9 @@ w32font_coverage_ok (FONTSIGNATURE * coverage, BYTE charset) return 1; } +#ifndef WINDOWSNT +#define _strlwr strlwr +#endif /* !WINDOWSNT */ static int check_face_name (LOGFONT *font, char *full_name) diff --git a/src/w32heap.c b/src/w32heap.c index 26cc9aa0a0..f075340479 100644 --- a/src/w32heap.c +++ b/src/w32heap.c @@ -33,10 +33,9 @@ along with GNU Emacs. If not, see . */ SYSTEM_INFO sysinfo_cache; /* This gives us version, build, and platform identification. */ +extern unsigned long syspage_mask; OSVERSIONINFO osinfo_cache; -unsigned long syspage_mask = 0; - /* The major and minor versions of NT. */ int w32_major_version; int w32_minor_version; @@ -45,44 +44,6 @@ 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_9X; - 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_9X) - w32_build_number &= 0xffff; -} - /* Emulate getpagesize. */ int getpagesize (void) diff --git a/src/w32inevt.c b/src/w32inevt.c index 731dd6715d..ca97fed1fe 100644 --- a/src/w32inevt.c +++ b/src/w32inevt.c @@ -71,6 +71,9 @@ w32_read_console_input (HANDLE h, INPUT_RECORD *rec, DWORD recsize, : ReadConsoleInputA (h, rec, recsize, waiting)); } +/* Set by w32_console_toggle_lock_key. */ +int faked_key; + static int fill_queue (BOOL block) { @@ -111,67 +114,7 @@ get_frame (void) /* 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. */ @@ -188,90 +131,7 @@ is_dead_key (int wparam) /* The return code indicates key code size. cpID is the codepage to use for translation to Unicode; -1 means use the current console input codepage. */ -int -w32_kbd_patch_key (KEY_EVENT_RECORD *event, int cpId) -{ - 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 - console input codepage. */ - if (os_subtype == OS_NT) - { - WCHAR buf[128]; - - isdead = ToUnicode (event->wVirtualKeyCode, event->wVirtualScanCode, - keystate, buf, 128, 0); - if (isdead > 0) - { - /* When we are called from the GUI message processing code, - we are passed the current keyboard codepage, a positive - number, to use below. */ - if (cpId == -1) - cpId = GetConsoleCP (); - - event->uChar.UnicodeChar = buf[isdead - 1]; - 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) */ @@ -532,32 +392,6 @@ key_event (KEY_EVENT_RECORD *event, struct input_event *emacs_ev, int *isdead) 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, diff --git a/src/w32menu.c b/src/w32menu.c index 3aa4c8bc96..886fd55bbe 100644 --- a/src/w32menu.c +++ b/src/w32menu.c @@ -21,7 +21,6 @@ along with GNU Emacs. If not, see . */ #include #include -#include #include #include "lisp.h" @@ -41,6 +40,14 @@ along with GNU Emacs. If not, see . */ if this is not done before the other system files. */ #include "w32term.h" +/* Cygwin does not support the multibyte string functions declared in + * mbstring.h below --- but that's okay: because Cygwin is + * UNICODE-only, we don't need to use these functions anyway. */ + +#ifndef NTGUI_UNICODE +#include +#endif /* !NTGUI_UNICODE */ + /* Load sys/types.h if not already loaded. In some systems loading it twice is suicidal. */ #ifndef makedev @@ -79,10 +86,17 @@ typedef int (WINAPI * MessageBoxW_Proc) ( IN WCHAR *caption, IN UINT type); +#ifdef NTGUI_UNICODE +#define get_menu_item_info GetMenuItemInfoA +#define set_menu_item_info SetMenuItemInfoA +#define unicode_append_menu AppendMenuW +#define unicode_message_box MessageBoxW +#else /* !NTGUI_UNICODE */ GetMenuItemInfoA_Proc get_menu_item_info = NULL; SetMenuItemInfoA_Proc set_menu_item_info = NULL; AppendMenuW_Proc unicode_append_menu = NULL; MessageBoxW_Proc unicode_message_box = NULL; +#endif /* NTGUI_UNICODE */ Lisp_Object Qdebug_on_next_call; @@ -99,6 +113,7 @@ static void utf8to16 (unsigned char *, int, WCHAR *); static int fill_in_menu (HMENU, widget_value *); void w32_free_menu_strings (HWND); + /* This is set nonzero after the user activates the menu bar, and set @@ -1406,6 +1421,7 @@ add_menu_item (HMENU menu, widget_value *wv, HMENU item) nlen++; } } +#ifndef NTGUI_UNICODE else { /* If encoded with the system codepage, use multibyte string @@ -1416,6 +1432,7 @@ add_menu_item (HMENU menu, widget_value *wv, HMENU item) nlen++; } } +#endif /* !NTGUI_UNICODE */ if (nlen > orig_len) { @@ -1430,6 +1447,7 @@ add_menu_item (HMENU menu, widget_value *wv, HMENU item) *q++ = *p; *q++ = *p++; } +#ifndef NTGUI_UNICODE else { if (_mbsnextc (p) == '&') @@ -1441,6 +1459,7 @@ add_menu_item (HMENU menu, widget_value *wv, HMENU item) p = _mbsinc (p); q = _mbsinc (q); } +#endif /* !NTGUI_UNICODE */ } *q = '\0'; } @@ -1487,6 +1506,8 @@ add_menu_item (HMENU menu, widget_value *wv, HMENU item) item != NULL ? (UINT) item : (UINT) wv->call_data, utf16_string); + +#ifndef NTGUI_UNICODE /* Fallback does not apply when always UNICODE */ if (!return_value) { /* On W9x/ME, Unicode menus are not supported, though AppendMenuW @@ -1505,6 +1526,7 @@ add_menu_item (HMENU menu, widget_value *wv, HMENU item) if (osinfo_cache.dwPlatformId != VER_PLATFORM_WIN32_NT) unicode_append_menu = NULL; } +#endif /* NTGUI_UNICODE */ if (unicode_append_menu && (fuFlags & MF_OWNERDRAW)) local_free (out_string); @@ -1724,10 +1746,12 @@ syms_of_w32menu (void) void globals_of_w32menu (void) { +#ifndef NTGUI_UNICODE /* See if Get/SetMenuItemInfo functions are available. */ HMODULE user32 = GetModuleHandle ("user32.dll"); get_menu_item_info = (GetMenuItemInfoA_Proc) GetProcAddress (user32, "GetMenuItemInfoA"); set_menu_item_info = (SetMenuItemInfoA_Proc) GetProcAddress (user32, "SetMenuItemInfoA"); unicode_append_menu = (AppendMenuW_Proc) GetProcAddress (user32, "AppendMenuW"); unicode_message_box = (MessageBoxW_Proc) GetProcAddress (user32, "MessageBoxW"); +#endif /* !NTGUI_UNICODE */ } diff --git a/src/w32proc.c b/src/w32proc.c index 33aed5eb8e..0cc62aebca 100644 --- a/src/w32proc.c +++ b/src/w32proc.c @@ -68,20 +68,6 @@ extern BOOL WINAPI IsValidLocale (LCID, DWORD); 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. */ diff --git a/src/w32select.c b/src/w32select.c index 59ff440536..6b855b43a3 100644 --- a/src/w32select.c +++ b/src/w32select.c @@ -82,6 +82,11 @@ along with GNU Emacs. If not, see . */ #include "coding.h" #include "composite.h" +#ifdef CYGWIN +#include +#include +#define _memccpy memccpy +#endif static HGLOBAL convert_to_handle_as_ascii (void); static HGLOBAL convert_to_handle_as_coded (Lisp_Object coding_system); diff --git a/src/w32term.c b/src/w32term.c index 6948a98998..0dffcd0bf0 100644 --- a/src/w32term.c +++ b/src/w32term.c @@ -52,7 +52,14 @@ along with GNU Emacs. If not, see . */ #include "atimer.h" #include "keymap.h" +#ifdef WINDOWSNT #include "w32heap.h" +#endif + +#ifndef WINDOWSNT +#include /* for get_osfhandle */ +#endif + #include #include "font.h" @@ -103,7 +110,7 @@ struct w32_display_info *x_display_list; Lisp_Object w32_display_name_list; -#ifndef GLYPHSET +#if !defined (GLYPHSET) && _WIN32_WINNT < 0x500 /* Pre Windows 2000, this was not available, but define it here so that Emacs compiled on such a platform will run on newer versions. */ @@ -122,7 +129,7 @@ typedef struct tagGLYPHSET WCRANGE ranges[1]; } GLYPHSET; -#endif +#endif /* compiling for pre-Win2k */ /* Dynamic linking to SetLayeredWindowAttribute (only since 2000). */ BOOL (WINAPI *pfnSetLayeredWindowAttributes) (HWND, COLORREF, BYTE, DWORD); @@ -191,6 +198,13 @@ static int volatile input_signal_count; static int input_signal_count; #endif +#ifdef CYGWIN +int w32_message_fd = -1; +#endif /* CYGWIN */ + +/* Keyboard code page - may be changed by language-change events. */ +static int keyboard_codepage; + static void x_update_window_end (struct window *, int, int); static void w32_handle_tool_bar_click (struct frame *, struct input_event *); @@ -4158,6 +4172,7 @@ w32_read_socket (struct terminal *terminal, int expected, struct frame *f; struct w32_display_info *dpyinfo = &one_w32_display_info; Mouse_HLInfo *hlinfo = &dpyinfo->mouse_highlight; + static char buf[1]; if (interrupt_input_blocked) { @@ -4171,12 +4186,19 @@ w32_read_socket (struct terminal *terminal, int expected, /* So people can tell when we have read the available input. */ input_signal_count++; + /* Process any incoming thread messages. */ + drain_message_queue (); + /* TODO: ghostscript integration. */ while (get_next_msg (&msg, FALSE)) { 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; @@ -6309,8 +6331,15 @@ w32_term_init (Lisp_Object display_name, char *xrm_option, char *resource_name) 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. */ add_keyboard_wait_descriptor (0); +#elif CYGWIN + /* /dev/windows wakes us up when we have a thread message pending. */ + add_keyboard_wait_descriptor (w32_message_fd); +#endif /* Create Fringe Bitmaps and store them for later use. @@ -6321,15 +6350,6 @@ w32_term_init (Lisp_Object display_name, char *xrm_option, char *resource_name) 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; @@ -6379,6 +6399,7 @@ x_delete_display (struct w32_display_info *dpyinfo) w32_reset_fringes (); } + /* Set up use of W32. */ @@ -6416,6 +6437,11 @@ w32_initialize (void) set_user_model (L"GNU.Emacs"); } +#ifdef CYGWIN + if ((w32_message_fd = open ("/dev/windows", O_RDWR | O_CLOEXEC)) == -1) + fatal ("opening /dev/windows: %s", strerror (errno)); +#endif /* CYGWIN */ + /* Initialize w32_use_visible_system_caret based on whether a screen reader is in use. */ if (!SystemParametersInfo (SPI_GETSCREENREADER, 0, @@ -6576,4 +6602,6 @@ With MS Windows or Nextstep, the value is t. */); staticpro (&last_mouse_motion_frame); last_mouse_motion_frame = Qnil; + + Fprovide (intern_c_string ("w32"), Qnil); } diff --git a/src/w32term.h b/src/w32term.h index 5d756f435e..434eb92fde 100644 --- a/src/w32term.h +++ b/src/w32term.h @@ -19,6 +19,8 @@ along with GNU Emacs. If not, see . */ /* Added by Kevin Gallo */ #include "w32gui.h" +#include "frame.h" +#include "atimer.h" #define BLACK_PIX_DEFAULT(f) PALETTERGB(0,0,0) @@ -195,11 +197,47 @@ Lisp_Object display_x_get_resource (struct w32_display_info *, 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, 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, int cpId); +extern int w32_kbd_mods_to_emacs (DWORD mods, WORD key); + #define PIX_TYPE COLORREF @@ -573,8 +611,9 @@ do { \ #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_BRINGTOTOP (WM_EMACS_START + 21) -#define WM_EMACS_END (WM_EMACS_START + 22) +#define WM_EMACS_BRINGTOTOP (WM_EMACS_START + 22) +#define WM_EMACS_INPUT_READY (WM_EMACS_START + 23) +#define WM_EMACS_END (WM_EMACS_START + 24) #define WND_FONTWIDTH_INDEX (0) #define WND_LINEHEIGHT_INDEX (4) @@ -596,6 +635,8 @@ typedef struct W32Msg { 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. */ @@ -699,3 +740,19 @@ extern HWND w32_system_caret_hwnd; 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 */ + +extern void syms_of_w32term (void); +extern void syms_of_w32menu (void); +extern void syms_of_w32fns (void); + +extern void globals_of_w32menu (void); +extern void globals_of_w32fns (void); + +#ifdef CYGWIN +extern int w32_message_fd; +#endif /* CYGWIN */ diff --git a/src/w32xfns.c b/src/w32xfns.c index 62e45dd987..dfafb0ac74 100644 --- a/src/w32xfns.c +++ b/src/w32xfns.c @@ -20,6 +20,7 @@ along with GNU Emacs. If not, see . */ #include #include #include + #include "lisp.h" #include "keyboard.h" #include "frame.h" @@ -33,7 +34,11 @@ along with GNU Emacs. If not, see . */ #define myfree(lp) GlobalFreePtr (lp) CRITICAL_SECTION critsect; + +#ifdef WINDOWSNT extern HANDLE keyboard_handle; +#endif /* WINDOWSNT */ + HANDLE input_available = NULL; HANDLE interrupt_handle = NULL; @@ -44,7 +49,11 @@ init_crit (void) /* 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); + +#ifdef WINDOWSNT + keyboard_handle = input_available; +#endif /* WINDOWSNT */ /* 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 +250,22 @@ get_next_msg (W32Msg * lpmsg, BOOL bWait) return (bRet); } +extern char * w32_strerror (int error_no); + +/* Tell the main thread that we have input available; if the main + thread is blocked in select(), we wake it up here. */ +static void +notify_msg_ready (void) +{ + SetEvent (input_available); + +#ifdef CYGWIN + /* Wakes up the main thread, which is blocked select()ing for /dev/windows, + among other files. */ + (void) PostThreadMessage (dwMainThreadId, WM_EMACS_INPUT_READY, 0, 0); +#endif /* CYGWIN */ +} + BOOL post_msg (W32Msg * lpmsg) { @@ -264,8 +289,7 @@ post_msg (W32Msg * lpmsg) } lpTail = lpNew; - SetEvent (input_available); - + notify_msg_ready (); leave_crit (); return (TRUE); @@ -286,7 +310,7 @@ prepend_msg (W32Msg *lpmsg) nQueue++; lpNew->lpNext = lpHead; lpHead = lpNew; - + notify_msg_ready (); leave_crit (); return (TRUE); diff --git a/src/window.c b/src/window.c index 38124cb13a..117e86065e 100644 --- a/src/window.c +++ b/src/window.c @@ -44,7 +44,7 @@ along with GNU Emacs. If not, see . */ #ifdef HAVE_X_WINDOWS #include "xterm.h" #endif /* HAVE_X_WINDOWS */ -#ifdef WINDOWSNT +#ifdef HAVE_NTGUI #include "w32term.h" #endif #ifdef MSDOS diff --git a/src/xdisp.c b/src/xdisp.c index 13b03736bd..9b9b91a890 100644 --- a/src/xdisp.c +++ b/src/xdisp.c @@ -302,7 +302,7 @@ along with GNU Emacs. If not, see . */ #ifdef HAVE_X_WINDOWS #include "xterm.h" #endif -#ifdef WINDOWSNT +#ifdef HAVE_NTGUI #include "w32term.h" #endif #ifdef HAVE_NS @@ -29361,7 +29361,7 @@ init_xdisp (void) /* 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. */ @@ -29407,4 +29407,4 @@ cancel_hourglass (void) hide_hourglass (); #endif } -#endif /* ! WINDOWSNT */ +#endif /* ! HAVE_NTGUI */ diff --git a/src/xfaces.c b/src/xfaces.c index 5554c4aa70..67e9c2c37c 100644 --- a/src/xfaces.c +++ b/src/xfaces.c @@ -228,13 +228,13 @@ along with GNU Emacs. If not, see . */ #ifdef HAVE_WINDOW_SYSTEM #include TERM_HEADER #include "fontset.h" -#ifdef WINDOWSNT +#ifdef HAVE_NTGUI #undef FRAME_X_DISPLAY_INFO #define FRAME_X_DISPLAY_INFO FRAME_W32_DISPLAY_INFO #define x_display_info w32_display_info #define check_x check_w32 #define GCGraphicsExposures 0 -#endif /* WINDOWSNT */ +#endif /* HAVE_NTGUI */ #ifdef HAVE_NS #undef FRAME_X_DISPLAY_INFO @@ -663,7 +663,7 @@ x_free_gc (struct frame *f, GC gc) #endif /* HAVE_X_WINDOWS */ -#ifdef WINDOWSNT +#ifdef HAVE_NTGUI /* W32 emulation of GCs */ static inline GC @@ -687,7 +687,7 @@ x_free_gc (struct frame *f, GC gc) xfree (gc); } -#endif /* WINDOWSNT */ +#endif /* HAVE_NTGUI */ #ifdef HAVE_NS /* NS emulation of GCs */ @@ -757,7 +757,7 @@ init_frame_faces (struct frame *f) #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 @@ -1136,7 +1136,7 @@ defined_color (struct frame *f, const char *color_name, XColor *color_def, 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 @@ -3283,7 +3283,7 @@ FRAME 0 means change the face on all frames, and change the default 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 @@ -3293,7 +3293,7 @@ FRAME 0 means change the face on all frames, and change the default 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 @@ -6400,7 +6400,7 @@ where R,G,B are numbers between 0 and 255 and name is an arbitrary string. */) 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)), diff --git a/src/xterm.h b/src/xterm.h index 2d718f4911..8b8ae2a12f 100644 --- a/src/xterm.h +++ b/src/xterm.h @@ -967,7 +967,6 @@ extern int x_alloc_lighter_color_for_widget (Widget, Display *, Colormap, double, int); #endif extern int x_alloc_nearest_color (struct frame *, Colormap, XColor *); -extern void x_query_color (struct frame *f, XColor *); extern void x_clear_area (Display *, Window, int, int, int, int, int); #if defined HAVE_MENUS && !defined USE_X_TOOLKIT && !defined USE_GTK extern void x_mouse_leave (struct x_display_info *); -- 2.20.1