(line-number-display-limit): Doc fix.
[bpt/emacs.git] / src / xdisp.c
index 9564cd8..9f5c613 100644 (file)
@@ -66,6 +66,10 @@ Lisp_Object Qwindow_scroll_functions, Vwindow_scroll_functions;
 Lisp_Object Qredisplay_end_trigger_functions;
 Lisp_Object Qinhibit_point_motion_hooks;
 
+/* Non-nil means don't actually do any redisplay.  */
+
+Lisp_Object Vinhibit_redisplay, Qinhibit_redisplay;
+
 /* Nonzero means print newline to stdout before next minibuffer message.  */
 
 int noninteractive_need_newline;
@@ -108,6 +112,9 @@ char *previous_echo_glyphs;
 /* Nonzero means truncate lines in all windows less wide than the frame */
 int truncate_partial_width_windows;
 
+/* A flag to control how to display unibyte 8-bit character.  */
+int unibyte_display_via_language_environment;
+
 /* Nonzero means we have more than one non-minibuffer-only frame.
    Not guaranteed to be accurate except while parsing frame-title-format.  */
 int multiple_frames;
@@ -296,7 +303,8 @@ message_dolog (m, len, nlflag, multibyte)
       int old_windows_or_buffers_changed = windows_or_buffers_changed;
       int point_at_end = 0;
       int zv_at_end = 0;
-      Lisp_Object old_deactivate_mark;
+      Lisp_Object old_deactivate_mark, tem;
+      struct gcpro gcpro1, gcpro2, gcpro3, gcpro4;
 
       old_deactivate_mark = Vdeactivate_mark;
       oldbuf = current_buffer;
@@ -306,6 +314,7 @@ message_dolog (m, len, nlflag, multibyte)
       oldpoint = Fpoint_marker ();
       oldbegv = Fpoint_min_marker ();
       oldzv = Fpoint_max_marker ();
+      GCPRO4 (oldpoint, oldbegv, oldzv, old_deactivate_mark);
 
       if (PT == Z)
        point_at_end = 1;
@@ -323,31 +332,32 @@ message_dolog (m, len, nlflag, multibyte)
       if (multibyte
          && NILP (current_buffer->enable_multibyte_characters))
        {
-         int c, i = 0, nbytes;
+         int i, c, nbytes;
+         unsigned char work[1];
          /* Convert a multibyte string to single-byte
             for the *Message* buffer.  */
-         while (i < len)
+         for (i = 0; i < len; i += nbytes)
            {
-             c = STRING_CHAR (m + i, len - i);
-             i += XFASTINT (Fchar_bytes (make_number (c)));
-             /* Truncate the character to its last byte--we can only hope
-                the user is happy with the character he gets,
-                since if it isn't right, there is no way to do it right.  */
-             c &= 0xff;
-             insert_char (c);
+             c = STRING_CHAR_AND_LENGTH (m + i, len - i, nbytes);
+             work[0] = (SINGLE_BYTE_CHAR_P (c)
+                        ? c
+                        : multibyte_char_to_unibyte (c, Qnil));
+             insert_1_both (work, 1, 1, 1, 0, 0);
            }
        }
       else if (! multibyte
               && ! NILP (current_buffer->enable_multibyte_characters))
        {
-         int i = 0;
+         int i, c, nbytes;
          unsigned char *msg = (unsigned char *) m;
+         unsigned char *str, work[4];
          /* Convert a single-byte string to multibyte
             for the *Message* buffer.  */
-         while (i < len)
+         for (i = 0; i < len; i++)
            {
-             int c = unibyte_char_to_multibyte (msg[i++]);
-             insert_char (c);
+             c = unibyte_char_to_multibyte (msg[i]);
+             nbytes = CHAR_STRING (c, work, str);
+             insert_1_both (work, 1, nbytes, 1, 0, 0);
            }
        }
       else if (len)
@@ -413,14 +423,20 @@ message_dolog (m, len, nlflag, multibyte)
       if (point_at_end)
        TEMP_SET_PT_BOTH (Z, Z_BYTE);
       else
-       Fgoto_char (oldpoint);
+       /* We can't do Fgoto_char (oldpoint) because it will run some
+           Lisp code.  */
+       TEMP_SET_PT_BOTH (XMARKER (oldpoint)->charpos,
+                         XMARKER (oldpoint)->bytepos);
 
