dynwind fixes
[bpt/emacs.git] / src / xdisp.c
index 70e4d1b..774903b 100644 (file)
@@ -637,7 +637,7 @@ void
 wset_redisplay (struct window *w)
 {
   /* Beware: selected_window can be nil during early stages.  */
-  if (!EQ (make_lisp_ptr (w, Lisp_Vectorlike), selected_window))
+  if (!EQ (w->header.self, selected_window))
     redisplay_other_windows ();
   w->redisplay = true;
 }
@@ -2616,7 +2616,7 @@ safe__call (bool inhibit_quit, ptrdiff_t nargs, Lisp_Object func, va_list ap)
   else
     {
       ptrdiff_t i;
-      ptrdiff_t count = SPECPDL_INDEX ();
+      dynwind_begin ();
       struct gcpro gcpro1;
       Lisp_Object *args = alloca (nargs * word_size);
 
@@ -2634,7 +2634,7 @@ safe__call (bool inhibit_quit, ptrdiff_t nargs, Lisp_Object func, va_list ap)
       val = internal_condition_case_n (Ffuncall, nargs, args, Qt,
                                       safe_eval_handler);
       UNGCPRO;
-      val = unbind_to (count, val);
+      dynwind_end ();
     }
 
   return val;
@@ -3811,7 +3811,7 @@ handle_fontified_prop (struct it *it)
             no amount of fontifying will be able to change it.  */
          NILP (prop) && IT_CHARPOS (*it) < Z))
     {
-      ptrdiff_t count = SPECPDL_INDEX ();
+      dynwind_begin ();
       Lisp_Object val;
       struct buffer *obuf = current_buffer;
       ptrdiff_t begv = BEGV, zv = ZV;
@@ -3859,7 +3859,7 @@ handle_fontified_prop (struct it *it)
          UNGCPRO;
        }
 
-      unbind_to (count, Qnil);
+      dynwind_end ();
 
       /* Fontification functions routinely call `save-restriction'.
         Normally, this tags clip_changed, which can confuse redisplay
@@ -4823,7 +4823,7 @@ handle_single_display_spec (struct it *it, Lisp_Object spec, Lisp_Object object,
 
   if (!NILP (form) && !EQ (form, Qt))
     {
-      ptrdiff_t count = SPECPDL_INDEX ();
+      dynwind_begin ();
       struct gcpro gcpro1;
 
       /* Bind `object' to the object having the `display' property, a
@@ -4839,7 +4839,7 @@ handle_single_display_spec (struct it *it, Lisp_Object spec, Lisp_Object object,
       GCPRO1 (form);
       form = safe_eval (form);
       UNGCPRO;
-      unbind_to (count, Qnil);
+      dynwind_end ();
     }
 
   if (NILP (form))
@@ -4897,11 +4897,11 @@ handle_single_display_spec (struct it *it, Lisp_Object spec, Lisp_Object object,
                {
                  /* Evaluate IT->font_height with `height' bound to the
                     current specified height to get the new height.  */
-                 ptrdiff_t count = SPECPDL_INDEX ();
+                 dynwind_begin ();
 
                  specbind (Qheight, face->lface[LFACE_HEIGHT_INDEX]);
                  value = safe_eval (it->font_height);
-                 unbind_to (count, Qnil);
+                 dynwind_end ();
 
                  if (NUMBERP (value))
                    new_height = XFLOATINT (value);
@@ -8269,7 +8269,7 @@ next_element_from_buffer (struct it *it)
 
       /* Get the next character, maybe multibyte.  */
       p = BYTE_POS_ADDR (IT_BYTEPOS (*it));
-      if (it->multibyte_p && !ASCII_BYTE_P (*p))
+      if (it->multibyte_p && !ASCII_CHAR_P (*p))
        it->c = STRING_CHAR_AND_LENGTH (p, it->len);
       else
        it->c = *p, it->len = 1;
