]> code.delx.au - gnu-emacs/blobdiff - src/xdisp.c
Backport 2010-04-10T10:52:30Z!mituharu@math.s.chiba-u.ac.jp from trunk
[gnu-emacs] / src / xdisp.c
index a750a1b73b5e3315207cc2382d663a991a6ce5c1..a416c8ff43504441b7930812b0fbb9f11d4830f6 100644 (file)
@@ -1,7 +1,8 @@
 /* Display generation from window structure and buffer text.
    Copyright (C) 1985, 1986, 1987, 1988, 1993, 1994, 1995,
                  1997, 1998, 1999, 2000, 2001, 2002, 2003,
-                 2004, 2005, 2006, 2007, 2008, 2009 Free Software Foundation, Inc.
+                 2004, 2005, 2006, 2007, 2008, 2009, 2010
+                 Free Software Foundation, Inc.
 
 This file is part of GNU Emacs.
 
@@ -168,6 +169,7 @@ along with GNU Emacs.  If not, see <http://www.gnu.org/licenses/>.  */
 #include <config.h>
 #include <stdio.h>
 #include <limits.h>
+#include <setjmp.h>
 
 #include "lisp.h"
 #include "keyboard.h"
@@ -918,7 +920,7 @@ static int display_echo_area P_ ((struct window *));
 static int display_echo_area_1 P_ ((EMACS_INT, Lisp_Object, EMACS_INT, EMACS_INT));
 static int resize_mini_window_1 P_ ((EMACS_INT, Lisp_Object, EMACS_INT, EMACS_INT));
 static Lisp_Object unwind_redisplay P_ ((Lisp_Object));
-static int string_char_and_length P_ ((const unsigned char *, int, int *));
+static int string_char_and_length P_ ((const unsigned char *, int *));
 static struct text_pos display_prop_end P_ ((struct it *, Lisp_Object,
                                             struct text_pos));
 static int compute_window_start_on_continuation_line P_ ((struct window *));
@@ -952,7 +954,8 @@ static int display_mode_lines P_ ((struct window *));
 static int display_mode_line P_ ((struct window *, enum face_id, Lisp_Object));
 static int display_mode_element P_ ((struct it *, int, int, int, Lisp_Object, Lisp_Object, int));
 static int store_mode_line_string P_ ((char *, Lisp_Object, int, int, int, Lisp_Object));
