Remove the vc-dir-insert-directories global.
[bpt/emacs.git] / src / xdisp.c
index 588d145..bb9ec58 100644 (file)
@@ -917,12 +917,11 @@ 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 *,
-                                  Lisp_Object *));
+static char *decode_mode_spec P_ ((struct window *, int, int, int, int *));
 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,
-                              int, int, struct it *, int, int, int, int));
+                              EMACS_INT, EMACS_INT, struct it *, int, int, int, int));
 static void compute_line_metrics P_ ((struct it *));
 static void run_redisplay_end_trigger_hook P_ ((struct it *));
 static int get_overlay_strings P_ ((struct it *, int));
@@ -964,7 +963,7 @@ static void compute_stop_pos P_ ((struct it *));
 static void compute_string_pos P_ ((struct text_pos *, struct text_pos,
                                    Lisp_Object));
 static int face_before_or_after_it_pos P_ ((struct it *, int));
-static int next_overlay_change P_ ((int));
+static EMACS_INT next_overlay_change P_ ((EMACS_INT));
 static int handle_single_display_spec P_ ((struct it *, Lisp_Object,
                                           Lisp_Object, Lisp_Object,
                                           struct text_pos *, int));
@@ -1331,26 +1330,29 @@ pos_visible_p (w, charpos, x, y, rtop, rbot, rowh, vpos)
          visible_p = 1;
       if (visible_p)
        {
-         Lisp_Object window, prop;
+         if (it.method == GET_FROM_BUFFER)
+           {
+             Lisp_Object window, prop;
 
-         XSETWINDOW (window, w);
-         prop = Fget_char_property (make_number (it.position.charpos),
-                                    Qinvisible, window);
+             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;
+             /* 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 && glyph->charpos < charpos; glyph++)
-               x += glyph->pixel_width;
+                 for (; glyph < end && glyph->charpos < charpos; glyph++)
+                   x += glyph->pixel_width;
 
-             top_x = x;
+                 top_x = x;
+               }
            }
 
          *x = top_x;
@@ -1721,7 +1723,10 @@ glyph_to_pixel_coords (w, hpos, vpos, frame_x, frame_y)
    text, or we can't tell because W's current matrix is not up to
    date.  */
 
-static struct glyph *
+#ifndef HAVE_CARBON
+static
+#endif
+struct glyph *
 x_y_to_hpos_vpos (w, x, y, hpos, vpos, dx, dy, area)
      struct window *w;
      int x, y;
@@ -2317,33 +2322,6 @@ safe_eval_handler (arg)
 /* Evaluate SEXPR and return the result, or nil if something went
    wrong.  Prevent redisplay during the evaluation.  */
 
-Lisp_Object
-safe_eval (sexpr)
-     Lisp_Object sexpr;
-{
-  Lisp_Object val;
-
-  if (inhibit_eval_during_redisplay)
-    val = Qnil;
-  else
-    {
-      int count = SPECPDL_INDEX ();
-      struct gcpro gcpro1;
-
-      GCPRO1 (sexpr);
-      specbind (Qinhibit_redisplay, Qt);
-      /* Use Qt to ensure debugger does not run,
-        so there is no possibility of wanting to redisplay.  */
-      val = internal_condition_case_1 (Feval, sexpr, Qt,
-                                      safe_eval_handler);
-      UNGCPRO;
-      val = unbind_to (count, val);
-    }
-
-  return val;
-}
-
-
 /* Call function ARGS[0] with arguments ARGS[1] to ARGS[NARGS - 1].
    Return the result, or nil if something went wrong.  Prevent
    redisplay during the evaluation.  */
@@ -2390,6 +2368,27 @@ safe_call1 (fn, arg)
   return safe_call (2, args);
 }
 
+static Lisp_Object Qeval;
+
+Lisp_Object
+safe_eval (Lisp_Object sexpr)
+{
+  return safe_call1 (Qeval, sexpr);
+}
+
+/* Call function FN with one argument ARG.
+   Return the result, or nil if something went wrong.  */
+
+Lisp_Object
+safe_call2 (Lisp_Object fn, Lisp_Object arg1, Lisp_Object arg2)
+{
+  Lisp_Object args[3];
+  args[0] = fn;
+  args[1] = arg1;
+  args[2] = arg2;
+  return safe_call (3, args);
+}
+
 
 \f
 /***********************************************************************
@@ -3224,9 +3223,9 @@ compute_stop_pos (it)
    follows.  This is like `next-overlay-change' but doesn't use
    xmalloc.  */
 
-static int
+static EMACS_INT
 next_overlay_change (pos)
-     int pos;
+     EMACS_INT pos;
 {
   int noverlays;
   EMACS_INT endpos;
@@ -3241,7 +3240,7 @@ next_overlay_change (pos)
   for (i = 0; i < noverlays; ++i)
     {
       Lisp_Object oend;
-      int oendpos;
+      EMACS_INT oendpos;
 
       oend = OVERLAY_END (overlays[i]);
       oendpos = OVERLAY_POSITION (oend);
@@ -3353,7 +3352,8 @@ static enum prop_handled
 handle_face_prop (it)
      struct it *it;
 {
-  int new_face_id, next_stop;
+  int new_face_id;
+  EMACS_INT next_stop;
 
   if (!STRINGP (it->string))
     {
@@ -3521,7 +3521,7 @@ face_before_or_after_it_pos (it, before_p)
      int before_p;
 {
   int face_id, limit;
-  int next_check_charpos;
+  EMACS_INT next_check_charpos;
   struct text_pos pos;
 
   xassert (it->s == NULL);
@@ -4331,15 +4331,13 @@ handle_single_display_spec (it, spec, object, overlay, position,
             `display' property yet.  The call to pop_it in
             set_iterator_to_next will clean this up.  */
          if (BUFFERP (object))
-           it->current.pos = start_pos;
+           *position = start_pos;
        }
       else if (CONSP (value) && EQ (XCAR (value), Qspace))
        {
          it->method = GET_FROM_STRETCH;
          it->object = value;
-         it->position = start_pos;
-         if (BUFFERP (object))
-           it->current.pos = start_pos;
+         *position = it->position = start_pos;
        }
 #ifdef HAVE_WINDOW_SYSTEM
       else
@@ -4353,8 +4351,7 @@ handle_single_display_spec (it, spec, object, overlay, position,
          /* Say that we haven't consumed the characters with
             `display' property yet.  The call to pop_it in
             set_iterator_to_next will clean this up.  */
-         if (BUFFERP (object))
-           it->current.pos = start_pos;
+         *position = start_pos;
        }
 #endif /* HAVE_WINDOW_SYSTEM */
 
@@ -4634,7 +4631,7 @@ handle_auto_composed_prop (it)
                val = Qnil;
            }
        }
-      if (NILP (val))
+      if (NILP (val) && ! STRINGP (it->string))
        {
          if (limit < 0)
            limit = (STRINGP (it->string) ? SCHARS (it->string)
@@ -4743,6 +4740,7 @@ handle_composition_prop (it)
 #ifdef USE_FONT_BACKEND
          if (composition_table[id]->method == COMPOSITION_WITH_GLYPH_STRING)
            {
+             /* FIXME: This doesn't do anything!?! */
              Lisp_Object lgstring = AREF (XHASH_TABLE (composition_hash_table)
                                           ->key_and_value,
                                           cmp->hash_index * 2);
@@ -4833,7 +4831,7 @@ next_overlay_string (it)
       /* If we're at the end of the buffer, record that we have
         processed the overlay strings there already, so that
         next_element_from_buffer doesn't try it again.  */
-      if (IT_CHARPOS (*it) >= it->end_charpos)
+      if (NILP (it->string) && IT_CHARPOS (*it) >= it->end_charpos)
        it->overlay_strings_at_end_processed_p = 1;
 
       /* If we have to display `...' for invisible text, set
@@ -5090,6 +5088,7 @@ static int
 get_overlay_strings_1 (it, charpos, compute_stop_p)
      struct it *it;
      int charpos;
+     int compute_stop_p;
 {
   /* Get the first OVERLAY_STRING_CHUNK_SIZE overlay strings to
      process.  This fills IT->overlay_strings with strings, and sets
@@ -5711,6 +5710,7 @@ static int (* get_next_element[NUM_IT_METHODS]) P_ ((struct it *it)) =
   next_element_from_stretch
 };
 
+#define GET_NEXT_DISPLAY_ELEMENT(it) (*get_next_element[(it)->method]) (it)
 
 /* Load IT's display element fields with information about the next
    display element from the current position of IT.  Value is zero if
@@ -5731,7 +5731,7 @@ get_next_display_element (it)
   int success_p;
 
  get_next:
-  success_p = (*get_next_element[it->method]) (it);
+  success_p = GET_NEXT_DISPLAY_ELEMENT (it);
 
   if (it->what == IT_CHARACTER)
     {
@@ -5807,29 +5807,29 @@ get_next_display_element (it)
                 can be defined in the display table.  Fill
                 IT->ctl_chars with glyphs for what we have to
                 display.  Then, set IT->dpvec to these glyphs.  */
-             GLYPH g;
+             Lisp_Object gc;
              int ctl_len;
              int face_id, lface_id = 0 ;
-             GLYPH escape_glyph;
+             int escape_glyph;
 
              /* Handle control characters with ^.  */
 
              if (it->c < 128 && it->ctl_arrow_p)
                {
+                 int g;
+
                  g = '^';           /* default glyph for Control */
                  /* Set IT->ctl_chars[0] to the glyph for `^'.  */
                  if (it->dp
-                     && INTEGERP (DISP_CTRL_GLYPH (it->dp))
-                     && GLYPH_CHAR_VALID_P (XINT (DISP_CTRL_GLYPH (it->dp))))
+                     && (gc = DISP_CTRL_GLYPH (it->dp), GLYPH_CODE_P (gc))
+                     && GLYPH_CODE_CHAR_VALID_P (gc))
                    {
-                     g = XINT (DISP_CTRL_GLYPH (it->dp));
-                     lface_id = FAST_GLYPH_FACE (g);
+                     g = GLYPH_CODE_CHAR (gc);
+                     lface_id = GLYPH_CODE_FACE (gc);
                    }
                  if (lface_id)
                    {
-                      g = FAST_GLYPH_CHAR (g);
-                      face_id = merge_faces (it->f, Qt, lface_id,
-                                             it->face_id);
+                     face_id = merge_faces (it->f, Qt, lface_id, it->face_id);
                    }
                  else if (it->f == last_escape_glyph_frame
                           && it->face_id == last_escape_glyph_face_id)
@@ -5847,8 +5847,7 @@ get_next_display_element (it)
                    }
 
                  XSETINT (it->ctl_chars[0], g);
-                 g = it->c ^ 0100;
-                 XSETINT (it->ctl_chars[1], g);
+                 XSETINT (it->ctl_chars[1], it->c ^ 0100);
                  ctl_len = 2;
                  goto display_control;
                }
@@ -5863,8 +5862,8 @@ get_next_display_element (it)
                  face_id = merge_faces (it->f, Qnobreak_space, 0,
                                         it->face_id);
 
-                 g = it->c = ' ';
-                 XSETINT (it->ctl_chars[0], g);
+                 it->c = ' ';
+                 XSETINT (it->ctl_chars[0], ' ');
                  ctl_len = 1;
                  goto display_control;
                }
@@ -5875,17 +5874,16 @@ get_next_display_element (it)
              escape_glyph = '\\';
 
              if (it->dp
-                 && INTEGERP (DISP_ESCAPE_GLYPH (it->dp))
-                 && GLYPH_CHAR_VALID_P (XFASTINT (DISP_ESCAPE_GLYPH (it->dp))))
+                 && (gc = DISP_ESCAPE_GLYPH (it->dp), GLYPH_CODE_P (gc))
+                 && GLYPH_CODE_CHAR_VALID_P (gc))
                {
-                 escape_glyph = XFASTINT (DISP_ESCAPE_GLYPH (it->dp));
-                 lface_id = FAST_GLYPH_FACE (escape_glyph);
+                 escape_glyph = GLYPH_CODE_CHAR (gc);
+                 lface_id = GLYPH_CODE_FACE (gc);
                }
              if (lface_id)
                {
                  /* The display table specified a face.
                     Merge it into face_id and also into escape_glyph.  */
-                 escape_glyph = FAST_GLYPH_CHAR (escape_glyph);
                  face_id = merge_faces (it->f, Qt, lface_id,
                                         it->face_id);
                }
@@ -5910,8 +5908,8 @@ get_next_display_element (it)
              if (EQ (Vnobreak_char_display, Qt)
                  && it->c == 0xAD)
                {
-                 g = it->c = '-';
-                 XSETINT (it->ctl_chars[0], g);
+                 it->c = '-';
+                 XSETINT (it->ctl_chars[0], '-');
                  ctl_len = 1;
                  goto display_control;
                }
@@ -5922,8 +5920,8 @@ get_next_display_element (it)
              if (it->c == 0xA0 || it->c == 0xAD)
                {
                  XSETINT (it->ctl_chars[0], escape_glyph);
-                 g = it->c = (it->c == 0xA0 ? ' ' : '-');
-                 XSETINT (it->ctl_chars[1], g);
+                 it->c = (it->c == 0xA0 ? ' ' : '-');
+                 XSETINT (it->ctl_chars[1], it->c);
                  ctl_len = 2;
                  goto display_control;
                }
@@ -5959,6 +5957,7 @@ get_next_display_element (it)
 
                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.  */
@@ -6198,18 +6197,20 @@ static int
 next_element_from_display_vector (it)
      struct it *it;
 {
+  Lisp_Object gc;
+
   /* Precondition.  */
   xassert (it->dpvec && it->current.dpvec_index >= 0);
 
   it->face_id = it->saved_face_id;
 
-  if (INTEGERP (*it->dpvec)
-      && GLYPH_CHAR_VALID_P (XFASTINT (*it->dpvec)))
-    {
-      GLYPH g;
+  /* KFS: This code used to check ip->dpvec[0] instead of the current element.
+          That seemed totally bogus - so I changed it...  */
 
-      g = XFASTINT (it->dpvec[it->current.dpvec_index]);
-      it->c = FAST_GLYPH_CHAR (g);
+  if ((gc = it->dpvec[it->current.dpvec_index], GLYPH_CODE_P (gc))
+      && GLYPH_CODE_CHAR_VALID_P (gc))
+    {
+      it->c = GLYPH_CODE_CHAR (gc);
       it->len = CHAR_BYTES (it->c);
 
       /* The entry may contain a face id to use.  Such a face id is
@@ -6219,7 +6220,7 @@ next_element_from_display_vector (it)
        it->face_id = it->dpvec_face_id;
       else
        {
-         int lface_id = FAST_GLYPH_FACE (g);
+         int lface_id = GLYPH_CODE_FACE (gc);
          if (lface_id > 0)
            it->face_id = merge_faces (it->f, Qt, lface_id,
                                       it->saved_face_id);
@@ -6260,7 +6261,7 @@ next_element_from_string (it)
 
       /* Since a handler may have changed IT->method, we must
         recurse here.  */
-      return get_next_display_element (it);
+      return GET_NEXT_DISPLAY_ELEMENT (it);
     }
 
   if (it->current.overlay_string_index >= 0)
@@ -6398,7 +6399,7 @@ next_element_from_ellipsis (it)
       it->face_before_selective_p = 1;
     }
 
-  return get_next_display_element (it);
+  return GET_NEXT_DISPLAY_ELEMENT (it);
 }
 
 
@@ -6462,7 +6463,7 @@ next_element_from_buffer (it)
            }
 
          if (overlay_strings_follow_p)
-           success_p = get_next_display_element (it);
+           success_p = GET_NEXT_DISPLAY_ELEMENT (it);
          else
            {
              it->what = IT_EOB;
@@ -6473,7 +6474,7 @@ next_element_from_buffer (it)
       else
        {
          handle_stop (it);
-         return get_next_display_element (it);
+         return GET_NEXT_DISPLAY_ELEMENT (it);
        }
     }
   else
@@ -8633,7 +8634,7 @@ current_message ()
 {
   Lisp_Object msg;
 
-  if (NILP (echo_area_buffer[0]))
+  if (!BUFFERP (echo_area_buffer[0]))
     msg = Qnil;
   else
     {
@@ -9091,8 +9092,9 @@ static Lisp_Object mode_line_string_face_prop;
 static Lisp_Object Vmode_line_unwind_vector;
 
 static Lisp_Object
-format_mode_line_unwind_data (obuf, save_proptrans)
-     struct buffer *obuf;
+format_mode_line_unwind_data (struct buffer *obuf,
+                             Lisp_Object owin,
+                             int save_proptrans)
 {
   Lisp_Object vector, tmp;
 
@@ -9102,7 +9104,7 @@ format_mode_line_unwind_data (obuf, save_proptrans)
   Vmode_line_unwind_vector = Qnil;
 
   if (NILP (vector))
-    vector = Fmake_vector (make_number (7), Qnil);
+    vector = Fmake_vector (make_number (8), Qnil);
 
   ASET (vector, 0, make_number (mode_line_target));
   ASET (vector, 1, make_number (MODE_LINE_NOPROP_LEN (0)));
@@ -9116,6 +9118,7 @@ format_mode_line_unwind_data (obuf, save_proptrans)
   else
     tmp = Qnil;
   ASET (vector, 6, tmp);
+  ASET (vector, 7, owin);
 
   return vector;
 }
@@ -9132,6 +9135,10 @@ unwind_format_mode_line (vector)
   mode_line_string_face = AREF (vector, 4);
   mode_line_string_face_prop = AREF (vector, 5);
 
+  if (!NILP (AREF (vector, 7)))
+    /* Select window before buffer, since it may change the buffer.  */
+    Fselect_window (AREF (vector, 7), Qt);
+
   if (!NILP (AREF (vector, 6)))
     {
       set_buffer_internal_1 (XBUFFER (AREF (vector, 6)));
@@ -9251,8 +9258,10 @@ x_consider_frame_title (frame)
         mode_line_target so that display_mode_element will output into
         mode_line_noprop_buf; then display the title.  */
       record_unwind_protect (unwind_format_mode_line,
-                            format_mode_line_unwind_data (current_buffer, 0));
+                            format_mode_line_unwind_data
+                               (current_buffer, selected_window, 0));
 
+      Fselect_window (f->selected_window, Qt);
       set_buffer_internal_1 (XBUFFER (XWINDOW (f->selected_window)->buffer));
       fmt = FRAME_ICONIFIED_P (f) ? Vicon_title_format : Vframe_title_format;
 
@@ -11185,6 +11194,9 @@ redisplay_internal (preserve_echo_area)
         the whole thing.  */
       windows_or_buffers_changed++;
       SET_FRAME_GARBAGED (sf);
+#ifndef WINDOWSNT
+      set_tty_color_mode (FRAME_TTY (sf), sf);
+#endif
       FRAME_TTY (sf)->previous_frame = sf;
     }
 
@@ -11627,6 +11639,14 @@ redisplay_internal (preserve_echo_area)
            }
        }
 
+      if (!EQ (old_frame, selected_frame)
+         && FRAME_LIVE_P (XFRAME (old_frame)))
+       /* We played a bit fast-and-loose above and allowed selected_frame
+          and selected_window to be temporarily out-of-sync but let's make
+          sure this stays contained.  */
+       select_frame_for_redisplay (old_frame);
+      eassert (EQ (XFRAME (selected_frame)->selected_window, selected_window));
+
       if (!pause)
        {
          /* Do the mark_window_display_accurate after all windows have
@@ -14998,7 +15018,8 @@ try_window_id (w)
     }
   else
     {
-      delta = dvpos = dy = run.current_y = run.desired_y = run.height = 0;
+      delta = delta_bytes = dvpos = dy
+       = run.current_y = run.desired_y = run.height = 0;
       first_unchanged_at_end_row = NULL;
     }
   IF_DEBUG (debug_dvpos = dvpos; debug_dy = dy);
@@ -16923,7 +16944,7 @@ display_mode_line (w, face_id, format)
     it.base_face_id = it.face_id = DEFAULT_FACE_ID;
 
   record_unwind_protect (unwind_format_mode_line,
-                        format_mode_line_unwind_data (NULL, 0));
+                        format_mode_line_unwind_data (NULL, Qnil, 0));
 
   mode_line_target = MODE_LINE_DISPLAY;
 
@@ -17220,14 +17241,13 @@ 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,
-                                            &string);
+                   spec
+                     = decode_mode_spec (it->w, c, field, prec, &multibyte);
 
                    switch (mode_line_target)
                      {
@@ -17237,24 +17257,19 @@ display_mode_element (it, depth, field_width, precision, elt, props, risky)
                        break;
                      case MODE_LINE_STRING:
                        {
-                         if (NILP (string))
-                           {
-                             int len = strlen (spec);
-                             string = make_string (spec, len);
-                           }
+                         int len = strlen (spec);
+                         Lisp_Object tem = make_string (spec, len);
                          props = Ftext_properties_at (make_number (charpos), elt);
                          /* Should only keep face property in props */
-                         n += store_mode_line_string (NULL, string, 0, field, prec, props);
+                         n += store_mode_line_string (NULL, tem, 0, field, prec, props);
                        }
                        break;
                      case MODE_LINE_DISPLAY:
                        {
                          int nglyphs_before, nwritten;
 
-                         if (STRINGP (string))
-                           spec = NULL;
                          nglyphs_before = it->glyph_row->used[TEXT_AREA];
-                         nwritten = display_string (spec, string, elt,
+                         nwritten = display_string (spec, Qnil, elt,
                                                     charpos, 0, it,
                                                     field, prec, 0,
                                                     multibyte);
@@ -17631,9 +17646,11 @@ are the selected window and the window's buffer).  */)
   /* Save things including mode_line_proptrans_alist,
      and set that to nil so that we don't alter the outer value.  */
   record_unwind_protect (unwind_format_mode_line,
-                        format_mode_line_unwind_data (old_buffer, 1));
+                        format_mode_line_unwind_data
+                            (old_buffer, selected_window, 1));
   mode_line_proptrans_alist = Qnil;
 
+  Fselect_window (window, Qt);
   if (old_buffer)
     set_buffer_internal_1 (XBUFFER (buffer));
 
@@ -17918,19 +17935,18 @@ 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, string)
+decode_mode_spec (w, c, field_width, precision, multibyte)
      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));
   char *decode_mode_spec_buf = f->decode_mode_spec_buffer;
   struct buffer *b = current_buffer;
 
