Implement mouse highlight for bidi-reordered lines.
authorEli Zaretskii <eliz@gnu.org>
Sat, 23 Oct 2010 15:30:45 +0000 (17:30 +0200)
committerEli Zaretskii <eliz@gnu.org>
Sat, 23 Oct 2010 15:30:45 +0000 (17:30 +0200)
 xdisp.c (fast_find_string_pos): #ifdef away, not used anymore.
 (mouse_face_from_string_pos): New function, replaces
 fast_find_string_pos.
 (note_mouse_highlight): Call it instead of fast_find_string_pos.
 (note_mode_line_or_margin_highlight): Support bidi-reordered
 strings and R2L glyph rows.  Fix comments.
 (note_mouse_highlight): When bidi reordering is turned on in a
 buffer, call next-single-property-change and
 previous-single-property-change with last argument nil.  Clear
 mouse highlight when mouse pointer is in a R2L row on the stretch
 glyph that stands for no text beyond the line end.
 (row_containing_pos): Don't return too early when CHARPOS is in a
 bidi-reordered continued line.  Return immediately when the first
 hit is found in a line that is not continued, or when an exact
 match for CHARPOS is found.
 (rows_from_pos_range): New function.
 (mouse_face_from_buffer_pos): Use it instead of calling
 row_containing_pos for START_CHARPOS and END_CHARPOS.  Rewrite the
 function to support mouse highlight in bidi-reordered lines and
 not to assume that START_CHARPOS is always in mouse_face_beg_row.
 If necessary, swap mouse_face_beg_row and mouse_face_end_row so
 that the former is always above the latter or identical to it.
 (show_mouse_face): Support drawing highlighted R2L lines.
 (coords_in_mouse_face_p): New function, bidi-aware.
 (cursor_in_mouse_face_p, note_mouse_highlight, erase_phys_cursor):
 Call it instead of comparing with mouse-face members of dpyinfo.
 (note_mode_line_or_margin_highlight): Fix confusingly swapped
 usage of hpos and vpos.

1  2 
src/ChangeLog
src/xdisp.c

