aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorMiles Bader2006-06-17 20:57:37 +0000
committerMiles Bader2006-06-17 20:57:37 +0000
commit10c1758c0b2d29b3e1fb8e3ffe5c5dc262f25217 (patch)
tree78d2db4ab91026e7d5373086d022a2bce083200b /src
parent2090e2a3897bd0e36fd0e8ba13d861668a0a887f (diff)
parentf362b76002bfd0f43af76a7772a808c042302f07 (diff)
downloademacs-10c1758c0b2d29b3e1fb8e3ffe5c5dc262f25217.tar.gz
emacs-10c1758c0b2d29b3e1fb8e3ffe5c5dc262f25217.zip
Merge from emacs--devo--0
Patches applied: * emacs--devo--0 (patch 300-313) - Update from CVS - Update from CVS: lispref/display.texi (Forcing Redisplay): Fix typo. - Merge from gnus--rel--5.10 * gnus--rel--5.10 (patch 105-106) - Update from CVS Revision: emacs@sv.gnu.org/emacs--unicode--0--patch-74
Diffstat (limited to 'src')
-rw-r--r--src/.gdbinit129
-rw-r--r--src/ChangeLog123
-rw-r--r--src/callproc.c4
-rw-r--r--src/dispextern.h21
-rw-r--r--src/dispnew.c133
-rw-r--r--src/eval.c4
-rw-r--r--src/lread.c49
-rw-r--r--src/macfns.c26
-rw-r--r--src/macterm.c141
-rw-r--r--src/window.c24
-rw-r--r--src/xdisp.c208
-rw-r--r--src/xterm.c139
-rw-r--r--src/xterm.h12
13 files changed, 839 insertions, 174 deletions
diff --git a/src/.gdbinit b/src/.gdbinit
index 7de361fddfb..dd848fed3d5 100644
--- a/src/.gdbinit
+++ b/src/.gdbinit
@@ -190,12 +190,8 @@ define pitx
190 printf " ch=[%d,%d]", $it->c, $it->len 190 printf " ch=[%d,%d]", $it->c, $it->len
191 end 191 end
192 else 192 else
193 if ($it->what == IT_IMAGE) 193 printf " "
194 printf " IMAGE=%d", $it->image_id 194 output $it->what
195 else
196 printf " "
197 output $it->what
198 end
199 end 195 end
200 if ($it->method != GET_FROM_BUFFER) 196 if ($it->method != GET_FROM_BUFFER)
201 printf " next=" 197 printf " next="
@@ -203,6 +199,12 @@ define pitx
203 if ($it->method == GET_FROM_STRING) 199 if ($it->method == GET_FROM_STRING)
204 printf "[%d]", $it->current.string_pos.charpos 200 printf "[%d]", $it->current.string_pos.charpos
205 end 201 end
202 if ($it->method == GET_FROM_IMAGE)
203 printf "[%d]", $it->image_id
204 end
205 if ($it->method == GET_FROM_COMPOSITION)
206 printf "[%d,%d,%d]", $it->cmp_id, $it->len, $it->cmp_len
207 end
206 end 208 end
207 printf "\n" 209 printf "\n"
208 if ($it->region_beg_charpos >= 0) 210 if ($it->region_beg_charpos >= 0)
@@ -372,6 +374,121 @@ document pwin
372Pretty print window structure w. 374Pretty print window structure w.
373end 375end
374 376
377define pgx
378 set $g = $arg0
379 if ($g->type == CHAR_GLYPH)
380 if ($g->u.ch >= ' ' && $g->u.ch < 127)
381 printf "CHAR[%c]", $g->u.ch
382 else
383 printf "CHAR[0x%x]", $g->u.ch
384 end
385 end
386 if ($g->type == COMPOSITE_GLYPH)
387 printf "COMP[%d]", $g->u.cmp_id
388 end
389 if ($g->type == IMAGE_GLYPH)
390 printf "IMAGE[%d]", $g->u.img_id
391 end
392 if ($g->type == STRETCH_GLYPH)
393 printf "STRETCH[%d+%d]", $g->u.stretch.height, $g->u.stretch.ascent
394 end
395 xgettype ($g->object)
396 if ($type == Lisp_String)
397 printf " str=%x[%d]", $g->object, $g->charpos
398 else
399 printf " pos=%d", $g->charpos
400 end
401 printf " w=%d a+d=%d+%d", $g->pixel_width, $g->ascent, $g->descent
402 if ($g->face_id != DEFAULT_FACE_ID)
403 printf " face=%d", $g->face_id
404 end
405 if ($g->voffset)
406 printf " vof=%d", $g->voffset
407 end
408 if ($g->multibyte_p)
409 printf " MB"
410 end
411 if ($g->padding_p)
412 printf " PAD"
413 end
414 if ($g->glyph_not_available_p)
415 printf " N/A"
416 end
417 if ($g->overlaps_vertically_p)
418 printf " OVL"
419 end
420 if ($g->left_box_line_p)
421 printf " ["
422 end
423 if ($g->right_box_line_p)
424 printf " ]"
425 end
426 if ($g->slice.x || $g->slice.y || $g->slice.width || $g->slice.height)
427 printf " slice=%d,%d,%d,%d" ,$g->slice.x, $g->slice.y, $g->slice.width, $g->slice.height
428 end
429 printf "\n"
430end
431document pgx
432Pretty print a glyph structure.
433Takes one argument, a pointer to a glyph structure
434end
435
436define pg
437 set $pgidx = 0
438 pgx glyph
439end
440document pg
441Pretty print glyph structure glyph.
442end
443
444define pgi
445 set $pgidx = $arg0
446 pgx (&glyph[$pgidx])
447end
448document pgi
449Pretty print glyph structure glyph[I].
450Takes one argument, a integer I.
451end
452
453define pgn
454 set $pgidx = $pgidx + 1
455 pgx (&glyph[$pgidx])
456end
457document pgn
458Pretty print next glyph structure.
459end
460
461define pgrowx
462 set $row = $arg0
463 set $area = 0
464 set $xofs = $row->x
465 while ($area < 3)
466 set $used = $row->used[$area]
467 if ($used > 0)
468 set $gl0 = $row->glyphs[$area]
469 set $pgidx = 0
470 printf "%s: %d glyphs\n", ($area == 0 ? "LEFT" : $area == 2 ? "RIGHT" : "TEXT"), $used
471 while ($pgidx < $used)
472 printf "%3d %4d: ", $pgidx, $xofs
473 pgx $gl0[$pgidx]
474 set $xofs = $xofs + $gl0[$pgidx]->pixel_width
475 set $pgidx = $pgidx + 1
476 end
477 end
478 set $area = $area + 1
479 end
480end
481document pgrowx
482Pretty print all glyphs in a row structure.
483Takes one argument, a pointer to a row structure.
484end
485
486define pgrow
487 pgrowx row
488end
489document pgrow
490Pretty print all glyphs in row structure row.
491end
375 492
376define xtype 493define xtype
377 xgettype $ 494 xgettype $
diff --git a/src/ChangeLog b/src/ChangeLog
index d0ad63de10d..c4c798e6f77 100644
--- a/src/ChangeLog
+++ b/src/ChangeLog
@@ -1,3 +1,126 @@
12006-06-17 Kim F. Storm <storm@cua.dk>
2
3 * dispnew.c (update_frame): Check for input pending on entry.
4 (update_window, update_frame_1): Break loop if input is detected.
5
62006-06-16 Francis Litterio <flitterio@gmail.com>
7
8 * xterm.c (x_check_expected_move, handle_one_xevent)
9 (x_set_offset, x_check_fullscreen): Extensive changes to make
10 frame positioning deterministic under X.
11
12 * xterm.h (x_output): Added members left_before_move and
13 top_before_move. Removed members expected_left and expected_top.
14
152006-06-16 Kim F. Storm <storm@cua.dk>
16
17 * dispextern.h (struct it): Add union to iterator stack to save
18 image, composition, and stretch specific paramters.
19
20 * xdisp.c (next_overlay_string): Fix assert.
21 (push_it, pop_it): Handle composition and stretch specific values.
22 Only handle it->slice in image (for now).
23 (back_to_previous_visible_line_start): Continue search if newline is
24 part of a compisition. Simplify.
25 (reseat_1): Set it->object to buffer.
26 (set_iterator_to_next): Set it->object to string or buffer, when
27 setting it->method to GET_FROM_STRING or GET_FROM_BUFFER.
28 (next_element_from_composition): Set it->object to buffer if not
29 from string.
30 (set_cursor_from_row): Only save start of string if not already
31 done to handle multiple strings in a row.
32
33 * .gdbinit (pitx): Show composition parameters.
34 (pgx, pg): New commands to print a glyph structure.
35 (pgi, pgn): New commands to print specific/next glyph.
36 (pgrowx, pgrow): New commands to print all glyphs in a row.
37
382006-06-16 YAMAMOTO Mitsuharu <mituharu@math.s.chiba-u.ac.jp>
39
40 * macfns.c (Fx_display_mm_height, Fx_display_mm_width)
41 [MAC_OS_X_VERSION_MAX_ALLOWED >= 1030]: Use CGDisplayScreenSize.
42
43 * macterm.c (do_app_resume, do_app_suspend): Remove functions.
44 (mac_tsm_resume, mac_tsm_suspend) [USE_MAC_TSM]: New functions.
45 (mac_handle_window_event, XTread_socket) [USE_MAC_TSM]: Use them.
46 (Vmac_ts_script_language_on_focus) [USE_MAC_TSM]: New variable.
47 (syms_of_macterm) [USE_MAC_TSM]: Defvar it.
48 (saved_ts_language, saved_ts_component) [USE_MAC_TSM]: New variables.
49 (mac_initialize_display_info) [MAC_OSX]: Use Quartz Display
50 Services functions to get size of main display in pixels.
51
522006-06-14 Chong Yidong <cyd@stupidchicken.com>
53
54 * xdisp.c (back_to_previous_visible_line_start): Reset
55 it->continuation_lines_width.
56
572006-06-14 Richard Stallman <rms@gnu.org>
58
59 * eval.c (Fdefconst): Mark variable as risky.
60
61 * callproc.c (Fcall_process): Doc fix.
62
63 * window.c (adjust_window_trailing_edge): Don't break out of the loop
64 because there's no next window, if there are parallel windows.
65 Do break out when WINDOW is nil.
66
672006-06-14 Kim F. Storm <storm@cua.dk>
68
69 * dispextern.h (IT_STACK_SIZE): New macro specifying size of
70 iterator stack (instead of hardcoded number). Increase from 2 to
71 4 to make room for propertized overlay strings before and after a
72 display string, image or composition.
73 (struct it): Add image_id and method members to iterator stack.
74
75 * xdisp.c (init_from_display_pos): Don't set it->method and
76 overlay_string_index after pop_it. Add asserts.
77 (handle_stop): Look for overlay strings around a display string,
78 image, or composition. Handle properties on those strings.
79 (next_overlay_string): Don't set string, pos or method after pop_it.
80 (get_overlay_strings_1): Split from get_overlay_strings; don't
81 modify it if no overlay strings are found.
82 (get_overlay_strings): Use get_overlay_strings_1. Always set
83 it->string and it->method.
84 (push_it): Push it->image_id and it->method. Push it->object
85 instead of it->string if method is GET_FROM_IMAGE.
86 (pop_it): Pop it->image_id and it->method. Ppo it->object
87 instead of it->string if method is GET_FROM_IMAGE.
88 Reset it->current.string_pos if popped it->string is nil.
89 (reseat_1): Remove comment dated 19 May 2003. It expressed doubt
90 whether a given change was correct; but the change is correct.
91 Clear it->string_from_display_prop_p.
92 (set_iterator_to_next): Rely on it->method and it->image_id from
93 iterator stack, instead of setting them explicitly after pop_it.
94
95 * dispnew.c (sit_for): Undo 2006-06-01 change. Instead, a
96 negative time forces redisplay even when input is available.
97 (Fsit_for): Doc fix.
98
992006-06-13 Kim F. Storm <storm@cua.dk>
100
101 * dispnew.c: Modify preemptive redisplay to be based on periodic
102 checks for input.
103 (PERIODIC_PREEMPTION_CHECKING): Define to 1 iff EMACS_HAS_USECS.
104 (Vredisplay_preemption_period): New variable.
105 (syms_of_display): DEFVAR_LISP and initialize it.
106 (preemption_period, preemption_next_check): New variables.
107 (update_frame, update_single_window): Initialize them based on
108 Vredisplay_preemption_period if !force_p.
109 (update_window, update_frame_1): Use them to determine when to
110 check for input.
111
1122006-06-03 Aidan Kehoe <kehoea@parhasard.net>
113
114 * lread.c (read_escape): Provide a Unicode character escape
115 syntax; \u followed by exactly four or \U followed by exactly
116 eight hex digits in a comment or string is read as a Unicode
117 character with that code point.
118
1192006-06-09 Eli Zaretskii <eliz@gnu.org>
120
121 * window.c (window_scroll_pixel_based): Signal "Beginning of
122 buffer" when scroll-down at the beginning of an empty buffer.
123
12006-06-06 YAMAMOTO Mitsuharu <mituharu@math.s.chiba-u.ac.jp> 1242006-06-06 YAMAMOTO Mitsuharu <mituharu@math.s.chiba-u.ac.jp>
2 125
3 * macterm.c [USE_MAC_TSM] (mac_handle_text_input_event): Exclude 126 * macterm.c [USE_MAC_TSM] (mac_handle_text_input_event): Exclude
diff --git a/src/callproc.c b/src/callproc.c
index 4fcf2ec0eda..d8eebac08a6 100644
--- a/src/callproc.c
+++ b/src/callproc.c
@@ -203,6 +203,10 @@ t (mix it with ordinary output), or a file name string.
203Fourth arg DISPLAY non-nil means redisplay buffer as output is inserted. 203Fourth arg DISPLAY non-nil means redisplay buffer as output is inserted.
204Remaining arguments are strings passed as command arguments to PROGRAM. 204Remaining arguments are strings passed as command arguments to PROGRAM.
205 205
206If executable PROGRAM can't be found as an executable, `call-process'
207signals a Lisp error. `call-process' reports errors in execution of
208the program only through its return and output.
209
206If BUFFER is 0, `call-process' returns immediately with value nil. 210If BUFFER is 0, `call-process' returns immediately with value nil.
207Otherwise it waits for PROGRAM to terminate 211Otherwise it waits for PROGRAM to terminate
208and returns a numeric exit status or a signal description string. 212and returns a numeric exit status or a signal description string.
diff --git a/src/dispextern.h b/src/dispextern.h
index 92005e6b149..8c9c427f68d 100644
--- a/src/dispextern.h
+++ b/src/dispextern.h
@@ -1827,6 +1827,8 @@ enum it_method {
1827 NUM_IT_METHODS 1827 NUM_IT_METHODS
1828}; 1828};
1829 1829
1830#define IT_STACK_SIZE 4
1831
1830struct it 1832struct it
1831{ 1833{
1832 /* The window in which we iterate over current_buffer (or a string). */ 1834 /* The window in which we iterate over current_buffer (or a string). */
@@ -1938,19 +1940,34 @@ struct it
1938 int stop_charpos; 1940 int stop_charpos;
1939 int face_id; 1941 int face_id;
1940 Lisp_Object string; 1942 Lisp_Object string;
1943 union {
1944 struct {
1945 Lisp_Object object;
1946 struct it_slice slice;
1947 int image_id;
1948 } image;
1949 struct {
1950 Lisp_Object object;
1951 int c, len;
1952 int cmp_id, cmp_len;
1953 } comp;
1954 struct {
1955 Lisp_Object object;
1956 } stretch;
1957 } u;
1941 struct display_pos pos; 1958 struct display_pos pos;
1942 int end_charpos; 1959 int end_charpos;
1943 int string_nchars; 1960 int string_nchars;
1944 enum glyph_row_area area; 1961 enum glyph_row_area area;
1962 enum it_method method;
1945 unsigned multibyte_p : 1; 1963 unsigned multibyte_p : 1;
1946 unsigned string_from_display_prop_p : 1; 1964 unsigned string_from_display_prop_p : 1;
1947 unsigned display_ellipsis_p : 1; 1965 unsigned display_ellipsis_p : 1;
1948 struct it_slice slice;
1949 Lisp_Object space_width; 1966 Lisp_Object space_width;
1950 short voffset; 1967 short voffset;
1951 Lisp_Object font_height; 1968 Lisp_Object font_height;
1952 } 1969 }
1953 stack[2]; 1970 stack[IT_STACK_SIZE];
1954 1971
1955 /* Stack pointer. */ 1972 /* Stack pointer. */
1956 int sp; 1973 int sp;
diff --git a/src/dispnew.c b/src/dispnew.c
index f239d6969f4..b899cd2bd93 100644
--- a/src/dispnew.c
+++ b/src/dispnew.c
@@ -192,6 +192,28 @@ struct window *frame_row_to_window P_ ((struct window *, int));
192 192
193int redisplay_dont_pause; 193int redisplay_dont_pause;
194 194
195/* Define PERIODIC_PREEMPTION_CHECKING to 1, if micro-second timers
196 are supported, so we can check for input during redisplay at
197 regular intervals. */
198#ifdef EMACS_HAS_USECS
199#define PERIODIC_PREEMPTION_CHECKING 1
200#else
201#define PERIODIC_PREEMPTION_CHECKING 0
202#endif
203
204#if PERIODIC_PREEMPTION_CHECKING
205
206/* If a number (float), check for user input every N seconds. */
207
208Lisp_Object Vredisplay_preemption_period;
209
210/* Redisplay preemption timers. */
211
212static EMACS_TIME preemption_period;
213static EMACS_TIME preemption_next_check;
214
215#endif
216
195/* Nonzero upon entry to redisplay means do not assume anything about 217/* Nonzero upon entry to redisplay means do not assume anything about
196 current contents of actual terminal frame; clear and redraw it. */ 218 current contents of actual terminal frame; clear and redraw it. */
197 219
@@ -3806,6 +3828,28 @@ update_frame (f, force_p, inhibit_hairy_id_p)
3806 int paused_p; 3828 int paused_p;
3807 struct window *root_window = XWINDOW (f->root_window); 3829 struct window *root_window = XWINDOW (f->root_window);
3808 3830
3831#if PERIODIC_PREEMPTION_CHECKING
3832 if (!force_p && NUMBERP (Vredisplay_preemption_period))
3833 {
3834 EMACS_TIME tm;
3835 double p = XFLOATINT (Vredisplay_preemption_period);
3836 int sec, usec;
3837
3838 if (detect_input_pending_ignore_squeezables ())
3839 {
3840 paused_p = 1;
3841 goto do_pause;
3842 }
3843
3844 sec = (int) p;
3845 usec = (p - sec) * 1000000;
3846
3847 EMACS_GET_TIME (tm);
3848 EMACS_SET_SECS_USECS (preemption_period, sec, usec);
3849 EMACS_ADD_TIME (preemption_next_check, tm, preemption_period);
3850 }
3851#endif
3852
3809 if (FRAME_WINDOW_P (f)) 3853 if (FRAME_WINDOW_P (f))
3810 { 3854 {
3811 /* We are working on window matrix basis. All windows whose 3855 /* We are working on window matrix basis. All windows whose
@@ -3884,6 +3928,7 @@ update_frame (f, force_p, inhibit_hairy_id_p)
3884#endif 3928#endif
3885 } 3929 }
3886 3930
3931 do_pause:
3887 /* Reset flags indicating that a window should be updated. */ 3932 /* Reset flags indicating that a window should be updated. */
3888 set_window_update_flags (root_window, 0); 3933 set_window_update_flags (root_window, 0);
3889 3934
@@ -3938,6 +3983,22 @@ update_single_window (w, force_p)
3938 /* Record that this is not a frame-based redisplay. */ 3983 /* Record that this is not a frame-based redisplay. */
3939 set_frame_matrix_frame (NULL); 3984 set_frame_matrix_frame (NULL);
3940 3985
3986#if PERIODIC_PREEMPTION_CHECKING
3987 if (!force_p && NUMBERP (Vredisplay_preemption_period))
3988 {
3989 EMACS_TIME tm;
3990 double p = XFLOATINT (Vredisplay_preemption_period);
3991 int sec, usec;
3992
3993 sec = (int) p;
3994 usec = (p - sec) * 1000000;
3995
3996 EMACS_GET_TIME (tm);
3997 EMACS_SET_SECS_USECS (preemption_period, sec, usec);
3998 EMACS_ADD_TIME (preemption_next_check, tm, preemption_period);
3999 }
4000#endif
4001
3941 /* Update W. */ 4002 /* Update W. */
3942 update_begin (f); 4003 update_begin (f);
3943 update_window (w, force_p); 4004 update_window (w, force_p);
@@ -4093,7 +4154,9 @@ update_window (w, force_p)
4093{ 4154{
4094 struct glyph_matrix *desired_matrix = w->desired_matrix; 4155 struct glyph_matrix *desired_matrix = w->desired_matrix;
4095 int paused_p; 4156 int paused_p;
4157#if !PERIODIC_PREEMPTION_CHECKING
4096 int preempt_count = baud_rate / 2400 + 1; 4158 int preempt_count = baud_rate / 2400 + 1;
4159#endif
4097 extern int input_pending; 4160 extern int input_pending;
4098 extern Lisp_Object do_mouse_tracking; 4161 extern Lisp_Object do_mouse_tracking;
4099#if GLYPH_DEBUG 4162#if GLYPH_DEBUG
@@ -4105,8 +4168,13 @@ update_window (w, force_p)
4105 /* Check pending input the first time so that we can quickly return. */ 4168 /* Check pending input the first time so that we can quickly return. */
4106 if (redisplay_dont_pause) 4169 if (redisplay_dont_pause)
4107 force_p = 1; 4170 force_p = 1;
4108 else 4171#if PERIODIC_PREEMPTION_CHECKING
4172 else if (NILP (Vredisplay_preemption_period))
4173 force_p = 1;
4174#else
4175 else if (!force_p)
4109 detect_input_pending_ignore_squeezables (); 4176 detect_input_pending_ignore_squeezables ();
4177#endif
4110 4178
4111 /* If forced to complete the update, or if no input is pending, do 4179 /* If forced to complete the update, or if no input is pending, do
4112 the update. */ 4180 the update. */
@@ -4178,9 +4246,23 @@ update_window (w, force_p)
4178 detect_input_pending. If it's done too often, 4246 detect_input_pending. If it's done too often,
4179 scrolling large windows with repeated scroll-up 4247 scrolling large windows with repeated scroll-up
4180 commands will too quickly pause redisplay. */ 4248 commands will too quickly pause redisplay. */
4249#if PERIODIC_PREEMPTION_CHECKING
4250 if (!force_p)
4251 {
4252 EMACS_TIME tm, dif;
4253 EMACS_GET_TIME (tm);
4254 EMACS_SUB_TIME (dif, preemption_next_check, tm);
4255 if (EMACS_TIME_NEG_P (dif))
4256 {
4257 EMACS_ADD_TIME (preemption_next_check, tm, preemption_period);
4258 if (detect_input_pending_ignore_squeezables ())
4259 break;
4260 }
4261 }
4262#else
4181 if (!force_p && ++n_updated % preempt_count == 0) 4263 if (!force_p && ++n_updated % preempt_count == 0)
4182 detect_input_pending_ignore_squeezables (); 4264 detect_input_pending_ignore_squeezables ();
4183 4265#endif
4184 changed_p |= update_window_line (w, vpos, 4266 changed_p |= update_window_line (w, vpos,
4185 &mouse_face_overwritten_p); 4267 &mouse_face_overwritten_p);
4186 4268
@@ -5131,11 +5213,16 @@ update_frame_1 (f, force_p, inhibit_id_p)
5131 5213
5132 if (redisplay_dont_pause) 5214 if (redisplay_dont_pause)
5133 force_p = 1; 5215 force_p = 1;
5216#if PERIODIC_PREEMPTION_CHECKING
5217 else if (NILP (Vredisplay_preemption_period))
5218 force_p = 1;
5219#else
5134 else if (!force_p && detect_input_pending_ignore_squeezables ()) 5220 else if (!force_p && detect_input_pending_ignore_squeezables ())
5135 { 5221 {
5136 pause = 1; 5222 pause = 1;
5137 goto do_pause; 5223 goto do_pause;
5138 } 5224 }
5225#endif
5139 5226
5140 /* If we cannot insert/delete lines, it's no use trying it. */ 5227 /* If we cannot insert/delete lines, it's no use trying it. */
5141 if (!line_ins_del_ok) 5228 if (!line_ins_del_ok)
@@ -5186,8 +5273,23 @@ update_frame_1 (f, force_p, inhibit_id_p)
5186 } 5273 }
5187 } 5274 }
5188 5275
5189 if ((i - 1) % preempt_count == 0) 5276#if PERIODIC_PREEMPTION_CHECKING
5277 if (!force_p)
5278 {
5279 EMACS_TIME tm, dif;
5280 EMACS_GET_TIME (tm);
5281 EMACS_SUB_TIME (dif, preemption_next_check, tm);
5282 if (EMACS_TIME_NEG_P (dif))
5283 {
5284 EMACS_ADD_TIME (preemption_next_check, tm, preemption_period);
5285 if (detect_input_pending_ignore_squeezables ())
5286 break;
5287 }
5288 }
5289#else
5290 if (!force_p && (i - 1) % preempt_count == 0)
5190 detect_input_pending_ignore_squeezables (); 5291 detect_input_pending_ignore_squeezables ();
5292#endif
5191 5293
5192 update_frame_line (f, i); 5294 update_frame_line (f, i);
5193 } 5295 }
@@ -6388,15 +6490,22 @@ Lisp_Object
6388sit_for (sec, usec, reading, display, initial_display) 6490sit_for (sec, usec, reading, display, initial_display)
6389 int sec, usec, reading, display, initial_display; 6491 int sec, usec, reading, display, initial_display;
6390{ 6492{
6493 int preempt = (sec >= 0) || (sec == 0 && usec >= 0);
6494
6391 swallow_events (display); 6495 swallow_events (display);
6392 6496
6393 if ((detect_input_pending_run_timers (display) 6497 if ((detect_input_pending_run_timers (display) && preempt)
6394 && !redisplay_dont_pause)
6395 || !NILP (Vexecuting_kbd_macro)) 6498 || !NILP (Vexecuting_kbd_macro))
6396 return Qnil; 6499 return Qnil;
6397 6500
6398 if (initial_display) 6501 if (initial_display)
6399 redisplay_preserve_echo_area (2); 6502 {
6503 int count = SPECPDL_INDEX ();
6504 if (!preempt)
6505 specbind (Qredisplay_dont_pause, Qt);
6506 redisplay_preserve_echo_area (2);
6507 unbind_to (count, Qnil);
6508 }
6400 6509
6401 if (sec == 0 && usec == 0) 6510 if (sec == 0 && usec == 0)
6402 return Qt; 6511 return Qt;
@@ -6422,8 +6531,7 @@ Redisplay is preempted as always if input arrives, and does not happen
6422if input is available before it starts. 6531if input is available before it starts.
6423Value is t if waited the full time with no input arriving. 6532Value is t if waited the full time with no input arriving.
6424 6533
6425Redisplay will occur even when input is available if you bind 6534Redisplay will occur even when input is available if SECONDS is negative.
6426`redisplay-dont-pause' to a non-nil value.
6427 6535
6428An obsolete but still supported form is 6536An obsolete but still supported form is
6429\(sit-for SECONDS &optional MILLISECONDS NODISP) 6537\(sit-for SECONDS &optional MILLISECONDS NODISP)
@@ -6922,7 +7030,14 @@ See `buffer-display-table' for more information. */);
6922 doc: /* *Non-nil means update isn't paused when input is detected. */); 7030 doc: /* *Non-nil means update isn't paused when input is detected. */);
6923 redisplay_dont_pause = 0; 7031 redisplay_dont_pause = 0;
6924 7032
6925 /* Initialize `window-system', unless init_display already decided it. */ 7033#if PERIODIC_PREEMPTION_CHECKING
7034 DEFVAR_LISP ("redisplay-preemption-period", &Vredisplay_preemption_period,
7035 doc: /* *The period in seconds between checking for input during redisplay.
7036If input is detected, redisplay is pre-empted, and the input is processed.
7037If nil, never pre-empt redisplay. */);
7038 Vredisplay_preemption_period = make_float (0.10);
7039#endif
7040
6926#ifdef CANNOT_DUMP 7041#ifdef CANNOT_DUMP
6927 if (noninteractive) 7042 if (noninteractive)
6928#endif 7043#endif
diff --git a/src/eval.c b/src/eval.c
index 20f29b5f06b..5f8d266ec7b 100644
--- a/src/eval.c
+++ b/src/eval.c
@@ -195,9 +195,10 @@ int handling_signal;
195 195
196Lisp_Object Vmacro_declaration_function; 196Lisp_Object Vmacro_declaration_function;
197 197
198extern Lisp_Object Qrisky_local_variable;
198 199
199static Lisp_Object funcall_lambda P_ ((Lisp_Object, int, Lisp_Object*)); 200static Lisp_Object funcall_lambda P_ ((Lisp_Object, int, Lisp_Object*));
200 201
201void 202void
202init_eval_once () 203init_eval_once ()
203{ 204{
@@ -895,6 +896,7 @@ usage: (defconst SYMBOL INITVALUE [DOCSTRING]) */)
895 tem = Fpurecopy (tem); 896 tem = Fpurecopy (tem);
896 Fput (sym, Qvariable_documentation, tem); 897 Fput (sym, Qvariable_documentation, tem);
897 } 898 }
899 Fput (sym, Qrisky_local_variable, Qt);
898 LOADHIST_ATTACH (sym); 900 LOADHIST_ATTACH (sym);
899 return sym; 901 return sym;
900} 902}
diff --git a/src/lread.c b/src/lread.c
index d8abde1c458..6ea92d1aebf 100644
--- a/src/lread.c
+++ b/src/lread.c
@@ -1924,6 +1924,9 @@ read_escape (readcharfun, stringp)
1924 int stringp; 1924 int stringp;
1925{ 1925{
1926 register int c = READCHAR; 1926 register int c = READCHAR;
1927 /* \u allows up to four hex digits, \U up to eight. Default to the
1928 behaviour for \u, and change this value in the case that \U is seen. */
1929 int unicode_hex_count = 4;
1927 1930
1928 switch (c) 1931 switch (c)
1929 { 1932 {
@@ -2090,6 +2093,52 @@ read_escape (readcharfun, stringp)
2090 return i; 2093 return i;
2091 } 2094 }
2092 2095
2096 case 'U':
2097 /* Post-Unicode-2.0: Up to eight hex chars. */
2098 unicode_hex_count = 8;
2099 case 'u':
2100
2101 /* A Unicode escape. We only permit them in strings and characters,
2102 not arbitrarily in the source code, as in some other languages. */
2103 {
2104 int i = 0;
2105 int count = 0;
2106 Lisp_Object lisp_char;
2107 struct gcpro gcpro1;
2108
2109 while (++count <= unicode_hex_count)
2110 {
2111 c = READCHAR;
2112 /* isdigit(), isalpha() may be locale-specific, which we don't
2113 want. */
2114 if (c >= '0' && c <= '9') i = (i << 4) + (c - '0');
2115 else if (c >= 'a' && c <= 'f') i = (i << 4) + (c - 'a') + 10;
2116 else if (c >= 'A' && c <= 'F') i = (i << 4) + (c - 'A') + 10;
2117 else
2118 {
2119 error ("Non-hex digit used for Unicode escape");
2120 break;
2121 }
2122 }
2123
2124 GCPRO1 (readcharfun);
2125 lisp_char = call2(intern("decode-char"), intern("ucs"),
2126 make_number(i));
2127 UNGCPRO;
2128
2129 if (EQ(Qnil, lisp_char))
2130 {
2131 /* This is ugly and horrible and trashes the user's data. */
2132 XSETFASTINT (i, MAKE_CHAR (charset_katakana_jisx0201,
2133 34 + 128, 46 + 128));
2134 return i;
2135 }
2136 else
2137 {
2138 return XFASTINT (lisp_char);
2139 }
2140 }
2141
2093 default: 2142 default:
2094 return c; 2143 return c;
2095 } 2144 }
diff --git a/src/macfns.c b/src/macfns.c
index 1c774f8ade2..6d77aea0409 100644
--- a/src/macfns.c
+++ b/src/macfns.c
@@ -3070,11 +3070,20 @@ If omitted or nil, that stands for the selected frame's display. */)
3070 (display) 3070 (display)
3071 Lisp_Object display; 3071 Lisp_Object display;
3072{ 3072{
3073 /* MAC_TODO: this is an approximation, and only of the main display */
3074
3075 struct mac_display_info *dpyinfo = check_x_display_info (display); 3073 struct mac_display_info *dpyinfo = check_x_display_info (display);
3074 /* Only of the main display. */
3075#if MAC_OS_X_VERSION_MAX_ALLOWED >= 1030
3076 CGSize size;
3077
3078 BLOCK_INPUT;
3079 size = CGDisplayScreenSize (kCGDirectMainDisplay);
3080 UNBLOCK_INPUT;
3076 3081
3082 return make_number ((int) (size.height + .5f));
3083#else
3084 /* This is an approximation. */
3077 return make_number ((int) (dpyinfo->height * 25.4 / dpyinfo->resy)); 3085 return make_number ((int) (dpyinfo->height * 25.4 / dpyinfo->resy));
3086#endif
3078} 3087}
3079 3088
3080DEFUN ("x-display-mm-width", Fx_display_mm_width, Sx_display_mm_width, 0, 1, 0, 3089DEFUN ("x-display-mm-width", Fx_display_mm_width, Sx_display_mm_width, 0, 1, 0,
@@ -3085,11 +3094,20 @@ If omitted or nil, that stands for the selected frame's display. */)
3085 (display) 3094 (display)
3086 Lisp_Object display; 3095 Lisp_Object display;
3087{ 3096{
3088 /* MAC_TODO: this is an approximation, and only of the main display */
3089
3090 struct mac_display_info *dpyinfo = check_x_display_info (display); 3097 struct mac_display_info *dpyinfo = check_x_display_info (display);
3098 /* Only of the main display. */
3099#if MAC_OS_X_VERSION_MAX_ALLOWED >= 1030
3100 CGSize size;
3101
3102 BLOCK_INPUT;
3103 size = CGDisplayScreenSize (kCGDirectMainDisplay);
3104 UNBLOCK_INPUT;
3091 3105
3106 return make_number ((int) (size.width + .5f));
3107#else
3108 /* This is an approximation. */
3092 return make_number ((int) (dpyinfo->width * 25.4 / dpyinfo->resx)); 3109 return make_number ((int) (dpyinfo->width * 25.4 / dpyinfo->resx));
3110#endif
3093} 3111}
3094 3112
3095DEFUN ("x-display-backing-store", Fx_display_backing_store, 3113DEFUN ("x-display-backing-store", Fx_display_backing_store,
diff --git a/src/macterm.c b/src/macterm.c
index dc449498a4a..7e354642759 100644
--- a/src/macterm.c
+++ b/src/macterm.c
@@ -8533,6 +8533,9 @@ static Lisp_Object Qtext_input;
8533static Lisp_Object Qupdate_active_input_area, Qunicode_for_key_event; 8533static Lisp_Object Qupdate_active_input_area, Qunicode_for_key_event;
8534static Lisp_Object Vmac_ts_active_input_overlay; 8534static Lisp_Object Vmac_ts_active_input_overlay;
8535extern Lisp_Object Qbefore_string; 8535extern Lisp_Object Qbefore_string;
8536static Lisp_Object Vmac_ts_script_language_on_focus;
8537static ScriptLanguageRecord saved_ts_language;
8538static Component saved_ts_component;
8536#endif 8539#endif
8537#endif 8540#endif
8538extern int mac_ready_for_apple_events; 8541extern int mac_ready_for_apple_events;
@@ -8882,22 +8885,84 @@ is_emacs_window (WindowPtr win)
8882 return 0; 8885 return 0;
8883} 8886}
8884 8887
8885static void
8886do_app_resume ()
8887{
8888#if USE_MAC_TSM 8888#if USE_MAC_TSM
8889 ActivateTSMDocument (tsm_document_id); 8889static OSStatus
8890mac_tsm_resume ()
8891{
8892 OSStatus err;
8893 ScriptLanguageRecord slrec, *slptr = NULL;
8894
8895 err = ActivateTSMDocument (tsm_document_id);
8896
8897 if (err == noErr)
8898 {
8899 if (EQ (Vmac_ts_script_language_on_focus, Qt))
8900 slptr = &saved_ts_language;
8901 else if (CONSP (Vmac_ts_script_language_on_focus)
8902 && INTEGERP (XCAR (Vmac_ts_script_language_on_focus))
8903 && INTEGERP (XCDR (Vmac_ts_script_language_on_focus)))
8904 {
8905 slrec.fScript = XINT (XCAR (Vmac_ts_script_language_on_focus));
8906 slrec.fLanguage = XINT (XCDR (Vmac_ts_script_language_on_focus));
8907 slptr = &slrec;
8908 }
8909 }
8910
8911 if (slptr)
8912 {
8913#if MAC_OS_X_VERSION_MAX_ALLOWED >= 1020
8914 err = SetDefaultInputMethodOfClass (saved_ts_component, slptr,
8915 kKeyboardInputMethodClass);
8916#else
8917 err = SetDefaultInputMethod (saved_ts_component, slptr);
8890#endif 8918#endif
8919 if (err == noErr)
8920 err = SetTextServiceLanguage (slptr);
8921
8922 /* Seems to be needed on Mac OS X 10.2. */
8923 if (err == noErr)
8924 KeyScript (slptr->fScript | smKeyForceKeyScriptMask);
8925 }
8926
8927 return err;
8891} 8928}
8892 8929
8893static void 8930static OSStatus
8894do_app_suspend () 8931mac_tsm_suspend ()
8895{ 8932{
8896#if USE_MAC_TSM 8933 OSStatus err;
8897 DeactivateTSMDocument (tsm_document_id); 8934 ScriptLanguageRecord slrec, *slptr = NULL;
8935
8936 if (EQ (Vmac_ts_script_language_on_focus, Qt))
8937 {
8938 err = GetTextServiceLanguage (&saved_ts_language);
8939 if (err == noErr)
8940 slptr = &saved_ts_language;
8941 }
8942 else if (CONSP (Vmac_ts_script_language_on_focus)
8943 && INTEGERP (XCAR (Vmac_ts_script_language_on_focus))
8944 && INTEGERP (XCDR (Vmac_ts_script_language_on_focus)))
8945 {
8946 slrec.fScript = XINT (XCAR (Vmac_ts_script_language_on_focus));
8947 slrec.fLanguage = XINT (XCDR (Vmac_ts_script_language_on_focus));
8948 slptr = &slrec;
8949 }
8950
8951 if (slptr)
8952 {
8953#if MAC_OS_X_VERSION_MAX_ALLOWED >= 1020
8954 GetDefaultInputMethodOfClass (&saved_ts_component, slptr,
8955 kKeyboardInputMethodClass);
8956#else
8957 GetDefaultInputMethod (&saved_ts_component, slptr);
8898#endif 8958#endif
8899} 8959 }
8900 8960
8961 err = DeactivateTSMDocument (tsm_document_id);
8962
8963 return err;
8964}
8965#endif
8901 8966
8902static void 8967static void
8903do_apple_menu (SInt16 menu_item) 8968do_apple_menu (SInt16 menu_item)
@@ -9351,12 +9416,12 @@ mac_handle_window_event (next_handler, event, data)
9351#if USE_MAC_TSM 9416#if USE_MAC_TSM
9352 case kEventWindowFocusAcquired: 9417 case kEventWindowFocusAcquired:
9353 result = CallNextEventHandler (next_handler, event); 9418 result = CallNextEventHandler (next_handler, event);
9354 err = ActivateTSMDocument (tsm_document_id); 9419 err = mac_tsm_resume ();
9355 return err == noErr ? noErr : result; 9420 return err == noErr ? noErr : result;
9356 9421
9357 case kEventWindowFocusRelinquish: 9422 case kEventWindowFocusRelinquish:
9358 result = CallNextEventHandler (next_handler, event); 9423 result = CallNextEventHandler (next_handler, event);
9359 err = DeactivateTSMDocument (tsm_document_id); 9424 err = mac_tsm_suspend ();
9360 return err == noErr ? noErr : result; 9425 return err == noErr ? noErr : result;
9361#endif 9426#endif
9362 } 9427 }
@@ -10391,10 +10456,12 @@ XTread_socket (sd, expected, hold_quit)
10391 switch ((er.message >> 24) & 0x000000FF) 10456 switch ((er.message >> 24) & 0x000000FF)
10392 { 10457 {
10393 case suspendResumeMessage: 10458 case suspendResumeMessage:
10394 if ((er.message & resumeFlag) == 1) 10459#if USE_MAC_TSM
10395 do_app_resume (); 10460 if (er.message & resumeFlag)
10461 mac_tsm_resume ();
10396 else 10462 else
10397 do_app_suspend (); 10463 mac_tsm_suspend ();
10464#endif
10398 break; 10465 break;
10399 10466
10400 case mouseMovedMessage: 10467 case mouseMovedMessage:
@@ -10957,7 +11024,6 @@ void
10957mac_initialize_display_info () 11024mac_initialize_display_info ()
10958{ 11025{
10959 struct mac_display_info *dpyinfo = &one_mac_display_info; 11026 struct mac_display_info *dpyinfo = &one_mac_display_info;
10960 GDHandle main_device_handle;
10961 11027
10962 bzero (dpyinfo, sizeof (*dpyinfo)); 11028 bzero (dpyinfo, sizeof (*dpyinfo));
10963 11029
@@ -10973,37 +11039,29 @@ mac_initialize_display_info ()
10973 strcpy (dpyinfo->mac_id_name, "Mac Display"); 11039 strcpy (dpyinfo->mac_id_name, "Mac Display");
10974#endif 11040#endif
10975 11041
10976 main_device_handle = LMGetMainDevice();
10977
10978 dpyinfo->reference_count = 0; 11042 dpyinfo->reference_count = 0;
10979 dpyinfo->resx = 72.0; 11043 dpyinfo->resx = 72.0;
10980 dpyinfo->resy = 72.0; 11044 dpyinfo->resy = 72.0;
10981 dpyinfo->color_p = TestDeviceAttribute (main_device_handle, gdDevType);
10982#ifdef MAC_OSX 11045#ifdef MAC_OSX
10983 /* HasDepth returns true if it is possible to have a 32 bit display, 11046 /* HasDepth returns true if it is possible to have a 32 bit display,
10984 but this may not be what is actually used. Mac OSX can do better. 11047 but this may not be what is actually used. Mac OSX can do better. */
10985 CGMainDisplayID is only available on OSX 10.2 and higher, but the 11048 dpyinfo->color_p = 1;
10986 header for CGGetActiveDisplayList says that the first display returned 11049 dpyinfo->n_planes = CGDisplayBitsPerPixel (kCGDirectMainDisplay);
10987 is the active one, so we use that. */ 11050 dpyinfo->height = CGDisplayPixelsHigh (kCGDirectMainDisplay);
11051 dpyinfo->width = CGDisplayPixelsWide (kCGDirectMainDisplay);
11052#else
10988 { 11053 {
10989 CGDirectDisplayID disp_id[1]; 11054 GDHandle main_device_handle = LMGetMainDevice();
10990 CGDisplayCount disp_count;
10991 CGDisplayErr error_code;
10992
10993 error_code = CGGetActiveDisplayList (1, disp_id, &disp_count);
10994 if (error_code != 0)
10995 error ("No display found, CGGetActiveDisplayList error %d", error_code);
10996 11055
10997 dpyinfo->n_planes = CGDisplayBitsPerPixel (disp_id[0]); 11056 dpyinfo->color_p = TestDeviceAttribute (main_device_handle, gdDevType);
11057 for (dpyinfo->n_planes = 32; dpyinfo->n_planes > 0; dpyinfo->n_planes >>= 1)
11058 if (HasDepth (main_device_handle, dpyinfo->n_planes,
11059 gdDevType, dpyinfo->color_p))
11060 break;
11061 dpyinfo->height = (**main_device_handle).gdRect.bottom;
11062 dpyinfo->width = (**main_device_handle).gdRect.right;
10998 } 11063 }
10999#else
11000 for (dpyinfo->n_planes = 32; dpyinfo->n_planes > 0; dpyinfo->n_planes >>= 1)
11001 if (HasDepth (main_device_handle, dpyinfo->n_planes,
11002 gdDevType, dpyinfo->color_p))
11003 break;
11004#endif 11064#endif
11005 dpyinfo->height = (**main_device_handle).gdRect.bottom;
11006 dpyinfo->width = (**main_device_handle).gdRect.right;
11007 dpyinfo->grabbed = 0; 11065 dpyinfo->grabbed = 0;
11008 dpyinfo->root_window = NULL; 11066 dpyinfo->root_window = NULL;
11009 dpyinfo->image_cache = make_image_cache (); 11067 dpyinfo->image_cache = make_image_cache ();
@@ -11554,6 +11612,15 @@ order. */);
11554 DEFVAR_LISP ("mac-ts-active-input-overlay", &Vmac_ts_active_input_overlay, 11612 DEFVAR_LISP ("mac-ts-active-input-overlay", &Vmac_ts_active_input_overlay,
11555 doc: /* Overlay used to display Mac TSM active input area. */); 11613 doc: /* Overlay used to display Mac TSM active input area. */);
11556 Vmac_ts_active_input_overlay = Qnil; 11614 Vmac_ts_active_input_overlay = Qnil;
11615
11616 DEFVAR_LISP ("mac-ts-script-language-on-focus", &Vmac_ts_script_language_on_focus,
11617 doc: /* *How to change Mac TSM script/language when a frame gets focus.
11618If the value is t, the input script and language are restored to those
11619used in the last focus frame. If the value is a pair of integers, the
11620input script and language codes, which are defined in the Script
11621Manager, are set to its car and cdr parts, respectively. Otherwise,
11622Emacs doesn't set them and thus follows the system default behavior. */);
11623 Vmac_ts_script_language_on_focus = Qnil;
11557#endif 11624#endif
11558} 11625}
11559 11626
diff --git a/src/window.c b/src/window.c
index 59c223b4a8f..6a1edb24efb 100644
--- a/src/window.c
+++ b/src/window.c
@@ -4279,15 +4279,17 @@ adjust_window_trailing_edge (window, delta, horiz_flag)
4279 { 4279 {
4280 Lisp_Object first_parallel = Qnil; 4280 Lisp_Object first_parallel = Qnil;
4281 4281
4282 p = XWINDOW (window); 4282 if (NILP (window))
4283 parent = p->parent;
4284
4285 if (NILP (XWINDOW (window)->next))
4286 { 4283 {
4284 /* This can happen if WINDOW on the previous iteration was
4285 at top level of the tree and we did not exit. */
4287 Fset_window_configuration (old_config); 4286 Fset_window_configuration (old_config);
4288 error ("No other window following this one"); 4287 error ("Specified window edge is fixed");
4289 } 4288 }
4290 4289
4290 p = XWINDOW (window);
4291 parent = p->parent;
4292
4291 /* See if this level has windows in parallel in the specified 4293 /* See if this level has windows in parallel in the specified
4292 direction. If so, set FIRST_PARALLEL to the first one. */ 4294 direction. If so, set FIRST_PARALLEL to the first one. */
4293 if (horiz_flag) 4295 if (horiz_flag)
@@ -4301,6 +4303,14 @@ adjust_window_trailing_edge (window, delta, horiz_flag)
4301 first_parallel = XWINDOW (parent)->hchild; 4303 first_parallel = XWINDOW (parent)->hchild;
4302 } 4304 }
4303 4305
4306 /* If this level's succession is in the desired dimension,
4307 and this window is the last one, its trailing edge is fixed. */
4308 if (NILP (XWINDOW (window)->next) && NILP (first_parallel))
4309 {
4310 Fset_window_configuration (old_config);
4311 error ("Specified window edge is fixed");
4312 }
4313
4304 /* Don't make this window too small. */ 4314 /* Don't make this window too small. */
4305 if (XINT (CURSIZE (window)) + delta 4315 if (XINT (CURSIZE (window)) + delta
4306 < (horiz_flag ? window_min_width : window_min_height)) 4316 < (horiz_flag ? window_min_width : window_min_height))
@@ -4324,7 +4334,7 @@ adjust_window_trailing_edge (window, delta, horiz_flag)
4324 we will fail and report an error, above.) */ 4334 we will fail and report an error, above.) */
4325 if (NILP (first_parallel)) 4335 if (NILP (first_parallel))
4326 { 4336 {
4327 if (!NILP (XWINDOW (window)->next)) 4337 if (!NILP (p->next))
4328 { 4338 {
4329 /* This may happen for the minibuffer. In that case 4339 /* This may happen for the minibuffer. In that case
4330 the window_deletion_count check below does not work. */ 4340 the window_deletion_count check below does not work. */
@@ -4895,6 +4905,8 @@ window_scroll_pixel_based (window, n, whole, noerror)
4895 } 4905 }
4896 else if (noerror) 4906 else if (noerror)
4897 return; 4907 return;
4908 else if (n < 0) /* could happen with empty buffers */
4909 Fsignal (Qbeginning_of_buffer, Qnil);
4898 else 4910 else
4899 Fsignal (Qend_of_buffer, Qnil); 4911 Fsignal (Qend_of_buffer, Qnil);
4900 } 4912 }
diff --git a/src/xdisp.c b/src/xdisp.c
index 0cb34a2fef8..bf51137c716 100644
--- a/src/xdisp.c
+++ b/src/xdisp.c
@@ -925,6 +925,7 @@ static int display_string P_ ((unsigned char *, Lisp_Object, Lisp_Object,
925static void compute_line_metrics P_ ((struct it *)); 925static void compute_line_metrics P_ ((struct it *));
926static void run_redisplay_end_trigger_hook P_ ((struct it *)); 926static void run_redisplay_end_trigger_hook P_ ((struct it *));
927static int get_overlay_strings P_ ((struct it *, int)); 927static int get_overlay_strings P_ ((struct it *, int));
928static int get_overlay_strings_1 P_ ((struct it *, int, int));
928static void next_overlay_string P_ ((struct it *)); 929static void next_overlay_string P_ ((struct it *));
929static void reseat P_ ((struct it *, struct text_pos, int)); 930static void reseat P_ ((struct it *, struct text_pos, int));
930static void reseat_1 P_ ((struct it *, struct text_pos, int)); 931static void reseat_1 P_ ((struct it *, struct text_pos, int));
@@ -2918,8 +2919,8 @@ init_from_display_pos (it, w, pos)
2918 also ``processed'' overlay strings at ZV. */ 2919 also ``processed'' overlay strings at ZV. */
2919 while (it->sp) 2920 while (it->sp)
2920 pop_it (it); 2921 pop_it (it);
2921 it->current.overlay_string_index = -1; 2922 xassert (it->current.overlay_string_index == -1);
2922 it->method = GET_FROM_BUFFER; 2923 xassert (it->method == GET_FROM_BUFFER);
2923 if (CHARPOS (pos->pos) == ZV) 2924 if (CHARPOS (pos->pos) == ZV)
2924 it->overlay_strings_at_end_processed_p = 1; 2925 it->overlay_strings_at_end_processed_p = 1;
2925 } 2926 }
@@ -3030,7 +3031,18 @@ handle_stop (it)
3030 if (handled == HANDLED_RECOMPUTE_PROPS) 3031 if (handled == HANDLED_RECOMPUTE_PROPS)
3031 break; 3032 break;
3032 else if (handled == HANDLED_RETURN) 3033 else if (handled == HANDLED_RETURN)
3033 return; 3034 {
3035 /* We still want to show before and after strings from
3036 overlays even if the actual buffer text is replaced. */
3037 if (!handle_overlay_change_p || it->sp > 1)
3038 return;
3039 if (!get_overlay_strings_1 (it, 0, 0))
3040 return;
3041 it->string_from_display_prop_p = 0;
3042 handle_overlay_change_p = 0;
3043 handled = HANDLED_RECOMPUTE_PROPS;
3044 break;
3045 }
3034 else if (handled == HANDLED_OVERLAY_STRING_CONSUMED) 3046 else if (handled == HANDLED_OVERLAY_STRING_CONSUMED)
3035 handle_overlay_change_p = 0; 3047 handle_overlay_change_p = 0;
3036 } 3048 }
@@ -4650,13 +4662,14 @@ next_overlay_string (it)
4650 int display_ellipsis_p = it->stack[it->sp - 1].display_ellipsis_p; 4662 int display_ellipsis_p = it->stack[it->sp - 1].display_ellipsis_p;
4651 4663
4652 pop_it (it); 4664 pop_it (it);
4653 xassert (it->stop_charpos >= BEGV 4665 xassert (it->sp > 0
4654 && it->stop_charpos <= it->end_charpos); 4666 || it->method == GET_FROM_COMPOSITION
4655 it->string = Qnil; 4667 || (NILP (it->string)
4668 && it->method == GET_FROM_BUFFER
4669 && it->stop_charpos >= BEGV
4670 && it->stop_charpos <= it->end_charpos));
4656 it->current.overlay_string_index = -1; 4671 it->current.overlay_string_index = -1;
4657 SET_TEXT_POS (it->current.string_pos, -1, -1);
4658 it->n_overlay_strings = 0; 4672 it->n_overlay_strings = 0;
4659 it->method = GET_FROM_BUFFER;
4660 4673
4661 /* If we're at the end of the buffer, record that we have 4674 /* If we're at the end of the buffer, record that we have
4662 processed the overlay strings there already, so that 4675 processed the overlay strings there already, so that
@@ -4912,7 +4925,7 @@ load_overlay_strings (it, charpos)
4912 least one overlay string was found. */ 4925 least one overlay string was found. */
4913 4926
4914static int 4927static int
4915get_overlay_strings (it, charpos) 4928get_overlay_strings_1 (it, charpos, compute_stop_p)
4916 struct it *it; 4929 struct it *it;
4917 int charpos; 4930 int charpos;
4918{ 4931{
@@ -4934,12 +4947,13 @@ get_overlay_strings (it, charpos)
4934 /* Make sure we know settings in current_buffer, so that we can 4947 /* Make sure we know settings in current_buffer, so that we can
4935 restore meaningful values when we're done with the overlay 4948 restore meaningful values when we're done with the overlay
4936 strings. */ 4949 strings. */
4937 compute_stop_pos (it); 4950 if (compute_stop_p)
4951 compute_stop_pos (it);
4938 xassert (it->face_id >= 0); 4952 xassert (it->face_id >= 0);
4939 4953
4940 /* Save IT's settings. They are restored after all overlay 4954 /* Save IT's settings. They are restored after all overlay
4941 strings have been processed. */ 4955 strings have been processed. */
4942 xassert (it->sp == 0); 4956 xassert (!compute_stop_p || it->sp == 0);
4943 push_it (it); 4957 push_it (it);
4944 4958
4945 /* Set up IT to deliver display elements from the first overlay 4959 /* Set up IT to deliver display elements from the first overlay
@@ -4951,13 +4965,22 @@ get_overlay_strings (it, charpos)
4951 it->end_charpos = SCHARS (it->string); 4965 it->end_charpos = SCHARS (it->string);
4952 it->multibyte_p = STRING_MULTIBYTE (it->string); 4966 it->multibyte_p = STRING_MULTIBYTE (it->string);
4953 it->method = GET_FROM_STRING; 4967 it->method = GET_FROM_STRING;
4968 return 1;
4954 } 4969 }
4955 else 4970
4956 { 4971 it->current.overlay_string_index = -1;
4957 it->string = Qnil; 4972 return 0;
4958 it->current.overlay_string_index = -1; 4973}
4959 it->method = GET_FROM_BUFFER; 4974
4960 } 4975static int
4976get_overlay_strings (it, charpos)
4977 struct it *it;
4978 int charpos;
4979{
4980 it->string = Qnil;
4981 it->method = GET_FROM_BUFFER;
4982
4983 (void) get_overlay_strings_1 (it, charpos, 1);
4961 4984
4962 CHECK_IT (it); 4985 CHECK_IT (it);
4963 4986
@@ -4982,19 +5005,37 @@ push_it (it)
4982{ 5005{
4983 struct iterator_stack_entry *p; 5006 struct iterator_stack_entry *p;
4984 5007
4985 xassert (it->sp < 2); 5008 xassert (it->sp < IT_STACK_SIZE);
4986 p = it->stack + it->sp; 5009 p = it->stack + it->sp;
4987 5010
4988 p->stop_charpos = it->stop_charpos; 5011 p->stop_charpos = it->stop_charpos;
4989 xassert (it->face_id >= 0); 5012 xassert (it->face_id >= 0);
4990 p->face_id = it->face_id; 5013 p->face_id = it->face_id;
4991 p->string = it->string; 5014 p->string = it->string;
5015 p->method = it->method;
5016 switch (p->method)
5017 {
5018 case GET_FROM_IMAGE:
5019 p->u.image.object = it->object;
5020 p->u.image.image_id = it->image_id;
5021 p->u.image.slice = it->slice;
5022 break;
5023 case GET_FROM_COMPOSITION:
5024 p->u.comp.object = it->object;
5025 p->u.comp.c = it->c;
5026 p->u.comp.len = it->len;
5027 p->u.comp.cmp_id = it->cmp_id;
5028 p->u.comp.cmp_len = it->cmp_len;
5029 break;
5030 case GET_FROM_STRETCH:
5031 p->u.stretch.object = it->object;
5032 break;
5033 }
4992 p->pos = it->current; 5034 p->pos = it->current;
4993 p->end_charpos = it->end_charpos; 5035 p->end_charpos = it->end_charpos;
4994 p->string_nchars = it->string_nchars; 5036 p->string_nchars = it->string_nchars;
4995 p->area = it->area; 5037 p->area = it->area;
4996 p->multibyte_p = it->multibyte_p; 5038 p->multibyte_p = it->multibyte_p;
4997 p->slice = it->slice;
4998 p->space_width = it->space_width; 5039 p->space_width = it->space_width;
4999 p->font_height = it->font_height; 5040 p->font_height = it->font_height;
5000 p->voffset = it->voffset; 5041 p->voffset = it->voffset;
@@ -5021,13 +5062,33 @@ pop_it (it)
5021 p = it->stack + it->sp; 5062 p = it->stack + it->sp;
5022 it->stop_charpos = p->stop_charpos; 5063 it->stop_charpos = p->stop_charpos;
5023 it->face_id = p->face_id; 5064 it->face_id = p->face_id;
5024 it->string = p->string;
5025 it->current = p->pos; 5065 it->current = p->pos;
5066 it->string = p->string;
5067 if (NILP (it->string))
5068 SET_TEXT_POS (it->current.string_pos, -1, -1);
5069 it->method = p->method;
5070 switch (it->method)
5071 {
5072 case GET_FROM_IMAGE:
5073 it->image_id = p->u.image.image_id;
5074 it->object = p->u.image.object;
5075 it->slice = p->u.image.slice;
5076 break;
5077 case GET_FROM_COMPOSITION:
5078 it->object = p->u.comp.object;
5079 it->c = p->u.comp.c;
5080 it->len = p->u.comp.len;
5081 it->cmp_id = p->u.comp.cmp_id;
5082 it->cmp_len = p->u.comp.cmp_len;
5083 break;
5084 case GET_FROM_STRETCH:
5085 it->object = p->u.comp.object;
5086 break;
5087 }
5026 it->end_charpos = p->end_charpos; 5088 it->end_charpos = p->end_charpos;
5027 it->string_nchars = p->string_nchars; 5089 it->string_nchars = p->string_nchars;
5028 it->area = p->area; 5090 it->area = p->area;
5029 it->multibyte_p = p->multibyte_p; 5091 it->multibyte_p = p->multibyte_p;
5030 it->slice = p->slice;
5031 it->space_width = p->space_width; 5092 it->space_width = p->space_width;
5032 it->font_height = p->font_height; 5093 it->font_height = p->font_height;
5033 it->voffset = p->voffset; 5094 it->voffset = p->voffset;
@@ -5178,37 +5239,47 @@ back_to_previous_visible_line_start (it)
5178 continue; 5239 continue;
5179 } 5240 }
5180 5241
5181 /* If newline has a display property that replaces the newline with something 5242 if (IT_CHARPOS (*it) <= BEGV)
5182 else (image or text), find start of overlay or interval and continue search 5243 break;
5183 from that point. */
5184 if (IT_CHARPOS (*it) > BEGV)
5185 {
5186 struct it it2 = *it;
5187 int pos;
5188 int beg, end;
5189 Lisp_Object val, overlay;
5190
5191 pos = --IT_CHARPOS (it2);
5192 --IT_BYTEPOS (it2);
5193 it2.sp = 0;
5194 if (handle_display_prop (&it2) == HANDLED_RETURN
5195 && !NILP (val = get_char_property_and_overlay
5196 (make_number (pos), Qdisplay, Qnil, &overlay))
5197 && (OVERLAYP (overlay)
5198 ? (beg = OVERLAY_POSITION (OVERLAY_START (overlay)))
5199 : get_property_and_range (pos, Qdisplay, &val, &beg, &end, Qnil)))
5200 {
5201 if (beg < BEGV)
5202 beg = BEGV;
5203 IT_CHARPOS (*it) = beg;
5204 IT_BYTEPOS (*it) = buf_charpos_to_bytepos (current_buffer, beg);
5205 continue;
5206 }
5207 }
5208 5244
5209 break; 5245 {
5246 struct it it2;
5247 int pos;
5248 int beg, end;
5249 Lisp_Object val, overlay;
5250
5251 /* If newline is part of a composition, continue from start of composition */
5252 if (find_composition (IT_CHARPOS (*it), -1, &beg, &end, &val, Qnil)
5253 && beg < IT_CHARPOS (*it))
5254 goto replaced;
5255
5256 /* If newline is replaced by a display property, find start of overlay
5257 or interval and continue search from that point. */
5258 it2 = *it;
5259 pos = --IT_CHARPOS (it2);
5260 --IT_BYTEPOS (it2);
5261 it2.sp = 0;
5262 if (handle_display_prop (&it2) == HANDLED_RETURN
5263 && !NILP (val = get_char_property_and_overlay
5264 (make_number (pos), Qdisplay, Qnil, &overlay))
5265 && (OVERLAYP (overlay)
5266 ? (beg = OVERLAY_POSITION (OVERLAY_START (overlay)))
5267 : get_property_and_range (pos, Qdisplay, &val, &beg, &end, Qnil)))
5268 goto replaced;
5269
5270 /* Newline is not replaced by anything -- so we are done. */
5271 break;
5272
5273 replaced:
5274 if (beg < BEGV)
5275 beg = BEGV;
5276 IT_CHARPOS (*it) = beg;
5277 IT_BYTEPOS (*it) = buf_charpos_to_bytepos (current_buffer, beg);
5278 }
5210 } 5279 }
5211 5280
5281 it->continuation_lines_width = 0;
5282
5212 xassert (IT_CHARPOS (*it) >= BEGV); 5283 xassert (IT_CHARPOS (*it) >= BEGV);
5213 xassert (IT_CHARPOS (*it) == BEGV 5284 xassert (IT_CHARPOS (*it) == BEGV
5214 || FETCH_BYTE (IT_BYTEPOS (*it) - 1) == '\n'); 5285 || FETCH_BYTE (IT_BYTEPOS (*it) - 1) == '\n');
@@ -5340,15 +5411,11 @@ reseat_1 (it, pos, set_stop_p)
5340 IT_STRING_BYTEPOS (*it) = -1; 5411 IT_STRING_BYTEPOS (*it) = -1;
5341 it->string = Qnil; 5412 it->string = Qnil;
5342 it->method = GET_FROM_BUFFER; 5413 it->method = GET_FROM_BUFFER;
5343 /* RMS: I added this to fix a bug in move_it_vertically_backward 5414 it->object = it->w->buffer;
5344 where it->area continued to relate to the starting point
5345 for the backward motion. Bug report from
5346 Nick Roberts <nick@nick.uklinux.net> on 19 May 2003.
5347 However, I am not sure whether reseat still does the right thing
5348 in general after this change. */
5349 it->area = TEXT_AREA; 5415 it->area = TEXT_AREA;
5350 it->multibyte_p = !NILP (current_buffer->enable_multibyte_characters); 5416 it->multibyte_p = !NILP (current_buffer->enable_multibyte_characters);
5351 it->sp = 0; 5417 it->sp = 0;
5418 it->string_from_display_prop_p = 0;
5352 it->face_before_selective_p = 0; 5419 it->face_before_selective_p = 0;
5353 5420
5354 if (set_stop_p) 5421 if (set_stop_p)
@@ -5830,6 +5897,7 @@ set_iterator_to_next (it, reseat_p)
5830 IT_STRING_BYTEPOS (*it) += it->len; 5897 IT_STRING_BYTEPOS (*it) += it->len;
5831 IT_STRING_CHARPOS (*it) += it->cmp_len; 5898 IT_STRING_CHARPOS (*it) += it->cmp_len;
5832 it->method = GET_FROM_STRING; 5899 it->method = GET_FROM_STRING;
5900 it->object = it->string;
5833 goto consider_string_end; 5901 goto consider_string_end;
5834 } 5902 }
5835 else 5903 else
@@ -5837,6 +5905,7 @@ set_iterator_to_next (it, reseat_p)
5837 IT_BYTEPOS (*it) += it->len; 5905 IT_BYTEPOS (*it) += it->len;
5838 IT_CHARPOS (*it) += it->cmp_len; 5906 IT_CHARPOS (*it) += it->cmp_len;
5839 it->method = GET_FROM_BUFFER; 5907 it->method = GET_FROM_BUFFER;
5908 it->object = it->w->buffer;
5840 } 5909 }
5841 break; 5910 break;
5842 5911
@@ -5866,7 +5935,10 @@ set_iterator_to_next (it, reseat_p)
5866 else if (STRINGP (it->string)) 5935 else if (STRINGP (it->string))
5867 it->method = GET_FROM_STRING; 5936 it->method = GET_FROM_STRING;
5868 else 5937 else
5869 it->method = GET_FROM_BUFFER; 5938 {
5939 it->method = GET_FROM_BUFFER;
5940 it->object = it->w->buffer;
5941 }
5870 5942
5871 it->dpvec = NULL; 5943 it->dpvec = NULL;
5872 it->current.dpvec_index = -1; 5944 it->current.dpvec_index = -1;
@@ -5914,9 +5986,8 @@ set_iterator_to_next (it, reseat_p)
5914 && it->sp > 0) 5986 && it->sp > 0)
5915 { 5987 {
5916 pop_it (it); 5988 pop_it (it);
5917 if (STRINGP (it->string)) 5989 if (it->method == GET_FROM_STRING)
5918 goto consider_string_end; 5990 goto consider_string_end;
5919 it->method = GET_FROM_BUFFER;
5920 } 5991 }
5921 } 5992 }
5922 break; 5993 break;
@@ -5928,13 +5999,8 @@ set_iterator_to_next (it, reseat_p)
5928 if the `display' property takes up the whole string. */ 5999 if the `display' property takes up the whole string. */
5929 xassert (it->sp > 0); 6000 xassert (it->sp > 0);
5930 pop_it (it); 6001 pop_it (it);
5931 it->image_id = 0; 6002 if (it->method == GET_FROM_STRING)
5932 if (STRINGP (it->string)) 6003 goto consider_string_end;
5933 {
5934 it->method = GET_FROM_STRING;
5935 goto consider_string_end;
5936 }
5937 it->method = GET_FROM_BUFFER;
5938 break; 6004 break;
5939 6005
5940 default: 6006 default:
@@ -6157,6 +6223,7 @@ next_element_from_ellipsis (it)
6157 setting face_before_selective_p. */ 6223 setting face_before_selective_p. */
6158 it->saved_face_id = it->face_id; 6224 it->saved_face_id = it->face_id;
6159 it->method = GET_FROM_BUFFER; 6225 it->method = GET_FROM_BUFFER;
6226 it->object = it->w->buffer;
6160 reseat_at_next_visible_line_start (it, 1); 6227 reseat_at_next_visible_line_start (it, 1);
6161 it->face_before_selective_p = 1; 6228 it->face_before_selective_p = 1;
6162 } 6229 }
@@ -6345,6 +6412,8 @@ next_element_from_composition (it)
6345 : it->current.pos); 6412 : it->current.pos);
6346 if (STRINGP (it->string)) 6413 if (STRINGP (it->string))
6347 it->object = it->string; 6414 it->object = it->string;
6415 else
6416 it->object = it->w->buffer;
6348 return 1; 6417 return 1;
6349} 6418}
6350 6419
@@ -11787,9 +11856,12 @@ set_cursor_from_row (w, row, matrix, delta, delta_bytes, dy, dvpos)
11787 } 11856 }
11788 else 11857 else
11789 { 11858 {
11790 string_before_pos = last_pos; 11859 if (string_start == NULL)
11791 string_start = glyph; 11860 {
11792 string_start_x = x; 11861 string_before_pos = last_pos;
11862 string_start = glyph;
11863 string_start_x = x;
11864 }
11793 /* Skip all glyphs from string. */ 11865 /* Skip all glyphs from string. */
11794 do 11866 do
11795 { 11867 {
diff --git a/src/xterm.c b/src/xterm.c
index 4f2bc73c9f9..df99f9cad0d 100644
--- a/src/xterm.c
+++ b/src/xterm.c
@@ -359,7 +359,8 @@ static void x_scroll_bar_report_motion P_ ((struct frame **, Lisp_Object *,
359 Lisp_Object *, Lisp_Object *, 359 Lisp_Object *, Lisp_Object *,
360 unsigned long *)); 360 unsigned long *));
361static void x_check_fullscreen P_ ((struct frame *)); 361static void x_check_fullscreen P_ ((struct frame *));
362static void x_check_expected_move P_ ((struct frame *)); 362static void x_check_expected_move P_ ((struct frame *, int, int));
363static void x_sync_with_move P_ ((struct frame *, int, int, int));
363static int handle_one_xevent P_ ((struct x_display_info *, XEvent *, 364static int handle_one_xevent P_ ((struct x_display_info *, XEvent *,
364 int *, struct input_event *)); 365 int *, struct input_event *));
365static SIGTYPE x_connection_closed P_ ((Display *, char *)); 366static SIGTYPE x_connection_closed P_ ((Display *, char *));
@@ -6883,11 +6884,8 @@ handle_one_xevent (dpyinfo, eventp, finish, hold_quit)
6883 && GTK_WIDGET_MAPPED (FRAME_GTK_OUTER_WIDGET (f))) 6884 && GTK_WIDGET_MAPPED (FRAME_GTK_OUTER_WIDGET (f)))
6884#endif 6885#endif
6885 { 6886 {
6886 /* What we have now is the position of Emacs's own window.
6887 Convert that to the position of the window manager window. */
6888 x_real_positions (f, &f->left_pos, &f->top_pos); 6887 x_real_positions (f, &f->left_pos, &f->top_pos);
6889 6888
6890 x_check_expected_move (f);
6891 if (f->want_fullscreen & FULLSCREEN_WAIT) 6889 if (f->want_fullscreen & FULLSCREEN_WAIT)
6892 f->want_fullscreen &= ~(FULLSCREEN_WAIT|FULLSCREEN_BOTH); 6890 f->want_fullscreen &= ~(FULLSCREEN_WAIT|FULLSCREEN_BOTH);
6893 } 6891 }
@@ -8512,8 +8510,11 @@ x_set_offset (f, xoff, yoff, change_gravity)
8512{ 8510{
8513 int modified_top, modified_left; 8511 int modified_top, modified_left;
8514 8512
8515 if (change_gravity > 0) 8513 if (change_gravity != 0)
8516 { 8514 {
8515 FRAME_X_OUTPUT (f)->left_before_move = f->left_pos;
8516 FRAME_X_OUTPUT (f)->top_before_move = f->top_pos;
8517
8517 f->top_pos = yoff; 8518 f->top_pos = yoff;
8518 f->left_pos = xoff; 8519 f->left_pos = xoff;
8519 f->size_hint_flags &= ~ (XNegative | YNegative); 8520 f->size_hint_flags &= ~ (XNegative | YNegative);
@@ -8531,7 +8532,7 @@ x_set_offset (f, xoff, yoff, change_gravity)
8531 modified_left = f->left_pos; 8532 modified_left = f->left_pos;
8532 modified_top = f->top_pos; 8533 modified_top = f->top_pos;
8533 8534
8534 if (FRAME_X_DISPLAY_INFO (f)->wm_type == X_WMTYPE_A) 8535 if (change_gravity != 0 && FRAME_X_DISPLAY_INFO (f)->wm_type == X_WMTYPE_A)
8535 { 8536 {
8536 /* Some WMs (twm, wmaker at least) has an offset that is smaller 8537 /* Some WMs (twm, wmaker at least) has an offset that is smaller
8537 than the WM decorations. So we use the calculated offset instead 8538 than the WM decorations. So we use the calculated offset instead
@@ -8543,13 +8544,26 @@ x_set_offset (f, xoff, yoff, change_gravity)
8543 XMoveWindow (FRAME_X_DISPLAY (f), FRAME_OUTER_WINDOW (f), 8544 XMoveWindow (FRAME_X_DISPLAY (f), FRAME_OUTER_WINDOW (f),
8544 modified_left, modified_top); 8545 modified_left, modified_top);
8545 8546
8546 if (FRAME_VISIBLE_P (f) 8547 x_sync_with_move (f, f->left_pos, f->top_pos,
8547 && FRAME_X_DISPLAY_INFO (f)->wm_type == X_WMTYPE_UNKNOWN) 8548 FRAME_X_DISPLAY_INFO (f)->wm_type == X_WMTYPE_UNKNOWN
8548 { 8549 ? 1 : 0);
8549 FRAME_X_OUTPUT (f)->check_expected_move = 1; 8550
8550 FRAME_X_OUTPUT (f)->expected_top = f->top_pos; 8551 /* change_gravity is non-zero when this function is called from Lisp to
8551 FRAME_X_OUTPUT (f)->expected_left = f->left_pos; 8552 programmatically move a frame. In that case, we call
8552 } 8553 x_check_expected_move to discover if we have a "Type A" or "Type B"
8554 window manager, and, for a "Type A" window manager, adjust the position
8555 of the frame.
8556
8557 We call x_check_expected_move if a programmatic move occurred, and
8558 either the window manager type (A/B) is unknown or it is Type A but we
8559 need to compute the top/left offset adjustment for this frame. */
8560
8561 if (change_gravity != 0 &&
8562 (FRAME_X_DISPLAY_INFO (f)->wm_type == X_WMTYPE_UNKNOWN
8563 || (FRAME_X_DISPLAY_INFO (f)->wm_type == X_WMTYPE_A
8564 && (FRAME_X_OUTPUT (f)->move_offset_left == 0
8565 && FRAME_X_OUTPUT (f)->move_offset_top == 0))))
8566 x_check_expected_move (f, modified_left, modified_top);
8553 8567
8554 UNBLOCK_INPUT; 8568 UNBLOCK_INPUT;
8555} 8569}
@@ -8584,37 +8598,96 @@ x_check_fullscreen (f)
8584 } 8598 }
8585} 8599}
8586 8600
8587/* If frame parameters are set after the frame is mapped, we need to move 8601/* This function is called by x_set_offset to determine whether the window
8588 the window. 8602 manager interfered with the positioning of the frame. Type A window
8589 Some window managers moves the window to the right position, some 8603 managers position the surrounding window manager decorations a small
8590 moves the outer window manager window to the specified position. 8604 amount above and left of the user-supplied position. Type B window
8591 Here we check that we are in the right spot. If not, make a second 8605 managers position the surrounding window manager decorations at the
8592 move, assuming we are dealing with the second kind of window manager. */ 8606 user-specified position. If we detect a Type A window manager, we
8607 compensate by moving the window right and down by the proper amount. */
8608
8593static void 8609static void
8594x_check_expected_move (f) 8610x_check_expected_move (f, expected_left, expected_top)
8595 struct frame *f; 8611 struct frame *f;
8612 int expected_left;
8613 int expected_top;
8596{ 8614{
8597 if (FRAME_X_OUTPUT (f)->check_expected_move) 8615 int count = 0, current_left = 0, current_top = 0;
8598 { 8616
8599 int expect_top = FRAME_X_OUTPUT (f)->expected_top; 8617 /* x_real_positions returns the left and top offsets of the outermost
8600 int expect_left = FRAME_X_OUTPUT (f)->expected_left; 8618 window manager window around the frame. */
8601 8619
8602 if (expect_top != f->top_pos || expect_left != f->left_pos) 8620 x_real_positions (f, &current_left, &current_top);
8621
8622 if (current_left != expected_left || current_top != expected_top)
8603 { 8623 {
8624 /* It's a "Type A" window manager. */
8625
8626 int adjusted_left;
8627 int adjusted_top;
8628
8604 FRAME_X_DISPLAY_INFO (f)->wm_type = X_WMTYPE_A; 8629 FRAME_X_DISPLAY_INFO (f)->wm_type = X_WMTYPE_A;
8605 FRAME_X_OUTPUT (f)->move_offset_left = expect_left - f->left_pos; 8630 FRAME_X_OUTPUT (f)->move_offset_left = expected_left - current_left;
8606 FRAME_X_OUTPUT (f)->move_offset_top = expect_top - f->top_pos; 8631 FRAME_X_OUTPUT (f)->move_offset_top = expected_top - current_top;
8632
8633 /* Now fix the mispositioned frame's location. */
8607 8634
8608 f->left_pos = expect_left; 8635 adjusted_left = expected_left + FRAME_X_OUTPUT (f)->move_offset_left;
8609 f->top_pos = expect_top; 8636 adjusted_top = expected_top + FRAME_X_OUTPUT (f)->move_offset_top;
8610 x_set_offset (f, expect_left, expect_top, 0); 8637
8638 XMoveWindow (FRAME_X_DISPLAY (f), FRAME_OUTER_WINDOW (f),
8639 adjusted_left, adjusted_top);
8640
8641 x_sync_with_move (f, expected_left, expected_top, 0);
8611 } 8642 }
8612 else if (FRAME_X_DISPLAY_INFO (f)->wm_type == X_WMTYPE_UNKNOWN) 8643 else
8644 /* It's a "Type B" window manager. We don't have to adjust the
8645 frame's position. */
8646
8613 FRAME_X_DISPLAY_INFO (f)->wm_type = X_WMTYPE_B; 8647 FRAME_X_DISPLAY_INFO (f)->wm_type = X_WMTYPE_B;
8648}
8649
8650
8651/* Wait for XGetGeometry to return up-to-date position information for a
8652 recently-moved frame. Call this immediately after calling XMoveWindow.
8653 If FUZZY is non-zero, then LEFT and TOP are just estimates of where the
8654 frame has been moved to, so we use a fuzzy position comparison instead
8655 of an exact comparison. */
8656
8657static void
8658x_sync_with_move (f, left, top, fuzzy)
8659 struct frame *f;
8660 int left, top, fuzzy;
8661{
8662 int count = 0;
8663
8664 while (count++ < 50)
8665 {
8666 int current_left = 0, current_top = 0;
8667
8668 /* In theory, this call to XSync only needs to happen once, but in
8669 practice, it doesn't seem to work, hence the need for the surrounding
8670 loop. */
8671
8672 XSync (FRAME_X_DISPLAY (f), False);
8673 x_real_positions (f, &current_left, &current_top);
8674
8675 if (fuzzy)
8676 {
8677 /* The left fuzz-factor is 10 pixels. The top fuzz-factor is 40
8678 pixels. */
8614 8679
8615 /* Just do this once */ 8680 if (abs (current_left - left) <= 10 && abs (current_top - top) <= 40)
8616 FRAME_X_OUTPUT (f)->check_expected_move = 0; 8681 return;
8617 } 8682 }
8683 else if (current_left == left && current_top == top)
8684 return;
8685 }
8686
8687 /* As a last resort, just wait 0.5 seconds and hope that XGetGeometry
8688 will then return up-to-date position info. */
8689
8690 wait_reading_process_output (0, 500000, 0, 0, Qnil, NULL, 0);
8618} 8691}
8619 8692
8620 8693
diff --git a/src/xterm.h b/src/xterm.h
index 411a7deea87..8bc9782b02b 100644
--- a/src/xterm.h
+++ b/src/xterm.h
@@ -644,18 +644,14 @@ struct x_output
644 FocusOut and LeaveNotify clears EXPLICIT/IMPLICIT. */ 644 FocusOut and LeaveNotify clears EXPLICIT/IMPLICIT. */
645 int focus_state; 645 int focus_state;
646 646
647 /* The latest move we made to FRAME_OUTER_WINDOW. Saved so we can
648 compensate for type A WMs (see wm_type in dpyinfo above). */
649 int expected_top;
650 int expected_left;
651
652 /* The offset we need to add to compensate for type A WMs. */ 647 /* The offset we need to add to compensate for type A WMs. */
653 int move_offset_top; 648 int move_offset_top;
654 int move_offset_left; 649 int move_offset_left;
655 650
656 /* Nonzero if we have made a move and needs to check if the WM placed us 651 /* The frame's left/top offsets before we call XMoveWindow. See
657 at the right position. */ 652 x_check_expected_move. */
658 int check_expected_move; 653 int left_before_move;
654 int top_before_move;
659}; 655};
660 656
661#define No_Cursor (None) 657#define No_Cursor (None)