+      UNGCPRO;
       free_marker (oldpoint);
       free_marker (oldbegv);
       free_marker (oldzv);
 
+      tem = Fget_buffer_window (Fcurrent_buffer (), Qt);
       set_buffer_internal (oldbuf);
-      windows_or_buffers_changed = old_windows_or_buffers_changed;
+      if (NILP (tem))
+       windows_or_buffers_changed = old_windows_or_buffers_changed;
       message_log_need_newline = !nlflag;
       Vdeactivate_mark = old_deactivate_mark;
     }
@@ -438,7 +454,7 @@ message_log_check_duplicate (prev_bol, prev_bol_byte, this_bol, this_bol_byte)
      int prev_bol_byte, this_bol_byte;
 {
   int i;
-  int len = Z - 1 - this_bol;
+  int len = Z_BYTE - 1 - this_bol_byte;
   int seen_dots = 0;
   unsigned char *p1 = BUF_BYTE_ADDRESS (current_buffer, prev_bol_byte);
   unsigned char *p2 = BUF_BYTE_ADDRESS (current_buffer, this_bol_byte);
@@ -1031,6 +1047,9 @@ redisplay_internal (preserve_echo_area)
     return;
 #endif
 
+  if (! NILP (Vinhibit_redisplay))
+    return;
+
  retry:
 
   if (! FRAME_WINDOW_P (selected_frame)
@@ -1194,7 +1213,7 @@ redisplay_internal (preserve_echo_area)
                                 1 << (BITS_PER_SHORT - 1),
                                 window_internal_width (w) - 1,
                                 XINT (w->hscroll), 0, w);
-         SET_PT_BOTH (opoint, opoint_byte);
+         TEMP_SET_PT_BOTH (opoint, opoint_byte);
          if (val.hpos != this_line_start_hpos)
            goto cancel;
 
@@ -1428,9 +1447,20 @@ update:
       beg_unchanged = BUF_GPT (b) - BUF_BEG (b);
       end_unchanged = BUF_Z (b) - BUF_GPT (b);
 
-      XSETFASTINT (w->last_point, BUF_PT (b));
-      XSETFASTINT (w->last_point_x, FRAME_CURSOR_X (selected_frame));
-      XSETFASTINT (w->last_point_y, FRAME_CURSOR_Y (selected_frame));
+      /* Record the last place cursor was displayed in this window.
+        But not if cursor is in the echo area, because in that case
+        FRAME_CURSOR_X and FRAME_CURSOR_Y are in the echo area.  */
+      if (!(cursor_in_echo_area && FRAME_HAS_MINIBUF_P (selected_frame)
+           && EQ (FRAME_MINIBUF_WINDOW (selected_frame), minibuf_window)))
+       {
+         XSETFASTINT (w->last_point, BUF_PT (b));
+         XSETFASTINT (w->last_point_x, FRAME_CURSOR_X (selected_frame));
+         XSETFASTINT (w->last_point_y, FRAME_CURSOR_Y (selected_frame));
+       }
+      else
+       /* Make last_point invalid, since we don't really know
+          where the cursor would be if it were not in the echo area.  */
+       XSETINT (w->last_point, -1);
 
       if (all_windows)
        mark_window_display_accurate (FRAME_ROOT_WINDOW (selected_frame), 1);
@@ -1897,7 +1927,8 @@ redisplay_window (window, just_this_one, preserve_echo_area)
 
   /* If someone specified a new starting point but did not insist,
      check whether it can be used.  */
-  if (!NILP (w->optional_new_start))
+  if (!NILP (w->optional_new_start)
+      && startp >= BEGV && startp <= ZV)
     {
       w->optional_new_start = Qnil;
       /* Check whether this start pos is usable given where point is.  */
@@ -1927,6 +1958,8 @@ redisplay_window (window, just_this_one, preserve_echo_area)
       w->force_start = Qnil;
       /* Forget any recorded base line for line number display.  */
       w->base_line_number = Qnil;
+      /* The old bottom-of-screen position is no longer valid.  */
+      w->window_end_valid = Qnil;
       /* Redisplay the mode line.  Select the buffer properly for that.
         Also, run the hook window-scroll-functions
         because we have scrolled.  */
@@ -2059,7 +2092,7 @@ redisplay_window (window, just_this_one, preserve_echo_area)
          int tab_offset = (pos_tab_offset (w, last_point, last_point_byte)
                            - (last_point_x + hscroll - !! hscroll));
 
-         pos = *compute_motion (last_point, last_point_y, last_point_x, 0,
+         pos = *compute_motion (last_point, last_point_y, last_point_x, 1,
                                 PT, height,
                                 /* BUG FIX: See the comment of 
                                    Fpos_visible_in_window_p (window.c).  */
@@ -2211,6 +2244,8 @@ redisplay_window (window, just_this_one, preserve_echo_area)
       int this_scroll_margin = scroll_margin;
       int scroll_margin_pos, scroll_margin_bytepos;
       int scroll_max = scroll_step;
+      Lisp_Object ltemp;
+
       if (scroll_conservatively)
        scroll_max = scroll_conservatively;
 
@@ -2221,7 +2256,9 @@ redisplay_window (window, just_this_one, preserve_echo_area)
       if (XINT (w->height) < 4 * this_scroll_margin)
        this_scroll_margin = XINT (w->height) / 4;
 
-      scroll_margin_pos = Z - XFASTINT (w->window_end_pos);
+      ltemp = Fwindow_end (window, Qt);
+      scroll_margin_pos = XINT (ltemp);
+
       if (this_scroll_margin)
        {
          pos = *vmotion (scroll_margin_pos, -this_scroll_margin, w);
@@ -2247,6 +2284,8 @@ redisplay_window (window, just_this_one, preserve_echo_area)
                          scroll_conservatively ? pos.vpos + 1 : scroll_step,
                          w);
 
+         /* The old bottom-of-screen position is no longer valid.  */
+         w->window_end_valid = Qnil;
          if (! NILP (Vwindow_scroll_functions))
            {
              set_marker_both (w->start, Qnil, pos.bufpos, pos.bytepos);
@@ -2288,6 +2327,8 @@ redisplay_window (window, just_this_one, preserve_echo_area)
                          scroll_conservatively ? -pos.vpos : - scroll_step,
                          w);
 
+         /* The old bottom-of-screen position is no longer valid.  */
+         w->window_end_valid = Qnil;
          if (! NILP (Vwindow_scroll_functions))
            {
              set_marker_both (w->start, Qnil, pos.bufpos, pos.bytepos);
@@ -2328,6 +2369,9 @@ redisplay_window (window, just_this_one, preserve_echo_area)
 
       if (PT >= pos.bufpos)
        {
+         /* The old bottom-of-screen position is no longer valid.  */
+         w->window_end_valid = Qnil;
+
          if (! NILP (Vwindow_scroll_functions))
            {
              set_marker_both (w->start, Qnil, pos.bufpos, pos.bytepos);
@@ -2378,6 +2422,9 @@ recenter:
   /* Set startp here explicitly in case that helps avoid an infinite loop
      in case the window-scroll-functions functions get errors.  */
   set_marker_both (w->start, Qnil, pos.bufpos, pos.bytepos);
+
+  /* The old bottom-of-screen position is no longer valid.  */
+  w->window_end_valid = Qnil;
   if (! NILP (Vwindow_scroll_functions))
     {
       run_hook_with_args_2 (Qwindow_scroll_functions, window,
@@ -2661,7 +2708,7 @@ try_window_id (window)
   if (bp.contin && bp.hpos != lmargin)
     {
       val.hpos = bp.prevhpos - width + lmargin;
-      val.tab_offset = bp.tab_offset + bp.prevhpos - width;
+      val.tab_offset = bp.tab_offset + width - bp.prevhpos;
       did_motion = 1;
       DEC_BOTH (pos, pos_byte);
     }
@@ -2670,13 +2717,13 @@ try_window_id (window)
 
   /* Find first visible newline after which no more is changed.  */
   opoint = PT, opoint_byte = PT_BYTE;
-  SET_PT (Z - max (end_unchanged, Z - ZV));
+  TEMP_SET_PT (Z - max (end_unchanged, Z - ZV));
   scan_newline (PT, PT_BYTE, ZV, ZV_BYTE, 1, 1);
   if (selective > 0)
     while (PT < ZV - 1 && indented_beyond_p (PT, PT_BYTE, selective))
       scan_newline (PT, PT_BYTE, ZV, ZV_BYTE, 1, 1);
   tem = PT;
-  SET_PT_BOTH (opoint, opoint_byte);
+  TEMP_SET_PT_BOTH (opoint, opoint_byte);
 
   /* Compute the cursor position after that newline.  */
   ep = *compute_motion (pos, vpos, val.hpos, did_motion, tem,
@@ -2854,6 +2901,7 @@ try_window_id (window)
     Fset_marker (w->start, make_number (pos), Qnil);
 
   val.bytepos = pos_byte;
+  val.ovstring_chars_done = 0;
 
   /* Redisplay the lines where the text was changed */
   last_text_vpos = vpos;
@@ -3135,7 +3183,7 @@ pos_tab_offset (w, pos, pos_byte)
 
   return col;
 }
-\f\f
+\f
 /* Display one line of window W, starting at char position START in W's buffer.
    START_BYTE is the corresponding byte position.
 
@@ -3331,8 +3379,9 @@ display_text_line (w, start, start_byte, vpos, hpos, taboffset, ovstr_done)
          compute_motion may have moved us past the screen position we
          requested, if we hit a multi-column character, or the end of
          the line.  If so, back up.  */
-      if (left_edge->vpos > vpos
-          || left_edge->hpos > 0)
+      if ((left_edge->vpos > vpos
+          || left_edge->hpos > 0)
+         && left_edge->bufpos > pos)
         {
           pos = left_edge->bufpos;
          pos_byte = left_edge->bytepos;
@@ -3411,7 +3460,7 @@ display_text_line (w, start, start_byte, vpos, hpos, taboffset, ovstr_done)
                      ovstr += ovstr_done;
                      ovlen -= ovstr_done;
 
-                     while (ovlen > 0)
+                     while (ovlen > 0 && p1 < endp)
                        {
                          int charset, cols;
                          GLYPH g;
@@ -3640,7 +3689,7 @@ display_text_line (w, start, start_byte, vpos, hpos, taboffset, ovstr_done)
                  pos--;
                  pos_byte--;
                }
-             SET_PT_BOTH (opoint, opoint_byte);
+             TEMP_SET_PT_BOTH (opoint, opoint_byte);
            }
          if (invis && selective_rlen > 0 && p1 >= leftmargin)
            {
@@ -3716,7 +3765,7 @@ display_text_line (w, start, start_byte, vpos, hpos, taboffset, ovstr_done)
          int opoint = PT, opoint_byte = PT_BYTE;
          scan_newline (pos, pos_byte, ZV, ZV_BYTE, 1, 1);
          pos = PT, pos_byte = PT_BYTE;
-         SET_PT_BOTH (opoint, opoint_byte);
+         TEMP_SET_PT_BOTH (opoint, opoint_byte);
 
          if (FETCH_BYTE (pos_byte - 1) == '\n')
            pos--, pos_byte--;
@@ -3776,10 +3825,16 @@ display_text_line (w, start, start_byte, vpos, hpos, taboffset, ovstr_done)
       else
        {
          /* C is a multibyte character or a character to be displayed
-             by octral form.  */
+             by octal form.  */
          int remaining_bytes = len;
 
-         if (c >= 0400)
+         if (unibyte_display_via_language_environment
+             && SINGLE_BYTE_CHAR_P (c)
+             && (c >= 0240
+                 || (c >= 0200 && !NILP (Vnonascii_translation_table))))
+           c = unibyte_char_to_multibyte (c);
+
+         if (c >= 0400 && CHAR_VALID_P (c, 0))
            {
              /* C is a multibyte character.  */
              int charset = CHAR_CHARSET (c);
@@ -3934,7 +3989,7 @@ display_text_line (w, start, start_byte, vpos, hpos, taboffset, ovstr_done)
          int opoint = PT, opoint_byte = PT_BYTE;
 
          /* If stopped due to a newline, start next line after it */
-         SET_PT_BOTH (pos + 1, pos_byte + 1);
+         TEMP_SET_PT_BOTH (pos + 1, pos_byte + 1);
 
          val.tab_offset = 0;
          /* Check again for hidden lines, in case the newline occurred exactly
@@ -3944,7 +3999,7 @@ display_text_line (w, start, start_byte, vpos, hpos, taboffset, ovstr_done)
            scan_newline (PT, PT_BYTE, ZV, ZV_BYTE, 1, 1);
 
          pos = PT, pos_byte = PT_BYTE;
-         SET_PT_BOTH (opoint, opoint_byte);
+         TEMP_SET_PT_BOTH (opoint, opoint_byte);
        }
       else
        /* Stopped due to right margin of window */
@@ -3953,7 +4008,7 @@ display_text_line (w, start, start_byte, vpos, hpos, taboffset, ovstr_done)
            {
              int opoint = PT, opoint_byte = PT_BYTE;
 
-             SET_PT_BOTH (pos, pos_byte);
+             TEMP_SET_PT_BOTH (pos, pos_byte);
              *p1++ = fix_glyph (f, truncator, 0);
              /* Truncating => start next line after next newline,
                 and point is on this line if it is before the newline,
@@ -3964,7 +4019,7 @@ display_text_line (w, start, start_byte, vpos, hpos, taboffset, ovstr_done)
                     && indented_beyond_p (PT, PT_BYTE, selective));
              pos = PT, pos_byte = PT_BYTE;
              val.hpos = XINT (w->hscroll) ? 1 - XINT (w->hscroll) : 0;
-             SET_PT_BOTH (opoint, opoint_byte);
+             TEMP_SET_PT_BOTH (opoint, opoint_byte);
 
              lastpos = pos - (FETCH_BYTE (pos_byte - 1) == '\n');
              lastpos_byte = CHAR_TO_BYTE (lastpos);
@@ -3998,29 +4053,32 @@ display_text_line (w, start, start_byte, vpos, hpos, taboffset, ovstr_done)
       cursor_hpos += WINDOW_LEFT_MARGIN (w);
       if (w == XWINDOW (FRAME_SELECTED_WINDOW (f)))
        {
+         this_line_bufpos = 0;
+
+         /* If this frame's cursor will be in its echo area,
+            don't record a cursor from the window text,
+            and turn off the optimization for cursor-motion-only case.  */
          if (!(cursor_in_echo_area && FRAME_HAS_MINIBUF_P (f)
                && EQ (FRAME_MINIBUF_WINDOW (f), minibuf_window)))
            {
              FRAME_CURSOR_Y (f) = cursor_vpos;
              FRAME_CURSOR_X (f) = cursor_hpos;
-           }
 
-         if (w == XWINDOW (selected_window))
-           {
-             /* Line is not continued and did not start
-                in middle of character */
-             if ((hpos - WINDOW_LEFT_MARGIN (w)
-                  == (XINT (w->hscroll) ? 1 - XINT (w->hscroll) : 0))
-                 && val.vpos)
+             if (w == XWINDOW (selected_window))
                {
-                 this_line_bufpos = start;
-                 this_line_buffer = current_buffer;
-                 this_line_vpos = cursor_vpos;
-                 this_line_start_hpos = hpos - WINDOW_LEFT_MARGIN (w);
-                 this_line_endpos = Z - lastpos;
+                 /* Line is not continued and did not start
+                    in middle of character */
+                 if ((hpos - WINDOW_LEFT_MARGIN (w)
+                      == (XINT (w->hscroll) ? 1 - XINT (w->hscroll) : 0))
+                     && val.vpos)
+                   {
+                     this_line_bufpos = start;
+                     this_line_buffer = current_buffer;
+                     this_line_vpos = cursor_vpos;
+                     this_line_start_hpos = hpos - WINDOW_LEFT_MARGIN (w);
+                     this_line_endpos = Z - lastpos;
+                   }
                }
-             else
-               this_line_bufpos = 0;
            }
        }
     }
@@ -4508,6 +4566,8 @@ pint2str (buf, width, d)
    If EOL_FLAG is 1, set also a mnemonic character for end-of-line
    type of CODING_SYSTEM.  Return updated pointer into BUF.  */
 
+static unsigned char invalid_eol_type[] = "(*invalid*)";
+
 static char *
 decode_mode_spec_coding (coding_system, buf, eol_flag)
      Lisp_Object coding_system;
@@ -4516,6 +4576,10 @@ decode_mode_spec_coding (coding_system, buf, eol_flag)
 {
   Lisp_Object val;
   int multibyte = !NILP (current_buffer->enable_multibyte_characters);
+  unsigned char *eol_str;
+  int eol_str_len;
+  /* The EOL conversion we are using.  */
+  Lisp_Object eoltype;
 
   val = coding_system;
 
@@ -4524,7 +4588,7 @@ decode_mode_spec_coding (coding_system, buf, eol_flag)
       if (multibyte)
        *buf++ = '-';
       if (eol_flag)
-       *buf++ = eol_mnemonic_undecided;
+       eoltype = eol_mnemonic_undecided;
       /* Don't mention EOL conversion if it isn't decided.  */
     }
   else
@@ -4545,8 +4609,6 @@ decode_mode_spec_coding (coding_system, buf, eol_flag)
 
       if (eol_flag)
        {
-         /* The EOL conversion we are using.  */
-         int eoltype;
          /* The EOL conversion that is normal on this system.  */
 
          if (NILP (eolvalue))  /* Not yet decided.  */
@@ -4558,11 +4620,34 @@ decode_mode_spec_coding (coding_system, buf, eol_flag)
                       ? eol_mnemonic_unix
                       : (XFASTINT (eolvalue) == 1
                          ? eol_mnemonic_dos : eol_mnemonic_mac));
+       }
+    }
+
+  if (eol_flag)
+    {
+      /* Mention the EOL conversion if it is not the usual one.  */
+      if (STRINGP (eoltype))
+       {
+         eol_str = XSTRING (eoltype)->data;
+         eol_str_len = XSTRING (eoltype)->size;
+       }
+      else if (INTEGERP (eoltype)
+              && CHAR_VALID_P (XINT (eoltype), 0))
+       {
+         int c = XINT (eoltype);
+         unsigned char work[4];
 
-         /* Mention the EOL conversion if it is not the usual one.  */
-         *buf++ = eoltype;
+         eol_str_len = CHAR_STRING (XINT (eoltype), work, eol_str);
        }
+      else
+       {
+         eol_str = invalid_eol_type;
+         eol_str_len = sizeof (invalid_eol_type) - 1;
+       }
+      bcopy (eol_str, buf, eol_str_len);
+      buf += eol_str_len;
     }
+
   return buf;
 }
 
@@ -5206,66 +5291,76 @@ display_string (w, vpos, string, length, hpos, truncate,
            *p1 = c ^ 0100;
          p1++;
        }
-      else if (len == 1)
-       {
-         /* C is a control character or a binary byte data.  */
-         if (p1 >= start)
-           *p1 = (fix_glyph
-                  (f, (dp && INTEGERP (DISP_ESCAPE_GLYPH (dp))
-                       && GLYPH_CHAR_VALID_P (XINT (DISP_ESCAPE_GLYPH (dp)))
-                       ? XINT (DISP_ESCAPE_GLYPH (dp)) : '\\'),
-                   0));
-         p1++;
-         if (p1 >= start && p1 < end)
-           *p1 = (c >> 6) + '0';
-         p1++;
-         if (p1 >= start && p1 < end)
-           *p1 = (7 & (c >> 3)) + '0';
-         p1++;
-         if (p1 >= start && p1 < end)
-           *p1 = (7 & c) + '0';
-         p1++;
-       }
       else
        {
-         /* C is a multibyte character.  */      
-         int charset = CHAR_CHARSET (c);
-         int columns = (charset == CHARSET_COMPOSITION
-                        ? cmpchar_table[COMPOSITE_CHAR_ID (c)]->width
-                        : CHARSET_WIDTH (charset));
+         /* C is a multibyte character, control character or a binary
+             byte data.  */
+         int remaining_bytes = len;
 
-         if (p1 < start)
+         if (c >= 0400 && CHAR_VALID_P (c, 0))
            {
-             /* Since we can't show the left part of C, fill all
-                 columns with spaces.  */
-             columns -= start - p1;
-             p1 = start;
-             while (columns--)
+             /* C is a multibyte character.  */          
+             int charset = CHAR_CHARSET (c);
+             int columns = (charset == CHARSET_COMPOSITION
+                            ? cmpchar_table[COMPOSITE_CHAR_ID (c)]->width
+                            : CHARSET_WIDTH (charset));
+
+             remaining_bytes -= CHARSET_BYTES (charset);
+             if (p1 < start)
                {
-                 if (p1 < end)
-                   *p1 = SPACEGLYPH;
-                 p1++;
+                 /* Since we can't show the left part of C, fill all
+                    columns with spaces.  */
+                 columns -= start - p1;
+                 p1 = start;
+                 while (columns--)
+                   {
+                     if (p1 < end)
+                       *p1 = SPACEGLYPH;
+                     p1++;
+                   }
                }
-           }
-         else if (p1 + columns > end)
-           {
-             /* Since we can't show the right part of C, fill all
-                 columns with TRUNCATE if TRUNCATE is specified.  */
-             if (truncate)
+             else if (p1 + columns > end)
                {
-                 while (p1 < end)
-                   *p1++ = fix_glyph (f, truncate, 0);
-                 /* And tell the line is truncated.  */
-                 truncated = 1;
+                 /* Since we can't show the right part of C, fill all
+                    columns with TRUNCATE if TRUNCATE is specified.  */
+                 if (truncate)
+                   {
+                     while (p1 < end)
+                       *p1++ = fix_glyph (f, truncate, 0);
+                     /* And tell the line is truncated.  */
+                     truncated = 1;
+                   }
+                 break;
+               }
+             else
+               {
+                 /* We can show the whole glyph of C.  */
+                 *p1++ = c;
+                 while (--columns)
+                   *p1++ = c | GLYPH_MASK_PADDING;
                }
-             break;
            }
-         else
+
+         while (remaining_bytes > 0)
            {
-             /* We can show the whole glyph of C.  */
-             *p1++ = c;
-             while (--columns)
-               *p1++ = c | GLYPH_MASK_PADDING;
+             c = *(string - remaining_bytes--);
+
+             if (p1 >= start)
+               *p1 = (fix_glyph
+                      (f, (dp && INTEGERP (DISP_ESCAPE_GLYPH (dp))
+                           && GLYPH_CHAR_VALID_P (XINT (DISP_ESCAPE_GLYPH (dp)))
+                           ? XINT (DISP_ESCAPE_GLYPH (dp)) : '\\'),
+                       0));
+             p1++;
+             if (p1 >= start && p1 < end)
+               *p1 = (c >> 6) + '0';
+             p1++;
+             if (p1 >= start && p1 < end)
+               *p1 = (7 & (c >> 3)) + '0';
+             p1++;
+             if (p1 >= start && p1 < end)
+               *p1 = (7 & c) + '0';
+             p1++;
            }
        }
     }
@@ -5376,6 +5471,9 @@ invisible_ellipsis_p (propval, list)
 void
 syms_of_xdisp ()
 {
+  staticpro (&Qinhibit_redisplay);
+  Qinhibit_redisplay = intern ("inhibit-redisplay");
+
   staticpro (&Qmenu_bar_update_hook);
   Qmenu_bar_update_hook = intern ("menu-bar-update-hook");
 
@@ -5399,6 +5497,11 @@ syms_of_xdisp ()
   last_arrow_position = Qnil;
   last_arrow_string = Qnil;
 
+  DEFVAR_LISP ("inhibit-redisplay", &Vinhibit_redisplay,
+    "Non-nil means don't actually do any redisplay.\n\
+This is used for internal purposes.");
+  Vinhibit_redisplay = Qnil;
+
   DEFVAR_LISP ("global-mode-string", &Vglobal_mode_string,
     "String (or mode line construct) included (normally) in `mode-line-format'.");
   Vglobal_mode_string = Qnil;
@@ -5442,7 +5545,7 @@ of the top or bottom of the window.");
   DEFVAR_INT ("line-number-display-limit", &line_number_display_limit,
     "*Maximum buffer size (in characters) for line number display\n\
 If the buffer is bigger than this, the line number does not appear\n\
-in the mode line..");
+in the mode line.");
   line_number_display_limit = 1000000;
 
   DEFVAR_BOOL ("highlight-nonselected-windows", &highlight_nonselected_windows,
@@ -5503,6 +5606,15 @@ is not valid when these functions are called.");
     "*Number of characters of overlap when scrolling a one-line window.\n\
 This commonly affects the minibuffer window, hence the name of the variable.");
   minibuffer_scroll_overlap = 20;
+
+  DEFVAR_BOOL ("unibyte-display-via-language-environment",
+              &unibyte_display_via_language_environment,
+   "*Non-nil means display unibyte text according to language environment.\n\
+Specifically this means that unibyte non-ASCII characters\n\
+are displayed by converting them to the equivalent multibyte characters\n\
+according to the current language environment.  As a result, they are\n\
+displayed according to the current fontset.");
+  unibyte_display_via_language_environment = 0;
 }
 
 /* initialize the window system */