diff --combined src/ChangeLog
 -      * xdisp.c (mouse_face_from_string_pos): Initialize the `found'
 -      flag to zero, and exit the outer loop when it's non-zero.  Bail
 -      our early if no row in the window belongs to the highlighted
 -      string.  Always back up after exiting the second loop.
 -      Fix off-by-one error when testing against ENDPOS.
 -      Fix support for R2L lines.
 -
 -2010-10-16  Eli Zaretskii  <eliz@gnu.org>
+ 2010-10-23  Eli Zaretskii  <eliz@gnu.org>
 -
 -2010-10-16  Eli Zaretskii  <eliz@gnu.org>
 -
 -      * xdisp.c (note_mode_line_or_margin_highlight): Support
 -      bidi-reordered strings and R2L glyph rows.  Fix more comments.
 -
 -2010-10-16  Eli Zaretskii  <eliz@gnu.org>
 -
 -      * xdisp.c (rows_from_pos_range, mouse_face_from_buffer_pos)
 -      (note_mode_line_or_margin_highlight): Fix comments.
 -
 -2010-10-09  Eli Zaretskii  <eliz@gnu.org>
 -
 -      Finished work on mouse_face_from_buffer_pos for bidi-reordered
 -      rows.  Need lots of testing, including bug#1220.
 -      Next task: get rid of fast_find_position, call
 -      mouse_face_from_buffer_pos instead.
 -
 -      * xdisp.c (rows_from_pos_range): New function.
 -      (mouse_face_from_buffer_pos): Use it instead of calling
 -      row_containing_pos for START_CHARPOS and END_CHARPOS.
++      Implement mouse highlight for bidi-reordered lines.
+       * xdisp.c (fast_find_string_pos): #ifdef away, not used anymore.
+       (mouse_face_from_string_pos): New function, replaces
+       fast_find_string_pos.
+       (note_mouse_highlight): Call it instead of fast_find_string_pos.
 -      previous-single-property-change with last argument nil.
 -
 -2010-10-02  Eli Zaretskii  <eliz@gnu.org>
 -
 -      * xdisp.c (coords_in_mouse_face_p): Fix the conditions for when
 -      mouse_face_beg_row and mouse_face_end_row are equal.
 -      (note_mouse_highlight): Clear mouse highlight when mouse pointer
 -      is in a R2L row on the stretch glyph that stands for no text
 -      beyond the line end.
++      (note_mode_line_or_margin_highlight): Support bidi-reordered
++      strings and R2L glyph rows.  Fix comments.
+       (note_mouse_highlight): When bidi reordering is turned on in a
+       buffer, call next-single-property-change and
 -      (mouse_face_from_buffer_pos): Rewrite to not assume that
 -      START_CHARPOS is always in mouse_face_beg_row.  If necessary, swap
 -      mouse_face_beg_row and mouse_face_end_row so that the former is
 -      always above the latter or identical to it.  Don't compute beg_col
 -      if already decided to paint from beginning of window.
 -
 -2010-08-28  Eli Zaretskii  <eliz@gnu.org>
 -
 -      * xdisp.c (mouse_face_from_buffer_pos): Fix code using bug#1220 as
 -      test case.  Implement  highlight for R2L rows.  Fix the case of
 -      continued L2R lines.
++      previous-single-property-change with last argument nil.  Clear
++      mouse highlight when mouse pointer is in a R2L row on the stretch
++      glyph that stands for no text beyond the line end.
+       (row_containing_pos): Don't return too early when CHARPOS is in a
+       bidi-reordered continued line.  Return immediately when the first
+       hit is found in a line that is not continued, or when an exact
+       match for CHARPOS is found.
 -2010-08-21  Eli Zaretskii  <eliz@gnu.org>
++      (rows_from_pos_range): New function.
++      (mouse_face_from_buffer_pos): Use it instead of calling
++      row_containing_pos for START_CHARPOS and END_CHARPOS.  Rewrite the
++      function to support mouse highlight in bidi-reordered lines and
++      not to assume that START_CHARPOS is always in mouse_face_beg_row.
++      If necessary, swap mouse_face_beg_row and mouse_face_end_row so
++      that the former is always above the latter or identical to it.
+       (show_mouse_face): Support drawing highlighted R2L lines.
+       (coords_in_mouse_face_p): New function, bidi-aware.
+       (cursor_in_mouse_face_p, note_mouse_highlight, erase_phys_cursor):
+       Call it instead of comparing with mouse-face members of dpyinfo.
+       (note_mode_line_or_margin_highlight): Fix confusingly swapped
+       usage of hpos and vpos.
 +2010-10-22  Jan Djärv  <jan.h.d@swipnet.se>
 +
 +      * xrdb.c: Include keyboard.h for MOTIF.
 +
 +      * xmenu.c: Revert 2010-07-27 change: lwlib.h is needed for
 +      MOTIF (Bug#7263).
 +
 +      * xfns.c: Include Xm/TextF and Xm/List.
 +      (file_dialog_cb, file_dialog_unmap_cb, clean_up_file_dialog): Make
 +      ANSI prototypes.
 +
 +2010-10-22  Glenn Morris  <rgm@gnu.org>
 +
 +      * Makefile.in (SOME_MACHINE_LISP): Add w32-vars.
 +      Remove ccl and duplicate mouse.
 +
 +2010-10-21  Chong Yidong  <cyd@stupidchicken.com>
 +
 +      * insdel.c (prepare_to_modify_buffer): Don't set
 +      saved-region-selection if modification hooks are disabled.
 +
 +2010-10-19  Chong Yidong  <cyd@stupidchicken.com>
 +
 +      * cmds.c (Fdelete_char): Doc fix.
 +
 +2010-10-19  Ken Brown  <kbrown@cornell.edu>
 +
 +      * s/cygwin.h (SIGNALS_VIA_CHARACTERS): New define (bug#7225).
 +
 +2010-10-19  Kenichi Handa  <handa@m17n.org>
 +
 +      Fix incorrect font metrics when the same font is opened with
 +      different pixelsizes.
 +
 +      * xftfont.c: Include composite.h.
 +      (xftfont_shape): New function.
 +      (syms_of_xftfont): Set xftfont_driver.shape.
 +
 +2010-10-18  Julien Danjou  <julien@danjou.info>
 +
 +      * frame.c (Fframe_pointer_visible_p):
 +      Add `frame-pointer-visible-p' to get the pointer visibility.
 +
 +2010-10-18  Lars Magne Ingebrigtsen  <larsi@gnus.org>
 +
 +      * gnutls.c (emacs_gnutls_read): Return 0 if we get a
 +      non-"EAGAIN"-like error to signal to Emacs that the socket should
 +      be closed.
 +
 +2010-10-15  Eli Zaretskii  <eliz@gnu.org>
 +
 +      * unexcoff.c (make_hdr): Fix prototype according to changes in
 +      2010-10-03T13:59:56Z!dann@ics.uci.edu.
 +
 +      * image.c (tiff_load): Cast 3rd argument to avoid compiler warning.
 +
 +2010-10-15  Tassilo Horn  <tassilo@member.fsf.org>
 +
 +      * Makefile.in (really-oldXMenu): Fix typo in variable name that
 +      made building the X menu fail.
 +      (really-oldXMenu): Fix my previous fix.
 +
 +2010-10-14  Damyan Pepper  <damyanp@gmail.com>
 +
 +      Fix handling of font properties on Windows (bug#6303).
 +      * font.c (font_filter_properties): New function, refactored from
 +      ftfont_filter_properties.
 +      * font.h (font_filter_properties): Declare.
 +      * ftfont.c (ftfont_filter_properties): Use font_filter_properties.
 +      * w32font.c (w32font_booleans, w32font_non_booleans): New variables.
 +      (w32font_filter_properties): New function.
 +      (w32font_driver): Add w32font_filter_properties.
 +
 +2010-10-14  Juanma Barranquero  <lekktu@gmail.com>
 +
 +      * font.c (Ffont_variation_glyphs):
 +      * ccl.c (Fccl_execute_on_string): Fix typo in docstring.
 +
 +2010-10-14  Juanma Barranquero  <lekktu@gmail.com>
 +
 +      * w32fns.c (w32_wnd_proc, file_dialog_callback):
 +      * w32font.c (w32_generic_family):
 +      * w32inevt.c (key_event):
 +      * w32menu.c (fill_in_menu):
 +      * w32proc.c (reader_thread, w32_executable_type, compare_env)
 +      (merge_and_sort_env, int_from_hex, enum_locale_fn, enum_codepage_fn):
 +      * w32term.c (w32_read_socket): Make static.
 +
 +2010-10-13  Juanma Barranquero  <lekktu@gmail.com>
 +
 +      * image.c (DEF_IMGLIB_FN): Add argument to adapt to strict
 +      prototypes; all callers changed.
 +
 +2010-10-13  Juanma Barranquero  <lekktu@gmail.com>
 +
 +      * makefile.w32-in (TLIB2): Rename from TLIBW32.
 +      (OBJ2): New macro.
 +      (WIN32OBJ, FONTOBJ): Remove.
 +      (OBJ1): Redistribute object files with OBJ2.
 +      (LIBS, $(TEMACS)): Use TLIB2.
 +      (make-buildobj-CMD, make-buildobj-SH): Use OBJ2.
 +      ($(TLIB2), TAGS, TAGS-LISP, TAGS-gmake): Depend on OBJ2.
 +
 +2010-10-13  Juanma Barranquero  <lekktu@gmail.com>
 +
 +      * emacs.c (Vdynamic_library_alist)
 +      (syms_of_emacs) <dynamic-library-alist>: Move from image.c and rename.
 +      Doc fix.
 +
 +      * lisp.h (Vdynamic_library_alist): Declare extern.
 +
 +      * image.c (Vimage_library_alist)
 +      (syms_of_image) <image-library-alist>: Move to emacs.c and rename.
 +      (lookup_image_type): Use Vdynamic_library_alist.
 +      (Finit_image_library): Doc fix.
 +
 +2010-10-12  Dan Nicolaescu  <dann@ics.uci.edu>
 +
 +      * Makefile.in (lispsource, libsrc, etc, oldxmenudir, lwlibdir)
 +      (lispdir): Remove trailing /, update all uses.
 +
 +2010-10-12  Jan Djärv  <jan.h.d@swipnet.se>
 +
 +      * nsterm.m (Qleft): Declare.
 +      (ns_right_alternate_modifier): New variable
 +      (NSRightAlternateKeyMask): New define.
 +      (EV_MODIFIERS): Parse NSRightAlternateKeyMask if
 +      ns_right_alternate_modifier isn't Qleft.
 +      (keyDown): If ns_right_alternate_modifier isn't Qleft, use it
 +      as emacs modifier for NSRightAlternateKeyMask.
 +      (syms_of_nsterm): DEFVAR_LISP ns-right-alternate-modifier.
 +
 +2010-10-10  Lars Magne Ingebrigtsen  <larsi@gnus.org>
 +
 +      * gnutls.c (emacs_gnutls_write): If we're trying to write before
 +      gnutls is ready, return EAGAIN as the errno.
 +
 +2010-10-10  Dan Nicolaescu  <dann@ics.uci.edu>
 +
 +      * vm-limit.c:
 +      * unexhp9k800.c:
 +      * unexelf.c:
 +      * unexaix.c:
 +      * termcap.c: Remove #ifdef emacs / #ifndef emacs code, unused.
 +
 +      * Makefile.in (temacs): Use $(ALL_CFLAGS) on the link line.
 +      (PROFILING_LDFLAGS): Remove, not needed anymore.
 +
 +      * Makefile.in: Use $(...) everywhere instead of ${...}
 +      (CRT_DIR): Move near potential user.
 +      (START_FILE): Move near CRT_DIR, it might use it.
 +
 +      * sysdep.c (LPASS8): Remove, unused.
 +      (emacs_ospeed): Change from being a global to a local in the only
 +      user: init_baud_rate.
 +
 +2010-10-09  Lars Magne Ingebrigtsen  <larsi@gnus.org>
 +
 +      * gnutls.c (syms_of_gnutls): All the bootprops are keywords.
 +      (emacs_gnutls_write): Remove the debuggin fsync call.
 +      (emacs_gnutls_read): Return -1 if we got an error from
 +      gnutls_read.  This allows us to actually read lots of data from
 +      the GnuTLS stream.
 +      (emacs_gnutls_write): Check for GNUTLS_E_AGAIN and not EINTR.
 +      According to the documentation, this is correct, and it seems to
 +      make things work.
 +
 +2010-10-09  Chong Yidong  <cyd@stupidchicken.com>
 +
 +      * xterm.c (x_draw_relief_rect): Clear corner pixels.
 +
 +2010-10-08  Michael Albinus  <michael.albinus@gmx.de>
 +
 +      * keyboard.c: Revert last change; it was not intended to be
 +      synchronized with the trunk.
 +
 +2010-10-08  Kenichi Handa  <handa@m17n.org>
 +
 +      * coding.c (complement_process_encoding_system): Fix previous change.
 +
 +2010-10-08  Michael Albinus  <michael.albinus@gmx.de>
 +
 +      * dbusbind.c (syms_of_dbusbind): Move putenv call ...
 +      (Fdbus_init_bus): ... here.  (Bug#7113)
 +
 +2010-10-08  Glenn Morris  <rgm@gnu.org>
 +
 +      * buffer.c (before-change-functions, after-change-functions):
 +      Three-year overdue doc fix following 2007-08-13 change.
 +
 +2010-10-08  Kenichi Handa  <handa@m17n.org>
 +
 +      * coding.c (coding_inherit_eol_type): If parent doesn't specify
 +      eol-format, inherit from the system's default.
 +      (complement_process_encoding_system): Make a new coding system
 +      inherit the original eol-format.
 +
 +2010-10-08  Kenichi Handa  <handa@m17n.org>
 +
 +      * coding.c (complement_process_encoding_system): New function.
 +
 +      * coding.h (complement_process_encoding_system): Extern it.
 +
 +      * callproc.c (Fcall_process): Complement the coding system for
 +      encoding arguments.
 +      (Fcall_process_region): Complement the coding system for encoding
 +      the input to the process.
 +
 +      * process.c (Fstart_process): Complement the coding system for
 +      encoding arguments.
 +      (send_process): Complement the coding system for encoding what
 +      sent to the process.
 +
 +2010-10-08  Kenichi Handa  <handa@m17n.org>
 +
 +      * xfont.c (xfont_open): Fix setting of font->average_width from
 +      :avgwidth property (Bug#7123).
 +
 +2010-10-08  Michael Albinus  <michael.albinus@gmx.de>
 +
 +      * dbusbind.c (syms_of_dbusbind): Use putenv instead of setenv, it
 +      is more portable.
 +
 +      * keyboard.c (gobble_input): Move call of xd_read_queued_messages ...
 +      (kbd_buffer_get_event): ... here. This is needed for cygwin, which
 +      has not defined SIGIO.
 +
 +2010-10-08  Chong Yidong  <cyd@stupidchicken.com>
 +
 +      * xterm.c (x_draw_relief_rect): If box width is larger than 1,
 +      draw the outermost line using the black relief, for legibility.
 +      Omit drawing the four corner pixels.
 +
 +2010-10-04  Chong Yidong  <cyd@stupidchicken.com>
 +
 +      * keyboard.c (echo_prompt): Function moved into read_key_sequence.
 +      (read_key_sequence): Inline echo_prompt.
 +      (echo_dash): Add a dash only if key is continued (Bug#7137).
 +
 +2010-10-04  Dan Nicolaescu  <dann@ics.uci.edu>
 +
 +      Remove O_RDONLY, O_WRONLY definitions, not needed.
 +      * unexcoff.c:
 +      * lread.c:
 +      * fileio.c:
 +      * doc.c:
 +      * callproc.c:
 +      * alloc.c:
 +      * termcap.c: Remove O_RDONLY O_WRONLY definitions.
 +
 +2010-10-03  Teodor Zlatanov  <tzz@lifelogs.com>
 +
 +      * gnutls.h (GNUTLS_LOG2): Convenience macro.
 +
 +      * gnutls.c: Add property list symbol holders.
 +      (emacs_gnutls_handshake): Clarify how sockets are passed to
 +      GnuTLS.
 +      (gnutls_log_function2): Convenience function using GNUTLS_LOG2.
 +      (Fgnutls_boot): Get all parameters from a plist.  Require trustfiles
 +      and keyfiles to be a list of file names.  Default to "NORMAL" for
 +      the priority string.  Improve logging.
 +
 +2010-10-03  Glenn Morris  <rgm@gnu.org>
 +
 +      * fileio.c (Vdirectory_sep_char): Remove.
 +
 +2010-10-03  Dan Nicolaescu  <dann@ics.uci.edu>
 +
 +      * termhooks.h: Remove #ifdef CONSP.
 +
 +      * xterm.c (NO_INLINE, noinline): Move definitions to ../configure.in.
 +
 +      Include <fcntl.h> unconditionally.
 +      * termcap.c:
 +      * sysdep.c:
 +      * lread.c:
 +      * keyboard.c:
 +      * filelock.c:
 +      * fileio.c:
 +      * doc.c:
 +      * callproc.c:
 +      * alloc.c: Remove include guards for <fcntl.h>, process.c already
 +      does it.
 +
 +      * process.c: Do not include <sys/wait.h>, syswait.h does it.
 +
 +      * sysdep.c (flush_pending_output): Remove code, does not do
 +      anything on any platform.
 +
 +      Remove unused code.
 +      * sysdep.c (select_alarm, sys_select, read_input_waiting): Remove
 +      select emulation, all systems support select.
 +      (set_exclusive_use): Remove, the only user is in an #if 0 block.
 +      * process.c (create_process): Remove #if 0 code.
 +
 +      Remove unused arguments for unexec.
 +      The third one is never used, and the last two are always passed as zero.
 +      * emacs.c (unexec): Add declaration.
 +      (Fdump_emacs): Only pass the first two arguments to unexec.
 +      Simplify #ifdef.
 +      * unexw32.c (unexec):
 +      * unexsol.c (unexec):
 +      * unexhp9k800.c (unexec):
 +      * unexcw.c (unexec): Remove the last 3 arguments, unused.
 +      * unexelf.c (unexec): Remove the last 3 arguments, unused.
 +      (find_section): Use const.
 +      * unexmacosx.c (unexec): Remove the last 3 arguments, unused.
 +      (unexec_error): Declare it NO_RETURN.
 +      * unexcoff.c (make_hdr): Assume bss_start is always zero, remove
 +      it as an argument, remove data_start and entry_address arguments, unused.
 +      (unexec): Remove bss_start, data_start and
 +      entry_address arguments.
 +      * unexaix.c (make_hdr): Assume bss_start is always zero, remove
 +      it as an argument, remove data_start and entry_address arguments, unused.
 +      (unexec): Remove bss_start, data_start and
 +      entry_address arguments.
 +
 +2010-10-03  Juanma Barranquero  <lekktu@gmail.com>
 +
 +      * makefile.w32-in (TAGS, TAGS-LISP, TAGS-gmake): Add $(FONTOBJ).
 +
 +      * gnutls.c (emacs_gnutls_handshake, gnutls_make_error)
 +      (gnutls_emacs_global_init, gnutls_emacs_global_deinit): Make static.
 +      (Fgnutls_get_initstage, Fgnutls_deinit, Fgnutls_boot, Fgnutls_bye):
 +      Fix typos in docstrings.
 +      (Fgnutls_error_fatalp, Fgnutls_error_string): Doc fixes.
 +      (Fgnutls_errorp): Doc fix; use ERR for the argument name.
 +
 +2010-10-03  Chong Yidong  <cyd@stupidchicken.com>
 +
 +      * keyboard.c (command_loop_1): Make sure the mark is really alive
 +      before using it (Bug#7044).
 +
 +2010-10-02  Juanma Barranquero  <lekktu@gmail.com>
 +
 +      * makefile.w32-in (tags): Rename target to full-tags.
 +
 +2010-10-02  Eli Zaretskii  <eliz@gnu.org>
 +
 +      * emacs.c (main): Remove !WINDOWSNT conditional.
 +      (Fkill_emacs): Don't mention exemption on MS-Windows.
 +
 +2010-10-02  Glenn Morris  <rgm@gnu.org>
 +
 +      * character.c (Fchar_bytes): Remove obsolete function.
 +      (syms_of_character): Remove Schar_bytes.
 +
 +      * emacs.c (fatal_error_signal): Also run Fkill_emacs on SIGINT.
 +      (main) [!WINDOWSNT]: Handle SIGINT with fatal_error_signal
 +      in batch-mode.
 +      (Fkill_emacs): Doc fix.  Also run the hook in batch mode.
 +      (kill-emacs-hook): Doc fix.
 +
 +2010-10-02  Lars Magne Ingebrigtsen  <larsi@gnus.org>
 +
 +      * xml.c (Flibxml_parse_xml_region, Flibxml_parse_html_region)
 +      (parse_region): Reworked to take regions instead of strings, and
 +      renamed to reflect that these are the libxml functions.
 +
 +2010-10-01  Eli Zaretskii  <eliz@gnu.org>
 +
 +      * term.c (init_tty) [DOS_NT]: Don't call Wcm_clear after setting
 +      screen dimensions in tty->Wcm.
 +
 +      * xdisp.c (set_cursor_from_row): When the row is truncated and
 +      point is outside the range of displayed characters, position the
 +      cursor inside the scroll margin.  (Bug#6349)
 +
 +2010-10-01  Dan Nicolaescu  <dann@ics.uci.edu>
 +
 +      Do not include stdlib.h and string.h, config.h does it.
 +      * xfont.c:
 +      * w32term.c:
 +      * w32reg.c:
 +      * w32inevt.c:
 +      * w32heap.c:
 +      * w32console.c:
 +      * w16select.c:
 +      * unexsol.c:
 +      * term.c:
 +      * sound.c:
 +      * scroll.c (m):
 +      * gtkutil.c:
 +      * font.c:
 +      * filelock.c:
 +      * fileio.c:
 +      * dosfns.c:
 +      * dbusbind.c:
 +      * bidi.c:
 +      * callproc.c:
 +      * process.c:
 +      * msdos.c:
 +      * charset.c: Do not include stdlib.h and string.h, config.h does it.
 +
 +      * callproc.c (SIGCHLD): Remove conditional definition, syssignal.h defines it.
 +
 +      * process.c: Move #include <pty.h> earlier.
 +      (SIGCHLD): Remove conditional definition, syssignal.h defines it.
 +      (pty_name): Move definition later.
 +
 +      * nsselect.m (syms_of_nsselect):
 +      * nsmenu.m (syms_of_nsmenu):
 +      * nsfns.m (syms_of_nsfns):
 +      * msdos.c (syms_of_msdos):
 +
 +      * image.c (syms_of_image):
 +      * charset.c (syms_of_charset): Use intern_c_string instead of intern.
 +
 +      * point.h: Remove, unused.
 +
 +2010-10-01  Eli Zaretskii  <eliz@gnu.org>
 +
 +      * makefile.w32-in (TAGS, frc, TAGS-LISP, ../nt/TAGS, tags)
 +      (TAGS-gmake, TAGS-nmake, TAGS-LISP-gmake, TAGS-LISP-nmake)
 +      (nt-TAGS-gmake, nt-TAGS-nmake): New targets.
 +
 +2010-09-30  Dan Nicolaescu  <dann@ics.uci.edu>
 +
 +      * xml.c (parse_string): Use const.
 +
 +2010-09-30  Lars Magne Ingebrigtsen  <larsi@gnus.org>
 +
 +      * eval.c (Fbacktrace): Don't overwrite print-level on exit.  Also
 +      only override Vprint_level if it isn't already bound, and increase
 +      the level to 8 to produce more useful backtraces for bug reports.
 +
 +2010-09-30  Dan Nicolaescu  <dann@ics.uci.edu>
 +
 +      * Makefile.in: ecrt0.c does not exist anymore, do not mention it.
 +
 +2010-09-30  Juanma Barranquero  <lekktu@gmail.com>
 +
 +      * w32console.c (vga_stdcolor_name): Remove unused function;
 +      presumed dead after 2007-11-30T13:57:21Z!jasonr@gnu.org.
 +
 +2010-09-29  Lars Magne Ingebrigtsen  <larsi@gnus.org>
 +
 +      * gnutls.c (emacs_gnutls_handshake): Made into internal function.
 +      (Fgnutls_boot): Start the handshake.
 +      (emacs_gnutls_read): Perform the handshake from the reader loop.
 +      (Fgnutls_boot): Remove some debugging messages.
 +      Change indentation throughout to use the Emacs style.
 +      (emacs_gnutls_handshake): Cast the fds to something that's
 +      possibly the expected length.
 +      (emacs_gnutls_write): Return -1 if we try to write before handshake.
 +
 +      * process.h (Lisp_Process): Add a gnutls_p field to Lisp_Process.
 +
 +      * process.c (make_process): Set the gnutls_p field to zero by
 +      default.
 +      (read_process_output): Always call the gnutls_read function if the
 +      stream is a gnutls stream.
 +      (send_process): Ditto for writes.
 +
 +      * gnutls.c (emacs_gnutls_write, emacs_gnutls_read): Refuse to read
 +      or write anything until the state is GNUTLS_STAGE_READY.
 +      (Fgnutls_boot): Mark the stream as being a gnutls stream.
 +
 +2010-09-29  Eli Zaretskii  <eliz@gnu.org>
 +
 +      * xdisp.c (reseat_1): Initialize bidi_it.paragraph_dir to
 +      NEUTRAL_DIR.
 +      (handle_invisible_prop, iterate_out_of_display_property)
 +      (next_element_from_buffer): If bidi_it.first_elt is set, call
 +      bidi_paragraph_init with NO_DEFAULT_P argument non-zero.
 +      (Bug#7128)
 +
 +      * print.c (print_object): Fix format string and argument types for
 +      printing a Lisp_Misc_Marker.
 +
 +      * xdisp.c (pos_visible_p, c_string_pos, number_of_chars)
 +      (load_overlay_strings, get_overlay_strings_1)
 +      (get_overlay_strings, forward_to_next_line_start)
 +      (back_to_previous_visible_line_start, reseat, reseat_to_string)
 +      (get_next_display_element, next_element_from_string)
 +      (next_element_from_c_string, next_element_from_buffer)
 +      (move_it_vertically_backward, move_it_by_lines, add_to_log)
 +      (message_dolog, message_log_check_duplicate, message2_nolog)
 +      (message3, message3_nolog, vmessage, set_message, set_message_1)
 +      (hscroll_window_tree, text_outside_line_unchanged_p)
 +      (set_cursor_from_row, set_vertical_scroll_bar, redisplay_window)
 +      (find_last_unchanged_at_beg_row)
 +      (find_first_unchanged_at_end_row, row_containing_pos)
 +      (trailing_whitespace_p, display_mode_element, decode_mode_spec)
 +      (display_count_lines, x_produce_glyphs, note_mouse_highlight): Use
 +      EMACS_INT for buffer and string positions.
 +
 +      * dispextern.h (struct it) <string_nchars>: Declare EMACS_INT.
 +      (row_containing_pos): Adjust prototype.
 +
 +      * lisp.h (pos_visible_p, message2, message2_nolog, message3)
 +      (message2_nolog, set_message): Adjust prototypes.
 +
 +2010-09-28  Stefan Monnier  <monnier@iro.umontreal.ca>
 +
 +      * gnutls.c (Fgnutls_boot): Remove unused vars `data' and `srp_cred'.
 +      (Fgnutls_boot): Use SDATA.
 +      (Fgnutls_handshake): Remove unused var `max_log_level'.
 +
 +2010-09-27  Michael Albinus  <michael.albinus@gmx.de>
 +
 +      * dbusbind.c (syms_of_dbusbind): Set $DBUS_FATAL_WARNINGS to "0".
 +      (Bug#7113)
 +
 +2010-09-27  Jan Djärv  <jan.h.d@swipnet.se>
 +
 +      * xgselect.c (xg_select): Clear file descriptors not set from
 +      rfds and wfds.
 +
 +      * process.c (wait_reading_process_output): Add missing FD_CLR
 +      for write_mask (must mirror connect_wait_mask).
 +
 +2010-09-27  Teodor Zlatanov  <tzz@lifelogs.com>
 +
 +      * gnutls.c (gnutls_log_function): Show level and "gnutls.c"
 +      prefix.
 +      (Fgnutls_boot): Use changed process members.  Use log level with a
 +      function parameter to set it.  Bring back Emacs-level debugging
 +      messages at log level 1 and 2.
 +
 +      * process.c (make_process): Initialize gnutls_log_level.
 +
 +      * process.h: Add gnutls_log_level and rename x509_cred and
 +      anon_cred to have the gnutls_ prefix for consistency.
 +
 +      * gnutls.h (GNUTLS_LOG): Add convenience macro.
 +
 +2010-09-27  Juanma Barranquero  <lekktu@gmail.com>
 +
 +      * w32.c (g_b_init_get_sid_identifier_authority)
 +      (GetSidIdentifierAuthority_Proc, get_sid_identifier_authority):
 +      Remove, not used.
 +      (globals_of_w32): Don't set g_b_init_get_sid_identifier_authority.
 +      (init_winsock): Remove useless assignment.
 +      (open_process_token, get_token_information, lookup_account_sid)
 +      (get_sid_sub_authority, get_sid_sub_authority_count, get_file_security)
 +      (get_security_descriptor_owner, get_security_descriptor_group)
 +      (is_valid_sid, equal_sid, get_length_sid, copy_sid)
 +      (get_native_system_info, get_system_times, init_user_info, crlf_to_lf)
 +      (is_unc_volume, GetCachedVolumeInformation, get_volume_info)
 +      (is_fat_volume, open_unc_volume, read_unc_volume, close_unc_volume)
 +      (unc_volume_file_attributes, convert_from_time_t)
 +      (create_toolhelp32_snapshot, process32_first, process32_next)
 +      (open_thread_token, impersonate_self, revert_to_self)
 +      (get_process_memory_info, get_process_working_set_size)
 +      (global_memory_status, global_memory_status_ex, socket_to_fd)
 +      (shutdown_handler): Make static.
 +
 +2010-09-27  Michael Albinus  <michael.albinus@gmx.de>
 +
 +      * dbusbind.c (dbus_fd_cb, xd_get_dispatch_status)
 +      (xd_pending_messages): Functions removed.
 +      (xd_read_queued_messages): Add parameters fd, *data, for_read in
 +      order to be compatible with add_read_fd.  Determine bus from data,
 +      and call xd_read_message just for this bus.
 +      (xd_add_watch): Use xd_read_queued_messages as callback function.
 +      Add data.
 +
 +      * lisp.h (xd_pending_messages, xd_read_queued_messages): Remove.
 +
 +2010-09-27  Lars Magne Ingebrigtsen  <larsi@gnus.org>
 +
 +      * gnutls.c (gnutls_log_function): Added more debugging.
 +      (emacs_gnutls_read): Don't infloop while reading.
 +
 +2010-09-27  Kenichi Handa  <handa@m17n.org>
 +
 +      These changes are to remove restriction on the number of glyphs in
 +      one composition.
 +
 +      * dispextern.h (struct glyph): Change the member "slice" to union.
 +      Remove u.cmp.from and u.cmp.to.  Give more bits to u.cmp.id.
 +      (GLYPH_SLICE_EQUAL_P): Adjusted for the above change.
 +
 +      * dispnew.c (buffer_posn_from_coords): Use glyph->slice.img
 +      instead of glyph->slice.
 +      (marginal_area_string): Likewise.
 +
 +      * term.c (encode_terminal_code): Use glyph->slice.cmp instead of
 +      glyph->u.cmp.
 +      (append_composite_glyph): Likewise.
 +
 +      * xdisp.c (dump_glyph): Use glyph->slice.cmp instead of
 +      glyph->u.cmp.
 +      (fill_gstring_glyph_string, x_get_glyph_overhangs)
 +      (append_composite_glyph): Likewise.
 +      (fill_image_glyph_string): Use glyph->slice.img instead of
 +      glyph->slice.
 +      (append_glyph, produce_image_glyph, append_stretch_glyph)
 +      (note_mouse_highlight): Likewise.
 +
 +2010-09-26  Jan Djärv  <jan.h.d@swipnet.se>
 +
 +      * process.c (add_keyboard_wait_descriptor)
 +      (delete_keyboard_wait_descriptor): Reinstate ifdef subprocesses.
 +      (wait_reading_process_output): Don't pass write_mask to select
 +      if SELECT_CANT_DO_WRITE_MASK is defined.
 +      (SELECT_CANT_DO_WRITE_MASK): Define if SELECT_CANT_DO_WRITE_MASK.
 +
 +      * process.h (add_read_fd, delete_read_fd, add_write_fd)
 +      (delete_write_fd): Declare.
 +
 +      * process.c (gpm_wait_mask, max_gpm_desc): Remove.
 +      (write_mask): New variable.
 +      (max_input_desc): Renamed from max_keyboard_desc.
 +      (fd_callback_info): New variable.
 +      (add_read_fd, delete_read_fd, add_write_fd, delete_write_fd):
 +      New functions.
 +      (Fmake_network_process): FD_SET write_mask.
 +      (deactivate_process): FD_CLR write_mask.
 +      (wait_reading_process_output): Connecting renamed to Writeok.
 +      check_connect removed.  check_write is new.  Remove references to gpm.
 +      Use Writeok/check_write unconditionally (i.e. no #ifdef
 +      NON_BLOCKING_CONNECT) instead of Connecting.
 +      Loop over file descriptors and call callbacks in fd_callback_info
 +      if file descriptor is ready for I/O.
 +      (add_gpm_wait_descriptor): Just call add_keyboard_wait_descriptor.
 +      (delete_gpm_wait_descriptor): Just call delete_keyboard_wait_descriptor.
 +      (keyboard_bit_set): Use max_input_desc.
 +      (add_keyboard_wait_descriptor, delete_keyboard_wait_descriptor):
 +      Remove #ifdef subprocesses.  Use max_input_desc.
 +      (init_process): Initialize write_mask and fd_callback_info.
 +
 +      * keyboard.c (readable_events, gobble_input): Remove DBUS code.
 +
 +      * dbusbind.c: Include process.h.
 +      (dbus_fd_cb, xd_find_watch_fd, xd_toggle_watch)
 +      (xd_read_message_1): New functions.
 +      (xd_add_watch, xd_remove_watch): Call xd_find_watch_fd.
 +      Handle watch for both read and write.
 +      (Fdbus_init_bus): Also register xd_toggle_watch.
 +      (Fdbus_call_method_asynchronously, Fdbus_method_return_internal)
 +      (Fdbus_method_error_internal, Fdbus_send_signal): Remove call
 +      to dbus_connection_flush.
 +      (xd_read_message): Move most of the code to xd_read_message_1.
 +      Call xd_read_message_1 until status is COMPLETE.
 +
 +2010-09-26  Dan Nicolaescu  <dann@ics.uci.edu>
 +
 +      * term.c: Do not include sys/ioctl.h, not needed.
 +      (init_tty): Reorder code to reduce the number of #ifdefs.
 +      No code changes.
 +
 +2010-09-26  Teodor Zlatanov  <tzz@lifelogs.com>
 +
 +      * process.h: Set up GnuTLS support.
 +
 +      * process.c (make_process, Fstart_process)
 +      (read_process_output, send_process): Set up GnuTLS support for
 +      process input/output file descriptors.
 +
 +      * gnutls.h: The GnuTLS glue for Emacs, macros and enums.
 +
 +      * gnutls.c: The source code for GnuTLS support in Emacs.
 +
 +      * emacs.c: Set up GnuTLS support and call syms_of_gnutls.
 +
 +      * config.in: Set up GnuTLS support.
 +
 +      * Makefile.in (LIBGNUTLS_LIBS, LIBGNUTLS_CFLAGS, ALL_CFLAGS)
 +      (obj, LIBES): Set up GnuTLS support.
 +
 +2010-09-26  Juanma Barranquero  <lekktu@gmail.com>
 +
 +      * w32.c (get_emacs_configuration_options): Fix previous change.
 +
 +2010-09-25  Chong Yidong  <cyd@stupidchicken.com>
 +
 +      * insdel.c (prepare_to_modify_buffer): Ensure the mark marker is
 +      alive before using it (Bug#6977).
 +
 +2010-09-25  Lars Magne Ingebrigtsen  <larsi@gnus.org>
 +
 +      * xdisp.c (face_before_or_after_it_pos): EMACS_INT/int fixup.
 +
 +      * dispextern.h: EMACS_INT/int fixup.
  
 -      * xdisp.c (mouse_face_from_buffer_pos): Support mouse highlight in
 -      bidi-reordered L2R lines.  Continued lines are not yet supported.
 +      * xdisp.c (string_pos_nchars_ahead, init_iterator): EMACS_INT/int
 +      fixup.
 +
 +      * xrdb.c (magic_file_p): EMACS_INT/int fixup.
 +
 +2010-09-25  Eli Zaretskii  <eliz@gnu.org>
 +
 +      * window.c (Fpos_visible_in_window_p, Fdelete_other_windows)
 +      (Fselect_window, window_scroll_pixel_based)
 +      (window_scroll_line_based, Frecenter, Fset_window_configuration):
 +      Use EMACS_INT for buffer positions.
 +
 +      * textprop.c (validate_interval_range, interval_of)
 +      (property_change_between_p, Fadd_text_properties)
 +      (set_text_properties_1, Fremove_text_properties)
 +      (Fremove_list_of_text_properties, Ftext_property_any)
 +      (Ftext_property_not_all, copy_text_properties)
 +      (text_property_list, extend_property_ranges)
 +      (verify_interval_modification): Use EMACS_INT for buffer
 +      positions.
 +
 +      * term.c (fast_find_position, term_mouse_highlight): Use EMACS_INT
 +      for buffer positions.
 +
 +      * process.c (read_process_output, send_process)
 +      (Fprocess_send_region, status_notify): Use EMACS_INT for buffer
 +      and string positions and size.
 +
 +      * print.c (print_object, print_string, strout): Use EMACS_INT for
 +      string indices.
 +
 +      * minibuf.c (string_to_object): Use EMACS_INT for string position
 +      and size.
 +
 +      * marker.c (verify_bytepos): Use EMACS_INT for buffer positions.
 +
 +      * lread.c <read_from_string_index, read_from_string_index_byte>
 +      <read_from_string_limit, readchar_count>: Define EMACS_INT.
 +      (readchar, unreadchar, read_internal_start): Use EMACS_INT for
 +      buffer positions and string length.
 +
 +      * keyboard.c <last_point_position, last_non_minibuf_size>: Declare
 +      EMACS_INT.
 +      (echo_truncate, adjust_point_for_property, read_char)
 +      (gen_help_event, make_lispy_event, modify_event_symbol)
 +      (Fexecute_extended_command, stuff_buffered_input): Use EMACS_INT
 +      for buffer positions and string length.
 +
 +      * keyboard.h (gen_help_event): Adjust prototype.
 +
 +      * termhooks.h <struct input_event>: Make `code' member EMACS_INT.
 +
 +      * commands.h <last_point_position>: Declare EMACS_INT.
 +
 +      * xdisp.c <help_echo_pos>: Define as EMACS_INT.
 +      (truncate_echo_area): Accept EMACS_INT argument.
 +
 +      * dispextern.h <help_echo_pos>: Declare EMACS_INT.
 +
 +      * lisp.h (truncate_echo_area): Adjust prototype.
 +
 +      * composite.c (composition_adjust_point): Return EMACS_INT.
 +
 +      * composite.h (composition_adjust_point): Adjust prototype.
 +
 +2010-09-25  Juanma Barranquero  <lekktu@gmail.com>
 +
 +      * process.c (Fmake_network_process): When arg :host is 'local,
 +      use address 127.0.0.1, not name "localhost".  (Bug#6781)
 +
 +2010-09-24  Eli Zaretskii  <eliz@gnu.org>
 +
 +      * indent.c (Fcurrent_indentation, indented_beyond_p)
 +      (compute_motion): Use EMACS_INT for buffer position variables.
 +
 +      * lisp.h (indented_beyond_p): Adjust prototype.
 +
 +      * buffer.c (overlay_strings): Return EMACS_INT.
 +
 +      * buffer.h (overlay_strings): Adjust prototype.
 +
 +      * region-cache.c (pp_cache): Adjust format to arguments.
 +
 +      * eval.c <specpdl_size, lisp_eval_depth>: Declare EMACS_INT.
 +      (call_debugger): Use EMACS_INT for specpdl_size related variables.
 +      (verror): Use EMACS_INT for size of allocated buffer.
 +
 +      * keyboard.c (make_lispy_position): Use EMACS_INT for buffer
 +      positions.
 +
 +      * xdisp.c (redisplay_internal, try_window_id)
 +      (set_cursor_from_row, find_first_unchanged_at_end_row): Use
 +      EMACS_INT for buffer positions.
 +
 +      * dispextern.h (set_cursor_from_row): Adjust prototype.
 +
 +      * dispnew.c (increment_matrix_positions)
 +      (increment_row_positions, copy_glyph_row_contents)
 +      (mode_line_string, marginal_area_string): Use EMACS_INT for buffer
 +      positions.
 +
 +      * dispextern.h (mode_line_string, marginal_area_string)
 +      (increment_matrix_positions, increment_row_positions): Adjust
 +      prototypes.
 +
 +      * data.c (Faref, Faset): Use EMACS_INT for string length and
 +      positions.
 +
 +      * cmds.c (internal_self_insert): Use EMACS_INT for the count of
 +      characters to insert.
 +
 +      * ccl.c (Fccl_execute_on_string): Use EMACS_INT for string
 +      position and size.
 +
 +      * syntax.c (scan_words, update_syntax_table)
 +      (prev_char_comend_first, back_comment, skip_chars)
 +      (skip_syntaxes, Fforward_comment, Fbackward_prefix_chars): Use
 +      EMACS_INT for buffer and string positions.
 +
 +      * syntax.h (scan_words, update_syntax_table): Adjust prototypes.
 +
 +      * casefiddle.c (operate_on_word): Use EMACS_INT for buffer
 +      positions.
 +
 +2010-09-24  Lars Magne Ingebrigtsen  <larsi@gnus.org>
 +
 +      * scroll.c (calculate_scrolling, line_ins_del)
 +      (calculate_direct_scrolling, scroll_cost): Fix EMACS_INT/int
 +      conversion.
 +
 +      * region-cache.c (move_cache_gap, set_cache_region, pp_cache)
 +      (region_cache_backward, region_cache_forward)
 +      (revalidate_region_cache, set_cache_region): FIX EMACS_INT/int
 +      conversion.
 +
 +      * xdisp.c (message_dolog): Fix EMACS_INT/int conversion.
 +
 +      * eval.c (verror): Fix EMACS_INT/int conversion.
 +
 +      * print.c (PRINTDECLARE, PRINTPREPARE, strout, print_string)
 +      (print_preprocess, print_check_string_charset_prop)
 +      (print_object): Fix EMACS_INT/int conversion.
 +
 +      * xdisp.c (message_dolog): Fix EMACS_INT/int conversion.
 +
 +2010-09-24  Eli Zaretskii  <eliz@gnu.org>
 +
 +      * callproc.c (Fcall_process): Use EMACS_INT for count of
 +      characters read from the subprocess.
 +
 +      * bidi.c (struct bidi_paragraph_info): Use EMACS_INT for buffer
 +      positions.
 +      (bidi_cache_search, bidi_cache_find): Use EMACS_INT for buffer
 +      positions.
 +
 +      * buffer.c (struct sortvec): Use EMACS_INT for buffer positions.
 +      (struct sortstrlist, overlay_str_len): Use EMACS_INT for string
 +      length.
 +      (advance_to_char_boundary, Fset_buffer_multibyte)
 +      (overlays_at, overlays_in, mouse_face_overlay_overlaps)
 +      (overlay_touches_p, record_overlay_string, overlay_strings)
 +      (recenter_overlay_lists, fix_start_end_in_overlays)
 +      (modify_overlay, Fmove_overlay, report_overlay_modification)
 +      (evaporate_overlays): Use EMACS_INT for buffer positions.
 +
 +      * lisp.h (fix_start_end_in_overlays, overlay_touches_p): Adjust
 +      prototypes.
 +
 +      * dispextern.h (struct bidi_saved_info): Use EMACS_INT for buffer
 +      positions.
 +
 +      * fns.c (Fcompare_strings, Fstring_lessp, concat)
 +      (string_make_unibyte, Fstring_as_unibyte, Fsubstring)
 +      (Fsubstring_no_properties, substring_both, Ffillarray)
 +      (Fclear_string, mapcar1, Fmapconcat, Fmapcar, Fmapc)
 +      (Fbase64_encode_region, Fbase64_encode_string, base64_encode_1)
 +      (Fbase64_decode_region, Fbase64_decode_string, base64_decode_1)
 +      (Fmd5): Use EMACS_INT for buffer and string positions and length
 +      variables and arguments.
 +
 +      * lisp.h (substring_both): Adjust prototype.
 +
 +2010-09-24  Juanma Barranquero  <lekktu@gmail.com>
 +
 +      Remove W32 API function pointer unused since 2005-02-15 (revno 2005-02-15T23:19:26Z!jasonr@gnu.org).
 +      * w32fns.c (clipboard_sequence_fn): Don't declare.
 +      (globals_of_w32fns): Don't initialize it.
 +
 +2010-09-23  Stefan Monnier  <monnier@iro.umontreal.ca>
 +
 +      * syntax.c (back_comment): Detect the case where a 1-char comment
 +      starter is also the 2nd char of a 2-char comment ender.
 +
 +2010-09-23  Jan Djärv  <jan.h.d@swipnet.se>
 +
 +      * gtkutil.c (xg_tool_bar_menu_proxy): Set gtk-menu-items to TRUE.
 +
 +2010-09-23  Lars Magne Ingebrigtsen  <larsi@gnus.org>
 +
 +      * eval.c (verror): EMACS_INT/int cleanup.
 +
 +      * lisp.h (SPECPDL_INDEX): Cast to int, since we're not going to
 +      unwind_protect more than 2GB worth of functions.
 +
 +      * editfns.c (Finsert_char): EMACS_INT/int cleanup.
 +
 +      * lisp.h: Have oblookup take EMACS_INT to allow interning big
 +      string and avoid compiler warnings.
 +      (USE_SAFE_ALLOCA): Cast to int to avoid compilation warnings in
 +      all users.
 +
 +      * lread.c (oblookup): EMACS_INT/int cleanup.
 +
 +      * cmds.c (Fforward_line, Fdelete_char): EMACS_INT/int cleanup.
 +
 +2010-09-23  Eli Zaretskii  <eliz@gnu.org>
 +
 +      * editfns.c (clip_to_bounds): Return an EMACS_INT value.
 +
 +      * lisp.h (clip_to_bounds): Adjust prototype.
 +
 +      * intervals.c (adjust_for_invis_intang): Return EMACS_INT value.
 +
 +2010-09-23  Lars Magne Ingebrigtsen  <larsi@gnus.org>
 +
 +      * lisp.h: doprnt.c EMACS_INT/int cleanup.
 +
 +      * doprnt.c (doprnt): EMACS_INT/int cleanup.
 +
 +      * doc.c (Fsnarf_documentation, get_doc_string): EMACS_INT/int
 +      cleanup.
 +
 +      * lisp.h: Change the definition of all marker.c functions that
 +      take and return buffer stuff to be EMACS_INT instead of int.
 +
 +      * marker.c (buf_charpos_to_bytepos, CONSIDER, set_marker_both)
 +      (buf_charpos_to_bytepos, bytepos_to_charpos)
 +      (buf_bytepos_to_charpos, Fbuffer_has_markers_at)
 +      (set_marker_restricted, set_marker_both): Convert int to EMACS_INT
 +      for all buffer positions.
 +
 +2010-09-23  Chong Yidong  <cyd@stupidchicken.com>
 +
 +      * intervals.c (traverse_intervals, rotate_right, rotate_left)
 +      (split_interval_right, find_interval, next_interval)
 +      (delete_node, delete_interval, interval_deletion_adjustment)
 +      (adjust_intervals_for_deletion, merge_interval_right)
 +      (merge_interval_left, graft_intervals_into_buffer)
 +      (copy_intervals): Convert EMACS_UINTs to EMACS_INT.
 +
 +      * intervals.h (traverse_intervals): Update prototype.
 +
 +2010-09-23  Eli Zaretskii  <eliz@gnu.org>
 +
 +      * indent.c (compute_motion): Use EMACS_INT for arguments to
 +      region_cache_forward.
 +
 +      * region-cache.c (struct boundary, struct region_cache): Use
 +      EMACS_INT for positions.
 +      (find_cache_boundary, move_cache_gap, insert_cache_boundary)
 +      (delete_cache_boundaries, set_cache_region)
 +      (invalidate_region_cache, know_region_cache)
 +      (region_cache_forward, region_cache_backward, pp_cache): Use
 +      EMACS_INT for buffer positions.
 +
 +      * region-cache.h (know_region_cache, invalidate_region_cache)
 +      (region_cache_forward, region_cache_backward): Adjust prototypes.
 +
 +      * search.c (string_match_1, fast_c_string_match_ignore_case)
 +      (looking_at_1, scan_buffer, scan_newline)
 +      (find_next_newline_no_quit, find_before_next_newline)
 +      (search_command, trivial_regexp_p, search_buffer, simple_search)
 +      (boyer_moore, wordify, Freplace_match): Use EMACS_INT for buffer
 +      and string positions and length.
 +
 +      * lisp.h (scan_buffer, scan_newline, find_next_newline_no_quit)
 +      (find_before_next_newline): Adjust prototypes.
 +
 +      * editfns.c (transpose_markers, update_buffer_properties)
 +      (buildmark, clip_to_bounds, Fgoto_char, overlays_around)
 +      (get_pos_property, Fconstrain_to_field)
 +      (Fline_beginning_position, Fline_end_position, Fprevious_char)
 +      (Fchar_after, Fchar_before, Finsert_char)
 +      (Finsert_buffer_substring, Fcompare_buffer_substrings)
 +      (Fsubst_char_in_region, Fformat, Ftranspose_regions): Use
 +      EMACS_INT for buffer and string position variables.
 +      (Finsert_char): Protect against too large insertions.
 +
 +      * lisp.h (clip_to_bounds): Adjust prototype.
 +
 +      * intervals.c (traverse_intervals, rotate_right, rotate_left)
 +      (balance_an_interval, split_interval_right, split_interval_left)
 +      (find_interval, next_interval, update_interval)
 +      (adjust_intervals_for_insertion, delete_node, delete_interval)
 +      (interval_deletion_adjustment, adjust_intervals_for_deletion)
 +      (offset_intervals, merge_interval_right, merge_interval_left)
 +      (graft_intervals_into_buffer, adjust_for_invis_intang)
 +      (move_if_not_intangible, get_local_map, copy_intervals)
 +      (copy_intervals_to_string, compare_string_intervals)
 +      (set_intervals_multibyte_1): Use EMACS_INT for buffer positions
 +      and for interval tree size.
 +
 +      * intervals.h (traverse_intervals, split_interval_right)
 +      (split_interval_left, find_interval, offset_intervals)
 +      (graft_intervals_into_buffer, copy_intervals)
 +      (copy_intervals_to_string, move_if_not_intangible, get_local_map)
 +      (update_interval): Adjust prototypes.
 +
 +      * xdisp.c (check_point_in_composition, reconsider_clip_changes):
 +      Use EMACS_INT for buffer position variables and arguments.
 +
 +      * composite.c (get_composition_id, find_composition)
 +      (run_composition_function, compose_text)
 +      (composition_gstring_width, autocmp_chars)
 +      (composition_update_it, Ffind_composition_internal): Use EMACS_INT
 +      for buffer positions and string length variables and arguments.
 +
 +      * composite.h (get_composition_id, find_composition, compose_text)
 +      (composition_gstring_width): Adjust prototypes.
 +
 +      * editfns.c (Fformat): Use EMACS_INT for string size variables.
 +
 +      * xdisp.c (store_mode_line_noprop, display_mode_element): Use
 +      EMACS_INT for string positions.
 +
 +      * intervals.c (get_property_and_range): Use EMACS_INT for buffer
 +      position arguments.
 +
 +      * intervals.h (get_property_and_range): Adjust prototype.
 +
 +      * character.c (parse_str_as_multibyte, str_as_multibyte)
 +      (parse_str_to_multibyte, str_to_multibyte, str_as_unibyte)
 +      (string_count_byte8, string_escape_byte8, c_string_width)
 +      (strwidth, lisp_string_width, multibyte_chars_in_text): Use
 +      EMACS_INT for string length variables and arguments.
 +
 +      * character.h (parse_str_as_multibyte, str_as_multibyte)
 +      (parse_str_to_multibyte, str_to_multibyte, str_as_unibyte)
 +      (c_string_width, strwidth, lisp_string_width): Adjust
 +      prototypes.
 +
 +      * font.c (font_intern_prop): Use EMACS_INT for string length
 +      variables.
 +
 +      * font.c (font_intern_prop): Use EMACS_INT for string length
 +      variables.
 +
 +      * fns.c (Fstring_as_multibyte): Use EMACS_INT for string length
 +      variables.
 +
 +      * alloc.c <total_string_size>: Declare as EMACS_INT, not int.
 +      (Fmake_string): Protect against too large strings.
 +      (live_string_p, live_cons_p, live_symbol_p, live_float_p)
 +      (live_misc_p): Use ptrdiff_t instead of int for pointer
 +      differences.
 +      (string_bytes, check_sblock, check_string_free_list)
 +      (allocate_string_data, compact_small_strings, Fmake_string)
 +      (Fmake_bool_vector, make_string, make_unibyte_string)
 +      (make_multibyte_string, make_string_from_bytes)
 +      (make_specified_string_string, Fmake_list, Fmake_vector): Use
 +      EMACS_INT for string length variables and arguments.
 +      (find_string_data_in_pure, make_pure_string, make_pure_c_string)
 +      (Fpurecopy): Use EMACS_INT for string size.
 +      (mark_vectorlike, mark_char_table, mark_object): Use EMACS_UINT
 +      for vector size.
 +
 +      * lisp.h (make_string, make_unibyte_string, make_multibyte_string)
 +      (make_string_from_bytes, make_specified_string_string)
 +      (make_pure_string, string_bytes, check_point_in_composition):
 +      Adjust prototypes.
 +
 +2010-09-22  Eli Zaretskii  <eliz@gnu.org>
 +
 +      * editfns.c (Fsubst_char_in_region, Ftranslate_region_internal)
 +      (check_translation): Use EMACS_INT for buffer positions and
 +      length.
 +
 +      * undo.c (record_marker_adjustment, record_delete)
 +      (record_change, record_point, record_insert)
 +      (record_property_change, Fprimitive_undo): Use EMACS_INT for
 +      buffer positions.
 +
 +      * lisp.h (record_marker_adjustment, record_delete)
 +      (record_change, record_point, record_insert)
 +      (record_property_change, Fprimitive_undo): Adjust prototypes.
 +
 +2010-09-22  Juanma Barranquero  <lekktu@gmail.com>
 +            Eli Zaretskii  <eliz@gnu.org>
 +
 +      * w32.c (get_emacs_configuration_options): Fix buffer overrun.
 +
 +2010-09-22  Eli Zaretskii  <eliz@gnu.org>
 +
 +      * minibuf.c (Fminibuffer_contents)
 +      (Fminibuffer_contents_no_properties)
 +      (Fminibuffer_completion_contents): Use EMACS_INT for minibuffer
 +      positions.
 +
 +      * keyboard.c (command_loop_1): Use EMACS_INT to compare point with
 +      mark.
 +
 +      * alloc.c (make_uninit_string, make_uninit_multibyte_string)
 +      (allocate_string_data): Accept EMACS_INT for string length.
 +
 +      * editfns.c (Ffield_string, Ffield_string_no_properties)
 +      (make_buffer_string, make_buffer_string_both, Fbuffer_substring)
 +      (Fbuffer_substring_no_properties, find_field, Fdelete_field)
 +      (Ffield_string, Ffield_string_no_properties, Ffield_beginning)
 +      (Ffield_end): Use EMACS_INT for buffer positions.
 +
 +      * insdel.c (prepare_to_modify_buffer): Use EMACS_INT to compare
 +      point with mark.
 +
 +      * lisp.h (allocate_string_data, make_uninit_string)
 +      (make_uninit_multibyte_string, make_buffer_string)
 +      (make_buffer_string_both): Adjust prototypes.
 +
 +2010-09-22  Chong Yidong  <cyd@stupidchicken.com>
 +
 +      * xml.c: Switch to GNU indentation.
 +      (make_dom): Change parse tree format to match xml.el.
 +      (Fxml_parse_html_string_internal): Rename from html-parse-string.
 +      (Fxml_parse_string_internal): Rename from xml-parse-string.
 +
 +2010-09-22  Kenichi Handa  <handa@m17n.org>
 +
 +      * xdisp.c (compute_stop_pos): Call composition_compute_stop_pos
 +      only if we are not at a composition.
 +      (set_iterator_to_next): Give it->end_charpos to
 +      composition_compute_stop_pos.
 +      (set_iterator_to_next, next_element_from_buffer): Likewise.
 +
 +      * dispnew.c (buffer_posn_from_coords): Fix position when the
 +      current display element is a grapheme cluster in bidi-reordered
 +      region.
 +
 +2010-09-21  Ari Roponen  <ari.roponen@gmail.com>  (tiny change)
 +
 +      * doc.c (Fsnarf_documentation): Use memmove instead of memcpy as
 +      the regions may overlap.
 +
 +2010-09-21  Juanma Barranquero  <lekktu@gmail.com>
 +
 +      * makefile.w32-in ($(BLD)/sysdep.$(O)): Update dependencies.
 +
 +2010-09-21  Dan Nicolaescu  <dann@ics.uci.edu>
 +
 +      * emacs.c: Do not include sys/ioctl.h, not needed.
 +
 +      * doprnt.c: Do not include stdlib.h, config.h does it.
 +      Move #include before macro definition.
 +
 +2010-09-20  Dan Nicolaescu  <dann@ics.uci.edu>
 +
 +      * Makefile.in (temacs): Link using $(CC) not $(LD).
 +      (LD_FIRSTFLAG): Define using autoconf.
 +      (LD): Remove.
 +
 +      Remove HAVE_TERMIOS definitions.
 +      * s/usg5-4-common.h (HAVE_TERMIOS):
 +      * s/template.h (HAVE_TERMIOS):
 +      * s/gnu-linux.h (HAVE_TERMIOS):
 +      * s/darwin.h (HAVE_TERMIOS):
 +      * s/cygwin.h (HAVE_TERMIOS):
 +      * s/bsd-common.h (HAVE_TERMIOS):
 +      * s/aix4-2.h (HAVE_TERMIOS):
 +      * s/hpux10-20.h (HAVE_TERMIOS): Do not define, it is assumed
 +      defined on all non-MS platforms.
 +      (HAVE_PSTAT_GETDYNAMIC): Do not define, autoconf does it.
 +
 +      * xterm.c (xt_action_hook): Use const.
 +
 +2010-09-20  Juanma Barranquero  <lekktu@gmail.com>
 +
 +      Don't make W32 code conditional on HAVE_SOCKETS, it's always defined.
 +      * w32.c: Remove top-level uses of #ifdef HAVE_SOCKETS.
 +      (gethostname) [!HAVE_SOCKETS]: Remove.
 +      (SOCK_REPLACE_HANDLE): Remove macro.
 +      (socket_to_fd, sys_close, _sys_read_ahead, sys_read, sys_write)
 +      (term_ntproc, init_ntproc): Don't conditionalize on HAVE_SOCKETS.
 +      * w32proc.c: Remove top-level uses of #ifdef HAVE_SOCKETS.
 +      (syms_of_ntproc): Don't conditionalize on HAVE_SOCKETS.
 +
 +2010-09-18  Eli Zaretskii  <eliz@gnu.org>
 +
 +      * deps.mk (xml.o): Add dependencies.
 +
 +      * xdisp.c (Fcurrent_bidi_paragraph_direction):
 +      Call bidi_paragraph_init with NO_DEFAULT_P non-zero.  (Bug#7038)
 +
 +      * bidi.c (bidi_paragraph_init): Accept an additional argument
 +      NO_DEFAULT_P; all callers changed.  If NO_DEFAULT_P is non-zero,
 +      search back until a paragraph with a strong directional character
 +      is found, and use that to determine paragraph's base direction.
 +
 +      * dispextern.h (bidi_paragraph_init): Update prototype.
 +
 +2010-09-17  Eli Zaretskii  <eliz@gnu.org>
 +
 +      * w32.c (_PROCESS_MEMORY_COUNTERS_EX): Don't define with versions
 +      of w32api >= 3.15.  (Bug#6989)
 +
 +2010-09-17  Lars Magne Ingebrigtsen  <larsi@gnus.org>
 +
 +      * process.c (wait_reading_process_output): Don't message about
 +      accept-process-output unless the time limit really is zero.
 +
 +2010-09-17  Stefan Monnier  <monnier@iro.umontreal.ca>
 +
 +      * frame.c (Ftool_bar_pixel_width): YAILOM (Yet another
 +      int/Lisp_Object mixup).
 +
 +2010-09-17  Jan Djärv  <jan.h.d@swipnet.se>
 +
 +      * keyboard.c (parse_tool_bar_item): For QClabel, set TOOL_BAR_ITEM_LABEL
 +      not HELP.
 +
 +2010-09-17  Stephen Berman  <stephen.berman@gmx.net>
 +
 +      * frame.c (Ftool_bar_pixel_width): New function to expose tool
 +      bar's pixel width to Lisp (Bug#7048).
 +
 +2010-09-14  Juanma Barranquero  <lekktu@gmail.com>
 +
 +      * cmds.c (syms_of_cmds) <post-self-insert-hook>: Fix typos in docstring.
 +
 +2010-09-17  Jan Djärv  <jan.h.d@swipnet.se>
 +
 +      * gtkutil.c (xg_pack_tool_bar): Call gtk_handle_box_set_handle_position
 +      with argument top/left if tool bar is vertical/horizontal (Bug#7051).
 +
 +2010-09-17  Kenichi Handa  <handa@m17n.org>
 +
 +      * ftfont.c (ftfont_check_otf): Fix previous change.
 +
 +2010-09-14  Kenichi Handa  <handa@m17n.org>
 +
 +      * ftfont.c (ftfont_check_otf): Fix the case of checking just
 +      existence of GSUB or GPOS.
 +
 +2010-09-14  Juanma Barranquero  <lekktu@gmail.com>
 +
 +      * cmds.c (syms_of_cmds) <post-self-insert-hook>: Fix typos in docstring.
 +
 +2010-09-14  Lars Magne Ingebrigtsen  <larsi@gnus.org>
 +
 +      * xml.c (parse_buffer): Renamed to parse_string(), since that's
 +      what it does.
 +      (parse_string): Return nil when the document can't be parsed.
 +
 +2010-09-14  Jan Djärv  <jan.h.d@swipnet.se>
 +
 +      * xterm.c (get_current_vm_state): New function.
 +      (do_ewmh_fullscreen): Call get_current_vm_state and compare with
 +      want_fullscreen so set_wm_state calls are few (Bug#7013).
 +      (x_handle_net_wm_state): Move code to get_current_vm_state and
 +      call that function.
 +
 +2010-09-14  Courtney Bane  <emacs-bugs-7626@cbane.org>  (tiny change)
 +
 +      * term.c (tty_set_terminal_modes): Don't initialize twice (bug#7002).
 +
 +2010-09-14  Kenichi Handa  <handa@m17n.org>
 +
 +      * coding.c (encode_coding_iso_2022): Don't optimize for ASCII if
 +      we may use designation or locking-shift.
 +
 +2010-09-14  Kenichi Handa  <handa@m17n.org>
 +
 +      * coding.c (detect_coding_emacs_mule): Fix checking of multibyte
 +      sequence when the source is multibyte.
 +
 +2010-09-14  Andreas Schwab  <schwab@linux-m68k.org>
 +
 +      * xml.c (Fxml_parse_string, Fxml_parse_string): Revert last change.
 +      Don't make first argument optional.  Doc fix.
 +
 +2010-09-14  Leo  <sdl.web@gmail.com>  (tiny change)
 +
 +      * xml.c (Fxml_parse_string, Fhtml_parse_string): Fix up the
 +      parameters for the doc string.
 +
 +2010-09-12  Lars Magne Ingebrigtsen  <larsi@gnus.org>
 +
 +      * xml.c (Fhtml_parse_string, Fxml_parse_string): Mention BASE-URL.
 +
 +2010-09-12  Stefan Monnier  <monnier@iro.umontreal.ca>
 +
 +      * fns.c (Fy_or_n_p): Move to lisp/subr.el.
 +      (syms_of_fns): Don't defsubr Sy_or_n_p.
 +      * lisp.h: Don't declare Fy_or_n_p.
 +      * fileio.c (barf_or_query_if_file_exists): Fy_or_n_p -> y-or-n-p.
 +
 +2010-09-09  Lars Magne Ingebrigtsen  <larsi@gnus.org>
 +
 +      * xml.c (Fxml_parse_buffer): New function to parse XML files.
 +
 +2010-09-08  Lars Magne Ingebrigtsen  <larsi@gnus.org>
 +
 +      * xml.c: New file.
 +      (Fhtml_parse_buffer): New function to interface to the libxml2
 +      html parsing function.
 +
 +2010-09-05  Juanma Barranquero  <lekktu@gmail.com>
 +
 +      * biditype.h: Regenerate.
 +
 +2010-09-04  Andreas Schwab  <schwab@linux-m68k.org>
 +
 +      * nsimage.m (ns_load_image): Check argument types.
 +
 +      * image.c: Remove all uses of gcpro.
 +      (xpm_load): Check all lisp types.
 +      (pbm_load): Likewise.
 +      (png_load): Likewise.
 +      (jpeg_load): Likewise.
 +      (tiff_load): Likewise.
 +      (gif_load): Likewise.
 +      (imagemagick_load_image): Likewise.
 +      (imagemagick_load): Likewise.
 +      (svg_load): Likewise.
 +      (gs_load): Likewise.
 +
 +2010-09-04  Eli Zaretskii  <eliz@gnu.org>
 +
 +      * w32uniscribe.c (uniscribe_shape): Update commentary.  Don't
 +      try to reorder grapheme clusters, since LGSTRING should always
 +      hold them in the logical order.
 +      (uniscribe_encode_char, uniscribe_shape): Force ScriptShape to
 +      return glyph codes in the logical order.
 +
 +2010-09-04  Andreas Schwab  <schwab@linux-m68k.org>
 +
 +      * image.c (imagemagick_image_p): Replace bcopy by memcpy.
 +      (imagemagick_load_image): Fix type mismatch.
 +      (Fimagemagick_types): Likewise.  Doc fix.
 +
 +2010-09-02  Jan Djärv  <jan.h.d@swipnet.se>
 +
 +      * xterm.h (struct dpyinfo): Remove cut_buffers_initialized.
 +
 +      * xterm.c (x_term_init): Don't set dpyinfo->cut_buffers_initialized.
 +
 +      * xselect.c: Remove declaration of cut-buffer objects and functions.
 +      (symbol_to_x_atom): Remove mapping to XA_CUT_BUFFERn.
 +      (x_atom_to_symbol): Remove mapping to QCUT_BUFFERn.
 +      (Fx_get_cut_buffer_internal, Fx_store_cut_buffer_internal)
 +      (Fx_rotate_cut_buffers_internal): Remove.
 +      (syms_of_xselect): Remove defsubr of above.
 +      Remove intern of QCUT_BUFFERn.
 +
 +2010-09-01  Stefan Monnier  <monnier@iro.umontreal.ca>
 +
 +      * cmds.c (Vblink_paren_function): Remove.
 +      (internal_self_insert): Make it insert N chars at a time.
 +      Don't call blink-paren-function.
 +      (Fself_insert_command): Adjust accordingly.
 +      (syms_of_cmds): Don't declare blink-paren-function.
 +
 +2010-08-31  Kenichi Handa  <handa@m17n.org>
 +
 +      * dispextern.h (FACE_FOR_CHAR): Use an ASCII face for 8-bit
 +      characters.
 +
 +      * term.c (encode_terminal_code): Fix the previous change.
 +      (produce_glyphs): Don't set it->char_to_display here.
 +      Don't handle unibyte-display-via-language-environment here.
 +      (produce_special_glyphs): Set temp_it.char_to_display before
 +      calling produce_glyphs.
 +
 +      * xdisp.c (get_next_display_element): Set it->char_to_display
 +      here.  Convert all 8-bit bytes from unibyte buffer/string to 8-bit
 +      characters.
 +      (get_overlay_arrow_glyph_row): Set it.char_to_display too before
 +      calling PRODUCE_GLYPHS.
 +      (append_space_for_newline): Save and store it->char_to_display.
 +      Set it->char_to_display before calling PRODUCE_GLYPHS.
 +      (extend_face_to_end_of_line): Set it->char_to_display before
 +      calling PRODUCE_GLYPHS.
 +      (get_glyph_face_and_encoding): Set the glyph code an 8-bit
 +      character to its byte value.
 +      (get_char_glyph_code): New function.
 +      (produce_stretch_glyph): Set it2.char_to_display too before
 +      calling x_produce_glyphs.
 +      (x_produce_glyphs): Simplify by using the same code for ASCII and
 +      non-ASCII characters.  Don't set it->char_to_display here.
 +      Don't handle unibyte-display-via-language-environment here.  For a
 +      character of no glyph, use font->space_width instead of FONT_WIDTH.
 +
 +2010-08-31  Stefan Monnier  <monnier@iro.umontreal.ca>
 +
 +      * keyboard.c (Fwindow_system): Fix compilation for USE_LISP_UNION_TYPE.
 +
 +2010-08-31  Chong Yidong  <cyd@stupidchicken.com>
 +
 +      * keyboard.c (command_loop_1): Don't call x-set-selection on tty.
 +
 +2010-08-30  Stefan Monnier  <monnier@iro.umontreal.ca>
 +
 +      * marker.c (Fcopy_marker): Make the first arg optional.
 +
 +2010-08-30  Kenichi Handa  <handa@m17n.org>
 +
 +      * composite.c (composition_update_it): Fix computing of
 +      cmp_it->width.
 +
 +2010-08-29  Kenichi Handa  <handa@m17n.org>
 +
 +      * term.c (encode_terminal_code): Encode byte chars to the
 +      corresponding bytes.
 +
 +2010-08-29  Jan Djärv  <jan.h.d@swipnet.se>
 +
 +      * nsterm.m (ns_draw_window_cursor): Draw BAR_CURSOR correct for R2L.
 +
 +2010-08-26  Kenichi Handa  <handa@m17n.org>
 +
 +      * xdisp.c (compute_stop_pos): Pay attention to bidi scan direction
 +      on calling composition_compute_stop_pos.
 +
 +2010-08-25  Kenichi Handa  <handa@m17n.org>
 +
 +      * fontset.c (reorder_font_vector): Prefer a font-spec specifying
 +      :otf.
 +
 +      * composite.c (composition_compute_stop_pos): Don't break
 +      composition at PT.
 +      (composition_reseat_it): Likewise.  Fix calculation of character
 +      position starting a composition.
 +      (Fcomposition_get_gstring): Don't limit the number of components
 +      for automatic composition.
 +
 +2010-08-25  Kenichi Handa  <handa@m17n.org>
 +
 +      * composite.c (composition_compute_stop_pos): In forward search,
 +      pay attention to the possibility that some character after ENDPOS
 +      will be composed with charactrs before ENDPOS.
 +
 +2010-08-24  Chong Yidong  <cyd@stupidchicken.com>
 +
 +      * keyboard.c (command_loop_1): Don't clobber primary selection
 +      during handle-switch-frame (Bug#6872).
 +
 +2010-08-23  Michael Albinus  <michael.albinus@gmx.de>
 +
 +      * dbusbind.c: Accept UNIX domain sockets as bus address.
 +      (Fdbus_close_bus): New function.
 +      (Vdbus_registered_buses): New variable.
 +      (xd_initialize): Implement string as bus address.
 +      (Fdbus_init_bus): Add bus to Vdbus_registered_buses).
 +      (Fdbus_get_unique_name, Fdbus_call_method)
 +      (Fdbus_call_method_asynchronously, Fdbus_method_return_internal)
 +      (Fdbus_method_error_internal, Fdbus_send_signal)
 +      (Fdbus_register_signal, Fdbus_register_method): Remove bus type
 +      check.  This is done in xd_initialize_bus.  Adapt doc string, if
 +      necessary.
 +      (xd_pending_messages, xd_read_queued_messages): Loop over buses in
 +      Vdbus_registered_buses.
 +      (Vdbus_registered_objects_table): Create hash.
 +
 +2010-08-22  Juri Linkov  <juri@jurta.org>
 +
 +      * keyboard.c (Fexecute_extended_command): Move reading a command name
 +      with `completing-read' to a new Elisp function `read-extended-command'.
 +      Call it to read a command to `function'  (bug#5364, bug#5214).
 +
 +2010-08-22  Chong Yidong  <cyd@stupidchicken.com>
 +
 +      * emacs.c (main): Remove handling of --unibyte arg (Bug#6886).
 +
 +2010-08-22  Andreas Schwab  <schwab@linux-m68k.org>
 +
 +      * eval.c (Flet, Feval, Fapply, apply_lambda): Use SAFE_ALLOCA_LISP
 +      instead of SAFE_ALLOCA.
 +
 +2010-08-22  Chong Yidong  <cyd@stupidchicken.com>
 +
 +      * eval.c (Flet, Feval, Fapply, apply_lambda): Use SAFE_ALLOCA
 +      (Bug#6214).
 +
 +2010-08-22  Jan Djärv  <jan.h.d@swipnet.se>
 +
 +      * doc.c (Fsnarf_documentation): Set skip_file only if p[1] is S.
 +
 +2010-08-22  Jan Djärv  <jan.h.d@swipnet.se>
 +
 +      * doc.c (Fsnarf_documentation): Initialize skip_file before
 +      build-files test.
 +
 +2010-08-22  Peter O'Gorman  <pogma@thewrittenword.com>  (tiny change)
 +
 +      * s/hpux10-20.h (HAVE_TERMIOS, NO_TERMIO, ORDINARY_LINK):
 +      New definitions.
 +      (HAVE_TERMIO): Remove.
 +
 +2010-08-22  Eli Zaretskii  <eliz@gnu.org>
 +
 +      * deps.mk (sysdep.o, msdos.o): Depend on sysselect.h.
 +
 +      * sysselect.h [WINDOWSNT]: Don't define the FD_* and select stuff
 +      for w32.
 +
 +      * s/ms-w32.h (HAVE_SYS_TIMEB_H): Don't #undef HAVE_SYS_SELECT_H,
 +      it's done in nt/config.nt.
 +
 +      * makefile.w32-in ($(BLD)/sysdep.$(O)): Depend on sysselect.h.
 +
 +      * unexcoff.c (report_error, make_hdr, write_segment)
 +      (copy_text_and_data, copy_sym, mark_x, adjust_lnnoptrs, unexec):
 +      Convert argument lists and prototypes to ANSI C.
 +      (make_hdr, write_segment): Remove unused variables.
 +      (unexec): Remove commented-out line.  Initialize `new' to shut up
 +      compiler warnings.
 +
 +2010-08-22  Dan Nicolaescu  <dann@ics.uci.edu>
 +
 +      Simplify termio code.
 +      All non-MSDOS non-WINDOWSNT platforms define HAVE_TERMIOS, so
 +      HAVE_TERMIO code is obsolete.
 +      Replace HAVE_TERMIOS conditionals with !DOS_NT.
 +      * systty.h: Do not define HAVE_TCATTR.
 +      Remove HAVE_TERMIO, HAVE_LTCHARS and HAVE_TCHARS code.
 +      Do not define EMACS_HAVE_TTY_PGRP.  Only define
 +      EMACS_GET_TTY_PGRP for !DOS_NT.
 +      * sysdep.c: Include sysselect.h unconditionally.  Do not include
 +      sys/ioctl.h and termios.h, systty.h does it.  Use
 +      HAVE_SYS_UTSNAME_H instead of USG as an include guard.
 +      (init_baud_rate): Remove HAVE_TERMIO code.
 +      (child_setup_tty): Remove HAVE_TERMIO code.
 +      (emacs_get_tty, emacs_set_tty): Remove HAVE_TERMIO, HAVE_TCHARS
 +      and HAVE_LTCHARS code.  Use !DOS_NT instead of HAVE_TCATTR.
 +      (new_ltchars, new_tchars): Remove, unused.
 +      (init_sys_modes): Remove HAVE_TERMIO, HAVE_TCHARS and HAVE_LTCHARS
 +      code.  Remove special casing for __mips__, it was a no-op.  Remove
 +      HAVE_TCATTR conditional, it is implied by HAVE_TERMIOS.
 +      (init_sys_modes): Remove HPUX special case.
 +      * process.c: Include stdlib.h unconditionally.  Do not include
 +      fcntl.h, systty.h does it.  Remove conditional code for
 +      HAVE_SERIAL, it is always true.
 +      (process_send_signal): Remove HAVE_TERMIOS conditional, it's
 +      always true when SIGNALS_VIA_CHARACTERS is true.
 +      (Fcontinue_process, Fprocess_send_eof): Simplify conditionals:
 +      !WINDOWSNT means HAVE_TERMIOS.
 +      (create_process): Remove HAVE_TERMIOS, it's inside a HAVE_PTYS
 +      conditional, which is true for all HAVE_TERMIOS systems.
 +      * keyboard.c (init_keyboard): Do not use HAVE_TERMIO, use !DOS_NT
 +      instead of HAVE_TERMIOS.
 +      * emacs.c (shut_down_emacs): Use !defined DOS_NT instead of
 +      EMACS_HAVE_TTY_PGRP.
 +      * callproc.c (child_setup): Move EMACS_SET_TTY_PGRP use to the
 +      non-MSDOS, non-WINDOWSNT code, it's only defined for such systems
 +      anyway.
 +
- 2010-08-21  Eli Zaretskii  <eliz@gnu.org>
++2010-08-20  Eli Zaretskii  <eliz@gnu.org>
  
        * dispnew.c (buffer_posn_from_coords): Fix off-by-one error in
        mirroring pixel positions.
  
  2010-08-18  Jan Djärv  <jan.h.d@swipnet.se>
  
 -      * gtkutil.c (update_frame_tool_bar): Literal stings are const char*.
 +      * gtkutil.c (update_frame_tool_bar): Literal strings are const char*.
  
  2010-08-18  David De La Harpe Golden  <david@harpegolden.net>
  
        * xterm.c (emacs_class): New char[] for EMACS_CLASS.
        (xim_open_dpy, xim_initialize, xim_close_dpy): Use emacs_class.
        (x_term_init): Use char[] display_opt and name_opt instead of
 -      string literal. file is const char*.
 +      string literal.  file is const char*.
  
        * xsmfns.c (NOSPLASH_OPT): Change to char[].
        (smc_save_yourself_CB): Do xstrdup on all ->type and ->name for
        non-const char.
  
        * xmenu.c (Fx_popup_dialog): error_name is const char*.
 -      (xmenu_show): error parameter is const char **. pane_string is const
 +      (xmenu_show): error parameter is const char **.  pane_string is const
        char *.
        (button_names): Is const char *.
        (xdialog_show): error_name and pane_string is const.
  
  2010-08-08  Kenichi Handa  <handa@m17n.org>
  
 -      * charset.c: Include <stdlib.h>
 +      * charset.c: Include <stdlib.h>.
        (struct charset_sort_data): New struct.
        (charset_compare): New function.
 -      (Fsort_charsets): New funciton.
 +      (Fsort_charsets): New function.
        (syms_of_charset): Declare Fsort_charsets as a Lisp function.
  
        * coding.c (decode_coding_iso_2022): Fix checking of dimension
        (smc_save_yourself_CB, x_session_initialize): Use SSDATA for strings
        passed to strlen/strcpy/strcat.
        (create_client_leader_window): Surround with #ifndef USE_GTK.  Cast
 -      7:th arg to XChangeProperty to (unsigned char *)
 +      7:th arg to XChangeProperty to (unsigned char *).
  
        * xsettings.c (something_changedCB, parse_settings)
        (apply_xft_settings): Reformat prototype.
        (Ffont_shape_text): New function.
        (Fopen_font): If the font size is not given, use 12-pixel.
        (Ffont_at): New arg STRING.
 -      (syms_of_font): Initalize font_charset_alist.
 +      (syms_of_font): Initialize font_charset_alist.
        Declare Ffont_shape_text as a Lisp function.  Call syms_of_XXfont
        conditionally.
  
  
        * font.c (font_unparse_fcname): Fix typo (swidth->width).
        (font_list_entities): Check driver_list->on.
 -      (register_font_driver): Initalize `on' member to 0.
 +      (register_font_driver): Initialize `on' member to 0.
        (font_update_drivers): New function.
        (Fclear_font_cache): Check driver_list->on.
  
  
        * search.c (search_buffer): Give up BM search on case-fold-search
        if one of a target character has a case-equivalence of different
 -      byte length even if that target charcter is an ASCII.
 +      byte length even if that target character is an ASCII.
        (simple_search): Fix calculation of byte length of matched text.
        (boyer_moore): Fix handling of case-equivalent multibyte characters.
  
diff --combined src/xdisp.c
@@@ -907,7 -907,7 +907,7 @@@ Lisp_Object Qinhibit_free_realized_face
  Lisp_Object help_echo_string;
  Lisp_Object help_echo_window;
  Lisp_Object help_echo_object;
 -int help_echo_pos;
 +EMACS_INT help_echo_pos;
  
  /* Temporary variable for XTread_socket.  */
  
@@@ -956,8 -956,7 +956,8 @@@ static void pint2hrstr (char *, int, in
  static struct text_pos run_window_scroll_functions (Lisp_Object,
                                                      struct text_pos);
  static void reconsider_clip_changes (struct window *, struct buffer *);
 -static int text_outside_line_unchanged_p (struct window *, int, int);
 +static int text_outside_line_unchanged_p (struct window *,
 +                                        EMACS_INT, EMACS_INT);
  static void store_mode_line_noprop_char (char);
  static int store_mode_line_noprop (const unsigned char *, int, int);
  static void x_consider_frame_title (Lisp_Object);
@@@ -992,9 -991,8 +992,9 @@@ static int append_space_for_newline (st
  static int cursor_row_fully_visible_p (struct window *, int, int);
  static int try_scrolling (Lisp_Object, int, EMACS_INT, EMACS_INT, int, int);
  static int try_cursor_movement (Lisp_Object, struct text_pos, int *);
 -static int trailing_whitespace_p (int);
 -static int message_log_check_duplicate (int, int, int, int);
 +static int trailing_whitespace_p (EMACS_INT);
 +static int message_log_check_duplicate (EMACS_INT, EMACS_INT,
 +                                      EMACS_INT, EMACS_INT);
  static void push_it (struct it *);
  static void pop_it (struct it *);
  static void sync_frame_with_window_matrix_rows (struct window *);
@@@ -1017,14 -1015,13 +1017,14 @@@ static int store_mode_line_string (cons
  static const char *decode_mode_spec (struct window *, int, int, int,
                                     Lisp_Object *);
  static void display_menu_bar (struct window *);
 -static int display_count_lines (int, int, int, int, int *);
 +static int display_count_lines (EMACS_INT, EMACS_INT, EMACS_INT, int,
 +                              EMACS_INT *);
  static int display_string (const unsigned char *, Lisp_Object, Lisp_Object,
                             EMACS_INT, EMACS_INT, struct it *, int, int, int, int);
  static void compute_line_metrics (struct it *);
  static void run_redisplay_end_trigger_hook (struct it *);
 -static int get_overlay_strings (struct it *, int);
 -static int get_overlay_strings_1 (struct it *, int, int);
 +static int get_overlay_strings (struct it *, EMACS_INT);
 +static int get_overlay_strings_1 (struct it *, EMACS_INT, int);
  static void next_overlay_string (struct it *);
  static void reseat (struct it *, struct text_pos, int);
  static void reseat_1 (struct it *, struct text_pos, int);
@@@ -1039,11 -1036,11 +1039,11 @@@ static int next_element_from_buffer (st
  static int next_element_from_composition (struct it *);
  static int next_element_from_image (struct it *);
  static int next_element_from_stretch (struct it *);
 -static void load_overlay_strings (struct it *, int);
 +static void load_overlay_strings (struct it *, EMACS_INT);
  static int init_from_display_pos (struct it *, struct window *,
                                    struct display_pos *);
  static void reseat_to_string (struct it *, const unsigned char *,
 -                              Lisp_Object, int, int, int, int);
 +                              Lisp_Object, EMACS_INT, EMACS_INT, int, int);
  static enum move_it_result
         move_it_in_display_line_to (struct it *, EMACS_INT, int,
                                   enum move_operation_enum);
@@@ -1055,10 -1052,10 +1055,10 @@@ static int init_to_row_end (struct it *
  static void back_to_previous_line_start (struct it *);
  static int forward_to_next_line_start (struct it *, int *);
  static struct text_pos string_pos_nchars_ahead (struct text_pos,
 -                                                Lisp_Object, int);
 -static struct text_pos string_pos (int, Lisp_Object);
 -static struct text_pos c_string_pos (int, const unsigned char *, int);
 -static int number_of_chars (const unsigned char *, int);
 +                                                Lisp_Object, EMACS_INT);
 +static struct text_pos string_pos (EMACS_INT, Lisp_Object);
 +static struct text_pos c_string_pos (EMACS_INT, const unsigned char *, int);
 +static EMACS_INT number_of_chars (const unsigned char *, int);
  static void compute_stop_pos (struct it *);
  static void compute_string_pos (struct text_pos *, struct text_pos,
                                  Lisp_Object);
@@@ -1085,6 -1082,7 +1085,7 @@@ static void notice_overwritten_cursor (
                                         int, int, int, int);
  static void append_stretch_glyph (struct it *, Lisp_Object,
                                    int, int, int);
+ static int coords_in_mouse_face_p (struct window *, int, int);
  
  
  
@@@ -1365,7 -1363,7 +1366,7 @@@ line_bottom_y (struct it *it
     Set *ROWH and *VPOS to row's visible height and VPOS (row number).  */
  
  int
 -pos_visible_p (struct window *w, int charpos, int *x, int *y,
 +pos_visible_p (struct window *w, EMACS_INT charpos, int *x, int *y,
               int *rtop, int *rbot, int *rowh, int *vpos)
  {
    struct it it;
@@@ -1525,13 -1523,13 +1526,13 @@@ string_char_and_length (const unsigned 
     in STRING, return the position NCHARS ahead (NCHARS >= 0).  */
  
  static struct text_pos
 -string_pos_nchars_ahead (struct text_pos pos, Lisp_Object string, int nchars)
 +string_pos_nchars_ahead (struct text_pos pos, Lisp_Object string, EMACS_INT nchars)
  {
    xassert (STRINGP (string) && nchars >= 0);
  
    if (STRING_MULTIBYTE (string))
      {
 -      int rest = SBYTES (string) - BYTEPOS (pos);
 +      EMACS_INT rest = SBYTES (string) - BYTEPOS (pos);
        const unsigned char *p = SDATA (string) + BYTEPOS (pos);
        int len;
  
     for character position CHARPOS in STRING.  */
  
  static INLINE struct text_pos
 -string_pos (int charpos, Lisp_Object string)
 +string_pos (EMACS_INT charpos, Lisp_Object string)
  {
    struct text_pos pos;
    xassert (STRINGP (string));
     means recognize multibyte characters.  */
  
  static struct text_pos
 -c_string_pos (int charpos, const unsigned char *s, int multibyte_p)
 +c_string_pos (EMACS_INT charpos, const unsigned char *s, int multibyte_p)
  {
    struct text_pos pos;
  
  
    if (multibyte_p)
      {
 -      int rest = strlen (s), len;
 +      EMACS_INT rest = strlen (s);
 +      int len;
  
        SET_TEXT_POS (pos, 0, 0);
        while (charpos--)
  /* Value is the number of characters in C string S.  MULTIBYTE_P
     non-zero means recognize multibyte characters.  */
  
 -static int
 +static EMACS_INT
  number_of_chars (const unsigned char *s, int multibyte_p)
  {
 -  int nchars;
 +  EMACS_INT nchars;
  
    if (multibyte_p)
      {
 -      int rest = strlen (s), len;
 +      EMACS_INT rest = strlen (s);
 +      int len;
        unsigned char *p = (unsigned char *) s;
  
        for (nchars = 0; rest > 0; ++nchars)
@@@ -2658,7 -2654,7 +2659,7 @@@ init_iterator (struct it *it, struct wi
              && WINDOWP (minibuf_selected_window)
              && w == XWINDOW (minibuf_selected_window))))
      {
 -      int charpos = marker_position (current_buffer->mark);
 +      EMACS_INT charpos = marker_position (current_buffer->mark);
        it->region_beg_charpos = min (PT, charpos);
        it->region_end_charpos = max (PT, charpos);
      }
@@@ -2904,7 -2900,7 +2905,7 @@@ in_ellipses_for_invisible_text_p (struc
  {
    Lisp_Object prop, window;
    int ellipses_p = 0;
 -  int charpos = CHARPOS (pos->pos);
 +  EMACS_INT charpos = CHARPOS (pos->pos);
  
    /* If POS specifies a position in a display vector, this might
       be for an ellipsis displayed for invisible text.  We won't
@@@ -3272,15 -3268,8 +3273,15 @@@ compute_stop_pos (struct it *it
        }
      }
  
 -  composition_compute_stop_pos (&it->cmp_it, charpos, bytepos,
 -                              it->stop_charpos, it->string);
 +  if (it->cmp_it.id < 0)
 +    {
 +      EMACS_INT stoppos = it->end_charpos;
 +
 +      if (it->bidi_p && it->bidi_it.scan_dir < 0)
 +      stoppos = -1;
 +      composition_compute_stop_pos (&it->cmp_it, charpos, bytepos,
 +                                  stoppos, it->string);
 +    }
  
    xassert (STRINGP (it->string)
           || (it->stop_charpos >= BEGV
@@@ -3460,8 -3449,7 +3461,8 @@@ handle_face_prop (struct it *it
      }
    else
      {
 -      int base_face_id, bufpos;
 +      int base_face_id;
 +      EMACS_INT bufpos;
        int i;
        Lisp_Object from_overlay
        = (it->current.overlay_string_index >= 0
@@@ -3585,8 -3573,7 +3586,8 @@@ face_before_or_after_it_pos (struct it 
  
    if (STRINGP (it->string))
      {
 -      int bufpos, base_face_id;
 +      EMACS_INT bufpos;
 +      int base_face_id;
  
        /* No face change past the end of the string (for the case
         we are padding with spaces).  No face change before the
        if (STRING_MULTIBYTE (it->string))
        {
          const unsigned char *p = SDATA (it->string) + BYTEPOS (pos);
 -        int rest = SBYTES (it->string) - BYTEPOS (pos);
          int c, len;
          struct face *face = FACE_FROM_ID (it->f, face_id);
  
@@@ -3830,8 -3818,7 +3831,8 @@@ handle_invisible_prop (struct it *it
                     not have a chance to do it, if we are going to
                     skip any text at the beginning, which resets the
                     FIRST_ELT flag.  */
 -                bidi_paragraph_init (it->paragraph_embedding, &it->bidi_it);
 +                bidi_paragraph_init (it->paragraph_embedding,
 +                                     &it->bidi_it, 1);
                }
              do
                {
@@@ -4646,6 -4633,7 +4647,6 @@@ string_buffer_position_lim (struct wind
  EMACS_INT
  string_buffer_position (struct window *w, Lisp_Object string, EMACS_INT around_charpos)
  {
 -  Lisp_Object limit, prop, pos;
    const int MAX_DISTANCE = 1000;
    EMACS_INT found = string_buffer_position_lim (w, string, around_charpos,
                                                around_charpos + MAX_DISTANCE,
@@@ -4876,11 -4864,11 +4877,11 @@@ compare_overlay_entries (const void *e1
     compare_overlay_entries.  */
  
  static void
 -load_overlay_strings (struct it *it, int charpos)
 +load_overlay_strings (struct it *it, EMACS_INT charpos)
  {
    Lisp_Object overlay, window, str, invisible;
    struct Lisp_Overlay *ov;
 -  int start, end;
 +  EMACS_INT start, end;
    int size = 20;
    int n = 0, i, j, invis_p;
    struct overlay_entry *entries
     least one overlay string was found.  */
  
  static int
 -get_overlay_strings_1 (struct it *it, int charpos, int compute_stop_p)
 +get_overlay_strings_1 (struct it *it, EMACS_INT charpos, int compute_stop_p)
  {
    /* Get the first OVERLAY_STRING_CHUNK_SIZE overlay strings to
       process.  This fills IT->overlay_strings with strings, and sets
  }
  
  static int
 -get_overlay_strings (struct it *it, int charpos)
 +get_overlay_strings (struct it *it, EMACS_INT charpos)
  {
    it->string = Qnil;
    it->method = GET_FROM_BUFFER;
@@@ -5152,7 -5140,7 +5153,7 @@@ iterate_out_of_display_property (struc
       of a new paragraph, next_element_from_buffer may not have a
       chance to do that.  */
    if (it->bidi_it.first_elt && it->bidi_it.charpos < ZV)
 -    bidi_paragraph_init (it->paragraph_embedding, &it->bidi_it);
 +    bidi_paragraph_init (it->paragraph_embedding, &it->bidi_it, 1);
    /* prev_stop can be zero, so check against BEGV as well.  */
    while (it->bidi_it.charpos >= BEGV
         && it->prev_stop <= it->bidi_it.charpos
@@@ -5323,8 -5311,8 +5324,8 @@@ forward_to_next_line_start (struct it *
       short-cut.  */
    if (!newline_found_p)
      {
 -      int start = IT_CHARPOS (*it);
 -      int limit = find_next_newline_no_quit (start, 1);
 +      EMACS_INT start = IT_CHARPOS (*it);
 +      EMACS_INT limit = find_next_newline_no_quit (start, 1);
        Lisp_Object pos;
  
        xassert (!STRINGP (it->string));
@@@ -5395,7 -5383,7 +5396,7 @@@ back_to_previous_visible_line_start (st
  
        {
        struct it it2;
 -      int pos;
 +      EMACS_INT pos;
        EMACS_INT beg, end;
        Lisp_Object val, overlay;
  
@@@ -5517,7 -5505,7 +5518,7 @@@ reseat_at_next_visible_line_start (stru
  static void
  reseat (struct it *it, struct text_pos pos, int force_p)
  {
 -  int original_pos = IT_CHARPOS (*it);
 +  EMACS_INT original_pos = IT_CHARPOS (*it);
  
    reseat_1 (it, pos, 0);
  
@@@ -5584,10 -5572,7 +5585,10 @@@ reseat_1 (struct it *it, struct text_po
    it->string_from_display_prop_p = 0;
    it->face_before_selective_p = 0;
    if (it->bidi_p)
 -    it->bidi_it.first_elt = 1;
 +    {
 +      it->bidi_it.first_elt = 1;
 +      it->bidi_it.paragraph_dir = NEUTRAL_DIR;
 +    }
  
    if (set_stop_p)
      {
  
  static void
  reseat_to_string (struct it *it, const unsigned char *s, Lisp_Object string,
 -                int charpos, int precision, int field_width, int multibyte)
 +                EMACS_INT charpos, EMACS_INT precision, int field_width,
 +                int multibyte)
  {
    /* No region in strings.  */
    it->region_beg_charpos = it->region_end_charpos = -1;
@@@ -5775,23 -5759,10 +5776,23 @@@ get_next_display_element (struct it *it
          struct charset *unibyte = CHARSET_FROM_ID (charset_unibyte);
          enum { char_is_other = 0, char_is_nbsp, char_is_soft_hyphen }
          nbsp_or_shy = char_is_other;
 -        int decoded = it->c;
 +        int c = it->c;        /* This is the character to display.  */
 +
 +        if (! it->multibyte_p && ! ASCII_CHAR_P (c))
 +          {
 +            xassert (SINGLE_BYTE_CHAR_P (c));
 +            if (unibyte_display_via_language_environment)
 +              {
 +                c = DECODE_CHAR (unibyte, c);
 +                if (c < 0)
 +                  c = BYTE8_TO_CHAR (it->c);
 +              }
 +            else
 +              c = BYTE8_TO_CHAR (it->c);
 +          }
  
          if (it->dp
 -            && (dv = DISP_CHAR_VECTOR (it->dp, it->c),
 +            && (dv = DISP_CHAR_VECTOR (it->dp, c),
                  VECTORP (dv)))
            {
              struct Lisp_Vector *v = XVECTOR (dv);
              goto get_next;
            }
  
 -        if (unibyte_display_via_language_environment
 -            && !ASCII_CHAR_P (it->c))
 -          decoded = DECODE_CHAR (unibyte, it->c);
 -
 -        if (it->c >= 0x80 && ! NILP (Vnobreak_char_display))
 -          {
 -            if (it->multibyte_p)
 -              nbsp_or_shy = (it->c == 0xA0   ? char_is_nbsp
 -                             : it->c == 0xAD ? char_is_soft_hyphen
 -                             :                 char_is_other);
 -            else if (unibyte_display_via_language_environment)
 -              nbsp_or_shy = (decoded == 0xA0   ? char_is_nbsp
 -                             : decoded == 0xAD ? char_is_soft_hyphen
 -                             :                   char_is_other);
 -          }
 +        if (! ASCII_CHAR_P (c) && ! NILP (Vnobreak_char_display))
 +          nbsp_or_shy = (c == 0xA0   ? char_is_nbsp
 +                         : c == 0xAD ? char_is_soft_hyphen
 +                         :             char_is_other);
  
          /* Translate control characters into `\003' or `^C' form.
             Control characters coming from a display table entry are
             the translation.  This could easily be changed but I
             don't believe that it is worth doing.
  
 -           If it->multibyte_p is nonzero, non-printable non-ASCII
 -           characters are also translated to octal form.
 +           NBSP and SOFT-HYPEN are property translated too.
  
 -           If it->multibyte_p is zero, eight-bit characters that
 -           don't have corresponding multibyte char code are also
 +           Non-printable characters and raw-byte characters are also
             translated to octal form.  */
 -        if ((it->c < ' '
 +        if (((c < ' ' || c == 127) /* ASCII control chars */
               ? (it->area != TEXT_AREA
                  /* In mode line, treat \n, \t like other crl chars.  */
 -                || (it->c != '\t'
 +                || (c != '\t'
                      && it->glyph_row
                      && (it->glyph_row->mode_line_p || it->avoid_cursor_p))
 -                || (it->c != '\n' && it->c != '\t'))
 +                || (c != '\n' && c != '\t'))
               : (nbsp_or_shy
 -                || (it->multibyte_p
 -                    ? ! CHAR_PRINTABLE_P (it->c)
 -                    : (! unibyte_display_via_language_environment
 -                       ? it->c >= 0x80
 -                       : (decoded >= 0x80 && decoded < 0xA0))))))
 +                || CHAR_BYTE8_P (c)
 +                || ! CHAR_PRINTABLE_P (c))))
            {
 -            /* IT->c is a control character which must be displayed
 +            /* C is a control character, NBSP, SOFT-HYPEN, raw-byte,
 +               or a non-printable character which must be displayed
                 either as '\003' or as `^C' where the '\\' and '^'
                 can be defined in the display table.  Fill
                 IT->ctl_chars with glyphs for what we have to
  
              /* Handle control characters with ^.  */
  
 -            if (it->c < 128 && it->ctl_arrow_p)
 +            if (ASCII_CHAR_P (c) && it->ctl_arrow_p)
                {
                  int g;
  
                    }
  
                  XSETINT (it->ctl_chars[0], g);
 -                XSETINT (it->ctl_chars[1], it->c ^ 0100);
 +                XSETINT (it->ctl_chars[1], c ^ 0100);
                  ctl_len = 2;
                  goto display_control;
                }
                  face_id = merge_faces (it->f, Qnobreak_space, 0,
                                         it->face_id);
  
 -                it->c = ' ';
 +                c = ' ';
                  XSETINT (it->ctl_chars[0], ' ');
                  ctl_len = 1;
                  goto display_control;
              if (EQ (Vnobreak_char_display, Qt)
                  && nbsp_or_shy == char_is_soft_hyphen)
                {
 -                it->c = '-';
                  XSETINT (it->ctl_chars[0], '-');
                  ctl_len = 1;
                  goto display_control;
              if (nbsp_or_shy)
                {
                  XSETINT (it->ctl_chars[0], escape_glyph);
 -                it->c = (nbsp_or_shy == char_is_nbsp ? ' ' : '-');
 -                XSETINT (it->ctl_chars[1], it->c);
 +                c = (nbsp_or_shy == char_is_nbsp ? ' ' : '-');
 +                XSETINT (it->ctl_chars[1], c);
                  ctl_len = 2;
                  goto display_control;
                }
  
              {
 -              unsigned char str[MAX_MULTIBYTE_LENGTH];
 -              int len;
 -              int i;
 +              char str[10];
 +              int len, i;
  
 -              /* Set IT->ctl_chars[0] to the glyph for `\\'.  */
 -              if (CHAR_BYTE8_P (it->c))
 -                {
 -                  str[0] = CHAR_TO_BYTE8 (it->c);
 -                  len = 1;
 -                }
 -              else if (it->c < 256)
 -                {
 -                  str[0] = it->c;
 -                  len = 1;
 -                }
 -              else
 -                {
 -                  /* It's an invalid character, which shouldn't
 -                     happen actually, but due to bugs it may
 -                     happen.  Let's print the char as is, there's
 -                     not much meaningful we can do with it.  */
 -                  str[0] = it->c;
 -                  str[1] = it->c >> 8;
 -                  str[2] = it->c >> 16;
 -                  str[3] = it->c >> 24;
 -                  len = 4;
 -                }
 +              if (CHAR_BYTE8_P (c))
 +                /* Display \200 instead of \17777600.  */
 +                c = CHAR_TO_BYTE8 (c);
 +              len = sprintf (str, "%03o", c);
  
 +              XSETINT (it->ctl_chars[0], escape_glyph);
                for (i = 0; i < len; i++)
 -                {
 -                  int g;
 -                  XSETINT (it->ctl_chars[i * 4], escape_glyph);
 -                  /* Insert three more glyphs into IT->ctl_chars for
 -                     the octal display of the character.  */
 -                  g = ((str[i] >> 6) & 7) + '0';
 -                  XSETINT (it->ctl_chars[i * 4 + 1], g);
 -                  g = ((str[i] >> 3) & 7) + '0';
 -                  XSETINT (it->ctl_chars[i * 4 + 2], g);
 -                  g = (str[i] & 7) + '0';
 -                  XSETINT (it->ctl_chars[i * 4 + 3], g);
 -                }
 -              ctl_len = len * 4;
 +                XSETINT (it->ctl_chars[i + 1], str[i]);
 +              ctl_len = len + 1;
              }
  
            display_control:
              it->ellipsis_p = 0;
              goto get_next;
            }
 +        it->char_to_display = c;
 +      }
 +      else if (success_p)
 +      {
 +        it->char_to_display = it->c;
        }
      }
  
        }
        else
        {
 -        int pos = (it->s ? -1
 -                   : STRINGP (it->string) ? IT_STRING_CHARPOS (*it)
 -                   : IT_CHARPOS (*it));
 +        EMACS_INT pos = (it->s ? -1
 +                         : STRINGP (it->string) ? IT_STRING_CHARPOS (*it)
 +                         : IT_CHARPOS (*it));
  
 -        it->face_id = FACE_FOR_CHAR (it->f, face, it->c, pos, it->string);
 +        it->face_id = FACE_FOR_CHAR (it->f, face, it->char_to_display, pos,
 +                                     it->string);
        }
      }
  #endif
@@@ -6138,7 -6149,7 +6139,7 @@@ set_iterator_to_next (struct it *it, in
                  it->cmp_it.id = -1;
                  composition_compute_stop_pos (&it->cmp_it, IT_CHARPOS (*it),
                                                IT_BYTEPOS (*it),
 -                                              it->stop_charpos, Qnil);
 +                                              it->end_charpos, Qnil);
                }
            }
          else if (! it->cmp_it.reversed_p)
                {
                  /* No more grapheme clusters in this composition.
                     Find the next stop position.  */
 -                EMACS_INT stop = it->stop_charpos;
 +                EMACS_INT stop = it->end_charpos;
                  if (it->bidi_it.scan_dir < 0)
                    /* Now we are scanning backward and don't know
                       where to stop.  */
                {
                  /* No more grapheme clusters in this composition.
                     Find the next stop position.  */
 -                EMACS_INT stop = it->stop_charpos;
 +                EMACS_INT stop = it->end_charpos;
                  if (it->bidi_it.scan_dir < 0)
                    /* Now we are scanning backward and don't know
                       where to stop.  */
              /* If this is a new paragraph, determine its base
                 direction (a.k.a. its base embedding level).  */
              if (it->bidi_it.new_paragraph)
 -              bidi_paragraph_init (it->paragraph_embedding, &it->bidi_it);
 +              bidi_paragraph_init (it->paragraph_embedding, &it->bidi_it, 0);
              bidi_move_to_visually_next (&it->bidi_it);
              IT_BYTEPOS (*it) = it->bidi_it.bytepos;
              IT_CHARPOS (*it) = it->bidi_it.charpos;
                {
                  /* As the scan direction was changed, we must
                     re-compute the stop position for composition.  */
 -                EMACS_INT stop = it->stop_charpos;
 +                EMACS_INT stop = it->end_charpos;
                  if (it->bidi_it.scan_dir < 0)
                    stop = -1;
                  composition_compute_stop_pos (&it->cmp_it, IT_CHARPOS (*it),
              composition_compute_stop_pos (&it->cmp_it,
                                            IT_STRING_CHARPOS (*it),
                                            IT_STRING_BYTEPOS (*it),
 -                                          it->stop_charpos, it->string);
 +                                          it->end_charpos, it->string);
            }
        }
        else
@@@ -6456,6 -6467,7 +6457,6 @@@ next_element_from_string (struct it *it
        }
        else if (STRING_MULTIBYTE (it->string))
        {
 -        int remaining = SBYTES (it->string) - IT_STRING_BYTEPOS (*it);
          const unsigned char *s = (SDATA (it->string)
                                    + IT_STRING_BYTEPOS (*it));
          it->c = string_char_and_length (s, &it->len);
        }
        else if (STRING_MULTIBYTE (it->string))
        {
 -        int maxlen = SBYTES (it->string) - IT_STRING_BYTEPOS (*it);
          const unsigned char *s = (SDATA (it->string)
                                    + IT_STRING_BYTEPOS (*it));
          it->c = string_char_and_length (s, &it->len);
@@@ -6543,7 -6556,13 +6544,7 @@@ next_element_from_c_string (struct it *
        BYTEPOS (it->position) = CHARPOS (it->position) = -1;
      }
    else if (it->multibyte_p)
 -    {
 -      /* Implementation note: The calls to strlen apparently aren't a
 -       performance problem because there is no noticeable performance
 -       difference between Emacs running in unibyte or multibyte mode.  */
 -      int maxlen = strlen (it->s) - IT_BYTEPOS (*it);
 -      it->c = string_char_and_length (it->s + IT_BYTEPOS (*it), &it->len);
 -    }
 +    it->c = string_char_and_length (it->s + IT_BYTEPOS (*it), &it->len);
    else
      it->c = it->s[IT_BYTEPOS (*it)], it->len = 1;
  
@@@ -6678,12 -6697,12 +6679,12 @@@ next_element_from_buffer (struct it *it
        {
          /* If we are at the beginning of a line, we can produce the
             next element right away.  */
 -        bidi_paragraph_init (it->paragraph_embedding, &it->bidi_it);
 +        bidi_paragraph_init (it->paragraph_embedding, &it->bidi_it, 1);
          bidi_move_to_visually_next (&it->bidi_it);
        }
        else
        {
 -        int orig_bytepos = IT_BYTEPOS (*it);
 +        EMACS_INT orig_bytepos = IT_BYTEPOS (*it);
  
          /* We need to prime the bidi iterator starting at the line's
             beginning, before we will be able to produce the next
          IT_BYTEPOS (*it) = CHAR_TO_BYTE (IT_CHARPOS (*it));
          it->bidi_it.charpos = IT_CHARPOS (*it);
          it->bidi_it.bytepos = IT_BYTEPOS (*it);
 -        bidi_paragraph_init (it->paragraph_embedding, &it->bidi_it);
 +        bidi_paragraph_init (it->paragraph_embedding, &it->bidi_it, 1);
          do
            {
              /* Now return to buffer position where we were asked to
        IT_BYTEPOS (*it) = it->bidi_it.bytepos;
        SET_TEXT_POS (it->position, IT_CHARPOS (*it), IT_BYTEPOS (*it));
        {
 -      EMACS_INT stop = it->stop_charpos;
 +      EMACS_INT stop = it->end_charpos;
        if (it->bidi_it.scan_dir < 0)
          stop = -1;
        composition_compute_stop_pos (&it->cmp_it, IT_CHARPOS (*it),
@@@ -6915,7 -6934,7 +6916,7 @@@ next_element_from_composition (struct i
          if (it->bidi_p)
            {
              if (it->bidi_it.new_paragraph)
 -              bidi_paragraph_init (it->paragraph_embedding, &it->bidi_it);
 +              bidi_paragraph_init (it->paragraph_embedding, &it->bidi_it, 0);
              /* Resync the bidi iterator with IT's new position.
                 FIXME: this doesn't support bidirectional text.  */
              while (it->bidi_it.charpos < IT_CHARPOS (*it))
@@@ -7412,7 -7431,7 +7413,7 @@@ move_it_in_display_line (struct it *it
     TO_CHARPOS.  */
  
  void
 -move_it_to (struct it *it, int to_charpos, int to_x, int to_y, int to_vpos, int op)
 +move_it_to (struct it *it, EMACS_INT to_charpos, int to_x, int to_y, int to_vpos, int op)
  {
    enum move_it_result skip, skip2 = MOVE_X_REACHED;
    int line_height, line_start_x = 0, reached = 0;
@@@ -7667,7 -7686,7 +7668,7 @@@ move_it_vertically_backward (struct it 
  {
    int nlines, h;
    struct it it2, it3;
 -  int start_pos;
 +  EMACS_INT start_pos;
  
   move_further_back:
    xassert (dy >= 0);
@@@ -7828,12 -7847,12 +7829,12 @@@ move_it_past_eol (struct it *it
  void
  move_it_by_lines (struct it *it, int dvpos, int need_y_p)
  {
 -  struct position pos;
  
    /* The commented-out optimization uses vmotion on terminals.  This
       gives bad results, because elements like it->what, on which
       callers such as pos_visible_p rely, aren't updated. */
 -  /*  if (!FRAME_WINDOW_P (it->f))
 +  /* struct position pos;
 +    if (!FRAME_WINDOW_P (it->f))
      {
        struct text_pos textpos;
  
    else
      {
        struct it it2;
 -      int start_charpos, i;
 +      EMACS_INT start_charpos, i;
  
        /* Start at the beginning of the screen line containing IT's
         position.  This may actually move vertically backwards,
@@@ -7942,7 -7961,7 +7943,7 @@@ add_to_log (const char *format, Lisp_Ob
    Lisp_Object args[3];
    Lisp_Object msg, fmt;
    char *buffer;
 -  int len;
 +  EMACS_INT len;
    struct gcpro gcpro1, gcpro2, gcpro3, gcpro4;
    USE_SAFE_ALLOCA;
  
@@@ -7991,7 -8010,7 +7992,7 @@@ message_log_maybe_newline (void
     so the buffer M must NOT point to a Lisp string.  */
  
  void
 -message_dolog (const char *m, int nbytes, int nlflag, int multibyte)
 +message_dolog (const char *m, EMACS_INT nbytes, int nlflag, int multibyte)
  {
    if (!NILP (Vmemory_full))
      return;
        struct buffer *oldbuf;
        Lisp_Object oldpoint, oldbegv, oldzv;
        int old_windows_or_buffers_changed = windows_or_buffers_changed;
 -      int point_at_end = 0;
 -      int zv_at_end = 0;
 +      EMACS_INT point_at_end = 0;
 +      EMACS_INT zv_at_end = 0;
        Lisp_Object old_deactivate_mark, tem;
        struct gcpro gcpro1;
  
        if (multibyte
          && NILP (current_buffer->enable_multibyte_characters))
        {
 -        int i, c, char_bytes;
 +        EMACS_INT i;
 +        int c, char_bytes;
          unsigned char work[1];
  
          /* Convert a multibyte string to single-byte
        else if (! multibyte
               && ! NILP (current_buffer->enable_multibyte_characters))
        {
 -        int i, c, char_bytes;
 +        EMACS_INT i;
 +        int c, char_bytes;
          unsigned char *msg = (unsigned char *) m;
          unsigned char str[MAX_MULTIBYTE_LENGTH];
          /* Convert a single-byte string to multibyte
  
        if (nlflag)
        {
 -        int this_bol, this_bol_byte, prev_bol, prev_bol_byte, dup;
 +        EMACS_INT this_bol, this_bol_byte, prev_bol, prev_bol_byte;
 +        int dup;
          insert_1 ("\n", 1, 1, 0, 0);
  
          scan_newline (Z, Z_BYTE, BEG, BEG_BYTE, -2, 0);
     value N > 1 if we should also append " [N times]".  */
  
  static int
 -message_log_check_duplicate (int prev_bol, int prev_bol_byte,
 -                           int this_bol, int this_bol_byte)
 +message_log_check_duplicate (EMACS_INT prev_bol, EMACS_INT prev_bol_byte,
 +                           EMACS_INT this_bol, EMACS_INT this_bol_byte)
  {
 -  int i;
 -  int len = Z_BYTE - 1 - this_bol_byte;
 +  EMACS_INT i;
 +  EMACS_INT len = Z_BYTE - 1 - this_bol_byte;
    int seen_dots = 0;
    unsigned char *p1 = BUF_BYTE_ADDRESS (current_buffer, prev_bol_byte);
    unsigned char *p2 = BUF_BYTE_ADDRESS (current_buffer, this_bol_byte);
     This may GC, so the buffer M must NOT point to a Lisp string.  */
  
  void
 -message2 (const char *m, int nbytes, int multibyte)
 +message2 (const char *m, EMACS_INT nbytes, int multibyte)
  {
    /* First flush out any partial line written with print.  */
    message_log_maybe_newline ();
  /* The non-logging counterpart of message2.  */
  
  void
 -message2_nolog (const char *m, int nbytes, int multibyte)
 +message2_nolog (const char *m, EMACS_INT nbytes, int multibyte)
  {
    struct frame *sf = SELECTED_FRAME ();
    message_enable_multibyte = multibyte;
     This function cancels echoing.  */
  
  void
 -message3 (Lisp_Object m, int nbytes, int multibyte)
 +message3 (Lisp_Object m, EMACS_INT nbytes, int multibyte)
  {
    struct gcpro gcpro1;
  
     and make this cancel echoing.  */
  
  void
 -message3_nolog (Lisp_Object m, int nbytes, int multibyte)
 +message3_nolog (Lisp_Object m, EMACS_INT nbytes, int multibyte)
  {
    struct frame *sf = SELECTED_FRAME ();
    message_enable_multibyte = multibyte;
@@@ -8496,7 -8512,7 +8497,7 @@@ vmessage (const char *m, va_list ap
        {
          if (m)
            {
 -            int len;
 +            EMACS_INT len;
  
              len = doprnt (FRAME_MESSAGE_BUF (f),
                            FRAME_MESSAGE_BUF_SIZE (f), m, (char *)0, ap);
@@@ -9193,7 -9209,7 +9194,7 @@@ check_message_stack (void
     time we display it---but don't redisplay it now.  */
  
  void
 -truncate_echo_area (int nchars)
 +truncate_echo_area (EMACS_INT nchars)
  {
    if (nchars == 0)
      echo_area_buffer[0] = Qnil;
@@@ -9240,8 -9256,7 +9241,8 @@@ truncate_message_1 (EMACS_INT nchars, L
    */
  
  void
 -set_message (const char *s, Lisp_Object string, int nbytes, int multibyte_p)
 +set_message (const char *s, Lisp_Object string,
 +           EMACS_INT nbytes, int multibyte_p)
  {
    message_enable_multibyte
      = ((s && multibyte_p)
@@@ -9277,7 -9292,7 +9278,7 @@@ set_message_1 (EMACS_INT a1, Lisp_Objec
  
    if (STRINGP (string))
      {
 -      int nchars;
 +      EMACS_INT nchars;
  
        if (nbytes == 0)
        nbytes = SBYTES (string);
        if (multibyte_p && NILP (current_buffer->enable_multibyte_characters))
        {
          /* Convert from multi-byte to single-byte.  */
 -        int i, c, n;
 +        EMACS_INT i;
 +        int c, n;
          unsigned char work[1];
  
          /* Convert a multibyte string to single-byte.  */
               && !NILP (current_buffer->enable_multibyte_characters))
        {
          /* Convert from single-byte to multi-byte.  */
 -        int i, c, n;
 +        EMACS_INT i;
 +        int c, n;
          const unsigned char *msg = (const unsigned char *) s;
          unsigned char str[MAX_MULTIBYTE_LENGTH];
  
@@@ -9635,7 -9648,7 +9636,7 @@@ static in
  store_mode_line_noprop (const unsigned char *str, int field_width, int precision)
  {
    int n = 0;
 -  int dummy, nbytes;
 +  EMACS_INT dummy, nbytes;
  
    /* Copy at most PRECISION chars from STR.  */
    nbytes = strlen (str);
@@@ -10846,7 -10859,7 +10847,7 @@@ note_tool_bar_highlight (struct frame *
    enum draw_glyphs_face draw = DRAW_IMAGE_RAISED;
    int mouse_down_p, rc;
  
 -  /* Function note_mouse_highlight is called with negative x(y
 +  /* Function note_mouse_highlight is called with negative X/Y
       values when mouse moves outside of the frame.  */
    if (x <= 0 || y <= 0)
      {
@@@ -10997,7 -11010,7 +10998,7 @@@ hscroll_window_tree (Lisp_Object window
              struct it it;
              int hscroll;
              struct buffer *saved_current_buffer;
 -            int pt;
 +            EMACS_INT pt;
              int wanted_x;
  
              /* Find point in a display of infinite width.  */
@@@ -11110,7 -11123,7 +11111,7 @@@ int debug_dvpos, debug_dy
  
  /* Delta in characters and bytes for try_window_id.  */
  
 -int debug_delta, debug_delta_bytes;
 +EMACS_INT debug_delta, debug_delta_bytes;
  
  /* Values of window_end_pos and window_end_vpos at the end of
     try_window_id.  */
@@@ -11162,8 -11175,7 +11163,8 @@@ debug_method_add (w, fmt, a1, a2, a3, a
     redisplay_internal for display optimization.  */
  
  static INLINE int
 -text_outside_line_unchanged_p (struct window *w, int start, int end)
 +text_outside_line_unchanged_p (struct window *w,
 +                             EMACS_INT start, EMACS_INT end)
  {
    int unchanged_p = 1;
  
@@@ -11386,8 -11398,8 +11387,8 @@@ overlay_arrow_at_row (struct it *it, st
     position.  BUF and PT are the current point buffer and position.  */
  
  int
 -check_point_in_composition (struct buffer *prev_buf, int prev_pt,
 -                          struct buffer *buf, int pt)
 +check_point_in_composition (struct buffer *prev_buf, EMACS_INT prev_pt,
 +                          struct buffer *buf, EMACS_INT pt)
  {
    EMACS_INT start, end;
    Lisp_Object prop;
@@@ -11440,7 -11452,7 +11441,7 @@@ reconsider_clip_changes (struct window 
    if (!b->clip_changed
        && BUFFERP (w->buffer) && !NILP (w->window_end_valid))
      {
 -      int pt;
 +      EMACS_INT pt;
  
        if (w == XWINDOW (selected_window))
        pt = BUF_PT (current_buffer);
@@@ -11842,7 -11854,7 +11843,7 @@@ redisplay_internal (int preserve_echo_a
                {
                  struct glyph_row *row
                    = MATRIX_ROW (w->current_matrix, this_line_vpos + 1);
 -                int delta, delta_bytes;
 +                EMACS_INT delta, delta_bytes;
  
                  /* We used to distinguish between two cases here,
                     conditioned by Z - CHARPOS (tlendpos) == ZV, for
@@@ -12471,15 -12483,14 +12472,15 @@@ redisplay_window_1 (Lisp_Object window
  
  int
  set_cursor_from_row (struct window *w, struct glyph_row *row,
 -                   struct glyph_matrix *matrix, int delta, int delta_bytes,
 +                   struct glyph_matrix *matrix,
 +                   EMACS_INT delta, EMACS_INT delta_bytes,
                     int dy, int dvpos)
  {
    struct glyph *glyph = row->glyphs[TEXT_AREA];
    struct glyph *end = glyph + row->used[TEXT_AREA];
    struct glyph *cursor = NULL;
    /* The last known character position in row.  */
 -  int last_pos = MATRIX_ROW_START_CHARPOS (row) + delta;
 +  EMACS_INT last_pos = MATRIX_ROW_START_CHARPOS (row) + delta;
    int x = row->x;
    EMACS_INT pt_old = PT - delta;
    EMACS_INT pos_before = MATRIX_ROW_START_CHARPOS (row) + delta;
    /* Non-zero means we've seen at least one glyph that came from a
       display string.  */
    int string_seen = 0;
 -  /* Largest buffer position seen so far during scan of glyph row.  */
 -  EMACS_INT bpos_max = last_pos;
 +  /* Largest and smalles buffer positions seen so far during scan of
 +     glyph row.  */
 +  EMACS_INT bpos_max = pos_before;
 +  EMACS_INT bpos_min = pos_after;
    /* Last buffer position covered by an overlay string with an integer
       `cursor' property.  */
    EMACS_INT bpos_covered = 0;
  
            if (glyph->charpos > bpos_max)
              bpos_max = glyph->charpos;
 +          if (glyph->charpos < bpos_min)
 +            bpos_min = glyph->charpos;
            if (!glyph->avoid_cursor_p)
              {
                /* If we hit point, we've found the glyph on which to
        else if (STRINGP (glyph->object))
          {
            Lisp_Object chprop;
 -          int glyph_pos = glyph->charpos;
 +          EMACS_INT glyph_pos = glyph->charpos;
  
            chprop = Fget_char_property (make_number (glyph_pos), Qcursor,
                                         glyph->object);
  
            if (glyph->charpos > bpos_max)
              bpos_max = glyph->charpos;
 +          if (glyph->charpos < bpos_min)
 +            bpos_min = glyph->charpos;
            if (!glyph->avoid_cursor_p)
              {
                if (dpos == 0)
        else if (STRINGP (glyph->object))
          {
            Lisp_Object chprop;
 -          int glyph_pos = glyph->charpos;
 +          EMACS_INT glyph_pos = glyph->charpos;
  
            chprop = Fget_char_property (make_number (glyph_pos), Qcursor,
                                         glyph->object);
            }
        }
        else if (match_with_avoid_cursor
 -             /* zero-width characters produce no glyphs */
 +             /* A truncated row may not include PT among its
 +                character positions.  Setting the cursor inside the
 +                scroll margin will trigger recalculation of hscroll
 +                in hscroll_window_tree.  */
 +             || (row->truncated_on_left_p && pt_old < bpos_min)
 +             || (row->truncated_on_right_p && pt_old > bpos_max)
 +             /* Zero-width characters produce no glyphs.  */
               || ((row->reversed_p
                    ? glyph_after > glyphs_end
                    : glyph_after < glyphs_end)
                             be a character in the string with the
                             `cursor' property, which means display
                             cursor on that character's glyph.  */
 -                        int strpos = glyph->charpos;
 +                        EMACS_INT strpos = glyph->charpos;
  
                          cursor = glyph;
                          for (glyph += incr;
                               glyph += incr)
                            {
                              Lisp_Object cprop;
 -                            int gpos = glyph->charpos;
 +                            EMACS_INT gpos = glyph->charpos;
  
                              cprop = Fget_char_property (make_number (gpos),
                                                          Qcursor,
@@@ -13712,7 -13711,7 +13713,7 @@@ try_cursor_movement (Lisp_Object window
  void
  set_vertical_scroll_bar (struct window *w)
  {
 -  int start, end, whole;
 +  EMACS_INT start, end, whole;
  
    /* Calculate the start and end positions for the current window.
       At some point, it would be nice to choose between scrollbars
@@@ -13776,7 -13775,7 +13777,7 @@@ redisplay_window (Lisp_Object window, i
    int rc;
    int centering_position = -1;
    int last_line_misfit = 0;
 -  int beg_unchanged, end_unchanged;
 +  EMACS_INT beg_unchanged, end_unchanged;
  
    SET_TEXT_POS (lpoint, PT, PT_BYTE);
    opoint = lpoint;
       window, set up appropriate value.  */
    if (!EQ (window, selected_window))
      {
 -      int new_pt = XMARKER (w->pointm)->charpos;
 -      int new_pt_byte = marker_byte_position (w->pointm);
 +      EMACS_INT new_pt = XMARKER (w->pointm)->charpos;
 +      EMACS_INT new_pt_byte = marker_byte_position (w->pointm);
        if (new_pt < BEGV)
        {
          new_pt = BEGV;
@@@ -15077,7 -15076,7 +15078,7 @@@ try_window_reusing_current_matrix (stru
  
  static struct glyph_row *find_last_unchanged_at_beg_row (struct window *);
  static struct glyph_row *find_first_unchanged_at_end_row (struct window *,
 -                                                          int *, int *);
 +                                                          EMACS_INT *, EMACS_INT *);
  static struct glyph_row *
  find_last_row_displaying_text (struct glyph_matrix *, struct it *,
                                 struct glyph_row *);
@@@ -15125,7 -15124,7 +15126,7 @@@ find_last_row_displaying_text (struct g
  static struct glyph_row *
  find_last_unchanged_at_beg_row (struct window *w)
  {
 -  int first_changed_pos = BEG + BEG_UNCHANGED;
 +  EMACS_INT first_changed_pos = BEG + BEG_UNCHANGED;
    struct glyph_row *row;
    struct glyph_row *row_found = NULL;
    int yb = window_text_bottom_y (w);
     changes.  */
  
  static struct glyph_row *
 -find_first_unchanged_at_end_row (struct window *w, int *delta, int *delta_bytes)
 +find_first_unchanged_at_end_row (struct window *w,
 +                               EMACS_INT *delta, EMACS_INT *delta_bytes)
  {
    struct glyph_row *row;
    struct glyph_row *row_found = NULL;
         corresponds to window_end_pos.  This allows us to translate
         buffer positions in the current matrix to current buffer
         positions for characters not in changed text.  */
 -      int Z_old = MATRIX_ROW_END_CHARPOS (row) + XFASTINT (w->window_end_pos);
 -      int Z_BYTE_old = MATRIX_ROW_END_BYTEPOS (row) + w->window_end_bytepos;
 -      int last_unchanged_pos, last_unchanged_pos_old;
 +      EMACS_INT Z_old =
 +      MATRIX_ROW_END_CHARPOS (row) + XFASTINT (w->window_end_pos);
 +      EMACS_INT Z_BYTE_old =
 +      MATRIX_ROW_END_BYTEPOS (row) + w->window_end_bytepos;
 +      EMACS_INT last_unchanged_pos, last_unchanged_pos_old;
        struct glyph_row *first_text_row
        = MATRIX_FIRST_TEXT_ROW (w->current_matrix);
  
@@@ -15292,8 -15288,8 +15293,8 @@@ sync_frame_with_window_matrix_rows (str
     containing CHARPOS or null.  */
  
  struct glyph_row *
 -row_containing_pos (struct window *w, int charpos, struct glyph_row *start,
 -                  struct glyph_row *end, int dy)
 +row_containing_pos (struct window *w, EMACS_INT charpos,
 +                  struct glyph_row *start, struct glyph_row *end, int dy)
  {
    struct glyph_row *row = start;
    struct glyph_row *best_row = NULL;
        {
          struct glyph *g;
  
-         if (NILP (XBUFFER (w->buffer)->bidi_display_reordering))
+         if (NILP (XBUFFER (w->buffer)->bidi_display_reordering)
+             || (!best_row && !row->continued_p))
            return row;
          /* In bidi-reordered rows, there could be several rows
-            occluding point.  We need to find the one which fits
+            occluding point, all of them belonging to the same
+            continued line.  We need to find the row which fits
             CHARPOS the best.  */
          for (g = row->glyphs[TEXT_AREA];
               g < row->glyphs[TEXT_AREA] + row->used[TEXT_AREA];
                    {
                      mindif = eabs (g->charpos - charpos);
                      best_row = row;
+                     /* Exact match always wins.  */
+                     if (mindif == 0)
+                       return best_row;
                    }
                }
            }
        }
-       else if (best_row)
+       else if (best_row && !row->continued_p)
        return best_row;
        ++row;
      }
@@@ -15406,14 -15407,13 +15412,14 @@@ try_window_id (struct window *w
    struct glyph_row *bottom_row;
    int bottom_vpos;
    struct it it;
 -  int delta = 0, delta_bytes = 0, stop_pos, dvpos, dy;
 +  EMACS_INT delta = 0, delta_bytes = 0, stop_pos;
 +  int dvpos, dy;
    struct text_pos start_pos;
    struct run run;
    int first_unchanged_at_end_vpos = 0;
    struct glyph_row *last_text_row, *last_text_row_at_end;
    struct text_pos start;
 -  int first_changed_charpos, last_changed_charpos;
 +  EMACS_INT first_changed_charpos, last_changed_charpos;
  
  #if GLYPH_DEBUG
    if (inhibit_try_window_id)
          || (last_changed_charpos < CHARPOS (start) - 1
              && FETCH_BYTE (BYTEPOS (start) - 1) == '\n')))
      {
 -      int Z_old, delta, Z_BYTE_old, delta_bytes;
 +      EMACS_INT Z_old, delta, Z_BYTE_old, delta_bytes;
        struct glyph_row *r0;
  
        /* Compute how many chars/bytes have been added to or removed
@@@ -16239,7 -16239,7 +16245,7 @@@ dump_glyph (row, glyph, area
        if (glyph->u.cmp.automatic)
        fprintf (stderr,
                 "[%d-%d]",
 -               glyph->u.cmp.from, glyph->u.cmp.to);
 +               glyph->slice.cmp.from, glyph->slice.cmp.to);
        fprintf (stderr, " . %4d %1.1d%1.1d\n",
               glyph->face_id,
               glyph->left_box_line_p,
@@@ -16483,19 -16483,15 +16489,19 @@@ get_overlay_arrow_glyph_row (struct win
  
        /* Get the next character.  */
        if (multibyte_p)
 -      it.c = string_char_and_length (p, &it.len);
 +      it.c = it.char_to_display = string_char_and_length (p, &it.len);
        else
 -      it.c = *p, it.len = 1;
 +      {
 +        it.c = it.char_to_display = *p, it.len = 1;
 +        if (! ASCII_CHAR_P (it.c))
 +          it.char_to_display = BYTE8_TO_CHAR (it.c);
 +      }
        p += it.len;
  
        /* Get its face.  */
        ilisp = make_number (p - arrow_string);
        face = Fget_text_property (ilisp, Qface, overlay_arrow_string);
 -      it.face_id = compute_char_face (f, it.c, face);
 +      it.face_id = compute_char_face (f, it.char_to_display, face);
  
        /* Compute its width, get its glyphs.  */
        n_glyphs_before = it.glyph_row->used[TEXT_AREA];
@@@ -16727,7 -16723,6 +16733,7 @@@ append_space_for_newline (struct it *it
             append_space_for_newline has been called.  */
          enum display_element_type saved_what = it->what;
          int saved_c = it->c, saved_len = it->len;
 +        int saved_char_to_display = it->char_to_display;
          int saved_x = it->current_x;
          int saved_face_id = it->face_id;
          struct text_pos saved_pos;
          it->what = IT_CHARACTER;
          memset (&it->position, 0, sizeof it->position);
          it->object = make_number (0);
 -        it->c = ' ';
 +        it->c = it->char_to_display = ' ';
          it->len = 1;
  
          if (default_face_p)
          it->face_id = saved_face_id;
          it->len = saved_len;
          it->c = saved_c;
 +        it->char_to_display = saved_char_to_display;
          return 1;
        }
      }
@@@ -16894,7 -16888,7 +16900,7 @@@ extend_face_to_end_of_line (struct it *
        it->what = IT_CHARACTER;
        memset (&it->position, 0, sizeof it->position);
        it->object = make_number (0);
 -      it->c = ' ';
 +      it->c = it->char_to_display = ' ';
        it->len = 1;
        /* The last row's blank glyphs should get the default face, to
         avoid painting the rest of the window with the region face,
     trailing whitespace.  */
  
  static int
 -trailing_whitespace_p (int charpos)
 +trailing_whitespace_p (EMACS_INT charpos)
  {
 -  int bytepos = CHAR_TO_BYTE (charpos);
 +  EMACS_INT bytepos = CHAR_TO_BYTE (charpos);
    int c = 0;
  
    while (bytepos < ZV_BYTE
@@@ -18021,9 -18015,8 +18027,9 @@@ See also `bidi-paragraph-direction'.  *
        itb.bytepos = bytepos;
        itb.first_elt = 1;
        itb.separator_limit = -1;
 +      itb.paragraph_dir = NEUTRAL_DIR;
  
 -      bidi_paragraph_init (NEUTRAL_DIR, &itb);
 +      bidi_paragraph_init (NEUTRAL_DIR, &itb, 1);
        if (buf != current_buffer)
        set_buffer_temp (old);
        switch (itb.paragraph_dir)
@@@ -18402,7 -18395,7 +18408,7 @@@ display_mode_element (struct it *it, in
        {
        /* A string: output it and check for %-constructs within it.  */
        unsigned char c;
 -      int offset = 0;
 +      EMACS_INT offset = 0;
  
        if (SCHARS (elt) > 0
            && (!NILP (props) || risky))
               && (mode_line_target != MODE_LINE_DISPLAY
                   || it->current_x < it->last_visible_x))
          {
 -          int last_offset = offset;
 +          EMACS_INT last_offset = offset;
  
            /* Advance to end of string or next format specifier.  */
            while ((c = SREF (elt, offset++)) != '\0' && c != '%')
  
            if (offset - 1 != last_offset)
              {
 -              int nchars, nbytes;
 +              EMACS_INT nchars, nbytes;
  
                /* Output to end of string or up to '%'.  Field width
                   is length of string.  Don't output more than
                    break;
                  case MODE_LINE_STRING:
                    {
 -                    int bytepos = last_offset;
 -                    int charpos = string_byte_to_char (elt, bytepos);
 -                    int endpos = (precision <= 0
 -                                  ? string_byte_to_char (elt, offset)
 -                                  : charpos + nchars);
 +                    EMACS_INT bytepos = last_offset;
 +                    EMACS_INT charpos = string_byte_to_char (elt, bytepos);
 +                    EMACS_INT endpos = (precision <= 0
 +                                        ? string_byte_to_char (elt, offset)
 +                                        : charpos + nchars);
  
                      n += store_mode_line_string (NULL,
                                                   Fsubstring (elt, make_number (charpos),
                    break;
                  case MODE_LINE_DISPLAY:
                    {
 -                    int bytepos = last_offset;
 -                    int charpos = string_byte_to_char (elt, bytepos);
 +                    EMACS_INT bytepos = last_offset;
 +                    EMACS_INT charpos = string_byte_to_char (elt, bytepos);
  
                      if (precision <= 0)
                        nchars = string_byte_to_char (elt, offset) - charpos;
              }
            else /* c == '%' */
              {
 -              int percent_position = offset;
 +              EMACS_INT percent_position = offset;
  
                /* Get the specified minimum width.  Zero means
                   don't pad.  */
                else if (c != 0)
                  {
                    int multibyte;
 -                  int bytepos, charpos;
 +                  EMACS_INT bytepos, charpos;
                    const unsigned char *spec;
                    Lisp_Object string;
  
@@@ -18850,7 -18843,7 +18856,7 @@@ static in
  store_mode_line_string (const char *string, Lisp_Object lisp_string, int copy_string,
                        int field_width, int precision, Lisp_Object props)
  {
 -  int len;
 +  EMACS_INT len;
    int n = 0;
  
    if (string != NULL)
@@@ -19395,23 -19388,22 +19401,23 @@@ decode_mode_spec (struct window *w, reg
  
      case 'i':
        {
 -      int size = ZV - BEGV;
 +      EMACS_INT size = ZV - BEGV;
        pint2str (decode_mode_spec_buf, field_width, size);
        return decode_mode_spec_buf;
        }
  
      case 'I':
        {
 -      int size = ZV - BEGV;
 +      EMACS_INT size = ZV - BEGV;
        pint2hrstr (decode_mode_spec_buf, field_width, size);
        return decode_mode_spec_buf;
        }
  
      case 'l':
        {
 -      int startpos, startpos_byte, line, linepos, linepos_byte;
 -      int topline, nlines, junk, height;
 +      EMACS_INT startpos, startpos_byte, line, linepos, linepos_byte;
 +      int topline, nlines, height;
 +      EMACS_INT junk;
  
        /* %c and %l are ignored in `frame-title-format'.  */
        if (mode_line_target == MODE_LINE_TITLE)
        else if (nlines < height + 25 || nlines > height * 3 + 50
                 || linepos == BUF_BEGV (b))
          {
 -          int limit = BUF_BEGV (b);
 -          int limit_byte = BUF_BEGV_BYTE (b);
 -          int position;
 +          EMACS_INT limit = BUF_BEGV (b);
 +          EMACS_INT limit_byte = BUF_BEGV_BYTE (b);
 +          EMACS_INT position;
            int distance = (height * 2 + 30) * line_number_display_limit_width;
  
            if (startpos - distance > limit)
  
      case 'p':
        {
 -      int pos = marker_position (w->start);
 -      int total = BUF_ZV (b) - BUF_BEGV (b);
 +      EMACS_INT pos = marker_position (w->start);
 +      EMACS_INT total = BUF_ZV (b) - BUF_BEGV (b);
  
        if (XFASTINT (w->window_end_pos) <= BUF_Z (b) - BUF_ZV (b))
          {
               so get us a 2-digit number that is close.  */
            if (total == 100)
              total = 99;
 -          sprintf (decode_mode_spec_buf, "%2d%%", total);
 +          sprintf (decode_mode_spec_buf, "%2ld%%", (long)total);
            return decode_mode_spec_buf;
          }
        }
        /* Display percentage of size above the bottom of the screen.  */
      case 'P':
        {
 -      int toppos = marker_position (w->start);
 -      int botpos = BUF_Z (b) - XFASTINT (w->window_end_pos);
 -      int total = BUF_ZV (b) - BUF_BEGV (b);
 +      EMACS_INT toppos = marker_position (w->start);
 +      EMACS_INT botpos = BUF_Z (b) - XFASTINT (w->window_end_pos);
 +      EMACS_INT total = BUF_ZV (b) - BUF_BEGV (b);
  
        if (botpos >= BUF_ZV (b))
          {
            if (total == 100)
              total = 99;
            if (toppos <= BUF_BEGV (b))
 -            sprintf (decode_mode_spec_buf, "Top%2d%%", total);
 +            sprintf (decode_mode_spec_buf, "Top%2ld%%", (long)total);
            else
 -            sprintf (decode_mode_spec_buf, "%2d%%", total);
 +            sprintf (decode_mode_spec_buf, "%2ld%%", (long)total);
            return decode_mode_spec_buf;
          }
        }
     Set *BYTE_POS_PTR to 1 if we found COUNT lines, 0 if we hit LIMIT.  */
  
  static int
 -display_count_lines (int start, int start_byte, int limit_byte, int count,
 -                   int *byte_pos_ptr)
 +display_count_lines (EMACS_INT start, EMACS_INT start_byte,
 +                   EMACS_INT limit_byte, int count,
 +                   EMACS_INT *byte_pos_ptr)
  {
    register unsigned char *cursor;
    unsigned char *base;
@@@ -20501,12 -20492,7 +20507,12 @@@ get_glyph_face_and_encoding (struct fra
  
    if (face->font)
      {
 -      unsigned code = face->font->driver->encode_char (face->font, glyph->u.ch);
 +      unsigned code;
 +
 +      if (CHAR_BYTE8_P (glyph->u.ch))
 +      code = CHAR_TO_BYTE8 (glyph->u.ch);
 +      else
 +      code = face->font->driver->encode_char (face->font, glyph->u.ch);
  
        if (code != FONT_INVALID_CODE)
        STORE_XCHAR2B (char2b, (code >> 8), (code & 0xFF));
  }
  
  
 +/* Get glyph code of character C in FONT in the two-byte form CHAR2B.
 +   Retunr 1 if FONT has a glyph for C, otherwise return 0.  */
 +
 +static INLINE int
 +get_char_glyph_code (int c, struct font *font, XChar2b *char2b)
 +{
 +  unsigned code;
 +
 +  if (CHAR_BYTE8_P (c))
 +    code = CHAR_TO_BYTE8 (c);
 +  else
 +    code = font->driver->encode_char (font, c);
 +
 +  if (code == FONT_INVALID_CODE)
 +    return 0;
 +  STORE_XCHAR2B (char2b, (code >> 8), (code & 0xFF));
 +  return 1;
 +}
 +
 +
  /* Fill glyph string S with composition components specified by S->cmp.
  
     BASE_FACE is the base face of the composition.
@@@ -20627,8 -20593,8 +20633,8 @@@ fill_gstring_glyph_string (struct glyph
    glyph = s->row->glyphs[s->area] + start;
    last = s->row->glyphs[s->area] + end;
    s->cmp_id = glyph->u.cmp.id;
 -  s->cmp_from = glyph->u.cmp.from;
 -  s->cmp_to = glyph->u.cmp.to + 1;
 +  s->cmp_from = glyph->slice.cmp.from;
 +  s->cmp_to = glyph->slice.cmp.to + 1;
    s->face = FACE_FROM_ID (s->f, face_id);
    lgstring = composition_gstring_from_id (s->cmp_id);
    s->font = XFONT_OBJECT (LGSTRING_FONT (lgstring));
    while (glyph < last
         && glyph->u.cmp.automatic
         && glyph->u.cmp.id == s->cmp_id
 -       && s->cmp_to == glyph->u.cmp.from)
 -    s->cmp_to = (glyph++)->u.cmp.to + 1;
 +       && s->cmp_to == glyph->slice.cmp.from)
 +    s->cmp_to = (glyph++)->slice.cmp.to + 1;
  
    for (i = s->cmp_from; i < s->cmp_to; i++)
      {
@@@ -20727,7 -20693,7 +20733,7 @@@ fill_image_glyph_string (struct glyph_s
    xassert (s->first_glyph->type == IMAGE_GLYPH);
    s->img = IMAGE_FROM_ID (s->f, s->first_glyph->u.img_id);
    xassert (s->img);
 -  s->slice = s->first_glyph->slice;
 +  s->slice = s->first_glyph->slice.img;
    s->face = FACE_FROM_ID (s->f, s->first_glyph->face_id);
    s->font = s->face->font;
    s->width = s->first_glyph->pixel_width;
@@@ -20833,8 -20799,8 +20839,8 @@@ x_get_glyph_overhangs (struct glyph *gl
          Lisp_Object gstring = composition_gstring_from_id (glyph->u.cmp.id);
          struct font_metrics metrics;
  
 -        composition_gstring_width (gstring, glyph->u.cmp.from,
 -                                   glyph->u.cmp.to + 1, &metrics);
 +        composition_gstring_width (gstring, glyph->slice.cmp.from,
 +                                   glyph->slice.cmp.to + 1, &metrics);
          if (metrics.rbearing > metrics.width)
            *right = metrics.rbearing - metrics.width;
          if (metrics.lbearing < 0)
@@@ -21539,7 -21505,7 +21545,7 @@@ append_glyph (struct it *it
        glyph->glyph_not_available_p = it->glyph_not_available_p;
        glyph->face_id = it->face_id;
        glyph->u.ch = it->char_to_display;
 -      glyph->slice = null_glyph_slice;
 +      glyph->slice.img = null_glyph_slice;
        glyph->font_type = FONT_TYPE_UNKNOWN;
        if (it->bidi_p)
        {
@@@ -21596,14 -21562,13 +21602,14 @@@ append_composite_glyph (struct it *it
        {
          glyph->u.cmp.automatic = 0;
          glyph->u.cmp.id = it->cmp_it.id;
 +        glyph->slice.cmp.from = glyph->slice.cmp.to = 0;
        }
        else
        {
          glyph->u.cmp.automatic = 1;
          glyph->u.cmp.id = it->cmp_it.id;
 -        glyph->u.cmp.from = it->cmp_it.from;
 -        glyph->u.cmp.to = it->cmp_it.to - 1;
 +        glyph->slice.cmp.from = it->cmp_it.from;
 +        glyph->slice.cmp.to = it->cmp_it.to - 1;
        }
        glyph->avoid_cursor_p = it->avoid_cursor_p;
        glyph->multibyte_p = it->multibyte_p;
        glyph->padding_p = 0;
        glyph->glyph_not_available_p = 0;
        glyph->face_id = it->face_id;
 -      glyph->slice = null_glyph_slice;
        glyph->font_type = FONT_TYPE_UNKNOWN;
        if (it->bidi_p)
        {
@@@ -21792,7 -21758,7 +21798,7 @@@ produce_image_glyph (struct it *it
          glyph->glyph_not_available_p = 0;
          glyph->face_id = it->face_id;
          glyph->u.img_id = img->id;
 -        glyph->slice = slice;
 +        glyph->slice.img = slice;
          glyph->font_type = FONT_TYPE_UNKNOWN;
          if (it->bidi_p)
            {
@@@ -21853,7 -21819,7 +21859,7 @@@ append_stretch_glyph (struct it *it, Li
        glyph->face_id = it->face_id;
        glyph->u.stretch.ascent = ascent;
        glyph->u.stretch.height = height;
 -      glyph->slice = null_glyph_slice;
 +      glyph->slice.img = null_glyph_slice;
        glyph->font_type = FONT_TYPE_UNKNOWN;
        if (it->bidi_p)
        {
@@@ -21942,13 -21908,13 +21948,13 @@@ produce_stretch_glyph (struct it *it
  
        it2 = *it;
        if (it->multibyte_p)
 +      it2.c = it2.char_to_display = STRING_CHAR_AND_LENGTH (p, it2.len);
 +      else
        {
 -        int maxlen = ((IT_BYTEPOS (*it) >= GPT ? ZV : GPT)
 -                      - IT_BYTEPOS (*it));
 -        it2.c = STRING_CHAR_AND_LENGTH (p, it2.len);
 +        it2.c = it2.char_to_display = *p, it2.len = 1;
 +        if (! ASCII_CHAR_P (it2.c))
 +          it2.char_to_display = BYTE8_TO_CHAR (it2.c);
        }
 -      else
 -      it2.c = *p, it2.len = 1;
  
        it2.glyph_row = NULL;
        it2.what = IT_CHARACTER;
@@@ -22118,12 -22084,49 +22124,12 @@@ x_produce_glyphs (struct it *it
    if (it->what == IT_CHARACTER)
      {
        XChar2b char2b;
 -      struct font *font;
        struct face *face = FACE_FROM_ID (it->f, it->face_id);
 -      struct font_metrics *pcm;
 -      int font_not_found_p;
 +      struct font *font = face->font;
 +      int font_not_found_p = font == NULL;
 +      struct font_metrics *pcm = NULL;
        int boff;                       /* baseline offset */
 -      /* We may change it->multibyte_p upon unibyte<->multibyte
 -       conversion.  So, save the current value now and restore it
 -       later.
 -
 -       Note: It seems that we don't have to record multibyte_p in
 -       struct glyph because the character code itself tells whether
 -       or not the character is multibyte.  Thus, in the future, we
 -       must consider eliminating the field `multibyte_p' in the
 -       struct glyph.  */
 -      int saved_multibyte_p = it->multibyte_p;
 -
 -      /* Maybe translate single-byte characters to multibyte, or the
 -       other way.  */
 -      it->char_to_display = it->c;
 -      if (!ASCII_BYTE_P (it->c)
 -        && ! it->multibyte_p)
 -      {
 -        if (SINGLE_BYTE_CHAR_P (it->c)
 -            && unibyte_display_via_language_environment)
 -          {
 -            struct charset *unibyte = CHARSET_FROM_ID (charset_unibyte);
 -
 -            /* get_next_display_element assures that this decoding
 -               never fails.  */
 -            it->char_to_display = DECODE_CHAR (unibyte, it->c);
 -            it->multibyte_p = 1;
 -            it->face_id = FACE_FOR_CHAR (it->f, face, it->char_to_display,
 -                                         -1, Qnil);
 -            face = FACE_FROM_ID (it->f, it->face_id);
 -          }
 -      }
 -
 -      /* Get font to use.  Encode IT->char_to_display.  */
 -      get_char_face_and_encoding (it->f, it->char_to_display, it->face_id,
 -                                &char2b, it->multibyte_p, 0);
 -      font = face->font;
  
 -      font_not_found_p = font == NULL;
        if (font_not_found_p)
        {
          /* When no suitable font found, display an empty box based
            boff = VCENTER_BASELINE_OFFSET (font, it->f) - boff;
        }
  
 -      if (it->char_to_display >= ' '
 -        && (!it->multibyte_p || it->char_to_display < 128))
 +      if (it->char_to_display != '\n' && it->char_to_display != '\t')
        {
 -        /* Either unibyte or ASCII.  */
          int stretched_p;
  
          it->nglyphs = 1;
  
 -        pcm = get_per_char_metric (it->f, font, &char2b);
 -
          if (it->override_ascent >= 0)
            {
              it->ascent = it->override_ascent;
              it->descent = FONT_DESCENT (font) - boff;
            }
  
 +        if (! font_not_found_p
 +            && get_char_glyph_code (it->char_to_display, font, &char2b))
 +          {
 +            pcm = get_per_char_metric (it->f, font, &char2b);
 +            if (pcm->width == 0
 +                && pcm->rbearing == 0 && pcm->lbearing == 0)
 +              pcm = NULL;
 +          }
 +
          if (pcm)
            {
              it->phys_ascent = pcm->ascent + boff;
              it->glyph_not_available_p = 1;
              it->phys_ascent = it->ascent;
              it->phys_descent = it->descent;
 -            it->pixel_width = FONT_WIDTH (font);
 +            it->pixel_width = font->space_width;
            }
  
          if (it->constrain_row_ascent_descent_p)
                }
            }
        }
 -      else if (it->char_to_display == '\t')
 +      else                  /* i.e. (it->char_to_display == '\t') */
        {
          if (font->space_width > 0)
            {
              it->nglyphs = 1;
            }
        }
 -      else
 -      {
 -        /* A multi-byte character.  Assume that the display width of the
 -           character is the width of the character multiplied by the
 -           width of the font.  */
 -
 -        /* If we found a font, this font should give us the right
 -           metrics.  If we didn't find a font, use the frame's
 -           default font and calculate the width of the character by
 -           multiplying the width of font by the width of the
 -           character.  */
 -
 -        pcm = get_per_char_metric (it->f, font, &char2b);
 -
 -        if (font_not_found_p || !pcm)
 -          {
 -            int char_width = CHAR_WIDTH (it->char_to_display);
 -
 -            if (char_width == 0)
 -              /* This is a non spacing character.  But, as we are
 -                 going to display an empty box, the box must occupy
 -                 at least one column.  */
 -              char_width = 1;
 -            it->glyph_not_available_p = 1;
 -            it->pixel_width = font->space_width * char_width;
 -            it->phys_ascent = FONT_BASE (font) + boff;
 -            it->phys_descent = FONT_DESCENT (font) - boff;
 -          }
 -        else
 -          {
 -            it->pixel_width = pcm->width;
 -            it->phys_ascent = pcm->ascent + boff;
 -            it->phys_descent = pcm->descent - boff;
 -            if (it->glyph_row
 -                && (pcm->lbearing < 0
 -                    || pcm->rbearing > pcm->width))
 -              it->glyph_row->contains_overlapping_glyphs_p = 1;
 -          }
 -        it->nglyphs = 1;
 -          it->ascent = FONT_BASE (font) + boff;
 -          it->descent = FONT_DESCENT (font) - boff;
 -        if (face->box != FACE_NO_BOX)
 -          {
 -            int thick = face->box_line_width;
 -
 -            if (thick > 0)
 -              {
 -                it->ascent += thick;
 -                it->descent += thick;
 -              }
 -            else
 -              thick = - thick;
 -
 -            if (it->start_of_box_run_p)
 -              it->pixel_width += thick;
 -            if (it->end_of_box_run_p)
 -              it->pixel_width += thick;
 -          }
 -
 -        /* If face has an overline, add the height of the overline
 -           (1 pixel) and a 1 pixel margin to the character height.  */
 -        if (face->overline_p)
 -          it->ascent += overline_margin;
 -
 -        take_vertical_position_into_account (it);
 -
 -        if (it->ascent < 0)
 -          it->ascent = 0;
 -        if (it->descent < 0)
 -          it->descent = 0;
 -
 -        if (it->glyph_row)
 -          append_glyph (it);
 -        if (it->pixel_width == 0)
 -          /* We assure that all visible glyphs have at least 1-pixel
 -             width.  */
 -          it->pixel_width = 1;
 -      }
 -      it->multibyte_p = saved_multibyte_p;
      }
    else if (it->what == IT_COMPOSITION && it->cmp_it.ch < 0)
      {
          XChar2b char2b;
          struct font_metrics *pcm;
          int font_not_found_p;
 -        int pos;
 +        EMACS_INT pos;
  
          for (glyph_len = cmp->glyph_len; glyph_len > 0; glyph_len--)
            if ((c = COMPOSITION_GLYPH (cmp, glyph_len - 1)) != '\t')
            }
          else
            {
 -            width = FONT_WIDTH (font);
 +            width = font->space_width;
              ascent = FONT_BASE (font);
              descent = FONT_DESCENT (font);
              lbearing = 0;
@@@ -23411,13 -23488,7 +23417,7 @@@ erase_phys_cursor (struct window *w
    /* If the cursor is in the mouse face area, redisplay that when
       we clear the cursor.  */
    if (! NILP (dpyinfo->mouse_face_window)
-       && w == XWINDOW (dpyinfo->mouse_face_window)
-       && (vpos > dpyinfo->mouse_face_beg_row
-         || (vpos == dpyinfo->mouse_face_beg_row
-             && hpos >= dpyinfo->mouse_face_beg_col))
-       && (vpos < dpyinfo->mouse_face_end_row
-         || (vpos == dpyinfo->mouse_face_end_row
-             && hpos < dpyinfo->mouse_face_end_col))
+       && coords_in_mouse_face_p (w, hpos, vpos)
        /* Don't redraw the cursor's spot in mouse face if it is at the
         end of a line (on a newline).  The cursor appears there, but
         mouse highlighting does not.  */
@@@ -23640,8 -23711,30 +23640,30 @@@ show_mouse_face (Display_Info *dpyinfo
          /* For all but the first row, the highlight starts at column 0.  */
          if (row == first)
            {
-             start_hpos = dpyinfo->mouse_face_beg_col;
-             start_x = dpyinfo->mouse_face_beg_x;
+             /* R2L rows have BEG and END in reversed order, but the
+                screen drawing geometry is always left to right.  So
+                we need to mirror the beginning and end of the
+                highlighted area in R2L rows.  */
+             if (!row->reversed_p)
+               {
+                 start_hpos = dpyinfo->mouse_face_beg_col;
+                 start_x = dpyinfo->mouse_face_beg_x;
+               }
+             else if (row == last)
+               {
+                 start_hpos = dpyinfo->mouse_face_end_col;
+                 start_x = dpyinfo->mouse_face_end_x;
+               }
+             else
+               {
+                 start_hpos = 0;
+                 start_x = 0;
+               }
+           }
+         else if (row->reversed_p && row == last)
+           {
+             start_hpos = dpyinfo->mouse_face_end_col;
+             start_x = dpyinfo->mouse_face_end_x;
            }
          else
            {
            }
  
          if (row == last)
-           end_hpos = dpyinfo->mouse_face_end_col;
+           {
+             if (!row->reversed_p)
+               end_hpos = dpyinfo->mouse_face_end_col;
+             else if (row == first)
+               end_hpos = dpyinfo->mouse_face_beg_col;
+             else
+               {
+                 end_hpos = row->used[TEXT_AREA];
+                 if (draw == DRAW_NORMAL_TEXT)
+                   row->fill_line_p = 1; /* Clear to end of line */
+               }
+           }
+         else if (row->reversed_p && row == first)
+           end_hpos = dpyinfo->mouse_face_beg_col;
          else
            {
              end_hpos = row->used[TEXT_AREA];
@@@ -23713,6 -23819,53 +23748,53 @@@ clear_mouse_face (Display_Info *dpyinfo
    return cleared;
  }
  
+ /* Return non-zero if the coordinates HPOS and VPOS on windows W are
+    within the mouse face on that window.  */
+ static int
+ coords_in_mouse_face_p (struct window *w, int hpos, int vpos)
+ {
+   Display_Info *dpyinfo = FRAME_X_DISPLAY_INFO (XFRAME (w->frame));
+   /* Quickly resolve the easy cases.  */
+   if (!(WINDOWP (dpyinfo->mouse_face_window)
+       && XWINDOW (dpyinfo->mouse_face_window) == w))
+     return 0;
+   if (vpos < dpyinfo->mouse_face_beg_row
+       || vpos > dpyinfo->mouse_face_end_row)
+     return 0;
+   if (vpos > dpyinfo->mouse_face_beg_row
+       && vpos < dpyinfo->mouse_face_end_row)
+     return 1;
+   if (!MATRIX_ROW (w->current_matrix, vpos)->reversed_p)
+     {
+       if (dpyinfo->mouse_face_beg_row == dpyinfo->mouse_face_end_row)
+       {
+         if (dpyinfo->mouse_face_beg_col <= hpos && hpos < dpyinfo->mouse_face_end_col)
+           return 1;
+       }
+       else if ((vpos == dpyinfo->mouse_face_beg_row
+               && hpos >= dpyinfo->mouse_face_beg_col)
+              || (vpos == dpyinfo->mouse_face_end_row
+                  && hpos < dpyinfo->mouse_face_end_col))
+       return 1;
+     }
+   else
+     {
+        if (dpyinfo->mouse_face_beg_row == dpyinfo->mouse_face_end_row)
+       {
+         if (dpyinfo->mouse_face_end_col < hpos && hpos <= dpyinfo->mouse_face_beg_col)
+           return 1;
+       }
+       else if ((vpos == dpyinfo->mouse_face_beg_row
+               && hpos <= dpyinfo->mouse_face_beg_col)
+              || (vpos == dpyinfo->mouse_face_end_row
+                  && hpos > dpyinfo->mouse_face_end_col))
+       return 1;
+     }
+   return 0;
+ }
  
  /* EXPORT:
     Non-zero if physical cursor of window W is within mouse face.  */
  int
  cursor_in_mouse_face_p (struct window *w)
  {
-   Display_Info *dpyinfo = FRAME_X_DISPLAY_INFO (XFRAME (w->frame));
-   int in_mouse_face = 0;
+   return coords_in_mouse_face_p (w, w->phys_cursor.hpos, w->phys_cursor.vpos);
+ }
  
-   if (WINDOWP (dpyinfo->mouse_face_window)
-       && XWINDOW (dpyinfo->mouse_face_window) == w)
-     {
-       int hpos = w->phys_cursor.hpos;
-       int vpos = w->phys_cursor.vpos;
  
-       if (vpos >= dpyinfo->mouse_face_beg_row
-         && vpos <= dpyinfo->mouse_face_end_row
-         && (vpos > dpyinfo->mouse_face_beg_row
-             || hpos >= dpyinfo->mouse_face_beg_col)
-         && (vpos < dpyinfo->mouse_face_end_row
-             || hpos < dpyinfo->mouse_face_end_col
-             || dpyinfo->mouse_face_past_end))
-       in_mouse_face = 1;
-     }
\f
+ /* Find the glyph rows START_ROW and END_ROW of window W that display
+    characters between buffer positions START_CHARPOS and END_CHARPOS
+    (excluding END_CHARPOS).  This is similar to row_containing_pos,
+    but is more accurate when bidi reordering makes buffer positions
+    change non-linearly with glyph rows.  */
+ static void
+ rows_from_pos_range (struct window *w,
+                    EMACS_INT start_charpos, EMACS_INT end_charpos,
+                    struct glyph_row **start, struct glyph_row **end)
+ {
+   struct glyph_row *first = MATRIX_FIRST_TEXT_ROW (w->current_matrix);
+   int last_y = window_text_bottom_y (w);
+   struct glyph_row *row;
  
-   return in_mouse_face;
- }
+   *start = NULL;
+   *end = NULL;
+   while (!first->enabled_p
+        && first < MATRIX_BOTTOM_TEXT_ROW (w->current_matrix, w))
+     first++;
+   /* Find the START row.  */
+   for (row = first;
+        row->enabled_p && MATRIX_ROW_BOTTOM_Y (row) <= last_y;
+        row++)
+     {
+       /* A row can potentially be the START row if the range of the
+        characters it displays intersects the range
+        [START_CHARPOS..END_CHARPOS).  */
+       if (! ((start_charpos < MATRIX_ROW_START_CHARPOS (row)
+             && end_charpos < MATRIX_ROW_START_CHARPOS (row))
+            /* See the commentary in row_containing_pos, for the
+               explanation of the complicated way to check whether
+               some position is beyond the end of the characters
+               displayed by a row.  */
+            || ((start_charpos > MATRIX_ROW_END_CHARPOS (row)
+                 || (start_charpos == MATRIX_ROW_END_CHARPOS (row)
+                     && !row->ends_at_zv_p
+                     && !MATRIX_ROW_ENDS_IN_MIDDLE_OF_CHAR_P (row)))
+                && (end_charpos > MATRIX_ROW_END_CHARPOS (row)
+                    || (end_charpos == MATRIX_ROW_END_CHARPOS (row)
+                        && !row->ends_at_zv_p
+                        && !MATRIX_ROW_ENDS_IN_MIDDLE_OF_CHAR_P (row))))))
+       {
+         /* Found a candidate row.  Now make sure at least one of the
+            glyphs it displays has a charpos from the range
+            [START_CHARPOS..END_CHARPOS).
+            This is not obvious because bidi reordering could make
+            buffer positions of a row be 1,2,3,102,101,100, and if we
+            want to highlight characters in [50..60), we don't want
+            this row, even though [50..60) does intersect [1..103),
+            the range of character positions given by the row's start
+            and end positions.  */
+         struct glyph *g = row->glyphs[TEXT_AREA];
+         struct glyph *e = g + row->used[TEXT_AREA];
+         while (g < e)
+           {
+             if (BUFFERP (g->object)
+                 && start_charpos <= g->charpos && g->charpos < end_charpos)
+               *start = row;
+             g++;
+           }
+         if (*start)
+           break;
+       }
+     }
  
+   /* Find the END row.  */
+   if (!*start
+       /* If the last row is partially visible, start looking for END
+        from that row, instead of starting from FIRST.  */
+       && !(row->enabled_p
+          && row->y < last_y && MATRIX_ROW_BOTTOM_Y (row) > last_y))
+     row = first;
+   for ( ; row->enabled_p && MATRIX_ROW_BOTTOM_Y (row) <= last_y; row++)
+     {
+       struct glyph_row *next = row + 1;
+       if (!next->enabled_p
+         || next >= MATRIX_BOTTOM_TEXT_ROW (w->current_matrix, w)
+         /* The first row >= START whose range of displayed characters
+            does NOT intersect the range [START_CHARPOS..END_CHARPOS]
+            is the row END + 1.  */
+         || (start_charpos < MATRIX_ROW_START_CHARPOS (next)
+             && end_charpos < MATRIX_ROW_START_CHARPOS (next))
+         || ((start_charpos > MATRIX_ROW_END_CHARPOS (next)
+              || (start_charpos == MATRIX_ROW_END_CHARPOS (next)
+                  && !next->ends_at_zv_p
+                  && !MATRIX_ROW_ENDS_IN_MIDDLE_OF_CHAR_P (next)))
+             && (end_charpos > MATRIX_ROW_END_CHARPOS (next)
+                 || (end_charpos == MATRIX_ROW_END_CHARPOS (next)
+                     && !next->ends_at_zv_p
+                     && !MATRIX_ROW_ENDS_IN_MIDDLE_OF_CHAR_P (next)))))
+       {
+         *end = row;
+         break;
+       }
+       else
+       {
+         /* If the next row's edges intersect [START_CHARPOS..END_CHARPOS],
+            but none of the characters it displays are in the range, it is
+            also END + 1. */
+         struct glyph *g = next->glyphs[TEXT_AREA];
+         struct glyph *e = g + next->used[TEXT_AREA];
  
+         while (g < e)
+           {
+             if (BUFFERP (g->object)
+                 && start_charpos <= g->charpos && g->charpos < end_charpos)
+               break;
+             g++;
+           }
+         if (g == e)
+           {
+             *end = row;
+             break;
+           }
+       }
+     }
+ }
  
\f
  /* This function sets the mouse_face_* elements of DPYINFO, assuming
     the mouse cursor is on a glyph with buffer charpos MOUSE_CHARPOS in
     window WINDOW.  START_CHARPOS and END_CHARPOS are buffer positions
@@@ -23766,158 -24022,300 +23951,300 @@@ mouse_face_from_buffer_pos (Lisp_Objec
  {
    struct window *w = XWINDOW (window);
    struct glyph_row *first = MATRIX_FIRST_TEXT_ROW (w->current_matrix);
-   struct glyph_row *row;
+   struct glyph_row *r1, *r2;
    struct glyph *glyph, *end;
-   EMACS_INT ignore;
+   EMACS_INT ignore, pos;
    int x;
  
    xassert (NILP (display_string) || STRINGP (display_string));
    xassert (NILP (before_string) || STRINGP (before_string));
    xassert (NILP (after_string) || STRINGP (after_string));
  
-   /* Find the first highlighted glyph.  */
-   if (start_charpos < MATRIX_ROW_START_CHARPOS (first))
+   /* Find the rows corresponding to START_CHARPOS and END_CHARPOS.  */
+   rows_from_pos_range (w, start_charpos, end_charpos, &r1, &r2);
+   if (r1 == NULL)
+     r1 = MATRIX_ROW (w->current_matrix, XFASTINT (w->window_end_vpos));
+   /* If the before-string or display-string contains newlines,
+      rows_from_pos_range skips to its last row.  Move back.  */
+   if (!NILP (before_string) || !NILP (display_string))
+     {
+       struct glyph_row *prev;
+       while ((prev = r1 - 1, prev >= first)
+            && MATRIX_ROW_END_CHARPOS (prev) == start_charpos
+            && prev->used[TEXT_AREA] > 0)
+       {
+         struct glyph *beg = prev->glyphs[TEXT_AREA];
+         glyph = beg + prev->used[TEXT_AREA];
+         while (--glyph >= beg && INTEGERP (glyph->object));
+         if (glyph < beg
+             || !(EQ (glyph->object, before_string)
+                  || EQ (glyph->object, display_string)))
+           break;
+         r1 = prev;
+       }
+     }
+   if (r2 == NULL)
      {
-       dpyinfo->mouse_face_beg_col = 0;
-       dpyinfo->mouse_face_beg_row = MATRIX_ROW_VPOS (first, w->current_matrix);
-       dpyinfo->mouse_face_beg_x = first->x;
-       dpyinfo->mouse_face_beg_y = first->y;
+       r2 = MATRIX_ROW (w->current_matrix, XFASTINT (w->window_end_vpos));
+       dpyinfo->mouse_face_past_end = 1;
      }
-   else
+   else if (!NILP (after_string))
      {
-       row = row_containing_pos (w, start_charpos, first, NULL, 0);
-       if (row == NULL)
-       row = MATRIX_ROW (w->current_matrix, XFASTINT (w->window_end_vpos));
-       /* If the before-string or display-string contains newlines,
-        row_containing_pos skips to its last row.  Move back.  */
-       if (!NILP (before_string) || !NILP (display_string))
-       {
-         struct glyph_row *prev;
-         while ((prev = row - 1, prev >= first)
-                && MATRIX_ROW_END_CHARPOS (prev) == start_charpos
-                && prev->used[TEXT_AREA] > 0)
-           {
-             struct glyph *beg = prev->glyphs[TEXT_AREA];
-             glyph = beg + prev->used[TEXT_AREA];
-             while (--glyph >= beg && INTEGERP (glyph->object));
-             if (glyph < beg
-                 || !(EQ (glyph->object, before_string)
-                      || EQ (glyph->object, display_string)))
-               break;
-             row = prev;
-           }
-       }
+       /* If the after-string has newlines, advance to its last row.  */
+       struct glyph_row *next;
+       struct glyph_row *last
+       = MATRIX_ROW (w->current_matrix, XFASTINT (w->window_end_vpos));
  
-       glyph = row->glyphs[TEXT_AREA];
-       end = glyph + row->used[TEXT_AREA];
-       x = row->x;
-       dpyinfo->mouse_face_beg_y = row->y;
-       dpyinfo->mouse_face_beg_row = MATRIX_ROW_VPOS (row, w->current_matrix);
+       for (next = r2 + 1;
+          next <= last
+            && next->used[TEXT_AREA] > 0
+            && EQ (next->glyphs[TEXT_AREA]->object, after_string);
+          ++next)
+       r2 = next;
+     }
+   /* The rest of the display engine assumes that mouse_face_beg_row is
+      either above below mouse_face_end_row or identical to it.  But
+      with bidi-reordered continued lines, the row for START_CHARPOS
+      could be below the row for END_CHARPOS.  If so, swap the rows and
+      store them in correct order.  */
+   if (r1->y > r2->y)
+     {
+       struct glyph_row *tem = r2;
+       r2 = r1;
+       r1 = tem;
+     }
+   dpyinfo->mouse_face_beg_y = r1->y;
+   dpyinfo->mouse_face_beg_row = MATRIX_ROW_VPOS (r1, w->current_matrix);
+   dpyinfo->mouse_face_end_y = r2->y;
+   dpyinfo->mouse_face_end_row = MATRIX_ROW_VPOS (r2, w->current_matrix);
+   /* For a bidi-reordered row, the positions of BEFORE_STRING,
+      AFTER_STRING, DISPLAY_STRING, START_CHARPOS, and END_CHARPOS
+      could be anywhere in the row and in any order.  The strategy
+      below is to find the leftmost and the rightmost glyph that
+      belongs to either of these 3 strings, or whose position is
+      between START_CHARPOS and END_CHARPOS, and highlight all the
+      glyphs between those two.  This may cover more than just the text
+      between START_CHARPOS and END_CHARPOS if the range of characters
+      strides the bidi level boundary, e.g. if the beginning is in R2L
+      text while the end is in L2R text or vice versa.  */
+   if (!r1->reversed_p)
+     {
+       /* This row is in a left to right paragraph.  Scan it left to
+        right.  */
+       glyph = r1->glyphs[TEXT_AREA];
+       end = glyph + r1->used[TEXT_AREA];
+       x = r1->x;
  
        /* Skip truncation glyphs at the start of the glyph row.  */
-       if (row->displays_text_p)
+       if (r1->displays_text_p)
        for (; glyph < end
               && INTEGERP (glyph->object)
               && glyph->charpos < 0;
             ++glyph)
          x += glyph->pixel_width;
  
-       /* Scan the glyph row, stopping before BEFORE_STRING or
-        DISPLAY_STRING or START_CHARPOS.  */
+       /* Scan the glyph row, looking for BEFORE_STRING, AFTER_STRING,
+        or DISPLAY_STRING, and the first glyph from buffer whose
+        position is between START_CHARPOS and END_CHARPOS.  */
        for (; glyph < end
             && !INTEGERP (glyph->object)
-            && !EQ (glyph->object, before_string)
             && !EQ (glyph->object, display_string)
             && !(BUFFERP (glyph->object)
-                 && glyph->charpos >= start_charpos);
+                 && (glyph->charpos >= start_charpos
+                     && glyph->charpos < end_charpos));
           ++glyph)
-       x += glyph->pixel_width;
+       {
+         /* BEFORE_STRING or AFTER_STRING are only relevant if they
+            are present at buffer positions between START_CHARPOS and
+            END_CHARPOS, or if they come from an overlay.  */
+         if (EQ (glyph->object, before_string))
+           {
+             pos = string_buffer_position (w, before_string,
+                                           start_charpos);
+             /* If pos == 0, it means before_string came from an
+                overlay, not from a buffer position.  */
+             if (!pos || pos >= start_charpos && pos < end_charpos)
+               break;
+           }
+         else if (EQ (glyph->object, after_string))
+           {
+             pos = string_buffer_position (w, after_string, end_charpos);
+             if (!pos || pos >= start_charpos && pos < end_charpos)
+               break;
+           }
+         x += glyph->pixel_width;
+       }
        dpyinfo->mouse_face_beg_x = x;
-       dpyinfo->mouse_face_beg_col = glyph - row->glyphs[TEXT_AREA];
+       dpyinfo->mouse_face_beg_col = glyph - r1->glyphs[TEXT_AREA];
      }
-   /* Find the last highlighted glyph.  */
-   row = row_containing_pos (w, end_charpos, first, NULL, 0);
-   if (row == NULL)
-     {
-       row = MATRIX_ROW (w->current_matrix, XFASTINT (w->window_end_vpos));
-       dpyinfo->mouse_face_past_end = 1;
-     }
-   else if (!NILP (after_string))
+   else
      {
-       /* If the after-string has newlines, advance to its last row.  */
-       struct glyph_row *next;
-       struct glyph_row *last
-       = MATRIX_ROW (w->current_matrix, XFASTINT (w->window_end_vpos));
+       /* This row is in a right to left paragraph.  Scan it right to
+        left.  */
+       struct glyph *g;
  
-       for (next = row + 1;
-          next <= last
-            && next->used[TEXT_AREA] > 0
-            && EQ (next->glyphs[TEXT_AREA]->object, after_string);
-          ++next)
-       row = next;
-     }
+       end = r1->glyphs[TEXT_AREA] - 1;
+       glyph = end + r1->used[TEXT_AREA];
  
-   glyph = row->glyphs[TEXT_AREA];
-   end = glyph + row->used[TEXT_AREA];
-   x = row->x;
-   dpyinfo->mouse_face_end_y = row->y;
-   dpyinfo->mouse_face_end_row = MATRIX_ROW_VPOS (row, w->current_matrix);
+       /* Skip truncation glyphs at the start of the glyph row.  */
+       if (r1->displays_text_p)
+       for (; glyph > end
+              && INTEGERP (glyph->object)
+              && glyph->charpos < 0;
+            --glyph)
+         ;
  
-   /* Skip truncation glyphs at the start of the row.  */
-   if (row->displays_text_p)
-     for (; glyph < end
-          && INTEGERP (glyph->object)
-          && glyph->charpos < 0;
-        ++glyph)
-       x += glyph->pixel_width;
-   /* Scan the glyph row, stopping at END_CHARPOS or when we encounter
-      AFTER_STRING.  */
-   for (; glyph < end
-        && !INTEGERP (glyph->object)
-        && !EQ (glyph->object, after_string)
-        && !(BUFFERP (glyph->object) && glyph->charpos >= end_charpos);
-        ++glyph)
-     x += glyph->pixel_width;
+       /* Scan the glyph row, looking for BEFORE_STRING, AFTER_STRING,
+        or DISPLAY_STRING, and the first glyph from buffer whose
+        position is between START_CHARPOS and END_CHARPOS.  */
+       for (; glyph > end
+            && !INTEGERP (glyph->object)
+            && !EQ (glyph->object, display_string)
+            && !(BUFFERP (glyph->object)
+                 && (glyph->charpos >= start_charpos
+                     && glyph->charpos < end_charpos));
+          --glyph)
+       {
+         /* BEFORE_STRING or AFTER_STRING are only relevant if they
+            are present at buffer positions between START_CHARPOS and
+            END_CHARPOS, or if they come from an overlay.  */
+         if (EQ (glyph->object, before_string))
+           {
+             pos = string_buffer_position (w, before_string, start_charpos);
+             /* If pos == 0, it means before_string came from an
+                overlay, not from a buffer position.  */
+             if (!pos || pos >= start_charpos && pos < end_charpos)
+               break;
+           }
+         else if (EQ (glyph->object, after_string))
+           {
+             pos = string_buffer_position (w, after_string, end_charpos);
+             if (!pos || pos >= start_charpos && pos < end_charpos)
+               break;
+           }
+       }
+       glyph++; /* first glyph to the right of the highlighted area */
+       for (g = r1->glyphs[TEXT_AREA], x = r1->x; g < glyph; g++)
+       x += g->pixel_width;
+       dpyinfo->mouse_face_beg_x = x;
+       dpyinfo->mouse_face_beg_col = glyph - r1->glyphs[TEXT_AREA];
+     }
  
-   /* If we found AFTER_STRING, consume it and stop.  */
-   if (EQ (glyph->object, after_string))
+   /* If the highlight ends in a different row, compute GLYPH and END
+      for the end row.  Otherwise, reuse the values computed above for
+      the row where the highlight begins.  */
+   if (r2 != r1)
      {
-       for (; EQ (glyph->object, after_string) && glyph < end; ++glyph)
+       if (!r2->reversed_p)
+       {
+         glyph = r2->glyphs[TEXT_AREA];
+         end = glyph + r2->used[TEXT_AREA];
+         x = r2->x;
+       }
+       else
+       {
+         end = r2->glyphs[TEXT_AREA] - 1;
+         glyph = end + r2->used[TEXT_AREA];
+       }
+     }
+   if (!r2->reversed_p)
+     {
+       /* Skip truncation and continuation glyphs near the end of the
+        row, and also blanks and stretch glyphs inserted by
+        extend_face_to_end_of_line.  */
+       while (end > glyph
+            && INTEGERP ((end - 1)->object)
+            && (end - 1)->charpos <= 0)
+       --end;
+       /* Scan the rest of the glyph row from the end, looking for the
+        first glyph that comes from BEFORE_STRING, AFTER_STRING, or
+        DISPLAY_STRING, or whose position is between START_CHARPOS
+        and END_CHARPOS */
+       for (--end;
+            end > glyph
+            && !INTEGERP (end->object)
+            && !EQ (end->object, display_string)
+            && !(BUFFERP (end->object)
+                 && (end->charpos >= start_charpos
+                     && end->charpos < end_charpos));
+          --end)
+       {
+         /* BEFORE_STRING or AFTER_STRING are only relevant if they
+            are present at buffer positions between START_CHARPOS and
+            END_CHARPOS, or if they come from an overlay.  */
+         if (EQ (end->object, before_string))
+           {
+             pos = string_buffer_position (w, before_string, start_charpos);
+             if (!pos || pos >= start_charpos && pos < end_charpos)
+               break;
+           }
+         else if (EQ (end->object, after_string))
+           {
+             pos = string_buffer_position (w, after_string, end_charpos);
+             if (!pos || pos >= start_charpos && pos < end_charpos)
+               break;
+           }
+       }
+       /* Find the X coordinate of the last glyph to be highlighted.  */
+       for (; glyph <= end; ++glyph)
        x += glyph->pixel_width;
+       dpyinfo->mouse_face_end_x = x;
+       dpyinfo->mouse_face_end_col = glyph - r2->glyphs[TEXT_AREA];
      }
    else
      {
-       /* If there's no after-string, we must check if we overshot,
-        which might be the case if we stopped after a string glyph.
-        That glyph may belong to a before-string or display-string
-        associated with the end position, which must not be
-        highlighted.  */
-       Lisp_Object prev_object;
-       EMACS_INT pos;
-       while (glyph > row->glyphs[TEXT_AREA])
-       {
-         prev_object = (glyph - 1)->object;
-         if (!STRINGP (prev_object) || EQ (prev_object, display_string))
-           break;
-         pos = string_buffer_position (w, prev_object, end_charpos);
-         if (pos && pos < end_charpos)
-           break;
-         for (; glyph > row->glyphs[TEXT_AREA]
-                && EQ ((glyph - 1)->object, prev_object);
-              --glyph)
-           x -= (glyph - 1)->pixel_width;
+       /* Skip truncation and continuation glyphs near the end of the
+        row, and also blanks and stretch glyphs inserted by
+        extend_face_to_end_of_line.  */
+       x = r2->x;
+       end++;
+       while (end < glyph
+            && INTEGERP (end->object)
+            && end->charpos <= 0)
+       {
+         x += end->pixel_width;
+         ++end;
+       }
+       /* Scan the rest of the glyph row from the end, looking for the
+        first glyph that comes from BEFORE_STRING, AFTER_STRING, or
+        DISPLAY_STRING, or whose position is between START_CHARPOS
+        and END_CHARPOS */
+       for ( ;
+            end < glyph
+            && !INTEGERP (end->object)
+            && !EQ (end->object, display_string)
+            && !(BUFFERP (end->object)
+                 && (end->charpos >= start_charpos
+                     && end->charpos < end_charpos));
+          ++end)
+       {
+         /* BEFORE_STRING or AFTER_STRING are only relevant if they
+            are present at buffer positions between START_CHARPOS and
+            END_CHARPOS, or if they come from an overlay.  */
+         if (EQ (end->object, before_string))
+           {
+             pos = string_buffer_position (w, before_string, start_charpos);
+             if (!pos || pos >= start_charpos && pos < end_charpos)
+               break;
+           }
+         else if (EQ (end->object, after_string))
+           {
+             pos = string_buffer_position (w, after_string, end_charpos);
+             if (!pos || pos >= start_charpos && pos < end_charpos)
+               break;
+           }
+         x += end->pixel_width;
        }
+       dpyinfo->mouse_face_end_x = x;
+       dpyinfo->mouse_face_end_col = end - r2->glyphs[TEXT_AREA];
      }
  
-   dpyinfo->mouse_face_end_x = x;
-   dpyinfo->mouse_face_end_col = glyph - row->glyphs[TEXT_AREA];
    dpyinfo->mouse_face_window = window;
    dpyinfo->mouse_face_face_id
      = face_at_buffer_position (w, mouse_charpos, 0, 0, &ignore,
    show_mouse_face (dpyinfo, DRAW_MOUSE_FACE);
  }
  
+ /* The following function is not used anymore (replaced with
+    mouse_face_from_string_pos), but I leave it here for the time
+    being, in case someone would.  */
+ #if 0 /* not used */
  
  /* Find the position of the glyph for position POS in OBJECT in
     window W's current matrix, and return in *X, *Y the pixel
@@@ -24003,7 -24406,130 +24335,130 @@@ fast_find_string_pos (struct window *w
  
    return best_glyph != NULL;
  }
+ #endif        /* not used */
+ /* Find the positions of the first and the last glyphs in window W's
+    current matrix that occlude positions [STARTPOS..ENDPOS] in OBJECT
+    (assumed to be a string), and return in DPYINFO's mouse_face
+    members the pixel and column/row coordinates of those glyphs.  */
+ static void
+ mouse_face_from_string_pos (struct window *w, Display_Info *dpyinfo,
+                           Lisp_Object object,
+                           EMACS_INT startpos, EMACS_INT endpos)
+ {
+   int yb = window_text_bottom_y (w);
+   struct glyph_row *r;
+   struct glyph *g, *e;
+   int gx;
+   int found = 0;
+   /* Find the glyph row with at least one position in the range
+      [STARTPOS..ENDPOS], and the first glyph in that row whose
+      position belongs to that range.  */
+   for (r = MATRIX_FIRST_TEXT_ROW (w->current_matrix);
+        r->enabled_p && r->y < yb;
+        ++r)
+     {
+       if (!r->reversed_p)
+       {
+         g = r->glyphs[TEXT_AREA];
+         e = g + r->used[TEXT_AREA];
+         for (gx = r->x; g < e; gx += g->pixel_width, ++g)
+           if (EQ (g->object, object)
+               && startpos <= g->charpos && g->charpos <= endpos)
+             {
+               dpyinfo->mouse_face_beg_row = r - w->current_matrix->rows;
+               dpyinfo->mouse_face_beg_y = r->y;
+               dpyinfo->mouse_face_beg_col = g - r->glyphs[TEXT_AREA];
+               dpyinfo->mouse_face_beg_x = gx;
+               found = 1;
+               break;
+             }
+       }
+       else
+       {
+         struct glyph *g1;
+         e = r->glyphs[TEXT_AREA];
+         g = e + r->used[TEXT_AREA];
+         for ( ; g > e; --g)
+           if (EQ ((g-1)->object, object)
+               && startpos <= (g-1)->charpos && (g-1)->charpos <= endpos)
+             {
+               dpyinfo->mouse_face_beg_row = r - w->current_matrix->rows;
+               dpyinfo->mouse_face_beg_y = r->y;
+               dpyinfo->mouse_face_beg_col = g - r->glyphs[TEXT_AREA];
+               for (gx = r->x, g1 = r->glyphs[TEXT_AREA]; g1 < g; ++g1)
+                 gx += g1->pixel_width;
+               dpyinfo->mouse_face_beg_x = gx;
+               found = 1;
+               break;
+             }
+       }
+       if (found)
+       break;
+     }
+   if (!found)
+     return;
  
+   /* Starting with the next row, look for the first row which does NOT
+      include any glyphs whose positions are in the range.  */
+   for (++r; r->enabled_p && r->y < yb; ++r)
+     {
+       g = r->glyphs[TEXT_AREA];
+       e = g + r->used[TEXT_AREA];
+       found = 0;
+       for ( ; g < e; ++g)
+       if (EQ (g->object, object)
+           && startpos <= g->charpos && g->charpos <= endpos)
+         {
+           found = 1;
+           break;
+         }
+       if (!found)
+       break;
+     }
+   /* The highlighted region ends on the previous row.  */
+   r--;
+   /* Set the end row and its vertical pixel coordinate.  */
+   dpyinfo->mouse_face_end_row = r - w->current_matrix->rows;
+   dpyinfo->mouse_face_end_y = r->y;
+   /* Compute and set the end column and the end column's horizontal
+      pixel coordinate.  */
+   if (!r->reversed_p)
+     {
+       g = r->glyphs[TEXT_AREA];
+       e = g + r->used[TEXT_AREA];
+       for ( ; e > g; --e)
+       if (EQ ((e-1)->object, object)
+           && startpos <= (e-1)->charpos && (e-1)->charpos <= endpos)
+         break;
+       dpyinfo->mouse_face_end_col = e - g;
+       for (gx = r->x; g < e; ++g)
+       gx += g->pixel_width;
+       dpyinfo->mouse_face_end_x = gx;
+     }
+   else
+     {
+       e = r->glyphs[TEXT_AREA];
+       g = e + r->used[TEXT_AREA];
+       for (gx = r->x ; e < g; ++e)
+       {
+         if (EQ (e->object, object)
+             && startpos <= e->charpos && e->charpos <= endpos)
+           break;
+         gx += e->pixel_width;
+       }
+       dpyinfo->mouse_face_end_col = e - r->glyphs[TEXT_AREA];
+       dpyinfo->mouse_face_end_x = gx;
+     }
+ }
  
  /* See if position X, Y is within a hot-spot of an image.  */
  
@@@ -24190,8 -24716,7 +24645,8 @@@ note_mode_line_or_margin_highlight (Lis
    Display_Info *dpyinfo = FRAME_X_DISPLAY_INFO (f);
    Cursor cursor = FRAME_X_OUTPUT (f)->nontext_cursor;
    Lisp_Object pointer = Qnil;
 -  int charpos, dx, dy, width, height;
 +  int dx, dy, width, height;
 +  EMACS_INT charpos;
    Lisp_Object string, object = Qnil;
    Lisp_Object pos, help;
  
        int x0;
        struct glyph *end;
  
+       /* Kludge alert: mode_line_string takes X/Y in pixels, but
+        returns them in row/column units!  */
        string = mode_line_string (w, area, &x, &y, &charpos,
                                 &object, &dx, &dy, &width, &height);
  
             ? MATRIX_MODE_LINE_ROW (w->current_matrix)
             : MATRIX_HEADER_LINE_ROW (w->current_matrix));
  
-       /* Find glyph */
+       /* Find the glyph under the mouse pointer.  */
        if (row->mode_line_p && row->enabled_p)
        {
          glyph = row_start_glyph = row->glyphs[TEXT_AREA];
    else
      {
        x -= WINDOW_LEFT_SCROLL_BAR_AREA_WIDTH (w);
+       /* Kludge alert: marginal_area_string takes X/Y in pixels, but
+        returns them in row/column units!  */
        string = marginal_area_string (w, area, &x, &y, &charpos,
                                     &object, &dx, &dy, &width, &height);
      }
          int gpos;
          int gseq_length;
          int total_pixel_width;
-         EMACS_INT ignore;
+         EMACS_INT begpos, endpos, ignore;
  
          int vpos, hpos;
  
          b = Fprevious_single_property_change (make_number (charpos + 1),
                                                Qmouse_face, string, Qnil);
          if (NILP (b))
-           b = make_number (0);
+           begpos = 0;
+         else
+           begpos = XINT (b);
  
          e = Fnext_single_property_change (pos, Qmouse_face, string, Qnil);
          if (NILP (e))
-           e = make_number (SCHARS (string));
-         /* Calculate the position(glyph position: GPOS) of GLYPH in
-            displayed string. GPOS is different from CHARPOS.
-            CHARPOS is the position of glyph in internal string
-            object. A mode line string format has structures which
-            is converted to a flatten by emacs lisp interpreter.
-            The internal string is an element of the structures.
-            The displayed string is the flatten string. */
-         gpos = 0;
-         if (glyph > row_start_glyph)
-           {
-             tmp_glyph = glyph - 1;
-             while (tmp_glyph >= row_start_glyph
-                    && tmp_glyph->charpos >= XINT (b)
-                    && EQ (tmp_glyph->object, glyph->object))
-               {
-                 tmp_glyph--;
-                 gpos++;
-               }
-           }
-         /* Calculate the lenght(glyph sequence length: GSEQ_LENGTH) of
-            displayed string holding GLYPH.
-            GSEQ_LENGTH is different from SCHARS (STRING).
-            SCHARS (STRING) returns the length of the internal string. */
-         for (tmp_glyph = glyph, gseq_length = gpos;
-              tmp_glyph->charpos < XINT (e);
-              tmp_glyph++, gseq_length++)
-             {
-               if (!EQ (tmp_glyph->object, glyph->object))
-                 break;
-             }
+           endpos = SCHARS (string);
+         else
+           endpos = XINT (e);
+         /* Calculate the glyph position GPOS of GLYPH in the
+            displayed string, relative to the beginning of the
+            highlighted part of the string.
+            Note: GPOS is different from CHARPOS.  CHARPOS is the
+            position of GLYPH in the internal string object.  A mode
+            line string format has structures which are converted to
+            a flattened string by the Emacs Lisp interpreter.  The
+            internal string is an element of those structures.  The
+            displayed string is the flattened string.  */
+         tmp_glyph = row_start_glyph;
+         while (tmp_glyph < glyph
+                && (!(EQ (tmp_glyph->object, glyph->object)
+                      && begpos <= tmp_glyph->charpos
+                      && tmp_glyph->charpos < endpos)))
+           tmp_glyph++;
+         gpos = glyph - tmp_glyph;
+         /* Calculate the length GSEQ_LENGTH of the glyph sequence of
+            the highlighted part of the displayed string to which
+            GLYPH belongs.  Note: GSEQ_LENGTH is different from
+            SCHARS (STRING), because the latter returns the length of
+            the internal string.  */
+         for (tmp_glyph = row->glyphs[TEXT_AREA] + row->used[TEXT_AREA] - 1;
+              tmp_glyph > glyph
+                && (!(EQ (tmp_glyph->object, glyph->object)
+                      && begpos <= tmp_glyph->charpos
+                      && tmp_glyph->charpos < endpos));
+              tmp_glyph--)
+           ;
+         gseq_length = gpos + (tmp_glyph - glyph) + 1;
  
+         /* Calculate the total pixel width of all the glyphs between
+            the beginning of the highlighted area and GLYPH.  */
          total_pixel_width = 0;
          for (tmp_glyph = glyph - gpos; tmp_glyph != glyph; tmp_glyph++)
            total_pixel_width += tmp_glyph->pixel_width;
  
-         /* Pre calculation of re-rendering position */
-         vpos = (x - gpos);
-         hpos = (area == ON_MODE_LINE
+         /* Pre calculation of re-rendering position.  Note: X is in
+            column units here, after the call to mode_line_string or
+            marginal_area_string.  */
+         hpos = x - gpos;
+         vpos = (area == ON_MODE_LINE
                  ? (w->current_matrix)->nrows - 1
                  : 0);
  
-         /* If the re-rendering position is included in the last
-            re-rendering area, we should do nothing. */
+         /* If GLYPH's position is included in the region that is
+            already drawn in mouse face, we have nothing to do.  */
          if ( EQ (window, dpyinfo->mouse_face_window)
-              && dpyinfo->mouse_face_beg_col <= vpos
-              && vpos < dpyinfo->mouse_face_end_col
-              && dpyinfo->mouse_face_beg_row == hpos )
+              && (!row->reversed_p
+                  ? (dpyinfo->mouse_face_beg_col <= hpos
+                     && hpos < dpyinfo->mouse_face_end_col)
+                  /* In R2L rows we swap BEG and END, see below.  */
+                  : (dpyinfo->mouse_face_end_col <= hpos
+                     && hpos < dpyinfo->mouse_face_beg_col))
+              && dpyinfo->mouse_face_beg_row == vpos )
            return;
  
          if (clear_mouse_face (dpyinfo))
            cursor = No_Cursor;
  
-         dpyinfo->mouse_face_beg_col = vpos;
-         dpyinfo->mouse_face_beg_row = hpos;
-         dpyinfo->mouse_face_beg_x   = original_x_pixel - (total_pixel_width + dx);
-         dpyinfo->mouse_face_beg_y   = 0;
-         dpyinfo->mouse_face_end_col = vpos + gseq_length;
-         dpyinfo->mouse_face_end_row = dpyinfo->mouse_face_beg_row;
-         dpyinfo->mouse_face_end_x   = 0;
-         dpyinfo->mouse_face_end_y   = 0;
+         if (!row->reversed_p)
+           {
+             dpyinfo->mouse_face_beg_col = hpos;
+             dpyinfo->mouse_face_beg_x   = original_x_pixel
+                                           - (total_pixel_width + dx);
+             dpyinfo->mouse_face_end_col = hpos + gseq_length;
+             dpyinfo->mouse_face_end_x   = 0;
+           }
+         else
+           {
+             /* In R2L rows, show_mouse_face expects BEG and END
+                coordinates to be swapped.  */
+             dpyinfo->mouse_face_end_col = hpos;
+             dpyinfo->mouse_face_end_x   = original_x_pixel
+                                           - (total_pixel_width + dx);
+             dpyinfo->mouse_face_beg_col = hpos + gseq_length;
+             dpyinfo->mouse_face_beg_x   = 0;
+           }
  
+         dpyinfo->mouse_face_beg_row  = vpos;
+         dpyinfo->mouse_face_end_row  = dpyinfo->mouse_face_beg_row;
+         dpyinfo->mouse_face_beg_y    = 0;
+         dpyinfo->mouse_face_end_y    = 0;
          dpyinfo->mouse_face_past_end = 0;
-         dpyinfo->mouse_face_window  = window;
+         dpyinfo->mouse_face_window   = window;
  
          dpyinfo->mouse_face_face_id = face_at_string_position (w, string,
                                                                 charpos,
-                                                                0, 0, 0, &ignore,
-                                                                glyph->face_id, 1);
+                                                                0, 0, 0,
+                                                                &ignore,
+                                                                glyph->face_id,
+                                                                1);
          show_mouse_face (dpyinfo, DRAW_MOUSE_FACE);
  
          if (NILP (pointer))
@@@ -24522,8 -25074,7 +25004,8 @@@ note_mouse_highlight (struct frame *f, 
        Lisp_Object *overlay_vec = NULL;
        int noverlays;
        struct buffer *obuf;
 -      int obegv, ozv, same_region;
 +      EMACS_INT obegv, ozv;
 +      int same_region;
  
        /* Find the glyph under X/Y.  */
        glyph = x_y_to_hpos_vpos (w, x, y, &hpos, &vpos, &dx, &dy, &area);
              if ((image_map = Fplist_get (XCDR (img->spec), QCmap),
                   !NILP (image_map))
                  && (hotspot = find_hot_spot (image_map,
 -                                             glyph->slice.x + dx,
 -                                             glyph->slice.y + dy),
 +                                             glyph->slice.img.x + dx,
 +                                             glyph->slice.img.y + dy),
                      CONSP (hotspot))
                  && (hotspot = XCDR (hotspot), CONSP (hotspot)))
                {
        /* Clear mouse face if X/Y not over text.  */
        if (glyph == NULL
          || area != TEXT_AREA
-         || !MATRIX_ROW (w->current_matrix, vpos)->displays_text_p)
+         || !MATRIX_ROW (w->current_matrix, vpos)->displays_text_p
+         /* R2L rows have a stretch glyph at their front, which
+            stands for no text, whereas L2R rows have no glyphs at
+            all beyond the end of text.  Treat such stretch glyphs
+            like we do with NULL glyphs in L2R rows.  */
+         || (MATRIX_ROW (w->current_matrix, vpos)->reversed_p
+             && glyph == MATRIX_ROW (w->current_matrix, vpos)->glyphs[TEXT_AREA]
+             && glyph->type == STRETCH_GLYPH
+             && glyph->avoid_cursor_p))
        {
          if (clear_mouse_face (dpyinfo))
            cursor = No_Cursor;
        else
        noverlays = 0;
  
-       same_region = (EQ (window, dpyinfo->mouse_face_window)
-                    && vpos >= dpyinfo->mouse_face_beg_row
-                    && vpos <= dpyinfo->mouse_face_end_row
-                    && (vpos > dpyinfo->mouse_face_beg_row
-                        || hpos >= dpyinfo->mouse_face_beg_col)
-                    && (vpos < dpyinfo->mouse_face_end_row
-                        || hpos < dpyinfo->mouse_face_end_col
-                        || dpyinfo->mouse_face_past_end));
+       same_region = coords_in_mouse_face_p (w, hpos, vpos);
  
        if (same_region)
        cursor = No_Cursor;
                b = make_number (0);
              if (NILP (e))
                e = make_number (SCHARS (object) - 1);
-             fast_find_string_pos (w, XINT (b), object,
-                                   &dpyinfo->mouse_face_beg_col,
-                                   &dpyinfo->mouse_face_beg_row,
-                                   &dpyinfo->mouse_face_beg_x,
-                                   &dpyinfo->mouse_face_beg_y, 0);
-             fast_find_string_pos (w, XINT (e), object,
-                                   &dpyinfo->mouse_face_end_col,
-                                   &dpyinfo->mouse_face_end_row,
-                                   &dpyinfo->mouse_face_end_x,
-                                   &dpyinfo->mouse_face_end_y, 1);
+             mouse_face_from_string_pos (w, dpyinfo, object,
+                                         XINT (b), XINT (e));
              dpyinfo->mouse_face_past_end = 0;
              dpyinfo->mouse_face_window = window;
              dpyinfo->mouse_face_face_id
                  /* If we are on a display string with no mouse-face,
                     check if the text under it has one.  */
                  struct glyph_row *r = MATRIX_ROW (w->current_matrix, vpos);
 -                int start = MATRIX_ROW_START_CHARPOS (r);
 +                EMACS_INT start = MATRIX_ROW_START_CHARPOS (r);
                  pos = string_buffer_position (w, object, start);
                  if (pos > 0)
                    {
                {
                  Lisp_Object before, after;
                  Lisp_Object before_string, after_string;
+                 /* To correctly find the limits of mouse highlight
+                    in a bidi-reordered buffer, we must not use the
+                    optimization of limiting the search in
+                    previous-single-property-change and
+                    next-single-property-change, because
+                    rows_from_pos_range needs the real start and end
+                    positions to DTRT in this case.  That's because
+                    the first row visible in a window does not
+                    necessarily display the character whose position
+                    is the smallest.  */
+                 Lisp_Object lim1 =
+                   NILP (XBUFFER (buffer)->bidi_display_reordering)
+                   ? Fmarker_position (w->start)
+                   : Qnil;
+                 Lisp_Object lim2 =
+                   NILP (XBUFFER (buffer)->bidi_display_reordering)
+                   ? make_number (BUF_Z (XBUFFER (buffer))
+                                  - XFASTINT (w->window_end_pos))
+                   : Qnil;
  
                  if (NILP (overlay))
                    {
                      /* Handle the text property case.  */
                      before = Fprevious_single_property_change
-                       (make_number (pos + 1), Qmouse_face, buffer,
-                        Fmarker_position (w->start));
+                       (make_number (pos + 1), Qmouse_face, buffer, lim1);
                      after = Fnext_single_property_change
-                       (make_number (pos), Qmouse_face, buffer,
-                        make_number (BUF_Z (XBUFFER (buffer))
-                                     - XFASTINT (w->window_end_pos)));
+                       (make_number (pos), Qmouse_face, buffer, lim2);
                      before_string = after_string = Qnil;
                    }
                  else
        else
          {
            Lisp_Object object = glyph->object;
 -          int charpos = glyph->charpos;
 +          EMACS_INT charpos = glyph->charpos;
  
            /* Try text properties.  */
            if (STRINGP (object)
                       see if the buffer text ``under'' it does.  */
                    struct glyph_row *r
                      = MATRIX_ROW (w->current_matrix, vpos);
 -                  int start = MATRIX_ROW_START_CHARPOS (r);
 +                  EMACS_INT start = MATRIX_ROW_START_CHARPOS (r);
                    EMACS_INT pos = string_buffer_position (w, object, start);
                    if (pos > 0)
                      {
          if (NILP (pointer))
            {
              Lisp_Object object = glyph->object;
 -            int charpos = glyph->charpos;
 +            EMACS_INT charpos = glyph->charpos;
  
              /* Try text properties.  */
              if (STRINGP (object)
                         see if the buffer text ``under'' it does.  */
                      struct glyph_row *r
                        = MATRIX_ROW (w->current_matrix, vpos);
 -                    int start = MATRIX_ROW_START_CHARPOS (r);
 +                    EMACS_INT start = MATRIX_ROW_START_CHARPOS (r);
                      EMACS_INT pos = string_buffer_position (w, object,
                                                              start);
                      if (pos > 0)