aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorKenichi Handa2013-05-23 00:12:59 +0900
committerKenichi Handa2013-05-23 00:12:59 +0900
commite1b96d7e637cf76864013f8dba68135f07638ab8 (patch)
tree1a2ccd5961a60f0268a37444071e8cd7a2255fbc /src
parente6d2f1553635a746396f2f4261dde31e03e0fdd1 (diff)
parent5d0acd9d3bb26adfac1c80b78aa48dc8b2d34fe0 (diff)
downloademacs-e1b96d7e637cf76864013f8dba68135f07638ab8.tar.gz
emacs-e1b96d7e637cf76864013f8dba68135f07638ab8.zip
merge trunk
Diffstat (limited to 'src')
-rw-r--r--src/ChangeLog151
-rw-r--r--src/Makefile.in44
-rw-r--r--src/bytecode.c7
-rw-r--r--src/dbusbind.c2
-rw-r--r--src/doc.c26
-rw-r--r--src/editfns.c2
-rw-r--r--src/fileio.c2
-rw-r--r--src/font.c4
-rw-r--r--src/gtkutil.c9
-rw-r--r--src/image.c19
-rw-r--r--src/insdel.c9
-rw-r--r--src/lisp.h6
-rw-r--r--src/lread.c23
-rw-r--r--src/makefile.w32-in2
-rw-r--r--src/nsfns.m550
-rw-r--r--src/nsfont.m7
-rw-r--r--src/nsterm.m24
-rw-r--r--src/process.c454
-rw-r--r--src/regex.c16
-rw-r--r--src/search.c12
-rw-r--r--src/undo.c6
-rw-r--r--src/unexw32.c8
-rw-r--r--src/w32.c72
-rw-r--r--src/w32fns.c5
-rw-r--r--src/xdisp.c12
-rw-r--r--src/xfns.c36
-rw-r--r--src/xterm.c2
-rw-r--r--src/xterm.h22
28 files changed, 1041 insertions, 491 deletions
diff --git a/src/ChangeLog b/src/ChangeLog
index cc6194ac467..418a89d7b89 100644
--- a/src/ChangeLog
+++ b/src/ChangeLog
@@ -19,6 +19,157 @@
19 character numbers counted by detect_coding_utf_8. Fix detection 19 character numbers counted by detect_coding_utf_8. Fix detection
20 of BOM for utf-8. 20 of BOM for utf-8.
21 21
222013-05-21 Barry OReilly <gundaetiapo@gmail.com> (tiny change)
23
24 * search.c (looking_at_1): Only set last_thing_searched if the match
25 changed the match-data (bug#14281).
26
272013-05-21 Dmitry Antipov <dmantipov@yandex.ru>
28
29 * xdisp.c (reseat_at_previous_visible_line_start):
30 Already declared in dispextern.h, so remove it here.
31 (move_it_vertically_backward): Likewise.
32
332013-05-20 YAMAMOTO Mitsuharu <mituharu@math.s.chiba-u.ac.jp>
34
35 * xfns.c (check_x_display_info): Don't use XINT for terminal object.
36 (Fx_display_pixel_width, Fx_display_pixel_height)
37 (Fx_display_mm_width, Fx_display_mm_height):
38 Mention `display-monitor-attributes-list' in docstrings.
39
40 * nsfns.m (ns_get_screen): Remove function. All uses removed.
41 (check_ns_display_info): Sync with check_x_display_info in xfns.c.
42 (Fx_server_max_request_size, Fx_server_vendor, Fx_server_version)
43 (Fx_display_screens, Fx_display_mm_width, Fx_display_mm_height)
44 (Fx_display_backing_store, Fx_display_visual_class)
45 (Fx_display_save_under, Fx_close_connection, Fxw_display_color_p)
46 (Fx_display_grayscale_p, Fx_display_pixel_width)
47 (Fx_display_pixel_height, Fx_display_planes)
48 (Fx_display_color_cells): Sync args and docstrings with xfns.c.
49 (Fx_display_screens): Don't confuse X11 screens with NS screens.
50 (Fx_display_mm_width, Fx_display_mm_height)
51 (Fx_display_pixel_width, Fx_display_pixel_width): Return width or
52 height for all physical monitors as in X11.
53
54 * nsterm.m (x_display_pixel_width, x_display_pixel_height):
55 Return pixel width or height for all physical monitors as in X11.
56
572013-05-18 Paul Eggert <eggert@cs.ucla.edu>
58
59 Port --enable-gcc-warnings to clang.
60 * bytecode.c (exec_byte_code):
61 * regex.c:
62 Redo diagnostic pragmas to pacify clang, too.
63 * dbusbind.c (xd_retrieve_arg): Do not use uninitialized variable.
64 * editfns.c (Fencode_time):
65 * fileio.c (file_accessible_directory_p):
66 * font.c (font_unparse_xlfd):
67 Use '&"string"[index]' instead of '"string" + (index)'.
68 * undo.c (user_error): Remove; unused.
69
702013-05-16 Eli Zaretskii <eliz@gnu.org>
71
72 * insdel.c (insert_1_both): Document the arguments, instead of
73 referring to insert_1, which no longer exists.
74
75 * xdisp.c (message_dolog): If the *Messages* buffer is shown in
76 some window, increment windows_or_buffers_changed, so that
77 *Messages* display in that window is updated. (Bug#14408)
78
79 * w32.c: Include epaths.h.
80 (init_environment): Use cmdproxy.exe without leading directories.
81 Support emacs.exe in src; point SHELL to cmdproxy in ../nt in that
82 case.
83 (gettimeofday): Adjust signature and return value to Posix
84 expectations.
85
86 * unexw32.c (open_output_file): Delete the existing emacs.exe
87 before creating it, to break the hard link to the versioned
88 executable.
89
90 * Makefile.in (EMACS_MANIFEST, CM_OBJ, TEMACS_POST_LINK)
91 (ADDSECTION, EMACS_HEAPSIZE, MINGW_TEMACS_POST_LINK)
92 (FIRSTFILE_OBJ): New variables.
93 (W32_RES): Rename to EMACSRES. All users changed.
94 (base_obj): Use $(CM_OBJ).
95 (ALLOBJS): Use $(FIRSTFILE_OBJ).
96 (emacs$(EXEEXT)): Depend on $(ADDSECTION).
97 (temacs$(EXEEXT)): Use $(TEMACS_POST_LINK), and move
98 $(W32_RES_LINK) before $(LIBES).
99 (emacs.res): Depend on $(EMACS_MANIFEST). Put emacs.rc in nt.
100
1012013-05-15 Stefan Monnier <monnier@iro.umontreal.ca>
102
103 * makefile.w32-in (DOC): Use just "DOC".
104
105 * Makefile.in (bootstrap-clean): DOC-* doesn't exist any more.
106
107 * process.c: Export default filters and sentinels to Elisp.
108 (Qinternal_default_process_sentinel, Qinternal_default_process_filter):
109 New constants.
110 (pset_filter, pset_sentinel, make_process, Fset_process_filter)
111 (Fset_process_sentinel, Fformat_network_address):
112 Default to them instead of nil.
113 (server_accept_connection): Sentinels can't be nil any more.
114 (read_and_dispose_of_process_output): New function, extracted from
115 read_process_output.
116 (read_process_output): Use it; filters can't be nil.
117 (Finternal_default_process_filter): New function, extracted from
118 read_process_output.
119 (exec_sentinel_unwind): Remove function.
120 (exec_sentinel): Don't zilch sentinel while running.
121 (status_notify): Sentinels can't be nil.
122 (Finternal_default_process_sentinel): New function extracted from
123 status_notify.
124 (setup_process_coding_systems): Default filter is not nil any more.
125 (syms_of_process): Export new Elisp functions and initialize
126 new constants.
127 * lisp.h (make_lisp_proc): New function.
128
1292013-05-15 Stefan Monnier <monnier@iro.umontreal.ca>
130
131 * regex.c (regex_compile) [\=, \>, \<]: Don't forget to set laststart.
132
1332013-05-14 Eli Zaretskii <eliz@gnu.org>
134
135 * w32fns.c (w32_wnd_proc): Don't call WINDOW_HEADER_LINE_HEIGHT
136 unless we know that the window w is a leaf window.
137 Another attempt at solving bug#14062.
138
1392013-05-14 Jan Djärv <jan.h.d@swipnet.se>
140
141 * nsfont.m (ns_spec_to_descriptor): Retain and autorelease
142 fdesc (Bug#14375).
143
1442013-05-12 Paul Eggert <eggert@cs.ucla.edu>
145
146 * image.c (gif_load): Check that subimages fit (Bug#14345).
147
1482013-05-09 Stefan Monnier <monnier@iro.umontreal.ca>
149
150 * lread.c (skip_dyn_eof): New function.
151 (read1): Use it to skip the end of a file in response to #@00.
152
153 * doc.c (get_doc_string): Slightly relax the sanity checking.
154
1552013-05-09 Jan Djärv <jan.h.d@swipnet.se>
156
157 * nsfns.m: Include IOGraphicsLib.h if Cocoa.
158 (Qgeometry, Qworkarea, Qmm_size, Qframes, Qsource): Declare.
159 (MonitorInfo): New struct.
160 (free_monitors, ns_screen_name, ns_make_monitor_attribute_list)
161 (Fns_display_monitor_attributes_list): New functions.
162 (display-usable-bounds): Remove.
163 (syms_of_nsfns): DEFSYM Qgeometry, Qworkarea, Qmm_size, Qframes and
164 Qsource.
165
1662013-05-09 Paul Eggert <eggert@cs.ucla.edu>
167
168 * xterm.h (GTK_PREREQ): Remove, replacing with GTK_CHECK_VERSION.
169 (GTK_CHECK_VERSION): New macro, if not already defined.
170 All uses of GTK_PREREQ, GTK_MAJOR_VERSION, etc.
171 replaced by GTK_CHECK_VERSION.
172
222013-05-08 Paul Eggert <eggert@cs.ucla.edu> 1732013-05-08 Paul Eggert <eggert@cs.ucla.edu>
23 174
24 * xterm.h (GTK_PREREQ): New macro. 175 * xterm.h (GTK_PREREQ): New macro.
diff --git a/src/Makefile.in b/src/Makefile.in
index ad81a8d6592..c7a18363a5a 100644
--- a/src/Makefile.in
+++ b/src/Makefile.in
@@ -267,10 +267,13 @@ W32_OBJ=@W32_OBJ@
267W32_LIBS=@W32_LIBS@ 267W32_LIBS=@W32_LIBS@
268 268
269## emacs.res if HAVE_W32 269## emacs.res if HAVE_W32
270W32_RES=@W32_RES@ 270EMACSRES = @EMACSRES@
271## emacs-*.manifest if HAVE_W32
272EMACS_MANIFEST = @EMACS_MANIFEST@
271## If HAVE_W32, compiler arguments for including 273## If HAVE_W32, compiler arguments for including
272## the resource file in the binary. 274## the resource file in the binary.
273## XXX -Wl,-b -Wl,pe-i386 -Wl,emacs.res 275## Cygwin: -Wl,emacs.res
276## MinGW: emacs.res
274W32_RES_LINK=@W32_RES_LINK@ 277W32_RES_LINK=@W32_RES_LINK@
275 278
276## Empty if !HAVE_X_WINDOWS 279## Empty if !HAVE_X_WINDOWS
@@ -279,6 +282,9 @@ W32_RES_LINK=@W32_RES_LINK@
279## else xfont.o 282## else xfont.o
280FONT_OBJ=@FONT_OBJ@ 283FONT_OBJ=@FONT_OBJ@
281 284
285## Empty for MinGW, cm.o for the rest.
286CM_OBJ=@CM_OBJ@
287
282LIBGPM = @LIBGPM@ 288LIBGPM = @LIBGPM@
283 289
284## -lresolv, or empty. 290## -lresolv, or empty.
@@ -297,6 +303,14 @@ GETLOADAVG_LIBS = @GETLOADAVG_LIBS@
297 303
298RUN_TEMACS = `/bin/pwd`/temacs 304RUN_TEMACS = `/bin/pwd`/temacs
299 305
306## Invoke ../nt/addsection for MinGW, ":" elsewhere.
307TEMACS_POST_LINK = @TEMACS_POST_LINK@
308ADDSECTION = @ADDSECTION@
309EMACS_HEAPSIZE = @EMACS_HEAPSIZE@
310MINGW_TEMACS_POST_LINK = \
311 mv temacs$(EXEEXT) temacs.tmp; \
312 ../nt/addsection temacs.tmp temacs$(EXEEXT) EMHEAP $(EMACS_HEAPSIZE)
313
300UNEXEC_OBJ = @UNEXEC_OBJ@ 314UNEXEC_OBJ = @UNEXEC_OBJ@
301 315
302CANNOT_DUMP=@CANNOT_DUMP@ 316CANNOT_DUMP=@CANNOT_DUMP@
@@ -339,7 +353,7 @@ ALL_OBJC_CFLAGS=$(ALL_CFLAGS) $(GNU_OBJC_CFLAGS)
339## be dumped as pure by dump-emacs. 353## be dumped as pure by dump-emacs.
340base_obj = dispnew.o frame.o scroll.o xdisp.o menu.o $(XMENU_OBJ) window.o \ 354base_obj = dispnew.o frame.o scroll.o xdisp.o menu.o $(XMENU_OBJ) window.o \
341 charset.o coding.o category.o ccl.o character.o chartab.o bidi.o \ 355 charset.o coding.o category.o ccl.o character.o chartab.o bidi.o \
342 cm.o term.o terminal.o xfaces.o $(XOBJ) $(GTK_OBJ) $(DBUS_OBJ) \ 356 $(CM_OBJ) term.o terminal.o xfaces.o $(XOBJ) $(GTK_OBJ) $(DBUS_OBJ) \
343 emacs.o keyboard.o macros.o keymap.o sysdep.o \ 357 emacs.o keyboard.o macros.o keymap.o sysdep.o \
344 buffer.o filelock.o insdel.o marker.o \ 358 buffer.o filelock.o insdel.o marker.o \
345 minibuf.o fileio.o dired.o \ 359 minibuf.o fileio.o dired.o \
@@ -377,9 +391,9 @@ VMLIMIT_OBJ=@VMLIMIT_OBJ@
377## ralloc.o if !SYSTEM_MALLOC && REL_ALLOC, else empty. 391## ralloc.o if !SYSTEM_MALLOC && REL_ALLOC, else empty.
378RALLOC_OBJ=@RALLOC_OBJ@ 392RALLOC_OBJ=@RALLOC_OBJ@
379 393
380## Empty on Cygwin, lastfile.o elsewhere. 394## Empty on Cygwin and MinGW, lastfile.o elsewhere.
381PRE_ALLOC_OBJ=@PRE_ALLOC_OBJ@ 395PRE_ALLOC_OBJ=@PRE_ALLOC_OBJ@
382## lastfile.o on Cygwin, empty elsewhere. 396## lastfile.o on Cygwin and MinGW, empty elsewhere.
383POST_ALLOC_OBJ=@POST_ALLOC_OBJ@ 397POST_ALLOC_OBJ=@POST_ALLOC_OBJ@
384 398
385## List of object files that make-docfile should not be told about. 399## List of object files that make-docfile should not be told about.
@@ -387,7 +401,9 @@ otherobj= $(TERMCAP_OBJ) $(PRE_ALLOC_OBJ) $(GMALLOC_OBJ) $(RALLOC_OBJ) \
387 $(POST_ALLOC_OBJ) $(WIDGET_OBJ) $(LIBOBJS) 401 $(POST_ALLOC_OBJ) $(WIDGET_OBJ) $(LIBOBJS)
388 402
389## All object files linked into temacs. $(VMLIMIT_OBJ) should be first. 403## All object files linked into temacs. $(VMLIMIT_OBJ) should be first.
390ALLOBJS = $(VMLIMIT_OBJ) $(obj) $(otherobj) 404## (On MinGW, firstfile.o should be before vm-limit.o.)
405FIRSTFILE_OBJ=@FIRSTFILE_OBJ@
406ALLOBJS = $(FIRSTFILE_OBJ) $(VMLIMIT_OBJ) $(obj) $(otherobj)
391 407
392## Configure inserts the file lisp.mk at this point, defining $lisp. 408## Configure inserts the file lisp.mk at this point, defining $lisp.
393@lisp_frag@ 409@lisp_frag@
@@ -416,7 +432,8 @@ $(leimdir)/leim-list.el: bootstrap-emacs$(EXEEXT)
416## Strictly speaking, emacs does not depend directly on all of $lisp, 432## Strictly speaking, emacs does not depend directly on all of $lisp,
417## since not all pieces are used on all platforms. But DOC depends 433## since not all pieces are used on all platforms. But DOC depends
418## on all of $lisp, and emacs depends on DOC, so it is ok to use $lisp here. 434## on all of $lisp, and emacs depends on DOC, so it is ok to use $lisp here.
419emacs$(EXEEXT): temacs$(EXEEXT) $(etc)/DOC $(lisp) $(leimdir)/leim-list.el 435emacs$(EXEEXT): temacs$(EXEEXT) $(ADDSECTION) \
436 $(etc)/DOC $(lisp) $(leimdir)/leim-list.el
420 if test "$(CANNOT_DUMP)" = "yes"; then \ 437 if test "$(CANNOT_DUMP)" = "yes"; then \
421 rm -f emacs$(EXEEXT); \ 438 rm -f emacs$(EXEEXT); \
422 ln temacs$(EXEEXT) emacs$(EXEEXT); \ 439 ln temacs$(EXEEXT) emacs$(EXEEXT); \
@@ -468,10 +485,10 @@ $(lib)/libgnu.a: $(config_h)
468 cd $(lib) && $(MAKE) libgnu.a 485 cd $(lib) && $(MAKE) libgnu.a
469 486
470temacs$(EXEEXT): stamp-oldxmenu $(ALLOBJS) \ 487temacs$(EXEEXT): stamp-oldxmenu $(ALLOBJS) \
471 $(lib)/libgnu.a $(W32_RES) 488 $(lib)/libgnu.a $(EMACSRES)
472 $(CC) $(ALL_CFLAGS) $(TEMACS_LDFLAGS) $(LDFLAGS) \ 489 $(CC) $(ALL_CFLAGS) $(TEMACS_LDFLAGS) $(LDFLAGS) \
473 -o temacs $(ALLOBJS) $(lib)/libgnu.a $(LIBES) \ 490 -o temacs $(ALLOBJS) $(lib)/libgnu.a $(W32_RES_LINK) $(LIBES)
474 $(W32_RES_LINK) 491 $(TEMACS_POST_LINK)
475 test "$(CANNOT_DUMP)" = "yes" || \ 492 test "$(CANNOT_DUMP)" = "yes" || \
476 test "X$(PAXCTL)" = X || $(PAXCTL) -r temacs$(EXEEXT) 493 test "X$(PAXCTL)" = X || $(PAXCTL) -r temacs$(EXEEXT)
477 494
@@ -514,8 +531,9 @@ doc.o: buildobj.h
514 531
515emacs.res: $(ntsource)/emacs.rc \ 532emacs.res: $(ntsource)/emacs.rc \
516 $(ntsource)/icons/emacs.ico \ 533 $(ntsource)/icons/emacs.ico \
517 $(ntsource)/emacs-x86.manifest 534 $(ntsource)/$(EMACS_MANIFEST)
518 $(WINDRES) -O COFF -o $@ $(ntsource)/emacs.rc 535 $(WINDRES) -O COFF --include-dir=$(srcdir)/../nt \
536 -o $@ $(ntsource)/emacs.rc
519 537
520ns-app: emacs$(EXEEXT) 538ns-app: emacs$(EXEEXT)
521 cd ../nextstep && $(MAKE) $(MFLAGS) all 539 cd ../nextstep && $(MAKE) $(MFLAGS) all
@@ -537,7 +555,7 @@ clean: mostlyclean
537## It should remove all files generated during a compilation/bootstrap, 555## It should remove all files generated during a compilation/bootstrap,
538## but not things like config.status or TAGS. 556## but not things like config.status or TAGS.
539bootstrap-clean: clean 557bootstrap-clean: clean
540 rm -f epaths.h config.h config.stamp stamp-h1 stamp-oldxmenu ../etc/DOC-* 558 rm -f epaths.h config.h config.stamp stamp-h1 stamp-oldxmenu
541 if test -f ./.gdbinit; then \ 559 if test -f ./.gdbinit; then \
542 mv ./.gdbinit ./.gdbinit.save; \ 560 mv ./.gdbinit ./.gdbinit.save; \
543 if test -f "$(srcdir)/.gdbinit"; then rm -f ./.gdbinit.save; \ 561 if test -f "$(srcdir)/.gdbinit"; then rm -f ./.gdbinit.save; \
diff --git a/src/bytecode.c b/src/bytecode.c
index 7676c8550a4..4940fd5c182 100644
--- a/src/bytecode.c
+++ b/src/bytecode.c
@@ -660,9 +660,12 @@ exec_byte_code (Lisp_Object bytestr, Lisp_Object vector, Lisp_Object maxdepth,
660 the table clearer. */ 660 the table clearer. */
661#define LABEL(OP) [OP] = &&insn_ ## OP 661#define LABEL(OP) [OP] = &&insn_ ## OP
662 662
663#if __GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 6) 663#if 4 < __GNUC__ + (6 <= __GNUC_MINOR__)
664# pragma GCC diagnostic push 664# pragma GCC diagnostic push
665# pragma GCC diagnostic ignored "-Woverride-init" 665# pragma GCC diagnostic ignored "-Woverride-init"
666#elif defined __clang__
667# pragma GCC diagnostic push
668# pragma GCC diagnostic ignored "-Winitializer-overrides"
666#endif 669#endif
667 670
668 /* This is the dispatch table for the threaded interpreter. */ 671 /* This is the dispatch table for the threaded interpreter. */
@@ -676,7 +679,7 @@ exec_byte_code (Lisp_Object bytestr, Lisp_Object vector, Lisp_Object maxdepth,
676#undef DEFINE 679#undef DEFINE
677 }; 680 };
678 681
679#if __GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 6) 682#if 4 < __GNUC__ + (6 <= __GNUC_MINOR__) || defined __clang__
680# pragma GCC diagnostic pop 683# pragma GCC diagnostic pop
681#endif 684#endif
682 685
diff --git a/src/dbusbind.c b/src/dbusbind.c
index 863f7634eb5..3ec3c28431b 100644
--- a/src/dbusbind.c
+++ b/src/dbusbind.c
@@ -882,7 +882,7 @@ xd_retrieve_arg (int dtype, DBusMessageIter *iter)
882#endif 882#endif
883 { 883 {
884 dbus_uint32_t val; 884 dbus_uint32_t val;
885 unsigned int pval = val; 885 unsigned int pval;
886 dbus_message_iter_get_basic (iter, &val); 886 dbus_message_iter_get_basic (iter, &val);
887 pval = val; 887 pval = val;
888 XD_DEBUG_MESSAGE ("%c %u", dtype, pval); 888 XD_DEBUG_MESSAGE ("%c %u", dtype, pval);
diff --git a/src/doc.c b/src/doc.c
index 7234fb38bf9..e45481944f0 100644
--- a/src/doc.c
+++ b/src/doc.c
@@ -58,7 +58,7 @@ read_bytecode_char (bool unreadflag)
58} 58}
59 59
60/* Extract a doc string from a file. FILEPOS says where to get it. 60/* Extract a doc string from a file. FILEPOS says where to get it.
61 If it is an integer, use that position in the standard DOC-... file. 61 If it is an integer, use that position in the standard DOC file.
62 If it is (FILE . INTEGER), use FILE as the file name 62 If it is (FILE . INTEGER), use FILE as the file name
63 and INTEGER as the position in that file. 63 and INTEGER as the position in that file.
64 But if INTEGER is negative, make it positive. 64 But if INTEGER is negative, make it positive.
@@ -215,14 +215,20 @@ get_doc_string (Lisp_Object filepos, bool unibyte, bool definition)
215 if (CONSP (filepos)) 215 if (CONSP (filepos))
216 { 216 {
217 int test = 1; 217 int test = 1;
218 if (get_doc_string_buffer[offset - test++] != ' ') 218 /* A dynamic docstring should be either at the very beginning of a "#@
219 return Qnil; 219 comment" or right after a dynamic docstring delimiter (in case we
220 while (get_doc_string_buffer[offset - test] >= '0' 220 pack several such docstrings within the same comment). */
221 && get_doc_string_buffer[offset - test] <= '9') 221 if (get_doc_string_buffer[offset - test] != '\037')
222 test++; 222 {
223 if (get_doc_string_buffer[offset - test++] != '@' 223 if (get_doc_string_buffer[offset - test++] != ' ')
224 || get_doc_string_buffer[offset - test] != '#') 224 return Qnil;
225 return Qnil; 225 while (get_doc_string_buffer[offset - test] >= '0'
226 && get_doc_string_buffer[offset - test] <= '9')
227 test++;
228 if (get_doc_string_buffer[offset - test++] != '@'
229 || get_doc_string_buffer[offset - test] != '#')
230 return Qnil;
231 }
226 } 232 }
227 else 233 else
228 { 234 {
@@ -602,7 +608,7 @@ the same file name is found in the `doc-directory'. */)
602 while (*beg && c_isspace (*beg)) ++beg; 608 while (*beg && c_isspace (*beg)) ++beg;
603 609
604 for (end = beg; *end && ! c_isspace (*end); ++end) 610 for (end = beg; *end && ! c_isspace (*end); ++end)
605 if (*end == '/') beg = end+1; /* skip directory part */ 611 if (*end == '/') beg = end + 1; /* Skip directory part. */
606 612
607 len = end - beg; 613 len = end - beg;
608 if (len > 4 && end[-4] == '.' && end[-3] == 'o') 614 if (len > 4 && end[-4] == '.' && end[-3] == 'o')
diff --git a/src/editfns.c b/src/editfns.c
index e0b0347fe69..cc6b4cff895 100644
--- a/src/editfns.c
+++ b/src/editfns.c
@@ -1946,7 +1946,7 @@ usage: (encode-time SECOND MINUTE HOUR DAY MONTH YEAR &optional ZONE) */)
1946 EMACS_INT zone_hr = abszone / (60*60); 1946 EMACS_INT zone_hr = abszone / (60*60);
1947 int zone_min = (abszone/60) % 60; 1947 int zone_min = (abszone/60) % 60;
1948 int zone_sec = abszone % 60; 1948 int zone_sec = abszone % 60;
1949 sprintf (tzbuf, tzbuf_format, "-" + (XINT (zone) < 0), 1949 sprintf (tzbuf, tzbuf_format, &"-"[XINT (zone) < 0],
1950 zone_hr, zone_min, zone_sec); 1950 zone_hr, zone_min, zone_sec);
1951 tzstring = tzbuf; 1951 tzstring = tzbuf;
1952 } 1952 }
diff --git a/src/fileio.c b/src/fileio.c
index fe1bce16ca0..f20721251e6 100644
--- a/src/fileio.c
+++ b/src/fileio.c
@@ -2873,7 +2873,7 @@ file_accessible_directory_p (char const *file)
2873 and it's a safe optimization here. */ 2873 and it's a safe optimization here. */
2874 char *buf = SAFE_ALLOCA (len + 3); 2874 char *buf = SAFE_ALLOCA (len + 3);
2875 memcpy (buf, file, len); 2875 memcpy (buf, file, len);
2876 strcpy (buf + len, "/." + (file[len - 1] == '/')); 2876 strcpy (buf + len, &"/."[file[len - 1] == '/']);
2877 dir = buf; 2877 dir = buf;
2878 } 2878 }
2879 2879
diff --git a/src/font.c b/src/font.c
index ad601177b50..7bd44a5e52f 100644
--- a/src/font.c
+++ b/src/font.c
@@ -1219,7 +1219,7 @@ font_unparse_xlfd (Lisp_Object font, int pixel_size, char *name, int nbytes)
1219 return -1; 1219 return -1;
1220 f[j] = p = alloca (alloc); 1220 f[j] = p = alloca (alloc);
1221 sprintf (p, "%s%s-*", SDATA (val), 1221 sprintf (p, "%s%s-*", SDATA (val),
1222 "*" + (SDATA (val)[SBYTES (val) - 1] == '*')); 1222 &"*"[SDATA (val)[SBYTES (val) - 1] == '*']);
1223 } 1223 }
1224 else 1224 else
1225 f[j] = SSDATA (val); 1225 f[j] = SSDATA (val);
@@ -1618,7 +1618,7 @@ font_unparse_fcname (Lisp_Object font, int pixel_size, char *name, int nbytes)
1618 } 1618 }
1619 if (point_size > 0) 1619 if (point_size > 0)
1620 { 1620 {
1621 int len = snprintf (p, lim - p, "-%d" + (p == name), point_size); 1621 int len = snprintf (p, lim - p, &"-%d"[p == name], point_size);
1622 if (! (0 <= len && len < lim - p)) 1622 if (! (0 <= len && len < lim - p))
1623 return -1; 1623 return -1;
1624 p += len; 1624 p += len;
diff --git a/src/gtkutil.c b/src/gtkutil.c
index d4f72fd6b7f..8ac58f18158 100644
--- a/src/gtkutil.c
+++ b/src/gtkutil.c
@@ -70,13 +70,13 @@ along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. */
70#define gtk_adjustment_get_step_increment(w) ((w)->step_increment) 70#define gtk_adjustment_get_step_increment(w) ((w)->step_increment)
71#define gtk_adjustment_set_step_increment(w, s) ((w)->step_increment = (s)) 71#define gtk_adjustment_set_step_increment(w, s) ((w)->step_increment = (s))
72#endif 72#endif
73#if GTK_PREREQ (2, 12) 73#if GTK_CHECK_VERSION (2, 12, 0)
74#define remove_submenu(w) gtk_menu_item_set_submenu ((w), NULL) 74#define remove_submenu(w) gtk_menu_item_set_submenu ((w), NULL)
75#else 75#else
76#define remove_submenu(w) gtk_menu_item_remove_submenu ((w)) 76#define remove_submenu(w) gtk_menu_item_remove_submenu ((w))
77#endif 77#endif
78 78
79#if GTK_PREREQ (3, 2) 79#if GTK_CHECK_VERSION (3, 2, 0)
80#define USE_NEW_GTK_FONT_CHOOSER 1 80#define USE_NEW_GTK_FONT_CHOOSER 1
81#else 81#else
82#define USE_NEW_GTK_FONT_CHOOSER 0 82#define USE_NEW_GTK_FONT_CHOOSER 0
@@ -202,7 +202,7 @@ xg_display_close (Display *dpy)
202 gdpy_def = gdpy_new; 202 gdpy_def = gdpy_new;
203 } 203 }
204 204
205#if GTK_MAJOR_VERSION == 2 && GTK_MINOR_VERSION < 10 205#if GTK_CHECK_VERSION (2, 0, 0) && ! GTK_CHECK_VERSION (2, 10, 0)
206 /* GTK 2.2-2.8 has a bug that makes gdk_display_close crash (bug 206 /* GTK 2.2-2.8 has a bug that makes gdk_display_close crash (bug
207 http://bugzilla.gnome.org/show_bug.cgi?id=85715). This way we 207 http://bugzilla.gnome.org/show_bug.cgi?id=85715). This way we
208 can continue running, but there will be memory leaks. */ 208 can continue running, but there will be memory leaks. */
@@ -1155,7 +1155,8 @@ xg_create_frame_widgets (FRAME_PTR f)
1155 has backported it to Gtk+ 2.0 and they add the resize grip for 1155 has backported it to Gtk+ 2.0 and they add the resize grip for
1156 Gtk+ 2.0 applications also. But it has a bug that makes Emacs loop 1156 Gtk+ 2.0 applications also. But it has a bug that makes Emacs loop
1157 forever, so disable the grip. */ 1157 forever, so disable the grip. */
1158#if GTK_MAJOR_VERSION < 3 && defined (HAVE_GTK_WINDOW_SET_HAS_RESIZE_GRIP) 1158#if (! GTK_CHECK_VERSION (3, 0, 0) \
1159 && defined HAVE_GTK_WINDOW_SET_HAS_RESIZE_GRIP)
1159 gtk_window_set_has_resize_grip (GTK_WINDOW (wtop), FALSE); 1160 gtk_window_set_has_resize_grip (GTK_WINDOW (wtop), FALSE);
1160#endif 1161#endif
1161 1162
diff --git a/src/image.c b/src/image.c
index 2dae63a294f..f9f6ce70040 100644
--- a/src/image.c
+++ b/src/image.c
@@ -7263,6 +7263,25 @@ gif_load (struct frame *f, struct image *img)
7263 return 0; 7263 return 0;
7264 } 7264 }
7265 7265
7266 /* Check that the selected subimages fit. It's not clear whether
7267 the GIF spec requires this, but Emacs can crash if they don't fit. */
7268 for (j = 0; j <= idx; ++j)
7269 {
7270 struct SavedImage *subimage = gif->SavedImages + j;
7271 int subimg_width = subimage->ImageDesc.Width;
7272 int subimg_height = subimage->ImageDesc.Height;
7273 int subimg_top = subimage->ImageDesc.Top;
7274 int subimg_left = subimage->ImageDesc.Left;
7275 if (! (0 <= subimg_width && 0 <= subimg_height
7276 && 0 <= subimg_top && subimg_top <= height - subimg_height
7277 && 0 <= subimg_left && subimg_left <= width - subimg_width))
7278 {
7279 image_error ("Subimage does not fit in image", Qnil, Qnil);
7280 fn_DGifCloseFile (gif);
7281 return 0;
7282 }
7283 }
7284
7266 /* Create the X image and pixmap. */ 7285 /* Create the X image and pixmap. */
7267 if (!x_create_x_image_and_pixmap (f, width, height, 0, &ximg, &img->pixmap)) 7286 if (!x_create_x_image_and_pixmap (f, width, height, 0, &ximg, &img->pixmap))
7268 { 7287 {
diff --git a/src/insdel.c b/src/insdel.c
index 8029291cd68..ed684264249 100644
--- a/src/insdel.c
+++ b/src/insdel.c
@@ -771,8 +771,13 @@ count_combining_after (const unsigned char *string,
771 771
772 772
773/* Insert a sequence of NCHARS chars which occupy NBYTES bytes 773/* Insert a sequence of NCHARS chars which occupy NBYTES bytes
774 starting at STRING. INHERIT, PREPARE and BEFORE_MARKERS 774 starting at STRING. INHERIT non-zero means inherit the text
775 are the same as in insert_1. */ 775 properties from neighboring characters; zero means inserted text
776 will have no text properties. PREPARE non-zero means call
777 prepare_to_modify_buffer, which checks that the region is not
778 read-only, and calls before-change-function and any modification
779 properties the text may have. BEFORE_MARKERS non-zero means adjust
780 all markers that point at the insertion place to point after it. */
776 781
777void 782void
778insert_1_both (const char *string, 783insert_1_both (const char *string,
diff --git a/src/lisp.h b/src/lisp.h
index e2c24eed352..79d32c90f73 100644
--- a/src/lisp.h
+++ b/src/lisp.h
@@ -585,10 +585,12 @@ clip_to_bounds (ptrdiff_t lower, EMACS_INT num, ptrdiff_t upper)
585 (eassert (KBOARD_OBJFWDP (a)), &((a)->u_kboard_objfwd)) 585 (eassert (KBOARD_OBJFWDP (a)), &((a)->u_kboard_objfwd))
586 586
587/* Pseudovector types. */ 587/* Pseudovector types. */
588 588struct Lisp_Process;
589LISP_INLINE Lisp_Object make_lisp_proc (struct Lisp_Process *p)
590{ return make_lisp_ptr (p, Lisp_Vectorlike); }
589#define XPROCESS(a) (eassert (PROCESSP (a)), \ 591#define XPROCESS(a) (eassert (PROCESSP (a)), \
590 (struct Lisp_Process *) XUNTAG (a, Lisp_Vectorlike)) 592 (struct Lisp_Process *) XUNTAG (a, Lisp_Vectorlike))
591#define XWINDOW(a) (eassert (WINDOWP (a)), \ 593#define XWINDOW(a) (eassert (WINDOWP (a)), \
592 (struct window *) XUNTAG (a, Lisp_Vectorlike)) 594 (struct window *) XUNTAG (a, Lisp_Vectorlike))
593#define XTERMINAL(a) (eassert (TERMINALP (a)), \ 595#define XTERMINAL(a) (eassert (TERMINALP (a)), \
594 (struct terminal *) XUNTAG (a, Lisp_Vectorlike)) 596 (struct terminal *) XUNTAG (a, Lisp_Vectorlike))
diff --git a/src/lread.c b/src/lread.c
index 272f252cf7b..3ca644bb45b 100644
--- a/src/lread.c
+++ b/src/lread.c
@@ -378,6 +378,19 @@ skip_dyn_bytes (Lisp_Object readcharfun, ptrdiff_t n)
378 } 378 }
379} 379}
380 380
381static void
382skip_dyn_eof (Lisp_Object readcharfun)
383{
384 if (FROM_FILE_P (readcharfun))
385 {
386 block_input (); /* FIXME: Not sure if it's needed. */
387 fseek (instream, 0, SEEK_END);
388 unblock_input ();
389 }
390 else
391 while (READCHAR >= 0);
392}
393
381/* Unread the character C in the way appropriate for the stream READCHARFUN. 394/* Unread the character C in the way appropriate for the stream READCHARFUN.
382 If the stream is a user function, call it with the char as argument. */ 395 If the stream is a user function, call it with the char as argument. */
383 396
@@ -2622,7 +2635,7 @@ read1 (Lisp_Object readcharfun, int *pch, bool first_in_list)
2622 if (c == '@') 2635 if (c == '@')
2623 { 2636 {
2624 enum { extra = 100 }; 2637 enum { extra = 100 };
2625 ptrdiff_t i, nskip = 0; 2638 ptrdiff_t i, nskip = 0, digits = 0;
2626 2639
2627 /* Read a decimal integer. */ 2640 /* Read a decimal integer. */
2628 while ((c = READCHAR) >= 0 2641 while ((c = READCHAR) >= 0
@@ -2630,8 +2643,14 @@ read1 (Lisp_Object readcharfun, int *pch, bool first_in_list)
2630 { 2643 {
2631 if ((STRING_BYTES_BOUND - extra) / 10 <= nskip) 2644 if ((STRING_BYTES_BOUND - extra) / 10 <= nskip)
2632 string_overflow (); 2645 string_overflow ();
2646 digits++;
2633 nskip *= 10; 2647 nskip *= 10;
2634 nskip += c - '0'; 2648 nskip += c - '0';
2649 if (digits == 2 && nskip == 0)
2650 { /* We've just seen #@00, which means "skip to end". */
2651 skip_dyn_eof (readcharfun);
2652 return Qnil;
2653 }
2635 } 2654 }
2636 if (nskip > 0) 2655 if (nskip > 0)
2637 /* We can't use UNREAD here, because in the code below we side-step 2656 /* We can't use UNREAD here, because in the code below we side-step
@@ -3538,7 +3557,7 @@ read_list (bool flag, Lisp_Object readcharfun)
3538 { 3557 {
3539 if (NILP (Vdoc_file_name)) 3558 if (NILP (Vdoc_file_name))
3540 /* We have not yet called Snarf-documentation, so assume 3559 /* We have not yet called Snarf-documentation, so assume
3541 this file is described in the DOC-MM.NN file 3560 this file is described in the DOC file
3542 and Snarf-documentation will fill in the right value later. 3561 and Snarf-documentation will fill in the right value later.
3543 For now, replace the whole list with 0. */ 3562 For now, replace the whole list with 0. */
3544 doc_reference = 1; 3563 doc_reference = 1;
diff --git a/src/makefile.w32-in b/src/makefile.w32-in
index 3484d6c70c8..272b053ed12 100644
--- a/src/makefile.w32-in
+++ b/src/makefile.w32-in
@@ -41,7 +41,7 @@ TRES = $(BLD)/emacs.res
41TLASTLIB = $(BLD)/lastfile.$(A) 41TLASTLIB = $(BLD)/lastfile.$(A)
42GNULIB = ../lib/$(BLD)/libgnu.$(A) 42GNULIB = ../lib/$(BLD)/libgnu.$(A)
43 43
44DOC = $(OBJDIR)/etc/DOC-X 44DOC = $(OBJDIR)/etc/DOC
45 45
46FULL_LINK_FLAGS = $(LINK_FLAGS) $(TEMACS_EXTRA_LINK) 46FULL_LINK_FLAGS = $(LINK_FLAGS) $(TEMACS_EXTRA_LINK)
47 47
diff --git a/src/nsfns.m b/src/nsfns.m
index 95fdd516b99..7643c8b6e1d 100644
--- a/src/nsfns.m
+++ b/src/nsfns.m
@@ -44,6 +44,10 @@ GNUstep port and post-20 update by Adrian Robert (arobert@cogsci.ucsd.edu)
44#include "fontset.h" 44#include "fontset.h"
45#include "font.h" 45#include "font.h"
46 46
47#ifdef NS_IMPL_COCOA
48#include <IOKit/graphics/IOGraphicsLib.h>
49#endif
50
47#if 0 51#if 0
48int fns_trace_num = 1; 52int fns_trace_num = 1;
49#define NSTRACE(x) fprintf (stderr, "%s:%d: [%d] " #x "\n", \ 53#define NSTRACE(x) fprintf (stderr, "%s:%d: [%d] " #x "\n", \
@@ -101,50 +105,53 @@ static int as_status;
101static ptrdiff_t image_cache_refcount; 105static ptrdiff_t image_cache_refcount;
102#endif 106#endif
103 107
108static Lisp_Object Qgeometry, Qworkarea, Qmm_size, Qframes, Qsource;
109
104/* ========================================================================== 110/* ==========================================================================
105 111
106 Internal utility functions 112 Internal utility functions
107 113
108 ========================================================================== */ 114 ========================================================================== */
109 115
110/* Let the user specify an Nextstep display with a frame. 116/* Let the user specify a Nextstep display with a Lisp object.
111 nil stands for the selected frame--or, if that is not an Nextstep frame, 117 OBJECT may be nil, a frame or a terminal object.
118 nil stands for the selected frame--or, if that is not a Nextstep frame,
112 the first Nextstep display on the list. */ 119 the first Nextstep display on the list. */
120
113static struct ns_display_info * 121static struct ns_display_info *
114check_ns_display_info (Lisp_Object frame) 122check_ns_display_info (Lisp_Object object)
115{ 123{
116 if (NILP (frame)) 124 struct ns_display_info *dpyinfo = NULL;
125
126 if (NILP (object))
117 { 127 {
118 struct frame *f = SELECTED_FRAME (); 128 struct frame *sf = XFRAME (selected_frame);
119 if (FRAME_NS_P (f) && FRAME_LIVE_P (f) ) 129
120 return FRAME_NS_DISPLAY_INFO (f); 130 if (FRAME_NS_P (sf) && FRAME_LIVE_P (sf))
131 dpyinfo = FRAME_NS_DISPLAY_INFO (sf);
121 else if (x_display_list != 0) 132 else if (x_display_list != 0)
122 return x_display_list; 133 dpyinfo = x_display_list;
123 else 134 else
124 error ("Nextstep windows are not in use or not initialized"); 135 error ("Nextstep windows are not in use or not initialized");
125 } 136 }
126 else if (INTEGERP (frame)) 137 else if (TERMINALP (object))
127 { 138 {
128 struct terminal *t = get_terminal (frame, 1); 139 struct terminal *t = get_terminal (object, 1);
129 140
130 if (t->type != output_ns) 141 if (t->type != output_ns)
131 error ("Terminal %"pI"d is not a Nextstep display", XINT (frame)); 142 error ("Terminal %d is not a Nextstep display", t->id);
132 143
133 return t->display_info.ns; 144 dpyinfo = t->display_info.ns;
134 } 145 }
135 else if (STRINGP (frame)) 146 else if (STRINGP (object))
136 return ns_display_info_for_name (frame); 147 dpyinfo = ns_display_info_for_name (object);
137 else 148 else
138 { 149 {
139 FRAME_PTR f; 150 FRAME_PTR f = decode_window_system_frame (object);
140 151 dpyinfo = FRAME_NS_DISPLAY_INFO (f);
141 CHECK_LIVE_FRAME (frame);
142 f = XFRAME (frame);
143 if (! FRAME_NS_P (f))
144 error ("non-Nextstep frame used");
145 return FRAME_NS_DISPLAY_INFO (f);
146 } 152 }
147 return NULL; /* shut compiler up */ 153
154 return dpyinfo;
148} 155}
149 156
150 157
@@ -164,35 +171,6 @@ ns_get_window (Lisp_Object maybeFrame)
164} 171}
165 172
166 173
167static NSScreen *
168ns_get_screen (Lisp_Object screen)
169{
170 struct frame *f;
171 struct terminal *terminal;
172
173 if (EQ (Qt, screen)) /* not documented */
174 return [NSScreen mainScreen];
175
176 terminal = get_terminal (screen, 1);
177 if (terminal->type != output_ns)
178 return NULL;
179
180 if (NILP (screen))
181 f = SELECTED_FRAME ();
182 else if (FRAMEP (screen))
183 f = XFRAME (screen);
184 else
185 {
186 struct ns_display_info *dpyinfo = terminal->display_info.ns;
187 f = dpyinfo->x_focus_frame
188 ? dpyinfo->x_focus_frame : dpyinfo->x_highlight_frame;
189 }
190
191 return ((f && FRAME_NS_P (f)) ? [[FRAME_NS_VIEW (f) window] screen]
192 : NULL);
193}
194
195
196/* Return the X display structure for the display named NAME. 174/* Return the X display structure for the display named NAME.
197 Open a new connection if necessary. */ 175 Open a new connection if necessary. */
198struct ns_display_info * 176struct ns_display_info *
@@ -1580,9 +1558,9 @@ DEFUN ("x-server-max-request-size", Fx_server_max_request_size,
1580 Sx_server_max_request_size, 1558 Sx_server_max_request_size,
1581 0, 1, 0, 1559 0, 1, 0,
1582 doc: /* This function is a no-op. It is only present for completeness. */) 1560 doc: /* This function is a no-op. It is only present for completeness. */)
1583 (Lisp_Object display) 1561 (Lisp_Object terminal)
1584{ 1562{
1585 check_ns_display_info (display); 1563 check_ns_display_info (terminal);
1586 /* This function has no real equivalent under NeXTstep. Return nil to 1564 /* This function has no real equivalent under NeXTstep. Return nil to
1587 indicate this. */ 1565 indicate this. */
1588 return Qnil; 1566 return Qnil;
@@ -1590,11 +1568,15 @@ DEFUN ("x-server-max-request-size", Fx_server_max_request_size,
1590 1568
1591 1569
1592DEFUN ("x-server-vendor", Fx_server_vendor, Sx_server_vendor, 0, 1, 0, 1570DEFUN ("x-server-vendor", Fx_server_vendor, Sx_server_vendor, 0, 1, 0,
1593 doc: /* Return the vendor ID string of Nextstep display server DISPLAY. 1571 doc: /* Return the "vendor ID" string of Nextstep display server TERMINAL.
1594DISPLAY should be either a frame or a display name (a string). 1572\(Labeling every distributor as a "vendor" embodies the false assumption
1595If omitted or nil, the selected frame's display is used. */) 1573that operating systems cannot be developed and distributed noncommercially.)
1596 (Lisp_Object display) 1574The optional argument TERMINAL specifies which display to ask about.
1575TERMINAL should be a terminal object, a frame or a display name (a string).
1576If omitted or nil, that stands for the selected frame's display. */)
1577 (Lisp_Object terminal)
1597{ 1578{
1579 check_ns_display_info (terminal);
1598#ifdef NS_IMPL_GNUSTEP 1580#ifdef NS_IMPL_GNUSTEP
1599 return build_string ("GNU"); 1581 return build_string ("GNU");
1600#else 1582#else
@@ -1604,16 +1586,17 @@ If omitted or nil, the selected frame's display is used. */)
1604 1586
1605 1587
1606DEFUN ("x-server-version", Fx_server_version, Sx_server_version, 0, 1, 0, 1588DEFUN ("x-server-version", Fx_server_version, Sx_server_version, 0, 1, 0,
1607 doc: /* Return the version numbers of the server of DISPLAY. 1589 doc: /* Return the version numbers of the server of display TERMINAL.
1608The value is a list of three integers: the major and minor 1590The value is a list of three integers: the major and minor
1609version numbers of the X Protocol in use, and the distributor-specific 1591version numbers of the X Protocol in use, and the distributor-specific release
1610release number. See also the function `x-server-vendor'. 1592number. See also the function `x-server-vendor'.
1611 1593
1612The optional argument DISPLAY specifies which display to ask about. 1594The optional argument TERMINAL specifies which display to ask about.
1613DISPLAY should be either a frame or a display name (a string). 1595TERMINAL should be a terminal object, a frame or a display name (a string).
1614If omitted or nil, that stands for the selected frame's display. */) 1596If omitted or nil, that stands for the selected frame's display. */)
1615 (Lisp_Object display) 1597 (Lisp_Object terminal)
1616{ 1598{
1599 check_ns_display_info (terminal);
1617 /*NOTE: it is unclear what would best correspond with "protocol"; 1600 /*NOTE: it is unclear what would best correspond with "protocol";
1618 we return 10.3, meaning Panther, since this is roughly the 1601 we return 10.3, meaning Panther, since this is roughly the
1619 level that GNUstep's APIs correspond to. 1602 level that GNUstep's APIs correspond to.
@@ -1625,56 +1608,66 @@ If omitted or nil, that stands for the selected frame's display. */)
1625 1608
1626 1609
1627DEFUN ("x-display-screens", Fx_display_screens, Sx_display_screens, 0, 1, 0, 1610DEFUN ("x-display-screens", Fx_display_screens, Sx_display_screens, 0, 1, 0,
1628 doc: /* Return the number of screens on Nextstep display server DISPLAY. 1611 doc: /* Return the number of screens on Nextstep display server TERMINAL.
1629DISPLAY should be a frame, the display name as a string, or a terminal ID. 1612The optional argument TERMINAL specifies which display to ask about.
1630If omitted or nil, the selected frame's display is used. */) 1613TERMINAL should be a terminal object, a frame or a display name (a string).
1631 (Lisp_Object display) 1614If omitted or nil, that stands for the selected frame's display.
1632{
1633 int num;
1634
1635 check_ns_display_info (display);
1636 num = [[NSScreen screens] count];
1637 1615
1638 return (num != 0) ? make_number (num) : Qnil; 1616Note: "screen" here is not in Nextstep terminology but in X11's. For
1617the number of physical monitors, use `(length
1618(display-monitor-attributes-list TERMINAL))' instead. */)
1619 (Lisp_Object terminal)
1620{
1621 check_ns_display_info (terminal);
1622 return make_number (1);
1639} 1623}
1640 1624
1641 1625
1642DEFUN ("x-display-mm-height", Fx_display_mm_height, Sx_display_mm_height, 1626DEFUN ("x-display-mm-height", Fx_display_mm_height, Sx_display_mm_height, 0, 1, 0,
1643 0, 1, 0, 1627 doc: /* Return the height in millimeters of the Nextstep display TERMINAL.
1644 doc: /* Return the height of Nextstep display server DISPLAY, in millimeters. 1628The optional argument TERMINAL specifies which display to ask about.
1645DISPLAY should be a frame, the display name as a string, or a terminal ID. 1629TERMINAL should be a terminal object, a frame or a display name (a string).
1646If omitted or nil, the selected frame's display is used. */) 1630If omitted or nil, that stands for the selected frame's display.
1647 (Lisp_Object display) 1631
1632On \"multi-monitor\" setups this refers to the height in millimeters for
1633all physical monitors associated with TERMINAL. To get information
1634for each physical monitor, use `display-monitor-attributes-list'. */)
1635 (Lisp_Object terminal)
1648{ 1636{
1649 check_ns_display_info (display); 1637 struct ns_display_info *dpyinfo = check_ns_display_info (terminal);
1650 return make_number ((int) 1638
1651 ([ns_get_screen (display) frame].size.height/(92.0/25.4))); 1639 return make_number (x_display_pixel_height (dpyinfo) / (92.0/25.4));
1652} 1640}
1653 1641
1654 1642
1655DEFUN ("x-display-mm-width", Fx_display_mm_width, Sx_display_mm_width, 1643DEFUN ("x-display-mm-width", Fx_display_mm_width, Sx_display_mm_width, 0, 1, 0,
1656 0, 1, 0, 1644 doc: /* Return the width in millimeters of the Nextstep display TERMINAL.
1657 doc: /* Return the width of Nextstep display server DISPLAY, in millimeters. 1645The optional argument TERMINAL specifies which display to ask about.
1658DISPLAY should be a frame, the display name as a string, or a terminal ID. 1646TERMINAL should be a terminal object, a frame or a display name (a string).
1659If omitted or nil, the selected frame's display is used. */) 1647If omitted or nil, that stands for the selected frame's display.
1660 (Lisp_Object display) 1648
1649On \"multi-monitor\" setups this refers to the width in millimeters for
1650all physical monitors associated with TERMINAL. To get information
1651for each physical monitor, use `display-monitor-attributes-list'. */)
1652 (Lisp_Object terminal)
1661{ 1653{
1662 check_ns_display_info (display); 1654 struct ns_display_info *dpyinfo = check_ns_display_info (terminal);
1663 return make_number ((int) 1655
1664 ([ns_get_screen (display) frame].size.width/(92.0/25.4))); 1656 return make_number (x_display_pixel_width (dpyinfo) / (92.0/25.4));
1665} 1657}
1666 1658
1667 1659
1668DEFUN ("x-display-backing-store", Fx_display_backing_store, 1660DEFUN ("x-display-backing-store", Fx_display_backing_store,
1669 Sx_display_backing_store, 0, 1, 0, 1661 Sx_display_backing_store, 0, 1, 0,
1670 doc: /* Return whether the Nextstep display DISPLAY supports backing store. 1662 doc: /* Return an indication of whether the Nextstep display TERMINAL does backing store.
1671The value may be `buffered', `retained', or `non-retained'. 1663The value may be `buffered', `retained', or `non-retained'.
1672DISPLAY should be a frame, the display name as a string, or a terminal ID. 1664The optional argument TERMINAL specifies which display to ask about.
1673If omitted or nil, the selected frame's display is used. */) 1665TERMINAL should be a terminal object, a frame or a display name (a string).
1674 (Lisp_Object display) 1666If omitted or nil, that stands for the selected frame's display. */)
1667 (Lisp_Object terminal)
1675{ 1668{
1676 check_ns_display_info (display); 1669 check_ns_display_info (terminal);
1677 switch ([ns_get_window (display) backingType]) 1670 switch ([ns_get_window (terminal) backingType])
1678 { 1671 {
1679 case NSBackingStoreBuffered: 1672 case NSBackingStoreBuffered:
1680 return intern ("buffered"); 1673 return intern ("buffered");
@@ -1691,17 +1684,19 @@ If omitted or nil, the selected frame's display is used. */)
1691 1684
1692DEFUN ("x-display-visual-class", Fx_display_visual_class, 1685DEFUN ("x-display-visual-class", Fx_display_visual_class,
1693 Sx_display_visual_class, 0, 1, 0, 1686 Sx_display_visual_class, 0, 1, 0,
1694 doc: /* Return the visual class of the Nextstep display server DISPLAY. 1687 doc: /* Return the visual class of the Nextstep display TERMINAL.
1695The value is one of the symbols `static-gray', `gray-scale', 1688The value is one of the symbols `static-gray', `gray-scale',
1696`static-color', `pseudo-color', `true-color', or `direct-color'. 1689`static-color', `pseudo-color', `true-color', or `direct-color'.
1697DISPLAY should be a frame, the display name as a string, or a terminal ID. 1690
1698If omitted or nil, the selected frame's display is used. */) 1691The optional argument TERMINAL specifies which display to ask about.
1699 (Lisp_Object display) 1692TERMINAL should a terminal object, a frame or a display name (a string).
1693If omitted or nil, that stands for the selected frame's display. */)
1694 (Lisp_Object terminal)
1700{ 1695{
1701 NSWindowDepth depth; 1696 NSWindowDepth depth;
1702 1697
1703 check_ns_display_info (display); 1698 check_ns_display_info (terminal);
1704 depth = [ns_get_screen (display) depth]; 1699 depth = [[[NSScreen screens] objectAtIndex:0] depth];
1705 1700
1706 if ( depth == NSBestDepth (NSCalibratedWhiteColorSpace, 2, 2, YES, NULL)) 1701 if ( depth == NSBestDepth (NSCalibratedWhiteColorSpace, 2, 2, YES, NULL))
1707 return intern ("static-gray"); 1702 return intern ("static-gray");
@@ -1721,14 +1716,14 @@ If omitted or nil, the selected frame's display is used. */)
1721 1716
1722DEFUN ("x-display-save-under", Fx_display_save_under, 1717DEFUN ("x-display-save-under", Fx_display_save_under,
1723 Sx_display_save_under, 0, 1, 0, 1718 Sx_display_save_under, 0, 1, 0,
1724 doc: /* Return t if DISPLAY supports the save-under feature. 1719 doc: /* Return t if TERMINAL supports the save-under feature.
1725The optional argument DISPLAY specifies which display to ask about. 1720The optional argument TERMINAL specifies which display to ask about.
1726DISPLAY should be a frame, the display name as a string, or a terminal ID. 1721TERMINAL should be a terminal object, a frame or a display name (a string).
1727If omitted or nil, the selected frame's display is used. */) 1722If omitted or nil, that stands for the selected frame's display. */)
1728 (Lisp_Object display) 1723 (Lisp_Object terminal)
1729{ 1724{
1730 check_ns_display_info (display); 1725 check_ns_display_info (terminal);
1731 switch ([ns_get_window (display) backingType]) 1726 switch ([ns_get_window (terminal) backingType])
1732 { 1727 {
1733 case NSBackingStoreBuffered: 1728 case NSBackingStoreBuffered:
1734 return Qt; 1729 return Qt;
@@ -1776,11 +1771,13 @@ terminate Emacs if we can't open the connection.
1776 1771
1777DEFUN ("x-close-connection", Fx_close_connection, Sx_close_connection, 1772DEFUN ("x-close-connection", Fx_close_connection, Sx_close_connection,
1778 1, 1, 0, 1773 1, 1, 0,
1779 doc: /* Close the connection to the current Nextstep display server. 1774 doc: /* Close the connection to TERMINAL's Nextstep display server.
1780DISPLAY should be a frame, the display name as a string, or a terminal ID. */) 1775For TERMINAL, specify a terminal object, a frame or a display name (a
1781 (Lisp_Object display) 1776string). If TERMINAL is nil, that stands for the selected frame's
1777terminal. */)
1778 (Lisp_Object terminal)
1782{ 1779{
1783 check_ns_display_info (display); 1780 check_ns_display_info (terminal);
1784 [NSApp terminate: NSApp]; 1781 [NSApp terminate: NSApp];
1785 return Qnil; 1782 return Qnil;
1786} 1783}
@@ -2263,13 +2260,13 @@ DEFUN ("xw-color-values", Fxw_color_values, Sxw_color_values, 1, 2, 0,
2263 2260
2264DEFUN ("xw-display-color-p", Fxw_display_color_p, Sxw_display_color_p, 0, 1, 0, 2261DEFUN ("xw-display-color-p", Fxw_display_color_p, Sxw_display_color_p, 0, 1, 0,
2265 doc: /* Internal function called by `display-color-p', which see. */) 2262 doc: /* Internal function called by `display-color-p', which see. */)
2266 (Lisp_Object display) 2263 (Lisp_Object terminal)
2267{ 2264{
2268 NSWindowDepth depth; 2265 NSWindowDepth depth;
2269 NSString *colorSpace; 2266 NSString *colorSpace;
2270 2267
2271 check_ns_display_info (display); 2268 check_ns_display_info (terminal);
2272 depth = [ns_get_screen (display) depth]; 2269 depth = [[[NSScreen screens] objectAtIndex:0] depth];
2273 colorSpace = NSColorSpaceFromDepth (depth); 2270 colorSpace = NSColorSpaceFromDepth (depth);
2274 2271
2275 return [colorSpace isEqualToString: NSDeviceWhiteColorSpace] 2272 return [colorSpace isEqualToString: NSDeviceWhiteColorSpace]
@@ -2278,19 +2275,19 @@ DEFUN ("xw-display-color-p", Fxw_display_color_p, Sxw_display_color_p, 0, 1, 0,
2278} 2275}
2279 2276
2280 2277
2281DEFUN ("x-display-grayscale-p", Fx_display_grayscale_p, 2278DEFUN ("x-display-grayscale-p", Fx_display_grayscale_p, Sx_display_grayscale_p,
2282 Sx_display_grayscale_p, 0, 1, 0, 2279 0, 1, 0,
2283 doc: /* Return t if the Nextstep display supports shades of gray. 2280 doc: /* Return t if the Nextstep display supports shades of gray.
2284Note that color displays do support shades of gray. 2281Note that color displays do support shades of gray.
2285The optional argument DISPLAY specifies which display to ask about. 2282The optional argument TERMINAL specifies which display to ask about.
2286DISPLAY should be either a frame, a display name (a string), or terminal ID. 2283TERMINAL should be a terminal object, a frame or a display name (a string).
2287If omitted or nil, that stands for the selected frame's display. */) 2284If omitted or nil, that stands for the selected frame's display. */)
2288 (Lisp_Object display) 2285 (Lisp_Object terminal)
2289{ 2286{
2290 NSWindowDepth depth; 2287 NSWindowDepth depth;
2291 2288
2292 check_ns_display_info (display); 2289 check_ns_display_info (terminal);
2293 depth = [ns_get_screen (display) depth]; 2290 depth = [[[NSScreen screens] objectAtIndex:0] depth];
2294 2291
2295 return NSBitsPerPixelFromDepth (depth) > 1 ? Qt : Qnil; 2292 return NSBitsPerPixelFromDepth (depth) > 1 ? Qt : Qnil;
2296} 2293}
@@ -2298,84 +2295,280 @@ If omitted or nil, that stands for the selected frame's display. */)
2298 2295
2299DEFUN ("x-display-pixel-width", Fx_display_pixel_width, Sx_display_pixel_width, 2296DEFUN ("x-display-pixel-width", Fx_display_pixel_width, Sx_display_pixel_width,
2300 0, 1, 0, 2297 0, 1, 0,
2301 doc: /* Return the width in pixels of the Nextstep display DISPLAY. 2298 doc: /* Return the width in pixels of the Nextstep display TERMINAL.
2302The optional argument DISPLAY specifies which display to ask about. 2299The optional argument TERMINAL specifies which display to ask about.
2303DISPLAY should be either a frame, a display name (a string), or terminal ID. 2300TERMINAL should be a terminal object, a frame or a display name (a string).
2304If omitted or nil, that stands for the selected frame's display. */) 2301If omitted or nil, that stands for the selected frame's display.
2305 (Lisp_Object display) 2302
2303On \"multi-monitor\" setups this refers to the pixel width for all
2304physical monitors associated with TERMINAL. To get information for
2305each physical monitor, use `display-monitor-attributes-list'. */)
2306 (Lisp_Object terminal)
2306{ 2307{
2307 check_ns_display_info (display); 2308 struct ns_display_info *dpyinfo = check_ns_display_info (terminal);
2308 return make_number ((int) [ns_get_screen (display) frame].size.width); 2309
2310 return make_number (x_display_pixel_width (dpyinfo));
2309} 2311}
2310 2312
2311 2313
2312DEFUN ("x-display-pixel-height", Fx_display_pixel_height, 2314DEFUN ("x-display-pixel-height", Fx_display_pixel_height,
2313 Sx_display_pixel_height, 0, 1, 0, 2315 Sx_display_pixel_height, 0, 1, 0,
2314 doc: /* Return the height in pixels of the Nextstep display DISPLAY. 2316 doc: /* Return the height in pixels of the Nextstep display TERMINAL.
2315The optional argument DISPLAY specifies which display to ask about. 2317The optional argument TERMINAL specifies which display to ask about.
2316DISPLAY should be either a frame, a display name (a string), or terminal ID. 2318TERMINAL should be a terminal object, a frame or a display name (a string).
2317If omitted or nil, that stands for the selected frame's display. */) 2319If omitted or nil, that stands for the selected frame's display.
2318 (Lisp_Object display) 2320
2321On \"multi-monitor\" setups this refers to the pixel height for all
2322physical monitors associated with TERMINAL. To get information for
2323each physical monitor, use `display-monitor-attributes-list'. */)
2324 (Lisp_Object terminal)
2319{ 2325{
2320 check_ns_display_info (display); 2326 struct ns_display_info *dpyinfo = check_ns_display_info (terminal);
2321 return make_number ((int) [ns_get_screen (display) frame].size.height); 2327
2328 return make_number (x_display_pixel_height (dpyinfo));
2322} 2329}
2323 2330
2331struct MonitorInfo {
2332 XRectangle geom, work;
2333 int mm_width, mm_height;
2334 char *name;
2335};
2324 2336
2325DEFUN ("display-usable-bounds", Fns_display_usable_bounds, 2337static void
2326 Sns_display_usable_bounds, 0, 1, 0, 2338free_monitors (struct MonitorInfo *monitors, int n_monitors)
2327 doc: /* Return the bounds of the usable part of the screen. 2339{
2328The return value is a list of integers (LEFT TOP WIDTH HEIGHT), which 2340 int i;
2329are the boundaries of the usable part of the screen, excluding areas 2341 for (i = 0; i < n_monitors; ++i)
2330reserved for the Mac menu, dock, and so forth. 2342 xfree (monitors[i].name);
2343 xfree (monitors);
2344}
2331 2345
2332The screen queried corresponds to DISPLAY, which should be either a 2346#ifdef NS_IMPL_COCOA
2333frame, a display name (a string), or terminal ID. If omitted or nil, 2347/* Returns the name for the screen that DICT came from, or NULL.
2334that stands for the selected frame's display. */) 2348 Caller must free return value.
2335 (Lisp_Object display) 2349*/
2350
2351char *
2352ns_screen_name (CGDirectDisplayID did)
2353{
2354 char *name = NULL;
2355 NSDictionary *info = (NSDictionary *)
2356 IODisplayCreateInfoDictionary (CGDisplayIOServicePort (did),
2357 kIODisplayOnlyPreferredName);
2358 NSDictionary *names
2359 = [info objectForKey:
2360 [NSString stringWithUTF8String:kDisplayProductName]];
2361
2362 if ([names count] > 0) {
2363 NSString *n = [names objectForKey: [[names allKeys] objectAtIndex:0]];
2364 if (n != nil)
2365 name = xstrdup ([n UTF8String]);
2366 }
2367
2368 [info release];
2369 return name;
2370}
2371#endif
2372
2373static Lisp_Object
2374ns_make_monitor_attribute_list (struct MonitorInfo *monitors,
2375 int n_monitors,
2376 int primary_monitor,
2377 const char *source)
2378{
2379 Lisp_Object monitor_frames = Fmake_vector (make_number (n_monitors), Qnil);
2380 Lisp_Object frame, rest, attributes_list = Qnil;
2381 Lisp_Object primary_monitor_attributes = Qnil;
2382 NSArray *screens = [NSScreen screens];
2383 int i;
2384
2385 FOR_EACH_FRAME (rest, frame)
2386 {
2387 struct frame *f = XFRAME (frame);
2388
2389 if (FRAME_NS_P (f))
2390 {
2391 NSView *view = FRAME_NS_VIEW (f);
2392 NSScreen *screen = [[view window] screen];
2393 NSUInteger k;
2394
2395 i = -1;
2396 for (k = 0; i == -1 && k < [screens count]; ++k)
2397 {
2398 if ([screens objectAtIndex: k] == screen)
2399 i = (int)k;
2400 }
2401
2402 if (i > -1)
2403 ASET (monitor_frames, i, Fcons (frame, AREF (monitor_frames, i)));
2404 }
2405 }
2406
2407 for (i = 0; i < n_monitors; ++i)
2408 {
2409 Lisp_Object geometry, workarea, attributes = Qnil;
2410 struct MonitorInfo *mi = &monitors[i];
2411
2412 if (mi->geom.width == 0) continue;
2413
2414 workarea = list4i (mi->work.x, mi->work.y,
2415 mi->work.width, mi->work.height);
2416 geometry = list4i (mi->geom.x, mi->geom.y,
2417 mi->geom.width, mi->geom.height);
2418 attributes = Fcons (Fcons (Qsource,
2419 make_string (source, strlen (source))),
2420 attributes);
2421 attributes = Fcons (Fcons (Qframes, AREF (monitor_frames, i)),
2422 attributes);
2423 attributes = Fcons (Fcons (Qmm_size,
2424 list2i (mi->mm_width, mi->mm_height)),
2425 attributes);
2426 attributes = Fcons (Fcons (Qworkarea, workarea), attributes);
2427 attributes = Fcons (Fcons (Qgeometry, geometry), attributes);
2428 if (mi->name)
2429 attributes = Fcons (Fcons (Qname, make_string (mi->name,
2430 strlen (mi->name))),
2431 attributes);
2432
2433 if (i == primary_monitor)
2434 primary_monitor_attributes = attributes;
2435 else
2436 attributes_list = Fcons (attributes, attributes_list);
2437 }
2438
2439 if (!NILP (primary_monitor_attributes))
2440 attributes_list = Fcons (primary_monitor_attributes, attributes_list);
2441 return attributes_list;
2442}
2443
2444DEFUN ("ns-display-monitor-attributes-list",
2445 Fns_display_monitor_attributes_list,
2446 Sns_display_monitor_attributes_list,
2447 0, 1, 0,
2448 doc: /* Return a list of physical monitor attributes on the X display TERMINAL.
2449
2450The optional argument TERMINAL specifies which display to ask about.
2451TERMINAL should be a terminal object, a frame or a display name (a string).
2452If omitted or nil, that stands for the selected frame's display.
2453
2454In addition to the standard attribute keys listed in
2455`display-monitor-attributes-list', the following keys are contained in
2456the attributes:
2457
2458 source -- String describing the source from which multi-monitor
2459 information is obtained, \"NS\" is always the source."
2460
2461Internal use only, use `display-monitor-attributes-list' instead. */)
2462 (Lisp_Object terminal)
2336{ 2463{
2337 NSScreen *screen; 2464 struct terminal *term = get_terminal (terminal, 1);
2338 NSRect vScreen; 2465 NSArray *screens;
2466 NSUInteger i, n_monitors;
2467 struct MonitorInfo *monitors;
2468 Lisp_Object attributes_list = Qnil;
2469 CGFloat primary_display_height = 0;
2470
2471 if (term->type != output_ns)
2472 return Qnil;
2339 2473
2340 check_ns_display_info (display); 2474 screens = [NSScreen screens];
2341 screen = ns_get_screen (display); 2475 n_monitors = [screens count];
2342 if (!screen) 2476 if (n_monitors == 0)
2343 return Qnil; 2477 return Qnil;
2344 2478
2345 vScreen = [screen visibleFrame]; 2479 monitors = (struct MonitorInfo *) xzalloc (n_monitors * sizeof (*monitors));
2480
2481 for (i = 0; i < [screens count]; ++i)
2482 {
2483 NSScreen *s = [screens objectAtIndex:i];
2484 struct MonitorInfo *m = &monitors[i];
2485 NSRect fr = [s frame];
2486 NSRect vfr = [s visibleFrame];
2487 NSDictionary *dict = [s deviceDescription];
2488 NSValue *resval = [dict valueForKey:NSDeviceResolution];
2489 short y, vy;
2490
2491#ifdef NS_IMPL_COCOA
2492 NSNumber *nid = [dict objectForKey:@"NSScreenNumber"];
2493 CGDirectDisplayID did = [nid unsignedIntValue];
2494#endif
2495 if (i == 0)
2496 {
2497 primary_display_height = fr.size.height;
2498 y = (short) fr.origin.y;
2499 vy = (short) vfr.origin.y;
2500 }
2501 else
2502 {
2503 // Flip y coordinate as NS has y starting from the bottom.
2504 y = (short) (primary_display_height - fr.size.height - fr.origin.y);
2505 vy = (short) (primary_display_height -
2506 vfr.size.height - vfr.origin.y);
2507 }
2508
2509 m->geom.x = (short) fr.origin.x;
2510 m->geom.y = y;
2511 m->geom.width = (unsigned short) fr.size.width;
2512 m->geom.height = (unsigned short) fr.size.height;
2513
2514 m->work.x = (short) vfr.origin.x;
2515 // y is flipped on NS, so vy - y are pixels missing at the bottom,
2516 // and fr.size.height - vfr.size.height are pixels missing in total.
2517 // Pixels missing at top are
2518 // fr.size.height - vfr.size.height - vy + y.
2519 // work.y is then pixels missing at top + y.
2520 m->work.y = (short) (fr.size.height - vfr.size.height) - vy + y + y;
2521 m->work.width = (unsigned short) vfr.size.width;
2522 m->work.height = (unsigned short) vfr.size.height;
2523
2524#ifdef NS_IMPL_COCOA
2525 m->name = ns_screen_name (did);
2526
2527 {
2528 CGSize mms = CGDisplayScreenSize (did);
2529 m->mm_width = (int) mms.width;
2530 m->mm_height = (int) mms.height;
2531 }
2346 2532
2347 /* NS coordinate system is upside-down. 2533#else
2348 Transform to screen-specific coordinates. */ 2534 // Assume 92 dpi as x-display-mm-height/x-display-mm-width does.
2349 return list4i (vScreen.origin.x, 2535 m->mm_width = (int) (25.4 * fr.size.width / 92.0);
2350 [screen frame].size.height 2536 m->mm_height = (int) (25.4 * fr.size.height / 92.0);
2351 - vScreen.size.height - vScreen.origin.y, 2537#endif
2352 vScreen.size.width, vScreen.size.height); 2538 }
2539
2540 // Primary monitor is always first for NS.
2541 attributes_list = ns_make_monitor_attribute_list (monitors, n_monitors,
2542 0, "NS");
2543
2544 free_monitors (monitors, n_monitors);
2545 return attributes_list;
2353} 2546}
2354 2547
2355 2548
2356DEFUN ("x-display-planes", Fx_display_planes, Sx_display_planes, 2549DEFUN ("x-display-planes", Fx_display_planes, Sx_display_planes,
2357 0, 1, 0, 2550 0, 1, 0,
2358 doc: /* Return the number of bitplanes of the Nextstep display DISPLAY. 2551 doc: /* Return the number of bitplanes of the Nextstep display TERMINAL.
2359The optional argument DISPLAY specifies which display to ask about. 2552The optional argument TERMINAL specifies which display to ask about.
2360DISPLAY should be either a frame, a display name (a string), or terminal ID. 2553TERMINAL should be a terminal object, a frame or a display name (a string).
2361If omitted or nil, that stands for the selected frame's display. */) 2554If omitted or nil, that stands for the selected frame's display. */)
2362 (Lisp_Object display) 2555 (Lisp_Object terminal)
2363{ 2556{
2364 check_ns_display_info (display); 2557 check_ns_display_info (terminal);
2365 return make_number 2558 return make_number
2366 (NSBitsPerPixelFromDepth ([ns_get_screen (display) depth])); 2559 (NSBitsPerPixelFromDepth ([[[NSScreen screens] objectAtIndex:0] depth]));
2367} 2560}
2368 2561
2369 2562
2370DEFUN ("x-display-color-cells", Fx_display_color_cells, 2563DEFUN ("x-display-color-cells", Fx_display_color_cells, Sx_display_color_cells,
2371 Sx_display_color_cells, 0, 1, 0, 2564 0, 1, 0,
2372 doc: /* Returns the number of color cells of the Nextstep display DISPLAY. 2565 doc: /* Returns the number of color cells of the Nextstep display TERMINAL.
2373The optional argument DISPLAY specifies which display to ask about. 2566The optional argument TERMINAL specifies which display to ask about.
2374DISPLAY should be either a frame, a display name (a string), or terminal ID. 2567TERMINAL should be a terminal object, a frame or a display name (a string).
2375If omitted or nil, that stands for the selected frame's display. */) 2568If omitted or nil, that stands for the selected frame's display. */)
2376 (Lisp_Object display) 2569 (Lisp_Object terminal)
2377{ 2570{
2378 struct ns_display_info *dpyinfo = check_ns_display_info (display); 2571 struct ns_display_info *dpyinfo = check_ns_display_info (terminal);
2379 /* We force 24+ bit depths to 24-bit to prevent an overflow. */ 2572 /* We force 24+ bit depths to 24-bit to prevent an overflow. */
2380 return make_number (1 << min (dpyinfo->n_planes, 24)); 2573 return make_number (1 << min (dpyinfo->n_planes, 24));
2381} 2574}
@@ -2729,6 +2922,11 @@ handlePanelKeys (NSSavePanel *panel, NSEvent *theEvent)
2729void 2922void
2730syms_of_nsfns (void) 2923syms_of_nsfns (void)
2731{ 2924{
2925 DEFSYM (Qgeometry, "geometry");
2926 DEFSYM (Qworkarea, "workarea");
2927 DEFSYM (Qmm_size, "mm-size");
2928 DEFSYM (Qframes, "frames");
2929 DEFSYM (Qsource, "source");
2732 Qfontsize = intern_c_string ("fontsize"); 2930 Qfontsize = intern_c_string ("fontsize");
2733 staticpro (&Qfontsize); 2931 staticpro (&Qfontsize);
2734 2932
@@ -2774,7 +2972,7 @@ be used as the image of the icon representing the frame. */);
2774 defsubr (&Sx_server_version); 2972 defsubr (&Sx_server_version);
2775 defsubr (&Sx_display_pixel_width); 2973 defsubr (&Sx_display_pixel_width);
2776 defsubr (&Sx_display_pixel_height); 2974 defsubr (&Sx_display_pixel_height);
2777 defsubr (&Sns_display_usable_bounds); 2975 defsubr (&Sns_display_monitor_attributes_list);
2778 defsubr (&Sx_display_mm_width); 2976 defsubr (&Sx_display_mm_width);
2779 defsubr (&Sx_display_mm_height); 2977 defsubr (&Sx_display_mm_height);
2780 defsubr (&Sx_display_screens); 2978 defsubr (&Sx_display_screens);
diff --git a/src/nsfont.m b/src/nsfont.m
index ebee363651f..9ab369d1fcd 100644
--- a/src/nsfont.m
+++ b/src/nsfont.m
@@ -151,10 +151,13 @@ ns_spec_to_descriptor (Lisp_Object font_spec)
151 if ([tdict count] > 0) 151 if ([tdict count] > 0)
152 [fdAttrs setObject: tdict forKey: NSFontTraitsAttribute]; 152 [fdAttrs setObject: tdict forKey: NSFontTraitsAttribute];
153 153
154 fdesc = [NSFontDescriptor fontDescriptorWithFontAttributes: fdAttrs]; 154 fdesc = [[[NSFontDescriptor fontDescriptorWithFontAttributes: fdAttrs]
155 retain] autorelease];
156
155 if (family != nil) 157 if (family != nil)
156 { 158 {
157 fdesc = [fdesc fontDescriptorWithFamily: family]; 159 NSFontDescriptor *fdesc2 = [fdesc fontDescriptorWithFamily: family];
160 fdesc = [[fdesc2 retain] autorelease];
158 } 161 }
159 162
160 [fdAttrs release]; 163 [fdAttrs release];
diff --git a/src/nsterm.m b/src/nsterm.m
index f5b48ee4b11..e882f00e977 100644
--- a/src/nsterm.m
+++ b/src/nsterm.m
@@ -3913,15 +3913,31 @@ x_wm_set_icon_position (struct frame *f, int icon_x, int icon_y)
3913int 3913int
3914x_display_pixel_height (struct ns_display_info *dpyinfo) 3914x_display_pixel_height (struct ns_display_info *dpyinfo)
3915{ 3915{
3916 NSScreen *screen = [NSScreen mainScreen]; 3916 NSArray *screens = [NSScreen screens];
3917 return [screen frame].size.height; 3917 NSEnumerator *enumerator = [screens objectEnumerator];
3918 NSScreen *screen;
3919 NSRect frame;
3920
3921 frame = NSZeroRect;
3922 while ((screen = [enumerator nextObject]) != nil)
3923 frame = NSUnionRect (frame, [screen frame]);
3924
3925 return NSHeight (frame);
3918} 3926}
3919 3927
3920int 3928int
3921x_display_pixel_width (struct ns_display_info *dpyinfo) 3929x_display_pixel_width (struct ns_display_info *dpyinfo)
3922{ 3930{
3923 NSScreen *screen = [NSScreen mainScreen]; 3931 NSArray *screens = [NSScreen screens];
3924 return [screen frame].size.width; 3932 NSEnumerator *enumerator = [screens objectEnumerator];
3933 NSScreen *screen;
3934 NSRect frame;
3935
3936 frame = NSZeroRect;
3937 while ((screen = [enumerator nextObject]) != nil)
3938 frame = NSUnionRect (frame, [screen frame]);
3939
3940 return NSWidth (frame);
3925} 3941}
3926 3942
3927 3943
diff --git a/src/process.c b/src/process.c
index 911a30bc808..46385fa096b 100644
--- a/src/process.c
+++ b/src/process.c
@@ -174,6 +174,8 @@ static Lisp_Object QClocal, QCremote, QCcoding;
174static Lisp_Object QCserver, QCnowait, QCnoquery, QCstop; 174static Lisp_Object QCserver, QCnowait, QCnoquery, QCstop;
175static Lisp_Object QCsentinel, QClog, QCoptions, QCplist; 175static Lisp_Object QCsentinel, QClog, QCoptions, QCplist;
176static Lisp_Object Qlast_nonmenu_event; 176static Lisp_Object Qlast_nonmenu_event;
177static Lisp_Object Qinternal_default_process_sentinel;
178static Lisp_Object Qinternal_default_process_filter;
177 179
178#define NETCONN_P(p) (EQ (XPROCESS (p)->type, Qnetwork)) 180#define NETCONN_P(p) (EQ (XPROCESS (p)->type, Qnetwork))
179#define NETCONN1_P(p) (EQ (p->type, Qnetwork)) 181#define NETCONN1_P(p) (EQ (p->type, Qnetwork))
@@ -359,7 +361,7 @@ pset_encoding_buf (struct Lisp_Process *p, Lisp_Object val)
359static void 361static void
360pset_filter (struct Lisp_Process *p, Lisp_Object val) 362pset_filter (struct Lisp_Process *p, Lisp_Object val)
361{ 363{
362 p->filter = val; 364 p->filter = NILP (val) ? Qinternal_default_process_filter : val;
363} 365}
364static void 366static void
365pset_log (struct Lisp_Process *p, Lisp_Object val) 367pset_log (struct Lisp_Process *p, Lisp_Object val)
@@ -384,7 +386,7 @@ pset_plist (struct Lisp_Process *p, Lisp_Object val)
384static void 386static void
385pset_sentinel (struct Lisp_Process *p, Lisp_Object val) 387pset_sentinel (struct Lisp_Process *p, Lisp_Object val)
386{ 388{
387 p->sentinel = val; 389 p->sentinel = NILP (val) ? Qinternal_default_process_sentinel : val;
388} 390}
389static void 391static void
390pset_status (struct Lisp_Process *p, Lisp_Object val) 392pset_status (struct Lisp_Process *p, Lisp_Object val)
@@ -700,6 +702,8 @@ make_process (Lisp_Object name)
700 } 702 }
701 name = name1; 703 name = name1;
702 pset_name (p, name); 704 pset_name (p, name);
705 pset_sentinel (p, Qinternal_default_process_sentinel);
706 pset_filter (p, Qinternal_default_process_filter);
703 XSETPROCESS (val, p); 707 XSETPROCESS (val, p);
704 Vprocess_alist = Fcons (Fcons (name, val), Vprocess_alist); 708 Vprocess_alist = Fcons (Fcons (name, val), Vprocess_alist);
705 return val; 709 return val;
@@ -979,10 +983,10 @@ DEFUN ("process-mark", Fprocess_mark, Sprocess_mark,
979 983
980DEFUN ("set-process-filter", Fset_process_filter, Sset_process_filter, 984DEFUN ("set-process-filter", Fset_process_filter, Sset_process_filter,
981 2, 2, 0, 985 2, 2, 0,
982 doc: /* Give PROCESS the filter function FILTER; nil means no filter. 986 doc: /* Give PROCESS the filter function FILTER; nil means default.
983A value of t means stop accepting output from the process. 987A value of t means stop accepting output from the process.
984 988
985When a process has a filter, its buffer is not used for output. 989When a process has a non-default filter, its buffer is not used for output.
986Instead, each time it does output, the entire string of output is 990Instead, each time it does output, the entire string of output is
987passed to the filter. 991passed to the filter.
988 992
@@ -1008,6 +1012,9 @@ The string argument is normally a multibyte string, except:
1008 (debug) 1012 (debug)
1009 (set-process-filter process ...) */ 1013 (set-process-filter process ...) */
1010 1014
1015 if (NILP (filter))
1016 filter = Qinternal_default_process_filter;
1017
1011 if (p->infd >= 0) 1018 if (p->infd >= 0)
1012 { 1019 {
1013 if (EQ (filter, Qt) && !EQ (p->status, Qlisten)) 1020 if (EQ (filter, Qt) && !EQ (p->status, Qlisten))
@@ -1033,7 +1040,7 @@ The string argument is normally a multibyte string, except:
1033 1040
1034DEFUN ("process-filter", Fprocess_filter, Sprocess_filter, 1041DEFUN ("process-filter", Fprocess_filter, Sprocess_filter,
1035 1, 1, 0, 1042 1, 1, 0,
1036 doc: /* Returns the filter function of PROCESS; nil if none. 1043 doc: /* Return the filter function of PROCESS.
1037See `set-process-filter' for more info on filter functions. */) 1044See `set-process-filter' for more info on filter functions. */)
1038 (register Lisp_Object process) 1045 (register Lisp_Object process)
1039{ 1046{
@@ -1043,7 +1050,7 @@ See `set-process-filter' for more info on filter functions. */)
1043 1050
1044DEFUN ("set-process-sentinel", Fset_process_sentinel, Sset_process_sentinel, 1051DEFUN ("set-process-sentinel", Fset_process_sentinel, Sset_process_sentinel,
1045 2, 2, 0, 1052 2, 2, 0,
1046 doc: /* Give PROCESS the sentinel SENTINEL; nil for none. 1053 doc: /* Give PROCESS the sentinel SENTINEL; nil for default.
1047The sentinel is called as a function when the process changes state. 1054The sentinel is called as a function when the process changes state.
1048It gets two arguments: the process, and a string describing the change. */) 1055It gets two arguments: the process, and a string describing the change. */)
1049 (register Lisp_Object process, Lisp_Object sentinel) 1056 (register Lisp_Object process, Lisp_Object sentinel)
@@ -1053,6 +1060,9 @@ It gets two arguments: the process, and a string describing the change. */)
1053 CHECK_PROCESS (process); 1060 CHECK_PROCESS (process);
1054 p = XPROCESS (process); 1061 p = XPROCESS (process);
1055 1062
1063 if (NILP (sentinel))
1064 sentinel = Qinternal_default_process_sentinel;
1065
1056 pset_sentinel (p, sentinel); 1066 pset_sentinel (p, sentinel);
1057 if (NETCONN1_P (p) || SERIALCONN1_P (p)) 1067 if (NETCONN1_P (p) || SERIALCONN1_P (p))
1058 pset_childp (p, Fplist_put (p->childp, QCsentinel, sentinel)); 1068 pset_childp (p, Fplist_put (p->childp, QCsentinel, sentinel));
@@ -1061,7 +1071,7 @@ It gets two arguments: the process, and a string describing the change. */)
1061 1071
1062DEFUN ("process-sentinel", Fprocess_sentinel, Sprocess_sentinel, 1072DEFUN ("process-sentinel", Fprocess_sentinel, Sprocess_sentinel,
1063 1, 1, 0, 1073 1, 1, 0,
1064 doc: /* Return the sentinel of PROCESS; nil if none. 1074 doc: /* Return the sentinel of PROCESS.
1065See `set-process-sentinel' for more info on sentinels. */) 1075See `set-process-sentinel' for more info on sentinels. */)
1066 (register Lisp_Object process) 1076 (register Lisp_Object process)
1067{ 1077{
@@ -1378,8 +1388,8 @@ usage: (start-process NAME BUFFER PROGRAM &rest PROGRAM-ARGS) */)
1378 pset_plist (XPROCESS (proc), Qnil); 1388 pset_plist (XPROCESS (proc), Qnil);
1379 pset_type (XPROCESS (proc), Qreal); 1389 pset_type (XPROCESS (proc), Qreal);
1380 pset_buffer (XPROCESS (proc), buffer); 1390 pset_buffer (XPROCESS (proc), buffer);
1381 pset_sentinel (XPROCESS (proc), Qnil); 1391 pset_sentinel (XPROCESS (proc), Qinternal_default_process_sentinel);
1382 pset_filter (XPROCESS (proc), Qnil); 1392 pset_filter (XPROCESS (proc), Qinternal_default_process_filter);
1383 pset_command (XPROCESS (proc), Flist (nargs - 2, args + 2)); 1393 pset_command (XPROCESS (proc), Flist (nargs - 2, args + 2));
1384 1394
1385#ifdef HAVE_GNUTLS 1395#ifdef HAVE_GNUTLS
@@ -4039,7 +4049,8 @@ server_accept_connection (Lisp_Object server, int channel)
4039 process name of the server process concatenated with the caller 4049 process name of the server process concatenated with the caller
4040 identification. */ 4050 identification. */
4041 4051
4042 if (!NILP (ps->filter) && !EQ (ps->filter, Qt)) 4052 if (!(EQ (ps->filter, Qinternal_default_process_filter)
4053 || EQ (ps->filter, Qt)))
4043 buffer = Qnil; 4054 buffer = Qnil;
4044 else 4055 else
4045 { 4056 {
@@ -4108,7 +4119,7 @@ server_accept_connection (Lisp_Object server, int channel)
4108 /* Setup coding system for new process based on server process. 4119 /* Setup coding system for new process based on server process.
4109 This seems to be the proper thing to do, as the coding system 4120 This seems to be the proper thing to do, as the coding system
4110 of the new process should reflect the settings at the time the 4121 of the new process should reflect the settings at the time the
4111 server socket was opened; not the current settings. */ 4122 server socket was opened; not the current settings. */
4112 4123
4113 pset_decode_coding_system (p, ps->decode_coding_system); 4124 pset_decode_coding_system (p, ps->decode_coding_system);
4114 pset_encode_coding_system (p, ps->encode_coding_system); 4125 pset_encode_coding_system (p, ps->encode_coding_system);
@@ -4127,11 +4138,10 @@ server_accept_connection (Lisp_Object server, int channel)
4127 (STRINGP (host) ? host : build_string ("-")), 4138 (STRINGP (host) ? host : build_string ("-")),
4128 build_string ("\n"))); 4139 build_string ("\n")));
4129 4140
4130 if (!NILP (p->sentinel)) 4141 exec_sentinel (proc,
4131 exec_sentinel (proc, 4142 concat3 (build_string ("open from "),
4132 concat3 (build_string ("open from "), 4143 (STRINGP (host) ? host : build_string ("-")),
4133 (STRINGP (host) ? host : build_string ("-")), 4144 build_string ("\n")));
4134 build_string ("\n")));
4135} 4145}
4136 4146
4137/* This variable is different from waiting_for_input in keyboard.c. 4147/* This variable is different from waiting_for_input in keyboard.c.
@@ -4263,8 +4273,8 @@ wait_reading_process_output (intmax_t time_limit, int nsecs, int read_kbd,
4263 if (! NILP (wait_for_cell) && ! NILP (XCAR (wait_for_cell))) 4273 if (! NILP (wait_for_cell) && ! NILP (XCAR (wait_for_cell)))
4264 break; 4274 break;
4265 4275
4266 /* Compute time from now till when time limit is up */ 4276 /* Compute time from now till when time limit is up. */
4267 /* Exit if already run out */ 4277 /* Exit if already run out. */
4268 if (nsecs < 0) 4278 if (nsecs < 0)
4269 { 4279 {
4270 /* A negative timeout means 4280 /* A negative timeout means
@@ -4871,8 +4881,8 @@ wait_reading_process_output (intmax_t time_limit, int nsecs, int read_kbd,
4871 } 4881 }
4872 } 4882 }
4873#endif /* NON_BLOCKING_CONNECT */ 4883#endif /* NON_BLOCKING_CONNECT */
4874 } /* end for each file descriptor */ 4884 } /* End for each file descriptor. */
4875 } /* end while exit conditions not met */ 4885 } /* End while exit conditions not met. */
4876 4886
4877 unbind_to (count, Qnil); 4887 unbind_to (count, Qnil);
4878 4888
@@ -4907,6 +4917,11 @@ read_process_output_error_handler (Lisp_Object error_val)
4907 return Qt; 4917 return Qt;
4908} 4918}
4909 4919
4920static void
4921read_and_dispose_of_process_output (struct Lisp_Process *p, char *chars,
4922 ssize_t nbytes,
4923 struct coding_system *coding);
4924
4910/* Read pending output from the process channel, 4925/* Read pending output from the process channel,
4911 starting with our buffered-ahead character if we have one. 4926 starting with our buffered-ahead character if we have one.
4912 Yield number of decoded characters read. 4927 Yield number of decoded characters read.
@@ -4923,9 +4938,7 @@ read_process_output (Lisp_Object proc, register int channel)
4923{ 4938{
4924 register ssize_t nbytes; 4939 register ssize_t nbytes;
4925 char *chars; 4940 char *chars;
4926 register Lisp_Object outstream;
4927 register struct Lisp_Process *p = XPROCESS (proc); 4941 register struct Lisp_Process *p = XPROCESS (proc);
4928 register ptrdiff_t opoint;
4929 struct coding_system *coding = proc_decode_coding_system[channel]; 4942 struct coding_system *coding = proc_decode_coding_system[channel];
4930 int carryover = p->decoding_carryover; 4943 int carryover = p->decoding_carryover;
4931 int readmax = 4096; 4944 int readmax = 4096;
@@ -5013,122 +5026,144 @@ read_process_output (Lisp_Object proc, register int channel)
5013 friends don't expect current-buffer to be changed from under them. */ 5026 friends don't expect current-buffer to be changed from under them. */
5014 record_unwind_current_buffer (); 5027 record_unwind_current_buffer ();
5015 5028
5016 /* Read and dispose of the process output. */ 5029 read_and_dispose_of_process_output (p, chars, nbytes, coding);
5017 outstream = p->filter; 5030
5018 if (!NILP (outstream)) 5031 /* Handling the process output should not deactivate the mark. */
5019 { 5032 Vdeactivate_mark = odeactivate;
5020 Lisp_Object text; 5033
5021 bool outer_running_asynch_code = running_asynch_code; 5034 unbind_to (count, Qnil);
5022 int waiting = waiting_for_user_input_p; 5035 return nbytes;
5036}
5037
5038static void
5039read_and_dispose_of_process_output (struct Lisp_Process *p, char *chars,
5040 ssize_t nbytes,
5041 struct coding_system *coding)
5042{
5043 Lisp_Object outstream = p->filter;
5044 Lisp_Object text;
5045 bool outer_running_asynch_code = running_asynch_code;
5046 int waiting = waiting_for_user_input_p;
5023 5047
5024 /* No need to gcpro these, because all we do with them later 5048 /* No need to gcpro these, because all we do with them later
5025 is test them for EQness, and none of them should be a string. */ 5049 is test them for EQness, and none of them should be a string. */
5026#if 0 5050#if 0
5027 Lisp_Object obuffer, okeymap; 5051 Lisp_Object obuffer, okeymap;
5028 XSETBUFFER (obuffer, current_buffer); 5052 XSETBUFFER (obuffer, current_buffer);
5029 okeymap = BVAR (current_buffer, keymap); 5053 okeymap = BVAR (current_buffer, keymap);
5030#endif 5054#endif
5031 5055
5032 /* We inhibit quit here instead of just catching it so that 5056 /* We inhibit quit here instead of just catching it so that
5033 hitting ^G when a filter happens to be running won't screw 5057 hitting ^G when a filter happens to be running won't screw
5034 it up. */ 5058 it up. */
5035 specbind (Qinhibit_quit, Qt); 5059 specbind (Qinhibit_quit, Qt);
5036 specbind (Qlast_nonmenu_event, Qt); 5060 specbind (Qlast_nonmenu_event, Qt);
5037
5038 /* In case we get recursively called,
5039 and we already saved the match data nonrecursively,
5040 save the same match data in safely recursive fashion. */
5041 if (outer_running_asynch_code)
5042 {
5043 Lisp_Object tem;
5044 /* Don't clobber the CURRENT match data, either! */
5045 tem = Fmatch_data (Qnil, Qnil, Qnil);
5046 restore_search_regs ();
5047 record_unwind_save_match_data ();
5048 Fset_match_data (tem, Qt);
5049 }
5050 5061
5051 /* For speed, if a search happens within this code, 5062 /* In case we get recursively called,
5052 save the match data in a special nonrecursive fashion. */ 5063 and we already saved the match data nonrecursively,
5053 running_asynch_code = 1; 5064 save the same match data in safely recursive fashion. */
5065 if (outer_running_asynch_code)
5066 {
5067 Lisp_Object tem;
5068 /* Don't clobber the CURRENT match data, either! */
5069 tem = Fmatch_data (Qnil, Qnil, Qnil);
5070 restore_search_regs ();
5071 record_unwind_save_match_data ();
5072 Fset_match_data (tem, Qt);
5073 }
5054 5074
5055 decode_coding_c_string (coding, (unsigned char *) chars, nbytes, Qt); 5075 /* For speed, if a search happens within this code,
5056 text = coding->dst_object; 5076 save the match data in a special nonrecursive fashion. */
5057 Vlast_coding_system_used = CODING_ID_NAME (coding->id); 5077 running_asynch_code = 1;
5058 /* A new coding system might be found. */
5059 if (!EQ (p->decode_coding_system, Vlast_coding_system_used))
5060 {
5061 pset_decode_coding_system (p, Vlast_coding_system_used);
5062 5078
5063 /* Don't call setup_coding_system for 5079 decode_coding_c_string (coding, (unsigned char *) chars, nbytes, Qt);
5064 proc_decode_coding_system[channel] here. It is done in 5080 text = coding->dst_object;
5065 detect_coding called via decode_coding above. */ 5081 Vlast_coding_system_used = CODING_ID_NAME (coding->id);
5082 /* A new coding system might be found. */
5083 if (!EQ (p->decode_coding_system, Vlast_coding_system_used))
5084 {
5085 pset_decode_coding_system (p, Vlast_coding_system_used);
5066 5086
5067 /* If a coding system for encoding is not yet decided, we set 5087 /* Don't call setup_coding_system for
5068 it as the same as coding-system for decoding. 5088 proc_decode_coding_system[channel] here. It is done in
5089 detect_coding called via decode_coding above. */
5069 5090
5070 But, before doing that we must check if 5091 /* If a coding system for encoding is not yet decided, we set
5071 proc_encode_coding_system[p->outfd] surely points to a 5092 it as the same as coding-system for decoding.
5072 valid memory because p->outfd will be changed once EOF is
5073 sent to the process. */
5074 if (NILP (p->encode_coding_system)
5075 && proc_encode_coding_system[p->outfd])
5076 {
5077 pset_encode_coding_system
5078 (p, coding_inherit_eol_type (Vlast_coding_system_used, Qnil));
5079 setup_coding_system (p->encode_coding_system,
5080 proc_encode_coding_system[p->outfd]);
5081 }
5082 }
5083 5093
5084 if (coding->carryover_bytes > 0) 5094 But, before doing that we must check if
5095 proc_encode_coding_system[p->outfd] surely points to a
5096 valid memory because p->outfd will be changed once EOF is
5097 sent to the process. */
5098 if (NILP (p->encode_coding_system)
5099 && proc_encode_coding_system[p->outfd])
5085 { 5100 {
5086 if (SCHARS (p->decoding_buf) < coding->carryover_bytes) 5101 pset_encode_coding_system
5087 pset_decoding_buf (p, make_uninit_string (coding->carryover_bytes)); 5102 (p, coding_inherit_eol_type (Vlast_coding_system_used, Qnil));
5088 memcpy (SDATA (p->decoding_buf), coding->carryover, 5103 setup_coding_system (p->encode_coding_system,
5089 coding->carryover_bytes); 5104 proc_encode_coding_system[p->outfd]);
5090 p->decoding_carryover = coding->carryover_bytes;
5091 } 5105 }
5092 if (SBYTES (text) > 0) 5106 }
5093 /* FIXME: It's wrong to wrap or not based on debug-on-error, and
5094 sometimes it's simply wrong to wrap (e.g. when called from
5095 accept-process-output). */
5096 internal_condition_case_1 (read_process_output_call,
5097 Fcons (outstream,
5098 Fcons (proc, Fcons (text, Qnil))),
5099 !NILP (Vdebug_on_error) ? Qnil : Qerror,
5100 read_process_output_error_handler);
5101
5102 /* If we saved the match data nonrecursively, restore it now. */
5103 restore_search_regs ();
5104 running_asynch_code = outer_running_asynch_code;
5105 5107
5106 /* Restore waiting_for_user_input_p as it was 5108 if (coding->carryover_bytes > 0)
5107 when we were called, in case the filter clobbered it. */ 5109 {
5108 waiting_for_user_input_p = waiting; 5110 if (SCHARS (p->decoding_buf) < coding->carryover_bytes)
5111 pset_decoding_buf (p, make_uninit_string (coding->carryover_bytes));
5112 memcpy (SDATA (p->decoding_buf), coding->carryover,
5113 coding->carryover_bytes);
5114 p->decoding_carryover = coding->carryover_bytes;
5115 }
5116 if (SBYTES (text) > 0)
5117 /* FIXME: It's wrong to wrap or not based on debug-on-error, and
5118 sometimes it's simply wrong to wrap (e.g. when called from
5119 accept-process-output). */
5120 internal_condition_case_1 (read_process_output_call,
5121 Fcons (outstream,
5122 Fcons (make_lisp_proc (p),
5123 Fcons (text, Qnil))),
5124 !NILP (Vdebug_on_error) ? Qnil : Qerror,
5125 read_process_output_error_handler);
5126
5127 /* If we saved the match data nonrecursively, restore it now. */
5128 restore_search_regs ();
5129 running_asynch_code = outer_running_asynch_code;
5130
5131 /* Restore waiting_for_user_input_p as it was
5132 when we were called, in case the filter clobbered it. */
5133 waiting_for_user_input_p = waiting;
5109 5134
5110#if 0 /* Call record_asynch_buffer_change unconditionally, 5135#if 0 /* Call record_asynch_buffer_change unconditionally,
5111 because we might have changed minor modes or other things 5136 because we might have changed minor modes or other things
5112 that affect key bindings. */ 5137 that affect key bindings. */
5113 if (! EQ (Fcurrent_buffer (), obuffer) 5138 if (! EQ (Fcurrent_buffer (), obuffer)
5114 || ! EQ (current_buffer->keymap, okeymap)) 5139 || ! EQ (current_buffer->keymap, okeymap))
5115#endif 5140#endif
5116 /* But do it only if the caller is actually going to read events. 5141 /* But do it only if the caller is actually going to read events.
5117 Otherwise there's no need to make him wake up, and it could 5142 Otherwise there's no need to make him wake up, and it could
5118 cause trouble (for example it would make sit_for return). */ 5143 cause trouble (for example it would make sit_for return). */
5119 if (waiting_for_user_input_p == -1) 5144 if (waiting_for_user_input_p == -1)
5120 record_asynch_buffer_change (); 5145 record_asynch_buffer_change ();
5121 } 5146}
5147
5148DEFUN ("internal-default-process-filter", Finternal_default_process_filter,
5149 Sinternal_default_process_filter, 2, 2, 0,
5150 doc: /* Function used as default process filter. */)
5151 (Lisp_Object proc, Lisp_Object text)
5152{
5153 struct Lisp_Process *p;
5154 ptrdiff_t opoint;
5122 5155
5123 /* If no filter, write into buffer if it isn't dead. */ 5156 CHECK_PROCESS (proc);
5124 else if (!NILP (p->buffer) && BUFFER_LIVE_P (XBUFFER (p->buffer))) 5157 p = XPROCESS (proc);
5158 CHECK_STRING (text);
5159
5160 if (!NILP (p->buffer) && BUFFER_LIVE_P (XBUFFER (p->buffer)))
5125 { 5161 {
5126 Lisp_Object old_read_only; 5162 Lisp_Object old_read_only;
5127 ptrdiff_t old_begv, old_zv; 5163 ptrdiff_t old_begv, old_zv;
5128 ptrdiff_t old_begv_byte, old_zv_byte; 5164 ptrdiff_t old_begv_byte, old_zv_byte;
5129 ptrdiff_t before, before_byte; 5165 ptrdiff_t before, before_byte;
5130 ptrdiff_t opoint_byte; 5166 ptrdiff_t opoint_byte;
5131 Lisp_Object text;
5132 struct buffer *b; 5167 struct buffer *b;
5133 5168
5134 Fset_buffer (p->buffer); 5169 Fset_buffer (p->buffer);
@@ -5161,31 +5196,6 @@ read_process_output (Lisp_Object proc, register int channel)
5161 if (! (BEGV <= PT && PT <= ZV)) 5196 if (! (BEGV <= PT && PT <= ZV))
5162 Fwiden (); 5197 Fwiden ();
5163 5198
5164 decode_coding_c_string (coding, (unsigned char *) chars, nbytes, Qt);
5165 text = coding->dst_object;
5166 Vlast_coding_system_used = CODING_ID_NAME (coding->id);
5167 /* A new coding system might be found. See the comment in the
5168 similar code in the previous `if' block. */
5169 if (!EQ (p->decode_coding_system, Vlast_coding_system_used))
5170 {
5171 pset_decode_coding_system (p, Vlast_coding_system_used);
5172 if (NILP (p->encode_coding_system)
5173 && proc_encode_coding_system[p->outfd])
5174 {
5175 pset_encode_coding_system
5176 (p, coding_inherit_eol_type (Vlast_coding_system_used, Qnil));
5177 setup_coding_system (p->encode_coding_system,
5178 proc_encode_coding_system[p->outfd]);
5179 }
5180 }
5181 if (coding->carryover_bytes > 0)
5182 {
5183 if (SCHARS (p->decoding_buf) < coding->carryover_bytes)
5184 pset_decoding_buf (p, make_uninit_string (coding->carryover_bytes));
5185 memcpy (SDATA (p->decoding_buf), coding->carryover,
5186 coding->carryover_bytes);
5187 p->decoding_carryover = coding->carryover_bytes;
5188 }
5189 /* Adjust the multibyteness of TEXT to that of the buffer. */ 5199 /* Adjust the multibyteness of TEXT to that of the buffer. */
5190 if (NILP (BVAR (current_buffer, enable_multibyte_characters)) 5200 if (NILP (BVAR (current_buffer, enable_multibyte_characters))
5191 != ! STRING_MULTIBYTE (text)) 5201 != ! STRING_MULTIBYTE (text))
@@ -5230,18 +5240,13 @@ read_process_output (Lisp_Object proc, register int channel)
5230 if (old_begv != BEGV || old_zv != ZV) 5240 if (old_begv != BEGV || old_zv != ZV)
5231 Fnarrow_to_region (make_number (old_begv), make_number (old_zv)); 5241 Fnarrow_to_region (make_number (old_begv), make_number (old_zv));
5232 5242
5233
5234 bset_read_only (current_buffer, old_read_only); 5243 bset_read_only (current_buffer, old_read_only);
5235 SET_PT_BOTH (opoint, opoint_byte); 5244 SET_PT_BOTH (opoint, opoint_byte);
5236 } 5245 }
5237 /* Handling the process output should not deactivate the mark. */ 5246 return Qnil;
5238 Vdeactivate_mark = odeactivate;
5239
5240 unbind_to (count, Qnil);
5241 return nbytes;
5242} 5247}
5243 5248
5244/* Sending data to subprocess */ 5249/* Sending data to subprocess. */
5245 5250
5246/* In send_process, when a write fails temporarily, 5251/* In send_process, when a write fails temporarily,
5247 wait_reading_process_output is called. It may execute user code, 5252 wait_reading_process_output is called. It may execute user code,
@@ -6188,13 +6193,6 @@ deliver_child_signal (int sig)
6188 6193
6189 6194
6190static Lisp_Object 6195static Lisp_Object
6191exec_sentinel_unwind (Lisp_Object data)
6192{
6193 pset_sentinel (XPROCESS (XCAR (data)), XCDR (data));
6194 return Qnil;
6195}
6196
6197static Lisp_Object
6198exec_sentinel_error_handler (Lisp_Object error_val) 6196exec_sentinel_error_handler (Lisp_Object error_val)
6199{ 6197{
6200 cmd_error_internal (error_val, "error in process sentinel: "); 6198 cmd_error_internal (error_val, "error in process sentinel: ");
@@ -6231,13 +6229,7 @@ exec_sentinel (Lisp_Object proc, Lisp_Object reason)
6231 record_unwind_current_buffer (); 6229 record_unwind_current_buffer ();
6232 6230
6233 sentinel = p->sentinel; 6231 sentinel = p->sentinel;
6234 if (NILP (sentinel))
6235 return;
6236 6232
6237 /* Zilch the sentinel while it's running, to avoid recursive invocations;
6238 assure that it gets restored no matter how the sentinel exits. */
6239 pset_sentinel (p, Qnil);
6240 record_unwind_protect (exec_sentinel_unwind, Fcons (proc, sentinel));
6241 /* Inhibit quit so that random quits don't screw up a running filter. */ 6233 /* Inhibit quit so that random quits don't screw up a running filter. */
6242 specbind (Qinhibit_quit, Qt); 6234 specbind (Qinhibit_quit, Qt);
6243 specbind (Qlast_nonmenu_event, Qt); /* Why? --Stef */ 6235 specbind (Qlast_nonmenu_event, Qt); /* Why? --Stef */
@@ -6295,7 +6287,7 @@ exec_sentinel (Lisp_Object proc, Lisp_Object reason)
6295static void 6287static void
6296status_notify (struct Lisp_Process *deleting_process) 6288status_notify (struct Lisp_Process *deleting_process)
6297{ 6289{
6298 register Lisp_Object proc, buffer; 6290 register Lisp_Object proc;
6299 Lisp_Object tail, msg; 6291 Lisp_Object tail, msg;
6300 struct gcpro gcpro1, gcpro2; 6292 struct gcpro gcpro1, gcpro2;
6301 6293
@@ -6333,8 +6325,6 @@ status_notify (struct Lisp_Process *deleting_process)
6333 && p != deleting_process 6325 && p != deleting_process
6334 && read_process_output (proc, p->infd) > 0); 6326 && read_process_output (proc, p->infd) > 0);
6335 6327
6336 buffer = p->buffer;
6337
6338 /* Get the text to use for the message. */ 6328 /* Get the text to use for the message. */
6339 if (p->raw_status_new) 6329 if (p->raw_status_new)
6340 update_status (p); 6330 update_status (p);
@@ -6355,66 +6345,83 @@ status_notify (struct Lisp_Process *deleting_process)
6355 } 6345 }
6356 6346
6357 /* The actions above may have further incremented p->tick. 6347 /* The actions above may have further incremented p->tick.
6358 So set p->update_tick again 6348 So set p->update_tick again so that an error in the sentinel will
6359 so that an error in the sentinel will not cause 6349 not cause this code to be run again. */
6360 this code to be run again. */
6361 p->update_tick = p->tick; 6350 p->update_tick = p->tick;
6362 /* Now output the message suitably. */ 6351 /* Now output the message suitably. */
6363 if (!NILP (p->sentinel)) 6352 exec_sentinel (proc, msg);
6364 exec_sentinel (proc, msg);
6365 /* Don't bother with a message in the buffer
6366 when a process becomes runnable. */
6367 else if (!EQ (symbol, Qrun) && !NILP (buffer))
6368 {
6369 Lisp_Object tem;
6370 struct buffer *old = current_buffer;
6371 ptrdiff_t opoint, opoint_byte;
6372 ptrdiff_t before, before_byte;
6373
6374 /* Avoid error if buffer is deleted
6375 (probably that's why the process is dead, too) */
6376 if (!BUFFER_LIVE_P (XBUFFER (buffer)))
6377 continue;
6378 Fset_buffer (buffer);
6379
6380 opoint = PT;
6381 opoint_byte = PT_BYTE;
6382 /* Insert new output into buffer
6383 at the current end-of-output marker,
6384 thus preserving logical ordering of input and output. */
6385 if (XMARKER (p->mark)->buffer)
6386 Fgoto_char (p->mark);
6387 else
6388 SET_PT_BOTH (ZV, ZV_BYTE);
6389
6390 before = PT;
6391 before_byte = PT_BYTE;
6392
6393 tem = BVAR (current_buffer, read_only);
6394 bset_read_only (current_buffer, Qnil);
6395 insert_string ("\nProcess ");
6396 { /* FIXME: temporary kludge */
6397 Lisp_Object tem2 = p->name; Finsert (1, &tem2); }
6398 insert_string (" ");
6399 Finsert (1, &msg);
6400 bset_read_only (current_buffer, tem);
6401 set_marker_both (p->mark, p->buffer, PT, PT_BYTE);
6402
6403 if (opoint >= before)
6404 SET_PT_BOTH (opoint + (PT - before),
6405 opoint_byte + (PT_BYTE - before_byte));
6406 else
6407 SET_PT_BOTH (opoint, opoint_byte);
6408
6409 set_buffer_internal (old);
6410 }
6411 } 6353 }
6412 } /* end for */ 6354 } /* end for */
6413 6355
6414 update_mode_lines++; /* in case buffers use %s in mode-line-format */ 6356 update_mode_lines++; /* In case buffers use %s in mode-line-format. */
6415 UNGCPRO; 6357 UNGCPRO;
6416} 6358}
6417 6359
6360DEFUN ("internal-default-process-sentinel", Finternal_default_process_sentinel,
6361 Sinternal_default_process_sentinel, 2, 2, 0,
6362 doc: /* Function used as default sentinel for processes. */)
6363 (Lisp_Object proc, Lisp_Object msg)
6364{
6365 Lisp_Object buffer, symbol;
6366 struct Lisp_Process *p;
6367 CHECK_PROCESS (proc);
6368 p = XPROCESS (proc);
6369 buffer = p->buffer;
6370 symbol = p->status;
6371 if (CONSP (symbol))
6372 symbol = XCAR (symbol);
6373
6374 if (!EQ (symbol, Qrun) && !NILP (buffer))
6375 {
6376 Lisp_Object tem;
6377 struct buffer *old = current_buffer;
6378 ptrdiff_t opoint, opoint_byte;
6379 ptrdiff_t before, before_byte;
6380
6381 /* Avoid error if buffer is deleted
6382 (probably that's why the process is dead, too). */
6383 if (!BUFFER_LIVE_P (XBUFFER (buffer)))
6384 return Qnil;
6385 Fset_buffer (buffer);
6386
6387 if (NILP (BVAR (current_buffer, enable_multibyte_characters)))
6388 msg = (code_convert_string_norecord
6389 (msg, Vlocale_coding_system, 1));
6390
6391 opoint = PT;
6392 opoint_byte = PT_BYTE;
6393 /* Insert new output into buffer
6394 at the current end-of-output marker,
6395 thus preserving logical ordering of input and output. */
6396 if (XMARKER (p->mark)->buffer)
6397 Fgoto_char (p->mark);
6398 else
6399 SET_PT_BOTH (ZV, ZV_BYTE);
6400
6401 before = PT;
6402 before_byte = PT_BYTE;
6403
6404 tem = BVAR (current_buffer, read_only);
6405 bset_read_only (current_buffer, Qnil);
6406 insert_string ("\nProcess ");
6407 { /* FIXME: temporary kludge. */
6408 Lisp_Object tem2 = p->name; Finsert (1, &tem2); }
6409 insert_string (" ");
6410 Finsert (1, &msg);
6411 bset_read_only (current_buffer, tem);
6412 set_marker_both (p->mark, p->buffer, PT, PT_BYTE);
6413
6414 if (opoint >= before)
6415 SET_PT_BOTH (opoint + (PT - before),
6416 opoint_byte + (PT_BYTE - before_byte));
6417 else
6418 SET_PT_BOTH (opoint, opoint_byte);
6419
6420 set_buffer_internal (old);
6421 }
6422 return Qnil;
6423}
6424
6418 6425
6419DEFUN ("set-process-coding-system", Fset_process_coding_system, 6426DEFUN ("set-process-coding-system", Fset_process_coding_system,
6420 Sset_process_coding_system, 1, 3, 0, 6427 Sset_process_coding_system, 1, 3, 0,
@@ -6606,13 +6613,13 @@ wait_reading_process_output (intmax_t time_limit, int nsecs, int read_kbd,
6606 if (! NILP (wait_for_cell) && ! NILP (XCAR (wait_for_cell))) 6613 if (! NILP (wait_for_cell) && ! NILP (XCAR (wait_for_cell)))
6607 break; 6614 break;
6608 6615
6609 /* Compute time from now till when time limit is up */ 6616 /* Compute time from now till when time limit is up. */
6610 /* Exit if already run out */ 6617 /* Exit if already run out. */
6611 if (nsecs < 0) 6618 if (nsecs < 0)
6612 { 6619 {
6613 /* A negative timeout means 6620 /* A negative timeout means
6614 gobble output available now 6621 gobble output available now
6615 but don't wait at all. */ 6622 but don't wait at all. */
6616 6623
6617 timeout = make_emacs_time (0, 0); 6624 timeout = make_emacs_time (0, 0);
6618 } 6625 }
@@ -6805,9 +6812,8 @@ setup_process_coding_systems (Lisp_Object process)
6805 if (!proc_decode_coding_system[inch]) 6812 if (!proc_decode_coding_system[inch])
6806 proc_decode_coding_system[inch] = xmalloc (sizeof (struct coding_system)); 6813 proc_decode_coding_system[inch] = xmalloc (sizeof (struct coding_system));
6807 coding_system = p->decode_coding_system; 6814 coding_system = p->decode_coding_system;
6808 if (! NILP (p->filter)) 6815 if (EQ (p->filter, Qinternal_default_process_filter)
6809 ; 6816 && BUFFERP (p->buffer))
6810 else if (BUFFERP (p->buffer))
6811 { 6817 {
6812 if (NILP (BVAR (XBUFFER (p->buffer), enable_multibyte_characters))) 6818 if (NILP (BVAR (XBUFFER (p->buffer), enable_multibyte_characters)))
6813 coding_system = raw_text_coding_system (coding_system); 6819 coding_system = raw_text_coding_system (coding_system);
@@ -6916,7 +6922,7 @@ kill_buffer_processes (Lisp_Object buffer)
6916 6922
6917DEFUN ("waiting-for-user-input-p", Fwaiting_for_user_input_p, 6923DEFUN ("waiting-for-user-input-p", Fwaiting_for_user_input_p,
6918 Swaiting_for_user_input_p, 0, 0, 0, 6924 Swaiting_for_user_input_p, 0, 0, 0,
6919 doc: /* Returns non-nil if Emacs is waiting for input from the user. 6925 doc: /* Return non-nil if Emacs is waiting for input from the user.
6920This is intended for use by asynchronous process output filters and sentinels. */) 6926This is intended for use by asynchronous process output filters and sentinels. */)
6921 (void) 6927 (void)
6922{ 6928{
@@ -7222,6 +7228,10 @@ syms_of_process (void)
7222 DEFSYM (Qcutime, "cutime"); 7228 DEFSYM (Qcutime, "cutime");
7223 DEFSYM (Qcstime, "cstime"); 7229 DEFSYM (Qcstime, "cstime");
7224 DEFSYM (Qctime, "ctime"); 7230 DEFSYM (Qctime, "ctime");
7231 DEFSYM (Qinternal_default_process_sentinel,
7232 "internal-default-process-sentinel");
7233 DEFSYM (Qinternal_default_process_filter,
7234 "internal-default-process-filter");
7225 DEFSYM (Qpri, "pri"); 7235 DEFSYM (Qpri, "pri");
7226 DEFSYM (Qnice, "nice"); 7236 DEFSYM (Qnice, "nice");
7227 DEFSYM (Qthcount, "thcount"); 7237 DEFSYM (Qthcount, "thcount");
@@ -7317,6 +7327,8 @@ The variable takes effect when `start-process' is called. */);
7317 defsubr (&Ssignal_process); 7327 defsubr (&Ssignal_process);
7318 defsubr (&Swaiting_for_user_input_p); 7328 defsubr (&Swaiting_for_user_input_p);
7319 defsubr (&Sprocess_type); 7329 defsubr (&Sprocess_type);
7330 defsubr (&Sinternal_default_process_sentinel);
7331 defsubr (&Sinternal_default_process_filter);
7320 defsubr (&Sset_process_coding_system); 7332 defsubr (&Sset_process_coding_system);
7321 defsubr (&Sprocess_coding_system); 7333 defsubr (&Sprocess_coding_system);
7322 defsubr (&Sset_process_filter_multibyte); 7334 defsubr (&Sset_process_filter_multibyte);
diff --git a/src/regex.c b/src/regex.c
index 83d80b5aaa9..79fb28ba12a 100644
--- a/src/regex.c
+++ b/src/regex.c
@@ -33,10 +33,9 @@
33 33
34/* Ignore some GCC warnings for now. This section should go away 34/* Ignore some GCC warnings for now. This section should go away
35 once the Emacs and Gnulib regex code is merged. */ 35 once the Emacs and Gnulib regex code is merged. */
36#if __GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 5) 36#if 4 < __GNUC__ + (5 <= __GNUC_MINOR__) || defined __clang__
37# pragma GCC diagnostic ignored "-Wstrict-overflow" 37# pragma GCC diagnostic ignored "-Wstrict-overflow"
38# ifndef emacs 38# ifndef emacs
39# pragma GCC diagnostic ignored "-Wunused-but-set-variable"
40# pragma GCC diagnostic ignored "-Wunused-function" 39# pragma GCC diagnostic ignored "-Wunused-function"
41# pragma GCC diagnostic ignored "-Wunused-macros" 40# pragma GCC diagnostic ignored "-Wunused-macros"
42# pragma GCC diagnostic ignored "-Wunused-result" 41# pragma GCC diagnostic ignored "-Wunused-result"
@@ -44,6 +43,10 @@
44# endif 43# endif
45#endif 44#endif
46 45
46#if 4 < __GNUC__ + (5 <= __GNUC_MINOR__) && ! defined __clang__
47# pragma GCC diagnostic ignored "-Wunused-but-set-variable"
48#endif
49
47#include <config.h> 50#include <config.h>
48 51
49#include <stddef.h> 52#include <stddef.h>
@@ -2622,7 +2625,7 @@ regex_compile (const re_char *pattern, size_t size, reg_syntax_t syntax, struct
2622 goto normal_char; 2625 goto normal_char;
2623 handle_plus: 2626 handle_plus:
2624 case '*': 2627 case '*':
2625 /* If there is no previous pattern... */ 2628 /* If there is no previous pattern... */
2626 if (!laststart) 2629 if (!laststart)
2627 { 2630 {
2628 if (syntax & RE_CONTEXT_INVALID_OPS) 2631 if (syntax & RE_CONTEXT_INVALID_OPS)
@@ -2730,7 +2733,7 @@ regex_compile (const re_char *pattern, size_t size, reg_syntax_t syntax, struct
2730 } 2733 }
2731 } 2734 }
2732 else /* not greedy */ 2735 else /* not greedy */
2733 { /* I wish the greedy and non-greedy cases could be merged. */ 2736 { /* I wish the greedy and non-greedy cases could be merged. */
2734 2737
2735 GET_BUFFER_SPACE (7); /* We might use less. */ 2738 GET_BUFFER_SPACE (7); /* We might use less. */
2736 if (many_times_ok) 2739 if (many_times_ok)
@@ -3034,7 +3037,7 @@ regex_compile (const re_char *pattern, size_t size, reg_syntax_t syntax, struct
3034 3037
3035 /* Allocate space for COUNT + RANGE_TABLE. Needs two 3038 /* Allocate space for COUNT + RANGE_TABLE. Needs two
3036 bytes for flags, two for COUNT, and three bytes for 3039 bytes for flags, two for COUNT, and three bytes for
3037 each character. */ 3040 each character. */
3038 GET_BUFFER_SPACE (4 + used * 3); 3041 GET_BUFFER_SPACE (4 + used * 3);
3039 3042
3040 /* Indicate the existence of range table. */ 3043 /* Indicate the existence of range table. */
@@ -3461,6 +3464,7 @@ regex_compile (const re_char *pattern, size_t size, reg_syntax_t syntax, struct
3461 /* There is no way to specify the before_dot and after_dot 3464 /* There is no way to specify the before_dot and after_dot
3462 operators. rms says this is ok. --karl */ 3465 operators. rms says this is ok. --karl */
3463 case '=': 3466 case '=':
3467 laststart = b;
3464 BUF_PUSH (at_dot); 3468 BUF_PUSH (at_dot);
3465 break; 3469 break;
3466 3470
@@ -3509,12 +3513,14 @@ regex_compile (const re_char *pattern, size_t size, reg_syntax_t syntax, struct
3509 case '<': 3513 case '<':
3510 if (syntax & RE_NO_GNU_OPS) 3514 if (syntax & RE_NO_GNU_OPS)
3511 goto normal_char; 3515 goto normal_char;
3516 laststart = b;
3512 BUF_PUSH (wordbeg); 3517 BUF_PUSH (wordbeg);
3513 break; 3518 break;
3514 3519
3515 case '>': 3520 case '>':
3516 if (syntax & RE_NO_GNU_OPS) 3521 if (syntax & RE_NO_GNU_OPS)
3517 goto normal_char; 3522 goto normal_char;
3523 laststart = b;
3518 BUF_PUSH (wordend); 3524 BUF_PUSH (wordend);
3519 break; 3525 break;
3520 3526
diff --git a/src/search.c b/src/search.c
index ea36133deb7..8b4d39c7811 100644
--- a/src/search.c
+++ b/src/search.c
@@ -328,18 +328,18 @@ looking_at_1 (Lisp_Object string, bool posix)
328 328
329 val = (i >= 0 ? Qt : Qnil); 329 val = (i >= 0 ? Qt : Qnil);
330 if (NILP (Vinhibit_changing_match_data) && i >= 0) 330 if (NILP (Vinhibit_changing_match_data) && i >= 0)
331 {
331 for (i = 0; i < search_regs.num_regs; i++) 332 for (i = 0; i < search_regs.num_regs; i++)
332 if (search_regs.start[i] >= 0) 333 if (search_regs.start[i] >= 0)
333 { 334 {
334 search_regs.start[i] 335 search_regs.start[i]
335 = BYTE_TO_CHAR (search_regs.start[i] + BEGV_BYTE); 336 = BYTE_TO_CHAR (search_regs.start[i] + BEGV_BYTE);
336 search_regs.end[i] 337 search_regs.end[i]
337 = BYTE_TO_CHAR (search_regs.end[i] + BEGV_BYTE); 338 = BYTE_TO_CHAR (search_regs.end[i] + BEGV_BYTE);
338 } 339 }
339 340 /* Set last_thing_searched only when match data is changed. */
340 /* Set last_thing_searched only when match data is changed. */
341 if (NILP (Vinhibit_changing_match_data))
342 XSETBUFFER (last_thing_searched, current_buffer); 341 XSETBUFFER (last_thing_searched, current_buffer);
342 }
343 343
344 return val; 344 return val;
345} 345}
diff --git a/src/undo.c b/src/undo.c
index 63edc8e9b8d..d8711882fbf 100644
--- a/src/undo.c
+++ b/src/undo.c
@@ -445,12 +445,6 @@ truncate_undo_list (struct buffer *b)
445 unbind_to (count, Qnil); 445 unbind_to (count, Qnil);
446} 446}
447 447
448static _Noreturn void
449user_error (const char *msg)
450{
451 xsignal1 (Quser_error, build_string (msg));
452}
453
454 448
455void 449void
456syms_of_undo (void) 450syms_of_undo (void)
diff --git a/src/unexw32.c b/src/unexw32.c
index e8b553a87d3..a01ac799592 100644
--- a/src/unexw32.c
+++ b/src/unexw32.c
@@ -159,6 +159,14 @@ open_output_file (file_data *p_file, char *filename, unsigned long size)
159 HANDLE file_mapping; 159 HANDLE file_mapping;
160 void *file_base; 160 void *file_base;
161 161
162 /* We delete any existing FILENAME because loadup.el will create a
163 hard link to it under the name emacs-XX.YY.ZZ.nn.exe. Evidently,
164 overwriting a file on Unix breaks any hard links to it, but that
165 doesn't happen on Windows. If we don't delete the file before
166 creating it, all the emacs-XX.YY.ZZ.nn.exe end up being hard
167 links to the same file, which defeats the purpose of these hard
168 links: being able to run previous builds. */
169 DeleteFile (filename);
162 file = CreateFile (filename, GENERIC_READ | GENERIC_WRITE, 0, NULL, 170 file = CreateFile (filename, GENERIC_READ | GENERIC_WRITE, 0, NULL,
163 CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, 0); 171 CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, 0);
164 if (file == INVALID_HANDLE_VALUE) 172 if (file == INVALID_HANDLE_VALUE)
diff --git a/src/w32.c b/src/w32.c
index 431826c4b82..7d63c73eb18 100644
--- a/src/w32.c
+++ b/src/w32.c
@@ -65,6 +65,7 @@ along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. */
65#undef localtime 65#undef localtime
66 66
67#include "lisp.h" 67#include "lisp.h"
68#include "epaths.h" /* for SHELL */
68 69
69#include <pwd.h> 70#include <pwd.h>
70#include <grp.h> 71#include <grp.h>
@@ -2018,7 +2019,7 @@ init_environment (char ** argv)
2018 {"PRELOAD_WINSOCK", NULL}, 2019 {"PRELOAD_WINSOCK", NULL},
2019 {"emacs_dir", "C:/emacs"}, 2020 {"emacs_dir", "C:/emacs"},
2020 {"EMACSLOADPATH", NULL}, 2021 {"EMACSLOADPATH", NULL},
2021 {"SHELL", "%emacs_dir%/bin/cmdproxy.exe"}, 2022 {"SHELL", "cmdproxy.exe"}, /* perhaps it is somewhere on PATH */
2022 {"EMACSDATA", NULL}, 2023 {"EMACSDATA", NULL},
2023 {"EMACSPATH", NULL}, 2024 {"EMACSPATH", NULL},
2024 {"INFOPATH", NULL}, 2025 {"INFOPATH", NULL},
@@ -2094,9 +2095,12 @@ init_environment (char ** argv)
2094 emacs_abort (); 2095 emacs_abort ();
2095 *p = 0; 2096 *p = 0;
2096 2097
2097 if ((p = _mbsrchr (modname, '\\')) && xstrcasecmp (p, "\\bin") == 0) 2098 if ((p = _mbsrchr (modname, '\\'))
2099 /* From bin means installed Emacs, from src means uninstalled. */
2100 && (xstrcasecmp (p, "\\bin") == 0 || xstrcasecmp (p, "\\src") == 0))
2098 { 2101 {
2099 char buf[SET_ENV_BUF_SIZE]; 2102 char buf[SET_ENV_BUF_SIZE];
2103 int within_build_tree = xstrcasecmp (p, "\\src") == 0;
2100 2104
2101 *p = 0; 2105 *p = 0;
2102 for (p = modname; *p; p = CharNext (p)) 2106 for (p = modname; *p; p = CharNext (p))
@@ -2104,6 +2108,15 @@ init_environment (char ** argv)
2104 2108
2105 _snprintf (buf, sizeof (buf)-1, "emacs_dir=%s", modname); 2109 _snprintf (buf, sizeof (buf)-1, "emacs_dir=%s", modname);
2106 _putenv (strdup (buf)); 2110 _putenv (strdup (buf));
2111 /* If we are running from the Posix-like build tree, define
2112 SHELL to point to our own cmdproxy. The loop below will
2113 then disregard PATH_EXEC and the default value. */
2114 if (within_build_tree)
2115 {
2116 _snprintf (buf, sizeof (buf) - 1,
2117 "SHELL=%s/nt/cmdproxy.exe", modname);
2118 _putenv (strdup (buf));
2119 }
2107 } 2120 }
2108 /* Handle running emacs from the build directory: src/oo-spd/i386/ */ 2121 /* Handle running emacs from the build directory: src/oo-spd/i386/ */
2109 2122
@@ -2139,16 +2152,60 @@ init_environment (char ** argv)
2139 if (!getenv (env_vars[i].name)) 2152 if (!getenv (env_vars[i].name))
2140 { 2153 {
2141 int dont_free = 0; 2154 int dont_free = 0;
2155 char bufc[SET_ENV_BUF_SIZE];
2142 2156
2143 if ((lpval = w32_get_resource (env_vars[i].name, &dwType)) == NULL 2157 if ((lpval = w32_get_resource (env_vars[i].name, &dwType)) == NULL
2144 /* Also ignore empty environment variables. */ 2158 /* Also ignore empty environment variables. */
2145 || *lpval == 0) 2159 || *lpval == 0)
2146 { 2160 {
2147 xfree (lpval); 2161 xfree (lpval);
2148 lpval = env_vars[i].def_value;
2149 dwType = REG_EXPAND_SZ;
2150 dont_free = 1; 2162 dont_free = 1;
2151 if (!strcmp (env_vars[i].name, "HOME") && !appdata) 2163 if (strcmp (env_vars[i].name, "SHELL") == 0)
2164 {
2165 /* Look for cmdproxy.exe in every directory in
2166 PATH_EXEC. FIXME: This does not find cmdproxy
2167 in nt/ when we run uninstalled. */
2168 char fname[MAX_PATH];
2169 const char *pstart = PATH_EXEC, *pend;
2170
2171 do {
2172 pend = _mbschr (pstart, ';');
2173 if (!pend)
2174 pend = pstart + strlen (pstart);
2175 /* Be defensive against series of ;;; characters. */
2176 if (pend > pstart)
2177 {
2178 strncpy (fname, pstart, pend - pstart);
2179 fname[pend - pstart] = '/';
2180 strcpy (&fname[pend - pstart + 1], "cmdproxy.exe");
2181 ExpandEnvironmentStrings ((LPSTR) fname, bufc,
2182 sizeof (bufc));
2183 if (check_existing (bufc))
2184 {
2185 lpval = bufc;
2186 dwType = REG_SZ;
2187 break;
2188 }
2189 }
2190 if (*pend)
2191 pstart = pend + 1;
2192 else
2193 pstart = pend;
2194 if (!*pstart)
2195 {
2196 /* If not found in any directory, use the
2197 default as the last resort. */
2198 lpval = env_vars[i].def_value;
2199 dwType = REG_EXPAND_SZ;
2200 }
2201 } while (*pstart);
2202 }
2203 else
2204 {
2205 lpval = env_vars[i].def_value;
2206 dwType = REG_EXPAND_SZ;
2207 }
2208 if (strcmp (env_vars[i].name, "HOME") == 0 && !appdata)
2152 Vdelayed_warnings_list 2209 Vdelayed_warnings_list
2153 = Fcons (listn (CONSTYPE_HEAP, 2, 2210 = Fcons (listn (CONSTYPE_HEAP, 2,
2154 intern ("initialization"), 2211 intern ("initialization"),
@@ -2394,8 +2451,8 @@ get_emacs_configuration_options (void)
2394#include <sys/timeb.h> 2451#include <sys/timeb.h>
2395 2452
2396/* Emulate gettimeofday (Ulrich Leodolter, 1/11/95). */ 2453/* Emulate gettimeofday (Ulrich Leodolter, 1/11/95). */
2397void 2454int
2398gettimeofday (struct timeval *tv, struct timezone *tz) 2455gettimeofday (struct timeval *restrict tv, struct timezone *restrict tz)
2399{ 2456{
2400 struct _timeb tb; 2457 struct _timeb tb;
2401 _ftime (&tb); 2458 _ftime (&tb);
@@ -2413,6 +2470,7 @@ gettimeofday (struct timeval *tv, struct timezone *tz)
2413 tz->tz_minuteswest = tb.timezone; /* minutes west of Greenwich */ 2470 tz->tz_minuteswest = tb.timezone; /* minutes west of Greenwich */
2414 tz->tz_dsttime = tb.dstflag; /* type of dst correction */ 2471 tz->tz_dsttime = tb.dstflag; /* type of dst correction */
2415 } 2472 }
2473 return 0;
2416} 2474}
2417 2475
2418/* Emulate fdutimens. */ 2476/* Emulate fdutimens. */
diff --git a/src/w32fns.c b/src/w32fns.c
index 66581341478..d7ac0dd1a6c 100644
--- a/src/w32fns.c
+++ b/src/w32fns.c
@@ -3183,8 +3183,9 @@ w32_wnd_proc (HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
3183 form.ptCurrentPos.y = w32_system_caret_y; 3183 form.ptCurrentPos.y = w32_system_caret_y;
3184 3184
3185 form.rcArea.left = WINDOW_TEXT_TO_FRAME_PIXEL_X (w, 0); 3185 form.rcArea.left = WINDOW_TEXT_TO_FRAME_PIXEL_X (w, 0);
3186 form.rcArea.top = (WINDOW_TOP_EDGE_Y (w) 3186 form.rcArea.top = WINDOW_TOP_EDGE_Y (w);
3187 + WINDOW_HEADER_LINE_HEIGHT (w)); 3187 if (BUFFERP (w->contents))
3188 form.rcArea.top += WINDOW_HEADER_LINE_HEIGHT (w);
3188 form.rcArea.right = (WINDOW_BOX_RIGHT_EDGE_X (w) 3189 form.rcArea.right = (WINDOW_BOX_RIGHT_EDGE_X (w)
3189 - WINDOW_RIGHT_MARGIN_WIDTH (w) 3190 - WINDOW_RIGHT_MARGIN_WIDTH (w)
3190 - WINDOW_RIGHT_FRINGE_WIDTH (w)); 3191 - WINDOW_RIGHT_FRINGE_WIDTH (w));
diff --git a/src/xdisp.c b/src/xdisp.c
index 0a79e6fd891..5e92f3643c0 100644
--- a/src/xdisp.c
+++ b/src/xdisp.c
@@ -881,7 +881,6 @@ static void next_overlay_string (struct it *);
881static void reseat (struct it *, struct text_pos, int); 881static void reseat (struct it *, struct text_pos, int);
882static void reseat_1 (struct it *, struct text_pos, int); 882static void reseat_1 (struct it *, struct text_pos, int);
883static void back_to_previous_visible_line_start (struct it *); 883static void back_to_previous_visible_line_start (struct it *);
884void reseat_at_previous_visible_line_start (struct it *);
885static void reseat_at_next_visible_line_start (struct it *, int); 884static void reseat_at_next_visible_line_start (struct it *, int);
886static int next_element_from_ellipsis (struct it *); 885static int next_element_from_ellipsis (struct it *);
887static int next_element_from_display_vector (struct it *); 886static int next_element_from_display_vector (struct it *);
@@ -900,7 +899,6 @@ static int get_next_display_element (struct it *);
900static enum move_it_result 899static enum move_it_result
901 move_it_in_display_line_to (struct it *, ptrdiff_t, int, 900 move_it_in_display_line_to (struct it *, ptrdiff_t, int,
902 enum move_operation_enum); 901 enum move_operation_enum);
903void move_it_vertically_backward (struct it *, int);
904static void get_visually_first_element (struct it *); 902static void get_visually_first_element (struct it *);
905static void init_to_row_start (struct it *, struct window *, 903static void init_to_row_start (struct it *, struct window *,
906 struct glyph_row *); 904 struct glyph_row *);
@@ -9537,7 +9535,15 @@ message_dolog (const char *m, ptrdiff_t nbytes, bool nlflag, bool multibyte)
9537 9535
9538 shown = buffer_window_count (current_buffer) > 0; 9536 shown = buffer_window_count (current_buffer) > 0;
9539 set_buffer_internal (oldbuf); 9537 set_buffer_internal (oldbuf);
9540 if (!shown) 9538 /* We called insert_1_both above with its 5th argument (PREPARE)
9539 zero, which prevents insert_1_both from calling
9540 prepare_to_modify_buffer, which in turns prevents us from
9541 incrementing windows_or_buffers_changed even if *Messages* is
9542 shown in some window. So we must manually incrementing
9543 windows_or_buffers_changed here to make up for that. */
9544 if (shown)
9545 windows_or_buffers_changed++;
9546 else
9541 windows_or_buffers_changed = old_windows_or_buffers_changed; 9547 windows_or_buffers_changed = old_windows_or_buffers_changed;
9542 message_log_need_newline = !nlflag; 9548 message_log_need_newline = !nlflag;
9543 Vdeactivate_mark = old_deactivate_mark; 9549 Vdeactivate_mark = old_deactivate_mark;
diff --git a/src/xfns.c b/src/xfns.c
index 6d1d68dcada..af29c5bdc3f 100644
--- a/src/xfns.c
+++ b/src/xfns.c
@@ -169,7 +169,7 @@ check_x_display_info (Lisp_Object object)
169 struct terminal *t = get_terminal (object, 1); 169 struct terminal *t = get_terminal (object, 1);
170 170
171 if (t->type != output_x_window) 171 if (t->type != output_x_window)
172 error ("Terminal %"pI"d is not an X display", XINT (object)); 172 error ("Terminal %d is not an X display", t->id);
173 173
174 dpyinfo = t->display_info.x; 174 dpyinfo = t->display_info.x;
175 } 175 }
@@ -3569,7 +3569,11 @@ DEFUN ("x-display-pixel-width", Fx_display_pixel_width, Sx_display_pixel_width,
3569 doc: /* Return the width in pixels of the X display TERMINAL. 3569 doc: /* Return the width in pixels of the X display TERMINAL.
3570The optional argument TERMINAL specifies which display to ask about. 3570The optional argument TERMINAL specifies which display to ask about.
3571TERMINAL should be a terminal object, a frame or a display name (a string). 3571TERMINAL should be a terminal object, a frame or a display name (a string).
3572If omitted or nil, that stands for the selected frame's display. */) 3572If omitted or nil, that stands for the selected frame's display.
3573
3574On \"multi-monitor\" setups this refers to the pixel width for all
3575physical monitors associated with TERMINAL. To get information for
3576each physical monitor, use `display-monitor-attributes-list'. */)
3573 (Lisp_Object terminal) 3577 (Lisp_Object terminal)
3574{ 3578{
3575 struct x_display_info *dpyinfo = check_x_display_info (terminal); 3579 struct x_display_info *dpyinfo = check_x_display_info (terminal);
@@ -3582,7 +3586,11 @@ DEFUN ("x-display-pixel-height", Fx_display_pixel_height,
3582 doc: /* Return the height in pixels of the X display TERMINAL. 3586 doc: /* Return the height in pixels of the X display TERMINAL.
3583The optional argument TERMINAL specifies which display to ask about. 3587The optional argument TERMINAL specifies which display to ask about.
3584TERMINAL should be a terminal object, a frame or a display name (a string). 3588TERMINAL should be a terminal object, a frame or a display name (a string).
3585If omitted or nil, that stands for the selected frame's display. */) 3589If omitted or nil, that stands for the selected frame's display.
3590
3591On \"multi-monitor\" setups this refers to the pixel height for all
3592physical monitors associated with TERMINAL. To get information for
3593each physical monitor, use `display-monitor-attributes-list'. */)
3586 (Lisp_Object terminal) 3594 (Lisp_Object terminal)
3587{ 3595{
3588 struct x_display_info *dpyinfo = check_x_display_info (terminal); 3596 struct x_display_info *dpyinfo = check_x_display_info (terminal);
@@ -3690,7 +3698,11 @@ DEFUN ("x-display-mm-height", Fx_display_mm_height, Sx_display_mm_height, 0, 1,
3690 doc: /* Return the height in millimeters of the X display TERMINAL. 3698 doc: /* Return the height in millimeters of the X display TERMINAL.
3691The optional argument TERMINAL specifies which display to ask about. 3699The optional argument TERMINAL specifies which display to ask about.
3692TERMINAL should be a terminal object, a frame or a display name (a string). 3700TERMINAL should be a terminal object, a frame or a display name (a string).
3693If omitted or nil, that stands for the selected frame's display. */) 3701If omitted or nil, that stands for the selected frame's display.
3702
3703On \"multi-monitor\" setups this refers to the height in millimeters for
3704all physical monitors associated with TERMINAL. To get information
3705for each physical monitor, use `display-monitor-attributes-list'. */)
3694 (Lisp_Object terminal) 3706 (Lisp_Object terminal)
3695{ 3707{
3696 struct x_display_info *dpyinfo = check_x_display_info (terminal); 3708 struct x_display_info *dpyinfo = check_x_display_info (terminal);
@@ -3702,7 +3714,11 @@ DEFUN ("x-display-mm-width", Fx_display_mm_width, Sx_display_mm_width, 0, 1, 0,
3702 doc: /* Return the width in millimeters of the X display TERMINAL. 3714 doc: /* Return the width in millimeters of the X display TERMINAL.
3703The optional argument TERMINAL specifies which display to ask about. 3715The optional argument TERMINAL specifies which display to ask about.
3704TERMINAL should be a terminal object, a frame or a display name (a string). 3716TERMINAL should be a terminal object, a frame or a display name (a string).
3705If omitted or nil, that stands for the selected frame's display. */) 3717If omitted or nil, that stands for the selected frame's display.
3718
3719On \"multi-monitor\" setups this refers to the width in millimeters for
3720all physical monitors associated with TERMINAL. To get information
3721for each physical monitor, use `display-monitor-attributes-list'. */)
3706 (Lisp_Object terminal) 3722 (Lisp_Object terminal)
3707{ 3723{
3708 struct x_display_info *dpyinfo = check_x_display_info (terminal); 3724 struct x_display_info *dpyinfo = check_x_display_info (terminal);
@@ -3804,7 +3820,7 @@ If omitted or nil, that stands for the selected frame's display. */)
3804 Return false if and only if the workarea information cannot be 3820 Return false if and only if the workarea information cannot be
3805 obtained via the _NET_WORKAREA root window property. */ 3821 obtained via the _NET_WORKAREA root window property. */
3806 3822
3807#if ! (defined USE_GTK && GTK_PREREQ (3, 4)) 3823#if ! GTK_CHECK_VERSION (3, 4, 0)
3808static bool 3824static bool
3809x_get_net_workarea (struct x_display_info *dpyinfo, XRectangle *rect) 3825x_get_net_workarea (struct x_display_info *dpyinfo, XRectangle *rect)
3810{ 3826{
@@ -4265,7 +4281,7 @@ Internal use only, use `display-monitor-attributes-list' instead. */)
4265 / x_display_pixel_height (dpyinfo)); 4281 / x_display_pixel_height (dpyinfo));
4266 gdpy = gdk_x11_lookup_xdisplay (dpyinfo->display); 4282 gdpy = gdk_x11_lookup_xdisplay (dpyinfo->display);
4267 gscreen = gdk_display_get_default_screen (gdpy); 4283 gscreen = gdk_display_get_default_screen (gdpy);
4268#if GTK_PREREQ (2, 20) 4284#if GTK_CHECK_VERSION (2, 20, 0)
4269 primary_monitor = gdk_screen_get_primary_monitor (gscreen); 4285 primary_monitor = gdk_screen_get_primary_monitor (gscreen);
4270#endif 4286#endif
4271 n_monitors = gdk_screen_get_n_monitors (gscreen); 4287 n_monitors = gdk_screen_get_n_monitors (gscreen);
@@ -4300,7 +4316,7 @@ Internal use only, use `display-monitor-attributes-list' instead. */)
4300 gdk_screen_get_monitor_geometry (gscreen, i, &rec); 4316 gdk_screen_get_monitor_geometry (gscreen, i, &rec);
4301 geometry = list4i (rec.x, rec.y, rec.width, rec.height); 4317 geometry = list4i (rec.x, rec.y, rec.width, rec.height);
4302 4318
4303#if GTK_PREREQ (2, 14) 4319#if GTK_CHECK_VERSION (2, 14, 0)
4304 width_mm = gdk_screen_get_monitor_width_mm (gscreen, i); 4320 width_mm = gdk_screen_get_monitor_width_mm (gscreen, i);
4305 height_mm = gdk_screen_get_monitor_height_mm (gscreen, i); 4321 height_mm = gdk_screen_get_monitor_height_mm (gscreen, i);
4306#endif 4322#endif
@@ -4312,7 +4328,7 @@ Internal use only, use `display-monitor-attributes-list' instead. */)
4312 list2i (width_mm, height_mm)), 4328 list2i (width_mm, height_mm)),
4313 attributes); 4329 attributes);
4314 4330
4315#if GTK_PREREQ (3, 4) 4331#if GTK_CHECK_VERSION (3, 4, 0)
4316 gdk_screen_get_monitor_workarea (gscreen, i, &rec); 4332 gdk_screen_get_monitor_workarea (gscreen, i, &rec);
4317 workarea = list4i (rec.x, rec.y, rec.width, rec.height); 4333 workarea = list4i (rec.x, rec.y, rec.width, rec.height);
4318#else 4334#else
@@ -4339,7 +4355,7 @@ Internal use only, use `display-monitor-attributes-list' instead. */)
4339 attributes = Fcons (Fcons (Qworkarea, workarea), attributes); 4355 attributes = Fcons (Fcons (Qworkarea, workarea), attributes);
4340 4356
4341 attributes = Fcons (Fcons (Qgeometry, geometry), attributes); 4357 attributes = Fcons (Fcons (Qgeometry, geometry), attributes);
4342#if GTK_PREREQ (2, 14) 4358#if GTK_CHECK_VERSION (2, 14, 0)
4343 { 4359 {
4344 char *name = gdk_screen_get_monitor_plug_name (gscreen, i); 4360 char *name = gdk_screen_get_monitor_plug_name (gscreen, i);
4345 if (name) 4361 if (name)
diff --git a/src/xterm.c b/src/xterm.c
index 55458077750..7505aa3936b 100644
--- a/src/xterm.c
+++ b/src/xterm.c
@@ -9921,7 +9921,7 @@ x_term_init (Lisp_Object display_name, char *xrm_option, char *resource_name)
9921 9921
9922 dpy = DEFAULT_GDK_DISPLAY (); 9922 dpy = DEFAULT_GDK_DISPLAY ();
9923 9923
9924#if ! GTK_PREREQ (2, 90) 9924#if ! GTK_CHECK_VERSION (2, 90, 0)
9925 /* Load our own gtkrc if it exists. */ 9925 /* Load our own gtkrc if it exists. */
9926 { 9926 {
9927 const char *file = "~/.emacs.d/gtkrc"; 9927 const char *file = "~/.emacs.d/gtkrc";
diff --git a/src/xterm.h b/src/xterm.h
index 7722372ce6b..4a5ebc66370 100644
--- a/src/xterm.h
+++ b/src/xterm.h
@@ -43,10 +43,6 @@ along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. */
43typedef Widget xt_or_gtk_widget; 43typedef Widget xt_or_gtk_widget;
44#endif 44#endif
45 45
46/* True iff GTK's version is at least MAJOR.MINOR. */
47#define GTK_PREREQ(major, minor) \
48 ((major) < GTK_MAJOR_VERSION + ((minor) <= GTK_MINOR_VERSION))
49
50#ifdef USE_GTK 46#ifdef USE_GTK
51#include <gtk/gtk.h> 47#include <gtk/gtk.h>
52#include <gdk/gdkx.h> 48#include <gdk/gdkx.h>
@@ -57,14 +53,26 @@ typedef GtkWidget *xt_or_gtk_widget;
57#undef XSync 53#undef XSync
58#define XSync(d, b) do { gdk_window_process_all_updates (); \ 54#define XSync(d, b) do { gdk_window_process_all_updates (); \
59 XSync (d, b); } while (0) 55 XSync (d, b); } while (0)
56#endif /* USE_GTK */
57
58/* True iff GTK's version is at least I.J.K. */
59#ifndef GTK_CHECK_VERSION
60# ifdef USE_GTK
61# define GTK_CHECK_VERSION(i, j, k) \
62 ((i) \
63 < GTK_MAJOR_VERSION + ((j) \
64 < GTK_MINOR_VERSION + ((k) \
65 <= GTK_MICRO_VERSION)))
66# else
67# define GTK_CHECK_VERSION(i, j, k) 0
68# endif
69#endif
60 70
61/* The GtkTooltip API came in 2.12, but gtk-enable-tooltips in 2.14. */ 71/* The GtkTooltip API came in 2.12, but gtk-enable-tooltips in 2.14. */
62#if GTK_PREREQ (2, 14) 72#if GTK_CHECK_VERSION (2, 14, 0)
63#define USE_GTK_TOOLTIP 73#define USE_GTK_TOOLTIP
64#endif 74#endif
65 75
66#endif /* USE_GTK */
67
68 76
69/* Bookkeeping to distinguish X versions. */ 77/* Bookkeeping to distinguish X versions. */
70 78