@@ -9932,9 +9932,7 @@ message_dolog (const char *m, ptrdiff_t nbytes, bool nlflag, bool multibyte)
          for (i = 0; i < nbytes; i += char_bytes)
            {
              c = string_char_and_length (msg + i, &char_bytes);
-             work[0] = (ASCII_CHAR_P (c)
-                        ? c
-                        : multibyte_char_to_unibyte (c));
+             work[0] = CHAR_TO_BYTE8 (c);
              insert_1_both (work, 1, 1, 1, 0, 0);
            }
        }
@@ -10427,7 +10425,7 @@ with_echo_area_buffer (struct window *w, int which,
 {
   Lisp_Object buffer;
   int this_one, the_other, clear_buffer_p, rc;
-  ptrdiff_t count = SPECPDL_INDEX ();
+  dynwind_begin ();
 
   /* If buffers aren't live, make new ones.  */
   ensure_echo_area_buffers ();
@@ -10501,7 +10499,7 @@ with_echo_area_buffer (struct window *w, int which,
   eassert (BEGV >= BEG);
   eassert (ZV <= Z && ZV >= BEGV);
 
-  unbind_to (count, Qnil);
+  dynwind_end ();
   return rc;
 }
 
@@ -10606,11 +10604,11 @@ setup_echo_area_for_printing (int multibyte_p)
 
       if (Z > BEG)
        {
-         ptrdiff_t count = SPECPDL_INDEX ();
+         dynwind_begin ();
          specbind (Qinhibit_read_only, Qt);
          /* Note that undo recording is always disabled.  */
          del_range (BEG, Z);
-         unbind_to (count, Qnil);
+         dynwind_end ();
        }
       TEMP_SET_PT_BOTH (BEG, BEG_BYTE);
 
@@ -10661,13 +10659,6 @@ display_echo_area (struct window *w)
 {
   int i, no_message_p, window_height_changed_p;
 
-  /* Temporarily disable garbage collections while displaying the echo
-     area.  This is done because a GC can print a message itself.
-     That message would modify the echo area buffer's contents while a
-     redisplay of the buffer is going on, and seriously confuse
-     redisplay.  */
-  ptrdiff_t count = inhibit_garbage_collection ();
-
   /* If there is no message, we must call display_echo_area_1
      nevertheless because it resizes the window.  But we will have to
      reset the echo_area_buffer in question to nil at the end because
@@ -10683,7 +10674,6 @@ display_echo_area (struct window *w)
   if (no_message_p)
     echo_area_buffer[i] = Qnil;
 
-  unbind_to (count, Qnil);
   return window_height_changed_p;
 }
 
@@ -11195,11 +11185,11 @@ echo_area_display (int update_frame_p)
              /* Must update other windows.  Likewise as in other
                 cases, don't let this update be interrupted by
                 pending input.  */
-             ptrdiff_t count = SPECPDL_INDEX ();
+             dynwind_begin ();
              specbind (Qredisplay_dont_pause, Qt);
              windows_or_buffers_changed = 44;
              redisplay_internal ();
-             unbind_to (count, Qnil);
+             dynwind_end ();
            }
          else if (FRAME_WINDOW_P (f) && n == 0)
            {
@@ -11491,7 +11481,7 @@ x_consider_frame_title (Lisp_Object frame)
       char *title;
       ptrdiff_t len;
       struct it it;
-      ptrdiff_t count = SPECPDL_INDEX ();
+      dynwind_begin ();
 
       FOR_EACH_FRAME (tail, other_frame)
        {
@@ -11527,7 +11517,7 @@ x_consider_frame_title (Lisp_Object frame)
       display_mode_element (&it, 0, -1, -1, fmt, Qnil, 0);
       len = MODE_LINE_NOPROP_LEN (title_start);
       title = mode_line_noprop_buf + title_start;
-      unbind_to (count, Qnil);
+      dynwind_end ();
 
       /* Set the title only if it's changed.  This avoids consing in
         the common case where it hasn't.  (If it turns out that we've
@@ -11635,7 +11625,7 @@ prepare_menu_bars (void)
   if (all_windows)
     {
       Lisp_Object tail, frame;
-      ptrdiff_t count = SPECPDL_INDEX ();
+      dynwind_begin ();
       /* 1 means that update_menu_bar has run its hooks
         so any further calls to update_menu_bar shouldn't do so again.  */
       int menu_bar_hooks_run = 0;
@@ -11691,7 +11681,7 @@ prepare_menu_bars (void)
          UNGCPRO;
        }
 
-      unbind_to (count, Qnil);
+      dynwind_end ();
     }
   else
     {
@@ -11754,7 +11744,7 @@ update_menu_bar (struct frame *f, int save_match_data, int hooks_run)
          || window_buffer_changed (w))
        {
          struct buffer *prev = current_buffer;
-         ptrdiff_t count = SPECPDL_INDEX ();
+         dynwind_begin ();
 
          specbind (Qinhibit_menubar_update, Qt);
 
@@ -11807,7 +11797,7 @@ update_menu_bar (struct frame *f, int save_match_data, int hooks_run)
          w->update_mode_line = 1;
 #endif /* ! (USE_X_TOOLKIT || HAVE_NTGUI || HAVE_NS || USE_GTK) */
 
-         unbind_to (count, Qnil);
+         dynwind_end ();
          set_buffer_internal_1 (prev);
        }
     }
@@ -11871,7 +11861,7 @@ update_tool_bar (struct frame *f, int save_match_data)
          || window_buffer_changed (w))
        {
          struct buffer *prev = current_buffer;
-         ptrdiff_t count = SPECPDL_INDEX ();
+         dynwind_begin ();
          Lisp_Object frame, new_tool_bar;
           int new_n_tool_bar;
          struct gcpro gcpro1;
@@ -11927,7 +11917,7 @@ update_tool_bar (struct frame *f, int save_match_data)
 
          UNGCPRO;
 
-         unbind_to (count, Qnil);
+         dynwind_end ();
          set_buffer_internal_1 (prev);
        }
     }
