Replace bcopy, bzero, bcmp by memcpy, memmove, memset, memcmp
[bpt/emacs.git] / src / xdisp.c
index 1320b8a..545f597 100644 (file)
@@ -80,7 +80,39 @@ along with GNU Emacs.  If not, see <http://www.gnu.org/licenses/>.  */
    You will find a lot of redisplay optimizations when you start
    looking at the innards of redisplay.  The overall goal of all these
    optimizations is to make redisplay fast because it is done
-   frequently.
+   frequently.  Some of these optimizations are implemented by the
+   following functions:
+
+    . try_cursor_movement
+
+      This function tries to update the display if the text in the
+      window did not change and did not scroll, only point moved, and
+      it did not move off the displayed portion of the text.
+
+    . try_window_reusing_current_matrix
+
+      This function reuses the current matrix of a window when text
+      has not changed, but the window start changed (e.g., due to
+      scrolling).
+
+    . try_window_id
+
+      This function attempts to redisplay a window by reusing parts of
+      its existing display.  It finds and reuses the part that was not
+      changed, and redraws the rest.
+
+    . try_window
+
+      This function performs the full redisplay of a single window
+      assuming that its fonts were not changed and that the cursor
+      will not end up in the scroll margins.  (Loading fonts requires
+      re-adjustment of dimensions of glyph matrices, which makes this
+      method impossible to use.)
+
+   These optimizations are tried in sequence (some can be skipped if
+   it is known that they are not applicable).  If none of the
+   optimizations were successful, redisplay calls redisplay_windows,
+   which performs a full redisplay of all windows.
 
    Desired matrices.
 
@@ -112,13 +144,16 @@ along with GNU Emacs.  If not, see <http://www.gnu.org/licenses/>.  */
    see in dispextern.h.
 
    Glyphs in a desired matrix are normally constructed in a loop
-   calling get_next_display_element and then produce_glyphs.  The call
-   to produce_glyphs will fill the iterator structure with pixel
+   calling get_next_display_element and then PRODUCE_GLYPHS.  The call
+   to PRODUCE_GLYPHS will fill the iterator structure with pixel
    information about the element being displayed and at the same time
    produce glyphs for it.  If the display element fits on the line
    being displayed, set_iterator_to_next is called next, otherwise the
-   glyphs produced are discarded.
-
+   glyphs produced are discarded.  The function display_line is the
+   workhorse of filling glyph rows in the desired matrix with glyphs.
+   In addition to producing glyphs, it also handles line truncation
+   and continuation, word wrap, and cursor positioning (for the
+   latter, see also set_cursor_from_row).
 
    Frame matrices.
 
@@ -139,7 +174,50 @@ along with GNU Emacs.  If not, see <http://www.gnu.org/licenses/>.  */
    wanted to have without having to move many bytes around.  To be
    honest, there is a little bit more done, but not much more.  If you
    plan to extend that code, take a look at dispnew.c.  The function
-   build_frame_matrix is a good starting point.  */
+   build_frame_matrix is a good starting point.
+
+   Bidirectional display.
+
+   Bidirectional display adds quite some hair to this already complex
+   design.  The good news are that a large portion of that hairy stuff
+   is hidden in bidi.c behind only 3 interfaces.  bidi.c implements a
+   reordering engine which is called by set_iterator_to_next and
+   returns the next character to display in the visual order.  See
+   commentary on bidi.c for more details.  As far as redisplay is
+   concerned, the effect of calling bidi_move_to_visually_next, the
+   main interface of the reordering engine, is that the iterator gets
+   magically placed on the buffer or string position that is to be
+   displayed next.  In other words, a linear iteration through the
+   buffer/string is replaced with a non-linear one.  All the rest of
+   the redisplay is oblivious to the bidi reordering.
+
+   Well, almost oblivious---there are still complications, most of
+   them due to the fact that buffer and string positions no longer
+   change monotonously with glyph indices in a glyph row.  Moreover,
+   for continued lines, the buffer positions may not even be
+   monotonously changing with vertical positions.  Also, accounting
+   for face changes, overlays, etc. becomes more complex because
+   non-linear iteration could potentially skip many positions with
+   changes, and then cross them again on the way back...
+
+   One other prominent effect of bidirectional display is that some
+   paragraphs of text need to be displayed starting at the right
+   margin of the window---the so-called right-to-left, or R2L
+   paragraphs.  R2L paragraphs are displayed with R2L glyph rows,
+   which have their reversed_p flag set.  The bidi reordering engine
+   produces characters in such rows starting from the character which
+   should be the rightmost on display.  PRODUCE_GLYPHS then reverses
+   the order, when it fills up the glyph row whose reversed_p flag is
+   set, by prepending each new glyph to what is already there, instead
+   of appending it.  When the glyph row is complete, the function
+   extend_face_to_end_of_line fills the empty space to the left of the
+   leftmost character with special glyphs, which will display as,
+   well, empty.  On text terminals, these special glyphs are simply
+   blank characters.  On graphics terminals, there's a single stretch
+   glyph with suitably computed width.  Both the blanks and the
+   stretch glyph are given the face of the background of the line.
+   This way, the terminal-specific back-end can still draw the glyphs
+   left to right, even for R2L lines.  */
 
 #include <config.h>
 #include <stdio.h>
@@ -192,7 +270,7 @@ along with GNU Emacs.  If not, see <http://www.gnu.org/licenses/>.  */
 
 #if defined (USE_X_TOOLKIT) || defined (HAVE_NTGUI) \
     || defined(HAVE_NS) || defined (USE_GTK)
-extern void set_frame_menubar P_ ((struct frame *f, int, int));
+extern void set_frame_menubar (struct frame *f, int, int);
 extern int pending_menu_activation;
 #endif
 
@@ -279,6 +357,14 @@ EMACS_INT tool_bar_button_relief;
 
 Lisp_Object Vauto_resize_tool_bars;
 
+/* Type of tool bar.  Can be symbols image, text, both or both-hroiz.  */
+
+Lisp_Object Vtool_bar_style;
+
+/* Maximum number of characters a label can have to be shown.  */
+
+EMACS_INT tool_bar_max_label_size;
+
 /* Non-zero means draw block and hollow cursor as wide as the glyph
    under it.  For example, if a block cursor is over a tab, it will be
    drawn as wide as that tab on the display.  */
@@ -364,7 +450,7 @@ Lisp_Object Qescape_glyph;
 Lisp_Object Qnobreak_space;
 
 /* The symbol `image' which is the car of the lists used to represent
-   images in Lisp.  */
+   images in Lisp.  Also a tool bar style.  */
 
 Lisp_Object Qimage;
 
@@ -372,6 +458,9 @@ Lisp_Object Qimage;
 Lisp_Object QCmap, QCpointer;
 Lisp_Object Qrect, Qcircle, Qpoly;
 
+/* Tool bar styles */
+Lisp_Object Qtext, Qboth, Qboth_horiz;
+
 /* Non-zero means print newline to stdout before next mini-buffer
    message.  */
 
@@ -742,15 +831,15 @@ struct props
 
   /* A handler function called to set up iterator IT from the property
      at IT's current position.  Value is used to steer handle_stop.  */
-  enum prop_handled (*handler) P_ ((struct it *it));
+  enum prop_handled (*handler) (struct it *it);
 };
 
-static enum prop_handled handle_face_prop P_ ((struct it *));
-static enum prop_handled handle_invisible_prop P_ ((struct it *));
-static enum prop_handled handle_display_prop P_ ((struct it *));
-static enum prop_handled handle_composition_prop P_ ((struct it *));
-static enum prop_handled handle_overlay_change P_ ((struct it *));
-static enum prop_handled handle_fontified_prop P_ ((struct it *));
+static enum prop_handled handle_face_prop (struct it *);
+static enum prop_handled handle_invisible_prop (struct it *);
+static enum prop_handled handle_display_prop (struct it *);
+static enum prop_handled handle_composition_prop (struct it *);
+static enum prop_handled handle_overlay_change (struct it *);
+static enum prop_handled handle_fontified_prop (struct it *);
 
 /* Properties handled by iterators.  */
 
@@ -860,149 +949,149 @@ Lisp_Object Vhourglass_delay;
 \f
 /* Function prototypes.  */
 
-static void setup_for_ellipsis P_ ((struct it *, int));
-static void mark_window_display_accurate_1 P_ ((struct window *, int));
-static int single_display_spec_string_p P_ ((Lisp_Object, Lisp_Object));
-static int display_prop_string_p P_ ((Lisp_Object, Lisp_Object));
-static int cursor_row_p P_ ((struct window *, struct glyph_row *));
-static int redisplay_mode_lines P_ ((Lisp_Object, int));
-static char *decode_mode_spec_coding P_ ((Lisp_Object, char *, int));
-
-static Lisp_Object get_it_property P_ ((struct it *it, Lisp_Object prop));
-
-static void handle_line_prefix P_ ((struct it *));
-
-static void pint2str P_ ((char *, int, int));
-static void pint2hrstr P_ ((char *, int, int));
-static struct text_pos run_window_scroll_functions P_ ((Lisp_Object,
-                                                       struct text_pos));
-static void reconsider_clip_changes P_ ((struct window *, struct buffer *));
-static int text_outside_line_unchanged_p P_ ((struct window *, int, int));
-static void store_mode_line_noprop_char P_ ((char));
-static int store_mode_line_noprop P_ ((const unsigned char *, int, int));
-static void x_consider_frame_title P_ ((Lisp_Object));
-static void handle_stop P_ ((struct it *));
-static void handle_stop_backwards P_ ((struct it *, EMACS_INT));
-static int tool_bar_lines_needed P_ ((struct frame *, int *));
-static int single_display_spec_intangible_p P_ ((Lisp_Object));
-static void ensure_echo_area_buffers P_ ((void));
-static Lisp_Object unwind_with_echo_area_buffer P_ ((Lisp_Object));
-static Lisp_Object with_echo_area_buffer_unwind_data P_ ((struct window *));
-static int with_echo_area_buffer P_ ((struct window *, int,
-                                     int (*) (EMACS_INT, Lisp_Object, EMACS_INT, EMACS_INT),
-                                     EMACS_INT, Lisp_Object, EMACS_INT, EMACS_INT));
-static void clear_garbaged_frames P_ ((void));
-static int current_message_1 P_ ((EMACS_INT, Lisp_Object, EMACS_INT, EMACS_INT));
-static int truncate_message_1 P_ ((EMACS_INT, Lisp_Object, EMACS_INT, EMACS_INT));
-static int set_message_1 P_ ((EMACS_INT, Lisp_Object, EMACS_INT, EMACS_INT));
-static int display_echo_area P_ ((struct window *));
-static int display_echo_area_1 P_ ((EMACS_INT, Lisp_Object, EMACS_INT, EMACS_INT));
-static int resize_mini_window_1 P_ ((EMACS_INT, Lisp_Object, EMACS_INT, EMACS_INT));
-static Lisp_Object unwind_redisplay P_ ((Lisp_Object));
-static int string_char_and_length P_ ((const unsigned char *, int *));
-static struct text_pos display_prop_end P_ ((struct it *, Lisp_Object,
-                                            struct text_pos));
-static int compute_window_start_on_continuation_line P_ ((struct window *));
-static Lisp_Object safe_eval_handler P_ ((Lisp_Object));
-static void insert_left_trunc_glyphs P_ ((struct it *));
-static struct glyph_row *get_overlay_arrow_glyph_row P_ ((struct window *,
-                                                         Lisp_Object));
-static void extend_face_to_end_of_line P_ ((struct it *));
-static int append_space_for_newline P_ ((struct it *, int));
-static int cursor_row_fully_visible_p P_ ((struct window *, int, int));
-static int try_scrolling P_ ((Lisp_Object, int, EMACS_INT, EMACS_INT, int, int));
-static int try_cursor_movement P_ ((Lisp_Object, struct text_pos, int *));
-static int trailing_whitespace_p P_ ((int));
-static int message_log_check_duplicate P_ ((int, int, int, int));
-static void push_it P_ ((struct it *));
-static void pop_it P_ ((struct it *));
-static void sync_frame_with_window_matrix_rows P_ ((struct window *));
-static void select_frame_for_redisplay P_ ((Lisp_Object));
-static void redisplay_internal P_ ((int));
-static int echo_area_display P_ ((int));
-static void redisplay_windows P_ ((Lisp_Object));
-static void redisplay_window P_ ((Lisp_Object, int));
-static Lisp_Object redisplay_window_error ();
-static Lisp_Object redisplay_window_0 P_ ((Lisp_Object));
-static Lisp_Object redisplay_window_1 P_ ((Lisp_Object));
-static int update_menu_bar P_ ((struct frame *, int, int));
-static int try_window_reusing_current_matrix P_ ((struct window *));
-static int try_window_id P_ ((struct window *));
-static int display_line P_ ((struct it *));
-static int display_mode_lines P_ ((struct window *));
-static int display_mode_line P_ ((struct window *, enum face_id, Lisp_Object));
-static int display_mode_element P_ ((struct it *, int, int, int, Lisp_Object, Lisp_Object, int));
-static int store_mode_line_string P_ ((char *, Lisp_Object, int, int, int, Lisp_Object));
-static char *decode_mode_spec P_ ((struct window *, int, int, int,
-                                  Lisp_Object *));
-static void display_menu_bar P_ ((struct window *));
-static int display_count_lines P_ ((int, int, int, int, int *));
-static int display_string P_ ((unsigned char *, Lisp_Object, Lisp_Object,
-                              EMACS_INT, EMACS_INT, struct it *, int, int, int, int));
-static void compute_line_metrics P_ ((struct it *));
-static void run_redisplay_end_trigger_hook P_ ((struct it *));
-static int get_overlay_strings P_ ((struct it *, int));
-static int get_overlay_strings_1 P_ ((struct it *, int, int));
-static void next_overlay_string P_ ((struct it *));
-static void reseat P_ ((struct it *, struct text_pos, int));
-static void reseat_1 P_ ((struct it *, struct text_pos, int));
-static void back_to_previous_visible_line_start P_ ((struct it *));
-void reseat_at_previous_visible_line_start P_ ((struct it *));
-static void reseat_at_next_visible_line_start P_ ((struct it *, int));
-static int next_element_from_ellipsis P_ ((struct it *));
-static int next_element_from_display_vector P_ ((struct it *));
-static int next_element_from_string P_ ((struct it *));
-static int next_element_from_c_string P_ ((struct it *));
-static int next_element_from_buffer P_ ((struct it *));
-static int next_element_from_composition P_ ((struct it *));
-static int next_element_from_image P_ ((struct it *));
-static int next_element_from_stretch P_ ((struct it *));
-static void load_overlay_strings P_ ((struct it *, int));
-static int init_from_display_pos P_ ((struct it *, struct window *,
-                                     struct display_pos *));
-static void reseat_to_string P_ ((struct it *, unsigned char *,
-                                 Lisp_Object, int, int, int, int));
+static void setup_for_ellipsis (struct it *, int);
+static void mark_window_display_accurate_1 (struct window *, int);
+static int single_display_spec_string_p (Lisp_Object, Lisp_Object);
+static int display_prop_string_p (Lisp_Object, Lisp_Object);
+static int cursor_row_p (struct window *, struct glyph_row *);
+static int redisplay_mode_lines (Lisp_Object, int);
+static char *decode_mode_spec_coding (Lisp_Object, char *, int);
+
+static Lisp_Object get_it_property (struct it *it, Lisp_Object prop);
+
+static void handle_line_prefix (struct it *);
+
+static void pint2str (char *, int, int);
+static void pint2hrstr (char *, int, int);
+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 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);
+static void handle_stop (struct it *);
+static void handle_stop_backwards (struct it *, EMACS_INT);
+static int tool_bar_lines_needed (struct frame *, int *);
+static int single_display_spec_intangible_p (Lisp_Object);
+static void ensure_echo_area_buffers (void);
+static Lisp_Object unwind_with_echo_area_buffer (Lisp_Object);
+static Lisp_Object with_echo_area_buffer_unwind_data (struct window *);
+static int with_echo_area_buffer (struct window *, int,
+                                  int (*) (EMACS_INT, Lisp_Object, EMACS_INT, EMACS_INT),
+                                  EMACS_INT, Lisp_Object, EMACS_INT, EMACS_INT);
+static void clear_garbaged_frames (void);
+static int current_message_1 (EMACS_INT, Lisp_Object, EMACS_INT, EMACS_INT);
+static int truncate_message_1 (EMACS_INT, Lisp_Object, EMACS_INT, EMACS_INT);
+static int set_message_1 (EMACS_INT, Lisp_Object, EMACS_INT, EMACS_INT);
+static int display_echo_area (struct window *);
+static int display_echo_area_1 (EMACS_INT, Lisp_Object, EMACS_INT, EMACS_INT);
+static int resize_mini_window_1 (EMACS_INT, Lisp_Object, EMACS_INT, EMACS_INT);
+static Lisp_Object unwind_redisplay (Lisp_Object);
+static int string_char_and_length (const unsigned char *, int *);
+static struct text_pos display_prop_end (struct it *, Lisp_Object,
+                                         struct text_pos);
+static int compute_window_start_on_continuation_line (struct window *);
+static Lisp_Object safe_eval_handler (Lisp_Object);
+static void insert_left_trunc_glyphs (struct it *);
+static struct glyph_row *get_overlay_arrow_glyph_row (struct window *,
+                                                      Lisp_Object);
+static void extend_face_to_end_of_line (struct it *);
+static int append_space_for_newline (struct it *, int);
+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 void push_it (struct it *);
+static void pop_it (struct it *);
+static void sync_frame_with_window_matrix_rows (struct window *);
+static void select_frame_for_redisplay (Lisp_Object);
+static void redisplay_internal (int);
+static int echo_area_display (int);
+static void redisplay_windows (Lisp_Object);
+static void redisplay_window (Lisp_Object, int);
+static Lisp_Object redisplay_window_error (Lisp_Object);
+static Lisp_Object redisplay_window_0 (Lisp_Object);
+static Lisp_Object redisplay_window_1 (Lisp_Object);
+static int update_menu_bar (struct frame *, int, int);
+static int try_window_reusing_current_matrix (struct window *);
+static int try_window_id (struct window *);
+static int display_line (struct it *);
+static int display_mode_lines (struct window *);
+static int display_mode_line (struct window *, enum face_id, Lisp_Object);
+static int display_mode_element (struct it *, int, int, int, Lisp_Object, Lisp_Object, int);
+static int store_mode_line_string (char *, Lisp_Object, int, int, int, Lisp_Object);
+static 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_string (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 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);
+static void back_to_previous_visible_line_start (struct it *);
+void reseat_at_previous_visible_line_start (struct it *);
+static void reseat_at_next_visible_line_start (struct it *, int);
+static int next_element_from_ellipsis (struct it *);
+static int next_element_from_display_vector (struct it *);
+static int next_element_from_string (struct it *);
+static int next_element_from_c_string (struct it *);
+static int next_element_from_buffer (struct it *);
+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 int init_from_display_pos (struct it *, struct window *,
+                                  struct display_pos *);
+static void reseat_to_string (struct it *, unsigned char *,
+                              Lisp_Object, int, int, int, int);
 static enum move_it_result
        move_it_in_display_line_to (struct it *, EMACS_INT, int,
                                   enum move_operation_enum);
-void move_it_vertically_backward P_ ((struct it *, int));
-static void init_to_row_start P_ ((struct it *, struct window *,
-                                  struct glyph_row *));
-static int init_to_row_end P_ ((struct it *, struct window *,
-                               struct glyph_row *));
-static void back_to_previous_line_start P_ ((struct it *));
-static int forward_to_next_line_start P_ ((struct it *, int *));
-static struct text_pos string_pos_nchars_ahead P_ ((struct text_pos,
-                                                   Lisp_Object, int));
-static struct text_pos string_pos P_ ((int, Lisp_Object));
-static struct text_pos c_string_pos P_ ((int, unsigned char *, int));
-static int number_of_chars P_ ((unsigned char *, int));
-static void compute_stop_pos P_ ((struct it *));
-static void compute_string_pos P_ ((struct text_pos *, struct text_pos,
-                                   Lisp_Object));
-static int face_before_or_after_it_pos P_ ((struct it *, int));
-static EMACS_INT next_overlay_change P_ ((EMACS_INT));
-static int handle_single_display_spec P_ ((struct it *, Lisp_Object,
-                                          Lisp_Object, Lisp_Object,
-                                          struct text_pos *, int));
-static int underlying_face_id P_ ((struct it *));
-static int in_ellipses_for_invisible_text_p P_ ((struct display_pos *,
-                                                struct window *));
+void move_it_vertically_backward (struct it *, int);
+static void init_to_row_start (struct it *, struct window *,
+                               struct glyph_row *);
+static int init_to_row_end (struct it *, struct window *,
+                            struct glyph_row *);
+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, unsigned char *, int);
+static int number_of_chars (unsigned char *, int);
+static void compute_stop_pos (struct it *);
+static void compute_string_pos (struct text_pos *, struct text_pos,
+                                Lisp_Object);
+static int face_before_or_after_it_pos (struct it *, int);
+static EMACS_INT next_overlay_change (EMACS_INT);
+static int handle_single_display_spec (struct it *, Lisp_Object,
+                                       Lisp_Object, Lisp_Object,
+                                       struct text_pos *, int);
+static int underlying_face_id (struct it *);
+static int in_ellipses_for_invisible_text_p (struct display_pos *,
+                                             struct window *);
 
 #define face_before_it_pos(IT) face_before_or_after_it_pos ((IT), 1)
 #define face_after_it_pos(IT)  face_before_or_after_it_pos ((IT), 0)
 
 #ifdef HAVE_WINDOW_SYSTEM
 
-static void update_tool_bar P_ ((struct frame *, int));
-static void build_desired_tool_bar_string P_ ((struct frame *f));
-static int redisplay_tool_bar P_ ((struct frame *));
-static void display_tool_bar_line P_ ((struct it *, int));
-static void notice_overwritten_cursor P_ ((struct window *,
-                                          enum glyph_row_area,
-                                          int, int, int, int));
-static void append_stretch_glyph P_ ((struct it *, Lisp_Object,
-                                     int, int, int));
+static void update_tool_bar (struct frame *, int);
+static void build_desired_tool_bar_string (struct frame *f);
+static int redisplay_tool_bar (struct frame *);
+static void display_tool_bar_line (struct it *, int);
+static void notice_overwritten_cursor (struct window *,
+                                       enum glyph_row_area,
+                                       int, int, int, int);
+static void append_stretch_glyph (struct it *, Lisp_Object,
+                                  int, int, int);
 
 
 
