]> code.delx.au - gnu-emacs/blobdiff - src/xdisp.c
Merge from origin/emacs-24
[gnu-emacs] / src / xdisp.c
index a1cc286512bc6258cfbe33835834d39987307bca..8d15febddc66e38b33a5a0826af9115443866290 100644 (file)
@@ -324,52 +324,9 @@ along with GNU Emacs.  If not, see <http://www.gnu.org/licenses/>.  */
 
 #define INFINITY 10000000
 
-Lisp_Object Qoverriding_local_map, Qoverriding_terminal_local_map;
-Lisp_Object Qwindow_scroll_functions;
-static Lisp_Object Qwindow_text_change_functions;
-static Lisp_Object Qredisplay_end_trigger_functions;
-Lisp_Object Qinhibit_point_motion_hooks;
-static Lisp_Object QCeval, QCpropertize;
-Lisp_Object QCfile, QCdata;
-static Lisp_Object Qfontified;
-static Lisp_Object Qgrow_only;
-static Lisp_Object Qinhibit_eval_during_redisplay;
-static Lisp_Object Qbuffer_position, Qposition, Qobject;
-static Lisp_Object Qright_to_left, Qleft_to_right;
-
-/* Cursor shapes.  */
-Lisp_Object Qbar, Qhbar, Qbox, Qhollow;
-
-/* Pointer shapes.  */
-static Lisp_Object Qarrow, Qhand;
-Lisp_Object Qtext;
-
 /* Holds the list (error).  */
 static Lisp_Object list_of_error;
 
-static Lisp_Object Qfontification_functions;
-
-static Lisp_Object Qwrap_prefix;
-static Lisp_Object Qline_prefix;
-static Lisp_Object Qredisplay_internal;
-
-/* Non-nil means don't actually do any redisplay.  */
-
-Lisp_Object Qinhibit_redisplay;
-
-/* Names of text properties relevant for redisplay.  */
-
-Lisp_Object Qdisplay;
-
-Lisp_Object Qspace, QCalign_to;
-static Lisp_Object QCrelative_width, QCrelative_height;
-Lisp_Object Qleft_margin, Qright_margin;
-static Lisp_Object Qspace_width, Qraise;
-static Lisp_Object Qslice;
-Lisp_Object Qcenter;
-static Lisp_Object Qmargin, Qpointer;
-static Lisp_Object Qline_height;
-
 #ifdef HAVE_WINDOW_SYSTEM
 
 /* Test if overflow newline into fringe.  Called with iterator IT
@@ -403,31 +360,6 @@ static Lisp_Object Qline_height;
           && (*BYTE_POS_ADDR (IT_BYTEPOS (*it)) == ' '                 \
               || *BYTE_POS_ADDR (IT_BYTEPOS (*it)) == '\t'))))         \
 
-/* Name of the face used to highlight trailing whitespace.  */
-
-static Lisp_Object Qtrailing_whitespace;
-
-/* Name and number of the face used to highlight escape glyphs.  */
-
-static Lisp_Object Qescape_glyph;
-
-/* Name and number of the face used to highlight non-breaking spaces.  */
-
-static Lisp_Object Qnobreak_space;
-
-/* The symbol `image' which is the car of the lists used to represent
-   images in Lisp.  Also a tool bar style.  */
-
-Lisp_Object Qimage;
-
-/* The image map types.  */
-Lisp_Object QCmap;
-static Lisp_Object QCpointer;
-static Lisp_Object Qrect, Qcircle, Qpoly;
-
-/* Tool bar styles */
-Lisp_Object Qboth, Qboth_horiz, Qtext_image_horiz;
-
 /* Non-zero means print newline to stdout before next mini-buffer
    message.  */
 
@@ -477,21 +409,6 @@ static struct text_pos this_line_min_pos;
 
 static struct buffer *this_line_buffer;
 
-
-/* Values of those variables at last redisplay are stored as
-   properties on `overlay-arrow-position' symbol.  However, if
-   Voverlay_arrow_position is a marker, last-arrow-position is its
-   numerical position.  */
-
-static Lisp_Object Qlast_arrow_position, Qlast_arrow_string;
-
-/* Alternative overlay-arrow-string and overlay-arrow-bitmap
-   properties on a symbol in overlay-arrow-variable-list.  */
-
-static Lisp_Object Qoverlay_arrow_string, Qoverlay_arrow_bitmap;
-
-Lisp_Object Qmenu_bar_update_hook;
-
 /* Nonzero if an overlay arrow has been displayed in this window.  */
 
 static bool overlay_arrow_seen;
@@ -567,11 +484,6 @@ static bool display_last_displayed_message_p;
 
 static bool message_buf_print;
 
-/* The symbol `inhibit-menubar-update' and its DEFVAR_BOOL variable.  */
-
-static Lisp_Object Qinhibit_menubar_update;
-static Lisp_Object Qmessage_truncate_lines;
-
 /* Set to 1 in clear_message to make redisplay_internal aware
    of an emptied echo area.  */
 
@@ -691,8 +603,6 @@ int trace_move;
 #define TRACE_MOVE(x)  (void) 0
 #endif
 
-static Lisp_Object Qauto_hscroll_mode;
-
 /* Buffer being redisplayed -- for redisplay_window_error.  */
 
 static struct buffer *displayed_buffer;
@@ -712,8 +622,8 @@ enum prop_handled
 
 struct props
 {
-  /* The name of the property.  */
-  Lisp_Object *name;
+  /* The symbol index of the name of the property.  */
+  short name;
 
   /* A unique index for the property.  */
   enum prop_idx idx;
@@ -734,14 +644,14 @@ static enum prop_handled handle_fontified_prop (struct it *);
 
 static struct props it_props[] =
 {
-  {&Qfontified,                FONTIFIED_PROP_IDX,     handle_fontified_prop},
+  {SYMBOL_INDEX (Qfontified),  FONTIFIED_PROP_IDX,     handle_fontified_prop},
   /* Handle `face' before `display' because some sub-properties of
      `display' need to know the face.  */
-  {&Qface,             FACE_PROP_IDX,          handle_face_prop},
-  {&Qdisplay,          DISPLAY_PROP_IDX,       handle_display_prop},
-  {&Qinvisible,                INVISIBLE_PROP_IDX,     handle_invisible_prop},
-  {&Qcomposition,      COMPOSITION_PROP_IDX,   handle_composition_prop},
-  {NULL,               0,                      NULL}
+  {SYMBOL_INDEX (Qface),       FACE_PROP_IDX,          handle_face_prop},
+  {SYMBOL_INDEX (Qdisplay),    DISPLAY_PROP_IDX,       handle_display_prop},
+  {SYMBOL_INDEX (Qinvisible),  INVISIBLE_PROP_IDX,     handle_invisible_prop},
+  {SYMBOL_INDEX (Qcomposition),        COMPOSITION_PROP_IDX, handle_composition_prop},
+  {0,                          0,                      NULL}
 };
 
 /* Value is the position described by X.  If X is a marker, value is
@@ -796,9 +706,6 @@ static struct glyph_slice null_glyph_slice = { 0, 0, 0, 0 };
 
 bool redisplaying_p;
 
-static Lisp_Object Qinhibit_free_realized_faces;
-static Lisp_Object Qmode_line_default_help_echo;
-
 /* If a string, XTread_socket generates an event to display that string.
    (The display is done in read_char.)  */
 
@@ -816,23 +723,14 @@ Lisp_Object previous_help_echo_string;
 #ifdef HAVE_WINDOW_SYSTEM
 
 /* Non-zero means an hourglass cursor is currently shown.  */
-bool hourglass_shown_p;
+static bool hourglass_shown_p;
 
 /* If non-null, an asynchronous timer that, when it expires, displays
    an hourglass cursor on all frames.  */
-struct atimer *hourglass_atimer;
+static struct atimer *hourglass_atimer;
 
 #endif /* HAVE_WINDOW_SYSTEM */
 
-/* Name of the face used to display glyphless characters.  */
-static Lisp_Object Qglyphless_char;
-
-/* Symbol for the purpose of Vglyphless_char_display.  */
-static Lisp_Object Qglyphless_char_display;
-
-/* Method symbols for Vglyphless_char_display.  */
-static Lisp_Object Qhex_code, Qempty_box, Qthin_space, Qzero_width;
-
 /* Default number of seconds to wait before displaying an hourglass
    cursor.  */
 #define DEFAULT_HOURGLASS_DELAY 1
@@ -905,7 +803,7 @@ static void iterate_out_of_display_property (struct it *);
 static void pop_it (struct it *);
 static void sync_frame_with_window_matrix_rows (struct window *);
 static void redisplay_internal (void);
-static int echo_area_display (int);
+static bool echo_area_display (bool);
 static void redisplay_windows (Lisp_Object);
 static void redisplay_window (Lisp_Object, bool);
 static Lisp_Object redisplay_window_error (Lisp_Object);
@@ -1024,6 +922,8 @@ window_text_bottom_y (struct window *w)
   if (WINDOW_WANTS_MODELINE_P (w))
     height -= CURRENT_MODE_LINE_HEIGHT (w);
 
+  height -= WINDOW_SCROLL_BAR_AREA_HEIGHT (w);
+
   return height;
 }
 
@@ -1068,6 +968,7 @@ window_box_height (struct window *w)
   eassert (height >= 0);
 
   height -= WINDOW_BOTTOM_DIVIDER_WIDTH (w);
+  height -= WINDOW_SCROLL_BAR_AREA_HEIGHT (w);
 
   /* Note: the code below that determines the mode-line/header-line
      height is essentially the same as that contained in the macro
@@ -1141,7 +1042,7 @@ window_box_left_offset (struct window *w, enum glyph_row_area area)
    area AREA of window W.  ANY_AREA means return the right edge of the
    whole window, to the left of the right fringe of W.  */
 
-int
+static int
 window_box_right_offset (struct window *w, enum glyph_row_area area)
 {
   /* Don't return more than the window's pixel width.  */
@@ -1972,8 +1873,8 @@ pixel_to_glyph_coords (struct frame *f, register int pix_x, register int pix_y,
 
          if (pix_y < 0)
            pix_y = 0;
-         else if (pix_y > FRAME_LINES (f))
-           pix_y = FRAME_LINES (f);
+         else if (pix_y > FRAME_TOTAL_LINES (f))
+           pix_y = FRAME_TOTAL_LINES (f);
        }
     }
 #endif
