Index: lisp/gutter-items.el
===================================================================
RCS file: /usr/CVSroot/XEmacs/xemacs/lisp/Attic/gutter-items.el,v
retrieving revision 1.1.2.53
diff -u -r1.1.2.53 gutter-items.el
--- lisp/gutter-items.el 2000/07/31 16:08:13 1.1.2.53
+++ lisp/gutter-items.el 2000/11/07 01:57:57
@@ -47,11 +47,16 @@
 					 'buffers-tab val)
 	   (setq gutter-buffers-tab-visible-p val)))
 
+(defcustom gutter-buffers-tab-enabled t
+  "*Whether to enable support for buffers tab in the gutter.
+This is different to `gutter-buffers-tab-visible-p' which still runs hooks
+even when the gutter is invisible."
+  :group 'buffers-tab
+  :type 'boolean)
+
 (defvar gutter-buffers-tab-orientation 'top
   "Where the buffers tab currently is. Do not set this.")
 
-(defvar gutter-buffers-tab-extent nil)
-
 (defcustom buffers-tab-max-size 6
   "*Maximum number of entries which may appear on the \"Buffers\" tab.
 If this is 10, then only the ten most-recently-selected buffers will be
@@ -72,7 +77,7 @@
 (defcustom buffers-tab-omit-function 'buffers-menu-omit-invisible-buffers
   "*If non-nil, a function specifying the buffers to omit from the buffers tab.
 This is passed a buffer and should return non-nil if the buffer should be
-omitted.  The default value `buffers-tab-omit-invisible-buffers' omits
+omitted.  The default value `buffers-menu-omit-invisible-buffers' omits
 buffers that are normally considered \"invisible\" (those whose name
 begins with a space)."
   :type '(choice (const :tag "None" nil)
@@ -90,6 +95,18 @@
 		 function)
   :group 'buffers-tab)
 
+(defcustom buffers-tab-filter-functions (list buffers-tab-selection-function)
+  "*If non-nil, a list of functions specifying the buffers to select 
+from the buffers tab.
+Each function in the list is passed two buffers, the buffer to
+potentially select and the context buffer, and should return non-nil
+if the first buffer should be selected.  The default value groups
+buffers by major mode and by `buffers-tab-grouping-regexp'."
+
+  :type '(choice (const :tag "None" nil)
+		 sexp)
+  :group 'buffers-tab)
+
 (defcustom buffers-tab-sort-function nil
   "*If non-nil, a function specifying the buffers to select from the
 buffers tab.  This is passed the buffer list and returns the list in the
@@ -159,13 +176,14 @@
 	(select-window (car (windows-of-buffer buffer)))
       (switch-to-buffer buffer))))
 