@@ -13328,15 +13318,6 @@ propagate_buffer_redisplay (void)
     }
 }
 
-#define STOP_POLLING                                   \
-do { if (! polling_stopped_here) stop_polling ();      \
-       polling_stopped_here = 1; } while (0)
-
-#define RESUME_POLLING                                 \
-do { if (polling_stopped_here) start_polling ();       \
-       polling_stopped_here = 0; } while (0)
-
-
 /* Perhaps in the future avoid recentering windows if it
    is not necessary; currently that causes some problems.  */
 
@@ -13391,13 +13372,13 @@ redisplay_internal (void)
 
   /* Record a function that clears redisplaying_p
      when we leave this function.  */
-  count = SPECPDL_INDEX ();
+  dynwind_begin ();
   record_unwind_protect_void (unwind_redisplay);
   redisplaying_p = 1;
   specbind (Qinhibit_free_realized_faces, Qnil);
 
   /* Record this function, so it appears on the profiler's backtraces.  */
-  record_in_backtrace (Qredisplay_internal, &Qnil, 0);
+  /*record_in_backtrace (Qredisplay_internal, &Qnil, 0);*/
 
   FOR_EACH_FRAME (tail, frame)
     XFRAME (frame)->already_hscrolled_p = 0;
@@ -13836,13 +13817,6 @@ redisplay_internal (void)
                        goto retry_frame;
                    }
 
-                 /* Prevent various kinds of signals during display
-                    update.  stdio is not robust about handling
-                    signals, which can cause an apparent I/O error.  */
-                 if (interrupt_input)
-                   unrequest_sigio ();
-                 STOP_POLLING;
-
                  pending |= update_frame (f, 0, 0);
                  f->cursor_type_changed = 0;
                  f->updated_p = 1;
@@ -13893,13 +13867,6 @@ redisplay_internal (void)
       if (sf->fonts_changed)
        goto retry;
 
-      /* Prevent various kinds of signals during display update.
-        stdio is not robust about handling signals,
-        which can cause an apparent I/O error.  */
-      if (interrupt_input)
-       unrequest_sigio ();
-      STOP_POLLING;
-
       if (FRAME_VISIBLE_P (sf) && !FRAME_OBSCURED_P (sf))
        {
          if (hscroll_windows (selected_window))
@@ -13970,14 +13937,6 @@ redisplay_internal (void)
       windows_or_buffers_changed = 0;
     }
 