@@ -2189,7 +2090,10 @@ get_glyph_string_clip_rects (struct glyph_string *s, NativeRectangle *rects, int
 
       if (s->x > r.x)
        {
-         r.width -= s->x - r.x;
+         if (r.width >= s->x - r.x)
+           r.width -= s->x - r.x;
+         else  /* R2L hscrolled row with cursor outside text area */
+           r.width = 0;
          r.x = s->x;
        }
       r.width = min (r.width, glyph->pixel_width);
@@ -2311,10 +2215,7 @@ get_phys_cursor_geometry (struct window *w, struct glyph_row *row,
      glyph, and `x-stretch-block-cursor' is nil, don't draw a
      rectangle as wide as the glyph, but use a canonical character
      width instead.  */
-  wd = glyph->pixel_width - 1;
-#if defined (HAVE_NTGUI) || defined (HAVE_NS)
-  wd++; /* Why? */
-#endif
+  wd = glyph->pixel_width;
 
   x = w->phys_cursor.x;
   if (x < 0)
@@ -2516,7 +2417,7 @@ remember_mouse_glyph (struct frame *f, int gx, int gy, NativeRectangle *rect)
       gx = WINDOW_PIXEL_WIDTH (w) - width;
       goto row_glyph;
 
-    case ON_SCROLL_BAR:
+    case ON_VERTICAL_SCROLL_BAR:
       gx = (WINDOW_HAS_VERTICAL_SCROLL_BAR_ON_LEFT (w)
            ? 0
            : (window_box_right_offset (w, RIGHT_MARGIN_AREA)
@@ -2550,7 +2451,7 @@ remember_mouse_glyph (struct frame *f, int gx, int gy, NativeRectangle *rect)
       gy = 0;
       /* The bottom divider prevails. */
       height = WINDOW_PIXEL_HEIGHT (w) - WINDOW_BOTTOM_DIVIDER_WIDTH (w);
-      goto add_edge;;
+      goto add_edge;
 
     case ON_BOTTOM_DIVIDER:
       gx = 0;
@@ -2638,15 +2539,14 @@ safe__call (bool inhibit_quit, ptrdiff_t nargs, Lisp_Object func, va_list ap)
     {
       ptrdiff_t i;
       ptrdiff_t count = SPECPDL_INDEX ();
-      struct gcpro gcpro1;
-      Lisp_Object *args = alloca (nargs * word_size);
+      Lisp_Object *args;
+      USE_SAFE_ALLOCA;
+      SAFE_ALLOCA_LISP (args, nargs);
 
       args[0] = func;
       for (i = 1; i < nargs; i++)
        args[i] = va_arg (ap, Lisp_Object);
 
-      GCPRO1 (args[0]);
-      gcpro1.nvars = nargs;
       specbind (Qinhibit_redisplay, Qt);
       if (inhibit_quit)
        specbind (Qinhibit_quit, Qt);
@@ -2654,7 +2554,7 @@ safe__call (bool inhibit_quit, ptrdiff_t nargs, Lisp_Object func, va_list ap)
         so there is no possibility of wanting to redisplay.  */
       val = internal_condition_case_n (Ffuncall, nargs, args, Qt,
                                       safe_eval_handler);
-      UNGCPRO;
+      SAFE_FREE ();
       val = unbind_to (count, val);
     }
 
@@ -2694,8 +2594,6 @@ safe__call1 (bool inhibit_quit, Lisp_Object fn, ...)
   return retval;
 }
 
-static Lisp_Object Qeval;
-
 Lisp_Object
 safe_eval (Lisp_Object sexpr)
 {
@@ -2848,17 +2746,14 @@ init_iterator (struct it *it, struct window *w,
        row = MATRIX_HEADER_LINE_ROW (w->desired_matrix);
     }
 
-  /* Clear IT.  */
-  memset (it, 0, sizeof *it);
+  /* Clear IT, and set it->object and other IT's Lisp objects to Qnil.
+     Other parts of redisplay rely on that.  */
+  memclear (it, sizeof *it);
   it->current.overlay_string_index = -1;
   it->current.dpvec_index = -1;
   it->base_face_id = remapped_base_face_id;
-  it->string = Qnil;
   IT_STRING_CHARPOS (*it) = IT_STRING_BYTEPOS (*it) = -1;
   it->paragraph_embedding = L2R;
-  it->bidi_it.string.lstring = Qnil;
-  it->bidi_it.string.s = NULL;
-  it->bidi_it.string.bufpos = 0;
   it->bidi_it.w = w;
 
   /* The window in which we iterate over current_buffer:  */
@@ -2879,7 +2774,6 @@ init_iterator (struct it *it, struct window *w,
                                  * FRAME_LINE_HEIGHT (it->f));
       else if (it->f->extra_line_spacing > 0)
        it->extra_line_spacing = it->f->extra_line_spacing;
-      it->max_extra_line_spacing = 0;
     }
 
   /* If realized faces have been removed, e.g. because of face
@@ -2891,10 +2785,6 @@ init_iterator (struct it *it, struct window *w,
   if (FRAME_FACE_CACHE (it->f)->used == 0)
     recompute_basic_faces (it->f);
 
-  /* Current value of the `slice', `space-width', and 'height' properties.  */
-  it->slice.x = it->slice.y = it->slice.width = it->slice.height = Qnil;
-  it->space_width = Qnil;
-  it->font_height = Qnil;
   it->override_ascent = -1;
 
   /* Are control characters displayed as `^C'?  */
@@ -2932,21 +2822,19 @@ init_iterator (struct it *it, struct window *w,
   it->tab_width = SANE_TAB_WIDTH (current_buffer);
 
   /* Are lines in the display truncated?  */
-  if (base_face_id != DEFAULT_FACE_ID
-      || it->w->hscroll
-      || (! WINDOW_FULL_WIDTH_P (it->w)
-         && ((!NILP (Vtruncate_partial_width_windows)
-              && !INTEGERP (Vtruncate_partial_width_windows))
-             || (INTEGERP (Vtruncate_partial_width_windows)
-                 /* PXW: Shall we do something about this?  */
-                 && (WINDOW_TOTAL_COLS (it->w)
-                     < XINT (Vtruncate_partial_width_windows))))))
+  if (TRUNCATE != 0)
     it->line_wrap = TRUNCATE;
-  else if (NILP (BVAR (current_buffer, truncate_lines)))
+  if (base_face_id == DEFAULT_FACE_ID
+      && !it->w->hscroll
+      && (WINDOW_FULL_WIDTH_P (it->w)
+         || NILP (Vtruncate_partial_width_windows)
+         || (INTEGERP (Vtruncate_partial_width_windows)
+             /* PXW: Shall we do something about this?  */
+             && (XINT (Vtruncate_partial_width_windows)
+                 <= WINDOW_TOTAL_COLS (it->w))))
+      && NILP (BVAR (current_buffer, truncate_lines)))
     it->line_wrap = NILP (BVAR (current_buffer, word_wrap))
       ? WINDOW_WRAP : WORD_WRAP;
-  else
-    it->line_wrap = TRUNCATE;
 
   /* Get dimensions of truncation and continuation glyphs.  These are
      displayed as fringe bitmaps under X, but we need them for such
@@ -2986,10 +2874,6 @@ init_iterator (struct it *it, struct window *w,
   it->glyph_row = row;
   it->area = TEXT_AREA;
 
-  /* Forget any previous info about this row being reversed.  */
-  if (it->glyph_row)
-    it->glyph_row->reversed_p = 0;
-
   /* Get the dimensions of the display area.  The display area
      consists of the visible window area plus a horizontally scrolled
      part to the left of the window.  All x-values are relative to the
@@ -3622,7 +3506,8 @@ compute_stop_pos (struct it *it)
 
       /* Get properties here.  */
       for (p = it_props; p->handler; ++p)
-       values_here[p->idx] = textget (iv->plist, *p->name);
+       values_here[p->idx] = textget (iv->plist,
+                                      builtin_lisp_symbol (p->name));
 
       /* Look for an interval following iv that has different
         properties.  */
@@ -3634,9 +3519,8 @@ compute_stop_pos (struct it *it)
        {
          for (p = it_props; p->handler; ++p)
            {
-             Lisp_Object new_value;
-
-             new_value = textget (next_iv->plist, *p->name);
+             Lisp_Object new_value = textget (next_iv->plist,
+                                              builtin_lisp_symbol (p->name));
              if (!EQ (values_here[p->idx], new_value))
                break;
            }
@@ -3684,6 +3568,7 @@ next_overlay_change (ptrdiff_t pos)
   ptrdiff_t i, noverlays;
   ptrdiff_t endpos;
   Lisp_Object *overlays;
+  USE_SAFE_ALLOCA;
 
   /* Get all overlays at the given position.  */
   GET_OVERLAYS_AT (pos, overlays, noverlays, &endpos, 1);
@@ -3700,6 +3585,7 @@ next_overlay_change (ptrdiff_t pos)
       endpos = min (endpos, oendpos);
     }
 
+  SAFE_FREE ();
   return endpos;
 }
 
@@ -3991,7 +3877,7 @@ handle_face_prop (struct it *it)
                                   &next_stop,
                                   (IT_CHARPOS (*it)
                                    + TEXT_PROP_DISTANCE_LIMIT),
-                                  0, it->base_face_id);
+                                  false, it->base_face_id);
 
       /* Is this a start of a run of characters with box face?
         Caveat: this can be called for a freshly initialized
@@ -4067,7 +3953,7 @@ handle_face_prop (struct it *it)
                                       &next_stop,
                                       (IT_CHARPOS (*it)
                                        + TEXT_PROP_DISTANCE_LIMIT),
-                                      0,
+                                      false,
                                       from_overlay);
        }
       else
@@ -4102,7 +3988,7 @@ handle_face_prop (struct it *it)
                                             IT_STRING_CHARPOS (*it),
                                             bufpos,
                                             &next_stop,
-                                            base_face_id, 0);
+                                            base_face_id, false);
 
       /* Is this a start of a run of characters with box?  Caveat:
         this can be called for a freshly allocated iterator; face_id
@@ -4244,7 +4130,7 @@ face_before_or_after_it_pos (struct it *it, int before_p)
                                         charpos,
                                         bufpos,
                                         &next_check_charpos,
-                                        base_face_id, 0);
+                                        base_face_id, false);
 
       /* Correct the face for charsets different from ASCII.  Do it
         for the multibyte case only.  The face returned above is
@@ -4333,7 +4219,7 @@ face_before_or_after_it_pos (struct it *it, int before_p)
       face_id = face_at_buffer_position (it->w,
                                         CHARPOS (pos),
                                         &next_check_charpos,
-                                        limit, 0, -1);
+                                        limit, false, -1);
 
       /* Correct the face for charsets different from ASCII.  Do it
         for the multibyte case only.  The face returned above is
@@ -5153,7 +5039,7 @@ handle_single_display_spec (struct it *it, Lisp_Object spec, Lisp_Object object,
 
       if (it)
        {
-         int face_id = lookup_basic_face (it->f, DEFAULT_FACE_ID);;
+         int face_id = lookup_basic_face (it->f, DEFAULT_FACE_ID);
 
          if (CONSP (XCDR (XCDR (spec))))
            {
@@ -5768,10 +5654,11 @@ load_overlay_strings (struct it *it, ptrdiff_t charpos)
   Lisp_Object overlay, window, str, invisible;
   struct Lisp_Overlay *ov;
   ptrdiff_t start, end;
-  ptrdiff_t size = 20;
   ptrdiff_t n = 0, i, j;
   int invis_p;
-  struct overlay_entry *entries = alloca (size * sizeof *entries);
+  struct overlay_entry entriesbuf[20];
+  ptrdiff_t size = ARRAYELTS (entriesbuf);
+  struct overlay_entry *entries = entriesbuf;
   USE_SAFE_ALLOCA;
 
   if (charpos <= 0)
@@ -6954,7 +6841,8 @@ get_next_display_element (struct it *it)
         is R..."  */
       /* FIXME: Do we need an exception for characters from display
         tables?  */
-      if (it->bidi_p && it->bidi_it.type == STRONG_R)
+      if (it->bidi_p && it->bidi_it.type == STRONG_R
+         && !inhibit_bidi_mirroring)
        it->c = bidi_mirror_char (it->c);
       /* Map via display table or translate control characters.
         IT->c, IT->len etc. have been set to the next character by
@@ -7277,7 +7165,7 @@ get_next_display_element (struct it *it)
                    {
                      next_face_id = face_at_buffer_position
                        (it->w, CHARPOS (pos), &ignore,
-                        CHARPOS (pos) + TEXT_PROP_DISTANCE_LIMIT, 0, -1);
+                        CHARPOS (pos) + TEXT_PROP_DISTANCE_LIMIT, false, -1);
                      it->end_of_box_run_p
                        = (FACE_FROM_ID (it->f, next_face_id)->box
                           == FACE_NO_BOX);
@@ -8036,7 +7924,7 @@ next_element_from_c_string (struct it *it)
   eassert (!it->bidi_p || it->s == it->bidi_it.string.s);
   it->what = IT_CHARACTER;
   BYTEPOS (it->position) = CHARPOS (it->position) = 0;
-  it->object = Qnil;
+  it->object = make_number (0);
 
   /* With bidi reordering, the character to display might not be the
      character at IT_CHARPOS.  BIDI_IT.FIRST_ELT non-zero means that
@@ -8348,7 +8236,7 @@ next_element_from_buffer (struct it *it)
 
       /* Get the next character, maybe multibyte.  */
       p = BYTE_POS_ADDR (IT_BYTEPOS (*it));
-      if (it->multibyte_p && !ASCII_BYTE_P (*p))
+      if (it->multibyte_p && !ASCII_CHAR_P (*p))
        it->c = STRING_CHAR_AND_LENGTH (p, it->len);
       else
        it->c = *p, it->len = 1;
@@ -8398,22 +8286,18 @@ next_element_from_buffer (struct it *it)
 static void
 run_redisplay_end_trigger_hook (struct it *it)
 {
-  Lisp_Object args[3];
-
   /* IT->glyph_row should be non-null, i.e. we should be actually
      displaying something, or otherwise we should not run the hook.  */
   eassert (it->glyph_row);
 
-  /* Set up hook arguments.  */
-  args[0] = Qredisplay_end_trigger_functions;
-  args[1] = it->window;
-  XSETINT (args[2], it->redisplay_end_trigger_charpos);
+  ptrdiff_t charpos = it->redisplay_end_trigger_charpos;
   it->redisplay_end_trigger_charpos = 0;
 
   /* Since we are *trying* to run these functions, don't try to run
      them again, even if they get an error.  */
   wset_redisplay_end_trigger (it->w, Qnil);
-  Frun_hook_with_args (3, args);
+  CALLN (Frun_hook_with_args, Qredisplay_end_trigger_functions, it->window,
+        make_number (charpos));
 
   /* Notice if it changed the face of the character we are on.  */
   handle_face_prop (it);
@@ -9913,7 +9797,6 @@ include the height of both, if present, in the return value.  */)
 void
 add_to_log (const char *format, Lisp_Object arg1, Lisp_Object arg2)
 {
-  Lisp_Object args[3];
   Lisp_Object msg, fmt;
   char *buffer;
   ptrdiff_t len;
@@ -9923,10 +9806,8 @@ add_to_log (const char *format, Lisp_Object arg1, Lisp_Object arg2)
   fmt = msg = Qnil;
   GCPRO4 (fmt, msg, arg1, arg2);
 
-  args[0] = fmt = build_string (format);
-  args[1] = arg1;
-  args[2] = arg2;
-  msg = Fformat (3, args);
+  fmt = build_string (format);
+  msg = CALLN (Fformat, fmt, arg1, arg2);
 
   len = SBYTES (msg) + 1;
   buffer = SAFE_ALLOCA (len);
@@ -10028,9 +9909,7 @@ message_dolog (const char *m, ptrdiff_t nbytes, bool nlflag, bool multibyte)
          for (i = 0; i < nbytes; i += char_bytes)
            {
              c = string_char_and_length (msg + i, &char_bytes);
-             work[0] = (ASCII_CHAR_P (c)
-                        ? c
-                        : multibyte_char_to_unibyte (c));
+             work[0] = CHAR_TO_BYTE8 (c);
              insert_1_both (work, 1, 1, 1, 0, 0);
            }
        }
@@ -10205,9 +10084,9 @@ message3 (Lisp_Object m)
     {
       ptrdiff_t nbytes = SBYTES (m);
       bool multibyte = STRING_MULTIBYTE (m);
+      char *buffer;
       USE_SAFE_ALLOCA;
-      char *buffer = SAFE_ALLOCA (nbytes);
-      memcpy (buffer, SDATA (m), nbytes);
+      SAFE_ALLOCA_STRING (buffer, m);
       message_dolog (buffer, nbytes, 1, multibyte);
       SAFE_FREE ();
     }
@@ -10268,9 +10147,9 @@ message3_nolog (Lisp_Object m)
       else
        clear_message (true, true);
 
-      do_pending_window_change (0);
-      echo_area_display (1);
-      do_pending_window_change (0);
+      do_pending_window_change (false);
+      echo_area_display (true);
+      do_pending_window_change (false);
       if (FRAME_TERMINAL (f)->frame_up_to_date_hook)
        (*FRAME_TERMINAL (f)->frame_up_to_date_hook) (f);
     }
@@ -10312,19 +10191,17 @@ message_with_string (const char *m, Lisp_Object string, int log)
     {
       if (m)
        {
-         /* ENCODE_SYSTEM below can GC and/or relocate the Lisp
-            String whose data pointer might be passed to us in M.  So
-            we use a local copy.  */
-         char *fmt = xstrdup (m);
+         /* ENCODE_SYSTEM below can GC and/or relocate the
+            Lisp data, so make sure we don't use it here.  */
+         eassert (relocatable_string_data_p (m) != 1);
 
          if (noninteractive_need_newline)
            putc ('\n', stderr);
          noninteractive_need_newline = 0;
-         fprintf (stderr, fmt, SDATA (ENCODE_SYSTEM (string)));
+         fprintf (stderr, m, SDATA (ENCODE_SYSTEM (string)));
          if (!cursor_in_echo_area)
            fprintf (stderr, "\n");
          fflush (stderr);
-         xfree (fmt);
        }
     }
   else if (INTERACTIVE)
