aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorAndrea Corallo2021-01-24 21:05:33 +0100
committerAndrea Corallo2021-01-24 21:05:33 +0100
commitb8d3ae78c54db7c7bb65d367a80f9be3d8744c48 (patch)
tree982f190d1dd79685c43a9829dd66e6a7cbbd0c67 /src
parent0ffb3dfaa483b0c5cf1f7f367efcb5e9c041ab53 (diff)
parente5aaa1251cfb9d6d18682a5eda137a2e12ca4213 (diff)
downloademacs-b8d3ae78c54db7c7bb65d367a80f9be3d8744c48.tar.gz
emacs-b8d3ae78c54db7c7bb65d367a80f9be3d8744c48.zip
Merge remote-tracking branch 'savannah/master' into native-comp
Diffstat (limited to 'src')
-rw-r--r--src/alloc.c6
-rw-r--r--src/conf_post.h4
-rw-r--r--src/emacs-module.h.in4
-rw-r--r--src/frame.c59
-rw-r--r--src/nsfns.m1
-rw-r--r--src/nsmenu.m1
-rw-r--r--src/nsselect.m15
-rw-r--r--src/nsterm.h9
-rw-r--r--src/nsterm.m52
-rw-r--r--src/process.c130
-rw-r--r--src/term.c43
-rw-r--r--src/termhooks.h2
-rw-r--r--src/window.c2
-rw-r--r--src/xdisp.c6
14 files changed, 263 insertions, 71 deletions
diff --git a/src/alloc.c b/src/alloc.c
index 350fec25a02..0ed5b9346f6 100644
--- a/src/alloc.c
+++ b/src/alloc.c
@@ -6122,11 +6122,13 @@ garbage_collect (void)
6122 6122
6123 gc_in_progress = 0; 6123 gc_in_progress = 0;
6124 6124
6125 unblock_input ();
6126
6127 consing_until_gc = gc_threshold 6125 consing_until_gc = gc_threshold
6128 = consing_threshold (gc_cons_threshold, Vgc_cons_percentage, 0); 6126 = consing_threshold (gc_cons_threshold, Vgc_cons_percentage, 0);
6129 6127
6128 /* Unblock *after* re-setting `consing_until_gc` in case `unblock_input`
6129 signals an error (see bug#43389). */
6130 unblock_input ();
6131
6130 if (garbage_collection_messages && NILP (Vmemory_full)) 6132 if (garbage_collection_messages && NILP (Vmemory_full))
6131 { 6133 {
6132 if (message_p || minibuf_level > 0) 6134 if (message_p || minibuf_level > 0)
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;
71 It is used only on arguments like cleanup that are handled here. 71 It is used only on arguments like cleanup that are handled here.
72 This macro should be used only in #if expressions, as Oracle 72 This macro should be used only in #if expressions, as Oracle
73 Studio 12.5's __has_attribute does not work in plain code. */ 73 Studio 12.5's __has_attribute does not work in plain code. */
74#ifdef __has_attribute 74#if (defined __has_attribute \
75 && (!defined __clang_minor__ \
76 || 3 < __clang_major__ + (5 <= __clang_minor__)))
75# define HAS_ATTRIBUTE(a) __has_attribute (__##a##__) 77# define HAS_ATTRIBUTE(a) __has_attribute (__##a##__)
76#else 78#else
77# define HAS_ATTRIBUTE(a) HAS_ATTR_##a 79# define HAS_ATTRIBUTE(a) HAS_ATTR_##a
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.
51#if 3 < __GNUC__ + (3 <= __GNUC_MINOR__) 51#if 3 < __GNUC__ + (3 <= __GNUC_MINOR__)
52# define EMACS_ATTRIBUTE_NONNULL(...) \ 52# define EMACS_ATTRIBUTE_NONNULL(...) \
53 __attribute__ ((__nonnull__ (__VA_ARGS__))) 53 __attribute__ ((__nonnull__ (__VA_ARGS__)))
54#elif defined __has_attribute 54#elif (defined __has_attribute \
55 && (!defined __clang_minor__ \
56 || 3 < __clang_major__ + (5 <= __clang_minor__)))
55# if __has_attribute (__nonnull__) 57# if __has_attribute (__nonnull__)
56# define EMACS_ATTRIBUTE_NONNULL(...) \ 58# define EMACS_ATTRIBUTE_NONNULL(...) \
57 __attribute__ ((__nonnull__ (__VA_ARGS__))) 59 __attribute__ ((__nonnull__ (__VA_ARGS__)))
diff --git a/src/frame.c b/src/frame.c
index 45ee96e9620..599c4075f88 100644
--- a/src/frame.c
+++ b/src/frame.c
@@ -2572,23 +2572,30 @@ before calling this function on it, like this.
2572 int yval = check_integer_range (y, INT_MIN, INT_MAX); 2572 int yval = check_integer_range (y, INT_MIN, INT_MAX);
2573 2573
2574 /* I think this should be done with a hook. */ 2574 /* I think this should be done with a hook. */
2575#ifdef HAVE_WINDOW_SYSTEM
2576 if (FRAME_WINDOW_P (XFRAME (frame))) 2575 if (FRAME_WINDOW_P (XFRAME (frame)))
2577 /* Warping the mouse will cause enternotify and focus events. */ 2576 {
2578 frame_set_mouse_position (XFRAME (frame), xval, yval); 2577#ifdef HAVE_WINDOW_SYSTEM
2579#elif defined MSDOS 2578 /* Warping the mouse will cause enternotify and focus events. */
2580 if (FRAME_MSDOS_P (XFRAME (frame))) 2579 frame_set_mouse_position (XFRAME (frame), xval, yval);
2580#endif /* HAVE_WINDOW_SYSTEM */
2581 }
2582#ifdef MSDOS
2583 else if (FRAME_MSDOS_P (XFRAME (frame)))
2581 { 2584 {
2582 Fselect_frame (frame, Qnil); 2585 Fselect_frame (frame, Qnil);
2583 mouse_moveto (xval, yval); 2586 mouse_moveto (xval, yval);
2584 } 2587 }
2585#elif defined HAVE_GPM 2588#endif /* MSDOS */
2586 Fselect_frame (frame, Qnil); 2589 else
2587 term_mouse_moveto (xval, yval); 2590 {
2591 Fselect_frame (frame, Qnil);
2592#ifdef HAVE_GPM
2593 term_mouse_moveto (xval, yval);
2588#else 2594#else
2589 (void) xval; 2595 (void) xval;
2590 (void) yval; 2596 (void) yval;
2591#endif 2597#endif /* HAVE_GPM */
2598 }
2592 2599
2593 return Qnil; 2600 return Qnil;
2594} 2601}
@@ -2610,23 +2617,31 @@ before calling this function on it, like this.
2610 int yval = check_integer_range (y, INT_MIN, INT_MAX); 2617 int yval = check_integer_range (y, INT_MIN, INT_MAX);
2611 2618
2612 /* I think this should be done with a hook. */ 2619 /* I think this should be done with a hook. */
2613#ifdef HAVE_WINDOW_SYSTEM
2614 if (FRAME_WINDOW_P (XFRAME (frame))) 2620 if (FRAME_WINDOW_P (XFRAME (frame)))
2615 /* Warping the mouse will cause enternotify and focus events. */ 2621 {
2616 frame_set_mouse_pixel_position (XFRAME (frame), xval, yval); 2622 /* Warping the mouse will cause enternotify and focus events. */
2617#elif defined MSDOS 2623#ifdef HAVE_WINDOW_SYSTEM
2618 if (FRAME_MSDOS_P (XFRAME (frame))) 2624 frame_set_mouse_pixel_position (XFRAME (frame), xval, yval);
2625#endif /* HAVE_WINDOW_SYSTEM */
2626 }
2627#ifdef MSDOS
2628 else if (FRAME_MSDOS_P (XFRAME (frame)))
2619 { 2629 {
2620 Fselect_frame (frame, Qnil); 2630 Fselect_frame (frame, Qnil);
2621 mouse_moveto (xval, yval); 2631 mouse_moveto (xval, yval);
2622 } 2632 }
2623#elif defined HAVE_GPM 2633#endif /* MSDOS */
2624 Fselect_frame (frame, Qnil); 2634 else
2625 term_mouse_moveto (xval, yval); 2635 {
2636 Fselect_frame (frame, Qnil);
2637#ifdef HAVE_GPM
2638 term_mouse_moveto (xval, yval);
2626#else 2639#else
2627 (void) xval; 2640 (void) xval;
2628 (void) yval; 2641 (void) yval;
2629#endif 2642#endif /* HAVE_GPM */
2643
2644 }
2630 2645
2631 return Qnil; 2646 return Qnil;
2632} 2647}
diff --git a/src/nsfns.m b/src/nsfns.m
index ae114f83e4d..24ea7d7f63b 100644
--- a/src/nsfns.m
+++ b/src/nsfns.m
@@ -1487,7 +1487,6 @@ Some window managers may refuse to restack windows. */)
1487 { 1487 {
1488 EmacsWindow *window = (EmacsWindow *)[FRAME_NS_VIEW (f1) window]; 1488 EmacsWindow *window = (EmacsWindow *)[FRAME_NS_VIEW (f1) window];
1489 NSWindow *window2 = [FRAME_NS_VIEW (f2) window]; 1489 NSWindow *window2 = [FRAME_NS_VIEW (f2) window];
1490 BOOL flag = !NILP (above);
1491 1490
1492 if ([window restackWindow:window2 above:!NILP (above)]) 1491 if ([window restackWindow:window2 above:!NILP (above)])
1493 return Qt; 1492 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)
101static void 101static void
102ns_update_menubar (struct frame *f, bool deep_p) 102ns_update_menubar (struct frame *f, bool deep_p)
103{ 103{
104 NSAutoreleasePool *pool;
105 BOOL needsSet = NO; 104 BOOL needsSet = NO;
106 id menu = [NSApp mainMenu]; 105 id menu = [NSApp mainMenu];
107 bool owfi; 106 bool owfi;
diff --git a/src/nsselect.m b/src/nsselect.m
index 27db9248e46..5ab3ef77fec 100644
--- a/src/nsselect.m
+++ b/src/nsselect.m
@@ -78,7 +78,13 @@ ns_string_to_symbol (NSString *t)
78 return QSECONDARY; 78 return QSECONDARY;
79 if ([t isEqualToString: NSPasteboardTypeString]) 79 if ([t isEqualToString: NSPasteboardTypeString])
80 return QTEXT; 80 return QTEXT;
81 if ([t isEqualToString: NSFilenamesPboardType]) 81 if ([t isEqualToString:
82#if NS_USE_NSPasteboardTypeFileURL != 0
83 NSPasteboardTypeFileURL
84#else
85 NSFilenamesPboardType
86#endif
87 ])
82 return QFILE_NAME; 88 return QFILE_NAME;
83 if ([t isEqualToString: NSPasteboardTypeTabularText]) 89 if ([t isEqualToString: NSPasteboardTypeTabularText])
84 return QTEXT; 90 return QTEXT;
@@ -467,7 +473,12 @@ nxatoms_of_nsselect (void)
467 [NSNumber numberWithLong:0], NXPrimaryPboard, 473 [NSNumber numberWithLong:0], NXPrimaryPboard,
468 [NSNumber numberWithLong:0], NXSecondaryPboard, 474 [NSNumber numberWithLong:0], NXSecondaryPboard,
469 [NSNumber numberWithLong:0], NSPasteboardTypeString, 475 [NSNumber numberWithLong:0], NSPasteboardTypeString,
470 [NSNumber numberWithLong:0], NSFilenamesPboardType, 476 [NSNumber numberWithLong:0],
477#if NS_USE_NSPasteboardTypeFileURL != 0
478 NSPasteboardTypeFileURL,
479#else
480 NSFilenamesPboardType,
481#endif
471 [NSNumber numberWithLong:0], NSPasteboardTypeTabularText, 482 [NSNumber numberWithLong:0], NSPasteboardTypeTabularText,
472 nil] retain]; 483 nil] retain];
473} 484}
diff --git a/src/nsterm.h b/src/nsterm.h
index 2c9d8e85ba9..eae1d0725ea 100644
--- a/src/nsterm.h
+++ b/src/nsterm.h
@@ -39,6 +39,15 @@ typedef CGFloat EmacsCGFloat;
39typedef float EmacsCGFloat; 39typedef float EmacsCGFloat;
40#endif 40#endif
41 41
42/* NSFilenamesPboardType is deprecated in macOS 10.14, but
43 NSPasteboardTypeFileURL is only available in 10.13 (and GNUstep
44 probably lacks it too). */
45#if defined NS_IMPL_COCOA && MAC_OS_X_VERSION_MIN_REQUIRED >= 101300
46#define NS_USE_NSPasteboardTypeFileURL 1
47#else
48#define NS_USE_NSPasteboardTypeFileURL 0
49#endif
50
42/* ========================================================================== 51/* ==========================================================================
43 52
44 Trace support 53 Trace support
diff --git a/src/nsterm.m b/src/nsterm.m
index 2defb9e2eec..df3934c5c34 100644
--- a/src/nsterm.m
+++ b/src/nsterm.m
@@ -272,7 +272,9 @@ long context_menu_value = 0;
272 272
273/* display update */ 273/* display update */
274static struct frame *ns_updating_frame; 274static struct frame *ns_updating_frame;
275#if !defined (NS_DRAW_TO_BUFFER) || MAC_OS_X_VERSION_MIN_REQUIRED < 101400
275static NSView *focus_view = NULL; 276static NSView *focus_view = NULL;
277#endif
276static int ns_window_num = 0; 278static int ns_window_num = 0;
277static BOOL gsaved = NO; 279static BOOL gsaved = NO;
278static BOOL ns_fake_keydown = NO; 280static BOOL ns_fake_keydown = NO;
@@ -1139,7 +1141,9 @@ ns_update_end (struct frame *f)
1139 external (RIF) call; for whole frame, called after gui_update_window_end 1141 external (RIF) call; for whole frame, called after gui_update_window_end
1140 -------------------------------------------------------------------------- */ 1142 -------------------------------------------------------------------------- */
1141{ 1143{
1144#if !defined (NS_DRAW_TO_BUFFER) || MAC_OS_X_VERSION_MIN_REQUIRED < 101400
1142 EmacsView *view = FRAME_NS_VIEW (f); 1145 EmacsView *view = FRAME_NS_VIEW (f);
1146#endif
1143 1147
1144 NSTRACE_WHEN (NSTRACE_GROUP_UPDATES, "ns_update_end"); 1148 NSTRACE_WHEN (NSTRACE_GROUP_UPDATES, "ns_update_end");
1145 1149
@@ -1449,7 +1453,7 @@ ns_ring_bell (struct frame *f)
1449 } 1453 }
1450} 1454}
1451 1455
1452 1456#if !defined (NS_DRAW_TO_BUFFER) || MAC_OS_X_VERSION_MIN_REQUIRED < 101400
1453static void 1457static void
1454hide_bell (void) 1458hide_bell (void)
1455/* -------------------------------------------------------------------------- 1459/* --------------------------------------------------------------------------
@@ -1463,6 +1467,7 @@ hide_bell (void)
1463 [bell_view remove]; 1467 [bell_view remove];
1464 } 1468 }
1465} 1469}
1470#endif
1466 1471
1467 1472
1468/* ========================================================================== 1473/* ==========================================================================
@@ -2876,6 +2881,8 @@ ns_get_shifted_character (NSEvent *event)
2876 ========================================================================== */ 2881 ========================================================================== */
2877 2882
2878 2883
2884#if 0
2885/* FIXME: Remove this function. */
2879static void 2886static void
2880ns_redraw_scroll_bars (struct frame *f) 2887ns_redraw_scroll_bars (struct frame *f)
2881{ 2888{
@@ -2890,6 +2897,7 @@ ns_redraw_scroll_bars (struct frame *f)
2890 [view display]; 2897 [view display];
2891 } 2898 }
2892} 2899}
2900#endif
2893 2901
2894 2902
2895void 2903void
@@ -5602,7 +5610,11 @@ ns_term_init (Lisp_Object display_name)
5602 ns_drag_types = [[NSArray arrayWithObjects: 5610 ns_drag_types = [[NSArray arrayWithObjects:
5603 NSPasteboardTypeString, 5611 NSPasteboardTypeString,
5604 NSPasteboardTypeTabularText, 5612 NSPasteboardTypeTabularText,
5613#if NS_USE_NSPasteboardTypeFileURL != 0
5614 NSPasteboardTypeFileURL,
5615#else
5605 NSFilenamesPboardType, 5616 NSFilenamesPboardType,
5617#endif
5606 NSPasteboardTypeURL, nil] retain]; 5618 NSPasteboardTypeURL, nil] retain];
5607 5619
5608 /* If fullscreen is in init/default-frame-alist, focus isn't set 5620 /* If fullscreen is in init/default-frame-alist, focus isn't set
@@ -8395,21 +8407,23 @@ not_in_argv (NSString *arg)
8395 void *pixels = CGBitmapContextGetData (context); 8407 void *pixels = CGBitmapContextGetData (context);
8396 int rowSize = CGBitmapContextGetBytesPerRow (context); 8408 int rowSize = CGBitmapContextGetBytesPerRow (context);
8397 int srcRowSize = NSWidth (srcRect) * scale * bpp; 8409 int srcRowSize = NSWidth (srcRect) * scale * bpp;
8398 void *srcPixels = pixels + (int)(NSMinY (srcRect) * scale * rowSize 8410 void *srcPixels = (char *) pixels
8399 + NSMinX (srcRect) * scale * bpp); 8411 + (int) (NSMinY (srcRect) * scale * rowSize
8400 void *dstPixels = pixels + (int)(NSMinY (dstRect) * scale * rowSize 8412 + NSMinX (srcRect) * scale * bpp);
8401 + NSMinX (dstRect) * scale * bpp); 8413 void *dstPixels = (char *) pixels
8414 + (int) (NSMinY (dstRect) * scale * rowSize
8415 + NSMinX (dstRect) * scale * bpp);
8402 8416
8403 if (NSIntersectsRect (srcRect, dstRect) 8417 if (NSIntersectsRect (srcRect, dstRect)
8404 && NSMinY (srcRect) < NSMinY (dstRect)) 8418 && NSMinY (srcRect) < NSMinY (dstRect))
8405 for (int y = NSHeight (srcRect) * scale - 1 ; y >= 0 ; y--) 8419 for (int y = NSHeight (srcRect) * scale - 1 ; y >= 0 ; y--)
8406 memmove (dstPixels + y * rowSize, 8420 memmove ((char *) dstPixels + y * rowSize,
8407 srcPixels + y * rowSize, 8421 (char *) srcPixels + y * rowSize,
8408 srcRowSize); 8422 srcRowSize);
8409 else 8423 else
8410 for (int y = 0 ; y < NSHeight (srcRect) * scale ; y++) 8424 for (int y = 0 ; y < NSHeight (srcRect) * scale ; y++)
8411 memmove (dstPixels + y * rowSize, 8425 memmove ((char *) dstPixels + y * rowSize,
8412 srcPixels + y * rowSize, 8426 (char *) srcPixels + y * rowSize,
8413 srcRowSize); 8427 srcRowSize);
8414 8428
8415#if MAC_OS_X_VERSION_MIN_REQUIRED < 101400 8429#if MAC_OS_X_VERSION_MIN_REQUIRED < 101400
@@ -8533,9 +8547,19 @@ not_in_argv (NSString *arg)
8533 { 8547 {
8534 return NO; 8548 return NO;
8535 } 8549 }
8536 /* FIXME: NSFilenamesPboardType is deprecated in 10.14, but the 8550#if NS_USE_NSPasteboardTypeFileURL != 0
8537 NSURL method can only handle one file at a time. Stick with the 8551 else if ([type isEqualToString: NSPasteboardTypeFileURL])
8538 existing code at the moment. */ 8552 {
8553 type_sym = Qfile;
8554
8555 NSArray *urls = [pb readObjectsForClasses: @[[NSURL self]]
8556 options: nil];
8557 NSEnumerator *uenum = [urls objectEnumerator];
8558 NSURL *url;
8559 while ((url = [uenum nextObject]))
8560 strings = Fcons ([[url path] lispString], strings);
8561 }
8562#else // !NS_USE_NSPasteboardTypeFileURL
8539 else if ([type isEqualToString: NSFilenamesPboardType]) 8563 else if ([type isEqualToString: NSFilenamesPboardType])
8540 { 8564 {
8541 NSArray *files; 8565 NSArray *files;
@@ -8551,6 +8575,7 @@ not_in_argv (NSString *arg)
8551 while ( (file = [fenum nextObject]) ) 8575 while ( (file = [fenum nextObject]) )
8552 strings = Fcons ([file lispString], strings); 8576 strings = Fcons ([file lispString], strings);
8553 } 8577 }
8578#endif // !NS_USE_NSPasteboardTypeFileURL
8554 else if ([type isEqualToString: NSPasteboardTypeURL]) 8579 else if ([type isEqualToString: NSPasteboardTypeURL])
8555 { 8580 {
8556 NSURL *url = [NSURL URLFromPasteboard: pb]; 8581 NSURL *url = [NSURL URLFromPasteboard: pb];
@@ -8727,7 +8752,8 @@ not_in_argv (NSString *arg)
8727/* The array returned by [NSWindow parentWindow] may already be 8752/* The array returned by [NSWindow parentWindow] may already be
8728 sorted, but the documentation doesn't tell us whether or not it is, 8753 sorted, but the documentation doesn't tell us whether or not it is,
8729 so to be safe we'll sort it. */ 8754 so to be safe we'll sort it. */
8730NSInteger nswindow_orderedIndex_sort (id w1, id w2, void *c) 8755static NSInteger
8756nswindow_orderedIndex_sort (id w1, id w2, void *c)
8731{ 8757{
8732 NSInteger i1 = [w1 orderedIndex]; 8758 NSInteger i1 = [w1 orderedIndex];
8733 NSInteger i2 = [w2 orderedIndex]; 8759 NSInteger i2 = [w2 orderedIndex];
diff --git a/src/process.c b/src/process.c
index dac7d0440fa..1df4ed9ce03 100644
--- a/src/process.c
+++ b/src/process.c
@@ -283,6 +283,18 @@ static int max_desc;
283 the file descriptor of a socket that is already bound. */ 283 the file descriptor of a socket that is already bound. */
284static int external_sock_fd; 284static int external_sock_fd;
285 285
286/* File descriptor that becomes readable when we receive SIGCHLD. */
287static int child_signal_read_fd = -1;
288/* The write end thereof. The SIGCHLD handler writes to this file
289 descriptor to notify `wait_reading_process_output' of process
290 status changes. */
291static int child_signal_write_fd = -1;
292static void child_signal_init (void);
293#ifndef WINDOWSNT
294static void child_signal_read (int, void *);
295#endif
296static void child_signal_notify (void);
297
286/* Indexed by descriptor, gives the process (if any) for that descriptor. */ 298/* Indexed by descriptor, gives the process (if any) for that descriptor. */
287static Lisp_Object chan_process[FD_SETSIZE]; 299static Lisp_Object chan_process[FD_SETSIZE];
288static void wait_for_socket_fds (Lisp_Object, char const *); 300static void wait_for_socket_fds (Lisp_Object, char const *);
@@ -2060,6 +2072,10 @@ create_process (Lisp_Object process, char **new_argv, Lisp_Object current_dir)
2060 Lisp_Object lisp_pty_name = Qnil; 2072 Lisp_Object lisp_pty_name = Qnil;
2061 sigset_t oldset; 2073 sigset_t oldset;
2062 2074
2075 /* Ensure that the SIGCHLD handler can notify
2076 `wait_reading_process_output'. */
2077 child_signal_init ();
2078
2063 inchannel = outchannel = -1; 2079 inchannel = outchannel = -1;
2064 2080
2065 if (p->pty_flag) 2081 if (p->pty_flag)
@@ -5309,6 +5325,15 @@ wait_reading_process_output (intmax_t time_limit, int nsecs, int read_kbd,
5309 compute_input_wait_mask (&Atemp); 5325 compute_input_wait_mask (&Atemp);
5310 compute_write_mask (&Ctemp); 5326 compute_write_mask (&Ctemp);
5311 5327
5328 /* If a process status has changed, the child signal pipe
5329 will likely be readable. We want to ignore it for now,
5330 because otherwise we wouldn't run into a timeout
5331 below. */
5332 int fd = child_signal_read_fd;
5333 eassert (fd < FD_SETSIZE);
5334 if (0 <= fd)
5335 FD_CLR (fd, &Atemp);
5336
5312 timeout = make_timespec (0, 0); 5337 timeout = make_timespec (0, 0);
5313 if ((thread_select (pselect, max_desc + 1, 5338 if ((thread_select (pselect, max_desc + 1,
5314 &Atemp, 5339 &Atemp,
@@ -5395,6 +5420,14 @@ wait_reading_process_output (intmax_t time_limit, int nsecs, int read_kbd,
5395 check_write = true; 5420 check_write = true;
5396 } 5421 }
5397 5422
5423 /* We have to be informed when we receive a SIGCHLD signal for
5424 an asynchronous process. Otherwise this might deadlock if we
5425 receive a SIGCHLD during `pselect'. */
5426 int child_fd = child_signal_read_fd;
5427 eassert (child_fd < FD_SETSIZE);
5428 if (0 <= child_fd)
5429 FD_SET (child_fd, &Available);
5430
5398 /* If frame size has changed or the window is newly mapped, 5431 /* If frame size has changed or the window is newly mapped,
5399 redisplay now, before we start to wait. There is a race 5432 redisplay now, before we start to wait. There is a race
5400 condition here; if a SIGIO arrives between now and the select 5433 condition here; if a SIGIO arrives between now and the select
@@ -7114,7 +7147,95 @@ process has been transmitted to the serial port. */)
7114 subprocesses which the main thread should not reap. For example, 7147 subprocesses which the main thread should not reap. For example,
7115 if the main thread attempted to reap an already-reaped child, it 7148 if the main thread attempted to reap an already-reaped child, it
7116 might inadvertently reap a GTK-created process that happened to 7149 might inadvertently reap a GTK-created process that happened to
7117 have the same process ID. */ 7150 have the same process ID.
7151
7152 To avoid a deadlock when receiving SIGCHLD while
7153 'wait_reading_process_output' is in 'pselect', the SIGCHLD handler
7154 will notify the `pselect' using a self-pipe. The deadlock could
7155 occur if SIGCHLD is delivered outside of the 'pselect' call, in
7156 which case 'pselect' will not be interrupted by the signal, and
7157 will therefore wait on the process's output descriptor for the
7158 output that will never come.
7159
7160 WINDOWSNT doesn't need this facility because its 'pselect'
7161 emulation (see 'sys_select' in w32proc.c) waits on a subprocess
7162 handle, which becomes signaled when the process exits, and also
7163 because that emulation delays the delivery of the simulated SIGCHLD
7164 until all the output from the subprocess has been consumed. */
7165
7166/* FIXME: On Unix-like systems that have a proper 'pselect'
7167 (HAVE_PSELECT), we should block SIGCHLD in
7168 'wait_reading_process_output' and pass a non-NULL signal mask to
7169 'pselect' to avoid the need for the self-pipe. */
7170
7171/* Set up `child_signal_read_fd' and `child_signal_write_fd'. */
7172
7173static void
7174child_signal_init (void)
7175{
7176 /* Either both are initialized, or both are uninitialized. */
7177 eassert ((child_signal_read_fd < 0) == (child_signal_write_fd < 0));
7178
7179#ifndef WINDOWSNT
7180 if (0 <= child_signal_read_fd)
7181 return; /* already done */
7182
7183 int fds[2];
7184 if (emacs_pipe (fds) < 0)
7185 report_file_error ("Creating pipe for child signal", Qnil);
7186 if (FD_SETSIZE <= fds[0])
7187 {
7188 /* Since we need to `pselect' on the read end, it has to fit
7189 into an `fd_set'. */
7190 emacs_close (fds[0]);
7191 emacs_close (fds[1]);
7192 report_file_errno ("Creating pipe for child signal", Qnil,
7193 EMFILE);
7194 }
7195
7196 /* We leave the file descriptors open until the Emacs process
7197 exits. */
7198 eassert (0 <= fds[0]);
7199 eassert (0 <= fds[1]);
7200 if (fcntl (fds[0], F_SETFL, O_NONBLOCK) != 0)
7201 emacs_perror ("fcntl");
7202 if (fcntl (fds[1], F_SETFL, O_NONBLOCK) != 0)
7203 emacs_perror ("fcntl");
7204 add_read_fd (fds[0], child_signal_read, NULL);
7205 fd_callback_info[fds[0]].flags &= ~KEYBOARD_FD;
7206 child_signal_read_fd = fds[0];
7207 child_signal_write_fd = fds[1];
7208#endif /* !WINDOWSNT */
7209}
7210
7211#ifndef WINDOWSNT
7212/* Consume a process status change. */
7213
7214static void
7215child_signal_read (int fd, void *data)
7216{
7217 eassert (0 <= fd);
7218 eassert (fd == child_signal_read_fd);
7219 char dummy;
7220 if (emacs_read (fd, &dummy, 1) < 0)
7221 emacs_perror ("reading from child signal FD");
7222}
7223#endif /* !WINDOWSNT */
7224
7225/* Notify `wait_reading_process_output' of a process status
7226 change. */
7227
7228static void
7229child_signal_notify (void)
7230{
7231#ifndef WINDOWSNT
7232 int fd = child_signal_write_fd;
7233 eassert (0 <= fd);
7234 char dummy = 0;
7235 if (emacs_write (fd, &dummy, 1) != 1)
7236 emacs_perror ("writing to child signal FD");
7237#endif
7238}
7118 7239
7119/* LIB_CHILD_HANDLER is a SIGCHLD handler that Emacs calls while doing 7240/* LIB_CHILD_HANDLER is a SIGCHLD handler that Emacs calls while doing
7120 its own SIGCHLD handling. On POSIXish systems, glib needs this to 7241 its own SIGCHLD handling. On POSIXish systems, glib needs this to
@@ -7152,6 +7273,7 @@ static void
7152handle_child_signal (int sig) 7273handle_child_signal (int sig)
7153{ 7274{
7154 Lisp_Object tail, proc; 7275 Lisp_Object tail, proc;
7276 bool changed = false;
7155 7277
7156 /* Find the process that signaled us, and record its status. */ 7278 /* Find the process that signaled us, and record its status. */
7157 7279
@@ -7174,6 +7296,7 @@ handle_child_signal (int sig)
7174 eassert (ok); 7296 eassert (ok);
7175 if (child_status_changed (deleted_pid, 0, 0)) 7297 if (child_status_changed (deleted_pid, 0, 0))
7176 { 7298 {
7299 changed = true;
7177 if (STRINGP (XCDR (head))) 7300 if (STRINGP (XCDR (head)))
7178 unlink (SSDATA (XCDR (head))); 7301 unlink (SSDATA (XCDR (head)));
7179 XSETCAR (tail, Qnil); 7302 XSETCAR (tail, Qnil);
@@ -7191,6 +7314,7 @@ handle_child_signal (int sig)
7191 && child_status_changed (p->pid, &status, WUNTRACED | WCONTINUED)) 7314 && child_status_changed (p->pid, &status, WUNTRACED | WCONTINUED))
7192 { 7315 {
7193 /* Change the status of the process that was found. */ 7316 /* Change the status of the process that was found. */
7317 changed = true;
7194 p->tick = ++process_tick; 7318 p->tick = ++process_tick;
7195 p->raw_status = status; 7319 p->raw_status = status;
7196 p->raw_status_new = 1; 7320 p->raw_status_new = 1;
@@ -7210,6 +7334,10 @@ handle_child_signal (int sig)
7210 } 7334 }
7211 } 7335 }
7212 7336
7337 if (changed)
7338 /* Wake up `wait_reading_process_output'. */
7339 child_signal_notify ();
7340
7213 lib_child_handler (sig); 7341 lib_child_handler (sig);
7214#ifdef NS_IMPL_GNUSTEP 7342#ifdef NS_IMPL_GNUSTEP
7215 /* NSTask in GNUstep sets its child handler each time it is called. 7343 /* NSTask in GNUstep sets its child handler each time it is called.
diff --git a/src/term.c b/src/term.c
index a87f9c745ce..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)
790 cmcheckmagic (tty); 790 cmcheckmagic (tty);
791} 791}
792 792
793#ifdef HAVE_GPM /* Only used by GPM code. */ 793#ifndef DOS_NT
794 794
795static void 795static void
796tty_write_glyphs_with_face (register struct frame *f, register struct glyph *string, 796tty_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
847 847
848 cmcheckmagic (tty); 848 cmcheckmagic (tty);
849} 849}
850
850#endif 851#endif
851 852
852/* An implementation of insert_glyphs for termcap frames. */ 853/* An implementation of insert_glyphs for termcap frames. */
@@ -2380,25 +2381,9 @@ frame's terminal). */)
2380 Mouse 2381 Mouse
2381 ***********************************************************************/ 2382 ***********************************************************************/
2382 2383
2383#ifdef HAVE_GPM 2384#ifndef DOS_NT
2384
2385#ifndef HAVE_WINDOW_SYSTEM
2386void
2387term_mouse_moveto (int x, int y)
2388{
2389 /* TODO: how to set mouse position?
2390 const char *name;
2391 int fd;
2392 name = (const char *) ttyname (0);
2393 fd = emacs_open (name, O_WRONLY, 0);
2394 SOME_FUNCTION (x, y, fd);
2395 emacs_close (fd);
2396 last_mouse_x = x;
2397 last_mouse_y = y; */
2398}
2399#endif /* HAVE_WINDOW_SYSTEM */
2400 2385
2401/* Implementation of draw_row_with_mouse_face for TTY/GPM. */ 2386/* Implementation of draw_row_with_mouse_face for TTY/GPM and macOS. */
2402void 2387void
2403tty_draw_row_with_mouse_face (struct window *w, struct glyph_row *row, 2388tty_draw_row_with_mouse_face (struct window *w, struct glyph_row *row,
2404 int start_hpos, int end_hpos, 2389 int start_hpos, int end_hpos,
@@ -2430,6 +2415,24 @@ tty_draw_row_with_mouse_face (struct window *w, struct glyph_row *row,
2430 cursor_to (f, save_y, save_x); 2415 cursor_to (f, save_y, save_x);
2431} 2416}
2432 2417
2418#endif
2419
2420#ifdef HAVE_GPM
2421
2422void
2423term_mouse_moveto (int x, int y)
2424{
2425 /* TODO: how to set mouse position?
2426 const char *name;
2427 int fd;
2428 name = (const char *) ttyname (0);
2429 fd = emacs_open (name, O_WRONLY, 0);
2430 SOME_FUNCTION (x, y, fd);
2431 emacs_close (fd);
2432 last_mouse_x = x;
2433 last_mouse_y = y; */
2434}
2435
2433/* Return the current time, as a Time value. Wrap around on overflow. */ 2436/* Return the current time, as a Time value. Wrap around on overflow. */
2434static Time 2437static Time
2435current_Time (void) 2438current_Time (void)
@@ -4246,8 +4249,8 @@ use the Bourne shell command 'TERM=...; export TERM' (C-shell:\n\
4246 4249
4247#ifdef HAVE_GPM 4250#ifdef HAVE_GPM
4248 terminal->mouse_position_hook = term_mouse_position; 4251 terminal->mouse_position_hook = term_mouse_position;
4249 tty->mouse_highlight.mouse_face_window = Qnil;
4250#endif 4252#endif
4253 tty->mouse_highlight.mouse_face_window = Qnil;
4251 4254
4252 terminal->kboard = allocate_kboard (Qnil); 4255 terminal->kboard = allocate_kboard (Qnil);
4253 terminal->kboard->reference_count++; 4256 terminal->kboard->reference_count++;
diff --git a/src/termhooks.h b/src/termhooks.h
index 85a47c071b6..3800679e803 100644
--- a/src/termhooks.h
+++ b/src/termhooks.h
@@ -366,9 +366,7 @@ enum {
366#ifdef HAVE_GPM 366#ifdef HAVE_GPM
367#include <gpm.h> 367#include <gpm.h>
368extern int handle_one_term_event (struct tty_display_info *, Gpm_Event *); 368extern int handle_one_term_event (struct tty_display_info *, Gpm_Event *);
369#ifndef HAVE_WINDOW_SYSTEM
370extern void term_mouse_moveto (int, int); 369extern void term_mouse_moveto (int, int);
371#endif
372 370
373/* The device for which we have enabled gpm support. */ 371/* The device for which we have enabled gpm support. */
374extern struct tty_display_info *gpm_tty; 372extern struct tty_display_info *gpm_tty;
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). */)
2260Lisp_Object 2260Lisp_Object
2261window_parameter (struct window *w, Lisp_Object parameter) 2261window_parameter (struct window *w, Lisp_Object parameter)
2262{ 2262{
2263 Lisp_Object result = Fassq (parameter, w->window_parameters); 2263 Lisp_Object result = assq_no_quit (parameter, w->window_parameters);
2264 2264
2265 return CDR_SAFE (result); 2265 return CDR_SAFE (result);
2266} 2266}
diff --git a/src/xdisp.c b/src/xdisp.c
index ea67329cff1..e1e4ff41365 100644
--- a/src/xdisp.c
+++ b/src/xdisp.c
@@ -20822,9 +20822,8 @@ try_window_id (struct window *w)
20822 + window_wants_header_line (w) 20822 + window_wants_header_line (w)
20823 + window_internal_height (w)); 20823 + window_internal_height (w));
20824 20824
20825#if defined (HAVE_GPM) || defined (MSDOS)
20826 gui_clear_window_mouse_face (w); 20825 gui_clear_window_mouse_face (w);
20827#endif 20826
20828 /* Perform the operation on the screen. */ 20827 /* Perform the operation on the screen. */
20829 if (dvpos > 0) 20828 if (dvpos > 0)
20830 { 20829 {
@@ -31928,9 +31927,8 @@ draw_row_with_mouse_face (struct window *w, int start_x, struct glyph_row *row,
31928 return; 31927 return;
31929 } 31928 }
31930#endif 31929#endif
31931#if defined (HAVE_GPM) || defined (MSDOS) || defined (WINDOWSNT) 31930
31932 tty_draw_row_with_mouse_face (w, row, start_hpos, end_hpos, draw); 31931 tty_draw_row_with_mouse_face (w, row, start_hpos, end_hpos, draw);
31933#endif
31934} 31932}
31935 31933
31936/* Display the active region described by mouse_face_* according to DRAW. */ 31934/* Display the active region described by mouse_face_* according to DRAW. */