-(defun select-buffers-tab-buffers-by-mode (buf1 buf2)
+(defun select-buffers-tab-buffers-by-mode (buffer-to-select buf1)
   "For use as a value of `buffers-tab-selection-function'.
 This selects buffers by major mode `buffers-tab-grouping-regexp'."
   (let ((mode1 (symbol-name (symbol-value-in-buffer 'major-mode buf1)))
-	(mode2 (symbol-name (symbol-value-in-buffer 'major-mode buf2)))
+	(mode2 (symbol-name (symbol-value-in-buffer 'major-mode 
+						    buffer-to-select)))
 	(modenm1 (symbol-value-in-buffer 'mode-name buf1))
-	(modenm2 (symbol-value-in-buffer 'mode-name buf2)))
+	(modenm2 (symbol-value-in-buffer 'mode-name buffer-to-select)))
     (cond ((or (eq mode1 mode2)
 	       (eq modenm1 modenm2)
 	       (and (string-match "^[^-]+-" mode1)
@@ -212,32 +230,25 @@
 	   (when selected (setq selected nil))))
      buffers)))
 
-;;; #### SJT I'd really like this function to have just two hooks: (1) the
-;;; buffer filter list and (2) a sort function list.  Both should be lists
-;;; of functions.  Each filter takes two arguments:  a buffer and a model
-;;; buffer.  (The model buffer argument allows selecting according to the
-;;; mode or directory of that buffer.)  The filter returns t if the buffer
-;;; should be listed and nil otherwise.  Effectively the filter amounts to
-;;; the conjuction of the filter list.  (Optionally the filter could take a
-;;; frame instead of a buffer or generalize to a locale as in a specifier?)
-;;; The filtering is done this way to preserve the ordering imposed by
-;;; `buffer-list'.  In addition, the in-deletion argument will be used the
-;;; same way as in the current design.
-;;; The list is checked for length and pruned according to least-recently-
-;;; selected.  (Optionally there could be some kind of sort function here,
-;;; too.)
-;;; Finally the list is sorted to gutter display order, and the tab data
-;;; structure is created and returned.
-;;; #### Docstring isn't very well expressed.
+;;; #### SJT would like this function to have a sort function list. I
+;;; don't see how this could work given that sorting is not
+;;; cumulative --andyp.
 (defun buffers-tab-items (&optional in-deletion frame force-selection)
-  "This is the tab filter for the top-level buffers \"Buffers\" tab.
-It dynamically creates a list of buffers to use as the contents of the tab.
-Only the most-recently-used few buffers will be listed on the tab, for
-efficiency reasons.  You can control how many buffers will be shown by
-setting `buffers-tab-max-size'.  You can control the text of the tab
-items by redefining the function `format-buffers-menu-line'."
+  "Return a list of tab instantiators based on the current buffers list.
+This function is used as the tab filter for the top-level buffers
+\"Buffers\" tab.  It dynamically creates a list of tab instantiators
+to use as the contents of the tab.  The contents and order of the list
+is controlled by `buffers-tab-filter-functions' which by default
+groups buffers according to major mode and removes invisible buffers.
+You can control how many buffers will be shown by setting
+`buffers-tab-max-size'.  You can control the text of the tab items by
+redefining the function `format-buffers-menu-line'."
   (save-match-data
-    (let* ((buffers (delete-if buffers-tab-omit-function (buffer-list frame)))
+    ;; NB it is too late if we run the omit function as part of the
+    ;; filter functions because we need to know which buffer is the
+    ;; context buffer before they get run.
+    (let* ((buffers (delete-if 
+		     buffers-tab-omit-function (buffer-list frame)))
 	   (first-buf (car buffers)))
       ;; maybe force the selected window
       (when (and force-selection
@@ -249,11 +260,19 @@
       (when in-deletion 
 	(setq buffers (delq (current-buffer) buffers))
 	(setq first-buf (car buffers)))
-      ;; select buffers in group (default is by mode)
-      (when buffers-tab-selection-function
-	(delete-if-not #'(lambda (buf)
-			   (funcall buffers-tab-selection-function
-				    first-buf buf)) buffers))
+      ;; filter buffers
+      (when buffers-tab-filter-functions
+	(setq buffers
+	      (delete-if 
+	       #'null 
+	       (mapcar #'(lambda (buf)
+			   (let ((tmp-buf buf))
+			     (mapc #'(lambda (fun)
+				       (unless (funcall fun buf first-buf)
+					 (setq tmp-buf nil)))
+				   buffers-tab-filter-functions)
+			     tmp-buf))
+		       buffers))))
       ;; maybe shorten list of buffers
       (and (integerp buffers-tab-max-size)
 	   (> buffers-tab-max-size 1)
@@ -269,14 +288,11 @@
 (defun add-tab-to-gutter ()
   "Put a tab control in the gutter area to hold the most recent buffers."
   (setq gutter-buffers-tab-orientation (default-gutter-position))
-  (let ((gutter-string (copy-sequence "\n")))
-    (unless gutter-buffers-tab-extent
-      (setq gutter-buffers-tab-extent (make-extent 0 1 gutter-string)))
-    (set-extent-begin-glyph 
-     gutter-buffers-tab-extent
-     (setq gutter-buffers-tab 
-	   (make-glyph)))
-
+  (let* ((gutter-string (copy-sequence "\n"))
+	 (gutter-buffers-tab-extent (make-extent 0 1 gutter-string)))
+    (set-extent-begin-glyph gutter-buffers-tab-extent
+			    (setq gutter-buffers-tab 
+				  (make-glyph)))
     ;; Nuke all existing tabs
     (remove-gutter-element top-gutter 'buffers-tab)
     (remove-gutter-element bottom-gutter 'buffers-tab)
@@ -298,17 +314,11 @@
 		 ((eq gutter-buffers-tab-orientation 'left)
 		  (set-specifier left-gutter-border-width 0 'global x)
 		  (set-gutter-element left-gutter 'buffers-tab
-				      gutter-string 'global x)
-		  (set-specifier left-gutter-width
-				 (glyph-width gutter-buffers-tab)
-				 'global x))
+				      gutter-string 'global x))
 		 ((eq gutter-buffers-tab-orientation 'right)
 		  (set-specifier right-gutter-border-width 0 'global x)
 		  (set-gutter-element right-gutter 'buffers-tab
-				      gutter-string 'global x)
-		  (set-specifier right-gutter-width
-				 (glyph-width gutter-buffers-tab)
-				 'global x))
+				      gutter-string 'global x))
 		 )))
      (console-type-list))))
 
@@ -333,21 +343,33 @@
 			 (eq gutter-buffers-tab-orientation 'bottom))
 		     '(gutter-pixel-width) '(gutter-pixel-height))
 		 :items (buffers-tab-items nil frame force-selection))
-	 frame)))))
+	 frame)
+	;; set-glyph-image will not make the gutter dirty
+	(set-specifier-dirty-flag 
+	 (eval (intern (concat 
+			(symbol-name gutter-buffers-tab-orientation) 
+			"-gutter"))))))))
 
 ;; A myriad of different update hooks all doing slightly different things
-(add-hook 'create-frame-hook 
-	  #'(lambda (frame)
-	      (when gutter-buffers-tab (update-tab-in-gutter frame t))))
-(add-hook 'buffer-list-changed-hook 'update-tab-in-gutter)
-(add-hook 'default-gutter-position-changed-hook
-	  #'(lambda ()
-	      (when gutter-buffers-tab
-		(mapc #'update-tab-in-gutter (frame-list)))))
-(add-hook 'gutter-element-visibility-changed-hook
-	  #'(lambda (prop visible-p)
-	      (when (and (eq prop 'buffers-tab) visible-p)
-		(mapc #'update-tab-in-gutter (frame-list)))))
+(add-one-shot-hook 
+ 'after-init-hook
+ #'(lambda ()
+     ;; don't add the hooks if the user really doesn't want them
+     (when gutter-buffers-tab-enabled
+       (add-hook 'create-frame-hook 
+		 #'(lambda (frame)
+		     (when gutter-buffers-tab (update-tab-in-gutter frame t))))
+       (add-hook 'buffer-list-changed-hook 'update-tab-in-gutter)
+       (add-hook 'default-gutter-position-changed-hook
+		 #'(lambda ()
+		     (when gutter-buffers-tab
+		       (mapc #'update-tab-in-gutter (frame-list)))))
+       (add-hook 'gutter-element-visibility-changed-hook
+		 #'(lambda (prop visible-p)
+		     (when (and (eq prop 'buffers-tab) visible-p)
+		       (mapc #'update-tab-in-gutter (frame-list)))))
+       (update-tab-in-gutter (selected-frame) t))))
+
 ;;
 ;; progress display
 ;; ripped off from message display
Index: src/glyphs-x.c
===================================================================
RCS file: /usr/CVSroot/XEmacs/xemacs/src/glyphs-x.c,v
retrieving revision 1.49.2.83
diff -u -r1.49.2.83 glyphs-x.c
--- src/glyphs-x.c 2000/10/12 04:59:08 1.49.2.83
+++ src/glyphs-x.c 2000/11/07 01:58:05
@@ -2210,8 +2210,8 @@
 	 reference to the real values rather than a copy thus any
 	 changes we make to the values we get back will look like they
 	 have already been applied. If we rebuild the widget tree then
-	 we may lose propertie. */
-      wv = copy_widget_value_tree (lw_get_all_values
+	 we may lose properties. */
+      wv = copy_widget_value_tree (lw_get_all_values 
 				   (IMAGE_INSTANCE_X_WIDGET_LWID (p)),
 				   NO_CHANGE);
     }
Index: src/glyphs.c
===================================================================
RCS file: /usr/CVSroot/XEmacs/xemacs/src/glyphs.c,v
retrieving revision 1.23.2.84
diff -u -r1.23.2.84 glyphs.c
--- src/glyphs.c 2000/10/12 04:59:03 1.23.2.84
+++ src/glyphs.c 2000/11/07 01:58:20
@@ -5383,7 +5383,7 @@
   set_specifier_caching (Vcurrent_display_table,
 			 offsetof (struct window, display_table),
 			 some_window_value_changed,
-			 0, 0);
+			 0, 0, 0);
 }
 
 void
Index: src/gutter.c
===================================================================
RCS file: /usr/CVSroot/XEmacs/xemacs/src/Attic/gutter.c,v
retrieving revision 1.1.2.37
diff -u -r1.1.2.37 gutter.c
--- src/gutter.c 2000/09/20 02:38:20 1.1.2.37
+++ src/gutter.c 2000/11/07 01:58:23
@@ -249,6 +249,96 @@
   return Fconcat (nargs, args);
 }
 
+/* Sizing gutters is a pain so we try and help the user by determining
+   what height will accommodate all lines. This is useless on left and
+   right gutters as we always have a maximal number of lines. */
+static int
+calculate_gutter_size_from_display_lines (enum gutter_pos pos,
+					  display_line_dynarr* ddla)
+{
+  int size = 0;
+  struct display_line *dl;
+
+  /* For top and bottom the calculation is easy. */
+  if (pos == TOP_GUTTER || pos == BOTTOM_GUTTER)
+    {
+      /* grab coordinates of last line  */
+      if (Dynarr_length (ddla))
+	{
+	  dl = Dynarr_atp (ddla, Dynarr_length (ddla) - 1);
+	  size = (dl->ypos + dl->descent - dl->clip) 
+	    - (Dynarr_atp (ddla, 0)->ypos - Dynarr_atp (ddla, 0)->ascent);
+	}
+    }
+  /* For left and right we have to do some maths. */
+  else
+    {
+      int start_pos = 0, end_pos = 0, line;
+      for (line = 0; line < Dynarr_length (ddla); line++)
+	{
+	  int block;
+	  dl = Dynarr_atp (ddla, line);
+
+	  for (block = 0; block < Dynarr_largest (dl->display_blocks); block++)
+	    {
+	      struct display_block *db = Dynarr_atp (dl->display_blocks, block);
+
+	      if (db->type == TEXT)
+		{
+		  start_pos = min (db->start_pos, start_pos);
+		  end_pos = max (db->end_pos, end_pos);
+		}
+	    }
+	}
+      size = end_pos - start_pos;
+    }
+
+  return size;
+}
+
+static Lisp_Object
+calculate_gutter_size (struct window *w, enum gutter_pos pos)
+{
+  struct frame* f = XFRAME (WINDOW_FRAME (w));
+  int count;
+  display_line_dynarr* ddla;
+  Lisp_Object ret = Qnil;
+
+  /* degenerate case */
+  if (NILP (RAW_WINDOW_GUTTER (w, pos))
+      ||
+      !FRAME_VISIBLE_P (f)
+      ||
+      NILP (w->buffer))
+    return Qnil;
+
+  /* Redisplay code that we use relies on GC not happening. Make it
+     so. */
+  count = specpdl_depth ();
+  record_unwind_protect (restore_gc_inhibit,
+			 make_int (gc_currently_forbidden));
+  gc_currently_forbidden = 1;
+
+  ddla = Dynarr_new (display_line);
+  /* generate some display lines */
+  generate_displayable_area (w, WINDOW_GUTTER (w, pos),
+			     FRAME_LEFT_BORDER_END (f),
+			     FRAME_TOP_BORDER_END (f),
+			     FRAME_RIGHT_BORDER_START (f)
+			     - FRAME_LEFT_BORDER_END (f),
+			     FRAME_BOTTOM_BORDER_START (f)
+			     - FRAME_TOP_BORDER_END (f),
+			     ddla, 0, 0);
+
+  /* Let GC happen again. */
+  unbind_to (count, Qnil);
+
+  ret = make_int (calculate_gutter_size_from_display_lines (pos, ddla));
+  free_display_lines (ddla);
+
+  return ret;
+}
+
 static void
 output_gutter (struct frame *f, enum gutter_pos pos, int force)
 {
@@ -339,7 +429,10 @@
          room for, and we are allowed to resize the gutter, then make
          sure this happens before the next time we try and
          output. This can happen when face font sizes change. */
-      if (dl && dl->clip > 0 && EQ (w->gutter_size[pos], Qautodetect))
+      if (dl && EQ (w->gutter_size[pos], Qautodetect) 
+	  && (dl->clip > 0 ||
+	      calculate_gutter_size_from_display_lines (pos, ddla) > 
+	      WINDOW_GUTTER_SIZE_INTERNAL (w, pos)))
 	{
 	  /* #### Ideally we would just mark the specifier as dirty
 	  and everything else would "just work". Unfortunately we have
@@ -378,63 +471,6 @@
   w->gutter_extent_modiff [pos] = 0;
 }
 
-/* Sizing gutters is a pain so we try and help the user by determining
-   what height will accommodate all lines. This is useless on left and
-   right gutters as we always have a maximal number of lines. */
-static Lisp_Object
-calculate_gutter_size (struct window *w, enum gutter_pos pos)
-{
-  struct frame* f = XFRAME (WINDOW_FRAME (w));
-  int ypos, count;
-  display_line_dynarr* ddla;
-  struct display_line *dl;
-
-  /* we cannot autodetect gutter sizes for the left and right as there
-     is no reasonable metric to use */
-  assert (pos == TOP_GUTTER || pos == BOTTOM_GUTTER);
-  /* degenerate case */
-  if (NILP (RAW_WINDOW_GUTTER (w, pos))
-      ||
-      !FRAME_VISIBLE_P (f)
-      ||
-      NILP (w->buffer))
-    return Qnil;
-
-  /* Redisplay code that we use relies on GC not happening. Make it
-     so. */
-  count = specpdl_depth ();
-  record_unwind_protect (restore_gc_inhibit,
-			 make_int (gc_currently_forbidden));
-  gc_currently_forbidden = 1;
-
-  ddla = Dynarr_new (display_line);
-  /* generate some display lines */
-  generate_displayable_area (w, WINDOW_GUTTER (w, pos),
-			     FRAME_LEFT_BORDER_END (f),
-			     0,
-			     FRAME_RIGHT_BORDER_START (f)
-			     - FRAME_LEFT_BORDER_END (f),
-			     200,
-			     ddla, 0, 0);
-
-  /* Let GC happen again. */
-  unbind_to (count, Qnil);
-
-  /* grab coordinates of last line  */
-  if (Dynarr_length (ddla))
-    {
-      dl = Dynarr_atp (ddla, Dynarr_length (ddla) - 1);
-      ypos = dl->ypos + dl->descent - dl->clip;
-      free_display_lines (ddla);
-      return make_int (ypos);
-    }
-  else
-    {
-      free_display_lines (ddla);
-      return Qnil;
-    }
-}
-
 static void
 clear_gutter (struct frame *f, enum gutter_pos pos)
 {
@@ -686,14 +722,8 @@
 			      list1 (Fcons (Qnil, Qzero)));
       set_specifier_fallback (Vgutter_border_width[new],
 			      Vdefault_gutter_border_width);
-      /* We don't really want the left and right gutters to default to
-         visible. */
-      set_specifier_fallback (Vgutter_visible_p[cur],
-			      cur == TOP_GUTTER || cur == BOTTOM_GUTTER ?
-			      list1 (Fcons (Qnil, Qt))
-			      : list1 (Fcons (Qnil, Qnil)));
-      set_specifier_fallback (Vgutter_visible_p[new],
-			      Vdefault_gutter_visible_p);
+      set_specifier_fallback (Vgutter_visible_p[cur], list1 (Fcons (Qnil, Qt)));
+      set_specifier_fallback (Vgutter_visible_p[new], Vdefault_gutter_visible_p);
 
       Vdefault_gutter_position = position;
       unhold_frame_size_changes ();
@@ -1158,7 +1188,7 @@
   set_specifier_caching (Vdefault_gutter,
 			 offsetof (struct window, default_gutter),
 			 default_gutter_specs_changed,
-			 0, 0);
+			 0, 0, 1);
 
   DEFVAR_SPECIFIER ("top-gutter",
 		    &Vgutter[TOP_GUTTER] /*
@@ -1170,7 +1200,7 @@
   set_specifier_caching (Vgutter[TOP_GUTTER],
 			 offsetof (struct window, gutter[TOP_GUTTER]),
 			 top_gutter_specs_changed,
-			 0, 0);
+			 0, 0, 1);
 
   DEFVAR_SPECIFIER ("bottom-gutter",
 		    &Vgutter[BOTTOM_GUTTER] /*
@@ -1187,7 +1217,7 @@
   set_specifier_caching (Vgutter[BOTTOM_GUTTER],
 			 offsetof (struct window, gutter[BOTTOM_GUTTER]),
 			 bottom_gutter_specs_changed,
-			 0, 0);
+			 0, 0, 1);
 
   DEFVAR_SPECIFIER ("left-gutter",
 		    &Vgutter[LEFT_GUTTER] /*
@@ -1204,7 +1234,7 @@
   set_specifier_caching (Vgutter[LEFT_GUTTER],
 			 offsetof (struct window, gutter[LEFT_GUTTER]),
 			 left_gutter_specs_changed,
-			 0, 0);
+			 0, 0, 1);
 
   DEFVAR_SPECIFIER ("right-gutter",
 		    &Vgutter[RIGHT_GUTTER] /*
@@ -1221,7 +1251,7 @@
   set_specifier_caching (Vgutter[RIGHT_GUTTER],
 			 offsetof (struct window, gutter[RIGHT_GUTTER]),
 			 right_gutter_specs_changed,
-			 0, 0);
+			 0, 0, 1);
 
   /* initially, top inherits from default; this can be
      changed with `set-default-gutter-position'. */
@@ -1261,7 +1291,7 @@
   set_specifier_caching (Vdefault_gutter_height,
 			 offsetof (struct window, default_gutter_height),
 			 default_gutter_size_changed_in_window,
-			 0, 0);
+			 0, 0, 1);
 
   DEFVAR_SPECIFIER ("default-gutter-width", &Vdefault_gutter_width /*
 *Width of the default gutter, if it's oriented vertically.
@@ -1269,11 +1299,11 @@
 
 See `default-gutter-height' for more information.
 */ );
-  Vdefault_gutter_width = Fmake_specifier (Qnatnum);
+  Vdefault_gutter_width = Fmake_specifier (Qgutter_size);
   set_specifier_caching (Vdefault_gutter_width,
 			 offsetof (struct window, default_gutter_width),
 			 default_gutter_size_changed_in_window,
-			 0, 0);
+			 0, 0, 1);
 
   DEFVAR_SPECIFIER ("top-gutter-height",
 		    &Vgutter_size[TOP_GUTTER] /*
@@ -1285,7 +1315,7 @@
   Vgutter_size[TOP_GUTTER] = Fmake_specifier (Qgutter_size);
   set_specifier_caching (Vgutter_size[TOP_GUTTER],
 			 offsetof (struct window, gutter_size[TOP_GUTTER]),
-			 gutter_geometry_changed_in_window, 0, 0);
+			 gutter_geometry_changed_in_window, 0, 0, 1);
 
   DEFVAR_SPECIFIER ("bottom-gutter-height",
 		    &Vgutter_size[BOTTOM_GUTTER] /*
@@ -1297,7 +1327,7 @@
   Vgutter_size[BOTTOM_GUTTER] = Fmake_specifier (Qgutter_size);
   set_specifier_caching (Vgutter_size[BOTTOM_GUTTER],
 			 offsetof (struct window, gutter_size[BOTTOM_GUTTER]),
-			 gutter_geometry_changed_in_window, 0, 0);
+			 gutter_geometry_changed_in_window, 0, 0, 1);
 
   DEFVAR_SPECIFIER ("left-gutter-width",
 		    &Vgutter_size[LEFT_GUTTER] /*
@@ -1306,10 +1336,10 @@
 
 See `default-gutter-height' for more information.
 */ );
-  Vgutter_size[LEFT_GUTTER] = Fmake_specifier (Qnatnum);
+  Vgutter_size[LEFT_GUTTER] = Fmake_specifier (Qgutter_size);
   set_specifier_caching (Vgutter_size[LEFT_GUTTER],
 			 offsetof (struct window, gutter_size[LEFT_GUTTER]),
-			 gutter_geometry_changed_in_window, 0, 0);
+			 gutter_geometry_changed_in_window, 0, 0, 1);
 
   DEFVAR_SPECIFIER ("right-gutter-width",
 		    &Vgutter_size[RIGHT_GUTTER] /*
@@ -1318,10 +1348,10 @@
 
 See `default-gutter-height' for more information.
 */ );