@@ -10345,15 +10222,13 @@ message_with_string (const char *m, Lisp_Object string, int log)
         initialized yet, just toss it.  */
       if (f->glyphs_initialized_p)
        {
-         Lisp_Object args[2], msg;
          struct gcpro gcpro1, gcpro2;
 
-         args[0] = build_string (m);
-         args[1] = msg = string;
-         GCPRO2 (args[0], msg);
-         gcpro1.nvars = 2;
+         Lisp_Object fmt = build_string (m);
+         Lisp_Object msg = string;
+         GCPRO2 (fmt, msg);
 
-         msg = Fformat (2, args);
+         msg = CALLN (Fformat, fmt, msg);
 
          if (log)
            message3 (msg);
@@ -10411,11 +10286,13 @@ vmessage (const char *m, va_list ap)
            {
              ptrdiff_t len;
              ptrdiff_t maxsize = FRAME_MESSAGE_BUF_SIZE (f);
-             char *message_buf = alloca (maxsize + 1);
+             USE_SAFE_ALLOCA;
+             char *message_buf = SAFE_ALLOCA (maxsize + 1);
 
              len = doprnt (message_buf, maxsize, m, 0, ap);
 
              message3 (make_string (message_buf, len));
+             SAFE_FREE ();
            }
          else
            message1 (0);
@@ -10581,6 +10458,7 @@ with_echo_area_buffer (struct window *w, int which,
     {
       wset_buffer (w, buffer);
       set_marker_both (w->pointm, buffer, BEG, BEG_BYTE);
+      set_marker_both (w->old_pointm, buffer, BEG, BEG_BYTE);
     }
 
   bset_undo_list (current_buffer, Qt);
@@ -10619,7 +10497,7 @@ with_echo_area_buffer_unwind_data (struct window *w)
   Vwith_echo_area_save_vector = Qnil;
 
   if (NILP (vector))
-    vector = Fmake_vector (make_number (9), Qnil);
+    vector = Fmake_vector (make_number (11), Qnil);
 
   XSETBUFFER (tmp, current_buffer); ASET (vector, i, tmp); ++i;
   ASET (vector, i, Vdeactivate_mark); ++i;
@@ -10631,12 +10509,14 @@ with_echo_area_buffer_unwind_data (struct window *w)
       ASET (vector, i, w->contents); ++i;
       ASET (vector, i, make_number (marker_position (w->pointm))); ++i;
       ASET (vector, i, make_number (marker_byte_position (w->pointm))); ++i;
+      ASET (vector, i, make_number (marker_position (w->old_pointm))); ++i;
+      ASET (vector, i, make_number (marker_byte_position (w->old_pointm))); ++i;
       ASET (vector, i, make_number (marker_position (w->start))); ++i;
       ASET (vector, i, make_number (marker_byte_position (w->start))); ++i;
     }
   else
     {
-      int end = i + 6;
+      int end = i + 8;
       for (; i < end; ++i)
        ASET (vector, i, Qnil);
     }
@@ -10668,9 +10548,12 @@ unwind_with_echo_area_buffer (Lisp_Object vector)
       set_marker_both (w->pointm, buffer,
                       XFASTINT (AREF (vector, 5)),
                       XFASTINT (AREF (vector, 6)));
-      set_marker_both (w->start, buffer,
+      set_marker_both (w->old_pointm, buffer,
                       XFASTINT (AREF (vector, 7)),
                       XFASTINT (AREF (vector, 8)));
+      set_marker_both (w->start, buffer,
+                      XFASTINT (AREF (vector, 9)),
+                      XFASTINT (AREF (vector, 10)));
     }
 
   Vwith_echo_area_save_vector = vector;
@@ -11235,13 +11118,13 @@ clear_garbaged_frames (void)
    is non-zero update selected_frame.  Value is non-zero if the
    mini-windows height has been changed.  */
 
-static int
-echo_area_display (int update_frame_p)
+static bool
+echo_area_display (bool update_frame_p)
 {
   Lisp_Object mini_window;
   struct window *w;
   struct frame *f;
-  int window_height_changed_p = 0;
+  bool window_height_changed_p = false;
   struct frame *sf = SELECTED_FRAME ();
 
   mini_window = FRAME_MINIBUF_WINDOW (sf);
@@ -11304,11 +11187,11 @@ echo_area_display (int update_frame_p)
              /* Window configuration is the same as before.
                 Can do with a display update of the echo area,
                 unless we displayed some mode lines.  */
-             update_single_window (w, 1);
+             update_single_window (w);
              flush_frame (f);
            }
          else
-           update_frame (f, 1, 1);
+           update_frame (f, true, true);
 
          /* If cursor is in the echo area, make sure that the next
             redisplay displays the minibuffer, so that the cursor will
@@ -11913,11 +11796,6 @@ update_menu_bar (struct frame *f, int save_match_data, int hooks_run)
 
 #ifdef HAVE_WINDOW_SYSTEM
 
-/* Tool-bar item index of the item on which a mouse button was pressed
-   or -1.  */
-
-int last_tool_bar_item;
-
 /* Select `frame' temporarily without running all the code in
    do_switch_frame.
    FIXME: Maybe do_switch_frame should be trimmed down similarly
@@ -11944,7 +11822,7 @@ update_tool_bar (struct frame *f, int save_match_data)
   int do_update = FRAME_EXTERNAL_TOOL_BAR (f);
 #else
   int do_update = (WINDOWP (f->tool_bar_window)
-                  && WINDOW_PIXEL_HEIGHT (XWINDOW (f->tool_bar_window)) > 0);
+                  && WINDOW_TOTAL_LINES (XWINDOW (f->tool_bar_window)) > 0);
 #endif
 
   if (do_update)
@@ -12040,11 +11918,11 @@ static void
 build_desired_tool_bar_string (struct frame *f)
 {
   int i, size, size_needed;
-  struct gcpro gcpro1, gcpro2, gcpro3;
-  Lisp_Object image, plist, props;
+  struct gcpro gcpro1, gcpro2;
+  Lisp_Object image, plist;
 
-  image = plist = props = Qnil;
-  GCPRO3 (image, plist, props);
+  image = plist = Qnil;
+  GCPRO2 (image, plist);
 
   /* Prepare F->desired_tool_bar_string.  If we can reuse it, do so.
      Otherwise, make a new string.  */
@@ -12063,9 +11941,12 @@ build_desired_tool_bar_string (struct frame *f)
       (f, Fmake_string (make_number (size_needed), make_number (' ')));
   else
     {
-      props = list4 (Qdisplay, Qnil, Qmenu_item, Qnil);
+      AUTO_LIST4 (props, Qdisplay, Qnil, Qmenu_item, Qnil);
+      struct gcpro gcpro1;
+      GCPRO1 (props);
       Fremove_text_properties (make_number (0), make_number (size),
                               props, f->desired_tool_bar_string);
+      UNGCPRO;
     }
 
   /* Put a `display' property on the string for the images to display,
@@ -12176,8 +12057,10 @@ build_desired_tool_bar_string (struct frame *f)
         the start of this item's properties in the tool-bar items
         vector.  */
       image = Fcons (Qimage, plist);
-      props = list4 (Qdisplay, image,
-                    Qmenu_item, make_number (i * TOOL_BAR_ITEM_NSLOTS));
+      AUTO_LIST4 (props, Qdisplay, image, Qmenu_item,
+                 make_number (i * TOOL_BAR_ITEM_NSLOTS));
+      struct gcpro gcpro1;
+      GCPRO1 (props);
 
       /* Let the last image hide all remaining spaces in the tool bar
          string.  The string can be longer than needed when we reuse a
@@ -12188,6 +12071,7 @@ build_desired_tool_bar_string (struct frame *f)
        end = i + 1;
       Fadd_text_properties (make_number (i), make_number (end),
                            props, f->desired_tool_bar_string);
+      UNGCPRO;
 #undef PROP
     }
 
@@ -12328,16 +12212,9 @@ display_tool_bar_line (struct it *it, int height)
 }
 
 
-/* Max tool-bar height.  Basically, this is what makes all other windows
-   disappear when the frame gets too small.  Rethink this!  */
-
-#define MAX_FRAME_TOOL_BAR_HEIGHT(f) \
-  ((FRAME_LINE_HEIGHT (f) * FRAME_LINES (f)))
-
 /* Value is the number of pixels needed to make all tool-bar items of
    frame F visible.  The actual number of glyph rows needed is
    returned in *N_ROWS if non-NULL.  */
-
 static int
 tool_bar_height (struct frame *f, int *n_rows, bool pixelwise)
 {
@@ -12351,6 +12228,7 @@ tool_bar_height (struct frame *f, int *n_rows, bool pixelwise)
   /* Initialize an iterator for iteration over
      F->desired_tool_bar_string in the tool-bar window of frame F.  */
   init_iterator (&it, w, -1, -1, temp_row, TOOL_BAR_FACE_ID);
+  temp_row->reversed_p = false;
   it.first_visible_x = 0;
   it.last_visible_x = WINDOW_PIXEL_WIDTH (w);
   reseat_to_string (&it, NULL, f->desired_tool_bar_string, 0, 0, 0, -1);
@@ -12376,11 +12254,6 @@ tool_bar_height (struct frame *f, int *n_rows, bool pixelwise)
 
 #endif /* !USE_GTK && !HAVE_NS */
 
-#if defined USE_GTK || defined HAVE_NS
-EXFUN (Ftool_bar_height, 2) ATTRIBUTE_CONST;
-EXFUN (Ftool_bar_lines_needed, 1) ATTRIBUTE_CONST;
-#endif
-
 DEFUN ("tool-bar-height", Ftool_bar_height, Stool_bar_height,
        0, 2, 0,
        doc: /* Return the number of lines occupied by the tool bar of FRAME.
@@ -12411,7 +12284,6 @@ PIXELWISE non-nil means return the height of the tool bar in pixels.  */)
 
 /* Display the tool-bar of frame F.  Value is non-zero if tool-bar's
    height should be changed.  */
-
 static int
 redisplay_tool_bar (struct frame *f)
 {
@@ -12433,7 +12305,7 @@ redisplay_tool_bar (struct frame *f)
      can turn off tool-bars by specifying tool-bar-lines zero.  */
   if (!WINDOWP (f->tool_bar_window)
       || (w = XWINDOW (f->tool_bar_window),
-          WINDOW_PIXEL_HEIGHT (w) == 0))
+          WINDOW_TOTAL_LINES (w) == 0))
     return 0;
 
   /* Set up an iterator for the tool-bar window.  */
@@ -12441,6 +12313,7 @@ redisplay_tool_bar (struct frame *f)
   it.first_visible_x = 0;
   it.last_visible_x = WINDOW_PIXEL_WIDTH (w);
   row = it.glyph_row;
+  row->reversed_p = false;
 
   /* Build a string that represents the contents of the tool-bar.  */
   build_desired_tool_bar_string (f);
@@ -12460,14 +12333,8 @@ redisplay_tool_bar (struct frame *f)
 
       if (new_height != WINDOW_PIXEL_HEIGHT (w))
        {
-         Lisp_Object frame;
-         int new_lines = ((new_height + FRAME_LINE_HEIGHT (f) - 1)
-                          / FRAME_LINE_HEIGHT (f));
-
-         XSETFRAME (frame, f);
-         Fmodify_frame_parameters (frame,
-                                   list1 (Fcons (Qtool_bar_lines,
-                                                 make_number (new_lines))));
+         x_change_tool_bar_height (f, new_height);
+         frame_default_tool_bar_height = new_height;
          /* Always do that now.  */
          clear_glyph_matrix (w->desired_matrix);
          f->fonts_changed = 1;
@@ -12520,14 +12387,11 @@ redisplay_tool_bar (struct frame *f)
 
   if (!NILP (Vauto_resize_tool_bars))
     {
-      /* Do we really allow the toolbar to occupy the whole frame?  */
-      int max_tool_bar_height = MAX_FRAME_TOOL_BAR_HEIGHT (f);
       int change_height_p = 0;
 
       /* If we couldn't display everything, change the tool-bar's
         height if there is room for more.  */
-      if (IT_STRING_CHARPOS (it) < it.end_charpos
-         && it.current_y < max_tool_bar_height)
+      if (IT_STRING_CHARPOS (it) < it.end_charpos)
        change_height_p = 1;
 
       /* We subtract 1 because display_tool_bar_line advances the
@@ -12546,15 +12410,13 @@ redisplay_tool_bar (struct frame *f)
       /* If row displays tool-bar items, but is partially visible,
         change the tool-bar's height.  */
       if (MATRIX_ROW_DISPLAYS_TEXT_P (row)
-         && MATRIX_ROW_BOTTOM_Y (row) > it.last_visible_y
-         && MATRIX_ROW_BOTTOM_Y (row) < max_tool_bar_height)
+         && MATRIX_ROW_BOTTOM_Y (row) > it.last_visible_y)
        change_height_p = 1;
 
       /* Resize windows as needed by changing the `tool-bar-lines'
         frame parameter.  */
       if (change_height_p)
        {
-         Lisp_Object frame;
          int nrows;
          int new_height = tool_bar_height (f, &nrows, 1);
 
@@ -12566,35 +12428,13 @@ redisplay_tool_bar (struct frame *f)
 
          if (change_height_p)
            {
-             /* Current size of the tool-bar window in canonical line
-                units.  */
-             int old_lines = WINDOW_TOTAL_LINES (w);
-             /* Required size of the tool-bar window in canonical
-                line units. */
-             int new_lines = ((new_height + FRAME_LINE_HEIGHT (f) - 1)
-                              / FRAME_LINE_HEIGHT (f));
-             /* Maximum size of the tool-bar window in canonical line
-                units that this frame can allow. */
-             int max_lines =
-               WINDOW_TOTAL_LINES (XWINDOW (FRAME_ROOT_WINDOW (f))) - 1;
-
-             /* Don't try to change the tool-bar window size and set
-                the fonts_changed flag unless really necessary.  That
-                flag causes redisplay to give up and retry
-                redisplaying the frame from scratch, so setting it
-                unnecessarily can lead to nasty redisplay loops.  */
-             if (new_lines <= max_lines
-                 && eabs (new_lines - old_lines) >= 1)
-               {
-                 XSETFRAME (frame, f);
-                 Fmodify_frame_parameters (frame,
-                                           list1 (Fcons (Qtool_bar_lines,
-                                                         make_number (new_lines))));
-                 clear_glyph_matrix (w->desired_matrix);
-                 f->n_tool_bar_rows = nrows;
-                 f->fonts_changed = 1;
-                 return 1;
-               }
+             x_change_tool_bar_height (f, new_height);
+             frame_default_tool_bar_height = new_height;
+             clear_glyph_matrix (w->desired_matrix);
+             f->n_tool_bar_rows = nrows;
+             f->fonts_changed = 1;
+
+             return 1;
            }
        }
     }
@@ -12719,7 +12559,7 @@ handle_tool_bar_click (struct frame *f, int x, int y, int down_p,
      where the button was pressed, disregarding where it was
      released.  */
   if (NILP (Vmouse_highlight) && !down_p)
-    prop_idx = last_tool_bar_item;
+    prop_idx = f->last_tool_bar_item;
 
   /* If item is disabled, do nothing.  */
   enabled_p = AREF (f->tool_bar_items, prop_idx + TOOL_BAR_ITEM_ENABLED_P);
@@ -12731,7 +12571,7 @@ handle_tool_bar_click (struct frame *f, int x, int y, int down_p,
       /* Show item in pressed state.  */
       if (!NILP (Vmouse_highlight))
        show_mouse_face (hlinfo, DRAW_IMAGE_SUNKEN);
-      last_tool_bar_item = prop_idx;
+      f->last_tool_bar_item = prop_idx;
     }
   else
     {
@@ -12756,7 +12596,7 @@ handle_tool_bar_click (struct frame *f, int x, int y, int down_p,
       event.arg = key;
       event.modifiers = modifiers;
       kbd_buffer_store_event (&event);
-      last_tool_bar_item = -1;
+      f->last_tool_bar_item = -1;
     }
 }
 
@@ -12806,8 +12646,7 @@ note_tool_bar_highlight (struct frame *f, int x, int y)
   mouse_down_p = (x_mouse_grabbed (dpyinfo)
                  && f == dpyinfo->last_mouse_frame);
 
-  if (mouse_down_p
-      && last_tool_bar_item != prop_idx)
+  if (mouse_down_p && f->last_tool_bar_item != prop_idx)
     return;
 
   draw = mouse_down_p ? DRAW_IMAGE_SUNKEN : DRAW_IMAGE_RAISED;
@@ -12929,7 +12768,20 @@ hscroll_window_tree (Lisp_Object window)
          /* Scroll when cursor is inside this scroll margin.  */
          h_margin = hscroll_margin * WINDOW_FRAME_COLUMN_WIDTH (w);
 
+         /* If the position of this window's point has explicitly
+            changed, no more suspend auto hscrolling.  */
+         if (NILP (Fequal (Fwindow_point (window), Fwindow_old_point (window))))
+           w->suspend_auto_hscroll = 0;
+
+         /* Remember window point.  */
+         Fset_marker (w->old_pointm,
+                      ((w == XWINDOW (selected_window))
+                       ? make_number (BUF_PT (XBUFFER (w->contents)))
+                       : Fmarker_position (w->pointm)),
+                      w->contents);
+
          if (!NILP (Fbuffer_local_value (Qauto_hscroll_mode, w->contents))
+             && w->suspend_auto_hscroll == 0
              /* In some pathological cases, like restoring a window
                 configuration into a frame that is much smaller than
                 the one from which the configuration was saved, we
@@ -12942,8 +12794,7 @@ hscroll_window_tree (Lisp_Object window)
                 inside the left margin and the window is already
                 hscrolled.  */
              && ((!row_r2l_p
-                  && ((w->hscroll
-                       && w->cursor.x <= h_margin)
+                  && ((w->hscroll && w->cursor.x <= h_margin)
                       || (cursor_row->enabled_p
                           && cursor_row->truncated_on_right_p
                           && (w->cursor.x >= text_area_width - h_margin))))
@@ -13456,7 +13307,7 @@ redisplay_internal (void)
   struct window *w = XWINDOW (selected_window);
   struct window *sw;
   struct frame *fr;
-  int pending;
+  bool pending;
   bool must_finish = 0, match_p;
   struct text_pos tlbufpos, tlendpos;
   int number_of_visible_frames;
@@ -13507,7 +13358,7 @@ redisplay_internal (void)
   specbind (Qinhibit_free_realized_faces, Qnil);
 
   /* Record this function, so it appears on the profiler's backtraces.  */
-  record_in_backtrace (Qredisplay_internal, &Qnil, 0);
+  record_in_backtrace (Qredisplay_internal, 0, 0);
 
   FOR_EACH_FRAME (tail, frame)
     XFRAME (frame)->already_hscrolled_p = 0;
@@ -13516,7 +13367,7 @@ redisplay_internal (void)
   /* Remember the currently selected window.  */
   sw = w;
 
-  pending = 0;
+  pending = false;
   last_escape_glyph_frame = NULL;
   last_escape_glyph_face_id = (1 << FACE_ID_BITS);
   last_glyphless_glyph_frame = NULL;
@@ -13568,7 +13419,7 @@ redisplay_internal (void)
     }
 
   /* Notice any pending interrupt request to change frame size.  */
-  do_pending_window_change (1);
+  do_pending_window_change (true);
 
   /* do_pending_window_change could change the selected_window due to
      frame resizing which makes the selected window too small.  */
@@ -13615,7 +13466,7 @@ redisplay_internal (void)
             echo-area doesn't show through.  */
          && !MINI_WINDOW_P (XWINDOW (selected_window))))
     {
-      int window_height_changed_p = echo_area_display (0);
+      int window_height_changed_p = echo_area_display (false);
 
       if (message_cleared_p)
        update_miniwindow_p = true;
@@ -13823,7 +13674,7 @@ redisplay_internal (void)
        {
          if (!must_finish)
            {
-             do_pending_window_change (1);
+             do_pending_window_change (true);
              /* If selected_window changed, redisplay again.  */
              if (WINDOWP (selected_window)
                  && (w = XWINDOW (selected_window)) != sw)
@@ -13908,6 +13759,17 @@ redisplay_internal (void)
 
        retry_frame:
 
+#if defined (HAVE_WINDOW_SYSTEM) && !defined (USE_GTK) && !defined (HAVE_NS)
+         /* Redisplay internal tool bar if this is the first time so we
+            can adjust the frame height right now, if necessary.  */
+         if (!f->tool_bar_redisplayed_once)
+           {
+             if (redisplay_tool_bar (f))
+               adjust_frame_glyphs (f);
+             f->tool_bar_redisplayed_once = true;
+           }
+#endif
+
          if (FRAME_WINDOW_P (f) || FRAME_TERMCAP_P (f) || f == sf)
            {
              bool gcscrollbars
@@ -13940,14 +13802,14 @@ redisplay_internal (void)
                  if (f->fonts_changed)
                    {
                      adjust_frame_glyphs (f);
-                     f->fonts_changed = 0;
+                     f->fonts_changed = false;
                      goto retry_frame;
                    }
 
                  /* See if we have to hscroll.  */
                  if (!f->already_hscrolled_p)
                    {
-                     f->already_hscrolled_p = 1;
+                     f->already_hscrolled_p = true;
                      if (hscroll_windows (f->root_window))
                        goto retry_frame;
                    }
@@ -13959,9 +13821,9 @@ redisplay_internal (void)
                    unrequest_sigio ();
                  STOP_POLLING;
 
-                 pending |= update_frame (f, 0, 0);
-                 f->cursor_type_changed = 0;
-                 f->updated_p = 1;
+                 pending |= update_frame (f, false, false);
+                 f->cursor_type_changed = false;
+                 f->updated_p = true;
                }
            }
        }
@@ -14022,8 +13884,8 @@ redisplay_internal (void)
            goto retry;
 
          XWINDOW (selected_window)->must_be_updated_p = true;
-         pending = update_frame (sf, 0, 0);
-         sf->cursor_type_changed = 0;
+         pending = update_frame (sf, false, false);
+         sf->cursor_type_changed = false;
        }
 
       /* We may have called echo_area_display at the top of this
@@ -14037,8 +13899,8 @@ redisplay_internal (void)
       if (mini_frame != sf && FRAME_WINDOW_P (mini_frame))
        {
          XWINDOW (mini_window)->must_be_updated_p = true;
-         pending |= update_frame (mini_frame, 0, 0);
-         mini_frame->cursor_type_changed = 0;
+         pending |= update_frame (mini_frame, false, false);
+         mini_frame->cursor_type_changed = false;
          if (!pending && hscroll_windows (mini_window))
            goto retry;
        }
@@ -14115,7 +13977,7 @@ redisplay_internal (void)
     }
 
   /* Change frame size now if a change is pending.  */
-  do_pending_window_change (1);
+  do_pending_window_change (true);
 
   /* If we just did a pending size change, or have additional
      visible frames, or selected_window changed, redisplay again.  */
@@ -14131,7 +13993,7 @@ redisplay_internal (void)
 
   if (clear_face_cache_count > CLEAR_FACE_CACHE_COUNT)
     {
-      clear_face_cache (0);
+      clear_face_cache (false);
       clear_face_cache_count = 0;
     }
 
@@ -14175,9 +14037,9 @@ redisplay_preserve_echo_area (int from_where)
     {
       /* We have a previously displayed message, but no current
         message.  Redisplay the previous message.  */
-      display_last_displayed_message_p = 1;
+      display_last_displayed_message_p = true;
       redisplay_internal ();
-      display_last_displayed_message_p = 0;
+      display_last_displayed_message_p = false;
     }
   else
     redisplay_internal ();
@@ -14414,14 +14276,14 @@ set_cursor_from_row (struct window *w, struct glyph_row *row,
       if (!row->reversed_p)
        {
          while (glyph < end
-                && INTEGERP (glyph->object)
+                && NILP (glyph->object)
                 && glyph->charpos < 0)
            {
              x += glyph->pixel_width;
              ++glyph;
            }
          while (end > glyph
-                && INTEGERP ((end - 1)->object)
+                && NILP ((end - 1)->object)
                 /* CHARPOS is zero for blanks and stretch glyphs
                    inserted by extend_face_to_end_of_line.  */
                 && (end - 1)->charpos <= 0)
@@ -14439,20 +14301,20 @@ set_cursor_from_row (struct window *w, struct glyph_row *row,
          glyph += row->used[TEXT_AREA] - 1;
 
          while (glyph > end + 1
-                && INTEGERP (glyph->object)
+                && NILP (glyph->object)
                 && glyph->charpos < 0)
            {
              --glyph;
              x -= glyph->pixel_width;
            }
-         if (INTEGERP (glyph->object) && glyph->charpos < 0)
+         if (NILP (glyph->object) && glyph->charpos < 0)
            --glyph;
          /* By default, in reversed rows we put the cursor on the
             rightmost (first in the reading order) glyph.  */
          for (g = end + 1; g < glyph; g++)
            x += g->pixel_width;
          while (end < glyph
-                && INTEGERP ((end + 1)->object)
+                && NILP ((end + 1)->object)
                 && (end + 1)->charpos <= 0)
            ++end;
          glyph_before = glyph + 1;
@@ -14483,7 +14345,7 @@ set_cursor_from_row (struct window *w, struct glyph_row *row,
     while (/* not marched to end of glyph row */
           glyph < end
           /* glyph was not inserted by redisplay for internal purposes */
-          && !INTEGERP (glyph->object))
+          && !NILP (glyph->object))
       {
        if (BUFFERP (glyph->object))
          {
@@ -14571,7 +14433,7 @@ set_cursor_from_row (struct window *w, struct glyph_row *row,
        ++glyph;
       }
   else if (glyph > end)        /* row is reversed */
-    while (!INTEGERP (glyph->object))
+    while (!NILP (glyph->object))
       {
        if (BUFFERP (glyph->object))
          {
@@ -14648,16 +14510,16 @@ set_cursor_from_row (struct window *w, struct glyph_row *row,
        && BUFFERP (glyph->object) && glyph->charpos == pt_old)
       && !(bpos_max <= pt_old && pt_old <= bpos_covered))
     {
-      /* An empty line has a single glyph whose OBJECT is zero and
+      /* An empty line has a single glyph whose OBJECT is nil and
         whose CHARPOS is the position of a newline on that line.
         Note that on a TTY, there are more glyphs after that, which
         were produced by extend_face_to_end_of_line, but their
         CHARPOS is zero or negative.  */
       int empty_line_p =
        (row->reversed_p ? glyph > glyphs_end : glyph < glyphs_end)
-       && INTEGERP (glyph->object) && glyph->charpos > 0
+       && NILP (glyph->object) && glyph->charpos > 0
        /* On a TTY, continued and truncated rows also have a glyph at
-          their end whose OBJECT is zero and whose CHARPOS is
+          their end whose OBJECT is nil and whose CHARPOS is
           positive (the continuation and truncation glyphs), but such
           rows are obviously not "empty".  */
        && !(row->continued_p || row->truncated_on_right_p);
@@ -14934,7 +14796,7 @@ set_cursor_from_row (struct window *w, struct glyph_row *row,
                          && string_from_text_prop)
                      /* this candidate is from newline and its
                         position is not an exact match */
-                     || (INTEGERP (glyph->object)
+                     || (NILP (glyph->object)
                          && glyph->charpos != pt_old)))))
        return 0;
       /* If this candidate gives an exact match, use that.  */
@@ -14943,7 +14805,7 @@ set_cursor_from_row (struct window *w, struct glyph_row *row,
               terminating newline of a line, and point is on that
               newline, it wins because it's an exact match.  */
            || (!row->continued_p
-               && INTEGERP (glyph->object)
+               && NILP (glyph->object)
                && glyph->charpos == 0
                && pt_old == MATRIX_ROW_END_CHARPOS (row) - 1))
          /* Otherwise, keep the candidate that comes from a row
@@ -15225,8 +15087,8 @@ try_scrolling (Lisp_Object window, int just_this_one_p,
                 non-zero margins, because scroll_up_aggressively
                 means put point that fraction of window height
                 _from_the_bottom_margin_.  */
-             if (aggressive_scroll + 2*this_scroll_margin > height)
-               aggressive_scroll = height - 2*this_scroll_margin;
+             if (aggressive_scroll + 2 * this_scroll_margin > height)
+               aggressive_scroll = height - 2 * this_scroll_margin;
              amount_to_scroll = dy + aggressive_scroll;
            }
        }
@@ -15319,8 +15181,8 @@ try_scrolling (Lisp_Object window, int just_this_one_p,
          start_display (&it, w, startp);
 
          if (arg_scroll_conservatively)
-           amount_to_scroll = max (dy, frame_line_height *
-                                   max (scroll_step, temp_scroll_step));
+           amount_to_scroll = max (dy, frame_line_height
+                                   max (scroll_step, temp_scroll_step));
          else if (scroll_step || temp_scroll_step)
            amount_to_scroll = scroll_max;
          else
@@ -15337,8 +15199,8 @@ try_scrolling (Lisp_Object window, int just_this_one_p,
                     bottom of the window, if the value of
                     scroll_down_aggressively happens to be too
                     large.  */
-                 if (aggressive_scroll + 2*this_scroll_margin > height)
-                   aggressive_scroll = height - 2*this_scroll_margin;
+                 if (aggressive_scroll + 2 * this_scroll_margin > height)
+                   aggressive_scroll = height - 2 * this_scroll_margin;
                  amount_to_scroll = dy + aggressive_scroll;
                }
            }
@@ -15787,7 +15649,7 @@ try_cursor_movement (Lisp_Object window, struct text_pos startp, int *scroll_ste
 
                          exact_match_p =
                            (BUFFERP (g->object) && g->charpos == PT)
-                           || (INTEGERP (g->object)
+                           || (NILP (g->object)
                                && (g->charpos == PT
                                    || (g->charpos == 0 && endpos - 1 == PT)));
                        }
@@ -15838,9 +15700,7 @@ try_cursor_movement (Lisp_Object window, struct text_pos startp, int *scroll_ste
   return rc;
 }
 
-#if !defined USE_TOOLKIT_SCROLL_BARS || defined USE_GTK
-static
-#endif
+
 void
 set_vertical_scroll_bar (struct window *w)
 {
@@ -15879,6 +15739,71 @@ set_vertical_scroll_bar (struct window *w)
 }
 
 
+void
+set_horizontal_scroll_bar (struct window *w)
+{
+  int start, end, whole, portion;
+
+  if (!MINI_WINDOW_P (w)
+      || (w == XWINDOW (minibuf_window)
+         && NILP (echo_area_buffer[0])))
+    {
+      struct buffer *b = XBUFFER (w->contents);
+      struct buffer *old_buffer = NULL;
+      struct it it;
+      struct text_pos startp;
+
+      if (b != current_buffer)
+       {
+         old_buffer = current_buffer;
+         set_buffer_internal (b);
+       }
+
+      SET_TEXT_POS_FROM_MARKER (startp, w->start);
+      start_display (&it, w, startp);
+      it.last_visible_x = INT_MAX;
+      whole = move_it_to (&it, -1, INT_MAX, window_box_height (w), -1,
+                         MOVE_TO_X | MOVE_TO_Y);
+      /* whole = move_it_to (&it, w->window_end_pos, INT_MAX,
+                         window_box_height (w), -1,
+                         MOVE_TO_POS | MOVE_TO_X | MOVE_TO_Y); */
+
+      start = w->hscroll * FRAME_COLUMN_WIDTH (WINDOW_XFRAME (w));
+      end = start + window_box_width (w, TEXT_AREA);
+      portion = end - start;
+      /* After enlarging a horizontally scrolled window such that it
+        gets at least as wide as the text it contains, make sure that
+        the thumb doesn't fill the entire scroll bar so we can still
+        drag it back to see the entire text.  */
+      whole = max (whole, end);
+
+      if (it.bidi_p)
+       {
+         Lisp_Object pdir;
+
+         pdir = Fcurrent_bidi_paragraph_direction (Qnil);
+         if (EQ (pdir, Qright_to_left))
+           {
+             start = whole - end;
+             end = start + portion;
+           }
+       }
+
+      if (old_buffer)
+       set_buffer_internal (old_buffer);
+    }
+  else
+    start = end = whole = portion = 0;
+
+  w->hscroll_whole = whole;
+
+  /* Indicate what this scroll bar ought to be displaying now.  */
+  if (FRAME_TERMINAL (XFRAME (w->frame))->set_horizontal_scroll_bar_hook)
+    (*FRAME_TERMINAL (XFRAME (w->frame))->set_horizontal_scroll_bar_hook)
+      (w, portion, whole, start);
+}
+
+
 /* Redisplay leaf window WINDOW.  JUST_THIS_ONE_P non-zero means only
    selected_window is redisplayed.
 
@@ -16092,6 +16017,7 @@ redisplay_window (Lisp_Object window, bool just_this_one_p)
     {
       ptrdiff_t new_pt = marker_position (w->pointm);
       ptrdiff_t new_pt_byte = marker_byte_position (w->pointm);
+
       if (new_pt < BEGV)
        {
          new_pt = BEGV;
@@ -16546,8 +16472,8 @@ redisplay_window (Lisp_Object window, bool just_this_one_p)
     {
       int window_total_lines
        = WINDOW_TOTAL_LINES (w) * FRAME_LINE_HEIGHT (f) / frame_line_height;
-      int margin =
-       scroll_margin > 0
+      int margin
+       scroll_margin > 0
        ? min (scroll_margin, window_total_lines / 4)
        : 0;
       ptrdiff_t margin_pos = CHARPOS (startp);
@@ -16873,7 +16799,7 @@ redisplay_window (Lisp_Object window, bool just_this_one_p)
            redisplay_tool_bar (f);
 #else
          if (WINDOWP (f->tool_bar_window)
-             && (FRAME_TOOL_BAR_HEIGHT (f) > 0
+             && (FRAME_TOOL_BAR_LINES (f) > 0
                  || !NILP (Vauto_resize_tool_bars))
              && redisplay_tool_bar (f))
            ignore_mouse_drag_p = 1;
@@ -16913,10 +16839,15 @@ redisplay_window (Lisp_Object window, bool just_this_one_p)
   ;
  finish_scroll_bars:
 
-  if (WINDOW_HAS_VERTICAL_SCROLL_BAR (w))
+   if (WINDOW_HAS_VERTICAL_SCROLL_BAR (w) || WINDOW_HAS_HORIZONTAL_SCROLL_BAR (w))
     {
-      /* Set the thumb's position and size.  */
-      set_vertical_scroll_bar (w);
+      if (WINDOW_HAS_VERTICAL_SCROLL_BAR (w))
+       /* Set the thumb's position and size.  */
+       set_vertical_scroll_bar (w);
+
+      if (WINDOW_HAS_HORIZONTAL_SCROLL_BAR (w))
+       /* Set the thumb's position and size.  */
+       set_horizontal_scroll_bar (w);
 
       /* Note that we actually used the scroll bar attached to this
         window, so it shouldn't be deleted at the end of redisplay.  */
@@ -16972,6 +16903,7 @@ try_window (Lisp_Object window, struct text_pos pos, int flags)
 
   /* Initialize iterator and info to start at POS.  */
   start_display (&it, w, pos);
+  it.glyph_row->reversed_p = false;
 
   /* Display all lines of W.  */
   while (it.current_y < it.last_visible_y)
@@ -17155,6 +17087,7 @@ try_window_reusing_current_matrix (struct window *w)
              && it.current.dpvec_index < 0)
            break;
 
+         it.glyph_row->reversed_p = false;
          if (display_line (&it))
            last_text_row = it.glyph_row - 1;
 
@@ -18175,6 +18108,11 @@ try_window_id (struct window *w)
   w->cursor.vpos = -1;
   last_text_row = NULL;
   overlay_arrow_seen = 0;
+  if (it.current_y < it.last_visible_y
+      && !f->fonts_changed
+      && (first_unchanged_at_end_row == NULL
+         || IT_CHARPOS (it) < stop_pos))
+    it.glyph_row->reversed_p = false;
   while (it.current_y < it.last_visible_y
         && !f->fonts_changed
         && (first_unchanged_at_end_row == NULL
@@ -18580,7 +18518,7 @@ dump_glyph (struct glyph_row *row, struct glyph *glyph, int area)
                ? 'B'
                : (STRINGP (glyph->object)
                   ? 'S'
-                  : (INTEGERP (glyph->object)
+                  : (NILP (glyph->object)
                      ? '0'
                      : '-'))),
               glyph->pixel_width,
@@ -18603,7 +18541,7 @@ dump_glyph (struct glyph_row *row, struct glyph *glyph, int area)
                ? 'B'
                : (STRINGP (glyph->object)
                   ? 'S'
-                  : (INTEGERP (glyph->object)
+                  : (NILP (glyph->object)
                      ? '0'
                      : '-'))),
               glyph->pixel_width,
@@ -18624,7 +18562,7 @@ dump_glyph (struct glyph_row *row, struct glyph *glyph, int area)
                ? 'B'
                : (STRINGP (glyph->object)
                   ? 'S'
-                  : (INTEGERP (glyph->object)
+                  : (NILP (glyph->object)
                      ? '0'
                      : '-'))),
               glyph->pixel_width,
@@ -18645,7 +18583,7 @@ dump_glyph (struct glyph_row *row, struct glyph *glyph, int area)
                ? 'B'
                : (STRINGP (glyph->object)
                   ? 'S'
-                  : (INTEGERP (glyph->object)
+                  : (NILP (glyph->object)
                      ? '0'
                      : '-'))),
               glyph->pixel_width,
@@ -18734,10 +18672,10 @@ dump_glyph_row (struct glyph_row *row, int vpos, int glyphs)
   else if (glyphs == 1)
     {
       int area;
+      char s[SHRT_MAX + 4];
 
       for (area = LEFT_MARGIN_AREA; area < LAST_AREA; ++area)
        {
-         char *s = alloca (row->used[area] + 4);
          int i;
 
          for (i = 0; i < row->used[area]; ++i)
@@ -18745,7 +18683,7 @@ dump_glyph_row (struct glyph_row *row, int vpos, int glyphs)
              struct glyph *glyph = row->glyphs[area] + i;
              if (i == row->used[area] - 1
                  && area == TEXT_AREA
-                 && INTEGERP (glyph->object)
+                 && NILP (glyph->object)
                  && glyph->type == CHAR_GLYPH
                  && glyph->u.ch == ' ')
                {
@@ -18876,7 +18814,7 @@ usage: (trace-to-stderr STRING &rest OBJECTS)  */)
   (ptrdiff_t nargs, Lisp_Object *args)
 {
   Lisp_Object s = Fformat (nargs, args);
-  fprintf (stderr, "%s", SDATA (s));
+  fwrite (SDATA (s), 1, SBYTES (s), stderr);
   return Qnil;
 }
 
@@ -18898,7 +18836,7 @@ get_overlay_arrow_glyph_row (struct window *w, Lisp_Object overlay_arrow_string)
   struct buffer *buffer = XBUFFER (w->contents);
   struct buffer *old = current_buffer;
   const unsigned char *arrow_string = SDATA (overlay_arrow_string);
-  int arrow_len = SCHARS (overlay_arrow_string);
+  ptrdiff_t arrow_len = SCHARS (overlay_arrow_string);
   const unsigned char *arrow_end = arrow_string + arrow_len;
   const unsigned char *p;
   struct it it;
@@ -18907,6 +18845,7 @@ get_overlay_arrow_glyph_row (struct window *w, Lisp_Object overlay_arrow_string)
 
   set_buffer_temp (buffer);
   init_iterator (&it, w, -1, -1, &scratch_glyph_row, DEFAULT_FACE_ID);
+  scratch_glyph_row.reversed_p = false;
   it.glyph_row->used[TEXT_AREA] = 0;
   SET_TEXT_POS (it.position, 0, 0);
 
@@ -18974,7 +18913,7 @@ insert_left_trunc_glyphs (struct it *it)
   truncate_it.area = TEXT_AREA;
   truncate_it.glyph_row->used[TEXT_AREA] = 0;
   CHARPOS (truncate_it.position) = BYTEPOS (truncate_it.position) = -1;
-  truncate_it.object = make_number (0);
+  truncate_it.object = Qnil;
   produce_special_glyphs (&truncate_it, IT_TRUNCATION);
 
   /* Overwrite glyphs from IT with truncation glyphs.  */
@@ -19257,7 +19196,7 @@ append_space_for_newline (struct it *it, int default_face_p)
 
          it->what = IT_CHARACTER;
          memset (&it->position, 0, sizeof it->position);
-         it->object = make_number (0);
+         it->object = Qnil;
          it->c = it->char_to_display = ' ';
          it->len = 1;
 
@@ -19449,7 +19388,7 @@ extend_face_to_end_of_line (struct it *it)
              else
                it->face_id = face->id;
              it->start_of_box_run_p = 0;
-             append_stretch_glyph (it, make_number (0), stretch_width,
+             append_stretch_glyph (it, Qnil, stretch_width,
                                    it->ascent + it->descent, stretch_ascent);
              it->position = saved_pos;
              it->avoid_cursor_p = saved_avoid_cursor;
@@ -19479,7 +19418,7 @@ extend_face_to_end_of_line (struct it *it)
 
       it->what = IT_CHARACTER;
       memset (&it->position, 0, sizeof it->position);
-      it->object = make_number (0);
+      it->object = Qnil;
       it->c = it->char_to_display = ' ';
       it->len = 1;
 
@@ -19608,14 +19547,14 @@ highlight_trailing_whitespace (struct frame *f, struct glyph_row *row)
        {
          while (glyph >= start
                 && glyph->type == CHAR_GLYPH
-                && INTEGERP (glyph->object))
+                && NILP (glyph->object))
            --glyph;
        }
       else
        {
          while (glyph <= start
                 && glyph->type == CHAR_GLYPH
-                && INTEGERP (glyph->object))
+                && NILP (glyph->object))
            ++glyph;
        }
 
@@ -19629,7 +19568,7 @@ highlight_trailing_whitespace (struct frame *f, struct glyph_row *row)
                  && glyph->u.ch == ' '))
          && trailing_whitespace_p (glyph->charpos))
        {
-         int face_id = lookup_named_face (f, Qtrailing_whitespace, 0);
+         int face_id = lookup_named_face (f, Qtrailing_whitespace, false);
          if (face_id < 0)
            return;
 
@@ -19978,10 +19917,9 @@ find_row_edges (struct it *it, struct glyph_row *row,
            {
              start = r1->glyphs[TEXT_AREA];
              end = start + r1->used[TEXT_AREA];
-             /* Glyphs inserted by redisplay have an integer (zero)
-                as their object.  */
+             /* Glyphs inserted by redisplay have nil as their object.  */
              while (end > start
-                    && INTEGERP ((end - 1)->object)
+                    && NILP ((end - 1)->object)
                     && (end - 1)->charpos <= 0)
                --end;
              if (end > start)
@@ -20002,7 +19940,7 @@ find_row_edges (struct it *it, struct glyph_row *row,
              end = r1->glyphs[TEXT_AREA] - 1;
              start = end + r1->used[TEXT_AREA];
              while (end < start
-                    && INTEGERP ((end + 1)->object)
+                    && NILP ((end + 1)->object)
                     && (end + 1)->charpos <= 0)
                ++end;
              if (end < start)
@@ -20958,7 +20896,8 @@ See also `bidi-paragraph-direction'.  */)
         the previous non-empty line.  */
       if (pos >= ZV && pos > BEGV)
        DEC_BOTH (pos, bytepos);
-      if (fast_looking_at (build_string ("[\f\t ]*\n"),
+      AUTO_STRING (trailing_white_space, "[\f\t ]*\n");
+      if (fast_looking_at (trailing_white_space,
                           pos, bytepos, ZV, ZV_BYTE, Qnil) > 0)
        {
          while ((c = FETCH_BYTE (bytepos)) == '\n'
@@ -21000,6 +20939,143 @@ See also `bidi-paragraph-direction'.  */)
     }
 }
 
+DEFUN ("bidi-find-overridden-directionality",
+       Fbidi_find_overridden_directionality,
+       Sbidi_find_overridden_directionality, 2, 3, 0,
+       doc: /* Return position between FROM and TO where directionality was overridden.
+
+This function returns the first character position in the specified
+region of OBJECT where there is a character whose `bidi-class' property
+is `L', but which was forced to display as `R' by a directional
+override, and likewise with characters whose `bidi-class' is `R'
+or `AL' that were forced to display as `L'.
+
+If no such character is found, the function returns nil.
+
+OBJECT is a Lisp string or buffer to search for overridden
+directionality, and defaults to the current buffer if nil or omitted.
+OBJECT can also be a window, in which case the function will search
+the buffer displayed in that window.  Passing the window instead of
+a buffer is preferable when the buffer is displayed in some window,
+because this function will then be able to correctly account for
+window-specific overlays, which can affect the results.
+
+Strong directional characters `L', `R', and `AL' can have their
+intrinsic directionality overridden by directional override
+control characters RLO \(u+202e) and LRO \(u+202d).  See the
+function `get-char-code-property' for a way to inquire about
+the `bidi-class' property of a character.  */)
+  (Lisp_Object from, Lisp_Object to, Lisp_Object object)
+{
+  struct buffer *buf = current_buffer;
+  struct buffer *old = buf;
+  struct window *w = NULL;
+  bool frame_window_p = FRAME_WINDOW_P (SELECTED_FRAME ());
+  struct bidi_it itb;
+  ptrdiff_t from_pos, to_pos, from_bpos;
+  void *itb_data;
+
+  if (!NILP (object))
+    {
+      if (BUFFERP (object))
+       buf = XBUFFER (object);
+      else if (WINDOWP (object))
+       {
+         w = decode_live_window (object);
+         buf = XBUFFER (w->contents);
+         frame_window_p = FRAME_WINDOW_P (XFRAME (w->frame));
+       }
+      else
+       CHECK_STRING (object);
+    }
+
+  if (STRINGP (object))
+    {
+      /* Characters in unibyte strings are always treated by bidi.c as
+        strong LTR.  */
+      if (!STRING_MULTIBYTE (object)
+         /* When we are loading loadup.el, the character property
+            tables needed for bidi iteration are not yet
+            available.  */
+         || !NILP (Vpurify_flag))
+       return Qnil;
+
+      validate_subarray (object, from, to, SCHARS (object), &from_pos, &to_pos);
+      if (from_pos >= SCHARS (object))
+       return Qnil;
+
+      /* Set up the bidi iterator.  */
+      itb_data = bidi_shelve_cache ();
+      itb.paragraph_dir = NEUTRAL_DIR;
+      itb.string.lstring = object;
+      itb.string.s = NULL;
+      itb.string.schars = SCHARS (object);
+      itb.string.bufpos = 0;
+      itb.string.from_disp_str = 0;
+      itb.string.unibyte = 0;
+      itb.w = w;
+      bidi_init_it (0, 0, frame_window_p, &itb);
+    }
+  else
+    {
+      /* Nothing this fancy can happen in unibyte buffers, or in a
+        buffer that disabled reordering, or if FROM is at EOB.  */
+      if (NILP (BVAR (buf, bidi_display_reordering))
+         || NILP (BVAR (buf, enable_multibyte_characters))
+         /* When we are loading loadup.el, the character property
+            tables needed for bidi iteration are not yet
+            available.  */
+         || !NILP (Vpurify_flag))
+       return Qnil;
+
+      set_buffer_temp (buf);
+      validate_region (&from, &to);
+      from_pos = XINT (from);
+      to_pos = XINT (to);
+      if (from_pos >= ZV)
+       return Qnil;
+
+      /* Set up the bidi iterator.  */
+      itb_data = bidi_shelve_cache ();
+      from_bpos = CHAR_TO_BYTE (from_pos);
+      if (from_pos == BEGV)
+       {
+         itb.charpos = BEGV;
+         itb.bytepos = BEGV_BYTE;
+       }
+      else if (FETCH_CHAR (from_bpos - 1) == '\n')
+       {
+         itb.charpos = from_pos;
+         itb.bytepos = from_bpos;
+       }
+      else
+       itb.charpos = find_newline_no_quit (from_pos, CHAR_TO_BYTE (from_pos),
+                                           -1, &itb.bytepos);
+      itb.paragraph_dir = NEUTRAL_DIR;
+      itb.string.s = NULL;
+      itb.string.lstring = Qnil;
+      itb.string.bufpos = 0;
+      itb.string.from_disp_str = 0;
+      itb.string.unibyte = 0;
+      itb.w = w;
+      bidi_init_it (itb.charpos, itb.bytepos, frame_window_p, &itb);
+    }
+
+  ptrdiff_t found;
+  do {
+    /* For the purposes of this function, the actual base direction of
+       the paragraph doesn't matter, so just set it to L2R.  */
+    bidi_paragraph_init (L2R, &itb, 0);
+    while ((found = bidi_find_first_overridden (&itb)) < from_pos)
+      ;
+  } while (found == ZV && itb.ch == '\n' && itb.charpos < to_pos);
+
+  bidi_unshelve_cache (itb_data, 0);
+  set_buffer_temp (old);
+
+  return (from_pos <= found && found < to_pos) ? make_number (found) : Qnil;
+}
+
 DEFUN ("move-point-visually", Fmove_point_visually,
        Smove_point_visually, 1, 1, 0,
        doc: /* Move point in the visual order in the specified DIRECTION.
@@ -21017,7 +21093,7 @@ Value is the new character position of point.  */)
 
 #define ROW_GLYPH_NEWLINE_P(ROW,GLYPH)         \
   (!(ROW)->continued_p                         \
-   && INTEGERP ((GLYPH)->object)               \
+   && NILP ((GLYPH)->object)                   \
    && (GLYPH)->type == CHAR_GLYPH              \
    && (GLYPH)->u.ch == ' '                     \
    && (GLYPH)->charpos >= 0                    \
@@ -21059,7 +21135,7 @@ Value is the new character position of point.  */)
              w->cursor.vpos = -1;
              return make_number (PT);
            }
-         else if (!INTEGERP (g->object) && !EQ (g->object, gpt->object))
+         else if (!NILP (g->object) && !EQ (g->object, gpt->object))
            {
              ptrdiff_t new_pos;
 
@@ -21069,7 +21145,7 @@ Value is the new character position of point.  */)
                  if ((gpt->resolved_level - row->reversed_p) % 2 == 0)
                    new_pos += (row->reversed_p ? -dir : dir);
                  else
-                   new_pos -= (row->reversed_p ? -dir : dir);;
+                   new_pos -= (row->reversed_p ? -dir : dir);
                }
              else if (BUFFERP (g->object))
                new_pos = g->charpos;
@@ -21096,7 +21172,7 @@ Value is the new character position of point.  */)
              return make_number (PT);
            }
        }
-      if (g == e || INTEGERP (g->object))
+      if (g == e || NILP (g->object))
        {
          if (row->truncated_on_left_p || row->truncated_on_right_p)
            goto simulate_display;
@@ -21129,7 +21205,7 @@ Value is the new character position of point.  */)
                         EOB also has one glyph, but its charpos is -1.  */
                      || (row->ends_at_zv_p
                          && !row->reversed_p
-                         && INTEGERP (g->object)
+                         && NILP (g->object)
                          && g->type == CHAR_GLYPH
                          && g->u.ch == ' '))
                    {
@@ -21167,7 +21243,7 @@ Value is the new character position of point.  */)
                      || g->type == STRETCH_GLYPH
                      || (row->ends_at_zv_p
                          && row->reversed_p
-                         && INTEGERP (g->object)
+                         && NILP (g->object)
                          && g->type == CHAR_GLYPH
                          && g->u.ch == ' '))
                    {
@@ -21459,6 +21535,114 @@ Value is the new character position of point.  */)
 #undef ROW_GLYPH_NEWLINE_P
 }
 
