Avoid character to byte conversions in motion subroutines.
[bpt/emacs.git] / src / window.c
index 5679c15..7769613 100644 (file)
@@ -300,15 +300,6 @@ wset_buffer (struct window *w, Lisp_Object val)
   adjust_window_count (w, 1);
 }
 
-/* Build a frequently used 4-integer (X Y W H) list.  */
-
-static Lisp_Object
-list4i (EMACS_INT x, EMACS_INT y, EMACS_INT w, EMACS_INT h)
-{
-  return list4 (make_number (x), make_number (y),
-               make_number (w), make_number (h));
-}
-
 DEFUN ("windowp", Fwindowp, Swindowp, 1, 1, 0,
        doc: /* Return t if OBJECT is a window and nil otherwise.  */)
   (Lisp_Object object)
@@ -1544,7 +1535,7 @@ Return POS.  */)
 {
   register struct window *w = decode_live_window (window);
 
-  CHECK_NUMBER_COERCE_MARKER (pos);
+  /* Type of POS is checked by Fgoto_char or set_marker_restricted ...  */
 
   if (w == XWINDOW (selected_window))
     {
@@ -1554,6 +1545,8 @@ Return POS.  */)
        {
          struct buffer *old_buffer = current_buffer;
 
+         /* ... but here we want to catch type error before buffer change.  */
+         CHECK_NUMBER_COERCE_MARKER (pos);
          set_buffer_internal (XBUFFER (w->buffer));
          Fgoto_char (pos);
          set_buffer_internal (old_buffer);
@@ -1579,9 +1572,8 @@ overriding motion of point in order to display at this exact start.  */)
 {
   register struct window *w = decode_live_window (window);
 
-  CHECK_NUMBER_COERCE_MARKER (pos);
   set_marker_restricted (w->start, pos, w->buffer);
-  /* this is not right, but much easier than doing what is right. */
+  /* This is not right, but much easier than doing what is right.  */
   w->start_at_line_beg = 0;
   if (NILP (noforce))
     w->force_start = 1;
@@ -2751,7 +2743,7 @@ window-start value is reasonable when this function is called.  */)
   struct window *w, *r, *s;
   struct frame *f;
   Lisp_Object sibling, pwindow, swindow IF_LINT (= Qnil), delta;
-  ptrdiff_t startpos IF_LINT (= 0);
+  ptrdiff_t startpos IF_LINT (= 0), startbyte IF_LINT (= 0);
   int top IF_LINT (= 0), new_top, resize_failed;
 
   w = decode_valid_window (window);
@@ -2790,6 +2782,7 @@ window-start value is reasonable when this function is called.  */)
   if (!NILP (w->buffer))
     {
       startpos = marker_position (w->start);
+      startbyte = marker_byte_position (w->start);
       top = WINDOW_TOP_EDGE_LINE (w)
        - FRAME_TOP_MARGIN (XFRAME (WINDOW_FRAME (w)));
       /* Make sure WINDOW is the frame's selected window.  */
@@ -2959,7 +2952,7 @@ window-start value is reasonable when this function is called.  */)
          Fset_buffer (w->buffer);
          /* This computation used to temporarily move point, but that
             can have unwanted side effects due to text properties.  */
-         pos = *vmotion (startpos, -top, w);
+         pos = *vmotion (startpos, startbyte, -top, w);
 
          set_marker_both (w->start, w->buffer, pos.bufpos, pos.bytepos);
          w->window_end_valid = 0;
@@ -4615,8 +4608,8 @@ window_scroll_pixel_based (Lisp_Object window, int n, int whole, int noerror)
        }
 
       /* Set the window start, and set up the window for redisplay.  */
-      set_marker_restricted (w->start, make_number (pos),
-                            w->buffer);
+      set_marker_restricted_both (w->start, w->buffer, IT_CHARPOS (it),
+                                 IT_BYTEPOS (it));
       bytepos = marker_byte_position (w->start);
       w->start_at_line_beg = (pos == BEGV || FETCH_BYTE (bytepos - 1) == '\n');
       w->update_mode_line = 1;
@@ -4756,7 +4749,8 @@ window_scroll_line_based (Lisp_Object window, int n, int whole, int noerror)
   register Lisp_Object tem;
   int lose;
   Lisp_Object bolp;
