changeset 5130:4f4672e2aa34 ben-lisp-object

merge
author Ben Wing <ben@xemacs.org>
date Sun, 07 Mar 2010 06:20:19 -0600
parents ebd8cab8629f (current diff) 34b22f7e1815 (diff)
children b42a3c0d709e
files lisp/ChangeLog src/ChangeLog src/frame.c
diffstat 7 files changed, 570 insertions(+), 277 deletions(-) [+]
line wrap: on
line diff
--- a/lisp/ChangeLog	Sun Mar 07 02:23:16 2010 -0600
+++ b/lisp/ChangeLog	Sun Mar 07 06:20:19 2010 -0600
@@ -1,3 +1,19 @@
+2010-03-06  Ben Wing  <ben@xemacs.org>
+
+	* test-harness.el:
+	* test-harness.el (test-harness-backtrace): New.
+	* test-harness.el (test-harness-assertion-failure-do-debug):
+	* test-harness.el (test-harness-unexpected-error-do-debug):
+	Use the print settings from edebug.el to make backtraces not
+	be so huge.
+
+2010-03-06  Aidan Kehoe  <kehoea@parhasard.net>
+
+	* bytecomp.el (byte-compile-compiled-obj-to-list):
+	Remove this function, printing a compiled object to a string and
+	then reading back a substring is senseless, just use the
+	compiled-function slot accessor functions.
+
 2010-03-05  Aidan Kehoe  <kehoea@parhasard.net>
 
 	* cl-macs.el (delete-duplicates):
--- a/lisp/bytecomp.el	Sun Mar 07 02:23:16 2010 -0600
+++ b/lisp/bytecomp.el	Sun Mar 07 06:20:19 2010 -0600
@@ -2247,22 +2247,6 @@
 (defun byte-compile-file-form-defmacro (form)
   (byte-compile-file-form-defmumble form t))
 