+DEFUN ("bidi-resolved-levels", Fbidi_resolved_levels,
+       Sbidi_resolved_levels, 0, 1, 0,
+       doc: /* Return the resolved bidirectional levels of characters at VPOS.
+
+The resolved levels are produced by the Emacs bidi reordering engine
+that implements the UBA, the Unicode Bidirectional Algorithm.  Please
+read the Unicode Standard Annex 9 (UAX#9) for background information
+about these levels.
+
+VPOS is the zero-based number of the current window's screen line
+for which to produce the resolved levels.  If VPOS is nil or omitted,
+it defaults to the screen line of point.  If the window displays a
+header line, VPOS of zero will report on the header line, and first
+line of text in the window will have VPOS of 1.
+
+Value is an array of resolved levels, indexed by glyph number.
+Glyphs are numbered from zero starting from the beginning of the
+screen line, i.e. the left edge of the window for left-to-right lines
+and from the right edge for right-to-left lines.  The resolved levels
+are produced only for the window's text area; text in display margins
+is not included.
+
+If the selected window's display is not up-to-date, or if the specified
+screen line does not display text, this function returns nil.  It is
+highly recommended to bind this function to some simple key, like F8,
+in order to avoid these problems.
+
+This function exists mainly for testing the correctness of the
+Emacs UBA implementation, in particular with the test suite.  */)
+  (Lisp_Object vpos)
+{
+  struct window *w = XWINDOW (selected_window);
+  struct buffer *b = XBUFFER (w->contents);
+  int nrow;
+  struct glyph_row *row;
+
+  if (NILP (vpos))
+    {
+      int d1, d2, d3, d4, d5;
+
+      pos_visible_p (w, PT, &d1, &d2, &d3, &d4, &d5, &nrow);
+    }
+  else
+    {
+      CHECK_NUMBER_COERCE_MARKER (vpos);
+      nrow = XINT (vpos);
+    }
+
+  /* We require up-to-date glyph matrix for this window.  */
+  if (w->window_end_valid
+      && !windows_or_buffers_changed
+      && b
+      && !b->clip_changed
+      && !b->prevent_redisplay_optimizations_p
+      && !window_outdated (w)
+      && nrow >= 0
+      && nrow < w->current_matrix->nrows
+      && (row = MATRIX_ROW (w->current_matrix, nrow))->enabled_p
+      && MATRIX_ROW_DISPLAYS_TEXT_P (row))
+    {
+      struct glyph *g, *e, *g1;
+      int nglyphs, i;
+      Lisp_Object levels;
+
+      if (!row->reversed_p)    /* Left-to-right glyph row.  */
+       {
+         g = g1 = row->glyphs[TEXT_AREA];
+         e = g + row->used[TEXT_AREA];
+
+         /* Skip over glyphs at the start of the row that was
+            generated by redisplay for its own needs.  */
+         while (g < e
+                && NILP (g->object)
+                && g->charpos < 0)
+           g++;
+         g1 = g;
+
+         /* Count the "interesting" glyphs in this row.  */
+         for (nglyphs = 0; g < e && !NILP (g->object); g++)
+           nglyphs++;
+
+         /* Create and fill the array.  */
+         levels = make_uninit_vector (nglyphs);
+         for (i = 0; g1 < g; i++, g1++)
+           ASET (levels, i, make_number (g1->resolved_level));
+       }
+      else                     /* Right-to-left glyph row.  */
+       {
+         g = row->glyphs[TEXT_AREA] + row->used[TEXT_AREA] - 1;
+         e = row->glyphs[TEXT_AREA] - 1;
+         while (g > e
+                && NILP (g->object)
+                && g->charpos < 0)
+           g--;
+         g1 = g;
+         for (nglyphs = 0; g > e && !NILP (g->object); g--)
+           nglyphs++;
+         levels = make_uninit_vector (nglyphs);
+         for (i = 0; g1 > g; i++, g1--)
+           ASET (levels, i, make_number (g1->resolved_level));
+       }
+      return levels;
+    }
+  else
+    return Qnil;
+}
+
+
 \f
 /***********************************************************************
                               Menu Bar
@@ -21537,6 +21721,7 @@ display_menu_bar (struct window *w)
       clear_glyph_row (row);
       row->enabled_p = true;
       row->full_width_p = 1;
+      row->reversed_p = false;
     }
 
   /* Display all items of the menu bar.  */
