aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorAndrea Corallo2021-01-16 13:26:10 +0100
committerAndrea Corallo2021-01-16 13:26:10 +0100
commit0a7ac0b5504e75275699a3d8d2d5d94bcfda8708 (patch)
treebb6158c8a9edeb1e716718abfc98dca16aef9e9e /src
parentf1efac1f9efbfa15b6434ebef507c00c1277633f (diff)
parent0732fc31932c75c682c8b65b4dcb4376ca63e8fd (diff)
downloademacs-0a7ac0b5504e75275699a3d8d2d5d94bcfda8708.tar.gz
emacs-0a7ac0b5504e75275699a3d8d2d5d94bcfda8708.zip
Merge remote-tracking branch 'savannah/master' into native-comp
Diffstat (limited to 'src')
-rw-r--r--src/buffer.c2
-rw-r--r--src/callproc.c33
-rw-r--r--src/data.c3
-rw-r--r--src/dispnew.c16
-rw-r--r--src/emacs.c4
-rw-r--r--src/eval.c26
-rw-r--r--src/fns.c85
-rw-r--r--src/keymap.c35
-rw-r--r--src/lisp.h8
-rw-r--r--src/lread.c29
-rw-r--r--src/minibuf.c211
-rw-r--r--src/pdumper.c2
-rw-r--r--src/process.c13
-rw-r--r--src/sysdep.c217
-rw-r--r--src/w32term.c3
-rw-r--r--src/window.c5
-rw-r--r--src/window.h4
-rw-r--r--src/xdisp.c13
-rw-r--r--src/xfaces.c8
19 files changed, 619 insertions, 98 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 8d2a5619eb8..cb72b070b7b 100644
--- a/src/callproc.c
+++ b/src/callproc.c
@@ -314,6 +314,7 @@ call_process (ptrdiff_t nargs, Lisp_Object *args, int filefd,
314#ifdef MSDOS /* Demacs 1.1.1 91/10/16 HIRANO Satoshi */ 314#ifdef MSDOS /* Demacs 1.1.1 91/10/16 HIRANO Satoshi */
315 char *tempfile = NULL; 315 char *tempfile = NULL;
316#else 316#else
317 sigset_t oldset;
317 pid_t pid = -1; 318 pid_t pid = -1;
318#endif 319#endif
319 int child_errno; 320 int child_errno;
@@ -601,9 +602,12 @@ call_process (ptrdiff_t nargs, Lisp_Object *args, int filefd,
601 602
602#ifndef MSDOS 603#ifndef MSDOS
603 604
605 block_input ();
606 block_child_signal (&oldset);
607
604 child_errno 608 child_errno
605 = emacs_spawn (&pid, filefd, fd_output, fd_error, new_argv, env, 609 = emacs_spawn (&pid, filefd, fd_output, fd_error, new_argv, env,
606 SSDATA (current_dir), NULL); 610 SSDATA (current_dir), NULL, &oldset);
607 eassert ((child_errno == 0) == (0 < pid)); 611 eassert ((child_errno == 0) == (0 < pid));
608 612
609 if (pid > 0) 613 if (pid > 0)
@@ -624,6 +628,9 @@ call_process (ptrdiff_t nargs, Lisp_Object *args, int filefd,
624 } 628 }
625 } 629 }
626 630
631 unblock_child_signal (&oldset);
632 unblock_input ();
633
627 if (pid < 0) 634 if (pid < 0)
628 report_file_errno (CHILD_SETUP_ERROR_DESC, Qnil, child_errno); 635 report_file_errno (CHILD_SETUP_ERROR_DESC, Qnil, child_errno);
629 636
@@ -1227,17 +1234,21 @@ child_setup (int in, int out, int err, char **new_argv, char **env,
1227 process image file ARGV[0]. Use ENVP for the environment block for 1234 process image file ARGV[0]. Use ENVP for the environment block for
1228 the new process. Use CWD as working directory for the new process. 1235 the new process. Use CWD as working directory for the new process.
1229 If PTY is not NULL, it must be a pseudoterminal device. If PTY is 1236 If PTY is not NULL, it must be a pseudoterminal device. If PTY is
1230 NULL, don't perform any terminal setup. */ 1237 NULL, don't perform any terminal setup. OLDSET must be a pointer
1238 to a signal set initialized by `block_child_signal'. Before
1239 calling this function, call `block_input' and `block_child_signal';
1240 afterwards, call `unblock_input' and `unblock_child_signal'. Be
1241 sure to call `unblock_child_signal' only after registering NEWPID
1242 in a list where `handle_child_signal' can find it! */
1231 1243
1232int 1244int
1233emacs_spawn (pid_t *newpid, int std_in, int std_out, int std_err, 1245emacs_spawn (pid_t *newpid, int std_in, int std_out, int std_err,
1234 char **argv, char **envp, const char *cwd, const char *pty) 1246 char **argv, char **envp, const char *cwd,
1247 const char *pty, const sigset_t *oldset)
1235{ 1248{
1236 sigset_t oldset;
1237 int pid; 1249 int pid;
1238 1250
1239 block_input (); 1251 eassert (input_blocked_p ());
1240 block_child_signal (&oldset);
1241 1252
1242#ifndef WINDOWSNT 1253#ifndef WINDOWSNT
1243 /* vfork, and prevent local vars from being clobbered by the vfork. */ 1254 /* vfork, and prevent local vars from being clobbered by the vfork. */
@@ -1249,6 +1260,7 @@ emacs_spawn (pid_t *newpid, int std_in, int std_out, int std_err,
1249 int volatile stdout_volatile = std_out; 1260 int volatile stdout_volatile = std_out;
1250 int volatile stderr_volatile = std_err; 1261 int volatile stderr_volatile = std_err;
1251 char **volatile envp_volatile = envp; 1262 char **volatile envp_volatile = envp;
1263 const sigset_t *volatile oldset_volatile = oldset;
1252 1264
1253#ifdef DARWIN_OS 1265#ifdef DARWIN_OS
1254 /* Darwin doesn't let us run setsid after a vfork, so use fork when 1266 /* Darwin doesn't let us run setsid after a vfork, so use fork when
@@ -1270,6 +1282,7 @@ emacs_spawn (pid_t *newpid, int std_in, int std_out, int std_err,
1270 std_out = stdout_volatile; 1282 std_out = stdout_volatile;
1271 std_err = stderr_volatile; 1283 std_err = stderr_volatile;
1272 envp = envp_volatile; 1284 envp = envp_volatile;
1285 oldset = oldset_volatile;
1273 1286
1274 if (pid == 0) 1287 if (pid == 0)
1275#endif /* not WINDOWSNT */ 1288#endif /* not WINDOWSNT */
@@ -1323,7 +1336,7 @@ emacs_spawn (pid_t *newpid, int std_in, int std_out, int std_err,
1323 would work? */ 1336 would work? */
1324 if (std_in >= 0) 1337 if (std_in >= 0)
1325 emacs_close (std_in); 1338 emacs_close (std_in);
1326 std_out = std_in = emacs_open (pty, O_RDWR, 0); 1339 std_out = std_in = emacs_open_noquit (pty, O_RDWR, 0);
1327 1340
1328 if (std_in < 0) 1341 if (std_in < 0)
1329 { 1342 {
@@ -1364,7 +1377,7 @@ emacs_spawn (pid_t *newpid, int std_in, int std_out, int std_err,
1364#endif 1377#endif
1365 1378
1366 /* Stop blocking SIGCHLD in the child. */ 1379 /* Stop blocking SIGCHLD in the child. */
1367 unblock_child_signal (&oldset); 1380 unblock_child_signal (oldset);
1368 1381
1369 if (pty_flag) 1382 if (pty_flag)
1370 child_setup_tty (std_out); 1383 child_setup_tty (std_out);
@@ -1382,10 +1395,6 @@ emacs_spawn (pid_t *newpid, int std_in, int std_out, int std_err,
1382 1395
1383 int vfork_error = pid < 0 ? errno : 0; 1396 int vfork_error = pid < 0 ? errno : 0;
1384 1397
1385 /* Stop blocking in the parent. */
1386 unblock_child_signal (&oldset);
1387 unblock_input ();
1388
1389 if (pid < 0) 1398 if (pid < 0)
1390 { 1399 {
1391 eassert (0 < vfork_error); 1400 eassert (0 < vfork_error);
diff --git a/src/data.c b/src/data.c
index 3cf5bbbdd56..0dc21c8c2a1 100644
--- a/src/data.c
+++ b/src/data.c
@@ -3834,6 +3834,7 @@ syms_of_data (void)
3834 DEFSYM (Qbuffer_read_only, "buffer-read-only"); 3834 DEFSYM (Qbuffer_read_only, "buffer-read-only");
3835 DEFSYM (Qtext_read_only, "text-read-only"); 3835 DEFSYM (Qtext_read_only, "text-read-only");
3836 DEFSYM (Qmark_inactive, "mark-inactive"); 3836 DEFSYM (Qmark_inactive, "mark-inactive");
3837 DEFSYM (Qinhibited_interaction, "inhibited-interaction");
3837 3838
3838 DEFSYM (Qlistp, "listp"); 3839 DEFSYM (Qlistp, "listp");
3839 DEFSYM (Qconsp, "consp"); 3840 DEFSYM (Qconsp, "consp");
@@ -3918,6 +3919,8 @@ syms_of_data (void)
3918 PUT_ERROR (Qbuffer_read_only, error_tail, "Buffer is read-only"); 3919 PUT_ERROR (Qbuffer_read_only, error_tail, "Buffer is read-only");
3919 PUT_ERROR (Qtext_read_only, pure_cons (Qbuffer_read_only, error_tail), 3920 PUT_ERROR (Qtext_read_only, pure_cons (Qbuffer_read_only, error_tail),
3920 "Text is read-only"); 3921 "Text is read-only");
3922 PUT_ERROR (Qinhibited_interaction, error_tail,
3923 "User interaction while inhibited");
3921 3924
3922 DEFSYM (Qrange_error, "range-error"); 3925 DEFSYM (Qrange_error, "range-error");
3923 DEFSYM (Qdomain_error, "domain-error"); 3926 DEFSYM (Qdomain_error, "domain-error");
diff --git a/src/dispnew.c b/src/dispnew.c
index 36a6dd8a091..e603c671363 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
6054Lisp_Object 6061Lisp_Object
6055sit_for (Lisp_Object timeout, bool reading, int display_option) 6062sit_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 738ef12c98c..c6581bba37e 100644
--- a/src/emacs.c
+++ b/src/emacs.c
@@ -1300,7 +1300,7 @@ main (int argc, char **argv)
1300 { 1300 {
1301 emacs_close (STDIN_FILENO); 1301 emacs_close (STDIN_FILENO);
1302 emacs_close (STDOUT_FILENO); 1302 emacs_close (STDOUT_FILENO);
1303 int result = emacs_open (term, O_RDWR, 0); 1303 int result = emacs_open_noquit (term, O_RDWR, 0);
1304 if (result != STDIN_FILENO 1304 if (result != STDIN_FILENO
1305 || (fcntl (STDIN_FILENO, F_DUPFD_CLOEXEC, STDOUT_FILENO) 1305 || (fcntl (STDIN_FILENO, F_DUPFD_CLOEXEC, STDOUT_FILENO)
1306 != STDOUT_FILENO)) 1306 != STDOUT_FILENO))
@@ -2884,7 +2884,7 @@ from the parent process and its tty file descriptors. */)
2884 int nfd; 2884 int nfd;
2885 2885
2886 /* Get rid of stdin, stdout and stderr. */ 2886 /* Get rid of stdin, stdout and stderr. */
2887 nfd = emacs_open ("/dev/null", O_RDWR, 0); 2887 nfd = emacs_open_noquit ("/dev/null", O_RDWR, 0);
2888 err |= nfd < 0; 2888 err |= nfd < 0;
2889 err |= dup2 (nfd, STDIN_FILENO) < 0; 2889 err |= dup2 (nfd, STDIN_FILENO) < 0;
2890 err |= dup2 (nfd, STDOUT_FILENO) < 0; 2890 err |= dup2 (nfd, STDOUT_FILENO) < 0;
diff --git a/src/eval.c b/src/eval.c
index f77f07e1711..cef9407dbfa 100644
--- a/src/eval.c
+++ b/src/eval.c
@@ -1176,9 +1176,18 @@ Lisp_Object
1176internal_catch (Lisp_Object tag, 1176internal_catch (Lisp_Object tag,
1177 Lisp_Object (*func) (Lisp_Object), Lisp_Object arg) 1177 Lisp_Object (*func) (Lisp_Object), Lisp_Object arg)
1178{ 1178{
1179 /* MINIBUFFER_QUIT_LEVEL is to handle quitting from nested minibuffers by
1180 throwing t to tag `exit'.
1181 Value -1 means there is no (throw 'exit t) in progress;
1182 0 means the `throw' wasn't done from an active minibuffer;
1183 N > 0 means the `throw' was done from the minibuffer at level N. */
1184 static EMACS_INT minibuffer_quit_level = -1;
1179 /* This structure is made part of the chain `catchlist'. */ 1185 /* This structure is made part of the chain `catchlist'. */
1180 struct handler *c = push_handler (tag, CATCHER); 1186 struct handler *c = push_handler (tag, CATCHER);
1181 1187
1188 if (EQ (tag, Qexit))
1189 minibuffer_quit_level = -1;
1190
1182 /* Call FUNC. */ 1191 /* Call FUNC. */
1183 if (! sys_setjmp (c->jmp)) 1192 if (! sys_setjmp (c->jmp))
1184 { 1193 {
@@ -1192,6 +1201,23 @@ internal_catch (Lisp_Object tag,
1192 Lisp_Object val = handlerlist->val; 1201 Lisp_Object val = handlerlist->val;
1193 clobbered_eassert (handlerlist == c); 1202 clobbered_eassert (handlerlist == c);
1194 handlerlist = handlerlist->next; 1203 handlerlist = handlerlist->next;
1204 if (EQ (tag, Qexit) && EQ (val, Qt))
1205 /* If we've thrown t to tag `exit' from within a minibuffer, we
1206 exit all minibuffers more deeply nested than the current
1207 one. */
1208 {
1209 EMACS_INT mini_depth = this_minibuffer_depth (Qnil);
1210 if (mini_depth && mini_depth != minibuffer_quit_level)
1211 {
1212 if (minibuffer_quit_level == -1)
1213 minibuffer_quit_level = mini_depth;
1214 if (minibuffer_quit_level
1215 && (minibuf_level > minibuffer_quit_level))
1216 Fthrow (Qexit, Qt);
1217 }
1218 else
1219 minibuffer_quit_level = -1;
1220 }
1195 return val; 1221 return val;
1196 } 1222 }
1197} 1223}
diff --git a/src/fns.c b/src/fns.c
index 5fcc54f0d1f..7ab2e8f1a03 100644
--- a/src/fns.c
+++ b/src/fns.c
@@ -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
5551DEFUN ("buffer-line-statistics", Fbuffer_line_statistics,
5552 Sbuffer_line_statistics, 0, 1, 0,
5553 doc: /* Return data about lines in BUFFER.
5554The data is returned as a list, and the first element is the number of
5555lines in the buffer, the second is the length of the longest line, and
5556the third is the mean line length. The lengths returned are in bytes, not
5557characters. */ )
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
5551static bool 5635static bool
5552string_ascii_p (Lisp_Object string) 5636string_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/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
1649DEFUN ("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.
1651KEYS is a string or vector, a sequence of keystrokes.
1652The binding is probably a symbol with a function definition.
1653
1654If optional argument ACCEPT-DEFAULT is non-nil, recognize default
1655bindings; 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
1666DEFUN ("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.
1668KEYS is a string or vector, a sequence of keystrokes.
1669The binding is probably a symbol with a function definition.
1670This function's return values are the same as those of `lookup-key'
1671\(which see).
1672
1673If optional argument ACCEPT-DEFAULT is non-nil, recognize default
1674bindings; 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
1682DEFUN ("minor-mode-key-binding", Fminor_mode_key_binding, Sminor_mode_key_binding, 1, 2, 0, 1649DEFUN ("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.
1684Return an alist of pairs (MODENAME . BINDING), where MODENAME is 1651Return 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 b6182c37eed..296f9af7337 100644
--- a/src/lisp.h
+++ b/src/lisp.h
@@ -4368,9 +4368,12 @@ extern Lisp_Object Vminibuffer_list;
4368extern Lisp_Object last_minibuf_string; 4368extern Lisp_Object last_minibuf_string;
4369extern void move_minibuffer_onto_frame (void); 4369extern void move_minibuffer_onto_frame (void);
4370extern bool is_minibuffer (EMACS_INT, Lisp_Object); 4370extern bool is_minibuffer (EMACS_INT, Lisp_Object);
4371extern EMACS_INT this_minibuffer_depth (Lisp_Object);
4372extern EMACS_INT minibuf_level;
4371extern Lisp_Object get_minibuffer (EMACS_INT); 4373extern Lisp_Object get_minibuffer (EMACS_INT);
4372extern void init_minibuf_once (void); 4374extern void init_minibuf_once (void);
4373extern void syms_of_minibuf (void); 4375extern void syms_of_minibuf (void);
4376extern void barf_if_interaction_inhibited (void);
4374 4377
4375/* Defined in callint.c. */ 4378/* Defined in callint.c. */
4376 4379
@@ -4518,8 +4521,8 @@ extern void setup_process_coding_systems (Lisp_Object);
4518# define CHILD_SETUP_ERROR_DESC "Doing vfork" 4521# define CHILD_SETUP_ERROR_DESC "Doing vfork"
4519#endif 4522#endif
4520 4523
4521extern int emacs_spawn (pid_t *, int, int, int, char **, char **, const char *, 4524extern int emacs_spawn (pid_t *, int, int, int, char **, char **,
4522 const char *); 4525 const char *, const char *, const sigset_t *);
4523extern char **make_environment_block (Lisp_Object); 4526extern char **make_environment_block (Lisp_Object);
4524extern void init_callproc_1 (void); 4527extern void init_callproc_1 (void);
4525extern void init_callproc (void); 4528extern void init_callproc (void);
@@ -4598,6 +4601,7 @@ extern AVOID emacs_abort (void) NO_INLINE;
4598extern int emacs_fstatat (int, char const *, void *, int); 4601extern int emacs_fstatat (int, char const *, void *, int);
4599extern int emacs_openat (int, char const *, int, int); 4602extern int emacs_openat (int, char const *, int, int);
4600extern int emacs_open (const char *, int, int); 4603extern int emacs_open (const char *, int, int);
4604extern int emacs_open_noquit (const char *, int, int);
4601extern int emacs_pipe (int[2]); 4605extern int emacs_pipe (int[2]);
4602extern int emacs_close (int); 4606extern int emacs_close (int);
4603extern ptrdiff_t emacs_read (int, void *, ptrdiff_t); 4607extern ptrdiff_t emacs_read (int, void *, ptrdiff_t);
diff --git a/src/lread.c b/src/lread.c
index e308fa88699..4cf4f8cde9b 100644
--- a/src/lread.c
+++ b/src/lread.c
@@ -767,11 +767,16 @@ is used for reading a character.
767If the optional argument SECONDS is non-nil, it should be a number 767If the optional argument SECONDS is non-nil, it should be a number
768specifying the maximum number of seconds to wait for input. If no 768specifying the maximum number of seconds to wait for input. If no
769input arrives in that time, return nil. SECONDS may be a 769input arrives in that time, return nil. SECONDS may be a
770floating-point value. */) 770floating-point value.
771
772If `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
783DEFUN ("read-event", Fread_event, Sread_event, 0, 3, 0, 788DEFUN ("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
791If you want to read non-character events, consider calling `read-key'
792instead. `read-key' will decode events via `input-decode-map' that
793`read-event' will not. On a terminal this includes function keys such
794as <F7> and <RIGHT>, or mouse events generated by `xterm-mouse-mode'.
795
785If the optional argument PROMPT is non-nil, display that as a prompt. 796If the optional argument PROMPT is non-nil, display that as a prompt.
786If PROMPT is nil or the string \"\", the key sequence/events that led 797If PROMPT is nil or the string \"\", the key sequence/events that led
787to the current command is used as the prompt. 798to the current command is used as the prompt.
@@ -793,9 +804,14 @@ is used for reading a character.
793If the optional argument SECONDS is non-nil, it should be a number 804If the optional argument SECONDS is non-nil, it should be a number
794specifying the maximum number of seconds to wait for input. If no 805specifying the maximum number of seconds to wait for input. If no
795input arrives in that time, return nil. SECONDS may be a 806input arrives in that time, return nil. SECONDS may be a
796floating-point value. */) 807floating-point value.
808
809If `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.
822If the optional argument SECONDS is non-nil, it should be a number 838If the optional argument SECONDS is non-nil, it should be a number
823specifying the maximum number of seconds to wait for input. If no 839specifying the maximum number of seconds to wait for input. If no
824input arrives in that time, return nil. SECONDS may be a 840input arrives in that time, return nil. SECONDS may be a
825floating-point value. */) 841floating-point value.
826 (Lisp_Object prompt, Lisp_Object inherit_input_method, Lisp_Object seconds) 842
843If `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
64static ptrdiff_t minibuf_prompt_width; 64static ptrdiff_t minibuf_prompt_width;
65 65
66static 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. */
67static bool 71static bool
68minibuf_follows_frame (void) 72minibuf_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. */
80static bool
81minibuf_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. */
88static bool
89minibuf_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. */
128void move_minibuffer_onto_frame (void) 163void 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
378DEFUN ("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.
381No 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. */
395EMACS_INT
396this_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
411DEFUN ("abort-minibuffers", Fabort_minibuffers, Sabort_minibuffers, 0, 0, "",
412 doc: /* Abort the current minibuffer.
413If we are not currently in the innermost minibuffer, prompt the user to
414confirm 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
339DEFUN ("minibuffer-prompt-end", Fminibuffer_prompt_end, 435DEFUN ("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. */
922static Lisp_Object
923nth_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
1078void
1079barf_if_interaction_inhibited (void)
1080{
1081 if (inhibit_interaction)
1082 xsignal0 (Qinhibited_interaction);
1083}
1084
942DEFUN ("read-from-minibuffer", Fread_from_minibuffer, 1085DEFUN ("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
1129If `inhibit-interaction' is non-nil, this function will signal an
1130 `inhibited-interaction' error.
1131
986The remainder of this documentation string describes the 1132The remainder of this documentation string describes the
987INITIAL-CONTENTS argument in more detail. It is only relevant when 1133INITIAL-CONTENTS argument in more detail. It is only relevant when
988studying existing code, or when HIST is a cons. If non-nil, 1134studying 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.
1072Such values are treated as in `read-from-minibuffer', but are normally 1220Such values are treated as in `read-from-minibuffer', but are normally
1073not useful in this function.) 1221not useful in this function.)
1222
1074Third arg INHERIT-INPUT-METHOD, if non-nil, means the minibuffer inherits 1223Third arg INHERIT-INPUT-METHOD, if non-nil, means the minibuffer inherits
1075the current input method and the setting of`enable-multibyte-characters'. */) 1224the current input method and the setting of`enable-multibyte-characters'.
1225
1226If `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. */);
2032The function is called with the arguments passed to `read-buffer'. */); 2186The 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.
2037Nil means that a minibuffer will appear only in the frame which created it. 2191Nil means that a minibuffer will appear only in the frame which created it.
2192Any other value means the minibuffer will move onto another frame, but
2193only when the user starts using a minibuffer there.
2038 2194
2039Any buffer local or dynamic binding of this variable is ignored. Only the 2195Any buffer local or dynamic binding of this variable is ignored. Only the
2040default top level value is used. */); 2196default 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'
2183uses to hide passwords. */); 2339uses 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.
2345This variable can be bound when user interaction can't be performed,
2346for instance when running a headless Emacs server. Functions like
2347`read-from-minibuffer' (and the like) will signal `inhibited-interaction'
2348instead. */);
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/pdumper.c b/src/pdumper.c
index 7eefcc83fda..f0711078a5a 100644
--- a/src/pdumper.c
+++ b/src/pdumper.c
@@ -5460,7 +5460,7 @@ pdumper_load (const char *dump_filename, char *argv0, char const *original_pwd)
5460 eassert (!dump_loaded_p ()); 5460 eassert (!dump_loaded_p ());
5461 5461
5462 int err; 5462 int err;
5463 int dump_fd = emacs_open (dump_filename, O_RDONLY, 0); 5463 int dump_fd = emacs_open_noquit (dump_filename, O_RDONLY, 0);
5464 if (dump_fd < 0) 5464 if (dump_fd < 0)
5465 { 5465 {
5466 err = (errno == ENOENT || errno == ENOTDIR 5466 err = (errno == ENOENT || errno == ENOTDIR
diff --git a/src/process.c b/src/process.c
index 06d750d3368..dac7d0440fa 100644
--- a/src/process.c
+++ b/src/process.c
@@ -692,8 +692,7 @@ status_convert (int w)
692 if (WIFSTOPPED (w)) 692 if (WIFSTOPPED (w))
693 return Fcons (Qstop, Fcons (make_fixnum (WSTOPSIG (w)), Qnil)); 693 return Fcons (Qstop, Fcons (make_fixnum (WSTOPSIG (w)), Qnil));
694 else if (WIFEXITED (w)) 694 else if (WIFEXITED (w))
695 return Fcons (Qexit, Fcons (make_fixnum (WEXITSTATUS (w)), 695 return Fcons (Qexit, Fcons (make_fixnum (WEXITSTATUS (w)), Qnil));
696 WCOREDUMP (w) ? Qt : Qnil));
697 else if (WIFSIGNALED (w)) 696 else if (WIFSIGNALED (w))
698 return Fcons (Qsignal, Fcons (make_fixnum (WTERMSIG (w)), 697 return Fcons (Qsignal, Fcons (make_fixnum (WTERMSIG (w)),
699 WCOREDUMP (w) ? Qt : Qnil)); 698 WCOREDUMP (w) ? Qt : Qnil));
@@ -2059,6 +2058,7 @@ create_process (Lisp_Object process, char **new_argv, Lisp_Object current_dir)
2059 bool pty_flag = 0; 2058 bool pty_flag = 0;
2060 char pty_name[PTY_NAME_SIZE]; 2059 char pty_name[PTY_NAME_SIZE];
2061 Lisp_Object lisp_pty_name = Qnil; 2060 Lisp_Object lisp_pty_name = Qnil;
2061 sigset_t oldset;
2062 2062
2063 inchannel = outchannel = -1; 2063 inchannel = outchannel = -1;
2064 2064
@@ -2139,13 +2139,16 @@ create_process (Lisp_Object process, char **new_argv, Lisp_Object current_dir)
2139 setup_process_coding_systems (process); 2139 setup_process_coding_systems (process);
2140 char **env = make_environment_block (current_dir); 2140 char **env = make_environment_block (current_dir);
2141 2141
2142 block_input ();
2143 block_child_signal (&oldset);
2144
2142 pty_flag = p->pty_flag; 2145 pty_flag = p->pty_flag;
2143 eassert (pty_flag == ! NILP (lisp_pty_name)); 2146 eassert (pty_flag == ! NILP (lisp_pty_name));
2144 2147
2145 vfork_errno 2148 vfork_errno
2146 = emacs_spawn (&pid, forkin, forkout, forkerr, new_argv, env, 2149 = emacs_spawn (&pid, forkin, forkout, forkerr, new_argv, env,
2147 SSDATA (current_dir), 2150 SSDATA (current_dir),
2148 pty_flag ? SSDATA (lisp_pty_name) : NULL); 2151 pty_flag ? SSDATA (lisp_pty_name) : NULL, &oldset);
2149 2152
2150 eassert ((vfork_errno == 0) == (0 < pid)); 2153 eassert ((vfork_errno == 0) == (0 < pid));
2151 2154
@@ -2153,6 +2156,10 @@ create_process (Lisp_Object process, char **new_argv, Lisp_Object current_dir)
2153 if (pid >= 0) 2156 if (pid >= 0)
2154 p->alive = 1; 2157 p->alive = 1;
2155 2158
2159 /* Stop blocking in the parent. */
2160 unblock_child_signal (&oldset);
2161 unblock_input ();
2162
2156 /* Environment block no longer needed. */ 2163 /* Environment block no longer needed. */
2157 unbind_to (count, Qnil); 2164 unbind_to (count, Qnil);
2158 2165
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
2325static int
2326emacs_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
2339int
2340emacs_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
3003static Lisp_Object
3004make_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
3700Lisp_Object
3701system_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
3666Lisp_Object 3883Lisp_Object
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
2663decode_next_window_args (Lisp_Object *window, Lisp_Object *minibuf, Lisp_Object *all_frames) 2663decode_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 332cb3091fd..79eb44e7a38 100644
--- a/src/window.h
+++ b/src/window.h
@@ -1124,10 +1124,6 @@ extern Lisp_Object echo_area_window;
1124 1124
1125extern EMACS_INT command_loop_level; 1125extern EMACS_INT command_loop_level;
1126 1126
1127/* Depth in minibuffer invocations. */
1128
1129extern 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 6a4304d194b..ea67329cff1 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 {
diff --git a/src/xfaces.c b/src/xfaces.c
index b3b19a9cb2e..258b365eda3 100644
--- a/src/xfaces.c
+++ b/src/xfaces.c
@@ -3293,7 +3293,8 @@ FRAME 0 means change the face on all frames, and change the default
3293 } 3293 }
3294 else if (EQ (k, QCstyle)) 3294 else if (EQ (k, QCstyle))
3295 { 3295 {
3296 if (!EQ (v, Qpressed_button) && !EQ (v, Qreleased_button)) 3296 if (!EQ (v, Qpressed_button) && !EQ (v, Qreleased_button)
3297 && !EQ(v, Qflat_button))
3297 break; 3298 break;
3298 } 3299 }
3299 else 3300 else
@@ -6031,6 +6032,10 @@ realize_gui_face (struct face_cache *cache, Lisp_Object attrs[LFACE_VECTOR_SIZE]
6031 face->box = FACE_RAISED_BOX; 6032 face->box = FACE_RAISED_BOX;
6032 else if (EQ (value, Qpressed_button)) 6033 else if (EQ (value, Qpressed_button))
6033 face->box = FACE_SUNKEN_BOX; 6034 face->box = FACE_SUNKEN_BOX;
6035 else if (EQ (value, Qflat_button)) {
6036 face->box = FACE_SIMPLE_BOX;
6037 face->box_color = face->background;
6038 }
6034 } 6039 }
6035 } 6040 }
6036 } 6041 }
@@ -6919,6 +6924,7 @@ syms_of_xfaces (void)
6919 DEFSYM (Qwave, "wave"); 6924 DEFSYM (Qwave, "wave");
6920 DEFSYM (Qreleased_button, "released-button"); 6925 DEFSYM (Qreleased_button, "released-button");
6921 DEFSYM (Qpressed_button, "pressed-button"); 6926 DEFSYM (Qpressed_button, "pressed-button");
6927 DEFSYM (Qflat_button, "flat-button");
6922 DEFSYM (Qnormal, "normal"); 6928 DEFSYM (Qnormal, "normal");
6923 DEFSYM (Qextra_light, "extra-light"); 6929 DEFSYM (Qextra_light, "extra-light");
6924 DEFSYM (Qlight, "light"); 6930 DEFSYM (Qlight, "light");