-  /* Start SIGIO interrupts coming again.  Having them off during the
-     code above makes it less likely one will discard output, but not
-     impossible, since there might be stuff in the system buffer here.
-     But it is much hairier to try to do anything about that.  */
-  if (interrupt_input)
-    request_sigio ();
-  RESUME_POLLING;
-
   /* If a frame has become visible which was not before, redisplay
      again, so that we display it.  Expose events for such a frame
      (which it gets when becoming visible) don't call the parts of
@@ -14028,11 +13987,7 @@ redisplay_internal (void)
 #endif /* HAVE_WINDOW_SYSTEM */
 
  end_of_redisplay:
-  if (interrupt_input && interrupts_deferred)
-    request_sigio ();
-
-  unbind_to (count, Qnil);
-  RESUME_POLLING;
+  dynwind_end ();
 }
 
 
@@ -15790,7 +15745,7 @@ set_vertical_scroll_bar (struct window *w)
       redisplay itself, when it decides that the previous window start
       point is fine and should be kept.  Search for "goto force_start"
       below to see the details.  Like the values of window-start
-      specified outside of redisply, these internally deduced values
+      specified outside of redisplay, these internally-deduced values
       are tested for feasibility, and ignored if found to be
       unfeasible.
 
@@ -15820,7 +15775,6 @@ redisplay_window (Lisp_Object window, bool just_this_one_p)
      It indicates that the buffer contents and narrowing are unchanged.  */
   bool buffer_unchanged_p = false;
   int temp_scroll_step = 0;
-  ptrdiff_t count = SPECPDL_INDEX ();
   int rc;
   int centering_position = -1;
   int last_line_misfit = 0;
@@ -15846,6 +15800,8 @@ redisplay_window (Lisp_Object window, bool just_this_one_p)
   eassert (XMARKER (w->start)->buffer == buffer);
   eassert (XMARKER (w->pointm)->buffer == buffer);
 
+  dynwind_begin ();
+
   /* We come here again if we need to run window-text-change-functions
      below.  */
  restart:
@@ -16759,7 +16715,7 @@ redisplay_window (Lisp_Object window, bool just_this_one_p)
   if (CHARPOS (lpoint) <= ZV)
     TEMP_SET_PT_BOTH (CHARPOS (lpoint), BYTEPOS (lpoint));
 
-  unbind_to (count, Qnil);
+  dynwind_end ();
 }
 
 
@@ -20741,12 +20697,15 @@ Value is the new character position of point.  */)
      recorded in the glyphs, at least as long as the goal is on the
      screen.  */
   if (w->window_end_valid
-      && NILP (Vexecuting_kbd_macro)
       && !windows_or_buffers_changed
       && b
       && !b->clip_changed
       && !b->prevent_redisplay_optimizations_p
       && !window_outdated (w)
+      /* We rely below on the cursor coordinates to be up to date, but
+        we cannot trust them if some command moved point since the
+        last complete redisplay.  */
+      && w->last_point == BUF_PT (b)
       && w->cursor.vpos >= 0
       && w->cursor.vpos < w->current_matrix->nrows
       && (row = MATRIX_ROW (w->current_matrix, w->cursor.vpos))->enabled_p)
@@ -21510,7 +21469,7 @@ display_mode_line (struct window *w, enum face_id face_id, Lisp_Object format)
 {
   struct it it;
   struct face *face;
-  ptrdiff_t count = SPECPDL_INDEX ();
+  dynwind_begin ();
 
   init_iterator (&it, w, -1, -1, NULL, face_id);
   /* Don't extend on a previously drawn mode-line.
@@ -21538,7 +21497,7 @@ display_mode_line (struct window *w, enum face_id face_id, Lisp_Object format)
   display_mode_element (&it, 0, 0, 0, format, Qnil, 0);
   pop_kboard ();
 
-  unbind_to (count, Qnil);
+  dynwind_end ();
 
   /* Fill up with spaces.  */
   display_string (" ", Qnil, Qnil, 0, 0, &it, 10000, -1, -1, 0);
@@ -22190,7 +22149,7 @@ are the selected window and the WINDOW's buffer).  */)
   struct buffer *old_buffer = NULL;
   int face_id;
   int no_props = INTEGERP (face);
-  ptrdiff_t count = SPECPDL_INDEX ();
+  dynwind_begin ();
   Lisp_Object str;
   int string_start = 0;
 
@@ -22203,8 +22162,10 @@ are the selected window and the WINDOW's buffer).  */)
 
   /* Make formatting the modeline a non-op when noninteractive, otherwise
      there will be problems later caused by a partially initialized frame.  */
-  if (NILP (format) || noninteractive)
+  if (NILP (format) || noninteractive) {
+    dynwind_end ();
     return empty_unibyte_string;
+  }
 
   if (no_props)
     face = Qnil;
@@ -22265,7 +22226,7 @@ are the selected window and the WINDOW's buffer).  */)
                        empty_unibyte_string);
     }
 
