update.
[chise/xemacs-chise.git.1] / src / scrollbar.c
index 22a7228..6df936c 100644 (file)
@@ -34,6 +34,7 @@ Boston, MA 02111-1307, USA.  */
 #include "device.h"
 #include "frame.h"
 #include "glyphs.h"
+#include "gutter.h"
 #include "window.h"
 
 Lisp_Object Qinit_scrollbar_from_resources;
@@ -95,10 +96,10 @@ free_scrollbar_instance (struct scrollbar_instance *instance,
 static void
 free_window_mirror_scrollbars (struct window_mirror *mir)
 {
-  struct frame *f = mir->frame;
-  free_scrollbar_instance (mir->scrollbar_vertical_instance, f);
+  free_scrollbar_instance (mir->scrollbar_vertical_instance, mir->frame);
   mir->scrollbar_vertical_instance = 0;
-  free_scrollbar_instance (mir->scrollbar_horizontal_instance, f);
+
+  free_scrollbar_instance (mir->scrollbar_horizontal_instance, mir->frame);
   mir->scrollbar_horizontal_instance = 0;
 }
 
@@ -109,12 +110,7 @@ free_scrollbars_loop (Lisp_Object window, struct window_mirror *mir)
 
   while (mir)
     {
-      struct scrollbar_instance *vinst = mir->scrollbar_vertical_instance;
-      struct scrollbar_instance *hinst = mir->scrollbar_horizontal_instance;
-      struct frame *f;
-
       assert (!NILP (window));
-      f = XFRAME (XWINDOW (window)->frame);
 
       if (mir->vchild)
        {
@@ -130,7 +126,8 @@ free_scrollbars_loop (Lisp_Object window, struct window_mirror *mir)
       if (retval != NULL)
        return retval;
 
-      if (hinst || vinst)
+      if (mir->scrollbar_vertical_instance ||
+         mir->scrollbar_horizontal_instance)
        free_window_mirror_scrollbars (mir);
 
       mir = mir->next;
@@ -141,19 +138,7 @@ free_scrollbars_loop (Lisp_Object window, struct window_mirror *mir)
 }
 
 /* Destroy all scrollbars associated with FRAME.  Only called from
-   delete_frame_internal.
- */
-#define FREE_FRAME_SCROLLBARS_INTERNAL(cache)                          \
-  do {                                                                 \
-    while (FRAME_SB_##cache (f))                                       \
-      {                                                                        \
-       struct scrollbar_instance *tofree = FRAME_SB_##cache (f);       \
-       FRAME_SB_##cache (f) = FRAME_SB_##cache (f)->next;              \
-       tofree->next = NULL;                                            \
-       free_scrollbar_instance (tofree, f);                            \
-      }                                                                        \
-  } while (0)
-
+   delete_frame_internal. */
 void
 free_frame_scrollbars (struct frame *f)
 {
@@ -165,10 +150,22 @@ free_frame_scrollbars (struct frame *f)
 
   free_scrollbars_loop (f->root_window, f->root_mirror);
 
-  FREE_FRAME_SCROLLBARS_INTERNAL (VCACHE);
-  FREE_FRAME_SCROLLBARS_INTERNAL (HCACHE);
+  while (FRAME_SB_VCACHE (f))
+    {
+      struct scrollbar_instance *tofree = FRAME_SB_VCACHE (f);
+      FRAME_SB_VCACHE (f) = FRAME_SB_VCACHE (f)->next;
+      tofree->next = NULL;
+      free_scrollbar_instance (tofree, f);
+    }
+
+  while (FRAME_SB_HCACHE (f))
+    {
+      struct scrollbar_instance *tofree = FRAME_SB_HCACHE (f);
+      FRAME_SB_HCACHE (f) = FRAME_SB_HCACHE (f)->next;
+      tofree->next = NULL;
+      free_scrollbar_instance (tofree, f);
+    }
 }
-#undef FREE_FRAME_SCROLLBARS_INTERNAL
 
 \f
 static struct scrollbar_instance *
@@ -243,7 +240,8 @@ compute_scrollbar_instance_usage (struct device *d,
 {
   int total = 0;
 
-  total += DEVMETH (d, compute_scrollbar_instance_usage, (d, inst, ovstats));
+  if (HAS_DEVMETH_P(d, compute_scrollbar_instance_usage))
+    total += DEVMETH (d, compute_scrollbar_instance_usage, (d, inst, ovstats));
 
   while (inst)
     {
@@ -354,13 +352,6 @@ release_window_mirror_scrollbars (struct window_mirror *mir)
   mir->scrollbar_horizontal_instance = 0;
 }
 
-/* This check needs to be done in the device-specific side. */
-#define UPDATE_DATA_FIELD(field, value) \
-  if (instance->field != value) {\
-    instance->field = value;\
-    instance->scrollbar_instance_changed = 1;\
-  }\
-
 /*
  * If w->sb_point is on the top line then return w->sb_point else
  * return w->start.  If flag, then return beginning point of line
@@ -419,7 +410,7 @@ update_scrollbar_instance (struct window *w, int vertical,
   int new_minimum = -1, new_maximum = -1;
   int new_slider_size = -1, new_slider_position = -1;
   int new_width = -1, new_height = -1, new_x = -1, new_y = -1;
-  struct window *new_window = 0;       /* kludge city */
+  struct window *new_window = 0; /* #### currently unused */
 
   end_pos = BUF_Z (b) - w->window_end_pos[CURRENT_DISP];
   sb_pos = scrollbar_point (w, 0);
@@ -463,23 +454,35 @@ update_scrollbar_instance (struct window *w, int vertical,
   {
     int x_offset, y_offset;
 
-    /* Scrollbars are always the farthest from the text area. */
+    /* Scrollbars are always the farthest from the text area, barring
+       gutters. */
     if (vertical)
       {
-       x_offset = (!NILP (w->scrollbar_on_left_p)
-                   ? WINDOW_LEFT (w)
-                   : (WINDOW_RIGHT (w) - scrollbar_width
-                      - (window_needs_vertical_divider (w)
-                         ? window_divider_width (w) : 0)));
+       if (!NILP (w->scrollbar_on_left_p))
+         {
+           x_offset = WINDOW_LEFT (w);
+         }
+       else
+         {
+           x_offset = WINDOW_RIGHT (w) - scrollbar_width;
+           if (window_needs_vertical_divider (w))
+             x_offset -= window_divider_width (w);
+         }
        y_offset = WINDOW_TEXT_TOP (w) + f->scrollbar_y_offset;
       }
     else
       {
        x_offset = WINDOW_TEXT_LEFT (w);
-       y_offset = f->scrollbar_y_offset +
-         (!NILP (w->scrollbar_on_top_p)
-          ? WINDOW_TOP (w)
-          : WINDOW_TEXT_BOTTOM (w) + window_bottom_toolbar_height (w));
+       y_offset = f->scrollbar_y_offset;
+
+       if (!NILP (w->scrollbar_on_top_p))
+         {
+           y_offset += WINDOW_TOP (w);
+         }
+       else
+         {
+           y_offset += WINDOW_TEXT_BOTTOM (w);
+         }
       }
 
     new_x = x_offset;
@@ -598,7 +601,7 @@ vertical_scrollbar_changed_in_window (Lisp_Object specifier,
      changing scrollbar affects only how the text and scrollbar are
      laid out in the window. If we do not want the dividers to show up
      always, then we mark more drastic change, because changing
-     divider appearane changes lotta things. Although we actually need
+     divider appearance changes lotta things. Although we actually need
      to do this only if the scrollbar has appeared or disappeared
      completely at either window edge, we do this always, as users
      usually do not reposition scrollbars 200 times a second or so. Do
@@ -733,26 +736,26 @@ behavior.
      with their standard behaviors.  It is not possible to hide the
      differences down in lwlib because knowledge of XEmacs buffer and
      cursor motion routines is necessary. */
-#if defined (LWLIB_SCROLLBARS_MOTIF) || defined (LWLIB_SCROLLBARS_LUCID) || \
-    defined (LWLIB_SCROLLBARS_ATHENA3D) || defined(HAVE_MS_WINDOWS)
-  window_scroll (window, Qnil, -1, ERROR_ME_NOT);
-#else /* Athena */
-  {
-    Bufpos bufpos;
-    Lisp_Object value = Fcdr (object);
 
-    CHECK_INT (value);
-    Fmove_to_window_line (Qzero, window);
-    /* can't use Fvertical_motion() because it moves the buffer point
-       rather than the window's point.
-
-       #### It does?  Why does it take a window argument then? */
-    bufpos = vmotion (XWINDOW (window), XINT (Fwindow_point (window)),
-                     XINT (value), 0);
-    Fset_window_point (window, make_int (bufpos));
-    Fcenter_to_window_line (Qzero, window);
-  }
-#endif /* Athena */
+  if (NILP (XCDR (object)))
+    window_scroll (window, Qnil, -1, ERROR_ME_NOT);
+  else
+    {
+      Bufpos bufpos;
+      Lisp_Object value = Fcdr (object);
+
+      CHECK_INT (value);
+      Fmove_to_window_line (Qzero, window);
+      /* can't use Fvertical_motion() because it moves the buffer point
+        rather than the window's point.
+
+        #### It does?  Why does it take a window argument then? */
+      bufpos = vmotion (XWINDOW (window), XINT (Fwindow_point (window)),
+                       XINT (value), 0);
+      Fset_window_point (window, make_int (bufpos));
+      Fcenter_to_window_line (Qzero, window);
+    }
+
   zmacs_region_stays = 1;
   return Qnil;
 }
@@ -774,17 +777,17 @@ behavior.
      with their standard behaviors.  It is not possible to hide the
      differences down in lwlib because knowledge of XEmacs buffer and
      cursor motion routines is necessary. */
-#if defined (LWLIB_SCROLLBARS_MOTIF) || defined (LWLIB_SCROLLBARS_LUCID) || \
-    defined (LWLIB_SCROLLBARS_ATHENA3D) || defined (HAVE_MS_WINDOWS)
-  window_scroll (window, Qnil, 1, ERROR_ME_NOT);
-#else /* Athena */
-  {
-    Lisp_Object value = Fcdr (object);
-    CHECK_INT (value);
-    Fmove_to_window_line (value, window);
-    Fcenter_to_window_line (Qzero, window);
-  }
-#endif /* Athena */
+
+  if (NILP (XCDR (object)))
+    window_scroll (window, Qnil, 1, ERROR_ME_NOT);
+  else
+    {
+      Lisp_Object value = Fcdr (object);
+      CHECK_INT (value);
+      Fmove_to_window_line (value, window);
+      Fcenter_to_window_line (Qzero, window);
+    }
+
   zmacs_region_stays = 1;
   return Qnil;
 }
@@ -861,7 +864,7 @@ This ensures that VALUE is in the proper range for the horizontal scrollbar.
 
   w = XWINDOW (window);
   wcw = window_char_width (w, 0) - 1;
-  /* ### We should be able to scroll further right as long as there is
+  /* #### We should be able to scroll further right as long as there is
      a visible truncation glyph.  This calculation for max is bogus.  */
   max_len = w->max_line_len + 2;
 
@@ -872,7 +875,7 @@ This ensures that VALUE is in the proper range for the horizontal scrollbar.
 
   /* Can't allow this out of set-window-hscroll's acceptable range. */
   /* #### What hell on the earth this code limits scroll size to the
-     machine-dependant SHORT size? -- kkm */
+     machine-dependent SHORT size? -- kkm */
   if (hscroll < 0)
     hscroll = 0;
   else if (hscroll >= (1 << (SHORTBITS - 1)) - 1)
@@ -948,12 +951,10 @@ This is a specifier; use `set-specifier' to change it.
     (Vscrollbar_width,
      list1 (Fcons (Qnil, make_int (DEFAULT_SCROLLBAR_WIDTH))));
   set_specifier_caching (Vscrollbar_width,
-                        slot_offset (struct window,
-                                     scrollbar_width),
+                        offsetof (struct window, scrollbar_width),
                         vertical_scrollbar_changed_in_window,
-                        slot_offset (struct frame,
-                                     scrollbar_width),
-                        frame_size_slipped);
+                        offsetof (struct frame, scrollbar_width),
+                        frame_size_slipped, 0);
 
   DEFVAR_SPECIFIER ("scrollbar-height", &Vscrollbar_height /*
 *Height of horizontal scrollbars.
@@ -964,12 +965,10 @@ This is a specifier; use `set-specifier' to change it.
     (Vscrollbar_height,
      list1 (Fcons (Qnil, make_int (DEFAULT_SCROLLBAR_HEIGHT))));
   set_specifier_caching (Vscrollbar_height,
-                        slot_offset (struct window,
-                                     scrollbar_height),
+                        offsetof (struct window, scrollbar_height),
                         some_window_value_changed,
-                        slot_offset (struct frame,
-                                     scrollbar_height),
-                        frame_size_slipped);
+                        offsetof (struct frame, scrollbar_height),
+                        frame_size_slipped, 0);
 
   DEFVAR_SPECIFIER ("horizontal-scrollbar-visible-p", &Vhorizontal_scrollbar_visible_p /*
 *Whether the horizontal scrollbar is visible.
@@ -979,12 +978,12 @@ This is a specifier; use `set-specifier' to change it.
   set_specifier_fallback (Vhorizontal_scrollbar_visible_p,
                          list1 (Fcons (Qnil, Qt)));
   set_specifier_caching (Vhorizontal_scrollbar_visible_p,
-                        slot_offset (struct window,
-                                     horizontal_scrollbar_visible_p),
+                        offsetof (struct window,
+                                  horizontal_scrollbar_visible_p),
                         some_window_value_changed,
-                        slot_offset (struct frame,
-                                     horizontal_scrollbar_visible_p),
-                        frame_size_slipped);
+                        offsetof (struct frame,
+                                  horizontal_scrollbar_visible_p),
+                        frame_size_slipped, 0);
 
   DEFVAR_SPECIFIER ("vertical-scrollbar-visible-p", &Vvertical_scrollbar_visible_p /*
 *Whether the vertical scrollbar is visible.
@@ -994,21 +993,21 @@ This is a specifier; use `set-specifier' to change it.
   set_specifier_fallback (Vvertical_scrollbar_visible_p,
                          list1 (Fcons (Qnil, Qt)));
   set_specifier_caching (Vvertical_scrollbar_visible_p,
-                        slot_offset (struct window,
-                                     vertical_scrollbar_visible_p),
+                        offsetof (struct window,
+                                  vertical_scrollbar_visible_p),
                         vertical_scrollbar_changed_in_window,
-                        slot_offset (struct frame,
-                                     vertical_scrollbar_visible_p),
-                        frame_size_slipped);
+                        offsetof (struct frame,
+                                  vertical_scrollbar_visible_p),
+                        frame_size_slipped, 0);
 
   DEFVAR_SPECIFIER ("scrollbar-on-left-p", &Vscrollbar_on_left_p /*
-*Whether the verical scrollbar is on the left side of window or frame.
+*Whether the vertical scrollbar is on the left side of window or frame.
 This is a specifier; use `set-specifier' to change it.
 */ );
   Vscrollbar_on_left_p = Fmake_specifier (Qboolean);
-  
+
   {
-    /* Klugde. Under X, we want athena scrollbars on the left,
+    /* Kludge. Under X, we want athena scrollbars on the left,
        while all other scrollbars go on the right by default. */
     Lisp_Object fallback = list1 (Fcons (Qnil, Qnil));
 #if defined (HAVE_X_WINDOWS)                   \
@@ -1022,27 +1021,23 @@ This is a specifier; use `set-specifier' to change it.
   }
 
   set_specifier_caching (Vscrollbar_on_left_p,
-                        slot_offset (struct window,
-                                     scrollbar_on_left_p),
+                        offsetof (struct window, scrollbar_on_left_p),
                         vertical_scrollbar_changed_in_window,
-                        slot_offset (struct frame,
-                                     scrollbar_on_left_p),
-                        frame_size_slipped);
+                        offsetof (struct frame, scrollbar_on_left_p),
+                        frame_size_slipped, 0);
 
   DEFVAR_SPECIFIER ("scrollbar-on-top-p", &Vscrollbar_on_top_p /*
-*Whether the verical scrollbar is on the top side of window or frame.
+*Whether the horizontal scrollbar is on the top side of window or frame.
 This is a specifier; use `set-specifier' to change it.
 */ );
   Vscrollbar_on_top_p = Fmake_specifier (Qboolean);
   set_specifier_fallback (Vscrollbar_on_top_p,
                          list1 (Fcons (Qnil, Qnil)));
   set_specifier_caching (Vscrollbar_on_top_p,
-                        slot_offset (struct window,
-                                     scrollbar_on_top_p),
+                        offsetof (struct window, scrollbar_on_top_p),
                         some_window_value_changed,
-                        slot_offset (struct frame,
-                                     scrollbar_on_top_p),
-                        frame_size_slipped);
+                        offsetof (struct frame, scrollbar_on_top_p),
+                        frame_size_slipped, 0);
 }
 
 void
@@ -1051,8 +1046,7 @@ complex_vars_of_scrollbar (void)
   Vscrollbar_pointer_glyph = Fmake_glyph_internal (Qpointer);
 
   set_specifier_caching (XGLYPH (Vscrollbar_pointer_glyph)->image,
-                        slot_offset (struct window,
-                                     scrollbar_pointer),
+                        offsetof (struct window, scrollbar_pointer),
                         scrollbar_pointer_changed_in_window,
-                        0, 0);
+                        0, 0, 0);
 }