aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorYuuki Harano2020-12-14 01:52:10 +0900
committerYuuki Harano2020-12-14 01:52:10 +0900
commit3e30047ce3a81dd0879973012abbf570d3215dfd (patch)
treec7c10e82f2ff37705356a0c25b98d92c603c7983 /src
parentaea5dbec2514811fb2e1cc44b2347a976a5b7de8 (diff)
parentfe50a8b9ba79b4ac14a3a352d8bf84eaee4f2122 (diff)
downloademacs-3e30047ce3a81dd0879973012abbf570d3215dfd.tar.gz
emacs-3e30047ce3a81dd0879973012abbf570d3215dfd.zip
Merge branch 'master' of git.sv.gnu.org:/srv/git/emacs into feature/pgtk
Diffstat (limited to 'src')
-rw-r--r--src/charset.c4
-rw-r--r--src/chartab.c6
-rw-r--r--src/data.c5
-rw-r--r--src/emacs-module.c8
-rw-r--r--src/emacs.c13
-rw-r--r--src/eval.c24
-rw-r--r--src/fileio.c7
-rw-r--r--src/fns.c70
-rw-r--r--src/frame.c12
-rw-r--r--src/image.c125
-rw-r--r--src/keyboard.c61
-rw-r--r--src/keyboard.h1
-rw-r--r--src/lisp.h33
-rw-r--r--src/nsterm.m10
-rw-r--r--src/process.c43
-rw-r--r--src/regex-emacs.c17
-rw-r--r--src/termhooks.h1
-rw-r--r--src/thread.h1
-rw-r--r--src/w32gui.h1
-rw-r--r--src/w32term.c30
-rw-r--r--src/window.c56
-rw-r--r--src/xdisp.c98
-rw-r--r--src/xterm.c4
23 files changed, 365 insertions, 265 deletions
diff --git a/src/charset.c b/src/charset.c
index 520dd3a9605..f6b5173fad4 100644
--- a/src/charset.c
+++ b/src/charset.c
@@ -800,7 +800,9 @@ RANGE is a cons (FROM . TO), where FROM and TO indicate a range of
800characters contained in CHARSET. 800characters contained in CHARSET.
801 801
802The optional 4th and 5th arguments FROM-CODE and TO-CODE specify the 802The optional 4th and 5th arguments FROM-CODE and TO-CODE specify the
803range of code points (in CHARSET) of target characters. */) 803range of code points (in CHARSET) of target characters. Note that
804these are not character codes, but code points in CHARSET; for the
805difference see `decode-char' and `list-charset-chars'. */)
804 (Lisp_Object function, Lisp_Object charset, Lisp_Object arg, Lisp_Object from_code, Lisp_Object to_code) 806 (Lisp_Object function, Lisp_Object charset, Lisp_Object arg, Lisp_Object from_code, Lisp_Object to_code)
805{ 807{
806 struct charset *cs; 808 struct charset *cs;
diff --git a/src/chartab.c b/src/chartab.c
index cb2ced568d9..331e8595ebe 100644
--- a/src/chartab.c
+++ b/src/chartab.c
@@ -1000,10 +1000,10 @@ map_sub_char_table_for_charset (void (*c_function) (Lisp_Object, Lisp_Object),
1000 "mapping table" or a "deunifier table" of a certain charset. 1000 "mapping table" or a "deunifier table" of a certain charset.
1001 1001
1002 If CHARSET is not NULL (this is the case that `map-charset-chars' 1002 If CHARSET is not NULL (this is the case that `map-charset-chars'
1003 is called with non-nil FROM-CODE and TO-CODE), it is a charset who 1003 is called with non-nil FROM-CODE and TO-CODE), it is a charset that
1004 owns TABLE, and the function is called only on a character in the 1004 owns TABLE, and the function is called only for characters in the
1005 range FROM and TO. FROM and TO are not character codes, but code 1005 range FROM and TO. FROM and TO are not character codes, but code
1006 points of a character in CHARSET. 1006 points of characters in CHARSET (see 'decode-char').
1007 1007
1008 This function is called in these two cases: 1008 This function is called in these two cases:
1009 1009
diff --git a/src/data.c b/src/data.c
index 384c2592204..76bacf7e131 100644
--- a/src/data.c
+++ b/src/data.c
@@ -1639,8 +1639,9 @@ default_value (Lisp_Object symbol)
1639 1639
1640DEFUN ("default-boundp", Fdefault_boundp, Sdefault_boundp, 1, 1, 0, 1640DEFUN ("default-boundp", Fdefault_boundp, Sdefault_boundp, 1, 1, 0,
1641 doc: /* Return t if SYMBOL has a non-void default value. 1641 doc: /* Return t if SYMBOL has a non-void default value.
1642This is the value that is seen in buffers that do not have their own values 1642A variable may have a buffer-local or a `let'-bound local value. This
1643for this variable. */) 1643function says whether the variable has a non-void value outside of the
1644current context. Also see `default-value'. */)
1644 (Lisp_Object symbol) 1645 (Lisp_Object symbol)
1645{ 1646{
1646 register Lisp_Object value; 1647 register Lisp_Object value;
diff --git a/src/emacs-module.c b/src/emacs-module.c
index 0f3ef59fd8c..b7cd835c83c 100644
--- a/src/emacs-module.c
+++ b/src/emacs-module.c
@@ -784,7 +784,8 @@ module_make_string (emacs_env *env, const char *str, ptrdiff_t len)
784 MODULE_FUNCTION_BEGIN (NULL); 784 MODULE_FUNCTION_BEGIN (NULL);
785 if (! (0 <= len && len <= STRING_BYTES_BOUND)) 785 if (! (0 <= len && len <= STRING_BYTES_BOUND))
786 overflow_error (); 786 overflow_error ();
787 Lisp_Object lstr = module_decode_utf_8 (str, len); 787 Lisp_Object lstr
788 = len == 0 ? empty_multibyte_string : module_decode_utf_8 (str, len);
788 return lisp_to_value (env, lstr); 789 return lisp_to_value (env, lstr);
789} 790}
790 791
@@ -794,9 +795,8 @@ module_make_unibyte_string (emacs_env *env, const char *str, ptrdiff_t length)
794 MODULE_FUNCTION_BEGIN (NULL); 795 MODULE_FUNCTION_BEGIN (NULL);
795 if (! (0 <= length && length <= STRING_BYTES_BOUND)) 796 if (! (0 <= length && length <= STRING_BYTES_BOUND))
796 overflow_error (); 797 overflow_error ();
797 Lisp_Object lstr = make_uninit_string (length); 798 Lisp_Object lstr
798 memcpy (SDATA (lstr), str, length); 799 = length == 0 ? empty_unibyte_string : make_unibyte_string (str, length);
799 SDATA (lstr)[length] = 0;
800 return lisp_to_value (env, lstr); 800 return lisp_to_value (env, lstr);
801} 801}
802 802
diff --git a/src/emacs.c b/src/emacs.c
index d0e65ce2e80..00d3fc25abe 100644
--- a/src/emacs.c
+++ b/src/emacs.c
@@ -2380,10 +2380,13 @@ all of which are called before Emacs is actually killed. */
2380 /* Fsignal calls emacs_abort () if it sees that waiting_for_input is 2380 /* Fsignal calls emacs_abort () if it sees that waiting_for_input is
2381 set. */ 2381 set. */
2382 waiting_for_input = 0; 2382 waiting_for_input = 0;
2383 if (noninteractive) 2383 if (!NILP (find_symbol_value (Qkill_emacs_hook)))
2384 safe_run_hooks (Qkill_emacs_hook); 2384 {
2385 else 2385 if (noninteractive)
2386 run_hook (Qkill_emacs_hook); 2386 safe_run_hooks (Qkill_emacs_hook);
2387 else
2388 call1 (Qrun_hook_query_error_with_timeout, Qkill_emacs_hook);
2389 }
2387 2390
2388#ifdef HAVE_X_WINDOWS 2391#ifdef HAVE_X_WINDOWS
2389 /* Transfer any clipboards we own to the clipboard manager. */ 2392 /* Transfer any clipboards we own to the clipboard manager. */
@@ -2905,6 +2908,8 @@ syms_of_emacs (void)
2905 DEFSYM (Qrisky_local_variable, "risky-local-variable"); 2908 DEFSYM (Qrisky_local_variable, "risky-local-variable");
2906 DEFSYM (Qkill_emacs, "kill-emacs"); 2909 DEFSYM (Qkill_emacs, "kill-emacs");
2907 DEFSYM (Qkill_emacs_hook, "kill-emacs-hook"); 2910 DEFSYM (Qkill_emacs_hook, "kill-emacs-hook");
2911 DEFSYM (Qrun_hook_query_error_with_timeout,
2912 "run-hook-query-error-with-timeout");
2908 2913
2909#ifdef HAVE_UNEXEC 2914#ifdef HAVE_UNEXEC
2910 defsubr (&Sdump_emacs); 2915 defsubr (&Sdump_emacs);
diff --git a/src/eval.c b/src/eval.c
index d9a424b57a9..e2d70aaa0ef 100644
--- a/src/eval.c
+++ b/src/eval.c
@@ -1709,6 +1709,7 @@ signal_or_quit (Lisp_Object error_symbol, Lisp_Object data, bool keyboard_quit)
1709 break; 1709 break;
1710 } 1710 }
1711 1711
1712 bool debugger_called = false;
1712 if (/* Don't run the debugger for a memory-full error. 1713 if (/* Don't run the debugger for a memory-full error.
1713 (There is no room in memory to do that!) */ 1714 (There is no room in memory to do that!) */
1714 !NILP (error_symbol) 1715 !NILP (error_symbol)
@@ -1722,7 +1723,7 @@ signal_or_quit (Lisp_Object error_symbol, Lisp_Object data, bool keyboard_quit)
1722 if requested". */ 1723 if requested". */
1723 || EQ (h->tag_or_ch, Qerror))) 1724 || EQ (h->tag_or_ch, Qerror)))
1724 { 1725 {
1725 bool debugger_called 1726 debugger_called
1726 = maybe_call_debugger (conditions, error_symbol, data); 1727 = maybe_call_debugger (conditions, error_symbol, data);
1727 /* We can't return values to code which signaled an error, but we 1728 /* We can't return values to code which signaled an error, but we
1728 can continue code which has signaled a quit. */ 1729 can continue code which has signaled a quit. */
@@ -1730,6 +1731,19 @@ signal_or_quit (Lisp_Object error_symbol, Lisp_Object data, bool keyboard_quit)
1730 return Qnil; 1731 return Qnil;
1731 } 1732 }
1732 1733
1734 /* If we're in batch mode, print a backtrace unconditionally to help with
1735 debugging. Make sure to use `debug' unconditionally to not interfere with
1736 ERT or other packages that install custom debuggers. */
1737 if (!debugger_called && !NILP (error_symbol)
1738 && (NILP (clause) || EQ (h->tag_or_ch, Qerror)) && noninteractive
1739 && backtrace_on_error_noninteractive)
1740 {
1741 ptrdiff_t count = SPECPDL_INDEX ();
1742 specbind (Vdebugger, Qdebug);
1743 call_debugger (list2 (Qerror, Fcons (error_symbol, data)));
1744 unbind_to (count, Qnil);
1745 }
1746
1733 if (!NILP (clause)) 1747 if (!NILP (clause))
1734 { 1748 {
1735 Lisp_Object unwind_data 1749 Lisp_Object unwind_data
@@ -4251,6 +4265,14 @@ Note that `debug-on-error', `debug-on-quit' and friends
4251still determine whether to handle the particular condition. */); 4265still determine whether to handle the particular condition. */);
4252 Vdebug_on_signal = Qnil; 4266 Vdebug_on_signal = Qnil;
4253 4267
4268 DEFVAR_BOOL ("backtrace-on-error-noninteractive",
4269 backtrace_on_error_noninteractive,
4270 doc: /* Non-nil means print backtrace on error in batch mode.
4271If this is nil, errors in batch mode will just print the error
4272message upon encountering an unhandled error, without showing
4273the Lisp backtrace. */);
4274 backtrace_on_error_noninteractive = true;
4275
4254 /* The value of num_nonmacro_input_events as of the last time we 4276 /* The value of num_nonmacro_input_events as of the last time we
4255 started to enter the debugger. If we decide to enter the debugger 4277 started to enter the debugger. If we decide to enter the debugger
4256 again when this is still equal to num_nonmacro_input_events, then we 4278 again when this is still equal to num_nonmacro_input_events, then we
diff --git a/src/fileio.c b/src/fileio.c
index 283813ff89e..702c1438283 100644
--- a/src/fileio.c
+++ b/src/fileio.c
@@ -3757,9 +3757,10 @@ characters in the buffer. If VISIT is non-nil, BEG and END must be nil.
3757If optional fifth argument REPLACE is non-nil, replace the current 3757If optional fifth argument REPLACE is non-nil, replace the current
3758buffer contents (in the accessible portion) with the file contents. 3758buffer contents (in the accessible portion) with the file contents.
3759This is better than simply deleting and inserting the whole thing 3759This is better than simply deleting and inserting the whole thing
3760because (1) it preserves some marker positions and (2) it puts less data 3760because (1) it preserves some marker positions (in unchanged portions
3761in the undo list. When REPLACE is non-nil, the second return value is 3761at the start and end of the buffer) and (2) it puts less data in the
3762the number of characters that replace previous buffer contents. 3762undo list. When REPLACE is non-nil, the second return value is the
3763number of characters that replace previous buffer contents.
3763 3764
3764This function does code conversion according to the value of 3765This function does code conversion according to the value of
3765`coding-system-for-read' or `file-coding-system-alist', and sets the 3766`coding-system-for-read' or `file-coding-system-alist', and sets the
diff --git a/src/fns.c b/src/fns.c
index e4c9acc3163..646c3ed0834 100644
--- a/src/fns.c
+++ b/src/fns.c
@@ -4525,16 +4525,34 @@ sweep_weak_table (struct Lisp_Hash_Table *h, bool remove_entries_p)
4525EMACS_UINT 4525EMACS_UINT
4526hash_string (char const *ptr, ptrdiff_t len) 4526hash_string (char const *ptr, ptrdiff_t len)
4527{ 4527{
4528 char const *p = ptr; 4528 EMACS_UINT const *p = (EMACS_UINT const *) ptr;
4529 char const *end = p + len; 4529 EMACS_UINT const *end = (EMACS_UINT const *) (ptr + len);
4530 unsigned char c; 4530 EMACS_UINT hash = len;
4531 EMACS_UINT hash = 0; 4531 /* At most 8 steps. We could reuse SXHASH_MAX_LEN, of course,
4532 4532 * but dividing by 8 is cheaper. */
4533 while (p != end) 4533 ptrdiff_t step = 1 + ((end - p) >> 3);
4534
4535 /* Beware: `end` might be unaligned, so `p < end` is not always the same
4536 * as `p <= end - 1`. */
4537 while (p <= end - 1)
4534 { 4538 {
4535 c = *p++; 4539 EMACS_UINT c = *p;
4540 p += step;
4536 hash = sxhash_combine (hash, c); 4541 hash = sxhash_combine (hash, c);
4537 } 4542 }
4543 if (p < end)
4544 { /* A few last bytes remain (smaller than an EMACS_UINT). */
4545 /* FIXME: We could do this without a loop, but it'd require
4546 endian-dependent code :-( */
4547 char const *p1 = (char const *)p;
4548 char const *end1 = (char const *)end;
4549 do
4550 {
4551 unsigned char c = *p1++;
4552 hash = sxhash_combine (hash, c);
4553 }
4554 while (p1 < end1);
4555 }
4538 4556
4539 return hash; 4557 return hash;
4540} 4558}
@@ -5418,7 +5436,8 @@ disregarding any coding systems. If nil, use the current buffer.
5418 5436
5419This function is useful for comparing two buffers running in the same 5437This function is useful for comparing two buffers running in the same
5420Emacs, but is not guaranteed to return the same hash between different 5438Emacs, but is not guaranteed to return the same hash between different
5421Emacs versions. 5439Emacs versions. It should be somewhat more efficient on larger
5440buffers than `secure-hash' is, and should not allocate more memory.
5422 5441
5423It should not be used for anything security-related. See 5442It should not be used for anything security-related. See
5424`secure-hash' for these applications. */ ) 5443`secure-hash' for these applications. */ )
@@ -5551,6 +5570,40 @@ Case is always significant and text properties are ignored. */)
5551 5570
5552 return make_int (string_byte_to_char (haystack, res - SSDATA (haystack))); 5571 return make_int (string_byte_to_char (haystack, res - SSDATA (haystack)));
5553} 5572}
5573
5574static void
5575collect_interval (INTERVAL interval, Lisp_Object collector)
5576{
5577 nconc2 (collector,
5578 list1(list3 (make_fixnum (interval->position),
5579 make_fixnum (interval->position + LENGTH (interval)),
5580 interval->plist)));
5581}
5582
5583DEFUN ("object-intervals", Fobject_intervals, Sobject_intervals, 1, 1, 0,
5584 doc: /* Return a copy of the text properties of OBJECT.
5585OBJECT must be a buffer or a string.
5586
5587Altering this copy does not change the layout of the text properties
5588in OBJECT. */)
5589 (register Lisp_Object object)
5590{
5591 Lisp_Object collector = Fcons (Qnil, Qnil);
5592 INTERVAL intervals;
5593
5594 if (STRINGP (object))
5595 intervals = string_intervals (object);
5596 else if (BUFFERP (object))
5597 intervals = buffer_intervals (XBUFFER (object));
5598 else
5599 wrong_type_argument (Qbuffer_or_string_p, object);
5600
5601 if (! intervals)
5602 return Qnil;
5603
5604 traverse_intervals (intervals, 0, collect_interval, collector);
5605 return CDR (collector);
5606}
5554 5607
5555 5608
5556void 5609void
@@ -5592,6 +5645,7 @@ syms_of_fns (void)
5592 defsubr (&Smaphash); 5645 defsubr (&Smaphash);
5593 defsubr (&Sdefine_hash_table_test); 5646 defsubr (&Sdefine_hash_table_test);
5594 defsubr (&Sstring_search); 5647 defsubr (&Sstring_search);
5648 defsubr (&Sobject_intervals);
5595 5649
5596 /* Crypto and hashing stuff. */ 5650 /* Crypto and hashing stuff. */
5597 DEFSYM (Qiv_auto, "iv-auto"); 5651 DEFSYM (Qiv_auto, "iv-auto");
diff --git a/src/frame.c b/src/frame.c
index a67ec4772a8..a827eaa81e8 100644
--- a/src/frame.c
+++ b/src/frame.c
@@ -3580,7 +3580,9 @@ window managers may refuse to honor a HEIGHT that is not an integer
3580multiple of the default frame font height. 3580multiple of the default frame font height.
3581 3581
3582When called interactively, HEIGHT is the numeric prefix and the 3582When called interactively, HEIGHT is the numeric prefix and the
3583currently selected frame will be set to this height. */) 3583currently selected frame will be set to this height.
3584
3585If FRAME is nil, it defaults to the selected frame. */)
3584 (Lisp_Object frame, Lisp_Object height, Lisp_Object pretend, Lisp_Object pixelwise) 3586 (Lisp_Object frame, Lisp_Object height, Lisp_Object pretend, Lisp_Object pixelwise)
3585{ 3587{
3586 struct frame *f = decode_live_frame (frame); 3588 struct frame *f = decode_live_frame (frame);
@@ -3603,7 +3605,9 @@ window managers may refuse to honor a WIDTH that is not an integer
3603multiple of the default frame font width. 3605multiple of the default frame font width.
3604 3606
3605When called interactively, WIDTH is the numeric prefix and the 3607When called interactively, WIDTH is the numeric prefix and the
3606currently selected frame will be set to this width. */) 3608currently selected frame will be set to this width.
3609
3610If FRAME is nil, it defaults to the selected frame. */)
3607 (Lisp_Object frame, Lisp_Object width, Lisp_Object pretend, Lisp_Object pixelwise) 3611 (Lisp_Object frame, Lisp_Object width, Lisp_Object pretend, Lisp_Object pixelwise)
3608{ 3612{
3609 struct frame *f = decode_live_frame (frame); 3613 struct frame *f = decode_live_frame (frame);
@@ -3619,7 +3623,9 @@ Optional argument PIXELWISE non-nil means to measure in pixels. Note:
3619When `frame-resize-pixelwise' is nil, some window managers may refuse to 3623When `frame-resize-pixelwise' is nil, some window managers may refuse to
3620honor a WIDTH that is not an integer multiple of the default frame font 3624honor a WIDTH that is not an integer multiple of the default frame font
3621width or a HEIGHT that is not an integer multiple of the default frame 3625width or a HEIGHT that is not an integer multiple of the default frame
3622font height. */) 3626font height.
3627
3628If FRAME is nil, it defaults to the selected frame. */)
3623 (Lisp_Object frame, Lisp_Object width, Lisp_Object height, Lisp_Object pixelwise) 3629 (Lisp_Object frame, Lisp_Object width, Lisp_Object height, Lisp_Object pixelwise)
3624{ 3630{
3625 struct frame *f = decode_live_frame (frame); 3631 struct frame *f = decode_live_frame (frame);
diff --git a/src/image.c b/src/image.c
index e2d142ed32e..e2a3902b26c 100644
--- a/src/image.c
+++ b/src/image.c
@@ -1703,17 +1703,6 @@ make_image_cache (void)
1703 return c; 1703 return c;
1704} 1704}
1705 1705
1706/* Compare two lists (one of which must be proper), comparing each
1707 element with `eq'. */
1708static bool
1709equal_lists (Lisp_Object a, Lisp_Object b)
1710{
1711 while (CONSP (a) && CONSP (b) && EQ (XCAR (a), XCAR (b)))
1712 a = XCDR (a), b = XCDR (b);
1713
1714 return EQ (a, b);
1715}
1716
1717/* Find an image matching SPEC in the cache, and return it. If no 1706/* Find an image matching SPEC in the cache, and return it. If no
1718 image is found, return NULL. */ 1707 image is found, return NULL. */
1719static struct image * 1708static struct image *
@@ -1741,7 +1730,7 @@ search_image_cache (struct frame *f, Lisp_Object spec, EMACS_UINT hash,
1741 1730
1742 for (img = c->buckets[i]; img; img = img->next) 1731 for (img = c->buckets[i]; img; img = img->next)
1743 if (img->hash == hash 1732 if (img->hash == hash
1744 && equal_lists (img->spec, spec) 1733 && !NILP (Fequal (img->spec, spec))
1745 && (ignore_colors || (img->face_foreground == foreground 1734 && (ignore_colors || (img->face_foreground == foreground
1746 && img->face_background == background))) 1735 && img->face_background == background)))
1747 break; 1736 break;
@@ -1755,12 +1744,13 @@ static void
1755uncache_image (struct frame *f, Lisp_Object spec) 1744uncache_image (struct frame *f, Lisp_Object spec)
1756{ 1745{
1757 struct image *img; 1746 struct image *img;
1747 EMACS_UINT hash = sxhash (spec);
1758 1748
1759 /* Because the background colors are based on the current face, we 1749 /* Because the background colors are based on the current face, we
1760 can have multiple copies of an image with the same spec. We want 1750 can have multiple copies of an image with the same spec. We want
1761 to remove them all to ensure the user doesn't see an old version 1751 to remove them all to ensure the user doesn't see an old version
1762 of the image when the face changes. */ 1752 of the image when the face changes. */
1763 while ((img = search_image_cache (f, spec, sxhash (spec), 0, 0, true))) 1753 while ((img = search_image_cache (f, spec, hash, 0, 0, true)))
1764 { 1754 {
1765 free_image (f, img); 1755 free_image (f, img);
1766 /* As display glyphs may still be referring to the image ID, we 1756 /* As display glyphs may still be referring to the image ID, we
@@ -1913,6 +1903,55 @@ which is then usually a filename. */)
1913 return Qnil; 1903 return Qnil;
1914} 1904}
1915 1905
1906static size_t
1907image_frame_cache_size (struct frame *f)
1908{
1909 size_t total = 0;
1910#if defined USE_CAIRO
1911 struct image_cache *c = FRAME_IMAGE_CACHE (f);
1912
1913 if (!c)
1914 return 0;
1915
1916 for (ptrdiff_t i = 0; i < c->used; ++i)
1917 {
1918 struct image *img = c->images[i];
1919
1920 if (img && img->pixmap && img->pixmap != NO_PIXMAP)
1921 total += img->pixmap->width * img->pixmap->height *
1922 img->pixmap->bits_per_pixel / 8;
1923 }
1924#elif defined HAVE_NTGUI
1925 struct image_cache *c = FRAME_IMAGE_CACHE (f);
1926
1927 if (!c)
1928 return 0;
1929
1930 for (ptrdiff_t i = 0; i < c->used; ++i)
1931 {
1932 struct image *img = c->images[i];
1933
1934 if (img && img->pixmap && img->pixmap != NO_PIXMAP)
1935 total += w32_image_size (img);
1936 }
1937#endif
1938 return total;
1939}
1940
1941DEFUN ("image-cache-size", Fimage_cache_size, Simage_cache_size, 0, 0, 0,
1942 doc: /* Return the size of the image cache. */)
1943 (void)
1944{
1945 Lisp_Object tail, frame;
1946 size_t total = 0;
1947
1948 FOR_EACH_FRAME (tail, frame)
1949 if (FRAME_WINDOW_P (XFRAME (frame)))
1950 total += image_frame_cache_size (XFRAME (frame));
1951
1952 return make_int (total);
1953}
1954
1916 1955
1917DEFUN ("image-flush", Fimage_flush, Simage_flush, 1956DEFUN ("image-flush", Fimage_flush, Simage_flush,
1918 1, 2, 0, 1957 1, 2, 0,
@@ -9571,6 +9610,7 @@ enum svg_keyword_index
9571 SVG_TYPE, 9610 SVG_TYPE,
9572 SVG_DATA, 9611 SVG_DATA,
9573 SVG_FILE, 9612 SVG_FILE,
9613 SVG_BASE_URI,
9574 SVG_ASCENT, 9614 SVG_ASCENT,
9575 SVG_MARGIN, 9615 SVG_MARGIN,
9576 SVG_RELIEF, 9616 SVG_RELIEF,
@@ -9590,6 +9630,7 @@ static const struct image_keyword svg_format[SVG_LAST] =
9590 {":type", IMAGE_SYMBOL_VALUE, 1}, 9630 {":type", IMAGE_SYMBOL_VALUE, 1},
9591 {":data", IMAGE_STRING_VALUE, 0}, 9631 {":data", IMAGE_STRING_VALUE, 0},
9592 {":file", IMAGE_STRING_VALUE, 0}, 9632 {":file", IMAGE_STRING_VALUE, 0},
9633 {":base-uri", IMAGE_STRING_VALUE, 0},
9593 {":ascent", IMAGE_ASCENT_VALUE, 0}, 9634 {":ascent", IMAGE_ASCENT_VALUE, 0},
9594 {":margin", IMAGE_NON_NEGATIVE_INTEGER_VALUE_OR_PAIR, 0}, 9635 {":margin", IMAGE_NON_NEGATIVE_INTEGER_VALUE_OR_PAIR, 0},
9595 {":relief", IMAGE_INTEGER_VALUE, 0}, 9636 {":relief", IMAGE_INTEGER_VALUE, 0},
@@ -9662,6 +9703,9 @@ DEF_DLL_FN (gboolean, rsvg_handle_write,
9662DEF_DLL_FN (gboolean, rsvg_handle_close, (RsvgHandle *, GError **)); 9703DEF_DLL_FN (gboolean, rsvg_handle_close, (RsvgHandle *, GError **));
9663# endif 9704# endif
9664 9705
9706DEF_DLL_FN (void, rsvg_handle_set_dpi_x_y,
9707 (RsvgHandle * handle, double dpi_x, double dpi_y));
9708
9665# if LIBRSVG_CHECK_VERSION (2, 46, 0) 9709# if LIBRSVG_CHECK_VERSION (2, 46, 0)
9666DEF_DLL_FN (void, rsvg_handle_get_intrinsic_dimensions, 9710DEF_DLL_FN (void, rsvg_handle_get_intrinsic_dimensions,
9667 (RsvgHandle *, gboolean *, RsvgLength *, gboolean *, 9711 (RsvgHandle *, gboolean *, RsvgLength *, gboolean *,
@@ -9718,6 +9762,7 @@ init_svg_functions (void)
9718 LOAD_DLL_FN (library, rsvg_handle_write); 9762 LOAD_DLL_FN (library, rsvg_handle_write);
9719 LOAD_DLL_FN (library, rsvg_handle_close); 9763 LOAD_DLL_FN (library, rsvg_handle_close);
9720#endif 9764#endif
9765 LOAD_DLL_FN (library, rsvg_handle_set_dpi_x_y);
9721#if LIBRSVG_CHECK_VERSION (2, 46, 0) 9766#if LIBRSVG_CHECK_VERSION (2, 46, 0)
9722 LOAD_DLL_FN (library, rsvg_handle_get_intrinsic_dimensions); 9767 LOAD_DLL_FN (library, rsvg_handle_get_intrinsic_dimensions);
9723 LOAD_DLL_FN (library, rsvg_handle_get_geometry_for_layer); 9768 LOAD_DLL_FN (library, rsvg_handle_get_geometry_for_layer);
@@ -9773,6 +9818,7 @@ init_svg_functions (void)
9773# undef rsvg_handle_set_base_uri 9818# undef rsvg_handle_set_base_uri
9774# undef rsvg_handle_write 9819# undef rsvg_handle_write
9775# endif 9820# endif
9821# undef rsvg_handle_set_dpi_x_y
9776 9822
9777# define gdk_pixbuf_get_bits_per_sample fn_gdk_pixbuf_get_bits_per_sample 9823# define gdk_pixbuf_get_bits_per_sample fn_gdk_pixbuf_get_bits_per_sample
9778# define gdk_pixbuf_get_colorspace fn_gdk_pixbuf_get_colorspace 9824# define gdk_pixbuf_get_colorspace fn_gdk_pixbuf_get_colorspace
@@ -9806,6 +9852,7 @@ init_svg_functions (void)
9806# define rsvg_handle_set_base_uri fn_rsvg_handle_set_base_uri 9852# define rsvg_handle_set_base_uri fn_rsvg_handle_set_base_uri
9807# define rsvg_handle_write fn_rsvg_handle_write 9853# define rsvg_handle_write fn_rsvg_handle_write
9808# endif 9854# endif
9855# define rsvg_handle_set_dpi_x_y fn_rsvg_handle_set_dpi_x_y
9809 9856
9810# endif /* !WINDOWSNT */ 9857# endif /* !WINDOWSNT */
9811 9858
@@ -9816,10 +9863,11 @@ static bool
9816svg_load (struct frame *f, struct image *img) 9863svg_load (struct frame *f, struct image *img)
9817{ 9864{
9818 bool success_p = 0; 9865 bool success_p = 0;
9819 Lisp_Object file_name; 9866 Lisp_Object file_name, base_uri;
9820 9867
9821 /* If IMG->spec specifies a file name, create a non-file spec from it. */ 9868 /* If IMG->spec specifies a file name, create a non-file spec from it. */
9822 file_name = image_spec_value (img->spec, QCfile, NULL); 9869 file_name = image_spec_value (img->spec, QCfile, NULL);
9870 base_uri = image_spec_value (img->spec, QCbase_uri, NULL);
9823 if (STRINGP (file_name)) 9871 if (STRINGP (file_name))
9824 { 9872 {
9825 int fd; 9873 int fd;
@@ -9839,15 +9887,16 @@ svg_load (struct frame *f, struct image *img)
9839 return 0; 9887 return 0;
9840 } 9888 }
9841 /* If the file was slurped into memory properly, parse it. */ 9889 /* If the file was slurped into memory properly, parse it. */
9842 success_p = svg_load_image (f, img, contents, size, 9890 if (!STRINGP (base_uri))
9843 SSDATA (ENCODE_FILE (file))); 9891 base_uri = ENCODE_FILE (file);
9892 success_p = svg_load_image (f, img, contents, size, SSDATA (base_uri));
9844 xfree (contents); 9893 xfree (contents);
9845 } 9894 }
9846 /* Else it's not a file, it's a Lisp object. Load the image from a 9895 /* Else it's not a file, it's a Lisp object. Load the image from a
9847 Lisp object rather than a file. */ 9896 Lisp object rather than a file. */
9848 else 9897 else
9849 { 9898 {
9850 Lisp_Object data, original_filename; 9899 Lisp_Object data;
9851 9900
9852 data = image_spec_value (img->spec, QCdata, NULL); 9901 data = image_spec_value (img->spec, QCdata, NULL);
9853 if (!STRINGP (data)) 9902 if (!STRINGP (data))
@@ -9855,10 +9904,10 @@ svg_load (struct frame *f, struct image *img)
9855 image_error ("Invalid image data `%s'", data); 9904 image_error ("Invalid image data `%s'", data);
9856 return 0; 9905 return 0;
9857 } 9906 }
9858 original_filename = BVAR (current_buffer, filename); 9907 if (!STRINGP (base_uri))
9908 base_uri = BVAR (current_buffer, filename);
9859 success_p = svg_load_image (f, img, SSDATA (data), SBYTES (data), 9909 success_p = svg_load_image (f, img, SSDATA (data), SBYTES (data),
9860 (NILP (original_filename) ? NULL 9910 (NILP (base_uri) ? NULL : SSDATA (base_uri)));
9861 : SSDATA (original_filename)));
9862 } 9911 }
9863 9912
9864 return success_p; 9913 return success_p;
@@ -9866,11 +9915,8 @@ svg_load (struct frame *f, struct image *img)
9866 9915
9867#if LIBRSVG_CHECK_VERSION (2, 46, 0) 9916#if LIBRSVG_CHECK_VERSION (2, 46, 0)
9868static double 9917static double
9869svg_css_length_to_pixels (RsvgLength length) 9918svg_css_length_to_pixels (RsvgLength length, double dpi)
9870{ 9919{
9871 /* FIXME: 96 appears to be a pretty standard DPI but we should
9872 probably use the real DPI if we can get it. */
9873 double dpi = 96;
9874 double value = length.length; 9920 double value = length.length;
9875 9921
9876 switch (length.unit) 9922 switch (length.unit)
@@ -9944,18 +9990,26 @@ svg_load_image (struct frame *f, struct image *img, char *contents,
9944 rsvg_handle = rsvg_handle_new_from_stream_sync (input_stream, base_file, 9990 rsvg_handle = rsvg_handle_new_from_stream_sync (input_stream, base_file,
9945 RSVG_HANDLE_FLAGS_NONE, 9991 RSVG_HANDLE_FLAGS_NONE,
9946 NULL, &err); 9992 NULL, &err);
9993
9947 if (base_file) 9994 if (base_file)
9948 g_object_unref (base_file); 9995 g_object_unref (base_file);
9949 g_object_unref (input_stream); 9996 g_object_unref (input_stream);
9950 9997
9951 /* Check rsvg_handle too, to avoid librsvg 2.40.13 bug (Bug#36773#26). */ 9998 /* Check rsvg_handle too, to avoid librsvg 2.40.13 bug (Bug#36773#26). */
9952 if (!rsvg_handle || err) goto rsvg_error; 9999 if (!rsvg_handle || err) goto rsvg_error;
10000
10001 rsvg_handle_set_dpi_x_y (rsvg_handle, FRAME_DISPLAY_INFO (f)->resx,
10002 FRAME_DISPLAY_INFO (f)->resy);
9953#else 10003#else
9954 /* Make a handle to a new rsvg object. */ 10004 /* Make a handle to a new rsvg object. */
9955 rsvg_handle = rsvg_handle_new (); 10005 rsvg_handle = rsvg_handle_new ();
9956 eassume (rsvg_handle); 10006 eassume (rsvg_handle);
9957 10007
10008 rsvg_handle_set_dpi_x_y (rsvg_handle, FRAME_DISPLAY_INFO (f)->resx,
10009 FRAME_DISPLAY_INFO (f)->resy);
10010
9958 /* Set base_uri for properly handling referenced images (via 'href'). 10011 /* Set base_uri for properly handling referenced images (via 'href').
10012 Can be explicitly specified using `:base_uri' image property.
9959 See rsvg bug 596114 - "image refs are relative to curdir, not .svg file" 10013 See rsvg bug 596114 - "image refs are relative to curdir, not .svg file"
9960 <https://gitlab.gnome.org/GNOME/librsvg/issues/33>. */ 10014 <https://gitlab.gnome.org/GNOME/librsvg/issues/33>. */
9961 if (filename) 10015 if (filename)
@@ -9978,6 +10032,7 @@ svg_load_image (struct frame *f, struct image *img, char *contents,
9978 /* Try the instrinsic dimensions first. */ 10032 /* Try the instrinsic dimensions first. */
9979 gboolean has_width, has_height, has_viewbox; 10033 gboolean has_width, has_height, has_viewbox;
9980 RsvgLength iwidth, iheight; 10034 RsvgLength iwidth, iheight;
10035 double dpi = FRAME_DISPLAY_INFO (f)->resx;
9981 10036
9982 rsvg_handle_get_intrinsic_dimensions (rsvg_handle, 10037 rsvg_handle_get_intrinsic_dimensions (rsvg_handle,
9983 &has_width, &iwidth, 10038 &has_width, &iwidth,
@@ -9987,19 +10042,19 @@ svg_load_image (struct frame *f, struct image *img, char *contents,
9987 if (has_width && has_height) 10042 if (has_width && has_height)
9988 { 10043 {
9989 /* Success! We can use these values directly. */ 10044 /* Success! We can use these values directly. */
9990 viewbox_width = svg_css_length_to_pixels (iwidth); 10045 viewbox_width = svg_css_length_to_pixels (iwidth, dpi);
9991 viewbox_height = svg_css_length_to_pixels (iheight); 10046 viewbox_height = svg_css_length_to_pixels (iheight, dpi);
9992 } 10047 }
9993 else if (has_width && has_viewbox) 10048 else if (has_width && has_viewbox)
9994 { 10049 {
9995 viewbox_width = svg_css_length_to_pixels (iwidth); 10050 viewbox_width = svg_css_length_to_pixels (iwidth, dpi);
9996 viewbox_height = svg_css_length_to_pixels (iwidth) 10051 viewbox_height = svg_css_length_to_pixels (iwidth, dpi)
9997 * viewbox.width / viewbox.height; 10052 * viewbox.width / viewbox.height;
9998 } 10053 }
9999 else if (has_height && has_viewbox) 10054 else if (has_height && has_viewbox)
10000 { 10055 {
10001 viewbox_height = svg_css_length_to_pixels (iheight); 10056 viewbox_height = svg_css_length_to_pixels (iheight, dpi);
10002 viewbox_width = svg_css_length_to_pixels (iheight) 10057 viewbox_width = svg_css_length_to_pixels (iheight, dpi)
10003 * viewbox.height / viewbox.width; 10058 * viewbox.height / viewbox.width;
10004 } 10059 }
10005 else if (has_viewbox) 10060 else if (has_viewbox)
@@ -10108,18 +10163,26 @@ svg_load_image (struct frame *f, struct image *img, char *contents,
10108 rsvg_handle = rsvg_handle_new_from_stream_sync (input_stream, base_file, 10163 rsvg_handle = rsvg_handle_new_from_stream_sync (input_stream, base_file,
10109 RSVG_HANDLE_FLAGS_NONE, 10164 RSVG_HANDLE_FLAGS_NONE,
10110 NULL, &err); 10165 NULL, &err);
10166
10111 if (base_file) 10167 if (base_file)
10112 g_object_unref (base_file); 10168 g_object_unref (base_file);
10113 g_object_unref (input_stream); 10169 g_object_unref (input_stream);
10114 10170
10115 /* Check rsvg_handle too, to avoid librsvg 2.40.13 bug (Bug#36773#26). */ 10171 /* Check rsvg_handle too, to avoid librsvg 2.40.13 bug (Bug#36773#26). */
10116 if (!rsvg_handle || err) goto rsvg_error; 10172 if (!rsvg_handle || err) goto rsvg_error;
10173
10174 rsvg_handle_set_dpi_x_y (rsvg_handle, FRAME_DISPLAY_INFO (f)->resx,
10175 FRAME_DISPLAY_INFO (f)->resy);
10117#else 10176#else
10118 /* Make a handle to a new rsvg object. */ 10177 /* Make a handle to a new rsvg object. */
10119 rsvg_handle = rsvg_handle_new (); 10178 rsvg_handle = rsvg_handle_new ();
10120 eassume (rsvg_handle); 10179 eassume (rsvg_handle);
10121 10180
10181 rsvg_handle_set_dpi_x_y (rsvg_handle, FRAME_DISPLAY_INFO (f)->resx,
10182 FRAME_DISPLAY_INFO (f)->resy);
10183
10122 /* Set base_uri for properly handling referenced images (via 'href'). 10184 /* Set base_uri for properly handling referenced images (via 'href').
10185 Can be explicitly specified using `:base_uri' image property.
10123 See rsvg bug 596114 - "image refs are relative to curdir, not .svg file" 10186 See rsvg bug 596114 - "image refs are relative to curdir, not .svg file"
10124 <https://gitlab.gnome.org/GNOME/librsvg/issues/33>. */ 10187 <https://gitlab.gnome.org/GNOME/librsvg/issues/33>. */
10125 if (filename) 10188 if (filename)
@@ -10802,6 +10865,7 @@ non-numeric, there is no explicit limit on the size of images. */);
10802 10865
10803#if defined (HAVE_RSVG) 10866#if defined (HAVE_RSVG)
10804 DEFSYM (Qsvg, "svg"); 10867 DEFSYM (Qsvg, "svg");
10868 DEFSYM (QCbase_uri, ":base-uri");
10805 add_image_type (Qsvg); 10869 add_image_type (Qsvg);
10806#ifdef HAVE_NTGUI 10870#ifdef HAVE_NTGUI
10807 /* Other libraries used directly by svg code. */ 10871 /* Other libraries used directly by svg code. */
@@ -10831,6 +10895,7 @@ non-numeric, there is no explicit limit on the size of images. */);
10831 defsubr (&Simage_size); 10895 defsubr (&Simage_size);
10832 defsubr (&Simage_mask_p); 10896 defsubr (&Simage_mask_p);
10833 defsubr (&Simage_metadata); 10897 defsubr (&Simage_metadata);
10898 defsubr (&Simage_cache_size);
10834 10899
10835#ifdef GLYPH_DEBUG 10900#ifdef GLYPH_DEBUG
10836 defsubr (&Simagep); 10901 defsubr (&Simagep);
diff --git a/src/keyboard.c b/src/keyboard.c
index 6605419c5c7..e8d0747210a 100644
--- a/src/keyboard.c
+++ b/src/keyboard.c
@@ -384,11 +384,13 @@ next_kbd_event (union buffered_input_event *ptr)
384 return ptr == kbd_buffer + KBD_BUFFER_SIZE - 1 ? kbd_buffer : ptr + 1; 384 return ptr == kbd_buffer + KBD_BUFFER_SIZE - 1 ? kbd_buffer : ptr + 1;
385} 385}
386 386
387#ifdef HAVE_X11
387static union buffered_input_event * 388static union buffered_input_event *
388prev_kbd_event (union buffered_input_event *ptr) 389prev_kbd_event (union buffered_input_event *ptr)
389{ 390{
390 return ptr == kbd_buffer ? kbd_buffer + KBD_BUFFER_SIZE - 1 : ptr - 1; 391 return ptr == kbd_buffer ? kbd_buffer + KBD_BUFFER_SIZE - 1 : ptr - 1;
391} 392}
393#endif
392 394
393/* Like EVENT_START, but assume EVENT is an event. 395/* Like EVENT_START, but assume EVENT is an event.
394 This pacifies gcc -Wnull-dereference, which might otherwise 396 This pacifies gcc -Wnull-dereference, which might otherwise
@@ -741,9 +743,6 @@ void
741force_auto_save_soon (void) 743force_auto_save_soon (void)
742{ 744{
743 last_auto_save = - auto_save_interval - 1; 745 last_auto_save = - auto_save_interval - 1;
744 /* FIXME: What's the relationship between forcing auto-save and adding
745 a buffer-switch event? */
746 record_asynch_buffer_change ();
747} 746}
748#endif 747#endif
749 748
@@ -3431,8 +3430,7 @@ readable_events (int flags)
3431 && event->ie.part == scroll_bar_handle 3430 && event->ie.part == scroll_bar_handle
3432 && event->ie.modifiers == 0) 3431 && event->ie.modifiers == 0)
3433#endif 3432#endif
3434 && !((flags & READABLE_EVENTS_FILTER_EVENTS) 3433 )
3435 && event->kind == BUFFER_SWITCH_EVENT))
3436 return 1; 3434 return 1;
3437 event = next_kbd_event (event); 3435 event = next_kbd_event (event);
3438 } 3436 }
@@ -3583,12 +3581,6 @@ kbd_buffer_store_buffered_event (union buffered_input_event *event,
3583 return; 3581 return;
3584 } 3582 }
3585 } 3583 }
3586 /* Don't insert two BUFFER_SWITCH_EVENT's in a row.
3587 Just ignore the second one. */
3588 else if (event->kind == BUFFER_SWITCH_EVENT
3589 && kbd_fetch_ptr != kbd_store_ptr
3590 && prev_kbd_event (kbd_store_ptr)->kind == BUFFER_SWITCH_EVENT)
3591 return;
3592 3584
3593 /* Don't let the very last slot in the buffer become full, 3585 /* Don't let the very last slot in the buffer become full,
3594 since that would make the two pointers equal, 3586 since that would make the two pointers equal,
@@ -3622,7 +3614,6 @@ kbd_buffer_store_buffered_event (union buffered_input_event *event,
3622 case ICONIFY_EVENT: ignore_event = Qiconify_frame; break; 3614 case ICONIFY_EVENT: ignore_event = Qiconify_frame; break;
3623 case DEICONIFY_EVENT: ignore_event = Qmake_frame_visible; break; 3615 case DEICONIFY_EVENT: ignore_event = Qmake_frame_visible; break;
3624 case SELECTION_REQUEST_EVENT: ignore_event = Qselection_request; break; 3616 case SELECTION_REQUEST_EVENT: ignore_event = Qselection_request; break;
3625 case BUFFER_SWITCH_EVENT: ignore_event = Qbuffer_switch; break;
3626 default: ignore_event = Qnil; break; 3617 default: ignore_event = Qnil; break;
3627 } 3618 }
3628 3619
@@ -3964,7 +3955,6 @@ kbd_buffer_get_event (KBOARD **kbp,
3964#ifdef HAVE_XWIDGETS 3955#ifdef HAVE_XWIDGETS
3965 case XWIDGET_EVENT: 3956 case XWIDGET_EVENT:
3966#endif 3957#endif
3967 case BUFFER_SWITCH_EVENT:
3968 case SAVE_SESSION_EVENT: 3958 case SAVE_SESSION_EVENT:
3969 case NO_EVENT: 3959 case NO_EVENT:
3970 case HELP_EVENT: 3960 case HELP_EVENT:
@@ -5344,14 +5334,6 @@ make_lispy_event (struct input_event *event)
5344 return list2 (Qmove_frame, list1 (event->frame_or_window)); 5334 return list2 (Qmove_frame, list1 (event->frame_or_window));
5345#endif 5335#endif
5346 5336
5347 case BUFFER_SWITCH_EVENT:
5348 {
5349 /* The value doesn't matter here; only the type is tested. */
5350 Lisp_Object obj;
5351 XSETBUFFER (obj, current_buffer);
5352 return obj;
5353 }
5354
5355 /* Just discard these, by returning nil. 5337 /* Just discard these, by returning nil.
5356 With MULTI_KBOARD, these events are used as placeholders 5338 With MULTI_KBOARD, these events are used as placeholders
5357 when we need to randomly delete events from the queue. 5339 when we need to randomly delete events from the queue.
@@ -6813,41 +6795,6 @@ get_input_pending (int flags)
6813 return input_pending; 6795 return input_pending;
6814} 6796}
6815 6797
6816/* Put a BUFFER_SWITCH_EVENT in the buffer
6817 so that read_key_sequence will notice the new current buffer. */
6818
6819void
6820record_asynch_buffer_change (void)
6821{
6822 /* We don't need a buffer-switch event unless Emacs is waiting for input.
6823 The purpose of the event is to make read_key_sequence look up the
6824 keymaps again. If we aren't in read_key_sequence, we don't need one,
6825 and the event could cause trouble by messing up (input-pending-p).
6826 Note: Fwaiting_for_user_input_p always returns nil when async
6827 subprocesses aren't supported. */
6828 if (!NILP (Fwaiting_for_user_input_p ()))
6829 {
6830 struct input_event event;
6831
6832 EVENT_INIT (event);
6833 event.kind = BUFFER_SWITCH_EVENT;
6834 event.frame_or_window = Qnil;
6835 event.arg = Qnil;
6836
6837 /* Make sure no interrupt happens while storing the event. */
6838#ifdef USABLE_SIGIO
6839 if (interrupt_input)
6840 kbd_buffer_store_event (&event);
6841 else
6842#endif
6843 {
6844 stop_polling ();
6845 kbd_buffer_store_event (&event);
6846 start_polling ();
6847 }
6848 }
6849}
6850
6851/* Read any terminal input already buffered up by the system 6798/* Read any terminal input already buffered up by the system
6852 into the kbd_buffer, but do not wait. 6799 into the kbd_buffer, but do not wait.
6853 6800
@@ -11581,8 +11528,6 @@ syms_of_keyboard (void)
11581 /* Menu and tool bar item parts. */ 11528 /* Menu and tool bar item parts. */
11582 DEFSYM (Qmenu_enable, "menu-enable"); 11529 DEFSYM (Qmenu_enable, "menu-enable");
11583 11530
11584 DEFSYM (Qbuffer_switch, "buffer-switch");
11585
11586#ifdef HAVE_NTGUI 11531#ifdef HAVE_NTGUI
11587 DEFSYM (Qlanguage_change, "language-change"); 11532 DEFSYM (Qlanguage_change, "language-change");
11588 DEFSYM (Qend_session, "end-session"); 11533 DEFSYM (Qend_session, "end-session");
diff --git a/src/keyboard.h b/src/keyboard.h
index 41da3a6bf44..24e9a007888 100644
--- a/src/keyboard.h
+++ b/src/keyboard.h
@@ -446,7 +446,6 @@ extern void push_kboard (struct kboard *);
446extern void push_frame_kboard (struct frame *); 446extern void push_frame_kboard (struct frame *);
447extern void pop_kboard (void); 447extern void pop_kboard (void);
448extern void temporarily_switch_to_single_kboard (struct frame *); 448extern void temporarily_switch_to_single_kboard (struct frame *);
449extern void record_asynch_buffer_change (void);
450extern void input_poll_signal (int); 449extern void input_poll_signal (int);
451extern void start_polling (void); 450extern void start_polling (void);
452extern void stop_polling (void); 451extern void stop_polling (void);
diff --git a/src/lisp.h b/src/lisp.h
index 416c9b0cac1..e83304462fa 100644
--- a/src/lisp.h
+++ b/src/lisp.h
@@ -1897,16 +1897,17 @@ ASCII_CHAR_P (intmax_t c)
1897 return 0 <= c && c < 0x80; 1897 return 0 <= c && c < 0x80;
1898} 1898}
1899 1899
1900/* A char-table is a kind of vectorlike, with contents are like a 1900/* A char-table is a kind of vectorlike, with contents like a vector,
1901 vector but with a few other slots. For some purposes, it makes 1901 but with a few additional slots. For some purposes, it makes sense
1902 sense to handle a char-table with type struct Lisp_Vector. An 1902 to handle a char-table as type 'struct Lisp_Vector'. An element of
1903 element of a char table can be any Lisp objects, but if it is a sub 1903 a char-table can be any Lisp object, but if it is a sub-char-table,
1904 char-table, we treat it a table that contains information of a 1904 we treat it as a table that contains information of a specific
1905 specific range of characters. A sub char-table is like a vector but 1905 range of characters. A sub-char-table is like a vector, but with
1906 with two integer fields between the header and Lisp data, which means 1906 two integer fields between the header and Lisp data, which means
1907 that it has to be marked with some precautions (see mark_char_table 1907 that it has to be marked with some precautions (see mark_char_table
1908 in alloc.c). A sub char-table appears only in an element of a char-table, 1908 in alloc.c). A sub-char-table appears only in an element of a
1909 and there's no way to access it directly from Emacs Lisp program. */ 1909 char-table, and there's no way to access it directly from a Lisp
1910 program. */
1910 1911
1911enum CHARTAB_SIZE_BITS 1912enum CHARTAB_SIZE_BITS
1912 { 1913 {
@@ -1926,11 +1927,11 @@ struct Lisp_Char_Table
1926 contents, and extras slots. */ 1927 contents, and extras slots. */
1927 union vectorlike_header header; 1928 union vectorlike_header header;
1928 1929
1929 /* This holds a default value, 1930 /* This holds the default value, which is used whenever the value
1930 which is used whenever the value for a specific character is nil. */ 1931 for a specific character is nil. */
1931 Lisp_Object defalt; 1932 Lisp_Object defalt;
1932 1933
1933 /* This points to another char table, which we inherit from when the 1934 /* This points to another char table, from which we inherit when the
1934 value for a specific character is nil. The `defalt' slot takes 1935 value for a specific character is nil. The `defalt' slot takes
1935 precedence over this. */ 1936 precedence over this. */
1936 Lisp_Object parent; 1937 Lisp_Object parent;
@@ -1939,8 +1940,8 @@ struct Lisp_Char_Table
1939 meant for. */ 1940 meant for. */
1940 Lisp_Object purpose; 1941 Lisp_Object purpose;
1941 1942
1942 /* The bottom sub char-table for characters of the range 0..127. It 1943 /* The bottom sub char-table for characters in the range 0..127. It
1943 is nil if none of ASCII character has a specific value. */ 1944 is nil if no ASCII character has a specific value. */
1944 Lisp_Object ascii; 1945 Lisp_Object ascii;
1945 1946
1946 Lisp_Object contents[(1 << CHARTAB_SIZE_BITS_0)]; 1947 Lisp_Object contents[(1 << CHARTAB_SIZE_BITS_0)];
@@ -2015,7 +2016,7 @@ CHAR_TABLE_REF_ASCII (Lisp_Object ct, ptrdiff_t idx)
2015} 2016}
2016 2017
2017/* Almost equivalent to Faref (CT, IDX) with optimization for ASCII 2018/* Almost equivalent to Faref (CT, IDX) with optimization for ASCII
2018 characters. Do not check validity of CT. */ 2019 characters. Does not check validity of CT. */
2019INLINE Lisp_Object 2020INLINE Lisp_Object
2020CHAR_TABLE_REF (Lisp_Object ct, int idx) 2021CHAR_TABLE_REF (Lisp_Object ct, int idx)
2021{ 2022{
@@ -2025,7 +2026,7 @@ CHAR_TABLE_REF (Lisp_Object ct, int idx)
2025} 2026}
2026 2027
2027/* Equivalent to Faset (CT, IDX, VAL) with optimization for ASCII and 2028/* Equivalent to Faset (CT, IDX, VAL) with optimization for ASCII and
2028 8-bit European characters. Do not check validity of CT. */ 2029 8-bit European characters. Does not check validity of CT. */
2029INLINE void 2030INLINE void
2030CHAR_TABLE_SET (Lisp_Object ct, int idx, Lisp_Object val) 2031CHAR_TABLE_SET (Lisp_Object ct, int idx, Lisp_Object val)
2031{ 2032{
diff --git a/src/nsterm.m b/src/nsterm.m
index 0729c961bdf..7972fa4dabb 100644
--- a/src/nsterm.m
+++ b/src/nsterm.m
@@ -1166,7 +1166,6 @@ ns_update_end (struct frame *f)
1166 { 1166 {
1167#endif 1167#endif
1168 [NSGraphicsContext setCurrentContext:nil]; 1168 [NSGraphicsContext setCurrentContext:nil];
1169 [view setNeedsDisplay:YES];
1170#if MAC_OS_X_VERSION_MIN_REQUIRED < 101400 1169#if MAC_OS_X_VERSION_MIN_REQUIRED < 101400
1171 } 1170 }
1172 else 1171 else
@@ -3056,7 +3055,7 @@ ns_clear_under_internal_border (struct frame *f)
3056 if (!face) 3055 if (!face)
3057 return; 3056 return;
3058 3057
3059 ns_focus (f, &frame_rect, 1); 3058 ns_focus (f, NULL, 1);
3060 [ns_lookup_indexed_color (NS_FACE_BACKGROUND (face), f) set]; 3059 [ns_lookup_indexed_color (NS_FACE_BACKGROUND (face), f) set];
3061 for (int i = 0; i < 4 ; i++) 3060 for (int i = 0; i < 4 ; i++)
3062 { 3061 {
@@ -4987,8 +4986,8 @@ ns_set_vertical_scroll_bar (struct window *window,
4987 [bar removeFromSuperview]; 4986 [bar removeFromSuperview];
4988 wset_vertical_scroll_bar (window, Qnil); 4987 wset_vertical_scroll_bar (window, Qnil);
4989 [bar release]; 4988 [bar release];
4989 ns_clear_frame_area (f, left, top, width, height);
4990 } 4990 }
4991 ns_clear_frame_area (f, left, top, width, height);
4992 unblock_input (); 4991 unblock_input ();
4993 return; 4992 return;
4994 } 4993 }
@@ -5010,7 +5009,7 @@ ns_set_vertical_scroll_bar (struct window *window,
5010 r.size.width = oldRect.size.width; 5009 r.size.width = oldRect.size.width;
5011 if (FRAME_LIVE_P (f) && !NSEqualRects (oldRect, r)) 5010 if (FRAME_LIVE_P (f) && !NSEqualRects (oldRect, r))
5012 { 5011 {
5013 if (oldRect.origin.x != r.origin.x) 5012 if (! NSEqualRects (oldRect, r))
5014 ns_clear_frame_area (f, left, top, width, height); 5013 ns_clear_frame_area (f, left, top, width, height);
5015 [bar setFrame: r]; 5014 [bar setFrame: r];
5016 } 5015 }
@@ -5088,8 +5087,7 @@ ns_set_horizontal_scroll_bar (struct window *window,
5088 oldRect = [bar frame]; 5087 oldRect = [bar frame];
5089 if (FRAME_LIVE_P (f) && !NSEqualRects (oldRect, r)) 5088 if (FRAME_LIVE_P (f) && !NSEqualRects (oldRect, r))
5090 { 5089 {
5091 if (oldRect.origin.y != r.origin.y) 5090 ns_clear_frame_area (f, left, top, width, height);
5092 ns_clear_frame_area (f, left, top, width, height);
5093 [bar setFrame: r]; 5091 [bar setFrame: r];
5094 update_p = YES; 5092 update_p = YES;
5095 } 5093 }
diff --git a/src/process.c b/src/process.c
index 9926993fae9..b2d94d8f8a8 100644
--- a/src/process.c
+++ b/src/process.c
@@ -5328,19 +5328,9 @@ wait_reading_process_output (intmax_t time_limit, int nsecs, int read_kbd,
5328 do 5328 do
5329 { 5329 {
5330 unsigned old_timers_run = timers_run; 5330 unsigned old_timers_run = timers_run;
5331 struct buffer *old_buffer = current_buffer;
5332 Lisp_Object old_window = selected_window;
5333 5331
5334 timer_delay = timer_check (); 5332 timer_delay = timer_check ();
5335 5333
5336 /* If a timer has run, this might have changed buffers
5337 an alike. Make read_key_sequence aware of that. */
5338 if (timers_run != old_timers_run
5339 && (old_buffer != current_buffer
5340 || !EQ (old_window, selected_window))
5341 && waiting_for_user_input_p == -1)
5342 record_asynch_buffer_change ();
5343
5344 if (timers_run != old_timers_run && do_display) 5334 if (timers_run != old_timers_run && do_display)
5345 /* We must retry, since a timer may have requeued itself 5335 /* We must retry, since a timer may have requeued itself
5346 and that could alter the time_delay. */ 5336 and that could alter the time_delay. */
@@ -5698,9 +5688,6 @@ wait_reading_process_output (intmax_t time_limit, int nsecs, int read_kbd,
5698 5688
5699 if (read_kbd != 0) 5689 if (read_kbd != 0)
5700 { 5690 {
5701 unsigned old_timers_run = timers_run;
5702 struct buffer *old_buffer = current_buffer;
5703 Lisp_Object old_window = selected_window;
5704 bool leave = false; 5691 bool leave = false;
5705 5692
5706 if (detect_input_pending_run_timers (do_display)) 5693 if (detect_input_pending_run_timers (do_display))
@@ -5710,14 +5697,6 @@ wait_reading_process_output (intmax_t time_limit, int nsecs, int read_kbd,
5710 leave = true; 5697 leave = true;
5711 } 5698 }
5712 5699
5713 /* If a timer has run, this might have changed buffers
5714 an alike. Make read_key_sequence aware of that. */
5715 if (timers_run != old_timers_run
5716 && waiting_for_user_input_p == -1
5717 && (old_buffer != current_buffer
5718 || !EQ (old_window, selected_window)))
5719 record_asynch_buffer_change ();
5720
5721 if (leave) 5700 if (leave)
5722 break; 5701 break;
5723 } 5702 }
@@ -6217,18 +6196,6 @@ read_and_dispose_of_process_output (struct Lisp_Process *p, char *chars,
6217 /* Restore waiting_for_user_input_p as it was 6196 /* Restore waiting_for_user_input_p as it was
6218 when we were called, in case the filter clobbered it. */ 6197 when we were called, in case the filter clobbered it. */
6219 waiting_for_user_input_p = waiting; 6198 waiting_for_user_input_p = waiting;
6220
6221#if 0 /* Call record_asynch_buffer_change unconditionally,
6222 because we might have changed minor modes or other things
6223 that affect key bindings. */
6224 if (! EQ (Fcurrent_buffer (), obuffer)
6225 || ! EQ (current_buffer->keymap, okeymap))
6226#endif
6227 /* But do it only if the caller is actually going to read events.
6228 Otherwise there's no need to make him wake up, and it could
6229 cause trouble (for example it would make sit_for return). */
6230 if (waiting_for_user_input_p == -1)
6231 record_asynch_buffer_change ();
6232} 6199}
6233 6200
6234DEFUN ("internal-default-process-filter", Finternal_default_process_filter, 6201DEFUN ("internal-default-process-filter", Finternal_default_process_filter,
@@ -7394,16 +7361,6 @@ exec_sentinel (Lisp_Object proc, Lisp_Object reason)
7394 when we were called, in case the filter clobbered it. */ 7361 when we were called, in case the filter clobbered it. */
7395 waiting_for_user_input_p = waiting; 7362 waiting_for_user_input_p = waiting;
7396 7363
7397#if 0
7398 if (! EQ (Fcurrent_buffer (), obuffer)
7399 || ! EQ (current_buffer->keymap, okeymap))
7400#endif
7401 /* But do it only if the caller is actually going to read events.
7402 Otherwise there's no need to make him wake up, and it could
7403 cause trouble (for example it would make sit_for return). */
7404 if (waiting_for_user_input_p == -1)
7405 record_asynch_buffer_change ();
7406
7407 unbind_to (count, Qnil); 7364 unbind_to (count, Qnil);
7408} 7365}
7409 7366
diff --git a/src/regex-emacs.c b/src/regex-emacs.c
index 971a5f63749..904ca0c7b95 100644
--- a/src/regex-emacs.c
+++ b/src/regex-emacs.c
@@ -3575,9 +3575,11 @@ skip_noops (re_char *p, re_char *pend)
3575 opcode. When the function finishes, *PP will be advanced past that opcode. 3575 opcode. When the function finishes, *PP will be advanced past that opcode.
3576 C is character to test (possibly after translations) and CORIG is original 3576 C is character to test (possibly after translations) and CORIG is original
3577 character (i.e. without any translations). UNIBYTE denotes whether c is 3577 character (i.e. without any translations). UNIBYTE denotes whether c is
3578 unibyte or multibyte character. */ 3578 unibyte or multibyte character.
3579 CANON_TABLE is the canonicalisation table for case folding or Qnil. */
3579static bool 3580static bool
3580execute_charset (re_char **pp, int c, int corig, bool unibyte) 3581execute_charset (re_char **pp, int c, int corig, bool unibyte,
3582 Lisp_Object canon_table)
3581{ 3583{
3582 eassume (0 <= c && 0 <= corig); 3584 eassume (0 <= c && 0 <= corig);
3583 re_char *p = *pp, *rtp = NULL; 3585 re_char *p = *pp, *rtp = NULL;
@@ -3617,11 +3619,9 @@ execute_charset (re_char **pp, int c, int corig, bool unibyte)
3617 (class_bits & BIT_BLANK && ISBLANK (c)) || 3619 (class_bits & BIT_BLANK && ISBLANK (c)) ||
3618 (class_bits & BIT_WORD && ISWORD (c)) || 3620 (class_bits & BIT_WORD && ISWORD (c)) ||
3619 ((class_bits & BIT_UPPER) && 3621 ((class_bits & BIT_UPPER) &&
3620 (ISUPPER (c) || (corig != c && 3622 (ISUPPER (corig) || (!NILP (canon_table) && ISLOWER (corig)))) ||
3621 c == downcase (corig) && ISLOWER (c)))) ||
3622 ((class_bits & BIT_LOWER) && 3623 ((class_bits & BIT_LOWER) &&
3623 (ISLOWER (c) || (corig != c && 3624 (ISLOWER (corig) || (!NILP (canon_table) && ISUPPER (corig)))) ||
3624 c == upcase (corig) && ISUPPER(c)))) ||
3625 (class_bits & BIT_PUNCT && ISPUNCT (c)) || 3625 (class_bits & BIT_PUNCT && ISPUNCT (c)) ||
3626 (class_bits & BIT_GRAPH && ISGRAPH (c)) || 3626 (class_bits & BIT_GRAPH && ISGRAPH (c)) ||
3627 (class_bits & BIT_PRINT && ISPRINT (c))) 3627 (class_bits & BIT_PRINT && ISPRINT (c)))
@@ -3696,7 +3696,8 @@ mutually_exclusive_p (struct re_pattern_buffer *bufp, re_char *p1,
3696 else if ((re_opcode_t) *p1 == charset 3696 else if ((re_opcode_t) *p1 == charset
3697 || (re_opcode_t) *p1 == charset_not) 3697 || (re_opcode_t) *p1 == charset_not)
3698 { 3698 {
3699 if (!execute_charset (&p1, c, c, !multibyte || ASCII_CHAR_P (c))) 3699 if (!execute_charset (&p1, c, c, !multibyte || ASCII_CHAR_P (c),
3700 Qnil))
3700 { 3701 {
3701 DEBUG_PRINT (" No match => fast loop.\n"); 3702 DEBUG_PRINT (" No match => fast loop.\n");
3702 return true; 3703 return true;
@@ -4367,7 +4368,7 @@ re_match_2_internal (struct re_pattern_buffer *bufp,
4367 } 4368 }
4368 4369
4369 p -= 1; 4370 p -= 1;
4370 if (!execute_charset (&p, c, corig, unibyte_char)) 4371 if (!execute_charset (&p, c, corig, unibyte_char, translate))
4371 goto fail; 4372 goto fail;
4372 4373
4373 d += len; 4374 d += len;
diff --git a/src/termhooks.h b/src/termhooks.h
index c28c3fbbd02..276b0687e6f 100644
--- a/src/termhooks.h
+++ b/src/termhooks.h
@@ -160,7 +160,6 @@ enum event_kind
160 SELECTION_REQUEST_EVENT, /* Another X client wants a selection from us. 160 SELECTION_REQUEST_EVENT, /* Another X client wants a selection from us.
161 See `struct selection_input_event'. */ 161 See `struct selection_input_event'. */
162 SELECTION_CLEAR_EVENT, /* Another X client cleared our selection. */ 162 SELECTION_CLEAR_EVENT, /* Another X client cleared our selection. */
163 BUFFER_SWITCH_EVENT, /* A process filter has switched buffers. */
164 DELETE_WINDOW_EVENT, /* An X client said "delete this window". */ 163 DELETE_WINDOW_EVENT, /* An X client said "delete this window". */
165#ifdef HAVE_NTGUI 164#ifdef HAVE_NTGUI
166 END_SESSION_EVENT, /* The user is logging out or shutting down. */ 165 END_SESSION_EVENT, /* The user is logging out or shutting down. */
diff --git a/src/thread.h b/src/thread.h
index a09929fa440..9697e49f09f 100644
--- a/src/thread.h
+++ b/src/thread.h
@@ -140,7 +140,6 @@ struct thread_state
140 for user-input when that process-filter was called. 140 for user-input when that process-filter was called.
141 waiting_for_input cannot be used as that is by definition 0 when 141 waiting_for_input cannot be used as that is by definition 0 when
142 lisp code is being evalled. 142 lisp code is being evalled.
143 This is also used in record_asynch_buffer_change.
144 For that purpose, this must be 0 143 For that purpose, this must be 0
145 when not inside wait_reading_process_output. */ 144 when not inside wait_reading_process_output. */
146 int m_waiting_for_user_input_p; 145 int m_waiting_for_user_input_p;
diff --git a/src/w32gui.h b/src/w32gui.h
index dfec1f08617..fc8131130fb 100644
--- a/src/w32gui.h
+++ b/src/w32gui.h
@@ -46,6 +46,7 @@ extern int w32_load_image (struct frame *f, struct image *img,
46 Lisp_Object spec_file, Lisp_Object spec_data); 46 Lisp_Object spec_file, Lisp_Object spec_data);
47extern bool w32_can_use_native_image_api (Lisp_Object); 47extern bool w32_can_use_native_image_api (Lisp_Object);
48extern void w32_gdiplus_shutdown (void); 48extern void w32_gdiplus_shutdown (void);
49extern size_t w32_image_size (struct image *);
49 50
50#define FACE_DEFAULT (~0) 51#define FACE_DEFAULT (~0)
51 52
diff --git a/src/w32term.c b/src/w32term.c
index 23cb380040b..a038e4593f4 100644
--- a/src/w32term.c
+++ b/src/w32term.c
@@ -1991,6 +1991,17 @@ w32_draw_image_foreground (struct glyph_string *s)
1991 RestoreDC (s->hdc ,-1); 1991 RestoreDC (s->hdc ,-1);
1992} 1992}
1993 1993
1994size_t
1995w32_image_size (struct image *img)
1996{
1997 BITMAP bm_info;
1998 size_t rv = 0;
1999
2000 if (GetObject (img->pixmap, sizeof (BITMAP), &bm_info))
2001 rv = bm_info.bmWidth * bm_info.bmHeight * bm_info.bmBitsPixel / 8;
2002 return rv;
2003}
2004
1994 2005
1995/* Draw a relief around the image glyph string S. */ 2006/* Draw a relief around the image glyph string S. */
1996 2007
@@ -4847,10 +4858,6 @@ w32_read_socket (struct terminal *terminal,
4847 inev.kind = DEICONIFY_EVENT; 4858 inev.kind = DEICONIFY_EVENT;
4848 XSETFRAME (inev.frame_or_window, f); 4859 XSETFRAME (inev.frame_or_window, f);
4849 } 4860 }
4850 else if (!NILP (Vframe_list) && !NILP (XCDR (Vframe_list)))
4851 /* Force a redisplay sooner or later to update the
4852 frame titles in case this is the second frame. */
4853 record_asynch_buffer_change ();
4854 } 4861 }
4855 else 4862 else
4856 { 4863 {
@@ -5468,12 +5475,6 @@ w32_read_socket (struct terminal *terminal,
5468 inev.kind = DEICONIFY_EVENT; 5475 inev.kind = DEICONIFY_EVENT;
5469 XSETFRAME (inev.frame_or_window, f); 5476 XSETFRAME (inev.frame_or_window, f);
5470 } 5477 }
5471 else if (! NILP (Vframe_list)
5472 && ! NILP (XCDR (Vframe_list)))
5473 /* Force a redisplay sooner or later
5474 to update the frame titles
5475 in case this is the second frame. */
5476 record_asynch_buffer_change ();
5477 5478
5478 /* Windows can send us a SIZE_MAXIMIZED message even 5479 /* Windows can send us a SIZE_MAXIMIZED message even
5479 when fullscreen is fullboth. The following is a 5480 when fullscreen is fullboth. The following is a
@@ -5521,12 +5522,6 @@ w32_read_socket (struct terminal *terminal,
5521 inev.kind = DEICONIFY_EVENT; 5522 inev.kind = DEICONIFY_EVENT;
5522 XSETFRAME (inev.frame_or_window, f); 5523 XSETFRAME (inev.frame_or_window, f);
5523 } 5524 }
5524 else if (! NILP (Vframe_list)
5525 && ! NILP (XCDR (Vframe_list)))
5526 /* Force a redisplay sooner or later
5527 to update the frame titles
5528 in case this is the second frame. */
5529 record_asynch_buffer_change ();
5530 } 5525 }
5531 5526
5532 if (EQ (get_frame_param (f, Qfullscreen), Qmaximized)) 5527 if (EQ (get_frame_param (f, Qfullscreen), Qmaximized))
@@ -5818,9 +5813,6 @@ w32_read_socket (struct terminal *terminal,
5818 SET_FRAME_GARBAGED (f); 5813 SET_FRAME_GARBAGED (f);
5819 DebPrint (("obscured frame %p (%s) found to be visible\n", 5814 DebPrint (("obscured frame %p (%s) found to be visible\n",
5820 f, SDATA (f->name))); 5815 f, SDATA (f->name)));
5821
5822 /* Force a redisplay sooner or later. */
5823 record_asynch_buffer_change ();
5824 } 5816 }
5825 } 5817 }
5826 } 5818 }
diff --git a/src/window.c b/src/window.c
index 6cd3122b43b..8e75e460b2b 100644
--- a/src/window.c
+++ b/src/window.c
@@ -5669,7 +5669,7 @@ window_scroll_pixel_based (Lisp_Object window, int n, bool whole, bool noerror)
5669 if (whole) 5669 if (whole)
5670 { 5670 {
5671 ptrdiff_t start_pos = IT_CHARPOS (it); 5671 ptrdiff_t start_pos = IT_CHARPOS (it);
5672 int dy = frame_line_height; 5672 int flh = frame_line_height;
5673 int ht = window_box_height (w); 5673 int ht = window_box_height (w);
5674 int nscls = sanitize_next_screen_context_lines (); 5674 int nscls = sanitize_next_screen_context_lines ();
5675 /* In the below we divide the window box height by the frame's 5675 /* In the below we divide the window box height by the frame's
@@ -5677,14 +5677,37 @@ window_scroll_pixel_based (Lisp_Object window, int n, bool whole, bool noerror)
5677 box is not an integral multiple of the line height. This is 5677 box is not an integral multiple of the line height. This is
5678 important to ensure we get back to the same position when 5678 important to ensure we get back to the same position when
5679 scrolling up, then down. */ 5679 scrolling up, then down. */
5680 dy = n * max (dy, (ht / dy - nscls) * dy); 5680 int dy = n * max (flh, (ht / flh - nscls) * flh);
5681 int goal_y;
5682 void *it_data;
5681 5683
5682 /* Note that move_it_vertically always moves the iterator to the 5684 /* Note that move_it_vertically always moves the iterator to the
5683 start of a line. So, if the last line doesn't have a newline, 5685 start of a line. So, if the last line doesn't have a newline,
5684 we would end up at the start of the line ending at ZV. */ 5686 we would end up at the start of the line ending at ZV. */
5685 if (dy <= 0) 5687 if (dy <= 0)
5686 { 5688 {
5689 goal_y = it.current_y - dy;
5687 move_it_vertically_backward (&it, -dy); 5690 move_it_vertically_backward (&it, -dy);
5691 /* Extra precision for people who want us to preserve the
5692 screen position of the cursor: effectively round DY to the
5693 nearest screen line, instead of rounding to zero; the latter
5694 causes point to move by one line after C-v followed by M-v,
5695 if the buffer has lines of different height. */
5696 if (!NILP (Vscroll_preserve_screen_position)
5697 && it.current_y - goal_y > 0.5 * flh)
5698 {
5699 it_data = bidi_shelve_cache ();
5700 struct it it2 = it;
5701
5702 move_it_by_lines (&it, -1);
5703 if (it.current_y < goal_y - 0.5 * flh)
5704 {
5705 it = it2;
5706 bidi_unshelve_cache (it_data, false);
5707 }
5708 else
5709 bidi_unshelve_cache (it_data, true);
5710 }
5688 /* Ensure we actually do move, e.g. in case we are currently 5711 /* Ensure we actually do move, e.g. in case we are currently
5689 looking at an image that is taller that the window height. */ 5712 looking at an image that is taller that the window height. */
5690 while (start_pos == IT_CHARPOS (it) 5713 while (start_pos == IT_CHARPOS (it)
@@ -5693,8 +5716,25 @@ window_scroll_pixel_based (Lisp_Object window, int n, bool whole, bool noerror)
5693 } 5716 }
5694 else if (dy > 0) 5717 else if (dy > 0)
5695 { 5718 {
5696 move_it_to (&it, ZV, -1, it.current_y + dy, -1, 5719 goal_y = it.current_y + dy;
5697 MOVE_TO_POS | MOVE_TO_Y); 5720 move_it_to (&it, ZV, -1, goal_y, -1, MOVE_TO_POS | MOVE_TO_Y);
5721 /* See the comment above, for the reasons of this
5722 extra-precision. */
5723 if (!NILP (Vscroll_preserve_screen_position)
5724 && goal_y - it.current_y > 0.5 * flh)
5725 {
5726 it_data = bidi_shelve_cache ();
5727 struct it it2 = it;
5728
5729 move_it_by_lines (&it, 1);
5730 if (it.current_y > goal_y + 0.5 * flh)
5731 {
5732 it = it2;
5733 bidi_unshelve_cache (it_data, false);
5734 }
5735 else
5736 bidi_unshelve_cache (it_data, true);
5737 }
5698 /* Ensure we actually do move, e.g. in case we are currently 5738 /* Ensure we actually do move, e.g. in case we are currently
5699 looking at an image that is taller that the window height. */ 5739 looking at an image that is taller that the window height. */
5700 while (start_pos == IT_CHARPOS (it) 5740 while (start_pos == IT_CHARPOS (it)
@@ -8206,11 +8246,17 @@ is displayed in the `mode-line' face. */);
8206 DEFVAR_LISP ("scroll-preserve-screen-position", 8246 DEFVAR_LISP ("scroll-preserve-screen-position",
8207 Vscroll_preserve_screen_position, 8247 Vscroll_preserve_screen_position,
8208 doc: /* Controls if scroll commands move point to keep its screen position unchanged. 8248 doc: /* Controls if scroll commands move point to keep its screen position unchanged.
8249
8209A value of nil means point does not keep its screen position except 8250A value of nil means point does not keep its screen position except
8210at the scroll margin or window boundary respectively. 8251at the scroll margin or window boundary respectively.
8252
8211A value of t means point keeps its screen position if the scroll 8253A value of t means point keeps its screen position if the scroll
8212command moved it vertically out of the window, e.g. when scrolling 8254command moved it vertically out of the window, e.g. when scrolling
8213by full screens. 8255by full screens. If point is within `next-screen-context-lines' lines
8256from the edges of the window, point will typically not keep its screen
8257position when doing commands like `scroll-up-command'/`scroll-down-command'
8258and the like.
8259
8214Any other value means point always keeps its screen position. 8260Any other value means point always keeps its screen position.
8215Scroll commands should have the `scroll-command' property 8261Scroll commands should have the `scroll-command' property
8216on their symbols to be controlled by this variable. */); 8262on their symbols to be controlled by this variable. */);
diff --git a/src/xdisp.c b/src/xdisp.c
index 431d8111880..a8c66f017fc 100644
--- a/src/xdisp.c
+++ b/src/xdisp.c
@@ -1925,12 +1925,12 @@ pos_visible_p (struct window *w, ptrdiff_t charpos, int *x, int *y,
1925 /* If it3_moved stays false after the 'while' loop 1925 /* If it3_moved stays false after the 'while' loop
1926 below, that means we already were at a newline 1926 below, that means we already were at a newline
1927 before the loop (e.g., the display string begins 1927 before the loop (e.g., the display string begins
1928 with a newline), so we don't need to (and cannot) 1928 with a newline), so we don't need to return to
1929 inspect the glyphs of it3.glyph_row, because 1929 the last position before the display string,
1930 PRODUCE_GLYPHS will not produce anything for a 1930 because PRODUCE_GLYPHS will not produce anything
1931 newline, and thus it3.glyph_row stays at its 1931 for a newline. */
1932 stale content it got at top of the window. */
1933 bool it3_moved = false; 1932 bool it3_moved = false;
1933 int top_x_before_string = it3.current_x;
1934 /* Finally, advance the iterator until we hit the 1934 /* Finally, advance the iterator until we hit the
1935 first display element whose character position is 1935 first display element whose character position is
1936 CHARPOS, or until the first newline from the 1936 CHARPOS, or until the first newline from the
@@ -1938,6 +1938,8 @@ pos_visible_p (struct window *w, ptrdiff_t charpos, int *x, int *y,
1938 display line. */ 1938 display line. */
1939 while (get_next_display_element (&it3)) 1939 while (get_next_display_element (&it3))
1940 { 1940 {
1941 if (!EQ (it3.object, string))
1942 top_x_before_string = it3.current_x;
1941 PRODUCE_GLYPHS (&it3); 1943 PRODUCE_GLYPHS (&it3);
1942 if (IT_CHARPOS (it3) == charpos 1944 if (IT_CHARPOS (it3) == charpos
1943 || ITERATOR_AT_END_OF_LINE_P (&it3)) 1945 || ITERATOR_AT_END_OF_LINE_P (&it3))
@@ -1952,32 +1954,26 @@ pos_visible_p (struct window *w, ptrdiff_t charpos, int *x, int *y,
1952 if (!it3.line_number_produced_p) 1954 if (!it3.line_number_produced_p)
1953 { 1955 {
1954 if (it3.lnum_pixel_width > 0) 1956 if (it3.lnum_pixel_width > 0)
1955 top_x += it3.lnum_pixel_width; 1957 {
1958 top_x += it3.lnum_pixel_width;
1959 top_x_before_string += it3.lnum_pixel_width;
1960 }
1956 else if (it.line_number_produced_p) 1961 else if (it.line_number_produced_p)
1957 top_x += it.lnum_pixel_width; 1962 {
1963 top_x += it.lnum_pixel_width;
1964 top_x_before_string += it3.lnum_pixel_width;
1965 }
1958 } 1966 }
1959 /* Normally, we would exit the above loop because we 1967 /* Normally, we would exit the above loop because we
1960 found the display element whose character 1968 found the display element whose character
1961 position is CHARPOS. For the contingency that we 1969 position is CHARPOS. For the contingency that we
1962 didn't, and stopped at the first newline from the 1970 didn't, and stopped at the first newline from the
1963 display string, move back over the glyphs 1971 display string, reset top_x to the coordinate of
1964 produced from the string, until we find the 1972 the rightmost glyph not from the string. */
1965 rightmost glyph not from the string. */
1966 if (it3_moved 1973 if (it3_moved
1967 && newline_in_string 1974 && newline_in_string
1968 && IT_CHARPOS (it3) != charpos && EQ (it3.object, string)) 1975 && IT_CHARPOS (it3) != charpos && EQ (it3.object, string))
1969 { 1976 top_x = top_x_before_string;
1970 struct glyph *g = it3.glyph_row->glyphs[TEXT_AREA]
1971 + it3.glyph_row->used[TEXT_AREA];
1972
1973 while (EQ ((g - 1)->object, string))
1974 {
1975 --g;
1976 top_x -= g->pixel_width;
1977 }
1978 eassert (g < it3.glyph_row->glyphs[TEXT_AREA]
1979 + it3.glyph_row->used[TEXT_AREA]);
1980 }
1981 } 1977 }
1982 } 1978 }
1983 1979
@@ -11755,9 +11751,10 @@ resize_mini_window (struct window *w, bool exact_p)
11755 return false; 11751 return false;
11756 11752
11757 /* By default, start display at the beginning. */ 11753 /* By default, start display at the beginning. */
11758 set_marker_both (w->start, w->contents, 11754 if (redisplay_adhoc_scroll_in_resize_mini_windows)
11759 BUF_BEGV (XBUFFER (w->contents)), 11755 set_marker_both (w->start, w->contents,
11760 BUF_BEGV_BYTE (XBUFFER (w->contents))); 11756 BUF_BEGV (XBUFFER (w->contents)),
11757 BUF_BEGV_BYTE (XBUFFER (w->contents)));
11761 11758
11762 /* Nil means don't try to resize. */ 11759 /* Nil means don't try to resize. */
11763 if ((NILP (Vresize_mini_windows) 11760 if ((NILP (Vresize_mini_windows)
@@ -11816,27 +11813,32 @@ resize_mini_window (struct window *w, bool exact_p)
11816 if (height > max_height) 11813 if (height > max_height)
11817 { 11814 {
11818 height = (max_height / unit) * unit; 11815 height = (max_height / unit) * unit;
11819 init_iterator (&it, w, ZV, ZV_BYTE, NULL, DEFAULT_FACE_ID); 11816 if (redisplay_adhoc_scroll_in_resize_mini_windows)
11820 move_it_vertically_backward (&it, height - unit); 11817 {
11821 /* The following move is usually a no-op when the stuff 11818 init_iterator (&it, w, ZV, ZV_BYTE, NULL, DEFAULT_FACE_ID);
11822 displayed in the mini-window comes entirely from buffer 11819 move_it_vertically_backward (&it, height - unit);
11823 text, but it is needed when some of it comes from overlay 11820 /* The following move is usually a no-op when the stuff
11824 strings, especially when there's an after-string at ZV. 11821 displayed in the mini-window comes entirely from buffer
11825 This happens with some completion packages, like 11822 text, but it is needed when some of it comes from overlay
11826 icomplete, ido-vertical, etc. With those packages, if we 11823 strings, especially when there's an after-string at ZV.
11827 don't force w->start to be at the beginning of a screen 11824 This happens with some completion packages, like
11828 line, important parts of the stuff in the mini-window, 11825 icomplete, ido-vertical, etc. With those packages, if we
11829 such as user prompt, will be hidden from view. */ 11826 don't force w->start to be at the beginning of a screen
11830 move_it_by_lines (&it, 0); 11827 line, important parts of the stuff in the mini-window,
11831 start = it.current.pos; 11828 such as user prompt, will be hidden from view. */
11832 /* Prevent redisplay_window from recentering, and thus from 11829 move_it_by_lines (&it, 0);
11833 overriding the window-start point we computed here. */ 11830 start = it.current.pos;
11834 w->start_at_line_beg = false; 11831 /* Prevent redisplay_window from recentering, and thus from
11832 overriding the window-start point we computed here. */
11833 w->start_at_line_beg = false;
11834 SET_MARKER_FROM_TEXT_POS (w->start, start);
11835 }
11835 } 11836 }
11836 else 11837 else
11837 SET_TEXT_POS (start, BEGV, BEGV_BYTE); 11838 {
11838 11839 SET_TEXT_POS (start, BEGV, BEGV_BYTE);
11839 SET_MARKER_FROM_TEXT_POS (w->start, start); 11840 SET_MARKER_FROM_TEXT_POS (w->start, start);
11841 }
11840 11842
11841 if (EQ (Vresize_mini_windows, Qgrow_only)) 11843 if (EQ (Vresize_mini_windows, Qgrow_only))
11842 { 11844 {
@@ -35521,6 +35523,14 @@ The initial frame is not displayed anywhere, so skipping it is
35521best except in special circumstances such as running redisplay tests 35523best except in special circumstances such as running redisplay tests
35522in batch mode. */); 35524in batch mode. */);
35523 redisplay_skip_initial_frame = true; 35525 redisplay_skip_initial_frame = true;
35526
35527 DEFVAR_BOOL ("redisplay-adhoc-scroll-in-resize-mini-windows",
35528 redisplay_adhoc_scroll_in_resize_mini_windows,
35529 doc: /* If nil always use normal scrolling in minibuffer windows.
35530Otherwise, use custom-tailored code after resizing minibuffer windows to try
35531and display the most important part of the minibuffer. */);
35532 /* See bug#43519 for some discussion around this. */
35533 redisplay_adhoc_scroll_in_resize_mini_windows = true;
35524} 35534}
35525 35535
35526 35536
diff --git a/src/xterm.c b/src/xterm.c
index 0d2452de929..3de0d2e73c0 100644
--- a/src/xterm.c
+++ b/src/xterm.c
@@ -8383,10 +8383,6 @@ handle_one_xevent (struct x_display_info *dpyinfo,
8383 inev.ie.kind = DEICONIFY_EVENT; 8383 inev.ie.kind = DEICONIFY_EVENT;
8384 XSETFRAME (inev.ie.frame_or_window, f); 8384 XSETFRAME (inev.ie.frame_or_window, f);
8385 } 8385 }
8386 else if (! NILP (Vframe_list) && ! NILP (XCDR (Vframe_list)))
8387 /* Force a redisplay sooner or later to update the
8388 frame titles in case this is the second frame. */
8389 record_asynch_buffer_change ();
8390 } 8386 }
8391 goto OTHER; 8387 goto OTHER;
8392 8388