aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorPhilip Kaludercic2022-10-15 17:38:30 +0200
committerPhilip Kaludercic2022-10-15 17:38:30 +0200
commit01e45efcd44e92dd259283df0e62653c7c20e9cc (patch)
tree552c1a6ce7d52b897cf5f089d6c589921efbe9bd /src
parent982c0e6c15535defcf6ac3c4d4169708c60efc18 (diff)
parent5933055a3e7387b0095f0df7876a208ab15f4f45 (diff)
downloademacs-01e45efcd44e92dd259283df0e62653c7c20e9cc.tar.gz
emacs-01e45efcd44e92dd259283df0e62653c7c20e9cc.zip
Merge branch 'master' into feature/package+vc
Diffstat (limited to 'src')
-rw-r--r--src/ChangeLog.134
-rw-r--r--src/dired.c5
-rw-r--r--src/editfns.c13
-rw-r--r--src/fileio.c5
-rw-r--r--src/fns.c41
-rw-r--r--src/frame.c28
-rw-r--r--src/lisp.h15
-rw-r--r--src/minibuf.c12
-rw-r--r--src/nsterm.m23
-rw-r--r--src/pdumper.c2
-rw-r--r--src/sqlite.c173
-rw-r--r--src/sysdep.c2
-rw-r--r--src/widget.c42
-rw-r--r--src/widget.h2
-rw-r--r--src/widgetprv.h3
-rw-r--r--src/window.c97
-rw-r--r--src/xdisp.c15
-rw-r--r--src/xfns.c14
-rw-r--r--src/xterm.c226
19 files changed, 481 insertions, 241 deletions
diff --git a/src/ChangeLog.13 b/src/ChangeLog.13
index abf2a9421a2..268a59219c4 100644
--- a/src/ChangeLog.13
+++ b/src/ChangeLog.13
@@ -11147,7 +11147,7 @@
111472013-11-01 Claudio Bley <claudio.bley@googlemail.com> 111472013-11-01 Claudio Bley <claudio.bley@googlemail.com>
11148 11148
11149 * image.c (pbm_next_char): New function. 11149 * image.c (pbm_next_char): New function.
11150 See http://netpbm.sourceforge.net/doc/pbm.html for the details. 11150 See https://netpbm.sourceforge.net/doc/pbm.html for the details.
11151 (pbm_scan_number): Use it. 11151 (pbm_scan_number): Use it.
11152 (Qlibjpeg_version): New variable. 11152 (Qlibjpeg_version): New variable.
11153 (syms_of_image): DEFSYM and initialize it. 11153 (syms_of_image): DEFSYM and initialize it.
@@ -14215,7 +14215,7 @@
14215 * w32.c (PEXCEPTION_POINTERS, PEXCEPTION_RECORD, PCONTEXT): Define 14215 * w32.c (PEXCEPTION_POINTERS, PEXCEPTION_RECORD, PCONTEXT): Define
14216 variables of these types so that GDB would know about them, as aid 14216 variables of these types so that GDB would know about them, as aid
14217 for debugging fatal exceptions. (Bug#15024) See also 14217 for debugging fatal exceptions. (Bug#15024) See also
14218 http://sourceware.org/ml/gdb/2013-08/msg00010.html for related 14218 https://sourceware.org/ml/gdb/2013-08/msg00010.html for related
14219 discussions. 14219 discussions.
14220 14220
142212013-08-08 Jan Djärv <jan.h.d@swipnet.se> 142212013-08-08 Jan Djärv <jan.h.d@swipnet.se>
diff --git a/src/dired.c b/src/dired.c
index c2c099f0a5f..ef729df5d2b 100644
--- a/src/dired.c
+++ b/src/dired.c
@@ -923,11 +923,12 @@ Elements of the attribute list are:
923 8. File modes, as a string of ten letters or dashes as in ls -l. 923 8. File modes, as a string of ten letters or dashes as in ls -l.
924 9. An unspecified value, present only for backward compatibility. 924 9. An unspecified value, present only for backward compatibility.
92510. inode number, as a nonnegative integer. 92510. inode number, as a nonnegative integer.
92611. Filesystem device number, as an integer. 92611. Filesystem device identifier, as an integer or a cons cell of integers.
927 927
928Large integers are bignums, so `eq' might not work on them. 928Large integers are bignums, so `eq' might not work on them.
929On most filesystems, the combination of the inode and the device 929On most filesystems, the combination of the inode and the device
930number uniquely identifies the file. 930identifier uniquely identifies the file. This unique file identification
931is provided by the access function `file-attribute-file-identifier'.
931 932
932On MS-Windows, performance depends on `w32-get-true-file-attributes', 933On MS-Windows, performance depends on `w32-get-true-file-attributes',
933which see. 934which see.
diff --git a/src/editfns.c b/src/editfns.c
index c1414071c79..3f9618edb08 100644
--- a/src/editfns.c
+++ b/src/editfns.c
@@ -3551,10 +3551,15 @@ styled_format (ptrdiff_t nargs, Lisp_Object *args, bool message)
3551 || float_conversion || conversion == 'i' 3551 || float_conversion || conversion == 'i'
3552 || conversion == 'o' || conversion == 'x' 3552 || conversion == 'o' || conversion == 'x'
3553 || conversion == 'X')) 3553 || conversion == 'X'))
3554 error ("Invalid format operation %%%c", 3554 {
3555 multibyte_format 3555 unsigned char *p = (unsigned char *) format - 1;
3556 ? STRING_CHAR ((unsigned char *) format - 1) 3556 if (multibyte_format)
3557 : *((unsigned char *) format - 1)); 3557 error ("Invalid format operation %%%c", STRING_CHAR (p));
3558 else
3559 error (*p <= 127 ? "Invalid format operation %%%c"
3560 : "Invalid format operation char #o%03o",
3561 *p);
3562 }
3558 else if (! (FIXNUMP (arg) || ((BIGNUMP (arg) || FLOATP (arg)) 3563 else if (! (FIXNUMP (arg) || ((BIGNUMP (arg) || FLOATP (arg))
3559 && conversion != 'c'))) 3564 && conversion != 'c')))
3560 error ("Format specifier doesn't match argument type"); 3565 error ("Format specifier doesn't match argument type");
diff --git a/src/fileio.c b/src/fileio.c
index dd7f85ec97f..8f96e973b25 100644
--- a/src/fileio.c
+++ b/src/fileio.c
@@ -5000,9 +5000,10 @@ by calling `format-decode', which see. */)
5000 unbind_to (count1, Qnil); 5000 unbind_to (count1, Qnil);
5001 } 5001 }
5002 5002
5003 if (!NILP (visit) && current_buffer->modtime.tv_nsec < 0) 5003 if (save_errno != 0)
5004 { 5004 {
5005 /* Signal an error if visiting a file that could not be opened. */ 5005 /* Signal an error if visiting a file that could not be opened. */
5006 eassert (!NILP (visit) && NILP (handler));
5006 report_file_errno ("Opening input file", orig_filename, save_errno); 5007 report_file_errno ("Opening input file", orig_filename, save_errno);
5007 } 5008 }
5008 5009
@@ -6362,7 +6363,7 @@ init_fileio (void)
6362 For more on why fsync does not suffice even if it works properly, see: 6363 For more on why fsync does not suffice even if it works properly, see:
6363 Roche X. Necessary step(s) to synchronize filename operations on disk. 6364 Roche X. Necessary step(s) to synchronize filename operations on disk.
6364 Austin Group Defect 672, 2013-03-19 6365 Austin Group Defect 672, 2013-03-19
6365 http://austingroupbugs.net/view.php?id=672 */ 6366 https://austingroupbugs.net/view.php?id=672 */
6366 write_region_inhibit_fsync = noninteractive; 6367 write_region_inhibit_fsync = noninteractive;
6367} 6368}
6368 6369
diff --git a/src/fns.c b/src/fns.c
index bc4915eb25b..40557923827 100644
--- a/src/fns.c
+++ b/src/fns.c
@@ -433,6 +433,22 @@ If string STR1 is greater, the value is a positive number N;
433 return Qt; 433 return Qt;
434} 434}
435 435
436/* Check whether the platform allows access to unaligned addresses for
437 size_t integers without trapping or undue penalty (a few cycles is OK).
438
439 This whitelist is incomplete but since it is only used to improve
440 performance, omitting cases is safe. */
441#if defined __x86_64__|| defined __amd64__ \
442 || defined __i386__ || defined __i386 \
443 || defined __arm64__ || defined __aarch64__ \
444 || defined __powerpc__ || defined __powerpc \
445 || defined __ppc__ || defined __ppc \
446 || defined __s390__ || defined __s390x__
447#define HAVE_FAST_UNALIGNED_ACCESS 1
448#else
449#define HAVE_FAST_UNALIGNED_ACCESS 0
450#endif
451
436DEFUN ("string-lessp", Fstring_lessp, Sstring_lessp, 2, 2, 0, 452DEFUN ("string-lessp", Fstring_lessp, Sstring_lessp, 2, 2, 0,
437 doc: /* Return non-nil if STRING1 is less than STRING2 in lexicographic order. 453 doc: /* Return non-nil if STRING1 is less than STRING2 in lexicographic order.
438Case is significant. 454Case is significant.
@@ -468,18 +484,23 @@ Symbols are also allowed; their print names are used instead. */)
468 ptrdiff_t nb1 = SBYTES (string1); 484 ptrdiff_t nb1 = SBYTES (string1);
469 ptrdiff_t nb2 = SBYTES (string2); 485 ptrdiff_t nb2 = SBYTES (string2);
470 ptrdiff_t nb = min (nb1, nb2); 486 ptrdiff_t nb = min (nb1, nb2);
471
472 /* First compare entire machine words. (String data is allocated
473 with word alignment.) */
474 typedef size_t word_t;
475 int ws = sizeof (word_t);
476 const word_t *w1 = (const word_t *) SDATA (string1);
477 const word_t *w2 = (const word_t *) SDATA (string2);
478 ptrdiff_t b = 0; 487 ptrdiff_t b = 0;
479 while (b < nb - ws + 1 && w1[b / ws] == w2[b / ws])
480 b += ws;
481 488
482 /* Scan forward to the differing byte (at most ws-1 bytes). */ 489 /* String data is normally allocated with word alignment, but
490 there are exceptions (notably pure strings) so we restrict the
491 wordwise skipping to safe architectures. */
492 if (HAVE_FAST_UNALIGNED_ACCESS)
493 {
494 /* First compare entire machine words. */
495 typedef size_t word_t;
496 int ws = sizeof (word_t);
497 const word_t *w1 = (const word_t *) SDATA (string1);
498 const word_t *w2 = (const word_t *) SDATA (string2);
499 while (b < nb - ws + 1 && w1[b / ws] == w2[b / ws])
500 b += ws;
501 }
502
503 /* Scan forward to the differing byte. */
483 while (b < nb && SREF (string1, b) == SREF (string2, b)) 504 while (b < nb && SREF (string1, b) == SREF (string2, b))
484 b++; 505 b++;
485 506
diff --git a/src/frame.c b/src/frame.c
index 91b9bec82c3..f076a5ba54e 100644
--- a/src/frame.c
+++ b/src/frame.c
@@ -1503,17 +1503,7 @@ do_switch_frame (Lisp_Object frame, int for_deletion, Lisp_Object norecord)
1503 1503
1504 sf->select_mini_window_flag = MINI_WINDOW_P (XWINDOW (sf->selected_window)); 1504 sf->select_mini_window_flag = MINI_WINDOW_P (XWINDOW (sf->selected_window));
1505 1505
1506 selected_frame = frame; 1506 move_minibuffers_onto_frame (sf, frame, for_deletion);
1507
1508 move_minibuffers_onto_frame (sf, for_deletion);
1509
1510 if (f->select_mini_window_flag
1511 && !NILP (Fminibufferp (XWINDOW (f->minibuffer_window)->contents, Qt)))
1512 f->selected_window = f->minibuffer_window;
1513 f->select_mini_window_flag = false;
1514
1515 if (! FRAME_MINIBUF_ONLY_P (XFRAME (selected_frame)))
1516 last_nonminibuf_frame = XFRAME (selected_frame);
1517 1507
1518 /* If the selected window in the target frame is its mini-window, we move 1508 /* If the selected window in the target frame is its mini-window, we move
1519 to a different window, the most recently used one, unless there is a 1509 to a different window, the most recently used one, unless there is a
@@ -1528,6 +1518,20 @@ do_switch_frame (Lisp_Object frame, int for_deletion, Lisp_Object norecord)
1528 Fset_frame_selected_window (frame, w, Qnil); 1518 Fset_frame_selected_window (frame, w, Qnil);
1529 } 1519 }
1530 1520
1521 /* After setting `selected_frame`, we're temporarily in an inconsistent
1522 state where (selected-window) != (frame-selected-window). Until this
1523 invariant is restored we should be very careful not to run ELisp code.
1524 (bug#58343) */
1525 selected_frame = frame;
1526
1527 if (f->select_mini_window_flag
1528 && !NILP (Fminibufferp (XWINDOW (f->minibuffer_window)->contents, Qt)))
1529 f->selected_window = f->minibuffer_window;
1530 f->select_mini_window_flag = false;
1531
1532 if (! FRAME_MINIBUF_ONLY_P (XFRAME (selected_frame)))
1533 last_nonminibuf_frame = XFRAME (selected_frame);
1534
1531 Fselect_window (f->selected_window, norecord); 1535 Fselect_window (f->selected_window, norecord);
1532 1536
1533 /* We want to make sure that the next event generates a frame-switch 1537 /* We want to make sure that the next event generates a frame-switch
@@ -2110,7 +2114,7 @@ delete_frame (Lisp_Object frame, Lisp_Object force)
2110 else 2114 else
2111 /* Ensure any minibuffers on FRAME are moved onto the selected 2115 /* Ensure any minibuffers on FRAME are moved onto the selected
2112 frame. */ 2116 frame. */
2113 move_minibuffers_onto_frame (f, true); 2117 move_minibuffers_onto_frame (f, selected_frame, true);
2114 2118
2115 /* Don't let echo_area_window to remain on a deleted frame. */ 2119 /* Don't let echo_area_window to remain on a deleted frame. */
2116 if (EQ (f->minibuffer_window, echo_area_window)) 2120 if (EQ (f->minibuffer_window, echo_area_window))
diff --git a/src/lisp.h b/src/lisp.h
index 9710dbef8d2..5f6721595c0 100644
--- a/src/lisp.h
+++ b/src/lisp.h
@@ -1575,10 +1575,15 @@ struct Lisp_String
1575 { 1575 {
1576 struct 1576 struct
1577 { 1577 {
1578 ptrdiff_t size; /* MSB is used as the markbit. */ 1578 /* Number of characters in string; MSB is used as the mark bit. */
1579 ptrdiff_t size_byte; /* Set to -1 for unibyte strings, 1579 ptrdiff_t size;
1580 -2 for data in rodata, 1580 /* If nonnegative, number of bytes in the string (which is multibyte).
1581 -3 for immovable unibyte strings. */ 1581 If negative, the string is unibyte:
1582 -1 for data normally allocated
1583 -2 for data in rodata (C string constants)
1584 -3 for data that must be immovable (used for bytecode) */
1585 ptrdiff_t size_byte;
1586
1582 INTERVAL intervals; /* Text properties in this string. */ 1587 INTERVAL intervals; /* Text properties in this string. */
1583 unsigned char *data; 1588 unsigned char *data;
1584 } s; 1589 } s;
@@ -4787,7 +4792,7 @@ extern void clear_regexp_cache (void);
4787 4792
4788extern Lisp_Object Vminibuffer_list; 4793extern Lisp_Object Vminibuffer_list;
4789extern Lisp_Object last_minibuf_string; 4794extern Lisp_Object last_minibuf_string;
4790extern void move_minibuffers_onto_frame (struct frame *, bool); 4795extern void move_minibuffers_onto_frame (struct frame *, Lisp_Object, bool);
4791extern bool is_minibuffer (EMACS_INT, Lisp_Object); 4796extern bool is_minibuffer (EMACS_INT, Lisp_Object);
4792extern EMACS_INT this_minibuffer_depth (Lisp_Object); 4797extern EMACS_INT this_minibuffer_depth (Lisp_Object);
4793extern EMACS_INT minibuf_level; 4798extern EMACS_INT minibuf_level;
diff --git a/src/minibuf.c b/src/minibuf.c
index bedc5644807..3f34b1b0834 100644
--- a/src/minibuf.c
+++ b/src/minibuf.c
@@ -187,13 +187,15 @@ zip_minibuffer_stacks (Lisp_Object dest_window, Lisp_Object source_window)
187 187
188/* If `minibuffer_follows_selected_frame' is t, or we're about to 188/* If `minibuffer_follows_selected_frame' is t, or we're about to
189 delete a frame which potentially "contains" minibuffers, move them 189 delete a frame which potentially "contains" minibuffers, move them
190 from the old frame to the selected frame. This function is 190 from the old frame to the to-be-selected frame. This function is
191 intended to be called from `do_switch_frame' in frame.c. OF is the 191 intended to be called from `do_switch_frame' in frame.c. OF is the
192 old frame, FOR_DELETION is true if OF is about to be deleted. */ 192 old frame, FRAME is the to-be-selected frame, and FOR_DELETION is true
193 if OF is about to be deleted. */
193void 194void
194move_minibuffers_onto_frame (struct frame *of, bool for_deletion) 195move_minibuffers_onto_frame (struct frame *of, Lisp_Object frame,
196 bool for_deletion)
195{ 197{
196 struct frame *f = XFRAME (selected_frame); 198 struct frame *f = XFRAME (frame);
197 199
198 minibuf_window = f->minibuffer_window; 200 minibuf_window = f->minibuffer_window;
199 if (!(minibuf_level 201 if (!(minibuf_level
@@ -206,7 +208,7 @@ move_minibuffers_onto_frame (struct frame *of, bool for_deletion)
206 { 208 {
207 zip_minibuffer_stacks (f->minibuffer_window, of->minibuffer_window); 209 zip_minibuffer_stacks (f->minibuffer_window, of->minibuffer_window);
208 if (for_deletion && XFRAME (MB_frame) != of) 210 if (for_deletion && XFRAME (MB_frame) != of)
209 MB_frame = selected_frame; 211 MB_frame = frame;
210 } 212 }
211} 213}
212 214
diff --git a/src/nsterm.m b/src/nsterm.m
index 82fe58e90ec..1fc72d83f66 100644
--- a/src/nsterm.m
+++ b/src/nsterm.m
@@ -2479,7 +2479,7 @@ get_keysym_name (int keysym)
2479{ 2479{
2480 static char value[16]; 2480 static char value[16];
2481 NSTRACE ("get_keysym_name"); 2481 NSTRACE ("get_keysym_name");
2482 sprintf (value, "%d", keysym); 2482 snprintf (value, 16, "%d", keysym);
2483 return value; 2483 return value;
2484} 2484}
2485 2485
@@ -4263,7 +4263,7 @@ ns_draw_glyphless_glyph_string_foreground (struct glyph_string *s)
4263 { 4263 {
4264 unsigned int ch = glyph->u.glyphless.ch; 4264 unsigned int ch = glyph->u.glyphless.ch;
4265 eassume (ch <= MAX_CHAR); 4265 eassume (ch <= MAX_CHAR);
4266 sprintf (buf, "%0*X", ch < 0x10000 ? 4 : 6, ch); 4266 snprintf (buf, 7, "%0*X", ch < 0x10000 ? 4 : 6, ch);
4267 str = buf; 4267 str = buf;
4268 } 4268 }
4269 4269
@@ -6116,17 +6116,20 @@ ns_term_shutdown (int sig)
6116 6116
6117- (void) terminate: (id)sender 6117- (void) terminate: (id)sender
6118{ 6118{
6119 struct input_event ie;
6120 struct frame *f;
6121
6119 NSTRACE ("[EmacsApp terminate:]"); 6122 NSTRACE ("[EmacsApp terminate:]");
6120 6123
6121 struct frame *emacsframe = SELECTED_FRAME (); 6124 f = SELECTED_FRAME ();
6125 EVENT_INIT (ie);
6122 6126
6123 if (!emacs_event) 6127 ie.kind = NS_NONKEY_EVENT;
6124 return; 6128 ie.code = KEY_NS_POWER_OFF;
6129 ie.arg = Qt; /* mark as non-key event */
6130 XSETFRAME (ie.frame_or_window, f);
6125 6131
6126 emacs_event->kind = NS_NONKEY_EVENT; 6132 kbd_buffer_store_event (&ie);
6127 emacs_event->code = KEY_NS_POWER_OFF;
6128 emacs_event->arg = Qt; /* mark as non-key event */
6129 EV_TRAILER ((id)nil);
6130} 6133}
6131 6134
6132static bool 6135static bool
@@ -8593,7 +8596,7 @@ ns_create_font_panel_buttons (id target, SEL select, SEL cancel_action)
8593 EmacsLayer *layer = (EmacsLayer *)[self layer]; 8596 EmacsLayer *layer = (EmacsLayer *)[self layer];
8594 8597
8595 [layer setContentsScale:[[notification object] backingScaleFactor]]; 8598 [layer setContentsScale:[[notification object] backingScaleFactor]];
8596 [layer setColorSpace:[[[notification object] colorSpace] CGColorSpace]]; 8599 [layer setColorSpace:[(id) [[notification object] colorSpace] CGColorSpace]];
8597 8600
8598 ns_clear_frame (emacsframe); 8601 ns_clear_frame (emacsframe);
8599 expose_frame (emacsframe, 0, 0, NSWidth (frame), NSHeight (frame)); 8602 expose_frame (emacsframe, 0, 0, NSWidth (frame), NSHeight (frame));
diff --git a/src/pdumper.c b/src/pdumper.c
index 903298f17d2..5e6ccd9bd88 100644
--- a/src/pdumper.c
+++ b/src/pdumper.c
@@ -2067,7 +2067,7 @@ dump_interval_tree (struct dump_context *ctx,
2067static dump_off 2067static dump_off
2068dump_string (struct dump_context *ctx, const struct Lisp_String *string) 2068dump_string (struct dump_context *ctx, const struct Lisp_String *string)
2069{ 2069{
2070#if CHECK_STRUCTS && !defined (HASH_Lisp_String_C2CAF90352) 2070#if CHECK_STRUCTS && !defined (HASH_Lisp_String_03B2DF1C8E)
2071# error "Lisp_String changed. See CHECK_STRUCTS comment in config.h." 2071# error "Lisp_String changed. See CHECK_STRUCTS comment in config.h."
2072#endif 2072#endif
2073 /* If we have text properties, write them _after_ the string so that 2073 /* If we have text properties, write them _after_ the string so that
diff --git a/src/sqlite.c b/src/sqlite.c
index 54bfb7b6c61..1526e344e53 100644
--- a/src/sqlite.c
+++ b/src/sqlite.c
@@ -51,6 +51,7 @@ DEF_DLL_FN (SQLITE_API int, sqlite3_bind_double, (sqlite3_stmt*, int, double));
51DEF_DLL_FN (SQLITE_API int, sqlite3_bind_null, (sqlite3_stmt*, int)); 51DEF_DLL_FN (SQLITE_API int, sqlite3_bind_null, (sqlite3_stmt*, int));
52DEF_DLL_FN (SQLITE_API int, sqlite3_bind_int, (sqlite3_stmt*, int, int)); 52DEF_DLL_FN (SQLITE_API int, sqlite3_bind_int, (sqlite3_stmt*, int, int));
53DEF_DLL_FN (SQLITE_API const char*, sqlite3_errmsg, (sqlite3*)); 53DEF_DLL_FN (SQLITE_API const char*, sqlite3_errmsg, (sqlite3*));
54DEF_DLL_FN (SQLITE_API const char*, sqlite3_errstr, (int));
54DEF_DLL_FN (SQLITE_API int, sqlite3_step, (sqlite3_stmt*)); 55DEF_DLL_FN (SQLITE_API int, sqlite3_step, (sqlite3_stmt*));
55DEF_DLL_FN (SQLITE_API int, sqlite3_changes, (sqlite3*)); 56DEF_DLL_FN (SQLITE_API int, sqlite3_changes, (sqlite3*));
56DEF_DLL_FN (SQLITE_API int, sqlite3_column_count, (sqlite3_stmt*)); 57DEF_DLL_FN (SQLITE_API int, sqlite3_column_count, (sqlite3_stmt*));
@@ -88,6 +89,7 @@ DEF_DLL_FN (SQLITE_API int, sqlite3_load_extension,
88# undef sqlite3_bind_null 89# undef sqlite3_bind_null
89# undef sqlite3_bind_int 90# undef sqlite3_bind_int
90# undef sqlite3_errmsg 91# undef sqlite3_errmsg
92# undef sqlite3_errstr
91# undef sqlite3_step 93# undef sqlite3_step
92# undef sqlite3_changes 94# undef sqlite3_changes
93# undef sqlite3_column_count 95# undef sqlite3_column_count
@@ -112,6 +114,7 @@ DEF_DLL_FN (SQLITE_API int, sqlite3_load_extension,
112# define sqlite3_bind_null fn_sqlite3_bind_null 114# define sqlite3_bind_null fn_sqlite3_bind_null
113# define sqlite3_bind_int fn_sqlite3_bind_int 115# define sqlite3_bind_int fn_sqlite3_bind_int
114# define sqlite3_errmsg fn_sqlite3_errmsg 116# define sqlite3_errmsg fn_sqlite3_errmsg
117# define sqlite3_errstr fn_sqlite3_errstr
115# define sqlite3_step fn_sqlite3_step 118# define sqlite3_step fn_sqlite3_step
116# define sqlite3_changes fn_sqlite3_changes 119# define sqlite3_changes fn_sqlite3_changes
117# define sqlite3_column_count fn_sqlite3_column_count 120# define sqlite3_column_count fn_sqlite3_column_count
@@ -139,6 +142,7 @@ load_dll_functions (HMODULE library)
139 LOAD_DLL_FN (library, sqlite3_bind_null); 142 LOAD_DLL_FN (library, sqlite3_bind_null);
140 LOAD_DLL_FN (library, sqlite3_bind_int); 143 LOAD_DLL_FN (library, sqlite3_bind_int);
141 LOAD_DLL_FN (library, sqlite3_errmsg); 144 LOAD_DLL_FN (library, sqlite3_errmsg);
145 LOAD_DLL_FN (library, sqlite3_errstr);
142 LOAD_DLL_FN (library, sqlite3_step); 146 LOAD_DLL_FN (library, sqlite3_step);
143 LOAD_DLL_FN (library, sqlite3_changes); 147 LOAD_DLL_FN (library, sqlite3_changes);
144 LOAD_DLL_FN (library, sqlite3_column_count); 148 LOAD_DLL_FN (library, sqlite3_column_count);
@@ -373,72 +377,6 @@ bind_values (sqlite3 *db, sqlite3_stmt *stmt, Lisp_Object values)
373 return NULL; 377 return NULL;
374} 378}
375 379
376DEFUN ("sqlite-execute", Fsqlite_execute, Ssqlite_execute, 2, 3, 0,
377 doc: /* Execute a non-select SQL statement.
378If VALUES is non-nil, it should be a vector or a list of values
379to bind when executing a statement like
380
381 insert into foo values (?, ?, ...)
382
383Value is the number of affected rows. */)
384 (Lisp_Object db, Lisp_Object query, Lisp_Object values)
385{
386 check_sqlite (db, false);
387 CHECK_STRING (query);
388 if (!(NILP (values) || CONSP (values) || VECTORP (values)))
389 xsignal1 (Qerror, build_string ("VALUES must be a list or a vector"));
390
391 sqlite3 *sdb = XSQLITE (db)->db;
392 Lisp_Object retval = Qnil;
393 const char *errmsg = NULL;
394 Lisp_Object encoded = encode_string (query);
395 sqlite3_stmt *stmt = NULL;
396
397 /* We only execute the first statement -- if there's several
398 (separated by a semicolon), the subsequent statements won't be
399 done. */
400 int ret = sqlite3_prepare_v2 (sdb, SSDATA (encoded), -1, &stmt, NULL);
401 if (ret != SQLITE_OK)
402 {
403 if (stmt != NULL)
404 {
405 sqlite3_finalize (stmt);
406 sqlite3_reset (stmt);
407 }
408
409 errmsg = sqlite3_errmsg (sdb);
410 goto exit;
411 }
412
413 /* Bind ? values. */
414 if (!NILP (values)) {
415 const char *err = bind_values (sdb, stmt, values);
416 if (err != NULL)
417 {
418 errmsg = err;
419 goto exit;
420 }
421 }
422
423 ret = sqlite3_step (stmt);
424 sqlite3_finalize (stmt);
425 if (ret != SQLITE_OK && ret != SQLITE_DONE)
426 {
427 errmsg = sqlite3_errmsg (sdb);
428 goto exit;
429 }
430
431 retval = make_fixnum (sqlite3_changes (sdb));
432
433 exit:
434 if (errmsg != NULL)
435 xsignal1 (ret == SQLITE_LOCKED || ret == SQLITE_BUSY?
436 Qsqlite_locked_error: Qerror,
437 build_string (errmsg));
438
439 return retval;
440}
441
442static Lisp_Object 380static Lisp_Object
443row_to_value (sqlite3_stmt *stmt) 381row_to_value (sqlite3_stmt *stmt)
444{ 382{
@@ -484,6 +422,94 @@ row_to_value (sqlite3_stmt *stmt)
484} 422}
485 423
486static Lisp_Object 424static Lisp_Object
425sqlite_prepare_errmsg (int code, sqlite3 *sdb)
426{
427 Lisp_Object errmsg = build_string (sqlite3_errstr (code));
428 /* More details about what went wrong. */
429 const char *sql_error = sqlite3_errmsg (sdb);
430 if (sql_error)
431 return CALLN (Fformat, build_string ("%s (%s)"),
432 errmsg, build_string (sql_error));
433 else
434 return errmsg;
435}
436
437DEFUN ("sqlite-execute", Fsqlite_execute, Ssqlite_execute, 2, 3, 0,
438 doc: /* Execute a non-select SQL statement.
439If VALUES is non-nil, it should be a vector or a list of values
440to bind when executing a statement like
441
442 insert into foo values (?, ?, ...)
443
444Value is the number of affected rows. */)
445 (Lisp_Object db, Lisp_Object query, Lisp_Object values)
446{
447 check_sqlite (db, false);
448 CHECK_STRING (query);
449 if (!(NILP (values) || CONSP (values) || VECTORP (values)))
450 xsignal1 (Qerror, build_string ("VALUES must be a list or a vector"));
451
452 sqlite3 *sdb = XSQLITE (db)->db;
453 Lisp_Object errmsg = Qnil,
454 encoded = encode_string (query);
455 sqlite3_stmt *stmt = NULL;
456
457 /* We only execute the first statement -- if there's several
458 (separated by a semicolon), the subsequent statements won't be
459 done. */
460 int ret = sqlite3_prepare_v2 (sdb, SSDATA (encoded), -1, &stmt, NULL);
461 if (ret != SQLITE_OK)
462 {
463 if (stmt != NULL)
464 {
465 sqlite3_finalize (stmt);
466 sqlite3_reset (stmt);
467 }
468
469 errmsg = sqlite_prepare_errmsg (ret, sdb);
470 goto exit;
471 }
472
473 /* Bind ? values. */
474 if (!NILP (values))
475 {
476 const char *err = bind_values (sdb, stmt, values);
477 if (err != NULL)
478 {
479 errmsg = build_string (err);
480 goto exit;
481 }
482 }
483
484 ret = sqlite3_step (stmt);
485
486 if (ret == SQLITE_ROW)
487 {
488 Lisp_Object data = Qnil;
489 do
490 data = Fcons (row_to_value (stmt), data);
491 while (sqlite3_step (stmt) == SQLITE_ROW);
492
493 sqlite3_finalize (stmt);
494 return Fnreverse (data);
495 }
496 else if (ret == SQLITE_OK || ret == SQLITE_DONE)
497 {
498 Lisp_Object rows = make_fixnum (sqlite3_changes (sdb));
499 sqlite3_finalize (stmt);
500 return rows;
501 }
502 else
503 errmsg = build_string (sqlite3_errmsg (sdb));
504
505 exit:
506 sqlite3_finalize (stmt);
507 xsignal1 (ret == SQLITE_LOCKED || ret == SQLITE_BUSY?
508 Qsqlite_locked_error: Qerror,
509 errmsg);
510}
511
512static Lisp_Object
487column_names (sqlite3_stmt *stmt) 513column_names (sqlite3_stmt *stmt)
488{ 514{
489 Lisp_Object columns = Qnil; 515 Lisp_Object columns = Qnil;
@@ -517,9 +543,8 @@ which means that we return a set object that can be queried with
517 xsignal1 (Qerror, build_string ("VALUES must be a list or a vector")); 543 xsignal1 (Qerror, build_string ("VALUES must be a list or a vector"));
518 544
519 sqlite3 *sdb = XSQLITE (db)->db; 545 sqlite3 *sdb = XSQLITE (db)->db;
520 Lisp_Object retval = Qnil; 546 Lisp_Object retval = Qnil, errmsg = Qnil,
521 const char *errmsg = NULL; 547 encoded = encode_string (query);
522 Lisp_Object encoded = encode_string (query);
523 548
524 sqlite3_stmt *stmt = NULL; 549 sqlite3_stmt *stmt = NULL;
525 int ret = sqlite3_prepare_v2 (sdb, SSDATA (encoded), SBYTES (encoded), 550 int ret = sqlite3_prepare_v2 (sdb, SSDATA (encoded), SBYTES (encoded),
@@ -528,7 +553,7 @@ which means that we return a set object that can be queried with
528 { 553 {
529 if (stmt) 554 if (stmt)
530 sqlite3_finalize (stmt); 555 sqlite3_finalize (stmt);
531 556 errmsg = sqlite_prepare_errmsg (ret, sdb);
532 goto exit; 557 goto exit;
533 } 558 }
534 559
@@ -539,7 +564,7 @@ which means that we return a set object that can be queried with
539 if (err != NULL) 564 if (err != NULL)
540 { 565 {
541 sqlite3_finalize (stmt); 566 sqlite3_finalize (stmt);
542 errmsg = err; 567 errmsg = build_string (err);
543 goto exit; 568 goto exit;
544 } 569 }
545 } 570 }
@@ -553,7 +578,7 @@ which means that we return a set object that can be queried with
553 578
554 /* Return the data directly. */ 579 /* Return the data directly. */
555 Lisp_Object data = Qnil; 580 Lisp_Object data = Qnil;
556 while ((ret = sqlite3_step (stmt)) == SQLITE_ROW) 581 while (sqlite3_step (stmt) == SQLITE_ROW)
557 data = Fcons (row_to_value (stmt), data); 582 data = Fcons (row_to_value (stmt), data);
558 583
559 if (EQ (return_type, Qfull)) 584 if (EQ (return_type, Qfull))
@@ -563,8 +588,8 @@ which means that we return a set object that can be queried with
563 sqlite3_finalize (stmt); 588 sqlite3_finalize (stmt);
564 589
565 exit: 590 exit:
566 if (errmsg != NULL) 591 if (! NILP (errmsg))
567 xsignal1 (Qerror, build_string (errmsg)); 592 xsignal1 (Qerror, errmsg);
568 593
569 return retval; 594 return retval;
570} 595}
diff --git a/src/sysdep.c b/src/sysdep.c
index abb385d1388..736723bdf3d 100644
--- a/src/sysdep.c
+++ b/src/sysdep.c
@@ -2432,7 +2432,7 @@ emacs_pipe (int fd[2])
2432 2432
2433/* Approximate posix_close and POSIX_CLOSE_RESTART well enough for Emacs. 2433/* Approximate posix_close and POSIX_CLOSE_RESTART well enough for Emacs.
2434 For the background behind this mess, please see Austin Group defect 529 2434 For the background behind this mess, please see Austin Group defect 529
2435 <http://austingroupbugs.net/view.php?id=529>. */ 2435 <https://austingroupbugs.net/view.php?id=529>. */
2436 2436
2437#ifndef POSIX_CLOSE_RESTART 2437#ifndef POSIX_CLOSE_RESTART
2438# define POSIX_CLOSE_RESTART 1 2438# define POSIX_CLOSE_RESTART 1
diff --git a/src/widget.c b/src/widget.c
index 5a75cdaca8e..aaab33b6d8e 100644
--- a/src/widget.c
+++ b/src/widget.c
@@ -195,7 +195,7 @@ round_size_to_char (EmacsFrame ew, Dimension in_width, Dimension in_height,
195 out_width, out_height); 195 out_width, out_height);
196} 196}
197 197
198static Widget 198static WMShellWidget
199get_wm_shell (Widget w) 199get_wm_shell (Widget w)
200{ 200{
201 Widget wmshell; 201 Widget wmshell;
@@ -204,7 +204,7 @@ get_wm_shell (Widget w)
204 wmshell && !XtIsWMShell (wmshell); 204 wmshell && !XtIsWMShell (wmshell);
205 wmshell = XtParent (wmshell)); 205 wmshell = XtParent (wmshell));
206 206
207 return wmshell; 207 return (WMShellWidget) wmshell;
208} 208}
209 209
210#if 0 /* Currently not used. */ 210#if 0 /* Currently not used. */
@@ -269,8 +269,8 @@ set_frame_size (EmacsFrame ew)
269 (f, build_string ("set_frame_size")); 269 (f, build_string ("set_frame_size"));
270} 270}
271 271
272static void 272static bool
273update_wm_hints (Widget wmshell, EmacsFrame ew) 273update_wm_hints (WMShellWidget wmshell, EmacsFrame ew)
274{ 274{
275 int cw; 275 int cw;
276 int ch; 276 int ch;
@@ -280,6 +280,12 @@ update_wm_hints (Widget wmshell, EmacsFrame ew)
280 int char_height; 280 int char_height;
281 int base_width; 281 int base_width;
282 int base_height; 282 int base_height;
283 char buffer[sizeof wmshell->wm.size_hints];
284 char *hints_ptr;
285
286 /* Copy the old size hints to the buffer. */
287 memcpy (buffer, &wmshell->wm.size_hints,
288 sizeof wmshell->wm.size_hints);
283 289
284 pixel_to_char_size (ew, ew->core.width, ew->core.height, 290 pixel_to_char_size (ew, ew->core.width, ew->core.height,
285 &char_width, &char_height); 291 &char_width, &char_height);
@@ -292,27 +298,29 @@ update_wm_hints (Widget wmshell, EmacsFrame ew)
292 base_height = (wmshell->core.height - ew->core.height 298 base_height = (wmshell->core.height - ew->core.height
293 + (rounded_height - (char_height * ch))); 299 + (rounded_height - (char_height * ch)));
294 300
295 /* Ensure that Xt actually sets window manager hint flags specified 301 XtVaSetValues ((Widget) wmshell,
296 by the caller by making sure XtNminWidth (a relatively harmless
297 resource) always changes each time this function is invoked. */
298 ew->emacs_frame.size_switch = !ew->emacs_frame.size_switch;
299
300 XtVaSetValues (wmshell,
301 XtNbaseWidth, (XtArgVal) base_width, 302 XtNbaseWidth, (XtArgVal) base_width,
302 XtNbaseHeight, (XtArgVal) base_height, 303 XtNbaseHeight, (XtArgVal) base_height,
303 XtNwidthInc, (XtArgVal) (frame_resize_pixelwise ? 1 : cw), 304 XtNwidthInc, (XtArgVal) (frame_resize_pixelwise ? 1 : cw),
304 XtNheightInc, (XtArgVal) (frame_resize_pixelwise ? 1 : ch), 305 XtNheightInc, (XtArgVal) (frame_resize_pixelwise ? 1 : ch),
305 XtNminWidth, (XtArgVal) (base_width 306 XtNminWidth, (XtArgVal) base_width,
306 + ew->emacs_frame.size_switch), 307 XtNminHeight, (XtArgVal) base_height,
307 XtNminHeight, (XtArgVal) (base_height
308 + ew->emacs_frame.size_switch),
309 NULL); 308 NULL);
309
310 /* Return if size hints really changed. If they did not, then Xt
311 probably didn't set them either (or take the flags into
312 account.) */
313 hints_ptr = (char *) &wmshell->wm.size_hints;
314
315 /* Skip flags, which is unsigned long. */
316 return memcmp (hints_ptr + sizeof (long), buffer + sizeof (long),
317 sizeof wmshell->wm.wm_hints - sizeof (long));
310} 318}
311 319
312void 320bool
313widget_update_wm_size_hints (Widget widget, Widget frame) 321widget_update_wm_size_hints (Widget widget, Widget frame)
314{ 322{
315 update_wm_hints (widget, (EmacsFrame) frame); 323 return update_wm_hints ((WMShellWidget) widget, (EmacsFrame) frame);
316} 324}
317 325
318static void 326static void
@@ -357,8 +365,6 @@ EmacsFrameInitialize (Widget request, Widget new,
357 exit (1); 365 exit (1);
358 } 366 }
359 367
360 ew->emacs_frame.size_switch = 1;
361
362 update_from_various_frame_slots (ew); 368 update_from_various_frame_slots (ew);
363 set_frame_size (ew); 369 set_frame_size (ew);
364} 370}
diff --git a/src/widget.h b/src/widget.h
index 2906d5ff9ec..cf83cb10781 100644
--- a/src/widget.h
+++ b/src/widget.h
@@ -97,6 +97,6 @@ extern struct _DisplayContext *display_context;
97/* Special entry points */ 97/* Special entry points */
98void EmacsFrameSetCharSize (Widget, int, int); 98void EmacsFrameSetCharSize (Widget, int, int);
99void widget_store_internal_border (Widget widget); 99void widget_store_internal_border (Widget widget);
100void widget_update_wm_size_hints (Widget widget, Widget frame); 100bool widget_update_wm_size_hints (Widget widget, Widget frame);
101 101
102#endif /* _EmacsFrame_h */ 102#endif /* _EmacsFrame_h */
diff --git a/src/widgetprv.h b/src/widgetprv.h
index fe960326b03..3a4d9206ffe 100644
--- a/src/widgetprv.h
+++ b/src/widgetprv.h
@@ -49,9 +49,6 @@ typedef struct {
49 49
50 Boolean visual_bell; /* flash instead of beep */ 50 Boolean visual_bell; /* flash instead of beep */
51 int bell_volume; /* how loud is beep */ 51 int bell_volume; /* how loud is beep */
52 int size_switch; /* hack to make setting size
53 hints work correctly */
54
55 /* private state */ 52 /* private state */
56 53
57} EmacsFramePart; 54} EmacsFramePart;
diff --git a/src/window.c b/src/window.c
index da80fabe33f..4e8b352e164 100644
--- a/src/window.c
+++ b/src/window.c
@@ -52,6 +52,7 @@ static ptrdiff_t get_leaf_windows (struct window *, struct window **,
52 ptrdiff_t); 52 ptrdiff_t);
53static void window_scroll_pixel_based (Lisp_Object, int, bool, bool); 53static void window_scroll_pixel_based (Lisp_Object, int, bool, bool);
54static void window_scroll_line_based (Lisp_Object, int, bool, bool); 54static void window_scroll_line_based (Lisp_Object, int, bool, bool);
55static void window_scroll_for_long_lines (struct window *, int, bool);
55static void foreach_window (struct frame *, 56static void foreach_window (struct frame *,
56 bool (* fn) (struct window *, void *), 57 bool (* fn) (struct window *, void *),
57 void *); 58 void *);
@@ -5536,19 +5537,40 @@ window_internal_height (struct window *w)
5536static void 5537static void
5537window_scroll (Lisp_Object window, EMACS_INT n, bool whole, bool noerror) 5538window_scroll (Lisp_Object window, EMACS_INT n, bool whole, bool noerror)
5538{ 5539{
5540 struct window *w = XWINDOW (window);
5541 struct buffer *b = XBUFFER (w->contents);
5542 bool long_lines_truncated =
5543 b->long_line_optimizations_p && !NILP (BVAR (b, truncate_lines));
5539 specpdl_ref count = SPECPDL_INDEX (); 5544 specpdl_ref count = SPECPDL_INDEX ();
5540 5545
5541 n = clip_to_bounds (INT_MIN, n, INT_MAX); 5546 n = clip_to_bounds (INT_MIN, n, INT_MAX);
5542 5547
5543 wset_redisplay (XWINDOW (window)); 5548 wset_redisplay (w);
5544 5549
5545 if (whole && fast_but_imprecise_scrolling) 5550 /* Does this window's buffer have very long and truncated lines? */
5551 if (b->long_line_optimizations_p
5552 && !long_lines_truncated
5553 && !NILP (Vtruncate_partial_width_windows)
5554 && w->total_cols < FRAME_COLS (XFRAME (WINDOW_FRAME (w))))
5555 {
5556 if (FIXNUMP (Vtruncate_partial_width_windows))
5557 long_lines_truncated =
5558 w->total_cols < XFIXNAT (Vtruncate_partial_width_windows);
5559 else
5560 long_lines_truncated = true;
5561 }
5562
5563 if (whole && (fast_but_imprecise_scrolling || long_lines_truncated))
5546 specbind (Qfontification_functions, Qnil); 5564 specbind (Qfontification_functions, Qnil);
5547 5565
5548 /* On GUI frames, use the pixel-based version which is much slower 5566 if (whole && long_lines_truncated)
5549 than the line-based one but can handle varying line heights. */ 5567 window_scroll_for_long_lines (w, n, noerror);
5550 if (FRAME_WINDOW_P (XFRAME (XWINDOW (window)->frame))) 5568 else if (FRAME_WINDOW_P (XFRAME (XWINDOW (window)->frame)))
5551 { 5569 {
5570
5571 /* On GUI frames, use the pixel-based version which is much
5572 slower than the line-based one, but can handle varying
5573 line heights. */
5552 record_unwind_protect_void (unwind_display_working_on_window); 5574 record_unwind_protect_void (unwind_display_working_on_window);
5553 display_working_on_window_p = true; 5575 display_working_on_window_p = true;
5554 window_scroll_pixel_based (window, n, whole, noerror); 5576 window_scroll_pixel_based (window, n, whole, noerror);
@@ -5598,6 +5620,71 @@ sanitize_next_screen_context_lines (void)
5598 return clip_to_bounds (0, next_screen_context_lines, 1000000); 5620 return clip_to_bounds (0, next_screen_context_lines, 1000000);
5599} 5621}
5600 5622
5623/* Implementation of window_scroll for very long and truncated lines.
5624 This is a simplified version, it only handles WHOLE window scrolls,
5625 and doesn't honor scroll-preserve-screen-position nor scroll-margin. */
5626static void
5627window_scroll_for_long_lines (struct window *w, int n, bool noerror)
5628{
5629 ptrdiff_t startpos = marker_position (w->start);
5630 ptrdiff_t startbyte = marker_byte_position (w->start);
5631 int nscls = sanitize_next_screen_context_lines ();
5632 register int ht = window_internal_height (w);
5633
5634 n *= max (1, ht - nscls);
5635
5636 /* If point is not visible in window, bring it inside window. */
5637 struct position pos;
5638 int rtop, rbot, dummy_rowh, dummy_vpos, dummy_x, dummy_y;
5639 if (!(PT >= startpos
5640 && PT <= ZV
5641 && startpos <= ZV
5642 && pos_visible_p (w, PT, &dummy_x, &dummy_y, &rtop, &rbot, &dummy_rowh,
5643 &dummy_vpos)
5644 && !rtop && !rbot))
5645 {
5646 pos = *vmotion (PT, PT_BYTE, - (ht / 2), w);
5647 startpos = pos.bufpos;
5648 startbyte = pos.bytepos;
5649 }
5650 SET_PT_BOTH (startpos, startbyte);
5651
5652 bool lose = n < 0 && PT == BEGV;
5653 pos = *vmotion (PT, PT_BYTE, n, w);
5654 if (lose)
5655 {
5656 if (noerror)
5657 return;
5658 else
5659 xsignal0 (Qbeginning_of_buffer);
5660 }
5661
5662 bool bolp = pos.bufpos == BEGV || FETCH_BYTE (pos.bytepos - 1) == '\n';
5663 if (pos.bufpos < ZV)
5664 {
5665 set_marker_restricted_both (w->start, w->contents,
5666 pos.bufpos, pos.bytepos);
5667 w->start_at_line_beg = bolp;
5668 wset_update_mode_line (w);
5669 /* Set force_start so that redisplay_window will run
5670 the window-scroll-functions. */
5671 w->force_start = true;
5672 SET_PT_BOTH (pos.bufpos, pos.bytepos);
5673 if (n > 0)
5674 pos = *vmotion (PT, PT_BYTE, ht / 2, w);
5675 else if (n < 0)
5676 pos = *vmotion (PT, PT_BYTE, - (ht / 2), w);
5677 SET_PT_BOTH (pos.bufpos, pos.bytepos);
5678 }
5679 else
5680 {
5681 if (noerror)
5682 return;
5683 else
5684 xsignal0 (Qend_of_buffer);
5685 }
5686}
5687
5601/* Implementation of window_scroll that works based on pixel line 5688/* Implementation of window_scroll that works based on pixel line
5602 heights. See the comment of window_scroll for parameter 5689 heights. See the comment of window_scroll for parameter
5603 descriptions. */ 5690 descriptions. */
diff --git a/src/xdisp.c b/src/xdisp.c
index 9534e27843e..e390de6a336 100644
--- a/src/xdisp.c
+++ b/src/xdisp.c
@@ -20165,7 +20165,20 @@ redisplay_window (Lisp_Object window, bool just_this_one_p)
20165 from point. */ 20165 from point. */
20166 centering_position = window_box_height (w) / 2; 20166 centering_position = window_box_height (w) / 2;
20167 } 20167 }
20168 move_it_vertically_backward (&it, centering_position); 20168 if (current_buffer->long_line_optimizations_p
20169 && it.line_wrap == TRUNCATE)
20170 {
20171 /* For very long and truncated lines, go back using a simplified
20172 method, which ignored any inaccuracies due to line-height
20173 differences, display properties/overlays, etc. */
20174 int nlines = centering_position / frame_line_height;
20175
20176 while (nlines-- && IT_CHARPOS (it) > BEGV)
20177 back_to_previous_visible_line_start (&it);
20178 reseat_1 (&it, it.current.pos, true);
20179 }
20180 else
20181 move_it_vertically_backward (&it, centering_position);
20169 20182
20170 eassert (IT_CHARPOS (it) >= BEGV); 20183 eassert (IT_CHARPOS (it) >= BEGV);
20171 20184
diff --git a/src/xfns.c b/src/xfns.c
index 8cea93c6698..91124488994 100644
--- a/src/xfns.c
+++ b/src/xfns.c
@@ -4179,11 +4179,15 @@ x_window (struct frame *f)
4179 { 4179 {
4180 /* XIM server might require some X events. */ 4180 /* XIM server might require some X events. */
4181 unsigned long fevent = NoEventMask; 4181 unsigned long fevent = NoEventMask;
4182 XGetICValues (FRAME_XIC (f), XNFilterEvents, &fevent, NULL); 4182
4183 attributes.event_mask |= fevent; 4183 if (fevent)
4184 attribute_mask = CWEventMask; 4184 {
4185 XChangeWindowAttributes (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f), 4185 XGetICValues (FRAME_XIC (f), XNFilterEvents, &fevent, NULL);
4186 attribute_mask, &attributes); 4186 attributes.event_mask |= fevent;
4187 attribute_mask = CWEventMask;
4188 XChangeWindowAttributes (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f),
4189 attribute_mask, &attributes);
4190 }
4187 } 4191 }
4188 } 4192 }
4189#endif /* HAVE_X_I18N */ 4193#endif /* HAVE_X_I18N */
diff --git a/src/xterm.c b/src/xterm.c
index aaf2e7988be..d35af7a8de2 100644
--- a/src/xterm.c
+++ b/src/xterm.c
@@ -1425,9 +1425,6 @@ struct x_client_list_window
1425 /* The width and height of the window. */ 1425 /* The width and height of the window. */
1426 int width, height; 1426 int width, height;
1427 1427
1428 /* Whether or not the window is mapped. */
1429 bool mapped_p;
1430
1431 /* A bitmask describing events Emacs was listening for from the 1428 /* A bitmask describing events Emacs was listening for from the
1432 window before some extra events were added in 1429 window before some extra events were added in
1433 `x_dnd_compute_toplevels'. */ 1430 `x_dnd_compute_toplevels'. */
@@ -1439,9 +1436,6 @@ struct x_client_list_window
1439 /* The next window in this list. */ 1436 /* The next window in this list. */
1440 struct x_client_list_window *next; 1437 struct x_client_list_window *next;
1441 1438
1442 /* The Motif protocol style of this window, if any. */
1443 uint8_t xm_protocol_style;
1444
1445 /* The extents of the frame window in each direction. */ 1439 /* The extents of the frame window in each direction. */
1446 int frame_extents_left; 1440 int frame_extents_left;
1447 int frame_extents_right; 1441 int frame_extents_right;
@@ -1452,18 +1446,24 @@ struct x_client_list_window
1452 /* The border width of this window. */ 1446 /* The border width of this window. */
1453 int border_width; 1447 int border_width;
1454 1448
1455 /* The rectangles making up the input shape. */
1456 XRectangle *input_rects;
1457
1458 /* The number of rectangles composing the input shape. */ 1449 /* The number of rectangles composing the input shape. */
1459 int n_input_rects; 1450 int n_input_rects;
1460 1451
1452 /* The rectangles making up the input shape. */
1453 XRectangle *input_rects;
1454
1461 /* The rectangles making up the bounding shape. */ 1455 /* The rectangles making up the bounding shape. */
1462 XRectangle *bounding_rects; 1456 XRectangle *bounding_rects;
1463 1457
1464 /* The number of rectangles composing the bounding shape. */ 1458 /* The number of rectangles composing the bounding shape. */
1465 int n_bounding_rects; 1459 int n_bounding_rects;
1466#endif 1460#endif
1461
1462 /* The Motif protocol style of this window, if any. */
1463 uint8_t xm_protocol_style;
1464
1465 /* Whether or not the window is mapped. */
1466 bool mapped_p;
1467}; 1467};
1468 1468
1469/* List of all toplevels in stacking order, from top to bottom. */ 1469/* List of all toplevels in stacking order, from top to bottom. */
@@ -5139,24 +5139,20 @@ x_update_opaque_region (struct frame *f, XEvent *configure)
5139 if (!FRAME_DISPLAY_INFO (f)->alpha_bits) 5139 if (!FRAME_DISPLAY_INFO (f)->alpha_bits)
5140 return; 5140 return;
5141 5141
5142 block_input ();
5143 if (f->alpha_background < 1.0) 5142 if (f->alpha_background < 1.0)
5144 XChangeProperty (FRAME_X_DISPLAY (f), 5143 XChangeProperty (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f),
5145 FRAME_X_WINDOW (f),
5146 FRAME_DISPLAY_INFO (f)->Xatom_net_wm_opaque_region, 5144 FRAME_DISPLAY_INFO (f)->Xatom_net_wm_opaque_region,
5147 XA_CARDINAL, 32, PropModeReplace, 5145 XA_CARDINAL, 32, PropModeReplace,
5148 NULL, 0); 5146 NULL, 0);
5149#ifndef HAVE_GTK3 5147#ifndef HAVE_GTK3
5150 else 5148 else
5151 XChangeProperty (FRAME_X_DISPLAY (f), 5149 XChangeProperty (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f),
5152 FRAME_X_WINDOW (f),
5153 FRAME_DISPLAY_INFO (f)->Xatom_net_wm_opaque_region, 5150 FRAME_DISPLAY_INFO (f)->Xatom_net_wm_opaque_region,
5154 XA_CARDINAL, 32, PropModeReplace, 5151 XA_CARDINAL, 32, PropModeReplace,
5155 (unsigned char *) &opaque_region, 4); 5152 (unsigned char *) &opaque_region, 4);
5156#else 5153#else
5157 else if (FRAME_TOOLTIP_P (f)) 5154 else if (FRAME_TOOLTIP_P (f))
5158 XChangeProperty (FRAME_X_DISPLAY (f), 5155 XChangeProperty (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f),
5159 FRAME_X_WINDOW (f),
5160 FRAME_DISPLAY_INFO (f)->Xatom_net_wm_opaque_region, 5156 FRAME_DISPLAY_INFO (f)->Xatom_net_wm_opaque_region,
5161 XA_CARDINAL, 32, PropModeReplace, 5157 XA_CARDINAL, 32, PropModeReplace,
5162 (unsigned char *) &opaque_region, 4); 5158 (unsigned char *) &opaque_region, 4);
@@ -5174,7 +5170,6 @@ x_update_opaque_region (struct frame *f, XEvent *configure)
5174 } 5170 }
5175 } 5171 }
5176#endif 5172#endif
5177 unblock_input ();
5178} 5173}
5179 5174
5180 5175
@@ -7144,8 +7139,6 @@ show_back_buffer (struct frame *f)
7144 cairo_t *cr; 7139 cairo_t *cr;
7145#endif 7140#endif
7146 7141
7147 block_input ();
7148
7149 if (FRAME_X_DOUBLE_BUFFERED_P (f)) 7142 if (FRAME_X_DOUBLE_BUFFERED_P (f))
7150 { 7143 {
7151#if defined HAVE_XSYNC && !defined USE_GTK && defined HAVE_CLOCK_GETTIME 7144#if defined HAVE_XSYNC && !defined USE_GTK && defined HAVE_CLOCK_GETTIME
@@ -7174,8 +7167,6 @@ show_back_buffer (struct frame *f)
7174 } 7167 }
7175 7168
7176 FRAME_X_NEED_BUFFER_FLIP (f) = false; 7169 FRAME_X_NEED_BUFFER_FLIP (f) = false;
7177
7178 unblock_input ();
7179} 7170}
7180 7171
7181#endif 7172#endif
@@ -7283,8 +7274,12 @@ XTframe_up_to_date (struct frame *f)
7283static void 7274static void
7284XTbuffer_flipping_unblocked_hook (struct frame *f) 7275XTbuffer_flipping_unblocked_hook (struct frame *f)
7285{ 7276{
7277 block_input ();
7278
7286 if (FRAME_X_NEED_BUFFER_FLIP (f)) 7279 if (FRAME_X_NEED_BUFFER_FLIP (f))
7287 show_back_buffer (f); 7280 show_back_buffer (f);
7281
7282 unblock_input ();
7288} 7283}
7289#endif 7284#endif
7290 7285
@@ -7313,8 +7308,6 @@ x_clear_under_internal_border (struct frame *f)
7313 : INTERNAL_BORDER_FACE_ID)); 7308 : INTERNAL_BORDER_FACE_ID));
7314 struct face *face = FACE_FROM_ID_OR_NULL (f, face_id); 7309 struct face *face = FACE_FROM_ID_OR_NULL (f, face_id);
7315 7310
7316 block_input ();
7317
7318 if (face) 7311 if (face)
7319 { 7312 {
7320 unsigned long color = face->background; 7313 unsigned long color = face->background;
@@ -7335,8 +7328,6 @@ x_clear_under_internal_border (struct frame *f)
7335 x_clear_area (f, width - border, 0, border, height); 7328 x_clear_area (f, width - border, 0, border, height);
7336 x_clear_area (f, 0, height - border, width, border); 7329 x_clear_area (f, 0, height - border, width, border);
7337 } 7330 }
7338
7339 unblock_input ();
7340 } 7331 }
7341} 7332}
7342 7333
@@ -7384,7 +7375,6 @@ x_after_update_window_line (struct window *w, struct glyph_row *desired_row)
7384 : INTERNAL_BORDER_FACE_ID)); 7375 : INTERNAL_BORDER_FACE_ID));
7385 struct face *face = FACE_FROM_ID_OR_NULL (f, face_id); 7376 struct face *face = FACE_FROM_ID_OR_NULL (f, face_id);
7386 7377
7387 block_input ();
7388 if (face) 7378 if (face)
7389 { 7379 {
7390 unsigned long color = face->background; 7380 unsigned long color = face->background;
@@ -7402,7 +7392,6 @@ x_after_update_window_line (struct window *w, struct glyph_row *desired_row)
7402 x_clear_area (f, 0, y, width, height); 7392 x_clear_area (f, 0, y, width, height);
7403 x_clear_area (f, FRAME_PIXEL_WIDTH (f) - width, y, width, height); 7393 x_clear_area (f, FRAME_PIXEL_WIDTH (f) - width, y, width, height);
7404 } 7394 }
7405 unblock_input ();
7406 } 7395 }
7407 } 7396 }
7408#endif 7397#endif
@@ -7601,11 +7590,27 @@ static void x_check_font (struct frame *, struct font *);
7601 user time. We don't sanitize timestamps from events sent by the X 7590 user time. We don't sanitize timestamps from events sent by the X
7602 server itself because some Lisp might have set the user time to a 7591 server itself because some Lisp might have set the user time to a
7603 ridiculously large value, and this way a more reasonable timestamp 7592 ridiculously large value, and this way a more reasonable timestamp
7604 can be obtained upon the next event. */ 7593 can be obtained upon the next event.
7594
7595 Alternatively, the server time could've overflowed.
7596
7597 SET_PROPERTY specifies whether or not to change the user time
7598 property for the active frame. The important thing is to not set
7599 the last user time upon leave events; on Metacity and GNOME Shell,
7600 mapping a new frame on top of the old frame potentially causes
7601 crossing events to be sent to the old frame if it contains the
7602 pointer, as the new frame will initially stack above the old frame.
7603 If _NET_WM_USER_TIME is changed at that point, then GNOME may get
7604 notified about the user time change on the old frame before it
7605 tries to focus the new frame, which will make it consider the new
7606 frame (whose user time property will not have been updated at that
7607 point, due to not being focused) as having been mapped
7608 out-of-order, and lower the new frame, which is typically not what
7609 users want. */
7605 7610
7606static void 7611static void
7607x_display_set_last_user_time (struct x_display_info *dpyinfo, Time time, 7612x_display_set_last_user_time (struct x_display_info *dpyinfo, Time time,
7608 bool send_event) 7613 bool send_event, bool set_property)
7609{ 7614{
7610#if defined HAVE_XSYNC && !defined USE_GTK && defined HAVE_CLOCK_GETTIME 7615#if defined HAVE_XSYNC && !defined USE_GTK && defined HAVE_CLOCK_GETTIME
7611 uint_fast64_t monotonic_time; 7616 uint_fast64_t monotonic_time;
@@ -7678,7 +7683,8 @@ x_display_set_last_user_time (struct x_display_info *dpyinfo, Time time,
7678 7683
7679#ifndef USE_GTK 7684#ifndef USE_GTK
7680 /* Don't waste bandwidth if the time hasn't actually changed. */ 7685 /* Don't waste bandwidth if the time hasn't actually changed. */
7681 if (focus_frame && old_time != dpyinfo->last_user_time) 7686 if (focus_frame && old_time != dpyinfo->last_user_time
7687 && set_property)
7682 { 7688 {
7683 time = dpyinfo->last_user_time; 7689 time = dpyinfo->last_user_time;
7684 7690
@@ -7719,6 +7725,7 @@ x_set_gtk_user_time (struct frame *f, Time time)
7719 itself. */ 7725 itself. */
7720 7726
7721#ifndef USE_GTK 7727#ifndef USE_GTK
7728
7722static void 7729static void
7723x_update_frame_user_time_window (struct frame *f) 7730x_update_frame_user_time_window (struct frame *f)
7724{ 7731{
@@ -7782,13 +7789,14 @@ x_update_frame_user_time_window (struct frame *f)
7782 } 7789 }
7783 } 7790 }
7784} 7791}
7792
7785#endif 7793#endif
7786 7794
7787void 7795void
7788x_set_last_user_time_from_lisp (struct x_display_info *dpyinfo, 7796x_set_last_user_time_from_lisp (struct x_display_info *dpyinfo,
7789 Time time) 7797 Time time)
7790{ 7798{
7791 x_display_set_last_user_time (dpyinfo, time, true); 7799 x_display_set_last_user_time (dpyinfo, time, true, true);
7792} 7800}
7793 7801
7794 7802
@@ -9595,31 +9603,49 @@ x_draw_glyph_string_box (struct glyph_string *s)
9595 9603
9596 9604
9597#ifndef USE_CAIRO 9605#ifndef USE_CAIRO
9606
9598static void 9607static void
9599x_composite_image (struct glyph_string *s, Pixmap dest, 9608x_composite_image (struct glyph_string *s, Pixmap dest,
9609#ifdef HAVE_XRENDER
9610 Picture destination,
9611#endif
9600 int srcX, int srcY, int dstX, int dstY, 9612 int srcX, int srcY, int dstX, int dstY,
9601 int width, int height) 9613 int width, int height)
9602{ 9614{
9603 Display *display = FRAME_X_DISPLAY (s->f); 9615 Display *display;
9604#ifdef HAVE_XRENDER 9616#ifdef HAVE_XRENDER
9605 if (s->img->picture && FRAME_X_PICTURE_FORMAT (s->f)) 9617 XRenderPictFormat *default_format;
9606 { 9618 XRenderPictureAttributes attr UNINIT;
9607 Picture destination; 9619#endif
9608 XRenderPictFormat *default_format;
9609 XRenderPictureAttributes attr UNINIT;
9610 9620
9611 default_format = FRAME_X_PICTURE_FORMAT (s->f); 9621 display = FRAME_X_DISPLAY (s->f);
9612 destination = XRenderCreatePicture (display, dest,
9613 default_format, 0, &attr);
9614 9622
9615 XRenderComposite (display, s->img->mask_picture ? PictOpOver : PictOpSrc, 9623#ifdef HAVE_XRENDER
9616 s->img->picture, s->img->mask_picture, destination, 9624 if (s->img->picture && FRAME_X_PICTURE_FORMAT (s->f))
9617 srcX, srcY, 9625 {
9618 srcX, srcY, 9626 if (destination == None)
9619 dstX, dstY, 9627 {
9620 width, height); 9628 /* The destination picture was not specified. This means we
9629 have to create a picture representing the */
9630 default_format = FRAME_X_PICTURE_FORMAT (s->f);
9631 destination = XRenderCreatePicture (display, dest,
9632 default_format, 0, &attr);
9633
9634 XRenderComposite (display, (s->img->mask_picture
9635 ? PictOpOver : PictOpSrc),
9636 s->img->picture, s->img->mask_picture,
9637 destination, srcX, srcY, srcX, srcY,
9638 dstX, dstY, width, height);
9639
9640 XRenderFreePicture (display, destination);
9641 }
9642 else
9643 XRenderComposite (display, (s->img->mask_picture
9644 ? PictOpOver : PictOpSrc),
9645 s->img->picture, s->img->mask_picture,
9646 destination, srcX, srcY, srcX, srcY,
9647 dstX, dstY, width, height);
9621 9648
9622 XRenderFreePicture (display, destination);
9623 return; 9649 return;
9624 } 9650 }
9625#endif 9651#endif
@@ -9629,6 +9655,7 @@ x_composite_image (struct glyph_string *s, Pixmap dest,
9629 srcX, srcY, 9655 srcX, srcY,
9630 width, height, dstX, dstY); 9656 width, height, dstX, dstY);
9631} 9657}
9658
9632#endif /* !USE_CAIRO */ 9659#endif /* !USE_CAIRO */
9633 9660
9634 9661
@@ -9707,6 +9734,9 @@ x_draw_image_foreground (struct glyph_string *s)
9707 image_rect.height = s->slice.height; 9734 image_rect.height = s->slice.height;
9708 if (gui_intersect_rectangles (&clip_rect, &image_rect, &r)) 9735 if (gui_intersect_rectangles (&clip_rect, &image_rect, &r))
9709 x_composite_image (s, FRAME_X_DRAWABLE (s->f), 9736 x_composite_image (s, FRAME_X_DRAWABLE (s->f),
9737#ifdef HAVE_XRENDER
9738 FRAME_X_PICTURE (s->f),
9739#endif
9710 s->slice.x + r.x - x, s->slice.y + r.y - y, 9740 s->slice.x + r.x - x, s->slice.y + r.y - y,
9711 r.x, r.y, r.width, r.height); 9741 r.x, r.y, r.width, r.height);
9712 } 9742 }
@@ -9720,7 +9750,12 @@ x_draw_image_foreground (struct glyph_string *s)
9720 image_rect.width = s->slice.width; 9750 image_rect.width = s->slice.width;
9721 image_rect.height = s->slice.height; 9751 image_rect.height = s->slice.height;
9722 if (gui_intersect_rectangles (&clip_rect, &image_rect, &r)) 9752 if (gui_intersect_rectangles (&clip_rect, &image_rect, &r))
9723 x_composite_image (s, FRAME_X_DRAWABLE (s->f), s->slice.x + r.x - x, s->slice.y + r.y - y, 9753 x_composite_image (s, FRAME_X_DRAWABLE (s->f),
9754#ifdef HAVE_XRENDER
9755 FRAME_X_PICTURE (s->f),
9756#endif
9757 s->slice.x + r.x - x,
9758 s->slice.y + r.y - y,
9724 r.x, r.y, r.width, r.height); 9759 r.x, r.y, r.width, r.height);
9725 9760
9726 /* When the image has a mask, we can expect that at 9761 /* When the image has a mask, we can expect that at
@@ -9886,8 +9921,11 @@ x_draw_image_foreground_1 (struct glyph_string *s, Pixmap pixmap)
9886 XChangeGC (display, s->gc, mask, &xgcv); 9921 XChangeGC (display, s->gc, mask, &xgcv);
9887 9922
9888 x_composite_image (s, pixmap, 9923 x_composite_image (s, pixmap,
9889 s->slice.x, s->slice.y, 9924#ifdef HAVE_XRENDER
9890 x, y, s->slice.width, s->slice.height); 9925 None,
9926#endif
9927 s->slice.x, s->slice.y, x, y,
9928 s->slice.width, s->slice.height);
9891 XSetClipMask (display, s->gc, None); 9929 XSetClipMask (display, s->gc, None);
9892 } 9930 }
9893 else 9931 else
@@ -12761,7 +12799,7 @@ xi_focus_handle_for_device (struct x_display_info *dpyinfo,
12761 /* The last-focus-change time of the device changed, so update the 12799 /* The last-focus-change time of the device changed, so update the
12762 frame's user time. */ 12800 frame's user time. */
12763 x_display_set_last_user_time (dpyinfo, event->time, 12801 x_display_set_last_user_time (dpyinfo, event->time,
12764 event->send_event); 12802 event->send_event, true);
12765 12803
12766 device->focus_frame = mentioned_frame; 12804 device->focus_frame = mentioned_frame;
12767 device->focus_frame_time = event->time; 12805 device->focus_frame_time = event->time;
@@ -12771,7 +12809,7 @@ xi_focus_handle_for_device (struct x_display_info *dpyinfo,
12771 /* The last-focus-change time of the device changed, so update the 12809 /* The last-focus-change time of the device changed, so update the
12772 frame's user time. */ 12810 frame's user time. */
12773 x_display_set_last_user_time (dpyinfo, event->time, 12811 x_display_set_last_user_time (dpyinfo, event->time,
12774 event->send_event); 12812 event->send_event, false);
12775 12813
12776 device->focus_frame = NULL; 12814 device->focus_frame = NULL;
12777 12815
@@ -14153,7 +14191,8 @@ XTmouse_position (struct frame **fp, int insist, Lisp_Object *bar_window,
14153 < dpyinfo->last_mouse_movement_time)) 14191 < dpyinfo->last_mouse_movement_time))
14154 x_display_set_last_user_time (dpyinfo, 14192 x_display_set_last_user_time (dpyinfo,
14155 dpyinfo->last_mouse_movement_time, 14193 dpyinfo->last_mouse_movement_time,
14156 dpyinfo->last_mouse_movement_time_send_event); 14194 dpyinfo->last_mouse_movement_time_send_event,
14195 true);
14157 14196
14158 if ((!f1 || FRAME_TOOLTIP_P (f1)) 14197 if ((!f1 || FRAME_TOOLTIP_P (f1))
14159 && (EQ (track_mouse, Qdropping) 14198 && (EQ (track_mouse, Qdropping)
@@ -14769,7 +14808,8 @@ xg_scroll_callback (GtkRange *range, GtkScrollType scroll,
14769 dpyinfo = FRAME_DISPLAY_INFO (f); 14808 dpyinfo = FRAME_DISPLAY_INFO (f);
14770 14809
14771 if (time != GDK_CURRENT_TIME) 14810 if (time != GDK_CURRENT_TIME)
14772 x_display_set_last_user_time (dpyinfo, time, true); 14811 x_display_set_last_user_time (dpyinfo, time, true,
14812 true);
14773 14813
14774 switch (scroll) 14814 switch (scroll)
14775 { 14815 {
@@ -18091,7 +18131,7 @@ handle_one_xevent (struct x_display_info *dpyinfo,
18091 required for SetInputFocus to work correctly after 18131 required for SetInputFocus to work correctly after
18092 taking the input focus. */ 18132 taking the input focus. */
18093 x_display_set_last_user_time (dpyinfo, event->xclient.data.l[1], 18133 x_display_set_last_user_time (dpyinfo, event->xclient.data.l[1],
18094 true); 18134 true, true);
18095 goto done; 18135 goto done;
18096 } 18136 }
18097 18137
@@ -19079,7 +19119,8 @@ handle_one_xevent (struct x_display_info *dpyinfo,
19079 19119
19080 case KeyPress: 19120 case KeyPress:
19081 x_display_set_last_user_time (dpyinfo, event->xkey.time, 19121 x_display_set_last_user_time (dpyinfo, event->xkey.time,
19082 event->xkey.send_event); 19122 event->xkey.send_event,
19123 true);
19083 ignore_next_mouse_click_timeout = 0; 19124 ignore_next_mouse_click_timeout = 0;
19084 19125
19085 coding = Qlatin_1; 19126 coding = Qlatin_1;
@@ -19558,7 +19599,7 @@ handle_one_xevent (struct x_display_info *dpyinfo,
19558 19599
19559 case EnterNotify: 19600 case EnterNotify:
19560 x_display_set_last_user_time (dpyinfo, event->xcrossing.time, 19601 x_display_set_last_user_time (dpyinfo, event->xcrossing.time,
19561 event->xcrossing.send_event); 19602 event->xcrossing.send_event, false);
19562 19603
19563#ifdef HAVE_XINPUT2 19604#ifdef HAVE_XINPUT2
19564 /* For whatever reason, the X server continues to deliver 19605 /* For whatever reason, the X server continues to deliver
@@ -19681,7 +19722,7 @@ handle_one_xevent (struct x_display_info *dpyinfo,
19681 19722
19682 case LeaveNotify: 19723 case LeaveNotify:
19683 x_display_set_last_user_time (dpyinfo, event->xcrossing.time, 19724 x_display_set_last_user_time (dpyinfo, event->xcrossing.time,
19684 event->xcrossing.send_event); 19725 event->xcrossing.send_event, false);
19685 19726
19686#ifdef HAVE_XINPUT2 19727#ifdef HAVE_XINPUT2
19687 /* For whatever reason, the X server continues to deliver 19728 /* For whatever reason, the X server continues to deliver
@@ -20496,7 +20537,7 @@ handle_one_xevent (struct x_display_info *dpyinfo,
20496 { 20537 {
20497 if (event->xbutton.type == ButtonPress) 20538 if (event->xbutton.type == ButtonPress)
20498 x_display_set_last_user_time (dpyinfo, event->xbutton.time, 20539 x_display_set_last_user_time (dpyinfo, event->xbutton.time,
20499 event->xbutton.send_event); 20540 event->xbutton.send_event, true);
20500 20541
20501#ifdef HAVE_XWIDGETS 20542#ifdef HAVE_XWIDGETS
20502 struct xwidget_view *xvw = xwidget_view_from_window (event->xbutton.window); 20543 struct xwidget_view *xvw = xwidget_view_from_window (event->xbutton.window);
@@ -20548,7 +20589,7 @@ handle_one_xevent (struct x_display_info *dpyinfo,
20548 if (event->type == ButtonPress) 20589 if (event->type == ButtonPress)
20549 { 20590 {
20550 x_display_set_last_user_time (dpyinfo, event->xbutton.time, 20591 x_display_set_last_user_time (dpyinfo, event->xbutton.time,
20551 event->xbutton.send_event); 20592 event->xbutton.send_event, true);
20552 20593
20553 dpyinfo->grabbed |= (1 << event->xbutton.button); 20594 dpyinfo->grabbed |= (1 << event->xbutton.button);
20554 dpyinfo->last_mouse_frame = f; 20595 dpyinfo->last_mouse_frame = f;
@@ -21105,7 +21146,7 @@ handle_one_xevent (struct x_display_info *dpyinfo,
21105 ev.send_event = enter->send_event; 21146 ev.send_event = enter->send_event;
21106 21147
21107 x_display_set_last_user_time (dpyinfo, enter->time, 21148 x_display_set_last_user_time (dpyinfo, enter->time,
21108 enter->send_event); 21149 enter->send_event, false);
21109 21150
21110#ifdef USE_MOTIF 21151#ifdef USE_MOTIF
21111 use_copy = true; 21152 use_copy = true;
@@ -21291,7 +21332,7 @@ handle_one_xevent (struct x_display_info *dpyinfo,
21291#endif 21332#endif
21292 21333
21293 x_display_set_last_user_time (dpyinfo, leave->time, 21334 x_display_set_last_user_time (dpyinfo, leave->time,
21294 leave->send_event); 21335 leave->send_event, false);
21295 21336
21296#ifdef HAVE_XWIDGETS 21337#ifdef HAVE_XWIDGETS
21297 { 21338 {
@@ -21566,7 +21607,7 @@ handle_one_xevent (struct x_display_info *dpyinfo,
21566 21607
21567 state = xi_convert_event_state (xev); 21608 state = xi_convert_event_state (xev);
21568 x_display_set_last_user_time (dpyinfo, xev->time, 21609 x_display_set_last_user_time (dpyinfo, xev->time,
21569 xev->send_event); 21610 xev->send_event, true);
21570 21611
21571 if (found_valuator) 21612 if (found_valuator)
21572 xwidget_scroll (xv, xev->event_x, xev->event_y, 21613 xwidget_scroll (xv, xev->event_x, xev->event_y,
@@ -21586,7 +21627,7 @@ handle_one_xevent (struct x_display_info *dpyinfo,
21586 if (found_valuator) 21627 if (found_valuator)
21587 { 21628 {
21588 x_display_set_last_user_time (dpyinfo, xev->time, 21629 x_display_set_last_user_time (dpyinfo, xev->time,
21589 xev->send_event); 21630 xev->send_event, true);
21590 21631
21591 21632
21592#if defined USE_GTK && !defined HAVE_GTK3 21633#if defined USE_GTK && !defined HAVE_GTK3
@@ -22077,7 +22118,7 @@ handle_one_xevent (struct x_display_info *dpyinfo,
22077 if (xev->evtype == XI_ButtonPress) 22118 if (xev->evtype == XI_ButtonPress)
22078 { 22119 {
22079 x_display_set_last_user_time (dpyinfo, xev->time, 22120 x_display_set_last_user_time (dpyinfo, xev->time,
22080 xev->send_event); 22121 xev->send_event, true);
22081 22122
22082 dpyinfo->grabbed |= (1 << xev->detail); 22123 dpyinfo->grabbed |= (1 << xev->detail);
22083 dpyinfo->last_mouse_frame = f; 22124 dpyinfo->last_mouse_frame = f;
@@ -22120,7 +22161,7 @@ handle_one_xevent (struct x_display_info *dpyinfo,
22120 22161
22121 if (xev->flags & XIPointerEmulated) 22162 if (xev->flags & XIPointerEmulated)
22122 x_display_set_last_user_time (dpyinfo, xev->time, 22163 x_display_set_last_user_time (dpyinfo, xev->time,
22123 xev->send_event); 22164 xev->send_event, true);
22124#endif 22165#endif
22125 x_dnd_note_self_wheel (dpyinfo, 22166 x_dnd_note_self_wheel (dpyinfo,
22126 x_dnd_last_seen_window, 22167 x_dnd_last_seen_window,
@@ -22356,7 +22397,7 @@ handle_one_xevent (struct x_display_info *dpyinfo,
22356 22397
22357 if (xev->evtype == XI_ButtonPress) 22398 if (xev->evtype == XI_ButtonPress)
22358 x_display_set_last_user_time (dpyinfo, xev->time, 22399 x_display_set_last_user_time (dpyinfo, xev->time,
22359 xev->send_event); 22400 xev->send_event, true);
22360 22401
22361 source = xi_device_from_id (dpyinfo, xev->sourceid); 22402 source = xi_device_from_id (dpyinfo, xev->sourceid);
22362 device = xi_device_from_id (dpyinfo, xev->deviceid); 22403 device = xi_device_from_id (dpyinfo, xev->deviceid);
@@ -22735,7 +22776,7 @@ handle_one_xevent (struct x_display_info *dpyinfo,
22735#endif 22776#endif
22736 22777
22737 x_display_set_last_user_time (dpyinfo, xev->time, 22778 x_display_set_last_user_time (dpyinfo, xev->time,
22738 xev->send_event); 22779 xev->send_event, true);
22739 ignore_next_mouse_click_timeout = 0; 22780 ignore_next_mouse_click_timeout = 0;
22740 22781
22741 f = x_any_window_to_frame (dpyinfo, xev->event); 22782 f = x_any_window_to_frame (dpyinfo, xev->event);
@@ -23374,7 +23415,7 @@ handle_one_xevent (struct x_display_info *dpyinfo,
23374 device = xi_device_from_id (dpyinfo, xev->deviceid); 23415 device = xi_device_from_id (dpyinfo, xev->deviceid);
23375 source = xi_device_from_id (dpyinfo, xev->sourceid); 23416 source = xi_device_from_id (dpyinfo, xev->sourceid);
23376 x_display_set_last_user_time (dpyinfo, xev->time, 23417 x_display_set_last_user_time (dpyinfo, xev->time,
23377 xev->send_event); 23418 xev->send_event, true);
23378 23419
23379 if (!device) 23420 if (!device)
23380 goto XI_OTHER; 23421 goto XI_OTHER;
@@ -23472,7 +23513,7 @@ handle_one_xevent (struct x_display_info *dpyinfo,
23472 device = xi_device_from_id (dpyinfo, xev->deviceid); 23513 device = xi_device_from_id (dpyinfo, xev->deviceid);
23473 source = xi_device_from_id (dpyinfo, xev->sourceid); 23514 source = xi_device_from_id (dpyinfo, xev->sourceid);
23474 x_display_set_last_user_time (dpyinfo, xev->time, 23515 x_display_set_last_user_time (dpyinfo, xev->time,
23475 xev->send_event); 23516 xev->send_event, true);
23476 23517
23477 if (!device) 23518 if (!device)
23478 goto XI_OTHER; 23519 goto XI_OTHER;
@@ -23519,7 +23560,7 @@ handle_one_xevent (struct x_display_info *dpyinfo,
23519 device = xi_device_from_id (dpyinfo, xev->deviceid); 23560 device = xi_device_from_id (dpyinfo, xev->deviceid);
23520 source = xi_device_from_id (dpyinfo, xev->sourceid); 23561 source = xi_device_from_id (dpyinfo, xev->sourceid);
23521 x_display_set_last_user_time (dpyinfo, xev->time, 23562 x_display_set_last_user_time (dpyinfo, xev->time,
23522 xev->send_event); 23563 xev->send_event, true);
23523 23564
23524 if (!device) 23565 if (!device)
23525 goto XI_OTHER; 23566 goto XI_OTHER;
@@ -23560,7 +23601,7 @@ handle_one_xevent (struct x_display_info *dpyinfo,
23560 device = xi_device_from_id (dpyinfo, pev->deviceid); 23601 device = xi_device_from_id (dpyinfo, pev->deviceid);
23561 source = xi_device_from_id (dpyinfo, pev->sourceid); 23602 source = xi_device_from_id (dpyinfo, pev->sourceid);
23562 x_display_set_last_user_time (dpyinfo, pev->time, 23603 x_display_set_last_user_time (dpyinfo, pev->time,
23563 pev->send_event); 23604 pev->send_event, true);
23564 23605
23565 if (!device) 23606 if (!device)
23566 goto XI_OTHER; 23607 goto XI_OTHER;
@@ -27995,6 +28036,7 @@ x_wm_set_size_hint (struct frame *f, long flags, bool user_position)
27995 Window window = FRAME_OUTER_WINDOW (f); 28036 Window window = FRAME_OUTER_WINDOW (f);
27996#ifdef USE_X_TOOLKIT 28037#ifdef USE_X_TOOLKIT
27997 WMShellWidget shell; 28038 WMShellWidget shell;
28039 bool hints_changed;
27998#endif 28040#endif
27999 28041
28000 if (!window) 28042 if (!window)
@@ -28021,8 +28063,9 @@ x_wm_set_size_hint (struct frame *f, long flags, bool user_position)
28021 shell->wm.size_hints.flags |= USPosition; 28063 shell->wm.size_hints.flags |= USPosition;
28022 } 28064 }
28023 28065
28024 widget_update_wm_size_hints (f->output_data.x->widget, 28066 hints_changed
28025 f->output_data.x->edit_widget); 28067 = widget_update_wm_size_hints (f->output_data.x->widget,
28068 f->output_data.x->edit_widget);
28026 28069
28027#ifdef USE_MOTIF 28070#ifdef USE_MOTIF
28028 /* Do this all over again for the benefit of Motif, which always 28071 /* Do this all over again for the benefit of Motif, which always
@@ -28035,6 +28078,7 @@ x_wm_set_size_hint (struct frame *f, long flags, bool user_position)
28035 shell->wm.size_hints.flags &= ~PPosition; 28078 shell->wm.size_hints.flags &= ~PPosition;
28036 shell->wm.size_hints.flags |= USPosition; 28079 shell->wm.size_hints.flags |= USPosition;
28037 } 28080 }
28081#endif
28038 28082
28039 /* Drill hints into Motif, since it keeps setting its own. */ 28083 /* Drill hints into Motif, since it keeps setting its own. */
28040 size_hints.flags = shell->wm.size_hints.flags; 28084 size_hints.flags = shell->wm.size_hints.flags;
@@ -28052,15 +28096,23 @@ x_wm_set_size_hint (struct frame *f, long flags, bool user_position)
28052 size_hints.min_aspect.y = shell->wm.size_hints.min_aspect.y; 28096 size_hints.min_aspect.y = shell->wm.size_hints.min_aspect.y;
28053 size_hints.max_aspect.x = shell->wm.size_hints.max_aspect.x; 28097 size_hints.max_aspect.x = shell->wm.size_hints.max_aspect.x;
28054 size_hints.max_aspect.y = shell->wm.size_hints.max_aspect.y; 28098 size_hints.max_aspect.y = shell->wm.size_hints.max_aspect.y;
28055#ifdef HAVE_X11XTR6
28056 size_hints.base_width = shell->wm.base_width; 28099 size_hints.base_width = shell->wm.base_width;
28057 size_hints.base_height = shell->wm.base_height; 28100 size_hints.base_height = shell->wm.base_height;
28058 size_hints.win_gravity = shell->wm.win_gravity; 28101 size_hints.win_gravity = shell->wm.win_gravity;
28059#endif
28060 28102
28103#ifdef USE_MOTIF
28061 XSetWMNormalHints (XtDisplay (f->output_data.x->widget), 28104 XSetWMNormalHints (XtDisplay (f->output_data.x->widget),
28062 XtWindow (f->output_data.x->widget), 28105 XtWindow (f->output_data.x->widget),
28063 &size_hints); 28106 &size_hints);
28107#else
28108 /* In many cases, widget_update_wm_size_hints will not have
28109 updated the size hints if only flags changed. When that
28110 happens, set the WM hints manually. */
28111
28112 if (!hints_changed)
28113 XSetWMNormalHints (XtDisplay (f->output_data.x->widget),
28114 XtWindow (f->output_data.x->widget),
28115 &size_hints);
28064#endif 28116#endif
28065 28117
28066 return; 28118 return;
@@ -28475,9 +28527,10 @@ xi_check_toolkit (Display *display)
28475 28527
28476#endif 28528#endif
28477 28529
28478/* Open a connection to X display DISPLAY_NAME, and return 28530/* Open a connection to X display DISPLAY_NAME, and return the
28479 the structure that describes the open display. 28531 structure that describes the open display. If obtaining the XCB
28480 If we cannot contact the display, return null. */ 28532 connection or toolkit-specific display fails, return NULL. Signal
28533 an error if opening the display itself failed. */
28481 28534
28482struct x_display_info * 28535struct x_display_info *
28483x_term_init (Lisp_Object display_name, char *xrm_option, char *resource_name) 28536x_term_init (Lisp_Object display_name, char *xrm_option, char *resource_name)
@@ -28504,9 +28557,13 @@ x_term_init (Lisp_Object display_name, char *xrm_option, char *resource_name)
28504 ++x_initialized; 28557 ++x_initialized;
28505 } 28558 }
28506 28559
28507 if (! x_display_ok (SSDATA (display_name))) 28560#if defined USE_X_TOOLKIT || defined USE_GTK
28561
28562 if (!x_display_ok (SSDATA (display_name)))
28508 error ("Display %s can't be opened", SSDATA (display_name)); 28563 error ("Display %s can't be opened", SSDATA (display_name));
28509 28564
28565#endif
28566
28510#ifdef USE_GTK 28567#ifdef USE_GTK
28511 { 28568 {
28512#define NUM_ARGV 10 28569#define NUM_ARGV 10
@@ -28633,6 +28690,15 @@ x_term_init (Lisp_Object display_name, char *xrm_option, char *resource_name)
28633 /* Detect failure. */ 28690 /* Detect failure. */
28634 if (dpy == 0) 28691 if (dpy == 0)
28635 { 28692 {
28693#if !defined USE_X_TOOLKIT && !defined USE_GTK
28694 /* Avoid opening a display three times (once in dispextern.c
28695 upon startup, once in x_display_ok, and once above) to
28696 determine whether or not the display is alive on no toolkit
28697 builds, where no toolkit initialization happens at all. */
28698
28699 error ("Display %s can't be opened", SSDATA (display_name));
28700#endif
28701
28636 unblock_input (); 28702 unblock_input ();
28637 return 0; 28703 return 0;
28638 } 28704 }