diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/alloc.c | 6 | ||||
-rw-r--r-- | src/cmds.c | 1 | ||||
-rw-r--r-- | src/conf_post.h | 4 | ||||
-rw-r--r-- | src/dispextern.h | 1 | ||||
-rw-r--r-- | src/editfns.c | 11 | ||||
-rw-r--r-- | src/emacs-module.h.in | 4 | ||||
-rw-r--r-- | src/emacs.c | 10 | ||||
-rw-r--r-- | src/fns.c | 34 | ||||
-rw-r--r-- | src/frame.c | 12 | ||||
-rw-r--r-- | src/frame.h | 22 | ||||
-rw-r--r-- | src/nsfns.m | 20 | ||||
-rw-r--r-- | src/nsmenu.m | 1 | ||||
-rw-r--r-- | src/nsterm.m | 41 | ||||
-rw-r--r-- | src/process.c | 31 | ||||
-rw-r--r-- | src/term.c | 39 | ||||
-rw-r--r-- | src/w32common.h | 5 | ||||
-rw-r--r-- | src/w32fns.c | 71 | ||||
-rw-r--r-- | src/w32term.c | 27 | ||||
-rw-r--r-- | src/window.c | 2 | ||||
-rw-r--r-- | src/xdisp.c | 6 | ||||
-rw-r--r-- | src/xfaces.c | 3 | ||||
-rw-r--r-- | src/xfns.c | 46 | ||||
-rw-r--r-- | src/xterm.c | 47 |
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); |