*** empty log message ***
[bpt/emacs.git] / src / xdisp.c
index cc5c3e3..2808c51 100644 (file)
@@ -1,5 +1,5 @@
 /* Display generation from window structure and buffer text.
-   Copyright (C) 1985, 1986, 1987, 1988 Free Software Foundation, Inc.
+   Copyright (C) 1985, 1986, 1987, 1988, 1992 Free Software Foundation, Inc.
 
 This file is part of GNU Emacs.
 
@@ -167,28 +167,9 @@ int clip_changed;
 int windows_or_buffers_changed;
 
 \f
-#ifndef MULTI_SCREEN
-
-DEFUN ("redraw-display", Fredraw_display, Sredraw_display, 0, 0, "",
-  "Clear the screen and output again what is supposed to appear on it.")
-  ()
-{
-  if (screen_height == 0) abort (); /* Some bug zeros some core */
-  clear_screen ();
-  fflush (stdout);
-  clear_screen_records ();
-  if (screen_height == 0) abort (); /* Some bug zeros some core */
-  windows_or_buffers_changed++;
-  /* Mark all windows as INaccurate,
-     so that every window will have its redisplay done.  */
-  mark_window_display_accurate (XWINDOW (minibuf_window)->prev, 0);
-  if (screen_height == 0) abort (); /* Some bug zeros some core */
-  return Qnil;
-}
-
-#endif /* not MULTI_SCREEN */
-\f
-char *message_buf;
+/* Nonzero if SCREEN_MESSAGE_BUF (selected_screen) is being used by print;
+   zero if being used by message.  */
+int message_buf_print;
 
 /* dump an informative message to the minibuf */
 /* VARARGS 1 */
@@ -206,22 +187,37 @@ message (m, a1, a2, a3)
       fprintf (stderr, "\n");
       fflush (stderr);
     }
