aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorDaniel Colascione2012-10-08 00:23:13 -0800
committerDaniel Colascione2012-10-08 00:23:13 -0800
commit7148eba270e9c521cf6423fdc94b8c86ff604964 (patch)
tree2c78c4581a0377e50f3d722d119823c77172067b /src
parent97fbed87597d0b1b93159095170fb296b307d6b0 (diff)
parenta28a3ae36276ad96cd41c1843d9ae0881390c840 (diff)
downloademacs-7148eba270e9c521cf6423fdc94b8c86ff604964.tar.gz
emacs-7148eba270e9c521cf6423fdc94b8c86ff604964.zip
Merge cygw32
Diffstat (limited to 'src')
-rw-r--r--src/ChangeLog138
-rw-r--r--src/Makefile.in30
-rw-r--r--src/conf_post.h14
-rw-r--r--src/cygw32.c169
-rw-r--r--src/cygw32.h59
-rw-r--r--src/dispextern.h4
-rw-r--r--src/emacs.c66
-rw-r--r--src/font.c4
-rw-r--r--src/font.h5
-rw-r--r--src/fontset.c2
-rw-r--r--src/frame.c4
-rw-r--r--src/frame.h5
-rw-r--r--src/image.c76
-rw-r--r--src/keyboard.c12
-rw-r--r--src/keyboard.h2
-rw-r--r--src/menu.c4
-rw-r--r--src/process.c1
-rw-r--r--src/termhooks.h6
-rw-r--r--src/unexw32.c2
-rw-r--r--src/w32.c19
-rw-r--r--src/w32.h17
-rw-r--r--src/w32console.c49
-rw-r--r--src/w32fns.c751
-rw-r--r--src/w32font.c4
-rw-r--r--src/w32heap.c41
-rw-r--r--src/w32inevt.c172
-rw-r--r--src/w32menu.c27
-rw-r--r--src/w32proc.c14
-rw-r--r--src/w32select.c5
-rw-r--r--src/w32select.h30
-rw-r--r--src/w32term.c50
-rw-r--r--src/w32term.h61
-rw-r--r--src/w32xfns.c32
-rw-r--r--src/window.c2
-rw-r--r--src/xdisp.c2
-rw-r--r--src/xfaces.c18
36 files changed, 1361 insertions, 536 deletions
diff --git a/src/ChangeLog b/src/ChangeLog
index 29e831a2eb8..2a312199512 100644
--- a/src/ChangeLog
+++ b/src/ChangeLog
@@ -1,3 +1,141 @@
12012-10-08 Daniel Colascione <dancol@dancol.org>
2
3 * xfaces.c, xdisp.c, window.c, w32xfns.c, w32term.h, w32term.c,
4 w32select.h w32select.c, w32proc.c, w32menu.c, w32inevt.c,
5 w32help.c, w32font.c, w32font.c, w32fns.c, w32console.c, w32.h,
6 w32.c, unexw32.c, termhooks.h, process.c, menu.c, keyboard.h,
7 keyboard.c, image.c, frame.h, frame.c, fontset.c, font.h, font.c,
8 emacs.c, dispextern.h, cygw32.h, cygw32.c, conf_post.h,
9 Makefile.in: use HAVE_NTGUI for W32 GUI and WINDOWSNT for the
10 operating system. defined(HAVE_NTGUI) && !defined(WINDOWSNT) is
11 now a supported configuration.
12
13 * Makefile.in: consolidate image variables into LIBIMAGE; add
14 W32_OBJ and W32_LIBS. Compile new files.
15
16 * conf_post.h:
17 (_DebPrint) declare tracing facility for W32 debugging. We need
18 to unify tracing later.
19
20 (NTGUI_UNICODE) Define when compiling for Cygwin to allow the
21 unconditional use of W32 Unicode functions. Cygwin runs only on
22 100% Unicode operating systems.
23
24 * cygw32.c: New file. Define Cygwin-specific facilities.
25 (Fcygwin_convert_path_to_windows)
26 (Fcygwin_convert_path_from_windows): New user functions for
27 accessing Cygwin path-munging routines.
28
29 * cygw32.h: New file.
30 (WCSDATA, to_unicode, from_unicode): Define facilities for storing
31 UTF-16LE strings temporarily inside non-Lisp-visible string
32 objects.
33
34 (w32_strerror): Just what it says on the tin.
35
36 * emacs.c: Make the NS fork-then-exec code for daemon-launching
37 also run for Cygwin; both systems have the same problem with using
38 GUI facilities in a forked child. Also call syms_of_cygw32,
39 syms_of_w32select in correct places.
40
41 (DAEMON_MUST_EXEC): new macro defined to signal that a platform
42 needs fork-then-exec for daemon launching.
43
44 * font.h: Include frame.h.
45
46 * image.c: Use the image library cache machinery only when we're
47 compiling for native WINDOWSNT; Cygwin can use shared libraries
48 like any other Unixlike system.
49
50 * keyboard.c: Clarify a comment regarding the input loop.
51
52 * menu.c: When NTGUI_UNICODE is defined, use Unicode menu
53 functions directly instead of trying to detect at runtime that our
54 host operating system supports them. We make this change for two
55 reasons: Cygwin lacks support for the multibyte character
56 conversion functions used by the legacy menu code, and Cygwin
57 never needs to rely on non-Unicode APIs.
58
59 * unexw32.c (hinst): Declare extern.
60
61 * w32.c: Change header order;
62 (w32_strerror): Move to w32fns.c because we need it for
63 non-WINDOWSNT builds.
64
65 * w32.h: Add #error macro to make sure we don't include w32.h for
66 Cygwin builds. Remove w32select declarations.
67
68 * w32console.c (w32_sys_ring_bell, Fset_message_beep): Move to
69 w32fns.c. w32console.c is WINDOWSNT-only.
70
71 * w32fns.c: Include cygw32.h or w32.h depending on CYGWIN; more
72 NTGUI_UNICODE tweaks. (See above.) Change _snprintf to the more
73 POSIXy alternative.
74 (faked_key, sysinfo_cache, osinfo_cahce, syspage_mask)
75 (w32_major_version, w32_minor_version, w32_build_number)
76 (os_subtype, sound_type): Define here
77 (w32_defined_color): Make color parameter const for consistency
78 with other _defined_color functions.
79 (w32_createwindow): Unconditionally call w32_init_class instead of
80 doing so only when hprevinst is non-NULL. Plumbing hprevinst
81 through the code is complex and unnecessary because class
82 registration is practically free.
83 (w32_name_of_message): New EMACSDEBUG-only function.
84 (Fset_message_beep): Move here
85 (Fx_open_connection): Require that the display name for Windows be
86 "w32" for consistency, emacsclient disambiguation, and maybe, one
87 day, multi-window-system support.
88 (file_dialog_callback): NTGUI_UNICODE changes; encode and decode
89 Cygwin files for W32 GUI facilities, since these clearly don't
90 expect Cygwin names.
91 (_DebPrint): Define.
92 (w32_strerror, w32_console_toggle_lock_key, w32_kbd_mods_to_emacs)
93 (w32_kbd_patch_key, w32_sys_ring_bell): Move here.
94 (Ssystem_move_file_to_trash): Define only for native WINDOWSNT.
95 (w32_last_error): Remove.
96
97 * w32font.c: Define _strlwr to strlwr for non-WINDOWSNT builds.
98
99 * w32heap.c (syspage_mask): Declare here.
100 (cache_system_info): Remove.
101
102 * w32inevt.c (faked_key): Define globally, not statically.
103 (w32_kbd_mods_to_emacs, w32_kbd_patch_key, faked_key)
104 (w32_console_toggle_lock_key): Move to w32fns.c.
105
106 * w32menu.c: Include setjmp.h. NTGUI_UNICODE changes throughout.
107
108 * w32proc.c (_DebPrint): Move to w32fns.c.
109 * w32select.c: Include string.h, stdio.h for Cygwin.
110 * w32select.h: New File.
111
112 * w32term.c: Include io.h for non-CYGWIN builds; needed for
113 get_osfhandle.
114 (w32_message_fd): New variable. Under Cygwin, holds the file
115 descriptor the system used to tell us about pending thread
116 messages.
117
118 (w32_init_term): Remove incorrect calls to fcntl and init_sigio
119 that prevented compilation under non-WINDOWSNT systems.
120
121 (w32_initialize): Open /dev/windows and assign it to
122 w32_message_fd. Provide w32 feature.
123
124 * w32term.h: Include frame.h, atimer.h. Declare various frame functions.
125 (WM_EMACS_INPUT_READY): add.
126 (prepend_msg, w32_message_fd): Declare globally.
127
128 * w32xfns.c:
129 (keyboard_handle): Use only when WINDOWSNT.
130 (notify_msg_ready): New function. Posts a message to the main
131 thread's message queue under CYGWIN, which wakes up the main
132 thread from select(2) by making the /dev/windows file descriptor
133 ready. Under WINDOWSNT, it sets an event the same way the old
134 code did.
135
136 (post, prepend_msg): Actually call notify_msg_ready instead of
137 setting the input event directly.
138
12012-10-07 Eli Zaretskii <eliz@gnu.org> 1392012-10-07 Eli Zaretskii <eliz@gnu.org>
2 140
3 * ralloc.c (relinquish): If a heap is ready to be relinquished, 141 * ralloc.c (relinquish): If a heap is ready to be relinquished,
diff --git a/src/Makefile.in b/src/Makefile.in
index f8da0091711..e704f2f5c0c 100644
--- a/src/Makefile.in
+++ b/src/Makefile.in
@@ -135,13 +135,10 @@ LIB_MATH=@LIB_MATH@
135## -lpthreads, or empty. 135## -lpthreads, or empty.
136LIB_PTHREAD=@LIB_PTHREAD@ 136LIB_PTHREAD=@LIB_PTHREAD@
137 137
138LIBTIFF=@LIBTIFF@ 138LIBIMAGE=@LIBTIFF@ @LIBJPEG@ @LIBPNG@ @LIBGIF@ @LIBXPM@
139LIBJPEG=@LIBJPEG@ 139
140LIBPNG=@LIBPNG@
141LIBGIF=@LIBGIF@
142LIBXPM=@LIBXPM@
143XFT_LIBS=@XFT_LIBS@ 140XFT_LIBS=@XFT_LIBS@
144LIBX_EXTRA=$(LIBTIFF) $(LIBJPEG) $(LIBPNG) $(LIBGIF) $(LIBXPM) -lX11 $(XFT_LIBS) 141LIBX_EXTRA=-lX11 $(XFT_LIBS)
145 142
146FONTCONFIG_CFLAGS = @FONTCONFIG_CFLAGS@ 143FONTCONFIG_CFLAGS = @FONTCONFIG_CFLAGS@
147FONTCONFIG_LIBS = @FONTCONFIG_LIBS@ 144FONTCONFIG_LIBS = @FONTCONFIG_LIBS@
@@ -261,6 +258,13 @@ NS_OBJ=@NS_OBJ@
261NS_OBJC_OBJ=@NS_OBJC_OBJ@ 258NS_OBJC_OBJ=@NS_OBJC_OBJ@
262## Only set if NS_IMPL_GNUSTEP. 259## Only set if NS_IMPL_GNUSTEP.
263GNU_OBJC_CFLAGS=@GNU_OBJC_CFLAGS@ 260GNU_OBJC_CFLAGS=@GNU_OBJC_CFLAGS@
261## w32fns.o w32menu.c w32reg.o fringe.o fontset.o w32font.o w32term.o
262## w32xfns.o w32select.o image.o w32uniscribe.o if HAVE_W32, else
263## empty.
264W32_OBJ=@W32_OBJ@
265## -lkernel32 -luser32 -lgdi32 -lole32 -lcomdlg32 lusp10 -lcomctl32
266## --lwinspool if HAVE_W32, else empty.
267W32_LIBS=@W32_LIBS@
264 268
265## Empty if !HAVE_X_WINDOWS 269## Empty if !HAVE_X_WINDOWS
266## xfont.o ftfont.o xftfont.o ftxfont.o if HAVE_XFT 270## xfont.o ftfont.o xftfont.o ftxfont.o if HAVE_XFT
@@ -342,7 +346,7 @@ base_obj = dispnew.o frame.o scroll.o xdisp.o menu.o $(XMENU_OBJ) window.o \
342 doprnt.o intervals.o textprop.o composite.o xml.o \ 346 doprnt.o intervals.o textprop.o composite.o xml.o \
343 profiler.o \ 347 profiler.o \
344 $(MSDOS_OBJ) $(MSDOS_X_OBJ) $(NS_OBJ) $(CYGWIN_OBJ) $(FONT_OBJ) \ 348 $(MSDOS_OBJ) $(MSDOS_X_OBJ) $(NS_OBJ) $(CYGWIN_OBJ) $(FONT_OBJ) \
345 $(WINDOW_SYSTEM_OBJ) 349 $(W32_OBJ) $(WINDOW_SYSTEM_OBJ)
346obj = $(base_obj) $(NS_OBJC_OBJ) 350obj = $(base_obj) $(NS_OBJC_OBJ)
347 351
348## Object files used on some machine or other. 352## Object files used on some machine or other.
@@ -351,9 +355,9 @@ obj = $(base_obj) $(NS_OBJC_OBJ)
351## in the list, in case they ever add any such entries. 355## in the list, in case they ever add any such entries.
352SOME_MACHINE_OBJECTS = dosfns.o msdos.o \ 356SOME_MACHINE_OBJECTS = dosfns.o msdos.o \
353 xterm.o xfns.o xmenu.o xselect.o xrdb.o xsmfns.o fringe.o image.o \ 357 xterm.o xfns.o xmenu.o xselect.o xrdb.o xsmfns.o fringe.o image.o \
354 fontset.o dbusbind.o \ 358 fontset.o dbusbind.o cygw32.o \
355 nsterm.o nsfns.o nsmenu.o nsselect.o nsimage.o nsfont.o \ 359 nsterm.o nsfns.o nsmenu.o nsselect.o nsimage.o nsfont.o \
356 w32.o w32console.o w32fns.o w32heap.o w32inevt.o \ 360 w32.o w32console.o w32fns.o w32heap.o \
357 w32menu.o w32proc.o w32reg.o w32select.o w32term.o w32xfns.o \ 361 w32menu.o w32proc.o w32reg.o w32select.o w32term.o w32xfns.o \
358 w16select.o widget.o xfont.o ftfont.o xftfont.o ftxfont.o gtkutil.o \ 362 w16select.o widget.o xfont.o ftfont.o xftfont.o ftxfont.o gtkutil.o \
359 xsettings.o xgselect.o termcap.o 363 xsettings.o xgselect.o termcap.o
@@ -385,9 +389,11 @@ otherobj= $(TERMCAP_OBJ) $(PRE_ALLOC_OBJ) $(GMALLOC_OBJ) $(RALLOC_OBJ) \
385## Note that SunOS needs -lm to come before -lc; otherwise, you get 389## Note that SunOS needs -lm to come before -lc; otherwise, you get
386## duplicated symbols. If the standard libraries were compiled 390## duplicated symbols. If the standard libraries were compiled
387## with GCC, we might need LIB_GCC again after them. 391## with GCC, we might need LIB_GCC again after them.
388LIBES = $(LIBS) $(LIBX_BASE) $(LIBX_OTHER) $(LIBSOUND) \ 392LIBES = $(LIBS) $(W32_LIBS) $(LIBX_BASE) $(LIBIMAGE) \
389 $(RSVG_LIBS) $(IMAGEMAGICK_LIBS) $(LIB_CLOCK_GETTIME) $(LIB_TIMER_TIME) \ 393 $(LIBX_OTHER) $(LIBSOUND) \
390 $(DBUS_LIBS) $(LIB_EXECINFO) \ 394 $(RSVG_LIBS) $(IMAGEMAGICK_LIBS) $(LIB_CLOCK_GETTIME) \
395 $(LIB_TIMER_TIME) $(DBUS_LIBS) \
396 $(LIB_EXECINFO) \
391 $(LIBXML2_LIBS) $(LIBGPM) $(LIBRESOLV) $(LIBS_SYSTEM) \ 397 $(LIBXML2_LIBS) $(LIBGPM) $(LIBRESOLV) $(LIBS_SYSTEM) \
392 $(LIBS_TERMCAP) $(GETLOADAVG_LIBS) $(SETTINGS_LIBS) $(LIBSELINUX_LIBS) \ 398 $(LIBS_TERMCAP) $(GETLOADAVG_LIBS) $(SETTINGS_LIBS) $(LIBSELINUX_LIBS) \
393 $(FREETYPE_LIBS) $(FONTCONFIG_LIBS) $(LIBOTF_LIBS) $(M17N_FLT_LIBS) \ 399 $(FREETYPE_LIBS) $(FONTCONFIG_LIBS) $(LIBOTF_LIBS) $(M17N_FLT_LIBS) \
diff --git a/src/conf_post.h b/src/conf_post.h
index 0c4d029bc5d..53fc941f464 100644
--- a/src/conf_post.h
+++ b/src/conf_post.h
@@ -142,6 +142,20 @@ You lose; /* Emacs for DOS must be compiled with DJGPP */
142#endif 142#endif
143#endif 143#endif
144 144
145#if defined(HAVE_NTGUI) && !defined(DebPrint)
146# if defined(EMACSDEBUG)
147extern void _DebPrint (const char *fmt, ...);
148# define DebPrint(stuff) _DebPrint stuff
149# else
150# define DebPrint(stuff)
151# endif /* EMACSDEBUG */
152#endif /* DebPrint */
153
154#if defined(CYGWIN) && defined(HAVE_NTGUI)
155#define NTGUI_UNICODE /* Cygwin runs only on UNICODE-supporting systems */
156#define _WIN32_WINNT 0x500 /* Win2k */
157#endif /* CYGWIN && HAVE_NTGUI */
158
145#ifdef emacs /* Don't do this for lib-src. */ 159#ifdef emacs /* Don't do this for lib-src. */
146/* Tell regex.c to use a type compatible with Emacs. */ 160/* Tell regex.c to use a type compatible with Emacs. */
147#define RE_TRANSLATE_TYPE Lisp_Object 161#define RE_TRANSLATE_TYPE Lisp_Object
diff --git a/src/cygw32.c b/src/cygw32.c
new file mode 100644
index 00000000000..065ab948118
--- /dev/null
+++ b/src/cygw32.c
@@ -0,0 +1,169 @@
1/* Cygwin support routines.
2 Copyright (C) 2011 Free Software Foundation, Inc.
3
4This file is part of GNU Emacs.
5
6GNU Emacs is free software: you can redistribute it and/or modify
7it under the terms of the GNU General Public License as published by
8the Free Software Foundation, either version 3 of the License, or
9(at your option) any later version.
10
11GNU Emacs is distributed in the hope that it will be useful,
12but WITHOUT ANY WARRANTY; without even the implied warranty of
13MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14GNU General Public License for more details.
15
16You should have received a copy of the GNU General Public License
17along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. */
18
19
20#include "cygw32.h"
21#include "character.h"
22#include "buffer.h"
23#include <unistd.h>
24#include <fcntl.h>
25static Lisp_Object Qutf_16_le;
26
27static Lisp_Object
28fchdir_unwind (Lisp_Object dir_fd)
29{
30 (void) fchdir (XFASTINT (dir_fd));
31 (void) close (XFASTINT (dir_fd));
32 return Qnil;
33}
34
35static void
36chdir_to_default_directory ()
37{
38 Lisp_Object new_cwd;
39 int old_cwd_fd = open (".", O_RDONLY | O_DIRECTORY);
40
41 if (old_cwd_fd == -1)
42 error ("could not open current directory: %s", strerror (errno));
43
44 record_unwind_protect (fchdir_unwind, make_number (old_cwd_fd));
45
46 new_cwd = Funhandled_file_name_directory (
47 Fexpand_file_name (build_string ("."), Qnil));
48 if (!STRINGP (new_cwd))
49 new_cwd = build_string ("/");
50
51 if (chdir (SDATA (ENCODE_FILE (new_cwd))))
52 error ("could not chdir: %s", strerror (errno));
53}
54
55static Lisp_Object
56conv_filename_to_w32_unicode (Lisp_Object in, int absolute_p)
57{
58 ssize_t converted_len;
59 Lisp_Object converted;
60 unsigned flags;
61 int count = SPECPDL_INDEX ();
62
63 chdir_to_default_directory ();
64
65 flags = CCP_POSIX_TO_WIN_W;
66 if (!absolute_p) {
67 flags |= CCP_RELATIVE;
68 }
69
70 in = ENCODE_FILE (in);
71
72 converted_len = cygwin_conv_path (flags, SDATA (in), NULL, 0);
73 if (converted_len < 2)
74 error ("cygwin_conv_path: %s", strerror (errno));
75
76 converted = make_uninit_string (converted_len - 1);
77 if (cygwin_conv_path (flags, SDATA (in),
78 SDATA (converted), converted_len))
79 error ("cygwin_conv_path: %s", strerror (errno));
80
81 return unbind_to (count, converted);
82}
83
84static Lisp_Object
85conv_filename_from_w32_unicode (const wchar_t* in, int absolute_p)
86{
87 ssize_t converted_len;
88 Lisp_Object converted;
89 unsigned flags;
90 int count = SPECPDL_INDEX ();
91
92 chdir_to_default_directory ();
93
94 flags = CCP_WIN_W_TO_POSIX;
95 if (!absolute_p) {
96 flags |= CCP_RELATIVE;
97 }
98
99 converted_len = cygwin_conv_path (flags, in, NULL, 0);
100 if (converted_len < 1)
101 error ("cygwin_conv_path: %s", strerror (errno));
102
103 converted = make_uninit_string (converted_len - 1 /*subtract terminator*/);
104 if (cygwin_conv_path (flags, in, SDATA (converted), converted_len))
105 error ("cygwin_conv_path: %s", strerror (errno));
106
107 return unbind_to (count, DECODE_FILE (converted));
108}
109
110Lisp_Object
111from_unicode (Lisp_Object str)
112{
113 CHECK_STRING (str);
114 if (!STRING_MULTIBYTE (str) &&
115 SBYTES (str) & 1)
116 {
117 str = Fsubstring (str, make_number (0), make_number (-1));
118 }
119
120 return code_convert_string_norecord (str, Qutf_16_le, 0);
121}
122
123wchar_t *
124to_unicode (Lisp_Object str, Lisp_Object *buf)
125{
126 *buf = code_convert_string_norecord (str, Qutf_16_le, 1);
127 /* We need to make a another copy (in addition to the one made by
128 code_convert_string_norecord) to ensure that the final string is
129 _doubly_ zero terminated --- that is, that the string is
130 terminated by two zero bytes and one utf-16le null character.
131 Because strings are already terminated with a single zero byte,
132 we just add one additional zero. */
133 str = make_uninit_string (SBYTES (*buf) + 1);
134 memcpy (SDATA (str), SDATA (*buf), SBYTES (*buf));
135 SDATA (str) [SBYTES (*buf)] = '\0';
136 *buf = str;
137 return WCSDATA (*buf);
138}
139
140DEFUN ("cygwin-convert-path-to-windows",
141 Fcygwin_convert_path_to_windows, Scygwin_convert_path_to_windows,
142 1, 2, 0,
143 doc: /* Convert PATH to a Windows path. If ABSOLUTE-P if
144 non-nil, return an absolute path.*/)
145 (Lisp_Object path, Lisp_Object absolute_p)
146{
147 return from_unicode (
148 conv_filename_to_w32_unicode (path, absolute_p == Qnil ? 0 : 1));
149}
150
151DEFUN ("cygwin-convert-path-from-windows",
152 Fcygwin_convert_path_from_windows, Scygwin_convert_path_from_windows,
153 1, 2, 0,
154 doc: /* Convert a Windows path to a Cygwin path. If ABSOLUTE-P
155 if non-nil, return an absolute path.*/)
156 (Lisp_Object path, Lisp_Object absolute_p)
157{
158 return conv_filename_from_w32_unicode (to_unicode (path, &path),
159 absolute_p == Qnil ? 0 : 1);
160}
161
162void
163syms_of_cygw32 (void)
164{
165 /* No, not utf-16-le: that one has a BOM. */
166 DEFSYM (Qutf_16_le, "utf-16le");
167 defsubr (&Scygwin_convert_path_from_windows);
168 defsubr (&Scygwin_convert_path_to_windows);
169}
diff --git a/src/cygw32.h b/src/cygw32.h
new file mode 100644
index 00000000000..c63343c3f5a
--- /dev/null
+++ b/src/cygw32.h
@@ -0,0 +1,59 @@
1/* Header for Cygwin support routines.
2 Copyright (C) 2011 Free Software Foundation, Inc.
3
4This file is part of GNU Emacs.
5
6GNU Emacs is free software: you can redistribute it and/or modify
7it under the terms of the GNU General Public License as published by
8the Free Software Foundation, either version 3 of the License, or
9(at your option) any later version.
10
11GNU Emacs is distributed in the hope that it will be useful,
12but WITHOUT ANY WARRANTY; without even the implied warranty of
13MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14GNU General Public License for more details.
15
16You should have received a copy of the GNU General Public License
17along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. */
18
19#ifndef CYGW32_H
20#define CYGW32_H
21#include <config.h>
22#include <windef.h>
23#include <sys/cygwin.h>
24#include <wchar.h>
25
26#include <signal.h>
27#include <stdio.h>
28#include <limits.h>
29#include <errno.h>
30#include <math.h>
31#include <setjmp.h>
32
33#include "lisp.h"
34#include "coding.h"
35
36/* *** Character conversion *** */
37
38/* Access the wide-character string stored in a Lisp string object. */
39#define WCSDATA(x) ((wchar_t *) SDATA (x))
40
41/* Convert the Emacs string in STR to UTF-16LE and store a new string
42 containing the encoded version of STR into *BUF. BUF may safely
43 point to STR on entry. */
44extern wchar_t *to_unicode (Lisp_Object str, Lisp_Object *buf);
45
46/* Convert STR, a UTF-16LE encoded string embedded in an Emacs string
47 object, to a normal Emacs string and return it. */
48extern Lisp_Object from_unicode (Lisp_Object str);
49
50/* *** Path conversion. *** */
51
52EXFUN (Fcygwin_convert_path_to_windows, 2);
53EXFUN (Fcygwin_convert_path_from_windows, 2);
54
55/* *** Misc *** */
56extern void syms_of_cygw32 (void);
57extern char * w32_strerror (int error_no);
58
59#endif /* CYGW32_H */
diff --git a/src/dispextern.h b/src/dispextern.h
index f1ea8e97ee8..c5ebb808b05 100644
--- a/src/dispextern.h
+++ b/src/dispextern.h
@@ -3144,7 +3144,7 @@ int draw_window_fringes (struct window *, int);
3144int update_window_fringes (struct window *, int); 3144int update_window_fringes (struct window *, int);
3145void compute_fringe_widths (struct frame *, int); 3145void compute_fringe_widths (struct frame *, int);
3146 3146
3147#ifdef WINDOWSNT 3147#ifdef HAVE_NTGUI
3148void w32_init_fringe (struct redisplay_interface *); 3148void w32_init_fringe (struct redisplay_interface *);
3149void w32_reset_fringes (void); 3149void w32_reset_fringes (void);
3150#endif 3150#endif
@@ -3247,7 +3247,7 @@ extern char unspecified_fg[], unspecified_bg[];
3247#ifdef HAVE_X_WINDOWS 3247#ifdef HAVE_X_WINDOWS
3248void gamma_correct (struct frame *, XColor *); 3248void gamma_correct (struct frame *, XColor *);
3249#endif 3249#endif
3250#ifdef WINDOWSNT 3250#ifdef HAVE_NTGUI
3251void gamma_correct (struct frame *, COLORREF *); 3251void gamma_correct (struct frame *, COLORREF *);
3252#endif 3252#endif
3253 3253
diff --git a/src/emacs.c b/src/emacs.c
index bc54f56b98a..6cc50a23d66 100644
--- a/src/emacs.c
+++ b/src/emacs.c
@@ -33,9 +33,20 @@ along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. */
33 33
34#ifdef WINDOWSNT 34#ifdef WINDOWSNT
35#include <fcntl.h> 35#include <fcntl.h>
36#include <windows.h> /* just for w32.h */
37#include "w32.h" 36#include "w32.h"
38#include "w32heap.h" /* for prototype of sbrk */ 37#endif
38
39#if defined (WINDOWSNT)
40#include "w32heap.h"
41#endif
42
43#if defined (WINDOWSNT) || defined (HAVE_NTGUI)
44#include "w32select.h"
45#include "w32font.h"
46#endif
47
48#if defined (HAVE_NTGUI) && defined (CYGWIN)
49#include "cygw32.h"
39#endif 50#endif
40 51
41#ifdef HAVE_WINDOW_SYSTEM 52#ifdef HAVE_WINDOW_SYSTEM
@@ -156,6 +167,22 @@ static void *my_heap_start;
156static uprintmax_t heap_bss_diff; 167static uprintmax_t heap_bss_diff;
157#endif 168#endif
158 169
170/* To run as a daemon under Cocoa or Windows, we must do a fork+exec,
171 not a simple fork.
172
173 On Cocoa, CoreFoundation lib fails in forked process:
174 http://developer.apple.com/ReleaseNotes/
175 CoreFoundation/CoreFoundation.html)
176
177 On Windows, a Cygwin fork child cannot access the USER subsystem.
178
179 We mark being in the exec'd process by a daemon name argument of
180 form "--daemon=\nFD0,FD1\nNAME" where FD are the pipe file descriptors,
181 NAME is the original daemon name, if any. */
182#if defined (NS_IMPL_COCOA) || defined (HAVE_NTGUI)
183# define DAEMON_MUST_EXEC
184#endif
185
159/* True means running Emacs without interactive terminal. */ 186/* True means running Emacs without interactive terminal. */
160bool noninteractive; 187bool noninteractive;
161 188
@@ -669,9 +696,9 @@ main (int argc, char **argv)
669 bool no_loadup = 0; 696 bool no_loadup = 0;
670 char *junk = 0; 697 char *junk = 0;
671 char *dname_arg = 0; 698 char *dname_arg = 0;
672#ifdef NS_IMPL_COCOA 699#ifdef DAEMON_MUST_EXEC
673 char dname_arg2[80]; 700 char dname_arg2[80];
674#endif 701#endif /* DAEMON_MUST_EXEC */
675 char *ch_to_dir; 702 char *ch_to_dir;
676 703
677#if GC_MARK_STACK 704#if GC_MARK_STACK
@@ -964,25 +991,19 @@ main (int argc, char **argv)
964 exit (1); 991 exit (1);
965 } 992 }
966 993
967#ifndef NS_IMPL_COCOA 994#ifndef DAEMON_MUST_EXEC
968#ifdef USE_GTK 995#ifdef USE_GTK
969 fprintf (stderr, "\nWarning: due to a long standing Gtk+ bug\nhttp://bugzilla.gnome.org/show_bug.cgi?id=85715\n\ 996 fprintf (stderr, "\nWarning: due to a long standing Gtk+ bug\nhttp://bugzilla.gnome.org/show_bug.cgi?id=85715\n\
970Emacs might crash when run in daemon mode and the X11 connection is unexpectedly lost.\n\ 997Emacs might crash when run in daemon mode and the X11 connection is unexpectedly lost.\n\
971Using an Emacs configured with --with-x-toolkit=lucid does not have this problem.\n"); 998Using an Emacs configured with --with-x-toolkit=lucid does not have this problem.\n");
972#endif 999#endif /* USE_GTK */
973 f = fork (); 1000 f = fork ();
974#else /* NS_IMPL_COCOA */ 1001#else /* DAEMON_MUST_EXEC */
975 /* Under Cocoa we must do fork+exec as CoreFoundation lib fails in
976 forked process: http://developer.apple.com/ReleaseNotes/
977 CoreFoundation/CoreFoundation.html)
978 We mark being in the exec'd process by a daemon name argument of
979 form "--daemon=\nFD0,FD1\nNAME" where FD are the pipe file descriptors,
980 NAME is the original daemon name, if any. */
981 if (!dname_arg || !strchr (dname_arg, '\n')) 1002 if (!dname_arg || !strchr (dname_arg, '\n'))
982 f = fork (); /* in orig */ 1003 f = fork (); /* in orig */
983 else 1004 else
984 f = 0; /* in exec'd */ 1005 f = 0; /* in exec'd */
985#endif /* NS_IMPL_COCOA */ 1006#endif /* !DAEMON_MUST_EXEC */
986 if (f > 0) 1007 if (f > 0)
987 { 1008 {
988 int retval; 1009 int retval;
@@ -1018,7 +1039,7 @@ Using an Emacs configured with --with-x-toolkit=lucid does not have this problem
1018 exit (1); 1039 exit (1);
1019 } 1040 }
1020 1041
1021#ifdef NS_IMPL_COCOA 1042#ifdef DAEMON_MUST_EXEC
1022 { 1043 {
1023 /* In orig process, forked as child, OR in exec'd. */ 1044 /* In orig process, forked as child, OR in exec'd. */
1024 if (!dname_arg || !strchr (dname_arg, '\n')) 1045 if (!dname_arg || !strchr (dname_arg, '\n'))
@@ -1054,7 +1075,7 @@ Using an Emacs configured with --with-x-toolkit=lucid does not have this problem
1054 dname_arg2); 1075 dname_arg2);
1055 dname_arg = *dname_arg2 ? dname_arg2 : NULL; 1076 dname_arg = *dname_arg2 ? dname_arg2 : NULL;
1056 } 1077 }
1057#endif /* NS_IMPL_COCOA */ 1078#endif /* DAEMON_MUST_EXEC */
1058 1079
1059 if (dname_arg) 1080 if (dname_arg)
1060 daemon_name = xstrdup (dname_arg); 1081 daemon_name = xstrdup (dname_arg);
@@ -1357,6 +1378,9 @@ Using an Emacs configured with --with-x-toolkit=lucid does not have this problem
1357#ifdef WINDOWSNT 1378#ifdef WINDOWSNT
1358 syms_of_ntproc (); 1379 syms_of_ntproc ();
1359#endif /* WINDOWSNT */ 1380#endif /* WINDOWSNT */
1381#if defined (CYGWIN) && defined (HAVE_NTGUI)
1382 syms_of_cygw32 ();
1383#endif /* defined(CYGWIN) && defined (HAVE_NTGUI) */
1360 syms_of_window (); 1384 syms_of_window ();
1361 syms_of_xdisp (); 1385 syms_of_xdisp ();
1362 syms_of_font (); 1386 syms_of_font ();
@@ -1387,11 +1411,14 @@ Using an Emacs configured with --with-x-toolkit=lucid does not have this problem
1387#ifdef HAVE_NTGUI 1411#ifdef HAVE_NTGUI
1388 syms_of_w32term (); 1412 syms_of_w32term ();
1389 syms_of_w32fns (); 1413 syms_of_w32fns ();
1390 syms_of_w32select ();
1391 syms_of_w32menu (); 1414 syms_of_w32menu ();
1392 syms_of_fontset (); 1415 syms_of_fontset ();
1393#endif /* HAVE_NTGUI */ 1416#endif /* HAVE_NTGUI */
1394 1417
1418#ifdef HAVE_W32SELECT
1419 syms_of_w32select ();
1420#endif /* HAVE_W32SELECT */
1421
1395#ifdef MSDOS 1422#ifdef MSDOS
1396 syms_of_xmenu (); 1423 syms_of_xmenu ();
1397 syms_of_dosfns (); 1424 syms_of_dosfns ();
@@ -1436,8 +1463,11 @@ Using an Emacs configured with --with-x-toolkit=lucid does not have this problem
1436 globals_of_w32font (); 1463 globals_of_w32font ();
1437 globals_of_w32fns (); 1464 globals_of_w32fns ();
1438 globals_of_w32menu (); 1465 globals_of_w32menu ();
1439 globals_of_w32select ();
1440#endif /* HAVE_NTGUI */ 1466#endif /* HAVE_NTGUI */
1467
1468#ifdef HAVE_W32SELECT
1469 globals_of_w32select ();
1470#endif /* HAVE_W32SELECT */
1441 } 1471 }
1442 1472
1443 init_charset (); 1473 init_charset ();
diff --git a/src/font.c b/src/font.c
index 1f22fee88ee..629e8bb977a 100644
--- a/src/font.c
+++ b/src/font.c
@@ -5208,9 +5208,9 @@ EMACS_FONT_LOG is set. Otherwise, it is set to t. */);
5208#ifdef HAVE_BDFFONT 5208#ifdef HAVE_BDFFONT
5209 syms_of_bdffont (); 5209 syms_of_bdffont ();
5210#endif /* HAVE_BDFFONT */ 5210#endif /* HAVE_BDFFONT */
5211#ifdef WINDOWSNT 5211#ifdef HAVE_NTGUI
5212 syms_of_w32font (); 5212 syms_of_w32font ();
5213#endif /* WINDOWSNT */ 5213#endif /* HAVE_NTGUI */
5214#ifdef HAVE_NS 5214#ifdef HAVE_NS
5215 syms_of_nsfont (); 5215 syms_of_nsfont ();
5216#endif /* HAVE_NS */ 5216#endif /* HAVE_NS */
diff --git a/src/font.h b/src/font.h
index 0475eb665dd..3035a909efc 100644
--- a/src/font.h
+++ b/src/font.h
@@ -23,6 +23,7 @@ along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. */
23#define EMACS_FONT_H 23#define EMACS_FONT_H
24 24
25#include "ccl.h" 25#include "ccl.h"
26#include "frame.h"
26 27
27/* We have three types of Lisp objects related to font. 28/* We have three types of Lisp objects related to font.
28 29
@@ -818,11 +819,11 @@ extern struct font_driver ftxfont_driver;
818extern void syms_of_bdffont (void); 819extern void syms_of_bdffont (void);
819#endif /* HAVE_BDFFONT */ 820#endif /* HAVE_BDFFONT */
820#endif /* HAVE_X_WINDOWS */ 821#endif /* HAVE_X_WINDOWS */
821#ifdef WINDOWSNT 822#ifdef HAVE_NTGUI
822extern struct font_driver w32font_driver; 823extern struct font_driver w32font_driver;
823extern struct font_driver uniscribe_font_driver; 824extern struct font_driver uniscribe_font_driver;
824extern void syms_of_w32font (void); 825extern void syms_of_w32font (void);
825#endif /* WINDOWSNT */ 826#endif /* HAVE_NTGUI */
826#ifdef HAVE_NS 827#ifdef HAVE_NS
827extern Lisp_Object Qfontsize; 828extern Lisp_Object Qfontsize;
828extern struct font_driver nsfont_driver; 829extern struct font_driver nsfont_driver;
diff --git a/src/fontset.c b/src/fontset.c
index 7b051cbe1f3..da745b31ca1 100644
--- a/src/fontset.c
+++ b/src/fontset.c
@@ -42,7 +42,7 @@ along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. */
42#ifdef HAVE_X_WINDOWS 42#ifdef HAVE_X_WINDOWS
43#include "xterm.h" 43#include "xterm.h"
44#endif 44#endif
45#ifdef WINDOWSNT 45#ifdef HAVE_NTGUI
46#include "w32term.h" 46#include "w32term.h"
47#endif 47#endif
48#ifdef HAVE_NS 48#ifdef HAVE_NS
diff --git a/src/frame.c b/src/frame.c
index 2fcf7275f9c..599d8879169 100644
--- a/src/frame.c
+++ b/src/frame.c
@@ -2697,7 +2697,7 @@ static const struct frame_parm_table frame_parms[] =
2697 {"tool-bar-position", &Qtool_bar_position}, 2697 {"tool-bar-position", &Qtool_bar_position},
2698}; 2698};
2699 2699
2700#ifdef WINDOWSNT 2700#ifdef HAVE_NTGUI
2701 2701
2702/* Calculate fullscreen size. Return in *TOP_POS and *LEFT_POS the 2702/* Calculate fullscreen size. Return in *TOP_POS and *LEFT_POS the
2703 wanted positions of the WM window (not Emacs window). 2703 wanted positions of the WM window (not Emacs window).
@@ -2741,7 +2741,7 @@ x_fullscreen_adjust (struct frame *f, int *width, int *height, int *top_pos, int
2741 *height = newheight; 2741 *height = newheight;
2742} 2742}
2743 2743
2744#endif /* WINDOWSNT */ 2744#endif /* HAVE_NTGUI */
2745 2745
2746#ifdef HAVE_WINDOW_SYSTEM 2746#ifdef HAVE_WINDOW_SYSTEM
2747 2747
diff --git a/src/frame.h b/src/frame.h
index 26235cc036e..7bf76c21c56 100644
--- a/src/frame.h
+++ b/src/frame.h
@@ -618,7 +618,7 @@ typedef struct frame *FRAME_PTR;
618#define FRAME_INITIAL_P(f) ((f)->output_method == output_initial) 618#define FRAME_INITIAL_P(f) ((f)->output_method == output_initial)
619#define FRAME_TERMCAP_P(f) ((f)->output_method == output_termcap) 619#define FRAME_TERMCAP_P(f) ((f)->output_method == output_termcap)
620#define FRAME_X_P(f) ((f)->output_method == output_x_window) 620#define FRAME_X_P(f) ((f)->output_method == output_x_window)
621#ifndef WINDOWSNT 621#ifndef HAVE_NTGUI
622#define FRAME_W32_P(f) (0) 622#define FRAME_W32_P(f) (0)
623#else 623#else
624#define FRAME_W32_P(f) ((f)->output_method == output_w32) 624#define FRAME_W32_P(f) ((f)->output_method == output_w32)
@@ -1210,7 +1210,7 @@ extern Lisp_Object x_new_font (struct frame *, Lisp_Object, int);
1210 1210
1211extern Lisp_Object Qface_set_after_frame_default; 1211extern Lisp_Object Qface_set_after_frame_default;
1212 1212
1213#ifdef WINDOWSNT 1213#ifdef HAVE_NTGUI
1214extern void x_fullscreen_adjust (struct frame *f, int *, int *, 1214extern void x_fullscreen_adjust (struct frame *f, int *, int *,
1215 int *, int *); 1215 int *, int *);
1216#endif 1216#endif
@@ -1282,6 +1282,7 @@ extern char *x_get_resource_string (const char *, const char *);
1282#endif 1282#endif
1283 1283
1284extern void x_query_colors (struct frame *f, XColor *, int); 1284extern void x_query_colors (struct frame *f, XColor *, int);
1285extern void x_query_color (struct frame *f, XColor *);
1285 1286
1286#endif /* HAVE_WINDOW_SYSTEM */ 1287#endif /* HAVE_WINDOW_SYSTEM */
1287 1288
diff --git a/src/image.c b/src/image.c
index 91eeb91920c..6fc459f0bbc 100644
--- a/src/image.c
+++ b/src/image.c
@@ -75,7 +75,11 @@ typedef struct x_bitmap_record Bitmap_Record;
75#endif /* HAVE_X_WINDOWS */ 75#endif /* HAVE_X_WINDOWS */
76 76
77#ifdef HAVE_NTGUI 77#ifdef HAVE_NTGUI
78#include "w32.h" 78# ifdef WINDOWSNT
79/* We only need (or want) w32.h when we're _not_
80 * compiling for Cygwin */
81# include "w32.h"
82# endif /* WINDOWSNT */
79/* W32_TODO : Color tables on W32. */ 83/* W32_TODO : Color tables on W32. */
80#undef COLOR_TABLE_SUPPORT 84#undef COLOR_TABLE_SUPPORT
81 85
@@ -560,13 +564,14 @@ static struct image_type *lookup_image_type (Lisp_Object);
560static void x_laplace (struct frame *, struct image *); 564static void x_laplace (struct frame *, struct image *);
561static void x_emboss (struct frame *, struct image *); 565static void x_emboss (struct frame *, struct image *);
562static void x_build_heuristic_mask (struct frame *, struct image *, 566static void x_build_heuristic_mask (struct frame *, struct image *,
563 Lisp_Object); 567 Lisp_Object);
564#ifdef HAVE_NTGUI 568#ifdef WINDOWSNT
569extern Lisp_Object Vlibrary_cache;
565#define CACHE_IMAGE_TYPE(type, status) \ 570#define CACHE_IMAGE_TYPE(type, status) \
566 do { Vlibrary_cache = Fcons (Fcons (type, status), Vlibrary_cache); } while (0) 571 do { Vlibrary_cache = Fcons (Fcons (type, status), Vlibrary_cache); } while (0)
567#else 572#else
568#define CACHE_IMAGE_TYPE(type, status) 573#define CACHE_IMAGE_TYPE(type, status)
569#endif 574#endif /* WINDOWSNT */
570 575
571#define ADD_IMAGE_TYPE(type) \ 576#define ADD_IMAGE_TYPE(type) \
572 do { Vimage_types = Fcons (type, Vimage_types); } while (0) 577 do { Vimage_types = Fcons (type, Vimage_types); } while (0)
@@ -589,7 +594,7 @@ define_image_type (struct image_type *type)
589 594
590 if (type->init) 595 if (type->init)
591 { 596 {
592#ifdef HAVE_NTGUI 597#if defined (HAVE_NTGUI) && defined (WINDOWSNT)
593 /* If we failed to load the library before, don't try again. */ 598 /* If we failed to load the library before, don't try again. */
594 Lisp_Object tested = Fassq (target_type, Vlibrary_cache); 599 Lisp_Object tested = Fassq (target_type, Vlibrary_cache);
595 if (CONSP (tested) && NILP (XCDR (tested))) 600 if (CONSP (tested) && NILP (XCDR (tested)))
@@ -1834,7 +1839,7 @@ mark_image_cache (struct image_cache *c)
1834 X / NS / W32 support code 1839 X / NS / W32 support code
1835 ***********************************************************************/ 1840 ***********************************************************************/
1836 1841
1837#ifdef HAVE_NTGUI 1842#ifdef WINDOWSNT
1838 1843
1839/* Macro for defining functions that will be loaded from image DLLs. */ 1844/* Macro for defining functions that will be loaded from image DLLs. */
1840#define DEF_IMGLIB_FN(rettype,func,args) static rettype (FAR CDECL *fn_##func)args 1845#define DEF_IMGLIB_FN(rettype,func,args) static rettype (FAR CDECL *fn_##func)args
@@ -1845,7 +1850,7 @@ mark_image_cache (struct image_cache *c)
1845 if (!fn_##func) return 0; \ 1850 if (!fn_##func) return 0; \
1846 } 1851 }
1847 1852
1848#endif /* HAVE_NTGUI */ 1853#endif /* WINDOWSNT */
1849 1854
1850/* Return true if XIMG's size WIDTH x HEIGHT doesn't break the 1855/* Return true if XIMG's size WIDTH x HEIGHT doesn't break the
1851 windowing system. 1856 windowing system.
@@ -2897,7 +2902,7 @@ xbm_load (struct frame *f, struct image *img)
2897 else 2902 else
2898 bits = (char *) XBOOL_VECTOR (data)->data; 2903 bits = (char *) XBOOL_VECTOR (data)->data;
2899 2904
2900#ifdef WINDOWSNT 2905#ifdef HAVE_NTGUI
2901 { 2906 {
2902 char *invertedBits; 2907 char *invertedBits;
2903 int nbytes, i; 2908 int nbytes, i;
@@ -3008,7 +3013,7 @@ static const struct image_keyword xpm_format[XPM_LAST] =
3008 {":background", IMAGE_STRING_OR_NIL_VALUE, 0} 3013 {":background", IMAGE_STRING_OR_NIL_VALUE, 0}
3009}; 3014};
3010 3015
3011#ifdef HAVE_NTGUI 3016#if defined(HAVE_NTGUI) && defined(WINDOWSNT)
3012static bool init_xpm_functions (void); 3017static bool init_xpm_functions (void);
3013#else 3018#else
3014#define init_xpm_functions NULL 3019#define init_xpm_functions NULL
@@ -3207,7 +3212,7 @@ xpm_free_colors (Display *dpy, Colormap cmap, Pixel *pixels, int npixels, void *
3207#endif /* ALLOC_XPM_COLORS */ 3212#endif /* ALLOC_XPM_COLORS */
3208 3213
3209 3214
3210#ifdef HAVE_NTGUI 3215#ifdef WINDOWSNT
3211 3216
3212/* XPM library details. */ 3217/* XPM library details. */
3213 3218
@@ -3233,8 +3238,15 @@ init_xpm_functions (void)
3233 return 1; 3238 return 1;
3234} 3239}
3235 3240
3236#endif /* HAVE_NTGUI */ 3241#endif /* WINDOWSNT */
3237 3242
3243#ifdef HAVE_NTGUI
3244/* Glue for code below */
3245#define fn_XpmReadFileToImage XpmReadFileToImage
3246#define fn_XpmCreateImageFromBuffer XpmCreateImageFromBuffer
3247#define fn_XImageFree XImageFree
3248#define fn_XpmFreeAttributes XpmFreeAttributes
3249#endif /* HAVE_NTGUI */
3238 3250
3239/* Value is true if COLOR_SYMBOLS is a valid color symbols list 3251/* Value is true if COLOR_SYMBOLS is a valid color symbols list
3240 for XPM images. Such a list must consist of conses whose car and 3252 for XPM images. Such a list must consist of conses whose car and
@@ -5340,7 +5352,7 @@ static const struct image_keyword png_format[PNG_LAST] =
5340 {":background", IMAGE_STRING_OR_NIL_VALUE, 0} 5352 {":background", IMAGE_STRING_OR_NIL_VALUE, 0}
5341}; 5353};
5342 5354
5343#ifdef HAVE_NTGUI 5355#if defined(HAVE_NTGUI) && defined (WINDOWSNT)
5344static bool init_png_functions (void); 5356static bool init_png_functions (void);
5345#else 5357#else
5346#define init_png_functions NULL 5358#define init_png_functions NULL
@@ -5378,7 +5390,7 @@ png_image_p (Lisp_Object object)
5378 5390
5379#ifdef HAVE_PNG 5391#ifdef HAVE_PNG
5380 5392
5381#ifdef HAVE_NTGUI 5393#ifdef WINDOWSNT
5382/* PNG library details. */ 5394/* PNG library details. */
5383 5395
5384DEF_IMGLIB_FN (png_voidp, png_get_io_ptr, (png_structp)); 5396DEF_IMGLIB_FN (png_voidp, png_get_io_ptr, (png_structp));
@@ -5478,7 +5490,7 @@ init_png_functions (void)
5478#define fn_png_set_longjmp_fn png_set_longjmp_fn 5490#define fn_png_set_longjmp_fn png_set_longjmp_fn
5479#endif /* libpng version >= 1.5 */ 5491#endif /* libpng version >= 1.5 */
5480 5492
5481#endif /* HAVE_NTGUI */ 5493#endif /* WINDOWSNT */
5482 5494
5483/* Possibly inefficient/inexact substitutes for _setjmp and _longjmp. 5495/* Possibly inefficient/inexact substitutes for _setjmp and _longjmp.
5484 Do not use sys_setjmp, as PNG supports only jmp_buf. The _longjmp 5496 Do not use sys_setjmp, as PNG supports only jmp_buf. The _longjmp
@@ -5999,7 +6011,7 @@ static const struct image_keyword jpeg_format[JPEG_LAST] =
5999 {":background", IMAGE_STRING_OR_NIL_VALUE, 0} 6011 {":background", IMAGE_STRING_OR_NIL_VALUE, 0}
6000}; 6012};
6001 6013
6002#ifdef HAVE_NTGUI 6014#if defined(HAVE_NTGUI) && defined(WINDOWSNT)
6003static bool init_jpeg_functions (void); 6015static bool init_jpeg_functions (void);
6004#else 6016#else
6005#define init_jpeg_functions NULL 6017#define init_jpeg_functions NULL
@@ -6049,14 +6061,20 @@ jpeg_image_p (Lisp_Object object)
6049#define __WIN32__ 1 6061#define __WIN32__ 1
6050#endif 6062#endif
6051 6063
6064/* Work around conflict between jpeg boolean and rpcndr.h
6065 under Windows. */
6066#define boolean jpeg_boolean
6052#include <jpeglib.h> 6067#include <jpeglib.h>
6053#include <jerror.h> 6068#include <jerror.h>
6054 6069
6070/* Don't undefine boolean --- use the JPEG boolean
6071 through the rest of the file. */
6072
6055#ifdef HAVE_STLIB_H_1 6073#ifdef HAVE_STLIB_H_1
6056#define HAVE_STDLIB_H 1 6074#define HAVE_STDLIB_H 1
6057#endif 6075#endif
6058 6076
6059#ifdef HAVE_NTGUI 6077#ifdef WINDOWSNT
6060 6078
6061/* JPEG library details. */ 6079/* JPEG library details. */
6062DEF_IMGLIB_FN (void, jpeg_CreateDecompress, (j_decompress_ptr, int, size_t)); 6080DEF_IMGLIB_FN (void, jpeg_CreateDecompress, (j_decompress_ptr, int, size_t));
@@ -6106,7 +6124,7 @@ jpeg_resync_to_restart_wrapper (j_decompress_ptr cinfo, int desired)
6106#define fn_jpeg_std_error jpeg_std_error 6124#define fn_jpeg_std_error jpeg_std_error
6107#define jpeg_resync_to_restart_wrapper jpeg_resync_to_restart 6125#define jpeg_resync_to_restart_wrapper jpeg_resync_to_restart
6108 6126
6109#endif /* HAVE_NTGUI */ 6127#endif /* WINDOWSNT */
6110 6128
6111struct my_jpeg_error_mgr 6129struct my_jpeg_error_mgr
6112{ 6130{
@@ -6630,7 +6648,7 @@ tiff_image_p (Lisp_Object object)
6630 6648
6631#include <tiffio.h> 6649#include <tiffio.h>
6632 6650
6633#ifdef HAVE_NTGUI 6651#ifdef WINDOWSNT
6634 6652
6635/* TIFF library details. */ 6653/* TIFF library details. */
6636DEF_IMGLIB_FN (TIFFErrorHandler, TIFFSetErrorHandler, (TIFFErrorHandler)); 6654DEF_IMGLIB_FN (TIFFErrorHandler, TIFFSetErrorHandler, (TIFFErrorHandler));
@@ -6674,7 +6692,7 @@ init_tiff_functions (void)
6674#define fn_TIFFReadRGBAImage TIFFReadRGBAImage 6692#define fn_TIFFReadRGBAImage TIFFReadRGBAImage
6675#define fn_TIFFClose TIFFClose 6693#define fn_TIFFClose TIFFClose
6676#define fn_TIFFSetDirectory TIFFSetDirectory 6694#define fn_TIFFSetDirectory TIFFSetDirectory
6677#endif /* HAVE_NTGUI */ 6695#endif /* WINDOWSNT */
6678 6696
6679 6697
6680/* Reading from a memory buffer for TIFF images Based on the PNG 6698/* Reading from a memory buffer for TIFF images Based on the PNG
@@ -7046,7 +7064,7 @@ static const struct image_keyword gif_format[GIF_LAST] =
7046 {":background", IMAGE_STRING_OR_NIL_VALUE, 0} 7064 {":background", IMAGE_STRING_OR_NIL_VALUE, 0}
7047}; 7065};
7048 7066
7049#ifdef HAVE_NTGUI 7067#if defined(HAVE_NTGUI) && defined(WINDOWSNT)
7050static bool init_gif_functions (void); 7068static bool init_gif_functions (void);
7051#else 7069#else
7052#define init_gif_functions NULL 7070#define init_gif_functions NULL
@@ -7110,7 +7128,7 @@ gif_image_p (Lisp_Object object)
7110#endif /* HAVE_NTGUI */ 7128#endif /* HAVE_NTGUI */
7111 7129
7112 7130
7113#ifdef HAVE_NTGUI 7131#ifdef WINDOWSNT
7114 7132
7115/* GIF library details. */ 7133/* GIF library details. */
7116DEF_IMGLIB_FN (int, DGifCloseFile, (GifFileType *)); 7134DEF_IMGLIB_FN (int, DGifCloseFile, (GifFileType *));
@@ -7140,7 +7158,7 @@ init_gif_functions (void)
7140#define fn_DGifOpen DGifOpen 7158#define fn_DGifOpen DGifOpen
7141#define fn_DGifOpenFileName DGifOpenFileName 7159#define fn_DGifOpenFileName DGifOpenFileName
7142 7160
7143#endif /* HAVE_NTGUI */ 7161#endif /* WINDOWSNT */
7144 7162
7145/* Reading a GIF image from memory 7163/* Reading a GIF image from memory
7146 Based on the PNG memory stuff to a certain extent. */ 7164 Based on the PNG memory stuff to a certain extent. */
@@ -8137,7 +8155,7 @@ svg_image_p (Lisp_Object object)
8137 8155
8138#include <librsvg/rsvg.h> 8156#include <librsvg/rsvg.h>
8139 8157
8140#ifdef HAVE_NTGUI 8158#ifdef WINDOWSNT
8141 8159
8142/* SVG library functions. */ 8160/* SVG library functions. */
8143DEF_IMGLIB_FN (RsvgHandle *, rsvg_handle_new); 8161DEF_IMGLIB_FN (RsvgHandle *, rsvg_handle_new);
@@ -8215,7 +8233,7 @@ init_svg_functions (void)
8215#define fn_g_type_init g_type_init 8233#define fn_g_type_init g_type_init
8216#define fn_g_object_unref g_object_unref 8234#define fn_g_object_unref g_object_unref
8217#define fn_g_error_free g_error_free 8235#define fn_g_error_free g_error_free
8218#endif /* !HAVE_NTGUI */ 8236#endif /* !WINDOWSNT */
8219 8237
8220/* Load SVG image IMG for use on frame F. Value is true if 8238/* Load SVG image IMG for use on frame F. Value is true if
8221 successful. */ 8239 successful. */
@@ -8763,6 +8781,16 @@ DEFUN ("lookup-image", Flookup_image, Slookup_image, 1, 1, 0, "")
8763 Initialization 8781 Initialization
8764 ***********************************************************************/ 8782 ***********************************************************************/
8765 8783
8784#ifdef WINDOWSNT
8785/* Image types that rely on external libraries are loaded dynamically
8786 if the library is available. */
8787#define CHECK_LIB_AVAILABLE(image_type, init_lib_fn, libraries) \
8788 define_image_type (image_type, init_lib_fn (libraries))
8789#else
8790#define CHECK_LIB_AVAILABLE(image_type, init_lib_fn, libraries) \
8791 define_image_type (image_type, 1)
8792#endif /* WINDOWSNT */
8793
8766DEFUN ("init-image-library", Finit_image_library, Sinit_image_library, 1, 1, 0, 8794DEFUN ("init-image-library", Finit_image_library, Sinit_image_library, 1, 1, 0,
8767 doc: /* Initialize image library implementing image type TYPE. 8795 doc: /* Initialize image library implementing image type TYPE.
8768Return non-nil if TYPE is a supported image type. 8796Return non-nil if TYPE is a supported image type.
diff --git a/src/keyboard.c b/src/keyboard.c
index d06b02024c5..05b9a9dde01 100644
--- a/src/keyboard.c
+++ b/src/keyboard.c
@@ -313,7 +313,7 @@ static Lisp_Object Qmouse_fixup_help_message;
313/* Symbols to denote kinds of events. */ 313/* Symbols to denote kinds of events. */
314static Lisp_Object Qfunction_key; 314static Lisp_Object Qfunction_key;
315Lisp_Object Qmouse_click; 315Lisp_Object Qmouse_click;
316#if defined (WINDOWSNT) 316#if defined (HAVE_NTGUI)
317Lisp_Object Qlanguage_change; 317Lisp_Object Qlanguage_change;
318#endif 318#endif
319static Lisp_Object Qdrag_n_drop; 319static Lisp_Object Qdrag_n_drop;
@@ -3766,8 +3766,8 @@ kbd_buffer_get_event (KBOARD **kbp,
3766#ifdef subprocesses 3766#ifdef subprocesses
3767 if (kbd_on_hold_p () && kbd_buffer_nr_stored () < KBD_BUFFER_SIZE/4) 3767 if (kbd_on_hold_p () && kbd_buffer_nr_stored () < KBD_BUFFER_SIZE/4)
3768 { 3768 {
3769 /* Start reading input again, we have processed enough so we can 3769 /* Start reading input again because we have processed enough to
3770 accept new events again. */ 3770 be able to accept new events again. */
3771 unhold_keyboard_input (); 3771 unhold_keyboard_input ();
3772 start_polling (); 3772 start_polling ();
3773 } 3773 }
@@ -3947,7 +3947,7 @@ kbd_buffer_get_event (KBOARD **kbp,
3947 x_activate_menubar (XFRAME (event->frame_or_window)); 3947 x_activate_menubar (XFRAME (event->frame_or_window));
3948 } 3948 }
3949#endif 3949#endif
3950#if defined (WINDOWSNT) 3950#if defined (HAVE_NTGUI)
3951 else if (event->kind == LANGUAGE_CHANGE_EVENT) 3951 else if (event->kind == LANGUAGE_CHANGE_EVENT)
3952 { 3952 {
3953 /* Make an event (language-change (FRAME CODEPAGE LANGUAGE-ID)). */ 3953 /* Make an event (language-change (FRAME CODEPAGE LANGUAGE-ID)). */
@@ -5417,7 +5417,7 @@ make_lispy_event (struct input_event *event)
5417 (sizeof (lispy_function_keys) 5417 (sizeof (lispy_function_keys)
5418 / sizeof (lispy_function_keys[0]))); 5418 / sizeof (lispy_function_keys[0])));
5419 5419
5420#ifdef WINDOWSNT 5420#ifdef HAVE_NTGUI
5421 case MULTIMEDIA_KEY_EVENT: 5421 case MULTIMEDIA_KEY_EVENT:
5422 if (event->code < (sizeof (lispy_multimedia_keys) 5422 if (event->code < (sizeof (lispy_multimedia_keys)
5423 / sizeof (lispy_multimedia_keys[0])) 5423 / sizeof (lispy_multimedia_keys[0]))
@@ -11394,7 +11394,7 @@ syms_of_keyboard (void)
11394 DEFSYM (Qconfig_changed_event, "config-changed-event"); 11394 DEFSYM (Qconfig_changed_event, "config-changed-event");
11395 DEFSYM (Qmenu_enable, "menu-enable"); 11395 DEFSYM (Qmenu_enable, "menu-enable");
11396 11396
11397#if defined (WINDOWSNT) 11397#if defined (HAVE_NTGUI)
11398 DEFSYM (Qlanguage_change, "language-change"); 11398 DEFSYM (Qlanguage_change, "language-change");
11399#endif 11399#endif
11400 11400
diff --git a/src/keyboard.h b/src/keyboard.h
index bc35bba4ecc..d78c27fbf9b 100644
--- a/src/keyboard.h
+++ b/src/keyboard.h
@@ -551,7 +551,7 @@ extern int tty_read_avail_input (struct terminal *, struct input_event *);
551extern EMACS_TIME timer_check (void); 551extern EMACS_TIME timer_check (void);
552extern void mark_kboards (void); 552extern void mark_kboards (void);
553 553
554#ifdef WINDOWSNT 554#ifdef HAVE_NTGUI
555extern const char *const lispy_function_keys[]; 555extern const char *const lispy_function_keys[];
556#endif 556#endif
557 557
diff --git a/src/menu.c b/src/menu.c
index 5374aa9157a..835267b2f0c 100644
--- a/src/menu.c
+++ b/src/menu.c
@@ -40,7 +40,11 @@ along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. */
40#endif /* HAVE_WINDOW_SYSTEM */ 40#endif /* HAVE_WINDOW_SYSTEM */
41 41
42#ifdef HAVE_NTGUI 42#ifdef HAVE_NTGUI
43# ifdef NTGUI_UNICODE
44# define unicode_append_menu AppendMenuW
45# else /* !NTGUI_UNICODE */
43extern AppendMenuW_Proc unicode_append_menu; 46extern AppendMenuW_Proc unicode_append_menu;
47# endif /* NTGUI_UNICODE */
44extern HMENU current_popup_menu; 48extern HMENU current_popup_menu;
45#endif /* HAVE_NTGUI */ 49#endif /* HAVE_NTGUI */
46 50
diff --git a/src/process.c b/src/process.c
index 92bea0d3a27..c941a196539 100644
--- a/src/process.c
+++ b/src/process.c
@@ -4646,6 +4646,7 @@ wait_reading_process_output (intmax_t time_limit, int nsecs, int read_kbd,
4646 process_output_skip = 0; 4646 process_output_skip = 0;
4647 } 4647 }
4648#endif 4648#endif
4649
4649#if defined (USE_GTK) || defined (HAVE_GCONF) || defined (HAVE_GSETTINGS) 4650#if defined (USE_GTK) || defined (HAVE_GCONF) || defined (HAVE_GSETTINGS)
4650 nfds = xg_select 4651 nfds = xg_select
4651#elif defined (HAVE_NS) 4652#elif defined (HAVE_NS)
diff --git a/src/termhooks.h b/src/termhooks.h
index f35bd929af1..42f2e16e577 100644
--- a/src/termhooks.h
+++ b/src/termhooks.h
@@ -107,9 +107,9 @@ enum event_kind
107 HORIZ_WHEEL_EVENT, /* A wheel event generated by a second 107 HORIZ_WHEEL_EVENT, /* A wheel event generated by a second
108 horizontal wheel that is present on some 108 horizontal wheel that is present on some
109 mice. See WHEEL_EVENT. */ 109 mice. See WHEEL_EVENT. */
110#if defined (WINDOWSNT) 110#if defined (HAVE_NTGUI)
111 LANGUAGE_CHANGE_EVENT, /* A LANGUAGE_CHANGE_EVENT is 111 LANGUAGE_CHANGE_EVENT, /* A LANGUAGE_CHANGE_EVENT is
112 generated on WINDOWSNT or Mac OS 112 generated when HAVE_NTGUI or on Mac OS
113 when the keyboard layout or input 113 when the keyboard layout or input
114 language is changed by the 114 language is changed by the
115 user. */ 115 user. */
@@ -188,7 +188,7 @@ enum event_kind
188 188
189 , CONFIG_CHANGED_EVENT 189 , CONFIG_CHANGED_EVENT
190 190
191#ifdef WINDOWSNT 191#ifdef HAVE_NTGUI
192 /* Generated when an APPCOMMAND event is received, in response to 192 /* Generated when an APPCOMMAND event is received, in response to
193 Multimedia or Internet buttons on some keyboards. 193 Multimedia or Internet buttons on some keyboards.
194 Such keys are available as normal function keys on X through the 194 Such keys are available as normal function keys on X through the
diff --git a/src/unexw32.c b/src/unexw32.c
index 3eefc9ce058..d57378b2421 100644
--- a/src/unexw32.c
+++ b/src/unexw32.c
@@ -83,7 +83,7 @@ DWORD_PTR extra_bss_size_static = 0;
83PIMAGE_SECTION_HEADER heap_section; 83PIMAGE_SECTION_HEADER heap_section;
84 84
85#ifdef HAVE_NTGUI 85#ifdef HAVE_NTGUI
86HINSTANCE hinst = NULL; 86extern HINSTANCE hinst;
87HINSTANCE hprevinst = NULL; 87HINSTANCE hprevinst = NULL;
88LPSTR lpCmdLine = ""; 88LPSTR lpCmdLine = "";
89int nCmdShow = 0; 89int nCmdShow = 0;
diff --git a/src/w32.c b/src/w32.c
index f17c06ea807..85210cb8e4c 100644
--- a/src/w32.c
+++ b/src/w32.c
@@ -31,13 +31,13 @@ along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. */
31#include <sys/file.h> 31#include <sys/file.h>
32#include <sys/time.h> 32#include <sys/time.h>
33#include <sys/utime.h> 33#include <sys/utime.h>
34#include <mbstring.h> /* for _mbspbrk */
35#include <math.h> 34#include <math.h>
36#include <time.h> 35#include <time.h>
37 36
38/* must include CRT headers *before* config.h */ 37/* must include CRT headers *before* config.h */
39 38
40#include <config.h> 39#include <config.h>
40#include <mbstring.h> /* for _mbspbrk */
41 41
42#undef access 42#undef access
43#undef chdir 43#undef chdir
@@ -866,23 +866,6 @@ create_symbolic_link (LPTSTR lpSymlinkFilename,
866 return retval; 866 return retval;
867} 867}
868 868
869/* Equivalent of strerror for W32 error codes. */
870char *
871w32_strerror (int error_no)
872{
873 static char buf[500];
874
875 if (error_no == 0)
876 error_no = GetLastError ();
877
878 buf[0] = '\0';
879 if (!FormatMessage (FORMAT_MESSAGE_FROM_SYSTEM, NULL,
880 error_no,
881 0, /* choose most suitable language */
882 buf, sizeof (buf), NULL))
883 sprintf (buf, "w32 error %u", error_no);
884 return buf;
885}
886 869
887/* Return 1 if P is a valid pointer to an object of size SIZE. Return 870/* Return 1 if P is a valid pointer to an object of size SIZE. Return
888 0 if P is NOT a valid pointer. Return -1 if we cannot validate P. 871 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 2e2315e245d..c4cfdf5fedd 100644
--- a/src/w32.h
+++ b/src/w32.h
@@ -19,6 +19,12 @@ GNU General Public License for more details.
19You should have received a copy of the GNU General Public License 19You should have received a copy of the GNU General Public License
20along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. */ 20along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. */
21 21
22#ifdef CYGWIN
23#error "w32.h is not compatible with Cygwin"
24#endif
25
26#include <windows.h>
27
22 28
23/* File descriptor set emulation. */ 29/* File descriptor set emulation. */
24 30
@@ -130,17 +136,6 @@ extern LPBYTE w32_get_resource (char * key, LPDWORD type);
130extern void init_ntproc (int); 136extern void init_ntproc (int);
131extern void term_ntproc (int); 137extern void term_ntproc (int);
132extern void globals_of_w32 (void); 138extern void globals_of_w32 (void);
133extern void syms_of_w32term (void);
134extern void syms_of_w32fns (void);
135extern void globals_of_w32fns (void);
136extern void syms_of_w32select (void);
137extern void globals_of_w32select (void);
138extern void term_w32select (void);
139extern void syms_of_w32menu (void);
140extern void globals_of_w32menu (void);
141extern void syms_of_fontset (void);
142extern void syms_of_w32font (void);
143extern void check_windows_init_file (void);
144 139
145extern void term_timers (void); 140extern void term_timers (void);
146extern void init_timers (void); 141extern void init_timers (void);
diff --git a/src/w32console.c b/src/w32console.c
index b22b09af2f2..5a44d3748a2 100644
--- a/src/w32console.c
+++ b/src/w32console.c
@@ -36,6 +36,7 @@ along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. */
36#include "termhooks.h" 36#include "termhooks.h"
37#include "termchar.h" 37#include "termchar.h"
38#include "dispextern.h" 38#include "dispextern.h"
39#include "w32term.h"
39#include "w32heap.h" /* for os_subtype */ 40#include "w32heap.h" /* for os_subtype */
40#include "w32inevt.h" 41#include "w32inevt.h"
41 42
@@ -430,53 +431,6 @@ w32con_delete_glyphs (struct frame *f, int n)
430 scroll_line (f, n, LEFT); 431 scroll_line (f, n, LEFT);
431} 432}
432 433
433static unsigned int sound_type = 0xFFFFFFFF;
434#define MB_EMACS_SILENT (0xFFFFFFFF - 1)
435
436void
437w32_sys_ring_bell (struct frame *f)
438{
439 if (sound_type == 0xFFFFFFFF)
440 {
441 Beep (666, 100);
442 }
443 else if (sound_type == MB_EMACS_SILENT)
444 {
445 /* Do nothing. */
446 }
447 else
448 MessageBeep (sound_type);
449}
450
451DEFUN ("set-message-beep", Fset_message_beep, Sset_message_beep, 1, 1, 0,
452 doc: /* Set the sound generated when the bell is rung.
453SOUND is 'asterisk, 'exclamation, 'hand, 'question, 'ok, or 'silent
454to use the corresponding system sound for the bell. The 'silent sound
455prevents Emacs from making any sound at all.
456SOUND is nil to use the normal beep. */)
457 (Lisp_Object sound)
458{
459 CHECK_SYMBOL (sound);
460
461 if (NILP (sound))
462 sound_type = 0xFFFFFFFF;
463 else if (EQ (sound, intern ("asterisk")))
464 sound_type = MB_ICONASTERISK;
465 else if (EQ (sound, intern ("exclamation")))
466 sound_type = MB_ICONEXCLAMATION;
467 else if (EQ (sound, intern ("hand")))
468 sound_type = MB_ICONHAND;
469 else if (EQ (sound, intern ("question")))
470 sound_type = MB_ICONQUESTION;
471 else if (EQ (sound, intern ("ok")))
472 sound_type = MB_OK;
473 else if (EQ (sound, intern ("silent")))
474 sound_type = MB_EMACS_SILENT;
475 else
476 sound_type = 0xFFFFFFFF;
477
478 return sound;
479}
480 434
481static void 435static void
482w32con_reset_terminal_modes (struct terminal *t) 436w32con_reset_terminal_modes (struct terminal *t)
@@ -850,5 +804,4 @@ scroll-back buffer. */);
850 defsubr (&Sset_screen_color); 804 defsubr (&Sset_screen_color);
851 defsubr (&Sget_screen_color); 805 defsubr (&Sget_screen_color);
852 defsubr (&Sset_cursor_size); 806 defsubr (&Sset_cursor_size);
853 defsubr (&Sset_message_beep);
854} 807}
diff --git a/src/w32fns.c b/src/w32fns.c
index db3b3e64b2d..7f0e6d5e5bf 100644
--- a/src/w32fns.c
+++ b/src/w32fns.c
@@ -44,8 +44,14 @@ along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. */
44#include "fontset.h" 44#include "fontset.h"
45#include "systime.h" 45#include "systime.h"
46#include "termhooks.h" 46#include "termhooks.h"
47
47#include "w32heap.h" 48#include "w32heap.h"
49
50#if CYGWIN
51#include "cygw32.h"
52#else
48#include "w32.h" 53#include "w32.h"
54#endif
49 55
50#include "bitmaps/gray.xbm" 56#include "bitmaps/gray.xbm"
51 57
@@ -58,9 +64,6 @@ along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. */
58 64
59#include <dlgs.h> 65#include <dlgs.h>
60#include <imm.h> 66#include <imm.h>
61#define FILE_NAME_TEXT_FIELD edt1
62#define FILE_NAME_COMBO_BOX cmb13
63#define FILE_NAME_LIST lst1
64 67
65#include "font.h" 68#include "font.h"
66#include "w32font.h" 69#include "w32font.h"
@@ -78,6 +81,7 @@ extern int w32_console_toggle_lock_key (int, Lisp_Object);
78extern void w32_menu_display_help (HWND, HMENU, UINT, UINT); 81extern void w32_menu_display_help (HWND, HMENU, UINT, UINT);
79extern void w32_free_menu_strings (HWND); 82extern void w32_free_menu_strings (HWND);
80extern const char *map_w32_filename (const char *, const char **); 83extern const char *map_w32_filename (const char *, const char **);
84extern char * w32_strerror (int error_no);
81 85
82/* If non-NULL, a handle to a frame where to display the hourglass cursor. */ 86/* If non-NULL, a handle to a frame where to display the hourglass cursor. */
83static HWND hourglass_hwnd = NULL; 87static HWND hourglass_hwnd = NULL;
@@ -161,7 +165,11 @@ ImmSetCompositionWindow_Proc set_ime_composition_window_fn = NULL;
161MonitorFromPoint_Proc monitor_from_point_fn = NULL; 165MonitorFromPoint_Proc monitor_from_point_fn = NULL;
162GetMonitorInfo_Proc get_monitor_info_fn = NULL; 166GetMonitorInfo_Proc get_monitor_info_fn = NULL;
163 167
168#ifdef NTGUI_UNICODE
169#define unicode_append_menu AppendMenuW
170#else /* !NTGUI_UNICODE */
164extern AppendMenuW_Proc unicode_append_menu; 171extern AppendMenuW_Proc unicode_append_menu;
172#endif /* NTGUI_UNICODE */
165 173
166/* Flag to selectively ignore WM_IME_CHAR messages. */ 174/* Flag to selectively ignore WM_IME_CHAR messages. */
167static int ignore_ime_char = 0; 175static int ignore_ime_char = 0;
@@ -198,6 +206,33 @@ extern int uniscribe_available;
198static void w32_show_hourglass (struct frame *); 206static void w32_show_hourglass (struct frame *);
199static void w32_hide_hourglass (void); 207static void w32_hide_hourglass (void);
200 208
209#ifdef WINDOWSNT
210/* From w32inevet.c */
211extern int faked_key;
212#endif /* WINDOWSNT */
213
214/* This gives us the page size and the size of the allocation unit on NT. */
215SYSTEM_INFO sysinfo_cache;
216
217/* This gives us version, build, and platform identification. */
218OSVERSIONINFO osinfo_cache;
219
220unsigned long syspage_mask = 0;
221
222/* The major and minor versions of NT. */
223int w32_major_version;
224int w32_minor_version;
225int w32_build_number;
226
227/* Distinguish between Windows NT and Windows 95. */
228int os_subtype;
229
230#ifdef HAVE_NTGUI
231HINSTANCE hinst = NULL;
232#endif
233
234static unsigned int sound_type = 0xFFFFFFFF;
235#define MB_EMACS_SILENT (0xFFFFFFFF - 1)
201 236
202 237
203/* Error if we are not connected to MS-Windows. */ 238/* Error if we are not connected to MS-Windows. */
@@ -1068,7 +1103,7 @@ gamma_correct (struct frame *f, COLORREF *color)
1068 If ALLOC is nonzero, allocate a new colormap cell. */ 1103 If ALLOC is nonzero, allocate a new colormap cell. */
1069 1104
1070int 1105int
1071w32_defined_color (FRAME_PTR f, char *color, XColor *color_def, int alloc) 1106w32_defined_color (FRAME_PTR f, const char *color, XColor *color_def, int alloc)
1072{ 1107{
1073 register Lisp_Object tem; 1108 register Lisp_Object tem;
1074 COLORREF w32_color_ref; 1109 COLORREF w32_color_ref;
@@ -1843,10 +1878,7 @@ w32_createwindow (struct frame *f)
1843 1878
1844 /* Do first time app init */ 1879 /* Do first time app init */
1845 1880
1846 if (!hprevinst) 1881 w32_init_class (hinst);
1847 {
1848 w32_init_class (hinst);
1849 }
1850 1882
1851 if (f->size_hint_flags & USPosition || f->size_hint_flags & PPosition) 1883 if (f->size_hint_flags & USPosition || f->size_hint_flags & PPosition)
1852 { 1884 {
@@ -2246,6 +2278,58 @@ unregister_hot_keys (HWND hwnd)
2246 } 2278 }
2247} 2279}
2248 2280
2281#if EMACSDEBUG
2282const char*
2283w32_name_of_message (UINT msg)
2284{
2285 unsigned i;
2286 static char buf[64];
2287 static const struct {
2288 UINT msg;
2289 const char* name;
2290 } msgnames[] = {
2291#define M(msg) { msg, # msg }
2292 M (WM_PAINT),
2293 M (WM_TIMER),
2294 M (WM_USER),
2295 M (WM_MOUSEMOVE),
2296 M (WM_LBUTTONUP),
2297 M (WM_KEYDOWN),
2298 M (WM_EMACS_KILL),
2299 M (WM_EMACS_CREATEWINDOW),
2300 M (WM_EMACS_DONE),
2301 M (WM_EMACS_CREATESCROLLBAR),
2302 M (WM_EMACS_SHOWWINDOW),
2303 M (WM_EMACS_SETWINDOWPOS),
2304 M (WM_EMACS_DESTROYWINDOW),
2305 M (WM_EMACS_TRACKPOPUPMENU),
2306 M (WM_EMACS_SETFOCUS),
2307 M (WM_EMACS_SETFOREGROUND),
2308 M (WM_EMACS_SETLOCALE),
2309 M (WM_EMACS_SETKEYBOARDLAYOUT),
2310 M (WM_EMACS_REGISTER_HOT_KEY),
2311 M (WM_EMACS_UNREGISTER_HOT_KEY),
2312 M (WM_EMACS_TOGGLE_LOCK_KEY),
2313 M (WM_EMACS_TRACK_CARET),
2314 M (WM_EMACS_DESTROY_CARET),
2315 M (WM_EMACS_SHOW_CARET),
2316 M (WM_EMACS_HIDE_CARET),
2317 M (WM_EMACS_SETCURSOR),
2318 M (WM_EMACS_PAINT),
2319 M (WM_CHAR),
2320#undef M
2321 { 0, 0 }
2322 };
2323
2324 for (i = 0; msgnames[i].name; ++i)
2325 if (msgnames[i].msg == msg)
2326 return msgnames[i].name;
2327
2328 sprintf (buf, "message 0x%04x", (unsigned)msg);
2329 return buf;
2330}
2331#endif /* EMACSDEBUG */
2332
2249/* Here's an overview of how Emacs input works on MS-Windows. 2333/* Here's an overview of how Emacs input works on MS-Windows.
2250 2334
2251 System messages are read and processed by w32_msg_pump below. This 2335 System messages are read and processed by w32_msg_pump below. This
@@ -2265,7 +2349,12 @@ unregister_hot_keys (HWND hwnd)
2265 messages immediately, or converts them into Emacs input events and 2349 messages immediately, or converts them into Emacs input events and
2266 stuffs them into kbd_buffer, where kbd_buffer_get_event can get at 2350 stuffs them into kbd_buffer, where kbd_buffer_get_event can get at
2267 them and process them when read_char and its callers require 2351 them and process them when read_char and its callers require
2268 input. */ 2352 input.
2353
2354 Under Cygwin with the W32 toolkit, the use of /dev/windows with
2355 select(2) takes the place of w32_read_socket.
2356
2357 */
2269 2358
2270/* Main message dispatch loop. */ 2359/* Main message dispatch loop. */
2271 2360
@@ -2280,6 +2369,10 @@ w32_msg_pump (deferred_msg * msg_buf)
2280 2369
2281 while ((w32_unicode_gui ? GetMessageW : GetMessageA) (&msg, NULL, 0, 0)) 2370 while ((w32_unicode_gui ? GetMessageW : GetMessageA) (&msg, NULL, 0, 0))
2282 { 2371 {
2372
2373 /* DebPrint (("w32_msg_pump: %s time:%u\n", */
2374 /* w32_name_of_message (msg.message), msg.time)); */
2375
2283 if (msg.hwnd == NULL) 2376 if (msg.hwnd == NULL)
2284 { 2377 {
2285 switch (msg.message) 2378 switch (msg.message)
@@ -2367,7 +2460,7 @@ w32_msg_pump (deferred_msg * msg_buf)
2367 /* Broadcast messages make it here, so you need to be looking 2460 /* Broadcast messages make it here, so you need to be looking
2368 for something in particular for this to be useful. */ 2461 for something in particular for this to be useful. */
2369 default: 2462 default:
2370 DebPrint (("msg %x not expected by w32_msg_pump\n", msg.message)); 2463 DebPrint (("msg %x not expected by w32_msg_pump\n", msg.message));
2371#endif 2464#endif
2372 } 2465 }
2373 } 2466 }
@@ -4703,6 +4796,37 @@ If omitted or nil, that stands for the selected frame's display. */)
4703{ 4796{
4704 return Qnil; 4797 return Qnil;
4705} 4798}
4799
4800DEFUN ("set-message-beep", Fset_message_beep, Sset_message_beep, 1, 1, 0,
4801 doc: /* Set the sound generated when the bell is rung.
4802SOUND is 'asterisk, 'exclamation, 'hand, 'question, 'ok, or 'silent
4803to use the corresponding system sound for the bell. The 'silent sound
4804prevents Emacs from making any sound at all.
4805SOUND is nil to use the normal beep. */)
4806 (Lisp_Object sound)
4807{
4808 CHECK_SYMBOL (sound);
4809
4810 if (NILP (sound))
4811 sound_type = 0xFFFFFFFF;
4812 else if (EQ (sound, intern ("asterisk")))
4813 sound_type = MB_ICONASTERISK;
4814 else if (EQ (sound, intern ("exclamation")))
4815 sound_type = MB_ICONEXCLAMATION;
4816 else if (EQ (sound, intern ("hand")))
4817 sound_type = MB_ICONHAND;
4818 else if (EQ (sound, intern ("question")))
4819 sound_type = MB_ICONQUESTION;
4820 else if (EQ (sound, intern ("ok")))
4821 sound_type = MB_OK;
4822 else if (EQ (sound, intern ("silent")))
4823 sound_type = MB_EMACS_SILENT;
4824 else
4825 sound_type = 0xFFFFFFFF;
4826
4827 return sound;
4828}
4829
4706 4830
4707int 4831int
4708x_pixel_width (register struct frame *f) 4832x_pixel_width (register struct frame *f)
@@ -4784,12 +4908,21 @@ terminate Emacs if we can't open the connection.
4784 unsigned char *xrm_option; 4908 unsigned char *xrm_option;
4785 struct w32_display_info *dpyinfo; 4909 struct w32_display_info *dpyinfo;
4786 4910
4911 CHECK_STRING (display);
4912
4913 /* Signal an error in order to encourage correct use from callers.
4914 * If we ever support multiple window systems in the same Emacs,
4915 * we'll need callers to be precise about what window system they
4916 * want. */
4917
4918 if (strcmp (SSDATA (display), "w32") != 0)
4919 error ("The name of the display in this Emacs must be \"w32\"");
4920
4787 /* If initialization has already been done, return now to avoid 4921 /* If initialization has already been done, return now to avoid
4788 overwriting critical parts of one_w32_display_info. */ 4922 overwriting critical parts of one_w32_display_info. */
4789 if (w32_in_use) 4923 if (w32_in_use)
4790 return Qnil; 4924 return Qnil;
4791 4925
4792 CHECK_STRING (display);
4793 if (! NILP (xrm_string)) 4926 if (! NILP (xrm_string))
4794 CHECK_STRING (xrm_string); 4927 CHECK_STRING (xrm_string);
4795 4928
@@ -5860,6 +5993,18 @@ Value is t if tooltip was open, nil otherwise. */)
5860 File selection dialog 5993 File selection dialog
5861 ***********************************************************************/ 5994 ***********************************************************************/
5862 5995
5996#define FILE_NAME_TEXT_FIELD edt1
5997#define FILE_NAME_COMBO_BOX cmb13
5998#define FILE_NAME_LIST lst1
5999
6000#ifdef NTGUI_UNICODE
6001#define GUISTR(x) (L ## x)
6002typedef wchar_t guichar_t;
6003#else /* !NTGUI_UNICODE */
6004#define GUISTR(x) x
6005typedef char guichar_t;
6006#endif /* NTGUI_UNICODE */
6007
5863/* Callback for altering the behavior of the Open File dialog. 6008/* Callback for altering the behavior of the Open File dialog.
5864 Makes the Filename text field contain "Current Directory" and be 6009 Makes the Filename text field contain "Current Directory" and be
5865 read-only when "Directories" is selected in the filter. This 6010 read-only when "Directories" is selected in the filter. This
@@ -5870,7 +6015,11 @@ file_dialog_callback (HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
5870{ 6015{
5871 if (msg == WM_NOTIFY) 6016 if (msg == WM_NOTIFY)
5872 { 6017 {
5873 OFNOTIFY * notify = (OFNOTIFY *)lParam; 6018#ifdef NTGUI_UNICODE
6019 OFNOTIFYW * notify = (OFNOTIFYW *)lParam;
6020#else /* !NTGUI_UNICODE */
6021 OFNOTIFYA * notify = (OFNOTIFYA *)lParam;
6022#endif /* NTGUI_UNICODE */
5874 /* Detect when the Filter dropdown is changed. */ 6023 /* Detect when the Filter dropdown is changed. */
5875 if (notify->hdr.code == CDN_TYPECHANGE 6024 if (notify->hdr.code == CDN_TYPECHANGE
5876 || notify->hdr.code == CDN_INITDONE) 6025 || notify->hdr.code == CDN_INITDONE)
@@ -5898,7 +6047,7 @@ file_dialog_callback (HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
5898 if (notify->lpOFN->nFilterIndex == 2) 6047 if (notify->lpOFN->nFilterIndex == 2)
5899 { 6048 {
5900 CommDlg_OpenSave_SetControlText (dialog, FILE_NAME_TEXT_FIELD, 6049 CommDlg_OpenSave_SetControlText (dialog, FILE_NAME_TEXT_FIELD,
5901 "Current Directory"); 6050 GUISTR ("Current Directory"));
5902 EnableWindow (edit_control, FALSE); 6051 EnableWindow (edit_control, FALSE);
5903 /* Note that at least on Windows 7, the above call to EnableWindow 6052 /* Note that at least on Windows 7, the above call to EnableWindow
5904 disables the window that would ordinarily have focus. If we 6053 disables the window that would ordinarily have focus. If we
@@ -5914,7 +6063,8 @@ file_dialog_callback (HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
5914 /* Don't override default filename on init done. */ 6063 /* Don't override default filename on init done. */
5915 if (notify->hdr.code == CDN_TYPECHANGE) 6064 if (notify->hdr.code == CDN_TYPECHANGE)
5916 CommDlg_OpenSave_SetControlText (dialog, 6065 CommDlg_OpenSave_SetControlText (dialog,
5917 FILE_NAME_TEXT_FIELD, ""); 6066 FILE_NAME_TEXT_FIELD,
6067 GUISTR (""));
5918 EnableWindow (edit_control, TRUE); 6068 EnableWindow (edit_control, TRUE);
5919 } 6069 }
5920 } 6070 }
@@ -5922,19 +6072,6 @@ file_dialog_callback (HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
5922 return 0; 6072 return 0;
5923} 6073}
5924 6074
5925/* Since we compile with _WIN32_WINNT set to 0x0400 (for NT4 compatibility)
5926 we end up with the old file dialogs. Define a big enough struct for the
5927 new dialog to trick GetOpenFileName into giving us the new dialogs on
5928 Windows 2000 and XP. */
5929typedef struct
5930{
5931 OPENFILENAME real_details;
5932 void * pReserved;
5933 DWORD dwReserved;
5934 DWORD FlagsEx;
5935} NEWOPENFILENAME;
5936
5937
5938DEFUN ("x-file-dialog", Fx_file_dialog, Sx_file_dialog, 2, 5, 0, 6075DEFUN ("x-file-dialog", Fx_file_dialog, Sx_file_dialog, 2, 5, 0,
5939 doc: /* Read file name, prompting with PROMPT in directory DIR. 6076 doc: /* Read file name, prompting with PROMPT in directory DIR.
5940Use a file selection dialog. Select DEFAULT-FILENAME in the dialog's file 6077Use a file selection dialog. Select DEFAULT-FILENAME in the dialog's file
@@ -5946,134 +6083,203 @@ Motif or Gtk toolkits. With the Motif toolkit, ONLY-DIR-P is ignored.
5946Otherwise, if ONLY-DIR-P is non-nil, the user can only select directories. */) 6083Otherwise, if ONLY-DIR-P is non-nil, the user can only select directories. */)
5947 (Lisp_Object prompt, Lisp_Object dir, Lisp_Object default_filename, Lisp_Object mustmatch, Lisp_Object only_dir_p) 6084 (Lisp_Object prompt, Lisp_Object dir, Lisp_Object default_filename, Lisp_Object mustmatch, Lisp_Object only_dir_p)
5948{ 6085{
6086 /* Filter index: 1: All Files, 2: Directories only */
6087 static const guichar_t filter[] =
6088 GUISTR ("All Files (*.*)\0*.*\0Directories\0*|*\0");
6089
6090 Lisp_Object filename = default_filename;
5949 struct frame *f = SELECTED_FRAME (); 6091 struct frame *f = SELECTED_FRAME ();
5950 Lisp_Object file = Qnil; 6092 BOOL file_opened = FALSE;
5951 ptrdiff_t count = SPECPDL_INDEX (); 6093 Lisp_Object orig_dir = dir;
6094 Lisp_Object orig_prompt = prompt;
6095
6096 /* If we compile with _WIN32_WINNT set to 0x0400 (for NT4
6097 compatibility) we end up with the old file dialogs. Define a big
6098 enough struct for the new dialog to trick GetOpenFileName into
6099 giving us the new dialogs on newer versions of Windows. */
6100 struct {
6101#ifdef NTGUI_UNICODE
6102 OPENFILENAMEW details;
6103#else /* !NTGUI_UNICODE */
6104 OPENFILENAMEA details;
6105#endif /* NTGUI_UNICODE */
6106
6107#if _WIN32_WINNT < 0x500 /* < win2k */
6108 PVOID pvReserved;
6109 DWORD dwReserved;
6110 DWORD FlagsEx;
6111#endif /* < win2k */
6112 } new_file_details;
6113
6114#ifdef NTGUI_UNICODE
6115 wchar_t filename_buf[MAX_PATH + 1];
6116 OPENFILENAMEW * file_details = &new_file_details.details;
6117#else /* not NTGUI_UNICODE */
6118 char filename_buf[MAX_PATH + 1];
6119 OPENFILENAMEA * file_details = &new_file_details.details;
6120#endif /* NTGUI_UNICODE */
6121
5952 struct gcpro gcpro1, gcpro2, gcpro3, gcpro4, gcpro5, gcpro6; 6122 struct gcpro gcpro1, gcpro2, gcpro3, gcpro4, gcpro5, gcpro6;
5953 char filename[MAX_PATH + 1]; 6123 GCPRO6 (prompt, dir, default_filename, mustmatch, only_dir_p, filename);
5954 char init_dir[MAX_PATH + 1];
5955 int default_filter_index = 1; /* 1: All Files, 2: Directories only */
5956
5957 GCPRO6 (prompt, dir, default_filename, mustmatch, only_dir_p, file);
5958 CHECK_STRING (prompt);
5959 CHECK_STRING (dir);
5960
5961 /* Create the dialog with PROMPT as title, using DIR as initial
5962 directory and using "*" as pattern. */
5963 dir = Fexpand_file_name (dir, Qnil);
5964 strncpy (init_dir, SDATA (ENCODE_FILE (dir)), MAX_PATH);
5965 init_dir[MAX_PATH] = '\0';
5966 unixtodos_filename (init_dir);
5967
5968 if (STRINGP (default_filename))
5969 {
5970 char *file_name_only;
5971 char *full_path_name = SDATA (ENCODE_FILE (default_filename));
5972 6124
5973 unixtodos_filename (full_path_name); 6125 {
6126 struct gcpro gcpro1, gcpro2;
6127 GCPRO2 (orig_dir, orig_prompt); /* There is no GCPRON, N>6. */
5974 6128
5975 file_name_only = strrchr (full_path_name, '\\'); 6129 /* Note: under NTGUI_UNICODE, we do _NOT_ use ENCODE_FILE: the
5976 if (!file_name_only) 6130 system file encoding expected by the platform APIs (e.g. Cygwin's
5977 file_name_only = full_path_name; 6131 POSIX implementation) may not the same as the encoding expected
5978 else 6132 by the Windows API! */
5979 file_name_only++;
5980 6133
5981 strncpy (filename, file_name_only, MAX_PATH); 6134 CHECK_STRING (prompt);
5982 filename[MAX_PATH] = '\0'; 6135 CHECK_STRING (dir);
5983 }
5984 else
5985 filename[0] = '\0';
5986 6136
5987 /* The code in file_dialog_callback that attempts to set the text 6137 dir = Fexpand_file_name (dir, Qnil);
5988 of the file name edit window when handling the CDN_INITDONE
5989 WM_NOTIFY message does not work. Setting filename to "Current
5990 Directory" in the only_dir_p case here does work however. */
5991 if (filename[0] == 0 && ! NILP (only_dir_p))
5992 strcpy (filename, "Current Directory");
5993 6138
5994 { 6139 if (STRINGP (filename))
5995 NEWOPENFILENAME new_file_details; 6140 filename = Ffile_name_nondirectory (filename);
5996 BOOL file_opened = FALSE; 6141 else
5997 OPENFILENAME * file_details = &new_file_details.real_details; 6142 filename = empty_unibyte_string;
5998 6143
5999 /* Prevent redisplay. */ 6144#ifdef CYGWIN
6000 specbind (Qinhibit_redisplay, Qt); 6145 dir = Fcygwin_convert_path_to_windows (dir, Qt);
6001 block_input (); 6146 if (SCHARS (filename) > 0)
6147 filename = Fcygwin_convert_path_to_windows (filename, Qnil);
6148#endif
6002 6149
6150 CHECK_STRING (dir);
6151 CHECK_STRING (filename);
6152
6153 /* The code in file_dialog_callback that attempts to set the text
6154 of the file name edit window when handling the CDN_INITDONE
6155 WM_NOTIFY message does not work. Setting filename to "Current
6156 Directory" in the only_dir_p case here does work however. */
6157 if (SCHARS (filename) == 0 && ! NILP (only_dir_p))
6158 filename = build_string ("Current Directory");
6159
6160 /* Convert the values we've computed so far to system form. */
6161#ifdef NTGUI_UNICODE
6162 to_unicode (prompt, &prompt);
6163 to_unicode (dir, &dir);
6164 to_unicode (filename, &filename);
6165#else /* !NTGUI_UNICODE */
6166 prompt = ENCODE_FILE (prompt);
6167 dir = ENCODE_FILE (dir);
6168 filename = ENCODE_FILE (filename);
6169
6170 /* We modify these in-place, so make copies for safety. */
6171 dir = Fcopy_sequence (dir);
6172 unixtodos_filename (SDATA (dir));
6173 filename = Fcopy_sequence (filename);
6174 unixtodos_filename (SDATA (filename));
6175#endif /* NTGUI_UNICODE */
6176
6177 /* Fill in the structure for the call to GetOpenFileName below. For
6178 NTGUI_UNICODE builds (which run only on NT), we just use the
6179 actual size of the structure. For non-NTGUI_UNICODE builds, we
6180 tell the OS we're using an old version of the structure if it's not
6181 new enough to support the newer version. */
6003 memset (&new_file_details, 0, sizeof (new_file_details)); 6182 memset (&new_file_details, 0, sizeof (new_file_details));
6004 /* Apparently NT4 crashes if you give it an unexpected size. 6183
6005 I'm not sure about Windows 9x, so play it safe. */
6006 if (w32_major_version > 4 && w32_major_version < 95) 6184 if (w32_major_version > 4 && w32_major_version < 95)
6007 file_details->lStructSize = sizeof (NEWOPENFILENAME); 6185 file_details->lStructSize = sizeof (new_file_details);
6008 else 6186 else
6009 file_details->lStructSize = sizeof (OPENFILENAME); 6187 file_details->lStructSize = sizeof (*file_details);
6188
6189 /* Set up the inout parameter for the selected file name. */
6190 if (SBYTES (filename) + 1 > sizeof (filename_buf))
6191 error ("filename too long");
6192
6193 memcpy (filename_buf, SDATA (filename), SBYTES (filename) + 1);
6194 file_details->lpstrFile = filename_buf;
6195 file_details->nMaxFile = sizeof (filename_buf) / sizeof (*filename_buf);
6010 6196
6011 file_details->hwndOwner = FRAME_W32_WINDOW (f); 6197 file_details->hwndOwner = FRAME_W32_WINDOW (f);
6012 /* Undocumented Bug in Common File Dialog: 6198 /* Undocumented Bug in Common File Dialog:
6013 If a filter is not specified, shell links are not resolved. */ 6199 If a filter is not specified, shell links are not resolved. */
6014 file_details->lpstrFilter = "All Files (*.*)\0*.*\0Directories\0*|*\0\0"; 6200 file_details->lpstrFilter = filter;
6015 file_details->lpstrFile = filename; 6201 file_details->lpstrInitialDir = (guichar_t*) SDATA (dir);
6016 file_details->nMaxFile = sizeof (filename); 6202 file_details->lpstrTitle = (guichar_t*) SDATA (prompt);
6017 file_details->lpstrInitialDir = init_dir; 6203 file_details->nFilterIndex = NILP (only_dir_p) ? 1 : 2;
6018 file_details->lpstrTitle = SDATA (prompt);
6019
6020 if (! NILP (only_dir_p))
6021 default_filter_index = 2;
6022
6023 file_details->nFilterIndex = default_filter_index;
6024
6025 file_details->Flags = (OFN_HIDEREADONLY | OFN_NOCHANGEDIR 6204 file_details->Flags = (OFN_HIDEREADONLY | OFN_NOCHANGEDIR
6026 | OFN_EXPLORER | OFN_ENABLEHOOK); 6205 | OFN_EXPLORER | OFN_ENABLEHOOK);
6206
6027 if (!NILP (mustmatch)) 6207 if (!NILP (mustmatch))
6028 { 6208 {
6029 /* Require that the path to the parent directory exists. */ 6209 /* Require that the path to the parent directory exists. */
6030 file_details->Flags |= OFN_PATHMUSTEXIST; 6210 file_details->Flags |= OFN_PATHMUSTEXIST;
6031 /* If we are looking for a file, require that it exists. */ 6211 /* If we are looking for a file, require that it exists. */
6032 if (NILP (only_dir_p)) 6212 if (NILP (only_dir_p))
6033 file_details->Flags |= OFN_FILEMUSTEXIST; 6213 file_details->Flags |= OFN_FILEMUSTEXIST;
6034 } 6214 }
6035 6215
6036 file_details->lpfnHook = (LPOFNHOOKPROC) file_dialog_callback; 6216 {
6037 6217 int count = SPECPDL_INDEX ();
6038 file_opened = GetOpenFileName (file_details); 6218 specbind (Qinhibit_redisplay, Qt);
6219 block_input ();
6220 file_details->lpfnHook = file_dialog_callback;
6039 6221
6040 unblock_input (); 6222#ifdef NTGUI_UNICODE
6223 file_opened = GetOpenFileNameW (file_details);
6224#else /* !NTGUI_UNICODE */
6225 file_opened = GetOpenFileNameA (file_details);
6226#endif /* NTGUI_UNICODE */
6227 unblock_input ();
6228 unbind_to (count, Qnil);
6229 }
6041 6230
6042 if (file_opened) 6231 if (file_opened)
6043 { 6232 {
6044 dostounix_filename (filename); 6233 /* Get an Emacs string from the value Windows gave us. */
6045 6234#ifdef NTGUI_UNICODE
6046 if (file_details->nFilterIndex == 2) 6235 filename = from_unicode (
6047 { 6236 make_unibyte_string (
6048 /* "Directories" selected - strip dummy file name. */ 6237 (char*) filename_buf,
6049 char * last = strrchr (filename, '/'); 6238 /* we get one of the two final 0 bytes for free. */
6050 *last = '\0'; 6239 1 + sizeof (wchar_t) * wcslen (filename_buf)));
6051 } 6240#else /* !NTGUI_UNICODE */
6052 6241 dostounix_filename (filename_buf);
6053 file = DECODE_FILE (build_string (filename)); 6242 filename = DECODE_FILE (build_string (filename_buf));
6243#endif /* NTGUI_UNICODE */
6244
6245#ifdef CYGWIN
6246 filename = Fcygwin_convert_path_from_windows (filename, Qt);
6247#endif /* CYGWIN */
6248
6249 /* Strip the dummy filename off the end of the string if we
6250 added it to select a directory. */
6251 if (file_details->nFilterIndex == 2)
6252 {
6253 filename = Ffile_name_directory (filename);
6254 }
6054 } 6255 }
6055 /* User canceled the dialog without making a selection. */ 6256 /* User canceled the dialog without making a selection. */
6056 else if (!CommDlgExtendedError ()) 6257 else if (!CommDlgExtendedError ())
6057 file = Qnil; 6258 filename = Qnil;
6058 /* An error occurred, fallback on reading from the mini-buffer. */ 6259 /* An error occurred, fallback on reading from the mini-buffer. */
6059 else 6260 else
6060 file = Fcompleting_read (prompt, intern ("read-file-name-internal"), 6261 filename = Fcompleting_read (
6061 dir, mustmatch, dir, Qfile_name_history, 6262 orig_prompt,
6062 default_filename, Qnil); 6263 intern ("read-file-name-internal"),
6264 orig_dir,
6265 mustmatch,
6266 orig_dir,
6267 Qfile_name_history,
6268 default_filename,
6269 Qnil);
6063 6270
6064 file = unbind_to (count, file); 6271 UNGCPRO;
6065 } 6272 }
6066 6273
6067 UNGCPRO;
6068
6069 /* Make "Cancel" equivalent to C-g. */ 6274 /* Make "Cancel" equivalent to C-g. */
6070 if (NILP (file)) 6275 if (NILP (filename))
6071 Fsignal (Qquit, Qnil); 6276 Fsignal (Qquit, Qnil);
6072 6277
6073 return unbind_to (count, file); 6278 RETURN_UNGCPRO (filename);
6074} 6279}
6075 6280
6076 6281
6282#ifdef WINDOWSNT
6077/* Moving files to the system recycle bin. 6283/* Moving files to the system recycle bin.
6078 Used by `move-file-to-trash' instead of the default moving to ~/.Trash */ 6284 Used by `move-file-to-trash' instead of the default moving to ~/.Trash */
6079DEFUN ("system-move-file-to-trash", Fsystem_move_file_to_trash, 6285DEFUN ("system-move-file-to-trash", Fsystem_move_file_to_trash,
@@ -6127,6 +6333,8 @@ DEFUN ("system-move-file-to-trash", Fsystem_move_file_to_trash,
6127 return Qnil; 6333 return Qnil;
6128} 6334}
6129 6335
6336#endif /* WINDOWSNT */
6337
6130 6338
6131/*********************************************************************** 6339/***********************************************************************
6132 w32 specialized functions 6340 w32 specialized functions
@@ -6544,7 +6752,7 @@ The following %-sequences are provided:
6544 else 6752 else
6545 { 6753 {
6546 char buffer[16]; 6754 char buffer[16];
6547 _snprintf (buffer, 16, "%d", system_status.BatteryLifePercent); 6755 snprintf (buffer, 16, "%d", system_status.BatteryLifePercent);
6548 load_percentage = build_string (buffer); 6756 load_percentage = build_string (buffer);
6549 } 6757 }
6550 6758
@@ -6555,18 +6763,18 @@ The following %-sequences are provided:
6555 long m; 6763 long m;
6556 float h; 6764 float h;
6557 char buffer[16]; 6765 char buffer[16];
6558 _snprintf (buffer, 16, "%ld", seconds_left); 6766 snprintf (buffer, 16, "%ld", seconds_left);
6559 seconds = build_string (buffer); 6767 seconds = build_string (buffer);
6560 6768
6561 m = seconds_left / 60; 6769 m = seconds_left / 60;
6562 _snprintf (buffer, 16, "%ld", m); 6770 snprintf (buffer, 16, "%ld", m);
6563 minutes = build_string (buffer); 6771 minutes = build_string (buffer);
6564 6772
6565 h = seconds_left / 3600.0; 6773 h = seconds_left / 3600.0;
6566 _snprintf (buffer, 16, "%3.1f", h); 6774 snprintf (buffer, 16, "%3.1f", h);
6567 hours = build_string (buffer); 6775 hours = build_string (buffer);
6568 6776
6569 _snprintf (buffer, 16, "%ld:%02ld", m / 60, m % 60); 6777 snprintf (buffer, 16, "%ld:%02ld", m / 60, m % 60);
6570 remain = build_string (buffer); 6778 remain = build_string (buffer);
6571 } 6779 }
6572 6780
@@ -6728,10 +6936,10 @@ DEFUN ("default-printer-name", Fdefault_printer_name, Sdefault_printer_name,
6728 { 6936 {
6729 /* a remote printer */ 6937 /* a remote printer */
6730 if (*ppi2->pServerName == '\\') 6938 if (*ppi2->pServerName == '\\')
6731 _snprintf (pname_buf, sizeof (pname_buf), "%s\\%s", ppi2->pServerName, 6939 snprintf (pname_buf, sizeof (pname_buf), "%s\\%s", ppi2->pServerName,
6732 ppi2->pShareName); 6940 ppi2->pShareName);
6733 else 6941 else
6734 _snprintf (pname_buf, sizeof (pname_buf), "\\\\%s\\%s", ppi2->pServerName, 6942 snprintf (pname_buf, sizeof (pname_buf), "\\\\%s\\%s", ppi2->pServerName,
6735 ppi2->pShareName); 6943 ppi2->pShareName);
6736 pname_buf[sizeof (pname_buf) - 1] = '\0'; 6944 pname_buf[sizeof (pname_buf) - 1] = '\0';
6737 } 6945 }
@@ -6750,6 +6958,292 @@ DEFUN ("default-printer-name", Fdefault_printer_name, Sdefault_printer_name,
6750 return build_string (pname_buf); 6958 return build_string (pname_buf);
6751} 6959}
6752 6960
6961
6962/* Equivalent of strerror for W32 error codes. */
6963char *
6964w32_strerror (int error_no)
6965{
6966 static char buf[500];
6967 DWORD ret;
6968
6969 if (error_no == 0)
6970 error_no = GetLastError ();
6971
6972 ret = FormatMessage (FORMAT_MESSAGE_FROM_SYSTEM |
6973 FORMAT_MESSAGE_IGNORE_INSERTS,
6974 NULL,
6975 error_no,
6976 0, /* choose most suitable language */
6977 buf, sizeof (buf), NULL);
6978
6979 while (ret > 0 && (buf[ret - 1] == '\n' ||
6980 buf[ret - 1] == '\r' ))
6981 --ret;
6982 buf[ret] = '\0';
6983 if (!ret)
6984 sprintf (buf, "w32 error %u", error_no);
6985
6986 return buf;
6987}
6988
6989/* For convenience when debugging. */
6990int
6991w32_last_error (void)
6992{
6993 return GetLastError ();
6994}
6995
6996/* Cache information describing the NT system for later use. */
6997void
6998cache_system_info (void)
6999{
7000 union
7001 {
7002 struct info
7003 {
7004 char major;
7005 char minor;
7006 short platform;
7007 } info;
7008 DWORD data;
7009 } version;
7010
7011 /* Cache the version of the operating system. */
7012 version.data = GetVersion ();
7013 w32_major_version = version.info.major;
7014 w32_minor_version = version.info.minor;
7015
7016 if (version.info.platform & 0x8000)
7017 os_subtype = OS_9X;
7018 else
7019 os_subtype = OS_NT;
7020
7021 /* Cache page size, allocation unit, processor type, etc. */
7022 GetSystemInfo (&sysinfo_cache);
7023 syspage_mask = sysinfo_cache.dwPageSize - 1;
7024
7025 /* Cache os info. */
7026 osinfo_cache.dwOSVersionInfoSize = sizeof (OSVERSIONINFO);
7027 GetVersionEx (&osinfo_cache);
7028
7029 w32_build_number = osinfo_cache.dwBuildNumber;
7030 if (os_subtype == OS_9X)
7031 w32_build_number &= 0xffff;
7032
7033 w32_num_mouse_buttons = GetSystemMetrics (SM_CMOUSEBUTTONS);
7034}
7035
7036#ifdef EMACSDEBUG
7037void
7038_DebPrint (const char *fmt, ...)
7039{
7040 char buf[1024];
7041 va_list args;
7042
7043 va_start (args, fmt);
7044 vsprintf (buf, fmt, args);
7045 va_end (args);
7046#if CYGWIN
7047 fprintf (stderr, "%s", buf);
7048#endif
7049 OutputDebugString (buf);
7050}
7051#endif
7052
7053int
7054w32_console_toggle_lock_key (int vk_code, Lisp_Object new_state)
7055{
7056 int cur_state = (GetKeyState (vk_code) & 1);
7057
7058 if (NILP (new_state)
7059 || (NUMBERP (new_state)
7060 && ((XUINT (new_state)) & 1) != cur_state))
7061 {
7062#ifdef WINDOWSNT
7063 faked_key = vk_code;
7064#endif /* WINDOWSNT */
7065
7066 keybd_event ((BYTE) vk_code,
7067 (BYTE) MapVirtualKey (vk_code, 0),
7068 KEYEVENTF_EXTENDEDKEY | KEYEVENTF_KEYUP, 0);
7069 keybd_event ((BYTE) vk_code,
7070 (BYTE) MapVirtualKey (vk_code, 0),
7071 KEYEVENTF_EXTENDEDKEY | 0, 0);
7072 keybd_event ((BYTE) vk_code,
7073 (BYTE) MapVirtualKey (vk_code, 0),
7074 KEYEVENTF_EXTENDEDKEY | KEYEVENTF_KEYUP, 0);
7075 cur_state = !cur_state;
7076 }
7077
7078 return cur_state;
7079}
7080
7081/* Translate console modifiers to emacs modifiers.
7082 German keyboard support (Kai Morgan Zeise 2/18/95). */
7083int
7084w32_kbd_mods_to_emacs (DWORD mods, WORD key)
7085{
7086 int retval = 0;
7087
7088 /* If we recognize right-alt and left-ctrl as AltGr, and it has been
7089 pressed, first remove those modifiers. */
7090 if (!NILP (Vw32_recognize_altgr)
7091 && (mods & (RIGHT_ALT_PRESSED | LEFT_CTRL_PRESSED))
7092 == (RIGHT_ALT_PRESSED | LEFT_CTRL_PRESSED))
7093 mods &= ~ (RIGHT_ALT_PRESSED | LEFT_CTRL_PRESSED);
7094
7095 if (mods & (RIGHT_ALT_PRESSED | LEFT_ALT_PRESSED))
7096 retval = ((NILP (Vw32_alt_is_meta)) ? alt_modifier : meta_modifier);
7097
7098 if (mods & (RIGHT_CTRL_PRESSED | LEFT_CTRL_PRESSED))
7099 {
7100 retval |= ctrl_modifier;
7101 if ((mods & (RIGHT_CTRL_PRESSED | LEFT_CTRL_PRESSED))
7102 == (RIGHT_CTRL_PRESSED | LEFT_CTRL_PRESSED))
7103 retval |= meta_modifier;
7104 }
7105
7106 if (mods & LEFT_WIN_PRESSED)
7107 retval |= w32_key_to_modifier (VK_LWIN);
7108 if (mods & RIGHT_WIN_PRESSED)
7109 retval |= w32_key_to_modifier (VK_RWIN);
7110 if (mods & APPS_PRESSED)
7111 retval |= w32_key_to_modifier (VK_APPS);
7112 if (mods & SCROLLLOCK_ON)
7113 retval |= w32_key_to_modifier (VK_SCROLL);
7114
7115 /* Just in case someone wanted the original behavior, make it
7116 optional by setting w32-capslock-is-shiftlock to t. */
7117 if (NILP (Vw32_capslock_is_shiftlock)
7118 /* Keys that should _not_ be affected by CapsLock. */
7119 && ( (key == VK_BACK)
7120 || (key == VK_TAB)
7121 || (key == VK_CLEAR)
7122 || (key == VK_RETURN)
7123 || (key == VK_ESCAPE)
7124 || ((key >= VK_SPACE) && (key <= VK_HELP))
7125 || ((key >= VK_NUMPAD0) && (key <= VK_F24))
7126 || ((key >= VK_NUMPAD_CLEAR) && (key <= VK_NUMPAD_DELETE))
7127 ))
7128 {
7129 /* Only consider shift state. */
7130 if ((mods & SHIFT_PRESSED) != 0)
7131 retval |= shift_modifier;
7132 }
7133 else
7134 {
7135 /* Ignore CapsLock state if not enabled. */
7136 if (NILP (Vw32_enable_caps_lock))
7137 mods &= ~CAPSLOCK_ON;
7138 if ((mods & (SHIFT_PRESSED | CAPSLOCK_ON)) != 0)
7139 retval |= shift_modifier;
7140 }
7141
7142 return retval;
7143}
7144
7145/* The return code indicates key code size. cpID is the codepage to
7146 use for translation to Unicode; -1 means use the current console
7147 input codepage. */
7148int
7149w32_kbd_patch_key (KEY_EVENT_RECORD *event, int cpId)
7150{
7151 unsigned int key_code = event->wVirtualKeyCode;
7152 unsigned int mods = event->dwControlKeyState;
7153 BYTE keystate[256];
7154 static BYTE ansi_code[4];
7155 static int isdead = 0;
7156
7157 if (isdead == 2)
7158 {
7159 event->uChar.AsciiChar = ansi_code[2];
7160 isdead = 0;
7161 return 1;
7162 }
7163 if (event->uChar.AsciiChar != 0)
7164 return 1;
7165
7166 memset (keystate, 0, sizeof (keystate));
7167 keystate[key_code] = 0x80;
7168 if (mods & SHIFT_PRESSED)
7169 keystate[VK_SHIFT] = 0x80;
7170 if (mods & CAPSLOCK_ON)
7171 keystate[VK_CAPITAL] = 1;
7172 /* If we recognize right-alt and left-ctrl as AltGr, set the key
7173 states accordingly before invoking ToAscii. */
7174 if (!NILP (Vw32_recognize_altgr)
7175 && (mods & LEFT_CTRL_PRESSED) && (mods & RIGHT_ALT_PRESSED))
7176 {
7177 keystate[VK_CONTROL] = 0x80;
7178 keystate[VK_LCONTROL] = 0x80;
7179 keystate[VK_MENU] = 0x80;
7180 keystate[VK_RMENU] = 0x80;
7181 }
7182
7183#if 0
7184 /* Because of an OS bug, ToAscii corrupts the stack when called to
7185 convert a dead key in console mode on NT4. Unfortunately, trying
7186 to check for dead keys using MapVirtualKey doesn't work either -
7187 these functions apparently use internal information about keyboard
7188 layout which doesn't get properly updated in console programs when
7189 changing layout (though apparently it gets partly updated,
7190 otherwise ToAscii wouldn't crash). */
7191 if (is_dead_key (event->wVirtualKeyCode))
7192 return 0;
7193#endif
7194
7195 /* On NT, call ToUnicode instead and then convert to the current
7196 console input codepage. */
7197 if (os_subtype == OS_NT)
7198 {
7199 WCHAR buf[128];
7200
7201 isdead = ToUnicode (event->wVirtualKeyCode, event->wVirtualScanCode,
7202 keystate, buf, 128, 0);
7203 if (isdead > 0)
7204 {
7205 /* When we are called from the GUI message processing code,
7206 we are passed the current keyboard codepage, a positive
7207 number, to use below. */
7208 if (cpId == -1)
7209 cpId = GetConsoleCP ();
7210
7211 event->uChar.UnicodeChar = buf[isdead - 1];
7212 isdead = WideCharToMultiByte (cpId, 0, buf, isdead,
7213 ansi_code, 4, NULL, NULL);
7214 }
7215 else
7216 isdead = 0;
7217 }
7218 else
7219 {
7220 isdead = ToAscii (event->wVirtualKeyCode, event->wVirtualScanCode,
7221 keystate, (LPWORD) ansi_code, 0);
7222 }
7223
7224 if (isdead == 0)
7225 return 0;
7226 event->uChar.AsciiChar = ansi_code[0];
7227 return isdead;
7228}
7229
7230
7231void
7232w32_sys_ring_bell (struct frame *f)
7233{
7234 if (sound_type == 0xFFFFFFFF)
7235 {
7236 Beep (666, 100);
7237 }
7238 else if (sound_type == MB_EMACS_SILENT)
7239 {
7240 /* Do nothing. */
7241 }
7242 else
7243 MessageBeep (sound_type);
7244}
7245
7246
6753/*********************************************************************** 7247/***********************************************************************
6754 Initialization 7248 Initialization
6755 ***********************************************************************/ 7249 ***********************************************************************/
@@ -7116,6 +7610,7 @@ only be necessary if the default setting causes problems. */);
7116 7610
7117 defsubr (&Sfile_system_info); 7611 defsubr (&Sfile_system_info);
7118 defsubr (&Sdefault_printer_name); 7612 defsubr (&Sdefault_printer_name);
7613 defsubr (&Sset_message_beep);
7119 7614
7120 check_window_system_func = check_w32; 7615 check_window_system_func = check_w32;
7121 7616
@@ -7132,7 +7627,9 @@ only be necessary if the default setting causes problems. */);
7132 staticpro (&last_show_tip_args); 7627 staticpro (&last_show_tip_args);
7133 7628
7134 defsubr (&Sx_file_dialog); 7629 defsubr (&Sx_file_dialog);
7630#ifdef WINDOWSNT
7135 defsubr (&Ssystem_move_file_to_trash); 7631 defsubr (&Ssystem_move_file_to_trash);
7632#endif
7136} 7633}
7137 7634
7138 7635
@@ -7214,9 +7711,3 @@ emacs_abort (void)
7214 } 7711 }
7215} 7712}
7216 7713
7217/* For convenience when debugging. */
7218int
7219w32_last_error (void)
7220{
7221 return GetLastError ();
7222}
diff --git a/src/w32font.c b/src/w32font.c
index 833b7cdfb25..d7d25d89939 100644
--- a/src/w32font.c
+++ b/src/w32font.c
@@ -18,6 +18,7 @@ along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. */
18 18
19#include <config.h> 19#include <config.h>
20#include <windows.h> 20#include <windows.h>
21#include <stdio.h>
21#include <math.h> 22#include <math.h>
22#include <ctype.h> 23#include <ctype.h>
23#include <commdlg.h> 24#include <commdlg.h>
@@ -1434,6 +1435,9 @@ w32font_coverage_ok (FONTSIGNATURE * coverage, BYTE charset)
1434 return 1; 1435 return 1;
1435} 1436}
1436 1437
1438#ifndef WINDOWSNT
1439#define _strlwr strlwr
1440#endif /* !WINDOWSNT */
1437 1441
1438static int 1442static int
1439check_face_name (LOGFONT *font, char *full_name) 1443check_face_name (LOGFONT *font, char *full_name)
diff --git a/src/w32heap.c b/src/w32heap.c
index 8b9b19ea35d..0ff473fb0a8 100644
--- a/src/w32heap.c
+++ b/src/w32heap.c
@@ -32,10 +32,9 @@ along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. */
32SYSTEM_INFO sysinfo_cache; 32SYSTEM_INFO sysinfo_cache;
33 33
34/* This gives us version, build, and platform identification. */ 34/* This gives us version, build, and platform identification. */
35extern unsigned long syspage_mask;
35OSVERSIONINFO osinfo_cache; 36OSVERSIONINFO osinfo_cache;
36 37
37size_t syspage_mask = 0;
38
39/* The major and minor versions of NT. */ 38/* The major and minor versions of NT. */
40int w32_major_version; 39int w32_major_version;
41int w32_minor_version; 40int w32_minor_version;
@@ -44,44 +43,6 @@ int w32_build_number;
44/* Distinguish between Windows NT and Windows 95. */ 43/* Distinguish between Windows NT and Windows 95. */
45int os_subtype; 44int os_subtype;
46 45
47/* Cache information describing the NT system for later use. */
48void
49cache_system_info (void)
50{
51 union
52 {
53 struct info
54 {
55 char major;
56 char minor;
57 short platform;
58 } info;
59 DWORD data;
60 } version;
61
62 /* Cache the version of the operating system. */
63 version.data = GetVersion ();
64 w32_major_version = version.info.major;
65 w32_minor_version = version.info.minor;
66
67 if (version.info.platform & 0x8000)
68 os_subtype = OS_9X;
69 else
70 os_subtype = OS_NT;
71
72 /* Cache page size, allocation unit, processor type, etc. */
73 GetSystemInfo (&sysinfo_cache);
74 syspage_mask = sysinfo_cache.dwPageSize - 1;
75
76 /* Cache os info. */
77 osinfo_cache.dwOSVersionInfoSize = sizeof (OSVERSIONINFO);
78 GetVersionEx (&osinfo_cache);
79
80 w32_build_number = osinfo_cache.dwBuildNumber;
81 if (os_subtype == OS_9X)
82 w32_build_number &= 0xffff;
83}
84
85/* Emulate getpagesize. */ 46/* Emulate getpagesize. */
86int 47int
87getpagesize (void) 48getpagesize (void)
diff --git a/src/w32inevt.c b/src/w32inevt.c
index ebb95dcace5..c322d3a0b44 100644
--- a/src/w32inevt.c
+++ b/src/w32inevt.c
@@ -70,6 +70,9 @@ w32_read_console_input (HANDLE h, INPUT_RECORD *rec, DWORD recsize,
70 : ReadConsoleInputA (h, rec, recsize, waiting)); 70 : ReadConsoleInputA (h, rec, recsize, waiting));
71} 71}
72 72
73/* Set by w32_console_toggle_lock_key. */
74int faked_key;
75
73static int 76static int
74fill_queue (BOOL block) 77fill_queue (BOOL block)
75{ 78{
@@ -110,67 +113,7 @@ get_frame (void)
110 113
111/* Translate console modifiers to emacs modifiers. 114/* Translate console modifiers to emacs modifiers.
112 German keyboard support (Kai Morgan Zeise 2/18/95). */ 115 German keyboard support (Kai Morgan Zeise 2/18/95). */
113int
114w32_kbd_mods_to_emacs (DWORD mods, WORD key)
115{
116 int retval = 0;
117
118 /* If we recognize right-alt and left-ctrl as AltGr, and it has been
119 pressed, first remove those modifiers. */
120 if (!NILP (Vw32_recognize_altgr)
121 && (mods & (RIGHT_ALT_PRESSED | LEFT_CTRL_PRESSED))
122 == (RIGHT_ALT_PRESSED | LEFT_CTRL_PRESSED))
123 mods &= ~ (RIGHT_ALT_PRESSED | LEFT_CTRL_PRESSED);
124 116
125 if (mods & (RIGHT_ALT_PRESSED | LEFT_ALT_PRESSED))
126 retval = ((NILP (Vw32_alt_is_meta)) ? alt_modifier : meta_modifier);
127
128 if (mods & (RIGHT_CTRL_PRESSED | LEFT_CTRL_PRESSED))
129 {
130 retval |= ctrl_modifier;
131 if ((mods & (RIGHT_CTRL_PRESSED | LEFT_CTRL_PRESSED))
132 == (RIGHT_CTRL_PRESSED | LEFT_CTRL_PRESSED))
133 retval |= meta_modifier;
134 }
135
136 if (mods & LEFT_WIN_PRESSED)
137 retval |= w32_key_to_modifier (VK_LWIN);
138 if (mods & RIGHT_WIN_PRESSED)
139 retval |= w32_key_to_modifier (VK_RWIN);
140 if (mods & APPS_PRESSED)
141 retval |= w32_key_to_modifier (VK_APPS);
142 if (mods & SCROLLLOCK_ON)
143 retval |= w32_key_to_modifier (VK_SCROLL);
144
145 /* Just in case someone wanted the original behavior, make it
146 optional by setting w32-capslock-is-shiftlock to t. */
147 if (NILP (Vw32_capslock_is_shiftlock)
148 /* Keys that should _not_ be affected by CapsLock. */
149 && ( (key == VK_BACK)
150 || (key == VK_TAB)
151 || (key == VK_CLEAR)
152 || (key == VK_RETURN)
153 || (key == VK_ESCAPE)
154 || ((key >= VK_SPACE) && (key <= VK_HELP))
155 || ((key >= VK_NUMPAD0) && (key <= VK_F24))
156 || ((key >= VK_NUMPAD_CLEAR) && (key <= VK_NUMPAD_DELETE))
157 ))
158 {
159 /* Only consider shift state. */
160 if ((mods & SHIFT_PRESSED) != 0)
161 retval |= shift_modifier;
162 }
163 else
164 {
165 /* Ignore CapsLock state if not enabled. */
166 if (NILP (Vw32_enable_caps_lock))
167 mods &= ~CAPSLOCK_ON;
168 if ((mods & (SHIFT_PRESSED | CAPSLOCK_ON)) != 0)
169 retval |= shift_modifier;
170 }
171
172 return retval;
173}
174 117
175#if 0 118#if 0
176/* Return nonzero if the virtual key is a dead key. */ 119/* Return nonzero if the virtual key is a dead key. */
@@ -187,90 +130,7 @@ is_dead_key (int wparam)
187/* The return code indicates key code size. cpID is the codepage to 130/* The return code indicates key code size. cpID is the codepage to
188 use for translation to Unicode; -1 means use the current console 131 use for translation to Unicode; -1 means use the current console
189 input codepage. */ 132 input codepage. */
190int
191w32_kbd_patch_key (KEY_EVENT_RECORD *event, int cpId)
192{
193 unsigned int key_code = event->wVirtualKeyCode;
194 unsigned int mods = event->dwControlKeyState;
195 BYTE keystate[256];
196 static BYTE ansi_code[4];
197 static int isdead = 0;
198 133
199 if (isdead == 2)
200 {
201 event->uChar.AsciiChar = ansi_code[2];
202 isdead = 0;
203 return 1;
204 }
205 if (event->uChar.AsciiChar != 0)
206 return 1;
207
208 memset (keystate, 0, sizeof (keystate));
209 keystate[key_code] = 0x80;
210 if (mods & SHIFT_PRESSED)
211 keystate[VK_SHIFT] = 0x80;
212 if (mods & CAPSLOCK_ON)
213 keystate[VK_CAPITAL] = 1;
214 /* If we recognize right-alt and left-ctrl as AltGr, set the key
215 states accordingly before invoking ToAscii. */
216 if (!NILP (Vw32_recognize_altgr)
217 && (mods & LEFT_CTRL_PRESSED) && (mods & RIGHT_ALT_PRESSED))
218 {
219 keystate[VK_CONTROL] = 0x80;
220 keystate[VK_LCONTROL] = 0x80;
221 keystate[VK_MENU] = 0x80;
222 keystate[VK_RMENU] = 0x80;
223 }
224
225#if 0
226 /* Because of an OS bug, ToAscii corrupts the stack when called to
227 convert a dead key in console mode on NT4. Unfortunately, trying
228 to check for dead keys using MapVirtualKey doesn't work either -
229 these functions apparently use internal information about keyboard
230 layout which doesn't get properly updated in console programs when
231 changing layout (though apparently it gets partly updated,
232 otherwise ToAscii wouldn't crash). */
233 if (is_dead_key (event->wVirtualKeyCode))
234 return 0;
235#endif
236
237 /* On NT, call ToUnicode instead and then convert to the current
238 console input codepage. */
239 if (os_subtype == OS_NT)
240 {
241 WCHAR buf[128];
242
243 isdead = ToUnicode (event->wVirtualKeyCode, event->wVirtualScanCode,
244 keystate, buf, 128, 0);
245 if (isdead > 0)
246 {
247 /* When we are called from the GUI message processing code,
248 we are passed the current keyboard codepage, a positive
249 number, to use below. */
250 if (cpId == -1)
251 cpId = GetConsoleCP ();
252
253 event->uChar.UnicodeChar = buf[isdead - 1];
254 isdead = WideCharToMultiByte (cpId, 0, buf, isdead,
255 ansi_code, 4, NULL, NULL);
256 }
257 else
258 isdead = 0;
259 }
260 else
261 {
262 isdead = ToAscii (event->wVirtualKeyCode, event->wVirtualScanCode,
263 keystate, (LPWORD) ansi_code, 0);
264 }
265
266 if (isdead == 0)
267 return 0;
268 event->uChar.AsciiChar = ansi_code[0];
269 return isdead;
270}
271
272
273static int faked_key = 0;
274 134
275/* return code -1 means that event_queue_ptr won't be incremented. 135/* return code -1 means that event_queue_ptr won't be incremented.
276 In other word, this event makes two key codes. (by himi) */ 136 In other word, this event makes two key codes. (by himi) */
@@ -531,32 +391,6 @@ key_event (KEY_EVENT_RECORD *event, struct input_event *emacs_ev, int *isdead)
531 return 1; 391 return 1;
532} 392}
533 393
534int
535w32_console_toggle_lock_key (int vk_code, Lisp_Object new_state)
536{
537 int cur_state = (GetKeyState (vk_code) & 1);
538
539 if (NILP (new_state)
540 || (NUMBERP (new_state)
541 && ((XUINT (new_state)) & 1) != cur_state))
542 {
543 faked_key = vk_code;
544
545 keybd_event ((BYTE) vk_code,
546 (BYTE) MapVirtualKey (vk_code, 0),
547 KEYEVENTF_EXTENDEDKEY | KEYEVENTF_KEYUP, 0);
548 keybd_event ((BYTE) vk_code,
549 (BYTE) MapVirtualKey (vk_code, 0),
550 KEYEVENTF_EXTENDEDKEY | 0, 0);
551 keybd_event ((BYTE) vk_code,
552 (BYTE) MapVirtualKey (vk_code, 0),
553 KEYEVENTF_EXTENDEDKEY | KEYEVENTF_KEYUP, 0);
554 cur_state = !cur_state;
555 }
556
557 return cur_state;
558}
559
560/* Mouse position hook. */ 394/* Mouse position hook. */
561void 395void
562w32_console_mouse_position (FRAME_PTR *f, 396w32_console_mouse_position (FRAME_PTR *f,
diff --git a/src/w32menu.c b/src/w32menu.c
index 0a10f1f0893..40ee82d42d5 100644
--- a/src/w32menu.c
+++ b/src/w32menu.c
@@ -21,7 +21,7 @@ along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. */
21 21
22#include <signal.h> 22#include <signal.h>
23#include <stdio.h> 23#include <stdio.h>
24#include <mbstring.h> 24#include <setjmp.h>
25 25
26#include "lisp.h" 26#include "lisp.h"
27#include "keyboard.h" 27#include "keyboard.h"
@@ -40,6 +40,14 @@ along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. */
40 if this is not done before the other system files. */ 40 if this is not done before the other system files. */
41#include "w32term.h" 41#include "w32term.h"
42 42
43/* Cygwin does not support the multibyte string functions declared in
44 * mbstring.h below --- but that's okay: because Cygwin is
45 * UNICODE-only, we don't need to use these functions anyway. */
46
47#ifndef NTGUI_UNICODE
48#include <mbstring.h>
49#endif /* !NTGUI_UNICODE */
50
43/* Load sys/types.h if not already loaded. 51/* Load sys/types.h if not already loaded.
44 In some systems loading it twice is suicidal. */ 52 In some systems loading it twice is suicidal. */
45#ifndef makedev 53#ifndef makedev
@@ -78,10 +86,17 @@ typedef int (WINAPI * MessageBoxW_Proc) (
78 IN WCHAR *caption, 86 IN WCHAR *caption,
79 IN UINT type); 87 IN UINT type);
80 88
89#ifdef NTGUI_UNICODE
90#define get_menu_item_info GetMenuItemInfoA
91#define set_menu_item_info SetMenuItemInfoA
92#define unicode_append_menu AppendMenuW
93#define unicode_message_box MessageBoxW
94#else /* !NTGUI_UNICODE */
81GetMenuItemInfoA_Proc get_menu_item_info = NULL; 95GetMenuItemInfoA_Proc get_menu_item_info = NULL;
82SetMenuItemInfoA_Proc set_menu_item_info = NULL; 96SetMenuItemInfoA_Proc set_menu_item_info = NULL;
83AppendMenuW_Proc unicode_append_menu = NULL; 97AppendMenuW_Proc unicode_append_menu = NULL;
84MessageBoxW_Proc unicode_message_box = NULL; 98MessageBoxW_Proc unicode_message_box = NULL;
99#endif /* NTGUI_UNICODE */
85 100
86Lisp_Object Qdebug_on_next_call; 101Lisp_Object Qdebug_on_next_call;
87 102
@@ -98,6 +113,7 @@ static void utf8to16 (unsigned char *, int, WCHAR *);
98static int fill_in_menu (HMENU, widget_value *); 113static int fill_in_menu (HMENU, widget_value *);
99 114
100void w32_free_menu_strings (HWND); 115void w32_free_menu_strings (HWND);
116
101 117
102 118
103/* This is set nonzero after the user activates the menu bar, and set 119/* This is set nonzero after the user activates the menu bar, and set
@@ -1405,6 +1421,7 @@ add_menu_item (HMENU menu, widget_value *wv, HMENU item)
1405 nlen++; 1421 nlen++;
1406 } 1422 }
1407 } 1423 }
1424#ifndef NTGUI_UNICODE
1408 else 1425 else
1409 { 1426 {
1410 /* If encoded with the system codepage, use multibyte string 1427 /* If encoded with the system codepage, use multibyte string
@@ -1415,6 +1432,7 @@ add_menu_item (HMENU menu, widget_value *wv, HMENU item)
1415 nlen++; 1432 nlen++;
1416 } 1433 }
1417 } 1434 }
1435#endif /* !NTGUI_UNICODE */
1418 1436
1419 if (nlen > orig_len) 1437 if (nlen > orig_len)
1420 { 1438 {
@@ -1429,6 +1447,7 @@ add_menu_item (HMENU menu, widget_value *wv, HMENU item)
1429 *q++ = *p; 1447 *q++ = *p;
1430 *q++ = *p++; 1448 *q++ = *p++;
1431 } 1449 }
1450#ifndef NTGUI_UNICODE
1432 else 1451 else
1433 { 1452 {
1434 if (_mbsnextc (p) == '&') 1453 if (_mbsnextc (p) == '&')
@@ -1440,6 +1459,7 @@ add_menu_item (HMENU menu, widget_value *wv, HMENU item)
1440 p = _mbsinc (p); 1459 p = _mbsinc (p);
1441 q = _mbsinc (q); 1460 q = _mbsinc (q);
1442 } 1461 }
1462#endif /* !NTGUI_UNICODE */
1443 } 1463 }
1444 *q = '\0'; 1464 *q = '\0';
1445 } 1465 }
@@ -1486,6 +1506,8 @@ add_menu_item (HMENU menu, widget_value *wv, HMENU item)
1486 item != NULL ? (UINT_PTR) item 1506 item != NULL ? (UINT_PTR) item
1487 : (UINT_PTR) wv->call_data, 1507 : (UINT_PTR) wv->call_data,
1488 utf16_string); 1508 utf16_string);
1509
1510#ifndef NTGUI_UNICODE /* Fallback does not apply when always UNICODE */
1489 if (!return_value) 1511 if (!return_value)
1490 { 1512 {
1491 /* On W9x/ME, Unicode menus are not supported, though AppendMenuW 1513 /* On W9x/ME, Unicode menus are not supported, though AppendMenuW
@@ -1504,6 +1526,7 @@ add_menu_item (HMENU menu, widget_value *wv, HMENU item)
1504 if (osinfo_cache.dwPlatformId != VER_PLATFORM_WIN32_NT) 1526 if (osinfo_cache.dwPlatformId != VER_PLATFORM_WIN32_NT)
1505 unicode_append_menu = NULL; 1527 unicode_append_menu = NULL;
1506 } 1528 }
1529#endif /* NTGUI_UNICODE */
1507 1530
1508 if (unicode_append_menu && (fuFlags & MF_OWNERDRAW)) 1531 if (unicode_append_menu && (fuFlags & MF_OWNERDRAW))
1509 local_free (out_string); 1532 local_free (out_string);
@@ -1723,10 +1746,12 @@ syms_of_w32menu (void)
1723void 1746void
1724globals_of_w32menu (void) 1747globals_of_w32menu (void)
1725{ 1748{
1749#ifndef NTGUI_UNICODE
1726 /* See if Get/SetMenuItemInfo functions are available. */ 1750 /* See if Get/SetMenuItemInfo functions are available. */
1727 HMODULE user32 = GetModuleHandle ("user32.dll"); 1751 HMODULE user32 = GetModuleHandle ("user32.dll");
1728 get_menu_item_info = (GetMenuItemInfoA_Proc) GetProcAddress (user32, "GetMenuItemInfoA"); 1752 get_menu_item_info = (GetMenuItemInfoA_Proc) GetProcAddress (user32, "GetMenuItemInfoA");
1729 set_menu_item_info = (SetMenuItemInfoA_Proc) GetProcAddress (user32, "SetMenuItemInfoA"); 1753 set_menu_item_info = (SetMenuItemInfoA_Proc) GetProcAddress (user32, "SetMenuItemInfoA");
1730 unicode_append_menu = (AppendMenuW_Proc) GetProcAddress (user32, "AppendMenuW"); 1754 unicode_append_menu = (AppendMenuW_Proc) GetProcAddress (user32, "AppendMenuW");
1731 unicode_message_box = (MessageBoxW_Proc) GetProcAddress (user32, "MessageBoxW"); 1755 unicode_message_box = (MessageBoxW_Proc) GetProcAddress (user32, "MessageBoxW");
1756#endif /* !NTGUI_UNICODE */
1732} 1757}
diff --git a/src/w32proc.c b/src/w32proc.c
index d032b21c59e..7d0039d0d5e 100644
--- a/src/w32proc.c
+++ b/src/w32proc.c
@@ -67,20 +67,6 @@ extern BOOL WINAPI IsValidLocale (LCID, DWORD);
67 67
68Lisp_Object Qhigh, Qlow; 68Lisp_Object Qhigh, Qlow;
69 69
70#ifdef EMACSDEBUG
71void
72_DebPrint (const char *fmt, ...)
73{
74 char buf[1024];
75 va_list args;
76
77 va_start (args, fmt);
78 vsprintf (buf, fmt, args);
79 va_end (args);
80 OutputDebugString (buf);
81}
82#endif
83
84typedef void (_CALLBACK_ *signal_handler) (int); 70typedef void (_CALLBACK_ *signal_handler) (int);
85 71
86/* Signal handlers...SIG_DFL == 0 so this is initialized correctly. */ 72/* Signal handlers...SIG_DFL == 0 so this is initialized correctly. */
diff --git a/src/w32select.c b/src/w32select.c
index 66f9f7ab041..1690c3b7824 100644
--- a/src/w32select.c
+++ b/src/w32select.c
@@ -81,6 +81,11 @@ along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. */
81#include "coding.h" 81#include "coding.h"
82#include "composite.h" 82#include "composite.h"
83 83
84#ifdef CYGWIN
85#include <string.h>
86#include <stdio.h>
87#define _memccpy memccpy
88#endif
84 89
85static HGLOBAL convert_to_handle_as_ascii (void); 90static HGLOBAL convert_to_handle_as_ascii (void);
86static HGLOBAL convert_to_handle_as_coded (Lisp_Object coding_system); 91static HGLOBAL convert_to_handle_as_coded (Lisp_Object coding_system);
diff --git a/src/w32select.h b/src/w32select.h
new file mode 100644
index 00000000000..6924d4d51ae
--- /dev/null
+++ b/src/w32select.h
@@ -0,0 +1,30 @@
1/* Selection processing for Emacs on the Microsoft W32 API.
2
3Copyright (C) 1993-1994, 2001-2011 Free Software Foundation, Inc.
4
5This file is part of GNU Emacs.
6
7GNU Emacs is free software: you can redistribute it and/or modify
8it under the terms of the GNU General Public License as published by
9the Free Software Foundation, either version 3 of the License, or
10(at your option) any later version.
11
12GNU Emacs is distributed in the hope that it will be useful,
13but WITHOUT ANY WARRANTY; without even the implied warranty of
14MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15GNU General Public License for more details.
16
17You should have received a copy of the GNU General Public License
18along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. */
19
20#ifndef W32SELECT_H
21#define W32SELECT_H
22#include <windows.h>
23
24#define HAVE_W32SELECT 1
25
26extern void syms_of_w32select (void);
27extern void globals_of_w32select (void);
28extern void term_w32select (void);
29
30#endif
diff --git a/src/w32term.c b/src/w32term.c
index 517813672c4..627ff54394b 100644
--- a/src/w32term.c
+++ b/src/w32term.c
@@ -51,7 +51,14 @@ along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. */
51#include "atimer.h" 51#include "atimer.h"
52#include "keymap.h" 52#include "keymap.h"
53 53
54#ifdef WINDOWSNT
54#include "w32heap.h" 55#include "w32heap.h"
56#endif
57
58#ifndef WINDOWSNT
59#include <io.h> /* for get_osfhandle */
60#endif
61
55#include <shellapi.h> 62#include <shellapi.h>
56 63
57#include "font.h" 64#include "font.h"
@@ -121,7 +128,7 @@ typedef struct tagGLYPHSET
121 WCRANGE ranges[1]; 128 WCRANGE ranges[1];
122} GLYPHSET; 129} GLYPHSET;
123 130
124#endif 131#endif /* compiling for pre-Win2k */
125 132
126/* Dynamic linking to SetLayeredWindowAttribute (only since 2000). */ 133/* Dynamic linking to SetLayeredWindowAttribute (only since 2000). */
127BOOL (WINAPI *pfnSetLayeredWindowAttributes) (HWND, COLORREF, BYTE, DWORD); 134BOOL (WINAPI *pfnSetLayeredWindowAttributes) (HWND, COLORREF, BYTE, DWORD);
@@ -190,6 +197,13 @@ static int volatile input_signal_count;
190static int input_signal_count; 197static int input_signal_count;
191#endif 198#endif
192 199
200#ifdef CYGWIN
201int w32_message_fd = -1;
202#endif /* CYGWIN */
203
204/* Keyboard code page - may be changed by language-change events. */
205static int keyboard_codepage;
206
193static void x_update_window_end (struct window *, int, int); 207static void x_update_window_end (struct window *, int, int);
194static void w32_handle_tool_bar_click (struct frame *, 208static void w32_handle_tool_bar_click (struct frame *,
195 struct input_event *); 209 struct input_event *);
@@ -4163,18 +4177,26 @@ w32_read_socket (struct terminal *terminal,
4163 struct frame *f; 4177 struct frame *f;
4164 struct w32_display_info *dpyinfo = &one_w32_display_info; 4178 struct w32_display_info *dpyinfo = &one_w32_display_info;
4165 Mouse_HLInfo *hlinfo = &dpyinfo->mouse_highlight; 4179 Mouse_HLInfo *hlinfo = &dpyinfo->mouse_highlight;
4180 static char buf[1];
4166 4181
4167 block_input (); 4182 block_input ();
4168 4183
4169 /* So people can tell when we have read the available input. */ 4184 /* So people can tell when we have read the available input. */
4170 input_signal_count++; 4185 input_signal_count++;
4171 4186
4187 /* Process any incoming thread messages. */
4188 drain_message_queue ();
4189
4172 /* TODO: ghostscript integration. */ 4190 /* TODO: ghostscript integration. */
4173 while (get_next_msg (&msg, FALSE)) 4191 while (get_next_msg (&msg, FALSE))
4174 { 4192 {
4175 struct input_event inev; 4193 struct input_event inev;
4176 int do_help = 0; 4194 int do_help = 0;
4177 4195
4196 /* DebPrint (("w32_read_socket: %s time:%u\n", */
4197 /* w32_name_of_message (msg.msg.message), */
4198 /* msg.msg.time)); */
4199
4178 EVENT_INIT (inev); 4200 EVENT_INIT (inev);
4179 inev.kind = NO_EVENT; 4201 inev.kind = NO_EVENT;
4180 inev.arg = Qnil; 4202 inev.arg = Qnil;
@@ -6307,8 +6329,15 @@ w32_term_init (Lisp_Object display_name, char *xrm_option, char *resource_name)
6307 w32_defined_color (0, "black", &color, 1); 6329 w32_defined_color (0, "black", &color, 1);
6308 } 6330 }
6309 6331
6310 /* Add the default keyboard. */ 6332#ifdef WINDOWSNT
6333 /* Add the default keyboard. When !WINDOWSNT, we're using the
6334 standard Emacs console handling machinery and don't need an
6335 explicit FD here. */
6311 add_keyboard_wait_descriptor (0); 6336 add_keyboard_wait_descriptor (0);
6337#elif CYGWIN
6338 /* /dev/windows wakes us up when we have a thread message pending. */
6339 add_keyboard_wait_descriptor (w32_message_fd);
6340#endif
6312 6341
6313 /* Create Fringe Bitmaps and store them for later use. 6342 /* Create Fringe Bitmaps and store them for later use.
6314 6343
@@ -6319,15 +6348,6 @@ w32_term_init (Lisp_Object display_name, char *xrm_option, char *resource_name)
6319 the bitmaps. */ 6348 the bitmaps. */
6320 w32_init_fringe (terminal->rif); 6349 w32_init_fringe (terminal->rif);
6321 6350
6322#ifdef F_SETOWN
6323 fcntl (connection, F_SETOWN, getpid ());
6324#endif /* ! defined (F_SETOWN) */
6325
6326#ifdef SIGIO
6327 if (interrupt_input)
6328 init_sigio (connection);
6329#endif /* ! defined (SIGIO) */
6330
6331 unblock_input (); 6351 unblock_input ();
6332 6352
6333 return dpyinfo; 6353 return dpyinfo;
@@ -6377,6 +6397,7 @@ x_delete_display (struct w32_display_info *dpyinfo)
6377 6397
6378 w32_reset_fringes (); 6398 w32_reset_fringes ();
6379} 6399}
6400
6380 6401
6381/* Set up use of W32. */ 6402/* Set up use of W32. */
6382 6403
@@ -6414,6 +6435,11 @@ w32_initialize (void)
6414 set_user_model (L"GNU.Emacs"); 6435 set_user_model (L"GNU.Emacs");
6415 } 6436 }
6416 6437
6438#ifdef CYGWIN
6439 if ((w32_message_fd = open ("/dev/windows", O_RDWR | O_CLOEXEC)) == -1)
6440 fatal ("opening /dev/windows: %s", strerror (errno));
6441#endif /* CYGWIN */
6442
6417 /* Initialize w32_use_visible_system_caret based on whether a screen 6443 /* Initialize w32_use_visible_system_caret based on whether a screen
6418 reader is in use. */ 6444 reader is in use. */
6419 if (!SystemParametersInfo (SPI_GETSCREENREADER, 0, 6445 if (!SystemParametersInfo (SPI_GETSCREENREADER, 0,
@@ -6574,4 +6600,6 @@ With MS Windows or Nextstep, the value is t. */);
6574 6600
6575 staticpro (&last_mouse_motion_frame); 6601 staticpro (&last_mouse_motion_frame);
6576 last_mouse_motion_frame = Qnil; 6602 last_mouse_motion_frame = Qnil;
6603
6604 Fprovide (intern_c_string ("w32"), Qnil);
6577} 6605}
diff --git a/src/w32term.h b/src/w32term.h
index fcaccc4d624..9fb37b9f030 100644
--- a/src/w32term.h
+++ b/src/w32term.h
@@ -19,6 +19,8 @@ along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. */
19/* Added by Kevin Gallo */ 19/* Added by Kevin Gallo */
20 20
21#include "w32gui.h" 21#include "w32gui.h"
22#include "frame.h"
23#include "atimer.h"
22 24
23 25
24#define BLACK_PIX_DEFAULT(f) PALETTERGB(0,0,0) 26#define BLACK_PIX_DEFAULT(f) PALETTERGB(0,0,0)
@@ -195,11 +197,45 @@ Lisp_Object display_x_get_resource (struct w32_display_info *,
195 Lisp_Object, Lisp_Object, 197 Lisp_Object, Lisp_Object,
196 Lisp_Object, Lisp_Object); 198 Lisp_Object, Lisp_Object);
197 199
200extern void x_focus_on_frame (struct frame *f);
201
202/* also defined in xterm.h XXX: factor out to common header */
203
198extern struct w32_display_info *w32_term_init (Lisp_Object, 204extern struct w32_display_info *w32_term_init (Lisp_Object,
199 char *, char *); 205 char *, char *);
200 206extern void check_w32 (void);
207extern int w32_defined_color (FRAME_PTR f, const char *color,
208 XColor *color_def, int alloc);
209extern void x_set_window_size (struct frame *f, int change_grav,
210 int cols, int rows);
201extern int x_display_pixel_height (struct w32_display_info *); 211extern int x_display_pixel_height (struct w32_display_info *);
202extern int x_display_pixel_width (struct w32_display_info *); 212extern int x_display_pixel_width (struct w32_display_info *);
213extern void x_sync (struct frame *);
214extern Lisp_Object x_get_focus_frame (struct frame *);
215extern void x_set_mouse_position (struct frame *f, int h, int v);
216extern void x_set_mouse_pixel_position (struct frame *f, int pix_x, int pix_y);
217extern void x_make_frame_visible (struct frame *f);
218extern void x_make_frame_invisible (struct frame *f);
219extern void x_iconify_frame (struct frame *f);
220extern int x_char_width (struct frame *f);
221extern int x_char_height (struct frame *f);
222extern int x_pixel_width (struct frame *f);
223extern int x_pixel_height (struct frame *f);
224extern void x_set_frame_alpha (struct frame *f);
225extern void x_set_menu_bar_lines (struct frame *, Lisp_Object, Lisp_Object);
226extern void x_set_tool_bar_lines (struct frame *f,
227 Lisp_Object value,
228 Lisp_Object oldval);
229extern void x_activate_menubar (struct frame *);
230extern int x_bitmap_icon (struct frame *, Lisp_Object);
231extern void initialize_frame_menubar (struct frame *);
232extern void x_free_frame_resources (struct frame *);
233extern void x_real_positions (struct frame *, int *, int *);
234
235/* w32inevt.c */
236extern int w32_kbd_patch_key (KEY_EVENT_RECORD *event, int cpId);
237extern int w32_kbd_mods_to_emacs (DWORD mods, WORD key);
238
203 239
204extern Lisp_Object x_get_focus_frame (struct frame *); 240extern Lisp_Object x_get_focus_frame (struct frame *);
205 241
@@ -583,8 +619,9 @@ do { \
583#define WM_EMACS_HIDE_CARET (WM_EMACS_START + 18) 619#define WM_EMACS_HIDE_CARET (WM_EMACS_START + 18)
584#define WM_EMACS_SETCURSOR (WM_EMACS_START + 19) 620#define WM_EMACS_SETCURSOR (WM_EMACS_START + 19)
585#define WM_EMACS_PAINT (WM_EMACS_START + 20) 621#define WM_EMACS_PAINT (WM_EMACS_START + 20)
586#define WM_EMACS_BRINGTOTOP (WM_EMACS_START + 21) 622#define WM_EMACS_BRINGTOTOP (WM_EMACS_START + 22)
587#define WM_EMACS_END (WM_EMACS_START + 22) 623#define WM_EMACS_INPUT_READY (WM_EMACS_START + 23)
624#define WM_EMACS_END (WM_EMACS_START + 24)
588 625
589#define WND_FONTWIDTH_INDEX (0) 626#define WND_FONTWIDTH_INDEX (0)
590#define WND_LINEHEIGHT_INDEX (4) 627#define WND_LINEHEIGHT_INDEX (4)
@@ -606,6 +643,8 @@ typedef struct W32Msg {
606 RECT rect; 643 RECT rect;
607} W32Msg; 644} W32Msg;
608 645
646extern BOOL prepend_msg (W32Msg *lpmsg);
647
609/* Structure for recording message when input thread must return a 648/* Structure for recording message when input thread must return a
610 result that depends on lisp thread to compute. Lisp thread can 649 result that depends on lisp thread to compute. Lisp thread can
611 complete deferred messages out of order. */ 650 complete deferred messages out of order. */
@@ -709,3 +748,19 @@ extern HWND w32_system_caret_hwnd;
709extern int w32_system_caret_height; 748extern int w32_system_caret_height;
710extern int w32_system_caret_x; 749extern int w32_system_caret_x;
711extern int w32_system_caret_y; 750extern int w32_system_caret_y;
751
752#if EMACSDEBUG
753extern const char*
754w32_name_of_message (UINT msg);
755#endif /* EMACSDEBUG */
756
757extern void syms_of_w32term (void);
758extern void syms_of_w32menu (void);
759extern void syms_of_w32fns (void);
760
761extern void globals_of_w32menu (void);
762extern void globals_of_w32fns (void);
763
764#ifdef CYGWIN
765extern int w32_message_fd;
766#endif /* CYGWIN */
diff --git a/src/w32xfns.c b/src/w32xfns.c
index 018dd14cb80..cb452571665 100644
--- a/src/w32xfns.c
+++ b/src/w32xfns.c
@@ -19,6 +19,7 @@ along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. */
19#include <config.h> 19#include <config.h>
20#include <signal.h> 20#include <signal.h>
21#include <stdio.h> 21#include <stdio.h>
22
22#include "lisp.h" 23#include "lisp.h"
23#include "keyboard.h" 24#include "keyboard.h"
24#include "frame.h" 25#include "frame.h"
@@ -32,7 +33,11 @@ along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. */
32#define myfree(lp) GlobalFreePtr (lp) 33#define myfree(lp) GlobalFreePtr (lp)
33 34
34CRITICAL_SECTION critsect; 35CRITICAL_SECTION critsect;
36
37#ifdef WINDOWSNT
35extern HANDLE keyboard_handle; 38extern HANDLE keyboard_handle;
39#endif /* WINDOWSNT */
40
36HANDLE input_available = NULL; 41HANDLE input_available = NULL;
37HANDLE interrupt_handle = NULL; 42HANDLE interrupt_handle = NULL;
38 43
@@ -43,7 +48,11 @@ init_crit (void)
43 48
44 /* For safety, input_available should only be reset by get_next_msg 49 /* For safety, input_available should only be reset by get_next_msg
45 when the input queue is empty, so make it a manual reset event. */ 50 when the input queue is empty, so make it a manual reset event. */
46 keyboard_handle = input_available = CreateEvent (NULL, TRUE, FALSE, NULL); 51 input_available = CreateEvent (NULL, TRUE, FALSE, NULL);
52
53#ifdef WINDOWSNT
54 keyboard_handle = input_available;
55#endif /* WINDOWSNT */
47 56
48 /* interrupt_handle is signaled when quit (C-g) is detected, so that 57 /* interrupt_handle is signaled when quit (C-g) is detected, so that
49 blocking system calls can be interrupted. We make it a manual 58 blocking system calls can be interrupted. We make it a manual
@@ -240,6 +249,22 @@ get_next_msg (W32Msg * lpmsg, BOOL bWait)
240 return (bRet); 249 return (bRet);
241} 250}
242 251
252extern char * w32_strerror (int error_no);
253
254/* Tell the main thread that we have input available; if the main
255 thread is blocked in select(), we wake it up here. */
256static void
257notify_msg_ready (void)
258{
259 SetEvent (input_available);
260
261#ifdef CYGWIN
262 /* Wakes up the main thread, which is blocked select()ing for /dev/windows,
263 among other files. */
264 (void) PostThreadMessage (dwMainThreadId, WM_EMACS_INPUT_READY, 0, 0);
265#endif /* CYGWIN */
266}
267
243BOOL 268BOOL
244post_msg (W32Msg * lpmsg) 269post_msg (W32Msg * lpmsg)
245{ 270{
@@ -263,8 +288,7 @@ post_msg (W32Msg * lpmsg)
263 } 288 }
264 289
265 lpTail = lpNew; 290 lpTail = lpNew;
266 SetEvent (input_available); 291 notify_msg_ready ();
267
268 leave_crit (); 292 leave_crit ();
269 293
270 return (TRUE); 294 return (TRUE);
@@ -285,7 +309,7 @@ prepend_msg (W32Msg *lpmsg)
285 nQueue++; 309 nQueue++;
286 lpNew->lpNext = lpHead; 310 lpNew->lpNext = lpHead;
287 lpHead = lpNew; 311 lpHead = lpNew;
288 312 notify_msg_ready ();
289 leave_crit (); 313 leave_crit ();
290 314
291 return (TRUE); 315 return (TRUE);
diff --git a/src/window.c b/src/window.c
index 3b974616e38..61d2a8b073f 100644
--- a/src/window.c
+++ b/src/window.c
@@ -43,7 +43,7 @@ along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. */
43#ifdef HAVE_X_WINDOWS 43#ifdef HAVE_X_WINDOWS
44#include "xterm.h" 44#include "xterm.h"
45#endif /* HAVE_X_WINDOWS */ 45#endif /* HAVE_X_WINDOWS */
46#ifdef WINDOWSNT 46#ifdef HAVE_NTGUI
47#include "w32term.h" 47#include "w32term.h"
48#endif 48#endif
49#ifdef MSDOS 49#ifdef MSDOS
diff --git a/src/xdisp.c b/src/xdisp.c
index 635e7ecd0b2..2047c0e78c1 100644
--- a/src/xdisp.c
+++ b/src/xdisp.c
@@ -302,7 +302,7 @@ along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. */
302#ifdef HAVE_X_WINDOWS 302#ifdef HAVE_X_WINDOWS
303#include "xterm.h" 303#include "xterm.h"
304#endif 304#endif
305#ifdef WINDOWSNT 305#ifdef HAVE_NTGUI
306#include "w32term.h" 306#include "w32term.h"
307#endif 307#endif
308#ifdef HAVE_NS 308#ifdef HAVE_NS
diff --git a/src/xfaces.c b/src/xfaces.c
index f861dde2d15..3e6e9dc8ec0 100644
--- a/src/xfaces.c
+++ b/src/xfaces.c
@@ -227,13 +227,13 @@ along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. */
227#ifdef HAVE_WINDOW_SYSTEM 227#ifdef HAVE_WINDOW_SYSTEM
228#include TERM_HEADER 228#include TERM_HEADER
229#include "fontset.h" 229#include "fontset.h"
230#ifdef WINDOWSNT 230#ifdef HAVE_NTGUI
231#undef FRAME_X_DISPLAY_INFO 231#undef FRAME_X_DISPLAY_INFO
232#define FRAME_X_DISPLAY_INFO FRAME_W32_DISPLAY_INFO 232#define FRAME_X_DISPLAY_INFO FRAME_W32_DISPLAY_INFO
233#define x_display_info w32_display_info 233#define x_display_info w32_display_info
234#define check_x check_w32 234#define check_x check_w32
235#define GCGraphicsExposures 0 235#define GCGraphicsExposures 0
236#endif /* WINDOWSNT */ 236#endif /* HAVE_NTGUI */
237 237
238#ifdef HAVE_NS 238#ifdef HAVE_NS
239#undef FRAME_X_DISPLAY_INFO 239#undef FRAME_X_DISPLAY_INFO
@@ -625,7 +625,7 @@ x_free_gc (struct frame *f, GC gc)
625 625
626#endif /* HAVE_X_WINDOWS */ 626#endif /* HAVE_X_WINDOWS */
627 627
628#ifdef WINDOWSNT 628#ifdef HAVE_NTGUI
629/* W32 emulation of GCs */ 629/* W32 emulation of GCs */
630 630
631static GC 631static GC
@@ -649,7 +649,7 @@ x_free_gc (struct frame *f, GC gc)
649 xfree (gc); 649 xfree (gc);
650} 650}
651 651
652#endif /* WINDOWSNT */ 652#endif /* HAVE_NTGUI */
653 653
654#ifdef HAVE_NS 654#ifdef HAVE_NS
655/* NS emulation of GCs */ 655/* NS emulation of GCs */
@@ -719,7 +719,7 @@ init_frame_faces (struct frame *f)
719#ifdef HAVE_X_WINDOWS 719#ifdef HAVE_X_WINDOWS
720 if (!FRAME_X_P (f) || FRAME_X_WINDOW (f)) 720 if (!FRAME_X_P (f) || FRAME_X_WINDOW (f))
721#endif 721#endif
722#ifdef WINDOWSNT 722#ifdef HAVE_NTGUI
723 if (!FRAME_WINDOW_P (f) || FRAME_W32_WINDOW (f)) 723 if (!FRAME_WINDOW_P (f) || FRAME_W32_WINDOW (f))
724#endif 724#endif
725#ifdef HAVE_NS 725#ifdef HAVE_NS
@@ -1098,7 +1098,7 @@ defined_color (struct frame *f, const char *color_name, XColor *color_def,
1098 else if (FRAME_X_P (f)) 1098 else if (FRAME_X_P (f))
1099 return x_defined_color (f, color_name, color_def, alloc); 1099 return x_defined_color (f, color_name, color_def, alloc);
1100#endif 1100#endif
1101#ifdef WINDOWSNT 1101#ifdef HAVE_NTGUI
1102 else if (FRAME_W32_P (f)) 1102 else if (FRAME_W32_P (f))
1103 return w32_defined_color (f, color_name, color_def, alloc); 1103 return w32_defined_color (f, color_name, color_def, alloc);
1104#endif 1104#endif
@@ -3245,7 +3245,7 @@ FRAME 0 means change the face on all frames, and change the default
3245 param = Qbackground_color; 3245 param = Qbackground_color;
3246 } 3246 }
3247#ifdef HAVE_WINDOW_SYSTEM 3247#ifdef HAVE_WINDOW_SYSTEM
3248#ifndef WINDOWSNT 3248#ifndef HAVE_NTGUI
3249 else if (EQ (face, Qscroll_bar)) 3249 else if (EQ (face, Qscroll_bar))
3250 { 3250 {
3251 /* Changing the colors of `scroll-bar' sets frame parameters 3251 /* Changing the colors of `scroll-bar' sets frame parameters
@@ -3255,7 +3255,7 @@ FRAME 0 means change the face on all frames, and change the default
3255 else if (EQ (attr, QCbackground)) 3255 else if (EQ (attr, QCbackground))
3256 param = Qscroll_bar_background; 3256 param = Qscroll_bar_background;
3257 } 3257 }
3258#endif /* not WINDOWSNT */ 3258#endif /* not HAVE_NTGUI */
3259 else if (EQ (face, Qborder)) 3259 else if (EQ (face, Qborder))
3260 { 3260 {
3261 /* Changing background color of `border' sets frame parameter 3261 /* Changing background color of `border' sets frame parameter
@@ -6362,7 +6362,7 @@ where R,G,B are numbers between 0 and 255 and name is an arbitrary string. */)
6362 if (num >= 0 && name[num] == '\n') 6362 if (num >= 0 && name[num] == '\n')
6363 name[num] = 0; 6363 name[num] = 0;
6364 cmap = Fcons (Fcons (build_string (name), 6364 cmap = Fcons (Fcons (build_string (name),
6365#ifdef WINDOWSNT 6365#ifdef HAVE_NTGUI
6366 make_number (RGB (red, green, blue))), 6366 make_number (RGB (red, green, blue))),
6367#else 6367#else
6368 make_number ((red << 16) | (green << 8) | blue)), 6368 make_number ((red << 16) | (green << 8) | blue)),