summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/alloc.c6
-rw-r--r--src/cmds.c1
-rw-r--r--src/conf_post.h4
-rw-r--r--src/dispextern.h1
-rw-r--r--src/editfns.c11
-rw-r--r--src/emacs-module.h.in4
-rw-r--r--src/emacs.c10
-rw-r--r--src/fns.c34
-rw-r--r--src/frame.c12
-rw-r--r--src/frame.h22
-rw-r--r--src/nsfns.m20
-rw-r--r--src/nsmenu.m1
-rw-r--r--src/nsterm.m41
-rw-r--r--src/process.c31
-rw-r--r--src/term.c39
-rw-r--r--src/w32common.h5
-rw-r--r--src/w32fns.c71
-rw-r--r--src/w32term.c27
-rw-r--r--src/window.c2
-rw-r--r--src/xdisp.c6
-rw-r--r--src/xfaces.c3
-rw-r--r--src/xfns.c46
-rw-r--r--src/xterm.c47
23 files changed, 355 insertions, 89 deletions
diff --git a/src/alloc.c b/src/alloc.c
index a3900dbd93c..1763a795ab8 100644
--- a/src/alloc.c
+++ b/src/alloc.c
@@ -6104,11 +6104,13 @@ garbage_collect (void)
gc_in_progress = 0;
- unblock_input ();
-
consing_until_gc = gc_threshold
= consing_threshold (gc_cons_threshold, Vgc_cons_percentage, 0);
+ /* Unblock *after* re-setting `consing_until_gc` in case `unblock_input`
+ signals an error (see bug#43389). */
+ unblock_input ();
+
if (garbage_collection_messages && NILP (Vmemory_full))
{
if (message_p || minibuf_level > 0)
diff --git a/src/cmds.c b/src/cmds.c
index 1547db80e88..c8a96d918cd 100644
--- a/src/cmds.c
+++ b/src/cmds.c
@@ -99,6 +99,7 @@ DEFUN ("forward-line", Fforward_line, Sforward_line, 0, 1, "^p",
Precisely, if point is on line I, move to the start of line I + N
\("start of line" in the logical order).
If there isn't room, go as far as possible (no error).
+Interactively, N is the numeric prefix argument and defaults to 1.
Returns the count of lines left to move. If moving forward,
that is N minus number of lines moved; if backward, N plus number
diff --git a/src/conf_post.h b/src/conf_post.h
index bd56f29e287..176ab28b21a 100644
--- a/src/conf_post.h
+++ b/src/conf_post.h
@@ -71,7 +71,9 @@ typedef bool bool_bf;
It is used only on arguments like cleanup that are handled here.
This macro should be used only in #if expressions, as Oracle
Studio 12.5's __has_attribute does not work in plain code. */
-#ifdef __has_attribute
+#if (defined __has_attribute \
+ && (!defined __clang_minor__ \
+ || 3 < __clang_major__ + (5 <= __clang_minor__)))
# define HAS_ATTRIBUTE(a) __has_attribute (__##a##__)
#else
# define HAS_ATTRIBUTE(a) HAS_ATTR_##a
diff --git a/src/dispextern.h b/src/dispextern.h
index 34b3ef7418b..742fac28bab 100644
--- a/src/dispextern.h
+++ b/src/dispextern.h
@@ -1837,6 +1837,7 @@ enum face_id
WINDOW_DIVIDER_FIRST_PIXEL_FACE_ID,
WINDOW_DIVIDER_LAST_PIXEL_FACE_ID,
INTERNAL_BORDER_FACE_ID,
+ CHILD_FRAME_BORDER_FACE_ID,
TAB_BAR_FACE_ID,
TAB_LINE_FACE_ID,
BASIC_FACE_ID_SENTINEL
diff --git a/src/editfns.c b/src/editfns.c
index 6f04c998915..e3285494c14 100644
--- a/src/editfns.c
+++ b/src/editfns.c
@@ -52,6 +52,9 @@ along with GNU Emacs. If not, see <https://www.gnu.org/licenses/>. */
#include "window.h"
#include "blockinput.h"
+#ifdef WINDOWSNT
+# include "w32common.h"
+#endif
static void update_buffer_properties (ptrdiff_t, ptrdiff_t);
static Lisp_Object styled_format (ptrdiff_t, Lisp_Object *, bool);
@@ -121,12 +124,14 @@ init_editfns (void)
else if (NILP (Vuser_full_name))
Vuser_full_name = build_string ("unknown");
-#ifdef HAVE_SYS_UTSNAME_H
+#if defined HAVE_SYS_UTSNAME_H
{
struct utsname uts;
uname (&uts);
Voperating_system_release = build_string (uts.release);
}
+#elif defined WINDOWSNT
+ Voperating_system_release = build_string (w32_version_string ());
#else
Voperating_system_release = Qnil;
#endif
@@ -4479,7 +4484,9 @@ functions if all the text being accessed has this property. */);
doc: /* The user's name, based upon the real uid only. */);
DEFVAR_LISP ("operating-system-release", Voperating_system_release,
- doc: /* The release of the operating system Emacs is running on. */);
+ doc: /* The kernel version of the operating system on which Emacs is running.
+The value is a string. It can also be nil if Emacs doesn't
+know how to get the kernel version on the underlying OS. */);
DEFVAR_BOOL ("binary-as-unsigned",
binary_as_unsigned,
diff --git a/src/emacs-module.h.in b/src/emacs-module.h.in
index 2989b439109..fe52587c1a5 100644
--- a/src/emacs-module.h.in
+++ b/src/emacs-module.h.in
@@ -51,7 +51,9 @@ information how to write modules and use this header file.
#if 3 < __GNUC__ + (3 <= __GNUC_MINOR__)
# define EMACS_ATTRIBUTE_NONNULL(...) \
__attribute__ ((__nonnull__ (__VA_ARGS__)))
-#elif defined __has_attribute
+#elif (defined __has_attribute \
+ && (!defined __clang_minor__ \
+ || 3 < __clang_major__ + (5 <= __clang_minor__)))
# if __has_attribute (__nonnull__)
# define EMACS_ATTRIBUTE_NONNULL(...) \
__attribute__ ((__nonnull__ (__VA_ARGS__)))
diff --git a/src/emacs.c b/src/emacs.c
index 22995520112..5995410037d 100644
--- a/src/emacs.c
+++ b/src/emacs.c
@@ -186,7 +186,8 @@ bool build_details;
/* Name for the server started by the daemon.*/
static char *daemon_name;
-/* 0 not a daemon, 1 new-style (foreground), 2 old-style (background). */
+/* 0 not a daemon, 1 new-style (foreground), 2 old-style (background).
+ A negative value means the daemon initialization was already done. */
int daemon_type;
#ifndef WINDOWSNT
@@ -2369,7 +2370,10 @@ all of which are called before Emacs is actually killed. */
int exit_code;
#ifdef HAVE_LIBSYSTEMD
- sd_notify(0, "STOPPING=1");
+ /* Notify systemd we are shutting down, but only if we have notified
+ it about startup. */
+ if (daemon_type == -1)
+ sd_notify(0, "STOPPING=1");
#endif /* HAVE_LIBSYSTEMD */
/* Fsignal calls emacs_abort () if it sees that waiting_for_input is
@@ -2881,7 +2885,7 @@ from the parent process and its tty file descriptors. */)
}
/* Set it to an invalid value so we know we've already run this function. */
- daemon_type = -1;
+ daemon_type = -daemon_type;
#else /* WINDOWSNT */
/* Signal the waiting emacsclient process. */
diff --git a/src/fns.c b/src/fns.c
index 7ab2e8f1a03..bd4afa0c4e9 100644
--- a/src/fns.c
+++ b/src/fns.c
@@ -4599,33 +4599,29 @@ sweep_weak_table (struct Lisp_Hash_Table *h, bool remove_entries_p)
EMACS_UINT
hash_string (char const *ptr, ptrdiff_t len)
{
- EMACS_UINT const *p = (EMACS_UINT const *) ptr;
- EMACS_UINT const *end = (EMACS_UINT const *) (ptr + len);
+ char const *p = ptr;
+ char const *end = ptr + len;
EMACS_UINT hash = len;
/* At most 8 steps. We could reuse SXHASH_MAX_LEN, of course,
* but dividing by 8 is cheaper. */
- ptrdiff_t step = 1 + ((end - p) >> 3);
+ ptrdiff_t step = sizeof hash + ((end - p) >> 3);
- /* Beware: `end` might be unaligned, so `p < end` is not always the same
- * as `p <= end - 1`. */
- while (p <= end - 1)
+ while (p + sizeof hash <= end)
{
- EMACS_UINT c = *p;
+ EMACS_UINT c;
+ /* We presume that the compiler will replace this `memcpy` with
+ a single load/move instruction when applicable. */
+ memcpy (&c, p, sizeof hash);
p += step;
hash = sxhash_combine (hash, c);
}
- if (p < end)
- { /* A few last bytes remain (smaller than an EMACS_UINT). */
- /* FIXME: We could do this without a loop, but it'd require
- endian-dependent code :-( */
- char const *p1 = (char const *)p;
- char const *end1 = (char const *)end;
- do
- {
- unsigned char c = *p1++;
- hash = sxhash_combine (hash, c);
- }
- while (p1 < end1);
+ /* A few last bytes may remain (smaller than an EMACS_UINT). */
+ /* FIXME: We could do this without a loop, but it'd require
+ endian-dependent code :-( */
+ while (p < end)
+ {
+ unsigned char c = *p++;
+ hash = sxhash_combine (hash, c);
}
return hash;
diff --git a/src/frame.c b/src/frame.c
index 998ddaabb39..a3e44c75eeb 100644
--- a/src/frame.c
+++ b/src/frame.c
@@ -3546,6 +3546,13 @@ DEFUN ("frame-fringe-width", Ffringe_width, Sfringe_width, 0, 1, 0,
return make_fixnum (FRAME_TOTAL_FRINGE_WIDTH (decode_any_frame (frame)));
}
+DEFUN ("frame-child-frame-border-width", Fframe_child_frame_border_width, Sframe_child_frame_border_width, 0, 1, 0,
+ doc: /* Return width of FRAME's child-frame border in pixels. */)
+ (Lisp_Object frame)
+{
+ return make_fixnum (FRAME_CHILD_FRAME_BORDER_WIDTH (decode_any_frame (frame)));
+}
+
DEFUN ("frame-internal-border-width", Fframe_internal_border_width, Sframe_internal_border_width, 0, 1, 0,
doc: /* Return width of FRAME's internal border in pixels. */)
(Lisp_Object frame)
@@ -3762,6 +3769,7 @@ static const struct frame_parm_table frame_parms[] =
{"foreground-color", -1},
{"icon-name", SYMBOL_INDEX (Qicon_name)},
{"icon-type", SYMBOL_INDEX (Qicon_type)},
+ {"child-frame-border-width", SYMBOL_INDEX (Qchild_frame_border_width)},
{"internal-border-width", SYMBOL_INDEX (Qinternal_border_width)},
{"right-divider-width", SYMBOL_INDEX (Qright_divider_width)},
{"bottom-divider-width", SYMBOL_INDEX (Qbottom_divider_width)},
@@ -4305,6 +4313,8 @@ gui_report_frame_params (struct frame *f, Lisp_Object *alistptr)
store_in_alist (alistptr, Qborder_width,
make_fixnum (f->border_width));
+ store_in_alist (alistptr, Qchild_frame_border_width,
+ make_fixnum (FRAME_CHILD_FRAME_BORDER_WIDTH (f)));
store_in_alist (alistptr, Qinternal_border_width,
make_fixnum (FRAME_INTERNAL_BORDER_WIDTH (f)));
store_in_alist (alistptr, Qright_divider_width,
@@ -6017,6 +6027,7 @@ syms_of_frame (void)
DEFSYM (Qhorizontal_scroll_bars, "horizontal-scroll-bars");
DEFSYM (Qicon_name, "icon-name");
DEFSYM (Qicon_type, "icon-type");
+ DEFSYM (Qchild_frame_border_width, "child-frame-border-width");
DEFSYM (Qinternal_border_width, "internal-border-width");
DEFSYM (Qleft_fringe, "left-fringe");
DEFSYM (Qline_spacing, "line-spacing");
@@ -6446,6 +6457,7 @@ iconify the top level frame instead. */);
defsubr (&Sscroll_bar_width);
defsubr (&Sscroll_bar_height);
defsubr (&Sfringe_width);
+ defsubr (&Sframe_child_frame_border_width);
defsubr (&Sframe_internal_border_width);
defsubr (&Sright_divider_width);
defsubr (&Sbottom_divider_width);
diff --git a/src/frame.h b/src/frame.h
index 7372e74cfef..a80d2a1f5ae 100644
--- a/src/frame.h
+++ b/src/frame.h
@@ -534,6 +534,10 @@ struct frame
/* Border width of the frame window as known by the (X) window system. */
int border_width;
+ /* Width of child frames' internal border. Acts as
+ internal_border_width for child frames. */
+ int child_frame_border_width;
+
/* Width of the internal border. This is a line of background color
just inside the window's border. When the frame is selected,
a highlighting is displayed inside the internal border. */
@@ -1441,11 +1445,27 @@ FRAME_TOTAL_FRINGE_WIDTH (struct frame *f)
return FRAME_LEFT_FRINGE_WIDTH (f) + FRAME_RIGHT_FRINGE_WIDTH (f);
}
-/* Pixel-width of internal border lines. */
+INLINE int
+FRAME_CHILD_FRAME_BORDER_WIDTH (struct frame *f)
+{
+ return frame_dimension (f->child_frame_border_width);
+}
+
+/* Pixel-width of internal border. Uses child_frame_border_width for
+ child frames if possible, and falls back on internal_border_width
+ otherwise. */
INLINE int
FRAME_INTERNAL_BORDER_WIDTH (struct frame *f)
{
+#ifdef HAVE_WINDOW_SYSTEM
+ return FRAME_PARENT_FRAME(f)
+ ? (f->child_frame_border_width
+ ? FRAME_CHILD_FRAME_BORDER_WIDTH(f)
+ : frame_dimension (f->internal_border_width))
+ : frame_dimension (f->internal_border_width);
+#else
return frame_dimension (f->internal_border_width);
+#endif
}
/* Pixel-size of window divider lines. */
diff --git a/src/nsfns.m b/src/nsfns.m
index ae114f83e4d..c383e2f7ecf 100644
--- a/src/nsfns.m
+++ b/src/nsfns.m
@@ -687,6 +687,21 @@ ns_set_tool_bar_lines (struct frame *f, Lisp_Object value, Lisp_Object oldval)
}
}
+static void
+ns_set_child_frame_border_width (struct frame *f, Lisp_Object arg, Lisp_Object oldval)
+{
+ int old_width = FRAME_CHILD_FRAME_BORDER_WIDTH (f);
+ int new_width = check_int_nonnegative (arg);
+
+ if (new_width == old_width)
+ return;
+ f->child_frame_border_width = new_width;
+
+ if (FRAME_NATIVE_WINDOW (f) != 0)
+ adjust_frame_size (f, -1, -1, 3, 0, Qchild_frame_border_width);
+
+ SET_FRAME_GARBAGED (f);
+}
static void
ns_set_internal_border_width (struct frame *f, Lisp_Object arg, Lisp_Object oldval)
@@ -912,6 +927,7 @@ frame_parm_handler ns_frame_parm_handlers[] =
ns_set_foreground_color,
ns_set_icon_name,
ns_set_icon_type,
+ ns_set_child_frame_border_width,
ns_set_internal_border_width,
gui_set_right_divider_width, /* generic OK */
gui_set_bottom_divider_width, /* generic OK */
@@ -1197,6 +1213,9 @@ DEFUN ("x-create-frame", Fx_create_frame, Sx_create_frame,
gui_default_parameter (f, parms, Qinternal_border_width, make_fixnum (2),
"internalBorderWidth", "InternalBorderWidth",
RES_TYPE_NUMBER);
+ gui_default_parameter (f, parms, Qchild_frame_border_width, make_fixnum (2),
+ "childFrameBorderWidth", "childFrameBorderWidth",
+ RES_TYPE_NUMBER);
gui_default_parameter (f, parms, Qright_divider_width, make_fixnum (0),
NULL, NULL, RES_TYPE_NUMBER);
gui_default_parameter (f, parms, Qbottom_divider_width, make_fixnum (0),
@@ -1487,7 +1506,6 @@ Some window managers may refuse to restack windows. */)
{
EmacsWindow *window = (EmacsWindow *)[FRAME_NS_VIEW (f1) window];
NSWindow *window2 = [FRAME_NS_VIEW (f2) window];
- BOOL flag = !NILP (above);
if ([window restackWindow:window2 above:!NILP (above)])
return Qt;
diff --git a/src/nsmenu.m b/src/nsmenu.m
index 8086f56854e..f8219d27026 100644
--- a/src/nsmenu.m
+++ b/src/nsmenu.m
@@ -101,7 +101,6 @@ popup_activated (void)
static void
ns_update_menubar (struct frame *f, bool deep_p)
{
- NSAutoreleasePool *pool;
BOOL needsSet = NO;
id menu = [NSApp mainMenu];
bool owfi;
diff --git a/src/nsterm.m b/src/nsterm.m
index c5815ce8d10..1b2328628ee 100644
--- a/src/nsterm.m
+++ b/src/nsterm.m
@@ -272,7 +272,9 @@ long context_menu_value = 0;
/* display update */
static struct frame *ns_updating_frame;
+#if !defined (NS_DRAW_TO_BUFFER) || MAC_OS_X_VERSION_MIN_REQUIRED < 101400
static NSView *focus_view = NULL;
+#endif
static int ns_window_num = 0;
static BOOL gsaved = NO;
static BOOL ns_fake_keydown = NO;
@@ -1139,7 +1141,9 @@ ns_update_end (struct frame *f)
external (RIF) call; for whole frame, called after gui_update_window_end
-------------------------------------------------------------------------- */
{
+#if !defined (NS_DRAW_TO_BUFFER) || MAC_OS_X_VERSION_MIN_REQUIRED < 101400
EmacsView *view = FRAME_NS_VIEW (f);
+#endif
NSTRACE_WHEN (NSTRACE_GROUP_UPDATES, "ns_update_end");
@@ -1449,7 +1453,7 @@ ns_ring_bell (struct frame *f)
}
}
-
+#if !defined (NS_DRAW_TO_BUFFER) || MAC_OS_X_VERSION_MIN_REQUIRED < 101400
static void
hide_bell (void)
/* --------------------------------------------------------------------------
@@ -1463,6 +1467,7 @@ hide_bell (void)
[bell_view remove];
}
}
+#endif
/* ==========================================================================
@@ -2876,6 +2881,8 @@ ns_get_shifted_character (NSEvent *event)
========================================================================== */
+#if 0
+/* FIXME: Remove this function. */
static void
ns_redraw_scroll_bars (struct frame *f)
{
@@ -2890,6 +2897,7 @@ ns_redraw_scroll_bars (struct frame *f)
[view display];
}
}
+#endif
void
@@ -3029,9 +3037,13 @@ ns_clear_under_internal_border (struct frame *f)
NSRectEdge edge[] = {NSMinXEdge, NSMinYEdge, NSMaxXEdge, NSMaxYEdge};
int face_id =
- !NILP (Vface_remapping_alist)
- ? lookup_basic_face (NULL, f, INTERNAL_BORDER_FACE_ID)
- : INTERNAL_BORDER_FACE_ID;
+ (FRAME_PARENT_FRAME (f)
+ ? (!NILP (Vface_remapping_alist)
+ ? lookup_basic_face (NULL, f, CHILD_FRAME_BORDER_FACE_ID)
+ : CHILD_FRAME_BORDER_FACE_ID)
+ : (!NILP (Vface_remapping_alist)
+ ? lookup_basic_face (NULL, f, INTERNAL_BORDER_FACE_ID)
+ : INTERNAL_BORDER_FACE_ID));
struct face *face = FACE_FROM_ID_OR_NULL (f, face_id);
if (!face)
@@ -8399,21 +8411,23 @@ not_in_argv (NSString *arg)
void *pixels = CGBitmapContextGetData (context);
int rowSize = CGBitmapContextGetBytesPerRow (context);
int srcRowSize = NSWidth (srcRect) * scale * bpp;
- void *srcPixels = pixels + (int)(NSMinY (srcRect) * scale * rowSize
- + NSMinX (srcRect) * scale * bpp);
- void *dstPixels = pixels + (int)(NSMinY (dstRect) * scale * rowSize
- + NSMinX (dstRect) * scale * bpp);
+ void *srcPixels = (char *) pixels
+ + (int) (NSMinY (srcRect) * scale * rowSize
+ + NSMinX (srcRect) * scale * bpp);
+ void *dstPixels = (char *) pixels
+ + (int) (NSMinY (dstRect) * scale * rowSize
+ + NSMinX (dstRect) * scale * bpp);
if (NSIntersectsRect (srcRect, dstRect)
&& NSMinY (srcRect) < NSMinY (dstRect))
for (int y = NSHeight (srcRect) * scale - 1 ; y >= 0 ; y--)
- memmove (dstPixels + y * rowSize,
- srcPixels + y * rowSize,
+ memmove ((char *) dstPixels + y * rowSize,
+ (char *) srcPixels + y * rowSize,
srcRowSize);
else
for (int y = 0 ; y < NSHeight (srcRect) * scale ; y++)
- memmove (dstPixels + y * rowSize,
- srcPixels + y * rowSize,
+ memmove ((char *) dstPixels + y * rowSize,
+ (char *) srcPixels + y * rowSize,
srcRowSize);
#if MAC_OS_X_VERSION_MIN_REQUIRED < 101400
@@ -8742,7 +8756,8 @@ not_in_argv (NSString *arg)
/* The array returned by [NSWindow parentWindow] may already be
sorted, but the documentation doesn't tell us whether or not it is,
so to be safe we'll sort it. */
-NSInteger nswindow_orderedIndex_sort (id w1, id w2, void *c)
+static NSInteger
+nswindow_orderedIndex_sort (id w1, id w2, void *c)
{
NSInteger i1 = [w1 orderedIndex];
NSInteger i2 = [w2 orderedIndex];
diff --git a/src/process.c b/src/process.c
index 4ab194b2b5b..5ac0d20df5b 100644
--- a/src/process.c
+++ b/src/process.c
@@ -290,7 +290,9 @@ static int child_signal_read_fd = -1;
status changes. */
static int child_signal_write_fd = -1;
static void child_signal_init (void);
+#ifndef WINDOWSNT
static void child_signal_read (int, void *);
+#endif
static void child_signal_notify (void);
/* Indexed by descriptor, gives the process (if any) for that descriptor. */
@@ -7152,8 +7154,23 @@ process has been transmitted to the serial port. */)
have the same process ID.
To avoid a deadlock when receiving SIGCHLD while
- `wait_reading_process_output' is in `pselect', the SIGCHLD handler
- will notify the `pselect' using a pipe. */
+ 'wait_reading_process_output' is in 'pselect', the SIGCHLD handler
+ will notify the `pselect' using a self-pipe. The deadlock could
+ occur if SIGCHLD is delivered outside of the 'pselect' call, in
+ which case 'pselect' will not be interrupted by the signal, and
+ will therefore wait on the process's output descriptor for the
+ output that will never come.
+
+ WINDOWSNT doesn't need this facility because its 'pselect'
+ emulation (see 'sys_select' in w32proc.c) waits on a subprocess
+ handle, which becomes signaled when the process exits, and also
+ because that emulation delays the delivery of the simulated SIGCHLD
+ until all the output from the subprocess has been consumed. */
+
+/* FIXME: On Unix-like systems that have a proper 'pselect'
+ (HAVE_PSELECT), we should block SIGCHLD in
+ 'wait_reading_process_output' and pass a non-NULL signal mask to
+ 'pselect' to avoid the need for the self-pipe. */
/* Set up `child_signal_read_fd' and `child_signal_write_fd'. */
@@ -7163,6 +7180,7 @@ child_signal_init (void)
/* Either both are initialized, or both are uninitialized. */
eassert ((child_signal_read_fd < 0) == (child_signal_write_fd < 0));
+#ifndef WINDOWSNT
if (0 <= child_signal_read_fd)
return; /* already done */
@@ -7185,12 +7203,16 @@ child_signal_init (void)
eassert (0 <= fds[1]);
if (fcntl (fds[0], F_SETFL, O_NONBLOCK) != 0)
emacs_perror ("fcntl");
+ if (fcntl (fds[1], F_SETFL, O_NONBLOCK) != 0)
+ emacs_perror ("fcntl");
add_read_fd (fds[0], child_signal_read, NULL);
fd_callback_info[fds[0]].flags &= ~KEYBOARD_FD;
child_signal_read_fd = fds[0];
child_signal_write_fd = fds[1];
+#endif /* !WINDOWSNT */
}
+#ifndef WINDOWSNT
/* Consume a process status change. */
static void
@@ -7199,9 +7221,10 @@ child_signal_read (int fd, void *data)
eassert (0 <= fd);
eassert (fd == child_signal_read_fd);
char dummy;
- if (emacs_read (fd, &dummy, 1) < 0)
+ if (emacs_read (fd, &dummy, 1) < 0 && errno != EAGAIN)
emacs_perror ("reading from child signal FD");
}
+#endif /* !WINDOWSNT */
/* Notify `wait_reading_process_output' of a process status
change. */
@@ -7209,11 +7232,13 @@ child_signal_read (int fd, void *data)
static void
child_signal_notify (void)
{
+#ifndef WINDOWSNT
int fd = child_signal_write_fd;
eassert (0 <= fd);
char dummy = 0;
if (emacs_write (fd, &dummy, 1) != 1)
emacs_perror ("writing to child signal FD");
+#endif
}
/* LIB_CHILD_HANDLER is a SIGCHLD handler that Emacs calls while doing
diff --git a/src/term.c b/src/term.c
index 2e2ab2bf438..1059b0669a7 100644
--- a/src/term.c
+++ b/src/term.c
@@ -790,7 +790,7 @@ tty_write_glyphs (struct frame *f, struct glyph *string, int len)
cmcheckmagic (tty);
}
-#ifdef HAVE_GPM /* Only used by GPM code. */
+#ifndef DOS_NT
static void
tty_write_glyphs_with_face (register struct frame *f, register struct glyph *string,
@@ -847,6 +847,7 @@ tty_write_glyphs_with_face (register struct frame *f, register struct glyph *str
cmcheckmagic (tty);
}
+
#endif
/* An implementation of insert_glyphs for termcap frames. */
@@ -2380,23 +2381,9 @@ frame's terminal). */)
Mouse
***********************************************************************/
-#ifdef HAVE_GPM
-
-void
-term_mouse_moveto (int x, int y)
-{
- /* TODO: how to set mouse position?
- const char *name;
- int fd;
- name = (const char *) ttyname (0);
- fd = emacs_open (name, O_WRONLY, 0);
- SOME_FUNCTION (x, y, fd);
- emacs_close (fd);
- last_mouse_x = x;
- last_mouse_y = y; */
-}
+#ifndef DOS_NT
-/* Implementation of draw_row_with_mouse_face for TTY/GPM. */
+/* Implementation of draw_row_with_mouse_face for TTY/GPM and macOS. */
void
tty_draw_row_with_mouse_face (struct window *w, struct glyph_row *row,
int start_hpos, int end_hpos,
@@ -2428,6 +2415,24 @@ tty_draw_row_with_mouse_face (struct window *w, struct glyph_row *row,
cursor_to (f, save_y, save_x);
}
+#endif
+
+#ifdef HAVE_GPM
+
+void
+term_mouse_moveto (int x, int y)
+{
+ /* TODO: how to set mouse position?
+ const char *name;
+ int fd;
+ name = (const char *) ttyname (0);
+ fd = emacs_open (name, O_WRONLY, 0);
+ SOME_FUNCTION (x, y, fd);
+ emacs_close (fd);
+ last_mouse_x = x;
+ last_mouse_y = y; */
+}
+
/* Return the current time, as a Time value. Wrap around on overflow. */
static Time
current_Time (void)
diff --git a/src/w32common.h b/src/w32common.h
index 94bb457e59d..714a2386a68 100644
--- a/src/w32common.h
+++ b/src/w32common.h
@@ -50,6 +50,11 @@ extern int os_subtype;
/* Cache system info, e.g., the NT page size. */
extern void cache_system_info (void);
+#ifdef WINDOWSNT
+/* Return a static buffer with the MS-Windows version string. */
+extern char * w32_version_string (void);
+#endif
+
typedef void (* VOIDFNPTR) (void);
/* Load a function address from a DLL. Cast the result via VOIDFNPTR
diff --git a/src/w32fns.c b/src/w32fns.c
index c1e18ff7fad..e93a0b85d93 100644
--- a/src/w32fns.c
+++ b/src/w32fns.c
@@ -1519,9 +1519,13 @@ w32_clear_under_internal_border (struct frame *f)
int width = FRAME_PIXEL_WIDTH (f);
int height = FRAME_PIXEL_HEIGHT (f);
int face_id =
- !NILP (Vface_remapping_alist)
- ? lookup_basic_face (NULL, f, INTERNAL_BORDER_FACE_ID)
- : INTERNAL_BORDER_FACE_ID;
+ (FRAME_PARENT_FRAME (f)
+ ? (!NILP (Vface_remapping_alist)
+ ? lookup_basic_face (NULL, f, CHILD_FRAME_BORDER_FACE_ID)
+ : CHILD_FRAME_BORDER_FACE_ID)
+ : (!NILP (Vface_remapping_alist)
+ ? lookup_basic_face (NULL, f, INTERNAL_BORDER_FACE_ID)
+ : INTERNAL_BORDER_FACE_ID));
struct face *face = FACE_FROM_ID_OR_NULL (f, face_id);
block_input ();
@@ -1548,6 +1552,32 @@ w32_clear_under_internal_border (struct frame *f)
}
}
+/**
+ * w32_set_child_frame_border_width:
+ *
+ * Set width of child frame F's internal border to ARG pixels.
+ * ARG < 0 is treated like ARG = 0.
+ */
+static void
+w32_set_child_frame_border_width (struct frame *f, Lisp_Object arg, Lisp_Object oldval)
+{
+ int argval = check_integer_range (arg, INT_MIN, INT_MAX);
+ int border = max (argval, 0);
+
+ if (border != FRAME_CHILD_FRAME_BORDER_WIDTH (f))
+ {
+ f->child_frame_border_width = border;
+
+ if (FRAME_NATIVE_WINDOW (f) != 0)
+ {
+ adjust_frame_size (f, -1, -1, 3, false, Qchild_frame_border_width);
+
+ if (FRAME_VISIBLE_P (f))
+ w32_clear_under_internal_border (f);
+ }
+ }
+}
+
/**
* w32_set_internal_border_width:
@@ -5873,6 +5903,28 @@ DEFUN ("x-create-frame", Fx_create_frame, Sx_create_frame,
parameters);
}
+ /* Same for child frames. */
+ if (NILP (Fassq (Qchild_frame_border_width, parameters)))
+ {
+ Lisp_Object value;
+
+ value = gui_display_get_arg (dpyinfo, parameters, Qchild_frame_border_width,
+ "childFrameBorderWidth", "childFrameBorderWidth",
+ RES_TYPE_NUMBER);
+ if (! EQ (value, Qunbound))
+ parameters = Fcons (Fcons (Qchild_frame_border_width, value),
+ parameters);
+
+ }
+
+ gui_default_parameter (f, parameters, Qchild_frame_border_width,
+#ifdef USE_GTK /* We used to impose 0 in xg_create_frame_widgets. */
+ make_fixnum (0),
+#else
+ make_fixnum (1),
+#endif
+ "childFrameBorderWidth", "childFrameBorderWidth",
+ RES_TYPE_NUMBER);
gui_default_parameter (f, parameters, Qinternal_border_width, make_fixnum (0),
"internalBorderWidth", "InternalBorder", RES_TYPE_NUMBER);
gui_default_parameter (f, parameters, Qright_divider_width, make_fixnum (0),
@@ -9428,6 +9480,18 @@ cache_system_info (void)
w32_num_mouse_buttons = GetSystemMetrics (SM_CMOUSEBUTTONS);
}
+#ifdef WINDOWSNT
+char *
+w32_version_string (void)
+{
+ /* NNN.NNN.NNNNNNNNNN */
+ static char version_string[3 + 1 + 3 + 1 + 10 + 1];
+ _snprintf (version_string, sizeof version_string, "%d.%d.%d",
+ w32_major_version, w32_minor_version, w32_build_number);
+ return version_string;
+}
+#endif
+
#ifdef EMACSDEBUG
void
_DebPrint (const char *fmt, ...)
@@ -10232,6 +10296,7 @@ frame_parm_handler w32_frame_parm_handlers[] =
w32_set_foreground_color,
w32_set_icon_name,
w32_set_icon_type,
+ w32_set_child_frame_border_width,
w32_set_internal_border_width,
gui_set_right_divider_width,
gui_set_bottom_divider_width,
diff --git a/src/w32term.c b/src/w32term.c
index 109aa58d732..0ee805a8526 100644
--- a/src/w32term.c
+++ b/src/w32term.c
@@ -2404,14 +2404,29 @@ w32_draw_stretch_glyph_string (struct glyph_string *s)
else if (!s->background_filled_p)
{
int background_width = s->background_width;
- int x = s->x, left_x = window_box_left_offset (s->w, TEXT_AREA);
+ int x = s->x, text_left_x = window_box_left_offset (s->w, TEXT_AREA);
- /* Don't draw into left margin, fringe or scrollbar area
- except for header line and mode line. */
- if (x < left_x && !s->row->mode_line_p)
+ /* Don't draw into left fringe or scrollbar area except for
+ header line and mode line. */
+ if (x < text_left_x && !s->row->mode_line_p)
{
- background_width -= left_x - x;
- x = left_x;
+ int left_x = WINDOW_LEFT_SCROLL_BAR_AREA_WIDTH (s->w);
+ int right_x = text_left_x;
+
+ if (WINDOW_HAS_FRINGES_OUTSIDE_MARGINS (s->w))
+ left_x += WINDOW_LEFT_FRINGE_WIDTH (s->w);
+ else
+ right_x -= WINDOW_LEFT_FRINGE_WIDTH (s->w);
+
+ /* Adjust X and BACKGROUND_WIDTH to fit inside the space
+ between LEFT_X and RIGHT_X. */
+ if (x < left_x)
+ {
+ background_width -= left_x - x;
+ x = left_x;
+ }
+ if (x + background_width > right_x)
+ background_width = right_x - x;
}
if (background_width > 0)
w32_draw_glyph_string_bg_rect (s, x, s->y, background_width, s->height);
diff --git a/src/window.c b/src/window.c
index e025e0b0821..eb16e2a4338 100644
--- a/src/window.c
+++ b/src/window.c
@@ -2260,7 +2260,7 @@ return value is a list of elements of the form (PARAMETER . VALUE). */)
Lisp_Object
window_parameter (struct window *w, Lisp_Object parameter)
{
- Lisp_Object result = Fassq (parameter, w->window_parameters);
+ Lisp_Object result = assq_no_quit (parameter, w->window_parameters);
return CDR_SAFE (result);
}
diff --git a/src/xdisp.c b/src/xdisp.c
index 592bdb7be34..c63a6e5171b 100644
--- a/src/xdisp.c
+++ b/src/xdisp.c
@@ -29828,7 +29828,8 @@ produce_stretch_glyph (struct it *it)
#endif /* HAVE_WINDOW_SYSTEM */
height = 1;
- if (width > 0 && it->line_wrap != TRUNCATE
+ if (width > 0
+ && it->area == TEXT_AREA && it->line_wrap != TRUNCATE
&& it->current_x + width > it->last_visible_x)
{
width = it->last_visible_x - it->current_x;
@@ -31942,9 +31943,8 @@ draw_row_with_mouse_face (struct window *w, int start_x, struct glyph_row *row,
return;
}
#endif
-#if defined (HAVE_GPM) || defined (MSDOS) || defined (WINDOWSNT)
+
tty_draw_row_with_mouse_face (w, row, start_hpos, end_hpos, draw);
-#endif
}
/* Display the active region described by mouse_face_* according to DRAW. */
diff --git a/src/xfaces.c b/src/xfaces.c
index d38328476a4..b3960fbf9a8 100644
--- a/src/xfaces.c
+++ b/src/xfaces.c
@@ -4938,6 +4938,7 @@ lookup_basic_face (struct window *w, struct frame *f, int face_id)
case WINDOW_DIVIDER_FIRST_PIXEL_FACE_ID: name = Qwindow_divider_first_pixel; break;
case WINDOW_DIVIDER_LAST_PIXEL_FACE_ID: name = Qwindow_divider_last_pixel; break;
case INTERNAL_BORDER_FACE_ID: name = Qinternal_border; break;
+ case CHILD_FRAME_BORDER_FACE_ID: name = Qchild_frame_border; break;
default:
emacs_abort (); /* the caller is supposed to pass us a basic face id */
@@ -5644,6 +5645,7 @@ realize_basic_faces (struct frame *f)
realize_named_face (f, Qwindow_divider_last_pixel,
WINDOW_DIVIDER_LAST_PIXEL_FACE_ID);
realize_named_face (f, Qinternal_border, INTERNAL_BORDER_FACE_ID);
+ realize_named_face (f, Qchild_frame_border, CHILD_FRAME_BORDER_FACE_ID);
realize_named_face (f, Qtab_bar, TAB_BAR_FACE_ID);
realize_named_face (f, Qtab_line, TAB_LINE_FACE_ID);
@@ -6997,6 +6999,7 @@ syms_of_xfaces (void)
DEFSYM (Qwindow_divider_first_pixel, "window-divider-first-pixel");
DEFSYM (Qwindow_divider_last_pixel, "window-divider-last-pixel");
DEFSYM (Qinternal_border, "internal-border");
+ DEFSYM (Qchild_frame_border, "child-frame-border");
/* TTY color-related functions (defined in tty-colors.el). */
DEFSYM (Qtty_color_desc, "tty-color-desc");
diff --git a/src/xfns.c b/src/xfns.c
index 9ab537ca8d9..cac41ee4856 100644
--- a/src/xfns.c
+++ b/src/xfns.c
@@ -1800,6 +1800,28 @@ x_change_tool_bar_height (struct frame *f, int height)
#endif /* USE_GTK */
}
+static void
+x_set_child_frame_border_width (struct frame *f, Lisp_Object arg, Lisp_Object oldval)
+{
+ int border = check_int_nonnegative (arg);
+
+ if (border != FRAME_CHILD_FRAME_BORDER_WIDTH (f))
+ {
+ f->child_frame_border_width = border;
+
+#ifdef USE_X_TOOLKIT
+ if (FRAME_X_OUTPUT (f)->edit_widget)
+ widget_store_internal_border (FRAME_X_OUTPUT (f)->edit_widget);
+#endif
+
+ if (FRAME_X_WINDOW (f))
+ {
+ adjust_frame_size (f, -1, -1, 3, false, Qchild_frame_border_width);
+ x_clear_under_internal_border (f);
+ }
+ }
+
+}
static void
x_set_internal_border_width (struct frame *f, Lisp_Object arg, Lisp_Object oldval)
@@ -3897,6 +3919,29 @@ This function is an internal primitive--use `make-frame' instead. */)
parms = Fcons (Fcons (Qinternal_border_width, value),
parms);
}
+
+ /* Same for child frames. */
+ if (NILP (Fassq (Qchild_frame_border_width, parms)))
+ {
+ Lisp_Object value;
+
+ value = gui_display_get_arg (dpyinfo, parms, Qchild_frame_border_width,
+ "childFrameBorderWidth", "childFrameBorderWidth",
+ RES_TYPE_NUMBER);
+ if (! EQ (value, Qunbound))
+ parms = Fcons (Fcons (Qchild_frame_border_width, value),
+ parms);
+
+ }
+
+ gui_default_parameter (f, parms, Qchild_frame_border_width,
+#ifdef USE_GTK /* We used to impose 0 in xg_create_frame_widgets. */
+ make_fixnum (0),
+#else
+ make_fixnum (1),
+#endif
+ "childFrameBorderWidth", "childFrameBorderWidth",
+ RES_TYPE_NUMBER);
gui_default_parameter (f, parms, Qinternal_border_width,
#ifdef USE_GTK /* We used to impose 0 in xg_create_frame_widgets. */
make_fixnum (0),
@@ -7762,6 +7807,7 @@ frame_parm_handler x_frame_parm_handlers[] =
x_set_foreground_color,
x_set_icon_name,
x_set_icon_type,
+ x_set_child_frame_border_width,
x_set_internal_border_width,
gui_set_right_divider_width,
gui_set_bottom_divider_width,
diff --git a/src/xterm.c b/src/xterm.c
index b8374fed8b1..744b80c68a0 100644
--- a/src/xterm.c
+++ b/src/xterm.c
@@ -1293,9 +1293,13 @@ x_clear_under_internal_border (struct frame *f)
int height = FRAME_PIXEL_HEIGHT (f);
int margin = FRAME_TOP_MARGIN_HEIGHT (f);
int face_id =
- !NILP (Vface_remapping_alist)
- ? lookup_basic_face (NULL, f, INTERNAL_BORDER_FACE_ID)
- : INTERNAL_BORDER_FACE_ID;
+ (FRAME_PARENT_FRAME (f)
+ ? (!NILP (Vface_remapping_alist)
+ ? lookup_basic_face (NULL, f, CHILD_FRAME_BORDER_FACE_ID)
+ : CHILD_FRAME_BORDER_FACE_ID)
+ : (!NILP (Vface_remapping_alist)
+ ? lookup_basic_face (NULL, f, INTERNAL_BORDER_FACE_ID)
+ : INTERNAL_BORDER_FACE_ID));
struct face *face = FACE_FROM_ID_OR_NULL (f, face_id);
block_input ();
@@ -1360,9 +1364,13 @@ x_after_update_window_line (struct window *w, struct glyph_row *desired_row)
{
int y = WINDOW_TO_FRAME_PIXEL_Y (w, max (0, desired_row->y));
int face_id =
- !NILP (Vface_remapping_alist)
- ? lookup_basic_face (NULL, f, INTERNAL_BORDER_FACE_ID)
- : INTERNAL_BORDER_FACE_ID;
+ (FRAME_PARENT_FRAME (f)
+ ? (!NILP (Vface_remapping_alist)
+ ? lookup_basic_face (NULL, f, CHILD_FRAME_BORDER_FACE_ID)
+ : CHILD_FRAME_BORDER_FACE_ID)
+ : (!NILP (Vface_remapping_alist)
+ ? lookup_basic_face (NULL, f, INTERNAL_BORDER_FACE_ID)
+ : INTERNAL_BORDER_FACE_ID));
struct face *face = FACE_FROM_ID_OR_NULL (f, face_id);
block_input ();
@@ -3577,14 +3585,29 @@ x_draw_stretch_glyph_string (struct glyph_string *s)
else if (!s->background_filled_p)
{
int background_width = s->background_width;
- int x = s->x, left_x = window_box_left_offset (s->w, TEXT_AREA);
+ int x = s->x, text_left_x = window_box_left_offset (s->w, TEXT_AREA);
- /* Don't draw into left margin, fringe or scrollbar area
- except for header line and mode line. */
- if (x < left_x && !s->row->mode_line_p)
+ /* Don't draw into left fringe or scrollbar area except for
+ header line and mode line. */
+ if (x < text_left_x && !s->row->mode_line_p)
{
- background_width -= left_x - x;
- x = left_x;
+ int left_x = WINDOW_LEFT_SCROLL_BAR_AREA_WIDTH (s->w);
+ int right_x = text_left_x;
+
+ if (WINDOW_HAS_FRINGES_OUTSIDE_MARGINS (s->w))
+ left_x += WINDOW_LEFT_FRINGE_WIDTH (s->w);
+ else
+ right_x -= WINDOW_LEFT_FRINGE_WIDTH (s->w);
+
+ /* Adjust X and BACKGROUND_WIDTH to fit inside the space
+ between LEFT_X and RIGHT_X. */
+ if (x < left_x)
+ {
+ background_width -= left_x - x;
+ x = left_x;
+ }
+ if (x + background_width > right_x)
+ background_width = right_x - x;
}
if (background_width > 0)
x_draw_glyph_string_bg_rect (s, x, s->y, background_width, s->height);