changeset 5104:868a5349acee

add documentation to frame.c, rearrange some functions to consolidate in related areas -------------------- ChangeLog entries follow: -------------------- src/ChangeLog addition: 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.
author Ben Wing <ben@xemacs.org>
date Fri, 05 Mar 2010 22:50:27 -0600
parents 4129013a3954
children d76a51b29d91
files src/ChangeLog src/frame.c
diffstat 2 files changed, 371 insertions(+), 157 deletions(-) [+]
line wrap: on
line diff
--- a/src/ChangeLog	Fri Mar 05 17:51:36 2010 -0600
+++ b/src/ChangeLog	Fri Mar 05 22:50:27 2010 -0600
@@ -1,3 +1,28 @@
+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>
 
 	* mule-coding.c:
--- a/src/frame.c	Fri Mar 05 17:51:36 2010 -0600
+++ b/src/frame.c	Fri Mar 05 22:50:27 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"
 
@@ -452,6 +495,11 @@
 static Ichar_dynarr *title_string_ichar_dynarr;
 
 
+/**************************************************************************/
+/*                                                                        */
+/*                              frame object                              */
+/*                                                                        */
+/**************************************************************************/
 
 #ifndef NEW_GC
 extern const struct sized_memory_description gtk_frame_data_description;
@@ -602,6 +650,12 @@
 			       frame_description,
 			       struct frame);
 
+/**************************************************************************/
+/*                                                                        */
+/*                             frame creation                             */
+/*                                                                        */
+/**************************************************************************/
+
 static void
 nuke_all_frame_slots (struct frame *f)
 {
@@ -1039,6 +1093,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
@@ -1071,93 +1131,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'.
@@ -1178,6 +1157,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'.
@@ -1277,6 +1277,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.
@@ -1428,16 +1431,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)
 {
@@ -1730,6 +1756,11 @@
 }
 
 
+/**************************************************************************/
+/*                                                                        */
+/*                             frame deletion                             */
+/*                                                                        */
+/**************************************************************************/
 
 /* extern void free_line_insertion_deletion_costs (struct frame *f); */
 
@@ -2182,6 +2213,12 @@
 }
 
 
+/**************************************************************************/
+/*                                                                        */
+/*                        mouse position in frame                         */
+/*                                                                        */
+/**************************************************************************/
+
 /* Return mouse position in character cell units.  */
 
 static int
@@ -2369,6 +2406,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.
@@ -2531,7 +2574,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.
@@ -2564,36 +2606,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.
 */
@@ -2621,9 +2639,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)
 {
@@ -3024,6 +3067,12 @@
 }
 
 
+/**************************************************************************/
+/*                                                                        */
+/*                     frame sizing (user functions)                      */
+/*                                                                        */
+/**************************************************************************/
+
 DEFUN ("frame-pixel-height", Fframe_pixel_height, 0, 1, 0, /*
 Return the total height in pixels of FRAME.
 */
@@ -3064,42 +3113,6 @@
   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
@@ -3303,6 +3316,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.
@@ -3310,9 +3328,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,
@@ -3417,7 +3439,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,
@@ -3574,6 +3599,13 @@
 			     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). */
@@ -3682,6 +3714,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)
 {
@@ -3721,7 +3770,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,