diff --git a/src/buffer.c b/src/buffer.c
index 98b61c3..454457a 100644
--- a/src/buffer.c
+++ b/src/buffer.c
@@ -5073,6 +5073,8 @@ init_buffer_once (void)
   XSETFASTINT (BVAR (&buffer_local_flags, display_table), idx); ++idx;
   XSETFASTINT (BVAR (&buffer_local_flags, syntax_table), idx); ++idx;
   XSETFASTINT (BVAR (&buffer_local_flags, cache_long_scans), idx); ++idx;
+  XSETFASTINT (BVAR (&buffer_local_flags, window_start_end_hook), idx); ++idx;
+  XSETFASTINT (BVAR (&buffer_local_flags, mc_list), idx); ++idx;
   XSETFASTINT (BVAR (&buffer_local_flags, category_table), idx); ++idx;
   XSETFASTINT (BVAR (&buffer_local_flags, bidi_display_reordering), idx); ++idx;
   XSETFASTINT (BVAR (&buffer_local_flags, bidi_paragraph_direction), idx); ++idx;
@@ -5166,6 +5168,8 @@ init_buffer_once (void)
   XSETFASTINT (BVAR (&buffer_defaults, fill_column), 70);
   XSETFASTINT (BVAR (&buffer_defaults, left_margin), 0);
   bset_cache_long_scans (&buffer_defaults, Qt);
+  bset_window_start_end_hook (&buffer_defaults, Qnil);
+  bset_mc_list (&buffer_defaults, Qnil);
   bset_file_truename (&buffer_defaults, Qnil);
   XSETFASTINT (BVAR (&buffer_defaults, display_count), 0);
   XSETFASTINT (BVAR (&buffer_defaults, left_margin_cols), 0);
@@ -5379,6 +5383,9 @@ syms_of_buffer (void)
   staticpro (&QSFundamental);
   staticpro (&Vbuffer_alist);
 
+  DEFSYM (Qwindow_start_end_hook, "window-start-end-hook");
+  DEFSYM (Qmc_list, "mc-list");
+
   DEFSYM (Qchoice, "choice");
   DEFSYM (Qleft, "left");
   DEFSYM (Qright, "right");
@@ -6148,6 +6155,15 @@ maintained internally by the Emacs primitives.  Enabling or disabling
 the cache should not affect the behavior of any of the motion
 functions; it should only affect their performance.  */);
 
+  DEFVAR_PER_BUFFER ("window-start-end-hook", &BVAR (current_buffer, window_start_end_hook), Qnil,
+    doc: /* A bufer-local hook used to obtain new `window-start` and `window-end`
+during redisplay.  The function attached to this hook has the following arguments:
+WINDOW, WINDOW-START, WINDOW-END, PBOL-START, PEOL-END, FULLY-P.  */);
+
+  DEFVAR_PER_BUFFER ("mc-list", &BVAR (current_buffer, mc_list), Qnil,
+    doc: /* A bufer-local variable to store the value of the multiple cursors to be displayed
+during the next redisplay.  */);
+
   DEFVAR_PER_BUFFER ("point-before-scroll", &BVAR (current_buffer, point_before_scroll), Qnil,
 		     doc: /* Value of point before the last series of scroll operations, or nil.  */);
 
diff --git a/src/buffer.h b/src/buffer.h
index 5783bfb..e683b9b 100644
--- a/src/buffer.h
+++ b/src/buffer.h
@@ -643,6 +643,12 @@ struct buffer
      cache are enabled.  See search.c, indent.c and bidi.c for details.  */
   Lisp_Object cache_long_scans_;
 
+  /* The name of the hook.  */
+  Lisp_Object window_start_end_hook_;
+
+  /* The name of list used by multiple cursors for next redisplay.  */
+  Lisp_Object mc_list_;
+
   /* If the width run cache is enabled, this table contains the
      character widths width_run_cache (see above) assumes.  When we
      do a thorough redisplay, we compare this against the buffer's
@@ -885,6 +891,16 @@ struct buffer
    buffer.  (Some setters that are private to a single .c file are
    defined as static in those files.)  */
 INLINE void
+bset_window_start_end_hook (struct buffer *b, Lisp_Object val)
+{
+  b->window_start_end_hook_ = val;
+}
+INLINE void
+bset_mc_list (struct buffer *b, Lisp_Object val)
+{
+  b->mc_list_ = val;
+}
+INLINE void
 bset_bidi_paragraph_direction (struct buffer *b, Lisp_Object val)
 {
   b->bidi_paragraph_direction_ = val;
diff --git a/src/dispextern.h b/src/dispextern.h
index 00667c5..759b21b 100644
--- a/src/dispextern.h
+++ b/src/dispextern.h
@@ -2891,7 +2891,8 @@ struct redisplay_interface
 			      struct glyph_row *glyph_row,
 			      int x, int y,
 			      enum text_cursor_kinds cursor_type,
-			      int cursor_width, bool on_p, bool active_p);
+			      int cursor_width, bool on_p, bool active_p,
+			      double red, double green, double blue);
 
   /* Draw vertical border for window W from (X,Y_0) to (X,Y_1).  */
   void (*draw_vertical_window_border) (struct window *w,
@@ -3287,11 +3288,11 @@ extern void x_fix_overlapping_area (struct window *, struct glyph_row *,
                                     enum glyph_row_area, int);
 extern void draw_phys_cursor_glyph (struct window *,
                                     struct glyph_row *,
-                                    enum draw_glyphs_face);
+                                    enum draw_glyphs_face, char *);
 extern void get_phys_cursor_geometry (struct window *, struct glyph_row *,
                                       struct glyph *, int *, int *, int *);
-extern void erase_phys_cursor (struct window *);
-extern void display_and_set_cursor (struct window *, bool, int, int, int, int);
+extern void erase_phys_cursor (struct window *, char *);
+extern void display_and_set_cursor (struct window *, bool, int, int, int, int, char *);
 extern void x_update_cursor (struct frame *, bool);
 extern void x_clear_cursor (struct window *);
 extern void x_draw_vertical_border (struct window *w);
diff --git a/src/keyboard.c b/src/keyboard.c
index 4e1ac15..329cba0 100644
--- a/src/keyboard.c
+++ b/src/keyboard.c
@@ -1244,6 +1244,15 @@ static int read_key_sequence (Lisp_Object *, int, Lisp_Object,
                               bool, bool, bool, bool);
 static void adjust_point_for_property (ptrdiff_t, bool);
 