-(defun byte-compile-compiled-obj-to-list (obj)
-  ;; #### this is fairly disgusting.  Rewrite the code instead
-  ;; so that it doesn't create compiled objects in the first place!
-  ;; Much better than creating them and then "uncreating" them
-  ;; like this.
-  (read (concat "("
-		(substring (let ((print-readably t)
-				 (print-gensym
-				  (if (and byte-compile-print-gensym
-					   (not byte-compile-emacs19-compatibility))
-				      '(t) nil))
-				 (print-gensym-alist nil))
-			     (prin1-to-string obj))
-			   2 -1)
-		")")))
-
 (defun byte-compile-file-form-defmumble (form macrop)
   (let* ((name (car (cdr form)))
 	 (this-kind (if macrop 'byte-compile-macro-environment
@@ -2330,7 +2314,14 @@
 	  (byte-compile-warn "Probable `\"' without `\\' in doc string of %s"
 			     (nth 1 form))))
     (let* ((new-one (byte-compile-lambda (cons 'lambda (nthcdr 2 form))))
-	   (code (byte-compile-byte-code-maker new-one)))
+	   (code (byte-compile-byte-code-maker new-one))
+           (docform-info
+            (cond ((atom code) ; compiled-function-p
+                   (if macrop '(" '(macro . #[" 4 "])") '(" #[" 4 "]")))
+                  ((eq (car code) 'quote)
+                   (setq code new-one)
+                   (if macrop '(" '(macro " 2 ")") '(" '(" 2 ")")))
+                  ((if macrop '(" (cons 'macro (" 5 "))") '(" (" 5 ")"))))))
       (if this-one
 	  (setcdr this-one new-one)
 	(set this-kind
@@ -2339,60 +2330,37 @@
 	       (eq 'quote (car-safe code))
 	       (eq 'lambda (car-safe (nth 1 code))))
 	  (cons (car form)
-		(cons name (cdr (nth 1 code))))
+                (cons name (cdr (nth 1 code))))
 	(byte-compile-flush-pending)
 	(if (not (stringp (nth 3 form)))
-	    ;; No doc string.  Provide -1 as the "doc string index"
-	    ;; so that no element will be treated as a doc string.
-	    (byte-compile-output-docform
-	     "\n(defalias '"
-	     name
-	     (cond ((atom code)
-		    (if macrop '(" '(macro . #[" -1 "])") '(" #[" -1 "]")))
-		   ((eq (car code) 'quote)
-		    (setq code new-one)
-		    (if macrop '(" '(macro " -1 ")") '(" '(" -1 ")")))
-		   ((if macrop '(" (cons 'macro (" -1 "))") '(" (" -1 ")"))))
-	     ;; FSF just calls `(append code nil)' here but that relies
-	     ;; on horrible C kludges in concat() that accept byte-
-	     ;; compiled objects and pretend they're vectors.
-	     (if (compiled-function-p code)
-		 (byte-compile-compiled-obj-to-list code)
-	       (append code nil))
-	     (and (atom code) byte-compile-dynamic
-		  1)
-	     nil)
-	  ;; Output the form by hand, that's much simpler than having
-	  ;; b-c-output-file-form analyze the defalias.
-	  (byte-compile-output-docform
-	   "\n(defalias '"
-	   name
-	   (cond ((atom code) ; compiled-function-p
-		  (if macrop '(" '(macro . #[" 4 "])") '(" #[" 4 "]")))
-		 ((eq (car code) 'quote)
-		  (setq code new-one)
-		  (if macrop '(" '(macro " 2 ")") '(" '(" 2 ")")))
-		 ((if macrop '(" (cons 'macro (" 5 "))") '(" (" 5 ")"))))
-	   ;; The result of byte-compile-byte-code-maker is either a
-	   ;; compiled-function object, or a list of some kind.  If it's
-	   ;; not a cons, we must coerce it into a list of the elements
-	   ;; to be printed to the file.
-	   (if (consp code)
-	       code
-	     (nconc (list
-		     (compiled-function-arglist code)
-		     (compiled-function-instructions code)
-		     (compiled-function-constants code)
-		     (compiled-function-stack-depth code))
-		    (let ((doc (documentation code t)))
-		      (if doc (list doc)))
-		    (if (commandp code)
-			(list (nth 1 (compiled-function-interactive code))))))
-	   (and (atom code) byte-compile-dynamic
-		1)
+            ;; No doc string.  Provide -1 as the "doc string index" so that
+            ;; no element will be treated as a doc string by
+            ;; byte-compile-output-doc-form.
+            (setq docform-info (list (first docform-info) -1
+                                     (third docform-info))))
+        (byte-compile-output-docform
+         "\n(defalias '"
+         name
+         docform-info
+         ;; The result of byte-compile-byte-code-maker is either a
+         ;; compiled-function object, or a list of some kind.  If it's not a
+         ;; cons, we must coerce it into a list of the elements to be
+         ;; printed to the file.
+         (if (consp code)
+             code
+           (nconc (list
+                   (compiled-function-arglist code)
+                   (compiled-function-instructions code)
+                   (compiled-function-constants code)
+                   (compiled-function-stack-depth code)
+                   (compiled-function-doc-string code))
+                  (if (commandp code)
+                      (list (nth 1 (compiled-function-interactive code))))))
+         (and (atom code) byte-compile-dynamic
+              1)
 	   nil))
 	(princ ")" byte-compile-outbuffer)
-	nil))))
+	nil)))
 
 ;; Print Lisp object EXP in the output file, inside a comment,
 ;; and return the file position it will have.
--- a/lisp/test-harness.el	Sun Mar 07 02:23:16 2010 -0600
+++ b/lisp/test-harness.el	Sun Mar 07 06:20:19 2010 -0600
@@ -194,6 +194,12 @@
     (kill-buffer input-buffer)
     ))
 
+(defsubst test-harness-backtrace ()
+  "Display a reasonable-size backtrace."
+  (let ((print-escape-newlines t)
+	(print-length 50))
+    (backtrace nil t)))
+
 (defsubst test-harness-assertion-failure-do-debug (error-info)
   "Maybe enter debugger or display a backtrace on assertion failure.
 ERROR-INFO is a cons of the args (SIG . DATA) that were passed to `signal'.
@@ -206,7 +212,7 @@
 		test-harness-assertion-failure-enter-debugger)
 	   (funcall debugger 'error error-info))
 	  (test-harness-assertion-failure-show-backtrace
-	   (backtrace nil t)))))
+	   (test-harness-backtrace)))))
 
 (defsubst test-harness-unexpected-error-do-debug (error-info)
   "Maybe enter debugger or display a backtrace on unexpected error.
@@ -220,7 +226,7 @@
 		test-harness-unexpected-error-enter-debugger)
 	   (funcall debugger 'error error-info))
 	  (test-harness-unexpected-error-show-backtrace
-	   (backtrace nil t)))))
+	   (test-harness-backtrace)))))
 
 (defsubst test-harness-unexpected-error-condition-handler (error-info context-msg)
   "Condition handler for when unexpected errors occur.
--- a/src/ChangeLog	Sun Mar 07 02:23:16 2010 -0600
+++ b/src/ChangeLog	Sun Mar 07 06:20:19 2010 -0600
@@ -1,3 +1,56 @@
+2010-03-06  Ben Wing  <ben@xemacs.org>
+
+	* frame.c (change_frame_size_1):
+	Add a comment about where FRAME_PIXWIDTH/FRAME_PIXHEIGHT is set.
+	
+2010-03-05  Ben Wing  <ben@xemacs.org>
+
+	* frame.c:
+	* frame.c (Fframe_pixel_height):
+	* frame.c (Fframe_displayable_pixel_height):
+	* frame.c (Fframe_pixel_width):
+	* frame.c (Fframe_displayable_pixel_width):
+	* frame.c (Fset_frame_pixel_height):
+	* frame.c (Fset_frame_displayable_pixel_height):
+	* frame.c (Fset_frame_pixel_width):
+	* frame.c (Fset_frame_displayable_pixel_width):
+	* frame.c (get_frame_char_size):
+	* frame.c (change_frame_size_1):
+	Make it so that `frame-pixel-height', `set-frame-pixel-height', etc.
+	use updated values for the displayable or total pixel size that
+	will reflect what will happen as of the next redisplay.  This
+	basically means using the character-cell height and converting
+	on-the-fly to pixel units.  In the process, make sure FRAME_CHARWIDTH/
+	FRAME_CHARHEIGHT are always correct and change
+	get_frame_char_size() to simply use them; the old logic in that
+	function was inlined into change_frame_size_1(), which is the only
+	place that needs the logic.
+
+2010-03-05  Ben Wing  <ben@xemacs.org>
+
+	* frame.c:
+	* frame.c (frame_live_p):
+	* frame.c (Fframep):
+	* frame.c (Fdisable_frame):
+	* frame.c (Fenable_frame):
+	* frame.c (Fraise_frame):
+	* frame.c (Fframe_name):
+	* frame.c (Fset_frame_height):
+	* frame.c (internal_set_frame_size):
+	* frame.c (adjust_frame_size):
+	Add documentation on the different types of units used to measure
+	frame size.
+
+	Add section headers to the various sections.
+	
+	Rearrange the location of some functions in the file to keep
+	related functions together.  This especially goes for frame-sizing
+	functions (internal_set_frame_size() and adjust_frame_size()),
+	which have been moved so that they form a group with
+	change_frame_size() and change_frame_size_1().
+
+	No functionality should change.
+
 2010-03-05  Ben Wing  <ben@xemacs.org>
 
 	* alloc.c:
--- a/src/frame.c	Sun Mar 07 02:23:16 2010 -0600
+++ b/src/frame.c	Sun Mar 07 06:20:19 2010 -0600
@@ -321,6 +321,49 @@
 
 */
 
+/*
+   About different types of units:
+
+   (1) "Total pixels" measure the pixel size of the client area of the
+       frame (everything except the menubars and window-manager decorations;
+       see comment at top of file).
+
+   (2) "Displayable pixels" measure the pixel size of the "displayable area"
+       of the frame, a convenient fiction that specifies which portion of
+       the frame "counts" for the purposes of determining the size of the
+       frame in character cells.  Approximately speaking, the difference
+       between the client area and displayable area is that toolbars,
+       gutters, internal border width and bottom-most/right-most scrollbars
+       are inside the client area but outside the displayable area.  See
+       comment at top of file for more discussion.
+
+   (3) "Character-cell units" measure the frame size in "character cells",
+       which are fixed rectangles of a size meant to correspond with the
+       height and (average) width of the bounding box of a single character
+       in the default font.  The size of a frame in character cells is
+       determined by computing the size in "displayable pixels" and dividing
+       by the pixel size of the default font as instantiated in the frame.
+       See comment at top of file under "displayable area" for more info.
+
+   (4) In window-system "frame units" -- pixels on MS Windows, character
+       cells on X and GTK (on TTY's, pixels and character cells are the
+       same).  Note that on MS Windows the pixels measure the size of the
+       displayable area, not the entire client area.
+
+       This bogosity exists because MS Windows always reports frame sizes
+       in pixels, whereas X-Windows has a scheme whereby character-cell
+       sizes and extra sizes (e.g. for toolbars, menubars, etc.) can be
+       reported to the window manager, and the window manager displays
+       character-cell units when resizing, only allows resizing to integral
+       character-cell sizes, and reports back the size in character cells.
+       As a result, someone thought it was a good idea to make the
+       fundamental units for measuring frame size correspond to what the
+       window system "reports" and hence vary between pixels and character
+       cells, as described above.
+
+  --ben
+*/
+
 #include <config.h>
 #include "lisp.h"
 
@@ -443,8 +486,12 @@
 				       int *dest_width, int *dest_height);
 static void get_frame_char_size (struct frame *f, int *out_width,
 				 int *out_height);
-static void get_frame_displayable_pixel_size (struct frame *f, int *out_width,
-					      int *out_height);
+static void get_frame_new_displayable_pixel_size (struct frame *f,
+						  int *out_width,
+						  int *out_height);
+static void get_frame_new_total_pixel_size (struct frame *f,
+					    int *out_width,
+					    int *out_height);
 
 static struct display_line title_string_display_line;
 /* Used by generate_title_string. Global because they get used so much that
@@ -452,6 +499,11 @@
 static Ichar_dynarr *title_string_ichar_dynarr;
 
 
+/**************************************************************************/
+/*                                                                        */
+/*                              frame object                              */
+/*                                                                        */
+/**************************************************************************/
 
 #ifndef NEW_GC
 extern const struct sized_memory_description gtk_frame_data_description;
@@ -598,6 +650,12 @@
 			   frame_description,
 			   struct frame);
 
+/**************************************************************************/
+/*                                                                        */
+/*                             frame creation                             */
+/*                                                                        */
+/**************************************************************************/
+
 static void
 nuke_all_frame_slots (struct frame *f)
 {
@@ -1034,6 +1092,12 @@
 }
 
 
+/**************************************************************************/
+/*                                                                        */
+/*                      validating a frame argument                       */
+/*                                                                        */
+/**************************************************************************/
+
 /* this function should be used in most cases when a Lisp function is passed
    a FRAME argument.  Use this unless you don't accept nil == current frame
    (in which case, do a CHECK_LIVE_FRAME() and then an XFRAME()) or you
@@ -1066,93 +1130,12 @@
   return decode_frame (cdf);
 }
 
-Lisp_Object
-frame_device (struct frame *f)
-{
-  return FRAME_DEVICE (f);
-}
-
 int
 frame_live_p (struct frame *f)
 {
   return FRAME_LIVE_P (f);
 }
 
-
-void
-invalidate_vertical_divider_cache_in_frame (struct frame *f)
-{
-  /* Invalidate cached value of needs_vertical_divider_p in
-     every and all windows */
-  map_windows (f, invalidate_vertical_divider_cache_in_window, 0);
-}
-
-/*
- * Frame size may change due to changes in scrollbars, toolbars,
- * default font etc. These changes are applied early in redisplay
- * frame.
- */
-void
-adjust_frame_size (struct frame *f)
-{
-  /* This can call Lisp. */
-  int keep_char_size = 0;
-  Lisp_Object frame = wrap_frame (f);
-
-  if (!f->size_slipped)
-    return;
-
-  /* Don't adjust tty frames. #### May break when TTY have menubars.
-     Then, write an Vadjust_frame_function which will return t for TTY
-     frames. Another solution is frame_size_fixed_p method for TTYs,
-     which always returned yes it's fixed.
-  */
-  if (!FRAME_WIN_P (f))
-    {
-      CLEAR_FRAME_SIZE_SLIPPED (f);
-      return;
-    }
-
-  /* frame_size_fixed_p tells that frame size cannot currently
-     be changed change due to external conditions */
-  if (!FRAMEMETH_OR_GIVEN (f, frame_size_fixed_p, (f), 0))
-    {
-      if (NILP (Vadjust_frame_function))
-	keep_char_size = 1;
-      else if (EQ (Vadjust_frame_function, Qt))
-	keep_char_size = 0;
-      else
-	keep_char_size =
-	  NILP (call1_trapping_problems ("Error in adjust-frame-function",
-					 Vadjust_frame_function, frame,
-					 0));
-
-      if (keep_char_size)
-	Fset_frame_size (frame, make_int (FRAME_CHARWIDTH(f)),
-			 make_int (FRAME_CHARHEIGHT(f)), Qnil);
-    }
-
-  if (!keep_char_size)
-    {
-      int height, width;
-      pixel_to_frame_unit_size (f, FRAME_PIXWIDTH(f), FRAME_PIXHEIGHT(f),
-			  &width, &height);
-      change_frame_size (f, width, height, 0);
-      CLEAR_FRAME_SIZE_SLIPPED (f);
-    }
-}
-
-/*
- * This is a "specifier changed in frame" handler for various specifiers
- * changing which causes frame size adjustment
- */
-void
-frame_size_slipped (Lisp_Object UNUSED (specifier), struct frame *f,
-		    Lisp_Object UNUSED (oldval))
-{
-  MARK_FRAME_SIZE_SLIPPED(f);
-}
-
 DEFUN ("framep", Fframep, 1, 1, 0, /*
 Return non-nil if OBJECT is a frame.
 Also see `frame-live-p'.
@@ -1173,6 +1156,27 @@
 }
 
 
+/**************************************************************************/
+/*                                                                        */
+/*                         frame focus/selection                          */
+/*                                                                        */
+/**************************************************************************/
+
+Lisp_Object
+frame_device (struct frame *f)
+{
+  return FRAME_DEVICE (f);
+}
+
+DEFUN ("frame-device", Fframe_device, 0, 1, 0, /*
+Return the device that FRAME is on.
+If omitted, FRAME defaults to the currently selected frame.
+*/
+       (frame))
+{
+  return FRAME_DEVICE (decode_frame (frame));
+}
+
 DEFUN ("focus-frame", Ffocus_frame, 1, 1, 0, /*
 Select FRAME and give it the window system focus.
 This function is not affected by the value of `focus-follows-mouse'.
@@ -1272,6 +1276,9 @@
 
 #if 0 /* FSFmacs */
 
+/* Ben thinks there is no need for `redirect-frame-focus' or `frame-focus',
+   crockish FSFmacs functions.  See summary on focus in event-stream.c. */
+
 DEFUN ("handle-switch-frame", Fhandle_switch_frame, 1, 2, "e", /*
 Handle a switch-frame event EVENT.
 Switch-frame events are usually bound to this function.
@@ -1423,16 +1430,39 @@
   return window;
 }
 
-
-DEFUN ("frame-device", Fframe_device, 0, 1, 0, /*
-Return the device that FRAME is on.
-If omitted, FRAME defaults to the currently selected frame.
+DEFUN ("disable-frame", Fdisable_frame, 1, 1, 0, /*
+Disable frame FRAME, so that it cannot have the focus or receive user input.
+This is normally used during modal dialog boxes.
+WARNING: Be very careful not to wedge XEmacs!
+Use an `unwind-protect' that re-enables the frame to avoid this.
 */
        (frame))
 {
-  return FRAME_DEVICE (decode_frame (frame));
+  struct frame *f = decode_frame (frame);
+
+  f->disabled = 1;
+  MAYBE_FRAMEMETH (f, disable_frame, (f));
+  return Qnil;
 }
 
+DEFUN ("enable-frame", Fenable_frame, 1, 1, 0, /*
+Enable frame FRAME, so that it can have the focus and receive user input.
+Frames are normally enabled, unless explicitly disabled using `disable-frame'.
+*/
+       (frame))
+{
+  struct frame *f = decode_frame (frame);
+  f->disabled = 0;
+  MAYBE_FRAMEMETH (f, enable_frame, (f));
+  return Qnil;
+}
+
+/**************************************************************************/
+/*                                                                        */
+/*                     traversing the list of frames                      */
+/*                                                                        */
+/**************************************************************************/
+
 int
 is_surrogate_for_selected_frame (struct frame *f)
 {
@@ -1725,6 +1755,11 @@
 }
 
 
+/**************************************************************************/
+/*                                                                        */
+/*                             frame deletion                             */
+/*                                                                        */
+/**************************************************************************/
 
 /* extern void free_line_insertion_deletion_costs (struct frame *f); */
 
@@ -2177,6 +2212,12 @@
 }
 
 
+/**************************************************************************/
+/*                                                                        */
+/*                        mouse position in frame                         */
+/*                                                                        */
+/**************************************************************************/
+
 /* Return mouse position in character cell units.  */
 
 static int
@@ -2364,6 +2405,12 @@
   return Qnil;
 }
 
+/**************************************************************************/
+/*                                                                        */
+/*                            frame visibility                            */
+/*                                                                        */
+/**************************************************************************/
+
 DEFUN ("make-frame-visible", Fmake_frame_visible, 0, 1, 0, /*
 Make the frame FRAME visible (assuming it is an X-window).
 If omitted, FRAME defaults to the currently selected frame.
@@ -2526,7 +2573,6 @@
   return value;
 }
 
-
 DEFUN ("raise-frame", Fraise_frame, 0, 1, "", /*
 Bring FRAME to the front, so it occludes any frames it overlaps.
 If omitted, FRAME defaults to the currently selected frame.
@@ -2559,36 +2605,12 @@
 }
 
 
-DEFUN ("disable-frame", Fdisable_frame, 1, 1, 0, /*
-Disable frame FRAME, so that it cannot have the focus or receive user input.
-This is normally used during modal dialog boxes.
-WARNING: Be very careful not to wedge XEmacs!
-Use an `unwind-protect' that re-enables the frame to avoid this.
-*/
-       (frame))
-{
-  struct frame *f = decode_frame (frame);
-
-  f->disabled = 1;
-  MAYBE_FRAMEMETH (f, disable_frame, (f));
-  return Qnil;
-}
-
-DEFUN ("enable-frame", Fenable_frame, 1, 1, 0, /*
-Enable frame FRAME, so that it can have the focus and receive user input.
-Frames are normally enabled, unless explicitly disabled using `disable-frame'.
-*/
-       (frame))
-{
-  struct frame *f = decode_frame (frame);
-  f->disabled = 0;
-  MAYBE_FRAMEMETH (f, enable_frame, (f));
-  return Qnil;
-}
-
-/* Ben thinks there is no need for `redirect-frame-focus' or `frame-focus',
-   crockish FSFmacs functions.  See summary on focus in event-stream.c. */
-
+/***************************************************************************/
+/*                                                                         */
+/*                           print-related functions                       */
+/*                                                                         */
+/***************************************************************************/
+
 DEFUN ("print-job-page-number", Fprint_job_page_number, 1, 1, 0, /*
 Return current page number for the print job FRAME.
 */
@@ -2616,9 +2638,34 @@
 
 
 /***************************************************************************/
+/*                                                                         */
 /*                           frame properties                              */
+/*                                                                         */
 /***************************************************************************/
 
+DEFUN ("frame-name", Fframe_name, 0, 1, 0, /*
+Return the name of FRAME (defaulting to the selected frame).
+This is not the same as the `title' of the frame.
+*/
+       (frame))
+{
+  return decode_frame (frame)->name;
+}
+
+DEFUN ("frame-modified-tick", Fframe_modified_tick, 0, 1, 0, /*
+Return FRAME's tick counter, incremented for each change to the frame.
+Each frame has a tick counter which is incremented each time the frame
+is resized, a window is resized, added, or deleted, a face is changed,
+`set-window-buffer' or `select-window' is called on a window in the
+frame, the window-start of a window in the frame has changed, or
+anything else interesting has happened.  It wraps around occasionally.
+No argument or nil as argument means use selected frame as FRAME.
+*/
+       (frame))
+{
+  return make_int (decode_frame (frame)->modiff);
+}
+
 static void
 store_minibuf_frame_prop (struct frame *f, Lisp_Object val)
 {
@@ -3019,12 +3066,22 @@
 }
 
 
+/**************************************************************************/
+/*                                                                        */
+/*                     frame sizing (user functions)                      */
+/*                                                                        */
+/**************************************************************************/
+
 DEFUN ("frame-pixel-height", Fframe_pixel_height, 0, 1, 0, /*
 Return the total height in pixels of FRAME.
 */
        (frame))
 {
-  return make_int (decode_frame (frame)->pixheight);
+  struct frame *f = decode_frame (frame);
+  int width, height;
+
+  get_frame_new_total_pixel_size (f, &width, &height);
+  return make_int (height);
 }
 
 DEFUN ("frame-displayable-pixel-height", Fframe_displayable_pixel_height, 0, 1, 0, /*
@@ -3035,7 +3092,7 @@
   struct frame *f = decode_frame (frame);
   int width, height;
 
-  get_frame_displayable_pixel_size (f, &width, &height);
+  get_frame_new_displayable_pixel_size (f, &width, &height);
   return make_int (height);
 }
 
@@ -3044,7 +3101,11 @@
 */
        (frame))
 {
-  return make_int (decode_frame (frame)->pixwidth);
+  struct frame *f = decode_frame (frame);
+  int width, height;
+
+  get_frame_new_total_pixel_size (f, &width, &height);
+  return make_int (width);
 }
 
 DEFUN ("frame-displayable-pixel-width", Fframe_displayable_pixel_width, 0, 1, 0, /*
@@ -3055,46 +3116,10 @@
   struct frame *f = decode_frame (frame);
   int width, height;
 
-  get_frame_displayable_pixel_size (f, &width, &height);
+  get_frame_new_displayable_pixel_size (f, &width, &height);
   return make_int (width);
 }
 
-DEFUN ("frame-name", Fframe_name, 0, 1, 0, /*
-Return the name of FRAME (defaulting to the selected frame).
-This is not the same as the `title' of the frame.
-*/
-       (frame))
-{
-  return decode_frame (frame)->name;
-}
-
-DEFUN ("frame-modified-tick", Fframe_modified_tick, 0, 1, 0, /*
-Return FRAME's tick counter, incremented for each change to the frame.
-Each frame has a tick counter which is incremented each time the frame
-is resized, a window is resized, added, or deleted, a face is changed,
-`set-window-buffer' or `select-window' is called on a window in the
-frame, the window-start of a window in the frame has changed, or
-anything else interesting has happened.  It wraps around occasionally.
-No argument or nil as argument means use selected frame as FRAME.
-*/
-       (frame))
-{
-  return make_int (decode_frame (frame)->modiff);
-}
-
-void
-internal_set_frame_size (struct frame *f, int cols, int rows, int pretend)
-{
-  /* This can call Lisp.  See mswindows_set_frame_size(). */
-  /* An explicit size change cancels any pending frame size adjustment */
-  CLEAR_FRAME_SIZE_SLIPPED (f);
-
-  if (pretend || !HAS_FRAMEMETH_P (f, set_frame_size))
-    change_frame_size (f, cols, rows, 0);
-  else
-    FRAMEMETH (f, set_frame_size, (f, cols, rows));
-}
-
 DEFUN ("set-frame-height", Fset_frame_height, 2, 3, 0, /*
 Specify that the frame FRAME has LINES lines.
 Optional third arg non-nil means that redisplay should use LINES lines
@@ -3129,8 +3154,8 @@
   int guwidth, guheight;
 
   CHECK_INT (height);
+  get_frame_new_total_pixel_size (f, &pwidth, &pheight);
   pheight = XINT (height);
-  pwidth = FRAME_PIXWIDTH (f);
   frame_conversion_internal (f, SIZE_TOTAL_PIXEL, pwidth, pheight,
 			     SIZE_FRAME_UNIT, &guwidth, &guheight);
   internal_set_frame_size (f, guwidth, guheight, !NILP (pretend));
@@ -3150,7 +3175,7 @@
   int guwidth, guheight;
 
   CHECK_INT (height);
-  get_frame_displayable_pixel_size (f, &pwidth, &pheight);
+  get_frame_new_displayable_pixel_size (f, &pwidth, &pheight);
   pheight = XINT (height);
   frame_conversion_internal (f, SIZE_DISPLAYABLE_PIXEL, pwidth, pheight,
 			     SIZE_FRAME_UNIT, &guwidth, &guheight);
@@ -3193,8 +3218,8 @@
   int guwidth, guheight;
 
   CHECK_INT (width);
+  get_frame_new_total_pixel_size (f, &pwidth, &pheight);
   pwidth = XINT (width);
-  pheight = FRAME_PIXHEIGHT (f);
   frame_conversion_internal (f, SIZE_TOTAL_PIXEL, pwidth, pheight,
 			     SIZE_FRAME_UNIT, &guwidth, &guheight);
   internal_set_frame_size (f, guwidth, guheight, !NILP (pretend));
@@ -3214,7 +3239,7 @@
   int guwidth, guheight;
 
   CHECK_INT (width);
-  get_frame_displayable_pixel_size (f, &pwidth, &pheight);
+  get_frame_new_displayable_pixel_size (f, &pwidth, &pheight);
   pwidth = XINT (width);
   frame_conversion_internal (f, SIZE_DISPLAYABLE_PIXEL, pwidth, pheight,
 			     SIZE_FRAME_UNIT, &guwidth, &guheight);
@@ -3298,6 +3323,11 @@
 }
 
 
+/**************************************************************************/
+/*                                                                        */
+/*                various ways of measuring the frame size                */
+/*                                                                        */
+/**************************************************************************/
 
 /* Frame size conversion functions moved here from EmacsFrame.c
    because they're generic and really don't belong in that file.
@@ -3305,9 +3335,13 @@
    exactly the same as default_face_width_and_height().
 
    Convert between total pixel size, displayable pixel size and
-   character-cell size.  Variables are either "in" or "out"
-   depending on the value of PIXEL_TO_CHAR.
-*/
+   character-cell size.  Variables are either "in", "out" or unused,
+   depending on the value of PIXEL_TO_CHAR, which indicates which units the
+   source and destination values are measured in.
+
+   See frame_conversion_internal() for a discussion of the different
+   types of units. */
+
 static void
 frame_conversion_internal_1 (struct frame *f,
 			     pixel_to_char_mode_t pixel_to_char,
@@ -3412,7 +3446,10 @@
 
 /* Basic frame conversion function.  Convert source size to destination
    size, where either of them can be in total pixels, displayable pixels,
-   frame units or character-cell units. */
+   frame units or character-cell units.
+
+   See comment at top of file for discussion about different types of
+   units. */
 
 static void
 frame_conversion_internal (struct frame *f,
@@ -3534,41 +3571,49 @@
   char_to_pixel_size (f, char_width, char_height, out_width, out_height);
 }
 
-/* Get the frame size in character cells, recalculating on the fly.
-   #### The logic of this function follows former logic elsewhere,
-   which used FRAME_PIXWIDTH() on pixelated-geometry systems but
-   FRAME_WIDTH() on non-pixelated-geometry systems.  Not clear why not
-   always just use one or the other.
-
-   Why don't we just use FRAME_CHARWIDTH() etc. in get_frame_char_size()?
-   That wouldn't work because change_frame_size_1() depends on the
-   following function to *set* the values of FRAME_CHARWIDTH() etc.
-
-   But elsewhere I suppose we could use it.
-*/
-
 static void
 get_frame_char_size (struct frame *f, int *out_width, int *out_height)
 {
-  if (window_system_pixelated_geometry (wrap_frame (f)))
-    pixel_to_char_size (f, FRAME_PIXWIDTH (f), FRAME_PIXHEIGHT (f),
-			out_width, out_height);
-  else
-    {
-      *out_width = FRAME_WIDTH (f);
-      *out_height = FRAME_HEIGHT (f);
-    }
+  *out_width = FRAME_CHARWIDTH (f);
+  *out_height = FRAME_CHARHEIGHT (f);
 }
 
+/* Return the "new" frame size in displayable pixels, which will be
+   accurate as of next redisplay.  If we have changed the default font or
+   toolbar or scrollbar specifiers, the frame pixel size will change as of
+   next redisplay, but the frame character-cell size will remain the same.
+   So use those dimensions to compute the displayable-pixel size. */
+
 static void
-get_frame_displayable_pixel_size (struct frame *f, int *out_width,
-				  int *out_height)
+get_frame_new_displayable_pixel_size (struct frame *f, int *out_width,
+				      int *out_height)
 {
-  frame_conversion_internal (f, SIZE_FRAME_UNIT, FRAME_WIDTH (f),
-			     FRAME_HEIGHT (f), SIZE_DISPLAYABLE_PIXEL,
+  frame_conversion_internal (f, SIZE_CHAR_CELL, FRAME_CHARWIDTH (f),
+			     FRAME_CHARHEIGHT (f), SIZE_DISPLAYABLE_PIXEL,
 			     out_width, out_height);
 }
 
+/* Return the "new" frame size in total pixels, which will be
+   accurate as of next redisplay.  See get_frame_new_displayable_pixel_size().
+*/
+
+
+static void
+get_frame_new_total_pixel_size (struct frame *f, int *out_width,
+				int *out_height)
+{
+  frame_conversion_internal (f, SIZE_CHAR_CELL, FRAME_CHARWIDTH (f),
+			     FRAME_CHARHEIGHT (f), SIZE_TOTAL_PIXEL,
+			     out_width, out_height);
+}
+
+
+/**************************************************************************/
+/*                                                                        */
+/*                    frame resizing (implementation)                     */
+/*                                                                        */
+/**************************************************************************/
+
 /* Change the frame height and/or width.  Values passed in are in
    frame units (character cells on X/GTK, displayable-area pixels
    on MS Windows or generally on pixelated-geometry window systems). */
@@ -3576,6 +3621,7 @@
 change_frame_size_1 (struct frame *f, int newwidth, int newheight)
 {
   int new_pixheight, new_pixwidth;
+  int paned_pixheight, paned_pixwidth;
   int real_font_height, real_font_width;
 
   /* #### Chuck -- shouldn't we be checking to see if the frame
@@ -3604,9 +3650,9 @@
   /* We need to remove the boundaries of the paned area (see top of file)
      from the total-area pixel size, which is what we have now.
   */
-  new_pixheight -=
+  paned_pixheight = new_pixheight -
     (FRAME_NONPANED_SIZE (f, TOP_EDGE) + FRAME_NONPANED_SIZE (f, BOTTOM_EDGE));
-  new_pixwidth -=
+  paned_pixwidth = new_pixwidth -
     (FRAME_NONPANED_SIZE (f, LEFT_EDGE) + FRAME_NONPANED_SIZE (f, RIGHT_EDGE));
 
   XWINDOW (FRAME_ROOT_WINDOW (f))->pixel_top = FRAME_PANED_TOP_EDGE (f);
@@ -3625,51 +3671,69 @@
        * other frame size changes, which seems reasonable.
        */
       int old_minibuf_height =
-	XWINDOW(FRAME_MINIBUF_WINDOW(f))->pixel_height;
+	XWINDOW (FRAME_MINIBUF_WINDOW (f))->pixel_height;
       int minibuf_height =
 	f->init_finished && (old_minibuf_height % real_font_height) == 0 ?
-	max(old_minibuf_height, real_font_height) :
+	max (old_minibuf_height, real_font_height) :
 	real_font_height;
       set_window_pixheight (FRAME_ROOT_WINDOW (f),
 			    /* - font_height for minibuffer */
-			    new_pixheight - minibuf_height, 0);
+			    paned_pixheight - minibuf_height, 0);
 
       XWINDOW (FRAME_MINIBUF_WINDOW (f))->pixel_top =
 	FRAME_PANED_TOP_EDGE (f) +
 	FRAME_BOTTOM_GUTTER_BOUNDS (f) +
-	new_pixheight - minibuf_height;
+	paned_pixheight - minibuf_height;
 
       set_window_pixheight (FRAME_MINIBUF_WINDOW (f), minibuf_height, 0);
     }
   else
     /* Frame has just one top-level window.  */
-    set_window_pixheight (FRAME_ROOT_WINDOW (f), new_pixheight, 0);
+    set_window_pixheight (FRAME_ROOT_WINDOW (f), paned_pixheight, 0);
+
+  /* Set the value of FRAME_WIDTH/FRAME_HEIGHT and
+     FRAME_CHARWIDTH/FRAME_CHARHEIGHT.
+
+     Question: Where is FRAME_PIXWIDTH/FRAME_PIXHEIGHT set?
+     Answer: In the device-specific code, as a result of a callback from
+     the window system indicating that the frame has changed size.
+     This happens:
+
+     (1) in the WM_SIZE processing in event-msw.c
+     (2) in update_various_frame_slots() called from EmacsFrameResize()
+         (called from Xt when the frame is resized) in EmacsFrame.c for X
+     (3) in resize_event_cb() in frame-gtk.c
+     (4) For TTY's, there is no such callback, so we have to set it
+         ourselves.
+  */
 
   FRAME_HEIGHT (f) = newheight;
   if (FRAME_TTY_P (f))
     f->pixheight = newheight;
 
   XWINDOW (FRAME_ROOT_WINDOW (f))->pixel_left = FRAME_PANED_LEFT_EDGE (f);
-  set_window_pixwidth (FRAME_ROOT_WINDOW (f), new_pixwidth, 0);
+  set_window_pixwidth (FRAME_ROOT_WINDOW (f), paned_pixwidth, 0);
 
   if (FRAME_HAS_MINIBUF_P (f))
     {
       XWINDOW (FRAME_MINIBUF_WINDOW (f))->pixel_left =
 	FRAME_PANED_LEFT_EDGE (f);
-      set_window_pixwidth (FRAME_MINIBUF_WINDOW (f), new_pixwidth, 0);
+      set_window_pixwidth (FRAME_MINIBUF_WINDOW (f), paned_pixwidth, 0);
     }
 
   FRAME_WIDTH (f) = newwidth;
   if (FRAME_TTY_P (f))
     f->pixwidth = newwidth;
 
-  /* #### On MS Windows, this references FRAME_PIXWIDTH() and
-     FRAME_PIXHEIGHT().  I'm not sure we can count on those values being
-     set.  Instead we should use the total pixel size we got near the top
-     by calling frame_conversion_internal().  We should inline the logic in
-     get_frame_char_size() here and change that function so it just looks
-     at FRAME_CHARWIDTH() and FRAME_CHARHEIGHT(). */
-  get_frame_char_size (f, &FRAME_CHARWIDTH (f), &FRAME_CHARHEIGHT (f));
+  /* Set the frame character-cell width appropriately. */
+  if (window_system_pixelated_geometry (wrap_frame (f)))
+    pixel_to_char_size (f, new_pixwidth, new_pixheight,
+			&FRAME_CHARWIDTH (f), &FRAME_CHARHEIGHT (f));
+  else
+    {
+      FRAME_CHARWIDTH (f) = FRAME_WIDTH (f);
+      FRAME_CHARHEIGHT (f) = FRAME_HEIGHT (f);
+    }
 
   MARK_FRAME_TOOLBARS_CHANGED (f);
   MARK_FRAME_GUTTERS_CHANGED (f);
@@ -3677,6 +3741,23 @@
   f->echo_area_garbaged = 1;
 }
 
+/* This function is called to change the redisplay structures of a frame
+   to correspond to a new width and height.  IT DOES NOT CHANGE THE ACTUAL
+   SIZE OF A FRAME.  It is meant to be called after the frame has been
+   resized, either as a result of user action or a call to a function
+   such as `set-frame-size'.  For example, under MS-Windows it is called
+   from mswindows_wnd_proc() when a WM_SIZE message is received, indicating
+   that the user resized the frame, and from mswindows_set_frame_size(),
+   which is the device method that is called (from internal_set_frame_size())
+   when `set-frame-size' or similar function is called.
+
+   Values passed in are in frame units (character cells on X/GTK,
+   displayable-area pixels on MS Windows or generally on pixelated-geometry
+   window systems).  See discussion at top of file.
+
+   See also internal_set_frame_size() and adjust_frame_size().
+*/
+
 void
 change_frame_size (struct frame *f, int newwidth, int newheight, int delay)
 {
@@ -3716,7 +3797,147 @@
     change_frame_size_1 (f, newwidth, newheight);
 }
 
+
+/* This function is called from `set-frame-size' or the like, to explicitly
+   change the size of a frame.  It calls the `set_frame_size' device
+   method, which makes the necessary window-system-specific call to change
+   the size of the frame and then calls change_frame_size() to change
+   the redisplay structures appropriately.
+
+   Values passed in are in frame units (character cells on X/GTK,
+   displayable-area pixels on MS Windows or generally on pixelated-geometry
+   window systems).  See discussion at top of file.
+ */
+
+void
+internal_set_frame_size (struct frame *f, int cols, int rows, int pretend)
+{
+  /* This can call Lisp.  See mswindows_set_frame_size(). */
+  /* An explicit size change cancels any pending frame size adjustment */
+  CLEAR_FRAME_SIZE_SLIPPED (f);
+
+  if (pretend || !HAS_FRAMEMETH_P (f, set_frame_size))
+    change_frame_size (f, cols, rows, 0);
+  else
+    FRAMEMETH (f, set_frame_size, (f, cols, rows));
+}
+
+/* This function is called from redisplay_frame() as a result of the
+   "frame_slipped" flag being set.  This flag is set when the default font
+   changes or when a change to scrollbar or toolbar visibility or size
+   is made (e.g. when a specifier such as `scrollbar-width' is changed).
+   Its purpose is to resize the frame so that its size in character-cell
+   units stays the same.
+
+   #### It should also be triggered by a change the gutter visibility or
+   size.
+
+   When a scrollbar or toolbar specifier is changed, the
+   frame_size_slipped() function is called (this happens because the
+   specifier's value_changed_in_frame() hook has been set to
+   frame_size_slipped() by a call to set_specifier_caching()).
+   All this does is call MARK_FRAME_SIZE_SLIPPED(), which sets the
+   frame_slipped flag, which gets noticed by redisplay_frame(), as just
+   discussed.
+
+   The way things get triggered when a change is made to the default font
+   is as follows:
+
+   (1) The specifier for the default font, which is attached to the
+       face named `default', has its "face" property set to the `default'
+       face.
+
+   (2) font_after_change() (the font specifier's after_changed() method)
+       is called for the font specifier.
+
+
+   (3) It in turn calls face_property_was_changed(), passing in the
+       default face.
+
+   (4) face_property_was_changed() notices that the default face is having
+       a property set and calls update_EmacsFrame().
+
+   (5) This in turn notices that the default face's font is being changed
+       and calls MARK_FRAME_SIZE_SLIPPED() -- see above.
+ */
+
+void
+adjust_frame_size (struct frame *f)
+{
+  /* This can call Lisp. */
+  int keep_char_size = 0;
+  Lisp_Object frame = wrap_frame (f);
+
+  if (!f->size_slipped)
+    return;
+
+  /* Don't adjust tty frames. #### May break when TTY have menubars.
+     Then, write an Vadjust_frame_function which will return t for TTY
+     frames. Another solution is frame_size_fixed_p method for TTYs,
+     which always returned yes it's fixed.
+  */
+  if (!FRAME_WIN_P (f))
+    {
+      CLEAR_FRAME_SIZE_SLIPPED (f);
+      return;
+    }
+
+  /* frame_size_fixed_p tells that frame size cannot currently
+     be changed change due to external conditions */
+  if (!FRAMEMETH_OR_GIVEN (f, frame_size_fixed_p, (f), 0))
+    {
+      if (NILP (Vadjust_frame_function))
+	keep_char_size = 1;
+      else if (EQ (Vadjust_frame_function, Qt))
+	keep_char_size = 0;
+      else
+	keep_char_size =
+	  NILP (call1_trapping_problems ("Error in adjust-frame-function",
+					 Vadjust_frame_function, frame,
+					 0));
+
+      if (keep_char_size)
+	Fset_frame_size (frame, make_int (FRAME_CHARWIDTH(f)),
+			 make_int (FRAME_CHARHEIGHT(f)), Qnil);
+    }
+
+  if (!keep_char_size)
+    {
+      int height, width;
+      pixel_to_frame_unit_size (f, FRAME_PIXWIDTH(f), FRAME_PIXHEIGHT(f),
+			  &width, &height);
+      change_frame_size (f, width, height, 0);
+      CLEAR_FRAME_SIZE_SLIPPED (f);
+    }
+}
+
+/* This is a "specifier changed in frame" handler for various specifiers
+   changing which causes frame size adjustment.  See the discussion in
+   adjust_frame_size().
+ */
+
+void
+frame_size_slipped (Lisp_Object UNUSED (specifier), struct frame *f,
+		    Lisp_Object UNUSED (oldval))
+{
+  MARK_FRAME_SIZE_SLIPPED (f);
+}
+
+void
+invalidate_vertical_divider_cache_in_frame (struct frame *f)
+{
+  /* Invalidate cached value of needs_vertical_divider_p in
+     every and all windows */
+  map_windows (f, invalidate_vertical_divider_cache_in_window, 0);
+}
+
 
+/**************************************************************************/
+/*                                                                        */
+/*                       frame title, icon, pointer                       */
+/*                                                                        */
+/**************************************************************************/
+
 /* The caller is responsible for freeing the returned string. */
 static Ibyte *
 generate_title_string (struct window *w, Lisp_Object format_str,
--- a/tests/ChangeLog	Sun Mar 07 02:23:16 2010 -0600
+++ b/tests/ChangeLog	Sun Mar 07 06:20:19 2010 -0600
@@ -1,3 +1,9 @@
+2010-03-07  Stephen J. Turnbull  <stephen@xemacs.org>
+
+	* automated/mule-tests.el (string character conversion):
+	Test escape-quoted for the range U+0000 to U+00FF.
+	Inspired by Ben's patch to fix quoting of specials from C1 controls.
+
 2010-02-22  Ben Wing  <ben@xemacs.org>
 
 	* automated/syntax-tests.el:
--- a/tests/automated/mule-tests.el	Sun Mar 07 02:23:16 2010 -0600
+++ b/tests/automated/mule-tests.el	Sun Mar 07 06:20:19 2010 -0600
@@ -375,6 +375,29 @@
       (Assert-equal (substring string (* 94 k) (* 94 (1+ k))) ascii-string)))
 
   ;;---------------------------------------------------------------
+  ;; Test string character conversion
+  ;;---------------------------------------------------------------
+
+  ;; #### This should test all coding systems!
+
+  (let ((all-octets (let ((s (make-string 256 ?\000)))
+		      (loop for i from (1- (length s)) downto 0 do
+			(aset s i (int-char i)))
+		      s))
+	(escape-quoted-result (let ((schar '(27 155 142 143 14 15))
+				    (s (make-string 262 ?\000))
+				    (pos 0))
+				(loop for ord from 0 to 255 do
+				  (when (member ord schar)
+				    (aset s pos ?\033)
+				    (incf pos))
+				  (aset s pos (int-char ord))
+				  (incf pos))
+				s)))
+    (Assert (string= (encode-coding-string all-octets 'escape-quoted)
+		     escape-quoted-result)))
+
+  ;;---------------------------------------------------------------
   ;; Test file-system character conversion (and, en passant, file ops)
   ;;---------------------------------------------------------------
   (let* ((dstroke (make-char 'latin-iso8859-2 80))