aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorAndrea Corallo2021-01-30 14:09:37 +0100
committerAndrea Corallo2021-01-30 14:09:37 +0100
commita8b8d220b4fccaa812e85f9b2b3715593dc285ac (patch)
tree07051469f09277b1993eee37870059e3d0abf71e /src
parentb8d3ae78c54db7c7bb65d367a80f9be3d8744c48 (diff)
parented2f2cc5577d5d9b61db7a5b61e93e79d678be41 (diff)
downloademacs-a8b8d220b4fccaa812e85f9b2b3715593dc285ac.tar.gz
emacs-a8b8d220b4fccaa812e85f9b2b3715593dc285ac.zip
Merge remote-tracking branch 'savannah/master' into native-comp
Diffstat (limited to 'src')
-rw-r--r--src/cmds.c1
-rw-r--r--src/dispextern.h1
-rw-r--r--src/editfns.c11
-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.m19
-rw-r--r--src/nsterm.m10
-rw-r--r--src/process.c2
-rw-r--r--src/w32common.h5
-rw-r--r--src/w32fns.c71
-rw-r--r--src/w32term.c27
-rw-r--r--src/xdisp.c3
-rw-r--r--src/xfaces.c3
-rw-r--r--src/xfns.c46
-rw-r--r--src/xterm.c47
17 files changed, 273 insertions, 51 deletions
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",
99Precisely, if point is on line I, move to the start of line I + N 99Precisely, if point is on line I, move to the start of line I + N
100\("start of line" in the logical order). 100\("start of line" in the logical order).
101If there isn't room, go as far as possible (no error). 101If there isn't room, go as far as possible (no error).
102Interactively, N is the numeric prefix argument and defaults to 1.
102 103
103Returns the count of lines left to move. If moving forward, 104Returns the count of lines left to move. If moving forward,
104that is N minus number of lines moved; if backward, N plus number 105that is N minus number of lines moved; if backward, N plus number
diff --git a/src/dispextern.h b/src/dispextern.h
index 3ad98b8344e..f4e872644db 100644
--- a/src/dispextern.h
+++ b/src/dispextern.h
@@ -1826,6 +1826,7 @@ enum face_id
1826 WINDOW_DIVIDER_FIRST_PIXEL_FACE_ID, 1826 WINDOW_DIVIDER_FIRST_PIXEL_FACE_ID,
1827 WINDOW_DIVIDER_LAST_PIXEL_FACE_ID, 1827 WINDOW_DIVIDER_LAST_PIXEL_FACE_ID,
1828 INTERNAL_BORDER_FACE_ID, 1828 INTERNAL_BORDER_FACE_ID,
1829 CHILD_FRAME_BORDER_FACE_ID,
1829 TAB_BAR_FACE_ID, 1830 TAB_BAR_FACE_ID,
1830 TAB_LINE_FACE_ID, 1831 TAB_LINE_FACE_ID,
1831 BASIC_FACE_ID_SENTINEL 1832 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/>. */
52#include "window.h" 52#include "window.h"
53#include "blockinput.h" 53#include "blockinput.h"
54 54
55#ifdef WINDOWSNT
56# include "w32common.h"
57#endif
55static void update_buffer_properties (ptrdiff_t, ptrdiff_t); 58static void update_buffer_properties (ptrdiff_t, ptrdiff_t);
56static Lisp_Object styled_format (ptrdiff_t, Lisp_Object *, bool); 59static Lisp_Object styled_format (ptrdiff_t, Lisp_Object *, bool);
57 60
@@ -121,12 +124,14 @@ init_editfns (void)
121 else if (NILP (Vuser_full_name)) 124 else if (NILP (Vuser_full_name))
122 Vuser_full_name = build_string ("unknown"); 125 Vuser_full_name = build_string ("unknown");
123 126
124#ifdef HAVE_SYS_UTSNAME_H 127#if defined HAVE_SYS_UTSNAME_H
125 { 128 {
126 struct utsname uts; 129 struct utsname uts;
127 uname (&uts); 130 uname (&uts);
128 Voperating_system_release = build_string (uts.release); 131 Voperating_system_release = build_string (uts.release);
129 } 132 }
133#elif defined WINDOWSNT
134 Voperating_system_release = build_string (w32_version_string ());
130#else 135#else
131 Voperating_system_release = Qnil; 136 Voperating_system_release = Qnil;
132#endif 137#endif
@@ -4479,7 +4484,9 @@ functions if all the text being accessed has this property. */);
4479 doc: /* The user's name, based upon the real uid only. */); 4484 doc: /* The user's name, based upon the real uid only. */);
4480 4485
4481 DEFVAR_LISP ("operating-system-release", Voperating_system_release, 4486 DEFVAR_LISP ("operating-system-release", Voperating_system_release,
4482 doc: /* The release of the operating system Emacs is running on. */); 4487 doc: /* The kernel version of the operating system on which Emacs is running.
4488The value is a string. It can also be nil if Emacs doesn't
4489know how to get the kernel version on the underlying OS. */);
4483 4490
4484 DEFVAR_BOOL ("binary-as-unsigned", 4491 DEFVAR_BOOL ("binary-as-unsigned",
4485 binary_as_unsigned, 4492 binary_as_unsigned,
diff --git a/src/emacs.c b/src/emacs.c
index c6581bba37e..acf8a17a12a 100644
--- a/src/emacs.c
+++ b/src/emacs.c
@@ -186,7 +186,8 @@ bool build_details;
186/* Name for the server started by the daemon.*/ 186/* Name for the server started by the daemon.*/
187static char *daemon_name; 187static char *daemon_name;
188 188
189/* 0 not a daemon, 1 new-style (foreground), 2 old-style (background). */ 189/* 0 not a daemon, 1 new-style (foreground), 2 old-style (background).
190 A negative value means the daemon initialization was already done. */
190int daemon_type; 191int daemon_type;
191 192
192#ifndef WINDOWSNT 193#ifndef WINDOWSNT
@@ -2387,7 +2388,10 @@ all of which are called before Emacs is actually killed. */
2387 int exit_code; 2388 int exit_code;
2388 2389
2389#ifdef HAVE_LIBSYSTEMD 2390#ifdef HAVE_LIBSYSTEMD
2390 sd_notify(0, "STOPPING=1"); 2391 /* Notify systemd we are shutting down, but only if we have notified
2392 it about startup. */
2393 if (daemon_type == -1)
2394 sd_notify(0, "STOPPING=1");
2391#endif /* HAVE_LIBSYSTEMD */ 2395#endif /* HAVE_LIBSYSTEMD */
2392 2396
2393 /* Fsignal calls emacs_abort () if it sees that waiting_for_input is 2397 /* Fsignal calls emacs_abort () if it sees that waiting_for_input is
@@ -2903,7 +2907,7 @@ from the parent process and its tty file descriptors. */)
2903 } 2907 }
2904 2908
2905 /* Set it to an invalid value so we know we've already run this function. */ 2909 /* Set it to an invalid value so we know we've already run this function. */
2906 daemon_type = -1; 2910 daemon_type = -daemon_type;
2907 2911
2908#else /* WINDOWSNT */ 2912#else /* WINDOWSNT */
2909 /* Signal the waiting emacsclient process. */ 2913 /* 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)
4599EMACS_UINT 4599EMACS_UINT
4600hash_string (char const *ptr, ptrdiff_t len) 4600hash_string (char const *ptr, ptrdiff_t len)
4601{ 4601{
4602 EMACS_UINT const *p = (EMACS_UINT const *) ptr; 4602 char const *p = ptr;
4603 EMACS_UINT const *end = (EMACS_UINT const *) (ptr + len); 4603 char const *end = ptr + len;
4604 EMACS_UINT hash = len; 4604 EMACS_UINT hash = len;
4605 /* At most 8 steps. We could reuse SXHASH_MAX_LEN, of course, 4605 /* At most 8 steps. We could reuse SXHASH_MAX_LEN, of course,
4606 * but dividing by 8 is cheaper. */ 4606 * but dividing by 8 is cheaper. */
4607 ptrdiff_t step = 1 + ((end - p) >> 3); 4607 ptrdiff_t step = sizeof hash + ((end - p) >> 3);
4608 4608
4609 /* Beware: `end` might be unaligned, so `p < end` is not always the same 4609 while (p + sizeof hash <= end)
4610 * as `p <= end - 1`. */
4611 while (p <= end - 1)
4612 { 4610 {
4613 EMACS_UINT c = *p; 4611 EMACS_UINT c;
4612 /* We presume that the compiler will replace this `memcpy` with
4613 a single load/move instruction when applicable. */
4614 memcpy (&c, p, sizeof hash);
4614 p += step; 4615 p += step;
4615 hash = sxhash_combine (hash, c); 4616 hash = sxhash_combine (hash, c);
4616 } 4617 }
4617 if (p < end) 4618 /* A few last bytes may remain (smaller than an EMACS_UINT). */
4618 { /* A few last bytes remain (smaller than an EMACS_UINT). */ 4619 /* FIXME: We could do this without a loop, but it'd require
4619 /* FIXME: We could do this without a loop, but it'd require 4620 endian-dependent code :-( */
4620 endian-dependent code :-( */ 4621 while (p < end)
4621 char const *p1 = (char const *)p; 4622 {
4622 char const *end1 = (char const *)end; 4623 unsigned char c = *p++;
4623 do 4624 hash = sxhash_combine (hash, c);
4624 {
4625 unsigned char c = *p1++;
4626 hash = sxhash_combine (hash, c);
4627 }
4628 while (p1 < end1);
4629 } 4625 }
4630 4626
4631 return hash; 4627 return hash;
diff --git a/src/frame.c b/src/frame.c
index 599c4075f88..a2167ce1e49 100644
--- a/src/frame.c
+++ b/src/frame.c
@@ -3543,6 +3543,13 @@ DEFUN ("frame-fringe-width", Ffringe_width, Sfringe_width, 0, 1, 0,
3543 return make_fixnum (FRAME_TOTAL_FRINGE_WIDTH (decode_any_frame (frame))); 3543 return make_fixnum (FRAME_TOTAL_FRINGE_WIDTH (decode_any_frame (frame)));
3544} 3544}
3545 3545
3546DEFUN ("frame-child-frame-border-width", Fframe_child_frame_border_width, Sframe_child_frame_border_width, 0, 1, 0,
3547 doc: /* Return width of FRAME's child-frame border in pixels. */)
3548 (Lisp_Object frame)
3549{
3550 return make_fixnum (FRAME_CHILD_FRAME_BORDER_WIDTH (decode_any_frame (frame)));
3551}
3552
3546DEFUN ("frame-internal-border-width", Fframe_internal_border_width, Sframe_internal_border_width, 0, 1, 0, 3553DEFUN ("frame-internal-border-width", Fframe_internal_border_width, Sframe_internal_border_width, 0, 1, 0,
3547 doc: /* Return width of FRAME's internal border in pixels. */) 3554 doc: /* Return width of FRAME's internal border in pixels. */)
3548 (Lisp_Object frame) 3555 (Lisp_Object frame)
@@ -3759,6 +3766,7 @@ static const struct frame_parm_table frame_parms[] =
3759 {"foreground-color", -1}, 3766 {"foreground-color", -1},
3760 {"icon-name", SYMBOL_INDEX (Qicon_name)}, 3767 {"icon-name", SYMBOL_INDEX (Qicon_name)},
3761 {"icon-type", SYMBOL_INDEX (Qicon_type)}, 3768 {"icon-type", SYMBOL_INDEX (Qicon_type)},
3769 {"child-frame-border-width", SYMBOL_INDEX (Qchild_frame_border_width)},
3762 {"internal-border-width", SYMBOL_INDEX (Qinternal_border_width)}, 3770 {"internal-border-width", SYMBOL_INDEX (Qinternal_border_width)},
3763 {"right-divider-width", SYMBOL_INDEX (Qright_divider_width)}, 3771 {"right-divider-width", SYMBOL_INDEX (Qright_divider_width)},
3764 {"bottom-divider-width", SYMBOL_INDEX (Qbottom_divider_width)}, 3772 {"bottom-divider-width", SYMBOL_INDEX (Qbottom_divider_width)},
@@ -4302,6 +4310,8 @@ gui_report_frame_params (struct frame *f, Lisp_Object *alistptr)
4302 4310
4303 store_in_alist (alistptr, Qborder_width, 4311 store_in_alist (alistptr, Qborder_width,
4304 make_fixnum (f->border_width)); 4312 make_fixnum (f->border_width));
4313 store_in_alist (alistptr, Qchild_frame_border_width,
4314 make_fixnum (FRAME_CHILD_FRAME_BORDER_WIDTH (f)));
4305 store_in_alist (alistptr, Qinternal_border_width, 4315 store_in_alist (alistptr, Qinternal_border_width,
4306 make_fixnum (FRAME_INTERNAL_BORDER_WIDTH (f))); 4316 make_fixnum (FRAME_INTERNAL_BORDER_WIDTH (f)));
4307 store_in_alist (alistptr, Qright_divider_width, 4317 store_in_alist (alistptr, Qright_divider_width,
@@ -5999,6 +6009,7 @@ syms_of_frame (void)
5999 DEFSYM (Qhorizontal_scroll_bars, "horizontal-scroll-bars"); 6009 DEFSYM (Qhorizontal_scroll_bars, "horizontal-scroll-bars");
6000 DEFSYM (Qicon_name, "icon-name"); 6010 DEFSYM (Qicon_name, "icon-name");
6001 DEFSYM (Qicon_type, "icon-type"); 6011 DEFSYM (Qicon_type, "icon-type");
6012 DEFSYM (Qchild_frame_border_width, "child-frame-border-width");
6002 DEFSYM (Qinternal_border_width, "internal-border-width"); 6013 DEFSYM (Qinternal_border_width, "internal-border-width");
6003 DEFSYM (Qleft_fringe, "left-fringe"); 6014 DEFSYM (Qleft_fringe, "left-fringe");
6004 DEFSYM (Qline_spacing, "line-spacing"); 6015 DEFSYM (Qline_spacing, "line-spacing");
@@ -6423,6 +6434,7 @@ iconify the top level frame instead. */);
6423 defsubr (&Sscroll_bar_width); 6434 defsubr (&Sscroll_bar_width);
6424 defsubr (&Sscroll_bar_height); 6435 defsubr (&Sscroll_bar_height);
6425 defsubr (&Sfringe_width); 6436 defsubr (&Sfringe_width);
6437 defsubr (&Sframe_child_frame_border_width);
6426 defsubr (&Sframe_internal_border_width); 6438 defsubr (&Sframe_internal_border_width);
6427 defsubr (&Sright_divider_width); 6439 defsubr (&Sright_divider_width);
6428 defsubr (&Sbottom_divider_width); 6440 defsubr (&Sbottom_divider_width);
diff --git a/src/frame.h b/src/frame.h
index 8cf41dc0046..9b0852c7b9c 100644
--- a/src/frame.h
+++ b/src/frame.h
@@ -534,6 +534,10 @@ struct frame
534 /* Border width of the frame window as known by the (X) window system. */ 534 /* Border width of the frame window as known by the (X) window system. */
535 int border_width; 535 int border_width;
536 536
537 /* Width of child frames' internal border. Acts as
538 internal_border_width for child frames. */
539 int child_frame_border_width;
540
537 /* Width of the internal border. This is a line of background color 541 /* Width of the internal border. This is a line of background color
538 just inside the window's border. When the frame is selected, 542 just inside the window's border. When the frame is selected,
539 a highlighting is displayed inside the internal border. */ 543 a highlighting is displayed inside the internal border. */
@@ -1432,11 +1436,27 @@ FRAME_TOTAL_FRINGE_WIDTH (struct frame *f)
1432 return FRAME_LEFT_FRINGE_WIDTH (f) + FRAME_RIGHT_FRINGE_WIDTH (f); 1436 return FRAME_LEFT_FRINGE_WIDTH (f) + FRAME_RIGHT_FRINGE_WIDTH (f);
1433} 1437}
1434 1438
1435/* Pixel-width of internal border lines. */ 1439INLINE int
1440FRAME_CHILD_FRAME_BORDER_WIDTH (struct frame *f)
1441{
1442 return frame_dimension (f->child_frame_border_width);
1443}
1444
1445/* Pixel-width of internal border. Uses child_frame_border_width for
1446 child frames if possible, and falls back on internal_border_width
1447 otherwise. */
1436INLINE int 1448INLINE int
1437FRAME_INTERNAL_BORDER_WIDTH (struct frame *f) 1449FRAME_INTERNAL_BORDER_WIDTH (struct frame *f)
1438{ 1450{
1451#ifdef HAVE_WINDOW_SYSTEM
1452 return FRAME_PARENT_FRAME(f)
1453 ? (f->child_frame_border_width
1454 ? FRAME_CHILD_FRAME_BORDER_WIDTH(f)
1455 : frame_dimension (f->internal_border_width))
1456 : frame_dimension (f->internal_border_width);
1457#else
1439 return frame_dimension (f->internal_border_width); 1458 return frame_dimension (f->internal_border_width);
1459#endif
1440} 1460}
1441 1461
1442/* Pixel-size of window divider lines. */ 1462/* Pixel-size of window divider lines. */
diff --git a/src/nsfns.m b/src/nsfns.m
index 24ea7d7f63b..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)
687 } 687 }
688} 688}
689 689
690static void
691ns_set_child_frame_border_width (struct frame *f, Lisp_Object arg, Lisp_Object oldval)
692{
693 int old_width = FRAME_CHILD_FRAME_BORDER_WIDTH (f);
694 int new_width = check_int_nonnegative (arg);
695
696 if (new_width == old_width)
697 return;
698 f->child_frame_border_width = new_width;
699
700 if (FRAME_NATIVE_WINDOW (f) != 0)
701 adjust_frame_size (f, -1, -1, 3, 0, Qchild_frame_border_width);
702
703 SET_FRAME_GARBAGED (f);
704}
690 705
691static void 706static void
692ns_set_internal_border_width (struct frame *f, Lisp_Object arg, Lisp_Object oldval) 707ns_set_internal_border_width (struct frame *f, Lisp_Object arg, Lisp_Object oldval)
@@ -912,6 +927,7 @@ frame_parm_handler ns_frame_parm_handlers[] =
912 ns_set_foreground_color, 927 ns_set_foreground_color,
913 ns_set_icon_name, 928 ns_set_icon_name,
914 ns_set_icon_type, 929 ns_set_icon_type,
930 ns_set_child_frame_border_width,
915 ns_set_internal_border_width, 931 ns_set_internal_border_width,
916 gui_set_right_divider_width, /* generic OK */ 932 gui_set_right_divider_width, /* generic OK */
917 gui_set_bottom_divider_width, /* generic OK */ 933 gui_set_bottom_divider_width, /* generic OK */
@@ -1197,6 +1213,9 @@ DEFUN ("x-create-frame", Fx_create_frame, Sx_create_frame,
1197 gui_default_parameter (f, parms, Qinternal_border_width, make_fixnum (2), 1213 gui_default_parameter (f, parms, Qinternal_border_width, make_fixnum (2),
1198 "internalBorderWidth", "InternalBorderWidth", 1214 "internalBorderWidth", "InternalBorderWidth",
1199 RES_TYPE_NUMBER); 1215 RES_TYPE_NUMBER);
1216 gui_default_parameter (f, parms, Qchild_frame_border_width, make_fixnum (2),
1217 "childFrameBorderWidth", "childFrameBorderWidth",
1218 RES_TYPE_NUMBER);
1200 gui_default_parameter (f, parms, Qright_divider_width, make_fixnum (0), 1219 gui_default_parameter (f, parms, Qright_divider_width, make_fixnum (0),
1201 NULL, NULL, RES_TYPE_NUMBER); 1220 NULL, NULL, RES_TYPE_NUMBER);
1202 gui_default_parameter (f, parms, Qbottom_divider_width, make_fixnum (0), 1221 gui_default_parameter (f, parms, Qbottom_divider_width, make_fixnum (0),
diff --git a/src/nsterm.m b/src/nsterm.m
index df3934c5c34..1b2328628ee 100644
--- a/src/nsterm.m
+++ b/src/nsterm.m
@@ -3037,9 +3037,13 @@ ns_clear_under_internal_border (struct frame *f)
3037 NSRectEdge edge[] = {NSMinXEdge, NSMinYEdge, NSMaxXEdge, NSMaxYEdge}; 3037 NSRectEdge edge[] = {NSMinXEdge, NSMinYEdge, NSMaxXEdge, NSMaxYEdge};
3038 3038
3039 int face_id = 3039 int face_id =
3040 !NILP (Vface_remapping_alist) 3040 (FRAME_PARENT_FRAME (f)
3041 ? lookup_basic_face (NULL, f, INTERNAL_BORDER_FACE_ID) 3041 ? (!NILP (Vface_remapping_alist)
3042 : INTERNAL_BORDER_FACE_ID; 3042 ? lookup_basic_face (NULL, f, CHILD_FRAME_BORDER_FACE_ID)
3043 : CHILD_FRAME_BORDER_FACE_ID)
3044 : (!NILP (Vface_remapping_alist)
3045 ? lookup_basic_face (NULL, f, INTERNAL_BORDER_FACE_ID)
3046 : INTERNAL_BORDER_FACE_ID));
3043 struct face *face = FACE_FROM_ID_OR_NULL (f, face_id); 3047 struct face *face = FACE_FROM_ID_OR_NULL (f, face_id);
3044 3048
3045 if (!face) 3049 if (!face)
diff --git a/src/process.c b/src/process.c
index 1df4ed9ce03..3beb9cf7146 100644
--- a/src/process.c
+++ b/src/process.c
@@ -7217,7 +7217,7 @@ child_signal_read (int fd, void *data)
7217 eassert (0 <= fd); 7217 eassert (0 <= fd);
7218 eassert (fd == child_signal_read_fd); 7218 eassert (fd == child_signal_read_fd);
7219 char dummy; 7219 char dummy;
7220 if (emacs_read (fd, &dummy, 1) < 0) 7220 if (emacs_read (fd, &dummy, 1) < 0 && errno != EAGAIN)
7221 emacs_perror ("reading from child signal FD"); 7221 emacs_perror ("reading from child signal FD");
7222} 7222}
7223#endif /* !WINDOWSNT */ 7223#endif /* !WINDOWSNT */
diff --git a/src/w32common.h b/src/w32common.h
index 90e88876aba..cbe05c5d8d1 100644
--- a/src/w32common.h
+++ b/src/w32common.h
@@ -50,6 +50,11 @@ extern int os_subtype;
50/* Cache system info, e.g., the NT page size. */ 50/* Cache system info, e.g., the NT page size. */
51extern void cache_system_info (void); 51extern void cache_system_info (void);
52 52
53#ifdef WINDOWSNT
54/* Return a static buffer with the MS-Windows version string. */
55extern char * w32_version_string (void);
56#endif
57
53typedef void (* VOIDFNPTR) (void); 58typedef void (* VOIDFNPTR) (void);
54 59
55/* Load a function address from a DLL. Cast the result via VOIDFNPTR 60/* 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)
1519 int width = FRAME_PIXEL_WIDTH (f); 1519 int width = FRAME_PIXEL_WIDTH (f);
1520 int height = FRAME_PIXEL_HEIGHT (f); 1520 int height = FRAME_PIXEL_HEIGHT (f);
1521 int face_id = 1521 int face_id =
1522 !NILP (Vface_remapping_alist) 1522 (FRAME_PARENT_FRAME (f)
1523 ? lookup_basic_face (NULL, f, INTERNAL_BORDER_FACE_ID) 1523 ? (!NILP (Vface_remapping_alist)
1524 : INTERNAL_BORDER_FACE_ID; 1524 ? lookup_basic_face (NULL, f, CHILD_FRAME_BORDER_FACE_ID)
1525 : CHILD_FRAME_BORDER_FACE_ID)
1526 : (!NILP (Vface_remapping_alist)
1527 ? lookup_basic_face (NULL, f, INTERNAL_BORDER_FACE_ID)
1528 : INTERNAL_BORDER_FACE_ID));
1525 struct face *face = FACE_FROM_ID_OR_NULL (f, face_id); 1529 struct face *face = FACE_FROM_ID_OR_NULL (f, face_id);
1526 1530
1527 block_input (); 1531 block_input ();
@@ -1548,6 +1552,32 @@ w32_clear_under_internal_border (struct frame *f)
1548 } 1552 }
1549} 1553}
1550 1554
1555/**
1556 * w32_set_child_frame_border_width:
1557 *
1558 * Set width of child frame F's internal border to ARG pixels.
1559 * ARG < 0 is treated like ARG = 0.
1560 */
1561static void
1562w32_set_child_frame_border_width (struct frame *f, Lisp_Object arg, Lisp_Object oldval)
1563{
1564 int argval = check_integer_range (arg, INT_MIN, INT_MAX);
1565 int border = max (argval, 0);
1566
1567 if (border != FRAME_CHILD_FRAME_BORDER_WIDTH (f))
1568 {
1569 f->child_frame_border_width = border;
1570
1571 if (FRAME_NATIVE_WINDOW (f) != 0)
1572 {
1573 adjust_frame_size (f, -1, -1, 3, false, Qchild_frame_border_width);
1574
1575 if (FRAME_VISIBLE_P (f))
1576 w32_clear_under_internal_border (f);
1577 }
1578 }
1579}
1580
1551 1581
1552/** 1582/**
1553 * w32_set_internal_border_width: 1583 * w32_set_internal_border_width:
@@ -5873,6 +5903,28 @@ DEFUN ("x-create-frame", Fx_create_frame, Sx_create_frame,
5873 parameters); 5903 parameters);
5874 } 5904 }
5875 5905
5906 /* Same for child frames. */
5907 if (NILP (Fassq (Qchild_frame_border_width, parameters)))
5908 {
5909 Lisp_Object value;
5910
5911 value = gui_display_get_arg (dpyinfo, parameters, Qchild_frame_border_width,
5912 "childFrameBorderWidth", "childFrameBorderWidth",
5913 RES_TYPE_NUMBER);
5914 if (! EQ (value, Qunbound))
5915 parameters = Fcons (Fcons (Qchild_frame_border_width, value),
5916 parameters);
5917
5918 }
5919
5920 gui_default_parameter (f, parameters, Qchild_frame_border_width,
5921#ifdef USE_GTK /* We used to impose 0 in xg_create_frame_widgets. */
5922 make_fixnum (0),
5923#else
5924 make_fixnum (1),
5925#endif
5926 "childFrameBorderWidth", "childFrameBorderWidth",
5927 RES_TYPE_NUMBER);
5876 gui_default_parameter (f, parameters, Qinternal_border_width, make_fixnum (0), 5928 gui_default_parameter (f, parameters, Qinternal_border_width, make_fixnum (0),
5877 "internalBorderWidth", "InternalBorder", RES_TYPE_NUMBER); 5929 "internalBorderWidth", "InternalBorder", RES_TYPE_NUMBER);
5878 gui_default_parameter (f, parameters, Qright_divider_width, make_fixnum (0), 5930 gui_default_parameter (f, parameters, Qright_divider_width, make_fixnum (0),
@@ -9428,6 +9480,18 @@ cache_system_info (void)
9428 w32_num_mouse_buttons = GetSystemMetrics (SM_CMOUSEBUTTONS); 9480 w32_num_mouse_buttons = GetSystemMetrics (SM_CMOUSEBUTTONS);
9429} 9481}
9430 9482
9483#ifdef WINDOWSNT
9484char *
9485w32_version_string (void)
9486{
9487 /* NNN.NNN.NNNNNNNNNN */
9488 static char version_string[3 + 1 + 3 + 1 + 10 + 1];
9489 _snprintf (version_string, sizeof version_string, "%d.%d.%d",
9490 w32_major_version, w32_minor_version, w32_build_number);
9491 return version_string;
9492}
9493#endif
9494
9431#ifdef EMACSDEBUG 9495#ifdef EMACSDEBUG
9432void 9496void
9433_DebPrint (const char *fmt, ...) 9497_DebPrint (const char *fmt, ...)
@@ -10232,6 +10296,7 @@ frame_parm_handler w32_frame_parm_handlers[] =
10232 w32_set_foreground_color, 10296 w32_set_foreground_color,
10233 w32_set_icon_name, 10297 w32_set_icon_name,
10234 w32_set_icon_type, 10298 w32_set_icon_type,
10299 w32_set_child_frame_border_width,
10235 w32_set_internal_border_width, 10300 w32_set_internal_border_width,
10236 gui_set_right_divider_width, 10301 gui_set_right_divider_width,
10237 gui_set_bottom_divider_width, 10302 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)
2404 else if (!s->background_filled_p) 2404 else if (!s->background_filled_p)
2405 { 2405 {
2406 int background_width = s->background_width; 2406 int background_width = s->background_width;
2407 int x = s->x, left_x = window_box_left_offset (s->w, TEXT_AREA); 2407 int x = s->x, text_left_x = window_box_left_offset (s->w, TEXT_AREA);
2408 2408
2409 /* Don't draw into left margin, fringe or scrollbar area 2409 /* Don't draw into left fringe or scrollbar area except for
2410 except for header line and mode line. */ 2410 header line and mode line. */
2411 if (x < left_x && !s->row->mode_line_p) 2411 if (x < text_left_x && !s->row->mode_line_p)
2412 { 2412 {
2413 background_width -= left_x - x; 2413 int left_x = WINDOW_LEFT_SCROLL_BAR_AREA_WIDTH (s->w);
2414 x = left_x; 2414 int right_x = text_left_x;
2415
2416 if (WINDOW_HAS_FRINGES_OUTSIDE_MARGINS (s->w))
2417 left_x += WINDOW_LEFT_FRINGE_WIDTH (s->w);
2418 else
2419 right_x -= WINDOW_LEFT_FRINGE_WIDTH (s->w);
2420
2421 /* Adjust X and BACKGROUND_WIDTH to fit inside the space
2422 between LEFT_X and RIGHT_X. */
2423 if (x < left_x)
2424 {
2425 background_width -= left_x - x;
2426 x = left_x;
2427 }
2428 if (x + background_width > right_x)
2429 background_width = right_x - x;
2415 } 2430 }
2416 if (background_width > 0) 2431 if (background_width > 0)
2417 w32_draw_glyph_string_bg_rect (s, x, s->y, background_width, s->height); 2432 w32_draw_glyph_string_bg_rect (s, x, s->y, background_width, s->height);
diff --git a/src/xdisp.c b/src/xdisp.c
index e1e4ff41365..11b9e1becfd 100644
--- a/src/xdisp.c
+++ b/src/xdisp.c
@@ -29813,7 +29813,8 @@ produce_stretch_glyph (struct it *it)
29813#endif /* HAVE_WINDOW_SYSTEM */ 29813#endif /* HAVE_WINDOW_SYSTEM */
29814 height = 1; 29814 height = 1;
29815 29815
29816 if (width > 0 && it->line_wrap != TRUNCATE 29816 if (width > 0
29817 && it->area == TEXT_AREA && it->line_wrap != TRUNCATE
29817 && it->current_x + width > it->last_visible_x) 29818 && it->current_x + width > it->last_visible_x)
29818 { 29819 {
29819 width = it->last_visible_x - it->current_x; 29820 width = it->last_visible_x - it->current_x;
diff --git a/src/xfaces.c b/src/xfaces.c
index 258b365eda3..12087138e51 100644
--- a/src/xfaces.c
+++ b/src/xfaces.c
@@ -4914,6 +4914,7 @@ lookup_basic_face (struct window *w, struct frame *f, int face_id)
4914 case WINDOW_DIVIDER_FIRST_PIXEL_FACE_ID: name = Qwindow_divider_first_pixel; break; 4914 case WINDOW_DIVIDER_FIRST_PIXEL_FACE_ID: name = Qwindow_divider_first_pixel; break;
4915 case WINDOW_DIVIDER_LAST_PIXEL_FACE_ID: name = Qwindow_divider_last_pixel; break; 4915 case WINDOW_DIVIDER_LAST_PIXEL_FACE_ID: name = Qwindow_divider_last_pixel; break;
4916 case INTERNAL_BORDER_FACE_ID: name = Qinternal_border; break; 4916 case INTERNAL_BORDER_FACE_ID: name = Qinternal_border; break;
4917 case CHILD_FRAME_BORDER_FACE_ID: name = Qchild_frame_border; break;
4917 4918
4918 default: 4919 default:
4919 emacs_abort (); /* the caller is supposed to pass us a basic face id */ 4920 emacs_abort (); /* the caller is supposed to pass us a basic face id */
@@ -5620,6 +5621,7 @@ realize_basic_faces (struct frame *f)
5620 realize_named_face (f, Qwindow_divider_last_pixel, 5621 realize_named_face (f, Qwindow_divider_last_pixel,
5621 WINDOW_DIVIDER_LAST_PIXEL_FACE_ID); 5622 WINDOW_DIVIDER_LAST_PIXEL_FACE_ID);
5622 realize_named_face (f, Qinternal_border, INTERNAL_BORDER_FACE_ID); 5623 realize_named_face (f, Qinternal_border, INTERNAL_BORDER_FACE_ID);
5624 realize_named_face (f, Qchild_frame_border, CHILD_FRAME_BORDER_FACE_ID);
5623 realize_named_face (f, Qtab_bar, TAB_BAR_FACE_ID); 5625 realize_named_face (f, Qtab_bar, TAB_BAR_FACE_ID);
5624 realize_named_face (f, Qtab_line, TAB_LINE_FACE_ID); 5626 realize_named_face (f, Qtab_line, TAB_LINE_FACE_ID);
5625 5627
@@ -6973,6 +6975,7 @@ syms_of_xfaces (void)
6973 DEFSYM (Qwindow_divider_first_pixel, "window-divider-first-pixel"); 6975 DEFSYM (Qwindow_divider_first_pixel, "window-divider-first-pixel");
6974 DEFSYM (Qwindow_divider_last_pixel, "window-divider-last-pixel"); 6976 DEFSYM (Qwindow_divider_last_pixel, "window-divider-last-pixel");
6975 DEFSYM (Qinternal_border, "internal-border"); 6977 DEFSYM (Qinternal_border, "internal-border");
6978 DEFSYM (Qchild_frame_border, "child-frame-border");
6976 6979
6977 /* TTY color-related functions (defined in tty-colors.el). */ 6980 /* TTY color-related functions (defined in tty-colors.el). */
6978 DEFSYM (Qtty_color_desc, "tty-color-desc"); 6981 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)
1800#endif /* USE_GTK */ 1800#endif /* USE_GTK */
1801} 1801}
1802 1802
1803static void
1804x_set_child_frame_border_width (struct frame *f, Lisp_Object arg, Lisp_Object oldval)
1805{
1806 int border = check_int_nonnegative (arg);
1807
1808 if (border != FRAME_CHILD_FRAME_BORDER_WIDTH (f))
1809 {
1810 f->child_frame_border_width = border;
1811
1812#ifdef USE_X_TOOLKIT
1813 if (FRAME_X_OUTPUT (f)->edit_widget)
1814 widget_store_internal_border (FRAME_X_OUTPUT (f)->edit_widget);
1815#endif
1816
1817 if (FRAME_X_WINDOW (f))
1818 {
1819 adjust_frame_size (f, -1, -1, 3, false, Qchild_frame_border_width);
1820 x_clear_under_internal_border (f);
1821 }
1822 }
1823
1824}
1803 1825
1804static void 1826static void
1805x_set_internal_border_width (struct frame *f, Lisp_Object arg, Lisp_Object oldval) 1827x_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. */)
3897 parms = Fcons (Fcons (Qinternal_border_width, value), 3919 parms = Fcons (Fcons (Qinternal_border_width, value),
3898 parms); 3920 parms);
3899 } 3921 }
3922
3923 /* Same for child frames. */
3924 if (NILP (Fassq (Qchild_frame_border_width, parms)))
3925 {
3926 Lisp_Object value;
3927
3928 value = gui_display_get_arg (dpyinfo, parms, Qchild_frame_border_width,
3929 "childFrameBorderWidth", "childFrameBorderWidth",
3930 RES_TYPE_NUMBER);
3931 if (! EQ (value, Qunbound))
3932 parms = Fcons (Fcons (Qchild_frame_border_width, value),
3933 parms);
3934
3935 }
3936
3937 gui_default_parameter (f, parms, Qchild_frame_border_width,
3938#ifdef USE_GTK /* We used to impose 0 in xg_create_frame_widgets. */
3939 make_fixnum (0),
3940#else
3941 make_fixnum (1),
3942#endif
3943 "childFrameBorderWidth", "childFrameBorderWidth",
3944 RES_TYPE_NUMBER);
3900 gui_default_parameter (f, parms, Qinternal_border_width, 3945 gui_default_parameter (f, parms, Qinternal_border_width,
3901#ifdef USE_GTK /* We used to impose 0 in xg_create_frame_widgets. */ 3946#ifdef USE_GTK /* We used to impose 0 in xg_create_frame_widgets. */
3902 make_fixnum (0), 3947 make_fixnum (0),
@@ -7762,6 +7807,7 @@ frame_parm_handler x_frame_parm_handlers[] =
7762 x_set_foreground_color, 7807 x_set_foreground_color,
7763 x_set_icon_name, 7808 x_set_icon_name,
7764 x_set_icon_type, 7809 x_set_icon_type,
7810 x_set_child_frame_border_width,
7765 x_set_internal_border_width, 7811 x_set_internal_border_width,
7766 gui_set_right_divider_width, 7812 gui_set_right_divider_width,
7767 gui_set_bottom_divider_width, 7813 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)
1293 int height = FRAME_PIXEL_HEIGHT (f); 1293 int height = FRAME_PIXEL_HEIGHT (f);
1294 int margin = FRAME_TOP_MARGIN_HEIGHT (f); 1294 int margin = FRAME_TOP_MARGIN_HEIGHT (f);
1295 int face_id = 1295 int face_id =
1296 !NILP (Vface_remapping_alist) 1296 (FRAME_PARENT_FRAME (f)
1297 ? lookup_basic_face (NULL, f, INTERNAL_BORDER_FACE_ID) 1297 ? (!NILP (Vface_remapping_alist)
1298 : INTERNAL_BORDER_FACE_ID; 1298 ? lookup_basic_face (NULL, f, CHILD_FRAME_BORDER_FACE_ID)
1299 : CHILD_FRAME_BORDER_FACE_ID)
1300 : (!NILP (Vface_remapping_alist)
1301 ? lookup_basic_face (NULL, f, INTERNAL_BORDER_FACE_ID)
1302 : INTERNAL_BORDER_FACE_ID));
1299 struct face *face = FACE_FROM_ID_OR_NULL (f, face_id); 1303 struct face *face = FACE_FROM_ID_OR_NULL (f, face_id);
1300 1304
1301 block_input (); 1305 block_input ();
@@ -1360,9 +1364,13 @@ x_after_update_window_line (struct window *w, struct glyph_row *desired_row)
1360 { 1364 {
1361 int y = WINDOW_TO_FRAME_PIXEL_Y (w, max (0, desired_row->y)); 1365 int y = WINDOW_TO_FRAME_PIXEL_Y (w, max (0, desired_row->y));
1362 int face_id = 1366 int face_id =
1363 !NILP (Vface_remapping_alist) 1367 (FRAME_PARENT_FRAME (f)
1364 ? lookup_basic_face (NULL, f, INTERNAL_BORDER_FACE_ID) 1368 ? (!NILP (Vface_remapping_alist)
1365 : INTERNAL_BORDER_FACE_ID; 1369 ? lookup_basic_face (NULL, f, CHILD_FRAME_BORDER_FACE_ID)
1370 : CHILD_FRAME_BORDER_FACE_ID)
1371 : (!NILP (Vface_remapping_alist)
1372 ? lookup_basic_face (NULL, f, INTERNAL_BORDER_FACE_ID)
1373 : INTERNAL_BORDER_FACE_ID));
1366 struct face *face = FACE_FROM_ID_OR_NULL (f, face_id); 1374 struct face *face = FACE_FROM_ID_OR_NULL (f, face_id);
1367 1375
1368 block_input (); 1376 block_input ();
@@ -3577,14 +3585,29 @@ x_draw_stretch_glyph_string (struct glyph_string *s)
3577 else if (!s->background_filled_p) 3585 else if (!s->background_filled_p)
3578 { 3586 {
3579 int background_width = s->background_width; 3587 int background_width = s->background_width;
3580 int x = s->x, left_x = window_box_left_offset (s->w, TEXT_AREA); 3588 int x = s->x, text_left_x = window_box_left_offset (s->w, TEXT_AREA);
3581 3589
3582 /* Don't draw into left margin, fringe or scrollbar area 3590 /* Don't draw into left fringe or scrollbar area except for
3583 except for header line and mode line. */ 3591 header line and mode line. */
3584 if (x < left_x && !s->row->mode_line_p) 3592 if (x < text_left_x && !s->row->mode_line_p)
3585 { 3593 {
3586 background_width -= left_x - x; 3594 int left_x = WINDOW_LEFT_SCROLL_BAR_AREA_WIDTH (s->w);
3587 x = left_x; 3595 int right_x = text_left_x;
3596
3597 if (WINDOW_HAS_FRINGES_OUTSIDE_MARGINS (s->w))
3598 left_x += WINDOW_LEFT_FRINGE_WIDTH (s->w);
3599 else
3600 right_x -= WINDOW_LEFT_FRINGE_WIDTH (s->w);
3601
3602 /* Adjust X and BACKGROUND_WIDTH to fit inside the space
3603 between LEFT_X and RIGHT_X. */
3604 if (x < left_x)
3605 {
3606 background_width -= left_x - x;
3607 x = left_x;
3608 }
3609 if (x + background_width > right_x)
3610 background_width = right_x - x;
3588 } 3611 }
3589 if (background_width > 0) 3612 if (background_width > 0)
3590 x_draw_glyph_string_bg_rect (s, x, s->y, background_width, s->height); 3613 x_draw_glyph_string_bg_rect (s, x, s->y, background_width, s->height);