@@ -22770,10 +22955,8 @@ decode_mode_spec_coding (Lisp_Object coding_system, register char *buf, int eol_
        }
       else if (CHARACTERP (eoltype))
        {
-         unsigned char *tmp = alloca (MAX_MULTIBYTE_LENGTH);
          int c = XFASTINT (eoltype);
-         eol_str_len = CHAR_STRING (c, tmp);
-         eol_str = tmp;
+         return buf + CHAR_STRING (c, (unsigned char *) buf);
        }
       else
        {
@@ -22909,7 +23092,7 @@ decode_mode_spec (struct window *w, register int c, int field_width,
        }
 
     case 'e':
-#ifndef SYSTEM_MALLOC
+#if !defined SYSTEM_MALLOC && !defined HYBRID_MALLOC
       {
        if (NILP (Vmemory_full))
          return "";
@@ -23050,7 +23233,7 @@ decode_mode_spec (struct window *w, register int c, int field_width,
        return decode_mode_spec_buf;
     no_value:
         {
-         charp = decode_mode_spec_buf;
+         char *p = decode_mode_spec_buf;
          int pad = width - 2;
          while (pad-- > 0)
            *p++ = ' ';
@@ -23395,7 +23578,7 @@ display_string (const char *string, Lisp_Object lisp_string, Lisp_Object face_st
 
       it->face_id
        = face_at_string_position (it->w, face_string, face_string_pos,
-                                  0, &endptr, it->base_face_id, 0);
+                                  0, &endptr, it->base_face_id, false);
       face = FACE_FROM_ID (it->f, it->face_id);
       it->face_box_p = face->box != FACE_NO_BOX;
     }
@@ -23802,7 +23985,7 @@ calc_pixel_width_or_height (double *res, struct it *it, Lisp_Object prop,
            return OK_PIXELS (WINDOW_SCROLL_BAR_AREA_WIDTH (it->w));
        }
 
-      prop = buffer_local_value_1 (prop, it->w->contents);
+      prop = buffer_local_value (prop, it->w->contents);
       if (EQ (prop, Qunbound))
        prop = Qnil;
     }
@@ -23854,7 +24037,7 @@ calc_pixel_width_or_height (double *res, struct it *it, Lisp_Object prop,
              return OK_PIXELS (pixels);
            }
 
-         car = buffer_local_value_1 (car, it->w->contents);
+         car = buffer_local_value (car, it->w->contents);
          if (EQ (car, Qunbound))
            car = Qnil;
        }
@@ -24031,7 +24214,7 @@ get_char_face_and_encoding (struct frame *f, int c, int face_id,
 #endif
     {
       eassert (face != NULL);
-      PREPARE_FACE_FOR_DISPLAY (f, face);
+      prepare_face_for_display (f, face);
     }
 
   return face;
@@ -24054,7 +24237,7 @@ get_glyph_face_and_encoding (struct frame *f, struct glyph *glyph,
 
   /* Make sure X resources of the face are allocated.  */
   eassert (face != NULL);
-  PREPARE_FACE_FOR_DISPLAY (f, face);
+  prepare_face_for_display (f, face);
 
   if (two_byte_p)
     *two_byte_p = 0;
@@ -24371,7 +24554,7 @@ fill_stretch_glyph_string (struct glyph_string *s, int start, int end)
   s->ybase += voffset;
 
   /* The case that face->gc == 0 is handled when drawing the glyph
-     string by calling PREPARE_FACE_FOR_DISPLAY.  */
+     string by calling prepare_face_for_display.  */
   eassert (s->face);
   return glyph - s->row->glyphs[s->area];
 }
@@ -24689,7 +24872,7 @@ compute_overhangs_and_x (struct glyph_string *s, int x, int backward_p)
         face_id = (row)->glyphs[area][START].face_id;                     \
                                                                           \
         s = alloca (sizeof *s);                                           \
-        char2b = alloca ((END - START) * sizeof *char2b);                 \
+        SAFE_NALLOCA (char2b, 1, (END) - (START));                        \
         INIT_GLYPH_STRING (s, char2b, w, row, area, START, HL);           \
         append_glyph_string (&HEAD, &TAIL, s);                            \
         s->x = (X);                                                       \
@@ -24717,7 +24900,7 @@ compute_overhangs_and_x (struct glyph_string *s, int x, int backward_p)
     struct glyph_string *first_s = NULL;                                   \
     int n;                                                                 \
                                                                            \
-    char2b = alloca (cmp->glyph_len * sizeof *char2b);                     \
+    SAFE_NALLOCA (char2b, 1, cmp->glyph_len);                              \
                                                                            \
     /* Make glyph_strings for each glyph sequence that is drawable by      \
        the same face, and append them to HEAD/TAIL.  */                            \
@@ -24752,7 +24935,7 @@ compute_overhangs_and_x (struct glyph_string *s, int x, int backward_p)
     gstring = (composition_gstring_from_id                               \
               ((row)->glyphs[area][START].u.cmp.id));                    \
     s = alloca (sizeof *s);                                              \
-    char2b = alloca (LGSTRING_GLYPH_LEN (gstring) * sizeof *char2b);     \
+    SAFE_NALLOCA (char2b, 1, LGSTRING_GLYPH_LEN (gstring));              \
     INIT_GLYPH_STRING (s, char2b, w, row, area, START, HL);              \
     append_glyph_string (&(HEAD), &(TAIL), s);                           \
     s->x = (X);                                                                  \
@@ -24904,6 +25087,7 @@ draw_glyphs (struct window *w, int x, struct glyph_row *row,
      BUILD_GLYPH_STRINGS will modify its start parameter.  That's
      the reason we use a separate variable `i'.  */
   i = start;
+  USE_SAFE_ALLOCA;
   BUILD_GLYPH_STRINGS (i, end, head, tail, hl, x, last_x);
   if (tail)
     x_reached = tail->x + tail->background_width;
@@ -25103,6 +25287,7 @@ draw_glyphs (struct window *w, int x, struct glyph_row *row,
 
   RELEASE_HDC (hdc, f);
 
+  SAFE_FREE ();
   return x_reached;
 }
 
@@ -25188,8 +25373,7 @@ append_glyph (struct it *it)
       if (it->bidi_p)
        {
          glyph->resolved_level = it->bidi_it.resolved_level;
-         if ((it->bidi_it.type & 7) != it->bidi_it.type)
-           emacs_abort ();
+         eassert ((it->bidi_it.type & 7) == it->bidi_it.type);
          glyph->bidi_type = it->bidi_it.type;
        }
       else
@@ -25272,8 +25456,7 @@ append_composite_glyph (struct it *it)
       if (it->bidi_p)
        {
          glyph->resolved_level = it->bidi_it.resolved_level;
-         if ((it->bidi_it.type & 7) != it->bidi_it.type)
-           emacs_abort ();
+         eassert ((it->bidi_it.type & 7) == it->bidi_it.type);
          glyph->bidi_type = it->bidi_it.type;
        }
       ++it->glyph_row->used[area];
@@ -25320,7 +25503,7 @@ produce_image_glyph (struct it *it)
   face = FACE_FROM_ID (it->f, it->face_id);
   eassert (face);
   /* Make sure X resources of the face is loaded.  */
-  PREPARE_FACE_FOR_DISPLAY (it->f, face);
+  prepare_face_for_display (it->f, face);
 
   if (it->image_id < 0)
     {
@@ -25461,8 +25644,7 @@ produce_image_glyph (struct it *it)
          if (it->bidi_p)
            {
              glyph->resolved_level = it->bidi_it.resolved_level;
-             if ((it->bidi_it.type & 7) != it->bidi_it.type)
-               emacs_abort ();
+             eassert ((it->bidi_it.type & 7) == it->bidi_it.type);
              glyph->bidi_type = it->bidi_it.type;
            }
          ++it->glyph_row->used[area];
@@ -25550,8 +25732,7 @@ append_stretch_glyph (struct it *it, Lisp_Object object,
       if (it->bidi_p)
        {
          glyph->resolved_level = it->bidi_it.resolved_level;
-         if ((it->bidi_it.type & 7) != it->bidi_it.type)
-           emacs_abort ();
+         eassert ((it->bidi_it.type & 7) == it->bidi_it.type);
          glyph->bidi_type = it->bidi_it.type;
        }
       else
@@ -25616,7 +25797,7 @@ produce_stretch_glyph (struct it *it)
     {
       struct face *face = FACE_FROM_ID (it->f, it->face_id);
       font = face->font ? face->font : FRAME_FONT (it->f);
-      PREPARE_FACE_FOR_DISPLAY (it->f, face);
+      prepare_face_for_display (it->f, face);
     }
 #endif
 
@@ -25774,7 +25955,7 @@ produce_special_glyphs (struct it *it, enum display_element_type what)
   GLYPH glyph;
 
   temp_it = *it;
-  temp_it.object = make_number (0);
+  temp_it.object = Qnil;
   memset (&temp_it.current, 0, sizeof temp_it.current);
 
   if (what == IT_CONTINUATION)
@@ -25837,7 +26018,7 @@ produce_special_glyphs (struct it *it, enum display_element_type what)
            (((temp_it.ascent + temp_it.descent)
              * FONT_BASE (font)) / FONT_HEIGHT (font));
 
-         append_stretch_glyph (&temp_it, make_number (0), stretch_width,
+         append_stretch_glyph (&temp_it, Qnil, stretch_width,
                                temp_it.ascent + temp_it.descent,
                                stretch_ascent);
        }
@@ -25903,7 +26084,7 @@ calc_line_height_property (struct it *it, Lisp_Object val, struct font *font,
       int face_id;
       struct face *face;
 
-      face_id = lookup_named_face (it->f, face_name, 0);
+      face_id = lookup_named_face (it->f, face_name, false);
       if (face_id < 0)
        return make_number (-1);
 
@@ -26010,8 +26191,7 @@ append_glyphless_glyph (struct it *it, int face_id, int for_no_font, int len,
       if (it->bidi_p)
        {
          glyph->resolved_level = it->bidi_it.resolved_level;
-         if ((it->bidi_it.type & 7) != it->bidi_it.type)
-           emacs_abort ();
+         eassert ((it->bidi_it.type & 7) == it->bidi_it.type);
          glyph->bidi_type = it->bidi_it.type;
        }
       ++it->glyph_row->used[area];
@@ -26079,7 +26259,7 @@ produce_glyphless_glyph (struct it *it, int for_no_font, Lisp_Object acronym)
 
       face = FACE_FROM_ID (it->f, face_id);
       font = face->font ? face->font : FRAME_FONT (it->f);
-      PREPARE_FACE_FOR_DISPLAY (it->f, face);
+      prepare_face_for_display (it->f, face);
 
       if (it->glyphless_method == GLYPHLESS_DISPLAY_ACRONYM)
        {
@@ -26095,7 +26275,7 @@ produce_glyphless_glyph (struct it *it, int for_no_font, Lisp_Object acronym)
          sprintf (buf, "%0*X", it->c < 0x10000 ? 4 : 6, it->c);
          str = buf;
        }
-      for (len = 0; str[len] && ASCII_BYTE_P (str[len]) && len < 6; len++)
+      for (len = 0; str[len] && ASCII_CHAR_P (str[len]) && len < 6; len++)
        code[len] = font->driver->encode_char (font, str[len]);
       upper_len = (len + 1) / 2;
       font->driver->text_extents (font, code, upper_len,
@@ -27420,9 +27600,6 @@ draw_phys_cursor_glyph (struct window *w, struct glyph_row *row,
 
 /* Erase the image of a cursor of window W from the screen.  */
 
-#ifndef HAVE_NTGUI
-static
-#endif
 void
 erase_phys_cursor (struct window *w)
 {
@@ -27845,7 +28022,7 @@ show_mouse_face (Mouse_HLInfo *hlinfo, enum draw_glyphs_face draw)
 
 #ifdef HAVE_WINDOW_SYSTEM
   /* Change the mouse cursor.  */
-  if (FRAME_WINDOW_P (f))
+  if (FRAME_WINDOW_P (f) && NILP (do_mouse_tracking))
     {
 #if ! defined (USE_GTK) && ! defined (HAVE_NS)
       if (draw == DRAW_NORMAL_TEXT
@@ -28016,7 +28193,7 @@ rows_from_pos_range (struct window *w,
 
          while (g < e)
            {
-             if (((BUFFERP (g->object) || INTEGERP (g->object))
+             if (((BUFFERP (g->object) || NILP (g->object))
                   && start_charpos <= g->charpos && g->charpos < end_charpos)
                  /* A glyph that comes from DISP_STRING is by
                     definition to be highlighted.  */
@@ -28071,7 +28248,7 @@ rows_from_pos_range (struct window *w,
 
          while (g < e)
            {
-             if (((BUFFERP (g->object) || INTEGERP (g->object))
+             if (((BUFFERP (g->object) || NILP (g->object))
                   && ((start_charpos <= g->charpos && g->charpos < end_charpos)
                       /* If the buffer position of the first glyph in
                          the row is equal to END_CHARPOS, it means
@@ -28153,7 +28330,7 @@ mouse_face_from_buffer_pos (Lisp_Object window,
        {
          struct glyph *beg = prev->glyphs[TEXT_AREA];
          glyph = beg + prev->used[TEXT_AREA];
-         while (--glyph >= beg && INTEGERP (glyph->object));
+         while (--glyph >= beg && NILP (glyph->object));
          if (glyph < beg
              || !(EQ (glyph->object, before_string)
                   || EQ (glyph->object, disp_string)))
@@ -28217,7 +28394,7 @@ mouse_face_from_buffer_pos (Lisp_Object window,
       /* Skip truncation glyphs at the start of the glyph row.  */
       if (MATRIX_ROW_DISPLAYS_TEXT_P (r1))
        for (; glyph < end
-              && INTEGERP (glyph->object)
+              && NILP (glyph->object)
               && glyph->charpos < 0;
             ++glyph)
          x += glyph->pixel_width;
@@ -28226,7 +28403,7 @@ mouse_face_from_buffer_pos (Lisp_Object window,
         or DISP_STRING, and the first glyph from buffer whose
         position is between START_CHARPOS and END_CHARPOS.  */
       for (; glyph < end
-            && !INTEGERP (glyph->object)
+            && !NILP (glyph->object)
             && !EQ (glyph->object, disp_string)
             && !(BUFFERP (glyph->object)
                  && (glyph->charpos >= start_charpos
@@ -28268,7 +28445,7 @@ mouse_face_from_buffer_pos (Lisp_Object window,
       /* Skip truncation glyphs at the start of the glyph row.  */
       if (MATRIX_ROW_DISPLAYS_TEXT_P (r1))
        for (; glyph > end
-              && INTEGERP (glyph->object)
+              && NILP (glyph->object)
               && glyph->charpos < 0;
             --glyph)
          ;
@@ -28277,7 +28454,7 @@ mouse_face_from_buffer_pos (Lisp_Object window,
         or DISP_STRING, and the first glyph from buffer whose
         position is between START_CHARPOS and END_CHARPOS.  */
       for (; glyph > end
-            && !INTEGERP (glyph->object)
+            && !NILP (glyph->object)
             && !EQ (glyph->object, disp_string)
             && !(BUFFERP (glyph->object)
                  && (glyph->charpos >= start_charpos
@@ -28334,7 +28511,7 @@ mouse_face_from_buffer_pos (Lisp_Object window,
         row, and also blanks and stretch glyphs inserted by
         extend_face_to_end_of_line.  */
       while (end > glyph
-            && INTEGERP ((end - 1)->object))
+            && NILP ((end - 1)->object))
        --end;
       /* Scan the rest of the glyph row from the end, looking for the
         first glyph that comes from BEFORE_STRING, AFTER_STRING, or
@@ -28342,7 +28519,7 @@ mouse_face_from_buffer_pos (Lisp_Object window,
         and END_CHARPOS */
       for (--end;
             end > glyph
-            && !INTEGERP (end->object)
+            && !NILP (end->object)
             && !EQ (end->object, disp_string)
             && !(BUFFERP (end->object)
                  && (end->charpos >= start_charpos
@@ -28380,7 +28557,7 @@ mouse_face_from_buffer_pos (Lisp_Object window,
       x = r2->x;
       end++;
       while (end < glyph
-            && INTEGERP (end->object))
+            && NILP (end->object))
        {
          x += end->pixel_width;
          ++end;
@@ -28391,7 +28568,7 @@ mouse_face_from_buffer_pos (Lisp_Object window,
         and END_CHARPOS */
       for ( ;
             end < glyph
-            && !INTEGERP (end->object)
+            && !NILP (end->object)
             && !EQ (end->object, disp_string)
             && !(BUFFERP (end->object)
                  && (end->charpos >= start_charpos
@@ -28954,8 +29131,8 @@ note_mode_line_or_margin_highlight (Lisp_Object window, int x, int y,
          else if (area == ON_MODE_LINE)
            {
              Lisp_Object default_help
-               = buffer_local_value_1 (Qmode_line_default_help_echo,
-                                       w->contents);
+               = buffer_local_value (Qmode_line_default_help_echo,
+                                     w->contents);
 
              if (STRINGP (default_help))
                {
@@ -29123,7 +29300,7 @@ note_mode_line_or_margin_highlight (Lisp_Object window, int x, int y,
                                                                charpos,
                                                                0, &ignore,
                                                                glyph->face_id,
-                                                               1);
+                                                               true);
          show_mouse_face (hlinfo, DRAW_MOUSE_FACE);
 
          if (NILP (pointer))
@@ -29249,7 +29426,8 @@ note_mouse_highlight (struct frame *f, int x, int y)
     else
       cursor = FRAME_X_OUTPUT (f)->nontext_cursor;
   else if (part == ON_LEFT_FRINGE || part == ON_RIGHT_FRINGE
-          || part == ON_SCROLL_BAR)
+          || part == ON_VERTICAL_SCROLL_BAR
+          || part == ON_HORIZONTAL_SCROLL_BAR)
     cursor = FRAME_X_OUTPUT (f)->nontext_cursor;
   else
     cursor = FRAME_X_OUTPUT (f)->text_cursor;
@@ -29322,12 +29500,12 @@ note_mouse_highlight (struct frame *f, int x, int y)
       if (glyph == NULL
          || area != TEXT_AREA
          || !MATRIX_ROW_DISPLAYS_TEXT_P (MATRIX_ROW (w->current_matrix, vpos))
-         /* Glyph's OBJECT is an integer for glyphs inserted by the
+         /* Glyph's OBJECT is nil for glyphs inserted by the
             display engine for its internal purposes, like truncation
             and continuation glyphs and blanks beyond the end of
             line's text on text terminals.  If we are over such a
             glyph, we are not over any text.  */
-         || INTEGERP (glyph->object)
+         || NILP (glyph->object)
          /* R2L rows have a stretch glyph at their front, which
             stands for no text, whereas L2R rows have no glyphs at
             all beyond the end of text.  Treat such stretch glyphs
@@ -29372,6 +29550,8 @@ note_mouse_highlight (struct frame *f, int x, int y)
       /* Is this char mouse-active or does it have help-echo?  */
       position = make_number (pos);
 
+      USE_SAFE_ALLOCA;
+
       if (BUFFERP (object))
        {
          /* Put all the overlays we want in a vector in overlay_vec.  */
@@ -29448,7 +29628,7 @@ note_mouse_highlight (struct frame *f, int x, int y)
              hlinfo->mouse_face_window = window;
              hlinfo->mouse_face_face_id
                = face_at_string_position (w, object, pos, 0, &ignore,
-                                          glyph->face_id, 1);
+                                          glyph->face_id, true);
              show_mouse_face (hlinfo, DRAW_MOUSE_FACE);
              cursor = No_Cursor;
            }
@@ -29653,6 +29833,7 @@ note_mouse_highlight (struct frame *f, int x, int y)
       BEGV = obegv;
       ZV = ozv;
       current_buffer = obuf;
+      SAFE_FREE ();
     }
 
  set_cursor:
@@ -30170,8 +30351,8 @@ expose_frame (struct frame *f, int x, int y, int w, int h)
   if (w == 0 || h == 0)
     {
       r.x = r.y = 0;
-      r.width = FRAME_COLUMN_WIDTH (f) * FRAME_COLS (f);
-      r.height = FRAME_LINE_HEIGHT (f) * FRAME_LINES (f);
+      r.width = FRAME_TEXT_WIDTH (f);
+      r.height = FRAME_TEXT_HEIGHT (f);
     }
   else
     {
@@ -30296,7 +30477,9 @@ syms_of_xdisp (void)
   Vmessage_stack = Qnil;
   staticpro (&Vmessage_stack);
 
+  /* Non-nil means don't actually do any redisplay.  */
   DEFSYM (Qinhibit_redisplay, "inhibit-redisplay");
+
   DEFSYM (Qredisplay_internal, "redisplay_internal (C function)");
 
   message_dolog_marker1 = Fmake_marker ();
@@ -30324,6 +30507,7 @@ syms_of_xdisp (void)
   defsubr (&Scurrent_bidi_paragraph_direction);
   defsubr (&Swindow_text_pixel_size);
   defsubr (&Smove_point_visually);
+  defsubr (&Sbidi_find_overridden_directionality);
 
   DEFSYM (Qmenu_bar_update_hook, "menu-bar-update-hook");
   DEFSYM (Qoverriding_terminal_local_map, "overriding-terminal-local-map");
@@ -30334,6 +30518,8 @@ syms_of_xdisp (void)
   DEFSYM (Qinhibit_point_motion_hooks, "inhibit-point-motion-hooks");
   DEFSYM (Qeval, "eval");
   DEFSYM (QCdata, ":data");
+
+  /* Names of text properties relevant for redisplay.  */
   DEFSYM (Qdisplay, "display");
   DEFSYM (Qspace_width, "space-width");
   DEFSYM (Qraise, "raise");
@@ -30353,40 +30539,69 @@ syms_of_xdisp (void)
   DEFSYM (QCfile, ":file");
   DEFSYM (Qfontified, "fontified");
   DEFSYM (Qfontification_functions, "fontification-functions");
+
+  /* Name of the face used to highlight trailing whitespace.  */
   DEFSYM (Qtrailing_whitespace, "trailing-whitespace");
+
+  /* Name and number of the face used to highlight escape glyphs.  */
   DEFSYM (Qescape_glyph, "escape-glyph");
+
+  /* Name and number of the face used to highlight non-breaking spaces.  */
   DEFSYM (Qnobreak_space, "nobreak-space");
+
+  /* The symbol 'image' which is the car of the lists used to represent
+     images in Lisp.  Also a tool bar style.  */
   DEFSYM (Qimage, "image");
+
+  /* Tool bar styles.  */
   DEFSYM (Qtext, "text");
   DEFSYM (Qboth, "both");
   DEFSYM (Qboth_horiz, "both-horiz");
   DEFSYM (Qtext_image_horiz, "text-image-horiz");
+
+  /* The image map types.  */
   DEFSYM (QCmap, ":map");
   DEFSYM (QCpointer, ":pointer");
   DEFSYM (Qrect, "rect");
   DEFSYM (Qcircle, "circle");
   DEFSYM (Qpoly, "poly");
+
+  /* The symbol `inhibit-menubar-update' and its DEFVAR_BOOL variable.  */
+  DEFSYM (Qinhibit_menubar_update, "inhibit-menubar-update");
   DEFSYM (Qmessage_truncate_lines, "message-truncate-lines");
+
   DEFSYM (Qgrow_only, "grow-only");
-  DEFSYM (Qinhibit_menubar_update, "inhibit-menubar-update");
   DEFSYM (Qinhibit_eval_during_redisplay, "inhibit-eval-during-redisplay");
   DEFSYM (Qposition, "position");
   DEFSYM (Qbuffer_position, "buffer-position");
   DEFSYM (Qobject, "object");
+
+  /* Cursor shapes.  */
   DEFSYM (Qbar, "bar");
   DEFSYM (Qhbar, "hbar");
   DEFSYM (Qbox, "box");
   DEFSYM (Qhollow, "hollow");
+
+  /* Pointer shapes.  */
   DEFSYM (Qhand, "hand");
   DEFSYM (Qarrow, "arrow");
+  /* also Qtext */
+
   DEFSYM (Qinhibit_free_realized_faces, "inhibit-free-realized-faces");
 
   list_of_error = list1 (list2 (intern_c_string ("error"),
                                intern_c_string ("void-variable")));
   staticpro (&list_of_error);
 
+  /* Values of those variables at last redisplay are stored as
+     properties on 'overlay-arrow-position' symbol.  However, if
+     Voverlay_arrow_position is a marker, last-arrow-position is its
+     numerical position.  */
   DEFSYM (Qlast_arrow_position, "last-arrow-position");
   DEFSYM (Qlast_arrow_string, "last-arrow-string");
+
+  /* Alternative overlay-arrow-string and overlay-arrow-bitmap
+     properties on a symbol in overlay-arrow-variable-list.  */
   DEFSYM (Qoverlay_arrow_string, "overlay-arrow-string");
   DEFSYM (Qoverlay_arrow_bitmap, "overlay-arrow-bitmap");
 
@@ -30426,6 +30641,7 @@ syms_of_xdisp (void)
 
   DEFSYM (Qright_to_left, "right-to-left");
   DEFSYM (Qleft_to_right, "left-to-right");
+  defsubr (&Sbidi_resolved_levels);
 
 #ifdef HAVE_WINDOW_SYSTEM
   DEFVAR_BOOL ("x-stretch-cursor", x_stretch_cursor_p,
@@ -30457,8 +30673,9 @@ A value of nil means no special handling of these characters.  */);
 
   DEFVAR_LISP ("void-text-area-pointer", Vvoid_text_area_pointer,
     doc: /* The pointer shape to show in void text areas.
-A value of nil means to show the text pointer.  Other options are `arrow',
-`text', `hand', `vdrag', `hdrag', `modeline', and `hourglass'.  */);
+A value of nil means to show the text pointer.  Other options are
+`arrow', `text', `hand', `vdrag', `hdrag', `nhdrag', `modeline', and
+`hourglass'.  */);
   Vvoid_text_area_pointer = Qarrow;
 
   DEFVAR_LISP ("inhibit-redisplay", Vinhibit_redisplay,
@@ -30604,9 +30821,12 @@ all the functions in the list are called, with the frame as argument.  */);
   DEFVAR_LISP ("window-scroll-functions", Vwindow_scroll_functions,
     doc: /* List of functions to call before redisplaying a window with scrolling.
 Each function is called with two arguments, the window and its new
-display-start position.  Note that these functions are also called by
-`set-window-buffer'.  Also note that the value of `window-end' is not
-valid when these functions are called.
+display-start position.
+These functions are called whenever the `window-start' marker is modified,
+either to point into another buffer (e.g. via `set-window-buffer') or another
+place in the same buffer.
+Note that the value of `window-end' is not valid when these functions are
+called.
 
 Warning: Do not use this feature to alter the way the window
 is scrolled.  It is not designed for that, and such use probably won't
@@ -30831,6 +31051,12 @@ To add a prefix to continuation lines, use `wrap-prefix'.  */);
     doc: /* Non-nil means don't free realized faces.  Internal use only.  */);
   inhibit_free_realized_faces = 0;
 
+  DEFVAR_BOOL ("inhibit-bidi-mirroring", inhibit_bidi_mirroring,
+    doc: /* Non-nil means don't mirror characters even when bidi context requires that.
+Intended for use during debugging and for testing bidi display;
+see biditest.el in the test suite.  */);
+  inhibit_bidi_mirroring = 0;
+
 #ifdef GLYPH_DEBUG
   DEFVAR_BOOL ("inhibit-try-window-id", inhibit_try_window_id,
               doc: /* Inhibit try_window_id display optimization.  */);
@@ -30875,7 +31101,10 @@ cursor shapes.  */);
   hourglass_shown_p = 0;
 #endif /* HAVE_WINDOW_SYSTEM */
 
+  /* Name of the face used to display glyphless characters.  */
   DEFSYM (Qglyphless_char, "glyphless-char");
+
+  /* Method symbols for Vglyphless_char_display.  */
   DEFSYM (Qhex_code, "hex-code");
   DEFSYM (Qempty_box, "empty-box");
   DEFSYM (Qthin_space, "thin-space");
@@ -30888,6 +31117,7 @@ be redisplayed.  This set can be nil (meaning, only the selected window),
 or t (meaning all windows).  */);
   Vpre_redisplay_function = intern ("ignore");
 