-  Vgutter_size[RIGHT_GUTTER] = Fmake_specifier (Qnatnum);
+  Vgutter_size[RIGHT_GUTTER] = Fmake_specifier (Qgutter_size);
   set_specifier_caching (Vgutter_size[RIGHT_GUTTER],
 			 offsetof (struct window, gutter_size[RIGHT_GUTTER]),
-			 gutter_geometry_changed_in_window, 0, 0);
+			 gutter_geometry_changed_in_window, 0, 0, 1);
 
   fb = Qnil;
 #ifdef HAVE_TTY
@@ -1339,15 +1369,14 @@
 
   fb = Qnil;
 #ifdef HAVE_TTY
-  fb = Fcons (Fcons (list1 (Qtty), Qzero), fb);
+  fb = Fcons (Fcons (list1 (Qtty), Qautodetect), fb);
 #endif
 #ifdef HAVE_X_WINDOWS
-  fb = Fcons (Fcons (list1 (Qx), make_int (DEFAULT_GUTTER_WIDTH)), fb);
+  fb = Fcons (Fcons (list1 (Qx), Qautodetect), fb);
 #endif
 #ifdef HAVE_MS_WINDOWS
-  fb = Fcons (Fcons (list1 (Qmsprinter), Qzero), fb);
-  fb = Fcons (Fcons (list1 (Qmswindows),
-		     make_int (DEFAULT_GUTTER_WIDTH)), fb);
+  fb = Fcons (Fcons (list1 (Qmsprinter), Qautodetect), fb);
+  fb = Fcons (Fcons (list1 (Qmswindows), Qautodetect), fb);
 #endif
   if (!NILP (fb))
     set_specifier_fallback (Vdefault_gutter_width, fb);
