diff --git a/src/buffer.c b/src/buffer.c
index 62b0bc8..05961ef 100644
--- a/src/buffer.c
+++ b/src/buffer.c
@@ -5073,6 +5073,7 @@ 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, 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 +5167,7 @@ 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_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 +5381,8 @@ syms_of_buffer (void)
   staticpro (&QSFundamental);
   staticpro (&Vbuffer_alist);
 
+  DEFSYM (Qmc_list, "mc-list");
+
   DEFSYM (Qchoice, "choice");
   DEFSYM (Qleft, "left");
   DEFSYM (Qright, "right");
@@ -6148,6 +6152,10 @@ 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 ("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 87b7cee..9d7add0 100644
--- a/src/buffer.h
+++ b/src/buffer.h
@@ -643,6 +643,9 @@ struct buffer
      cache are enabled.  See search.c, indent.c and bidi.c for details.  */
   Lisp_Object cache_long_scans_;
 
+  /* 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 +888,11 @@ struct buffer
    buffer.  (Some setters that are private to a single .c file are
    defined as static in those files.)  */
 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 7035872..ac364f9 100644
--- a/src/dispextern.h
+++ b/src/dispextern.h
@@ -2891,7 +2891,7 @@ 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,
@@ -3292,6 +3292,7 @@ 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 mc_calc (struct window *, bool);
 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/nsterm.m b/src/nsterm.m
index 4048ac4..cae89e7 100644
--- a/src/nsterm.m
+++ b/src/nsterm.m
@@ -1112,6 +1112,24 @@ static NSRect constrain_frame_rect(NSRect frameRect, bool isFullscreen)
 				w->output_cursor.hpos, w->output_cursor.vpos,
 				w->output_cursor.x, w->output_cursor.y);
 
+      /* `mc_calc' must follow the creation of the real cursor so that a fake cursor
+      is not erroneously erased during said process.  If the `mc-list' has just been
+      set to `Qnil', then remove fake cursors and redraw the real cursor.  */
+      if ((!NILP (BVAR (current_buffer, mc_list)) || w->mc_cache)
+          && !MINI_WINDOW_P (w))
+        {
+          if (NILP (BVAR (current_buffer, mc_list)) && w->mc_cache)
+            {
+              mc_calc (w, 1); /* Remove fake cursors.  */
+              if (cursor_on_p) /* Redraw real cursor.  */
+                display_and_set_cursor (w, 1,
+                  w->output_cursor.hpos, w->output_cursor.vpos,
+                  w->output_cursor.x, w->output_cursor.y);
+            }
+            else
+              mc_calc (w, 0); /* Draw fake cursors  */
+        }
+
       if (draw_window_fringes (w, 1))
 	{
 	  if (WINDOW_RIGHT_DIVIDER_WIDTH (w))
@@ -2811,7 +2829,7 @@ static void hide_bell ()
 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.
@@ -2896,7 +2914,12 @@ Note that CURSOR_WIDTH is meaningful only for (h)bar cursors.
       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
@@ -3816,6 +3839,8 @@ overwriting cursor (usually when cursor on a tab) */
          (s->for_overlaps ? NS_DUMPGLYPH_FOREGROUND :
           NS_DUMPGLYPH_NORMAL));
 
