diff options
| author | Miles Bader | 2006-06-17 20:57:37 +0000 |
|---|---|---|
| committer | Miles Bader | 2006-06-17 20:57:37 +0000 |
| commit | 10c1758c0b2d29b3e1fb8e3ffe5c5dc262f25217 (patch) | |
| tree | 78d2db4ab91026e7d5373086d022a2bce083200b /src | |
| parent | 2090e2a3897bd0e36fd0e8ba13d861668a0a887f (diff) | |
| parent | f362b76002bfd0f43af76a7772a808c042302f07 (diff) | |
| download | emacs-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/.gdbinit | 129 | ||||
| -rw-r--r-- | src/ChangeLog | 123 | ||||
| -rw-r--r-- | src/callproc.c | 4 | ||||
| -rw-r--r-- | src/dispextern.h | 21 | ||||
| -rw-r--r-- | src/dispnew.c | 133 | ||||
| -rw-r--r-- | src/eval.c | 4 | ||||
| -rw-r--r-- | src/lread.c | 49 | ||||
| -rw-r--r-- | src/macfns.c | 26 | ||||
| -rw-r--r-- | src/macterm.c | 141 | ||||
| -rw-r--r-- | src/window.c | 24 | ||||
| -rw-r--r-- | src/xdisp.c | 208 | ||||
| -rw-r--r-- | src/xterm.c | 139 | ||||
| -rw-r--r-- | src/xterm.h | 12 |
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 | |||
| 372 | Pretty print window structure w. | 374 | Pretty print window structure w. |
| 373 | end | 375 | end |
| 374 | 376 | ||
| 377 | define 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" | ||
| 430 | end | ||
| 431 | document pgx | ||
| 432 | Pretty print a glyph structure. | ||
| 433 | Takes one argument, a pointer to a glyph structure | ||
| 434 | end | ||
| 435 | |||
| 436 | define pg | ||
| 437 | set $pgidx = 0 | ||
| 438 | pgx glyph | ||
| 439 | end | ||
| 440 | document pg | ||
| 441 | Pretty print glyph structure glyph. | ||
| 442 | end | ||
| 443 | |||
| 444 | define pgi | ||
| 445 | set $pgidx = $arg0 | ||
| 446 | pgx (&glyph[$pgidx]) | ||
| 447 | end | ||
| 448 | document pgi | ||
| 449 | Pretty print glyph structure glyph[I]. | ||
| 450 | Takes one argument, a integer I. | ||
| 451 | end | ||
| 452 | |||
| 453 | define pgn | ||
| 454 | set $pgidx = $pgidx + 1 | ||
| 455 | pgx (&glyph[$pgidx]) | ||
| 456 | end | ||
| 457 | document pgn | ||
| 458 | Pretty print next glyph structure. | ||
| 459 | end | ||
| 460 | |||
| 461 | define 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 | ||
| 480 | end | ||
| 481 | document pgrowx | ||
| 482 | Pretty print all glyphs in a row structure. | ||
| 483 | Takes one argument, a pointer to a row structure. | ||
| 484 | end | ||
| 485 | |||
| 486 | define pgrow | ||
| 487 | pgrowx row | ||
| 488 | end | ||
| 489 | document pgrow | ||
| 490 | Pretty print all glyphs in row structure row. | ||
| 491 | end | ||
| 375 | 492 | ||
| 376 | define xtype | 493 | define 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 @@ | |||
| 1 | 2006-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 | |||
| 6 | 2006-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 | |||
| 15 | 2006-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 | |||
| 38 | 2006-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 | |||
| 52 | 2006-06-14 Chong Yidong <cyd@stupidchicken.com> | ||
| 53 | |||
| 54 | * xdisp.c (back_to_previous_visible_line_start): Reset | ||
| 55 | it->continuation_lines_width. | ||
| 56 | |||
| 57 | 2006-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 | |||
| 67 | 2006-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 | |||
| 99 | 2006-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 | |||
| 112 | 2006-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 | |||
| 119 | 2006-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 | |||
| 1 | 2006-06-06 YAMAMOTO Mitsuharu <mituharu@math.s.chiba-u.ac.jp> | 124 | 2006-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. | |||
| 203 | Fourth arg DISPLAY non-nil means redisplay buffer as output is inserted. | 203 | Fourth arg DISPLAY non-nil means redisplay buffer as output is inserted. |
| 204 | Remaining arguments are strings passed as command arguments to PROGRAM. | 204 | Remaining arguments are strings passed as command arguments to PROGRAM. |
| 205 | 205 | ||
| 206 | If executable PROGRAM can't be found as an executable, `call-process' | ||
| 207 | signals a Lisp error. `call-process' reports errors in execution of | ||
| 208 | the program only through its return and output. | ||
| 209 | |||
| 206 | If BUFFER is 0, `call-process' returns immediately with value nil. | 210 | If BUFFER is 0, `call-process' returns immediately with value nil. |
| 207 | Otherwise it waits for PROGRAM to terminate | 211 | Otherwise it waits for PROGRAM to terminate |
| 208 | and returns a numeric exit status or a signal description string. | 212 | and 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 | |||
| 1830 | struct it | 1832 | struct 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 | ||
| 193 | int redisplay_dont_pause; | 193 | int 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 | |||
| 208 | Lisp_Object Vredisplay_preemption_period; | ||
| 209 | |||
| 210 | /* Redisplay preemption timers. */ | ||
| 211 | |||
| 212 | static EMACS_TIME preemption_period; | ||
| 213 | static 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 | |||
| 6388 | sit_for (sec, usec, reading, display, initial_display) | 6490 | sit_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 | |||
| 6422 | if input is available before it starts. | 6531 | if input is available before it starts. |
| 6423 | Value is t if waited the full time with no input arriving. | 6532 | Value is t if waited the full time with no input arriving. |
| 6424 | 6533 | ||
| 6425 | Redisplay will occur even when input is available if you bind | 6534 | Redisplay will occur even when input is available if SECONDS is negative. |
| 6426 | `redisplay-dont-pause' to a non-nil value. | ||
| 6427 | 6535 | ||
| 6428 | An obsolete but still supported form is | 6536 | An 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. | ||
| 7036 | If input is detected, redisplay is pre-empted, and the input is processed. | ||
| 7037 | If 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 | ||
| 196 | Lisp_Object Vmacro_declaration_function; | 196 | Lisp_Object Vmacro_declaration_function; |
| 197 | 197 | ||
| 198 | extern Lisp_Object Qrisky_local_variable; | ||
| 198 | 199 | ||
| 199 | static Lisp_Object funcall_lambda P_ ((Lisp_Object, int, Lisp_Object*)); | 200 | static Lisp_Object funcall_lambda P_ ((Lisp_Object, int, Lisp_Object*)); |
| 200 | 201 | ||
| 201 | void | 202 | void |
| 202 | init_eval_once () | 203 | init_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 | ||
| 3080 | DEFUN ("x-display-mm-width", Fx_display_mm_width, Sx_display_mm_width, 0, 1, 0, | 3089 | DEFUN ("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 | ||
| 3095 | DEFUN ("x-display-backing-store", Fx_display_backing_store, | 3113 | DEFUN ("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; | |||
| 8533 | static Lisp_Object Qupdate_active_input_area, Qunicode_for_key_event; | 8533 | static Lisp_Object Qupdate_active_input_area, Qunicode_for_key_event; |
| 8534 | static Lisp_Object Vmac_ts_active_input_overlay; | 8534 | static Lisp_Object Vmac_ts_active_input_overlay; |
| 8535 | extern Lisp_Object Qbefore_string; | 8535 | extern Lisp_Object Qbefore_string; |
| 8536 | static Lisp_Object Vmac_ts_script_language_on_focus; | ||
| 8537 | static ScriptLanguageRecord saved_ts_language; | ||
| 8538 | static Component saved_ts_component; | ||
| 8536 | #endif | 8539 | #endif |
| 8537 | #endif | 8540 | #endif |
| 8538 | extern int mac_ready_for_apple_events; | 8541 | extern 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 | ||
| 8885 | static void | ||
| 8886 | do_app_resume () | ||
| 8887 | { | ||
| 8888 | #if USE_MAC_TSM | 8888 | #if USE_MAC_TSM |
| 8889 | ActivateTSMDocument (tsm_document_id); | 8889 | static OSStatus |
| 8890 | mac_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 | ||
| 8893 | static void | 8930 | static OSStatus |
| 8894 | do_app_suspend () | 8931 | mac_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 | ||
| 8902 | static void | 8967 | static void |
| 8903 | do_apple_menu (SInt16 menu_item) | 8968 | do_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 | |||
| 10957 | mac_initialize_display_info () | 11024 | mac_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. | ||
| 11618 | If the value is t, the input script and language are restored to those | ||
| 11619 | used in the last focus frame. If the value is a pair of integers, the | ||
| 11620 | input script and language codes, which are defined in the Script | ||
| 11621 | Manager, are set to its car and cdr parts, respectively. Otherwise, | ||
| 11622 | Emacs 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, | |||
| 925 | static void compute_line_metrics P_ ((struct it *)); | 925 | static void compute_line_metrics P_ ((struct it *)); |
| 926 | static void run_redisplay_end_trigger_hook P_ ((struct it *)); | 926 | static void run_redisplay_end_trigger_hook P_ ((struct it *)); |
| 927 | static int get_overlay_strings P_ ((struct it *, int)); | 927 | static int get_overlay_strings P_ ((struct it *, int)); |
| 928 | static int get_overlay_strings_1 P_ ((struct it *, int, int)); | ||
| 928 | static void next_overlay_string P_ ((struct it *)); | 929 | static void next_overlay_string P_ ((struct it *)); |
| 929 | static void reseat P_ ((struct it *, struct text_pos, int)); | 930 | static void reseat P_ ((struct it *, struct text_pos, int)); |
| 930 | static void reseat_1 P_ ((struct it *, struct text_pos, int)); | 931 | static 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 | ||
| 4914 | static int | 4927 | static int |
| 4915 | get_overlay_strings (it, charpos) | 4928 | get_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 | } | 4975 | static int |
| 4976 | get_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 *)); |
| 361 | static void x_check_fullscreen P_ ((struct frame *)); | 361 | static void x_check_fullscreen P_ ((struct frame *)); |
| 362 | static void x_check_expected_move P_ ((struct frame *)); | 362 | static void x_check_expected_move P_ ((struct frame *, int, int)); |
| 363 | static void x_sync_with_move P_ ((struct frame *, int, int, int)); | ||
| 363 | static int handle_one_xevent P_ ((struct x_display_info *, XEvent *, | 364 | static int handle_one_xevent P_ ((struct x_display_info *, XEvent *, |
| 364 | int *, struct input_event *)); | 365 | int *, struct input_event *)); |
| 365 | static SIGTYPE x_connection_closed P_ ((Display *, char *)); | 366 | static 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 | |||
| 8593 | static void | 8609 | static void |
| 8594 | x_check_expected_move (f) | 8610 | x_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, ¤t_left, ¤t_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 | |||
| 8657 | static void | ||
| 8658 | x_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, ¤t_left, ¤t_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) |