+static void
+set_window_start_end_hook (void)
+{
+  Lisp_Object window = (selected_window);
+  struct window *w = decode_live_window (window);
+  w->window_start_end_hook_force = true;
+  w->window_start_end_hook_pending = true;
+}
+
 Lisp_Object
 command_loop_1 (void)
 {
@@ -1269,6 +1278,8 @@ command_loop_1 (void)
       if (!NILP (Vpost_command_hook) && !NILP (Vrun_hooks))
 	safe_run_hooks (Qpost_command_hook);
 
+      set_window_start_end_hook ();
+
       /* If displaying a message, resize the echo area window to fit
 	 that message's size exactly.  */
       if (!NILP (echo_area_buffer[0]))
@@ -1485,6 +1496,8 @@ command_loop_1 (void)
 
       safe_run_hooks (Qpost_command_hook);
 
+      set_window_start_end_hook ();
+
       /* If displaying a message, resize the echo area window to fit
 	 that message's size exactly.  */
       if (!NILP (echo_area_buffer[0]))
diff --git a/src/nsterm.m b/src/nsterm.m
index 185753d..c8660b7 100644
--- a/src/nsterm.m
+++ b/src/nsterm.m
@@ -1023,7 +1023,7 @@ ns_update_window_end (struct window *w, bool cursor_on_p,
       if (cursor_on_p)
 	display_and_set_cursor (w, 1,
 				w->output_cursor.hpos, w->output_cursor.vpos,
-				w->output_cursor.x, w->output_cursor.y);
+				w->output_cursor.x, w->output_cursor.y, "nsterm.m:1024");
 
       if (draw_window_fringes (w, 1))
 	{
@@ -2696,7 +2696,7 @@ ns_draw_fringe_bitmap (struct window *w, struct glyph_row *row,
 static void
 ns_draw_window_cursor (struct window *w, struct glyph_row *glyph_row,
 		       int x, int y, enum text_cursor_kinds cursor_type,
-		       int cursor_width, bool on_p, bool active_p)
+		       int cursor_width, bool on_p, bool active_p, double red, double green, double blue)
 /* --------------------------------------------------------------------------
      External call (RIF): draw cursor.
      Note that CURSOR_WIDTH is meaningful only for (h)bar cursors.
@@ -2781,7 +2781,12 @@ ns_draw_window_cursor (struct window *w, struct glyph_row *glyph_row,
       hollow_color = FRAME_CURSOR_COLOR (f);
     }
   else
-    [FRAME_CURSOR_COLOR (f) set];
+    {
+      if (red >= 0 && blue >= 0 && green >= 0)
+        [[NSColor colorWithCalibratedRed: red green: green blue: blue alpha: 1.0] set];
+        else
+          [FRAME_CURSOR_COLOR (f) set];
+    }
 
 #ifdef NS_IMPL_COCOA
   /* TODO: This makes drawing of cursor plus that of phys_cursor_glyph
@@ -2824,7 +2829,7 @@ ns_draw_window_cursor (struct window *w, struct glyph_row *glyph_row,
 
   /* draw the character under the cursor */
   if (cursor_type != NO_CURSOR)
-    draw_phys_cursor_glyph (w, glyph_row, DRAW_CURSOR);
+    draw_phys_cursor_glyph (w, glyph_row, DRAW_CURSOR, "nsterm.m:2824");
 
 #ifdef NS_IMPL_COCOA
   NSEnableScreenUpdates ();
@@ -3701,6 +3706,8 @@ ns_draw_glyph_string (struct glyph_string *s)
          (s->for_overlaps ? NS_DUMPGLYPH_FOREGROUND :
           NS_DUMPGLYPH_NORMAL));
 
+      /* FIXME:  kdb to consider adding support for multiple cursor foreground
+      customization of a FILLED_BOX_CURSOR.  */
       if (s->hl == DRAW_CURSOR && s->w->phys_cursor_type == FILLED_BOX_CURSOR)
         {
           unsigned long tmp = NS_FACE_BACKGROUND (s->face);
diff --git a/src/w32term.c b/src/w32term.c
index 36a5021..2023079 100644
--- a/src/w32term.c
+++ b/src/w32term.c
@@ -685,7 +685,7 @@ x_update_window_end (struct window *w, bool cursor_on_p,
       if (cursor_on_p)
 	display_and_set_cursor (w, true,
 				w->output_cursor.hpos, w->output_cursor.vpos,
-				w->output_cursor.x, w->output_cursor.y);
+				w->output_cursor.x, w->output_cursor.y, "w32term.c:686");
 
       if (draw_window_fringes (w, true))
 	{
@@ -5535,7 +5535,7 @@ x_draw_bar_cursor (struct window *w, struct glyph_row *row,
     {
       struct glyph_row *row;
       row = MATRIX_ROW (w->current_matrix, w->phys_cursor.vpos);
-      draw_phys_cursor_glyph (w, row, DRAW_CURSOR);
+      draw_phys_cursor_glyph (w, row, DRAW_CURSOR, "w32term.c: 5538");
     }
   else
     {
@@ -5626,7 +5626,7 @@ w32_clear_frame_area (struct frame *f, int x, int y, int width, int height)
 static void
 w32_draw_window_cursor (struct window *w, struct glyph_row *glyph_row,
 			int x, int y, enum text_cursor_kinds cursor_type,
-			int cursor_width, bool on_p, bool active_p)
+			int cursor_width, bool on_p, bool active_p, double red, double green, double blue)
 {
   if (on_p)
     {
@@ -5638,7 +5638,7 @@ w32_draw_window_cursor (struct window *w, struct glyph_row *glyph_row,
 	     wrong values of w->phys_cursor, as they have been
 	     overwritten before this function was called. */
 	  if (w->phys_cursor_type != NO_CURSOR)
-	    erase_phys_cursor (w);
+	    erase_phys_cursor (w, "w32term.c:5641");
 
 	  cursor_type = w->phys_cursor_type = NO_CURSOR;
 	  w->phys_cursor_width = -1;
@@ -5693,21 +5693,86 @@ w32_draw_window_cursor (struct window *w, struct glyph_row *glyph_row,
 
       switch (cursor_type)
 	{
+
 	case HOLLOW_BOX_CURSOR:
-	  x_draw_hollow_cursor (w, glyph_row);
-	  break;
+  {
+    if (red >= 0 && blue >= 0 && green >= 0)
+      {
+        struct frame *f = XFRAME (WINDOW_FRAME (w));
+        COLORREF orig_val = f->output_data.w32->cursor_pixel;
+        int int_red = red * 255;
+        int int_green = green * 255;
+        int int_blue = blue * 255;
+        f->output_data.w32->cursor_pixel = PALETTERGB (int_red, int_green, int_blue);
+        x_draw_hollow_cursor (w, glyph_row);
+        f->output_data.w32->cursor_pixel = orig_val;
+      }
+      else
+        x_draw_hollow_cursor (w, glyph_row);
+    break;
+  }
 
 	case FILLED_BOX_CURSOR:
-	  draw_phys_cursor_glyph (w, glyph_row, DRAW_CURSOR);
-	  break;
+  {
+    if (red >= 0 && blue >= 0 && green >= 0)
+      {
+        struct frame *f = XFRAME (WINDOW_FRAME (w));
+        COLORREF orig_val_a, orig_val_b;
+        orig_val_a = f->output_data.w32->cursor_gc->foreground;
+        orig_val_b = f->output_data.w32->cursor_gc->background;
+        int int_red = red * 255;
+        int int_green = green * 255;
+        int int_blue = blue * 255;
+        /* FIXME:  kdb to consider adding support for multiple cursor foreground
+        customization of a FILLED_BOX_CURSOR.  */
+        f->output_data.w32->cursor_gc->foreground = FRAME_BACKGROUND_PIXEL (f);
+        f->output_data.w32->cursor_gc->background = PALETTERGB (int_red, int_green, int_blue);
+        draw_phys_cursor_glyph (w, glyph_row, DRAW_CURSOR, "w32term.c:5730");
+        f->output_data.w32->cursor_gc->foreground = orig_val_a;
+        f->output_data.w32->cursor_gc->background = orig_val_b;
+      }
+      else
+        draw_phys_cursor_glyph (w, glyph_row, DRAW_CURSOR, "w32term.c:5735");
+    break;
+  }
 
 	case BAR_CURSOR:
-	  x_draw_bar_cursor (w, glyph_row, cursor_width, BAR_CURSOR);
-	  break;
+  {
+    if (red >= 0 && blue >= 0 && green >= 0)
+      /* Temporarily hijack `f->output_data.w32->cursor_pixel'.  */
+      {
+        struct frame *f = XFRAME (WINDOW_FRAME (w));
+        COLORREF orig_val = f->output_data.w32->cursor_pixel;
+        int int_red = red * 255;
+        int int_green = green * 255;
+        int int_blue = blue * 255;
+        f->output_data.w32->cursor_pixel = PALETTERGB (int_red, int_green, int_blue);
+        x_draw_bar_cursor (w, glyph_row, cursor_width, BAR_CURSOR);
+        f->output_data.w32->cursor_pixel = orig_val;
+      }
+      else
+        x_draw_bar_cursor (w, glyph_row, cursor_width, BAR_CURSOR);
+    break;
+  }
 
 	case HBAR_CURSOR:
-	  x_draw_bar_cursor (w, glyph_row, cursor_width, HBAR_CURSOR);
-	  break;
+  {
+    if (red >= 0 && blue >= 0 && green >= 0)
+      /* Temporarily hijack `f->output_data.w32->cursor_pixel'.  */
+      {
+        struct frame *f = XFRAME (WINDOW_FRAME (w));
+        COLORREF orig_val = f->output_data.w32->cursor_pixel;
+        int int_red = red * 255;
+        int int_green = green * 255;
+        int int_blue = blue * 255;
+        f->output_data.w32->cursor_pixel = PALETTERGB (int_red, int_green, int_blue);
+        x_draw_bar_cursor (w, glyph_row, cursor_width, HBAR_CURSOR);
+        f->output_data.w32->cursor_pixel = orig_val;
+      }
+      else
+        x_draw_bar_cursor (w, glyph_row, cursor_width, HBAR_CURSOR);
+    break;
+  }
 
 	case NO_CURSOR:
 	  w->phys_cursor_width = 0;
diff --git a/src/window.h b/src/window.h
index 2c03033..a28c677 100644
--- a/src/window.h
+++ b/src/window.h
@@ -395,6 +395,19 @@ struct window
     /* Z_BYTE - buffer position of the last glyph in the current matrix of W.
        Should be nonnegative, and only valid if window_end_valid is true.  */
     ptrdiff_t window_end_bytepos;
+
+    /* True means force a call to Vwindow_start_end_hook.  */
+    bool_bf window_start_end_hook_force : 1;
+
+    /* True means the hook has not yet run with point fully visible.  */
+    bool_bf window_start_end_hook_pending : 1;
+
+    /* Values for previous and current `window-start' and `window-end'.  */
+    int window_start_end_hook_int_window_start, window_start_end_hook_int_window_end,
+        window_start_end_hook_int_previous_window_start, window_start_end_hook_int_previous_window_end;
+
+    /* The cache for multiple cursors.  */
+    Lisp_Object mc_cache;
   };
 
 /* Most code should use these functions to set Lisp fields in struct
diff --git a/src/xdisp.c b/src/xdisp.c
index 5b96144..6275020 100644
--- a/src/xdisp.c
+++ b/src/xdisp.c
@@ -13414,6 +13414,93 @@ do { if (! polling_stopped_here) stop_polling ();	\
 do { if (polling_stopped_here) start_polling ();	\
        polling_stopped_here = false; } while (false)
 
+static void
+run_window_start_end_hook (Lisp_Object window, struct text_pos startp, EMACS_INT posint, struct it it, char *string, bool force)
+{
+  struct window *w = decode_live_window (window);
+  Lisp_Object buf;
+  struct buffer *b;
+  buf = w->contents;
+  CHECK_BUFFER (buf);
+  b = XBUFFER (buf);
+  struct buffer *old_buffer = NULL;
+  void *itdata = NULL;
+  bool fully_p = false;
+  int x, y, rtop, rbot, rowh, vpos, startp_integer, endp, pbol_startp, peol_endp;
+  startp_integer = CHARPOS (startp);
+  if (b != current_buffer)
+    {
+      old_buffer = current_buffer;
+      set_buffer_internal (b);
+    }
+  if (w->window_start_end_hook_pending
+        && (!NILP (BVAR (current_buffer, window_start_end_hook))
+            || !NILP (BVAR (current_buffer, mc_list))
+            || w->mc_cache))
+    {
+      if (((posint >= CHARPOS (startp) && posint <= BUF_ZV (b))
+            && CHARPOS (startp) >= BUF_BEGV (b)
+            && CHARPOS (startp) <= BUF_ZV (b)
+            && pos_visible_p (w, posint, &x, &y, &rtop, &rbot, &rowh, &vpos)))
+        fully_p = !rtop && !rbot;
+      if (fully_p)
+        {
+          w->window_start_end_hook_int_previous_window_start = w->window_start_end_hook_int_window_start;
+          w->window_start_end_hook_int_window_start = startp_integer;
+          itdata = bidi_shelve_cache ();
+          start_display (&it, w, startp);
+          move_it_vertically (&it, window_box_height (w));
+          if (it.current_y < it.last_visible_y)
+            move_it_past_eol (&it);
+          endp = (IT_CHARPOS (it));
+          w->window_start_end_hook_int_previous_window_end = w->window_start_end_hook_int_window_end;
+          w->window_start_end_hook_int_window_end = endp;
+          bidi_unshelve_cache (itdata, false);
+          SET_PT (startp_integer);
+          pbol_startp = XINT (Fline_beginning_position (Qnil));
+          SET_PT (endp);
+          peol_endp = XINT (Fline_end_position (Qnil));
+          SET_PT (posint);
+#ifdef GLYPH_DEBUG
+          debug_method_add (w, "%s -- x: %d | y: %d | startp: %d | endp: %d | pbol_startp: %d | peol_endp: %d",
+                               string, x, y, startp_integer, endp, pbol_startp, peol_endp);
+#endif
+          /* Reset the flag _before_ calling Lisp, not after, so that
+             if Lisp does signal an error, the flag will be reset, and
+             won't cause the hook to be called ad nauseam.  */
+          w->window_start_end_hook_pending = false;
+          /* When calling Lisp from redisplay, always use safe_call, to be
+             protected against errors signaled by that Lisp.  */
+          /* safe_call:  fn, arg1, arg2, arg3, arg4, arg5, arg6, arg7  */
+          safe_call (8,
+              Qrun_hook_with_args,
+              Qwindow_start_end_hook,
+              window,
+              make_number (startp_integer),
+              make_number (endp),
+              make_number (pbol_startp),
+              make_number (peol_endp),
+              fully_p ? Qt : Qnil);
+          /* At the catch-all when scrolling with the mouse wheel, this next section causes a visual flash
+          of cursor in the wrong position due to SET_PT above.  */
+          if (force)
+            {
+              clear_glyph_matrix (w->desired_matrix);
+              try_window (window, startp, 0);
+            }
+        }
+        else
+          {
+#ifdef GLYPH_DEBUG
+            /* See the doc-string for `pos-visible-in-window-p'.  */
+            debug_method_add (w, "%s -- x: %d | y: %d | rtop: %d | rbot %d | rowh: %d | vpos: %d",
+                                 string, x, y, rtop, rbot, rowh, vpos);
+#endif
+          }
+    }
+  if (old_buffer)
+    set_buffer_internal (old_buffer);
+}
 
 /* Perhaps in the future avoid recentering windows if it
    is not necessary; currently that causes some problems.  */
@@ -13687,6 +13774,7 @@ redisplay_internal (void)
       && match_p
       && !w->force_start
       && !w->optional_new_start
+      && !w->window_start_end_hook_force
       /* Point must be on the line that we have info recorded about.  */
       && PT >= CHARPOS (tlbufpos)
       && PT <= Z - CHARPOS (tlendpos)
@@ -15388,6 +15476,8 @@ try_scrolling (Lisp_Object window, bool just_this_one_p,
   /* Run window scroll functions.  */
   startp = run_window_scroll_functions (window, startp);
 
+  run_window_start_end_hook (window, startp, PT, it, "try_scrolling", false);
+
   /* Display the window.  Give up if new fonts are loaded, or if point
      doesn't appear.  */
   if (!try_window (window, startp, 0))
@@ -16053,6 +16143,7 @@ redisplay_window (Lisp_Object window, bool just_this_one_p)
   ptrdiff_t beg_unchanged, end_unchanged;
   int frame_line_height;
   bool use_desired_matrix;
+  bool window_start_end_hook_suppress_wsf = false;
 
   SET_TEXT_POS (lpoint, PT, PT_BYTE);
   opoint = lpoint;
@@ -16243,13 +16334,16 @@ redisplay_window (Lisp_Object window, bool just_this_one_p)
 
   /* If someone specified a new starting point but did not insist,
      check whether it can be used.  */
-  if ((w->optional_new_start || window_frozen_p (w))
+  if ((w->optional_new_start || w->window_start_end_hook_force || window_frozen_p (w))
       && CHARPOS (startp) >= BEGV
       && CHARPOS (startp) <= ZV)
     {
+
+      if (w->window_start_end_hook_force && !w->optional_new_start && !window_frozen_p (w) && !w->force_start)
+        window_start_end_hook_suppress_wsf = true;
+
       ptrdiff_t it_charpos;
 
-      w->optional_new_start = false;
       start_display (&it, w, startp);
       move_it_to (&it, PT, 0, it.last_visible_y, -1,
 		  MOVE_TO_POS | MOVE_TO_X | MOVE_TO_Y);
@@ -16270,14 +16364,28 @@ redisplay_window (Lisp_Object window, bool just_this_one_p)
 	    w->force_start = true;
 #ifdef GLYPH_DEBUG
 	  if (w->force_start)
-	    {
-	      if (window_frozen_p (w))
-		debug_method_add (w, "set force_start from frozen window start");
-	      else
-		debug_method_add (w, "set force_start from optional_new_start");
-	    }
+    {
+      if (window_frozen_p (w))
+        {
+        debug_method_add (w, "redisplay_window (force_start):  window_frozen_p (w)");
+      }
+      else if (w->optional_new_start)
+        {
+        debug_method_add (w, "redisplay_window (force_start):  w->optional_new_start");
+      }
+      else if (w->window_start_end_hook_force)
+        {
+        debug_method_add (w, "redisplay_window (force_start):  w->window_start_end_hook_force");
+      }
+      else
+        {
+        debug_method_add (w, "redisplay_window (force_start):  This situation is not yet contemplated.");
+      }
+    }
 #endif
 	}
+      w->optional_new_start = false;
+      w->window_start_end_hook_force = false;
     }
 
  force_start:
@@ -16305,11 +16413,18 @@ redisplay_window (Lisp_Object window, bool just_this_one_p)
 	 than to get into an infinite loop calling the hook functions
 	 and having them get more errors.  */
       if (!update_mode_line
-	  || ! NILP (Vwindow_scroll_functions))
+	  || ! NILP (Vwindow_scroll_functions)
+	  || ! NILP (BVAR (current_buffer, window_start_end_hook)))
 	{
 	  update_mode_line = true;
 	  w->update_mode_line = true;
-	  startp = run_window_scroll_functions (window, startp);
+
+  /* Run window scroll functions.  */
+  if (!window_start_end_hook_suppress_wsf)
+    startp = run_window_scroll_functions (window, startp);
+
+  run_window_start_end_hook (window, startp, PT, it, "redisplay_window (force_start)", false);
+
 	}
 
       if (CHARPOS (startp) < BEGV)
@@ -16460,9 +16575,13 @@ redisplay_window (Lisp_Object window, bool just_this_one_p)
 	  goto try_to_scroll;
 	}
 
+  /* When scrolling with the mouse wheel, PT has not yet been reset so we use CHARPOS (startp).  */
+  run_window_start_end_hook (window, startp, CHARPOS (startp), it, "redisplay_window:  catch-all", false);
+
 #ifdef GLYPH_DEBUG
-      debug_method_add (w, "forced window start");
+      debug_method_add (w, "redisplay_window:  forced window start");
 #endif
+
       goto done;
     }
 
@@ -16577,6 +16696,7 @@ redisplay_window (Lisp_Object window, bool just_this_one_p)
 	     because a window scroll function can have changed the
 	     buffer.  */
 	  || !NILP (Vwindow_scroll_functions)
+	  || !NILP (BVAR (current_buffer, window_start_end_hook))
 	  || MINI_WINDOW_P (w)
 	  || !(used_current_matrix_p
 	       = try_window_reusing_current_matrix (w)))
@@ -16774,6 +16894,8 @@ redisplay_window (Lisp_Object window, bool just_this_one_p)
   /* Run scroll hooks.  */
   startp = run_window_scroll_functions (window, it.current.pos);
 
+  run_window_start_end_hook (window, startp, PT, it, "redisplay_window (recenter)", false);
+
   /* Redisplay the window.  */
   use_desired_matrix = false;
   if (!current_matrix_up_to_date_p
@@ -16782,6 +16904,7 @@ redisplay_window (Lisp_Object window, bool just_this_one_p)
       /* Don't use try_window_reusing_current_matrix in this case
 	 because it can have changed the buffer.  */
       || !NILP (Vwindow_scroll_functions)
+      || !NILP (BVAR (current_buffer, window_start_end_hook))
       || !just_this_one_p
       || MINI_WINDOW_P (w)
       || !(used_current_matrix_p
@@ -16902,7 +17025,13 @@ redisplay_window (Lisp_Object window, bool just_this_one_p)
 	  clear_glyph_matrix (w->desired_matrix);
 	  if (1 == try_window (window, it.current.pos,
 			       TRY_WINDOW_CHECK_MARGINS))
-	    goto done;
+    {
+      /* To avoid a visual hick-up, it is necessary to set the last argument to true -- that triggers
+      `clear_glyph_matrix' and `try_window' after the functions attached to the hook have run.  */
+      run_window_start_end_hook (window, it.current.pos, PT, it, "redisplay_window (post-recenter)", true);
+      goto done;
+    }
+
 	}
 
       /* If centering point failed to make the whole line visible,
@@ -23705,7 +23834,6 @@ decode_mode_spec (struct window *w, register int c, int field_width,
     return "";
 }
 
-
 /* Count up to COUNT lines starting from START_BYTE.  COUNT negative
    means count lines back from START_BYTE.  But don't go beyond
    LIMIT_BYTE.  Return the number of lines thus found (always
@@ -28151,8 +28279,15 @@ x_fix_overlapping_area (struct window *w, struct glyph_row *row,
 
 void
 draw_phys_cursor_glyph (struct window *w, struct glyph_row *row,
-			enum draw_glyphs_face hl)
+			enum draw_glyphs_face hl, char *string)
 {
+
+/*
+#ifdef GLYPH_DEBUG
+  debug_method_add (w, "draw_phys_cursor_glyph: %s", string);
+#endif
+*/
+
   /* If cursor hpos is out of bounds, don't draw garbage.  This can
      happen in mini-buffer windows when switching between echo area
      glyphs and mini-buffer.  */
@@ -28202,7 +28337,7 @@ draw_phys_cursor_glyph (struct window *w, struct glyph_row *row,
 /* Erase the image of a cursor of window W from the screen.  */
 
 void
-erase_phys_cursor (struct window *w)
+erase_phys_cursor (struct window *w, char *string)
 {
   struct frame *f = XFRAME (w->frame);
   Mouse_HLInfo *hlinfo = MOUSE_HL_INFO (f);
@@ -28214,6 +28349,12 @@ erase_phys_cursor (struct window *w)
   struct glyph *cursor_glyph;
   enum draw_glyphs_face hl;
 
+/*
+#ifdef GLYPH_DEBUG
+  debug_method_add (w, "erase_phys_cursor: %s", string);
+#endif
+*/
+
   /* No cursor displayed or row invalidated => nothing to do on the
      screen.  */
   if (w->phys_cursor_type == NO_CURSOR)
@@ -28308,13 +28449,407 @@ erase_phys_cursor (struct window *w)
     hl = DRAW_MOUSE_FACE;
   else
     hl = DRAW_NORMAL_TEXT;
-  draw_phys_cursor_glyph (w, cursor_row, hl);
+  draw_phys_cursor_glyph (w, cursor_row, hl, "xdisp.c: 1 of 1");
 
  mark_cursor_off:
   w->phys_cursor_on_p = false;
   w->phys_cursor_type = NO_CURSOR;
 }
 
+void
+mc_erase (struct window *w, EMACS_INT x, EMACS_INT y, EMACS_INT hpos, EMACS_INT vpos,
+                      enum text_cursor_kinds cursor_type, int cursor_width, double red, double green, double blue)
+{
+  int header_line_height = WINDOW_HEADER_LINE_HEIGHT (w);
+  if (header_line_height > 0)
+    vpos = vpos + 1;
+  struct frame *f = XFRAME (w->frame);
+  Mouse_HLInfo *hlinfo = MOUSE_HL_INFO (f);
+  bool mouse_face_here_p = false;
+  struct glyph_matrix *active_glyphs = w->current_matrix;
+  struct glyph_row *cursor_row;
+  struct glyph *cursor_glyph;
+  enum draw_glyphs_face hl;
+  cursor_row = MATRIX_ROW (active_glyphs, vpos);
+  /* Maybe clear the display under the cursor.  */
+  if (w->phys_cursor_type == HOLLOW_BOX_CURSOR)
+    {
+      int hollow_x, hollow_y;
+      int width;
+      if (!(vpos >= 0
+          && vpos < w->current_matrix->nrows))
+        cursor_glyph = NULL;
+      if (!cursor_row->enabled_p)
+        cursor_glyph = NULL;
+      if (w->hscroll)
+        {
+          /* When the window is hscrolled, cursor hpos can legitimately be
+           out of bounds, but we draw the cursor at the corresponding
+           window margin in that case.  */
+          if (!cursor_row->reversed_p && hpos < 0)
+            hpos = 0;
+          if (cursor_row->reversed_p && hpos >= cursor_row->used[TEXT_AREA])
+            hpos = cursor_row->used[TEXT_AREA] - 1;
+        }
+      if (0 <= hpos && hpos < cursor_row->used[TEXT_AREA])
+        cursor_glyph = cursor_row->glyphs[TEXT_AREA] + hpos;
+      else
+        cursor_glyph = NULL;
+      if (cursor_glyph == NULL)
+        goto mark_cursor_off;
+      width = cursor_glyph->pixel_width;
+      hollow_x = x;
+      if (x < 0)
+        {
+          width += hollow_x;
+          hollow_x = 0;
+        }
+      width = min (width, window_box_width (w, TEXT_AREA) - hollow_x);
+      hollow_y = WINDOW_TO_FRAME_PIXEL_Y (w, max (header_line_height, cursor_row->y));
+      hollow_x = WINDOW_TEXT_TO_FRAME_PIXEL_X (w, hollow_x);
+      if (width > 0)
+        FRAME_RIF (f)->clear_frame_area (f, hollow_x, hollow_y, width, cursor_row->visible_height);
+    }
+  /* Erase the cursor by redrawing the character underneath it.  */
+  if (mouse_face_here_p)
+    hl = DRAW_MOUSE_FACE;
+  else
+    hl = DRAW_NORMAL_TEXT;
+  /* If cursor hpos is out of bounds, don't draw garbage.  This can
+     happen in mini-buffer windows when switching between echo area
+     glyphs and mini-buffer.  */
+  if ((cursor_row->reversed_p
+       ? (hpos >= 0)
+       : (hpos < cursor_row->used[TEXT_AREA])))
+    {
+      int x1;
+      /* When the window is hscrolled, cursor hpos can legitimately be
+   out of bounds, but we draw the cursor at the corresponding
+   window margin in that case.  */
+      if (!cursor_row->reversed_p && hpos < 0)
+        hpos = 0;
+      if (cursor_row->reversed_p && hpos >= cursor_row->used[TEXT_AREA])
+        hpos = cursor_row->used[TEXT_AREA] - 1;
+      x1 = draw_glyphs (w, x, cursor_row, TEXT_AREA, hpos, hpos + 1,
+      hl, 0);
+      if (hl == DRAW_CURSOR)
+        w->phys_cursor_width = x1 - x;
+      /* When we erase the cursor, and ROW is overlapped by other
+   rows, make sure that these overlapping parts of other rows
+   are redrawn.  */
+        else if (hl == DRAW_NORMAL_TEXT && cursor_row->overlapped_p)
+          {
+            w->phys_cursor_width = x1 - x;
+            if (cursor_row > w->current_matrix->rows
+                && MATRIX_ROW_OVERLAPS_SUCC_P (cursor_row - 1))
+              x_fix_overlapping_area (w, cursor_row - 1, TEXT_AREA,
+                    OVERLAPS_ERASED_CURSOR);
+            if (MATRIX_ROW_BOTTOM_Y (cursor_row) < window_text_bottom_y (w)
+                && MATRIX_ROW_OVERLAPS_PRED_P (cursor_row + 1))
+              x_fix_overlapping_area (w, cursor_row + 1, TEXT_AREA,
+                    OVERLAPS_ERASED_CURSOR);
+          }
+    }
+  mark_cursor_off:
+  Qnil;
+}
+
+void
+mc_draw (struct window *w, bool on, EMACS_INT x, EMACS_INT y, EMACS_INT hpos, EMACS_INT vpos,
+                           enum text_cursor_kinds cursor_type, int cursor_width, double red, double green, double blue)
+{
+
+  int header_line_height = WINDOW_HEADER_LINE_HEIGHT (w);
+  if (header_line_height > 0)
+    vpos = vpos + 1;
+  struct frame *f = XFRAME (w->frame);
+  bool active_cursor;
+  struct glyph_row *glyph_row;
+  struct glyph *glyph;
+  int prior_hpos, prior_vpos, prior_x, prior_y;
+  glyph_row = MATRIX_ROW (w->current_matrix, vpos);
+  glyph = NULL;
+  if (!glyph_row->exact_window_width_line_p
+      || (0 <= hpos && hpos < glyph_row->used[TEXT_AREA]))
+    glyph = glyph_row->glyphs[TEXT_AREA] + hpos;
+  eassert (input_blocked_p ());
+  w->phys_cursor_ascent = glyph_row->ascent;
+  w->phys_cursor_height = glyph_row->height;
+  /* Record the current values for w->phys_cursor.x/y/hpos/vpos.  */
+  prior_hpos = w->phys_cursor.hpos;
+  prior_vpos = w->phys_cursor.vpos;
+  prior_x = w->phys_cursor.x;
+  prior_y = w->phys_cursor.y;
+  /* Hijack w->phys_cursor.x/y/hpos/vpos by setting new values.  */
+  w->phys_cursor.hpos = hpos;
+  w->phys_cursor.vpos = vpos;
+  w->phys_cursor.x = x;
+  w->phys_cursor.y = glyph_row->y;
+  FRAME_RIF (f)->draw_window_cursor (w, glyph_row, x, y, cursor_type, cursor_width, on, active_cursor, red, green, blue);
+  /* Restore the previous values for w->phys_cursor.x/y/hpos/vpos.  */
+  w->phys_cursor.hpos = prior_hpos;
+  w->phys_cursor.vpos = prior_vpos;
+  w->phys_cursor.x = prior_x;
+  w->phys_cursor.y = prior_y;
+}
+
+Lisp_Object
+mc_x_y_hpos_vpos (struct window *w, EMACS_INT posint)
+{
+  struct it it;
+  void *itdata = bidi_shelve_cache ();
+  struct text_pos pt;
+  struct text_pos pos;
+  int x, y, hpos, vpos;
+  if (w->window_start_end_hook_int_window_start
+      && w->window_start_end_hook_int_window_end
+      && posint >= w->window_start_end_hook_int_window_start
+      && posint <= w->window_start_end_hook_int_window_end)
+    {
+      SET_TEXT_POS_FROM_MARKER (pt, w->start);
+      start_display (&it, w, pt);
+      move_it_to (&it, posint, -1, -1, -1, MOVE_TO_POS);
+      pos = it.current.pos;
+      x = it.current_x;
+      y = it.current_y;
+      hpos = it.hpos;
+      vpos = it.vpos;
+      bidi_unshelve_cache (itdata, false);
+    }
+    else
+      {
+        x = -1;
+        y = -1;
+        hpos = -1;
+        vpos = -1;
+      }
+  return listn (CONSTYPE_PURE, 4, make_number (x), make_number (y), make_number (hpos), make_number (vpos));
+}
+
+int
+mc_lisp_to_cursor_type (Lisp_Object arg)
+{
+  char *str;
+  if (XTYPE (arg) == Lisp_String)
+    str = SSDATA (arg);
+  else if (XTYPE (arg) == Lisp_Symbol)
+    str = SSDATA (SYMBOL_NAME (arg));
+  else return -1;
+  if (!strcmp (str, "box"))
+    return FILLED_BOX_CURSOR;
+  if (!strcmp (str, "hollow"))
+    return HOLLOW_BOX_CURSOR;
+  if (!strcmp (str, "hbar"))
+    return HBAR_CURSOR;
+  if (!strcmp (str, "bar"))
+    return BAR_CURSOR;
+  if (!strcmp (str, "no"))
+    return NO_CURSOR;
+  return -1;
+}
+
+/* EXAMPLE #1:
+    (setq mc-list '(
+      (3 "hbar" [1.0 0.0 0.0])
+      (4 "bar" [0.0 1.0 0.0])
+      (5 "box" [0.0 0.0 1.0])
+      (6 "hollow" [0.8 0.4 0.2])
+      (7 ("hbar" 3) [1.0 0.0 1.0])
+      (8 ("bar" 3) [0.0 1.0 1.0])))
+   EXAMPLE #2:  (setq mc-list nil)
+The `mc_cache' is kept in the following example format:
+  ((
+    (3 hbar [1.0 0.0 0.0])
+    (4 bar [0.0 1.0 0.0])
+    (5 box [0.0 0.0 1.0])
+    (6 hollow [0.8 0.4 0.2])
+    (7 (hbar 3) [1.0 0.0 1.0])
+    (8 (bar 3) [0.0 1.0 1.0]))
+   (
+    ((3 hbar [1.0 0.0 0.0]) (22 20 2 0))
+    ((4 bar [0.0 1.0 0.0]) (33 20 3 0))
+    ((5 box [0.0 0.0 1.0]) (44 20 4 0))
+    ((6 hollow [0.8 0.4 0.2]) (55 20 5 0))
+    ((7 (hbar 3) [1.0 0.0 1.0]) (66 20 6 0))
+    ((8 (bar 3) [0.0 1.0 1.0]) (77 20 7 0))
+    ))
+To inspect the lisp object, use -- beware that raw numbers will crash Emacs:
+  Lisp_Object foo_r = make_float (red);
+  AUTO_STRING (format_r, "red:  %s");
+  CALLN (Fmessage, format_r, foo_r);
+  Lisp_Object foo_g = make_float (green);
+  AUTO_STRING (format_g, "green:  %s");
+  CALLN (Fmessage, format_g, foo_g);
+  Lisp_Object foo_b = make_float (blue);
+  AUTO_STRING (format_b, "blue:  %s");
+  CALLN (Fmessage, format_b, foo_b);  */
+void
+mc_calc (struct window *w)
+{
+  struct frame *f = XFRAME (w->frame);
+  struct window *sw = XWINDOW (f->selected_window);
+  enum text_cursor_kinds cursor_type = Qnil;
+  int cursor_width = 1;
+  double red, green, blue;
+  EMACS_INT posint, x, y, hpos, vpos;
+  Lisp_Object cursor_spec_list, cursor_spec_type, cursor_color_vector, vlist, x_y_hpos_vpos_list, buf;
+  Lisp_Object temp = Qnil;
+  Lisp_Object result = Qnil;
+  struct text_pos startp;
+  struct buffer *b;
+  buf = w->contents;
+  CHECK_BUFFER (buf);
+  b = XBUFFER (buf);
+  struct buffer *old_buffer = NULL;
+  struct it it;
+  void *itdata = NULL;
+  struct text_pos pt;
+  struct text_pos test_pos;
+  int test_x, test_y, test_hpos, test_vpos;
+  if (b != current_buffer)
+    {
+      old_buffer = current_buffer;
+      set_buffer_internal (b);
+    }
+  if (Fminibufferp (buf))
+    goto done;
+  if (w->mc_cache
+      && (NILP (Fequal (Fnth (make_number (0), w->mc_cache), BVAR (current_buffer, mc_list)))
+          || w != sw))
+    {
+#ifdef GLYPH_DEBUG
+  debug_method_add (w, "mc_calc:  remove cursors using cache");
+#endif
+      for (vlist = XCAR (XCDR (w->mc_cache));
+           CONSP (vlist);
+           vlist = XCDR (vlist))
+        {
+          cursor_spec_list = XCAR (XCAR (vlist));
+          posint = XINT (Fnth (make_number (0), cursor_spec_list));
+          cursor_spec_type = Fnth (make_number (1), cursor_spec_list);
+          if (CONSP (cursor_spec_type))
+            cursor_type = mc_lisp_to_cursor_type (XCAR (cursor_spec_type));
+            else
+              cursor_type = mc_lisp_to_cursor_type (cursor_spec_type);
+          if (CONSP (cursor_spec_type))
+            cursor_width = XINT (XCAR (XCDR (cursor_spec_type)));
+            else
+              cursor_width = 1;
+          cursor_color_vector = Fnth (make_number (2), cursor_spec_list);
+          red = XFLOAT_DATA (AREF (cursor_color_vector, 0));
+          green = XFLOAT_DATA (AREF (cursor_color_vector, 1));
+          blue = XFLOAT_DATA (AREF (cursor_color_vector, 2));
+          if (posint
+              && w->window_start_end_hook_int_window_start
+              && w->window_start_end_hook_int_window_end
+              && posint >= w->window_start_end_hook_int_window_start
+              && posint <= w->window_start_end_hook_int_window_end)
+            {
+              x_y_hpos_vpos_list = XCAR (XCDR (XCAR (vlist)));
+              x = XINT (Fnth (make_number (0), x_y_hpos_vpos_list));
+              y = XINT (Fnth (make_number (1), x_y_hpos_vpos_list));
+              hpos = XINT (Fnth (make_number (2), x_y_hpos_vpos_list));
+              vpos = XINT (Fnth (make_number (3), x_y_hpos_vpos_list));
+              mc_erase (w, x, y, hpos, vpos, cursor_type, cursor_width, red, green, blue);
+            }
+        }
+      w->mc_cache = Qnil;
+    }
+    else if (w == sw
+            && w->window_start_end_hook_int_window_start
+            && w->window_start_end_hook_int_window_end
+            && w->window_start_end_hook_int_previous_window_start
+            && w->window_start_end_hook_int_previous_window_end
+            && w->window_start_end_hook_int_window_start == w->window_start_end_hook_int_previous_window_start
+            && w->window_start_end_hook_int_window_end == w->window_start_end_hook_int_previous_window_end
+            && !NILP (BVAR (current_buffer, mc_list))
+            && w->mc_cache
+            && !NILP (Fequal (Fnth (make_number (0), w->mc_cache), BVAR (current_buffer, mc_list))))
+      {
+#ifdef GLYPH_DEBUG
+  debug_method_add (w, "mc_calc:  draw cursors using cache");
+#endif
+        for (vlist = XCAR (XCDR (w->mc_cache));
+             CONSP (vlist);
+             vlist = XCDR (vlist))
+          {
+            cursor_spec_list = XCAR (XCAR (vlist));
+            posint = XINT (Fnth (make_number (0), cursor_spec_list));
+            cursor_spec_type = Fnth (make_number (1), cursor_spec_list);
+            if (CONSP (cursor_spec_type))
+              cursor_type = mc_lisp_to_cursor_type (XCAR (cursor_spec_type));
+              else
+                cursor_type = mc_lisp_to_cursor_type (cursor_spec_type);
+            if (CONSP (cursor_spec_type))
+              cursor_width = XINT (XCAR (XCDR (cursor_spec_type)));
+              else
+                cursor_width = 1;
+            cursor_color_vector = Fnth (make_number (2), cursor_spec_list);
+            red = XFLOAT_DATA (AREF (cursor_color_vector, 0));
+            green = XFLOAT_DATA (AREF (cursor_color_vector, 1));
+            blue = XFLOAT_DATA (AREF (cursor_color_vector, 2));
+            if (posint
+                && w->window_start_end_hook_int_window_start
+                && w->window_start_end_hook_int_window_end
+                && posint >= w->window_start_end_hook_int_window_start
+                && posint <= w->window_start_end_hook_int_window_end)
+              {
+                x_y_hpos_vpos_list = XCAR (XCDR (XCAR (vlist)));
+                x = XINT (Fnth (make_number (0), x_y_hpos_vpos_list));
+                y = XINT (Fnth (make_number (1), x_y_hpos_vpos_list));
+                hpos = XINT (Fnth (make_number (2), x_y_hpos_vpos_list));
+                vpos = XINT (Fnth (make_number (3), x_y_hpos_vpos_list));
+                mc_draw (w, 1, x, y, hpos, vpos, cursor_type, cursor_width, red, green, blue);
+              }
+          }
+      }
+      else if (w == sw
+               && !NILP (BVAR (current_buffer, mc_list)))
+        {
+#ifdef GLYPH_DEBUG
+  debug_method_add (w, "mc_calc:  draw cursors anew");
+#endif
+          for (vlist = BVAR (current_buffer, mc_list);
+               CONSP (vlist);
+               vlist = XCDR (vlist))
+            {
+              cursor_spec_list = XCAR (vlist);
+              posint = XINT (Fnth (make_number (0), cursor_spec_list));
+              cursor_spec_type = Fnth (make_number (1), cursor_spec_list);
+              if (CONSP (cursor_spec_type))
+                cursor_type = mc_lisp_to_cursor_type (XCAR (cursor_spec_type));
+                else
+                  cursor_type = mc_lisp_to_cursor_type (cursor_spec_type);
+              if (CONSP (cursor_spec_type))
+                cursor_width = XINT (XCAR (XCDR (cursor_spec_type)));
+                else
+                  cursor_width = 1;
+              cursor_color_vector = Fnth (make_number (2), cursor_spec_list);
+              red = XFLOAT_DATA (AREF (cursor_color_vector, 0));
+              green = XFLOAT_DATA (AREF (cursor_color_vector, 1));
+              blue = XFLOAT_DATA (AREF (cursor_color_vector, 2));
+              if (posint)
+                {
+                  x_y_hpos_vpos_list = mc_x_y_hpos_vpos (w, posint);
+                  temp = Fcons (cursor_spec_list, Fcons (x_y_hpos_vpos_list, Qnil));
+                  result = Fcons (temp, result);
+                  x = XINT (Fnth (make_number (0), x_y_hpos_vpos_list));
+                  y = XINT (Fnth (make_number (1), x_y_hpos_vpos_list));
+                  hpos = XINT (Fnth (make_number (2), x_y_hpos_vpos_list));
+                  vpos = XINT (Fnth (make_number (3), x_y_hpos_vpos_list));
+                  if (w->window_start_end_hook_int_window_start
+                      && w->window_start_end_hook_int_window_end
+                      && posint >= w->window_start_end_hook_int_window_start
+                      && posint <= w->window_start_end_hook_int_window_end)
+                    mc_draw (w, 1, x, y, hpos, vpos, cursor_type, cursor_width, red, green, blue);
+                }
+            }
+          w->mc_cache = Fcons (BVAR (current_buffer, mc_list), Fcons (Freverse (result), Qnil));
+        }
+  done:
+  if (old_buffer)
+    set_buffer_internal (old_buffer);
+}
 
 /* Display or clear cursor of window W.  If !ON, clear the cursor.
    If ON, display the cursor; where to put the cursor is specified by
@@ -28322,7 +28857,7 @@ erase_phys_cursor (struct window *w)
 
 void
 display_and_set_cursor (struct window *w, bool on,
-			int hpos, int vpos, int x, int y)
+			int hpos, int vpos, int x, int y, char *string)
 {
   struct frame *f = XFRAME (w->frame);
   int new_cursor_type;
@@ -28330,6 +28865,20 @@ display_and_set_cursor (struct window *w, bool on,
   bool active_cursor;
   struct glyph_row *glyph_row;
   struct glyph *glyph;
+  /* These are not being used per se in `display_and_set_cursor', but the arguments have been
+  added to `draw_window_cursor`.  We need them as argument place holders.  If the values for
+  red/green/blue are not all greater than or equal to 0, then the default cursor_color prevails.  */
+  enum text_cursor_kinds cursor_type = Qnil;
+  int cursor_width = 1;
+  float red = -1.0;
+  float blue = -1.0;
+  float green = -1.0;
+
+/*
+#ifdef GLYPH_DEBUG
+  debug_method_add (w, "display_and_set_cursor:  %s", string);
+#endif
+*/
 
   /* This is pointless on invisible frames, and dangerous on garbaged
      windows and frames; in the latter case, the frame or window may
@@ -28379,7 +28928,7 @@ display_and_set_cursor (struct window *w, bool on,
 	  || new_cursor_type != w->phys_cursor_type
 	  || ((new_cursor_type == BAR_CURSOR || new_cursor_type == HBAR_CURSOR)
 	      && new_cursor_width != w->phys_cursor_width)))
-    erase_phys_cursor (w);
+    erase_phys_cursor (w, "xdisp.c: 1 of 1");
 
   /* Don't check phys_cursor_on_p here because that flag is only set
      to false in some cases where we know that the cursor has been
@@ -28401,7 +28950,15 @@ display_and_set_cursor (struct window *w, bool on,
 
   FRAME_RIF (f)->draw_window_cursor (w, glyph_row, x, y,
                                      new_cursor_type, new_cursor_width,
-                                     on, active_cursor);
+                                     on, active_cursor, red, green, blue);
+
+  /* `mc_calc' must follow the creation of the original/master cursor so that a fake cursor
+  is not erroneously erased during the process by the original/master cursor.  xdisp: 1 of 2
+  caused erroneous multiple cursors to be placed on the line at the top of the window when
+  interactively calling `beginning-of-buffer'.*/
+  if (NILP (Fequal (build_string (string), build_string ("xdisp: 1 of 2"))))
+    mc_calc (w);
+
 }
 
 
@@ -28435,7 +28992,7 @@ update_window_cursor (struct window *w, bool on)
 
       block_input ();
       display_and_set_cursor (w, on, hpos, vpos,
-			      w->phys_cursor.x, w->phys_cursor.y);
+			      w->phys_cursor.x, w->phys_cursor.y, "xdisp: 1 of 2");
       unblock_input ();
     }
 }