+      /* TODO:  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 8955ce2..509f89d 100644
--- a/src/w32term.c
+++ b/src/w32term.c
@@ -687,6 +687,24 @@ x_update_window_end (struct window *w, bool cursor_on_p,
 				w->output_cursor.hpos, w->output_cursor.vpos,
 				w->output_cursor.x, w->output_cursor.y);
 
+      /* `mc_calc' must follow the creation of the real cursor so that a fake cursor
+      is not erroneously erased during said process.  If the `mc-list' has just been
+      set to `Qnil', then remove fake cursors and redraw the real cursor.  */
+      if ((!NILP (BVAR (current_buffer, mc_list)) || w->mc_cache)
+          && !MINI_WINDOW_P (w))
+        {
+          if (NILP (BVAR (current_buffer, mc_list)) && w->mc_cache)
+            {
+              mc_calc (w, 1); /* Remove fake cursors.  */
+              if (cursor_on_p) /* Redraw real cursor.  */
+                display_and_set_cursor (w, 1,
+                  w->output_cursor.hpos, w->output_cursor.vpos,
+                  w->output_cursor.x, w->output_cursor.y);
+            }
+            else
+              mc_calc (w, 0); /* Draw fake cursors  */
+        }
+
       if (draw_window_fringes (w, true))
 	{
 	  if (WINDOW_RIGHT_DIVIDER_WIDTH (w))
@@ -935,10 +953,13 @@ static void w32_draw_box_rect (struct glyph_string *, int, int, int, int,
 static void
 x_set_cursor_gc (struct glyph_string *s)
 {
-  if (s->font == FRAME_FONT (s->f)
+  Lisp_Object window = (selected_window);
+  struct window *w = decode_live_window (window);
+  if ((s->font == FRAME_FONT (s->f)
       && s->face->background == FRAME_BACKGROUND_PIXEL (s->f)
       && s->face->foreground == FRAME_FOREGROUND_PIXEL (s->f)
       && !s->cmp)
+      || w->mc.set_cursor_gc)
     s->gc = s->f->output_data.w32->cursor_gc;
   else
     {
@@ -5640,7 +5661,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)
     {
@@ -5705,31 +5726,110 @@ w32_draw_window_cursor (struct window *w, struct glyph_row *glyph_row,
 	  return;
 	}
 
-      switch (cursor_type)
-	{
-	case HOLLOW_BOX_CURSOR:
-	  x_draw_hollow_cursor (w, glyph_row);
-	  break;
-
-	case FILLED_BOX_CURSOR:
-	  draw_phys_cursor_glyph (w, glyph_row, DRAW_CURSOR);
-	  break;
-
-	case BAR_CURSOR:
-	  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;
 
-	case NO_CURSOR:
-	  w->phys_cursor_width = 0;
-	  break;
-
-	default:
-	  emacs_abort ();
-	}
+  switch (cursor_type)
+    {
+      case HOLLOW_BOX_CURSOR:
+      {
+        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_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:
+      {
+        /* TODO:  kdb to consider adding support for multiple cursor foreground
+        customization of a FILLED_BOX_CURSOR.  */
+        if (red >= 0 && blue >= 0 && green >= 0)
+          /* Temporarily hijack `f->output_data.w32->cursor_gc' by borrowing the
+          functionality of `x_make_gc' in w32fns.c.  */
+          {
+            block_input ();
+            Lisp_Object window = (selected_window);
+            struct window *w = decode_live_window (window);
+            struct frame *f = XFRAME (WINDOW_FRAME (w));
+            int int_red = red * 255;
+            int int_green = green * 255;
+            int int_blue = blue * 255;
+            XGCValues gc_values;
+            unsigned long mask = GCFont | GCForeground | GCBackground;
+            COLORREF orig_val_a = FRAME_BACKGROUND_PIXEL (f);
+            COLORREF orig_val_b = f->output_data.w32->cursor_pixel;
+            gc_values.font = FRAME_FONT (f);
+            gc_values.foreground = FRAME_BACKGROUND_PIXEL (f);
+            gc_values.background = PALETTERGB (int_red, int_green, int_blue);
+            f->output_data.w32->cursor_gc
+              = XCreateGC (NULL, FRAME_W32_WINDOW (f), mask, &gc_values);
+            /* When `w->mc.set_cursor_gc = true', force `x_set_cursor_gc' to
+            use `s->f->output_data.w32->cursor_gc'.  */
+            w->mc.set_cursor_gc = true;
+            draw_phys_cursor_glyph (w, glyph_row, DRAW_CURSOR);
+            w->mc.set_cursor_gc = false;
+            gc_values.font = FRAME_FONT (f);
+            gc_values.foreground = orig_val_a;
+            gc_values.background = orig_val_b;
+            f->output_data.w32->cursor_gc
+              = XCreateGC (NULL, FRAME_W32_WINDOW (f), mask, &gc_values);
+            unblock_input ();
+          }
+          else
+            draw_phys_cursor_glyph (w, glyph_row, DRAW_CURSOR);
+        break;
+      }
+      case BAR_CURSOR:
+      {
+        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:
+      {
+        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;
+        break;
+      default:
+        emacs_abort ();
+  }
     }
 }
 
diff --git a/src/window.h b/src/window.h
index 84180c9..631c5e4 100644
--- a/src/window.h
+++ b/src/window.h
@@ -76,6 +76,16 @@ one and the same, so its prev and next members are nil.
 
 A dead window has its contents field set to nil.  */
 
+struct multiple_cursors
+{
+  /* Values for previous and current `window-start' and `window-end'.  */
+  EMACS_INT start, end, prev_start, prev_end;
+
+  /* True means to force `x_set_cursor_gc' to use `s->f->output_data.w32->cursor_gc'
+  in w32term.c or `s->f->output_data.x->cursor_gc' in xterm.c.  */
+  bool_bf set_cursor_gc : 1;
+};
+
 struct cursor_pos
 {
   /* Pixel position.  These are always window relative.  */
@@ -178,6 +188,10 @@ struct window
     /* An alist with parameters.  */
     Lisp_Object window_parameters;
 
+    /* The cache for multiple cursors.  For an example of the structure of
+    the list, see the comments at the beginning of `mc_calc' in xdisp.c.  */
+    Lisp_Object mc_cache;
+
     /* No Lisp data may follow below this point without changing
        mark_object in alloc.c.  The member current_matrix must be the
        first non-Lisp member.  */
@@ -280,6 +294,9 @@ struct window
 
 #ifdef HAVE_WINDOW_SYSTEM
 
+    /* The prefix for window pointers relating to multiple cursors.  */
+    struct multiple_cursors mc;
+
     /* Cursor type of last cursor drawn on the window.  */
     enum text_cursor_kinds phys_cursor_type;
 
diff --git a/src/xdisp.c b/src/xdisp.c
index bdc8af8..7fd03ce 100644
--- a/src/xdisp.c
+++ b/src/xdisp.c
@@ -17107,6 +17107,22 @@ redisplay_window (Lisp_Object window, bool just_this_one_p)
   else
     TEMP_SET_PT_BOTH (CHARPOS (opoint), BYTEPOS (opoint));
 
+  /* This section must precede setting the `old' buffer below.  An additional
+  check for window-start and window-end is needed inside `mc_calc' when
+  initializing the `mc_list' because redisplay may not necessarily run this
+  particular section of code.  If the `mc_list' has just been set to `Qnil',
+  then it is necessary to make one final pass to remove the cursors.  */
+  if ((!NILP (BVAR (current_buffer, mc_list)) || w->mc_cache)
+      && !MINI_WINDOW_P (w))
+    {
+      if (w->mc.start)
+        w->mc.prev_start = w->mc.start;
+      if (w->mc.end)
+        w->mc.prev_end = w->mc.end;
+      w->mc.start = CHARPOS (startp);
+      w->mc.end = BUF_Z (buffer) - w->window_end_pos;
+    }
+
   set_buffer_internal_1 (old);
   /* Avoid an abort in TEMP_SET_PT_BOTH if the buffer has become
      shorter.  This can be caused by log truncation in *Messages*.  */
@@ -28348,6 +28364,459 @@ erase_phys_cursor (struct window *w)
   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);
+  struct glyph *cursor_glyph;
+  struct glyph_row *cursor_row = MATRIX_ROW (w->current_matrix, vpos);
+  /* Maybe clear the display under the cursor.  */
+  if (w->phys_cursor_type == HOLLOW_BOX_CURSOR)
+    {
+      int hollow_x, hollow_y, 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 done;
+      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);
+    }
+  /* 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, DRAW_NORMAL_TEXT, 0);
+      if (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);
+        }
+    }
+  done:
+    Qnil;
+}
+
+void
+mc_draw (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 glyph *glyph;
+  /* Record the current values for w->phys_cursor.x/y/hpos/vpos.  */
+  int prior_hpos = w->phys_cursor.hpos;
+  int prior_vpos = w->phys_cursor.vpos;
+  int prior_x = w->phys_cursor.x;
+  int prior_y = w->phys_cursor.y;
+  struct frame *f = XFRAME (w->frame);
+  struct glyph_row *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;
+  /* 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, 1, 0, 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, pos;
+  int x, y, hpos, vpos;
+  if (w->mc.start
+      && w->mc.end
+      && posint >= w->mc.start
+      && posint <= w->mc.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))
+    ))
+TODO:  Set up a user option similar to `cursor-in-non-selected-windows'.
+To inspect a value that does not squarely fit into a GLYPH_DEBUG category,
+convert it to a lisp object and use `Fmessage'.  To avoid crashing Emacs,
+convert raw numbers using functions like `make_number', `make_float', etc.:
+  Lisp_Object obj_one = make_float (red);
+  AUTO_STRING (format_one, "red:  %s");
+  CALLN (Fmessage, format_one, obj_one);
+  Lisp_Object obj_two = make_float (green);
+  AUTO_STRING (format_two, "green:  %s");
+  CALLN (Fmessage, format_two, obj_two);
+  Lisp_Object obj_three = make_float (blue);
+  AUTO_STRING (format_three, "blue:  %s");
+  CALLN (Fmessage, format_three, obj_three);  */
+void
+mc_calc (struct window *w, bool remove)
+{
+  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 buffer *b;
+  struct buffer *old_buffer = NULL;
+  buf = w->contents;
+  CHECK_BUFFER (buf);
+  b = XBUFFER (buf);
+  if (b != current_buffer)
+    {
+      old_buffer = current_buffer;
+      set_buffer_internal (b);
+    }
+  /* Normally window-start and window-end pointers are set within `redisplay_window', however,
+  that section of the code may not necessarily run when initializing the `mc_list'.  */
+  if (w->mc.start && !w->mc.prev_start)
+    w->mc.prev_start = w->mc.start;
+  if (w->mc.end && !w->mc.prev_end)
+    w->mc.prev_end = w->mc.end;
+  if (!w->mc.start)
+    w->mc.start = marker_position (w->start);
+  if (!w->mc.end)
+    w->mc.end = BUF_Z (XBUFFER (w->contents)) - w->window_end_pos;
+
+/* RESERVED FOR POTENTIAL FUTURE USE TO EXTRACT START FROM EACH OVERLAY.  */
+/*   Lisp_Object overlays = Foverlays_in (make_number (BEGV), make_number (ZV));
+     Lisp_Object temp_list = Qnil;
+     Lisp_Object new_list = Qnil;
+     Lisp_Object ov = Qnil;
+     ptrdiff_t ov_start;
+     Lisp_Object ov_type = Qnil;
+     Lisp_Object ov_list = Qnil;
+     Lisp_Object type = intern ("type");
+     Lisp_Object fake_cursor = intern ("fake-cursor");
+     AUTO_STRING (format_one, "overlays:  %s");
+     CALLN (Fmessage, format_one, overlays);
+     for (ov_list = overlays;
+          CONSP (ov_list);
+          ov_list = XCDR (ov_list))
+       {
+         ov = XCAR (ov_list);
+         ov_type = Foverlay_get (ov, type);
+         if (EQ (ov_type, fake_cursor))
+         {
+           ov_start = make_number (OVERLAY_POSITION (OVERLAY_START (ov)));
+           temp_list = listn (CONSTYPE_PURE, 3,
+             ov_start,
+             build_pure_c_string ("bar"),
+             CALLN (Fvector, make_float (0.0), make_float (0.0), make_float (1.0)));
+           AUTO_STRING (format_two, "temp_list:  %s");
+           CALLN (Fmessage, format_two, temp_list);
+           new_list = Fcons (temp_list, new_list);
+         }
+       }
+     AUTO_STRING (format_three, "new_list:  %s");
+     CALLN (Fmessage, format_three, new_list);
+     if (!NILP (new_list))
+       bset_mc_list (current_buffer, new_list);  */
+
+  if (remove
+      || (w->mc_cache && NILP (BVAR (current_buffer, mc_list)))
+      || (w->mc_cache && !NILP (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
+              && posint != PT  /* Protect the real cursor from being erased.  */
+              && w->mc.start
+              && w->mc.end
+              && posint >= w->mc.start
+              && posint <= w->mc.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;
+    }
+
+  if (!remove
+      && w == sw
+      && w->mc.start
+      && w->mc.end
+      && w->mc.prev_start
+      && w->mc.prev_end
+      && w->mc.start == w->mc.prev_start
+      && w->mc.end == w->mc.prev_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->mc.start
+              && w->mc.end
+              && posint >= w->mc.start
+              && posint <= w->mc.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, x, y, hpos, vpos, cursor_type, cursor_width, red, green, blue);
+            }
+        }
+    }
+
+  if (!remove
+      && w == sw
+      && w->mc.start
+      && w->mc.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 anew");
+#endif
+      /* Erase all of the old cursors at the previously recorded x/y/hpos/vpos even
+      though the corresponding `posint' has changed.  */
+      if (w->mc_cache)
+        {
+          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));
+              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;
+        }
+      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->mc.start
+                  && w->mc.end
+                  && posint >= w->mc.start
+                  && posint <= w->mc.end)
+                mc_draw (w, x, y, hpos, vpos, cursor_type, cursor_width, red, green, blue);
+            }
+        }
+      if (result)
+        w->mc_cache = Fcons (BVAR (current_buffer, mc_list), Fcons (Freverse (result), Qnil));
+    }
+  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
@@ -28363,6 +28832,12 @@ 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.  */
+  double red = -1.0;
+  double blue = -1.0;
+  double green = -1.0;
 
   /* This is pointless on invisible frames, and dangerous on garbaged
      windows and frames; in the latter case, the frame or window may
@@ -28434,7 +28909,7 @@ 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);
 }
 
 
diff --git a/src/xterm.c b/src/xterm.c
index ba9bf50..28bd942 100644
--- a/src/xterm.c
+++ b/src/xterm.c
@@ -1153,6 +1153,24 @@ x_update_window_end (struct window *w, bool cursor_on_p,
 				w->output_cursor.hpos, w->output_cursor.vpos,
 				w->output_cursor.x, w->output_cursor.y);
 
+      /* `mc_calc' must follow the creation of the real cursor so that a fake cursor
+      is not erroneously erased during said process.  If the `mc-list' has just been
+      set to `Qnil', then remove fake cursors and redraw the real cursor.  */
+      if ((!NILP (BVAR (current_buffer, mc_list)) || w->mc_cache)
+          && !MINI_WINDOW_P (w))
+        {
+          if (NILP (BVAR (current_buffer, mc_list)) && w->mc_cache)
+            {
+              mc_calc (w, 1); /* Remove fake cursors.  */
+              if (cursor_on_p) /* Redraw real cursor.  */
+                display_and_set_cursor (w, 1,
+                  w->output_cursor.hpos, w->output_cursor.vpos,
+                  w->output_cursor.x, w->output_cursor.y);
+            }
+            else
+              mc_calc (w, 0); /* Draw fake cursors  */
+        }
+
       if (draw_window_fringes (w, true))
 	{
 	  if (WINDOW_RIGHT_DIVIDER_WIDTH (w))
@@ -1449,10 +1467,13 @@ static void x_check_font (struct frame *, struct font *);
 static void
 x_set_cursor_gc (struct glyph_string *s)
 {
-  if (s->font == FRAME_FONT (s->f)
+  Lisp_Object window = (selected_window);
+  struct window *w = decode_live_window (window);
+  if ((s->font == FRAME_FONT (s->f)
       && s->face->background == FRAME_BACKGROUND_PIXEL (s->f)
       && s->face->foreground == FRAME_FOREGROUND_PIXEL (s->f)
       && !s->cmp)
+      || w->mc.set_cursor_gc)
     s->gc = s->f->output_data.x->cursor_gc;
   else
     {
@@ -9044,7 +9065,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));
 
@@ -9063,31 +9084,114 @@ x_draw_window_cursor (struct window *w, struct glyph_row *glyph_row, int x,
 	}
       else
 	{
-	  switch (cursor_type)
-	    {
-	    case HOLLOW_BOX_CURSOR:
-	      x_draw_hollow_cursor (w, glyph_row);
-	      break;
-
-	    case FILLED_BOX_CURSOR:
-	      draw_phys_cursor_glyph (w, glyph_row, DRAW_CURSOR);
-	      break;
-
-	    case BAR_CURSOR:
-	      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;
-
-	    case NO_CURSOR:
-	      w->phys_cursor_width = 0;
-	      break;
-
-	    default:
-	      emacs_abort ();
-	    }
+  switch (cursor_type)
+  {
+  case HOLLOW_BOX_CURSOR:
+  {
+    if (red >= 0 && blue >= 0 && green >= 0)
+      /* Temporarily hijack `f->output_data.x->cursor_pixel'.  */
+      {
+        struct frame *f = XFRAME (WINDOW_FRAME (w));
+        struct x_display_info *dpyinfo = FRAME_DISPLAY_INFO (f);
+        unsigned long orig_val = f->output_data.x->cursor_pixel;
+        int int_red = red * 65535;
+        int int_green = green * 65535;
+        int int_blue = blue * 65535;
+        f->output_data.x->cursor_pixel = x_make_truecolor_pixel (dpyinfo, int_red, int_green, int_blue);
+        x_draw_hollow_cursor (w, glyph_row);
+        f->output_data.x->cursor_pixel = orig_val;
+      }
+      else
+        x_draw_hollow_cursor (w, glyph_row);
+    break;
+  }
+  case FILLED_BOX_CURSOR:
+  {
+     /* TODO:  kdb to consider adding support for multiple cursor foreground
+     customization of a FILLED_BOX_CURSOR.  */
+    if (red >= 0 && blue >= 0 && green >= 0)
+      /* Temporarily hijack `f->output_data.x->cursor_gc' by borrowing the
+      functionality of `x_make_gc' in xfns.c.  */
+      {
+        block_input ();
+        Lisp_Object window = (selected_window);
+        struct window *w = decode_live_window (window);
+        struct frame *f = XFRAME (WINDOW_FRAME (w));
+        struct x_display_info *dpyinfo = FRAME_DISPLAY_INFO (f);
+        int int_red = red * 65535;
+        int int_green = green * 65535;
+        int int_blue = blue * 65535;
+        XGCValues gc_values;
+        unsigned long mask = GCForeground | GCBackground | GCFillStyle | GCLineWidth;
+        unsigned long orig_val_a = FRAME_BACKGROUND_PIXEL (f);
+        unsigned long orig_val_b = f->output_data.x->cursor_pixel;
+        gc_values.line_width = 0;  /* Means 1 using fast algorithm.  */
+        gc_values.foreground = FRAME_BACKGROUND_PIXEL (f);
+        gc_values.background = x_make_truecolor_pixel (dpyinfo, int_red, int_green, int_blue);
+        gc_values.fill_style = FillOpaqueStippled;
+        f->output_data.x->cursor_gc
+          = XCreateGC (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f), mask, &gc_values);
+        /* When `w->mc.set_cursor_gc = true', force `x_set_cursor_gc' to
+        use `s->f->output_data.x->cursor_gc'.  */
+        w->mc.set_cursor_gc = true;
+        draw_phys_cursor_glyph (w, glyph_row, DRAW_CURSOR);
+        w->mc.set_cursor_gc = false;
+        gc_values.line_width = 0;  /* Means 1 using fast algorithm.  */
+        gc_values.foreground = orig_val_a;
+        gc_values.background = orig_val_b;
+        gc_values.fill_style = FillOpaqueStippled;
+        f->output_data.x->cursor_gc
+          = XCreateGC (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f), mask, &gc_values);
+        unblock_input ();
+      }
+      else
+        draw_phys_cursor_glyph (w, glyph_row, DRAW_CURSOR);
+    break;
+  }
+  case BAR_CURSOR:
+  {
+    if (red >= 0 && blue >= 0 && green >= 0)
+      /* Temporarily hijack `f->output_data.x->cursor_pixel'.  */
+      {
+        struct frame *f = XFRAME (WINDOW_FRAME (w));
+        struct x_display_info *dpyinfo = FRAME_DISPLAY_INFO (f);
+        unsigned long orig_val = f->output_data.x->cursor_pixel;
+        int int_red = red * 65535;
+        int int_green = green * 65535;
+        int int_blue = blue * 65535;
+        f->output_data.x->cursor_pixel = x_make_truecolor_pixel (dpyinfo, int_red, int_green, int_blue);
+        x_draw_bar_cursor (w, glyph_row, cursor_width, BAR_CURSOR);
+        f->output_data.x->cursor_pixel = orig_val;
+      }
+      else
+        x_draw_bar_cursor (w, glyph_row, cursor_width, BAR_CURSOR);
+    break;
+  }
+  case HBAR_CURSOR:
+  {
+    if (red >= 0 && blue >= 0 && green >= 0)
+      /* Temporarily hijack `f->output_data.x->cursor_pixel'.  */
+      {
+        struct frame *f = XFRAME (WINDOW_FRAME (w));
+        struct x_display_info *dpyinfo = FRAME_DISPLAY_INFO (f);
+        unsigned long orig_val = f->output_data.x->cursor_pixel;
+        int int_red = red * 65535;
+        int int_green = green * 65535;
+        int int_blue = blue * 65535;
+        f->output_data.x->cursor_pixel = x_make_truecolor_pixel (dpyinfo, int_red, int_green, int_blue);
+        x_draw_bar_cursor (w, glyph_row, cursor_width, HBAR_CURSOR);
+        f->output_data.x->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;
+    break;
+  default:
+    emacs_abort ();
+  }
 	}
 
 #ifdef HAVE_X_I18N
