diff --git a/src/buffer.c b/src/buffer.c
index ab47748..0364eba 100644
--- a/src/buffer.c
+++ b/src/buffer.c
@@ -133,6 +133,21 @@ CHECK_OVERLAY (Lisp_Object x)
 
 /* These setters are used only in this file, so they can be private.
    The public setters are inline functions defined in buffer.h.  */
+
+
+/* *************************************************************************** */
+/* begin MULTIPLE-CURSORS */
+
+static void
+bset_crosshairs (struct buffer *b, Lisp_Object val)
+{
+  b->crosshairs_ = val;
+}
+
+/* end MULTIPLE-CURSORS */
+/* *************************************************************************** */
+
+
 static void
 bset_abbrev_mode (struct buffer *b, Lisp_Object val)
 {
@@ -5142,6 +5157,16 @@ init_buffer_once (void)
   bset_last_selected_window (&buffer_local_flags, make_fixnum (0));
 
   idx = 1;
+
+
+/* *************************************************************************** */
+/* MULTIPLE-CURSORS */
+
+  XSETFASTINT (BVAR (&buffer_local_flags, crosshairs), idx); ++idx;
+
+/* *************************************************************************** */
+
+
   XSETFASTINT (BVAR (&buffer_local_flags, mode_line_format), idx); ++idx;
   XSETFASTINT (BVAR (&buffer_local_flags, abbrev_mode), idx); ++idx;
   XSETFASTINT (BVAR (&buffer_local_flags, overwrite_mode), idx); ++idx;
@@ -5228,6 +5253,16 @@ init_buffer_once (void)
   /* Must do these before making the first buffer! */
 
   /* real setup is done in bindings.el */
+
+
+/* *************************************************************************** */
+/* MULTIPLE-CURSORS */
+
+  bset_crosshairs (&buffer_defaults, Qnil);
+
+/* *************************************************************************** */
+
+
   bset_mode_line_format (&buffer_defaults, build_pure_c_string ("%-"));
   bset_header_line_format (&buffer_defaults, Qnil);
   bset_abbrev_mode (&buffer_defaults, Qnil);
@@ -5464,6 +5499,15 @@ syms_of_buffer (void)
   staticpro (&QSFundamental);
   staticpro (&Vbuffer_alist);
 
+
+/* *************************************************************************** */
+/* MULTIPLE-CURSORS */
+
+  DEFSYM (Qcrosshairs, "crosshairs");
+
+/* *************************************************************************** */
+
+
   DEFSYM (Qchoice, "choice");
   DEFSYM (Qleft, "left");
   DEFSYM (Qright, "right");
@@ -5501,6 +5545,16 @@ syms_of_buffer (void)
   Fput (Qprotected_field, Qerror_message,
 	build_pure_c_string ("Attempt to modify a protected field"));
 
+
+/* *************************************************************************** */
+/* MULTIPLE-CURSORS */
+
+  DEFVAR_PER_BUFFER ("crosshairs", &BVAR (current_buffer, crosshairs), Qnil,
+    doc: /* A bufer-local variable to activate/deactivate crosshairs. */);
+
+/* *************************************************************************** */
+
+
   DEFVAR_PER_BUFFER ("header-line-format",
 		     &BVAR (current_buffer, header_line_format),
 		     Qnil,
diff --git a/src/buffer.h b/src/buffer.h
index f42c3e9..233dbca 100644
--- a/src/buffer.h
+++ b/src/buffer.h
@@ -636,6 +636,16 @@ struct buffer
      cache are enabled.  See search.c, indent.c and bidi.c for details.  */
   Lisp_Object cache_long_scans_;
 
+
+/* *************************************************************************** */
+/* MULTIPLE-CURSORS */
+
+  /* The name of the buffer-local variable. */
+  Lisp_Object crosshairs_;
+
+/* *************************************************************************** */
+
+
   /* 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
diff --git a/src/dispnew.c b/src/dispnew.c
index ccb08ec..42cdc96 100644
--- a/src/dispnew.c
+++ b/src/dispnew.c
@@ -3380,6 +3380,114 @@ check_current_matrix_flags (struct window *w)
 
 #endif /* GLYPH_DEBUG */
 
+enum type_of_cache
+{
+  NO_CACHE,
+  MC_TEMP_CACHE,
+  MC_CACHE,
+  CH_CACHE,
+  FC_CACHE
+};
+
+static void
+mc_reset_cache (struct window *w, enum type_of_cache cache_type)
+{
+  switch (cache_type)
+    {
+      case NO_CACHE:
+        {
+          return;
+        }
+      case MC_TEMP_CACHE:
+        {
+          break;
+        }
+      case MC_CACHE:
+        {
+          break;
+        }
+      case CH_CACHE:
+        {
+          if (BUFFERP (w->contents) && NILP (BVAR (XBUFFER (w->contents), crosshairs))
+              && w->mc_nelts > 1)
+            {
+              /* Decrease the size of the array to a bare minimum. */
+              xnrealloc (w->mc_elts, 1, sizeof *w->mc_elts);
+              w->mc_nelts = 0;
+              w->mc_elts_allocated = 1;
+            }
+            else if (BUFFERP (w->contents) && !NILP (BVAR (XBUFFER (w->contents), crosshairs)))
+              {
+                /* Set all _used_ elements of the array to zero.  elts_allocated remain
+                the same. */
+                memset (w->mc_elts, 0, w->mc_nelts * (sizeof *w->mc_elts));
+                /* Uncomment next line when debugging is finished. */
+                // w->mc_nelts = 0;
+              }
+          break;
+        }
+      case FC_CACHE:
+        {
+          break;
+        }
+    }
+}
+
+static void
+mc_populate_cache (struct window *w, enum type_of_cache cache_type)
+{
+  switch (cache_type)
+    {
+      case NO_CACHE:
+        {
+          return;
+        }
+      case MC_TEMP_CACHE:
+        {
+          break;
+        }
+      case MC_CACHE:
+        {
+          break;
+        }
+      case CH_CACHE:
+        {
+          if (BUFFERP (w->contents)
+              && !NILP (BVAR (XBUFFER (w->contents), crosshairs)))
+            {
+              int max_elts = 25000;
+              w->mc_nelts += (w->mc_nelts < max_elts)
+                             ? 100
+                             : 0;
+              /* Increase the size of the array. */
+              if (w->mc_elts_allocated < w->mc_nelts
+                  && w->mc_nelts < max_elts)
+                {
+                  int old_alloc = w->mc_elts_allocated;
+                  int new_elts = w->mc_nelts - w->mc_elts_allocated;
+                  w->mc_elts = xpalloc (w->mc_elts, &w->mc_elts_allocated,
+                                          new_elts, INT_MAX, sizeof *w->mc_elts);
+                  memset (w->mc_elts + old_alloc, 0,
+                           (w->mc_elts_allocated - old_alloc) * sizeof *w->mc_elts);
+                  for (int elt = 0; elt < w->mc_nelts; ++elt)
+                    {
+                      w->mc_elts[elt].x = elt;
+                      double red = elt; 
+                      w->mc_elts[elt].foreground.red = red;
+                      w->mc_elts[elt].enabled_p = true;
+                    }
+                }
+              fprintf (stderr, "w->mc_nelts (%d) | w->mc_elts_allocated (%d) | w->mc_elts[99].x (%d)\n",
+                                w->mc_nelts, w->mc_elts_allocated, w->mc_elts[99].x);
+            }
+          break;
+        }
+      case FC_CACHE:
+        {
+          break;
+        }
+    }
+}
 
 /* Update display of window W.
    If FORCE_P, don't stop updating when input is pending.  */
@@ -3388,6 +3496,23 @@ static bool
 update_window (struct window *w, bool force_p)
 {
   struct glyph_matrix *desired_matrix = w->desired_matrix;
+
+
+/* *************************************************************************** */
+/* begin MULTIPLE-CURSORS */
+
+mc_reset_cache (w, MC_TEMP_CACHE);
+
+mc_reset_cache (w, MC_CACHE);
+
+mc_reset_cache (w, CH_CACHE);
+
+mc_reset_cache (w, FC_CACHE);
+
+/* end MULTIPLE-CURSORS */
+/* *************************************************************************** */
+
+
   bool paused_p;
   int preempt_count = clip_to_bounds (1, baud_rate / 2400 + 1, INT_MAX);
   struct redisplay_interface *rif = FRAME_RIF (XFRAME (WINDOW_FRAME (w)));
@@ -3497,6 +3622,21 @@ update_window (struct window *w, bool force_p)
 
     set_cursor:
 
+
+/* *************************************************************************** */
+/* MULTIPLE-CURSORS */
+
+mc_populate_cache (w, MC_TEMP_CACHE);
+
+mc_populate_cache (w, MC_CACHE);
+
+mc_populate_cache (w, CH_CACHE);
+
+mc_populate_cache (w, FC_CACHE);
+
+/* *************************************************************************** */
+
+
       /* Update the header line after scrolling because a new header
 	 line would otherwise overwrite lines at the top of the window
 	 that can be scrolled.  */
diff --git a/src/pdumper.c b/src/pdumper.c
index cb2915c..dc79eb1 100644
--- a/src/pdumper.c
+++ b/src/pdumper.c
@@ -2770,7 +2770,7 @@ dump_hash_table (struct dump_context *ctx,
 static dump_off
 dump_buffer (struct dump_context *ctx, const struct buffer *in_buffer)
 {
-#if CHECK_STRUCTS && !defined HASH_buffer_E34A11C6B9
+#if CHECK_STRUCTS && !defined HASH_buffer_B712F6B3DC
 # error "buffer changed. See CHECK_STRUCTS comment."
 #endif
   struct buffer munged_buffer = *in_buffer;
diff --git a/src/window.h b/src/window.h
index fdef407..e5a6cca 100644
--- a/src/window.h
+++ b/src/window.h
@@ -88,6 +88,39 @@ display the menu bar or the tool bar (when Emacs uses toolkits that
 don't display their own menu bar and tool bar) or a tooltip in a
 tooltip frame (when tooltips are not display by the toolkit).  */
 
+
+/* *************************************************************************** */
+/* MULTIPLE-CURSORS */
+
+struct RGB
+{
+  double red;
+  double green;
+  double blue;
+};
+
+struct multiple_cursors_cache
+{
+  int x;
+  int fx;
+  int y;
+  int fy;
+  int hpos;
+  int vpos;
+  int wd;
+  int h;
+  int cursor_type;
+  int cursor_width;
+  struct RGB foreground;
+  struct RGB background;
+  bool active_p;
+  int glyph_flavor;
+  bool enabled_p;
+};
+
+/* *************************************************************************** */
+
+
 struct cursor_pos
 {
   /* Pixel position.  These are always window relative.  */
@@ -324,6 +357,65 @@ struct window
 
 #ifdef HAVE_WINDOW_SYSTEM
 
+
+/* *************************************************************************** */
+/* MULTIPLE-CURSORS */
+
+/* --------------------------------------------------------------------------- */
+/*                              TEMPORARY CACHE                                */
+/* --------------------------------------------------------------------------- */
+
+    /* Vector of fake cursor cache structures. */
+    struct multiple_cursors_cache *temp_elts;
+
+    /* Number of elements allocated for the vector above. */
+    ptrdiff_t temp_elts_allocated;
+
+  /* The number of fake cursors presently being used. */
+    int temp_nelts;
+
+/* --------------------------------------------------------------------------- */
+/*                        "MC" FLAVOR OF FAKE CURSORS                          */
+/* --------------------------------------------------------------------------- */
+
+    /* Vector of fake cursor cache structures. */
+    struct multiple_cursors_cache *mc_elts;
+
+    /* Number of elements allocated for the vector above. */
+    ptrdiff_t mc_elts_allocated;
+
+  /* The number of fake cursors presently being used. */
+    int mc_nelts;
+
+/* --------------------------------------------------------------------------- */
+/*                        "CH" FLAVOR OF FAKE CURSORS                          */
+/* --------------------------------------------------------------------------- */
+
+    /* Vector of fake cursor cache structures. */
+    struct multiple_cursors_cache *ch_elts;
+
+    /* Number of elements allocated for the vector above. */
+    ptrdiff_t ch_elts_allocated;
+
+  /* The number of fake cursors presently being used. */
+    int ch_nelts;
+
+/* --------------------------------------------------------------------------- */
+/*                        "FC" FLAVOR OF FAKE CURSORS                          */
+/* --------------------------------------------------------------------------- */
+
+    /* Vector of fake cursor cache structures. */
+    struct multiple_cursors_cache *fc_elts;
+
+    /* Number of elements allocated for the vector above. */
+    ptrdiff_t fc_elts_allocated;
+
+  /* The number of fake cursors presently being used. */
+    int fc_nelts;
+
+/* *************************************************************************** */
+
+
     /* Cursor type of last cursor drawn on the window.  */
     enum text_cursor_kinds phys_cursor_type;
 
