summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
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 @@
character numbers counted by detect_coding_utf_8. Fix detection
of BOM for utf-8.
+2013-05-21 Barry OReilly <gundaetiapo@gmail.com> (tiny change)
+
+ * search.c (looking_at_1): Only set last_thing_searched if the match
+ changed the match-data (bug#14281).
+
+2013-05-21 Dmitry Antipov <dmantipov@yandex.ru>
+
+ * xdisp.c (reseat_at_previous_visible_line_start):
+ Already declared in dispextern.h, so remove it here.
+ (move_it_vertically_backward): Likewise.
+
+2013-05-20 YAMAMOTO Mitsuharu <mituharu@math.s.chiba-u.ac.jp>
+
+ * xfns.c (check_x_display_info): Don't use XINT for terminal object.
+ (Fx_display_pixel_width, Fx_display_pixel_height)
+ (Fx_display_mm_width, Fx_display_mm_height):
+ Mention `display-monitor-attributes-list' in docstrings.
+
+ * nsfns.m (ns_get_screen): Remove function. All uses removed.
+ (check_ns_display_info): Sync with check_x_display_info in xfns.c.
+ (Fx_server_max_request_size, Fx_server_vendor, Fx_server_version)
+ (Fx_display_screens, Fx_display_mm_width, Fx_display_mm_height)
+ (Fx_display_backing_store, Fx_display_visual_class)
+ (Fx_display_save_under, Fx_close_connection, Fxw_display_color_p)
+ (Fx_display_grayscale_p, Fx_display_pixel_width)
+ (Fx_display_pixel_height, Fx_display_planes)
+ (Fx_display_color_cells): Sync args and docstrings with xfns.c.
+ (Fx_display_screens): Don't confuse X11 screens with NS screens.
+ (Fx_display_mm_width, Fx_display_mm_height)
+ (Fx_display_pixel_width, Fx_display_pixel_width): Return width or
+ height for all physical monitors as in X11.
+
+ * nsterm.m (x_display_pixel_width, x_display_pixel_height):
+ Return pixel width or height for all physical monitors as in X11.
+
+2013-05-18 Paul Eggert <eggert@cs.ucla.edu>
+
+ Port --enable-gcc-warnings to clang.
+ * bytecode.c (exec_byte_code):
+ * regex.c:
+ Redo diagnostic pragmas to pacify clang, too.
+ * dbusbind.c (xd_retrieve_arg): Do not use uninitialized variable.
+ * editfns.c (Fencode_time):
+ * fileio.c (file_accessible_directory_p):
+ * font.c (font_unparse_xlfd):
+ Use '&"string"[index]' instead of '"string" + (index)'.
+ * undo.c (user_error): Remove; unused.
+
+2013-05-16 Eli Zaretskii <eliz@gnu.org>
+
+ * insdel.c (insert_1_both): Document the arguments, instead of
+ referring to insert_1, which no longer exists.
+
+ * xdisp.c (message_dolog): If the *Messages* buffer is shown in
+ some window, increment windows_or_buffers_changed, so that
+ *Messages* display in that window is updated. (Bug#14408)
+
+ * w32.c: Include epaths.h.
+ (init_environment): Use cmdproxy.exe without leading directories.
+ Support emacs.exe in src; point SHELL to cmdproxy in ../nt in that
+ case.
+ (gettimeofday): Adjust signature and return value to Posix
+ expectations.
+
+ * unexw32.c (open_output_file): Delete the existing emacs.exe
+ before creating it, to break the hard link to the versioned
+ executable.
+
+ * Makefile.in (EMACS_MANIFEST, CM_OBJ, TEMACS_POST_LINK)
+ (ADDSECTION, EMACS_HEAPSIZE, MINGW_TEMACS_POST_LINK)
+ (FIRSTFILE_OBJ): New variables.
+ (W32_RES): Rename to EMACSRES. All users changed.
+ (base_obj): Use $(CM_OBJ).
+ (ALLOBJS): Use $(FIRSTFILE_OBJ).
+ (emacs$(EXEEXT)): Depend on $(ADDSECTION).
+ (temacs$(EXEEXT)): Use $(TEMACS_POST_LINK), and move
+ $(W32_RES_LINK) before $(LIBES).
+ (emacs.res): Depend on $(EMACS_MANIFEST). Put emacs.rc in nt.
+
+2013-05-15 Stefan Monnier <monnier@iro.umontreal.ca>
+
+ * makefile.w32-in (DOC): Use just "DOC".
+
+ * Makefile.in (bootstrap-clean): DOC-* doesn't exist any more.
+
+ * process.c: Export default filters and sentinels to Elisp.
+ (Qinternal_default_process_sentinel, Qinternal_default_process_filter):
+ New constants.
+ (pset_filter, pset_sentinel, make_process, Fset_process_filter)
+ (Fset_process_sentinel, Fformat_network_address):
+ Default to them instead of nil.
+ (server_accept_connection): Sentinels can't be nil any more.
+ (read_and_dispose_of_process_output): New function, extracted from
+ read_process_output.
+ (read_process_output): Use it; filters can't be nil.
+ (Finternal_default_process_filter): New function, extracted from
+ read_process_output.
+ (exec_sentinel_unwind): Remove function.
+ (exec_sentinel): Don't zilch sentinel while running.
+ (status_notify): Sentinels can't be nil.
+ (Finternal_default_process_sentinel): New function extracted from
+ status_notify.
+ (setup_process_coding_systems): Default filter is not nil any more.
+ (syms_of_process): Export new Elisp functions and initialize
+ new constants.
+ * lisp.h (make_lisp_proc): New function.
+
+2013-05-15 Stefan Monnier <monnier@iro.umontreal.ca>
+
+ * regex.c (regex_compile) [\=, \>, \<]: Don't forget to set laststart.
+
+2013-05-14 Eli Zaretskii <eliz@gnu.org>
+
+ * w32fns.c (w32_wnd_proc): Don't call WINDOW_HEADER_LINE_HEIGHT
+ unless we know that the window w is a leaf window.
+ Another attempt at solving bug#14062.
+
+2013-05-14 Jan Djärv <jan.h.d@swipnet.se>
+
+ * nsfont.m (ns_spec_to_descriptor): Retain and autorelease
+ fdesc (Bug#14375).
+
+2013-05-12 Paul Eggert <eggert@cs.ucla.edu>
+
+ * image.c (gif_load): Check that subimages fit (Bug#14345).
+
+2013-05-09 Stefan Monnier <monnier@iro.umontreal.ca>
+
+ * lread.c (skip_dyn_eof): New function.
+ (read1): Use it to skip the end of a file in response to #@00.
+
+ * doc.c (get_doc_string): Slightly relax the sanity checking.
+
+2013-05-09 Jan Djärv <jan.h.d@swipnet.se>
+
+ * nsfns.m: Include IOGraphicsLib.h if Cocoa.
+ (Qgeometry, Qworkarea, Qmm_size, Qframes, Qsource): Declare.
+ (MonitorInfo): New struct.
+ (free_monitors, ns_screen_name, ns_make_monitor_attribute_list)
+ (Fns_display_monitor_attributes_list): New functions.
+ (display-usable-bounds): Remove.
+ (syms_of_nsfns): DEFSYM Qgeometry, Qworkarea, Qmm_size, Qframes and
+ Qsource.
+
+2013-05-09 Paul Eggert <eggert@cs.ucla.edu>
+
+ * xterm.h (GTK_PREREQ): Remove, replacing with GTK_CHECK_VERSION.
+ (GTK_CHECK_VERSION): New macro, if not already defined.
+ All uses of GTK_PREREQ, GTK_MAJOR_VERSION, etc.
+ replaced by GTK_CHECK_VERSION.
+
2013-05-08 Paul Eggert <eggert@cs.ucla.edu>
* 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@
W32_LIBS=@W32_LIBS@
## emacs.res if HAVE_W32
-W32_RES=@W32_RES@
+EMACSRES = @EMACSRES@
+## emacs-*.manifest if HAVE_W32
+EMACS_MANIFEST = @EMACS_MANIFEST@
## If HAVE_W32, compiler arguments for including
## the resource file in the binary.
-## XXX -Wl,-b -Wl,pe-i386 -Wl,emacs.res
+## Cygwin: -Wl,emacs.res
+## MinGW: emacs.res
W32_RES_LINK=@W32_RES_LINK@
## Empty if !HAVE_X_WINDOWS
@@ -279,6 +282,9 @@ W32_RES_LINK=@W32_RES_LINK@
## else xfont.o
FONT_OBJ=@FONT_OBJ@
+## Empty for MinGW, cm.o for the rest.
+CM_OBJ=@CM_OBJ@
+
LIBGPM = @LIBGPM@
## -lresolv, or empty.
@@ -297,6 +303,14 @@ GETLOADAVG_LIBS = @GETLOADAVG_LIBS@
RUN_TEMACS = `/bin/pwd`/temacs
+## Invoke ../nt/addsection for MinGW, ":" elsewhere.
+TEMACS_POST_LINK = @TEMACS_POST_LINK@
+ADDSECTION = @ADDSECTION@
+EMACS_HEAPSIZE = @EMACS_HEAPSIZE@
+MINGW_TEMACS_POST_LINK = \
+ mv temacs$(EXEEXT) temacs.tmp; \
+ ../nt/addsection temacs.tmp temacs$(EXEEXT) EMHEAP $(EMACS_HEAPSIZE)
+
UNEXEC_OBJ = @UNEXEC_OBJ@
CANNOT_DUMP=@CANNOT_DUMP@
@@ -339,7 +353,7 @@ ALL_OBJC_CFLAGS=$(ALL_CFLAGS) $(GNU_OBJC_CFLAGS)
## be dumped as pure by dump-emacs.
base_obj = dispnew.o frame.o scroll.o xdisp.o menu.o $(XMENU_OBJ) window.o \
charset.o coding.o category.o ccl.o character.o chartab.o bidi.o \
- cm.o term.o terminal.o xfaces.o $(XOBJ) $(GTK_OBJ) $(DBUS_OBJ) \
+ $(CM_OBJ) term.o terminal.o xfaces.o $(XOBJ) $(GTK_OBJ) $(DBUS_OBJ) \
emacs.o keyboard.o macros.o keymap.o sysdep.o \
buffer.o filelock.o insdel.o marker.o \
minibuf.o fileio.o dired.o \
@@ -377,9 +391,9 @@ VMLIMIT_OBJ=@VMLIMIT_OBJ@
## ralloc.o if !SYSTEM_MALLOC && REL_ALLOC, else empty.
RALLOC_OBJ=@RALLOC_OBJ@
-## Empty on Cygwin, lastfile.o elsewhere.
+## Empty on Cygwin and MinGW, lastfile.o elsewhere.
PRE_ALLOC_OBJ=@PRE_ALLOC_OBJ@
-## lastfile.o on Cygwin, empty elsewhere.
+## lastfile.o on Cygwin and MinGW, empty elsewhere.
POST_ALLOC_OBJ=@POST_ALLOC_OBJ@
## 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) \
$(POST_ALLOC_OBJ) $(WIDGET_OBJ) $(LIBOBJS)
## All object files linked into temacs. $(VMLIMIT_OBJ) should be first.
-ALLOBJS = $(VMLIMIT_OBJ) $(obj) $(otherobj)
+## (On MinGW, firstfile.o should be before vm-limit.o.)
+FIRSTFILE_OBJ=@FIRSTFILE_OBJ@
+ALLOBJS = $(FIRSTFILE_OBJ) $(VMLIMIT_OBJ) $(obj) $(otherobj)
## Configure inserts the file lisp.mk at this point, defining $lisp.
@lisp_frag@
@@ -416,7 +432,8 @@ $(leimdir)/leim-list.el: bootstrap-emacs$(EXEEXT)
## Strictly speaking, emacs does not depend directly on all of $lisp,
## since not all pieces are used on all platforms. But DOC depends
## on all of $lisp, and emacs depends on DOC, so it is ok to use $lisp here.
-emacs$(EXEEXT): temacs$(EXEEXT) $(etc)/DOC $(lisp) $(leimdir)/leim-list.el
+emacs$(EXEEXT): temacs$(EXEEXT) $(ADDSECTION) \
+ $(etc)/DOC $(lisp) $(leimdir)/leim-list.el
if test "$(CANNOT_DUMP)" = "yes"; then \
rm -f emacs$(EXEEXT); \
ln temacs$(EXEEXT) emacs$(EXEEXT); \
@@ -468,10 +485,10 @@ $(lib)/libgnu.a: $(config_h)
cd $(lib) && $(MAKE) libgnu.a
temacs$(EXEEXT): stamp-oldxmenu $(ALLOBJS) \
- $(lib)/libgnu.a $(W32_RES)
+ $(lib)/libgnu.a $(EMACSRES)
$(CC) $(ALL_CFLAGS) $(TEMACS_LDFLAGS) $(LDFLAGS) \
- -o temacs $(ALLOBJS) $(lib)/libgnu.a $(LIBES) \
- $(W32_RES_LINK)
+ -o temacs $(ALLOBJS) $(lib)/libgnu.a $(W32_RES_LINK) $(LIBES)
+ $(TEMACS_POST_LINK)
test "$(CANNOT_DUMP)" = "yes" || \
test "X$(PAXCTL)" = X || $(PAXCTL) -r temacs$(EXEEXT)
@@ -514,8 +531,9 @@ doc.o: buildobj.h
emacs.res: $(ntsource)/emacs.rc \
$(ntsource)/icons/emacs.ico \
- $(ntsource)/emacs-x86.manifest
- $(WINDRES) -O COFF -o $@ $(ntsource)/emacs.rc
+ $(ntsource)/$(EMACS_MANIFEST)
+ $(WINDRES) -O COFF --include-dir=$(srcdir)/../nt \
+ -o $@ $(ntsource)/emacs.rc
ns-app: emacs$(EXEEXT)
cd ../nextstep && $(MAKE) $(MFLAGS) all
@@ -537,7 +555,7 @@ clean: mostlyclean
## It should remove all files generated during a compilation/bootstrap,
## but not things like config.status or TAGS.
bootstrap-clean: clean
- rm -f epaths.h config.h config.stamp stamp-h1 stamp-oldxmenu ../etc/DOC-*
+ rm -f epaths.h config.h config.stamp stamp-h1 stamp-oldxmenu
if test -f ./.gdbinit; then \
mv ./.gdbinit ./.gdbinit.save; \
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,
the table clearer. */
#define LABEL(OP) [OP] = &&insn_ ## OP
-#if __GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 6)
+#if 4 < __GNUC__ + (6 <= __GNUC_MINOR__)
# pragma GCC diagnostic push
# pragma GCC diagnostic ignored "-Woverride-init"
+#elif defined __clang__
+# pragma GCC diagnostic push
+# pragma GCC diagnostic ignored "-Winitializer-overrides"
#endif
/* 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,
#undef DEFINE
};
-#if __GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 6)
+#if 4 < __GNUC__ + (6 <= __GNUC_MINOR__) || defined __clang__
# pragma GCC diagnostic pop
#endif
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)
#endif
{
dbus_uint32_t val;
- unsigned int pval = val;
+ unsigned int pval;
dbus_message_iter_get_basic (iter, &val);
pval = val;
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)
}
/* Extract a doc string from a file. FILEPOS says where to get it.
- If it is an integer, use that position in the standard DOC-... file.
+ If it is an integer, use that position in the standard DOC file.
If it is (FILE . INTEGER), use FILE as the file name
and INTEGER as the position in that file.
But if INTEGER is negative, make it positive.
@@ -215,14 +215,20 @@ get_doc_string (Lisp_Object filepos, bool unibyte, bool definition)
if (CONSP (filepos))
{
int test = 1;
- if (get_doc_string_buffer[offset - test++] != ' ')
- return Qnil;
- while (get_doc_string_buffer[offset - test] >= '0'
- && get_doc_string_buffer[offset - test] <= '9')
- test++;
- if (get_doc_string_buffer[offset - test++] != '@'
- || get_doc_string_buffer[offset - test] != '#')
- return Qnil;
+ /* A dynamic docstring should be either at the very beginning of a "#@
+ comment" or right after a dynamic docstring delimiter (in case we
+ pack several such docstrings within the same comment). */
+ if (get_doc_string_buffer[offset - test] != '\037')
+ {
+ if (get_doc_string_buffer[offset - test++] != ' ')
+ return Qnil;
+ while (get_doc_string_buffer[offset - test] >= '0'
+ && get_doc_string_buffer[offset - test] <= '9')
+ test++;
+ if (get_doc_string_buffer[offset - test++] != '@'
+ || get_doc_string_buffer[offset - test] != '#')
+ return Qnil;
+ }
}
else
{
@@ -602,7 +608,7 @@ the same file name is found in the `doc-directory'. */)
while (*beg && c_isspace (*beg)) ++beg;
for (end = beg; *end && ! c_isspace (*end); ++end)
- if (*end == '/') beg = end+1; /* skip directory part */
+ if (*end == '/') beg = end + 1; /* Skip directory part. */
len = end - beg;
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) */)
EMACS_INT zone_hr = abszone / (60*60);
int zone_min = (abszone/60) % 60;
int zone_sec = abszone % 60;
- sprintf (tzbuf, tzbuf_format, "-" + (XINT (zone) < 0),
+ sprintf (tzbuf, tzbuf_format, &"-"[XINT (zone) < 0],
zone_hr, zone_min, zone_sec);
tzstring = tzbuf;
}
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)
and it's a safe optimization here. */
char *buf = SAFE_ALLOCA (len + 3);
memcpy (buf, file, len);
- strcpy (buf + len, "/." + (file[len - 1] == '/'));
+ strcpy (buf + len, &"/."[file[len - 1] == '/']);
dir = buf;
}
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)
return -1;
f[j] = p = alloca (alloc);
sprintf (p, "%s%s-*", SDATA (val),
- "*" + (SDATA (val)[SBYTES (val) - 1] == '*'));
+ &"*"[SDATA (val)[SBYTES (val) - 1] == '*']);
}
else
f[j] = SSDATA (val);
@@ -1618,7 +1618,7 @@ font_unparse_fcname (Lisp_Object font, int pixel_size, char *name, int nbytes)
}
if (point_size > 0)
{
- int len = snprintf (p, lim - p, "-%d" + (p == name), point_size);
+ int len = snprintf (p, lim - p, &"-%d"[p == name], point_size);
if (! (0 <= len && len < lim - p))
return -1;
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/>. */
#define gtk_adjustment_get_step_increment(w) ((w)->step_increment)
#define gtk_adjustment_set_step_increment(w, s) ((w)->step_increment = (s))
#endif
-#if GTK_PREREQ (2, 12)
+#if GTK_CHECK_VERSION (2, 12, 0)
#define remove_submenu(w) gtk_menu_item_set_submenu ((w), NULL)
#else
#define remove_submenu(w) gtk_menu_item_remove_submenu ((w))
#endif
-#if GTK_PREREQ (3, 2)
+#if GTK_CHECK_VERSION (3, 2, 0)
#define USE_NEW_GTK_FONT_CHOOSER 1
#else
#define USE_NEW_GTK_FONT_CHOOSER 0
@@ -202,7 +202,7 @@ xg_display_close (Display *dpy)
gdpy_def = gdpy_new;
}
-#if GTK_MAJOR_VERSION == 2 && GTK_MINOR_VERSION < 10
+#if GTK_CHECK_VERSION (2, 0, 0) && ! GTK_CHECK_VERSION (2, 10, 0)
/* GTK 2.2-2.8 has a bug that makes gdk_display_close crash (bug
http://bugzilla.gnome.org/show_bug.cgi?id=85715). This way we
can continue running, but there will be memory leaks. */
@@ -1155,7 +1155,8 @@ xg_create_frame_widgets (FRAME_PTR f)
has backported it to Gtk+ 2.0 and they add the resize grip for
Gtk+ 2.0 applications also. But it has a bug that makes Emacs loop
forever, so disable the grip. */
-#if GTK_MAJOR_VERSION < 3 && defined (HAVE_GTK_WINDOW_SET_HAS_RESIZE_GRIP)
+#if (! GTK_CHECK_VERSION (3, 0, 0) \
+ && defined HAVE_GTK_WINDOW_SET_HAS_RESIZE_GRIP)
gtk_window_set_has_resize_grip (GTK_WINDOW (wtop), FALSE);
#endif
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)
return 0;
}
+ /* Check that the selected subimages fit. It's not clear whether
+ the GIF spec requires this, but Emacs can crash if they don't fit. */
+ for (j = 0; j <= idx; ++j)
+ {
+ struct SavedImage *subimage = gif->SavedImages + j;
+ int subimg_width = subimage->ImageDesc.Width;
+ int subimg_height = subimage->ImageDesc.Height;
+ int subimg_top = subimage->ImageDesc.Top;
+ int subimg_left = subimage->ImageDesc.Left;
+ if (! (0 <= subimg_width && 0 <= subimg_height
+ && 0 <= subimg_top && subimg_top <= height - subimg_height
+ && 0 <= subimg_left && subimg_left <= width - subimg_width))
+ {
+ image_error ("Subimage does not fit in image", Qnil, Qnil);
+ fn_DGifCloseFile (gif);
+ return 0;
+ }
+ }
+
/* Create the X image and pixmap. */
if (!x_create_x_image_and_pixmap (f, width, height, 0, &ximg, &img->pixmap))
{
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,
/* Insert a sequence of NCHARS chars which occupy NBYTES bytes
- starting at STRING. INHERIT, PREPARE and BEFORE_MARKERS
- are the same as in insert_1. */
+ starting at STRING. INHERIT non-zero means inherit the text
+ properties from neighboring characters; zero means inserted text
+ will have no text properties. PREPARE non-zero means call
+ prepare_to_modify_buffer, which checks that the region is not
+ read-only, and calls before-change-function and any modification
+ properties the text may have. BEFORE_MARKERS non-zero means adjust
+ all markers that point at the insertion place to point after it. */
void
insert_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)
(eassert (KBOARD_OBJFWDP (a)), &((a)->u_kboard_objfwd))
/* Pseudovector types. */
-
+struct Lisp_Process;
+LISP_INLINE Lisp_Object make_lisp_proc (struct Lisp_Process *p)
+{ return make_lisp_ptr (p, Lisp_Vectorlike); }
#define XPROCESS(a) (eassert (PROCESSP (a)), \
(struct Lisp_Process *) XUNTAG (a, Lisp_Vectorlike))
-#define XWINDOW(a) (eassert (WINDOWP (a)), \
+#define XWINDOW(a) (eassert (WINDOWP (a)), \
(struct window *) XUNTAG (a, Lisp_Vectorlike))
#define XTERMINAL(a) (eassert (TERMINALP (a)), \
(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)
}
}
+static void
+skip_dyn_eof (Lisp_Object readcharfun)
+{
+ if (FROM_FILE_P (readcharfun))
+ {
+ block_input (); /* FIXME: Not sure if it's needed. */
+ fseek (instream, 0, SEEK_END);
+ unblock_input ();
+ }
+ else
+ while (READCHAR >= 0);
+}
+
/* Unread the character C in the way appropriate for the stream READCHARFUN.
If the stream is a user function, call it with the char as argument. */
@@ -2622,7 +2635,7 @@ read1 (Lisp_Object readcharfun, int *pch, bool first_in_list)
if (c == '@')
{
enum { extra = 100 };
- ptrdiff_t i, nskip = 0;
+ ptrdiff_t i, nskip = 0, digits = 0;
/* Read a decimal integer. */
while ((c = READCHAR) >= 0
@@ -2630,8 +2643,14 @@ read1 (Lisp_Object readcharfun, int *pch, bool first_in_list)
{
if ((STRING_BYTES_BOUND - extra) / 10 <= nskip)
string_overflow ();
+ digits++;
nskip *= 10;
nskip += c - '0';
+ if (digits == 2 && nskip == 0)
+ { /* We've just seen #@00, which means "skip to end". */
+ skip_dyn_eof (readcharfun);
+ return Qnil;
+ }
}
if (nskip > 0)
/* 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)
{
if (NILP (Vdoc_file_name))
/* We have not yet called Snarf-documentation, so assume
- this file is described in the DOC-MM.NN file
+ this file is described in the DOC file
and Snarf-documentation will fill in the right value later.
For now, replace the whole list with 0. */
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
TLASTLIB = $(BLD)/lastfile.$(A)
GNULIB = ../lib/$(BLD)/libgnu.$(A)
-DOC = $(OBJDIR)/etc/DOC-X
+DOC = $(OBJDIR)/etc/DOC
FULL_LINK_FLAGS = $(LINK_FLAGS) $(TEMACS_EXTRA_LINK)
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)
#include "fontset.h"
#include "font.h"
+#ifdef NS_IMPL_COCOA
+#include <IOKit/graphics/IOGraphicsLib.h>
+#endif
+
#if 0
int fns_trace_num = 1;
#define NSTRACE(x) fprintf (stderr, "%s:%d: [%d] " #x "\n", \
@@ -101,50 +105,53 @@ static int as_status;
static ptrdiff_t image_cache_refcount;
#endif
+static Lisp_Object Qgeometry, Qworkarea, Qmm_size, Qframes, Qsource;
+
/* ==========================================================================
Internal utility functions
========================================================================== */
-/* Let the user specify an Nextstep display with a frame.
- nil stands for the selected frame--or, if that is not an Nextstep frame,
+/* Let the user specify a Nextstep display with a Lisp object.
+ OBJECT may be nil, a frame or a terminal object.
+ nil stands for the selected frame--or, if that is not a Nextstep frame,
the first Nextstep display on the list. */
+
static struct ns_display_info *
-check_ns_display_info (Lisp_Object frame)
+check_ns_display_info (Lisp_Object object)
{
- if (NILP (frame))
+ struct ns_display_info *dpyinfo = NULL;
+
+ if (NILP (object))
{
- struct frame *f = SELECTED_FRAME ();
- if (FRAME_NS_P (f) && FRAME_LIVE_P (f) )
- return FRAME_NS_DISPLAY_INFO (f);
+ struct frame *sf = XFRAME (selected_frame);
+
+ if (FRAME_NS_P (sf) && FRAME_LIVE_P (sf))
+ dpyinfo = FRAME_NS_DISPLAY_INFO (sf);
else if (x_display_list != 0)
- return x_display_list;
+ dpyinfo = x_display_list;
else
error ("Nextstep windows are not in use or not initialized");
}
- else if (INTEGERP (frame))
+ else if (TERMINALP (object))
{
- struct terminal *t = get_terminal (frame, 1);
+ struct terminal *t = get_terminal (object, 1);
if (t->type != output_ns)
- error ("Terminal %"pI"d is not a Nextstep display", XINT (frame));
+ error ("Terminal %d is not a Nextstep display", t->id);
- return t->display_info.ns;
+ dpyinfo = t->display_info.ns;
}
- else if (STRINGP (frame))
- return ns_display_info_for_name (frame);
+ else if (STRINGP (object))
+ dpyinfo = ns_display_info_for_name (object);
else
{
- FRAME_PTR f;
-
- CHECK_LIVE_FRAME (frame);
- f = XFRAME (frame);
- if (! FRAME_NS_P (f))
- error ("non-Nextstep frame used");
- return FRAME_NS_DISPLAY_INFO (f);
+ FRAME_PTR f = decode_window_system_frame (object);
+ dpyinfo = FRAME_NS_DISPLAY_INFO (f);
}
- return NULL; /* shut compiler up */
+
+ return dpyinfo;
}
@@ -164,35 +171,6 @@ ns_get_window (Lisp_Object maybeFrame)
}
-static NSScreen *
-ns_get_screen (Lisp_Object screen)
-{
- struct frame *f;
- struct terminal *terminal;
-
- if (EQ (Qt, screen)) /* not documented */
- return [NSScreen mainScreen];
-
- terminal = get_terminal (screen, 1);
- if (terminal->type != output_ns)
- return NULL;
-
- if (NILP (screen))
- f = SELECTED_FRAME ();
- else if (FRAMEP (screen))
- f = XFRAME (screen);
- else
- {
- struct ns_display_info *dpyinfo = terminal->display_info.ns;
- f = dpyinfo->x_focus_frame
- ? dpyinfo->x_focus_frame : dpyinfo->x_highlight_frame;
- }
-
- return ((f && FRAME_NS_P (f)) ? [[FRAME_NS_VIEW (f) window] screen]
- : NULL);
-}
-
-
/* Return the X display structure for the display named NAME.
Open a new connection if necessary. */
struct ns_display_info *
@@ -1580,9 +1558,9 @@ DEFUN ("x-server-max-request-size", Fx_server_max_request_size,
Sx_server_max_request_size,
0, 1, 0,
doc: /* This function is a no-op. It is only present for completeness. */)
- (Lisp_Object display)
+ (Lisp_Object terminal)
{
- check_ns_display_info (display);
+ check_ns_display_info (terminal);
/* This function has no real equivalent under NeXTstep. Return nil to
indicate this. */
return Qnil;
@@ -1590,11 +1568,15 @@ DEFUN ("x-server-max-request-size", Fx_server_max_request_size,
DEFUN ("x-server-vendor", Fx_server_vendor, Sx_server_vendor, 0, 1, 0,
- doc: /* Return the vendor ID string of Nextstep display server DISPLAY.
-DISPLAY should be either a frame or a display name (a string).
-If omitted or nil, the selected frame's display is used. */)
- (Lisp_Object display)
+ doc: /* Return the "vendor ID" string of Nextstep display server TERMINAL.
+\(Labeling every distributor as a "vendor" embodies the false assumption
+that operating systems cannot be developed and distributed noncommercially.)
+The optional argument TERMINAL specifies which display to ask about.
+TERMINAL should be a terminal object, a frame or a display name (a string).
+If omitted or nil, that stands for the selected frame's display. */)
+ (Lisp_Object terminal)
{
+ check_ns_display_info (terminal);
#ifdef NS_IMPL_GNUSTEP
return build_string ("GNU");
#else
@@ -1604,16 +1586,17 @@ If omitted or nil, the selected frame's display is used. */)
DEFUN ("x-server-version", Fx_server_version, Sx_server_version, 0, 1, 0,
- doc: /* Return the version numbers of the server of DISPLAY.
+ doc: /* Return the version numbers of the server of display TERMINAL.
The value is a list of three integers: the major and minor
-version numbers of the X Protocol in use, and the distributor-specific
-release number. See also the function `x-server-vendor'.
+version numbers of the X Protocol in use, and the distributor-specific release
+number. See also the function `x-server-vendor'.
-The optional argument DISPLAY specifies which display to ask about.
-DISPLAY should be either a frame or a display name (a string).
+The optional argument TERMINAL specifies which display to ask about.
+TERMINAL should be a terminal object, a frame or a display name (a string).
If omitted or nil, that stands for the selected frame's display. */)
- (Lisp_Object display)
+ (Lisp_Object terminal)
{
+ check_ns_display_info (terminal);
/*NOTE: it is unclear what would best correspond with "protocol";
we return 10.3, meaning Panther, since this is roughly the
level that GNUstep's APIs correspond to.
@@ -1625,56 +1608,66 @@ If omitted or nil, that stands for the selected frame's display. */)
DEFUN ("x-display-screens", Fx_display_screens, Sx_display_screens, 0, 1, 0,
- doc: /* Return the number of screens on Nextstep display server DISPLAY.
-DISPLAY should be a frame, the display name as a string, or a terminal ID.
-If omitted or nil, the selected frame's display is used. */)
- (Lisp_Object display)
-{
- int num;
-
- check_ns_display_info (display);
- num = [[NSScreen screens] count];
+ doc: /* Return the number of screens on Nextstep display server TERMINAL.
+The optional argument TERMINAL specifies which display to ask about.
+TERMINAL should be a terminal object, a frame or a display name (a string).
+If omitted or nil, that stands for the selected frame's display.
- return (num != 0) ? make_number (num) : Qnil;
+Note: "screen" here is not in Nextstep terminology but in X11's. For
+the number of physical monitors, use `(length
+(display-monitor-attributes-list TERMINAL))' instead. */)
+ (Lisp_Object terminal)
+{
+ check_ns_display_info (terminal);
+ return make_number (1);
}
-DEFUN ("x-display-mm-height", Fx_display_mm_height, Sx_display_mm_height,
- 0, 1, 0,
- doc: /* Return the height of Nextstep display server DISPLAY, in millimeters.
-DISPLAY should be a frame, the display name as a string, or a terminal ID.
-If omitted or nil, the selected frame's display is used. */)
- (Lisp_Object display)
+DEFUN ("x-display-mm-height", Fx_display_mm_height, Sx_display_mm_height, 0, 1, 0,
+ doc: /* Return the height in millimeters of the Nextstep display TERMINAL.
+The optional argument TERMINAL specifies which display to ask about.
+TERMINAL should be a terminal object, a frame or a display name (a string).
+If omitted or nil, that stands for the selected frame's display.
+
+On \"multi-monitor\" setups this refers to the height in millimeters for
+all physical monitors associated with TERMINAL. To get information
+for each physical monitor, use `display-monitor-attributes-list'. */)
+ (Lisp_Object terminal)
{
- check_ns_display_info (display);
- return make_number ((int)
- ([ns_get_screen (display) frame].size.height/(92.0/25.4)));
+ struct ns_display_info *dpyinfo = check_ns_display_info (terminal);
+
+ return make_number (x_display_pixel_height (dpyinfo) / (92.0/25.4));
}
-DEFUN ("x-display-mm-width", Fx_display_mm_width, Sx_display_mm_width,
- 0, 1, 0,
- doc: /* Return the width of Nextstep display server DISPLAY, in millimeters.
-DISPLAY should be a frame, the display name as a string, or a terminal ID.
-If omitted or nil, the selected frame's display is used. */)
- (Lisp_Object display)
+DEFUN ("x-display-mm-width", Fx_display_mm_width, Sx_display_mm_width, 0, 1, 0,
+ doc: /* Return the width in millimeters of the Nextstep display TERMINAL.
+The optional argument TERMINAL specifies which display to ask about.
+TERMINAL should be a terminal object, a frame or a display name (a string).
+If omitted or nil, that stands for the selected frame's display.
+
+On \"multi-monitor\" setups this refers to the width in millimeters for
+all physical monitors associated with TERMINAL. To get information
+for each physical monitor, use `display-monitor-attributes-list'. */)
+ (Lisp_Object terminal)
{
- check_ns_display_info (display);
- return make_number ((int)
- ([ns_get_screen (display) frame].size.width/(92.0/25.4)));
+ struct ns_display_info *dpyinfo = check_ns_display_info (terminal);
+
+ return make_number (x_display_pixel_width (dpyinfo) / (92.0/25.4));
}
DEFUN ("x-display-backing-store", Fx_display_backing_store,
Sx_display_backing_store, 0, 1, 0,
- doc: /* Return whether the Nextstep display DISPLAY supports backing store.
+ doc: /* Return an indication of whether the Nextstep display TERMINAL does backing store.
The value may be `buffered', `retained', or `non-retained'.
-DISPLAY should be a frame, the display name as a string, or a terminal ID.
-If omitted or nil, the selected frame's display is used. */)
- (Lisp_Object display)
+The optional argument TERMINAL specifies which display to ask about.
+TERMINAL should be a terminal object, a frame or a display name (a string).
+If omitted or nil, that stands for the selected frame's display. */)
+ (Lisp_Object terminal)
{
- check_ns_display_info (display);
- switch ([ns_get_window (display) backingType])
+ check_ns_display_info (terminal);
+ switch ([ns_get_window (terminal) backingType])
{
case NSBackingStoreBuffered:
return intern ("buffered");
@@ -1691,17 +1684,19 @@ If omitted or nil, the selected frame's display is used. */)
DEFUN ("x-display-visual-class", Fx_display_visual_class,
Sx_display_visual_class, 0, 1, 0,
- doc: /* Return the visual class of the Nextstep display server DISPLAY.
+ doc: /* Return the visual class of the Nextstep display TERMINAL.
The value is one of the symbols `static-gray', `gray-scale',
`static-color', `pseudo-color', `true-color', or `direct-color'.
-DISPLAY should be a frame, the display name as a string, or a terminal ID.
-If omitted or nil, the selected frame's display is used. */)
- (Lisp_Object display)
+
+The optional argument TERMINAL specifies which display to ask about.
+TERMINAL should a terminal object, a frame or a display name (a string).
+If omitted or nil, that stands for the selected frame's display. */)
+ (Lisp_Object terminal)
{
NSWindowDepth depth;
- check_ns_display_info (display);
- depth = [ns_get_screen (display) depth];
+ check_ns_display_info (terminal);
+ depth = [[[NSScreen screens] objectAtIndex:0] depth];
if ( depth == NSBestDepth (NSCalibratedWhiteColorSpace, 2, 2, YES, NULL))
return intern ("static-gray");
@@ -1721,14 +1716,14 @@ If omitted or nil, the selected frame's display is used. */)
DEFUN ("x-display-save-under", Fx_display_save_under,
Sx_display_save_under, 0, 1, 0,
- doc: /* Return t if DISPLAY supports the save-under feature.
-The optional argument DISPLAY specifies which display to ask about.
-DISPLAY should be a frame, the display name as a string, or a terminal ID.
-If omitted or nil, the selected frame's display is used. */)
- (Lisp_Object display)
-{
- check_ns_display_info (display);
- switch ([ns_get_window (display) backingType])
+ doc: /* Return t if TERMINAL supports the save-under feature.
+The optional argument TERMINAL specifies which display to ask about.
+TERMINAL should be a terminal object, a frame or a display name (a string).
+If omitted or nil, that stands for the selected frame's display. */)
+ (Lisp_Object terminal)
+{
+ check_ns_display_info (terminal);
+ switch ([ns_get_window (terminal) backingType])
{
case NSBackingStoreBuffered:
return Qt;
@@ -1776,11 +1771,13 @@ terminate Emacs if we can't open the connection.
DEFUN ("x-close-connection", Fx_close_connection, Sx_close_connection,
1, 1, 0,
- doc: /* Close the connection to the current Nextstep display server.
-DISPLAY should be a frame, the display name as a string, or a terminal ID. */)
- (Lisp_Object display)
+ doc: /* Close the connection to TERMINAL's Nextstep display server.
+For TERMINAL, specify a terminal object, a frame or a display name (a
+string). If TERMINAL is nil, that stands for the selected frame's
+terminal. */)
+ (Lisp_Object terminal)
{
- check_ns_display_info (display);
+ check_ns_display_info (terminal);
[NSApp terminate: NSApp];
return Qnil;
}
@@ -2263,13 +2260,13 @@ DEFUN ("xw-color-values", Fxw_color_values, Sxw_color_values, 1, 2, 0,
DEFUN ("xw-display-color-p", Fxw_display_color_p, Sxw_display_color_p, 0, 1, 0,
doc: /* Internal function called by `display-color-p', which see. */)
- (Lisp_Object display)
+ (Lisp_Object terminal)
{
NSWindowDepth depth;
NSString *colorSpace;
- check_ns_display_info (display);
- depth = [ns_get_screen (display) depth];
+ check_ns_display_info (terminal);
+ depth = [[[NSScreen screens] objectAtIndex:0] depth];
colorSpace = NSColorSpaceFromDepth (depth);
return [colorSpace isEqualToString: NSDeviceWhiteColorSpace]
@@ -2278,19 +2275,19 @@ DEFUN ("xw-display-color-p", Fxw_display_color_p, Sxw_display_color_p, 0, 1, 0,
}
-DEFUN ("x-display-grayscale-p", Fx_display_grayscale_p,
- Sx_display_grayscale_p, 0, 1, 0,
+DEFUN ("x-display-grayscale-p", Fx_display_grayscale_p, Sx_display_grayscale_p,
+ 0, 1, 0,
doc: /* Return t if the Nextstep display supports shades of gray.
Note that color displays do support shades of gray.
-The optional argument DISPLAY specifies which display to ask about.
-DISPLAY should be either a frame, a display name (a string), or terminal ID.
-If omitted or nil, that stands for the selected frame's display. */)
- (Lisp_Object display)
+The optional argument TERMINAL specifies which display to ask about.
+TERMINAL should be a terminal object, a frame or a display name (a string).
+If omitted or nil, that stands for the selected frame's display. */)
+ (Lisp_Object terminal)
{
NSWindowDepth depth;
- check_ns_display_info (display);
- depth = [ns_get_screen (display) depth];
+ check_ns_display_info (terminal);
+ depth = [[[NSScreen screens] objectAtIndex:0] depth];
return NSBitsPerPixelFromDepth (depth) > 1 ? Qt : Qnil;
}
@@ -2298,84 +2295,280 @@ If omitted or nil, that stands for the selected frame's display. */)
DEFUN ("x-display-pixel-width", Fx_display_pixel_width, Sx_display_pixel_width,
0, 1, 0,
- doc: /* Return the width in pixels of the Nextstep display DISPLAY.
-The optional argument DISPLAY specifies which display to ask about.
-DISPLAY should be either a frame, a display name (a string), or terminal ID.
-If omitted or nil, that stands for the selected frame's display. */)
- (Lisp_Object display)
+ doc: /* Return the width in pixels of the Nextstep display TERMINAL.
+The optional argument TERMINAL specifies which display to ask about.
+TERMINAL should be a terminal object, a frame or a display name (a string).
+If omitted or nil, that stands for the selected frame's display.
+
+On \"multi-monitor\" setups this refers to the pixel width for all
+physical monitors associated with TERMINAL. To get information for
+each physical monitor, use `display-monitor-attributes-list'. */)
+ (Lisp_Object terminal)
{
- check_ns_display_info (display);
- return make_number ((int) [ns_get_screen (display) frame].size.width);
+ struct ns_display_info *dpyinfo = check_ns_display_info (terminal);
+
+ return make_number (x_display_pixel_width (dpyinfo));
}
DEFUN ("x-display-pixel-height", Fx_display_pixel_height,
Sx_display_pixel_height, 0, 1, 0,
- doc: /* Return the height in pixels of the Nextstep display DISPLAY.
-The optional argument DISPLAY specifies which display to ask about.
-DISPLAY should be either a frame, a display name (a string), or terminal ID.
-If omitted or nil, that stands for the selected frame's display. */)
- (Lisp_Object display)
+ doc: /* Return the height in pixels of the Nextstep display TERMINAL.
+The optional argument TERMINAL specifies which display to ask about.
+TERMINAL should be a terminal object, a frame or a display name (a string).
+If omitted or nil, that stands for the selected frame's display.
+
+On \"multi-monitor\" setups this refers to the pixel height for all
+physical monitors associated with TERMINAL. To get information for
+each physical monitor, use `display-monitor-attributes-list'. */)
+ (Lisp_Object terminal)
{
- check_ns_display_info (display);
- return make_number ((int) [ns_get_screen (display) frame].size.height);
+ struct ns_display_info *dpyinfo = check_ns_display_info (terminal);
+
+ return make_number (x_display_pixel_height (dpyinfo));
}
+struct MonitorInfo {
+ XRectangle geom, work;
+ int mm_width, mm_height;
+ char *name;
+};
-DEFUN ("display-usable-bounds", Fns_display_usable_bounds,
- Sns_display_usable_bounds, 0, 1, 0,
- doc: /* Return the bounds of the usable part of the screen.
-The return value is a list of integers (LEFT TOP WIDTH HEIGHT), which
-are the boundaries of the usable part of the screen, excluding areas
-reserved for the Mac menu, dock, and so forth.
+static void
+free_monitors (struct MonitorInfo *monitors, int n_monitors)
+{
+ int i;
+ for (i = 0; i < n_monitors; ++i)
+ xfree (monitors[i].name);
+ xfree (monitors);
+}
-The screen queried corresponds to DISPLAY, which should be either a
-frame, a display name (a string), or terminal ID. If omitted or nil,
-that stands for the selected frame's display. */)
- (Lisp_Object display)
+#ifdef NS_IMPL_COCOA
+/* Returns the name for the screen that DICT came from, or NULL.
+ Caller must free return value.
+*/
+
+char *
+ns_screen_name (CGDirectDisplayID did)
+{
+ char *name = NULL;
+ NSDictionary *info = (NSDictionary *)
+ IODisplayCreateInfoDictionary (CGDisplayIOServicePort (did),
+ kIODisplayOnlyPreferredName);
+ NSDictionary *names
+ = [info objectForKey:
+ [NSString stringWithUTF8String:kDisplayProductName]];
+
+ if ([names count] > 0) {
+ NSString *n = [names objectForKey: [[names allKeys] objectAtIndex:0]];
+ if (n != nil)
+ name = xstrdup ([n UTF8String]);
+ }
+
+ [info release];
+ return name;
+}
+#endif
+
+static Lisp_Object
+ns_make_monitor_attribute_list (struct MonitorInfo *monitors,
+ int n_monitors,
+ int primary_monitor,
+ const char *source)
+{
+ Lisp_Object monitor_frames = Fmake_vector (make_number (n_monitors), Qnil);
+ Lisp_Object frame, rest, attributes_list = Qnil;
+ Lisp_Object primary_monitor_attributes = Qnil;
+ NSArray *screens = [NSScreen screens];
+ int i;
+
+ FOR_EACH_FRAME (rest, frame)
+ {
+ struct frame *f = XFRAME (frame);
+
+ if (FRAME_NS_P (f))
+ {
+ NSView *view = FRAME_NS_VIEW (f);
+ NSScreen *screen = [[view window] screen];
+ NSUInteger k;
+
+ i = -1;
+ for (k = 0; i == -1 && k < [screens count]; ++k)
+ {
+ if ([screens objectAtIndex: k] == screen)
+ i = (int)k;
+ }
+
+ if (i > -1)
+ ASET (monitor_frames, i, Fcons (frame, AREF (monitor_frames, i)));
+ }
+ }
+
+ for (i = 0; i < n_monitors; ++i)
+ {
+ Lisp_Object geometry, workarea, attributes = Qnil;
+ struct MonitorInfo *mi = &monitors[i];
+
+ if (mi->geom.width == 0) continue;
+
+ workarea = list4i (mi->work.x, mi->work.y,
+ mi->work.width, mi->work.height);
+ geometry = list4i (mi->geom.x, mi->geom.y,
+ mi->geom.width, mi->geom.height);
+ attributes = Fcons (Fcons (Qsource,
+ make_string (source, strlen (source))),
+ attributes);
+ attributes = Fcons (Fcons (Qframes, AREF (monitor_frames, i)),
+ attributes);
+ attributes = Fcons (Fcons (Qmm_size,
+ list2i (mi->mm_width, mi->mm_height)),
+ attributes);
+ attributes = Fcons (Fcons (Qworkarea, workarea), attributes);
+ attributes = Fcons (Fcons (Qgeometry, geometry), attributes);
+ if (mi->name)
+ attributes = Fcons (Fcons (Qname, make_string (mi->name,
+ strlen (mi->name))),
+ attributes);
+
+ if (i == primary_monitor)
+ primary_monitor_attributes = attributes;
+ else
+ attributes_list = Fcons (attributes, attributes_list);
+ }
+
+ if (!NILP (primary_monitor_attributes))
+ attributes_list = Fcons (primary_monitor_attributes, attributes_list);
+ return attributes_list;
+}
+
+DEFUN ("ns-display-monitor-attributes-list",
+ Fns_display_monitor_attributes_list,
+ Sns_display_monitor_attributes_list,
+ 0, 1, 0,
+ doc: /* Return a list of physical monitor attributes on the X display TERMINAL.
+
+The optional argument TERMINAL specifies which display to ask about.
+TERMINAL should be a terminal object, a frame or a display name (a string).
+If omitted or nil, that stands for the selected frame's display.
+
+In addition to the standard attribute keys listed in
+`display-monitor-attributes-list', the following keys are contained in
+the attributes:
+
+ source -- String describing the source from which multi-monitor
+ information is obtained, \"NS\" is always the source."
+
+Internal use only, use `display-monitor-attributes-list' instead. */)
+ (Lisp_Object terminal)
{
- NSScreen *screen;
- NSRect vScreen;
+ struct terminal *term = get_terminal (terminal, 1);
+ NSArray *screens;
+ NSUInteger i, n_monitors;
+ struct MonitorInfo *monitors;
+ Lisp_Object attributes_list = Qnil;
+ CGFloat primary_display_height = 0;
+
+ if (term->type != output_ns)
+ return Qnil;
- check_ns_display_info (display);
- screen = ns_get_screen (display);
- if (!screen)
+ screens = [NSScreen screens];
+ n_monitors = [screens count];
+ if (n_monitors == 0)
return Qnil;
- vScreen = [screen visibleFrame];
+ monitors = (struct MonitorInfo *) xzalloc (n_monitors * sizeof (*monitors));
+
+ for (i = 0; i < [screens count]; ++i)
+ {
+ NSScreen *s = [screens objectAtIndex:i];
+ struct MonitorInfo *m = &monitors[i];
+ NSRect fr = [s frame];
+ NSRect vfr = [s visibleFrame];
+ NSDictionary *dict = [s deviceDescription];
+ NSValue *resval = [dict valueForKey:NSDeviceResolution];
+ short y, vy;
+
+#ifdef NS_IMPL_COCOA
+ NSNumber *nid = [dict objectForKey:@"NSScreenNumber"];
+ CGDirectDisplayID did = [nid unsignedIntValue];
+#endif
+ if (i == 0)
+ {
+ primary_display_height = fr.size.height;
+ y = (short) fr.origin.y;
+ vy = (short) vfr.origin.y;
+ }
+ else
+ {
+ // Flip y coordinate as NS has y starting from the bottom.
+ y = (short) (primary_display_height - fr.size.height - fr.origin.y);
+ vy = (short) (primary_display_height -
+ vfr.size.height - vfr.origin.y);
+ }
+
+ m->geom.x = (short) fr.origin.x;
+ m->geom.y = y;
+ m->geom.width = (unsigned short) fr.size.width;
+ m->geom.height = (unsigned short) fr.size.height;
+
+ m->work.x = (short) vfr.origin.x;
+ // y is flipped on NS, so vy - y are pixels missing at the bottom,
+ // and fr.size.height - vfr.size.height are pixels missing in total.
+ // Pixels missing at top are
+ // fr.size.height - vfr.size.height - vy + y.
+ // work.y is then pixels missing at top + y.
+ m->work.y = (short) (fr.size.height - vfr.size.height) - vy + y + y;
+ m->work.width = (unsigned short) vfr.size.width;
+ m->work.height = (unsigned short) vfr.size.height;
+
+#ifdef NS_IMPL_COCOA
+ m->name = ns_screen_name (did);
+
+ {
+ CGSize mms = CGDisplayScreenSize (did);
+ m->mm_width = (int) mms.width;
+ m->mm_height = (int) mms.height;
+ }
- /* NS coordinate system is upside-down.
- Transform to screen-specific coordinates. */
- return list4i (vScreen.origin.x,
- [screen frame].size.height
- - vScreen.size.height - vScreen.origin.y,
- vScreen.size.width, vScreen.size.height);
+#else
+ // Assume 92 dpi as x-display-mm-height/x-display-mm-width does.
+ m->mm_width = (int) (25.4 * fr.size.width / 92.0);
+ m->mm_height = (int) (25.4 * fr.size.height / 92.0);
+#endif
+ }
+
+ // Primary monitor is always first for NS.
+ attributes_list = ns_make_monitor_attribute_list (monitors, n_monitors,
+ 0, "NS");
+
+ free_monitors (monitors, n_monitors);
+ return attributes_list;
}
DEFUN ("x-display-planes", Fx_display_planes, Sx_display_planes,
0, 1, 0,
- doc: /* Return the number of bitplanes of the Nextstep display DISPLAY.
-The optional argument DISPLAY specifies which display to ask about.
-DISPLAY should be either a frame, a display name (a string), or terminal ID.
+ doc: /* Return the number of bitplanes of the Nextstep display TERMINAL.
+The optional argument TERMINAL specifies which display to ask about.
+TERMINAL should be a terminal object, a frame or a display name (a string).
If omitted or nil, that stands for the selected frame's display. */)
- (Lisp_Object display)
+ (Lisp_Object terminal)
{
- check_ns_display_info (display);
+ check_ns_display_info (terminal);
return make_number
- (NSBitsPerPixelFromDepth ([ns_get_screen (display) depth]));
+ (NSBitsPerPixelFromDepth ([[[NSScreen screens] objectAtIndex:0] depth]));
}
-DEFUN ("x-display-color-cells", Fx_display_color_cells,
- Sx_display_color_cells, 0, 1, 0,
- doc: /* Returns the number of color cells of the Nextstep display DISPLAY.
-The optional argument DISPLAY specifies which display to ask about.
-DISPLAY should be either a frame, a display name (a string), or terminal ID.
+DEFUN ("x-display-color-cells", Fx_display_color_cells, Sx_display_color_cells,
+ 0, 1, 0,
+ doc: /* Returns the number of color cells of the Nextstep display TERMINAL.
+The optional argument TERMINAL specifies which display to ask about.
+TERMINAL should be a terminal object, a frame or a display name (a string).
If omitted or nil, that stands for the selected frame's display. */)
- (Lisp_Object display)
+ (Lisp_Object terminal)
{
- struct ns_display_info *dpyinfo = check_ns_display_info (display);
+ struct ns_display_info *dpyinfo = check_ns_display_info (terminal);
/* We force 24+ bit depths to 24-bit to prevent an overflow. */
return make_number (1 << min (dpyinfo->n_planes, 24));
}
@@ -2729,6 +2922,11 @@ handlePanelKeys (NSSavePanel *panel, NSEvent *theEvent)
void
syms_of_nsfns (void)
{
+ DEFSYM (Qgeometry, "geometry");
+ DEFSYM (Qworkarea, "workarea");
+ DEFSYM (Qmm_size, "mm-size");
+ DEFSYM (Qframes, "frames");
+ DEFSYM (Qsource, "source");
Qfontsize = intern_c_string ("fontsize");
staticpro (&Qfontsize);
@@ -2774,7 +2972,7 @@ be used as the image of the icon representing the frame. */);
defsubr (&Sx_server_version);
defsubr (&Sx_display_pixel_width);
defsubr (&Sx_display_pixel_height);
- defsubr (&Sns_display_usable_bounds);
+ defsubr (&Sns_display_monitor_attributes_list);
defsubr (&Sx_display_mm_width);
defsubr (&Sx_display_mm_height);
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)
if ([tdict count] > 0)
[fdAttrs setObject: tdict forKey: NSFontTraitsAttribute];
- fdesc = [NSFontDescriptor fontDescriptorWithFontAttributes: fdAttrs];
+ fdesc = [[[NSFontDescriptor fontDescriptorWithFontAttributes: fdAttrs]
+ retain] autorelease];
+
if (family != nil)
{
- fdesc = [fdesc fontDescriptorWithFamily: family];
+ NSFontDescriptor *fdesc2 = [fdesc fontDescriptorWithFamily: family];
+ fdesc = [[fdesc2 retain] autorelease];
}
[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)
int
x_display_pixel_height (struct ns_display_info *dpyinfo)
{
- NSScreen *screen = [NSScreen mainScreen];
- return [screen frame].size.height;
+ NSArray *screens = [NSScreen screens];
+ NSEnumerator *enumerator = [screens objectEnumerator];
+ NSScreen *screen;
+ NSRect frame;
+
+ frame = NSZeroRect;
+ while ((screen = [enumerator nextObject]) != nil)
+ frame = NSUnionRect (frame, [screen frame]);
+
+ return NSHeight (frame);
}
int
x_display_pixel_width (struct ns_display_info *dpyinfo)
{
- NSScreen *screen = [NSScreen mainScreen];
- return [screen frame].size.width;
+ NSArray *screens = [NSScreen screens];
+ NSEnumerator *enumerator = [screens objectEnumerator];
+ NSScreen *screen;
+ NSRect frame;
+
+ frame = NSZeroRect;
+ while ((screen = [enumerator nextObject]) != nil)
+ frame = NSUnionRect (frame, [screen frame]);
+
+ return NSWidth (frame);
}
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;
static Lisp_Object QCserver, QCnowait, QCnoquery, QCstop;
static Lisp_Object QCsentinel, QClog, QCoptions, QCplist;
static Lisp_Object Qlast_nonmenu_event;
+static Lisp_Object Qinternal_default_process_sentinel;
+static Lisp_Object Qinternal_default_process_filter;
#define NETCONN_P(p) (EQ (XPROCESS (p)->type, Qnetwork))
#define NETCONN1_P(p) (EQ (p->type, Qnetwork))
@@ -359,7 +361,7 @@ pset_encoding_buf (struct Lisp_Process *p, Lisp_Object val)
static void
pset_filter (struct Lisp_Process *p, Lisp_Object val)
{
- p->filter = val;
+ p->filter = NILP (val) ? Qinternal_default_process_filter : val;
}
static void
pset_log (struct Lisp_Process *p, Lisp_Object val)
@@ -384,7 +386,7 @@ pset_plist (struct Lisp_Process *p, Lisp_Object val)
static void
pset_sentinel (struct Lisp_Process *p, Lisp_Object val)
{
- p->sentinel = val;
+ p->sentinel = NILP (val) ? Qinternal_default_process_sentinel : val;
}
static void
pset_status (struct Lisp_Process *p, Lisp_Object val)
@@ -700,6 +702,8 @@ make_process (Lisp_Object name)
}
name = name1;
pset_name (p, name);
+ pset_sentinel (p, Qinternal_default_process_sentinel);
+ pset_filter (p, Qinternal_default_process_filter);
XSETPROCESS (val, p);
Vprocess_alist = Fcons (Fcons (name, val), Vprocess_alist);
return val;
@@ -979,10 +983,10 @@ DEFUN ("process-mark", Fprocess_mark, Sprocess_mark,
DEFUN ("set-process-filter", Fset_process_filter, Sset_process_filter,
2, 2, 0,
- doc: /* Give PROCESS the filter function FILTER; nil means no filter.
+ doc: /* Give PROCESS the filter function FILTER; nil means default.
A value of t means stop accepting output from the process.
-When a process has a filter, its buffer is not used for output.
+When a process has a non-default filter, its buffer is not used for output.
Instead, each time it does output, the entire string of output is
passed to the filter.
@@ -1008,6 +1012,9 @@ The string argument is normally a multibyte string, except:
(debug)
(set-process-filter process ...) */
+ if (NILP (filter))
+ filter = Qinternal_default_process_filter;
+
if (p->infd >= 0)
{
if (EQ (filter, Qt) && !EQ (p->status, Qlisten))
@@ -1033,7 +1040,7 @@ The string argument is normally a multibyte string, except:
DEFUN ("process-filter", Fprocess_filter, Sprocess_filter,
1, 1, 0,
- doc: /* Returns the filter function of PROCESS; nil if none.
+ doc: /* Return the filter function of PROCESS.
See `set-process-filter' for more info on filter functions. */)
(register Lisp_Object process)
{
@@ -1043,7 +1050,7 @@ See `set-process-filter' for more info on filter functions. */)
DEFUN ("set-process-sentinel", Fset_process_sentinel, Sset_process_sentinel,
2, 2, 0,
- doc: /* Give PROCESS the sentinel SENTINEL; nil for none.
+ doc: /* Give PROCESS the sentinel SENTINEL; nil for default.
The sentinel is called as a function when the process changes state.
It gets two arguments: the process, and a string describing the change. */)
(register Lisp_Object process, Lisp_Object sentinel)
@@ -1053,6 +1060,9 @@ It gets two arguments: the process, and a string describing the change. */)
CHECK_PROCESS (process);
p = XPROCESS (process);
+ if (NILP (sentinel))
+ sentinel = Qinternal_default_process_sentinel;
+
pset_sentinel (p, sentinel);
if (NETCONN1_P (p) || SERIALCONN1_P (p))
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. */)
DEFUN ("process-sentinel", Fprocess_sentinel, Sprocess_sentinel,
1, 1, 0,
- doc: /* Return the sentinel of PROCESS; nil if none.
+ doc: /* Return the sentinel of PROCESS.
See `set-process-sentinel' for more info on sentinels. */)
(register Lisp_Object process)
{
@@ -1378,8 +1388,8 @@ usage: (start-process NAME BUFFER PROGRAM &rest PROGRAM-ARGS) */)
pset_plist (XPROCESS (proc), Qnil);
pset_type (XPROCESS (proc), Qreal);
pset_buffer (XPROCESS (proc), buffer);
- pset_sentinel (XPROCESS (proc), Qnil);
- pset_filter (XPROCESS (proc), Qnil);
+ pset_sentinel (XPROCESS (proc), Qinternal_default_process_sentinel);
+ pset_filter (XPROCESS (proc), Qinternal_default_process_filter);
pset_command (XPROCESS (proc), Flist (nargs - 2, args + 2));
#ifdef HAVE_GNUTLS
@@ -4039,7 +4049,8 @@ server_accept_connection (Lisp_Object server, int channel)
process name of the server process concatenated with the caller
identification. */
- if (!NILP (ps->filter) && !EQ (ps->filter, Qt))
+ if (!(EQ (ps->filter, Qinternal_default_process_filter)
+ || EQ (ps->filter, Qt)))
buffer = Qnil;
else
{
@@ -4108,7 +4119,7 @@ server_accept_connection (Lisp_Object server, int channel)
/* Setup coding system for new process based on server process.
This seems to be the proper thing to do, as the coding system
of the new process should reflect the settings at the time the
- server socket was opened; not the current settings. */
+ server socket was opened; not the current settings. */
pset_decode_coding_system (p, ps->decode_coding_system);
pset_encode_coding_system (p, ps->encode_coding_system);
@@ -4127,11 +4138,10 @@ server_accept_connection (Lisp_Object server, int channel)
(STRINGP (host) ? host : build_string ("-")),
build_string ("\n")));
- if (!NILP (p->sentinel))
- exec_sentinel (proc,
- concat3 (build_string ("open from "),
- (STRINGP (host) ? host : build_string ("-")),
- build_string ("\n")));
+ exec_sentinel (proc,
+ concat3 (build_string ("open from "),
+ (STRINGP (host) ? host : build_string ("-")),
+ build_string ("\n")));
}
/* 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,
if (! NILP (wait_for_cell) && ! NILP (XCAR (wait_for_cell)))
break;
- /* Compute time from now till when time limit is up */
- /* Exit if already run out */
+ /* Compute time from now till when time limit is up. */
+ /* Exit if already run out. */
if (nsecs < 0)
{
/* A negative timeout means
@@ -4871,8 +4881,8 @@ wait_reading_process_output (intmax_t time_limit, int nsecs, int read_kbd,
}
}
#endif /* NON_BLOCKING_CONNECT */
- } /* end for each file descriptor */
- } /* end while exit conditions not met */
+ } /* End for each file descriptor. */
+ } /* End while exit conditions not met. */
unbind_to (count, Qnil);
@@ -4907,6 +4917,11 @@ read_process_output_error_handler (Lisp_Object error_val)
return Qt;
}
+static void
+read_and_dispose_of_process_output (struct Lisp_Process *p, char *chars,
+ ssize_t nbytes,
+ struct coding_system *coding);
+
/* Read pending output from the process channel,
starting with our buffered-ahead character if we have one.
Yield number of decoded characters read.
@@ -4923,9 +4938,7 @@ read_process_output (Lisp_Object proc, register int channel)
{
register ssize_t nbytes;
char *chars;
- register Lisp_Object outstream;
register struct Lisp_Process *p = XPROCESS (proc);
- register ptrdiff_t opoint;
struct coding_system *coding = proc_decode_coding_system[channel];
int carryover = p->decoding_carryover;
int readmax = 4096;
@@ -5013,122 +5026,144 @@ read_process_output (Lisp_Object proc, register int channel)
friends don't expect current-buffer to be changed from under them. */
record_unwind_current_buffer ();
- /* Read and dispose of the process output. */
- outstream = p->filter;
- if (!NILP (outstream))
- {
- Lisp_Object text;
- bool outer_running_asynch_code = running_asynch_code;
- int waiting = waiting_for_user_input_p;
+ read_and_dispose_of_process_output (p, chars, nbytes, coding);
+
+ /* Handling the process output should not deactivate the mark. */
+ Vdeactivate_mark = odeactivate;
+
+ unbind_to (count, Qnil);
+ return nbytes;
+}
+
+static void
+read_and_dispose_of_process_output (struct Lisp_Process *p, char *chars,
+ ssize_t nbytes,
+ struct coding_system *coding)
+{
+ Lisp_Object outstream = p->filter;
+ Lisp_Object text;
+ bool outer_running_asynch_code = running_asynch_code;
+ int waiting = waiting_for_user_input_p;
- /* No need to gcpro these, because all we do with them later
- is test them for EQness, and none of them should be a string. */
+ /* No need to gcpro these, because all we do with them later
+ is test them for EQness, and none of them should be a string. */
#if 0
- Lisp_Object obuffer, okeymap;
- XSETBUFFER (obuffer, current_buffer);
- okeymap = BVAR (current_buffer, keymap);
+ Lisp_Object obuffer, okeymap;
+ XSETBUFFER (obuffer, current_buffer);
+ okeymap = BVAR (current_buffer, keymap);
#endif
- /* We inhibit quit here instead of just catching it so that
- hitting ^G when a filter happens to be running won't screw
- it up. */
- specbind (Qinhibit_quit, Qt);
- specbind (Qlast_nonmenu_event, Qt);
-
- /* In case we get recursively called,
- and we already saved the match data nonrecursively,
- save the same match data in safely recursive fashion. */
- if (outer_running_asynch_code)
- {
- Lisp_Object tem;
- /* Don't clobber the CURRENT match data, either! */
- tem = Fmatch_data (Qnil, Qnil, Qnil);
- restore_search_regs ();
- record_unwind_save_match_data ();
- Fset_match_data (tem, Qt);
- }
+ /* We inhibit quit here instead of just catching it so that
+ hitting ^G when a filter happens to be running won't screw
+ it up. */
+ specbind (Qinhibit_quit, Qt);
+ specbind (Qlast_nonmenu_event, Qt);
- /* For speed, if a search happens within this code,
- save the match data in a special nonrecursive fashion. */
- running_asynch_code = 1;
+ /* In case we get recursively called,
+ and we already saved the match data nonrecursively,
+ save the same match data in safely recursive fashion. */
+ if (outer_running_asynch_code)
+ {
+ Lisp_Object tem;
+ /* Don't clobber the CURRENT match data, either! */
+ tem = Fmatch_data (Qnil, Qnil, Qnil);
+ restore_search_regs ();
+ record_unwind_save_match_data ();
+ Fset_match_data (tem, Qt);
+ }
- decode_coding_c_string (coding, (unsigned char *) chars, nbytes, Qt);
- text = coding->dst_object;
- Vlast_coding_system_used = CODING_ID_NAME (coding->id);
- /* A new coding system might be found. */
- if (!EQ (p->decode_coding_system, Vlast_coding_system_used))
- {
- pset_decode_coding_system (p, Vlast_coding_system_used);
+ /* For speed, if a search happens within this code,
+ save the match data in a special nonrecursive fashion. */
+ running_asynch_code = 1;
- /* Don't call setup_coding_system for
- proc_decode_coding_system[channel] here. It is done in
- detect_coding called via decode_coding above. */
+ decode_coding_c_string (coding, (unsigned char *) chars, nbytes, Qt);
+ text = coding->dst_object;
+ Vlast_coding_system_used = CODING_ID_NAME (coding->id);
+ /* A new coding system might be found. */
+ if (!EQ (p->decode_coding_system, Vlast_coding_system_used))
+ {
+ pset_decode_coding_system (p, Vlast_coding_system_used);
- /* If a coding system for encoding is not yet decided, we set
- it as the same as coding-system for decoding.
+ /* Don't call setup_coding_system for
+ proc_decode_coding_system[channel] here. It is done in
+ detect_coding called via decode_coding above. */
- But, before doing that we must check if
- proc_encode_coding_system[p->outfd] surely points to a
- valid memory because p->outfd will be changed once EOF is
- sent to the process. */
- if (NILP (p->encode_coding_system)
- && proc_encode_coding_system[p->outfd])
- {
- pset_encode_coding_system
- (p, coding_inherit_eol_type (Vlast_coding_system_used, Qnil));
- setup_coding_system (p->encode_coding_system,
- proc_encode_coding_system[p->outfd]);
- }
- }
+ /* If a coding system for encoding is not yet decided, we set
+ it as the same as coding-system for decoding.
- if (coding->carryover_bytes > 0)
+ But, before doing that we must check if
+ proc_encode_coding_system[p->outfd] surely points to a
+ valid memory because p->outfd will be changed once EOF is
+ sent to the process. */
+ if (NILP (p->encode_coding_system)
+ && proc_encode_coding_system[p->outfd])
{
- if (SCHARS (p->decoding_buf) < coding->carryover_bytes)
- pset_decoding_buf (p, make_uninit_string (coding->carryover_bytes));
- memcpy (SDATA (p->decoding_buf), coding->carryover,
- coding->carryover_bytes);
- p->decoding_carryover = coding->carryover_bytes;
+ pset_encode_coding_system
+ (p, coding_inherit_eol_type (Vlast_coding_system_used, Qnil));
+ setup_coding_system (p->encode_coding_system,
+ proc_encode_coding_system[p->outfd]);
}
- if (SBYTES (text) > 0)
- /* FIXME: It's wrong to wrap or not based on debug-on-error, and
- sometimes it's simply wrong to wrap (e.g. when called from
- accept-process-output). */
- internal_condition_case_1 (read_process_output_call,
- Fcons (outstream,
- Fcons (proc, Fcons (text, Qnil))),
- !NILP (Vdebug_on_error) ? Qnil : Qerror,
- read_process_output_error_handler);
-
- /* If we saved the match data nonrecursively, restore it now. */
- restore_search_regs ();
- running_asynch_code = outer_running_asynch_code;
+ }
- /* Restore waiting_for_user_input_p as it was
- when we were called, in case the filter clobbered it. */
- waiting_for_user_input_p = waiting;
+ if (coding->carryover_bytes > 0)
+ {
+ if (SCHARS (p->decoding_buf) < coding->carryover_bytes)
+ pset_decoding_buf (p, make_uninit_string (coding->carryover_bytes));
+ memcpy (SDATA (p->decoding_buf), coding->carryover,
+ coding->carryover_bytes);
+ p->decoding_carryover = coding->carryover_bytes;
+ }
+ if (SBYTES (text) > 0)
+ /* FIXME: It's wrong to wrap or not based on debug-on-error, and
+ sometimes it's simply wrong to wrap (e.g. when called from
+ accept-process-output). */
+ internal_condition_case_1 (read_process_output_call,
+ Fcons (outstream,
+ Fcons (make_lisp_proc (p),
+ Fcons (text, Qnil))),
+ !NILP (Vdebug_on_error) ? Qnil : Qerror,
+ read_process_output_error_handler);
+
+ /* If we saved the match data nonrecursively, restore it now. */
+ restore_search_regs ();
+ running_asynch_code = outer_running_asynch_code;
+
+ /* Restore waiting_for_user_input_p as it was
+ when we were called, in case the filter clobbered it. */
+ waiting_for_user_input_p = waiting;
#if 0 /* Call record_asynch_buffer_change unconditionally,
because we might have changed minor modes or other things
that affect key bindings. */
- if (! EQ (Fcurrent_buffer (), obuffer)
- || ! EQ (current_buffer->keymap, okeymap))
-#endif
- /* But do it only if the caller is actually going to read events.
- Otherwise there's no need to make him wake up, and it could
- cause trouble (for example it would make sit_for return). */
- if (waiting_for_user_input_p == -1)
- record_asynch_buffer_change ();
- }
+ if (! EQ (Fcurrent_buffer (), obuffer)
+ || ! EQ (current_buffer->keymap, okeymap))
+#endif
+ /* But do it only if the caller is actually going to read events.
+ Otherwise there's no need to make him wake up, and it could
+ cause trouble (for example it would make sit_for return). */
+ if (waiting_for_user_input_p == -1)
+ record_asynch_buffer_change ();
+}
+
+DEFUN ("internal-default-process-filter", Finternal_default_process_filter,
+ Sinternal_default_process_filter, 2, 2, 0,
+ doc: /* Function used as default process filter. */)
+ (Lisp_Object proc, Lisp_Object text)
+{
+ struct Lisp_Process *p;
+ ptrdiff_t opoint;
- /* If no filter, write into buffer if it isn't dead. */
- else if (!NILP (p->buffer) && BUFFER_LIVE_P (XBUFFER (p->buffer)))
+ CHECK_PROCESS (proc);
+ p = XPROCESS (proc);
+ CHECK_STRING (text);
+
+ if (!NILP (p->buffer) && BUFFER_LIVE_P (XBUFFER (p->buffer)))
{
Lisp_Object old_read_only;
ptrdiff_t old_begv, old_zv;
ptrdiff_t old_begv_byte, old_zv_byte;
ptrdiff_t before, before_byte;
ptrdiff_t opoint_byte;
- Lisp_Object text;
struct buffer *b;
Fset_buffer (p->buffer);
@@ -5161,31 +5196,6 @@ read_process_output (Lisp_Object proc, register int channel)
if (! (BEGV <= PT && PT <= ZV))
Fwiden ();
- decode_coding_c_string (coding, (unsigned char *) chars, nbytes, Qt);
- text = coding->dst_object;
- Vlast_coding_system_used = CODING_ID_NAME (coding->id);
- /* A new coding system might be found. See the comment in the
- similar code in the previous `if' block. */
- if (!EQ (p->decode_coding_system, Vlast_coding_system_used))
- {
- pset_decode_coding_system (p, Vlast_coding_system_used);
- if (NILP (p->encode_coding_system)
- && proc_encode_coding_system[p->outfd])
- {
- pset_encode_coding_system
- (p, coding_inherit_eol_type (Vlast_coding_system_used, Qnil));
- setup_coding_system (p->encode_coding_system,
- proc_encode_coding_system[p->outfd]);
- }
- }
- if (coding->carryover_bytes > 0)
- {
- if (SCHARS (p->decoding_buf) < coding->carryover_bytes)
- pset_decoding_buf (p, make_uninit_string (coding->carryover_bytes));
- memcpy (SDATA (p->decoding_buf), coding->carryover,
- coding->carryover_bytes);
- p->decoding_carryover = coding->carryover_bytes;
- }
/* Adjust the multibyteness of TEXT to that of the buffer. */
if (NILP (BVAR (current_buffer, enable_multibyte_characters))
!= ! STRING_MULTIBYTE (text))
@@ -5230,18 +5240,13 @@ read_process_output (Lisp_Object proc, register int channel)
if (old_begv != BEGV || old_zv != ZV)
Fnarrow_to_region (make_number (old_begv), make_number (old_zv));
-
bset_read_only (current_buffer, old_read_only);
SET_PT_BOTH (opoint, opoint_byte);
}
- /* Handling the process output should not deactivate the mark. */
- Vdeactivate_mark = odeactivate;
-
- unbind_to (count, Qnil);
- return nbytes;
+ return Qnil;
}
-/* Sending data to subprocess */
+/* Sending data to subprocess. */
/* In send_process, when a write fails temporarily,
wait_reading_process_output is called. It may execute user code,
@@ -6188,13 +6193,6 @@ deliver_child_signal (int sig)
static Lisp_Object
-exec_sentinel_unwind (Lisp_Object data)
-{
- pset_sentinel (XPROCESS (XCAR (data)), XCDR (data));
- return Qnil;
-}
-
-static Lisp_Object
exec_sentinel_error_handler (Lisp_Object error_val)
{
cmd_error_internal (error_val, "error in process sentinel: ");
@@ -6231,13 +6229,7 @@ exec_sentinel (Lisp_Object proc, Lisp_Object reason)
record_unwind_current_buffer ();
sentinel = p->sentinel;
- if (NILP (sentinel))
- return;
- /* Zilch the sentinel while it's running, to avoid recursive invocations;
- assure that it gets restored no matter how the sentinel exits. */
- pset_sentinel (p, Qnil);
- record_unwind_protect (exec_sentinel_unwind, Fcons (proc, sentinel));
/* Inhibit quit so that random quits don't screw up a running filter. */
specbind (Qinhibit_quit, Qt);
specbind (Qlast_nonmenu_event, Qt); /* Why? --Stef */
@@ -6295,7 +6287,7 @@ exec_sentinel (Lisp_Object proc, Lisp_Object reason)
static void
status_notify (struct Lisp_Process *deleting_process)
{
- register Lisp_Object proc, buffer;
+ register Lisp_Object proc;
Lisp_Object tail, msg;
struct gcpro gcpro1, gcpro2;
@@ -6333,8 +6325,6 @@ status_notify (struct Lisp_Process *deleting_process)
&& p != deleting_process
&& read_process_output (proc, p->infd) > 0);
- buffer = p->buffer;
-
/* Get the text to use for the message. */
if (p->raw_status_new)
update_status (p);
@@ -6355,66 +6345,83 @@ status_notify (struct Lisp_Process *deleting_process)
}
/* The actions above may have further incremented p->tick.
- So set p->update_tick again
- so that an error in the sentinel will not cause
- this code to be run again. */
+ So set p->update_tick again so that an error in the sentinel will
+ not cause this code to be run again. */
p->update_tick = p->tick;
/* Now output the message suitably. */
- if (!NILP (p->sentinel))
- exec_sentinel (proc, msg);
- /* Don't bother with a message in the buffer
- when a process becomes runnable. */
- else if (!EQ (symbol, Qrun) && !NILP (buffer))
- {
- Lisp_Object tem;
- struct buffer *old = current_buffer;
- ptrdiff_t opoint, opoint_byte;
- ptrdiff_t before, before_byte;
-
- /* Avoid error if buffer is deleted
- (probably that's why the process is dead, too) */
- if (!BUFFER_LIVE_P (XBUFFER (buffer)))
- continue;
- Fset_buffer (buffer);
-
- opoint = PT;
- opoint_byte = PT_BYTE;
- /* Insert new output into buffer
- at the current end-of-output marker,
- thus preserving logical ordering of input and output. */
- if (XMARKER (p->mark)->buffer)
- Fgoto_char (p->mark);
- else
- SET_PT_BOTH (ZV, ZV_BYTE);
-
- before = PT;
- before_byte = PT_BYTE;
-
- tem = BVAR (current_buffer, read_only);
- bset_read_only (current_buffer, Qnil);
- insert_string ("\nProcess ");
- { /* FIXME: temporary kludge */
- Lisp_Object tem2 = p->name; Finsert (1, &tem2); }
- insert_string (" ");
- Finsert (1, &msg);
- bset_read_only (current_buffer, tem);
- set_marker_both (p->mark, p->buffer, PT, PT_BYTE);
-
- if (opoint >= before)
- SET_PT_BOTH (opoint + (PT - before),
- opoint_byte + (PT_BYTE - before_byte));
- else
- SET_PT_BOTH (opoint, opoint_byte);
-
- set_buffer_internal (old);
- }
+ exec_sentinel (proc, msg);
}
} /* end for */
- update_mode_lines++; /* in case buffers use %s in mode-line-format */
+ update_mode_lines++; /* In case buffers use %s in mode-line-format. */
UNGCPRO;
}
+DEFUN ("internal-default-process-sentinel", Finternal_default_process_sentinel,
+ Sinternal_default_process_sentinel, 2, 2, 0,
+ doc: /* Function used as default sentinel for processes. */)
+ (Lisp_Object proc, Lisp_Object msg)
+{
+ Lisp_Object buffer, symbol;
+ struct Lisp_Process *p;
+ CHECK_PROCESS (proc);
+ p = XPROCESS (proc);
+ buffer = p->buffer;
+ symbol = p->status;
+ if (CONSP (symbol))
+ symbol = XCAR (symbol);
+
+ if (!EQ (symbol, Qrun) && !NILP (buffer))
+ {
+ Lisp_Object tem;
+ struct buffer *old = current_buffer;
+ ptrdiff_t opoint, opoint_byte;
+ ptrdiff_t before, before_byte;
+
+ /* Avoid error if buffer is deleted
+ (probably that's why the process is dead, too). */
+ if (!BUFFER_LIVE_P (XBUFFER (buffer)))
+ return Qnil;
+ Fset_buffer (buffer);
+
+ if (NILP (BVAR (current_buffer, enable_multibyte_characters)))
+ msg = (code_convert_string_norecord
+ (msg, Vlocale_coding_system, 1));
+
+ opoint = PT;
+ opoint_byte = PT_BYTE;
+ /* Insert new output into buffer
+ at the current end-of-output marker,
+ thus preserving logical ordering of input and output. */
+ if (XMARKER (p->mark)->buffer)
+ Fgoto_char (p->mark);
+ else
+ SET_PT_BOTH (ZV, ZV_BYTE);
+
+ before = PT;
+ before_byte = PT_BYTE;
+
+ tem = BVAR (current_buffer, read_only);
+ bset_read_only (current_buffer, Qnil);
+ insert_string ("\nProcess ");
+ { /* FIXME: temporary kludge. */
+ Lisp_Object tem2 = p->name; Finsert (1, &tem2); }
+ insert_string (" ");
+ Finsert (1, &msg);
+ bset_read_only (current_buffer, tem);
+ set_marker_both (p->mark, p->buffer, PT, PT_BYTE);
+
+ if (opoint >= before)
+ SET_PT_BOTH (opoint + (PT - before),
+ opoint_byte + (PT_BYTE - before_byte));
+ else
+ SET_PT_BOTH (opoint, opoint_byte);
+
+ set_buffer_internal (old);
+ }
+ return Qnil;
+}
+
DEFUN ("set-process-coding-system", Fset_process_coding_system,
Sset_process_coding_system, 1, 3, 0,
@@ -6606,13 +6613,13 @@ wait_reading_process_output (intmax_t time_limit, int nsecs, int read_kbd,
if (! NILP (wait_for_cell) && ! NILP (XCAR (wait_for_cell)))
break;
- /* Compute time from now till when time limit is up */
- /* Exit if already run out */
+ /* Compute time from now till when time limit is up. */
+ /* Exit if already run out. */
if (nsecs < 0)
{
/* A negative timeout means
gobble output available now
- but don't wait at all. */
+ but don't wait at all. */
timeout = make_emacs_time (0, 0);
}
@@ -6805,9 +6812,8 @@ setup_process_coding_systems (Lisp_Object process)
if (!proc_decode_coding_system[inch])
proc_decode_coding_system[inch] = xmalloc (sizeof (struct coding_system));
coding_system = p->decode_coding_system;
- if (! NILP (p->filter))
- ;
- else if (BUFFERP (p->buffer))
+ if (EQ (p->filter, Qinternal_default_process_filter)
+ && BUFFERP (p->buffer))
{
if (NILP (BVAR (XBUFFER (p->buffer), enable_multibyte_characters)))
coding_system = raw_text_coding_system (coding_system);
@@ -6916,7 +6922,7 @@ kill_buffer_processes (Lisp_Object buffer)
DEFUN ("waiting-for-user-input-p", Fwaiting_for_user_input_p,
Swaiting_for_user_input_p, 0, 0, 0,
- doc: /* Returns non-nil if Emacs is waiting for input from the user.
+ doc: /* Return non-nil if Emacs is waiting for input from the user.
This is intended for use by asynchronous process output filters and sentinels. */)
(void)
{
@@ -7222,6 +7228,10 @@ syms_of_process (void)
DEFSYM (Qcutime, "cutime");
DEFSYM (Qcstime, "cstime");
DEFSYM (Qctime, "ctime");
+ DEFSYM (Qinternal_default_process_sentinel,
+ "internal-default-process-sentinel");
+ DEFSYM (Qinternal_default_process_filter,
+ "internal-default-process-filter");
DEFSYM (Qpri, "pri");
DEFSYM (Qnice, "nice");
DEFSYM (Qthcount, "thcount");
@@ -7317,6 +7327,8 @@ The variable takes effect when `start-process' is called. */);
defsubr (&Ssignal_process);
defsubr (&Swaiting_for_user_input_p);
defsubr (&Sprocess_type);
+ defsubr (&Sinternal_default_process_sentinel);
+ defsubr (&Sinternal_default_process_filter);
defsubr (&Sset_process_coding_system);
defsubr (&Sprocess_coding_system);
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 @@
/* Ignore some GCC warnings for now. This section should go away
once the Emacs and Gnulib regex code is merged. */
-#if __GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 5)
+#if 4 < __GNUC__ + (5 <= __GNUC_MINOR__) || defined __clang__
# pragma GCC diagnostic ignored "-Wstrict-overflow"
# ifndef emacs
-# pragma GCC diagnostic ignored "-Wunused-but-set-variable"
# pragma GCC diagnostic ignored "-Wunused-function"
# pragma GCC diagnostic ignored "-Wunused-macros"
# pragma GCC diagnostic ignored "-Wunused-result"
@@ -44,6 +43,10 @@
# endif
#endif
+#if 4 < __GNUC__ + (5 <= __GNUC_MINOR__) && ! defined __clang__
+# pragma GCC diagnostic ignored "-Wunused-but-set-variable"
+#endif
+
#include <config.h>
#include <stddef.h>
@@ -2622,7 +2625,7 @@ regex_compile (const re_char *pattern, size_t size, reg_syntax_t syntax, struct
goto normal_char;
handle_plus:
case '*':
- /* If there is no previous pattern... */
+ /* If there is no previous pattern... */
if (!laststart)
{
if (syntax & RE_CONTEXT_INVALID_OPS)
@@ -2730,7 +2733,7 @@ regex_compile (const re_char *pattern, size_t size, reg_syntax_t syntax, struct
}
}
else /* not greedy */
- { /* I wish the greedy and non-greedy cases could be merged. */
+ { /* I wish the greedy and non-greedy cases could be merged. */
GET_BUFFER_SPACE (7); /* We might use less. */
if (many_times_ok)
@@ -3034,7 +3037,7 @@ regex_compile (const re_char *pattern, size_t size, reg_syntax_t syntax, struct
/* Allocate space for COUNT + RANGE_TABLE. Needs two
bytes for flags, two for COUNT, and three bytes for
- each character. */
+ each character. */
GET_BUFFER_SPACE (4 + used * 3);
/* Indicate the existence of range table. */
@@ -3461,6 +3464,7 @@ regex_compile (const re_char *pattern, size_t size, reg_syntax_t syntax, struct
/* There is no way to specify the before_dot and after_dot
operators. rms says this is ok. --karl */
case '=':
+ laststart = b;
BUF_PUSH (at_dot);
break;
@@ -3509,12 +3513,14 @@ regex_compile (const re_char *pattern, size_t size, reg_syntax_t syntax, struct
case '<':
if (syntax & RE_NO_GNU_OPS)
goto normal_char;
+ laststart = b;
BUF_PUSH (wordbeg);
break;
case '>':
if (syntax & RE_NO_GNU_OPS)
goto normal_char;
+ laststart = b;
BUF_PUSH (wordend);
break;
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)
val = (i >= 0 ? Qt : Qnil);
if (NILP (Vinhibit_changing_match_data) && i >= 0)
+ {
for (i = 0; i < search_regs.num_regs; i++)
if (search_regs.start[i] >= 0)
{
search_regs.start[i]
= BYTE_TO_CHAR (search_regs.start[i] + BEGV_BYTE);
- search_regs.end[i]
- = BYTE_TO_CHAR (search_regs.end[i] + BEGV_BYTE);
- }
-
- /* Set last_thing_searched only when match data is changed. */
- if (NILP (Vinhibit_changing_match_data))
+ search_regs.end[i]
+ = BYTE_TO_CHAR (search_regs.end[i] + BEGV_BYTE);
+ }
+ /* Set last_thing_searched only when match data is changed. */
XSETBUFFER (last_thing_searched, current_buffer);
+ }
return val;
}
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)
unbind_to (count, Qnil);
}
-static _Noreturn void
-user_error (const char *msg)
-{
- xsignal1 (Quser_error, build_string (msg));
-}
-
void
syms_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)
HANDLE file_mapping;
void *file_base;
+ /* We delete any existing FILENAME because loadup.el will create a
+ hard link to it under the name emacs-XX.YY.ZZ.nn.exe. Evidently,
+ overwriting a file on Unix breaks any hard links to it, but that
+ doesn't happen on Windows. If we don't delete the file before
+ creating it, all the emacs-XX.YY.ZZ.nn.exe end up being hard
+ links to the same file, which defeats the purpose of these hard
+ links: being able to run previous builds. */
+ DeleteFile (filename);
file = CreateFile (filename, GENERIC_READ | GENERIC_WRITE, 0, NULL,
CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, 0);
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/>. */
#undef localtime
#include "lisp.h"
+#include "epaths.h" /* for SHELL */
#include <pwd.h>
#include <grp.h>
@@ -2018,7 +2019,7 @@ init_environment (char ** argv)
{"PRELOAD_WINSOCK", NULL},
{"emacs_dir", "C:/emacs"},
{"EMACSLOADPATH", NULL},
- {"SHELL", "%emacs_dir%/bin/cmdproxy.exe"},
+ {"SHELL", "cmdproxy.exe"}, /* perhaps it is somewhere on PATH */
{"EMACSDATA", NULL},
{"EMACSPATH", NULL},
{"INFOPATH", NULL},
@@ -2094,9 +2095,12 @@ init_environment (char ** argv)
emacs_abort ();
*p = 0;
- if ((p = _mbsrchr (modname, '\\')) && xstrcasecmp (p, "\\bin") == 0)
+ if ((p = _mbsrchr (modname, '\\'))
+ /* From bin means installed Emacs, from src means uninstalled. */
+ && (xstrcasecmp (p, "\\bin") == 0 || xstrcasecmp (p, "\\src") == 0))
{
char buf[SET_ENV_BUF_SIZE];
+ int within_build_tree = xstrcasecmp (p, "\\src") == 0;
*p = 0;
for (p = modname; *p; p = CharNext (p))
@@ -2104,6 +2108,15 @@ init_environment (char ** argv)
_snprintf (buf, sizeof (buf)-1, "emacs_dir=%s", modname);
_putenv (strdup (buf));
+ /* If we are running from the Posix-like build tree, define
+ SHELL to point to our own cmdproxy. The loop below will
+ then disregard PATH_EXEC and the default value. */
+ if (within_build_tree)
+ {
+ _snprintf (buf, sizeof (buf) - 1,
+ "SHELL=%s/nt/cmdproxy.exe", modname);
+ _putenv (strdup (buf));
+ }
}
/* Handle running emacs from the build directory: src/oo-spd/i386/ */
@@ -2139,16 +2152,60 @@ init_environment (char ** argv)
if (!getenv (env_vars[i].name))
{
int dont_free = 0;
+ char bufc[SET_ENV_BUF_SIZE];
if ((lpval = w32_get_resource (env_vars[i].name, &dwType)) == NULL
/* Also ignore empty environment variables. */
|| *lpval == 0)
{
xfree (lpval);
- lpval = env_vars[i].def_value;
- dwType = REG_EXPAND_SZ;
dont_free = 1;
- if (!strcmp (env_vars[i].name, "HOME") && !appdata)
+ if (strcmp (env_vars[i].name, "SHELL") == 0)
+ {
+ /* Look for cmdproxy.exe in every directory in
+ PATH_EXEC. FIXME: This does not find cmdproxy
+ in nt/ when we run uninstalled. */
+ char fname[MAX_PATH];
+ const char *pstart = PATH_EXEC, *pend;
+
+ do {
+ pend = _mbschr (pstart, ';');
+ if (!pend)
+ pend = pstart + strlen (pstart);
+ /* Be defensive against series of ;;; characters. */
+ if (pend > pstart)
+ {
+ strncpy (fname, pstart, pend - pstart);
+ fname[pend - pstart] = '/';
+ strcpy (&fname[pend - pstart + 1], "cmdproxy.exe");
+ ExpandEnvironmentStrings ((LPSTR) fname, bufc,
+ sizeof (bufc));
+ if (check_existing (bufc))
+ {
+ lpval = bufc;
+ dwType = REG_SZ;
+ break;
+ }
+ }
+ if (*pend)
+ pstart = pend + 1;
+ else
+ pstart = pend;
+ if (!*pstart)
+ {
+ /* If not found in any directory, use the
+ default as the last resort. */
+ lpval = env_vars[i].def_value;
+ dwType = REG_EXPAND_SZ;
+ }
+ } while (*pstart);
+ }
+ else
+ {
+ lpval = env_vars[i].def_value;
+ dwType = REG_EXPAND_SZ;
+ }
+ if (strcmp (env_vars[i].name, "HOME") == 0 && !appdata)
Vdelayed_warnings_list
= Fcons (listn (CONSTYPE_HEAP, 2,
intern ("initialization"),
@@ -2394,8 +2451,8 @@ get_emacs_configuration_options (void)
#include <sys/timeb.h>
/* Emulate gettimeofday (Ulrich Leodolter, 1/11/95). */
-void
-gettimeofday (struct timeval *tv, struct timezone *tz)
+int
+gettimeofday (struct timeval *restrict tv, struct timezone *restrict tz)
{
struct _timeb tb;
_ftime (&tb);
@@ -2413,6 +2470,7 @@ gettimeofday (struct timeval *tv, struct timezone *tz)
tz->tz_minuteswest = tb.timezone; /* minutes west of Greenwich */
tz->tz_dsttime = tb.dstflag; /* type of dst correction */
}
+ return 0;
}
/* 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)
form.ptCurrentPos.y = w32_system_caret_y;
form.rcArea.left = WINDOW_TEXT_TO_FRAME_PIXEL_X (w, 0);
- form.rcArea.top = (WINDOW_TOP_EDGE_Y (w)
- + WINDOW_HEADER_LINE_HEIGHT (w));
+ form.rcArea.top = WINDOW_TOP_EDGE_Y (w);
+ if (BUFFERP (w->contents))
+ form.rcArea.top += WINDOW_HEADER_LINE_HEIGHT (w);
form.rcArea.right = (WINDOW_BOX_RIGHT_EDGE_X (w)
- WINDOW_RIGHT_MARGIN_WIDTH (w)
- 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 *);
static void reseat (struct it *, struct text_pos, int);
static void reseat_1 (struct it *, struct text_pos, int);
static void back_to_previous_visible_line_start (struct it *);
-void reseat_at_previous_visible_line_start (struct it *);
static void reseat_at_next_visible_line_start (struct it *, int);
static int next_element_from_ellipsis (struct it *);
static int next_element_from_display_vector (struct it *);
@@ -900,7 +899,6 @@ static int get_next_display_element (struct it *);
static enum move_it_result
move_it_in_display_line_to (struct it *, ptrdiff_t, int,
enum move_operation_enum);
-void move_it_vertically_backward (struct it *, int);
static void get_visually_first_element (struct it *);
static void init_to_row_start (struct it *, struct window *,
struct glyph_row *);
@@ -9537,7 +9535,15 @@ message_dolog (const char *m, ptrdiff_t nbytes, bool nlflag, bool multibyte)
shown = buffer_window_count (current_buffer) > 0;
set_buffer_internal (oldbuf);
- if (!shown)
+ /* We called insert_1_both above with its 5th argument (PREPARE)
+ zero, which prevents insert_1_both from calling
+ prepare_to_modify_buffer, which in turns prevents us from
+ incrementing windows_or_buffers_changed even if *Messages* is
+ shown in some window. So we must manually incrementing
+ windows_or_buffers_changed here to make up for that. */
+ if (shown)
+ windows_or_buffers_changed++;
+ else
windows_or_buffers_changed = old_windows_or_buffers_changed;
message_log_need_newline = !nlflag;
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)
struct terminal *t = get_terminal (object, 1);
if (t->type != output_x_window)
- error ("Terminal %"pI"d is not an X display", XINT (object));
+ error ("Terminal %d is not an X display", t->id);
dpyinfo = t->display_info.x;
}
@@ -3569,7 +3569,11 @@ DEFUN ("x-display-pixel-width", Fx_display_pixel_width, Sx_display_pixel_width,
doc: /* Return the width in pixels of the X display TERMINAL.
The optional argument TERMINAL specifies which display to ask about.
TERMINAL should be a terminal object, a frame or a display name (a string).
-If omitted or nil, that stands for the selected frame's display. */)
+If omitted or nil, that stands for the selected frame's display.
+
+On \"multi-monitor\" setups this refers to the pixel width for all
+physical monitors associated with TERMINAL. To get information for
+each physical monitor, use `display-monitor-attributes-list'. */)
(Lisp_Object terminal)
{
struct x_display_info *dpyinfo = check_x_display_info (terminal);
@@ -3582,7 +3586,11 @@ DEFUN ("x-display-pixel-height", Fx_display_pixel_height,
doc: /* Return the height in pixels of the X display TERMINAL.
The optional argument TERMINAL specifies which display to ask about.
TERMINAL should be a terminal object, a frame or a display name (a string).
-If omitted or nil, that stands for the selected frame's display. */)
+If omitted or nil, that stands for the selected frame's display.
+
+On \"multi-monitor\" setups this refers to the pixel height for all
+physical monitors associated with TERMINAL. To get information for
+each physical monitor, use `display-monitor-attributes-list'. */)
(Lisp_Object terminal)
{
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,
doc: /* Return the height in millimeters of the X display TERMINAL.
The optional argument TERMINAL specifies which display to ask about.
TERMINAL should be a terminal object, a frame or a display name (a string).
-If omitted or nil, that stands for the selected frame's display. */)
+If omitted or nil, that stands for the selected frame's display.
+
+On \"multi-monitor\" setups this refers to the height in millimeters for
+all physical monitors associated with TERMINAL. To get information
+for each physical monitor, use `display-monitor-attributes-list'. */)
(Lisp_Object terminal)
{
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,
doc: /* Return the width in millimeters of the X display TERMINAL.
The optional argument TERMINAL specifies which display to ask about.
TERMINAL should be a terminal object, a frame or a display name (a string).
-If omitted or nil, that stands for the selected frame's display. */)
+If omitted or nil, that stands for the selected frame's display.
+
+On \"multi-monitor\" setups this refers to the width in millimeters for
+all physical monitors associated with TERMINAL. To get information
+for each physical monitor, use `display-monitor-attributes-list'. */)
(Lisp_Object terminal)
{
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. */)
Return false if and only if the workarea information cannot be
obtained via the _NET_WORKAREA root window property. */
-#if ! (defined USE_GTK && GTK_PREREQ (3, 4))
+#if ! GTK_CHECK_VERSION (3, 4, 0)
static bool
x_get_net_workarea (struct x_display_info *dpyinfo, XRectangle *rect)
{
@@ -4265,7 +4281,7 @@ Internal use only, use `display-monitor-attributes-list' instead. */)
/ x_display_pixel_height (dpyinfo));
gdpy = gdk_x11_lookup_xdisplay (dpyinfo->display);
gscreen = gdk_display_get_default_screen (gdpy);
-#if GTK_PREREQ (2, 20)
+#if GTK_CHECK_VERSION (2, 20, 0)
primary_monitor = gdk_screen_get_primary_monitor (gscreen);
#endif
n_monitors = gdk_screen_get_n_monitors (gscreen);
@@ -4300,7 +4316,7 @@ Internal use only, use `display-monitor-attributes-list' instead. */)
gdk_screen_get_monitor_geometry (gscreen, i, &rec);
geometry = list4i (rec.x, rec.y, rec.width, rec.height);
-#if GTK_PREREQ (2, 14)
+#if GTK_CHECK_VERSION (2, 14, 0)
width_mm = gdk_screen_get_monitor_width_mm (gscreen, i);
height_mm = gdk_screen_get_monitor_height_mm (gscreen, i);
#endif
@@ -4312,7 +4328,7 @@ Internal use only, use `display-monitor-attributes-list' instead. */)
list2i (width_mm, height_mm)),
attributes);
-#if GTK_PREREQ (3, 4)
+#if GTK_CHECK_VERSION (3, 4, 0)
gdk_screen_get_monitor_workarea (gscreen, i, &rec);
workarea = list4i (rec.x, rec.y, rec.width, rec.height);
#else
@@ -4339,7 +4355,7 @@ Internal use only, use `display-monitor-attributes-list' instead. */)
attributes = Fcons (Fcons (Qworkarea, workarea), attributes);
attributes = Fcons (Fcons (Qgeometry, geometry), attributes);
-#if GTK_PREREQ (2, 14)
+#if GTK_CHECK_VERSION (2, 14, 0)
{
char *name = gdk_screen_get_monitor_plug_name (gscreen, i);
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)
dpy = DEFAULT_GDK_DISPLAY ();
-#if ! GTK_PREREQ (2, 90)
+#if ! GTK_CHECK_VERSION (2, 90, 0)
/* Load our own gtkrc if it exists. */
{
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/>. */
typedef Widget xt_or_gtk_widget;
#endif
-/* True iff GTK's version is at least MAJOR.MINOR. */
-#define GTK_PREREQ(major, minor) \
- ((major) < GTK_MAJOR_VERSION + ((minor) <= GTK_MINOR_VERSION))
-
#ifdef USE_GTK
#include <gtk/gtk.h>
#include <gdk/gdkx.h>
@@ -57,14 +53,26 @@ typedef GtkWidget *xt_or_gtk_widget;
#undef XSync
#define XSync(d, b) do { gdk_window_process_all_updates (); \
XSync (d, b); } while (0)
+#endif /* USE_GTK */
+
+/* True iff GTK's version is at least I.J.K. */
+#ifndef GTK_CHECK_VERSION
+# ifdef USE_GTK
+# define GTK_CHECK_VERSION(i, j, k) \
+ ((i) \
+ < GTK_MAJOR_VERSION + ((j) \
+ < GTK_MINOR_VERSION + ((k) \
+ <= GTK_MICRO_VERSION)))
+# else
+# define GTK_CHECK_VERSION(i, j, k) 0
+# endif
+#endif
/* The GtkTooltip API came in 2.12, but gtk-enable-tooltips in 2.14. */
-#if GTK_PREREQ (2, 14)
+#if GTK_CHECK_VERSION (2, 14, 0)
#define USE_GTK_TOOLTIP
#endif
-#endif /* USE_GTK */
-
/* Bookkeeping to distinguish X versions. */