-  ptrdiff_t startpos;
+  ptrdiff_t startpos = marker_position (w->start);
+  ptrdiff_t startbyte = marker_byte_position (w->start);
   Lisp_Object original_pos = Qnil;
 
   /* If scrolling screen-fulls, compute the number of lines to
@@ -4764,8 +4758,6 @@ window_scroll_line_based (Lisp_Object window, int n, int whole, int noerror)
   if (whole)
     n *= max (1, ht - next_screen_context_lines);
 
-  startpos = marker_position (w->start);
-
   if (!NILP (Vscroll_preserve_screen_position))
     {
       if (window_scroll_preserve_vpos <= 0
@@ -4773,10 +4765,8 @@ window_scroll_line_based (Lisp_Object window, int n, int whole, int noerror)
          || NILP (Fget (KVAR (current_kboard, Vlast_command), Qscroll_command)))
        {
          struct position posit
-           = *compute_motion (startpos, 0, 0, 0,
-                              PT, ht, 0,
-                              -1, w->hscroll,
-                              0, w);
+           = *compute_motion (startpos, startbyte, 0, 0, 0,
+                              PT, ht, 0, -1, w->hscroll, 0, w);
          window_scroll_preserve_vpos = posit.vpos;
          window_scroll_preserve_hpos = posit.hpos + w->hscroll;
        }
@@ -4792,9 +4782,10 @@ window_scroll_line_based (Lisp_Object window, int n, int whole, int noerror)
     {
       Fvertical_motion (make_number (- (ht / 2)), window);
       startpos = PT;
+      startbyte = PT_BYTE;
     }
 
-  SET_PT (startpos);
+  SET_PT_BOTH (startpos, startbyte);
   lose = n < 0 && PT == BEGV;
   Fvertical_motion (make_number (n), window);
   pos = PT;
@@ -5172,7 +5163,7 @@ displayed_window_lines (struct window *w)
 
 DEFUN ("recenter", Frecenter, Srecenter, 0, 1, "P",
        doc: /* Center point in selected window and maybe redisplay frame.
-With prefix argument ARG, recenter putting point on screen line ARG
+With a numeric prefix argument ARG, recenter putting point on screen line ARG
 relative to the selected window.  If ARG is negative, it counts up from the
 bottom of the window.  (ARG should be less than the height of the window.)
 
@@ -5329,7 +5320,7 @@ and redisplay normally--don't erase and redraw the frame.  */)
 
          iarg = max (iarg, this_scroll_margin);
 
-         pos = *vmotion (PT, -iarg, w);
+         pos = *vmotion (PT, PT_BYTE, -iarg, w);
          charpos = pos.bufpos;
          bytepos = pos.bytepos;
        }
@@ -5348,7 +5339,7 @@ and redisplay normally--don't erase and redraw the frame.  */)
       iarg = clip_to_bounds (this_scroll_margin, iarg,
                             ht - this_scroll_margin - 1);
 
-      pos = *vmotion (PT, - iarg, w);
+      pos = *vmotion (PT, PT_BYTE, - iarg, w);
       charpos = pos.bufpos;
       bytepos = pos.bytepos;
     }
@@ -5795,8 +5786,7 @@ the return value is nil.  Otherwise the value is t.  */)
             {
               /* Set window markers at start of visible range.  */
               if (XMARKER (w->start)->buffer == 0)
-                set_marker_restricted (w->start, make_number (0),
-                                       w->buffer);
+                set_marker_restricted_both (w->start, w->buffer, 0, 0);
               if (XMARKER (w->pointm)->buffer == 0)
                 set_marker_restricted_both
                   (w->pointm, w->buffer,
@@ -5814,10 +5804,8 @@ the return value is nil.  Otherwise the value is t.  */)
              wset_buffer (w, other_buffer_safely (Fcurrent_buffer ()));
              /* This will set the markers to beginning of visible
                 range.  */
-             set_marker_restricted (w->start,
-                                    make_number (0), w->buffer);
-             set_marker_restricted (w->pointm,
-                                    make_number (0), w->buffer);
+             set_marker_restricted_both (w->start, w->buffer, 0, 0);
+             set_marker_restricted_both (w->pointm, w->buffer, 0, 0);
              w->start_at_line_beg = 1;
              if (!NILP (w->dedicated))
                /* Record this window as dead.  */
@@ -6190,11 +6178,11 @@ saved by this function.  */)
   data->minibuf_selected_window = minibuf_level > 0 ? minibuf_selected_window : Qnil;
   data->root_window = FRAME_ROOT_WINDOW (f);
   data->focus_frame = FRAME_FOCUS_FRAME (f);
-  tem = Fmake_vector (make_number (n_windows), Qnil);
+  tem = make_uninit_vector (n_windows);
   data->saved_windows = tem;
   for (i = 0; i < n_windows; i++)
     ASET (tem, i,
-         Fmake_vector (make_number (VECSIZE (struct saved_window)), Qnil));
+         Fmake_vector (make_number (VECSIZE (struct saved_window)), Qnil));
   save_window_save (FRAME_ROOT_WINDOW (f), XVECTOR (tem), 0);
   XSETWINDOW_CONFIGURATION (tem, data);
   return (tem);