+  /* Symbol for the purpose of Vglyphless_char_display.  */
   DEFSYM (Qglyphless_char_display, "glyphless-char-display");
   Fput (Qglyphless_char_display, Qchar_table_extra_slots, make_number (1));
 
@@ -30953,10 +31183,10 @@ init_xdisp (void)
       r->pixel_top = r->top_line * FRAME_LINE_HEIGHT (f);
       r->total_cols = FRAME_COLS (f);
       r->pixel_width = r->total_cols * FRAME_COLUMN_WIDTH (f);
-      r->total_lines = FRAME_LINES (f) - 1 - FRAME_TOP_MARGIN (f);
+      r->total_lines = FRAME_TOTAL_LINES (f) - 1 - FRAME_TOP_MARGIN (f);
       r->pixel_height = r->total_lines * FRAME_LINE_HEIGHT (f);
 
-      m->top_line = FRAME_LINES (f) - 1;
+      m->top_line = FRAME_TOTAL_LINES (f) - 1;
       m->pixel_top = m->top_line * FRAME_LINE_HEIGHT (f);
       m->total_cols = FRAME_COLS (f);
       m->pixel_width = m->total_cols * FRAME_COLUMN_WIDTH (f);
@@ -30989,7 +31219,38 @@ init_xdisp (void)
 
 /* Platform-independent portion of hourglass implementation.  */
 