@@ -1376,7 +1405,7 @@
   set_specifier_caching (Vdefault_gutter_border_width,
 			 offsetof (struct window, default_gutter_border_width),
 			 default_gutter_border_width_changed_in_window,
-			 0, 0);
+			 0, 0, 0);
 
   DEFVAR_SPECIFIER ("top-gutter-border-width",
 		    &Vgutter_border_width[TOP_GUTTER] /*
@@ -1389,7 +1418,7 @@
   set_specifier_caching (Vgutter_border_width[TOP_GUTTER],
 			 offsetof (struct window,
 				   gutter_border_width[TOP_GUTTER]),
-			 gutter_geometry_changed_in_window, 0, 0);
+			 gutter_geometry_changed_in_window, 0, 0, 0);
 
   DEFVAR_SPECIFIER ("bottom-gutter-border-width",
 		    &Vgutter_border_width[BOTTOM_GUTTER] /*
@@ -1402,7 +1431,7 @@
   set_specifier_caching (Vgutter_border_width[BOTTOM_GUTTER],
 			 offsetof (struct window,
 				   gutter_border_width[BOTTOM_GUTTER]),
-			 gutter_geometry_changed_in_window, 0, 0);
+			 gutter_geometry_changed_in_window, 0, 0, 0);
 
   DEFVAR_SPECIFIER ("left-gutter-border-width",
 		    &Vgutter_border_width[LEFT_GUTTER] /*
@@ -1415,7 +1444,7 @@
   set_specifier_caching (Vgutter_border_width[LEFT_GUTTER],
 			 offsetof (struct window,
 				   gutter_border_width[LEFT_GUTTER]),
-			 gutter_geometry_changed_in_window, 0, 0);
+			 gutter_geometry_changed_in_window, 0, 0, 0);
 
   DEFVAR_SPECIFIER ("right-gutter-border-width",
 		    &Vgutter_border_width[RIGHT_GUTTER] /*
@@ -1428,7 +1457,7 @@
   set_specifier_caching (Vgutter_border_width[RIGHT_GUTTER],
 			 offsetof (struct window,
 				   gutter_border_width[RIGHT_GUTTER]),
-			 gutter_geometry_changed_in_window, 0, 0);
+			 gutter_geometry_changed_in_window, 0, 0, 0);
 
   fb = Qnil;
 #ifdef HAVE_TTY
@@ -1470,7 +1499,7 @@
 			 offsetof (struct window,
 				   default_gutter_visible_p),
 			 default_gutter_visible_p_changed_in_window,
-			 0, 0);
+			 0, 0, 0);
 
   DEFVAR_SPECIFIER ("top-gutter-visible-p",
 		    &Vgutter_visible_p[TOP_GUTTER] /*
@@ -1483,7 +1512,7 @@
   set_specifier_caching (Vgutter_visible_p[TOP_GUTTER],
 			 offsetof (struct window,
 				   gutter_visible_p[TOP_GUTTER]),
-			 top_gutter_specs_changed, 0, 0);
+			 top_gutter_specs_changed, 0, 0, 0);
 
   DEFVAR_SPECIFIER ("bottom-gutter-visible-p",
 		    &Vgutter_visible_p[BOTTOM_GUTTER] /*
@@ -1496,7 +1525,7 @@
   set_specifier_caching (Vgutter_visible_p[BOTTOM_GUTTER],
 			 offsetof (struct window,
 				   gutter_visible_p[BOTTOM_GUTTER]),
-			 bottom_gutter_specs_changed, 0, 0);
+			 bottom_gutter_specs_changed, 0, 0, 0);
 
   DEFVAR_SPECIFIER ("left-gutter-visible-p",
 		    &Vgutter_visible_p[LEFT_GUTTER] /*
@@ -1509,7 +1538,7 @@
   set_specifier_caching (Vgutter_visible_p[LEFT_GUTTER],
 			 offsetof (struct window,
 				   gutter_visible_p[LEFT_GUTTER]),
-			 left_gutter_specs_changed, 0, 0);
+			 left_gutter_specs_changed, 0, 0, 0);
 
   DEFVAR_SPECIFIER ("right-gutter-visible-p",
 		    &Vgutter_visible_p[RIGHT_GUTTER] /*
@@ -1522,7 +1551,7 @@
   set_specifier_caching (Vgutter_visible_p[RIGHT_GUTTER],
 			 offsetof (struct window,
 				   gutter_visible_p[RIGHT_GUTTER]),
-			 right_gutter_specs_changed, 0, 0);
+			 right_gutter_specs_changed, 0, 0, 0);
 
   /* initially, top inherits from default; this can be
      changed with `set-default-gutter-position'. */
Index: src/menubar.c
===================================================================
RCS file: /usr/CVSroot/XEmacs/xemacs/src/menubar.c,v
retrieving revision 1.12.2.12
diff -u -r1.12.2.12 menubar.c
--- src/menubar.c 2000/08/06 09:27:20 1.12.2.12
+++ src/menubar.c 2000/11/07 01:58:26
@@ -739,7 +739,7 @@
 			 offsetof (struct window, menubar_visible_p),
 			 menubar_visible_p_changed,
 			 offsetof (struct frame, menubar_visible_p),
-			 menubar_visible_p_changed_in_frame);
+			 menubar_visible_p_changed_in_frame, 0);
 }
 
 void