-static char *decode_mode_spec P_ ((struct window *, int, int, int, int *));
+static char *decode_mode_spec P_ ((struct window *, int, int, int,
+                                  Lisp_Object *));
 static void display_menu_bar P_ ((struct window *));
 static int display_count_lines P_ ((int, int, int, int, int *));
 static int display_string P_ ((unsigned char *, Lisp_Object, Lisp_Object,
@@ -1362,7 +1365,7 @@ pos_visible_p (w, charpos, x, y, rtop, rbot, rowh, vpos)
       int top_x = it.current_x;
       int top_y = it.current_y;
       enum it_method it_method = it.method;
-      /* Calling line_bottom_y may change it.method.  */
+      /* Calling line_bottom_y may change it.method, it.position, etc.  */
       int bottom_y = (last_height = 0, line_bottom_y (&it));
       int window_top_y = WINDOW_HEADER_LINE_HEIGHT (w);
 
@@ -1372,33 +1375,7 @@ pos_visible_p (w, charpos, x, y, rtop, rbot, rowh, vpos)
        visible_p = 1;
       if (visible_p)
        {
-         if (it_method == GET_FROM_BUFFER)
-           {
-             Lisp_Object window, prop;
-
-             XSETWINDOW (window, w);
-             prop = Fget_char_property (make_number (it.position.charpos),
-                                        Qinvisible, window);
-
-             /* If charpos coincides with invisible text covered with an
-                ellipsis, use the first glyph of the ellipsis to compute
-                the pixel positions.  */
-             if (TEXT_PROP_MEANS_INVISIBLE (prop) == 2)
-               {
-                 struct glyph_row *row = it.glyph_row;
-                 struct glyph *glyph = row->glyphs[TEXT_AREA];
-                 struct glyph *end = glyph + row->used[TEXT_AREA];
-                 int x = row->x;
-
-                 for (; glyph < end
-                        && (!BUFFERP (glyph->object)
-                            || glyph->charpos < charpos);
-                      glyph++)
-                   x += glyph->pixel_width;
-                 top_x = x;
-               }
-           }
-         else if (it_method == GET_FROM_DISPLAY_VECTOR)
+         if (it_method == GET_FROM_DISPLAY_VECTOR)
            {
              /* We stopped on the last glyph of a display vector.
                 Try and recompute.  Hack alert!  */
@@ -1484,13 +1461,13 @@ pos_visible_p (w, charpos, x, y, rtop, rbot, rowh, vpos)
    character.  */
 
 static INLINE int
-string_char_and_length (str, maxlen, len)
+string_char_and_length (str, len)
      const unsigned char *str;
-     int maxlen, *len;
+     int *len;
 {
   int c;
 
-  c = STRING_CHAR_AND_LENGTH (str, maxlen, *len);
+  c = STRING_CHAR_AND_LENGTH (str, *len);
   if (!CHAR_VALID_P (c, 1))
     /* We may not change the length here because other places in Emacs
        don't use this function, i.e. they silently accept invalid
@@ -1521,7 +1498,7 @@ string_pos_nchars_ahead (pos, string, nchars)
 
       while (nchars--)
        {
-         string_char_and_length (p, rest, &len);
+         string_char_and_length (p, &len);
          p += len, rest -= len;
          xassert (rest >= 0);
          CHARPOS (pos) += 1;
@@ -1573,7 +1550,7 @@ c_string_pos (charpos, s, multibyte_p)
       SET_TEXT_POS (pos, 0, 0);
       while (charpos--)
        {
-         string_char_and_length (s, rest, &len);
+         string_char_and_length (s, &len);
          s += len, rest -= len;
          xassert (rest >= 0);
          CHARPOS (pos) += 1;
@@ -1604,7 +1581,7 @@ number_of_chars (s, multibyte_p)
 
       for (nchars = 0; rest > 0; ++nchars)
        {
-         string_char_and_length (p, rest, &len);
+         string_char_and_length (p, &len);
          rest -= len, p += len;
        }
     }
@@ -1980,12 +1957,6 @@ get_glyph_string_clip_rects (s, rects, n)
        r.y = WINDOW_HEADER_LINE_HEIGHT (s->w);
       else
        r.y = max (0, s->row->y);
-
-      /* If drawing a tool-bar window, draw it over the internal border
-        at the top of the window.  */
-      if (WINDOWP (s->f->tool_bar_window)
-         && s->w == XWINDOW (s->f->tool_bar_window))
-       r.y -= FRAME_INTERNAL_BORDER_WIDTH (s->f);
     }
 
   r.y = WINDOW_TO_FRAME_PIXEL_Y (s->w, r.y);
@@ -3647,7 +3618,7 @@ face_before_or_after_it_pos (it, before_p)
          int c, len;
          struct face *face = FACE_FROM_ID (it->f, face_id);
 
-         c = string_char_and_length (p, rest, &len);
+         c = string_char_and_length (p, &len);
          face_id = FACE_FOR_CHAR (it->f, face, c, CHARPOS (pos), it->string);
        }
     }
@@ -4649,7 +4620,7 @@ handle_composition_prop (it)
       pos_byte = IT_STRING_BYTEPOS (*it);
       string = it->string;
       s = SDATA (string) + pos_byte;
-      it->c = STRING_CHAR (s, 0);
+      it->c = STRING_CHAR (s);
     }
   else
     {
@@ -5612,6 +5583,14 @@ reseat_to_string (it, s, string, charpos, precision, field_width, multibyte)
     it->dp = XCHAR_TABLE (Vstandard_display_table);
 
   it->stop_charpos = charpos;
+  if (s == NULL && it->multibyte_p)
+    {
+      EMACS_INT endpos = SCHARS (it->string);
+      if (endpos > it->end_charpos)
+       endpos = it->end_charpos;
+      composition_compute_stop_pos (&it->cmp_it, charpos, -1, endpos,
+                                   it->string);
+    }
   CHECK_IT (it);
 }
 
@@ -5639,11 +5618,11 @@ static int (* get_next_element[NUM_IT_METHODS]) P_ ((struct it *it)) =
 /* Return 1 iff a character at CHARPOS (and BYTEPOS) is composed
    (possibly with the following characters).  */
 
-#define CHAR_COMPOSED_P(IT,CHARPOS,BYTEPOS)                            \
+#define CHAR_COMPOSED_P(IT,CHARPOS,BYTEPOS,END_CHARPOS)                        \
   ((IT)->cmp_it.id >= 0                                                        \
    || ((IT)->cmp_it.stop_pos == (CHARPOS)                              \
        && composition_reseat_it (&(IT)->cmp_it, CHARPOS, BYTEPOS,      \
-                                (IT)->end_charpos, (IT)->w,            \
+                                END_CHARPOS, (IT)->w,                  \
                                 FACE_FROM_ID ((IT)->f, (IT)->face_id), \
                                 (IT)->string)))
 
@@ -5685,11 +5664,24 @@ get_next_display_element (it)
          Lisp_Object dv;
          struct charset *unibyte = CHARSET_FROM_ID (charset_unibyte);
          enum { char_is_other = 0, char_is_nbsp, char_is_soft_hyphen }
-              nbsp_or_shy = char_is_other;
-         int decoded = it->c;
+         nbsp_or_shy = char_is_other;
+         int c = it->c;        /* This is the character to display.  */
+
+         if (! it->multibyte_p && ! ASCII_CHAR_P (c))
+           {
+             xassert (SINGLE_BYTE_CHAR_P (c));
+             if (unibyte_display_via_language_environment)
+               {
+                 c = DECODE_CHAR (unibyte, c);
+                 if (c < 0)
+                   c = BYTE8_TO_CHAR (it->c);
+               }
+             else
+               c = BYTE8_TO_CHAR (it->c);
+           }
 
          if (it->dp
-             && (dv = DISP_CHAR_VECTOR (it->dp, it->c),
+             && (dv = DISP_CHAR_VECTOR (it->dp, c),
                  VECTORP (dv)))
            {
              struct Lisp_Vector *v = XVECTOR (dv);
@@ -5715,21 +5707,10 @@ get_next_display_element (it)
              goto get_next;
            }
 
-         if (unibyte_display_via_language_environment
-             && !ASCII_CHAR_P (it->c))
-           decoded = DECODE_CHAR (unibyte, it->c);
-
-         if (it->c >= 0x80 && ! NILP (Vnobreak_char_display))
-           {
-             if (it->multibyte_p)
-               nbsp_or_shy = (it->c == 0xA0   ? char_is_nbsp
-                              : it->c == 0xAD ? char_is_soft_hyphen
-                              :                 char_is_other);
-             else if (unibyte_display_via_language_environment)
-               nbsp_or_shy = (decoded == 0xA0   ? char_is_nbsp
-                              : decoded == 0xAD ? char_is_soft_hyphen
-                              :                   char_is_other);
-           }
+         if (! ASCII_CHAR_P (c) && ! NILP (Vnobreak_char_display))
+           nbsp_or_shy = (c == 0xA0   ? char_is_nbsp
+                          : c == 0xAD ? char_is_soft_hyphen
+                          :             char_is_other);
 
          /* Translate control characters into `\003' or `^C' form.
             Control characters coming from a display table entry are
@@ -5737,27 +5718,23 @@ get_next_display_element (it)
             the translation.  This could easily be changed but I
             don't believe that it is worth doing.
 
-            If it->multibyte_p is nonzero, non-printable non-ASCII
-            characters are also translated to octal form.
+            NBSP and SOFT-HYPEN are property translated too.
 
-            If it->multibyte_p is zero, eight-bit characters that
-            don't have corresponding multibyte char code are also
+            Non-printable characters and raw-byte characters are also
             translated to octal form.  */
-         if ((it->c < ' '
+         if (((c < ' ' || c == 127) /* ASCII control chars */
               ? (it->area != TEXT_AREA
                  /* In mode line, treat \n, \t like other crl chars.  */
-                 || (it->c != '\t'
+                 || (c != '\t'
                      && it->glyph_row
                      && (it->glyph_row->mode_line_p || it->avoid_cursor_p))
-                 || (it->c != '\n' && it->c != '\t'))
+                 || (c != '\n' && c != '\t'))
               : (nbsp_or_shy
-                 || (it->multibyte_p
-                     ? ! CHAR_PRINTABLE_P (it->c)
-                     : (! unibyte_display_via_language_environment
-                        ? it->c >= 0x80
-                        : (decoded >= 0x80 && decoded < 0xA0))))))
+                 || CHAR_BYTE8_P (c)
+                 || ! CHAR_PRINTABLE_P (c))))
            {
-             /* IT->c is a control character which must be displayed
+             /* C is a control character, NBSP, SOFT-HYPEN, raw-byte,
+                or a non-printable character which must be displayed
                 either as '\003' or as `^C' where the '\\' and '^'
                 can be defined in the display table.  Fill
                 IT->ctl_chars with glyphs for what we have to
@@ -5769,7 +5746,7 @@ get_next_display_element (it)
 
              /* Handle control characters with ^.  */
 
-             if (it->c < 128 && it->ctl_arrow_p)
+             if (ASCII_CHAR_P (c) && it->ctl_arrow_p)
                {
                  int g;
 
@@ -5802,7 +5779,7 @@ get_next_display_element (it)
                    }
 
                  XSETINT (it->ctl_chars[0], g);
-                 XSETINT (it->ctl_chars[1], it->c ^ 0100);
+                 XSETINT (it->ctl_chars[1], c ^ 0100);
                  ctl_len = 2;
                  goto display_control;
                }
@@ -5817,7 +5794,7 @@ get_next_display_element (it)
                  face_id = merge_faces (it->f, Qnobreak_space, 0,
                                         it->face_id);
 
-                 it->c = ' ';
+                 c = ' ';
                  XSETINT (it->ctl_chars[0], ' ');
                  ctl_len = 1;
                  goto display_control;
@@ -5863,7 +5840,6 @@ get_next_display_element (it)
              if (EQ (Vnobreak_char_display, Qt)
                  && nbsp_or_shy == char_is_soft_hyphen)
                {
-                 it->c = '-';
                  XSETINT (it->ctl_chars[0], '-');
                  ctl_len = 1;
                  goto display_control;
@@ -5875,55 +5851,25 @@ get_next_display_element (it)
              if (nbsp_or_shy)
                {
                  XSETINT (it->ctl_chars[0], escape_glyph);
-                 it->c = (nbsp_or_shy == char_is_nbsp ? ' ' : '-');
-                 XSETINT (it->ctl_chars[1], it->c);
+                 c = (nbsp_or_shy == char_is_nbsp ? ' ' : '-');
+                 XSETINT (it->ctl_chars[1], c);
                  ctl_len = 2;
                  goto display_control;
                }
 
              {
-               unsigned char str[MAX_MULTIBYTE_LENGTH];
-               int len;
-               int i;
+               char str[10];
+               int len, i;
 
-               /* Set IT->ctl_chars[0] to the glyph for `\\'.  */
-               if (CHAR_BYTE8_P (it->c))
-                 {
-                   str[0] = CHAR_TO_BYTE8 (it->c);
-                   len = 1;
-                 }
-               else if (it->c < 256)
-                 {
-                   str[0] = it->c;
-                   len = 1;
-                 }
-               else
-                 {
-                   /* It's an invalid character, which shouldn't
-                      happen actually, but due to bugs it may
-                      happen.  Let's print the char as is, there's
-                      not much meaningful we can do with it.  */
-                     str[0] = it->c;
-                     str[1] = it->c >> 8;
-                     str[2] = it->c >> 16;
-                     str[3] = it->c >> 24;
-                     len = 4;
-                   }
+               if (CHAR_BYTE8_P (c))
+                 /* Display \200 instead of \17777600.  */
+                 c = CHAR_TO_BYTE8 (c);
+               len = sprintf (str, "%03o", c);
 
+               XSETINT (it->ctl_chars[0], escape_glyph);
                for (i = 0; i < len; i++)
-                 {
-                   int g;
-                   XSETINT (it->ctl_chars[i * 4], escape_glyph);
-                   /* Insert three more glyphs into IT->ctl_chars for
-                      the octal display of the character.  */
-                   g = ((str[i] >> 6) & 7) + '0';
-                   XSETINT (it->ctl_chars[i * 4 + 1], g);
-                   g = ((str[i] >> 3) & 7) + '0';
-                   XSETINT (it->ctl_chars[i * 4 + 2], g);
-                   g = (str[i] & 7) + '0';
-                   XSETINT (it->ctl_chars[i * 4 + 3], g);
-                 }
-               ctl_len = len * 4;
+                 XSETINT (it->ctl_chars[i + 1], str[i]);
+               ctl_len = len + 1;
              }
 
            display_control:
@@ -5938,6 +5884,11 @@ get_next_display_element (it)
              it->ellipsis_p = 0;
              goto get_next;
            }
+         it->char_to_display = c;
+       }
+      else if (success_p)
+       {
+         it->char_to_display = it->c;
        }
     }
 