-  else if (INTERACTIVE)
+  /* A null message buffer means that the screen hasn't really been
+     initialized yet.  Error messages get reported properly by
+     cmd_error, so this must be just an informative message; toss it.  */
+  else if (INTERACTIVE && SCREEN_MESSAGE_BUF (selected_screen))
     {
+#ifdef MULTI_SCREEN
+      choose_minibuf_screen ();
+      Fmake_screen_visible (WINDOW_SCREEN (XWINDOW (minibuf_window)));
+#endif
+
+      {
 #ifdef NO_ARG_ARRAY
-      int a[3];
-      a[0] = a1;
-      a[1] = a2;
-      a[2] = a3;
+       int a[3];
+       a[0] = a1;
+       a[1] = a2;
+       a[2] = a3;
 
-      doprnt (SCREEN_MESSAGE_BUF (selected_screen),
-             SCREEN_WIDTH (selected_screen), m, 0, 3, a);
+       doprnt (SCREEN_MESSAGE_BUF (selected_screen),
+               SCREEN_WIDTH (selected_screen), m, 0, 3, a);
 #else
-      doprnt (SCREEN_MESSAGE_BUF (selected_screen),
-             SCREEN_WIDTH (selected_screen), m, 0, 3, &a1);
-#endif /* NO_ARG_ARRAY */
+       doprnt (SCREEN_MESSAGE_BUF (selected_screen),
+               SCREEN_WIDTH (selected_screen), m, 0, 3, &a1);
+#endif                         /* NO_ARG_ARRAY */
+      }
 
       echo_area_glyphs = SCREEN_MESSAGE_BUF (selected_screen);
+
+      /* Print should start at the beginning of the message
+        buffer next time.  */
+      message_buf_print = 0;
+
       do_pending_window_change ();
       echo_area_display ();
       update_screen (XSCREEN (XWINDOW (minibuf_window)->screen), 1, 1);
@@ -234,9 +230,6 @@ void
 message1 (m)
      char *m;
 {
-  if (!NULL (Vwindow_system) && SCREEN_IS_TERMCAP (selected_screen))
-    return;
-
   if (noninteractive)
     {
       if (noninteractive_need_newline)
@@ -245,8 +238,16 @@ message1 (m)
       fprintf (stderr, "%s\n", m);
       fflush (stderr);
     }
-  else if (INTERACTIVE)
+  /* A null message buffer means that the screen hasn't really been
+     initialized yet.  Error messages get reported properly by
+     cmd_error, so this must be just an informative message; toss it.  */
+  else if (INTERACTIVE && SCREEN_MESSAGE_BUF (selected_screen))
     {
+#ifdef MULTI_SCREEN
+      choose_minibuf_screen ();
+      Fmake_screen_visible (WINDOW_SCREEN (XWINDOW (minibuf_window)));
+#endif
+
       echo_area_glyphs = m;
       do_pending_window_change ();
       echo_area_display ();
@@ -263,9 +264,9 @@ echo_area_display ()
 
 #ifdef MULTI_SCREEN
   choose_minibuf_screen ();
-  s = XSCREEN (XWINDOW (minibuf_window)->screen);
+  s = XSCREEN (WINDOW_SCREEN (XWINDOW (minibuf_window)));
 
-  if (!s->visible)
+  if (! SCREEN_VISIBLE_P (s))
     return;
 #endif
 
@@ -285,7 +286,19 @@ echo_area_display ()
 
       /* If desired cursor location is on this line, put it at end of text */
       if (SCREEN_CURSOR_Y (s) == vpos)
-       SCREEN_CURSOR_X (s) = s->desired_glyphs->used[vpos];
+       SCREEN_CURSOR_X (s) = SCREEN_DESIRED_GLYPHS (s)->used[vpos];
+
+      /* Fill the rest of the minibuffer window with blank lines.  */
+      {
+       int i;
+
+       for (i = vpos + 1; i < vpos + XWINDOW (minibuf_window)->height; i++)
+         {
+           get_display_line (s, i, 0);
+           display_string (XWINDOW (minibuf_window), vpos,
+                           "", 0, 0, 0, SCREEN_WIDTH (s));
+         }
+      }
     }
   else if (!EQ (minibuf_window, selected_window))
     windows_or_buffers_changed++;
@@ -334,6 +347,10 @@ redisplay ()
       screen_garbaged = 0;
     }
 
+  /* Normally the message* functions will have already displayed and
+     updated the echo area, but the screen may have been trashed, or
+     the update may have been preempted, so display the echo area
+     again here.  */
   if (echo_area_glyphs || previous_echo_glyphs)
     {
       echo_area_display ();
@@ -355,10 +372,6 @@ redisplay ()
   SCREEN_SCROLL_BOTTOM_VPOS (XSCREEN (w->screen)) = -1;
 
   all_windows = update_mode_lines || buffer_shared > 1;
-#ifdef MULTI_SCREEN
-  all_windows |= (XTYPE (Vglobal_minibuffer_screen) == Lisp_Screen
-                 && selected_screen != XSCREEN (Vglobal_minibuffer_screen));
-#endif /* MULTI_SCREEN */
 
   /* If specs for an arrow have changed, do thorough redisplay
      to ensure we remove any arrow that should no longer exist.  */
@@ -368,12 +381,12 @@ redisplay ()
 
   tlbufpos = this_line_bufpos;
   tlendpos = this_line_endpos;
-  if (!all_windows && tlbufpos > 0 && NULL (w->update_mode_line)
+  if (!all_windows && tlbufpos > 0 && NILP (w->update_mode_line)
       && SCREEN_VISIBLE_P (XSCREEN (w->screen))
       /* Make sure recorded data applies to current buffer, etc */
       && this_line_buffer == current_buffer
       && current_buffer == XBUFFER (w->buffer)
-      && NULL (w->force_start)
+      && NILP (w->force_start)
       /* Point must be on the line that we have info recorded about */
       && point >= tlbufpos
       && point <= Z - tlendpos
@@ -382,6 +395,13 @@ redisplay ()
       && (XFASTINT (w->last_modified) >= MODIFF
          || (beg_unchanged >= tlbufpos - 1
              && GPT >= tlbufpos
+             /* If selective display, can't optimize
+                if the changes start at the beginning of the line.  */
+             && ((XTYPE (current_buffer->selective_display) == Lisp_Int
+                  && XINT (current_buffer->selective_display) > 0
+                  ? (beg_unchanged >= tlbufpos
+                     && GPT > tlbufpos)
+                  : 1))
              && end_unchanged >= tlendpos
              && Z - GPT >= tlendpos)))
     {
@@ -426,7 +446,8 @@ redisplay ()
                                 XFASTINT (w->width) - 1
                                 - (XFASTINT (w->width) + XFASTINT (w->left)
                                    != SCREEN_WIDTH (selected_screen)),
-                                XINT (w->hscroll), 0);
+                                XINT (w->hscroll),
+                                pos_tab_offset (w, tlbufpos));
          if (pos.vpos < 1)
            {
              SCREEN_CURSOR_X (selected_screen)
@@ -451,7 +472,7 @@ redisplay ()
       Lisp_Object tail;
 
       /* Recompute # windows showing selected buffer.
-        This will be increment each time such a window is displayed.  */
+        This will be incremented each time such a window is displayed.  */
       buffer_shared = 0;
 
       for (tail = Vscreen_list; CONSP (tail); tail = XCONS (tail)->cdr)
@@ -463,24 +484,8 @@ redisplay ()
 
          s = XSCREEN (XCONS (tail)->car);
          if (s->visible)
-           {
-
-             /* Clear the echo area on screens where the minibuffer isn't.  */
-             if (s != XSCREEN (XWINDOW (minibuf_window)->screen)
-                 /* But only screens that have minibuffers.  */
-                 && s->has_minibuffer)
-               {
-                 int vpos = XFASTINT (XWINDOW (s->minibuffer_window)->top);
-                 register struct screen_glyphs *line;
-
-                 get_display_line (s, vpos, 0);
-                 display_string (XWINDOW (s->minibuffer_window), vpos, "",
-                                 0, 0, 0, s->width);
-               }
-
-             /* Redraw its windows.  */
-             redisplay_windows (SCREEN_ROOT_WINDOW (s));
-           }
+           /* Redraw its windows.  */
+           redisplay_windows (SCREEN_ROOT_WINDOW (s));
        }
 #else
     redisplay_windows (SCREEN_ROOT_WINDOW (s));
@@ -518,7 +523,7 @@ update:
          s = XSCREEN (XCONS (tail)->car);
          if (s->visible)
            {
-             pause |= update_screen (s, 0, 0, SCREEN_SCROLL_BOTTOM_VPOS (s));
+             pause |= update_screen (s, 0, 0);
              if (!pause)
                mark_window_display_accurate (s->root_window, 1);
            }
@@ -526,15 +531,31 @@ update:
     }
   else
 #endif /* MULTI_SCREEN */
-    if (SCREEN_VISIBLE_P (selected_screen))
-      pause = update_screen (selected_screen, 0, 0);
+    {
+      if (SCREEN_VISIBLE_P (selected_screen))
+       pause = update_screen (selected_screen, 0, 0);
+#ifdef MULTI_SCREEN
+      /* We may have called echo_area_display at the top of this
+        function.  If the echo area is on another screen, that may
+        have put text on a screen other than the selected one, so the
+        above call to update_screen would not have caught it.  Catch
+        it here.  */
+      {
+       SCREEN_PTR mini_screen =
+         XSCREEN (WINDOW_SCREEN (XWINDOW (minibuf_window)));
+       
+       if (mini_screen != selected_screen)
+         pause |= update_screen (mini_screen, 0, 0);
+      }
+#endif
+    }
 
   /* If screen does not match, prevent doing single-line-update next time.
      Also, don't forget to check every line to update the arrow.  */
   if (pause)
     {
       this_line_bufpos = 0;
-      if (!NULL (last_arrow_position))
+      if (!NILP (last_arrow_position))
        {
          last_arrow_position = Qt;
          last_arrow_string = Qt;
@@ -620,11 +641,11 @@ mark_window_display_accurate (window, flag)
 {
   register struct window *w;
 
-  for (;!NULL (window); window = w->next)
+  for (;!NILP (window); window = w->next)
     {
       w = XWINDOW (window);
 
-      if (!NULL (w->buffer))
+      if (!NILP (w->buffer))
        XFASTINT (w->last_modified)
          = !flag ? 0
            : XBUFFER (w->buffer) == current_buffer
@@ -632,9 +653,9 @@ mark_window_display_accurate (window, flag)
       w->window_end_valid = Qt;
       w->update_mode_line = Qnil;
 
-      if (!NULL (w->vchild))
+      if (!NILP (w->vchild))
        mark_window_display_accurate (w->vchild, flag);
-      if (!NULL (w->hchild))
+      if (!NILP (w->hchild))
        mark_window_display_accurate (w->hchild, flag);
     }
 
@@ -657,7 +678,7 @@ static void
 redisplay_windows (window)
      Lisp_Object window;
 {
-  for (; !NULL (window); window = XWINDOW (window)->next)
+  for (; !NILP (window); window = XWINDOW (window)->next)
     redisplay_window (window, 0);
 }
 
@@ -685,32 +706,51 @@ redisplay_window (window, just_this_one)
 
   /* If this is a combination window, do its children; that's all.  */
 
-  if (!NULL (w->vchild))
+  if (!NILP (w->vchild))
     {
       redisplay_windows (w->vchild);
       return;
     }
-  if (!NULL (w->hchild))
+  if (!NILP (w->hchild))
     {
       redisplay_windows (w->hchild);
       return;
     }
-  if (NULL (w->buffer))
+  if (NILP (w->buffer))
     abort ();
+  
+  height = window_internal_height (w);
+
+  if (MINI_WINDOW_P (w))
+    {
+      if (w == XWINDOW (minibuf_window))
+       {
+         if (echo_area_glyphs)
+           /* We've already displayed the echo area glyphs, if any.  */
+           return;
+       }
+      else
+       {
+         /* This is a minibuffer, but it's not the currently active one, so
+            clear it.  */
+         int vpos = XFASTINT (XWINDOW (SCREEN_MINIBUF_WINDOW (s))->top);
+         int i;
+
+         for (i = 0; i < height; i++)
+           {
+             get_display_line (s, vpos + i, 0);
+             display_string (w, vpos + i, "", 0, 0, 0, width);
+           }
+         
+         return;
+       }
+    }
 
   if (update_mode_lines)
     w->update_mode_line = Qt;
 
   /* Otherwise set up data on this window; select its buffer and point value */
 
-  height = window_internal_height (w);
-
-  if (MINI_WINDOW_P (w)
-      && (echo_area_glyphs
-         /* Don't display minibuffers except minibuf_window.  */
-         || w != XWINDOW (minibuf_window)))
-    return;
-
   current_buffer = XBUFFER (w->buffer);
   opoint = point;
 
@@ -728,30 +768,31 @@ redisplay_window (window, just_this_one)
       SET_PT (marker_position (w->pointm));
       if (point < BEGV)
        {
-         point = BEGV;
+         SET_PT (BEGV);
          Fset_marker (w->pointm, make_number (point), Qnil);
        }
       else if (point > (ZV - 1))
        {
-         point = ZV;
+         SET_PT (ZV);
          Fset_marker (w->pointm, make_number (point), Qnil);
        }
     }
 
   /* If window-start is screwed up, choose a new one.  */
-
   if (XMARKER (w->start)->buffer != current_buffer)
     goto recenter;
 
   startp = marker_position (w->start);
 
-  /* Handle case where place to start displaying has been specified */
-
-  if (!NULL (w->force_start))
+  /* Handle case where place to start displaying has been specified,
+     unless the specified location is outside the visible range.  */
+  if (!NILP (w->force_start))
     {
       w->update_mode_line = Qt;
       w->force_start = Qnil;
       XFASTINT (w->last_modified) = 0;
+      if (startp < BEGV) startp = BEGV;
+      if (startp > ZV)   startp = ZV;
       try_window (window, startp);
       if (cursor_vpos < 0)
        {
@@ -819,7 +860,7 @@ redisplay_window (window, just_this_one)
     }
   /* If current starting point was originally the beginning of a line
      but no longer is, find a new starting point.  */
-  else if (!NULL (w->start_at_line_beg)
+  else if (!NILP (w->start_at_line_beg)
           && !(startp == BEGV
                || FETCH_CHAR (startp - 1) == '\n'))
     {
@@ -846,7 +887,7 @@ redisplay_window (window, just_this_one)
     }
   else if (startp >= BEGV && startp <= ZV
           /* Avoid starting display at end of buffer! */
-          && (startp <= ZV || startp == BEGV
+          && (startp < ZV || startp == BEGV
               || (XFASTINT (w->last_modified) >= MODIFF)))
     {
       /* Try to redisplay starting at same place as before */
@@ -900,7 +941,7 @@ recenter:
 done:
   /* If window not full width, must redo its mode line
      if the window to its side is being redone */
-  if ((!NULL (w->update_mode_line)
+  if ((!NILP (w->update_mode_line)
        || (!just_this_one && width < SCREEN_WIDTH (s) - 1))
       && height != XFASTINT (w->height))
     display_mode_line (w);
@@ -1003,10 +1044,25 @@ try_window_id (window)
 
   /* Find position before which nothing is changed.  */
   bp = *compute_motion (start, 0, lmargin,
-                       beg_unchanged + 1, 10000, 10000, width, hscroll,
+                       beg_unchanged + 1, height + 1, 0, width, hscroll,
                        pos_tab_offset (w, start));
   if (bp.vpos >= height)
-    return point < bp.bufpos && !bp.contin;
+    {
+      if (point < bp.bufpos && !bp.contin)
+       {
+         /* All changes are below the screen, and point is on the screen.
+            We don't need to change the screen at all.
+            But we need to update window_end_pos to account for
+            any change in buffer size.  */
+         bp = *compute_motion (start, 0, lmargin,
+                               Z, height, 0,
+                               width, hscroll, pos_tab_offset (w, start));
+         XFASTINT (w->window_end_vpos) = height;
+         XFASTINT (w->window_end_pos) = Z - bp.bufpos;
+         return 1;
+       }
+      return 0;
+    }
 
   vpos = bp.vpos;
 
@@ -1021,7 +1077,12 @@ try_window_id (window)
   /* If about to start displaying at the beginning of a continuation line,
      really start with previous screen line, in case it was not
      continued when last redisplayed */
-  if (bp.contin && bp.bufpos - 1 == beg_unchanged && vpos > 0)
+  if ((bp.contin && bp.bufpos - 1 == beg_unchanged && vpos > 0)
+      ||
+      /* Likewise if we have to worry about selective display.  */
+      (XTYPE (current_buffer->selective_display) == Lisp_Int
+       && XINT (current_buffer->selective_display) > 0
+       && bp.bufpos - 1 == beg_unchanged && vpos > 0))
     {
       bp = *vmotion (bp.bufpos, -1, width, hscroll, window);
       --vpos;
@@ -1314,8 +1375,8 @@ try_window_id (window)
   return 1;
 }
 \f
-/* Copy part of the contents of the string FROM into a glyph-vector at S.
-   But don't actually copy the parts that would come in before T.
+/* Copy glyphs from the rope FROM to T.
+   But don't actually copy the parts that would come in before S.
    Value is T, advanced past the copied data.
 
    Characters in FROM are grouped into units of `sizeof GLYPH' chars;
@@ -1374,7 +1435,7 @@ display_text_line (w, start, vpos, hpos, taboffset)
   register GLYPH *p1prev;
   SCREEN_PTR s = XSCREEN (w->screen);
   int tab_width = XINT (current_buffer->tab_width);
-  int ctl_arrow = !NULL (current_buffer->ctl_arrow);
+  int ctl_arrow = !NILP (current_buffer->ctl_arrow);
   int width = XFASTINT (w->width) - 1
     - (XFASTINT (w->width) + XFASTINT (w->left) != SCREEN_WIDTH (s));
   struct position val;
@@ -1384,13 +1445,13 @@ display_text_line (w, start, vpos, hpos, taboffset)
   int truncate = hscroll
     || (truncate_partial_width_windows
        && XFASTINT (w->width) < SCREEN_WIDTH (s))
-    || !NULL (current_buffer->truncate_lines);
+    || !NILP (current_buffer->truncate_lines);
   int selective
     = XTYPE (current_buffer->selective_display) == Lisp_Int
       ? XINT (current_buffer->selective_display)
-       : !NULL (current_buffer->selective_display) ? -1 : 0;
+       : !NILP (current_buffer->selective_display) ? -1 : 0;
 #ifndef old
-  int selective_e = selective && !NULL (current_buffer->selective_display_ellipses);
+  int selective_e = selective && !NILP (current_buffer->selective_display_ellipses);
 #endif
   register struct screen_glyphs *desired_glyphs = SCREEN_DESIRED_GLYPHS (s);
   register struct Lisp_Vector *dp = window_display_table (w);
@@ -1489,7 +1550,7 @@ display_text_line (w, start, vpos, hpos, taboffset)
          while ((p1 - startp + taboffset + hscroll - (hscroll > 0))
                 % tab_width);
        }
-      else if (c == Ctl('M') && selective == -1)
+      else if (c == Ctl ('M') && selective == -1)
        {
          pos = find_next_newline (pos, 1);
          if (FETCH_CHAR (pos - 1) == '\n')
@@ -1514,7 +1575,7 @@ display_text_line (w, start, vpos, hpos, taboffset)
            *p1 = (dp && XTYPE (DISP_CTRL_GLYPH (dp)) == Lisp_Int
                   ? XINT (DISP_CTRL_GLYPH (dp)) : '^');
          p1++;
-         if (p1 >= startp)
+         if (p1 >= startp && p1 < endp)
            *p1 = c ^ 0100;
          p1++;
        }
@@ -1524,13 +1585,13 @@ display_text_line (w, start, vpos, hpos, taboffset)
            *p1 = (dp && XTYPE (DISP_ESCAPE_GLYPH (dp)) == Lisp_Int
                   ? XINT (DISP_ESCAPE_GLYPH (dp)) : '\\');
          p1++;
-         if (p1 >= startp)
+         if (p1 >= startp && p1 < endp)
            *p1 = (c >> 6) + '0';
          p1++;
-         if (p1 >= startp)
+         if (p1 >= startp && p1 < endp)
            *p1 = (7 & (c >> 3)) + '0';
          p1++;
-         if (p1 >= startp)
+         if (p1 >= startp && p1 < endp)
            *p1 = (7 & c) + '0';
          p1++;
        }
@@ -1701,17 +1762,16 @@ display_mode_line (w)
      and the rest of this line is mode lines of the sibling windows).  */
   if (XFASTINT (w->width) == SCREEN_WIDTH (s)
       || XFASTINT (XWINDOW (w->parent)->width) == SCREEN_WIDTH (s))
-    s->desired_glyphs->highlight[vpos] = mode_line_inverse_video;
+    SCREEN_DESIRED_GLYPHS (s)->highlight[vpos] = mode_line_inverse_video;
 
 #ifdef HAVE_X_WINDOWS
   /* I'm trying this out because I saw Unimpress use it, but it's
-     possible that this may fuck adversely with some window managers.  jla */
+     possible that this may mess adversely with some window managers.  jla */
 
   if (SCREEN_IS_X (s)
-      && (XTYPE (Vglobal_minibuffer_screen) != Lisp_Screen
-         || s != XSCREEN (Vglobal_minibuffer_screen))
+      && ! SCREEN_MINIBUF_ONLY_P (s)
       && w == XWINDOW (s->selected_window)
-      && (NULL (Fstring_equal (XBUFFER (w->buffer)->name, s->name))))
+      && (NILP (Fstring_equal (XBUFFER (w->buffer)->name, s->name))))
     x_set_name (s, XBUFFER (w->buffer)->name, Qnil);
 #endif
 }
@@ -1818,7 +1878,7 @@ display_mode_element (w, vpos, hpos, depth, minendcol, maxendcol, elt)
       {
        register Lisp_Object tem;
        tem = Fboundp (elt);
-       if (!NULL (tem))
+       if (!NILP (tem))
          {
            tem = Fsymbol_value (elt);
            /* If value is a string, output that string literally:
@@ -1854,17 +1914,17 @@ display_mode_element (w, vpos, hpos, depth, minendcol, maxendcol, elt)
              goto invalid;
            /* elt is now the cdr, and we know it is a cons cell.
               Use its car if CAR has a non-nil value.  */
-           if (!NULL (tem))
+           if (!NILP (tem))
              {
                tem = Fsymbol_value (car);
-               if (!NULL (tem))
+               if (!NILP (tem))
                  { elt = XCONS (elt)->car; goto tail_recurse; }
              }
            /* Symbol's value is nil (or symbol is unbound)
               Get the cddr of the original list
               and if possible find the caddr and use that.  */
            elt = XCONS (elt)->cdr;
-           if (NULL (elt))
+           if (NILP (elt))
              break;
            else if (XTYPE (elt) != Lisp_Cons)
              goto invalid;
@@ -1958,7 +2018,7 @@ decode_mode_spec (w, c, maxwidth)
     case 'f': 
       obj = current_buffer->filename;
 #if 0
-      if (NULL (obj))
+      if (NILP (obj))
        return "[none]";
       else if (XTYPE (obj) == Lisp_String && XSTRING (obj)->size > maxwidth)
        {
@@ -1980,7 +2040,7 @@ decode_mode_spec (w, c, maxwidth)
       break;
 
     case '*':
-      if (!NULL (current_buffer->read_only))
+      if (!NILP (current_buffer->read_only))
        return "%";
       if (MODIFF > current_buffer->save_modified)
        return "*";
@@ -1988,15 +2048,11 @@ decode_mode_spec (w, c, maxwidth)
 
     case 's':
       /* status of process */
-#ifdef subprocesses
       obj = Fget_buffer_process (Fcurrent_buffer ());
-      if (NULL (obj))
+      if (NILP (obj))
        return "no process";
       obj = Fsymbol_name (Fprocess_status (obj));
       break;
-#else
-      return "no processes";
-#endif /* subprocesses */
 
     case 'p':
       {
@@ -2163,7 +2219,7 @@ display_string (w, vpos, string, hpos, truncate, mincol, maxcol)
            *p1 = (dp && XTYPE (DISP_CTRL_GLYPH (dp)) == Lisp_Int
                   ? XINT (DISP_CTRL_GLYPH (dp)) : '^');
          p1++;
-         if (p1 >= start)
+         if (p1 >= start && p1 < end)
            *p1 = c ^ 0100;
          p1++;
        }
@@ -2173,13 +2229,13 @@ display_string (w, vpos, string, hpos, truncate, mincol, maxcol)
            *p1 = (dp && XTYPE (DISP_ESCAPE_GLYPH (dp)) == Lisp_Int
                   ? XINT (DISP_ESCAPE_GLYPH (dp)) : '\\');
          p1++;
-         if (p1 >= start)
+         if (p1 >= start && p1 < end)
            *p1 = (c >> 6) + '0';
          p1++;
-         if (p1 >= start)
+         if (p1 >= start && p1 < end)
            *p1 = (7 & (c >> 3)) + '0';
          p1++;
-         if (p1 >= start)
+         if (p1 >= start && p1 < end)
            *p1 = (7 & c) + '0';
          p1++;
        }
@@ -2245,10 +2301,6 @@ If this is zero, point is always centered after it moves off screen.");
   DEFVAR_BOOL ("mode-line-inverse-video", &mode_line_inverse_video,
     "*Non-nil means use inverse video for the mode line.");
   mode_line_inverse_video = 1;
-
-#ifndef MULTI_SCREEN
-  defsubr (&Sredraw_display);
-#endif /* MULTI_SCREEN */
 }
 
 /* initialize the window system */