Index: src/redisplay.c
===================================================================
RCS file: /usr/CVSroot/XEmacs/xemacs/src/redisplay.c,v
retrieving revision 1.55.2.63
diff -u -r1.55.2.63 redisplay.c
--- src/redisplay.c 2000/09/20 02:38:36 1.55.2.63
+++ src/redisplay.c 2000/11/07 01:58:52
@@ -9451,7 +9451,7 @@
 			 offsetof (struct window, left_margin_width),
 			 some_window_value_changed,
 			 offsetof (struct frame, left_margin_width),
-			 margin_width_changed_in_frame);
+			 margin_width_changed_in_frame, 0);
 
   DEFVAR_SPECIFIER ("right-margin-width", &Vright_margin_width /*
 *Width of right margin.
@@ -9463,7 +9463,7 @@
 			 offsetof (struct window, right_margin_width),
 			 some_window_value_changed,
 			 offsetof (struct frame, right_margin_width),
-			 margin_width_changed_in_frame);
+			 margin_width_changed_in_frame, 0);
 
   DEFVAR_SPECIFIER ("minimum-line-ascent", &Vminimum_line_ascent /*
 *Minimum ascent height of lines.
@@ -9474,7 +9474,7 @@
   set_specifier_caching (Vminimum_line_ascent,
 			 offsetof (struct window, minimum_line_ascent),
 			 some_window_value_changed,
-			 0, 0);
+			 0, 0, 0);
 
   DEFVAR_SPECIFIER ("minimum-line-descent", &Vminimum_line_descent /*
 *Minimum descent height of lines.
@@ -9485,7 +9485,7 @@
   set_specifier_caching (Vminimum_line_descent,
 			 offsetof (struct window, minimum_line_descent),
 			 some_window_value_changed,
-			 0, 0);
+			 0, 0, 0);
 
   DEFVAR_SPECIFIER ("use-left-overflow", &Vuse_left_overflow /*
 *Non-nil means use the left outside margin as extra whitespace when
@@ -9497,7 +9497,7 @@
   set_specifier_caching (Vuse_left_overflow,
 			 offsetof (struct window, use_left_overflow),
 			 some_window_value_changed,
-			 0, 0);
+			 0, 0, 0);
 
   DEFVAR_SPECIFIER ("use-right-overflow", &Vuse_right_overflow /*
 *Non-nil means use the right outside margin as extra whitespace when
@@ -9509,7 +9509,7 @@
   set_specifier_caching (Vuse_right_overflow,
 			 offsetof (struct window, use_right_overflow),
 			 some_window_value_changed,
-			 0, 0);
+			 0, 0, 0);
 
   DEFVAR_SPECIFIER ("text-cursor-visible-p", &Vtext_cursor_visible_p /*
 *Non-nil means the text cursor is visible (this is usually the case).
@@ -9520,6 +9520,6 @@
   set_specifier_caching (Vtext_cursor_visible_p,
 			 offsetof (struct window, text_cursor_visible_p),
 			 text_cursor_visible_p_changed,
-			 0, 0);
+			 0, 0, 0);
 
 }
Index: src/scrollbar.c
===================================================================
RCS file: /usr/CVSroot/XEmacs/xemacs/src/scrollbar.c,v
retrieving revision 1.17.2.8
diff -u -r1.17.2.8 scrollbar.c
--- src/scrollbar.c 2000/10/03 06:29:29 1.17.2.8
+++ src/scrollbar.c 2000/11/07 01:58:54
@@ -953,7 +953,7 @@
 			 offsetof (struct window, scrollbar_width),
 			 vertical_scrollbar_changed_in_window,
 			 offsetof (struct frame, scrollbar_width),
-			 frame_size_slipped);
+			 frame_size_slipped, 0);
 
   DEFVAR_SPECIFIER ("scrollbar-height", &Vscrollbar_height /*
 *Height of horizontal scrollbars.
@@ -967,7 +967,7 @@
 			 offsetof (struct window, scrollbar_height),
 			 some_window_value_changed,
 			 offsetof (struct frame, scrollbar_height),
-			 frame_size_slipped);
+			 frame_size_slipped, 0);
 
   DEFVAR_SPECIFIER ("horizontal-scrollbar-visible-p", &Vhorizontal_scrollbar_visible_p /*
 *Whether the horizontal scrollbar is visible.
@@ -982,7 +982,7 @@
 			 some_window_value_changed,
 			 offsetof (struct frame,
 				   horizontal_scrollbar_visible_p),
-			 frame_size_slipped);
+			 frame_size_slipped, 0);
 
   DEFVAR_SPECIFIER ("vertical-scrollbar-visible-p", &Vvertical_scrollbar_visible_p /*
 *Whether the vertical scrollbar is visible.
@@ -997,7 +997,7 @@
 			 vertical_scrollbar_changed_in_window,
 			 offsetof (struct frame,
 				   vertical_scrollbar_visible_p),
-			 frame_size_slipped);
+			 frame_size_slipped, 0);
 
   DEFVAR_SPECIFIER ("scrollbar-on-left-p", &Vscrollbar_on_left_p /*
 *Whether the vertical scrollbar is on the left side of window or frame.
@@ -1023,7 +1023,7 @@
 			 offsetof (struct window, scrollbar_on_left_p),
 			 vertical_scrollbar_changed_in_window,
 			 offsetof (struct frame, scrollbar_on_left_p),
-			 frame_size_slipped);
+			 frame_size_slipped, 0);
 
   DEFVAR_SPECIFIER ("scrollbar-on-top-p", &Vscrollbar_on_top_p /*
 *Whether the horizontal scrollbar is on the top side of window or frame.
@@ -1036,7 +1036,7 @@
 			 offsetof (struct window, scrollbar_on_top_p),
 			 some_window_value_changed,
 			 offsetof (struct frame, scrollbar_on_top_p),
-			 frame_size_slipped);
+			 frame_size_slipped, 0);
 }
 
 void
@@ -1047,5 +1047,5 @@
   set_specifier_caching (XGLYPH (Vscrollbar_pointer_glyph)->image,
 			 offsetof (struct window, scrollbar_pointer),
 			 scrollbar_pointer_changed_in_window,
-			 0, 0);
+			 0, 0, 0);
 }
Index: src/specifier.c
===================================================================
RCS file: /usr/CVSroot/XEmacs/xemacs/src/specifier.c,v
retrieving revision 1.15.2.22
diff -u -r1.15.2.22 specifier.c
--- src/specifier.c 2000/07/21 10:17:17 1.15.2.22
+++ src/specifier.c 2000/11/07 01:59:03
@@ -2836,7 +2836,8 @@
 		       int struct_frame_offset,
 		       void (*value_changed_in_frame)
 		       (Lisp_Object specifier, struct frame *f,
-			Lisp_Object oldval))
+			Lisp_Object oldval),
+		       int always_recompute)
 {
   Lisp_Specifier *sp = XSPECIFIER (specifier);
   assert (!GHOST_SPECIFIER_P (sp));
@@ -2847,6 +2848,7 @@
   sp->caching->value_changed_in_window = value_changed_in_window;
   sp->caching->offset_into_struct_frame = struct_frame_offset;
   sp->caching->value_changed_in_frame = value_changed_in_frame;
+  sp->caching->always_recompute = always_recompute;
   Vcached_specifiers = Fcons (specifier, Vcached_specifiers);
   if (BODILY_SPECIFIER_P (sp))
     GHOST_SPECIFIER(sp)->caching = sp->caching;
@@ -2858,7 +2860,7 @@
 					  struct window *w)
 {
   Lisp_Object window;
-  Lisp_Object newval, *location;
+  Lisp_Object newval, *location, oldval;
 
   assert (!GHOST_SPECIFIER_P (XSPECIFIER (specifier)));
 
@@ -2879,9 +2881,9 @@
      calling equal is no good either as this doesn't take into account
      things attached to the specifier - for instance strings on
      extents. --andyp */
-  if (!EQ (newval, *location))
+  if (!EQ (newval, *location) || XSPECIFIER (specifier)->caching->always_recompute)
     {
-      Lisp_Object oldval = *location;
+      oldval = *location;
       *location = newval;
       (XSPECIFIER (specifier)->caching->value_changed_in_window)
 	(specifier, w, oldval);
@@ -2893,7 +2895,7 @@
 					 struct frame *f)
 {
   Lisp_Object frame;
-  Lisp_Object newval, *location;
+  Lisp_Object newval, *location, oldval;
 
   assert (!GHOST_SPECIFIER_P (XSPECIFIER (specifier)));
 
@@ -2907,9 +2909,9 @@
      method. */
   location = (Lisp_Object *)
     ((char *) f + XSPECIFIER (specifier)->caching->offset_into_struct_frame);
-  if (!EQ (newval, *location))
+  if (!EQ (newval, *location) || XSPECIFIER (specifier)->caching->always_recompute)
     {
-      Lisp_Object oldval = *location;
+      oldval = *location;
       *location = newval;
       (XSPECIFIER (specifier)->caching->value_changed_in_frame)
 	(specifier, f, oldval);
Index: src/specifier.h
===================================================================
RCS file: /usr/CVSroot/XEmacs/xemacs/src/specifier.h,v
retrieving revision 1.6.2.14
diff -u -r1.6.2.14 specifier.h
--- src/specifier.h 2000/09/20 02:38:22 1.6.2.14
+++ src/specifier.h 2000/11/07 01:59:05
@@ -411,6 +411,7 @@
   int offset_into_struct_frame;
   void (*value_changed_in_frame) (Lisp_Object specifier, struct frame *f,
 				  Lisp_Object oldval);
+  int always_recompute;
 };
 
 /* #### get image instances out of domains! */
@@ -480,7 +481,8 @@
 			    int struct_frame_offset,
 			    void (*value_changed_in_frame)
 			    (Lisp_Object specifier, struct frame *f,
-			     Lisp_Object oldval));
+			     Lisp_Object oldval),
+			    int always_recompute);
 void set_specifier_fallback (Lisp_Object specifier,
 			     Lisp_Object fallback);
 void recompute_all_cached_specifiers_in_window (struct window *w);