-  *string = obj = Qnil;
+  obj = Qnil;
   *multibyte = 0;
 
   switch (c)
@@ -18323,7 +18339,6 @@ decode_mode_spec (w, c, field_width, precision, multibyte, string)
   if (STRINGP (obj))
     {
       *multibyte = STRING_MULTIBYTE (obj);
-      *string = obj;
       return (char *) SDATA (obj);
     }
   else
@@ -18482,8 +18497,8 @@ display_string (string, lisp_string, face_string, face_string_pos,
      unsigned char *string;
      Lisp_Object lisp_string;
      Lisp_Object face_string;
-     int face_string_pos;
-     int start;
+     EMACS_INT face_string_pos;
+     EMACS_INT start;
      struct it *it;
      int field_width, precision, max_x;
      int multibyte;
@@ -18501,7 +18516,7 @@ display_string (string, lisp_string, face_string, face_string_pos,
      from LISP_STRING, if that's given.  */
   if (STRINGP (face_string))
     {
-      int endptr;
+      EMACS_INT endptr;
       struct face *face;
 
       it->face_id
@@ -19409,7 +19424,7 @@ fill_glyph_string (s, face_id, start, end, overlaps)
   glyph = s->row->glyphs[s->area] + start;
   last = s->row->glyphs[s->area] + end;
   voffset = glyph->voffset;
-
+  s->padding_p = glyph->padding_p;
   glyph_not_available_p = glyph->glyph_not_available_p;
 
   while (glyph < last
@@ -19428,7 +19443,8 @@ fill_glyph_string (s, face_id, start, end, overlaps)
       ++s->nchars;
       xassert (s->nchars <= end - start);
       s->width += glyph->pixel_width;
-      ++glyph;
+      if (glyph++->padding_p != s->padding_p)
+       break;
     }
 
   s->font = s->face->font;
@@ -20181,7 +20197,18 @@ append_glyph (it)
     {
       glyph->charpos = CHARPOS (it->position);
       glyph->object = it->object;
-      glyph->pixel_width = it->pixel_width;
+      if (it->pixel_width > 0)
+       {
+         glyph->pixel_width = it->pixel_width;
+         glyph->padding_p = 0;
+       }
+      else
+       {
+         /* Assure at least 1-pixel width.  Otherwise, cursor can't
+            be displayed correctly.  */
+         glyph->pixel_width = 1;
+         glyph->padding_p = 1;
+       }
       glyph->ascent = it->ascent;
       glyph->descent = it->descent;
       glyph->voffset = it->voffset;
@@ -20191,7 +20218,6 @@ append_glyph (it)
       glyph->right_box_line_p = it->end_of_box_run_p;
       glyph->overlaps_vertically_p = (it->phys_ascent > it->ascent
                                      || it->phys_descent > it->descent);
-      glyph->padding_p = 0;
       glyph->glyph_not_available_p = it->glyph_not_available_p;
       glyph->face_id = it->face_id;
       glyph->u.ch = it->char_to_display;
@@ -20914,6 +20940,10 @@ x_produce_glyphs (it)
              if (pcm && (pcm->lbearing < 0 || pcm->rbearing > pcm->width))
                it->glyph_row->contains_overlapping_glyphs_p = 1;
            }
+         if (! stretched_p && it->pixel_width == 0)
+           /* We assure that all visible glyphs have at least 1-pixel
+              width.  */
+           it->pixel_width = 1;
        }
       else if (it->char_to_display == '\n')
        {
@@ -21098,6 +21128,10 @@ x_produce_glyphs (it)
 
          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;
     }
@@ -22467,7 +22501,10 @@ cursor_in_mouse_face_p (w)
         in 20.x as well, and I think it's too risky to install
         so near the release of 21.1.  2001-09-25 gerd.  */
 
-static int
+#ifndef HAVE_CARBON
+static
+#endif
+int
 fast_find_position (w, charpos, hpos, vpos, x, y, stop)
      struct window *w;
      EMACS_INT charpos;
@@ -23059,7 +23096,7 @@ note_mode_line_or_margin_highlight (window, x, y, area)
          int gpos;
          int gseq_length;
          int total_pixel_width;
-         int ignore;
+         EMACS_INT ignore;
 
          int vpos, hpos;
 
@@ -23411,7 +23448,7 @@ note_mouse_highlight (f, x, y)
              /* Find the range of text around this char that
                 should be active.  */
              Lisp_Object before, after;
-             int ignore;
+             EMACS_INT ignore;
 
              before = Foverlay_start (overlay);
              after = Foverlay_end (overlay);
@@ -23445,7 +23482,7 @@ note_mouse_highlight (f, x, y)
              /* Find the range of text around this char that
                 should be active.  */
              Lisp_Object before, after, beginning, end;
-             int ignore;
+             EMACS_INT ignore;
 
              beginning = Fmarker_position (w->start);
              end = make_number (BUF_Z (XBUFFER (object))
@@ -23485,7 +23522,7 @@ note_mouse_highlight (f, x, y)
          else if (!NILP (mouse_face) && STRINGP (object))
            {
              Lisp_Object b, e;
-             int ignore;
+             EMACS_INT ignore;
 
              b = Fprevious_single_property_change (make_number (pos + 1),
                                                    Qmouse_face,
@@ -23532,7 +23569,7 @@ note_mouse_highlight (f, x, y)
                {
                  Lisp_Object before = Foverlay_start (overlay);
                  Lisp_Object after = Foverlay_end (overlay);
-                 int ignore;
+                 EMACS_INT ignore;
 
                  /* Note that we might not be able to find position
                     BEFORE in the glyph matrix if the overlay is
@@ -24329,6 +24366,9 @@ syms_of_xdisp ()
   staticpro (&Qinhibit_point_motion_hooks);
   Qinhibit_point_motion_hooks = intern ("inhibit-point-motion-hooks");
 
+  Qeval = intern ("eval");
+  staticpro (&Qeval);
+
   QCdata = intern (":data");
   staticpro (&QCdata);
   Qdisplay = intern ("display");
@@ -24556,7 +24596,8 @@ Value is a number or a cons (WIDTH-DPI . HEIGHT-DPI).  */);
 
   DEFVAR_BOOL ("truncate-partial-width-windows",
               &truncate_partial_width_windows,
-    doc: /* *Non-nil means truncate lines in all windows less than full frame wide.  */);
+    doc: /* *Non-nil means truncate lines in all windows less than full frame wide.
+Nil means to respect the value of `truncate-lines'.  */);
   truncate_partial_width_windows = 1;
 
   DEFVAR_BOOL ("mode-line-inverse-video", &mode_line_inverse_video,