emacs-diffs
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Emacs-diffs] /srv/bzr/emacs/trunk r108856: Avoid weird behavior with la


From: Paul Eggert
Subject: [Emacs-diffs] /srv/bzr/emacs/trunk r108856: Avoid weird behavior with large horizontal scrolls.
Date: Tue, 03 Jul 2012 23:15:31 -0700
User-agent: Bazaar (2.5.0)

------------------------------------------------------------
revno: 108856
committer: Paul Eggert <address@hidden>
branch nick: trunk
timestamp: Tue 2012-07-03 23:15:31 -0700
message:
  Avoid weird behavior with large horizontal scrolls.
  
  Without this change, for example, large hscroll values would
  mess up Emacs's display on Fedora 15 x86, presumably due to
  overflows in int calculations in the display code.
  Also, if buffers had long lines, Emacs would freeze.
  * window.c (HSCROLL_MAX): Reduce to 100000, and make it visible to GDB.
  (set_window_hscroll): New function, containing the old guts of
  Fset_window_hscroll.  Return the clipped value.
  (Fset_window_hscroll, Fscroll_left, Fscroll_right): Use it.
  This avoids the need to check against PTRDIFF_MAX.
modified:
  src/ChangeLog
  src/window.c
=== modified file 'src/ChangeLog'
--- a/src/ChangeLog     2012-07-04 05:39:36 +0000
+++ b/src/ChangeLog     2012-07-04 06:15:31 +0000
@@ -1,5 +1,16 @@
 2012-07-04  Paul Eggert  <address@hidden>
 
+       Avoid weird behavior with large horizontal scrolls.
+       Without this change, for example, large hscroll values would
+       mess up Emacs's display on Fedora 15 x86, presumably due to
+       overflows in int calculations in the display code.
+       Also, if buffers had long lines, Emacs would freeze.
+       * window.c (HSCROLL_MAX): Reduce to 100000, and make it visible to GDB.
+       (set_window_hscroll): New function, containing the old guts of
+       Fset_window_hscroll.  Return the clipped value.
+       (Fset_window_hscroll, Fscroll_left, Fscroll_right): Use it.
+       This avoids the need to check against PTRDIFF_MAX.
+
        * buffer.c (Fgenerate_new_buffer_name): Fix sprintf format mismatch.
 
 2012-07-04  Dmitry Antipov  <address@hidden>

=== modified file 'src/window.c'
--- a/src/window.c      2012-07-03 18:24:42 +0000
+++ b/src/window.c      2012-07-04 06:15:31 +0000
@@ -51,6 +51,11 @@
 #include "nsterm.h"
 #endif
 
+/* Horizontal scrolling has problems with large scroll amounts.
+   It's too slow with long lines, and even with small lines the
+   display can be messed up.  Impose a reasonable maximum.  */
+enum { HSCROLL_MAX = 100000 };
+
 Lisp_Object Qwindowp, Qwindow_live_p;
 static Lisp_Object Qwindow_configuration_p, Qrecord_window_buffer;
 static Lisp_Object Qwindow_deletable_p, Qdelete_window, Qdisplay_buffer;
@@ -670,27 +675,35 @@
   return make_number (decode_window (window)->hscroll);
 }
 
+/* Set W's horizontal scroll amount to HSCROLL clipped to a reasonable
+   range, returning the new amount as a fixnum.  */
+static Lisp_Object
+set_window_hscroll (struct window *w, EMACS_INT hscroll)
+{
+  int new_hscroll = clip_to_bounds (0, hscroll, HSCROLL_MAX);
+
+  /* Prevent redisplay shortcuts when changing the hscroll.  */
+  if (w->hscroll != new_hscroll)
+    XBUFFER (w->buffer)->prevent_redisplay_optimizations_p = 1;
+
+  w->hscroll = new_hscroll;
+  return make_number (new_hscroll);
+}
+
 DEFUN ("set-window-hscroll", Fset_window_hscroll, Sset_window_hscroll, 2, 2, 0,
        doc: /* Set number of columns WINDOW is scrolled from left margin to 
NCOL.
 If WINDOW is nil, the selected window is used.
-Return NCOL.  NCOL should be zero or positive.
+Clip the number to a reasonable value if out of range.
+Return the new number.  NCOL should be zero or positive.
 
 Note that if `automatic-hscrolling' is non-nil, you cannot scroll the
 window so that the location of point moves off-window.  */)
   (Lisp_Object window, Lisp_Object ncol)
 {
   struct window *w = decode_window (window);
-  ptrdiff_t hscroll;
 
   CHECK_NUMBER (ncol);
-  hscroll = clip_to_bounds (0, XINT (ncol), PTRDIFF_MAX);
-
-  /* Prevent redisplay shortcuts when changing the hscroll.  */
-  if (w->hscroll != hscroll)
-    XBUFFER (w->buffer)->prevent_redisplay_optimizations_p = 1;
-
-  w->hscroll = hscroll;
-  return ncol;
+  return set_window_hscroll (w, XINT (ncol));
 }
 
 DEFUN ("window-redisplay-end-trigger", Fwindow_redisplay_end_trigger,
@@ -4850,9 +4863,6 @@
   return Qnil;
 }
 
-/* Scrolling amount must fit in both ptrdiff_t and Emacs fixnum.  */
-#define HSCROLL_MAX min (PTRDIFF_MAX, MOST_POSITIVE_FIXNUM)
-
 DEFUN ("scroll-left", Fscroll_left, Sscroll_left, 0, 2, "^P\np",
        doc: /* Scroll selected window display ARG columns left.
 Default for ARG is window width minus 2.
@@ -4864,16 +4874,11 @@
 by this function.  This happens in an interactive call.  */)
   (register Lisp_Object arg, Lisp_Object set_minimum)
 {
-  Lisp_Object result;
-  ptrdiff_t hscroll;
   struct window *w = XWINDOW (selected_window);
   EMACS_INT requested_arg = (NILP (arg)
                             ? window_body_cols (w) - 2
                             : XINT (Fprefix_numeric_value (arg)));
-  ptrdiff_t clipped_arg =
-    clip_to_bounds (- w->hscroll, requested_arg, HSCROLL_MAX - w->hscroll);
-  hscroll = w->hscroll + clipped_arg;
-  result = Fset_window_hscroll (selected_window, make_number (hscroll));
+  Lisp_Object result = set_window_hscroll (w, w->hscroll + requested_arg);
 
   if (!NILP (set_minimum))
     w->min_hscroll = w->hscroll;
@@ -4892,16 +4897,11 @@
 by this function.  This happens in an interactive call.  */)
   (register Lisp_Object arg, Lisp_Object set_minimum)
 {
-  Lisp_Object result;
-  ptrdiff_t hscroll;
   struct window *w = XWINDOW (selected_window);
   EMACS_INT requested_arg = (NILP (arg)
                             ? window_body_cols (w) - 2
                             : XINT (Fprefix_numeric_value (arg)));
-  ptrdiff_t clipped_arg =
-    clip_to_bounds (w->hscroll - HSCROLL_MAX, requested_arg, w->hscroll);
-  hscroll = w->hscroll - clipped_arg;
-  result = Fset_window_hscroll (selected_window, make_number (hscroll));
+  Lisp_Object result = set_window_hscroll (w, w->hscroll - requested_arg);
 
   if (!NILP (set_minimum))
     w->min_hscroll = w->hscroll;


reply via email to

[Prev in Thread] Current Thread [Next in Thread]