-  unbind_to (count, Qnil);
+  dynwind_end ();
   return str;
 }
 
@@ -22850,10 +22811,8 @@ decode_mode_spec (struct window *w, register int c, int field_width,
 
     case '@':
       {
-       ptrdiff_t count = inhibit_garbage_collection ();
        Lisp_Object val = call1 (intern ("file-remote-p"),
                                 BVAR (current_buffer, directory));
-       unbind_to (count, Qnil);
 
        if (NILP (val))
          return "-";
@@ -25778,7 +25737,7 @@ produce_glyphless_glyph (struct it *it, int for_no_font, Lisp_Object acronym)
          sprintf (buf, "%0*X", it->c < 0x10000 ? 4 : 6, it->c);
          str = buf;
        }
-      for (len = 0; str[len] && ASCII_BYTE_P (str[len]) && len < 6; len++)
+      for (len = 0; str[len] && ASCII_CHAR_P (str[len]) && len < 6; len++)
        code[len] = font->driver->encode_char (font, str[len]);
       upper_len = (len + 1) / 2;
       font->driver->text_extents (font, code, upper_len,
@@ -29964,6 +29923,8 @@ x_intersect_rectangles (XRectangle *r1, XRectangle *r2, XRectangle *result)
 void
 syms_of_xdisp (void)
 {
+#include "xdisp.x"
+
   Vwith_echo_area_save_vector = Qnil;
   staticpro (&Vwith_echo_area_save_vector);
 
@@ -29980,25 +29941,6 @@ syms_of_xdisp (void)
   message_dolog_marker3 = Fmake_marker ();
   staticpro (&message_dolog_marker3);
 
-#ifdef GLYPH_DEBUG
-  defsubr (&Sdump_frame_glyph_matrix);
-  defsubr (&Sdump_glyph_matrix);
-  defsubr (&Sdump_glyph_row);
-  defsubr (&Sdump_tool_bar_row);
-  defsubr (&Strace_redisplay);
-  defsubr (&Strace_to_stderr);
-#endif
-#ifdef HAVE_WINDOW_SYSTEM
-  defsubr (&Stool_bar_height);
-  defsubr (&Slookup_image_map);
-#endif
-  defsubr (&Sline_pixel_height);
-  defsubr (&Sformat_mode_line);
-  defsubr (&Sinvisible_p);
-  defsubr (&Scurrent_bidi_paragraph_direction);
-  defsubr (&Swindow_text_pixel_size);
-  defsubr (&Smove_point_visually);
-
   DEFSYM (Qmenu_bar_update_hook, "menu-bar-update-hook");
   DEFSYM (Qoverriding_terminal_local_map, "overriding-terminal-local-map");
   DEFSYM (Qoverriding_local_map, "overriding-local-map");
@@ -30650,7 +30592,7 @@ init_xdisp (void)
     /* Allocate the buffer for frame titles.
        Also used for `format-mode-line'.  */
     int size = 100;
-    mode_line_noprop_buf = xmalloc (size);
+    mode_line_noprop_buf = xmalloc_atomic (size);
     mode_line_noprop_buf_end = mode_line_noprop_buf + size;
     mode_line_noprop_ptr = mode_line_noprop_buf;
     mode_line_target = MODE_LINE_DISPLAY;