@@ -1020,8 +1109,7 @@ static void append_stretch_glyph P_ ((struct it *, Lisp_Object,
    This is the height of W minus the height of a mode line, if any.  */
 
 INLINE int
-window_text_bottom_y (w)
-     struct window *w;
+window_text_bottom_y (struct window *w)
 {
   int height = WINDOW_TOTAL_HEIGHT (w);
 
@@ -1035,9 +1123,7 @@ window_text_bottom_y (w)
    the left and right of the window.  */
 
 INLINE int
-window_box_width (w, area)
-     struct window *w;
-     int area;
+window_box_width (struct window *w, int area)
 {
   int cols = XFASTINT (w->total_cols);
   int pixels = 0;
@@ -1076,8 +1162,7 @@ window_box_width (w, area)
    including mode lines of W, if any.  */
 
 INLINE int
-window_box_height (w)
-     struct window *w;
+window_box_height (struct window *w)
 {
   struct frame *f = XFRAME (w->frame);
   int height = WINDOW_TOTAL_HEIGHT (w);
@@ -1124,9 +1209,7 @@ window_box_height (w)
    whole window, to the right of the left fringe of W.  */
 
 INLINE int
-window_box_left_offset (w, area)
-     struct window *w;
-     int area;
+window_box_left_offset (struct window *w, int area)
 {
   int x;
 
@@ -1158,9 +1241,7 @@ window_box_left_offset (w, area)
    whole window, to the left of the right fringe of W.  */
 
 INLINE int
-window_box_right_offset (w, area)
-     struct window *w;
-     int area;
+window_box_right_offset (struct window *w, int area)
 {
   return window_box_left_offset (w, area) + window_box_width (w, area);
 }
@@ -1170,9 +1251,7 @@ window_box_right_offset (w, area)
    whole window, to the right of the left fringe of W.  */
 
 INLINE int
-window_box_left (w, area)
-     struct window *w;
-     int area;
+window_box_left (struct window *w, int area)
 {
   struct frame *f = XFRAME (w->frame);
   int x;
@@ -1192,9 +1271,7 @@ window_box_left (w, area)
    whole window, to the left of the right fringe of W.  */
 
 INLINE int
-window_box_right (w, area)
-     struct window *w;
-     int area;
+window_box_right (struct window *w, int area)
 {
   return window_box_left (w, area) + window_box_width (w, area);
 }
@@ -1207,10 +1284,8 @@ window_box_right (w, area)
    *BOX_WIDTH, and *BOX_HEIGHT the pixel width and height of the box.  */
 
 INLINE void
-window_box (w, area, box_x, box_y, box_width, box_height)
-     struct window *w;
-     int area;
-     int *box_x, *box_y, *box_width, *box_height;
+window_box (struct window *w, int area, int *box_x, int *box_y,
+           int *box_width, int *box_height)
 {
   if (box_width)
     *box_width = window_box_width (w, area);
@@ -1258,8 +1333,7 @@ window_box_edges (w, area, top_left_x, top_left_y,
    This can modify IT's settings.  */
 
 int
-line_bottom_y (it)
-     struct it *it;
+line_bottom_y (struct it *it)
 {
   int line_height = it->max_ascent + it->max_descent;
   int line_top_y = it->current_y;
@@ -1301,9 +1375,8 @@ line_bottom_y (it)
    Set *ROWH and *VPOS to row's visible height and VPOS (row number).  */
 
 int
-pos_visible_p (w, charpos, x, y, rtop, rbot, rowh, vpos)
-     struct window *w;
-     int charpos, *x, *y, *rtop, *rbot, *rowh, *vpos;
+pos_visible_p (struct window *w, int charpos, int *x, int *y,
+              int *rtop, int *rbot, int *rowh, int *vpos)
 {
   struct it it;
   struct text_pos top;
@@ -1442,9 +1515,7 @@ pos_visible_p (w, charpos, x, y, rtop, rbot, rowh, vpos)
    character.  */
 
 static INLINE int
-string_char_and_length (str, len)
-     const unsigned char *str;
-     int *len;
+string_char_and_length (const unsigned char *str, int *len)
 {
   int c;
 
@@ -1464,10 +1535,7 @@ string_char_and_length (str, len)
    in STRING, return the position NCHARS ahead (NCHARS >= 0).  */
 
 static struct text_pos
-string_pos_nchars_ahead (pos, string, nchars)
-     struct text_pos pos;
-     Lisp_Object string;
-     int nchars;
+string_pos_nchars_ahead (struct text_pos pos, Lisp_Object string, int nchars)
 {
   xassert (STRINGP (string) && nchars >= 0);
 
@@ -1497,9 +1565,7 @@ string_pos_nchars_ahead (pos, string, nchars)
    for character position CHARPOS in STRING.  */
 
 static INLINE struct text_pos
-string_pos (charpos, string)
-     int charpos;
-     Lisp_Object string;
+string_pos (int charpos, Lisp_Object string)
 {
   struct text_pos pos;
   xassert (STRINGP (string));
@@ -1514,10 +1580,7 @@ string_pos (charpos, string)
    means recognize multibyte characters.  */
 
 static struct text_pos
-c_string_pos (charpos, s, multibyte_p)
-     int charpos;
-     unsigned char *s;
-     int multibyte_p;
+c_string_pos (int charpos, unsigned char *s, int multibyte_p)
 {
   struct text_pos pos;
 
@@ -1549,9 +1612,7 @@ c_string_pos (charpos, s, multibyte_p)
    non-zero means recognize multibyte characters.  */
 
 static int
-number_of_chars (s, multibyte_p)
-     unsigned char *s;
-     int multibyte_p;
+number_of_chars (unsigned char *s, int multibyte_p)
 {
   int nchars;
 
@@ -1578,9 +1639,7 @@ number_of_chars (s, multibyte_p)
    NEWPOS->charpos must be >= POS.charpos.  */
 
 static void
-compute_string_pos (newpos, pos, string)
-     struct text_pos *newpos, pos;
-     Lisp_Object string;
+compute_string_pos (struct text_pos *newpos, struct text_pos pos, Lisp_Object string)
 {
   xassert (STRINGP (string));
   xassert (CHARPOS (*newpos) >= CHARPOS (pos));
@@ -1597,9 +1656,7 @@ compute_string_pos (newpos, pos, string)
    frame F.  FACE_ID specifies what line's height to estimate.  */
 
 int
-estimate_mode_line_height (f, face_id)
-     struct frame *f;
-     enum face_id face_id;
+estimate_mode_line_height (struct frame *f, enum face_id face_id)
 {
 #ifdef HAVE_WINDOW_SYSTEM
   if (FRAME_WINDOW_P (f))
@@ -1633,12 +1690,8 @@ estimate_mode_line_height (f, face_id)
    not force the value into range.  */
 
 void
-pixel_to_glyph_coords (f, pix_x, pix_y, x, y, bounds, noclip)
-     FRAME_PTR f;
-     register int pix_x, pix_y;
-     int *x, *y;
-     NativeRectangle *bounds;
-     int noclip;
+pixel_to_glyph_coords (FRAME_PTR f, register int pix_x, register int pix_y,
+                      int *x, int *y, NativeRectangle *bounds, int noclip)
 {
 
 #ifdef HAVE_WINDOW_SYSTEM
@@ -1687,10 +1740,8 @@ pixel_to_glyph_coords (f, pix_x, pix_y, x, y, bounds, noclip)
    return 0.  */
 
 int
-glyph_to_pixel_coords (w, hpos, vpos, frame_x, frame_y)
-     struct window *w;
-     int hpos, vpos;
-     int *frame_x, *frame_y;
+glyph_to_pixel_coords (struct window *w, int hpos, int vpos,
+                      int *frame_x, int *frame_y)
 {
 #ifdef HAVE_WINDOW_SYSTEM
   if (FRAME_WINDOW_P (XFRAME (WINDOW_FRAME (w))))
@@ -1750,10 +1801,8 @@ glyph_to_pixel_coords (w, hpos, vpos, frame_x, frame_y)
 
 static
 struct glyph *
-x_y_to_hpos_vpos (w, x, y, hpos, vpos, dx, dy, area)
-     struct window *w;
-     int x, y;
-     int *hpos, *vpos, *dx, *dy, *area;
+x_y_to_hpos_vpos (struct window *w, int x, int y, int *hpos, int *vpos,
+                 int *dx, int *dy, int *area)
 {
   struct glyph *glyph, *end;
   struct glyph_row *row = NULL;
@@ -1830,9 +1879,7 @@ x_y_to_hpos_vpos (w, x, y, hpos, vpos, dx, dy, area)
    Takes pseudo-windows into account.  */
 
 void
-frame_to_window_pixel_xy (w, x, y)
-     struct window *w;
-     int *x, *y;
+frame_to_window_pixel_xy (struct window *w, int *x, int *y)
 {
   if (w->pseudo_window_p)
     {
@@ -1854,10 +1901,7 @@ frame_to_window_pixel_xy (w, x, y)
    Return the number of stored rectangles.  */
 
 int
-get_glyph_string_clip_rects (s, rects, n)
-     struct glyph_string *s;
-     NativeRectangle *rects;
-     int n;
+get_glyph_string_clip_rects (struct glyph_string *s, NativeRectangle *rects, int n)
 {
   XRectangle r;
 
@@ -2051,9 +2095,7 @@ get_glyph_string_clip_rects (s, rects, n)
    Return in *NR the clipping rectangle for glyph string S.  */
 
 void
-get_glyph_string_clip_rect (s, nr)
-     struct glyph_string *s;
-     NativeRectangle *nr;
+get_glyph_string_clip_rect (struct glyph_string *s, NativeRectangle *nr)
 {
   get_glyph_string_clip_rects (s, nr, 1);
 }
@@ -2065,11 +2107,8 @@ get_glyph_string_clip_rect (s, nr)
 */
 
 void
-get_phys_cursor_geometry (w, row, glyph, xp, yp, heightp)
-     struct window *w;
-     struct glyph_row *row;
-     struct glyph *glyph;
-     int *xp, *yp, *heightp;
+get_phys_cursor_geometry (struct window *w, struct glyph_row *row,
+                         struct glyph *glyph, int *xp, int *yp, int *heightp)
 {
   struct frame *f = XFRAME (WINDOW_FRAME (w));
   int x, y, wd, h, h0, y0;
@@ -2129,10 +2168,7 @@ get_phys_cursor_geometry (w, row, glyph, xp, yp, heightp)
  */
 
 void
-remember_mouse_glyph (f, gx, gy, rect)
-     struct frame *f;
-     int gx, gy;
-     NativeRectangle *rect;
+remember_mouse_glyph (struct frame *f, int gx, int gy, NativeRectangle *rect)
 {
   Lisp_Object window;
   struct window *w;
@@ -2328,8 +2364,7 @@ remember_mouse_glyph (f, gx, gy, rect)
 /* Error handler for safe_eval and safe_call.  */
 
 static Lisp_Object
-safe_eval_handler (arg)
-     Lisp_Object arg;
+safe_eval_handler (Lisp_Object arg)
 {
   add_to_log ("Error during redisplay: %s", arg, Qnil);
   return Qnil;
@@ -2344,9 +2379,7 @@ safe_eval_handler (arg)
    redisplay during the evaluation.  */
 
 Lisp_Object
-safe_call (nargs, args)
-     int nargs;
-     Lisp_Object *args;
+safe_call (int nargs, Lisp_Object *args)
 {
   Lisp_Object val;
 
@@ -2362,7 +2395,7 @@ safe_call (nargs, args)
       specbind (Qinhibit_redisplay, Qt);
       /* Use Qt to ensure debugger does not run,
         so there is no possibility of wanting to redisplay.  */
-      val = internal_condition_case_2 (Ffuncall, nargs, args, Qt,
+      val = internal_condition_case_n (Ffuncall, nargs, args, Qt,
                                       safe_eval_handler);
       UNGCPRO;
       val = unbind_to (count, val);
@@ -2376,8 +2409,7 @@ safe_call (nargs, args)
    Return the result, or nil if something went wrong.  */
 
 Lisp_Object
-safe_call1 (fn, arg)
-     Lisp_Object fn, arg;
+safe_call1 (Lisp_Object fn, Lisp_Object arg)
 {
   Lisp_Object args[2];
   args[0] = fn;
@@ -2506,12 +2538,9 @@ check_window_end (w)
    the desired matrix of W.  */
 
 void
-init_iterator (it, w, charpos, bytepos, row, base_face_id)
-     struct it *it;
-     struct window *w;
-     int charpos, bytepos;
-     struct glyph_row *row;
-     enum face_id base_face_id;
+init_iterator (struct it *it, struct window *w,
+              EMACS_INT charpos, EMACS_INT bytepos,
+              struct glyph_row *row, enum face_id base_face_id)
 {
   int highlight_region_p;
   enum face_id remapped_base_face_id = base_face_id;
@@ -2547,7 +2576,7 @@ init_iterator (it, w, charpos, bytepos, row, base_face_id)
     }
 
   /* Clear IT.  */
-  bzero (it, sizeof *it);
+  memset (it, 0, sizeof *it);
   it->current.overlay_string_index = -1;
   it->current.dpvec_index = -1;
   it->base_face_id = remapped_base_face_id;
@@ -2609,8 +2638,12 @@ init_iterator (it, w, charpos, bytepos, row, base_face_id)
   /* Are multibyte characters enabled in current_buffer?  */
   it->multibyte_p = !NILP (current_buffer->enable_multibyte_characters);
 
-  /* Do we need to reorder bidirectional text?  */
-  it->bidi_p = !NILP (current_buffer->bidi_display_reordering);
+  /* Do we need to reorder bidirectional text?  Not if this is a
+     unibyte buffer: by definition, none of the single-byte characters
+     are strong R2L, so no reordering is needed.  And bidi.c doesn't
+     support unibyte buffers anyway.  */
+  it->bidi_p
+    = !NILP (current_buffer->bidi_display_reordering) && it->multibyte_p;
 
   /* Non-zero if we should highlight the region.  */
   highlight_region_p
@@ -2803,10 +2836,7 @@ init_iterator (it, w, charpos, bytepos, row, base_face_id)
 /* Initialize IT for the display of window W with window start POS.  */
 
 void
-start_display (it, w, pos)
-     struct it *it;
-     struct window *w;
-     struct text_pos pos;
+start_display (struct it *it, struct window *w, struct text_pos pos)
 {
   struct glyph_row *row;
   int first_vpos = WINDOW_WANTS_HEADER_LINE_P (w) ? 1 : 0;
@@ -2878,9 +2908,7 @@ start_display (it, w, pos)
    text.  W is the window we display, for text property lookup.  */
 
 static int
-in_ellipses_for_invisible_text_p (pos, w)
-     struct display_pos *pos;
-     struct window *w;
+in_ellipses_for_invisible_text_p (struct display_pos *pos, struct window *w)
 {
   Lisp_Object prop, window;
   int ellipses_p = 0;
@@ -2914,12 +2942,9 @@ in_ellipses_for_invisible_text_p (pos, w)
    is zero if there are overlay strings with newlines at POS.  */
 
 static int
-init_from_display_pos (it, w, pos)
-     struct it *it;
-     struct window *w;
-     struct display_pos *pos;
+init_from_display_pos (struct it *it, struct window *w, struct display_pos *pos)
 {
-  int charpos = CHARPOS (pos->pos), bytepos = BYTEPOS (pos->pos);
+  EMACS_INT charpos = CHARPOS (pos->pos), bytepos = BYTEPOS (pos->pos);
   int i, overlay_strings_with_newlines = 0;
 
   /* If POS specifies a position in a display vector, this might
@@ -3025,10 +3050,7 @@ init_from_display_pos (it, w, pos)
    starting at ROW->start.  */
 
 static void
-init_to_row_start (it, w, row)
-     struct it *it;
-     struct window *w;
-     struct glyph_row *row;
+init_to_row_start (struct it *it, struct window *w, struct glyph_row *row)
 {
   init_from_display_pos (it, w, &row->start);
   it->start = row->start;
@@ -3043,10 +3065,7 @@ init_to_row_start (it, w, row)
    end position.  */
 
 static int
-init_to_row_end (it, w, row)
-     struct it *it;
-     struct window *w;
-     struct glyph_row *row;
+init_to_row_end (struct it *it, struct window *w, struct glyph_row *row)
 {
   int success = 0;
 
@@ -3074,8 +3093,7 @@ init_to_row_end (it, w, row)
    to stop.  */
 
 static void
-handle_stop (it)
-     struct it *it;
+handle_stop (struct it *it)
 {
   enum prop_handled handled;
   int handle_overlay_change_p;
@@ -3168,8 +3186,7 @@ handle_stop (it)
    information for IT's current position.  */
 
 static void
-compute_stop_pos (it)
-     struct it *it;
+compute_stop_pos (struct it *it)
 {
   register INTERVAL iv, next_iv;
   Lisp_Object object, limit, position;
@@ -3278,8 +3295,7 @@ compute_stop_pos (it)
    xmalloc.  */
 
 static EMACS_INT
-next_overlay_change (pos)
-     EMACS_INT pos;
+next_overlay_change (EMACS_INT pos)
 {
   int noverlays;
   EMACS_INT endpos;
@@ -3315,8 +3331,7 @@ next_overlay_change (pos)
    regions of text.  */
 
 static enum prop_handled
-handle_fontified_prop (it)
-     struct it *it;
+handle_fontified_prop (struct it *it)
 {
   Lisp_Object prop, pos;
   enum prop_handled handled = HANDLED_NORMALLY;
@@ -3403,8 +3418,7 @@ handle_fontified_prop (it)
    Called from handle_stop.  */
 
 static enum prop_handled
-handle_face_prop (it)
-     struct it *it;
+handle_face_prop (struct it *it)
 {
   int new_face_id;
   EMACS_INT next_stop;
@@ -3542,8 +3556,7 @@ handle_face_prop (it)
    Otherwise, use the iterator's base_face_id.  */
 
 static int
-underlying_face_id (it)
-     struct it *it;
+underlying_face_id (struct it *it)
 {
   int face_id = it->base_face_id, i;
 
@@ -3562,9 +3575,7 @@ underlying_face_id (it)
    position.  Value is the id of the face.  */
 
 static int
-face_before_or_after_it_pos (it, before_p)
-     struct it *it;
-     int before_p;
+face_before_or_after_it_pos (struct it *it, int before_p)
 {
   int face_id, limit;
   EMACS_INT next_check_charpos;
@@ -3678,8 +3689,7 @@ face_before_or_after_it_pos (it, before_p)
    position.  Called from handle_stop.  */
 
 static enum prop_handled
-handle_invisible_prop (it)
-     struct it *it;
+handle_invisible_prop (struct it *it)
 {
   enum prop_handled handled = HANDLED_NORMALLY;
 
@@ -3825,7 +3835,7 @@ handle_invisible_prop (it)
                }
              do
                {
-                 bidi_get_next_char_visually (&it->bidi_it);
+                 bidi_move_to_visually_next (&it->bidi_it);
                }
              while (it->stop_charpos <= it->bidi_it.charpos
                     && it->bidi_it.charpos < newpos);
@@ -3892,9 +3902,7 @@ handle_invisible_prop (it)
    Replaces LEN characters from buffer.  */
 
 static void
-setup_for_ellipsis (it, len)
-     struct it *it;
-     int len;
+setup_for_ellipsis (struct it *it, int len)
 {
   /* Use the display table definition for `...'.  Invalid glyphs
      will be handled by the method returning elements from dpvec.  */
@@ -3938,8 +3946,7 @@ setup_for_ellipsis (it, len)
    Otherwise we return HANDLED_NORMALLY.  */
 
 static enum prop_handled
-handle_display_prop (it)
-     struct it *it;
+handle_display_prop (struct it *it)
 {
   Lisp_Object prop, object, overlay;
   struct text_pos *position;
@@ -4036,10 +4043,7 @@ handle_display_prop (it)
    at START_POS in OBJECT.  */
 
 static struct text_pos
-display_prop_end (it, object, start_pos)
-     struct it *it;
-     Lisp_Object object;
-     struct text_pos start_pos;
+display_prop_end (struct it *it, Lisp_Object object, struct text_pos start_pos)
 {
   Lisp_Object end;
   struct text_pos end_pos;
@@ -4446,8 +4450,7 @@ handle_single_display_spec (it, spec, object, overlay, position,
    treated as intangible.  */
 
 static int
-single_display_spec_intangible_p (prop)
-     Lisp_Object prop;
+single_display_spec_intangible_p (Lisp_Object prop)
 {
   /* Skip over `when FORM'.  */
   if (CONSP (prop) && EQ (XCAR (prop), Qwhen))
@@ -4489,8 +4492,7 @@ single_display_spec_intangible_p (prop)
    treated as intangible.  */
 
 int
-display_prop_intangible_p (prop)
-     Lisp_Object prop;
+display_prop_intangible_p (Lisp_Object prop)
 {
   if (CONSP (prop)
       && CONSP (XCAR (prop))
@@ -4522,8 +4524,7 @@ display_prop_intangible_p (prop)
 /* Return 1 if PROP is a display sub-property value containing STRING.  */
 
 static int
-single_display_spec_string_p (prop, string)
-     Lisp_Object prop, string;
+single_display_spec_string_p (Lisp_Object prop, Lisp_Object string)
 {
   if (EQ (string, prop))
     return 1;
@@ -4557,8 +4558,7 @@ single_display_spec_string_p (prop, string)
 /* Return 1 if STRING appears in the `display' property PROP.  */
 
 static int
-display_prop_string_p (prop, string)
-     Lisp_Object prop, string;
+display_prop_string_p (Lisp_Object prop, Lisp_Object string)
 {
   if (CONSP (prop)
       && CONSP (XCAR (prop))
@@ -4599,11 +4599,8 @@ display_prop_string_p (prop, string)
    called asynchronously from note_mouse_highlight.  */
 
 static EMACS_INT
-string_buffer_position_lim (w, string, from, to, back_p)
-     struct window *w;
-     Lisp_Object string;
-     EMACS_INT from, to;
-     int back_p;
+string_buffer_position_lim (struct window *w, Lisp_Object string,
+                           EMACS_INT from, EMACS_INT to, int back_p)
 {
   Lisp_Object limit, prop, pos;
   int found = 0;
@@ -4652,10 +4649,7 @@ string_buffer_position_lim (w, string, from, to, back_p)
    called asynchronously from note_mouse_highlight.  */
 
 EMACS_INT
-string_buffer_position (w, string, around_charpos)
-     struct window *w;
-     Lisp_Object string;
-     EMACS_INT around_charpos;
+string_buffer_position (struct window *w, Lisp_Object string, EMACS_INT around_charpos)
 {
   Lisp_Object limit, prop, pos;
   const int MAX_DISTANCE = 1000;
@@ -4679,8 +4673,7 @@ string_buffer_position (w, string, around_charpos)
    position.  Called from handle_stop.  */
 
 static enum prop_handled
-handle_composition_prop (it)
-     struct it *it;
+handle_composition_prop (struct it *it)
 {
   Lisp_Object prop, string;
   EMACS_INT pos, pos_byte, start, end;
@@ -4753,8 +4746,7 @@ struct overlay_entry
    Called from handle_stop.  */
 
 static enum prop_handled
-handle_overlay_change (it)
-     struct it *it;
+handle_overlay_change (struct it *it)
 {
   if (!STRINGP (it->string) && get_overlay_strings (it, 0))
     return HANDLED_RECOMPUTE_PROPS;
@@ -4771,8 +4763,7 @@ handle_overlay_change (it)
    Otherwise IT->string is set to nil.  */
 
 static void
-next_overlay_string (it)
-     struct it *it;
+next_overlay_string (struct it *it)
 {
   ++it->current.overlay_string_index;
   if (it->current.overlay_string_index == it->n_overlay_strings)
@@ -4840,8 +4831,7 @@ next_overlay_string (it)
 
 
 static int
-compare_overlay_entries (e1, e2)
-     void *e1, *e2;
+compare_overlay_entries (const void *e1, const void *e2)
 {
   struct overlay_entry *entry1 = (struct overlay_entry *) e1;
   struct overlay_entry *entry2 = (struct overlay_entry *) e2;
@@ -4892,9 +4882,7 @@ compare_overlay_entries (e1, e2)
    compare_overlay_entries.  */
 
 static void
-load_overlay_strings (it, charpos)
-     struct it *it;
-     int charpos;
+load_overlay_strings (struct it *it, int charpos)
 {
   extern Lisp_Object Qwindow, Qpriority;
   Lisp_Object overlay, window, str, invisible;
@@ -4924,7 +4912,7 @@ load_overlay_strings (it, charpos)
          entries =                                                     \
             (struct overlay_entry *) alloca (new_size                  \
                                             * sizeof *entries);        \
-         bcopy (old, entries, size * sizeof *entries);                 \
+         memcpy (entries, old, size * sizeof *entries);                \
          size = new_size;                                              \
        }                                                               \
                                                                        \
@@ -5045,10 +5033,7 @@ load_overlay_strings (it, charpos)
    least one overlay string was found.  */
 
 static int
-get_overlay_strings_1 (it, charpos, compute_stop_p)
-     struct it *it;
-     int charpos;
-     int compute_stop_p;
+get_overlay_strings_1 (struct it *it, 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
@@ -5099,9 +5084,7 @@ get_overlay_strings_1 (it, charpos, compute_stop_p)
 }
 
 static int
-get_overlay_strings (it, charpos)
-     struct it *it;
-     int charpos;
+get_overlay_strings (struct it *it, int charpos)
 {
   it->string = Qnil;
   it->method = GET_FROM_BUFFER;
@@ -5126,8 +5109,7 @@ get_overlay_strings (it, charpos)
    processed.  */
 
 static void
-push_it (it)
-     struct it *it;
+push_it (struct it *it)
 {
   struct iterator_stack_entry *p;
 
@@ -5170,6 +5152,32 @@ push_it (it)
   ++it->sp;
 }
 
+static void
+iterate_out_of_display_property (struct it *it)
+{
+  /* Maybe initialize paragraph direction.  If we are at the beginning
+     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);
+  /* prev_stop can be zero, so check against BEGV as well.  */
+  while (it->bidi_it.charpos >= BEGV
+        && it->prev_stop <= it->bidi_it.charpos
+        && it->bidi_it.charpos < CHARPOS (it->position))
+    bidi_move_to_visually_next (&it->bidi_it);
+  /* Record the stop_pos we just crossed, for when we cross it
+     back, maybe.  */
+  if (it->bidi_it.charpos > CHARPOS (it->position))
+    it->prev_stop = CHARPOS (it->position);
+  /* If we ended up not where pop_it put us, resync IT's
+     positional members with the bidi iterator. */
+  if (it->bidi_it.charpos != CHARPOS (it->position))
+    {
+      SET_TEXT_POS (it->position,
+                   it->bidi_it.charpos, it->bidi_it.bytepos);
+      it->current.pos = it->position;
+    }
+}
 
 /* Restore IT's settings from IT->stack.  Called, for example, when no
    more overlay strings must be processed, and we return to delivering
@@ -5178,8 +5186,7 @@ push_it (it)
    elements from an overlay string, or from a buffer.  */
 
 static void
-pop_it (it)
-     struct it *it;
+pop_it (struct it *it)
 {
   struct iterator_stack_entry *p;
 
@@ -5210,6 +5217,18 @@ pop_it (it)
       break;
     case GET_FROM_BUFFER:
       it->object = it->w->buffer;
+      if (it->bidi_p)
+       {
+         /* Bidi-iterate until we get out of the portion of text, if
+            any, covered by a `display' text property or an overlay
+            with `display' property.  (We cannot just jump there,
+            because the internal coherency of the bidi iterator state
+            can not be preserved across such jumps.)  We also must
+            determine the paragraph base direction if the overlay we
+            just processed is at the beginning of a new
+            paragraph.  */
+         iterate_out_of_display_property (it);
+       }
       break;
     case GET_FROM_STRING:
       it->object = it->string;
@@ -5246,8 +5265,7 @@ pop_it (it)
 /* Set IT's current position to the previous line start.  */
 
 static void
-back_to_previous_line_start (it)
-     struct it *it;
+back_to_previous_line_start (struct it *it)
 {
   IT_CHARPOS (*it) = find_next_newline_no_quit (IT_CHARPOS (*it) - 1, -1);
   IT_BYTEPOS (*it) = CHAR_TO_BYTE (IT_CHARPOS (*it));
@@ -5273,9 +5291,7 @@ back_to_previous_line_start (it)
    leads to wrong cursor motion.  */
 
 static int
-forward_to_next_line_start (it, skipped_p)
-     struct it *it;
-     int *skipped_p;
+forward_to_next_line_start (struct it *it, int *skipped_p)
 {
   int old_selective, newline_found_p, n;
   const int MAX_NEWLINE_DISTANCE = 500;
@@ -5356,8 +5372,7 @@ forward_to_next_line_start (it, skipped_p)
    IT->hpos.  */
 
 static void
-back_to_previous_visible_line_start (it)
-     struct it *it;
+back_to_previous_visible_line_start (struct it *it)
 {
   while (IT_CHARPOS (*it) > BEGV)
     {
@@ -5437,8 +5452,7 @@ back_to_previous_visible_line_start (it)
    face information etc.  */
 
 void
-reseat_at_previous_visible_line_start (it)
-     struct it *it;
+reseat_at_previous_visible_line_start (struct it *it)
 {
   back_to_previous_visible_line_start (it);
   reseat (it, it->current.pos, 1);
@@ -5454,9 +5468,7 @@ reseat_at_previous_visible_line_start (it)
    is invisible because of text properties.  */
 
 static void
-reseat_at_next_visible_line_start (it, on_newline_p)
-     struct it *it;
-     int on_newline_p;
+reseat_at_next_visible_line_start (struct it *it, int on_newline_p)
 {
   int newline_found_p, skipped_p = 0;
 
@@ -5510,10 +5522,7 @@ reseat_at_next_visible_line_start (it, on_newline_p)
    IT->check_charpos of a property.  */
 
 static void
-reseat (it, pos, force_p)
-     struct it *it;
-     struct text_pos pos;
-     int force_p;
+reseat (struct it *it, struct text_pos pos, int force_p)
 {
   int original_pos = IT_CHARPOS (*it);
 
@@ -5557,10 +5566,7 @@ reseat (it, pos, force_p)
    IT->stop_pos to POS, also.  */
 
 static void
-reseat_1 (it, pos, set_stop_p)
-     struct it *it;
-     struct text_pos pos;
-     int set_stop_p;
+reseat_1 (struct it *it, struct text_pos pos, int set_stop_p)
 {
   /* Don't call this function when scanning a C string.  */
   xassert (it->s == NULL);
@@ -5614,12 +5620,8 @@ reseat_1 (it, pos, set_stop_p)
    calling this function.  */
 
 static void
-reseat_to_string (it, s, string, charpos, precision, field_width, multibyte)
-     struct it *it;
-     unsigned char *s;
-     Lisp_Object string;
-     int charpos;
-     int precision, field_width, multibyte;
+reseat_to_string (struct it *it, unsigned char *s, Lisp_Object string,
+                 int charpos, int precision, int field_width, int multibyte)
 {
   /* No region in strings.  */
   it->region_beg_charpos = it->region_end_charpos = -1;
@@ -5628,7 +5630,7 @@ reseat_to_string (it, s, string, charpos, precision, field_width, multibyte)
   it->stop_charpos = -1;
 
   /* Set iterator position and end position.  */
-  bzero (&it->current, sizeof it->current);
+  memset (&it->current, 0, sizeof it->current);
   it->current.overlay_string_index = -1;
   it->current.dpvec_index = -1;
   xassert (charpos >= 0);
@@ -5707,7 +5709,7 @@ reseat_to_string (it, s, string, charpos, precision, field_width, multibyte)
 
 /* Map enum it_method value to corresponding next_element_from_* function.  */
 
-static int (* get_next_element[NUM_IT_METHODS]) P_ ((struct it *it)) =
+static int (* get_next_element[NUM_IT_METHODS]) (struct it *it) =
 {
   next_element_from_buffer,
   next_element_from_display_vector,
@@ -5741,8 +5743,7 @@ static unsigned last_escape_glyph_face_id = (1 << FACE_ID_BITS);
 static int last_escape_glyph_merged_face_id = 0;
 
 int
-get_next_display_element (it)
-     struct it *it;
+get_next_display_element (struct it *it)
 {
   /* Non-zero means that we found a display element.  Zero means that
      we hit the end of what we iterate over.  Performance note: the
@@ -6134,9 +6135,7 @@ get_next_display_element (it)
    decrement position function which would not be easy to write.  */
 
 void
-set_iterator_to_next (it, reseat_p)
-     struct it *it;
-     int reseat_p;
+set_iterator_to_next (struct it *it, int reseat_p)
 {
   /* Reset flags indicating start and end of a sequence of characters
      with box.  Reset them at the start of this function because
@@ -6153,16 +6152,81 @@ set_iterator_to_next (it, reseat_p)
        reseat_at_next_visible_line_start (it, 0);
       else if (it->cmp_it.id >= 0)
        {
-         IT_CHARPOS (*it) += it->cmp_it.nchars;
-         IT_BYTEPOS (*it) += it->cmp_it.nbytes;
-         if (it->cmp_it.to < it->cmp_it.nglyphs)
-           it->cmp_it.from = it->cmp_it.to;
+         /* We are currently getting glyphs from a composition.  */
+         int i;
+
+         if (! it->bidi_p)
+           {
+             IT_CHARPOS (*it) += it->cmp_it.nchars;
+             IT_BYTEPOS (*it) += it->cmp_it.nbytes;
+             if (it->cmp_it.to < it->cmp_it.nglyphs)
+               {
+                 it->cmp_it.from = it->cmp_it.to;
+               }
+             else
+               {
+                 it->cmp_it.id = -1;
+                 composition_compute_stop_pos (&it->cmp_it, IT_CHARPOS (*it),
+                                               IT_BYTEPOS (*it),
+                                               it->stop_charpos, Qnil);
+               }
+           }
+         else if (! it->cmp_it.reversed_p)
+           {
+             /* Composition created while scanning forward.  */
+             /* Update IT's char/byte positions to point to the first
+                character of the next grapheme cluster, or to the
+                character visually after the current composition.  */
+             for (i = 0; i < it->cmp_it.nchars; i++)
+               bidi_move_to_visually_next (&it->bidi_it);
+             IT_BYTEPOS (*it) = it->bidi_it.bytepos;
+             IT_CHARPOS (*it) = it->bidi_it.charpos;
+
+             if (it->cmp_it.to < it->cmp_it.nglyphs)
+               {
+                 /* Proceed to the next grapheme cluster.  */
+                 it->cmp_it.from = it->cmp_it.to;
+               }
+             else
+               {
+                 /* No more grapheme clusters in this composition.
+                    Find the next stop position.  */
+                 EMACS_INT stop = it->stop_charpos;
+                 if (it->bidi_it.scan_dir < 0)
+                   /* Now we are scanning backward and don't know
+                      where to stop.  */
+                   stop = -1;
+                 composition_compute_stop_pos (&it->cmp_it, IT_CHARPOS (*it),
+                                               IT_BYTEPOS (*it), stop, Qnil);
+               }
+           }
          else
            {
-             it->cmp_it.id = -1;
-             composition_compute_stop_pos (&it->cmp_it, IT_CHARPOS (*it),
-                                           IT_BYTEPOS (*it), it->stop_charpos,
-                                           Qnil);
+             /* Composition created while scanning backward.  */
+             /* Update IT's char/byte positions to point to the last
+                character of the previous grapheme cluster, or the
+                character visually after the current composition.  */
+             for (i = 0; i < it->cmp_it.nchars; i++)
+               bidi_move_to_visually_next (&it->bidi_it);
+             IT_BYTEPOS (*it) = it->bidi_it.bytepos;
+             IT_CHARPOS (*it) = it->bidi_it.charpos;
+             if (it->cmp_it.from > 0)
+               {
+                 /* Proceed to the previous grapheme cluster.  */
+                 it->cmp_it.to = it->cmp_it.from;
+               }
+             else
+               {
+                 /* No more grapheme clusters in this composition.
+                    Find the next stop position.  */
+                 EMACS_INT stop = it->stop_charpos;
+                 if (it->bidi_it.scan_dir < 0)
+                   /* Now we are scanning backward and don't know
+                      where to stop.  */
+                   stop = -1;
+                 composition_compute_stop_pos (&it->cmp_it, IT_CHARPOS (*it),
+                                               IT_BYTEPOS (*it), stop, Qnil);
+               }
            }
        }
       else
@@ -6176,13 +6240,24 @@ set_iterator_to_next (it, reseat_p)
            }
          else
            {
+             int prev_scan_dir = it->bidi_it.scan_dir;
              /* 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_get_next_char_visually (&it->bidi_it);
+             bidi_move_to_visually_next (&it->bidi_it);
              IT_BYTEPOS (*it) = it->bidi_it.bytepos;
              IT_CHARPOS (*it) = it->bidi_it.charpos;
+             if (prev_scan_dir != it->bidi_it.scan_dir)
+               {
+                 /* As the scan direction was changed, we must
+                    re-compute the stop position for composition.  */
+                 EMACS_INT stop = it->stop_charpos;
+                 if (it->bidi_it.scan_dir < 0)
+                   stop = -1;
+                 composition_compute_stop_pos (&it->cmp_it, IT_CHARPOS (*it),
+                                               IT_BYTEPOS (*it), stop, Qnil);
+               }
            }
          xassert (IT_BYTEPOS (*it) == CHAR_TO_BYTE (IT_CHARPOS (*it)));
        }
@@ -6325,8 +6400,7 @@ set_iterator_to_next (it, reseat_p)
    is restored into IT->face_id in set_iterator_to_next.  */
 
 static int
-next_element_from_display_vector (it)
-     struct it *it;
+next_element_from_display_vector (struct it *it)
 {
   Lisp_Object gc;
 
@@ -6375,8 +6449,7 @@ next_element_from_display_vector (it)
    overlay string.  */
 
 static int
-next_element_from_string (it)
-     struct it *it;
+next_element_from_string (struct it *it)
 {
   struct text_pos position;
 
@@ -6477,8 +6550,7 @@ next_element_from_string (it)
    reached, including padding spaces.  */
 
 static int
-next_element_from_c_string (it)
-     struct it *it;
+next_element_from_c_string (struct it *it)
 {
   int success_p = 1;
 
@@ -6523,8 +6595,7 @@ next_element_from_c_string (it)
    ellipsis if an ellipsis is to be displayed.  */
 
 static int
-next_element_from_ellipsis (it)
-     struct it *it;
+next_element_from_ellipsis (struct it *it)
 {
   if (it->selective_display_ellipsis_p)
     setup_for_ellipsis (it, it->len);
@@ -6551,8 +6622,7 @@ next_element_from_ellipsis (it)
 
 
 static int
-next_element_from_image (it)
-     struct it *it;
+next_element_from_image (struct it *it)
 {
   it->what = IT_IMAGE;
   return 1;
@@ -6564,8 +6634,7 @@ next_element_from_image (it)
    always 1.  */
 
 static int
-next_element_from_stretch (it)
-     struct it *it;
+next_element_from_stretch (struct it *it)
 {
   it->what = IT_STRETCH;
   return 1;
@@ -6580,9 +6649,7 @@ next_element_from_stretch (it)
    position.  */
 
 static void
-handle_stop_backwards (it, charpos)
-     struct it *it;
-     EMACS_INT charpos;
+handle_stop_backwards (struct it *it, EMACS_INT charpos)
 {
   EMACS_INT where_we_are = IT_CHARPOS (*it);
   struct display_pos save_current = it->current;
@@ -6620,8 +6687,7 @@ handle_stop_backwards (it, charpos)
    end.  */
 
 static int
-next_element_from_buffer (it)
-     struct it *it;
+next_element_from_buffer (struct it *it)
 {
   int success_p = 1;
 
@@ -6635,15 +6701,22 @@ next_element_from_buffer (it)
     {
       it->bidi_it.charpos = IT_CHARPOS (*it);
       it->bidi_it.bytepos = IT_BYTEPOS (*it);
-      /* If we are at the beginning of a line, we can produce the next
-        element right away.  */
-      if (it->bidi_it.bytepos == BEGV_BYTE
+      if (it->bidi_it.bytepos == ZV_BYTE)
+       {
+         /* Nothing to do, but reset the FIRST_ELT flag, like
+            bidi_paragraph_init does, because we are not going to
+            call it.  */
+         it->bidi_it.first_elt = 0;
+       }
+      else if (it->bidi_it.bytepos == BEGV_BYTE
          /* FIXME: Should support all Unicode line separators.  */
          || FETCH_CHAR (it->bidi_it.bytepos - 1) == '\n'
          || FETCH_CHAR (it->bidi_it.bytepos) == '\n')
        {
+         /* 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_get_next_char_visually (&it->bidi_it);
+         bidi_move_to_visually_next (&it->bidi_it);
        }
       else
        {
@@ -6661,7 +6734,7 @@ next_element_from_buffer (it)
            {
              /* Now return to buffer position where we were asked to
                 get the next display element, and produce that.  */
-             bidi_get_next_char_visually (&it->bidi_it);
+             bidi_move_to_visually_next (&it->bidi_it);
            }
          while (it->bidi_it.bytepos != orig_bytepos
                 && it->bidi_it.bytepos < ZV_BYTE);
@@ -6672,6 +6745,13 @@ next_element_from_buffer (it)
       IT_CHARPOS (*it) = it->bidi_it.charpos;
       IT_BYTEPOS (*it) = it->bidi_it.bytepos;
       SET_TEXT_POS (it->position, IT_CHARPOS (*it), IT_BYTEPOS (*it));
+      {
+       EMACS_INT stop = it->stop_charpos;
+       if (it->bidi_it.scan_dir < 0)
+         stop = -1;
+       composition_compute_stop_pos (&it->cmp_it, IT_CHARPOS (*it),
+                                     IT_BYTEPOS (*it), stop, Qnil);
+      }
     }
 
   if (IT_CHARPOS (*it) >= it->stop_charpos)
@@ -6749,6 +6829,7 @@ next_element_from_buffer (it)
       /* No face changes, overlays etc. in sight, so just return a
         character from current_buffer.  */
       unsigned char *p;
+      EMACS_INT stop;
 
       /* Maybe run the redisplay end trigger hook.  Performance note:
         This doesn't seem to cost measurable time.  */
@@ -6757,8 +6838,9 @@ next_element_from_buffer (it)
          && IT_CHARPOS (*it) >= it->redisplay_end_trigger_charpos)
        run_redisplay_end_trigger_hook (it);
 
+      stop = it->bidi_it.scan_dir < 0 ? -1 : it->end_charpos;
       if (CHAR_COMPOSED_P (it, IT_CHARPOS (*it), IT_BYTEPOS (*it),
-                          it->end_charpos)
+                          stop)
          && next_element_from_composition (it))
        {
          return 1;
@@ -6814,8 +6896,7 @@ next_element_from_buffer (it)
 /* Run the redisplay end trigger hook for IT.  */
 
 static void
-run_redisplay_end_trigger_hook (it)
-     struct it *it;
+run_redisplay_end_trigger_hook (struct it *it)
 {
   Lisp_Object args[3];
 
@@ -6845,8 +6926,7 @@ run_redisplay_end_trigger_hook (it)
    next_element_from_string when necessary.  */
 
 static int
-next_element_from_composition (it)
-     struct it *it;
+next_element_from_composition (struct it *it)
 {
   it->what = IT_COMPOSITION;
   it->len = it->cmp_it.nbytes;
@@ -6869,6 +6949,15 @@ next_element_from_composition (it)
        {
          IT_CHARPOS (*it) += it->cmp_it.nchars;
          IT_BYTEPOS (*it) += it->cmp_it.nbytes;
+         if (it->bidi_p)
+           {
+             if (it->bidi_it.new_paragraph)
+               bidi_paragraph_init (it->paragraph_embedding, &it->bidi_it);
+             /* Resync the bidi iterator with IT's new position.
+                FIXME: this doesn't support bidirectional text.  */
+             while (it->bidi_it.charpos < IT_CHARPOS (*it))
+               bidi_move_to_visually_next (&it->bidi_it);
+           }
          return 0;
        }
       it->position = it->current.pos;
@@ -7360,10 +7449,7 @@ move_it_in_display_line (struct it *it,
    TO_CHARPOS.  */
 
 void
-move_it_to (it, to_charpos, to_x, to_y, to_vpos, op)
-     struct it *it;
-     int to_charpos, to_x, to_y, to_vpos;
-     int op;
+move_it_to (struct it *it, 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;
@@ -7614,9 +7700,7 @@ move_it_to (it, to_charpos, to_x, to_y, to_vpos, op)
    set to the top of the line moved to.  */
 
 void
-move_it_vertically_backward (it, dy)
-     struct it *it;
-     int dy;
+move_it_vertically_backward (struct it *it, int dy)
 {
   int nlines, h;
   struct it it2, it3;
@@ -7735,9 +7819,7 @@ move_it_vertically_backward (it, dy)
    end, IT will be on the start of a screen line.  */
 
 void
-move_it_vertically (it, dy)
-    struct it *it;
-    int dy;
+move_it_vertically (struct it *it, int dy)
 {
   if (dy <= 0)
     move_it_vertically_backward (it, -dy);
@@ -7761,8 +7843,7 @@ move_it_vertically (it, dy)
 /* Move iterator IT past the end of the text line it is in.  */
 
 void
-move_it_past_eol (it)
-     struct it *it;
+move_it_past_eol (struct it *it)
 {
   enum move_it_result rc;
 
@@ -7782,9 +7863,7 @@ move_it_past_eol (it)
    truncate-lines nil.  */
 
 void
-move_it_by_lines (it, dvpos, need_y_p)
-     struct it *it;
-     int dvpos, need_y_p;
+move_it_by_lines (struct it *it, int dvpos, int need_y_p)
 {
   struct position pos;
 
@@ -7878,8 +7957,7 @@ move_it_by_lines (it, dvpos, need_y_p)
 /* Return 1 if IT points into the middle of a display vector.  */
 
 int
-in_display_vector_p (it)
-     struct it *it;
+in_display_vector_p (struct it *it)
 {
   return (it->method == GET_FROM_DISPLAY_VECTOR
          && it->current.dpvec_index > 0
@@ -7896,9 +7974,7 @@ in_display_vector_p (it)
    to *Messages*.  */
 
 void
-add_to_log (format, arg1, arg2)
-     char *format;
-     Lisp_Object arg1, arg2;
+add_to_log (char *format, Lisp_Object arg1, Lisp_Object arg2)
 {
   Lisp_Object args[3];
   Lisp_Object msg, fmt;
@@ -7923,7 +7999,7 @@ add_to_log (format, arg1, arg2)
 
   len = SBYTES (msg) + 1;
   SAFE_ALLOCA (buffer, char *, len);
-  bcopy (SDATA (msg), buffer, len);
+  memcpy (buffer, SDATA (msg), len);
 
   message_dolog (buffer, len - 1, 1, 0);
   SAFE_FREE ();
@@ -7935,7 +8011,7 @@ add_to_log (format, arg1, arg2)
 /* Output a newline in the *Messages* buffer if "needs" one.  */
 
 void
-message_log_maybe_newline ()
+message_log_maybe_newline (void)
 {
   if (message_log_need_newline)
     message_dolog ("", 0, 1, 0);
@@ -7952,9 +8028,7 @@ message_log_maybe_newline ()
    so the buffer M must NOT point to a Lisp string.  */
 
 void
-message_dolog (m, nbytes, nlflag, multibyte)
-     const char *m;
-     int nbytes, nlflag, multibyte;
+message_dolog (const char *m, int nbytes, int nlflag, int multibyte)
 {
   if (!NILP (Vmemory_full))
     return;
@@ -8124,9 +8198,8 @@ message_dolog (m, nbytes, nlflag, multibyte)
    value N > 1 if we should also append " [N times]".  */
 
 static int
-message_log_check_duplicate (prev_bol, prev_bol_byte, this_bol, this_bol_byte)
-     int prev_bol, this_bol;
-     int prev_bol_byte, this_bol_byte;
+message_log_check_duplicate (int prev_bol, int prev_bol_byte,
+                            int this_bol, int this_bol_byte)
 {
   int i;
   int len = Z_BYTE - 1 - this_bol_byte;
@@ -8164,10 +8237,7 @@ message_log_check_duplicate (prev_bol, prev_bol_byte, this_bol, this_bol_byte)
    This may GC, so the buffer M must NOT point to a Lisp string.  */
 
 void
-message2 (m, nbytes, multibyte)
-     const char *m;
-     int nbytes;
-     int multibyte;
+message2 (const char *m, int nbytes, int multibyte)
 {
   /* First flush out any partial line written with print.  */
   message_log_maybe_newline ();
@@ -8180,9 +8250,7 @@ message2 (m, nbytes, multibyte)
 /* The non-logging counterpart of message2.  */
 
 void
-message2_nolog (m, nbytes, multibyte)
-     const char *m;
-     int nbytes, multibyte;
+message2_nolog (const char *m, int nbytes, int multibyte)
 {
   struct frame *sf = SELECTED_FRAME ();
   message_enable_multibyte = multibyte;
@@ -8244,10 +8312,7 @@ message2_nolog (m, nbytes, multibyte)
    This function cancels echoing.  */
 
 void
-message3 (m, nbytes, multibyte)
-     Lisp_Object m;
-     int nbytes;
-     int multibyte;
+message3 (Lisp_Object m, int nbytes, int multibyte)
 {
   struct gcpro gcpro1;
 
@@ -8263,7 +8328,7 @@ message3 (m, nbytes, multibyte)
       USE_SAFE_ALLOCA;
 
       SAFE_ALLOCA (buffer, char *, nbytes);
-      bcopy (SDATA (m), buffer, nbytes);
+      memcpy (buffer, SDATA (m), nbytes);
       message_dolog (buffer, nbytes, 1, multibyte);
       SAFE_FREE ();
     }
@@ -8279,9 +8344,7 @@ message3 (m, nbytes, multibyte)
    and make this cancel echoing.  */
 
 void
-message3_nolog (m, nbytes, multibyte)
-     Lisp_Object m;
-     int nbytes, multibyte;
+message3_nolog (Lisp_Object m, int nbytes, int multibyte)
 {
   struct frame *sf = SELECTED_FRAME ();
   message_enable_multibyte = multibyte;
@@ -8349,8 +8412,7 @@ message3_nolog (m, nbytes, multibyte)
    that was alloca'd.  */
 
 void
-message1 (m)
-     char *m;
+message1 (char *m)
 {
   message2 (m, (m ? strlen (m) : 0), 0);
 }
@@ -8359,8 +8421,7 @@ message1 (m)
 /* The non-logging counterpart of message1.  */
 
 void
-message1_nolog (m)
-     char *m;
+message1_nolog (char *m)
 {
   message2_nolog (m, (m ? strlen (m) : 0), 0);
 }
@@ -8369,10 +8430,7 @@ message1_nolog (m)
    which gets replaced with STRING.  */
 
 void
-message_with_string (m, string, log)
-     char *m;
-     Lisp_Object string;
-     int log;
+message_with_string (char *m, Lisp_Object string, int log)
 {
   CHECK_STRING (string);
 
@@ -8437,9 +8495,7 @@ message_with_string (m, string, log)
 
 /* VARARGS 1 */
 void
-message (m, a1, a2, a3)
-     char *m;
-     EMACS_INT a1, a2, a3;
+message (char *m, EMACS_INT a1, EMACS_INT a2, EMACS_INT a3)
 {
   if (noninteractive)
     {
@@ -8476,7 +8532,6 @@ message (m, a1, a2, a3)
          if (m)
            {
              int len;
-#ifdef NO_ARG_ARRAY
              char *a[3];
              a[0] = (char *) a1;
              a[1] = (char *) a2;
@@ -8484,11 +8539,6 @@ message (m, a1, a2, a3)
 
              len = doprnt (FRAME_MESSAGE_BUF (f),
                            FRAME_MESSAGE_BUF_SIZE (f), m, (char *)0, 3, a);
-#else
-             len = doprnt (FRAME_MESSAGE_BUF (f),
-                           FRAME_MESSAGE_BUF_SIZE (f), m, (char *)0, 3,
-                           (char **) &a1);
-#endif /* NO_ARG_ARRAY */
 
              message2 (FRAME_MESSAGE_BUF (f), len, 0);
            }
@@ -8506,9 +8556,7 @@ message (m, a1, a2, a3)
 /* The non-logging version of message.  */
 
 void
-message_nolog (m, a1, a2, a3)
-     char *m;
-     EMACS_INT a1, a2, a3;
+message_nolog (char *m, EMACS_INT a1, EMACS_INT a2, EMACS_INT a3)
 {
   Lisp_Object old_log_max;
   old_log_max = Vmessage_log_max;
@@ -8523,7 +8571,7 @@ message_nolog (m, a1, a2, a3)
    critical.  */
 
 void
-update_echo_area ()
+update_echo_area (void)
 {
   if (!NILP (echo_area_buffer[0]))
     {
@@ -8539,7 +8587,7 @@ update_echo_area ()
    If they aren't, make new ones.  */
 
 static void
-ensure_echo_area_buffers ()
+ensure_echo_area_buffers (void)
 {
   int i;
 
@@ -8583,13 +8631,9 @@ ensure_echo_area_buffers ()
    Value is what FN returns.  */
 
 static int
-with_echo_area_buffer (w, which, fn, a1, a2, a3, a4)
-     struct window *w;
-     int which;
-     int (*fn) P_ ((EMACS_INT, Lisp_Object, EMACS_INT, EMACS_INT));
-     EMACS_INT a1;
-     Lisp_Object a2;
-     EMACS_INT a3, a4;
+with_echo_area_buffer (struct window *w, int which,
+                      int (*fn) (EMACS_INT, Lisp_Object, EMACS_INT, EMACS_INT),
+                      EMACS_INT a1, Lisp_Object a2, EMACS_INT a3, EMACS_INT a4)
 {
   Lisp_Object buffer;
   int this_one, the_other, clear_buffer_p, rc;
@@ -8676,8 +8720,7 @@ with_echo_area_buffer (w, which, fn, a1, a2, a3, a4)
    FN called in with_echo_area_buffer.  */
 
 static Lisp_Object
-with_echo_area_buffer_unwind_data (w)
-     struct window *w;
+with_echo_area_buffer_unwind_data (struct window *w)
 {
   int i = 0;
   Lisp_Object vector, tmp;
@@ -8717,8 +8760,7 @@ with_echo_area_buffer_unwind_data (w)
    with_echo_area_buffer_unwind_data.  */
 
 static Lisp_Object
-unwind_with_echo_area_buffer (vector)
-     Lisp_Object vector;
+unwind_with_echo_area_buffer (Lisp_Object vector)
 {
   set_buffer_internal_1 (XBUFFER (AREF (vector, 0)));
   Vdeactivate_mark = AREF (vector, 1);
@@ -8748,8 +8790,7 @@ unwind_with_echo_area_buffer (vector)
    non-zero means we will print multibyte.  */
 
 void
-setup_echo_area_for_printing (multibyte_p)
-     int multibyte_p;
+setup_echo_area_for_printing (int multibyte_p)
 {
   /* If we can't find an echo area any more, exit.  */
   if (! FRAME_LIVE_P (XFRAME (selected_frame)))
@@ -8823,8 +8864,7 @@ setup_echo_area_for_printing (multibyte_p)
    display the current message.  */
 
 static int
-display_echo_area (w)
-     struct window *w;
+display_echo_area (struct window *w)
 {
   int i, no_message_p, window_height_changed_p, count;
 
@@ -8862,10 +8902,7 @@ display_echo_area (w)
    Value is non-zero if height of W was changed.  */
 
 static int
-display_echo_area_1 (a1, a2, a3, a4)
-     EMACS_INT a1;
-     Lisp_Object a2;
-     EMACS_INT a3, a4;
+display_echo_area_1 (EMACS_INT a1, Lisp_Object a2, EMACS_INT a3, EMACS_INT a4)
 {
   struct window *w = (struct window *) a1;
   Lisp_Object window;
@@ -8894,7 +8931,7 @@ display_echo_area_1 (a1, a2, a3, a4)
    is active, don't shrink it.  */
 
 void
-resize_echo_area_exactly ()
+resize_echo_area_exactly (void)
 {
   if (BUFFERP (echo_area_buffer[0])
       && WINDOWP (echo_area_window))
@@ -8927,10 +8964,7 @@ resize_echo_area_exactly ()
    resize_mini_window returns.  */
 
 static int
-resize_mini_window_1 (a1, exactly, a3, a4)
-     EMACS_INT a1;
-     Lisp_Object exactly;
-     EMACS_INT a3, a4;
+resize_mini_window_1 (EMACS_INT a1, Lisp_Object exactly, EMACS_INT a3, EMACS_INT a4)
 {
   return resize_mini_window ((struct window *) a1, !NILP (exactly));
 }
@@ -8948,9 +8982,7 @@ resize_mini_window_1 (a1, exactly, a3, a4)
    Value is non-zero if the window height has been changed.  */
 
 int
-resize_mini_window (w, exact_p)
-     struct window *w;
-     int exact_p;
+resize_mini_window (struct window *w, int exact_p)
 {
   struct frame *f = XFRAME (w->frame);
   int window_height_changed_p = 0;
@@ -9091,7 +9123,7 @@ resize_mini_window (w, exact_p)
    current message.  */
 
 Lisp_Object
-current_message ()
+current_message (void)
 {
   Lisp_Object msg;
 
@@ -9110,10 +9142,7 @@ current_message ()
 
 
 static int
-current_message_1 (a1, a2, a3, a4)
-     EMACS_INT a1;
-     Lisp_Object a2;
-     EMACS_INT a3, a4;
+current_message_1 (EMACS_INT a1, Lisp_Object a2, EMACS_INT a3, EMACS_INT a4)
 {
   Lisp_Object *msg = (Lisp_Object *) a1;
 
@@ -9131,7 +9160,7 @@ current_message_1 (a1, a2, a3, a4)
    worth optimizing.  */
 
 int
-push_message ()
+push_message (void)
 {
   Lisp_Object msg;
   msg = current_message ();
@@ -9143,7 +9172,7 @@ push_message ()
 /* Restore message display from the top of Vmessage_stack.  */
 
 void
-restore_message ()
+restore_message (void)
 {
   Lisp_Object msg;
 
@@ -9159,8 +9188,7 @@ restore_message ()
 /* Handler for record_unwind_protect calling pop_message.  */
 
 Lisp_Object
-pop_message_unwind (dummy)
-     Lisp_Object dummy;
+pop_message_unwind (Lisp_Object dummy)
 {
   pop_message ();
   return Qnil;
@@ -9169,7 +9197,7 @@ pop_message_unwind (dummy)
 /* Pop the top-most entry off Vmessage_stack.  */
 
 void
-pop_message ()
+pop_message (void)
 {
   xassert (CONSP (Vmessage_stack));
   Vmessage_stack = XCDR (Vmessage_stack);
@@ -9181,7 +9209,7 @@ pop_message ()
    somewhere.  */
 
 void
-check_message_stack ()
+check_message_stack (void)
 {
   if (!NILP (Vmessage_stack))
     abort ();
@@ -9192,8 +9220,7 @@ check_message_stack ()
    time we display it---but don't redisplay it now.  */
 
 void
-truncate_echo_area (nchars)
-     int nchars;
+truncate_echo_area (int nchars)
 {
   if (nchars == 0)
     echo_area_buffer[0] = Qnil;
@@ -9215,10 +9242,7 @@ truncate_echo_area (nchars)
    message to at most NCHARS characters.  */
 
 static int
-truncate_message_1 (nchars, a2, a3, a4)
-     EMACS_INT nchars;
-     Lisp_Object a2;
-     EMACS_INT a3, a4;
+truncate_message_1 (EMACS_INT nchars, Lisp_Object a2, EMACS_INT a3, EMACS_INT a4)
 {
   if (BEG + nchars < Z)
     del_range (BEG + nchars, Z);
@@ -9243,10 +9267,7 @@ truncate_message_1 (nchars, a2, a3, a4)
   */
 
 void
-set_message (s, string, nbytes, multibyte_p)
-     const char *s;
-     Lisp_Object string;
-     int nbytes, multibyte_p;
+set_message (const char *s, Lisp_Object string, int nbytes, int multibyte_p)
 {
   message_enable_multibyte
     = ((s && multibyte_p)
@@ -9265,10 +9286,7 @@ set_message (s, string, nbytes, multibyte_p)
    current.  */
 
 static int
-set_message_1 (a1, a2, nbytes, multibyte_p)
-     EMACS_INT a1;
-     Lisp_Object a2;
-     EMACS_INT nbytes, multibyte_p;
+set_message_1 (EMACS_INT a1, Lisp_Object a2, EMACS_INT nbytes, EMACS_INT multibyte_p)
 {
   const char *s = (const char *) a1;
   Lisp_Object string = a2;
@@ -9347,8 +9365,7 @@ set_message_1 (a1, a2, nbytes, multibyte_p)
    last displayed.  */
 
 void
-clear_message (current_p, last_displayed_p)
-     int current_p, last_displayed_p;
+clear_message (int current_p, int last_displayed_p)
 {
   if (current_p)
     {
@@ -9372,7 +9389,7 @@ clear_message (current_p, last_displayed_p)
    and ensure a complete redisplay of all windows.  */
 
 static void
-clear_garbaged_frames ()
+clear_garbaged_frames (void)
 {
   if (frame_garbaged)
     {
@@ -9409,8 +9426,7 @@ clear_garbaged_frames ()
    mini-windows height has been changed.  */
 
 static int
-echo_area_display (update_frame_p)
-     int update_frame_p;
+echo_area_display (int update_frame_p)
 {
   Lisp_Object mini_window;
   struct window *w;
@@ -9585,8 +9601,7 @@ format_mode_line_unwind_data (struct buffer *obuf,
 }
 
 static Lisp_Object
-unwind_format_mode_line (vector)
-     Lisp_Object vector;
+unwind_format_mode_line (Lisp_Object vector)
 {
   mode_line_target = XINT (AREF (vector, 0));
   mode_line_noprop_ptr = mode_line_noprop_buf + XINT (AREF (vector, 1));
@@ -9646,9 +9661,7 @@ store_mode_line_noprop_char (c)
    frame title.  */
 
 static int
-store_mode_line_noprop (str, field_width, precision)
-     const unsigned char *str;
-     int field_width, precision;
+store_mode_line_noprop (const unsigned char *str, int field_width, int precision)
 {
   int n = 0;
   int dummy, nbytes;
@@ -9681,8 +9694,7 @@ store_mode_line_noprop (str, field_width, precision)
    frame_title_format.  */
 
 static void
-x_consider_frame_title (frame)
-     Lisp_Object frame;
+x_consider_frame_title (Lisp_Object frame)
 {
   struct frame *f = XFRAME (frame);
 
@@ -9742,7 +9754,7 @@ x_consider_frame_title (frame)
         higher level than this.)  */
       if (! STRINGP (f->name)
          || SBYTES (f->name) != len
-         || bcmp (title, SDATA (f->name), len) != 0)
+         || memcmp (title, SDATA (f->name), len) != 0)
        x_implicitly_set_name (f, make_string (title, len), Qnil);
     }
 }
@@ -9761,7 +9773,7 @@ x_consider_frame_title (frame)
    appropriate.  This can call eval.  */
 
 void
-prepare_menu_bars ()
+prepare_menu_bars (void)
 {
   int all_windows;
   struct gcpro gcpro1, gcpro2;
@@ -9841,7 +9853,8 @@ prepare_menu_bars ()
          update_tool_bar (f, 0);
 #endif
 #ifdef HAVE_NS
-          if (windows_or_buffers_changed)
+          if (windows_or_buffers_changed
+             && FRAME_NS_P (f))
             ns_set_doc_edited (f, Fbuffer_modified_p
                               (XWINDOW (f->selected_window)->buffer));
 #endif
@@ -9879,10 +9892,7 @@ prepare_menu_bars ()
    updated value of this flag, to pass to the next call.  */
 
 static int
-update_menu_bar (f, save_match_data, hooks_run)
-     struct frame *f;
-     int save_match_data;
-     int hooks_run;
+update_menu_bar (struct frame *f, int save_match_data, int hooks_run)
 {
   Lisp_Object window;
   register struct window *w;
@@ -10007,8 +10017,7 @@ struct cursor_pos output_cursor;
    positions are relative to updated_window.  */
 
 void
-set_output_cursor (cursor)
-    struct cursor_pos *cursor;
+set_output_cursor (struct cursor_pos *cursor)
 {
   output_cursor.hpos = cursor->hpos;
   output_cursor.vpos = cursor->vpos;
@@ -10029,8 +10038,7 @@ set_output_cursor (cursor)
    selected_window and display the cursor at the given position.  */
 
 void
-x_cursor_to (vpos, hpos, y, x)
-     int vpos, hpos, y, x;
+x_cursor_to (int vpos, int hpos, int y, int x)
 {
   struct window *w;
 
@@ -10078,8 +10086,7 @@ int last_tool_bar_item;
 
 
 static Lisp_Object
-update_tool_bar_unwind (frame)
-     Lisp_Object frame;
+update_tool_bar_unwind (Lisp_Object frame)
 {
   selected_frame = frame;
   return Qnil;
@@ -10091,9 +10098,7 @@ update_tool_bar_unwind (frame)
    and restore it here.  */
 
 static void
-update_tool_bar (f, save_match_data)
-     struct frame *f;
-     int save_match_data;
+update_tool_bar (struct frame *f, int save_match_data)
 {
 #if defined (USE_GTK) || defined (HAVE_NS)
   int do_update = FRAME_EXTERNAL_TOOL_BAR (f);
@@ -10191,8 +10196,7 @@ update_tool_bar (f, save_match_data)
    been set up previously by calling prepare_menu_bars.  */
 
 static void
-build_desired_tool_bar_string (f)
-     struct frame *f;
+build_desired_tool_bar_string (struct frame *f)
 {
   int i, size, size_needed;
   struct gcpro gcpro1, gcpro2, gcpro3;
@@ -10363,9 +10367,7 @@ build_desired_tool_bar_string (f)
 */
 
 static void
-display_tool_bar_line (it, height)
-     struct it *it;
-     int height;
+display_tool_bar_line (struct it *it, int height)
 {
   struct glyph_row *row = it->glyph_row;
   int max_x = it->last_visible_x;
@@ -10492,9 +10494,7 @@ display_tool_bar_line (it, height)
    returned in *N_ROWS if non-NULL.  */
 
 static int
-tool_bar_lines_needed (f, n_rows)
-     struct frame *f;
-     int *n_rows;
+tool_bar_lines_needed (struct frame *f, int *n_rows)
 {
   struct window *w = XWINDOW (f->tool_bar_window);
   struct it it;
@@ -10562,8 +10562,7 @@ DEFUN ("tool-bar-lines-needed", Ftool_bar_lines_needed, Stool_bar_lines_needed,
    height should be changed.  */
 
 static int
-redisplay_tool_bar (f)
-     struct frame *f;
+redisplay_tool_bar (struct frame *f)
 {
   struct window *w;
   struct it it;
@@ -10734,10 +10733,7 @@ redisplay_tool_bar (f)
    GLYPH doesn't display a tool-bar item.  */
 
 static int
-tool_bar_item_info (f, glyph, prop_idx)
-     struct frame *f;
-     struct glyph *glyph;
-     int *prop_idx;
+tool_bar_item_info (struct frame *f, struct glyph *glyph, int *prop_idx)
 {
   Lisp_Object prop;
   int success_p;
@@ -10777,11 +10773,8 @@ tool_bar_item_info (f, glyph, prop_idx)
    1   otherwise.  */
 
 static int
-get_tool_bar_item (f, x, y, glyph, hpos, vpos, prop_idx)
-     struct frame *f;
-     int x, y;
-     struct glyph **glyph;
-     int *hpos, *vpos, *prop_idx;
+get_tool_bar_item (struct frame *f, int x, int y, struct glyph **glyph,
+                  int *hpos, int *vpos, int *prop_idx)
 {
   Display_Info *dpyinfo = FRAME_X_DISPLAY_INFO (f);
   struct window *w = XWINDOW (f->tool_bar_window);
@@ -10819,10 +10812,8 @@ get_tool_bar_item (f, x, y, glyph, hpos, vpos, prop_idx)
    release.  */
 
 void
-handle_tool_bar_click (f, x, y, down_p, modifiers)
-     struct frame *f;
-     int x, y, down_p;
-     unsigned int modifiers;
+handle_tool_bar_click (struct frame *f, int x, int y, int down_p,
+                      unsigned int modifiers)
 {
   Display_Info *dpyinfo = FRAME_X_DISPLAY_INFO (f);
   struct window *w = XWINDOW (f->tool_bar_window);
@@ -10880,9 +10871,7 @@ handle_tool_bar_click (f, x, y, down_p, modifiers)
    note_mouse_highlight.  */
 
 static void
-note_tool_bar_highlight (f, x, y)
-     struct frame *f;
-     int x, y;
+note_tool_bar_highlight (struct frame *f, int x, int y)
 {
   Lisp_Object window = f->tool_bar_window;
   struct window *w = XWINDOW (window);
@@ -10976,8 +10965,8 @@ note_tool_bar_highlight (f, x, y)
                         Horizontal scrolling
  ************************************************************************/
 
-static int hscroll_window_tree P_ ((Lisp_Object));
-static int hscroll_windows P_ ((Lisp_Object));
+static int hscroll_window_tree (Lisp_Object);
+static int hscroll_windows (Lisp_Object);
 
 /* For all leaf windows in the window tree rooted at WINDOW, set their
    hscroll value so that PT is (i) visible in the window, and (ii) so
@@ -10986,8 +10975,7 @@ static int hscroll_windows P_ ((Lisp_Object));
    changed.  */
 
 static int
-hscroll_window_tree (window)
-     Lisp_Object window;
+hscroll_window_tree (Lisp_Object window)
 {
   int hscrolled_p = 0;
   int hscroll_relative_p = FLOATP (Vhscroll_step);
@@ -11130,8 +11118,7 @@ hscroll_window_tree (window)
    of WINDOW are cleared.  */
 
 static int
-hscroll_windows (window)
-     Lisp_Object window;
+hscroll_windows (Lisp_Object window)
 {
   int hscrolled_p = hscroll_window_tree (window);
   if (hscrolled_p)
@@ -11214,9 +11201,7 @@ debug_method_add (w, fmt, a1, a2, a3, a4, a5, a6, a7, a8, a9)
    redisplay_internal for display optimization.  */
 
 static INLINE int
-text_outside_line_unchanged_p (w, start, end)
-     struct window *w;
-     int start, end;
+text_outside_line_unchanged_p (struct window *w, int start, int end)
 {
   int unchanged_p = 1;
 
@@ -11283,15 +11268,14 @@ text_outside_line_unchanged_p (w, start, end)
    mini-buffer if that is in use.  */
 
 void
-redisplay ()
+redisplay (void)
 {
   redisplay_internal (0);
 }
 
 
 static Lisp_Object
-overlay_arrow_string_or_property (var)
-     Lisp_Object var;
+overlay_arrow_string_or_property (Lisp_Object var)
 {
   Lisp_Object val;
 
@@ -11303,7 +11287,7 @@ overlay_arrow_string_or_property (var)
 
 /* Return 1 if there are any overlay-arrows in current_buffer.  */
 static int
-overlay_arrow_in_current_buffer_p ()
+overlay_arrow_in_current_buffer_p (void)
 {
   Lisp_Object vlist;
 
@@ -11329,7 +11313,7 @@ overlay_arrow_in_current_buffer_p ()
    has changed.  */
 
 static int
-overlay_arrows_changed_p ()
+overlay_arrows_changed_p (void)
 {
   Lisp_Object vlist;
 
@@ -11357,8 +11341,7 @@ overlay_arrows_changed_p ()
 /* Mark overlay arrows to be updated on next redisplay.  */
 
 static void
-update_overlay_arrows (up_to_date)
-     int up_to_date;
+update_overlay_arrows (int up_to_date)
 {
   Lisp_Object vlist;
 
@@ -11394,9 +11377,7 @@ update_overlay_arrows (up_to_date)
    Return nil if no overlay arrow.  */
 
 static Lisp_Object
-overlay_arrow_at_row (it, row)
-     struct it *it;
-     struct glyph_row *row;
+overlay_arrow_at_row (struct it *it, struct glyph_row *row)
 {
   Lisp_Object vlist;
 
@@ -11441,9 +11422,8 @@ overlay_arrow_at_row (it, row)
    position.  BUF and PT are the current point buffer and position.  */
 
 int
-check_point_in_composition (prev_buf, prev_pt, buf, pt)
-     struct buffer *prev_buf, *buf;
-     int prev_pt, pt;
+check_point_in_composition (struct buffer *prev_buf, int prev_pt,
+                           struct buffer *buf, int pt)
 {
   EMACS_INT start, end;
   Lisp_Object prop;
@@ -11479,9 +11459,7 @@ check_point_in_composition (prev_buf, prev_pt, buf, pt)
    in window W.  */
 
 static INLINE void
-reconsider_clip_changes (w, b)
-     struct window *w;
-     struct buffer *b;
+reconsider_clip_changes (struct window *w, struct buffer *b)
 {
   if (b->clip_changed
           && !NILP (w->window_end_valid)
@@ -11520,10 +11498,9 @@ reconsider_clip_changes (w, b)
    directly.  */
 
 static void
-select_frame_for_redisplay (frame)
-     Lisp_Object frame;
+select_frame_for_redisplay (Lisp_Object frame)
 {
-  Lisp_Object tail, symbol, val;
+  Lisp_Object tail, tem;
   Lisp_Object old = selected_frame;
   struct Lisp_Symbol *sym;
 
@@ -11531,20 +11508,18 @@ select_frame_for_redisplay (frame)
 
   selected_frame = frame;
 
-  do
-    {
-      for (tail = XFRAME (frame)->param_alist; CONSP (tail); tail = XCDR (tail))
-       if (CONSP (XCAR (tail))
-           && (symbol = XCAR (XCAR (tail)),
-               SYMBOLP (symbol))
-           && (sym = indirect_variable (XSYMBOL (symbol)),
-               val = sym->value,
-               (BUFFER_LOCAL_VALUEP (val)))
-           && XBUFFER_LOCAL_VALUE (val)->check_frame)
-         /* Use find_symbol_value rather than Fsymbol_value
-            to avoid an error if it is void.  */
-         find_symbol_value (symbol);
-    } while (!EQ (frame, old) && (frame = old, 1));
+  do {
+    for (tail = XFRAME (frame)->param_alist; CONSP (tail); tail = XCDR (tail))
+      if (CONSP (XCAR (tail))
+         && (tem = XCAR (XCAR (tail)),
+             SYMBOLP (tem))
+         && (sym = indirect_variable (XSYMBOL (tem)),
+             sym->redirect == SYMBOL_LOCALIZED)
+         && sym->val.blv->frame_local)
+       /* Use find_symbol_value rather than Fsymbol_value
+          to avoid an error if it is void.  */
+       find_symbol_value (tem);
+  } while (!EQ (frame, old) && (frame = old, 1));
 }
 
 
@@ -11564,8 +11539,7 @@ do { if (polling_stopped_here) start_polling ();        \
    causes some problems.  */
 
 static void
-redisplay_internal (preserve_echo_area)
-     int preserve_echo_area;
+redisplay_internal (int preserve_echo_area)
 {
   struct window *w = XWINDOW (selected_window);
   struct frame *f;
@@ -12260,22 +12234,25 @@ redisplay_internal (preserve_echo_area)
   if (windows_or_buffers_changed && !pause)
     goto retry;
 
-  /* Clear the face cache eventually.  */
-  if (consider_all_windows_p)
+  /* Clear the face and image caches.
+
+     We used to do this only if consider_all_windows_p.  But the cache
+     needs to be cleared if a timer creates images in the current
+     buffer (e.g. the test case in Bug#6230).  */
+
+  if (clear_face_cache_count > CLEAR_FACE_CACHE_COUNT)
     {
-      if (clear_face_cache_count > CLEAR_FACE_CACHE_COUNT)
-       {
-         clear_face_cache (0);
-         clear_face_cache_count = 0;
-       }
+      clear_face_cache (0);
+      clear_face_cache_count = 0;
+    }
+
 #ifdef HAVE_WINDOW_SYSTEM
-      if (clear_image_cache_count > CLEAR_IMAGE_CACHE_COUNT)
-       {
-         clear_image_caches (Qnil);
-         clear_image_cache_count = 0;
-       }
-#endif /* HAVE_WINDOW_SYSTEM */
+  if (clear_image_cache_count > CLEAR_IMAGE_CACHE_COUNT)
+    {
+      clear_image_caches (Qnil);
+      clear_image_cache_count = 0;
     }
+#endif /* HAVE_WINDOW_SYSTEM */
 
  end_of_redisplay:
   unbind_to (count, Qnil);
@@ -12295,8 +12272,7 @@ redisplay_internal (preserve_echo_area)
    called.  This is useful for debugging.  */
 
 void
-redisplay_preserve_echo_area (from_where)
-     int from_where;
+redisplay_preserve_echo_area (int from_where)
 {
   TRACE ((stderr, "redisplay_preserve_echo_area (%d)\n", from_where));
 
@@ -12325,8 +12301,7 @@ redisplay_preserve_echo_area (from_where)
    failure during redisplay, for example).  */
 
 static Lisp_Object
-unwind_redisplay (val)
-     Lisp_Object val;
+unwind_redisplay (Lisp_Object val)
 {
   Lisp_Object old_redisplaying_p, old_frame;
 
@@ -12346,9 +12321,7 @@ unwind_redisplay (val)
    redisplay_internal is called.  */
 
 static void
-mark_window_display_accurate_1 (w, accurate_p)
-     struct window *w;
-     int accurate_p;
+mark_window_display_accurate_1 (struct window *w, int accurate_p)
 {
   if (BUFFERP (w->buffer))
     {
@@ -12399,9 +12372,7 @@ mark_window_display_accurate_1 (w, accurate_p)
    be redisplayed the next time redisplay_internal is called.  */
 
 void
-mark_window_display_accurate (window, accurate_p)
-     Lisp_Object window;
-     int accurate_p;
+mark_window_display_accurate (Lisp_Object window, int accurate_p)
 {
   struct window *w;
 
@@ -12436,9 +12407,7 @@ mark_window_display_accurate (window, accurate_p)
    macro DISP_CHAR_VECTOR.  */
 
 Lisp_Object
-disp_char_vector (dp, c)
-     struct Lisp_Char_Table *dp;
-     int c;
+disp_char_vector (struct Lisp_Char_Table *dp, int c)
 {
   Lisp_Object val;
 
@@ -12469,8 +12438,7 @@ disp_char_vector (dp, c)
 /* Redisplay all leaf windows in the window tree rooted at WINDOW.  */
 
 static void
-redisplay_windows (window)
-     Lisp_Object window;
+redisplay_windows (Lisp_Object window)
 {
   while (!NILP (window))
     {
@@ -12495,15 +12463,14 @@ redisplay_windows (window)
 }
 
 static Lisp_Object
-redisplay_window_error ()
+redisplay_window_error (Lisp_Object ignore)
 {
   displayed_buffer->display_error_modiff = BUF_MODIFF (displayed_buffer);
   return Qnil;
 }
 
 static Lisp_Object
-redisplay_window_0 (window)
-     Lisp_Object window;
+redisplay_window_0 (Lisp_Object window)
 {
   if (displayed_buffer->display_error_modiff < BUF_MODIFF (displayed_buffer))
     redisplay_window (window, 0);
@@ -12511,8 +12478,7 @@ redisplay_window_0 (window)
 }
 
 static Lisp_Object
-redisplay_window_1 (window)
-     Lisp_Object window;
+redisplay_window_1 (Lisp_Object window)
 {
   if (displayed_buffer->display_error_modiff < BUF_MODIFF (displayed_buffer))
     redisplay_window (window, 1);
@@ -12540,11 +12506,9 @@ redisplay_window_1 (window)
    Return 0 if cursor is not on this row, 1 otherwise.  */
 
 int
-set_cursor_from_row (w, row, matrix, delta, delta_bytes, dy, dvpos)
-     struct window *w;
-     struct glyph_row *row;
-     struct glyph_matrix *matrix;
-     int delta, delta_bytes, dy, dvpos;
+set_cursor_from_row (struct window *w, struct glyph_row *row,
+                    struct glyph_matrix *matrix, int delta, int delta_bytes,
+                    int dy, int dvpos)
 {
   struct glyph *glyph = row->glyphs[TEXT_AREA];
   struct glyph *end = glyph + row->used[TEXT_AREA];
@@ -12587,8 +12551,8 @@ set_cursor_from_row (w, row, matrix, delta, delta_bytes, dy, dvpos)
            }
          while (end > glyph
                 && INTEGERP ((end - 1)->object)
-                /* CHARPOS is zero for blanks inserted by
-                   extend_face_to_end_of_line.  */
+                /* CHARPOS is zero for blanks and stretch glyphs
+                   inserted by extend_face_to_end_of_line.  */
                 && (end - 1)->charpos <= 0)
            --end;
          glyph_before = glyph - 1;
@@ -12630,6 +12594,13 @@ set_cursor_from_row (w, row, matrix, delta, delta_bytes, dy, dvpos)
         rightmost glyph.  Case in point: an empty last line that is
         part of an R2L paragraph.  */
       cursor = end - 1;
+      /* Avoid placing the cursor on the last glyph of the row, where
+        on terminal frames we hold the vertical border between
+        adjacent windows.  */
+      if (!FRAME_WINDOW_P (WINDOW_XFRAME (w))
+         && !WINDOW_RIGHTMOST_P (w)
+         && cursor == row->glyphs[LAST_AREA] - 1)
+       cursor--;
       x = -1;  /* will be computed below, at label compute_x */
     }
 
@@ -12810,7 +12781,10 @@ set_cursor_from_row (w, row, matrix, delta, delta_bytes, dy, dvpos)
        }
       else if (match_with_avoid_cursor
               /* zero-width characters produce no glyphs */
-              || eabs (glyph_after - glyph_before) == 1)
+              || ((row->reversed_p
+                   ? glyph_after > glyphs_end
+                   : glyph_after < glyphs_end)
+                  && eabs (glyph_after - glyph_before) == 1))
        {
          cursor = glyph_after;
          x = -1;
@@ -12866,7 +12840,8 @@ set_cursor_from_row (w, row, matrix, delta, delta_bytes, dy, dvpos)
 
                          cursor = glyph;
                          for (glyph += incr;
-                              EQ (glyph->object, str);
+                              (row->reversed_p ? glyph > stop : glyph < stop)
+                                && EQ (glyph->object, str);
                               glyph += incr)
                            {
                              Lisp_Object cprop;
@@ -12906,8 +12881,9 @@ set_cursor_from_row (w, row, matrix, delta, delta_bytes, dy, dvpos)
 
          /* If we reached the end of the line, and END was from a string,
             the cursor is not on this line.  */
-         if (glyph == end
-             && STRINGP ((glyph - incr)->object)
+         if (cursor == NULL
+             && (row->reversed_p ? glyph <= end : glyph >= end)
+             && STRINGP (end->object)
              && row->continued_p)
            return 0;
        }
@@ -12929,11 +12905,17 @@ set_cursor_from_row (w, row, matrix, delta, delta_bytes, dy, dvpos)
        }
     }
 
-  /* ROW could be part of a continued line, which might have other
-     rows whose start and end charpos occlude point.  Only set
-     w->cursor if we found a better approximation to the cursor
-     position than we have from previously examined rows.  */
-  if (w->cursor.vpos >= 0
+  /* ROW could be part of a continued line, which, under bidi
+     reordering, might have other rows whose start and end charpos
+     occlude point.  Only set w->cursor if we found a better
+     approximation to the cursor position than we have from previously
+     examined candidate rows belonging to the same continued line.  */
+  if (/* we already have a candidate row */
+      w->cursor.vpos >= 0
+      /* that candidate is not the row we are processing */
+      && MATRIX_ROW (matrix, w->cursor.vpos) != row
+      /* the row we are processing is part of a continued line */
+      && (row->continued_p || MATRIX_ROW_CONTINUATION_LINE_P (row))
       /* Make sure cursor.vpos specifies a row whose start and end
         charpos occlude point.  This is because some callers of this
         function leave cursor.vpos at the row where the cursor was
@@ -12951,7 +12933,7 @@ set_cursor_from_row (w, row, matrix, delta, delta_bytes, dy, dvpos)
         point.  */
       if (/* previous candidate is a glyph in TEXT_AREA of that row */
          w->cursor.hpos >= 0
-         && w->cursor.hpos < MATRIX_ROW_USED(matrix, w->cursor.vpos)
+         && w->cursor.hpos < MATRIX_ROW_USED (matrix, w->cursor.vpos)
          && BUFFERP (g1->object)
          && (g1->charpos == pt_old /* an exact match always wins */
              || (BUFFERP (glyph->object)
@@ -13012,9 +12994,7 @@ set_cursor_from_row (w, row, matrix, delta, delta_bytes, dy, dvpos)
    We assume that the window's buffer is really current.  */
 
 static INLINE struct text_pos
-run_window_scroll_functions (window, startp)
-     Lisp_Object window;
-     struct text_pos startp;
+run_window_scroll_functions (Lisp_Object window, struct text_pos startp)
 {
   struct window *w = XWINDOW (window);
   SET_MARKER_FROM_TEXT_POS (w->start, startp);
@@ -13048,10 +13028,7 @@ run_window_scroll_functions (window, startp)
    as if point had gone off the screen.  */
 
 static int
-cursor_row_fully_visible_p (w, force_p, current_matrix_p)
-     struct window *w;
-     int force_p;
-     int current_matrix_p;
+cursor_row_fully_visible_p (struct window *w, int force_p, int current_matrix_p)
 {
   struct glyph_matrix *matrix;
   struct glyph_row *row;
@@ -13184,14 +13161,22 @@ try_scrolling (window, just_this_one_p, scroll_conservatively,
       if (PT > CHARPOS (it.current.pos))
        {
          int y0 = line_bottom_y (&it);
-
-         /* Compute the distance from the scroll margin to PT
-            (including the height of the cursor line).  Moving the
-            iterator unconditionally to PT can be slow if PT is far
-            away, so stop 10 lines past the window bottom (is there a
-            way to do the right thing quickly?).  */
-         move_it_to (&it, PT, -1,
-                     it.last_visible_y + 10 * FRAME_LINE_HEIGHT (f),
+         /* Compute how many pixels below window bottom to stop searching
+            for PT.  This avoids costly search for PT that is far away if
+            the user limited scrolling by a small number of lines, but
+            always finds PT if scroll_conservatively is set to a large
+            number, such as most-positive-fixnum.  */
+         int slack = max (scroll_max, 10 * FRAME_LINE_HEIGHT (f));
+         int y_to_move =
+           slack >= INT_MAX - it.last_visible_y
+           ? INT_MAX
+           : it.last_visible_y + slack;
+
+         /* Compute the distance from the scroll margin to PT or to
+            the scroll limit, whichever comes first.  This should
+            include the height of the cursor line, to make that line
+            fully visible.  */
+         move_it_to (&it, PT, -1, y_to_move,
                      -1, MOVE_TO_POS | MOVE_TO_Y);
          dy = line_bottom_y (&it) - y0;
 
@@ -13231,7 +13216,26 @@ try_scrolling (window, just_this_one_p, scroll_conservatively,
        return SCROLLING_FAILED;
 
       start_display (&it, w, startp);
-      move_it_vertically (&it, amount_to_scroll);
+      if (scroll_max < INT_MAX)
+       move_it_vertically (&it, amount_to_scroll);
+      else
+       {
+         /* Extra precision for users who set scroll-conservatively
+            to most-positive-fixnum: make sure the amount we scroll
+            the window start is never less than amount_to_scroll,
+            which was computed as distance from window bottom to
+            point.  This matters when lines at window top and lines
+            below window bottom have different height.  */
+         struct it it1 = it;
+         /* We use a temporary it1 because line_bottom_y can modify
+            its argument, if it moves one line down; see there.  */
+         int start_y = line_bottom_y (&it1);
+
+         do {
+           move_it_by_lines (&it, 1, 1);
+           it1 = it;
+         } while (line_bottom_y (&it1) - start_y < amount_to_scroll);
+       }
 
       /* If STARTP is unchanged, move it down another screen line.  */
       if (CHARPOS (it.current.pos) == CHARPOS (startp))
@@ -13343,8 +13347,7 @@ try_scrolling (window, just_this_one_p, scroll_conservatively,
    screen line with the minimum distance from the old start W->start.  */
 
 static int
-compute_window_start_on_continuation_line (w)
-     struct window *w;
+compute_window_start_on_continuation_line (struct window *w)
 {
   struct text_pos pos, start_pos;
   int window_start_changed_p = 0;
@@ -13430,10 +13433,7 @@ enum
 };
 
 static int
-try_cursor_movement (window, startp, scroll_step)
-     Lisp_Object window;
-     struct text_pos startp;
-     int *scroll_step;
+try_cursor_movement (Lisp_Object window, struct text_pos startp, int *scroll_step)
 {
   struct window *w = XWINDOW (window);
   struct frame *f = XFRAME (w->frame);
@@ -13516,37 +13516,11 @@ try_cursor_movement (window, startp, scroll_step)
            ++row;
          if (!row->enabled_p)
            rc = CURSOR_MOVEMENT_MUST_SCROLL;
-         /* If rows are bidi-reordered, back up until we find a row
-            that does not belong to a continuation line.  This is
-            because we must consider all rows of a continued line as
-            candidates for cursor positioning, since row start and
-            end positions change non-linearly with vertical position
-            in such rows.  */
-         /* FIXME: Revisit this when glyph ``spilling'' in
-            continuation lines' rows is implemented for
-            bidi-reordered rows.  */
-         if (!NILP (XBUFFER (w->buffer)->bidi_display_reordering))
-           {
-             while (MATRIX_ROW_CONTINUATION_LINE_P (row))
-               {
-                 xassert (row->enabled_p);
-                 --row;
-                 /* If we hit the beginning of the displayed portion
-                    without finding the first row of a continued
-                    line, give up.  */
-                 if (row <= w->current_matrix->rows)
-                   {
-                     rc = CURSOR_MOVEMENT_MUST_SCROLL;
-                     break;
-                   }
-
-               }
-           }
        }
 
       if (rc == CURSOR_MOVEMENT_CANNOT_BE_USED)
        {
-         int scroll_p = 0;
+         int scroll_p = 0, must_scroll = 0;
          int last_y = window_text_bottom_y (w) - this_scroll_margin;
 
          if (PT > XFASTINT (w->last_point))
@@ -13559,11 +13533,14 @@ try_cursor_movement (window, startp, scroll_step)
                  ++row;
                }
 
-             /* The end position of a row equals the start position
-                of the next row.  If PT is there, we would rather
-                display it in the next line.  */
+             /* If the end position of a row equals the start
+                position of the next row, and PT is at that position,
+                we would rather display cursor in the next line.  */
              while (MATRIX_ROW_BOTTOM_Y (row) < last_y
                     && MATRIX_ROW_END_CHARPOS (row) == PT
+                    && row < w->current_matrix->rows
+                               + w->current_matrix->nrows - 1
+                    && MATRIX_ROW_START_CHARPOS (row+1) == PT
                     && !cursor_row_p (w, row))
                ++row;
 
@@ -13636,10 +13613,41 @@ try_cursor_movement (window, startp, scroll_step)
            {
              /* if PT is not in the glyph row, give up.  */
              rc = CURSOR_MOVEMENT_MUST_SCROLL;
+             must_scroll = 1;
            }
          else if (rc != CURSOR_MOVEMENT_SUCCESS
-                  && MATRIX_ROW_PARTIALLY_VISIBLE_P (w, row)
-                  && make_cursor_line_fully_visible_p)
+                  && !NILP (XBUFFER (w->buffer)->bidi_display_reordering))
+           {
+             /* If rows are bidi-reordered and point moved, back up
+                until we find a row that does not belong to a
+                continuation line.  This is because we must consider
+                all rows of a continued line as candidates for the
+                new cursor positioning, since row start and end
+                positions change non-linearly with vertical position
+                in such rows.  */
+             /* FIXME: Revisit this when glyph ``spilling'' in
+                continuation lines' rows is implemented for
+                bidi-reordered rows.  */
+             while (MATRIX_ROW_CONTINUATION_LINE_P (row))
+               {
+                 xassert (row->enabled_p);
+                 --row;
+                 /* If we hit the beginning of the displayed portion
+                    without finding the first row of a continued
+                    line, give up.  */
+                 if (row <= w->current_matrix->rows)
+                   {
+                     rc = CURSOR_MOVEMENT_MUST_SCROLL;
+                     break;
+                   }
+
+               }
+           }
+         if (must_scroll)
+           ;
+         else if (rc != CURSOR_MOVEMENT_SUCCESS
+             && MATRIX_ROW_PARTIALLY_VISIBLE_P (w, row)
+             && make_cursor_line_fully_visible_p)
            {
              if (PT == MATRIX_ROW_END_CHARPOS (row)
                  && !row->ends_at_zv_p
@@ -13665,7 +13673,8 @@ try_cursor_movement (window, startp, scroll_step)
            }
          else if (scroll_p)
            rc = CURSOR_MOVEMENT_MUST_SCROLL;
-         else if (!NILP (XBUFFER (w->buffer)->bidi_display_reordering))
+         else if (rc != CURSOR_MOVEMENT_SUCCESS
+                  && !NILP (XBUFFER (w->buffer)->bidi_display_reordering))
            {
              /* With bidi-reordered rows, there could be more than
                 one candidate row whose start and end positions
@@ -13678,8 +13687,11 @@ try_cursor_movement (window, startp, scroll_step)
 
              do
                {
-                 rv |= set_cursor_from_row (w, row, w->current_matrix,
-                                            0, 0, 0, 0);
+                 if (MATRIX_ROW_START_CHARPOS (row) <= PT
+                     && PT <= MATRIX_ROW_END_CHARPOS (row)
+                     && cursor_row_p (w, row))
+                   rv |= set_cursor_from_row (w, row, w->current_matrix,
+                                              0, 0, 0, 0);
                  /* As soon as we've found the first suitable row
                     whose ends_at_zv_p flag is set, we are done.  */
                  if (rv
@@ -13690,19 +13702,17 @@ try_cursor_movement (window, startp, scroll_step)
                    }
                  ++row;
                }
-             while (MATRIX_ROW_BOTTOM_Y (row) < last_y
-                    && MATRIX_ROW_START_CHARPOS (row) <= PT
-                    && PT <= MATRIX_ROW_END_CHARPOS (row)
-                    && cursor_row_p (w, row));
+             while ((MATRIX_ROW_CONTINUATION_LINE_P (row)
+                     && MATRIX_ROW_BOTTOM_Y (row) <= last_y)
+                    || (MATRIX_ROW_START_CHARPOS (row) == PT
+                        && MATRIX_ROW_BOTTOM_Y (row) < last_y));
              /* If we didn't find any candidate rows, or exited the
                 loop before all the candidates were examined, signal
                 to the caller that this method failed.  */
              if (rc != CURSOR_MOVEMENT_SUCCESS
-                 && (!rv
-                     || (MATRIX_ROW_START_CHARPOS (row) <= PT
-                         && PT <= MATRIX_ROW_END_CHARPOS (row))))
-               rc = CURSOR_MOVEMENT_CANNOT_BE_USED;
-             else
+                 && (!rv || MATRIX_ROW_CONTINUATION_LINE_P (row)))
+               rc = CURSOR_MOVEMENT_MUST_SCROLL;
+             else if (rv)
                rc = CURSOR_MOVEMENT_SUCCESS;
            }
          else
@@ -13727,8 +13737,7 @@ try_cursor_movement (window, startp, scroll_step)
 }
 
 void
-set_vertical_scroll_bar (w)
-     struct window *w;
+set_vertical_scroll_bar (struct window *w)
 {
   int start, end, whole;
 
@@ -13773,9 +13782,7 @@ set_vertical_scroll_bar (w)
    retry.  */
 
 static void
-redisplay_window (window, just_this_one_p)
-     Lisp_Object window;
-     int just_this_one_p;
+redisplay_window (Lisp_Object window, int just_this_one_p)
 {
   struct window *w = XWINDOW (window);
   struct frame *f = XFRAME (w->frame);
@@ -14205,7 +14212,7 @@ redisplay_window (window, just_this_one_p)
               = try_window_reusing_current_matrix (w)))
        {
          IF_DEBUG (debug_method_add (w, "1"));
-         if (try_window (window, startp, 1) < 0)
+         if (try_window (window, startp, TRY_WINDOW_CHECK_MARGINS) < 0)
            /* -1 means we need to scroll.
               0 means we need new matrices, but fonts_changed_p
               is set in that case, so we will detect it below.  */
@@ -14538,8 +14545,16 @@ redisplay_window (window, just_this_one_p)
         (*FRAME_TERMINAL (f)->redeem_scroll_bar_hook) (w);
     }
 
-  /* Restore current_buffer and value of point in it.  */
-  TEMP_SET_PT_BOTH (CHARPOS (opoint), BYTEPOS (opoint));
+  /* Restore current_buffer and value of point in it.  The window
+     update may have changed the buffer, so first make sure `opoint'
+     is still valid (Bug#6177).  */
+  if (CHARPOS (opoint) < BEGV)
+    TEMP_SET_PT_BOTH (BEGV, BEGV_BYTE);
+  else if (CHARPOS (opoint) > ZV)
+    TEMP_SET_PT_BOTH (Z, Z_BYTE);
+  else
+    TEMP_SET_PT_BOTH (CHARPOS (opoint), BYTEPOS (opoint));
+
   set_buffer_internal_1 (old);
   /* Avoid an abort in TEMP_SET_PT_BOTH if the buffer has become
      shorter.  This can be caused by log truncation in *Messages*. */
@@ -14556,13 +14571,12 @@ redisplay_window (window, just_this_one_p)
    Value is 1 if successful.  It is zero if fonts were loaded during
    redisplay which makes re-adjusting glyph matrices necessary, and -1
    if point would appear in the scroll margins.
-   (We check that only if CHECK_MARGINS is nonzero.  */
+   (We check the former only if TRY_WINDOW_IGNORE_FONTS_CHANGE is
+   unset in FLAGS, and the latter only if TRY_WINDOW_CHECK_MARGINS is
+   set in FLAGS.)  */
 
 int
-try_window (window, pos, check_margins)
-     Lisp_Object window;
-     struct text_pos pos;
-     int check_margins;
+try_window (Lisp_Object window, struct text_pos pos, int flags)
 {
   struct window *w = XWINDOW (window);
   struct it it;
@@ -14584,12 +14598,12 @@ try_window (window, pos, check_margins)
     {
       if (display_line (&it))
        last_text_row = it.glyph_row - 1;
-      if (fonts_changed_p)
+      if (fonts_changed_p && !(flags & TRY_WINDOW_IGNORE_FONTS_CHANGE))
        return 0;
     }
 
   /* Don't let the cursor end in the scroll margins.  */
-  if (check_margins
+  if ((flags & TRY_WINDOW_CHECK_MARGINS)
       && !MINI_WINDOW_P (w))
     {
       int this_scroll_margin;
@@ -14662,8 +14676,7 @@ try_window (window, pos, check_margins)
    W->start is the new window start.  */
 
 static int
-try_window_reusing_current_matrix (w)
-     struct window *w;
+try_window_reusing_current_matrix (struct window *w)
 {
   struct frame *f = XFRAME (w->frame);
   struct glyph_row *row, *bottom_row;
@@ -14710,7 +14723,7 @@ try_window_reusing_current_matrix (w)
   /* The variable new_start now holds the new window start.  The old
      start `start' can be determined from the current matrix.  */
   SET_TEXT_POS_FROM_MARKER (new_start, w->start);
-  start = start_row->start.pos;
+  start = start_row->minpos;
   start_vpos = MATRIX_ROW_VPOS (start_row, w->current_matrix);
 
   /* Clear the desired matrix for the display below.  */
@@ -14749,7 +14762,7 @@ try_window_reusing_current_matrix (w)
            {
              /* Advance to the next row as the "start".  */
              start_row++;
-             start = start_row->start.pos;
+             start = start_row->minpos;
              /* If there are no more rows to try, or just one, give up.  */
              if (start_row == MATRIX_MODE_LINE_ROW (w->current_matrix) - 1
                  || w->vscroll || MATRIX_ROW_PARTIALLY_VISIBLE_P (w, start_row)
@@ -15031,39 +15044,26 @@ try_window_reusing_current_matrix (w)
            {
              struct glyph *glyph = row->glyphs[TEXT_AREA] + w->cursor.hpos;
              struct glyph *end = glyph + row->used[TEXT_AREA];
-             struct glyph *orig_glyph = glyph;
-             struct cursor_pos orig_cursor = w->cursor;
 
-             for (; glyph < end
-                    && (!BUFFERP (glyph->object)
-                        || glyph->charpos != PT);
-                  glyph++)
-               {
-                 w->cursor.hpos++;
-                 w->cursor.x += glyph->pixel_width;
-               }
-             /* With bidi reordering, charpos changes non-linearly
-                with hpos, so the right glyph could be to the
-                left.  */
-             if (!NILP (XBUFFER (w->buffer)->bidi_display_reordering)
-                 && (!BUFFERP (glyph->object) || glyph->charpos != PT))
+             /* Can't use this optimization with bidi-reordered glyph
+                rows, unless cursor is already at point. */
+             if (!NILP (XBUFFER (w->buffer)->bidi_display_reordering))
                {
-                 struct glyph *start_glyph = row->glyphs[TEXT_AREA];
-
-                 glyph = orig_glyph - 1;
-                 orig_cursor.hpos--;
-                 orig_cursor.x -= glyph->pixel_width;
-                 for (; glyph >= start_glyph
-                        && (!BUFFERP (glyph->object)
-                            || glyph->charpos != PT);
-                      glyph--)
-                   {
-                     w->cursor.hpos--;
-                     w->cursor.x -= glyph->pixel_width;
-                   }
-                 if (BUFFERP (glyph->object) && glyph->charpos == PT)
-                   w->cursor = orig_cursor;
+                 if (!(w->cursor.hpos >= 0
+                       && w->cursor.hpos < row->used[TEXT_AREA]
+                       && BUFFERP (glyph->object)
+                       && glyph->charpos == PT))
+                   return 0;
                }
+             else
+               for (; glyph < end
+                      && (!BUFFERP (glyph->object)
+                          || glyph->charpos < PT);
+                    glyph++)
+                 {
+                   w->cursor.hpos++;
+                   w->cursor.x += glyph->pixel_width;
+                 }
            }
        }
 
@@ -15103,12 +15103,12 @@ try_window_reusing_current_matrix (w)
    Window redisplay reusing current matrix when buffer has changed
  ************************************************************************/
 
-static struct glyph_row *find_last_unchanged_at_beg_row P_ ((struct window *));
-static struct glyph_row *find_first_unchanged_at_end_row P_ ((struct window *,
-                                                            int *, int *));
+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 *);
 static struct glyph_row *
-find_last_row_displaying_text P_ ((struct glyph_matrix *, struct it *,
-                                  struct glyph_row *));
+find_last_row_displaying_text (struct glyph_matrix *, struct it *,
+                               struct glyph_row *);
 
 
 /* Return the last row in MATRIX displaying text.  If row START is
@@ -15117,10 +15117,8 @@ find_last_row_displaying_text P_ ((struct glyph_matrix *, struct it *,
    a pointer to the row found.  */
 
 static struct glyph_row *
-find_last_row_displaying_text (matrix, it, start)
-     struct glyph_matrix *matrix;
-     struct it *it;
-     struct glyph_row *start;
+find_last_row_displaying_text (struct glyph_matrix *matrix, struct it *it,
+                              struct glyph_row *start)
 {
   struct glyph_row *row, *row_found;
 
@@ -15153,8 +15151,7 @@ find_last_row_displaying_text (matrix, it, start)
    when the current matrix was built.  */
 
 static struct glyph_row *
-find_last_unchanged_at_beg_row (w)
-     struct window *w;
+find_last_unchanged_at_beg_row (struct window *w)
 {
   int first_changed_pos = BEG + BEG_UNCHANGED;
   struct glyph_row *row;
@@ -15203,9 +15200,7 @@ find_last_unchanged_at_beg_row (w)
    changes.  */
 
 static struct glyph_row *
-find_first_unchanged_at_end_row (w, delta, delta_bytes)
-     struct window *w;
-     int *delta, *delta_bytes;
+find_first_unchanged_at_end_row (struct window *w, int *delta, int *delta_bytes)
 {
   struct glyph_row *row;
   struct glyph_row *row_found = NULL;
@@ -15278,8 +15273,7 @@ find_first_unchanged_at_end_row (w, delta, delta_bytes)
    try_window_reusing_current_matrix.  */
 
 static void
-sync_frame_with_window_matrix_rows (w)
-     struct window *w;
+sync_frame_with_window_matrix_rows (struct window *w)
 {
   struct frame *f = XFRAME (w->frame);
   struct glyph_row *window_row, *window_row_end, *frame_row;
@@ -15323,11 +15317,8 @@ sync_frame_with_window_matrix_rows (w)
    containing CHARPOS or null.  */
 
 struct glyph_row *
-row_containing_pos (w, charpos, start, end, dy)
-     struct window *w;
-     int charpos;
-     struct glyph_row *start, *end;
-     int dy;
+row_containing_pos (struct window *w, int charpos, struct glyph_row *start,
+                   struct glyph_row *end, int dy)
 {
   struct glyph_row *row = start;
   struct glyph_row *best_row = NULL;
@@ -15429,8 +15420,7 @@ row_containing_pos (w, charpos, start, end, dy)
    7. Update W's window end information.  */
 
 static int
-try_window_id (w)
-     struct window *w;
+try_window_id (struct window *w)
 {
   struct frame *f = XFRAME (w->frame);
   struct glyph_matrix *current_matrix = w->current_matrix;
@@ -15643,13 +15633,13 @@ try_window_id (w)
         as is, without changing glyph positions since no text has
         been added/removed in front of the window end.  */
       r0 = MATRIX_FIRST_TEXT_ROW (current_matrix);
-      if (TEXT_POS_EQUAL_P (start, r0->start.pos)
+      if (TEXT_POS_EQUAL_P (start, r0->minpos)
          /* PT must not be in a partially visible line.  */
          && !(PT >= MATRIX_ROW_START_CHARPOS (row)
               && MATRIX_ROW_BOTTOM_Y (row) > window_text_bottom_y (w)))
        {
          /* We have to compute the window end anew since text
-            can have been added/removed after it.  */
+            could have been added/removed after it.  */
          w->window_end_pos
            = make_number (Z - MATRIX_ROW_END_CHARPOS (row));
          w->window_end_bytepos
@@ -15681,7 +15671,7 @@ try_window_id (w)
      start is not in changed text, otherwise positions would not be
      comparable.  */
   row = MATRIX_FIRST_TEXT_ROW (current_matrix);
-  if (!TEXT_POS_EQUAL_P (start, row->start.pos))
+  if (!TEXT_POS_EQUAL_P (start, row->minpos))
     GIVE_UP (16);
 
   /* Give up if the window ends in strings.  Overlay strings
@@ -16166,9 +16156,9 @@ try_window_id (w)
 
 #if GLYPH_DEBUG
 
-void dump_glyph_row P_ ((struct glyph_row *, int, int));
-void dump_glyph_matrix P_ ((struct glyph_matrix *, int));
-void dump_glyph P_ ((struct glyph_row *, struct glyph *, int));
+void dump_glyph_row (struct glyph_row *, int, int);
+void dump_glyph_matrix (struct glyph_matrix *, int);
+void dump_glyph (struct glyph_row *, struct glyph *, int);
 
 
 /* Dump the contents of glyph matrix MATRIX on stderr.
@@ -16497,9 +16487,7 @@ usage: (trace-to-stderr STRING &rest OBJECTS)  */)
    Used for non-window-redisplay windows, and for windows w/o left fringe.  */
 
 static struct glyph_row *
-get_overlay_arrow_glyph_row (w, overlay_arrow_string)
-     struct window *w;
-     Lisp_Object overlay_arrow_string;
+get_overlay_arrow_glyph_row (struct window *w, Lisp_Object overlay_arrow_string)
 {
   struct frame *f = XFRAME (WINDOW_FRAME (w));
   struct buffer *buffer = XBUFFER (w->buffer);
@@ -16561,8 +16549,7 @@ get_overlay_arrow_glyph_row (w, overlay_arrow_string)
    produce_special_glyphs.  */
 
 static void
-insert_left_trunc_glyphs (it)
-     struct it *it;
+insert_left_trunc_glyphs (struct it *it)
 {
   struct it truncate_it;
   struct glyph *from, *end, *to, *toend;
@@ -16580,24 +16567,61 @@ insert_left_trunc_glyphs (it)
   produce_special_glyphs (&truncate_it, IT_TRUNCATION);
 
   /* Overwrite glyphs from IT with truncation glyphs.  */
-  from = truncate_it.glyph_row->glyphs[TEXT_AREA];
-  end = from + truncate_it.glyph_row->used[TEXT_AREA];
-  to = it->glyph_row->glyphs[TEXT_AREA];
-  toend = to + it->glyph_row->used[TEXT_AREA];
-
-  while (from < end)
-    *to++ = *from++;
-
-  /* There may be padding glyphs left over.  Overwrite them too.  */
-  while (to < toend && CHAR_GLYPH_PADDING_P (*to))
+  if (!it->glyph_row->reversed_p)
     {
       from = truncate_it.glyph_row->glyphs[TEXT_AREA];
+      end = from + truncate_it.glyph_row->used[TEXT_AREA];
+      to = it->glyph_row->glyphs[TEXT_AREA];
+      toend = to + it->glyph_row->used[TEXT_AREA];
+
       while (from < end)
        *to++ = *from++;
+
+      /* There may be padding glyphs left over.  Overwrite them too.  */
+      while (to < toend && CHAR_GLYPH_PADDING_P (*to))
+       {
+         from = truncate_it.glyph_row->glyphs[TEXT_AREA];
+         while (from < end)
+           *to++ = *from++;
+       }
+
+      if (to > toend)
+       it->glyph_row->used[TEXT_AREA] = to - it->glyph_row->glyphs[TEXT_AREA];
     }
+  else
+    {
+      /* In R2L rows, overwrite the last (rightmost) glyphs, and do
+        that back to front.  */
+      end = truncate_it.glyph_row->glyphs[TEXT_AREA];
+      from = end + truncate_it.glyph_row->used[TEXT_AREA] - 1;
+      toend = it->glyph_row->glyphs[TEXT_AREA];
+      to = toend + it->glyph_row->used[TEXT_AREA] - 1;
 
-  if (to > toend)
-    it->glyph_row->used[TEXT_AREA] = to - it->glyph_row->glyphs[TEXT_AREA];
+      while (from >= end && to >= toend)
+       *to-- = *from--;
+      while (to >= toend && CHAR_GLYPH_PADDING_P (*to))
+       {
+         from =
+           truncate_it.glyph_row->glyphs[TEXT_AREA]
+           + truncate_it.glyph_row->used[TEXT_AREA] - 1;
+         while (from >= end && to >= toend)
+           *to-- = *from--;
+       }
+      if (from >= end)
+       {
+         /* Need to free some room before prepending additional
+            glyphs.  */
+         int move_by = from - end + 1;
+         struct glyph *g0 = it->glyph_row->glyphs[TEXT_AREA];
+         struct glyph *g = g0 + it->glyph_row->used[TEXT_AREA] - 1;
+
+         for ( ; g >= g0; g--)
+           g[move_by] = *g;
+         while (from >= end)
+           *to-- = *from--;
+         it->glyph_row->used[TEXT_AREA] += move_by;
+       }
+    }
 }
 
 
@@ -16619,8 +16643,7 @@ insert_left_trunc_glyphs (it)
    must not be zero.  */
 
 static void
-compute_line_metrics (it)
-     struct it *it;
+compute_line_metrics (struct it *it)
 {
   struct glyph_row *row = it->glyph_row;
   int area, i;
@@ -16715,9 +16738,7 @@ compute_line_metrics (it)
    end of the line if the row ends in italic text.  */
 
 static int
-append_space_for_newline (it, default_face_p)
-     struct it *it;
-     int default_face_p;
+append_space_for_newline (struct it *it, int default_face_p)
 {
   if (FRAME_WINDOW_P (it->f))
     {
@@ -16742,7 +16763,7 @@ append_space_for_newline (it, default_face_p)
          saved_pos = it->position;
 
          it->what = IT_CHARACTER;
-         bzero (&it->position, sizeof it->position);
+         memset (&it->position, 0, sizeof it->position);
          it->object = make_number (0);
          it->c = ' ';
          it->len = 1;
@@ -16781,14 +16802,20 @@ append_space_for_newline (it, default_face_p)
    left of the leftmost glyph.  */
 
 static void
-extend_face_to_end_of_line (it)
-     struct it *it;
+extend_face_to_end_of_line (struct it *it)
 {
   struct face *face;
   struct frame *f = it->f;
 
-  /* If line is already filled, do nothing.  */
-  if (it->current_x >= it->last_visible_x)
+  /* If line is already filled, do nothing.  Non window-system frames
+     get a grace of one more ``pixel'' because their characters are
+     1-``pixel'' wide, so they hit the equality too early.  This grace
+     is needed only for R2L rows that are not continued, to produce
+     one extra blank where we could display the cursor.  */
+  if (it->current_x >= it->last_visible_x
+      + (!FRAME_WINDOW_P (f)
+        && it->glyph_row->reversed_p
+        && !it->glyph_row->continued_p))
     return;
 
   /* Face extension extends the background and box of IT->face_id
@@ -16849,21 +16876,24 @@ extend_face_to_end_of_line (it)
 
          for (row_width = 0, g = row_start; g < row_end; g++)
            row_width += g->pixel_width;
-         stretch_width = WINDOW_BOX_RIGHT_EDGE_X(it->w)
-                         - WINDOW_BOX_LEFT_EDGE_X(it->w)
-                         - WINDOW_TOTAL_FRINGE_WIDTH(it->w)
-                         - row_width;
+         stretch_width = window_box_width (it->w, TEXT_AREA) - row_width;
          if (stretch_width > 0)
            {
              stretch_ascent =
                (((it->ascent + it->descent)
                  * FONT_BASE (font)) / FONT_HEIGHT (font));
              saved_pos = it->position;
+             memset (&it->position, 0, sizeof it->position);
              saved_avoid_cursor = it->avoid_cursor_p;
-             saved_face_id = it->face_id;
-             bzero (&it->position, sizeof it->position);
              it->avoid_cursor_p = 1;
-             it->face_id = face->id;
+             saved_face_id = it->face_id;
+             /* The last row's stretch glyph should get the default
+                face, to avoid painting the rest of the window with
+                the region face, if the region ends at ZV.  */
+             if (it->glyph_row->ends_at_zv_p)
+               it->face_id = DEFAULT_FACE_ID;
+             else
+               it->face_id = face->id;
              append_stretch_glyph (it, make_number (0), stretch_width,
                                    it->ascent + it->descent, stretch_ascent);
              it->position = saved_pos;
@@ -16886,11 +16916,17 @@ extend_face_to_end_of_line (it)
       saved_pos = it->position;
 
       it->what = IT_CHARACTER;
-      bzero (&it->position, sizeof it->position);
+      memset (&it->position, 0, sizeof it->position);
       it->object = make_number (0);
       it->c = ' ';
       it->len = 1;
-      it->face_id = face->id;
+      /* The last row's blank glyphs should get the default face, to
+        avoid painting the rest of the window with the region face,
+        if the region ends at ZV.  */
+      if (it->glyph_row->ends_at_zv_p)
+       it->face_id = DEFAULT_FACE_ID;
+      else
+       it->face_id = face->id;
 
       PRODUCE_GLYPHS (it);
 
@@ -16912,8 +16948,7 @@ extend_face_to_end_of_line (it)
    trailing whitespace.  */
 
 static int
-trailing_whitespace_p (charpos)
-     int charpos;
+trailing_whitespace_p (int charpos)
 {
   int bytepos = CHAR_TO_BYTE (charpos);
   int c = 0;
@@ -16935,9 +16970,7 @@ trailing_whitespace_p (charpos)
 /* Highlight trailing whitespace, if any, in ROW.  */
 
 void
-highlight_trailing_whitespace (f, row)
-     struct frame *f;
-     struct glyph_row *row;
+highlight_trailing_whitespace (struct frame *f, struct glyph_row *row)
 {
   int used = row->used[TEXT_AREA];
 
@@ -17014,13 +17047,11 @@ highlight_trailing_whitespace (f, row)
    used to hold the cursor.  */
 
 static int
-cursor_row_p (w, row)
-     struct window *w;
-     struct glyph_row *row;
+cursor_row_p (struct window *w, struct glyph_row *row)
 {
   int cursor_row_p = 1;
 
-  if (PT == MATRIX_ROW_END_CHARPOS (row))
+  if (PT == CHARPOS (row->end.pos))
     {
       /* Suppose the row ends on a string.
         Unless the row is continued, that means it ends on a newline
@@ -17057,14 +17088,15 @@ cursor_row_p (w, row)
        {
          /* If the row ends in middle of a real character,
             and the line is continued, we want the cursor here.
-            That's because MATRIX_ROW_END_CHARPOS would equal
+            That's because CHARPOS (ROW->end.pos) would equal
             PT if PT is before the character.  */
          if (!row->ends_in_ellipsis_p)
            cursor_row_p = row->continued_p;
          else
          /* If the row ends in an ellipsis, then
-            MATRIX_ROW_END_CHARPOS will equal point after the invisible text.
-            We want that position to be displayed after the ellipsis.  */
+            CHARPOS (ROW->end.pos) will equal point after the
+            invisible text.  We want that position to be displayed
+            after the ellipsis.  */
            cursor_row_p = 0;
        }
       /* If the row ends at ZV, display the cursor at the end of that
@@ -17130,9 +17162,7 @@ push_display_prop (struct it *it, Lisp_Object prop)
 /* Return the character-property PROP at the current position in IT.  */
 
 static Lisp_Object
-get_it_property (it, prop)
-     struct it *it;
-     Lisp_Object prop;
+get_it_property (struct it *it, Lisp_Object prop)
 {
   Lisp_Object position;
 
@@ -17176,6 +17206,110 @@ handle_line_prefix (struct it *it)
 
 \f
 
+/* Remove N glyphs at the start of a reversed IT->glyph_row.  Called
+   only for R2L lines from display_line, when it decides that too many
+   glyphs were produced by PRODUCE_GLYPHS, and the line needs to be
+   continued.  */
+static void
+unproduce_glyphs (struct it *it, int n)
+{
+  struct glyph *glyph, *end;
+
+  xassert (it->glyph_row);
+  xassert (it->glyph_row->reversed_p);
+  xassert (it->area == TEXT_AREA);
+  xassert (n <= it->glyph_row->used[TEXT_AREA]);
+
+  if (n > it->glyph_row->used[TEXT_AREA])
+    n = it->glyph_row->used[TEXT_AREA];
+  glyph = it->glyph_row->glyphs[TEXT_AREA] + n;
+  end = it->glyph_row->glyphs[TEXT_AREA] + it->glyph_row->used[TEXT_AREA];
+  for ( ; glyph < end; glyph++)
+    glyph[-n] = *glyph;
+}
+
+/* Find the positions in a bidi-reordered ROW to serve as ROW->minpos
+   and ROW->maxpos.  */
+static void
+find_row_edges (struct it *it, struct glyph_row *row,
+               EMACS_INT min_pos, EMACS_INT min_bpos,
+               EMACS_INT max_pos, EMACS_INT max_bpos)
+{
+  /* FIXME: Revisit this when glyph ``spilling'' in continuation
+     lines' rows is implemented for bidi-reordered rows.  */
+
+  /* ROW->minpos is the value of min_pos, the minimal buffer position
+     we have in ROW.  */
+  if (min_pos <= ZV)
+    SET_TEXT_POS (row->minpos, min_pos, min_bpos);
+  else
+    {
+      /* We didn't find _any_ valid buffer positions in any of the
+        glyphs, so we must trust the iterator's computed
+        positions.  */
+      row->minpos = row->start.pos;
+      max_pos = CHARPOS (it->current.pos);
+      max_bpos = BYTEPOS (it->current.pos);
+    }
+
+  if (!max_pos)
+    abort ();
+
+  /* Here are the various use-cases for ending the row, and the
+     corresponding values for ROW->maxpos:
+
+     Line ends in a newline from buffer       eol_pos + 1
+     Line is continued from buffer            max_pos + 1
+     Line is truncated on right               it->current.pos
+     Line ends in a newline from string       max_pos
+     Line is continued from string            max_pos
+     Line is continued from display vector    max_pos
+     Line is entirely from a string           min_pos == max_pos
+     Line is entirely from a display vector   min_pos == max_pos
+     Line that ends at ZV                     ZV
+
+     If you discover other use-cases, please add them here as
+     appropriate.  */
+  if (row->ends_at_zv_p)
+    row->maxpos = it->current.pos;
+  else if (row->used[TEXT_AREA])
+    {
+      if (row->ends_in_newline_from_string_p)
+       SET_TEXT_POS (row->maxpos, max_pos, max_bpos);
+      else if (CHARPOS (it->eol_pos) > 0)
+       SET_TEXT_POS (row->maxpos,
+                     CHARPOS (it->eol_pos) + 1, BYTEPOS (it->eol_pos) + 1);
+      else if (row->continued_p)
+       {
+         /* If max_pos is different from IT's current position, it
+            means IT->method does not belong to the display element
+            at max_pos.  However, it also means that the display
+            element at max_pos was displayed in its entirety on this
+            line, which is equivalent to saying that the next line
+            starts at the next buffer position.  */
+         if (IT_CHARPOS (*it) == max_pos && it->method != GET_FROM_BUFFER)
+           SET_TEXT_POS (row->maxpos, max_pos, max_bpos);
+         else
+           {
+             INC_BOTH (max_pos, max_bpos);
+             SET_TEXT_POS (row->maxpos, max_pos, max_bpos);
+           }
+       }
+      else if (row->truncated_on_right_p)
+       /* display_line already called reseat_at_next_visible_line_start,
+          which puts the iterator at the beginning of the next line, in
+          the logical order. */
+       row->maxpos = it->current.pos;
+      else if (max_pos == min_pos && it->method != GET_FROM_BUFFER)
+       /* A line that is entirely from a string/image/stretch...  */
+       row->maxpos = row->minpos;
+      else
+       abort ();
+    }
+  else
+    row->maxpos = it->current.pos;
+}
+
 /* Construct the glyph row IT->glyph_row in the desired matrix of
    IT->w from text at the current position of IT.  See dispextern.h
    for an overview of struct it.  Value is non-zero if
@@ -17183,8 +17317,7 @@ handle_line_prefix (struct it *it)
    only.  */
 
 static int
-display_line (it)
-     struct it *it;
+display_line (struct it *it)
 {
   struct glyph_row *row = it->glyph_row;
   Lisp_Object overlay_arrow_string;
@@ -17193,8 +17326,10 @@ display_line (it)
   int wrap_row_used = -1, wrap_row_ascent, wrap_row_height;
   int wrap_row_phys_ascent, wrap_row_phys_height;
   int wrap_row_extra_line_spacing;
-  struct display_pos row_end;
+  EMACS_INT wrap_row_min_pos, wrap_row_min_bpos;
+  EMACS_INT wrap_row_max_pos, wrap_row_max_bpos;
   int cvpos;
+  EMACS_INT min_pos = ZV + 1, min_bpos, max_pos = 0, max_bpos;
 
   /* We always start displaying at hpos zero even if hscrolled.  */
   xassert (it->hpos == 0 && it->current_x == 0);
@@ -17251,6 +17386,23 @@ display_line (it)
   row->phys_height = it->max_phys_ascent + it->max_phys_descent;
   row->extra_line_spacing = it->max_extra_line_spacing;
 
+/* Utility macro to record max and min buffer positions seen until now.  */
+#define RECORD_MAX_MIN_POS(IT)                                 \
+  do                                                           \
+    {                                                          \
+      if (IT_CHARPOS (*(IT)) < min_pos)                                \
+       {                                                       \
+         min_pos = IT_CHARPOS (*(IT));                         \
+         min_bpos = IT_BYTEPOS (*(IT));                        \
+       }                                                       \
+      if (IT_CHARPOS (*(IT)) > max_pos)                                \
+       {                                                       \
+         max_pos = IT_CHARPOS (*(IT));                         \
+         max_bpos = IT_BYTEPOS (*(IT));                        \
+       }                                                       \
+    }                                                          \
+  while (0)
+
   /* Loop generating characters.  The loop is left with IT on the next
      character to display.  */
   while (1)
@@ -17285,7 +17437,8 @@ display_line (it)
          row->ends_at_zv_p = 1;
          /* A row that displays right-to-left text must always have
             its last face extended all the way to the end of line,
-            even if this row ends in ZV.  */
+            even if this row ends in ZV, because we still write to th
+            screen left to right.  */
          if (row->reversed_p)
            extend_face_to_end_of_line (it);
          break;
@@ -17319,6 +17472,10 @@ display_line (it)
                  wrap_row_phys_ascent = row->phys_ascent;
                  wrap_row_phys_height = row->phys_height;
                  wrap_row_extra_line_spacing = row->extra_line_spacing;
+                 wrap_row_min_pos = min_pos;
+                 wrap_row_min_bpos = min_bpos;
+                 wrap_row_max_pos = max_pos;
+                 wrap_row_max_bpos = max_bpos;
                  may_wrap = 0;
                }
            }
@@ -17369,6 +17526,10 @@ display_line (it)
                                         it->max_extra_line_spacing);
          if (it->current_x - it->pixel_width < it->first_visible_x)
            row->x = x - it->first_visible_x;
+         /* Record the maximum and minimum buffer positions seen so
+            far in glyphs that will be displayed by this row.  */
+         if (it->bidi_p)
+           RECORD_MAX_MIN_POS (it);
        }
       else
        {
@@ -17402,6 +17563,11 @@ display_line (it)
                      it->current_x = new_x;
                      it->continuation_lines_width += new_x;
                      ++it->hpos;
+                     /* Record the maximum and minimum buffer
+                        positions seen so far in glyphs that will be
+                        displayed by this row.  */
+                     if (it->bidi_p)
+                       RECORD_MAX_MIN_POS (it);
                      if (i == nglyphs - 1)
                        {
                          /* If line-wrap is on, check if a previous
@@ -17440,6 +17606,9 @@ display_line (it)
                      /* A padding glyph that doesn't fit on this line.
                         This means the whole character doesn't fit
                         on the line.  */
+                     if (row->reversed_p)
+                       unproduce_glyphs (it, row->used[TEXT_AREA]
+                                              - n_glyphs_before);
                      row->used[TEXT_AREA] = n_glyphs_before;
 
                      /* Fill the rest of the row with continuation
@@ -17462,6 +17631,9 @@ display_line (it)
                  else if (wrap_row_used > 0)
                    {
                    back_to_wrap:
+                     if (row->reversed_p)
+                       unproduce_glyphs (it,
+                                         row->used[TEXT_AREA] - wrap_row_used);
                      *it = wrap_it;
                      it->continuation_lines_width += wrap_x;
                      row->used[TEXT_AREA] = wrap_row_used;
@@ -17470,6 +17642,10 @@ display_line (it)
                      row->phys_ascent = wrap_row_phys_ascent;
                      row->phys_height = wrap_row_phys_height;
                      row->extra_line_spacing = wrap_row_extra_line_spacing;
+                     min_pos = wrap_row_min_pos;
+                     min_bpos = wrap_row_min_bpos;
+                     max_pos = wrap_row_max_pos;
+                     max_bpos = wrap_row_max_bpos;
                      row->continued_p = 1;
                      row->ends_at_zv_p = 0;
                      row->exact_window_width_line_p = 0;
@@ -17497,6 +17673,9 @@ display_line (it)
                      /* Something other than a TAB that draws past
                         the right edge of the window.  Restore
                         positions to values before the element.  */
+                     if (row->reversed_p)
+                       unproduce_glyphs (it, row->used[TEXT_AREA]
+                                              - (n_glyphs_before + i));
                      row->used[TEXT_AREA] = n_glyphs_before + i;
 
                      /* Display continuation glyphs.  */
@@ -17529,6 +17708,12 @@ display_line (it)
                  /* Increment number of glyphs actually displayed.  */
                  ++it->hpos;
 
+                 /* Record the maximum and minimum buffer positions
+                    seen so far in glyphs that will be displayed by
+                    this row.  */
+                 if (it->bidi_p)
+                   RECORD_MAX_MIN_POS (it);
+
                  if (x < it->first_visible_x)
                    /* Glyph is partially visible, i.e. row starts at
                       negative X position.  */
@@ -17580,6 +17765,10 @@ display_line (it)
          if (used_before == 0)
            row->glyphs[TEXT_AREA]->charpos = CHARPOS (it->position);
 
+         /* Record the position of the newline, for use in
+            find_row_edges.  */
+         it->eol_pos = it->current.pos;
+
          /* Consume the line end.  This skips over invisible lines.  */
          set_iterator_to_next (it, 1);
          it->continuation_lines_width = 0;
@@ -17602,9 +17791,26 @@ display_line (it)
            {
              int i, n;
 
-             for (i = row->used[TEXT_AREA] - 1; i > 0; --i)
-               if (!CHAR_GLYPH_PADDING_P (row->glyphs[TEXT_AREA][i]))
-                 break;
+             if (!row->reversed_p)
+               {
+                 for (i = row->used[TEXT_AREA] - 1; i > 0; --i)
+                   if (!CHAR_GLYPH_PADDING_P (row->glyphs[TEXT_AREA][i]))
+                     break;
+               }
+             else
+               {
+                 for (i = 0; i < row->used[TEXT_AREA]; i++)
+                   if (!CHAR_GLYPH_PADDING_P (row->glyphs[TEXT_AREA][i]))
+                     break;
+                 /* Remove any padding glyphs at the front of ROW, to
+                    make room for the truncation glyphs we will be
+                    adding below.  The loop below always inserts at
+                    least one truncation glyph, so also remove the
+                    last glyph added to ROW.  */
+                 unproduce_glyphs (it, i + 1);
+                 /* Adjust i for the loop below.  */
+                 i = row->used[TEXT_AREA] - (i + 1);
+               }
 
              for (n = row->used[TEXT_AREA]; i < n; ++i)
                {
@@ -17642,7 +17848,7 @@ display_line (it)
   /* If line is not empty and hscrolled, maybe insert truncation glyphs
      at the left window margin.  */
   if (it->first_visible_x
-      && IT_CHARPOS (*it) != MATRIX_ROW_START_CHARPOS (row))
+      && IT_CHARPOS (*it) != CHARPOS (row->start.pos))
     {
       if (!FRAME_WINDOW_P (it->f))
        insert_left_trunc_glyphs (it);
@@ -17695,115 +17901,19 @@ display_line (it)
   compute_line_metrics (it);
 
   /* Remember the position at which this line ends.  */
-  row->end = row_end = it->current;
-  if (it->bidi_p)
+  row->end = it->current;
+  if (!it->bidi_p)
     {
-      /* ROW->start and ROW->end must be the smallest and largest
-        buffer positions in ROW.  But if ROW was bidi-reordered,
-        these two positions can be anywhere in the row, so we must
-        rescan all of the ROW's glyphs to find them.  */
-      /* FIXME: Revisit this when glyph ``spilling'' in continuation
-        lines' rows is implemented for bidi-reordered rows.  */
-      EMACS_INT min_pos = ZV + 1, max_pos = 0;
-      struct glyph *g;
-      struct it save_it;
-      struct text_pos tpos;
-
-      for (g = row->glyphs[TEXT_AREA];
-          g < row->glyphs[TEXT_AREA] + row->used[TEXT_AREA];
-          g++)
-       {
-         if (BUFFERP (g->object))
-           {
-             if (g->charpos > 0 && g->charpos < min_pos)
-               min_pos = g->charpos;
-             if (g->charpos > max_pos)
-               max_pos = g->charpos;
-           }
-       }
-      /* Empty lines have a valid buffer position at their first
-        glyph, but that glyph's OBJECT is zero, as if it didn't come
-        from a buffer.  If we didn't find any valid buffer positions
-        in this row, maybe we have such an empty line.  */
-      if (min_pos == ZV + 1 && row->used[TEXT_AREA])
-       {
-         for (g = row->glyphs[TEXT_AREA];
-              g < row->glyphs[TEXT_AREA] + row->used[TEXT_AREA];
-              g++)
-           {
-             if (INTEGERP (g->object))
-               {
-                 if (g->charpos > 0 && g->charpos < min_pos)
-                   min_pos = g->charpos;
-                 if (g->charpos > max_pos)
-                   max_pos = g->charpos;
-               }
-           }
-       }
-      if (min_pos <= ZV)
-       {
-         if (min_pos != row->start.pos.charpos)
-           {
-             row->start.pos.charpos = min_pos;
-             row->start.pos.bytepos = CHAR_TO_BYTE (min_pos);
-           }
-         if (max_pos == 0)
-           max_pos = min_pos;
-       }
-      /* For ROW->end, we need the position that is _after_ max_pos,
-        in the logical order, unless we are at ZV.  */
-      if (row->ends_at_zv_p)
-       {
-         row_end = row->end = it->current;
-         if (!row->used[TEXT_AREA])
-           {
-             row->start.pos.charpos = row_end.pos.charpos;
-             row->start.pos.bytepos = row_end.pos.bytepos;
-           }
-       }
-      else if (row->used[TEXT_AREA] && max_pos)
-       {
-         SET_TEXT_POS (tpos, max_pos + 1, CHAR_TO_BYTE (max_pos + 1));
-         row_end = it->current;
-         row_end.pos = tpos;
-         /* If the character at max_pos+1 is a newline, skip that as
-            well.  Note that this may skip some invisible text.  */
-         if (FETCH_CHAR (tpos.bytepos) == '\n'
-             || (FETCH_CHAR (tpos.bytepos) == '\r' && it->selective))
-           {
-             save_it = *it;
-             it->bidi_p = 0;
-             reseat_1 (it, tpos, 0);
-             set_iterator_to_next (it, 1);
-             /* Record the position after the newline of a continued
-                row.  We will need that to set ROW->end of the last
-                row produced for a continued line.  */
-             if (row->continued_p)
-               {
-                 save_it.eol_pos.charpos = IT_CHARPOS (*it);
-                 save_it.eol_pos.bytepos = IT_BYTEPOS (*it);
-               }
-             else
-               {
-                 row_end = it->current;
-                 save_it.eol_pos.charpos = save_it.eol_pos.bytepos = 0;
-               }
-             *it = save_it;
-           }
-         else if (!row->continued_p
-                  && row->continuation_lines_width
-                  && it->eol_pos.charpos > 0)
-           {
-             /* Last row of a continued line.  Use the position
-                recorded in ROW->eol_pos, to the effect that the
-                newline belongs to this row, not to the row which
-                displays the character with the largest buffer
-                position.  */
-             row_end.pos = it->eol_pos;
-             it->eol_pos.charpos = it->eol_pos.bytepos = 0;
-           }
-         row->end = row_end;
-       }
+      row->minpos = row->start.pos;
+      row->maxpos = row->end.pos;
+    }
+  else
+    {
+      /* ROW->minpos and ROW->maxpos must be the smallest and
+        `1 + the largest' buffer positions in ROW.  But if ROW was
+        bidi-reordered, these two positions can be anywhere in the
+        row, so we must determine them now.  */
+      find_row_edges (it, row, min_pos, min_bpos, max_pos, max_bpos);
     }
 
   /* Record whether this row ends inside an ellipsis.  */
@@ -17850,14 +17960,97 @@ display_line (it)
      row to be used.  */
   it->current_x = it->hpos = 0;
   it->current_y += row->height;
+  SET_TEXT_POS (it->eol_pos, 0, 0);
   ++it->vpos;
   ++it->glyph_row;
-  /* The next row should use same value of the reversed_p flag as this
-     one.  set_iterator_to_next decides when it's a new paragraph, and
-     PRODUCE_GLYPHS recomputes the value of the flag accordingly.  */
-  it->glyph_row->reversed_p = row->reversed_p;
-  it->start = row_end;
+  /* The next row should by default use the same value of the
+     reversed_p flag as this one.  set_iterator_to_next decides when
+     it's a new paragraph, and PRODUCE_GLYPHS recomputes the value of
+     the flag accordingly.  */
+  if (it->glyph_row < MATRIX_BOTTOM_TEXT_ROW (it->w->desired_matrix, it->w))
+    it->glyph_row->reversed_p = row->reversed_p;
+  it->start = row->end;
   return row->displays_text_p;
+
+#undef RECORD_MAX_MIN_POS
+}
+
+DEFUN ("current-bidi-paragraph-direction", Fcurrent_bidi_paragraph_direction,
+       Scurrent_bidi_paragraph_direction, 0, 1, 0,
+       doc: /* Return paragraph direction at point in BUFFER.
+Value is either `left-to-right' or `right-to-left'.
+If BUFFER is omitted or nil, it defaults to the current buffer.
+
+Paragraph direction determines how the text in the paragraph is displayed.
+In left-to-right paragraphs, text begins at the left margin of the window
+and the reading direction is generally left to right.  In right-to-left
+paragraphs, text begins at the right margin and is read from right to left.
+
+See also `bidi-paragraph-direction'.  */)
+     (buffer)
+     Lisp_Object buffer;
+{
+  struct buffer *buf;
+  struct buffer *old;
+
+  if (NILP (buffer))
+    buf = current_buffer;
+  else
+    {
+      CHECK_BUFFER (buffer);
+      buf = XBUFFER (buffer);
+      old = current_buffer;
+    }
+
+  if (NILP (buf->bidi_display_reordering))
+    return Qleft_to_right;
+  else if (!NILP (buf->bidi_paragraph_direction))
+    return buf->bidi_paragraph_direction;
+  else
+    {
+      /* Determine the direction from buffer text.  We could try to
+        use current_matrix if it is up to date, but this seems fast
+        enough as it is.  */
+      struct bidi_it itb;
+      EMACS_INT pos = BUF_PT (buf);
+      EMACS_INT bytepos = BUF_PT_BYTE (buf);
+
+      if (buf != current_buffer)
+       set_buffer_temp (buf);
+      /* Find previous non-empty line.  */
+      if (pos >= ZV && pos > BEGV)
+       {
+         pos--;
+         bytepos = CHAR_TO_BYTE (pos);
+       }
+      while (FETCH_BYTE (bytepos) == '\n')
+       {
+         if (bytepos <= BEGV_BYTE)
+           break;
+         bytepos--;
+         pos--;
+       }
+      while (!CHAR_HEAD_P (FETCH_BYTE (bytepos)))
+       bytepos--;
+      itb.charpos = pos;
+      itb.bytepos = bytepos;
+      itb.first_elt = 1;
+
+      bidi_paragraph_init (NEUTRAL_DIR, &itb);
+      if (buf != current_buffer)
+       set_buffer_temp (old);
+      switch (itb.paragraph_dir)
+       {
+       case L2R:
+         return Qleft_to_right;
+         break;
+       case R2L:
+         return Qright_to_left;
+         break;
+       default:
+         abort ();
+       }
+    }
 }
 
 
@@ -17877,8 +18070,7 @@ display_line (it)
    for the menu bar.  */
 
 static void
-display_menu_bar (w)
-     struct window *w;
+display_menu_bar (struct window *w)
 {
   struct frame *f = XFRAME (WINDOW_FRAME (w));
   struct it it;
@@ -17982,9 +18174,7 @@ display_menu_bar (w)
    the number of windows whose mode lines were redisplayed.  */
 
 static int
-redisplay_mode_lines (window, force)
-     Lisp_Object window;
-     int force;
+redisplay_mode_lines (Lisp_Object window, int force)
 {
   int nwindows = 0;
 
@@ -18046,8 +18236,7 @@ redisplay_mode_lines (window, force)
    sum number of mode lines and header lines displayed.  */
 
 static int
-display_mode_lines (w)
-     struct window *w;
+display_mode_lines (struct window *w)
 {
   Lisp_Object old_selected_window, old_selected_frame;
   int n = 0;
@@ -18091,10 +18280,7 @@ display_mode_lines (w)
    displayed.  */
 
 static int
-display_mode_line (w, face_id, format)
-     struct window *w;
-     enum face_id face_id;
-     Lisp_Object format;
+display_mode_line (struct window *w, enum face_id face_id, Lisp_Object format)
 {
   struct it it;
   struct face *face;
@@ -18153,8 +18339,7 @@ display_mode_line (w, face_id, format)
    Return the updated list.  */
 
 static Lisp_Object
-move_elt_to_front (elt, list)
-     Lisp_Object elt, list;
+move_elt_to_front (Lisp_Object elt, Lisp_Object list)
 {
   register Lisp_Object tail, prev;
   register Lisp_Object tem;
@@ -18212,12 +18397,8 @@ move_elt_to_front (elt, list)
    `store_mode_line_string', or `display_string'.  */
 
 static int
-display_mode_element (it, depth, field_width, precision, elt, props, risky)
-     struct it *it;
-     int depth;
-     int field_width, precision;
-     Lisp_Object elt, props;
-     int risky;
+display_mode_element (struct it *it, int depth, int field_width, int precision,
+                     Lisp_Object elt, Lisp_Object props, int risky)
 {
   int n = 0, field, prec;
   int literal = 0;
@@ -18679,13 +18860,8 @@ display_mode_element (it, depth, field_width, precision, elt, props, risky)
  */
 
 static int
-store_mode_line_string (string, lisp_string, copy_string, field_width, precision, props)
-     char *string;
-     Lisp_Object lisp_string;
-     int copy_string;
-     int field_width;
-     int precision;
-     Lisp_Object props;
+store_mode_line_string (char *string, Lisp_Object lisp_string, int copy_string,
+                       int field_width, int precision, Lisp_Object props)
 {
   int len;
   int n = 0;
@@ -18872,10 +19048,7 @@ are the selected window and the window's buffer).  */)
    the positive integer D to BUF using a minimal field width WIDTH.  */
 
 static void
-pint2str (buf, width, d)
-     register char *buf;
-     register int width;
-     register int d;
+pint2str (register char *buf, register int width, register int d)
 {
   register char *p = buf;
 
@@ -18919,10 +19092,7 @@ static const char power_letter[] =
   };
 
 static void
-pint2hrstr (buf, width, d)
-     char *buf;
-     int width;
-     int d;
+pint2hrstr (char *buf, int width, int d)
 {
   /* We aim to represent the nonnegative integer D as
      QUOTIENT.TENTHS * 10 ^ (3 * EXPONENT). */
@@ -19023,10 +19193,7 @@ pint2hrstr (buf, width, d)
 static unsigned char invalid_eol_type[] = "(*invalid*)";
 
 static char *
-decode_mode_spec_coding (coding_system, buf, eol_flag)
-     Lisp_Object coding_system;
-     register char *buf;
-     int eol_flag;
+decode_mode_spec_coding (Lisp_Object coding_system, register char *buf, int eol_flag)
 {
   Lisp_Object val;
   int multibyte = !NILP (current_buffer->enable_multibyte_characters);
@@ -19092,7 +19259,7 @@ decode_mode_spec_coding (coding_system, buf, eol_flag)
          eol_str = invalid_eol_type;
          eol_str_len = sizeof (invalid_eol_type) - 1;
        }
-      bcopy (eol_str, buf, eol_str_len);
+      memcpy (buf, eol_str, eol_str_len);
       buf += eol_str_len;
     }
 
@@ -19111,11 +19278,8 @@ decode_mode_spec_coding (coding_system, buf, eol_flag)
 static char lots_of_dashes[] = "--------------------------------------------------------------------------------------------------------------------------------------------";
 
 static char *
-decode_mode_spec (w, c, field_width, precision, string)
-     struct window *w;
-     register int c;
-     int field_width, precision;
-     Lisp_Object *string;
+decode_mode_spec (struct window *w, register int c, int field_width,
+                 int precision, Lisp_Object *string)
 {
   Lisp_Object obj;
   struct frame *f = XFRAME (WINDOW_FRAME (w));
@@ -19532,9 +19696,8 @@ decode_mode_spec (w, c, field_width, precision, string)
    Set *BYTE_POS_PTR to 1 if we found COUNT lines, 0 if we hit LIMIT.  */
 
 static int
-display_count_lines (start, start_byte, limit_byte, count, byte_pos_ptr)
-     int start, start_byte, limit_byte, count;
-     int *byte_pos_ptr;
+display_count_lines (int start, int start_byte, int limit_byte, int count,
+                    int *byte_pos_ptr)
 {
   register unsigned char *cursor;
   unsigned char *base;
@@ -19693,7 +19856,7 @@ display_string (string, lisp_string, face_string, face_string_pos,
      with index START.  */
   reseat_to_string (it, NILP (lisp_string) ? string : NULL, lisp_string, start,
                    precision, field_width, multibyte);
-  if (string && STRINGP (lisp_string)) 
+  if (string && STRINGP (lisp_string))
     /* LISP_STRING is the one returned by decode_mode_spec.  We should
        ignore its text properties.  */
     it->stop_charpos = -1;
@@ -19867,9 +20030,7 @@ display_string (string, lisp_string, face_string, face_string_pos,
    and 1 if it's invisible and without an ellipsis.  */
 
 int
-invisible_p (propval, list)
-     register Lisp_Object propval;
-     Lisp_Object list;
+invisible_p (register Lisp_Object propval, Lisp_Object list)
 {
   register Lisp_Object tail, proptail;
 
@@ -19998,12 +20159,8 @@ else if the text is replaced by an ellipsis.  */)
       : - 1)
 
 int
-calc_pixel_width_or_height (res, it, prop, font, width_p, align_to)
-     double *res;
-     struct it *it;
-     Lisp_Object prop;
-     struct font *font;
-     int width_p, *align_to;
+calc_pixel_width_or_height (double *res, struct it *it, Lisp_Object prop,
+                           struct font *font, int width_p, int *align_to)
 {
   double pixels;
 
@@ -20221,7 +20378,7 @@ dump_glyph_string (s)
    face-override for drawing S.  */
 
 #ifdef HAVE_NTGUI
-#define OPTIONAL_HDC(hdc)  hdc,
+#define OPTIONAL_HDC(hdc)  HDC hdc,
 #define DECLARE_HDC(hdc)   HDC hdc;
 #define ALLOCATE_HDC(hdc, f) hdc = get_frame_dc ((f))
 #define RELEASE_HDC(hdc, f)  release_frame_dc ((f), (hdc))
@@ -20235,17 +20392,12 @@ dump_glyph_string (s)
 #endif
 
 static void
-init_glyph_string (s, OPTIONAL_HDC (hdc) char2b, w, row, area, start, hl)
-     struct glyph_string *s;
-     DECLARE_HDC (hdc)
-     XChar2b *char2b;
-     struct window *w;
-     struct glyph_row *row;
-     enum glyph_row_area area;
-     int start;
-     enum draw_glyphs_face hl;
+init_glyph_string (struct glyph_string *s,
+                  OPTIONAL_HDC (hdc)
+                  XChar2b *char2b, struct window *w, struct glyph_row *row,
+                  enum glyph_row_area area, int start, enum draw_glyphs_face hl)
 {
-  bzero (s, sizeof *s);
+  memset (s, 0, sizeof *s);
   s->w = w;
   s->f = XFRAME (w->frame);
 #ifdef HAVE_NTGUI
@@ -20268,9 +20420,8 @@ init_glyph_string (s, OPTIONAL_HDC (hdc) char2b, w, row, area, start, hl)
    with head *HEAD and tail *TAIL.  Set *HEAD and *TAIL to the result.  */
 
 static INLINE void
-append_glyph_string_lists (head, tail, h, t)
-     struct glyph_string **head, **tail;
-     struct glyph_string *h, *t;
+append_glyph_string_lists (struct glyph_string **head, struct glyph_string **tail,
+                          struct glyph_string *h, struct glyph_string *t)
 {
   if (h)
     {
@@ -20289,9 +20440,8 @@ append_glyph_string_lists (head, tail, h, t)
    result.  */
 
 static INLINE void
-prepend_glyph_string_lists (head, tail, h, t)
-     struct glyph_string **head, **tail;
-     struct glyph_string *h, *t;
+prepend_glyph_string_lists (struct glyph_string **head, struct glyph_string **tail,
+                           struct glyph_string *h, struct glyph_string *t)
 {
   if (h)
     {
@@ -20309,9 +20459,8 @@ prepend_glyph_string_lists (head, tail, h, t)
    Set *HEAD and *TAIL to the resulting list.  */
 
 static INLINE void
-append_glyph_string (head, tail, s)
-     struct glyph_string **head, **tail;
-     struct glyph_string *s;
+append_glyph_string (struct glyph_string **head, struct glyph_string **tail,
+                    struct glyph_string *s)
 {
   s->next = s->prev = NULL;
   append_glyph_string_lists (head, tail, s, s);
@@ -20326,11 +20475,8 @@ append_glyph_string (head, tail, s)
    DISPLAY_P is non-zero.  */
 
 static INLINE struct face *
-get_char_face_and_encoding (f, c, face_id, char2b, multibyte_p, display_p)
-     struct frame *f;
-     int c, face_id;
-     XChar2b *char2b;
-     int multibyte_p, display_p;
+get_char_face_and_encoding (struct frame *f, int c, int face_id,
+                           XChar2b *char2b, int multibyte_p, int display_p)
 {
   struct face *face = FACE_FROM_ID (f, face_id);
 
@@ -20362,11 +20508,8 @@ get_char_face_and_encoding (f, c, face_id, char2b, multibyte_p, display_p)
    a pointer to a realized face that is ready for display.  */
 
 static INLINE struct face *
-get_glyph_face_and_encoding (f, glyph, char2b, two_byte_p)
-     struct frame *f;
-     struct glyph *glyph;
-     XChar2b *char2b;
-     int *two_byte_p;
+get_glyph_face_and_encoding (struct frame *f, struct glyph *glyph,
+                            XChar2b *char2b, int *two_byte_p)
 {
   struct face *face;
 
@@ -20404,10 +20547,8 @@ get_glyph_face_and_encoding (f, glyph, char2b, two_byte_p)
    Value is the index of a component not in S.  */
 
 static int
-fill_composite_glyph_string (s, base_face, overlaps)
-     struct glyph_string *s;
-     struct face *base_face;
-     int overlaps;
+fill_composite_glyph_string (struct glyph_string *s, struct face *base_face,
+                            int overlaps)
 {
   int i;
   /* For all glyphs of this composition, starting at the offset
@@ -20470,10 +20611,8 @@ fill_composite_glyph_string (s, base_face, overlaps)
 }
 
 static int
-fill_gstring_glyph_string (s, face_id, start, end, overlaps)
-     struct glyph_string *s;
-     int face_id;
-     int start, end, overlaps;
+fill_gstring_glyph_string (struct glyph_string *s, int face_id,
+                          int start, int end, int overlaps)
 {
   struct glyph *glyph, *last;
   Lisp_Object lgstring;
@@ -20517,10 +20656,8 @@ fill_gstring_glyph_string (s, face_id, start, end, overlaps)
    Value is the index of the first glyph not in S.  */
 
 static int
-fill_glyph_string (s, face_id, start, end, overlaps)
-     struct glyph_string *s;
-     int face_id;
-     int start, end, overlaps;
+fill_glyph_string (struct glyph_string *s, int face_id,
+                  int start, int end, int overlaps)
 {
   struct glyph *glyph, *last;
   int voffset;
@@ -20580,8 +20717,7 @@ fill_glyph_string (s, face_id, start, end, overlaps)
 /* Fill glyph string S from image glyph S->first_glyph.  */
 
 static void
-fill_image_glyph_string (s)
-     struct glyph_string *s;
+fill_image_glyph_string (struct glyph_string *s)
 {
   xassert (s->first_glyph->type == IMAGE_GLYPH);
   s->img = IMAGE_FROM_ID (s->f, s->first_glyph->u.img_id);
@@ -20605,11 +20741,8 @@ fill_image_glyph_string (s)
    Value is the index of the first glyph not in S.  */
 
 static int
-fill_stretch_glyph_string (s, row, area, start, end)
-     struct glyph_string *s;
-     struct glyph_row *row;
-     enum glyph_row_area area;
-     int start, end;
+fill_stretch_glyph_string (struct glyph_string *s, struct glyph_row *row,
+                          enum glyph_row_area area, int start, int end)
 {
   struct glyph *glyph, *last;
   int voffset, face_id;
@@ -20643,10 +20776,7 @@ fill_stretch_glyph_string (s, row, area, start, end)
 }
 
 static struct font_metrics *
-get_per_char_metric (f, font, char2b)
-     struct frame *f;
-     struct font *font;
-     XChar2b *char2b;
+get_per_char_metric (struct frame *f, struct font *font, XChar2b *char2b)
 {
   static struct font_metrics metrics;
   unsigned code = (XCHAR2B_BYTE1 (char2b) << 8) | XCHAR2B_BYTE2 (char2b);
@@ -20663,10 +20793,7 @@ get_per_char_metric (f, font, char2b)
    assumed to be zero.  */
 
 void
-x_get_glyph_overhangs (glyph, f, left, right)
-     struct glyph *glyph;
-     struct frame *f;
-     int *left, *right;
+x_get_glyph_overhangs (struct glyph *glyph, struct frame *f, int *left, int *right)
 {
   *left = *right = 0;
 
@@ -20717,8 +20844,7 @@ x_get_glyph_overhangs (glyph, f, left, right)
    if no glyphs are overwritten.  */
 
 static int
-left_overwritten (s)
-     struct glyph_string *s;
+left_overwritten (struct glyph_string *s)
 {
   int k;
 
@@ -20745,8 +20871,7 @@ left_overwritten (s)
    glyph in front of S overwrites S.  */
 
 static int
-left_overwriting (s)
-     struct glyph_string *s;
+left_overwriting (struct glyph_string *s)
 {
   int i, k, x;
   struct glyph *glyphs = s->row->glyphs[s->area];
@@ -20772,8 +20897,7 @@ left_overwriting (s)
    no such glyph is found.  */
 
 static int
-right_overwritten (s)
-     struct glyph_string *s;
+right_overwritten (struct glyph_string *s)
 {
   int k = -1;
 
@@ -20799,8 +20923,7 @@ right_overwritten (s)
    if no such glyph is found.  */
 
 static int
-right_overwriting (s)
-     struct glyph_string *s;
+right_overwriting (struct glyph_string *s)
 {
   int i, k, x;
   int end = s->row->used[s->area];
@@ -20827,10 +20950,7 @@ right_overwriting (s)
    in the drawing area.  */
 
 static INLINE void
-set_glyph_string_background_width (s, start, last_x)
-     struct glyph_string *s;
-     int start;
-     int last_x;
+set_glyph_string_background_width (struct glyph_string *s, int start, int last_x)
 {
   /* If the face of this glyph string has to be drawn to the end of
      the drawing area, set S->extends_to_end_of_line_p.  */
@@ -20859,10 +20979,7 @@ set_glyph_string_background_width (s, start, last_x)
    BACKWARD_P non-zero means process predecessors.  */
 
 static void
-compute_overhangs_and_x (s, x, backward_p)
-     struct glyph_string *s;
-     int x;
-     int backward_p;
+compute_overhangs_and_x (struct glyph_string *s, int x, int backward_p)
 {
   if (backward_p)
     {
@@ -21118,14 +21235,9 @@ compute_overhangs_and_x (s, x, backward_p)
    Value is the x-position reached, relative to AREA of W.  */
 
 static int
-draw_glyphs (w, x, row, area, start, end, hl, overlaps)
-     struct window *w;
-     int x;
-     struct glyph_row *row;
-     enum glyph_row_area area;
-     EMACS_INT start, end;
-     enum draw_glyphs_face hl;
-     int overlaps;
+draw_glyphs (struct window *w, int x, struct glyph_row *row,
+            enum glyph_row_area area, EMACS_INT start, EMACS_INT end,
+            enum draw_glyphs_face hl, int overlaps)
 {
   struct glyph_string *head, *tail;
   struct glyph_string *s;
@@ -21373,8 +21485,7 @@ draw_glyphs (w, x, row, area, start, end, hl, overlaps)
    Called from x_produce_glyphs when IT->glyph_row is non-null.  */
 
 static INLINE void
-append_glyph (it)
-     struct it *it;
+append_glyph (struct it *it)
 {
   struct glyph *glyph;
   enum glyph_row_area area = it->area;
@@ -21448,8 +21559,7 @@ append_glyph (it)
    non-null.  */
 
 static INLINE void
-append_composite_glyph (it)
-     struct it *it;
+append_composite_glyph (struct it *it)
 {
   struct glyph *glyph;
   enum glyph_row_area area = it->area;
@@ -21459,7 +21569,18 @@ append_composite_glyph (it)
   glyph = it->glyph_row->glyphs[area] + it->glyph_row->used[area];
   if (glyph < it->glyph_row->glyphs[area + 1])
     {
-      glyph->charpos = CHARPOS (it->position);
+      /* If the glyph row is reversed, we need to prepend the glyph
+        rather than append it.  */
+      if (it->glyph_row->reversed_p && it->area == TEXT_AREA)
+       {
+         struct glyph *g;
+
+         /* Make room for the new glyph.  */
+         for (g = glyph - 1; g >= it->glyph_row->glyphs[it->area]; g--)
+           g[1] = *g;
+         glyph = it->glyph_row->glyphs[it->area];
+       }
+      glyph->charpos = it->cmp_it.charpos;
       glyph->object = it->object;
       glyph->pixel_width = it->pixel_width;
       glyph->ascent = it->ascent;
@@ -21507,8 +21628,7 @@ append_composite_glyph (it)
    IT->voffset.  */
 
 static INLINE void
-take_vertical_position_into_account (it)
-     struct it *it;
+take_vertical_position_into_account (struct it *it)
 {
   if (it->voffset)
     {
@@ -21529,8 +21649,7 @@ take_vertical_position_into_account (it)
    an overview of struct display_iterator.  */
 
 static void
-produce_image_glyph (it)
-     struct it *it;
+produce_image_glyph (struct it *it)
 {
   struct image *img;
   struct face *face;
@@ -21690,11 +21809,8 @@ produce_image_glyph (it)
    stretch.  ASCENT is the ascent of the glyph (0 <= ASCENT <= HEIGHT).  */
 
 static void
-append_stretch_glyph (it, object, width, height, ascent)
-     struct it *it;
-     Lisp_Object object;
-     int width, height;
-     int ascent;
+append_stretch_glyph (struct it *it, Lisp_Object object,
+                     int width, int height, int ascent)
 {
   struct glyph *glyph;
   enum glyph_row_area area = it->area;
@@ -21785,8 +21901,7 @@ append_stretch_glyph (it, object, width, height, ascent)
    ASCENT must be in the range 0 <= ASCENT <= 100.  */
 
 static void
-produce_stretch_glyph (it)
-     struct it *it;
+produce_stretch_glyph (struct it *it)
 {
   /* (space :width WIDTH :height HEIGHT ...)  */
   Lisp_Object prop, plist;
@@ -21912,11 +22027,8 @@ produce_stretch_glyph (it)
 
 
 static Lisp_Object
-calc_line_height_property (it, val, font, boff, override)
-     struct it *it;
-     Lisp_Object val;
-     struct font *font;
-     int boff, override;
+calc_line_height_property (struct it *it, Lisp_Object val, struct font *font,
+                          int boff, int override)
 {
   Lisp_Object face_name = Qnil;
   int ascent, descent, height;
@@ -21992,8 +22104,7 @@ calc_line_height_property (it, val, font, boff, override)
    for an overview of struct it.  */
 
 void
-x_produce_glyphs (it)
-     struct it *it;
+x_produce_glyphs (struct it *it)
 {
   int extra_line_spacing = it->extra_line_spacing;
 
@@ -22198,7 +22309,7 @@ x_produce_glyphs (it)
          it->pixel_width = 0;
          it->nglyphs = 0;
 
-         height = get_it_property(it, Qline_height);
+         height = get_it_property (it, Qline_height);
          /* Split (line-height total-height) list */
          if (CONSP (height)
              && CONSP (XCDR (height))
@@ -22207,7 +22318,7 @@ x_produce_glyphs (it)
              total_height = XCAR (XCDR (height));
              height = XCAR (height);
            }
-         height = calc_line_height_property(it, height, font, boff, 1);
+         height = calc_line_height_property (it, height, font, boff, 1);
 
          if (it->override_ascent >= 0)
            {
@@ -22257,11 +22368,11 @@ x_produce_glyphs (it)
                it->ascent = XINT (height) - it->descent;
 
              if (!NILP (total_height))
-               spacing = calc_line_height_property(it, total_height, font, boff, 0);
+               spacing = calc_line_height_property (it, total_height, font, boff, 0);
              else
                {
-                 spacing = get_it_property(it, Qline_spacing);
-                 spacing = calc_line_height_property(it, spacing, font, boff, 0);
+                 spacing = get_it_property (it, Qline_spacing);
+                 spacing = calc_line_height_property (it, spacing, font, boff, 0);
                }
              if (INTEGERP (spacing))
                {
@@ -22779,9 +22890,7 @@ x_produce_glyphs (it)
    row being updated.  */
 
 void
-x_write_glyphs (start, len)
-     struct glyph *start;
-     int len;
+x_write_glyphs (struct glyph *start, int len)
 {
   int x, hpos;
 
@@ -22816,9 +22925,7 @@ x_write_glyphs (start, len)
    Insert LEN glyphs from START at the nominal cursor position.  */
 
 void
-x_insert_glyphs (start, len)
-     struct glyph *start;
-     int len;
+x_insert_glyphs (struct glyph *start, int len)
 {
   struct frame *f;
   struct window *w;
@@ -22876,8 +22983,7 @@ x_insert_glyphs (start, len)
    updated_window.  TO_X == -1 means clear to the end of this area.  */
 
 void
-x_clear_end_of_line (to_x)
-     int to_x;
+x_clear_end_of_line (int to_x)
 {
   struct frame *f;
   struct window *w = updated_window;
@@ -22953,9 +23059,7 @@ x_clear_end_of_line (to_x)
    of the bar cursor.  */
 
 static enum text_cursor_kinds
-get_specified_cursor_type (arg, width)
-     Lisp_Object arg;
-     int *width;
+get_specified_cursor_type (Lisp_Object arg, int *width)
 {
   enum text_cursor_kinds type;
 
@@ -23008,9 +23112,7 @@ get_specified_cursor_type (arg, width)
 
 /* Set the default cursor types for specified frame.  */
 void
-set_frame_cursor_types (f, arg)
-     struct frame *f;
-     Lisp_Object arg;
+set_frame_cursor_types (struct frame *f, Lisp_Object arg)
 {
   int width;
   Lisp_Object tem;
@@ -23044,11 +23146,8 @@ set_frame_cursor_types (f, arg)
    In all other cases, we want a hollow box cursor.  */
 
 static enum text_cursor_kinds
-get_window_cursor_type (w, glyph, width, active_cursor)
-     struct window *w;
-     struct glyph *glyph;
-     int *width;
-     int *active_cursor;
+get_window_cursor_type (struct window *w, struct glyph *glyph, int *width,
+                       int *active_cursor)
 {
   struct frame *f = XFRAME (w->frame);
   struct buffer *b = XBUFFER (w->buffer);
@@ -23204,10 +23303,8 @@ get_window_cursor_type (w, glyph, width, active_cursor)
    are window-relative.  */
 
 static void
-notice_overwritten_cursor (w, area, x0, x1, y0, y1)
-     struct window *w;
-     enum glyph_row_area area;
-     int x0, y0, x1, y1;
+notice_overwritten_cursor (struct window *w, enum glyph_row_area area,
+                          int x0, int x1, int y0, int y1)
 {
   int cx0, cx1, cy0, cy1;
   struct glyph_row *row;
@@ -23274,11 +23371,8 @@ notice_overwritten_cursor (w, area, x0, x1, y0, y1)
    with respect to the overlapping part OVERLAPS.  */
 
 void
-x_fix_overlapping_area (w, row, area, overlaps)
-     struct window *w;
-     struct glyph_row *row;
-     enum glyph_row_area area;
-     int overlaps;
+x_fix_overlapping_area (struct window *w, struct glyph_row *row,
+                       enum glyph_row_area area, int overlaps)
 {
   int i, x;
 
@@ -23319,10 +23413,8 @@ x_fix_overlapping_area (w, row, area, overlaps)
    comment of draw_glyphs for the meaning of HL.  */
 
 void
-draw_phys_cursor_glyph (w, row, hl)
-     struct window *w;
-     struct glyph_row *row;
-     enum draw_glyphs_face hl;
+draw_phys_cursor_glyph (struct window *w, struct glyph_row *row,
+                       enum draw_glyphs_face hl)
 {
   /* If cursor hpos is out of bounds, don't draw garbage.  This can
      happen in mini-buffer windows when switching between echo area
@@ -23365,8 +23457,7 @@ draw_phys_cursor_glyph (w, row, hl)
    Erase the image of a cursor of window W from the screen.  */
 
 void
-erase_phys_cursor (w)
-     struct window *w;
+erase_phys_cursor (struct window *w)
 {
   struct frame *f = XFRAME (w->frame);
   Display_Info *dpyinfo = FRAME_X_DISPLAY_INFO (f);
@@ -23436,7 +23527,7 @@ erase_phys_cursor (w)
       /* 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.  */
-      && cursor_row->used[TEXT_AREA] > hpos)
+      && cursor_row->used[TEXT_AREA] > hpos && hpos >= 0)
     mouse_face_here_p = 1;
 
   /* Maybe clear the display under the cursor.  */
@@ -23482,9 +23573,8 @@ erase_phys_cursor (w)
    where to put the cursor is specified by HPOS, VPOS, X and Y.  */
 
 void
-display_and_set_cursor (w, on, hpos, vpos, x, y)
-     struct window *w;
-     int on, hpos, vpos, x, y;
+display_and_set_cursor (struct window *w, int on,
+                       int hpos, int vpos, int x, int y)
 {
   struct frame *f = XFRAME (w->frame);
   int new_cursor_type;
@@ -23518,7 +23608,7 @@ display_and_set_cursor (w, on, hpos, vpos, x, y)
 
   glyph = NULL;
   if (!glyph_row->exact_window_width_line_p
-      || hpos < glyph_row->used[TEXT_AREA])
+      || (0 <= hpos && hpos < glyph_row->used[TEXT_AREA]))
     glyph = glyph_row->glyphs[TEXT_AREA] + hpos;
 
   xassert (interrupt_input_blocked);
@@ -23567,9 +23657,7 @@ display_and_set_cursor (w, on, hpos, vpos, x, y)
    of ON.  */
 
 void
-update_window_cursor (w, on)
-     struct window *w;
-     int on;
+update_window_cursor (struct window *w, int on)
 {
   /* Don't update cursor in windows whose frame is in the process
      of being deleted.  */
@@ -23587,9 +23675,7 @@ update_window_cursor (w, on)
    in the window tree rooted at W.  */
 
 static void
-update_cursor_in_window_tree (w, on_p)
-     struct window *w;
-     int on_p;
+update_cursor_in_window_tree (struct window *w, int on_p)
 {
   while (w)
     {
@@ -23610,9 +23696,7 @@ update_cursor_in_window_tree (w, on_p)
    Don't change the cursor's position.  */
 
 void
-x_update_cursor (f, on_p)
-     struct frame *f;
-     int on_p;
+x_update_cursor (struct frame *f, int on_p)
 {
   update_cursor_in_window_tree (XWINDOW (f->root_window), on_p);
 }
@@ -23624,8 +23708,7 @@ x_update_cursor (f, on_p)
    is about to be rewritten.  */
 
 void
-x_clear_cursor (w)
-     struct window *w;
+x_clear_cursor (struct window *w)
 {
   if (FRAME_VISIBLE_P (XFRAME (w->frame)) && w->phys_cursor_on_p)
     update_window_cursor (w, 0);
@@ -23636,9 +23719,7 @@ x_clear_cursor (w)
    Display the active region described by mouse_face_* according to DRAW.  */
 
 void
-show_mouse_face (dpyinfo, draw)
-     Display_Info *dpyinfo;
-     enum draw_glyphs_face draw;
+show_mouse_face (Display_Info *dpyinfo, enum draw_glyphs_face draw)
 {
   struct window *w = XWINDOW (dpyinfo->mouse_face_window);
   struct frame *f = XFRAME (WINDOW_FRAME (w));
@@ -23721,8 +23802,7 @@ show_mouse_face (dpyinfo, draw)
    face was actually drawn unhighlighted.  */
 
 int
-clear_mouse_face (dpyinfo)
-     Display_Info *dpyinfo;
+clear_mouse_face (Display_Info *dpyinfo)
 {
   int cleared = 0;
 
@@ -23744,8 +23824,7 @@ clear_mouse_face (dpyinfo)
    Non-zero if physical cursor of window W is within mouse face.  */
 
 int
-cursor_in_mouse_face_p (w)
-     struct window *w;
+cursor_in_mouse_face_p (struct window *w)
 {
   Display_Info *dpyinfo = FRAME_X_DISPLAY_INFO (XFRAME (w->frame));
   int in_mouse_face = 0;
@@ -23970,12 +24049,8 @@ mouse_face_from_buffer_pos (Lisp_Object window,
    Value is non-zero if a glyph was found.  */
 
 static int
-fast_find_string_pos (w, pos, object, hpos, vpos, x, y, right_p)
-     struct window *w;
-     EMACS_INT pos;
-     Lisp_Object object;
-     int *hpos, *vpos, *x, *y;
-     int right_p;
+fast_find_string_pos (struct window *w, EMACS_INT pos, Lisp_Object object,
+                     int *hpos, int *vpos, int *x, int *y, int right_p)
 {
   int yb = window_text_bottom_y (w);
   struct glyph_row *r;
@@ -24039,9 +24114,7 @@ fast_find_string_pos (w, pos, object, hpos, vpos, x, y, right_p)
 /* See if position X, Y is within a hot-spot of an image.  */
 
 static int
-on_hot_spot_p (hot_spot, x, y)
-     Lisp_Object hot_spot;
-     int x, y;
+on_hot_spot_p (Lisp_Object hot_spot, int x, int y)
 {
   if (!CONSP (hot_spot))
     return 0;
@@ -24137,9 +24210,7 @@ on_hot_spot_p (hot_spot, x, y)
 }
 
 Lisp_Object
-find_hot_spot (map, x, y)
-     Lisp_Object map;
-     int x, y;
+find_hot_spot (Lisp_Object map, int x, int y)
 {
   while (CONSP (map))
     {
@@ -24180,10 +24251,7 @@ Returns the alist element for the first matching AREA in MAP.  */)
 
 /* Display frame CURSOR, optionally using shape defined by POINTER.  */
 static void
-define_frame_cursor1 (f, cursor, pointer)
-     struct frame *f;
-     Cursor cursor;
-     Lisp_Object pointer;
+define_frame_cursor1 (struct frame *f, Cursor cursor, Lisp_Object pointer)
 {
   /* Do not change cursor shape while dragging mouse.  */
   if (!NILP (do_mouse_tracking))
@@ -24222,10 +24290,8 @@ define_frame_cursor1 (f, cursor, pointer)
    position relative to the start of the mode line.  */
 
 static void
-note_mode_line_or_margin_highlight (window, x, y, area)
-     Lisp_Object window;
-     int x, y;
-     enum window_part area;
+note_mode_line_or_margin_highlight (Lisp_Object window, int x, int y,
+                                   enum window_part area)
 {
   struct window *w = XWINDOW (window);
   struct frame *f = XFRAME (w->frame);
@@ -24465,9 +24531,7 @@ note_mode_line_or_margin_highlight (window, x, y, area)
    X and Y can be negative or out of range.  */
 
 void
-note_mouse_highlight (f, x, y)
-     struct frame *f;
-     int x, y;
+note_mouse_highlight (struct frame *f, int x, int y)
 {
   Display_Info *dpyinfo = FRAME_X_DISPLAY_INFO (f);
   enum window_part part;
@@ -24933,8 +24997,7 @@ note_mouse_highlight (f, x, y)
    functions to ensure the mouse-highlight is off.  */
 
 void
-x_clear_window_mouse_face (w)
-     struct window *w;
+x_clear_window_mouse_face (struct window *w)
 {
   Display_Info *dpyinfo = FRAME_X_DISPLAY_INFO (XFRAME (w->frame));
   Lisp_Object window;
@@ -24952,8 +25015,7 @@ x_clear_window_mouse_face (w)
    This is used when the size of F is changed.  */
 
 void
-cancel_mouse_face (f)
-     struct frame *f;
+cancel_mouse_face (struct frame *f)
 {
   Lisp_Object window;
   Display_Info *dpyinfo = FRAME_X_DISPLAY_INFO (f);
@@ -24981,11 +25043,8 @@ cancel_mouse_face (f)
    which intersects rectangle R.  R is in window-relative coordinates.  */
 
 static void
-expose_area (w, row, r, area)
-     struct window *w;
-     struct glyph_row *row;
-     XRectangle *r;
-     enum glyph_row_area area;
+expose_area (struct window *w, struct glyph_row *row, XRectangle *r,
+            enum glyph_row_area area)
 {
   struct glyph *first = row->glyphs[area];
   struct glyph *end = row->glyphs[area] + row->used[area];
@@ -25039,10 +25098,7 @@ expose_area (w, row, r, area)
    non-zero if mouse-face was overwritten.  */
 
 static int
-expose_line (w, row, r)
-     struct window *w;
-     struct glyph_row *row;
-     XRectangle *r;
+expose_line (struct window *w, struct glyph_row *row, XRectangle *r)
 {
   xassert (row->enabled_p);
 
@@ -25074,11 +25130,10 @@ expose_line (w, row, r)
    LAST_OVERLAPPING_ROW is the last such row.  */
 
 static void
-expose_overlaps (w, first_overlapping_row, last_overlapping_row, r)
-     struct window *w;
-     struct glyph_row *first_overlapping_row;
-     struct glyph_row *last_overlapping_row;
-     XRectangle *r;
+expose_overlaps (struct window *w,
+                struct glyph_row *first_overlapping_row,
+                struct glyph_row *last_overlapping_row,
+                XRectangle *r)
 {
   struct glyph_row *row;
 
@@ -25104,9 +25159,7 @@ expose_overlaps (w, first_overlapping_row, last_overlapping_row, r)
 /* Return non-zero if W's cursor intersects rectangle R.  */
 
 static int
-phys_cursor_in_rect_p (w, r)
-     struct window *w;
-     XRectangle *r;
+phys_cursor_in_rect_p (struct window *w, XRectangle *r)
 {
   XRectangle cr, result;
   struct glyph *cursor_glyph;
@@ -25152,8 +25205,7 @@ phys_cursor_in_rect_p (w, r)
    have vertical scroll bars.  */
 
 void
-x_draw_vertical_border (w)
-     struct window *w;
+x_draw_vertical_border (struct window *w)
 {
   struct frame *f = XFRAME (WINDOW_FRAME (w));
 
@@ -25203,9 +25255,7 @@ x_draw_vertical_border (w)
    mouse-face.  */
 
 static int
-expose_window (w, fr)
-     struct window *w;
-     XRectangle *fr;
+expose_window (struct window *w, XRectangle *fr)
 {
   struct frame *f = XFRAME (w->frame);
   XRectangle wr, r;
@@ -25338,9 +25388,7 @@ expose_window (w, fr)
    non-zero if the exposure overwrites mouse-face.  */
 
 static int
-expose_window_tree (w, r)
-     struct window *w;
-     XRectangle *r;
+expose_window_tree (struct window *w, XRectangle *r)
 {
   struct frame *f = XFRAME (w->frame);
   int mouse_face_overwritten_p = 0;
@@ -25370,9 +25418,7 @@ expose_window_tree (w, r)
    the entire frame.  */
 
 void
-expose_frame (f, x, y, w, h)
-     struct frame *f;
-     int x, y, w, h;
+expose_frame (struct frame *f, int x, int y, int w, int h)
 {
   XRectangle r;
   int mouse_face_overwritten_p = 0;
@@ -25460,8 +25506,7 @@ expose_frame (f, x, y, w, h)
    empty.  */
 
 int
-x_intersect_rectangles (r1, r2, result)
-     XRectangle *r1, *r2, *result;
+x_intersect_rectangles (XRectangle *r1, XRectangle *r2, XRectangle *result)
 {
   XRectangle *left, *right;
   XRectangle *upper, *lower;
@@ -25516,7 +25561,7 @@ x_intersect_rectangles (r1, r2, result)
  ***********************************************************************/
 
 void
-syms_of_xdisp ()
+syms_of_xdisp (void)
 {
   Vwith_echo_area_save_vector = Qnil;
   staticpro (&Vwith_echo_area_save_vector);
@@ -25548,6 +25593,7 @@ syms_of_xdisp ()
 #endif
   defsubr (&Sformat_mode_line);
   defsubr (&Sinvisible_p);
+  defsubr (&Scurrent_bidi_paragraph_direction);
 
   staticpro (&Qmenu_bar_update_hook);
   Qmenu_bar_update_hook = intern_c_string ("menu-bar-update-hook");
@@ -25621,6 +25667,12 @@ syms_of_xdisp ()
   staticpro (&Qnobreak_space);
   Qimage = intern_c_string ("image");
   staticpro (&Qimage);
+  Qtext = intern_c_string ("text");
+  staticpro (&Qtext);
+  Qboth = intern_c_string ("both");
+  staticpro (&Qboth);
+  Qboth_horiz = intern_c_string ("both-horiz");
+  staticpro (&Qboth_horiz);
   QCmap = intern_c_string (":map");
   staticpro (&QCmap);
   QCpointer = intern_c_string (":pointer");
@@ -25961,6 +26013,22 @@ vertical margin.  */);
     doc: /* *Relief thickness of tool-bar buttons.  */);
   tool_bar_button_relief = DEFAULT_TOOL_BAR_BUTTON_RELIEF;
 
+  DEFVAR_LISP ("tool-bar-style", &Vtool_bar_style,
+    doc: /* *Tool bar style to use.
+It can be one of
+ image      - show images only
+ text       - show text only
+ both       - show both, text under image
+ both-horiz - show text to the right of the image
+ any other  - use system default or image if no system default.  */);
+  Vtool_bar_style = Qnil;
+
+  DEFVAR_INT ("tool-bar-max-label-size", &tool_bar_max_label_size,
+    doc: /* *Maximum number of characters a label can have to be shown.
+The tool bar style must also show labels for this to have any effect, see
+`tool-bar-style'.  */);
+  tool_bar_max_label_size = DEFAULT_TOOL_BAR_LABEL_SIZE;
+
   DEFVAR_LISP ("fontification-functions", &Vfontification_functions,
     doc: /* List of functions to call to fontify regions of text.
 Each function is called with one argument POS.  Functions must
@@ -26140,7 +26208,7 @@ Value must be an integer or float.  */);
 /* Initialize this module when Emacs starts.  */
 
 void
-init_xdisp ()
+init_xdisp (void)
 {
   Lisp_Object root_window;
   struct window *mini_w;
@@ -26197,14 +26265,14 @@ init_xdisp ()
 
 /* Return non-zero if houglass timer has been started or hourglass is shown.  */
 int
-hourglass_started ()
+hourglass_started (void)
 {
   return hourglass_shown_p || hourglass_atimer != NULL;
 }
 
 /* Cancel a currently active hourglass timer, and start a new one.  */
 void
-start_hourglass ()
+start_hourglass (void)
 {
 #if defined (HAVE_WINDOW_SYSTEM)
   EMACS_TIME delay;
@@ -26236,7 +26304,7 @@ start_hourglass ()
 /* Cancel the hourglass cursor timer if active, hide a busy cursor if
    shown.  */
 void
-cancel_hourglass ()
+cancel_hourglass (void)
 {
 #if defined (HAVE_WINDOW_SYSTEM)
   if (hourglass_atimer)