diff options
| author | Yuuki Harano | 2021-01-20 21:46:03 +0900 |
|---|---|---|
| committer | Yuuki Harano | 2021-01-20 21:46:03 +0900 |
| commit | bebc657aad7c9b448a8e0cafd9d09d7774097975 (patch) | |
| tree | 41869bfa2dcdbfdfefedb84be3ee2b05037372fc /src | |
| parent | 7326982d283abe7545d5f5742ea2b57e513fd285 (diff) | |
| parent | 8b33b76eb9fbb857bccbe3d223c961c486e4e8f9 (diff) | |
| download | emacs-bebc657aad7c9b448a8e0cafd9d09d7774097975.tar.gz emacs-bebc657aad7c9b448a8e0cafd9d09d7774097975.zip | |
Merge branch 'master' of git.sv.gnu.org:/srv/git/emacs into feature/pgtk
Diffstat (limited to 'src')
| -rw-r--r-- | src/buffer.c | 2 | ||||
| -rw-r--r-- | src/callproc.c | 2 | ||||
| -rw-r--r-- | src/data.c | 3 | ||||
| -rw-r--r-- | src/dispnew.c | 16 | ||||
| -rw-r--r-- | src/emacs.c | 4 | ||||
| -rw-r--r-- | src/eval.c | 26 | ||||
| -rw-r--r-- | src/fns.c | 85 | ||||
| -rw-r--r-- | src/frame.c | 59 | ||||
| -rw-r--r-- | src/keymap.c | 35 | ||||
| -rw-r--r-- | src/lisp.h | 4 | ||||
| -rw-r--r-- | src/lread.c | 29 | ||||
| -rw-r--r-- | src/minibuf.c | 211 | ||||
| -rw-r--r-- | src/nsselect.m | 15 | ||||
| -rw-r--r-- | src/nsterm.h | 9 | ||||
| -rw-r--r-- | src/nsterm.m | 21 | ||||
| -rw-r--r-- | src/pdumper.c | 2 | ||||
| -rw-r--r-- | src/process.c | 105 | ||||
| -rw-r--r-- | src/sysdep.c | 217 | ||||
| -rw-r--r-- | src/term.c | 4 | ||||
| -rw-r--r-- | src/termhooks.h | 2 | ||||
| -rw-r--r-- | src/w32term.c | 3 | ||||
| -rw-r--r-- | src/window.c | 5 | ||||
| -rw-r--r-- | src/window.h | 4 | ||||
| -rw-r--r-- | src/xdisp.c | 16 | ||||
| -rw-r--r-- | src/xfaces.c | 8 |
25 files changed, 770 insertions, 117 deletions
diff --git a/src/buffer.c b/src/buffer.c index 71ad5edd527..80c799e719b 100644 --- a/src/buffer.c +++ b/src/buffer.c | |||
| @@ -4785,7 +4785,7 @@ mmap_init (void) | |||
| 4785 | if (mmap_fd <= 0) | 4785 | if (mmap_fd <= 0) |
| 4786 | { | 4786 | { |
| 4787 | /* No anonymous mmap -- we need the file descriptor. */ | 4787 | /* No anonymous mmap -- we need the file descriptor. */ |
| 4788 | mmap_fd = emacs_open ("/dev/zero", O_RDONLY, 0); | 4788 | mmap_fd = emacs_open_noquit ("/dev/zero", O_RDONLY, 0); |
| 4789 | if (mmap_fd == -1) | 4789 | if (mmap_fd == -1) |
| 4790 | fatal ("Cannot open /dev/zero: %s", emacs_strerror (errno)); | 4790 | fatal ("Cannot open /dev/zero: %s", emacs_strerror (errno)); |
| 4791 | } | 4791 | } |
diff --git a/src/callproc.c b/src/callproc.c index 1da315bef18..cb72b070b7b 100644 --- a/src/callproc.c +++ b/src/callproc.c | |||
| @@ -1336,7 +1336,7 @@ emacs_spawn (pid_t *newpid, int std_in, int std_out, int std_err, | |||
| 1336 | would work? */ | 1336 | would work? */ |
| 1337 | if (std_in >= 0) | 1337 | if (std_in >= 0) |
| 1338 | emacs_close (std_in); | 1338 | emacs_close (std_in); |
| 1339 | std_out = std_in = emacs_open (pty, O_RDWR, 0); | 1339 | std_out = std_in = emacs_open_noquit (pty, O_RDWR, 0); |
| 1340 | 1340 | ||
| 1341 | if (std_in < 0) | 1341 | if (std_in < 0) |
| 1342 | { | 1342 | { |
diff --git a/src/data.c b/src/data.c index d420bf5fc58..35a6890b9bd 100644 --- a/src/data.c +++ b/src/data.c | |||
| @@ -3760,6 +3760,7 @@ syms_of_data (void) | |||
| 3760 | DEFSYM (Qbuffer_read_only, "buffer-read-only"); | 3760 | DEFSYM (Qbuffer_read_only, "buffer-read-only"); |
| 3761 | DEFSYM (Qtext_read_only, "text-read-only"); | 3761 | DEFSYM (Qtext_read_only, "text-read-only"); |
| 3762 | DEFSYM (Qmark_inactive, "mark-inactive"); | 3762 | DEFSYM (Qmark_inactive, "mark-inactive"); |
| 3763 | DEFSYM (Qinhibited_interaction, "inhibited-interaction"); | ||
| 3763 | 3764 | ||
| 3764 | DEFSYM (Qlistp, "listp"); | 3765 | DEFSYM (Qlistp, "listp"); |
| 3765 | DEFSYM (Qconsp, "consp"); | 3766 | DEFSYM (Qconsp, "consp"); |
| @@ -3844,6 +3845,8 @@ syms_of_data (void) | |||
| 3844 | PUT_ERROR (Qbuffer_read_only, error_tail, "Buffer is read-only"); | 3845 | PUT_ERROR (Qbuffer_read_only, error_tail, "Buffer is read-only"); |
| 3845 | PUT_ERROR (Qtext_read_only, pure_cons (Qbuffer_read_only, error_tail), | 3846 | PUT_ERROR (Qtext_read_only, pure_cons (Qbuffer_read_only, error_tail), |
| 3846 | "Text is read-only"); | 3847 | "Text is read-only"); |
| 3848 | PUT_ERROR (Qinhibited_interaction, error_tail, | ||
| 3849 | "User interaction while inhibited"); | ||
| 3847 | 3850 | ||
| 3848 | DEFSYM (Qrange_error, "range-error"); | 3851 | DEFSYM (Qrange_error, "range-error"); |
| 3849 | DEFSYM (Qdomain_error, "domain-error"); | 3852 | DEFSYM (Qdomain_error, "domain-error"); |
diff --git a/src/dispnew.c b/src/dispnew.c index 881bc5202cc..55667fa124d 100644 --- a/src/dispnew.c +++ b/src/dispnew.c | |||
| @@ -6049,7 +6049,14 @@ additional wait period, in milliseconds; this is for backwards compatibility. | |||
| 6049 | READING is true if reading input. | 6049 | READING is true if reading input. |
| 6050 | If DISPLAY_OPTION is >0 display process output while waiting. | 6050 | If DISPLAY_OPTION is >0 display process output while waiting. |
| 6051 | If DISPLAY_OPTION is >1 perform an initial redisplay before waiting. | 6051 | If DISPLAY_OPTION is >1 perform an initial redisplay before waiting. |
| 6052 | */ | 6052 | |
| 6053 | Returns a boolean Qt if we waited the full time and returns Qnil if the | ||
| 6054 | wait was interrupted by incoming process output or keyboard events. | ||
| 6055 | |||
| 6056 | FIXME: When `wait_reading_process_output` returns early because of | ||
| 6057 | process output, instead of returning nil we should loop and wait some | ||
| 6058 | more (i.e. until either there's pending input events or the timeout | ||
| 6059 | expired). */ | ||
| 6053 | 6060 | ||
| 6054 | Lisp_Object | 6061 | Lisp_Object |
| 6055 | sit_for (Lisp_Object timeout, bool reading, int display_option) | 6062 | sit_for (Lisp_Object timeout, bool reading, int display_option) |
| @@ -6110,8 +6117,9 @@ sit_for (Lisp_Object timeout, bool reading, int display_option) | |||
| 6110 | gobble_input (); | 6117 | gobble_input (); |
| 6111 | #endif | 6118 | #endif |
| 6112 | 6119 | ||
| 6113 | wait_reading_process_output (sec, nsec, reading ? -1 : 1, do_display, | 6120 | int nbytes |
| 6114 | Qnil, NULL, 0); | 6121 | = wait_reading_process_output (sec, nsec, reading ? -1 : 1, do_display, |
| 6122 | Qnil, NULL, 0); | ||
| 6115 | 6123 | ||
| 6116 | if (reading && curbuf_eq_winbuf) | 6124 | if (reading && curbuf_eq_winbuf) |
| 6117 | /* Timers and process filters/sentinels may have changed the selected | 6125 | /* Timers and process filters/sentinels may have changed the selected |
| @@ -6120,7 +6128,7 @@ sit_for (Lisp_Object timeout, bool reading, int display_option) | |||
| 6120 | buffer to start with). */ | 6128 | buffer to start with). */ |
| 6121 | set_buffer_internal (XBUFFER (XWINDOW (selected_window)->contents)); | 6129 | set_buffer_internal (XBUFFER (XWINDOW (selected_window)->contents)); |
| 6122 | 6130 | ||
| 6123 | return detect_input_pending () ? Qnil : Qt; | 6131 | return (nbytes > 0 || detect_input_pending ()) ? Qnil : Qt; |
| 6124 | } | 6132 | } |
| 6125 | 6133 | ||
| 6126 | 6134 | ||
diff --git a/src/emacs.c b/src/emacs.c index 461d1b72e4c..22995520112 100644 --- a/src/emacs.c +++ b/src/emacs.c | |||
| @@ -1275,7 +1275,7 @@ main (int argc, char **argv) | |||
| 1275 | { | 1275 | { |
| 1276 | emacs_close (STDIN_FILENO); | 1276 | emacs_close (STDIN_FILENO); |
| 1277 | emacs_close (STDOUT_FILENO); | 1277 | emacs_close (STDOUT_FILENO); |
| 1278 | int result = emacs_open (term, O_RDWR, 0); | 1278 | int result = emacs_open_noquit (term, O_RDWR, 0); |
| 1279 | if (result != STDIN_FILENO | 1279 | if (result != STDIN_FILENO |
| 1280 | || (fcntl (STDIN_FILENO, F_DUPFD_CLOEXEC, STDOUT_FILENO) | 1280 | || (fcntl (STDIN_FILENO, F_DUPFD_CLOEXEC, STDOUT_FILENO) |
| 1281 | != STDOUT_FILENO)) | 1281 | != STDOUT_FILENO)) |
| @@ -2862,7 +2862,7 @@ from the parent process and its tty file descriptors. */) | |||
| 2862 | int nfd; | 2862 | int nfd; |
| 2863 | 2863 | ||
| 2864 | /* Get rid of stdin, stdout and stderr. */ | 2864 | /* Get rid of stdin, stdout and stderr. */ |
| 2865 | nfd = emacs_open ("/dev/null", O_RDWR, 0); | 2865 | nfd = emacs_open_noquit ("/dev/null", O_RDWR, 0); |
| 2866 | err |= nfd < 0; | 2866 | err |= nfd < 0; |
| 2867 | err |= dup2 (nfd, STDIN_FILENO) < 0; | 2867 | err |= dup2 (nfd, STDIN_FILENO) < 0; |
| 2868 | err |= dup2 (nfd, STDOUT_FILENO) < 0; | 2868 | err |= dup2 (nfd, STDOUT_FILENO) < 0; |
diff --git a/src/eval.c b/src/eval.c index 706aafdf509..5bf3faebc85 100644 --- a/src/eval.c +++ b/src/eval.c | |||
| @@ -1167,9 +1167,18 @@ Lisp_Object | |||
| 1167 | internal_catch (Lisp_Object tag, | 1167 | internal_catch (Lisp_Object tag, |
| 1168 | Lisp_Object (*func) (Lisp_Object), Lisp_Object arg) | 1168 | Lisp_Object (*func) (Lisp_Object), Lisp_Object arg) |
| 1169 | { | 1169 | { |
| 1170 | /* MINIBUFFER_QUIT_LEVEL is to handle quitting from nested minibuffers by | ||
| 1171 | throwing t to tag `exit'. | ||
| 1172 | Value -1 means there is no (throw 'exit t) in progress; | ||
| 1173 | 0 means the `throw' wasn't done from an active minibuffer; | ||
| 1174 | N > 0 means the `throw' was done from the minibuffer at level N. */ | ||
| 1175 | static EMACS_INT minibuffer_quit_level = -1; | ||
| 1170 | /* This structure is made part of the chain `catchlist'. */ | 1176 | /* This structure is made part of the chain `catchlist'. */ |
| 1171 | struct handler *c = push_handler (tag, CATCHER); | 1177 | struct handler *c = push_handler (tag, CATCHER); |
| 1172 | 1178 | ||
| 1179 | if (EQ (tag, Qexit)) | ||
| 1180 | minibuffer_quit_level = -1; | ||
| 1181 | |||
| 1173 | /* Call FUNC. */ | 1182 | /* Call FUNC. */ |
| 1174 | if (! sys_setjmp (c->jmp)) | 1183 | if (! sys_setjmp (c->jmp)) |
| 1175 | { | 1184 | { |
| @@ -1183,6 +1192,23 @@ internal_catch (Lisp_Object tag, | |||
| 1183 | Lisp_Object val = handlerlist->val; | 1192 | Lisp_Object val = handlerlist->val; |
| 1184 | clobbered_eassert (handlerlist == c); | 1193 | clobbered_eassert (handlerlist == c); |
| 1185 | handlerlist = handlerlist->next; | 1194 | handlerlist = handlerlist->next; |
| 1195 | if (EQ (tag, Qexit) && EQ (val, Qt)) | ||
| 1196 | /* If we've thrown t to tag `exit' from within a minibuffer, we | ||
| 1197 | exit all minibuffers more deeply nested than the current | ||
| 1198 | one. */ | ||
| 1199 | { | ||
| 1200 | EMACS_INT mini_depth = this_minibuffer_depth (Qnil); | ||
| 1201 | if (mini_depth && mini_depth != minibuffer_quit_level) | ||
| 1202 | { | ||
| 1203 | if (minibuffer_quit_level == -1) | ||
| 1204 | minibuffer_quit_level = mini_depth; | ||
| 1205 | if (minibuffer_quit_level | ||
| 1206 | && (minibuf_level > minibuffer_quit_level)) | ||
| 1207 | Fthrow (Qexit, Qt); | ||
| 1208 | } | ||
| 1209 | else | ||
| 1210 | minibuffer_quit_level = -1; | ||
| 1211 | } | ||
| 1186 | return val; | 1212 | return val; |
| 1187 | } | 1213 | } |
| 1188 | } | 1214 | } |
| @@ -5548,6 +5548,90 @@ It should not be used for anything security-related. See | |||
| 5548 | return make_digest_string (digest, SHA1_DIGEST_SIZE); | 5548 | return make_digest_string (digest, SHA1_DIGEST_SIZE); |
| 5549 | } | 5549 | } |
| 5550 | 5550 | ||
| 5551 | DEFUN ("buffer-line-statistics", Fbuffer_line_statistics, | ||
| 5552 | Sbuffer_line_statistics, 0, 1, 0, | ||
| 5553 | doc: /* Return data about lines in BUFFER. | ||
| 5554 | The data is returned as a list, and the first element is the number of | ||
| 5555 | lines in the buffer, the second is the length of the longest line, and | ||
| 5556 | the third is the mean line length. The lengths returned are in bytes, not | ||
| 5557 | characters. */ ) | ||
| 5558 | (Lisp_Object buffer_or_name) | ||
| 5559 | { | ||
| 5560 | Lisp_Object buffer; | ||
| 5561 | ptrdiff_t lines = 0, longest = 0; | ||
| 5562 | double mean = 0; | ||
| 5563 | struct buffer *b; | ||
| 5564 | |||
| 5565 | if (NILP (buffer_or_name)) | ||
| 5566 | buffer = Fcurrent_buffer (); | ||
| 5567 | else | ||
| 5568 | buffer = Fget_buffer (buffer_or_name); | ||
| 5569 | if (NILP (buffer)) | ||
| 5570 | nsberror (buffer_or_name); | ||
| 5571 | |||
| 5572 | b = XBUFFER (buffer); | ||
| 5573 | |||
| 5574 | unsigned char *start = BUF_BEG_ADDR (b); | ||
| 5575 | ptrdiff_t area = BUF_GPT_BYTE (b) - BUF_BEG_BYTE (b), pre_gap = 0; | ||
| 5576 | |||
| 5577 | /* Process the first part of the buffer. */ | ||
| 5578 | while (area > 0) | ||
| 5579 | { | ||
| 5580 | unsigned char *n = memchr (start, '\n', area); | ||
| 5581 | |||
| 5582 | if (n) | ||
| 5583 | { | ||
| 5584 | ptrdiff_t this_line = n - start; | ||
| 5585 | if (this_line > longest) | ||
| 5586 | longest = this_line; | ||
| 5587 | lines++; | ||
| 5588 | /* Blame Knuth. */ | ||
| 5589 | mean = mean + (this_line - mean) / lines; | ||
| 5590 | area = area - this_line - 1; | ||
| 5591 | start += this_line + 1; | ||
| 5592 | } | ||
| 5593 | else | ||
| 5594 | { | ||
| 5595 | /* Didn't have a newline here, so save the rest for the | ||
| 5596 | post-gap calculation. */ | ||
| 5597 | pre_gap = area; | ||
| 5598 | area = 0; | ||
| 5599 | } | ||
| 5600 | } | ||
| 5601 | |||
| 5602 | /* If the gap is before the end of the buffer, process the last half | ||
| 5603 | of the buffer. */ | ||
| 5604 | if (BUF_GPT_BYTE (b) < BUF_Z_BYTE (b)) | ||
| 5605 | { | ||
| 5606 | start = BUF_GAP_END_ADDR (b); | ||
| 5607 | area = BUF_Z_ADDR (b) - BUF_GAP_END_ADDR (b); | ||
| 5608 | |||
| 5609 | while (area > 0) | ||
| 5610 | { | ||
| 5611 | unsigned char *n = memchr (start, '\n', area); | ||
| 5612 | ptrdiff_t this_line = n? n - start + pre_gap: area + pre_gap; | ||
| 5613 | |||
| 5614 | if (this_line > longest) | ||
| 5615 | longest = this_line; | ||
| 5616 | lines++; | ||
| 5617 | /* Blame Knuth again. */ | ||
| 5618 | mean = mean + (this_line - mean) / lines; | ||
| 5619 | area = area - this_line - 1; | ||
| 5620 | start += this_line + 1; | ||
| 5621 | pre_gap = 0; | ||
| 5622 | } | ||
| 5623 | } | ||
| 5624 | else if (pre_gap > 0) | ||
| 5625 | { | ||
| 5626 | if (pre_gap > longest) | ||
| 5627 | longest = pre_gap; | ||
| 5628 | lines++; | ||
| 5629 | mean = mean + (pre_gap - mean) / lines; | ||
| 5630 | } | ||
| 5631 | |||
| 5632 | return list3 (make_int (lines), make_int (longest), make_float (mean)); | ||
| 5633 | } | ||
| 5634 | |||
| 5551 | static bool | 5635 | static bool |
| 5552 | string_ascii_p (Lisp_Object string) | 5636 | string_ascii_p (Lisp_Object string) |
| 5553 | { | 5637 | { |
| @@ -5871,4 +5955,5 @@ this variable. */); | |||
| 5871 | defsubr (&Ssecure_hash); | 5955 | defsubr (&Ssecure_hash); |
| 5872 | defsubr (&Sbuffer_hash); | 5956 | defsubr (&Sbuffer_hash); |
| 5873 | defsubr (&Slocale_info); | 5957 | defsubr (&Slocale_info); |
| 5958 | defsubr (&Sbuffer_line_statistics); | ||
| 5874 | } | 5959 | } |
diff --git a/src/frame.c b/src/frame.c index 4ecb0e920a3..daaba2abfec 100644 --- a/src/frame.c +++ b/src/frame.c | |||
| @@ -2575,23 +2575,30 @@ before calling this function on it, like this. | |||
| 2575 | int yval = check_integer_range (y, INT_MIN, INT_MAX); | 2575 | int yval = check_integer_range (y, INT_MIN, INT_MAX); |
| 2576 | 2576 | ||
| 2577 | /* I think this should be done with a hook. */ | 2577 | /* I think this should be done with a hook. */ |
| 2578 | #ifdef HAVE_WINDOW_SYSTEM | ||
| 2579 | if (FRAME_WINDOW_P (XFRAME (frame))) | 2578 | if (FRAME_WINDOW_P (XFRAME (frame))) |
| 2580 | /* Warping the mouse will cause enternotify and focus events. */ | 2579 | { |
| 2581 | frame_set_mouse_position (XFRAME (frame), xval, yval); | 2580 | #ifdef HAVE_WINDOW_SYSTEM |
| 2582 | #elif defined MSDOS | 2581 | /* Warping the mouse will cause enternotify and focus events. */ |
| 2583 | if (FRAME_MSDOS_P (XFRAME (frame))) | 2582 | frame_set_mouse_position (XFRAME (frame), xval, yval); |
| 2583 | #endif /* HAVE_WINDOW_SYSTEM */ | ||
| 2584 | } | ||
| 2585 | #ifdef MSDOS | ||
| 2586 | else if (FRAME_MSDOS_P (XFRAME (frame))) | ||
| 2584 | { | 2587 | { |
| 2585 | Fselect_frame (frame, Qnil); | 2588 | Fselect_frame (frame, Qnil); |
| 2586 | mouse_moveto (xval, yval); | 2589 | mouse_moveto (xval, yval); |
| 2587 | } | 2590 | } |
| 2588 | #elif defined HAVE_GPM | 2591 | #endif /* MSDOS */ |
| 2589 | Fselect_frame (frame, Qnil); | 2592 | else |
| 2590 | term_mouse_moveto (xval, yval); | 2593 | { |
| 2594 | Fselect_frame (frame, Qnil); | ||
| 2595 | #ifdef HAVE_GPM | ||
| 2596 | term_mouse_moveto (xval, yval); | ||
| 2591 | #else | 2597 | #else |
| 2592 | (void) xval; | 2598 | (void) xval; |
| 2593 | (void) yval; | 2599 | (void) yval; |
| 2594 | #endif | 2600 | #endif /* HAVE_GPM */ |
| 2601 | } | ||
| 2595 | 2602 | ||
| 2596 | return Qnil; | 2603 | return Qnil; |
| 2597 | } | 2604 | } |
| @@ -2613,23 +2620,31 @@ before calling this function on it, like this. | |||
| 2613 | int yval = check_integer_range (y, INT_MIN, INT_MAX); | 2620 | int yval = check_integer_range (y, INT_MIN, INT_MAX); |
| 2614 | 2621 | ||
| 2615 | /* I think this should be done with a hook. */ | 2622 | /* I think this should be done with a hook. */ |
| 2616 | #ifdef HAVE_WINDOW_SYSTEM | ||
| 2617 | if (FRAME_WINDOW_P (XFRAME (frame))) | 2623 | if (FRAME_WINDOW_P (XFRAME (frame))) |
| 2618 | /* Warping the mouse will cause enternotify and focus events. */ | 2624 | { |
| 2619 | frame_set_mouse_pixel_position (XFRAME (frame), xval, yval); | 2625 | /* Warping the mouse will cause enternotify and focus events. */ |
| 2620 | #elif defined MSDOS | 2626 | #ifdef HAVE_WINDOW_SYSTEM |
| 2621 | if (FRAME_MSDOS_P (XFRAME (frame))) | 2627 | frame_set_mouse_pixel_position (XFRAME (frame), xval, yval); |
| 2628 | #endif /* HAVE_WINDOW_SYSTEM */ | ||
| 2629 | } | ||
| 2630 | #ifdef MSDOS | ||
| 2631 | else if (FRAME_MSDOS_P (XFRAME (frame))) | ||
| 2622 | { | 2632 | { |
| 2623 | Fselect_frame (frame, Qnil); | 2633 | Fselect_frame (frame, Qnil); |
| 2624 | mouse_moveto (xval, yval); | 2634 | mouse_moveto (xval, yval); |
| 2625 | } | 2635 | } |
| 2626 | #elif defined HAVE_GPM | 2636 | #endif /* MSDOS */ |
| 2627 | Fselect_frame (frame, Qnil); | 2637 | else |
| 2628 | term_mouse_moveto (xval, yval); | 2638 | { |
| 2639 | Fselect_frame (frame, Qnil); | ||
| 2640 | #ifdef HAVE_GPM | ||
| 2641 | term_mouse_moveto (xval, yval); | ||
| 2629 | #else | 2642 | #else |
| 2630 | (void) xval; | 2643 | (void) xval; |
| 2631 | (void) yval; | 2644 | (void) yval; |
| 2632 | #endif | 2645 | #endif /* HAVE_GPM */ |
| 2646 | |||
| 2647 | } | ||
| 2633 | 2648 | ||
| 2634 | return Qnil; | 2649 | return Qnil; |
| 2635 | } | 2650 | } |
diff --git a/src/keymap.c b/src/keymap.c index 1197f6fd4a5..de9b2b58c5e 100644 --- a/src/keymap.c +++ b/src/keymap.c | |||
| @@ -1646,39 +1646,6 @@ specified buffer position instead of point are used. | |||
| 1646 | 1646 | ||
| 1647 | /* GC is possible in this function if it autoloads a keymap. */ | 1647 | /* GC is possible in this function if it autoloads a keymap. */ |
| 1648 | 1648 | ||
| 1649 | DEFUN ("local-key-binding", Flocal_key_binding, Slocal_key_binding, 1, 2, 0, | ||
| 1650 | doc: /* Return the binding for command KEYS in current local keymap only. | ||
| 1651 | KEYS is a string or vector, a sequence of keystrokes. | ||
| 1652 | The binding is probably a symbol with a function definition. | ||
| 1653 | |||
| 1654 | If optional argument ACCEPT-DEFAULT is non-nil, recognize default | ||
| 1655 | bindings; see the description of `lookup-key' for more details about this. */) | ||
| 1656 | (Lisp_Object keys, Lisp_Object accept_default) | ||
| 1657 | { | ||
| 1658 | register Lisp_Object map = BVAR (current_buffer, keymap); | ||
| 1659 | if (NILP (map)) | ||
| 1660 | return Qnil; | ||
| 1661 | return Flookup_key (map, keys, accept_default); | ||
| 1662 | } | ||
| 1663 | |||
| 1664 | /* GC is possible in this function if it autoloads a keymap. */ | ||
| 1665 | |||
| 1666 | DEFUN ("global-key-binding", Fglobal_key_binding, Sglobal_key_binding, 1, 2, 0, | ||
| 1667 | doc: /* Return the binding for command KEYS in current global keymap only. | ||
| 1668 | KEYS is a string or vector, a sequence of keystrokes. | ||
| 1669 | The binding is probably a symbol with a function definition. | ||
| 1670 | This function's return values are the same as those of `lookup-key' | ||
| 1671 | \(which see). | ||
| 1672 | |||
| 1673 | If optional argument ACCEPT-DEFAULT is non-nil, recognize default | ||
| 1674 | bindings; see the description of `lookup-key' for more details about this. */) | ||
| 1675 | (Lisp_Object keys, Lisp_Object accept_default) | ||
| 1676 | { | ||
| 1677 | return Flookup_key (current_global_map, keys, accept_default); | ||
| 1678 | } | ||
| 1679 | |||
| 1680 | /* GC is possible in this function if it autoloads a keymap. */ | ||
| 1681 | |||
| 1682 | DEFUN ("minor-mode-key-binding", Fminor_mode_key_binding, Sminor_mode_key_binding, 1, 2, 0, | 1649 | DEFUN ("minor-mode-key-binding", Fminor_mode_key_binding, Sminor_mode_key_binding, 1, 2, 0, |
| 1683 | doc: /* Find the visible minor mode bindings of KEY. | 1650 | doc: /* Find the visible minor mode bindings of KEY. |
| 1684 | Return an alist of pairs (MODENAME . BINDING), where MODENAME is | 1651 | Return an alist of pairs (MODENAME . BINDING), where MODENAME is |
| @@ -3253,8 +3220,6 @@ be preferred. */); | |||
| 3253 | defsubr (&Scopy_keymap); | 3220 | defsubr (&Scopy_keymap); |
| 3254 | defsubr (&Scommand_remapping); | 3221 | defsubr (&Scommand_remapping); |
| 3255 | defsubr (&Skey_binding); | 3222 | defsubr (&Skey_binding); |
| 3256 | defsubr (&Slocal_key_binding); | ||
| 3257 | defsubr (&Sglobal_key_binding); | ||
| 3258 | defsubr (&Sminor_mode_key_binding); | 3223 | defsubr (&Sminor_mode_key_binding); |
| 3259 | defsubr (&Sdefine_key); | 3224 | defsubr (&Sdefine_key); |
| 3260 | defsubr (&Slookup_key); | 3225 | defsubr (&Slookup_key); |
diff --git a/src/lisp.h b/src/lisp.h index d139df93424..f6588685443 100644 --- a/src/lisp.h +++ b/src/lisp.h | |||
| @@ -4346,9 +4346,12 @@ extern Lisp_Object Vminibuffer_list; | |||
| 4346 | extern Lisp_Object last_minibuf_string; | 4346 | extern Lisp_Object last_minibuf_string; |
| 4347 | extern void move_minibuffer_onto_frame (void); | 4347 | extern void move_minibuffer_onto_frame (void); |
| 4348 | extern bool is_minibuffer (EMACS_INT, Lisp_Object); | 4348 | extern bool is_minibuffer (EMACS_INT, Lisp_Object); |
| 4349 | extern EMACS_INT this_minibuffer_depth (Lisp_Object); | ||
| 4350 | extern EMACS_INT minibuf_level; | ||
| 4349 | extern Lisp_Object get_minibuffer (EMACS_INT); | 4351 | extern Lisp_Object get_minibuffer (EMACS_INT); |
| 4350 | extern void init_minibuf_once (void); | 4352 | extern void init_minibuf_once (void); |
| 4351 | extern void syms_of_minibuf (void); | 4353 | extern void syms_of_minibuf (void); |
| 4354 | extern void barf_if_interaction_inhibited (void); | ||
| 4352 | 4355 | ||
| 4353 | /* Defined in callint.c. */ | 4356 | /* Defined in callint.c. */ |
| 4354 | 4357 | ||
| @@ -4575,6 +4578,7 @@ extern AVOID emacs_abort (void) NO_INLINE; | |||
| 4575 | extern int emacs_fstatat (int, char const *, void *, int); | 4578 | extern int emacs_fstatat (int, char const *, void *, int); |
| 4576 | extern int emacs_openat (int, char const *, int, int); | 4579 | extern int emacs_openat (int, char const *, int, int); |
| 4577 | extern int emacs_open (const char *, int, int); | 4580 | extern int emacs_open (const char *, int, int); |
| 4581 | extern int emacs_open_noquit (const char *, int, int); | ||
| 4578 | extern int emacs_pipe (int[2]); | 4582 | extern int emacs_pipe (int[2]); |
| 4579 | extern int emacs_close (int); | 4583 | extern int emacs_close (int); |
| 4580 | extern ptrdiff_t emacs_read (int, void *, ptrdiff_t); | 4584 | extern ptrdiff_t emacs_read (int, void *, ptrdiff_t); |
diff --git a/src/lread.c b/src/lread.c index 1ff0828e85e..72b68df6631 100644 --- a/src/lread.c +++ b/src/lread.c | |||
| @@ -767,11 +767,16 @@ is used for reading a character. | |||
| 767 | If the optional argument SECONDS is non-nil, it should be a number | 767 | If the optional argument SECONDS is non-nil, it should be a number |
| 768 | specifying the maximum number of seconds to wait for input. If no | 768 | specifying the maximum number of seconds to wait for input. If no |
| 769 | input arrives in that time, return nil. SECONDS may be a | 769 | input arrives in that time, return nil. SECONDS may be a |
| 770 | floating-point value. */) | 770 | floating-point value. |
| 771 | |||
| 772 | If `inhibit-interaction' is non-nil, this function will signal an | ||
| 773 | `inhibited-interaction' error. */) | ||
| 771 | (Lisp_Object prompt, Lisp_Object inherit_input_method, Lisp_Object seconds) | 774 | (Lisp_Object prompt, Lisp_Object inherit_input_method, Lisp_Object seconds) |
| 772 | { | 775 | { |
| 773 | Lisp_Object val; | 776 | Lisp_Object val; |
| 774 | 777 | ||
| 778 | barf_if_interaction_inhibited (); | ||
| 779 | |||
| 775 | if (! NILP (prompt)) | 780 | if (! NILP (prompt)) |
| 776 | message_with_string ("%s", prompt, 0); | 781 | message_with_string ("%s", prompt, 0); |
| 777 | val = read_filtered_event (1, 1, 1, ! NILP (inherit_input_method), seconds); | 782 | val = read_filtered_event (1, 1, 1, ! NILP (inherit_input_method), seconds); |
| @@ -782,6 +787,12 @@ floating-point value. */) | |||
| 782 | 787 | ||
| 783 | DEFUN ("read-event", Fread_event, Sread_event, 0, 3, 0, | 788 | DEFUN ("read-event", Fread_event, Sread_event, 0, 3, 0, |
| 784 | doc: /* Read an event object from the input stream. | 789 | doc: /* Read an event object from the input stream. |
| 790 | |||
| 791 | If you want to read non-character events, consider calling `read-key' | ||
| 792 | instead. `read-key' will decode events via `input-decode-map' that | ||
| 793 | `read-event' will not. On a terminal this includes function keys such | ||
| 794 | as <F7> and <RIGHT>, or mouse events generated by `xterm-mouse-mode'. | ||
| 795 | |||
| 785 | If the optional argument PROMPT is non-nil, display that as a prompt. | 796 | If the optional argument PROMPT is non-nil, display that as a prompt. |
| 786 | If PROMPT is nil or the string \"\", the key sequence/events that led | 797 | If PROMPT is nil or the string \"\", the key sequence/events that led |
| 787 | to the current command is used as the prompt. | 798 | to the current command is used as the prompt. |
| @@ -793,9 +804,14 @@ is used for reading a character. | |||
| 793 | If the optional argument SECONDS is non-nil, it should be a number | 804 | If the optional argument SECONDS is non-nil, it should be a number |
| 794 | specifying the maximum number of seconds to wait for input. If no | 805 | specifying the maximum number of seconds to wait for input. If no |
| 795 | input arrives in that time, return nil. SECONDS may be a | 806 | input arrives in that time, return nil. SECONDS may be a |
| 796 | floating-point value. */) | 807 | floating-point value. |
| 808 | |||
| 809 | If `inhibit-interaction' is non-nil, this function will signal an | ||
| 810 | `inhibited-interaction' error. */) | ||
| 797 | (Lisp_Object prompt, Lisp_Object inherit_input_method, Lisp_Object seconds) | 811 | (Lisp_Object prompt, Lisp_Object inherit_input_method, Lisp_Object seconds) |
| 798 | { | 812 | { |
| 813 | barf_if_interaction_inhibited (); | ||
| 814 | |||
| 799 | if (! NILP (prompt)) | 815 | if (! NILP (prompt)) |
| 800 | message_with_string ("%s", prompt, 0); | 816 | message_with_string ("%s", prompt, 0); |
| 801 | return read_filtered_event (0, 0, 0, ! NILP (inherit_input_method), seconds); | 817 | return read_filtered_event (0, 0, 0, ! NILP (inherit_input_method), seconds); |
| @@ -822,11 +838,16 @@ is used for reading a character. | |||
| 822 | If the optional argument SECONDS is non-nil, it should be a number | 838 | If the optional argument SECONDS is non-nil, it should be a number |
| 823 | specifying the maximum number of seconds to wait for input. If no | 839 | specifying the maximum number of seconds to wait for input. If no |
| 824 | input arrives in that time, return nil. SECONDS may be a | 840 | input arrives in that time, return nil. SECONDS may be a |
| 825 | floating-point value. */) | 841 | floating-point value. |
| 826 | (Lisp_Object prompt, Lisp_Object inherit_input_method, Lisp_Object seconds) | 842 | |
| 843 | If `inhibit-interaction' is non-nil, this function will signal an | ||
| 844 | `inhibited-interaction' error. */) | ||
| 845 | (Lisp_Object prompt, Lisp_Object inherit_input_method, Lisp_Object seconds) | ||
| 827 | { | 846 | { |
| 828 | Lisp_Object val; | 847 | Lisp_Object val; |
| 829 | 848 | ||
| 849 | barf_if_interaction_inhibited (); | ||
| 850 | |||
| 830 | if (! NILP (prompt)) | 851 | if (! NILP (prompt)) |
| 831 | message_with_string ("%s", prompt, 0); | 852 | message_with_string ("%s", prompt, 0); |
| 832 | 853 | ||
diff --git a/src/minibuf.c b/src/minibuf.c index 5ee440f6622..5df10453739 100644 --- a/src/minibuf.c +++ b/src/minibuf.c | |||
| @@ -63,10 +63,31 @@ static Lisp_Object minibuf_prompt; | |||
| 63 | 63 | ||
| 64 | static ptrdiff_t minibuf_prompt_width; | 64 | static ptrdiff_t minibuf_prompt_width; |
| 65 | 65 | ||
| 66 | static Lisp_Object nth_minibuffer (EMACS_INT depth); | ||
| 67 | |||
| 66 | 68 | ||
| 69 | /* Return TRUE when a frame switch causes a minibuffer on the old | ||
| 70 | frame to move onto the new one. */ | ||
| 67 | static bool | 71 | static bool |
| 68 | minibuf_follows_frame (void) | 72 | minibuf_follows_frame (void) |
| 69 | { | 73 | { |
| 74 | return EQ (Fdefault_toplevel_value (Qminibuffer_follows_selected_frame), | ||
| 75 | Qt); | ||
| 76 | } | ||
| 77 | |||
| 78 | /* Return TRUE when a minibuffer always remains on the frame where it | ||
| 79 | was first invoked. */ | ||
| 80 | static bool | ||
| 81 | minibuf_stays_put (void) | ||
| 82 | { | ||
| 83 | return NILP (Fdefault_toplevel_value (Qminibuffer_follows_selected_frame)); | ||
| 84 | } | ||
| 85 | |||
| 86 | /* Return TRUE when opening a (recursive) minibuffer causes | ||
| 87 | minibuffers on other frames to move to the selected frame. */ | ||
| 88 | static bool | ||
| 89 | minibuf_moves_frame_when_opened (void) | ||
| 90 | { | ||
| 70 | return !NILP (Fdefault_toplevel_value (Qminibuffer_follows_selected_frame)); | 91 | return !NILP (Fdefault_toplevel_value (Qminibuffer_follows_selected_frame)); |
| 71 | } | 92 | } |
| 72 | 93 | ||
| @@ -90,7 +111,7 @@ choose_minibuf_frame (void) | |||
| 90 | minibuf_window = sf->minibuffer_window; | 111 | minibuf_window = sf->minibuffer_window; |
| 91 | /* If we've still got another minibuffer open, use its mini-window | 112 | /* If we've still got another minibuffer open, use its mini-window |
| 92 | instead. */ | 113 | instead. */ |
| 93 | if (minibuf_level && !minibuf_follows_frame ()) | 114 | if (minibuf_level > 1 && minibuf_stays_put ()) |
| 94 | { | 115 | { |
| 95 | Lisp_Object buffer = get_minibuffer (minibuf_level); | 116 | Lisp_Object buffer = get_minibuffer (minibuf_level); |
| 96 | Lisp_Object tail, frame; | 117 | Lisp_Object tail, frame; |
| @@ -105,26 +126,40 @@ choose_minibuf_frame (void) | |||
| 105 | } | 126 | } |
| 106 | } | 127 | } |
| 107 | 128 | ||
| 108 | if (minibuf_follows_frame ()) | 129 | if (minibuf_moves_frame_when_opened () |
| 130 | && FRAMEP (selected_frame) | ||
| 131 | && FRAME_LIVE_P (XFRAME (selected_frame))) | ||
| 109 | /* Make sure no other frame has a minibuffer as its selected window, | 132 | /* Make sure no other frame has a minibuffer as its selected window, |
| 110 | because the text would not be displayed in it, and that would be | 133 | because the text would not be displayed in it, and that would be |
| 111 | confusing. Only allow the selected frame to do this, | 134 | confusing. Only allow the selected frame to do this, |
| 112 | and that only if the minibuffer is active. */ | 135 | and that only if the minibuffer is active. */ |
| 113 | { | 136 | { |
| 114 | Lisp_Object tail, frame; | 137 | Lisp_Object tail, frame; |
| 115 | 138 | struct frame *of; | |
| 116 | FOR_EACH_FRAME (tail, frame) | 139 | |
| 117 | if (MINI_WINDOW_P (XWINDOW (FRAME_SELECTED_WINDOW (XFRAME (frame)))) | 140 | FOR_EACH_FRAME (tail, frame) |
| 118 | && !(EQ (frame, selected_frame) | 141 | if (!EQ (frame, selected_frame) |
| 119 | && minibuf_level > 0)) | 142 | && minibuf_level > 1 |
| 120 | Fset_frame_selected_window (frame, Fframe_first_window (frame), | 143 | /* The frame's minibuffer can be on a different frame. */ |
| 121 | Qnil); | 144 | && ! EQ (XWINDOW ((of = XFRAME (frame))->minibuffer_window)->frame, |
| 122 | } | 145 | selected_frame)) |
| 146 | { | ||
| 147 | if (MINI_WINDOW_P (XWINDOW (FRAME_SELECTED_WINDOW (of)))) | ||
| 148 | Fset_frame_selected_window (frame, Fframe_first_window (frame), | ||
| 149 | Qnil); | ||
| 150 | |||
| 151 | if (!EQ (XWINDOW (of->minibuffer_window)->contents, | ||
| 152 | nth_minibuffer (0))) | ||
| 153 | set_window_buffer (of->minibuffer_window, | ||
| 154 | nth_minibuffer (0), 0, 0); | ||
| 155 | } | ||
| 156 | } | ||
| 123 | } | 157 | } |
| 124 | 158 | ||
| 125 | /* If `minibuffer_follows_selected_frame' and we have a minibuffer, move it | 159 | /* If `minibuffer_follows_selected_frame' is t and we have a |
| 126 | from its current frame to the selected frame. This function is | 160 | minibuffer, move it from its current frame to the selected frame. |
| 127 | intended to be called from `do_switch_frame' in frame.c. */ | 161 | This function is intended to be called from `do_switch_frame' in |
| 162 | frame.c. */ | ||
| 128 | void move_minibuffer_onto_frame (void) | 163 | void move_minibuffer_onto_frame (void) |
| 129 | { | 164 | { |
| 130 | if (!minibuf_level) | 165 | if (!minibuf_level) |
| @@ -135,14 +170,18 @@ void move_minibuffer_onto_frame (void) | |||
| 135 | && FRAME_LIVE_P (XFRAME (selected_frame)) | 170 | && FRAME_LIVE_P (XFRAME (selected_frame)) |
| 136 | && !EQ (minibuf_window, XFRAME (selected_frame)->minibuffer_window)) | 171 | && !EQ (minibuf_window, XFRAME (selected_frame)->minibuffer_window)) |
| 137 | { | 172 | { |
| 173 | EMACS_INT i; | ||
| 138 | struct frame *sf = XFRAME (selected_frame); | 174 | struct frame *sf = XFRAME (selected_frame); |
| 139 | Lisp_Object old_frame = XWINDOW (minibuf_window)->frame; | 175 | Lisp_Object old_frame = XWINDOW (minibuf_window)->frame; |
| 140 | struct frame *of = XFRAME (old_frame); | 176 | struct frame *of = XFRAME (old_frame); |
| 141 | Lisp_Object buffer = XWINDOW (minibuf_window)->contents; | ||
| 142 | 177 | ||
| 143 | set_window_buffer (sf->minibuffer_window, buffer, 0, 0); | 178 | /* Stack up all the (recursively) open minibuffers on the selected |
| 179 | mini_window. */ | ||
| 180 | for (i = 1; i <= minibuf_level; i++) | ||
| 181 | set_window_buffer (sf->minibuffer_window, nth_minibuffer (i), 0, 0); | ||
| 144 | minibuf_window = sf->minibuffer_window; | 182 | minibuf_window = sf->minibuffer_window; |
| 145 | set_window_buffer (of->minibuffer_window, get_minibuffer (0), 0, 0); | 183 | if (of != sf) |
| 184 | set_window_buffer (of->minibuffer_window, get_minibuffer (0), 0, 0); | ||
| 146 | } | 185 | } |
| 147 | } | 186 | } |
| 148 | 187 | ||
| @@ -336,6 +375,63 @@ return t only if BUFFER is an active minibuffer. */) | |||
| 336 | ? Qt : Qnil; | 375 | ? Qt : Qnil; |
| 337 | } | 376 | } |
| 338 | 377 | ||
| 378 | DEFUN ("innermost-minibuffer-p", Finnermost_minibuffer_p, | ||
| 379 | Sinnermost_minibuffer_p, 0, 1, 0, | ||
| 380 | doc: /* Return t if BUFFER is the most nested active minibuffer. | ||
| 381 | No argument or nil as argument means use the current buffer as BUFFER. */) | ||
| 382 | (Lisp_Object buffer) | ||
| 383 | { | ||
| 384 | if (NILP (buffer)) | ||
| 385 | buffer = Fcurrent_buffer (); | ||
| 386 | return EQ (buffer, (Fcar (Fnthcdr (make_fixnum (minibuf_level), | ||
| 387 | Vminibuffer_list)))) | ||
| 388 | ? Qt | ||
| 389 | : Qnil; | ||
| 390 | } | ||
| 391 | |||
| 392 | /* Return the nesting depth of the active minibuffer BUFFER, or 0 if | ||
| 393 | BUFFER isn't such a thing. If BUFFER is nil, this means use the current | ||
| 394 | buffer. */ | ||
| 395 | EMACS_INT | ||
| 396 | this_minibuffer_depth (Lisp_Object buffer) | ||
| 397 | { | ||
| 398 | EMACS_INT i; | ||
| 399 | Lisp_Object bufs; | ||
| 400 | |||
| 401 | if (NILP (buffer)) | ||
| 402 | buffer = Fcurrent_buffer (); | ||
| 403 | for (i = 1, bufs = Fcdr (Vminibuffer_list); | ||
| 404 | i <= minibuf_level; | ||
| 405 | i++, bufs = Fcdr (bufs)) | ||
| 406 | if (EQ (Fcar (bufs), buffer)) | ||
| 407 | return i; | ||
| 408 | return 0; | ||
| 409 | } | ||
| 410 | |||
| 411 | DEFUN ("abort-minibuffers", Fabort_minibuffers, Sabort_minibuffers, 0, 0, "", | ||
| 412 | doc: /* Abort the current minibuffer. | ||
| 413 | If we are not currently in the innermost minibuffer, prompt the user to | ||
| 414 | confirm the aborting of the current minibuffer and all contained ones. */) | ||
| 415 | (void) | ||
| 416 | { | ||
| 417 | EMACS_INT minibuf_depth = this_minibuffer_depth (Qnil); | ||
| 418 | Lisp_Object array[2]; | ||
| 419 | AUTO_STRING (fmt, "Abort %s minibuffer levels? "); | ||
| 420 | |||
| 421 | if (!minibuf_depth) | ||
| 422 | error ("Not in a minibuffer"); | ||
| 423 | if (minibuf_depth < minibuf_level) | ||
| 424 | { | ||
| 425 | array[0] = fmt; | ||
| 426 | array[1] = make_fixnum (minibuf_level - minibuf_depth + 1); | ||
| 427 | if (!NILP (Fyes_or_no_p (Fformat (2, array)))) | ||
| 428 | Fthrow (Qexit, Qt); | ||
| 429 | } | ||
| 430 | else | ||
| 431 | Fthrow (Qexit, Qt); | ||
| 432 | return Qnil; | ||
| 433 | } | ||
| 434 | |||
| 339 | DEFUN ("minibuffer-prompt-end", Fminibuffer_prompt_end, | 435 | DEFUN ("minibuffer-prompt-end", Fminibuffer_prompt_end, |
| 340 | Sminibuffer_prompt_end, 0, 0, 0, | 436 | Sminibuffer_prompt_end, 0, 0, 0, |
| 341 | doc: /* Return the buffer position of the end of the minibuffer prompt. | 437 | doc: /* Return the buffer position of the end of the minibuffer prompt. |
| @@ -411,6 +507,7 @@ read_minibuf (Lisp_Object map, Lisp_Object initial, Lisp_Object prompt, | |||
| 411 | Lisp_Object val; | 507 | Lisp_Object val; |
| 412 | ptrdiff_t count = SPECPDL_INDEX (); | 508 | ptrdiff_t count = SPECPDL_INDEX (); |
| 413 | Lisp_Object mini_frame, ambient_dir, minibuffer, input_method; | 509 | Lisp_Object mini_frame, ambient_dir, minibuffer, input_method; |
| 510 | Lisp_Object calling_frame = selected_frame; | ||
| 414 | Lisp_Object enable_multibyte; | 511 | Lisp_Object enable_multibyte; |
| 415 | EMACS_INT pos = 0; | 512 | EMACS_INT pos = 0; |
| 416 | /* String to add to the history. */ | 513 | /* String to add to the history. */ |
| @@ -648,6 +745,17 @@ read_minibuf (Lisp_Object map, Lisp_Object initial, Lisp_Object prompt, | |||
| 648 | } | 745 | } |
| 649 | } | 746 | } |
| 650 | 747 | ||
| 748 | if (minibuf_moves_frame_when_opened ()) | ||
| 749 | { | ||
| 750 | EMACS_INT i; | ||
| 751 | |||
| 752 | /* Stack up all the (recursively) open minibuffers on the selected | ||
| 753 | mini_window. */ | ||
| 754 | for (i = 1; i < minibuf_level; i++) | ||
| 755 | set_window_buffer (XFRAME (mini_frame)->minibuffer_window, | ||
| 756 | nth_minibuffer (i), 0, 0); | ||
| 757 | } | ||
| 758 | |||
| 651 | /* Display this minibuffer in the proper window. */ | 759 | /* Display this minibuffer in the proper window. */ |
| 652 | /* Use set_window_buffer instead of Fset_window_buffer (see | 760 | /* Use set_window_buffer instead of Fset_window_buffer (see |
| 653 | discussion of bug#11984, bug#12025, bug#12026). */ | 761 | discussion of bug#11984, bug#12025, bug#12026). */ |
| @@ -729,6 +837,20 @@ read_minibuf (Lisp_Object map, Lisp_Object initial, Lisp_Object prompt, | |||
| 729 | 837 | ||
| 730 | recursive_edit_1 (); | 838 | recursive_edit_1 (); |
| 731 | 839 | ||
| 840 | /* We've exited the recursive edit without an error, so switch the | ||
| 841 | current window away from the expired minibuffer window. */ | ||
| 842 | { | ||
| 843 | Lisp_Object prev = Fprevious_window (minibuf_window, Qnil, Qnil); | ||
| 844 | /* PREV can be on a different frame when we have a minibuffer only | ||
| 845 | frame, the other frame's minibuffer window is MINIBUF_WINDOW, | ||
| 846 | and its "focus window" is also MINIBUF_WINDOW. */ | ||
| 847 | while (!EQ (prev, minibuf_window) | ||
| 848 | && !EQ (selected_frame, WINDOW_FRAME (XWINDOW (prev)))) | ||
| 849 | prev = Fprevious_window (prev, Qnil, Qnil); | ||
| 850 | if (!EQ (prev, minibuf_window)) | ||
| 851 | Fset_frame_selected_window (selected_frame, prev, Qnil); | ||
| 852 | } | ||
| 853 | |||
| 732 | /* If cursor is on the minibuffer line, | 854 | /* If cursor is on the minibuffer line, |
| 733 | show the user we have exited by putting it in column 0. */ | 855 | show the user we have exited by putting it in column 0. */ |
| 734 | if (XWINDOW (minibuf_window)->cursor.vpos >= 0 | 856 | if (XWINDOW (minibuf_window)->cursor.vpos >= 0 |
| @@ -767,6 +889,12 @@ read_minibuf (Lisp_Object map, Lisp_Object initial, Lisp_Object prompt, | |||
| 767 | in set-window-configuration. */ | 889 | in set-window-configuration. */ |
| 768 | unbind_to (count, Qnil); | 890 | unbind_to (count, Qnil); |
| 769 | 891 | ||
| 892 | /* Switch the frame back to the calling frame. */ | ||
| 893 | if (!EQ (selected_frame, calling_frame) | ||
| 894 | && FRAMEP (calling_frame) | ||
| 895 | && FRAME_LIVE_P (XFRAME (calling_frame))) | ||
| 896 | call2 (intern ("select-frame-set-input-focus"), calling_frame, Qnil); | ||
| 897 | |||
| 770 | /* Add the value to the appropriate history list, if any. This is | 898 | /* Add the value to the appropriate history list, if any. This is |
| 771 | done after the previous buffer has been made current again, in | 899 | done after the previous buffer has been made current again, in |
| 772 | case the history variable is buffer-local. */ | 900 | case the history variable is buffer-local. */ |
| @@ -790,6 +918,14 @@ is_minibuffer (EMACS_INT depth, Lisp_Object buf) | |||
| 790 | && EQ (Fcar (tail), buf); | 918 | && EQ (Fcar (tail), buf); |
| 791 | } | 919 | } |
| 792 | 920 | ||
| 921 | /* Return the DEPTHth minibuffer, or nil if such does not yet exist. */ | ||
| 922 | static Lisp_Object | ||
| 923 | nth_minibuffer (EMACS_INT depth) | ||
| 924 | { | ||
| 925 | Lisp_Object tail = Fnthcdr (make_fixnum (depth), Vminibuffer_list); | ||
| 926 | return XCAR (tail); | ||
| 927 | } | ||
| 928 | |||
| 793 | /* Return a buffer to be used as the minibuffer at depth `depth'. | 929 | /* Return a buffer to be used as the minibuffer at depth `depth'. |
| 794 | depth = 0 is the lowest allowed argument, and that is the value | 930 | depth = 0 is the lowest allowed argument, and that is the value |
| 795 | used for nonrecursive minibuffer invocations. */ | 931 | used for nonrecursive minibuffer invocations. */ |
| @@ -939,6 +1075,13 @@ read_minibuf_unwind (void) | |||
| 939 | } | 1075 | } |
| 940 | 1076 | ||
| 941 | 1077 | ||
| 1078 | void | ||
| 1079 | barf_if_interaction_inhibited (void) | ||
| 1080 | { | ||
| 1081 | if (inhibit_interaction) | ||
| 1082 | xsignal0 (Qinhibited_interaction); | ||
| 1083 | } | ||
| 1084 | |||
| 942 | DEFUN ("read-from-minibuffer", Fread_from_minibuffer, | 1085 | DEFUN ("read-from-minibuffer", Fread_from_minibuffer, |
| 943 | Sread_from_minibuffer, 1, 7, 0, | 1086 | Sread_from_minibuffer, 1, 7, 0, |
| 944 | doc: /* Read a string from the minibuffer, prompting with string PROMPT. | 1087 | doc: /* Read a string from the minibuffer, prompting with string PROMPT. |
| @@ -983,6 +1126,9 @@ If the variable `minibuffer-allow-text-properties' is non-nil, | |||
| 983 | then the string which is returned includes whatever text properties | 1126 | then the string which is returned includes whatever text properties |
| 984 | were present in the minibuffer. Otherwise the value has no text properties. | 1127 | were present in the minibuffer. Otherwise the value has no text properties. |
| 985 | 1128 | ||
| 1129 | If `inhibit-interaction' is non-nil, this function will signal an | ||
| 1130 | `inhibited-interaction' error. | ||
| 1131 | |||
| 986 | The remainder of this documentation string describes the | 1132 | The remainder of this documentation string describes the |
| 987 | INITIAL-CONTENTS argument in more detail. It is only relevant when | 1133 | INITIAL-CONTENTS argument in more detail. It is only relevant when |
| 988 | studying existing code, or when HIST is a cons. If non-nil, | 1134 | studying existing code, or when HIST is a cons. If non-nil, |
| @@ -998,6 +1144,8 @@ and some related functions, which use zero-indexing for POSITION. */) | |||
| 998 | { | 1144 | { |
| 999 | Lisp_Object histvar, histpos, val; | 1145 | Lisp_Object histvar, histpos, val; |
| 1000 | 1146 | ||
| 1147 | barf_if_interaction_inhibited (); | ||
| 1148 | |||
| 1001 | CHECK_STRING (prompt); | 1149 | CHECK_STRING (prompt); |
| 1002 | if (NILP (keymap)) | 1150 | if (NILP (keymap)) |
| 1003 | keymap = Vminibuffer_local_map; | 1151 | keymap = Vminibuffer_local_map; |
| @@ -1071,11 +1219,17 @@ point positioned at the end, so that SPACE will accept the input. | |||
| 1071 | \(Actually, INITIAL can also be a cons of a string and an integer. | 1219 | \(Actually, INITIAL can also be a cons of a string and an integer. |
| 1072 | Such values are treated as in `read-from-minibuffer', but are normally | 1220 | Such values are treated as in `read-from-minibuffer', but are normally |
| 1073 | not useful in this function.) | 1221 | not useful in this function.) |
| 1222 | |||
| 1074 | Third arg INHERIT-INPUT-METHOD, if non-nil, means the minibuffer inherits | 1223 | Third arg INHERIT-INPUT-METHOD, if non-nil, means the minibuffer inherits |
| 1075 | the current input method and the setting of`enable-multibyte-characters'. */) | 1224 | the current input method and the setting of`enable-multibyte-characters'. |
| 1225 | |||
| 1226 | If `inhibit-interaction' is non-nil, this function will signal an | ||
| 1227 | `inhibited-interaction' error. */) | ||
| 1076 | (Lisp_Object prompt, Lisp_Object initial, Lisp_Object inherit_input_method) | 1228 | (Lisp_Object prompt, Lisp_Object initial, Lisp_Object inherit_input_method) |
| 1077 | { | 1229 | { |
| 1078 | CHECK_STRING (prompt); | 1230 | CHECK_STRING (prompt); |
| 1231 | barf_if_interaction_inhibited (); | ||
| 1232 | |||
| 1079 | return read_minibuf (Vminibuffer_local_ns_map, initial, prompt, | 1233 | return read_minibuf (Vminibuffer_local_ns_map, initial, prompt, |
| 1080 | 0, Qminibuffer_history, make_fixnum (0), Qnil, 0, | 1234 | 0, Qminibuffer_history, make_fixnum (0), Qnil, 0, |
| 1081 | !NILP (inherit_input_method)); | 1235 | !NILP (inherit_input_method)); |
| @@ -2032,13 +2186,15 @@ For example, `eval-expression' uses this. */); | |||
| 2032 | The function is called with the arguments passed to `read-buffer'. */); | 2186 | The function is called with the arguments passed to `read-buffer'. */); |
| 2033 | Vread_buffer_function = Qnil; | 2187 | Vread_buffer_function = Qnil; |
| 2034 | 2188 | ||
| 2035 | DEFVAR_BOOL ("minibuffer-follows-selected-frame", minibuffer_follows_selected_frame, | 2189 | DEFVAR_LISP ("minibuffer-follows-selected-frame", minibuffer_follows_selected_frame, |
| 2036 | doc: /* Non-nil means the active minibuffer always displays on the selected frame. | 2190 | doc: /* t means the active minibuffer always displays on the selected frame. |
| 2037 | Nil means that a minibuffer will appear only in the frame which created it. | 2191 | Nil means that a minibuffer will appear only in the frame which created it. |
| 2192 | Any other value means the minibuffer will move onto another frame, but | ||
| 2193 | only when the user starts using a minibuffer there. | ||
| 2038 | 2194 | ||
| 2039 | Any buffer local or dynamic binding of this variable is ignored. Only the | 2195 | Any buffer local or dynamic binding of this variable is ignored. Only the |
| 2040 | default top level value is used. */); | 2196 | default top level value is used. */); |
| 2041 | minibuffer_follows_selected_frame = 1; | 2197 | minibuffer_follows_selected_frame = Qt; |
| 2042 | 2198 | ||
| 2043 | DEFVAR_BOOL ("read-buffer-completion-ignore-case", | 2199 | DEFVAR_BOOL ("read-buffer-completion-ignore-case", |
| 2044 | read_buffer_completion_ignore_case, | 2200 | read_buffer_completion_ignore_case, |
| @@ -2183,6 +2339,15 @@ This variable also overrides the default character that `read-passwd' | |||
| 2183 | uses to hide passwords. */); | 2339 | uses to hide passwords. */); |
| 2184 | Vread_hide_char = Qnil; | 2340 | Vread_hide_char = Qnil; |
| 2185 | 2341 | ||
| 2342 | DEFVAR_BOOL ("inhibit-interaction", | ||
| 2343 | inhibit_interaction, | ||
| 2344 | doc: /* Non-nil means any user interaction will signal an error. | ||
| 2345 | This variable can be bound when user interaction can't be performed, | ||
| 2346 | for instance when running a headless Emacs server. Functions like | ||
| 2347 | `read-from-minibuffer' (and the like) will signal `inhibited-interaction' | ||
| 2348 | instead. */); | ||
| 2349 | inhibit_interaction = 0; | ||
| 2350 | |||
| 2186 | defsubr (&Sactive_minibuffer_window); | 2351 | defsubr (&Sactive_minibuffer_window); |
| 2187 | defsubr (&Sset_minibuffer_window); | 2352 | defsubr (&Sset_minibuffer_window); |
| 2188 | defsubr (&Sread_from_minibuffer); | 2353 | defsubr (&Sread_from_minibuffer); |
| @@ -2196,6 +2361,8 @@ uses to hide passwords. */); | |||
| 2196 | defsubr (&Sminibuffer_prompt); | 2361 | defsubr (&Sminibuffer_prompt); |
| 2197 | 2362 | ||
| 2198 | defsubr (&Sminibufferp); | 2363 | defsubr (&Sminibufferp); |
| 2364 | defsubr (&Sinnermost_minibuffer_p); | ||
| 2365 | defsubr (&Sabort_minibuffers); | ||
| 2199 | defsubr (&Sminibuffer_prompt_end); | 2366 | defsubr (&Sminibuffer_prompt_end); |
| 2200 | defsubr (&Sminibuffer_contents); | 2367 | defsubr (&Sminibuffer_contents); |
| 2201 | defsubr (&Sminibuffer_contents_no_properties); | 2368 | defsubr (&Sminibuffer_contents_no_properties); |
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; | |||
| 39 | typedef float EmacsCGFloat; | 39 | typedef 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..c5815ce8d10 100644 --- a/src/nsterm.m +++ b/src/nsterm.m | |||
| @@ -5602,7 +5602,11 @@ ns_term_init (Lisp_Object display_name) | |||
| 5602 | ns_drag_types = [[NSArray arrayWithObjects: | 5602 | ns_drag_types = [[NSArray arrayWithObjects: |
| 5603 | NSPasteboardTypeString, | 5603 | NSPasteboardTypeString, |
| 5604 | NSPasteboardTypeTabularText, | 5604 | NSPasteboardTypeTabularText, |
| 5605 | #if NS_USE_NSPasteboardTypeFileURL != 0 | ||
| 5606 | NSPasteboardTypeFileURL, | ||
| 5607 | #else | ||
| 5605 | NSFilenamesPboardType, | 5608 | NSFilenamesPboardType, |
| 5609 | #endif | ||
| 5606 | NSPasteboardTypeURL, nil] retain]; | 5610 | NSPasteboardTypeURL, nil] retain]; |
| 5607 | 5611 | ||
| 5608 | /* If fullscreen is in init/default-frame-alist, focus isn't set | 5612 | /* If fullscreen is in init/default-frame-alist, focus isn't set |
| @@ -8533,9 +8537,19 @@ not_in_argv (NSString *arg) | |||
| 8533 | { | 8537 | { |
| 8534 | return NO; | 8538 | return NO; |
| 8535 | } | 8539 | } |
| 8536 | /* FIXME: NSFilenamesPboardType is deprecated in 10.14, but the | 8540 | #if NS_USE_NSPasteboardTypeFileURL != 0 |
| 8537 | NSURL method can only handle one file at a time. Stick with the | 8541 | else if ([type isEqualToString: NSPasteboardTypeFileURL]) |
| 8538 | existing code at the moment. */ | 8542 | { |
| 8543 | type_sym = Qfile; | ||
| 8544 | |||
| 8545 | NSArray *urls = [pb readObjectsForClasses: @[[NSURL self]] | ||
| 8546 | options: nil]; | ||
| 8547 | NSEnumerator *uenum = [urls objectEnumerator]; | ||
| 8548 | NSURL *url; | ||
| 8549 | while ((url = [uenum nextObject])) | ||
| 8550 | strings = Fcons ([[url path] lispString], strings); | ||
| 8551 | } | ||
| 8552 | #else // !NS_USE_NSPasteboardTypeFileURL | ||
| 8539 | else if ([type isEqualToString: NSFilenamesPboardType]) | 8553 | else if ([type isEqualToString: NSFilenamesPboardType]) |
| 8540 | { | 8554 | { |
| 8541 | NSArray *files; | 8555 | NSArray *files; |
| @@ -8551,6 +8565,7 @@ not_in_argv (NSString *arg) | |||
| 8551 | while ( (file = [fenum nextObject]) ) | 8565 | while ( (file = [fenum nextObject]) ) |
| 8552 | strings = Fcons ([file lispString], strings); | 8566 | strings = Fcons ([file lispString], strings); |
| 8553 | } | 8567 | } |
| 8568 | #endif // !NS_USE_NSPasteboardTypeFileURL | ||
| 8554 | else if ([type isEqualToString: NSPasteboardTypeURL]) | 8569 | else if ([type isEqualToString: NSPasteboardTypeURL]) |
| 8555 | { | 8570 | { |
| 8556 | NSURL *url = [NSURL URLFromPasteboard: pb]; | 8571 | NSURL *url = [NSURL URLFromPasteboard: pb]; |
diff --git a/src/pdumper.c b/src/pdumper.c index 116cc28dbba..c1388ebbb37 100644 --- a/src/pdumper.c +++ b/src/pdumper.c | |||
| @@ -5273,7 +5273,7 @@ pdumper_load (const char *dump_filename) | |||
| 5273 | eassert (!dump_loaded_p ()); | 5273 | eassert (!dump_loaded_p ()); |
| 5274 | 5274 | ||
| 5275 | int err; | 5275 | int err; |
| 5276 | int dump_fd = emacs_open (dump_filename, O_RDONLY, 0); | 5276 | int dump_fd = emacs_open_noquit (dump_filename, O_RDONLY, 0); |
| 5277 | if (dump_fd < 0) | 5277 | if (dump_fd < 0) |
| 5278 | { | 5278 | { |
| 5279 | err = (errno == ENOENT || errno == ENOTDIR | 5279 | err = (errno == ENOENT || errno == ENOTDIR |
diff --git a/src/process.c b/src/process.c index 25883f911f1..4ab194b2b5b 100644 --- a/src/process.c +++ b/src/process.c | |||
| @@ -283,6 +283,16 @@ 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. */ |
| 284 | static int external_sock_fd; | 284 | static int external_sock_fd; |
| 285 | 285 | ||
| 286 | /* File descriptor that becomes readable when we receive SIGCHLD. */ | ||
| 287 | static 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. */ | ||
| 291 | static int child_signal_write_fd = -1; | ||
| 292 | static void child_signal_init (void); | ||
| 293 | static void child_signal_read (int, void *); | ||
| 294 | static void child_signal_notify (void); | ||
| 295 | |||
| 286 | /* Indexed by descriptor, gives the process (if any) for that descriptor. */ | 296 | /* Indexed by descriptor, gives the process (if any) for that descriptor. */ |
| 287 | static Lisp_Object chan_process[FD_SETSIZE]; | 297 | static Lisp_Object chan_process[FD_SETSIZE]; |
| 288 | static void wait_for_socket_fds (Lisp_Object, char const *); | 298 | static void wait_for_socket_fds (Lisp_Object, char const *); |
| @@ -2060,6 +2070,10 @@ create_process (Lisp_Object process, char **new_argv, Lisp_Object current_dir) | |||
| 2060 | Lisp_Object lisp_pty_name = Qnil; | 2070 | Lisp_Object lisp_pty_name = Qnil; |
| 2061 | sigset_t oldset; | 2071 | sigset_t oldset; |
| 2062 | 2072 | ||
| 2073 | /* Ensure that the SIGCHLD handler can notify | ||
| 2074 | `wait_reading_process_output'. */ | ||
| 2075 | child_signal_init (); | ||
| 2076 | |||
| 2063 | inchannel = outchannel = -1; | 2077 | inchannel = outchannel = -1; |
| 2064 | 2078 | ||
| 2065 | if (p->pty_flag) | 2079 | if (p->pty_flag) |
| @@ -5309,6 +5323,15 @@ wait_reading_process_output (intmax_t time_limit, int nsecs, int read_kbd, | |||
| 5309 | compute_input_wait_mask (&Atemp); | 5323 | compute_input_wait_mask (&Atemp); |
| 5310 | compute_write_mask (&Ctemp); | 5324 | compute_write_mask (&Ctemp); |
| 5311 | 5325 | ||
| 5326 | /* If a process status has changed, the child signal pipe | ||
| 5327 | will likely be readable. We want to ignore it for now, | ||
| 5328 | because otherwise we wouldn't run into a timeout | ||
| 5329 | below. */ | ||
| 5330 | int fd = child_signal_read_fd; | ||
| 5331 | eassert (fd < FD_SETSIZE); | ||
| 5332 | if (0 <= fd) | ||
| 5333 | FD_CLR (fd, &Atemp); | ||
| 5334 | |||
| 5312 | timeout = make_timespec (0, 0); | 5335 | timeout = make_timespec (0, 0); |
| 5313 | if ((thread_select (pselect, max_desc + 1, | 5336 | if ((thread_select (pselect, max_desc + 1, |
| 5314 | &Atemp, | 5337 | &Atemp, |
| @@ -5395,6 +5418,14 @@ wait_reading_process_output (intmax_t time_limit, int nsecs, int read_kbd, | |||
| 5395 | check_write = true; | 5418 | check_write = true; |
| 5396 | } | 5419 | } |
| 5397 | 5420 | ||
| 5421 | /* We have to be informed when we receive a SIGCHLD signal for | ||
| 5422 | an asynchronous process. Otherwise this might deadlock if we | ||
| 5423 | receive a SIGCHLD during `pselect'. */ | ||
| 5424 | int child_fd = child_signal_read_fd; | ||
| 5425 | eassert (child_fd < FD_SETSIZE); | ||
| 5426 | if (0 <= child_fd) | ||
| 5427 | FD_SET (child_fd, &Available); | ||
| 5428 | |||
| 5398 | /* If frame size has changed or the window is newly mapped, | 5429 | /* If frame size has changed or the window is newly mapped, |
| 5399 | redisplay now, before we start to wait. There is a race | 5430 | redisplay now, before we start to wait. There is a race |
| 5400 | condition here; if a SIGIO arrives between now and the select | 5431 | condition here; if a SIGIO arrives between now and the select |
| @@ -7118,7 +7149,72 @@ process has been transmitted to the serial port. */) | |||
| 7118 | subprocesses which the main thread should not reap. For example, | 7149 | subprocesses which the main thread should not reap. For example, |
| 7119 | if the main thread attempted to reap an already-reaped child, it | 7150 | if the main thread attempted to reap an already-reaped child, it |
| 7120 | might inadvertently reap a GTK-created process that happened to | 7151 | might inadvertently reap a GTK-created process that happened to |
| 7121 | have the same process ID. */ | 7152 | have the same process ID. |
| 7153 | |||
| 7154 | To avoid a deadlock when receiving SIGCHLD while | ||
| 7155 | `wait_reading_process_output' is in `pselect', the SIGCHLD handler | ||
| 7156 | will notify the `pselect' using a pipe. */ | ||
| 7157 | |||
| 7158 | /* Set up `child_signal_read_fd' and `child_signal_write_fd'. */ | ||
| 7159 | |||
| 7160 | static void | ||
| 7161 | child_signal_init (void) | ||
| 7162 | { | ||
| 7163 | /* Either both are initialized, or both are uninitialized. */ | ||
| 7164 | eassert ((child_signal_read_fd < 0) == (child_signal_write_fd < 0)); | ||
| 7165 | |||
| 7166 | if (0 <= child_signal_read_fd) | ||
| 7167 | return; /* already done */ | ||
| 7168 | |||
| 7169 | int fds[2]; | ||
| 7170 | if (emacs_pipe (fds) < 0) | ||
| 7171 | report_file_error ("Creating pipe for child signal", Qnil); | ||
| 7172 | if (FD_SETSIZE <= fds[0]) | ||
| 7173 | { | ||
| 7174 | /* Since we need to `pselect' on the read end, it has to fit | ||
| 7175 | into an `fd_set'. */ | ||
| 7176 | emacs_close (fds[0]); | ||
| 7177 | emacs_close (fds[1]); | ||
| 7178 | report_file_errno ("Creating pipe for child signal", Qnil, | ||
| 7179 | EMFILE); | ||
| 7180 | } | ||
| 7181 | |||
| 7182 | /* We leave the file descriptors open until the Emacs process | ||
| 7183 | exits. */ | ||
| 7184 | eassert (0 <= fds[0]); | ||
| 7185 | eassert (0 <= fds[1]); | ||
| 7186 | if (fcntl (fds[0], F_SETFL, O_NONBLOCK) != 0) | ||
| 7187 | emacs_perror ("fcntl"); | ||
| 7188 | add_read_fd (fds[0], child_signal_read, NULL); | ||
| 7189 | fd_callback_info[fds[0]].flags &= ~KEYBOARD_FD; | ||
| 7190 | child_signal_read_fd = fds[0]; | ||
| 7191 | child_signal_write_fd = fds[1]; | ||
| 7192 | } | ||
| 7193 | |||
| 7194 | /* Consume a process status change. */ | ||
| 7195 | |||
| 7196 | static void | ||
| 7197 | child_signal_read (int fd, void *data) | ||
| 7198 | { | ||
| 7199 | eassert (0 <= fd); | ||
| 7200 | eassert (fd == child_signal_read_fd); | ||
| 7201 | char dummy; | ||
| 7202 | if (emacs_read (fd, &dummy, 1) < 0) | ||
| 7203 | emacs_perror ("reading from child signal FD"); | ||
| 7204 | } | ||
| 7205 | |||
| 7206 | /* Notify `wait_reading_process_output' of a process status | ||
| 7207 | change. */ | ||
| 7208 | |||
| 7209 | static void | ||
| 7210 | child_signal_notify (void) | ||
| 7211 | { | ||
| 7212 | int fd = child_signal_write_fd; | ||
| 7213 | eassert (0 <= fd); | ||
| 7214 | char dummy = 0; | ||
| 7215 | if (emacs_write (fd, &dummy, 1) != 1) | ||
| 7216 | emacs_perror ("writing to child signal FD"); | ||
| 7217 | } | ||
| 7122 | 7218 | ||
| 7123 | /* LIB_CHILD_HANDLER is a SIGCHLD handler that Emacs calls while doing | 7219 | /* LIB_CHILD_HANDLER is a SIGCHLD handler that Emacs calls while doing |
| 7124 | its own SIGCHLD handling. On POSIXish systems, glib needs this to | 7220 | its own SIGCHLD handling. On POSIXish systems, glib needs this to |
| @@ -7156,6 +7252,7 @@ static void | |||
| 7156 | handle_child_signal (int sig) | 7252 | handle_child_signal (int sig) |
| 7157 | { | 7253 | { |
| 7158 | Lisp_Object tail, proc; | 7254 | Lisp_Object tail, proc; |
| 7255 | bool changed = false; | ||
| 7159 | 7256 | ||
| 7160 | /* Find the process that signaled us, and record its status. */ | 7257 | /* Find the process that signaled us, and record its status. */ |
| 7161 | 7258 | ||
| @@ -7178,6 +7275,7 @@ handle_child_signal (int sig) | |||
| 7178 | eassert (ok); | 7275 | eassert (ok); |
| 7179 | if (child_status_changed (deleted_pid, 0, 0)) | 7276 | if (child_status_changed (deleted_pid, 0, 0)) |
| 7180 | { | 7277 | { |
| 7278 | changed = true; | ||
| 7181 | if (STRINGP (XCDR (head))) | 7279 | if (STRINGP (XCDR (head))) |
| 7182 | unlink (SSDATA (XCDR (head))); | 7280 | unlink (SSDATA (XCDR (head))); |
| 7183 | XSETCAR (tail, Qnil); | 7281 | XSETCAR (tail, Qnil); |
| @@ -7195,6 +7293,7 @@ handle_child_signal (int sig) | |||
| 7195 | && child_status_changed (p->pid, &status, WUNTRACED | WCONTINUED)) | 7293 | && child_status_changed (p->pid, &status, WUNTRACED | WCONTINUED)) |
| 7196 | { | 7294 | { |
| 7197 | /* Change the status of the process that was found. */ | 7295 | /* Change the status of the process that was found. */ |
| 7296 | changed = true; | ||
| 7198 | p->tick = ++process_tick; | 7297 | p->tick = ++process_tick; |
| 7199 | p->raw_status = status; | 7298 | p->raw_status = status; |
| 7200 | p->raw_status_new = 1; | 7299 | p->raw_status_new = 1; |
| @@ -7214,6 +7313,10 @@ handle_child_signal (int sig) | |||
| 7214 | } | 7313 | } |
| 7215 | } | 7314 | } |
| 7216 | 7315 | ||
| 7316 | if (changed) | ||
| 7317 | /* Wake up `wait_reading_process_output'. */ | ||
| 7318 | child_signal_notify (); | ||
| 7319 | |||
| 7217 | lib_child_handler (sig); | 7320 | lib_child_handler (sig); |
| 7218 | #ifdef NS_IMPL_GNUSTEP | 7321 | #ifdef NS_IMPL_GNUSTEP |
| 7219 | /* NSTask in GNUstep sets its child handler each time it is called. | 7322 | /* NSTask in GNUstep sets its child handler each time it is called. |
diff --git a/src/sysdep.c b/src/sysdep.c index 6ede06b1aa3..941b4e2fa24 100644 --- a/src/sysdep.c +++ b/src/sysdep.c | |||
| @@ -53,6 +53,10 @@ along with GNU Emacs. If not, see <https://www.gnu.org/licenses/>. */ | |||
| 53 | # include <sys/sysctl.h> | 53 | # include <sys/sysctl.h> |
| 54 | #endif | 54 | #endif |
| 55 | 55 | ||
| 56 | #if defined __OpenBSD__ | ||
| 57 | # include <sys/proc.h> | ||
| 58 | #endif | ||
| 59 | |||
| 56 | #ifdef DARWIN_OS | 60 | #ifdef DARWIN_OS |
| 57 | # include <libproc.h> | 61 | # include <libproc.h> |
| 58 | #endif | 62 | #endif |
| @@ -2316,6 +2320,28 @@ emacs_open (char const *file, int oflags, int mode) | |||
| 2316 | return emacs_openat (AT_FDCWD, file, oflags, mode); | 2320 | return emacs_openat (AT_FDCWD, file, oflags, mode); |
| 2317 | } | 2321 | } |
| 2318 | 2322 | ||
| 2323 | /* Same as above, but doesn't allow the user to quit. */ | ||
| 2324 | |||
| 2325 | static int | ||
| 2326 | emacs_openat_noquit (int dirfd, const char *file, int oflags, | ||
| 2327 | int mode) | ||
| 2328 | { | ||
| 2329 | int fd; | ||
| 2330 | if (! (oflags & O_TEXT)) | ||
| 2331 | oflags |= O_BINARY; | ||
| 2332 | oflags |= O_CLOEXEC; | ||
| 2333 | do | ||
| 2334 | fd = openat (dirfd, file, oflags, mode); | ||
| 2335 | while (fd < 0 && errno == EINTR); | ||
| 2336 | return fd; | ||
| 2337 | } | ||
| 2338 | |||
| 2339 | int | ||
| 2340 | emacs_open_noquit (char const *file, int oflags, int mode) | ||
| 2341 | { | ||
| 2342 | return emacs_openat_noquit (AT_FDCWD, file, oflags, mode); | ||
| 2343 | } | ||
| 2344 | |||
| 2319 | /* Open FILE as a stream for Emacs use, with mode MODE. | 2345 | /* Open FILE as a stream for Emacs use, with mode MODE. |
| 2320 | Act like emacs_open with respect to threads, signals, and quits. */ | 2346 | Act like emacs_open with respect to threads, signals, and quits. */ |
| 2321 | 2347 | ||
| @@ -2972,6 +2998,14 @@ make_lisp_timeval (struct timeval t) | |||
| 2972 | return make_lisp_time (timeval_to_timespec (t)); | 2998 | return make_lisp_time (timeval_to_timespec (t)); |
| 2973 | } | 2999 | } |
| 2974 | 3000 | ||
| 3001 | #elif defined __OpenBSD__ | ||
| 3002 | |||
| 3003 | static Lisp_Object | ||
| 3004 | make_lisp_timeval (long sec, long usec) | ||
| 3005 | { | ||
| 3006 | return make_lisp_time(make_timespec(sec, usec * 1000)); | ||
| 3007 | } | ||
| 3008 | |||
| 2975 | #endif | 3009 | #endif |
| 2976 | 3010 | ||
| 2977 | #ifdef GNU_LINUX | 3011 | #ifdef GNU_LINUX |
| @@ -3661,6 +3695,189 @@ system_process_attributes (Lisp_Object pid) | |||
| 3661 | return attrs; | 3695 | return attrs; |
| 3662 | } | 3696 | } |
| 3663 | 3697 | ||
| 3698 | #elif defined __OpenBSD__ | ||
| 3699 | |||
| 3700 | Lisp_Object | ||
| 3701 | system_process_attributes (Lisp_Object pid) | ||
| 3702 | { | ||
| 3703 | int proc_id, nentries, fscale, i; | ||
| 3704 | int pagesize = getpagesize (); | ||
| 3705 | int mib[6]; | ||
| 3706 | size_t len; | ||
| 3707 | double pct; | ||
| 3708 | char *ttyname, args[ARG_MAX]; | ||
| 3709 | struct kinfo_proc proc; | ||
| 3710 | struct passwd *pw; | ||
| 3711 | struct group *gr; | ||
| 3712 | struct timespec t; | ||
| 3713 | struct uvmexp uvmexp; | ||
| 3714 | |||
| 3715 | Lisp_Object attrs = Qnil; | ||
| 3716 | Lisp_Object decoded_comm; | ||
| 3717 | |||
| 3718 | CHECK_NUMBER (pid); | ||
| 3719 | CONS_TO_INTEGER (pid, int, proc_id); | ||
| 3720 | |||
| 3721 | len = sizeof proc; | ||
| 3722 | mib[0] = CTL_KERN; | ||
| 3723 | mib[1] = KERN_PROC; | ||
| 3724 | mib[2] = KERN_PROC_PID; | ||
| 3725 | mib[3] = proc_id; | ||
| 3726 | mib[4] = len; | ||
| 3727 | mib[5] = 1; | ||
| 3728 | if (sysctl (mib, 6, &proc, &len, NULL, 0) != 0) | ||
| 3729 | return attrs; | ||
| 3730 | |||
| 3731 | attrs = Fcons (Fcons (Qeuid, INT_TO_INTEGER (proc.p_uid)), attrs); | ||
| 3732 | |||
| 3733 | block_input (); | ||
| 3734 | pw = getpwuid (proc.p_uid); | ||
| 3735 | unblock_input (); | ||
| 3736 | if (pw) | ||
| 3737 | attrs = Fcons (Fcons (Quser, build_string(pw->pw_name)), attrs); | ||
| 3738 | |||
| 3739 | attrs = Fcons (Fcons (Qegid, INT_TO_INTEGER(proc.p_svgid)), attrs); | ||
| 3740 | |||
| 3741 | block_input (); | ||
| 3742 | gr = getgrgid (proc.p_svgid); | ||
| 3743 | unblock_input (); | ||
| 3744 | if (gr) | ||
| 3745 | attrs = Fcons (Fcons (Qgroup, build_string (gr->gr_name)), attrs); | ||
| 3746 | |||
| 3747 | AUTO_STRING (comm, proc.p_comm); | ||
| 3748 | decoded_comm = code_convert_string_norecord (comm, Vlocale_coding_system, 0); | ||
| 3749 | attrs = Fcons (Fcons (Qcomm, decoded_comm), attrs); | ||
| 3750 | |||
| 3751 | { | ||
| 3752 | char state[2] = {'\0', '\0'}; | ||
| 3753 | switch (proc.p_stat) { | ||
| 3754 | case SIDL: | ||
| 3755 | state[0] = 'I'; | ||
| 3756 | break; | ||
| 3757 | case SRUN: | ||
| 3758 | state[0] = 'R'; | ||
| 3759 | break; | ||
| 3760 | case SSLEEP: | ||
| 3761 | state[0] = 'S'; | ||
| 3762 | break; | ||
| 3763 | case SSTOP: | ||
| 3764 | state[0] = 'T'; | ||
| 3765 | break; | ||
| 3766 | case SZOMB: | ||
| 3767 | state[0] = 'Z'; | ||
| 3768 | break; | ||
| 3769 | case SDEAD: | ||
| 3770 | state[0] = 'D'; | ||
| 3771 | break; | ||
| 3772 | } | ||
| 3773 | attrs = Fcons (Fcons (Qstate, build_string (state)), attrs); | ||
| 3774 | } | ||
| 3775 | |||
| 3776 | attrs = Fcons (Fcons (Qppid, INT_TO_INTEGER (proc.p_ppid)), attrs); | ||
| 3777 | attrs = Fcons (Fcons (Qpgrp, INT_TO_INTEGER (proc.p_gid)), attrs); | ||
| 3778 | attrs = Fcons (Fcons (Qsess, INT_TO_INTEGER (proc.p_sid)), attrs); | ||
| 3779 | |||
| 3780 | block_input (); | ||
| 3781 | ttyname = proc.p_tdev == NODEV ? NULL : devname (proc.p_tdev, S_IFCHR); | ||
| 3782 | unblock_input (); | ||
| 3783 | if (ttyname) | ||
| 3784 | attrs = Fcons (Fcons (Qttname, build_string (ttyname)), attrs); | ||
| 3785 | |||
| 3786 | attrs = Fcons (Fcons (Qtpgid, INT_TO_INTEGER (proc.p_tpgid)), attrs); | ||
| 3787 | attrs = Fcons (Fcons (Qminflt, INT_TO_INTEGER (proc.p_uru_minflt)), | ||
| 3788 | attrs); | ||
| 3789 | attrs = Fcons (Fcons (Qmajflt, INT_TO_INTEGER (proc.p_uru_majflt)), | ||
| 3790 | attrs); | ||
| 3791 | |||
| 3792 | /* FIXME: missing cminflt, cmajflt. */ | ||
| 3793 | |||
| 3794 | attrs = Fcons (Fcons (Qutime, make_lisp_timeval (proc.p_uutime_sec, | ||
| 3795 | proc.p_uutime_usec)), | ||
| 3796 | attrs); | ||
| 3797 | attrs = Fcons (Fcons (Qstime, make_lisp_timeval (proc.p_ustime_sec, | ||
| 3798 | proc.p_ustime_usec)), | ||
| 3799 | attrs); | ||
| 3800 | t = timespec_add (make_timespec (proc.p_uutime_sec, | ||
| 3801 | proc.p_uutime_usec * 1000), | ||
| 3802 | make_timespec (proc.p_ustime_sec, | ||
| 3803 | proc.p_ustime_usec * 1000)); | ||
| 3804 | attrs = Fcons (Fcons (Qtime, make_lisp_time (t)), attrs); | ||
| 3805 | |||
| 3806 | attrs = Fcons (Fcons (Qcutime, make_lisp_timeval (proc.p_uctime_sec, | ||
| 3807 | proc.p_uctime_usec)), | ||
| 3808 | attrs); | ||
| 3809 | |||
| 3810 | /* FIXME: missing cstime and thus ctime. */ | ||
| 3811 | |||
| 3812 | attrs = Fcons (Fcons (Qpri, make_fixnum (proc.p_priority)), attrs); | ||
| 3813 | attrs = Fcons (Fcons (Qnice, make_fixnum (proc.p_nice)), attrs); | ||
| 3814 | |||
| 3815 | /* FIXME: missing thcount (thread count) */ | ||
| 3816 | |||
| 3817 | attrs = Fcons (Fcons (Qstart, make_lisp_timeval (proc.p_ustart_sec, | ||
| 3818 | proc.p_ustart_usec)), | ||
| 3819 | attrs); | ||
| 3820 | |||
| 3821 | len = (proc.p_vm_tsize + proc.p_vm_dsize + proc.p_vm_ssize) * pagesize >> 10; | ||
| 3822 | attrs = Fcons (Fcons (Qvsize, make_fixnum (len)), attrs); | ||
| 3823 | |||
| 3824 | attrs = Fcons (Fcons (Qrss, make_fixnum (proc.p_vm_rssize * pagesize >> 10)), | ||
| 3825 | attrs); | ||
| 3826 | |||
| 3827 | t = make_timespec (proc.p_ustart_sec, | ||
| 3828 | proc.p_ustart_usec * 1000); | ||
| 3829 | t = timespec_sub (current_timespec (), t); | ||
| 3830 | attrs = Fcons (Fcons (Qetime, make_lisp_time (t)), attrs); | ||
| 3831 | |||
| 3832 | len = sizeof (fscale); | ||
| 3833 | mib[0] = CTL_KERN; | ||
| 3834 | mib[1] = KERN_FSCALE; | ||
| 3835 | if (sysctl (mib, 2, &fscale, &len, NULL, 0) != -1) | ||
| 3836 | { | ||
| 3837 | pct = (double)proc.p_pctcpu / fscale * 100.0; | ||
| 3838 | attrs = Fcons (Fcons (Qpcpu, make_float (pct)), attrs); | ||
| 3839 | } | ||
| 3840 | |||
| 3841 | len = sizeof (uvmexp); | ||
| 3842 | mib[0] = CTL_VM; | ||
| 3843 | mib[1] = VM_UVMEXP; | ||
| 3844 | if (sysctl (mib, 2, &uvmexp, &len, NULL, 0) != -1) | ||
| 3845 | { | ||
| 3846 | pct = (100.0 * (double)proc.p_vm_rssize / uvmexp.npages); | ||
| 3847 | attrs = Fcons (Fcons (Qpmem, make_float (pct)), attrs); | ||
| 3848 | } | ||
| 3849 | |||
| 3850 | len = sizeof args; | ||
| 3851 | mib[0] = CTL_KERN; | ||
| 3852 | mib[1] = KERN_PROC_ARGS; | ||
| 3853 | mib[2] = proc_id; | ||
| 3854 | mib[3] = KERN_PROC_ARGV; | ||
| 3855 | if (sysctl (mib, 4, &args, &len, NULL, 0) == 0 && len != 0) | ||
| 3856 | { | ||
| 3857 | char **argv = (char**)args; | ||
| 3858 | |||
| 3859 | /* concatenate argv reusing the existing storage storage. | ||
| 3860 | sysctl(8) guarantees that "the buffer pointed to by oldp is | ||
| 3861 | filled with an array of char pointers followed by the strings | ||
| 3862 | themselves." */ | ||
| 3863 | for (i = 0; argv[i] != NULL; ++i) | ||
| 3864 | { | ||
| 3865 | if (argv[i+1] != NULL) | ||
| 3866 | { | ||
| 3867 | len = strlen (argv[i]); | ||
| 3868 | argv[i][len] = ' '; | ||
| 3869 | } | ||
| 3870 | } | ||
| 3871 | |||
| 3872 | AUTO_STRING (comm, *argv); | ||
| 3873 | decoded_comm = code_convert_string_norecord (comm, | ||
| 3874 | Vlocale_coding_system, 0); | ||
| 3875 | attrs = Fcons (Fcons (Qargs, decoded_comm), attrs); | ||
| 3876 | } | ||
| 3877 | |||
| 3878 | return attrs; | ||
| 3879 | } | ||
| 3880 | |||
| 3664 | #elif defined DARWIN_OS | 3881 | #elif defined DARWIN_OS |
| 3665 | 3882 | ||
| 3666 | Lisp_Object | 3883 | Lisp_Object |
diff --git a/src/term.c b/src/term.c index a87f9c745ce..2e2ab2bf438 100644 --- a/src/term.c +++ b/src/term.c | |||
| @@ -2382,7 +2382,6 @@ frame's terminal). */) | |||
| 2382 | 2382 | ||
| 2383 | #ifdef HAVE_GPM | 2383 | #ifdef HAVE_GPM |
| 2384 | 2384 | ||
| 2385 | #ifndef HAVE_WINDOW_SYSTEM | ||
| 2386 | void | 2385 | void |
| 2387 | term_mouse_moveto (int x, int y) | 2386 | term_mouse_moveto (int x, int y) |
| 2388 | { | 2387 | { |
| @@ -2396,7 +2395,6 @@ term_mouse_moveto (int x, int y) | |||
| 2396 | last_mouse_x = x; | 2395 | last_mouse_x = x; |
| 2397 | last_mouse_y = y; */ | 2396 | last_mouse_y = y; */ |
| 2398 | } | 2397 | } |
| 2399 | #endif /* HAVE_WINDOW_SYSTEM */ | ||
| 2400 | 2398 | ||
| 2401 | /* Implementation of draw_row_with_mouse_face for TTY/GPM. */ | 2399 | /* Implementation of draw_row_with_mouse_face for TTY/GPM. */ |
| 2402 | void | 2400 | void |
| @@ -4246,8 +4244,8 @@ use the Bourne shell command 'TERM=...; export TERM' (C-shell:\n\ | |||
| 4246 | 4244 | ||
| 4247 | #ifdef HAVE_GPM | 4245 | #ifdef HAVE_GPM |
| 4248 | terminal->mouse_position_hook = term_mouse_position; | 4246 | terminal->mouse_position_hook = term_mouse_position; |
| 4249 | tty->mouse_highlight.mouse_face_window = Qnil; | ||
| 4250 | #endif | 4247 | #endif |
| 4248 | tty->mouse_highlight.mouse_face_window = Qnil; | ||
| 4251 | 4249 | ||
| 4252 | terminal->kboard = allocate_kboard (Qnil); | 4250 | terminal->kboard = allocate_kboard (Qnil); |
| 4253 | terminal->kboard->reference_count++; | 4251 | terminal->kboard->reference_count++; |
diff --git a/src/termhooks.h b/src/termhooks.h index 0cab7bd7542..524590fc938 100644 --- a/src/termhooks.h +++ b/src/termhooks.h | |||
| @@ -371,9 +371,7 @@ enum { | |||
| 371 | #ifdef HAVE_GPM | 371 | #ifdef HAVE_GPM |
| 372 | #include <gpm.h> | 372 | #include <gpm.h> |
| 373 | extern int handle_one_term_event (struct tty_display_info *, Gpm_Event *); | 373 | extern int handle_one_term_event (struct tty_display_info *, Gpm_Event *); |
| 374 | #ifndef HAVE_WINDOW_SYSTEM | ||
| 375 | extern void term_mouse_moveto (int, int); | 374 | extern void term_mouse_moveto (int, int); |
| 376 | #endif | ||
| 377 | 375 | ||
| 378 | /* The device for which we have enabled gpm support. */ | 376 | /* The device for which we have enabled gpm support. */ |
| 379 | extern struct tty_display_info *gpm_tty; | 377 | extern struct tty_display_info *gpm_tty; |
diff --git a/src/w32term.c b/src/w32term.c index e5a8a823b48..109aa58d732 100644 --- a/src/w32term.c +++ b/src/w32term.c | |||
| @@ -7507,7 +7507,8 @@ w32_initialize (void) | |||
| 7507 | } | 7507 | } |
| 7508 | 7508 | ||
| 7509 | #ifdef CYGWIN | 7509 | #ifdef CYGWIN |
| 7510 | if ((w32_message_fd = emacs_open ("/dev/windows", O_RDWR, 0)) == -1) | 7510 | if ((w32_message_fd = emacs_open_noquit ("/dev/windows", O_RDWR, 0)) |
| 7511 | == -1) | ||
| 7511 | fatal ("opening /dev/windows: %s", strerror (errno)); | 7512 | fatal ("opening /dev/windows: %s", strerror (errno)); |
| 7512 | #endif /* CYGWIN */ | 7513 | #endif /* CYGWIN */ |
| 7513 | 7514 | ||
diff --git a/src/window.c b/src/window.c index 5e78aa400b5..e025e0b0821 100644 --- a/src/window.c +++ b/src/window.c | |||
| @@ -2663,12 +2663,15 @@ static void | |||
| 2663 | decode_next_window_args (Lisp_Object *window, Lisp_Object *minibuf, Lisp_Object *all_frames) | 2663 | decode_next_window_args (Lisp_Object *window, Lisp_Object *minibuf, Lisp_Object *all_frames) |
| 2664 | { | 2664 | { |
| 2665 | struct window *w = decode_live_window (*window); | 2665 | struct window *w = decode_live_window (*window); |
| 2666 | Lisp_Object miniwin = XFRAME (w->frame)->minibuffer_window; | ||
| 2666 | 2667 | ||
| 2667 | XSETWINDOW (*window, w); | 2668 | XSETWINDOW (*window, w); |
| 2668 | /* MINIBUF nil may or may not include minibuffers. Decide if it | 2669 | /* MINIBUF nil may or may not include minibuffers. Decide if it |
| 2669 | does. */ | 2670 | does. */ |
| 2670 | if (NILP (*minibuf)) | 2671 | if (NILP (*minibuf)) |
| 2671 | *minibuf = minibuf_level ? minibuf_window : Qlambda; | 2672 | *minibuf = this_minibuffer_depth (XWINDOW (miniwin)->contents) |
| 2673 | ? miniwin | ||
| 2674 | : Qlambda; | ||
| 2672 | else if (!EQ (*minibuf, Qt)) | 2675 | else if (!EQ (*minibuf, Qt)) |
| 2673 | *minibuf = Qlambda; | 2676 | *minibuf = Qlambda; |
| 2674 | 2677 | ||
diff --git a/src/window.h b/src/window.h index fbdec0df997..4271fc88306 100644 --- a/src/window.h +++ b/src/window.h | |||
| @@ -1124,10 +1124,6 @@ extern Lisp_Object echo_area_window; | |||
| 1124 | 1124 | ||
| 1125 | extern EMACS_INT command_loop_level; | 1125 | extern EMACS_INT command_loop_level; |
| 1126 | 1126 | ||
| 1127 | /* Depth in minibuffer invocations. */ | ||
| 1128 | |||
| 1129 | extern EMACS_INT minibuf_level; | ||
| 1130 | |||
| 1131 | /* Non-zero if we should redraw the mode lines on the next redisplay. | 1127 | /* Non-zero if we should redraw the mode lines on the next redisplay. |
| 1132 | Usually set to a unique small integer so we can track the main causes of | 1128 | Usually set to a unique small integer so we can track the main causes of |
| 1133 | full redisplays in `redisplay--mode-lines-cause'. */ | 1129 | full redisplays in `redisplay--mode-lines-cause'. */ |
diff --git a/src/xdisp.c b/src/xdisp.c index d070c5ae5cd..592bdb7be34 100644 --- a/src/xdisp.c +++ b/src/xdisp.c | |||
| @@ -9285,8 +9285,8 @@ move_it_in_display_line_to (struct it *it, | |||
| 9285 | if (may_wrap && char_can_wrap_before (it)) | 9285 | if (may_wrap && char_can_wrap_before (it)) |
| 9286 | { | 9286 | { |
| 9287 | /* We have reached a glyph that follows one or more | 9287 | /* We have reached a glyph that follows one or more |
| 9288 | whitespace characters or a character that allows | 9288 | whitespace characters or characters that allow |
| 9289 | wrapping after it. If this character allows | 9289 | wrapping after them. If this character allows |
| 9290 | wrapping before it, save this position as a | 9290 | wrapping before it, save this position as a |
| 9291 | wrapping point. */ | 9291 | wrapping point. */ |
| 9292 | if (atpos_it.sp >= 0) | 9292 | if (atpos_it.sp >= 0) |
| @@ -9303,7 +9303,6 @@ move_it_in_display_line_to (struct it *it, | |||
| 9303 | } | 9303 | } |
| 9304 | /* Otherwise, we can wrap here. */ | 9304 | /* Otherwise, we can wrap here. */ |
| 9305 | SAVE_IT (wrap_it, *it, wrap_data); | 9305 | SAVE_IT (wrap_it, *it, wrap_data); |
| 9306 | next_may_wrap = false; | ||
| 9307 | } | 9306 | } |
| 9308 | /* Update may_wrap for the next iteration. */ | 9307 | /* Update may_wrap for the next iteration. */ |
| 9309 | may_wrap = next_may_wrap; | 9308 | may_wrap = next_may_wrap; |
| @@ -10650,9 +10649,10 @@ include the height of both, if present, in the return value. */) | |||
| 10650 | bpos = BEGV_BYTE; | 10649 | bpos = BEGV_BYTE; |
| 10651 | while (bpos < ZV_BYTE) | 10650 | while (bpos < ZV_BYTE) |
| 10652 | { | 10651 | { |
| 10653 | c = fetch_char_advance (&start, &bpos); | 10652 | c = FETCH_BYTE (bpos); |
| 10654 | if (!(c == ' ' || c == '\t' || c == '\n' || c == '\r')) | 10653 | if (!(c == ' ' || c == '\t' || c == '\n' || c == '\r')) |
| 10655 | break; | 10654 | break; |
| 10655 | inc_both (&start, &bpos); | ||
| 10656 | } | 10656 | } |
| 10657 | while (bpos > BEGV_BYTE) | 10657 | while (bpos > BEGV_BYTE) |
| 10658 | { | 10658 | { |
| @@ -10681,7 +10681,10 @@ include the height of both, if present, in the return value. */) | |||
| 10681 | dec_both (&end, &bpos); | 10681 | dec_both (&end, &bpos); |
| 10682 | c = FETCH_BYTE (bpos); | 10682 | c = FETCH_BYTE (bpos); |
| 10683 | if (!(c == ' ' || c == '\t' || c == '\n' || c == '\r')) | 10683 | if (!(c == ' ' || c == '\t' || c == '\n' || c == '\r')) |
| 10684 | break; | 10684 | { |
| 10685 | inc_both (&end, &bpos); | ||
| 10686 | break; | ||
| 10687 | } | ||
| 10685 | } | 10688 | } |
| 10686 | while (bpos < ZV_BYTE) | 10689 | while (bpos < ZV_BYTE) |
| 10687 | { | 10690 | { |
| @@ -20819,9 +20822,8 @@ try_window_id (struct window *w) | |||
| 20819 | + window_wants_header_line (w) | 20822 | + window_wants_header_line (w) |
| 20820 | + window_internal_height (w)); | 20823 | + window_internal_height (w)); |
| 20821 | 20824 | ||
| 20822 | #if defined (HAVE_GPM) || defined (MSDOS) | ||
| 20823 | gui_clear_window_mouse_face (w); | 20825 | gui_clear_window_mouse_face (w); |
| 20824 | #endif | 20826 | |
| 20825 | /* Perform the operation on the screen. */ | 20827 | /* Perform the operation on the screen. */ |
| 20826 | if (dvpos > 0) | 20828 | if (dvpos > 0) |
| 20827 | { | 20829 | { |
diff --git a/src/xfaces.c b/src/xfaces.c index 217aa0aee03..d38328476a4 100644 --- a/src/xfaces.c +++ b/src/xfaces.c | |||
| @@ -3317,7 +3317,8 @@ FRAME 0 means change the face on all frames, and change the default | |||
| 3317 | } | 3317 | } |
| 3318 | else if (EQ (k, QCstyle)) | 3318 | else if (EQ (k, QCstyle)) |
| 3319 | { | 3319 | { |
| 3320 | if (!EQ (v, Qpressed_button) && !EQ (v, Qreleased_button)) | 3320 | if (!EQ (v, Qpressed_button) && !EQ (v, Qreleased_button) |
| 3321 | && !EQ(v, Qflat_button)) | ||
| 3321 | break; | 3322 | break; |
| 3322 | } | 3323 | } |
| 3323 | else | 3324 | else |
| @@ -6055,6 +6056,10 @@ realize_gui_face (struct face_cache *cache, Lisp_Object attrs[LFACE_VECTOR_SIZE] | |||
| 6055 | face->box = FACE_RAISED_BOX; | 6056 | face->box = FACE_RAISED_BOX; |
| 6056 | else if (EQ (value, Qpressed_button)) | 6057 | else if (EQ (value, Qpressed_button)) |
| 6057 | face->box = FACE_SUNKEN_BOX; | 6058 | face->box = FACE_SUNKEN_BOX; |
| 6059 | else if (EQ (value, Qflat_button)) { | ||
| 6060 | face->box = FACE_SIMPLE_BOX; | ||
| 6061 | face->box_color = face->background; | ||
| 6062 | } | ||
| 6058 | } | 6063 | } |
| 6059 | } | 6064 | } |
| 6060 | } | 6065 | } |
| @@ -6943,6 +6948,7 @@ syms_of_xfaces (void) | |||
| 6943 | DEFSYM (Qwave, "wave"); | 6948 | DEFSYM (Qwave, "wave"); |
| 6944 | DEFSYM (Qreleased_button, "released-button"); | 6949 | DEFSYM (Qreleased_button, "released-button"); |
| 6945 | DEFSYM (Qpressed_button, "pressed-button"); | 6950 | DEFSYM (Qpressed_button, "pressed-button"); |
| 6951 | DEFSYM (Qflat_button, "flat-button"); | ||
| 6946 | DEFSYM (Qnormal, "normal"); | 6952 | DEFSYM (Qnormal, "normal"); |
| 6947 | DEFSYM (Qextra_light, "extra-light"); | 6953 | DEFSYM (Qextra_light, "extra-light"); |
| 6948 | DEFSYM (Qlight, "light"); | 6954 | DEFSYM (Qlight, "light"); |