@@ -5964,7 +5915,8 @@ get_next_display_element (it)
                     : STRINGP (it->string) ? IT_STRING_CHARPOS (*it)
                     : IT_CHARPOS (*it));
 
-         it->face_id = FACE_FOR_CHAR (it->f, face, it->c, pos, it->string);
+         it->face_id = FACE_FOR_CHAR (it->f, face, it->char_to_display, pos,
+                                      it->string);
        }
     }
 #endif
@@ -6216,8 +6168,8 @@ set_iterator_to_next (it, reseat_p)
    or `\003'.
 
    IT->dpvec holds the glyphs to return as characters.
-   IT->saved_face_id holds the face id before the display vector--
-   it is restored into IT->face_idin set_iterator_to_next.  */
+   IT->saved_face_id holds the face id before the display vector--it
+   is restored into IT->face_id in set_iterator_to_next.  */
 
 static int
 next_element_from_display_vector (it)
@@ -6301,7 +6253,7 @@ next_element_from_string (it)
          return 0;
        }
       else if (CHAR_COMPOSED_P (it, IT_STRING_CHARPOS (*it),
-                               IT_STRING_BYTEPOS (*it))
+                               IT_STRING_BYTEPOS (*it), SCHARS (it->string))
               && next_element_from_composition (it))
        {
          return 1;
@@ -6311,7 +6263,7 @@ next_element_from_string (it)
          int remaining = SBYTES (it->string) - IT_STRING_BYTEPOS (*it);
          const unsigned char *s = (SDATA (it->string)
                                    + IT_STRING_BYTEPOS (*it));
-         it->c = string_char_and_length (s, remaining, &it->len);
+         it->c = string_char_and_length (s, &it->len);
        }
       else
        {
@@ -6337,7 +6289,7 @@ next_element_from_string (it)
          CHARPOS (position) = BYTEPOS (position) = -1;
        }
       else if (CHAR_COMPOSED_P (it, IT_STRING_CHARPOS (*it),
-                               IT_STRING_BYTEPOS (*it))
+                               IT_STRING_BYTEPOS (*it), it->string_nchars)
               && next_element_from_composition (it))
        {
          return 1;
@@ -6347,7 +6299,7 @@ next_element_from_string (it)
          int maxlen = SBYTES (it->string) - IT_STRING_BYTEPOS (*it);
          const unsigned char *s = (SDATA (it->string)
                                    + IT_STRING_BYTEPOS (*it));
-         it->c = string_char_and_length (s, maxlen, &it->len);
+         it->c = string_char_and_length (s, &it->len);
        }
       else
        {
@@ -6403,8 +6355,7 @@ next_element_from_c_string (it)
         performance problem because there is no noticeable performance
         difference between Emacs running in unibyte or multibyte mode.  */
       int maxlen = strlen (it->s) - IT_BYTEPOS (*it);
-      it->c = string_char_and_length (it->s + IT_BYTEPOS (*it),
-                                     maxlen, &it->len);
+      it->c = string_char_and_length (it->s + IT_BYTEPOS (*it), &it->len);
     }
   else
     it->c = it->s[IT_BYTEPOS (*it)], it->len = 1;
@@ -6415,7 +6366,7 @@ next_element_from_c_string (it)
 
 /* Set up IT to return characters from an ellipsis, if appropriate.
    The definition of the ellipsis glyphs may come from a display table
-   entry.  This function Fills IT with the first glyph from the
+   entry.  This function fills IT with the first glyph from the
    ellipsis if an ellipsis is to be displayed.  */
 
 static int
@@ -6451,6 +6402,7 @@ next_element_from_image (it)
      struct it *it;
 {
   it->what = IT_IMAGE;
+  it->ignore_overlay_strings_at_pos_p = 0;
   return 1;
 }
 
@@ -6525,7 +6477,8 @@ next_element_from_buffer (it)
          && IT_CHARPOS (*it) >= it->redisplay_end_trigger_charpos)
        run_redisplay_end_trigger_hook (it);
 
-      if (CHAR_COMPOSED_P (it, IT_CHARPOS (*it), IT_BYTEPOS (*it))
+      if (CHAR_COMPOSED_P (it, IT_CHARPOS (*it), IT_BYTEPOS (*it),
+                          it->end_charpos)
          && next_element_from_composition (it))
        {
          return 1;
@@ -6534,7 +6487,7 @@ next_element_from_buffer (it)
       /* Get the next character, maybe multibyte.  */
       p = BYTE_POS_ADDR (IT_BYTEPOS (*it));
       if (it->multibyte_p && !ASCII_BYTE_P (*p))
-       it->c = STRING_CHAR_AND_LENGTH (p, 0, it->len);
+       it->c = STRING_CHAR_AND_LENGTH (p, it->len);
       else
        it->c = *p, it->len = 1;
 
@@ -7755,7 +7708,7 @@ message_dolog (m, nbytes, nlflag, multibyte)
             for the *Message* buffer.  */
          for (i = 0; i < nbytes; i += char_bytes)
            {
-             c = string_char_and_length (m + i, nbytes - i, &char_bytes);
+             c = string_char_and_length (m + i, &char_bytes);
              work[0] = (ASCII_CHAR_P (c)
                         ? c
                         : multibyte_char_to_unibyte (c, Qnil));
@@ -9060,7 +9013,7 @@ set_message_1 (a1, a2, nbytes, multibyte_p)
          /* Convert a multibyte string to single-byte.  */
          for (i = 0; i < nbytes; i += n)
            {
-             c = string_char_and_length (s + i, nbytes - i, &n);
+             c = string_char_and_length (s + i, &n);
              work[0] = (ASCII_CHAR_P (c)
                         ? c
                         : multibyte_char_to_unibyte (c, Qnil));
@@ -9493,32 +9446,7 @@ x_consider_frame_title (frame)
       if (! STRINGP (f->name)
          || SBYTES (f->name) != len
          || bcmp (title, SDATA (f->name), len) != 0)
-        {
-#ifdef HAVE_NS
-          if (FRAME_NS_P (f))
-            {
-              if (!MINI_WINDOW_P(XWINDOW(f->selected_window)))
-                {
-                  if (EQ (fmt, Qt))
-                    ns_set_name_as_filename (f);
-                  else
-                    x_implicitly_set_name (f, make_string(title, len),
-                                           Qnil);
-                }
-            }
-          else
-#endif
-           x_implicitly_set_name (f, make_string (title, len), Qnil);
-        }
-#ifdef HAVE_NS
-      if (FRAME_NS_P (f))
-        {
-          /* do this also for frames with explicit names */
-          ns_implicitly_set_icon_type(f);
-          ns_set_doc_edited(f, Fbuffer_modified_p
-                            (XWINDOW (f->selected_window)->buffer), Qnil);
-        }
-#endif
+       x_implicitly_set_name (f, make_string (title, len), Qnil);
     }
 }
 
@@ -9614,6 +9542,12 @@ prepare_menu_bars ()
          menu_bar_hooks_run = update_menu_bar (f, 0, menu_bar_hooks_run);
 #ifdef HAVE_WINDOW_SYSTEM
          update_tool_bar (f, 0);
+#endif
+#ifdef HAVE_NS
+          if (windows_or_buffers_changed
+             && FRAME_NS_P (f))
+            ns_set_doc_edited (f, Fbuffer_modified_p
+                              (XWINDOW (f->selected_window)->buffer));
 #endif
          UNGCPRO;
        }
@@ -13643,7 +13577,7 @@ redisplay_window (window, just_this_one_p)
               = try_window_reusing_current_matrix (w)))
        {
          IF_DEBUG (debug_method_add (w, "1"));
-         if (try_window (window, startp, 1) < 0)
+         if (try_window (window, startp, TRY_WINDOW_CHECK_MARGINS) < 0)
            /* -1 means we need to scroll.
               0 means we need new matrices, but fonts_changed_p
               is set in that case, so we will detect it below.  */
@@ -13976,8 +13910,16 @@ redisplay_window (window, just_this_one_p)
         (*FRAME_TERMINAL (f)->redeem_scroll_bar_hook) (w);
     }
 
-  /* Restore current_buffer and value of point in it.  */
-  TEMP_SET_PT_BOTH (CHARPOS (opoint), BYTEPOS (opoint));
+  /* Restore current_buffer and value of point in it.  The window
+     update may have changed the buffer, so first make sure `opoint'
+     is still valid (Bug#6177).  */
+  if (CHARPOS (opoint) < BEGV)
+    TEMP_SET_PT_BOTH (BEGV, BEGV_BYTE);
+  else if (CHARPOS (opoint) > ZV)
+    TEMP_SET_PT_BOTH (Z, Z_BYTE);
+  else
+    TEMP_SET_PT_BOTH (CHARPOS (opoint), BYTEPOS (opoint));
+
   set_buffer_internal_1 (old);
   /* Avoid an abort in TEMP_SET_PT_BOTH if the buffer has become
      shorter.  This can be caused by log truncation in *Messages*. */
@@ -13994,13 +13936,15 @@ redisplay_window (window, just_this_one_p)
    Value is 1 if successful.  It is zero if fonts were loaded during
    redisplay which makes re-adjusting glyph matrices necessary, and -1
    if point would appear in the scroll margins.
-   (We check that only if CHECK_MARGINS is nonzero.  */
+   (We check the former only if TRY_WINDOW_IGNORE_FONTS_CHANGE is
+   unset in FLAGS, and the latter only if TRY_WINDOW_CHECK_MARGINS is
+   set in FLAGS.)  */
 
 int
-try_window (window, pos, check_margins)
+try_window (window, pos, flags)
      Lisp_Object window;
      struct text_pos pos;
-     int check_margins;
+     int flags;
 {
   struct window *w = XWINDOW (window);
   struct it it;
@@ -14022,12 +13966,12 @@ try_window (window, pos, check_margins)
     {
       if (display_line (&it))
        last_text_row = it.glyph_row - 1;
-      if (fonts_changed_p)
+      if (fonts_changed_p && !(flags & TRY_WINDOW_IGNORE_FONTS_CHANGE))
        return 0;
     }
 
   /* Don't let the cursor end in the scroll margins.  */
-  if (check_margins
+  if ((flags & TRY_WINDOW_CHECK_MARGINS)
       && !MINI_WINDOW_P (w))
     {
       int this_scroll_margin;
@@ -15902,15 +15846,19 @@ get_overlay_arrow_glyph_row (w, overlay_arrow_string)
 
       /* Get the next character.  */
       if (multibyte_p)
-       it.c = string_char_and_length (p, arrow_len, &it.len);
+       it.c = it.char_to_display = string_char_and_length (p, &it.len);
       else
-       it.c = *p, it.len = 1;
+       {
+         it.c = it.char_to_display = *p, it.len = 1;
+         if (! ASCII_CHAR_P (it.c))
+           it.char_to_display = BYTE8_TO_CHAR (it.c);
+       }
       p += it.len;
 
       /* Get its face.  */
       ilisp = make_number (p - arrow_string);
       face = Fget_text_property (ilisp, Qface, overlay_arrow_string);
-      it.face_id = compute_char_face (f, it.c, face);
+      it.face_id = compute_char_face (f, it.char_to_display, face);
 
       /* Compute its width, get its glyphs.  */
       n_glyphs_before = it.glyph_row->used[TEXT_AREA];
@@ -16109,6 +16057,7 @@ append_space_for_newline (it, default_face_p)
             append_space_for_newline has been called.  */
          enum display_element_type saved_what = it->what;
          int saved_c = it->c, saved_len = it->len;
+         int saved_char_to_display = it->char_to_display;
          int saved_x = it->current_x;
          int saved_face_id = it->face_id;
          struct text_pos saved_pos;
@@ -16121,7 +16070,7 @@ append_space_for_newline (it, default_face_p)
          it->what = IT_CHARACTER;
          bzero (&it->position, sizeof it->position);
          it->object = make_number (0);
-         it->c = ' ';
+         it->c = it->char_to_display = ' ';
          it->len = 1;
 
          if (default_face_p)
@@ -16142,6 +16091,7 @@ append_space_for_newline (it, default_face_p)
          it->face_id = saved_face_id;
          it->len = saved_len;
          it->c = saved_c;
+         it->char_to_display = saved_char_to_display;
          return 1;
        }
     }
@@ -16221,7 +16171,7 @@ extend_face_to_end_of_line (it)
       it->what = IT_CHARACTER;
       bzero (&it->position, sizeof it->position);
       it->object = make_number (0);
-      it->c = ' ';
+      it->c = it->char_to_display = ' ';
       it->len = 1;
       it->face_id = face->id;
 
@@ -16384,22 +16334,20 @@ cursor_row_p (w, row)
 \f
 
 /* Push the display property PROP so that it will be rendered at the
-   current position in IT.  */
+   current position in IT.  Return 1 if PROP was successfully pushed,
+   0 otherwise.  */
 
-static void
+static int
 push_display_prop (struct it *it, Lisp_Object prop)
 {
   push_it (it);
 
-  /* Never display a cursor on the prefix.  */
-  it->avoid_cursor_p = 1;
-
   if (STRINGP (prop))
     {
       if (SCHARS (prop) == 0)
        {
          pop_it (it);
-         return;
+         return 0;
        }
 
       it->string = prop;
@@ -16426,8 +16374,10 @@ push_display_prop (struct it *it, Lisp_Object prop)
   else
     {
       pop_it (it);             /* bogus display property, give up */
-      return;
+      return 0;
     }
+
+  return 1;
 }
 
 /* Return the character-property PROP at the current position in IT.  */
@@ -16467,13 +16417,13 @@ handle_line_prefix (struct it *it)
       if (NILP (prefix))
        prefix = Vline_prefix;
     }
-  if (! NILP (prefix))
+  if (! NILP (prefix) && push_display_prop (it, prefix))
     {
-      push_display_prop (it, prefix);
       /* If the prefix is wider than the window, and we try to wrap
         it, it would acquire its own wrap prefix, and so on till the
         iterator stack overflows.  So, don't wrap the prefix.  */
       it->line_wrap = TRUNCATE;
+      it->avoid_cursor_p = 1;
     }
 }
 
@@ -17582,13 +17532,14 @@ display_mode_element (it, depth, field_width, precision, elt, props, risky)
                    int multibyte;
                    int bytepos, charpos;
                    unsigned char *spec;
+                   Lisp_Object string;
 
                    bytepos = percent_position;
                    charpos = (STRING_MULTIBYTE (elt)
                               ? string_byte_to_char (elt, bytepos)
                               : bytepos);
-                   spec
-                     = decode_mode_spec (it->w, c, field, prec, &multibyte);
+                   spec = decode_mode_spec (it->w, c, field, prec, &string);
+                   multibyte = STRINGP (string) && STRING_MULTIBYTE (string);
 
                    switch (mode_line_target)
                      {
@@ -17610,7 +17561,7 @@ display_mode_element (it, depth, field_width, precision, elt, props, risky)
                          int nglyphs_before, nwritten;
 
                          nglyphs_before = it->glyph_row->used[TEXT_AREA];
-                         nwritten = display_string (spec, Qnil, elt,
+                         nwritten = display_string (spec, string, elt,
                                                     charpos, 0, it,
                                                     field, prec, 0,
                                                     multibyte);
@@ -18273,8 +18224,8 @@ decode_mode_spec_coding (coding_system, buf, eol_flag)
 /* Return a string for the output of a mode line %-spec for window W,
    generated by character C.  PRECISION >= 0 means don't return a
    string longer than that value.  FIELD_WIDTH > 0 means pad the
-   string returned with spaces to that value.  Return 1 in *MULTIBYTE
-   if the result is multibyte text.
+   string returned with spaces to that value.  Return a Lisp string in
+   *STRING if the resulting string is taken from that Lisp string.
 
    Note we operate on the current buffer for most purposes,
    the exception being w->base_line_pos.  */
@@ -18282,11 +18233,11 @@ decode_mode_spec_coding (coding_system, buf, eol_flag)
 static char lots_of_dashes[] = "--------------------------------------------------------------------------------------------------------------------------------------------";
 
 static char *
-decode_mode_spec (w, c, field_width, precision, multibyte)
+decode_mode_spec (w, c, field_width, precision, string)
      struct window *w;
      register int c;
      int field_width, precision;
-     int *multibyte;
+     Lisp_Object *string;
 {
   Lisp_Object obj;
   struct frame *f = XFRAME (WINDOW_FRAME (w));
@@ -18294,7 +18245,7 @@ decode_mode_spec (w, c, field_width, precision, multibyte)
   struct buffer *b = current_buffer;
 
   obj = Qnil;
-  *multibyte = 0;
+  *string = Qnil;
 
   switch (c)
     {
@@ -18629,8 +18580,11 @@ decode_mode_spec (w, c, field_width, precision, multibyte)
 
     case '@':
       {
-       Lisp_Object val;
-       val = call1 (intern ("file-remote-p"), current_buffer->directory);
+       int count = inhibit_garbage_collection ();
+       Lisp_Object val = call1 (intern ("file-remote-p"),
+                                current_buffer->directory);
+       unbind_to (count, Qnil);
+
        if (NILP (val))
          return "-";
        else
@@ -18685,7 +18639,7 @@ decode_mode_spec (w, c, field_width, precision, multibyte)
 
   if (STRINGP (obj))
     {
-      *multibyte = STRING_MULTIBYTE (obj);
+      *string = obj;
       return (char *) SDATA (obj);
     }
   else
@@ -18806,7 +18760,10 @@ display_count_lines (start, start_byte, limit_byte, count, byte_pos_ptr)
 /* Display a NUL-terminated string, starting with index START.
 
    If STRING is non-null, display that C string.  Otherwise, the Lisp
-   string LISP_STRING is displayed.
+   string LISP_STRING is displayed.  There's a case that STRING is
+   non-null and LISP_STRING is not nil.  It means STRING is a string
+   data of LISP_STRING.  In that case, we display LISP_STRING while
+   ignoring its text properties.
 
    If FACE_STRING is not nil, FACE_STRING_POS is a position in
    FACE_STRING.  Display STRING or LISP_STRING with the face at
@@ -18856,8 +18813,12 @@ display_string (string, lisp_string, face_string, face_string_pos,
 
   /* Initialize the iterator IT for iteration over STRING beginning
      with index START.  */
-  reseat_to_string (it, string, lisp_string, start,
+  reseat_to_string (it, NILP (lisp_string) ? string : NULL, lisp_string, start,
                    precision, field_width, multibyte);
+  if (string && STRINGP (lisp_string)) 
+    /* LISP_STRING is the one returned by decode_mode_spec.  We should
+       ignore its text properties.  */
+    it->stop_charpos = -1;
 
   /* If displaying STRING, set up the face of the iterator
      from LISP_STRING, if that's given.  */
@@ -19421,12 +19382,6 @@ init_glyph_string (s, OPTIONAL_HDC (hdc) char2b, w, row, area, start, hl)
   s->first_glyph = row->glyphs[area] + start;
   s->height = row->height;
   s->y = WINDOW_TO_FRAME_PIXEL_Y (w, row->y);
-
-  /* Display the internal border below the tool-bar window.  */
-  if (WINDOWP (s->f->tool_bar_window)
-      && s->w == XWINDOW (s->f->tool_bar_window))
-    s->y -= FRAME_INTERNAL_BORDER_WIDTH (s->f);
-
   s->ybase = s->y + row->ascent;
 }
 
@@ -19545,7 +19500,12 @@ get_glyph_face_and_encoding (f, glyph, char2b, two_byte_p)
 
   if (face->font)
     {
-      unsigned code = face->font->driver->encode_char (face->font, glyph->u.ch);
+      unsigned code;
+
+      if (CHAR_BYTE8_P (glyph->u.ch))
+       code = CHAR_TO_BYTE8 (glyph->u.ch);
+      else
+       code = face->font->driver->encode_char (face->font, glyph->u.ch);
 
       if (code != FONT_INVALID_CODE)
        STORE_XCHAR2B (char2b, (code >> 8), (code & 0xFF));
@@ -19560,6 +19520,26 @@ get_glyph_face_and_encoding (f, glyph, char2b, two_byte_p)
 }
 
 
+/* Get glyph code of character C in FONT in the two-byte form CHAR2B.
+   Retunr 1 if FONT has a glyph for C, otherwise return 0.  */
+
+static INLINE int
+get_char_glyph_code (int c, struct font *font, XChar2b *char2b)
+{
+  unsigned code;
+
+  if (CHAR_BYTE8_P (c))
+    code = CHAR_TO_BYTE8 (c);
+  else
+    code = font->driver->encode_char (font, c);
+
+  if (code == FONT_INVALID_CODE)
+    return 0;
+  STORE_XCHAR2B (char2b, (code >> 8), (code & 0xFF));
+  return 1;
+}
+
+
 /* Fill glyph string S with composition components specified by S->cmp.
 
    BASE_FACE is the base face of the composition.
@@ -20396,6 +20376,7 @@ draw_glyphs (w, x, row, area, start, end, hl, overlaps)
          j = i;
          BUILD_GLYPH_STRINGS (j, start, h, t,
                               overlap_hl, dummy_x, last_x);
+         start = i;
          compute_overhangs_and_x (t, head->x, 1);
          prepend_glyph_string_lists (&head, &tail, h, t);
          clip_head = head;
@@ -20445,6 +20426,8 @@ draw_glyphs (w, x, row, area, start, end, hl, overlaps)
 
          BUILD_GLYPH_STRINGS (end, i, h, t,
                               overlap_hl, x, last_x);
+         /* Because BUILD_GLYPH_STRINGS updates the first argument,
+            we don't have `end = i;' here.  */
          compute_overhangs_and_x (h, tail->x + tail->width, 0);
          append_glyph_string_lists (&head, &tail, h, t);
          clip_tail = tail;
@@ -20929,10 +20912,14 @@ produce_stretch_glyph (it)
        {
          int maxlen = ((IT_BYTEPOS (*it) >= GPT ? ZV : GPT)
                        - IT_BYTEPOS (*it));
-         it2.c = STRING_CHAR_AND_LENGTH (p, maxlen, it2.len);
+         it2.c = it2.char_to_display = STRING_CHAR_AND_LENGTH (p, it2.len);
        }
       else
-       it2.c = *p, it2.len = 1;
+       {
+         it2.c = it2.char_to_display = *p, it2.len = 1;
+         if (! ASCII_CHAR_P (it2.c))
+           it2.char_to_display = BYTE8_TO_CHAR (it2.c);
+       }
 
       it2.glyph_row = NULL;
       it2.what = IT_CHARACTER;
@@ -21106,54 +21093,23 @@ x_produce_glyphs (it)
   if (it->what == IT_CHARACTER)
     {
       XChar2b char2b;
-      struct font *font;
       struct face *face = FACE_FROM_ID (it->f, it->face_id);
-      struct font_metrics *pcm;
-      int font_not_found_p;
+      struct font *font = face->font;
+      int font_not_found_p = font == NULL;
+      struct font_metrics *pcm = NULL;
       int boff;                        /* baseline offset */
-      /* We may change it->multibyte_p upon unibyte<->multibyte
-        conversion.  So, save the current value now and restore it
-        later.
-
-        Note: It seems that we don't have to record multibyte_p in
-        struct glyph because the character code itself tells whether
-        or not the character is multibyte.  Thus, in the future, we
-        must consider eliminating the field `multibyte_p' in the
-        struct glyph.  */
-      int saved_multibyte_p = it->multibyte_p;
-
-      /* Maybe translate single-byte characters to multibyte, or the
-        other way.  */
-      it->char_to_display = it->c;
-      if (!ASCII_BYTE_P (it->c)
-         && ! it->multibyte_p)
-       {
-         if (SINGLE_BYTE_CHAR_P (it->c)
-             && unibyte_display_via_language_environment)
-           {
-             struct charset *unibyte = CHARSET_FROM_ID (charset_unibyte);
-
-             /* get_next_display_element assures that this decoding
-                never fails.  */
-             it->char_to_display = DECODE_CHAR (unibyte, it->c);
-             it->multibyte_p = 1;
-             it->face_id = FACE_FOR_CHAR (it->f, face, it->char_to_display,
-                                          -1, Qnil);
-             face = FACE_FROM_ID (it->f, it->face_id);
-           }
-       }
 
-      /* Get font to use.  Encode IT->char_to_display.  */
-      get_char_face_and_encoding (it->f, it->char_to_display, it->face_id,
-                                 &char2b, it->multibyte_p, 0);
-      font = face->font;
-
-      /* When no suitable font found, use the default font.  */
-      font_not_found_p = font == NULL;
       if (font_not_found_p)
        {
-         font = FRAME_FONT (it->f);
-         boff = FRAME_BASELINE_OFFSET (it->f);
+         /* When no suitable font found, display an empty box based
+            on the metrics of the font of the default face (or what
+            remapped).  */
+         struct face *no_font_face
+           = FACE_FROM_ID (it->f,
+                           NILP (Vface_remapping_alist) ? DEFAULT_FACE_ID
+                           : lookup_basic_face (it->f, DEFAULT_FACE_ID));
+         font = no_font_face->font;
+         boff = font->baseline_offset;
        }
       else
        {
@@ -21162,16 +21118,12 @@ x_produce_glyphs (it)
            boff = VCENTER_BASELINE_OFFSET (font, it->f) - boff;
        }
 
-      if (it->char_to_display >= ' '
-         && (!it->multibyte_p || it->char_to_display < 128))
+      if (it->char_to_display != '\n' && it->char_to_display != '\t')
        {
-         /* Either unibyte or ASCII.  */
          int stretched_p;
 
          it->nglyphs = 1;
 
-         pcm = get_per_char_metric (it->f, font, &char2b);
-
          if (it->override_ascent >= 0)
            {
              it->ascent = it->override_ascent;
@@ -21184,6 +21136,15 @@ x_produce_glyphs (it)
              it->descent = FONT_DESCENT (font) - boff;
            }
 
+         if (! font_not_found_p
+             && get_char_glyph_code (it->char_to_display, font, &char2b))
+           {
+             pcm = get_per_char_metric (it->f, font, &char2b);
+             if (pcm->width == 0
+                 && pcm->rbearing == 0 && pcm->lbearing == 0)
+               pcm = NULL;
+           }
+
          if (pcm)
            {
              it->phys_ascent = pcm->ascent + boff;
@@ -21195,7 +21156,7 @@ x_produce_glyphs (it)
              it->glyph_not_available_p = 1;
              it->phys_ascent = it->ascent;
              it->phys_descent = it->descent;
-             it->pixel_width = FONT_WIDTH (font);
+             it->pixel_width = font->space_width;
            }
 
          if (it->constrain_row_ascent_descent_p)
@@ -21369,7 +21330,7 @@ x_produce_glyphs (it)
                }
            }
        }
-      else if (it->char_to_display == '\t')
+      else                   /* i.e. (it->char_to_display == '\t') */
        {
          if (font->space_width > 0)
            {
@@ -21400,85 +21361,6 @@ x_produce_glyphs (it)
              it->nglyphs = 1;
            }
        }
-      else
-       {
-         /* A multi-byte character.  Assume that the display width of the
-            character is the width of the character multiplied by the
-            width of the font.  */
-
-         /* If we found a font, this font should give us the right
-            metrics.  If we didn't find a font, use the frame's
-            default font and calculate the width of the character by
-            multiplying the width of font by the width of the
-            character.  */
-
-         pcm = get_per_char_metric (it->f, font, &char2b);
-
-         if (font_not_found_p || !pcm)
-           {
-             int char_width = CHAR_WIDTH (it->char_to_display);
-
-             if (char_width == 0)
-               /* This is a non spacing character.  But, as we are
-                  going to display an empty box, the box must occupy
-                  at least one column.  */
-               char_width = 1;
-             it->glyph_not_available_p = 1;
-             it->pixel_width = FRAME_COLUMN_WIDTH (it->f) * char_width;
-             it->phys_ascent = FONT_BASE (font) + boff;
-             it->phys_descent = FONT_DESCENT (font) - boff;
-           }
-         else
-           {
-             it->pixel_width = pcm->width;
-             it->phys_ascent = pcm->ascent + boff;
-             it->phys_descent = pcm->descent - boff;
-             if (it->glyph_row
-                 && (pcm->lbearing < 0
-                     || pcm->rbearing > pcm->width))
-               it->glyph_row->contains_overlapping_glyphs_p = 1;
-           }
-         it->nglyphs = 1;
-          it->ascent = FONT_BASE (font) + boff;
-          it->descent = FONT_DESCENT (font) - boff;
-         if (face->box != FACE_NO_BOX)
-           {
-             int thick = face->box_line_width;
-
-             if (thick > 0)
-               {
-                 it->ascent += thick;
-                 it->descent += thick;
-               }
-             else
-               thick = - thick;
-
-             if (it->start_of_box_run_p)
-               it->pixel_width += thick;
-             if (it->end_of_box_run_p)
-               it->pixel_width += thick;
-           }
-
-         /* If face has an overline, add the height of the overline
-            (1 pixel) and a 1 pixel margin to the character height.  */
-         if (face->overline_p)
-           it->ascent += overline_margin;
-
-         take_vertical_position_into_account (it);
-
-         if (it->ascent < 0)
-           it->ascent = 0;
-         if (it->descent < 0)
-           it->descent = 0;
-
-         if (it->glyph_row)
-           append_glyph (it);
-         if (it->pixel_width == 0)
-           /* We assure that all visible glyphs have at least 1-pixel
-              width.  */
-           it->pixel_width = 1;
-       }
-      it->multibyte_p = saved_multibyte_p;
     }
   else if (it->what == IT_COMPOSITION && it->cmp_it.ch < 0)
     {
@@ -21574,7 +21456,7 @@ x_produce_glyphs (it)
            }
          else
            {
-             width = FONT_WIDTH (font);
+             width = font->space_width;
              ascent = FONT_BASE (font);
              descent = FONT_DESCENT (font);
              lbearing = 0;
@@ -22660,9 +22542,6 @@ display_and_set_cursor (w, on, hpos, vpos, x, y)
 /* Switch the display of W's cursor on or off, according to the value
    of ON.  */
 
-#ifndef HAVE_NS
-static
-#endif
 void
 update_window_cursor (w, on)
      struct window *w;
@@ -23581,7 +23460,8 @@ note_mouse_highlight (f, x, y)
 #endif
 
   if (NILP (Vmouse_highlight)
-      || !f->glyphs_initialized_p)
+      || !f->glyphs_initialized_p
+      || f->pointer_invisible)
     return;
 
   dpyinfo->mouse_face_mouse_x = x;
@@ -24618,7 +24498,7 @@ syms_of_xdisp ()
   Vmessage_stack = Qnil;
   staticpro (&Vmessage_stack);
 
-  Qinhibit_redisplay = intern ("inhibit-redisplay");
+  Qinhibit_redisplay = intern_c_string ("inhibit-redisplay");
   staticpro (&Qinhibit_redisplay);
 
   message_dolog_marker1 = Fmake_marker ();
@@ -24644,133 +24524,133 @@ syms_of_xdisp ()
   defsubr (&Sinvisible_p);
 
   staticpro (&Qmenu_bar_update_hook);
-  Qmenu_bar_update_hook = intern ("menu-bar-update-hook");
+  Qmenu_bar_update_hook = intern_c_string ("menu-bar-update-hook");
 
   staticpro (&Qoverriding_terminal_local_map);
-  Qoverriding_terminal_local_map = intern ("overriding-terminal-local-map");
+  Qoverriding_terminal_local_map = intern_c_string ("overriding-terminal-local-map");
 
   staticpro (&Qoverriding_local_map);
-  Qoverriding_local_map = intern ("overriding-local-map");
+  Qoverriding_local_map = intern_c_string ("overriding-local-map");
 
   staticpro (&Qwindow_scroll_functions);
-  Qwindow_scroll_functions = intern ("window-scroll-functions");
+  Qwindow_scroll_functions = intern_c_string ("window-scroll-functions");
 
   staticpro (&Qwindow_text_change_functions);
-  Qwindow_text_change_functions = intern ("window-text-change-functions");
+  Qwindow_text_change_functions = intern_c_string ("window-text-change-functions");
 
   staticpro (&Qredisplay_end_trigger_functions);
-  Qredisplay_end_trigger_functions = intern ("redisplay-end-trigger-functions");
+  Qredisplay_end_trigger_functions = intern_c_string ("redisplay-end-trigger-functions");
 
   staticpro (&Qinhibit_point_motion_hooks);
-  Qinhibit_point_motion_hooks = intern ("inhibit-point-motion-hooks");
+  Qinhibit_point_motion_hooks = intern_c_string ("inhibit-point-motion-hooks");
 
-  Qeval = intern ("eval");
+  Qeval = intern_c_string ("eval");
   staticpro (&Qeval);
 
-  QCdata = intern (":data");
+  QCdata = intern_c_string (":data");
   staticpro (&QCdata);
-  Qdisplay = intern ("display");
+  Qdisplay = intern_c_string ("display");
   staticpro (&Qdisplay);
-  Qspace_width = intern ("space-width");
+  Qspace_width = intern_c_string ("space-width");
   staticpro (&Qspace_width);
-  Qraise = intern ("raise");
+  Qraise = intern_c_string ("raise");
   staticpro (&Qraise);
-  Qslice = intern ("slice");
+  Qslice = intern_c_string ("slice");
   staticpro (&Qslice);
-  Qspace = intern ("space");
+  Qspace = intern_c_string ("space");
   staticpro (&Qspace);
-  Qmargin = intern ("margin");
+  Qmargin = intern_c_string ("margin");
   staticpro (&Qmargin);
-  Qpointer = intern ("pointer");
+  Qpointer = intern_c_string ("pointer");
   staticpro (&Qpointer);
-  Qleft_margin = intern ("left-margin");
+  Qleft_margin = intern_c_string ("left-margin");
   staticpro (&Qleft_margin);
-  Qright_margin = intern ("right-margin");
+  Qright_margin = intern_c_string ("right-margin");
   staticpro (&Qright_margin);
-  Qcenter = intern ("center");
+  Qcenter = intern_c_string ("center");
   staticpro (&Qcenter);
-  Qline_height = intern ("line-height");
+  Qline_height = intern_c_string ("line-height");
   staticpro (&Qline_height);
-  QCalign_to = intern (":align-to");
+  QCalign_to = intern_c_string (":align-to");
   staticpro (&QCalign_to);
-  QCrelative_width = intern (":relative-width");
+  QCrelative_width = intern_c_string (":relative-width");
   staticpro (&QCrelative_width);
-  QCrelative_height = intern (":relative-height");
+  QCrelative_height = intern_c_string (":relative-height");
   staticpro (&QCrelative_height);
-  QCeval = intern (":eval");
+  QCeval = intern_c_string (":eval");
   staticpro (&QCeval);
-  QCpropertize = intern (":propertize");
+  QCpropertize = intern_c_string (":propertize");
   staticpro (&QCpropertize);
-  QCfile = intern (":file");
+  QCfile = intern_c_string (":file");
   staticpro (&QCfile);
-  Qfontified = intern ("fontified");
+  Qfontified = intern_c_string ("fontified");
   staticpro (&Qfontified);
-  Qfontification_functions = intern ("fontification-functions");
+  Qfontification_functions = intern_c_string ("fontification-functions");
   staticpro (&Qfontification_functions);
-  Qtrailing_whitespace = intern ("trailing-whitespace");
+  Qtrailing_whitespace = intern_c_string ("trailing-whitespace");
   staticpro (&Qtrailing_whitespace);
-  Qescape_glyph = intern ("escape-glyph");
+  Qescape_glyph = intern_c_string ("escape-glyph");
   staticpro (&Qescape_glyph);
-  Qnobreak_space = intern ("nobreak-space");
+  Qnobreak_space = intern_c_string ("nobreak-space");
   staticpro (&Qnobreak_space);
-  Qimage = intern ("image");
+  Qimage = intern_c_string ("image");
   staticpro (&Qimage);
-  QCmap = intern (":map");
+  QCmap = intern_c_string (":map");
   staticpro (&QCmap);
-  QCpointer = intern (":pointer");
+  QCpointer = intern_c_string (":pointer");
   staticpro (&QCpointer);
-  Qrect = intern ("rect");
+  Qrect = intern_c_string ("rect");
   staticpro (&Qrect);
-  Qcircle = intern ("circle");
+  Qcircle = intern_c_string ("circle");
   staticpro (&Qcircle);
-  Qpoly = intern ("poly");
+  Qpoly = intern_c_string ("poly");
   staticpro (&Qpoly);
-  Qmessage_truncate_lines = intern ("message-truncate-lines");
+  Qmessage_truncate_lines = intern_c_string ("message-truncate-lines");
   staticpro (&Qmessage_truncate_lines);
-  Qgrow_only = intern ("grow-only");
+  Qgrow_only = intern_c_string ("grow-only");
   staticpro (&Qgrow_only);
-  Qinhibit_menubar_update = intern ("inhibit-menubar-update");
+  Qinhibit_menubar_update = intern_c_string ("inhibit-menubar-update");
   staticpro (&Qinhibit_menubar_update);
-  Qinhibit_eval_during_redisplay = intern ("inhibit-eval-during-redisplay");
+  Qinhibit_eval_during_redisplay = intern_c_string ("inhibit-eval-during-redisplay");
   staticpro (&Qinhibit_eval_during_redisplay);
-  Qposition = intern ("position");
+  Qposition = intern_c_string ("position");
   staticpro (&Qposition);
-  Qbuffer_position = intern ("buffer-position");
+  Qbuffer_position = intern_c_string ("buffer-position");
   staticpro (&Qbuffer_position);
-  Qobject = intern ("object");
+  Qobject = intern_c_string ("object");
   staticpro (&Qobject);
-  Qbar = intern ("bar");
+  Qbar = intern_c_string ("bar");
   staticpro (&Qbar);
-  Qhbar = intern ("hbar");
+  Qhbar = intern_c_string ("hbar");
   staticpro (&Qhbar);
-  Qbox = intern ("box");
+  Qbox = intern_c_string ("box");
   staticpro (&Qbox);
-  Qhollow = intern ("hollow");
+  Qhollow = intern_c_string ("hollow");
   staticpro (&Qhollow);
-  Qhand = intern ("hand");
+  Qhand = intern_c_string ("hand");
   staticpro (&Qhand);
-  Qarrow = intern ("arrow");
+  Qarrow = intern_c_string ("arrow");
   staticpro (&Qarrow);
-  Qtext = intern ("text");
+  Qtext = intern_c_string ("text");
   staticpro (&Qtext);
-  Qrisky_local_variable = intern ("risky-local-variable");
+  Qrisky_local_variable = intern_c_string ("risky-local-variable");
   staticpro (&Qrisky_local_variable);
-  Qinhibit_free_realized_faces = intern ("inhibit-free-realized-faces");
+  Qinhibit_free_realized_faces = intern_c_string ("inhibit-free-realized-faces");
   staticpro (&Qinhibit_free_realized_faces);
 
-  list_of_error = Fcons (Fcons (intern ("error"),
-                               Fcons (intern ("void-variable"), Qnil)),
+  list_of_error = Fcons (Fcons (intern_c_string ("error"),
+                               Fcons (intern_c_string ("void-variable"), Qnil)),
                         Qnil);
   staticpro (&list_of_error);
 
-  Qlast_arrow_position = intern ("last-arrow-position");
+  Qlast_arrow_position = intern_c_string ("last-arrow-position");
   staticpro (&Qlast_arrow_position);
-  Qlast_arrow_string = intern ("last-arrow-string");
+  Qlast_arrow_string = intern_c_string ("last-arrow-string");
   staticpro (&Qlast_arrow_string);
 
-  Qoverlay_arrow_string = intern ("overlay-arrow-string");
+  Qoverlay_arrow_string = intern_c_string ("overlay-arrow-string");
   staticpro (&Qoverlay_arrow_string);
-  Qoverlay_arrow_bitmap = intern ("overlay-arrow-bitmap");
+  Qoverlay_arrow_bitmap = intern_c_string ("overlay-arrow-bitmap");
   staticpro (&Qoverlay_arrow_bitmap);
 
   echo_buffer[0] = echo_buffer[1] = Qnil;
@@ -24781,7 +24661,7 @@ syms_of_xdisp ()
   staticpro (&echo_area_buffer[0]);
   staticpro (&echo_area_buffer[1]);
 
-  Vmessages_buffer_name = build_string ("*Messages*");
+  Vmessages_buffer_name = make_pure_c_string ("*Messages*");
   staticpro (&Vmessages_buffer_name);
 
   mode_line_proptrans_alist = Qnil;
@@ -24851,14 +24731,14 @@ See also `overlay-arrow-string'.  */);
   DEFVAR_LISP ("overlay-arrow-string", &Voverlay_arrow_string,
     doc: /* String to display as an arrow in non-window frames.
 See also `overlay-arrow-position'.  */);
-  Voverlay_arrow_string = build_string ("=>");
+  Voverlay_arrow_string = make_pure_c_string ("=>");
 
   DEFVAR_LISP ("overlay-arrow-variable-list", &Voverlay_arrow_variable_list,
     doc: /* List of variables (symbols) which hold markers for overlay arrows.
 The symbols on this list are examined during redisplay to determine
 where to display overlay arrows.  */);
   Voverlay_arrow_variable_list
-    = Fcons (intern ("overlay-arrow-position"), Qnil);
+    = Fcons (intern_c_string ("overlay-arrow-position"), Qnil);
 
   DEFVAR_INT ("scroll-step", &scroll_step,
     doc: /* *The number of lines to try scrolling a window by when point moves out.
@@ -24952,14 +24832,14 @@ and is used only on frames for which no explicit name has been set
 \(see `modify-frame-parameters').  */);
   Vicon_title_format
     = Vframe_title_format
-    = Fcons (intern ("multiple-frames"),
-            Fcons (build_string ("%b"),
-                   Fcons (Fcons (empty_unibyte_string,
-                                 Fcons (intern ("invocation-name"),
-                                        Fcons (build_string ("@"),
-                                               Fcons (intern ("system-name"),
-                                                              Qnil)))),
-                          Qnil)));
+    = pure_cons (intern_c_string ("multiple-frames"),
+                pure_cons (make_pure_c_string ("%b"),
+                           pure_cons (pure_cons (empty_unibyte_string,
+                                                 pure_cons (intern_c_string ("invocation-name"),
+                                                            pure_cons (make_pure_c_string ("@"),
+                                                                       pure_cons (intern_c_string ("system-name"),
+                                                                                  Qnil)))),
+                                      Qnil)));
 
   DEFVAR_LISP ("message-log-max", &Vmessage_log_max,
     doc: /* Maximum number of lines to keep in the message log buffer.
@@ -25100,7 +24980,7 @@ the frame's other specifications determine how to blink the cursor off.  */);
   DEFVAR_BOOL ("auto-hscroll-mode", &automatic_hscrolling_p,
     doc: /* *Non-nil means scroll the display automatically to make point visible.  */);
   automatic_hscrolling_p = 1;
-  Qauto_hscroll_mode = intern ("auto-hscroll-mode");
+  Qauto_hscroll_mode = intern_c_string ("auto-hscroll-mode");
   staticpro (&Qauto_hscroll_mode);
 
   DEFVAR_INT ("hscroll-margin", &hscroll_margin,
@@ -25158,7 +25038,7 @@ property.
 To add a prefix to non-continuation lines, use `line-prefix'.  */);
   Vwrap_prefix = Qnil;
   staticpro (&Qwrap_prefix);
-  Qwrap_prefix = intern ("wrap-prefix");
+  Qwrap_prefix = intern_c_string ("wrap-prefix");
   Fmake_variable_buffer_local (Qwrap_prefix);
 
   DEFVAR_LISP ("line-prefix", &Vline_prefix,
@@ -25172,7 +25052,7 @@ property.
 To add a prefix to continuation lines, use `wrap-prefix'.  */);
   Vline_prefix = Qnil;
   staticpro (&Qline_prefix);
-  Qline_prefix = intern ("line-prefix");
+  Qline_prefix = intern_c_string ("line-prefix");
   Fmake_variable_buffer_local (Qline_prefix);
 
   DEFVAR_BOOL ("inhibit-eval-during-redisplay", &inhibit_eval_during_redisplay,