Index: src/toolbar.c
===================================================================
RCS file: /usr/CVSroot/XEmacs/xemacs/src/toolbar.c,v
retrieving revision 1.18.2.11
diff -u -r1.18.2.11 toolbar.c
--- src/toolbar.c 2000/10/03 06:29:35 1.18.2.11
+++ src/toolbar.c 2000/11/07 01:59:10
@@ -1417,7 +1417,7 @@
   set_specifier_caching (Vdefault_toolbar,
 			 offsetof (struct window, default_toolbar),
 			 default_toolbar_specs_changed,
-			 0, 0);
+			 0, 0, 0);
 
   DEFVAR_SPECIFIER ("top-toolbar",
 		    &Vtoolbar[TOP_TOOLBAR] /*
@@ -1429,7 +1429,7 @@
   set_specifier_caching (Vtoolbar[TOP_TOOLBAR],
 			 offsetof (struct window, toolbar[TOP_TOOLBAR]),
 			 toolbar_specs_changed,
-			 0, 0);
+			 0, 0, 0);
 
   DEFVAR_SPECIFIER ("bottom-toolbar",
 		    &Vtoolbar[BOTTOM_TOOLBAR] /*
@@ -1446,7 +1446,7 @@
   set_specifier_caching (Vtoolbar[BOTTOM_TOOLBAR],
 			 offsetof (struct window, toolbar[BOTTOM_TOOLBAR]),
 			 toolbar_specs_changed,
-			 0, 0);
+			 0, 0, 0);
 
   DEFVAR_SPECIFIER ("left-toolbar",
 		    &Vtoolbar[LEFT_TOOLBAR] /*
@@ -1463,7 +1463,7 @@
   set_specifier_caching (Vtoolbar[LEFT_TOOLBAR],
 			 offsetof (struct window, toolbar[LEFT_TOOLBAR]),
 			 toolbar_specs_changed,
-			 0, 0);
+			 0, 0, 0);
 
   DEFVAR_SPECIFIER ("right-toolbar",
 		    &Vtoolbar[RIGHT_TOOLBAR] /*
@@ -1480,7 +1480,7 @@
   set_specifier_caching (Vtoolbar[RIGHT_TOOLBAR],
 			 offsetof (struct window, toolbar[RIGHT_TOOLBAR]),
 			 toolbar_specs_changed,
-			 0, 0);
+			 0, 0, 0);
 
   /* initially, top inherits from default; this can be
      changed with `set-default-toolbar-position'. */
@@ -1535,7 +1535,7 @@
 			 offsetof (struct window, default_toolbar_height),
 			 default_toolbar_size_changed_in_window,
 			 offsetof (struct frame, default_toolbar_height),
-			 default_toolbar_size_changed_in_frame);
+			 default_toolbar_size_changed_in_frame, 0);
 
   DEFVAR_SPECIFIER ("default-toolbar-width", &Vdefault_toolbar_width /*
 *Width of the default toolbar, if it's oriented vertically.
@@ -1548,7 +1548,7 @@
 			 offsetof (struct window, default_toolbar_width),
 			 default_toolbar_size_changed_in_window,
 			 offsetof (struct frame, default_toolbar_width),
-			 default_toolbar_size_changed_in_frame);
+			 default_toolbar_size_changed_in_frame, 0);
 
   DEFVAR_SPECIFIER ("top-toolbar-height",
 		    &Vtoolbar_size[TOP_TOOLBAR] /*
@@ -1562,7 +1562,7 @@
 			 offsetof (struct window, toolbar_size[TOP_TOOLBAR]),
 			 toolbar_geometry_changed_in_window,
 			 offsetof (struct frame, toolbar_size[TOP_TOOLBAR]),
-			 frame_size_slipped);
+			 frame_size_slipped, 0);
 
   DEFVAR_SPECIFIER ("bottom-toolbar-height",
 		    &Vtoolbar_size[BOTTOM_TOOLBAR] /*
@@ -1576,7 +1576,7 @@
 			 offsetof (struct window, toolbar_size[BOTTOM_TOOLBAR]),
 			 toolbar_geometry_changed_in_window,
 			 offsetof (struct frame, toolbar_size[BOTTOM_TOOLBAR]),
-			 frame_size_slipped);
+			 frame_size_slipped, 0);
 
   DEFVAR_SPECIFIER ("left-toolbar-width",
 		    &Vtoolbar_size[LEFT_TOOLBAR] /*
@@ -1590,7 +1590,7 @@
 			 offsetof (struct window, toolbar_size[LEFT_TOOLBAR]),
 			 toolbar_geometry_changed_in_window,
 			 offsetof (struct frame, toolbar_size[LEFT_TOOLBAR]),
-			 frame_size_slipped);
+			 frame_size_slipped, 0);
 
   DEFVAR_SPECIFIER ("right-toolbar-width",
 		    &Vtoolbar_size[RIGHT_TOOLBAR] /*
@@ -1604,7 +1604,7 @@
 			 offsetof (struct window, toolbar_size[RIGHT_TOOLBAR]),
 			 toolbar_geometry_changed_in_window,
 			 offsetof (struct frame, toolbar_size[RIGHT_TOOLBAR]),
-			 frame_size_slipped);
+			 frame_size_slipped, 0);
 
   fb = Qnil;
 #ifdef HAVE_TTY
@@ -1667,7 +1667,7 @@
 			 offsetof (struct window, default_toolbar_border_width),
 			 default_toolbar_border_width_changed_in_window,
 			 offsetof (struct frame, default_toolbar_border_width),
-			 default_toolbar_border_width_changed_in_frame);
+			 default_toolbar_border_width_changed_in_frame, 0);
 
   DEFVAR_SPECIFIER ("top-toolbar-border-width",
 		    &Vtoolbar_border_width[TOP_TOOLBAR] /*
@@ -1683,7 +1683,7 @@
 			 toolbar_geometry_changed_in_window,
 			 offsetof (struct frame,
 				   toolbar_border_width[TOP_TOOLBAR]),
-			 frame_size_slipped);
+			 frame_size_slipped, 0);
 
   DEFVAR_SPECIFIER ("bottom-toolbar-border-width",
 		    &Vtoolbar_border_width[BOTTOM_TOOLBAR] /*
@@ -1699,7 +1699,7 @@
 			 toolbar_geometry_changed_in_window,
 			 offsetof (struct frame,
 				   toolbar_border_width[BOTTOM_TOOLBAR]),
-			 frame_size_slipped);
+			 frame_size_slipped, 0);
 
   DEFVAR_SPECIFIER ("left-toolbar-border-width",
 		    &Vtoolbar_border_width[LEFT_TOOLBAR] /*
@@ -1715,7 +1715,7 @@
 			 toolbar_geometry_changed_in_window,
 			 offsetof (struct frame,
 				   toolbar_border_width[LEFT_TOOLBAR]),
-			 frame_size_slipped);
+			 frame_size_slipped, 0);
 
   DEFVAR_SPECIFIER ("right-toolbar-border-width",
 		    &Vtoolbar_border_width[RIGHT_TOOLBAR] /*
@@ -1731,7 +1731,7 @@
 			 toolbar_geometry_changed_in_window,
 			 offsetof (struct frame,
 				   toolbar_border_width[RIGHT_TOOLBAR]),
-			 frame_size_slipped);
+			 frame_size_slipped, 0);
 
   fb = Qnil;
 #ifdef HAVE_TTY
@@ -1777,7 +1777,7 @@
 			 offsetof (struct window, default_toolbar_visible_p),
 			 default_toolbar_visible_p_changed_in_window,
 			 offsetof (struct frame, default_toolbar_visible_p),
-			 default_toolbar_visible_p_changed_in_frame);
+			 default_toolbar_visible_p_changed_in_frame, 0);
 
   DEFVAR_SPECIFIER ("top-toolbar-visible-p",
 		    &Vtoolbar_visible_p[TOP_TOOLBAR] /*
@@ -1793,7 +1793,7 @@
 			 toolbar_geometry_changed_in_window,
 			 offsetof (struct frame,
 				   toolbar_visible_p[TOP_TOOLBAR]),
-			 frame_size_slipped);
+			 frame_size_slipped, 0);
 
   DEFVAR_SPECIFIER ("bottom-toolbar-visible-p",
 		    &Vtoolbar_visible_p[BOTTOM_TOOLBAR] /*
@@ -1809,7 +1809,7 @@
 			 toolbar_geometry_changed_in_window,
 			 offsetof (struct frame,
 				   toolbar_visible_p[BOTTOM_TOOLBAR]),
-			 frame_size_slipped);
+			 frame_size_slipped, 0);
 
   DEFVAR_SPECIFIER ("left-toolbar-visible-p",
 		    &Vtoolbar_visible_p[LEFT_TOOLBAR] /*
@@ -1825,7 +1825,7 @@
 			 toolbar_geometry_changed_in_window,
 			 offsetof (struct frame,
 				   toolbar_visible_p[LEFT_TOOLBAR]),
-			 frame_size_slipped);
+			 frame_size_slipped, 0);
 
   DEFVAR_SPECIFIER ("right-toolbar-visible-p",
 		    &Vtoolbar_visible_p[RIGHT_TOOLBAR] /*
@@ -1841,7 +1841,7 @@
 			 toolbar_geometry_changed_in_window,
 			 offsetof (struct frame,
 				   toolbar_visible_p[RIGHT_TOOLBAR]),
-			 frame_size_slipped);
+			 frame_size_slipped, 0);
 
   /* initially, top inherits from default; this can be
      changed with `set-default-toolbar-position'. */
@@ -1864,7 +1864,7 @@
   set_specifier_caching (Vtoolbar_buttons_captioned_p,
 			 offsetof (struct window, toolbar_buttons_captioned_p),
 			 toolbar_buttons_captioned_p_changed,
-			 0, 0);
+			 0, 0, 0);
   set_specifier_fallback (Vtoolbar_buttons_captioned_p,
 			  list1 (Fcons (Qnil, Qt)));
 }