+/* Timer function of hourglass_atimer.  */
+
+static void
+show_hourglass (struct atimer *timer)
+{
+  /* The timer implementation will cancel this timer automatically
+     after this function has run.  Set hourglass_atimer to null
+     so that we know the timer doesn't have to be canceled.  */
+  hourglass_atimer = NULL;
+
+  if (!hourglass_shown_p)
+    {
+      Lisp_Object tail, frame;
+
+      block_input ();
+
+      FOR_EACH_FRAME (tail, frame)
+       {
+         struct frame *f = XFRAME (frame);
+
+         if (FRAME_LIVE_P (f) && FRAME_WINDOW_P (f)
+             && FRAME_RIF (f)->show_hourglass)
+           FRAME_RIF (f)->show_hourglass (f);
+       }
+
+      hourglass_shown_p = 1;
+      unblock_input ();
+    }
+}
+
 /* Cancel a currently active hourglass timer, and start a new one.  */
+
 void
 start_hourglass (void)
 {
@@ -31008,20 +31269,13 @@ start_hourglass (void)
   else
     delay = make_timespec (DEFAULT_HOURGLASS_DELAY, 0);
 
-#ifdef HAVE_NTGUI
-  {
-    extern void w32_note_current_window (void);
-    w32_note_current_window ();
-  }
-#endif /* HAVE_NTGUI */
-
   hourglass_atimer = start_atimer (ATIMER_RELATIVE, delay,
                                   show_hourglass, NULL);
 }
 
-
 /* Cancel the hourglass cursor timer if active, hide a busy cursor if
    shown.  */
+
 void
 cancel_hourglass (void)
 {
@@ -31032,7 +31286,28 @@ cancel_hourglass (void)
     }
 
   if (hourglass_shown_p)
-    hide_hourglass ();
+    {
+      Lisp_Object tail, frame;
+
+      block_input ();
+
+      FOR_EACH_FRAME (tail, frame)
+       {
+         struct frame *f = XFRAME (frame);
+
+         if (FRAME_LIVE_P (f) && FRAME_WINDOW_P (f)
+             && FRAME_RIF (f)->hide_hourglass)
+           FRAME_RIF (f)->hide_hourglass (f);
+#ifdef HAVE_NTGUI
+         /* No cursors on non GUI frames - restore to stock arrow cursor.  */
+         else if (!FRAME_W32_P (f))
+           w32_arrow_cursor ();
+#endif
+       }
+
+      hourglass_shown_p = 0;
+      unblock_input ();
+    }
 }
 
 #endif /* HAVE_WINDOW_SYSTEM */