use dynwind_begin and dynwind_end
[bpt/emacs.git] / src / dispnew.c
index c3cca33..5c6a43c 100644 (file)
@@ -92,7 +92,7 @@ static void check_matrix_pointers (struct glyph_matrix *,
 static void mirror_line_dance (struct window *, int, int, int *, char *);
 static bool update_window_tree (struct window *, bool);
 static bool update_window (struct window *, bool);
-static bool update_frame_1 (struct frame *, bool, bool);
+static bool update_frame_1 (struct frame *, bool, bool, bool);
 static bool scrolling (struct frame *);
 static void set_window_cursor_after_update (struct window *);
 static void adjust_frame_glyphs_for_window_redisplay (struct frame *);
@@ -2055,7 +2055,8 @@ adjust_frame_glyphs_for_window_redisplay (struct frame *f)
     w->left_col = 0;
     w->pixel_top = 0;
     w->top_line = 0;
-    w->pixel_width = FRAME_PIXEL_WIDTH (f);
+    w->pixel_width = (FRAME_PIXEL_WIDTH (f)
+                     - 2 * FRAME_INTERNAL_BORDER_WIDTH (f));
     w->total_cols = FRAME_TOTAL_COLS (f);
     w->pixel_height = FRAME_MENU_BAR_HEIGHT (f);
     w->total_lines = FRAME_MENU_BAR_LINES (f);
@@ -3069,7 +3070,7 @@ update_frame (struct frame *f, bool force_p, bool inhibit_hairy_id_p)
 
       /* Update the display  */
       update_begin (f);
-      paused_p = update_frame_1 (f, force_p, inhibit_hairy_id_p);
+      paused_p = update_frame_1 (f, force_p, inhibit_hairy_id_p, 1);
       update_end (f);
 
       if (FRAME_TERMCAP_P (f) || FRAME_MSDOS_P (f))
@@ -3099,12 +3100,17 @@ update_frame (struct frame *f, bool force_p, bool inhibit_hairy_id_p)
    glyphs.  This is like the second part of update_frame, but it
    doesn't call build_frame_matrix, because we already have the
    desired matrix prepared, and don't want it to be overwritten by the
-   text of the normal display.  */
+   text of the normal display.
+
+   ROW and COL, if non-negative, are the row and column of the TTY
+   frame where to position the cursor after the frame update is
+   complete.  Negative values mean ask update_frame_1 to position the
+   cursor "normally", i.e. at point in the selected window.  */
 void
-update_frame_with_menu (struct frame *f)
+update_frame_with_menu (struct frame *f, int row, int col)
 {
   struct window *root_window = XWINDOW (f->root_window);
-  bool paused_p;
+  bool paused_p, cursor_at_point_p;
 
   eassert (FRAME_TERMCAP_P (f));
 
@@ -3114,9 +3120,14 @@ update_frame_with_menu (struct frame *f)
 
   /* Update the display.  */
   update_begin (f);
+  cursor_at_point_p = !(row >= 0 && col >= 0);
   /* Force update_frame_1 not to stop due to pending input, and not
      try scrolling.  */
-  paused_p = update_frame_1 (f, 1, 1);
+  paused_p = update_frame_1 (f, 1, 1, cursor_at_point_p);
+  /* ROW and COL tell us where in the menu to position the cursor, so
+     that screen readers know the active region on the screen.  */
+  if (!cursor_at_point_p)
+    cursor_to (f, row, col);
   update_end (f);
 
   if (FRAME_TTY (f)->termscript)
@@ -3131,12 +3142,11 @@ update_frame_with_menu (struct frame *f)
   check_window_matrix_pointers (root_window);
 #endif
   add_frame_display_history (f, paused_p);
-#else
-  IF_LINT ((void) paused_p);
 #endif
 
   /* Reset flags indicating that a window should be updated.  */
   set_window_update_flags (root_window, false);
+  display_completed = !paused_p;
 }
 
 \f
@@ -4413,12 +4423,14 @@ scrolling_window (struct window *w, bool header_line_p)
 /* Update the desired frame matrix of frame F.
 
    FORCE_P means that the update should not be stopped by pending input.
-   INHIBIT_HAIRY_ID_P means that scrolling should not be tried.
+   INHIBIT_ID_P means that scrolling by insert/delete should not be tried.
+   SET_CURSOR_P false means do not set cursor at point in selected window.
 
    Value is true if update was stopped due to pending input.  */
 
 static bool
-update_frame_1 (struct frame *f, bool force_p, bool inhibit_id_p)
+update_frame_1 (struct frame *f, bool force_p, bool inhibit_id_p,
+               bool set_cursor_p)
 {
   /* Frame matrices to work on.  */
   struct glyph_matrix *current_matrix = f->current_matrix;
@@ -4490,7 +4502,7 @@ update_frame_1 (struct frame *f, bool force_p, bool inhibit_id_p)
   pause_p = 0 < i && i < FRAME_LINES (f) - 1;
 
   /* Now just clean up termcap drivers and set cursor, etc.  */
-  if (!pause_p)
+  if (!pause_p && set_cursor_p)
     {
       if ((cursor_in_echo_area
           /* If we are showing a message instead of the mini-buffer,
@@ -5465,7 +5477,7 @@ change_frame_size_1 (struct frame *f, int new_width, int new_height,
   int new_text_width, new_text_height, new_root_width;
   int old_root_width = WINDOW_PIXEL_WIDTH (XWINDOW (FRAME_ROOT_WINDOW (f)));
   int new_cols, new_lines;
-  ptrdiff_t count = SPECPDL_INDEX ();
+  dynwind_begin ();
 
   /* If we can't deal with the change now, queue it for later.  */
   if (delay || (redisplaying_p && !safe))
@@ -5474,6 +5486,7 @@ change_frame_size_1 (struct frame *f, int new_width, int new_height,
       f->new_height = new_height;
       f->new_pixelwise = pixelwise;
       delayed_size_change = 1;
+      dynwind_end ();
       return;
     }
 
@@ -5515,8 +5528,15 @@ change_frame_size_1 (struct frame *f, int new_width, int new_height,
      example, fullscreen and remove/add scroll bar.  */
   if (new_text_height == FRAME_TEXT_HEIGHT (f)
       && new_text_width == FRAME_TEXT_WIDTH (f)
-      && new_root_width == old_root_width)
-    return;
+      && new_root_width == old_root_width
+      && (FRAME_PIXEL_HEIGHT (f) ==
+         FRAME_TEXT_TO_PIXEL_HEIGHT (f, new_text_height))
+      && (FRAME_PIXEL_WIDTH (f) ==
+         FRAME_TEXT_TO_PIXEL_WIDTH (f, new_text_width)))
+    {
+      dynwind_end ();
+      return;
+    }
 
   block_input ();
 
@@ -5534,7 +5554,7 @@ change_frame_size_1 (struct frame *f, int new_width, int new_height,
       /* MSDOS frames cannot PRETEND, as they change frame size by
         manipulating video hardware.  */
       if ((FRAME_TERMCAP_P (f) && !pretend) || FRAME_MSDOS_P (f))
-       FrameRows (FRAME_TTY (f)) = new_height;
+       FrameRows (FRAME_TTY (f)) = new_lines;
     }
 
   if (new_text_width != FRAME_TEXT_WIDTH (f)
@@ -5586,7 +5606,7 @@ change_frame_size_1 (struct frame *f, int new_width, int new_height,
 
   run_window_configuration_change_hook (f);
 
-  unbind_to (count, Qnil);
+  dynwind_end ();
 }
 \f
 /***********************************************************************
@@ -5823,11 +5843,11 @@ immediately by pending input.  */)
       || !NILP (Vexecuting_kbd_macro))
     return Qnil;
 
-  count = SPECPDL_INDEX ();
+  dynwind_begin ();
   if (!NILP (force) && !redisplay_dont_pause)
     specbind (Qredisplay_dont_pause, Qt);
   redisplay_preserve_echo_area (2);
-  unbind_to (count, Qnil);
+  dynwind_end ();
   return Qt;
 }
 
@@ -6207,20 +6227,7 @@ WINDOW nil or omitted means report on the selected window.  */)
 void
 syms_of_display (void)
 {
-  defsubr (&Sredraw_frame);
-  defsubr (&Sredraw_display);
-  defsubr (&Sframe_or_buffer_changed_p);
-  defsubr (&Sopen_termscript);
-  defsubr (&Sding);
-  defsubr (&Sredisplay);
-  defsubr (&Ssleep_for);
-  defsubr (&Ssend_string_to_terminal);
-  defsubr (&Sinternal_show_cursor);
-  defsubr (&Sinternal_show_cursor_p);
-
-#ifdef GLYPH_DEBUG
-  defsubr (&Sdump_redisplay_history);
-#endif
+#include "dispnew.x"
 
   frame_and_buffer_state = Fmake_vector (make_number (20), Qlambda);
   staticpro (&frame_and_buffer_state);