Index: src/unexcw.c
===================================================================
RCS file: /usr/CVSroot/XEmacs/xemacs/src/unexcw.c,v
retrieving revision 1.4.2.6
diff -u -r1.4.2.6 unexcw.c
--- src/unexcw.c 2000/08/06 09:27:24 1.4.2.6
+++ src/unexcw.c 2000/11/07 01:59:12
@@ -51,6 +51,9 @@
 #define ALLOC_MASK ~((unsigned long)(ALLOC_UNIT))
 #define ALIGN_ALLOC(addr) \
 ((((unsigned long)addr) + ALLOC_UNIT) & ALLOC_MASK)
+/* Note that all sections must be aligned on a 0x1000 boundary so
+   this is the minimum size that our dummy bss can be. */
+#define BSS_PAD_SIZE	0x1000
 
 /* To prevent zero-initialized variables from being placed into the bss
    section, use non-zero values to represent an uninitialized state.  */
@@ -252,14 +255,20 @@
   void* empty_space;
   extern int static_heap_dumped;
   SCNHDR section;
-  /* calculate new sizes f_ohdr.dsize is the total initialized data
-     size on disk which is f_data.s_size + f_idata.s_size. 
-     f_ohdr.data_start is the base addres of all data and so should 
-     not be changed. *.s_vaddr is the virtual address of the start
-     of the section normalzed from f_ohdr.ImageBase. *.s_paddr
-     appears to be the number of bytes in the section actually used
-     (whereas *.s_size is aligned).
+  /* calculate new sizes:
 
+     f_ohdr.dsize is the total initialized data size on disk which is
+     f_data.s_size + f_idata.s_size.
+
+     f_ohdr.data_start is the base addres of all data and so should
+     not be changed.
+     
+     *.s_vaddr is the virtual address of the start of the section
+     *normalized from f_ohdr.ImageBase.
+
+     *.s_paddr appears to be the number of bytes in the section
+     *actually used (whereas *.s_size is aligned).
+
      bsize is now 0 since subsumed into .data
      dsize is dsize + (f_data.s_vaddr - f_bss.s_vaddr)
      f_data.s_vaddr is f_bss.s_vaddr
@@ -278,7 +287,7 @@
       data_padding = (f_bss.s_vaddr - f_data.s_vaddr) - f_data.s_size;
     }
 
-  file_sz_change=new_bss_size + data_padding;
+  file_sz_change=(new_bss_size + data_padding) - BSS_PAD_SIZE;
   new_data_size=f_ohdr.dsize + file_sz_change;
 
   if (!sections_reversed)
@@ -297,7 +306,7 @@
   lseek (a_new, 0, SEEK_SET);
   /* write file header */
   f_hdr.f_symptr += file_sz_change;