@@ -28614,7 +29171,7 @@ show_mouse_face (Mouse_HLInfo *hlinfo, enum draw_glyphs_face draw)
 
 	  block_input ();
 	  display_and_set_cursor (w, true, hpos, w->phys_cursor.vpos,
-				  w->phys_cursor.x, w->phys_cursor.y);
+				  w->phys_cursor.x, w->phys_cursor.y, "xdisp: 2 of 2");
 	  unblock_input ();
 	}
 #endif	/* HAVE_WINDOW_SYSTEM */
@@ -31122,6 +31679,7 @@ They are still logged to the *Messages* buffer.  */);
   DEFSYM (Qoverriding_terminal_local_map, "overriding-terminal-local-map");
   DEFSYM (Qoverriding_local_map, "overriding-local-map");
   DEFSYM (Qwindow_scroll_functions, "window-scroll-functions");
+  DEFSYM (Qcolor_vector_calc, "color-vector-calc");
   DEFSYM (Qwindow_text_change_functions, "window-text-change-functions");
   DEFSYM (Qredisplay_end_trigger_functions, "redisplay-end-trigger-functions");
   DEFSYM (Qinhibit_point_motion_hooks, "inhibit-point-motion-hooks");
diff --git a/src/xterm.c b/src/xterm.c
index 1f71afd..093c7fa 100644
--- a/src/xterm.c
+++ b/src/xterm.c
@@ -1151,7 +1151,7 @@ x_update_window_end (struct window *w, bool cursor_on_p,
       if (cursor_on_p)
 	display_and_set_cursor (w, true,
 				w->output_cursor.hpos, w->output_cursor.vpos,
-				w->output_cursor.x, w->output_cursor.y);
+				w->output_cursor.x, w->output_cursor.y, "xterm.c:1152");
 
       if (draw_window_fringes (w, true))
 	{
@@ -8935,7 +8935,7 @@ x_draw_bar_cursor (struct window *w, struct glyph_row *row, int width, enum text
     {
       struct glyph_row *r;
       r = MATRIX_ROW (w->current_matrix, w->phys_cursor.vpos);
-      draw_phys_cursor_glyph (w, r, DRAW_CURSOR);
+      draw_phys_cursor_glyph (w, r, DRAW_CURSOR, "xterm.c: 8938");
     }
   else
     {
@@ -9044,7 +9044,7 @@ x_clear_frame_area (struct frame *f, int x, int y, int width, int height)
 static void
 x_draw_window_cursor (struct window *w, struct glyph_row *glyph_row, int x,
 		      int y, enum text_cursor_kinds cursor_type,
-		      int cursor_width, bool on_p, bool active_p)
+		      int cursor_width, bool on_p, bool active_p, double red, double green, double blue)
 {
   struct frame *f = XFRAME (WINDOW_FRAME (w));
 
@@ -9070,7 +9070,7 @@ x_draw_window_cursor (struct window *w, struct glyph_row *glyph_row, int x,
 	      break;
 
 	    case FILLED_BOX_CURSOR:
-	      draw_phys_cursor_glyph (w, glyph_row, DRAW_CURSOR);
+	      draw_phys_cursor_glyph (w, glyph_row, DRAW_CURSOR, "xterm.c:9073");
 	      break;
 
 	    case BAR_CURSOR:
