]> code.delx.au - gnu-emacs/blobdiff - src/xdisp.c
* doc/lispref/modes.texi (Defining Minor Modes): Use C-backspace, not C-delete.
[gnu-emacs] / src / xdisp.c
index 9612f5cc9cf965093eb74ad30d19f91a4509413a..73ed675c4d23cc0842f9646b7fdb61d7e2a6e2cb 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.
 
@@ -953,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,
@@ -1363,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);
 
@@ -1373,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!  */
@@ -1981,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);
@@ -5613,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);
 }
 
@@ -5640,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)))
 
@@ -6217,8 +6195,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)
@@ -6302,7 +6280,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;
@@ -6338,7 +6316,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;
@@ -6415,7 +6393,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 +6429,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 +6504,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;
@@ -9493,32 +9473,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 +9569,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;
        }
@@ -13976,8 +13937,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*. */
@@ -16384,22 +16353,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 +16393,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 +16436,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 +17551,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 +17580,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);
@@ -18076,7 +18046,7 @@ pint2str (buf, width, d)
    readable" representation of the nonnegative integer D to BUF using
    a minimal field width WIDTH.  D should be smaller than 999.5e24. */
 
-static const const char power_letter[] =
+static const char power_letter[] =
   {
     0,  /* not used */
     'k', /* kilo */
@@ -18273,8 +18243,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 +18252,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 +18264,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 +18599,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 +18658,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 +18779,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 +18832,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 +19401,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;
 }
 
@@ -20396,6 +20370,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 +20420,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;
@@ -22666,9 +22643,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;
@@ -23587,7 +23561,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;