-  f_hdr.f_nscns--;
+
   printf("writing file header\n");
   if (write(a_new, &f_hdr, sizeof(f_hdr)) != sizeof(f_hdr))
     {
@@ -312,7 +321,7 @@
       PERROR("new data size is < approx");
     }
   f_ohdr.dsize=new_data_size;
-  f_ohdr.bsize=0;
+  f_ohdr.bsize=BSS_PAD_SIZE;
   if (write(a_new, &f_ohdr, sizeof(f_ohdr)) != sizeof(f_ohdr))
     {
       PERROR("failed to write optional header");
@@ -325,6 +334,18 @@
       PERROR("failed to write text header");
     }
 
+  /* Write small bss section. */
+  if (!sections_reversed)
+    {
+      f_bss.s_size = BSS_PAD_SIZE;
+      f_bss.s_paddr = BSS_PAD_SIZE;
+      f_bss.s_vaddr = f_data.s_vaddr - BSS_PAD_SIZE;
+      if (write(a_new, &f_bss, sizeof(f_bss)) != sizeof(f_bss))
+	{
+	  PERROR("failed to write bss header");
+	}
+    }
+
   /* write new data header */
   printf("writing .data header\n");
 
@@ -333,6 +354,18 @@
       PERROR("failed to write data header");
     }
 
+  /* Write small bss section. */
+  if (sections_reversed)
+    {
+      f_bss.s_size = BSS_PAD_SIZE;
+      f_bss.s_paddr = BSS_PAD_SIZE;
+      f_bss.s_vaddr = f_nextdata.s_vaddr - BSS_PAD_SIZE;
+      if (write(a_new, &f_bss, sizeof(f_bss)) != sizeof(f_bss))
+	{
+	  PERROR("failed to write bss header");
+	}
+    }
+
   printf("writing following data header\n");
   f_nextdata.s_scnptr += file_sz_change;
   if (f_nextdata.s_lnnoptr != 0) f_nextdata.s_lnnoptr += file_sz_change;
@@ -360,13 +393,6 @@
 	}
     }
 
-  /* dump bss to maintain offsets */
-  memset(&f_bss, 0, sizeof(f_bss));
-  if (write(a_new, &f_bss, sizeof(f_bss)) != sizeof(f_bss))
-    {
-      PERROR("failed to write bss header");
-    }
-  
   size=lseek(a_new, 0, SEEK_CUR);
   CHECK_AOUT_POS(size);
 
@@ -381,7 +407,7 @@
 
   if (!sections_reversed)
     {
-      /* dump bss + padding between sections */
+      /* dump bss + padding between sections, sans small bss pad */
       printf ("dumping .bss into executable... %lx bytes\n", bss_size);
       if (write(a_new, bss_start, bss_size) != (int)bss_size)
 	{
@@ -389,7 +415,11 @@
 	}
       
       /* pad, needs to be zero */
-      bss_padding = new_bss_size - bss_size;
+      bss_padding = (new_bss_size - bss_size) - BSS_PAD_SIZE;
+      if (bss_padding < 0)
+	{
+	  PERROR("padded .bss too small");
+	}
       printf ("padding .bss ... %lx bytes\n", bss_padding);
       empty_space = malloc(bss_padding);
       memset(empty_space, 0, bss_padding);
@@ -420,7 +450,7 @@
     }
   else
     {
-      /* need to bad to bss with data in file */
+      /* need to pad to bss with data in file */
       printf ("padding .data ... %lx bytes\n", data_padding);
       size = (f_bss_s_vaddr - f_data_s_vaddr) - data_size;
       dup_file_area(a_out, a_new, size);
@@ -433,7 +463,11 @@
 	}
       
       /* pad, needs to be zero */
-      bss_padding = new_bss_size - bss_size;
+      bss_padding = (new_bss_size - bss_size) - BSS_PAD_SIZE;
+      if (bss_padding < 0)
+	{
+	  PERROR("padded .bss too small");
+	}
       printf ("padding .bss ... %lx bytes\n", bss_padding);
       empty_space = malloc(bss_padding);
       memset(empty_space, 0, bss_padding);
Index: src/window.c
===================================================================
RCS file: /usr/CVSroot/XEmacs/xemacs/src/window.c,v
retrieving revision 1.41.2.64
diff -u -r1.41.2.64 window.c
--- src/window.c 2000/09/15 04:15:39 1.41.2.64
+++ src/window.c 2000/11/07 01:59:28
@@ -6136,7 +6136,7 @@
   set_specifier_caching (Vmodeline_shadow_thickness,
 			 offsetof (struct window, modeline_shadow_thickness),
 			 modeline_shadow_thickness_changed,
-			 0, 0);
+			 0, 0, 0);
 
   DEFVAR_SPECIFIER ("has-modeline-p", &Vhas_modeline_p /*
 *Whether the modeline should be displayed.
@@ -6152,7 +6152,7 @@
 			    has changed, but not one to indicate that
 			    the modeline has been turned off or on. */
 			 some_window_value_changed,
-			 0, 0);
+			 0, 0, 0);
 
   DEFVAR_SPECIFIER ("vertical-divider-always-visible-p",
 		    &Vvertical_divider_always_visible_p /*
@@ -6171,7 +6171,7 @@
 			 offsetof (struct window,
 				   vertical_divider_always_visible_p),
 			 vertical_divider_changed_in_window,
- 			 0, 0);
+ 			 0, 0, 0);
 
   DEFVAR_SPECIFIER ("vertical-divider-shadow-thickness", &Vvertical_divider_shadow_thickness /*
 *How thick to draw 3D shadows around vertical dividers.
@@ -6186,7 +6186,7 @@
 			 offsetof (struct window,
 				   vertical_divider_shadow_thickness),
 			 vertical_divider_changed_in_window,
- 			 0, 0);
+ 			 0, 0, 0);
   DEFVAR_SPECIFIER ("vertical-divider-line-width", &Vvertical_divider_line_width /*
 *The width of the vertical dividers, not including shadows.
 
@@ -6217,7 +6217,7 @@
                          offsetof (struct window,
 				   vertical_divider_line_width),
 			 vertical_divider_changed_in_window,
-                         0, 0);
+                         0, 0, 0);
 
   DEFVAR_SPECIFIER ("vertical-divider-spacing", &Vvertical_divider_spacing /*
 *How much space to leave around the vertical dividers.
@@ -6246,5 +6246,5 @@
   set_specifier_caching (Vvertical_divider_spacing,
 			 offsetof (struct window, vertical_divider_spacing),
 			 vertical_divider_changed_in_window,
-			 0, 0);
+			 0, 0, 0);
 }
