(mail-setup): Call set-buffer-multibyte because
[bpt/emacs.git] / src / window.c
index f2af5e3..baa55a5 100644 (file)
@@ -430,7 +430,7 @@ NCOL should be zero or positive.")
   if (XINT (w->hscroll) != hscroll)
     XBUFFER (w->buffer)->prevent_redisplay_optimizations_p = 1;
   
-  w->hscroll = w->min_hscroll = make_number (hscroll);
+  w->hscroll = make_number (hscroll);
   return ncol;
 }
 
@@ -864,7 +864,7 @@ DEFUN ("window-end", Fwindow_end, Swindow_end, 0, 2, 0,
 This is updated by redisplay, when it runs to completion.\n\
 Simply changing the buffer text or setting `window-start'\n\
 does not update this value.\n\
-If UP-TO-DATE is non-nil, compute the up-to-date position\n\
+If UPDATE is non-nil, compute the up-to-date position\n\
 if it isn't already recorded.")
   (window, update)
      Lisp_Object window, update;
@@ -908,6 +908,7 @@ if it isn't already recorded.")
         cope with variable-height lines.  */
       start_display (&it, w, startp);
       move_it_vertically (&it, window_box_height (w));
+      move_it_past_eol (&it);
       value = make_number (IT_CHARPOS (it));
     }
   else
@@ -1690,8 +1691,7 @@ window_list_1 (window, minibuf, all_frames)
                 Qnil, look at just the selected frame;
                Qvisible, look at visible frames;
                a frame, just look at windows on that frame.
-   If MINI is non-zero, perform the operation on minibuffer windows too.
-*/
+   If MINI is non-zero, perform the operation on minibuffer windows too.  */
 
 enum window_loop
 {
@@ -1988,13 +1988,12 @@ value is reasonable when this function is called.")
 {
   struct window *w;
   int startpos;
-  int top;
+  int top, new_top;
 
   if (NILP (window))
     window = selected_window;
   else
     CHECK_LIVE_WINDOW (window, 0);
-
   w = XWINDOW (window);
 
   startpos = marker_position (w->start);
@@ -2010,7 +2009,9 @@ value is reasonable when this function is called.")
      on the frame.  But don't try to do this if the window start is
      outside the visible portion (as might happen when the display is
      not current, due to typeahead).  */
-  if (startpos >= BUF_BEGV (XBUFFER (w->buffer))
+  new_top = XFASTINT (w->top) - FRAME_TOP_MARGIN (XFRAME (WINDOW_FRAME (w)));
+  if (new_top != top
+      && startpos >= BUF_BEGV (XBUFFER (w->buffer))
       && startpos <= BUF_ZV (XBUFFER (w->buffer)))
     {
       struct position pos;
@@ -2022,6 +2023,7 @@ value is reasonable when this function is called.")
       pos = *vmotion (startpos, -top, w);
 
       set_marker_both (w->start, w->buffer, pos.bufpos, pos.bytepos);
+      w->window_end_valid = Qnil;
       w->start_at_line_beg = ((pos.bytepos == BEGV_BYTE
                               || FETCH_BYTE (pos.bytepos - 1) == '\n') ? Qt
                              : Qnil);
@@ -2410,8 +2412,6 @@ size_window (window, size, width_p, nodelete_p)
   /* Maybe delete WINDOW if it's too small.  */
   if (!nodelete_p && !NILP (w->parent))
     {
-      int min_size;
-
       if (!MINI_WINDOW_P (w) && !NILP (w->too_small_ok))
        min_size = width_p ? MIN_SAFE_WINDOW_WIDTH : MIN_SAFE_WINDOW_HEIGHT;
       else
@@ -3995,10 +3995,13 @@ window_scroll_pixel_based (window, n, whole, noerror)
        {
          if (it.current_y + it.max_ascent + it.max_descent
              > it.last_visible_y)
-           /* The last line was only partially visible, make it fully
-              visible.  */
-           w->vscroll = (it.last_visible_y
-                         - it.current_y + it.max_ascent + it.max_descent);
+           {
+             /* The last line was only partially visible, make it fully
+                visible.  */
+             w->vscroll = (it.last_visible_y
+                           - it.current_y + it.max_ascent + it.max_descent);
+             adjust_glyphs (it.f);
+           }
          else if (noerror)
            return;
          else
@@ -4404,16 +4407,22 @@ Default for ARG is window width minus 2.")
   (arg)
      register Lisp_Object arg;
 {
-
+  Lisp_Object result;
+  int hscroll;
+  struct window *w = XWINDOW (selected_window);
+  
   if (NILP (arg))
-    XSETFASTINT (arg, window_internal_width (XWINDOW (selected_window)) - 2);
+    XSETFASTINT (arg, window_internal_width (w) - 2);
   else
     arg = Fprefix_numeric_value (arg);
 
-  return
-    Fset_window_hscroll (selected_window,
-                        make_number (XINT (XWINDOW (selected_window)->hscroll)
-                                     + XINT (arg)));
+  hscroll = XINT (w->hscroll) + XINT (arg);
+  result = Fset_window_hscroll (selected_window, make_number (hscroll));
+
+  if (!NILP (Finteractive_p ()))
+    w->min_hscroll = w->hscroll;
+
+  return result;
 }
 
 DEFUN ("scroll-right", Fscroll_right, Sscroll_right, 0, 1, "P",
@@ -4422,72 +4431,24 @@ Default for ARG is window width minus 2.")
   (arg)
      register Lisp_Object arg;
 {
+  Lisp_Object result;
+  int hscroll;
+  struct window *w = XWINDOW (selected_window);
+  
   if (NILP (arg))
-    XSETFASTINT (arg, window_internal_width (XWINDOW (selected_window)) - 2);
+    XSETFASTINT (arg, window_internal_width (w) - 2);
   else
     arg = Fprefix_numeric_value (arg);
 
-  return
-    Fset_window_hscroll (selected_window,
-                        make_number (XINT (XWINDOW (selected_window)->hscroll)
-                                     - XINT (arg)));
-}
-
-DEFUN ("recenter", Frecenter, Srecenter, 0, 1, "P",
-  "Center point in window and redisplay frame.  With ARG, put point on line ARG.\n\
-The desired position of point is always relative to the current window.\n\
-Just C-u as prefix means put point in the center of the window.\n\
-If ARG is omitted or nil, erases the entire frame and then\n\
-redraws with point in the center of the current window.")
-  (arg)
-     register Lisp_Object arg;
-{
-  register struct window *w = XWINDOW (selected_window);
-  register int ht = window_internal_height (w);
-  struct position pos;
-  struct buffer *buf = XBUFFER (w->buffer);
-  struct buffer *obuf = current_buffer;
-
-  if (NILP (arg))
-    {
-      extern int frame_garbaged;
-      int i;
-
-      /* Invalidate pixel data calculated for all compositions.  */
-      for (i = 0; i < n_compositions; i++)
-       composition_table[i]->font = NULL;
-
-      Fredraw_frame (w->frame);
-      SET_FRAME_GARBAGED (XFRAME (WINDOW_FRAME (w)));
-      XSETFASTINT (arg, ht / 2);
-    }
-  else if (CONSP (arg)) /* Just C-u. */
-    {
-      XSETFASTINT (arg, ht / 2);
-    }
-  else
-    {
-      arg = Fprefix_numeric_value (arg);
-      CHECK_NUMBER (arg, 0);
-    }
-
-  if (XINT (arg) < 0)
-    XSETINT (arg, XINT (arg) + ht);
-
-  set_buffer_internal (buf);
-  pos = *vmotion (PT, - XINT (arg), w);
-
-  set_marker_both (w->start, w->buffer, pos.bufpos, pos.bytepos);
-  w->start_at_line_beg = ((pos.bytepos == BEGV_BYTE
-                          || FETCH_BYTE (pos.bytepos - 1) == '\n')
-                         ? Qt : Qnil);
-  w->force_start = Qt;
-  set_buffer_internal (obuf);
+  hscroll = XINT (w->hscroll) - XINT (arg);
+  result = Fset_window_hscroll (selected_window, make_number (hscroll));
+  
+  if (!NILP (Finteractive_p ()))
+    w->min_hscroll = w->hscroll;
 
-  return Qnil;
+  return result;
 }
 
-
 /* Value is the number of lines actually displayed in window W,
    as opposed to its height.  */
 
@@ -4535,6 +4496,95 @@ displayed_window_lines (w)
 }
 
 
+DEFUN ("recenter", Frecenter, Srecenter, 0, 1, "P",
+  "Center point in window and redisplay frame.\n\
+With prefix argument ARG, recenter putting point on screen line ARG\n\
+relative to the current window.  If ARG is negative, it counts up from the\n\
+bottom of the window.  (ARG should be less than the height of the window.)\n\
+\n\
+If ARG is omitted or nil, erase the entire frame and then\n\
+redraw with point in the center of the current window.\n\
+Just C-u as prefix means put point in the center of the window\n\
+and redisplay normally--don't erase and redraw the frame.")
+  (arg)
+     register Lisp_Object arg;
+{
+  struct window *w = XWINDOW (selected_window);
+  struct buffer *buf = XBUFFER (w->buffer);
+  struct buffer *obuf = current_buffer;
+  int center_p = 0;
+  int charpos, bytepos;
+
+  if (NILP (arg))
+    {
+      int i;
+
+      /* Invalidate pixel data calculated for all compositions.  */
+      for (i = 0; i < n_compositions; i++)
+       composition_table[i]->font = NULL;
+
+      Fredraw_frame (w->frame);
+      SET_FRAME_GARBAGED (XFRAME (WINDOW_FRAME (w)));
+      center_p = 1;
+    }
+  else if (CONSP (arg)) /* Just C-u. */
+    center_p = 1;
+  else
+    {
+      arg = Fprefix_numeric_value (arg);
+      CHECK_NUMBER (arg, 0);
+    }
+
+  set_buffer_internal (buf);
+
+  /* Handle centering on a gfaphical frame specially.  Such frames can
+     have variable-height lines and centering point on the basis of
+     line counts would lead to strange effects.  */
+  if (center_p && FRAME_WINDOW_P (XFRAME (w->frame)))
+    {
+      struct it it;
+      struct text_pos pt;
+      
+      SET_TEXT_POS (pt, PT, PT_BYTE);
+      start_display (&it, w, pt);
+      move_it_vertically (&it, - it.last_visible_y / 2);
+      charpos = IT_CHARPOS (it);
+      bytepos = IT_BYTEPOS (it);
+    }
+  else
+    {
+      struct position pos;
+      
+      if (center_p)
+       {
+         int ht = displayed_window_lines (w);
+         arg = make_number (ht / 2);
+       }
+      else if (XINT (arg) < 0)
+       {
+         int ht = displayed_window_lines (w);
+         XSETINT (arg, XINT (arg) + ht);
+       }
+      
+      pos = *vmotion (PT, - XINT (arg), w);
+      charpos = pos.bufpos;
+      bytepos = pos.bytepos;
+    }
+
+  /* Set the new window start.  */
+  set_marker_both (w->start, w->buffer, charpos, bytepos);
+  w->window_end_valid = Qnil;
+  w->force_start = Qt;
+  if (bytepos == BEGV_BYTE || FETCH_BYTE (bytepos - 1) == '\n')
+    w->start_at_line_beg = Qt;
+  else
+    w->start_at_line_beg = Qnil;
+  
+  set_buffer_internal (obuf);
+  return Qnil;
+}
+
+
 DEFUN ("window-text-height", Fwindow_text_height, Swindow_text_height,
   0, 1, 0,
   "Return the height in lines of the text display area of WINDOW.\n\